From 5fd66b0bdeb5e717d35edd9ba63284bec187cc97 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 08:21:10 -0800 Subject: [PATCH 001/215] AGS: Skeleton engine Based on AGS 3.5.0.27 --- engines/ags/ags.cpp | 59 ++++++++++++++++++++++ engines/ags/ags.h | 90 ++++++++++++++++++++++++++++++++++ engines/ags/configure.engine | 3 ++ engines/ags/detection.cpp | 34 +++++++++++++ engines/ags/detection.h | 54 ++++++++++++++++++++ engines/ags/detection_tables.h | 34 +++++++++++++ engines/ags/metaengine.cpp | 42 ++++++++++++++++ engines/ags/metaengine.h | 37 ++++++++++++++ engines/ags/module.mk | 17 +++++++ 9 files changed, 370 insertions(+) create mode 100644 engines/ags/ags.cpp create mode 100644 engines/ags/ags.h create mode 100644 engines/ags/configure.engine create mode 100644 engines/ags/detection.cpp create mode 100644 engines/ags/detection.h create mode 100644 engines/ags/detection_tables.h create mode 100644 engines/ags/metaengine.cpp create mode 100644 engines/ags/metaengine.h create mode 100644 engines/ags/module.mk diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp new file mode 100644 index 000000000000..133e2ec91513 --- /dev/null +++ b/engines/ags/ags.cpp @@ -0,0 +1,59 @@ +/* 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 "ags/ags.h" +#include "ags/detection.h" +#include "common/scummsys.h" +#include "common/config-manager.h" +#include "common/debug-channels.h" +#include "common/events.h" +#include "common/file.h" + +namespace AGS { + +AGSEngine *g_vm; + +/*------------------------------------------------------------------*/ + +AGSEngine::AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc) : Engine(syst), + _gameDescription(gameDesc), _randomSource("AGS") { + g_vm = this; + DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); + DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); +} + +AGSEngine::~AGSEngine() { +} + +uint32 AGSEngine::getFeatures() const { + return _gameDescription->desc.flags; +} + +Common::Error AGSEngine::run() { + return Common::kNoError; +} + +SaveStateList AGSEngine::listSaves() const { + return getMetaEngine().listSaves(_targetName.c_str()); +} + +} // namespace AGS diff --git a/engines/ags/ags.h b/engines/ags/ags.h new file mode 100644 index 000000000000..fce049973e15 --- /dev/null +++ b/engines/ags/ags.h @@ -0,0 +1,90 @@ +/* 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 AGS_AGS_H +#define AGS_AGS_H + +#include "common/scummsys.h" +#include "common/system.h" +#include "common/error.h" +#include "common/random.h" +#include "common/hash-str.h" +#include "common/util.h" +#include "engines/engine.h" +#include "engines/savestate.h" +#include "graphics/surface.h" + +namespace AGS { + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 200 + +enum AGSDebugChannels { + kDebugPath = 1 << 0, + kDebugGraphics = 1 << 1 +}; + +struct AGSGameDescription; + +class AGSEngine : public Engine { +private: + const AGSGameDescription *_gameDescription; + Common::RandomSource _randomSource; +protected: + // Engine APIs + virtual Common::Error run(); +public: + AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc); + virtual ~AGSEngine(); + void GUIError(const Common::String &msg); + + void set_window_title(const char *str) { + // No implementation + } + + uint32 getFeatures() const; + + /** + * Returns the current list of savegames + */ + SaveStateList listSaves() const; + + /** + * Gets a random number + */ + uint32 getRandomNumber(uint maxNum) { + return _randomSource.getRandomNumber(maxNum); + } + + /** + * Sets the random number seed + */ + void setRandomNumberSeed(uint32 seed) { + _randomSource.setSeed(seed); + } +}; + +extern AGSEngine *g_vm; + +} // namespace AGS + +#endif diff --git a/engines/ags/configure.engine b/engines/ags/configure.engine new file mode 100644 index 000000000000..55cba93bb428 --- /dev/null +++ b/engines/ags/configure.engine @@ -0,0 +1,3 @@ +# This file is included from the main "configure" script +# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] +add_engine ags "Adventure Game Studio" no "" "" "cxx11" diff --git a/engines/ags/detection.cpp b/engines/ags/detection.cpp new file mode 100644 index 000000000000..898cc29fb7c3 --- /dev/null +++ b/engines/ags/detection.cpp @@ -0,0 +1,34 @@ +/* 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 "base/plugins.h" +#include "ags/detection.h" +#include "ags/detection_tables.h" + +AGSMetaEngineDetection::AGSMetaEngineDetection() : AdvancedMetaEngineDetection(AGS::GAME_DESCRIPTIONS, + sizeof(AGS::AGSGameDescription), AGS::AGS_GAMES) { + static const char *const DIRECTORY_GLOBS[2] = { "usecode", 0 }; + _maxScanDepth = 2; + _directoryGlobs = DIRECTORY_GLOBS; +} + +REGISTER_PLUGIN_STATIC(AGS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, AGSMetaEngineDetection); diff --git a/engines/ags/detection.h b/engines/ags/detection.h new file mode 100644 index 000000000000..f916f2f2a19d --- /dev/null +++ b/engines/ags/detection.h @@ -0,0 +1,54 @@ +/* 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 AGS_DETECTION_H +#define AGS_DETECTION_H + +#include "engines/advancedDetector.h" + +namespace AGS { + +struct AGSGameDescription { + ADGameDescription desc; +}; + +} // namespace AGS + +class AGSMetaEngineDetection : public AdvancedMetaEngineDetection { +public: + AGSMetaEngineDetection(); + ~AGSMetaEngineDetection() override {} + + virtual const char *getEngineId() const { + return "ags"; + } + + virtual const char *getName() const { + return "Adventure Game Studio"; + } + + virtual const char *getOriginalCopyright() const { + return ""; + } +}; + +#endif diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h new file mode 100644 index 000000000000..29a04e180b94 --- /dev/null +++ b/engines/ags/detection_tables.h @@ -0,0 +1,34 @@ +/* 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 AGS { + +static const PlainGameDescriptor AGS_GAMES[] = { + { "ags", "Adventure Game Studio Game" }, + { 0, 0 } +}; + +static const AGSGameDescription GAME_DESCRIPTIONS[] = { + { AD_TABLE_END_MARKER } +}; + +} // namespace AGS diff --git a/engines/ags/metaengine.cpp b/engines/ags/metaengine.cpp new file mode 100644 index 000000000000..bb737c24f0b9 --- /dev/null +++ b/engines/ags/metaengine.cpp @@ -0,0 +1,42 @@ +/* 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 "ags/metaengine.h" +#include "ags/detection.h" +#include "ags/ags.h" + +const char *AGSMetaEngine::getName() const { + return "ags"; +} + +Common::Error AGSMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + const AGS::AGSGameDescription *gd = (const AGS::AGSGameDescription *)desc; + + *engine = new AGS::AGSEngine(syst, gd); + return Common::kNoError; +} + +#if PLUGIN_ENABLED_DYNAMIC(AGS) +REGISTER_PLUGIN_DYNAMIC(AGS, PLUGIN_TYPE_ENGINE, AGSMetaEngine); +#else +REGISTER_PLUGIN_STATIC(AGS, PLUGIN_TYPE_ENGINE, AGSMetaEngine); +#endif diff --git a/engines/ags/metaengine.h b/engines/ags/metaengine.h new file mode 100644 index 000000000000..b8a6cd8c84f9 --- /dev/null +++ b/engines/ags/metaengine.h @@ -0,0 +1,37 @@ +/* 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 AGS_METAENGINE_H +#define AGS_METAENGINE_H + +#include "engines/advancedDetector.h" + +#define MAX_SAVES 99 + +class AGSMetaEngine : public AdvancedMetaEngine { +public: + const char *getName() const override; + + virtual Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; +}; + +#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk new file mode 100644 index 000000000000..92457bcd1768 --- /dev/null +++ b/engines/ags/module.mk @@ -0,0 +1,17 @@ +MODULE := engines/ags + +MODULE_OBJS = \ + ags.o \ + metaengine.o + + +# This module can be built as a plugin +ifeq ($(ENABLE_AGS), DYNAMIC_PLUGIN) +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk + +# Detection objects +DETECT_OBJS += $(MODULE)/detection.o From a0977d03ee2cfed423a9841d7301dfc0a7bf0b94 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 08:23:16 -0800 Subject: [PATCH 002/215] AGS: Added std class implementations and allegro stubs --- engines/ags/module.mk | 16 ++- engines/ags/std/array.h | 44 ++++++ engines/ags/std/chrono.h | 85 ++++++++++++ engines/ags/std/functional.h | 45 +++++++ engines/ags/std/limits.h | 49 +++++++ engines/ags/std/list.h | 77 +++++++++++ engines/ags/std/map.h | 53 ++++++++ engines/ags/std/memory.h | 44 ++++++ engines/ags/std/mutex.h | 37 +++++ engines/ags/std/set.h | 123 +++++++++++++++++ engines/ags/std/thread.h | 61 +++++++++ engines/ags/std/type_traits.h | 51 +++++++ engines/ags/std/utility.h | 48 +++++++ engines/ags/std/vector.h | 173 ++++++++++++++++++++++++ engines/ags/std/xutility.h | 34 +++++ engines/ags/stubs/allegro.cpp | 34 +++++ engines/ags/stubs/allegro.h | 49 +++++++ engines/ags/stubs/allegro/alconfig.h | 79 +++++++++++ engines/ags/stubs/allegro/base.h | 60 +++++++++ engines/ags/stubs/allegro/color.cpp | 68 ++++++++++ engines/ags/stubs/allegro/color.h | 66 +++++++++ engines/ags/stubs/allegro/config.cpp | 32 +++++ engines/ags/stubs/allegro/config.h | 32 +++++ engines/ags/stubs/allegro/digi.cpp | 40 ++++++ engines/ags/stubs/allegro/digi.h | 145 ++++++++++++++++++++ engines/ags/stubs/allegro/error.cpp | 28 ++++ engines/ags/stubs/allegro/error.h | 82 ++++++++++++ engines/ags/stubs/allegro/file.cpp | 57 ++++++++ engines/ags/stubs/allegro/file.h | 42 ++++++ engines/ags/stubs/allegro/fixed.cpp | 178 +++++++++++++++++++++++++ engines/ags/stubs/allegro/fixed.h | 63 +++++++++ engines/ags/stubs/allegro/gfx.cpp | 43 ++++++ engines/ags/stubs/allegro/gfx.h | 176 ++++++++++++++++++++++++ engines/ags/stubs/allegro/keyboard.cpp | 39 ++++++ engines/ags/stubs/allegro/keyboard.h | 105 +++++++++++++++ engines/ags/stubs/allegro/midi.cpp | 46 +++++++ engines/ags/stubs/allegro/midi.h | 123 +++++++++++++++++ engines/ags/stubs/allegro/mouse.cpp | 116 ++++++++++++++++ engines/ags/stubs/allegro/mouse.h | 120 +++++++++++++++++ engines/ags/stubs/allegro/sound.cpp | 103 ++++++++++++++ engines/ags/stubs/allegro/sound.h | 57 ++++++++ engines/ags/stubs/allegro/system.cpp | 65 +++++++++ engines/ags/stubs/allegro/system.h | 103 ++++++++++++++ engines/ags/stubs/allegro/unicode.cpp | 37 +++++ engines/ags/stubs/allegro/unicode.h | 41 ++++++ 45 files changed, 3168 insertions(+), 1 deletion(-) create mode 100644 engines/ags/std/array.h create mode 100644 engines/ags/std/chrono.h create mode 100644 engines/ags/std/functional.h create mode 100644 engines/ags/std/limits.h create mode 100644 engines/ags/std/list.h create mode 100644 engines/ags/std/map.h create mode 100644 engines/ags/std/memory.h create mode 100644 engines/ags/std/mutex.h create mode 100644 engines/ags/std/set.h create mode 100644 engines/ags/std/thread.h create mode 100644 engines/ags/std/type_traits.h create mode 100644 engines/ags/std/utility.h create mode 100644 engines/ags/std/vector.h create mode 100644 engines/ags/std/xutility.h create mode 100644 engines/ags/stubs/allegro.cpp create mode 100644 engines/ags/stubs/allegro.h create mode 100644 engines/ags/stubs/allegro/alconfig.h create mode 100644 engines/ags/stubs/allegro/base.h create mode 100644 engines/ags/stubs/allegro/color.cpp create mode 100644 engines/ags/stubs/allegro/color.h create mode 100644 engines/ags/stubs/allegro/config.cpp create mode 100644 engines/ags/stubs/allegro/config.h create mode 100644 engines/ags/stubs/allegro/digi.cpp create mode 100644 engines/ags/stubs/allegro/digi.h create mode 100644 engines/ags/stubs/allegro/error.cpp create mode 100644 engines/ags/stubs/allegro/error.h create mode 100644 engines/ags/stubs/allegro/file.cpp create mode 100644 engines/ags/stubs/allegro/file.h create mode 100644 engines/ags/stubs/allegro/fixed.cpp create mode 100644 engines/ags/stubs/allegro/fixed.h create mode 100644 engines/ags/stubs/allegro/gfx.cpp create mode 100644 engines/ags/stubs/allegro/gfx.h create mode 100644 engines/ags/stubs/allegro/keyboard.cpp create mode 100644 engines/ags/stubs/allegro/keyboard.h create mode 100644 engines/ags/stubs/allegro/midi.cpp create mode 100644 engines/ags/stubs/allegro/midi.h create mode 100644 engines/ags/stubs/allegro/mouse.cpp create mode 100644 engines/ags/stubs/allegro/mouse.h create mode 100644 engines/ags/stubs/allegro/sound.cpp create mode 100644 engines/ags/stubs/allegro/sound.h create mode 100644 engines/ags/stubs/allegro/system.cpp create mode 100644 engines/ags/stubs/allegro/system.h create mode 100644 engines/ags/stubs/allegro/unicode.cpp create mode 100644 engines/ags/stubs/allegro/unicode.h diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 92457bcd1768..5256e3b69e68 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -2,7 +2,21 @@ MODULE := engines/ags MODULE_OBJS = \ ags.o \ - metaengine.o + metaengine.o \ + stubs/allegro.o \ + stubs/allegro/color.o \ + stubs/allegro/config.o \ + stubs/allegro/digi.o \ + stubs/allegro/error.o \ + stubs/allegro/file.o \ + stubs/allegro/fixed.o \ + stubs/allegro/gfx.o \ + stubs/allegro/keyboard.o \ + stubs/allegro/midi.o \ + stubs/allegro/mouse.o \ + stubs/allegro/sound.o \ + stubs/allegro/system.o \ + stubs/allegro/unicode.o # This module can be built as a plugin diff --git a/engines/ags/std/array.h b/engines/ags/std/array.h new file mode 100644 index 000000000000..4505a669f688 --- /dev/null +++ b/engines/ags/std/array.h @@ -0,0 +1,44 @@ +/* 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 AGS_STD_ARRAY_H +#define AGS_STD_ARRAY_H + +#include "common/array.h" + +namespace AGS3 { +namespace std { + +template +class array : public Common::Array { +public: + array() : Common::Array() { + } + array(size_t size) : Common::Array() { + Common::Array::resize(size); + } +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/chrono.h b/engines/ags/std/chrono.h new file mode 100644 index 000000000000..5bbb2b03fd92 --- /dev/null +++ b/engines/ags/std/chrono.h @@ -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. + * + */ + +#ifndef AGS_STD_CHRONO_H +#define AGS_STD_CHRONO_H + +#include "common/system.h" + +namespace AGS3 { +namespace std { + +namespace chrono { + +typedef uint32 milliseconds; + +struct system_clock { +}; + + +struct steady_clock { // wraps QueryPerformanceCounter + using rep = uint32; + using period = milliseconds; + using duration = milliseconds; + using time_point = uint32; + static constexpr bool is_steady = true; + + static time_point now() { // get current time + return g_system->getMillis(); + } +}; + +using high_resolution_clock = steady_clock; + +class duration { +private: + uint32 _value; +public: + duration() : _value(0) { + } + duration(uint32 value) : _value(value) { + } + + size_t count() const { + // durations for ScummVM are hardcoded to be in milliseconds + return 1000; + } + + operator milliseconds() const { + return _value; + } +}; + +template +duration duration_cast(T param); + +template +duration duration_cast(milliseconds param) { + return duration(param); +} + +} // namespace chrono + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/functional.h b/engines/ags/std/functional.h new file mode 100644 index 000000000000..e83b997020a8 --- /dev/null +++ b/engines/ags/std/functional.h @@ -0,0 +1,45 @@ +/* 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 AGS_STD_FUNCTIONAL_H +#define AGS_STD_FUNCTIONAL_H + +namespace AGS3 { +namespace std { + +template +struct unary_function { // base class for unary functions + using argument_type = _Arg; + using result_type = _Result; +}; + +template +struct binary_function { // base class for binary functions + using first_argument_type = _Arg1; + using second_argument_type = _Arg2; + using result_type = _Result; +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/limits.h b/engines/ags/std/limits.h new file mode 100644 index 000000000000..31e6cf6ad9ef --- /dev/null +++ b/engines/ags/std/limits.h @@ -0,0 +1,49 @@ +/* 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 + +#ifndef AGS_STD_LIMITS_H +#define AGS_STD_LIMITS_H + +namespace AGS3 { +namespace std { + +class _Num_base { +}; + +template +class numeric_limits : public _Num_base { +}; + +template <> +class numeric_limits { +public: + static constexpr float quiet_NaN() { + return NAN; + } +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/list.h b/engines/ags/std/list.h new file mode 100644 index 000000000000..5694dfc64aa3 --- /dev/null +++ b/engines/ags/std/list.h @@ -0,0 +1,77 @@ +/* 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 AGS_STD_LIST_H +#define AGS_STD_LIST_H + +#include "common/list.h" + +namespace AGS3 { +namespace std { + +template +class list : public Common::List { +public: + struct reverse_iterator { + private: + typename Common::List::iterator _it; + public: + reverse_iterator(typename Common::List::iterator it) : _it(it) { + } + reverse_iterator() { + } + + T operator*() const { + return *_it; + } + + reverse_iterator &operator++() { + --_it; + return *this; + } + + bool operator==(const reverse_iterator &rhs) { + return _it == rhs._it; + } + bool operator!=(const reverse_iterator &rhs) { + return _it != rhs._it; + } + }; +public: + typename Common::List::iterator insert(typename Common::List::iterator pos, + const T &element) { + Common::List::insert(pos, element); + return pos; + } + + reverse_iterator rbegin() { + return reverse_iterator(Common::List::reverse_begin()); + } + reverse_iterator rend() { + return reverse_iterator(Common::List::end()); + } +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/map.h b/engines/ags/std/map.h new file mode 100644 index 000000000000..5899948db30f --- /dev/null +++ b/engines/ags/std/map.h @@ -0,0 +1,53 @@ +/* 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 AGS_STD_MAP_H +#define AGS_STD_MAP_H + +#include "common/hashmap.h" +#include "ags/std/utility.h" + +namespace AGS3 { +namespace std { + +template, +class EqualFunc = Common::EqualTo > +class map : public Common::HashMap { +public: + void insert(pair elem) { + this->operator[](elem.first) = elem.second; + } +}; + +template, + class EqualFunc = Common::EqualTo > +class unordered_map : public Common::HashMap { +public: + void insert(pair elem) { + this->operator[](elem.first) = elem.second; + } +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/memory.h b/engines/ags/std/memory.h new file mode 100644 index 000000000000..c33d945d76c8 --- /dev/null +++ b/engines/ags/std/memory.h @@ -0,0 +1,44 @@ +/* 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 AGS_STD_MEMORY_H +#define AGS_STD_MEMORY_H + +#include "common/ptr.h" +#include "common/textconsole.h" + +namespace AGS3 { +namespace std { + +template +using shared_ptr = Common::SharedPtr; + +template +using weak_ptr = Common::WeakPtr; + +template > +using unique_ptr = Common::ScopedPtr; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/mutex.h b/engines/ags/std/mutex.h new file mode 100644 index 000000000000..4a3352d8f156 --- /dev/null +++ b/engines/ags/std/mutex.h @@ -0,0 +1,37 @@ +/* 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 AGS_STD_MUTEX_H +#define AGS_STD_MUTEX_H + +#include "common/mutex.h" + +namespace AGS3 { +namespace std { + +class recursive_mutex : public Common::Mutex { +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/set.h b/engines/ags/std/set.h new file mode 100644 index 000000000000..30b39c0421e6 --- /dev/null +++ b/engines/ags/std/set.h @@ -0,0 +1,123 @@ +/* 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 AGS_STD_SET_H +#define AGS_STD_SET_H + +namespace AGS3 { +namespace std { + +template +class set { + struct Comparitor { + bool operator()(const T &a, const T &b) const { + return a == b; + } + }; + + class Items : public Common::Array { + public: + void swap(Items &arr) { + SWAP(this->_capacity, arr._capacity); + SWAP(this->_size, arr._size); + SWAP(this->_storage, arr._storage); + } + }; +private: + Items _items; + Comparitor _comparitor; +public: + typedef T *iterator; + typedef const T *const_iterator; + + iterator begin() { return _items.begin(); } + iterator end() { return _items.end(); } + const_iterator begin() const { return _items.begin(); } + const_iterator end() const { return _items.end(); } + + /** + * Clear the set + */ + void clear() { + _items.clear(); + } + + /** + * Inserts a new item + */ + void insert(T val) { + _items.push_back(val); + Common::sort(begin(), end(), _comparitor); + } + + /** + * Inserts a range of items + */ + void insert(iterator first, iterator last) { + for (; first != last; ++first) + _items.push_back(*first); + Common::sort(begin(), end(), _comparitor); + } + + /** + * Swaps a set + */ + void swap(set &arr) { + _items.swap(arr); + } + + /** + * Find an item + */ + iterator find(const T item) { + iterator it = begin(); + for (; it != end() && *it != item; ++it) {} + return it; + } + const_iterator find(const T item) const { + const_iterator it = begin(); + for (; it != end() && *it != item; ++it) { + } + return it; + } + bool empty() const { + return _items.empty(); + } + + /** + * Returns the number of matching entries + */ + size_t count(const T item) const { + size_t total = 0; + for (const_iterator it = begin(); it != end(); ++it) { + if (*it == item) + ++total; + } + + return total; + } +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/thread.h b/engines/ags/std/thread.h new file mode 100644 index 000000000000..46be465c51bb --- /dev/null +++ b/engines/ags/std/thread.h @@ -0,0 +1,61 @@ +/* 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 AGS_STD_THREAD_H +#define AGS_STD_THREAD_H + +#include "common/textconsole.h" + +namespace AGS3 { +namespace std { + +class thread { +public: + template + explicit thread(_Fn &&_Fx, _Args &&... _Ax) { + warning("TODO: thread::constructor"); + } + + thread() { + warning("TODO: thread::constructor"); + } + + void join() { + warning("TODO: thread::join"); + } + bool joinable() const { + warning("TODO: thread::joinable"); + return true; + } +}; + +class this_thread { +public: + static void yield() { + warning("TODO: this_thread::yield"); + } +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/type_traits.h b/engines/ags/std/type_traits.h new file mode 100644 index 000000000000..564a663ce684 --- /dev/null +++ b/engines/ags/std/type_traits.h @@ -0,0 +1,51 @@ +/* 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 AGS_STD_TYPE_TRAITS_H +#define AGS_STD_TYPE_TRAITS_H + +namespace AGS3 { +namespace std { + +// STRUCT TEMPLATE remove_extent +template +struct remove_extent { // remove array extent + using type = _Ty; +}; + +template +struct remove_extent<_Ty[_Ix]> { + using type = _Ty; +}; + +template +struct remove_extent<_Ty[]> { + using type = _Ty; +}; + +template +using remove_extent_t = typename remove_extent<_Ty>::type; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/utility.h b/engines/ags/std/utility.h new file mode 100644 index 000000000000..241a332a98db --- /dev/null +++ b/engines/ags/std/utility.h @@ -0,0 +1,48 @@ +/* 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 AGS_STD_UTILITY_H +#define AGS_STD_UTILITY_H + +namespace AGS3 { +namespace std { + +template +struct pair { + T1 first; + T2 second; + + pair() { + } + pair(T1 first_, T2 second_) : first(first_), second(second_) { + } +}; + +template< class T1, class T2 > +pair make_pair(T1 first, T2 second) { + return pair(first, second); +} + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/vector.h b/engines/ags/std/vector.h new file mode 100644 index 000000000000..745fb20bd64d --- /dev/null +++ b/engines/ags/std/vector.h @@ -0,0 +1,173 @@ +/* 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 AGS_STD_VECTOR_H +#define AGS_STD_VECTOR_H + +#include "common/array.h" + +namespace AGS3 { +namespace std { + +template +class vector : public Common::Array { +public: + struct reverse_iterator { + private: + vector *_owner; + int _index; + public: + reverse_iterator(vector *owner, int index) : _owner(owner), _index(index) { + } + reverse_iterator() : _owner(0), _index(-1) { + } + + T &operator*() { + return (*_owner)[_index]; + } + + reverse_iterator &operator++() { + --_index; + return *this; + } + + bool operator==(const reverse_iterator &rhs) { + return _owner == rhs._owner && _index == rhs._index; + } + bool operator!=(const reverse_iterator &rhs) { + return !operator==(rhs); + } + }; + + struct const_reverse_iterator { + private: + const vector *_owner; + int _index; + public: + const_reverse_iterator(const vector *owner, int index) : _owner(owner), _index(index) { + } + const_reverse_iterator() : _owner(0), _index(-1) { + } + + const T operator*() const { + return (*_owner)[_index]; + } + + const_reverse_iterator &operator++() { + --_index; + return *this; + } + + bool operator==(const const_reverse_iterator &rhs) { + return _owner == rhs._owner && _index == rhs._index; + } + bool operator!=(const const_reverse_iterator &rhs) { + return !operator==(rhs); + } + }; +public: + typedef T reference; + typedef const T const_reference; + + vector() : Common::Array() { + } + vector(size_t newSize) : Common::Array() { + Common::Array::resize(newSize); + } + vector(size_t newSize, const T elem) { + resize(newSize, elem); + } + + typename Common::Array::iterator erase(typename Common::Array::iterator pos) { + return Common::Array::erase(pos); + } + + typename Common::Array::iterator erase(typename Common::Array::iterator first, + typename Common::Array::iterator last) { + Common::copy(last, this->_storage + this->_size, first); + + int count = (last - first); + this->_size -= count; + + // We also need to destroy the objects beyond the new size + for (uint idx = this->_size; idx < (this->_size + count); ++idx) + this->_storage[idx].~T(); + + return first; + } + + void swap(vector &arr) { + SWAP(this->_capacity, arr._capacity); + SWAP(this->_size, arr._size); + SWAP(this->_storage, arr._storage); + } + + /** + * Rotates the array so that the item pointed to by the iterator becomes + * the first item, and the predeceding item becomes the last one + */ + void rotate(Common::Array::iterator &it) { + if (it != Common::Array::end()) { + size_t count = it - Common::Array::begin(); + for (size_t ctr = 0; ctr < count; ++ctr) { + Common::Array::push_back(Common::Array::front()); + Common::Array::remove_at(0); + } + } + } + + reverse_iterator rbegin() { + return reverse_iterator(this, (int)Common::Array::size() - 1); + } + reverse_iterator rend() { + return reverse_iterator(this, -1); + } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(this, (int)Common::Array::size() - 1); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(this, -1); + } + + void pop_front() { + Common::Array::remove_at(0); + } + + void resize(size_t newSize) { + Common::Array::resize(newSize); + } + void resize(size_t newSize, const T elem) { + size_t oldSize = Common::Array::size(); + resize(newSize); + for (size_t idx = oldSize; idx < newSize; ++idx) + this->operator[](idx) = elem; + } + + T at(size_t index) const { + return (*this)[index]; + } +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/xutility.h b/engines/ags/std/xutility.h new file mode 100644 index 000000000000..ac5627fbdb0b --- /dev/null +++ b/engines/ags/std/xutility.h @@ -0,0 +1,34 @@ +/* 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 AGS_STD_XUTILITY_H +#define AGS_STD_XUTILITY_H + +#include "common/algorithm.h" + +namespace AGS3 { +namespace std { + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro.cpp b/engines/ags/stubs/allegro.cpp new file mode 100644 index 000000000000..44f7099b3017 --- /dev/null +++ b/engines/ags/stubs/allegro.cpp @@ -0,0 +1,34 @@ +/* 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 "ags/stubs/allegro.h" + +namespace AGS3 { + +int install_allegro() { + return 0; +} + +void allegro_exit() { +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro.h b/engines/ags/stubs/allegro.h new file mode 100644 index 000000000000..6d3aed6b22e4 --- /dev/null +++ b/engines/ags/stubs/allegro.h @@ -0,0 +1,49 @@ +/* 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 AGS_STUBS_ALLEGRO_H +#define AGS_STUBS_ALLEGRO_H + +#include "ags/stubs/allegro/alconfig.h" +#include "ags/stubs/allegro/base.h" +#include "ags/stubs/allegro/color.h" +#include "ags/stubs/allegro/config.h" +#include "ags/stubs/allegro/digi.h" +#include "ags/stubs/allegro/error.h" +#include "ags/stubs/allegro/file.h" +#include "ags/stubs/allegro/fixed.h" +#include "ags/stubs/allegro/gfx.h" +#include "ags/stubs/allegro/keyboard.h" +#include "ags/stubs/allegro/midi.h" +#include "ags/stubs/allegro/mouse.h" +#include "ags/stubs/allegro/sound.h" +#include "ags/stubs/allegro/system.h" +#include "ags/stubs/allegro/unicode.h" + +namespace AGS3 { + +extern int install_allegro(); +extern void allegro_exit(); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/alconfig.h b/engines/ags/stubs/allegro/alconfig.h new file mode 100644 index 000000000000..88a154b8ea7d --- /dev/null +++ b/engines/ags/stubs/allegro/alconfig.h @@ -0,0 +1,79 @@ +/* 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 AGS_STUBS_ALLEGRO_ALCONFIG_H +#define AGS_STUBS_ALLEGRO_ALCONFIG_H + +namespace AGS3 { + + +#ifndef INLINE +#define INLINE +#endif + +#ifndef RET_VOLATILE +#define RET_VOLATILE volatile +#endif + +#ifndef ZERO_SIZE_ARRAY +#define ZERO_SIZE_ARRAY(type, name) type name[] +#endif + +#ifndef AL_CONST +#define AL_CONST +#endif + +#ifndef AL_VAR +#define AL_VAR(type, name) extern type name +#endif + +#ifndef AL_ARRAY +#define AL_ARRAY(type, name) extern type name[] +#endif + +#ifndef AL_FUNC +#define AL_FUNC(type, name, args) type name args +#endif + +#ifndef AL_PRINTFUNC +#define AL_PRINTFUNC(type, name, args, a, b) AL_FUNC(type, name, args) +#endif + +#ifndef AL_METHOD +#define AL_METHOD(type, name, args) type (*name) args +#endif + +#ifndef AL_FUNCPTR +#define AL_FUNCPTR(type, name, args) extern type (*name) args +#endif + +#ifndef AL_FUNCPTRARRAY +#define AL_FUNCPTRARRAY(type, name, args) extern type (*name[]) args +#endif + +#ifndef AL_INLINE +#define AL_INLINE(type, name, args, code) type name args; +#endif + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/base.h b/engines/ags/stubs/allegro/base.h new file mode 100644 index 000000000000..cc08b5b518f0 --- /dev/null +++ b/engines/ags/stubs/allegro/base.h @@ -0,0 +1,60 @@ +/* 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 AGS_STUBS_ALLEGRO_BASE_H +#define AGS_STUBS_ALLEGRO_BASE_H + +#include "common/scummsys.h" +#include "common/algorithm.h" + +namespace AGS3 { + +#define ALLEGRO_VERSION 4 +#define ALLEGRO_SUB_VERSION 4 +#define ALLEGRO_WIP_VERSION 2 +#define ALLEGRO_VERSION_STR "4.4.2" +#define ALLEGRO_DATE_STR "2011" +#define ALLEGRO_DATE 20110519 /* yyyymmdd */ + +/* Returns the median of x, y, z */ +#define MID(x,y,z) ((x) > (y) ? ((y) > (z) ? (y) : ((x) > (z) ? \ + (z) : (x))) : ((y) > (z) ? ((z) > (x) ? (z) : \ + (x)): (y))) + +#define AL_ID MKTAG + +extern int *allegro_errno; + +/** + * info about a hardware driver + */ +struct _DRIVER_INFO { + int id; /* integer ID */ + void *driver; /* the driver structure */ + int autodetect; /* set to allow autodetection */ +}; + +#define AL_FUNC(type, name, args) type name args + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/color.cpp b/engines/ags/stubs/allegro/color.cpp new file mode 100644 index 000000000000..a69500e38717 --- /dev/null +++ b/engines/ags/stubs/allegro/color.cpp @@ -0,0 +1,68 @@ +/* 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 "ags/stubs/allegro/color.h" +#include "common/textconsole.h" +#include "common/system.h" +#include "graphics/palette.h" + +namespace AGS3 { + +int _rgb_r_shift_15 = 0; +int _rgb_g_shift_15 = 0; +int _rgb_b_shift_15 = 0; +int _rgb_r_shift_16 = 0; +int _rgb_g_shift_16 = 0; +int _rgb_b_shift_16 = 0; +int _rgb_r_shift_24 = 0; +int _rgb_g_shift_24 = 0; +int _rgb_b_shift_24 = 0; +int _rgb_r_shift_32 = 0; +int _rgb_g_shift_32 = 0; +int _rgb_b_shift_32 = 0; +int _rgb_a_shift_32 = 0; + +int bestfit_color(const PALETTE pal, int r, int g, int b) { + error("TODO: bestfit_color"); +} + +void set_color(int idx, const RGB *p) { + g_system->getPaletteManager()->setPalette((const byte *)p, idx, 1); +} + +void set_palette(const PALETTE p) { + +} + +void set_palette_range(const PALETTE p, int from, int to, int retracesync) { + byte palette[256 * 3]; + byte *destP = palette; + for (int i = 0; i < 256; ++i, destP += 3) { + destP[0] = p->r; + destP[1] = p->g; + destP[2] = p->b; + } + + g_system->getPaletteManager()->setPalette(&palette[from], from, to - from + 1); +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/color.h b/engines/ags/stubs/allegro/color.h new file mode 100644 index 000000000000..0785bd23cd83 --- /dev/null +++ b/engines/ags/stubs/allegro/color.h @@ -0,0 +1,66 @@ +/* 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 AGS_STUBS_ALLEGRO_COLOR_H +#define AGS_STUBS_ALLEGRO_COLOR_H + +#include "common/scummsys.h" +#include "ags/stubs/allegro/alconfig.h" + +namespace AGS3 { + +#include "common/pack-start.h" // START STRUCT PACKING + +struct color { + byte r, g, b; +} PACKED_STRUCT; + +typedef color RGB; +typedef color PALETTE[256]; + +#include "common/pack-end.h" // END STRUCT PACKING + +//define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) + +extern int bestfit_color(const PALETTE pal, int r, int g, int b); + +extern int _rgb_r_shift_15; +extern int _rgb_g_shift_15; +extern int _rgb_b_shift_15; +extern int _rgb_r_shift_16; +extern int _rgb_g_shift_16; +extern int _rgb_b_shift_16; +extern int _rgb_r_shift_24; +extern int _rgb_g_shift_24; +extern int _rgb_b_shift_24; +extern int _rgb_r_shift_32; +extern int _rgb_g_shift_32; +extern int _rgb_b_shift_32; +extern int _rgb_a_shift_32; + +AL_FUNC(void, set_color, (int idx, AL_CONST RGB *p)); +AL_FUNC(void, set_palette, (AL_CONST PALETTE p)); +AL_FUNC(void, set_palette_range, (AL_CONST PALETTE p, int from, int to, int retracesync)); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/config.cpp b/engines/ags/stubs/allegro/config.cpp new file mode 100644 index 000000000000..537f86e43949 --- /dev/null +++ b/engines/ags/stubs/allegro/config.cpp @@ -0,0 +1,32 @@ +/* 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 "ags/stubs/allegro/config.h" +#include "common/textconsole.h" + +namespace AGS3 { + +void override_config_data(const char *data, int length) { + // No implementation +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/config.h b/engines/ags/stubs/allegro/config.h new file mode 100644 index 000000000000..5695ea0eda17 --- /dev/null +++ b/engines/ags/stubs/allegro/config.h @@ -0,0 +1,32 @@ +/* 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 AGS_STUBS_ALLEGRO_CONFIG_H +#define AGS_STUBS_ALLEGRO_CONFIG_H + +namespace AGS3 { + +extern void override_config_data(const char *data, int length); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/digi.cpp b/engines/ags/stubs/allegro/digi.cpp new file mode 100644 index 000000000000..07ba5ecfdaa4 --- /dev/null +++ b/engines/ags/stubs/allegro/digi.cpp @@ -0,0 +1,40 @@ +/* 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 "ags/stubs/allegro/digi.h" + +namespace AGS3 { + +DIGI_DRIVER *digi_driver; + +DIGI_DRIVER *digi_input_driver; + +int digi_card; + +int digi_input_card; + + +int detect_digi_driver(int driver_id) { + return 0; +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/digi.h b/engines/ags/stubs/allegro/digi.h new file mode 100644 index 000000000000..78f41cadee99 --- /dev/null +++ b/engines/ags/stubs/allegro/digi.h @@ -0,0 +1,145 @@ +/* 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 AGS_STUBS_ALLEGRO_DIGI_H +#define AGS_STUBS_ALLEGRO_DIGI_H + +#include "common/scummsys.h" +#include "ags/stubs/allegro/base.h" +#include "ags/stubs/allegro/alconfig.h" + +namespace AGS3 { + + +#define DIGI_VOICES 64 /* Theoretical maximums: */ +/* actual drivers may not be */ +/* able to handle this many */ + +/* a sample */ +struct SAMPLE { + int bits; /* 8 or 16 */ + int stereo; /* sample type flag */ + int freq; /* sample frequency */ + int priority; /* 0-255 */ + unsigned long len; /* length (in samples) */ + unsigned long loop_start; /* loop start position */ + unsigned long loop_end; /* loop finish position */ + unsigned long param; /* for internal use by the driver */ + void *data; /* sample data */ +}; + + +#define DIGI_AUTODETECT -1 /* for passing to install_sound() */ +#define DIGI_NONE 0 + +/* driver for playing digital sfx */ +struct DIGI_DRIVER { + int id; /* driver ID code */ + AL_CONST char *name; /* driver name */ + AL_CONST char *desc; /* description string */ + AL_CONST char *ascii_name; /* ASCII format name string */ + int voices; /* available voices */ + int basevoice; /* voice number offset */ + int max_voices; /* maximum voices we can support */ + int def_voices; /* default number of voices to use */ + + /* setup routines */ + AL_METHOD(int, detect, (int input)); + AL_METHOD(int, init, (int input, int voices)); + AL_METHOD(void, exit, (int input)); + AL_METHOD(int, set_mixer_volume, (int volume)); + AL_METHOD(int, get_mixer_volume, (void)); + + /* for use by the audiostream functions */ + AL_METHOD(void *, lock_voice, (int voice, int start, int end)); + AL_METHOD(void, unlock_voice, (int voice)); + AL_METHOD(int, buffer_size, (void)); + + /* voice control functions */ + AL_METHOD(void, init_voice, (int voice, AL_CONST SAMPLE *sample)); + AL_METHOD(void, release_voice, (int voice)); + AL_METHOD(void, start_voice, (int voice)); + AL_METHOD(void, stop_voice, (int voice)); + AL_METHOD(void, loop_voice, (int voice, int playmode)); + + /* position control functions */ + AL_METHOD(int, get_position, (int voice)); + AL_METHOD(void, set_position, (int voice, int position)); + + /* volume control functions */ + AL_METHOD(int, get_volume, (int voice)); + AL_METHOD(void, set_volume, (int voice, int volume)); + AL_METHOD(void, ramp_volume, (int voice, int tyme, int endvol)); + AL_METHOD(void, stop_volume_ramp, (int voice)); + + /* pitch control functions */ + AL_METHOD(int, get_frequency, (int voice)); + AL_METHOD(void, set_frequency, (int voice, int frequency)); + AL_METHOD(void, sweep_frequency, (int voice, int tyme, int endfreq)); + AL_METHOD(void, stop_frequency_sweep, (int voice)); + + /* pan control functions */ + AL_METHOD(int, get_pan, (int voice)); + AL_METHOD(void, set_pan, (int voice, int pan)); + AL_METHOD(void, sweep_pan, (int voice, int tyme, int endpan)); + AL_METHOD(void, stop_pan_sweep, (int voice)); + + /* effect control functions */ + AL_METHOD(void, set_echo, (int voice, int strength, int delay)); + AL_METHOD(void, set_tremolo, (int voice, int rate, int depth)); + AL_METHOD(void, set_vibrato, (int voice, int rate, int depth)); + + /* input functions */ + int rec_cap_bits; + int rec_cap_stereo; + AL_METHOD(int, rec_cap_rate, (int bits, int stereo)); + AL_METHOD(int, rec_cap_parm, (int rate, int bits, int stereo)); + AL_METHOD(int, rec_source, (int source)); + AL_METHOD(int, rec_start, (int rate, int bits, int stereo)); + AL_METHOD(void, rec_stop, (void)); + AL_METHOD(int, rec_read, (void *buf)); +}; + +AL_ARRAY(_DRIVER_INFO, _digi_driver_list); + +/* macros for constructing the driver lists */ +#define BEGIN_DIGI_DRIVER_LIST \ + _DRIVER_INFO _digi_driver_list[] = \ + { + +#define END_DIGI_DRIVER_LIST \ + { 0, nullptr, 0 } \ + }; + +AL_VAR(DIGI_DRIVER *, digi_driver); + +AL_VAR(DIGI_DRIVER *, digi_input_driver); + +AL_VAR(int, digi_card); + +AL_VAR(int, digi_input_card); + +AL_FUNC(int, detect_digi_driver, (int driver_id)); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/error.cpp b/engines/ags/stubs/allegro/error.cpp new file mode 100644 index 000000000000..b25496e834a5 --- /dev/null +++ b/engines/ags/stubs/allegro/error.cpp @@ -0,0 +1,28 @@ +/* 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 AGS3 { + +static int allegro_error; +extern int *allegro_errno = &allegro_error; + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/error.h b/engines/ags/stubs/allegro/error.h new file mode 100644 index 000000000000..46d3e03fdeaf --- /dev/null +++ b/engines/ags/stubs/allegro/error.h @@ -0,0 +1,82 @@ +/* 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 AGS_STUBS_ALLEGRO_ERROR_H +#define AGS_STUBS_ALLEGRO_ERROR_H + +#include "common/scummsys.h" + +namespace AGS3 { + + + +// Error codes +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define EDEADLK 36 +#define ENAMETOOLONG 38 +#define ENOLCK 39 +#define ENOSYS 40 +#define ENOTEMPTY 41 + +// Error codes used in the Secure CRT functions +#ifndef RC_INVOKED +#define _SECURECRT_ERRCODE_VALUES_DEFINED +#define EINVAL 22 +#define ERANGE 34 +#define EILSEQ 42 +#define STRUNCATE 80 +#endif + +extern int *allegro_errno; + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/file.cpp b/engines/ags/stubs/allegro/file.cpp new file mode 100644 index 000000000000..ad121f296b98 --- /dev/null +++ b/engines/ags/stubs/allegro/file.cpp @@ -0,0 +1,57 @@ +/* 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 "ags/stubs/allegro/file.h" +#include "common/str.h" + +namespace AGS3 { + +char *fix_filename_case(char *path) { + return path; +} + +char *fix_filename_slashes(char *path) { + return path; +} + +char *append_filename(char *dest, const char *path, const char *filename, int size) { + strncpy(dest, path, size); + strncat(dest, filename, size); + return dest; +} + +char *canonicalize_filename(char *dest, const char *filename, int size) { + strncpy(dest, filename, size); + return dest; +} + +char *make_relative_filename(char *dest, const char *path, const char *filename, int size) { + strncpy(dest, filename, size); + return dest; +} + +int is_relative_filename(const char *filename) { + Common::String fname(filename); + return !fname.contains('/') && !fname.contains('\\') ? 0 : -1; +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/file.h b/engines/ags/stubs/allegro/file.h new file mode 100644 index 000000000000..083e8d1db36d --- /dev/null +++ b/engines/ags/stubs/allegro/file.h @@ -0,0 +1,42 @@ +/* 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 AGS_STUBS_ALLEGRO_FILE_H +#define AGS_STUBS_ALLEGRO_FILE_H + +namespace AGS3 { + +struct PACKFILE { + // TODO: PACKFILE handling + int dummy; +}; + +extern char *fix_filename_case(char *path); +extern char *fix_filename_slashes(char *path); +extern char *append_filename(char *dest, const char *path, const char *filename, int size); +extern char *canonicalize_filename(char *dest, const char *filename, int size); +extern char *make_relative_filename(char *dest, const char *path, const char *filename, int size); +extern int is_relative_filename(const char *filename); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/fixed.cpp b/engines/ags/stubs/allegro/fixed.cpp new file mode 100644 index 000000000000..a6923e58ec04 --- /dev/null +++ b/engines/ags/stubs/allegro/fixed.cpp @@ -0,0 +1,178 @@ +/* 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 "ags/stubs/allegro/fixed.h" +#include "ags/stubs/allegro/error.h" + +namespace AGS3 { + +fixed fixtorad_r; +fixed radtofix_r; + +fixed ftofix(double x) { + if (x > 32767.0) { + *allegro_errno = ERANGE; + return 0x7FFFFFFF; + } + + if (x < -32767.0) { + *allegro_errno = ERANGE; + return (fixed)-0x7FFFFFFF; + } + + return (fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); +} + +double fixtof(fixed x) { + return (double)x / 65536.0; +} + +fixed fixadd(fixed x, fixed y) { + fixed result = x + y; + + if (result >= 0) { + if ((x < 0) && (y < 0)) { + *allegro_errno = ERANGE; + return (fixed)-0x7FFFFFFF; + } + else + return result; + } + else { + if ((x > 0) && (y > 0)) { + *allegro_errno = ERANGE; + return 0x7FFFFFFF; + } + else + return result; + } +} + +fixed fixsub(fixed x, fixed y) { + fixed result = x - y; + + if (result >= 0) { + if ((x < 0) && (y > 0)) { + *allegro_errno = ERANGE; + return (fixed)-0x7FFFFFFF; + } + else + return result; + } + else { + if ((x > 0) && (y < 0)) { + *allegro_errno = ERANGE; + return 0x7FFFFFFF; + } + else + return result; + } +} + +fixed fixmul(fixed x, fixed y) { + int64 lx = x; + int64 ly = y; + int64 lres = (lx * ly); + + if (lres > 0x7FFFFFFF0000LL) { + *allegro_errno = ERANGE; + return 0x7FFFFFFF; + } else if (lres < -0x7FFFFFFF0000LL) { + *allegro_errno = ERANGE; + return 0x80000000; + } else { + int res = lres >> 16; + return res; + } +} + +fixed fixdiv(fixed x, fixed y) { + if (y == 0) { + *allegro_errno = ERANGE; + return (fixed)(x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF; + } else + return ftofix(fixtof(x) / fixtof(y)); +} + +int fixfloor(fixed x) { + /* (x >> 16) is not portable */ + if (x >= 0) + return (x >> 16); + else + return ~((~x) >> 16); +} + + +int fixceil(fixed x) { + if (x > 0x7FFF0000) { + *allegro_errno = ERANGE; + return 0x7FFF; + } + + return fixfloor(x + 0xFFFF); +} + +fixed itofix(int x) { + return x << 16; +} + + +int fixtoi(fixed x) { + return fixfloor(x) + ((x & 0x8000) >> 15); +} + + +fixed fixcos(fixed x) { + return _cos_tbl[((x + 0x4000) >> 15) & 0x1FF]; +} + + +fixed fixsin(fixed x) { + return _cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF]; +} + + +fixed fixtan(fixed x) { + return _tan_tbl[((x + 0x4000) >> 15) & 0xFF]; +} + + +fixed fixacos(fixed x) { + if ((x < -65536) || (x > 65536)) { + *allegro_errno = EDOM; + return 0; + } + + return _acos_tbl[(x + 65536 + 127) >> 8]; +} + + +fixed fixasin(fixed x) { + if ((x < -65536) || (x > 65536)) { + *allegro_errno = EDOM; + return 0; + } + + return 0x00400000 - _acos_tbl[(x + 65536 + 127) >> 8]; +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/fixed.h b/engines/ags/stubs/allegro/fixed.h new file mode 100644 index 000000000000..45acd42c990b --- /dev/null +++ b/engines/ags/stubs/allegro/fixed.h @@ -0,0 +1,63 @@ +/* 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 AGS_STUBS_ALLEGRO_FIXED_H +#define AGS_STUBS_ALLEGRO_FIXED_H + +#include "common/scummsys.h" + +namespace AGS3 { + +typedef uint32 fixed; + +extern fixed fixtorad_r; +extern fixed radtofix_r; +extern fixed _cos_tbl[]; +extern fixed _tan_tbl[]; +extern fixed _acos_tbl[]; + +extern fixed ftofix(double x); +extern double fixtof(fixed x); +extern fixed fixadd(fixed x, fixed y); +extern fixed fixsub(fixed x, fixed y); +extern fixed fixmul(fixed x, fixed y); +extern fixed fixdiv(fixed x, fixed y); +extern int fixfloor(fixed x); +extern int fixceil(fixed x); +extern fixed itofix(int x); +extern int fixtoi(fixed x); +extern fixed fixcos(fixed x); +extern fixed fixsin(fixed x); +extern fixed fixtan(fixed x); +extern fixed fixacos(fixed x); +extern fixed fixasin(fixed x); + +#if 0 +extern fixed fixsqrt(fixed x); +extern fixed fixhypot(fixed x, fixed y); +extern fixed fixatan(fixed x); +extern fixed fixatan2(fixed y, fixed x); +#endif + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/gfx.cpp b/engines/ags/stubs/allegro/gfx.cpp new file mode 100644 index 000000000000..799e42a07dbc --- /dev/null +++ b/engines/ags/stubs/allegro/gfx.cpp @@ -0,0 +1,43 @@ +/* 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 "ags/stubs/allegro/gfx.h" +#include "common/textconsole.h" + +namespace AGS3 { + +int color_conversion; + +void set_color_conversion(int mode) { + color_conversion = mode; +} + +int get_color_conversion() { + return color_conversion; +} + +int set_gfx_mode(int card, int w, int h, int v_w, int v_h) { + error("TODO: set_gfx_mode"); +} + + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/gfx.h b/engines/ags/stubs/allegro/gfx.h new file mode 100644 index 000000000000..a3e15eaa8c17 --- /dev/null +++ b/engines/ags/stubs/allegro/gfx.h @@ -0,0 +1,176 @@ +/* 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 AGS_STUBS_ALLEGRO_GRAPHICS_H +#define AGS_STUBS_ALLEGRO_GRAPHICS_H + +#include "graphics/managed_surface.h" +#include "ags/stubs/allegro/base.h" + +namespace AGS3 { + +#define GFX_TEXT -1 +#define GFX_AUTODETECT 0 +#define GFX_AUTODETECT_FULLSCREEN 1 +#define GFX_AUTODETECT_WINDOWED 2 +#define GFX_SAFE AL_ID('S','A','F','E') +#define GFX_NONE AL_ID('N','O','N','E') + +/* drawing modes for draw_sprite_ex() */ +#define DRAW_SPRITE_NORMAL 0 +#define DRAW_SPRITE_LIT 1 +#define DRAW_SPRITE_TRANS 2 + +/* flipping modes for draw_sprite_ex() */ +#define DRAW_SPRITE_NO_FLIP 0x0 +#define DRAW_SPRITE_H_FLIP 0x1 +#define DRAW_SPRITE_V_FLIP 0x2 +#define DRAW_SPRITE_VH_FLIP 0x3 + +/* Blender mode defines, for the gfx_driver->set_blender_mode() function */ +#define blender_mode_none 0 +#define blender_mode_trans 1 +#define blender_mode_add 2 +#define blender_mode_burn 3 +#define blender_mode_color 4 +#define blender_mode_difference 5 +#define blender_mode_dissolve 6 +#define blender_mode_dodge 7 +#define blender_mode_hue 8 +#define blender_mode_invert 9 +#define blender_mode_luminance 10 +#define blender_mode_multiply 11 +#define blender_mode_saturation 12 +#define blender_mode_screen 13 +#define blender_mode_alpha 14 + + +#define SCREEN_W (gfx_driver ? gfx_driver->w : 0) +#define SCREEN_H (gfx_driver ? gfx_driver->h : 0) + +#define VIRTUAL_W (screen ? screen->w : 0) +#define VIRTUAL_H (screen ? screen->h : 0) + +#define COLORCONV_NONE 0 + +#define COLORCONV_8_TO_15 1 +#define COLORCONV_8_TO_16 2 +#define COLORCONV_8_TO_24 4 +#define COLORCONV_8_TO_32 8 + +#define COLORCONV_15_TO_8 0x10 +#define COLORCONV_15_TO_16 0x20 +#define COLORCONV_15_TO_24 0x40 +#define COLORCONV_15_TO_32 0x80 + +#define COLORCONV_16_TO_8 0x100 +#define COLORCONV_16_TO_15 0x200 +#define COLORCONV_16_TO_24 0x400 +#define COLORCONV_16_TO_32 0x800 + +#define COLORCONV_24_TO_8 0x1000 +#define COLORCONV_24_TO_15 0x2000 +#define COLORCONV_24_TO_16 0x4000 +#define COLORCONV_24_TO_32 0x8000 + +#define COLORCONV_32_TO_8 0x10000 +#define COLORCONV_32_TO_15 0x20000 +#define COLORCONV_32_TO_16 0x40000 +#define COLORCONV_32_TO_24 0x80000 + +#define COLORCONV_32A_TO_8 0x100000 +#define COLORCONV_32A_TO_15 0x200000 +#define COLORCONV_32A_TO_16 0x400000 +#define COLORCONV_32A_TO_24 0x800000 + +#define COLORCONV_DITHER_PAL 0x1000000 +#define COLORCONV_DITHER_HI 0x2000000 +#define COLORCONV_KEEP_TRANS 0x4000000 + +#define COLORCONV_DITHER (COLORCONV_DITHER_PAL | \ + COLORCONV_DITHER_HI) + +#define COLORCONV_EXPAND_256 (COLORCONV_8_TO_15 | \ + COLORCONV_8_TO_16 | \ + COLORCONV_8_TO_24 | \ + COLORCONV_8_TO_32) + +#define COLORCONV_REDUCE_TO_256 (COLORCONV_15_TO_8 | \ + COLORCONV_16_TO_8 | \ + COLORCONV_24_TO_8 | \ + COLORCONV_32_TO_8 | \ + COLORCONV_32A_TO_8) + +#define COLORCONV_EXPAND_15_TO_16 COLORCONV_15_TO_16 + +#define COLORCONV_REDUCE_16_TO_15 COLORCONV_16_TO_15 + +#define COLORCONV_EXPAND_HI_TO_TRUE (COLORCONV_15_TO_24 | \ + COLORCONV_15_TO_32 | \ + COLORCONV_16_TO_24 | \ + COLORCONV_16_TO_32) + +#define COLORCONV_REDUCE_TRUE_TO_HI (COLORCONV_24_TO_15 | \ + COLORCONV_24_TO_16 | \ + COLORCONV_32_TO_15 | \ + COLORCONV_32_TO_16) + +#define COLORCONV_24_EQUALS_32 (COLORCONV_24_TO_32 | \ + COLORCONV_32_TO_24) + +#define COLORCONV_TOTAL (COLORCONV_EXPAND_256 | \ + COLORCONV_REDUCE_TO_256 | \ + COLORCONV_EXPAND_15_TO_16 | \ + COLORCONV_REDUCE_16_TO_15 | \ + COLORCONV_EXPAND_HI_TO_TRUE | \ + COLORCONV_REDUCE_TRUE_TO_HI | \ + COLORCONV_24_EQUALS_32 | \ + COLORCONV_32A_TO_15 | \ + COLORCONV_32A_TO_16 | \ + COLORCONV_32A_TO_24) + +#define COLORCONV_PARTIAL (COLORCONV_EXPAND_15_TO_16 | \ + COLORCONV_REDUCE_16_TO_15 | \ + COLORCONV_24_EQUALS_32) + +#define COLORCONV_MOST (COLORCONV_EXPAND_15_TO_16 | \ + COLORCONV_REDUCE_16_TO_15 | \ + COLORCONV_EXPAND_HI_TO_TRUE | \ + COLORCONV_REDUCE_TRUE_TO_HI | \ + COLORCONV_24_EQUALS_32) + +#define COLORCONV_KEEP_ALPHA (COLORCONV_TOTAL \ + & ~(COLORCONV_32A_TO_8 | \ + COLORCONV_32A_TO_15 | \ + COLORCONV_32A_TO_16 | \ + COLORCONV_32A_TO_24)) + +class BITMAP : public Graphics::ManagedSurface { +}; + +AL_FUNC(void, set_color_conversion, (int mode)); +AL_FUNC(int, get_color_conversion, ()); +AL_FUNC(int, set_gfx_mode, (int card, int w, int h, int v_w, int v_h)); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/keyboard.cpp b/engines/ags/stubs/allegro/keyboard.cpp new file mode 100644 index 000000000000..ba014a85f521 --- /dev/null +++ b/engines/ags/stubs/allegro/keyboard.cpp @@ -0,0 +1,39 @@ +/* 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 "ags/stubs/allegro/keyboard.h" +#include "common/algorithm.h" +#include "common/textconsole.h" + +namespace AGS3 { + +bool key[Common::KEYCODE_LAST]; + +int install_keyboard() { + Common::fill(&key[0], &key[Common::KEYCODE_LAST], false); + return 0; +} + +void remove_keyboard() { +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/keyboard.h b/engines/ags/stubs/allegro/keyboard.h new file mode 100644 index 000000000000..8f8d0da14fb1 --- /dev/null +++ b/engines/ags/stubs/allegro/keyboard.h @@ -0,0 +1,105 @@ +/* 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 AGS_STUBS_ALLEGRO_KEYBOARD_H +#define AGS_STUBS_ALLEGRO_KEYBOARD_H + +#include "common/keyboard.h" + +namespace AGS3 { + +#define KB_SHIFT_FLAG Common::KBD_SHIFT +#define KB_CTRL_FLAG Common::KBD_CTRL +#define KB_ALT_FLAG Common::KBD_ALT + +#define KEY_F9 Common::KEYCODE_F9 +#define KEY_LCONTROL Common::KEYCODE_LCTRL +#define KEY_RCONTROL Common::KEYCODE_RCTRL + +#define __allegro_KEY_LSHIFT Common::KEYCODE_LSHIFT +#define __allegro_KEY_RSHIFT Common::KEYCODE_RSHIFT +#define __allegro_KEY_LCONTROL Common::KEYCODE_LCTRL +#define __allegro_KEY_RCONTROL Common::KEYCODE_RCTRL +#define __allegro_KEY_ALT Common::KEYCODE_LALT + +#define __allegro_KEY_F1 Common::KEYCODE_F1 +#define __allegro_KEY_F2 Common::KEYCODE_F2 +#define __allegro_KEY_F3 Common::KEYCODE_F3 +#define __allegro_KEY_F4 Common::KEYCODE_F4 +#define __allegro_KEY_F5 Common::KEYCODE_F5 +#define __allegro_KEY_F6 Common::KEYCODE_F6 +#define __allegro_KEY_F7 Common::KEYCODE_F7 +#define __allegro_KEY_F8 Common::KEYCODE_F8 +#define __allegro_KEY_F9 Common::KEYCODE_F9 +#define __allegro_KEY_F10 Common::KEYCODE_F10 +#define __allegro_KEY_F11 Common::KEYCODE_F11 +#define __allegro_KEY_F12 Common::KEYCODE_F12 + +#define __allegro_KEY_HOME Common::KEYCODE_HOME +#define __allegro_KEY_UP Common::KEYCODE_UP +#define __allegro_KEY_PGUP Common::KEYCODE_PAGEUP +#define __allegro_KEY_LEFT Common::KEYCODE_LEFT +#define __allegro_KEY_RIGHT Common::KEYCODE_RIGHT +#define __allegro_KEY_END Common::KEYCODE_END +#define __allegro_KEY_DOWN Common::KEYCODE_DOWN +#define __allegro_KEY_PGDN Common::KEYCODE_PAGEDOWN +#define __allegro_KEY_INSERT Common::KEYCODE_INSERT +#define __allegro_KEY_DEL Common::KEYCODE_DELETE + +#define __allegro_KEY_0_PAD Common::KEYCODE_KP0 +#define __allegro_KEY_1_PAD Common::KEYCODE_KP1 +#define __allegro_KEY_2_PAD Common::KEYCODE_KP2 +#define __allegro_KEY_3_PAD Common::KEYCODE_KP3 +#define __allegro_KEY_4_PAD Common::KEYCODE_KP4 +#define __allegro_KEY_5_PAD Common::KEYCODE_KP5 +#define __allegro_KEY_6_PAD Common::KEYCODE_KP6 +#define __allegro_KEY_7_PAD Common::KEYCODE_KP7 +#define __allegro_KEY_8_PAD Common::KEYCODE_KP8 +#define __allegro_KEY_9_PAD Common::KEYCODE_KP9 +#define __allegro_KEY_DEL_PAD Common::KEYCODE_KP_PERIOD + +#define __allegro_KEY_PRTSCR Common::KEYCODE_PRINT +#define __allegro_KEY_PAUSE Common::KEYCODE_PAUSE +#define __allegro_KEY_ABNT_C1 94 +#define __allegro_KEY_YEN 95 +#define __allegro_KEY_KANA 96 +#define __allegro_KEY_CONVERT 97 +#define __allegro_KEY_NOCONVERT 98 +#define __allegro_KEY_CIRCUMFLEX 100 +#define __allegro_KEY_KANJI 102 +#define __allegro_KEY_ALTGR 120 +#define __allegro_KEY_LWIN Common::KEYCODE_LMETA +#define __allegro_KEY_RWIN Common::KEYCODE_RMETA +#define __allegro_KEY_MENU 123 +#define __allegro_KEY_SCRLOCK Common::KEYCODE_SCROLLOCK +#define __allegro_KEY_NUMLOCK Common::KEYCODE_NUMLOCK +#define __allegro_KEY_CAPSLOCK Common::KEYCODE_CAPSLOCK + + +extern bool key[Common::KEYCODE_LAST]; + +extern int install_keyboard(); +extern void remove_keyboard(); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/midi.cpp b/engines/ags/stubs/allegro/midi.cpp new file mode 100644 index 000000000000..d0bab8025489 --- /dev/null +++ b/engines/ags/stubs/allegro/midi.cpp @@ -0,0 +1,46 @@ +/* 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 "ags/stubs/allegro/midi.h" + +namespace AGS3 { + +MIDI_DRIVER *midi_driver; + +MIDI_DRIVER *midi_input_driver; + +int midi_card; + +int midi_input_card; + +volatile long midi_pos; /* current position in the midi file, in beats */ +volatile long midi_time; /* current position in the midi file, in seconds */ + +long midi_loop_start; /* where to loop back to at EOF */ +long midi_loop_end; /* loop when we hit this position */ + + +int detect_midi_driver(int driver_id) { + return 0; +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/midi.h b/engines/ags/stubs/allegro/midi.h new file mode 100644 index 000000000000..8925ac653b6a --- /dev/null +++ b/engines/ags/stubs/allegro/midi.h @@ -0,0 +1,123 @@ +/* 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 AGS_STUBS_ALLEGRO_MIDI_H +#define AGS_STUBS_ALLEGRO_MIDI_H + +#include "common/scummsys.h" +#include "ags/stubs/allegro/base.h" +#include "ags/stubs/allegro/alconfig.h" + +namespace AGS3 { + +/* Theoretical maximums: */ +#define MIDI_VOICES 64 /* actual drivers may not be */ +#define MIDI_TRACKS 32 /* able to handle this many */ + +/* a midi file */ +struct MIDI { + int divisions; /* number of ticks per quarter note */ + struct { + unsigned char *data; /* MIDI message stream */ + int len; /* length of the track data */ + } track[MIDI_TRACKS]; +}; + + +#define MIDI_AUTODETECT -1 +#define MIDI_NONE 0 +#define MIDI_DIGMID AL_ID('D','I','G','I') + +/* driver for playing midi music */ +struct MIDI_DRIVER { + int id; /* driver ID code */ + AL_CONST char *name; /* driver name */ + AL_CONST char *desc; /* description string */ + AL_CONST char *ascii_name; /* ASCII format name string */ + int voices; /* available voices */ + int basevoice; /* voice number offset */ + int max_voices; /* maximum voices we can support */ + int def_voices; /* default number of voices to use */ + int xmin, xmax; /* reserved voice range */ + + /* setup routines */ + AL_METHOD(int, detect, (int input)); + AL_METHOD(int, init, (int input, int voices)); + AL_METHOD(void, exit, (int input)); + AL_METHOD(int, set_mixer_volume, (int volume)); + AL_METHOD(int, get_mixer_volume, (void)); + + /* raw MIDI output to MPU-401, etc. */ + AL_METHOD(void, raw_midi, (int data)); + + /* dynamic patch loading routines */ + AL_METHOD(int, load_patches, (AL_CONST char *patches, AL_CONST char *drums)); + AL_METHOD(void, adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); + + /* note control functions */ + AL_METHOD(void, key_on, (int inst, int note, int bend, int vol, int pan)); + AL_METHOD(void, key_off, (int voice)); + AL_METHOD(void, set_volume, (int voice, int vol)); + AL_METHOD(void, set_pitch, (int voice, int note, int bend)); + AL_METHOD(void, set_pan, (int voice, int pan)); + AL_METHOD(void, set_vibrato, (int voice, int amount)); +}; + + +AL_VAR(MIDI_DRIVER, midi_digmid); + +AL_ARRAY(_DRIVER_INFO, _midi_driver_list); + + +/* macros for constructing the driver lists */ +#define BEGIN_MIDI_DRIVER_LIST \ + _DRIVER_INFO _midi_driver_list[] = \ + { + +#define END_MIDI_DRIVER_LIST \ + { 0, NULL, 0 } \ + }; + +#define MIDI_DRIVER_DIGMID \ + { MIDI_DIGMID, &midi_digmid, TRUE }, + + +AL_VAR(MIDI_DRIVER *, midi_driver); + +AL_VAR(MIDI_DRIVER *, midi_input_driver); + +AL_VAR(int, midi_card); + +AL_VAR(int, midi_input_card); + +AL_VAR(volatile long, midi_pos); /* current position in the midi file, in beats */ +AL_VAR(volatile long, midi_time); /* current position in the midi file, in seconds */ + +AL_VAR(long, midi_loop_start); /* where to loop back to at EOF */ +AL_VAR(long, midi_loop_end); /* loop when we hit this position */ + + +AL_FUNC(int, detect_midi_driver, (int driver_id)); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/mouse.cpp b/engines/ags/stubs/allegro/mouse.cpp new file mode 100644 index 000000000000..c8bad8476f2b --- /dev/null +++ b/engines/ags/stubs/allegro/mouse.cpp @@ -0,0 +1,116 @@ +/* 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 "ags/stubs/allegro/mouse.h" +#include "common/textconsole.h" + +namespace AGS3 { + +MOUSE_DRIVER mousedrv_none; +MOUSE_DRIVER *mouse_driver; +_DRIVER_INFO _mouse_driver_list[]; + +BITMAP *mouse_sprite; +int mouse_x_focus; +int mouse_y_focus; + +volatile int mouse_x; +volatile int mouse_y; +volatile int mouse_z; +volatile int mouse_w; +volatile int mouse_b; +volatile int mouse_pos; + +volatile int freeze_mouse_flag; + +int install_mouse() { + return 0; +} + +void remove_mouse() { +} + +int poll_mouse() { + return 0; +} + +int mouse_needs_poll() { + return 0; +} + +void enable_hardware_cursor() { +} + +void disable_hardware_cursor() { +} + +void show_mouse(BITMAP *bmp) { +} + +void scare_mouse() { +} + +void scare_mouse_area(int x, int y, int w, int h) { +} + +void unscare_mouse() { +} + +void position_mouse(int x, int y) { +} + +void position_mouse_z(int z) { +} + +void position_mouse_w(int w) { +} + +void set_mouse_range(int x1, int y_1, int x2, int y2) { +} + +void set_mouse_speed(int xspeed, int yspeed) { +} + +void select_mouse_cursor(int cursor) { +} + +void set_mouse_cursor_bitmap(int cursor, BITMAP *bmp) { +} + +void set_mouse_sprite_focus(int x, int y) { +} + +void get_mouse_mickeys(int *mickeyx, int *mickeyy) { +} + +void set_mouse_sprite(BITMAP *sprite) { +} + +int show_os_cursor(int cursor) { + return 0; +} + +int mouse_on_screen() { + return 0; +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/mouse.h b/engines/ags/stubs/allegro/mouse.h new file mode 100644 index 000000000000..33538fac929b --- /dev/null +++ b/engines/ags/stubs/allegro/mouse.h @@ -0,0 +1,120 @@ +/* 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 AGS_STUBS_ALLEGRO_MOUSE_H +#define AGS_STUBS_ALLEGRO_MOUSE_H + +#include "common/events.h" +#include "ags/stubs/allegro/base.h" +#include "ags/stubs/allegro/alconfig.h" +#include "ags/stubs/allegro/gfx.h" + +namespace AGS3 { + +#define MOUSEDRV_AUTODETECT -1 +#define MOUSEDRV_NONE 0 + +struct MOUSE_DRIVER { + int id; + AL_CONST char *name; + AL_CONST char *desc; + AL_CONST char *ascii_name; + AL_METHOD(int, init, (void)); + AL_METHOD(void, exit, (void)); + AL_METHOD(void, poll, (void)); + AL_METHOD(void, timer_poll, (void)); + AL_METHOD(void, position, (int x, int y)); + AL_METHOD(void, set_range, (int x1, int y_1, int x2, int y2)); + AL_METHOD(void, set_speed, (int xspeed, int yspeed)); + AL_METHOD(void, get_mickeys, (int *mickeyx, int *mickeyy)); + AL_METHOD(int, analyse_data, (AL_CONST char *buffer, int size)); + AL_METHOD(void, enable_hardware_cursor, (int mode)); + AL_METHOD(int, select_system_cursor, (int cursor)); +}; + +AL_VAR(MOUSE_DRIVER, mousedrv_none); +AL_VAR(MOUSE_DRIVER *, mouse_driver); +AL_ARRAY(_DRIVER_INFO, _mouse_driver_list); + +AL_FUNC(int, install_mouse, (void)); +AL_FUNC(void, remove_mouse, (void)); + +AL_FUNC(int, poll_mouse, (void)); +AL_FUNC(int, mouse_needs_poll, (void)); + +AL_FUNC(void, enable_hardware_cursor, (void)); +AL_FUNC(void, disable_hardware_cursor, (void)); + +/* Mouse cursors */ +#define MOUSE_CURSOR_NONE 0 +#define MOUSE_CURSOR_ALLEGRO 1 +#define MOUSE_CURSOR_ARROW 2 +#define MOUSE_CURSOR_BUSY 3 +#define MOUSE_CURSOR_QUESTION 4 +#define MOUSE_CURSOR_EDIT 5 +#define AL_NUM_MOUSE_CURSORS 6 + +AL_VAR(BITMAP *, mouse_sprite); +AL_VAR(int, mouse_x_focus); +AL_VAR(int, mouse_y_focus); + +AL_VAR(volatile int, mouse_x); +AL_VAR(volatile int, mouse_y); +AL_VAR(volatile int, mouse_z); +AL_VAR(volatile int, mouse_w); +AL_VAR(volatile int, mouse_b); +AL_VAR(volatile int, mouse_pos); + +AL_VAR(volatile int, freeze_mouse_flag); + +#define MOUSE_FLAG_MOVE 1 +#define MOUSE_FLAG_LEFT_DOWN 2 +#define MOUSE_FLAG_LEFT_UP 4 +#define MOUSE_FLAG_RIGHT_DOWN 8 +#define MOUSE_FLAG_RIGHT_UP 16 +#define MOUSE_FLAG_MIDDLE_DOWN 32 +#define MOUSE_FLAG_MIDDLE_UP 64 +#define MOUSE_FLAG_MOVE_Z 128 +#define MOUSE_FLAG_MOVE_W 256 + +AL_FUNCPTR(void, mouse_callback, (int flags)); + +AL_FUNC(void, show_mouse, (BITMAP *bmp)); +AL_FUNC(void, scare_mouse, (void)); +AL_FUNC(void, scare_mouse_area, (int x, int y, int w, int h)); +AL_FUNC(void, unscare_mouse, (void)); +AL_FUNC(void, position_mouse, (int x, int y)); +AL_FUNC(void, position_mouse_z, (int z)); +AL_FUNC(void, position_mouse_w, (int w)); +AL_FUNC(void, set_mouse_range, (int x1, int y_1, int x2, int y2)); +AL_FUNC(void, set_mouse_speed, (int xspeed, int yspeed)); +AL_FUNC(void, select_mouse_cursor, (int cursor)); +AL_FUNC(void, set_mouse_cursor_bitmap, (int cursor, BITMAP *bmp)); +AL_FUNC(void, set_mouse_sprite_focus, (int x, int y)); +AL_FUNC(void, get_mouse_mickeys, (int *mickeyx, int *mickeyy)); +AL_FUNC(void, set_mouse_sprite, (BITMAP *sprite)); +AL_FUNC(int, show_os_cursor, (int cursor)); +AL_FUNC(int, mouse_on_screen, (void)); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/sound.cpp b/engines/ags/stubs/allegro/sound.cpp new file mode 100644 index 000000000000..5eda1fe992e2 --- /dev/null +++ b/engines/ags/stubs/allegro/sound.cpp @@ -0,0 +1,103 @@ +/* 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 "ags/stubs/allegro/sound.h" +#include "common/textconsole.h" + +namespace AGS3 { + +_DRIVER_INFO _digi_driver_list[] = { + { 0, nullptr, 0 } +}; + + +int install_sound(int digi, int midi, const char *cfg_path) { + // TODO: install_sound + return 0; +} + +void remove_sound() { + // TODO: remove_sound +} + +void reserve_voices(int digi_voices, int midi_voices) { + error("reserve_voices"); +} + +void set_volume_per_voice(int scale) { + error("set_volume_per_voice"); + +} + +int install_sound_input(int digi, int midi) { + error("install_sound_input"); +} + +void remove_sound_input() { + error("remove_sound_input"); +} + +void set_volume(int digi_volume, int midi_volume) { + error("set_volume"); +} + +void set_hardware_volume(int digi_volume, int midi_volume) { + error("set_hardware_volume"); +} + +void get_volume(int *digi_volume, int *midi_volume) { + error("get_volume"); +} + +void get_hardware_volume(int *digi_volume, int *midi_volume) { + error("get_hardware_volume"); +} + +void set_mixer_quality(int quality) { + error("set_mixer_quality"); +} + +int get_mixer_quality() { + error("get_mixer_quality"); +} + +int get_mixer_frequency() { + error("get_mixer_frequency"); +} + +int get_mixer_bits() { + error("get_mixer_bits"); +} + +int get_mixer_channels() { + error("get_mixer_channels"); +} + +int get_mixer_voices() { + error("get_mixer_voices"); +} + +int get_mixer_buffer_length() { + error("get_mixer_buffer_length"); +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/sound.h b/engines/ags/stubs/allegro/sound.h new file mode 100644 index 000000000000..fa9f64097e6b --- /dev/null +++ b/engines/ags/stubs/allegro/sound.h @@ -0,0 +1,57 @@ +/* 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 AGS_STUBS_ALLEGRO_SOUND_H +#define AGS_STUBS_ALLEGRO_SOUND_H + +#include "common/scummsys.h" +#include "ags/stubs/allegro/base.h" +#include "ags/stubs/allegro/alconfig.h" + +namespace AGS3 { + +AL_FUNC(void, reserve_voices, (int digi_voices, int midi_voices)); +AL_FUNC(void, set_volume_per_voice, (int scale)); + +AL_FUNC(int, install_sound, (int digi, int midi, AL_CONST char *cfg_path)); +AL_FUNC(void, remove_sound, (void)); + +AL_FUNC(int, install_sound_input, (int digi, int midi)); +AL_FUNC(void, remove_sound_input, (void)); + +AL_FUNC(void, set_volume, (int digi_volume, int midi_volume)); +AL_FUNC(void, set_hardware_volume, (int digi_volume, int midi_volume)); + +AL_FUNC(void, get_volume, (int *digi_volume, int *midi_volume)); +AL_FUNC(void, get_hardware_volume, (int *digi_volume, int *midi_volume)); + +AL_FUNC(void, set_mixer_quality, (int quality)); +AL_FUNC(int, get_mixer_quality, (void)); +AL_FUNC(int, get_mixer_frequency, (void)); +AL_FUNC(int, get_mixer_bits, (void)); +AL_FUNC(int, get_mixer_channels, (void)); +AL_FUNC(int, get_mixer_voices, (void)); +AL_FUNC(int, get_mixer_buffer_length, (void)); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/system.cpp b/engines/ags/stubs/allegro/system.cpp new file mode 100644 index 000000000000..47675373790b --- /dev/null +++ b/engines/ags/stubs/allegro/system.cpp @@ -0,0 +1,65 @@ +/* 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 "ags/stubs/allegro/system.h" +#include "common/system.h" + +namespace AGS3 { + +int color_depth; + +SYSTEM_DRIVER system_none; +SYSTEM_DRIVER *system_driver; + +_DRIVER_INFO _system_driver_list[] = { +// { SYSTEM_IOS, &system_none, true }, + { SYSTEM_NONE, &system_none, false }, + { 0, nullptr , 0 } +}; + + +void set_color_depth(int depth) { + color_depth = depth; +} + +int get_color_depth() { + return color_depth; +} + +int get_desktop_resolution(int *width, int *height) { + if (*width) + *width = g_system->getWidth(); + if (*height) + *height = g_system->getHeight(); + + return 0; +} + +void request_refresh_rate(int rate) { + // No implementation +} + +void set_close_button_callback(void(*proc)()) { + // No implementation +} + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/system.h b/engines/ags/stubs/allegro/system.h new file mode 100644 index 000000000000..0f6724600630 --- /dev/null +++ b/engines/ags/stubs/allegro/system.h @@ -0,0 +1,103 @@ +/* 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 AGS_STUBS_ALLEGRO_SYSTEM_H +#define AGS_STUBS_ALLEGRO_SYSTEM_H + +#include "ags/stubs/allegro/base.h" +#include "ags/stubs/allegro/color.h" +#include "ags/stubs/allegro/gfx.h" + +namespace AGS3 { + +#ifndef AL_METHOD +#define AL_METHOD(type, name, args) type (*name) args +#endif + +#define SYSTEM_AUTODETECT 0 +#define SYSTEM_NONE AL_ID('N','O','N','E') + + +struct GFX_MODE { + int width, height, bpp; +}; + +struct GFX_MODE_LIST { + int num_modes; /* number of gfx modes */ + GFX_MODE *mode; /* pointer to the actual mode list array */ +}; + +struct SYSTEM_DRIVER { + int id; + char *name; + char *desc; + char *ascii_name; + AL_METHOD(int, init, (void)); + AL_METHOD(void, exit, (void)); + AL_METHOD(void, get_executable_name, (char *output, int size)); + AL_METHOD(int, find_resource, (char *dest, const char *resource, int size)); + AL_METHOD(void, set_window_title, (const char *name)); + AL_METHOD(int, set_close_button_callback, (AL_METHOD(void, proc, (void)))); + AL_METHOD(void, message, (const char *msg)); + AL_METHOD(void, assert, (const char *msg)); + AL_METHOD(void, save_console_state, (void)); + AL_METHOD(void, restore_console_state, (void)); + AL_METHOD(BITMAP *, create_bitmap, (int color_depth, int width, int height)); + AL_METHOD(void, created_bitmap, (BITMAP *bmp)); + AL_METHOD(BITMAP *, create_sub_bitmap, (BITMAP *parent, int x, int y, int width, int height)); + AL_METHOD(void, created_sub_bitmap, (BITMAP *bmp, BITMAP *parent)); + AL_METHOD(int, destroy_bitmap, (BITMAP *bitmap)); + AL_METHOD(void, read_hardware_palette, (void)); + AL_METHOD(void, set_palette_range, (const RGB *p, int from, int to, int retracesync)); + AL_METHOD(struct GFX_VTABLE *, get_vtable, (int color_depth)); + AL_METHOD(int, set_display_switch_mode, (int mode)); + AL_METHOD(void, display_switch_lock, (int lock, int foreground)); + AL_METHOD(int, desktop_color_depth, (void)); + AL_METHOD(int, get_desktop_resolution, (int *width, int *height)); + AL_METHOD(void, get_gfx_safe_mode, (int *driver, struct GFX_MODE *mode)); + AL_METHOD(void, yield_timeslice, (void)); + AL_METHOD(void *, create_mutex, (void)); + AL_METHOD(void, destroy_mutex, (void *handle)); + AL_METHOD(void, lock_mutex, (void *handle)); + AL_METHOD(void, unlock_mutex, (void *handle)); + AL_METHOD(_DRIVER_INFO *, gfx_drivers, (void)); + AL_METHOD(_DRIVER_INFO *, digi_drivers, (void)); + AL_METHOD(_DRIVER_INFO *, midi_drivers, (void)); + AL_METHOD(_DRIVER_INFO *, keyboard_drivers, (void)); + AL_METHOD(_DRIVER_INFO *, mouse_drivers, (void)); + AL_METHOD(_DRIVER_INFO *, joystick_drivers, (void)); + AL_METHOD(_DRIVER_INFO *, timer_drivers, (void)); +}; + +extern SYSTEM_DRIVER system_none; +extern SYSTEM_DRIVER *system_driver; +extern _DRIVER_INFO _system_driver_list[]; + +extern void set_color_depth(int depth); +extern int get_color_depth(); +extern int get_desktop_resolution(int *width, int *height); +extern void request_refresh_rate(int rate); +extern void set_close_button_callback(void(*proc)()); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/stubs/allegro/unicode.cpp b/engines/ags/stubs/allegro/unicode.cpp new file mode 100644 index 000000000000..36372960e2a4 --- /dev/null +++ b/engines/ags/stubs/allegro/unicode.cpp @@ -0,0 +1,37 @@ +/* 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 "ags/stubs/allegro/unicode.h" +#include "common/textconsole.h" + +namespace AGS3 { + +void set_uformat(int format) { + // TODO: implementation +} + +size_t ustrsize(const char *s) { + error("TODO: ustrsize"); +} + + +} // namespace AGS3 diff --git a/engines/ags/stubs/allegro/unicode.h b/engines/ags/stubs/allegro/unicode.h new file mode 100644 index 000000000000..24e84d913aae --- /dev/null +++ b/engines/ags/stubs/allegro/unicode.h @@ -0,0 +1,41 @@ +/* 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 AGS_STUBS_ALLEGRO_UNICODE_H +#define AGS_STUBS_ALLEGRO_UNICODE_H + +#include "ags/stubs/allegro/base.h" + +namespace AGS3 { + +#define U_ASCII AL_ID('A','S','C','8') +#define U_ASCII_CP AL_ID('A','S','C','P') +#define U_UNICODE AL_ID('U','N','I','C') +#define U_UTF8 AL_ID('U','T','F','8') +#define U_CURRENT AL_ID('c','u','r','.') + +extern void set_uformat(int format); +extern size_t ustrsize(const char *s); + +} // namespace AGS3 + +#endif From bcb91b6e72bed46ee50592b9eb8c40961e895329 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 08:30:51 -0800 Subject: [PATCH 003/215] AGS: Initial addition of engine/ and shared/ folders --- engines/ags/engine/ac/asset_helper.h | 67 + engines/ags/engine/ac/audiochannel.cpp | 353 ++ engines/ags/engine/ac/audiochannel.h | 38 + engines/ags/engine/ac/audioclip.cpp | 154 + engines/ags/engine/ac/audioclip.h | 32 + engines/ags/engine/ac/button.cpp | 501 ++ engines/ags/engine/ac/button.h | 47 + engines/ags/engine/ac/cdaudio.cpp | 39 + engines/ags/engine/ac/cdaudio.h | 31 + engines/ags/engine/ac/character.cpp | 4122 +++++++++++++++++ engines/ags/engine/ac/character.h | 219 + engines/ags/engine/ac/charactercache.h | 35 + engines/ags/engine/ac/characterextras.cpp | 56 + engines/ags/engine/ac/characterextras.h | 52 + .../ags/engine/ac/characterinfo_engine.cpp | 508 ++ engines/ags/engine/ac/datetime.cpp | 141 + engines/ags/engine/ac/datetime.h | 33 + engines/ags/engine/ac/dialog.cpp | 1324 ++++++ engines/ags/engine/ac/dialog.h | 39 + .../ags/engine/ac/dialogoptionsrendering.cpp | 332 ++ .../ags/engine/ac/dialogoptionsrendering.h | 45 + engines/ags/engine/ac/display.cpp | 832 ++++ engines/ags/engine/ac/display.h | 80 + engines/ags/engine/ac/draw.cpp | 2563 ++++++++++ engines/ags/engine/ac/draw.h | 175 + engines/ags/engine/ac/draw_software.cpp | 491 ++ engines/ags/engine/ac/draw_software.h | 46 + engines/ags/engine/ac/drawingsurface.cpp | 694 +++ engines/ags/engine/ac/drawingsurface.h | 45 + engines/ags/engine/ac/dynamicsprite.cpp | 700 +++ engines/ags/engine/ac/dynamicsprite.h | 51 + .../ags/engine/ac/dynobj/all_dynamicclasses.h | 35 + .../ags/engine/ac/dynobj/all_scriptclasses.h | 37 + .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 130 + .../engine/ac/dynobj/cc_agsdynamicobject.h | 60 + .../ags/engine/ac/dynobj/cc_audiochannel.cpp | 36 + .../ags/engine/ac/dynobj/cc_audiochannel.h | 29 + engines/ags/engine/ac/dynobj/cc_audioclip.cpp | 36 + engines/ags/engine/ac/dynobj/cc_audioclip.h | 29 + engines/ags/engine/ac/dynobj/cc_character.cpp | 58 + engines/ags/engine/ac/dynobj/cc_character.h | 34 + engines/ags/engine/ac/dynobj/cc_dialog.cpp | 38 + engines/ags/engine/ac/dynobj/cc_dialog.h | 33 + .../ags/engine/ac/dynobj/cc_dynamicarray.cpp | 161 + .../ags/engine/ac/dynobj/cc_dynamicarray.h | 58 + .../ags/engine/ac/dynobj/cc_dynamicobject.cpp | 151 + .../ags/engine/ac/dynobj/cc_dynamicobject.h | 116 + .../cc_dynamicobject_addr_and_manager.h | 11 + engines/ags/engine/ac/dynobj/cc_gui.cpp | 38 + engines/ags/engine/ac/dynobj/cc_gui.h | 32 + engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 42 + engines/ags/engine/ac/dynobj/cc_guiobject.h | 33 + engines/ags/engine/ac/dynobj/cc_hotspot.cpp | 40 + engines/ags/engine/ac/dynobj/cc_hotspot.h | 33 + engines/ags/engine/ac/dynobj/cc_inventory.cpp | 39 + engines/ags/engine/ac/dynobj/cc_inventory.h | 33 + engines/ags/engine/ac/dynobj/cc_object.cpp | 40 + engines/ags/engine/ac/dynobj/cc_object.h | 33 + engines/ags/engine/ac/dynobj/cc_region.cpp | 40 + engines/ags/engine/ac/dynobj/cc_region.h | 33 + .../ags/engine/ac/dynobj/cc_serializer.cpp | 144 + engines/ags/engine/ac/dynobj/cc_serializer.h | 27 + .../engine/ac/dynobj/managedobjectpool.cpp | 322 ++ .../ags/engine/ac/dynobj/managedobjectpool.h | 88 + .../ags/engine/ac/dynobj/scriptaudiochannel.h | 27 + engines/ags/engine/ac/dynobj/scriptcamera.cpp | 64 + engines/ags/engine/ac/dynobj/scriptcamera.h | 44 + .../ags/engine/ac/dynobj/scriptcontainers.h | 29 + .../ags/engine/ac/dynobj/scriptdatetime.cpp | 55 + engines/ags/engine/ac/dynobj/scriptdatetime.h | 36 + engines/ags/engine/ac/dynobj/scriptdialog.h | 26 + .../dynobj/scriptdialogoptionsrendering.cpp | 53 + .../ac/dynobj/scriptdialogoptionsrendering.h | 47 + engines/ags/engine/ac/dynobj/scriptdict.cpp | 50 + engines/ags/engine/ac/dynobj/scriptdict.h | 186 + .../engine/ac/dynobj/scriptdrawingsurface.cpp | 129 + .../engine/ac/dynobj/scriptdrawingsurface.h | 55 + .../engine/ac/dynobj/scriptdynamicsprite.cpp | 50 + .../engine/ac/dynobj/scriptdynamicsprite.h | 32 + engines/ags/engine/ac/dynobj/scriptfile.cpp | 105 + engines/ags/engine/ac/dynobj/scriptfile.h | 61 + engines/ags/engine/ac/dynobj/scriptgui.h | 27 + engines/ags/engine/ac/dynobj/scripthotspot.h | 26 + engines/ags/engine/ac/dynobj/scriptinvitem.h | 26 + engines/ags/engine/ac/dynobj/scriptmouse.h | 26 + engines/ags/engine/ac/dynobj/scriptobject.h | 30 + .../ags/engine/ac/dynobj/scriptoverlay.cpp | 83 + engines/ags/engine/ac/dynobj/scriptoverlay.h | 34 + engines/ags/engine/ac/dynobj/scriptregion.h | 26 + engines/ags/engine/ac/dynobj/scriptset.cpp | 50 + engines/ags/engine/ac/dynobj/scriptset.h | 144 + engines/ags/engine/ac/dynobj/scriptstring.cpp | 66 + engines/ags/engine/ac/dynobj/scriptstring.h | 34 + engines/ags/engine/ac/dynobj/scriptsystem.h | 33 + .../ags/engine/ac/dynobj/scriptuserobject.cpp | 144 + .../ags/engine/ac/dynobj/scriptuserobject.h | 75 + .../ags/engine/ac/dynobj/scriptviewframe.cpp | 53 + .../ags/engine/ac/dynobj/scriptviewframe.h | 32 + .../ags/engine/ac/dynobj/scriptviewport.cpp | 64 + engines/ags/engine/ac/dynobj/scriptviewport.h | 43 + engines/ags/engine/ac/event.cpp | 426 ++ engines/ags/engine/ac/event.h | 83 + engines/ags/engine/ac/file.cpp | 834 ++++ engines/ags/engine/ac/file.h | 57 + engines/ags/engine/ac/game.cpp | 2545 ++++++++++ engines/ags/engine/ac/game.h | 192 + engines/ags/engine/ac/gamesetup.cpp | 45 + engines/ags/engine/ac/gamesetup.h | 86 + engines/ags/engine/ac/gamestate.cpp | 935 ++++ engines/ags/engine/ac/gamestate.h | 396 ++ engines/ags/engine/ac/global_api.cpp | 3041 ++++++++++++ engines/ags/engine/ac/global_audio.cpp | 680 +++ engines/ags/engine/ac/global_audio.h | 71 + engines/ags/engine/ac/global_button.cpp | 99 + engines/ags/engine/ac/global_button.h | 26 + engines/ags/engine/ac/global_character.cpp | 566 +++ engines/ags/engine/ac/global_character.h | 87 + engines/ags/engine/ac/global_datetime.cpp | 40 + engines/ags/engine/ac/global_datetime.h | 24 + engines/ags/engine/ac/global_debug.cpp | 190 + engines/ags/engine/ac/global_debug.h | 27 + engines/ags/engine/ac/global_dialog.cpp | 103 + engines/ags/engine/ac/global_dialog.h | 26 + engines/ags/engine/ac/global_display.cpp | 200 + engines/ags/engine/ac/global_display.h | 37 + .../ags/engine/ac/global_drawingsurface.cpp | 301 ++ engines/ags/engine/ac/global_drawingsurface.h | 44 + .../ags/engine/ac/global_dynamicsprite.cpp | 50 + engines/ags/engine/ac/global_dynamicsprite.h | 23 + engines/ags/engine/ac/global_file.cpp | 177 + engines/ags/engine/ac/global_file.h | 41 + engines/ags/engine/ac/global_game.cpp | 955 ++++ engines/ags/engine/ac/global_game.h | 88 + engines/ags/engine/ac/global_gui.cpp | 256 + engines/ags/engine/ac/global_gui.h | 54 + engines/ags/engine/ac/global_hotspot.cpp | 147 + engines/ags/engine/ac/global_hotspot.h | 35 + .../ags/engine/ac/global_inventoryitem.cpp | 144 + engines/ags/engine/ac/global_inventoryitem.h | 31 + engines/ags/engine/ac/global_invwindow.cpp | 40 + engines/ags/engine/ac/global_invwindow.h | 24 + engines/ags/engine/ac/global_label.cpp | 58 + engines/ags/engine/ac/global_label.h | 25 + engines/ags/engine/ac/global_listbox.cpp | 62 + engines/ags/engine/ac/global_listbox.h | 32 + engines/ags/engine/ac/global_mouse.cpp | 26 + engines/ags/engine/ac/global_mouse.h | 24 + engines/ags/engine/ac/global_object.cpp | 523 +++ engines/ags/engine/ac/global_object.h | 71 + engines/ags/engine/ac/global_overlay.cpp | 94 + engines/ags/engine/ac/global_overlay.h | 29 + engines/ags/engine/ac/global_palette.cpp | 67 + engines/ags/engine/ac/global_palette.h | 25 + engines/ags/engine/ac/global_parser.cpp | 29 + engines/ags/engine/ac/global_parser.h | 23 + engines/ags/engine/ac/global_plugin.h | 24 + engines/ags/engine/ac/global_record.cpp | 20 + engines/ags/engine/ac/global_record.h | 23 + engines/ags/engine/ac/global_region.cpp | 164 + engines/ags/engine/ac/global_region.h | 32 + engines/ags/engine/ac/global_room.cpp | 223 + engines/ags/engine/ac/global_room.h | 35 + engines/ags/engine/ac/global_screen.cpp | 180 + engines/ags/engine/ac/global_screen.h | 31 + engines/ags/engine/ac/global_slider.cpp | 42 + engines/ags/engine/ac/global_slider.h | 24 + engines/ags/engine/ac/global_string.cpp | 73 + engines/ags/engine/ac/global_string.h | 28 + engines/ags/engine/ac/global_textbox.cpp | 57 + engines/ags/engine/ac/global_textbox.h | 25 + engines/ags/engine/ac/global_timer.cpp | 37 + engines/ags/engine/ac/global_timer.h | 24 + engines/ags/engine/ac/global_translation.cpp | 85 + engines/ags/engine/ac/global_translation.h | 25 + engines/ags/engine/ac/global_video.cpp | 85 + engines/ags/engine/ac/global_video.h | 24 + engines/ags/engine/ac/global_viewframe.cpp | 49 + engines/ags/engine/ac/global_viewframe.h | 23 + engines/ags/engine/ac/global_viewport.cpp | 32 + engines/ags/engine/ac/global_viewport.h | 26 + engines/ags/engine/ac/global_walkablearea.cpp | 91 + engines/ags/engine/ac/global_walkablearea.h | 32 + engines/ags/engine/ac/global_walkbehind.cpp | 36 + engines/ags/engine/ac/global_walkbehind.h | 23 + engines/ags/engine/ac/gui.cpp | 1001 ++++ engines/ags/engine/ac/gui.h | 88 + engines/ags/engine/ac/guicontrol.cpp | 474 ++ engines/ags/engine/ac/guicontrol.h | 68 + engines/ags/engine/ac/guiinv.cpp | 94 + engines/ags/engine/ac/hotspot.cpp | 268 ++ engines/ags/engine/ac/hotspot.h | 42 + engines/ags/engine/ac/interfacebutton.cpp | 21 + engines/ags/engine/ac/interfaceelement.cpp | 21 + engines/ags/engine/ac/inventoryitem.cpp | 266 ++ engines/ags/engine/ac/inventoryitem.h | 40 + engines/ags/engine/ac/invwindow.cpp | 658 +++ engines/ags/engine/ac/invwindow.h | 48 + engines/ags/engine/ac/keycode.cpp | 142 + engines/ags/engine/ac/keycode.h | 175 + engines/ags/engine/ac/label.cpp | 172 + engines/ags/engine/ac/label.h | 33 + engines/ags/engine/ac/lipsync.h | 25 + engines/ags/engine/ac/listbox.cpp | 674 +++ engines/ags/engine/ac/listbox.h | 53 + engines/ags/engine/ac/math.cpp | 318 ++ engines/ags/engine/ac/math.h | 55 + engines/ags/engine/ac/mouse.cpp | 664 +++ engines/ags/engine/ac/mouse.h | 76 + engines/ags/engine/ac/movelist.cpp | 84 + engines/ags/engine/ac/movelist.h | 43 + engines/ags/engine/ac/object.cpp | 1070 +++++ engines/ags/engine/ac/object.h | 89 + engines/ags/engine/ac/objectcache.h | 31 + engines/ags/engine/ac/overlay.cpp | 396 ++ engines/ags/engine/ac/overlay.h | 51 + engines/ags/engine/ac/parser.cpp | 345 ++ engines/ags/engine/ac/parser.h | 33 + engines/ags/engine/ac/path_helper.h | 75 + engines/ags/engine/ac/properties.cpp | 107 + engines/ags/engine/ac/properties.h | 37 + engines/ags/engine/ac/region.cpp | 276 ++ engines/ags/engine/ac/region.h | 40 + engines/ags/engine/ac/richgamemedia.cpp | 35 + engines/ags/engine/ac/richgamemedia.h | 51 + engines/ags/engine/ac/room.cpp | 1248 +++++ engines/ags/engine/ac/room.h | 74 + engines/ags/engine/ac/roomobject.cpp | 166 + engines/ags/engine/ac/roomobject.h | 62 + engines/ags/engine/ac/roomstatus.cpp | 240 + engines/ags/engine/ac/roomstatus.h | 80 + engines/ags/engine/ac/route_finder.cpp | 162 + engines/ags/engine/ac/route_finder.h | 37 + engines/ags/engine/ac/route_finder_impl.cpp | 273 ++ engines/ags/engine/ac/route_finder_impl.h | 45 + .../engine/ac/route_finder_impl_legacy.cpp | 935 ++++ .../ags/engine/ac/route_finder_impl_legacy.h | 43 + engines/ags/engine/ac/route_finder_jps.inl | 921 ++++ engines/ags/engine/ac/runtime_defines.h | 153 + engines/ags/engine/ac/screen.cpp | 229 + engines/ags/engine/ac/screen.h | 31 + engines/ags/engine/ac/screenoverlay.cpp | 59 + engines/ags/engine/ac/screenoverlay.h | 44 + engines/ags/engine/ac/scriptcontainers.cpp | 354 ++ engines/ags/engine/ac/slider.cpp | 223 + engines/ags/engine/ac/slider.h | 38 + engines/ags/engine/ac/speech.cpp | 254 + engines/ags/engine/ac/speech.h | 39 + engines/ags/engine/ac/sprite.cpp | 186 + engines/ags/engine/ac/sprite.h | 30 + engines/ags/engine/ac/spritecache_engine.cpp | 43 + engines/ags/engine/ac/spritelistentry.h | 36 + .../ags/engine/ac/statobj/agsstaticobject.cpp | 80 + .../ags/engine/ac/statobj/agsstaticobject.h | 48 + engines/ags/engine/ac/statobj/staticarray.cpp | 196 + engines/ags/engine/ac/statobj/staticarray.h | 64 + engines/ags/engine/ac/statobj/staticobject.h | 42 + engines/ags/engine/ac/string.cpp | 491 ++ engines/ags/engine/ac/string.h | 56 + engines/ags/engine/ac/sys_events.cpp | 206 + engines/ags/engine/ac/sys_events.h | 36 + engines/ags/engine/ac/system.cpp | 467 ++ engines/ags/engine/ac/system.h | 48 + engines/ags/engine/ac/textbox.cpp | 171 + engines/ags/engine/ac/textbox.h | 33 + engines/ags/engine/ac/timer.cpp | 120 + engines/ags/engine/ac/timer.h | 40 + engines/ags/engine/ac/topbarsettings.h | 35 + engines/ags/engine/ac/translation.cpp | 180 + engines/ags/engine/ac/translation.h | 28 + engines/ags/engine/ac/tree_map.cpp | 98 + engines/ags/engine/ac/tree_map.h | 35 + engines/ags/engine/ac/viewframe.cpp | 287 ++ engines/ags/engine/ac/viewframe.h | 47 + engines/ags/engine/ac/viewport_script.cpp | 527 +++ engines/ags/engine/ac/walkablearea.cpp | 238 + engines/ags/engine/ac/walkablearea.h | 31 + engines/ags/engine/ac/walkbehind.cpp | 143 + engines/ags/engine/ac/walkbehind.h | 31 + .../ags/engine/debugging/agseditordebugger.h | 34 + .../engine/debugging/consoleoutputtarget.cpp | 42 + .../engine/debugging/consoleoutputtarget.h | 44 + engines/ags/engine/debugging/debug.cpp | 629 +++ engines/ags/engine/debugging/debug_log.h | 48 + engines/ags/engine/debugging/debugger.h | 60 + .../ags/engine/debugging/dummyagsdebugger.h | 31 + .../engine/debugging/filebasedagsdebugger.cpp | 77 + .../engine/debugging/filebasedagsdebugger.h | 34 + engines/ags/engine/debugging/logfile.cpp | 88 + engines/ags/engine/debugging/logfile.h | 78 + .../ags/engine/debugging/messagebuffer.cpp | 67 + engines/ags/engine/debugging/messagebuffer.h | 57 + engines/ags/engine/device/mousew32.cpp | 387 ++ engines/ags/engine/device/mousew32.h | 90 + engines/ags/engine/font/fonts_engine.cpp | 37 + engines/ags/engine/game/game_init.cpp | 477 ++ engines/ags/engine/game/game_init.h | 57 + engines/ags/engine/game/savegame.cpp | 798 ++++ engines/ags/engine/game/savegame.h | 169 + .../ags/engine/game/savegame_components.cpp | 1392 ++++++ engines/ags/engine/game/savegame_components.h | 56 + engines/ags/engine/game/savegame_internal.h | 144 + engines/ags/engine/game/viewport.cpp | 224 + engines/ags/engine/game/viewport.h | 192 + engines/ags/engine/gfx/ali3dexception.h | 49 + engines/ags/engine/gfx/ali3dogl.cpp | 2065 +++++++++ engines/ags/engine/gfx/ali3dogl.h | 362 ++ engines/ags/engine/gfx/ali3dsw.cpp | 911 ++++ engines/ags/engine/gfx/ali3dsw.h | 270 ++ engines/ags/engine/gfx/blender.cpp | 300 ++ engines/ags/engine/gfx/blender.h | 65 + engines/ags/engine/gfx/color_engine.cpp | 59 + engines/ags/engine/gfx/ddb.h | 45 + engines/ags/engine/gfx/gfx_util.cpp | 190 + engines/ags/engine/gfx/gfx_util.h | 59 + engines/ags/engine/gfx/gfxdefines.h | 82 + engines/ags/engine/gfx/gfxdriverbase.cpp | 498 ++ engines/ags/engine/gfx/gfxdriverbase.h | 251 + engines/ags/engine/gfx/gfxdriverfactory.cpp | 70 + engines/ags/engine/gfx/gfxdriverfactory.h | 77 + engines/ags/engine/gfx/gfxdriverfactorybase.h | 110 + engines/ags/engine/gfx/gfxfilter.h | 71 + engines/ags/engine/gfx/gfxfilter_aad3d.cpp | 53 + engines/ags/engine/gfx/gfxfilter_aad3d.h | 46 + engines/ags/engine/gfx/gfxfilter_aaogl.cpp | 51 + engines/ags/engine/gfx/gfxfilter_aaogl.h | 46 + engines/ags/engine/gfx/gfxfilter_allegro.cpp | 172 + engines/ags/engine/gfx/gfxfilter_allegro.h | 71 + engines/ags/engine/gfx/gfxfilter_d3d.cpp | 51 + engines/ags/engine/gfx/gfxfilter_d3d.h | 46 + engines/ags/engine/gfx/gfxfilter_hqx.cpp | 92 + engines/ags/engine/gfx/gfxfilter_hqx.h | 58 + engines/ags/engine/gfx/gfxfilter_ogl.cpp | 51 + engines/ags/engine/gfx/gfxfilter_ogl.h | 46 + engines/ags/engine/gfx/gfxfilter_scaling.cpp | 47 + engines/ags/engine/gfx/gfxfilter_scaling.h | 46 + engines/ags/engine/gfx/gfxmodelist.h | 40 + engines/ags/engine/gfx/graphicsdriver.h | 190 + engines/ags/engine/gfx/hq2x3x.h | 30 + engines/ags/engine/gfx/ogl_headers.h | 78 + engines/ags/engine/gui/animatingguibutton.cpp | 44 + engines/ags/engine/gui/animatingguibutton.h | 38 + engines/ags/engine/gui/cscidialog.cpp | 315 ++ engines/ags/engine/gui/cscidialog.h | 36 + engines/ags/engine/gui/gui_engine.cpp | 170 + engines/ags/engine/gui/guidialog.cpp | 533 +++ engines/ags/engine/gui/guidialog.h | 44 + engines/ags/engine/gui/guidialogdefines.h | 111 + .../ags/engine/gui/guidialoginternaldefs.h | 32 + engines/ags/engine/gui/mycontrols.h | 26 + engines/ags/engine/gui/mylabel.cpp | 62 + engines/ags/engine/gui/mylabel.h | 32 + engines/ags/engine/gui/mylistbox.cpp | 198 + engines/ags/engine/gui/mylistbox.h | 37 + engines/ags/engine/gui/mypushbutton.cpp | 106 + engines/ags/engine/gui/mypushbutton.h | 29 + engines/ags/engine/gui/mytextbox.cpp | 88 + engines/ags/engine/gui/mytextbox.h | 30 + engines/ags/engine/gui/newcontrol.cpp | 67 + engines/ags/engine/gui/newcontrol.h | 42 + engines/ags/engine/main/config.cpp | 672 +++ engines/ags/engine/main/config.h | 76 + engines/ags/engine/main/engine.cpp | 1677 +++++++ engines/ags/engine/main/engine.h | 58 + engines/ags/engine/main/engine_setup.cpp | 367 ++ engines/ags/engine/main/engine_setup.h | 32 + engines/ags/engine/main/game_file.cpp | 161 + engines/ags/engine/main/game_file.h | 32 + engines/ags/engine/main/game_run.cpp | 1050 +++++ engines/ags/engine/main/game_run.h | 48 + engines/ags/engine/main/game_start.cpp | 159 + engines/ags/engine/main/game_start.h | 24 + engines/ags/engine/main/graphics_mode.cpp | 679 +++ engines/ags/engine/main/graphics_mode.h | 158 + engines/ags/engine/main/main.cpp | 495 ++ engines/ags/engine/main/main.h | 65 + engines/ags/engine/main/main_allegro.cpp | 7 + engines/ags/engine/main/main_allegro.h | 31 + engines/ags/engine/main/maindefines_ex.h | 23 + engines/ags/engine/main/mainheader.h | 47 + engines/ags/engine/main/quit.cpp | 320 ++ engines/ags/engine/main/quit.h | 45 + engines/ags/engine/main/update.cpp | 497 ++ engines/ags/engine/main/update.h | 26 + .../ags/engine/media/audio/ambientsound.cpp | 46 + engines/ags/engine/media/audio/ambientsound.h | 37 + engines/ags/engine/media/audio/audio.cpp | 1228 +++++ engines/ags/engine/media/audio/audio.h | 153 + engines/ags/engine/media/audio/audio_system.h | 16 + engines/ags/engine/media/audio/audiodefines.h | 39 + .../engine/media/audio/audiointernaldefs.h | 21 + .../ags/engine/media/audio/clip_mydumbmod.cpp | 163 + .../ags/engine/media/audio/clip_mydumbmod.h | 69 + .../ags/engine/media/audio/clip_myjgmod.cpp | 89 + engines/ags/engine/media/audio/clip_myjgmod.h | 49 + .../ags/engine/media/audio/clip_mymidi.cpp | 111 + engines/ags/engine/media/audio/clip_mymidi.h | 55 + engines/ags/engine/media/audio/clip_mymp3.cpp | 173 + engines/ags/engine/media/audio/clip_mymp3.h | 50 + engines/ags/engine/media/audio/clip_myogg.cpp | 203 + engines/ags/engine/media/audio/clip_myogg.h | 60 + .../engine/media/audio/clip_mystaticmp3.cpp | 156 + .../ags/engine/media/audio/clip_mystaticmp3.h | 57 + .../engine/media/audio/clip_mystaticogg.cpp | 205 + .../ags/engine/media/audio/clip_mystaticogg.h | 63 + .../ags/engine/media/audio/clip_mywave.cpp | 116 + engines/ags/engine/media/audio/clip_mywave.h | 50 + .../engine/media/audio/queuedaudioitem.cpp | 38 + .../ags/engine/media/audio/queuedaudioitem.h | 33 + engines/ags/engine/media/audio/sound.cpp | 356 ++ engines/ags/engine/media/audio/sound.h | 35 + engines/ags/engine/media/audio/soundcache.cpp | 234 + engines/ags/engine/media/audio/soundcache.h | 48 + engines/ags/engine/media/audio/soundclip.cpp | 80 + engines/ags/engine/media/audio/soundclip.h | 170 + engines/ags/engine/media/video/VMR9Graph.h | 150 + engines/ags/engine/media/video/video.cpp | 431 ++ engines/ags/engine/media/video/video.h | 27 + .../ags/engine/platform/android/acpland.cpp | 757 +++ .../platform/base/agsplatformdriver.cpp | 236 + .../engine/platform/base/agsplatformdriver.h | 170 + engines/ags/engine/platform/ios/acplios.cpp | 644 +++ engines/ags/engine/platform/linux/acpllnx.cpp | 211 + engines/ags/engine/platform/linux/icon.xpm | 1103 +++++ engines/ags/engine/platform/osx/acplmac.cpp | 149 + engines/ags/engine/platform/osx/alplmac.mm | 30 + engines/ags/engine/platform/util/libc.c | 54 + engines/ags/engine/platform/util/pe.c | 311 ++ engines/ags/engine/platform/util/pe.h | 34 + .../ags/engine/platform/windows/acplwin.cpp | 1149 +++++ .../engine/platform/windows/gfx/ali3dd3d.cpp | 2090 +++++++++ .../engine/platform/windows/gfx/ali3dd3d.h | 336 ++ .../platform/windows/media/video/acwavi.cpp | 434 ++ .../platform/windows/media/video/acwavi3d.cpp | 962 ++++ .../ags/engine/platform/windows/minidump.cpp | 111 + .../platform/windows/setup/winsetup.cpp | 1255 +++++ .../engine/platform/windows/setup/winsetup.h | 38 + .../platform/windows/win_ex_handling.cpp | 97 + .../engine/platform/windows/win_ex_handling.h | 24 + .../platform/windows/winapi_exclusive.h | 51 + engines/ags/engine/plugin/agsplugin.cpp | 1109 +++++ engines/ags/engine/plugin/agsplugin.h | 570 +++ engines/ags/engine/plugin/global_plugin.cpp | 260 ++ engines/ags/engine/plugin/plugin_builtin.h | 41 + engines/ags/engine/plugin/plugin_engine.h | 46 + .../ags/engine/plugin/pluginobjectreader.cpp | 19 + .../ags/engine/plugin/pluginobjectreader.h | 28 + .../ags/engine/resource/DefaultGDF.gdf.xml | 18 + engines/ags/engine/resource/game-1.ICO | Bin 0 -> 33126 bytes engines/ags/engine/resource/resource.h | 46 + engines/ags/engine/resource/tintshader.fx | 53 + engines/ags/engine/resource/tintshader.fxo | Bin 0 -> 524 bytes .../ags/engine/resource/tintshaderLegacy.fx | 72 + .../ags/engine/resource/tintshaderLegacy.fxo | Bin 0 -> 892 bytes engines/ags/engine/resource/version.rc | 219 + engines/ags/engine/script/cc_error_engine.cpp | 0 engines/ags/engine/script/cc_instance.cpp | 2003 ++++++++ engines/ags/engine/script/cc_instance.h | 221 + engines/ags/engine/script/executingscript.cpp | 88 + engines/ags/engine/script/executingscript.h | 74 + engines/ags/engine/script/exports.cpp | 98 + engines/ags/engine/script/exports.h | 23 + .../engine/script/nonblockingscriptfunction.h | 48 + .../ags/engine/script/runtimescriptvalue.cpp | 321 ++ .../ags/engine/script/runtimescriptvalue.h | 385 ++ engines/ags/engine/script/script.cpp | 929 ++++ engines/ags/engine/script/script.h | 119 + engines/ags/engine/script/script_api.cpp | 243 + engines/ags/engine/script/script_api.h | 550 +++ engines/ags/engine/script/script_engine.cpp | 52 + engines/ags/engine/script/script_runtime.cpp | 291 ++ engines/ags/engine/script/script_runtime.h | 75 + engines/ags/engine/script/systemimports.cpp | 136 + engines/ags/engine/script/systemimports.h | 63 + engines/ags/engine/util/library.h | 62 + engines/ags/engine/util/library_dummy.h | 67 + engines/ags/engine/util/library_posix.h | 153 + engines/ags/engine/util/library_psp.h | 158 + engines/ags/engine/util/library_windows.h | 114 + engines/ags/engine/util/mutex.h | 50 + engines/ags/engine/util/mutex_base.h | 38 + engines/ags/engine/util/mutex_lock.h | 66 + engines/ags/engine/util/mutex_psp.h | 62 + engines/ags/engine/util/mutex_pthread.h | 59 + engines/ags/engine/util/mutex_std.h | 46 + engines/ags/engine/util/mutex_wii.h | 60 + engines/ags/engine/util/mutex_windows.h | 65 + engines/ags/engine/util/scaling.h | 173 + engines/ags/engine/util/thread.h | 56 + engines/ags/engine/util/thread_psp.h | 115 + engines/ags/engine/util/thread_pthread.h | 114 + engines/ags/engine/util/thread_std.h | 97 + engines/ags/engine/util/thread_wii.h | 114 + engines/ags/engine/util/thread_windows.h | 114 + engines/ags/shared/ac/audiocliptype.cpp | 48 + engines/ags/shared/ac/audiocliptype.h | 36 + engines/ags/shared/ac/characterinfo.cpp | 155 + engines/ags/shared/ac/characterinfo.h | 144 + engines/ags/shared/ac/common.cpp | 29 + engines/ags/shared/ac/common.h | 27 + engines/ags/shared/ac/common_defines.h | 123 + engines/ags/shared/ac/dialogtopic.cpp | 42 + engines/ags/shared/ac/dialogtopic.h | 68 + .../ags/shared/ac/dynobj/scriptaudioclip.cpp | 32 + .../ags/shared/ac/dynobj/scriptaudioclip.h | 54 + engines/ags/shared/ac/game_version.h | 146 + engines/ags/shared/ac/gamesetupstruct.cpp | 498 ++ engines/ags/shared/ac/gamesetupstruct.h | 165 + engines/ags/shared/ac/gamesetupstructbase.cpp | 267 ++ engines/ags/shared/ac/gamesetupstructbase.h | 222 + engines/ags/shared/ac/gamestructdefines.h | 256 + engines/ags/shared/ac/interfacebutton.h | 29 + engines/ags/shared/ac/interfaceelement.h | 51 + engines/ags/shared/ac/inventoryiteminfo.cpp | 55 + engines/ags/shared/ac/inventoryiteminfo.h | 35 + engines/ags/shared/ac/mousecursor.cpp | 58 + engines/ags/shared/ac/mousecursor.h | 40 + engines/ags/shared/ac/oldgamesetupstruct.h | 78 + engines/ags/shared/ac/spritecache.cpp | 983 ++++ engines/ags/shared/ac/spritecache.h | 240 + engines/ags/shared/ac/view.cpp | 214 + engines/ags/shared/ac/view.h | 80 + engines/ags/shared/ac/wordsdictionary.cpp | 173 + engines/ags/shared/ac/wordsdictionary.h | 55 + engines/ags/shared/api/stream_api.h | 90 + engines/ags/shared/core/asset.cpp | 37 + engines/ags/shared/core/asset.h | 60 + engines/ags/shared/core/assetmanager.cpp | 428 ++ engines/ags/shared/core/assetmanager.h | 155 + engines/ags/shared/core/def_version.h | 17 + engines/ags/shared/core/platform.h | 105 + engines/ags/shared/core/types.h | 61 + engines/ags/shared/debugging/assert.h | 23 + engines/ags/shared/debugging/debugmanager.cpp | 254 + engines/ags/shared/debugging/debugmanager.h | 162 + engines/ags/shared/debugging/out.h | 154 + engines/ags/shared/debugging/outputhandler.h | 59 + engines/ags/shared/font/agsfontrenderer.h | 59 + engines/ags/shared/font/fonts.cpp | 400 ++ engines/ags/shared/font/fonts.h | 112 + engines/ags/shared/font/ttffontrenderer.cpp | 142 + engines/ags/shared/font/ttffontrenderer.h | 48 + engines/ags/shared/font/wfnfont.cpp | 193 + engines/ags/shared/font/wfnfont.h | 102 + engines/ags/shared/font/wfnfontrenderer.cpp | 179 + engines/ags/shared/font/wfnfontrenderer.h | 46 + engines/ags/shared/game/customproperties.cpp | 136 + engines/ags/shared/game/customproperties.h | 102 + engines/ags/shared/game/interactions.cpp | 429 ++ engines/ags/shared/game/interactions.h | 212 + engines/ags/shared/game/main_game_file.cpp | 831 ++++ engines/ags/shared/game/main_game_file.h | 147 + engines/ags/shared/game/plugininfo.h | 47 + engines/ags/shared/game/room_file.cpp | 966 ++++ engines/ags/shared/game/room_file.h | 92 + .../ags/shared/game/room_file_deprecated.cpp | 135 + engines/ags/shared/game/room_version.h | 86 + engines/ags/shared/game/roomstruct.cpp | 325 ++ engines/ags/shared/game/roomstruct.h | 386 ++ engines/ags/shared/gfx/allegrobitmap.cpp | 502 ++ engines/ags/shared/gfx/allegrobitmap.h | 249 + engines/ags/shared/gfx/bitmap.cpp | 195 + engines/ags/shared/gfx/bitmap.h | 87 + engines/ags/shared/gfx/gfx_def.h | 117 + engines/ags/shared/gui/guibutton.cpp | 384 ++ engines/ags/shared/gui/guibutton.h | 136 + engines/ags/shared/gui/guidefines.h | 185 + engines/ags/shared/gui/guiinv.cpp | 144 + engines/ags/shared/gui/guiinv.h | 70 + engines/ags/shared/gui/guilabel.cpp | 128 + engines/ags/shared/gui/guilabel.h | 67 + engines/ags/shared/gui/guilistbox.cpp | 433 ++ engines/ags/shared/gui/guilistbox.h | 98 + engines/ags/shared/gui/guimain.cpp | 919 ++++ engines/ags/shared/gui/guimain.h | 241 + engines/ags/shared/gui/guiobject.cpp | 214 + engines/ags/shared/gui/guiobject.h | 126 + engines/ags/shared/gui/guislider.cpp | 267 ++ engines/ags/shared/gui/guislider.h | 71 + engines/ags/shared/gui/guitextbox.cpp | 146 + engines/ags/shared/gui/guitextbox.h | 65 + engines/ags/shared/script/cc_error.cpp | 63 + engines/ags/shared/script/cc_error.h | 34 + engines/ags/shared/script/cc_options.cpp | 33 + engines/ags/shared/script/cc_options.h | 34 + engines/ags/shared/script/cc_script.cpp | 404 ++ engines/ags/shared/script/cc_script.h | 75 + engines/ags/shared/script/script_common.h | 131 + engines/ags/shared/util/alignedstream.cpp | 389 ++ engines/ags/shared/util/alignedstream.h | 106 + engines/ags/shared/util/bbop.h | 158 + engines/ags/shared/util/bufferedstream.cpp | 134 + engines/ags/shared/util/bufferedstream.h | 69 + engines/ags/shared/util/compress.cpp | 434 ++ engines/ags/shared/util/compress.h | 40 + engines/ags/shared/util/datastream.cpp | 177 + engines/ags/shared/util/datastream.h | 132 + engines/ags/shared/util/directory.cpp | 72 + engines/ags/shared/util/directory.h | 45 + engines/ags/shared/util/error.h | 134 + engines/ags/shared/util/file.cpp | 177 + engines/ags/shared/util/file.h | 86 + engines/ags/shared/util/filestream.cpp | 180 + engines/ags/shared/util/filestream.h | 77 + engines/ags/shared/util/geometry.cpp | 133 + engines/ags/shared/util/geometry.h | 405 ++ engines/ags/shared/util/ini_util.cpp | 194 + engines/ags/shared/util/ini_util.h | 66 + engines/ags/shared/util/inifile.cpp | 301 ++ engines/ags/shared/util/inifile.h | 134 + engines/ags/shared/util/lzw.cpp | 271 ++ engines/ags/shared/util/lzw.h | 29 + engines/ags/shared/util/math.h | 90 + engines/ags/shared/util/memory.h | 245 + engines/ags/shared/util/misc.cpp | 200 + engines/ags/shared/util/misc.h | 65 + engines/ags/shared/util/multifilelib.h | 73 + engines/ags/shared/util/mutifilelib.cpp | 466 ++ engines/ags/shared/util/path.cpp | 250 + engines/ags/shared/util/path.h | 82 + engines/ags/shared/util/proxystream.cpp | 182 + engines/ags/shared/util/proxystream.h | 87 + engines/ags/shared/util/stdio_compat.c | 95 + engines/ags/shared/util/stdio_compat.h | 39 + engines/ags/shared/util/stream.cpp | 36 + engines/ags/shared/util/stream.h | 84 + engines/ags/shared/util/string.cpp | 1021 ++++ engines/ags/shared/util/string.h | 379 ++ engines/ags/shared/util/string_compat.c | 58 + engines/ags/shared/util/string_compat.h | 33 + engines/ags/shared/util/string_types.h | 114 + engines/ags/shared/util/string_utils.cpp | 171 + engines/ags/shared/util/string_utils.h | 76 + engines/ags/shared/util/textreader.h | 48 + engines/ags/shared/util/textstreamreader.cpp | 154 + engines/ags/shared/util/textstreamreader.h | 60 + engines/ags/shared/util/textstreamwriter.cpp | 121 + engines/ags/shared/util/textstreamwriter.h | 61 + engines/ags/shared/util/textwriter.h | 49 + engines/ags/shared/util/version.cpp | 150 + engines/ags/shared/util/version.h | 107 + engines/ags/shared/util/wgt2allg.cpp | 216 + engines/ags/shared/util/wgt2allg.h | 79 + 642 files changed, 123412 insertions(+) create mode 100644 engines/ags/engine/ac/asset_helper.h create mode 100644 engines/ags/engine/ac/audiochannel.cpp create mode 100644 engines/ags/engine/ac/audiochannel.h create mode 100644 engines/ags/engine/ac/audioclip.cpp create mode 100644 engines/ags/engine/ac/audioclip.h create mode 100644 engines/ags/engine/ac/button.cpp create mode 100644 engines/ags/engine/ac/button.h create mode 100644 engines/ags/engine/ac/cdaudio.cpp create mode 100644 engines/ags/engine/ac/cdaudio.h create mode 100644 engines/ags/engine/ac/character.cpp create mode 100644 engines/ags/engine/ac/character.h create mode 100644 engines/ags/engine/ac/charactercache.h create mode 100644 engines/ags/engine/ac/characterextras.cpp create mode 100644 engines/ags/engine/ac/characterextras.h create mode 100644 engines/ags/engine/ac/characterinfo_engine.cpp create mode 100644 engines/ags/engine/ac/datetime.cpp create mode 100644 engines/ags/engine/ac/datetime.h create mode 100644 engines/ags/engine/ac/dialog.cpp create mode 100644 engines/ags/engine/ac/dialog.h create mode 100644 engines/ags/engine/ac/dialogoptionsrendering.cpp create mode 100644 engines/ags/engine/ac/dialogoptionsrendering.h create mode 100644 engines/ags/engine/ac/display.cpp create mode 100644 engines/ags/engine/ac/display.h create mode 100644 engines/ags/engine/ac/draw.cpp create mode 100644 engines/ags/engine/ac/draw.h create mode 100644 engines/ags/engine/ac/draw_software.cpp create mode 100644 engines/ags/engine/ac/draw_software.h create mode 100644 engines/ags/engine/ac/drawingsurface.cpp create mode 100644 engines/ags/engine/ac/drawingsurface.h create mode 100644 engines/ags/engine/ac/dynamicsprite.cpp create mode 100644 engines/ags/engine/ac/dynamicsprite.h create mode 100644 engines/ags/engine/ac/dynobj/all_dynamicclasses.h create mode 100644 engines/ags/engine/ac/dynobj/all_scriptclasses.h create mode 100644 engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h create mode 100644 engines/ags/engine/ac/dynobj/cc_audiochannel.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_audiochannel.h create mode 100644 engines/ags/engine/ac/dynobj/cc_audioclip.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_audioclip.h create mode 100644 engines/ags/engine/ac/dynobj/cc_character.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_character.h create mode 100644 engines/ags/engine/ac/dynobj/cc_dialog.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_dialog.h create mode 100644 engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_dynamicarray.h create mode 100644 engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_dynamicobject.h create mode 100644 engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h create mode 100644 engines/ags/engine/ac/dynobj/cc_gui.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_gui.h create mode 100644 engines/ags/engine/ac/dynobj/cc_guiobject.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_guiobject.h create mode 100644 engines/ags/engine/ac/dynobj/cc_hotspot.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_hotspot.h create mode 100644 engines/ags/engine/ac/dynobj/cc_inventory.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_inventory.h create mode 100644 engines/ags/engine/ac/dynobj/cc_object.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_object.h create mode 100644 engines/ags/engine/ac/dynobj/cc_region.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_region.h create mode 100644 engines/ags/engine/ac/dynobj/cc_serializer.cpp create mode 100644 engines/ags/engine/ac/dynobj/cc_serializer.h create mode 100644 engines/ags/engine/ac/dynobj/managedobjectpool.cpp create mode 100644 engines/ags/engine/ac/dynobj/managedobjectpool.h create mode 100644 engines/ags/engine/ac/dynobj/scriptaudiochannel.h create mode 100644 engines/ags/engine/ac/dynobj/scriptcamera.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptcamera.h create mode 100644 engines/ags/engine/ac/dynobj/scriptcontainers.h create mode 100644 engines/ags/engine/ac/dynobj/scriptdatetime.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptdatetime.h create mode 100644 engines/ags/engine/ac/dynobj/scriptdialog.h create mode 100644 engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h create mode 100644 engines/ags/engine/ac/dynobj/scriptdict.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptdict.h create mode 100644 engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptdrawingsurface.h create mode 100644 engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptdynamicsprite.h create mode 100644 engines/ags/engine/ac/dynobj/scriptfile.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptfile.h create mode 100644 engines/ags/engine/ac/dynobj/scriptgui.h create mode 100644 engines/ags/engine/ac/dynobj/scripthotspot.h create mode 100644 engines/ags/engine/ac/dynobj/scriptinvitem.h create mode 100644 engines/ags/engine/ac/dynobj/scriptmouse.h create mode 100644 engines/ags/engine/ac/dynobj/scriptobject.h create mode 100644 engines/ags/engine/ac/dynobj/scriptoverlay.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptoverlay.h create mode 100644 engines/ags/engine/ac/dynobj/scriptregion.h create mode 100644 engines/ags/engine/ac/dynobj/scriptset.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptset.h create mode 100644 engines/ags/engine/ac/dynobj/scriptstring.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptstring.h create mode 100644 engines/ags/engine/ac/dynobj/scriptsystem.h create mode 100644 engines/ags/engine/ac/dynobj/scriptuserobject.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptuserobject.h create mode 100644 engines/ags/engine/ac/dynobj/scriptviewframe.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptviewframe.h create mode 100644 engines/ags/engine/ac/dynobj/scriptviewport.cpp create mode 100644 engines/ags/engine/ac/dynobj/scriptviewport.h create mode 100644 engines/ags/engine/ac/event.cpp create mode 100644 engines/ags/engine/ac/event.h create mode 100644 engines/ags/engine/ac/file.cpp create mode 100644 engines/ags/engine/ac/file.h create mode 100644 engines/ags/engine/ac/game.cpp create mode 100644 engines/ags/engine/ac/game.h create mode 100644 engines/ags/engine/ac/gamesetup.cpp create mode 100644 engines/ags/engine/ac/gamesetup.h create mode 100644 engines/ags/engine/ac/gamestate.cpp create mode 100644 engines/ags/engine/ac/gamestate.h create mode 100644 engines/ags/engine/ac/global_api.cpp create mode 100644 engines/ags/engine/ac/global_audio.cpp create mode 100644 engines/ags/engine/ac/global_audio.h create mode 100644 engines/ags/engine/ac/global_button.cpp create mode 100644 engines/ags/engine/ac/global_button.h create mode 100644 engines/ags/engine/ac/global_character.cpp create mode 100644 engines/ags/engine/ac/global_character.h create mode 100644 engines/ags/engine/ac/global_datetime.cpp create mode 100644 engines/ags/engine/ac/global_datetime.h create mode 100644 engines/ags/engine/ac/global_debug.cpp create mode 100644 engines/ags/engine/ac/global_debug.h create mode 100644 engines/ags/engine/ac/global_dialog.cpp create mode 100644 engines/ags/engine/ac/global_dialog.h create mode 100644 engines/ags/engine/ac/global_display.cpp create mode 100644 engines/ags/engine/ac/global_display.h create mode 100644 engines/ags/engine/ac/global_drawingsurface.cpp create mode 100644 engines/ags/engine/ac/global_drawingsurface.h create mode 100644 engines/ags/engine/ac/global_dynamicsprite.cpp create mode 100644 engines/ags/engine/ac/global_dynamicsprite.h create mode 100644 engines/ags/engine/ac/global_file.cpp create mode 100644 engines/ags/engine/ac/global_file.h create mode 100644 engines/ags/engine/ac/global_game.cpp create mode 100644 engines/ags/engine/ac/global_game.h create mode 100644 engines/ags/engine/ac/global_gui.cpp create mode 100644 engines/ags/engine/ac/global_gui.h create mode 100644 engines/ags/engine/ac/global_hotspot.cpp create mode 100644 engines/ags/engine/ac/global_hotspot.h create mode 100644 engines/ags/engine/ac/global_inventoryitem.cpp create mode 100644 engines/ags/engine/ac/global_inventoryitem.h create mode 100644 engines/ags/engine/ac/global_invwindow.cpp create mode 100644 engines/ags/engine/ac/global_invwindow.h create mode 100644 engines/ags/engine/ac/global_label.cpp create mode 100644 engines/ags/engine/ac/global_label.h create mode 100644 engines/ags/engine/ac/global_listbox.cpp create mode 100644 engines/ags/engine/ac/global_listbox.h create mode 100644 engines/ags/engine/ac/global_mouse.cpp create mode 100644 engines/ags/engine/ac/global_mouse.h create mode 100644 engines/ags/engine/ac/global_object.cpp create mode 100644 engines/ags/engine/ac/global_object.h create mode 100644 engines/ags/engine/ac/global_overlay.cpp create mode 100644 engines/ags/engine/ac/global_overlay.h create mode 100644 engines/ags/engine/ac/global_palette.cpp create mode 100644 engines/ags/engine/ac/global_palette.h create mode 100644 engines/ags/engine/ac/global_parser.cpp create mode 100644 engines/ags/engine/ac/global_parser.h create mode 100644 engines/ags/engine/ac/global_plugin.h create mode 100644 engines/ags/engine/ac/global_record.cpp create mode 100644 engines/ags/engine/ac/global_record.h create mode 100644 engines/ags/engine/ac/global_region.cpp create mode 100644 engines/ags/engine/ac/global_region.h create mode 100644 engines/ags/engine/ac/global_room.cpp create mode 100644 engines/ags/engine/ac/global_room.h create mode 100644 engines/ags/engine/ac/global_screen.cpp create mode 100644 engines/ags/engine/ac/global_screen.h create mode 100644 engines/ags/engine/ac/global_slider.cpp create mode 100644 engines/ags/engine/ac/global_slider.h create mode 100644 engines/ags/engine/ac/global_string.cpp create mode 100644 engines/ags/engine/ac/global_string.h create mode 100644 engines/ags/engine/ac/global_textbox.cpp create mode 100644 engines/ags/engine/ac/global_textbox.h create mode 100644 engines/ags/engine/ac/global_timer.cpp create mode 100644 engines/ags/engine/ac/global_timer.h create mode 100644 engines/ags/engine/ac/global_translation.cpp create mode 100644 engines/ags/engine/ac/global_translation.h create mode 100644 engines/ags/engine/ac/global_video.cpp create mode 100644 engines/ags/engine/ac/global_video.h create mode 100644 engines/ags/engine/ac/global_viewframe.cpp create mode 100644 engines/ags/engine/ac/global_viewframe.h create mode 100644 engines/ags/engine/ac/global_viewport.cpp create mode 100644 engines/ags/engine/ac/global_viewport.h create mode 100644 engines/ags/engine/ac/global_walkablearea.cpp create mode 100644 engines/ags/engine/ac/global_walkablearea.h create mode 100644 engines/ags/engine/ac/global_walkbehind.cpp create mode 100644 engines/ags/engine/ac/global_walkbehind.h create mode 100644 engines/ags/engine/ac/gui.cpp create mode 100644 engines/ags/engine/ac/gui.h create mode 100644 engines/ags/engine/ac/guicontrol.cpp create mode 100644 engines/ags/engine/ac/guicontrol.h create mode 100644 engines/ags/engine/ac/guiinv.cpp create mode 100644 engines/ags/engine/ac/hotspot.cpp create mode 100644 engines/ags/engine/ac/hotspot.h create mode 100644 engines/ags/engine/ac/interfacebutton.cpp create mode 100644 engines/ags/engine/ac/interfaceelement.cpp create mode 100644 engines/ags/engine/ac/inventoryitem.cpp create mode 100644 engines/ags/engine/ac/inventoryitem.h create mode 100644 engines/ags/engine/ac/invwindow.cpp create mode 100644 engines/ags/engine/ac/invwindow.h create mode 100644 engines/ags/engine/ac/keycode.cpp create mode 100644 engines/ags/engine/ac/keycode.h create mode 100644 engines/ags/engine/ac/label.cpp create mode 100644 engines/ags/engine/ac/label.h create mode 100644 engines/ags/engine/ac/lipsync.h create mode 100644 engines/ags/engine/ac/listbox.cpp create mode 100644 engines/ags/engine/ac/listbox.h create mode 100644 engines/ags/engine/ac/math.cpp create mode 100644 engines/ags/engine/ac/math.h create mode 100644 engines/ags/engine/ac/mouse.cpp create mode 100644 engines/ags/engine/ac/mouse.h create mode 100644 engines/ags/engine/ac/movelist.cpp create mode 100644 engines/ags/engine/ac/movelist.h create mode 100644 engines/ags/engine/ac/object.cpp create mode 100644 engines/ags/engine/ac/object.h create mode 100644 engines/ags/engine/ac/objectcache.h create mode 100644 engines/ags/engine/ac/overlay.cpp create mode 100644 engines/ags/engine/ac/overlay.h create mode 100644 engines/ags/engine/ac/parser.cpp create mode 100644 engines/ags/engine/ac/parser.h create mode 100644 engines/ags/engine/ac/path_helper.h create mode 100644 engines/ags/engine/ac/properties.cpp create mode 100644 engines/ags/engine/ac/properties.h create mode 100644 engines/ags/engine/ac/region.cpp create mode 100644 engines/ags/engine/ac/region.h create mode 100644 engines/ags/engine/ac/richgamemedia.cpp create mode 100644 engines/ags/engine/ac/richgamemedia.h create mode 100644 engines/ags/engine/ac/room.cpp create mode 100644 engines/ags/engine/ac/room.h create mode 100644 engines/ags/engine/ac/roomobject.cpp create mode 100644 engines/ags/engine/ac/roomobject.h create mode 100644 engines/ags/engine/ac/roomstatus.cpp create mode 100644 engines/ags/engine/ac/roomstatus.h create mode 100644 engines/ags/engine/ac/route_finder.cpp create mode 100644 engines/ags/engine/ac/route_finder.h create mode 100644 engines/ags/engine/ac/route_finder_impl.cpp create mode 100644 engines/ags/engine/ac/route_finder_impl.h create mode 100644 engines/ags/engine/ac/route_finder_impl_legacy.cpp create mode 100644 engines/ags/engine/ac/route_finder_impl_legacy.h create mode 100644 engines/ags/engine/ac/route_finder_jps.inl create mode 100644 engines/ags/engine/ac/runtime_defines.h create mode 100644 engines/ags/engine/ac/screen.cpp create mode 100644 engines/ags/engine/ac/screen.h create mode 100644 engines/ags/engine/ac/screenoverlay.cpp create mode 100644 engines/ags/engine/ac/screenoverlay.h create mode 100644 engines/ags/engine/ac/scriptcontainers.cpp create mode 100644 engines/ags/engine/ac/slider.cpp create mode 100644 engines/ags/engine/ac/slider.h create mode 100644 engines/ags/engine/ac/speech.cpp create mode 100644 engines/ags/engine/ac/speech.h create mode 100644 engines/ags/engine/ac/sprite.cpp create mode 100644 engines/ags/engine/ac/sprite.h create mode 100644 engines/ags/engine/ac/spritecache_engine.cpp create mode 100644 engines/ags/engine/ac/spritelistentry.h create mode 100644 engines/ags/engine/ac/statobj/agsstaticobject.cpp create mode 100644 engines/ags/engine/ac/statobj/agsstaticobject.h create mode 100644 engines/ags/engine/ac/statobj/staticarray.cpp create mode 100644 engines/ags/engine/ac/statobj/staticarray.h create mode 100644 engines/ags/engine/ac/statobj/staticobject.h create mode 100644 engines/ags/engine/ac/string.cpp create mode 100644 engines/ags/engine/ac/string.h create mode 100644 engines/ags/engine/ac/sys_events.cpp create mode 100644 engines/ags/engine/ac/sys_events.h create mode 100644 engines/ags/engine/ac/system.cpp create mode 100644 engines/ags/engine/ac/system.h create mode 100644 engines/ags/engine/ac/textbox.cpp create mode 100644 engines/ags/engine/ac/textbox.h create mode 100644 engines/ags/engine/ac/timer.cpp create mode 100644 engines/ags/engine/ac/timer.h create mode 100644 engines/ags/engine/ac/topbarsettings.h create mode 100644 engines/ags/engine/ac/translation.cpp create mode 100644 engines/ags/engine/ac/translation.h create mode 100644 engines/ags/engine/ac/tree_map.cpp create mode 100644 engines/ags/engine/ac/tree_map.h create mode 100644 engines/ags/engine/ac/viewframe.cpp create mode 100644 engines/ags/engine/ac/viewframe.h create mode 100644 engines/ags/engine/ac/viewport_script.cpp create mode 100644 engines/ags/engine/ac/walkablearea.cpp create mode 100644 engines/ags/engine/ac/walkablearea.h create mode 100644 engines/ags/engine/ac/walkbehind.cpp create mode 100644 engines/ags/engine/ac/walkbehind.h create mode 100644 engines/ags/engine/debugging/agseditordebugger.h create mode 100644 engines/ags/engine/debugging/consoleoutputtarget.cpp create mode 100644 engines/ags/engine/debugging/consoleoutputtarget.h create mode 100644 engines/ags/engine/debugging/debug.cpp create mode 100644 engines/ags/engine/debugging/debug_log.h create mode 100644 engines/ags/engine/debugging/debugger.h create mode 100644 engines/ags/engine/debugging/dummyagsdebugger.h create mode 100644 engines/ags/engine/debugging/filebasedagsdebugger.cpp create mode 100644 engines/ags/engine/debugging/filebasedagsdebugger.h create mode 100644 engines/ags/engine/debugging/logfile.cpp create mode 100644 engines/ags/engine/debugging/logfile.h create mode 100644 engines/ags/engine/debugging/messagebuffer.cpp create mode 100644 engines/ags/engine/debugging/messagebuffer.h create mode 100644 engines/ags/engine/device/mousew32.cpp create mode 100644 engines/ags/engine/device/mousew32.h create mode 100644 engines/ags/engine/font/fonts_engine.cpp create mode 100644 engines/ags/engine/game/game_init.cpp create mode 100644 engines/ags/engine/game/game_init.h create mode 100644 engines/ags/engine/game/savegame.cpp create mode 100644 engines/ags/engine/game/savegame.h create mode 100644 engines/ags/engine/game/savegame_components.cpp create mode 100644 engines/ags/engine/game/savegame_components.h create mode 100644 engines/ags/engine/game/savegame_internal.h create mode 100644 engines/ags/engine/game/viewport.cpp create mode 100644 engines/ags/engine/game/viewport.h create mode 100644 engines/ags/engine/gfx/ali3dexception.h create mode 100644 engines/ags/engine/gfx/ali3dogl.cpp create mode 100644 engines/ags/engine/gfx/ali3dogl.h create mode 100644 engines/ags/engine/gfx/ali3dsw.cpp create mode 100644 engines/ags/engine/gfx/ali3dsw.h create mode 100644 engines/ags/engine/gfx/blender.cpp create mode 100644 engines/ags/engine/gfx/blender.h create mode 100644 engines/ags/engine/gfx/color_engine.cpp create mode 100644 engines/ags/engine/gfx/ddb.h create mode 100644 engines/ags/engine/gfx/gfx_util.cpp create mode 100644 engines/ags/engine/gfx/gfx_util.h create mode 100644 engines/ags/engine/gfx/gfxdefines.h create mode 100644 engines/ags/engine/gfx/gfxdriverbase.cpp create mode 100644 engines/ags/engine/gfx/gfxdriverbase.h create mode 100644 engines/ags/engine/gfx/gfxdriverfactory.cpp create mode 100644 engines/ags/engine/gfx/gfxdriverfactory.h create mode 100644 engines/ags/engine/gfx/gfxdriverfactorybase.h create mode 100644 engines/ags/engine/gfx/gfxfilter.h create mode 100644 engines/ags/engine/gfx/gfxfilter_aad3d.cpp create mode 100644 engines/ags/engine/gfx/gfxfilter_aad3d.h create mode 100644 engines/ags/engine/gfx/gfxfilter_aaogl.cpp create mode 100644 engines/ags/engine/gfx/gfxfilter_aaogl.h create mode 100644 engines/ags/engine/gfx/gfxfilter_allegro.cpp create mode 100644 engines/ags/engine/gfx/gfxfilter_allegro.h create mode 100644 engines/ags/engine/gfx/gfxfilter_d3d.cpp create mode 100644 engines/ags/engine/gfx/gfxfilter_d3d.h create mode 100644 engines/ags/engine/gfx/gfxfilter_hqx.cpp create mode 100644 engines/ags/engine/gfx/gfxfilter_hqx.h create mode 100644 engines/ags/engine/gfx/gfxfilter_ogl.cpp create mode 100644 engines/ags/engine/gfx/gfxfilter_ogl.h create mode 100644 engines/ags/engine/gfx/gfxfilter_scaling.cpp create mode 100644 engines/ags/engine/gfx/gfxfilter_scaling.h create mode 100644 engines/ags/engine/gfx/gfxmodelist.h create mode 100644 engines/ags/engine/gfx/graphicsdriver.h create mode 100644 engines/ags/engine/gfx/hq2x3x.h create mode 100644 engines/ags/engine/gfx/ogl_headers.h create mode 100644 engines/ags/engine/gui/animatingguibutton.cpp create mode 100644 engines/ags/engine/gui/animatingguibutton.h create mode 100644 engines/ags/engine/gui/cscidialog.cpp create mode 100644 engines/ags/engine/gui/cscidialog.h create mode 100644 engines/ags/engine/gui/gui_engine.cpp create mode 100644 engines/ags/engine/gui/guidialog.cpp create mode 100644 engines/ags/engine/gui/guidialog.h create mode 100644 engines/ags/engine/gui/guidialogdefines.h create mode 100644 engines/ags/engine/gui/guidialoginternaldefs.h create mode 100644 engines/ags/engine/gui/mycontrols.h create mode 100644 engines/ags/engine/gui/mylabel.cpp create mode 100644 engines/ags/engine/gui/mylabel.h create mode 100644 engines/ags/engine/gui/mylistbox.cpp create mode 100644 engines/ags/engine/gui/mylistbox.h create mode 100644 engines/ags/engine/gui/mypushbutton.cpp create mode 100644 engines/ags/engine/gui/mypushbutton.h create mode 100644 engines/ags/engine/gui/mytextbox.cpp create mode 100644 engines/ags/engine/gui/mytextbox.h create mode 100644 engines/ags/engine/gui/newcontrol.cpp create mode 100644 engines/ags/engine/gui/newcontrol.h create mode 100644 engines/ags/engine/main/config.cpp create mode 100644 engines/ags/engine/main/config.h create mode 100644 engines/ags/engine/main/engine.cpp create mode 100644 engines/ags/engine/main/engine.h create mode 100644 engines/ags/engine/main/engine_setup.cpp create mode 100644 engines/ags/engine/main/engine_setup.h create mode 100644 engines/ags/engine/main/game_file.cpp create mode 100644 engines/ags/engine/main/game_file.h create mode 100644 engines/ags/engine/main/game_run.cpp create mode 100644 engines/ags/engine/main/game_run.h create mode 100644 engines/ags/engine/main/game_start.cpp create mode 100644 engines/ags/engine/main/game_start.h create mode 100644 engines/ags/engine/main/graphics_mode.cpp create mode 100644 engines/ags/engine/main/graphics_mode.h create mode 100644 engines/ags/engine/main/main.cpp create mode 100644 engines/ags/engine/main/main.h create mode 100644 engines/ags/engine/main/main_allegro.cpp create mode 100644 engines/ags/engine/main/main_allegro.h create mode 100644 engines/ags/engine/main/maindefines_ex.h create mode 100644 engines/ags/engine/main/mainheader.h create mode 100644 engines/ags/engine/main/quit.cpp create mode 100644 engines/ags/engine/main/quit.h create mode 100644 engines/ags/engine/main/update.cpp create mode 100644 engines/ags/engine/main/update.h create mode 100644 engines/ags/engine/media/audio/ambientsound.cpp create mode 100644 engines/ags/engine/media/audio/ambientsound.h create mode 100644 engines/ags/engine/media/audio/audio.cpp create mode 100644 engines/ags/engine/media/audio/audio.h create mode 100644 engines/ags/engine/media/audio/audio_system.h create mode 100644 engines/ags/engine/media/audio/audiodefines.h create mode 100644 engines/ags/engine/media/audio/audiointernaldefs.h create mode 100644 engines/ags/engine/media/audio/clip_mydumbmod.cpp create mode 100644 engines/ags/engine/media/audio/clip_mydumbmod.h create mode 100644 engines/ags/engine/media/audio/clip_myjgmod.cpp create mode 100644 engines/ags/engine/media/audio/clip_myjgmod.h create mode 100644 engines/ags/engine/media/audio/clip_mymidi.cpp create mode 100644 engines/ags/engine/media/audio/clip_mymidi.h create mode 100644 engines/ags/engine/media/audio/clip_mymp3.cpp create mode 100644 engines/ags/engine/media/audio/clip_mymp3.h create mode 100644 engines/ags/engine/media/audio/clip_myogg.cpp create mode 100644 engines/ags/engine/media/audio/clip_myogg.h create mode 100644 engines/ags/engine/media/audio/clip_mystaticmp3.cpp create mode 100644 engines/ags/engine/media/audio/clip_mystaticmp3.h create mode 100644 engines/ags/engine/media/audio/clip_mystaticogg.cpp create mode 100644 engines/ags/engine/media/audio/clip_mystaticogg.h create mode 100644 engines/ags/engine/media/audio/clip_mywave.cpp create mode 100644 engines/ags/engine/media/audio/clip_mywave.h create mode 100644 engines/ags/engine/media/audio/queuedaudioitem.cpp create mode 100644 engines/ags/engine/media/audio/queuedaudioitem.h create mode 100644 engines/ags/engine/media/audio/sound.cpp create mode 100644 engines/ags/engine/media/audio/sound.h create mode 100644 engines/ags/engine/media/audio/soundcache.cpp create mode 100644 engines/ags/engine/media/audio/soundcache.h create mode 100644 engines/ags/engine/media/audio/soundclip.cpp create mode 100644 engines/ags/engine/media/audio/soundclip.h create mode 100644 engines/ags/engine/media/video/VMR9Graph.h create mode 100644 engines/ags/engine/media/video/video.cpp create mode 100644 engines/ags/engine/media/video/video.h create mode 100644 engines/ags/engine/platform/android/acpland.cpp create mode 100644 engines/ags/engine/platform/base/agsplatformdriver.cpp create mode 100644 engines/ags/engine/platform/base/agsplatformdriver.h create mode 100644 engines/ags/engine/platform/ios/acplios.cpp create mode 100644 engines/ags/engine/platform/linux/acpllnx.cpp create mode 100644 engines/ags/engine/platform/linux/icon.xpm create mode 100644 engines/ags/engine/platform/osx/acplmac.cpp create mode 100644 engines/ags/engine/platform/osx/alplmac.mm create mode 100644 engines/ags/engine/platform/util/libc.c create mode 100644 engines/ags/engine/platform/util/pe.c create mode 100644 engines/ags/engine/platform/util/pe.h create mode 100644 engines/ags/engine/platform/windows/acplwin.cpp create mode 100644 engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp create mode 100644 engines/ags/engine/platform/windows/gfx/ali3dd3d.h create mode 100644 engines/ags/engine/platform/windows/media/video/acwavi.cpp create mode 100644 engines/ags/engine/platform/windows/media/video/acwavi3d.cpp create mode 100644 engines/ags/engine/platform/windows/minidump.cpp create mode 100644 engines/ags/engine/platform/windows/setup/winsetup.cpp create mode 100644 engines/ags/engine/platform/windows/setup/winsetup.h create mode 100644 engines/ags/engine/platform/windows/win_ex_handling.cpp create mode 100644 engines/ags/engine/platform/windows/win_ex_handling.h create mode 100644 engines/ags/engine/platform/windows/winapi_exclusive.h create mode 100644 engines/ags/engine/plugin/agsplugin.cpp create mode 100644 engines/ags/engine/plugin/agsplugin.h create mode 100644 engines/ags/engine/plugin/global_plugin.cpp create mode 100644 engines/ags/engine/plugin/plugin_builtin.h create mode 100644 engines/ags/engine/plugin/plugin_engine.h create mode 100644 engines/ags/engine/plugin/pluginobjectreader.cpp create mode 100644 engines/ags/engine/plugin/pluginobjectreader.h create mode 100644 engines/ags/engine/resource/DefaultGDF.gdf.xml create mode 100644 engines/ags/engine/resource/game-1.ICO create mode 100644 engines/ags/engine/resource/resource.h create mode 100644 engines/ags/engine/resource/tintshader.fx create mode 100644 engines/ags/engine/resource/tintshader.fxo create mode 100644 engines/ags/engine/resource/tintshaderLegacy.fx create mode 100644 engines/ags/engine/resource/tintshaderLegacy.fxo create mode 100644 engines/ags/engine/resource/version.rc create mode 100644 engines/ags/engine/script/cc_error_engine.cpp create mode 100644 engines/ags/engine/script/cc_instance.cpp create mode 100644 engines/ags/engine/script/cc_instance.h create mode 100644 engines/ags/engine/script/executingscript.cpp create mode 100644 engines/ags/engine/script/executingscript.h create mode 100644 engines/ags/engine/script/exports.cpp create mode 100644 engines/ags/engine/script/exports.h create mode 100644 engines/ags/engine/script/nonblockingscriptfunction.h create mode 100644 engines/ags/engine/script/runtimescriptvalue.cpp create mode 100644 engines/ags/engine/script/runtimescriptvalue.h create mode 100644 engines/ags/engine/script/script.cpp create mode 100644 engines/ags/engine/script/script.h create mode 100644 engines/ags/engine/script/script_api.cpp create mode 100644 engines/ags/engine/script/script_api.h create mode 100644 engines/ags/engine/script/script_engine.cpp create mode 100644 engines/ags/engine/script/script_runtime.cpp create mode 100644 engines/ags/engine/script/script_runtime.h create mode 100644 engines/ags/engine/script/systemimports.cpp create mode 100644 engines/ags/engine/script/systemimports.h create mode 100644 engines/ags/engine/util/library.h create mode 100644 engines/ags/engine/util/library_dummy.h create mode 100644 engines/ags/engine/util/library_posix.h create mode 100644 engines/ags/engine/util/library_psp.h create mode 100644 engines/ags/engine/util/library_windows.h create mode 100644 engines/ags/engine/util/mutex.h create mode 100644 engines/ags/engine/util/mutex_base.h create mode 100644 engines/ags/engine/util/mutex_lock.h create mode 100644 engines/ags/engine/util/mutex_psp.h create mode 100644 engines/ags/engine/util/mutex_pthread.h create mode 100644 engines/ags/engine/util/mutex_std.h create mode 100644 engines/ags/engine/util/mutex_wii.h create mode 100644 engines/ags/engine/util/mutex_windows.h create mode 100644 engines/ags/engine/util/scaling.h create mode 100644 engines/ags/engine/util/thread.h create mode 100644 engines/ags/engine/util/thread_psp.h create mode 100644 engines/ags/engine/util/thread_pthread.h create mode 100644 engines/ags/engine/util/thread_std.h create mode 100644 engines/ags/engine/util/thread_wii.h create mode 100644 engines/ags/engine/util/thread_windows.h create mode 100644 engines/ags/shared/ac/audiocliptype.cpp create mode 100644 engines/ags/shared/ac/audiocliptype.h create mode 100644 engines/ags/shared/ac/characterinfo.cpp create mode 100644 engines/ags/shared/ac/characterinfo.h create mode 100644 engines/ags/shared/ac/common.cpp create mode 100644 engines/ags/shared/ac/common.h create mode 100644 engines/ags/shared/ac/common_defines.h create mode 100644 engines/ags/shared/ac/dialogtopic.cpp create mode 100644 engines/ags/shared/ac/dialogtopic.h create mode 100644 engines/ags/shared/ac/dynobj/scriptaudioclip.cpp create mode 100644 engines/ags/shared/ac/dynobj/scriptaudioclip.h create mode 100644 engines/ags/shared/ac/game_version.h create mode 100644 engines/ags/shared/ac/gamesetupstruct.cpp create mode 100644 engines/ags/shared/ac/gamesetupstruct.h create mode 100644 engines/ags/shared/ac/gamesetupstructbase.cpp create mode 100644 engines/ags/shared/ac/gamesetupstructbase.h create mode 100644 engines/ags/shared/ac/gamestructdefines.h create mode 100644 engines/ags/shared/ac/interfacebutton.h create mode 100644 engines/ags/shared/ac/interfaceelement.h create mode 100644 engines/ags/shared/ac/inventoryiteminfo.cpp create mode 100644 engines/ags/shared/ac/inventoryiteminfo.h create mode 100644 engines/ags/shared/ac/mousecursor.cpp create mode 100644 engines/ags/shared/ac/mousecursor.h create mode 100644 engines/ags/shared/ac/oldgamesetupstruct.h create mode 100644 engines/ags/shared/ac/spritecache.cpp create mode 100644 engines/ags/shared/ac/spritecache.h create mode 100644 engines/ags/shared/ac/view.cpp create mode 100644 engines/ags/shared/ac/view.h create mode 100644 engines/ags/shared/ac/wordsdictionary.cpp create mode 100644 engines/ags/shared/ac/wordsdictionary.h create mode 100644 engines/ags/shared/api/stream_api.h create mode 100644 engines/ags/shared/core/asset.cpp create mode 100644 engines/ags/shared/core/asset.h create mode 100644 engines/ags/shared/core/assetmanager.cpp create mode 100644 engines/ags/shared/core/assetmanager.h create mode 100644 engines/ags/shared/core/def_version.h create mode 100644 engines/ags/shared/core/platform.h create mode 100644 engines/ags/shared/core/types.h create mode 100644 engines/ags/shared/debugging/assert.h create mode 100644 engines/ags/shared/debugging/debugmanager.cpp create mode 100644 engines/ags/shared/debugging/debugmanager.h create mode 100644 engines/ags/shared/debugging/out.h create mode 100644 engines/ags/shared/debugging/outputhandler.h create mode 100644 engines/ags/shared/font/agsfontrenderer.h create mode 100644 engines/ags/shared/font/fonts.cpp create mode 100644 engines/ags/shared/font/fonts.h create mode 100644 engines/ags/shared/font/ttffontrenderer.cpp create mode 100644 engines/ags/shared/font/ttffontrenderer.h create mode 100644 engines/ags/shared/font/wfnfont.cpp create mode 100644 engines/ags/shared/font/wfnfont.h create mode 100644 engines/ags/shared/font/wfnfontrenderer.cpp create mode 100644 engines/ags/shared/font/wfnfontrenderer.h create mode 100644 engines/ags/shared/game/customproperties.cpp create mode 100644 engines/ags/shared/game/customproperties.h create mode 100644 engines/ags/shared/game/interactions.cpp create mode 100644 engines/ags/shared/game/interactions.h create mode 100644 engines/ags/shared/game/main_game_file.cpp create mode 100644 engines/ags/shared/game/main_game_file.h create mode 100644 engines/ags/shared/game/plugininfo.h create mode 100644 engines/ags/shared/game/room_file.cpp create mode 100644 engines/ags/shared/game/room_file.h create mode 100644 engines/ags/shared/game/room_file_deprecated.cpp create mode 100644 engines/ags/shared/game/room_version.h create mode 100644 engines/ags/shared/game/roomstruct.cpp create mode 100644 engines/ags/shared/game/roomstruct.h create mode 100644 engines/ags/shared/gfx/allegrobitmap.cpp create mode 100644 engines/ags/shared/gfx/allegrobitmap.h create mode 100644 engines/ags/shared/gfx/bitmap.cpp create mode 100644 engines/ags/shared/gfx/bitmap.h create mode 100644 engines/ags/shared/gfx/gfx_def.h create mode 100644 engines/ags/shared/gui/guibutton.cpp create mode 100644 engines/ags/shared/gui/guibutton.h create mode 100644 engines/ags/shared/gui/guidefines.h create mode 100644 engines/ags/shared/gui/guiinv.cpp create mode 100644 engines/ags/shared/gui/guiinv.h create mode 100644 engines/ags/shared/gui/guilabel.cpp create mode 100644 engines/ags/shared/gui/guilabel.h create mode 100644 engines/ags/shared/gui/guilistbox.cpp create mode 100644 engines/ags/shared/gui/guilistbox.h create mode 100644 engines/ags/shared/gui/guimain.cpp create mode 100644 engines/ags/shared/gui/guimain.h create mode 100644 engines/ags/shared/gui/guiobject.cpp create mode 100644 engines/ags/shared/gui/guiobject.h create mode 100644 engines/ags/shared/gui/guislider.cpp create mode 100644 engines/ags/shared/gui/guislider.h create mode 100644 engines/ags/shared/gui/guitextbox.cpp create mode 100644 engines/ags/shared/gui/guitextbox.h create mode 100644 engines/ags/shared/script/cc_error.cpp create mode 100644 engines/ags/shared/script/cc_error.h create mode 100644 engines/ags/shared/script/cc_options.cpp create mode 100644 engines/ags/shared/script/cc_options.h create mode 100644 engines/ags/shared/script/cc_script.cpp create mode 100644 engines/ags/shared/script/cc_script.h create mode 100644 engines/ags/shared/script/script_common.h create mode 100644 engines/ags/shared/util/alignedstream.cpp create mode 100644 engines/ags/shared/util/alignedstream.h create mode 100644 engines/ags/shared/util/bbop.h create mode 100644 engines/ags/shared/util/bufferedstream.cpp create mode 100644 engines/ags/shared/util/bufferedstream.h create mode 100644 engines/ags/shared/util/compress.cpp create mode 100644 engines/ags/shared/util/compress.h create mode 100644 engines/ags/shared/util/datastream.cpp create mode 100644 engines/ags/shared/util/datastream.h create mode 100644 engines/ags/shared/util/directory.cpp create mode 100644 engines/ags/shared/util/directory.h create mode 100644 engines/ags/shared/util/error.h create mode 100644 engines/ags/shared/util/file.cpp create mode 100644 engines/ags/shared/util/file.h create mode 100644 engines/ags/shared/util/filestream.cpp create mode 100644 engines/ags/shared/util/filestream.h create mode 100644 engines/ags/shared/util/geometry.cpp create mode 100644 engines/ags/shared/util/geometry.h create mode 100644 engines/ags/shared/util/ini_util.cpp create mode 100644 engines/ags/shared/util/ini_util.h create mode 100644 engines/ags/shared/util/inifile.cpp create mode 100644 engines/ags/shared/util/inifile.h create mode 100644 engines/ags/shared/util/lzw.cpp create mode 100644 engines/ags/shared/util/lzw.h create mode 100644 engines/ags/shared/util/math.h create mode 100644 engines/ags/shared/util/memory.h create mode 100644 engines/ags/shared/util/misc.cpp create mode 100644 engines/ags/shared/util/misc.h create mode 100644 engines/ags/shared/util/multifilelib.h create mode 100644 engines/ags/shared/util/mutifilelib.cpp create mode 100644 engines/ags/shared/util/path.cpp create mode 100644 engines/ags/shared/util/path.h create mode 100644 engines/ags/shared/util/proxystream.cpp create mode 100644 engines/ags/shared/util/proxystream.h create mode 100644 engines/ags/shared/util/stdio_compat.c create mode 100644 engines/ags/shared/util/stdio_compat.h create mode 100644 engines/ags/shared/util/stream.cpp create mode 100644 engines/ags/shared/util/stream.h create mode 100644 engines/ags/shared/util/string.cpp create mode 100644 engines/ags/shared/util/string.h create mode 100644 engines/ags/shared/util/string_compat.c create mode 100644 engines/ags/shared/util/string_compat.h create mode 100644 engines/ags/shared/util/string_types.h create mode 100644 engines/ags/shared/util/string_utils.cpp create mode 100644 engines/ags/shared/util/string_utils.h create mode 100644 engines/ags/shared/util/textreader.h create mode 100644 engines/ags/shared/util/textstreamreader.cpp create mode 100644 engines/ags/shared/util/textstreamreader.h create mode 100644 engines/ags/shared/util/textstreamwriter.cpp create mode 100644 engines/ags/shared/util/textstreamwriter.h create mode 100644 engines/ags/shared/util/textwriter.h create mode 100644 engines/ags/shared/util/version.cpp create mode 100644 engines/ags/shared/util/version.h create mode 100644 engines/ags/shared/util/wgt2allg.cpp create mode 100644 engines/ags/shared/util/wgt2allg.h diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h new file mode 100644 index 000000000000..9c6c442166cd --- /dev/null +++ b/engines/ags/engine/ac/asset_helper.h @@ -0,0 +1,67 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Functions related to finding and opening game assets. +// +//============================================================================= +#ifndef __AGS_EE_AC__ASSETHELPER_H +#define __AGS_EE_AC__ASSETHELPER_H +#include +#include +#include "util/string.h" + +namespace AGS { namespace Common {class Stream;}} +using AGS::Common::Stream; +using AGS::Common::String; + +// Looks for valid asset library everywhere and returns path, or empty string if failed +String find_assetlib(const String &filename); +// Looks up for known valid asset library and returns path, or empty string if failed +String get_known_assetlib(const String &filename); +// Looks for asset everywhere and returns opened stream, or NULL if failed +Stream *find_open_asset(const String &filename); + +extern "C" { + struct PACKFILE; // Allegro 4's own stream type + struct DUMBFILE; // DUMB stream type +} + +// AssetPath combines asset library and item names +// TODO: implement support for registering multiple libraries at once for +// the AssetManager, then we could remove assetlib parameter. +typedef std::pair AssetPath; + +// Returns the path to the audio asset, considering the given bundling type +AssetPath get_audio_clip_assetpath(int bundling_type, const String &filename); +// Returns the path to the voice-over asset +AssetPath get_voice_over_assetpath(const String &filename); + +// Custom AGS PACKFILE user object +// TODO: it is preferrable to let our Stream define custom readable window instead, +// keeping this as simple as possible for now (we may require a stream classes overhaul). +struct AGS_PACKFILE_OBJ +{ + std::unique_ptr stream; + size_t asset_size = 0u; + size_t remains = 0u; +}; +// Creates PACKFILE stream from AGS asset. +// This function is supposed to be used only when you have to create Allegro +// object, passing PACKFILE stream to constructor. +PACKFILE *PackfileFromAsset(const AssetPath &path, size_t &asset_size); +// Creates DUMBFILE stream from AGS asset. Used for creating DUMB objects +DUMBFILE *DUMBfileFromAsset(const AssetPath &path, size_t &asset_size); +bool DoesAssetExistInLib(const AssetPath &assetname); + +#endif // __AGS_EE_AC__ASSETHELPER_H diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp new file mode 100644 index 000000000000..4ac75c4e7a76 --- /dev/null +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -0,0 +1,353 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/audiochannel.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/dynobj/cc_audioclip.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "script/runtimescriptvalue.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; + +extern GameState play; +extern RoomStruct thisroom; +extern CCAudioClip ccDynamicAudioClip; + +int AudioChannel_GetID(ScriptAudioChannel *channel) +{ + return channel->id; +} + +int AudioChannel_GetIsPlaying(ScriptAudioChannel *channel) +{ + if (play.fast_forward) + { + return 0; + } + + return channel_is_playing(channel->id) ? 1 : 0; +} + +int AudioChannel_GetPanning(ScriptAudioChannel *channel) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + return ch->panningAsPercentage; + } + return 0; +} + +void AudioChannel_SetPanning(ScriptAudioChannel *channel, int newPanning) +{ + if ((newPanning < -100) || (newPanning > 100)) + quitprintf("!AudioChannel.Panning: panning value must be between -100 and 100 (passed=%d)", newPanning); + + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + ch->set_panning(((newPanning + 100) * 255) / 200); + ch->panningAsPercentage = newPanning; + } +} + +ScriptAudioClip* AudioChannel_GetPlayingClip(ScriptAudioChannel *channel) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + return (ScriptAudioClip*)ch->sourceClip; + } + return nullptr; +} + +int AudioChannel_GetPosition(ScriptAudioChannel *channel) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + if (play.fast_forward) + return 999999999; + + return ch->get_pos(); + } + return 0; +} + +int AudioChannel_GetPositionMs(ScriptAudioChannel *channel) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + if (play.fast_forward) + return 999999999; + + return ch->get_pos_ms(); + } + return 0; +} + +int AudioChannel_GetLengthMs(ScriptAudioChannel *channel) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + return ch->get_length_ms(); + } + return 0; +} + +int AudioChannel_GetVolume(ScriptAudioChannel *channel) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + return ch->get_volume(); + } + return 0; +} + +int AudioChannel_SetVolume(ScriptAudioChannel *channel, int newVolume) +{ + if ((newVolume < 0) || (newVolume > 100)) + quitprintf("!AudioChannel.Volume: new value out of range (supplied: %d, range: 0..100)", newVolume); + + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + ch->set_volume_percent(newVolume); + } + return 0; +} + +int AudioChannel_GetSpeed(ScriptAudioChannel *channel) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + return ch->get_speed(); + } + return 0; +} + +void AudioChannel_SetSpeed(ScriptAudioChannel *channel, int new_speed) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + ch->set_speed(new_speed); + } +} + +void AudioChannel_Stop(ScriptAudioChannel *channel) +{ + if (channel->id == SCHAN_SPEECH && play.IsNonBlockingVoiceSpeech()) + stop_voice_nonblocking(); + else + stop_or_fade_out_channel(channel->id, -1, nullptr); +} + +void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition) +{ + if (newPosition < 0) + quitprintf("!AudioChannel.Seek: invalid seek position %d", newPosition); + + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + ch->seek(newPosition); + } +} + +void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos) +{ + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) + { + int maxDist = ((xPos > thisroom.Width / 2) ? xPos : (thisroom.Width - xPos)) - AMBIENCE_FULL_DIST; + ch->xSource = (xPos > 0) ? xPos : -1; + ch->ySource = yPos; + ch->maximumPossibleDistanceAway = maxDist; + if (xPos > 0) + { + update_directional_sound_vol(); + } + else + { + ch->apply_directional_modifier(0); + } + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// int | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetID); +} + +// int | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetIsPlaying(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetIsPlaying); +} + +// int | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetPanning(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPanning); +} + +// void | ScriptAudioChannel *channel, int newPanning +RuntimeScriptValue Sc_AudioChannel_SetPanning(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_SetPanning); +} + +// ScriptAudioClip* | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetPlayingClip(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptAudioChannel, ScriptAudioClip, ccDynamicAudioClip, AudioChannel_GetPlayingClip); +} + +// int | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPosition); +} + +// int | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetPositionMs(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPositionMs); +} + +// int | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetLengthMs(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetLengthMs); +} + +// int | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_GetVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetVolume); +} + +// int | ScriptAudioChannel *channel, int newVolume +RuntimeScriptValue Sc_AudioChannel_SetVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(ScriptAudioChannel, AudioChannel_SetVolume); +} + +// void | ScriptAudioChannel *channel +RuntimeScriptValue Sc_AudioChannel_Stop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptAudioChannel, AudioChannel_Stop); +} + +// void | ScriptAudioChannel *channel, int newPosition +RuntimeScriptValue Sc_AudioChannel_Seek(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_Seek); +} + +// void | ScriptAudioChannel *channel, int xPos, int yPos +RuntimeScriptValue Sc_AudioChannel_SetRoomLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptAudioChannel, AudioChannel_SetRoomLocation); +} + +RuntimeScriptValue Sc_AudioChannel_GetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetSpeed); +} + +RuntimeScriptValue Sc_AudioChannel_SetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_SetSpeed); +} + +void RegisterAudioChannelAPI() +{ + ccAddExternalObjectFunction("AudioChannel::Seek^1", Sc_AudioChannel_Seek); + ccAddExternalObjectFunction("AudioChannel::SetRoomLocation^2", Sc_AudioChannel_SetRoomLocation); + ccAddExternalObjectFunction("AudioChannel::Stop^0", Sc_AudioChannel_Stop); + ccAddExternalObjectFunction("AudioChannel::get_ID", Sc_AudioChannel_GetID); + ccAddExternalObjectFunction("AudioChannel::get_IsPlaying", Sc_AudioChannel_GetIsPlaying); + ccAddExternalObjectFunction("AudioChannel::get_LengthMs", Sc_AudioChannel_GetLengthMs); + ccAddExternalObjectFunction("AudioChannel::get_Panning", Sc_AudioChannel_GetPanning); + ccAddExternalObjectFunction("AudioChannel::set_Panning", Sc_AudioChannel_SetPanning); + ccAddExternalObjectFunction("AudioChannel::get_PlayingClip", Sc_AudioChannel_GetPlayingClip); + ccAddExternalObjectFunction("AudioChannel::get_Position", Sc_AudioChannel_GetPosition); + ccAddExternalObjectFunction("AudioChannel::get_PositionMs", Sc_AudioChannel_GetPositionMs); + ccAddExternalObjectFunction("AudioChannel::get_Volume", Sc_AudioChannel_GetVolume); + ccAddExternalObjectFunction("AudioChannel::set_Volume", Sc_AudioChannel_SetVolume); + ccAddExternalObjectFunction("AudioChannel::get_Speed", Sc_AudioChannel_GetSpeed); + ccAddExternalObjectFunction("AudioChannel::set_Speed", Sc_AudioChannel_SetSpeed); + // For compatibility with Ahmet Kamil's (aka Gord10) custom engine + ccAddExternalObjectFunction("AudioChannel::SetSpeed^1", Sc_AudioChannel_SetSpeed); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("AudioChannel::Seek^1", (void*)AudioChannel_Seek); + ccAddExternalFunctionForPlugin("AudioChannel::SetRoomLocation^2", (void*)AudioChannel_SetRoomLocation); + ccAddExternalFunctionForPlugin("AudioChannel::Stop^0", (void*)AudioChannel_Stop); + ccAddExternalFunctionForPlugin("AudioChannel::get_ID", (void*)AudioChannel_GetID); + ccAddExternalFunctionForPlugin("AudioChannel::get_IsPlaying", (void*)AudioChannel_GetIsPlaying); + ccAddExternalFunctionForPlugin("AudioChannel::get_LengthMs", (void*)AudioChannel_GetLengthMs); + ccAddExternalFunctionForPlugin("AudioChannel::get_Panning", (void*)AudioChannel_GetPanning); + ccAddExternalFunctionForPlugin("AudioChannel::set_Panning", (void*)AudioChannel_SetPanning); + ccAddExternalFunctionForPlugin("AudioChannel::get_PlayingClip", (void*)AudioChannel_GetPlayingClip); + ccAddExternalFunctionForPlugin("AudioChannel::get_Position", (void*)AudioChannel_GetPosition); + ccAddExternalFunctionForPlugin("AudioChannel::get_PositionMs", (void*)AudioChannel_GetPositionMs); + ccAddExternalFunctionForPlugin("AudioChannel::get_Volume", (void*)AudioChannel_GetVolume); + ccAddExternalFunctionForPlugin("AudioChannel::set_Volume", (void*)AudioChannel_SetVolume); +} diff --git a/engines/ags/engine/ac/audiochannel.h b/engines/ags/engine/ac/audiochannel.h new file mode 100644 index 000000000000..de655725ad47 --- /dev/null +++ b/engines/ags/engine/ac/audiochannel.h @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__AUDIOCHANNEL_H +#define __AGS_EE_AC__AUDIOCHANNEL_H + +#include "ac/dynobj/scriptaudioclip.h" +#include "ac/dynobj/scriptaudiochannel.h" + +int AudioChannel_GetID(ScriptAudioChannel *channel); +int AudioChannel_GetIsPlaying(ScriptAudioChannel *channel); +int AudioChannel_GetPanning(ScriptAudioChannel *channel); +void AudioChannel_SetPanning(ScriptAudioChannel *channel, int newPanning); +ScriptAudioClip* AudioChannel_GetPlayingClip(ScriptAudioChannel *channel); +int AudioChannel_GetPosition(ScriptAudioChannel *channel); +int AudioChannel_GetPositionMs(ScriptAudioChannel *channel); +int AudioChannel_GetLengthMs(ScriptAudioChannel *channel); +int AudioChannel_GetVolume(ScriptAudioChannel *channel); +int AudioChannel_SetVolume(ScriptAudioChannel *channel, int newVolume); +void AudioChannel_Stop(ScriptAudioChannel *channel); +void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition); +void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos); + +#endif // __AGS_EE_AC__AUDIOCHANNEL_H diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp new file mode 100644 index 000000000000..5489ee5a3b34 --- /dev/null +++ b/engines/ags/engine/ac/audioclip.cpp @@ -0,0 +1,154 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/asset_helper.h" +#include "ac/audioclip.h" +#include "ac/audiochannel.h" +#include "ac/gamesetupstruct.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_audiochannel.h" +#include "media/audio/audio_system.h" + +extern GameSetupStruct game; +extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; +extern CCAudioChannel ccDynamicAudio; + +int AudioClip_GetID(ScriptAudioClip *clip) +{ + return clip->id; +} + +int AudioClip_GetFileType(ScriptAudioClip *clip) +{ + return clip->fileType; +} + +int AudioClip_GetType(ScriptAudioClip *clip) +{ + return clip->type; +} +int AudioClip_GetIsAvailable(ScriptAudioClip *clip) +{ + return DoesAssetExistInLib(get_audio_clip_assetpath(clip->bundlingType, clip->fileName)) ? 1 : 0; +} + +void AudioClip_Stop(ScriptAudioClip *clip) +{ + AudioChannelsLock lock; + for (int i = 0; i < MAX_SOUND_CHANNELS; i++) + { + auto* ch = lock.GetChannelIfPlaying(i); + if ((ch != nullptr) && (ch->sourceClip == clip)) + { + AudioChannel_Stop(&scrAudioChannel[i]); + } + } +} + +ScriptAudioChannel* AudioClip_Play(ScriptAudioClip *clip, int priority, int repeat) +{ + ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, 0, false); + return sc_ch; +} + +ScriptAudioChannel* AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat) +{ + ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, position, false); + return sc_ch; +} + +ScriptAudioChannel* AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat) +{ + ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, 0, true); + return sc_ch; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +RuntimeScriptValue Sc_AudioClip_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetID); +} + +// int | ScriptAudioClip *clip +RuntimeScriptValue Sc_AudioClip_GetFileType(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetFileType); +} + +// int | ScriptAudioClip *clip +RuntimeScriptValue Sc_AudioClip_GetType(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetType); +} + +// int | ScriptAudioClip *clip +RuntimeScriptValue Sc_AudioClip_GetIsAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetIsAvailable); +} + +// void | ScriptAudioClip *clip +RuntimeScriptValue Sc_AudioClip_Stop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptAudioClip, AudioClip_Stop); +} + +// ScriptAudioChannel* | ScriptAudioClip *clip, int priority, int repeat +RuntimeScriptValue Sc_AudioClip_Play(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_Play); +} + +// ScriptAudioChannel* | ScriptAudioClip *clip, int position, int priority, int repeat +RuntimeScriptValue Sc_AudioClip_PlayFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT3(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayFrom); +} + +// ScriptAudioChannel* | ScriptAudioClip *clip, int priority, int repeat +RuntimeScriptValue Sc_AudioClip_PlayQueued(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayQueued); +} + +void RegisterAudioClipAPI() +{ + ccAddExternalObjectFunction("AudioClip::Play^2", Sc_AudioClip_Play); + ccAddExternalObjectFunction("AudioClip::PlayFrom^3", Sc_AudioClip_PlayFrom); + ccAddExternalObjectFunction("AudioClip::PlayQueued^2", Sc_AudioClip_PlayQueued); + ccAddExternalObjectFunction("AudioClip::Stop^0", Sc_AudioClip_Stop); + ccAddExternalObjectFunction("AudioClip::get_ID", Sc_AudioClip_GetID); + ccAddExternalObjectFunction("AudioClip::get_FileType", Sc_AudioClip_GetFileType); + ccAddExternalObjectFunction("AudioClip::get_IsAvailable", Sc_AudioClip_GetIsAvailable); + ccAddExternalObjectFunction("AudioClip::get_Type", Sc_AudioClip_GetType); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("AudioClip::Play^2", (void*)AudioClip_Play); + ccAddExternalFunctionForPlugin("AudioClip::PlayFrom^3", (void*)AudioClip_PlayFrom); + ccAddExternalFunctionForPlugin("AudioClip::PlayQueued^2", (void*)AudioClip_PlayQueued); + ccAddExternalFunctionForPlugin("AudioClip::Stop^0", (void*)AudioClip_Stop); + ccAddExternalFunctionForPlugin("AudioClip::get_FileType", (void*)AudioClip_GetFileType); + ccAddExternalFunctionForPlugin("AudioClip::get_IsAvailable", (void*)AudioClip_GetIsAvailable); + ccAddExternalFunctionForPlugin("AudioClip::get_Type", (void*)AudioClip_GetType); +} diff --git a/engines/ags/engine/ac/audioclip.h b/engines/ags/engine/ac/audioclip.h new file mode 100644 index 000000000000..ffb4a100b5e9 --- /dev/null +++ b/engines/ags/engine/ac/audioclip.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__AUDIOCLIP_H +#define __AGS_EE_AC__AUDIOCLIP_H + +#include "ac/dynobj/scriptaudioclip.h" +#include "ac/dynobj/scriptaudiochannel.h" + +int AudioClip_GetFileType(ScriptAudioClip *clip); +int AudioClip_GetType(ScriptAudioClip *clip); +int AudioClip_GetIsAvailable(ScriptAudioClip *clip); +void AudioClip_Stop(ScriptAudioClip *clip); +ScriptAudioChannel* AudioClip_Play(ScriptAudioClip *clip, int priority, int repeat); +ScriptAudioChannel* AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat); +ScriptAudioChannel* AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat); + +#endif // __AGS_EE_AC__AUDIOCLIP_H diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp new file mode 100644 index 000000000000..ecbcb1b1bc1f --- /dev/null +++ b/engines/ags/engine/ac/button.cpp @@ -0,0 +1,501 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/button.h" +#include "ac/common.h" +#include "ac/gui.h" +#include "ac/view.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_translation.h" +#include "ac/string.h" +#include "ac/viewframe.h" +#include "debug/debug_log.h" +#include "gui/animatingguibutton.h" +#include "gui/guimain.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern ViewStruct*views; + +// *** BUTTON FUNCTIONS + +AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; +int numAnimButs; + +void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat) { + int guin = butt->ParentId; + int objn = butt->Id; + + if ((view < 1) || (view > game.numviews)) + quit("!AnimateButton: invalid view specified"); + view--; + + if ((loop < 0) || (loop >= views[view].numLoops)) + quit("!AnimateButton: invalid loop specified for view"); + + // if it's already animating, stop it + FindAndRemoveButtonAnimation(guin, objn); + + if (numAnimButs >= MAX_ANIMATING_BUTTONS) + quit("!AnimateButton: too many animating GUI buttons at once"); + + int buttonId = guis[guin].GetControlID(objn); + + guibuts[buttonId].PushedImage = 0; + guibuts[buttonId].MouseOverImage = 0; + + animbuts[numAnimButs].ongui = guin; + animbuts[numAnimButs].onguibut = objn; + animbuts[numAnimButs].buttonid = buttonId; + animbuts[numAnimButs].view = view; + animbuts[numAnimButs].loop = loop; + animbuts[numAnimButs].speed = speed; + animbuts[numAnimButs].repeat = repeat; + animbuts[numAnimButs].frame = -1; + animbuts[numAnimButs].wait = 0; + numAnimButs++; + // launch into the first frame + if (UpdateAnimatingButton(numAnimButs - 1)) + { + debug_script_warn("AnimateButton: no frames to animate"); + StopButtonAnimation(numAnimButs - 1); + } +} + +const char* Button_GetText_New(GUIButton *butt) { + return CreateNewScriptString(butt->GetText()); +} + +void Button_GetText(GUIButton *butt, char *buffer) { + strcpy(buffer, butt->GetText()); +} + +void Button_SetText(GUIButton *butt, const char *newtx) { + newtx = get_translation(newtx); + + if (strcmp(butt->GetText(), newtx)) { + guis_need_update = 1; + butt->SetText(newtx); + } +} + +void Button_SetFont(GUIButton *butt, int newFont) { + if ((newFont < 0) || (newFont >= game.numfonts)) + quit("!Button.Font: invalid font number."); + + if (butt->Font != newFont) { + butt->Font = newFont; + guis_need_update = 1; + } +} + +int Button_GetFont(GUIButton *butt) { + return butt->Font; +} + +int Button_GetClipImage(GUIButton *butt) { + return butt->IsClippingImage() ? 1 : 0; +} + +void Button_SetClipImage(GUIButton *butt, int newval) { + if (butt->IsClippingImage() != (newval != 0)) + { + butt->SetClipImage(newval != 0); + guis_need_update = 1; + } +} + +int Button_GetGraphic(GUIButton *butt) { + // return currently displayed pic + if (butt->CurrentImage < 0) + return butt->Image; + return butt->CurrentImage; +} + +int Button_GetMouseOverGraphic(GUIButton *butt) { + return butt->MouseOverImage; +} + +void Button_SetMouseOverGraphic(GUIButton *guil, int slotn) { + debug_script_log("GUI %d Button %d mouseover set to slot %d", guil->ParentId, guil->Id, slotn); + + if ((guil->IsMouseOver != 0) && (guil->IsPushed == 0)) + guil->CurrentImage = slotn; + guil->MouseOverImage = slotn; + + guis_need_update = 1; + FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); +} + +int Button_GetNormalGraphic(GUIButton *butt) { + return butt->Image; +} + +void Button_SetNormalGraphic(GUIButton *guil, int slotn) { + debug_script_log("GUI %d Button %d normal set to slot %d", guil->ParentId, guil->Id, slotn); + // normal pic - update if mouse is not over, or if there's no MouseOverImage + if (((guil->IsMouseOver == 0) || (guil->MouseOverImage < 1)) && (guil->IsPushed == 0)) + guil->CurrentImage = slotn; + guil->Image = slotn; + // update the clickable area to the same size as the graphic + guil->Width = game.SpriteInfos[slotn].Width; + guil->Height = game.SpriteInfos[slotn].Height; + + guis_need_update = 1; + FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); +} + +int Button_GetPushedGraphic(GUIButton *butt) { + return butt->PushedImage; +} + +void Button_SetPushedGraphic(GUIButton *guil, int slotn) { + debug_script_log("GUI %d Button %d pushed set to slot %d", guil->ParentId, guil->Id, slotn); + + if (guil->IsPushed) + guil->CurrentImage = slotn; + guil->PushedImage = slotn; + + guis_need_update = 1; + FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); +} + +int Button_GetTextColor(GUIButton *butt) { + return butt->TextColor; +} + +void Button_SetTextColor(GUIButton *butt, int newcol) { + if (butt->TextColor != newcol) { + butt->TextColor = newcol; + guis_need_update = 1; + } +} + +extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; +extern int numAnimButs; + +// ** start animating buttons code + +// returns 1 if animation finished +int UpdateAnimatingButton(int bu) { + if (animbuts[bu].wait > 0) { + animbuts[bu].wait--; + return 0; + } + ViewStruct *tview = &views[animbuts[bu].view]; + + animbuts[bu].frame++; + + if (animbuts[bu].frame >= tview->loops[animbuts[bu].loop].numFrames) + { + if (tview->loops[animbuts[bu].loop].RunNextLoop()) { + // go to next loop + animbuts[bu].loop++; + animbuts[bu].frame = 0; + } + else if (animbuts[bu].repeat) { + animbuts[bu].frame = 0; + // multi-loop anim, go back + while ((animbuts[bu].loop > 0) && + (tview->loops[animbuts[bu].loop - 1].RunNextLoop())) + animbuts[bu].loop--; + } + else + return 1; + } + + CheckViewFrame(animbuts[bu].view, animbuts[bu].loop, animbuts[bu].frame); + + // update the button's image + guibuts[animbuts[bu].buttonid].Image = tview->loops[animbuts[bu].loop].frames[animbuts[bu].frame].pic; + guibuts[animbuts[bu].buttonid].CurrentImage = guibuts[animbuts[bu].buttonid].Image; + guibuts[animbuts[bu].buttonid].PushedImage = 0; + guibuts[animbuts[bu].buttonid].MouseOverImage = 0; + guis_need_update = 1; + + animbuts[bu].wait = animbuts[bu].speed + tview->loops[animbuts[bu].loop].frames[animbuts[bu].frame].speed; + return 0; +} + +void StopButtonAnimation(int idxn) { + numAnimButs--; + for (int aa = idxn; aa < numAnimButs; aa++) { + animbuts[aa] = animbuts[aa + 1]; + } +} + +// Returns the index of the AnimatingGUIButton object corresponding to the +// given button ID; returns -1 if no such animation exists +int FindAnimatedButton(int guin, int objn) +{ + for (int i = 0; i < numAnimButs; ++i) + { + if (animbuts[i].ongui == guin && animbuts[i].onguibut == objn) + return i; + } + return -1; +} + +void FindAndRemoveButtonAnimation(int guin, int objn) +{ + int idx = FindAnimatedButton(guin, objn); + if (idx >= 0) + StopButtonAnimation(idx); +} +// ** end animating buttons code + +void Button_Click(GUIButton *butt, int mbut) +{ + process_interface_click(butt->ParentId, butt->Id, mbut); +} + +bool Button_IsAnimating(GUIButton *butt) +{ + return FindAnimatedButton(butt->ParentId, butt->Id) >= 0; +} + +// NOTE: in correspondance to similar functions for Character & Object, +// GetView returns (view index + 1), while GetLoop and GetFrame return +// zero-based index and 0 in case of no animation. +int Button_GetAnimView(GUIButton *butt) +{ + int idx = FindAnimatedButton(butt->ParentId, butt->Id); + return idx >= 0 ? animbuts[idx].view + 1 : 0; +} + +int Button_GetAnimLoop(GUIButton *butt) +{ + int idx = FindAnimatedButton(butt->ParentId, butt->Id); + return idx >= 0 ? animbuts[idx].loop : 0; +} + +int Button_GetAnimFrame(GUIButton *butt) +{ + int idx = FindAnimatedButton(butt->ParentId, butt->Id); + return idx >= 0 ? animbuts[idx].frame : 0; +} + +int Button_GetTextAlignment(GUIButton *butt) +{ + return butt->TextAlignment; +} + +void Button_SetTextAlignment(GUIButton *butt, int align) +{ + if (butt->TextAlignment != align) { + butt->TextAlignment = (FrameAlignment)align; + guis_need_update = 1; + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// void | GUIButton *butt, int view, int loop, int speed, int repeat +RuntimeScriptValue Sc_Button_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(GUIButton, Button_Animate); +} + +// const char* | GUIButton *butt +RuntimeScriptValue Sc_Button_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIButton, const char, myScriptStringImpl, Button_GetText_New); +} + +// void | GUIButton *butt, char *buffer +RuntimeScriptValue Sc_Button_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUIButton, Button_GetText, char); +} + +// void | GUIButton *butt, const char *newtx +RuntimeScriptValue Sc_Button_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUIButton, Button_SetText, const char); +} + +// void | GUIButton *butt, int newFont +RuntimeScriptValue Sc_Button_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_SetFont); +} + +// int | GUIButton *butt +RuntimeScriptValue Sc_Button_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetFont); +} + +// int | GUIButton *butt +RuntimeScriptValue Sc_Button_GetClipImage(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetClipImage); +} + +// void | GUIButton *butt, int newval +RuntimeScriptValue Sc_Button_SetClipImage(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_SetClipImage); +} + +// int | GUIButton *butt +RuntimeScriptValue Sc_Button_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetGraphic); +} + +// int | GUIButton *butt +RuntimeScriptValue Sc_Button_GetMouseOverGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetMouseOverGraphic); +} + +// void | GUIButton *guil, int slotn +RuntimeScriptValue Sc_Button_SetMouseOverGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_SetMouseOverGraphic); +} + +// int | GUIButton *butt +RuntimeScriptValue Sc_Button_GetNormalGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetNormalGraphic); +} + +// void | GUIButton *guil, int slotn +RuntimeScriptValue Sc_Button_SetNormalGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_SetNormalGraphic); +} + +// int | GUIButton *butt +RuntimeScriptValue Sc_Button_GetPushedGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetPushedGraphic); +} + +// void | GUIButton *guil, int slotn +RuntimeScriptValue Sc_Button_SetPushedGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_SetPushedGraphic); +} + +// int | GUIButton *butt +RuntimeScriptValue Sc_Button_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetTextColor); +} + +// void | GUIButton *butt, int newcol +RuntimeScriptValue Sc_Button_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_SetTextColor); +} + +RuntimeScriptValue Sc_Button_Click(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_Click); +} + +RuntimeScriptValue Sc_Button_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(GUIButton, Button_IsAnimating); +} + +RuntimeScriptValue Sc_Button_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetTextAlignment); +} + +RuntimeScriptValue Sc_Button_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIButton, Button_SetTextAlignment); +} + +RuntimeScriptValue Sc_Button_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetAnimFrame); +} + +RuntimeScriptValue Sc_Button_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetAnimLoop); +} + +RuntimeScriptValue Sc_Button_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIButton, Button_GetAnimView); +} + +void RegisterButtonAPI() +{ + ccAddExternalObjectFunction("Button::Animate^4", Sc_Button_Animate); + ccAddExternalObjectFunction("Button::Click^1", Sc_Button_Click); + ccAddExternalObjectFunction("Button::GetText^1", Sc_Button_GetText); + ccAddExternalObjectFunction("Button::SetText^1", Sc_Button_SetText); + ccAddExternalObjectFunction("Button::get_TextAlignment", Sc_Button_GetTextAlignment); + ccAddExternalObjectFunction("Button::set_TextAlignment", Sc_Button_SetTextAlignment); + ccAddExternalObjectFunction("Button::get_Animating", Sc_Button_GetAnimating); + ccAddExternalObjectFunction("Button::get_ClipImage", Sc_Button_GetClipImage); + ccAddExternalObjectFunction("Button::set_ClipImage", Sc_Button_SetClipImage); + ccAddExternalObjectFunction("Button::get_Font", Sc_Button_GetFont); + ccAddExternalObjectFunction("Button::set_Font", Sc_Button_SetFont); + ccAddExternalObjectFunction("Button::get_Frame", Sc_Button_GetFrame); + ccAddExternalObjectFunction("Button::get_Graphic", Sc_Button_GetGraphic); + ccAddExternalObjectFunction("Button::get_Loop", Sc_Button_GetLoop); + ccAddExternalObjectFunction("Button::get_MouseOverGraphic", Sc_Button_GetMouseOverGraphic); + ccAddExternalObjectFunction("Button::set_MouseOverGraphic", Sc_Button_SetMouseOverGraphic); + ccAddExternalObjectFunction("Button::get_NormalGraphic", Sc_Button_GetNormalGraphic); + ccAddExternalObjectFunction("Button::set_NormalGraphic", Sc_Button_SetNormalGraphic); + ccAddExternalObjectFunction("Button::get_PushedGraphic", Sc_Button_GetPushedGraphic); + ccAddExternalObjectFunction("Button::set_PushedGraphic", Sc_Button_SetPushedGraphic); + ccAddExternalObjectFunction("Button::get_Text", Sc_Button_GetText_New); + ccAddExternalObjectFunction("Button::set_Text", Sc_Button_SetText); + ccAddExternalObjectFunction("Button::get_TextColor", Sc_Button_GetTextColor); + ccAddExternalObjectFunction("Button::set_TextColor", Sc_Button_SetTextColor); + ccAddExternalObjectFunction("Button::get_View", Sc_Button_GetView); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Button::Animate^4", (void*)Button_Animate); + ccAddExternalFunctionForPlugin("Button::GetText^1", (void*)Button_GetText); + ccAddExternalFunctionForPlugin("Button::SetText^1", (void*)Button_SetText); + ccAddExternalFunctionForPlugin("Button::get_ClipImage", (void*)Button_GetClipImage); + ccAddExternalFunctionForPlugin("Button::set_ClipImage", (void*)Button_SetClipImage); + ccAddExternalFunctionForPlugin("Button::get_Font", (void*)Button_GetFont); + ccAddExternalFunctionForPlugin("Button::set_Font", (void*)Button_SetFont); + ccAddExternalFunctionForPlugin("Button::get_Graphic", (void*)Button_GetGraphic); + ccAddExternalFunctionForPlugin("Button::get_MouseOverGraphic", (void*)Button_GetMouseOverGraphic); + ccAddExternalFunctionForPlugin("Button::set_MouseOverGraphic", (void*)Button_SetMouseOverGraphic); + ccAddExternalFunctionForPlugin("Button::get_NormalGraphic", (void*)Button_GetNormalGraphic); + ccAddExternalFunctionForPlugin("Button::set_NormalGraphic", (void*)Button_SetNormalGraphic); + ccAddExternalFunctionForPlugin("Button::get_PushedGraphic", (void*)Button_GetPushedGraphic); + ccAddExternalFunctionForPlugin("Button::set_PushedGraphic", (void*)Button_SetPushedGraphic); + ccAddExternalFunctionForPlugin("Button::get_Text", (void*)Button_GetText_New); + ccAddExternalFunctionForPlugin("Button::set_Text", (void*)Button_SetText); + ccAddExternalFunctionForPlugin("Button::get_TextColor", (void*)Button_GetTextColor); + ccAddExternalFunctionForPlugin("Button::set_TextColor", (void*)Button_SetTextColor); +} diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h new file mode 100644 index 000000000000..5f94aaea18d7 --- /dev/null +++ b/engines/ags/engine/ac/button.h @@ -0,0 +1,47 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__BUTTON_H +#define __AGS_EE_AC__BUTTON_H + +#include "gui/guibutton.h" + +using AGS::Common::GUIButton; + +void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat); +const char* Button_GetText_New(GUIButton *butt); +void Button_GetText(GUIButton *butt, char *buffer); +void Button_SetText(GUIButton *butt, const char *newtx); +void Button_SetFont(GUIButton *butt, int newFont); +int Button_GetFont(GUIButton *butt); +int Button_GetClipImage(GUIButton *butt); +void Button_SetClipImage(GUIButton *butt, int newval); +int Button_GetGraphic(GUIButton *butt); +int Button_GetMouseOverGraphic(GUIButton *butt); +void Button_SetMouseOverGraphic(GUIButton *guil, int slotn); +int Button_GetNormalGraphic(GUIButton *butt); +void Button_SetNormalGraphic(GUIButton *guil, int slotn); +int Button_GetPushedGraphic(GUIButton *butt); +void Button_SetPushedGraphic(GUIButton *guil, int slotn); +int Button_GetTextColor(GUIButton *butt); +void Button_SetTextColor(GUIButton *butt, int newcol); + +int UpdateAnimatingButton(int bu); +void StopButtonAnimation(int idxn); +void FindAndRemoveButtonAnimation(int guin, int objn); + +#endif // __AGS_EE_AC__BUTTON_H diff --git a/engines/ags/engine/ac/cdaudio.cpp b/engines/ags/engine/ac/cdaudio.cpp new file mode 100644 index 000000000000..866d797f50cc --- /dev/null +++ b/engines/ags/engine/ac/cdaudio.cpp @@ -0,0 +1,39 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/cdaudio.h" +#include "platform/base/agsplatformdriver.h" + +int use_cdplayer=0; +bool triedToUseCdAudioCommand = false; +int need_to_stop_cd=0; + +int init_cd_player() +{ + use_cdplayer=0; + return platform->InitializeCDPlayer(); +} + +int cd_manager(int cmdd,int datt) +{ + if (!triedToUseCdAudioCommand) + { + triedToUseCdAudioCommand = true; + init_cd_player(); + } + if (cmdd==0) return use_cdplayer; + if (use_cdplayer==0) return 0; // ignore other commands + + return platform->CDPlayerCommand(cmdd, datt); +} diff --git a/engines/ags/engine/ac/cdaudio.h b/engines/ags/engine/ac/cdaudio.h new file mode 100644 index 000000000000..4009b520fbe4 --- /dev/null +++ b/engines/ags/engine/ac/cdaudio.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__CDAUDIO_H +#define __AGS_EE_AC__CDAUDIO_H + +// CD Player functions +// flags returned with cd_getstatus +#define CDS_DRIVEOPEN 0x0001 // tray is open +#define CDS_DRIVELOCKED 0x0002 // tray locked shut by software +#define CDS_AUDIOSUPPORT 0x0010 // supports audio CDs +#define CDS_DRIVEEMPTY 0x0800 // no CD in drive + +int init_cd_player() ; +int cd_manager(int cmdd,int datt) ; + +#endif // __AGS_EE_AC__CDAUDIO_H diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp new file mode 100644 index 000000000000..526c9705acfa --- /dev/null +++ b/engines/ags/engine/ac/character.cpp @@ -0,0 +1,4122 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS Character functions +// +//============================================================================= + +#include "ac/character.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/view.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/game.h" +#include "ac/global_audio.h" +#include "ac/global_character.h" +#include "ac/global_game.h" +#include "ac/global_object.h" +#include "ac/global_region.h" +#include "ac/global_room.h" +#include "ac/global_translation.h" +#include "ac/gui.h" +#include "ac/lipsync.h" +#include "ac/mouse.h" +#include "ac/object.h" +#include "ac/overlay.h" +#include "ac/properties.h" +#include "ac/room.h" +#include "ac/screenoverlay.h" +#include "ac/string.h" +#include "ac/system.h" +#include "ac/viewframe.h" +#include "ac/walkablearea.h" +#include "gui/guimain.h" +#include "ac/route_finder.h" +#include "ac/gamestate.h" +#include "debug/debug_log.h" +#include "main/game_run.h" +#include "main/update.h" +#include "ac/spritecache.h" +#include "util/string_compat.h" +#include +#include "gfx/graphicsdriver.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_character.h" +#include "ac/dynobj/cc_inventory.h" +#include "script/script_runtime.h" +#include "gfx/gfx_def.h" +#include "media/audio/audio_system.h" +#include "ac/movelist.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern int displayed_room,starting_room; +extern RoomStruct thisroom; +extern MoveList *mls; +extern ViewStruct*views; +extern RoomObject*objs; +extern ScriptInvItem scrInv[MAX_INV]; +extern SpriteCache spriteset; +extern Bitmap *walkable_areas_temp; +extern IGraphicsDriver *gfxDriver; +extern Bitmap **actsps; +extern int is_text_overlay; +extern int said_speech_line; +extern int said_text; +extern int our_eip; +extern CCCharacter ccDynamicCharacter; +extern CCInventory ccDynamicInv; + +//-------------------------------- + + +CharacterExtras *charextra; +CharacterInfo*playerchar; +int32_t _sc_PlayerCharPtr = 0; +int char_lowest_yp; + +// Sierra-style speech settings +int face_talking=-1,facetalkview=0,facetalkwait=0,facetalkframe=0; +int facetalkloop=0, facetalkrepeat = 0, facetalkAllowBlink = 1; +int facetalkBlinkLoop = 0; +CharacterInfo *facetalkchar = nullptr; +// Do override default portrait position during QFG4-style speech overlay update +bool facetalk_qfg4_override_placement_x = false; +bool facetalk_qfg4_override_placement_y = false; + +// lip-sync speech settings +int loops_per_character, text_lips_offset, char_speaking = -1; +int char_thinking = -1; +const char *text_lips_text = nullptr; +SpeechLipSyncLine *splipsync = nullptr; +int numLipLines = 0, curLipLine = -1, curLipLinePhoneme = 0; + +// **** CHARACTER: FUNCTIONS **** + +void Character_AddInventory(CharacterInfo *chaa, ScriptInvItem *invi, int addIndex) { + int ee; + + if (invi == nullptr) + quit("!AddInventoryToCharacter: invalid invnetory number"); + + int inum = invi->id; + + if (chaa->inv[inum] >= 32000) + quit("!AddInventory: cannot carry more than 32000 of one inventory item"); + + chaa->inv[inum]++; + + int charid = chaa->index_id; + + if (game.options[OPT_DUPLICATEINV] == 0) { + // Ensure it is only in the list once + for (ee = 0; ee < charextra[charid].invorder_count; ee++) { + if (charextra[charid].invorder[ee] == inum) { + // They already have the item, so don't add it to the list + if (chaa == playerchar) + run_on_event (GE_ADD_INV, RuntimeScriptValue().SetInt32(inum)); + return; + } + } + } + if (charextra[charid].invorder_count >= MAX_INVORDER) + quit("!Too many inventory items added, max 500 display at one time"); + + if ((addIndex == SCR_NO_VALUE) || + (addIndex >= charextra[charid].invorder_count) || + (addIndex < 0)) { + // add new item at end of list + charextra[charid].invorder[charextra[charid].invorder_count] = inum; + } + else { + // insert new item at index + for (ee = charextra[charid].invorder_count - 1; ee >= addIndex; ee--) + charextra[charid].invorder[ee + 1] = charextra[charid].invorder[ee]; + + charextra[charid].invorder[addIndex] = inum; + } + charextra[charid].invorder_count++; + guis_need_update = 1; + if (chaa == playerchar) + run_on_event (GE_ADD_INV, RuntimeScriptValue().SetInt32(inum)); + +} + +void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) { + + if (chaa->room != displayed_room) + quit("!MoveCharacterPath: specified character not in current room"); + + // not already walking, so just do a normal move + if (chaa->walking <= 0) { + Character_Walk(chaa, x, y, IN_BACKGROUND, ANYWHERE); + return; + } + + MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; + if (cmls->numstage >= MAXNEEDSTAGES) + { + debug_script_warn("Character_AddWaypoint: move is too complex, cannot add any further paths"); + return; + } + + cmls->pos[cmls->numstage] = (x << 16) + y; + // They're already walking there anyway + if (cmls->pos[cmls->numstage] == cmls->pos[cmls->numstage - 1]) + return; + + calculate_move_stage (cmls, cmls->numstage-1); + cmls->numstage ++; + +} + +void Character_AnimateFrom(CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction, int sframe) { + + if (direction == FORWARDS) + direction = 0; + else if (direction == BACKWARDS) + direction = 1; + else + quit("!Character.Animate: Invalid DIRECTION parameter"); + + animate_character(chaa, loop, delay, repeat, 0, direction, sframe); + + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilValueIsZero(&chaa->animating); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("!Character.Animate: Invalid BLOCKING parameter"); +} + +void Character_Animate(CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction) { + Character_AnimateFrom(chaa, loop, delay, repeat, blocking, direction, 0); +} + +void Character_ChangeRoomAutoPosition(CharacterInfo *chaa, int room, int newPos) +{ + if (chaa->index_id != game.playercharacter) + { + quit("!Character.ChangeRoomAutoPosition can only be used with the player character."); + } + + new_room_pos = newPos; + + if (new_room_pos == 0) { + // auto place on other side of screen + if (chaa->x <= thisroom.Edges.Left + 10) + new_room_pos = 2000; + else if (chaa->x >= thisroom.Edges.Right - 10) + new_room_pos = 1000; + else if (chaa->y <= thisroom.Edges.Top + 10) + new_room_pos = 3000; + else if (chaa->y >= thisroom.Edges.Bottom - 10) + new_room_pos = 4000; + + if (new_room_pos < 3000) + new_room_pos += chaa->y; + else + new_room_pos += chaa->x; + } + NewRoom(room); +} + +void Character_ChangeRoom(CharacterInfo *chaa, int room, int x, int y) { + Character_ChangeRoomSetLoop(chaa, room, x, y, SCR_NO_VALUE); +} + +void Character_ChangeRoomSetLoop(CharacterInfo *chaa, int room, int x, int y, int direction) { + + if (chaa->index_id != game.playercharacter) { + // NewRoomNPC + if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) { + chaa->x = x; + chaa->y = y; + if (direction != SCR_NO_VALUE && direction>=0) chaa->loop = direction; + } + chaa->prevroom = chaa->room; + chaa->room = room; + + debug_script_log("%s moved to room %d, location %d,%d, loop %d", + chaa->scrname, room, chaa->x, chaa->y, chaa->loop); + + return; + } + + if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) { + new_room_pos = 0; + + if (loaded_game_file_version <= kGameVersion_272) + { + // Set position immediately on 2.x. + chaa->x = x; + chaa->y = y; + } + else + { + // don't check X or Y bounds, so that they can do a + // walk-in animation if they want + new_room_x = x; + new_room_y = y; + if (direction != SCR_NO_VALUE) new_room_loop = direction; + } + } + + NewRoom(room); +} + + +void Character_ChangeView(CharacterInfo *chap, int vii) { + vii--; + + if ((vii < 0) || (vii >= game.numviews)) + quit("!ChangeCharacterView: invalid view number specified"); + + // if animating, but not idle view, give warning message + if ((chap->flags & CHF_FIXVIEW) && (chap->idleleft >= 0)) + debug_script_warn("Warning: ChangeCharacterView was used while the view was fixed - call ReleaseCharView first"); + + // if the idle animation is playing we should release the view + if ( chap->idleleft < 0) { + Character_UnlockView(chap); + chap->idleleft = chap->idletime; + } + + debug_script_log("%s: Change view to %d", chap->scrname, vii+1); + chap->defview = vii; + chap->view = vii; + chap->animating = 0; + chap->frame = 0; + chap->wait = 0; + chap->walkwait = 0; + charextra[chap->index_id].animwait = 0; + FindReasonableLoopForCharacter(chap); +} + +enum DirectionalLoop +{ + kDirLoop_Down = 0, + kDirLoop_Left = 1, + kDirLoop_Right = 2, + kDirLoop_Up = 3, + kDirLoop_DownRight = 4, + kDirLoop_UpRight = 5, + kDirLoop_DownLeft = 6, + kDirLoop_UpLeft = 7, + + kDirLoop_Default = kDirLoop_Down, + kDirLoop_LastOrthogonal = kDirLoop_Up, + kDirLoop_Last = kDirLoop_UpLeft, +}; + +// Internal direction-facing functions + +DirectionalLoop GetDirectionalLoop(CharacterInfo *chinfo, int x_diff, int y_diff) +{ + DirectionalLoop next_loop = kDirLoop_Left; // NOTE: default loop was Left for some reason + + const ViewStruct &chview = views[chinfo->view]; + const bool new_version = loaded_game_file_version > kGameVersion_272; + const bool has_down_loop = ((chview.numLoops > kDirLoop_Down) && (chview.loops[kDirLoop_Down].numFrames > 0)); + const bool has_up_loop = ((chview.numLoops > kDirLoop_Up) && (chview.loops[kDirLoop_Up].numFrames > 0)); + // NOTE: 3.+ games required left & right loops to be present at all times + const bool has_left_loop = new_version || + ((chview.numLoops > kDirLoop_Left) && (chview.loops[kDirLoop_Left].numFrames > 0)); + const bool has_right_loop = new_version || + ((chview.numLoops > kDirLoop_Right) && (chview.loops[kDirLoop_Right].numFrames > 0)); + const bool has_diagonal_loops = useDiagonal(chinfo) == 0; // NOTE: useDiagonal returns 0 for "true" + + const bool want_horizontal = (abs(y_diff) < abs(x_diff)) || + (new_version && (!has_down_loop || !has_up_loop) )|| + // NOTE: <= 2.72 games switch to horizontal loops only if both vertical ones are missing + (!new_version && (!has_down_loop && !has_up_loop)); + if (want_horizontal) + { + const bool want_diagonal = has_diagonal_loops && (abs(y_diff) > abs(x_diff) / 2); + if (!has_left_loop && !has_right_loop) + { + next_loop = kDirLoop_Down; + } + else if (has_right_loop && (x_diff > 0)) + { + next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpRight : kDirLoop_DownRight) : + kDirLoop_Right; + } + else if (has_left_loop && (x_diff <= 0)) + { + next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpLeft : kDirLoop_DownLeft) : + kDirLoop_Left; + } + } + else + { + const bool want_diagonal = has_diagonal_loops && (abs(x_diff) > abs(y_diff) / 2); + if (y_diff > 0 || !has_up_loop) + { + next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_DownLeft : kDirLoop_DownRight) : + kDirLoop_Down; + } + else + { + next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_UpLeft : kDirLoop_UpRight) : + kDirLoop_Up; + } + } + return next_loop; +} + +void FaceDirectionalLoop(CharacterInfo *char1, int direction, int blockingStyle) +{ + // Change facing only if the desired direction is different + if (direction != char1->loop) + { + if ((game.options[OPT_TURNTOFACELOC] != 0) && + (in_enters_screen == 0)) + { + const int no_diagonal = useDiagonal (char1); + const int highestLoopForTurning = no_diagonal != 1 ? kDirLoop_Last : kDirLoop_LastOrthogonal; + if ((char1->loop <= highestLoopForTurning)) + { + // Turn to face new direction + Character_StopMoving(char1); + if (char1->on == 1) + { + // only do the turning if the character is not hidden + // (otherwise GameLoopUntilNotMoving will never return) + start_character_turning (char1, direction, no_diagonal); + + if ((blockingStyle == BLOCKING) || (blockingStyle == 1)) + GameLoopUntilNotMoving(&char1->walking); + } + else + char1->loop = direction; + } + else + char1->loop = direction; + } + else + char1->loop = direction; + } + + char1->frame = 0; +} + +void FaceLocationXY(CharacterInfo *char1, int xx, int yy, int blockingStyle) +{ + debug_script_log("%s: Face location %d,%d", char1->scrname, xx, yy); + + const int diffrx = xx - char1->x; + const int diffry = yy - char1->y; + + if ((diffrx == 0) && (diffry == 0)) { + // FaceLocation called on their current position - do nothing + return; + } + + FaceDirectionalLoop(char1, GetDirectionalLoop(char1, diffrx, diffry), blockingStyle); +} + +// External direction-facing functions with validation + +void Character_FaceDirection(CharacterInfo *char1, int direction, int blockingStyle) +{ + if (char1 == nullptr) + quit("!FaceDirection: invalid character specified"); + + if (direction != SCR_NO_VALUE) + { + if (direction < 0 || direction > kDirLoop_Last) + quit("!FaceDirection: invalid direction specified"); + + FaceDirectionalLoop(char1, direction, blockingStyle); + } +} + +void Character_FaceLocation(CharacterInfo *char1, int xx, int yy, int blockingStyle) +{ + if (char1 == nullptr) + quit("!FaceLocation: invalid character specified"); + + FaceLocationXY(char1, xx, yy, blockingStyle); +} + +void Character_FaceObject(CharacterInfo *char1, ScriptObject *obj, int blockingStyle) { + if (obj == nullptr) + quit("!FaceObject: invalid object specified"); + + FaceLocationXY(char1, objs[obj->id].x, objs[obj->id].y, blockingStyle); +} + +void Character_FaceCharacter(CharacterInfo *char1, CharacterInfo *char2, int blockingStyle) { + if (char2 == nullptr) + quit("!FaceCharacter: invalid character specified"); + + if (char1->room != char2->room) + quit("!FaceCharacter: characters are in different rooms"); + + FaceLocationXY(char1, char2->x, char2->y, blockingStyle); +} + +void Character_FollowCharacter(CharacterInfo *chaa, CharacterInfo *tofollow, int distaway, int eagerness) { + + if ((eagerness < 0) || (eagerness > 250)) + quit("!FollowCharacterEx: invalid eagerness: must be 0-250"); + + if ((chaa->index_id == game.playercharacter) && (tofollow != nullptr) && + (tofollow->room != chaa->room)) + quit("!FollowCharacterEx: you cannot tell the player character to follow a character in another room"); + + if (tofollow != nullptr) { + debug_script_log("%s: Start following %s (dist %d, eager %d)", chaa->scrname, tofollow->scrname, distaway, eagerness); + } + else { + debug_script_log("%s: Stop following other character", chaa->scrname); + } + + if ((chaa->following >= 0) && + (chaa->followinfo == FOLLOW_ALWAYSONTOP)) { + // if this character was following always-on-top, its baseline will + // have been changed, so release it. + chaa->baseline = -1; + } + + if (tofollow == nullptr) + chaa->following = -1; + else + chaa->following = tofollow->index_id; + + chaa->followinfo=(distaway << 8) | eagerness; + + chaa->flags &= ~CHF_BEHINDSHEPHERD; + + // special case for Always On Other Character + if (distaway == FOLLOW_ALWAYSONTOP) { + chaa->followinfo = FOLLOW_ALWAYSONTOP; + if (eagerness == 1) + chaa->flags |= CHF_BEHINDSHEPHERD; + } + + if (chaa->animating & CHANIM_REPEAT) + debug_script_warn("Warning: FollowCharacter called but the sheep is currently animating looped. It may never start to follow."); + +} + +int Character_IsCollidingWithChar(CharacterInfo *char1, CharacterInfo *char2) { + if (char2 == nullptr) + quit("!AreCharactersColliding: invalid char2"); + + if (char1->room != char2->room) return 0; // not colliding + + if ((char1->y > char2->y - 5) && (char1->y < char2->y + 5)) ; + else return 0; + + int w1 = game_to_data_coord(GetCharacterWidth(char1->index_id)); + int w2 = game_to_data_coord(GetCharacterWidth(char2->index_id)); + + int xps1=char1->x - w1/2; + int xps2=char2->x - w2/2; + + if ((xps1 >= xps2 - w1) & (xps1 <= xps2 + w2)) return 1; + return 0; +} + +int Character_IsCollidingWithObject(CharacterInfo *chin, ScriptObject *objid) { + if (objid == nullptr) + quit("!AreCharObjColliding: invalid object number"); + + if (chin->room != displayed_room) + return 0; + if (objs[objid->id].on != 1) + return 0; + + Bitmap *checkblk = GetObjectImage(objid->id, nullptr); + int objWidth = checkblk->GetWidth(); + int objHeight = checkblk->GetHeight(); + int o1x = objs[objid->id].x; + int o1y = objs[objid->id].y - game_to_data_coord(objHeight); + + Bitmap *charpic = GetCharacterImage(chin->index_id, nullptr); + + int charWidth = charpic->GetWidth(); + int charHeight = charpic->GetHeight(); + int o2x = chin->x - game_to_data_coord(charWidth) / 2; + int o2y = chin->get_effective_y() - 5; // only check feet + + if ((o2x >= o1x - game_to_data_coord(charWidth)) && + (o2x <= o1x + game_to_data_coord(objWidth)) && + (o2y >= o1y - 8) && + (o2y <= o1y + game_to_data_coord(objHeight))) { + // the character's feet are on the object + if (game.options[OPT_PIXPERFECT] == 0) + return 1; + // check if they're on a transparent bit of the object + int stxp = data_to_game_coord(o2x - o1x); + int styp = data_to_game_coord(o2y - o1y); + int maskcol = checkblk->GetMaskColor (); + int maskcolc = charpic->GetMaskColor (); + int thispix, thispixc; + // check each pixel of the object along the char's feet + for (int i = 0; i < charWidth; i += get_fixed_pixel_size(1)) { + for (int j = 0; j < get_fixed_pixel_size(6); j += get_fixed_pixel_size(1)) { + thispix = my_getpixel(checkblk, i + stxp, j + styp); + thispixc = my_getpixel(charpic, i, j + (charHeight - get_fixed_pixel_size(5))); + + if ((thispix != -1) && (thispix != maskcol) && + (thispixc != -1) && (thispixc != maskcolc)) + return 1; + } + } + + } + return 0; +} + +bool Character_IsInteractionAvailable(CharacterInfo *cchar, int mood) { + + play.check_interaction_only = 1; + RunCharacterInteraction(cchar->index_id, mood); + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + return (ciwas == 2); +} + +void Character_LockView(CharacterInfo *chap, int vii) { + Character_LockViewEx(chap, vii, STOP_MOVING); +} + +void Character_LockViewEx(CharacterInfo *chap, int vii, int stopMoving) { + + if ((vii < 1) || (vii > game.numviews)) { + quitprintf("!SetCharacterView: invalid view number (You said %d, max is %d)", vii, game.numviews); + } + vii--; + + debug_script_log("%s: View locked to %d", chap->scrname, vii+1); + if (chap->idleleft < 0) { + Character_UnlockView(chap); + chap->idleleft = chap->idletime; + } + if (stopMoving != KEEP_MOVING) + { + Character_StopMoving(chap); + } + chap->view=vii; + chap->animating=0; + FindReasonableLoopForCharacter(chap); + chap->frame=0; + chap->wait=0; + chap->flags|=CHF_FIXVIEW; + chap->pic_xoffs = 0; + chap->pic_yoffs = 0; +} + +void Character_LockViewAligned_Old(CharacterInfo *chap, int vii, int loop, int align) { + Character_LockViewAlignedEx(chap, vii, loop, ConvertLegacyScriptAlignment((LegacyScriptAlignment)align), STOP_MOVING); +} + +void Character_LockViewAlignedEx_Old(CharacterInfo *chap, int vii, int loop, int align, int stopMoving) { + Character_LockViewAlignedEx(chap, vii, loop, ConvertLegacyScriptAlignment((LegacyScriptAlignment)align), stopMoving); +} + +void Character_LockViewAligned(CharacterInfo *chap, int vii, int loop, int align) { + Character_LockViewAlignedEx(chap, vii, loop, align, STOP_MOVING); +} + +void Character_LockViewAlignedEx(CharacterInfo *chap, int vii, int loop, int align, int stopMoving) { + if (chap->view < 0) + quit("!SetCharacterLoop: character has invalid old view number"); + + int sppic = views[chap->view].loops[chap->loop].frames[chap->frame].pic; + int leftSide = data_to_game_coord(chap->x) - game.SpriteInfos[sppic].Width / 2; + + Character_LockViewEx(chap, vii, stopMoving); + + if ((loop < 0) || (loop >= views[chap->view].numLoops)) + quit("!SetCharacterViewEx: invalid loop specified"); + + chap->loop = loop; + chap->frame = 0; + int newpic = views[chap->view].loops[chap->loop].frames[chap->frame].pic; + int newLeft = data_to_game_coord(chap->x) - game.SpriteInfos[newpic].Width / 2; + int xdiff = 0; + + if (align & kMAlignLeft) + xdiff = leftSide - newLeft; + else if (align & kMAlignHCenter) + xdiff = 0; + else if (align & kMAlignRight) + xdiff = (leftSide + game.SpriteInfos[sppic].Width) - (newLeft + game.SpriteInfos[newpic].Width); + else + quit("!SetCharacterViewEx: invalid alignment type specified"); + + chap->pic_xoffs = xdiff; + chap->pic_yoffs = 0; +} + +void Character_LockViewFrame(CharacterInfo *chaa, int view, int loop, int frame) { + Character_LockViewFrameEx(chaa, view, loop, frame, STOP_MOVING); +} + +void Character_LockViewFrameEx(CharacterInfo *chaa, int view, int loop, int frame, int stopMoving) { + + Character_LockViewEx(chaa, view, stopMoving); + + view--; + if ((loop < 0) || (loop >= views[view].numLoops)) + quit("!SetCharacterFrame: invalid loop specified"); + if ((frame < 0) || (frame >= views[view].loops[loop].numFrames)) + quit("!SetCharacterFrame: invalid frame specified"); + + chaa->loop = loop; + chaa->frame = frame; +} + +void Character_LockViewOffset(CharacterInfo *chap, int vii, int xoffs, int yoffs) { + Character_LockViewOffsetEx(chap, vii, xoffs, yoffs, STOP_MOVING); +} + +void Character_LockViewOffsetEx(CharacterInfo *chap, int vii, int xoffs, int yoffs, int stopMoving) { + Character_LockViewEx(chap, vii, stopMoving); + + // This function takes offsets in real game coordinates as opposed to script coordinates + defgame_to_finalgame_coords(xoffs, yoffs); + chap->pic_xoffs = xoffs; + chap->pic_yoffs = yoffs; +} + +void Character_LoseInventory(CharacterInfo *chap, ScriptInvItem *invi) { + + if (invi == nullptr) + quit("!LoseInventoryFromCharacter: invalid invnetory number"); + + int inum = invi->id; + + if (chap->inv[inum] > 0) + chap->inv[inum]--; + + if ((chap->activeinv == inum) & (chap->inv[inum] < 1)) { + chap->activeinv = -1; + if ((chap == playerchar) && (GetCursorMode() == MODE_USE)) + set_cursor_mode(0); + } + + int charid = chap->index_id; + + if ((chap->inv[inum] == 0) || (game.options[OPT_DUPLICATEINV] > 0)) { + int xx,tt; + for (xx = 0; xx < charextra[charid].invorder_count; xx++) { + if (charextra[charid].invorder[xx] == inum) { + charextra[charid].invorder_count--; + for (tt = xx; tt < charextra[charid].invorder_count; tt++) + charextra[charid].invorder[tt] = charextra[charid].invorder[tt+1]; + break; + } + } + } + guis_need_update = 1; + + if (chap == playerchar) + run_on_event (GE_LOSE_INV, RuntimeScriptValue().SetInt32(inum)); +} + +void Character_PlaceOnWalkableArea(CharacterInfo *chap) +{ + if (displayed_room < 0) + quit("!Character.PlaceOnWalkableArea: no room is currently loaded"); + + find_nearest_walkable_area(&chap->x, &chap->y); +} + +void Character_RemoveTint(CharacterInfo *chaa) { + + if (chaa->flags & (CHF_HASTINT | CHF_HASLIGHT)) { + debug_script_log("Un-tint %s", chaa->scrname); + chaa->flags &= ~(CHF_HASTINT | CHF_HASLIGHT); + } + else { + debug_script_warn("Character.RemoveTint called but character was not tinted"); + } +} + +int Character_GetHasExplicitTint_Old(CharacterInfo *ch) +{ + return ch->has_explicit_tint() || ch->has_explicit_light(); +} + +int Character_GetHasExplicitTint(CharacterInfo *ch) +{ + return ch->has_explicit_tint(); +} + +void Character_Say(CharacterInfo *chaa, const char *text) { + _DisplaySpeechCore(chaa->index_id, text); +} + +void Character_SayAt(CharacterInfo *chaa, int x, int y, int width, const char *texx) { + + DisplaySpeechAt(x, y, width, chaa->index_id, (char*)texx); +} + +ScriptOverlay* Character_SayBackground(CharacterInfo *chaa, const char *texx) { + + int ovltype = DisplaySpeechBackground(chaa->index_id, (char*)texx); + int ovri = find_overlay_of_type(ovltype); + if (ovri<0) + quit("!SayBackground internal error: no overlay"); + + // Convert the overlay ID to an Overlay object + ScriptOverlay *scOver = new ScriptOverlay(); + scOver->overlayId = ovltype; + scOver->borderHeight = 0; + scOver->borderWidth = 0; + scOver->isBackgroundSpeech = 1; + int handl = ccRegisterManagedObject(scOver, scOver); + screenover[ovri].associatedOverlayHandle = handl; + + return scOver; +} + +void Character_SetAsPlayer(CharacterInfo *chaa) { + + // Set to same character, so ignore. + // But only on versions > 2.61. The relevant entry in the 2.62 changelog is: + // - Fixed SetPlayerCharacter to do nothing at all if you pass the current + // player character to it (previously it was resetting the inventory layout) + if ((loaded_game_file_version > kGameVersion_261) && (game.playercharacter == chaa->index_id)) + return; + + setup_player_character(chaa->index_id); + + //update_invorder(); + + debug_script_log("%s is new player character", playerchar->scrname); + + // Within game_start, return now + if (displayed_room < 0) + return; + + // Ignore invalid room numbers for the character and just place him in + // the current room for 2.x. Following script calls to NewRoom() will + // make sure this still works as intended. + if ((loaded_game_file_version <= kGameVersion_272) && (playerchar->room < 0)) + playerchar->room = displayed_room; + + if (displayed_room != playerchar->room) + NewRoom(playerchar->room); + else // make sure it doesn't run the region interactions + play.player_on_region = GetRegionIDAtRoom(playerchar->x, playerchar->y); + + if ((playerchar->activeinv >= 0) && (playerchar->inv[playerchar->activeinv] < 1)) + playerchar->activeinv = -1; + + // They had inv selected, so change the cursor + if (cur_mode == MODE_USE) { + if (playerchar->activeinv < 0) + SetNextCursor (); + else + SetActiveInventory (playerchar->activeinv); + } + +} + + +void Character_SetIdleView(CharacterInfo *chaa, int iview, int itime) { + + if (iview == 1) + quit("!SetCharacterIdle: view 1 cannot be used as an idle view, sorry."); + + // if an idle anim is currently playing, release it + if (chaa->idleleft < 0) + Character_UnlockView(chaa); + + chaa->idleview = iview - 1; + // make sure they don't appear idle while idle anim is disabled + if (iview < 1) + itime = 10; + chaa->idletime = itime; + chaa->idleleft = itime; + + // if not currently animating, reset the wait counter + if ((chaa->animating == 0) && (chaa->walking == 0)) + chaa->wait = 0; + + if (iview >= 1) { + debug_script_log("Set %s idle view to %d (time %d)", chaa->scrname, iview, itime); + } + else { + debug_script_log("%s idle view disabled", chaa->scrname); + } + if (chaa->flags & CHF_FIXVIEW) { + debug_script_warn("SetCharacterIdle called while character view locked with SetCharacterView; idle ignored"); + debug_script_log("View locked, idle will not kick in until Released"); + } + // if they switch to a swimming animation, kick it off immediately + if (itime == 0) + charextra[chaa->index_id].process_idle_this_time = 1; + +} + +bool Character_GetHasExplicitLight(CharacterInfo *ch) +{ + return ch->has_explicit_light(); +} + +int Character_GetLightLevel(CharacterInfo *ch) +{ + return ch->has_explicit_light() ? charextra[ch->index_id].tint_light : 0; +} + +void Character_SetLightLevel(CharacterInfo *chaa, int light_level) +{ + light_level = Math::Clamp(light_level, -100, 100); + + charextra[chaa->index_id].tint_light = light_level; + chaa->flags &= ~CHF_HASTINT; + chaa->flags |= CHF_HASLIGHT; +} + +int Character_GetTintRed(CharacterInfo *ch) +{ + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_r : 0; +} + +int Character_GetTintGreen(CharacterInfo *ch) +{ + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_g : 0; +} + +int Character_GetTintBlue(CharacterInfo *ch) +{ + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_b : 0; +} + +int Character_GetTintSaturation(CharacterInfo *ch) +{ + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_level : 0; +} + +int Character_GetTintLuminance(CharacterInfo *ch) +{ + return ch->has_explicit_tint() ? ((charextra[ch->index_id].tint_light * 10) / 25) : 0; +} + +void Character_SetOption(CharacterInfo *chaa, int flag, int yesorno) { + + if ((yesorno < 0) || (yesorno > 1)) + quit("!SetCharacterProperty: last parameter must be 0 or 1"); + + if (flag & CHF_MANUALSCALING) { + // backwards compatibility fix + Character_SetIgnoreScaling(chaa, yesorno); + } + else { + chaa->flags &= ~flag; + if (yesorno) + chaa->flags |= flag; + } + +} + +void Character_SetSpeed(CharacterInfo *chaa, int xspeed, int yspeed) { + + if ((xspeed == 0) || (xspeed > 50) || (yspeed == 0) || (yspeed > 50)) + quit("!SetCharacterSpeedEx: invalid speed value"); + if (chaa->walking) + { + debug_script_warn("Character_SetSpeed: cannot change speed while walking"); + return; + } + + chaa->walkspeed = xspeed; + + if (yspeed == xspeed) + chaa->walkspeed_y = UNIFORM_WALK_SPEED; + else + chaa->walkspeed_y = yspeed; +} + + +void Character_StopMoving(CharacterInfo *charp) { + + int chaa = charp->index_id; + if (chaa == play.skip_until_char_stops) + EndSkippingUntilCharStops(); + + if (charextra[chaa].xwas != INVALID_X) { + charp->x = charextra[chaa].xwas; + charp->y = charextra[chaa].ywas; + charextra[chaa].xwas = INVALID_X; + } + if ((charp->walking > 0) && (charp->walking < TURNING_AROUND)) { + // if it's not a MoveCharDirect, make sure they end up on a walkable area + if ((mls[charp->walking].direct == 0) && (charp->room == displayed_room)) + Character_PlaceOnWalkableArea(charp); + + debug_script_log("%s: stop moving", charp->scrname); + + charp->idleleft = charp->idletime; + // restart the idle animation straight away + charextra[chaa].process_idle_this_time = 1; + } + if (charp->walking) { + // If the character is currently moving, stop them and reset their frame + charp->walking = 0; + if ((charp->flags & CHF_MOVENOTWALK) == 0) + charp->frame = 0; + } +} + +void Character_Tint(CharacterInfo *chaa, int red, int green, int blue, int opacity, int luminance) { + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) + quit("!Character.Tint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); + + debug_script_log("Set %s tint RGB(%d,%d,%d) %d%%", chaa->scrname, red, green, blue, opacity); + + charextra[chaa->index_id].tint_r = red; + charextra[chaa->index_id].tint_g = green; + charextra[chaa->index_id].tint_b = blue; + charextra[chaa->index_id].tint_level = opacity; + charextra[chaa->index_id].tint_light = (luminance * 25) / 10; + chaa->flags &= ~CHF_HASLIGHT; + chaa->flags |= CHF_HASTINT; +} + +void Character_Think(CharacterInfo *chaa, const char *text) { + _DisplayThoughtCore(chaa->index_id, text); +} + +void Character_UnlockView(CharacterInfo *chaa) { + Character_UnlockViewEx(chaa, STOP_MOVING); +} + +void Character_UnlockViewEx(CharacterInfo *chaa, int stopMoving) { + if (chaa->flags & CHF_FIXVIEW) { + debug_script_log("%s: Released view back to default", chaa->scrname); + } + chaa->flags &= ~CHF_FIXVIEW; + chaa->view = chaa->defview; + chaa->frame = 0; + if (stopMoving != KEEP_MOVING) + { + Character_StopMoving(chaa); + } + if (chaa->view >= 0) { + int maxloop = views[chaa->view].numLoops; + if (((chaa->flags & CHF_NODIAGONAL)!=0) && (maxloop > 4)) + maxloop = 4; + FindReasonableLoopForCharacter(chaa); + } + chaa->animating = 0; + chaa->idleleft = chaa->idletime; + chaa->pic_xoffs = 0; + chaa->pic_yoffs = 0; + // restart the idle animation straight away + charextra[chaa->index_id].process_idle_this_time = 1; + +} + + +void Character_Walk(CharacterInfo *chaa, int x, int y, int blocking, int direct) +{ + walk_or_move_character(chaa, x, y, blocking, direct, true); +} + +void Character_Move(CharacterInfo *chaa, int x, int y, int blocking, int direct) +{ + walk_or_move_character(chaa, x, y, blocking, direct, false); +} + +void Character_WalkStraight(CharacterInfo *chaa, int xx, int yy, int blocking) { + + if (chaa->room != displayed_room) + quit("!MoveCharacterStraight: specified character not in current room"); + + Character_StopMoving(chaa); + int movetox = xx, movetoy = yy; + + set_wallscreen(prepare_walkable_areas(chaa->index_id)); + + int fromXLowres = room_to_mask_coord(chaa->x); + int fromYLowres = room_to_mask_coord(chaa->y); + int toXLowres = room_to_mask_coord(xx); + int toYLowres = room_to_mask_coord(yy); + + if (!can_see_from(fromXLowres, fromYLowres, toXLowres, toYLowres)) { + int lastcx, lastcy; + get_lastcpos(lastcx, lastcy); + movetox = mask_to_room_coord(lastcx); + movetoy = mask_to_room_coord(lastcy); + } + + walk_character(chaa->index_id, movetox, movetoy, 1, true); + + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilNotMoving(&chaa->walking); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND"); + +} + +void Character_RunInteraction(CharacterInfo *chaa, int mood) { + + RunCharacterInteraction(chaa->index_id, mood); +} + + + +// **** CHARACTER: PROPERTIES **** + +int Character_GetProperty(CharacterInfo *chaa, const char *property) { + + return get_int_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property); + +} +void Character_GetPropertyText(CharacterInfo *chaa, const char *property, char *bufer) { + get_text_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property, bufer); +} +const char* Character_GetTextProperty(CharacterInfo *chaa, const char *property) { + return get_text_property_dynamic_string(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property); +} + +bool Character_SetProperty(CharacterInfo *chaa, const char *property, int value) +{ + return set_int_property(play.charProps[chaa->index_id], property, value); +} + +bool Character_SetTextProperty(CharacterInfo *chaa, const char *property, const char *value) +{ + return set_text_property(play.charProps[chaa->index_id], property, value); +} + +ScriptInvItem* Character_GetActiveInventory(CharacterInfo *chaa) { + + if (chaa->activeinv <= 0) + return nullptr; + + return &scrInv[chaa->activeinv]; +} + +void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem* iit) { + guis_need_update = 1; + + if (iit == nullptr) { + chaa->activeinv = -1; + + if (chaa->index_id == game.playercharacter) { + + if (GetCursorMode()==MODE_USE) + set_cursor_mode(0); + } + return; + } + + if (chaa->inv[iit->id] < 1) + { + debug_script_warn("SetActiveInventory: character doesn't have any of that inventory"); + return; + } + + chaa->activeinv = iit->id; + + if (chaa->index_id == game.playercharacter) { + // if it's the player character, update mouse cursor + update_inv_cursor(iit->id); + set_cursor_mode(MODE_USE); + } +} + +int Character_GetAnimating(CharacterInfo *chaa) { + if (chaa->animating) + return 1; + return 0; +} + +int Character_GetAnimationSpeed(CharacterInfo *chaa) { + return chaa->animspeed; +} + +void Character_SetAnimationSpeed(CharacterInfo *chaa, int newval) { + + chaa->animspeed = newval; +} + +int Character_GetBaseline(CharacterInfo *chaa) { + + if (chaa->baseline < 1) + return 0; + + return chaa->baseline; +} + +void Character_SetBaseline(CharacterInfo *chaa, int basel) { + + chaa->baseline = basel; +} + +int Character_GetBlinkInterval(CharacterInfo *chaa) { + + return chaa->blinkinterval; +} + +void Character_SetBlinkInterval(CharacterInfo *chaa, int interval) { + + if (interval < 0) + quit("!SetCharacterBlinkView: invalid blink interval"); + + chaa->blinkinterval = interval; + + if (chaa->blinktimer > 0) + chaa->blinktimer = chaa->blinkinterval; +} + +int Character_GetBlinkView(CharacterInfo *chaa) { + + return chaa->blinkview + 1; +} + +void Character_SetBlinkView(CharacterInfo *chaa, int vii) { + + if (((vii < 2) || (vii > game.numviews)) && (vii != -1)) + quit("!SetCharacterBlinkView: invalid view number"); + + chaa->blinkview = vii - 1; +} + +int Character_GetBlinkWhileThinking(CharacterInfo *chaa) { + if (chaa->flags & CHF_NOBLINKANDTHINK) + return 0; + return 1; +} + +void Character_SetBlinkWhileThinking(CharacterInfo *chaa, int yesOrNo) { + chaa->flags &= ~CHF_NOBLINKANDTHINK; + if (yesOrNo == 0) + chaa->flags |= CHF_NOBLINKANDTHINK; +} + +int Character_GetBlockingHeight(CharacterInfo *chaa) { + + return chaa->blocking_height; +} + +void Character_SetBlockingHeight(CharacterInfo *chaa, int hit) { + + chaa->blocking_height = hit; +} + +int Character_GetBlockingWidth(CharacterInfo *chaa) { + + return chaa->blocking_width; +} + +void Character_SetBlockingWidth(CharacterInfo *chaa, int wid) { + + chaa->blocking_width = wid; +} + +int Character_GetDiagonalWalking(CharacterInfo *chaa) { + + if (chaa->flags & CHF_NODIAGONAL) + return 0; + return 1; +} + +void Character_SetDiagonalWalking(CharacterInfo *chaa, int yesorno) { + + chaa->flags &= ~CHF_NODIAGONAL; + if (!yesorno) + chaa->flags |= CHF_NODIAGONAL; +} + +int Character_GetClickable(CharacterInfo *chaa) { + + if (chaa->flags & CHF_NOINTERACT) + return 0; + return 1; +} + +void Character_SetClickable(CharacterInfo *chaa, int clik) { + + chaa->flags &= ~CHF_NOINTERACT; + // if they don't want it clickable, set the relevant bit + if (clik == 0) + chaa->flags |= CHF_NOINTERACT; +} + +int Character_GetID(CharacterInfo *chaa) { + + return chaa->index_id; + +} + +int Character_GetFrame(CharacterInfo *chaa) { + return chaa->frame; +} + +void Character_SetFrame(CharacterInfo *chaa, int newval) { + chaa->frame = newval; +} + +int Character_GetIdleView(CharacterInfo *chaa) { + + if (chaa->idleview < 1) + return -1; + + return chaa->idleview + 1; +} + +int Character_GetIInventoryQuantity(CharacterInfo *chaa, int index) { + if ((index < 1) || (index >= game.numinvitems)) + quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index); + + return chaa->inv[index]; +} + +int Character_HasInventory(CharacterInfo *chaa, ScriptInvItem *invi) +{ + if (invi == nullptr) + quit("!Character.HasInventory: NULL inventory item supplied"); + + return (chaa->inv[invi->id] > 0) ? 1 : 0; +} + +void Character_SetIInventoryQuantity(CharacterInfo *chaa, int index, int quant) { + if ((index < 1) || (index >= game.numinvitems)) + quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index); + + if ((quant < 0) || (quant > 32000)) + quitprintf("!Character.InventoryQuantity: invalid quantity %d", quant); + + chaa->inv[index] = quant; +} + +int Character_GetIgnoreLighting(CharacterInfo *chaa) { + + if (chaa->flags & CHF_NOLIGHTING) + return 1; + return 0; +} + +void Character_SetIgnoreLighting(CharacterInfo *chaa, int yesorno) { + + chaa->flags &= ~CHF_NOLIGHTING; + if (yesorno) + chaa->flags |= CHF_NOLIGHTING; +} + +int Character_GetIgnoreScaling(CharacterInfo *chaa) { + + if (chaa->flags & CHF_MANUALSCALING) + return 1; + return 0; +} + +void Character_SetIgnoreScaling(CharacterInfo *chaa, int yesorno) { + + if (yesorno) { + // when setting IgnoreScaling to 1, should reset zoom level + // like it used to in pre-2.71 + charextra[chaa->index_id].zoom = 100; + } + Character_SetManualScaling(chaa, yesorno); +} + +void Character_SetManualScaling(CharacterInfo *chaa, int yesorno) { + + chaa->flags &= ~CHF_MANUALSCALING; + if (yesorno) + chaa->flags |= CHF_MANUALSCALING; +} + +int Character_GetIgnoreWalkbehinds(CharacterInfo *chaa) { + + if (chaa->flags & CHF_NOWALKBEHINDS) + return 1; + return 0; +} + +void Character_SetIgnoreWalkbehinds(CharacterInfo *chaa, int yesorno) { + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v350) + debug_script_warn("IgnoreWalkbehinds is not recommended for use, consider other solutions"); + chaa->flags &= ~CHF_NOWALKBEHINDS; + if (yesorno) + chaa->flags |= CHF_NOWALKBEHINDS; +} + +int Character_GetMovementLinkedToAnimation(CharacterInfo *chaa) { + + if (chaa->flags & CHF_ANTIGLIDE) + return 1; + return 0; +} + +void Character_SetMovementLinkedToAnimation(CharacterInfo *chaa, int yesorno) { + + chaa->flags &= ~CHF_ANTIGLIDE; + if (yesorno) + chaa->flags |= CHF_ANTIGLIDE; +} + +int Character_GetLoop(CharacterInfo *chaa) { + return chaa->loop; +} + +void Character_SetLoop(CharacterInfo *chaa, int newval) { + if ((newval < 0) || (newval >= views[chaa->view].numLoops)) + quit("!Character.Loop: invalid loop number for this view"); + + chaa->loop = newval; + + if (chaa->frame >= views[chaa->view].loops[chaa->loop].numFrames) + chaa->frame = 0; +} + +int Character_GetMoving(CharacterInfo *chaa) { + if (chaa->walking) + return 1; + return 0; +} + +int Character_GetDestinationX(CharacterInfo *chaa) { + if (chaa->walking) { + MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; + return cmls->pos[cmls->numstage - 1] >> 16; + } + else + return chaa->x; +} + +int Character_GetDestinationY(CharacterInfo *chaa) { + if (chaa->walking) { + MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; + return cmls->pos[cmls->numstage - 1] & 0xFFFF; + } + else + return chaa->y; +} + +const char* Character_GetName(CharacterInfo *chaa) { + return CreateNewScriptString(chaa->name); +} + +void Character_SetName(CharacterInfo *chaa, const char *newName) { + strncpy(chaa->name, newName, 40); + chaa->name[39] = 0; +} + +int Character_GetNormalView(CharacterInfo *chaa) { + return chaa->defview + 1; +} + +int Character_GetPreviousRoom(CharacterInfo *chaa) { + return chaa->prevroom; +} + +int Character_GetRoom(CharacterInfo *chaa) { + return chaa->room; +} + + +int Character_GetScaleMoveSpeed(CharacterInfo *chaa) { + + if (chaa->flags & CHF_SCALEMOVESPEED) + return 1; + return 0; +} + +void Character_SetScaleMoveSpeed(CharacterInfo *chaa, int yesorno) { + + if ((yesorno < 0) || (yesorno > 1)) + quit("Character.ScaleMoveSpeed: value must be true or false (1 or 0)"); + + chaa->flags &= ~CHF_SCALEMOVESPEED; + if (yesorno) + chaa->flags |= CHF_SCALEMOVESPEED; +} + +int Character_GetScaleVolume(CharacterInfo *chaa) { + + if (chaa->flags & CHF_SCALEVOLUME) + return 1; + return 0; +} + +void Character_SetScaleVolume(CharacterInfo *chaa, int yesorno) { + + if ((yesorno < 0) || (yesorno > 1)) + quit("Character.ScaleVolume: value must be true or false (1 or 0)"); + + chaa->flags &= ~CHF_SCALEVOLUME; + if (yesorno) + chaa->flags |= CHF_SCALEVOLUME; +} + +int Character_GetScaling(CharacterInfo *chaa) { + return charextra[chaa->index_id].zoom; +} + +void Character_SetScaling(CharacterInfo *chaa, int zoomlevel) { + + if ((chaa->flags & CHF_MANUALSCALING) == 0) + { + debug_script_warn("Character.Scaling: cannot set property unless ManualScaling is enabled"); + return; + } + if ((zoomlevel < 5) || (zoomlevel > 200)) + quit("!Character.Scaling: scaling level must be between 5 and 200%"); + + charextra[chaa->index_id].zoom = zoomlevel; +} + +int Character_GetSolid(CharacterInfo *chaa) { + + if (chaa->flags & CHF_NOBLOCKING) + return 0; + return 1; +} + +void Character_SetSolid(CharacterInfo *chaa, int yesorno) { + + chaa->flags &= ~CHF_NOBLOCKING; + if (!yesorno) + chaa->flags |= CHF_NOBLOCKING; +} + +int Character_GetSpeaking(CharacterInfo *chaa) { + if (get_character_currently_talking() == chaa->index_id) + return 1; + + return 0; +} + +int Character_GetSpeechColor(CharacterInfo *chaa) { + + return chaa->talkcolor; +} + +void Character_SetSpeechColor(CharacterInfo *chaa, int ncol) { + + chaa->talkcolor = ncol; +} + +void Character_SetSpeechAnimationDelay(CharacterInfo *chaa, int newDelay) +{ + if (game.options[OPT_GLOBALTALKANIMSPD] != 0) + { + debug_script_warn("Character.SpeechAnimationDelay cannot be set when global speech animation speed is enabled"); + return; + } + + chaa->speech_anim_speed = newDelay; +} + +int Character_GetSpeechView(CharacterInfo *chaa) { + + return chaa->talkview + 1; +} + +void Character_SetSpeechView(CharacterInfo *chaa, int vii) { + if (vii == -1) { + chaa->talkview = -1; + return; + } + + if ((vii < 1) || (vii > game.numviews)) + quit("!SetCharacterSpeechView: invalid view number"); + + chaa->talkview = vii - 1; +} + +bool Character_GetThinking(CharacterInfo *chaa) +{ + return char_thinking == chaa->index_id; +} + +int Character_GetThinkingFrame(CharacterInfo *chaa) +{ + if (char_thinking == chaa->index_id) + return chaa->thinkview > 0 ? chaa->frame : -1; + + debug_script_warn("Character.ThinkingFrame: character is not currently thinking"); + return -1; +} + +int Character_GetThinkView(CharacterInfo *chaa) { + + return chaa->thinkview + 1; +} + +void Character_SetThinkView(CharacterInfo *chaa, int vii) { + if (((vii < 2) || (vii > game.numviews)) && (vii != -1)) + quit("!SetCharacterThinkView: invalid view number"); + + chaa->thinkview = vii - 1; +} + +int Character_GetTransparency(CharacterInfo *chaa) { + + return GfxDef::LegacyTrans255ToTrans100(chaa->transparency); +} + +void Character_SetTransparency(CharacterInfo *chaa, int trans) { + + if ((trans < 0) || (trans > 100)) + quit("!SetCharTransparent: transparency value must be between 0 and 100"); + + chaa->transparency = GfxDef::Trans100ToLegacyTrans255(trans); +} + +int Character_GetTurnBeforeWalking(CharacterInfo *chaa) { + + if (chaa->flags & CHF_NOTURNING) + return 0; + return 1; +} + +void Character_SetTurnBeforeWalking(CharacterInfo *chaa, int yesorno) { + + chaa->flags &= ~CHF_NOTURNING; + if (!yesorno) + chaa->flags |= CHF_NOTURNING; +} + +int Character_GetView(CharacterInfo *chaa) { + return chaa->view + 1; +} + +int Character_GetWalkSpeedX(CharacterInfo *chaa) { + return chaa->walkspeed; +} + +int Character_GetWalkSpeedY(CharacterInfo *chaa) { + if (chaa->walkspeed_y != UNIFORM_WALK_SPEED) + return chaa->walkspeed_y; + + return chaa->walkspeed; +} + +int Character_GetX(CharacterInfo *chaa) { + return chaa->x; +} + +void Character_SetX(CharacterInfo *chaa, int newval) { + chaa->x = newval; +} + +int Character_GetY(CharacterInfo *chaa) { + return chaa->y; +} + +void Character_SetY(CharacterInfo *chaa, int newval) { + chaa->y = newval; +} + +int Character_GetZ(CharacterInfo *chaa) { + return chaa->z; +} + +void Character_SetZ(CharacterInfo *chaa, int newval) { + chaa->z = newval; +} + +extern int char_speaking; + +int Character_GetSpeakingFrame(CharacterInfo *chaa) { + + if ((face_talking >= 0) && (facetalkrepeat)) + { + if (facetalkchar->index_id == chaa->index_id) + { + return facetalkframe; + } + } + else if (char_speaking >= 0) + { + if (char_speaking == chaa->index_id) + { + return chaa->frame; + } + } + + debug_script_warn("Character.SpeakingFrame: character is not currently speaking"); + return -1; +} + +//============================================================================= + +// order of loops to turn character in circle from down to down +int turnlooporder[8] = {0, 6, 1, 7, 3, 5, 2, 4}; + +void walk_character(int chac,int tox,int toy,int ignwal, bool autoWalkAnims) { + CharacterInfo*chin=&game.chars[chac]; + if (chin->room!=displayed_room) + quit("!MoveCharacter: character not in current room"); + + chin->flags &= ~CHF_MOVENOTWALK; + + int toxPassedIn = tox, toyPassedIn = toy; + int charX = room_to_mask_coord(chin->x); + int charY = room_to_mask_coord(chin->y); + tox = room_to_mask_coord(tox); + toy = room_to_mask_coord(toy); + + if ((tox == charX) && (toy == charY)) { + StopMoving(chac); + debug_script_log("%s already at destination, not moving", chin->scrname); + return; + } + + if ((chin->animating) && (autoWalkAnims)) + chin->animating = 0; + + if (chin->idleleft < 0) { + ReleaseCharacterView(chac); + chin->idleleft=chin->idletime; + } + // stop them to make sure they're on a walkable area + // but save their frame first so that if they're already + // moving it looks smoother + int oldframe = chin->frame; + int waitWas = 0, animWaitWas = 0; + // if they are currently walking, save the current Wait + if (chin->walking) + { + waitWas = chin->walkwait; + animWaitWas = charextra[chac].animwait; + } + + StopMoving (chac); + chin->frame = oldframe; + // use toxPassedIn cached variable so the hi-res co-ordinates + // are still displayed as such + debug_script_log("%s: Start move to %d,%d", chin->scrname, toxPassedIn, toyPassedIn); + + int move_speed_x = chin->walkspeed; + int move_speed_y = chin->walkspeed; + + if (chin->walkspeed_y != UNIFORM_WALK_SPEED) + move_speed_y = chin->walkspeed_y; + + if ((move_speed_x == 0) && (move_speed_y == 0)) { + debug_script_warn("Warning: MoveCharacter called for '%s' with walk speed 0", chin->name); + } + + set_route_move_speed(move_speed_x, move_speed_y); + set_color_depth(8); + int mslot=find_route(charX, charY, tox, toy, prepare_walkable_areas(chac), chac+CHMLSOFFS, 1, ignwal); + set_color_depth(game.GetColorDepth()); + if (mslot>0) { + chin->walking = mslot; + mls[mslot].direct = ignwal; + convert_move_path_to_room_resolution(&mls[mslot]); + + // cancel any pending waits on current animations + // or if they were already moving, keep the current wait - + // this prevents a glitch if MoveCharacter is called when they + // are already moving + if (autoWalkAnims) + { + chin->walkwait = waitWas; + charextra[chac].animwait = animWaitWas; + + if (mls[mslot].pos[0] != mls[mslot].pos[1]) { + fix_player_sprite(&mls[mslot],chin); + } + } + else + chin->flags |= CHF_MOVENOTWALK; + } + else if (autoWalkAnims) // pathfinder couldn't get a route, stand them still + chin->frame = 0; +} + +int find_looporder_index (int curloop) { + int rr; + for (rr = 0; rr < 8; rr++) { + if (turnlooporder[rr] == curloop) + return rr; + } + return 0; +} + +// returns 0 to use diagonal, 1 to not +int useDiagonal (CharacterInfo *char1) { + if ((views[char1->view].numLoops < 8) || ((char1->flags & CHF_NODIAGONAL)!=0)) + return 1; + // If they have just provided standing frames for loops 4-7, to + // provide smoother turning + if (views[char1->view].loops[4].numFrames < 2) + return 2; + return 0; +} + +// returns 1 normally, or 0 if they only have horizontal animations +int hasUpDownLoops(CharacterInfo *char1) { + // if no loops in the Down animation + // or no loops in the Up animation + if ((views[char1->view].loops[0].numFrames < 1) || + (views[char1->view].numLoops < 4) || + (views[char1->view].loops[3].numFrames < 1)) + { + return 0; + } + + return 1; +} + +void start_character_turning (CharacterInfo *chinf, int useloop, int no_diagonal) { + // work out how far round they have to turn + int fromidx = find_looporder_index (chinf->loop); + int toidx = find_looporder_index (useloop); + //Display("Curloop: %d, needloop: %d",chinf->loop, useloop); + int ii, go_anticlock = 0; + // work out whether anticlockwise is quicker or not + if ((toidx > fromidx) && ((toidx - fromidx) > 4)) + go_anticlock = 1; + if ((toidx < fromidx) && ((fromidx - toidx) < 4)) + go_anticlock = 1; + // strip any current turning_around stages + chinf->walking = chinf->walking % TURNING_AROUND; + if (go_anticlock) + chinf->walking += TURNING_BACKWARDS; + else + go_anticlock = -1; + + // Allow the diagonal frames just for turning + if (no_diagonal == 2) + no_diagonal = 0; + + for (ii = fromidx; ii != toidx; ii -= go_anticlock) { + if (ii < 0) + ii = 7; + if (ii >= 8) + ii = 0; + if (ii == toidx) + break; + if ((turnlooporder[ii] >= 4) && (no_diagonal > 0)) + continue; + if (views[chinf->view].loops[turnlooporder[ii]].numFrames < 1) + continue; + if (turnlooporder[ii] < views[chinf->view].numLoops) + chinf->walking += TURNING_AROUND; + } + +} + +void fix_player_sprite(MoveList*cmls,CharacterInfo*chinf) { + const fixed xpmove = cmls->xpermove[cmls->onstage]; + const fixed ypmove = cmls->ypermove[cmls->onstage]; + + // if not moving, do nothing + if ((xpmove == 0) && (ypmove == 0)) + return; + + const int useloop = GetDirectionalLoop(chinf, xpmove, ypmove); + + if ((game.options[OPT_ROTATECHARS] == 0) || ((chinf->flags & CHF_NOTURNING) != 0)) { + chinf->loop = useloop; + return; + } + if ((chinf->loop > kDirLoop_LastOrthogonal) && ((chinf->flags & CHF_NODIAGONAL)!=0)) { + // They've just been playing an animation with an extended loop number, + // so don't try and rotate using it + chinf->loop = useloop; + return; + } + if ((chinf->loop >= views[chinf->view].numLoops) || + (views[chinf->view].loops[chinf->loop].numFrames < 1) || + (hasUpDownLoops(chinf) == 0)) { + // Character is not currently on a valid loop, so don't try to rotate + // eg. left/right only view, but current loop 0 + chinf->loop = useloop; + return; + } + const int no_diagonal = useDiagonal (chinf); + start_character_turning (chinf, useloop, no_diagonal); +} + +// Check whether two characters have walked into each other +int has_hit_another_character(int sourceChar) { + + // if the character who's moving doesn't Bitmap *, don't bother checking + if (game.chars[sourceChar].flags & CHF_NOBLOCKING) + return -1; + + for (int ww = 0; ww < game.numcharacters; ww++) { + if (game.chars[ww].on != 1) continue; + if (game.chars[ww].room != displayed_room) continue; + if (ww == sourceChar) continue; + if (game.chars[ww].flags & CHF_NOBLOCKING) continue; + + if (is_char_on_another (sourceChar, ww, nullptr, nullptr)) { + // we are now overlapping character 'ww' + if ((game.chars[ww].walking) && + ((game.chars[ww].flags & CHF_AWAITINGMOVE) == 0)) + return ww; + } + + } + return -1; +} + +// Does the next move from the character's movelist. +// Returns 1 if they are now waiting for another char to move, +// otherwise returns 0 +int doNextCharMoveStep (CharacterInfo *chi, int &char_index, CharacterExtras *chex) { + int ntf=0, xwas = chi->x, ywas = chi->y; + + if (do_movelist_move(&chi->walking,&chi->x,&chi->y) == 2) + { + if ((chi->flags & CHF_MOVENOTWALK) == 0) + fix_player_sprite(&mls[chi->walking], chi); + } + + ntf = has_hit_another_character(char_index); + if (ntf >= 0) { + chi->walkwait = 30; + if (game.chars[ntf].walkspeed < 5) + chi->walkwait += (5 - game.chars[ntf].walkspeed) * 5; + // we are now waiting for the other char to move, so + // make sure he doesn't stop for us too + + chi->flags |= CHF_AWAITINGMOVE; + + if ((chi->flags & CHF_MOVENOTWALK) == 0) + { + chi->frame = 0; + chex->animwait = chi->walkwait; + } + + if ((chi->walking < 1) || (chi->walking >= TURNING_AROUND)) ; + else if (mls[chi->walking].onpart > 0) { + mls[chi->walking].onpart --; + chi->x = xwas; + chi->y = ywas; + } + debug_script_log("%s: Bumped into %s, waiting for them to move", chi->scrname, game.chars[ntf].scrname); + return 1; + } + return 0; +} + +int find_nearest_walkable_area_within(int *xx, int *yy, int range, int step) +{ + int ex, ey, nearest = 99999, thisis, nearx = 0, neary = 0; + int startx = 0, starty = 14; + int roomWidthLowRes = room_to_mask_coord(thisroom.Width); + int roomHeightLowRes = room_to_mask_coord(thisroom.Height); + int xwidth = roomWidthLowRes, yheight = roomHeightLowRes; + + int xLowRes = room_to_mask_coord(xx[0]); + int yLowRes = room_to_mask_coord(yy[0]); + int rightEdge = room_to_mask_coord(thisroom.Edges.Right); + int leftEdge = room_to_mask_coord(thisroom.Edges.Left); + int topEdge = room_to_mask_coord(thisroom.Edges.Top); + int bottomEdge = room_to_mask_coord(thisroom.Edges.Bottom); + + // tweak because people forget to move the edges sometimes + // if the player is already over the edge, ignore it + if (xLowRes >= rightEdge) rightEdge = roomWidthLowRes; + if (xLowRes <= leftEdge) leftEdge = 0; + if (yLowRes >= bottomEdge) bottomEdge = roomHeightLowRes; + if (yLowRes <= topEdge) topEdge = 0; + + if (range > 0) + { + startx = xLowRes - range; + starty = yLowRes - range; + xwidth = startx + range * 2; + yheight = starty + range * 2; + if (startx < 0) startx = 0; + if (starty < 10) starty = 10; + if (xwidth > roomWidthLowRes) xwidth = roomWidthLowRes; + if (yheight > roomHeightLowRes) yheight = roomHeightLowRes; + } + + for (ex = startx; ex < xwidth; ex += step) { + for (ey = starty; ey < yheight; ey += step) { + // non-walkalbe, so don't go here + if (thisroom.WalkAreaMask->GetPixel(ex,ey) == 0) continue; + // off a screen edge, don't move them there + if ((ex <= leftEdge) || (ex >= rightEdge) || + (ey <= topEdge) || (ey >= bottomEdge)) + continue; + // otherwise, calculate distance from target + thisis=(int) ::sqrt((double)((ex - xLowRes) * (ex - xLowRes) + (ey - yLowRes) * (ey - yLowRes))); + if (thisisGetPixel(room_to_mask_coord(xx[0]), room_to_mask_coord(yy[0])); + // only fix this code if the game was built with 2.61 or above + if (pixValue == 0 || (loaded_game_file_version >= kGameVersion_261 && pixValue < 1)) + { + // First, check every 2 pixels within immediate area + if (!find_nearest_walkable_area_within(xx, yy, 20, 2)) + { + // If not, check whole screen at 5 pixel intervals + find_nearest_walkable_area_within(xx, yy, -1, 5); + } + } + +} + +void FindReasonableLoopForCharacter(CharacterInfo *chap) { + + if (chap->loop >= views[chap->view].numLoops) + chap->loop=kDirLoop_Default; + if (views[chap->view].numLoops < 1) + quitprintf("!View %d does not have any loops", chap->view + 1); + + // if the current loop has no frames, find one that does + if (views[chap->view].loops[chap->loop].numFrames < 1) + { + for (int i = 0; i < views[chap->view].numLoops; i++) + { + if (views[chap->view].loops[i].numFrames > 0) { + chap->loop = i; + break; + } + } + } + +} + +void walk_or_move_character(CharacterInfo *chaa, int x, int y, int blocking, int direct, bool isWalk) +{ + if (chaa->on != 1) + { + debug_script_warn("MoveCharacterBlocking: character is turned off and cannot be moved"); + return; + } + + if ((direct == ANYWHERE) || (direct == 1)) + walk_character(chaa->index_id, x, y, 1, isWalk); + else if ((direct == WALKABLE_AREAS) || (direct == 0)) + walk_character(chaa->index_id, x, y, 0, isWalk); + else + quit("!Character.Walk: Direct must be ANYWHERE or WALKABLE_AREAS"); + + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilNotMoving(&chaa->walking); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND"); + +} + +int is_valid_character(int newchar) { + if ((newchar < 0) || (newchar >= game.numcharacters)) return 0; + return 1; +} + +int wantMoveNow (CharacterInfo *chi, CharacterExtras *chex) { + // check most likely case first + if ((chex->zoom == 100) || ((chi->flags & CHF_SCALEMOVESPEED) == 0)) + return 1; + + // the % checks don't work when the counter is negative, so once + // it wraps round, correct it + while (chi->walkwaitcounter < 0) { + chi->walkwaitcounter += 12000; + } + + // scaling 170-200%, move 175% speed + if (chex->zoom >= 170) { + if ((chi->walkwaitcounter % 4) >= 1) + return 2; + else + return 1; + } + // scaling 140-170%, move 150% speed + else if (chex->zoom >= 140) { + if ((chi->walkwaitcounter % 2) == 1) + return 2; + else + return 1; + } + // scaling 115-140%, move 125% speed + else if (chex->zoom >= 115) { + if ((chi->walkwaitcounter % 4) >= 3) + return 2; + else + return 1; + } + // scaling 80-120%, normal speed + else if (chex->zoom >= 80) + return 1; + // scaling 60-80%, move 75% speed + if (chex->zoom >= 60) { + if ((chi->walkwaitcounter % 4) >= 1) + return -1; + else if (chex->xwas != INVALID_X) { + // move the second half of the movement to make it smoother + chi->x = chex->xwas; + chi->y = chex->ywas; + chex->xwas = INVALID_X; + } + } + // scaling 30-60%, move 50% speed + else if (chex->zoom >= 30) { + if ((chi->walkwaitcounter % 2) == 1) + return -1; + else if (chex->xwas != INVALID_X) { + // move the second half of the movement to make it smoother + chi->x = chex->xwas; + chi->y = chex->ywas; + chex->xwas = INVALID_X; + } + } + // scaling 0-30%, move 25% speed + else { + if ((chi->walkwaitcounter % 4) >= 3) + return -1; + if (((chi->walkwaitcounter % 4) == 1) && (chex->xwas != INVALID_X)) { + // move the second half of the movement to make it smoother + chi->x = chex->xwas; + chi->y = chex->ywas; + chex->xwas = INVALID_X; + } + + } + + return 0; +} + +void setup_player_character(int charid) { + game.playercharacter = charid; + playerchar = &game.chars[charid]; + _sc_PlayerCharPtr = ccGetObjectHandleFromAddress((char*)playerchar); + if (loaded_game_file_version < kGameVersion_270) { + ccAddExternalDynamicObject("player", playerchar, &ccDynamicCharacter); + } +} + +void animate_character(CharacterInfo *chap, int loopn,int sppd,int rept, int noidleoverride, int direction, int sframe) { + + if ((chap->view < 0) || (chap->view > game.numviews)) { + quitprintf("!AnimateCharacter: you need to set the view number first\n" + "(trying to animate '%s' using loop %d. View is currently %d).",chap->name,loopn,chap->view+1); + } + debug_script_log("%s: Start anim view %d loop %d, spd %d, repeat %d, frame: %d", chap->scrname, chap->view+1, loopn, sppd, rept, sframe); + if ((chap->idleleft < 0) && (noidleoverride == 0)) { + // if idle view in progress for the character (and this is not the + // "start idle animation" animate_character call), stop the idle anim + Character_UnlockView(chap); + chap->idleleft=chap->idletime; + } + if ((loopn < 0) || (loopn >= views[chap->view].numLoops)) + quit("!AnimateCharacter: invalid loop number specified"); + if ((sframe < 0) || (sframe >= views[chap->view].loops[loopn].numFrames)) + quit("!AnimateCharacter: invalid starting frame number specified"); + Character_StopMoving(chap); + chap->animating=1; + if (rept) chap->animating |= CHANIM_REPEAT; + if (direction) chap->animating |= CHANIM_BACKWARDS; + + chap->animating|=((sppd << 8) & 0xff00); + chap->loop=loopn; + // reverse animation starts at the *previous frame* + if (direction) { + sframe--; + if (sframe < 0) + sframe = views[chap->view].loops[loopn].numFrames - (-sframe); + } + chap->frame = sframe; + + chap->wait = sppd + views[chap->view].loops[loopn].frames[chap->frame].speed; + CheckViewFrameForCharacter(chap); +} + +void CheckViewFrameForCharacter(CharacterInfo *chi) { + + int soundVolume = SCR_NO_VALUE; + + if (chi->flags & CHF_SCALEVOLUME) { + // adjust the sound volume using the character's zoom level + int zoom_level = charextra[chi->index_id].zoom; + if (zoom_level == 0) + zoom_level = 100; + + soundVolume = zoom_level; + + if (soundVolume < 0) + soundVolume = 0; + if (soundVolume > 100) + soundVolume = 100; + } + + CheckViewFrame(chi->view, chi->loop, chi->frame, soundVolume); +} + +Bitmap *GetCharacterImage(int charid, int *isFlipped) +{ + if (!gfxDriver->HasAcceleratedTransform()) + { + if (actsps[charid + MAX_ROOM_OBJECTS] != nullptr) + { + // the actsps image is pre-flipped, so no longer register the image as such + if (isFlipped) + *isFlipped = 0; + return actsps[charid + MAX_ROOM_OBJECTS]; + } + } + CharacterInfo*chin=&game.chars[charid]; + int sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic; + return spriteset[sppic]; +} + +CharacterInfo *GetCharacterAtScreen(int xx, int yy) { + int hsnum = GetCharIDAtScreen(xx, yy); + if (hsnum < 0) + return nullptr; + return &game.chars[hsnum]; +} + +CharacterInfo *GetCharacterAtRoom(int x, int y) +{ + int hsnum = is_pos_on_character(x, y); + if (hsnum < 0) + return nullptr; + return &game.chars[hsnum]; +} + +extern int char_lowest_yp, obj_lowest_yp; + +int is_pos_on_character(int xx,int yy) { + int cc,sppic,lowestyp=0,lowestwas=-1; + for (cc=0;ccview < 0) || + (chin->loop >= views[chin->view].numLoops) || + (chin->frame >= views[chin->view].loops[chin->loop].numFrames)) + { + continue; + } + + sppic=views[chin->view].loops[chin->loop].frames[chin->frame].pic; + int usewid = charextra[cc].width; + int usehit = charextra[cc].height; + if (usewid==0) usewid=game.SpriteInfos[sppic].Width; + if (usehit==0) usehit= game.SpriteInfos[sppic].Height; + int xxx = chin->x - game_to_data_coord(usewid) / 2; + int yyy = chin->get_effective_y() - game_to_data_coord(usehit); + + int mirrored = views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE; + Bitmap *theImage = GetCharacterImage(cc, &mirrored); + + if (is_pos_in_sprite(xx,yy,xxx,yyy, theImage, + game_to_data_coord(usewid), + game_to_data_coord(usehit), mirrored) == FALSE) + continue; + + int use_base = chin->get_baseline(); + if (use_base < lowestyp) continue; + lowestyp=use_base; + lowestwas=cc; + } + char_lowest_yp = lowestyp; + return lowestwas; +} + +void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2) { + CharacterInfo *char1 = &game.chars[charid]; + int cwidth, fromx; + + if (char1->blocking_width < 1) + cwidth = game_to_data_coord(GetCharacterWidth(charid)) - 4; + else + cwidth = char1->blocking_width; + + fromx = char1->x - cwidth/2; + if (fromx < 0) { + cwidth += fromx; + fromx = 0; + } + if (fromx + cwidth >= mask_to_room_coord(walkable_areas_temp->GetWidth())) + cwidth = mask_to_room_coord(walkable_areas_temp->GetWidth()) - fromx; + + if (x1) + *x1 = fromx; + if (width) + *width = cwidth; + if (y1) + *y1 = char1->get_blocking_top(); + if (y2) + *y2 = char1->get_blocking_bottom(); +} + +// Check whether the source char has walked onto character ww +int is_char_on_another (int sourceChar, int ww, int*fromxptr, int*cwidptr) { + + int fromx, cwidth; + int y1, y2; + get_char_blocking_rect(ww, &fromx, &y1, &cwidth, &y2); + + if (fromxptr) + fromxptr[0] = fromx; + if (cwidptr) + cwidptr[0] = cwidth; + + // if the character trying to move is already on top of + // this char somehow, allow them through + if ((sourceChar >= 0) && + // x/width are left and width co-ords, so they need >= and < + (game.chars[sourceChar].x >= fromx) && + (game.chars[sourceChar].x < fromx + cwidth) && + // y1/y2 are the top/bottom co-ords, so they need >= / <= + (game.chars[sourceChar].y >= y1 ) && + (game.chars[sourceChar].y <= y2 )) + return 1; + + return 0; +} + +int my_getpixel(Bitmap *blk, int x, int y) { + if ((x < 0) || (y < 0) || (x >= blk->GetWidth()) || (y >= blk->GetHeight())) + return -1; + + // strip the alpha channel + // TODO: is there a way to do this vtable thing with Bitmap? + BITMAP *al_bmp = (BITMAP*)blk->GetAllegroBitmap(); + return al_bmp->vtable->getpixel(al_bmp, x, y) & 0x00ffffff; +} + +int check_click_on_character(int xx,int yy,int mood) { + int lowestwas=is_pos_on_character(xx,yy); + if (lowestwas>=0) { + RunCharacterInteraction (lowestwas, mood); + return 1; + } + return 0; +} + +void _DisplaySpeechCore(int chid, const char *displbuf) { + if (displbuf[0] == 0) { + // no text, just update the current character who's speaking + // this allows the portrait side to be switched with an empty + // speech line + play.swap_portrait_lastchar = chid; + return; + } + + // adjust timing of text (so that DisplaySpeech("%s", str) pauses + // for the length of the string not 2 frames) + int len = (int)strlen(displbuf); + if (len > source_text_length + 3) + source_text_length = len; + + DisplaySpeech(displbuf, chid); +} + +void _DisplayThoughtCore(int chid, const char *displbuf) { + // adjust timing of text (so that DisplayThought("%s", str) pauses + // for the length of the string not 2 frames) + int len = (int)strlen(displbuf); + if (len > source_text_length + 3) + source_text_length = len; + + int xpp = -1, ypp = -1, width = -1; + + if ((game.options[OPT_SPEECHTYPE] == 0) || (game.chars[chid].thinkview <= 0)) { + // lucasarts-style, so we want a speech bubble actually above + // their head (or if they have no think anim in Sierra-style) + width = data_to_game_coord(play.speech_bubble_width); + xpp = play.RoomToScreenX(data_to_game_coord(game.chars[chid].x)) - width / 2; + if (xpp < 0) + xpp = 0; + // -1 will automatically put it above the char's head + ypp = -1; + } + + _displayspeech ((char*)displbuf, chid, xpp, ypp, width, 1); +} + +void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int isThought) { + if (!is_valid_character(aschar)) + quit("!DisplaySpeech: invalid character"); + + CharacterInfo *speakingChar = &game.chars[aschar]; + if ((speakingChar->view < 0) || (speakingChar->view >= game.numviews)) + quit("!DisplaySpeech: character has invalid view"); + + if (is_text_overlay > 0) + { + debug_script_warn("DisplaySpeech: speech was already displayed (nested DisplaySpeech, perhaps room script and global script conflict?)"); + return; + } + + EndSkippingUntilCharStops(); + + said_speech_line = 1; + + if (play.bgspeech_stay_on_display == 0) { + // remove any background speech + for (size_t i = 0; i < screenover.size();) { + if (screenover[i].timeout > 0) + remove_screen_overlay(screenover[i].type); + else + i++; + } + } + said_text = 1; + + // the strings are pre-translated + //texx = get_translation(texx); + our_eip=150; + + int isPause = 1; + // if the message is all .'s, don't display anything + for (int aa = 0; texx[aa] != 0; aa++) { + if (texx[aa] != '.') { + isPause = 0; + break; + } + } + + play.messagetime = GetTextDisplayTime(texx); + play.speech_in_post_state = false; + + if (isPause) { + postpone_scheduled_music_update_by(std::chrono::milliseconds(play.messagetime * 1000 / frames_per_second)); + GameLoopUntilValueIsNegative(&play.messagetime); + return; + } + + int textcol = speakingChar->talkcolor; + + // if it's 0, it won't be recognised as speech + if (textcol == 0) + textcol = 16; + + Rect ui_view = play.GetUIViewport(); + int allowShrink = 0; + int bwidth = widd; + if (bwidth < 0) + bwidth = ui_view.GetWidth()/2 + ui_view.GetWidth()/4; + + our_eip=151; + + int useview = speakingChar->talkview; + if (isThought) { + useview = speakingChar->thinkview; + // view 0 is not valid for think views + if (useview == 0) + useview = -1; + // speech bubble can shrink to fit + allowShrink = 1; + if (speakingChar->room != displayed_room) { + // not in room, centre it + xx = -1; + yy = -1; + } + } + + if (useview >= game.numviews) + quitprintf("!Character.Say: attempted to use view %d for animation, but it does not exist", useview + 1); + + int tdxp = xx,tdyp = yy; + int oldview=-1, oldloop = -1; + int ovr_type = 0; + + text_lips_offset = 0; + text_lips_text = texx; + + Bitmap *closeupface=nullptr; + // TODO: we always call _display_at later which may also start voice-over; + // find out if this may be refactored and voice started only in one place. + try_auto_play_speech(texx, texx, aschar, true); + + if (game.options[OPT_SPEECHTYPE] == 3) + remove_screen_overlay(OVER_COMPLETE); + our_eip=1500; + + if (game.options[OPT_SPEECHTYPE] == 0) + allowShrink = 1; + + if (speakingChar->idleleft < 0) { + // if idle anim in progress for the character, stop it + ReleaseCharacterView(aschar); + // speakingChar->idleleft = speakingChar->idletime; + } + + bool overlayPositionFixed = false; + int charFrameWas = 0; + int viewWasLocked = 0; + if (speakingChar->flags & CHF_FIXVIEW) + viewWasLocked = 1; + + /*if ((speakingChar->room == displayed_room) || + ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) ) {*/ + + if (speakingChar->room == displayed_room) { + // If the character is in this room, go for it - otherwise + // run the "else" clause which does text in the middle of + // the screen. + our_eip=1501; + + if (speakingChar->walking) + StopMoving(aschar); + + // save the frame we need to go back to + // if they were moving, this will be 0 (because we just called + // StopMoving); otherwise, it might be a specific animation + // frame which we should return to + if (viewWasLocked) + charFrameWas = speakingChar->frame; + + // if the current loop doesn't exist in talking view, use loop 0 + if (speakingChar->loop >= views[speakingChar->view].numLoops) + speakingChar->loop = 0; + + if ((speakingChar->view < 0) || + (speakingChar->loop >= views[speakingChar->view].numLoops) || + (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1)) + { + quitprintf("Unable to display speech because the character %s has an invalid view frame (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame); + } + + our_eip=1504; + + // Calculate speech position based on character's position on screen + auto view = FindNearestViewport(aschar); + if (tdxp < 0) + tdxp = view->RoomToScreen(data_to_game_coord(speakingChar->x), 0).first.X; + if (tdxp < 2) + tdxp = 2; + tdxp = -tdxp; // tell it to centre it ([ikm] not sure what's going on here... wrong comment?) + + if (tdyp < 0) + { + int sppic = views[speakingChar->view].loops[speakingChar->loop].frames[0].pic; + int height = (charextra[aschar].height < 1) ? game.SpriteInfos[sppic].Height : height = charextra[aschar].height; + tdyp = view->RoomToScreen(0, data_to_game_coord(game.chars[aschar].get_effective_y()) - height).first.Y + - get_fixed_pixel_size(5); + if (isThought) // if it's a thought, lift it a bit further up + tdyp -= get_fixed_pixel_size(10); + } + if (tdyp < 5) + tdyp = 5; + + our_eip=152; + + if ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) { + // Sierra-style close-up portrait + + if (play.swap_portrait_lastchar != aschar) { + // if the portraits are set to Alternate, OR they are + // set to Left but swap_portrait has been set to 1 (the old + // method for enabling it), then swap them round + if ((game.options[OPT_PORTRAITSIDE] == PORTRAIT_ALTERNATE) || + ((game.options[OPT_PORTRAITSIDE] == 0) && + (play.swap_portrait_side > 0))) { + + if (play.swap_portrait_side == 2) + play.swap_portrait_side = 1; + else + play.swap_portrait_side = 2; + } + + if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION) { + // Portrait side based on character X-positions + if (play.swap_portrait_lastchar < 0) { + // No previous character been spoken to + // therefore, assume it's the player + if(game.playercharacter != aschar && game.chars[game.playercharacter].room == speakingChar->room && game.chars[game.playercharacter].on == 1) + play.swap_portrait_lastchar = game.playercharacter; + else + // The player's not here. Find another character in this room + // that it could be + for (int ce = 0; ce < game.numcharacters; ce++) { + if ((game.chars[ce].room == speakingChar->room) && + (game.chars[ce].on == 1) && + (ce != aschar)) { + play.swap_portrait_lastchar = ce; + break; + } + } + } + + if (play.swap_portrait_lastchar >= 0) { + // if this character is right of the one before, put the + // portrait on the right + if (speakingChar->x > game.chars[play.swap_portrait_lastchar].x) + play.swap_portrait_side = -1; + else + play.swap_portrait_side = 0; + } + } + play.swap_portrait_lastlastchar = play.swap_portrait_lastchar; + play.swap_portrait_lastchar = aschar; + } + else + // If the portrait side is based on the character's X position and the same character is + // speaking, compare against the previous *previous* character to see where the speech should be + if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION && play.swap_portrait_lastlastchar >= 0) { + if (speakingChar->x > game.chars[play.swap_portrait_lastlastchar].x) + play.swap_portrait_side = -1; + else + play.swap_portrait_side = 0; + } + + // Determine whether to display the portrait on the left or right + int portrait_on_right = 0; + + if (game.options[OPT_SPEECHTYPE] == 3) + { } // always on left with QFG-style speech + else if ((play.swap_portrait_side == 1) || + (play.swap_portrait_side == -1) || + (game.options[OPT_PORTRAITSIDE] == PORTRAIT_RIGHT)) + portrait_on_right = 1; + + + int bigx=0,bigy=0,kk; + ViewStruct*viptr=&views[useview]; + for (kk = 0; kk < viptr->loops[0].numFrames; kk++) + { + int tw = game.SpriteInfos[viptr->loops[0].frames[kk].pic].Width; + if (tw > bigx) bigx=tw; + tw = game.SpriteInfos[viptr->loops[0].frames[kk].pic].Height; + if (tw > bigy) bigy=tw; + } + + // if they accidentally used a large full-screen image as the sierra-style + // talk view, correct it + if ((game.options[OPT_SPEECHTYPE] != 3) && (bigx > ui_view.GetWidth() - get_fixed_pixel_size(50))) + bigx = ui_view.GetWidth() - get_fixed_pixel_size(50); + + if (widd > 0) + bwidth = widd - bigx; + + our_eip=153; + int ovr_yp = get_fixed_pixel_size(20); + int view_frame_x = 0; + int view_frame_y = 0; + facetalk_qfg4_override_placement_x = false; + facetalk_qfg4_override_placement_y = false; + + if (game.options[OPT_SPEECHTYPE] == 3) { + // QFG4-style whole screen picture + closeupface = BitmapHelper::CreateBitmap(ui_view.GetWidth(), ui_view.GetHeight(), spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth()); + closeupface->Clear(0); + if (xx < 0 && play.speech_portrait_placement) + { + facetalk_qfg4_override_placement_x = true; + view_frame_x = play.speech_portrait_x; + } + if (yy < 0 && play.speech_portrait_placement) + { + facetalk_qfg4_override_placement_y = true; + view_frame_y = play.speech_portrait_y; + } + else + { + view_frame_y = ui_view.GetHeight()/2 - game.SpriteInfos[viptr->loops[0].frames[0].pic].Height/2; + } + bigx = ui_view.GetWidth()/2 - get_fixed_pixel_size(20); + ovr_type = OVER_COMPLETE; + ovr_yp = 0; + tdyp = -1; // center vertically + } + else { + // KQ6-style close-up face picture + if (yy < 0 && play.speech_portrait_placement) + { + ovr_yp = play.speech_portrait_y; + } + else if (yy < 0) + ovr_yp = adjust_y_for_guis (ovr_yp); + else + ovr_yp = yy; + + closeupface = BitmapHelper::CreateTransparentBitmap(bigx+1,bigy+1,spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth()); + ovr_type = OVER_PICTURE; + + if (yy < 0) + tdyp = ovr_yp + get_textwindow_top_border_height(play.speech_textwindow_gui); + } + const ViewFrame *vf = &viptr->loops[0].frames[0]; + const bool closeupface_has_alpha = (game.SpriteInfos[vf->pic].Flags & SPF_ALPHACHANNEL) != 0; + DrawViewFrame(closeupface, vf, view_frame_x, view_frame_y); + + int overlay_x = get_fixed_pixel_size(10); + if (xx < 0) { + tdxp = bigx + get_textwindow_border_width(play.speech_textwindow_gui) / 2; + if (play.speech_portrait_placement) + { + overlay_x = play.speech_portrait_x; + tdxp += overlay_x + get_fixed_pixel_size(6); + } + else + { + tdxp += get_fixed_pixel_size(16); + } + + int maxWidth = (ui_view.GetWidth() - tdxp) - get_fixed_pixel_size(5) - + get_textwindow_border_width (play.speech_textwindow_gui) / 2; + + if (bwidth > maxWidth) + bwidth = maxWidth; + } + else { + tdxp = xx + bigx + get_fixed_pixel_size(8); + overlay_x = xx; + } + + // allow the text box to be shrunk to fit the text + allowShrink = 1; + + // if the portrait's on the right, swap it round + if (portrait_on_right) { + if ((xx < 0) || (widd < 0)) { + tdxp = get_fixed_pixel_size(9); + if (play.speech_portrait_placement) + { + overlay_x = (ui_view.GetWidth() - bigx) - play.speech_portrait_x; + int maxWidth = overlay_x - tdxp - get_fixed_pixel_size(9) - + get_textwindow_border_width (play.speech_textwindow_gui) / 2; + if (bwidth > maxWidth) + bwidth = maxWidth; + } + else + { + overlay_x = (ui_view.GetWidth() - bigx) - get_fixed_pixel_size(5); + } + } + else { + overlay_x = (xx + widd - bigx) - get_fixed_pixel_size(5); + tdxp = xx; + } + tdxp += get_textwindow_border_width(play.speech_textwindow_gui) / 2; + allowShrink = 2; + } + if (game.options[OPT_SPEECHTYPE] == 3) + overlay_x = 0; + face_talking=add_screen_overlay(overlay_x,ovr_yp,ovr_type,closeupface, closeupface_has_alpha); + facetalkframe = 0; + facetalkwait = viptr->loops[0].frames[0].speed + GetCharacterSpeechAnimationDelay(speakingChar); + facetalkloop = 0; + facetalkview = useview; + facetalkrepeat = (isThought) ? 0 : 1; + facetalkBlinkLoop = 0; + facetalkAllowBlink = 1; + if ((isThought) && (speakingChar->flags & CHF_NOBLINKANDTHINK)) + facetalkAllowBlink = 0; + facetalkchar = &game.chars[aschar]; + if (facetalkchar->blinktimer < 0) + facetalkchar->blinktimer = facetalkchar->blinkinterval; + textcol=-textcol; + overlayPositionFixed = true; + } + else if (useview >= 0) { + // Lucasarts-style speech + our_eip=154; + + oldview = speakingChar->view; + oldloop = speakingChar->loop; + speakingChar->animating = 1 | (GetCharacterSpeechAnimationDelay(speakingChar) << 8); + // only repeat if speech, not thought + if (!isThought) + speakingChar->animating |= CHANIM_REPEAT; + + speakingChar->view = useview; + speakingChar->frame=0; + speakingChar->flags|=CHF_FIXVIEW; + + if (speakingChar->loop >= views[speakingChar->view].numLoops) + { + // current character loop is outside the normal talking directions + speakingChar->loop = 0; + } + + facetalkBlinkLoop = speakingChar->loop; + + if (speakingChar->on && // don't bother checking if character is not visible (also fixes 'Trilby's Notes' legacy game) + ((speakingChar->loop >= views[speakingChar->view].numLoops) || + (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1))) + { + quitprintf("!Unable to display speech because the character %s has an invalid speech view (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame); + } + + // set up the speed of the first frame + speakingChar->wait = GetCharacterSpeechAnimationDelay(speakingChar) + + views[speakingChar->view].loops[speakingChar->loop].frames[0].speed; + + if (widd < 0) { + bwidth = ui_view.GetWidth()/2 + ui_view.GetWidth()/6; + // If they are close to the screen edge, make the text narrower + int relx = play.RoomToScreenX(data_to_game_coord(speakingChar->x)); + if ((relx < ui_view.GetWidth() / 4) || (relx > ui_view.GetWidth() - (ui_view.GetWidth() / 4))) + bwidth -= ui_view.GetWidth() / 5; + } + /* this causes the text to bob up and down as they talk + tdxp = OVR_AUTOPLACE; + tdyp = aschar;*/ + if (!isThought) // set up the lip sync if not thinking + char_speaking = aschar; + + } + } + else + allowShrink = 1; + + // it wants the centred position, so make it so + if ((xx >= 0) && (tdxp < 0)) + tdxp -= widd / 2; + + // if they used DisplaySpeechAt, then use the supplied width + if ((widd > 0) && (isThought == 0)) + allowShrink = 0; + + if (isThought) + char_thinking = aschar; + + our_eip=155; + _display_at(tdxp, tdyp, bwidth, texx, DISPLAYTEXT_SPEECH, textcol, isThought, allowShrink, overlayPositionFixed); + our_eip=156; + if ((play.in_conversation > 0) && (game.options[OPT_SPEECHTYPE] == 3)) + closeupface = nullptr; + if (closeupface!=nullptr) + remove_screen_overlay(ovr_type); + mark_screen_dirty(); + face_talking = -1; + facetalkchar = nullptr; + our_eip=157; + if (oldview>=0) { + speakingChar->flags &= ~CHF_FIXVIEW; + if (viewWasLocked) + speakingChar->flags |= CHF_FIXVIEW; + speakingChar->view=oldview; + + // Don't reset the loop in 2.x games + if (loaded_game_file_version > kGameVersion_272) + speakingChar->loop = oldloop; + + speakingChar->animating=0; + speakingChar->frame = charFrameWas; + speakingChar->wait=0; + speakingChar->idleleft = speakingChar->idletime; + // restart the idle animation straight away + charextra[aschar].process_idle_this_time = 1; + } + char_speaking = -1; + char_thinking = -1; + if (play.IsBlockingVoiceSpeech()) + stop_voice_speech(); +} + +int get_character_currently_talking() { + if ((face_talking >= 0) && (facetalkrepeat)) + return facetalkchar->index_id; + else if (char_speaking >= 0) + return char_speaking; + + return -1; +} + +void DisplaySpeech(const char*texx, int aschar) { + _displayspeech (texx, aschar, -1, -1, -1, 0); +} + +// Calculate which frame of the loop to use for this character of +// speech +int GetLipSyncFrame (const char *curtex, int *stroffs) { + /*char *frameletters[MAXLIPSYNCFRAMES] = + {"./,/ ", "A", "O", "F/V", "D/N/G/L/R", "B/P/M", + "Y/H/K/Q/C", "I/T/E/X/th", "U/W", "S/Z/J/ch", NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};*/ + + int bestfit_len = 0, bestfit = game.default_lipsync_frame; + for (int aa = 0; aa < MAXLIPSYNCFRAMES; aa++) { + char *tptr = game.lipSyncFrameLetters[aa]; + while (tptr[0] != 0) { + int lenthisbit = strlen(tptr); + if (strchr(tptr, '/')) + lenthisbit = strchr(tptr, '/') - tptr; + + if ((ags_strnicmp (curtex, tptr, lenthisbit) == 0) && (lenthisbit > bestfit_len)) { + bestfit = aa; + bestfit_len = lenthisbit; + } + tptr += lenthisbit; + while (tptr[0] == '/') + tptr++; + } + } + // If it's an unknown character, use the default frame + if (bestfit_len == 0) + bestfit_len = 1; + *stroffs += bestfit_len; + return bestfit; +} + +int update_lip_sync(int talkview, int talkloop, int *talkframeptr) { + int talkframe = talkframeptr[0]; + int talkwait = 0; + + // lip-sync speech + const char *nowsaying = &text_lips_text[text_lips_offset]; + // if it's an apostraphe, skip it (we'll, I'll, etc) + if (nowsaying[0] == '\'') { + text_lips_offset++; + nowsaying++; + } + + if (text_lips_offset >= (int)strlen(text_lips_text)) + talkframe = 0; + else { + talkframe = GetLipSyncFrame (nowsaying, &text_lips_offset); + if (talkframe >= views[talkview].loops[talkloop].numFrames) + talkframe = 0; + } + + talkwait = loops_per_character + views[talkview].loops[talkloop].frames[talkframe].speed; + + talkframeptr[0] = talkframe; + return talkwait; +} + +Rect GetCharacterRoomBBox(int charid, bool use_frame_0) +{ + int width, height; + const CharacterExtras& chex = charextra[charid]; + const CharacterInfo& chin = game.chars[charid]; + int frame = use_frame_0 ? 0 : chin.frame; + int pic = views[chin.view].loops[chin.loop].frames[frame].pic; + scale_sprite_size(pic, chex.zoom, &width, &height); + return RectWH(chin.x - width / 2, chin.y - height, width, height); +} + +PViewport FindNearestViewport(int charid) +{ + Rect bbox = GetCharacterRoomBBox(charid, true); + float min_dist = -1.f; + PViewport nearest_view; + for (int i = 0; i < play.GetRoomViewportCount(); ++i) + { + auto view = play.GetRoomViewport(i); + if (!view->IsVisible()) + continue; + auto cam = view->GetCamera(); + if (!cam) + continue; + Rect camr = cam->GetRect(); + float dist = DistanceBetween(bbox, camr); + if (dist == 0.f) + return view; + if (min_dist < 0.f || dist < min_dist) + { + min_dist = dist; + nearest_view = view; + } + } + return nearest_view ? nearest_view : play.GetRoomViewport(0); +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// void | CharacterInfo *chaa, ScriptInvItem *invi, int addIndex +RuntimeScriptValue Sc_Character_AddInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_AddInventory, ScriptInvItem); +} + +// void | CharacterInfo *chaa, int x, int y +RuntimeScriptValue Sc_Character_AddWaypoint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_AddWaypoint); +} + +// void | CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction +RuntimeScriptValue Sc_Character_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Animate); +} + +RuntimeScriptValue Sc_Character_AnimateFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT6(CharacterInfo, Character_AnimateFrom); +} + +// void | CharacterInfo *chaa, int room, int x, int y +RuntimeScriptValue Sc_Character_ChangeRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_ChangeRoom); +} + +RuntimeScriptValue Sc_Character_ChangeRoomSetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_ChangeRoomSetLoop); +} + +// void | CharacterInfo *chaa, int room, int newPos +RuntimeScriptValue Sc_Character_ChangeRoomAutoPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_ChangeRoomAutoPosition); +} + +// void | CharacterInfo *chap, int vii +RuntimeScriptValue Sc_Character_ChangeView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_ChangeView); +} + +// void | CharacterInfo *char1, CharacterInfo *char2, int blockingStyle +RuntimeScriptValue Sc_Character_FaceCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceCharacter, CharacterInfo); +} + +// void | CharacterInfo *char1, int direction, int blockingStyle +RuntimeScriptValue Sc_Character_FaceDirection(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_FaceDirection); +} + +// void | CharacterInfo *char1, int xx, int yy, int blockingStyle +RuntimeScriptValue Sc_Character_FaceLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_FaceLocation); +} + +// void | CharacterInfo *char1, ScriptObject *obj, int blockingStyle +RuntimeScriptValue Sc_Character_FaceObject(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceObject, ScriptObject); +} + +// void | CharacterInfo *chaa, CharacterInfo *tofollow, int distaway, int eagerness +RuntimeScriptValue Sc_Character_FollowCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ_PINT2(CharacterInfo, Character_FollowCharacter, CharacterInfo); +} + +// int (CharacterInfo *chaa, const char *property) +RuntimeScriptValue Sc_Character_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(CharacterInfo, Character_GetProperty, const char); +} + +// void (CharacterInfo *chaa, const char *property, char *bufer) +RuntimeScriptValue Sc_Character_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ2(CharacterInfo, Character_GetPropertyText, const char, char); +} + +// const char* (CharacterInfo *chaa, const char *property) +RuntimeScriptValue Sc_Character_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_POBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetTextProperty, const char); +} + +RuntimeScriptValue Sc_Character_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ_PINT(CharacterInfo, Character_SetProperty, const char); +} + +RuntimeScriptValue Sc_Character_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ2(CharacterInfo, Character_SetTextProperty, const char, const char); +} + +// int (CharacterInfo *chaa, ScriptInvItem *invi) +RuntimeScriptValue Sc_Character_HasInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(CharacterInfo, Character_HasInventory, ScriptInvItem); +} + +// int (CharacterInfo *char1, CharacterInfo *char2) +RuntimeScriptValue Sc_Character_IsCollidingWithChar(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithChar, CharacterInfo); +} + +// int (CharacterInfo *chin, ScriptObject *objid) +RuntimeScriptValue Sc_Character_IsCollidingWithObject(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithObject, ScriptObject); +} + +RuntimeScriptValue Sc_Character_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_PINT(CharacterInfo, Character_IsInteractionAvailable); +} + +// void (CharacterInfo *chap, int vii) +RuntimeScriptValue Sc_Character_LockView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_LockView); +} + +// void (CharacterInfo *chap, int vii, int stopMoving) +RuntimeScriptValue Sc_Character_LockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_LockViewEx); +} + +// void (CharacterInfo *chap, int vii, int loop, int align) +RuntimeScriptValue Sc_Character_LockViewAligned_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewAligned_Old); +} + +// void (CharacterInfo *chap, int vii, int loop, int align, int stopMoving) +RuntimeScriptValue Sc_Character_LockViewAlignedEx_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewAlignedEx_Old); +} + +RuntimeScriptValue Sc_Character_LockViewAligned(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewAligned); +} + +RuntimeScriptValue Sc_Character_LockViewAlignedEx(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewAlignedEx); +} + +// void (CharacterInfo *chaa, int view, int loop, int frame) +RuntimeScriptValue Sc_Character_LockViewFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewFrame); +} + +// void (CharacterInfo *chaa, int view, int loop, int frame, int stopMoving) +RuntimeScriptValue Sc_Character_LockViewFrameEx(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewFrameEx); +} + +// void (CharacterInfo *chap, int vii, int xoffs, int yoffs) +RuntimeScriptValue Sc_Character_LockViewOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewOffset); +} + +// void (CharacterInfo *chap, int vii, int xoffs, int yoffs, int stopMoving) +RuntimeScriptValue Sc_Character_LockViewOffsetEx(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewOffsetEx); +} + +// void (CharacterInfo *chap, ScriptInvItem *invi) +RuntimeScriptValue Sc_Character_LoseInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(CharacterInfo, Character_LoseInventory, ScriptInvItem); +} + +// void (CharacterInfo *chaa, int x, int y, int blocking, int direct) +RuntimeScriptValue Sc_Character_Move(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Move); +} + +// void (CharacterInfo *chap) +RuntimeScriptValue Sc_Character_PlaceOnWalkableArea(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(CharacterInfo, Character_PlaceOnWalkableArea); +} + +// void (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_RemoveTint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(CharacterInfo, Character_RemoveTint); +} + +// void (CharacterInfo *chaa, int mood) +RuntimeScriptValue Sc_Character_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_RunInteraction); +} + +// void (CharacterInfo *chaa, const char *texx, ...) +RuntimeScriptValue Sc_Character_Say(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_SCRIPT_SPRINTF(Character_Say, 1); + Character_Say((CharacterInfo*)self, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (CharacterInfo *chaa, int x, int y, int width, const char *texx) +RuntimeScriptValue Sc_Character_SayAt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3_POBJ(CharacterInfo, Character_SayAt, const char); +} + +// ScriptOverlay* (CharacterInfo *chaa, const char *texx) +RuntimeScriptValue Sc_Character_SayBackground(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJAUTO_POBJ(CharacterInfo, ScriptOverlay, Character_SayBackground, const char); +} + +// void (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_SetAsPlayer(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(CharacterInfo, Character_SetAsPlayer); +} + +// void (CharacterInfo *chaa, int iview, int itime) +RuntimeScriptValue Sc_Character_SetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIdleView); +} + +RuntimeScriptValue Sc_Character_HasExplicitLight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(CharacterInfo, Character_GetHasExplicitLight); +} + +RuntimeScriptValue Sc_Character_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetLightLevel); +} + +RuntimeScriptValue Sc_Character_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLightLevel); +} + +RuntimeScriptValue Sc_Character_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetTintBlue); +} + +RuntimeScriptValue Sc_Character_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetTintGreen); +} + +RuntimeScriptValue Sc_Character_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetTintRed); +} + +RuntimeScriptValue Sc_Character_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetTintSaturation); +} + +RuntimeScriptValue Sc_Character_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetTintLuminance); +} + +/* +RuntimeScriptValue Sc_Character_SetOption(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ +} +*/ + +// void (CharacterInfo *chaa, int xspeed, int yspeed) +RuntimeScriptValue Sc_Character_SetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetSpeed); +} + +// void (CharacterInfo *charp) +RuntimeScriptValue Sc_Character_StopMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(CharacterInfo, Character_StopMoving); +} + +// void (CharacterInfo *chaa, const char *texx, ...) +RuntimeScriptValue Sc_Character_Think(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_SCRIPT_SPRINTF(Character_Think, 1); + Character_Think((CharacterInfo*)self, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +//void (CharacterInfo *chaa, int red, int green, int blue, int opacity, int luminance) +RuntimeScriptValue Sc_Character_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Tint); +} + +// void (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_UnlockView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(CharacterInfo, Character_UnlockView); +} + +// void (CharacterInfo *chaa, int stopMoving) +RuntimeScriptValue Sc_Character_UnlockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_UnlockViewEx); +} + +// void (CharacterInfo *chaa, int x, int y, int blocking, int direct) +RuntimeScriptValue Sc_Character_Walk(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Walk); +} + +// void (CharacterInfo *chaa, int xx, int yy, int blocking) +RuntimeScriptValue Sc_Character_WalkStraight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_WalkStraight); +} + +RuntimeScriptValue Sc_GetCharacterAtRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtRoom); +} + +// CharacterInfo *(int xx, int yy) +RuntimeScriptValue Sc_GetCharacterAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtScreen); +} + +// ScriptInvItem* (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(CharacterInfo, ScriptInvItem, ccDynamicInv, Character_GetActiveInventory); +} + +// void (CharacterInfo *chaa, ScriptInvItem* iit) +RuntimeScriptValue Sc_Character_SetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetActiveInventory, ScriptInvItem); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetAnimating); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetAnimationSpeed); +} + +// void (CharacterInfo *chaa, int newval) +RuntimeScriptValue Sc_Character_SetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetAnimationSpeed); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetBaseline); +} + +// void (CharacterInfo *chaa, int basel) +RuntimeScriptValue Sc_Character_SetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBaseline); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetBlinkInterval); +} + +// void (CharacterInfo *chaa, int interval) +RuntimeScriptValue Sc_Character_SetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkInterval); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetBlinkView); +} + +// void (CharacterInfo *chaa, int vii) +RuntimeScriptValue Sc_Character_SetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkView); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetBlinkWhileThinking); +} + +// void (CharacterInfo *chaa, int yesOrNo) +RuntimeScriptValue Sc_Character_SetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkWhileThinking); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetBlockingHeight); +} + +// void (CharacterInfo *chaa, int hit) +RuntimeScriptValue Sc_Character_SetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingHeight); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetBlockingWidth); +} + +// void (CharacterInfo *chaa, int wid) +RuntimeScriptValue Sc_Character_SetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingWidth); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetClickable); +} + +// void (CharacterInfo *chaa, int clik) +RuntimeScriptValue Sc_Character_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetClickable); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetDiagonalWalking); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetDiagonalWalking); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetFrame); +} + +// void (CharacterInfo *chaa, int newval) +RuntimeScriptValue Sc_Character_SetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetFrame); +} + +RuntimeScriptValue Sc_Character_GetHasExplicitTint_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetHasExplicitTint_Old); +} + +RuntimeScriptValue Sc_Character_GetHasExplicitTint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetHasExplicitTint); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetID); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetIdleView); +} + +// int (CharacterInfo *chaa, int index) +RuntimeScriptValue Sc_Character_GetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(CharacterInfo, Character_GetIInventoryQuantity); +} + +// void (CharacterInfo *chaa, int index, int quant) +RuntimeScriptValue Sc_Character_SetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIInventoryQuantity); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreLighting); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreLighting); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreScaling); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreScaling); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreWalkbehinds); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreWalkbehinds); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetLoop); +} + +// void (CharacterInfo *chaa, int newval) +RuntimeScriptValue Sc_Character_SetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLoop); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetManualScaling); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetMovementLinkedToAnimation); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetMovementLinkedToAnimation); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetMoving); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetDestinationX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetDestinationX); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetDestinationY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetDestinationY); +} + +// const char* (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetName); +} + +// void (CharacterInfo *chaa, const char *newName) +RuntimeScriptValue Sc_Character_SetName(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetName, const char); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetNormalView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetNormalView); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetPreviousRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetPreviousRoom); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetRoom); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetScaleMoveSpeed); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleMoveSpeed); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetScaleVolume); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleVolume); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetScaling); +} + +// void (CharacterInfo *chaa, int zoomlevel) +RuntimeScriptValue Sc_Character_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaling); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetSolid); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSolid); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetSpeaking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetSpeaking); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetSpeakingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetSpeakingFrame); +} + +// int (CharacterInfo *cha) +RuntimeScriptValue Sc_GetCharacterSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, GetCharacterSpeechAnimationDelay); +} + +// void (CharacterInfo *chaa, int newDelay) +RuntimeScriptValue Sc_Character_SetSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechAnimationDelay); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetSpeechColor); +} + +// void (CharacterInfo *chaa, int ncol) +RuntimeScriptValue Sc_Character_SetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechColor); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetSpeechView); +} + +// void (CharacterInfo *chaa, int vii) +RuntimeScriptValue Sc_Character_SetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechView); +} + +RuntimeScriptValue Sc_Character_GetThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(CharacterInfo, Character_GetThinking); +} + +RuntimeScriptValue Sc_Character_GetThinkingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetThinkingFrame); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetThinkView); +} + +// void (CharacterInfo *chaa, int vii) +RuntimeScriptValue Sc_Character_SetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetThinkView); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetTransparency); +} + +// void (CharacterInfo *chaa, int trans) +RuntimeScriptValue Sc_Character_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTransparency); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetTurnBeforeWalking); +} + +// void (CharacterInfo *chaa, int yesorno) +RuntimeScriptValue Sc_Character_SetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTurnBeforeWalking); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetView); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetWalkSpeedX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedX); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetWalkSpeedY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedY); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetX); +} + +// void (CharacterInfo *chaa, int newval) +RuntimeScriptValue Sc_Character_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetX); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetY); +} + +// void (CharacterInfo *chaa, int newval) +RuntimeScriptValue Sc_Character_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetY); +} + +// int (CharacterInfo *chaa) +RuntimeScriptValue Sc_Character_GetZ(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(CharacterInfo, Character_GetZ); +} + +// void (CharacterInfo *chaa, int newval) +RuntimeScriptValue Sc_Character_SetZ(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetZ); +} + +//============================================================================= +// +// Exclusive API for Plugins +// +//============================================================================= + +// void (CharacterInfo *chaa, const char *texx, ...) +void ScPl_Character_Say(CharacterInfo *chaa, const char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + Character_Say(chaa, scsf_buffer); +} + +// void (CharacterInfo *chaa, const char *texx, ...) +void ScPl_Character_Think(CharacterInfo *chaa, const char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + Character_Think(chaa, scsf_buffer); +} + +void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) +{ + ccAddExternalObjectFunction("Character::AddInventory^2", Sc_Character_AddInventory); + ccAddExternalObjectFunction("Character::AddWaypoint^2", Sc_Character_AddWaypoint); + ccAddExternalObjectFunction("Character::Animate^5", Sc_Character_Animate); + ccAddExternalObjectFunction("Character::Animate^6", Sc_Character_AnimateFrom); + ccAddExternalObjectFunction("Character::ChangeRoom^3", Sc_Character_ChangeRoom); + ccAddExternalObjectFunction("Character::ChangeRoom^4", Sc_Character_ChangeRoomSetLoop); + ccAddExternalObjectFunction("Character::ChangeRoomAutoPosition^2", Sc_Character_ChangeRoomAutoPosition); + ccAddExternalObjectFunction("Character::ChangeView^1", Sc_Character_ChangeView); + ccAddExternalObjectFunction("Character::FaceCharacter^2", Sc_Character_FaceCharacter); + ccAddExternalObjectFunction("Character::FaceDirection^2", Sc_Character_FaceDirection); + ccAddExternalObjectFunction("Character::FaceLocation^3", Sc_Character_FaceLocation); + ccAddExternalObjectFunction("Character::FaceObject^2", Sc_Character_FaceObject); + ccAddExternalObjectFunction("Character::FollowCharacter^3", Sc_Character_FollowCharacter); + ccAddExternalObjectFunction("Character::GetProperty^1", Sc_Character_GetProperty); + ccAddExternalObjectFunction("Character::GetPropertyText^2", Sc_Character_GetPropertyText); + ccAddExternalObjectFunction("Character::GetTextProperty^1", Sc_Character_GetTextProperty); + ccAddExternalObjectFunction("Character::SetProperty^2", Sc_Character_SetProperty); + ccAddExternalObjectFunction("Character::SetTextProperty^2", Sc_Character_SetTextProperty); + ccAddExternalObjectFunction("Character::HasInventory^1", Sc_Character_HasInventory); + ccAddExternalObjectFunction("Character::IsCollidingWithChar^1", Sc_Character_IsCollidingWithChar); + ccAddExternalObjectFunction("Character::IsCollidingWithObject^1", Sc_Character_IsCollidingWithObject); + ccAddExternalObjectFunction("Character::IsInteractionAvailable^1", Sc_Character_IsInteractionAvailable); + ccAddExternalObjectFunction("Character::LockView^1", Sc_Character_LockView); + ccAddExternalObjectFunction("Character::LockView^2", Sc_Character_LockViewEx); + if (base_api < kScriptAPI_v350) + { + ccAddExternalObjectFunction("Character::LockViewAligned^3", Sc_Character_LockViewAligned_Old); + ccAddExternalObjectFunction("Character::LockViewAligned^4", Sc_Character_LockViewAlignedEx_Old); + } + else + { + ccAddExternalObjectFunction("Character::LockViewAligned^3", Sc_Character_LockViewAligned); + ccAddExternalObjectFunction("Character::LockViewAligned^4", Sc_Character_LockViewAlignedEx); + } + ccAddExternalObjectFunction("Character::LockViewFrame^3", Sc_Character_LockViewFrame); + ccAddExternalObjectFunction("Character::LockViewFrame^4", Sc_Character_LockViewFrameEx); + ccAddExternalObjectFunction("Character::LockViewOffset^3", Sc_Character_LockViewOffset); + ccAddExternalObjectFunction("Character::LockViewOffset^4", Sc_Character_LockViewOffsetEx); + ccAddExternalObjectFunction("Character::LoseInventory^1", Sc_Character_LoseInventory); + ccAddExternalObjectFunction("Character::Move^4", Sc_Character_Move); + ccAddExternalObjectFunction("Character::PlaceOnWalkableArea^0", Sc_Character_PlaceOnWalkableArea); + ccAddExternalObjectFunction("Character::RemoveTint^0", Sc_Character_RemoveTint); + ccAddExternalObjectFunction("Character::RunInteraction^1", Sc_Character_RunInteraction); + ccAddExternalObjectFunction("Character::Say^101", Sc_Character_Say); + ccAddExternalObjectFunction("Character::SayAt^4", Sc_Character_SayAt); + ccAddExternalObjectFunction("Character::SayBackground^1", Sc_Character_SayBackground); + ccAddExternalObjectFunction("Character::SetAsPlayer^0", Sc_Character_SetAsPlayer); + ccAddExternalObjectFunction("Character::SetIdleView^2", Sc_Character_SetIdleView); + ccAddExternalObjectFunction("Character::SetLightLevel^1", Sc_Character_SetLightLevel); + //ccAddExternalObjectFunction("Character::SetOption^2", Sc_Character_SetOption); + ccAddExternalObjectFunction("Character::SetWalkSpeed^2", Sc_Character_SetSpeed); + ccAddExternalObjectFunction("Character::StopMoving^0", Sc_Character_StopMoving); + ccAddExternalObjectFunction("Character::Think^101", Sc_Character_Think); + ccAddExternalObjectFunction("Character::Tint^5", Sc_Character_Tint); + ccAddExternalObjectFunction("Character::UnlockView^0", Sc_Character_UnlockView); + ccAddExternalObjectFunction("Character::UnlockView^1", Sc_Character_UnlockViewEx); + ccAddExternalObjectFunction("Character::Walk^4", Sc_Character_Walk); + ccAddExternalObjectFunction("Character::WalkStraight^3", Sc_Character_WalkStraight); + + ccAddExternalStaticFunction("Character::GetAtRoomXY^2", Sc_GetCharacterAtRoom); + ccAddExternalStaticFunction("Character::GetAtScreenXY^2", Sc_GetCharacterAtScreen); + + ccAddExternalObjectFunction("Character::get_ActiveInventory", Sc_Character_GetActiveInventory); + ccAddExternalObjectFunction("Character::set_ActiveInventory", Sc_Character_SetActiveInventory); + ccAddExternalObjectFunction("Character::get_Animating", Sc_Character_GetAnimating); + ccAddExternalObjectFunction("Character::get_AnimationSpeed", Sc_Character_GetAnimationSpeed); + ccAddExternalObjectFunction("Character::set_AnimationSpeed", Sc_Character_SetAnimationSpeed); + ccAddExternalObjectFunction("Character::get_Baseline", Sc_Character_GetBaseline); + ccAddExternalObjectFunction("Character::set_Baseline", Sc_Character_SetBaseline); + ccAddExternalObjectFunction("Character::get_BlinkInterval", Sc_Character_GetBlinkInterval); + ccAddExternalObjectFunction("Character::set_BlinkInterval", Sc_Character_SetBlinkInterval); + ccAddExternalObjectFunction("Character::get_BlinkView", Sc_Character_GetBlinkView); + ccAddExternalObjectFunction("Character::set_BlinkView", Sc_Character_SetBlinkView); + ccAddExternalObjectFunction("Character::get_BlinkWhileThinking", Sc_Character_GetBlinkWhileThinking); + ccAddExternalObjectFunction("Character::set_BlinkWhileThinking", Sc_Character_SetBlinkWhileThinking); + ccAddExternalObjectFunction("Character::get_BlockingHeight", Sc_Character_GetBlockingHeight); + ccAddExternalObjectFunction("Character::set_BlockingHeight", Sc_Character_SetBlockingHeight); + ccAddExternalObjectFunction("Character::get_BlockingWidth", Sc_Character_GetBlockingWidth); + ccAddExternalObjectFunction("Character::set_BlockingWidth", Sc_Character_SetBlockingWidth); + ccAddExternalObjectFunction("Character::get_Clickable", Sc_Character_GetClickable); + ccAddExternalObjectFunction("Character::set_Clickable", Sc_Character_SetClickable); + ccAddExternalObjectFunction("Character::get_DestinationX", Sc_Character_GetDestinationX); + ccAddExternalObjectFunction("Character::get_DestinationY", Sc_Character_GetDestinationY); + ccAddExternalObjectFunction("Character::get_DiagonalLoops", Sc_Character_GetDiagonalWalking); + ccAddExternalObjectFunction("Character::set_DiagonalLoops", Sc_Character_SetDiagonalWalking); + ccAddExternalObjectFunction("Character::get_Frame", Sc_Character_GetFrame); + ccAddExternalObjectFunction("Character::set_Frame", Sc_Character_SetFrame); + if (base_api < kScriptAPI_v341) + ccAddExternalObjectFunction("Character::get_HasExplicitTint", Sc_Character_GetHasExplicitTint_Old); + else + ccAddExternalObjectFunction("Character::get_HasExplicitTint", Sc_Character_GetHasExplicitTint); + ccAddExternalObjectFunction("Character::get_ID", Sc_Character_GetID); + ccAddExternalObjectFunction("Character::get_IdleView", Sc_Character_GetIdleView); + ccAddExternalObjectFunction("Character::geti_InventoryQuantity", Sc_Character_GetIInventoryQuantity); + ccAddExternalObjectFunction("Character::seti_InventoryQuantity", Sc_Character_SetIInventoryQuantity); + ccAddExternalObjectFunction("Character::get_IgnoreLighting", Sc_Character_GetIgnoreLighting); + ccAddExternalObjectFunction("Character::set_IgnoreLighting", Sc_Character_SetIgnoreLighting); + ccAddExternalObjectFunction("Character::get_IgnoreScaling", Sc_Character_GetIgnoreScaling); + ccAddExternalObjectFunction("Character::set_IgnoreScaling", Sc_Character_SetIgnoreScaling); + ccAddExternalObjectFunction("Character::get_IgnoreWalkbehinds", Sc_Character_GetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Character::set_IgnoreWalkbehinds", Sc_Character_SetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Character::get_Loop", Sc_Character_GetLoop); + ccAddExternalObjectFunction("Character::set_Loop", Sc_Character_SetLoop); + ccAddExternalObjectFunction("Character::get_ManualScaling", Sc_Character_GetIgnoreScaling); + ccAddExternalObjectFunction("Character::set_ManualScaling", Sc_Character_SetManualScaling); + ccAddExternalObjectFunction("Character::get_MovementLinkedToAnimation",Sc_Character_GetMovementLinkedToAnimation); + ccAddExternalObjectFunction("Character::set_MovementLinkedToAnimation",Sc_Character_SetMovementLinkedToAnimation); + ccAddExternalObjectFunction("Character::get_Moving", Sc_Character_GetMoving); + ccAddExternalObjectFunction("Character::get_Name", Sc_Character_GetName); + ccAddExternalObjectFunction("Character::set_Name", Sc_Character_SetName); + ccAddExternalObjectFunction("Character::get_NormalView", Sc_Character_GetNormalView); + ccAddExternalObjectFunction("Character::get_PreviousRoom", Sc_Character_GetPreviousRoom); + ccAddExternalObjectFunction("Character::get_Room", Sc_Character_GetRoom); + ccAddExternalObjectFunction("Character::get_ScaleMoveSpeed", Sc_Character_GetScaleMoveSpeed); + ccAddExternalObjectFunction("Character::set_ScaleMoveSpeed", Sc_Character_SetScaleMoveSpeed); + ccAddExternalObjectFunction("Character::get_ScaleVolume", Sc_Character_GetScaleVolume); + ccAddExternalObjectFunction("Character::set_ScaleVolume", Sc_Character_SetScaleVolume); + ccAddExternalObjectFunction("Character::get_Scaling", Sc_Character_GetScaling); + ccAddExternalObjectFunction("Character::set_Scaling", Sc_Character_SetScaling); + ccAddExternalObjectFunction("Character::get_Solid", Sc_Character_GetSolid); + ccAddExternalObjectFunction("Character::set_Solid", Sc_Character_SetSolid); + ccAddExternalObjectFunction("Character::get_Speaking", Sc_Character_GetSpeaking); + ccAddExternalObjectFunction("Character::get_SpeakingFrame", Sc_Character_GetSpeakingFrame); + ccAddExternalObjectFunction("Character::get_SpeechAnimationDelay", Sc_GetCharacterSpeechAnimationDelay); + ccAddExternalObjectFunction("Character::set_SpeechAnimationDelay", Sc_Character_SetSpeechAnimationDelay); + ccAddExternalObjectFunction("Character::get_SpeechColor", Sc_Character_GetSpeechColor); + ccAddExternalObjectFunction("Character::set_SpeechColor", Sc_Character_SetSpeechColor); + ccAddExternalObjectFunction("Character::get_SpeechView", Sc_Character_GetSpeechView); + ccAddExternalObjectFunction("Character::set_SpeechView", Sc_Character_SetSpeechView); + ccAddExternalObjectFunction("Character::get_Thinking", Sc_Character_GetThinking); + ccAddExternalObjectFunction("Character::get_ThinkingFrame", Sc_Character_GetThinkingFrame); + ccAddExternalObjectFunction("Character::get_ThinkView", Sc_Character_GetThinkView); + ccAddExternalObjectFunction("Character::set_ThinkView", Sc_Character_SetThinkView); + ccAddExternalObjectFunction("Character::get_Transparency", Sc_Character_GetTransparency); + ccAddExternalObjectFunction("Character::set_Transparency", Sc_Character_SetTransparency); + ccAddExternalObjectFunction("Character::get_TurnBeforeWalking", Sc_Character_GetTurnBeforeWalking); + ccAddExternalObjectFunction("Character::set_TurnBeforeWalking", Sc_Character_SetTurnBeforeWalking); + ccAddExternalObjectFunction("Character::get_View", Sc_Character_GetView); + ccAddExternalObjectFunction("Character::get_WalkSpeedX", Sc_Character_GetWalkSpeedX); + ccAddExternalObjectFunction("Character::get_WalkSpeedY", Sc_Character_GetWalkSpeedY); + ccAddExternalObjectFunction("Character::get_X", Sc_Character_GetX); + ccAddExternalObjectFunction("Character::set_X", Sc_Character_SetX); + ccAddExternalObjectFunction("Character::get_x", Sc_Character_GetX); + ccAddExternalObjectFunction("Character::set_x", Sc_Character_SetX); + ccAddExternalObjectFunction("Character::get_Y", Sc_Character_GetY); + ccAddExternalObjectFunction("Character::set_Y", Sc_Character_SetY); + ccAddExternalObjectFunction("Character::get_y", Sc_Character_GetY); + ccAddExternalObjectFunction("Character::set_y", Sc_Character_SetY); + ccAddExternalObjectFunction("Character::get_Z", Sc_Character_GetZ); + ccAddExternalObjectFunction("Character::set_Z", Sc_Character_SetZ); + ccAddExternalObjectFunction("Character::get_z", Sc_Character_GetZ); + ccAddExternalObjectFunction("Character::set_z", Sc_Character_SetZ); + + ccAddExternalObjectFunction("Character::get_HasExplicitLight", Sc_Character_HasExplicitLight); + ccAddExternalObjectFunction("Character::get_LightLevel", Sc_Character_GetLightLevel); + ccAddExternalObjectFunction("Character::get_TintBlue", Sc_Character_GetTintBlue); + ccAddExternalObjectFunction("Character::get_TintGreen", Sc_Character_GetTintGreen); + ccAddExternalObjectFunction("Character::get_TintRed", Sc_Character_GetTintRed); + ccAddExternalObjectFunction("Character::get_TintSaturation", Sc_Character_GetTintSaturation); + ccAddExternalObjectFunction("Character::get_TintLuminance", Sc_Character_GetTintLuminance); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Character::AddInventory^2", (void*)Character_AddInventory); + ccAddExternalFunctionForPlugin("Character::AddWaypoint^2", (void*)Character_AddWaypoint); + ccAddExternalFunctionForPlugin("Character::Animate^5", (void*)Character_Animate); + ccAddExternalFunctionForPlugin("Character::ChangeRoom^3", (void*)Character_ChangeRoom); + ccAddExternalFunctionForPlugin("Character::ChangeRoomAutoPosition^2", (void*)Character_ChangeRoomAutoPosition); + ccAddExternalFunctionForPlugin("Character::ChangeView^1", (void*)Character_ChangeView); + ccAddExternalFunctionForPlugin("Character::FaceCharacter^2", (void*)Character_FaceCharacter); + ccAddExternalFunctionForPlugin("Character::FaceDirection^2", (void*)Character_FaceDirection); + ccAddExternalFunctionForPlugin("Character::FaceLocation^3", (void*)Character_FaceLocation); + ccAddExternalFunctionForPlugin("Character::FaceObject^2", (void*)Character_FaceObject); + ccAddExternalFunctionForPlugin("Character::FollowCharacter^3", (void*)Character_FollowCharacter); + ccAddExternalFunctionForPlugin("Character::GetProperty^1", (void*)Character_GetProperty); + ccAddExternalFunctionForPlugin("Character::GetPropertyText^2", (void*)Character_GetPropertyText); + ccAddExternalFunctionForPlugin("Character::GetTextProperty^1", (void*)Character_GetTextProperty); + ccAddExternalFunctionForPlugin("Character::HasInventory^1", (void*)Character_HasInventory); + ccAddExternalFunctionForPlugin("Character::IsCollidingWithChar^1", (void*)Character_IsCollidingWithChar); + ccAddExternalFunctionForPlugin("Character::IsCollidingWithObject^1", (void*)Character_IsCollidingWithObject); + ccAddExternalFunctionForPlugin("Character::LockView^1", (void*)Character_LockView); + ccAddExternalFunctionForPlugin("Character::LockView^2", (void*)Character_LockViewEx); + if (base_api < kScriptAPI_v341) + { + ccAddExternalFunctionForPlugin("Character::LockViewAligned^3", (void*)Character_LockViewAligned_Old); + ccAddExternalFunctionForPlugin("Character::LockViewAligned^4", (void*)Character_LockViewAlignedEx_Old); + } + else + { + ccAddExternalFunctionForPlugin("Character::LockViewAligned^3", (void*)Character_LockViewAligned); + ccAddExternalFunctionForPlugin("Character::LockViewAligned^4", (void*)Character_LockViewAlignedEx); + } + ccAddExternalFunctionForPlugin("Character::LockViewFrame^3", (void*)Character_LockViewFrame); + ccAddExternalFunctionForPlugin("Character::LockViewFrame^4", (void*)Character_LockViewFrameEx); + ccAddExternalFunctionForPlugin("Character::LockViewOffset^3", (void*)Character_LockViewOffset); + ccAddExternalFunctionForPlugin("Character::LockViewOffset^4", (void*)Character_LockViewOffset); + ccAddExternalFunctionForPlugin("Character::LoseInventory^1", (void*)Character_LoseInventory); + ccAddExternalFunctionForPlugin("Character::Move^4", (void*)Character_Move); + ccAddExternalFunctionForPlugin("Character::PlaceOnWalkableArea^0", (void*)Character_PlaceOnWalkableArea); + ccAddExternalFunctionForPlugin("Character::RemoveTint^0", (void*)Character_RemoveTint); + ccAddExternalFunctionForPlugin("Character::RunInteraction^1", (void*)Character_RunInteraction); + ccAddExternalFunctionForPlugin("Character::Say^101", (void*)ScPl_Character_Say); + ccAddExternalFunctionForPlugin("Character::SayAt^4", (void*)Character_SayAt); + ccAddExternalFunctionForPlugin("Character::SayBackground^1", (void*)Character_SayBackground); + ccAddExternalFunctionForPlugin("Character::SetAsPlayer^0", (void*)Character_SetAsPlayer); + ccAddExternalFunctionForPlugin("Character::SetIdleView^2", (void*)Character_SetIdleView); + //ccAddExternalFunctionForPlugin("Character::SetOption^2", (void*)Character_SetOption); + ccAddExternalFunctionForPlugin("Character::SetWalkSpeed^2", (void*)Character_SetSpeed); + ccAddExternalFunctionForPlugin("Character::StopMoving^0", (void*)Character_StopMoving); + ccAddExternalFunctionForPlugin("Character::Think^101", (void*)ScPl_Character_Think); + ccAddExternalFunctionForPlugin("Character::Tint^5", (void*)Character_Tint); + ccAddExternalFunctionForPlugin("Character::UnlockView^0", (void*)Character_UnlockView); + ccAddExternalFunctionForPlugin("Character::UnlockView^1", (void*)Character_UnlockViewEx); + ccAddExternalFunctionForPlugin("Character::Walk^4", (void*)Character_Walk); + ccAddExternalFunctionForPlugin("Character::WalkStraight^3", (void*)Character_WalkStraight); + ccAddExternalFunctionForPlugin("Character::GetAtRoomXY^2", (void*)GetCharacterAtRoom); + ccAddExternalFunctionForPlugin("Character::GetAtScreenXY^2", (void*)GetCharacterAtScreen); + ccAddExternalFunctionForPlugin("Character::get_ActiveInventory", (void*)Character_GetActiveInventory); + ccAddExternalFunctionForPlugin("Character::set_ActiveInventory", (void*)Character_SetActiveInventory); + ccAddExternalFunctionForPlugin("Character::get_Animating", (void*)Character_GetAnimating); + ccAddExternalFunctionForPlugin("Character::get_AnimationSpeed", (void*)Character_GetAnimationSpeed); + ccAddExternalFunctionForPlugin("Character::set_AnimationSpeed", (void*)Character_SetAnimationSpeed); + ccAddExternalFunctionForPlugin("Character::get_Baseline", (void*)Character_GetBaseline); + ccAddExternalFunctionForPlugin("Character::set_Baseline", (void*)Character_SetBaseline); + ccAddExternalFunctionForPlugin("Character::get_BlinkInterval", (void*)Character_GetBlinkInterval); + ccAddExternalFunctionForPlugin("Character::set_BlinkInterval", (void*)Character_SetBlinkInterval); + ccAddExternalFunctionForPlugin("Character::get_BlinkView", (void*)Character_GetBlinkView); + ccAddExternalFunctionForPlugin("Character::set_BlinkView", (void*)Character_SetBlinkView); + ccAddExternalFunctionForPlugin("Character::get_BlinkWhileThinking", (void*)Character_GetBlinkWhileThinking); + ccAddExternalFunctionForPlugin("Character::set_BlinkWhileThinking", (void*)Character_SetBlinkWhileThinking); + ccAddExternalFunctionForPlugin("Character::get_BlockingHeight", (void*)Character_GetBlockingHeight); + ccAddExternalFunctionForPlugin("Character::set_BlockingHeight", (void*)Character_SetBlockingHeight); + ccAddExternalFunctionForPlugin("Character::get_BlockingWidth", (void*)Character_GetBlockingWidth); + ccAddExternalFunctionForPlugin("Character::set_BlockingWidth", (void*)Character_SetBlockingWidth); + ccAddExternalFunctionForPlugin("Character::get_Clickable", (void*)Character_GetClickable); + ccAddExternalFunctionForPlugin("Character::set_Clickable", (void*)Character_SetClickable); + ccAddExternalFunctionForPlugin("Character::get_DestinationX", (void*)Character_GetDestinationX); + ccAddExternalFunctionForPlugin("Character::get_DestinationY", (void*)Character_GetDestinationY); + ccAddExternalFunctionForPlugin("Character::get_DiagonalLoops", (void*)Character_GetDiagonalWalking); + ccAddExternalFunctionForPlugin("Character::set_DiagonalLoops", (void*)Character_SetDiagonalWalking); + ccAddExternalFunctionForPlugin("Character::get_Frame", (void*)Character_GetFrame); + ccAddExternalFunctionForPlugin("Character::set_Frame", (void*)Character_SetFrame); + if (base_api < kScriptAPI_v341) + ccAddExternalFunctionForPlugin("Character::get_HasExplicitTint", (void*)Character_GetHasExplicitTint_Old); + else + ccAddExternalFunctionForPlugin("Character::get_HasExplicitTint", (void*)Character_GetHasExplicitTint); + ccAddExternalFunctionForPlugin("Character::get_ID", (void*)Character_GetID); + ccAddExternalFunctionForPlugin("Character::get_IdleView", (void*)Character_GetIdleView); + ccAddExternalFunctionForPlugin("Character::geti_InventoryQuantity", (void*)Character_GetIInventoryQuantity); + ccAddExternalFunctionForPlugin("Character::seti_InventoryQuantity", (void*)Character_SetIInventoryQuantity); + ccAddExternalFunctionForPlugin("Character::get_IgnoreLighting", (void*)Character_GetIgnoreLighting); + ccAddExternalFunctionForPlugin("Character::set_IgnoreLighting", (void*)Character_SetIgnoreLighting); + ccAddExternalFunctionForPlugin("Character::get_IgnoreScaling", (void*)Character_GetIgnoreScaling); + ccAddExternalFunctionForPlugin("Character::set_IgnoreScaling", (void*)Character_SetIgnoreScaling); + ccAddExternalFunctionForPlugin("Character::get_IgnoreWalkbehinds", (void*)Character_GetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Character::set_IgnoreWalkbehinds", (void*)Character_SetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Character::get_Loop", (void*)Character_GetLoop); + ccAddExternalFunctionForPlugin("Character::set_Loop", (void*)Character_SetLoop); + ccAddExternalFunctionForPlugin("Character::get_ManualScaling", (void*)Character_GetIgnoreScaling); + ccAddExternalFunctionForPlugin("Character::set_ManualScaling", (void*)Character_SetManualScaling); + ccAddExternalFunctionForPlugin("Character::get_MovementLinkedToAnimation",(void*)Character_GetMovementLinkedToAnimation); + ccAddExternalFunctionForPlugin("Character::set_MovementLinkedToAnimation",(void*)Character_SetMovementLinkedToAnimation); + ccAddExternalFunctionForPlugin("Character::get_Moving", (void*)Character_GetMoving); + ccAddExternalFunctionForPlugin("Character::get_Name", (void*)Character_GetName); + ccAddExternalFunctionForPlugin("Character::set_Name", (void*)Character_SetName); + ccAddExternalFunctionForPlugin("Character::get_NormalView", (void*)Character_GetNormalView); + ccAddExternalFunctionForPlugin("Character::get_PreviousRoom", (void*)Character_GetPreviousRoom); + ccAddExternalFunctionForPlugin("Character::get_Room", (void*)Character_GetRoom); + ccAddExternalFunctionForPlugin("Character::get_ScaleMoveSpeed", (void*)Character_GetScaleMoveSpeed); + ccAddExternalFunctionForPlugin("Character::set_ScaleMoveSpeed", (void*)Character_SetScaleMoveSpeed); + ccAddExternalFunctionForPlugin("Character::get_ScaleVolume", (void*)Character_GetScaleVolume); + ccAddExternalFunctionForPlugin("Character::set_ScaleVolume", (void*)Character_SetScaleVolume); + ccAddExternalFunctionForPlugin("Character::get_Scaling", (void*)Character_GetScaling); + ccAddExternalFunctionForPlugin("Character::set_Scaling", (void*)Character_SetScaling); + ccAddExternalFunctionForPlugin("Character::get_Solid", (void*)Character_GetSolid); + ccAddExternalFunctionForPlugin("Character::set_Solid", (void*)Character_SetSolid); + ccAddExternalFunctionForPlugin("Character::get_Speaking", (void*)Character_GetSpeaking); + ccAddExternalFunctionForPlugin("Character::get_SpeakingFrame", (void*)Character_GetSpeakingFrame); + ccAddExternalFunctionForPlugin("Character::get_SpeechAnimationDelay", (void*)GetCharacterSpeechAnimationDelay); + ccAddExternalFunctionForPlugin("Character::set_SpeechAnimationDelay", (void*)Character_SetSpeechAnimationDelay); + ccAddExternalFunctionForPlugin("Character::get_SpeechColor", (void*)Character_GetSpeechColor); + ccAddExternalFunctionForPlugin("Character::set_SpeechColor", (void*)Character_SetSpeechColor); + ccAddExternalFunctionForPlugin("Character::get_SpeechView", (void*)Character_GetSpeechView); + ccAddExternalFunctionForPlugin("Character::set_SpeechView", (void*)Character_SetSpeechView); + ccAddExternalFunctionForPlugin("Character::get_ThinkView", (void*)Character_GetThinkView); + ccAddExternalFunctionForPlugin("Character::set_ThinkView", (void*)Character_SetThinkView); + ccAddExternalFunctionForPlugin("Character::get_Transparency", (void*)Character_GetTransparency); + ccAddExternalFunctionForPlugin("Character::set_Transparency", (void*)Character_SetTransparency); + ccAddExternalFunctionForPlugin("Character::get_TurnBeforeWalking", (void*)Character_GetTurnBeforeWalking); + ccAddExternalFunctionForPlugin("Character::set_TurnBeforeWalking", (void*)Character_SetTurnBeforeWalking); + ccAddExternalFunctionForPlugin("Character::get_View", (void*)Character_GetView); + ccAddExternalFunctionForPlugin("Character::get_WalkSpeedX", (void*)Character_GetWalkSpeedX); + ccAddExternalFunctionForPlugin("Character::get_WalkSpeedY", (void*)Character_GetWalkSpeedY); + ccAddExternalFunctionForPlugin("Character::get_X", (void*)Character_GetX); + ccAddExternalFunctionForPlugin("Character::set_X", (void*)Character_SetX); + ccAddExternalFunctionForPlugin("Character::get_x", (void*)Character_GetX); + ccAddExternalFunctionForPlugin("Character::set_x", (void*)Character_SetX); + ccAddExternalFunctionForPlugin("Character::get_Y", (void*)Character_GetY); + ccAddExternalFunctionForPlugin("Character::set_Y", (void*)Character_SetY); + ccAddExternalFunctionForPlugin("Character::get_y", (void*)Character_GetY); + ccAddExternalFunctionForPlugin("Character::set_y", (void*)Character_SetY); + ccAddExternalFunctionForPlugin("Character::get_Z", (void*)Character_GetZ); + ccAddExternalFunctionForPlugin("Character::set_Z", (void*)Character_SetZ); + ccAddExternalFunctionForPlugin("Character::get_z", (void*)Character_GetZ); + ccAddExternalFunctionForPlugin("Character::set_z", (void*)Character_SetZ); +} diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h new file mode 100644 index 000000000000..cb678fda3a1b --- /dev/null +++ b/engines/ags/engine/ac/character.h @@ -0,0 +1,219 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__CHARACTER_H +#define __AGS_EE_AC__CHARACTER_H + +#include "ac/characterinfo.h" +#include "ac/characterextras.h" +#include "ac/dynobj/scriptobject.h" +#include "ac/dynobj/scriptinvitem.h" +#include "ac/dynobj/scriptoverlay.h" +#include "game/viewport.h" +#include "util/geometry.h" + +// **** CHARACTER: FUNCTIONS **** + +void Character_AddInventory(CharacterInfo *chaa, ScriptInvItem *invi, int addIndex); +void Character_AddWaypoint(CharacterInfo *chaa, int x, int y); +void Character_Animate(CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction); +void Character_ChangeRoomAutoPosition(CharacterInfo *chaa, int room, int newPos); +void Character_ChangeRoom(CharacterInfo *chaa, int room, int x, int y); +void Character_ChangeRoomSetLoop(CharacterInfo *chaa, int room, int x, int y, int direction); +void Character_ChangeView(CharacterInfo *chap, int vii); +void Character_FaceDirection(CharacterInfo *char1, int direction, int blockingStyle); +void Character_FaceCharacter(CharacterInfo *char1, CharacterInfo *char2, int blockingStyle); +void Character_FaceLocation(CharacterInfo *char1, int xx, int yy, int blockingStyle); +void Character_FaceObject(CharacterInfo *char1, ScriptObject *obj, int blockingStyle); +void Character_FollowCharacter(CharacterInfo *chaa, CharacterInfo *tofollow, int distaway, int eagerness); +int Character_IsCollidingWithChar(CharacterInfo *char1, CharacterInfo *char2); +int Character_IsCollidingWithObject(CharacterInfo *chin, ScriptObject *objid); +bool Character_IsInteractionAvailable(CharacterInfo *cchar, int mood); +void Character_LockView(CharacterInfo *chap, int vii); +void Character_LockViewEx(CharacterInfo *chap, int vii, int stopMoving); +void Character_LockViewAligned(CharacterInfo *chap, int vii, int loop, int align); +void Character_LockViewAlignedEx(CharacterInfo *chap, int vii, int loop, int align, int stopMoving); +void Character_LockViewFrame(CharacterInfo *chaa, int view, int loop, int frame); +void Character_LockViewFrameEx(CharacterInfo *chaa, int view, int loop, int frame, int stopMoving); +void Character_LockViewOffset(CharacterInfo *chap, int vii, int xoffs, int yoffs); +void Character_LockViewOffsetEx(CharacterInfo *chap, int vii, int xoffs, int yoffs, int stopMoving); +void Character_LoseInventory(CharacterInfo *chap, ScriptInvItem *invi); +void Character_PlaceOnWalkableArea(CharacterInfo *chap); +void Character_RemoveTint(CharacterInfo *chaa); +int Character_GetHasExplicitTint(CharacterInfo *chaa); +void Character_Say(CharacterInfo *chaa, const char *text); +void Character_SayAt(CharacterInfo *chaa, int x, int y, int width, const char *texx); +ScriptOverlay* Character_SayBackground(CharacterInfo *chaa, const char *texx); +void Character_SetAsPlayer(CharacterInfo *chaa); +void Character_SetIdleView(CharacterInfo *chaa, int iview, int itime); +void Character_SetOption(CharacterInfo *chaa, int flag, int yesorno); +void Character_SetSpeed(CharacterInfo *chaa, int xspeed, int yspeed); +void Character_StopMoving(CharacterInfo *charp); +void Character_Tint(CharacterInfo *chaa, int red, int green, int blue, int opacity, int luminance); +void Character_Think(CharacterInfo *chaa, const char *text); +void Character_UnlockView(CharacterInfo *chaa); +void Character_UnlockViewEx(CharacterInfo *chaa, int stopMoving); +void Character_Walk(CharacterInfo *chaa, int x, int y, int blocking, int direct); +void Character_Move(CharacterInfo *chaa, int x, int y, int blocking, int direct); +void Character_WalkStraight(CharacterInfo *chaa, int xx, int yy, int blocking); + +void Character_RunInteraction(CharacterInfo *chaa, int mood); + +// **** CHARACTER: PROPERTIES **** + +int Character_GetProperty(CharacterInfo *chaa, const char *property); +void Character_GetPropertyText(CharacterInfo *chaa, const char *property, char *bufer); +const char* Character_GetTextProperty(CharacterInfo *chaa, const char *property); + +ScriptInvItem* Character_GetActiveInventory(CharacterInfo *chaa); +void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem* iit); +int Character_GetAnimating(CharacterInfo *chaa); +int Character_GetAnimationSpeed(CharacterInfo *chaa); +void Character_SetAnimationSpeed(CharacterInfo *chaa, int newval); +int Character_GetBaseline(CharacterInfo *chaa); +void Character_SetBaseline(CharacterInfo *chaa, int basel); +int Character_GetBlinkInterval(CharacterInfo *chaa); +void Character_SetBlinkInterval(CharacterInfo *chaa, int interval); +int Character_GetBlinkView(CharacterInfo *chaa); +void Character_SetBlinkView(CharacterInfo *chaa, int vii); +int Character_GetBlinkWhileThinking(CharacterInfo *chaa); +void Character_SetBlinkWhileThinking(CharacterInfo *chaa, int yesOrNo); +int Character_GetBlockingHeight(CharacterInfo *chaa); +void Character_SetBlockingHeight(CharacterInfo *chaa, int hit); +int Character_GetBlockingWidth(CharacterInfo *chaa); +void Character_SetBlockingWidth(CharacterInfo *chaa, int wid); +int Character_GetDiagonalWalking(CharacterInfo *chaa); +void Character_SetDiagonalWalking(CharacterInfo *chaa, int yesorno); +int Character_GetClickable(CharacterInfo *chaa); +void Character_SetClickable(CharacterInfo *chaa, int clik); +int Character_GetID(CharacterInfo *chaa); +int Character_GetFrame(CharacterInfo *chaa); +void Character_SetFrame(CharacterInfo *chaa, int newval); +int Character_GetIdleView(CharacterInfo *chaa); +int Character_GetIInventoryQuantity(CharacterInfo *chaa, int index); +int Character_HasInventory(CharacterInfo *chaa, ScriptInvItem *invi); +void Character_SetIInventoryQuantity(CharacterInfo *chaa, int index, int quant); +int Character_GetIgnoreLighting(CharacterInfo *chaa); +void Character_SetIgnoreLighting(CharacterInfo *chaa, int yesorno); +int Character_GetIgnoreScaling(CharacterInfo *chaa); +void Character_SetIgnoreScaling(CharacterInfo *chaa, int yesorno); +void Character_SetManualScaling(CharacterInfo *chaa, int yesorno); +int Character_GetIgnoreWalkbehinds(CharacterInfo *chaa); +void Character_SetIgnoreWalkbehinds(CharacterInfo *chaa, int yesorno); +int Character_GetMovementLinkedToAnimation(CharacterInfo *chaa); +void Character_SetMovementLinkedToAnimation(CharacterInfo *chaa, int yesorno); +int Character_GetLoop(CharacterInfo *chaa); +void Character_SetLoop(CharacterInfo *chaa, int newval); +int Character_GetMoving(CharacterInfo *chaa); +const char* Character_GetName(CharacterInfo *chaa); +void Character_SetName(CharacterInfo *chaa, const char *newName); +int Character_GetNormalView(CharacterInfo *chaa); +int Character_GetPreviousRoom(CharacterInfo *chaa); +int Character_GetRoom(CharacterInfo *chaa); +int Character_GetScaleMoveSpeed(CharacterInfo *chaa); +void Character_SetScaleMoveSpeed(CharacterInfo *chaa, int yesorno); +int Character_GetScaleVolume(CharacterInfo *chaa); +void Character_SetScaleVolume(CharacterInfo *chaa, int yesorno); +int Character_GetScaling(CharacterInfo *chaa); +void Character_SetScaling(CharacterInfo *chaa, int zoomlevel); +int Character_GetSolid(CharacterInfo *chaa); +void Character_SetSolid(CharacterInfo *chaa, int yesorno); +int Character_GetSpeaking(CharacterInfo *chaa); +int Character_GetSpeechColor(CharacterInfo *chaa); +void Character_SetSpeechColor(CharacterInfo *chaa, int ncol); +void Character_SetSpeechAnimationDelay(CharacterInfo *chaa, int newDelay); +int Character_GetSpeechView(CharacterInfo *chaa); +void Character_SetSpeechView(CharacterInfo *chaa, int vii); +int Character_GetThinkView(CharacterInfo *chaa); +void Character_SetThinkView(CharacterInfo *chaa, int vii); +int Character_GetTransparency(CharacterInfo *chaa); +void Character_SetTransparency(CharacterInfo *chaa, int trans); +int Character_GetTurnBeforeWalking(CharacterInfo *chaa); +void Character_SetTurnBeforeWalking(CharacterInfo *chaa, int yesorno); +int Character_GetView(CharacterInfo *chaa); +int Character_GetWalkSpeedX(CharacterInfo *chaa); +int Character_GetWalkSpeedY(CharacterInfo *chaa); +int Character_GetX(CharacterInfo *chaa); +void Character_SetX(CharacterInfo *chaa, int newval); +int Character_GetY(CharacterInfo *chaa); +void Character_SetY(CharacterInfo *chaa, int newval); +int Character_GetZ(CharacterInfo *chaa); +void Character_SetZ(CharacterInfo *chaa, int newval); +int Character_GetSpeakingFrame(CharacterInfo *chaa); + +//============================================================================= + +struct MoveList; +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; // FIXME later + +void animate_character(CharacterInfo *chap, int loopn,int sppd,int rept, int noidleoverride = 0, int direction = 0, int sframe = 0); +void walk_character(int chac,int tox,int toy,int ignwal, bool autoWalkAnims); +int find_looporder_index (int curloop); +// returns 0 to use diagonal, 1 to not +int useDiagonal (CharacterInfo *char1); +// returns 1 normally, or 0 if they only have horizontal animations +int hasUpDownLoops(CharacterInfo *char1); +void start_character_turning (CharacterInfo *chinf, int useloop, int no_diagonal); +void fix_player_sprite(MoveList*cmls,CharacterInfo*chinf); +// Check whether two characters have walked into each other +int has_hit_another_character(int sourceChar); +int doNextCharMoveStep (CharacterInfo *chi, int &char_index, CharacterExtras *chex); +int find_nearest_walkable_area_within(int *xx, int *yy, int range, int step); +void find_nearest_walkable_area (int *xx, int *yy); +void walk_character(int chac,int tox,int toy,int ignwal, bool autoWalkAnims); +void FindReasonableLoopForCharacter(CharacterInfo *chap); +void walk_or_move_character(CharacterInfo *chaa, int x, int y, int blocking, int direct, bool isWalk); +int is_valid_character(int newchar); +int wantMoveNow (CharacterInfo *chi, CharacterExtras *chex); +void setup_player_character(int charid); +void CheckViewFrameForCharacter(CharacterInfo *chi); +Common::Bitmap *GetCharacterImage(int charid, int *isFlipped); +CharacterInfo *GetCharacterAtScreen(int xx, int yy); +// Get character ID at the given room coordinates +int is_pos_on_character(int xx,int yy); +void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2); +// Check whether the source char has walked onto character ww +int is_char_on_another (int sourceChar, int ww, int*fromxptr, int*cwidptr); +int my_getpixel(Common::Bitmap *blk, int x, int y); +// X and Y co-ordinates must be in 320x200 format +int check_click_on_character(int xx,int yy,int mood); +int is_pos_on_character(int xx,int yy); +void _DisplaySpeechCore(int chid, const char *displbuf); +void _DisplayThoughtCore(int chid, const char *displbuf); +void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int isThought); +int get_character_currently_talking(); +void DisplaySpeech(const char*texx, int aschar); +int update_lip_sync(int talkview, int talkloop, int *talkframeptr); + +// Calculates character's bounding box in room coordinates (takes only in-room transform into account) +// use_frame_0 optionally tells to use frame 0 of current loop instead of current frame. +Rect GetCharacterRoomBBox(int charid, bool use_frame_0 = false); +// Find a closest viewport given character is to. Checks viewports in their order in game's array, +// and returns either first viewport character's bounding box intersects with (or rather with its camera), +// or the one that is least far away from its camera; calculated as a perpendicular distance between two AABBs. +PViewport FindNearestViewport(int charid); + +extern CharacterInfo*playerchar; +extern CharacterExtras *charextra; +extern MoveList *mls; +extern int32_t _sc_PlayerCharPtr; + +// order of loops to turn character in circle from down to down +extern int turnlooporder[8]; + +#endif // __AGS_EE_AC__CHARACTER_H diff --git a/engines/ags/engine/ac/charactercache.h b/engines/ags/engine/ac/charactercache.h new file mode 100644 index 000000000000..f4b5c640120f --- /dev/null +++ b/engines/ags/engine/ac/charactercache.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__CHARACTERCACHE_H +#define __AGS_EE_AC__CHARACTERCACHE_H + +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; // FIXME later + +// stores cached info about the character +struct CharacterCache { + Common::Bitmap *image; + int sppic; + int scaling; + int inUse; + short tintredwas, tintgrnwas, tintbluwas, tintamntwas; + short lightlevwas, tintlightwas; + // no mirroredWas is required, since the code inverts the sprite number +}; + +#endif // __AGS_EE_AC__CHARACTERCACHE_H diff --git a/engines/ags/engine/ac/characterextras.cpp b/engines/ags/engine/ac/characterextras.cpp new file mode 100644 index 000000000000..13c8f8135057 --- /dev/null +++ b/engines/ags/engine/ac/characterextras.cpp @@ -0,0 +1,56 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/characterextras.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +void CharacterExtras::ReadFromFile(Stream *in) +{ + in->ReadArrayOfInt16(invorder, MAX_INVORDER); + invorder_count = in->ReadInt16(); + width = in->ReadInt16(); + height = in->ReadInt16(); + zoom = in->ReadInt16(); + xwas = in->ReadInt16(); + ywas = in->ReadInt16(); + tint_r = in->ReadInt16(); + tint_g = in->ReadInt16(); + tint_b = in->ReadInt16(); + tint_level = in->ReadInt16(); + tint_light = in->ReadInt16(); + process_idle_this_time = in->ReadInt8(); + slow_move_counter = in->ReadInt8(); + animwait = in->ReadInt16(); +} + +void CharacterExtras::WriteToFile(Stream *out) +{ + out->WriteArrayOfInt16(invorder, MAX_INVORDER); + out->WriteInt16(invorder_count); + out->WriteInt16(width); + out->WriteInt16(height); + out->WriteInt16(zoom); + out->WriteInt16(xwas); + out->WriteInt16(ywas); + out->WriteInt16(tint_r); + out->WriteInt16(tint_g); + out->WriteInt16(tint_b); + out->WriteInt16(tint_level); + out->WriteInt16(tint_light); + out->WriteInt8(process_idle_this_time); + out->WriteInt8(slow_move_counter); + out->WriteInt16(animwait); +} diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h new file mode 100644 index 000000000000..2e9d6e6098d2 --- /dev/null +++ b/engines/ags/engine/ac/characterextras.h @@ -0,0 +1,52 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__CHARACTEREXTRAS_H +#define __AGS_EE_AC__CHARACTEREXTRAS_H + +#include "ac/runtime_defines.h" + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +struct CharacterExtras { + // UGLY UGLY UGLY!! The CharacterInfo struct size is fixed because it's + // used in the scripts, therefore overflowing stuff has to go here + short invorder[MAX_INVORDER]; + short invorder_count; + // TODO: implement full AABB and keep updated, so that engine could rely on these cached values all time; + // TODO: consider having both fixed AABB and volatile one that changes with animation frame (unless you change how anims work) + short width; + short height; + short zoom; + short xwas; + short ywas; + short tint_r; + short tint_g; + short tint_b; + short tint_level; + short tint_light; + char process_idle_this_time; + char slow_move_counter; + short animwait; + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); +}; + +#endif // __AGS_EE_AC__CHARACTEREXTRAS_H diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp new file mode 100644 index 000000000000..8f6f1a5a8376 --- /dev/null +++ b/engines/ags/engine/ac/characterinfo_engine.cpp @@ -0,0 +1,508 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/characterinfo.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/character.h" +#include "ac/characterextras.h" +#include "ac/gamestate.h" +#include "ac/global_character.h" +#include "ac/math.h" +#include "ac/viewframe.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "main/maindefines_ex.h" // RETURN_CONTINUE +#include "main/update.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; + +extern ViewStruct*views; +extern GameSetupStruct game; +extern int displayed_room; +extern GameState play; +extern int char_speaking; +extern RoomStruct thisroom; +extern unsigned int loopcounter; + +#define Random __Rand + +int CharacterInfo::get_effective_y() { + return y - z; +} +int CharacterInfo::get_baseline() { + if (baseline < 1) + return y; + return baseline; +} +int CharacterInfo::get_blocking_top() { + if (blocking_height > 0) + return y - blocking_height / 2; + return y - 2; +} +int CharacterInfo::get_blocking_bottom() { + // the blocking_bottom should be 1 less than the top + height + // since the code does <= checks on it rather than < checks + if (blocking_height > 0) + return (y + (blocking_height + 1) / 2) - 1; + return y + 3; +} + +void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, int &numSheep, int *followingAsSheep) +{ + int res; + + if (on != 1) return; + + // walking + res = update_character_walking(chex); + // [IKM] Yes, it should return! upon getting RETURN_CONTINUE here + if (res == RETURN_CONTINUE) { // [IKM] now, this is one of those places... + return; // must be careful not to screw things up + } + + // Make sure it doesn't flash up a blue cup + if (view < 0) ; + else if (loop >= views[view].numLoops) + loop = 0; + + int doing_nothing = 1; + + update_character_moving(char_index, chex, doing_nothing); + + // [IKM] 2012-06-28: + // Character index value is used to set up some variables in there, so I cannot just cease using it + res = update_character_animating(char_index, doing_nothing); + // [IKM] Yes, it should return! upon getting RETURN_CONTINUE here + if (res == RETURN_CONTINUE) { // [IKM] now, this is one of those places... + return; // must be careful not to screw things up + } + + update_character_follower(char_index, numSheep, followingAsSheep, doing_nothing); + + update_character_idle(chex, doing_nothing); + + chex->process_idle_this_time = 0; +} + +void CharacterInfo::UpdateFollowingExactlyCharacter() +{ + x = game.chars[following].x; + y = game.chars[following].y; + z = game.chars[following].z; + room = game.chars[following].room; + prevroom = game.chars[following].prevroom; + + int usebase = game.chars[following].get_baseline(); + + if (flags & CHF_BEHINDSHEPHERD) + baseline = usebase - 1; + else + baseline = usebase + 1; +} + +int CharacterInfo::update_character_walking(CharacterExtras *chex) +{ + if (walking >= TURNING_AROUND) { + // Currently rotating to correct direction + if (walkwait > 0) walkwait--; + else { + // Work out which direction is next + int wantloop = find_looporder_index(loop) + 1; + // going anti-clockwise, take one before instead + if (walking >= TURNING_BACKWARDS) + wantloop -= 2; + while (1) { + if (wantloop >= 8) + wantloop = 0; + if (wantloop < 0) + wantloop = 7; + if ((turnlooporder[wantloop] >= views[view].numLoops) || + (views[view].loops[turnlooporder[wantloop]].numFrames < 1) || + ((turnlooporder[wantloop] >= 4) && ((flags & CHF_NODIAGONAL)!=0))) { + if (walking >= TURNING_BACKWARDS) + wantloop--; + else + wantloop++; + } + else break; + } + loop = turnlooporder[wantloop]; + walking -= TURNING_AROUND; + // if still turning, wait for next frame + if (walking % TURNING_BACKWARDS >= TURNING_AROUND) + walkwait = animspeed; + else + walking = walking % TURNING_BACKWARDS; + chex->animwait = 0; + } + return RETURN_CONTINUE; + //continue; + } + + return 0; +} + +void CharacterInfo::update_character_moving(int &char_index, CharacterExtras *chex, int &doing_nothing) +{ + if ((walking > 0) && (room == displayed_room)) + { + if (walkwait > 0) walkwait--; + else + { + flags &= ~CHF_AWAITINGMOVE; + + // Move the character + int numSteps = wantMoveNow(this, chex); + + if ((numSteps) && (chex->xwas != INVALID_X)) { + // if the zoom level changed mid-move, the walkcounter + // might not have come round properly - so sort it out + x = chex->xwas; + y = chex->ywas; + chex->xwas = INVALID_X; + } + + int oldxp = x, oldyp = y; + + for (int ff = 0; ff < abs(numSteps); ff++) { + if (doNextCharMoveStep (this, char_index, chex)) + break; + if ((walking == 0) || (walking >= TURNING_AROUND)) + break; + } + + if (numSteps < 0) { + // very small scaling, intersperse the movement + // to stop it being jumpy + chex->xwas = x; + chex->ywas = y; + x = ((x) - oldxp) / 2 + oldxp; + y = ((y) - oldyp) / 2 + oldyp; + } + else if (numSteps > 0) + chex->xwas = INVALID_X; + + if ((flags & CHF_ANTIGLIDE) == 0) + walkwaitcounter++; + } + + if (loop >= views[view].numLoops) + quitprintf("Unable to render character %d (%s) because loop %d does not exist in view %d", index_id, name, loop, view + 1); + + // check don't overflow loop + int framesInLoop = views[view].loops[loop].numFrames; + if (frame > framesInLoop) + { + frame = 1; + + if (framesInLoop < 2) + frame = 0; + + if (framesInLoop < 1) + quitprintf("Unable to render character %d (%s) because there are no frames in loop %d", index_id, name, loop); + } + + if (walking<1) { + chex->process_idle_this_time = 1; + doing_nothing=1; + walkwait=0; + chex->animwait = 0; + // use standing pic + Character_StopMoving(this); + frame = 0; + CheckViewFrameForCharacter(this); + } + else if (chex->animwait > 0) chex->animwait--; + else { + if (flags & CHF_ANTIGLIDE) + walkwaitcounter++; + + if ((flags & CHF_MOVENOTWALK) == 0) + { + frame++; + if (frame >= views[view].loops[loop].numFrames) + { + // end of loop, so loop back round skipping the standing frame + frame = 1; + + if (views[view].loops[loop].numFrames < 2) + frame = 0; + } + + chex->animwait = views[view].loops[loop].frames[frame].speed + animspeed; + + if (flags & CHF_ANTIGLIDE) + walkwait = chex->animwait; + else + walkwait = 0; + + CheckViewFrameForCharacter(this); + } + } + doing_nothing = 0; + } +} + +int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) +{ + // not moving, but animating + // idleleft is <0 while idle view is playing (.animating is 0) + if (((animating != 0) || (idleleft < 0)) && + ((walking == 0) || ((flags & CHF_MOVENOTWALK) != 0)) && + (room == displayed_room)) + { + doing_nothing = 0; + // idle anim doesn't count as doing something + if (idleleft < 0) + doing_nothing = 1; + + if (wait>0) wait--; + else if ((char_speaking == aa) && (game.options[OPT_LIPSYNCTEXT] != 0)) { + // currently talking with lip-sync speech + int fraa = frame; + wait = update_lip_sync (view, loop, &fraa) - 1; + // closed mouth at end of sentence + // NOTE: standard lip-sync is synchronized with text timer, not voice file + if (play.speech_in_post_state || + ((play.messagetime >= 0) && (play.messagetime < play.close_mouth_speech_time))) + frame = 0; + + if (frame != fraa) { + frame = fraa; + CheckViewFrameForCharacter(this); + } + + //continue; + return RETURN_CONTINUE; + } + else { + int oldframe = frame; + if (animating & CHANIM_BACKWARDS) { + frame--; + if (frame < 0) { + // if the previous loop is a Run Next Loop one, go back to it + if ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) { + + loop --; + frame = views[view].loops[loop].numFrames - 1; + } + else if (animating & CHANIM_REPEAT) { + + frame = views[view].loops[loop].numFrames - 1; + + while (views[view].loops[loop].RunNextLoop()) { + loop++; + frame = views[view].loops[loop].numFrames - 1; + } + } + else { + frame++; + animating = 0; + } + } + } + else + frame++; + + if ((aa == char_speaking) && + (play.speech_in_post_state || + ((!play.speech_has_voice) && + (play.close_mouth_speech_time > 0) && + (play.messagetime < play.close_mouth_speech_time)))) { + // finished talking - stop animation + animating = 0; + frame = 0; + } + + if (frame >= views[view].loops[loop].numFrames) { + + if (views[view].loops[loop].RunNextLoop()) + { + if (loop+1 >= views[view].numLoops) + quit("!Animating character tried to overrun last loop in view"); + loop++; + frame=0; + } + else if ((animating & CHANIM_REPEAT)==0) { + animating=0; + frame--; + // end of idle anim + if (idleleft < 0) { + // constant anim, reset (need this cos animating==0) + if (idletime == 0) + frame = 0; + // one-off anim, stop + else { + ReleaseCharacterView(aa); + idleleft=idletime; + } + } + } + else { + frame=0; + // if it's a multi-loop animation, go back to start + if (play.no_multiloop_repeat == 0) { + while ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) + loop--; + } + } + } + wait = views[view].loops[loop].frames[frame].speed; + // idle anim doesn't have speed stored cos animating==0 + if (idleleft < 0) + wait += animspeed+5; + else + wait += (animating >> 8) & 0x00ff; + + if (frame != oldframe) + CheckViewFrameForCharacter(this); + } + } + + return 0; +} + +void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *followingAsSheep, int &doing_nothing) +{ + if ((following >= 0) && (followinfo == FOLLOW_ALWAYSONTOP)) { + // an always-on-top follow + if (numSheep >= MAX_SHEEP) + quit("too many sheep"); + followingAsSheep[numSheep] = aa; + numSheep++; + } + // not moving, but should be following another character + else if ((following >= 0) && (doing_nothing == 1)) { + short distaway=(followinfo >> 8) & 0x00ff; + // no character in this room + if ((game.chars[following].on == 0) || (on == 0)) ; + else if (room < 0) { + room ++; + if (room == 0) { + // appear in the new room + room = game.chars[following].room; + x = play.entered_at_x; + y = play.entered_at_y; + } + } + // wait a bit, so we're not constantly walking + else if (Random(100) < (followinfo & 0x00ff)) ; + // the followed character has changed room + else if ((room != game.chars[following].room) + && (game.chars[following].on == 0)) + ; // do nothing if the player isn't visible + else if (room != game.chars[following].room) { + prevroom = room; + room = game.chars[following].room; + + if (room == displayed_room) { + // only move to the room-entered position if coming into + // the current room + if (play.entered_at_x > (thisroom.Width - 8)) { + x = thisroom.Width+8; + y = play.entered_at_y; + } + else if (play.entered_at_x < 8) { + x = -8; + y = play.entered_at_y; + } + else if (play.entered_at_y > (thisroom.Height - 8)) { + y = thisroom.Height+8; + x = play.entered_at_x; + } + else if (play.entered_at_y < thisroom.Edges.Top+8) { + y = thisroom.Edges.Top+1; + x = play.entered_at_x; + } + else { + // not at one of the edges + // delay for a few seconds to let the player move + room = -play.follow_change_room_timer; + } + if (room >= 0) { + walk_character(aa,play.entered_at_x,play.entered_at_y,1, true); + doing_nothing = 0; + } + } + } + else if (room != displayed_room) { + // if the characetr is following another character and + // neither is in the current room, don't try to move + } + else if ((abs(game.chars[following].x - x) > distaway+30) | + (abs(game.chars[following].y - y) > distaway+30) | + ((followinfo & 0x00ff) == 0)) { + // in same room + int goxoffs=(Random(50)-25); + // make sure he's not standing on top of the other man + if (goxoffs < 0) goxoffs-=distaway; + else goxoffs+=distaway; + walk_character(aa,game.chars[following].x + goxoffs, + game.chars[following].y + (Random(50)-25),0, true); + doing_nothing = 0; + } + } +} + +void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_nothing) +{ + // no idle animation, so skip this bit + if (idleview < 1) ; + // currently playing idle anim + else if (idleleft < 0) ; + // not in the current room + else if (room != displayed_room) ; + // they are moving or animating (or the view is locked), so + // reset idle timeout + else if ((doing_nothing == 0) || ((flags & CHF_FIXVIEW) != 0)) + idleleft = idletime; + // count idle time + else if ((loopcounter%40==0) || (chex->process_idle_this_time == 1)) { + idleleft--; + if (idleleft == -1) { + int useloop=loop; + debug_script_log("%s: Now idle (view %d)", scrname, idleview+1); + Character_LockView(this, idleview+1); + // SetCharView resets it to 0 + idleleft = -2; + int maxLoops = views[idleview].numLoops; + // if the char is set to "no diagonal loops", don't try + // to use diagonal idle loops either + if ((maxLoops > 4) && (useDiagonal(this))) + maxLoops = 4; + // If it's not a "swimming"-type idleanim, choose a random loop + // if there arent enough loops to do the current one. + if ((idletime > 0) && (useloop >= maxLoops)) { + do { + useloop = rand() % maxLoops; + // don't select a loop which is a continuation of a previous one + } while ((useloop > 0) && (views[idleview].loops[useloop-1].RunNextLoop())); + } + // Normal idle anim - just reset to loop 0 if not enough to + // use the current one + else if (useloop >= maxLoops) + useloop = 0; + + animate_character(this,useloop, + animspeed+5,(idletime == 0) ? 1 : 0, 1); + + // don't set Animating while the idle anim plays + animating = 0; + } + } // end do idle animation +} diff --git a/engines/ags/engine/ac/datetime.cpp b/engines/ags/engine/ac/datetime.cpp new file mode 100644 index 000000000000..d2f8b230b21a --- /dev/null +++ b/engines/ags/engine/ac/datetime.cpp @@ -0,0 +1,141 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/datetime.h" +#include "platform/base/agsplatformdriver.h" +#include "script/runtimescriptvalue.h" + +ScriptDateTime* DateTime_Now_Core() { + ScriptDateTime *sdt = new ScriptDateTime(); + + platform->GetSystemTime(sdt); + + return sdt; +} + +ScriptDateTime* DateTime_Now() { + ScriptDateTime *sdt = DateTime_Now_Core(); + ccRegisterManagedObject(sdt, sdt); + return sdt; +} + +int DateTime_GetYear(ScriptDateTime *sdt) { + return sdt->year; +} + +int DateTime_GetMonth(ScriptDateTime *sdt) { + return sdt->month; +} + +int DateTime_GetDayOfMonth(ScriptDateTime *sdt) { + return sdt->day; +} + +int DateTime_GetHour(ScriptDateTime *sdt) { + return sdt->hour; +} + +int DateTime_GetMinute(ScriptDateTime *sdt) { + return sdt->minute; +} + +int DateTime_GetSecond(ScriptDateTime *sdt) { + return sdt->second; +} + +int DateTime_GetRawTime(ScriptDateTime *sdt) { + return sdt->rawUnixTime; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// ScriptDateTime* () +RuntimeScriptValue Sc_DateTime_Now(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO(ScriptDateTime, DateTime_Now); +} + +// int (ScriptDateTime *sdt) +RuntimeScriptValue Sc_DateTime_GetYear(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDateTime, DateTime_GetYear); +} + +// int (ScriptDateTime *sdt) +RuntimeScriptValue Sc_DateTime_GetMonth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDateTime, DateTime_GetMonth); +} + +// int (ScriptDateTime *sdt) +RuntimeScriptValue Sc_DateTime_GetDayOfMonth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDateTime, DateTime_GetDayOfMonth); +} + +// int (ScriptDateTime *sdt) +RuntimeScriptValue Sc_DateTime_GetHour(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDateTime, DateTime_GetHour); +} + +// int (ScriptDateTime *sdt) +RuntimeScriptValue Sc_DateTime_GetMinute(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDateTime, DateTime_GetMinute); +} + +// int (ScriptDateTime *sdt) +RuntimeScriptValue Sc_DateTime_GetSecond(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDateTime, DateTime_GetSecond); +} + +// int (ScriptDateTime *sdt) +RuntimeScriptValue Sc_DateTime_GetRawTime(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDateTime, DateTime_GetRawTime); +} + +void RegisterDateTimeAPI() +{ + ccAddExternalStaticFunction("DateTime::get_Now", Sc_DateTime_Now); + ccAddExternalObjectFunction("DateTime::get_DayOfMonth", Sc_DateTime_GetDayOfMonth); + ccAddExternalObjectFunction("DateTime::get_Hour", Sc_DateTime_GetHour); + ccAddExternalObjectFunction("DateTime::get_Minute", Sc_DateTime_GetMinute); + ccAddExternalObjectFunction("DateTime::get_Month", Sc_DateTime_GetMonth); + ccAddExternalObjectFunction("DateTime::get_RawTime", Sc_DateTime_GetRawTime); + ccAddExternalObjectFunction("DateTime::get_Second", Sc_DateTime_GetSecond); + ccAddExternalObjectFunction("DateTime::get_Year", Sc_DateTime_GetYear); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DateTime::get_Now", (void*)DateTime_Now); + ccAddExternalFunctionForPlugin("DateTime::get_DayOfMonth", (void*)DateTime_GetDayOfMonth); + ccAddExternalFunctionForPlugin("DateTime::get_Hour", (void*)DateTime_GetHour); + ccAddExternalFunctionForPlugin("DateTime::get_Minute", (void*)DateTime_GetMinute); + ccAddExternalFunctionForPlugin("DateTime::get_Month", (void*)DateTime_GetMonth); + ccAddExternalFunctionForPlugin("DateTime::get_RawTime", (void*)DateTime_GetRawTime); + ccAddExternalFunctionForPlugin("DateTime::get_Second", (void*)DateTime_GetSecond); + ccAddExternalFunctionForPlugin("DateTime::get_Year", (void*)DateTime_GetYear); +} diff --git a/engines/ags/engine/ac/datetime.h b/engines/ags/engine/ac/datetime.h new file mode 100644 index 000000000000..76d474ee0062 --- /dev/null +++ b/engines/ags/engine/ac/datetime.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__DATETIME_H +#define __AGS_EE_AC__DATETIME_H + +#include "ac/dynobj/scriptdatetime.h" + +ScriptDateTime* DateTime_Now_Core(); +ScriptDateTime* DateTime_Now(); +int DateTime_GetYear(ScriptDateTime *sdt); +int DateTime_GetMonth(ScriptDateTime *sdt); +int DateTime_GetDayOfMonth(ScriptDateTime *sdt); +int DateTime_GetHour(ScriptDateTime *sdt); +int DateTime_GetMinute(ScriptDateTime *sdt); +int DateTime_GetSecond(ScriptDateTime *sdt); +int DateTime_GetRawTime(ScriptDateTime *sdt); + +#endif // __AGS_EE_AC__DATETIME_H diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp new file mode 100644 index 000000000000..d27fe02f9425 --- /dev/null +++ b/engines/ags/engine/ac/dialog.cpp @@ -0,0 +1,1324 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dialog.h" +#include "ac/common.h" +#include "ac/character.h" +#include "ac/characterinfo.h" +#include "ac/dialogtopic.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/gamestate.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_character.h" +#include "ac/global_dialog.h" +#include "ac/global_display.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/global_room.h" +#include "ac/global_translation.h" +#include "ac/keycode.h" +#include "ac/overlay.h" +#include "ac/mouse.h" +#include "ac/parser.h" +#include "ac/sys_events.h" +#include "ac/string.h" +#include "ac/dynobj/scriptdialogoptionsrendering.h" +#include "ac/dynobj/scriptdrawingsurface.h" +#include "ac/system.h" +#include "debug/debug_log.h" +#include "font/fonts.h" +#include "script/cc_instance.h" +#include "gui/guimain.h" +#include "gui/guitextbox.h" +#include "main/game_run.h" +#include "platform/base/agsplatformdriver.h" +#include "script/script.h" +#include "ac/spritecache.h" +#include "gfx/ddb.h" +#include "gfx/gfx_util.h" +#include "gfx/graphicsdriver.h" +#include "ac/mouse.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern GameState play; +extern ccInstance *dialogScriptsInst; +extern int in_new_room; +extern CharacterInfo*playerchar; +extern SpriteCache spriteset; +extern AGSPlatformDriver *platform; +extern int cur_mode,cur_cursor; +extern IGraphicsDriver *gfxDriver; + +DialogTopic *dialog; +ScriptDialogOptionsRendering ccDialogOptionsRendering; +ScriptDrawingSurface* dialogOptionsRenderingSurface; + +int said_speech_line; // used while in dialog to track whether screen needs updating + +// Old dialog support +std::vector< std::shared_ptr > old_dialog_scripts; +std::vector old_speech_lines; + +int said_text = 0; +int longestline = 0; + + + + +void Dialog_Start(ScriptDialog *sd) { + RunDialog(sd->id); +} + +#define CHOSE_TEXTPARSER -3053 +#define SAYCHOSEN_USEFLAG 1 +#define SAYCHOSEN_YES 2 +#define SAYCHOSEN_NO 3 + +int Dialog_DisplayOptions(ScriptDialog *sd, int sayChosenOption) +{ + if ((sayChosenOption < 1) || (sayChosenOption > 3)) + quit("!Dialog.DisplayOptions: invalid parameter passed"); + + int chose = show_dialog_options(sd->id, sayChosenOption, (game.options[OPT_RUNGAMEDLGOPTS] != 0)); + if (chose != CHOSE_TEXTPARSER) + { + chose++; + } + return chose; +} + +void Dialog_SetOptionState(ScriptDialog *sd, int option, int newState) { + SetDialogOption(sd->id, option, newState); +} + +int Dialog_GetOptionState(ScriptDialog *sd, int option) { + return GetDialogOption(sd->id, option); +} + +int Dialog_HasOptionBeenChosen(ScriptDialog *sd, int option) +{ + if ((option < 1) || (option > dialog[sd->id].numoptions)) + quit("!Dialog.HasOptionBeenChosen: Invalid option number specified"); + option--; + + if (dialog[sd->id].optionflags[option] & DFLG_HASBEENCHOSEN) + return 1; + return 0; +} + +void Dialog_SetHasOptionBeenChosen(ScriptDialog *sd, int option, bool chosen) +{ + if (option < 1 || option > dialog[sd->id].numoptions) + { + quit("!Dialog.HasOptionBeenChosen: Invalid option number specified"); + } + option--; + if (chosen) + { + dialog[sd->id].optionflags[option] |= DFLG_HASBEENCHOSEN; + } + else + { + dialog[sd->id].optionflags[option] &= ~DFLG_HASBEENCHOSEN; + } +} + +int Dialog_GetOptionCount(ScriptDialog *sd) +{ + return dialog[sd->id].numoptions; +} + +int Dialog_GetShowTextParser(ScriptDialog *sd) +{ + return (dialog[sd->id].topicFlags & DTFLG_SHOWPARSER) ? 1 : 0; +} + +const char* Dialog_GetOptionText(ScriptDialog *sd, int option) +{ + if ((option < 1) || (option > dialog[sd->id].numoptions)) + quit("!Dialog.GetOptionText: Invalid option number specified"); + + option--; + + return CreateNewScriptString(get_translation(dialog[sd->id].optionnames[option])); +} + +int Dialog_GetID(ScriptDialog *sd) { + return sd->id; +} + +//============================================================================= + +#define RUN_DIALOG_STAY -1 +#define RUN_DIALOG_STOP_DIALOG -2 +#define RUN_DIALOG_GOTO_PREVIOUS -4 +// dialog manager stuff + +void get_dialog_script_parameters(unsigned char* &script, unsigned short* param1, unsigned short* param2) +{ + script++; + *param1 = *script; + script++; + *param1 += *script * 256; + script++; + + if (param2) + { + *param2 = *script; + script++; + *param2 += *script * 256; + script++; + } +} + +int run_dialog_script(DialogTopic*dtpp, int dialogID, int offse, int optionIndex) { + said_speech_line = 0; + int result = RUN_DIALOG_STAY; + + if (dialogScriptsInst) + { + char funcName[100]; + sprintf(funcName, "_run_dialog%d", dialogID); + RunTextScriptIParam(dialogScriptsInst, funcName, RuntimeScriptValue().SetInt32(optionIndex)); + result = dialogScriptsInst->returnValue; + } + else + { + // old dialog format + if (offse == -1) + return result; + + unsigned char* script = old_dialog_scripts[dialogID].get() + offse; + + unsigned short param1 = 0; + unsigned short param2 = 0; + bool script_running = true; + + while (script_running) + { + switch (*script) + { + case DCMD_SAY: + get_dialog_script_parameters(script, ¶m1, ¶m2); + + if (param1 == DCHAR_PLAYER) + param1 = game.playercharacter; + + if (param1 == DCHAR_NARRATOR) + Display(get_translation(old_speech_lines[param2])); + else + DisplaySpeech(get_translation(old_speech_lines[param2]), param1); + + said_speech_line = 1; + break; + + case DCMD_OPTOFF: + get_dialog_script_parameters(script, ¶m1, nullptr); + SetDialogOption(dialogID, param1 + 1, 0, true); + break; + + case DCMD_OPTON: + get_dialog_script_parameters(script, ¶m1, nullptr); + SetDialogOption(dialogID, param1 + 1, DFLG_ON, true); + break; + + case DCMD_RETURN: + script_running = false; + break; + + case DCMD_STOPDIALOG: + result = RUN_DIALOG_STOP_DIALOG; + script_running = false; + break; + + case DCMD_OPTOFFFOREVER: + get_dialog_script_parameters(script, ¶m1, nullptr); + SetDialogOption(dialogID, param1 + 1, DFLG_OFFPERM, true); + break; + + case DCMD_RUNTEXTSCRIPT: + get_dialog_script_parameters(script, ¶m1, nullptr); + result = run_dialog_request(param1); + script_running = (result == RUN_DIALOG_STAY); + break; + + case DCMD_GOTODIALOG: + get_dialog_script_parameters(script, ¶m1, nullptr); + result = param1; + script_running = false; + break; + + case DCMD_PLAYSOUND: + get_dialog_script_parameters(script, ¶m1, nullptr); + play_sound(param1); + break; + + case DCMD_ADDINV: + get_dialog_script_parameters(script, ¶m1, nullptr); + add_inventory(param1); + break; + + case DCMD_SETSPCHVIEW: + get_dialog_script_parameters(script, ¶m1, ¶m2); + SetCharacterSpeechView(param1, param2); + break; + + case DCMD_NEWROOM: + get_dialog_script_parameters(script, ¶m1, nullptr); + NewRoom(param1); + in_new_room = 1; + result = RUN_DIALOG_STOP_DIALOG; + script_running = false; + break; + + case DCMD_SETGLOBALINT: + get_dialog_script_parameters(script, ¶m1, ¶m2); + SetGlobalInt(param1, param2); + break; + + case DCMD_GIVESCORE: + get_dialog_script_parameters(script, ¶m1, nullptr); + GiveScore(param1); + break; + + case DCMD_GOTOPREVIOUS: + result = RUN_DIALOG_GOTO_PREVIOUS; + script_running = false; + break; + + case DCMD_LOSEINV: + get_dialog_script_parameters(script, ¶m1, nullptr); + lose_inventory(param1); + break; + + case DCMD_ENDSCRIPT: + result = RUN_DIALOG_STOP_DIALOG; + script_running = false; + break; + } + } + } + + if (in_new_room > 0) + return RUN_DIALOG_STOP_DIALOG; + + if (said_speech_line > 0) { + // the line below fixes the problem with the close-up face remaining on the + // screen after they finish talking; however, it makes the dialog options + // area flicker when going between topics. + DisableInterface(); + UpdateGameOnce(); // redraw the screen to make sure it looks right + EnableInterface(); + // if we're not about to abort the dialog, switch back to arrow + if (result != RUN_DIALOG_STOP_DIALOG) + set_mouse_cursor(CURS_ARROW); + } + + return result; +} + +int write_dialog_options(Bitmap *ds, bool ds_has_alpha, int dlgxp, int curyp, int numdisp, int mouseison, int areawid, + int bullet_wid, int usingfont, DialogTopic*dtop, char*disporder, short*dispyp, + int linespacing, int utextcol, int padding) { + int ww; + + color_t text_color; + for (ww=0;wwoptionflags[disporder[ww]] & DFLG_HASBEENCHOSEN) && + (play.read_dialog_option_colour >= 0)) { + // 'read' colour + text_color = ds->GetCompatibleColor(play.read_dialog_option_colour); + } + else { + // 'unread' colour + text_color = ds->GetCompatibleColor(playerchar->talkcolor); + } + + if (mouseison==ww) { + if (text_color == ds->GetCompatibleColor(utextcol)) + text_color = ds->GetCompatibleColor(13); // the normal colour is the same as highlight col + else text_color = ds->GetCompatibleColor(utextcol); + } + + break_up_text_into_lines(get_translation(dtop->optionnames[disporder[ww]]), Lines, areawid-(2*padding+2+bullet_wid), usingfont); + dispyp[ww]=curyp; + if (game.dialog_bullet > 0) + { + draw_gui_sprite_v330(ds, game.dialog_bullet, dlgxp, curyp, ds_has_alpha); + } + if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering) { + char tempbfr[20]; + int actualpicwid = 0; + if (game.dialog_bullet > 0) + actualpicwid = game.SpriteInfos[game.dialog_bullet].Width+3; + + sprintf (tempbfr, "%d.", ww + 1); + wouttext_outline (ds, dlgxp + actualpicwid, curyp, usingfont, text_color, tempbfr); + } + for (size_t cc=0;ccoptionnames[disporder[i]]), Lines, areawid-(2*padding+2+bullet_wid), usingfont);\ + needheight += getheightoflines(usingfont, Lines.Count()) + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ + }\ + if (parserInput) needheight += parserInput->Height + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ + } + + +void draw_gui_for_dialog_options(Bitmap *ds, GUIMain *guib, int dlgxp, int dlgyp) { + if (guib->BgColor != 0) { + color_t draw_color = ds->GetCompatibleColor(guib->BgColor); + ds->FillRect(Rect(dlgxp, dlgyp, dlgxp + guib->Width, dlgyp + guib->Height), draw_color); + } + if (guib->BgImage > 0) + GfxUtil::DrawSpriteWithTransparency(ds, spriteset[guib->BgImage], dlgxp, dlgyp); +} + +bool get_custom_dialog_options_dimensions(int dlgnum) +{ + ccDialogOptionsRendering.Reset(); + ccDialogOptionsRendering.dialogID = dlgnum; + + getDialogOptionsDimensionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&getDialogOptionsDimensionsFunc); + + if ((ccDialogOptionsRendering.width > 0) && + (ccDialogOptionsRendering.height > 0)) + { + return true; + } + return false; +} + +#define MAX_TOPIC_HISTORY 50 +#define DLG_OPTION_PARSER 99 + +struct DialogOptions +{ + int dlgnum; + bool runGameLoopsInBackground; + + int dlgxp; + int dlgyp; + int dialog_abs_x; // absolute dialog position on screen + int padding; + int usingfont; + int lineheight; + int linespacing; + int curswas; + int bullet_wid; + int needheight; + IDriverDependantBitmap *ddb; + Bitmap *subBitmap; + GUITextBox *parserInput; + DialogTopic*dtop; + + char disporder[MAXTOPICOPTIONS]; + short dispyp[MAXTOPICOPTIONS]; + + int numdisp; + int chose; + + Bitmap *tempScrn; + int parserActivated; + + int curyp; + bool wantRefresh; + bool usingCustomRendering; + int orixp; + int oriyp; + int areawid; + int is_textwindow; + int dirtyx; + int dirtyy; + int dirtywidth; + int dirtyheight; + + int mouseison; + int mousewason; + + int forecol; + + void Prepare(int _dlgnum, bool _runGameLoopsInBackground); + void Show(); + void Redraw(); + bool Run(); + void Close(); +}; + +void DialogOptions::Prepare(int _dlgnum, bool _runGameLoopsInBackground) +{ + dlgnum = _dlgnum; + runGameLoopsInBackground = _runGameLoopsInBackground; + + dlgyp = get_fixed_pixel_size(160); + usingfont=FONT_NORMAL; + lineheight = getfontheight_outlined(usingfont); + linespacing = getfontspacing_outlined(usingfont); + curswas=cur_cursor; + bullet_wid = 0; + ddb = nullptr; + subBitmap = nullptr; + parserInput = nullptr; + dtop = nullptr; + + if ((dlgnum < 0) || (dlgnum >= game.numdialog)) + quit("!RunDialog: invalid dialog number specified"); + + can_run_delayed_command(); + + play.in_conversation ++; + + update_polled_stuff_if_runtime(); + + if (game.dialog_bullet > 0) + bullet_wid = game.SpriteInfos[game.dialog_bullet].Width+3; + + // numbered options, leave space for the numbers + if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering) + bullet_wid += wgettextwidth_compensate("9. ", usingfont); + + said_text = 0; + + update_polled_stuff_if_runtime(); + + const Rect &ui_view = play.GetUIViewport(); + tempScrn = BitmapHelper::CreateBitmap(ui_view.GetWidth(), ui_view.GetHeight(), game.GetColorDepth()); + + set_mouse_cursor(CURS_ARROW); + + dtop=&dialog[dlgnum]; + + chose=-1; + numdisp=0; + + parserActivated = 0; + if ((dtop->topicFlags & DTFLG_SHOWPARSER) && (play.disable_dialog_parser == 0)) { + parserInput = new GUITextBox(); + parserInput->Height = lineheight + get_fixed_pixel_size(4); + parserInput->SetShowBorder(true); + parserInput->Font = usingfont; + } + + numdisp=0; + for (int i = 0; i < dtop->numoptions; ++i) { + if ((dtop->optionflags[i] & DFLG_ON)==0) continue; + ensure_text_valid_for_font(dtop->optionnames[i], usingfont); + disporder[numdisp]=i; + numdisp++; + } +} + +void DialogOptions::Show() +{ + if (numdisp<1) quit("!DoDialog: all options have been turned off"); + // Don't display the options if there is only one and the parser + // is not enabled. + if (!((numdisp > 1) || (parserInput != nullptr) || (play.show_single_dialog_option))) + { + chose = disporder[0]; // only one choice, so select it + return; + } + + is_textwindow = 0; + forecol = play.dialog_options_highlight_color; + + mouseison=-1; + mousewason=-10; + const Rect &ui_view = play.GetUIViewport(); + dirtyx = 0; + dirtyy = 0; + dirtywidth = ui_view.GetWidth(); + dirtyheight = ui_view.GetHeight(); + usingCustomRendering = false; + + + dlgxp = 1; + if (get_custom_dialog_options_dimensions(dlgnum)) + { + usingCustomRendering = true; + dirtyx = data_to_game_coord(ccDialogOptionsRendering.x); + dirtyy = data_to_game_coord(ccDialogOptionsRendering.y); + dirtywidth = data_to_game_coord(ccDialogOptionsRendering.width); + dirtyheight = data_to_game_coord(ccDialogOptionsRendering.height); + dialog_abs_x = dirtyx; + } + else if (game.options[OPT_DIALOGIFACE] > 0) + { + GUIMain*guib=&guis[game.options[OPT_DIALOGIFACE]]; + if (guib->IsTextWindow()) { + // text-window, so do the QFG4-style speech options + is_textwindow = 1; + forecol = guib->FgColor; + } + else { + dlgxp = guib->X; + dlgyp = guib->Y; + + dirtyx = dlgxp; + dirtyy = dlgyp; + dirtywidth = guib->Width; + dirtyheight = guib->Height; + dialog_abs_x = guib->X; + + areawid=guib->Width - 5; + padding = TEXTWINDOW_PADDING_DEFAULT; + + GET_OPTIONS_HEIGHT + + if (game.options[OPT_DIALOGUPWARDS]) { + // They want the options upwards from the bottom + dlgyp = (guib->Y + guib->Height) - needheight; + } + + } + } + else { + //dlgyp=(play.viewport.GetHeight()-numdisp*txthit)-1; + const Rect &ui_view = play.GetUIViewport(); + areawid= ui_view.GetWidth()-5; + padding = TEXTWINDOW_PADDING_DEFAULT; + GET_OPTIONS_HEIGHT + dlgyp = ui_view.GetHeight() - needheight; + + dirtyx = 0; + dirtyy = dlgyp - 1; + dirtywidth = ui_view.GetWidth(); + dirtyheight = ui_view.GetHeight() - dirtyy; + dialog_abs_x = 0; + } + if (!is_textwindow) + areawid -= data_to_game_coord(play.dialog_options_x) * 2; + + orixp = dlgxp; + oriyp = dlgyp; + wantRefresh = false; + mouseison=-10; + + update_polled_stuff_if_runtime(); + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_ENABLE); + update_polled_stuff_if_runtime(); + + Redraw(); + while(Run()); + + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_DISABLE); +} + +void DialogOptions::Redraw() +{ + wantRefresh = true; + + if (usingCustomRendering) + { + tempScrn = recycle_bitmap(tempScrn, game.GetColorDepth(), + data_to_game_coord(ccDialogOptionsRendering.width), + data_to_game_coord(ccDialogOptionsRendering.height)); + } + + tempScrn->ClearTransparent(); + Bitmap *ds = tempScrn; + + dlgxp = orixp; + dlgyp = oriyp; + const Rect &ui_view = play.GetUIViewport(); + + bool options_surface_has_alpha = false; + + if (usingCustomRendering) + { + ccDialogOptionsRendering.surfaceToRenderTo = dialogOptionsRenderingSurface; + ccDialogOptionsRendering.surfaceAccessed = false; + dialogOptionsRenderingSurface->linkedBitmapOnly = tempScrn; + dialogOptionsRenderingSurface->hasAlphaChannel = ccDialogOptionsRendering.hasAlphaChannel; + options_surface_has_alpha = dialogOptionsRenderingSurface->hasAlphaChannel != 0; + + renderDialogOptionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&renderDialogOptionsFunc); + + if (!ccDialogOptionsRendering.surfaceAccessed) + debug_script_warn("dialog_options_get_dimensions was implemented, but no dialog_options_render function drew anything to the surface"); + + if (parserInput) + { + parserInput->X = data_to_game_coord(ccDialogOptionsRendering.parserTextboxX); + curyp = data_to_game_coord(ccDialogOptionsRendering.parserTextboxY); + areawid = data_to_game_coord(ccDialogOptionsRendering.parserTextboxWidth); + if (areawid == 0) + areawid = tempScrn->GetWidth(); + } + ccDialogOptionsRendering.needRepaint = false; + } + else if (is_textwindow) { + // text window behind the options + areawid = data_to_game_coord(play.max_dialogoption_width); + int biggest = 0; + padding = guis[game.options[OPT_DIALOGIFACE]].Padding; + for (int i = 0; i < numdisp; ++i) { + break_up_text_into_lines(get_translation(dtop->optionnames[disporder[i]]), Lines, areawid-((2*padding+2)+bullet_wid), usingfont); + if (longestline > biggest) + biggest = longestline; + } + if (biggest < areawid - ((2*padding+6)+bullet_wid)) + areawid = biggest + ((2*padding+6)+bullet_wid); + + if (areawid < data_to_game_coord(play.min_dialogoption_width)) { + areawid = data_to_game_coord(play.min_dialogoption_width); + if (play.min_dialogoption_width > play.max_dialogoption_width) + quit("!game.min_dialogoption_width is larger than game.max_dialogoption_width"); + } + + GET_OPTIONS_HEIGHT + + int savedwid = areawid; + int txoffs=0,tyoffs=0,yspos = ui_view.GetHeight()/2-(2*padding+needheight)/2; + int xspos = ui_view.GetWidth()/2 - areawid/2; + // shift window to the right if QG4-style full-screen pic + if ((game.options[OPT_SPEECHTYPE] == 3) && (said_text > 0)) + xspos = (ui_view.GetWidth() - areawid) - get_fixed_pixel_size(10); + + // needs to draw the right text window, not the default + Bitmap *text_window_ds = nullptr; + draw_text_window(&text_window_ds, false, &txoffs,&tyoffs,&xspos,&yspos,&areawid,nullptr,needheight, game.options[OPT_DIALOGIFACE]); + options_surface_has_alpha = guis[game.options[OPT_DIALOGIFACE]].HasAlphaChannel(); + // since draw_text_window incrases the width, restore it + areawid = savedwid; + + dirtyx = xspos; + dirtyy = yspos; + dirtywidth = text_window_ds->GetWidth(); + dirtyheight = text_window_ds->GetHeight(); + dialog_abs_x = txoffs + xspos; + + GfxUtil::DrawSpriteWithTransparency(ds, text_window_ds, xspos, yspos); + // TODO: here we rely on draw_text_window always assigning new bitmap to text_window_ds; + // should make this more explicit + delete text_window_ds; + + // Ignore the dialog_options_x/y offsets when using a text window + txoffs += xspos; + tyoffs += yspos; + dlgyp = tyoffs; + curyp = write_dialog_options(ds, options_surface_has_alpha, txoffs,tyoffs,numdisp,mouseison,areawid,bullet_wid,usingfont,dtop,disporder,dispyp,linespacing,forecol,padding); + if (parserInput) + parserInput->X = txoffs; + } + else { + + if (wantRefresh) { + // redraw the black background so that anti-alias + // fonts don't re-alias themselves + if (game.options[OPT_DIALOGIFACE] == 0) { + color_t draw_color = ds->GetCompatibleColor(16); + ds->FillRect(Rect(0,dlgyp-1, ui_view.GetWidth()-1, ui_view.GetHeight()-1), draw_color); + } + else { + GUIMain* guib = &guis[game.options[OPT_DIALOGIFACE]]; + if (!guib->IsTextWindow()) + draw_gui_for_dialog_options(ds, guib, dlgxp, dlgyp); + } + } + + dirtyx = 0; + dirtywidth = ui_view.GetWidth(); + + if (game.options[OPT_DIALOGIFACE] > 0) + { + // the whole GUI area should be marked dirty in order + // to ensure it gets drawn + GUIMain* guib = &guis[game.options[OPT_DIALOGIFACE]]; + dirtyheight = guib->Height; + dirtyy = dlgyp; + options_surface_has_alpha = guib->HasAlphaChannel(); + } + else + { + dirtyy = dlgyp - 1; + dirtyheight = needheight + 1; + options_surface_has_alpha = false; + } + + dlgxp += data_to_game_coord(play.dialog_options_x); + dlgyp += data_to_game_coord(play.dialog_options_y); + + // if they use a negative dialog_options_y, make sure the + // area gets marked as dirty + if (dlgyp < dirtyy) + dirtyy = dlgyp; + + //curyp = dlgyp + 1; + curyp = dlgyp; + curyp = write_dialog_options(ds, options_surface_has_alpha, dlgxp,curyp,numdisp,mouseison,areawid,bullet_wid,usingfont,dtop,disporder,dispyp,linespacing,forecol,padding); + + /*if (curyp > play.viewport.GetHeight()) { + dlgyp = play.viewport.GetHeight() - (curyp - dlgyp); + ds->FillRect(Rect(0,dlgyp-1,play.viewport.GetWidth()-1,play.viewport.GetHeight()-1); + goto redraw_options; + }*/ + if (parserInput) + parserInput->X = dlgxp; + } + + if (parserInput) { + // Set up the text box, if present + parserInput->Y = curyp + data_to_game_coord(game.options[OPT_DIALOGGAP]); + parserInput->Width = areawid - get_fixed_pixel_size(10); + parserInput->TextColor = playerchar->talkcolor; + if (mouseison == DLG_OPTION_PARSER) + parserInput->TextColor = forecol; + + if (game.dialog_bullet) // the parser X will get moved in a second + { + draw_gui_sprite_v330(ds, game.dialog_bullet, parserInput->X, parserInput->Y, options_surface_has_alpha); + } + + parserInput->Width -= bullet_wid; + parserInput->X += bullet_wid; + + parserInput->Draw(ds); + parserInput->IsActivated = false; + } + + wantRefresh = false; + + update_polled_stuff_if_runtime(); + + subBitmap = recycle_bitmap(subBitmap, tempScrn->GetColorDepth(), dirtywidth, dirtyheight); + subBitmap = ReplaceBitmapWithSupportedFormat(subBitmap); + + update_polled_stuff_if_runtime(); + + if (usingCustomRendering) + { + subBitmap->Blit(tempScrn, 0, 0, 0, 0, tempScrn->GetWidth(), tempScrn->GetHeight()); + invalidate_rect(dirtyx, dirtyy, dirtyx + subBitmap->GetWidth(), dirtyy + subBitmap->GetHeight(), false); + } + else + { + subBitmap->Blit(tempScrn, dirtyx, dirtyy, 0, 0, dirtywidth, dirtyheight); + } + + if ((ddb != nullptr) && + ((ddb->GetWidth() != dirtywidth) || + (ddb->GetHeight() != dirtyheight))) + { + gfxDriver->DestroyDDB(ddb); + ddb = nullptr; + } + + if (ddb == nullptr) + ddb = gfxDriver->CreateDDBFromBitmap(subBitmap, options_surface_has_alpha, false); + else + gfxDriver->UpdateDDBFromBitmap(ddb, subBitmap, options_surface_has_alpha); + + if (runGameLoopsInBackground) + { + render_graphics(ddb, dirtyx, dirtyy); + } +} + +bool DialogOptions::Run() +{ + const bool new_custom_render = usingCustomRendering && game.options[OPT_DIALOGOPTIONSAPI] >= 0; + + if (runGameLoopsInBackground) + { + play.disabled_user_interface++; + UpdateGameOnce(false, ddb, dirtyx, dirtyy); + play.disabled_user_interface--; + } + else + { + update_audio_system_on_game_loop(); + render_graphics(ddb, dirtyx, dirtyy); + } + + if (new_custom_render) + { + runDialogOptionRepExecFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&runDialogOptionRepExecFunc); + } + + int gkey; + if (run_service_key_controls(gkey) && !play.IsIgnoringInput()) { + if (parserInput) { + wantRefresh = true; + // type into the parser + if ((gkey == 361) || ((gkey == ' ') && (strlen(parserInput->Text) == 0))) { + // write previous contents into textbox (F3 or Space when box is empty) + for (unsigned int i = strlen(parserInput->Text); i < strlen(play.lastParserEntry); i++) { + parserInput->OnKeyPress(play.lastParserEntry[i]); + } + //ags_domouse(DOMOUSE_DISABLE); + Redraw(); + return true; // continue running loop + } + else if ((gkey >= 32) || (gkey == 13) || (gkey == 8)) { + parserInput->OnKeyPress(gkey); + if (!parserInput->IsActivated) { + //ags_domouse(DOMOUSE_DISABLE); + Redraw(); + return true; // continue running loop + } + } + } + else if (new_custom_render) + { + runDialogOptionKeyPressHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionKeyPressHandlerFunc.params[1].SetInt32(GetKeyForKeyPressCb(gkey)); + run_function_on_non_blocking_thread(&runDialogOptionKeyPressHandlerFunc); + } + // Allow selection of options by keyboard shortcuts + else if (game.options[OPT_DIALOGNUMBERED] >= kDlgOptKeysOnly && + gkey >= '1' && gkey <= '9') + { + gkey -= '1'; + if (gkey < numdisp) { + chose = disporder[gkey]; + return false; // end dialog options running loop + } + } + } + mousewason=mouseison; + mouseison=-1; + if (new_custom_render); // do not automatically detect option under mouse + else if (usingCustomRendering) + { + if ((mousex >= dirtyx) && (mousey >= dirtyy) && + (mousex < dirtyx + tempScrn->GetWidth()) && + (mousey < dirtyy + tempScrn->GetHeight())) + { + getDialogOptionUnderCursorFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&getDialogOptionUnderCursorFunc); + + if (!getDialogOptionUnderCursorFunc.atLeastOneImplementationExists) + quit("!The script function dialog_options_get_active is not implemented. It must be present to use a custom dialogue system."); + + mouseison = ccDialogOptionsRendering.activeOptionID; + } + else + { + ccDialogOptionsRendering.activeOptionID = -1; + } + } + else if (mousex >= dialog_abs_x && mousex < (dialog_abs_x + areawid) && + mousey >= dlgyp && mousey < curyp) + { + mouseison=numdisp-1; + for (int i = 0; i < numdisp; ++i) { + if (mousey < dispyp[i]) { mouseison=i-1; break; } + } + if ((mouseison<0) | (mouseison>=numdisp)) mouseison=-1; + } + + if (parserInput != nullptr) { + int relativeMousey = mousey; + if (usingCustomRendering) + relativeMousey -= dirtyy; + + if ((relativeMousey > parserInput->Y) && + (relativeMousey < parserInput->Y + parserInput->Height)) + mouseison = DLG_OPTION_PARSER; + + if (parserInput->IsActivated) + parserActivated = 1; + } + + int mouseButtonPressed = NONE; + int mouseWheelTurn = 0; + if (run_service_mb_controls(mouseButtonPressed, mouseWheelTurn) && mouseButtonPressed >= 0 && + !play.IsIgnoringInput()) + { + if (mouseison < 0 && !new_custom_render) + { + if (usingCustomRendering) + { + runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1); + run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); + + if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists) + { + Redraw(); + return true; // continue running loop + } + } + return true; // continue running loop + } + if (mouseison == DLG_OPTION_PARSER) { + // they clicked the text box + parserActivated = 1; + } + else if (new_custom_render) + { + runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1); + run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); + } + else if (usingCustomRendering) + { + chose = mouseison; + return false; // end dialog options running loop + } + else { + chose=disporder[mouseison]; + return false; // end dialog options running loop + } + } + + if (usingCustomRendering) + { + if (mouseWheelTurn != 0) + { + runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionMouseClickHandlerFunc.params[1].SetInt32((mouseWheelTurn < 0) ? 9 : 8); + run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); + + if (!new_custom_render) + { + if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists) + Redraw(); + return true; // continue running loop + } + } + } + + if (parserActivated) { + // They have selected a custom parser-based option + if (!parserInput->Text.IsEmpty() != 0) { + chose = DLG_OPTION_PARSER; + return false; // end dialog options running loop + } + else { + parserActivated = 0; + parserInput->IsActivated = 0; + } + } + if (mousewason != mouseison) { + //ags_domouse(DOMOUSE_DISABLE); + Redraw(); + return true; // continue running loop + } + if (new_custom_render) + { + if (ccDialogOptionsRendering.chosenOptionID >= 0) + { + chose = ccDialogOptionsRendering.chosenOptionID; + ccDialogOptionsRendering.chosenOptionID = -1; + return false; // end dialog options running loop + } + if (ccDialogOptionsRendering.needRepaint) + { + Redraw(); + return true; // continue running loop + } + } + + update_polled_stuff_if_runtime(); + + if (play.fast_forward == 0) + { + WaitForNextFrame(); + } + + return true; // continue running loop +} + +void DialogOptions::Close() +{ + ags_clear_input_buffer(); + invalidate_screen(); + + if (parserActivated) + { + strcpy (play.lastParserEntry, parserInput->Text); + ParseText (parserInput->Text); + chose = CHOSE_TEXTPARSER; + } + + if (parserInput) { + delete parserInput; + parserInput = nullptr; + } + + if (ddb != nullptr) + gfxDriver->DestroyDDB(ddb); + delete subBitmap; + + set_mouse_cursor(curswas); + // In case it's the QFG4 style dialog, remove the black screen + play.in_conversation--; + remove_screen_overlay(OVER_COMPLETE); + + delete tempScrn; +} + +DialogOptions DlgOpt; + +int show_dialog_options(int _dlgnum, int sayChosenOption, bool _runGameLoopsInBackground) +{ + DlgOpt.Prepare(_dlgnum, _runGameLoopsInBackground); + DlgOpt.Show(); + DlgOpt.Close(); + + int dialog_choice = DlgOpt.chose; + if (dialog_choice != CHOSE_TEXTPARSER) + { + DialogTopic *dialog_topic = DlgOpt.dtop; + int &option_flags = dialog_topic->optionflags[dialog_choice]; + const char *option_name = DlgOpt.dtop->optionnames[dialog_choice]; + + option_flags |= DFLG_HASBEENCHOSEN; + bool sayTheOption = false; + if (sayChosenOption == SAYCHOSEN_YES) + { + sayTheOption = true; + } + else if (sayChosenOption == SAYCHOSEN_USEFLAG) + { + sayTheOption = ((option_flags & DFLG_NOREPEAT) == 0); + } + + if (sayTheOption) + DisplaySpeech(get_translation(option_name), game.playercharacter); + } + + return dialog_choice; +} + +void do_conversation(int dlgnum) +{ + EndSkippingUntilCharStops(); + + // AGS 2.x always makes the mouse cursor visible when displaying a dialog. + if (loaded_game_file_version <= kGameVersion_272) + play.mouse_cursor_hidden = 0; + + int dlgnum_was = dlgnum; + int previousTopics[MAX_TOPIC_HISTORY]; + int numPrevTopics = 0; + DialogTopic *dtop = &dialog[dlgnum]; + + // run the startup script + int tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0); + if ((tocar == RUN_DIALOG_STOP_DIALOG) || + (tocar == RUN_DIALOG_GOTO_PREVIOUS)) + { + // 'stop' or 'goto-previous' from first startup script + remove_screen_overlay(OVER_COMPLETE); + play.in_conversation--; + return; + } + else if (tocar >= 0) + dlgnum = tocar; + + while (dlgnum >= 0) + { + if (dlgnum >= game.numdialog) + quit("!RunDialog: invalid dialog number specified"); + + dtop = &dialog[dlgnum]; + + if (dlgnum != dlgnum_was) + { + // dialog topic changed, so play the startup + // script for the new topic + tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0); + dlgnum_was = dlgnum; + if (tocar == RUN_DIALOG_GOTO_PREVIOUS) { + if (numPrevTopics < 1) { + // goto-previous on first topic -- end dialog + tocar = RUN_DIALOG_STOP_DIALOG; + } + else { + tocar = previousTopics[numPrevTopics - 1]; + numPrevTopics--; + } + } + if (tocar == RUN_DIALOG_STOP_DIALOG) + break; + else if (tocar >= 0) { + // save the old topic number in the history + if (numPrevTopics < MAX_TOPIC_HISTORY) { + previousTopics[numPrevTopics] = dlgnum; + numPrevTopics++; + } + dlgnum = tocar; + continue; + } + } + + int chose = show_dialog_options(dlgnum, SAYCHOSEN_USEFLAG, (game.options[OPT_RUNGAMEDLGOPTS] != 0)); + + if (chose == CHOSE_TEXTPARSER) + { + said_speech_line = 0; + + tocar = run_dialog_request(dlgnum); + + if (said_speech_line > 0) { + // fix the problem with the close-up face remaining on screen + DisableInterface(); + UpdateGameOnce(); // redraw the screen to make sure it looks right + EnableInterface(); + set_mouse_cursor(CURS_ARROW); + } + } + else + { + tocar = run_dialog_script(dtop, dlgnum, dtop->entrypoints[chose], chose + 1); + } + + if (tocar == RUN_DIALOG_GOTO_PREVIOUS) { + if (numPrevTopics < 1) { + tocar = RUN_DIALOG_STOP_DIALOG; + } + else { + tocar = previousTopics[numPrevTopics - 1]; + numPrevTopics--; + } + } + if (tocar == RUN_DIALOG_STOP_DIALOG) break; + else if (tocar >= 0) { + // save the old topic number in the history + if (numPrevTopics < MAX_TOPIC_HISTORY) { + previousTopics[numPrevTopics] = dlgnum; + numPrevTopics++; + } + dlgnum = tocar; + } + + } + +} + +// end dialog manager + + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// int (ScriptDialog *sd) +RuntimeScriptValue Sc_Dialog_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialog, Dialog_GetID); +} + +// int (ScriptDialog *sd) +RuntimeScriptValue Sc_Dialog_GetOptionCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialog, Dialog_GetOptionCount); +} + +// int (ScriptDialog *sd) +RuntimeScriptValue Sc_Dialog_GetShowTextParser(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialog, Dialog_GetShowTextParser); +} + +// int (ScriptDialog *sd, int sayChosenOption) +RuntimeScriptValue Sc_Dialog_DisplayOptions(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(ScriptDialog, Dialog_DisplayOptions); +} + +// int (ScriptDialog *sd, int option) +RuntimeScriptValue Sc_Dialog_GetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(ScriptDialog, Dialog_GetOptionState); +} + +// const char* (ScriptDialog *sd, int option) +RuntimeScriptValue Sc_Dialog_GetOptionText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT(ScriptDialog, const char, myScriptStringImpl, Dialog_GetOptionText); +} + +// int (ScriptDialog *sd, int option) +RuntimeScriptValue Sc_Dialog_HasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(ScriptDialog, Dialog_HasOptionBeenChosen); +} + +RuntimeScriptValue Sc_Dialog_SetHasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT_PBOOL(ScriptDialog, Dialog_SetHasOptionBeenChosen); +} + +// void (ScriptDialog *sd, int option, int newState) +RuntimeScriptValue Sc_Dialog_SetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptDialog, Dialog_SetOptionState); +} + +// void (ScriptDialog *sd) +RuntimeScriptValue Sc_Dialog_Start(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptDialog, Dialog_Start); +} + +void RegisterDialogAPI() +{ + ccAddExternalObjectFunction("Dialog::get_ID", Sc_Dialog_GetID); + ccAddExternalObjectFunction("Dialog::get_OptionCount", Sc_Dialog_GetOptionCount); + ccAddExternalObjectFunction("Dialog::get_ShowTextParser", Sc_Dialog_GetShowTextParser); + ccAddExternalObjectFunction("Dialog::DisplayOptions^1", Sc_Dialog_DisplayOptions); + ccAddExternalObjectFunction("Dialog::GetOptionState^1", Sc_Dialog_GetOptionState); + ccAddExternalObjectFunction("Dialog::GetOptionText^1", Sc_Dialog_GetOptionText); + ccAddExternalObjectFunction("Dialog::HasOptionBeenChosen^1", Sc_Dialog_HasOptionBeenChosen); + ccAddExternalObjectFunction("Dialog::SetHasOptionBeenChosen^2", Sc_Dialog_SetHasOptionBeenChosen); + ccAddExternalObjectFunction("Dialog::SetOptionState^2", Sc_Dialog_SetOptionState); + ccAddExternalObjectFunction("Dialog::Start^0", Sc_Dialog_Start); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Dialog::get_ID", (void*)Dialog_GetID); + ccAddExternalFunctionForPlugin("Dialog::get_OptionCount", (void*)Dialog_GetOptionCount); + ccAddExternalFunctionForPlugin("Dialog::get_ShowTextParser", (void*)Dialog_GetShowTextParser); + ccAddExternalFunctionForPlugin("Dialog::DisplayOptions^1", (void*)Dialog_DisplayOptions); + ccAddExternalFunctionForPlugin("Dialog::GetOptionState^1", (void*)Dialog_GetOptionState); + ccAddExternalFunctionForPlugin("Dialog::GetOptionText^1", (void*)Dialog_GetOptionText); + ccAddExternalFunctionForPlugin("Dialog::HasOptionBeenChosen^1", (void*)Dialog_HasOptionBeenChosen); + ccAddExternalFunctionForPlugin("Dialog::SetOptionState^2", (void*)Dialog_SetOptionState); + ccAddExternalFunctionForPlugin("Dialog::Start^0", (void*)Dialog_Start); +} diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h new file mode 100644 index 000000000000..93fcf4868c28 --- /dev/null +++ b/engines/ags/engine/ac/dialog.h @@ -0,0 +1,39 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__DIALOG_H +#define __AGS_EE_AC__DIALOG_H + +#include +#include "ac/dynobj/scriptdialog.h" + +int Dialog_GetID(ScriptDialog *sd); +int Dialog_GetOptionCount(ScriptDialog *sd); +int Dialog_GetShowTextParser(ScriptDialog *sd); +const char* Dialog_GetOptionText(ScriptDialog *sd, int option); +int Dialog_DisplayOptions(ScriptDialog *sd, int sayChosenOption); +int Dialog_GetOptionState(ScriptDialog *sd, int option); +int Dialog_HasOptionBeenChosen(ScriptDialog *sd, int option); +void Dialog_SetOptionState(ScriptDialog *sd, int option, int newState); +void Dialog_Start(ScriptDialog *sd); + +void do_conversation(int dlgnum); +int show_dialog_options(int dlgnum, int sayChosenOption, bool runGameLoopsInBackground) ; + +extern ScriptDialog *scrDialog; + +#endif // __AGS_EE_AC__DIALOG_H diff --git a/engines/ags/engine/ac/dialogoptionsrendering.cpp b/engines/ags/engine/ac/dialogoptionsrendering.cpp new file mode 100644 index 000000000000..08f2e876abff --- /dev/null +++ b/engines/ags/engine/ac/dialogoptionsrendering.cpp @@ -0,0 +1,332 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dialog.h" +#include "ac/dialogtopic.h" +#include "ac/dialogoptionsrendering.h" +#include "ac/gamestructdefines.h" +#include "debug/debug_log.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_dialog.h" + +extern DialogTopic *dialog; +extern CCDialog ccDynamicDialog; + +// ** SCRIPT DIALOGOPTIONSRENDERING OBJECT + +void DialogOptionsRendering_Update(ScriptDialogOptionsRendering *dlgOptRender) +{ + dlgOptRender->needRepaint = true; +} + +bool DialogOptionsRendering_RunActiveOption(ScriptDialogOptionsRendering *dlgOptRender) +{ + dlgOptRender->chosenOptionID = dlgOptRender->activeOptionID; + return dlgOptRender->chosenOptionID >= 0; +} + +int DialogOptionsRendering_GetX(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->x; +} + +void DialogOptionsRendering_SetX(ScriptDialogOptionsRendering *dlgOptRender, int newX) +{ + dlgOptRender->x = newX; +} + +int DialogOptionsRendering_GetY(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->y; +} + +void DialogOptionsRendering_SetY(ScriptDialogOptionsRendering *dlgOptRender, int newY) +{ + dlgOptRender->y = newY; +} + +int DialogOptionsRendering_GetWidth(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->width; +} + +void DialogOptionsRendering_SetWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth) +{ + dlgOptRender->width = newWidth; +} + +int DialogOptionsRendering_GetHeight(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->height; +} + +void DialogOptionsRendering_SetHeight(ScriptDialogOptionsRendering *dlgOptRender, int newHeight) +{ + dlgOptRender->height = newHeight; +} + +int DialogOptionsRendering_GetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->hasAlphaChannel; +} + +void DialogOptionsRendering_SetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender, bool hasAlphaChannel) +{ + dlgOptRender->hasAlphaChannel = hasAlphaChannel; +} + +int DialogOptionsRendering_GetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->parserTextboxX; +} + +void DialogOptionsRendering_SetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender, int newX) +{ + dlgOptRender->parserTextboxX = newX; +} + +int DialogOptionsRendering_GetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->parserTextboxY; +} + +void DialogOptionsRendering_SetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender, int newY) +{ + dlgOptRender->parserTextboxY = newY; +} + +int DialogOptionsRendering_GetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->parserTextboxWidth; +} + +void DialogOptionsRendering_SetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth) +{ + dlgOptRender->parserTextboxWidth = newWidth; +} + +ScriptDialog* DialogOptionsRendering_GetDialogToRender(ScriptDialogOptionsRendering *dlgOptRender) +{ + return &scrDialog[dlgOptRender->dialogID]; +} + +ScriptDrawingSurface* DialogOptionsRendering_GetSurface(ScriptDialogOptionsRendering *dlgOptRender) +{ + dlgOptRender->surfaceAccessed = true; + return dlgOptRender->surfaceToRenderTo; +} + +int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender) +{ + return dlgOptRender->activeOptionID + 1; +} + +void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID) +{ + int optionCount = dialog[scrDialog[dlgOptRender->dialogID].id].numoptions; + if ((activeOptionID < 0) || (activeOptionID > optionCount)) + quitprintf("DialogOptionsRenderingInfo.ActiveOptionID: invalid ID specified for this dialog (specified %d, valid range: 1..%d)", activeOptionID, optionCount); + + if (dlgOptRender->activeOptionID != activeOptionID - 1) + { + dlgOptRender->activeOptionID = activeOptionID - 1; + dlgOptRender->needRepaint = true; + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +RuntimeScriptValue Sc_DialogOptionsRendering_Update(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptDialogOptionsRendering, DialogOptionsRendering_Update); +} + +RuntimeScriptValue Sc_DialogOptionsRendering_RunActiveOption(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(ScriptDialogOptionsRendering, DialogOptionsRendering_RunActiveOption); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetActiveOptionID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetActiveOptionID); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID) +RuntimeScriptValue Sc_DialogOptionsRendering_SetActiveOptionID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetActiveOptionID); +} + +// ScriptDialog* (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetDialogToRender(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptDialogOptionsRendering, ScriptDialog, ccDynamicDialog, DialogOptionsRendering_GetDialogToRender); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetHeight); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int newHeight) +RuntimeScriptValue Sc_DialogOptionsRendering_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetHeight); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxX); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int newX) +RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxX); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxY); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int newY) +RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxY); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxWidth); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int newWidth) +RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxWidth); +} + +// ScriptDrawingSurface* (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJAUTO(ScriptDialogOptionsRendering, ScriptDrawingSurface, DialogOptionsRendering_GetSurface); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetWidth); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int newWidth) +RuntimeScriptValue Sc_DialogOptionsRendering_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetWidth); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetX); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int newX) +RuntimeScriptValue Sc_DialogOptionsRendering_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetX); +} + +// int (ScriptDialogOptionsRendering *dlgOptRender) +RuntimeScriptValue Sc_DialogOptionsRendering_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetY); +} + +// void (ScriptDialogOptionsRendering *dlgOptRender, int newY) +RuntimeScriptValue Sc_DialogOptionsRendering_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetY); +} + +RuntimeScriptValue Sc_DialogOptionsRendering_GetHasAlphaChannel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetHasAlphaChannel); +} + +RuntimeScriptValue Sc_DialogOptionsRendering_SetHasAlphaChannel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PBOOL(ScriptDialogOptionsRendering, DialogOptionsRendering_SetHasAlphaChannel); +} + + +void RegisterDialogOptionsRenderingAPI() +{ + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::Update^0", Sc_DialogOptionsRendering_Update); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::RunActiveOption^0", Sc_DialogOptionsRendering_RunActiveOption); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ActiveOptionID", Sc_DialogOptionsRendering_GetActiveOptionID); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ActiveOptionID", Sc_DialogOptionsRendering_SetActiveOptionID); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_DialogToRender", Sc_DialogOptionsRendering_GetDialogToRender); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Height", Sc_DialogOptionsRendering_GetHeight); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Height", Sc_DialogOptionsRendering_SetHeight); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxX", Sc_DialogOptionsRendering_GetParserTextboxX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxX", Sc_DialogOptionsRendering_SetParserTextboxX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxY", Sc_DialogOptionsRendering_GetParserTextboxY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxY", Sc_DialogOptionsRendering_SetParserTextboxY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxWidth", Sc_DialogOptionsRendering_GetParserTextboxWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxWidth", Sc_DialogOptionsRendering_SetParserTextboxWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Surface", Sc_DialogOptionsRendering_GetSurface); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Width", Sc_DialogOptionsRendering_GetWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Width", Sc_DialogOptionsRendering_SetWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_X", Sc_DialogOptionsRendering_GetX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_X", Sc_DialogOptionsRendering_SetX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Y", Sc_DialogOptionsRendering_GetY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Y", Sc_DialogOptionsRendering_SetY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_HasAlphaChannel", Sc_DialogOptionsRendering_GetHasAlphaChannel); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_HasAlphaChannel", Sc_DialogOptionsRendering_SetHasAlphaChannel); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ActiveOptionID", (void*)DialogOptionsRendering_GetActiveOptionID); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ActiveOptionID", (void*)DialogOptionsRendering_SetActiveOptionID); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_DialogToRender", (void*)DialogOptionsRendering_GetDialogToRender); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Height", (void*)DialogOptionsRendering_GetHeight); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Height", (void*)DialogOptionsRendering_SetHeight); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxX", (void*)DialogOptionsRendering_GetParserTextboxX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxX", (void*)DialogOptionsRendering_SetParserTextboxX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxY", (void*)DialogOptionsRendering_GetParserTextboxY); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxY", (void*)DialogOptionsRendering_SetParserTextboxY); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxWidth", (void*)DialogOptionsRendering_GetParserTextboxWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxWidth", (void*)DialogOptionsRendering_SetParserTextboxWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Surface", (void*)DialogOptionsRendering_GetSurface); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Width", (void*)DialogOptionsRendering_GetWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Width", (void*)DialogOptionsRendering_SetWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_X", (void*)DialogOptionsRendering_GetX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_X", (void*)DialogOptionsRendering_SetX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Y", (void*)DialogOptionsRendering_GetY); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Y", (void*)DialogOptionsRendering_SetY); +} diff --git a/engines/ags/engine/ac/dialogoptionsrendering.h b/engines/ags/engine/ac/dialogoptionsrendering.h new file mode 100644 index 000000000000..f08366df3d95 --- /dev/null +++ b/engines/ags/engine/ac/dialogoptionsrendering.h @@ -0,0 +1,45 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__DIALOGOPTIONSRENDERING_H +#define __AGS_EE_AC__DIALOGOPTIONSRENDERING_H + +#include "ac/dynobj/scriptdialog.h" +#include "ac/dynobj/scriptdialogoptionsrendering.h" + +int DialogOptionsRendering_GetX(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetX(ScriptDialogOptionsRendering *dlgOptRender, int newX); +int DialogOptionsRendering_GetY(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetY(ScriptDialogOptionsRendering *dlgOptRender, int newY); +int DialogOptionsRendering_GetWidth(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth); +int DialogOptionsRendering_GetHeight(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetHeight(ScriptDialogOptionsRendering *dlgOptRender, int newHeight); +int DialogOptionsRendering_GetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender, bool hasAlphaChannel); +int DialogOptionsRendering_GetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender, int newX); +int DialogOptionsRendering_GetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender, int newY); +int DialogOptionsRendering_GetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth); +ScriptDialog* DialogOptionsRendering_GetDialogToRender(ScriptDialogOptionsRendering *dlgOptRender); +ScriptDrawingSurface* DialogOptionsRendering_GetSurface(ScriptDialogOptionsRendering *dlgOptRender); +int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender); +void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID); + +#endif // __AGS_EE_AC__DIALOGOPTIONSRENDERING_H diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp new file mode 100644 index 000000000000..f31db0641400 --- /dev/null +++ b/engines/ags/engine/ac/display.cpp @@ -0,0 +1,832 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include + +#include "ac/display.h" +#include "ac/common.h" +#include "font/agsfontrenderer.h" +#include "font/fonts.h" +#include "ac/character.h" +#include "ac/draw.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/global_game.h" +#include "ac/gui.h" +#include "ac/mouse.h" +#include "ac/overlay.h" +#include "ac/sys_events.h" +#include "ac/screenoverlay.h" +#include "ac/speech.h" +#include "ac/string.h" +#include "ac/system.h" +#include "ac/topbarsettings.h" +#include "debug/debug_log.h" +#include "gfx/blender.h" +#include "gui/guibutton.h" +#include "gui/guimain.h" +#include "main/game_run.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/spritecache.h" +#include "gfx/gfx_util.h" +#include "util/string_utils.h" +#include "ac/mouse.h" +#include "media/audio/audio_system.h" +#include "ac/timer.h" + +using namespace AGS::Common; +using namespace AGS::Common::BitmapHelper; + +extern GameState play; +extern GameSetupStruct game; +extern int longestline; +extern AGSPlatformDriver *platform; +extern int loops_per_character; +extern SpriteCache spriteset; + +int display_message_aschar=0; + + +TopBarSettings topBar; +struct DisplayVars +{ + int lineheight; // font's height of single line + int linespacing; // font's line spacing + int fulltxtheight; // total height of all the text +} disp; + +// Pass yy = -1 to find Y co-ord automatically +// allowShrink = 0 for none, 1 for leftwards, 2 for rightwards +// pass blocking=2 to create permanent overlay +int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int usingfont, int asspch, int isThought, int allowShrink, bool overlayPositionFixed) +{ + const bool use_speech_textwindow = (asspch < 0) && (game.options[OPT_SPEECHTYPE] >= 2); + const bool use_thought_gui = (isThought) && (game.options[OPT_THOUGHTGUI] > 0); + + bool alphaChannel = false; + char todis[STD_BUFFER_SIZE]; + snprintf(todis, STD_BUFFER_SIZE - 1, "%s", text); + int usingGui = -1; + if (use_speech_textwindow) + usingGui = play.speech_textwindow_gui; + else if (use_thought_gui) + usingGui = game.options[OPT_THOUGHTGUI]; + + int padding = get_textwindow_padding(usingGui); + int paddingScaled = get_fixed_pixel_size(padding); + int paddingDoubledScaled = get_fixed_pixel_size(padding * 2); // Just in case screen size does is not neatly divisible by 320x200 + + ensure_text_valid_for_font(todis, usingfont); + break_up_text_into_lines(todis, Lines, wii-2*padding, usingfont); + disp.lineheight = getfontheight_outlined(usingfont); + disp.linespacing= getfontspacing_outlined(usingfont); + disp.fulltxtheight = getheightoflines(usingfont, Lines.Count()); + + // AGS 2.x: If the screen is faded out, fade in again when displaying a message box. + if (!asspch && (loaded_game_file_version <= kGameVersion_272)) + play.screen_is_faded_out = 0; + + // if it's a normal message box and the game was being skipped, + // ensure that the screen is up to date before the message box + // is drawn on top of it + // TODO: is this really necessary anymore? + if ((play.skip_until_char_stops >= 0) && (disp_type == DISPLAYTEXT_MESSAGEBOX)) + render_graphics(); + + EndSkippingUntilCharStops(); + + if (topBar.wantIt) { + // ensure that the window is wide enough to display + // any top bar text + int topBarWid = wgettextwidth_compensate(topBar.text, topBar.font); + topBarWid += data_to_game_coord(play.top_bar_borderwidth + 2) * 2; + if (longestline < topBarWid) + longestline = topBarWid; + // the top bar should behave like DisplaySpeech wrt blocking + disp_type = DISPLAYTEXT_SPEECH; + } + + if (asspch > 0) { + // update the all_buttons_disabled variable in advance + // of the adjust_x/y_for_guis calls + play.disabled_user_interface++; + update_gui_disabled_status(); + play.disabled_user_interface--; + } + + const Rect &ui_view = play.GetUIViewport(); + if (xx == OVR_AUTOPLACE) ; + // centre text in middle of screen + else if (yy<0) yy= ui_view.GetHeight()/2-disp.fulltxtheight/2-padding; + // speech, so it wants to be above the character's head + else if (asspch > 0) { + yy-=disp.fulltxtheight; + if (yy < 5) yy=5; + yy = adjust_y_for_guis (yy); + } + + if (longestline < wii - paddingDoubledScaled) { + // shrink the width of the dialog box to fit the text + int oldWid = wii; + //if ((asspch >= 0) || (allowShrink > 0)) + // If it's not speech, or a shrink is allowed, then shrink it + if ((asspch == 0) || (allowShrink > 0)) + wii = longestline + paddingDoubledScaled; + + // shift the dialog box right to align it, if necessary + if ((allowShrink == 2) && (xx >= 0)) + xx += (oldWid - wii); + } + + if (xx<-1) { + xx=(-xx)-wii/2; + if (xx < 0) + xx = 0; + + xx = adjust_x_for_guis (xx, yy); + + if (xx + wii >= ui_view.GetWidth()) + xx = (ui_view.GetWidth() - wii) - 5; + } + else if (xx<0) xx= ui_view.GetWidth()/2-wii/2; + + int extraHeight = paddingDoubledScaled; + color_t text_color = MakeColor(15); + if (disp_type < DISPLAYTEXT_NORMALOVERLAY) + remove_screen_overlay(OVER_TEXTMSG); // remove any previous blocking texts + + Bitmap *text_window_ds = BitmapHelper::CreateTransparentBitmap((wii > 0) ? wii : 2, disp.fulltxtheight + extraHeight, game.GetColorDepth()); + + // inform draw_text_window to free the old bitmap + const bool wantFreeScreenop = true; + + // + // Creating displayed graphic + // + // may later change if usingGUI, needed to avoid changing original coordinates + int adjustedXX = xx; + int adjustedYY = yy; + + if ((strlen (todis) < 1) || (strcmp (todis, " ") == 0) || (wii == 0)) ; + // if it's an empty speech line, don't draw anything + else if (asspch) { //text_color = ds->GetCompatibleColor(12); + int ttxleft = 0, ttxtop = paddingScaled, oriwid = wii - padding * 2; + int drawBackground = 0; + + if (use_speech_textwindow) { + drawBackground = 1; + } + else if (use_thought_gui) { + // make it treat it as drawing inside a window now + if (asspch > 0) + asspch = -asspch; + drawBackground = 1; + } + + if (drawBackground) + { + draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &ttxleft, &ttxtop, &adjustedXX, &adjustedYY, &wii, &text_color, 0, usingGui); + if (usingGui > 0) + { + alphaChannel = guis[usingGui].HasAlphaChannel(); + } + } + else if ((ShouldAntiAliasText()) && (game.GetColorDepth() >= 24)) + alphaChannel = true; + + for (size_t ee=0;ee= 0) && + ((game.options[OPT_SPEECHTYPE] >= 2) || (isThought))) + text_color = text_window_ds->GetCompatibleColor(guis[usingGui].FgColor); + else + text_color = text_window_ds->GetCompatibleColor(-asspch); + + wouttext_aligned(text_window_ds, ttxleft, ttyp, oriwid, usingfont, text_color, Lines[ee], play.text_align); + } + else { + text_color = text_window_ds->GetCompatibleColor(asspch); + wouttext_aligned(text_window_ds, ttxleft, ttyp, wii, usingfont, text_color, Lines[ee], play.speech_text_align); + } + } + } + else { + int xoffs,yoffs, oriwid = wii - padding * 2; + draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &xoffs,&yoffs,&xx,&yy,&wii,&text_color); + + if (game.options[OPT_TWCUSTOM] > 0) + { + alphaChannel = guis[game.options[OPT_TWCUSTOM]].HasAlphaChannel(); + } + + adjust_y_coordinate_for_text(&yoffs, usingfont); + + for (size_t ee=0;ee= OVER_CUSTOM) ovrtype = disp_type; + + int nse = add_screen_overlay(xx, yy, ovrtype, text_window_ds, adjustedXX - xx, adjustedYY - yy, alphaChannel); + // we should not delete text_window_ds here, because it is now owned by Overlay + + if (disp_type >= DISPLAYTEXT_NORMALOVERLAY) { + return screenover[nse].type; + } + + // + // Wait for the blocking text to timeout or until skipped by another command + // + if (disp_type == DISPLAYTEXT_MESSAGEBOX) { + // If fast-forwarding, then skip immediately + if (play.fast_forward) { + remove_screen_overlay(OVER_TEXTMSG); + play.messagetime=-1; + return 0; + } + + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_ENABLE); + int countdown = GetTextDisplayTime (todis); + int skip_setting = user_to_internal_skip_speech((SkipSpeechStyle)play.skip_display); + // Loop until skipped + while (true) { + update_audio_system_on_game_loop(); + render_graphics(); + int mbut, mwheelz; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) { + check_skip_cutscene_mclick(mbut); + if (play.fast_forward) + break; + if (skip_setting & SKIP_MOUSECLICK && !play.IsIgnoringInput()) + break; + } + int kp; + if (run_service_key_controls(kp)) { + check_skip_cutscene_keypress (kp); + if (play.fast_forward) + break; + if ((skip_setting & SKIP_KEYPRESS) && !play.IsIgnoringInput()) + break; + } + + update_polled_stuff_if_runtime(); + + if (play.fast_forward == 0) + { + WaitForNextFrame(); + } + + countdown--; + + // Special behavior when coupled with a voice-over + if (play.speech_has_voice) { + // extend life of text if the voice hasn't finished yet + if (channel_is_playing(SCHAN_SPEECH) && (play.fast_forward == 0)) { + if (countdown <= 1) + countdown = 1; + } + else // if the voice has finished, remove the speech + countdown = 0; + } + // Test for the timed auto-skip + if ((countdown < 1) && (skip_setting & SKIP_AUTOTIMER)) + { + play.SetIgnoreInput(play.ignore_user_input_after_text_timeout_ms); + break; + } + // if skipping cutscene, don't get stuck on No Auto Remove text boxes + if ((countdown < 1) && (play.fast_forward)) + break; + } + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_DISABLE); + remove_screen_overlay(OVER_TEXTMSG); + invalidate_screen(); + } + else { + // if the speech does not time out, but we are skipping a cutscene, + // allow it to time out + if ((play.messagetime < 0) && (play.fast_forward)) + play.messagetime = 2; + + if (!overlayPositionFixed) + { + screenover[nse].positionRelativeToScreen = false; + VpPoint vpt = play.GetRoomViewport(0)->ScreenToRoom(screenover[nse].x, screenover[nse].y, false); + screenover[nse].x = vpt.first.X; + screenover[nse].y = vpt.first.Y; + } + + GameLoopUntilNoOverlay(); + } + + play.messagetime=-1; + return 0; +} + +void _display_at(int xx, int yy, int wii, const char *text, int disp_type, int asspch, int isThought, int allowShrink, bool overlayPositionFixed) { + int usingfont=FONT_NORMAL; + if (asspch) usingfont=FONT_SPEECH; + // TODO: _display_at may be called from _displayspeech, which can start + // and finalize voice speech on its own. Find out if we really need to + // keep track of this and not just stop voice regardless. + bool need_stop_speech = false; + + EndSkippingUntilCharStops(); + + if (try_auto_play_speech(text, text, play.narrator_speech, true)) + {// TODO: is there any need for this flag? + need_stop_speech = true; + } + _display_main(xx, yy, wii, text, disp_type, usingfont, asspch, isThought, allowShrink, overlayPositionFixed); + + if (need_stop_speech) + stop_voice_speech(); +} + +bool try_auto_play_speech(const char *text, const char *&replace_text, int charid, bool blocking) +{ + const char *src = text; + if (src[0] != '&') + return false; + + int sndid = atoi(&src[1]); + while ((src[0] != ' ') & (src[0] != 0)) src++; + if (src[0] == ' ') src++; + if (sndid <= 0) + quit("DisplaySpeech: auto-voice symbol '&' not followed by valid integer"); + + replace_text = src; // skip voice tag + if (play_voice_speech(charid, sndid)) + { + // if Voice Only, then blank out the text + if (play.want_speech == 2) + replace_text = " "; + return true; + } + return false; +} + +// TODO: refactor this global variable out; currently it is set at the every get_translation call. +// Be careful: a number of Say/Display functions expect it to be set beforehand. +int source_text_length = -1; + +int GetTextDisplayLength(const char *text) +{ + int len = (int)strlen(text); + if ((text[0] == '&') && (play.unfactor_speech_from_textlength != 0)) + { + // if there's an "&12 text" type line, remove "&12 " from the source length + size_t j = 0; + while ((text[j] != ' ') && (text[j] != 0)) + j++; + j++; + len -= j; + } + return len; +} + +int GetTextDisplayTime(const char *text, int canberel) { + int uselen = 0; + auto fpstimer = ::lround(get_current_fps()); + + // if it's background speech, make it stay relative to game speed + if ((canberel == 1) && (play.bgspeech_game_speed == 1)) + fpstimer = 40; + + if (source_text_length >= 0) { + // sync to length of original text, to make sure any animations + // and music sync up correctly + uselen = source_text_length; + source_text_length = -1; + } + else { + uselen = GetTextDisplayLength(text); + } + + if (uselen <= 0) + return 0; + + if (play.text_speed + play.text_speed_modifier <= 0) + quit("!Text speed is zero; unable to display text. Check your game.text_speed settings."); + + // Store how many game loops per character of text + // This is calculated using a hard-coded 15 for the text speed, + // so that it's always the same no matter how fast the user + // can read. + loops_per_character = (((uselen/play.lipsync_speed)+1) * fpstimer) / uselen; + + int textDisplayTimeInMS = ((uselen / (play.text_speed + play.text_speed_modifier)) + 1) * 1000; + if (textDisplayTimeInMS < play.text_min_display_time_ms) + textDisplayTimeInMS = play.text_min_display_time_ms; + + return (textDisplayTimeInMS * fpstimer) / 1000; +} + +bool ShouldAntiAliasText() { + return (game.options[OPT_ANTIALIASFONTS] != 0); +} + +#if defined (AGS_FONTOUTLINE_MOREOPAQUE) +// TODO: was suggested by fernewelten, but it's unclear whether is necessary +// Make semi-transparent bits much more opaque +void wouttextxy_AutoOutline_Semitransparent2Opaque(Bitmap *map) +{ + if (map->GetColorDepth() < 32) + return; // such maps don't feature partial transparency + size_t const width = map->GetWidth(); + size_t const height = map->GetHeight(); + + for (size_t y = 0; y < height; y++) + { + int32 *sc_line = reinterpret_cast(map->GetScanLineForWriting(y)); + for (size_t x = 0; x < width; x++) + { + int32 &px = sc_line[x]; + int const transparency = geta(px); + if (0 < transparency && transparency < 255) + px = makeacol32( + getr32(px), + getg32(px), + getb32(px), + std::min(85 + transparency * 2, 255)); + } + } +} +#endif + +// Draw outline that is calculated from the text font, not derived from an outline font +void wouttextxy_AutoOutline(Bitmap *ds, size_t font, int32_t color, const char *texx, int &xxp, int &yyp) +{ + int const thickness = game.fonts.at(font).AutoOutlineThickness; + auto const style = game.fonts.at(font).AutoOutlineStyle; + if (thickness <= 0) + return; + + // 16-bit games should use 32-bit stencils to keep anti-aliasing working + int const ds_cd = ds->GetColorDepth(); + bool const antialias = ds_cd >= 16 && game.options[OPT_ANTIALIASFONTS] != 0 && !is_bitmap_font(font); + int const stencil_cd = antialias ? 32 : ds_cd; + if (antialias) // This is to make sure TTFs render proper alpha channel in 16-bit games too + color |= makeacol32(0, 0, 0, 0xff); + + size_t const t_width = wgettextwidth(texx, font); + size_t const t_height = wgettextheight(texx, font); + if (t_width == 0 || t_height == 0) + return; + Bitmap texx_stencil, outline_stencil; + texx_stencil.CreateTransparent(t_width, t_height, stencil_cd); + outline_stencil.CreateTransparent(t_width, t_height + 2 * thickness, stencil_cd); + if (outline_stencil.IsNull() || texx_stencil.IsNull()) + return; + wouttextxy(&texx_stencil, 0, 0, font, color, texx); +#if defined (AGS_FONTOUTLINE_MOREOPAQUE) + wouttextxy_AutoOutline_Semitransparent2Opaque(texx_stencil); +#endif + + void(Bitmap::*pfn_drawstencil)(Bitmap *src, int dst_x, int dst_y); + if (antialias) + { // NOTE: we must set out blender AFTER wouttextxy, or it will be overidden + set_argb2any_blender(); + pfn_drawstencil = &Bitmap::TransBlendBlt; + } + else + { + pfn_drawstencil = &Bitmap::MaskedBlit; + } + + // move start of text so that the outline doesn't drop off the bitmap + xxp += thickness; + int const outline_y = yyp; + yyp += thickness; + + int largest_y_diff_reached_so_far = -1; + for (int x_diff = thickness; x_diff >= 0; x_diff--) + { + // Integer arithmetics: In the following, we use terms k*(k + 1) to account for rounding. + // (k + 0.5)^2 == k*k + 2*k*0.5 + 0.5^2 == k*k + k + 0.25 ==approx. k*(k + 1) + int y_term_limit = thickness * (thickness + 1); + if (FontInfo::kRounded == style) + y_term_limit -= x_diff * x_diff; + + // extend the outline stencil to the top and bottom + for (int y_diff = largest_y_diff_reached_so_far + 1; + y_diff <= thickness && y_diff * y_diff <= y_term_limit; + y_diff++) + { + (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness - y_diff); + if (y_diff > 0) + (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness + y_diff); + largest_y_diff_reached_so_far = y_diff; + } + + // stamp the outline stencil to the left and right of the text + (ds->*pfn_drawstencil)(&outline_stencil, xxp - x_diff, outline_y); + if (x_diff > 0) + (ds->*pfn_drawstencil)(&outline_stencil, xxp + x_diff, outline_y); + } +} + +// Draw an outline if requested, then draw the text on top +void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int font, color_t text_color, const char *texx) +{ + size_t const text_font = static_cast(font); + // Draw outline (a backdrop) if requested + color_t const outline_color = ds->GetCompatibleColor(play.speech_text_shadow); + int const outline_font = get_font_outline(font); + if (outline_font >= 0) + wouttextxy(ds, xxp, yyp, static_cast(outline_font), outline_color, texx); + else if (outline_font == FONT_OUTLINE_AUTO) + wouttextxy_AutoOutline(ds, text_font, outline_color, texx, xxp, yyp); + else + ; // no outline + + // Draw text on top + wouttextxy(ds, xxp, yyp, text_font, text_color, texx); +} + +void wouttext_aligned(Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align) { + + if (align & kMAlignHCenter) + usexp = usexp + (oriwid / 2) - (wgettextwidth_compensate(text, usingfont) / 2); + else if (align & kMAlignRight) + usexp = usexp + (oriwid - wgettextwidth_compensate(text, usingfont)); + + wouttext_outline(ds, usexp, yy, usingfont, text_color, (char *)text); +} + +// Get outline's thickness addition to the font's width or height +int get_outline_padding(int font) +{ + if (get_font_outline(font) == FONT_OUTLINE_AUTO) { + return get_font_outline_thickness(font) * 2; + } + return 0; +} + +int getfontheight_outlined(int font) +{ + return getfontheight(font) + get_outline_padding(font); +} + +int getfontspacing_outlined(int font) +{ + return use_default_linespacing(font) ? + getfontheight_outlined(font) : + getfontlinespacing(font); +} + +int getfontlinegap(int font) +{ + return getfontspacing_outlined(font) - getfontheight_outlined(font); +} + +int getheightoflines(int font, int numlines) +{ + return getfontspacing_outlined(font) * (numlines - 1) + getfontheight_outlined(font); +} + +int wgettextwidth_compensate(const char *tex, int font) +{ + return wgettextwidth(tex, font) + get_outline_padding(font); +} + +void do_corner(Bitmap *ds, int sprn, int x, int y, int offx, int offy) { + if (sprn<0) return; + if (spriteset[sprn] == nullptr) + { + sprn = 0; + } + + x = x + offx * game.SpriteInfos[sprn].Width; + y = y + offy * game.SpriteInfos[sprn].Height; + draw_gui_sprite_v330(ds, sprn, x, y); +} + +int get_but_pic(GUIMain*guo,int indx) +{ + int butid = guo->GetControlID(indx); + return butid >= 0 ? guibuts[butid].Image : 0; +} + +void draw_button_background(Bitmap *ds, int xx1,int yy1,int xx2,int yy2,GUIMain*iep) { + color_t draw_color; + if (iep==nullptr) { // standard window + draw_color = ds->GetCompatibleColor(15); + ds->FillRect(Rect(xx1,yy1,xx2,yy2), draw_color); + draw_color = ds->GetCompatibleColor(16); + ds->DrawRect(Rect(xx1,yy1,xx2,yy2), draw_color); + /* draw_color = ds->GetCompatibleColor(opts.tws.backcol); ds->FillRect(Rect(xx1,yy1,xx2,yy2); + draw_color = ds->GetCompatibleColor(opts.tws.ds->GetTextColor()); ds->DrawRect(Rect(xx1+1,yy1+1,xx2-1,yy2-1);*/ + } + else { + if (loaded_game_file_version < kGameVersion_262) // < 2.62 + { + // Color 0 wrongly shows as transparent instead of black + // From the changelog of 2.62: + // - Fixed text windows getting a black background if colour 0 was + // specified, rather than being transparent. + if (iep->BgColor == 0) + iep->BgColor = 16; + } + + if (iep->BgColor >= 0) draw_color = ds->GetCompatibleColor(iep->BgColor); + else draw_color = ds->GetCompatibleColor(0); // black backrgnd behind picture + + if (iep->BgColor > 0) + ds->FillRect(Rect(xx1,yy1,xx2,yy2), draw_color); + + int leftRightWidth = game.SpriteInfos[get_but_pic(iep,4)].Width; + int topBottomHeight = game.SpriteInfos[get_but_pic(iep,6)].Height; + if (iep->BgImage>0) { + if ((loaded_game_file_version <= kGameVersion_272) // 2.xx + && (spriteset[iep->BgImage]->GetWidth() == 1) + && (spriteset[iep->BgImage]->GetHeight() == 1) + && (*((unsigned int*)spriteset[iep->BgImage]->GetData()) == 0x00FF00FF)) + { + // Don't draw fully transparent dummy GUI backgrounds + } + else + { + // offset the background image and clip it so that it is drawn + // such that the border graphics can have a transparent outside + // edge + int bgoffsx = xx1 - leftRightWidth / 2; + int bgoffsy = yy1 - topBottomHeight / 2; + ds->SetClip(Rect(bgoffsx, bgoffsy, xx2 + leftRightWidth / 2, yy2 + topBottomHeight / 2)); + int bgfinishx = xx2; + int bgfinishy = yy2; + int bgoffsyStart = bgoffsy; + while (bgoffsx <= bgfinishx) + { + bgoffsy = bgoffsyStart; + while (bgoffsy <= bgfinishy) + { + draw_gui_sprite_v330(ds, iep->BgImage, bgoffsx, bgoffsy); + bgoffsy += game.SpriteInfos[iep->BgImage].Height; + } + bgoffsx += game.SpriteInfos[iep->BgImage].Width; + } + // return to normal clipping rectangle + ds->SetClip(Rect(0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1)); + } + } + int uu; + for (uu=yy1;uu <= yy2;uu+= game.SpriteInfos[get_but_pic(iep,4)].Height) { + do_corner(ds, get_but_pic(iep,4),xx1,uu,-1,0); // left side + do_corner(ds, get_but_pic(iep,5),xx2+1,uu,0,0); // right side + } + for (uu=xx1;uu <= xx2;uu+=game.SpriteInfos[get_but_pic(iep,6)].Width) { + do_corner(ds, get_but_pic(iep,6),uu,yy1,0,-1); // top side + do_corner(ds, get_but_pic(iep,7),uu,yy2+1,0,0); // bottom side + } + do_corner(ds, get_but_pic(iep,0),xx1,yy1,-1,-1); // top left + do_corner(ds, get_but_pic(iep,1),xx1,yy2+1,-1,0); // bottom left + do_corner(ds, get_but_pic(iep,2),xx2+1,yy1,0,-1); // top right + do_corner(ds, get_but_pic(iep,3),xx2+1,yy2+1,0,0); // bottom right + } +} + +// Calculate the width that the left and right border of the textwindow +// GUI take up +int get_textwindow_border_width (int twgui) { + if (twgui < 0) + return 0; + + if (!guis[twgui].IsTextWindow()) + quit("!GUI set as text window but is not actually a text window GUI"); + + int borwid = game.SpriteInfos[get_but_pic(&guis[twgui], 4)].Width + + game.SpriteInfos[get_but_pic(&guis[twgui], 5)].Width; + + return borwid; +} + +// get the hegiht of the text window's top border +int get_textwindow_top_border_height (int twgui) { + if (twgui < 0) + return 0; + + if (!guis[twgui].IsTextWindow()) + quit("!GUI set as text window but is not actually a text window GUI"); + + return game.SpriteInfos[get_but_pic(&guis[twgui], 6)].Height; +} + +// Get the padding for a text window +// -1 for the game's custom text window +int get_textwindow_padding(int ifnum) { + int result; + + if (ifnum < 0) + ifnum = game.options[OPT_TWCUSTOM]; + if (ifnum > 0 && ifnum < game.numgui) + result = guis[ifnum].Padding; + else + result = TEXTWINDOW_PADDING_DEFAULT; + + return result; +} + +void draw_text_window(Bitmap **text_window_ds, bool should_free_ds, + int*xins,int*yins,int*xx,int*yy,int*wii, color_t *set_text_color, int ovrheight, int ifnum) { + + Bitmap *ds = *text_window_ds; + if (ifnum < 0) + ifnum = game.options[OPT_TWCUSTOM]; + + if (ifnum <= 0) { + if (ovrheight) + quit("!Cannot use QFG4 style options without custom text window"); + draw_button_background(ds, 0,0,ds->GetWidth() - 1,ds->GetHeight() - 1,nullptr); + if (set_text_color) + *set_text_color = ds->GetCompatibleColor(16); + xins[0]=3; + yins[0]=3; + } + else { + if (ifnum >= game.numgui) + quitprintf("!Invalid GUI %d specified as text window (total GUIs: %d)", ifnum, game.numgui); + if (!guis[ifnum].IsTextWindow()) + quit("!GUI set as text window but is not actually a text window GUI"); + + int tbnum = get_but_pic(&guis[ifnum], 0); + + wii[0] += get_textwindow_border_width (ifnum); + xx[0]-=game.SpriteInfos[tbnum].Width; + yy[0]-=game.SpriteInfos[tbnum].Height; + if (ovrheight == 0) + ovrheight = disp.fulltxtheight; + + if (should_free_ds) + delete *text_window_ds; + int padding = get_textwindow_padding(ifnum); + *text_window_ds = BitmapHelper::CreateTransparentBitmap(wii[0],ovrheight+(padding*2)+ game.SpriteInfos[tbnum].Height*2,game.GetColorDepth()); + ds = *text_window_ds; + int xoffs=game.SpriteInfos[tbnum].Width,yoffs= game.SpriteInfos[tbnum].Height; + draw_button_background(ds, xoffs,yoffs,(ds->GetWidth() - xoffs) - 1,(ds->GetHeight() - yoffs) - 1,&guis[ifnum]); + if (set_text_color) + *set_text_color = ds->GetCompatibleColor(guis[ifnum].FgColor); + xins[0]=xoffs+padding; + yins[0]=yoffs+padding; + } +} + +void draw_text_window_and_bar(Bitmap **text_window_ds, bool should_free_ds, + int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight, int ifnum) { + + draw_text_window(text_window_ds, should_free_ds, xins, yins, xx, yy, wii, set_text_color, ovrheight, ifnum); + + if ((topBar.wantIt) && (text_window_ds && *text_window_ds)) { + // top bar on the dialog window with character's name + // create an enlarged window, then free the old one + Bitmap *ds = *text_window_ds; + Bitmap *newScreenop = BitmapHelper::CreateBitmap(ds->GetWidth(), ds->GetHeight() + topBar.height, game.GetColorDepth()); + newScreenop->Blit(ds, 0, 0, 0, topBar.height, ds->GetWidth(), ds->GetHeight()); + delete *text_window_ds; + *text_window_ds = newScreenop; + ds = *text_window_ds; + + // draw the top bar + color_t draw_color = ds->GetCompatibleColor(play.top_bar_backcolor); + ds->FillRect(Rect(0, 0, ds->GetWidth() - 1, topBar.height - 1), draw_color); + if (play.top_bar_backcolor != play.top_bar_bordercolor) { + // draw the border + draw_color = ds->GetCompatibleColor(play.top_bar_bordercolor); + for (int j = 0; j < data_to_game_coord(play.top_bar_borderwidth); j++) + ds->DrawRect(Rect(j, j, ds->GetWidth() - (j + 1), topBar.height - (j + 1)), draw_color); + } + + // draw the text + int textx = (ds->GetWidth() / 2) - wgettextwidth_compensate(topBar.text, topBar.font) / 2; + color_t text_color = ds->GetCompatibleColor(play.top_bar_textcolor); + wouttext_outline(ds, textx, play.top_bar_borderwidth + get_fixed_pixel_size(1), topBar.font, text_color, topBar.text); + + // don't draw it next time + topBar.wantIt = 0; + // adjust the text Y position + yins[0] += topBar.height; + } + else if (topBar.wantIt) + topBar.wantIt = 0; +} diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h new file mode 100644 index 000000000000..68b00bfdad28 --- /dev/null +++ b/engines/ags/engine/ac/display.h @@ -0,0 +1,80 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__DISPLAY_H +#define __AGS_EE_AC__DISPLAY_H + +#include "gui/guimain.h" + +using AGS::Common::GUIMain; + +// options for 'disp_type' parameter +#define DISPLAYTEXT_SPEECH 0 +#define DISPLAYTEXT_MESSAGEBOX 1 +#define DISPLAYTEXT_NORMALOVERLAY 2 +// also accepts explicit overlay ID >= OVER_CUSTOM + +int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int usingfont, int asspch, int isThought, int allowShrink, bool overlayPositionFixed); +void _display_at(int xx, int yy, int wii, const char *text, int disp_type, int asspch, int isThought, int allowShrink, bool overlayPositionFixed); +// Tests the given string for the voice-over tags and plays cue clip for the given character; +// will assign replacement string, which will be blank string if game is in "voice-only" mode +// and clip was started, or string cleaned from voice-over tags which is safe to display on screen. +// Returns whether voice-over clip was started successfully. +bool try_auto_play_speech(const char *text, const char *&replace_text, int charid, bool blocking); +bool ShouldAntiAliasText(); +// Calculates meaningful length of the displayed text +int GetTextDisplayLength(const char *text); +// Calculates number of game loops for displaying a text on screen +int GetTextDisplayTime(const char *text, int canberel = 0); +// Draw an outline if requested, then draw the text on top +void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); +void wouttext_aligned (Common::Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align); +// TODO: GUI classes located in Common library do not make use of outlining, +// need to find a way to make all code use same functions. +// Get the maximal height of the given font, with corresponding outlining +int getfontheight_outlined(int font); +// Get line spacing for the given font, with possible outlining in mind +int getfontspacing_outlined(int font); +// Get the distance between bottom one one line and top of the next line (may be negative!) +int getfontlinegap(int font); +// Gets the total maximal height of the given number of lines printed with the given font +int getheightoflines(int font, int numlines); +// Get the maximal width of the given font, with corresponding outlining +int wgettextwidth_compensate(const char *tex, int font); +void do_corner(Common::Bitmap *ds, int sprn,int xx1,int yy1,int typx,int typy); +// Returns the image of a button control on the GUI under given child index +int get_but_pic(GUIMain*guo,int indx); +void draw_button_background(Common::Bitmap *ds, int xx1,int yy1,int xx2,int yy2,GUIMain*iep); +// Calculate the width that the left and right border of the textwindow +// GUI take up +int get_textwindow_border_width (int twgui); +// get the hegiht of the text window's top border +int get_textwindow_top_border_height (int twgui); +// draw_text_window: draws the normal or custom text window +// create a new bitmap the size of the window before calling, and +// point text_window_ds to it +// returns text start x & y pos in parameters +// Warning!: draw_text_window() and draw_text_window_and_bar() can create new text_window_ds +void draw_text_window(Common::Bitmap **text_window_ds, bool should_free_ds, int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight, int ifnum); +void draw_text_window_and_bar(Common::Bitmap **text_window_ds, bool should_free_ds, + int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight=0, int ifnum=-1); +int get_textwindow_padding(int ifnum); + +// The efficient length of the last source text prepared for display +extern int source_text_length; + +#endif // __AGS_EE_AC__DISPLAY_H diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp new file mode 100644 index 000000000000..fe24f1c4534f --- /dev/null +++ b/engines/ags/engine/ac/draw.cpp @@ -0,0 +1,2563 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "aastr.h" +#include "core/platform.h" +#include "ac/common.h" +#include "util/compress.h" +#include "ac/view.h" +#include "ac/charactercache.h" +#include "ac/characterextras.h" +#include "ac/characterinfo.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/draw_software.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/global_region.h" +#include "ac/gui.h" +#include "ac/mouse.h" +#include "ac/objectcache.h" +#include "ac/overlay.h" +#include "ac/sys_events.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "ac/runtime_defines.h" +#include "ac/screenoverlay.h" +#include "ac/sprite.h" +#include "ac/spritelistentry.h" +#include "ac/string.h" +#include "ac/system.h" +#include "ac/viewframe.h" +#include "ac/walkablearea.h" +#include "ac/walkbehind.h" +#include "ac/dynobj/scriptsystem.h" +#include "debug/debugger.h" +#include "debug/debug_log.h" +#include "font/fonts.h" +#include "gui/guimain.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "ac/spritecache.h" +#include "gfx/gfx_util.h" +#include "gfx/graphicsdriver.h" +#include "gfx/ali3dexception.h" +#include "gfx/blender.h" +#include "media/audio/audio_system.h" +#include "ac/game.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +#if AGS_PLATFORM_OS_ANDROID +#include +#include + +extern "C" void android_render(); +#endif + +#if AGS_PLATFORM_OS_IOS +extern "C" void ios_render(); +#endif + +extern GameSetup usetup; +extern GameSetupStruct game; +extern GameState play; +extern int convert_16bit_bgr; +extern ScriptSystem scsystem; +extern AGSPlatformDriver *platform; +extern RoomStruct thisroom; +extern char noWalkBehindsAtAll; +extern unsigned int loopcounter; +extern char *walkBehindExists; // whether a WB area is in this column +extern int *walkBehindStartY, *walkBehindEndY; +extern int walkBehindLeft[MAX_WALK_BEHINDS], walkBehindTop[MAX_WALK_BEHINDS]; +extern int walkBehindRight[MAX_WALK_BEHINDS], walkBehindBottom[MAX_WALK_BEHINDS]; +extern IDriverDependantBitmap *walkBehindBitmap[MAX_WALK_BEHINDS]; +extern int walkBehindsCachedForBgNum; +extern WalkBehindMethodEnum walkBehindMethod; +extern int walk_behind_baselines_changed; +extern SpriteCache spriteset; +extern RoomStatus*croom; +extern int our_eip; +extern int in_new_room; +extern RoomObject*objs; +extern ViewStruct*views; +extern CharacterCache *charcache; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; +extern int displayed_room; +extern CharacterExtras *charextra; +extern CharacterInfo*playerchar; +extern int eip_guinum; +extern int is_complete_overlay; +extern int cur_mode,cur_cursor; +extern int mouse_frame,mouse_delay; +extern int lastmx,lastmy; +extern IDriverDependantBitmap *mouseCursor; +extern int hotx,hoty; +extern int bg_just_changed; + +color palette[256]; + +COLOR_MAP maincoltable; + +IGraphicsDriver *gfxDriver; +IDriverDependantBitmap *blankImage = nullptr; +IDriverDependantBitmap *blankSidebarImage = nullptr; +IDriverDependantBitmap *debugConsole = nullptr; + +// actsps is used for temporary storage of the bitamp image +// of the latest version of the sprite +int actSpsCount = 0; +Bitmap **actsps; +IDriverDependantBitmap* *actspsbmp; +// temporary cache of walk-behind for this actsps image +Bitmap **actspswb; +IDriverDependantBitmap* *actspswbbmp; +CachedActSpsData* actspswbcache; + +bool current_background_is_dirty = false; + +// Room background sprite +IDriverDependantBitmap* roomBackgroundBmp = nullptr; +// Buffer and info flags for viewport/camera pairs rendering in software mode +struct RoomCameraDrawData +{ + // Intermediate bitmap for the software drawing method. + // We use this bitmap in case room camera has scaling enabled, we draw dirty room rects on it, + // and then pass to software renderer which draws sprite on top and then either blits or stretch-blits + // to the virtual screen. + // For more details see comment in ALSoftwareGraphicsDriver::RenderToBackBuffer(). + PBitmap Buffer; // this is the actual bitmap + PBitmap Frame; // this is either same bitmap reference or sub-bitmap of virtual screen + bool IsOffscreen; // whether room viewport was offscreen (cannot use sub-bitmap) + bool IsOverlap; // whether room viewport overlaps any others (marking dirty rects is complicated) +}; +std::vector CameraDrawData; + +std::vector sprlist; +std::vector thingsToDrawList; + +Bitmap **guibg = nullptr; +IDriverDependantBitmap **guibgbmp = nullptr; + + +Bitmap *debugConsoleBuffer = nullptr; + +// whether there are currently remnants of a DisplaySpeech +bool screen_is_dirty = false; + +Bitmap *raw_saved_screen = nullptr; +Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; + + +SpriteListEntry::SpriteListEntry() + : bmp(nullptr) + , pic(nullptr) + , baseline(0), x(0), y(0) + , transparent(0) + , takesPriorityIfEqual(false), hasAlphaChannel(false) +{ +} + +void setpal() { + set_palette_range(palette, 0, 255, 0); +} + +int _places_r = 3, _places_g = 2, _places_b = 3; + +// convert RGB to BGR for strange graphics cards +Bitmap *convert_16_to_16bgr(Bitmap *tempbl) { + + int x,y; + unsigned short c,r,ds,b; + + for (y=0; y < tempbl->GetHeight(); y++) { + unsigned short*p16 = (unsigned short *)tempbl->GetScanLine(y); + + for (x=0; x < tempbl->GetWidth(); x++) { + c = p16[x]; + if (c != MASK_COLOR_16) { + b = _rgb_scale_5[c & 0x1F]; + ds = _rgb_scale_6[(c >> 5) & 0x3F]; + r = _rgb_scale_5[(c >> 11) & 0x1F]; + // allegro assumes 5-6-5 for 16-bit + p16[x] = (((r >> _places_r) << _rgb_r_shift_16) | + ((ds >> _places_g) << _rgb_g_shift_16) | + ((b >> _places_b) << _rgb_b_shift_16)); + + } + } + } + + return tempbl; +} + +// PSP: convert 32 bit RGB to BGR. +Bitmap *convert_32_to_32bgr(Bitmap *tempbl) { + + int i = 0; + int j = 0; + unsigned char* current; + while (i < tempbl->GetHeight()) + { + current = tempbl->GetScanLineForWriting(i); + while (j < tempbl->GetWidth()) + { + current[0] ^= current[2]; + current[2] ^= current[0]; + current[0] ^= current[2]; + current += 4; + j++; + } + i++; + j = 0; + } + + return tempbl; +} + +// NOTE: Some of these conversions are required even when using +// D3D and OpenGL rendering, for two reasons: +// 1) certain raw drawing operations are still performed by software +// Allegro methods, hence bitmaps should be kept compatible to any native +// software operations, such as blitting two bitmaps of different formats. +// 2) mobile ports feature an OpenGL renderer built in Allegro library, +// that assumes native bitmaps are in OpenGL-compatible format, so that it +// could copy them to texture without additional changes. +// AGS own OpenGL renderer tries to sync its behavior with the former one. +// +// TODO: make gfxDriver->GetCompatibleBitmapFormat describe all necessary +// conversions, so that we did not have to guess. +// +Bitmap *AdjustBitmapForUseWithDisplayMode(Bitmap* bitmap, bool has_alpha) +{ + const int bmp_col_depth = bitmap->GetColorDepth(); + const int sys_col_depth = System_GetColorDepth(); + const int game_col_depth = game.GetColorDepth(); + Bitmap *new_bitmap = bitmap; + + // + // The only special case when bitmap needs to be prepared for graphics driver + // + // In 32-bit display mode, 32-bit bitmaps may require component conversion + // to match graphics driver expectation about pixel format. + // TODO: make GetCompatibleBitmapFormat tell this somehow +#if defined (AGS_INVERTED_COLOR_ORDER) + if (sys_col_depth > 16 && bmp_col_depth == 32) + { + // Convert RGB to BGR. + new_bitmap = convert_32_to_32bgr(bitmap); + } +#endif + + // + // The rest is about bringing bitmaps to the native game's format + // (has no dependency on display mode). + // + // In 32-bit game 32-bit bitmaps should have transparent pixels marked + // (this adjustment is probably needed for DrawingSurface ops) + if (game_col_depth == 32 && bmp_col_depth == 32) + { + if (has_alpha) + set_rgb_mask_using_alpha_channel(new_bitmap); + } + // In 32-bit game hicolor bitmaps must be converted to the true color + else if (game_col_depth == 32 && (bmp_col_depth > 8 && bmp_col_depth <= 16)) + { + new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); + } + // In non-32-bit game truecolor bitmaps must be downgraded + else if (game_col_depth <= 16 && bmp_col_depth > 16) + { + if (has_alpha) // if has valid alpha channel, convert it to regular transparency mask + new_bitmap = remove_alpha_channel(bitmap); + else // else simply convert bitmap + new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); + } + // Special case when we must convert 16-bit RGB to BGR + else if (convert_16bit_bgr == 1 && bmp_col_depth == 16) + { + new_bitmap = convert_16_to_16bgr(bitmap); + } + return new_bitmap; +} + +Bitmap *ReplaceBitmapWithSupportedFormat(Bitmap *bitmap) +{ + Bitmap *new_bitmap = GfxUtil::ConvertBitmap(bitmap, gfxDriver->GetCompatibleBitmapFormat(bitmap->GetColorDepth())); + if (new_bitmap != bitmap) + delete bitmap; + return new_bitmap; +} + +Bitmap *PrepareSpriteForUse(Bitmap* bitmap, bool has_alpha) +{ + bool must_switch_palette = bitmap->GetColorDepth() == 8 && game.GetColorDepth() > 8; + if (must_switch_palette) + select_palette(palette); + + Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap, has_alpha); + if (new_bitmap != bitmap) + delete bitmap; + new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); + + if (must_switch_palette) + unselect_palette(); + return new_bitmap; +} + +PBitmap PrepareSpriteForUse(PBitmap bitmap, bool has_alpha) +{ + bool must_switch_palette = bitmap->GetColorDepth() == 8 && System_GetColorDepth() > 8; + if (must_switch_palette) + select_palette(palette); + + Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap.get(), has_alpha); + new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); + + if (must_switch_palette) + unselect_palette(); + return new_bitmap == bitmap.get() ? bitmap : PBitmap(new_bitmap); // if bitmap is same, don't create new smart ptr! +} + +Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res) +{ + Bitmap *dst = new Bitmap(width, height, game.GetColorDepth()); + GraphicResolution want_fmt; + // If the size and color depth are supported we may copy right into our bitmap + if (gfxDriver->GetCopyOfScreenIntoBitmap(dst, at_native_res, &want_fmt)) + return dst; + // Otherwise we might need to copy between few bitmaps... + Bitmap *buf_screenfmt = new Bitmap(want_fmt.Width, want_fmt.Height, want_fmt.ColorDepth); + gfxDriver->GetCopyOfScreenIntoBitmap(buf_screenfmt, at_native_res); + // If at least size matches then we may blit + if (dst->GetSize() == buf_screenfmt->GetSize()) + { + dst->Blit(buf_screenfmt); + } + // Otherwise we need to go through another bitmap of the matching format + else + { + Bitmap *buf_dstfmt = new Bitmap(buf_screenfmt->GetWidth(), buf_screenfmt->GetHeight(), dst->GetColorDepth()); + buf_dstfmt->Blit(buf_screenfmt); + dst->StretchBlt(buf_dstfmt, RectWH(dst->GetSize())); + delete buf_dstfmt; + } + delete buf_screenfmt; + return dst; +} + + +// Begin resolution system functions + +// Multiplies up the number of pixels depending on the current +// resolution, to give a relatively fixed size at any game res +AGS_INLINE int get_fixed_pixel_size(int pixels) +{ + return pixels * game.GetRelativeUIMult(); +} + +AGS_INLINE int data_to_game_coord(int coord) +{ + return coord * game.GetDataUpscaleMult(); +} + +AGS_INLINE void data_to_game_coords(int *x, int *y) +{ + const int mul = game.GetDataUpscaleMult(); + x[0] *= mul; + y[0] *= mul; +} + +AGS_INLINE void data_to_game_round_up(int *x, int *y) +{ + const int mul = game.GetDataUpscaleMult(); + x[0] = x[0] * mul + (mul - 1); + y[0] = y[0] * mul + (mul - 1); +} + +AGS_INLINE int game_to_data_coord(int coord) +{ + return coord / game.GetDataUpscaleMult(); +} + +AGS_INLINE void game_to_data_coords(int &x, int &y) +{ + const int mul = game.GetDataUpscaleMult(); + x /= mul; + y /= mul; +} + +AGS_INLINE int game_to_data_round_up(int coord) +{ + const int mul = game.GetDataUpscaleMult(); + return (coord / mul) + (mul - 1); +} + +AGS_INLINE void ctx_data_to_game_coord(int &x, int &y, bool hires_ctx) +{ + if (hires_ctx && !game.IsLegacyHiRes()) + { + x /= HIRES_COORD_MULTIPLIER; + y /= HIRES_COORD_MULTIPLIER; + } + else if (!hires_ctx && game.IsLegacyHiRes()) + { + x *= HIRES_COORD_MULTIPLIER; + y *= HIRES_COORD_MULTIPLIER; + } +} + +AGS_INLINE void ctx_data_to_game_size(int &w, int &h, bool hires_ctx) +{ + if (hires_ctx && !game.IsLegacyHiRes()) + { + w = Math::Max(1, (w / HIRES_COORD_MULTIPLIER)); + h = Math::Max(1, (h / HIRES_COORD_MULTIPLIER)); + } + else if (!hires_ctx && game.IsLegacyHiRes()) + { + w *= HIRES_COORD_MULTIPLIER; + h *= HIRES_COORD_MULTIPLIER; + } +} + +AGS_INLINE int ctx_data_to_game_size(int size, bool hires_ctx) +{ + if (hires_ctx && !game.IsLegacyHiRes()) + return Math::Max(1, (size / HIRES_COORD_MULTIPLIER)); + if (!hires_ctx && game.IsLegacyHiRes()) + return size * HIRES_COORD_MULTIPLIER; + return size; +} + +AGS_INLINE int game_to_ctx_data_size(int size, bool hires_ctx) +{ + if (hires_ctx && !game.IsLegacyHiRes()) + return size * HIRES_COORD_MULTIPLIER; + else if (!hires_ctx && game.IsLegacyHiRes()) + return Math::Max(1, (size / HIRES_COORD_MULTIPLIER)); + return size; +} + +AGS_INLINE void defgame_to_finalgame_coords(int &x, int &y) +{ // Note we support only upscale now + x *= game.GetScreenUpscaleMult(); + y *= game.GetScreenUpscaleMult(); +} + +// End resolution system functions + +// Create blank (black) images used to repaint borders around game frame +void create_blank_image(int coldepth) +{ + // this is the first time that we try to use the graphics driver, + // so it's the most likey place for a crash + try + { + Bitmap *blank = BitmapHelper::CreateBitmap(16, 16, coldepth); + blank = ReplaceBitmapWithSupportedFormat(blank); + blank->Clear(); + blankImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); + blankSidebarImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); + delete blank; + } + catch (Ali3DException gfxException) + { + quit((char*)gfxException._message); + } +} + +void destroy_blank_image() +{ + if (blankImage) + gfxDriver->DestroyDDB(blankImage); + if (blankSidebarImage) + gfxDriver->DestroyDDB(blankSidebarImage); + blankImage = nullptr; + blankSidebarImage = nullptr; +} + +int MakeColor(int color_index) +{ + color_t real_color = 0; + __my_setcolor(&real_color, color_index, game.GetColorDepth()); + return real_color; +} + +void init_draw_method() +{ + if (gfxDriver->HasAcceleratedTransform()) + { + walkBehindMethod = DrawAsSeparateSprite; + create_blank_image(game.GetColorDepth()); + } + else + { + walkBehindMethod = DrawOverCharSprite; + } + + on_mainviewport_changed(); + init_room_drawdata(); + if (gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->GetMemoryBackBuffer()->Clear(); +} + +void dispose_draw_method() +{ + dispose_room_drawdata(); + dispose_invalid_regions(false); + destroy_blank_image(); +} + +void dispose_room_drawdata() +{ + CameraDrawData.clear(); + dispose_invalid_regions(true); +} + +void on_mainviewport_changed() +{ + if (!gfxDriver->RequiresFullRedrawEachFrame()) + { + init_invalid_regions(-1, play.GetMainViewport().GetSize(), RectWH(play.GetMainViewport().GetSize())); + if (game.GetGameRes().ExceedsByAny(play.GetMainViewport().GetSize())) + clear_letterbox_borders(); + } +} + +// Allocates a bitmap for rendering camera/viewport pair (software render mode) +void prepare_roomview_frame(Viewport *view) +{ + const int view_index = view->GetID(); + const Size view_sz = view->GetRect().GetSize(); + const Size cam_sz = view->GetCamera()->GetRect().GetSize(); + RoomCameraDrawData &draw_dat = CameraDrawData[view_index]; + // We use intermediate bitmap to render camera/viewport pair in software mode under these conditions: + // * camera size and viewport size are different (this may be suboptimal to paint dirty rects stretched, + // and also Allegro backend cannot stretch background of different colour depth). + // * viewport is located outside of the virtual screen (even if partially): subbitmaps cannot contain + // regions outside of master bitmap, and we must not clamp surface size to virtual screen because + // plugins may want to also use viewport bitmap, therefore it should retain full size. + if (cam_sz == view_sz && !draw_dat.IsOffscreen) + { // note we keep the buffer allocated in case it will become useful later + draw_dat.Frame.reset(); + } + else + { + PBitmap &camera_frame = draw_dat.Frame; + PBitmap &camera_buffer = draw_dat.Buffer; + if (!camera_buffer || camera_buffer->GetWidth() < cam_sz.Width || camera_buffer->GetHeight() < cam_sz.Height) + { + // Allocate new buffer bitmap with an extra size in case they will want to zoom out + int room_width = data_to_game_coord(thisroom.Width); + int room_height = data_to_game_coord(thisroom.Height); + Size alloc_sz = Size::Clamp(cam_sz * 2, Size(1, 1), Size(room_width, room_height)); + camera_buffer.reset(new Bitmap(alloc_sz.Width, alloc_sz.Height, gfxDriver->GetMemoryBackBuffer()->GetColorDepth())); + } + + if (!camera_frame || camera_frame->GetSize() != cam_sz) + { + camera_frame.reset(BitmapHelper::CreateSubBitmap(camera_buffer.get(), RectWH(cam_sz))); + } + } +} + +// Syncs room viewport and camera in case either size has changed +void sync_roomview(Viewport *view) +{ + if (view->GetCamera() == nullptr) + return; + init_invalid_regions(view->GetID(), view->GetCamera()->GetRect().GetSize(), play.GetRoomViewportAbs(view->GetID())); + prepare_roomview_frame(view); +} + +void init_room_drawdata() +{ + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + // Make sure all frame buffers are created for software drawing + int view_count = play.GetRoomViewportCount(); + CameraDrawData.resize(view_count); + for (int i = 0; i < play.GetRoomViewportCount(); ++i) + sync_roomview(play.GetRoomViewport(i).get()); +} + +void on_roomviewport_created(int index) +{ + if (!gfxDriver || gfxDriver->RequiresFullRedrawEachFrame()) + return; + if ((size_t)index < CameraDrawData.size()) + return; + CameraDrawData.resize(index + 1); +} + +void on_roomviewport_deleted(int index) +{ + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + CameraDrawData.erase(CameraDrawData.begin() + index); + delete_invalid_regions(index); +} + +void on_roomviewport_changed(Viewport *view) +{ + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + if (!view->IsVisible() || view->GetCamera() == nullptr) + return; + const bool off = !IsRectInsideRect(RectWH(gfxDriver->GetMemoryBackBuffer()->GetSize()), view->GetRect()); + const bool off_changed = off != CameraDrawData[view->GetID()].IsOffscreen; + CameraDrawData[view->GetID()].IsOffscreen = off; + if (view->HasChangedSize()) + sync_roomview(view); + else if (off_changed) + prepare_roomview_frame(view); + // TODO: don't have to do this all the time, perhaps do "dirty rect" method + // and only clear previous viewport location? + invalidate_screen(); + gfxDriver->GetMemoryBackBuffer()->Clear(); +} + +void detect_roomviewport_overlaps(size_t z_index) +{ + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + // Find out if we overlap or are overlapped by anything; + const auto &viewports = play.GetRoomViewportsZOrdered(); + for (; z_index < viewports.size(); ++z_index) + { + auto this_view = viewports[z_index]; + const int this_id = this_view->GetID(); + bool is_overlap = false; + if (!this_view->IsVisible()) continue; + for (size_t z_index2 = 0; z_index2 < z_index; ++z_index) + { + if (!viewports[z_index2]->IsVisible()) continue; + if (AreRectsIntersecting(this_view->GetRect(), viewports[z_index2]->GetRect())) + { + is_overlap = true; + break; + } + } + if (CameraDrawData[this_id].IsOverlap != is_overlap) + { + CameraDrawData[this_id].IsOverlap = is_overlap; + prepare_roomview_frame(this_view.get()); + } + } +} + +void on_roomcamera_changed(Camera *cam) +{ + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + if (cam->HasChangedSize()) + { + auto viewrefs = cam->GetLinkedViewports(); + for (auto vr : viewrefs) + { + PViewport vp = vr.lock(); + if (vp) + sync_roomview(vp.get()); + } + } + // TODO: only invalidate what this particular camera sees + invalidate_screen(); +} + +void mark_screen_dirty() +{ + screen_is_dirty = true; +} + +bool is_screen_dirty() +{ + return screen_is_dirty; +} + +void invalidate_screen() +{ + invalidate_all_rects(); +} + +void invalidate_camera_frame(int index) +{ + invalidate_all_camera_rects(index); +} + +void invalidate_rect(int x1, int y1, int x2, int y2, bool in_room) +{ + //if (!in_room) + invalidate_rect_ds(x1, y1, x2, y2, in_room); +} + +void invalidate_sprite(int x1, int y1, IDriverDependantBitmap *pic, bool in_room) +{ + //if (!in_room) + invalidate_rect_ds(x1, y1, x1 + pic->GetWidth(), y1 + pic->GetHeight(), in_room); +} + +void mark_current_background_dirty() +{ + current_background_is_dirty = true; +} + + +void draw_and_invalidate_text(Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text) +{ + wouttext_outline(ds, x1, y1, font, text_color, (char*)text); + invalidate_rect(x1, y1, x1 + wgettextwidth_compensate(text, font), y1 + getfontheight_outlined(font) + get_fixed_pixel_size(1), false); +} + +// Renders black borders for the legacy boxed game mode, +// where whole game screen changes size between large and small rooms +void render_black_borders() +{ + if (gfxDriver->UsesMemoryBackBuffer()) + return; + { + gfxDriver->BeginSpriteBatch(RectWH(game.GetGameRes()), SpriteTransform()); + const Rect &viewport = play.GetMainViewport(); + if (viewport.Top > 0) + { + // letterbox borders + blankImage->SetStretch(game.GetGameRes().Width, viewport.Top, false); + gfxDriver->DrawSprite(0, 0, blankImage); + gfxDriver->DrawSprite(0, viewport.Bottom + 1, blankImage); + } + if (viewport.Left > 0) + { + // sidebar borders for widescreen + blankSidebarImage->SetStretch(viewport.Left, viewport.GetHeight(), false); + gfxDriver->DrawSprite(0, 0, blankSidebarImage); + gfxDriver->DrawSprite(viewport.Right + 1, 0, blankSidebarImage); + } + } +} + + +void render_to_screen() +{ + // Stage: final plugin callback (still drawn on game screen + if (pl_any_want_hook(AGSE_FINALSCREENDRAW)) + { + gfxDriver->BeginSpriteBatch(play.GetMainViewport(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + gfxDriver->DrawSprite(AGSE_FINALSCREENDRAW, 0, nullptr); + } + // Stage: engine overlay + construct_engine_overlay(); + + // only vsync in full screen mode, it makes things worse in a window + gfxDriver->EnableVsyncBeforeRender((scsystem.vsync > 0) && (!scsystem.windowed)); + + bool succeeded = false; + while (!succeeded) + { + try + { + // For software renderer, need to blacken upper part of the game frame when shaking screen moves image down + const Rect &viewport = play.GetMainViewport(); + if (play.shake_screen_yoff > 0 && !gfxDriver->RequiresFullRedrawEachFrame()) + gfxDriver->ClearRectangle(viewport.Left, viewport.Top, viewport.GetWidth() - 1, play.shake_screen_yoff, nullptr); + gfxDriver->Render(0, play.shake_screen_yoff, (GlobalFlipType)play.screen_flipped); + +#if AGS_PLATFORM_OS_ANDROID + if (game.color_depth == 1) + android_render(); +#elif AGS_PLATFORM_OS_IOS + if (game.color_depth == 1) + ios_render(); +#endif + + succeeded = true; + } + catch (Ali3DFullscreenLostException) + { + platform->Delay(500); + } + } +} + +// Blanks out borders around main viewport in case it became smaller (e.g. after loading another room) +void clear_letterbox_borders() +{ + const Rect &viewport = play.GetMainViewport(); + gfxDriver->ClearRectangle(0, 0, game.GetGameRes().Width - 1, viewport.Top - 1, nullptr); + gfxDriver->ClearRectangle(0, viewport.Bottom + 1, game.GetGameRes().Width - 1, game.GetGameRes().Height - 1, nullptr); +} + +void draw_game_screen_callback() +{ + construct_game_scene(true); + construct_game_screen_overlay(false); +} + + + +void putpixel_compensate (Bitmap *ds, int xx,int yy, int col) { + if ((ds->GetColorDepth() == 32) && (col != 0)) { + // ensure the alpha channel is preserved if it has one + int alphaval = geta32(ds->GetPixel(xx, yy)); + col = makeacol32(getr32(col), getg32(col), getb32(col), alphaval); + } + ds->FillRect(Rect(xx, yy, xx + get_fixed_pixel_size(1) - 1, yy + get_fixed_pixel_size(1) - 1), col); +} + + + + +void draw_sprite_support_alpha(Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Bitmap *image, bool src_has_alpha, + BlendMode blend_mode, int alpha) +{ + if (alpha <= 0) + return; + + if (game.options[OPT_SPRITEALPHA] == kSpriteAlphaRender_Proper) + { + GfxUtil::DrawSpriteBlend(ds, Point(xpos, ypos), image, blend_mode, ds_has_alpha, src_has_alpha, alpha); + } + // Backwards-compatible drawing + else if (src_has_alpha && alpha == 0xFF) + { + set_alpha_blender(); + ds->TransBlendBlt(image, xpos, ypos); + } + else + { + GfxUtil::DrawSpriteWithTransparency(ds, image, xpos, ypos, alpha); + } +} + +void draw_sprite_slot_support_alpha(Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot, + BlendMode blend_mode, int alpha) +{ + draw_sprite_support_alpha(ds, ds_has_alpha, xpos, ypos, spriteset[src_slot], (game.SpriteInfos[src_slot].Flags & SPF_ALPHACHANNEL) != 0, + blend_mode, alpha); +} + + +IDriverDependantBitmap* recycle_ddb_bitmap(IDriverDependantBitmap *bimp, Bitmap *source, bool hasAlpha, bool opaque) { + if (bimp != nullptr) { + // same colour depth, width and height -> reuse + if (((bimp->GetColorDepth() + 1) / 8 == source->GetBPP()) && + (bimp->GetWidth() == source->GetWidth()) && (bimp->GetHeight() == source->GetHeight())) + { + gfxDriver->UpdateDDBFromBitmap(bimp, source, hasAlpha); + return bimp; + } + + gfxDriver->DestroyDDB(bimp); + } + bimp = gfxDriver->CreateDDBFromBitmap(source, hasAlpha, opaque); + return bimp; +} + +void invalidate_cached_walkbehinds() +{ + memset(&actspswbcache[0], 0, sizeof(CachedActSpsData) * actSpsCount); +} + +// sort_out_walk_behinds: modifies the supplied sprite by overwriting parts +// of it with transparent pixels where there are walk-behind areas +// Returns whether any pixels were updated +int sort_out_walk_behinds(Bitmap *sprit,int xx,int yy,int basel, Bitmap *copyPixelsFrom = nullptr, Bitmap *checkPixelsFrom = nullptr, int zoom=100) { + if (noWalkBehindsAtAll) + return 0; + + if ((!thisroom.WalkBehindMask->IsMemoryBitmap()) || + (!sprit->IsMemoryBitmap())) + quit("!sort_out_walk_behinds: wb bitmap not linear"); + + int rr,tmm, toheight;//,tcol; + // precalculate this to try and shave some time off + int maskcol = sprit->GetMaskColor(); + int spcoldep = sprit->GetColorDepth(); + int screenhit = thisroom.WalkBehindMask->GetHeight(); + short *shptr, *shptr2; + int *loptr, *loptr2; + int pixelsChanged = 0; + int ee = 0; + if (xx < 0) + ee = 0 - xx; + + if ((checkPixelsFrom != nullptr) && (checkPixelsFrom->GetColorDepth() != spcoldep)) + quit("sprite colour depth does not match background colour depth"); + + for ( ; ee < sprit->GetWidth(); ee++) { + if (ee + xx >= thisroom.WalkBehindMask->GetWidth()) + break; + + if ((!walkBehindExists[ee+xx]) || + (walkBehindEndY[ee+xx] <= yy) || + (walkBehindStartY[ee+xx] > yy+sprit->GetHeight())) + continue; + + toheight = sprit->GetHeight(); + + if (walkBehindStartY[ee+xx] < yy) + rr = 0; + else + rr = (walkBehindStartY[ee+xx] - yy); + + // Since we will use _getpixel, ensure we only check within the screen + if (rr + yy < 0) + rr = 0 - yy; + if (toheight + yy > screenhit) + toheight = screenhit - yy; + if (toheight + yy > walkBehindEndY[ee+xx]) + toheight = walkBehindEndY[ee+xx] - yy; + if (rr < 0) + rr = 0; + + for ( ; rr < toheight;rr++) { + + // we're ok with _getpixel because we've checked the screen edges + //tmm = _getpixel(thisroom.WalkBehindMask,ee+xx,rr+yy); + // actually, _getpixel is well inefficient, do it ourselves + // since we know it's 8-bit bitmap + tmm = thisroom.WalkBehindMask->GetScanLine(rr+yy)[ee+xx]; + if (tmm<1) continue; + if (croom->walkbehind_base[tmm] <= basel) continue; + + if (copyPixelsFrom != nullptr) + { + if (spcoldep <= 8) + { + if (checkPixelsFrom->GetScanLine((rr * 100) / zoom)[(ee * 100) / zoom] != maskcol) { + sprit->GetScanLineForWriting(rr)[ee] = copyPixelsFrom->GetScanLine(rr + yy)[ee + xx]; + pixelsChanged = 1; + } + } + else if (spcoldep <= 16) { + shptr = (short*)&sprit->GetScanLine(rr)[0]; + shptr2 = (short*)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; + if (shptr2[(ee * 100) / zoom] != maskcol) { + shptr[ee] = ((short*)(©PixelsFrom->GetScanLine(rr + yy)[0]))[ee + xx]; + pixelsChanged = 1; + } + } + else if (spcoldep == 24) { + char *chptr = (char*)&sprit->GetScanLine(rr)[0]; + char *chptr2 = (char*)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; + if (memcmp(&chptr2[((ee * 100) / zoom) * 3], &maskcol, 3) != 0) { + memcpy(&chptr[ee * 3], ©PixelsFrom->GetScanLine(rr + yy)[(ee + xx) * 3], 3); + pixelsChanged = 1; + } + } + else if (spcoldep <= 32) { + loptr = (int*)&sprit->GetScanLine(rr)[0]; + loptr2 = (int*)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; + if (loptr2[(ee * 100) / zoom] != maskcol) { + loptr[ee] = ((int*)(©PixelsFrom->GetScanLine(rr + yy)[0]))[ee + xx]; + pixelsChanged = 1; + } + } + } + else + { + pixelsChanged = 1; + if (spcoldep <= 8) + sprit->GetScanLineForWriting(rr)[ee] = maskcol; + else if (spcoldep <= 16) { + shptr = (short*)&sprit->GetScanLine(rr)[0]; + shptr[ee] = maskcol; + } + else if (spcoldep == 24) { + char *chptr = (char*)&sprit->GetScanLine(rr)[0]; + memcpy(&chptr[ee * 3], &maskcol, 3); + } + else if (spcoldep <= 32) { + loptr = (int*)&sprit->GetScanLine(rr)[0]; + loptr[ee] = maskcol; + } + else + quit("!Sprite colour depth >32 ??"); + } + } + } + return pixelsChanged; +} + +void sort_out_char_sprite_walk_behind(int actspsIndex, int xx, int yy, int basel, int zoom, int width, int height) +{ + if (noWalkBehindsAtAll) + return; + + if ((!actspswbcache[actspsIndex].valid) || + (actspswbcache[actspsIndex].xWas != xx) || + (actspswbcache[actspsIndex].yWas != yy) || + (actspswbcache[actspsIndex].baselineWas != basel)) + { + actspswb[actspsIndex] = recycle_bitmap(actspswb[actspsIndex], thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth(), width, height, true); + Bitmap *wbSprite = actspswb[actspsIndex]; + + actspswbcache[actspsIndex].isWalkBehindHere = sort_out_walk_behinds(wbSprite, xx, yy, basel, thisroom.BgFrames[play.bg_frame].Graphic.get(), actsps[actspsIndex], zoom); + actspswbcache[actspsIndex].xWas = xx; + actspswbcache[actspsIndex].yWas = yy; + actspswbcache[actspsIndex].baselineWas = basel; + actspswbcache[actspsIndex].valid = 1; + + if (actspswbcache[actspsIndex].isWalkBehindHere) + { + actspswbbmp[actspsIndex] = recycle_ddb_bitmap(actspswbbmp[actspsIndex], actspswb[actspsIndex], false); + } + } + + if (actspswbcache[actspsIndex].isWalkBehindHere) + { + add_to_sprite_list(actspswbbmp[actspsIndex], xx, yy, basel, 0, -1, true); + } +} + +void clear_draw_list() { + thingsToDrawList.clear(); +} +void add_thing_to_draw(IDriverDependantBitmap* bmp, int x, int y, int trans, bool alphaChannel) { + SpriteListEntry sprite; + sprite.pic = nullptr; + sprite.bmp = bmp; + sprite.x = x; + sprite.y = y; + sprite.transparent = trans; + sprite.hasAlphaChannel = alphaChannel; + thingsToDrawList.push_back(sprite); +} + +// the sprite list is an intermediate list used to order +// objects and characters by their baselines before everything +// is added to the Thing To Draw List +void clear_sprite_list() { + sprlist.clear(); +} +void add_to_sprite_list(IDriverDependantBitmap* spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind) { + + if (spp == nullptr) + quit("add_to_sprite_list: attempted to draw NULL sprite"); + // completely invisible, so don't draw it at all + if (trans == 255) + return; + + SpriteListEntry sprite; + if ((sprNum >= 0) && ((game.SpriteInfos[sprNum].Flags & SPF_ALPHACHANNEL) != 0)) + sprite.hasAlphaChannel = true; + else + sprite.hasAlphaChannel = false; + + sprite.bmp = spp; + sprite.baseline = baseline; + sprite.x=xx; + sprite.y=yy; + sprite.transparent=trans; + + if (walkBehindMethod == DrawAsSeparateSprite) + sprite.takesPriorityIfEqual = !isWalkBehind; + else + sprite.takesPriorityIfEqual = isWalkBehind; + + sprlist.push_back(sprite); +} + +void repair_alpha_channel(Bitmap *dest, Bitmap *bgpic) +{ + // Repair the alpha channel, because sprites may have been drawn + // over it by the buttons, etc + int theWid = (dest->GetWidth() < bgpic->GetWidth()) ? dest->GetWidth() : bgpic->GetWidth(); + int theHit = (dest->GetHeight() < bgpic->GetHeight()) ? dest->GetHeight() : bgpic->GetHeight(); + for (int y = 0; y < theHit; y++) + { + unsigned int *destination = ((unsigned int*)dest->GetScanLineForWriting(y)); + unsigned int *source = ((unsigned int*)bgpic->GetScanLineForWriting(y)); + for (int x = 0; x < theWid; x++) + { + destination[x] |= (source[x] & 0xff000000); + } + } +} + + +// used by GUI renderer to draw images +void draw_gui_sprite(Bitmap *ds, int pic, int x, int y, bool use_alpha, BlendMode blend_mode) +{ + Bitmap *sprite = spriteset[pic]; + const bool ds_has_alpha = ds->GetColorDepth() == 32; + const bool src_has_alpha = (game.SpriteInfos[pic].Flags & SPF_ALPHACHANNEL) != 0; + + if (use_alpha && game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Proper) + { + GfxUtil::DrawSpriteBlend(ds, Point(x, y), sprite, blend_mode, ds_has_alpha, src_has_alpha); + } + // Backwards-compatible drawing + else if (use_alpha && ds_has_alpha && game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_AdditiveAlpha) + { + if (src_has_alpha) + set_additive_alpha_blender(); + else + set_opaque_alpha_blender(); + ds->TransBlendBlt(sprite, x, y); + } + else + { + GfxUtil::DrawSpriteWithTransparency(ds, sprite, x, y); + } +} + +void draw_gui_sprite_v330(Bitmap *ds, int pic, int x, int y, bool use_alpha, BlendMode blend_mode) +{ + draw_gui_sprite(ds, pic, x, y, use_alpha && (loaded_game_file_version >= kGameVersion_330), blend_mode); +} + +// function to sort the sprites into baseline order +bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2) +{ + if (e1.baseline == e2.baseline) + { + if (e1.takesPriorityIfEqual) + return false; + if (e2.takesPriorityIfEqual) + return true; + } + return e1.baseline < e2.baseline; +} + + + + +void draw_sprite_list() { + + if (walkBehindMethod == DrawAsSeparateSprite) + { + for (int ee = 1; ee < MAX_WALK_BEHINDS; ee++) + { + if (walkBehindBitmap[ee] != nullptr) + { + add_to_sprite_list(walkBehindBitmap[ee], walkBehindLeft[ee], walkBehindTop[ee], + croom->walkbehind_base[ee], 0, -1, true); + } + } + } + + std::sort(sprlist.begin(), sprlist.end(), spritelistentry_less); + + if(pl_any_want_hook(AGSE_PRESCREENDRAW)) + add_thing_to_draw(nullptr, AGSE_PRESCREENDRAW, 0, TRANS_RUN_PLUGIN, false); + + // copy the sorted sprites into the Things To Draw list + thingsToDrawList.insert(thingsToDrawList.end(), sprlist.begin(), sprlist.end()); +} + +// Avoid freeing and reallocating the memory if possible +Bitmap *recycle_bitmap(Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent) { + if (bimp != nullptr) { + // same colour depth, width and height -> reuse + if ((bimp->GetColorDepth() == coldep) && (bimp->GetWidth() == wid) + && (bimp->GetHeight() == hit)) + { + if (make_transparent) + { + bimp->ClearTransparent(); + } + return bimp; + } + + delete bimp; + } + bimp = make_transparent ? BitmapHelper::CreateTransparentBitmap(wid, hit,coldep) : + BitmapHelper::CreateBitmap(wid, hit,coldep); + return bimp; +} + + +// Get the local tint at the specified X & Y co-ordinates, based on +// room regions and SetAmbientTint +// tint_amnt will be set to 0 if there is no tint enabled +// if this is the case, then light_lev holds the light level (0=none) +void get_local_tint(int xpp, int ypp, int nolight, + int *tint_amnt, int *tint_r, int *tint_g, + int *tint_b, int *tint_lit, + int *light_lev) { + + int tint_level = 0, light_level = 0; + int tint_amount = 0; + int tint_red = 0; + int tint_green = 0; + int tint_blue = 0; + int tint_light = 255; + + if (nolight == 0) { + + int onRegion = 0; + + if ((play.ground_level_areas_disabled & GLED_EFFECTS) == 0) { + // check if the player is on a region, to find its + // light/tint level + onRegion = GetRegionIDAtRoom(xpp, ypp); + if (onRegion == 0) { + // when walking, he might just be off a walkable area + onRegion = GetRegionIDAtRoom(xpp - 3, ypp); + if (onRegion == 0) + onRegion = GetRegionIDAtRoom(xpp + 3, ypp); + if (onRegion == 0) + onRegion = GetRegionIDAtRoom(xpp, ypp - 3); + if (onRegion == 0) + onRegion = GetRegionIDAtRoom(xpp, ypp + 3); + } + } + + if ((onRegion > 0) && (onRegion < MAX_ROOM_REGIONS)) { + light_level = thisroom.Regions[onRegion].Light; + tint_level = thisroom.Regions[onRegion].Tint; + } + else if (onRegion <= 0) { + light_level = thisroom.Regions[0].Light; + tint_level = thisroom.Regions[0].Tint; + } + + int tint_sat = (tint_level >> 24) & 0xFF; + if ((game.color_depth == 1) || ((tint_level & 0x00ffffff) == 0) || + (tint_sat == 0)) + tint_level = 0; + + if (tint_level) { + tint_red = (unsigned char)(tint_level & 0x000ff); + tint_green = (unsigned char)((tint_level >> 8) & 0x000ff); + tint_blue = (unsigned char)((tint_level >> 16) & 0x000ff); + tint_amount = tint_sat; + tint_light = light_level; + } + + if (play.rtint_enabled) + { + if (play.rtint_level > 0) + { + // override with room tint + tint_red = play.rtint_red; + tint_green = play.rtint_green; + tint_blue = play.rtint_blue; + tint_amount = play.rtint_level; + tint_light = play.rtint_light; + } + else + { + // override with room light level + tint_amount = 0; + light_level = play.rtint_light; + } + } + } + + // copy to output parameters + *tint_amnt = tint_amount; + *tint_r = tint_red; + *tint_g = tint_green; + *tint_b = tint_blue; + *tint_lit = tint_light; + if (light_lev) + *light_lev = light_level; +} + + + + +// Applies the specified RGB Tint or Light Level to the actsps +// sprite indexed with actspsindex +void apply_tint_or_light(int actspsindex, int light_level, + int tint_amount, int tint_red, int tint_green, + int tint_blue, int tint_light, int coldept, + Bitmap *blitFrom) { + + // In a 256-colour game, we cannot do tinting or lightening + // (but we can do darkening, if light_level < 0) + if (game.color_depth == 1) { + if ((light_level > 0) || (tint_amount != 0)) + return; + } + + // we can only do tint/light if the colour depths match + if (game.GetColorDepth() == actsps[actspsindex]->GetColorDepth()) { + Bitmap *oldwas; + // if the caller supplied a source bitmap, ->Blit from it + // (used as a speed optimisation where possible) + if (blitFrom) + oldwas = blitFrom; + // otherwise, make a new target bmp + else { + oldwas = actsps[actspsindex]; + actsps[actspsindex] = BitmapHelper::CreateBitmap(oldwas->GetWidth(), oldwas->GetHeight(), coldept); + } + Bitmap *active_spr = actsps[actspsindex]; + + if (tint_amount) { + // It is an RGB tint + tint_image (active_spr, oldwas, tint_red, tint_green, tint_blue, tint_amount, tint_light); + } + else { + // the RGB values passed to set_trans_blender decide whether it will darken + // or lighten sprites ( <128=darken, >128=lighten). The parameter passed + // to LitBlendBlt defines how much it will be darkened/lightened by. + + int lit_amnt; + active_spr->FillTransparent(); + // It's a light level, not a tint + if (game.color_depth == 1) { + // 256-col + lit_amnt = (250 - ((-light_level) * 5)/2); + } + else { + // hi-color + if (light_level < 0) + set_my_trans_blender(8,8,8,0); + else + set_my_trans_blender(248,248,248,0); + lit_amnt = abs(light_level) * 2; + } + + active_spr->LitBlendBlt(oldwas, 0, 0, lit_amnt); + } + + if (oldwas != blitFrom) + delete oldwas; + + } + else if (blitFrom) { + // sprite colour depth != game colour depth, so don't try and tint + // but we do need to do something, so copy the source + Bitmap *active_spr = actsps[actspsindex]; + active_spr->Blit(blitFrom, 0, 0, 0, 0, active_spr->GetWidth(), active_spr->GetHeight()); + } + +} + +// Draws the specified 'sppic' sprite onto actsps[useindx] at the +// specified width and height, and flips the sprite if necessary. +// Returns 1 if something was drawn to actsps; returns 0 if no +// scaling or stretching was required, in which case nothing was done +int scale_and_flip_sprite(int useindx, int coldept, int zoom_level, + int sppic, int newwidth, int newheight, + int isMirrored) { + + int actsps_used = 1; + + // create and blank out the new sprite + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, newwidth, newheight, true); + Bitmap *active_spr = actsps[useindx]; + + if (zoom_level != 100) { + // Scaled character + + our_eip = 334; + + // Ensure that anti-aliasing routines have a palette to + // use for mapping while faded out + if (in_new_room) + select_palette (palette); + + + if (isMirrored) { + Bitmap *tempspr = BitmapHelper::CreateBitmap(newwidth, newheight,coldept); + tempspr->Fill (actsps[useindx]->GetMaskColor()); + if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) + tempspr->AAStretchBlt (spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + else + tempspr->StretchBlt (spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + active_spr->FlipBlt(tempspr, 0, 0, Common::kBitmap_HFlip); + delete tempspr; + } + else if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) + active_spr->AAStretchBlt(spriteset[sppic],RectWH(0,0,newwidth,newheight), Common::kBitmap_Transparency); + else + active_spr->StretchBlt(spriteset[sppic],RectWH(0,0,newwidth,newheight), Common::kBitmap_Transparency); + + /* AASTR2 version of code (doesn't work properly, gives black borders) + if (IS_ANTIALIAS_SPRITES) { + int aa_mode = AA_MASKED; + if (game.spriteflags[sppic] & SPF_ALPHACHANNEL) + aa_mode |= AA_ALPHA | AA_RAW_ALPHA; + if (isMirrored) + aa_mode |= AA_HFLIP; + + aa_set_mode(aa_mode); + ->AAStretchBlt(actsps[useindx],spriteset[sppic],0,0,newwidth,newheight); + } + else if (isMirrored) { + Bitmap *tempspr = BitmapHelper::CreateBitmap_ (coldept, newwidth, newheight); + ->Clear (tempspr, ->GetMaskColor(actsps[useindx])); + ->StretchBlt (tempspr, spriteset[sppic], 0, 0, newwidth, newheight); + ->FlipBlt(Common::kBitmap_HFlip, (actsps[useindx], tempspr, 0, 0); + wfreeblock (tempspr); + } + else + ->StretchBlt(actsps[useindx],spriteset[sppic],0,0,newwidth,newheight); + */ + if (in_new_room) + unselect_palette(); + + } + else { + // Not a scaled character, draw at normal size + + our_eip = 339; + + if (isMirrored) + active_spr->FlipBlt(spriteset[sppic], 0, 0, Common::kBitmap_HFlip); + else + actsps_used = 0; + //->Blit (spriteset[sppic], actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + } + + return actsps_used; +} + + + +// create the actsps[aa] image with the object drawn correctly +// returns 1 if nothing at all has changed and actsps is still +// intact from last time; 0 otherwise +int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysUseSoftware) { + int useindx = aa; + bool hardwareAccelerated = !alwaysUseSoftware && gfxDriver->HasAcceleratedTransform(); + + if (spriteset[objs[aa].num] == nullptr) + quitprintf("There was an error drawing object %d. Its current sprite, %d, is invalid.", aa, objs[aa].num); + + int coldept = spriteset[objs[aa].num]->GetColorDepth(); + int sprwidth = game.SpriteInfos[objs[aa].num].Width; + int sprheight = game.SpriteInfos[objs[aa].num].Height; + + int tint_red, tint_green, tint_blue; + int tint_level, tint_light, light_level; + int zoom_level = 100; + + // calculate the zoom level + if ((objs[aa].flags & OBJF_USEROOMSCALING) == 0) + { + zoom_level = objs[aa].zoom; + } + else + { + int onarea = get_walkable_area_at_location(objs[aa].x, objs[aa].y); + if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) { + // just off the edge of an area -- use the scaling we had + // while on the area + zoom_level = objs[aa].zoom; + } + else + zoom_level = get_area_scaling(onarea, objs[aa].x, objs[aa].y); + } + if (zoom_level != 100) + scale_sprite_size(objs[aa].num, zoom_level, &sprwidth, &sprheight); + objs[aa].zoom = zoom_level; + + // save width/height into parameters if requested + if (drawnWidth) + *drawnWidth = sprwidth; + if (drawnHeight) + *drawnHeight = sprheight; + + objs[aa].last_width = sprwidth; + objs[aa].last_height = sprheight; + + tint_red = tint_green = tint_blue = tint_level = tint_light = light_level = 0; + + if (objs[aa].flags & OBJF_HASTINT) { + // object specific tint, use it + tint_red = objs[aa].tint_r; + tint_green = objs[aa].tint_g; + tint_blue = objs[aa].tint_b; + tint_level = objs[aa].tint_level; + tint_light = objs[aa].tint_light; + light_level = 0; + } + else if (objs[aa].flags & OBJF_HASLIGHT) + { + light_level = objs[aa].tint_light; + } + else { + // get the ambient or region tint + int ignoreRegionTints = 1; + if (objs[aa].flags & OBJF_USEREGIONTINTS) + ignoreRegionTints = 0; + + get_local_tint(objs[aa].x, objs[aa].y, ignoreRegionTints, + &tint_level, &tint_red, &tint_green, &tint_blue, + &tint_light, &light_level); + } + + // check whether the image should be flipped + int isMirrored = 0; + if ( (objs[aa].view >= 0) && + (views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].pic == objs[aa].num) && + ((views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE) != 0)) { + isMirrored = 1; + } + + if ((hardwareAccelerated) && + (walkBehindMethod != DrawOverCharSprite) && + (objcache[aa].image != nullptr) && + (objcache[aa].sppic == objs[aa].num) && + (actsps[useindx] != nullptr)) + { + // HW acceleration + objcache[aa].tintamntwas = tint_level; + objcache[aa].tintredwas = tint_red; + objcache[aa].tintgrnwas = tint_green; + objcache[aa].tintbluwas = tint_blue; + objcache[aa].tintlightwas = tint_light; + objcache[aa].lightlevwas = light_level; + objcache[aa].zoomWas = zoom_level; + objcache[aa].mirroredWas = isMirrored; + + return 1; + } + + if ((!hardwareAccelerated) && (gfxDriver->HasAcceleratedTransform())) + { + // They want to draw it in software mode with the D3D driver, + // so force a redraw + objcache[aa].sppic = -389538; + } + + // If we have the image cached, use it + if ((objcache[aa].image != nullptr) && + (objcache[aa].sppic == objs[aa].num) && + (objcache[aa].tintamntwas == tint_level) && + (objcache[aa].tintlightwas == tint_light) && + (objcache[aa].tintredwas == tint_red) && + (objcache[aa].tintgrnwas == tint_green) && + (objcache[aa].tintbluwas == tint_blue) && + (objcache[aa].lightlevwas == light_level) && + (objcache[aa].zoomWas == zoom_level) && + (objcache[aa].mirroredWas == isMirrored)) { + // the image is the same, we can use it cached! + if ((walkBehindMethod != DrawOverCharSprite) && + (actsps[useindx] != nullptr)) + return 1; + // Check if the X & Y co-ords are the same, too -- if so, there + // is scope for further optimisations + if ((objcache[aa].xwas == objs[aa].x) && + (objcache[aa].ywas == objs[aa].y) && + (actsps[useindx] != nullptr) && + (walk_behind_baselines_changed == 0)) + return 1; + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, sprwidth, sprheight); + actsps[useindx]->Blit(objcache[aa].image, 0, 0, 0, 0, objcache[aa].image->GetWidth(), objcache[aa].image->GetHeight()); + return 0; + } + + // Not cached, so draw the image + + int actspsUsed = 0; + if (!hardwareAccelerated) + { + // draw the base sprite, scaled and flipped as appropriate + actspsUsed = scale_and_flip_sprite(useindx, coldept, zoom_level, + objs[aa].num, sprwidth, sprheight, isMirrored); + } + else + { + // ensure actsps exists + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, game.SpriteInfos[objs[aa].num].Width, game.SpriteInfos[objs[aa].num].Height); + } + + // direct read from source bitmap, where possible + Bitmap *comeFrom = nullptr; + if (!actspsUsed) + comeFrom = spriteset[objs[aa].num]; + + // apply tints or lightenings where appropriate, else just copy + // the source bitmap + if (!hardwareAccelerated && ((tint_level > 0) || (light_level != 0))) + { + apply_tint_or_light(useindx, light_level, tint_level, tint_red, + tint_green, tint_blue, tint_light, coldept, + comeFrom); + } + else if (!actspsUsed) { + actsps[useindx]->Blit(spriteset[objs[aa].num],0,0,0,0,game.SpriteInfos[objs[aa].num].Width, game.SpriteInfos[objs[aa].num].Height); + } + + // Re-use the bitmap if it's the same size + objcache[aa].image = recycle_bitmap(objcache[aa].image, coldept, sprwidth, sprheight); + // Create the cached image and store it + objcache[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, sprwidth, sprheight); + objcache[aa].sppic = objs[aa].num; + objcache[aa].tintamntwas = tint_level; + objcache[aa].tintredwas = tint_red; + objcache[aa].tintgrnwas = tint_green; + objcache[aa].tintbluwas = tint_blue; + objcache[aa].tintlightwas = tint_light; + objcache[aa].lightlevwas = light_level; + objcache[aa].zoomWas = zoom_level; + objcache[aa].mirroredWas = isMirrored; + return 0; +} + + + + +// This is only called from draw_screen_background, but it's seperated +// to help with profiling the program +void prepare_objects_for_drawing() { + our_eip=32; + + for (int aa=0; aanumobj; aa++) { + if (objs[aa].on != 1) continue; + // offscreen, don't draw + if ((objs[aa].x >= thisroom.Width) || (objs[aa].y < 1)) + continue; + + const int useindx = aa; + int tehHeight; + int actspsIntact = construct_object_gfx(aa, nullptr, &tehHeight, false); + + // update the cache for next time + objcache[aa].xwas = objs[aa].x; + objcache[aa].ywas = objs[aa].y; + int atxp = data_to_game_coord(objs[aa].x); + int atyp = data_to_game_coord(objs[aa].y) - tehHeight; + + int usebasel = objs[aa].get_baseline(); + + if (objs[aa].flags & OBJF_NOWALKBEHINDS) { + // ignore walk-behinds, do nothing + if (walkBehindMethod == DrawAsSeparateSprite) + { + usebasel += thisroom.Height; + } + } + else if (walkBehindMethod == DrawAsSeparateCharSprite) + { + sort_out_char_sprite_walk_behind(useindx, atxp, atyp, usebasel, objs[aa].zoom, objs[aa].last_width, objs[aa].last_height); + } + else if ((!actspsIntact) && (walkBehindMethod == DrawOverCharSprite)) + { + sort_out_walk_behinds(actsps[useindx], atxp, atyp, usebasel); + } + + if ((!actspsIntact) || (actspsbmp[useindx] == nullptr)) + { + bool hasAlpha = (game.SpriteInfos[objs[aa].num].Flags & SPF_ALPHACHANNEL) != 0; + + if (actspsbmp[useindx] != nullptr) + gfxDriver->DestroyDDB(actspsbmp[useindx]); + actspsbmp[useindx] = gfxDriver->CreateDDBFromBitmap(actsps[useindx], hasAlpha); + } + + if (gfxDriver->HasAcceleratedTransform()) + { + actspsbmp[useindx]->SetFlippedLeftRight(objcache[aa].mirroredWas != 0); + actspsbmp[useindx]->SetStretch(objs[aa].last_width, objs[aa].last_height); + actspsbmp[useindx]->SetTint(objcache[aa].tintredwas, objcache[aa].tintgrnwas, objcache[aa].tintbluwas, (objcache[aa].tintamntwas * 256) / 100); + + if (objcache[aa].tintamntwas > 0) + { + if (objcache[aa].tintlightwas == 0) // luminance of 0 -- pass 1 to enable + actspsbmp[useindx]->SetLightLevel(1); + else if (objcache[aa].tintlightwas < 250) + actspsbmp[useindx]->SetLightLevel(objcache[aa].tintlightwas); + else + actspsbmp[useindx]->SetLightLevel(0); + } + else if (objcache[aa].lightlevwas != 0) + actspsbmp[useindx]->SetLightLevel((objcache[aa].lightlevwas * 25) / 10 + 256); + else + actspsbmp[useindx]->SetLightLevel(0); + } + + add_to_sprite_list(actspsbmp[useindx], atxp, atyp, usebasel, objs[aa].transparent,objs[aa].num); + } +} + + + +// Draws srcimg onto destimg, tinting to the specified level +// Totally overwrites the contents of the destination image +void tint_image (Bitmap *ds, Bitmap *srcimg, int red, int grn, int blu, int light_level, int luminance) { + + if ((srcimg->GetColorDepth() != ds->GetColorDepth()) || + (srcimg->GetColorDepth() <= 8)) { + debug_script_warn("Image tint failed - images must both be hi-color"); + // the caller expects something to have been copied + ds->Blit(srcimg, 0, 0, 0, 0, srcimg->GetWidth(), srcimg->GetHeight()); + return; + } + + // For performance reasons, we have a seperate blender for + // when light is being adjusted and when it is not. + // If luminance >= 250, then normal brightness, otherwise darken + if (luminance >= 250) + set_blender_mode (_myblender_color15, _myblender_color16, _myblender_color32, red, grn, blu, 0); + else + set_blender_mode (_myblender_color15_light, _myblender_color16_light, _myblender_color32_light, red, grn, blu, 0); + + if (light_level >= 100) { + // fully colourised + ds->FillTransparent(); + ds->LitBlendBlt(srcimg, 0, 0, luminance); + } + else { + // light_level is between -100 and 100 normally; 0-100 in + // this case when it's a RGB tint + light_level = (light_level * 25) / 10; + + // Copy the image to the new bitmap + ds->Blit(srcimg, 0, 0, 0, 0, srcimg->GetWidth(), srcimg->GetHeight()); + // Render the colourised image to a temporary bitmap, + // then transparently draw it over the original image + Bitmap *finaltarget = BitmapHelper::CreateTransparentBitmap(srcimg->GetWidth(), srcimg->GetHeight(), srcimg->GetColorDepth()); + finaltarget->LitBlendBlt(srcimg, 0, 0, luminance); + + // customized trans blender to preserve alpha channel + set_my_trans_blender (0, 0, 0, light_level); + ds->TransBlendBlt (finaltarget, 0, 0); + delete finaltarget; + } +} + + + + +void prepare_characters_for_drawing() { + int zoom_level,newwidth,newheight,onarea,sppic; + int light_level,coldept; + int tint_red, tint_green, tint_blue, tint_amount, tint_light = 255; + + our_eip=33; + + // draw characters + for (int aa=0; aa < game.numcharacters; aa++) { + if (game.chars[aa].on==0) continue; + if (game.chars[aa].room!=displayed_room) continue; + eip_guinum = aa; + const int useindx = aa + MAX_ROOM_OBJECTS; + + CharacterInfo*chin=&game.chars[aa]; + our_eip = 330; + // if it's on but set to view -1, they're being silly + if (chin->view < 0) { + quitprintf("!The character '%s' was turned on in the current room (room %d) but has not been assigned a view number.", + chin->name, displayed_room); + } + + if (chin->frame >= views[chin->view].loops[chin->loop].numFrames) + chin->frame = 0; + + if ((chin->loop >= views[chin->view].numLoops) || + (views[chin->view].loops[chin->loop].numFrames < 1)) { + quitprintf("!The character '%s' could not be displayed because there were no frames in loop %d of view %d.", + chin->name, chin->loop, chin->view + 1); + } + + sppic=views[chin->view].loops[chin->loop].frames[chin->frame].pic; + if (sppic < 0) + sppic = 0; // in case it's screwed up somehow + our_eip = 331; + // sort out the stretching if required + onarea = get_walkable_area_at_character (aa); + our_eip = 332; + + // calculate the zoom level + if (chin->flags & CHF_MANUALSCALING) // character ignores scaling + zoom_level = charextra[aa].zoom; + else if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) { + zoom_level = charextra[aa].zoom; + // NOTE: room objects don't have this fix + if (zoom_level == 0) + zoom_level = 100; + } + else + zoom_level = get_area_scaling (onarea, chin->x, chin->y); + + charextra[aa].zoom = zoom_level; + + tint_red = tint_green = tint_blue = tint_amount = tint_light = light_level = 0; + + if (chin->flags & CHF_HASTINT) { + // object specific tint, use it + tint_red = charextra[aa].tint_r; + tint_green = charextra[aa].tint_g; + tint_blue = charextra[aa].tint_b; + tint_amount = charextra[aa].tint_level; + tint_light = charextra[aa].tint_light; + light_level = 0; + } + else if (chin->flags & CHF_HASLIGHT) + { + light_level = charextra[aa].tint_light; + } + else { + get_local_tint(chin->x, chin->y, chin->flags & CHF_NOLIGHTING, + &tint_amount, &tint_red, &tint_green, &tint_blue, + &tint_light, &light_level); + } + + our_eip = 3330; + int isMirrored = 0, specialpic = sppic; + bool usingCachedImage = false; + + coldept = spriteset[sppic]->GetColorDepth(); + + // adjust the sppic if mirrored, so it doesn't accidentally + // cache the mirrored frame as the real one + if (views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE) { + isMirrored = 1; + specialpic = -sppic; + } + + our_eip = 3331; + + // if the character was the same sprite and scaling last time, + // just use the cached image + if ((charcache[aa].inUse) && + (charcache[aa].sppic == specialpic) && + (charcache[aa].scaling == zoom_level) && + (charcache[aa].tintredwas == tint_red) && + (charcache[aa].tintgrnwas == tint_green) && + (charcache[aa].tintbluwas == tint_blue) && + (charcache[aa].tintamntwas == tint_amount) && + (charcache[aa].tintlightwas == tint_light) && + (charcache[aa].lightlevwas == light_level)) + { + if (walkBehindMethod == DrawOverCharSprite) + { + actsps[useindx] = recycle_bitmap(actsps[useindx], charcache[aa].image->GetColorDepth(), charcache[aa].image->GetWidth(), charcache[aa].image->GetHeight()); + actsps[useindx]->Blit (charcache[aa].image, 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + } + else + { + usingCachedImage = true; + } + } + else if ((charcache[aa].inUse) && + (charcache[aa].sppic == specialpic) && + (gfxDriver->HasAcceleratedTransform())) + { + usingCachedImage = true; + } + else if (charcache[aa].inUse) { + //destroy_bitmap (charcache[aa].image); + charcache[aa].inUse = 0; + } + + our_eip = 3332; + + if (zoom_level != 100) { + // it needs to be stretched, so calculate the new dimensions + + scale_sprite_size(sppic, zoom_level, &newwidth, &newheight); + charextra[aa].width=newwidth; + charextra[aa].height=newheight; + } + else { + // draw at original size, so just use the sprite width and height + // TODO: store width and height always, that's much simplier to use for reference! + charextra[aa].width=0; + charextra[aa].height=0; + newwidth = game.SpriteInfos[sppic].Width; + newheight = game.SpriteInfos[sppic].Height; + } + + our_eip = 3336; + + // Calculate the X & Y co-ordinates of where the sprite will be + const int atxp =(data_to_game_coord(chin->x)) - newwidth/2; + const int atyp =(data_to_game_coord(chin->y) - newheight) + // adjust the Y positioning for the character's Z co-ord + - data_to_game_coord(chin->z); + + charcache[aa].scaling = zoom_level; + charcache[aa].sppic = specialpic; + charcache[aa].tintredwas = tint_red; + charcache[aa].tintgrnwas = tint_green; + charcache[aa].tintbluwas = tint_blue; + charcache[aa].tintamntwas = tint_amount; + charcache[aa].tintlightwas = tint_light; + charcache[aa].lightlevwas = light_level; + + // If cache needs to be re-drawn + if (!charcache[aa].inUse) { + + // create the base sprite in actsps[useindx], which will + // be scaled and/or flipped, as appropriate + int actspsUsed = 0; + if (!gfxDriver->HasAcceleratedTransform()) + { + actspsUsed = scale_and_flip_sprite( + useindx, coldept, zoom_level, sppic, + newwidth, newheight, isMirrored); + } + else + { + // ensure actsps exists + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, game.SpriteInfos[sppic].Width, game.SpriteInfos[sppic].Height); + } + + our_eip = 335; + + if (((light_level != 0) || (tint_amount != 0)) && + (!gfxDriver->HasAcceleratedTransform())) { + // apply the lightening or tinting + Bitmap *comeFrom = nullptr; + // if possible, direct read from the source image + if (!actspsUsed) + comeFrom = spriteset[sppic]; + + apply_tint_or_light(useindx, light_level, tint_amount, tint_red, + tint_green, tint_blue, tint_light, coldept, + comeFrom); + } + else if (!actspsUsed) { + // no scaling, flipping or tinting was done, so just blit it normally + actsps[useindx]->Blit (spriteset[sppic], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + } + + // update the character cache with the new image + charcache[aa].inUse = 1; + //charcache[aa].image = BitmapHelper::CreateBitmap_ (coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + charcache[aa].image = recycle_bitmap(charcache[aa].image, coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + charcache[aa].image->Blit (actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + + } // end if !cache.inUse + + int usebasel = chin->get_baseline(); + + our_eip = 336; + + const int bgX = atxp + chin->pic_xoffs; + const int bgY = atyp + chin->pic_yoffs; + + if (chin->flags & CHF_NOWALKBEHINDS) { + // ignore walk-behinds, do nothing + if (walkBehindMethod == DrawAsSeparateSprite) + { + usebasel += thisroom.Height; + } + } + else if (walkBehindMethod == DrawAsSeparateCharSprite) + { + sort_out_char_sprite_walk_behind(useindx, bgX, bgY, usebasel, charextra[aa].zoom, newwidth, newheight); + } + else if (walkBehindMethod == DrawOverCharSprite) + { + sort_out_walk_behinds(actsps[useindx], bgX, bgY, usebasel); + } + + if ((!usingCachedImage) || (actspsbmp[useindx] == nullptr)) + { + bool hasAlpha = (game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) != 0; + + actspsbmp[useindx] = recycle_ddb_bitmap(actspsbmp[useindx], actsps[useindx], hasAlpha); + } + + if (gfxDriver->HasAcceleratedTransform()) + { + actspsbmp[useindx]->SetStretch(newwidth, newheight); + actspsbmp[useindx]->SetFlippedLeftRight(isMirrored != 0); + actspsbmp[useindx]->SetTint(tint_red, tint_green, tint_blue, (tint_amount * 256) / 100); + + if (tint_amount != 0) + { + if (tint_light == 0) // tint with 0 luminance, pass as 1 instead + actspsbmp[useindx]->SetLightLevel(1); + else if (tint_light < 250) + actspsbmp[useindx]->SetLightLevel(tint_light); + else + actspsbmp[useindx]->SetLightLevel(0); + } + else if (light_level != 0) + actspsbmp[useindx]->SetLightLevel((light_level * 25) / 10 + 256); + else + actspsbmp[useindx]->SetLightLevel(0); + + } + + our_eip = 337; + + chin->actx = atxp; + chin->acty = atyp; + + add_to_sprite_list(actspsbmp[useindx], bgX, bgY, usebasel, chin->transparency, sppic); + } +} + + +// Compiles a list of room sprites (characters, objects, background) +void prepare_room_sprites() +{ + // Background sprite is required for the non-software renderers always, + // and for software renderer in case there are overlapping viewports. + // Note that software DDB is just a tiny wrapper around bitmap, so overhead is negligible. + if (roomBackgroundBmp == nullptr) + { + update_polled_stuff_if_runtime(); + roomBackgroundBmp = gfxDriver->CreateDDBFromBitmap(thisroom.BgFrames[play.bg_frame].Graphic.get(), false, true); + } + else if (current_background_is_dirty) + { + update_polled_stuff_if_runtime(); + gfxDriver->UpdateDDBFromBitmap(roomBackgroundBmp, thisroom.BgFrames[play.bg_frame].Graphic.get(), false); + } + if (gfxDriver->RequiresFullRedrawEachFrame()) + { + if (current_background_is_dirty || walkBehindsCachedForBgNum != play.bg_frame) + { + if (walkBehindMethod == DrawAsSeparateSprite) + { + update_walk_behind_images(); + } + } + add_thing_to_draw(roomBackgroundBmp, 0, 0, 0, false); + } + current_background_is_dirty = false; // Note this is only place where this flag is checked + + clear_sprite_list(); + + if ((debug_flags & DBG_NOOBJECTS) == 0) + { + prepare_objects_for_drawing(); + prepare_characters_for_drawing(); + + if ((debug_flags & DBG_NODRAWSPRITES) == 0) + { + our_eip = 34; + draw_sprite_list(); + } + } + our_eip = 36; +} + +// Draws the black surface behind (or rather between) the room viewports +void draw_preroom_background() +{ + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + update_black_invreg_and_reset(gfxDriver->GetMemoryBackBuffer()); +} + +// Draws the room background on the given surface. +// +// NOTE that this is **strictly** for software rendering. +// ds is a full game screen surface, and roomcam_surface is a surface for drawing room camera content to. +// ds and roomcam_surface may be the same bitmap. +// no_transform flag tells to copy dirty regions on roomcam_surface without any coordinate conversion +// whatsoever. +PBitmap draw_room_background(Viewport *view, const SpriteTransform &room_trans) +{ + our_eip = 31; + + // For the sake of software renderer, if there is any kind of camera transform required + // except screen offset, we tell it to draw on separate bitmap first with zero transformation. + // There are few reasons for this, primary is that Allegro does not support StretchBlt + // between different colour depths (i.e. it won't correctly stretch blit 16-bit rooms to + // 32-bit virtual screen). + // Also see comment to ALSoftwareGraphicsDriver::RenderToBackBuffer(). + const int view_index = view->GetID(); + Bitmap *ds = gfxDriver->GetMemoryBackBuffer(); + // If separate bitmap was prepared for this view/camera pair then use it, draw untransformed + // and blit transformed whole surface later. + const bool draw_to_camsurf = CameraDrawData[view_index].Frame != nullptr; + Bitmap *roomcam_surface = draw_to_camsurf ? CameraDrawData[view_index].Frame.get() : ds; + { + // For software renderer: copy dirty rects onto the virtual screen. + // TODO: that would be SUPER NICE to reorganize the code and move this operation into SoftwareGraphicDriver somehow. + // Because basically we duplicate sprite batch transform here. + + auto camera = view->GetCamera(); + set_invalidrects_cameraoffs(view_index, camera->GetRect().Left, camera->GetRect().Top); + + // TODO: (by CJ) + // the following line takes up to 50% of the game CPU time at + // high resolutions and colour depths - if we can optimise it + // somehow, significant performance gains to be had + update_room_invreg_and_reset(view_index, roomcam_surface, thisroom.BgFrames[play.bg_frame].Graphic.get(), draw_to_camsurf); + } + + return CameraDrawData[view_index].Frame; +} + + +void draw_fps(const Rect &viewport) +{ + // TODO: make allocated "fps struct" instead of using static vars!! + static IDriverDependantBitmap* ddb = nullptr; + static Bitmap *fpsDisplay = nullptr; + const int font = FONT_NORMAL; + if (fpsDisplay == nullptr) + { + fpsDisplay = BitmapHelper::CreateBitmap(viewport.GetWidth(), (getfontheight_outlined(font) + get_fixed_pixel_size(5)), game.GetColorDepth()); + fpsDisplay = ReplaceBitmapWithSupportedFormat(fpsDisplay); + } + fpsDisplay->ClearTransparent(); + + color_t text_color = fpsDisplay->GetCompatibleColor(14); + + char base_buffer[20]; + if (!isTimerFpsMaxed()) { + sprintf(base_buffer, "%d", frames_per_second); + } else { + sprintf(base_buffer, "unlimited"); + } + + char fps_buffer[60]; + // Don't display fps if we don't have enough information (because loop count was just reset) + if (!std::isnan(fps)) { + snprintf(fps_buffer, sizeof(fps_buffer), "FPS: %2.1f / %s", fps, base_buffer); + } else { + snprintf(fps_buffer, sizeof(fps_buffer), "FPS: --.- / %s", base_buffer); + } + wouttext_outline(fpsDisplay, 1, 1, font, text_color, fps_buffer); + + char loop_buffer[60]; + sprintf(loop_buffer, "Loop %u", loopcounter); + wouttext_outline(fpsDisplay, viewport.GetWidth() / 2, 1, font, text_color, loop_buffer); + + if (ddb) + gfxDriver->UpdateDDBFromBitmap(ddb, fpsDisplay, false); + else + ddb = gfxDriver->CreateDDBFromBitmap(fpsDisplay, false); + int yp = viewport.GetHeight() - fpsDisplay->GetHeight(); + gfxDriver->DrawSprite(1, yp, ddb); + invalidate_sprite(1, yp, ddb, false); +} + +// Draw GUI and overlays of all kinds, anything outside the room space +void draw_gui_and_overlays() +{ + if(pl_any_want_hook(AGSE_PREGUIDRAW)) + add_thing_to_draw(nullptr, AGSE_PREGUIDRAW, 0, TRANS_RUN_PLUGIN, false); + + // draw overlays, except text boxes and portraits + for (const auto &over : screenover) { + // complete overlay draw in non-transparent mode + if (over.type == OVER_COMPLETE) + add_thing_to_draw(over.bmp, over.x, over.y, TRANS_OPAQUE, false); + else if (over.type != OVER_TEXTMSG && over.type != OVER_PICTURE) { + int tdxp, tdyp; + get_overlay_position(over, &tdxp, &tdyp); + add_thing_to_draw(over.bmp, tdxp, tdyp, 0, over.hasAlphaChannel); + } + } + + // Draw GUIs - they should always be on top of overlays like + // speech background text + our_eip=35; + if (((debug_flags & DBG_NOIFACE)==0) && (displayed_room >= 0)) { + int aa; + + if (playerchar->activeinv >= MAX_INV) { + quit("!The player.activeinv variable has been corrupted, probably as a result\n" + "of an incorrect assignment in the game script."); + } + if (playerchar->activeinv < 1) gui_inv_pic=-1; + else gui_inv_pic=game.invinfo[playerchar->activeinv].pic; + our_eip = 37; + if (guis_need_update) { + guis_need_update = 0; + for (aa=0;aaClearTransparent(); + our_eip = 372; + guis[aa].DrawAt(guibg[aa], 0,0); + our_eip = 373; + + bool isAlpha = false; + if (guis[aa].HasAlphaChannel()) + { + isAlpha = true; + + if ((game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Legacy) && (guis[aa].BgImage > 0)) + { + // old-style (pre-3.0.2) GUI alpha rendering + repair_alpha_channel(guibg[aa], spriteset[guis[aa].BgImage]); + } + } + + if (guibgbmp[aa] != nullptr) + { + gfxDriver->UpdateDDBFromBitmap(guibgbmp[aa], guibg[aa], isAlpha); + } + else + { + guibgbmp[aa] = gfxDriver->CreateDDBFromBitmap(guibg[aa], isAlpha); + } + our_eip = 374; + } + } + our_eip = 38; + // Draw the GUIs + for (int gg = 0; gg < game.numgui; gg++) { + aa = play.gui_draw_order[gg]; + if (!guis[aa].IsDisplayed()) continue; + + // Don't draw GUI if "GUIs Turn Off When Disabled" + if ((game.options[OPT_DISABLEOFF] == 3) && + (all_buttons_disabled > 0) && + (guis[aa].PopupStyle != kGUIPopupNoAutoRemove)) + continue; + + add_thing_to_draw(guibgbmp[aa], guis[aa].X, guis[aa].Y, guis[aa].Transparency, guis[aa].HasAlphaChannel()); + + // only poll if the interface is enabled (mouseovers should not + // work while in Wait state) + if (IsInterfaceEnabled()) + guis[aa].Poll(); + } + } + + // draw speech and portraits (so that they appear over GUIs) + for (const auto &over : screenover) + { + if (over.type == OVER_TEXTMSG || over.type == OVER_PICTURE) + { + int tdxp, tdyp; + get_overlay_position(over, &tdxp, &tdyp); + add_thing_to_draw(over.bmp, tdxp, tdyp, 0, false); + } + } + + our_eip = 1099; +} + +// Push the gathered list of sprites into the active graphic renderer +void put_sprite_list_on_screen(bool in_room) +{ + // *** Draw the Things To Draw List *** + + SpriteListEntry *thisThing; + + for (size_t i = 0; i < thingsToDrawList.size(); ++i) + { + thisThing = &thingsToDrawList[i]; + + if (thisThing->bmp != nullptr) { + // mark the image's region as dirty + invalidate_sprite(thisThing->x, thisThing->y, thisThing->bmp, in_room); + } + else if ((thisThing->transparent != TRANS_RUN_PLUGIN) && + (thisThing->bmp == nullptr)) + { + quit("Null pointer added to draw list"); + } + + if (thisThing->bmp != nullptr) + { + if (thisThing->transparent <= 255) + { + thisThing->bmp->SetTransparency(thisThing->transparent); + } + + gfxDriver->DrawSprite(thisThing->x, thisThing->y, thisThing->bmp); + } + else if (thisThing->transparent == TRANS_RUN_PLUGIN) + { + // meta entry to run the plugin hook + gfxDriver->DrawSprite(thisThing->x, thisThing->y, nullptr); + } + else + quit("Unknown entry in draw list"); + } + + our_eip = 1100; +} + +bool GfxDriverNullSpriteCallback(int x, int y) +{ + if (displayed_room < 0) + { + // if no room loaded, various stuff won't be initialized yet + return 1; + } + return (pl_run_plugin_hooks(x, y) != 0); +} + +void GfxDriverOnInitCallback(void *data) +{ + pl_run_plugin_init_gfx_hooks(gfxDriver->GetDriverID(), data); +} + +// Schedule room rendering: background, objects, characters +static void construct_room_view() +{ + draw_preroom_background(); + prepare_room_sprites(); + // reset the Baselines Changed flag now that we've drawn stuff + walk_behind_baselines_changed = 0; + + for (const auto &viewport : play.GetRoomViewportsZOrdered()) + { + if (!viewport->IsVisible()) + continue; + auto camera = viewport->GetCamera(); + if (!camera) + continue; + const Rect &view_rc = play.GetRoomViewportAbs(viewport->GetID()); + const Rect &cam_rc = camera->GetRect(); + SpriteTransform room_trans(-cam_rc.Left, -cam_rc.Top, + (float)view_rc.GetWidth() / (float)cam_rc.GetWidth(), + (float)view_rc.GetHeight() / (float)cam_rc.GetHeight(), + 0.f); + if (gfxDriver->RequiresFullRedrawEachFrame()) + { // we draw everything as a sprite stack + gfxDriver->BeginSpriteBatch(view_rc, room_trans, Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + } + else + { + if (CameraDrawData[viewport->GetID()].Frame == nullptr && CameraDrawData[viewport->GetID()].IsOverlap) + { // room background is prepended to the sprite stack + // TODO: here's why we have blit whole piece of background now: + // if we draw directly to the virtual screen overlapping another + // viewport, then we'd have to also mark and repaint every our + // region located directly over their dirty regions. That would + // require to update regions up the stack, converting their + // coordinates (cam1 -> screen -> cam2). + // It's not clear whether this is worth the effort, but if it is, + // then we'd need to optimise view/cam data first. + gfxDriver->BeginSpriteBatch(view_rc, room_trans); + gfxDriver->DrawSprite(0, 0, roomBackgroundBmp); + } + else + { // room background is drawn by dirty rects system + PBitmap bg_surface = draw_room_background(viewport.get(), room_trans); + gfxDriver->BeginSpriteBatch(view_rc, room_trans, Point(), kFlip_None, bg_surface); + } + } + put_sprite_list_on_screen(true); + } + + clear_draw_list(); +} + +// Schedule ui rendering +static void construct_ui_view() +{ + gfxDriver->BeginSpriteBatch(play.GetUIViewportAbs(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + draw_gui_and_overlays(); + put_sprite_list_on_screen(false); + clear_draw_list(); +} + +void construct_game_scene(bool full_redraw) +{ + gfxDriver->ClearDrawLists(); + + if (play.fast_forward) + return; + + our_eip=3; + + // React to changes to viewports and cameras (possibly from script) just before the render + play.UpdateViewports(); + + gfxDriver->UseSmoothScaling(IS_ANTIALIAS_SPRITES); + gfxDriver->RenderSpritesAtScreenResolution(usetup.RenderAtScreenRes, usetup.Supersampling); + + pl_run_plugin_hooks(AGSE_PRERENDER, 0); + + // Possible reasons to invalidate whole screen for the software renderer + if (full_redraw || play.screen_tint > 0 || play.shakesc_length > 0) + invalidate_screen(); + + // TODO: move to game update! don't call update during rendering pass! + // IMPORTANT: keep the order same because sometimes script may depend on it + if (displayed_room >= 0) + play.UpdateRoomCameras(); + + // Stage: room viewports + if (play.screen_is_faded_out == 0 && is_complete_overlay == 0) + { + if (displayed_room >= 0) + { + construct_room_view(); + update_polled_mp3(); + } + else if (!gfxDriver->RequiresFullRedrawEachFrame()) + { + // black it out so we don't get cursor trails + // TODO: this is possible to do with dirty rects system now too (it can paint black rects outside of room viewport) + gfxDriver->GetMemoryBackBuffer()->Fill(0); + } + } + + our_eip=4; + + // Stage: UI overlay + if (play.screen_is_faded_out == 0) + { + construct_ui_view(); + } +} + +void construct_game_screen_overlay(bool draw_mouse) +{ + gfxDriver->BeginSpriteBatch(play.GetMainViewport(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + if (pl_any_want_hook(AGSE_POSTSCREENDRAW)) + gfxDriver->DrawSprite(AGSE_POSTSCREENDRAW, 0, nullptr); + + // TODO: find out if it's okay to move cursor animation and state update + // to the update loop instead of doing it in the drawing routine + // update animating mouse cursor + if (game.mcurs[cur_cursor].view >= 0) { + ags_domouse(DOMOUSE_NOCURSOR); + // only on mousemove, and it's not moving + if (((game.mcurs[cur_cursor].flags & MCF_ANIMMOVE) != 0) && + (mousex == lastmx) && (mousey == lastmy)); + // only on hotspot, and it's not on one + else if (((game.mcurs[cur_cursor].flags & MCF_HOTSPOT) != 0) && + (GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey)) == 0)) + set_new_cursor_graphic(game.mcurs[cur_cursor].pic); + else if (mouse_delay>0) mouse_delay--; + else { + int viewnum = game.mcurs[cur_cursor].view; + int loopnum = 0; + if (loopnum >= views[viewnum].numLoops) + quitprintf("An animating mouse cursor is using view %d which has no loops", viewnum + 1); + if (views[viewnum].loops[loopnum].numFrames < 1) + quitprintf("An animating mouse cursor is using view %d which has no frames in loop %d", viewnum + 1, loopnum); + + mouse_frame++; + if (mouse_frame >= views[viewnum].loops[loopnum].numFrames) + mouse_frame = 0; + set_new_cursor_graphic(views[viewnum].loops[loopnum].frames[mouse_frame].pic); + mouse_delay = views[viewnum].loops[loopnum].frames[mouse_frame].speed + 5; + CheckViewFrame(viewnum, loopnum, mouse_frame); + } + lastmx = mousex; lastmy = mousey; + } + + ags_domouse(DOMOUSE_NOCURSOR); + + // Stage: mouse cursor + if (draw_mouse && !play.mouse_cursor_hidden && play.screen_is_faded_out == 0) + { + gfxDriver->DrawSprite(mousex - hotx, mousey - hoty, mouseCursor); + invalidate_sprite(mousex - hotx, mousey - hoty, mouseCursor, false); + } + + if (play.screen_is_faded_out == 0) + { + // Stage: screen fx + if (play.screen_tint >= 1) + gfxDriver->SetScreenTint(play.screen_tint & 0xff, (play.screen_tint >> 8) & 0xff, (play.screen_tint >> 16) & 0xff); + // Stage: legacy letterbox mode borders + render_black_borders(); + } + + if (play.screen_is_faded_out != 0 && gfxDriver->RequiresFullRedrawEachFrame()) + { + const Rect &main_viewport = play.GetMainViewport(); + gfxDriver->BeginSpriteBatch(main_viewport, SpriteTransform()); + gfxDriver->SetScreenFade(play.fade_to_red, play.fade_to_green, play.fade_to_blue); + } +} + +void construct_engine_overlay() +{ + const Rect &viewport = RectWH(game.GetGameRes()); + gfxDriver->BeginSpriteBatch(viewport, SpriteTransform()); + + // draw the debug console, if appropriate + if ((play.debug_mode > 0) && (display_console != 0)) + { + const int font = FONT_NORMAL; + int ypp = 1; + int txtspacing = getfontspacing_outlined(font); + int barheight = getheightoflines(font, DEBUG_CONSOLE_NUMLINES - 1) + 4; + + if (debugConsoleBuffer == nullptr) + { + debugConsoleBuffer = BitmapHelper::CreateBitmap(viewport.GetWidth(), barheight, game.GetColorDepth()); + debugConsoleBuffer = ReplaceBitmapWithSupportedFormat(debugConsoleBuffer); + } + + color_t draw_color = debugConsoleBuffer->GetCompatibleColor(15); + debugConsoleBuffer->FillRect(Rect(0, 0, viewport.GetWidth() - 1, barheight), draw_color); + color_t text_color = debugConsoleBuffer->GetCompatibleColor(16); + for (int jj = first_debug_line; jj != last_debug_line; jj = (jj + 1) % DEBUG_CONSOLE_NUMLINES) { + wouttextxy(debugConsoleBuffer, 1, ypp, font, text_color, debug_line[jj]); + ypp += txtspacing; + } + + if (debugConsole == nullptr) + debugConsole = gfxDriver->CreateDDBFromBitmap(debugConsoleBuffer, false, true); + else + gfxDriver->UpdateDDBFromBitmap(debugConsole, debugConsoleBuffer, false); + + gfxDriver->DrawSprite(0, 0, debugConsole); + invalidate_sprite(0, 0, debugConsole, false); + } + + if (display_fps != kFPS_Hide) + draw_fps(viewport); +} + +static void update_shakescreen() +{ + // TODO: unify blocking and non-blocking shake update + play.shake_screen_yoff = 0; + if (play.shakesc_length > 0) + { + if ((loopcounter % play.shakesc_delay) < (play.shakesc_delay / 2)) + play.shake_screen_yoff = play.shakesc_amount; + } +} + +// Draw everything +void render_graphics(IDriverDependantBitmap *extraBitmap, int extraX, int extraY) +{ + // Don't render if skipping cutscene + if (play.fast_forward) + return; + // Don't render if we've just entered new room and are before fade-in + // TODO: find out why this is not skipped for 8-bit games + if ((in_new_room > 0) & (game.color_depth > 1)) + return; + + // TODO: find out if it's okay to move shake to update function + update_shakescreen(); + + construct_game_scene(false); + our_eip=5; + // NOTE: extraBitmap will always be drawn with the UI render stage + if (extraBitmap != nullptr) + { + invalidate_sprite(extraX, extraY, extraBitmap, false); + gfxDriver->DrawSprite(extraX, extraY, extraBitmap); + } + construct_game_screen_overlay(true); + render_to_screen(); + + if (!play.screen_is_faded_out) { + // always update the palette, regardless of whether the plugin + // vetos the screen update + if (bg_just_changed) { + setpal(); + bg_just_changed = 0; + } + } + + screen_is_dirty = false; +} diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h new file mode 100644 index 000000000000..af6e8e935493 --- /dev/null +++ b/engines/ags/engine/ac/draw.h @@ -0,0 +1,175 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__DRAW_H +#define __AGS_EE_AC__DRAW_H + +#include +#include "core/types.h" +#include "ac/common_defines.h" +#include "gfx/gfx_def.h" +#include "util/wgt2allg.h" + +namespace AGS +{ + namespace Common + { + class Bitmap; + typedef std::shared_ptr PBitmap; + } + namespace Engine { class IDriverDependantBitmap; } +} +using namespace AGS; // FIXME later + +#define IS_ANTIALIAS_SPRITES usetup.enable_antialiasing && (play.disable_antialiasing == 0) + +// [IKM] WARNING: these definitions has to be made AFTER Allegro headers +// were included, because they override few Allegro function names; +// otherwise Allegro headers should not be included at all to the same +// code unit which uses these defines. +#define getr32(xx) ((xx >> _rgb_r_shift_32) & 0xFF) +#define getg32(xx) ((xx >> _rgb_g_shift_32) & 0xFF) +#define getb32(xx) ((xx >> _rgb_b_shift_32) & 0xFF) +#define geta32(xx) ((xx >> _rgb_a_shift_32) & 0xFF) +#define makeacol32(r,g,b,a) ((r << _rgb_r_shift_32) | (g << _rgb_g_shift_32) | (b << _rgb_b_shift_32) | (a << _rgb_a_shift_32)) + + +struct CachedActSpsData { + int xWas, yWas; + int baselineWas; + int isWalkBehindHere; + int valid; +}; + +// Converts AGS color index to the actual bitmap color using game's color depth +int MakeColor(int color_index); + +class Viewport; +class Camera; + +// Initializes drawing methods and optimisation +void init_draw_method(); +// Initializes drawing resources upon entering new room +void init_room_drawdata(); +// Disposes resources related to the current drawing methods +void dispose_draw_method(); +// Disposes any temporary resources on leaving current room +void dispose_room_drawdata(); +// Updates drawing settings depending on main viewport's size and position on screen +void on_mainviewport_changed(); +// Notifies that a new room viewport was created +void on_roomviewport_created(int index); +// Notifies that a new room viewport was deleted +void on_roomviewport_deleted(int index); +// Updates drawing settings if room viewport's position or size has changed +void on_roomviewport_changed(Viewport *view); +// Detects overlapping viewports, starting from the given index in z-sorted array +void detect_roomviewport_overlaps(size_t z_index); +// Updates drawing settings if room camera's size has changed +void on_roomcamera_changed(Camera *cam); + +// whether there are currently remnants of a DisplaySpeech +void mark_screen_dirty(); +bool is_screen_dirty(); + +// marks whole screen as needing a redraw +void invalidate_screen(); +// marks all the camera frame as needing a redraw +void invalidate_camera_frame(int index); +// marks certain rectangle on screen as needing a redraw +// in_room flag tells how to interpret the coordinates: as in-room coords or screen viewport coordinates. +void invalidate_rect(int x1, int y1, int x2, int y2, bool in_room); + +void mark_current_background_dirty(); +void invalidate_cached_walkbehinds(); +// Avoid freeing and reallocating the memory if possible +Common::Bitmap *recycle_bitmap(Common::Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent = false); +Engine::IDriverDependantBitmap* recycle_ddb_bitmap(Engine::IDriverDependantBitmap *bimp, Common::Bitmap *source, bool hasAlpha = false, bool opaque = false); +// Draw everything +void render_graphics(Engine::IDriverDependantBitmap *extraBitmap = nullptr, int extraX = 0, int extraY = 0); +// Construct game scene, scheduling drawing list for the renderer +void construct_game_scene(bool full_redraw = false); +// Construct final game screen elements; updates and draws mouse cursor +void construct_game_screen_overlay(bool draw_mouse = true); +// Construct engine overlay with debugging tools (fps, console) +void construct_engine_overlay(); +void add_to_sprite_list(Engine::IDriverDependantBitmap* spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind = false); +void tint_image (Common::Bitmap *g, Common::Bitmap *source, int red, int grn, int blu, int light_level, int luminance=255); +void draw_sprite_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Common::Bitmap *image, bool src_has_alpha, + Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); +void draw_sprite_slot_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot, + Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); +void draw_gui_sprite(Common::Bitmap *ds, int pic, int x, int y, bool use_alpha, Common::BlendMode blend_mode); +void draw_gui_sprite_v330(Common::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Common::BlendMode blend_mode = Common::kBlendMode_Alpha); +// Render game on screen +void render_to_screen(); +// Callbacks for the graphics driver +void draw_game_screen_callback(); +void GfxDriverOnInitCallback(void *data); +bool GfxDriverNullSpriteCallback(int x, int y); +void putpixel_compensate (Common::Bitmap *g, int xx,int yy, int col); +// create the actsps[aa] image with the object drawn correctly +// returns 1 if nothing at all has changed and actsps is still +// intact from last time; 0 otherwise +int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysUseSoftware); +void clear_letterbox_borders(); + +void draw_and_invalidate_text(Common::Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text); + +void setpal(); + +// These functions are converting coordinates between data resolution and +// game resolution units. The first are units used by game data and script, +// and second define the game's screen resolution, sprite and font sizes. +// This conversion is done before anything else (like moving from room to +// viewport on screen, or scaling game further in the window by the graphic +// renderer). +extern AGS_INLINE int get_fixed_pixel_size(int pixels); +// coordinate conversion data,script ---> final game resolution +extern AGS_INLINE int data_to_game_coord(int coord); +extern AGS_INLINE void data_to_game_coords(int *x, int *y); +extern AGS_INLINE void data_to_game_round_up(int *x, int *y); +// coordinate conversion final game resolution ---> data,script +extern AGS_INLINE int game_to_data_coord(int coord); +extern AGS_INLINE void game_to_data_coords(int &x, int &y); +extern AGS_INLINE int game_to_data_round_up(int coord); +// convert contextual data coordinates to final game resolution +extern AGS_INLINE void ctx_data_to_game_coord(int &x, int &y, bool hires_ctx); +extern AGS_INLINE void ctx_data_to_game_size(int &x, int &y, bool hires_ctx); +extern AGS_INLINE int ctx_data_to_game_size(int size, bool hires_ctx); +extern AGS_INLINE int game_to_ctx_data_size(int size, bool hires_ctx); +// This function converts game coordinates coming from script to the actual game resolution. +extern AGS_INLINE void defgame_to_finalgame_coords(int &x, int &y); + +// Checks if the bitmap needs to be converted and **deletes original** if a new bitmap +// had to be created (by default). +// TODO: this helper function was meant to remove bitmap deletion from the GraphicsDriver's +// implementations while keeping code changes to minimum. The proper solution would probably +// be to use shared pointers when storing Bitmaps, or make Bitmap reference-counted object. +Common::Bitmap *ReplaceBitmapWithSupportedFormat(Common::Bitmap *bitmap); +// Checks if the bitmap needs any kind of adjustments before it may be used +// in AGS sprite operations. Also handles number of certain special cases +// (old systems or uncommon gfx modes, and similar stuff). +// Original bitmap **gets deleted** if a new bitmap had to be created. +Common::Bitmap *PrepareSpriteForUse(Common::Bitmap *bitmap, bool has_alpha); +// Same as above, but compatible for std::shared_ptr. +Common::PBitmap PrepareSpriteForUse(Common::PBitmap bitmap, bool has_alpha); +// Makes a screenshot corresponding to the last screen render and returns it as a bitmap +// of the requested width and height and game's native color depth. +Common::Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res = false); + +#endif // __AGS_EE_AC__DRAW_H diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp new file mode 100644 index 000000000000..721b676924f6 --- /dev/null +++ b/engines/ags/engine/ac/draw_software.cpp @@ -0,0 +1,491 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Software drawing component. Optimizes drawing for software renderer using +// dirty rectangles technique. +// +// TODO: do research/profiling to find out if this dirty rectangles thing +// is still giving ANY notable perfomance boost at all. +// +// TODO: would that give any benefit to reorganize the code and move dirty +// rectangles into SoftwareGraphicDriver? +// Alternatively: we could pass dirty rects struct pointer and room background +// DDB when calling BeginSpriteBatch(). Driver itself could be calling +// update_invalid_region(). That will keep gfx driver's changes to minimum. +// +// NOTE: this code, including structs and functions, has underwent several +// iterations of changes. Originally it was meant to perform full transform +// of dirty rects right away, but later I realized it won't work that way +// because a) Allegro does not support scaling bitmaps over destination with +// different colour depth (which may be a case when running 16-bit game), +// and b) Allegro does not support scaling and rotating of sprites with +// blending and lighting at the same time which means that room objects have +// to be drawn upon non-scaled background first. Possibly some of the code +// below may be therefore simplified. +// +//============================================================================= + +#include +#include +#include "ac/draw_software.h" +#include "gfx/bitmap.h" +#include "util/scaling.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +// TODO: choose these values depending on game resolution? +#define MAXDIRTYREGIONS 25 +#define WHOLESCREENDIRTY (MAXDIRTYREGIONS + 5) +#define MAX_SPANS_PER_ROW 4 + +// Dirty rects store coordinate values in the coordinate system of a camera surface, +// where coords always span from 0,0 to surface width,height. +// Converting from room to dirty rects would require subtracting room camera offsets. +struct IRSpan +{ + int x1, x2; + int mergeSpan(int tx1, int tx2); + + IRSpan(); +}; + +struct IRRow +{ + IRSpan span[MAX_SPANS_PER_ROW]; + int numSpans; + + IRRow(); +}; + +struct DirtyRects +{ + // Size of the surface managed by this dirty rects object + Size SurfaceSize; + // Where the surface is rendered on screen + Rect Viewport; + // Room -> screen coordinate transformation + PlaneScaling Room2Screen; + // Screen -> dirty surface rect + // The dirty rects are saved in coordinates limited to (0,0)->(camera size) rather than room or screen coords + PlaneScaling Screen2DirtySurf; + + std::vector DirtyRows; + Rect DirtyRegions[MAXDIRTYREGIONS]; + size_t NumDirtyRegions; + + DirtyRects(); + bool IsInit() const; + // Initialize dirty rects for the given surface size + void Init(const Size &surf_size, const Rect &viewport); + void SetSurfaceOffsets(int x, int y); + // Delete dirty rects + void Destroy(); + // Mark all surface as tidy + void Reset(); +}; + + +IRSpan::IRSpan() + : x1(0), x2(0) +{ +} + +IRRow::IRRow() + : numSpans(0) +{ +} + +int IRSpan::mergeSpan(int tx1, int tx2) +{ + if ((tx1 > x2) || (tx2 < x1)) + return 0; + // overlapping, increase the span + if (tx1 < x1) + x1 = tx1; + if (tx2 > x2) + x2 = tx2; + return 1; +} + +DirtyRects::DirtyRects() + : NumDirtyRegions(0) +{ +} + +bool DirtyRects::IsInit() const +{ + return DirtyRows.size() > 0; +} + +void DirtyRects::Init(const Size &surf_size, const Rect &viewport) +{ + int height = surf_size.Height; + if (SurfaceSize != surf_size) + { + Destroy(); + SurfaceSize = surf_size; + DirtyRows.resize(height); + + NumDirtyRegions = WHOLESCREENDIRTY; + for (int i = 0; i < height; ++i) + DirtyRows[i].numSpans = 0; + } + + Viewport = viewport; + Room2Screen.Init(surf_size, viewport); + Screen2DirtySurf.Init(viewport, RectWH(0, 0, surf_size.Width, surf_size.Height)); +} + +void DirtyRects::SetSurfaceOffsets(int x, int y) +{ + Room2Screen.SetSrcOffsets(x, y); +} + +void DirtyRects::Destroy() +{ + DirtyRows.clear(); + NumDirtyRegions = 0; +} + +void DirtyRects::Reset() +{ + NumDirtyRegions = 0; + + for (size_t i = 0; i < DirtyRows.size(); ++i) + DirtyRows[i].numSpans = 0; +} + +// Dirty rects for the main viewport background (black screen); +// these are used when the room viewport does not cover whole screen, +// so that we know when to paint black after mouse cursor and gui. +DirtyRects BlackRects; +// Dirty rects object for the single room camera +std::vector RoomCamRects; +// Saved room camera offsets to know if we must invalidate whole surface. +// TODO: if we support rotation then we also need to compare full transform! +std::vector> RoomCamPositions; + + +void dispose_invalid_regions(bool /* room_only */) +{ + RoomCamRects.clear(); + RoomCamPositions.clear(); +} + +void init_invalid_regions(int view_index, const Size &surf_size, const Rect &viewport) +{ + if (view_index < 0) + { + BlackRects.Init(surf_size, viewport); + } + else + { + if (RoomCamRects.size() <= (size_t)view_index) + { + RoomCamRects.resize(view_index + 1); + RoomCamPositions.resize(view_index + 1); + } + RoomCamRects[view_index].Init(surf_size, viewport); + RoomCamPositions[view_index] = std::make_pair(-1000, -1000); + } +} + +void delete_invalid_regions(int view_index) +{ + if (view_index >= 0) + { + RoomCamRects.erase(RoomCamRects.begin() + view_index); + RoomCamPositions.erase(RoomCamPositions.begin() + view_index); + } +} + +void set_invalidrects_cameraoffs(int view_index, int x, int y) +{ + if (view_index < 0) + { + BlackRects.SetSurfaceOffsets(x, y); + return; + } + else + { + RoomCamRects[view_index].SetSurfaceOffsets(x, y); + } + + int &posxwas = RoomCamPositions[view_index].first; + int &posywas = RoomCamPositions[view_index].second; + if ((x != posxwas) || (y != posywas)) + { + invalidate_all_camera_rects(view_index); + posxwas = x; + posywas = y; + } +} + +void invalidate_all_rects() +{ + for (auto &rects : RoomCamRects) + { + if (!IsRectInsideRect(rects.Viewport, BlackRects.Viewport)) + BlackRects.NumDirtyRegions = WHOLESCREENDIRTY; + rects.NumDirtyRegions = WHOLESCREENDIRTY; + } +} + +void invalidate_all_camera_rects(int view_index) +{ + if (view_index < 0) + return; + RoomCamRects[view_index].NumDirtyRegions = WHOLESCREENDIRTY; +} + +void invalidate_rect_on_surf(int x1, int y1, int x2, int y2, DirtyRects &rects) +{ + if (rects.DirtyRows.size() == 0) + return; + if (rects.NumDirtyRegions >= MAXDIRTYREGIONS) { + // too many invalid rectangles, just mark the whole thing dirty + rects.NumDirtyRegions = WHOLESCREENDIRTY; + return; + } + + int a; + + const Size &surfsz = rects.SurfaceSize; + if (x1 >= surfsz.Width) x1 = surfsz.Width - 1; + if (y1 >= surfsz.Height) y1 = surfsz.Height - 1; + if (x2 >= surfsz.Width) x2 = surfsz.Width - 1; + if (y2 >= surfsz.Height) y2 = surfsz.Height - 1; + if (x1 < 0) x1 = 0; + if (y1 < 0) y1 = 0; + if (x2 < 0) x2 = 0; + if (y2 < 0) y2 = 0; + rects.NumDirtyRegions++; + + // ** Span code + std::vector &dirtyRow = rects.DirtyRows; + int s, foundOne; + // add this rect to the list for this row + for (a = y1; a <= y2; a++) { + foundOne = 0; + for (s = 0; s < dirtyRow[a].numSpans; s++) { + if (dirtyRow[a].span[s].mergeSpan(x1, x2)) { + foundOne = 1; + break; + } + } + if (foundOne) { + // we were merged into a span, so we're ok + int t; + // check whether now two of the spans overlap each other + // in which case merge them + for (s = 0; s < dirtyRow[a].numSpans; s++) { + for (t = s + 1; t < dirtyRow[a].numSpans; t++) { + if (dirtyRow[a].span[s].mergeSpan(dirtyRow[a].span[t].x1, dirtyRow[a].span[t].x2)) { + dirtyRow[a].numSpans--; + for (int u = t; u < dirtyRow[a].numSpans; u++) + dirtyRow[a].span[u] = dirtyRow[a].span[u + 1]; + break; + } + } + } + } + else if (dirtyRow[a].numSpans < MAX_SPANS_PER_ROW) { + dirtyRow[a].span[dirtyRow[a].numSpans].x1 = x1; + dirtyRow[a].span[dirtyRow[a].numSpans].x2 = x2; + dirtyRow[a].numSpans++; + } + else { + // didn't fit in an existing span, and there are none spare + int nearestDist = 99999, nearestWas = -1, extendLeft; + int tleft, tright; + // find the nearest span, and enlarge that to include this rect + for (s = 0; s < dirtyRow[a].numSpans; s++) { + tleft = dirtyRow[a].span[s].x1 - x2; + if ((tleft > 0) && (tleft < nearestDist)) { + nearestDist = tleft; + nearestWas = s; + extendLeft = 1; + } + tright = x1 - dirtyRow[a].span[s].x2; + if ((tright > 0) && (tright < nearestDist)) { + nearestDist = tright; + nearestWas = s; + extendLeft = 0; + } + } + if (extendLeft) + dirtyRow[a].span[nearestWas].x1 = x1; + else + dirtyRow[a].span[nearestWas].x2 = x2; + } + } + // ** End span code + //} +} + +void invalidate_rect_ds(DirtyRects &rects, int x1, int y1, int x2, int y2, bool in_room) +{ + if (!in_room) + { + // TODO: for most opimisation (esp. with multiple viewports) should perhaps + // split/cut parts of the original rectangle which overlap room viewport(s). + Rect r(x1, y1, x2, y2); + // If overlay is NOT completely over the room, then invalidate black rect + if (!IsRectInsideRect(rects.Viewport, r)) + invalidate_rect_on_surf(x1, y1, x2, y2, BlackRects); + // If overlay is NOT intersecting room viewport at all, then stop + if (!AreRectsIntersecting(rects.Viewport, r)) + return; + + // Transform from screen to room coordinates through the known viewport + x1 = rects.Screen2DirtySurf.X.ScalePt(x1); + x2 = rects.Screen2DirtySurf.X.ScalePt(x2); + y1 = rects.Screen2DirtySurf.Y.ScalePt(y1); + y2 = rects.Screen2DirtySurf.Y.ScalePt(y2); + } + else + { + x1 -= rects.Room2Screen.X.GetSrcOffset(); + y1 -= rects.Room2Screen.Y.GetSrcOffset(); + x2 -= rects.Room2Screen.X.GetSrcOffset(); + y2 -= rects.Room2Screen.Y.GetSrcOffset(); + } + + invalidate_rect_on_surf(x1, y1, x2, y2, rects); +} + +void invalidate_rect_ds(int x1, int y1, int x2, int y2, bool in_room) +{ + for (auto &rects : RoomCamRects) + invalidate_rect_ds(rects, x1, y1, x2, y2, in_room); +} + +// Note that this function is denied to perform any kind of scaling or other transformation +// other than blitting with offset. This is mainly because destination could be a 32-bit virtual screen +// while room background was 16-bit and Allegro lib does not support stretching between colour depths. +// The no_transform flag here means essentially "no offset", and indicates that the function +// must blit src on ds at 0;0. Otherwise, actual Viewport offset is used. +void update_invalid_region(Bitmap *ds, Bitmap *src, const DirtyRects &rects, bool no_transform) +{ + if (rects.NumDirtyRegions == 0) + return; + + if (!no_transform) + ds->SetClip(rects.Viewport); + + const int src_x = rects.Room2Screen.X.GetSrcOffset(); + const int src_y = rects.Room2Screen.Y.GetSrcOffset(); + const int dst_x = no_transform ? 0 : rects.Viewport.Left; + const int dst_y = no_transform ? 0 : rects.Viewport.Top; + + if (rects.NumDirtyRegions == WHOLESCREENDIRTY) + { + ds->Blit(src, src_x, src_y, dst_x, dst_y, rects.SurfaceSize.Width, rects.SurfaceSize.Height); + } + else + { + const std::vector &dirtyRow = rects.DirtyRows; + const int surf_height = rects.SurfaceSize.Height; + // TODO: is this IsMemoryBitmap check is still relevant? + // If bitmaps properties match and no transform required other than linear offset + if ((src->GetColorDepth() == ds->GetColorDepth()) && (ds->IsMemoryBitmap())) + { + const int bypp = src->GetBPP(); + // do the fast memory copy + for (int i = 0; i < surf_height; i++) + { + const uint8_t *src_scanline = src->GetScanLine(i + src_y); + uint8_t *dst_scanline = ds->GetScanLineForWriting(i + dst_y); + const IRRow &dirty_row = dirtyRow[i]; + for (int k = 0; k < dirty_row.numSpans; k++) + { + int tx1 = dirty_row.span[k].x1; + int tx2 = dirty_row.span[k].x2; + memcpy(&dst_scanline[(tx1 + dst_x) * bypp], &src_scanline[(tx1 + src_x) * bypp], ((tx2 - tx1) + 1) * bypp); + } + } + } + // If has to use Blit, but still must draw with no transform but offset + else + { + // do fast copy without transform + for (int i = 0, rowsInOne = 1; i < surf_height; i += rowsInOne, rowsInOne = 1) + { + // if there are rows with identical masks, do them all in one go + // TODO: what is this for? may this be done at the invalidate_rect merge step? + while ((i + rowsInOne < surf_height) && (memcmp(&dirtyRow[i], &dirtyRow[i + rowsInOne], sizeof(IRRow)) == 0)) + rowsInOne++; + + const IRRow &dirty_row = dirtyRow[i]; + for (int k = 0; k < dirty_row.numSpans; k++) + { + int tx1 = dirty_row.span[k].x1; + int tx2 = dirty_row.span[k].x2; + ds->Blit(src, tx1 + src_x, i + src_y, tx1 + dst_x, i + dst_y, (tx2 - tx1) + 1, rowsInOne); + } + } + } + } +} + +void update_invalid_region(Bitmap *ds, color_t fill_color, const DirtyRects &rects) +{ + ds->SetClip(rects.Viewport); + + if (rects.NumDirtyRegions == WHOLESCREENDIRTY) + { + ds->FillRect(rects.Viewport, fill_color); + } + else + { + const std::vector &dirtyRow = rects.DirtyRows; + const int surf_height = rects.SurfaceSize.Height; + { + const PlaneScaling &tf = rects.Room2Screen; + for (int i = 0, rowsInOne = 1; i < surf_height; i += rowsInOne, rowsInOne = 1) + { + // if there are rows with identical masks, do them all in one go + // TODO: what is this for? may this be done at the invalidate_rect merge step? + while ((i + rowsInOne < surf_height) && (memcmp(&dirtyRow[i], &dirtyRow[i + rowsInOne], sizeof(IRRow)) == 0)) + rowsInOne++; + + const IRRow &dirty_row = dirtyRow[i]; + for (int k = 0; k < dirty_row.numSpans; k++) + { + Rect src_r(dirty_row.span[k].x1, i, dirty_row.span[k].x2, i + rowsInOne - 1); + Rect dst_r = tf.ScaleRange(src_r); + ds->FillRect(dst_r, fill_color); + } + } + } + } +} + +void update_black_invreg_and_reset(Bitmap *ds) +{ + if (!BlackRects.IsInit()) + return; + update_invalid_region(ds, (color_t)0, BlackRects); + BlackRects.Reset(); +} + +void update_room_invreg_and_reset(int view_index, Bitmap *ds, Bitmap *src, bool no_transform) +{ + if (view_index < 0 || RoomCamRects.size() == 0) + return; + + update_invalid_region(ds, src, RoomCamRects[view_index], no_transform); + RoomCamRects[view_index].Reset(); +} diff --git a/engines/ags/engine/ac/draw_software.h b/engines/ags/engine/ac/draw_software.h new file mode 100644 index 000000000000..47db5b227f2a --- /dev/null +++ b/engines/ags/engine/ac/draw_software.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Software drawing component. Optimizes drawing for software renderer using +// dirty rectangles technique. +// +//============================================================================= +#ifndef __AGS_EE_AC__DRAWSOFTWARE_H +#define __AGS_EE_AC__DRAWSOFTWARE_H + +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "util/geometry.h" + +// Inits dirty rects array for the given room camera/viewport pair +// View_index indicates the room viewport (>= 0) or the main viewport (-1) +void init_invalid_regions(int view_index, const Size &surf_size, const Rect &viewport); +// Deletes dirty rects for particular index +void delete_invalid_regions(int view_index); +// Disposes dirty rects arrays +void dispose_invalid_regions(bool room_only); +// Update the coordinate transformation for the particular dirty rects object +void set_invalidrects_cameraoffs(int view_index, int x, int y); +// Mark the whole screen dirty +void invalidate_all_rects(); +// Mark the whole camera surface dirty +void invalidate_all_camera_rects(int view_index); +void invalidate_rect_ds(int x1, int y1, int x2, int y2, bool in_room); +// Paints the black screen background in the regions marked as dirty +void update_black_invreg_and_reset(AGS::Common::Bitmap *ds); +// Copies the room regions marked as dirty from source (src) to destination (ds) with the given offset (x, y) +// no_transform flag tells the system that the regions should be plain copied to the ds. +void update_room_invreg_and_reset(int view_index, AGS::Common::Bitmap *ds, AGS::Common::Bitmap *src, bool no_transform); + +#endif // __AGS_EE_AC__DRAWSOFTWARE_H diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp new file mode 100644 index 000000000000..5dc0ccdf9e27 --- /dev/null +++ b/engines/ags/engine/ac/drawingsurface.cpp @@ -0,0 +1,694 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/draw.h" +#include "ac/drawingsurface.h" +#include "ac/common.h" +#include "ac/charactercache.h" +#include "ac/display.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_translation.h" +#include "ac/objectcache.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "ac/string.h" +#include "ac/walkbehind.h" +#include "debug/debug_log.h" +#include "font/fonts.h" +#include "gui/guimain.h" +#include "ac/spritecache.h" +#include "script/runtimescriptvalue.h" +#include "gfx/gfx_def.h" +#include "gfx/gfx_util.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameState play; +extern RoomStatus*croom; +extern RoomObject*objs; +extern CharacterCache *charcache; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; +extern SpriteCache spriteset; +extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; + +// ** SCRIPT DRAWINGSURFACE OBJECT + +void DrawingSurface_Release(ScriptDrawingSurface* sds) +{ + if (sds->roomBackgroundNumber >= 0) + { + if (sds->modified) + { + if (sds->roomBackgroundNumber == play.bg_frame) + { + invalidate_screen(); + mark_current_background_dirty(); + } + play.raw_modified[sds->roomBackgroundNumber] = 1; + } + + sds->roomBackgroundNumber = -1; + } + if (sds->roomMaskType > kRoomAreaNone) + { + if (sds->roomMaskType == kRoomAreaWalkBehind) + { + recache_walk_behinds(); + } + sds->roomMaskType = kRoomAreaNone; + } + if (sds->dynamicSpriteNumber >= 0) + { + if (sds->modified) + { + int tt; + // force a refresh of any cached object or character images + if (croom != nullptr) + { + for (tt = 0; tt < croom->numobj; tt++) + { + if (objs[tt].num == sds->dynamicSpriteNumber) + objcache[tt].sppic = -31999; + } + } + for (tt = 0; tt < game.numcharacters; tt++) + { + if (charcache[tt].sppic == sds->dynamicSpriteNumber) + charcache[tt].sppic = -31999; + } + for (tt = 0; tt < game.numgui; tt++) + { + if ((guis[tt].BgImage == sds->dynamicSpriteNumber) && + (guis[tt].IsDisplayed())) + { + guis_need_update = 1; + break; + } + } + } + + sds->dynamicSpriteNumber = -1; + } + if (sds->dynamicSurfaceNumber >= 0) + { + delete dynamicallyCreatedSurfaces[sds->dynamicSurfaceNumber]; + dynamicallyCreatedSurfaces[sds->dynamicSurfaceNumber] = nullptr; + sds->dynamicSurfaceNumber = -1; + } + sds->modified = 0; +} + +void ScriptDrawingSurface::PointToGameResolution(int *xcoord, int *ycoord) +{ + ctx_data_to_game_coord(*xcoord, *ycoord, highResCoordinates != 0); +} + +void ScriptDrawingSurface::SizeToGameResolution(int *width, int *height) +{ + ctx_data_to_game_size(*width, *height, highResCoordinates != 0); +} + +void ScriptDrawingSurface::SizeToGameResolution(int *valueToAdjust) +{ + *valueToAdjust = ctx_data_to_game_size(*valueToAdjust, highResCoordinates != 0); +} + +// convert actual co-ordinate back to what the script is expecting +void ScriptDrawingSurface::SizeToDataResolution(int *valueToAdjust) +{ + *valueToAdjust = game_to_ctx_data_size(*valueToAdjust, highResCoordinates != 0); +} + +ScriptDrawingSurface* DrawingSurface_CreateCopy(ScriptDrawingSurface *sds) +{ + Bitmap *sourceBitmap = sds->GetBitmapSurface(); + + for (int i = 0; i < MAX_DYNAMIC_SURFACES; i++) + { + if (dynamicallyCreatedSurfaces[i] == nullptr) + { + dynamicallyCreatedSurfaces[i] = BitmapHelper::CreateBitmapCopy(sourceBitmap); + ScriptDrawingSurface *newSurface = new ScriptDrawingSurface(); + newSurface->dynamicSurfaceNumber = i; + newSurface->hasAlphaChannel = sds->hasAlphaChannel; + ccRegisterManagedObject(newSurface, newSurface); + return newSurface; + } + } + + quit("!DrawingSurface.CreateCopy: too many copied surfaces created"); + return nullptr; +} + +void DrawingSurface_DrawImageImpl(ScriptDrawingSurface* sds, Bitmap* src, int dst_x, int dst_y, int trans, int dst_width, int dst_height, + int src_x, int src_y, int src_width, int src_height, int sprite_id, bool src_has_alpha) +{ + Bitmap *ds = sds->GetBitmapSurface(); + if (src == ds) + quit("!DrawingSurface.DrawImage: cannot draw onto itself"); + if ((trans < 0) || (trans > 100)) + quit("!DrawingSurface.DrawImage: invalid transparency setting"); + + if (trans == 100) + return; // fully transparent + if (dst_width < 1 || dst_height < 1 || src_width < 1 || src_height < 1) + return; // invalid src or dest rectangles + + // Setup uninitialized arguments; convert coordinates for legacy script mode + if (dst_width == SCR_NO_VALUE) { dst_width = src->GetWidth(); } + else { sds->SizeToGameResolution(&dst_width); } + if (dst_height == SCR_NO_VALUE) { dst_height = src->GetHeight(); } + else { sds->SizeToGameResolution(&dst_height); } + + if (src_x == SCR_NO_VALUE) { src_x = 0; } + if (src_y == SCR_NO_VALUE) { src_y = 0; } + sds->PointToGameResolution(&src_x, &src_y); + if (src_width == SCR_NO_VALUE) { src_width = src->GetWidth(); } + else { sds->SizeToGameResolution(&src_width); } + if (src_height == SCR_NO_VALUE) { src_height = src->GetHeight(); } + else { sds->SizeToGameResolution(&src_height); } + + if (dst_x >= ds->GetWidth() || dst_x + dst_width <= 0 || dst_y >= ds->GetHeight() || dst_y + dst_height <= 0 || + src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0) + return; // source or destination rects lie completely off surface + // Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that) + Math::ClampLength(src_x, src_width, 0, src->GetWidth()); + Math::ClampLength(src_y, src_height, 0, src->GetHeight()); + + // TODO: possibly optimize by not making a stretched intermediate bitmap + // if simplier blit/draw_sprite could be called (no translucency with alpha channel). + bool needToFreeBitmap = false; + if (dst_width != src->GetWidth() || dst_height != src->GetHeight() || + src_width != src->GetWidth() || src_height != src->GetHeight()) + { + // Resize and/or partial copy specified + Bitmap *newPic = BitmapHelper::CreateBitmap(dst_width, dst_height, src->GetColorDepth()); + newPic->StretchBlt(src, + RectWH(src_x, src_y, src_width, src_height), + RectWH(0, 0, dst_width, dst_height)); + + src = newPic; + needToFreeBitmap = true; + update_polled_stuff_if_runtime(); + } + + ds = sds->StartDrawing(); + sds->PointToGameResolution(&dst_x, &dst_y); + + if (src->GetColorDepth() != ds->GetColorDepth()) { + if (sprite_id >= 0) + debug_script_warn("DrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", sprite_id, src->GetColorDepth(), ds->GetColorDepth()); + else + debug_script_warn("DrawImage: Source image colour depth %d-bit not same as background depth %d-bit", src->GetColorDepth(), ds->GetColorDepth()); + } + + draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, src_has_alpha, + kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans)); + + sds->FinishedDrawing(); + + if (needToFreeBitmap) + delete src; +} + +void DrawingSurface_DrawImageEx(ScriptDrawingSurface* sds, int dst_x, int dst_y, int slot, int trans, int dst_width, int dst_height, + int src_x, int src_y, int src_width, int src_height) +{ + if ((slot < 0) || (spriteset[slot] == nullptr)) + quit("!DrawingSurface.DrawImage: invalid sprite slot number specified"); + DrawingSurface_DrawImageImpl(sds, spriteset[slot], dst_x, dst_y, trans, dst_width, dst_height, + src_x, src_y, src_width, src_height, slot, (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +void DrawingSurface_DrawImage(ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height) +{ + DrawingSurface_DrawImageEx(sds, xx, yy, slot, trans, width, height, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE); +} + +void DrawingSurface_DrawSurfaceEx(ScriptDrawingSurface* target, ScriptDrawingSurface* source, int trans, + int dst_x, int dst_y, int dst_width, int dst_height, + int src_x, int src_y, int src_width, int src_height) +{ + DrawingSurface_DrawImageImpl(target, source->GetBitmapSurface(), dst_x, dst_y, trans, dst_width, dst_height, + src_x, src_y, src_width, src_height, -1, source->hasAlphaChannel); +} + +void DrawingSurface_DrawSurface(ScriptDrawingSurface* target, ScriptDrawingSurface* source, int trans) +{ + DrawingSurface_DrawSurfaceEx(target, source, trans, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE); +} + +void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour) +{ + sds->currentColourScript = newColour; + // StartDrawing to set up ds to set the colour at the appropriate + // depth for the background + Bitmap *ds = sds->StartDrawing(); + if (newColour == SCR_COLOR_TRANSPARENT) + { + sds->currentColour = ds->GetMaskColor(); + } + else + { + sds->currentColour = ds->GetCompatibleColor(newColour); + } + sds->FinishedDrawingReadOnly(); +} + +int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds) +{ + return sds->currentColourScript; +} + +void DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface *sds, int highRes) +{ + if (game.AllowRelativeRes()) + sds->highResCoordinates = (highRes) ? 1 : 0; +} + +int DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface *sds) +{ + return sds->highResCoordinates; +} + +int DrawingSurface_GetHeight(ScriptDrawingSurface *sds) +{ + Bitmap *ds = sds->GetBitmapSurface(); + int height = ds->GetHeight(); + sds->SizeToGameResolution(&height); + return height; +} + +int DrawingSurface_GetWidth(ScriptDrawingSurface *sds) +{ + Bitmap *ds = sds->GetBitmapSurface(); + int width = ds->GetWidth(); + sds->SizeToGameResolution(&width); + return width; +} + +void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour) +{ + Bitmap *ds = sds->StartDrawing(); + int allegroColor; + if ((colour == -SCR_NO_VALUE) || (colour == SCR_COLOR_TRANSPARENT)) + { + allegroColor = ds->GetMaskColor(); + } + else + { + allegroColor = ds->GetCompatibleColor(colour); + } + ds->Fill(allegroColor); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius) +{ + sds->PointToGameResolution(&x, &y); + sds->SizeToGameResolution(&radius); + + Bitmap *ds = sds->StartDrawing(); + ds->FillCircle(Circle(x, y, radius), sds->currentColour); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2) +{ + sds->PointToGameResolution(&x1, &y1); + sds->PointToGameResolution(&x2, &y2); + + Bitmap *ds = sds->StartDrawing(); + ds->FillRect(Rect(x1,y1,x2,y2), sds->currentColour); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3) +{ + sds->PointToGameResolution(&x1, &y1); + sds->PointToGameResolution(&x2, &y2); + sds->PointToGameResolution(&x3, &y3); + + Bitmap *ds = sds->StartDrawing(); + ds->DrawTriangle(Triangle(x1,y1,x2,y2,x3,y3), sds->currentColour); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char* text) +{ + sds->PointToGameResolution(&xx, &yy); + Bitmap *ds = sds->StartDrawing(); + // don't use wtextcolor because it will do a 16->32 conversion + color_t text_color = sds->currentColour; + if ((ds->GetColorDepth() <= 8) && (play.raw_color > 255)) { + text_color = ds->GetCompatibleColor(1); + debug_script_warn ("RawPrint: Attempted to use hi-color on 256-col background"); + } + wouttext_outline(ds, xx, yy, font, text_color, text); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawStringWrapped_Old(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) { + DrawingSurface_DrawStringWrapped(sds, xx, yy, wid, font, ConvertLegacyScriptAlignment((LegacyScriptAlignment)alignment), msg); +} + +void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) { + int linespacing = getfontspacing_outlined(font); + sds->PointToGameResolution(&xx, &yy); + sds->SizeToGameResolution(&wid); + + if (break_up_text_into_lines(msg, Lines, wid, font) == 0) + return; + + Bitmap *ds = sds->StartDrawing(); + color_t text_color = sds->currentColour; + + for (size_t i = 0; i < Lines.Count(); i++) + { + int drawAtX = xx; + + if (alignment & kMAlignHCenter) + { + drawAtX = xx + ((wid / 2) - wgettextwidth(Lines[i], font) / 2); + } + else if (alignment & kMAlignRight) + { + drawAtX = (xx + wid) - wgettextwidth(Lines[i], font); + } + + wouttext_outline(ds, drawAtX, yy + linespacing*i, font, text_color, Lines[i]); + } + + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm) +{ + char displbuf[3000]; + get_message_text(msgm, displbuf); + // it's probably too late but check anyway + if (strlen(displbuf) > 2899) + quit("!RawPrintMessageWrapped: message too long"); + + DrawingSurface_DrawStringWrapped_Old(sds, xx, yy, wid, font, kLegacyScAlignLeft, displbuf); +} + +void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness) { + sds->PointToGameResolution(&fromx, &fromy); + sds->PointToGameResolution(&tox, &toy); + sds->SizeToGameResolution(&thickness); + int ii,jj,xx,yy; + Bitmap *ds = sds->StartDrawing(); + // draw several lines to simulate the thickness + color_t draw_color = sds->currentColour; + for (ii = 0; ii < thickness; ii++) + { + xx = (ii - (thickness / 2)); + for (jj = 0; jj < thickness; jj++) + { + yy = (jj - (thickness / 2)); + ds->DrawLine (Line(fromx + xx, fromy + yy, tox + xx, toy + yy), draw_color); + } + } + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y) { + sds->PointToGameResolution(&x, &y); + int thickness = 1; + sds->SizeToGameResolution(&thickness); + int ii,jj; + Bitmap *ds = sds->StartDrawing(); + // draw several pixels to simulate the thickness + color_t draw_color = sds->currentColour; + for (ii = 0; ii < thickness; ii++) + { + for (jj = 0; jj < thickness; jj++) + { + ds->PutPixel(x + ii, y + jj, draw_color); + } + } + sds->FinishedDrawing(); +} + +int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) { + sds->PointToGameResolution(&x, &y); + Bitmap *ds = sds->StartDrawing(); + unsigned int rawPixel = ds->GetPixel(x, y); + unsigned int maskColor = ds->GetMaskColor(); + int colDepth = ds->GetColorDepth(); + + if (rawPixel == maskColor) + { + rawPixel = SCR_COLOR_TRANSPARENT; + } + else if (colDepth > 8) + { + int r = getr_depth(colDepth, rawPixel); + int ds = getg_depth(colDepth, rawPixel); + int b = getb_depth(colDepth, rawPixel); + + rawPixel = Game_GetColorFromRGB(r, ds, b); + } + + sds->FinishedDrawingReadOnly(); + + return rawPixel; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// void (ScriptDrawingSurface *sds, int colour) +RuntimeScriptValue Sc_DrawingSurface_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_Clear); +} + +// ScriptDrawingSurface* (ScriptDrawingSurface *sds) +RuntimeScriptValue Sc_DrawingSurface_CreateCopy(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJAUTO(ScriptDrawingSurface, ScriptDrawingSurface, DrawingSurface_CreateCopy); +} + +// void (ScriptDrawingSurface *sds, int x, int y, int radius) +RuntimeScriptValue Sc_DrawingSurface_DrawCircle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(ScriptDrawingSurface, DrawingSurface_DrawCircle); +} + +// void (ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height) +RuntimeScriptValue Sc_DrawingSurface_DrawImage_6(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawImage); +} + +RuntimeScriptValue Sc_DrawingSurface_DrawImage(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_OBJ_PARAM_COUNT(METHOD, 10); + DrawingSurface_DrawImageEx((ScriptDrawingSurface*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, + params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); + return RuntimeScriptValue((int32_t)0); +} + +// void (ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness) +RuntimeScriptValue Sc_DrawingSurface_DrawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawLine); +} + +// void (ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm) +RuntimeScriptValue Sc_DrawingSurface_DrawMessageWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawMessageWrapped); +} + +// void (ScriptDrawingSurface *sds, int x, int y) +RuntimeScriptValue Sc_DrawingSurface_DrawPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptDrawingSurface, DrawingSurface_DrawPixel); +} + +// void (ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2) +RuntimeScriptValue Sc_DrawingSurface_DrawRectangle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(ScriptDrawingSurface, DrawingSurface_DrawRectangle); +} + +// void (ScriptDrawingSurface *sds, int xx, int yy, int font, const char* texx, ...) +RuntimeScriptValue Sc_DrawingSurface_DrawString(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_SCRIPT_SPRINTF(DrawingSurface_DrawString, 4); + DrawingSurface_DrawString((ScriptDrawingSurface*)self, params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) +RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped_Old, const char); +} + +RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped, const char); +} + +// void (ScriptDrawingSurface* target, ScriptDrawingSurface* source, int translev) +RuntimeScriptValue Sc_DrawingSurface_DrawSurface_2(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ_PINT(ScriptDrawingSurface, DrawingSurface_DrawSurface, ScriptDrawingSurface); +} + +RuntimeScriptValue Sc_DrawingSurface_DrawSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_OBJ_PARAM_COUNT(METHOD, 10); + DrawingSurface_DrawSurfaceEx((ScriptDrawingSurface*)self, (ScriptDrawingSurface*)params[0].Ptr, + params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, + params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); + return RuntimeScriptValue((int32_t)0); +} + +// void (ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3) +RuntimeScriptValue Sc_DrawingSurface_DrawTriangle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawTriangle); +} + +// int (ScriptDrawingSurface *sds, int x, int y) +RuntimeScriptValue Sc_DrawingSurface_GetPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT2(ScriptDrawingSurface, DrawingSurface_GetPixel); +} + +// void (ScriptDrawingSurface* sds) +RuntimeScriptValue Sc_DrawingSurface_Release(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptDrawingSurface, DrawingSurface_Release); +} + +// int (ScriptDrawingSurface *sds) +RuntimeScriptValue Sc_DrawingSurface_GetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetDrawingColor); +} + +// void (ScriptDrawingSurface *sds, int newColour) +RuntimeScriptValue Sc_DrawingSurface_SetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetDrawingColor); +} + +// int (ScriptDrawingSurface *sds) +RuntimeScriptValue Sc_DrawingSurface_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetHeight); +} + +// int (ScriptDrawingSurface *sds) +RuntimeScriptValue Sc_DrawingSurface_GetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetUseHighResCoordinates); +} + +// void (ScriptDrawingSurface *sds, int highRes) +RuntimeScriptValue Sc_DrawingSurface_SetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetUseHighResCoordinates); +} + +// int (ScriptDrawingSurface *sds) +RuntimeScriptValue Sc_DrawingSurface_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetWidth); +} + +//============================================================================= +// +// Exclusive API for Plugins +// +//============================================================================= + +// void (ScriptDrawingSurface *sds, int xx, int yy, int font, const char* texx, ...) +void ScPl_DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char* texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + DrawingSurface_DrawString(sds, xx, yy, font, scsf_buffer); +} + +void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) +{ + ccAddExternalObjectFunction("DrawingSurface::Clear^1", Sc_DrawingSurface_Clear); + ccAddExternalObjectFunction("DrawingSurface::CreateCopy^0", Sc_DrawingSurface_CreateCopy); + ccAddExternalObjectFunction("DrawingSurface::DrawCircle^3", Sc_DrawingSurface_DrawCircle); + ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage_6); + ccAddExternalObjectFunction("DrawingSurface::DrawImage^10", Sc_DrawingSurface_DrawImage); + ccAddExternalObjectFunction("DrawingSurface::DrawLine^5", Sc_DrawingSurface_DrawLine); + ccAddExternalObjectFunction("DrawingSurface::DrawMessageWrapped^5", Sc_DrawingSurface_DrawMessageWrapped); + ccAddExternalObjectFunction("DrawingSurface::DrawPixel^2", Sc_DrawingSurface_DrawPixel); + ccAddExternalObjectFunction("DrawingSurface::DrawRectangle^4", Sc_DrawingSurface_DrawRectangle); + ccAddExternalObjectFunction("DrawingSurface::DrawString^104", Sc_DrawingSurface_DrawString); + if (base_api < kScriptAPI_v350) + ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped_Old); + else + ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped); + ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface_2); + ccAddExternalObjectFunction("DrawingSurface::DrawSurface^10", Sc_DrawingSurface_DrawSurface); + ccAddExternalObjectFunction("DrawingSurface::DrawTriangle^6", Sc_DrawingSurface_DrawTriangle); + ccAddExternalObjectFunction("DrawingSurface::GetPixel^2", Sc_DrawingSurface_GetPixel); + ccAddExternalObjectFunction("DrawingSurface::Release^0", Sc_DrawingSurface_Release); + ccAddExternalObjectFunction("DrawingSurface::get_DrawingColor", Sc_DrawingSurface_GetDrawingColor); + ccAddExternalObjectFunction("DrawingSurface::set_DrawingColor", Sc_DrawingSurface_SetDrawingColor); + ccAddExternalObjectFunction("DrawingSurface::get_Height", Sc_DrawingSurface_GetHeight); + ccAddExternalObjectFunction("DrawingSurface::get_UseHighResCoordinates", Sc_DrawingSurface_GetUseHighResCoordinates); + ccAddExternalObjectFunction("DrawingSurface::set_UseHighResCoordinates", Sc_DrawingSurface_SetUseHighResCoordinates); + ccAddExternalObjectFunction("DrawingSurface::get_Width", Sc_DrawingSurface_GetWidth); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DrawingSurface::Clear^1", (void*)DrawingSurface_Clear); + ccAddExternalFunctionForPlugin("DrawingSurface::CreateCopy^0", (void*)DrawingSurface_CreateCopy); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawCircle^3", (void*)DrawingSurface_DrawCircle); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawImage^6", (void*)DrawingSurface_DrawImage); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawLine^5", (void*)DrawingSurface_DrawLine); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawMessageWrapped^5", (void*)DrawingSurface_DrawMessageWrapped); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawPixel^2", (void*)DrawingSurface_DrawPixel); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawRectangle^4", (void*)DrawingSurface_DrawRectangle); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawString^104", (void*)ScPl_DrawingSurface_DrawString); + if (base_api < kScriptAPI_v350) + ccAddExternalFunctionForPlugin("DrawingSurface::DrawStringWrapped^6", (void*)DrawingSurface_DrawStringWrapped_Old); + else + ccAddExternalFunctionForPlugin("DrawingSurface::DrawStringWrapped^6", (void*)DrawingSurface_DrawStringWrapped); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawSurface^2", (void*)DrawingSurface_DrawSurface); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawTriangle^6", (void*)DrawingSurface_DrawTriangle); + ccAddExternalFunctionForPlugin("DrawingSurface::GetPixel^2", (void*)DrawingSurface_GetPixel); + ccAddExternalFunctionForPlugin("DrawingSurface::Release^0", (void*)DrawingSurface_Release); + ccAddExternalFunctionForPlugin("DrawingSurface::get_DrawingColor", (void*)DrawingSurface_GetDrawingColor); + ccAddExternalFunctionForPlugin("DrawingSurface::set_DrawingColor", (void*)DrawingSurface_SetDrawingColor); + ccAddExternalFunctionForPlugin("DrawingSurface::get_Height", (void*)DrawingSurface_GetHeight); + ccAddExternalFunctionForPlugin("DrawingSurface::get_UseHighResCoordinates", (void*)DrawingSurface_GetUseHighResCoordinates); + ccAddExternalFunctionForPlugin("DrawingSurface::set_UseHighResCoordinates", (void*)DrawingSurface_SetUseHighResCoordinates); + ccAddExternalFunctionForPlugin("DrawingSurface::get_Width", (void*)DrawingSurface_GetWidth); +} diff --git a/engines/ags/engine/ac/drawingsurface.h b/engines/ags/engine/ac/drawingsurface.h new file mode 100644 index 000000000000..5bd6b7aac716 --- /dev/null +++ b/engines/ags/engine/ac/drawingsurface.h @@ -0,0 +1,45 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__DRAWINGSURFACE_H +#define __AGS_EE_AC__DRAWINGSURFACE_H + +#include "ac/dynobj/scriptdrawingsurface.h" + +void DrawingSurface_Release(ScriptDrawingSurface* sds); +// convert actual co-ordinate back to what the script is expecting +ScriptDrawingSurface* DrawingSurface_CreateCopy(ScriptDrawingSurface *sds); +void DrawingSurface_DrawSurface(ScriptDrawingSurface* target, ScriptDrawingSurface* source, int translev); +void DrawingSurface_DrawImage_FullSrc(ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height); +void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour); +int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds); +void DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface *sds, int highRes); +int DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface *sds); +int DrawingSurface_GetHeight(ScriptDrawingSurface *sds); +int DrawingSurface_GetWidth(ScriptDrawingSurface *sds); +void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour); +void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius); +void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2); +void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3); +void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char* text); +void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg); +void DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm); +void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness); +void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y); +int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y); + +#endif // __AGS_EE_AC__DRAWINGSURFACE_H diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp new file mode 100644 index 000000000000..480a233e1ae1 --- /dev/null +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -0,0 +1,700 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/dynamicsprite.h" +#include "ac/common.h" +#include "ac/charactercache.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_dynamicsprite.h" +#include "ac/global_game.h" +#include "ac/math.h" // M_PI +#include "ac/objectcache.h" +#include "ac/path_helper.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "ac/system.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "gui/guibutton.h" +#include "ac/spritecache.h" +#include "gfx/graphicsdriver.h" +#include "script/runtimescriptvalue.h" + +using namespace Common; +using namespace Engine; + +extern GameSetupStruct game; +extern SpriteCache spriteset; +extern RoomStruct thisroom; +extern RoomObject*objs; +extern RoomStatus*croom; +extern CharacterCache *charcache; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; + +extern color palette[256]; +extern AGS::Engine::IGraphicsDriver *gfxDriver; + +char check_dynamic_sprites_at_exit = 1; + +// ** SCRIPT DYNAMIC SPRITE + +void DynamicSprite_Delete(ScriptDynamicSprite *sds) { + if (sds->slot) { + free_dynamic_sprite(sds->slot); + sds->slot = 0; + } +} + +ScriptDrawingSurface* DynamicSprite_GetDrawingSurface(ScriptDynamicSprite *dss) +{ + ScriptDrawingSurface *surface = new ScriptDrawingSurface(); + surface->dynamicSpriteNumber = dss->slot; + + if ((game.SpriteInfos[dss->slot].Flags & SPF_ALPHACHANNEL) != 0) + surface->hasAlphaChannel = true; + + ccRegisterManagedObject(surface, surface); + return surface; +} + +int DynamicSprite_GetGraphic(ScriptDynamicSprite *sds) { + if (sds->slot == 0) + quit("!DynamicSprite.Graphic: Cannot get graphic, sprite has been deleted"); + return sds->slot; +} + +int DynamicSprite_GetWidth(ScriptDynamicSprite *sds) { + return game_to_data_coord(game.SpriteInfos[sds->slot].Width); +} + +int DynamicSprite_GetHeight(ScriptDynamicSprite *sds) { + return game_to_data_coord(game.SpriteInfos[sds->slot].Height); +} + +int DynamicSprite_GetColorDepth(ScriptDynamicSprite *sds) { + int depth = spriteset[sds->slot]->GetColorDepth(); + if (depth == 15) + depth = 16; + if (depth == 24) + depth = 32; + return depth; +} + +void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height) { + if ((width < 1) || (height < 1)) + quit("!DynamicSprite.Resize: width and height must be greater than zero"); + if (sds->slot == 0) + quit("!DynamicSprite.Resize: sprite has been deleted"); + + data_to_game_coords(&width, &height); + + if (width * height >= 25000000) + quitprintf("!DynamicSprite.Resize: new size is too large: %d x %d", width, height); + + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + newPic->StretchBlt(spriteset[sds->slot], + RectWH(0, 0, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height), + RectWH(0, 0, width, height)); + + delete spriteset[sds->slot]; + + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction) { + if ((direction < 1) || (direction > 3)) + quit("!DynamicSprite.Flip: invalid direction"); + if (sds->slot == 0) + quit("!DynamicSprite.Flip: sprite has been deleted"); + + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height, spriteset[sds->slot]->GetColorDepth()); + + if (direction == 1) + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HFlip); + else if (direction == 2) + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_VFlip); + else if (direction == 3) + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HVFlip); + + delete spriteset[sds->slot]; + + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSprite) { + if (sds->slot == 0) + quit("!DynamicSprite.CopyTransparencyMask: sprite has been deleted"); + + if ((game.SpriteInfos[sds->slot].Width != game.SpriteInfos[sourceSprite].Width) || + (game.SpriteInfos[sds->slot].Height != game.SpriteInfos[sourceSprite].Height)) + { + quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same size"); + } + + Bitmap *target = spriteset[sds->slot]; + Bitmap *source = spriteset[sourceSprite]; + + if (target->GetColorDepth() != source->GetColorDepth()) + { + quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same colour depth"); + } + + // set the target's alpha channel depending on the source + bool dst_has_alpha = (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0; + bool src_has_alpha = (game.SpriteInfos[sourceSprite].Flags & SPF_ALPHACHANNEL) != 0; + game.SpriteInfos[sds->slot].Flags &= ~SPF_ALPHACHANNEL; + if (src_has_alpha) + { + game.SpriteInfos[sds->slot].Flags |= SPF_ALPHACHANNEL; + } + + BitmapHelper::CopyTransparency(target, source, dst_has_alpha, src_has_alpha); +} + +void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y) +{ + if (sds->slot == 0) + quit("!DynamicSprite.ChangeCanvasSize: sprite has been deleted"); + if ((width < 1) || (height < 1)) + quit("!DynamicSprite.ChangeCanvasSize: new size is too small"); + + data_to_game_coords(&x, &y); + data_to_game_coords(&width, &height); + + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + // blit it into the enlarged image + newPic->Blit(spriteset[sds->slot], 0, 0, x, y, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height); + + delete spriteset[sds->slot]; + + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int height) { + if ((width < 1) || (height < 1)) + quit("!DynamicSprite.Crop: co-ordinates do not make sense"); + if (sds->slot == 0) + quit("!DynamicSprite.Crop: sprite has been deleted"); + + data_to_game_coords(&x1, &y1); + data_to_game_coords(&width, &height); + + if ((width > game.SpriteInfos[sds->slot].Width) || (height > game.SpriteInfos[sds->slot].Height)) + quit("!DynamicSprite.Crop: requested to crop an area larger than the source"); + + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + // blit it cropped + newPic->Blit(spriteset[sds->slot], x1, y1, 0, 0, newPic->GetWidth(), newPic->GetHeight()); + + delete spriteset[sds->slot]; + + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int height) { + if ((angle < 1) || (angle > 359)) + quit("!DynamicSprite.Rotate: invalid angle (must be 1-359)"); + if (sds->slot == 0) + quit("!DynamicSprite.Rotate: sprite has been deleted"); + + if ((width == SCR_NO_VALUE) || (height == SCR_NO_VALUE)) { + // calculate the new image size automatically + // 1 degree = 181 degrees in terms of x/y size, so % 180 + int useAngle = angle % 180; + // and 0..90 is the same as 180..90 + if (useAngle > 90) + useAngle = 180 - useAngle; + // useAngle is now between 0 and 90 (otherwise the sin/cos stuff doesn't work) + double angleInRadians = (double)useAngle * (M_PI / 180.0); + double sinVal = sin(angleInRadians); + double cosVal = cos(angleInRadians); + + width = (cosVal * (double)game.SpriteInfos[sds->slot].Width + sinVal * (double)game.SpriteInfos[sds->slot].Height); + height = (sinVal * (double)game.SpriteInfos[sds->slot].Width + cosVal * (double)game.SpriteInfos[sds->slot].Height); + } + else { + data_to_game_coords(&width, &height); + } + + // convert to allegro angle + angle = (angle * 256) / 360; + + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + + // rotate the sprite about its centre + // (+ width%2 fixes one pixel offset problem) + newPic->RotateBlt(spriteset[sds->slot], width / 2 + width % 2, height / 2, + game.SpriteInfos[sds->slot].Width / 2, game.SpriteInfos[sds->slot].Height / 2, itofix(angle)); + + delete spriteset[sds->slot]; + + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance) +{ + Bitmap *source = spriteset[sds->slot]; + Bitmap *newPic = BitmapHelper::CreateBitmap(source->GetWidth(), source->GetHeight(), source->GetColorDepth()); + + tint_image(newPic, source, red, green, blue, saturation, (luminance * 25) / 10); + + delete source; + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char* namm) +{ + if (sds->slot == 0) + quit("!DynamicSprite.SaveToFile: sprite has been deleted"); + + auto filename = String(namm); + if (filename.FindChar('.') == -1) + filename.Append(".bmp"); + + ResolvedPath rp; + if (!ResolveWritePathAndCreateDirs(filename, rp)) + return 0; + return spriteset[sds->slot]->SaveToFile(rp.FullPath, palette) ? 1 : 0; +} + +ScriptDynamicSprite* DynamicSprite_CreateFromSaveGame(int sgslot, int width, int height) { + int slotnum = LoadSaveSlotScreenshot(sgslot, width, height); + if (slotnum) { + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(slotnum); + return new_spr; + } + return nullptr; +} + +ScriptDynamicSprite* DynamicSprite_CreateFromFile(const char *filename) { + int slotnum = LoadImageFile(filename); + if (slotnum) { + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(slotnum); + return new_spr; + } + return nullptr; +} + +ScriptDynamicSprite* DynamicSprite_CreateFromScreenShot(int width, int height) { + + // TODO: refactor and merge with create_savegame_screenshot() + + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; + + const Rect &viewport = play.GetMainViewport(); + if (width <= 0) + width = viewport.GetWidth(); + else + width = data_to_game_coord(width); + + if (height <= 0) + height = viewport.GetHeight(); + else + height = data_to_game_coord(height); + + Bitmap *newPic = CopyScreenIntoBitmap(width, height); + + update_polled_stuff_if_runtime(); + + // replace the bitmap in the sprite set + add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic)); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; +} + +ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite(int slot, int preserveAlphaChannel) { + + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; + + if (!spriteset.DoesSpriteExist(slot)) + quitprintf("DynamicSprite.CreateFromExistingSprite: sprite %d does not exist", slot); + + // create a new sprite as a copy of the existing one + Bitmap *newPic = BitmapHelper::CreateBitmapCopy(spriteset[slot]); + if (newPic == nullptr) + return nullptr; + + bool hasAlpha = (preserveAlphaChannel) && ((game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); + + // replace the bitmap in the sprite set + add_dynamic_sprite(gotSlot, newPic, hasAlpha); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; +} + +ScriptDynamicSprite* DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface *sds, int x, int y, int width, int height) +{ + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; + + // use DrawingSurface resolution + sds->PointToGameResolution(&x, &y); + sds->SizeToGameResolution(&width, &height); + + Bitmap *ds = sds->StartDrawing(); + + if ((x < 0) || (y < 0) || (x + width > ds->GetWidth()) || (y + height > ds->GetHeight())) + quit("!DynamicSprite.CreateFromDrawingSurface: requested area is outside the surface"); + + int colDepth = ds->GetColorDepth(); + + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, colDepth); + if (newPic == nullptr) + return nullptr; + + newPic->Blit(ds, x, y, 0, 0, width, height); + + sds->FinishedDrawingReadOnly(); + + add_dynamic_sprite(gotSlot, newPic, (sds->hasAlphaChannel != 0)); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; +} + +ScriptDynamicSprite* DynamicSprite_Create(int width, int height, int alphaChannel) +{ + data_to_game_coords(&width, &height); + + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; + + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, game.GetColorDepth()); + if (newPic == nullptr) + return nullptr; + + if ((alphaChannel) && (game.GetColorDepth() < 32)) + alphaChannel = false; + + add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic), alphaChannel != 0); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; +} + +ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite_Old(int slot) +{ + return DynamicSprite_CreateFromExistingSprite(slot, 0); +} + +ScriptDynamicSprite* DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height) { + + if (frame == SCR_NO_VALUE) { + frame = play.bg_frame; + } + else if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount)) + quit("!DynamicSprite.CreateFromBackground: invalid frame specified"); + + if (x1 == SCR_NO_VALUE) { + x1 = 0; + y1 = 0; + width = play.room_width; + height = play.room_height; + } + else if ((x1 < 0) || (y1 < 0) || (width < 1) || (height < 1) || + (x1 + width > play.room_width) || (y1 + height > play.room_height)) + quit("!DynamicSprite.CreateFromBackground: invalid co-ordinates specified"); + + data_to_game_coords(&x1, &y1); + data_to_game_coords(&width, &height); + + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; + + // create a new sprite as a copy of the existing one + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, thisroom.BgFrames[frame].Graphic->GetColorDepth()); + if (newPic == nullptr) + return nullptr; + + newPic->Blit(thisroom.BgFrames[frame].Graphic.get(), x1, y1, 0, 0, width, height); + + // replace the bitmap in the sprite set + add_dynamic_sprite(gotSlot, newPic); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; +} + +//============================================================================= + +void add_dynamic_sprite(int gotSlot, Bitmap *redin, bool hasAlpha) { + + spriteset.SetSprite(gotSlot, redin); + + game.SpriteInfos[gotSlot].Flags = SPF_DYNAMICALLOC; + + if (redin->GetColorDepth() > 8) + game.SpriteInfos[gotSlot].Flags |= SPF_HICOLOR; + if (redin->GetColorDepth() > 16) + game.SpriteInfos[gotSlot].Flags |= SPF_TRUECOLOR; + if (hasAlpha) + game.SpriteInfos[gotSlot].Flags |= SPF_ALPHACHANNEL; + + game.SpriteInfos[gotSlot].Width = redin->GetWidth(); + game.SpriteInfos[gotSlot].Height = redin->GetHeight(); +} + +void free_dynamic_sprite (int gotSlot) { + int tt; + + if ((gotSlot < 0) || (gotSlot >= spriteset.GetSpriteSlotCount())) + quit("!FreeDynamicSprite: invalid slot number"); + + if ((game.SpriteInfos[gotSlot].Flags & SPF_DYNAMICALLOC) == 0) + quitprintf("!DeleteSprite: Attempted to free static sprite %d that was not loaded by the script", gotSlot); + + spriteset.RemoveSprite(gotSlot, true); + + game.SpriteInfos[gotSlot].Flags = 0; + game.SpriteInfos[gotSlot].Width = 0; + game.SpriteInfos[gotSlot].Height = 0; + + // ensure it isn't still on any GUI buttons + for (tt = 0; tt < numguibuts; tt++) { + if (guibuts[tt].IsDeleted()) + continue; + if (guibuts[tt].Image == gotSlot) + guibuts[tt].Image = 0; + if (guibuts[tt].CurrentImage == gotSlot) + guibuts[tt].CurrentImage = 0; + if (guibuts[tt].MouseOverImage == gotSlot) + guibuts[tt].MouseOverImage = 0; + if (guibuts[tt].PushedImage == gotSlot) + guibuts[tt].PushedImage = 0; + } + + // force refresh of any object caches using the sprite + if (croom != nullptr) + { + for (tt = 0; tt < croom->numobj; tt++) + { + if (objs[tt].num == gotSlot) + { + objs[tt].num = 0; + objcache[tt].sppic = -1; + } + else if (objcache[tt].sppic == gotSlot) + objcache[tt].sppic = -1; + } + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// void (ScriptDynamicSprite *sds, int width, int height, int x, int y) +RuntimeScriptValue Sc_DynamicSprite_ChangeCanvasSize(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(ScriptDynamicSprite, DynamicSprite_ChangeCanvasSize); +} + +// void (ScriptDynamicSprite *sds, int sourceSprite) +RuntimeScriptValue Sc_DynamicSprite_CopyTransparencyMask(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDynamicSprite, DynamicSprite_CopyTransparencyMask); +} + +// void (ScriptDynamicSprite *sds, int x1, int y1, int width, int height) +RuntimeScriptValue Sc_DynamicSprite_Crop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(ScriptDynamicSprite, DynamicSprite_Crop); +} + +// void (ScriptDynamicSprite *sds) +RuntimeScriptValue Sc_DynamicSprite_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptDynamicSprite, DynamicSprite_Delete); +} + +// void (ScriptDynamicSprite *sds, int direction) +RuntimeScriptValue Sc_DynamicSprite_Flip(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptDynamicSprite, DynamicSprite_Flip); +} + +// ScriptDrawingSurface* (ScriptDynamicSprite *dss) +RuntimeScriptValue Sc_DynamicSprite_GetDrawingSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJAUTO(ScriptDynamicSprite, ScriptDrawingSurface, DynamicSprite_GetDrawingSurface); +} + +// void (ScriptDynamicSprite *sds, int width, int height) +RuntimeScriptValue Sc_DynamicSprite_Resize(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptDynamicSprite, DynamicSprite_Resize); +} + +// void (ScriptDynamicSprite *sds, int angle, int width, int height) +RuntimeScriptValue Sc_DynamicSprite_Rotate(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(ScriptDynamicSprite, DynamicSprite_Rotate); +} + +// int (ScriptDynamicSprite *sds, const char* namm) +RuntimeScriptValue Sc_DynamicSprite_SaveToFile(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(ScriptDynamicSprite, DynamicSprite_SaveToFile, const char); +} + +// void (ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance) +RuntimeScriptValue Sc_DynamicSprite_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(ScriptDynamicSprite, DynamicSprite_Tint); +} + +// int (ScriptDynamicSprite *sds) +RuntimeScriptValue Sc_DynamicSprite_GetColorDepth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetColorDepth); +} + +// int (ScriptDynamicSprite *sds) +RuntimeScriptValue Sc_DynamicSprite_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetGraphic); +} + +// int (ScriptDynamicSprite *sds) +RuntimeScriptValue Sc_DynamicSprite_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetHeight); +} + +// int (ScriptDynamicSprite *sds) +RuntimeScriptValue Sc_DynamicSprite_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetWidth); +} + +// ScriptDynamicSprite* (int width, int height, int alphaChannel) +RuntimeScriptValue Sc_DynamicSprite_Create(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT3(ScriptDynamicSprite, DynamicSprite_Create); +} + +// ScriptDynamicSprite* (int frame, int x1, int y1, int width, int height) +RuntimeScriptValue Sc_DynamicSprite_CreateFromBackground(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT5(ScriptDynamicSprite, DynamicSprite_CreateFromBackground); +} + +// ScriptDynamicSprite* (ScriptDrawingSurface *sds, int x, int y, int width, int height) +RuntimeScriptValue Sc_DynamicSprite_CreateFromDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_POBJ_PINT4(ScriptDynamicSprite, DynamicSprite_CreateFromDrawingSurface, ScriptDrawingSurface); +} + +// ScriptDynamicSprite* (int slot) +RuntimeScriptValue Sc_DynamicSprite_CreateFromExistingSprite_Old(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT(ScriptDynamicSprite, DynamicSprite_CreateFromExistingSprite_Old); +} + +// ScriptDynamicSprite* (int slot, int preserveAlphaChannel) +RuntimeScriptValue Sc_DynamicSprite_CreateFromExistingSprite(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT2(ScriptDynamicSprite, DynamicSprite_CreateFromExistingSprite); +} + +// ScriptDynamicSprite* (const char *filename) +RuntimeScriptValue Sc_DynamicSprite_CreateFromFile(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_POBJ(ScriptDynamicSprite, DynamicSprite_CreateFromFile, const char); +} + +// ScriptDynamicSprite* (int sgslot, int width, int height) +RuntimeScriptValue Sc_DynamicSprite_CreateFromSaveGame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT3(ScriptDynamicSprite, DynamicSprite_CreateFromSaveGame); +} + +// ScriptDynamicSprite* (int width, int height) +RuntimeScriptValue Sc_DynamicSprite_CreateFromScreenShot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT2(ScriptDynamicSprite, DynamicSprite_CreateFromScreenShot); +} + + +void RegisterDynamicSpriteAPI() +{ + ccAddExternalObjectFunction("DynamicSprite::ChangeCanvasSize^4", Sc_DynamicSprite_ChangeCanvasSize); + ccAddExternalObjectFunction("DynamicSprite::CopyTransparencyMask^1", Sc_DynamicSprite_CopyTransparencyMask); + ccAddExternalObjectFunction("DynamicSprite::Crop^4", Sc_DynamicSprite_Crop); + ccAddExternalObjectFunction("DynamicSprite::Delete", Sc_DynamicSprite_Delete); + ccAddExternalObjectFunction("DynamicSprite::Flip^1", Sc_DynamicSprite_Flip); + ccAddExternalObjectFunction("DynamicSprite::GetDrawingSurface^0", Sc_DynamicSprite_GetDrawingSurface); + ccAddExternalObjectFunction("DynamicSprite::Resize^2", Sc_DynamicSprite_Resize); + ccAddExternalObjectFunction("DynamicSprite::Rotate^3", Sc_DynamicSprite_Rotate); + ccAddExternalObjectFunction("DynamicSprite::SaveToFile^1", Sc_DynamicSprite_SaveToFile); + ccAddExternalObjectFunction("DynamicSprite::Tint^5", Sc_DynamicSprite_Tint); + ccAddExternalObjectFunction("DynamicSprite::get_ColorDepth", Sc_DynamicSprite_GetColorDepth); + ccAddExternalObjectFunction("DynamicSprite::get_Graphic", Sc_DynamicSprite_GetGraphic); + ccAddExternalObjectFunction("DynamicSprite::get_Height", Sc_DynamicSprite_GetHeight); + ccAddExternalObjectFunction("DynamicSprite::get_Width", Sc_DynamicSprite_GetWidth); + ccAddExternalStaticFunction("DynamicSprite::Create^3", Sc_DynamicSprite_Create); + ccAddExternalStaticFunction("DynamicSprite::CreateFromBackground", Sc_DynamicSprite_CreateFromBackground); + ccAddExternalStaticFunction("DynamicSprite::CreateFromDrawingSurface^5", Sc_DynamicSprite_CreateFromDrawingSurface); + ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^1", Sc_DynamicSprite_CreateFromExistingSprite_Old); + ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^2", Sc_DynamicSprite_CreateFromExistingSprite); + ccAddExternalStaticFunction("DynamicSprite::CreateFromFile", Sc_DynamicSprite_CreateFromFile); + ccAddExternalStaticFunction("DynamicSprite::CreateFromSaveGame", Sc_DynamicSprite_CreateFromSaveGame); + ccAddExternalStaticFunction("DynamicSprite::CreateFromScreenShot", Sc_DynamicSprite_CreateFromScreenShot); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DynamicSprite::ChangeCanvasSize^4", (void*)DynamicSprite_ChangeCanvasSize); + ccAddExternalFunctionForPlugin("DynamicSprite::CopyTransparencyMask^1", (void*)DynamicSprite_CopyTransparencyMask); + ccAddExternalFunctionForPlugin("DynamicSprite::Crop^4", (void*)DynamicSprite_Crop); + ccAddExternalFunctionForPlugin("DynamicSprite::Delete", (void*)DynamicSprite_Delete); + ccAddExternalFunctionForPlugin("DynamicSprite::Flip^1", (void*)DynamicSprite_Flip); + ccAddExternalFunctionForPlugin("DynamicSprite::GetDrawingSurface^0", (void*)DynamicSprite_GetDrawingSurface); + ccAddExternalFunctionForPlugin("DynamicSprite::Resize^2", (void*)DynamicSprite_Resize); + ccAddExternalFunctionForPlugin("DynamicSprite::Rotate^3", (void*)DynamicSprite_Rotate); + ccAddExternalFunctionForPlugin("DynamicSprite::SaveToFile^1", (void*)DynamicSprite_SaveToFile); + ccAddExternalFunctionForPlugin("DynamicSprite::Tint^5", (void*)DynamicSprite_Tint); + ccAddExternalFunctionForPlugin("DynamicSprite::get_ColorDepth", (void*)DynamicSprite_GetColorDepth); + ccAddExternalFunctionForPlugin("DynamicSprite::get_Graphic", (void*)DynamicSprite_GetGraphic); + ccAddExternalFunctionForPlugin("DynamicSprite::get_Height", (void*)DynamicSprite_GetHeight); + ccAddExternalFunctionForPlugin("DynamicSprite::get_Width", (void*)DynamicSprite_GetWidth); + ccAddExternalFunctionForPlugin("DynamicSprite::Create^3", (void*)DynamicSprite_Create); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromBackground", (void*)DynamicSprite_CreateFromBackground); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromDrawingSurface^5", (void*)DynamicSprite_CreateFromDrawingSurface); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromExistingSprite^1", (void*)DynamicSprite_CreateFromExistingSprite_Old); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromExistingSprite^2", (void*)DynamicSprite_CreateFromExistingSprite); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromFile", (void*)DynamicSprite_CreateFromFile); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromSaveGame", (void*)DynamicSprite_CreateFromSaveGame); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromScreenShot", (void*)DynamicSprite_CreateFromScreenShot); +} diff --git a/engines/ags/engine/ac/dynamicsprite.h b/engines/ags/engine/ac/dynamicsprite.h new file mode 100644 index 000000000000..6602c8540285 --- /dev/null +++ b/engines/ags/engine/ac/dynamicsprite.h @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__DYNAMICSPRITE_H +#define __AGS_EE_AC__DYNAMICSPRITE_H + +#include "ac/dynobj/scriptdynamicsprite.h" +#include "ac/dynobj/scriptdrawingsurface.h" + +void DynamicSprite_Delete(ScriptDynamicSprite *sds); +ScriptDrawingSurface* DynamicSprite_GetDrawingSurface(ScriptDynamicSprite *dss); +int DynamicSprite_GetGraphic(ScriptDynamicSprite *sds); +int DynamicSprite_GetWidth(ScriptDynamicSprite *sds); +int DynamicSprite_GetHeight(ScriptDynamicSprite *sds); +int DynamicSprite_GetColorDepth(ScriptDynamicSprite *sds); +void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height); +void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction); +void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSprite); +void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y); +void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int height); +void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int height); +void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance); +int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char* namm); +ScriptDynamicSprite* DynamicSprite_CreateFromSaveGame(int sgslot, int width, int height); +ScriptDynamicSprite* DynamicSprite_CreateFromFile(const char *filename); +ScriptDynamicSprite* DynamicSprite_CreateFromScreenShot(int width, int height); +ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite(int slot, int preserveAlphaChannel); +ScriptDynamicSprite* DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface *sds, int x, int y, int width, int height); +ScriptDynamicSprite* DynamicSprite_Create(int width, int height, int alphaChannel); +ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite_Old(int slot); +ScriptDynamicSprite* DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height); + + +void add_dynamic_sprite(int gotSlot, Common::Bitmap *redin, bool hasAlpha = false); +void free_dynamic_sprite (int gotSlot); + +#endif // __AGS_EE_AC__DYNAMICSPRITE_H diff --git a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h new file mode 100644 index 000000000000..cc6cb71c13be --- /dev/null +++ b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H +#define __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H + +#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ac/dynobj/cc_audiochannel.h" +#include "ac/dynobj/cc_audioclip.h" +#include "ac/dynobj/cc_character.h" +#include "ac/dynobj/cc_dialog.h" +#include "ac/dynobj/cc_gui.h" +#include "ac/dynobj/cc_guiobject.h" +#include "ac/dynobj/cc_hotspot.h" +#include "ac/dynobj/cc_inventory.h" +#include "ac/dynobj/cc_object.h" +#include "ac/dynobj/cc_region.h" + +#include "ac/dynobj/cc_serializer.h" + +#endif // __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H diff --git a/engines/ags/engine/ac/dynobj/all_scriptclasses.h b/engines/ags/engine/ac/dynobj/all_scriptclasses.h new file mode 100644 index 000000000000..bcaf7a1d4737 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/all_scriptclasses.h @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__ALLSCRIPTCLASSES_H +#define __AGS_EE_DYNOBJ__ALLSCRIPTCLASSES_H + +#include "ac/dynobj/scriptdatetime.h" +#include "ac/dynobj/scriptdialog.h" +#include "ac/dynobj/scriptdialogoptionsrendering.h" +#include "ac/dynobj/scriptdrawingsurface.h" +#include "ac/dynobj/scriptdynamicsprite.h" +#include "ac/dynobj/scriptgui.h" +#include "ac/dynobj/scripthotspot.h" +#include "ac/dynobj/scriptinvitem.h" +#include "ac/dynobj/scriptmouse.h" +#include "ac/dynobj/scriptobject.h" +#include "ac/dynobj/scriptoverlay.h" +#include "ac/dynobj/scriptregion.h" +#include "ac/dynobj/scriptstring.h" +#include "ac/dynobj/scriptsystem.h" +#include "ac/dynobj/scriptviewframe.h" + +#endif // __AGS_EE_DYNOBJ__ALLSCRIPTOBJECTS_H diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp new file mode 100644 index 000000000000..e1d0e6e6ee6e --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -0,0 +1,130 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "core/types.h" +#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ac/common.h" // quit() +#include "util/bbop.h" + +using namespace AGS::Common; + +// *** The script serialization routines for built-in types + +int AGSCCDynamicObject::Dispose(const char *address, bool force) { + // cannot be removed from memory + return 0; +} + +void AGSCCDynamicObject::StartSerialize(char *sbuffer) { + bytesSoFar = 0; + serbuffer = sbuffer; +} + +void AGSCCDynamicObject::SerializeInt(int val) { + char *chptr = &serbuffer[bytesSoFar]; + int *iptr = (int*)chptr; + *iptr = BBOp::Int32FromLE(val); + bytesSoFar += 4; +} + +void AGSCCDynamicObject::SerializeFloat(float val) { + char *chptr = &serbuffer[bytesSoFar]; + float *fptr = (float*)chptr; + *fptr = BBOp::FloatFromLE(val); + bytesSoFar += 4; +} + +int AGSCCDynamicObject::EndSerialize() { + return bytesSoFar; +} + +void AGSCCDynamicObject::StartUnserialize(const char *sbuffer, int pTotalBytes) { + bytesSoFar = 0; + totalBytes = pTotalBytes; + serbuffer = (char*)sbuffer; +} + +int AGSCCDynamicObject::UnserializeInt() { + if (bytesSoFar >= totalBytes) + quit("Unserialise: internal error: read past EOF"); + + char *chptr = &serbuffer[bytesSoFar]; + bytesSoFar += 4; + return BBOp::Int32FromLE(*((int*)chptr)); +} + +float AGSCCDynamicObject::UnserializeFloat() { + if (bytesSoFar >= totalBytes) + quit("Unserialise: internal error: read past EOF"); + + char *chptr = &serbuffer[bytesSoFar]; + bytesSoFar += 4; + return BBOp::FloatFromLE(*((float*)chptr)); +} + +const char* AGSCCDynamicObject::GetFieldPtr(const char *address, intptr_t offset) +{ + return address + offset; +} + +void AGSCCDynamicObject::Read(const char *address, intptr_t offset, void *dest, int size) +{ + memcpy(dest, address + offset, size); +} + +uint8_t AGSCCDynamicObject::ReadInt8(const char *address, intptr_t offset) +{ + return *(uint8_t*)(address + offset); +} + +int16_t AGSCCDynamicObject::ReadInt16(const char *address, intptr_t offset) +{ + return *(int16_t*)(address + offset); +} + +int32_t AGSCCDynamicObject::ReadInt32(const char *address, intptr_t offset) +{ + return *(int32_t*)(address + offset); +} + +float AGSCCDynamicObject::ReadFloat(const char *address, intptr_t offset) +{ + return *(float*)(address + offset); +} + +void AGSCCDynamicObject::Write(const char *address, intptr_t offset, void *src, int size) +{ + memcpy((void*)(address + offset), src, size); +} + +void AGSCCDynamicObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) +{ + *(uint8_t*)(address + offset) = val; +} + +void AGSCCDynamicObject::WriteInt16(const char *address, intptr_t offset, int16_t val) +{ + *(int16_t*)(address + offset) = val; +} + +void AGSCCDynamicObject::WriteInt32(const char *address, intptr_t offset, int32_t val) +{ + *(int32_t*)(address + offset) = val; +} + +void AGSCCDynamicObject::WriteFloat(const char *address, intptr_t offset, float val) +{ + *(float*)(address + offset) = val; +} diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h new file mode 100644 index 000000000000..3c2d795e1b9a --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h @@ -0,0 +1,60 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCDYNAMICOBJECT_H +#define __AC_CCDYNAMICOBJECT_H + +#include "ac/dynobj/cc_dynamicobject.h" + +struct AGSCCDynamicObject : ICCDynamicObject { +protected: + virtual ~AGSCCDynamicObject() = default; +public: + // default implementation + int Dispose(const char *address, bool force) override; + + // TODO: pass savegame format version + virtual void Unserialize(int index, const char *serializedData, int dataSize) = 0; + + // Legacy support for reading and writing object values by their relative offset + const char* GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; + +protected: + // Savegame serialization + // TODO: reimplement with the proper memory stream?! + int bytesSoFar; + int totalBytes; + char *serbuffer; + + void StartSerialize(char *sbuffer); + void SerializeInt(int val); + void SerializeFloat(float val); + int EndSerialize(); + void StartUnserialize(const char *sbuffer, int pTotalBytes); + int UnserializeInt(); + float UnserializeFloat(); + +}; + +#endif // __AC_CCDYNAMICOBJECT_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp new file mode 100644 index 000000000000..40f96af17017 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_audiochannel.h" +#include "ac/dynobj/scriptaudiochannel.h" +#include "media/audio/audio_system.h" + +extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; + +const char *CCAudioChannel::GetType() { + return "AudioChannel"; +} + +int CCAudioChannel::Serialize(const char *address, char *buffer, int bufsize) { + ScriptAudioChannel *ach = (ScriptAudioChannel*)address; + StartSerialize(buffer); + SerializeInt(ach->id); + return EndSerialize(); +} + +void CCAudioChannel::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int id = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrAudioChannel[id], this); +} diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.h b/engines/ags/engine/ac/dynobj/cc_audiochannel.h new file mode 100644 index 000000000000..d13dd4cd0910 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.h @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H +#define __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCAudioChannel final : AGSCCDynamicObject { + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; +}; + +#endif // __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp new file mode 100644 index 000000000000..31e4a0105bc9 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_audioclip.h" +#include "ac/dynobj/scriptaudioclip.h" +#include "ac/gamesetupstruct.h" + +extern GameSetupStruct game; + +const char *CCAudioClip::GetType() { + return "AudioClip"; +} + +int CCAudioClip::Serialize(const char *address, char *buffer, int bufsize) { + ScriptAudioClip *ach = (ScriptAudioClip*)address; + StartSerialize(buffer); + SerializeInt(ach->id); + return EndSerialize(); +} + +void CCAudioClip::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int id = UnserializeInt(); + ccRegisterUnserializedObject(index, &game.audioClips[id], this); +} diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.h b/engines/ags/engine/ac/dynobj/cc_audioclip.h new file mode 100644 index 000000000000..b8b633a63c27 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.h @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__CCAUDIOCLIP_H +#define __AGS_EE_DYNOBJ__CCAUDIOCLIP_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCAudioClip final : AGSCCDynamicObject { + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; +}; + +#endif // __AGS_EE_DYNOBJ__CCAUDIOCLIP_H diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp new file mode 100644 index 000000000000..00478f2b08b6 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -0,0 +1,58 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_character.h" +#include "ac/characterinfo.h" +#include "ac/global_character.h" +#include "ac/gamesetupstruct.h" +#include "ac/game_version.h" + +extern GameSetupStruct game; + +// return the type name of the object +const char *CCCharacter::GetType() { + return "Character"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCCharacter::Serialize(const char *address, char *buffer, int bufsize) { + CharacterInfo *chaa = (CharacterInfo*)address; + StartSerialize(buffer); + SerializeInt(chaa->index_id); + return EndSerialize(); +} + +void CCCharacter::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &game.chars[num], this); +} + +void CCCharacter::WriteInt16(const char *address, intptr_t offset, int16_t val) +{ + *(int16_t*)(address + offset) = val; + + // Detect when a game directly modifies the inventory, which causes the displayed + // and actual inventory to diverge since 2.70. Force an update of the displayed + // inventory for older games that reply on the previous behaviour. + if (loaded_game_file_version < kGameVersion_270) + { + const int invoffset = 112; + if (offset >= invoffset && offset < (invoffset + MAX_INV * sizeof(short))) + { + update_invorder(); + } + } +} diff --git a/engines/ags/engine/ac/dynobj/cc_character.h b/engines/ags/engine/ac/dynobj/cc_character.h new file mode 100644 index 000000000000..d610cb914f2a --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_character.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCCHARACTER_H +#define __AC_CCCHARACTER_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCCharacter final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; +}; + +#endif // __AC_CCCHARACTER_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp new file mode 100644 index 000000000000..5c52802cae38 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_dialog.h" +#include "ac/dialog.h" +#include "ac/dialogtopic.h" +#include "ac/gamestructdefines.h" + +// return the type name of the object +const char *CCDialog::GetType() { + return "Dialog"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCDialog::Serialize(const char *address, char *buffer, int bufsize) { + ScriptDialog *shh = (ScriptDialog*)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); +} + +void CCDialog::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrDialog[num], this); +} diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.h b/engines/ags/engine/ac/dynobj/cc_dialog.h new file mode 100644 index 000000000000..bf1a95e122af --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_dialog.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCDIALOG_H +#define __AC_CCDIALOG_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCDialog final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + +}; + +#endif // __AC_CCDIALOG_H diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp new file mode 100644 index 000000000000..694ef902132a --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp @@ -0,0 +1,161 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "cc_dynamicarray.h" + +// return the type name of the object +const char *CCDynamicArray::GetType() { + return CC_DYNAMIC_ARRAY_TYPE_NAME; +} + +int CCDynamicArray::Dispose(const char *address, bool force) { + address -= 8; + + // If it's an array of managed objects, release their ref counts; + // except if this array is forcefully removed from the managed pool, + // in which case just ignore these. + if (!force) + { + int *elementCount = (int*)address; + if (elementCount[0] & ARRAY_MANAGED_TYPE_FLAG) + { + elementCount[0] &= ~ARRAY_MANAGED_TYPE_FLAG; + for (int i = 0; i < elementCount[0]; i++) + { + if (elementCount[2 + i] != 0) + { + ccReleaseObjectReference(elementCount[2 + i]); + } + } + } + } + + delete address; + return 1; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCDynamicArray::Serialize(const char *address, char *buffer, int bufsize) { + int *sizeInBytes = &((int*)address)[-1]; + int sizeToWrite = *sizeInBytes + 8; + if (sizeToWrite > bufsize) + { + // buffer not big enough, ask for a bigger one + return -sizeToWrite; + } + memcpy(buffer, address - 8, sizeToWrite); + return sizeToWrite; +} + +void CCDynamicArray::Unserialize(int index, const char *serializedData, int dataSize) { + char *newArray = new char[dataSize]; + memcpy(newArray, serializedData, dataSize); + ccRegisterUnserializedObject(index, &newArray[8], this); +} + +DynObjectRef CCDynamicArray::Create(int numElements, int elementSize, bool isManagedType) +{ + char *newArray = new char[numElements * elementSize + 8]; + memset(newArray, 0, numElements * elementSize + 8); + int *sizePtr = (int*)newArray; + sizePtr[0] = numElements; + sizePtr[1] = numElements * elementSize; + if (isManagedType) + sizePtr[0] |= ARRAY_MANAGED_TYPE_FLAG; + void *obj_ptr = &newArray[8]; + int32_t handle = ccRegisterManagedObject(obj_ptr, this); + if (handle == 0) + { + delete[] newArray; + return DynObjectRef(0, nullptr); + } + return DynObjectRef(handle, obj_ptr); +} + + +const char* CCDynamicArray::GetFieldPtr(const char *address, intptr_t offset) +{ + return address + offset; +} + +void CCDynamicArray::Read(const char *address, intptr_t offset, void *dest, int size) +{ + memcpy(dest, address + offset, size); +} + +uint8_t CCDynamicArray::ReadInt8(const char *address, intptr_t offset) +{ + return *(uint8_t*)(address + offset); +} + +int16_t CCDynamicArray::ReadInt16(const char *address, intptr_t offset) +{ + return *(int16_t*)(address + offset); +} + +int32_t CCDynamicArray::ReadInt32(const char *address, intptr_t offset) +{ + return *(int32_t*)(address + offset); +} + +float CCDynamicArray::ReadFloat(const char *address, intptr_t offset) +{ + return *(float*)(address + offset); +} + +void CCDynamicArray::Write(const char *address, intptr_t offset, void *src, int size) +{ + memcpy((void*)(address + offset), src, size); +} + +void CCDynamicArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) +{ + *(uint8_t*)(address + offset) = val; +} + +void CCDynamicArray::WriteInt16(const char *address, intptr_t offset, int16_t val) +{ + *(int16_t*)(address + offset) = val; +} + +void CCDynamicArray::WriteInt32(const char *address, intptr_t offset, int32_t val) +{ + *(int32_t*)(address + offset) = val; +} + +void CCDynamicArray::WriteFloat(const char *address, intptr_t offset, float val) +{ + *(float*)(address + offset) = val; +} + +CCDynamicArray globalDynamicArray; + + +DynObjectRef DynamicArrayHelpers::CreateStringArray(const std::vector items) +{ + // NOTE: we need element size of "handle" for array of managed pointers + DynObjectRef arr = globalDynamicArray.Create(items.size(), sizeof(int32_t), true); + if (!arr.second) + return arr; + // Create script strings and put handles into array + int32_t *slots = static_cast(arr.second); + for (auto s : items) + { + DynObjectRef str = stringClassImpl->CreateString(s); + *(slots++) = str.first; + } + return arr; +} diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h new file mode 100644 index 000000000000..4619ff7137de --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -0,0 +1,58 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __CC_DYNAMICARRAY_H +#define __CC_DYNAMICARRAY_H + +#include +#include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject + +#define CC_DYNAMIC_ARRAY_TYPE_NAME "CCDynamicArray" +#define ARRAY_MANAGED_TYPE_FLAG 0x80000000 + +struct CCDynamicArray final : ICCDynamicObject +{ + // return the type name of the object + const char *GetType() override; + int Dispose(const char *address, bool force) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + virtual void Unserialize(int index, const char *serializedData, int dataSize); + // Create managed array object and return a pointer to the beginning of a buffer + DynObjectRef Create(int numElements, int elementSize, bool isManagedType); + + // Legacy support for reading and writing object values by their relative offset + const char* GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; +}; + +extern CCDynamicArray globalDynamicArray; + +// Helper functions for setting up dynamic arrays. +namespace DynamicArrayHelpers +{ + // Create array of managed strings + DynObjectRef CreateStringArray(const std::vector); +}; + +#endif \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp new file mode 100644 index 000000000000..7c9a1039d4d0 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp @@ -0,0 +1,151 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// C-Script run-time interpreter (c) 2001 Chris Jones +// +// You must DISABLE OPTIMIZATIONS AND REGISTER VARIABLES in your compiler +// when compiling this, or strange results can happen. +// +// There is a problem with importing functions on 16-bit compilers: the +// script system assumes that all parameters are passed as 4 bytes, which +// ints are not on 16-bit systems. Be sure to define all parameters as longs, +// or join the 21st century and switch to DJGPP or Visual C++. +// +//============================================================================= + +//#define DEBUG_MANAGED_OBJECTS + +#include +#include +#include "ac/dynobj/cc_dynamicobject.h" +#include "ac/dynobj/managedobjectpool.h" +#include "debug/out.h" +#include "script/cc_error.h" +#include "script/script_common.h" +#include "util/stream.h" + +using namespace AGS::Common; + +ICCStringClass *stringClassImpl = nullptr; + +// set the class that will be used for dynamic strings +void ccSetStringClassImpl(ICCStringClass *theClass) { + stringClassImpl = theClass; +} + +// register a memory handle for the object and allow script +// pointers to point to it +int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *callback, bool plugin_object) { + int32_t handl = pool.AddObject((const char*)object, callback, plugin_object); + + ManagedObjectLog("Register managed object type '%s' handle=%d addr=%08X", + ((callback == NULL) ? "(unknown)" : callback->GetType()), handl, object); + + return handl; +} + +// register a de-serialized object +int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *callback, bool plugin_object) { + return pool.AddUnserializedObject((const char*)object, callback, plugin_object, index); +} + +// unregister a particular object +int ccUnRegisterManagedObject(const void *object) { + return pool.RemoveObject((const char*)object); +} + +// remove all registered objects +void ccUnregisterAllObjects() { + pool.reset(); +} + +// serialize all objects to disk +void ccSerializeAllObjects(Stream *out) { + pool.WriteToDisk(out); +} + +// un-serialise all objects (will remove all currently registered ones) +int ccUnserializeAllObjects(Stream *in, ICCObjectReader *callback) { + return pool.ReadFromDisk(in, callback); +} + +// dispose the object if RefCount==0 +void ccAttemptDisposeObject(int32_t handle) { + pool.CheckDispose(handle); +} + +// translate between object handles and memory addresses +int32_t ccGetObjectHandleFromAddress(const char *address) { + // set to null + if (address == nullptr) + return 0; + + int32_t handl = pool.AddressToHandle(address); + + ManagedObjectLog("Line %d WritePtr: %08X to %d", currentline, address, handl); + + if (handl == 0) { + cc_error("Pointer cast failure: the object being pointed to is not in the managed object pool"); + return -1; + } + return handl; +} + +const char *ccGetObjectAddressFromHandle(int32_t handle) { + if (handle == 0) { + return nullptr; + } + const char *addr = pool.HandleToAddress(handle); + + ManagedObjectLog("Line %d ReadPtr: %d to %08X", currentline, handle, addr); + + if (addr == nullptr) { + cc_error("Error retrieving pointer: invalid handle %d", handle); + return nullptr; + } + return addr; +} + +ScriptValueType ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager) +{ + if (handle == 0) { + object = nullptr; + manager = nullptr; + return kScValUndefined; + } + ScriptValueType obj_type = pool.HandleToAddressAndManager(handle, object, manager); + if (obj_type == kScValUndefined) { + cc_error("Error retrieving pointer: invalid handle %d", handle); + } + return obj_type; +} + +int ccAddObjectReference(int32_t handle) { + if (handle == 0) + return 0; + + return pool.AddRef(handle); +} + +int ccReleaseObjectReference(int32_t handle) { + if (handle == 0) + return 0; + + if (pool.HandleToAddress(handle) == nullptr) { + cc_error("Error releasing pointer: invalid handle %d", handle); + return -1; + } + + return pool.SubRef(handle); +} diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h new file mode 100644 index 000000000000..2d417d5018af --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -0,0 +1,116 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Managed script object interface. +// +//============================================================================= +#ifndef __CC_DYNAMICOBJECT_H +#define __CC_DYNAMICOBJECT_H + +#include +#include "core/types.h" + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +// A pair of managed handle and abstract object pointer +typedef std::pair DynObjectRef; + + +// OBJECT-BASED SCRIPTING RUNTIME FUNCTIONS +// interface +struct ICCDynamicObject { + // when a ref count reaches 0, this is called with the address + // of the object. Return 1 to remove the object from memory, 0 to + // leave it + // The "force" flag tells system to detach the object, breaking any links and references + // to other managed objects or game resources (instead of disposing these too). + // TODO: it might be better to rewrite the managed pool and remove this flag at all, + // because it makes the use of this interface prone to mistakes. + virtual int Dispose(const char *address, bool force = false) = 0; + // return the type name of the object + virtual const char *GetType() = 0; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + // TODO: pass savegame format version + virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; + + // Legacy support for reading and writing object values by their relative offset. + // WARNING: following were never a part of plugin API, therefore these methods + // should **never** be called for kScValPluginObject script objects! + // + // RE: GetFieldPtr() + // According to AGS script specification, when the old-string pointer or char array is passed + // as an argument, the byte-code does not include any specific command for the member variable + // retrieval and instructs to pass an address of the object itself with certain offset. + // This results in functions like StrCopy writing directly over object address. + // There may be other implementations, but the big question is: how to detect when this is + // necessary, because byte-code does not contain any distinct operation for this case. + // The worst thing here is that with the current byte-code structure we can never tell whether + // offset 0 means getting pointer to whole object or a pointer to its first field. + virtual const char* GetFieldPtr(const char *address, intptr_t offset) = 0; + virtual void Read(const char *address, intptr_t offset, void *dest, int size) = 0; + virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; + virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; + virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; + virtual float ReadFloat(const char *address, intptr_t offset) = 0; + virtual void Write(const char *address, intptr_t offset, void *src, int size) = 0; + virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; + virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; + virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; + virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; + +protected: + ICCDynamicObject() = default; + ~ICCDynamicObject() = default; +}; + +struct ICCObjectReader { + // TODO: pass savegame format version + virtual void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) = 0; +}; +struct ICCStringClass { + virtual DynObjectRef CreateString(const char *fromText) = 0; +}; + +// set the class that will be used for dynamic strings +extern void ccSetStringClassImpl(ICCStringClass *theClass); +// register a memory handle for the object and allow script +// pointers to point to it +extern int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *, bool plugin_object = false); +// register a de-serialized object +extern int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *, bool plugin_object = false); +// unregister a particular object +extern int ccUnRegisterManagedObject(const void *object); +// remove all registered objects +extern void ccUnregisterAllObjects(); +// serialize all objects to disk +extern void ccSerializeAllObjects(Common::Stream *out); +// un-serialise all objects (will remove all currently registered ones) +extern int ccUnserializeAllObjects(Common::Stream *in, ICCObjectReader *callback); +// dispose the object if RefCount==0 +extern void ccAttemptDisposeObject(int32_t handle); +// translate between object handles and memory addresses +extern int32_t ccGetObjectHandleFromAddress(const char *address); +// TODO: not sure if it makes any sense whatsoever to use "const char*" +// in these functions, might as well change to char* or just void*. +extern const char *ccGetObjectAddressFromHandle(int32_t handle); + +extern int ccAddObjectReference(int32_t handle); +extern int ccReleaseObjectReference(int32_t handle); + +extern ICCStringClass *stringClassImpl; + +#endif // __CC_DYNAMICOBJECT_H diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h new file mode 100644 index 000000000000..0f22f30f174f --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h @@ -0,0 +1,11 @@ +#ifndef ADDR_AND_MANAGER_H +#define ADDR_AND_MANAGER_H + +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_dynamicobject.h" + +extern ScriptValueType ccGetObjectAddressAndManagerFromHandle( + int32_t handle, void *&object, ICCDynamicObject *&manager); + +#endif + diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp new file mode 100644 index 000000000000..40ff70c4a1e3 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_gui.h" +#include "ac/dynobj/scriptgui.h" + +extern ScriptGUI *scrGui; + +// return the type name of the object +const char *CCGUI::GetType() { + return "GUI"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCGUI::Serialize(const char *address, char *buffer, int bufsize) { + ScriptGUI *shh = (ScriptGUI*)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); +} + +void CCGUI::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrGui[num], this); +} \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_gui.h b/engines/ags/engine/ac/dynobj/cc_gui.h new file mode 100644 index 000000000000..b29f5171bce1 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_gui.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCGUI_H +#define __AC_CCGUI_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCGUI final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; +}; + +#endif // __AC_CCGUI_H diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp new file mode 100644 index 000000000000..a4d615332709 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -0,0 +1,42 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_guiobject.h" +#include "ac/dynobj/scriptgui.h" +#include "gui/guimain.h" +#include "gui/guiobject.h" + +using AGS::Common::GUIObject; + +// return the type name of the object +const char *CCGUIObject::GetType() { + return "GUIObject"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCGUIObject::Serialize(const char *address, char *buffer, int bufsize) { + GUIObject *guio = (GUIObject*)address; + StartSerialize(buffer); + SerializeInt(guio->ParentId); + SerializeInt(guio->Id); + return EndSerialize(); +} + +void CCGUIObject::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int guinum = UnserializeInt(); + int objnum = UnserializeInt(); + ccRegisterUnserializedObject(index, guis[guinum].GetControl(objnum), this); +} diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.h b/engines/ags/engine/ac/dynobj/cc_guiobject.h new file mode 100644 index 000000000000..2d261956f242 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCGUIOBJECT_H +#define __AC_CCGUIOBJECT_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCGUIObject final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + +}; + +#endif // __AC_CCGUIOBJECT_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp new file mode 100644 index 000000000000..cc109cd228f2 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_hotspot.h" +#include "ac/dynobj/scripthotspot.h" +#include "ac/common_defines.h" +#include "game/roomstruct.h" + +extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; + +// return the type name of the object +const char *CCHotspot::GetType() { + return "Hotspot"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCHotspot::Serialize(const char *address, char *buffer, int bufsize) { + ScriptHotspot *shh = (ScriptHotspot*)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); +} + +void CCHotspot::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrHotspot[num], this); +} \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.h b/engines/ags/engine/ac/dynobj/cc_hotspot.h new file mode 100644 index 000000000000..8137cd374077 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCHOTSPOT_H +#define __AC_CCHOTSPOT_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCHotspot final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + +}; + +#endif // __AC_CCHOTSPOT_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp new file mode 100644 index 000000000000..cf9268c997d7 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp @@ -0,0 +1,39 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_inventory.h" +#include "ac/dynobj/scriptinvitem.h" +#include "ac/characterinfo.h" + +extern ScriptInvItem scrInv[MAX_INV]; + +// return the type name of the object +const char *CCInventory::GetType() { + return "Inventory"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCInventory::Serialize(const char *address, char *buffer, int bufsize) { + ScriptInvItem *shh = (ScriptInvItem*)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); +} + +void CCInventory::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrInv[num], this); +} \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.h b/engines/ags/engine/ac/dynobj/cc_inventory.h new file mode 100644 index 000000000000..4e668aff7068 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_inventory.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCINVENTORY_H +#define __AC_CCINVENTORY_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCInventory final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + +}; + +#endif // __AC_CCINVENTORY_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp new file mode 100644 index 000000000000..215ad0e469c0 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_object.cpp @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_object.h" +#include "ac/dynobj/scriptobject.h" +#include "ac/common_defines.h" +#include "game/roomstruct.h" + +extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; + +// return the type name of the object +const char *CCObject::GetType() { + return "Object"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCObject::Serialize(const char *address, char *buffer, int bufsize) { + ScriptObject *shh = (ScriptObject*)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); +} + +void CCObject::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrObj[num], this); +} diff --git a/engines/ags/engine/ac/dynobj/cc_object.h b/engines/ags/engine/ac/dynobj/cc_object.h new file mode 100644 index 000000000000..6e654441325b --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_object.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCOBJECT_H +#define __AC_CCOBJECT_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCObject final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + +}; + +#endif // __AC_CCOBJECT_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp new file mode 100644 index 000000000000..92ba34911827 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_region.cpp @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_region.h" +#include "ac/dynobj/scriptregion.h" +#include "ac/common_defines.h" +#include "game/roomstruct.h" + +extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; + +// return the type name of the object +const char *CCRegion::GetType() { + return "Region"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int CCRegion::Serialize(const char *address, char *buffer, int bufsize) { + ScriptRegion *shh = (ScriptRegion*)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); +} + +void CCRegion::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrRegion[num], this); +} diff --git a/engines/ags/engine/ac/dynobj/cc_region.h b/engines/ags/engine/ac/dynobj/cc_region.h new file mode 100644 index 000000000000..626ee4e2bc5f --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_region.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CCREGION_H +#define __AC_CCREGION_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct CCRegion final : AGSCCDynamicObject { + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + +}; + +#endif // __AC_CCREGION_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp new file mode 100644 index 000000000000..140613116a61 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp @@ -0,0 +1,144 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/dynobj/cc_serializer.h" +#include "ac/dynobj/all_dynamicclasses.h" +#include "ac/dynobj/all_scriptclasses.h" +#include "ac/dynobj/scriptcamera.h" +#include "ac/dynobj/scriptcontainers.h" +#include "ac/dynobj/scriptfile.h" +#include "ac/dynobj/scriptuserobject.h" +#include "ac/dynobj/scriptviewport.h" +#include "ac/game.h" +#include "debug/debug_log.h" +#include "plugin/agsplugin.h" +#include "plugin/pluginobjectreader.h" + +extern CCGUIObject ccDynamicGUIObject; +extern CCCharacter ccDynamicCharacter; +extern CCHotspot ccDynamicHotspot; +extern CCRegion ccDynamicRegion; +extern CCInventory ccDynamicInv; +extern CCGUI ccDynamicGUI; +extern CCObject ccDynamicObject; +extern CCDialog ccDynamicDialog; +extern ScriptDrawingSurface* dialogOptionsRenderingSurface; +extern ScriptDialogOptionsRendering ccDialogOptionsRendering; +extern PluginObjectReader pluginReaders[MAX_PLUGIN_OBJECT_READERS]; +extern int numPluginReaders; + +// *** De-serialization of script objects + + + +void AGSDeSerializer::Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) { + if (strcmp(objectType, "GUIObject") == 0) { + ccDynamicGUIObject.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Character") == 0) { + ccDynamicCharacter.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Hotspot") == 0) { + ccDynamicHotspot.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Region") == 0) { + ccDynamicRegion.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Inventory") == 0) { + ccDynamicInv.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Dialog") == 0) { + ccDynamicDialog.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "GUI") == 0) { + ccDynamicGUI.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Object") == 0) { + ccDynamicObject.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "String") == 0) { + ScriptString *scf = new ScriptString(); + scf->Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "File") == 0) { + // files cannot be restored properly -- so just recreate + // the object; attempting any operations on it will fail + sc_File *scf = new sc_File(); + ccRegisterUnserializedObject(index, scf, scf); + } + else if (strcmp(objectType, "Overlay") == 0) { + ScriptOverlay *scf = new ScriptOverlay(); + scf->Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "DateTime") == 0) { + ScriptDateTime *scf = new ScriptDateTime(); + scf->Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "ViewFrame") == 0) { + ScriptViewFrame *scf = new ScriptViewFrame(); + scf->Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "DynamicSprite") == 0) { + ScriptDynamicSprite *scf = new ScriptDynamicSprite(); + scf->Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "DrawingSurface") == 0) { + ScriptDrawingSurface *sds = new ScriptDrawingSurface(); + sds->Unserialize(index, serializedData, dataSize); + + if (sds->isLinkedBitmapOnly) + { + dialogOptionsRenderingSurface = sds; + } + } + else if (strcmp(objectType, "DialogOptionsRendering") == 0) + { + ccDialogOptionsRendering.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "StringDictionary") == 0) + { + Dict_Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "StringSet") == 0) + { + Set_Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Viewport2") == 0) + { + Viewport_Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "Camera2") == 0) + { + Camera_Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "UserObject") == 0) { + ScriptUserObject *suo = new ScriptUserObject(); + suo->Unserialize(index, serializedData, dataSize); + } + else if (!unserialize_audio_script_object(index, objectType, serializedData, dataSize)) + { + // check if the type is read by a plugin + for (int ii = 0; ii < numPluginReaders; ii++) { + if (strcmp(objectType, pluginReaders[ii].type) == 0) { + pluginReaders[ii].reader->Unserialize(index, serializedData, dataSize); + return; + } + } + quitprintf("Unserialise: unknown object type: '%s'", objectType); + } +} + +AGSDeSerializer ccUnserializer; + diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h new file mode 100644 index 000000000000..d30a8f477d43 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -0,0 +1,27 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SERIALIZER_H +#define __AC_SERIALIZER_H + +#include "ac/dynobj/cc_dynamicobject.h" + +struct AGSDeSerializer : ICCObjectReader { + + void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) override; +}; + +extern AGSDeSerializer ccUnserializer; + +#endif // __AC_SERIALIZER_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp new file mode 100644 index 000000000000..422aff050fee --- /dev/null +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -0,0 +1,322 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include +#include +#include "ac/dynobj/managedobjectpool.h" +#include "ac/dynobj/cc_dynamicarray.h" // globalDynamicArray, constants +#include "debug/out.h" +#include "util/string_utils.h" // fputstring, etc +#include "script/cc_error.h" +#include "script/script_common.h" +#include "util/stream.h" + +using namespace AGS::Common; + +const auto OBJECT_CACHE_MAGIC_NUMBER = 0xa30b; +const auto SERIALIZE_BUFFER_SIZE = 10240; +const auto GARBAGE_COLLECTION_INTERVAL = 1024; +const auto RESERVED_SIZE = 2048; + +int ManagedObjectPool::Remove(ManagedObject &o, bool force) { + if (!o.isUsed()) { return 1; } // already removed + + bool canBeRemovedFromPool = o.callback->Dispose(o.addr, force) != 0; + if (!(canBeRemovedFromPool || force)) { return 0; } + + auto handle = o.handle; + available_ids.push(o.handle); + + handleByAddress.erase(o.addr); + o = ManagedObject(); + + ManagedObjectLog("Line %d Disposed managed object handle=%d", currentline, handle); + + return 1; +} + +int32_t ManagedObjectPool::AddRef(int32_t handle) { + if (handle < 0 || (size_t)handle >= objects.size()) { return 0; } + auto & o = objects[handle]; + if (!o.isUsed()) { return 0; } + + o.refCount += 1; + ManagedObjectLog("Line %d AddRef: handle=%d new refcount=%d", currentline, o.handle, o.refCount); + return o.refCount; +} + +int ManagedObjectPool::CheckDispose(int32_t handle) { + if (handle < 0 || (size_t)handle >= objects.size()) { return 1; } + auto & o = objects[handle]; + if (!o.isUsed()) { return 1; } + if (o.refCount >= 1) { return 0; } + return Remove(o); +} + +int32_t ManagedObjectPool::SubRef(int32_t handle) { + if (handle < 0 || (size_t)handle >= objects.size()) { return 0; } + auto & o = objects[handle]; + if (!o.isUsed()) { return 0; } + + o.refCount--; + auto newRefCount = o.refCount; + auto canBeDisposed = (o.addr != disableDisposeForObject); + if (canBeDisposed) { + CheckDispose(handle); + } + // object could be removed at this point, don't use any values. + ManagedObjectLog("Line %d SubRef: handle=%d new refcount=%d canBeDisposed=%d", currentline, handle, newRefCount, canBeDisposed); + return newRefCount; +} + +int32_t ManagedObjectPool::AddressToHandle(const char *addr) { + if (addr == nullptr) { return 0; } + auto it = handleByAddress.find(addr); + if (it == handleByAddress.end()) { return 0; } + return it->second; +} + +// this function is called often (whenever a pointer is used) +const char* ManagedObjectPool::HandleToAddress(int32_t handle) { + if (handle < 0 || (size_t)handle >= objects.size()) { return nullptr; } + auto & o = objects[handle]; + if (!o.isUsed()) { return nullptr; } + return o.addr; +} + +// this function is called often (whenever a pointer is used) +ScriptValueType ManagedObjectPool::HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager) { + if (handle < 0 || (size_t)handle >= objects.size()) { return kScValUndefined; } + auto & o = objects[handle]; + if (!o.isUsed()) { return kScValUndefined; } + + object = (void *)o.addr; // WARNING: This strips the const from the char* pointer. + manager = o.callback; + return o.obj_type; +} + +int ManagedObjectPool::RemoveObject(const char *address) { + if (address == nullptr) { return 0; } + auto it = handleByAddress.find(address); + if (it == handleByAddress.end()) { return 0; } + + auto & o = objects[it->second]; + return Remove(o, true); +} + +void ManagedObjectPool::RunGarbageCollectionIfAppropriate() +{ + if (objectCreationCounter <= GARBAGE_COLLECTION_INTERVAL) { return; } + RunGarbageCollection(); + objectCreationCounter = 0; +} + +void ManagedObjectPool::RunGarbageCollection() +{ + for (int i = 1; i < nextHandle; i++) { + auto & o = objects[i]; + if (!o.isUsed()) { continue; } + if (o.refCount < 1) { + Remove(o); + } + } + ManagedObjectLog("Ran garbage collection"); +} + +int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object) +{ + int32_t handle; + + if (!available_ids.empty()) { + handle = available_ids.front(); + available_ids.pop(); + } else { + handle = nextHandle++; + if ((size_t)handle >= objects.size()) { + objects.resize(handle + 1024, ManagedObject()); + } + } + + auto & o = objects[handle]; + if (o.isUsed()) { cc_error("used: %d", handle); return 0; } + + o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); + + handleByAddress.insert({address, o.handle}); + objectCreationCounter++; + ManagedObjectLog("Allocated managed object handle=%d, type=%s", handle, callback->GetType()); + return o.handle; +} + + +int ManagedObjectPool::AddUnserializedObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int handle) +{ + if (handle < 0) { cc_error("Attempt to assign invalid handle: %d", handle); return 0; } + if ((size_t)handle >= objects.size()) { + objects.resize(handle + 1024, ManagedObject()); + } + + auto & o = objects[handle]; + if (o.isUsed()) { cc_error("bad save. used: %d", o.handle); return 0; } + + o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); + + handleByAddress.insert({address, o.handle}); + ManagedObjectLog("Allocated unserialized managed object handle=%d, type=%s", o.handle, callback->GetType()); + return o.handle; +} + +void ManagedObjectPool::WriteToDisk(Stream *out) { + + // use this opportunity to clean up any non-referenced pointers + RunGarbageCollection(); + + std::vector serializeBuffer; + serializeBuffer.resize(SERIALIZE_BUFFER_SIZE); + + out->WriteInt32(OBJECT_CACHE_MAGIC_NUMBER); + out->WriteInt32(2); // version + + int size = 0; + for (int i = 1; i < nextHandle; i++) { + auto const & o = objects[i]; + if (o.isUsed()) { + size += 1; + } + } + out->WriteInt32(size); + + for (int i = 1; i < nextHandle; i++) { + auto const & o = objects[i]; + if (!o.isUsed()) { continue; } + + // handle + out->WriteInt32(o.handle); + // write the type of the object + StrUtil::WriteCStr((char*)o.callback->GetType(), out); + // now write the object data + int bytesWritten = o.callback->Serialize(o.addr, &serializeBuffer.front(), serializeBuffer.size()); + if ((bytesWritten < 0) && ((size_t)(-bytesWritten) > serializeBuffer.size())) + { + // buffer not big enough, re-allocate with requested size + serializeBuffer.resize(-bytesWritten); + bytesWritten = o.callback->Serialize(o.addr, &serializeBuffer.front(), serializeBuffer.size()); + } + assert(bytesWritten >= 0); + out->WriteInt32(bytesWritten); + out->Write(&serializeBuffer.front(), bytesWritten); + out->WriteInt32(o.refCount); + + ManagedObjectLog("Wrote handle = %d", o.handle); + } +} + +int ManagedObjectPool::ReadFromDisk(Stream *in, ICCObjectReader *reader) { + if (in->ReadInt32() != OBJECT_CACHE_MAGIC_NUMBER) { + cc_error("Data was not written by ccSeralize"); + return -1; + } + + char typeNameBuffer[200]; + std::vector serializeBuffer; + serializeBuffer.resize(SERIALIZE_BUFFER_SIZE); + + auto version = in->ReadInt32(); + + switch (version) { + case 1: + { + // IMPORTANT: numObjs is "nextHandleId", which is why we iterate from 1 to numObjs-1 + int numObjs = in->ReadInt32(); + for (int i = 1; i < numObjs; i++) { + StrUtil::ReadCStr(typeNameBuffer, in, sizeof(typeNameBuffer)); + if (typeNameBuffer[0] != 0) { + size_t numBytes = in->ReadInt32(); + if (numBytes > serializeBuffer.size()) { + serializeBuffer.resize(numBytes); + } + in->Read(&serializeBuffer.front(), numBytes); + if (strcmp(typeNameBuffer, CC_DYNAMIC_ARRAY_TYPE_NAME) == 0) { + globalDynamicArray.Unserialize(i, &serializeBuffer.front(), numBytes); + } else { + reader->Unserialize(i, typeNameBuffer, &serializeBuffer.front(), numBytes); + } + objects[i].refCount = in->ReadInt32(); + ManagedObjectLog("Read handle = %d", objects[i].handle); + } + } + } + break; + case 2: + { + // This is actually number of objects written. + int objectsSize = in->ReadInt32(); + for (int i = 0; i < objectsSize; i++) { + auto handle = in->ReadInt32(); + assert (handle >= 1); + StrUtil::ReadCStr(typeNameBuffer, in, sizeof(typeNameBuffer)); + assert (typeNameBuffer[0] != 0); + size_t numBytes = in->ReadInt32(); + if (numBytes > serializeBuffer.size()) { + serializeBuffer.resize(numBytes); + } + in->Read(&serializeBuffer.front(), numBytes); + if (strcmp(typeNameBuffer, CC_DYNAMIC_ARRAY_TYPE_NAME) == 0) { + globalDynamicArray.Unserialize(handle, &serializeBuffer.front(), numBytes); + } else { + reader->Unserialize(handle, typeNameBuffer, &serializeBuffer.front(), numBytes); + } + objects[handle].refCount = in->ReadInt32(); + ManagedObjectLog("Read handle = %d", objects[i].handle); + } + } + break; + default: + cc_error("Invalid data version: %d", version); + return -1; + } + + // re-adjust next handles. (in case saved in random order) + while (!available_ids.empty()) { available_ids.pop(); } + nextHandle = 1; + + for (const auto &o : objects) { + if (o.isUsed()) { + nextHandle = o.handle + 1; + } + } + for (int i = 1; i < nextHandle; i++) { + if (!objects[i].isUsed()) { + available_ids.push(i); + } + } + + return 0; +} + +// de-allocate all objects +void ManagedObjectPool::reset() { + for (int i = 1; i < nextHandle; i++) { + auto & o = objects[i]; + if (!o.isUsed()) { continue; } + Remove(o, true); + } + while (!available_ids.empty()) { available_ids.pop(); } + nextHandle = 1; +} + +ManagedObjectPool::ManagedObjectPool() : objectCreationCounter(0), nextHandle(1), available_ids(), objects(RESERVED_SIZE, ManagedObject()), handleByAddress() { + handleByAddress.reserve(RESERVED_SIZE); +} + +ManagedObjectPool pool; diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h new file mode 100644 index 000000000000..6107cadb81c0 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -0,0 +1,88 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __CC_MANAGEDOBJECTPOOL_H +#define __CC_MANAGEDOBJECTPOOL_H + +#include +#include +#include + +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject + +namespace AGS { namespace Common { class Stream; }} +using namespace AGS; // FIXME later + +struct ManagedObjectPool final { +private: + // TODO: find out if we can make handle size_t + struct ManagedObject { + ScriptValueType obj_type; + int32_t handle; + // TODO: this makes no sense having this as "const char*", + // void* will be proper (and in all related functions) + const char *addr; + ICCDynamicObject *callback; + int refCount; + + bool isUsed() const { return obj_type != kScValUndefined; } + + ManagedObject() + : obj_type(kScValUndefined), handle(0), addr(nullptr), callback(nullptr), refCount(0) {} + ManagedObject(ScriptValueType obj_type, int32_t handle, const char *addr, ICCDynamicObject * callback) + : obj_type(obj_type), handle(handle), addr(addr), callback(callback), refCount(0) {} + }; + + int objectCreationCounter; // used to do garbage collection every so often + + int32_t nextHandle {}; // TODO: manage nextHandle's going over INT32_MAX ! + std::queue available_ids; + std::vector objects; + std::unordered_map handleByAddress; + + void Init(int32_t theHandle, const char *theAddress, ICCDynamicObject *theCallback, ScriptValueType objType); + int Remove(ManagedObject &o, bool force = false); + + void RunGarbageCollection(); + +public: + + int32_t AddRef(int32_t handle); + int CheckDispose(int32_t handle); + int32_t SubRef(int32_t handle); + int32_t AddressToHandle(const char *addr); + const char* HandleToAddress(int32_t handle); + ScriptValueType HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager); + int RemoveObject(const char *address); + void RunGarbageCollectionIfAppropriate(); + int AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object); + int AddUnserializedObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int handle); + void WriteToDisk(Common::Stream *out); + int ReadFromDisk(Common::Stream *in, ICCObjectReader *reader); + void reset(); + ManagedObjectPool(); + + const char* disableDisposeForObject {nullptr}; +}; + +extern ManagedObjectPool pool; + +#ifdef DEBUG_MANAGED_OBJECTS +#define ManagedObjectLog(...) Debug::Printf(kDbgGroup_ManObj, kDbgMsg_Debug, __VA_ARGS__) +#else +#define ManagedObjectLog(...) +#endif + +#endif // __CC_MANAGEDOBJECTPOOL_H diff --git a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h new file mode 100644 index 000000000000..c256ead6e2fc --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h @@ -0,0 +1,27 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H +#define __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H + +struct ScriptAudioChannel +{ + int id; + int reserved; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp new file mode 100644 index 000000000000..e9db1cb99861 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -0,0 +1,64 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptcamera.h" +#include "ac/gamestate.h" +#include "util/bbop.h" + +using namespace AGS::Common; + +ScriptCamera::ScriptCamera(int id) : _id(id) {} + +const char *ScriptCamera::GetType() +{ + return "Camera2"; +} + +int ScriptCamera::Dispose(const char *address, bool force) +{ + // Note that ScriptCamera is a reference to actual Camera object, + // and this deletes the reference, while camera may remain in GameState. + delete this; + return 1; +} + +int ScriptCamera::Serialize(const char *address, char *buffer, int bufsize) +{ + StartSerialize(buffer); + SerializeInt(_id); + return EndSerialize(); +} + +void ScriptCamera::Unserialize(int index, const char *serializedData, int dataSize) +{ + StartUnserialize(serializedData, dataSize); + _id = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); +} + +ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dataSize) +{ + // The way it works now, we must not create a new script object, + // but acquire one from the GameState, which keeps the first reference. + // This is essential because GameState should be able to invalidate any + // script references when Camera gets removed. + const int id = BBOp::Int32FromLE(*((int*)serializedData)); + if (id >= 0) + { + auto scam = play.RegisterRoomCamera(id, handle); + if (scam) + return scam; + } + return new ScriptCamera(-1); // make invalid reference +} diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.h b/engines/ags/engine/ac/dynobj/scriptcamera.h new file mode 100644 index 000000000000..4aa25304e58f --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptcamera.h @@ -0,0 +1,44 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTCAMERA_H +#define __AC_SCRIPTCAMERA_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +// ScriptCamera keeps a reference to actual room Camera in script. +struct ScriptCamera final : AGSCCDynamicObject +{ +public: + ScriptCamera(int id); + + // Get camera index; negative means the camera was deleted + int GetID() const { return _id; } + void SetID(int id) { _id = id; } + // Reset camera index to indicate that this reference is no longer valid + void Invalidate() { _id = -1; } + + const char *GetType() override; + int Dispose(const char *address, bool force) override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + +private: + int _id = -1; // index of camera in the game state array +}; + +// Unserialize camera from the memory stream +ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dataSize); + +#endif // __AC_SCRIPTCAMERA_H diff --git a/engines/ags/engine/ac/dynobj/scriptcontainers.h b/engines/ags/engine/ac/dynobj/scriptcontainers.h new file mode 100644 index 000000000000..a0a374831a9b --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptcontainers.h @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AC_SCRIPTCONTAINERS_H +#define __AC_SCRIPTCONTAINERS_H + +class ScriptDictBase; +class ScriptSetBase; + +// Create and register new dictionary +ScriptDictBase *Dict_Create(bool sorted, bool case_sensitive); +// Unserialize dictionary from the memory stream +ScriptDictBase *Dict_Unserialize(int index, const char *serializedData, int dataSize); +// Create and register new set +ScriptSetBase *Set_Create(bool sorted, bool case_sensitive); +// Unserialize set from the memory stream +ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize); + +#endif // __AC_SCRIPTCONTAINERS_H diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp new file mode 100644 index 000000000000..eb57fbdf7651 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp @@ -0,0 +1,55 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptdatetime.h" + +int ScriptDateTime::Dispose(const char *address, bool force) { + // always dispose a DateTime + delete this; + return 1; +} + +const char *ScriptDateTime::GetType() { + return "DateTime"; +} + +int ScriptDateTime::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + SerializeInt(year); + SerializeInt(month); + SerializeInt(day); + SerializeInt(hour); + SerializeInt(minute); + SerializeInt(second); + SerializeInt(rawUnixTime); + return EndSerialize(); +} + +void ScriptDateTime::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + year = UnserializeInt(); + month = UnserializeInt(); + day = UnserializeInt(); + hour = UnserializeInt(); + minute = UnserializeInt(); + second = UnserializeInt(); + rawUnixTime = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); +} + +ScriptDateTime::ScriptDateTime() { + year = month = day = 0; + hour = minute = second = 0; + rawUnixTime = 0; +} diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.h b/engines/ags/engine/ac/dynobj/scriptdatetime.h new file mode 100644 index 000000000000..bc12bf27972d --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.h @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTDATETIME_H +#define __AGS_EE_DYNOBJ__SCRIPTDATETIME_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct ScriptDateTime final : AGSCCDynamicObject { + int year, month, day; + int hour, minute, second; + int rawUnixTime; + + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + + ScriptDateTime(); +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTDATETIME_H diff --git a/engines/ags/engine/ac/dynobj/scriptdialog.h b/engines/ags/engine/ac/dynobj/scriptdialog.h new file mode 100644 index 000000000000..9d8222e55035 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdialog.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTDIALOG_H +#define __AGS_EE_DYNOBJ__SCRIPTDIALOG_H + +struct ScriptDialog { + int id; + int reserved; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTDIALOG_H diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp new file mode 100644 index 000000000000..d05f63890527 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp @@ -0,0 +1,53 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptdialogoptionsrendering.h" + +// return the type name of the object +const char *ScriptDialogOptionsRendering::GetType() { + return "DialogOptionsRendering"; +} + +// serialize the object into BUFFER (which is BUFSIZE bytes) +// return number of bytes used +int ScriptDialogOptionsRendering::Serialize(const char *address, char *buffer, int bufsize) { + return 0; +} + +void ScriptDialogOptionsRendering::Unserialize(int index, const char *serializedData, int dataSize) { + ccRegisterUnserializedObject(index, this, this); +} + +void ScriptDialogOptionsRendering::Reset() +{ + x = 0; + y = 0; + width = 0; + height = 0; + hasAlphaChannel = false; + parserTextboxX = 0; + parserTextboxY = 0; + parserTextboxWidth = 0; + dialogID = 0; + surfaceToRenderTo = nullptr; + surfaceAccessed = false; + activeOptionID = -1; + chosenOptionID = -1; + needRepaint = false; +} + +ScriptDialogOptionsRendering::ScriptDialogOptionsRendering() +{ + Reset(); +} diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h new file mode 100644 index 000000000000..a50d9d02e294 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h @@ -0,0 +1,47 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTDIALOGOPTIONSRENDERING_H +#define __AC_SCRIPTDIALOGOPTIONSRENDERING_H + +#include "ac/dynobj/scriptdrawingsurface.h" + +struct ScriptDialogOptionsRendering final : AGSCCDynamicObject { + int x, y, width, height; + bool hasAlphaChannel; + int parserTextboxX, parserTextboxY; + int parserTextboxWidth; + int dialogID; + int activeOptionID; + int chosenOptionID; + ScriptDrawingSurface *surfaceToRenderTo; + bool surfaceAccessed; + bool needRepaint; + + // return the type name of the object + const char *GetType() override; + + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + + void Unserialize(int index, const char *serializedData, int dataSize) override; + + void Reset(); + + ScriptDialogOptionsRendering(); +}; + + +#endif // __AC_SCRIPTDIALOGOPTIONSRENDERING_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/scriptdict.cpp b/engines/ags/engine/ac/dynobj/scriptdict.cpp new file mode 100644 index 000000000000..5676ae260391 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdict.cpp @@ -0,0 +1,50 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "ac/dynobj/scriptdict.h" + +int ScriptDictBase::Dispose(const char *address, bool force) +{ + Clear(); + delete this; + return 1; +} + +const char *ScriptDictBase::GetType() +{ + return "StringDictionary"; +} + +int ScriptDictBase::Serialize(const char *address, char *buffer, int bufsize) +{ + size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; + if (bufsize < 0 || total_sz >(size_t)bufsize) + { + // buffer not big enough, ask for a bigger one + return -((int)total_sz); + } + StartSerialize(buffer); + SerializeInt(IsSorted()); + SerializeInt(IsCaseSensitive()); + SerializeContainer(); + return EndSerialize(); +} + +void ScriptDictBase::Unserialize(int index, const char *serializedData, int dataSize) +{ + // NOTE: we expect sorted/case flags are read by external reader; + // this is awkward, but I did not find better design solution atm + StartUnserialize(serializedData, dataSize); + UnserializeContainer(serializedData); + ccRegisterUnserializedObject(index, this, this); +} diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h new file mode 100644 index 000000000000..e89d22c10e7d --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -0,0 +1,186 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Managed script object wrapping std::map and +// unordered_map. +// +// TODO: support wrapping non-owned Dictionary, passed by the reference, - +// that would let expose internal engine's dicts using same interface. +// TODO: maybe optimize key lookup operations further by not creating a String +// object from const char*. It seems, C++14 standard allows to use convertible +// types as keys; need to research what perfomance impact that would make. +// +//============================================================================= +#ifndef __AC_SCRIPTDICT_H +#define __AC_SCRIPTDICT_H + +#include +#include +#include +#include "ac/dynobj/cc_agsdynamicobject.h" +#include "util/string.h" +#include "util/string_types.h" + +using namespace AGS::Common; + +class ScriptDictBase : public AGSCCDynamicObject +{ +public: + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + + virtual bool IsCaseSensitive() const = 0; + virtual bool IsSorted() const = 0; + + virtual void Clear() = 0; + virtual bool Contains(const char *key) = 0; + virtual const char *Get(const char *key) = 0; + virtual bool Remove(const char *key) = 0; + virtual bool Set(const char *key, const char *value) = 0; + virtual int GetItemCount() = 0; + virtual void GetKeys(std::vector &buf) const = 0; + virtual void GetValues(std::vector &buf) const = 0; + +private: + virtual size_t CalcSerializeSize() = 0; + virtual void SerializeContainer() = 0; + virtual void UnserializeContainer(const char *serializedData) = 0; +}; + +template +class ScriptDictImpl final : public ScriptDictBase +{ +public: + typedef typename TDict::const_iterator ConstIterator; + + ScriptDictImpl() = default; + + bool IsCaseSensitive() const override { return is_casesensitive; } + bool IsSorted() const override { return is_sorted; } + + void Clear() override + { + for (auto it = _dic.begin(); it != _dic.end(); ++it) + DeleteItem(it); + _dic.clear(); + } + bool Contains(const char *key) override { return _dic.count(String::Wrapper(key)) != 0; } + const char *Get(const char *key) override + { + auto it = _dic.find(String::Wrapper(key)); + if (it == _dic.end()) return nullptr; + return it->second.GetNullableCStr(); + } + bool Remove(const char *key) override + { + auto it = _dic.find(String::Wrapper(key)); + if (it == _dic.end()) return false; + DeleteItem(it); + _dic.erase(it); + return true; + } + bool Set(const char *key, const char *value) override + { + if (!key) return false; + size_t key_len = strlen(key); + size_t value_len = value ? strlen(value) : 0; + return TryAddItem(key, key_len, value, value_len); + } + int GetItemCount() override { return _dic.size(); } + void GetKeys(std::vector &buf) const override + { + for (auto it = _dic.begin(); it != _dic.end(); ++it) + buf.push_back(it->first.GetCStr()); // keys cannot be null + } + void GetValues(std::vector &buf) const override + { + for (auto it = _dic.begin(); it != _dic.end(); ++it) + buf.push_back(it->second.GetNullableCStr()); // values may be null + } + +private: + bool TryAddItem(const char *key, size_t key_len, const char *value, size_t value_len) + { + String elem_key(key, key_len); + String elem_value; + if (value) + elem_value.SetString(value, value_len); + _dic[elem_key] = elem_value; + return true; + } + void DeleteItem(ConstIterator it) { /* do nothing */ } + + size_t CalcSerializeSize() override + { + size_t total_sz = sizeof(int32_t); + for (auto it = _dic.begin(); it != _dic.end(); ++it) + { + total_sz += sizeof(int32_t) + it->first.GetLength(); + total_sz += sizeof(int32_t) + it->second.GetLength(); + } + return total_sz; + } + + void SerializeContainer() override + { + SerializeInt((int)_dic.size()); + for (auto it = _dic.begin(); it != _dic.end(); ++it) + { + SerializeInt((int)it->first.GetLength()); + memcpy(&serbuffer[bytesSoFar], it->first.GetCStr(), it->first.GetLength()); + bytesSoFar += it->first.GetLength(); + if (it->second.GetNullableCStr()) // values may be null + { + SerializeInt((int)it->second.GetLength()); + memcpy(&serbuffer[bytesSoFar], it->second.GetCStr(), it->second.GetLength()); + bytesSoFar += it->second.GetLength(); + } + else + { + SerializeInt(-1); + } + } + } + + void UnserializeContainer(const char *serializedData) override + { + size_t item_count = (size_t)UnserializeInt(); + for (size_t i = 0; i < item_count; ++i) + { + size_t key_len = UnserializeInt(); + int key_pos = bytesSoFar; bytesSoFar += key_len; + size_t value_len = UnserializeInt(); + if (value_len == (size_t)-1) + { + TryAddItem(&serializedData[key_pos], key_len, nullptr, 0); + } + else + { + int value_pos = bytesSoFar; bytesSoFar += value_len; + TryAddItem(&serializedData[key_pos], key_len, &serializedData[value_pos], value_len); + } + } + } + + TDict _dic; +}; + +typedef ScriptDictImpl< std::map, true, true > ScriptDict; +typedef ScriptDictImpl< std::map, true, false > ScriptDictCI; +typedef ScriptDictImpl< std::unordered_map, false, true > ScriptHashDict; +typedef ScriptDictImpl< std::unordered_map, false, false > ScriptHashDictCI; + +#endif // __AC_SCRIPTDICT_H diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp new file mode 100644 index 000000000000..1f68eb1ec571 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -0,0 +1,129 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptdrawingsurface.h" +#include "ac/spritecache.h" +#include "ac/runtime_defines.h" +#include "ac/common.h" +#include "ac/drawingsurface.h" +#include "ac/gamestate.h" +#include "ac/gamesetupstruct.h" +#include "game/roomstruct.h" +#include "gfx/bitmap.h" + +using namespace AGS::Common; + +extern RoomStruct thisroom; +extern SpriteCache spriteset; +extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; +extern GameState play; +extern GameSetupStruct game; + +Bitmap* ScriptDrawingSurface::GetBitmapSurface() +{ + // TODO: consider creating weak_ptr here, and store one in the DrawingSurface! + if (roomBackgroundNumber >= 0) + return thisroom.BgFrames[roomBackgroundNumber].Graphic.get(); + else if (dynamicSpriteNumber >= 0) + return spriteset[dynamicSpriteNumber]; + else if (dynamicSurfaceNumber >= 0) + return dynamicallyCreatedSurfaces[dynamicSurfaceNumber]; + else if (linkedBitmapOnly != nullptr) + return linkedBitmapOnly; + else if (roomMaskType > kRoomAreaNone) + return thisroom.GetMask(roomMaskType); + quit("!DrawingSurface: attempted to use surface after Release was called"); + return nullptr; +} + +Bitmap *ScriptDrawingSurface::StartDrawing() +{ + //abufBackup = abuf; + return this->GetBitmapSurface(); +} + +void ScriptDrawingSurface::FinishedDrawingReadOnly() +{ + //abuf = abufBackup; +} + +void ScriptDrawingSurface::FinishedDrawing() +{ + FinishedDrawingReadOnly(); + modified = 1; +} + +int ScriptDrawingSurface::Dispose(const char *address, bool force) { + + // dispose the drawing surface + DrawingSurface_Release(this); + delete this; + return 1; +} + +const char *ScriptDrawingSurface::GetType() { + return "DrawingSurface"; +} + +int ScriptDrawingSurface::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + SerializeInt(roomBackgroundNumber & 0xFFFF | (roomMaskType << 16)); + SerializeInt(dynamicSpriteNumber); + SerializeInt(dynamicSurfaceNumber); + SerializeInt(currentColour); + SerializeInt(currentColourScript); + SerializeInt(highResCoordinates); + SerializeInt(modified); + SerializeInt(hasAlphaChannel); + SerializeInt(isLinkedBitmapOnly ? 1 : 0); + return EndSerialize(); +} + +void ScriptDrawingSurface::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int room_ds = UnserializeInt(); + roomBackgroundNumber = static_cast(room_ds & 0xFFFF); + roomMaskType = (RoomAreaMask)(room_ds >> 16); + dynamicSpriteNumber = UnserializeInt(); + dynamicSurfaceNumber = UnserializeInt(); + currentColour = UnserializeInt(); + currentColourScript = UnserializeInt(); + highResCoordinates = UnserializeInt(); + modified = UnserializeInt(); + hasAlphaChannel = UnserializeInt(); + isLinkedBitmapOnly = (UnserializeInt() != 0); + ccRegisterUnserializedObject(index, this, this); +} + +ScriptDrawingSurface::ScriptDrawingSurface() +{ + roomBackgroundNumber = -1; + roomMaskType = kRoomAreaNone; + dynamicSpriteNumber = -1; + dynamicSurfaceNumber = -1; + isLinkedBitmapOnly = false; + linkedBitmapOnly = nullptr; + currentColour = play.raw_color; + currentColourScript = 0; + modified = 0; + hasAlphaChannel = 0; + highResCoordinates = 0; + // NOTE: Normally in contemporary games coordinates ratio will always be 1:1. + // But we still support legacy drawing, so have to set this up even for modern games, + // otherwise we'd have to complicate conversion conditions further. + if (game.IsLegacyHiRes() && game.IsDataInNativeCoordinates()) + { + highResCoordinates = 1; + } +} diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h new file mode 100644 index 000000000000..4751be333a98 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h @@ -0,0 +1,55 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTDRAWINGSURFACE_H +#define __AC_SCRIPTDRAWINGSURFACE_H + +#include "ac/dynobj/cc_agsdynamicobject.h" +#include "game/roomstruct.h" + +namespace AGS { namespace Common { class Bitmap; }} + +struct ScriptDrawingSurface final : AGSCCDynamicObject { + // These numbers and types are used to determine the source of this drawing surface; + // only one of them can be valid for this surface. + int roomBackgroundNumber; + RoomAreaMask roomMaskType; + int dynamicSpriteNumber; + int dynamicSurfaceNumber; + bool isLinkedBitmapOnly; + Common::Bitmap *linkedBitmapOnly; + int currentColour; + int currentColourScript; + int highResCoordinates; + int modified; + int hasAlphaChannel; + //Common::Bitmap* abufBackup; + + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + Common::Bitmap* GetBitmapSurface(); + Common::Bitmap *StartDrawing(); + void PointToGameResolution(int *xcoord, int *ycoord); + void SizeToGameResolution(int *width, int *height); + void SizeToGameResolution(int *adjustValue); + void SizeToDataResolution(int *adjustValue); + void FinishedDrawing(); + void FinishedDrawingReadOnly(); + + ScriptDrawingSurface(); +}; + +#endif // __AC_SCRIPTDRAWINGSURFACE_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp new file mode 100644 index 000000000000..6023eb607f9c --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp @@ -0,0 +1,50 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptdynamicsprite.h" +#include "ac/dynamicsprite.h" + +int ScriptDynamicSprite::Dispose(const char *address, bool force) { + // always dispose + if ((slot) && (!force)) + free_dynamic_sprite(slot); + + delete this; + return 1; +} + +const char *ScriptDynamicSprite::GetType() { + return "DynamicSprite"; +} + +int ScriptDynamicSprite::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + SerializeInt(slot); + return EndSerialize(); +} + +void ScriptDynamicSprite::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + slot = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); +} + +ScriptDynamicSprite::ScriptDynamicSprite(int theSlot) { + slot = theSlot; + ccRegisterManagedObject(this, this); +} + +ScriptDynamicSprite::ScriptDynamicSprite() { + slot = 0; +} diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h new file mode 100644 index 000000000000..11a53ed68da2 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTDYNAMICSPRITE_H +#define __AC_SCRIPTDYNAMICSPRITE_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct ScriptDynamicSprite final : AGSCCDynamicObject { + int slot; + + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + + ScriptDynamicSprite(int slot); + ScriptDynamicSprite(); +}; + +#endif // __AC_SCRIPTDYNAMICSPRITE_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/scriptfile.cpp b/engines/ags/engine/ac/dynobj/scriptfile.cpp new file mode 100644 index 000000000000..d52000c7d516 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptfile.cpp @@ -0,0 +1,105 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptfile.h" +#include "ac/global_file.h" + +// CHECKME: actually NULLs here will be equal to kFile_Open & kFile_Read +const Common::FileOpenMode sc_File::fopenModes[] = + {Common::kFile_Open/*CHECKME, was undefined*/, Common::kFile_Open, Common::kFile_CreateAlways, Common::kFile_Create}; +const Common::FileWorkMode sc_File::fworkModes[] = + {Common::kFile_Read/*CHECKME, was undefined*/, Common::kFile_Read, Common::kFile_Write, Common::kFile_Write}; + +int sc_File::Dispose(const char *address, bool force) { + Close(); + delete this; + return 1; +} + +const char *sc_File::GetType() { + return "File"; +} + +int sc_File::Serialize(const char *address, char *buffer, int bufsize) { + // we cannot serialize an open file, so it will get closed + return 0; +} + +int sc_File::OpenFile(const char *filename, int mode) { + handle = FileOpen(filename, fopenModes[mode], fworkModes[mode]); + if (handle <= 0) + return 0; + return 1; +} + +void sc_File::Close() { + if (handle > 0) { + FileClose(handle); + handle = 0; + } +} + +sc_File::sc_File() { + handle = 0; +} + + +const char* sc_File::GetFieldPtr(const char *address, intptr_t offset) +{ + return address; +} + +void sc_File::Read(const char *address, intptr_t offset, void *dest, int size) +{ +} + +uint8_t sc_File::ReadInt8(const char *address, intptr_t offset) +{ + return 0; +} + +int16_t sc_File::ReadInt16(const char *address, intptr_t offset) +{ + return 0; +} + +int32_t sc_File::ReadInt32(const char *address, intptr_t offset) +{ + return 0; +} + +float sc_File::ReadFloat(const char *address, intptr_t offset) +{ + return 0.0; +} + +void sc_File::Write(const char *address, intptr_t offset, void *src, int size) +{ +} + +void sc_File::WriteInt8(const char *address, intptr_t offset, uint8_t val) +{ +} + +void sc_File::WriteInt16(const char *address, intptr_t offset, int16_t val) +{ +} + +void sc_File::WriteInt32(const char *address, intptr_t offset, int32_t val) +{ +} + +void sc_File::WriteFloat(const char *address, intptr_t offset, float val) +{ +} diff --git a/engines/ags/engine/ac/dynobj/scriptfile.h b/engines/ags/engine/ac/dynobj/scriptfile.h new file mode 100644 index 000000000000..f039e9768e90 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptfile.h @@ -0,0 +1,61 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTFILE_H +#define __AGS_EE_DYNOBJ__SCRIPTFILE_H + +#include "ac/dynobj/cc_dynamicobject.h" +#include "util/file.h" + +using namespace AGS; // FIXME later + +#define scFileRead 1 +#define scFileWrite 2 +#define scFileAppend 3 + +struct sc_File final : ICCDynamicObject { + int32_t handle; + + static const Common::FileOpenMode fopenModes[]; + static const Common::FileWorkMode fworkModes[]; + + int Dispose(const char *address, bool force) override; + + const char *GetType() override; + + int Serialize(const char *address, char *buffer, int bufsize) override; + + int OpenFile(const char *filename, int mode); + void Close(); + + sc_File(); + + // Legacy support for reading and writing object values by their relative offset + const char* GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTFILE_H diff --git a/engines/ags/engine/ac/dynobj/scriptgui.h b/engines/ags/engine/ac/dynobj/scriptgui.h new file mode 100644 index 000000000000..c6651a22c50b --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptgui.h @@ -0,0 +1,27 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTGUI_H +#define __AGS_EE_DYNOBJ__SCRIPTGUI_H + +// 64 bit: This struct must be 8 byte long +struct ScriptGUI { + int id; + int __padding; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTGUI_H diff --git a/engines/ags/engine/ac/dynobj/scripthotspot.h b/engines/ags/engine/ac/dynobj/scripthotspot.h new file mode 100644 index 000000000000..1af83a772ac5 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scripthotspot.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H +#define __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H + +struct ScriptHotspot { + int id; + int reserved; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H diff --git a/engines/ags/engine/ac/dynobj/scriptinvitem.h b/engines/ags/engine/ac/dynobj/scriptinvitem.h new file mode 100644 index 000000000000..a614a5f5bfd6 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptinvitem.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTINVITEM_H +#define __AGS_EE_DYNOBJ__SCRIPTINVITEM_H + +struct ScriptInvItem { + int id; + int reserved; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTINVITEM_H diff --git a/engines/ags/engine/ac/dynobj/scriptmouse.h b/engines/ags/engine/ac/dynobj/scriptmouse.h new file mode 100644 index 000000000000..d0ee4316eaf2 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptmouse.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTMOUSE_H +#define __AGS_EE_DYNOBJ__SCRIPTMOUSE_H + +// The text script's "mouse" struct +struct ScriptMouse { + int x,y; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTMOUSE_H diff --git a/engines/ags/engine/ac/dynobj/scriptobject.h b/engines/ags/engine/ac/dynobj/scriptobject.h new file mode 100644 index 000000000000..57a9ee98686c --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptobject.h @@ -0,0 +1,30 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTOBJECT_H +#define __AGS_EE_DYNOBJ__SCRIPTOBJECT_H + +#include "ac/roomobject.h" + +// 64 bit: Struct size must be 8 byte for scripts to work +struct ScriptObject { + int id; + //RoomObject *obj; + int __padding; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTOBJECT_H diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp new file mode 100644 index 000000000000..d640ab8eb6d3 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp @@ -0,0 +1,83 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptoverlay.h" +#include "ac/common.h" +#include "ac/overlay.h" +#include "ac/runtime_defines.h" +#include "ac/screenoverlay.h" + +int ScriptOverlay::Dispose(const char *address, bool force) +{ + // since the managed object is being deleted, remove the + // reference so it doesn't try and dispose something else + // with that handle later + int overlayIndex = find_overlay_of_type(overlayId); + if (overlayIndex >= 0) + { + screenover[overlayIndex].associatedOverlayHandle = 0; + } + + // if this is being removed voluntarily (ie. pointer out of + // scope) then remove the associateed overlay + // Otherwise, it's a Restre Game or something so don't + if ((!force) && (!isBackgroundSpeech) && (Overlay_GetValid(this))) + { + Remove(); + } + + delete this; + return 1; +} + +const char *ScriptOverlay::GetType() { + return "Overlay"; +} + +int ScriptOverlay::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + SerializeInt(overlayId); + SerializeInt(borderWidth); + SerializeInt(borderHeight); + SerializeInt(isBackgroundSpeech); + return EndSerialize(); +} + +void ScriptOverlay::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + overlayId = UnserializeInt(); + borderWidth = UnserializeInt(); + borderHeight = UnserializeInt(); + isBackgroundSpeech = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); +} + +void ScriptOverlay::Remove() +{ + int overlayIndex = find_overlay_of_type(overlayId); + if (overlayIndex < 0) + { + quit("ScriptOverlay::Remove: overlay is not there!"); + } + remove_screen_overlay_index(overlayIndex); + overlayId = -1; +} + + +ScriptOverlay::ScriptOverlay() { + overlayId = -1; + borderWidth = 0; + borderHeight = 0; + isBackgroundSpeech = 0; +} diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.h b/engines/ags/engine/ac/dynobj/scriptoverlay.h new file mode 100644 index 000000000000..0b027b62bb7d --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTOVERLAY_H +#define __AC_SCRIPTOVERLAY_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct ScriptOverlay final : AGSCCDynamicObject { + int overlayId; + int borderWidth; + int borderHeight; + int isBackgroundSpeech; + + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + void Remove(); + ScriptOverlay(); +}; + +#endif // __AC_SCRIPTOVERLAY_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/scriptregion.h b/engines/ags/engine/ac/dynobj/scriptregion.h new file mode 100644 index 000000000000..9e2aff4fb392 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptregion.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTREGION_H +#define __AGS_EE_DYNOBJ__SCRIPTREGION_H + +struct ScriptRegion { + int id; + int reserved; +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTREGION_H diff --git a/engines/ags/engine/ac/dynobj/scriptset.cpp b/engines/ags/engine/ac/dynobj/scriptset.cpp new file mode 100644 index 000000000000..472671add1aa --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptset.cpp @@ -0,0 +1,50 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "ac/dynobj/scriptset.h" + +int ScriptSetBase::Dispose(const char *address, bool force) +{ + Clear(); + delete this; + return 1; +} + +const char *ScriptSetBase::GetType() +{ + return "StringSet"; +} + +int ScriptSetBase::Serialize(const char *address, char *buffer, int bufsize) +{ + size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; + if (bufsize < 0 || total_sz > (size_t)bufsize) + { + // buffer not big enough, ask for a bigger one + return -((int)total_sz); + } + StartSerialize(buffer); + SerializeInt(IsSorted()); + SerializeInt(IsCaseSensitive()); + SerializeContainer(); + return EndSerialize(); +} + +void ScriptSetBase::Unserialize(int index, const char *serializedData, int dataSize) +{ + // NOTE: we expect sorted/case flags are read by external reader; + // this is awkward, but I did not find better design solution atm + StartUnserialize(serializedData, dataSize); + UnserializeContainer(serializedData); + ccRegisterUnserializedObject(index, this, this); +} diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h new file mode 100644 index 000000000000..12dc89c914fc --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -0,0 +1,144 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Managed script object wrapping std::set and unordered_set. +// +// TODO: support wrapping non-owned Set, passed by the reference, - +// that would let expose internal engine's sets using same interface. +// TODO: maybe optimize key lookup operations further by not creating a String +// object from const char*. It seems, C++14 standard allows to use convertible +// types as keys; need to research what perfomance impact that would make. +// +//============================================================================= +#ifndef __AC_SCRIPTSET_H +#define __AC_SCRIPTSET_H + +#include +#include +#include +#include "ac/dynobj/cc_agsdynamicobject.h" +#include "util/string.h" +#include "util/string_types.h" + +using namespace AGS::Common; + +class ScriptSetBase : public AGSCCDynamicObject +{ +public: + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + + virtual bool IsCaseSensitive() const = 0; + virtual bool IsSorted() const = 0; + + virtual bool Add(const char *item) = 0; + virtual void Clear() = 0; + virtual bool Contains(const char *item) const = 0; + virtual bool Remove(const char *item) = 0; + virtual int GetItemCount() const = 0; + virtual void GetItems(std::vector &buf) const = 0; + +private: + virtual size_t CalcSerializeSize() = 0; + virtual void SerializeContainer() = 0; + virtual void UnserializeContainer(const char *serializedData) = 0; +}; + +template +class ScriptSetImpl final : public ScriptSetBase +{ +public: + typedef typename TSet::const_iterator ConstIterator; + + ScriptSetImpl() = default; + + bool IsCaseSensitive() const override { return is_casesensitive; } + bool IsSorted() const override { return is_sorted; } + + bool Add(const char *item) override + { + if (!item) return false; + size_t len = strlen(item); + return TryAddItem(item, len); + } + void Clear() override + { + for (auto it = _set.begin(); it != _set.end(); ++it) + DeleteItem(it); + _set.clear(); + } + bool Contains(const char *item) const override { return _set.count(String::Wrapper(item)) != 0; } + bool Remove(const char *item) override + { + auto it = _set.find(String::Wrapper(item)); + if (it == _set.end()) return false; + DeleteItem(it); + _set.erase(it); + return true; + } + int GetItemCount() const override { return _set.size(); } + void GetItems(std::vector &buf) const override + { + for (auto it = _set.begin(); it != _set.end(); ++it) + buf.push_back(it->GetCStr()); + } + +private: + bool TryAddItem(const char *item, size_t len) + { + return _set.insert(String(item, len)).second; + } + void DeleteItem(ConstIterator it) { /* do nothing */ } + + size_t CalcSerializeSize() override + { + size_t total_sz = sizeof(int32_t); + for (auto it = _set.begin(); it != _set.end(); ++it) + total_sz += sizeof(int32_t) + it->GetLength(); + return total_sz; + } + + void SerializeContainer() override + { + SerializeInt((int)_set.size()); + for (auto it = _set.begin(); it != _set.end(); ++it) + { + SerializeInt((int)it->GetLength()); + memcpy(&serbuffer[bytesSoFar], it->GetCStr(), it->GetLength()); + bytesSoFar += it->GetLength(); + } + } + + void UnserializeContainer(const char *serializedData) override + { + size_t item_count = (size_t)UnserializeInt(); + for (size_t i = 0; i < item_count; ++i) + { + size_t len = UnserializeInt(); + TryAddItem(&serializedData[bytesSoFar], len); + bytesSoFar += len; + } + } + + TSet _set; +}; + +typedef ScriptSetImpl< std::set, true, true > ScriptSet; +typedef ScriptSetImpl< std::set, true, false > ScriptSetCI; +typedef ScriptSetImpl< std::unordered_set, false, true > ScriptHashSet; +typedef ScriptSetImpl< std::unordered_set, false, false > ScriptHashSetCI; + +#endif // __AC_SCRIPTSET_H diff --git a/engines/ags/engine/ac/dynobj/scriptstring.cpp b/engines/ags/engine/ac/dynobj/scriptstring.cpp new file mode 100644 index 000000000000..d130d63e5b4f --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptstring.cpp @@ -0,0 +1,66 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptstring.h" +#include "ac/string.h" +#include +#include + +DynObjectRef ScriptString::CreateString(const char *fromText) { + return CreateNewScriptStringObj(fromText); +} + +int ScriptString::Dispose(const char *address, bool force) { + // always dispose + if (text) { + free(text); + text = nullptr; + } + delete this; + return 1; +} + +const char *ScriptString::GetType() { + return "String"; +} + +int ScriptString::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + + auto toSerialize = text ? text : ""; + + auto len = strlen(toSerialize); + SerializeInt(len); + strcpy(&serbuffer[bytesSoFar], toSerialize); + bytesSoFar += len + 1; + + return EndSerialize(); +} + +void ScriptString::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + int textsize = UnserializeInt(); + text = (char*)malloc(textsize + 1); + strcpy(text, &serializedData[bytesSoFar]); + ccRegisterUnserializedObject(index, text, this); +} + +ScriptString::ScriptString() { + text = nullptr; +} + +ScriptString::ScriptString(const char *fromText) { + text = (char*)malloc(strlen(fromText) + 1); + strcpy(text, fromText); +} diff --git a/engines/ags/engine/ac/dynobj/scriptstring.h b/engines/ags/engine/ac/dynobj/scriptstring.h new file mode 100644 index 000000000000..916d48998d59 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptstring.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTSTRING_H +#define __AC_SCRIPTSTRING_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct ScriptString final : AGSCCDynamicObject, ICCStringClass { + char *text; + + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + + DynObjectRef CreateString(const char *fromText) override; + + ScriptString(); + ScriptString(const char *fromText); +}; + +#endif // __AC_SCRIPTSTRING_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/scriptsystem.h b/engines/ags/engine/ac/dynobj/scriptsystem.h new file mode 100644 index 000000000000..e7c29b3d7a3b --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptsystem.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H +#define __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H + +// The text script's "system" struct +struct ScriptSystem { + int width,height; + int coldepth; + int os; + int windowed; + int vsync; + int viewport_width, viewport_height; + char aci_version[10]; // FIXME this when possible, version format is different now + int reserved[5]; // so that future scripts don't overwrite data +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp new file mode 100644 index 000000000000..4b70941a13d8 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp @@ -0,0 +1,144 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "scriptuserobject.h" + +// return the type name of the object +const char *ScriptUserObject::GetType() +{ + return "UserObject"; +} + +ScriptUserObject::ScriptUserObject() + : _size(0) + , _data(nullptr) +{ +} + +ScriptUserObject::~ScriptUserObject() +{ + delete [] _data; +} + +/* static */ ScriptUserObject *ScriptUserObject::CreateManaged(size_t size) +{ + ScriptUserObject *suo = new ScriptUserObject(); + suo->Create(nullptr, size); + ccRegisterManagedObject(suo, suo); + return suo; +} + +void ScriptUserObject::Create(const char *data, size_t size) +{ + delete [] _data; + _data = nullptr; + + _size = size; + if (_size > 0) + { + _data = new char[size]; + if (data) + memcpy(_data, data, _size); + else + memset(_data, 0, _size); + } +} + +int ScriptUserObject::Dispose(const char *address, bool force) +{ + delete this; + return 1; +} + +int ScriptUserObject::Serialize(const char *address, char *buffer, int bufsize) +{ + if (_size > bufsize) + // buffer not big enough, ask for a bigger one + return -_size; + + memcpy(buffer, _data, _size); + return _size; +} + +void ScriptUserObject::Unserialize(int index, const char *serializedData, int dataSize) +{ + Create(serializedData, dataSize); + ccRegisterUnserializedObject(index, this, this); +} + +const char* ScriptUserObject::GetFieldPtr(const char *address, intptr_t offset) +{ + return _data + offset; +} + +void ScriptUserObject::Read(const char *address, intptr_t offset, void *dest, int size) +{ + memcpy(dest, _data + offset, size); +} + +uint8_t ScriptUserObject::ReadInt8(const char *address, intptr_t offset) +{ + return *(uint8_t*)(_data + offset); +} + +int16_t ScriptUserObject::ReadInt16(const char *address, intptr_t offset) +{ + return *(int16_t*)(_data + offset); +} + +int32_t ScriptUserObject::ReadInt32(const char *address, intptr_t offset) +{ + return *(int32_t*)(_data + offset); +} + +float ScriptUserObject::ReadFloat(const char *address, intptr_t offset) +{ + return *(float*)(_data + offset); +} + +void ScriptUserObject::Write(const char *address, intptr_t offset, void *src, int size) +{ + memcpy((void*)(_data + offset), src, size); +} + +void ScriptUserObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) +{ + *(uint8_t*)(_data + offset) = val; +} + +void ScriptUserObject::WriteInt16(const char *address, intptr_t offset, int16_t val) +{ + *(int16_t*)(_data + offset) = val; +} + +void ScriptUserObject::WriteInt32(const char *address, intptr_t offset, int32_t val) +{ + *(int32_t*)(_data + offset) = val; +} + +void ScriptUserObject::WriteFloat(const char *address, intptr_t offset, float val) +{ + *(float*)(_data + offset) = val; +} + + +// Allocates managed struct containing two ints: X and Y +ScriptUserObject *ScriptStructHelpers::CreatePoint(int x, int y) +{ + ScriptUserObject *suo = ScriptUserObject::CreateManaged(sizeof(int32_t) * 2); + suo->WriteInt32((const char*)suo, 0, x); + suo->WriteInt32((const char*)suo, sizeof(int32_t), y); + return suo; +} diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h new file mode 100644 index 000000000000..931bdaa23c5b --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -0,0 +1,75 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Managed object, which size and contents are defined by user script +// +//============================================================================= +#ifndef __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H +#define __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct ScriptUserObject final : ICCDynamicObject +{ +public: + ScriptUserObject(); + +protected: + virtual ~ScriptUserObject(); + +public: + static ScriptUserObject *CreateManaged(size_t size); + void Create(const char *data, size_t size); + + // return the type name of the object + const char *GetType() override; + int Dispose(const char *address, bool force) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + virtual void Unserialize(int index, const char *serializedData, int dataSize); + + // Support for reading and writing object values by their relative offset + const char* GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; + +private: + // NOTE: we use signed int for Size at the moment, because the managed + // object interface's Serialize() function requires the object to return + // negative value of size in case the provided buffer was not large + // enough. Since this interface is also a part of Plugin API, we would + // need more significant change to program before we could use different + // approach. + int32_t _size; + char *_data; +}; + + +// Helper functions for setting up custom managed structs based on ScriptUserObject. +namespace ScriptStructHelpers +{ + // Creates a managed Point object, represented as a pair of X and Y coordinates. + ScriptUserObject *CreatePoint(int x, int y); +}; + +#endif // __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp new file mode 100644 index 000000000000..803269a46f48 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp @@ -0,0 +1,53 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptviewframe.h" + +int ScriptViewFrame::Dispose(const char *address, bool force) { + // always dispose a ViewFrame + delete this; + return 1; +} + +const char *ScriptViewFrame::GetType() { + return "ViewFrame"; +} + +int ScriptViewFrame::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + SerializeInt(view); + SerializeInt(loop); + SerializeInt(frame); + return EndSerialize(); +} + +void ScriptViewFrame::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + view = UnserializeInt(); + loop = UnserializeInt(); + frame = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); +} + +ScriptViewFrame::ScriptViewFrame(int p_view, int p_loop, int p_frame) { + view = p_view; + loop = p_loop; + frame = p_frame; +} + +ScriptViewFrame::ScriptViewFrame() { + view = -1; + loop = -1; + frame = -1; +} diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.h b/engines/ags/engine/ac/dynobj/scriptviewframe.h new file mode 100644 index 000000000000..1abb47e6d9d8 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTVIEWFRAME_H +#define __AC_SCRIPTVIEWFRAME_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +struct ScriptViewFrame final : AGSCCDynamicObject { + int view, loop, frame; + + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + + ScriptViewFrame(int p_view, int p_loop, int p_frame); + ScriptViewFrame(); +}; + +#endif // __AC_SCRIPTVIEWFRAME_H \ No newline at end of file diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp new file mode 100644 index 000000000000..0bd8a0af4f95 --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -0,0 +1,64 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptviewport.h" +#include "ac/gamestate.h" +#include "util/bbop.h" + +using namespace AGS::Common; + +ScriptViewport::ScriptViewport(int id) : _id(id) {} + +const char *ScriptViewport::GetType() +{ + return "Viewport2"; +} + +int ScriptViewport::Dispose(const char *address, bool force) +{ + // Note that ScriptViewport is a reference to actual Viewport object, + // and this deletes the reference, while viewport may remain in GameState. + delete this; + return 1; +} + +int ScriptViewport::Serialize(const char *address, char *buffer, int bufsize) +{ + StartSerialize(buffer); + SerializeInt(_id); + return EndSerialize(); +} + +void ScriptViewport::Unserialize(int index, const char *serializedData, int dataSize) +{ + StartUnserialize(serializedData, dataSize); + _id = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); +} + +ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int dataSize) +{ + // The way it works now, we must not create a new script object, + // but acquire one from the GameState, which keeps the first reference. + // This is essential because GameState should be able to invalidate any + // script references when Viewport gets removed. + const int id = BBOp::Int32FromLE(*((int*)serializedData)); + if (id >= 0) + { + auto scview = play.RegisterRoomViewport(id, handle); + if (scview) + return scview; + } + return new ScriptViewport(-1); // make invalid reference +} diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.h b/engines/ags/engine/ac/dynobj/scriptviewport.h new file mode 100644 index 000000000000..d742dfe12d0f --- /dev/null +++ b/engines/ags/engine/ac/dynobj/scriptviewport.h @@ -0,0 +1,43 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SCRIPTVIEWPORT_H +#define __AC_SCRIPTVIEWPORT_H + +#include "ac/dynobj/cc_agsdynamicobject.h" + +// ScriptViewport keeps a reference to actual room Viewport in script. +struct ScriptViewport final : AGSCCDynamicObject +{ +public: + ScriptViewport(int id); + // Get viewport index; negative means the viewport was deleted + int GetID() const { return _id; } + void SetID(int id) { _id = id; } + // Reset viewport index to indicate that this reference is no longer valid + void Invalidate() { _id = -1; } + + const char *GetType() override; + int Dispose(const char *address, bool force) override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + +private: + int _id = -1; // index of viewport in the game state array +}; + +// Unserialize viewport from the memory stream +ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int dataSize); + +#endif // __AC_SCRIPTVIEWPORT_H diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp new file mode 100644 index 000000000000..dc3bf6f6f84e --- /dev/null +++ b/engines/ags/engine/ac/event.cpp @@ -0,0 +1,426 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "event.h" +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_game.h" +#include "ac/global_room.h" +#include "ac/global_screen.h" +#include "ac/gui.h" +#include "ac/roomstatus.h" +#include "ac/screen.h" +#include "script/cc_error.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "script/script.h" +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "gfx/graphicsdriver.h" +#include "media/audio/audio_system.h" +#include "ac/timer.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern RoomStruct thisroom; +extern RoomStatus*croom; +extern int displayed_room; +extern GameState play; +extern color palette[256]; +extern IGraphicsDriver *gfxDriver; +extern AGSPlatformDriver *platform; +extern color old_palette[256]; + +int in_enters_screen=0,done_es_error = 0; +int in_leaves_screen = -1; + +EventHappened event[MAXEVENTS+1]; +int numevents=0; + +const char*evblockbasename; +int evblocknum; + +int inside_processevent=0; +int eventClaimed = EVENT_NONE; + +const char*tsnames[4]={nullptr, REP_EXEC_NAME, "on_key_press","on_mouse_click"}; + + +int run_claimable_event(const char *tsname, bool includeRoom, int numParams, const RuntimeScriptValue *params, bool *eventWasClaimed) { + *eventWasClaimed = true; + // Run the room script function, and if it is not claimed, + // then run the main one + // We need to remember the eventClaimed variable's state, in case + // this is a nested event + int eventClaimedOldValue = eventClaimed; + eventClaimed = EVENT_INPROGRESS; + int toret; + + if (includeRoom && roominst) { + toret = RunScriptFunctionIfExists(roominst, tsname, numParams, params); + + if (eventClaimed == EVENT_CLAIMED) { + eventClaimed = eventClaimedOldValue; + return toret; + } + } + + // run script modules + for (int kk = 0; kk < numScriptModules; kk++) { + toret = RunScriptFunctionIfExists(moduleInst[kk], tsname, numParams, params); + + if (eventClaimed == EVENT_CLAIMED) { + eventClaimed = eventClaimedOldValue; + return toret; + } + } + + eventClaimed = eventClaimedOldValue; + *eventWasClaimed = false; + return 0; +} + +// runs the global script on_event function +void run_on_event (int evtype, RuntimeScriptValue &wparam) +{ + QueueScriptFunction(kScInstGame, "on_event", 2, RuntimeScriptValue().SetInt32(evtype), wparam); +} + +void run_room_event(int id) { + evblockbasename="room"; + + if (thisroom.EventHandlers != nullptr) + { + run_interaction_script(thisroom.EventHandlers.get(), id); + } + else + { + run_interaction_event (&croom->intrRoom, id); + } +} + +void run_event_block_inv(int invNum, int event) { + evblockbasename="inventory%d"; + if (loaded_game_file_version > kGameVersion_272) + { + run_interaction_script(game.invScripts[invNum].get(), event); + } + else + { + run_interaction_event(game.intrInv[invNum].get(), event); + } + +} + +// event list functions +void setevent(int evtyp,int ev1,int ev2,int ev3) { + event[numevents].type=evtyp; + event[numevents].data1=ev1; + event[numevents].data2=ev2; + event[numevents].data3=ev3; + event[numevents].player=game.playercharacter; + numevents++; + if (numevents>=MAXEVENTS) quit("too many events posted"); +} + +// TODO: this is kind of a hack, which forces event to be processed even if +// it was fired from insides of other event processing. +// The proper solution would be to do the event processing overhaul in AGS. +void force_event(int evtyp,int ev1,int ev2,int ev3) +{ + if (inside_processevent) + runevent_now(evtyp, ev1, ev2, ev3); + else + setevent(evtyp, ev1, ev2, ev3); +} + +void process_event(EventHappened*evp) { + RuntimeScriptValue rval_null; + if (evp->type==EV_TEXTSCRIPT) { + ccError=0; + if (evp->data2 > -1000) { + QueueScriptFunction(kScInstGame, tsnames[evp->data1], 1, RuntimeScriptValue().SetInt32(evp->data2)); + } + else { + QueueScriptFunction(kScInstGame, tsnames[evp->data1]); + } + } + else if (evp->type==EV_NEWROOM) { + NewRoom(evp->data1); + } + else if (evp->type==EV_RUNEVBLOCK) { + Interaction*evpt=nullptr; + PInteractionScripts scriptPtr = nullptr; + const char *oldbasename = evblockbasename; + int oldblocknum = evblocknum; + + if (evp->data1==EVB_HOTSPOT) { + + if (thisroom.Hotspots[evp->data2].EventHandlers != nullptr) + scriptPtr = thisroom.Hotspots[evp->data2].EventHandlers; + else + evpt=&croom->intrHotspot[evp->data2]; + + evblockbasename="hotspot%d"; + evblocknum=evp->data2; + //Debug::Printf("Running hotspot interaction for hotspot %d, event %d", evp->data2, evp->data3); + } + else if (evp->data1==EVB_ROOM) { + + if (thisroom.EventHandlers != nullptr) + scriptPtr = thisroom.EventHandlers; + else + evpt=&croom->intrRoom; + + evblockbasename="room"; + if (evp->data3 == 5) { + in_enters_screen ++; + run_on_event (GE_ENTER_ROOM, RuntimeScriptValue().SetInt32(displayed_room)); + + } + //Debug::Printf("Running room interaction, event %d", evp->data3); + } + + if (scriptPtr != nullptr) + { + run_interaction_script(scriptPtr.get(), evp->data3); + } + else if (evpt != nullptr) + { + run_interaction_event(evpt,evp->data3); + } + else + quit("process_event: RunEvBlock: unknown evb type"); + + evblockbasename = oldbasename; + evblocknum = oldblocknum; + + if ((evp->data3 == 5) && (evp->data1 == EVB_ROOM)) + in_enters_screen --; + } + else if (evp->type==EV_FADEIN) { + // if they change the transition type before the fadein, make + // sure the screen doesn't freeze up + play.screen_is_faded_out = 0; + + // determine the transition style + int theTransition = play.fade_effect; + + if (play.next_screen_transition >= 0) { + // a one-off transition was selected, so use it + theTransition = play.next_screen_transition; + play.next_screen_transition = -1; + } + + if (pl_run_plugin_hooks(AGSE_TRANSITIONIN, 0)) + return; + + if (play.fast_forward) + return; + + const bool ignore_transition = (play.screen_tint > 0); + if (((theTransition == FADE_CROSSFADE) || (theTransition == FADE_DISSOLVE)) && + (saved_viewport_bitmap == nullptr) && !ignore_transition) + { + // transition type was not crossfade/dissolve when the screen faded out, + // but it is now when the screen fades in (Eg. a save game was restored + // with a different setting). Therefore just fade normally. + my_fade_out(5); + theTransition = FADE_NORMAL; + } + + // TODO: use normal coordinates instead of "native_size" and multiply_up_*? + const Size &data_res = game.GetDataRes(); + const Rect &viewport = play.GetMainViewport(); + + if ((theTransition == FADE_INSTANT) || ignore_transition) + set_palette_range(palette, 0, 255, 0); + else if (theTransition == FADE_NORMAL) + { + my_fade_in(palette,5); + } + else if (theTransition == FADE_BOXOUT) + { + if (!gfxDriver->UsesMemoryBackBuffer()) + { + gfxDriver->BoxOutEffect(false, get_fixed_pixel_size(16), 1000 / GetGameSpeed()); + } + else + { + // First of all we render the game once again and save backbuffer from further editing. + // We put temporary bitmap as a new backbuffer for the transition period, and + // will be drawing saved image of the game over to that backbuffer, simulating "box-out". + set_palette_range(palette, 0, 255, 0); + construct_game_scene(true); + construct_game_screen_overlay(false); + gfxDriver->RenderToBackBuffer(); + Bitmap *saved_backbuf = gfxDriver->GetMemoryBackBuffer(); + Bitmap *temp_scr = new Bitmap(saved_backbuf->GetWidth(), saved_backbuf->GetHeight(), saved_backbuf->GetColorDepth()); + gfxDriver->SetMemoryBackBuffer(temp_scr); + temp_scr->Clear(); + render_to_screen(); + + const int speed = get_fixed_pixel_size(16); + const int yspeed = viewport.GetHeight() / (viewport.GetWidth() / speed); + int boxwid = speed, boxhit = yspeed; + while (boxwid < temp_scr->GetWidth()) + { + boxwid += speed; + boxhit += yspeed; + boxwid = Math::Clamp(boxwid, 0, viewport.GetWidth()); + boxhit = Math::Clamp(boxhit, 0, viewport.GetHeight()); + int lxp = viewport.GetWidth() / 2 - boxwid / 2; + int lyp = viewport.GetHeight() / 2 - boxhit / 2; + gfxDriver->Vsync(); + temp_scr->Blit(saved_backbuf, lxp, lyp, lxp, lyp, + boxwid, boxhit); + render_to_screen(); + update_polled_mp3(); + WaitForNextFrame(); + } + gfxDriver->SetMemoryBackBuffer(saved_backbuf); + } + play.screen_is_faded_out = 0; + } + else if (theTransition == FADE_CROSSFADE) + { + if (game.color_depth == 1) + quit("!Cannot use crossfade screen transition in 256-colour games"); + + IDriverDependantBitmap *ddb = prepare_screen_for_transition_in(); + + int transparency = 254; + + while (transparency > 0) { + // do the crossfade + ddb->SetTransparency(transparency); + invalidate_screen(); + construct_game_scene(true); + construct_game_screen_overlay(false); + + if (transparency > 16) + { + // on last frame of fade (where transparency < 16), don't + // draw the old screen on top + gfxDriver->DrawSprite(0, 0, ddb); + } + render_to_screen(); + update_polled_stuff_if_runtime(); + WaitForNextFrame(); + transparency -= 16; + } + saved_viewport_bitmap->Release(); + + delete saved_viewport_bitmap; + saved_viewport_bitmap = nullptr; + set_palette_range(palette, 0, 255, 0); + gfxDriver->DestroyDDB(ddb); + } + else if (theTransition == FADE_DISSOLVE) { + int pattern[16]={0,4,14,9,5,11,2,8,10,3,12,7,15,6,13,1}; + int aa,bb,cc; + color interpal[256]; + + IDriverDependantBitmap *ddb = prepare_screen_for_transition_in(); + for (aa=0;aa<16;aa++) { + // merge the palette while dithering + if (game.color_depth == 1) + { + fade_interpolate(old_palette,palette,interpal,aa*4,0,255); + set_palette_range(interpal, 0, 255, 0); + } + // do the dissolving + int maskCol = saved_viewport_bitmap->GetMaskColor(); + for (bb=0;bbPutPixel(bb+pattern[aa]/4, cc+pattern[aa]%4, maskCol); + } + } + gfxDriver->UpdateDDBFromBitmap(ddb, saved_viewport_bitmap, false); + construct_game_scene(true); + construct_game_screen_overlay(false); + gfxDriver->DrawSprite(0, 0, ddb); + render_to_screen(); + update_polled_stuff_if_runtime(); + WaitForNextFrame(); + } + + delete saved_viewport_bitmap; + saved_viewport_bitmap = nullptr; + set_palette_range(palette, 0, 255, 0); + gfxDriver->DestroyDDB(ddb); + } + + } + else if (evp->type==EV_IFACECLICK) + process_interface_click(evp->data1, evp->data2, evp->data3); + else quit("process_event: unknown event to process"); +} + + +void runevent_now (int evtyp, int ev1, int ev2, int ev3) { + EventHappened evh; + evh.type = evtyp; + evh.data1 = ev1; + evh.data2 = ev2; + evh.data3 = ev3; + evh.player = game.playercharacter; + process_event(&evh); +} + +void processallevents(int numev,EventHappened*evlist) { + int dd; + + if (inside_processevent) + return; + + // make a copy of the events - if processing an event includes + // a blocking function it will continue to the next game loop + // and wipe out the event pointer we were passed + EventHappened copyOfList[MAXEVENTS]; + memcpy(©OfList[0], &evlist[0], sizeof(EventHappened) * numev); + + int room_was = play.room_changes; + + inside_processevent++; + + for (dd=0;dd scFileAppend)) + quit("!OpenFile: invalid file mode"); + + sc_File *scf = new sc_File(); + if (scf->OpenFile(fnmm, mode) == 0) { + delete scf; + return nullptr; + } + ccRegisterManagedObject(scf, scf); + return scf; +} + +void File_Close(sc_File *fil) { + fil->Close(); +} + +void File_WriteString(sc_File *fil, const char *towrite) { + FileWrite(fil->handle, towrite); +} + +void File_WriteInt(sc_File *fil, int towrite) { + FileWriteInt(fil->handle, towrite); +} + +void File_WriteRawChar(sc_File *fil, int towrite) { + FileWriteRawChar(fil->handle, towrite); +} + +void File_WriteRawLine(sc_File *fil, const char *towrite) { + FileWriteRawLine(fil->handle, towrite); +} + +void File_ReadRawLine(sc_File *fil, char* buffer) { + Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.ReadRawLine"); + check_strlen(buffer); + int i = 0; + while (i < MAXSTRLEN - 1) { + buffer[i] = in->ReadInt8(); + if (buffer[i] == 13) { + // CR -- skip LF and abort + in->ReadInt8(); + break; + } + if (buffer[i] == 10) // LF only -- abort + break; + if (in->EOS()) // EOF -- abort + break; + i++; + } + buffer[i] = 0; +} + +const char* File_ReadRawLineBack(sc_File *fil) { + char readbuffer[MAX_MAXSTRLEN + 1]; + File_ReadRawLine(fil, readbuffer); + return CreateNewScriptString(readbuffer); +} + +void File_ReadString(sc_File *fil, char *toread) { + FileRead(fil->handle, toread); +} + +const char* File_ReadStringBack(sc_File *fil) { + Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.ReadStringBack"); + if (in->EOS()) { + return CreateNewScriptString(""); + } + + int lle = in->ReadInt32(); + if ((lle >= 20000) || (lle < 1)) + quit("!File.ReadStringBack: file was not written by WriteString"); + + char *retVal = (char*)malloc(lle); + in->Read(retVal, lle); + + return CreateNewScriptString(retVal, false); +} + +int File_ReadInt(sc_File *fil) { + return FileReadInt(fil->handle); +} + +int File_ReadRawChar(sc_File *fil) { + return FileReadRawChar(fil->handle); +} + +int File_ReadRawInt(sc_File *fil) { + return FileReadRawInt(fil->handle); +} + +int File_Seek(sc_File *fil, int offset, int origin) +{ + Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.Seek"); + if (!in->Seek(offset, (StreamSeek)origin)) { return -1; } + return in->GetPosition(); +} + +int File_GetEOF(sc_File *fil) { + if (fil->handle <= 0) + return 1; + return FileIsEOF(fil->handle); +} + +int File_GetError(sc_File *fil) { + if (fil->handle <= 0) + return 1; + return FileIsError(fil->handle); +} + +int File_GetPosition(sc_File *fil) +{ + if (fil->handle <= 0) + return -1; + Stream *stream = get_valid_file_stream_from_handle(fil->handle, "File.Position"); + // TODO: a problem is that AGS script does not support unsigned or long int + return (int)stream->GetPosition(); +} + +//============================================================================= + + +const String GameInstallRootToken = "$INSTALLDIR$"; +const String UserSavedgamesRootToken = "$MYDOCS$"; +const String GameSavedgamesDirToken = "$SAVEGAMEDIR$"; +const String GameDataDirToken = "$APPDATADIR$"; + +void FixupFilename(char *filename) +{ + const char *illegal = platform->GetIllegalFileChars(); + for (char *name_ptr = filename; *name_ptr; ++name_ptr) + { + if (*name_ptr < ' ') + { + *name_ptr = '_'; + } + else + { + for (const char *ch_ptr = illegal; *ch_ptr; ++ch_ptr) + if (*name_ptr == *ch_ptr) + *name_ptr = '_'; + } + } +} + +// Tests if there is a special path token in the beginning of the given path; +// if there is and there is no slash between token and the rest of the string, +// then assigns new string that has such slash. +// Returns TRUE if the new string was created, and FALSE if the path was good. +bool FixSlashAfterToken(const String &path, const String &token, String &new_path) +{ + if (path.CompareLeft(token) == 0 && path.GetLength() > token.GetLength() && + path[token.GetLength()] != '/') + { + new_path = String::FromFormat("%s/%s", token.GetCStr(), path.Mid(token.GetLength()).GetCStr()); + return true; + } + return false; +} + +String FixSlashAfterToken(const String &path) +{ + String fixed_path = path; + Path::FixupPath(fixed_path); + if (FixSlashAfterToken(fixed_path, GameInstallRootToken, fixed_path) || + FixSlashAfterToken(fixed_path, UserSavedgamesRootToken, fixed_path) || + FixSlashAfterToken(fixed_path, GameSavedgamesDirToken, fixed_path) || + FixSlashAfterToken(fixed_path, GameDataDirToken, fixed_path)) + return fixed_path; + return path; +} + +String MakeSpecialSubDir(const String &sp_dir) +{ + if (is_relative_filename(sp_dir)) + return sp_dir; + String full_path = sp_dir; + if (full_path.GetLast() != '/' && full_path.GetLast() != '\\') + full_path.AppendChar('/'); + full_path.Append(game.saveGameFolderName); + Directory::CreateDirectory(full_path); + return full_path; +} + +String MakeAppDataPath() +{ + String app_data_path = usetup.shared_data_dir; + if (app_data_path.IsEmpty()) + app_data_path = MakeSpecialSubDir(PathOrCurDir(platform->GetAllUsersDataDirectory())); + Directory::CreateDirectory(app_data_path); + app_data_path.AppendChar('/'); + return app_data_path; +} + +bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath &rp) +{ + rp = ResolvedPath(); + + bool is_absolute = !is_relative_filename(orig_sc_path); + if (is_absolute && !read_only) + { + debug_script_warn("Attempt to access file '%s' denied (cannot write to absolute path)", orig_sc_path.GetCStr()); + return false; + } + + if (is_absolute) + { + rp.FullPath = orig_sc_path; + return true; + } + + String sc_path = FixSlashAfterToken(orig_sc_path); + String parent_dir; + String child_path; + String alt_path; + if (sc_path.CompareLeft(GameInstallRootToken, GameInstallRootToken.GetLength()) == 0) + { + if (!read_only) + { + debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory)", + sc_path.GetCStr()); + return false; + } + parent_dir = get_install_dir(); + parent_dir.AppendChar('/'); + child_path = sc_path.Mid(GameInstallRootToken.GetLength()); + } + else if (sc_path.CompareLeft(GameSavedgamesDirToken, GameSavedgamesDirToken.GetLength()) == 0) + { + parent_dir = get_save_game_directory(); + child_path = sc_path.Mid(GameSavedgamesDirToken.GetLength()); + } + else if (sc_path.CompareLeft(GameDataDirToken, GameDataDirToken.GetLength()) == 0) + { + parent_dir = MakeAppDataPath(); + child_path = sc_path.Mid(GameDataDirToken.GetLength()); + } + else + { + child_path = sc_path; + + // For games which were made without having safe paths in mind, + // provide two paths: a path to the local directory and a path to + // AppData directory. + // This is done in case game writes a file by local path, and would + // like to read it back later. Since AppData path has higher priority, + // game will first check the AppData location and find a previously + // written file. + // If no file was written yet, but game is trying to read a pre-created + // file in the installation directory, then such file will be found + // following the 'alt_path'. + parent_dir = MakeAppDataPath(); + // Set alternate non-remapped "unsafe" path for read-only operations + if (read_only) + alt_path = String::FromFormat("%s/%s", get_install_dir().GetCStr(), sc_path.GetCStr()); + + // For games made in the safe-path-aware versions of AGS, report a warning + // if the unsafe path is used for write operation + if (!read_only && game.options[OPT_SAFEFILEPATHS]) + { + debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory);\nPath will be remapped to the app data directory: '%s'", + sc_path.GetCStr(), parent_dir.GetCStr()); + } + } + + if (child_path[0u] == '\\' || child_path[0u] == '/') + child_path.ClipLeft(1); + + String full_path = String::FromFormat("%s%s", parent_dir.GetCStr(), child_path.GetCStr()); + // don't allow write operations for relative paths outside game dir + if (!read_only) + { + if (!Path::IsSameOrSubDir(parent_dir, full_path)) + { + debug_script_warn("Attempt to access file '%s' denied (outside of game directory)", sc_path.GetCStr()); + return false; + } + } + rp.BaseDir = parent_dir; + rp.FullPath = full_path; + rp.AltPath = alt_path; + return true; +} + +bool ResolveWritePathAndCreateDirs(const String &sc_path, ResolvedPath &rp) +{ + if (!ResolveScriptPath(sc_path, false, rp)) + return false; + if (!Directory::CreateAllDirectories(rp.BaseDir, Path::GetDirectoryPath(rp.FullPath))) + { + debug_script_warn("ResolveScriptPath: failed to create all subdirectories: %s", rp.FullPath.GetCStr()); + return false; + } + return true; +} + +Stream *LocateAsset(const AssetPath &path, size_t &asset_size) +{ + String assetlib = path.first; + String assetname = path.second; + bool needsetback = false; + // Change to the different library, if required + // TODO: teaching AssetManager to register multiple libraries simultaneously + // will let us skip this step, and also make this operation much faster. + if (!assetlib.IsEmpty() && assetlib.CompareNoCase(ResPaths.GamePak.Name) != 0) + { + AssetManager::SetDataFile(get_known_assetlib(assetlib)); + needsetback = true; + } + Stream *asset_stream = AssetManager::OpenAsset(assetname); + asset_size = AssetManager::GetLastAssetSize(); + if (needsetback) + AssetManager::SetDataFile(ResPaths.GamePak.Path); + return asset_stream; +} + +// +// AGS custom PACKFILE callbacks, that use our own Stream object +// +static int ags_pf_fclose(void *userdata) +{ + delete (AGS_PACKFILE_OBJ*)userdata; + return 0; +} + +static int ags_pf_getc(void *userdata) +{ + AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)userdata; + if (obj->remains > 0) + { + obj->remains--; + return obj->stream->ReadByte(); + } + return -1; +} + +static int ags_pf_ungetc(int c, void *userdata) +{ + return -1; // we do not want to support this +} + +static long ags_pf_fread(void *p, long n, void *userdata) +{ + AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)userdata; + if (obj->remains > 0) + { + size_t read = Math::Min(obj->remains, (size_t)n); + obj->remains -= read; + return obj->stream->Read(p, read); + } + return -1; +} + +static int ags_pf_putc(int c, void *userdata) +{ + return -1; // don't support write +} + +static long ags_pf_fwrite(AL_CONST void *p, long n, void *userdata) +{ + return -1; // don't support write +} + +static int ags_pf_fseek(void *userdata, int offset) +{ + return -1; // don't support seek +} + +static int ags_pf_feof(void *userdata) +{ + return ((AGS_PACKFILE_OBJ*)userdata)->remains == 0; +} + +static int ags_pf_ferror(void *userdata) +{ + return ((AGS_PACKFILE_OBJ*)userdata)->stream->HasErrors() ? 1 : 0; +} + +// Custom PACKFILE callback table +static PACKFILE_VTABLE ags_packfile_vtable = { + ags_pf_fclose, + ags_pf_getc, + ags_pf_ungetc, + ags_pf_fread, + ags_pf_putc, + ags_pf_fwrite, + ags_pf_fseek, + ags_pf_feof, + ags_pf_ferror +}; +// + +PACKFILE *PackfileFromAsset(const AssetPath &path, size_t &asset_size) +{ + Stream *asset_stream = LocateAsset(path, asset_size); + if (asset_stream && asset_size > 0) + { + AGS_PACKFILE_OBJ* obj = new AGS_PACKFILE_OBJ; + obj->stream.reset(asset_stream); + obj->asset_size = asset_size; + obj->remains = asset_size; + return pack_fopen_vtable(&ags_packfile_vtable, obj); + } + return nullptr; +} + +DUMBFILE *DUMBfileFromAsset(const AssetPath &path, size_t &asset_size) +{ + PACKFILE *pf = PackfileFromAsset(path, asset_size); + if (pf) + return dumbfile_open_packfile(pf); + return nullptr; +} + +bool DoesAssetExistInLib(const AssetPath &assetname) +{ + bool needsetback = false; + // Change to the different library, if required + // TODO: teaching AssetManager to register multiple libraries simultaneously + // will let us skip this step, and also make this operation much faster. + if (!assetname.first.IsEmpty() && assetname.first.CompareNoCase(ResPaths.GamePak.Name) != 0) + { + AssetManager::SetDataFile(get_known_assetlib(assetname.first)); + needsetback = true; + } + bool res = AssetManager::DoesAssetExist(assetname.second); + if (needsetback) + AssetManager::SetDataFile(ResPaths.GamePak.Path); + return res; +} + +void set_install_dir(const String &path, const String &audio_path, const String &voice_path) +{ + if (path.IsEmpty()) + installDirectory = "."; + else + installDirectory = Path::MakePathNoSlash(path); + if (audio_path.IsEmpty()) + installAudioDirectory = "."; + else + installAudioDirectory = Path::MakePathNoSlash(audio_path); + if (voice_path.IsEmpty()) + installVoiceDirectory = "."; + else + installVoiceDirectory = Path::MakePathNoSlash(voice_path); +} + +String get_install_dir() +{ + return installDirectory; +} + +String get_audio_install_dir() +{ + return installAudioDirectory; +} + +String get_voice_install_dir() +{ + return installVoiceDirectory; +} + +void get_install_dir_path(char* buffer, const char *fileName) +{ + sprintf(buffer, "%s/%s", installDirectory.GetCStr(), fileName); +} + +String find_assetlib(const String &filename) +{ + String libname = cbuf_to_string_and_free( ci_find_file(ResPaths.DataDir, filename) ); + if (AssetManager::IsDataFile(libname)) + return libname; + if (Path::ComparePaths(ResPaths.DataDir, installDirectory) != 0) + { + // Hack for running in Debugger + libname = cbuf_to_string_and_free( ci_find_file(installDirectory, filename) ); + if (AssetManager::IsDataFile(libname)) + return libname; + } + return ""; +} + +// Looks up for known valid asset library and returns path, or empty string if failed +String get_known_assetlib(const String &filename) +{ + // TODO: write now there's only 3 regular PAKs, so we may do this quick + // string comparison, but if we support more maybe we could use a table. + if (filename.CompareNoCase(ResPaths.GamePak.Name) == 0) + return ResPaths.GamePak.Path; + if (filename.CompareNoCase(ResPaths.AudioPak.Name) == 0) + return ResPaths.AudioPak.Path; + if (filename.CompareNoCase(ResPaths.SpeechPak.Name) == 0) + return ResPaths.SpeechPak.Path; + return String(); +} + +Stream *find_open_asset(const String &filename) +{ + Stream *asset_s = Common::AssetManager::OpenAsset(filename); + if (!asset_s && Path::ComparePaths(ResPaths.DataDir, installDirectory) != 0) + { + // Just in case they're running in Debug, try standalone file in compiled folder + asset_s = ci_fopen(String::FromFormat("%s/%s", installDirectory.GetCStr(), filename.GetCStr())); + } + return asset_s; +} + +AssetPath get_audio_clip_assetpath(int bundling_type, const String &filename) +{ + // Special case is explicitly defined audio directory, which should be + // tried first regardless of bundling type. + if (Path::ComparePaths(ResPaths.DataDir, installAudioDirectory) != 0) + { + String filepath = String::FromFormat("%s/%s", installAudioDirectory.GetCStr(), filename.GetCStr()); + if (Path::IsFile(filepath)) + return AssetPath("", filepath); + } + + if (bundling_type == AUCL_BUNDLE_EXE) + return AssetPath(ResPaths.GamePak.Name, filename); + else if (bundling_type == AUCL_BUNDLE_VOX) + return AssetPath(game.GetAudioVOXName(), filename); + return AssetPath(); +} + +AssetPath get_voice_over_assetpath(const String &filename) +{ + // Special case is explicitly defined voice-over directory, which should be + // tried first. + if (Path::ComparePaths(ResPaths.DataDir, installVoiceDirectory) != 0) + { + String filepath = String::FromFormat("%s/%s", installVoiceDirectory.GetCStr(), filename.GetCStr()); + if (Path::IsFile(filepath)) + return AssetPath("", filepath); + } + return AssetPath(ResPaths.SpeechPak.Name, filename); +} + +ScriptFileHandle valid_handles[MAX_OPEN_SCRIPT_FILES + 1]; +// [IKM] NOTE: this is not precisely the number of files opened at this moment, +// but rather maximal number of handles that were used simultaneously during game run +int num_open_script_files = 0; +ScriptFileHandle *check_valid_file_handle_ptr(Stream *stream_ptr, const char *operation_name) +{ + if (stream_ptr) + { + for (int i = 0; i < num_open_script_files; ++i) + { + if (stream_ptr == valid_handles[i].stream) + { + return &valid_handles[i]; + } + } + } + + String exmsg = String::FromFormat("!%s: invalid file handle; file not previously opened or has been closed", operation_name); + quit(exmsg); + return nullptr; +} + +ScriptFileHandle *check_valid_file_handle_int32(int32_t handle, const char *operation_name) +{ + if (handle > 0) + { + for (int i = 0; i < num_open_script_files; ++i) + { + if (handle == valid_handles[i].handle) + { + return &valid_handles[i]; + } + } + } + + String exmsg = String::FromFormat("!%s: invalid file handle; file not previously opened or has been closed", operation_name); + quit(exmsg); + return nullptr; +} + +Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_name) +{ + ScriptFileHandle *sc_handle = check_valid_file_handle_int32(handle, operation_name); + return sc_handle ? sc_handle->stream : nullptr; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// int (const char *fnmm) +RuntimeScriptValue Sc_File_Delete(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(File_Delete, const char); +} + +// int (const char *fnmm) +RuntimeScriptValue Sc_File_Exists(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(File_Exists, const char); +} + +// void *(const char *fnmm, int mode) +RuntimeScriptValue Sc_sc_OpenFile(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_POBJ_PINT(sc_File, sc_OpenFile, const char); +} + +// void (sc_File *fil) +RuntimeScriptValue Sc_File_Close(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(sc_File, File_Close); +} + +// int (sc_File *fil) +RuntimeScriptValue Sc_File_ReadInt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(sc_File, File_ReadInt); +} + +// int (sc_File *fil) +RuntimeScriptValue Sc_File_ReadRawChar(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(sc_File, File_ReadRawChar); +} + +// int (sc_File *fil) +RuntimeScriptValue Sc_File_ReadRawInt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(sc_File, File_ReadRawInt); +} + +// void (sc_File *fil, char* buffer) +RuntimeScriptValue Sc_File_ReadRawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(sc_File, File_ReadRawLine, char); +} + +// const char* (sc_File *fil) +RuntimeScriptValue Sc_File_ReadRawLineBack(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadRawLineBack); +} + +// void (sc_File *fil, char *toread) +RuntimeScriptValue Sc_File_ReadString(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(sc_File, File_ReadString, char); +} + +// const char* (sc_File *fil) +RuntimeScriptValue Sc_File_ReadStringBack(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadStringBack); +} + +// void (sc_File *fil, int towrite) +RuntimeScriptValue Sc_File_WriteInt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(sc_File, File_WriteInt); +} + +// void (sc_File *fil, int towrite) +RuntimeScriptValue Sc_File_WriteRawChar(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(sc_File, File_WriteRawChar); +} + +// void (sc_File *fil, const char *towrite) +RuntimeScriptValue Sc_File_WriteRawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(sc_File, File_WriteRawLine, const char); +} + +// void (sc_File *fil, const char *towrite) +RuntimeScriptValue Sc_File_WriteString(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(sc_File, File_WriteString, const char); +} + +RuntimeScriptValue Sc_File_Seek(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT2(sc_File, File_Seek); +} + +// int (sc_File *fil) +RuntimeScriptValue Sc_File_GetEOF(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(sc_File, File_GetEOF); +} + +// int (sc_File *fil) +RuntimeScriptValue Sc_File_GetError(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(sc_File, File_GetError); +} + +RuntimeScriptValue Sc_File_GetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(sc_File, File_GetPosition); +} + + +void RegisterFileAPI() +{ + ccAddExternalStaticFunction("File::Delete^1", Sc_File_Delete); + ccAddExternalStaticFunction("File::Exists^1", Sc_File_Exists); + ccAddExternalStaticFunction("File::Open^2", Sc_sc_OpenFile); + ccAddExternalObjectFunction("File::Close^0", Sc_File_Close); + ccAddExternalObjectFunction("File::ReadInt^0", Sc_File_ReadInt); + ccAddExternalObjectFunction("File::ReadRawChar^0", Sc_File_ReadRawChar); + ccAddExternalObjectFunction("File::ReadRawInt^0", Sc_File_ReadRawInt); + ccAddExternalObjectFunction("File::ReadRawLine^1", Sc_File_ReadRawLine); + ccAddExternalObjectFunction("File::ReadRawLineBack^0", Sc_File_ReadRawLineBack); + ccAddExternalObjectFunction("File::ReadString^1", Sc_File_ReadString); + ccAddExternalObjectFunction("File::ReadStringBack^0", Sc_File_ReadStringBack); + ccAddExternalObjectFunction("File::WriteInt^1", Sc_File_WriteInt); + ccAddExternalObjectFunction("File::WriteRawChar^1", Sc_File_WriteRawChar); + ccAddExternalObjectFunction("File::WriteRawLine^1", Sc_File_WriteRawLine); + ccAddExternalObjectFunction("File::WriteString^1", Sc_File_WriteString); + ccAddExternalObjectFunction("File::Seek^2", Sc_File_Seek); + ccAddExternalObjectFunction("File::get_EOF", Sc_File_GetEOF); + ccAddExternalObjectFunction("File::get_Error", Sc_File_GetError); + ccAddExternalObjectFunction("File::get_Position", Sc_File_GetPosition); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("File::Delete^1", (void*)File_Delete); + ccAddExternalFunctionForPlugin("File::Exists^1", (void*)File_Exists); + ccAddExternalFunctionForPlugin("File::Open^2", (void*)sc_OpenFile); + ccAddExternalFunctionForPlugin("File::Close^0", (void*)File_Close); + ccAddExternalFunctionForPlugin("File::ReadInt^0", (void*)File_ReadInt); + ccAddExternalFunctionForPlugin("File::ReadRawChar^0", (void*)File_ReadRawChar); + ccAddExternalFunctionForPlugin("File::ReadRawInt^0", (void*)File_ReadRawInt); + ccAddExternalFunctionForPlugin("File::ReadRawLine^1", (void*)File_ReadRawLine); + ccAddExternalFunctionForPlugin("File::ReadRawLineBack^0", (void*)File_ReadRawLineBack); + ccAddExternalFunctionForPlugin("File::ReadString^1", (void*)File_ReadString); + ccAddExternalFunctionForPlugin("File::ReadStringBack^0", (void*)File_ReadStringBack); + ccAddExternalFunctionForPlugin("File::WriteInt^1", (void*)File_WriteInt); + ccAddExternalFunctionForPlugin("File::WriteRawChar^1", (void*)File_WriteRawChar); + ccAddExternalFunctionForPlugin("File::WriteRawLine^1", (void*)File_WriteRawLine); + ccAddExternalFunctionForPlugin("File::WriteString^1", (void*)File_WriteString); + ccAddExternalFunctionForPlugin("File::get_EOF", (void*)File_GetEOF); + ccAddExternalFunctionForPlugin("File::get_Error", (void*)File_GetError); +} diff --git a/engines/ags/engine/ac/file.h b/engines/ags/engine/ac/file.h new file mode 100644 index 000000000000..cc12e7520624 --- /dev/null +++ b/engines/ags/engine/ac/file.h @@ -0,0 +1,57 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Script File API implementation. +// +//============================================================================= +#ifndef __AGS_EE_AC__FILE_H +#define __AGS_EE_AC__FILE_H + +#include "ac/dynobj/scriptfile.h" +#include "ac/runtime_defines.h" +using AGS::Common::Stream; + +int File_Exists(const char *fnmm); +int File_Delete(const char *fnmm); +void *sc_OpenFile(const char *fnmm, int mode); +void File_Close(sc_File *fil); +void File_WriteString(sc_File *fil, const char *towrite); +void File_WriteInt(sc_File *fil, int towrite); +void File_WriteRawChar(sc_File *fil, int towrite); +void File_WriteRawLine(sc_File *fil, const char *towrite); +void File_ReadRawLine(sc_File *fil, char* buffer); +const char* File_ReadRawLineBack(sc_File *fil); +void File_ReadString(sc_File *fil, char *toread); +const char* File_ReadStringBack(sc_File *fil); +int File_ReadInt(sc_File *fil); +int File_ReadRawChar(sc_File *fil); +int File_ReadRawInt(sc_File *fil); +int File_Seek(sc_File *fil, int offset, int origin); +int File_GetEOF(sc_File *fil); +int File_GetError(sc_File *fil); +int File_GetPosition(sc_File *fil); + +struct ScriptFileHandle +{ + Stream *stream; + int32_t handle; +}; +extern ScriptFileHandle valid_handles[MAX_OPEN_SCRIPT_FILES + 1]; +extern int num_open_script_files; + +ScriptFileHandle *check_valid_file_handle_ptr(Stream *stream_ptr, const char *operation_name); +ScriptFileHandle *check_valid_file_handle_int32(int32_t handle, const char *operation_name); +Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_name); + +#endif // __AGS_EE_AC__FILE_H diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp new file mode 100644 index 000000000000..ac3f6dc70a5e --- /dev/null +++ b/engines/ags/engine/ac/game.cpp @@ -0,0 +1,2545 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/game.h" + +#include "ac/common.h" +#include "ac/view.h" +#include "ac/audiocliptype.h" +#include "ac/audiochannel.h" +#include "ac/character.h" +#include "ac/charactercache.h" +#include "ac/characterextras.h" +#include "ac/dialogtopic.h" +#include "ac/draw.h" +#include "ac/dynamicsprite.h" +#include "ac/event.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/global_character.h" +#include "ac/global_display.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/global_object.h" +#include "ac/global_translation.h" +#include "ac/gui.h" +#include "ac/hotspot.h" +#include "ac/lipsync.h" +#include "ac/mouse.h" +#include "ac/movelist.h" +#include "ac/objectcache.h" +#include "ac/overlay.h" +#include "ac/path_helper.h" +#include "ac/sys_events.h" +#include "ac/region.h" +#include "ac/richgamemedia.h" +#include "ac/room.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "ac/runtime_defines.h" +#include "ac/screenoverlay.h" +#include "ac/spritecache.h" +#include "ac/string.h" +#include "ac/system.h" +#include "ac/timer.h" +#include "ac/translation.h" +#include "ac/dynobj/all_dynamicclasses.h" +#include "ac/dynobj/all_scriptclasses.h" +#include "ac/dynobj/cc_audiochannel.h" +#include "ac/dynobj/cc_audioclip.h" +#include "ac/dynobj/scriptcamera.h" +#include "debug/debug_log.h" +#include "debug/out.h" +#include "device/mousew32.h" +#include "font/fonts.h" +#include "game/savegame.h" +#include "game/savegame_components.h" +#include "game/savegame_internal.h" +#include "gui/animatingguibutton.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" +#include "gfx/gfxfilter.h" +#include "gui/guidialog.h" +#include "main/engine.h" +#include "main/graphics_mode.h" +#include "main/main.h" +#include "media/audio/audio_system.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "script/cc_error.h" +#include "script/runtimescriptvalue.h" +#include "script/script.h" +#include "script/script_runtime.h" +#include "util/alignedstream.h" +#include "util/directory.h" +#include "util/filestream.h" // TODO: needed only because plugins expect file handle +#include "util/path.h" +#include "util/string_utils.h" +#include "ac/keycode.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; +extern int cur_mode,cur_cursor; +extern SpeechLipSyncLine *splipsync; +extern int numLipLines, curLipLine, curLipLinePhoneme; + +extern CharacterExtras *charextra; +extern DialogTopic *dialog; + +extern int ifacepopped; // currently displayed pop-up GUI (-1 if none) +extern int mouse_on_iface; // mouse cursor is over this interface +extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; + +extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; +extern int numAnimButs; + +extern int is_complete_overlay,is_text_overlay; + +#if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID +extern int psp_gfx_renderer; +#endif + +extern int obj_lowest_yp, char_lowest_yp; + +extern int actSpsCount; +extern Bitmap **actsps; +extern IDriverDependantBitmap* *actspsbmp; +// temporary cache of walk-behind for this actsps image +extern Bitmap **actspswb; +extern IDriverDependantBitmap* *actspswbbmp; +extern CachedActSpsData* actspswbcache; +extern Bitmap **guibg; +extern IDriverDependantBitmap **guibgbmp; +extern char transFileName[MAX_PATH]; +extern color palette[256]; +extern unsigned int loopcounter; +extern Bitmap *raw_saved_screen; +extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; +extern IGraphicsDriver *gfxDriver; + +//============================================================================= +GameState play; +GameSetup usetup; +GameSetupStruct game; +RoomStatus troom; // used for non-saveable rooms, eg. intro +RoomObject*objs; +RoomStatus*croom=nullptr; +RoomStruct thisroom; + +volatile int switching_away_from_game = 0; +volatile bool switched_away = false; +volatile char want_exit = 0, abort_engine = 0; +GameDataVersion loaded_game_file_version = kGameVersion_Undefined; +int frames_per_second=40; +int displayed_room=-10,starting_room = -1; +int in_new_room=0, new_room_was = 0; // 1 in new room, 2 first time in new room, 3 loading saved game +int new_room_pos=0; +int new_room_x = SCR_NO_VALUE, new_room_y = SCR_NO_VALUE; +int new_room_loop = SCR_NO_VALUE; + +// initially size 1, this will be increased by the initFile function +SpriteCache spriteset(game.SpriteInfos); +int proper_exit=0,our_eip=0; + +std::vector guis; + +CCGUIObject ccDynamicGUIObject; +CCCharacter ccDynamicCharacter; +CCHotspot ccDynamicHotspot; +CCRegion ccDynamicRegion; +CCInventory ccDynamicInv; +CCGUI ccDynamicGUI; +CCObject ccDynamicObject; +CCDialog ccDynamicDialog; +CCAudioClip ccDynamicAudioClip; +CCAudioChannel ccDynamicAudio; +ScriptString myScriptStringImpl; +// TODO: IMPORTANT!! +// we cannot simply replace these arrays with vectors, or other C++ containers, +// until we implement safe management of such containers in script exports +// system. Noteably we would need an alternate to StaticArray class to track +// access to their elements. +ScriptObject scrObj[MAX_ROOM_OBJECTS]; +ScriptGUI *scrGui = nullptr; +ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; +ScriptRegion scrRegion[MAX_ROOM_REGIONS]; +ScriptInvItem scrInv[MAX_INV]; +ScriptDialog *scrDialog; + +ViewStruct*views=nullptr; + +CharacterCache *charcache = nullptr; +ObjectCache objcache[MAX_ROOM_OBJECTS]; + +MoveList *mls = nullptr; + +//============================================================================= + +String saveGameDirectory = "./"; +// Custom save game parent directory +String saveGameParent; + +const char* sgnametemplate = "agssave.%03d"; +String saveGameSuffix; + +int game_paused=0; +char pexbuf[STD_BUFFER_SIZE]; + +unsigned int load_new_game = 0; +int load_new_game_restore = -1; + +// TODO: refactor these global vars into function arguments +int getloctype_index = 0, getloctype_throughgui = 0; + +//============================================================================= +// Audio +//============================================================================= + +void Game_StopAudio(int audioType) +{ + if (((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) && (audioType != SCR_NO_VALUE)) + quitprintf("!Game.StopAudio: invalid audio type %d", audioType); + int aa; + + for (aa = 0; aa < MAX_SOUND_CHANNELS; aa++) + { + if (audioType == SCR_NO_VALUE) + { + stop_or_fade_out_channel(aa); + } + else + { + ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); + if ((clip != nullptr) && (clip->type == audioType)) + stop_or_fade_out_channel(aa); + } + } + + remove_clips_of_type_from_queue(audioType); +} + +int Game_IsAudioPlaying(int audioType) +{ + if (((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) && (audioType != SCR_NO_VALUE)) + quitprintf("!Game.IsAudioPlaying: invalid audio type %d", audioType); + + if (play.fast_forward) + return 0; + + for (int aa = 0; aa < MAX_SOUND_CHANNELS; aa++) + { + ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); + if (clip != nullptr) + { + if ((clip->type == audioType) || (audioType == SCR_NO_VALUE)) + { + return 1; + } + } + } + return 0; +} + +void Game_SetAudioTypeSpeechVolumeDrop(int audioType, int volumeDrop) +{ + if ((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) + quitprintf("!Game.SetAudioTypeVolume: invalid audio type: %d", audioType); + + Debug::Printf("Game.SetAudioTypeSpeechVolumeDrop: type: %d, drop: %d", audioType, volumeDrop); + game.audioClipTypes[audioType].volume_reduction_while_speech_playing = volumeDrop; + update_volume_drop_if_voiceover(); +} + +void Game_SetAudioTypeVolume(int audioType, int volume, int changeType) +{ + if ((volume < 0) || (volume > 100)) + quitprintf("!Game.SetAudioTypeVolume: volume %d is not between 0..100", volume); + if ((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) + quitprintf("!Game.SetAudioTypeVolume: invalid audio type: %d", audioType); + + Debug::Printf("Game.SetAudioTypeVolume: type: %d, volume: %d, change: %d", audioType, volume, changeType); + if ((changeType == VOL_CHANGEEXISTING) || + (changeType == VOL_BOTH)) + { + AudioChannelsLock lock; + for (int aa = 0; aa < MAX_SOUND_CHANNELS; aa++) + { + ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); + if ((clip != nullptr) && (clip->type == audioType)) + { + auto* ch = lock.GetChannel(aa); + if (ch) + ch->set_volume_percent(volume); + } + } + } + + if ((changeType == VOL_SETFUTUREDEFAULT) || + (changeType == VOL_BOTH)) + { + play.default_audio_type_volumes[audioType] = volume; + + // update queued clip volumes + update_queued_clips_volume(audioType, volume); + } + +} + +int Game_GetMODPattern() { + if (current_music_type != MUS_MOD) + return -1; + AudioChannelsLock lock; + auto* music_ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + return music_ch ? music_ch->get_pos() : -1; +} + +//============================================================================= +// --- +//============================================================================= + +int Game_GetDialogCount() +{ + return game.numdialog; +} + +void set_debug_mode(bool on) +{ + play.debug_mode = on ? 1 : 0; + debug_set_console(on); +} + +void set_game_speed(int new_fps) { + frames_per_second = new_fps; + if (!isTimerFpsMaxed()) // if in maxed mode, don't update timer for now + setTimerFps(new_fps); +} + +extern int cbuttfont; +extern int acdialog_font; + +int oldmouse; +void setup_for_dialog() { + cbuttfont = play.normal_font; + acdialog_font = play.normal_font; + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_ENABLE); + oldmouse=cur_cursor; set_mouse_cursor(CURS_ARROW); +} +void restore_after_dialog() { + set_mouse_cursor(oldmouse); + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_DISABLE); + invalidate_screen(); +} + + + +String get_save_game_directory() +{ + return saveGameDirectory; +} + +String get_save_game_suffix() +{ + return saveGameSuffix; +} + +void set_save_game_suffix(const String &suffix) +{ + saveGameSuffix = suffix; +} + +String get_save_game_path(int slotNum) { + String filename; + filename.Format(sgnametemplate, slotNum); + String path = saveGameDirectory; + path.Append(filename); + path.Append(saveGameSuffix); + return path; +} + +// Convert a path possibly containing path tags into acceptable save path +bool MakeSaveGameDir(const String &newFolder, ResolvedPath &rp) +{ + rp = ResolvedPath(); + // don't allow absolute paths + if (!is_relative_filename(newFolder)) + return false; + + String base_dir; + String newSaveGameDir = FixSlashAfterToken(newFolder); + + if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) + { + if (saveGameParent.IsEmpty()) + { + base_dir = PathOrCurDir(platform->GetUserSavedgamesDirectory()); + newSaveGameDir.ReplaceMid(0, UserSavedgamesRootToken.GetLength(), base_dir); + } + else + { + // If there is a custom save parent directory, then replace + // not only root token, but also first subdirectory + newSaveGameDir.ClipSection('/', 0, 1); + if (!newSaveGameDir.IsEmpty()) + newSaveGameDir.PrependChar('/'); + newSaveGameDir.Prepend(saveGameParent); + base_dir = saveGameParent; + } + } + else + { + // Convert the path relative to installation folder into path relative to the + // safe save path with default name + if (saveGameParent.IsEmpty()) + { + base_dir = PathOrCurDir(platform->GetUserSavedgamesDirectory()); + newSaveGameDir.Format("%s/%s/%s", base_dir.GetCStr(), game.saveGameFolderName, newFolder.GetCStr()); + } + else + { + base_dir = saveGameParent; + newSaveGameDir.Format("%s/%s", saveGameParent.GetCStr(), newFolder.GetCStr()); + } + // For games made in the safe-path-aware versions of AGS, report a warning + if (game.options[OPT_SAFEFILEPATHS]) + { + debug_script_warn("Attempt to explicitly set savegame location relative to the game installation directory ('%s') denied;\nPath will be remapped to the user documents directory: '%s'", + newFolder.GetCStr(), newSaveGameDir.GetCStr()); + } + } + rp.BaseDir = Path::MakeTrailingSlash(base_dir); + rp.FullPath = Path::MakeTrailingSlash(newSaveGameDir); + return true; +} + +bool SetCustomSaveParent(const String &path) +{ + if (SetSaveGameDirectoryPath(path, true)) + { + saveGameParent = path; + return true; + } + return false; +} + +bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path) +{ + if (!newFolder || newFolder[0] == 0) + newFolder = "."; + String newSaveGameDir; + if (explicit_path) + { + newSaveGameDir = Path::MakeTrailingSlash(newFolder); + if (!Directory::CreateDirectory(newSaveGameDir)) + return false; + } + else + { + ResolvedPath rp; + if (!MakeSaveGameDir(newFolder, rp)) + return false; + if (!Directory::CreateAllDirectories(rp.BaseDir, rp.FullPath)) + { + debug_script_warn("SetSaveGameDirectory: failed to create all subdirectories: %s", rp.FullPath.GetCStr()); + return false; + } + newSaveGameDir = rp.FullPath; + } + + String newFolderTempFile = String::FromFormat("%s""agstmp.tmp", newSaveGameDir.GetCStr()); + if (!Common::File::TestCreateFile(newFolderTempFile)) + return false; + + // copy the Restart Game file, if applicable + String restartGamePath = String::FromFormat("%s""agssave.%d%s", saveGameDirectory.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); + Stream *restartGameFile = Common::File::OpenFileRead(restartGamePath); + if (restartGameFile != nullptr) + { + long fileSize = restartGameFile->GetLength(); + char *mbuffer = (char*)malloc(fileSize); + restartGameFile->Read(mbuffer, fileSize); + delete restartGameFile; + + restartGamePath.Format("%s""agssave.%d%s", newSaveGameDir.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); + restartGameFile = Common::File::CreateFile(restartGamePath); + restartGameFile->Write(mbuffer, fileSize); + delete restartGameFile; + free(mbuffer); + } + + saveGameDirectory = newSaveGameDir; + return true; +} + +int Game_SetSaveGameDirectory(const char *newFolder) +{ + return SetSaveGameDirectoryPath(newFolder, false) ? 1 : 0; +} + +const char* Game_GetSaveSlotDescription(int slnum) { + String description; + if (read_savedgame_description(get_save_game_path(slnum), description)) + { + return CreateNewScriptString(description); + } + return nullptr; +} + + +void restore_game_dialog() { + can_run_delayed_command(); + if (thisroom.Options.SaveLoadDisabled == 1) { + DisplayMessage (983); + return; + } + if (inside_script) { + curscript->queue_action(ePSARestoreGameDialog, 0, "RestoreGameDialog"); + return; + } + setup_for_dialog(); + int toload=loadgamedialog(); + restore_after_dialog(); + if (toload>=0) { + try_restore_save(toload); + } +} + +void save_game_dialog() { + if (thisroom.Options.SaveLoadDisabled == 1) { + DisplayMessage (983); + return; + } + if (inside_script) { + curscript->queue_action(ePSASaveGameDialog, 0, "SaveGameDialog"); + return; + } + setup_for_dialog(); + int toload=savegamedialog(); + restore_after_dialog(); + if (toload>=0) + save_game(toload, get_gui_dialog_buffer()); +} + +void free_do_once_tokens() +{ + play.do_once_tokens.resize(0); +} + + +// Free all the memory associated with the game +// TODO: call this when exiting the game (currently only called in RunAGSGame) +void unload_game_file() +{ + close_translation(); + + play.FreeViewportsAndCameras(); + + characterScriptObjNames.clear(); + free(charextra); + free(mls); + free(actsps); + free(actspsbmp); + free(actspswb); + free(actspswbbmp); + free(actspswbcache); + + if ((gameinst != nullptr) && (gameinst->pc != 0)) + { + quit("Error: unload_game called while script still running"); + } + else + { + delete gameinstFork; + delete gameinst; + gameinstFork = nullptr; + gameinst = nullptr; + } + + gamescript.reset(); + + if ((dialogScriptsInst != nullptr) && (dialogScriptsInst->pc != 0)) + { + quit("Error: unload_game called while dialog script still running"); + } + else if (dialogScriptsInst != nullptr) + { + delete dialogScriptsInst; + dialogScriptsInst = nullptr; + } + + dialogScriptsScript.reset(); + + for (int i = 0; i < numScriptModules; ++i) + { + delete moduleInstFork[i]; + delete moduleInst[i]; + scriptModules[i].reset(); + } + moduleInstFork.resize(0); + moduleInst.resize(0); + scriptModules.resize(0); + repExecAlways.moduleHasFunction.resize(0); + lateRepExecAlways.moduleHasFunction.resize(0); + getDialogOptionsDimensionsFunc.moduleHasFunction.resize(0); + renderDialogOptionsFunc.moduleHasFunction.resize(0); + getDialogOptionUnderCursorFunc.moduleHasFunction.resize(0); + runDialogOptionMouseClickHandlerFunc.moduleHasFunction.resize(0); + runDialogOptionKeyPressHandlerFunc.moduleHasFunction.resize(0); + runDialogOptionRepExecFunc.moduleHasFunction.resize(0); + numScriptModules = 0; + + free(views); + views = nullptr; + + free(charcache); + charcache = nullptr; + + if (splipsync != nullptr) + { + for (int i = 0; i < numLipLines; ++i) + { + free(splipsync[i].endtimeoffs); + free(splipsync[i].frame); + } + free(splipsync); + splipsync = nullptr; + numLipLines = 0; + curLipLine = -1; + } + + for (int i = 0; i < game.numdialog; ++i) + { + if (dialog[i].optionscripts != nullptr) + free(dialog[i].optionscripts); + dialog[i].optionscripts = nullptr; + } + free(dialog); + dialog = nullptr; + delete[] scrDialog; + scrDialog = nullptr; + + for (int i = 0; i < game.numgui; ++i) { + free(guibg[i]); + guibg[i] = nullptr; + } + + guiScriptObjNames.clear(); + free(guibg); + guis.clear(); + free(scrGui); + + pl_stop_plugins(); + ccRemoveAllSymbols(); + ccUnregisterAllObjects(); + + free_all_fonts(); + + free_do_once_tokens(); + free(play.gui_draw_order); + + resetRoomStatuses(); + + // free game struct last because it contains object counts + game.Free(); +} + + + + + + +const char* Game_GetGlobalStrings(int index) { + if ((index < 0) || (index >= MAXGLOBALSTRINGS)) + quit("!Game.GlobalStrings: invalid index"); + + return CreateNewScriptString(play.globalstrings[index]); +} + + + +char gamefilenamebuf[200]; + + +// ** GetGameParameter replacement functions + +int Game_GetInventoryItemCount() { + // because of the dummy item 0, this is always one higher than it should be + return game.numinvitems - 1; +} + +int Game_GetFontCount() { + return game.numfonts; +} + +int Game_GetMouseCursorCount() { + return game.numcursors; +} + +int Game_GetCharacterCount() { + return game.numcharacters; +} + +int Game_GetGUICount() { + return game.numgui; +} + +int Game_GetViewCount() { + return game.numviews; +} + +int Game_GetUseNativeCoordinates() +{ + return game.IsDataInNativeCoordinates() ? 1 : 0; +} + +int Game_GetSpriteWidth(int spriteNum) { + if (spriteNum < 0) + return 0; + + if (!spriteset.DoesSpriteExist(spriteNum)) + return 0; + + return game_to_data_coord(game.SpriteInfos[spriteNum].Width); +} + +int Game_GetSpriteHeight(int spriteNum) { + if (spriteNum < 0) + return 0; + + if (!spriteset.DoesSpriteExist(spriteNum)) + return 0; + + return game_to_data_coord(game.SpriteInfos[spriteNum].Height); +} + +int Game_GetLoopCountForView(int viewNumber) { + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); + + return views[viewNumber - 1].numLoops; +} + +int Game_GetRunNextSettingForLoop(int viewNumber, int loopNumber) { + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); + if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) + quit("!GetGameParameter: invalid loop specified"); + + return (views[viewNumber - 1].loops[loopNumber].RunNextLoop()) ? 1 : 0; +} + +int Game_GetFrameCountForLoop(int viewNumber, int loopNumber) { + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); + if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) + quit("!GetGameParameter: invalid loop specified"); + + return views[viewNumber - 1].loops[loopNumber].numFrames; +} + +ScriptViewFrame* Game_GetViewFrame(int viewNumber, int loopNumber, int frame) { + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); + if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) + quit("!GetGameParameter: invalid loop specified"); + if ((frame < 0) || (frame >= views[viewNumber - 1].loops[loopNumber].numFrames)) + quit("!GetGameParameter: invalid frame specified"); + + ScriptViewFrame *sdt = new ScriptViewFrame(viewNumber - 1, loopNumber, frame); + ccRegisterManagedObject(sdt, sdt); + return sdt; +} + +int Game_DoOnceOnly(const char *token) +{ + for (int i = 0; i < (int)play.do_once_tokens.size(); i++) + { + if (play.do_once_tokens[i] == token) + { + return 0; + } + } + play.do_once_tokens.push_back(token); + return 1; +} + +int Game_GetTextReadingSpeed() +{ + return play.text_speed; +} + +void Game_SetTextReadingSpeed(int newTextSpeed) +{ + if (newTextSpeed < 1) + quitprintf("!Game.TextReadingSpeed: %d is an invalid speed", newTextSpeed); + + play.text_speed = newTextSpeed; +} + +int Game_GetMinimumTextDisplayTimeMs() +{ + return play.text_min_display_time_ms; +} + +void Game_SetMinimumTextDisplayTimeMs(int newTextMinTime) +{ + play.text_min_display_time_ms = newTextMinTime; +} + +int Game_GetIgnoreUserInputAfterTextTimeoutMs() +{ + return play.ignore_user_input_after_text_timeout_ms; +} + +void Game_SetIgnoreUserInputAfterTextTimeoutMs(int newValueMs) +{ + play.ignore_user_input_after_text_timeout_ms = newValueMs; +} + +const char *Game_GetFileName() { + return CreateNewScriptString(ResPaths.GamePak.Name); +} + +const char *Game_GetName() { + return CreateNewScriptString(play.game_name); +} + +void Game_SetName(const char *newName) { + strncpy(play.game_name, newName, 99); + play.game_name[99] = 0; + set_window_title(play.game_name); +} + +int Game_GetSkippingCutscene() +{ + if (play.fast_forward) + { + return 1; + } + return 0; +} + +int Game_GetInSkippableCutscene() +{ + if (play.in_cutscene) + { + return 1; + } + return 0; +} + +int Game_GetColorFromRGB(int red, int grn, int blu) { + if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) || + (blu < 0) || (blu > 255)) + quit("!GetColorFromRGB: colour values must be 0-255"); + + if (game.color_depth == 1) + { + return makecol8(red, grn, blu); + } + + int agscolor = ((blu >> 3) & 0x1f); + agscolor += ((grn >> 2) & 0x3f) << 5; + agscolor += ((red >> 3) & 0x1f) << 11; + return agscolor; +} + +const char* Game_InputBox(const char *msg) { + char buffer[STD_BUFFER_SIZE]; + sc_inputbox(msg, buffer); + return CreateNewScriptString(buffer); +} + +const char* Game_GetLocationName(int x, int y) { + char buffer[STD_BUFFER_SIZE]; + GetLocationName(x, y, buffer); + return CreateNewScriptString(buffer); +} + +const char* Game_GetGlobalMessages(int index) { + if ((index < 500) || (index >= MAXGLOBALMES + 500)) { + return nullptr; + } + char buffer[STD_BUFFER_SIZE]; + buffer[0] = 0; + replace_tokens(get_translation(get_global_message(index)), buffer, STD_BUFFER_SIZE); + return CreateNewScriptString(buffer); +} + +int Game_GetSpeechFont() { + return play.speech_font; +} +int Game_GetNormalFont() { + return play.normal_font; +} + +const char* Game_GetTranslationFilename() { + char buffer[STD_BUFFER_SIZE]; + GetTranslationName(buffer); + return CreateNewScriptString(buffer); +} + +int Game_ChangeTranslation(const char *newFilename) +{ + if ((newFilename == nullptr) || (newFilename[0] == 0)) + { + close_translation(); + strcpy(transFileName, ""); + usetup.translation = ""; + return 1; + } + + String oldTransFileName; + oldTransFileName = transFileName; + + if (init_translation(newFilename, oldTransFileName.LeftSection('.'), false)) + { + usetup.translation = newFilename; + return 1; + } + else + { + strcpy(transFileName, oldTransFileName); + return 0; + } +} + +ScriptAudioClip *Game_GetAudioClip(int index) +{ + if (index < 0 || (size_t)index >= game.audioClips.size()) + return nullptr; + return &game.audioClips[index]; +} + +ScriptCamera* Game_GetCamera() +{ + return play.GetScriptCamera(0); +} + +int Game_GetCameraCount() +{ + return play.GetRoomCameraCount(); +} + +ScriptCamera* Game_GetAnyCamera(int index) +{ + return play.GetScriptCamera(index); +} + +void Game_SimulateKeyPress(int key) +{ + int platformKey = GetKeyForKeyPressCb(key); + platformKey = PlatformKeyFromAgsKey(platformKey); + if (platformKey >= 0) { + simulate_keypress(platformKey); + } +} + +//============================================================================= + +// save game functions + + + +void serialize_bitmap(const Common::Bitmap *thispic, Stream *out) { + if (thispic != nullptr) { + out->WriteInt32(thispic->GetWidth()); + out->WriteInt32(thispic->GetHeight()); + out->WriteInt32(thispic->GetColorDepth()); + for (int cc=0;ccGetHeight();cc++) + { + switch (thispic->GetColorDepth()) + { + case 8: + // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8; + // therefore 15-bit bitmaps are saved only partially? is this a bug? or? + case 15: + out->WriteArray(&thispic->GetScanLine(cc)[0], thispic->GetWidth(), 1); + break; + case 16: + out->WriteArrayOfInt16((const int16_t*)&thispic->GetScanLine(cc)[0], thispic->GetWidth()); + break; + case 32: + out->WriteArrayOfInt32((const int32_t*)&thispic->GetScanLine(cc)[0], thispic->GetWidth()); + break; + } + } + } +} + +// On Windows we could just use IIDFromString but this is platform-independant +void convert_guid_from_text_to_binary(const char *guidText, unsigned char *buffer) +{ + guidText++; // skip { + for (int bytesDone = 0; bytesDone < 16; bytesDone++) + { + if (*guidText == '-') + guidText++; + + char tempString[3]; + tempString[0] = guidText[0]; + tempString[1] = guidText[1]; + tempString[2] = 0; + int thisByte = 0; + sscanf(tempString, "%X", &thisByte); + + buffer[bytesDone] = thisByte; + guidText += 2; + } + + // Swap bytes to give correct GUID order + unsigned char temp; + temp = buffer[0]; buffer[0] = buffer[3]; buffer[3] = temp; + temp = buffer[1]; buffer[1] = buffer[2]; buffer[2] = temp; + temp = buffer[4]; buffer[4] = buffer[5]; buffer[5] = temp; + temp = buffer[6]; buffer[6] = buffer[7]; buffer[7] = temp; +} + +Bitmap *read_serialized_bitmap(Stream *in) { + Bitmap *thispic; + int picwid = in->ReadInt32(); + int pichit = in->ReadInt32(); + int piccoldep = in->ReadInt32(); + thispic = BitmapHelper::CreateBitmap(picwid,pichit,piccoldep); + if (thispic == nullptr) + return nullptr; + for (int vv=0; vv < pichit; vv++) + { + switch (piccoldep) + { + case 8: + // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8 + case 15: + in->ReadArray(thispic->GetScanLineForWriting(vv), picwid, 1); + break; + case 16: + in->ReadArrayOfInt16((int16_t*)thispic->GetScanLineForWriting(vv), picwid); + break; + case 32: + in->ReadArrayOfInt32((int32_t*)thispic->GetScanLineForWriting(vv), picwid); + break; + } + } + + return thispic; +} + +void skip_serialized_bitmap(Stream *in) +{ + int picwid = in->ReadInt32(); + int pichit = in->ReadInt32(); + int piccoldep = in->ReadInt32(); + // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8 + int bpp = piccoldep / 8; + in->Seek(picwid * pichit * bpp); +} + +long write_screen_shot_for_vista(Stream *out, Bitmap *screenshot) +{ + long fileSize = 0; + String tempFileName = String::FromFormat("%s""_tmpscht.bmp", saveGameDirectory.GetCStr()); + + screenshot->SaveToFile(tempFileName, palette); + + update_polled_stuff_if_runtime(); + + if (exists(tempFileName)) + { + fileSize = file_size_ex(tempFileName); + char *buffer = (char*)malloc(fileSize); + + Stream *temp_in = Common::File::OpenFileRead(tempFileName); + temp_in->Read(buffer, fileSize); + delete temp_in; + ::remove(tempFileName); + + out->Write(buffer, fileSize); + free(buffer); + } + return fileSize; +} + +void WriteGameSetupStructBase_Aligned(Stream *out) +{ + AlignedStream align_s(out, Common::kAligned_Write); + game.GameSetupStructBase::WriteToFile(&align_s); +} + +#define MAGICNUMBER 0xbeefcafe + +void create_savegame_screenshot(Bitmap *&screenShot) +{ + if (game.options[OPT_SAVESCREENSHOT]) { + int usewid = data_to_game_coord(play.screenshot_width); + int usehit = data_to_game_coord(play.screenshot_height); + const Rect &viewport = play.GetMainViewport(); + if (usewid > viewport.GetWidth()) + usewid = viewport.GetWidth(); + if (usehit > viewport.GetHeight()) + usehit = viewport.GetHeight(); + + if ((play.screenshot_width < 16) || (play.screenshot_height < 16)) + quit("!Invalid game.screenshot_width/height, must be from 16x16 to screen res"); + + screenShot = CopyScreenIntoBitmap(usewid, usehit); + } +} + +void save_game(int slotn, const char*descript) { + + // dont allow save in rep_exec_always, because we dont save + // the state of blocked scripts + can_run_delayed_command(); + + if (inside_script) { + strcpy(curscript->postScriptSaveSlotDescription[curscript->queue_action(ePSASaveGame, slotn, "SaveGameSlot")], descript); + return; + } + + if (platform->GetDiskFreeSpaceMB() < 2) { + Display("ERROR: There is not enough disk space free to save the game. Clear some disk space and try again."); + return; + } + + VALIDATE_STRING(descript); + String nametouse; + nametouse = get_save_game_path(slotn); + + Bitmap *screenShot = nullptr; + + // Screenshot + create_savegame_screenshot(screenShot); + + Common::PStream out = StartSavegame(nametouse, descript, screenShot); + if (out == nullptr) + quit("save_game: unable to open savegame file for writing"); + + update_polled_stuff_if_runtime(); + + // Actual dynamic game data is saved here + SaveGameState(out); + + if (screenShot != nullptr) + { + int screenShotOffset = out->GetPosition() - sizeof(RICH_GAME_MEDIA_HEADER); + int screenShotSize = write_screen_shot_for_vista(out.get(), screenShot); + + update_polled_stuff_if_runtime(); + + out.reset(Common::File::OpenFile(nametouse, Common::kFile_Open, Common::kFile_ReadWrite)); + out->Seek(12, kSeekBegin); + out->WriteInt32(screenShotOffset); + out->Seek(4); + out->WriteInt32(screenShotSize); + } + + if (screenShot != nullptr) + delete screenShot; +} + +HSaveError restore_game_head_dynamic_values(Stream *in, RestoredData &r_data) +{ + r_data.FPS = in->ReadInt32(); + r_data.CursorMode = in->ReadInt32(); + r_data.CursorID = in->ReadInt32(); + SavegameComponents::ReadLegacyCameraState(in, r_data); + set_loop_counter(in->ReadInt32()); + return HSaveError::None(); +} + +void restore_game_spriteset(Stream *in) +{ + // ensure the sprite set is at least as large as it was + // when the game was saved + spriteset.EnlargeTo(in->ReadInt32() - 1); // they saved top_index + 1 + // get serialized dynamic sprites + int sprnum = in->ReadInt32(); + while (sprnum) { + unsigned char spriteflag = in->ReadByte(); + add_dynamic_sprite(sprnum, read_serialized_bitmap(in)); + game.SpriteInfos[sprnum].Flags = spriteflag; + sprnum = in->ReadInt32(); + } +} + +HSaveError restore_game_scripts(Stream *in, const PreservedParams &pp, RestoredData &r_data) +{ + // read the global script data segment + int gdatasize = in->ReadInt32(); + if (pp.GlScDataSize != gdatasize) + { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching size of global script data."); + } + r_data.GlobalScript.Len = gdatasize; + r_data.GlobalScript.Data.reset(new char[gdatasize]); + in->Read(r_data.GlobalScript.Data.get(), gdatasize); + + if (in->ReadInt32() != numScriptModules) + { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of script modules."); + } + r_data.ScriptModules.resize(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) + { + size_t module_size = in->ReadInt32(); + if (pp.ScMdDataSize[i] != module_size) + { + return new SavegameError(kSvgErr_GameContentAssertion, String::FromFormat("Mismatching size of script module data, module %d.", i)); + } + r_data.ScriptModules[i].Len = module_size; + r_data.ScriptModules[i].Data.reset(new char[module_size]); + in->Read(r_data.ScriptModules[i].Data.get(), module_size); + } + return HSaveError::None(); +} + +void ReadRoomStatus_Aligned(RoomStatus *roomstat, Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + roomstat->ReadFromFile_v321(&align_s); +} + +void restore_game_room_state(Stream *in) +{ + int vv; + + displayed_room = in->ReadInt32(); + + // read the room state for all the rooms the player has been in + RoomStatus* roomstat; + int beenhere; + for (vv=0;vvReadByte(); + if (beenhere) + { + roomstat = getRoomStatus(vv); + roomstat->beenhere = beenhere; + + if (roomstat->beenhere) + { + ReadRoomStatus_Aligned(roomstat, in); + if (roomstat->tsdatasize > 0) + { + roomstat->tsdata=(char*)malloc(roomstat->tsdatasize + 8); // JJS: Why allocate 8 additional bytes? + in->Read(&roomstat->tsdata[0], roomstat->tsdatasize); + } + } + } + } +} + +void ReadGameState_Aligned(Stream *in, RestoredData &r_data) +{ + AlignedStream align_s(in, Common::kAligned_Read); + play.ReadFromSavegame(&align_s, kGSSvgVersion_OldFormat, r_data); +} + +void restore_game_play_ex_data(Stream *in) +{ + char rbuffer[200]; + for (size_t i = 0; i < play.do_once_tokens.size(); ++i) + { + StrUtil::ReadCStr(rbuffer, in, sizeof(rbuffer)); + play.do_once_tokens[i] = rbuffer; + } + + in->ReadArrayOfInt32(&play.gui_draw_order[0], game.numgui); +} + +void restore_game_play(Stream *in, RestoredData &r_data) +{ + int screenfadedout_was = play.screen_is_faded_out; + int roomchanges_was = play.room_changes; + // make sure the pointer is preserved + int *gui_draw_order_was = play.gui_draw_order; + + ReadGameState_Aligned(in, r_data); + r_data.Cameras[0].Flags = r_data.Camera0_Flags; + + play.screen_is_faded_out = screenfadedout_was; + play.room_changes = roomchanges_was; + play.gui_draw_order = gui_draw_order_was; + + restore_game_play_ex_data(in); +} + +void ReadMoveList_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < game.numcharacters + MAX_ROOM_OBJECTS + 1; ++i) + { + mls[i].ReadFromFile_Legacy(&align_s); + + align_s.Reset(); + } +} + +void ReadGameSetupStructBase_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + game.GameSetupStructBase::ReadFromFile(&align_s); +} + +void ReadCharacterExtras_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < game.numcharacters; ++i) + { + charextra[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void restore_game_palette(Stream *in) +{ + in->ReadArray(&palette[0],sizeof(color),256); +} + +void restore_game_dialogs(Stream *in) +{ + for (int vv=0;vvReadArrayOfInt32(&dialog[vv].optionflags[0],MAXTOPICOPTIONS); +} + +void restore_game_more_dynamic_values(Stream *in) +{ + mouse_on_iface=in->ReadInt32(); + in->ReadInt32(); // mouse_on_iface_button + in->ReadInt32(); // mouse_pushed_iface + ifacepopped = in->ReadInt32(); + game_paused=in->ReadInt32(); +} + +void ReadAnimatedButtons_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < numAnimButs; ++i) + { + animbuts[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +HSaveError restore_game_gui(Stream *in, int numGuisWas) +{ + HError err = GUI::ReadGUI(guis, in, true); + if (!err) + return new SavegameError(kSvgErr_GameObjectInitFailed, err); + game.numgui = guis.size(); + + if (numGuisWas != game.numgui) + { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of GUI."); + } + + numAnimButs = in->ReadInt32(); + ReadAnimatedButtons_Aligned(in); + return HSaveError::None(); +} + +HSaveError restore_game_audiocliptypes(Stream *in) +{ + if (in->ReadInt32() != game.audioClipTypes.size()) + { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clip Types."); + } + + for (size_t i = 0; i < game.audioClipTypes.size(); ++i) + { + game.audioClipTypes[i].ReadFromFile(in); + } + return HSaveError::None(); +} + +void restore_game_thisroom(Stream *in, RestoredData &r_data) +{ + in->ReadArrayOfInt16(r_data.RoomLightLevels, MAX_ROOM_REGIONS); + in->ReadArrayOfInt32(r_data.RoomTintLevels, MAX_ROOM_REGIONS); + in->ReadArrayOfInt16(r_data.RoomZoomLevels1, MAX_WALK_AREAS + 1); + in->ReadArrayOfInt16(r_data.RoomZoomLevels2, MAX_WALK_AREAS + 1); +} + +void restore_game_ambientsounds(Stream *in, RestoredData &r_data) +{ + for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) + { + ambient[i].ReadFromFile(in); + } + + for (int bb = 1; bb < MAX_SOUND_CHANNELS; bb++) { + if (ambient[bb].channel == 0) + r_data.DoAmbient[bb] = 0; + else { + r_data.DoAmbient[bb] = ambient[bb].num; + ambient[bb].channel = 0; + } + } +} + +void ReadOverlays_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (auto &over : screenover) + { + over.ReadFromFile(&align_s, 0); + align_s.Reset(); + } +} + +void restore_game_overlays(Stream *in) +{ + screenover.resize(in->ReadInt32()); + ReadOverlays_Aligned(in); + for (auto &over : screenover) { + if (over.hasSerializedBitmap) + over.pic = read_serialized_bitmap(in); + } +} + +void restore_game_dynamic_surfaces(Stream *in, RestoredData &r_data) +{ + // load into a temp array since ccUnserialiseObjects will destroy + // it otherwise + r_data.DynamicSurfaces.resize(MAX_DYNAMIC_SURFACES); + for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) + { + if (in->ReadInt8() == 0) + { + r_data.DynamicSurfaces[i] = nullptr; + } + else + { + r_data.DynamicSurfaces[i] = read_serialized_bitmap(in); + } + } +} + +void restore_game_displayed_room_status(Stream *in, RestoredData &r_data) +{ + int bb; + for (bb = 0; bb < MAX_ROOM_BGFRAMES; bb++) + r_data.RoomBkgScene[bb].reset(); + + if (displayed_room >= 0) { + + for (bb = 0; bb < MAX_ROOM_BGFRAMES; bb++) { + r_data.RoomBkgScene[bb] = nullptr; + if (play.raw_modified[bb]) { + r_data.RoomBkgScene[bb].reset(read_serialized_bitmap(in)); + } + } + bb = in->ReadInt32(); + + if (bb) + raw_saved_screen = read_serialized_bitmap(in); + + // get the current troom, in case they save in room 600 or whatever + ReadRoomStatus_Aligned(&troom, in); + + if (troom.tsdatasize > 0) { + troom.tsdata=(char*)malloc(troom.tsdatasize+5); + in->Read(&troom.tsdata[0],troom.tsdatasize); + } + else + troom.tsdata = nullptr; + } +} + +HSaveError restore_game_globalvars(Stream *in) +{ + if (in->ReadInt32() != numGlobalVars) + { + return new SavegameError(kSvgErr_GameContentAssertion, "Restore game error: mismatching number of Global Variables."); + } + + for (int i = 0; i < numGlobalVars; ++i) + { + globalvars[i].Read(in); + } + return HSaveError::None(); +} + +HSaveError restore_game_views(Stream *in) +{ + if (in->ReadInt32() != game.numviews) + { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Views."); + } + + for (int bb = 0; bb < game.numviews; bb++) { + for (int cc = 0; cc < views[bb].numLoops; cc++) { + for (int dd = 0; dd < views[bb].loops[cc].numFrames; dd++) + { + views[bb].loops[cc].frames[dd].sound = in->ReadInt32(); + views[bb].loops[cc].frames[dd].pic = in->ReadInt32(); + } + } + } + return HSaveError::None(); +} + +HSaveError restore_game_audioclips_and_crossfade(Stream *in, RestoredData &r_data) +{ + if (in->ReadInt32() != game.audioClips.size()) + { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clips."); + } + + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) + { + RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; + chan_info.Pos = 0; + chan_info.ClipID = in->ReadInt32(); + if (chan_info.ClipID >= 0) + { + if ((size_t)chan_info.ClipID >= game.audioClips.size()) + { + return new SavegameError(kSvgErr_GameObjectInitFailed, "Invalid audio clip index."); + } + + chan_info.Pos = in->ReadInt32(); + if (chan_info.Pos < 0) + chan_info.Pos = 0; + chan_info.Priority = in->ReadInt32(); + chan_info.Repeat = in->ReadInt32(); + chan_info.Vol = in->ReadInt32(); + chan_info.Pan = in->ReadInt32(); + chan_info.VolAsPercent = in->ReadInt32(); + chan_info.PanAsPercent = in->ReadInt32(); + chan_info.Speed = 1000; + if (loaded_game_file_version >= kGameVersion_340_2) + chan_info.Speed = in->ReadInt32(); + } + } + crossFading = in->ReadInt32(); + crossFadeVolumePerStep = in->ReadInt32(); + crossFadeStep = in->ReadInt32(); + crossFadeVolumeAtStart = in->ReadInt32(); + return HSaveError::None(); +} + +HSaveError restore_game_data(Stream *in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) +{ + int vv; + + HSaveError err = restore_game_head_dynamic_values(in, r_data); + if (!err) + return err; + restore_game_spriteset(in); + + update_polled_stuff_if_runtime(); + + err = restore_game_scripts(in, pp, r_data); + if (!err) + return err; + restore_game_room_state(in); + restore_game_play(in, r_data); + ReadMoveList_Aligned(in); + + // save pointer members before reading + char* gswas=game.globalscript; + ccScript* compsc=game.compiled_script; + CharacterInfo* chwas=game.chars; + WordsDictionary *olddict = game.dict; + char* mesbk[MAXGLOBALMES]; + int numchwas = game.numcharacters; + for (vv=0;vvReadInt32() != MAGICNUMBER+1) + { + return new SavegameError(kSvgErr_InconsistentFormat, "MAGICNUMBER not found before Audio Clips."); + } + + err = restore_game_audioclips_and_crossfade(in, r_data); + if (!err) + return err; + + auto pluginFileHandle = AGSE_RESTOREGAME; + pl_set_file_handle(pluginFileHandle, in); + pl_run_plugin_hooks(AGSE_RESTOREGAME, pluginFileHandle); + pl_clear_file_handle(); + if (in->ReadInt32() != (unsigned)MAGICNUMBER) + return new SavegameError(kSvgErr_InconsistentPlugin); + + // save the new room music vol for later use + r_data.RoomVolume = (RoomVolumeMod)in->ReadInt32(); + + if (ccUnserializeAllObjects(in, &ccUnserializer)) + { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Managed pool deserialization failed: %s.", ccErrorString.GetCStr())); + } + + // preserve legacy music type setting + current_music_type = in->ReadInt32(); + + return HSaveError::None(); +} + +int gameHasBeenRestored = 0; +int oldeip; + +bool read_savedgame_description(const String &savedgame, String &description) +{ + SavegameDescription desc; + if (OpenSavegame(savedgame, desc, kSvgDesc_UserText)) + { + description = desc.UserText; + return true; + } + return false; +} + +bool read_savedgame_screenshot(const String &savedgame, int &want_shot) +{ + want_shot = 0; + + SavegameDescription desc; + HSaveError err = OpenSavegame(savedgame, desc, kSvgDesc_UserImage); + if (!err) + return false; + + if (desc.UserImage.get()) + { + int slot = spriteset.GetFreeIndex(); + if (slot > 0) + { + // add it into the sprite set + add_dynamic_sprite(slot, ReplaceBitmapWithSupportedFormat(desc.UserImage.release())); + want_shot = slot; + } + } + return true; +} + +HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten) +{ + data_overwritten = false; + gameHasBeenRestored++; + + oldeip = our_eip; + our_eip = 2050; + + HSaveError err; + SavegameSource src; + SavegameDescription desc; + err = OpenSavegame(path, src, desc, kSvgDesc_EnvInfo); + + // saved in incompatible enviroment + if (!err) + return err; + // CHECKME: is this color depth test still essential? if yes, is there possible workaround? + else if (desc.ColorDepth != game.GetColorDepth()) + return new SavegameError(kSvgErr_DifferentColorDepth, String::FromFormat("Running: %d-bit, saved in: %d-bit.", game.GetColorDepth(), desc.ColorDepth)); + + // saved with different game file + if (Path::ComparePaths(desc.MainDataFilename, ResPaths.GamePak.Name)) + { + // [IKM] 2012-11-26: this is a workaround, indeed. + // Try to find wanted game's executable; if it does not exist, + // continue loading savedgame in current game, and pray for the best + get_install_dir_path(gamefilenamebuf, desc.MainDataFilename); + if (Common::File::TestReadFile(gamefilenamebuf)) + { + RunAGSGame (desc.MainDataFilename, 0, 0); + load_new_game_restore = slotNumber; + return HSaveError::None(); + } + Common::Debug::Printf(kDbgMsg_Warn, "WARNING: the saved game '%s' references game file '%s', but it cannot be found in the current directory. Trying to restore in the running game instead.", + path.GetCStr(), desc.MainDataFilename.GetCStr()); + } + + // do the actual restore + err = RestoreGameState(src.InputStream, src.Version); + data_overwritten = true; + if (!err) + return err; + src.InputStream.reset(); + our_eip = oldeip; + + // ensure keyboard buffer is clean + ags_clear_input_buffer(); + // call "After Restore" event callback + run_on_event(GE_RESTORE_GAME, RuntimeScriptValue().SetInt32(slotNumber)); + return HSaveError::None(); +} + +bool try_restore_save(int slot) +{ + return try_restore_save(get_save_game_path(slot), slot); +} + +bool try_restore_save(const Common::String &path, int slot) +{ + bool data_overwritten; + HSaveError err = load_game(path, slot, data_overwritten); + if (!err) + { + String error = String::FromFormat("Unable to restore the saved game.\n%s", + err->FullMessage().GetCStr()); + // currently AGS cannot properly revert to stable state if some of the + // game data was released or overwritten by the data from save file, + // this is why we tell engine to shutdown if that happened. + if (data_overwritten) + quitprintf(error); + else + Display(error); + return false; + } + return true; +} + +bool is_in_cutscene() +{ + return play.in_cutscene > 0; +} + +CutsceneSkipStyle get_cutscene_skipstyle() +{ + return static_cast(play.in_cutscene); +} + +void start_skipping_cutscene () { + play.fast_forward = 1; + // if a drop-down icon bar is up, remove it as it will pause the game + if (ifacepopped>=0) + remove_popup_interface(ifacepopped); + + // if a text message is currently displayed, remove it + if (is_text_overlay > 0) + remove_screen_overlay(OVER_TEXTMSG); + +} + +bool check_skip_cutscene_keypress (int kgn) { + + CutsceneSkipStyle skip = get_cutscene_skipstyle(); + if (skip == eSkipSceneAnyKey || skip == eSkipSceneKeyMouse || + (kgn == 27 && (skip == eSkipSceneEscOnly || skip == eSkipSceneEscOrRMB))) + { + start_skipping_cutscene(); + return true; + } + return false; +} + +bool check_skip_cutscene_mclick(int mbut) +{ + CutsceneSkipStyle skip = get_cutscene_skipstyle(); + if (skip == eSkipSceneMouse || skip == eSkipSceneKeyMouse || + (mbut == RIGHT && skip == eSkipSceneEscOrRMB)) + { + start_skipping_cutscene(); + return true; + } + return false; +} + +// Helper functions used by StartCutscene/EndCutscene, but also +// by SkipUntilCharacterStops +void initialize_skippable_cutscene() { + play.end_cutscene_music = -1; +} + +void stop_fast_forwarding() { + // when the skipping of a cutscene comes to an end, update things + play.fast_forward = 0; + setpal(); + if (play.end_cutscene_music >= 0) + newmusic(play.end_cutscene_music); + + { + AudioChannelsLock lock; + + // Restore actual volume of sounds + for (int aa = 0; aa <= MAX_SOUND_CHANNELS; aa++) + { + auto* ch = lock.GetChannelIfPlaying(aa); + if (ch) + { + ch->set_mute(false); + } + } + } // -- AudioChannelsLock + + update_music_volume(); +} + +// allowHotspot0 defines whether Hotspot 0 returns LOCTYPE_HOTSPOT +// or whether it returns 0 +int __GetLocationType(int xxx,int yyy, int allowHotspot0) { + getloctype_index = 0; + // If it's not in ProcessClick, then return 0 when over a GUI + if ((GetGUIAt(xxx, yyy) >= 0) && (getloctype_throughgui == 0)) + return 0; + + getloctype_throughgui = 0; + + const int scrx = xxx; + const int scry = yyy; + VpPoint vpt = play.ScreenToRoomDivDown(xxx, yyy); + if (vpt.second < 0) + return 0; + xxx = vpt.first.X; + yyy = vpt.first.Y; + if ((xxx>=thisroom.Width) | (xxx<0) | (yyy<0) | (yyy>=thisroom.Height)) + return 0; + + // check characters, objects and walkbehinds, work out which is + // foremost visible to the player + int charat = is_pos_on_character(xxx,yyy); + int hsat = get_hotspot_at(xxx,yyy); + int objat = GetObjectIDAtScreen(scrx, scry); + + data_to_game_coords(&xxx, &yyy); + + int wbat = thisroom.WalkBehindMask->GetPixel(xxx, yyy); + + if (wbat <= 0) wbat = 0; + else wbat = croom->walkbehind_base[wbat]; + + int winner = 0; + // if it's an Ignore Walkbehinds object, then ignore the walkbehind + if ((objat >= 0) && ((objs[objat].flags & OBJF_NOWALKBEHINDS) != 0)) + wbat = 0; + if ((charat >= 0) && ((game.chars[charat].flags & CHF_NOWALKBEHINDS) != 0)) + wbat = 0; + + if ((charat >= 0) && (objat >= 0)) { + if ((wbat > obj_lowest_yp) && (wbat > char_lowest_yp)) + winner = LOCTYPE_HOTSPOT; + else if (obj_lowest_yp > char_lowest_yp) + winner = LOCTYPE_OBJ; + else + winner = LOCTYPE_CHAR; + } + else if (charat >= 0) { + if (wbat > char_lowest_yp) + winner = LOCTYPE_HOTSPOT; + else + winner = LOCTYPE_CHAR; + } + else if (objat >= 0) { + if (wbat > obj_lowest_yp) + winner = LOCTYPE_HOTSPOT; + else + winner = LOCTYPE_OBJ; + } + + if (winner == 0) { + if (hsat >= 0) + winner = LOCTYPE_HOTSPOT; + } + + if ((winner == LOCTYPE_HOTSPOT) && (!allowHotspot0) && (hsat == 0)) + winner = 0; + + if (winner == LOCTYPE_HOTSPOT) + getloctype_index = hsat; + else if (winner == LOCTYPE_CHAR) + getloctype_index = charat; + else if (winner == LOCTYPE_OBJ) + getloctype_index = objat; + + return winner; +} + +// Called whenever game looses input focus +void display_switch_out() +{ + switched_away = true; + ags_clear_input_buffer(); + // Always unlock mouse when switching out from the game + Mouse::UnlockFromWindow(); + platform->DisplaySwitchOut(); + platform->ExitFullscreenMode(); +} + +void display_switch_out_suspend() +{ + // this is only called if in SWITCH_PAUSE mode + //debug_script_warn("display_switch_out"); + display_switch_out(); + + switching_away_from_game++; + + platform->PauseApplication(); + + // allow background running temporarily to halt the sound + if (set_display_switch_mode(SWITCH_BACKGROUND) == -1) + set_display_switch_mode(SWITCH_BACKAMNESIA); + + { + // stop the sound stuttering + AudioChannelsLock lock; + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { + auto* ch = lock.GetChannelIfPlaying(i); + if (ch) { + ch->pause(); + } + } + } // -- AudioChannelsLock + + platform->Delay(1000); + + // restore the callbacks + SetMultitasking(0); + + switching_away_from_game--; +} + +// Called whenever game gets input focus +void display_switch_in() +{ + switched_away = false; + if (gfxDriver) + { + DisplayMode mode = gfxDriver->GetDisplayMode(); + if (!mode.Windowed) + platform->EnterFullscreenMode(mode); + } + platform->DisplaySwitchIn(); + ags_clear_input_buffer(); + // If auto lock option is set, lock mouse to the game window + if (usetup.mouse_auto_lock && scsystem.windowed) + Mouse::TryLockToWindow(); +} + +void display_switch_in_resume() +{ + display_switch_in(); + + { + AudioChannelsLock lock; + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { + auto* ch = lock.GetChannelIfPlaying(i); + if (ch) { + ch->resume(); + } + } + } // -- AudioChannelsLock + + // clear the screen if necessary + if (gfxDriver && gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->ClearRectangle(0, 0, game.GetGameRes().Width - 1, game.GetGameRes().Height - 1, nullptr); + + platform->ResumeApplication(); +} + +void replace_tokens(const char*srcmes,char*destm, int maxlen) { + int indxdest=0,indxsrc=0; + const char*srcp; + char *destp; + while (srcmes[indxsrc]!=0) { + srcp=&srcmes[indxsrc]; + destp=&destm[indxdest]; + if ((strncmp(srcp,"@IN",3)==0) | (strncmp(srcp,"@GI",3)==0)) { + int tokentype=0; + if (srcp[1]=='I') tokentype=1; + else tokentype=2; + int inx=atoi(&srcp[3]); + srcp++; + indxsrc+=2; + while (srcp[0]!='@') { + if (srcp[0]==0) quit("!Display: special token not terminated"); + srcp++; + indxsrc++; + } + char tval[10]; + if (tokentype==1) { + if ((inx<1) | (inx>=game.numinvitems)) + quit("!Display: invalid inv item specified in @IN@"); + snprintf(tval,sizeof(tval),"%d",playerchar->inv[inx]); + } + else { + if ((inx<0) | (inx>=MAXGSVALUES)) + quit("!Display: invalid global int index speicifed in @GI@"); + snprintf(tval,sizeof(tval),"%d",GetGlobalInt(inx)); + } + strcpy(destp,tval); + indxdest+=strlen(tval); + } + else { + destp[0]=srcp[0]; + indxdest++; + indxsrc++; + } + if (indxdest >= maxlen - 3) + break; + } + destm[indxdest]=0; +} + +const char *get_global_message (int msnum) { + if (game.messages[msnum-500] == nullptr) + return ""; + return get_translation(game.messages[msnum-500]); +} + +void get_message_text (int msnum, char *buffer, char giveErr) { + int maxlen = 9999; + if (!giveErr) + maxlen = MAX_MAXSTRLEN; + + if (msnum>=500) { + + if ((msnum >= MAXGLOBALMES + 500) || (game.messages[msnum-500]==nullptr)) { + if (giveErr) + quit("!DisplayGlobalMessage: message does not exist"); + buffer[0] = 0; + return; + } + buffer[0] = 0; + replace_tokens(get_translation(game.messages[msnum-500]), buffer, maxlen); + return; + } + else if (msnum < 0 || (size_t)msnum >= thisroom.MessageCount) { + if (giveErr) + quit("!DisplayMessage: Invalid message number to display"); + buffer[0] = 0; + return; + } + + buffer[0]=0; + replace_tokens(get_translation(thisroom.Messages[msnum]), buffer, maxlen); +} + +bool unserialize_audio_script_object(int index, const char *objectType, const char *serializedData, int dataSize) +{ + if (strcmp(objectType, "AudioChannel") == 0) + { + ccDynamicAudio.Unserialize(index, serializedData, dataSize); + } + else if (strcmp(objectType, "AudioClip") == 0) + { + ccDynamicAudioClip.Unserialize(index, serializedData, dataSize); + } + else + { + return false; + } + return true; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// int (int audioType); +RuntimeScriptValue Sc_Game_IsAudioPlaying(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(Game_IsAudioPlaying); +} + +// void (int audioType, int volumeDrop) +RuntimeScriptValue Sc_Game_SetAudioTypeSpeechVolumeDrop(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(Game_SetAudioTypeSpeechVolumeDrop); +} + +// void (int audioType, int volume, int changeType) +RuntimeScriptValue Sc_Game_SetAudioTypeVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(Game_SetAudioTypeVolume); +} + +// void (int audioType) +RuntimeScriptValue Sc_Game_StopAudio(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(Game_StopAudio); +} + +// int (const char *newFilename) +RuntimeScriptValue Sc_Game_ChangeTranslation(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(Game_ChangeTranslation, const char); +} + +// int (const char *token) +RuntimeScriptValue Sc_Game_DoOnceOnly(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(Game_DoOnceOnly, const char); +} + +// int (int red, int grn, int blu) +RuntimeScriptValue Sc_Game_GetColorFromRGB(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT3(Game_GetColorFromRGB); +} + +// int (int viewNumber, int loopNumber) +RuntimeScriptValue Sc_Game_GetFrameCountForLoop(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(Game_GetFrameCountForLoop); +} + +// const char* (int x, int y) +RuntimeScriptValue Sc_Game_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(const char, myScriptStringImpl, Game_GetLocationName); +} + +// int (int viewNumber) +RuntimeScriptValue Sc_Game_GetLoopCountForView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(Game_GetLoopCountForView); +} + +// int () +RuntimeScriptValue Sc_Game_GetMODPattern(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetMODPattern); +} + +// int (int viewNumber, int loopNumber) +RuntimeScriptValue Sc_Game_GetRunNextSettingForLoop(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(Game_GetRunNextSettingForLoop); +} + +// const char* (int slnum) +RuntimeScriptValue Sc_Game_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetSaveSlotDescription); +} + +// ScriptViewFrame* (int viewNumber, int loopNumber, int frame) +RuntimeScriptValue Sc_Game_GetViewFrame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT3(ScriptViewFrame, Game_GetViewFrame); +} + +// const char* (const char *msg) +RuntimeScriptValue Sc_Game_InputBox(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Game_InputBox, const char); +} + +// int (const char *newFolder) +RuntimeScriptValue Sc_Game_SetSaveGameDirectory(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(Game_SetSaveGameDirectory, const char); +} + +// void (int evenAmbient); +RuntimeScriptValue Sc_StopAllSounds(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(StopAllSounds); +} + +// int () +RuntimeScriptValue Sc_Game_GetCharacterCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetCharacterCount); +} + +// int () +RuntimeScriptValue Sc_Game_GetDialogCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetDialogCount); +} + +// const char *() +RuntimeScriptValue Sc_Game_GetFileName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetFileName); +} + +// int () +RuntimeScriptValue Sc_Game_GetFontCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetFontCount); +} + +// const char* (int index) +RuntimeScriptValue Sc_Game_GetGlobalMessages(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalMessages); +} + +// const char* (int index) +RuntimeScriptValue Sc_Game_GetGlobalStrings(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalStrings); +} + +// void (int index, char *newval); +RuntimeScriptValue Sc_SetGlobalString(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(SetGlobalString, const char); +} + +// int () +RuntimeScriptValue Sc_Game_GetGUICount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetGUICount); +} + +// int () +RuntimeScriptValue Sc_Game_GetIgnoreUserInputAfterTextTimeoutMs(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetIgnoreUserInputAfterTextTimeoutMs); +} + +// void (int newValueMs) +RuntimeScriptValue Sc_Game_SetIgnoreUserInputAfterTextTimeoutMs(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(Game_SetIgnoreUserInputAfterTextTimeoutMs); +} + +// int () +RuntimeScriptValue Sc_Game_GetInSkippableCutscene(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetInSkippableCutscene); +} + +// int () +RuntimeScriptValue Sc_Game_GetInventoryItemCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetInventoryItemCount); +} + +// int () +RuntimeScriptValue Sc_Game_GetMinimumTextDisplayTimeMs(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetMinimumTextDisplayTimeMs); +} + +// void (int newTextMinTime) +RuntimeScriptValue Sc_Game_SetMinimumTextDisplayTimeMs(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(Game_SetMinimumTextDisplayTimeMs); +} + +// int () +RuntimeScriptValue Sc_Game_GetMouseCursorCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetMouseCursorCount); +} + +// const char *() +RuntimeScriptValue Sc_Game_GetName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetName); +} + +// void (const char *newName) +RuntimeScriptValue Sc_Game_SetName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_POBJ(Game_SetName, const char); +} + +// int () +RuntimeScriptValue Sc_Game_GetNormalFont(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetNormalFont); +} + +// void (int fontnum); +RuntimeScriptValue Sc_SetNormalFont(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetNormalFont); +} + +// int () +RuntimeScriptValue Sc_Game_GetSkippingCutscene(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetSkippingCutscene); +} + +// int () +RuntimeScriptValue Sc_Game_GetSpeechFont(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetSpeechFont); +} + +// void (int fontnum); +RuntimeScriptValue Sc_SetSpeechFont(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetSpeechFont); +} + +// int (int spriteNum) +RuntimeScriptValue Sc_Game_GetSpriteWidth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(Game_GetSpriteWidth); +} + +// int (int spriteNum) +RuntimeScriptValue Sc_Game_GetSpriteHeight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(Game_GetSpriteHeight); +} + +// int () +RuntimeScriptValue Sc_Game_GetTextReadingSpeed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetTextReadingSpeed); +} + +// void (int newTextSpeed) +RuntimeScriptValue Sc_Game_SetTextReadingSpeed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(Game_SetTextReadingSpeed); +} + +// const char* () +RuntimeScriptValue Sc_Game_GetTranslationFilename(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetTranslationFilename); +} + +// int () +RuntimeScriptValue Sc_Game_GetUseNativeCoordinates(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetUseNativeCoordinates); +} + +// int () +RuntimeScriptValue Sc_Game_GetViewCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetViewCount); +} + +RuntimeScriptValue Sc_Game_GetAudioClipCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(game.audioClips.size()); +} + +RuntimeScriptValue Sc_Game_GetAudioClip(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT(ScriptAudioClip, ccDynamicAudioClip, Game_GetAudioClip); +} + +RuntimeScriptValue Sc_Game_IsPluginLoaded(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_BOOL_OBJ(pl_is_plugin_loaded, const char); +} + +RuntimeScriptValue Sc_Game_PlayVoiceClip(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_POBJ_PINT_PBOOL(ScriptAudioChannel, ccDynamicAudio, PlayVoiceClip, CharacterInfo); +} + +RuntimeScriptValue Sc_Game_GetCamera(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO(ScriptCamera, Game_GetCamera); +} + +RuntimeScriptValue Sc_Game_GetCameraCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Game_GetCameraCount); +} + +RuntimeScriptValue Sc_Game_GetAnyCamera(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT(ScriptCamera, Game_GetAnyCamera); +} + +RuntimeScriptValue Sc_Game_SimulateKeyPress(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(Game_SimulateKeyPress); +} + +void RegisterGameAPI() +{ + ccAddExternalStaticFunction("Game::IsAudioPlaying^1", Sc_Game_IsAudioPlaying); + ccAddExternalStaticFunction("Game::SetAudioTypeSpeechVolumeDrop^2", Sc_Game_SetAudioTypeSpeechVolumeDrop); + ccAddExternalStaticFunction("Game::SetAudioTypeVolume^3", Sc_Game_SetAudioTypeVolume); + ccAddExternalStaticFunction("Game::StopAudio^1", Sc_Game_StopAudio); + ccAddExternalStaticFunction("Game::ChangeTranslation^1", Sc_Game_ChangeTranslation); + ccAddExternalStaticFunction("Game::DoOnceOnly^1", Sc_Game_DoOnceOnly); + ccAddExternalStaticFunction("Game::GetColorFromRGB^3", Sc_Game_GetColorFromRGB); + ccAddExternalStaticFunction("Game::GetFrameCountForLoop^2", Sc_Game_GetFrameCountForLoop); + ccAddExternalStaticFunction("Game::GetLocationName^2", Sc_Game_GetLocationName); + ccAddExternalStaticFunction("Game::GetLoopCountForView^1", Sc_Game_GetLoopCountForView); + ccAddExternalStaticFunction("Game::GetMODPattern^0", Sc_Game_GetMODPattern); + ccAddExternalStaticFunction("Game::GetRunNextSettingForLoop^2", Sc_Game_GetRunNextSettingForLoop); + ccAddExternalStaticFunction("Game::GetSaveSlotDescription^1", Sc_Game_GetSaveSlotDescription); + ccAddExternalStaticFunction("Game::GetViewFrame^3", Sc_Game_GetViewFrame); + ccAddExternalStaticFunction("Game::InputBox^1", Sc_Game_InputBox); + ccAddExternalStaticFunction("Game::SetSaveGameDirectory^1", Sc_Game_SetSaveGameDirectory); + ccAddExternalStaticFunction("Game::StopSound^1", Sc_StopAllSounds); + ccAddExternalStaticFunction("Game::get_CharacterCount", Sc_Game_GetCharacterCount); + ccAddExternalStaticFunction("Game::get_DialogCount", Sc_Game_GetDialogCount); + ccAddExternalStaticFunction("Game::get_FileName", Sc_Game_GetFileName); + ccAddExternalStaticFunction("Game::get_FontCount", Sc_Game_GetFontCount); + ccAddExternalStaticFunction("Game::geti_GlobalMessages", Sc_Game_GetGlobalMessages); + ccAddExternalStaticFunction("Game::geti_GlobalStrings", Sc_Game_GetGlobalStrings); + ccAddExternalStaticFunction("Game::seti_GlobalStrings", Sc_SetGlobalString); + ccAddExternalStaticFunction("Game::get_GUICount", Sc_Game_GetGUICount); + ccAddExternalStaticFunction("Game::get_IgnoreUserInputAfterTextTimeoutMs", Sc_Game_GetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalStaticFunction("Game::set_IgnoreUserInputAfterTextTimeoutMs", Sc_Game_SetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalStaticFunction("Game::get_InSkippableCutscene", Sc_Game_GetInSkippableCutscene); + ccAddExternalStaticFunction("Game::get_InventoryItemCount", Sc_Game_GetInventoryItemCount); + ccAddExternalStaticFunction("Game::get_MinimumTextDisplayTimeMs", Sc_Game_GetMinimumTextDisplayTimeMs); + ccAddExternalStaticFunction("Game::set_MinimumTextDisplayTimeMs", Sc_Game_SetMinimumTextDisplayTimeMs); + ccAddExternalStaticFunction("Game::get_MouseCursorCount", Sc_Game_GetMouseCursorCount); + ccAddExternalStaticFunction("Game::get_Name", Sc_Game_GetName); + ccAddExternalStaticFunction("Game::set_Name", Sc_Game_SetName); + ccAddExternalStaticFunction("Game::get_NormalFont", Sc_Game_GetNormalFont); + ccAddExternalStaticFunction("Game::set_NormalFont", Sc_SetNormalFont); + ccAddExternalStaticFunction("Game::get_SkippingCutscene", Sc_Game_GetSkippingCutscene); + ccAddExternalStaticFunction("Game::get_SpeechFont", Sc_Game_GetSpeechFont); + ccAddExternalStaticFunction("Game::set_SpeechFont", Sc_SetSpeechFont); + ccAddExternalStaticFunction("Game::geti_SpriteWidth", Sc_Game_GetSpriteWidth); + ccAddExternalStaticFunction("Game::geti_SpriteHeight", Sc_Game_GetSpriteHeight); + ccAddExternalStaticFunction("Game::get_TextReadingSpeed", Sc_Game_GetTextReadingSpeed); + ccAddExternalStaticFunction("Game::set_TextReadingSpeed", Sc_Game_SetTextReadingSpeed); + ccAddExternalStaticFunction("Game::get_TranslationFilename", Sc_Game_GetTranslationFilename); + ccAddExternalStaticFunction("Game::get_UseNativeCoordinates", Sc_Game_GetUseNativeCoordinates); + ccAddExternalStaticFunction("Game::get_ViewCount", Sc_Game_GetViewCount); + ccAddExternalStaticFunction("Game::get_AudioClipCount", Sc_Game_GetAudioClipCount); + ccAddExternalStaticFunction("Game::geti_AudioClips", Sc_Game_GetAudioClip); + ccAddExternalStaticFunction("Game::IsPluginLoaded", Sc_Game_IsPluginLoaded); + ccAddExternalStaticFunction("Game::PlayVoiceClip", Sc_Game_PlayVoiceClip); + ccAddExternalStaticFunction("Game::SimulateKeyPress", Sc_Game_SimulateKeyPress); + + ccAddExternalStaticFunction("Game::get_Camera", Sc_Game_GetCamera); + ccAddExternalStaticFunction("Game::get_CameraCount", Sc_Game_GetCameraCount); + ccAddExternalStaticFunction("Game::geti_Cameras", Sc_Game_GetAnyCamera); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Game::IsAudioPlaying^1", (void*)Game_IsAudioPlaying); + ccAddExternalFunctionForPlugin("Game::SetAudioTypeSpeechVolumeDrop^2", (void*)Game_SetAudioTypeSpeechVolumeDrop); + ccAddExternalFunctionForPlugin("Game::SetAudioTypeVolume^3", (void*)Game_SetAudioTypeVolume); + ccAddExternalFunctionForPlugin("Game::StopAudio^1", (void*)Game_StopAudio); + ccAddExternalFunctionForPlugin("Game::ChangeTranslation^1", (void*)Game_ChangeTranslation); + ccAddExternalFunctionForPlugin("Game::DoOnceOnly^1", (void*)Game_DoOnceOnly); + ccAddExternalFunctionForPlugin("Game::GetColorFromRGB^3", (void*)Game_GetColorFromRGB); + ccAddExternalFunctionForPlugin("Game::GetFrameCountForLoop^2", (void*)Game_GetFrameCountForLoop); + ccAddExternalFunctionForPlugin("Game::GetLocationName^2", (void*)Game_GetLocationName); + ccAddExternalFunctionForPlugin("Game::GetLoopCountForView^1", (void*)Game_GetLoopCountForView); + ccAddExternalFunctionForPlugin("Game::GetMODPattern^0", (void*)Game_GetMODPattern); + ccAddExternalFunctionForPlugin("Game::GetRunNextSettingForLoop^2", (void*)Game_GetRunNextSettingForLoop); + ccAddExternalFunctionForPlugin("Game::GetSaveSlotDescription^1", (void*)Game_GetSaveSlotDescription); + ccAddExternalFunctionForPlugin("Game::GetViewFrame^3", (void*)Game_GetViewFrame); + ccAddExternalFunctionForPlugin("Game::InputBox^1", (void*)Game_InputBox); + ccAddExternalFunctionForPlugin("Game::SetSaveGameDirectory^1", (void*)Game_SetSaveGameDirectory); + ccAddExternalFunctionForPlugin("Game::StopSound^1", (void*)StopAllSounds); + ccAddExternalFunctionForPlugin("Game::get_CharacterCount", (void*)Game_GetCharacterCount); + ccAddExternalFunctionForPlugin("Game::get_DialogCount", (void*)Game_GetDialogCount); + ccAddExternalFunctionForPlugin("Game::get_FileName", (void*)Game_GetFileName); + ccAddExternalFunctionForPlugin("Game::get_FontCount", (void*)Game_GetFontCount); + ccAddExternalFunctionForPlugin("Game::geti_GlobalMessages", (void*)Game_GetGlobalMessages); + ccAddExternalFunctionForPlugin("Game::geti_GlobalStrings", (void*)Game_GetGlobalStrings); + ccAddExternalFunctionForPlugin("Game::seti_GlobalStrings", (void*)SetGlobalString); + ccAddExternalFunctionForPlugin("Game::get_GUICount", (void*)Game_GetGUICount); + ccAddExternalFunctionForPlugin("Game::get_IgnoreUserInputAfterTextTimeoutMs", (void*)Game_GetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalFunctionForPlugin("Game::set_IgnoreUserInputAfterTextTimeoutMs", (void*)Game_SetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalFunctionForPlugin("Game::get_InSkippableCutscene", (void*)Game_GetInSkippableCutscene); + ccAddExternalFunctionForPlugin("Game::get_InventoryItemCount", (void*)Game_GetInventoryItemCount); + ccAddExternalFunctionForPlugin("Game::get_MinimumTextDisplayTimeMs", (void*)Game_GetMinimumTextDisplayTimeMs); + ccAddExternalFunctionForPlugin("Game::set_MinimumTextDisplayTimeMs", (void*)Game_SetMinimumTextDisplayTimeMs); + ccAddExternalFunctionForPlugin("Game::get_MouseCursorCount", (void*)Game_GetMouseCursorCount); + ccAddExternalFunctionForPlugin("Game::get_Name", (void*)Game_GetName); + ccAddExternalFunctionForPlugin("Game::set_Name", (void*)Game_SetName); + ccAddExternalFunctionForPlugin("Game::get_NormalFont", (void*)Game_GetNormalFont); + ccAddExternalFunctionForPlugin("Game::set_NormalFont", (void*)SetNormalFont); + ccAddExternalFunctionForPlugin("Game::get_SkippingCutscene", (void*)Game_GetSkippingCutscene); + ccAddExternalFunctionForPlugin("Game::get_SpeechFont", (void*)Game_GetSpeechFont); + ccAddExternalFunctionForPlugin("Game::set_SpeechFont", (void*)SetSpeechFont); + ccAddExternalFunctionForPlugin("Game::geti_SpriteWidth", (void*)Game_GetSpriteWidth); + ccAddExternalFunctionForPlugin("Game::geti_SpriteHeight", (void*)Game_GetSpriteHeight); + ccAddExternalFunctionForPlugin("Game::get_TextReadingSpeed", (void*)Game_GetTextReadingSpeed); + ccAddExternalFunctionForPlugin("Game::set_TextReadingSpeed", (void*)Game_SetTextReadingSpeed); + ccAddExternalFunctionForPlugin("Game::get_TranslationFilename", (void*)Game_GetTranslationFilename); + ccAddExternalFunctionForPlugin("Game::get_UseNativeCoordinates", (void*)Game_GetUseNativeCoordinates); + ccAddExternalFunctionForPlugin("Game::get_ViewCount", (void*)Game_GetViewCount); + ccAddExternalFunctionForPlugin("Game::PlayVoiceClip", (void*)PlayVoiceClip); +} + +void RegisterStaticObjects() +{ + ccAddExternalStaticObject("game",&play, &GameStaticManager); + ccAddExternalStaticObject("gs_globals",&play.globalvars[0], &GlobalStaticManager); + ccAddExternalStaticObject("mouse",&scmouse, &GlobalStaticManager); + ccAddExternalStaticObject("palette",&palette[0], &GlobalStaticManager); + ccAddExternalStaticObject("system",&scsystem, &GlobalStaticManager); + ccAddExternalStaticObject("savegameindex",&play.filenumbers[0], &GlobalStaticManager); +} diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h new file mode 100644 index 000000000000..9bed7f02c217 --- /dev/null +++ b/engines/ags/engine/ac/game.h @@ -0,0 +1,192 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS Runtime header +// +//============================================================================= + +#ifndef __AGS_EE_AC__GAME_H +#define __AGS_EE_AC__GAME_H + +#include "ac/dynobj/scriptviewframe.h" +#include "main/game_file.h" +#include "util/string.h" + +// Forward declaration +namespace AGS { namespace Common { class Bitmap; class Stream; } } +using namespace AGS; // FIXME later + +#define RAGMODE_PRESERVEGLOBALINT 1 +#define RAGMODE_LOADNOW 0x8000000 // just to make sure it's non-zero + +// Game parameter constants for backward-compatibility functions +#define GP_SPRITEWIDTH 1 +#define GP_SPRITEHEIGHT 2 +#define GP_NUMLOOPS 3 +#define GP_NUMFRAMES 4 +#define GP_ISRUNNEXTLOOP 5 +#define GP_FRAMESPEED 6 +#define GP_FRAMEIMAGE 7 +#define GP_FRAMESOUND 8 +#define GP_NUMGUIS 9 +#define GP_NUMOBJECTS 10 +#define GP_NUMCHARACTERS 11 +#define GP_NUMINVITEMS 12 +#define GP_ISFRAMEFLIPPED 13 + +enum CutsceneSkipStyle +{ + kSkipSceneUndefined = 0, + eSkipSceneEscOnly = 1, + eSkipSceneAnyKey = 2, + eSkipSceneMouse = 3, + eSkipSceneKeyMouse = 4, + eSkipSceneEscOrRMB = 5, + eSkipSceneScriptOnly = 6 +}; + +//============================================================================= +// Audio +//============================================================================= +#define VOL_CHANGEEXISTING 1678 +#define VOL_SETFUTUREDEFAULT 1679 +#define VOL_BOTH 1680 + +void Game_StopAudio(int audioType); +int Game_IsAudioPlaying(int audioType); +void Game_SetAudioTypeSpeechVolumeDrop(int audioType, int volumeDrop); +void Game_SetAudioTypeVolume(int audioType, int volume, int changeType); + +int Game_GetMODPattern(); + +//============================================================================= +// --- +//============================================================================= +int Game_GetDialogCount(); + +// Defines a custom save parent directory, which will replace $MYDOCS$/GameName +// when a new save directory is set from the script +bool SetCustomSaveParent(const Common::String &path); +// If explicit_path flag is false, the actual path will be constructed +// as a relative to system's user saves directory +bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path = false); +int Game_SetSaveGameDirectory(const char *newFolder); +const char* Game_GetSaveSlotDescription(int slnum); + +const char* Game_GetGlobalStrings(int index); + +int Game_GetInventoryItemCount(); +int Game_GetFontCount(); +int Game_GetMouseCursorCount(); +int Game_GetCharacterCount(); +int Game_GetGUICount(); +int Game_GetViewCount(); +int Game_GetUseNativeCoordinates(); +int Game_GetSpriteWidth(int spriteNum); +int Game_GetSpriteHeight(int spriteNum); +int Game_GetLoopCountForView(int viewNumber); +int Game_GetRunNextSettingForLoop(int viewNumber, int loopNumber); +int Game_GetFrameCountForLoop(int viewNumber, int loopNumber); +ScriptViewFrame* Game_GetViewFrame(int viewNumber, int loopNumber, int frame); +int Game_DoOnceOnly(const char *token); + +int Game_GetTextReadingSpeed(); +void Game_SetTextReadingSpeed(int newTextSpeed); +int Game_GetMinimumTextDisplayTimeMs(); +void Game_SetMinimumTextDisplayTimeMs(int newTextMinTime); +int Game_GetIgnoreUserInputAfterTextTimeoutMs(); +void Game_SetIgnoreUserInputAfterTextTimeoutMs(int newValueMs); +const char *Game_GetFileName(); +const char *Game_GetName(); +void Game_SetName(const char *newName); + +int Game_GetSkippingCutscene(); +int Game_GetInSkippableCutscene(); + +int Game_GetColorFromRGB(int red, int grn, int blu); +const char* Game_InputBox(const char *msg); +const char* Game_GetLocationName(int x, int y); + +const char* Game_GetGlobalMessages(int index); + +int Game_GetSpeechFont(); +int Game_GetNormalFont(); + +const char* Game_GetTranslationFilename(); +int Game_ChangeTranslation(const char *newFilename); + +//============================================================================= + +void set_debug_mode(bool on); +void set_game_speed(int new_fps); +void setup_for_dialog(); +void restore_after_dialog(); +Common::String get_save_game_directory(); +Common::String get_save_game_suffix(); +void set_save_game_suffix(const Common::String &suffix); +Common::String get_save_game_path(int slotNum); +void restore_game_dialog(); +void save_game_dialog(); +void free_do_once_tokens(); +// Free all the memory associated with the game +void unload_game_file(); +void save_game(int slotn, const char*descript); +bool read_savedgame_description(const Common::String &savedgame, Common::String &description); +bool read_savedgame_screenshot(const Common::String &savedgame, int &want_shot); +// Tries to restore saved game and displays an error on failure; if the error occured +// too late, when the game data was already overwritten, shuts engine down. +bool try_restore_save(int slot); +bool try_restore_save(const Common::String &path, int slot); +void serialize_bitmap(const Common::Bitmap *thispic, Common::Stream *out); +// On Windows we could just use IIDFromString but this is platform-independant +void convert_guid_from_text_to_binary(const char *guidText, unsigned char *buffer); +Common::Bitmap *read_serialized_bitmap(Common::Stream *in); +void skip_serialized_bitmap(Common::Stream *in); +long write_screen_shot_for_vista(Common::Stream *out, Common::Bitmap *screenshot); + +bool is_in_cutscene(); +CutsceneSkipStyle get_cutscene_skipstyle(); +void start_skipping_cutscene (); +bool check_skip_cutscene_keypress(int kgn); +bool check_skip_cutscene_mclick(int mbut); +void initialize_skippable_cutscene(); +void stop_fast_forwarding(); + +int __GetLocationType(int xxx,int yyy, int allowHotspot0); + +// Called whenever game looses input focus +void display_switch_out(); +// Called whenever game gets input focus +void display_switch_in(); +// Called when the game looses input focus and must suspend +void display_switch_out_suspend(); +// Called when the game gets input focus and should resume +void display_switch_in_resume(); + +void replace_tokens(const char*srcmes,char*destm, int maxlen = 99999); +const char *get_global_message (int msnum); +void get_message_text (int msnum, char *buffer, char giveErr = 1); + +bool unserialize_audio_script_object(int index, const char *objectType, const char *serializedData, int dataSize); + +extern int in_new_room; +extern int new_room_pos; +extern int new_room_x, new_room_y, new_room_loop; +extern int displayed_room; +extern int frames_per_second; // fixed game fps, set by script +extern unsigned int loopcounter; +extern void set_loop_counter(unsigned int new_counter); +extern int game_paused; + +#endif // __AGS_EE_AC__GAME_H diff --git a/engines/ags/engine/ac/gamesetup.cpp b/engines/ags/engine/ac/gamesetup.cpp new file mode 100644 index 000000000000..88a22f4fceee --- /dev/null +++ b/engines/ags/engine/ac/gamesetup.cpp @@ -0,0 +1,45 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/wgt2allg.h" // DIGI_AUTODETECT & MIDI_AUTODETECT +#include "ac/gamesetup.h" + +GameSetup::GameSetup() +{ + digicard=DIGI_AUTODETECT; + midicard=MIDI_AUTODETECT; + mod_player=1; + no_speech_pack = false; + textheight = 0; + enable_antialiasing = false; + disable_exception_handling = false; + mouse_auto_lock = false; + override_script_os = -1; + override_multitasking = -1; + override_upscale = false; + mouse_speed = 1.f; + mouse_ctrl_when = kMouseCtrl_Fullscreen; + mouse_ctrl_enabled = true; + mouse_speed_def = kMouseSpeed_CurrentDisplay; + RenderAtScreenRes = false; + Supersampling = 1; + + Screen.DisplayMode.ScreenSize.MatchDeviceRatio = true; + Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_MaxDisplay; + Screen.DisplayMode.RefreshRate = 0; + Screen.DisplayMode.VSync = false; + Screen.DisplayMode.Windowed = false; + Screen.FsGameFrame = GameFrameSetup(kFrame_MaxProportional); + Screen.WinGameFrame = GameFrameSetup(kFrame_MaxRound); +} diff --git a/engines/ags/engine/ac/gamesetup.h b/engines/ags/engine/ac/gamesetup.h new file mode 100644 index 000000000000..672eb66d9124 --- /dev/null +++ b/engines/ags/engine/ac/gamesetup.h @@ -0,0 +1,86 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GAMESETUP_H +#define __AC_GAMESETUP_H + +#include "main/graphics_mode.h" +#include "util/string.h" + + +// Mouse control activation type +enum MouseControlWhen +{ + kMouseCtrl_Never, // never control mouse (track system mouse position) + kMouseCtrl_Fullscreen, // control mouse in fullscreen only + kMouseCtrl_Always, // always control mouse (fullscreen and windowed) + kNumMouseCtrlOptions +}; + +// Mouse speed definition, specifies how the speed setting is applied to the mouse movement +enum MouseSpeedDef +{ + kMouseSpeed_Absolute, // apply speed multiplier directly + kMouseSpeed_CurrentDisplay, // keep speed/resolution relation based on current system display mode + kNumMouseSpeedDefs +}; + +using AGS::Common::String; + +// TODO: reconsider the purpose of this struct. +// Earlier I was trying to remove the uses of this struct from the engine +// and restrict it to only config/init stage, while applying its values to +// respective game/engine subcomponents at init stage. +// However, it did not work well at all times, and consequently I thought +// that engine may use a "config" object or combo of objects to store +// current user config, which may also be changed from script, and saved. +struct GameSetup { + int digicard; + int midicard; + int mod_player; + int textheight; // text height used on the certain built-in GUI // TODO: move out to game class? + bool no_speech_pack; + bool enable_antialiasing; + bool disable_exception_handling; + String data_files_dir; + String main_data_filename; + String main_data_filepath; + String install_dir; // optional custom install dir path + String install_audio_dir; // optional custom install audio dir path + String install_voice_dir; // optional custom install voice-over dir path + String user_data_dir; // directory to write savedgames and user files to + String shared_data_dir; // directory to write shared game files to + String translation; + bool mouse_auto_lock; + int override_script_os; + char override_multitasking; + bool override_upscale; + float mouse_speed; + MouseControlWhen mouse_ctrl_when; + bool mouse_ctrl_enabled; + MouseSpeedDef mouse_speed_def; + bool RenderAtScreenRes; // render sprites at screen resolution, as opposed to native one + int Supersampling; + + ScreenSetup Screen; + + GameSetup(); +}; + +// TODO: setup object is used for two purposes: temporarily storing config +// options before engine is initialized, and storing certain runtime variables. +// Perhaps it makes sense to separate those two group of vars at some point. +extern GameSetup usetup; + +#endif // __AC_GAMESETUP_H \ No newline at end of file diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp new file mode 100644 index 000000000000..da4ec8079da4 --- /dev/null +++ b/engines/ags/engine/ac/gamestate.cpp @@ -0,0 +1,935 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include +#include "ac/draw.h" +#include "ac/game_version.h" +#include "ac/gamestate.h" +#include "ac/gamesetupstruct.h" +#include "ac/timer.h" +#include "ac/dynobj/scriptcamera.h" +#include "ac/dynobj/scriptsystem.h" +#include "ac/dynobj/scriptviewport.h" +#include "debug/debug_log.h" +#include "device/mousew32.h" +#include "game/customproperties.h" +#include "game/roomstruct.h" +#include "game/savegame_internal.h" +#include "main/engine.h" +#include "media/audio/audio_system.h" +#include "util/alignedstream.h" +#include "util/string_utils.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern RoomStruct thisroom; +extern CharacterInfo *playerchar; +extern ScriptSystem scsystem; + +GameState::GameState() +{ + _isAutoRoomViewport = true; + _mainViewportHasChanged = false; +} + +void GameState::Free() +{ + raw_drawing_surface.reset(); + FreeProperties(); +} + +bool GameState::IsAutoRoomViewport() const +{ + return _isAutoRoomViewport; +} + +void GameState::SetAutoRoomViewport(bool on) +{ + _isAutoRoomViewport = on; +} + +void GameState::SetMainViewport(const Rect &viewport) +{ + _mainViewport.SetRect(viewport); + Mouse::SetGraphicArea(); + scsystem.viewport_width = game_to_data_coord(_mainViewport.GetRect().GetWidth()); + scsystem.viewport_height = game_to_data_coord(_mainViewport.GetRect().GetHeight()); + _mainViewportHasChanged = true; +} + +const Rect &GameState::GetMainViewport() const +{ + return _mainViewport.GetRect(); +} + +const Rect &GameState::GetUIViewport() const +{ + return _uiViewport.GetRect(); +} + +PViewport GameState::GetRoomViewport(int index) const +{ + return _roomViewports[index]; +} + +const std::vector &GameState::GetRoomViewportsZOrdered() const +{ + return _roomViewportsSorted; +} + +PViewport GameState::GetRoomViewportAt(int x, int y) const +{ + // We iterate backwards, because in AGS low z-order means bottom + for (auto it = _roomViewportsSorted.rbegin(); it != _roomViewportsSorted.rend(); ++it) + if ((*it)->IsVisible() && (*it)->GetRect().IsInside(x, y)) + return *it; + return nullptr; +} + +Rect GameState::GetUIViewportAbs() const +{ + return Rect::MoveBy(_uiViewport.GetRect(), _mainViewport.GetRect().Left, _mainViewport.GetRect().Top); +} + +Rect GameState::GetRoomViewportAbs(int index) const +{ + return Rect::MoveBy(_roomViewports[index]->GetRect(), _mainViewport.GetRect().Left, _mainViewport.GetRect().Top); +} + +void GameState::SetUIViewport(const Rect &viewport) +{ + _uiViewport.SetRect(viewport); +} + +static bool ViewportZOrder(const PViewport e1, const PViewport e2) +{ + return e1->GetZOrder() < e2->GetZOrder(); +} + +void GameState::UpdateViewports() +{ + if (_mainViewportHasChanged) + { + on_mainviewport_changed(); + _mainViewportHasChanged = false; + } + if (_roomViewportZOrderChanged) + { + auto old_sort = _roomViewportsSorted; + _roomViewportsSorted = _roomViewports; + std::sort(_roomViewportsSorted.begin(), _roomViewportsSorted.end(), ViewportZOrder); + for (size_t i = 0; i < _roomViewportsSorted.size(); ++i) + { + if (i >= old_sort.size() || _roomViewportsSorted[i] != old_sort[i]) + _roomViewportsSorted[i]->SetChangedVisible(); + } + _roomViewportZOrderChanged = false; + } + size_t vp_changed = -1; + for (size_t i = _roomViewportsSorted.size(); i-- > 0;) + { + auto vp = _roomViewportsSorted[i]; + if (vp->HasChangedSize() || vp->HasChangedPosition() || vp->HasChangedVisible()) + { + vp_changed = i; + on_roomviewport_changed(vp.get()); + vp->ClearChangedFlags(); + } + } + if (vp_changed != -1) + detect_roomviewport_overlaps(vp_changed); + for (auto cam : _roomCameras) + { + if (cam->HasChangedSize() || cam->HasChangedPosition()) + { + on_roomcamera_changed(cam.get()); + cam->ClearChangedFlags(); + } + } +} + +void GameState::InvalidateViewportZOrder() +{ + _roomViewportZOrderChanged = true; +} + +PCamera GameState::GetRoomCamera(int index) const +{ + return _roomCameras[index]; +} + +void GameState::UpdateRoomCameras() +{ + for (size_t i = 0; i < _roomCameras.size(); ++i) + UpdateRoomCamera(i); +} + +void GameState::UpdateRoomCamera(int index) +{ + auto cam = _roomCameras[index]; + const Rect &rc = cam->GetRect(); + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + if ((real_room_sz.Width > rc.GetWidth()) || (real_room_sz.Height > rc.GetHeight())) + { + // TODO: split out into Camera Behavior + if (!cam->IsLocked()) + { + int x = data_to_game_coord(playerchar->x) - rc.GetWidth() / 2; + int y = data_to_game_coord(playerchar->y) - rc.GetHeight() / 2; + cam->SetAt(x, y); + } + } + else + { + cam->SetAt(0, 0); + } +} + +Point GameState::RoomToScreen(int roomx, int roomy) +{ + return _roomViewports[0]->RoomToScreen(roomx, roomy, false).first; +} + +int GameState::RoomToScreenX(int roomx) +{ + return _roomViewports[0]->RoomToScreen(roomx, 0, false).first.X; +} + +int GameState::RoomToScreenY(int roomy) +{ + return _roomViewports[0]->RoomToScreen(0, roomy, false).first.Y; +} + +VpPoint GameState::ScreenToRoomImpl(int scrx, int scry, int view_index, bool clip_viewport, bool convert_cam_to_data) +{ + PViewport view; + if (view_index < 0) + { + view = GetRoomViewportAt(scrx, scry); + if (!view) + return std::make_pair(Point(), -1); + } + else + { + view = _roomViewports[view_index]; + } + return view->ScreenToRoom(scrx, scry, clip_viewport, convert_cam_to_data); +} + +VpPoint GameState::ScreenToRoom(int scrx, int scry) +{ + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v3507) + return ScreenToRoomImpl(scrx, scry, -1, true, false); + return ScreenToRoomImpl(scrx, scry, 0, false, false); +} + +VpPoint GameState::ScreenToRoomDivDown(int scrx, int scry) +{ + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v3507) + return ScreenToRoomImpl(scrx, scry, -1, true, true); + return ScreenToRoomImpl(scrx, scry, 0, false, true); +} + +void GameState::CreatePrimaryViewportAndCamera() +{ + if (_roomViewports.size() == 0) + { + play.CreateRoomViewport(); + play.RegisterRoomViewport(0); + } + if (_roomCameras.size() == 0) + { + play.CreateRoomCamera(); + play.RegisterRoomCamera(0); + } + _roomViewports[0]->LinkCamera(_roomCameras[0]); + _roomCameras[0]->LinkToViewport(_roomViewports[0]); +} + +PViewport GameState::CreateRoomViewport() +{ + int index = (int)_roomViewports.size(); + PViewport viewport(new Viewport()); + viewport->SetID(index); + viewport->SetRect(_mainViewport.GetRect()); + ScriptViewport *scv = new ScriptViewport(index); + _roomViewports.push_back(viewport); + _scViewportRefs.push_back(std::make_pair(scv, 0)); + _roomViewportsSorted.push_back(viewport); + _roomViewportZOrderChanged = true; + on_roomviewport_created(index); + return viewport; +} + +ScriptViewport *GameState::RegisterRoomViewport(int index, int32_t handle) +{ + if (index < 0 || (size_t)index >= _roomViewports.size()) + return nullptr; + auto &scobj = _scViewportRefs[index]; + if (handle == 0) + { + handle = ccRegisterManagedObject(scobj.first, scobj.first); + ccAddObjectReference(handle); // one reference for the GameState + } + else + { + ccRegisterUnserializedObject(handle, scobj.first, scobj.first); + } + scobj.second = handle; + return scobj.first; +} + +void GameState::DeleteRoomViewport(int index) +{ + // NOTE: viewport 0 can not be deleted + if (index <= 0 || (size_t)index >= _roomViewports.size()) + return; + auto scobj = _scViewportRefs[index]; + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + auto cam = _roomViewports[index]->GetCamera(); + if (cam) + cam->UnlinkFromViewport(index); + _roomViewports.erase(_roomViewports.begin() + index); + _scViewportRefs.erase(_scViewportRefs.begin() + index); + for (size_t i = index; i < _roomViewports.size(); ++i) + { + _roomViewports[i]->SetID(i); + _scViewportRefs[i].first->SetID(i); + } + for (size_t i = 0; i < _roomViewportsSorted.size(); ++i) + { + if (_roomViewportsSorted[i]->GetID() == index) + { + _roomViewportsSorted.erase(_roomViewportsSorted.begin() + i); + break; + } + } + on_roomviewport_deleted(index); +} + +int GameState::GetRoomViewportCount() const +{ + return (int)_roomViewports.size(); +} + +PCamera GameState::CreateRoomCamera() +{ + int index = (int)_roomCameras.size(); + PCamera camera(new Camera()); + camera->SetID(index); + camera->SetAt(0, 0); + camera->SetSize(_mainViewport.GetRect().GetSize()); + ScriptCamera *scam = new ScriptCamera(index); + _scCameraRefs.push_back(std::make_pair(scam, 0)); + _roomCameras.push_back(camera); + return camera; +} + +ScriptCamera *GameState::RegisterRoomCamera(int index, int32_t handle) +{ + if (index < 0 || (size_t)index >= _roomCameras.size()) + return nullptr; + auto &scobj = _scCameraRefs[index]; + if (handle == 0) + { + handle = ccRegisterManagedObject(scobj.first, scobj.first); + ccAddObjectReference(handle); // one reference for the GameState + } + else + { + ccRegisterUnserializedObject(handle, scobj.first, scobj.first); + } + scobj.second = handle; + return scobj.first; +} + +void GameState::DeleteRoomCamera(int index) +{ + // NOTE: camera 0 can not be deleted + if (index <= 0 || (size_t)index >= _roomCameras.size()) + return; + auto scobj = _scCameraRefs[index]; + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + for (auto& viewref : _roomCameras[index]->GetLinkedViewports()) + { + auto view = viewref.lock(); + if (view) + view->LinkCamera(nullptr); + } + _roomCameras.erase(_roomCameras.begin() + index); + _scCameraRefs.erase(_scCameraRefs.begin() + index); + for (size_t i = index; i < _roomCameras.size(); ++i) + { + _roomCameras[i]->SetID(i); + _scCameraRefs[i].first->SetID(i); + } +} + +int GameState::GetRoomCameraCount() const +{ + return (int)_roomCameras.size(); +} + +ScriptViewport *GameState::GetScriptViewport(int index) +{ + if (index < 0 || (size_t)index >= _roomViewports.size()) + return NULL; + return _scViewportRefs[index].first; +} + +ScriptCamera *GameState::GetScriptCamera(int index) +{ + if (index < 0 || (size_t)index >= _roomCameras.size()) + return NULL; + return _scCameraRefs[index].first; +} + +bool GameState::IsIgnoringInput() const +{ + return AGS_Clock::now() < _ignoreUserInputUntilTime; +} + +void GameState::SetIgnoreInput(int timeout_ms) +{ + if (AGS_Clock::now() + std::chrono::milliseconds(timeout_ms) > _ignoreUserInputUntilTime) + _ignoreUserInputUntilTime = AGS_Clock::now() + std::chrono::milliseconds(timeout_ms); +} + +void GameState::ClearIgnoreInput() +{ + _ignoreUserInputUntilTime = AGS_Clock::now(); +} + +bool GameState::IsBlockingVoiceSpeech() const +{ + return speech_has_voice && speech_voice_blocking; +} + +bool GameState::IsNonBlockingVoiceSpeech() const +{ + return speech_has_voice && !speech_voice_blocking; +} + +bool GameState::ShouldPlayVoiceSpeech() const +{ + return !play.fast_forward && + (play.want_speech >= 1) && (!ResPaths.SpeechPak.Name.IsEmpty()); +} + +void GameState::ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, RestoredData &r_data) +{ + const bool old_save = svg_ver < kGSSvgVersion_Initial; + score = in->ReadInt32(); + usedmode = in->ReadInt32(); + disabled_user_interface = in->ReadInt32(); + gscript_timer = in->ReadInt32(); + debug_mode = in->ReadInt32(); + in->ReadArrayOfInt32(globalvars, MAXGLOBALVARS); + messagetime = in->ReadInt32(); + usedinv = in->ReadInt32(); + inv_top = in->ReadInt32(); + inv_numdisp = in->ReadInt32(); + obsolete_inv_numorder = in->ReadInt32(); + inv_numinline = in->ReadInt32(); + text_speed = in->ReadInt32(); + sierra_inv_color = in->ReadInt32(); + talkanim_speed = in->ReadInt32(); + inv_item_wid = in->ReadInt32(); + inv_item_hit = in->ReadInt32(); + speech_text_shadow = in->ReadInt32(); + swap_portrait_side = in->ReadInt32(); + speech_textwindow_gui = in->ReadInt32(); + follow_change_room_timer = in->ReadInt32(); + totalscore = in->ReadInt32(); + skip_display = in->ReadInt32(); + no_multiloop_repeat = in->ReadInt32(); + roomscript_finished = in->ReadInt32(); + used_inv_on = in->ReadInt32(); + no_textbg_when_voice = in->ReadInt32(); + max_dialogoption_width = in->ReadInt32(); + no_hicolor_fadein = in->ReadInt32(); + bgspeech_game_speed = in->ReadInt32(); + bgspeech_stay_on_display = in->ReadInt32(); + unfactor_speech_from_textlength = in->ReadInt32(); + mp3_loop_before_end = in->ReadInt32(); + speech_music_drop = in->ReadInt32(); + in_cutscene = in->ReadInt32(); + fast_forward = in->ReadInt32(); + room_width = in->ReadInt32(); + room_height = in->ReadInt32(); + game_speed_modifier = in->ReadInt32(); + score_sound = in->ReadInt32(); + takeover_data = in->ReadInt32(); + replay_hotkey_unused = in->ReadInt32(); + dialog_options_x = in->ReadInt32(); + dialog_options_y = in->ReadInt32(); + narrator_speech = in->ReadInt32(); + ambient_sounds_persist = in->ReadInt32(); + lipsync_speed = in->ReadInt32(); + close_mouth_speech_time = in->ReadInt32(); + disable_antialiasing = in->ReadInt32(); + text_speed_modifier = in->ReadInt32(); + if (svg_ver < kGSSvgVersion_350) + text_align = ConvertLegacyScriptAlignment((LegacyScriptAlignment)in->ReadInt32()); + else + text_align = (HorAlignment)in->ReadInt32(); + speech_bubble_width = in->ReadInt32(); + min_dialogoption_width = in->ReadInt32(); + disable_dialog_parser = in->ReadInt32(); + anim_background_speed = in->ReadInt32(); // the setting for this room + top_bar_backcolor= in->ReadInt32(); + top_bar_textcolor = in->ReadInt32(); + top_bar_bordercolor = in->ReadInt32(); + top_bar_borderwidth = in->ReadInt32(); + top_bar_ypos = in->ReadInt32(); + screenshot_width = in->ReadInt32(); + screenshot_height = in->ReadInt32(); + top_bar_font = in->ReadInt32(); + if (svg_ver < kGSSvgVersion_350) + speech_text_align = ConvertLegacyScriptAlignment((LegacyScriptAlignment)in->ReadInt32()); + else + speech_text_align = (HorAlignment)in->ReadInt32(); + auto_use_walkto_points = in->ReadInt32(); + inventory_greys_out = in->ReadInt32(); + skip_speech_specific_key = in->ReadInt32(); + abort_key = in->ReadInt32(); + fade_to_red = in->ReadInt32(); + fade_to_green = in->ReadInt32(); + fade_to_blue = in->ReadInt32(); + show_single_dialog_option = in->ReadInt32(); + keep_screen_during_instant_transition = in->ReadInt32(); + read_dialog_option_colour = in->ReadInt32(); + stop_dialog_at_end = in->ReadInt32(); + speech_portrait_placement = in->ReadInt32(); + speech_portrait_x = in->ReadInt32(); + speech_portrait_y = in->ReadInt32(); + speech_display_post_time_ms = in->ReadInt32(); + dialog_options_highlight_color = in->ReadInt32(); + if (old_save) + in->ReadArrayOfInt32(reserved, GAME_STATE_RESERVED_INTS); + // ** up to here is referenced in the script "game." object + if (old_save) + { + in->ReadInt32(); // recording + in->ReadInt32(); // playback + in->ReadInt16(); // gamestep + } + randseed = in->ReadInt32(); // random seed + player_on_region = in->ReadInt32(); // player's current region + if (old_save) + in->ReadInt32(); // screen_is_faded_out + check_interaction_only = in->ReadInt32(); + bg_frame = in->ReadInt32(); + bg_anim_delay = in->ReadInt32(); // for animating backgrounds + music_vol_was = in->ReadInt32(); // before the volume drop + wait_counter = in->ReadInt16(); + mboundx1 = in->ReadInt16(); + mboundx2 = in->ReadInt16(); + mboundy1 = in->ReadInt16(); + mboundy2 = in->ReadInt16(); + fade_effect = in->ReadInt32(); + bg_frame_locked = in->ReadInt32(); + in->ReadArrayOfInt32(globalscriptvars, MAXGSVALUES); + cur_music_number = in->ReadInt32(); + music_repeat = in->ReadInt32(); + music_master_volume = in->ReadInt32(); + digital_master_volume = in->ReadInt32(); + in->Read(walkable_areas_on, MAX_WALK_AREAS+1); + screen_flipped = in->ReadInt16(); + if (svg_ver < kGSSvgVersion_3510) + { + short offsets_locked = in->ReadInt16(); + if (offsets_locked != 0) + r_data.Camera0_Flags = kSvgCamPosLocked; + } + entered_at_x = in->ReadInt32(); + entered_at_y = in->ReadInt32(); + entered_edge = in->ReadInt32(); + want_speech = in->ReadInt32(); + cant_skip_speech = in->ReadInt32(); + in->ReadArrayOfInt32(script_timers, MAX_TIMERS); + sound_volume = in->ReadInt32(); + speech_volume = in->ReadInt32(); + normal_font = in->ReadInt32(); + speech_font = in->ReadInt32(); + key_skip_wait = in->ReadInt8(); + swap_portrait_lastchar = in->ReadInt32(); + separate_music_lib = in->ReadInt32(); + in_conversation = in->ReadInt32(); + screen_tint = in->ReadInt32(); + num_parsed_words = in->ReadInt32(); + in->ReadArrayOfInt16( parsed_words, MAX_PARSED_WORDS); + in->Read( bad_parsed_word, 100); + raw_color = in->ReadInt32(); + if (old_save) + in->ReadArrayOfInt32(raw_modified, MAX_ROOM_BGFRAMES); + in->ReadArrayOfInt16( filenumbers, MAXSAVEGAMES); + if (old_save) + in->ReadInt32(); // room_changes + mouse_cursor_hidden = in->ReadInt32(); + silent_midi = in->ReadInt32(); + silent_midi_channel = in->ReadInt32(); + current_music_repeating = in->ReadInt32(); + shakesc_delay = in->ReadInt32(); + shakesc_amount = in->ReadInt32(); + shakesc_length = in->ReadInt32(); + rtint_red = in->ReadInt32(); + rtint_green = in->ReadInt32(); + rtint_blue = in->ReadInt32(); + rtint_level = in->ReadInt32(); + rtint_light = in->ReadInt32(); + if (!old_save || loaded_game_file_version >= kGameVersion_340_4) + rtint_enabled = in->ReadBool(); + else + rtint_enabled = rtint_level > 0; + end_cutscene_music = in->ReadInt32(); + skip_until_char_stops = in->ReadInt32(); + get_loc_name_last_time = in->ReadInt32(); + get_loc_name_save_cursor = in->ReadInt32(); + restore_cursor_mode_to = in->ReadInt32(); + restore_cursor_image_to = in->ReadInt32(); + music_queue_size = in->ReadInt16(); + in->ReadArrayOfInt16( music_queue, MAX_QUEUED_MUSIC); + new_music_queue_size = in->ReadInt16(); + if (!old_save) + { + for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) + { + new_music_queue[i].ReadFromFile(in); + } + } + + crossfading_out_channel = in->ReadInt16(); + crossfade_step = in->ReadInt16(); + crossfade_out_volume_per_step = in->ReadInt16(); + crossfade_initial_volume_out = in->ReadInt16(); + crossfading_in_channel = in->ReadInt16(); + crossfade_in_volume_per_step = in->ReadInt16(); + crossfade_final_volume_in = in->ReadInt16(); + + if (old_save) + ReadQueuedAudioItems_Aligned(in); + + in->Read(takeover_from, 50); + in->Read(playmp3file_name, PLAYMP3FILE_MAX_FILENAME_LEN); + in->Read(globalstrings, MAXGLOBALSTRINGS * MAX_MAXSTRLEN); + in->Read(lastParserEntry, MAX_MAXSTRLEN); + in->Read(game_name, 100); + ground_level_areas_disabled = in->ReadInt32(); + next_screen_transition = in->ReadInt32(); + in->ReadInt32(); // gamma_adjustment -- do not apply gamma level from savegame + temporarily_turned_off_character = in->ReadInt16(); + inv_backwards_compatibility = in->ReadInt16(); + if (old_save) + { + in->ReadInt32(); // gui_draw_order + in->ReadInt32(); // do_once_tokens; + } + int num_do_once_tokens = in->ReadInt32(); + do_once_tokens.resize(num_do_once_tokens); + if (!old_save) + { + for (int i = 0; i < num_do_once_tokens; ++i) + { + StrUtil::ReadString(do_once_tokens[i], in); + } + } + text_min_display_time_ms = in->ReadInt32(); + ignore_user_input_after_text_timeout_ms = in->ReadInt32(); + if (svg_ver < kGSSvgVersion_3509) + in->ReadInt32(); // ignore_user_input_until_time -- do not apply from savegame + if (old_save) + in->ReadArrayOfInt32(default_audio_type_volumes, MAX_AUDIO_TYPES); + if (svg_ver >= kGSSvgVersion_3509) + { + int voice_speech_flags = in->ReadInt32(); + speech_has_voice = voice_speech_flags != 0; + speech_voice_blocking = (voice_speech_flags & 0x02) != 0; + } +} + +void GameState::WriteForSavegame(Common::Stream *out) const +{ + // NOTE: following parameters are never saved: + // recording, playback, gamestep, screen_is_faded_out, room_changes + out->WriteInt32(score); + out->WriteInt32(usedmode); + out->WriteInt32(disabled_user_interface); + out->WriteInt32(gscript_timer); + out->WriteInt32(debug_mode); + out->WriteArrayOfInt32(globalvars, MAXGLOBALVARS); + out->WriteInt32(messagetime); + out->WriteInt32(usedinv); + out->WriteInt32(inv_top); + out->WriteInt32(inv_numdisp); + out->WriteInt32(obsolete_inv_numorder); + out->WriteInt32(inv_numinline); + out->WriteInt32(text_speed); + out->WriteInt32(sierra_inv_color); + out->WriteInt32(talkanim_speed); + out->WriteInt32(inv_item_wid); + out->WriteInt32(inv_item_hit); + out->WriteInt32(speech_text_shadow); + out->WriteInt32(swap_portrait_side); + out->WriteInt32(speech_textwindow_gui); + out->WriteInt32(follow_change_room_timer); + out->WriteInt32(totalscore); + out->WriteInt32(skip_display); + out->WriteInt32(no_multiloop_repeat); + out->WriteInt32(roomscript_finished); + out->WriteInt32(used_inv_on); + out->WriteInt32(no_textbg_when_voice); + out->WriteInt32(max_dialogoption_width); + out->WriteInt32(no_hicolor_fadein); + out->WriteInt32(bgspeech_game_speed); + out->WriteInt32(bgspeech_stay_on_display); + out->WriteInt32(unfactor_speech_from_textlength); + out->WriteInt32(mp3_loop_before_end); + out->WriteInt32(speech_music_drop); + out->WriteInt32(in_cutscene); + out->WriteInt32(fast_forward); + out->WriteInt32(room_width); + out->WriteInt32(room_height); + out->WriteInt32(game_speed_modifier); + out->WriteInt32(score_sound); + out->WriteInt32(takeover_data); + out->WriteInt32(replay_hotkey_unused); // StartRecording: not supported + out->WriteInt32(dialog_options_x); + out->WriteInt32(dialog_options_y); + out->WriteInt32(narrator_speech); + out->WriteInt32(ambient_sounds_persist); + out->WriteInt32(lipsync_speed); + out->WriteInt32(close_mouth_speech_time); + out->WriteInt32(disable_antialiasing); + out->WriteInt32(text_speed_modifier); + out->WriteInt32(text_align); + out->WriteInt32(speech_bubble_width); + out->WriteInt32(min_dialogoption_width); + out->WriteInt32(disable_dialog_parser); + out->WriteInt32(anim_background_speed); // the setting for this room + out->WriteInt32(top_bar_backcolor); + out->WriteInt32(top_bar_textcolor); + out->WriteInt32(top_bar_bordercolor); + out->WriteInt32(top_bar_borderwidth); + out->WriteInt32(top_bar_ypos); + out->WriteInt32(screenshot_width); + out->WriteInt32(screenshot_height); + out->WriteInt32(top_bar_font); + out->WriteInt32(speech_text_align); + out->WriteInt32(auto_use_walkto_points); + out->WriteInt32(inventory_greys_out); + out->WriteInt32(skip_speech_specific_key); + out->WriteInt32(abort_key); + out->WriteInt32(fade_to_red); + out->WriteInt32(fade_to_green); + out->WriteInt32(fade_to_blue); + out->WriteInt32(show_single_dialog_option); + out->WriteInt32(keep_screen_during_instant_transition); + out->WriteInt32(read_dialog_option_colour); + out->WriteInt32(stop_dialog_at_end); + out->WriteInt32(speech_portrait_placement); + out->WriteInt32(speech_portrait_x); + out->WriteInt32(speech_portrait_y); + out->WriteInt32(speech_display_post_time_ms); + out->WriteInt32(dialog_options_highlight_color); + // ** up to here is referenced in the script "game." object + out->WriteInt32(randseed); // random seed + out->WriteInt32( player_on_region); // player's current region + out->WriteInt32( check_interaction_only); + out->WriteInt32( bg_frame); + out->WriteInt32( bg_anim_delay); // for animating backgrounds + out->WriteInt32( music_vol_was); // before the volume drop + out->WriteInt16(wait_counter); + out->WriteInt16(mboundx1); + out->WriteInt16(mboundx2); + out->WriteInt16(mboundy1); + out->WriteInt16(mboundy2); + out->WriteInt32( fade_effect); + out->WriteInt32( bg_frame_locked); + out->WriteArrayOfInt32(globalscriptvars, MAXGSVALUES); + out->WriteInt32( cur_music_number); + out->WriteInt32( music_repeat); + out->WriteInt32( music_master_volume); + out->WriteInt32( digital_master_volume); + out->Write(walkable_areas_on, MAX_WALK_AREAS+1); + out->WriteInt16( screen_flipped); + out->WriteInt32( entered_at_x); + out->WriteInt32( entered_at_y); + out->WriteInt32( entered_edge); + out->WriteInt32( want_speech); + out->WriteInt32( cant_skip_speech); + out->WriteArrayOfInt32(script_timers, MAX_TIMERS); + out->WriteInt32( sound_volume); + out->WriteInt32( speech_volume); + out->WriteInt32( normal_font); + out->WriteInt32( speech_font); + out->WriteInt8( key_skip_wait); + out->WriteInt32( swap_portrait_lastchar); + out->WriteInt32( separate_music_lib); + out->WriteInt32( in_conversation); + out->WriteInt32( screen_tint); + out->WriteInt32( num_parsed_words); + out->WriteArrayOfInt16( parsed_words, MAX_PARSED_WORDS); + out->Write( bad_parsed_word, 100); + out->WriteInt32( raw_color); + out->WriteArrayOfInt16( filenumbers, MAXSAVEGAMES); + out->WriteInt32( mouse_cursor_hidden); + out->WriteInt32( silent_midi); + out->WriteInt32( silent_midi_channel); + out->WriteInt32( current_music_repeating); + out->WriteInt32( shakesc_delay); + out->WriteInt32( shakesc_amount); + out->WriteInt32( shakesc_length); + out->WriteInt32( rtint_red); + out->WriteInt32( rtint_green); + out->WriteInt32( rtint_blue); + out->WriteInt32( rtint_level); + out->WriteInt32( rtint_light); + out->WriteBool(rtint_enabled); + out->WriteInt32( end_cutscene_music); + out->WriteInt32( skip_until_char_stops); + out->WriteInt32( get_loc_name_last_time); + out->WriteInt32( get_loc_name_save_cursor); + out->WriteInt32( restore_cursor_mode_to); + out->WriteInt32( restore_cursor_image_to); + out->WriteInt16( music_queue_size); + out->WriteArrayOfInt16( music_queue, MAX_QUEUED_MUSIC); + out->WriteInt16(new_music_queue_size); + for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) + { + new_music_queue[i].WriteToFile(out); + } + + out->WriteInt16( crossfading_out_channel); + out->WriteInt16( crossfade_step); + out->WriteInt16( crossfade_out_volume_per_step); + out->WriteInt16( crossfade_initial_volume_out); + out->WriteInt16( crossfading_in_channel); + out->WriteInt16( crossfade_in_volume_per_step); + out->WriteInt16( crossfade_final_volume_in); + + out->Write(takeover_from, 50); + out->Write(playmp3file_name, PLAYMP3FILE_MAX_FILENAME_LEN); + out->Write(globalstrings, MAXGLOBALSTRINGS * MAX_MAXSTRLEN); + out->Write(lastParserEntry, MAX_MAXSTRLEN); + out->Write(game_name, 100); + out->WriteInt32( ground_level_areas_disabled); + out->WriteInt32( next_screen_transition); + out->WriteInt32( gamma_adjustment); + out->WriteInt16(temporarily_turned_off_character); + out->WriteInt16(inv_backwards_compatibility); + out->WriteInt32(do_once_tokens.size()); + for (int i = 0; i < (int)do_once_tokens.size(); ++i) + { + StrUtil::WriteString(do_once_tokens[i], out); + } + out->WriteInt32( text_min_display_time_ms); + out->WriteInt32( ignore_user_input_after_text_timeout_ms); + + int voice_speech_flags = speech_has_voice ? 0x01 : 0; + if (speech_voice_blocking) + voice_speech_flags |= 0x02; + out->WriteInt32(voice_speech_flags); +} + +void GameState::ReadQueuedAudioItems_Aligned(Common::Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) + { + new_music_queue[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void GameState::FreeProperties() +{ + for (auto &p : charProps) + p.clear(); + for (auto &p : invProps) + p.clear(); +} + +void GameState::FreeViewportsAndCameras() +{ + _roomViewports.clear(); + _roomViewportsSorted.clear(); + for (auto &scobj : _scViewportRefs) + { + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + } + _scViewportRefs.clear(); + _roomCameras.clear(); + for (auto &scobj : _scCameraRefs) + { + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + } + _scCameraRefs.clear(); +} + +void GameState::ReadCustomProperties_v340(Common::Stream *in) +{ + if (loaded_game_file_version >= kGameVersion_340_4) + { + // After runtime property values were read we also copy missing default, + // because we do not keep defaults in the saved game, and also in case + // this save is made by an older game version which had different + // properties. + for (int i = 0; i < game.numcharacters; ++i) + Properties::ReadValues(charProps[i], in); + for (int i = 0; i < game.numinvitems; ++i) + Properties::ReadValues(invProps[i], in); + } +} + +void GameState::WriteCustomProperties_v340(Common::Stream *out) const +{ + if (loaded_game_file_version >= kGameVersion_340_4) + { + // We temporarily remove properties that kept default values + // just for the saving data time to avoid getting lots of + // redundant data into saved games + for (int i = 0; i < game.numcharacters; ++i) + Properties::WriteValues(charProps[i], out); + for (int i = 0; i < game.numinvitems; ++i) + Properties::WriteValues(invProps[i], out); + } +} + +// Converts legacy alignment type used in script API +HorAlignment ConvertLegacyScriptAlignment(LegacyScriptAlignment align) +{ + switch (align) + { + case kLegacyScAlignLeft: return kHAlignLeft; + case kLegacyScAlignCentre: return kHAlignCenter; + case kLegacyScAlignRight: return kHAlignRight; + } + return kHAlignNone; +} + +// Reads legacy alignment type from the value set in script depending on the +// current Script API level. This is made to make it possible to change +// Alignment constants in the Script API and still support old version. +HorAlignment ReadScriptAlignment(int32_t align) +{ + return game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v350 ? + ConvertLegacyScriptAlignment((LegacyScriptAlignment)align) : + (HorAlignment)align; +} diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h new file mode 100644 index 000000000000..b5843c130ce9 --- /dev/null +++ b/engines/ags/engine/ac/gamestate.h @@ -0,0 +1,396 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GAMESTATE_H +#define __AC_GAMESTATE_H + + +#include +#include + +#include "ac/characterinfo.h" +#include "ac/runtime_defines.h" +#include "game/roomstruct.h" +#include "game/viewport.h" +#include "media/audio/queuedaudioitem.h" +#include "util/geometry.h" +#include "util/string_types.h" +#include "util/string.h" +#include "ac/timer.h" + +// Forward declaration +namespace AGS +{ + namespace Common + { + class Bitmap; class Stream; + typedef std::shared_ptr PBitmap; + } + namespace Engine { struct RestoredData; } +} +using namespace AGS; // FIXME later +struct ScriptViewport; +struct ScriptCamera; + +#define GAME_STATE_RESERVED_INTS 5 + +// Savegame data format +enum GameStateSvgVersion +{ + kGSSvgVersion_OldFormat = -1, // TODO: remove after old save support is dropped + kGSSvgVersion_Initial = 0, + kGSSvgVersion_350 = 1, + kGSSvgVersion_3509 = 2, + kGSSvgVersion_3510 = 3, +}; + + + +// Adding to this might need to modify AGSDEFNS.SH and AGSPLUGIN.H +struct GameState { + int score; // player's current score + int usedmode; // set by ProcessClick to last cursor mode used + int disabled_user_interface; // >0 while in cutscene/etc + int gscript_timer; // obsolete + int debug_mode; // whether we're in debug mode + int globalvars[MAXGLOBALVARS]; // obsolete + int messagetime; // time left for auto-remove messages + int usedinv; // inventory item last used + int inv_top,inv_numdisp,obsolete_inv_numorder,inv_numinline; + int text_speed; // how quickly text is removed + int sierra_inv_color; // background used to paint defualt inv window + int talkanim_speed; // animation speed of talking anims + int inv_item_wid,inv_item_hit; // set by SetInvDimensions + int speech_text_shadow; // colour of outline fonts (default black) + int swap_portrait_side; // sierra-style speech swap sides + int speech_textwindow_gui; // textwindow used for sierra-style speech + int follow_change_room_timer; // delay before moving following characters into new room + int totalscore; // maximum possible score + int skip_display; // how the user can skip normal Display windows + int no_multiloop_repeat; // for backwards compatibility + int roomscript_finished; // on_call finished in room + int used_inv_on; // inv item they clicked on + int no_textbg_when_voice; // no textwindow bgrnd when voice speech is used + int max_dialogoption_width; // max width of dialog options text window + int no_hicolor_fadein; // fade out but instant in for hi-color + int bgspeech_game_speed; // is background speech relative to game speed + int bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used + int unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay + int mp3_loop_before_end; // (UNUSED!) loop this time before end of track (ms) + int speech_music_drop; // how much to drop music volume by when speech is played + int in_cutscene; // we are between a StartCutscene and EndCutscene + int fast_forward; // player has elected to skip cutscene + int room_width; // width of current room + int room_height; // height of current room + // ** up to here is referenced in the plugin interface + int game_speed_modifier; + int score_sound; + int takeover_data; // value passed to RunAGSGame in previous game + int replay_hotkey_unused; // (UNUSED!) StartRecording: not supported + int dialog_options_x; + int dialog_options_y; + int narrator_speech; + int ambient_sounds_persist; + int lipsync_speed; + int close_mouth_speech_time; // stop speech animation at (messagetime - close_mouth_speech_time) + // (this is designed to work in text-only mode) + int disable_antialiasing; + int text_speed_modifier; + HorAlignment text_align; + int speech_bubble_width; + int min_dialogoption_width; + int disable_dialog_parser; + int anim_background_speed; // the setting for this room + int top_bar_backcolor; + int top_bar_textcolor; + int top_bar_bordercolor; + int top_bar_borderwidth; + int top_bar_ypos; + int screenshot_width; + int screenshot_height; + int top_bar_font; + HorAlignment speech_text_align; + int auto_use_walkto_points; + int inventory_greys_out; + int skip_speech_specific_key; + int abort_key; + int fade_to_red; + int fade_to_green; + int fade_to_blue; + int show_single_dialog_option; + int keep_screen_during_instant_transition; + int read_dialog_option_colour; + int stop_dialog_at_end; + int speech_portrait_placement; // speech portrait placement mode (automatic/custom) + int speech_portrait_x; // a speech portrait x offset from corresponding screen side + int speech_portrait_y; // a speech portrait y offset + int speech_display_post_time_ms; // keep speech text/portrait on screen after text/voice has finished playing; + // no speech animation is supposed to be played at this time + int dialog_options_highlight_color; // The colour used for highlighted (hovered over) text in dialog options + int reserved[GAME_STATE_RESERVED_INTS]; // make sure if a future version adds a var, it doesn't mess anything up + // ** up to here is referenced in the script "game." object + long randseed; // random seed + int player_on_region; // player's current region + int screen_is_faded_out; // the screen is currently black + int check_interaction_only; + int bg_frame,bg_anim_delay; // for animating backgrounds + int music_vol_was; // before the volume drop + short wait_counter; + char wait_skipped_by; // tells how last wait was skipped [not serialized] + int wait_skipped_by_data; // extended data telling how last wait was skipped [not serialized] + short mboundx1,mboundx2,mboundy1,mboundy2; + int fade_effect; + int bg_frame_locked; + int globalscriptvars[MAXGSVALUES]; + int cur_music_number,music_repeat; + int music_master_volume; + int digital_master_volume; + char walkable_areas_on[MAX_WALK_AREAS+1]; + short screen_flipped; + int entered_at_x,entered_at_y, entered_edge; + int want_speech; + int cant_skip_speech; + int script_timers[MAX_TIMERS]; + int sound_volume,speech_volume; + int normal_font, speech_font; + char key_skip_wait; + int swap_portrait_lastchar; + int swap_portrait_lastlastchar; + int separate_music_lib; + int in_conversation; + int screen_tint; + int num_parsed_words; + short parsed_words[MAX_PARSED_WORDS]; + char bad_parsed_word[100]; + int raw_color; + int raw_modified[MAX_ROOM_BGFRAMES]; + Common::PBitmap raw_drawing_surface; + short filenumbers[MAXSAVEGAMES]; + int room_changes; + int mouse_cursor_hidden; + int silent_midi; + int silent_midi_channel; + int current_music_repeating; // remember what the loop flag was when this music started + unsigned long shakesc_delay; // unsigned long to match loopcounter + int shakesc_amount, shakesc_length; + int rtint_red, rtint_green, rtint_blue, rtint_level, rtint_light; + bool rtint_enabled; + int end_cutscene_music; + int skip_until_char_stops; + int get_loc_name_last_time; + int get_loc_name_save_cursor; + int restore_cursor_mode_to; + int restore_cursor_image_to; + short music_queue_size; + short music_queue[MAX_QUEUED_MUSIC]; + short new_music_queue_size; + short crossfading_out_channel; + short crossfade_step; + short crossfade_out_volume_per_step; + short crossfade_initial_volume_out; + short crossfading_in_channel; + short crossfade_in_volume_per_step; + short crossfade_final_volume_in; + QueuedAudioItem new_music_queue[MAX_QUEUED_MUSIC]; + char takeover_from[50]; + char playmp3file_name[PLAYMP3FILE_MAX_FILENAME_LEN]; + char globalstrings[MAXGLOBALSTRINGS][MAX_MAXSTRLEN]; + char lastParserEntry[MAX_MAXSTRLEN]; + char game_name[100]; + int ground_level_areas_disabled; + int next_screen_transition; + int gamma_adjustment; + short temporarily_turned_off_character; // Hide Player Charactr ticked + short inv_backwards_compatibility; + int *gui_draw_order; + std::vector do_once_tokens; + int text_min_display_time_ms; + int ignore_user_input_after_text_timeout_ms; + int default_audio_type_volumes[MAX_AUDIO_TYPES]; + + // Dynamic custom property values for characters and items + std::vector charProps; + AGS::Common::StringIMap invProps[MAX_INV]; + + // Dynamic speech state + // + // Tells whether there is a voice-over played during current speech + bool speech_has_voice; + // Tells whether the voice was played in blocking mode; + // atm blocking speech handles itself, and we only need to finalize + // non-blocking voice speech during game update; speech refactor would be + // required to get rid of this rule. + bool speech_voice_blocking; + // Tells whether character speech stays on screen not animated for additional time + bool speech_in_post_state; + + int shake_screen_yoff; // y offset of the shaking screen + + + GameState(); + // Free game resources + void Free(); + + // + // Viewport and camera control. + // Viewports are positioned in game screen coordinates, related to the "game size", + // while cameras are positioned in room coordinates. + // + // Tells if the room viewport should be adjusted automatically each time a new room is loaded + bool IsAutoRoomViewport() const; + // Returns main viewport position on screen, this is the overall game view + const Rect &GetMainViewport() const; + // Returns UI viewport position on screen, this is the GUI layer + const Rect &GetUIViewport() const; + // Returns Room viewport object by it's main index + PViewport GetRoomViewport(int index) const; + // Returns Room viewport object by index in z-order + const std::vector &GetRoomViewportsZOrdered() const; + // Finds room viewport at the given screen coordinates; returns nullptr if non found + PViewport GetRoomViewportAt(int x, int y) const; + // Returns UI viewport position in absolute coordinates (with main viewport offset) + Rect GetUIViewportAbs() const; + // Returns Room viewport position in absolute coordinates (with main viewport offset) + Rect GetRoomViewportAbs(int index) const; + // Sets if the room viewport should be adjusted automatically each time a new room is loaded + void SetAutoRoomViewport(bool on); + // Main viewport defines the location of all things drawn and interactable on the game screen. + // Other viewports are defined relative to the main viewports. + void SetMainViewport(const Rect &viewport); + // UI viewport is a formal dummy viewport for GUI and Overlays (like speech). + void SetUIViewport(const Rect &viewport); + // Applies all the pending changes to viewports and cameras; + // NOTE: this function may be slow, thus recommended to be called only once + // and during the main game update. + void UpdateViewports(); + // Notifies game state that viewports need z-order resorting upon next update. + void InvalidateViewportZOrder(); + // Returns room camera object chosen by index + PCamera GetRoomCamera(int index) const; + // Runs cameras behaviors + void UpdateRoomCameras(); + // Converts room coordinates to the game screen coordinates through the room viewport + // This group of functions always tries to pass a point through the **primary** room viewport + // TODO: also support using arbitrary viewport (for multiple viewports). + Point RoomToScreen(int roomx, int roomy); + int RoomToScreenX(int roomx); + int RoomToScreenY(int roomy); + // Converts game screen coordinates to the room coordinates through the room viewport + // This pair of functions tries to find if there is any viewport at the given coords and results + // in failure if there is none. + // TODO: find out if possible to refactor and get rid of "variadic" variants; + // usually this depends on how the arguments are created (whether they are in "variadic" or true coords) + VpPoint ScreenToRoom(int scrx, int scry); + VpPoint ScreenToRoomDivDown(int scrx, int scry); // native "variadic" coords variant + + // Makes sure primary viewport and camera are created and linked together + void CreatePrimaryViewportAndCamera(); + // Creates new room viewport + PViewport CreateRoomViewport(); + // Register camera in the managed system; optionally links to existing handle + ScriptViewport *RegisterRoomViewport(int index, int32_t handle = 0); + // Deletes existing room viewport + void DeleteRoomViewport(int index); + // Get number of room viewports + int GetRoomViewportCount() const; + // Creates new room camera + PCamera CreateRoomCamera(); + // Register camera in the managed system; optionally links to existing handle + ScriptCamera *RegisterRoomCamera(int index, int32_t handle = 0); + // Deletes existing room camera + void DeleteRoomCamera(int index); + // Get number of room cameras + int GetRoomCameraCount() const; + // Gets script viewport reference; does NOT increment refcount + // because script interpreter does this when acquiring managed pointer. + ScriptViewport *GetScriptViewport(int index); + // Gets script camera reference; does NOT increment refcount + // because script interpreter does this when acquiring managed pointer. + ScriptCamera *GetScriptCamera(int index); + + // + // User input management + // + // Tells if game should ignore user input right now. Note that some of the parent states + // may not ignore it at the same time, such as cutscene state, which may still be skipped + // with a key press or a mouse button. + bool IsIgnoringInput() const; + // Sets ignore input state, for the given time; if there's one already, chooses max timeout + void SetIgnoreInput(int timeout_ms); + // Clears ignore input state + void ClearIgnoreInput(); + + // + // Voice speech management + // + // Tells if there's a blocking voice speech playing right now + bool IsBlockingVoiceSpeech() const; + // Tells whether we have to finalize voice speech when stopping or reusing the channel + bool IsNonBlockingVoiceSpeech() const; + // Speech helpers + bool ShouldPlayVoiceSpeech() const; + + // + // Serialization + // + void ReadQueuedAudioItems_Aligned(Common::Stream *in); + void ReadCustomProperties_v340(Common::Stream *in); + void WriteCustomProperties_v340(Common::Stream *out) const; + void ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, AGS::Engine::RestoredData &r_data); + void WriteForSavegame(Common::Stream *out) const; + void FreeProperties(); + void FreeViewportsAndCameras(); + +private: + VpPoint ScreenToRoomImpl(int scrx, int scry, int view_index, bool clip_viewport, bool convert_cam_to_data); + void UpdateRoomCamera(int index); + + // Defines if the room viewport should be adjusted to the room size automatically. + bool _isAutoRoomViewport; + // Main viewport defines the rectangle of the drawn and interactable area + // in the most basic case it will be equal to the game size. + Viewport _mainViewport; + // UI viewport defines the render and interaction rectangle of game's UI. + Viewport _uiViewport; + // Room viewports define place on screen where the room camera's + // contents are drawn. + std::vector _roomViewports; + // Vector of viewports sorted in z-order. + std::vector _roomViewportsSorted; + // Cameras defines the position of a "looking eye" inside the room. + std::vector _roomCameras; + // Script viewports and cameras are references to real data export to + // user script. They became invalidated as the actual object gets + // destroyed, but are kept in memory to prevent script errors. + std::vector> _scViewportRefs; + std::vector> _scCameraRefs; + + // Tells that the main viewport's position has changed since last game update + bool _mainViewportHasChanged; + // Tells that room viewports need z-order resort + bool _roomViewportZOrderChanged; + + AGS_Clock::time_point _ignoreUserInputUntilTime; +}; + +// Converts legacy alignment type used in script API +HorAlignment ConvertLegacyScriptAlignment(LegacyScriptAlignment align); +// Reads legacy alignment type from the value set in script depending on the +// current Script API level. This is made to make it possible to change +// Alignment constants in the Script API and still support old version. +HorAlignment ReadScriptAlignment(int32_t align); + +extern GameState play; + +#endif // __AC_GAMESTATE_H diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp new file mode 100644 index 000000000000..f7e6d4474d35 --- /dev/null +++ b/engines/ags/engine/ac/global_api.cpp @@ -0,0 +1,3041 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +#include "ac/cdaudio.h" +#include "ac/display.h" +#include "ac/dynamicsprite.h" +#include "ac/event.h" +#include "ac/game.h" +#include "ac/global_audio.h" +#include "ac/global_button.h" +#include "ac/global_character.h" +#include "ac/global_datetime.h" +#include "ac/global_debug.h" +#include "ac/global_dialog.h" +#include "ac/global_display.h" +#include "ac/global_drawingsurface.h" +#include "ac/global_dynamicsprite.h" +#include "ac/global_file.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/global_hotspot.h" +#include "ac/global_inventoryitem.h" +#include "ac/global_invwindow.h" +#include "ac/global_label.h" +#include "ac/global_listbox.h" +#include "ac/global_mouse.h" +#include "ac/global_object.h" +#include "ac/global_overlay.h" +#include "ac/global_palette.h" +#include "ac/global_parser.h" +#include "ac/global_record.h" +#include "ac/global_region.h" +#include "ac/global_room.h" +#include "ac/global_slider.h" +#include "ac/global_screen.h" +#include "ac/global_string.h" +#include "ac/global_textbox.h" +#include "ac/global_timer.h" +#include "ac/global_translation.h" +#include "ac/global_video.h" +#include "ac/global_viewframe.h" +#include "ac/global_viewport.h" +#include "ac/global_walkablearea.h" +#include "ac/global_walkbehind.h" +#include "ac/math.h" +#include "ac/mouse.h" +#include "ac/parser.h" +#include "ac/string.h" +#include "ac/room.h" +#include "media/video/video.h" +#include "util/string_compat.h" +#include "media/audio/audio_system.h" + +#include "ac/dynobj/scriptstring.h" +extern ScriptString myScriptStringImpl; + +// void (char*texx, ...) +RuntimeScriptValue Sc_sc_AbortGame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(_sc_AbortGame, 1); + _sc_AbortGame(scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (int inum) +RuntimeScriptValue Sc_add_inventory(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(add_inventory); +} + +// void (int charid, int inum) +RuntimeScriptValue Sc_AddInventoryToCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(AddInventoryToCharacter); +} + +// void (int guin, int objn, int view, int loop, int speed, int repeat) +RuntimeScriptValue Sc_AnimateButton(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT6(AnimateButton); +} + +// void (int chh, int loopn, int sppd, int rept) +RuntimeScriptValue Sc_scAnimateCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(scAnimateCharacter); +} + +// void (int chh, int loopn, int sppd, int rept, int direction, int blocking) +RuntimeScriptValue Sc_AnimateCharacterEx(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT6(AnimateCharacterEx); +} + +// void (int obn,int loopn,int spdd,int rept) +RuntimeScriptValue Sc_AnimateObject(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(AnimateObject); +} + +// void (int obn,int loopn,int spdd,int rept, int direction, int blocking) +RuntimeScriptValue Sc_AnimateObjectEx(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT6(AnimateObjectEx); +} + +// int (int cchar1,int cchar2) +RuntimeScriptValue Sc_AreCharactersColliding(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(AreCharactersColliding); +} + +// int (int charid,int objid) +RuntimeScriptValue Sc_AreCharObjColliding(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(AreCharObjColliding); +} + +// int (int obj1,int obj2) +RuntimeScriptValue Sc_AreObjectsColliding(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(AreObjectsColliding); +} + +// int (int thing1, int thing2) +RuntimeScriptValue Sc_AreThingsOverlapping(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(AreThingsOverlapping); +} + +// void (int value) +RuntimeScriptValue Sc_CallRoomScript(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(CallRoomScript); +} + +// int (int cmdd,int datt) +RuntimeScriptValue Sc_cd_manager(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(cd_manager); +} + +// void (int ifn) +RuntimeScriptValue Sc_CentreGUI(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(CentreGUI); +} + +// void (int chaa,int vii) +RuntimeScriptValue Sc_ChangeCharacterView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(ChangeCharacterView); +} + +extern RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *params, int32_t param_count); + +extern RuntimeScriptValue Sc_ChangeCursorHotspot(const RuntimeScriptValue *params, int32_t param_count); + +// void () +RuntimeScriptValue Sc_ClaimEvent(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(ClaimEvent); +} + +// int (int xx,int yy,int slott,int trans) +RuntimeScriptValue Sc_CreateGraphicOverlay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT4(CreateGraphicOverlay); +} + +// int (int xx,int yy,int wii,int fontid,int clr,char*texx, ...) +RuntimeScriptValue Sc_CreateTextOverlay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(CreateTextOverlay, 6); + return RuntimeScriptValue().SetInt32( + CreateTextOverlay(params[0].IValue, params[1].IValue, params[2].IValue, + params[3].IValue, params[4].IValue, scsf_buffer, DISPLAYTEXT_NORMALOVERLAY)); +} + +// void (int strt,int eend) +RuntimeScriptValue Sc_CyclePalette(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(CyclePalette); +} + +// void (int cmdd,int dataa) +RuntimeScriptValue Sc_script_debug(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(script_debug); +} + +// void (int slnum) +RuntimeScriptValue Sc_DeleteSaveSlot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(DeleteSaveSlot); +} + +// void (int gotSlot) +RuntimeScriptValue Sc_free_dynamic_sprite(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(free_dynamic_sprite); +} + +extern RuntimeScriptValue Sc_disable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count); + +// void (int alsoEffects) +RuntimeScriptValue Sc_DisableGroundLevelAreas(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(DisableGroundLevelAreas); +} + +// void (int hsnum) +RuntimeScriptValue Sc_DisableHotspot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(DisableHotspot); +} + +// void () +RuntimeScriptValue Sc_DisableInterface(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(DisableInterface); +} + +// void (int hsnum) +RuntimeScriptValue Sc_DisableRegion(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(DisableRegion); +} + +// void (char*texx, ...) +RuntimeScriptValue Sc_Display(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(Display, 1); + DisplaySimple(scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (int xxp,int yyp,int widd,char*texx, ...) +RuntimeScriptValue Sc_DisplayAt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(DisplayAt, 4); + DisplayAt(params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (int ypos, char *texx) +RuntimeScriptValue Sc_DisplayAtY(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(DisplayAtY, const char); +} + +// void (int msnum) +RuntimeScriptValue Sc_DisplayMessage(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(DisplayMessage); +} + +// void (int msnum, int ypos) +RuntimeScriptValue Sc_DisplayMessageAtY(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(DisplayMessageAtY); +} + +// void (int ypos, int ttexcol, int backcol, char *title, int msgnum) +RuntimeScriptValue Sc_DisplayMessageBar(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3_POBJ_PINT(DisplayMessageBar, const char); +} + +// void (int chid,char*texx, ...) +RuntimeScriptValue Sc_sc_displayspeech(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(DisplayAt, 2); + __sc_displayspeech(params[0].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (int xx, int yy, int wii, int aschar, char*spch) +RuntimeScriptValue Sc_DisplaySpeechAt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4_POBJ(DisplaySpeechAt, const char); +} + +// int (int charid,char*speel) +RuntimeScriptValue Sc_DisplaySpeechBackground(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT_POBJ(DisplaySpeechBackground, const char); +} + +// void (int chid, const char*texx, ...) +RuntimeScriptValue Sc_DisplayThought(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(DisplayThought, 2); + DisplayThought(params[0].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (int ypos, int ttexcol, int backcol, char *title, char*texx, ...) +RuntimeScriptValue Sc_DisplayTopBar(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(DisplayTopBar, 5); + DisplayTopBar(params[0].IValue, params[1].IValue, params[2].IValue, params[3].Ptr, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +extern RuntimeScriptValue Sc_enable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count); + +// void () +RuntimeScriptValue Sc_EnableGroundLevelAreas(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(EnableGroundLevelAreas); +} + +// void (int hsnum) +RuntimeScriptValue Sc_EnableHotspot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(EnableHotspot); +} + +// void () +RuntimeScriptValue Sc_EnableInterface(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(EnableInterface); +} + +// void (int hsnum) +RuntimeScriptValue Sc_EnableRegion(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(EnableRegion); +} + +// int () +RuntimeScriptValue Sc_EndCutscene(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(EndCutscene); +} + +// void (int cha,int toface) +RuntimeScriptValue Sc_FaceCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(FaceCharacter); +} + +// void (int cha, int xx, int yy) +RuntimeScriptValue Sc_FaceLocation(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(FaceLocation); +} + +// void (int sppd) +RuntimeScriptValue Sc_FadeIn(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(FadeIn); +} + +// void (int spdd) +RuntimeScriptValue Sc_my_fade_out(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(my_fade_out); +} + +// void (int handle) +RuntimeScriptValue Sc_FileClose(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(FileClose); +} + +// int (int handle) +RuntimeScriptValue Sc_FileIsEOF(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(FileIsEOF); +} + +// int (int handle) +RuntimeScriptValue Sc_FileIsError(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(FileIsError); +} + +// int (const char*fnmm, const char* cmode) +RuntimeScriptValue Sc_FileOpenCMode(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ2(FileOpenCMode, const char, const char); +} + +// void (int handle,char*toread) +RuntimeScriptValue Sc_FileRead(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(FileRead, char); +} + +// int (int handle) +RuntimeScriptValue Sc_FileReadInt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(FileReadInt); +} + +// char (int handle) +RuntimeScriptValue Sc_FileReadRawChar(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(FileReadRawChar); +} + +// int (int handle) +RuntimeScriptValue Sc_FileReadRawInt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(FileReadRawInt); +} + +// void (int handle, const char *towrite) +RuntimeScriptValue Sc_FileWrite(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(FileWrite, const char); +} + +// void (int handle,int into) +RuntimeScriptValue Sc_FileWriteInt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(FileWriteInt); +} + +// void (int handle, int chartoWrite) +RuntimeScriptValue Sc_FileWriteRawChar(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(FileWriteRawChar); +} + +// void (int handle, const char*towrite) +RuntimeScriptValue Sc_FileWriteRawLine(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(FileWriteRawLine, const char); +} + +// int (const char* GUIName) +RuntimeScriptValue Sc_FindGUIID(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(FindGUIID, const char); +} + +// void (int amount) +RuntimeScriptValue Sc_FlipScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(FlipScreen); +} + +// int (SCRIPT_FLOAT(value), int roundDirection) +RuntimeScriptValue Sc_FloatToInt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PFLOAT_PINT(FloatToInt); +} + +// void (int who, int tofollow) +RuntimeScriptValue Sc_FollowCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(FollowCharacter); +} + +// void (int who, int tofollow, int distaway, int eagerness) +RuntimeScriptValue Sc_FollowCharacterEx(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(FollowCharacterEx); +} + +// int () +RuntimeScriptValue Sc_GetBackgroundFrame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetBackgroundFrame); +} + +// int (int guin, int objn, int ptype) +RuntimeScriptValue Sc_GetButtonPic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT3(GetButtonPic); +} + +// int (int xx, int yy) +RuntimeScriptValue Sc_GetCharIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetCharIDAtScreen); +} + +// int (int cha, const char *property) +RuntimeScriptValue Sc_GetCharacterProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT_POBJ(GetCharacterProperty, const char); +} + +// void (int item, const char *property, char *bufer) +RuntimeScriptValue Sc_GetCharacterPropertyText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ2(GetCharacterPropertyText, const char, char); +} + +// int () +RuntimeScriptValue Sc_GetCurrentMusic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetCurrentMusic); +} + +extern RuntimeScriptValue Sc_GetCursorMode(const RuntimeScriptValue *params, int32_t param_count); + +// int (int dlg, int opt) +RuntimeScriptValue Sc_GetDialogOption(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetDialogOption); +} + +// int (int opt) +RuntimeScriptValue Sc_GetGameOption(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetGameOption); +} + +// int (int parm, int data1, int data2, int data3) +RuntimeScriptValue Sc_GetGameParameter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT4(GetGameParameter); +} + +// int () +RuntimeScriptValue Sc_GetGameSpeed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetGameSpeed); +} + +// int (int index) +RuntimeScriptValue Sc_GetGlobalInt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetGlobalInt); +} + +// void (int index, char *strval) +RuntimeScriptValue Sc_GetGlobalString(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(GetGlobalString, char); +} + +// int (const char *varName) +RuntimeScriptValue Sc_GetGraphicalVariable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(GetGraphicalVariable, const char); +} + +// int (int xx,int yy) +RuntimeScriptValue Sc_GetGUIAt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetGUIAt); +} + +// int (int xx, int yy) +RuntimeScriptValue Sc_GetGUIObjectAt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetGUIObjectAt); +} + +// int (int xxx,int yyy) +RuntimeScriptValue Sc_GetHotspotIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetHotspotIDAtScreen); +} + +// void (int hotspot, char *buffer) +RuntimeScriptValue Sc_GetHotspotName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(GetHotspotName, char); +} + +// int (int hotspot) +RuntimeScriptValue Sc_GetHotspotPointX(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetHotspotPointX); +} + +// int (int hotspot) +RuntimeScriptValue Sc_GetHotspotPointY(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetHotspotPointY); +} + +// int (int hss, const char *property) +RuntimeScriptValue Sc_GetHotspotProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT_POBJ(GetHotspotProperty, const char); +} + +// void (int item, const char *property, char *bufer) +RuntimeScriptValue Sc_GetHotspotPropertyText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ2(GetHotspotPropertyText, const char, char); +} + +// int (int xxx, int yyy) +RuntimeScriptValue Sc_GetInvAt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetInvAt); +} + +// int (int indx) +RuntimeScriptValue Sc_GetInvGraphic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetInvGraphic); +} + +// void (int indx,char*buff) +RuntimeScriptValue Sc_GetInvName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(GetInvName, char); +} + +// int (int item, const char *property) +RuntimeScriptValue Sc_GetInvProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT_POBJ(GetInvProperty, const char); +} + +// void (int item, const char *property, char *bufer) +RuntimeScriptValue Sc_GetInvPropertyText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ2(GetInvPropertyText, const char, char); +} + +// void (int xxx,int yyy,char*tempo) +RuntimeScriptValue Sc_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2_POBJ(GetLocationName, char); +} + +// int (int xxx,int yyy) +RuntimeScriptValue Sc_GetLocationType(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetLocationType); +} + +// void (int msg, char *buffer) +RuntimeScriptValue Sc_GetMessageText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(GetMessageText, char); +} + +// int () +RuntimeScriptValue Sc_GetMIDIPosition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetMIDIPosition); +} + +// int () +RuntimeScriptValue Sc_GetMP3PosMillis(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetMP3PosMillis); +} + +// int (int xx,int yy) +RuntimeScriptValue Sc_GetObjectIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetObjectIDAtScreen); +} + +// int (int obn) +RuntimeScriptValue Sc_GetObjectBaseline(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetObjectBaseline); +} + +// int (int obn) +RuntimeScriptValue Sc_GetObjectGraphic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetObjectGraphic); +} + +// void (int obj, char *buffer) +RuntimeScriptValue Sc_GetObjectName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(GetObjectName, char); +} + +// int (int hss, const char *property) +RuntimeScriptValue Sc_GetObjectProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT_POBJ(GetObjectProperty, const char); +} + +// void (int item, const char *property, char *bufer) +RuntimeScriptValue Sc_GetObjectPropertyText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ2(GetObjectPropertyText, const char, char); +} + +// int (int objj) +RuntimeScriptValue Sc_GetObjectX(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetObjectX); +} + +// int (int objj) +RuntimeScriptValue Sc_GetObjectY(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetObjectY); +} + +// int () +RuntimeScriptValue Sc_GetPlayerCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetPlayerCharacter); +} + +// int () +RuntimeScriptValue Sc_GetRawTime(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetRawTime); +} + +// int (int xxx, int yyy) +RuntimeScriptValue Sc_GetRegionIDAtRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetRegionIDAtRoom); +} + +// void (const char *property, char *bufer) +RuntimeScriptValue Sc_GetRoomPropertyText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_POBJ2(GetRoomPropertyText, const char, char); +} + +// int (int slnum,char*desbuf) +RuntimeScriptValue Sc_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT_POBJ(GetSaveSlotDescription, char); +} + +// int (int x, int y) +RuntimeScriptValue Sc_GetScalingAt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetScalingAt); +} + +// int (int guin,int objn) +RuntimeScriptValue Sc_GetSliderValue(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetSliderValue); +} + +// void (int guin, int objn, char*txbuf) +RuntimeScriptValue Sc_GetTextBoxText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2_POBJ(GetTextBoxText, char); +} + +// int (char *text, int fontnum, int width) +RuntimeScriptValue Sc_GetTextHeight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ_PINT2(GetTextHeight, const char); +} + +// int (char *text, int fontnum) +RuntimeScriptValue Sc_GetTextWidth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ_PINT(GetTextWidth, const char); +} + +RuntimeScriptValue Sc_GetFontHeight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetFontHeight); +} + +RuntimeScriptValue Sc_GetFontLineSpacing(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(GetFontLineSpacing); +} + +// int (int whatti) +RuntimeScriptValue Sc_sc_GetTime(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(sc_GetTime); +} + +// char * (const char *text) +RuntimeScriptValue Sc_get_translation(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_POBJ(char, myScriptStringImpl, get_translation, const char); +} + +// int (char* buffer) +RuntimeScriptValue Sc_GetTranslationName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(GetTranslationName, char); +} + +// int () +RuntimeScriptValue Sc_GetViewportX(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetViewportX); +} + +// int () +RuntimeScriptValue Sc_GetViewportY(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetViewportY); +} + +RuntimeScriptValue Sc_GetWalkableAreaAtRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetWalkableAreaAtRoom); +} + +// int (int xxx,int yyy) +RuntimeScriptValue Sc_GetWalkableAreaAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(GetWalkableAreaAtScreen); +} + +RuntimeScriptValue Sc_GetDrawingSurfaceForWalkableArea(const RuntimeScriptValue *params, int32_t param_count) +{ + ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkable); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +} + +RuntimeScriptValue Sc_GetDrawingSurfaceForWalkbehind(const RuntimeScriptValue *params, int32_t param_count) +{ + ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkBehind); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +} + +// void (int amnt) +RuntimeScriptValue Sc_GiveScore(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(GiveScore); +} + +// int (int roomnum) +RuntimeScriptValue Sc_HasPlayerBeenInRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(HasPlayerBeenInRoom); +} + +// void () +RuntimeScriptValue Sc_HideMouseCursor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(HideMouseCursor); +} + +// void (const char*msg,char*bufr) +RuntimeScriptValue Sc_sc_inputbox(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_POBJ2(sc_inputbox, const char, char); +} + +// void (int ifn) +RuntimeScriptValue Sc_InterfaceOff(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(InterfaceOff); +} + +// void (int ifn) +RuntimeScriptValue Sc_InterfaceOn(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(InterfaceOn); +} + +// FLOAT_RETURN_TYPE (int value) +RuntimeScriptValue Sc_IntToFloat(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PINT(IntToFloat); +} + +// void () +RuntimeScriptValue Sc_sc_invscreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(sc_invscreen); +} + +extern RuntimeScriptValue Sc_IsButtonDown(const RuntimeScriptValue *params, int32_t param_count); + +// int (int chan) +RuntimeScriptValue Sc_IsChannelPlaying(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsChannelPlaying); +} + +// int () +RuntimeScriptValue Sc_IsGamePaused(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(IsGamePaused); +} + +// int (int guinum) +RuntimeScriptValue Sc_IsGUIOn(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsGUIOn); +} + +// int (int xx,int yy,int mood) +RuntimeScriptValue Sc_IsInteractionAvailable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT3(IsInteractionAvailable); +} + +// int (int item, int mood) +RuntimeScriptValue Sc_IsInventoryInteractionAvailable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(IsInventoryInteractionAvailable); +} + +// int () +RuntimeScriptValue Sc_IsInterfaceEnabled(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(IsInterfaceEnabled); +} + +// int (int keycode) +RuntimeScriptValue Sc_IsKeyPressed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsKeyPressed); +} + +// int () +RuntimeScriptValue Sc_IsMusicPlaying(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(IsMusicPlaying); +} + +// int () +RuntimeScriptValue Sc_IsMusicVoxAvailable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(IsMusicVoxAvailable); +} + +// int (int objj) +RuntimeScriptValue Sc_IsObjectAnimating(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsObjectAnimating); +} + +// int (int objj) +RuntimeScriptValue Sc_IsObjectMoving(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsObjectMoving); +} + +// int (int objj) +RuntimeScriptValue Sc_IsObjectOn(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsObjectOn); +} + +// int (int ovrid) +RuntimeScriptValue Sc_IsOverlayValid(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsOverlayValid); +} + +// int () +RuntimeScriptValue Sc_IsSoundPlaying(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(IsSoundPlaying); +} + +// int (int tnum) +RuntimeScriptValue Sc_IsTimerExpired(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsTimerExpired); +} + +// int () +RuntimeScriptValue Sc_IsTranslationAvailable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(IsTranslationAvailable); +} + +// int () +RuntimeScriptValue Sc_IsVoxAvailable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(IsVoxAvailable); +} + +// void (int guin, int objn, const char*newitem) +RuntimeScriptValue Sc_ListBoxAdd(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2_POBJ(ListBoxAdd, const char); +} + +// void (int guin, int objn) +RuntimeScriptValue Sc_ListBoxClear(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(ListBoxClear); +} + +// void (int guin, int objn, const char*filemask) +RuntimeScriptValue Sc_ListBoxDirList(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2_POBJ(ListBoxDirList, const char); +} + +// char* (int guin, int objn, int item, char*buffer) +RuntimeScriptValue Sc_ListBoxGetItemText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT3_POBJ(char, myScriptStringImpl, ListBoxGetItemText, char); +} + +// int (int guin, int objn) +RuntimeScriptValue Sc_ListBoxGetNumItems(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(ListBoxGetNumItems); +} + +// int (int guin, int objn) +RuntimeScriptValue Sc_ListBoxGetSelected(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(ListBoxGetSelected); +} + +// void (int guin, int objn, int itemIndex) +RuntimeScriptValue Sc_ListBoxRemove(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(ListBoxRemove); +} + +// int (int guin, int objn) +RuntimeScriptValue Sc_ListBoxSaveGameList(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(ListBoxSaveGameList); +} + +// void (int guin, int objn, int newsel) +RuntimeScriptValue Sc_ListBoxSetSelected(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(ListBoxSetSelected); +} + +// void (int guin, int objn, int item) +RuntimeScriptValue Sc_ListBoxSetTopItem(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(ListBoxSetTopItem); +} + +// int (const char *filename) +RuntimeScriptValue Sc_LoadImageFile(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(LoadImageFile, const char); +} + +// int (int slnum, int width, int height) +RuntimeScriptValue Sc_LoadSaveSlotScreenshot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT3(LoadSaveSlotScreenshot); +} + +// void (int inum) +RuntimeScriptValue Sc_lose_inventory(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(lose_inventory); +} + +// void (int charid, int inum) +RuntimeScriptValue Sc_LoseInventoryFromCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(LoseInventoryFromCharacter); +} + +// void (int obn) +RuntimeScriptValue Sc_MergeObject(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(MergeObject); +} + +// void (int cc,int xx,int yy) +RuntimeScriptValue Sc_MoveCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(MoveCharacter); +} + +// void (int chaa,int xx,int yy,int direct) +RuntimeScriptValue Sc_MoveCharacterBlocking(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(MoveCharacterBlocking); +} + +// void (int cc,int xx, int yy) +RuntimeScriptValue Sc_MoveCharacterDirect(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(MoveCharacterDirect); +} + +// void (int chac, int tox, int toy) +RuntimeScriptValue Sc_MoveCharacterPath(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(MoveCharacterPath); +} + +// void (int cc,int xx, int yy) +RuntimeScriptValue Sc_MoveCharacterStraight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(MoveCharacterStraight); +} + +// void (int chaa,int hotsp) +RuntimeScriptValue Sc_MoveCharacterToHotspot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(MoveCharacterToHotspot); +} + +// void (int chaa,int obbj) +RuntimeScriptValue Sc_MoveCharacterToObject(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(MoveCharacterToObject); +} + +// void (int objj,int xx,int yy,int spp) +RuntimeScriptValue Sc_MoveObject(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(MoveObject); +} + +// void (int objj,int xx,int yy,int spp) +RuntimeScriptValue Sc_MoveObjectDirect(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(MoveObjectDirect); +} + +// void (int ovrid, int newx,int newy) +RuntimeScriptValue Sc_MoveOverlay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(MoveOverlay); +} + +// void (int charid) +RuntimeScriptValue Sc_MoveToWalkableArea(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(MoveToWalkableArea); +} + +// void (int nrnum) +RuntimeScriptValue Sc_NewRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(NewRoom); +} + +// void (int nrnum,int newx,int newy) +RuntimeScriptValue Sc_NewRoomEx(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(NewRoomEx); +} + +// void (int charid, int nrnum, int newx, int newy) +RuntimeScriptValue Sc_NewRoomNPC(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(NewRoomNPC); +} + +// void (int obn) +RuntimeScriptValue Sc_ObjectOff(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(ObjectOff); +} + +// void (int obn) +RuntimeScriptValue Sc_ObjectOn(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(ObjectOn); +} + +extern RuntimeScriptValue Sc_ParseText(const RuntimeScriptValue *params, int32_t param_count); + +// void () +RuntimeScriptValue Sc_PauseGame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(PauseGame); +} + +// void (int channel, int sndnum, int vol, int x, int y) +RuntimeScriptValue Sc_PlayAmbientSound(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT5(PlayAmbientSound); +} + +// void (int numb,int playflags) +RuntimeScriptValue Sc_play_flc_file(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(play_flc_file); +} + +// void (char *filename) +RuntimeScriptValue Sc_PlayMP3File(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_POBJ(PlayMP3File, const char); +} + +// void (int newmus) +RuntimeScriptValue Sc_PlayMusicResetQueue(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(PlayMusicResetQueue); +} + +// int (int musnum) +RuntimeScriptValue Sc_PlayMusicQueued(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(PlayMusicQueued); +} + +// void (int mnum) +RuntimeScriptValue Sc_PlaySilentMIDI(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(PlaySilentMIDI); +} + +// int (int val1) +RuntimeScriptValue Sc_play_sound(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(play_sound); +} + +// int (int val1, int channel) +RuntimeScriptValue Sc_PlaySoundEx(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(PlaySoundEx); +} + +// void (const char* name, int skip, int flags) +RuntimeScriptValue Sc_scrPlayVideo(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_POBJ_PINT2(scrPlayVideo, const char); +} + +// void (int dialog) +RuntimeScriptValue Sc_QuitGame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(QuitGame); +} + +// int (int upto) +RuntimeScriptValue Sc_Rand(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(__Rand); +} + +// void (int clr) +RuntimeScriptValue Sc_RawClear(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RawClear); +} + +// void (int xx, int yy, int rad) +RuntimeScriptValue Sc_RawDrawCircle(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(RawDrawCircle); +} + +// void (int frame, int translev) +RuntimeScriptValue Sc_RawDrawFrameTransparent(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(RawDrawFrameTransparent); +} + +// void (int xx, int yy, int slot) +RuntimeScriptValue Sc_RawDrawImage(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(RawDrawImage); +} + +// void (int xx, int yy, int slot) +RuntimeScriptValue Sc_RawDrawImageOffset(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(RawDrawImageOffset); +} + +// void (int xx, int yy, int gotSlot, int width, int height) +RuntimeScriptValue Sc_RawDrawImageResized(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT5(RawDrawImageResized); +} + +// void (int xx, int yy, int slot, int trans) +RuntimeScriptValue Sc_RawDrawImageTransparent(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(RawDrawImageTransparent); +} + +// void (int fromx, int fromy, int tox, int toy) +RuntimeScriptValue Sc_RawDrawLine(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(RawDrawLine); +} + +// void (int x1, int y1, int x2, int y2) +RuntimeScriptValue Sc_RawDrawRectangle(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(RawDrawRectangle); +} + +// void (int x1, int y1, int x2, int y2, int x3, int y3) +RuntimeScriptValue Sc_RawDrawTriangle(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT6(RawDrawTriangle); +} + +// void (int xx, int yy, char*texx, ...) +RuntimeScriptValue Sc_RawPrint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(RawPrint, 3); + RawPrint(params[0].IValue, params[1].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (int xx, int yy, int wid, int font, int msgm) +RuntimeScriptValue Sc_RawPrintMessageWrapped(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT5(RawPrintMessageWrapped); +} + +// void () +RuntimeScriptValue Sc_RawRestoreScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(RawRestoreScreen); +} + +// void (int red, int green, int blue, int opacity) +RuntimeScriptValue Sc_RawRestoreScreenTinted(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(RawRestoreScreenTinted); +} + +// void () +RuntimeScriptValue Sc_RawSaveScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(RawSaveScreen); +} + +// void (int clr) +RuntimeScriptValue Sc_RawSetColor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RawSetColor); +} + +// void (int red, int grn, int blu) +RuntimeScriptValue Sc_RawSetColorRGB(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(RawSetColorRGB); +} + +extern RuntimeScriptValue Sc_RefreshMouse(const RuntimeScriptValue *params, int32_t param_count); + +// void (int chat) +RuntimeScriptValue Sc_ReleaseCharacterView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(ReleaseCharacterView); +} + +// void () +RuntimeScriptValue Sc_ReleaseViewport(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(ReleaseViewport); +} + +// void (int obj) +RuntimeScriptValue Sc_RemoveObjectTint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RemoveObjectTint); +} + +// void (int ovrid) +RuntimeScriptValue Sc_RemoveOverlay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RemoveOverlay); +} + +// void (int areanum) +RuntimeScriptValue Sc_RemoveWalkableArea(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RemoveWalkableArea); +} + +// void (int nrnum) +RuntimeScriptValue Sc_ResetRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(ResetRoom); +} + +// void () +RuntimeScriptValue Sc_restart_game(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(restart_game); +} + +// void () +RuntimeScriptValue Sc_restore_game_dialog(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(restore_game_dialog); +} + +// void (int slnum) +RuntimeScriptValue Sc_RestoreGameSlot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RestoreGameSlot); +} + +// void (int areanum) +RuntimeScriptValue Sc_RestoreWalkableArea(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RestoreWalkableArea); +} + +// int (char *newgame, unsigned int mode, int data) +RuntimeScriptValue Sc_RunAGSGame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ_PINT2(RunAGSGame, const char); +} + +// void (int cc, int mood) +RuntimeScriptValue Sc_RunCharacterInteraction(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(RunCharacterInteraction); +} + +// void (int tum) +RuntimeScriptValue Sc_RunDialog(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(RunDialog); +} + +// void (int hotspothere, int mood) +RuntimeScriptValue Sc_RunHotspotInteraction(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(RunHotspotInteraction); +} + +// void (int iit, int modd) +RuntimeScriptValue Sc_RunInventoryInteraction(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(RunInventoryInteraction); +} + +// void (int aa, int mood) +RuntimeScriptValue Sc_RunObjectInteraction(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(RunObjectInteraction); +} + +// void (int regnum, int mood) +RuntimeScriptValue Sc_RunRegionInteraction(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(RunRegionInteraction); +} + +extern RuntimeScriptValue Sc_Said(const RuntimeScriptValue *params, int32_t param_count); + +// int (char*buffer) +RuntimeScriptValue Sc_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(SaidUnknownWord, char); +} + +extern RuntimeScriptValue Sc_SaveCursorForLocationChange(const RuntimeScriptValue *params, int32_t param_count); + +// void () +RuntimeScriptValue Sc_save_game_dialog(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(save_game_dialog); +} + +// void (int slotn, const char*descript) +RuntimeScriptValue Sc_save_game(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(save_game, const char); +} + +// int (char*namm) +RuntimeScriptValue Sc_SaveScreenShot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(SaveScreenShot, const char); +} + +// void (int position) +RuntimeScriptValue Sc_SeekMIDIPosition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SeekMIDIPosition); +} + +// void (int patnum) +RuntimeScriptValue Sc_SeekMODPattern(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SeekMODPattern); +} + +// void (int posn) +RuntimeScriptValue Sc_SeekMP3PosMillis(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SeekMP3PosMillis); +} + +// void (int iit) +RuntimeScriptValue Sc_SetActiveInventory(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetActiveInventory); +} + +// void (int red, int green, int blue, int opacity, int luminance) +RuntimeScriptValue Sc_SetAmbientTint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT5(SetAmbientTint); +} + +RuntimeScriptValue Sc_SetAmbientLightLevel(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetAmbientLightLevel); +} + +// void (int area, int brightness) +RuntimeScriptValue Sc_SetAreaLightLevel(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetAreaLightLevel); +} + +// void (int area, int min, int max) +RuntimeScriptValue Sc_SetAreaScaling(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetAreaScaling); +} + +// void (int frnum) +RuntimeScriptValue Sc_SetBackgroundFrame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetBackgroundFrame); +} + +// void (int guin,int objn,int ptype,int slotn) +RuntimeScriptValue Sc_SetButtonPic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetButtonPic); +} + +// void (int guin,int objn,char*newtx) +RuntimeScriptValue Sc_SetButtonText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2_POBJ(SetButtonText, const char); +} + +// void (int chan, int newvol) +RuntimeScriptValue Sc_SetChannelVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetChannelVolume); +} + +// void (int obn, int basel) +RuntimeScriptValue Sc_SetCharacterBaseline(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterBaseline); +} + +// void (int cha, int clik) +RuntimeScriptValue Sc_SetCharacterClickable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterClickable); +} + +// void (int chaa, int view, int loop, int frame) +RuntimeScriptValue Sc_SetCharacterFrame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetCharacterFrame); +} + +// void (int who, int iview, int itime) +RuntimeScriptValue Sc_SetCharacterIdle(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetCharacterIdle); +} + +// void (int who, int yesorno) +RuntimeScriptValue Sc_SetCharacterIgnoreLight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterIgnoreLight); +} + +// void (int cha, int clik) +RuntimeScriptValue Sc_SetCharacterIgnoreWalkbehinds(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterIgnoreWalkbehinds); +} + +// void (int who, int flag, int yesorno) +RuntimeScriptValue Sc_SetCharacterProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetCharacterProperty); +} + +// void (int chaa, int vii, int intrv) +RuntimeScriptValue Sc_SetCharacterBlinkView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetCharacterBlinkView); +} + +// void (int chaa, int vii) +RuntimeScriptValue Sc_SetCharacterSpeechView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterSpeechView); +} + +// void (int chaa,int nspeed) +RuntimeScriptValue Sc_SetCharacterSpeed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterSpeed); +} + +// void (int chaa, int xspeed, int yspeed) +RuntimeScriptValue Sc_SetCharacterSpeedEx(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetCharacterSpeedEx); +} + +// void (int obn,int trans) +RuntimeScriptValue Sc_SetCharacterTransparency(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterTransparency); +} + +// void (int chaa,int vii) +RuntimeScriptValue Sc_SetCharacterView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetCharacterView); +} + +// void (int chaa, int vii, int loop, int align) +RuntimeScriptValue Sc_SetCharacterViewEx(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetCharacterViewEx); +} + +// void (int chaa, int vii, int xoffs, int yoffs) +RuntimeScriptValue Sc_SetCharacterViewOffset(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetCharacterViewOffset); +} + +extern RuntimeScriptValue Sc_set_cursor_mode(const RuntimeScriptValue *params, int32_t param_count); +extern RuntimeScriptValue Sc_set_default_cursor(const RuntimeScriptValue *params, int32_t param_count); + +// void (int dlg,int opt,int onoroff) +RuntimeScriptValue Sc_SetDialogOption(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetDialogOption); +} + +// void (int newvol) +RuntimeScriptValue Sc_SetDigitalMasterVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetDigitalMasterVolume); +} + +// void (int red, int green, int blue) +RuntimeScriptValue Sc_SetFadeColor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetFadeColor); +} + +// void (int vii, int loop, int frame, int sound) +RuntimeScriptValue Sc_SetFrameSound(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetFrameSound); +} + +// int (int opt, int setting) +RuntimeScriptValue Sc_SetGameOption(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT2(SetGameOption); +} + +// void (int newspd) +RuntimeScriptValue Sc_SetGameSpeed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetGameSpeed); +} + +// void (int index,int valu) +RuntimeScriptValue Sc_SetGlobalInt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetGlobalInt); +} + +extern RuntimeScriptValue Sc_SetGlobalString(const RuntimeScriptValue *params, int32_t param_count); + +// void (const char *varName, int p_value) +RuntimeScriptValue Sc_SetGraphicalVariable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_POBJ_PINT(SetGraphicalVariable, const char); +} + +// void (int guin, int slotn) +RuntimeScriptValue Sc_SetGUIBackgroundPic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetGUIBackgroundPic); +} + +// void (int guin, int clickable) +RuntimeScriptValue Sc_SetGUIClickable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetGUIClickable); +} + +// void (int guin, int objn, int enabled) +RuntimeScriptValue Sc_SetGUIObjectEnabled(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetGUIObjectEnabled); +} + +// void (int guin, int objn, int xx, int yy) +RuntimeScriptValue Sc_SetGUIObjectPosition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetGUIObjectPosition); +} + +// void (int ifn, int objn, int newwid, int newhit) +RuntimeScriptValue Sc_SetGUIObjectSize(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetGUIObjectSize); +} + +// void (int ifn,int xx,int yy) +RuntimeScriptValue Sc_SetGUIPosition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetGUIPosition); +} + +// void (int ifn, int widd, int hitt) +RuntimeScriptValue Sc_SetGUISize(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetGUISize); +} + +// void (int ifn, int trans) +RuntimeScriptValue Sc_SetGUITransparency(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetGUITransparency); +} + +// void (int guin, int z) +RuntimeScriptValue Sc_SetGUIZOrder(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetGUIZOrder); +} + +// void (int invi, const char *newName) +RuntimeScriptValue Sc_SetInvItemName(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT_POBJ(SetInvItemName, const char); +} + +// void (int invi, int piccy) +RuntimeScriptValue Sc_set_inv_item_pic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(set_inv_item_pic); +} + +// void (int ww,int hh) +RuntimeScriptValue Sc_SetInvDimensions(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetInvDimensions); +} + +// void (int guin,int objn, int colr) +RuntimeScriptValue Sc_SetLabelColor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetLabelColor); +} + +// void (int guin,int objn, int fontnum) +RuntimeScriptValue Sc_SetLabelFont(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetLabelFont); +} + +// void (int guin,int objn,char*newtx) +RuntimeScriptValue Sc_SetLabelText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2_POBJ(SetLabelText, const char); +} + +extern RuntimeScriptValue Sc_SetMouseBounds(const RuntimeScriptValue *params, int32_t param_count); +extern RuntimeScriptValue Sc_set_mouse_cursor(const RuntimeScriptValue *params, int32_t param_count); +extern RuntimeScriptValue Sc_SetMousePosition(const RuntimeScriptValue *params, int32_t param_count); + +// void (int mode) +RuntimeScriptValue Sc_SetMultitasking(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetMultitasking); +} + +// void (int newvol) +RuntimeScriptValue Sc_SetMusicMasterVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetMusicMasterVolume); +} + +// void (int loopflag) +RuntimeScriptValue Sc_SetMusicRepeat(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetMusicRepeat); +} + +// void (int newvol) +RuntimeScriptValue Sc_SetMusicVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetMusicVolume); +} + +extern RuntimeScriptValue Sc_SetNextCursor(const RuntimeScriptValue *params, int32_t param_count); + +// void (int newtrans) +RuntimeScriptValue Sc_SetNextScreenTransition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetNextScreenTransition); +} + +extern RuntimeScriptValue Sc_SetNormalFont(const RuntimeScriptValue *params, int32_t param_count); + +// void (int obn, int basel) +RuntimeScriptValue Sc_SetObjectBaseline(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetObjectBaseline); +} + +// void (int cha, int clik) +RuntimeScriptValue Sc_SetObjectClickable(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetObjectClickable); +} + +// void (int obn,int viw,int lop,int fra) +RuntimeScriptValue Sc_SetObjectFrame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetObjectFrame); +} + +// void (int obn,int slott) +RuntimeScriptValue Sc_SetObjectGraphic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetObjectGraphic); +} + +// void (int cha, int clik) +RuntimeScriptValue Sc_SetObjectIgnoreWalkbehinds(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetObjectIgnoreWalkbehinds); +} + +// void (int objj, int tox, int toy) +RuntimeScriptValue Sc_SetObjectPosition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetObjectPosition); +} + +// void (int obj, int red, int green, int blue, int opacity, int luminance) +RuntimeScriptValue Sc_SetObjectTint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT6(SetObjectTint); +} + +// void (int obn,int trans) +RuntimeScriptValue Sc_SetObjectTransparency(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetObjectTransparency); +} + +// void (int obn,int vii) +RuntimeScriptValue Sc_SetObjectView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetObjectView); +} + +// void (int inndx,int rr,int gg,int bb) +RuntimeScriptValue Sc_SetPalRGB(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetPalRGB); +} + +// void (int newchar) +RuntimeScriptValue Sc_SetPlayerCharacter(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetPlayerCharacter); +} + +// void (int area, int red, int green, int blue, int amount) +RuntimeScriptValue Sc_SetRegionTint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT5(SetRegionTint); +} + +// void () +RuntimeScriptValue Sc_SetRestartPoint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(SetRestartPoint); +} + +// void (int newtrans) +RuntimeScriptValue Sc_SetScreenTransition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetScreenTransition); +} + +// void (int newval) +RuntimeScriptValue Sc_SetSkipSpeech(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_PARAM_COUNT(SetSkipSpeech, 1); + SetSkipSpeech((SkipSpeechStyle)params[0].IValue); + return RuntimeScriptValue((int32_t)0); +} + +// void (int guin,int objn, int valn) +RuntimeScriptValue Sc_SetSliderValue(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetSliderValue); +} + +// void (int newvol) +RuntimeScriptValue Sc_SetSoundVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetSoundVolume); +} + +extern RuntimeScriptValue Sc_SetSpeechFont(const RuntimeScriptValue *params, int32_t param_count); + +// void (int newstyle) +RuntimeScriptValue Sc_SetSpeechStyle(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetSpeechStyle); +} + +// void (int newvol) +RuntimeScriptValue Sc_SetSpeechVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetSpeechVolume); +} + +// void (int chaa,int ncol) +RuntimeScriptValue Sc_SetTalkingColor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetTalkingColor); +} + +// void (int guin,int objn, int fontnum) +RuntimeScriptValue Sc_SetTextBoxFont(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(SetTextBoxFont); +} + +// void (int guin, int objn, char*txbuf) +RuntimeScriptValue Sc_SetTextBoxText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2_POBJ(SetTextBoxText, const char); +} + +// void (int ovrid,int xx,int yy,int wii,int fontid,int clr,char*texx,...) +RuntimeScriptValue Sc_SetTextOverlay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(SetTextOverlay, 7); + SetTextOverlay(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, + params[4].IValue, params[5].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (int guinum) +RuntimeScriptValue Sc_SetTextWindowGUI(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetTextWindowGUI); +} + +// void (int tnum,int timeout) +RuntimeScriptValue Sc_script_SetTimer(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(script_SetTimer); +} + +// void (int offsx,int offsy) +RuntimeScriptValue Sc_SetViewport(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetViewport); +} + +// void (int newmod) +RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SetVoiceMode); +} + +// void (int wa,int bl) +RuntimeScriptValue Sc_SetWalkBehindBase(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetWalkBehindBase); +} + +// void (int severe) +RuntimeScriptValue Sc_ShakeScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(ShakeScreen); +} + +// void (int delay, int amount, int length) +RuntimeScriptValue Sc_ShakeScreenBackground(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(ShakeScreenBackground); +} + +// void () +RuntimeScriptValue Sc_ShowMouseCursor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(ShowMouseCursor); +} + +RuntimeScriptValue Sc_SkipCutscene(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(SkipCutscene); +} + +// void (int cc) +RuntimeScriptValue Sc_SkipUntilCharacterStops(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(SkipUntilCharacterStops); +} + +// void (int skipwith) +RuntimeScriptValue Sc_StartCutscene(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(StartCutscene); +} + +// void (int keyToStop) +RuntimeScriptValue Sc_scStartRecording(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(scStartRecording); +} + +// void (int channel) +RuntimeScriptValue Sc_StopAmbientSound(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(StopAmbientSound); +} + +// void (int chid) +RuntimeScriptValue Sc_stop_and_destroy_channel(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(stop_and_destroy_channel); +} + +// void () +RuntimeScriptValue Sc_StopDialog(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(StopDialog); +} + +// void (int chaa) +RuntimeScriptValue Sc_StopMoving(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(StopMoving); +} + +// void () +RuntimeScriptValue Sc_scr_StopMusic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(scr_StopMusic); +} + +// void (int objj) +RuntimeScriptValue Sc_StopObjectMoving(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(StopObjectMoving); +} + +// void (char*s1,char*s2) +RuntimeScriptValue Sc_sc_strcat(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_PARAM_COUNT(_sc_strcat, 2); + _sc_strcat((char*)params[0].Ptr, (const char*)params[1].Ptr); + // NOTE: tests with old (<= 2.60) AGS show that StrCat returned the second string + // (could be result of UB, but we are doing this for more accurate emulation) + return params[1]; +} + +RuntimeScriptValue Sc_stricmp(const RuntimeScriptValue *params, int32_t param_count) +{ + // Calling C stdlib function ags_stricmp + API_SCALL_INT_POBJ2(ags_stricmp, const char, const char); +} + +RuntimeScriptValue Sc_strcmp(const RuntimeScriptValue *params, int32_t param_count) +{ + // Calling C stdlib function strcmp + API_SCALL_INT_POBJ2(strcmp, const char, const char); +} + +// int (const char *s1, const char *s2) +RuntimeScriptValue Sc_StrContains(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ2(StrContains, const char, const char); +} + +// void (char*s1, const char*s2); +RuntimeScriptValue Sc_sc_strcpy(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_PARAM_COUNT(_sc_strcpy, 2); + _sc_strcpy((char*)params[0].Ptr, (const char*)params[1].Ptr); + return params[0]; +} + +// void (char*destt, const char*texx, ...); +RuntimeScriptValue Sc_sc_sprintf(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(_sc_sprintf, 2); + _sc_strcpy(params[0].Ptr, scsf_buffer); + return params[0]; +} + +// int (char *strin, int posn) +RuntimeScriptValue Sc_StrGetCharAt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ_PINT(StrGetCharAt, const char); +} + +// int (const char*stino) +RuntimeScriptValue Sc_StringToInt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(StringToInt, const char); +} + +RuntimeScriptValue Sc_strlen(const RuntimeScriptValue *params, int32_t param_count) +{ + // Calling C stdlib function strlen + API_SCALL_INT_POBJ(strlen, const char); +} + +// void (char *strin, int posn, int nchar) +RuntimeScriptValue Sc_StrSetCharAt(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_PARAM_COUNT(StrSetCharAt, 3); + StrSetCharAt((char*)params[0].Ptr, params[1].IValue, params[2].IValue); + return params[0]; +} + +// void (char *desbuf) +RuntimeScriptValue Sc_sc_strlower(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_PARAM_COUNT(_sc_strlower, 1); + _sc_strlower((char*)params[0].Ptr); + return params[0]; +} + +// void (char *desbuf) +RuntimeScriptValue Sc_sc_strupper(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_PARAM_COUNT(_sc_strupper, 1); + _sc_strupper((char*)params[0].Ptr); + return params[0]; +} + +// void (int red, int grn, int blu) +RuntimeScriptValue Sc_TintScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(TintScreen); +} + +// void () +RuntimeScriptValue Sc_UnPauseGame(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(UnPauseGame); +} + +// void () +RuntimeScriptValue Sc_update_invorder(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(update_invorder); +} + +// void () +RuntimeScriptValue Sc_UpdatePalette(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(UpdatePalette); +} + +// void (int nloops) +RuntimeScriptValue Sc_scrWait(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(scrWait); +} + +// int (int nloops) +RuntimeScriptValue Sc_WaitKey(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(WaitKey); +} + +RuntimeScriptValue Sc_WaitMouse(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(WaitMouse); +} + +// int (int nloops) +RuntimeScriptValue Sc_WaitMouseKey(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(WaitMouseKey); +} + +RuntimeScriptValue Sc_SkipWait(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(SkipWait); +} + +//============================================================================= +// +// Exclusive API for Plugins +// +//============================================================================= + +// void (char*texx, ...) +void ScPl_sc_AbortGame(const char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + _sc_AbortGame(scsf_buffer); +} + +// int (int xx,int yy,int wii,int fontid,int clr,char*texx, ...) +int ScPl_CreateTextOverlay(int xx, int yy, int wii, int fontid, int clr, char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + return CreateTextOverlay(xx, yy, wii, fontid, clr, scsf_buffer, DISPLAYTEXT_NORMALOVERLAY); +} + +// void (char*texx, ...) +void ScPl_Display(char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplaySimple(scsf_buffer); +} + +// void (int xxp,int yyp,int widd,char*texx, ...) +void ScPl_DisplayAt(int xxp, int yyp, int widd, char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplayAt(xxp, yyp, widd, scsf_buffer); +} + +// void (int chid,char*texx, ...) +void ScPl_sc_displayspeech(int chid, char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + __sc_displayspeech(chid, scsf_buffer); +} + +// void (int chid, const char*texx, ...) +void ScPl_DisplayThought(int chid, const char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplayThought(chid, scsf_buffer); +} + +// void (int ypos, int ttexcol, int backcol, char *title, char*texx, ...) +void ScPl_DisplayTopBar(int ypos, int ttexcol, int backcol, char *title, char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplayTopBar(ypos, ttexcol, backcol, title, scsf_buffer); +} + +// void (int xx, int yy, char*texx, ...) +void ScPl_RawPrint(int xx, int yy, char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + RawPrint(xx, yy, scsf_buffer); +} + +// void (int ovrid,int xx,int yy,int wii,int fontid,int clr,char*texx,...) +void ScPl_SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int clr, char*texx,...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + SetTextOverlay(ovrid, xx, yy, wii, fontid, clr, scsf_buffer); +} + +// void (char*destt, const char*texx, ...); +void ScPl_sc_sprintf(char *destt, const char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + _sc_strcpy(destt, scsf_buffer); +} + + +void RegisterGlobalAPI() +{ + ccAddExternalStaticFunction("AbortGame", Sc_sc_AbortGame); + ccAddExternalStaticFunction("AddInventory", Sc_add_inventory); + ccAddExternalStaticFunction("AddInventoryToCharacter", Sc_AddInventoryToCharacter); + ccAddExternalStaticFunction("AnimateButton", Sc_AnimateButton); + ccAddExternalStaticFunction("AnimateCharacter", Sc_scAnimateCharacter); + ccAddExternalStaticFunction("AnimateCharacterEx", Sc_AnimateCharacterEx); + ccAddExternalStaticFunction("AnimateObject", Sc_AnimateObject); + ccAddExternalStaticFunction("AnimateObjectEx", Sc_AnimateObjectEx); + ccAddExternalStaticFunction("AreCharactersColliding", Sc_AreCharactersColliding); + ccAddExternalStaticFunction("AreCharObjColliding", Sc_AreCharObjColliding); + ccAddExternalStaticFunction("AreObjectsColliding", Sc_AreObjectsColliding); + ccAddExternalStaticFunction("AreThingsOverlapping", Sc_AreThingsOverlapping); + ccAddExternalStaticFunction("CallRoomScript", Sc_CallRoomScript); + ccAddExternalStaticFunction("CDAudio", Sc_cd_manager); + ccAddExternalStaticFunction("CentreGUI", Sc_CentreGUI); + ccAddExternalStaticFunction("ChangeCharacterView", Sc_ChangeCharacterView); + ccAddExternalStaticFunction("ChangeCursorGraphic", Sc_ChangeCursorGraphic); + ccAddExternalStaticFunction("ChangeCursorHotspot", Sc_ChangeCursorHotspot); + ccAddExternalStaticFunction("ClaimEvent", Sc_ClaimEvent); + ccAddExternalStaticFunction("CreateGraphicOverlay", Sc_CreateGraphicOverlay); + ccAddExternalStaticFunction("CreateTextOverlay", Sc_CreateTextOverlay); + ccAddExternalStaticFunction("CyclePalette", Sc_CyclePalette); + ccAddExternalStaticFunction("Debug", Sc_script_debug); + ccAddExternalStaticFunction("DeleteSaveSlot", Sc_DeleteSaveSlot); + ccAddExternalStaticFunction("DeleteSprite", Sc_free_dynamic_sprite); + ccAddExternalStaticFunction("DisableCursorMode", Sc_disable_cursor_mode); + ccAddExternalStaticFunction("DisableGroundLevelAreas", Sc_DisableGroundLevelAreas); + ccAddExternalStaticFunction("DisableHotspot", Sc_DisableHotspot); + ccAddExternalStaticFunction("DisableInterface", Sc_DisableInterface); + ccAddExternalStaticFunction("DisableRegion", Sc_DisableRegion); + ccAddExternalStaticFunction("Display", Sc_Display); + ccAddExternalStaticFunction("DisplayAt", Sc_DisplayAt); + ccAddExternalStaticFunction("DisplayAtY", Sc_DisplayAtY); + ccAddExternalStaticFunction("DisplayMessage", Sc_DisplayMessage); + ccAddExternalStaticFunction("DisplayMessageAtY", Sc_DisplayMessageAtY); + ccAddExternalStaticFunction("DisplayMessageBar", Sc_DisplayMessageBar); + ccAddExternalStaticFunction("DisplaySpeech", Sc_sc_displayspeech); + ccAddExternalStaticFunction("DisplaySpeechAt", Sc_DisplaySpeechAt); + ccAddExternalStaticFunction("DisplaySpeechBackground", Sc_DisplaySpeechBackground); + ccAddExternalStaticFunction("DisplayThought", Sc_DisplayThought); + ccAddExternalStaticFunction("DisplayTopBar", Sc_DisplayTopBar); + ccAddExternalStaticFunction("EnableCursorMode", Sc_enable_cursor_mode); + ccAddExternalStaticFunction("EnableGroundLevelAreas", Sc_EnableGroundLevelAreas); + ccAddExternalStaticFunction("EnableHotspot", Sc_EnableHotspot); + ccAddExternalStaticFunction("EnableInterface", Sc_EnableInterface); + ccAddExternalStaticFunction("EnableRegion", Sc_EnableRegion); + ccAddExternalStaticFunction("EndCutscene", Sc_EndCutscene); + ccAddExternalStaticFunction("FaceCharacter", Sc_FaceCharacter); + ccAddExternalStaticFunction("FaceLocation", Sc_FaceLocation); + ccAddExternalStaticFunction("FadeIn", Sc_FadeIn); + ccAddExternalStaticFunction("FadeOut", Sc_my_fade_out); + ccAddExternalStaticFunction("FileClose", Sc_FileClose); + ccAddExternalStaticFunction("FileIsEOF", Sc_FileIsEOF); + ccAddExternalStaticFunction("FileIsError", Sc_FileIsError); + // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen + ccAddExternalStaticFunction("FileOpen", Sc_FileOpenCMode); + ccAddExternalStaticFunction("FileRead", Sc_FileRead); + ccAddExternalStaticFunction("FileReadInt", Sc_FileReadInt); + ccAddExternalStaticFunction("FileReadRawChar", Sc_FileReadRawChar); + ccAddExternalStaticFunction("FileReadRawInt", Sc_FileReadRawInt); + ccAddExternalStaticFunction("FileWrite", Sc_FileWrite); + ccAddExternalStaticFunction("FileWriteInt", Sc_FileWriteInt); + ccAddExternalStaticFunction("FileWriteRawChar", Sc_FileWriteRawChar); + ccAddExternalStaticFunction("FileWriteRawLine", Sc_FileWriteRawLine); + ccAddExternalStaticFunction("FindGUIID", Sc_FindGUIID); + ccAddExternalStaticFunction("FlipScreen", Sc_FlipScreen); + ccAddExternalStaticFunction("FloatToInt", Sc_FloatToInt); + ccAddExternalStaticFunction("FollowCharacter", Sc_FollowCharacter); + ccAddExternalStaticFunction("FollowCharacterEx", Sc_FollowCharacterEx); + ccAddExternalStaticFunction("GetBackgroundFrame", Sc_GetBackgroundFrame); + ccAddExternalStaticFunction("GetButtonPic", Sc_GetButtonPic); + ccAddExternalStaticFunction("GetCharacterAt", Sc_GetCharIDAtScreen); + ccAddExternalStaticFunction("GetCharacterProperty", Sc_GetCharacterProperty); + ccAddExternalStaticFunction("GetCharacterPropertyText", Sc_GetCharacterPropertyText); + ccAddExternalStaticFunction("GetCurrentMusic", Sc_GetCurrentMusic); + ccAddExternalStaticFunction("GetCursorMode", Sc_GetCursorMode); + ccAddExternalStaticFunction("GetDialogOption", Sc_GetDialogOption); + ccAddExternalStaticFunction("GetGameOption", Sc_GetGameOption); + ccAddExternalStaticFunction("GetGameParameter", Sc_GetGameParameter); + ccAddExternalStaticFunction("GetGameSpeed", Sc_GetGameSpeed); + ccAddExternalStaticFunction("GetGlobalInt", Sc_GetGlobalInt); + ccAddExternalStaticFunction("GetGlobalString", Sc_GetGlobalString); + ccAddExternalStaticFunction("GetGraphicalVariable", Sc_GetGraphicalVariable); + ccAddExternalStaticFunction("GetGUIAt", Sc_GetGUIAt); + ccAddExternalStaticFunction("GetGUIObjectAt", Sc_GetGUIObjectAt); + ccAddExternalStaticFunction("GetHotspotAt", Sc_GetHotspotIDAtScreen); + ccAddExternalStaticFunction("GetHotspotName", Sc_GetHotspotName); + ccAddExternalStaticFunction("GetHotspotPointX", Sc_GetHotspotPointX); + ccAddExternalStaticFunction("GetHotspotPointY", Sc_GetHotspotPointY); + ccAddExternalStaticFunction("GetHotspotProperty", Sc_GetHotspotProperty); + ccAddExternalStaticFunction("GetHotspotPropertyText", Sc_GetHotspotPropertyText); + ccAddExternalStaticFunction("GetInvAt", Sc_GetInvAt); + ccAddExternalStaticFunction("GetInvGraphic", Sc_GetInvGraphic); + ccAddExternalStaticFunction("GetInvName", Sc_GetInvName); + ccAddExternalStaticFunction("GetInvProperty", Sc_GetInvProperty); + ccAddExternalStaticFunction("GetInvPropertyText", Sc_GetInvPropertyText); + //ccAddExternalStaticFunction("GetLanguageString", Sc_GetLanguageString); + ccAddExternalStaticFunction("GetLocationName", Sc_GetLocationName); + ccAddExternalStaticFunction("GetLocationType", Sc_GetLocationType); + ccAddExternalStaticFunction("GetMessageText", Sc_GetMessageText); + ccAddExternalStaticFunction("GetMIDIPosition", Sc_GetMIDIPosition); + ccAddExternalStaticFunction("GetMP3PosMillis", Sc_GetMP3PosMillis); + ccAddExternalStaticFunction("GetObjectAt", Sc_GetObjectIDAtScreen); + ccAddExternalStaticFunction("GetObjectBaseline", Sc_GetObjectBaseline); + ccAddExternalStaticFunction("GetObjectGraphic", Sc_GetObjectGraphic); + ccAddExternalStaticFunction("GetObjectName", Sc_GetObjectName); + ccAddExternalStaticFunction("GetObjectProperty", Sc_GetObjectProperty); + ccAddExternalStaticFunction("GetObjectPropertyText", Sc_GetObjectPropertyText); + ccAddExternalStaticFunction("GetObjectX", Sc_GetObjectX); + ccAddExternalStaticFunction("GetObjectY", Sc_GetObjectY); + // ccAddExternalStaticFunction("GetPalette", Sc_scGetPal); + ccAddExternalStaticFunction("GetPlayerCharacter", Sc_GetPlayerCharacter); + ccAddExternalStaticFunction("GetRawTime", Sc_GetRawTime); + ccAddExternalStaticFunction("GetRegionAt", Sc_GetRegionIDAtRoom); + ccAddExternalStaticFunction("GetRoomProperty", Sc_Room_GetProperty); + ccAddExternalStaticFunction("GetRoomPropertyText", Sc_GetRoomPropertyText); + ccAddExternalStaticFunction("GetSaveSlotDescription", Sc_GetSaveSlotDescription); + ccAddExternalStaticFunction("GetScalingAt", Sc_GetScalingAt); + ccAddExternalStaticFunction("GetSliderValue", Sc_GetSliderValue); + ccAddExternalStaticFunction("GetTextBoxText", Sc_GetTextBoxText); + ccAddExternalStaticFunction("GetTextHeight", Sc_GetTextHeight); + ccAddExternalStaticFunction("GetTextWidth", Sc_GetTextWidth); + ccAddExternalStaticFunction("GetFontHeight", Sc_GetFontHeight); + ccAddExternalStaticFunction("GetFontLineSpacing", Sc_GetFontLineSpacing); + ccAddExternalStaticFunction("GetTime", Sc_sc_GetTime); + ccAddExternalStaticFunction("GetTranslation", Sc_get_translation); + ccAddExternalStaticFunction("GetTranslationName", Sc_GetTranslationName); + ccAddExternalStaticFunction("GetViewportX", Sc_GetViewportX); + ccAddExternalStaticFunction("GetViewportY", Sc_GetViewportY); + ccAddExternalStaticFunction("GetWalkableAreaAtRoom", Sc_GetWalkableAreaAtRoom); + ccAddExternalStaticFunction("GetWalkableAreaAt", Sc_GetWalkableAreaAtScreen); + ccAddExternalStaticFunction("GetWalkableAreaAtScreen", Sc_GetWalkableAreaAtScreen); + ccAddExternalStaticFunction("GetDrawingSurfaceForWalkableArea", Sc_GetDrawingSurfaceForWalkableArea); + ccAddExternalStaticFunction("GetDrawingSurfaceForWalkbehind", Sc_GetDrawingSurfaceForWalkbehind); + ccAddExternalStaticFunction("GiveScore", Sc_GiveScore); + ccAddExternalStaticFunction("HasPlayerBeenInRoom", Sc_HasPlayerBeenInRoom); + ccAddExternalStaticFunction("HideMouseCursor", Sc_HideMouseCursor); + ccAddExternalStaticFunction("InputBox", Sc_sc_inputbox); + ccAddExternalStaticFunction("InterfaceOff", Sc_InterfaceOff); + ccAddExternalStaticFunction("InterfaceOn", Sc_InterfaceOn); + ccAddExternalStaticFunction("IntToFloat", Sc_IntToFloat); + ccAddExternalStaticFunction("InventoryScreen", Sc_sc_invscreen); + ccAddExternalStaticFunction("IsButtonDown", Sc_IsButtonDown); + ccAddExternalStaticFunction("IsChannelPlaying", Sc_IsChannelPlaying); + ccAddExternalStaticFunction("IsGamePaused", Sc_IsGamePaused); + ccAddExternalStaticFunction("IsGUIOn", Sc_IsGUIOn); + ccAddExternalStaticFunction("IsInteractionAvailable", Sc_IsInteractionAvailable); + ccAddExternalStaticFunction("IsInventoryInteractionAvailable", Sc_IsInventoryInteractionAvailable); + ccAddExternalStaticFunction("IsInterfaceEnabled", Sc_IsInterfaceEnabled); + ccAddExternalStaticFunction("IsKeyPressed", Sc_IsKeyPressed); + ccAddExternalStaticFunction("IsMusicPlaying", Sc_IsMusicPlaying); + ccAddExternalStaticFunction("IsMusicVoxAvailable", Sc_IsMusicVoxAvailable); + ccAddExternalStaticFunction("IsObjectAnimating", Sc_IsObjectAnimating); + ccAddExternalStaticFunction("IsObjectMoving", Sc_IsObjectMoving); + ccAddExternalStaticFunction("IsObjectOn", Sc_IsObjectOn); + ccAddExternalStaticFunction("IsOverlayValid", Sc_IsOverlayValid); + ccAddExternalStaticFunction("IsSoundPlaying", Sc_IsSoundPlaying); + ccAddExternalStaticFunction("IsTimerExpired", Sc_IsTimerExpired); + ccAddExternalStaticFunction("IsTranslationAvailable", Sc_IsTranslationAvailable); + ccAddExternalStaticFunction("IsVoxAvailable", Sc_IsVoxAvailable); + ccAddExternalStaticFunction("ListBoxAdd", Sc_ListBoxAdd); + ccAddExternalStaticFunction("ListBoxClear", Sc_ListBoxClear); + ccAddExternalStaticFunction("ListBoxDirList", Sc_ListBoxDirList); + ccAddExternalStaticFunction("ListBoxGetItemText", Sc_ListBoxGetItemText); + ccAddExternalStaticFunction("ListBoxGetNumItems", Sc_ListBoxGetNumItems); + ccAddExternalStaticFunction("ListBoxGetSelected", Sc_ListBoxGetSelected); + ccAddExternalStaticFunction("ListBoxRemove", Sc_ListBoxRemove); + ccAddExternalStaticFunction("ListBoxSaveGameList", Sc_ListBoxSaveGameList); + ccAddExternalStaticFunction("ListBoxSetSelected", Sc_ListBoxSetSelected); + ccAddExternalStaticFunction("ListBoxSetTopItem", Sc_ListBoxSetTopItem); + ccAddExternalStaticFunction("LoadImageFile", Sc_LoadImageFile); + ccAddExternalStaticFunction("LoadSaveSlotScreenshot", Sc_LoadSaveSlotScreenshot); + ccAddExternalStaticFunction("LoseInventory", Sc_lose_inventory); + ccAddExternalStaticFunction("LoseInventoryFromCharacter", Sc_LoseInventoryFromCharacter); + ccAddExternalStaticFunction("MergeObject", Sc_MergeObject); + ccAddExternalStaticFunction("MoveCharacter", Sc_MoveCharacter); + ccAddExternalStaticFunction("MoveCharacterBlocking", Sc_MoveCharacterBlocking); + ccAddExternalStaticFunction("MoveCharacterDirect", Sc_MoveCharacterDirect); + ccAddExternalStaticFunction("MoveCharacterPath", Sc_MoveCharacterPath); + ccAddExternalStaticFunction("MoveCharacterStraight", Sc_MoveCharacterStraight); + ccAddExternalStaticFunction("MoveCharacterToHotspot", Sc_MoveCharacterToHotspot); + ccAddExternalStaticFunction("MoveCharacterToObject", Sc_MoveCharacterToObject); + ccAddExternalStaticFunction("MoveObject", Sc_MoveObject); + ccAddExternalStaticFunction("MoveObjectDirect", Sc_MoveObjectDirect); + ccAddExternalStaticFunction("MoveOverlay", Sc_MoveOverlay); + ccAddExternalStaticFunction("MoveToWalkableArea", Sc_MoveToWalkableArea); + ccAddExternalStaticFunction("NewRoom", Sc_NewRoom); + ccAddExternalStaticFunction("NewRoomEx", Sc_NewRoomEx); + ccAddExternalStaticFunction("NewRoomNPC", Sc_NewRoomNPC); + ccAddExternalStaticFunction("ObjectOff", Sc_ObjectOff); + ccAddExternalStaticFunction("ObjectOn", Sc_ObjectOn); + ccAddExternalStaticFunction("ParseText", Sc_ParseText); + ccAddExternalStaticFunction("PauseGame", Sc_PauseGame); + ccAddExternalStaticFunction("PlayAmbientSound", Sc_PlayAmbientSound); + ccAddExternalStaticFunction("PlayFlic", Sc_play_flc_file); + ccAddExternalStaticFunction("PlayMP3File", Sc_PlayMP3File); + ccAddExternalStaticFunction("PlayMusic", Sc_PlayMusicResetQueue); + ccAddExternalStaticFunction("PlayMusicQueued", Sc_PlayMusicQueued); + ccAddExternalStaticFunction("PlaySilentMIDI", Sc_PlaySilentMIDI); + ccAddExternalStaticFunction("PlaySound", Sc_play_sound); + ccAddExternalStaticFunction("PlaySoundEx", Sc_PlaySoundEx); + ccAddExternalStaticFunction("PlayVideo", Sc_scrPlayVideo); + ccAddExternalStaticFunction("QuitGame", Sc_QuitGame); + ccAddExternalStaticFunction("Random", Sc_Rand); + ccAddExternalStaticFunction("RawClearScreen", Sc_RawClear); + ccAddExternalStaticFunction("RawDrawCircle", Sc_RawDrawCircle); + ccAddExternalStaticFunction("RawDrawFrameTransparent", Sc_RawDrawFrameTransparent); + ccAddExternalStaticFunction("RawDrawImage", Sc_RawDrawImage); + ccAddExternalStaticFunction("RawDrawImageOffset", Sc_RawDrawImageOffset); + ccAddExternalStaticFunction("RawDrawImageResized", Sc_RawDrawImageResized); + ccAddExternalStaticFunction("RawDrawImageTransparent", Sc_RawDrawImageTransparent); + ccAddExternalStaticFunction("RawDrawLine", Sc_RawDrawLine); + ccAddExternalStaticFunction("RawDrawRectangle", Sc_RawDrawRectangle); + ccAddExternalStaticFunction("RawDrawTriangle", Sc_RawDrawTriangle); + ccAddExternalStaticFunction("RawPrint", Sc_RawPrint); + ccAddExternalStaticFunction("RawPrintMessageWrapped", Sc_RawPrintMessageWrapped); + ccAddExternalStaticFunction("RawRestoreScreen", Sc_RawRestoreScreen); + ccAddExternalStaticFunction("RawRestoreScreenTinted", Sc_RawRestoreScreenTinted); + ccAddExternalStaticFunction("RawSaveScreen", Sc_RawSaveScreen); + ccAddExternalStaticFunction("RawSetColor", Sc_RawSetColor); + ccAddExternalStaticFunction("RawSetColorRGB", Sc_RawSetColorRGB); + ccAddExternalStaticFunction("RefreshMouse", Sc_RefreshMouse); + ccAddExternalStaticFunction("ReleaseCharacterView", Sc_ReleaseCharacterView); + ccAddExternalStaticFunction("ReleaseViewport", Sc_ReleaseViewport); + ccAddExternalStaticFunction("RemoveObjectTint", Sc_RemoveObjectTint); + ccAddExternalStaticFunction("RemoveOverlay", Sc_RemoveOverlay); + ccAddExternalStaticFunction("RemoveWalkableArea", Sc_RemoveWalkableArea); + ccAddExternalStaticFunction("ResetRoom", Sc_ResetRoom); + ccAddExternalStaticFunction("RestartGame", Sc_restart_game); + ccAddExternalStaticFunction("RestoreGameDialog", Sc_restore_game_dialog); + ccAddExternalStaticFunction("RestoreGameSlot", Sc_RestoreGameSlot); + ccAddExternalStaticFunction("RestoreWalkableArea", Sc_RestoreWalkableArea); + ccAddExternalStaticFunction("RunAGSGame", Sc_RunAGSGame); + ccAddExternalStaticFunction("RunCharacterInteraction", Sc_RunCharacterInteraction); + ccAddExternalStaticFunction("RunDialog", Sc_RunDialog); + ccAddExternalStaticFunction("RunHotspotInteraction", Sc_RunHotspotInteraction); + ccAddExternalStaticFunction("RunInventoryInteraction", Sc_RunInventoryInteraction); + ccAddExternalStaticFunction("RunObjectInteraction", Sc_RunObjectInteraction); + ccAddExternalStaticFunction("RunRegionInteraction", Sc_RunRegionInteraction); + ccAddExternalStaticFunction("Said", Sc_Said); + ccAddExternalStaticFunction("SaidUnknownWord", Sc_SaidUnknownWord); + ccAddExternalStaticFunction("SaveCursorForLocationChange", Sc_SaveCursorForLocationChange); + ccAddExternalStaticFunction("SaveGameDialog", Sc_save_game_dialog); + ccAddExternalStaticFunction("SaveGameSlot", Sc_save_game); + ccAddExternalStaticFunction("SaveScreenShot", Sc_SaveScreenShot); + ccAddExternalStaticFunction("SeekMIDIPosition", Sc_SeekMIDIPosition); + ccAddExternalStaticFunction("SeekMODPattern", Sc_SeekMODPattern); + ccAddExternalStaticFunction("SeekMP3PosMillis", Sc_SeekMP3PosMillis); + ccAddExternalStaticFunction("SetActiveInventory", Sc_SetActiveInventory); + ccAddExternalStaticFunction("SetAmbientTint", Sc_SetAmbientTint); + ccAddExternalStaticFunction("SetAmbientLightLevel", Sc_SetAmbientLightLevel); + ccAddExternalStaticFunction("SetAreaLightLevel", Sc_SetAreaLightLevel); + ccAddExternalStaticFunction("SetAreaScaling", Sc_SetAreaScaling); + ccAddExternalStaticFunction("SetBackgroundFrame", Sc_SetBackgroundFrame); + ccAddExternalStaticFunction("SetButtonPic", Sc_SetButtonPic); + ccAddExternalStaticFunction("SetButtonText", Sc_SetButtonText); + ccAddExternalStaticFunction("SetChannelVolume", Sc_SetChannelVolume); + ccAddExternalStaticFunction("SetCharacterBaseline", Sc_SetCharacterBaseline); + ccAddExternalStaticFunction("SetCharacterClickable", Sc_SetCharacterClickable); + ccAddExternalStaticFunction("SetCharacterFrame", Sc_SetCharacterFrame); + ccAddExternalStaticFunction("SetCharacterIdle", Sc_SetCharacterIdle); + ccAddExternalStaticFunction("SetCharacterIgnoreLight", Sc_SetCharacterIgnoreLight); + ccAddExternalStaticFunction("SetCharacterIgnoreWalkbehinds", Sc_SetCharacterIgnoreWalkbehinds); + ccAddExternalStaticFunction("SetCharacterProperty", Sc_SetCharacterProperty); + ccAddExternalStaticFunction("SetCharacterBlinkView", Sc_SetCharacterBlinkView); + ccAddExternalStaticFunction("SetCharacterSpeechView", Sc_SetCharacterSpeechView); + ccAddExternalStaticFunction("SetCharacterSpeed", Sc_SetCharacterSpeed); + ccAddExternalStaticFunction("SetCharacterSpeedEx", Sc_SetCharacterSpeedEx); + ccAddExternalStaticFunction("SetCharacterTransparency", Sc_SetCharacterTransparency); + ccAddExternalStaticFunction("SetCharacterView", Sc_SetCharacterView); + ccAddExternalStaticFunction("SetCharacterViewEx", Sc_SetCharacterViewEx); + ccAddExternalStaticFunction("SetCharacterViewOffset", Sc_SetCharacterViewOffset); + ccAddExternalStaticFunction("SetCursorMode", Sc_set_cursor_mode); + ccAddExternalStaticFunction("SetDefaultCursor", Sc_set_default_cursor); + ccAddExternalStaticFunction("SetDialogOption", Sc_SetDialogOption); + ccAddExternalStaticFunction("SetDigitalMasterVolume", Sc_SetDigitalMasterVolume); + ccAddExternalStaticFunction("SetFadeColor", Sc_SetFadeColor); + ccAddExternalStaticFunction("SetFrameSound", Sc_SetFrameSound); + ccAddExternalStaticFunction("SetGameOption", Sc_SetGameOption); + ccAddExternalStaticFunction("SetGameSpeed", Sc_SetGameSpeed); + ccAddExternalStaticFunction("SetGlobalInt", Sc_SetGlobalInt); + ccAddExternalStaticFunction("SetGlobalString", Sc_SetGlobalString); + ccAddExternalStaticFunction("SetGraphicalVariable", Sc_SetGraphicalVariable); + ccAddExternalStaticFunction("SetGUIBackgroundPic", Sc_SetGUIBackgroundPic); + ccAddExternalStaticFunction("SetGUIClickable", Sc_SetGUIClickable); + ccAddExternalStaticFunction("SetGUIObjectEnabled", Sc_SetGUIObjectEnabled); + ccAddExternalStaticFunction("SetGUIObjectPosition", Sc_SetGUIObjectPosition); + ccAddExternalStaticFunction("SetGUIObjectSize", Sc_SetGUIObjectSize); + ccAddExternalStaticFunction("SetGUIPosition", Sc_SetGUIPosition); + ccAddExternalStaticFunction("SetGUISize", Sc_SetGUISize); + ccAddExternalStaticFunction("SetGUITransparency", Sc_SetGUITransparency); + ccAddExternalStaticFunction("SetGUIZOrder", Sc_SetGUIZOrder); + ccAddExternalStaticFunction("SetInvItemName", Sc_SetInvItemName); + ccAddExternalStaticFunction("SetInvItemPic", Sc_set_inv_item_pic); + ccAddExternalStaticFunction("SetInvDimensions", Sc_SetInvDimensions); + ccAddExternalStaticFunction("SetLabelColor", Sc_SetLabelColor); + ccAddExternalStaticFunction("SetLabelFont", Sc_SetLabelFont); + ccAddExternalStaticFunction("SetLabelText", Sc_SetLabelText); + ccAddExternalStaticFunction("SetMouseBounds", Sc_SetMouseBounds); + ccAddExternalStaticFunction("SetMouseCursor", Sc_set_mouse_cursor); + ccAddExternalStaticFunction("SetMousePosition", Sc_SetMousePosition); + ccAddExternalStaticFunction("SetMultitaskingMode", Sc_SetMultitasking); + ccAddExternalStaticFunction("SetMusicMasterVolume", Sc_SetMusicMasterVolume); + ccAddExternalStaticFunction("SetMusicRepeat", Sc_SetMusicRepeat); + ccAddExternalStaticFunction("SetMusicVolume", Sc_SetMusicVolume); + ccAddExternalStaticFunction("SetNextCursorMode", Sc_SetNextCursor); + ccAddExternalStaticFunction("SetNextScreenTransition", Sc_SetNextScreenTransition); + ccAddExternalStaticFunction("SetNormalFont", Sc_SetNormalFont); + ccAddExternalStaticFunction("SetObjectBaseline", Sc_SetObjectBaseline); + ccAddExternalStaticFunction("SetObjectClickable", Sc_SetObjectClickable); + ccAddExternalStaticFunction("SetObjectFrame", Sc_SetObjectFrame); + ccAddExternalStaticFunction("SetObjectGraphic", Sc_SetObjectGraphic); + ccAddExternalStaticFunction("SetObjectIgnoreWalkbehinds", Sc_SetObjectIgnoreWalkbehinds); + ccAddExternalStaticFunction("SetObjectPosition", Sc_SetObjectPosition); + ccAddExternalStaticFunction("SetObjectTint", Sc_SetObjectTint); + ccAddExternalStaticFunction("SetObjectTransparency", Sc_SetObjectTransparency); + ccAddExternalStaticFunction("SetObjectView", Sc_SetObjectView); + // ccAddExternalStaticFunction("SetPalette", scSetPal); + ccAddExternalStaticFunction("SetPalRGB", Sc_SetPalRGB); + ccAddExternalStaticFunction("SetPlayerCharacter", Sc_SetPlayerCharacter); + ccAddExternalStaticFunction("SetRegionTint", Sc_SetRegionTint); + ccAddExternalStaticFunction("SetRestartPoint", Sc_SetRestartPoint); + ccAddExternalStaticFunction("SetScreenTransition", Sc_SetScreenTransition); + ccAddExternalStaticFunction("SetSkipSpeech", Sc_SetSkipSpeech); + ccAddExternalStaticFunction("SetSliderValue", Sc_SetSliderValue); + ccAddExternalStaticFunction("SetSoundVolume", Sc_SetSoundVolume); + ccAddExternalStaticFunction("SetSpeechFont", Sc_SetSpeechFont); + ccAddExternalStaticFunction("SetSpeechStyle", Sc_SetSpeechStyle); + ccAddExternalStaticFunction("SetSpeechVolume", Sc_SetSpeechVolume); + ccAddExternalStaticFunction("SetTalkingColor", Sc_SetTalkingColor); + ccAddExternalStaticFunction("SetTextBoxFont", Sc_SetTextBoxFont); + ccAddExternalStaticFunction("SetTextBoxText", Sc_SetTextBoxText); + ccAddExternalStaticFunction("SetTextOverlay", Sc_SetTextOverlay); + ccAddExternalStaticFunction("SetTextWindowGUI", Sc_SetTextWindowGUI); + ccAddExternalStaticFunction("SetTimer", Sc_script_SetTimer); + ccAddExternalStaticFunction("SetViewport", Sc_SetViewport); + ccAddExternalStaticFunction("SetVoiceMode", Sc_SetVoiceMode); + ccAddExternalStaticFunction("SetWalkBehindBase", Sc_SetWalkBehindBase); + ccAddExternalStaticFunction("ShakeScreen", Sc_ShakeScreen); + ccAddExternalStaticFunction("ShakeScreenBackground", Sc_ShakeScreenBackground); + ccAddExternalStaticFunction("ShowMouseCursor", Sc_ShowMouseCursor); + ccAddExternalStaticFunction("SkipCutscene", Sc_SkipCutscene); + ccAddExternalStaticFunction("SkipUntilCharacterStops", Sc_SkipUntilCharacterStops); + ccAddExternalStaticFunction("StartCutscene", Sc_StartCutscene); + ccAddExternalStaticFunction("StartRecording", Sc_scStartRecording); + ccAddExternalStaticFunction("StopAmbientSound", Sc_StopAmbientSound); + ccAddExternalStaticFunction("StopChannel", Sc_stop_and_destroy_channel); + ccAddExternalStaticFunction("StopDialog", Sc_StopDialog); + ccAddExternalStaticFunction("StopMoving", Sc_StopMoving); + ccAddExternalStaticFunction("StopMusic", Sc_scr_StopMusic); + ccAddExternalStaticFunction("StopObjectMoving", Sc_StopObjectMoving); + ccAddExternalStaticFunction("StrCat", Sc_sc_strcat); + ccAddExternalStaticFunction("StrCaseComp", Sc_stricmp); + ccAddExternalStaticFunction("StrComp", Sc_strcmp); + ccAddExternalStaticFunction("StrContains", Sc_StrContains); + ccAddExternalStaticFunction("StrCopy", Sc_sc_strcpy); + ccAddExternalStaticFunction("StrFormat", Sc_sc_sprintf); + ccAddExternalStaticFunction("StrGetCharAt", Sc_StrGetCharAt); + ccAddExternalStaticFunction("StringToInt", Sc_StringToInt); + ccAddExternalStaticFunction("StrLen", Sc_strlen); + ccAddExternalStaticFunction("StrSetCharAt", Sc_StrSetCharAt); + ccAddExternalStaticFunction("StrToLowerCase", Sc_sc_strlower); + ccAddExternalStaticFunction("StrToUpperCase", Sc_sc_strupper); + ccAddExternalStaticFunction("TintScreen", Sc_TintScreen); + ccAddExternalStaticFunction("UnPauseGame", Sc_UnPauseGame); + ccAddExternalStaticFunction("UpdateInventory", Sc_update_invorder); + ccAddExternalStaticFunction("UpdatePalette", Sc_UpdatePalette); + ccAddExternalStaticFunction("Wait", Sc_scrWait); + ccAddExternalStaticFunction("WaitKey", Sc_WaitKey); + ccAddExternalStaticFunction("WaitMouse", Sc_WaitMouse); + ccAddExternalStaticFunction("WaitMouseKey", Sc_WaitMouseKey); + ccAddExternalStaticFunction("SkipWait", Sc_SkipWait); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("AbortGame", (void*)ScPl_sc_AbortGame); + ccAddExternalFunctionForPlugin("AddInventory", (void*)add_inventory); + ccAddExternalFunctionForPlugin("AddInventoryToCharacter", (void*)AddInventoryToCharacter); + ccAddExternalFunctionForPlugin("AnimateButton", (void*)AnimateButton); + ccAddExternalFunctionForPlugin("AnimateCharacter", (void*)scAnimateCharacter); + ccAddExternalFunctionForPlugin("AnimateCharacterEx", (void*)AnimateCharacterEx); + ccAddExternalFunctionForPlugin("AnimateObject", (void*)AnimateObject); + ccAddExternalFunctionForPlugin("AnimateObjectEx", (void*)AnimateObjectEx); + ccAddExternalFunctionForPlugin("AreCharactersColliding", (void*)AreCharactersColliding); + ccAddExternalFunctionForPlugin("AreCharObjColliding", (void*)AreCharObjColliding); + ccAddExternalFunctionForPlugin("AreObjectsColliding", (void*)AreObjectsColliding); + ccAddExternalFunctionForPlugin("AreThingsOverlapping", (void*)AreThingsOverlapping); + ccAddExternalFunctionForPlugin("CallRoomScript", (void*)CallRoomScript); + ccAddExternalFunctionForPlugin("CDAudio", (void*)cd_manager); + ccAddExternalFunctionForPlugin("CentreGUI", (void*)CentreGUI); + ccAddExternalFunctionForPlugin("ChangeCharacterView", (void*)ChangeCharacterView); + ccAddExternalFunctionForPlugin("ChangeCursorGraphic", (void*)ChangeCursorGraphic); + ccAddExternalFunctionForPlugin("ChangeCursorHotspot", (void*)ChangeCursorHotspot); + ccAddExternalFunctionForPlugin("ClaimEvent", (void*)ClaimEvent); + ccAddExternalFunctionForPlugin("CreateGraphicOverlay", (void*)CreateGraphicOverlay); + ccAddExternalFunctionForPlugin("CreateTextOverlay", (void*)ScPl_CreateTextOverlay); + ccAddExternalFunctionForPlugin("CyclePalette", (void*)CyclePalette); + ccAddExternalFunctionForPlugin("Debug", (void*)script_debug); + ccAddExternalFunctionForPlugin("DeleteSaveSlot", (void*)DeleteSaveSlot); + ccAddExternalFunctionForPlugin("DeleteSprite", (void*)free_dynamic_sprite); + ccAddExternalFunctionForPlugin("DisableCursorMode", (void*)disable_cursor_mode); + ccAddExternalFunctionForPlugin("DisableGroundLevelAreas", (void*)DisableGroundLevelAreas); + ccAddExternalFunctionForPlugin("DisableHotspot", (void*)DisableHotspot); + ccAddExternalFunctionForPlugin("DisableInterface", (void*)DisableInterface); + ccAddExternalFunctionForPlugin("DisableRegion", (void*)DisableRegion); + ccAddExternalFunctionForPlugin("Display", (void*)ScPl_Display); + ccAddExternalFunctionForPlugin("DisplayAt", (void*)ScPl_DisplayAt); + ccAddExternalFunctionForPlugin("DisplayAtY", (void*)DisplayAtY); + ccAddExternalFunctionForPlugin("DisplayMessage", (void*)DisplayMessage); + ccAddExternalFunctionForPlugin("DisplayMessageAtY", (void*)DisplayMessageAtY); + ccAddExternalFunctionForPlugin("DisplayMessageBar", (void*)DisplayMessageBar); + ccAddExternalFunctionForPlugin("DisplaySpeech", (void*)ScPl_sc_displayspeech); + ccAddExternalFunctionForPlugin("DisplaySpeechAt", (void*)DisplaySpeechAt); + ccAddExternalFunctionForPlugin("DisplaySpeechBackground", (void*)DisplaySpeechBackground); + ccAddExternalFunctionForPlugin("DisplayThought", (void*)ScPl_DisplayThought); + ccAddExternalFunctionForPlugin("DisplayTopBar", (void*)ScPl_DisplayTopBar); + ccAddExternalFunctionForPlugin("EnableCursorMode", (void*)enable_cursor_mode); + ccAddExternalFunctionForPlugin("EnableGroundLevelAreas", (void*)EnableGroundLevelAreas); + ccAddExternalFunctionForPlugin("EnableHotspot", (void*)EnableHotspot); + ccAddExternalFunctionForPlugin("EnableInterface", (void*)EnableInterface); + ccAddExternalFunctionForPlugin("EnableRegion", (void*)EnableRegion); + ccAddExternalFunctionForPlugin("EndCutscene", (void*)EndCutscene); + ccAddExternalFunctionForPlugin("FaceCharacter", (void*)FaceCharacter); + ccAddExternalFunctionForPlugin("FaceLocation", (void*)FaceLocation); + ccAddExternalFunctionForPlugin("FadeIn", (void*)FadeIn); + ccAddExternalFunctionForPlugin("FadeOut", (void*)my_fade_out); + ccAddExternalFunctionForPlugin("FileClose", (void*)FileClose); + ccAddExternalFunctionForPlugin("FileIsEOF", (void*)FileIsEOF); + ccAddExternalFunctionForPlugin("FileIsError", (void*)FileIsError); + // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen + ccAddExternalFunctionForPlugin("FileOpen", (void*)FileOpenCMode); + ccAddExternalFunctionForPlugin("FileRead", (void*)FileRead); + ccAddExternalFunctionForPlugin("FileReadInt", (void*)FileReadInt); + ccAddExternalFunctionForPlugin("FileReadRawChar", (void*)FileReadRawChar); + ccAddExternalFunctionForPlugin("FileReadRawInt", (void*)FileReadRawInt); + ccAddExternalFunctionForPlugin("FileWrite", (void*)FileWrite); + ccAddExternalFunctionForPlugin("FileWriteInt", (void*)FileWriteInt); + ccAddExternalFunctionForPlugin("FileWriteRawChar", (void*)FileWriteRawChar); + ccAddExternalFunctionForPlugin("FileWriteRawLine", (void*)FileWriteRawLine); + ccAddExternalFunctionForPlugin("FindGUIID", (void*)FindGUIID); + ccAddExternalFunctionForPlugin("FlipScreen", (void*)FlipScreen); + ccAddExternalFunctionForPlugin("FloatToInt", (void*)FloatToInt); + ccAddExternalFunctionForPlugin("FollowCharacter", (void*)FollowCharacter); + ccAddExternalFunctionForPlugin("FollowCharacterEx", (void*)FollowCharacterEx); + ccAddExternalFunctionForPlugin("GetBackgroundFrame", (void*)GetBackgroundFrame); + ccAddExternalFunctionForPlugin("GetButtonPic", (void*)GetButtonPic); + ccAddExternalFunctionForPlugin("GetCharacterAt", (void*)GetCharIDAtScreen); + ccAddExternalFunctionForPlugin("GetCharacterProperty", (void*)GetCharacterProperty); + ccAddExternalFunctionForPlugin("GetCharacterPropertyText", (void*)GetCharacterPropertyText); + ccAddExternalFunctionForPlugin("GetCurrentMusic", (void*)GetCurrentMusic); + ccAddExternalFunctionForPlugin("GetCursorMode", (void*)GetCursorMode); + ccAddExternalFunctionForPlugin("GetDialogOption", (void*)GetDialogOption); + ccAddExternalFunctionForPlugin("GetGameOption", (void*)GetGameOption); + ccAddExternalFunctionForPlugin("GetGameParameter", (void*)GetGameParameter); + ccAddExternalFunctionForPlugin("GetGameSpeed", (void*)GetGameSpeed); + ccAddExternalFunctionForPlugin("GetGlobalInt", (void*)GetGlobalInt); + ccAddExternalFunctionForPlugin("GetGlobalString", (void*)GetGlobalString); + ccAddExternalFunctionForPlugin("GetGraphicalVariable", (void*)GetGraphicalVariable); + ccAddExternalFunctionForPlugin("GetGUIAt", (void*)GetGUIAt); + ccAddExternalFunctionForPlugin("GetGUIObjectAt", (void*)GetGUIObjectAt); + ccAddExternalFunctionForPlugin("GetHotspotAt", (void*)GetHotspotIDAtScreen); + ccAddExternalFunctionForPlugin("GetHotspotName", (void*)GetHotspotName); + ccAddExternalFunctionForPlugin("GetHotspotPointX", (void*)GetHotspotPointX); + ccAddExternalFunctionForPlugin("GetHotspotPointY", (void*)GetHotspotPointY); + ccAddExternalFunctionForPlugin("GetHotspotProperty", (void*)GetHotspotProperty); + ccAddExternalFunctionForPlugin("GetHotspotPropertyText", (void*)GetHotspotPropertyText); + ccAddExternalFunctionForPlugin("GetInvAt", (void*)GetInvAt); + ccAddExternalFunctionForPlugin("GetInvGraphic", (void*)GetInvGraphic); + ccAddExternalFunctionForPlugin("GetInvName", (void*)GetInvName); + ccAddExternalFunctionForPlugin("GetInvProperty", (void*)GetInvProperty); + ccAddExternalFunctionForPlugin("GetInvPropertyText", (void*)GetInvPropertyText); + //ccAddExternalFunctionForPlugin("GetLanguageString", (void*)GetLanguageString); + ccAddExternalFunctionForPlugin("GetLocationName", (void*)GetLocationName); + ccAddExternalFunctionForPlugin("GetLocationType", (void*)GetLocationType); + ccAddExternalFunctionForPlugin("GetMessageText", (void*)GetMessageText); + ccAddExternalFunctionForPlugin("GetMIDIPosition", (void*)GetMIDIPosition); + ccAddExternalFunctionForPlugin("GetMP3PosMillis", (void*)GetMP3PosMillis); + ccAddExternalFunctionForPlugin("GetObjectAt", (void*)GetObjectIDAtScreen); + ccAddExternalFunctionForPlugin("GetObjectBaseline", (void*)GetObjectBaseline); + ccAddExternalFunctionForPlugin("GetObjectGraphic", (void*)GetObjectGraphic); + ccAddExternalFunctionForPlugin("GetObjectName", (void*)GetObjectName); + ccAddExternalFunctionForPlugin("GetObjectProperty", (void*)GetObjectProperty); + ccAddExternalFunctionForPlugin("GetObjectPropertyText", (void*)GetObjectPropertyText); + ccAddExternalFunctionForPlugin("GetObjectX", (void*)GetObjectX); + ccAddExternalFunctionForPlugin("GetObjectY", (void*)GetObjectY); + // ccAddExternalFunctionForPlugin("GetPalette", (void*)scGetPal); + ccAddExternalFunctionForPlugin("GetPlayerCharacter", (void*)GetPlayerCharacter); + ccAddExternalFunctionForPlugin("GetRawTime", (void*)GetRawTime); + ccAddExternalFunctionForPlugin("GetRegionAt", (void*)GetRegionIDAtRoom); + ccAddExternalFunctionForPlugin("GetRoomProperty", (void*)Room_GetProperty); + ccAddExternalFunctionForPlugin("GetRoomPropertyText", (void*)GetRoomPropertyText); + ccAddExternalFunctionForPlugin("GetSaveSlotDescription", (void*)GetSaveSlotDescription); + ccAddExternalFunctionForPlugin("GetScalingAt", (void*)GetScalingAt); + ccAddExternalFunctionForPlugin("GetSliderValue", (void*)GetSliderValue); + ccAddExternalFunctionForPlugin("GetTextBoxText", (void*)GetTextBoxText); + ccAddExternalFunctionForPlugin("GetTextHeight", (void*)GetTextHeight); + ccAddExternalFunctionForPlugin("GetTextWidth", (void*)GetTextWidth); + ccAddExternalFunctionForPlugin("GetTime", (void*)sc_GetTime); + ccAddExternalFunctionForPlugin("GetTranslation", (void*)get_translation); + ccAddExternalFunctionForPlugin("GetTranslationName", (void*)GetTranslationName); + ccAddExternalFunctionForPlugin("GetViewportX", (void*)GetViewportX); + ccAddExternalFunctionForPlugin("GetViewportY", (void*)GetViewportY); + ccAddExternalFunctionForPlugin("GetWalkableAreaAtRoom", (void*)GetWalkableAreaAtRoom); + ccAddExternalFunctionForPlugin("GetWalkableAreaAt", (void*)GetWalkableAreaAtScreen); + ccAddExternalFunctionForPlugin("GetWalkableAreaAtScreen", (void*)GetWalkableAreaAtScreen); + ccAddExternalFunctionForPlugin("GiveScore", (void*)GiveScore); + ccAddExternalFunctionForPlugin("HasPlayerBeenInRoom", (void*)HasPlayerBeenInRoom); + ccAddExternalFunctionForPlugin("HideMouseCursor", (void*)HideMouseCursor); + ccAddExternalFunctionForPlugin("InputBox", (void*)sc_inputbox); + ccAddExternalFunctionForPlugin("InterfaceOff", (void*)InterfaceOff); + ccAddExternalFunctionForPlugin("InterfaceOn", (void*)InterfaceOn); + ccAddExternalFunctionForPlugin("IntToFloat", (void*)IntToFloat); + ccAddExternalFunctionForPlugin("InventoryScreen", (void*)sc_invscreen); + ccAddExternalFunctionForPlugin("IsButtonDown", (void*)IsButtonDown); + ccAddExternalFunctionForPlugin("IsChannelPlaying", (void*)IsChannelPlaying); + ccAddExternalFunctionForPlugin("IsGamePaused", (void*)IsGamePaused); + ccAddExternalFunctionForPlugin("IsGUIOn", (void*)IsGUIOn); + ccAddExternalFunctionForPlugin("IsInteractionAvailable", (void*)IsInteractionAvailable); + ccAddExternalFunctionForPlugin("IsInventoryInteractionAvailable", (void*)IsInventoryInteractionAvailable); + ccAddExternalFunctionForPlugin("IsInterfaceEnabled", (void*)IsInterfaceEnabled); + ccAddExternalFunctionForPlugin("IsKeyPressed", (void*)IsKeyPressed); + ccAddExternalFunctionForPlugin("IsMusicPlaying", (void*)IsMusicPlaying); + ccAddExternalFunctionForPlugin("IsMusicVoxAvailable", (void*)IsMusicVoxAvailable); + ccAddExternalFunctionForPlugin("IsObjectAnimating", (void*)IsObjectAnimating); + ccAddExternalFunctionForPlugin("IsObjectMoving", (void*)IsObjectMoving); + ccAddExternalFunctionForPlugin("IsObjectOn", (void*)IsObjectOn); + ccAddExternalFunctionForPlugin("IsOverlayValid", (void*)IsOverlayValid); + ccAddExternalFunctionForPlugin("IsSoundPlaying", (void*)IsSoundPlaying); + ccAddExternalFunctionForPlugin("IsTimerExpired", (void*)IsTimerExpired); + ccAddExternalFunctionForPlugin("IsTranslationAvailable", (void*)IsTranslationAvailable); + ccAddExternalFunctionForPlugin("IsVoxAvailable", (void*)IsVoxAvailable); + ccAddExternalFunctionForPlugin("ListBoxAdd", (void*)ListBoxAdd); + ccAddExternalFunctionForPlugin("ListBoxClear", (void*)ListBoxClear); + ccAddExternalFunctionForPlugin("ListBoxDirList", (void*)ListBoxDirList); + ccAddExternalFunctionForPlugin("ListBoxGetItemText", (void*)ListBoxGetItemText); + ccAddExternalFunctionForPlugin("ListBoxGetNumItems", (void*)ListBoxGetNumItems); + ccAddExternalFunctionForPlugin("ListBoxGetSelected", (void*)ListBoxGetSelected); + ccAddExternalFunctionForPlugin("ListBoxRemove", (void*)ListBoxRemove); + ccAddExternalFunctionForPlugin("ListBoxSaveGameList", (void*)ListBoxSaveGameList); + ccAddExternalFunctionForPlugin("ListBoxSetSelected", (void*)ListBoxSetSelected); + ccAddExternalFunctionForPlugin("ListBoxSetTopItem", (void*)ListBoxSetTopItem); + ccAddExternalFunctionForPlugin("LoadImageFile", (void*)LoadImageFile); + ccAddExternalFunctionForPlugin("LoadSaveSlotScreenshot", (void*)LoadSaveSlotScreenshot); + ccAddExternalFunctionForPlugin("LoseInventory", (void*)lose_inventory); + ccAddExternalFunctionForPlugin("LoseInventoryFromCharacter", (void*)LoseInventoryFromCharacter); + ccAddExternalFunctionForPlugin("MergeObject", (void*)MergeObject); + ccAddExternalFunctionForPlugin("MoveCharacter", (void*)MoveCharacter); + ccAddExternalFunctionForPlugin("MoveCharacterBlocking", (void*)MoveCharacterBlocking); + ccAddExternalFunctionForPlugin("MoveCharacterDirect", (void*)MoveCharacterDirect); + ccAddExternalFunctionForPlugin("MoveCharacterPath", (void*)MoveCharacterPath); + ccAddExternalFunctionForPlugin("MoveCharacterStraight", (void*)MoveCharacterStraight); + ccAddExternalFunctionForPlugin("MoveCharacterToHotspot", (void*)MoveCharacterToHotspot); + ccAddExternalFunctionForPlugin("MoveCharacterToObject", (void*)MoveCharacterToObject); + ccAddExternalFunctionForPlugin("MoveObject", (void*)MoveObject); + ccAddExternalFunctionForPlugin("MoveObjectDirect", (void*)MoveObjectDirect); + ccAddExternalFunctionForPlugin("MoveOverlay", (void*)MoveOverlay); + ccAddExternalFunctionForPlugin("MoveToWalkableArea", (void*)MoveToWalkableArea); + ccAddExternalFunctionForPlugin("NewRoom", (void*)NewRoom); + ccAddExternalFunctionForPlugin("NewRoomEx", (void*)NewRoomEx); + ccAddExternalFunctionForPlugin("NewRoomNPC", (void*)NewRoomNPC); + ccAddExternalFunctionForPlugin("ObjectOff", (void*)ObjectOff); + ccAddExternalFunctionForPlugin("ObjectOn", (void*)ObjectOn); + ccAddExternalFunctionForPlugin("ParseText", (void*)ParseText); + ccAddExternalFunctionForPlugin("PauseGame", (void*)PauseGame); + ccAddExternalFunctionForPlugin("PlayAmbientSound", (void*)PlayAmbientSound); + ccAddExternalFunctionForPlugin("PlayFlic", (void*)play_flc_file); + ccAddExternalFunctionForPlugin("PlayMP3File", (void*)PlayMP3File); + ccAddExternalFunctionForPlugin("PlayMusic", (void*)PlayMusicResetQueue); + ccAddExternalFunctionForPlugin("PlayMusicQueued", (void*)PlayMusicQueued); + ccAddExternalFunctionForPlugin("PlaySilentMIDI", (void*)PlaySilentMIDI); + ccAddExternalFunctionForPlugin("PlaySound", (void*)play_sound); + ccAddExternalFunctionForPlugin("PlaySoundEx", (void*)PlaySoundEx); + ccAddExternalFunctionForPlugin("PlayVideo", (void*)scrPlayVideo); + ccAddExternalFunctionForPlugin("ProcessClick", (void*)RoomProcessClick); + ccAddExternalFunctionForPlugin("QuitGame", (void*)QuitGame); + ccAddExternalFunctionForPlugin("Random", (void*)__Rand); + ccAddExternalFunctionForPlugin("RawClearScreen", (void*)RawClear); + ccAddExternalFunctionForPlugin("RawDrawCircle", (void*)RawDrawCircle); + ccAddExternalFunctionForPlugin("RawDrawFrameTransparent", (void*)RawDrawFrameTransparent); + ccAddExternalFunctionForPlugin("RawDrawImage", (void*)RawDrawImage); + ccAddExternalFunctionForPlugin("RawDrawImageOffset", (void*)RawDrawImageOffset); + ccAddExternalFunctionForPlugin("RawDrawImageResized", (void*)RawDrawImageResized); + ccAddExternalFunctionForPlugin("RawDrawImageTransparent", (void*)RawDrawImageTransparent); + ccAddExternalFunctionForPlugin("RawDrawLine", (void*)RawDrawLine); + ccAddExternalFunctionForPlugin("RawDrawRectangle", (void*)RawDrawRectangle); + ccAddExternalFunctionForPlugin("RawDrawTriangle", (void*)RawDrawTriangle); + ccAddExternalFunctionForPlugin("RawPrint", (void*)ScPl_RawPrint); + ccAddExternalFunctionForPlugin("RawPrintMessageWrapped", (void*)RawPrintMessageWrapped); + ccAddExternalFunctionForPlugin("RawRestoreScreen", (void*)RawRestoreScreen); + ccAddExternalFunctionForPlugin("RawRestoreScreenTinted", (void*)RawRestoreScreenTinted); + ccAddExternalFunctionForPlugin("RawSaveScreen", (void*)RawSaveScreen); + ccAddExternalFunctionForPlugin("RawSetColor", (void*)RawSetColor); + ccAddExternalFunctionForPlugin("RawSetColorRGB", (void*)RawSetColorRGB); + ccAddExternalFunctionForPlugin("RefreshMouse", (void*)RefreshMouse); + ccAddExternalFunctionForPlugin("ReleaseCharacterView", (void*)ReleaseCharacterView); + ccAddExternalFunctionForPlugin("ReleaseViewport", (void*)ReleaseViewport); + ccAddExternalFunctionForPlugin("RemoveObjectTint", (void*)RemoveObjectTint); + ccAddExternalFunctionForPlugin("RemoveOverlay", (void*)RemoveOverlay); + ccAddExternalFunctionForPlugin("RemoveWalkableArea", (void*)RemoveWalkableArea); + ccAddExternalFunctionForPlugin("ResetRoom", (void*)ResetRoom); + ccAddExternalFunctionForPlugin("RestartGame", (void*)restart_game); + ccAddExternalFunctionForPlugin("RestoreGameDialog", (void*)restore_game_dialog); + ccAddExternalFunctionForPlugin("RestoreGameSlot", (void*)RestoreGameSlot); + ccAddExternalFunctionForPlugin("RestoreWalkableArea", (void*)RestoreWalkableArea); + ccAddExternalFunctionForPlugin("RunAGSGame", (void*)RunAGSGame); + ccAddExternalFunctionForPlugin("RunCharacterInteraction", (void*)RunCharacterInteraction); + ccAddExternalFunctionForPlugin("RunDialog", (void*)RunDialog); + ccAddExternalFunctionForPlugin("RunHotspotInteraction", (void*)RunHotspotInteraction); + ccAddExternalFunctionForPlugin("RunInventoryInteraction", (void*)RunInventoryInteraction); + ccAddExternalFunctionForPlugin("RunObjectInteraction", (void*)RunObjectInteraction); + ccAddExternalFunctionForPlugin("RunRegionInteraction", (void*)RunRegionInteraction); + ccAddExternalFunctionForPlugin("Said", (void*)Said); + ccAddExternalFunctionForPlugin("SaidUnknownWord", (void*)SaidUnknownWord); + ccAddExternalFunctionForPlugin("SaveCursorForLocationChange", (void*)SaveCursorForLocationChange); + ccAddExternalFunctionForPlugin("SaveGameDialog", (void*)save_game_dialog); + ccAddExternalFunctionForPlugin("SaveGameSlot", (void*)save_game); + ccAddExternalFunctionForPlugin("SaveScreenShot", (void*)SaveScreenShot); + ccAddExternalFunctionForPlugin("SeekMIDIPosition", (void*)SeekMIDIPosition); + ccAddExternalFunctionForPlugin("SeekMODPattern", (void*)SeekMODPattern); + ccAddExternalFunctionForPlugin("SeekMP3PosMillis", (void*)SeekMP3PosMillis); + ccAddExternalFunctionForPlugin("SetActiveInventory", (void*)SetActiveInventory); + ccAddExternalFunctionForPlugin("SetAmbientTint", (void*)SetAmbientTint); + ccAddExternalFunctionForPlugin("SetAreaLightLevel", (void*)SetAreaLightLevel); + ccAddExternalFunctionForPlugin("SetAreaScaling", (void*)SetAreaScaling); + ccAddExternalFunctionForPlugin("SetBackgroundFrame", (void*)SetBackgroundFrame); + ccAddExternalFunctionForPlugin("SetButtonPic", (void*)SetButtonPic); + ccAddExternalFunctionForPlugin("SetButtonText", (void*)SetButtonText); + ccAddExternalFunctionForPlugin("SetChannelVolume", (void*)SetChannelVolume); + ccAddExternalFunctionForPlugin("SetCharacterBaseline", (void*)SetCharacterBaseline); + ccAddExternalFunctionForPlugin("SetCharacterClickable", (void*)SetCharacterClickable); + ccAddExternalFunctionForPlugin("SetCharacterFrame", (void*)SetCharacterFrame); + ccAddExternalFunctionForPlugin("SetCharacterIdle", (void*)SetCharacterIdle); + ccAddExternalFunctionForPlugin("SetCharacterIgnoreLight", (void*)SetCharacterIgnoreLight); + ccAddExternalFunctionForPlugin("SetCharacterIgnoreWalkbehinds", (void*)SetCharacterIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("SetCharacterProperty", (void*)SetCharacterProperty); + ccAddExternalFunctionForPlugin("SetCharacterBlinkView", (void*)SetCharacterBlinkView); + ccAddExternalFunctionForPlugin("SetCharacterSpeechView", (void*)SetCharacterSpeechView); + ccAddExternalFunctionForPlugin("SetCharacterSpeed", (void*)SetCharacterSpeed); + ccAddExternalFunctionForPlugin("SetCharacterSpeedEx", (void*)SetCharacterSpeedEx); + ccAddExternalFunctionForPlugin("SetCharacterTransparency", (void*)SetCharacterTransparency); + ccAddExternalFunctionForPlugin("SetCharacterView", (void*)SetCharacterView); + ccAddExternalFunctionForPlugin("SetCharacterViewEx", (void*)SetCharacterViewEx); + ccAddExternalFunctionForPlugin("SetCharacterViewOffset", (void*)SetCharacterViewOffset); + ccAddExternalFunctionForPlugin("SetCursorMode", (void*)set_cursor_mode); + ccAddExternalFunctionForPlugin("SetDefaultCursor", (void*)set_default_cursor); + ccAddExternalFunctionForPlugin("SetDialogOption", (void*)SetDialogOption); + ccAddExternalFunctionForPlugin("SetDigitalMasterVolume", (void*)SetDigitalMasterVolume); + ccAddExternalFunctionForPlugin("SetFadeColor", (void*)SetFadeColor); + ccAddExternalFunctionForPlugin("SetFrameSound", (void*)SetFrameSound); + ccAddExternalFunctionForPlugin("SetGameOption", (void*)SetGameOption); + ccAddExternalFunctionForPlugin("SetGameSpeed", (void*)SetGameSpeed); + ccAddExternalFunctionForPlugin("SetGlobalInt", (void*)SetGlobalInt); + ccAddExternalFunctionForPlugin("SetGlobalString", (void*)SetGlobalString); + ccAddExternalFunctionForPlugin("SetGraphicalVariable", (void*)SetGraphicalVariable); + ccAddExternalFunctionForPlugin("SetGUIBackgroundPic", (void*)SetGUIBackgroundPic); + ccAddExternalFunctionForPlugin("SetGUIClickable", (void*)SetGUIClickable); + ccAddExternalFunctionForPlugin("SetGUIObjectEnabled", (void*)SetGUIObjectEnabled); + ccAddExternalFunctionForPlugin("SetGUIObjectPosition", (void*)SetGUIObjectPosition); + ccAddExternalFunctionForPlugin("SetGUIObjectSize", (void*)SetGUIObjectSize); + ccAddExternalFunctionForPlugin("SetGUIPosition", (void*)SetGUIPosition); + ccAddExternalFunctionForPlugin("SetGUISize", (void*)SetGUISize); + ccAddExternalFunctionForPlugin("SetGUITransparency", (void*)SetGUITransparency); + ccAddExternalFunctionForPlugin("SetGUIZOrder", (void*)SetGUIZOrder); + ccAddExternalFunctionForPlugin("SetInvItemName", (void*)SetInvItemName); + ccAddExternalFunctionForPlugin("SetInvItemPic", (void*)set_inv_item_pic); + ccAddExternalFunctionForPlugin("SetInvDimensions", (void*)SetInvDimensions); + ccAddExternalFunctionForPlugin("SetLabelColor", (void*)SetLabelColor); + ccAddExternalFunctionForPlugin("SetLabelFont", (void*)SetLabelFont); + ccAddExternalFunctionForPlugin("SetLabelText", (void*)SetLabelText); + ccAddExternalFunctionForPlugin("SetMouseBounds", (void*)SetMouseBounds); + ccAddExternalFunctionForPlugin("SetMouseCursor", (void*)set_mouse_cursor); + ccAddExternalFunctionForPlugin("SetMousePosition", (void*)SetMousePosition); + ccAddExternalFunctionForPlugin("SetMultitaskingMode", (void*)SetMultitasking); + ccAddExternalFunctionForPlugin("SetMusicMasterVolume", (void*)SetMusicMasterVolume); + ccAddExternalFunctionForPlugin("SetMusicRepeat", (void*)SetMusicRepeat); + ccAddExternalFunctionForPlugin("SetMusicVolume", (void*)SetMusicVolume); + ccAddExternalFunctionForPlugin("SetNextCursorMode", (void*)SetNextCursor); + ccAddExternalFunctionForPlugin("SetNextScreenTransition", (void*)SetNextScreenTransition); + ccAddExternalFunctionForPlugin("SetNormalFont", (void*)SetNormalFont); + ccAddExternalFunctionForPlugin("SetObjectBaseline", (void*)SetObjectBaseline); + ccAddExternalFunctionForPlugin("SetObjectClickable", (void*)SetObjectClickable); + ccAddExternalFunctionForPlugin("SetObjectFrame", (void*)SetObjectFrame); + ccAddExternalFunctionForPlugin("SetObjectGraphic", (void*)SetObjectGraphic); + ccAddExternalFunctionForPlugin("SetObjectIgnoreWalkbehinds", (void*)SetObjectIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("SetObjectPosition", (void*)SetObjectPosition); + ccAddExternalFunctionForPlugin("SetObjectTint", (void*)SetObjectTint); + ccAddExternalFunctionForPlugin("SetObjectTransparency", (void*)SetObjectTransparency); + ccAddExternalFunctionForPlugin("SetObjectView", (void*)SetObjectView); + // ccAddExternalFunctionForPlugin("SetPalette", (void*)scSetPal); + ccAddExternalFunctionForPlugin("SetPalRGB", (void*)SetPalRGB); + ccAddExternalFunctionForPlugin("SetPlayerCharacter", (void*)SetPlayerCharacter); + ccAddExternalFunctionForPlugin("SetRegionTint", (void*)SetRegionTint); + ccAddExternalFunctionForPlugin("SetRestartPoint", (void*)SetRestartPoint); + ccAddExternalFunctionForPlugin("SetScreenTransition", (void*)SetScreenTransition); + ccAddExternalFunctionForPlugin("SetSkipSpeech", (void*)SetSkipSpeech); + ccAddExternalFunctionForPlugin("SetSliderValue", (void*)SetSliderValue); + ccAddExternalFunctionForPlugin("SetSoundVolume", (void*)SetSoundVolume); + ccAddExternalFunctionForPlugin("SetSpeechFont", (void*)SetSpeechFont); + ccAddExternalFunctionForPlugin("SetSpeechStyle", (void*)SetSpeechStyle); + ccAddExternalFunctionForPlugin("SetSpeechVolume", (void*)SetSpeechVolume); + ccAddExternalFunctionForPlugin("SetTalkingColor", (void*)SetTalkingColor); + ccAddExternalFunctionForPlugin("SetTextBoxFont", (void*)SetTextBoxFont); + ccAddExternalFunctionForPlugin("SetTextBoxText", (void*)SetTextBoxText); + ccAddExternalFunctionForPlugin("SetTextOverlay", (void*)ScPl_SetTextOverlay); + ccAddExternalFunctionForPlugin("SetTextWindowGUI", (void*)SetTextWindowGUI); + ccAddExternalFunctionForPlugin("SetTimer", (void*)script_SetTimer); + ccAddExternalFunctionForPlugin("SetViewport", (void*)SetViewport); + ccAddExternalFunctionForPlugin("SetVoiceMode", (void*)SetVoiceMode); + ccAddExternalFunctionForPlugin("SetWalkBehindBase", (void*)SetWalkBehindBase); + ccAddExternalFunctionForPlugin("ShakeScreen", (void*)ShakeScreen); + ccAddExternalFunctionForPlugin("ShakeScreenBackground", (void*)ShakeScreenBackground); + ccAddExternalFunctionForPlugin("ShowMouseCursor", (void*)ShowMouseCursor); + ccAddExternalFunctionForPlugin("SkipUntilCharacterStops", (void*)SkipUntilCharacterStops); + ccAddExternalFunctionForPlugin("StartCutscene", (void*)StartCutscene); + ccAddExternalFunctionForPlugin("StartRecording", (void*)scStartRecording); + ccAddExternalFunctionForPlugin("StopAmbientSound", (void*)StopAmbientSound); + ccAddExternalFunctionForPlugin("StopChannel", (void*)stop_and_destroy_channel); + ccAddExternalFunctionForPlugin("StopDialog", (void*)StopDialog); + ccAddExternalFunctionForPlugin("StopMoving", (void*)StopMoving); + ccAddExternalFunctionForPlugin("StopMusic", (void*)scr_StopMusic); + ccAddExternalFunctionForPlugin("StopObjectMoving", (void*)StopObjectMoving); + ccAddExternalFunctionForPlugin("StrCat", (void*)_sc_strcat); + ccAddExternalFunctionForPlugin("StrCaseComp", (void*)ags_stricmp); + ccAddExternalFunctionForPlugin("StrComp", (void*)strcmp); + ccAddExternalFunctionForPlugin("StrContains", (void*)StrContains); + ccAddExternalFunctionForPlugin("StrCopy", (void*)_sc_strcpy); + ccAddExternalFunctionForPlugin("StrFormat", (void*)ScPl_sc_sprintf); + ccAddExternalFunctionForPlugin("StrGetCharAt", (void*)StrGetCharAt); + ccAddExternalFunctionForPlugin("StringToInt", (void*)StringToInt); + ccAddExternalFunctionForPlugin("StrLen", (void*)strlen); + ccAddExternalFunctionForPlugin("StrSetCharAt", (void*)StrSetCharAt); + ccAddExternalFunctionForPlugin("StrToLowerCase", (void*)_sc_strlower); + ccAddExternalFunctionForPlugin("StrToUpperCase", (void*)_sc_strupper); + ccAddExternalFunctionForPlugin("TintScreen", (void*)TintScreen); + ccAddExternalFunctionForPlugin("UnPauseGame", (void*)UnPauseGame); + ccAddExternalFunctionForPlugin("UpdateInventory", (void*)update_invorder); + ccAddExternalFunctionForPlugin("UpdatePalette", (void*)UpdatePalette); + ccAddExternalFunctionForPlugin("Wait", (void*)scrWait); + ccAddExternalFunctionForPlugin("WaitKey", (void*)WaitKey); + ccAddExternalFunctionForPlugin("WaitMouseKey", (void*)WaitMouseKey); +} diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp new file mode 100644 index 000000000000..cf232e91f553 --- /dev/null +++ b/engines/ags/engine/ac/global_audio.cpp @@ -0,0 +1,680 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/lipsync.h" +#include "ac/path_helper.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "game/roomstruct.h" +#include "main/engine.h" +#include "media/audio/audio_system.h" +#include "ac/timer.h" +#include "util/string_compat.h" + +using namespace AGS::Common; + +extern GameSetup usetup; +extern GameState play; +extern GameSetupStruct game; +extern RoomStruct thisroom; +extern SpeechLipSyncLine *splipsync; +extern int numLipLines, curLipLine, curLipLinePhoneme; + +void StopAmbientSound (int channel) { + if ((channel < 0) || (channel >= MAX_SOUND_CHANNELS)) + quit("!StopAmbientSound: invalid channel"); + + if (ambient[channel].channel == 0) + return; + + stop_and_destroy_channel(channel); + ambient[channel].channel = 0; +} + +void PlayAmbientSound (int channel, int sndnum, int vol, int x, int y) { + // the channel parameter is to allow multiple ambient sounds in future + if ((channel < 1) || (channel == SCHAN_SPEECH) || (channel >= MAX_SOUND_CHANNELS)) + quit("!PlayAmbientSound: invalid channel number"); + if ((vol < 1) || (vol > 255)) + quit("!PlayAmbientSound: volume must be 1 to 255"); + + ScriptAudioClip *aclip = GetAudioClipForOldStyleNumber(game, false, sndnum); + if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) + return; + + // only play the sound if it's not already playing + if ((ambient[channel].channel < 1) || (!channel_is_playing(ambient[channel].channel)) || + (ambient[channel].num != sndnum)) { + + StopAmbientSound(channel); + // in case a normal non-ambient sound was playing, stop it too + stop_and_destroy_channel(channel); + + SOUNDCLIP *asound = aclip ? load_sound_and_play(aclip, true) : nullptr; + if (asound == nullptr) { + debug_script_warn ("Cannot load ambient sound %d", sndnum); + debug_script_log("FAILED to load ambient sound %d", sndnum); + return; + } + + debug_script_log("Playing ambient sound %d on channel %d", sndnum, channel); + ambient[channel].channel = channel; + asound->priority = 15; // ambient sound higher priority than normal sfx + set_clip_to_channel(channel, asound); + } + // calculate the maximum distance away the player can be, using X + // only (since X centred is still more-or-less total Y) + ambient[channel].maxdist = ((x > thisroom.Width / 2) ? x : (thisroom.Width - x)) - AMBIENCE_FULL_DIST; + ambient[channel].num = sndnum; + ambient[channel].x = x; + ambient[channel].y = y; + ambient[channel].vol = vol; + update_ambient_sound_vol(); +} + +int IsChannelPlaying(int chan) { + if (play.fast_forward) + return 0; + + if ((chan < 0) || (chan >= MAX_SOUND_CHANNELS)) + quit("!IsChannelPlaying: invalid sound channel"); + + if (channel_is_playing(chan)) + return 1; + + return 0; +} + +int IsSoundPlaying() { + if (play.fast_forward) + return 0; + + // find if there's a sound playing + AudioChannelsLock lock; + for (int i = SCHAN_NORMAL; i < MAX_SOUND_CHANNELS; i++) { + if (lock.GetChannelIfPlaying(i)) + return 1; + } + + return 0; +} + +// returns -1 on failure, channel number on success +int PlaySoundEx(int val1, int channel) { + + if (debug_flags & DBG_NOSFX) + return -1; + + ScriptAudioClip *aclip = GetAudioClipForOldStyleNumber(game, false, val1); + if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) + return -1; // if sound is off, ignore it + + if ((channel < SCHAN_NORMAL) || (channel >= MAX_SOUND_CHANNELS)) + quit("!PlaySoundEx: invalid channel specified, must be 3-7"); + + // if an ambient sound is playing on this channel, abort it + StopAmbientSound(channel); + + if (val1 < 0) { + stop_and_destroy_channel (channel); + return -1; + } + // if skipping a cutscene, don't try and play the sound + if (play.fast_forward) + return -1; + + // free the old sound + stop_and_destroy_channel (channel); + debug_script_log("Playing sound %d on channel %d", val1, channel); + + SOUNDCLIP *soundfx = aclip ? load_sound_and_play(aclip, false) : nullptr; + if (soundfx == nullptr) { + debug_script_warn("Sound sample load failure: cannot load sound %d", val1); + debug_script_log("FAILED to load sound %d", val1); + return -1; + } + + soundfx->priority = 10; + soundfx->set_volume (play.sound_volume); + set_clip_to_channel(channel,soundfx); + return channel; +} + +void StopAllSounds(int evenAmbient) { + // backwards-compatible hack -- stop Type 3 (default Sound Type) + Game_StopAudio(3); + + if (evenAmbient) + Game_StopAudio(1); +} + +void PlayMusicResetQueue(int newmus) { + play.music_queue_size = 0; + newmusic(newmus); +} + +void SeekMIDIPosition (int position) { + if (play.silent_midi == 0 && current_music_type != MUS_MIDI) + return; + + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_MUSIC); + ch->seek(position); + debug_script_log("Seek MIDI position to %d", position); +} + +int GetMIDIPosition () { + if (play.fast_forward) + return 99999; + if (play.silent_midi == 0 && current_music_type != MUS_MIDI) + return -1; // returns -1 on failure according to old manuals + + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + if (ch) { + return ch->get_pos(); + } + + return -1; +} + +int IsMusicPlaying() { + // in case they have a "while (IsMusicPlaying())" loop + if ((play.fast_forward) && (play.skip_until_char_stops < 0)) + return 0; + + // This only returns positive if there was a music started by old audio API + if (current_music_type == 0) + return 0; + + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_MUSIC); + if (ch == nullptr) + { // This was probably a hacky fix in case it was not reset by game update; TODO: find out if needed + current_music_type = 0; + return 0; + } + + bool result = (ch->is_playing()) || (crossFading > 0 && (lock.GetChannelIfPlaying(crossFading) != nullptr)); + return result ? 1 : 0; +} + +int PlayMusicQueued(int musnum) { + + // Just get the queue size + if (musnum < 0) + return play.music_queue_size; + + if ((IsMusicPlaying() == 0) && (play.music_queue_size == 0)) { + newmusic(musnum); + return 0; + } + + if (play.music_queue_size >= MAX_QUEUED_MUSIC) { + debug_script_log("Too many queued music, cannot add %d", musnum); + return 0; + } + + if ((play.music_queue_size > 0) && + (play.music_queue[play.music_queue_size - 1] >= QUEUED_MUSIC_REPEAT)) { + debug_script_warn("PlayMusicQueued: cannot queue music after a repeating tune has been queued"); + return 0; + } + + if (play.music_repeat) { + debug_script_log("Queuing music %d to loop", musnum); + musnum += QUEUED_MUSIC_REPEAT; + } + else { + debug_script_log("Queuing music %d", musnum); + } + + play.music_queue[play.music_queue_size] = musnum; + play.music_queue_size++; + + if (play.music_queue_size == 1) { + + clear_music_cache(); + + cachedQueuedMusic = load_music_from_disk(musnum, (play.music_repeat > 0)); + } + + return play.music_queue_size; +} + +void scr_StopMusic() { + play.music_queue_size = 0; + stopmusic(); +} + +void SeekMODPattern(int patnum) { + if (current_music_type != MUS_MOD) + return; + + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + if (ch) { + ch->seek (patnum); + debug_script_log("Seek MOD/XM to pattern %d", patnum); + } +} + +void SeekMP3PosMillis (int posn) { + if (current_music_type != MUS_MP3 && current_music_type != MUS_OGG) + return; + + AudioChannelsLock lock; + auto *mus_ch = lock.GetChannel(SCHAN_MUSIC); + auto *cf_ch = (crossFading > 0) ? lock.GetChannel(crossFading) : nullptr; + if (cf_ch) + cf_ch->seek(posn); + else if (mus_ch) + mus_ch->seek(posn); +} + +int GetMP3PosMillis () { + // in case they have "while (GetMP3PosMillis() < 5000) " + if (play.fast_forward) + return 999999; + if (current_music_type != MUS_MP3 && current_music_type != MUS_OGG) + return 0; // returns 0 on failure according to old manuals + + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + if (ch) { + int result = ch->get_pos_ms(); + if (result >= 0) + return result; + + return ch->get_pos (); + } + + return 0; +} + +void SetMusicVolume(int newvol) { + if ((newvol < kRoomVolumeMin) || (newvol > kRoomVolumeMax)) + quitprintf("!SetMusicVolume: invalid volume number. Must be from %d to %d.", kRoomVolumeMin, kRoomVolumeMax); + thisroom.Options.MusicVolume=(RoomVolumeMod)newvol; + update_music_volume(); +} + +void SetMusicMasterVolume(int newvol) { + const int min_volume = loaded_game_file_version < kGameVersion_330 ? 0 : + -LegacyMusicMasterVolumeAdjustment - (kRoomVolumeMax * LegacyRoomVolumeFactor); + if ((newvol < min_volume) | (newvol>100)) + quitprintf("!SetMusicMasterVolume: invalid volume - must be from %d to %d", min_volume, 100); + play.music_master_volume=newvol+LegacyMusicMasterVolumeAdjustment; + update_music_volume(); +} + +void SetSoundVolume(int newvol) { + if ((newvol<0) | (newvol>255)) + quit("!SetSoundVolume: invalid volume - must be from 0-255"); + play.sound_volume = newvol; + Game_SetAudioTypeVolume(AUDIOTYPE_LEGACY_AMBIENT_SOUND, (newvol * 100) / 255, VOL_BOTH); + Game_SetAudioTypeVolume(AUDIOTYPE_LEGACY_SOUND, (newvol * 100) / 255, VOL_BOTH); + update_ambient_sound_vol (); +} + +void SetChannelVolume(int chan, int newvol) { + if ((newvol<0) || (newvol>255)) + quit("!SetChannelVolume: invalid volume - must be from 0-255"); + if ((chan < 0) || (chan >= MAX_SOUND_CHANNELS)) + quit("!SetChannelVolume: invalid channel id"); + + AudioChannelsLock lock; + auto* ch = lock.GetChannelIfPlaying(chan); + + if (ch) { + if (chan == ambient[chan].channel) { + ambient[chan].vol = newvol; + update_ambient_sound_vol(); + } + else + ch->set_volume (newvol); + } +} + +void SetDigitalMasterVolume (int newvol) { + if ((newvol<0) | (newvol>100)) + quit("!SetDigitalMasterVolume: invalid volume - must be from 0-100"); + play.digital_master_volume = newvol; + set_volume ((newvol * 255) / 100, -1); +} + +int GetCurrentMusic() { + return play.cur_music_number; +} + +void SetMusicRepeat(int loopflag) { + play.music_repeat=loopflag; +} + +void PlayMP3File (const char *filename) { + if (strlen(filename) >= PLAYMP3FILE_MAX_FILENAME_LEN) + quit("!PlayMP3File: filename too long"); + + debug_script_log("PlayMP3File %s", filename); + + AssetPath asset_name("", filename); + + int useChan = prepare_for_new_music (); + bool doLoop = (play.music_repeat > 0); + + SOUNDCLIP *clip = nullptr; + + if (!clip) { + clip = my_load_static_ogg(asset_name, 150, doLoop); + if (clip) { + if (clip->play()) { + set_clip_to_channel(useChan, clip); + current_music_type = MUS_OGG; + play.cur_music_number = 1000; + // save the filename (if it's not what we were supplied with) + if (filename != &play.playmp3file_name[0]) + strcpy (play.playmp3file_name, filename); + } else { + clip->destroy(); + delete clip; + clip = nullptr; + } + } + } + + if (!clip) + { + clip = my_load_static_mp3(asset_name, 150, doLoop); + if (clip) { + if (clip->play()) { + set_clip_to_channel(useChan, clip); + current_music_type = MUS_MP3; + play.cur_music_number = 1000; + // save the filename (if it's not what we were supplied with) + if (filename != &play.playmp3file_name[0]) + strcpy(play.playmp3file_name, filename); + } else { + clip->destroy(); + delete clip; + clip = nullptr; + } + } + } + + if (!clip) { + set_clip_to_channel(useChan, nullptr); + debug_script_warn ("PlayMP3File: file '%s' not found or cannot play", filename); + } + + post_new_music_check(useChan); + + update_music_volume(); +} + +void PlaySilentMIDI (int mnum) { + if (current_music_type == MUS_MIDI) + quit("!PlaySilentMIDI: proper midi music is in progress"); + + set_volume (-1, 0); + play.silent_midi = mnum; + play.silent_midi_channel = SCHAN_SPEECH; + stop_and_destroy_channel(play.silent_midi_channel); + // No idea why it uses speech voice channel, but since it does (and until this is changed) + // we have to correctly reset speech voice in case there was a nonblocking speech + if (play.IsNonBlockingVoiceSpeech()) + stop_voice_nonblocking(); + + SOUNDCLIP *clip = load_sound_clip_from_old_style_number(true, mnum, false); + if (clip == nullptr) + { + quitprintf("!PlaySilentMIDI: failed to load aMusic%d", mnum); + } + AudioChannelsLock lock; + lock.SetChannel(play.silent_midi_channel, clip); + if (!clip->play()) { + clip->destroy(); + delete clip; + clip = nullptr; + quitprintf("!PlaySilentMIDI: failed to play aMusic%d", mnum); + } + clip->set_volume_percent(0); +} + +void SetSpeechVolume(int newvol) { + if ((newvol<0) | (newvol>255)) + quit("!SetSpeechVolume: invalid volume - must be from 0-255"); + + AudioChannelsLock lock; + auto* ch = lock.GetChannel(SCHAN_SPEECH); + if (ch) + ch->set_volume (newvol); + play.speech_volume = newvol; +} + +// 0 = text only +// 1 = voice & text +// 2 = voice only +void SetVoiceMode (int newmod) { + if ((newmod < 0) | (newmod > 2)) + quit("!SetVoiceMode: invalid mode number (must be 0,1,2)"); + // If speech is turned off, store the mode anyway in case the + // user adds the VOX file later + if (play.want_speech < 0) + play.want_speech = (-newmod) - 1; + else + play.want_speech = newmod; +} + +int GetVoiceMode() +{ + return play.want_speech >= 0 ? play.want_speech : -(play.want_speech + 1); +} + +int IsVoxAvailable() { + if (play.want_speech < 0) + return 0; + return 1; +} + +int IsMusicVoxAvailable () { + return play.separate_music_lib; +} + +extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; + +ScriptAudioChannel *PlayVoiceClip(CharacterInfo *ch, int sndid, bool as_speech) +{ + if (!play_voice_nonblocking(ch->index_id, sndid, as_speech)) + return NULL; + return &scrAudioChannel[SCHAN_SPEECH]; +} + +// Construct an asset name for the voice-over clip for the given character and cue id +String get_cue_filename(int charid, int sndid) +{ + String script_name; + if (charid >= 0) + { + // append the first 4 characters of the script name to the filename + if (game.chars[charid].scrname[0] == 'c') + script_name.SetString(&game.chars[charid].scrname[1], 4); + else + script_name.SetString(game.chars[charid].scrname, 4); + } + else + { + script_name = "NARR"; + } + return String::FromFormat("%s%d", script_name.GetCStr(), sndid); +} + +// Play voice-over clip on the common channel; +// voice_name should be bare clip name without extension +static bool play_voice_clip_on_channel(const String &voice_name) +{ + stop_and_destroy_channel(SCHAN_SPEECH); + + String asset_name = voice_name; + asset_name.Append(".wav"); + SOUNDCLIP *speechmp3 = my_load_wave(get_voice_over_assetpath(asset_name), play.speech_volume, 0); + + if (speechmp3 == nullptr) { + asset_name.ReplaceMid(asset_name.GetLength() - 3, 3, "ogg"); + speechmp3 = my_load_ogg(get_voice_over_assetpath(asset_name), play.speech_volume); + } + + if (speechmp3 == nullptr) { + asset_name.ReplaceMid(asset_name.GetLength() - 3, 3, "mp3"); + speechmp3 = my_load_mp3(get_voice_over_assetpath(asset_name), play.speech_volume); + } + + if (speechmp3 != nullptr) { + if (!speechmp3->play()) { + // not assigned to a channel, so clean up manually. + speechmp3->destroy(); + delete speechmp3; + speechmp3 = nullptr; + } + } + + if (speechmp3 == nullptr) { + debug_script_warn("Speech load failure: '%s'", voice_name.GetCStr()); + return false; + } + + set_clip_to_channel(SCHAN_SPEECH,speechmp3); + return true; +} + +// Play voice-over clip and adjust audio volumes; +// voice_name should be bare clip name without extension +static bool play_voice_clip_impl(const String &voice_name, bool as_speech, bool is_blocking) +{ + if (!play_voice_clip_on_channel(voice_name)) + return false; + if (!as_speech) + return true; + + play.speech_has_voice = true; + play.speech_voice_blocking = is_blocking; + + cancel_scheduled_music_update(); + play.music_vol_was = play.music_master_volume; + // Negative value means set exactly; positive means drop that amount + if (play.speech_music_drop < 0) + play.music_master_volume = -play.speech_music_drop; + else + play.music_master_volume -= play.speech_music_drop; + apply_volume_drop_modifier(true); + update_music_volume(); + update_ambient_sound_vol(); + return true; +} + +// Stop voice-over clip and schedule audio volume reset +static void stop_voice_clip_impl() +{ + play.music_master_volume = play.music_vol_was; + // update the music in a bit (fixes two speeches follow each other + // and music going up-then-down) + schedule_music_update_at(AGS_Clock::now() + std::chrono::milliseconds(500)); + stop_and_destroy_channel(SCHAN_SPEECH); +} + +bool play_voice_speech(int charid, int sndid) +{ + // don't play speech if we're skipping a cutscene + if (!play.ShouldPlayVoiceSpeech()) + return false; + + String voice_file = get_cue_filename(charid, sndid); + if (!play_voice_clip_impl(voice_file, true, true)) + return false; + + int ii; // Compare the base file name to the .pam file name + curLipLine = -1; // See if we have voice lip sync for this line + curLipLinePhoneme = -1; + for (ii = 0; ii < numLipLines; ii++) { + if (ags_stricmp(splipsync[ii].filename, voice_file) == 0) { + curLipLine = ii; + break; + } + } + // if the lip-sync is being used for voice sync, disable + // the text-related lipsync + if (numLipLines > 0) + game.options[OPT_LIPSYNCTEXT] = 0; + + // change Sierra w/bgrnd to Sierra without background when voice + // is available (for Tierra) + if ((game.options[OPT_SPEECHTYPE] == 2) && (play.no_textbg_when_voice > 0)) { + game.options[OPT_SPEECHTYPE] = 1; + play.no_textbg_when_voice = 2; + } + return true; +} + +bool play_voice_nonblocking(int charid, int sndid, bool as_speech) +{ + // don't play voice if we're skipping a cutscene + if (!play.ShouldPlayVoiceSpeech()) + return false; + // don't play voice if there's a blocking speech with voice-over already + if (play.IsBlockingVoiceSpeech()) + return false; + + String voice_file = get_cue_filename(charid, sndid); + return play_voice_clip_impl(voice_file, as_speech, false); +} + +void stop_voice_speech() +{ + if (!play.speech_has_voice) + return; + + stop_voice_clip_impl(); + + // Reset lipsync + curLipLine = -1; + // Set back to Sierra w/bgrnd + if (play.no_textbg_when_voice == 2) + { + play.no_textbg_when_voice = 1; + game.options[OPT_SPEECHTYPE] = 2; + } + play.speech_has_voice = false; + play.speech_voice_blocking = false; +} + +void stop_voice_nonblocking() +{ + if (!play.speech_has_voice) + return; + stop_voice_clip_impl(); + // Only reset speech flags if we are truly playing a non-blocking voice; + // otherwise we might be inside blocking speech function and should let + // it keep these flags to be able to finalize properly. + // This is an imperfection of current speech implementation. + if (!play.speech_voice_blocking) + { + play.speech_has_voice = false; + play.speech_voice_blocking = false; + } +} diff --git a/engines/ags/engine/ac/global_audio.h b/engines/ags/engine/ac/global_audio.h new file mode 100644 index 000000000000..9c9b55767801 --- /dev/null +++ b/engines/ags/engine/ac/global_audio.h @@ -0,0 +1,71 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALAUDIO_H +#define __AGS_EE_AC__GLOBALAUDIO_H + +void StopAmbientSound (int channel); +void PlayAmbientSound (int channel, int sndnum, int vol, int x, int y); +int IsChannelPlaying(int chan); +int IsSoundPlaying(); +// returns -1 on failure, channel number on success +int PlaySoundEx(int val1, int channel); +void StopAllSounds(int evenAmbient); + +void PlayMusicResetQueue(int newmus); +void SeekMIDIPosition (int position); +int GetMIDIPosition (); +int IsMusicPlaying(); +int PlayMusicQueued(int musnum); +void scr_StopMusic(); +void SeekMODPattern(int patnum); +void SeekMP3PosMillis (int posn); +int GetMP3PosMillis (); +void SetMusicVolume(int newvol); +void SetMusicMasterVolume(int newvol); +void SetSoundVolume(int newvol); +void SetChannelVolume(int chan, int newvol); +void SetDigitalMasterVolume (int newvol); +int GetCurrentMusic(); +void SetMusicRepeat(int loopflag); +void PlayMP3File (const char *filename); +void PlaySilentMIDI (int mnum); + +void SetSpeechVolume(int newvol); +void SetVoiceMode (int newmod); +int GetVoiceMode (); +int IsVoxAvailable(); +int IsMusicVoxAvailable (); + +struct CharacterInfo; +struct ScriptAudioChannel; +// Starts voice-over playback and returns audio channel it is played on; +// as_speech flag determines whether engine should apply speech-related logic +// as well, such as temporary volume reduction. +ScriptAudioChannel *PlayVoiceClip(CharacterInfo *ch, int sndid, bool as_speech); + +//============================================================================= +// Play voice-over for the active blocking speech and initialize relevant data +bool play_voice_speech(int charid, int sndid); +// Play voice-over clip in non-blocking manner +bool play_voice_nonblocking(int charid, int sndid, bool as_speech); +// Stop voice-over for the active speech and reset relevant data +void stop_voice_speech(); +// Stop non-blocking voice-over and revert audio volumes if necessary +void stop_voice_nonblocking(); + +#endif // __AGS_EE_AC__GLOBALAUDIO_H diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp new file mode 100644 index 000000000000..f2d66f585a2c --- /dev/null +++ b/engines/ags/engine/ac/global_button.cpp @@ -0,0 +1,99 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_button.h" +#include "ac/common.h" +#include "ac/button.h" +#include "ac/gamesetupstruct.h" +#include "ac/string.h" +#include "gui/guimain.h" +#include "gui/guibutton.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; + +void SetButtonText(int guin,int objn, const char*newtx) { + VALIDATE_STRING(newtx); + if ((guin<0) | (guin>=game.numgui)) + quit("!SetButtonText: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) + quit("!SetButtonText: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUIButton) + quit("!SetButtonText: specified control is not a button"); + + GUIButton*guil=(GUIButton*)guis[guin].GetControl(objn); + Button_SetText(guil, newtx); +} + + +void AnimateButton(int guin, int objn, int view, int loop, int speed, int repeat) { + if ((guin<0) | (guin>=game.numgui)) quit("!AnimateButton: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!AnimateButton: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUIButton) + quit("!AnimateButton: specified control is not a button"); + + Button_Animate((GUIButton*)guis[guin].GetControl(objn), view, loop, speed, repeat); +} + + +int GetButtonPic(int guin, int objn, int ptype) { + if ((guin<0) | (guin>=game.numgui)) quit("!GetButtonPic: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!GetButtonPic: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUIButton) + quit("!GetButtonPic: specified control is not a button"); + if ((ptype < 0) | (ptype > 3)) quit("!GetButtonPic: invalid pic type"); + + GUIButton*guil=(GUIButton*)guis[guin].GetControl(objn); + + if (ptype == 0) { + // currently displayed pic + if (guil->CurrentImage < 0) + return guil->Image; + return guil->CurrentImage; + } + else if (ptype==1) { + // nomal pic + return guil->Image; + } + else if (ptype==2) { + // mouseover pic + return guil->MouseOverImage; + } + else { // pushed pic + return guil->PushedImage; + } + + quit("internal error in getbuttonpic"); +} + +void SetButtonPic(int guin,int objn,int ptype,int slotn) { + if ((guin<0) | (guin>=game.numgui)) quit("!SetButtonPic: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetButtonPic: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUIButton) + quit("!SetButtonPic: specified control is not a button"); + if ((ptype<1) | (ptype>3)) quit("!SetButtonPic: invalid pic type"); + + GUIButton*guil=(GUIButton*)guis[guin].GetControl(objn); + if (ptype==1) { + Button_SetNormalGraphic(guil, slotn); + } + else if (ptype==2) { + // mouseover pic + Button_SetMouseOverGraphic(guil, slotn); + } + else { // pushed pic + Button_SetPushedGraphic(guil, slotn); + } +} diff --git a/engines/ags/engine/ac/global_button.h b/engines/ags/engine/ac/global_button.h new file mode 100644 index 000000000000..cb98cb53e29b --- /dev/null +++ b/engines/ags/engine/ac/global_button.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALBUTTON_H +#define __AGS_EE_AC__GLOBALBUTTON_H + +void SetButtonText(int guin,int objn, const char*newtx); +void AnimateButton(int guin, int objn, int view, int loop, int speed, int repeat); +int GetButtonPic(int guin, int objn, int ptype); +void SetButtonPic(int guin,int objn,int ptype,int slotn); + +#endif // __AGS_EE_AC__GLOBALBUTTON_H diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp new file mode 100644 index 000000000000..39f018ce68b1 --- /dev/null +++ b/engines/ags/engine/ac/global_character.cpp @@ -0,0 +1,566 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS Character functions +// +//============================================================================= + +#include "ac/global_character.h" +#include "ac/common.h" +#include "ac/view.h" +#include "ac/character.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_overlay.h" +#include "ac/global_translation.h" +#include "ac/object.h" +#include "ac/overlay.h" +#include "ac/properties.h" +#include "ac/screenoverlay.h" +#include "ac/string.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "main/game_run.h" +#include "script/script.h" + +using namespace AGS::Common; + + +extern GameSetupStruct game; +extern ViewStruct*views; +extern RoomObject*objs; +extern RoomStruct thisroom; +extern GameState play; +extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; +extern ScriptInvItem scrInv[MAX_INV]; + +// defined in character unit +extern CharacterExtras *charextra; +extern CharacterInfo*playerchar; +extern int32_t _sc_PlayerCharPtr; +extern CharacterInfo*playerchar; + + +void StopMoving(int chaa) { + + Character_StopMoving(&game.chars[chaa]); +} + +void ReleaseCharacterView(int chat) { + if (!is_valid_character(chat)) + quit("!ReleaseCahracterView: invalid character supplied"); + + Character_UnlockView(&game.chars[chat]); +} + +void MoveToWalkableArea(int charid) { + if (!is_valid_character(charid)) + quit("!MoveToWalkableArea: invalid character specified"); + + Character_PlaceOnWalkableArea(&game.chars[charid]); +} + +void FaceLocation(int cha, int xx, int yy) { + if (!is_valid_character(cha)) + quit("!FaceLocation: Invalid character specified"); + + Character_FaceLocation(&game.chars[cha], xx, yy, BLOCKING); +} + +void FaceCharacter(int cha,int toface) { + if (!is_valid_character(cha)) + quit("!FaceCharacter: Invalid character specified"); + if (!is_valid_character(toface)) + quit("!FaceCharacter: invalid character specified"); + + Character_FaceCharacter(&game.chars[cha], &game.chars[toface], BLOCKING); +} + + +void SetCharacterIdle(int who, int iview, int itime) { + if (!is_valid_character(who)) + quit("!SetCharacterIdle: Invalid character specified"); + + Character_SetIdleView(&game.chars[who], iview, itime); +} + + + +int GetCharacterWidth(int ww) { + CharacterInfo *char1 = &game.chars[ww]; + + if (charextra[ww].width < 1) + { + if ((char1->view < 0) || + (char1->loop >= views[char1->view].numLoops) || + (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) + { + debug_script_warn("GetCharacterWidth: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); + return data_to_game_coord(4); + } + + return game.SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Width; + } + else + return charextra[ww].width; +} + +int GetCharacterHeight(int charid) { + CharacterInfo *char1 = &game.chars[charid]; + + if (charextra[charid].height < 1) + { + if ((char1->view < 0) || + (char1->loop >= views[char1->view].numLoops) || + (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) + { + debug_script_warn("GetCharacterHeight: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); + return data_to_game_coord(2); + } + + return game.SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Height; + } + else + return charextra[charid].height; +} + + + +void SetCharacterBaseline (int obn, int basel) { + if (!is_valid_character(obn)) quit("!SetCharacterBaseline: invalid object number specified"); + + Character_SetBaseline(&game.chars[obn], basel); +} + +// pass trans=0 for fully solid, trans=100 for fully transparent +void SetCharacterTransparency(int obn,int trans) { + if (!is_valid_character(obn)) + quit("!SetCharTransparent: invalid character number specified"); + + Character_SetTransparency(&game.chars[obn], trans); +} + +void scAnimateCharacter (int chh, int loopn, int sppd, int rept) { + if (!is_valid_character(chh)) + quit("AnimateCharacter: invalid character"); + + animate_character(&game.chars[chh], loopn, sppd, rept); +} + +void AnimateCharacterEx(int chh, int loopn, int sppd, int rept, int direction, int blocking) { + if ((direction < 0) || (direction > 1)) + quit("!AnimateCharacterEx: invalid direction"); + if (!is_valid_character(chh)) + quit("AnimateCharacter: invalid character"); + + if (direction) + direction = BACKWARDS; + else + direction = FORWARDS; + + if (blocking) + blocking = BLOCKING; + else + blocking = IN_BACKGROUND; + + Character_Animate(&game.chars[chh], loopn, sppd, rept, blocking, direction); + +} + + +void SetPlayerCharacter(int newchar) { + if (!is_valid_character(newchar)) + quit("!SetPlayerCharacter: Invalid character specified"); + + Character_SetAsPlayer(&game.chars[newchar]); +} + +void FollowCharacterEx(int who, int tofollow, int distaway, int eagerness) { + if (!is_valid_character(who)) + quit("!FollowCharacter: Invalid character specified"); + CharacterInfo *chtofollow = nullptr; + if (tofollow != -1) + { + if (!is_valid_character(tofollow)) + quit("!FollowCharacterEx: invalid character to follow"); + else + chtofollow = &game.chars[tofollow]; + } + + Character_FollowCharacter(&game.chars[who], chtofollow, distaway, eagerness); +} + +void FollowCharacter(int who, int tofollow) { + FollowCharacterEx(who,tofollow,10,97); +} + +void SetCharacterIgnoreLight (int who, int yesorno) { + if (!is_valid_character(who)) + quit("!SetCharacterIgnoreLight: Invalid character specified"); + + Character_SetIgnoreLighting(&game.chars[who], yesorno); +} + + + + +void MoveCharacter(int cc,int xx,int yy) { + walk_character(cc,xx,yy,0, true); +} +void MoveCharacterDirect(int cc,int xx, int yy) { + walk_character(cc,xx,yy,1, true); +} +void MoveCharacterStraight(int cc,int xx, int yy) { + if (!is_valid_character(cc)) + quit("!MoveCharacterStraight: invalid character specified"); + + Character_WalkStraight(&game.chars[cc], xx, yy, IN_BACKGROUND); +} + +// Append to character path +void MoveCharacterPath (int chac, int tox, int toy) { + if (!is_valid_character(chac)) + quit("!MoveCharacterPath: invalid character specified"); + + Character_AddWaypoint(&game.chars[chac], tox, toy); +} + + +int GetPlayerCharacter() { + return game.playercharacter; +} + +void SetCharacterSpeedEx(int chaa, int xspeed, int yspeed) { + if (!is_valid_character(chaa)) + quit("!SetCharacterSpeedEx: invalid character"); + + Character_SetSpeed(&game.chars[chaa], xspeed, yspeed); + +} + +void SetCharacterSpeed(int chaa,int nspeed) { + SetCharacterSpeedEx(chaa, nspeed, nspeed); +} + +void SetTalkingColor(int chaa,int ncol) { + if (!is_valid_character(chaa)) quit("!SetTalkingColor: invalid character"); + + Character_SetSpeechColor(&game.chars[chaa], ncol); +} + +void SetCharacterSpeechView (int chaa, int vii) { + if (!is_valid_character(chaa)) + quit("!SetCharacterSpeechView: invalid character specified"); + + Character_SetSpeechView(&game.chars[chaa], vii); +} + +void SetCharacterBlinkView (int chaa, int vii, int intrv) { + if (!is_valid_character(chaa)) + quit("!SetCharacterBlinkView: invalid character specified"); + + Character_SetBlinkView(&game.chars[chaa], vii); + Character_SetBlinkInterval(&game.chars[chaa], intrv); +} + +void SetCharacterView(int chaa,int vii) { + if (!is_valid_character(chaa)) + quit("!SetCharacterView: invalid character specified"); + + Character_LockView(&game.chars[chaa], vii); +} + +void SetCharacterFrame(int chaa, int view, int loop, int frame) { + + Character_LockViewFrame(&game.chars[chaa], view, loop, frame); +} + +// similar to SetCharView, but aligns the frame to make it line up +void SetCharacterViewEx (int chaa, int vii, int loop, int align) { + + Character_LockViewAligned(&game.chars[chaa], vii, loop, align); +} + +void SetCharacterViewOffset (int chaa, int vii, int xoffs, int yoffs) { + + Character_LockViewOffset(&game.chars[chaa], vii, xoffs, yoffs); +} + + +void ChangeCharacterView(int chaa,int vii) { + if (!is_valid_character(chaa)) + quit("!ChangeCharacterView: invalid character specified"); + + Character_ChangeView(&game.chars[chaa], vii); +} + +void SetCharacterClickable (int cha, int clik) { + if (!is_valid_character(cha)) + quit("!SetCharacterClickable: Invalid character specified"); + // make the character clicklabe (reset "No interaction" bit) + game.chars[cha].flags&=~CHF_NOINTERACT; + // if they don't want it clickable, set the relevant bit + if (clik == 0) + game.chars[cha].flags|=CHF_NOINTERACT; +} + +void SetCharacterIgnoreWalkbehinds (int cha, int clik) { + if (!is_valid_character(cha)) + quit("!SetCharacterIgnoreWalkbehinds: Invalid character specified"); + + Character_SetIgnoreWalkbehinds(&game.chars[cha], clik); +} + + +void MoveCharacterToObject(int chaa,int obbj) { + // invalid object, do nothing + // this allows MoveCharacterToObject(EGO, GetObjectAt(...)); + if (!is_valid_object(obbj)) + return; + + walk_character(chaa,objs[obbj].x+5,objs[obbj].y+6,0, true); + + GameLoopUntilNotMoving(&game.chars[chaa].walking); +} + +void MoveCharacterToHotspot(int chaa,int hotsp) { + if ((hotsp<0) || (hotsp>=MAX_ROOM_HOTSPOTS)) + quit("!MovecharacterToHotspot: invalid hotspot"); + if (thisroom.Hotspots[hotsp].WalkTo.X<1) return; + walk_character(chaa,thisroom.Hotspots[hotsp].WalkTo.X,thisroom.Hotspots[hotsp].WalkTo.Y,0, true); + + GameLoopUntilNotMoving(&game.chars[chaa].walking); +} + +void MoveCharacterBlocking(int chaa,int xx,int yy,int direct) { + if (!is_valid_character (chaa)) + quit("!MoveCharacterBlocking: invalid character"); + + // check if they try to move the player when Hide Player Char is + // ticked -- otherwise this will hang the game + if (game.chars[chaa].on != 1) + { + debug_script_warn("MoveCharacterBlocking: character is turned off (is Hide Player Character selected?) and cannot be moved"); + return; + } + + if (direct) + MoveCharacterDirect(chaa,xx,yy); + else + MoveCharacter(chaa,xx,yy); + + GameLoopUntilNotMoving(&game.chars[chaa].walking); +} + +int GetCharacterSpeechAnimationDelay(CharacterInfo *cha) +{ + if ((loaded_game_file_version < kGameVersion_312) && (game.options[OPT_SPEECHTYPE] != 0)) + { + // legacy versions of AGS assigned a fixed delay to Sierra-style speech only + return 5; + } + if (game.options[OPT_GLOBALTALKANIMSPD] != 0) + return play.talkanim_speed; + else + return cha->speech_anim_speed; +} + +void RunCharacterInteraction (int cc, int mood) { + if (!is_valid_character(cc)) + quit("!RunCharacterInteraction: invalid character"); + + int passon=-1,cdata=-1; + if (mood==MODE_LOOK) passon=0; + else if (mood==MODE_HAND) passon=1; + else if (mood==MODE_TALK) passon=2; + else if (mood==MODE_USE) { passon=3; + cdata=playerchar->activeinv; + play.usedinv=cdata; + } + else if (mood==MODE_PICKUP) passon = 5; + else if (mood==MODE_CUSTOM1) passon = 6; + else if (mood==MODE_CUSTOM2) passon = 7; + + evblockbasename="character%d"; evblocknum=cc; + if (loaded_game_file_version > kGameVersion_272) + { + if (passon>=0) + run_interaction_script(game.charScripts[cc].get(), passon, 4, (passon == 3)); + run_interaction_script(game.charScripts[cc].get(), 4); // any click on char + } + else + { + if (passon>=0) + run_interaction_event(game.intrChar[cc].get(),passon, 4, (passon == 3)); + run_interaction_event(game.intrChar[cc].get(),4); // any click on char + } +} + +int AreCharObjColliding(int charid,int objid) { + if (!is_valid_character(charid)) + quit("!AreCharObjColliding: invalid character"); + if (!is_valid_object(objid)) + quit("!AreCharObjColliding: invalid object number"); + + return Character_IsCollidingWithObject(&game.chars[charid], &scrObj[objid]); +} + +int AreCharactersColliding(int cchar1,int cchar2) { + if (!is_valid_character(cchar1)) + quit("!AreCharactersColliding: invalid char1"); + if (!is_valid_character(cchar2)) + quit("!AreCharactersColliding: invalid char2"); + + return Character_IsCollidingWithChar(&game.chars[cchar1], &game.chars[cchar2]); +} + +int GetCharacterProperty (int cha, const char *property) { + if (!is_valid_character(cha)) + quit("!GetCharacterProperty: invalid character"); + return get_int_property (game.charProps[cha], play.charProps[cha], property); +} + +void SetCharacterProperty (int who, int flag, int yesorno) { + if (!is_valid_character(who)) + quit("!SetCharacterProperty: Invalid character specified"); + + Character_SetOption(&game.chars[who], flag, yesorno); +} + +void GetCharacterPropertyText (int item, const char *property, char *bufer) { + get_text_property (game.charProps[item], play.charProps[item], property, bufer); +} + +int GetCharIDAtScreen(int xx, int yy) { + VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); + if (vpt.second < 0) + return -1; + return is_pos_on_character(vpt.first.X, vpt.first.Y); +} + +void SetActiveInventory(int iit) { + + ScriptInvItem *tosend = nullptr; + if ((iit > 0) && (iit < game.numinvitems)) + tosend = &scrInv[iit]; + else if (iit != -1) + quitprintf("!SetActiveInventory: invalid inventory number %d", iit); + + Character_SetActiveInventory(playerchar, tosend); +} + +void update_invorder() { + for (int cc = 0; cc < game.numcharacters; cc++) { + charextra[cc].invorder_count = 0; + int ff, howmany; + // Iterate through all inv items, adding them once (or multiple + // times if requested) to the list. + for (ff=0;ff < game.numinvitems;ff++) { + howmany = game.chars[cc].inv[ff]; + if ((game.options[OPT_DUPLICATEINV] == 0) && (howmany > 1)) + howmany = 1; + + for (int ts = 0; ts < howmany; ts++) { + if (charextra[cc].invorder_count >= MAX_INVORDER) + quit("!Too many inventory items to display: 500 max"); + + charextra[cc].invorder[charextra[cc].invorder_count] = ff; + charextra[cc].invorder_count++; + } + } + } + // backwards compatibility + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; + + guis_need_update = 1; +} + +void add_inventory(int inum) { + if ((inum < 0) || (inum >= MAX_INV)) + quit("!AddInventory: invalid inventory number"); + + Character_AddInventory(playerchar, &scrInv[inum], SCR_NO_VALUE); + + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; +} + +void lose_inventory(int inum) { + if ((inum < 0) || (inum >= MAX_INV)) + quit("!LoseInventory: invalid inventory number"); + + Character_LoseInventory(playerchar, &scrInv[inum]); + + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; +} + +void AddInventoryToCharacter(int charid, int inum) { + if (!is_valid_character(charid)) + quit("!AddInventoryToCharacter: invalid character specified"); + if ((inum < 1) || (inum >= game.numinvitems)) + quit("!AddInventory: invalid inv item specified"); + + Character_AddInventory(&game.chars[charid], &scrInv[inum], SCR_NO_VALUE); +} + +void LoseInventoryFromCharacter(int charid, int inum) { + if (!is_valid_character(charid)) + quit("!LoseInventoryFromCharacter: invalid character specified"); + if ((inum < 1) || (inum >= game.numinvitems)) + quit("!AddInventory: invalid inv item specified"); + + Character_LoseInventory(&game.chars[charid], &scrInv[inum]); +} + +void DisplayThought(int chid, const char *text) { + if ((chid < 0) || (chid >= game.numcharacters)) + quit("!DisplayThought: invalid character specified"); + + _DisplayThoughtCore(chid, text); +} + +void __sc_displayspeech(int chid, const char *text) { + if ((chid<0) || (chid>=game.numcharacters)) + quit("!DisplaySpeech: invalid character specified"); + + _DisplaySpeechCore(chid, text); +} + +// **** THIS IS UNDOCUMENTED BECAUSE IT DOESN'T WORK PROPERLY +// **** AT 640x400 AND DOESN'T USE THE RIGHT SPEECH STYLE +void DisplaySpeechAt (int xx, int yy, int wii, int aschar, const char*spch) { + data_to_game_coords(&xx, &yy); + wii = data_to_game_coord(wii); + _displayspeech (get_translation(spch), aschar, xx, yy, wii, 0); +} + +int DisplaySpeechBackground(int charid, const char*speel) { + // remove any previous background speech for this character + for (size_t i = 0; i < screenover.size();) { + if (screenover[i].bgSpeechForChar == charid) + remove_screen_overlay_index(i); + else + i++; + } + + int ovrl=CreateTextOverlay(OVR_AUTOPLACE,charid,play.GetUIViewport().GetWidth()/2,FONT_SPEECH, + -game.chars[charid].talkcolor, get_translation(speel), DISPLAYTEXT_NORMALOVERLAY); + + int scid = find_overlay_of_type(ovrl); + screenover[scid].bgSpeechForChar = charid; + screenover[scid].timeout = GetTextDisplayTime(speel, 1); + return ovrl; +} diff --git a/engines/ags/engine/ac/global_character.h b/engines/ags/engine/ac/global_character.h new file mode 100644 index 000000000000..ad066c3ad212 --- /dev/null +++ b/engines/ags/engine/ac/global_character.h @@ -0,0 +1,87 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALCHARACTER_H +#define __AGS_EE_AC__GLOBALCHARACTER_H + +#include "ac/characterinfo.h" + +void StopMoving(int chaa); +void ReleaseCharacterView(int chat); +void MoveToWalkableArea(int charid); +void FaceLocation(int cha, int xx, int yy); +void FaceCharacter(int cha,int toface); +void SetCharacterIdle(int who, int iview, int itime); +int GetCharacterWidth(int ww); +int GetCharacterHeight(int charid); +void SetCharacterBaseline (int obn, int basel); +// pass trans=0 for fully solid, trans=100 for fully transparent +void SetCharacterTransparency(int obn,int trans); +void scAnimateCharacter (int chh, int loopn, int sppd, int rept); +void AnimateCharacterEx(int chh, int loopn, int sppd, int rept, int direction, int blocking); +void SetPlayerCharacter(int newchar); +void FollowCharacterEx(int who, int tofollow, int distaway, int eagerness); +void FollowCharacter(int who, int tofollow); +void SetCharacterIgnoreLight (int who, int yesorno); +void MoveCharacter(int cc,int xx,int yy); +void MoveCharacterDirect(int cc,int xx, int yy); +void MoveCharacterStraight(int cc,int xx, int yy); +// Append to character path +void MoveCharacterPath (int chac, int tox, int toy); + +void SetCharacterSpeedEx(int chaa, int xspeed, int yspeed); +void SetCharacterSpeed(int chaa,int nspeed); +void SetTalkingColor(int chaa,int ncol); +void SetCharacterSpeechView (int chaa, int vii); +void SetCharacterBlinkView (int chaa, int vii, int intrv); +void SetCharacterView(int chaa,int vii); +void SetCharacterFrame(int chaa, int view, int loop, int frame); +// similar to SetCharView, but aligns the frame to make it line up +void SetCharacterViewEx (int chaa, int vii, int loop, int align); +void SetCharacterViewOffset (int chaa, int vii, int xoffs, int yoffs); +void ChangeCharacterView(int chaa,int vii); +void SetCharacterClickable (int cha, int clik); +void SetCharacterIgnoreWalkbehinds (int cha, int clik); +void MoveCharacterToObject(int chaa,int obbj); +void MoveCharacterToHotspot(int chaa,int hotsp); +void MoveCharacterBlocking(int chaa,int xx,int yy,int direct); + +void RunCharacterInteraction (int cc, int mood); +int AreCharObjColliding(int charid,int objid); +int AreCharactersColliding(int cchar1,int cchar2); + +int GetCharacterProperty (int cha, const char *property); +void SetCharacterProperty (int who, int flag, int yesorno); +int GetPlayerCharacter(); +void GetCharacterPropertyText (int item, const char *property, char *bufer); + +int GetCharacterSpeechAnimationDelay(CharacterInfo *cha); +int GetCharIDAtScreen(int xx, int yy); + +void SetActiveInventory(int iit); +void AddInventoryToCharacter(int charid, int inum); +void LoseInventoryFromCharacter(int charid, int inum); +void update_invorder(); +void add_inventory(int inum); +void lose_inventory(int inum); + +void DisplayThought(int chid, const char *text); +void __sc_displayspeech(int chid, const char *text); +void DisplaySpeechAt (int xx, int yy, int wii, int aschar, const char*spch); +int DisplaySpeechBackground(int charid, const char*speel); + +#endif // __AGS_EE_AC__CHARACTEREXTRAS_H diff --git a/engines/ags/engine/ac/global_datetime.cpp b/engines/ags/engine/ac/global_datetime.cpp new file mode 100644 index 000000000000..e89311efc00b --- /dev/null +++ b/engines/ags/engine/ac/global_datetime.cpp @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/global_datetime.h" +#include "ac/datetime.h" +#include "ac/common.h" + +int sc_GetTime(int whatti) { + ScriptDateTime *sdt = DateTime_Now_Core(); + int returnVal = 0; + + if (whatti == 1) returnVal = sdt->hour; + else if (whatti == 2) returnVal = sdt->minute; + else if (whatti == 3) returnVal = sdt->second; + else if (whatti == 4) returnVal = sdt->day; + else if (whatti == 5) returnVal = sdt->month; + else if (whatti == 6) returnVal = sdt->year; + else quit("!GetTime: invalid parameter passed"); + + delete sdt; + + return returnVal; +} + +int GetRawTime () { + // TODO: we might need to modify script API to support larger time type + return static_cast(time(nullptr)); +} diff --git a/engines/ags/engine/ac/global_datetime.h b/engines/ags/engine/ac/global_datetime.h new file mode 100644 index 000000000000..59080d1a7a48 --- /dev/null +++ b/engines/ags/engine/ac/global_datetime.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALDATETIME_H +#define __AGS_EE_AC__GLOBALDATETIME_H + +int sc_GetTime(int whatti) ; +int GetRawTime (); + +#endif // __AGS_EE_AC__GLOBALDATETIME_H diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp new file mode 100644 index 000000000000..582e1d200947 --- /dev/null +++ b/engines/ags/engine/ac/global_debug.cpp @@ -0,0 +1,190 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_debug.h" +#include "ac/common.h" +#include "ac/characterinfo.h" +#include "ac/draw.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_character.h" +#include "ac/global_display.h" +#include "ac/global_room.h" +#include "ac/movelist.h" +#include "ac/properties.h" +#include "ac/sys_events.h" +#include "ac/tree_map.h" +#include "ac/walkablearea.h" +#include "gfx/gfxfilter.h" +#include "gui/guidialog.h" +#include "script/cc_options.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "main/main.h" +#include "ac/spritecache.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" +#include "main/graphics_mode.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameSetup usetup; +extern GameState play; +extern RoomStruct thisroom; +extern CharacterInfo*playerchar; + +extern int convert_16bit_bgr; +extern IGraphicsDriver *gfxDriver; +extern SpriteCache spriteset; +extern TreeMap *transtree; +extern int displayed_room, starting_room; +extern MoveList *mls; +extern char transFileName[MAX_PATH]; + +String GetRuntimeInfo() +{ + DisplayMode mode = gfxDriver->GetDisplayMode(); + Rect render_frame = gfxDriver->GetRenderDestination(); + PGfxFilter filter = gfxDriver->GetGraphicsFilter(); + String runtimeInfo = String::FromFormat( + "Adventure Game Studio run-time engine[ACI version %s" + "[Game resolution %d x %d (%d-bit)" + "[Running %d x %d at %d-bit%s%s[GFX: %s; %s[Draw frame %d x %d[" + "Sprite cache size: %d KB (limit %d KB; %d locked)", + EngineVersion.LongString.GetCStr(), game.GetGameRes().Width, game.GetGameRes().Height, game.GetColorDepth(), + mode.Width, mode.Height, mode.ColorDepth, (convert_16bit_bgr) ? " BGR" : "", + mode.Windowed ? " W" : "", + gfxDriver->GetDriverName(), filter->GetInfo().Name.GetCStr(), + render_frame.GetWidth(), render_frame.GetHeight(), + spriteset.GetCacheSize() / 1024, spriteset.GetMaxCacheSize() / 1024, spriteset.GetLockedSize() / 1024); + if (play.separate_music_lib) + runtimeInfo.Append("[AUDIO.VOX enabled"); + if (play.want_speech >= 1) + runtimeInfo.Append("[SPEECH.VOX enabled"); + if (transtree != nullptr) { + runtimeInfo.Append("[Using translation "); + runtimeInfo.Append(transFileName); + } + if (usetup.mod_player == 0) + runtimeInfo.Append("[(mod/xm player discarded)"); + + return runtimeInfo; +} + +void script_debug(int cmdd,int dataa) { + if (play.debug_mode==0) return; + int rr; + if (cmdd==0) { + for (rr=1;rrinv[rr]=1; + update_invorder(); + // Display("invorder decided there are %d items[display %d",play.inv_numorder,play.inv_numdisp); + } + else if (cmdd==1) { + String toDisplay = GetRuntimeInfo(); + Display(toDisplay.GetCStr()); + // Display("shftR: %d shftG: %d shftB: %d", _rgb_r_shift_16, _rgb_g_shift_16, _rgb_b_shift_16); + // Display("Remaining memory: %d kb",_go32_dpmi_remaining_virtual_memory()/1024); + //Display("Play char bcd: %d",->GetColorDepth(spriteset[views[playerchar->view].frames[playerchar->loop][playerchar->frame].pic])); + } + else if (cmdd==2) + { // show walkable areas from here + // TODO: support multiple viewports?! + const int viewport_index = 0; + const int camera_index = 0; + Bitmap *tempw=BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(),thisroom.WalkAreaMask->GetHeight()); + tempw->Blit(prepare_walkable_areas(-1),0,0,0,0,tempw->GetWidth(),tempw->GetHeight()); + const Rect &viewport = play.GetRoomViewport(viewport_index)->GetRect(); + const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); + Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); + Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); + view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); + + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); + render_graphics(ddb, viewport.Left, viewport.Top); + + delete tempw; + delete view_bmp; + gfxDriver->DestroyDDB(ddb); + ags_wait_until_keypress(); + invalidate_screen(); + } + else if (cmdd==3) + { + int goToRoom = -1; + if (game.roomCount == 0) + { + char inroomtex[80]; + sprintf(inroomtex, "!Enter new room: (in room %d)", displayed_room); + setup_for_dialog(); + goToRoom = enternumberwindow(inroomtex); + restore_after_dialog(); + } + else + { + setup_for_dialog(); + goToRoom = roomSelectorWindow(displayed_room, game.roomCount, game.roomNumbers, game.roomNames); + restore_after_dialog(); + } + if (goToRoom >= 0) + NewRoom(goToRoom); + } + else if (cmdd == 4) { + if (display_fps != kFPS_Forced) + display_fps = (FPSDisplayMode)dataa; + } + else if (cmdd == 5) { + if (dataa == 0) dataa = game.playercharacter; + if (game.chars[dataa].walking < 1) { + Display("Not currently moving."); + return; + } + Bitmap *tempw=BitmapHelper::CreateTransparentBitmap(thisroom.WalkAreaMask->GetWidth(),thisroom.WalkAreaMask->GetHeight()); + int mlsnum = game.chars[dataa].walking; + if (game.chars[dataa].walking >= TURNING_AROUND) + mlsnum %= TURNING_AROUND; + MoveList*cmls = &mls[mlsnum]; + for (int i = 0; i < cmls->numstage-1; i++) { + short srcx=short((cmls->pos[i] >> 16) & 0x00ffff); + short srcy=short(cmls->pos[i] & 0x00ffff); + short targetx=short((cmls->pos[i+1] >> 16) & 0x00ffff); + short targety=short(cmls->pos[i+1] & 0x00ffff); + tempw->DrawLine(Line(srcx, srcy, targetx, targety), MakeColor(i+1)); + } + + // TODO: support multiple viewports?! + const int viewport_index = 0; + const int camera_index = 0; + const Rect &viewport = play.GetRoomViewport(viewport_index)->GetRect(); + const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); + Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); + Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); + view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); + + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); + render_graphics(ddb, viewport.Left, viewport.Top); + + delete tempw; + delete view_bmp; + gfxDriver->DestroyDDB(ddb); + ags_wait_until_keypress(); + } + else if (cmdd == 99) + ccSetOption(SCOPT_DEBUGRUN, dataa); + else quit("!Debug: unknown command code"); +} diff --git a/engines/ags/engine/ac/global_debug.h b/engines/ags/engine/ac/global_debug.h new file mode 100644 index 000000000000..a4d50d0d4fd5 --- /dev/null +++ b/engines/ags/engine/ac/global_debug.h @@ -0,0 +1,27 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALDEBUG_H +#define __AGS_EE_AC__GLOBALDEBUG_H + +#include +#include "util/string.h" + +AGS::Common::String GetRuntimeInfo(); +void script_debug(int cmdd,int dataa); + +#endif // __AGS_EE_AC__GLOBALDEBUG_H diff --git a/engines/ags/engine/ac/global_dialog.cpp b/engines/ags/engine/ac/global_dialog.cpp new file mode 100644 index 000000000000..dbab9333a729 --- /dev/null +++ b/engines/ags/engine/ac/global_dialog.cpp @@ -0,0 +1,103 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_dialog.h" +#include "ac/common.h" +#include "ac/dialog.h" +#include "ac/dialogtopic.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "debug/out.h" +#include "script/script.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern GameState play; +extern DialogTopic *dialog; + +ScriptPosition last_in_dialog_request_script_pos; +void RunDialog(int tum) { + if ((tum<0) | (tum>=game.numdialog)) + quit("!RunDialog: invalid topic number specified"); + + can_run_delayed_command(); + + if (play.stop_dialog_at_end != DIALOG_NONE) { + if (play.stop_dialog_at_end == DIALOG_RUNNING) + play.stop_dialog_at_end = DIALOG_NEWTOPIC + tum; + else + quitprintf("!RunDialog: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", + last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); + return; + } + + get_script_position(last_in_dialog_request_script_pos); + + if (inside_script) + curscript->queue_action(ePSARunDialog, tum, "RunDialog"); + else + do_conversation(tum); +} + + +void StopDialog() { + if (play.stop_dialog_at_end == DIALOG_NONE) { + debug_script_warn("StopDialog called, but was not in a dialog"); + debug_script_log("StopDialog called but no dialog"); + return; + } + get_script_position(last_in_dialog_request_script_pos); + play.stop_dialog_at_end = DIALOG_STOP; +} + +void SetDialogOption(int dlg, int opt, int onoroff, bool dlg_script) +{ + if ((dlg<0) | (dlg>=game.numdialog)) + quit("!SetDialogOption: Invalid topic number specified"); + if ((opt<1) | (opt>dialog[dlg].numoptions)) + { + // Pre-3.1.1 games had "dialog scripts" that were written in different language and + // parsed differently; its "option-on/off" commands were more permissive. + if (dlg_script) + { + Debug::Printf(kDbgGroup_Game, kDbgMsg_Error, "SetDialogOption: Invalid option number specified (%d : %d)", dlg, opt); + return; + } + quit("!SetDialogOption: Invalid option number specified"); + } + opt--; + + dialog[dlg].optionflags[opt]&=~DFLG_ON; + if ((onoroff==1) & ((dialog[dlg].optionflags[opt] & DFLG_OFFPERM)==0)) + dialog[dlg].optionflags[opt]|=DFLG_ON; + else if (onoroff==2) + dialog[dlg].optionflags[opt]|=DFLG_OFFPERM; +} + +int GetDialogOption (int dlg, int opt) { + if ((dlg<0) | (dlg>=game.numdialog)) + quit("!GetDialogOption: Invalid topic number specified"); + if ((opt<1) | (opt>dialog[dlg].numoptions)) + quit("!GetDialogOption: Invalid option number specified"); + opt--; + + if (dialog[dlg].optionflags[opt] & DFLG_OFFPERM) + return 2; + if (dialog[dlg].optionflags[opt] & DFLG_ON) + return 1; + return 0; +} diff --git a/engines/ags/engine/ac/global_dialog.h b/engines/ags/engine/ac/global_dialog.h new file mode 100644 index 000000000000..feb16ae10f50 --- /dev/null +++ b/engines/ags/engine/ac/global_dialog.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALDIALOG_H +#define __AGS_EE_AC__GLOBALDIALOG_H + +void RunDialog(int tum); +int GetDialogOption (int dlg, int opt); +void SetDialogOption(int dlg, int opt, int onoroff, bool dlg_script = false); +void StopDialog(); + +#endif // __AGS_EE_AC__GLOBALDIALOG_H diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp new file mode 100644 index 000000000000..dfcd76bcc40e --- /dev/null +++ b/engines/ags/engine/ac/global_display.cpp @@ -0,0 +1,200 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "ac/common.h" +#include "ac/character.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_character.h" +#include "ac/global_display.h" +#include "ac/global_screen.h" +#include "ac/global_translation.h" +#include "ac/runtime_defines.h" +#include "ac/speech.h" +#include "ac/string.h" +#include "ac/topbarsettings.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "main/game_run.h" + +using namespace AGS::Common; + +extern TopBarSettings topBar; +extern GameState play; +extern RoomStruct thisroom; +extern int display_message_aschar; +extern GameSetupStruct game; + +void Display(const char*texx, ...) { + char displbuf[STD_BUFFER_SIZE]; + va_list ap; + va_start(ap,texx); + vsprintf(displbuf, get_translation(texx), ap); + va_end(ap); + DisplayAtY (-1, displbuf); +} + +void DisplaySimple(const char *text) +{ + DisplayAtY (-1, text); +} + +void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const char *text) +{ + // FIXME: refactor source_text_length and get rid of this ugly hack! + const int real_text_sourcelen = source_text_length; + snprintf(topBar.text, sizeof(topBar.text), "%s", get_translation(title)); + source_text_length = real_text_sourcelen; + + if (ypos > 0) + play.top_bar_ypos = ypos; + if (ttexcol > 0) + play.top_bar_textcolor = ttexcol; + if (backcol > 0) + play.top_bar_backcolor = backcol; + + topBar.wantIt = 1; + topBar.font = FONT_NORMAL; + topBar.height = getfontheight_outlined(topBar.font); + topBar.height += data_to_game_coord(play.top_bar_borderwidth) * 2 + get_fixed_pixel_size(1); + + // they want to customize the font + if (play.top_bar_font >= 0) + topBar.font = play.top_bar_font; + + // DisplaySpeech normally sets this up, but since we're not going via it... + if (play.cant_skip_speech & SKIP_AUTOTIMER) + play.messagetime = GetTextDisplayTime(text); + + DisplayAtY(play.top_bar_ypos, text); +} + +// Display a room/global message in the bar +void DisplayMessageBar(int ypos, int ttexcol, int backcol, const char *title, int msgnum) { + char msgbufr[3001]; + get_message_text(msgnum, msgbufr); + DisplayTopBar(ypos, ttexcol, backcol, title, msgbufr); +} + +void DisplayMessageAtY(int msnum, int ypos) { + char msgbufr[3001]; + if (msnum>=500) { + get_message_text (msnum, msgbufr); + if (display_message_aschar > 0) + DisplaySpeech(msgbufr, display_message_aschar); + else + DisplayAtY(ypos, msgbufr); + display_message_aschar=0; + return; + } + + if (display_message_aschar > 0) { + display_message_aschar=0; + quit("!DisplayMessage: data column specified a character for local\n" + "message; use the message editor to select the character for room\n" + "messages.\n"); + } + + int repeatloop=1; + while (repeatloop) { + get_message_text (msnum, msgbufr); + + if (thisroom.MessageInfos[msnum].DisplayAs > 0) { + DisplaySpeech(msgbufr, thisroom.MessageInfos[msnum].DisplayAs - 1); + } + else { + // time out automatically if they have set that + int oldGameSkipDisp = play.skip_display; + if (thisroom.MessageInfos[msnum].Flags & MSG_TIMELIMIT) + play.skip_display = 0; + + DisplayAtY(ypos, msgbufr); + + play.skip_display = oldGameSkipDisp; + } + if (thisroom.MessageInfos[msnum].Flags & MSG_DISPLAYNEXT) { + msnum++; + repeatloop=1; + } + else + repeatloop=0; + } + +} + +void DisplayMessage(int msnum) { + DisplayMessageAtY (msnum, -1); +} + +void DisplayAt(int xxp,int yyp,int widd, const char* text) { + data_to_game_coords(&xxp, &yyp); + widd = data_to_game_coord(widd); + + if (widd<1) widd=play.GetUIViewport().GetWidth()/2; + if (xxp<0) xxp=play.GetUIViewport().GetWidth()/2-widd/2; + _display_at(xxp, yyp, widd, text, DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); +} + +void DisplayAtY (int ypos, const char *texx) { + const Rect &ui_view = play.GetUIViewport(); + if ((ypos < -1) || (ypos >= ui_view.GetHeight())) + quitprintf("!DisplayAtY: invalid Y co-ordinate supplied (used: %d; valid: 0..%d)", ypos, ui_view.GetHeight()); + + // Display("") ... a bit of a stupid thing to do, so ignore it + if (texx[0] == 0) + return; + + if (ypos > 0) + ypos = data_to_game_coord(ypos); + + if (game.options[OPT_ALWAYSSPCH]) + DisplaySpeechAt(-1, (ypos > 0) ? game_to_data_coord(ypos) : ypos, -1, game.playercharacter, texx); + else { + // Normal "Display" in text box + + if (is_screen_dirty()) { + // erase any previous DisplaySpeech + play.disabled_user_interface ++; + UpdateGameOnce(); + play.disabled_user_interface --; + } + + _display_at(-1, ypos, ui_view.GetWidth() / 2 + ui_view.GetWidth() / 4, + get_translation(texx), DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); + } +} + +void SetSpeechStyle (int newstyle) { + if ((newstyle < 0) || (newstyle > 3)) + quit("!SetSpeechStyle: must use a SPEECH_* constant as parameter"); + game.options[OPT_SPEECHTYPE] = newstyle; +} + +void SetSkipSpeech (SkipSpeechStyle newval) { + if ((newval < kSkipSpeechFirst) || (newval > kSkipSpeechLast)) + quit("!SetSkipSpeech: invalid skip mode specified"); + + debug_script_log("SkipSpeech style set to %d", newval); + play.cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)newval); +} + +SkipSpeechStyle GetSkipSpeech() +{ + return internal_skip_speech_to_user(play.cant_skip_speech); +} diff --git a/engines/ags/engine/ac/global_display.h b/engines/ags/engine/ac/global_display.h new file mode 100644 index 000000000000..538d293924a1 --- /dev/null +++ b/engines/ags/engine/ac/global_display.h @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALDISPLAY_H +#define __AGS_EE_AC__GLOBALDISPLAY_H + +#include "ac/speech.h" + +void Display(const char*texx, ...); // applies translation +void DisplaySimple(const char* text); // does not apply translation +void DisplayAt(int xxp,int yyp,int widd, const char*text); +void DisplayAtY (int ypos, const char *texx); +void DisplayMessage(int msnum); +void DisplayMessageAtY(int msnum, int ypos); +void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const char *text); +// Display a room/global message in the bar +void DisplayMessageBar(int ypos, int ttexcol, int backcol, const char *title, int msgnum); + +void SetSpeechStyle (int newstyle); +void SetSkipSpeech (SkipSpeechStyle newval); +SkipSpeechStyle GetSkipSpeech(); + +#endif // __AGS_EE_AC__GLOBALDISPLAY_H diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp new file mode 100644 index 000000000000..4003c78f654e --- /dev/null +++ b/engines/ags/engine/ac/global_drawingsurface.cpp @@ -0,0 +1,301 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_drawingsurface.h" +#include "ac/global_translation.h" +#include "ac/string.h" +#include "debug/debug_log.h" +#include "font/fonts.h" +#include "game/roomstruct.h" +#include "gui/guidefines.h" +#include "ac/spritecache.h" +#include "gfx/gfx_def.h" +#include "gfx/gfx_util.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern Bitmap *raw_saved_screen; +extern RoomStruct thisroom; +extern GameState play; +extern SpriteCache spriteset; +extern GameSetupStruct game; + +// Raw screen writing routines - similar to old CapturedStuff +#define RAW_START() play.raw_drawing_surface = thisroom.BgFrames[play.bg_frame].Graphic; play.raw_modified[play.bg_frame] = 1 +#define RAW_END() +#define RAW_SURFACE() (play.raw_drawing_surface.get()) + +// RawSaveScreen: copy the current screen to a backup bitmap +void RawSaveScreen () { + if (raw_saved_screen != nullptr) + delete raw_saved_screen; + PBitmap source = thisroom.BgFrames[play.bg_frame].Graphic; + raw_saved_screen = BitmapHelper::CreateBitmapCopy(source.get()); +} +// RawRestoreScreen: copy backup bitmap back to screen; we +// deliberately don't free the Bitmap *cos they can multiple restore +// and it gets freed on room exit anyway +void RawRestoreScreen() { + if (raw_saved_screen == nullptr) { + debug_script_warn("RawRestoreScreen: unable to restore, since the screen hasn't been saved previously."); + return; + } + PBitmap deston = thisroom.BgFrames[play.bg_frame].Graphic; + deston->Blit(raw_saved_screen, 0, 0, 0, 0, deston->GetWidth(), deston->GetHeight()); + invalidate_screen(); + mark_current_background_dirty(); +} +// Restores the backup bitmap, but tints it to the specified level +void RawRestoreScreenTinted(int red, int green, int blue, int opacity) { + if (raw_saved_screen == nullptr) { + debug_script_warn("RawRestoreScreenTinted: unable to restore, since the screen hasn't been saved previously."); + return; + } + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 1) || (opacity > 100)) + quit("!RawRestoreScreenTinted: invalid parameter. R,G,B must be 0-255, opacity 1-100"); + + debug_script_log("RawRestoreTinted RGB(%d,%d,%d) %d%%", red, green, blue, opacity); + + PBitmap deston = thisroom.BgFrames[play.bg_frame].Graphic; + tint_image(deston.get(), raw_saved_screen, red, green, blue, opacity); + invalidate_screen(); + mark_current_background_dirty(); +} + +void RawDrawFrameTransparent (int frame, int translev) { + if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount) || + (translev < 0) || (translev > 99)) + quit("!RawDrawFrameTransparent: invalid parameter (transparency must be 0-99, frame a valid BG frame)"); + + PBitmap bg = thisroom.BgFrames[frame].Graphic; + if (bg->GetColorDepth() <= 8) + quit("!RawDrawFrameTransparent: 256-colour backgrounds not supported"); + + if (frame == play.bg_frame) + quit("!RawDrawFrameTransparent: cannot draw current background onto itself"); + + RAW_START(); + if (translev == 0) + { + // just draw it over the top, no transparency + RAW_SURFACE()->Blit(bg.get(), 0, 0, 0, 0, bg->GetWidth(), bg->GetHeight()); + } + else + { + // Draw it transparently + GfxUtil::DrawSpriteWithTransparency (RAW_SURFACE(), bg.get(), 0, 0, + GfxDef::Trans100ToAlpha255(translev)); + } + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); +} + +void RawClear (int clr) { + RAW_START(); + clr = RAW_SURFACE()->GetCompatibleColor(clr); + RAW_SURFACE()->Clear (clr); + invalidate_screen(); + mark_current_background_dirty(); +} +void RawSetColor (int clr) { + // set the colour at the appropriate depth for the background + play.raw_color = MakeColor(clr); +} +void RawSetColorRGB(int red, int grn, int blu) { + if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) || + (blu < 0) || (blu > 255)) + quit("!RawSetColorRGB: colour values must be 0-255"); + + play.raw_color = makecol_depth(thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth(), red, grn, blu); +} +void RawPrint (int xx, int yy, const char *text) { + RAW_START(); + // don't use wtextcolor because it will do a 16->32 conversion + color_t text_color = play.raw_color; + if ((RAW_SURFACE()->GetColorDepth() <= 8) && (play.raw_color > 255)) { + text_color = RAW_SURFACE()->GetCompatibleColor(1); + debug_script_warn ("RawPrint: Attempted to use hi-color on 256-col background"); + } + data_to_game_coords(&xx, &yy); + wouttext_outline(RAW_SURFACE(), xx, yy, play.normal_font, text_color, text); + // we must invalidate the entire screen because these are room + // co-ordinates, not screen co-ords which it works with + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); +} +void RawPrintMessageWrapped (int xx, int yy, int wid, int font, int msgm) { + char displbuf[3000]; + int linespacing = getfontspacing_outlined(font); + data_to_game_coords(&xx, &yy); + wid = data_to_game_coord(wid); + + get_message_text (msgm, displbuf); + // it's probably too late but check anyway + if (strlen(displbuf) > 2899) + quit("!RawPrintMessageWrapped: message too long"); + if (break_up_text_into_lines(displbuf, Lines, wid, font) == 0) + return; + + RAW_START(); + color_t text_color = play.raw_color; + for (size_t i = 0; i < Lines.Count(); i++) + wouttext_outline(RAW_SURFACE(), xx, yy + linespacing*i, font, text_color, Lines[i]); + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); +} + +void RawDrawImageCore(int xx, int yy, int slot, int alpha) { + if ((slot < 0) || (spriteset[slot] == nullptr)) + quit("!RawDrawImage: invalid sprite slot number specified"); + RAW_START(); + + if (spriteset[slot]->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) { + debug_script_warn("RawDrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", slot, spriteset[slot]->GetColorDepth(), RAW_SURFACE()->GetColorDepth()); + } + + draw_sprite_slot_support_alpha(RAW_SURFACE(), false, xx, yy, slot, kBlendMode_Alpha, alpha); + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); +} + +void RawDrawImage(int xx, int yy, int slot) { + data_to_game_coords(&xx, &yy); + RawDrawImageCore(xx, yy, slot); +} + +void RawDrawImageTrans(int xx, int yy, int slot, int alpha) { + data_to_game_coords(&xx, &yy); + RawDrawImageCore(xx, yy, slot, alpha); +} + +void RawDrawImageOffset(int xx, int yy, int slot) { + // This function takes coordinates in real game coordinates as opposed to script coordinates + defgame_to_finalgame_coords(xx, yy); + RawDrawImageCore(xx, yy, slot); +} + +void RawDrawImageTransparent(int xx, int yy, int slot, int legacy_transparency) { + if ((legacy_transparency < 0) || (legacy_transparency > 100)) + quit("!RawDrawImageTransparent: invalid transparency setting"); + + // WARNING: the previous versions of AGS actually had a bug: + // although manual stated that RawDrawImageTransparent takes % of transparency + // as an argument, that value was used improperly when setting up an Allegro's + // trans_blender, which caused it to act about as % of opacity instead, but + // with a twist. + // + // It was converted to 255-ranged "transparency" parameter: + // int transparency = (trans * 255) / 100; + // + // Note by CJ: + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + // + // In order to support this backward-compatible behavior, we convert the + // opacity into proper alpha this way: + // 0 => alpha 255 + // 100 => alpha 0 + // 1 - 99 => alpha 1 - 244 + // + RawDrawImageTrans(xx, yy, slot, GfxDef::LegacyTrans100ToAlpha255(legacy_transparency)); + + update_polled_stuff_if_runtime(); // this operation can be slow so stop music skipping +} +void RawDrawImageResized(int xx, int yy, int gotSlot, int width, int height) { + if ((gotSlot < 0) || (spriteset[gotSlot] == nullptr)) + quit("!RawDrawImageResized: invalid sprite slot number specified"); + // very small, don't draw it + if ((width < 1) || (height < 1)) + return; + + data_to_game_coords(&xx, &yy); + data_to_game_coords(&width, &height); + + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); + newPic->StretchBlt(spriteset[gotSlot], + RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), + RectWH(0, 0, width, height)); + + RAW_START(); + if (newPic->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) + quit("!RawDrawImageResized: image colour depth mismatch: the background image must have the same colour depth as the sprite being drawn"); + + GfxUtil::DrawSpriteWithTransparency(RAW_SURFACE(), newPic, xx, yy); + delete newPic; + invalidate_screen(); + mark_current_background_dirty(); + update_polled_stuff_if_runtime(); // this operation can be slow so stop music skipping + RAW_END(); +} +void RawDrawLine (int fromx, int fromy, int tox, int toy) { + data_to_game_coords(&fromx, &fromy); + data_to_game_coords(&tox, &toy); + + play.raw_modified[play.bg_frame] = 1; + int ii,jj; + // draw a line thick enough to look the same at all resolutions + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + color_t draw_color = play.raw_color; + for (ii = 0; ii < get_fixed_pixel_size(1); ii++) { + for (jj = 0; jj < get_fixed_pixel_size(1); jj++) + bg->DrawLine (Line(fromx+ii, fromy+jj, tox+ii, toy+jj), draw_color); + } + invalidate_screen(); + mark_current_background_dirty(); +} +void RawDrawCircle (int xx, int yy, int rad) { + data_to_game_coords(&xx, &yy); + rad = data_to_game_coord(rad); + + play.raw_modified[play.bg_frame] = 1; + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + bg->FillCircle(Circle (xx, yy, rad), play.raw_color); + invalidate_screen(); + mark_current_background_dirty(); +} +void RawDrawRectangle(int x1, int y1, int x2, int y2) { + play.raw_modified[play.bg_frame] = 1; + data_to_game_coords(&x1, &y1); + data_to_game_round_up(&x2, &y2); + + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + bg->FillRect(Rect(x1,y1,x2,y2), play.raw_color); + invalidate_screen(); + mark_current_background_dirty(); +} +void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) { + play.raw_modified[play.bg_frame] = 1; + data_to_game_coords(&x1, &y1); + data_to_game_coords(&x2, &y2); + data_to_game_coords(&x3, &y3); + + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + bg->DrawTriangle(Triangle (x1,y1,x2,y2,x3,y3), play.raw_color); + invalidate_screen(); + mark_current_background_dirty(); +} diff --git a/engines/ags/engine/ac/global_drawingsurface.h b/engines/ags/engine/ac/global_drawingsurface.h new file mode 100644 index 000000000000..d62ea61909e7 --- /dev/null +++ b/engines/ags/engine/ac/global_drawingsurface.h @@ -0,0 +1,44 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALDRAWINGSURFACE_H +#define __AGS_EE_AC__GLOBALDRAWINGSURFACE_H + +void RawSaveScreen (); +// RawRestoreScreen: copy backup bitmap back to screen; we +// deliberately don't free the Common::Bitmap *cos they can multiple restore +// and it gets freed on room exit anyway +void RawRestoreScreen(); +// Restores the backup bitmap, but tints it to the specified level +void RawRestoreScreenTinted(int red, int green, int blue, int opacity); +void RawDrawFrameTransparent (int frame, int translev); +void RawClear (int clr); +void RawSetColor (int clr); +void RawSetColorRGB(int red, int grn, int blu); +void RawPrint (int xx, int yy, const char *text); +void RawPrintMessageWrapped (int xx, int yy, int wid, int font, int msgm); +void RawDrawImageCore(int xx, int yy, int slot, int alpha = 0xFF); +void RawDrawImage(int xx, int yy, int slot); +void RawDrawImageOffset(int xx, int yy, int slot); +void RawDrawImageTransparent(int xx, int yy, int slot, int opacity); +void RawDrawImageResized(int xx, int yy, int gotSlot, int width, int height); +void RawDrawLine (int fromx, int fromy, int tox, int toy); +void RawDrawCircle (int xx, int yy, int rad); +void RawDrawRectangle(int x1, int y1, int x2, int y2); +void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3); + +#endif // __AGS_EE_AC__GLOBALDRAWINGSURFACE_H diff --git a/engines/ags/engine/ac/global_dynamicsprite.cpp b/engines/ags/engine/ac/global_dynamicsprite.cpp new file mode 100644 index 000000000000..b77a3f3c7ac4 --- /dev/null +++ b/engines/ags/engine/ac/global_dynamicsprite.cpp @@ -0,0 +1,50 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_dynamicsprite.h" +#include "util/wgt2allg.h" // Allegro RGB, PALETTE +#include "ac/draw.h" +#include "ac/dynamicsprite.h" +#include "ac/path_helper.h" +#include "ac/spritecache.h" +#include "ac/runtime_defines.h" //MAX_PATH +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern SpriteCache spriteset; +extern IGraphicsDriver *gfxDriver; + +int LoadImageFile(const char *filename) +{ + ResolvedPath rp; + if (!ResolveScriptPath(filename, true, rp)) + return 0; + + Bitmap *loadedFile = BitmapHelper::LoadFromFile(rp.FullPath); + if (!loadedFile && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) + loadedFile = BitmapHelper::LoadFromFile(rp.AltPath); + if (!loadedFile) + return 0; + + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return 0; + + add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(loadedFile)); + + return gotSlot; +} diff --git a/engines/ags/engine/ac/global_dynamicsprite.h b/engines/ags/engine/ac/global_dynamicsprite.h new file mode 100644 index 000000000000..a6f3ea8cca68 --- /dev/null +++ b/engines/ags/engine/ac/global_dynamicsprite.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALDYNAMICSPRITE_H +#define __AGS_EE_AC__GLOBALDYNAMICSPRITE_H + +int LoadImageFile(const char *filename); + +#endif // __AGS_EE_AC__GLOBALDYNAMICSPRITE_H diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp new file mode 100644 index 000000000000..d88a295cbbde --- /dev/null +++ b/engines/ags/engine/ac/global_file.cpp @@ -0,0 +1,177 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/global_file.h" +#include "ac/common.h" +#include "ac/file.h" +#include "ac/path_helper.h" +#include "ac/runtime_defines.h" +#include "ac/string.h" +#include "debug/debug_log.h" +#include "util/directory.h" +#include "util/path.h" +#include "util/stream.h" + +using namespace AGS::Common; + +int32_t FileOpenCMode(const char*fnmm, const char* cmode) +{ + Common::FileOpenMode open_mode; + Common::FileWorkMode work_mode; + // NOTE: here we ignore the text-mode flag. AGS 2.62 did not let + // game devs to open files in text mode. The file reading and + // writing logic in AGS makes extra control characters added for + // security reasons, and FileWriteRawLine adds CR/LF to the end + // of string on its own. + if (!Common::File::GetFileModesFromCMode(cmode, open_mode, work_mode)) + { + return 0; + } + return FileOpen(fnmm, open_mode, work_mode); +} + +// Find a free file slot to use +int32_t FindFreeFileSlot() +{ + int useindx = 0; + for (; useindx < num_open_script_files; useindx++) + { + if (valid_handles[useindx].stream == nullptr) + break; + } + + if (useindx >= num_open_script_files && + num_open_script_files >= MAX_OPEN_SCRIPT_FILES) + { + quit("!FileOpen: tried to open more than 10 files simultaneously - close some first"); + return -1; + } + return useindx; +} + +int32_t FileOpen(const char*fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode) +{ + int32_t useindx = FindFreeFileSlot(); + if (useindx < 0) + return 0; + + ResolvedPath rp; + if (open_mode == kFile_Open && work_mode == kFile_Read) + { + if (!ResolveScriptPath(fnmm, true, rp)) + return 0; + } + else + { + if (!ResolveWritePathAndCreateDirs(fnmm, rp)) + return 0; + } + + Stream *s = File::OpenFile(rp.FullPath, open_mode, work_mode); + if (!s && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) + s = File::OpenFile(rp.AltPath, open_mode, work_mode); + + valid_handles[useindx].stream = s; + if (valid_handles[useindx].stream == nullptr) + return 0; + valid_handles[useindx].handle = useindx + 1; // make handle indexes 1-based + + if (useindx >= num_open_script_files) + num_open_script_files++; + return valid_handles[useindx].handle; +} + +void FileClose(int32_t handle) { + ScriptFileHandle *sc_handle = check_valid_file_handle_int32(handle,"FileClose"); + delete sc_handle->stream; + sc_handle->stream = nullptr; + sc_handle->handle = 0; + } +void FileWrite(int32_t handle, const char *towrite) { + Stream *out = get_valid_file_stream_from_handle(handle,"FileWrite"); + out->WriteInt32(strlen(towrite)+1); + out->Write(towrite,strlen(towrite)+1); + } +void FileWriteRawLine(int32_t handle, const char*towrite) { + Stream *out = get_valid_file_stream_from_handle(handle,"FileWriteRawLine"); + out->Write(towrite,strlen(towrite)); + out->WriteInt8 (13); + out->WriteInt8 (10); + } +void FileRead(int32_t handle,char*toread) { + VALIDATE_STRING(toread); + Stream *in = get_valid_file_stream_from_handle(handle,"FileRead"); + if (in->EOS()) { + toread[0] = 0; + return; + } + int lle=in->ReadInt32(); + if ((lle>=200) | (lle<1)) quit("!FileRead: file was not written by FileWrite"); + in->Read(toread,lle); + } +int FileIsEOF (int32_t handle) { + Stream *stream = get_valid_file_stream_from_handle(handle,"FileIsEOF"); + if (stream->EOS()) + return 1; + + // TODO: stream errors + if (stream->HasErrors()) + return 1; + + if (stream->GetPosition () >= stream->GetLength()) + return 1; + return 0; +} +int FileIsError(int32_t handle) { + Stream *stream = get_valid_file_stream_from_handle(handle,"FileIsError"); + + // TODO: stream errors + if (stream->HasErrors()) + return 1; + + return 0; +} +void FileWriteInt(int32_t handle,int into) { + Stream *out = get_valid_file_stream_from_handle(handle,"FileWriteInt"); + out->WriteInt8('I'); + out->WriteInt32(into); + } +int FileReadInt(int32_t handle) { + Stream *in = get_valid_file_stream_from_handle(handle,"FileReadInt"); + if (in->EOS()) + return -1; + if (in->ReadInt8()!='I') + quit("!FileReadInt: File read back in wrong order"); + return in->ReadInt32(); + } +char FileReadRawChar(int32_t handle) { + Stream *in = get_valid_file_stream_from_handle(handle,"FileReadRawChar"); + if (in->EOS()) + return -1; + return in->ReadInt8(); + } +int FileReadRawInt(int32_t handle) { + Stream *in = get_valid_file_stream_from_handle(handle,"FileReadRawInt"); + if (in->EOS()) + return -1; + return in->ReadInt32(); +} +void FileWriteRawChar(int32_t handle, int chartoWrite) { + Stream *out = get_valid_file_stream_from_handle(handle,"FileWriteRawChar"); + if ((chartoWrite < 0) || (chartoWrite > 255)) + quit("!FileWriteRawChar: can only write values 0-255"); + + out->WriteInt8(chartoWrite); +} diff --git a/engines/ags/engine/ac/global_file.h b/engines/ags/engine/ac/global_file.h new file mode 100644 index 000000000000..1e827088eed8 --- /dev/null +++ b/engines/ags/engine/ac/global_file.h @@ -0,0 +1,41 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALFILE_H +#define __AGS_EE_AC__GLOBALFILE_H + +#include "util/file.h" + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +int32_t FileOpen(const char*fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); +// NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen +int32_t FileOpenCMode(const char*fnmm, const char* cmode); +void FileClose(int32_t handle); +void FileWrite(int32_t handle, const char *towrite); +void FileWriteRawLine(int32_t handle, const char*towrite); +void FileRead(int32_t handle,char*toread); +int FileIsEOF (int32_t handle); +int FileIsError(int32_t handle); +void FileWriteInt(int32_t handle,int into); +int FileReadInt(int32_t handle); +char FileReadRawChar(int32_t handle); +int FileReadRawInt(int32_t handle); +void FileWriteRawChar(int32_t handle, int chartoWrite); + +#endif // __AGS_EE_AC__GLOBALFILE_H diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp new file mode 100644 index 000000000000..40e263122c0c --- /dev/null +++ b/engines/ags/engine/ac/global_game.cpp @@ -0,0 +1,955 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include + +#include "core/platform.h" +#include "ac/audiocliptype.h" +#include "ac/global_game.h" +#include "ac/common.h" +#include "ac/view.h" +#include "ac/character.h" +#include "ac/draw.h" +#include "ac/dynamicsprite.h" +#include "ac/event.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_character.h" +#include "ac/global_gui.h" +#include "ac/global_hotspot.h" +#include "ac/global_inventoryitem.h" +#include "ac/global_translation.h" +#include "ac/gui.h" +#include "ac/hotspot.h" +#include "ac/keycode.h" +#include "ac/mouse.h" +#include "ac/object.h" +#include "ac/path_helper.h" +#include "ac/sys_events.h" +#include "ac/room.h" +#include "ac/roomstatus.h" +#include "ac/string.h" +#include "ac/system.h" +#include "debug/debugger.h" +#include "debug/debug_log.h" +#include "gui/guidialog.h" +#include "main/engine.h" +#include "main/game_start.h" +#include "main/game_run.h" +#include "main/graphics_mode.h" +#include "script/script.h" +#include "script/script_runtime.h" +#include "ac/spritecache.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" +#include "core/assetmanager.h" +#include "main/config.h" +#include "main/game_file.h" +#include "util/string_utils.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; + +#define ALLEGRO_KEYBOARD_HANDLER + +extern GameState play; +extern ExecutingScript*curscript; +extern int displayed_room; +extern int game_paused; +extern SpriteCache spriteset; +extern char gamefilenamebuf[200]; +extern GameSetup usetup; +extern unsigned int load_new_game; +extern int load_new_game_restore; +extern GameSetupStruct game; +extern ViewStruct*views; +extern RoomStatus*croom; +extern int gui_disabled_style; +extern RoomStruct thisroom; +extern int getloctype_index; +extern IGraphicsDriver *gfxDriver; +extern color palette[256]; + +#if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID +extern int psp_gfx_renderer; +#endif + +void GiveScore(int amnt) +{ + guis_need_update = 1; + play.score += amnt; + + if ((amnt > 0) && (play.score_sound >= 0)) + play_audio_clip_by_index(play.score_sound); + + run_on_event (GE_GOT_SCORE, RuntimeScriptValue().SetInt32(amnt)); +} + +void restart_game() { + can_run_delayed_command(); + if (inside_script) { + curscript->queue_action(ePSARestartGame, 0, "RestartGame"); + return; + } + try_restore_save(RESTART_POINT_SAVE_GAME_NUMBER); +} + +void RestoreGameSlot(int slnum) { + if (displayed_room < 0) + quit("!RestoreGameSlot: a game cannot be restored from within game_start"); + + can_run_delayed_command(); + if (inside_script) { + curscript->queue_action(ePSARestoreGame, slnum, "RestoreGameSlot"); + return; + } + try_restore_save(slnum); +} + +void DeleteSaveSlot (int slnum) { + String nametouse; + nametouse = get_save_game_path(slnum); + ::remove (nametouse); + if ((slnum >= 1) && (slnum <= MAXSAVEGAMES)) { + String thisname; + for (int i = MAXSAVEGAMES; i > slnum; i--) { + thisname = get_save_game_path(i); + if (Common::File::TestReadFile(thisname)) { + // Rename the highest save game to fill in the gap + rename (thisname, nametouse); + break; + } + } + + } +} + +void PauseGame() { + game_paused++; + debug_script_log("Game paused"); +} +void UnPauseGame() { + if (game_paused > 0) + game_paused--; + debug_script_log("Game UnPaused, pause level now %d", game_paused); +} + + +int IsGamePaused() { + if (game_paused>0) return 1; + return 0; +} + +int GetSaveSlotDescription(int slnum,char*desbuf) { + VALIDATE_STRING(desbuf); + String description; + if (read_savedgame_description(get_save_game_path(slnum), description)) + { + strcpy(desbuf, description); + return 1; + } + sprintf(desbuf,"INVALID SLOT %d", slnum); + return 0; +} + +int LoadSaveSlotScreenshot(int slnum, int width, int height) { + int gotSlot; + data_to_game_coords(&width, &height); + + if (!read_savedgame_screenshot(get_save_game_path(slnum), gotSlot)) + return 0; + + if (gotSlot == 0) + return 0; + + if ((game.SpriteInfos[gotSlot].Width == width) && (game.SpriteInfos[gotSlot].Height == height)) + return gotSlot; + + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); + newPic->StretchBlt(spriteset[gotSlot], + RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), + RectWH(0, 0, width, height)); + + update_polled_stuff_if_runtime(); + + // replace the bitmap in the sprite set + free_dynamic_sprite(gotSlot); + add_dynamic_sprite(gotSlot, newPic); + + return gotSlot; +} + +void SetGlobalInt(int index,int valu) { + if ((index<0) | (index>=MAXGSVALUES)) + quit("!SetGlobalInt: invalid index"); + + if (play.globalscriptvars[index] != valu) { + debug_script_log("GlobalInt %d set to %d", index, valu); + } + + play.globalscriptvars[index]=valu; +} + + +int GetGlobalInt(int index) { + if ((index<0) | (index>=MAXGSVALUES)) + quit("!GetGlobalInt: invalid index"); + return play.globalscriptvars[index]; +} + +void SetGlobalString (int index, const char *newval) { + if ((index<0) | (index >= MAXGLOBALSTRINGS)) + quit("!SetGlobalString: invalid index"); + debug_script_log("GlobalString %d set to '%s'", index, newval); + strncpy(play.globalstrings[index], newval, MAX_MAXSTRLEN); + // truncate it to 200 chars, to be sure + play.globalstrings[index][MAX_MAXSTRLEN - 1] = 0; +} + +void GetGlobalString (int index, char *strval) { + if ((index<0) | (index >= MAXGLOBALSTRINGS)) + quit("!GetGlobalString: invalid index"); + strcpy (strval, play.globalstrings[index]); +} + +// TODO: refactor this method, and use same shared procedure at both normal stop/startup and in RunAGSGame +int RunAGSGame (const char *newgame, unsigned int mode, int data) { + + can_run_delayed_command(); + + int AllowedModes = RAGMODE_PRESERVEGLOBALINT | RAGMODE_LOADNOW; + + if ((mode & (~AllowedModes)) != 0) + quit("!RunAGSGame: mode value unknown"); + + if (editor_debugging_enabled) + { + quit("!RunAGSGame cannot be used while running the game from within the AGS Editor. You must build the game EXE and run it from there to use this function."); + } + + if ((mode & RAGMODE_LOADNOW) == 0) { + // need to copy, since the script gets destroyed + get_install_dir_path(gamefilenamebuf, newgame); + ResPaths.GamePak.Path = gamefilenamebuf; + ResPaths.GamePak.Name = get_filename(gamefilenamebuf); + play.takeover_data = data; + load_new_game_restore = -1; + + if (inside_script) { + curscript->queue_action(ePSARunAGSGame, mode | RAGMODE_LOADNOW, "RunAGSGame"); + ccInstance::GetCurrentInstance()->Abort(); + } + else + load_new_game = mode | RAGMODE_LOADNOW; + + return 0; + } + + int ee; + + unload_old_room(); + displayed_room = -10; + + save_config_file(); // save current user config in case engine fails to run new game + unload_game_file(); + + // Adjust config (NOTE: normally, RunAGSGame would need a redesign to allow separate config etc per each game) + usetup.translation = ""; // reset to default, prevent from trying translation file of game A in game B + + if (Common::AssetManager::SetDataFile(ResPaths.GamePak.Path) != Common::kAssetNoError) + quitprintf("!RunAGSGame: unable to load new game file '%s'", ResPaths.GamePak.Path.GetCStr()); + + show_preload(); + + HError err = load_game_file(); + if (!err) + quitprintf("!RunAGSGame: error loading new game file:\n%s", err->FullMessage().GetCStr()); + + spriteset.Reset(); + err = spriteset.InitFile(SpriteCache::DefaultSpriteFileName, SpriteCache::DefaultSpriteIndexName); + if (!err) + quitprintf("!RunAGSGame: error loading new sprites:\n%s", err->FullMessage().GetCStr()); + + if ((mode & RAGMODE_PRESERVEGLOBALINT) == 0) { + // reset GlobalInts + for (ee = 0; ee < MAXGSVALUES; ee++) + play.globalscriptvars[ee] = 0; + } + + engine_init_game_settings(); + play.screen_is_faded_out = 1; + + if (load_new_game_restore >= 0) { + try_restore_save(load_new_game_restore); + load_new_game_restore = -1; + } + else + start_game(); + + return 0; +} + +int GetGameParameter (int parm, int data1, int data2, int data3) { + switch (parm) { + case GP_SPRITEWIDTH: + return Game_GetSpriteWidth(data1); + case GP_SPRITEHEIGHT: + return Game_GetSpriteHeight(data1); + case GP_NUMLOOPS: + return Game_GetLoopCountForView(data1); + case GP_NUMFRAMES: + return Game_GetFrameCountForLoop(data1, data2); + case GP_FRAMESPEED: + case GP_FRAMEIMAGE: + case GP_FRAMESOUND: + case GP_ISFRAMEFLIPPED: + { + if ((data1 < 1) || (data1 > game.numviews)) { + quitprintf("!GetGameParameter: invalid view specified (v: %d, l: %d, f: %d)", data1, data2, data3); + } + if ((data2 < 0) || (data2 >= views[data1 - 1].numLoops)) { + quitprintf("!GetGameParameter: invalid loop specified (v: %d, l: %d, f: %d)", data1, data2, data3); + } + if ((data3 < 0) || (data3 >= views[data1 - 1].loops[data2].numFrames)) { + quitprintf("!GetGameParameter: invalid frame specified (v: %d, l: %d, f: %d)", data1, data2, data3); + } + + ViewFrame *pvf = &views[data1 - 1].loops[data2].frames[data3]; + + if (parm == GP_FRAMESPEED) + return pvf->speed; + else if (parm == GP_FRAMEIMAGE) + return pvf->pic; + else if (parm == GP_FRAMESOUND) + return get_old_style_number_for_sound(pvf->sound); + else if (parm == GP_ISFRAMEFLIPPED) + return (pvf->flags & VFLG_FLIPSPRITE) ? 1 : 0; + else + quit("GetGameParameter internal error"); + } + case GP_ISRUNNEXTLOOP: + return Game_GetRunNextSettingForLoop(data1, data2); + case GP_NUMGUIS: + return game.numgui; + case GP_NUMOBJECTS: + return croom->numobj; + case GP_NUMCHARACTERS: + return game.numcharacters; + case GP_NUMINVITEMS: + return game.numinvitems; + default: + quit("!GetGameParameter: unknown parameter specified"); + } + return 0; +} + +void QuitGame(int dialog) { + if (dialog) { + int rcode; + setup_for_dialog(); + rcode=quitdialog(); + restore_after_dialog(); + if (rcode==0) return; + } + quit("|You have exited."); +} + + + + +void SetRestartPoint() { + save_game(RESTART_POINT_SAVE_GAME_NUMBER, "Restart Game Auto-Save"); +} + + + +void SetGameSpeed(int newspd) { + newspd += play.game_speed_modifier; + if (newspd>1000) newspd=1000; + if (newspd<10) newspd=10; + set_game_speed(newspd); + debug_script_log("Game speed set to %d", newspd); +} + +int GetGameSpeed() { + return ::lround(get_current_fps()) - play.game_speed_modifier; +} + +int SetGameOption (int opt, int setting) { + if (((opt < 1) || (opt > OPT_HIGHESTOPTION)) && (opt != OPT_LIPSYNCTEXT)) + quit("!SetGameOption: invalid option specified"); + + if (opt == OPT_ANTIGLIDE) + { + for (int i = 0; i < game.numcharacters; i++) + { + if (setting) + game.chars[i].flags |= CHF_ANTIGLIDE; + else + game.chars[i].flags &= ~CHF_ANTIGLIDE; + } + } + + if ((opt == OPT_CROSSFADEMUSIC) && (game.audioClipTypes.size() > AUDIOTYPE_LEGACY_MUSIC)) + { + // legacy compatibility -- changing crossfade speed here also + // updates the new audio clip type style + game.audioClipTypes[AUDIOTYPE_LEGACY_MUSIC].crossfadeSpeed = setting; + } + + int oldval = game.options[opt]; + game.options[opt] = setting; + + if (opt == OPT_DUPLICATEINV) + update_invorder(); + else if (opt == OPT_DISABLEOFF) + gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); + else if (opt == OPT_PORTRAITSIDE) { + if (setting == 0) // set back to Left + play.swap_portrait_side = 0; + } + + return oldval; +} + +int GetGameOption (int opt) { + if (((opt < 1) || (opt > OPT_HIGHESTOPTION)) && (opt != OPT_LIPSYNCTEXT)) + quit("!GetGameOption: invalid option specified"); + + return game.options[opt]; +} + +void SkipUntilCharacterStops(int cc) { + if (!is_valid_character(cc)) + quit("!SkipUntilCharacterStops: invalid character specified"); + if (game.chars[cc].room!=displayed_room) + quit("!SkipUntilCharacterStops: specified character not in current room"); + + // if they are not currently moving, do nothing + if (!game.chars[cc].walking) + return; + + if (is_in_cutscene()) + quit("!SkipUntilCharacterStops: cannot be used within a cutscene"); + + initialize_skippable_cutscene(); + play.fast_forward = 2; + play.skip_until_char_stops = cc; +} + +void EndSkippingUntilCharStops() { + // not currently skipping, so ignore + if (play.skip_until_char_stops < 0) + return; + + stop_fast_forwarding(); + play.skip_until_char_stops = -1; +} + +void StartCutscene (int skipwith) { + static ScriptPosition last_cutscene_script_pos; + + if (is_in_cutscene()) { + quitprintf("!StartCutscene: already in a cutscene; previous started in \"%s\", line %d", + last_cutscene_script_pos.Section.GetCStr(), last_cutscene_script_pos.Line); + } + + if ((skipwith < 1) || (skipwith > 6)) + quit("!StartCutscene: invalid argument, must be 1 to 5."); + + get_script_position(last_cutscene_script_pos); + + // make sure they can't be skipping and cutsceneing at the same time + EndSkippingUntilCharStops(); + + play.in_cutscene = skipwith; + initialize_skippable_cutscene(); +} + +void SkipCutscene() +{ + if (is_in_cutscene()) + start_skipping_cutscene(); +} + +int EndCutscene () { + if (!is_in_cutscene()) + quit("!EndCutscene: not in a cutscene"); + + int retval = play.fast_forward; + play.in_cutscene = 0; + // Stop it fast-forwarding + stop_fast_forwarding(); + + // make sure that the screen redraws + invalidate_screen(); + + // Return whether the player skipped it + return retval; +} + +void sc_inputbox(const char*msg,char*bufr) { + VALIDATE_STRING(bufr); + setup_for_dialog(); + enterstringwindow(get_translation(msg),bufr); + restore_after_dialog(); +} + +// GetLocationType exported function - just call through +// to the main function with default 0 +int GetLocationType(int xxx,int yyy) { + return __GetLocationType(xxx, yyy, 0); +} + +void SaveCursorForLocationChange() { + // update the current location name + char tempo[100]; + GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + + if (play.get_loc_name_save_cursor != play.get_loc_name_last_time) { + play.get_loc_name_save_cursor = play.get_loc_name_last_time; + play.restore_cursor_mode_to = GetCursorMode(); + play.restore_cursor_image_to = GetMouseCursor(); + debug_script_log("Saving mouse: mode %d cursor %d", play.restore_cursor_mode_to, play.restore_cursor_image_to); + } +} + +void GetLocationName(int xxx,int yyy,char*tempo) { + if (displayed_room < 0) + quit("!GetLocationName: no room has been loaded"); + + VALIDATE_STRING(tempo); + + tempo[0] = 0; + + if (GetGUIAt(xxx, yyy) >= 0) { + int mover = GetInvAt (xxx, yyy); + if (mover > 0) { + if (play.get_loc_name_last_time != 1000 + mover) + guis_need_update = 1; + play.get_loc_name_last_time = 1000 + mover; + strcpy(tempo,get_translation(game.invinfo[mover].name)); + } + else if ((play.get_loc_name_last_time > 1000) && (play.get_loc_name_last_time < 1000 + MAX_INV)) { + // no longer selecting an item + guis_need_update = 1; + play.get_loc_name_last_time = -1; + } + return; + } + + int loctype = GetLocationType(xxx, yyy); // GetLocationType takes screen coords + VpPoint vpt = play.ScreenToRoomDivDown(xxx, yyy); + if (vpt.second < 0) + return; + xxx = vpt.first.X; + yyy = vpt.first.Y; + if ((xxx>=thisroom.Width) | (xxx<0) | (yyy<0) | (yyy>=thisroom.Height)) + return; + + int onhs,aa; + if (loctype == 0) { + if (play.get_loc_name_last_time != 0) { + play.get_loc_name_last_time = 0; + guis_need_update = 1; + } + return; + } + + // on character + if (loctype == LOCTYPE_CHAR) { + onhs = getloctype_index; + strcpy(tempo,get_translation(game.chars[onhs].name)); + if (play.get_loc_name_last_time != 2000+onhs) + guis_need_update = 1; + play.get_loc_name_last_time = 2000+onhs; + return; + } + // on object + if (loctype == LOCTYPE_OBJ) { + aa = getloctype_index; + strcpy(tempo,get_translation(thisroom.Objects[aa].Name)); + // Compatibility: < 3.1.1 games returned space for nameless object + // (presumably was a bug, but fixing it affected certain games behavior) + if (loaded_game_file_version < kGameVersion_311 && tempo[0] == 0) { + tempo[0] = ' '; + tempo[1] = 0; + } + if (play.get_loc_name_last_time != 3000+aa) + guis_need_update = 1; + play.get_loc_name_last_time = 3000+aa; + return; + } + onhs = getloctype_index; + if (onhs>0) strcpy(tempo,get_translation(thisroom.Hotspots[onhs].Name)); + if (play.get_loc_name_last_time != onhs) + guis_need_update = 1; + play.get_loc_name_last_time = onhs; +} + +int IsKeyPressed (int keycode) { +#ifdef ALLEGRO_KEYBOARD_HANDLER + if (keyboard_needs_poll()) + poll_keyboard(); + + switch(keycode) { + case eAGSKeyCodeBackspace: return ags_iskeypressed(__allegro_KEY_BACKSPACE); break; + case eAGSKeyCodeTab: return ags_iskeypressed(__allegro_KEY_TAB); break; + case eAGSKeyCodeReturn: return ags_iskeypressed(__allegro_KEY_ENTER) || ags_iskeypressed(__allegro_KEY_ENTER_PAD); break; + case eAGSKeyCodeEscape: return ags_iskeypressed(__allegro_KEY_ESC); break; + case eAGSKeyCodeSpace: return ags_iskeypressed(__allegro_KEY_SPACE); break; + case eAGSKeyCodeSingleQuote: return ags_iskeypressed(__allegro_KEY_QUOTE); break; + case eAGSKeyCodeComma: return ags_iskeypressed(__allegro_KEY_COMMA); break; + case eAGSKeyCodePeriod: return ags_iskeypressed(__allegro_KEY_STOP); break; + case eAGSKeyCodeForwardSlash: return ags_iskeypressed(__allegro_KEY_SLASH) || ags_iskeypressed(__allegro_KEY_SLASH_PAD); break; + case eAGSKeyCodeBackSlash: return ags_iskeypressed(__allegro_KEY_BACKSLASH) || ags_iskeypressed(__allegro_KEY_BACKSLASH2); break; + case eAGSKeyCodeSemiColon: return ags_iskeypressed(__allegro_KEY_SEMICOLON); break; + case eAGSKeyCodeEquals: return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_EQUALS_PAD); break; + case eAGSKeyCodeOpenBracket: return ags_iskeypressed(__allegro_KEY_OPENBRACE); break; + case eAGSKeyCodeCloseBracket: return ags_iskeypressed(__allegro_KEY_CLOSEBRACE); break; + // NOTE: we're treating EQUALS like PLUS, even though it is only available shifted. + case eAGSKeyCodePlus: return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_PLUS_PAD); break; + case eAGSKeyCodeHyphen: return ags_iskeypressed(__allegro_KEY_MINUS) || ags_iskeypressed(__allegro_KEY_MINUS_PAD); break; + + // non-shifted versions of keys + case eAGSKeyCodeColon: return ags_iskeypressed(__allegro_KEY_COLON) || ags_iskeypressed(__allegro_KEY_COLON2); break; + case eAGSKeyCodeAsterisk: return ags_iskeypressed(__allegro_KEY_ASTERISK); break; + case eAGSKeyCodeAt: return ags_iskeypressed(__allegro_KEY_AT); break; + + case eAGSKeyCode0: return ags_iskeypressed(__allegro_KEY_0); break; + case eAGSKeyCode1: return ags_iskeypressed(__allegro_KEY_1); break; + case eAGSKeyCode2: return ags_iskeypressed(__allegro_KEY_2); break; + case eAGSKeyCode3: return ags_iskeypressed(__allegro_KEY_3); break; + case eAGSKeyCode4: return ags_iskeypressed(__allegro_KEY_4); break; + case eAGSKeyCode5: return ags_iskeypressed(__allegro_KEY_5); break; + case eAGSKeyCode6: return ags_iskeypressed(__allegro_KEY_6); break; + case eAGSKeyCode7: return ags_iskeypressed(__allegro_KEY_7); break; + case eAGSKeyCode8: return ags_iskeypressed(__allegro_KEY_8); break; + case eAGSKeyCode9: return ags_iskeypressed(__allegro_KEY_9); break; + + case eAGSKeyCodeA: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('A')); break; + case eAGSKeyCodeB: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('B')); break; + case eAGSKeyCodeC: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('C')); break; + case eAGSKeyCodeD: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('D')); break; + case eAGSKeyCodeE: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('E')); break; + case eAGSKeyCodeF: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('F')); break; + case eAGSKeyCodeG: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('G')); break; + case eAGSKeyCodeH: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('H')); break; + case eAGSKeyCodeI: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('I')); break; + case eAGSKeyCodeJ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('J')); break; + case eAGSKeyCodeK: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('K')); break; + case eAGSKeyCodeL: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('L')); break; + case eAGSKeyCodeM: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('M')); break; + case eAGSKeyCodeN: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('N')); break; + case eAGSKeyCodeO: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('O')); break; + case eAGSKeyCodeP: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('P')); break; + case eAGSKeyCodeQ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Q')); break; + case eAGSKeyCodeR: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('R')); break; + case eAGSKeyCodeS: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('S')); break; + case eAGSKeyCodeT: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('T')); break; + case eAGSKeyCodeU: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('U')); break; + case eAGSKeyCodeV: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('V')); break; + case eAGSKeyCodeW: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('W')); break; + case eAGSKeyCodeX: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('X')); break; + case eAGSKeyCodeY: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Y')); break; + case eAGSKeyCodeZ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Z')); break; + + case eAGSKeyCodeF1: return ags_iskeypressed(__allegro_KEY_F1); break; + case eAGSKeyCodeF2: return ags_iskeypressed(__allegro_KEY_F2); break; + case eAGSKeyCodeF3: return ags_iskeypressed(__allegro_KEY_F3); break; + case eAGSKeyCodeF4: return ags_iskeypressed(__allegro_KEY_F4); break; + case eAGSKeyCodeF5: return ags_iskeypressed(__allegro_KEY_F5); break; + case eAGSKeyCodeF6: return ags_iskeypressed(__allegro_KEY_F6); break; + case eAGSKeyCodeF7: return ags_iskeypressed(__allegro_KEY_F7); break; + case eAGSKeyCodeF8: return ags_iskeypressed(__allegro_KEY_F8); break; + case eAGSKeyCodeF9: return ags_iskeypressed(__allegro_KEY_F9); break; + case eAGSKeyCodeF10: return ags_iskeypressed(__allegro_KEY_F10); break; + case eAGSKeyCodeF11: return ags_iskeypressed(__allegro_KEY_F11); break; + case eAGSKeyCodeF12: return ags_iskeypressed(__allegro_KEY_F12); break; + + case eAGSKeyCodeHome: return ags_iskeypressed(__allegro_KEY_HOME) || ags_iskeypressed(__allegro_KEY_7_PAD); break; + case eAGSKeyCodeUpArrow: return ags_iskeypressed(__allegro_KEY_UP) || ags_iskeypressed(__allegro_KEY_8_PAD); break; + case eAGSKeyCodePageUp: return ags_iskeypressed(__allegro_KEY_PGUP) || ags_iskeypressed(__allegro_KEY_9_PAD); break; + case eAGSKeyCodeLeftArrow: return ags_iskeypressed(__allegro_KEY_LEFT) || ags_iskeypressed(__allegro_KEY_4_PAD); break; + case eAGSKeyCodeNumPad5: return ags_iskeypressed(__allegro_KEY_5_PAD); break; + case eAGSKeyCodeRightArrow: return ags_iskeypressed(__allegro_KEY_RIGHT) || ags_iskeypressed(__allegro_KEY_6_PAD); break; + case eAGSKeyCodeEnd: return ags_iskeypressed(__allegro_KEY_END) || ags_iskeypressed(__allegro_KEY_1_PAD); break; + case eAGSKeyCodeDownArrow: return ags_iskeypressed(__allegro_KEY_DOWN) || ags_iskeypressed(__allegro_KEY_2_PAD); break; + case eAGSKeyCodePageDown: return ags_iskeypressed(__allegro_KEY_PGDN) || ags_iskeypressed(__allegro_KEY_3_PAD); break; + case eAGSKeyCodeInsert: return ags_iskeypressed(__allegro_KEY_INSERT) || ags_iskeypressed(__allegro_KEY_0_PAD); break; + case eAGSKeyCodeDelete: return ags_iskeypressed(__allegro_KEY_DEL) || ags_iskeypressed(__allegro_KEY_DEL_PAD); break; + + // These keys are not defined in the eAGSKey enum but are in the manual + // https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html + + case 403: return ags_iskeypressed(__allegro_KEY_LSHIFT); break; + case 404: return ags_iskeypressed(__allegro_KEY_RSHIFT); break; + case 405: return ags_iskeypressed(__allegro_KEY_LCONTROL); break; + case 406: return ags_iskeypressed(__allegro_KEY_RCONTROL); break; + case 407: return ags_iskeypressed(__allegro_KEY_ALT); break; + + // (noted here for interest) + // The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes. + // These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints. + + case 392: return ags_iskeypressed(__allegro_KEY_PRTSCR); break; + case 393: return ags_iskeypressed(__allegro_KEY_PAUSE); break; + case 394: return ags_iskeypressed(__allegro_KEY_ABNT_C1); break; // The ABNT_C1 (Brazilian) key + case 395: return ags_iskeypressed(__allegro_KEY_YEN); break; + case 396: return ags_iskeypressed(__allegro_KEY_KANA); break; + case 397: return ags_iskeypressed(__allegro_KEY_CONVERT); break; + case 398: return ags_iskeypressed(__allegro_KEY_NOCONVERT); break; + case 400: return ags_iskeypressed(__allegro_KEY_CIRCUMFLEX); break; + case 402: return ags_iskeypressed(__allegro_KEY_KANJI); break; + case 420: return ags_iskeypressed(__allegro_KEY_ALTGR); break; + case 421: return ags_iskeypressed(__allegro_KEY_LWIN); break; + case 422: return ags_iskeypressed(__allegro_KEY_RWIN); break; + case 423: return ags_iskeypressed(__allegro_KEY_MENU); break; + case 424: return ags_iskeypressed(__allegro_KEY_SCRLOCK); break; + case 425: return ags_iskeypressed(__allegro_KEY_NUMLOCK); break; + case 426: return ags_iskeypressed(__allegro_KEY_CAPSLOCK); break; + + // Allegro4 keys that were never supported: + // __allegro_KEY_COMMAND + // __allegro_KEY_TILDE + // __allegro_KEY_BACKQUOTE + + default: + // Remaining Allegro4 keycodes are offset by AGS_EXT_KEY_SHIFT + if (keycode >= AGS_EXT_KEY_SHIFT) { + if (ags_iskeypressed(keycode - AGS_EXT_KEY_SHIFT)) { return 1; } + } + debug_script_log("IsKeyPressed: unsupported keycode %d", keycode); + return 0; + } +#else + // old allegro version + quit("allegro keyboard handler not in use??"); +#endif +} + +int SaveScreenShot(const char*namm) { + String fileName; + String svg_dir = get_save_game_directory(); + + if (strchr(namm,'.') == nullptr) + fileName.Format("%s%s.bmp", svg_dir.GetCStr(), namm); + else + fileName.Format("%s%s", svg_dir.GetCStr(), namm); + + Bitmap *buffer = CopyScreenIntoBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight()); + if (!buffer->SaveToFile(fileName, palette) != 0) + { + delete buffer; + return 0; + } + delete buffer; + return 1; // successful +} + +void SetMultitasking (int mode) { + if ((mode < 0) | (mode > 1)) + quit("!SetMultitasking: invalid mode parameter"); + + if (usetup.override_multitasking >= 0) + { + mode = usetup.override_multitasking; + } + + // Don't allow background running if full screen + if ((mode == 1) && (!scsystem.windowed)) + mode = 0; + + if (mode == 0) { + if (set_display_switch_mode(SWITCH_PAUSE) == -1) + set_display_switch_mode(SWITCH_AMNESIA); + // install callbacks to stop the sound when switching away + set_display_switch_callback(SWITCH_IN, display_switch_in_resume); + set_display_switch_callback(SWITCH_OUT, display_switch_out_suspend); + } + else { + if (set_display_switch_mode (SWITCH_BACKGROUND) == -1) + set_display_switch_mode(SWITCH_BACKAMNESIA); + set_display_switch_callback(SWITCH_IN, display_switch_in); + set_display_switch_callback(SWITCH_OUT, display_switch_out); + } +} + +extern int getloctype_throughgui, getloctype_index; + +void RoomProcessClick(int xx,int yy,int mood) { + getloctype_throughgui = 1; + int loctype = GetLocationType (xx, yy); + VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); + if (vpt.second < 0) + return; + xx = vpt.first.X; + yy = vpt.first.Y; + + if ((mood==MODE_WALK) && (game.options[OPT_NOWALKMODE]==0)) { + int hsnum=get_hotspot_at(xx,yy); + if (hsnum<1) ; + else if (thisroom.Hotspots[hsnum].WalkTo.X<1) ; + else if (play.auto_use_walkto_points == 0) ; + else { + xx=thisroom.Hotspots[hsnum].WalkTo.X; + yy=thisroom.Hotspots[hsnum].WalkTo.Y; + debug_script_log("Move to walk-to point hotspot %d", hsnum); + } + walk_character(game.playercharacter,xx,yy,0, true); + return; + } + play.usedmode=mood; + + if (loctype == 0) { + // click on nothing -> hotspot 0 + getloctype_index = 0; + loctype = LOCTYPE_HOTSPOT; + } + + if (loctype == LOCTYPE_CHAR) { + if (check_click_on_character(xx,yy,mood)) return; + } + else if (loctype == LOCTYPE_OBJ) { + if (check_click_on_object(xx,yy,mood)) return; + } + else if (loctype == LOCTYPE_HOTSPOT) + RunHotspotInteraction (getloctype_index, mood); +} + +int IsInteractionAvailable (int xx,int yy,int mood) { + getloctype_throughgui = 1; + int loctype = GetLocationType (xx, yy); + VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); + if (vpt.second < 0) + return 0; + xx = vpt.first.X; + yy = vpt.first.Y; + + // You can always walk places + if ((mood==MODE_WALK) && (game.options[OPT_NOWALKMODE]==0)) + return 1; + + play.check_interaction_only = 1; + + if (loctype == 0) { + // click on nothing -> hotspot 0 + getloctype_index = 0; + loctype = LOCTYPE_HOTSPOT; + } + + if (loctype == LOCTYPE_CHAR) { + check_click_on_character(xx,yy,mood); + } + else if (loctype == LOCTYPE_OBJ) { + check_click_on_object(xx,yy,mood); + } + else if (loctype == LOCTYPE_HOTSPOT) + RunHotspotInteraction (getloctype_index, mood); + + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + + if (ciwas == 2) + return 1; + + return 0; +} + +void GetMessageText (int msg, char *buffer) { + VALIDATE_STRING(buffer); + get_message_text (msg, buffer, 0); +} + +void SetSpeechFont (int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetSpeechFont: invalid font number."); + play.speech_font = fontnum; +} + +void SetNormalFont (int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetNormalFont: invalid font number."); + play.normal_font = fontnum; +} + +void _sc_AbortGame(const char* text) { + char displbuf[STD_BUFFER_SIZE] = "!?"; + snprintf(&displbuf[2], STD_BUFFER_SIZE - 3, "%s", text); + quit(displbuf); +} + +int GetGraphicalVariable (const char *varName) { + InteractionVariable *theVar = FindGraphicalVariable(varName); + if (theVar == nullptr) { + quitprintf("!GetGraphicalVariable: interaction variable '%s' not found", varName); + return 0; + } + return theVar->Value; +} + +void SetGraphicalVariable (const char *varName, int p_value) { + InteractionVariable *theVar = FindGraphicalVariable(varName); + if (theVar == nullptr) { + quitprintf("!SetGraphicalVariable: interaction variable '%s' not found", varName); + } + else + theVar->Value = p_value; +} + +int WaitImpl(int skip_type, int nloops) +{ + play.wait_counter = nloops; + play.wait_skipped_by = SKIP_AUTOTIMER; // we set timer flag by default to simplify that case + play.wait_skipped_by_data = 0; + play.key_skip_wait = skip_type; + + GameLoopUntilValueIsZero(&play.wait_counter); + + if (game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v351) + { + // < 3.5.1 return 1 is skipped by user input, otherwise 0 + return (play.wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK) != 0) ? 1 : 0; + } + // >= 3.5.1 return positive keycode, negative mouse button code, or 0 as time-out + switch (play.wait_skipped_by) + { + case SKIP_KEYPRESS: return play.wait_skipped_by_data; + case SKIP_MOUSECLICK: return -(play.wait_skipped_by_data + 1); // convert to 1-based code and negate + default: return 0; + } +} + +void scrWait(int nloops) { + WaitImpl(SKIP_AUTOTIMER, nloops); +} + +int WaitKey(int nloops) { + return WaitImpl(SKIP_KEYPRESS | SKIP_AUTOTIMER, nloops); +} + +int WaitMouse(int nloops) { + return WaitImpl(SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops); +} + +int WaitMouseKey(int nloops) { + return WaitImpl(SKIP_KEYPRESS | SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops); +} + +void SkipWait() { + play.wait_counter = 0; +} diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h new file mode 100644 index 000000000000..25e471a73342 --- /dev/null +++ b/engines/ags/engine/ac/global_game.h @@ -0,0 +1,88 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALGAME_H +#define __AGS_EE_AC__GLOBALGAME_H + +#include "util/string.h" +using namespace AGS; // FIXME later + +void GiveScore(int amnt); +void restart_game(); +void RestoreGameSlot(int slnum); +void DeleteSaveSlot (int slnum); +int GetSaveSlotDescription(int slnum,char*desbuf); +int LoadSaveSlotScreenshot(int slnum, int width, int height); +void PauseGame(); +void UnPauseGame(); +int IsGamePaused(); +void SetGlobalInt(int index,int valu); +int GetGlobalInt(int index); +void SetGlobalString (int index, const char *newval); +void GetGlobalString (int index, char *strval); +int RunAGSGame (const char *newgame, unsigned int mode, int data); +int GetGameParameter (int parm, int data1, int data2, int data3); +void QuitGame(int dialog); +void SetRestartPoint(); +void SetGameSpeed(int newspd); +int GetGameSpeed(); +int SetGameOption (int opt, int setting); +int GetGameOption (int opt); + +void SkipUntilCharacterStops(int cc); +void EndSkippingUntilCharStops(); +// skipwith decides how it can be skipped: +// 1 = ESC only +// 2 = any key +// 3 = mouse button +// 4 = mouse button or any key +// 5 = right click or ESC only +void StartCutscene (int skipwith); +int EndCutscene (); +// Tell the game to skip current cutscene +void SkipCutscene(); + +void sc_inputbox(const char*msg,char*bufr); + +int GetLocationType(int xxx,int yyy); +void SaveCursorForLocationChange(); +void GetLocationName(int xxx,int yyy,char*tempo); + +int IsKeyPressed (int keycode); + +int SaveScreenShot(const char*namm); +void SetMultitasking (int mode); + +void RoomProcessClick(int xx,int yy,int mood); +int IsInteractionAvailable (int xx,int yy,int mood); + +void GetMessageText (int msg, char *buffer); + +void SetSpeechFont (int fontnum); +void SetNormalFont (int fontnum); + +void _sc_AbortGame(const char* text); + +int GetGraphicalVariable (const char *varName); +void SetGraphicalVariable (const char *varName, int p_value); +void scrWait(int nloops); +int WaitKey(int nloops); +int WaitMouse(int nloops); +int WaitMouseKey(int nloops); +void SkipWait(); + +#endif // __AGS_EE_AC__GLOBALGAME_H diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp new file mode 100644 index 000000000000..3c8e6250ac31 --- /dev/null +++ b/engines/ags/engine/ac/global_gui.cpp @@ -0,0 +1,256 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/gui.h" +#include "ac/guicontrol.h" +#include "ac/mouse.h" +#include "ac/string.h" +#include "debug/debug_log.h" +#include "font/fonts.h" +#include "gui/guimain.h" +#include "script/runtimescriptvalue.h" +#include "util/string_compat.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern ScriptGUI *scrGui; + +int IsGUIOn (int guinum) { + if ((guinum < 0) || (guinum >= game.numgui)) + quit("!IsGUIOn: invalid GUI number specified"); + return (guis[guinum].IsDisplayed()) ? 1 : 0; +} + +// This is an internal script function, and is undocumented. +// It is used by the editor's automatic macro generation. +int FindGUIID (const char* GUIName) { + for (int ii = 0; ii < game.numgui; ii++) { + if (guis[ii].Name.IsEmpty()) + continue; + if (strcmp(guis[ii].Name, GUIName) == 0) + return ii; + if ((guis[ii].Name[0u] == 'g') && (ags_stricmp(guis[ii].Name.GetCStr() + 1, GUIName) == 0)) + return ii; + } + quit("FindGUIID: No matching GUI found: GUI may have been deleted"); + return -1; +} + +void InterfaceOn(int ifn) { + if ((ifn<0) | (ifn>=game.numgui)) + quit("!GUIOn: invalid GUI specified"); + + EndSkippingUntilCharStops(); + + if (guis[ifn].IsVisible()) { + debug_script_log("GUIOn(%d) ignored (already on)", ifn); + return; + } + guis_need_update = 1; + guis[ifn].SetVisible(true); + debug_script_log("GUI %d turned on", ifn); + // modal interface + if (guis[ifn].PopupStyle==kGUIPopupModal) PauseGame(); + // clear the cached mouse position + guis[ifn].OnControlPositionChanged(); + guis[ifn].Poll(); +} + +void InterfaceOff(int ifn) { + if ((ifn<0) | (ifn>=game.numgui)) quit("!GUIOff: invalid GUI specified"); + if (!guis[ifn].IsVisible()) { + debug_script_log("GUIOff(%d) ignored (already off)", ifn); + return; + } + debug_script_log("GUI %d turned off", ifn); + guis[ifn].SetVisible(false); + if (guis[ifn].MouseOverCtrl>=0) { + // Make sure that the overpic is turned off when the GUI goes off + guis[ifn].GetControl(guis[ifn].MouseOverCtrl)->OnMouseLeave(); + guis[ifn].MouseOverCtrl = -1; + } + guis[ifn].OnControlPositionChanged(); + guis_need_update = 1; + // modal interface + if (guis[ifn].PopupStyle==kGUIPopupModal) UnPauseGame(); +} + +void SetGUIObjectEnabled(int guin, int objn, int enabled) { + if ((guin<0) || (guin>=game.numgui)) + quit("!SetGUIObjectEnabled: invalid GUI number"); + if ((objn<0) || (objn>=guis[guin].GetControlCount())) + quit("!SetGUIObjectEnabled: invalid object number"); + + GUIControl_SetEnabled(guis[guin].GetControl(objn), enabled); +} + +void SetGUIObjectPosition(int guin, int objn, int xx, int yy) { + if ((guin<0) || (guin>=game.numgui)) + quit("!SetGUIObjectPosition: invalid GUI number"); + if ((objn<0) || (objn>=guis[guin].GetControlCount())) + quit("!SetGUIObjectPosition: invalid object number"); + + GUIControl_SetPosition(guis[guin].GetControl(objn), xx, yy); +} + +void SetGUIPosition(int ifn,int xx,int yy) { + if ((ifn<0) || (ifn>=game.numgui)) + quit("!SetGUIPosition: invalid GUI number"); + + GUI_SetPosition(&scrGui[ifn], xx, yy); +} + +void SetGUIObjectSize(int ifn, int objn, int newwid, int newhit) { + if ((ifn<0) || (ifn>=game.numgui)) + quit("!SetGUIObjectSize: invalid GUI number"); + + if ((objn<0) || (objn >= guis[ifn].GetControlCount())) + quit("!SetGUIObjectSize: invalid object number"); + + GUIControl_SetSize(guis[ifn].GetControl(objn), newwid, newhit); +} + +void SetGUISize (int ifn, int widd, int hitt) { + if ((ifn<0) || (ifn>=game.numgui)) + quit("!SetGUISize: invalid GUI number"); + + GUI_SetSize(&scrGui[ifn], widd, hitt); +} + +void SetGUIZOrder(int guin, int z) { + if ((guin<0) || (guin>=game.numgui)) + quit("!SetGUIZOrder: invalid GUI number"); + + GUI_SetZOrder(&scrGui[guin], z); +} + +void SetGUIClickable(int guin, int clickable) { + if ((guin<0) || (guin>=game.numgui)) + quit("!SetGUIClickable: invalid GUI number"); + + GUI_SetClickable(&scrGui[guin], clickable); +} + +// pass trans=0 for fully solid, trans=100 for fully transparent +void SetGUITransparency(int ifn, int trans) { + if ((ifn < 0) | (ifn >= game.numgui)) + quit("!SetGUITransparency: invalid GUI number"); + + GUI_SetTransparency(&scrGui[ifn], trans); +} + +void CentreGUI (int ifn) { + if ((ifn<0) | (ifn>=game.numgui)) + quit("!CentreGUI: invalid GUI number"); + + GUI_Centre(&scrGui[ifn]); +} + +int GetTextWidth(const char *text, int fontnum) { + VALIDATE_STRING(text); + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetTextWidth: invalid font number."); + + return game_to_data_coord(wgettextwidth_compensate(text, fontnum)); +} + +int GetTextHeight(const char *text, int fontnum, int width) { + VALIDATE_STRING(text); + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetTextHeight: invalid font number."); + + if (break_up_text_into_lines(text, Lines, data_to_game_coord(width), fontnum) == 0) + return 0; + return game_to_data_coord(getheightoflines(fontnum, Lines.Count())); +} + +int GetFontHeight(int fontnum) +{ + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetFontHeight: invalid font number."); + return game_to_data_coord(getfontheight_outlined(fontnum)); +} + +int GetFontLineSpacing(int fontnum) +{ + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetFontLineSpacing: invalid font number."); + return game_to_data_coord(getfontspacing_outlined(fontnum)); +} + +void SetGUIBackgroundPic (int guin, int slotn) { + if ((guin<0) | (guin>=game.numgui)) + quit("!SetGUIBackgroundPic: invalid GUI number"); + + GUI_SetBackgroundGraphic(&scrGui[guin], slotn); +} + +void DisableInterface() { + play.disabled_user_interface++; + guis_need_update = 1; + set_mouse_cursor(CURS_WAIT); + } + +void EnableInterface() { + guis_need_update = 1; + play.disabled_user_interface--; + if (play.disabled_user_interface<1) { + play.disabled_user_interface=0; + set_default_cursor(); + } + } +// Returns 1 if user interface is enabled, 0 if disabled +int IsInterfaceEnabled() { + return (play.disabled_user_interface > 0) ? 0 : 1; +} + +int GetGUIObjectAt (int xx, int yy) { + GUIObject *toret = GetGUIControlAtLocation(xx, yy); + if (toret == nullptr) + return -1; + + return toret->Id; +} + +int GetGUIAt (int xx,int yy) { + data_to_game_coords(&xx, &yy); + + int aa, ll; + for (ll = game.numgui - 1; ll >= 0; ll--) { + aa = play.gui_draw_order[ll]; + if (guis[aa].IsInteractableAt(xx, yy)) + return aa; + } + return -1; +} + +void SetTextWindowGUI (int guinum) { + if ((guinum < -1) | (guinum >= game.numgui)) + quit("!SetTextWindowGUI: invalid GUI number"); + + if (guinum < 0) ; // disable it + else if (!guis[guinum].IsTextWindow()) + quit("!SetTextWindowGUI: specified GUI is not a text window"); + + if (play.speech_textwindow_gui == game.options[OPT_TWCUSTOM]) + play.speech_textwindow_gui = guinum; + game.options[OPT_TWCUSTOM] = guinum; +} diff --git a/engines/ags/engine/ac/global_gui.h b/engines/ags/engine/ac/global_gui.h new file mode 100644 index 000000000000..2047fecc4b4a --- /dev/null +++ b/engines/ags/engine/ac/global_gui.h @@ -0,0 +1,54 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALGUI_H +#define __AGS_EE_AC__GLOBALGUI_H + +// IsGUIOn tells whether GUI is actually displayed on screen right now +int IsGUIOn (int guinum); +// This is an internal script function, and is undocumented. +// It is used by the editor's automatic macro generation. +// TODO: find out how relevant this comment is? +int FindGUIID (const char* GUIName); +// Sets GUI visible property on +void InterfaceOn(int ifn); +// Sets GUI visible property off +void InterfaceOff(int ifn); +void CentreGUI (int ifn); +int GetTextWidth(const char *text, int fontnum); +int GetTextHeight(const char *text, int fontnum, int width); +int GetFontHeight(int fontnum); +int GetFontLineSpacing(int fontnum); +void SetGUIBackgroundPic (int guin, int slotn); +void DisableInterface(); +void EnableInterface(); +// Returns 1 if user interface is enabled, 0 if disabled +int IsInterfaceEnabled(); +// pass trans=0 for fully solid, trans=100 for fully transparent +void SetGUITransparency(int ifn, int trans); +void SetGUIClickable(int guin, int clickable); +void SetGUIZOrder(int guin, int z); +void SetGUISize (int ifn, int widd, int hitt); +void SetGUIPosition(int ifn,int xx,int yy); +void SetGUIObjectSize(int ifn, int objn, int newwid, int newhit); +void SetGUIObjectEnabled(int guin, int objn, int enabled); +void SetGUIObjectPosition(int guin, int objn, int xx, int yy); +int GetGUIObjectAt (int xx, int yy); +int GetGUIAt (int xx,int yy); +void SetTextWindowGUI (int guinum); + +#endif // __AGS_EE_AC__GLOBALGUI_H diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp new file mode 100644 index 000000000000..cab508f5628e --- /dev/null +++ b/engines/ags/engine/ac/global_hotspot.cpp @@ -0,0 +1,147 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_hotspot.h" +#include "ac/common.h" +#include "ac/common_defines.h" +#include "ac/characterinfo.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_character.h" +#include "ac/global_translation.h" +#include "ac/hotspot.h" +#include "ac/properties.h" +#include "ac/roomstatus.h" +#include "ac/string.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "script/script.h" + +using namespace AGS::Common; + +extern RoomStruct thisroom; +extern RoomStatus*croom; +extern CharacterInfo*playerchar; +extern GameSetupStruct game; + + +void DisableHotspot(int hsnum) { + if ((hsnum<1) | (hsnum>=MAX_ROOM_HOTSPOTS)) + quit("!DisableHotspot: invalid hotspot specified"); + croom->hotspot_enabled[hsnum]=0; + debug_script_log("Hotspot %d disabled", hsnum); +} + +void EnableHotspot(int hsnum) { + if ((hsnum<1) | (hsnum>=MAX_ROOM_HOTSPOTS)) + quit("!EnableHotspot: invalid hotspot specified"); + croom->hotspot_enabled[hsnum]=1; + debug_script_log("Hotspot %d re-enabled", hsnum); +} + +int GetHotspotPointX (int hotspot) { + if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) + quit("!GetHotspotPointX: invalid hotspot"); + + if (thisroom.Hotspots[hotspot].WalkTo.X < 1) + return -1; + + return thisroom.Hotspots[hotspot].WalkTo.X; +} + +int GetHotspotPointY (int hotspot) { + if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) + quit("!GetHotspotPointY: invalid hotspot"); + + if (thisroom.Hotspots[hotspot].WalkTo.X < 1) // TODO: there was "x" here, why? + return -1; + + return thisroom.Hotspots[hotspot].WalkTo.Y; +} + +int GetHotspotIDAtScreen(int scrx, int scry) { + VpPoint vpt = play.ScreenToRoomDivDown(scrx, scry); + if (vpt.second < 0) return 0; + return get_hotspot_at(vpt.first.X, vpt.first.Y); +} + +void GetHotspotName(int hotspot, char *buffer) { + VALIDATE_STRING(buffer); + if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) + quit("!GetHotspotName: invalid hotspot number"); + + strcpy(buffer, get_translation(thisroom.Hotspots[hotspot].Name)); +} + +void RunHotspotInteraction (int hotspothere, int mood) { + + int passon=-1,cdata=-1; + if (mood==MODE_TALK) passon=4; + else if (mood==MODE_WALK) passon=0; + else if (mood==MODE_LOOK) passon=1; + else if (mood==MODE_HAND) passon=2; + else if (mood==MODE_PICKUP) passon=7; + else if (mood==MODE_CUSTOM1) passon = 8; + else if (mood==MODE_CUSTOM2) passon = 9; + else if (mood==MODE_USE) { passon=3; + cdata=playerchar->activeinv; + play.usedinv=cdata; + } + + if ((game.options[OPT_WALKONLOOK]==0) & (mood==MODE_LOOK)) ; + else if (play.auto_use_walkto_points == 0) ; + else if ((mood!=MODE_WALK) && (play.check_interaction_only == 0)) + MoveCharacterToHotspot(game.playercharacter,hotspothere); + + // can't use the setevent functions because this ProcessClick is only + // executed once in a eventlist + const char *oldbasename = evblockbasename; + int oldblocknum = evblocknum; + + evblockbasename="hotspot%d"; + evblocknum=hotspothere; + + if (thisroom.Hotspots[hotspothere].EventHandlers != nullptr) + { + if (passon>=0) + run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), passon, 5, (passon == 3)); + run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), 5); // any click on hotspot + } + else + { + if (passon>=0) { + if (run_interaction_event(&croom->intrHotspot[hotspothere],passon, 5, (passon == 3))) { + evblockbasename = oldbasename; + evblocknum = oldblocknum; + return; + } + } + // run the 'any click on hs' event + run_interaction_event(&croom->intrHotspot[hotspothere],5); + } + + evblockbasename = oldbasename; + evblocknum = oldblocknum; +} + +int GetHotspotProperty (int hss, const char *property) +{ + return get_int_property(thisroom.Hotspots[hss].Properties, croom->hsProps[hss], property); +} + +void GetHotspotPropertyText (int item, const char *property, char *bufer) +{ + get_text_property(thisroom.Hotspots[item].Properties, croom->hsProps[item], property, bufer); +} diff --git a/engines/ags/engine/ac/global_hotspot.h b/engines/ags/engine/ac/global_hotspot.h new file mode 100644 index 000000000000..ec595042eadd --- /dev/null +++ b/engines/ags/engine/ac/global_hotspot.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALHOTSPOT_H +#define __AGS_EE_AC__GLOBALHOTSPOT_H + +void DisableHotspot(int hsnum); +void EnableHotspot(int hsnum); +int GetHotspotPointX (int hotspot); +int GetHotspotPointY (int hotspot); +// Gets hotspot ID at the given screen coordinates; +// if hotspot is disabled or non-existing, returns 0 (no area) +int GetHotspotIDAtScreen(int xxx,int yyy); +void GetHotspotName(int hotspot, char *buffer); +void RunHotspotInteraction (int hotspothere, int mood); + +int GetHotspotProperty (int hss, const char *property); +void GetHotspotPropertyText (int item, const char *property, char *bufer); + + +#endif // __AGS_EE_AC__GLOBALHOTSPOT_H diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp new file mode 100644 index 000000000000..4180cc283c42 --- /dev/null +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -0,0 +1,144 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_gui.h" +#include "ac/global_inventoryitem.h" +#include "ac/global_translation.h" +#include "ac/inventoryitem.h" +#include "ac/invwindow.h" +#include "ac/properties.h" +#include "ac/string.h" +#include "gui/guimain.h" +#include "gui/guiinv.h" +#include "ac/event.h" +#include "ac/gamestate.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern GameState play; +extern int mousex, mousey; +extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; +extern const char*evblockbasename; +extern int evblocknum; +extern CharacterInfo*playerchar; + + +void set_inv_item_pic(int invi, int piccy) { + if ((invi < 1) || (invi > game.numinvitems)) + quit("!SetInvItemPic: invalid inventory item specified"); + + if (game.invinfo[invi].pic == piccy) + return; + + if (game.invinfo[invi].pic == game.invinfo[invi].cursorPic) + { + // Backwards compatibility -- there didn't used to be a cursorPic, + // so if they're the same update both. + set_inv_item_cursorpic(invi, piccy); + } + + game.invinfo[invi].pic = piccy; + guis_need_update = 1; +} + +void SetInvItemName(int invi, const char *newName) { + if ((invi < 1) || (invi > game.numinvitems)) + quit("!SetInvName: invalid inventory item specified"); + + // set the new name, making sure it doesn't overflow the buffer + strncpy(game.invinfo[invi].name, newName, 25); + game.invinfo[invi].name[24] = 0; + + // might need to redraw the GUI if it has the inv item name on it + guis_need_update = 1; +} + +int GetInvAt (int xxx, int yyy) { + int ongui = GetGUIAt (xxx, yyy); + if (ongui >= 0) { + int mxwas = mousex, mywas = mousey; + mousex = data_to_game_coord(xxx) - guis[ongui].X; + mousey = data_to_game_coord(yyy) - guis[ongui].Y; + int onobj = guis[ongui].FindControlUnderMouse(); + GUIObject *guio = guis[ongui].GetControl(onobj); + if (guio) { + mouse_ifacebut_xoffs = mousex-(guio->X); + mouse_ifacebut_yoffs = mousey-(guio->Y); + } + mousex = mxwas; + mousey = mywas; + if (guio && (guis[ongui].GetControlType(onobj) == kGUIInvWindow)) + return offset_over_inv((GUIInvWindow*)guio); + } + return -1; +} + +void GetInvName(int indx,char*buff) { + VALIDATE_STRING(buff); + if ((indx<0) | (indx>=game.numinvitems)) quit("!GetInvName: invalid inventory item specified"); + strcpy(buff,get_translation(game.invinfo[indx].name)); +} + +int GetInvGraphic(int indx) { + if ((indx<0) | (indx>=game.numinvitems)) quit("!GetInvGraphic: invalid inventory item specified"); + + return game.invinfo[indx].pic; +} + +void RunInventoryInteraction (int iit, int modd) { + if ((iit < 0) || (iit >= game.numinvitems)) + quit("!RunInventoryInteraction: invalid inventory number"); + + evblocknum = iit; + if (modd == MODE_LOOK) + run_event_block_inv(iit, 0); + else if (modd == MODE_HAND) + run_event_block_inv(iit, 1); + else if (modd == MODE_USE) { + play.usedinv = playerchar->activeinv; + run_event_block_inv(iit, 3); + } + else if (modd == MODE_TALK) + run_event_block_inv(iit, 2); + else // other click on invnetory + run_event_block_inv(iit, 4); +} + +int IsInventoryInteractionAvailable (int item, int mood) { + if ((item < 0) || (item >= MAX_INV)) + quit("!IsInventoryInteractionAvailable: invalid inventory number"); + + play.check_interaction_only = 1; + + RunInventoryInteraction(item, mood); + + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + + if (ciwas == 2) + return 1; + + return 0; +} + +int GetInvProperty (int item, const char *property) { + return get_int_property (game.invProps[item], play.invProps[item], property); +} + +void GetInvPropertyText (int item, const char *property, char *bufer) { + get_text_property (game.invProps[item], play.invProps[item], property, bufer); +} diff --git a/engines/ags/engine/ac/global_inventoryitem.h b/engines/ags/engine/ac/global_inventoryitem.h new file mode 100644 index 000000000000..840bb73e0ea8 --- /dev/null +++ b/engines/ags/engine/ac/global_inventoryitem.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALINVENTORYITEM_H +#define __AGS_EE_AC__GLOBALINVENTORYITEM_H + +void set_inv_item_pic(int invi, int piccy); +void SetInvItemName(int invi, const char *newName); +int GetInvAt (int xxx, int yyy); +void GetInvName(int indx,char*buff); +int GetInvGraphic(int indx); +void RunInventoryInteraction (int iit, int modd); +int IsInventoryInteractionAvailable (int item, int mood); +int GetInvProperty (int item, const char *property); +void GetInvPropertyText (int item, const char *property, char *bufer); + +#endif // __AGS_EE_AC__GLOBALINVENTORYITEM_H diff --git a/engines/ags/engine/ac/global_invwindow.cpp b/engines/ags/engine/ac/global_invwindow.cpp new file mode 100644 index 000000000000..edd4ed926b4c --- /dev/null +++ b/engines/ags/engine/ac/global_invwindow.cpp @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/gamestate.h" +#include "ac/global_invwindow.h" +#include "ac/global_translation.h" +#include "ac/properties.h" +#include "gui/guiinv.h" +#include "script/executingscript.h" + +extern ExecutingScript*curscript; +extern GameState play; + +void sc_invscreen() { + curscript->queue_action(ePSAInvScreen, 0, "InventoryScreen"); +} + +void SetInvDimensions(int ww,int hh) { + play.inv_item_wid = ww; + play.inv_item_hit = hh; + play.inv_numdisp = 0; + // backwards compatibility + for (int i = 0; i < numguiinv; i++) { + guiinv[i].ItemWidth = ww; + guiinv[i].ItemHeight = hh; + guiinv[i].OnResized(); + } + guis_need_update = 1; +} diff --git a/engines/ags/engine/ac/global_invwindow.h b/engines/ags/engine/ac/global_invwindow.h new file mode 100644 index 000000000000..afa1d25c5cb4 --- /dev/null +++ b/engines/ags/engine/ac/global_invwindow.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALINVWINDOW_H +#define __AGS_EE_AC__GLOBALINVWINDOW_H + +void sc_invscreen(); +void SetInvDimensions(int ww,int hh); + +#endif // __AGS_EE_AC__GLOBALINVWINDOW_H diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp new file mode 100644 index 000000000000..7a0335e93747 --- /dev/null +++ b/engines/ags/engine/ac/global_label.cpp @@ -0,0 +1,58 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_label.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/label.h" +#include "ac/string.h" +#include "gui/guimain.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; + +void SetLabelColor(int guin,int objn, int colr) { + if ((guin<0) | (guin>=game.numgui)) + quit("!SetLabelColor: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) + quit("!SetLabelColor: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUILabel) + quit("!SetLabelColor: specified control is not a label"); + + GUILabel*guil=(GUILabel*)guis[guin].GetControl(objn); + Label_SetColor(guil, colr); +} + +void SetLabelText(int guin,int objn, const char*newtx) { + VALIDATE_STRING(newtx); + if ((guin<0) | (guin>=game.numgui)) quit("!SetLabelText: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetLabelTexT: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUILabel) + quit("!SetLabelText: specified control is not a label"); + + GUILabel*guil=(GUILabel*)guis[guin].GetControl(objn); + Label_SetText(guil, newtx); +} + +void SetLabelFont(int guin,int objn, int fontnum) { + + if ((guin<0) | (guin>=game.numgui)) quit("!SetLabelFont: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetLabelFont: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUILabel) + quit("!SetLabelFont: specified control is not a label"); + + GUILabel*guil=(GUILabel*)guis[guin].GetControl(objn); + Label_SetFont(guil, fontnum); +} diff --git a/engines/ags/engine/ac/global_label.h b/engines/ags/engine/ac/global_label.h new file mode 100644 index 000000000000..fa96942f759b --- /dev/null +++ b/engines/ags/engine/ac/global_label.h @@ -0,0 +1,25 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALLABEL_H +#define __AGS_EE_AC__GLOBALLABEL_H + +void SetLabelColor(int guin,int objn, int colr); +void SetLabelText(int guin,int objn, const char*newtx); +void SetLabelFont(int guin,int objn, int fontnum); + +#endif // __AGS_EE_AC__GLOBALLABEL_H diff --git a/engines/ags/engine/ac/global_listbox.cpp b/engines/ags/engine/ac/global_listbox.cpp new file mode 100644 index 000000000000..546eac2e0088 --- /dev/null +++ b/engines/ags/engine/ac/global_listbox.cpp @@ -0,0 +1,62 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_listbox.h" +#include "ac/common.h" +#include "ac/listbox.h" +#include "ac/string.h" + +void ListBoxClear(int guin, int objn) { + GUIListBox*guisl=is_valid_listbox(guin,objn); + ListBox_Clear(guisl); +} +void ListBoxAdd(int guin, int objn, const char*newitem) { + GUIListBox*guisl=is_valid_listbox(guin,objn); + ListBox_AddItem(guisl, newitem); +} +void ListBoxRemove(int guin, int objn, int itemIndex) { + GUIListBox*guisl = is_valid_listbox(guin,objn); + ListBox_RemoveItem(guisl, itemIndex); +} +int ListBoxGetSelected(int guin, int objn) { + GUIListBox*guisl=is_valid_listbox(guin,objn); + return ListBox_GetSelectedIndex(guisl); +} +int ListBoxGetNumItems(int guin, int objn) { + GUIListBox*guisl=is_valid_listbox(guin,objn); + return ListBox_GetItemCount(guisl); +} +char* ListBoxGetItemText(int guin, int objn, int item, char*buffer) { + VALIDATE_STRING(buffer); + GUIListBox*guisl=is_valid_listbox(guin,objn); + return ListBox_GetItemText(guisl, item, buffer); +} +void ListBoxSetSelected(int guin, int objn, int newsel) { + GUIListBox*guisl=is_valid_listbox(guin,objn); + ListBox_SetSelectedIndex(guisl, newsel); +} +void ListBoxSetTopItem (int guin, int objn, int item) { + GUIListBox*guisl = is_valid_listbox(guin,objn); + ListBox_SetTopItem(guisl, item); +} + +int ListBoxSaveGameList (int guin, int objn) { + GUIListBox*guisl=is_valid_listbox(guin,objn); + return ListBox_FillSaveGameList(guisl); +} + +void ListBoxDirList (int guin, int objn, const char*filemask) { + GUIListBox *guisl = is_valid_listbox(guin,objn); + ListBox_FillDirList(guisl, filemask); +} diff --git a/engines/ags/engine/ac/global_listbox.h b/engines/ags/engine/ac/global_listbox.h new file mode 100644 index 000000000000..d6be2f449fd8 --- /dev/null +++ b/engines/ags/engine/ac/global_listbox.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALLISTBOX_H +#define __AGS_EE_AC__GLOBALLISTBOX_H + +void ListBoxClear(int guin, int objn); +void ListBoxAdd(int guin, int objn, const char*newitem); +void ListBoxRemove(int guin, int objn, int itemIndex); +int ListBoxGetSelected(int guin, int objn); +int ListBoxGetNumItems(int guin, int objn); +char* ListBoxGetItemText(int guin, int objn, int item, char*buffer); +void ListBoxSetSelected(int guin, int objn, int newsel); +void ListBoxSetTopItem (int guin, int objn, int item); +int ListBoxSaveGameList (int guin, int objn); +void ListBoxDirList (int guin, int objn, const char*filemask); + +#endif // __AGS_EE_AC__GLOBALLISTBOX_H diff --git a/engines/ags/engine/ac/global_mouse.cpp b/engines/ags/engine/ac/global_mouse.cpp new file mode 100644 index 000000000000..206f50297737 --- /dev/null +++ b/engines/ags/engine/ac/global_mouse.cpp @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_mouse.h" +#include "ac/gamestate.h" + +extern GameState play; + +void HideMouseCursor () { + play.mouse_cursor_hidden = 1; +} + +void ShowMouseCursor () { + play.mouse_cursor_hidden = 0; +} diff --git a/engines/ags/engine/ac/global_mouse.h b/engines/ags/engine/ac/global_mouse.h new file mode 100644 index 000000000000..dbff7fa38637 --- /dev/null +++ b/engines/ags/engine/ac/global_mouse.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALMOUSE_H +#define __AGS_EE_AC__GLOBALMOUSE_H + +void HideMouseCursor (); +void ShowMouseCursor (); + +#endif // __AGS_EE_AC__GLOBALMOUSE_H diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp new file mode 100644 index 000000000000..aa43d906b707 --- /dev/null +++ b/engines/ags/engine/ac/global_object.cpp @@ -0,0 +1,523 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_object.h" +#include "ac/common.h" +#include "ac/object.h" +#include "ac/view.h" +#include "ac/character.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_character.h" +#include "ac/global_translation.h" +#include "ac/object.h" +#include "ac/objectcache.h" +#include "ac/properties.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "ac/string.h" +#include "ac/viewframe.h" +#include "debug/debug_log.h" +#include "main/game_run.h" +#include "script/script.h" +#include "ac/spritecache.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" +#include "gfx/gfx_def.h" + +using namespace AGS::Common; + +#define OVERLAPPING_OBJECT 1000 + +extern RoomStatus*croom; +extern RoomObject*objs; +extern ViewStruct*views; +extern GameSetupStruct game; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; +extern RoomStruct thisroom; +extern CharacterInfo*playerchar; +extern int displayed_room; +extern SpriteCache spriteset; +extern int actSpsCount; +extern Bitmap **actsps; +extern IDriverDependantBitmap* *actspsbmp; +extern IGraphicsDriver *gfxDriver; + +// Used for deciding whether a char or obj was closer +int obj_lowest_yp; + +int GetObjectIDAtScreen(int scrx, int scry) +{ + // translate screen co-ordinates to room co-ordinates + VpPoint vpt = play.ScreenToRoomDivDown(scrx, scry); + if (vpt.second < 0) + return -1; + return GetObjectIDAtRoom(vpt.first.X, vpt.first.Y); +} + +int GetObjectIDAtRoom(int roomx, int roomy) +{ + int aa,bestshotyp=-1,bestshotwas=-1; + // Iterate through all objects in the room + for (aa=0;aanumobj;aa++) { + if (objs[aa].on != 1) continue; + if (objs[aa].flags & OBJF_NOINTERACT) + continue; + int xxx=objs[aa].x,yyy=objs[aa].y; + int isflipped = 0; + int spWidth = game_to_data_coord(objs[aa].get_width()); + int spHeight = game_to_data_coord(objs[aa].get_height()); + if (objs[aa].view >= 0) + isflipped = views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE; + + Bitmap *theImage = GetObjectImage(aa, &isflipped); + + if (is_pos_in_sprite(roomx, roomy, xxx, yyy - spHeight, theImage, + spWidth, spHeight, isflipped) == FALSE) + continue; + + int usebasel = objs[aa].get_baseline(); + if (usebasel < bestshotyp) continue; + + bestshotwas = aa; + bestshotyp = usebasel; + } + obj_lowest_yp = bestshotyp; + return bestshotwas; +} + +void SetObjectTint(int obj, int red, int green, int blue, int opacity, int luminance) { + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) + quit("!SetObjectTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); + + if (!is_valid_object(obj)) + quit("!SetObjectTint: invalid object number specified"); + + debug_script_log("Set object %d tint RGB(%d,%d,%d) %d%%", obj, red, green, blue, opacity); + + objs[obj].tint_r = red; + objs[obj].tint_g = green; + objs[obj].tint_b = blue; + objs[obj].tint_level = opacity; + objs[obj].tint_light = (luminance * 25) / 10; + objs[obj].flags &= ~OBJF_HASLIGHT; + objs[obj].flags |= OBJF_HASTINT; +} + +void RemoveObjectTint(int obj) { + if (!is_valid_object(obj)) + quit("!RemoveObjectTint: invalid object"); + + if (objs[obj].flags & (OBJF_HASTINT | OBJF_HASLIGHT)) { + debug_script_log("Un-tint object %d", obj); + objs[obj].flags &= ~(OBJF_HASTINT | OBJF_HASLIGHT); + } + else { + debug_script_warn("RemoveObjectTint called but object was not tinted"); + } +} + +void SetObjectView(int obn,int vii) { + if (!is_valid_object(obn)) quit("!SetObjectView: invalid object number specified"); + debug_script_log("Object %d set to view %d", obn, vii); + if ((vii < 1) || (vii > game.numviews)) { + quitprintf("!SetObjectView: invalid view number (You said %d, max is %d)", vii, game.numviews); + } + vii--; + + objs[obn].view=vii; + objs[obn].frame=0; + if (objs[obn].loop >= views[vii].numLoops) + objs[obn].loop=0; + objs[obn].cycling=0; + objs[obn].num = views[vii].loops[0].frames[0].pic; +} + +void SetObjectFrame(int obn,int viw,int lop,int fra) { + if (!is_valid_object(obn)) quit("!SetObjectFrame: invalid object number specified"); + viw--; + if (viw < 0 || viw >= game.numviews) quitprintf("!SetObjectFrame: invalid view number used (%d, range is 0 - %d)", viw, game.numviews - 1); + if (lop < 0 || lop >= views[viw].numLoops) quitprintf("!SetObjectFrame: invalid loop number used (%d, range is 0 - %d)", lop, views[viw].numLoops - 1); + // AGS < 3.5.1 let user to pass literally any positive invalid frame value by silently reassigning it to zero... + if (loaded_game_file_version < kGameVersion_351) + { + if (fra >= views[viw].loops[lop].numFrames) + { + debug_script_warn("SetObjectFrame: frame index out of range (%d, must be 0 - %d), set to 0", fra, views[viw].loops[lop].numFrames - 1); + fra = 0; + } + } + if (fra < 0 || fra >= views[viw].loops[lop].numFrames) quitprintf("!SetObjectFrame: invalid frame number used (%d, range is 0 - %d)", fra, views[viw].loops[lop].numFrames - 1); + // AGS >= 3.2.0 do not let assign an empty loop + // NOTE: pre-3.2.0 games are converting views from ViewStruct272 struct, always has at least 1 frame + if (loaded_game_file_version >= kGameVersion_320) + { + if (views[viw].loops[lop].numFrames == 0) + quit("!SetObjectFrame: specified loop has no frames"); + } + objs[obn].view = viw; + objs[obn].loop = lop; + objs[obn].frame = fra; + objs[obn].cycling=0; + objs[obn].num = views[viw].loops[lop].frames[fra].pic; + CheckViewFrame(viw, objs[obn].loop, objs[obn].frame); +} + +// pass trans=0 for fully solid, trans=100 for fully transparent +void SetObjectTransparency(int obn,int trans) { + if (!is_valid_object(obn)) quit("!SetObjectTransparent: invalid object number specified"); + if ((trans < 0) || (trans > 100)) quit("!SetObjectTransparent: transparency value must be between 0 and 100"); + + objs[obn].transparent = GfxDef::Trans100ToLegacyTrans255(trans); +} + + + +void SetObjectBaseline (int obn, int basel) { + if (!is_valid_object(obn)) quit("!SetObjectBaseline: invalid object number specified"); + // baseline has changed, invalidate the cache + if (objs[obn].baseline != basel) { + objcache[obn].ywas = -9999; + objs[obn].baseline = basel; + } +} + +int GetObjectBaseline(int obn) { + if (!is_valid_object(obn)) quit("!GetObjectBaseline: invalid object number specified"); + + if (objs[obn].baseline < 1) + return 0; + + return objs[obn].baseline; +} + +void AnimateObjectImpl(int obn, int loopn, int spdd, int rept, int direction, int blocking, int sframe) { + if (obn>=MANOBJNUM) { + scAnimateCharacter(obn - 100,loopn,spdd,rept); + return; + } + if (!is_valid_object(obn)) + quit("!AnimateObject: invalid object number specified"); + if (objs[obn].view < 0) + quit("!AnimateObject: object has not been assigned a view"); + if (loopn < 0 || loopn >= views[objs[obn].view].numLoops) + quit("!AnimateObject: invalid loop number specified"); + if (sframe < 0 || sframe >= views[objs[obn].view].loops[loopn].numFrames) + quit("!AnimateObject: invalid starting frame number specified"); + if ((direction < 0) || (direction > 1)) + quit("!AnimateObjectEx: invalid direction"); + if ((rept < 0) || (rept > 2)) + quit("!AnimateObjectEx: invalid repeat value"); + if (views[objs[obn].view].loops[loopn].numFrames < 1) + quit("!AnimateObject: no frames in the specified view loop"); + + debug_script_log("Obj %d start anim view %d loop %d, speed %d, repeat %d, frame %d", obn, objs[obn].view+1, loopn, spdd, rept, sframe); + + objs[obn].cycling = rept+1 + (direction * 10); + objs[obn].loop=loopn; + // reverse animation starts at the *previous frame* + if (direction) { + sframe--; + if (sframe < 0) + sframe = views[objs[obn].view].loops[loopn].numFrames - (-sframe); + } + objs[obn].frame = sframe; + + objs[obn].overall_speed=spdd; + objs[obn].wait = spdd+views[objs[obn].view].loops[loopn].frames[objs[obn].frame].speed; + objs[obn].num = views[objs[obn].view].loops[loopn].frames[objs[obn].frame].pic; + CheckViewFrame (objs[obn].view, loopn, objs[obn].frame); + + if (blocking) + GameLoopUntilValueIsZero(&objs[obn].cycling); +} + +void AnimateObjectEx(int obn, int loopn, int spdd, int rept, int direction, int blocking) { + AnimateObjectImpl(obn, loopn, spdd, rept, direction, blocking, 0); +} + +void AnimateObject(int obn,int loopn,int spdd,int rept) { + AnimateObjectImpl(obn, loopn, spdd, rept, 0, 0, 0); +} + +void MergeObject(int obn) { + if (!is_valid_object(obn)) quit("!MergeObject: invalid object specified"); + int theHeight; + + construct_object_gfx(obn, nullptr, &theHeight, true); + + //Bitmap *oldabuf = graphics->bmp; + //abuf = thisroom.BgFrames.Graphic[play.bg_frame]; + PBitmap bg_frame = thisroom.BgFrames[play.bg_frame].Graphic; + if (bg_frame->GetColorDepth() != actsps[obn]->GetColorDepth()) + quit("!MergeObject: unable to merge object due to color depth differences"); + + int xpos = data_to_game_coord(objs[obn].x); + int ypos = (data_to_game_coord(objs[obn].y) - theHeight); + + draw_sprite_support_alpha(bg_frame.get(), false, xpos, ypos, actsps[obn], (game.SpriteInfos[objs[obn].num].Flags & SPF_ALPHACHANNEL) != 0); + invalidate_screen(); + mark_current_background_dirty(); + + //abuf = oldabuf; + // mark the sprite as merged + objs[obn].on = 2; + debug_script_log("Object %d merged into background", obn); +} + +void StopObjectMoving(int objj) { + if (!is_valid_object(objj)) + quit("!StopObjectMoving: invalid object number"); + objs[objj].moving = 0; + + debug_script_log("Object %d stop moving", objj); +} + +void ObjectOff(int obn) { + if (!is_valid_object(obn)) quit("!ObjectOff: invalid object specified"); + // don't change it if on == 2 (merged) + if (objs[obn].on == 1) { + objs[obn].on = 0; + debug_script_log("Object %d turned off", obn); + StopObjectMoving(obn); + } +} + +void ObjectOn(int obn) { + if (!is_valid_object(obn)) quit("!ObjectOn: invalid object specified"); + if (objs[obn].on == 0) { + objs[obn].on = 1; + debug_script_log("Object %d turned on", obn); + } +} + +int IsObjectOn (int objj) { + if (!is_valid_object(objj)) quit("!IsObjectOn: invalid object number"); + + // ==1 is on, ==2 is merged into background + if (objs[objj].on == 1) + return 1; + + return 0; +} + +void SetObjectGraphic(int obn,int slott) { + if (!is_valid_object(obn)) quit("!SetObjectGraphic: invalid object specified"); + + if (objs[obn].num != slott) { + objs[obn].num = slott; + debug_script_log("Object %d graphic changed to slot %d", obn, slott); + } + objs[obn].cycling=0; + objs[obn].frame = 0; + objs[obn].loop = 0; + objs[obn].view = -1; +} + +int GetObjectGraphic(int obn) { + if (!is_valid_object(obn)) quit("!GetObjectGraphic: invalid object specified"); + return objs[obn].num; +} + +int GetObjectY (int objj) { + if (!is_valid_object(objj)) quit("!GetObjectY: invalid object number"); + return objs[objj].y; +} + +int IsObjectAnimating(int objj) { + if (!is_valid_object(objj)) quit("!IsObjectAnimating: invalid object number"); + return (objs[objj].cycling != 0) ? 1 : 0; +} + +int IsObjectMoving(int objj) { + if (!is_valid_object(objj)) quit("!IsObjectMoving: invalid object number"); + return (objs[objj].moving > 0) ? 1 : 0; +} + +void SetObjectPosition(int objj, int tox, int toy) { + if (!is_valid_object(objj)) + quit("!SetObjectPosition: invalid object number"); + + if (objs[objj].moving > 0) + { + debug_script_warn("Object.SetPosition: cannot set position while object is moving"); + return; + } + + objs[objj].x = tox; + objs[objj].y = toy; +} + +void GetObjectName(int obj, char *buffer) { + VALIDATE_STRING(buffer); + if (!is_valid_object(obj)) + quit("!GetObjectName: invalid object number"); + + strcpy(buffer, get_translation(thisroom.Objects[obj].Name)); +} + +void MoveObject(int objj,int xx,int yy,int spp) { + move_object(objj,xx,yy,spp,0); +} +void MoveObjectDirect(int objj,int xx,int yy,int spp) { + move_object(objj,xx,yy,spp,1); +} + +void SetObjectClickable (int cha, int clik) { + if (!is_valid_object(cha)) + quit("!SetObjectClickable: Invalid object specified"); + objs[cha].flags&=~OBJF_NOINTERACT; + if (clik == 0) + objs[cha].flags|=OBJF_NOINTERACT; +} + +void SetObjectIgnoreWalkbehinds (int cha, int clik) { + if (!is_valid_object(cha)) + quit("!SetObjectIgnoreWalkbehinds: Invalid object specified"); + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v350) + debug_script_warn("IgnoreWalkbehinds is not recommended for use, consider other solutions"); + objs[cha].flags&=~OBJF_NOWALKBEHINDS; + if (clik) + objs[cha].flags|=OBJF_NOWALKBEHINDS; + // clear the cache + objcache[cha].ywas = -9999; +} + +void RunObjectInteraction (int aa, int mood) { + if (!is_valid_object(aa)) + quit("!RunObjectInteraction: invalid object number for current room"); + int passon=-1,cdata=-1; + if (mood==MODE_LOOK) passon=0; + else if (mood==MODE_HAND) passon=1; + else if (mood==MODE_TALK) passon=2; + else if (mood==MODE_PICKUP) passon=5; + else if (mood==MODE_CUSTOM1) passon = 6; + else if (mood==MODE_CUSTOM2) passon = 7; + else if (mood==MODE_USE) { passon=3; + cdata=playerchar->activeinv; + play.usedinv=cdata; } + evblockbasename="object%d"; evblocknum=aa; + + if (thisroom.Objects[aa].EventHandlers != nullptr) + { + if (passon>=0) + { + if (run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), passon, 4, (passon == 3))) + return; + } + run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), 4); // any click on obj + } + else + { + if (passon>=0) { + if (run_interaction_event(&croom->intrObject[aa],passon, 4, (passon == 3))) + return; + } + run_interaction_event(&croom->intrObject[aa],4); // any click on obj + } +} + +int AreObjectsColliding(int obj1,int obj2) { + if ((!is_valid_object(obj1)) | (!is_valid_object(obj2))) + quit("!AreObjectsColliding: invalid object specified"); + + return (AreThingsOverlapping(obj1 + OVERLAPPING_OBJECT, obj2 + OVERLAPPING_OBJECT)) ? 1 : 0; +} + +int GetThingRect(int thing, _Rect *rect) { + if (is_valid_character(thing)) { + if (game.chars[thing].room != displayed_room) + return 0; + + int charwid = game_to_data_coord(GetCharacterWidth(thing)); + rect->x1 = game.chars[thing].x - (charwid / 2); + rect->x2 = rect->x1 + charwid; + rect->y1 = game.chars[thing].get_effective_y() - game_to_data_coord(GetCharacterHeight(thing)); + rect->y2 = game.chars[thing].get_effective_y(); + } + else if (is_valid_object(thing - OVERLAPPING_OBJECT)) { + int objid = thing - OVERLAPPING_OBJECT; + if (objs[objid].on != 1) + return 0; + rect->x1 = objs[objid].x; + rect->x2 = objs[objid].x + game_to_data_coord(objs[objid].get_width()); + rect->y1 = objs[objid].y - game_to_data_coord(objs[objid].get_height()); + rect->y2 = objs[objid].y; + } + else + quit("!AreThingsOverlapping: invalid parameter"); + + return 1; +} + +int AreThingsOverlapping(int thing1, int thing2) { + _Rect r1, r2; + // get the bounding rectangles, and return 0 if the object/char + // is currently turned off + if (GetThingRect(thing1, &r1) == 0) + return 0; + if (GetThingRect(thing2, &r2) == 0) + return 0; + + if ((r1.x2 > r2.x1) && (r1.x1 < r2.x2) && + (r1.y2 > r2.y1) && (r1.y1 < r2.y2)) { + // determine how far apart they are + // take the smaller of the X distances as the overlapping amount + int xdist = abs(r1.x2 - r2.x1); + if (abs(r1.x1 - r2.x2) < xdist) + xdist = abs(r1.x1 - r2.x2); + // take the smaller of the Y distances + int ydist = abs(r1.y2 - r2.y1); + if (abs(r1.y1 - r2.y2) < ydist) + ydist = abs(r1.y1 - r2.y2); + // the overlapping amount is the smaller of the X and Y ovrlap + if (xdist < ydist) + return xdist; + else + return ydist; + // return 1; + } + return 0; +} + +int GetObjectProperty (int hss, const char *property) +{ + if (!is_valid_object(hss)) + quit("!GetObjectProperty: invalid object"); + return get_int_property(thisroom.Objects[hss].Properties, croom->objProps[hss], property); +} + +void GetObjectPropertyText (int item, const char *property, char *bufer) +{ + get_text_property(thisroom.Objects[item].Properties, croom->objProps[item], property, bufer); +} + +Bitmap *GetObjectImage(int obj, int *isFlipped) +{ + if (!gfxDriver->HasAcceleratedTransform()) + { + if (actsps[obj] != nullptr) { + // the actsps image is pre-flipped, so no longer register the image as such + if (isFlipped) + *isFlipped = 0; + + return actsps[obj]; + } + } + return spriteset[objs[obj].num]; +} diff --git a/engines/ags/engine/ac/global_object.h b/engines/ags/engine/ac/global_object.h new file mode 100644 index 000000000000..ac4a8776572b --- /dev/null +++ b/engines/ags/engine/ac/global_object.h @@ -0,0 +1,71 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALOBJECT_H +#define __AGS_EE_AC__GLOBALOBJECT_H + +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; // FIXME later + +// TODO: merge with other Rect declared in bitmap unit +struct _Rect { + int x1,y1,x2,y2; +}; + +// Get object at the given screen coordinates +int GetObjectIDAtScreen(int xx,int yy); +// Get object at the given room coordinates +int GetObjectIDAtRoom(int roomx, int roomy); +void SetObjectTint(int obj, int red, int green, int blue, int opacity, int luminance); +void RemoveObjectTint(int obj); +void SetObjectView(int obn,int vii); +void SetObjectFrame(int obn,int viw,int lop,int fra); +// pass trans=0 for fully solid, trans=100 for fully transparent +void SetObjectTransparency(int obn,int trans); +void SetObjectBaseline (int obn, int basel); +int GetObjectBaseline(int obn); +void AnimateObjectEx(int obn,int loopn,int spdd,int rept, int direction, int blocking); +void AnimateObject(int obn,int loopn,int spdd,int rept); +void AnimateObjectImpl(int obn, int loopn, int spdd, int rept, int direction, int blocking, int sframe); +void MergeObject(int obn); +void StopObjectMoving(int objj); +void ObjectOff(int obn); +void ObjectOn(int obn); +int IsObjectOn (int objj); +void SetObjectGraphic(int obn,int slott); +int GetObjectGraphic(int obn); +int GetObjectX (int objj); +int GetObjectY (int objj); +int IsObjectAnimating(int objj); +int IsObjectMoving(int objj); +void SetObjectPosition(int objj, int tox, int toy); +void GetObjectName(int obj, char *buffer); +void MoveObject(int objj,int xx,int yy,int spp); +void MoveObjectDirect(int objj,int xx,int yy,int spp); +void SetObjectClickable (int cha, int clik); +void SetObjectIgnoreWalkbehinds (int cha, int clik); +void RunObjectInteraction (int aa, int mood); +int AreObjectsColliding(int obj1,int obj2); +int GetThingRect(int thing, _Rect *rect); +int AreThingsOverlapping(int thing1, int thing2); + +int GetObjectProperty (int hss, const char *property); +void GetObjectPropertyText (int item, const char *property, char *bufer); + +Common::Bitmap *GetObjectImage(int obj, int *isFlipped); + +#endif // __AGS_EE_AC__GLOBALOBJECT_H diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp new file mode 100644 index 000000000000..d9525810342f --- /dev/null +++ b/engines/ags/engine/ac/global_overlay.cpp @@ -0,0 +1,94 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_overlay.h" +#include "ac/common.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_translation.h" +#include "ac/overlay.h" +#include "ac/runtime_defines.h" +#include "ac/screenoverlay.h" +#include "ac/string.h" +#include "ac/spritecache.h" +#include "ac/system.h" +#include "gfx/bitmap.h" + +using namespace Common; +using namespace Engine; + +extern SpriteCache spriteset; +extern GameSetupStruct game; + + + +void RemoveOverlay(int ovrid) { + if (find_overlay_of_type(ovrid) < 0) quit("!RemoveOverlay: invalid overlay id passed"); + remove_screen_overlay(ovrid); +} + +int CreateGraphicOverlay(int xx,int yy,int slott,int trans) { + data_to_game_coords(&xx, &yy); + + Bitmap *screeno=BitmapHelper::CreateTransparentBitmap(game.SpriteInfos[slott].Width, game.SpriteInfos[slott].Height, game.GetColorDepth()); + wputblock(screeno, 0,0,spriteset[slott],trans); + bool hasAlpha = (game.SpriteInfos[slott].Flags & SPF_ALPHACHANNEL) != 0; + int nse = add_screen_overlay(xx, yy, OVER_CUSTOM, screeno, hasAlpha); + return screenover[nse].type; +} + +int CreateTextOverlayCore(int xx, int yy, int wii, int fontid, int text_color, const char *text, int disp_type, int allowShrink) { + if (wii<8) wii=play.GetUIViewport().GetWidth()/2; + if (xx<0) xx=play.GetUIViewport().GetWidth()/2-wii/2; + if (text_color ==0) text_color =16; + return _display_main(xx,yy,wii, text, disp_type, fontid, -text_color, 0, allowShrink, false); +} + +int CreateTextOverlay(int xx, int yy, int wii, int fontid, int text_color, const char* text, int disp_type) { + int allowShrink = 0; + + if (xx != OVR_AUTOPLACE) { + data_to_game_coords(&xx,&yy); + wii = data_to_game_coord(wii); + } + else // allow DisplaySpeechBackground to be shrunk + allowShrink = 1; + + return CreateTextOverlayCore(xx, yy, wii, fontid, text_color, text, disp_type, allowShrink); +} + +void SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int text_color, const char *text) { + RemoveOverlay(ovrid); + const int disp_type = ovrid; + if (CreateTextOverlay(xx, yy, wii, fontid, text_color, text, disp_type) !=ovrid) + quit("SetTextOverlay internal error: inconsistent type ids"); +} + +void MoveOverlay(int ovrid, int newx,int newy) { + data_to_game_coords(&newx, &newy); + + int ovri=find_overlay_of_type(ovrid); + if (ovri<0) quit("!MoveOverlay: invalid overlay ID specified"); + screenover[ovri].x=newx; + screenover[ovri].y=newy; +} + +int IsOverlayValid(int ovrid) { + if (find_overlay_of_type(ovrid) < 0) + return 0; + + return 1; +} diff --git a/engines/ags/engine/ac/global_overlay.h b/engines/ags/engine/ac/global_overlay.h new file mode 100644 index 000000000000..0282bdc86858 --- /dev/null +++ b/engines/ags/engine/ac/global_overlay.h @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALOVERLAY_H +#define __AGS_EE_AC__GLOBALOVERLAY_H + +void RemoveOverlay(int ovrid); +int CreateGraphicOverlay(int xx, int yy, int slott, int trans); +int CreateTextOverlayCore(int xx, int yy, int wii, int fontid, int text_color, const char *text, int disp_type, int allowShrink); +int CreateTextOverlay(int xx, int yy, int wii, int fontid, int clr, const char* text, int disp_type); +void SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int text_color, const char *text); +void MoveOverlay(int ovrid, int newx, int newy); +int IsOverlayValid(int ovrid); + +#endif // __AGS_EE_AC__GLOBALOVERLAY_H diff --git a/engines/ags/engine/ac/global_palette.cpp b/engines/ags/engine/ac/global_palette.cpp new file mode 100644 index 000000000000..89048897657d --- /dev/null +++ b/engines/ags/engine/ac/global_palette.cpp @@ -0,0 +1,67 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_palette.h" + +extern GameSetupStruct game; +extern GameState play; +extern color palette[256]; + + +void CyclePalette(int strt,int eend) { + // hi-color game must invalidate screen since the palette changes + // the effect of the drawing operations + if (game.color_depth > 1) + invalidate_screen(); + + if ((strt < 0) || (strt > 255) || (eend < 0) || (eend > 255)) + quit("!CyclePalette: start and end must be 0-255"); + + if (eend > strt) { + // forwards + wcolrotate(strt, eend, 0, palette); + set_palette_range(palette, strt, eend, 0); + } + else { + // backwards + wcolrotate(eend, strt, 1, palette); + set_palette_range(palette, eend, strt, 0); + } + +} +void SetPalRGB(int inndx,int rr,int gg,int bb) { + if (game.color_depth > 1) + invalidate_screen(); + + wsetrgb(inndx,rr,gg,bb,palette); + set_palette_range(palette, inndx, inndx, 0); +} +/*void scSetPal(color*pptr) { +wsetpalette(0,255,pptr); +} +void scGetPal(color*pptr) { +get_palette(pptr); +}*/ + +void UpdatePalette() { + if (game.color_depth > 1) + invalidate_screen(); + + if (!play.fast_forward) + setpal(); +} diff --git a/engines/ags/engine/ac/global_palette.h b/engines/ags/engine/ac/global_palette.h new file mode 100644 index 000000000000..95b03d449d90 --- /dev/null +++ b/engines/ags/engine/ac/global_palette.h @@ -0,0 +1,25 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALPALETTE_H +#define __AGS_EE_AC__GLOBALPALETTE_H + +void CyclePalette(int strt,int eend); +void SetPalRGB(int inndx,int rr,int gg,int bb); +void UpdatePalette(); + +#endif // __AGS_EE_AC__GLOBALPALETTE_H diff --git a/engines/ags/engine/ac/global_parser.cpp b/engines/ags/engine/ac/global_parser.cpp new file mode 100644 index 000000000000..eae49baf92ff --- /dev/null +++ b/engines/ags/engine/ac/global_parser.cpp @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include //strcpy() +#include "ac/global_parser.h" +#include "ac/common.h" +#include "ac/gamestate.h" +#include "ac/string.h" + +extern GameState play; + +int SaidUnknownWord (char*buffer) { + VALIDATE_STRING(buffer); + strcpy (buffer, play.bad_parsed_word); + if (play.bad_parsed_word[0] == 0) + return 0; + return 1; +} diff --git a/engines/ags/engine/ac/global_parser.h b/engines/ags/engine/ac/global_parser.h new file mode 100644 index 000000000000..07ceebd3a6d4 --- /dev/null +++ b/engines/ags/engine/ac/global_parser.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALPARSER_H +#define __AGS_EE_AC__GLOBALPARSER_H + +int SaidUnknownWord (char*buffer); + +#endif // __AGS_EE_AC__GLOBALPARSER_H diff --git a/engines/ags/engine/ac/global_plugin.h b/engines/ags/engine/ac/global_plugin.h new file mode 100644 index 000000000000..e3e1a9c2818c --- /dev/null +++ b/engines/ags/engine/ac/global_plugin.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_PLUGIN__PLUGINFUNC_H +#define __AGS_EE_PLUGIN__PLUGINFUNC_H + +void PluginSimulateMouseClick(int pluginButtonID); +bool RegisterPluginStubs(const char* name); + +#endif // __AGS_EE_PLUGIN__PLUGINFUNC_H diff --git a/engines/ags/engine/ac/global_record.cpp b/engines/ags/engine/ac/global_record.cpp new file mode 100644 index 000000000000..afada9a47ec8 --- /dev/null +++ b/engines/ags/engine/ac/global_record.cpp @@ -0,0 +1,20 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_record.h" +#include "ac/common.h" + +void scStartRecording (int keyToStop) { + quit("!StartRecording: not supported"); +} diff --git a/engines/ags/engine/ac/global_record.h b/engines/ags/engine/ac/global_record.h new file mode 100644 index 000000000000..51c4972f56c4 --- /dev/null +++ b/engines/ags/engine/ac/global_record.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALRECORD_H +#define __AGS_EE_AC__GLOBALRECORD_H + +void scStartRecording (int keyToStop); + +#endif // __AGS_EE_AC__GLOBALRECORD_H diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp new file mode 100644 index 000000000000..6c1442131267 --- /dev/null +++ b/engines/ags/engine/ac/global_region.cpp @@ -0,0 +1,164 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_region.h" +#include "ac/common.h" +#include "ac/game_version.h" +#include "ac/region.h" +#include "ac/room.h" +#include "ac/roomstatus.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "gfx/bitmap.h" +#include "script/script.h" + + +using namespace AGS::Common; + +extern RoomStruct thisroom; +extern RoomStatus*croom; +extern const char*evblockbasename; +extern int evblocknum; + +int GetRegionIDAtRoom(int xxx, int yyy) { + // if the co-ordinates are off the edge of the screen, + // correct them to be just within + // this fixes walk-off-screen problems + xxx = room_to_mask_coord(xxx); + yyy = room_to_mask_coord(yyy); + + if (loaded_game_file_version >= kGameVersion_262) // Version 2.6.2+ + { + if (xxx >= thisroom.RegionMask->GetWidth()) + xxx = thisroom.RegionMask->GetWidth() - 1; + if (yyy >= thisroom.RegionMask->GetHeight()) + yyy = thisroom.RegionMask->GetHeight() - 1; + if (xxx < 0) + xxx = 0; + if (yyy < 0) + yyy = 0; + } + + int hsthere = thisroom.RegionMask->GetPixel (xxx, yyy); + if (hsthere <= 0 || hsthere >= MAX_ROOM_REGIONS) return 0; + if (croom->region_enabled[hsthere] == 0) return 0; + return hsthere; +} + +void SetAreaLightLevel(int area, int brightness) { + if ((area < 0) || (area > MAX_ROOM_REGIONS)) + quit("!SetAreaLightLevel: invalid region"); + if (brightness < -100) brightness = -100; + if (brightness > 100) brightness = 100; + thisroom.Regions[area].Light = brightness; + // disable RGB tint for this area + thisroom.Regions[area].Tint = 0; + debug_script_log("Region %d light level set to %d", area, brightness); +} + +void SetRegionTint (int area, int red, int green, int blue, int amount, int luminance) +{ + if ((area < 0) || (area > MAX_ROOM_REGIONS)) + quit("!SetRegionTint: invalid region"); + + if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || + (blue < 0) || (blue > 255)) { + quit("!SetRegionTint: RGB values must be 0-255"); + } + + // originally the value was passed as 0 + // TODO: find out which versions had this; fixup only for past versions in the future! + if (amount == 0) + amount = 100; + + if ((amount < 1) || (amount > 100)) + quit("!SetRegionTint: amount must be 1-100"); + if ((luminance < 0) || (luminance > 100)) + quit("!SetRegionTint: luminance must be 0-100"); + + debug_script_log("Region %d tint set to %d,%d,%d", area, red, green, blue); + + /*red -= 100; + green -= 100; + blue -= 100;*/ + + thisroom.Regions[area].Tint = (red & 0xFF) | + ((green & 0xFF) << 8) | + ((blue & 0XFF) << 16) | + ((amount & 0xFF) << 24); + thisroom.Regions[area].Light = (luminance * 25) / 10; +} + +void DisableRegion(int hsnum) { + if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS)) + quit("!DisableRegion: invalid region specified"); + + croom->region_enabled[hsnum] = 0; + debug_script_log("Region %d disabled", hsnum); +} + +void EnableRegion(int hsnum) { + if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS)) + quit("!EnableRegion: invalid region specified"); + + croom->region_enabled[hsnum] = 1; + debug_script_log("Region %d enabled", hsnum); +} + +void DisableGroundLevelAreas(int alsoEffects) { + if ((alsoEffects < 0) || (alsoEffects > 1)) + quit("!DisableGroundLevelAreas: invalid parameter: must be 0 or 1"); + + play.ground_level_areas_disabled = GLED_INTERACTION; + + if (alsoEffects) + play.ground_level_areas_disabled |= GLED_EFFECTS; + + debug_script_log("Ground-level areas disabled"); +} + +void EnableGroundLevelAreas() { + play.ground_level_areas_disabled = 0; + + debug_script_log("Ground-level areas re-enabled"); +} + +void RunRegionInteraction (int regnum, int mood) { + if ((regnum < 0) || (regnum >= MAX_ROOM_REGIONS)) + quit("!RunRegionInteraction: invalid region speicfied"); + if ((mood < 0) || (mood > 2)) + quit("!RunRegionInteraction: invalid event specified"); + + // We need a backup, because region interactions can run + // while another interaction (eg. hotspot) is in a Wait + // command, and leaving our basename would call the wrong + // script later on + const char *oldbasename = evblockbasename; + int oldblocknum = evblocknum; + + evblockbasename = "region%d"; + evblocknum = regnum; + + if (thisroom.Regions[regnum].EventHandlers != nullptr) + { + run_interaction_script(thisroom.Regions[regnum].EventHandlers.get(), mood); + } + else + { + run_interaction_event(&croom->intrRegion[regnum], mood); + } + + evblockbasename = oldbasename; + evblocknum = oldblocknum; +} diff --git a/engines/ags/engine/ac/global_region.h b/engines/ags/engine/ac/global_region.h new file mode 100644 index 000000000000..40c65e0eeb75 --- /dev/null +++ b/engines/ags/engine/ac/global_region.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALREGION_H +#define __AGS_EE_AC__GLOBALREGION_H + +// Gets region ID at the given room coordinates; +// if region is disabled or non-existing, returns 0 (no area) +int GetRegionIDAtRoom(int xxx, int yyy); +void SetAreaLightLevel(int area, int brightness); +void SetRegionTint (int area, int red, int green, int blue, int amount, int luminance = 100); +void DisableRegion(int hsnum); +void EnableRegion(int hsnum); +void DisableGroundLevelAreas(int alsoEffects); +void EnableGroundLevelAreas(); +void RunRegionInteraction (int regnum, int mood); + +#endif // __AGS_EE_AC__GLOBALREGION_H diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp new file mode 100644 index 000000000000..daccbd40bb19 --- /dev/null +++ b/engines/ags/engine/ac/global_room.cpp @@ -0,0 +1,223 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_room.h" +#include "ac/common.h" +#include "ac/character.h" +#include "ac/characterinfo.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_character.h" +#include "ac/global_game.h" +#include "ac/movelist.h" +#include "ac/properties.h" +#include "ac/room.h" +#include "ac/roomstatus.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "script/script.h" +#include "util/math.h" + +using namespace Common; + +extern GameState play; +extern GameSetupStruct game; +extern RoomStatus *croom; +extern CharacterInfo*playerchar; +extern int displayed_room; +extern int in_enters_screen; +extern int in_leaves_screen; +extern int in_inv_screen, inv_screen_newroom; +extern MoveList *mls; +extern int gs_to_newroom; +extern RoomStruct thisroom; + +void SetAmbientTint (int red, int green, int blue, int opacity, int luminance) { + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) + quit("!SetTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); + + debug_script_log("Set ambient tint RGB(%d,%d,%d) %d%%", red, green, blue, opacity); + + play.rtint_enabled = opacity > 0; + play.rtint_red = red; + play.rtint_green = green; + play.rtint_blue = blue; + play.rtint_level = opacity; + play.rtint_light = (luminance * 25) / 10; +} + +void SetAmbientLightLevel(int light_level) +{ + light_level = Math::Clamp(light_level, -100, 100); + + play.rtint_enabled = light_level != 0; + play.rtint_level = 0; + play.rtint_light = light_level; +} + +extern ScriptPosition last_in_dialog_request_script_pos; +void NewRoom(int nrnum) { + if (nrnum < 0) + quitprintf("!NewRoom: room change requested to invalid room number %d.", nrnum); + + if (displayed_room < 0) { + // called from game_start; change the room where the game will start + playerchar->room = nrnum; + return; + } + + + debug_script_log("Room change requested to room %d", nrnum); + EndSkippingUntilCharStops(); + + can_run_delayed_command(); + + if (play.stop_dialog_at_end != DIALOG_NONE) { + if (play.stop_dialog_at_end == DIALOG_RUNNING) + play.stop_dialog_at_end = DIALOG_NEWROOM + nrnum; + else { + quitprintf("!NewRoom: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", + last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); + } + return; + } + + get_script_position(last_in_dialog_request_script_pos); + + if (in_leaves_screen >= 0) { + // NewRoom called from the Player Leaves Screen event -- just + // change which room it will go to + in_leaves_screen = nrnum; + } + else if (in_enters_screen) { + setevent(EV_NEWROOM,nrnum); + return; + } + else if (in_inv_screen) { + inv_screen_newroom = nrnum; + return; + } + else if ((inside_script==0) & (in_graph_script==0)) { + new_room(nrnum,playerchar); + return; + } + else if (inside_script) { + curscript->queue_action(ePSANewRoom, nrnum, "NewRoom"); + // we might be within a MoveCharacterBlocking -- the room + // change should abort it + if ((playerchar->walking > 0) && (playerchar->walking < TURNING_AROUND)) { + // nasty hack - make sure it doesn't move the character + // to a walkable area + mls[playerchar->walking].direct = 1; + StopMoving(game.playercharacter); + } + } + else if (in_graph_script) + gs_to_newroom = nrnum; +} + + +void NewRoomEx(int nrnum,int newx,int newy) { + Character_ChangeRoom(playerchar, nrnum, newx, newy); +} + +void NewRoomNPC(int charid, int nrnum, int newx, int newy) { + if (!is_valid_character(charid)) + quit("!NewRoomNPC: invalid character"); + if (charid == game.playercharacter) + quit("!NewRoomNPC: use NewRoomEx with the player character"); + + Character_ChangeRoom(&game.chars[charid], nrnum, newx, newy); +} + +void ResetRoom(int nrnum) { + if (nrnum == displayed_room) + quit("!ResetRoom: cannot reset current room"); + if ((nrnum<0) | (nrnum>=MAX_ROOMS)) + quit("!ResetRoom: invalid room number"); + + if (isRoomStatusValid(nrnum)) + { + RoomStatus* roomstat = getRoomStatus(nrnum); + roomstat->FreeScriptData(); + roomstat->FreeProperties(); + roomstat->beenhere = 0; + } + + debug_script_log("Room %d reset to original state", nrnum); +} + +int HasPlayerBeenInRoom(int roomnum) { + if ((roomnum < 0) || (roomnum >= MAX_ROOMS)) + return 0; + if (isRoomStatusValid(roomnum)) + return getRoomStatus(roomnum)->beenhere; + else + return 0; +} + +void CallRoomScript (int value) { + can_run_delayed_command(); + + if (!inside_script) + quit("!CallRoomScript: not inside a script???"); + + play.roomscript_finished = 0; + RuntimeScriptValue rval_null; + curscript->run_another("on_call", kScInstRoom, 1, RuntimeScriptValue().SetInt32(value), rval_null); +} + +int HasBeenToRoom (int roomnum) { + if ((roomnum < 0) || (roomnum >= MAX_ROOMS)) + quit("!HasBeenToRoom: invalid room number specified"); + + if (isRoomStatusValid(roomnum)) + return getRoomStatus(roomnum)->beenhere; + else + return 0; +} + +void GetRoomPropertyText (const char *property, char *bufer) +{ + get_text_property(thisroom.Properties, croom->roomProps, property, bufer); +} + +void SetBackgroundFrame(int frnum) { + if ((frnum < -1) || (frnum != -1 && (size_t)frnum >= thisroom.BgFrameCount)) + quit("!SetBackgrondFrame: invalid frame number specified"); + if (frnum<0) { + play.bg_frame_locked=0; + return; + } + + play.bg_frame_locked = 1; + + if (frnum == play.bg_frame) + { + // already on this frame, do nothing + return; + } + + play.bg_frame = frnum; + on_background_frame_change (); +} + +int GetBackgroundFrame() { + return play.bg_frame; +} diff --git a/engines/ags/engine/ac/global_room.h b/engines/ags/engine/ac/global_room.h new file mode 100644 index 000000000000..4028423a17b3 --- /dev/null +++ b/engines/ags/engine/ac/global_room.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALROOM_H +#define __AGS_EE_AC__GLOBALROOM_H + +void SetAmbientTint (int red, int green, int blue, int opacity, int luminance); +void SetAmbientLightLevel(int light_level); +void NewRoom(int nrnum); +void NewRoomEx(int nrnum,int newx,int newy); +void NewRoomNPC(int charid, int nrnum, int newx, int newy); +void ResetRoom(int nrnum); +int HasPlayerBeenInRoom(int roomnum); +void CallRoomScript (int value); +int HasBeenToRoom (int roomnum); +void GetRoomPropertyText (const char *property, char *bufer); + +void SetBackgroundFrame(int frnum); +int GetBackgroundFrame() ; + +#endif // __AGS_EE_AC__GLOBALROOM_H diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp new file mode 100644 index 000000000000..2a77a129146a --- /dev/null +++ b/engines/ags/engine/ac/global_screen.cpp @@ -0,0 +1,180 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/gamesetup.h" +#include "ac/draw.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_game.h" +#include "ac/global_screen.h" +#include "ac/runtime_defines.h" +#include "ac/screen.h" +#include "debug/debug_log.h" +#include "platform/base/agsplatformdriver.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetup usetup; +extern GameState play; +extern GameSetupStruct game; +extern RoomStruct thisroom; +extern IGraphicsDriver *gfxDriver; +extern AGSPlatformDriver *platform; +extern color palette[256]; +extern unsigned int loopcounter; + +void FlipScreen(int amount) { + if ((amount<0) | (amount>3)) quit("!FlipScreen: invalid argument (0-3)"); + play.screen_flipped=amount; +} + +void ShakeScreen(int severe) { + EndSkippingUntilCharStops(); + + if (play.fast_forward) + return; + + severe = data_to_game_coord(severe); + + // TODO: support shaking room viewport separately + // TODO: rely on game speed setting? and/or provide frequency and duration args + // TODO: unify blocking and non-blocking shake update + + play.shakesc_length = 10; + play.shakesc_delay = 2; + play.shakesc_amount = severe; + play.mouse_cursor_hidden++; + + if (gfxDriver->RequiresFullRedrawEachFrame()) + { + for (int hh = 0; hh < 40; hh++) + { + loopcounter++; + platform->Delay(50); + + render_graphics(); + + update_polled_stuff_if_runtime(); + } + } + else + { + // Optimized variant for software render: create game scene once and shake it + construct_game_scene(); + gfxDriver->RenderToBackBuffer(); + for (int hh = 0; hh < 40; hh++) + { + platform->Delay(50); + const int yoff = hh % 2 == 0 ? 0 : severe; + play.shake_screen_yoff = yoff; + render_to_screen(); + update_polled_stuff_if_runtime(); + } + clear_letterbox_borders(); + render_to_screen(); + } + + play.mouse_cursor_hidden--; + play.shakesc_length = 0; + play.shakesc_delay = 0; + play.shakesc_amount = 0; +} + +void ShakeScreenBackground (int delay, int amount, int length) { + if (delay < 2) + quit("!ShakeScreenBackground: invalid delay parameter"); + + amount = data_to_game_coord(amount); + + if (amount < play.shakesc_amount) + { + // from a bigger to smaller shake, clear up the borders + clear_letterbox_borders(); + } + + play.shakesc_amount = amount; + play.shakesc_delay = delay; + play.shakesc_length = length; +} + +void TintScreen(int red, int grn, int blu) { + if ((red < 0) || (grn < 0) || (blu < 0) || (red > 100) || (grn > 100) || (blu > 100)) + quit("!TintScreen: RGB values must be 0-100"); + + invalidate_screen(); + + if ((red == 0) && (grn == 0) && (blu == 0)) { + play.screen_tint = -1; + return; + } + red = (red * 25) / 10; + grn = (grn * 25) / 10; + blu = (blu * 25) / 10; + play.screen_tint = red + (grn << 8) + (blu << 16); +} + +void my_fade_out(int spdd) { + EndSkippingUntilCharStops(); + + if (play.fast_forward) + return; + + if (play.screen_is_faded_out == 0) + gfxDriver->FadeOut(spdd, play.fade_to_red, play.fade_to_green, play.fade_to_blue); + + if (game.color_depth > 1) + play.screen_is_faded_out = 1; +} + +void SetScreenTransition(int newtrans) { + if ((newtrans < 0) || (newtrans > FADE_LAST)) + quit("!SetScreenTransition: invalid transition type"); + + play.fade_effect = newtrans; + + debug_script_log("Screen transition changed"); +} + +void SetNextScreenTransition(int newtrans) { + if ((newtrans < 0) || (newtrans > FADE_LAST)) + quit("!SetNextScreenTransition: invalid transition type"); + + play.next_screen_transition = newtrans; + + debug_script_log("SetNextScreenTransition engaged"); +} + +void SetFadeColor(int red, int green, int blue) { + if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || + (blue < 0) || (blue > 255)) + quit("!SetFadeColor: Red, Green and Blue must be 0-255"); + + play.fade_to_red = red; + play.fade_to_green = green; + play.fade_to_blue = blue; +} + +void FadeIn(int sppd) { + EndSkippingUntilCharStops(); + + if (play.fast_forward) + return; + + my_fade_in(palette,sppd); +} diff --git a/engines/ags/engine/ac/global_screen.h b/engines/ags/engine/ac/global_screen.h new file mode 100644 index 000000000000..7158285d8a3d --- /dev/null +++ b/engines/ags/engine/ac/global_screen.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALSCREEN_H +#define __AGS_EE_AC__GLOBALSCREEN_H + +void FlipScreen(int amount); +void ShakeScreen(int severe); +void ShakeScreenBackground (int delay, int amount, int length); +void TintScreen(int red, int grn, int blu); +void my_fade_out(int spdd); +void SetScreenTransition(int newtrans); +void SetNextScreenTransition(int newtrans); +void SetFadeColor(int red, int green, int blue); +void FadeIn(int sppd); + +#endif // __AGS_EE_AC__GLOBALSCREEN_H diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp new file mode 100644 index 000000000000..613f2a1283aa --- /dev/null +++ b/engines/ags/engine/ac/global_slider.cpp @@ -0,0 +1,42 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_slider.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/slider.h" +#include "gui/guimain.h" +#include "gui/guislider.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; + +void SetSliderValue(int guin,int objn, int valn) { + if ((guin<0) | (guin>=game.numgui)) quit("!SetSliderValue: invalid GUI number"); + if (guis[guin].GetControlType(objn)!=kGUISlider) + quit("!SetSliderValue: specified control is not a slider"); + + GUISlider*guisl=(GUISlider*)guis[guin].GetControl(objn); + Slider_SetValue(guisl, valn); +} + +int GetSliderValue(int guin,int objn) { + if ((guin<0) | (guin>=game.numgui)) quit("!GetSliderValue: invalid GUI number"); + if (guis[guin].GetControlType(objn)!=kGUISlider) + quit("!GetSliderValue: specified control is not a slider"); + + GUISlider*guisl=(GUISlider*)guis[guin].GetControl(objn); + return Slider_GetValue(guisl); +} diff --git a/engines/ags/engine/ac/global_slider.h b/engines/ags/engine/ac/global_slider.h new file mode 100644 index 000000000000..27e0edf9b34a --- /dev/null +++ b/engines/ags/engine/ac/global_slider.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALSLIDER_H +#define __AGS_EE_AC__GLOBALSLIDER_H + +void SetSliderValue(int guin,int objn, int valn); +int GetSliderValue(int guin,int objn); + +#endif // __AGS_EE_AC__GLOBALSLIDER_H diff --git a/engines/ags/engine/ac/global_string.cpp b/engines/ags/engine/ac/global_string.cpp new file mode 100644 index 000000000000..7851ae91d21c --- /dev/null +++ b/engines/ags/engine/ac/global_string.cpp @@ -0,0 +1,73 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/common.h" +#include "ac/global_string.h" +#include "ac/global_translation.h" +#include "ac/runtime_defines.h" +#include "ac/string.h" +#include "util/string_compat.h" + +extern int MAXSTRLEN; + +int StrGetCharAt (const char *strin, int posn) { + if ((posn < 0) || (posn >= (int)strlen(strin))) + return 0; + return strin[posn]; +} + +void StrSetCharAt (char *strin, int posn, int nchar) { + if ((posn < 0) || (posn > (int)strlen(strin)) || (posn >= MAX_MAXSTRLEN)) + quit("!StrSetCharAt: tried to write past end of string"); + + if (posn == (int)strlen(strin)) + strin[posn+1] = 0; + strin[posn] = nchar; +} + +void _sc_strcat(char*s1, const char*s2) { + // make sure they don't try to append a char to the string + VALIDATE_STRING (s2); + check_strlen(s1); + int mosttocopy=(MAXSTRLEN-strlen(s1))-1; + // int numbf=game.iface[4].numbuttons; + my_strncpy(&s1[strlen(s1)], s2, mosttocopy); +} + +void _sc_strlower (char *desbuf) { + VALIDATE_STRING(desbuf); + check_strlen (desbuf); + ags_strlwr (desbuf); +} + +void _sc_strupper (char *desbuf) { + VALIDATE_STRING(desbuf); + check_strlen (desbuf); + ags_strupr (desbuf); +} + +/*int _sc_strcmp (char *s1, char *s2) { +return strcmp (get_translation (s1), get_translation(s2)); +} + +int _sc_stricmp (char *s1, char *s2) { +return ags_stricmp (get_translation (s1), get_translation(s2)); +}*/ + +void _sc_strcpy(char*destt, const char *text) { + VALIDATE_STRING(destt); + check_strlen(destt); + my_strncpy(destt, text, MAXSTRLEN - 1); +} diff --git a/engines/ags/engine/ac/global_string.h b/engines/ags/engine/ac/global_string.h new file mode 100644 index 000000000000..919666619161 --- /dev/null +++ b/engines/ags/engine/ac/global_string.h @@ -0,0 +1,28 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALSTRING_H +#define __AGS_EE_AC__GLOBALSTRING_H + +int StrGetCharAt (const char *strin, int posn); +void StrSetCharAt (char *strin, int posn, int nchar); +void _sc_strcat(char*s1, const char*s2); +void _sc_strlower (char *desbuf); +void _sc_strupper (char *desbuf); +void _sc_strcpy(char*destt, const char*text); + +#endif // __AGS_EE_AC__GLOBALSTRING_H diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp new file mode 100644 index 000000000000..672c0807e2a0 --- /dev/null +++ b/engines/ags/engine/ac/global_textbox.cpp @@ -0,0 +1,57 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_textbox.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/string.h" +#include "ac/textbox.h" +#include "gui/guimain.h" +#include "gui/guitextbox.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; + +void SetTextBoxFont(int guin,int objn, int fontnum) { + + if ((guin<0) | (guin>=game.numgui)) quit("!SetTextBoxFont: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetTextBoxFont: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUITextBox) + quit("!SetTextBoxFont: specified control is not a text box"); + + GUITextBox *guit = (GUITextBox*)guis[guin].GetControl(objn); + TextBox_SetFont(guit, fontnum); +} + +void GetTextBoxText(int guin, int objn, char*txbuf) { + VALIDATE_STRING(txbuf); + if ((guin<0) | (guin>=game.numgui)) quit("!GetTextBoxText: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!GetTextBoxText: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUITextBox) + quit("!GetTextBoxText: specified control is not a text box"); + + GUITextBox*guisl=(GUITextBox*)guis[guin].GetControl(objn); + TextBox_GetText(guisl, txbuf); +} + +void SetTextBoxText(int guin, int objn, const char* txbuf) { + if ((guin<0) | (guin>=game.numgui)) quit("!SetTextBoxText: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetTextBoxText: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUITextBox) + quit("!SetTextBoxText: specified control is not a text box"); + + GUITextBox*guisl=(GUITextBox*)guis[guin].GetControl(objn); + TextBox_SetText(guisl, txbuf); +} diff --git a/engines/ags/engine/ac/global_textbox.h b/engines/ags/engine/ac/global_textbox.h new file mode 100644 index 000000000000..1962f4f30c22 --- /dev/null +++ b/engines/ags/engine/ac/global_textbox.h @@ -0,0 +1,25 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALTEXTBOX_H +#define __AGS_EE_AC__GLOBALTEXTBOX_H + +void SetTextBoxFont(int guin,int objn, int fontnum); +void GetTextBoxText(int guin, int objn, char*txbuf); +void SetTextBoxText(int guin, int objn, const char*txbuf); + +#endif // __AGS_EE_AC__GLOBALTEXTBOX_H diff --git a/engines/ags/engine/ac/global_timer.cpp b/engines/ags/engine/ac/global_timer.cpp new file mode 100644 index 000000000000..4f197d889a77 --- /dev/null +++ b/engines/ags/engine/ac/global_timer.cpp @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_timer.h" +#include "ac/runtime_defines.h" +#include "ac/common.h" +#include "ac/gamestate.h" + +extern GameState play; + + +void script_SetTimer(int tnum,int timeout) { + if ((tnum < 1) || (tnum >= MAX_TIMERS)) + quit("!StartTimer: invalid timer number"); + play.script_timers[tnum] = timeout; +} + +int IsTimerExpired(int tnum) { + if ((tnum < 1) || (tnum >= MAX_TIMERS)) + quit("!IsTimerExpired: invalid timer number"); + if (play.script_timers[tnum] == 1) { + play.script_timers[tnum] = 0; + return 1; + } + return 0; +} diff --git a/engines/ags/engine/ac/global_timer.h b/engines/ags/engine/ac/global_timer.h new file mode 100644 index 000000000000..589a97ee8d5f --- /dev/null +++ b/engines/ags/engine/ac/global_timer.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALTIMER_H +#define __AGS_EE_AC__GLOBALTIMER_H + +void script_SetTimer(int tnum,int timeout); +int IsTimerExpired(int tnum); + +#endif // __AGS_EE_AC__GLOBALTIMER_H diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp new file mode 100644 index 000000000000..f793e111943f --- /dev/null +++ b/engines/ags/engine/ac/global_translation.cpp @@ -0,0 +1,85 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/common.h" +#include "ac/display.h" +#include "ac/gamestate.h" +#include "ac/global_translation.h" +#include "ac/string.h" +#include "ac/tree_map.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "util/memory.h" +#include "core/types.h" + +using namespace AGS::Common::Memory; + +extern GameState play; +extern AGSPlatformDriver *platform; +extern TreeMap *transtree; +extern char transFileName[MAX_PATH]; + +const char *get_translation (const char *text) { + if (text == nullptr) + quit("!Null string supplied to CheckForTranslations"); + + source_text_length = GetTextDisplayLength(text); + +#if AGS_PLATFORM_64BIT + // check if a plugin wants to translate it - if so, return that + // TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems + char *plResult = Int32ToPtr(pl_run_plugin_hooks(AGSE_TRANSLATETEXT, PtrToInt32(text))); + if (plResult) { + return plResult; + } +#endif + + if (transtree != nullptr) { + // translate the text using the translation file + char * transl = transtree->findValue (text); + if (transl != nullptr) + return transl; + } + // return the original text + return text; +} + +int IsTranslationAvailable () { + if (transtree != nullptr) + return 1; + return 0; +} + +int GetTranslationName (char* buffer) { + VALIDATE_STRING (buffer); + const char *copyFrom = transFileName; + + while (strchr(copyFrom, '\\') != nullptr) + { + copyFrom = strchr(copyFrom, '\\') + 1; + } + while (strchr(copyFrom, '/') != nullptr) + { + copyFrom = strchr(copyFrom, '/') + 1; + } + + strcpy (buffer, copyFrom); + // remove the ".tra" from the end of the filename + if (strstr (buffer, ".tra") != nullptr) + strstr (buffer, ".tra")[0] = 0; + + return IsTranslationAvailable(); +} diff --git a/engines/ags/engine/ac/global_translation.h b/engines/ags/engine/ac/global_translation.h new file mode 100644 index 000000000000..b506fd9498a4 --- /dev/null +++ b/engines/ags/engine/ac/global_translation.h @@ -0,0 +1,25 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALTRANSLATION_H +#define __AGS_EE_AC__GLOBALTRANSLATION_H + +const char *get_translation (const char *text); +int IsTranslationAvailable (); +int GetTranslationName (char* buffer); + +#endif // __AGS_EE_AC__GLOBALTRANSLATION_H diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp new file mode 100644 index 000000000000..438fcc833711 --- /dev/null +++ b/engines/ags/engine/ac/global_video.cpp @@ -0,0 +1,85 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/gamesetup.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/global_game.h" +#include "ac/global_video.h" +#include "ac/path_helper.h" +#include "debug/debugger.h" +#include "media/video/video.h" +#include "media/audio/audio_system.h" +#include "platform/base/agsplatformdriver.h" +#include "util/string_compat.h" + + +void scrPlayVideo(const char* name, int skip, int flags) { + EndSkippingUntilCharStops(); + + if (play.fast_forward) + return; + if (debug_flags & DBG_NOVIDEO) + return; + + if ((flags < 10) && (usetup.digicard == DIGI_NONE)) { + // if game audio is disabled in Setup, then don't + // play any sound on the video either + flags += 10; + } + + pause_sound_if_necessary_and_play_video(name, skip, flags); +} + + +#ifndef AGS_NO_VIDEO_PLAYER + +void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags) +{ + int musplaying = play.cur_music_number, i; + int ambientWas[MAX_SOUND_CHANNELS]; + for (i = 1; i < MAX_SOUND_CHANNELS; i++) + ambientWas[i] = ambient[i].channel; + + if ((strlen(name) > 3) && (ags_stricmp(&name[strlen(name) - 3], "ogv") == 0)) + { + play_theora_video(name, skip, flags); + } + else + { + char videoFilePath[MAX_PATH]; + get_install_dir_path(videoFilePath, name); + + platform->PlayVideo(videoFilePath, skip, flags); + } + + if (flags < 10) + { + update_music_volume(); + // restart the music + if (musplaying >= 0) + newmusic (musplaying); + for (i = 1; i < MAX_SOUND_CHANNELS; i++) { + if (ambientWas[i] > 0) + PlayAmbientSound(ambientWas[i], ambient[i].num, ambient[i].vol, ambient[i].x, ambient[i].y); + } + } +} + +#else + +void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags) {} + +#endif \ No newline at end of file diff --git a/engines/ags/engine/ac/global_video.h b/engines/ags/engine/ac/global_video.h new file mode 100644 index 000000000000..c3fa993847bd --- /dev/null +++ b/engines/ags/engine/ac/global_video.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALVIDEO_H +#define __AGS_EE_AC__GLOBALVIDEO_H + +void scrPlayVideo(const char* name, int skip, int flags); +void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags); + +#endif // __AGS_EE_AC__GLOBALVIDEO_H diff --git a/engines/ags/engine/ac/global_viewframe.cpp b/engines/ags/engine/ac/global_viewframe.cpp new file mode 100644 index 000000000000..81d55ca1b013 --- /dev/null +++ b/engines/ags/engine/ac/global_viewframe.cpp @@ -0,0 +1,49 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_viewframe.h" +#include "ac/common.h" +#include "ac/view.h" +#include "ac/gamesetupstruct.h" +#include "debug/debug_log.h" +#include "media/audio/audio_system.h" + +extern GameSetupStruct game; +extern ViewStruct*views; + + +void SetFrameSound (int vii, int loop, int frame, int sound) { + if ((vii < 1) || (vii > game.numviews)) + quit("!SetFrameSound: invalid view number"); + vii--; + + if (loop >= views[vii].numLoops) + quit("!SetFrameSound: invalid loop number"); + + if (frame >= views[vii].loops[loop].numFrames) + quit("!SetFrameSound: invalid frame number"); + + if (sound < 1) + { + views[vii].loops[loop].frames[frame].sound = -1; + } + else + { + ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, sound); + if (clip == nullptr) + quitprintf("!SetFrameSound: audio clip aSound%d not found", sound); + + views[vii].loops[loop].frames[frame].sound = clip->id + (game.IsLegacyAudioSystem() ? 0x10000000 : 0); + } +} diff --git a/engines/ags/engine/ac/global_viewframe.h b/engines/ags/engine/ac/global_viewframe.h new file mode 100644 index 000000000000..b92c3400b706 --- /dev/null +++ b/engines/ags/engine/ac/global_viewframe.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALVIEWFRAME_H +#define __AGS_EE_AC__GLOBALVIEWFRAME_H + +void SetFrameSound (int vii, int loop, int frame, int sound); + +#endif // __AGS_EE_AC__GLOBALVIEWFRAME_H diff --git a/engines/ags/engine/ac/global_viewport.cpp b/engines/ags/engine/ac/global_viewport.cpp new file mode 100644 index 000000000000..ea2b1dd8a2ef --- /dev/null +++ b/engines/ags/engine/ac/global_viewport.cpp @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_viewport.h" +#include "ac/draw.h" +#include "debug/debug_log.h" + +void SetViewport(int offsx, int offsy) { + offsx = data_to_game_coord(offsx); + offsy = data_to_game_coord(offsy); + play.GetRoomCamera(0)->LockAt(offsx, offsy); +} +void ReleaseViewport() { + play.GetRoomCamera(0)->Release(); +} +int GetViewportX () { + return game_to_data_coord(play.GetRoomCamera(0)->GetRect().Left); +} +int GetViewportY () { + return game_to_data_coord(play.GetRoomCamera(0)->GetRect().Top); +} diff --git a/engines/ags/engine/ac/global_viewport.h b/engines/ags/engine/ac/global_viewport.h new file mode 100644 index 000000000000..5c3903cb5e06 --- /dev/null +++ b/engines/ags/engine/ac/global_viewport.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALVIEWPORT_H +#define __AGS_EE_AC__GLOBALVIEWPORT_H + +void SetViewport(int offsx,int offsy); +void ReleaseViewport(); +int GetViewportX (); +int GetViewportY (); + +#endif // __AGS_EE_AC__GLOBAL_VIEWPORT_H diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp new file mode 100644 index 000000000000..219333f3dddb --- /dev/null +++ b/engines/ags/engine/ac/global_walkablearea.cpp @@ -0,0 +1,91 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_walkablearea.h" +#include "ac/common.h" +#include "ac/common_defines.h" +#include "ac/draw.h" +#include "ac/walkablearea.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" + +using namespace AGS::Common; + +extern RoomStruct thisroom; + + +int GetScalingAt (int x, int y) { + int onarea = get_walkable_area_pixel(x, y); + if (onarea < 0) + return 100; + + return get_area_scaling (onarea, x, y); +} + +void SetAreaScaling(int area, int min, int max) { + if ((area < 0) || (area > MAX_WALK_AREAS)) + quit("!SetAreaScaling: invalid walkalbe area"); + + if (min > max) + quit("!SetAreaScaling: min > max"); + + if ((min < 5) || (max < 5) || (min > 200) || (max > 200)) + quit("!SetAreaScaling: min and max must be in range 5-200"); + + // the values are stored differently + min -= 100; + max -= 100; + + if (min == max) { + thisroom.WalkAreas[area].ScalingFar = min; + thisroom.WalkAreas[area].ScalingNear = NOT_VECTOR_SCALED; + } + else { + thisroom.WalkAreas[area].ScalingFar = min; + thisroom.WalkAreas[area].ScalingNear = max; + } +} + +void RemoveWalkableArea(int areanum) { + if ((areanum<1) | (areanum>15)) + quit("!RemoveWalkableArea: invalid area number specified (1-15)."); + play.walkable_areas_on[areanum]=0; + redo_walkable_areas(); + debug_script_log("Walkable area %d removed", areanum); +} + +void RestoreWalkableArea(int areanum) { + if ((areanum<1) | (areanum>15)) + quit("!RestoreWalkableArea: invalid area number specified (1-15)."); + play.walkable_areas_on[areanum]=1; + redo_walkable_areas(); + debug_script_log("Walkable area %d restored", areanum); +} + +int GetWalkableAreaAtScreen(int x, int y) { + VpPoint vpt = play.ScreenToRoomDivDown(x, y); + if (vpt.second < 0) + return 0; + return GetWalkableAreaAtRoom(vpt.first.X, vpt.first.Y); +} + +int GetWalkableAreaAtRoom(int x, int y) { + int area = get_walkable_area_pixel(x, y); + // IMPORTANT: disabled walkable areas are actually erased completely from the mask; + // see: RemoveWalkableArea() and RestoreWalkableArea(). + return area >= 0 && area < (MAX_WALK_AREAS + 1) ? area : 0; +} + +//============================================================================= + diff --git a/engines/ags/engine/ac/global_walkablearea.h b/engines/ags/engine/ac/global_walkablearea.h new file mode 100644 index 000000000000..87f6ab811d8f --- /dev/null +++ b/engines/ags/engine/ac/global_walkablearea.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALWALKABLEAREA_H +#define __AGS_EE_AC__GLOBALWALKABLEAREA_H + +int GetScalingAt (int x, int y); +void SetAreaScaling(int area, int min, int max); +void RemoveWalkableArea(int areanum); +void RestoreWalkableArea(int areanum); +// Gets walkable area at the given room coordinates; +// if area is disabled or non-existing, returns 0 (no area) +int GetWalkableAreaAtRoom(int x, int y); +// Gets walkable area at the given screen coordinates +// if area is disabled or non-existing, returns 0 (no area) +int GetWalkableAreaAtScreen(int x, int y); + +#endif // __AGS_EE_AC__GLOBALWALKABLEAREA_H diff --git a/engines/ags/engine/ac/global_walkbehind.cpp b/engines/ags/engine/ac/global_walkbehind.cpp new file mode 100644 index 000000000000..4e0181a475a5 --- /dev/null +++ b/engines/ags/engine/ac/global_walkbehind.cpp @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/global_walkbehind.h" +#include "ac/common.h" +#include "ac/common_defines.h" +#include "ac/draw.h" +#include "ac/roomstatus.h" +#include "ac/walkbehind.h" +#include "debug/debug_log.h" + +extern RoomStatus*croom; +extern int walk_behind_baselines_changed; + +void SetWalkBehindBase(int wa,int bl) { + if ((wa < 1) || (wa >= MAX_WALK_BEHINDS)) + quit("!SetWalkBehindBase: invalid walk-behind area specified"); + + if (bl != croom->walkbehind_base[wa]) { + walk_behind_baselines_changed = 1; + invalidate_cached_walkbehinds(); + croom->walkbehind_base[wa] = bl; + debug_script_log("Walk-behind %d baseline changed to %d", wa, bl); + } +} diff --git a/engines/ags/engine/ac/global_walkbehind.h b/engines/ags/engine/ac/global_walkbehind.h new file mode 100644 index 000000000000..acf56b9472fa --- /dev/null +++ b/engines/ags/engine/ac/global_walkbehind.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GLOBALWALKBEHIND_H +#define __AGS_EE_AC__GLOBALWALKBEHIND_H + +void SetWalkBehindBase(int wa,int bl); + +#endif // __AGS_EE_AC__GLOBALWALKBEHIND_H diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp new file mode 100644 index 000000000000..330674102d1d --- /dev/null +++ b/engines/ags/engine/ac/gui.cpp @@ -0,0 +1,1001 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/gui.h" +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_character.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/global_inventoryitem.h" +#include "ac/global_screen.h" +#include "ac/guicontrol.h" +#include "ac/interfacebutton.h" +#include "ac/invwindow.h" +#include "ac/mouse.h" +#include "ac/runtime_defines.h" +#include "ac/system.h" +#include "ac/dynobj/cc_guiobject.h" +#include "ac/dynobj/scriptgui.h" +#include "script/cc_instance.h" +#include "debug/debug_log.h" +#include "device/mousew32.h" +#include "gfx/gfxfilter.h" +#include "gui/guibutton.h" +#include "gui/guimain.h" +#include "script/script.h" +#include "script/script_runtime.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" +#include "ac/dynobj/cc_gui.h" +#include "ac/dynobj/cc_guiobject.h" +#include "script/runtimescriptvalue.h" +#include "util/string_compat.h" + + +using namespace AGS::Common; +using namespace AGS::Engine; + + +extern GameSetup usetup; +extern RoomStruct thisroom; +extern int cur_mode,cur_cursor; +extern ccInstance *gameinst; +extern ScriptGUI *scrGui; +extern GameSetupStruct game; +extern CCGUIObject ccDynamicGUIObject; +extern Bitmap **guibg; +extern IDriverDependantBitmap **guibgbmp; +extern IGraphicsDriver *gfxDriver; + +extern CCGUI ccDynamicGUI; +extern CCGUIObject ccDynamicGUIObject; + + +int ifacepopped=-1; // currently displayed pop-up GUI (-1 if none) +int mouse_on_iface=-1; // mouse cursor is over this interface +int mouse_ifacebut_xoffs=-1,mouse_ifacebut_yoffs=-1; + +int eip_guinum, eip_guiobj; + + +ScriptGUI* GUI_AsTextWindow(ScriptGUI *tehgui) +{ // Internally both GUI and TextWindow are implemented by same class + return guis[tehgui->id].IsTextWindow() ? &scrGui[tehgui->id] : nullptr; +} + +int GUI_GetPopupStyle(ScriptGUI *tehgui) +{ + return guis[tehgui->id].PopupStyle; +} + +void GUI_SetVisible(ScriptGUI *tehgui, int isvisible) { + if (isvisible) + InterfaceOn(tehgui->id); + else + InterfaceOff(tehgui->id); +} + +int GUI_GetVisible(ScriptGUI *tehgui) { + // GUI_GetVisible is slightly different from IsGUIOn, because + // with a mouse ypos gui it returns 1 if the GUI is enabled, + // whereas IsGUIOn actually checks if it is displayed + return guis[tehgui->id].IsVisible() ? 1 : 0; +} + +int GUI_GetX(ScriptGUI *tehgui) { + return game_to_data_coord(guis[tehgui->id].X); +} + +void GUI_SetX(ScriptGUI *tehgui, int xx) { + guis[tehgui->id].X = data_to_game_coord(xx); +} + +int GUI_GetY(ScriptGUI *tehgui) { + return game_to_data_coord(guis[tehgui->id].Y); +} + +void GUI_SetY(ScriptGUI *tehgui, int yy) { + guis[tehgui->id].Y = data_to_game_coord(yy); +} + +void GUI_SetPosition(ScriptGUI *tehgui, int xx, int yy) { + GUI_SetX(tehgui, xx); + GUI_SetY(tehgui, yy); +} + +void GUI_SetSize(ScriptGUI *sgui, int widd, int hitt) { + if ((widd < 1) || (hitt < 1)) + quitprintf("!SetGUISize: invalid dimensions (tried to set to %d x %d)", widd, hitt); + + GUIMain *tehgui = &guis[sgui->id]; + data_to_game_coords(&widd, &hitt); + + if ((tehgui->Width == widd) && (tehgui->Height == hitt)) + return; + + tehgui->Width = widd; + tehgui->Height = hitt; + + recreate_guibg_image(tehgui); + + guis_need_update = 1; +} + +int GUI_GetWidth(ScriptGUI *sgui) { + return game_to_data_coord(guis[sgui->id].Width); +} + +int GUI_GetHeight(ScriptGUI *sgui) { + return game_to_data_coord(guis[sgui->id].Height); +} + +void GUI_SetWidth(ScriptGUI *sgui, int newwid) { + GUI_SetSize(sgui, newwid, GUI_GetHeight(sgui)); +} + +void GUI_SetHeight(ScriptGUI *sgui, int newhit) { + GUI_SetSize(sgui, GUI_GetWidth(sgui), newhit); +} + +void GUI_SetZOrder(ScriptGUI *tehgui, int z) { + guis[tehgui->id].ZOrder = z; + update_gui_zorder(); +} + +int GUI_GetZOrder(ScriptGUI *tehgui) { + return guis[tehgui->id].ZOrder; +} + +void GUI_SetClickable(ScriptGUI *tehgui, int clickable) { + guis[tehgui->id].SetClickable(clickable != 0); +} + +int GUI_GetClickable(ScriptGUI *tehgui) { + return guis[tehgui->id].IsClickable() ? 1 : 0; +} + +int GUI_GetID(ScriptGUI *tehgui) { + return tehgui->id; +} + +GUIObject* GUI_GetiControls(ScriptGUI *tehgui, int idx) { + if ((idx < 0) || (idx >= guis[tehgui->id].GetControlCount())) + return nullptr; + return guis[tehgui->id].GetControl(idx); +} + +int GUI_GetControlCount(ScriptGUI *tehgui) { + return guis[tehgui->id].GetControlCount(); +} + +int GUI_GetPopupYPos(ScriptGUI *tehgui) +{ + return guis[tehgui->id].PopupAtMouseY; +} + +void GUI_SetPopupYPos(ScriptGUI *tehgui, int newpos) +{ + if (!guis[tehgui->id].IsTextWindow()) + guis[tehgui->id].PopupAtMouseY = newpos; +} + +void GUI_SetTransparency(ScriptGUI *tehgui, int trans) { + if ((trans < 0) | (trans > 100)) + quit("!SetGUITransparency: transparency value must be between 0 and 100"); + + guis[tehgui->id].SetTransparencyAsPercentage(trans); +} + +int GUI_GetTransparency(ScriptGUI *tehgui) { + if (guis[tehgui->id].Transparency == 0) + return 0; + if (guis[tehgui->id].Transparency == 255) + return 100; + + return 100 - ((guis[tehgui->id].Transparency * 10) / 25); +} + +void GUI_Centre(ScriptGUI *sgui) { + GUIMain *tehgui = &guis[sgui->id]; + tehgui->X = play.GetUIViewport().GetWidth() / 2 - tehgui->Width / 2; + tehgui->Y = play.GetUIViewport().GetHeight() / 2 - tehgui->Height / 2; +} + +void GUI_SetBackgroundGraphic(ScriptGUI *tehgui, int slotn) { + if (guis[tehgui->id].BgImage != slotn) { + guis[tehgui->id].BgImage = slotn; + guis_need_update = 1; + } +} + +int GUI_GetBackgroundGraphic(ScriptGUI *tehgui) { + if (guis[tehgui->id].BgImage < 1) + return 0; + return guis[tehgui->id].BgImage; +} + +void GUI_SetBackgroundColor(ScriptGUI *tehgui, int newcol) +{ + if (guis[tehgui->id].BgColor != newcol) + { + guis[tehgui->id].BgColor = newcol; + guis_need_update = 1; + } +} + +int GUI_GetBackgroundColor(ScriptGUI *tehgui) +{ + return guis[tehgui->id].BgColor; +} + +void GUI_SetBorderColor(ScriptGUI *tehgui, int newcol) +{ + if (guis[tehgui->id].IsTextWindow()) + return; + if (guis[tehgui->id].FgColor != newcol) + { + guis[tehgui->id].FgColor = newcol; + guis_need_update = 1; + } +} + +int GUI_GetBorderColor(ScriptGUI *tehgui) +{ + if (guis[tehgui->id].IsTextWindow()) + return 0; + return guis[tehgui->id].FgColor; +} + +void GUI_SetTextColor(ScriptGUI *tehgui, int newcol) +{ + if (!guis[tehgui->id].IsTextWindow()) + return; + if (guis[tehgui->id].FgColor != newcol) + { + guis[tehgui->id].FgColor = newcol; + guis_need_update = 1; + } +} + +int GUI_GetTextColor(ScriptGUI *tehgui) +{ + if (!guis[tehgui->id].IsTextWindow()) + return 0; + return guis[tehgui->id].FgColor; +} + +int GUI_GetTextPadding(ScriptGUI *tehgui) +{ + return guis[tehgui->id].Padding; +} + +void GUI_SetTextPadding(ScriptGUI *tehgui, int newpos) +{ + if (guis[tehgui->id].IsTextWindow()) + guis[tehgui->id].Padding = newpos; +} + +ScriptGUI *GetGUIAtLocation(int xx, int yy) { + int guiid = GetGUIAt(xx, yy); + if (guiid < 0) + return nullptr; + return &scrGui[guiid]; +} + +void GUI_Click(ScriptGUI *scgui, int mbut) +{ + process_interface_click(scgui->id, -1, mbut); +} + +void GUI_ProcessClick(int x, int y, int mbut) +{ + int guiid = gui_get_interactable(x, y); + if (guiid >= 0) + { + const int real_mousex = mousex; + const int real_mousey = mousey; + mousex = x; + mousey = y; + guis[guiid].Poll(); + gui_on_mouse_down(guiid, mbut); + gui_on_mouse_up(guiid, mbut); + mousex = real_mousex; + mousey = real_mousey; + } +} + +//============================================================================= + +void remove_popup_interface(int ifacenum) { + if (ifacepopped != ifacenum) return; + ifacepopped=-1; UnPauseGame(); + guis[ifacenum].SetConceal(true); + if (mousey<=guis[ifacenum].PopupAtMouseY) + Mouse::SetPosition(Point(mousex, guis[ifacenum].PopupAtMouseY+2)); + if ((!IsInterfaceEnabled()) && (cur_cursor == cur_mode)) + // Only change the mouse cursor if it hasn't been specifically changed first + set_mouse_cursor(CURS_WAIT); + else if (IsInterfaceEnabled()) + set_default_cursor(); + + if (ifacenum==mouse_on_iface) mouse_on_iface=-1; + guis_need_update = 1; +} + +void process_interface_click(int ifce, int btn, int mbut) { + if (btn < 0) { + // click on GUI background + QueueScriptFunction(kScInstGame, guis[ifce].OnClickHandler, 2, + RuntimeScriptValue().SetDynamicObject(&scrGui[ifce], &ccDynamicGUI), + RuntimeScriptValue().SetInt32(mbut)); + return; + } + + int btype = guis[ifce].GetControlType(btn); + int rtype=kGUIAction_None,rdata; + if (btype==kGUIButton) { + GUIButton*gbuto=(GUIButton*)guis[ifce].GetControl(btn); + rtype=gbuto->ClickAction[kMouseLeft]; + rdata=gbuto->ClickData[kMouseLeft]; + } + else if ((btype==kGUISlider) || (btype == kGUITextBox) || (btype == kGUIListBox)) + rtype = kGUIAction_RunScript; + else quit("unknown GUI object triggered process_interface"); + + if (rtype==kGUIAction_None) ; + else if (rtype==kGUIAction_SetMode) + set_cursor_mode(rdata); + else if (rtype==kGUIAction_RunScript) { + GUIObject *theObj = guis[ifce].GetControl(btn); + // if the object has a special handler script then run it; + // otherwise, run interface_click + if ((theObj->GetEventCount() > 0) && + (!theObj->EventHandlers[0].IsEmpty()) && + (!gameinst->GetSymbolAddress(theObj->EventHandlers[0]).IsNull())) { + // control-specific event handler + if (strchr(theObj->GetEventArgs(0), ',') != nullptr) + QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 2, + RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject), + RuntimeScriptValue().SetInt32(mbut)); + else + QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 1, + RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject)); + } + else + QueueScriptFunction(kScInstGame, "interface_click", 2, + RuntimeScriptValue().SetInt32(ifce), + RuntimeScriptValue().SetInt32(btn)); + } +} + + +void replace_macro_tokens(const char *text, String &fixed_text) { + const char*curptr=&text[0]; + char tmpm[3]; + const char*endat = curptr + strlen(text); + fixed_text.Empty(); + char tempo[STD_BUFFER_SIZE]; + + while (1) { + if (curptr[0]==0) break; + if (curptr>=endat) break; + if (curptr[0]=='@') { + const char *curptrWasAt = curptr; + char macroname[21]; int idd=0; curptr++; + for (idd=0;idd<20;idd++) { + if (curptr[0]=='@') { + macroname[idd]=0; + curptr++; + break; + } + // unterminated macro (eg. "@SCORETEXT"), so abort + if (curptr[0] == 0) + break; + macroname[idd]=curptr[0]; + curptr++; + } + macroname[idd]=0; + tempo[0]=0; + if (ags_stricmp(macroname,"score")==0) + sprintf(tempo,"%d",play.score); + else if (ags_stricmp(macroname,"totalscore")==0) + sprintf(tempo,"%d",MAXSCORE); + else if (ags_stricmp(macroname,"scoretext")==0) + sprintf(tempo,"%d of %d",play.score,MAXSCORE); + else if (ags_stricmp(macroname,"gamename")==0) + strcpy(tempo, play.game_name); + else if (ags_stricmp(macroname,"overhotspot")==0) { + // While game is in Wait mode, no overhotspot text + if (!IsInterfaceEnabled()) + tempo[0] = 0; + else + GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + } + else { // not a macro, there's just a @ in the message + curptr = curptrWasAt + 1; + strcpy(tempo, "@"); + } + + fixed_text.Append(tempo); + } + else { + tmpm[0]=curptr[0]; tmpm[1]=0; + fixed_text.Append(tmpm); + curptr++; + } + } +} + + +void update_gui_zorder() { + int numdone = 0, b; + + // for each GUI + for (int a = 0; a < game.numgui; a++) { + // find the right place in the draw order array + int insertAt = numdone; + for (b = 0; b < numdone; b++) { + if (guis[a].ZOrder < guis[play.gui_draw_order[b]].ZOrder) { + insertAt = b; + break; + } + } + // insert the new item + for (b = numdone - 1; b >= insertAt; b--) + play.gui_draw_order[b + 1] = play.gui_draw_order[b]; + play.gui_draw_order[insertAt] = a; + numdone++; + } + +} + + +void export_gui_controls(int ee) +{ + for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) + { + GUIObject *guio = guis[ee].GetControl(ff); + if (!guio->Name.IsEmpty()) + ccAddExternalDynamicObject(guio->Name, guio, &ccDynamicGUIObject); + ccRegisterManagedObject(guio, &ccDynamicGUIObject); + } +} + +void unexport_gui_controls(int ee) +{ + for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) + { + GUIObject *guio = guis[ee].GetControl(ff); + if (!guio->Name.IsEmpty()) + ccRemoveExternalSymbol(guio->Name); + if (!ccUnRegisterManagedObject(guio)) + quit("unable to unregister guicontrol object"); + } +} + +int convert_gui_disabled_style(int oldStyle) { + int toret = GUIDIS_GREYOUT; + + // if GUIs Turn Off is selected, don't grey out buttons for + // any Persistent GUIs which remain + // set to 0x80 so that it is still non-zero, but has no effect + if (oldStyle == 3) + toret = GUIDIS_GUIOFF; + // GUIs Go Black + else if (oldStyle == 1) + toret = GUIDIS_BLACKOUT; + // GUIs unchanged + else if (oldStyle == 2) + toret = GUIDIS_UNCHANGED; + + return toret; +} + +void update_gui_disabled_status() { + // update GUI display status (perhaps we've gone into + // an interface disabled state) + int all_buttons_was = all_buttons_disabled; + all_buttons_disabled = 0; + + if (!IsInterfaceEnabled()) { + all_buttons_disabled = gui_disabled_style; + } + + if (all_buttons_was != all_buttons_disabled) { + // GUIs might have been removed/added + for (int aa = 0; aa < game.numgui; aa++) { + guis[aa].OnControlPositionChanged(); + } + guis_need_update = 1; + invalidate_screen(); + } +} + + +int adjust_x_for_guis (int xx, int yy) { + if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) + return xx; + // If it's covered by a GUI, move it right a bit + for (int aa=0;aa < game.numgui; aa++) { + if (!guis[aa].IsDisplayed()) + continue; + if ((guis[aa].X > xx) || (guis[aa].Y > yy) || (guis[aa].Y + guis[aa].Height < yy)) + continue; + // totally transparent GUI, ignore + if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1)) + continue; + + // try to deal with full-width GUIs across the top + if (guis[aa].X + guis[aa].Width >= get_fixed_pixel_size(280)) + continue; + + if (xx < guis[aa].X + guis[aa].Width) + xx = guis[aa].X + guis[aa].Width + 2; + } + return xx; +} + +int adjust_y_for_guis ( int yy) { + if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) + return yy; + // If it's covered by a GUI, move it down a bit + for (int aa=0;aa < game.numgui; aa++) { + if (!guis[aa].IsDisplayed()) + continue; + if (guis[aa].Y > yy) + continue; + // totally transparent GUI, ignore + if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1)) + continue; + + // try to deal with full-height GUIs down the left or right + if (guis[aa].Height > get_fixed_pixel_size(50)) + continue; + + if (yy < guis[aa].Y + guis[aa].Height) + yy = guis[aa].Y + guis[aa].Height + 2; + } + return yy; +} + +void recreate_guibg_image(GUIMain *tehgui) +{ + int ifn = tehgui->ID; + delete guibg[ifn]; + guibg[ifn] = BitmapHelper::CreateBitmap(tehgui->Width, tehgui->Height, game.GetColorDepth()); + if (guibg[ifn] == nullptr) + quit("SetGUISize: internal error: unable to reallocate gui cache"); + guibg[ifn] = ReplaceBitmapWithSupportedFormat(guibg[ifn]); + + if (guibgbmp[ifn] != nullptr) + { + gfxDriver->DestroyDDB(guibgbmp[ifn]); + guibgbmp[ifn] = nullptr; + } +} + +extern int is_complete_overlay; + +int gui_get_interactable(int x,int y) +{ + if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) + return -1; + return GetGUIAt(x, y); +} + +int gui_on_mouse_move() +{ + int mouse_over_gui = -1; + // If all GUIs are off, skip the loop + if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) ; + else { + // Scan for mouse-y-pos GUIs, and pop one up if appropriate + // Also work out the mouse-over GUI while we're at it + int ll; + for (ll = 0; ll < game.numgui;ll++) { + const int guin = play.gui_draw_order[ll]; + if (guis[guin].IsInteractableAt(mousex, mousey)) mouse_over_gui=guin; + + if (guis[guin].PopupStyle!=kGUIPopupMouseY) continue; + if (is_complete_overlay>0) break; // interfaces disabled + // if (play.disabled_user_interface>0) break; + if (ifacepopped==guin) continue; + if (!guis[guin].IsVisible()) continue; + // Don't allow it to be popped up while skipping cutscene + if (play.fast_forward) continue; + + if (mousey < guis[guin].PopupAtMouseY) { + set_mouse_cursor(CURS_ARROW); + guis[guin].SetConceal(false); guis_need_update = 1; + ifacepopped=guin; PauseGame(); + break; + } + } + } + return mouse_over_gui; +} + +void gui_on_mouse_hold(const int wasongui, const int wasbutdown) +{ + for (int i=0;iIsActivated) continue; + if (guis[wasongui].GetControlType(i)!=kGUISlider) continue; + // GUI Slider repeatedly activates while being dragged + guio->IsActivated = false; + force_event(EV_IFACECLICK, wasongui, i, wasbutdown); + break; + } +} + +void gui_on_mouse_up(const int wasongui, const int wasbutdown) +{ + guis[wasongui].OnMouseButtonUp(); + + for (int i=0;iIsActivated) continue; + guio->IsActivated = false; + if (!IsInterfaceEnabled()) break; + + int cttype=guis[wasongui].GetControlType(i); + if ((cttype == kGUIButton) || (cttype == kGUISlider) || (cttype == kGUIListBox)) { + force_event(EV_IFACECLICK, wasongui, i, wasbutdown); + } + else if (cttype == kGUIInvWindow) { + mouse_ifacebut_xoffs=mousex-(guio->X)-guis[wasongui].X; + mouse_ifacebut_yoffs=mousey-(guio->Y)-guis[wasongui].Y; + int iit=offset_over_inv((GUIInvWindow*)guio); + if (iit>=0) { + evblocknum=iit; + play.used_inv_on = iit; + if (game.options[OPT_HANDLEINVCLICKS]) { + // Let the script handle the click + // LEFTINV is 5, RIGHTINV is 6 + force_event(EV_TEXTSCRIPT,TS_MCLICK, wasbutdown + 4); + } + else if (wasbutdown==2) // right-click is always Look + run_event_block_inv(iit, 0); + else if (cur_mode == MODE_HAND) + SetActiveInventory(iit); + else + RunInventoryInteraction (iit, cur_mode); + evblocknum=-1; + } + } + else quit("clicked on unknown control type"); + if (guis[wasongui].PopupStyle==kGUIPopupMouseY) + remove_popup_interface(wasongui); + break; + } + + run_on_event(GE_GUI_MOUSEUP, RuntimeScriptValue().SetInt32(wasongui)); +} + +void gui_on_mouse_down(const int guin, const int mbut) +{ + debug_script_log("Mouse click over GUI %d", guin); + guis[guin].OnMouseButtonDown(); + // run GUI click handler if not on any control + if ((guis[guin].MouseDownCtrl < 0) && (!guis[guin].OnClickHandler.IsEmpty())) + force_event(EV_IFACECLICK, guin, -1, mbut); + + run_on_event(GE_GUI_MOUSEDOWN, RuntimeScriptValue().SetInt32(guin)); +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// void GUI_Centre(ScriptGUI *sgui) +RuntimeScriptValue Sc_GUI_Centre(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptGUI, GUI_Centre); +} + +// ScriptGUI *(int xx, int yy) +RuntimeScriptValue Sc_GetGUIAtLocation(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptGUI, ccDynamicGUI, GetGUIAtLocation); +} + +// void (ScriptGUI *tehgui, int xx, int yy) +RuntimeScriptValue Sc_GUI_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptGUI, GUI_SetPosition); +} + +// void (ScriptGUI *sgui, int widd, int hitt) +RuntimeScriptValue Sc_GUI_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptGUI, GUI_SetSize); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetBackgroundGraphic); +} + +// void (ScriptGUI *tehgui, int slotn) +RuntimeScriptValue Sc_GUI_SetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBackgroundGraphic); +} + +RuntimeScriptValue Sc_GUI_GetBackgroundColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetBackgroundColor); +} + +RuntimeScriptValue Sc_GUI_SetBackgroundColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBackgroundColor); +} + +RuntimeScriptValue Sc_GUI_GetBorderColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetBorderColor); +} + +RuntimeScriptValue Sc_GUI_SetBorderColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBorderColor); +} + +RuntimeScriptValue Sc_GUI_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetTextColor); +} + +RuntimeScriptValue Sc_GUI_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTextColor); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetClickable); +} + +// void (ScriptGUI *tehgui, int clickable) +RuntimeScriptValue Sc_GUI_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetClickable); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetControlCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetControlCount); +} + +// GUIObject* (ScriptGUI *tehgui, int idx) +RuntimeScriptValue Sc_GUI_GetiControls(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT(ScriptGUI, GUIObject, ccDynamicGUIObject, GUI_GetiControls); +} + +// int (ScriptGUI *sgui) +RuntimeScriptValue Sc_GUI_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetHeight); +} + +// void (ScriptGUI *sgui, int newhit) +RuntimeScriptValue Sc_GUI_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetHeight); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetID); +} + +RuntimeScriptValue Sc_GUI_GetPopupYPos(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetPopupYPos); +} + +RuntimeScriptValue Sc_GUI_SetPopupYPos(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetPopupYPos); +} + +RuntimeScriptValue Sc_GUI_GetTextPadding(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetTextPadding); +} + +RuntimeScriptValue Sc_GUI_SetTextPadding(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTextPadding); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetTransparency); +} + +// void (ScriptGUI *tehgui, int trans) +RuntimeScriptValue Sc_GUI_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTransparency); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetVisible); +} + +// void (ScriptGUI *tehgui, int isvisible) +RuntimeScriptValue Sc_GUI_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetVisible); +} + +// int (ScriptGUI *sgui) +RuntimeScriptValue Sc_GUI_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetWidth); +} + +// void (ScriptGUI *sgui, int newwid) +RuntimeScriptValue Sc_GUI_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetWidth); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetX); +} + +// void (ScriptGUI *tehgui, int xx) +RuntimeScriptValue Sc_GUI_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetX); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetY); +} + +// void (ScriptGUI *tehgui, int yy) +RuntimeScriptValue Sc_GUI_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetY); +} + +// int (ScriptGUI *tehgui) +RuntimeScriptValue Sc_GUI_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetZOrder); +} + +// void (ScriptGUI *tehgui, int z) +RuntimeScriptValue Sc_GUI_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetZOrder); +} + +RuntimeScriptValue Sc_GUI_AsTextWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptGUI, ScriptGUI, ccDynamicGUI, GUI_AsTextWindow); +} + +RuntimeScriptValue Sc_GUI_GetPopupStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptGUI, GUI_GetPopupStyle); +} + +RuntimeScriptValue Sc_GUI_Click(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_Click); +} + +RuntimeScriptValue Sc_GUI_ProcessClick(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(GUI_ProcessClick); +} + +void RegisterGUIAPI() +{ + ccAddExternalObjectFunction("GUI::Centre^0", Sc_GUI_Centre); + ccAddExternalObjectFunction("GUI::Click^1", Sc_GUI_Click); + ccAddExternalStaticFunction("GUI::GetAtScreenXY^2", Sc_GetGUIAtLocation); + ccAddExternalStaticFunction("GUI::ProcessClick^3", Sc_GUI_ProcessClick); + ccAddExternalObjectFunction("GUI::SetPosition^2", Sc_GUI_SetPosition); + ccAddExternalObjectFunction("GUI::SetSize^2", Sc_GUI_SetSize); + ccAddExternalObjectFunction("GUI::get_BackgroundGraphic", Sc_GUI_GetBackgroundGraphic); + ccAddExternalObjectFunction("GUI::set_BackgroundGraphic", Sc_GUI_SetBackgroundGraphic); + ccAddExternalObjectFunction("GUI::get_BackgroundColor", Sc_GUI_GetBackgroundColor); + ccAddExternalObjectFunction("GUI::set_BackgroundColor", Sc_GUI_SetBackgroundColor); + ccAddExternalObjectFunction("GUI::get_BorderColor", Sc_GUI_GetBorderColor); + ccAddExternalObjectFunction("GUI::set_BorderColor", Sc_GUI_SetBorderColor); + ccAddExternalObjectFunction("GUI::get_Clickable", Sc_GUI_GetClickable); + ccAddExternalObjectFunction("GUI::set_Clickable", Sc_GUI_SetClickable); + ccAddExternalObjectFunction("GUI::get_ControlCount", Sc_GUI_GetControlCount); + ccAddExternalObjectFunction("GUI::geti_Controls", Sc_GUI_GetiControls); + ccAddExternalObjectFunction("GUI::get_Height", Sc_GUI_GetHeight); + ccAddExternalObjectFunction("GUI::set_Height", Sc_GUI_SetHeight); + ccAddExternalObjectFunction("GUI::get_ID", Sc_GUI_GetID); + ccAddExternalObjectFunction("GUI::get_AsTextWindow", Sc_GUI_AsTextWindow); + ccAddExternalObjectFunction("GUI::get_PopupStyle", Sc_GUI_GetPopupStyle); + ccAddExternalObjectFunction("GUI::get_PopupYPos", Sc_GUI_GetPopupYPos); + ccAddExternalObjectFunction("GUI::set_PopupYPos", Sc_GUI_SetPopupYPos); + ccAddExternalObjectFunction("TextWindowGUI::get_TextColor", Sc_GUI_GetTextColor); + ccAddExternalObjectFunction("TextWindowGUI::set_TextColor", Sc_GUI_SetTextColor); + ccAddExternalObjectFunction("TextWindowGUI::get_TextPadding", Sc_GUI_GetTextPadding); + ccAddExternalObjectFunction("TextWindowGUI::set_TextPadding", Sc_GUI_SetTextPadding); + ccAddExternalObjectFunction("GUI::get_Transparency", Sc_GUI_GetTransparency); + ccAddExternalObjectFunction("GUI::set_Transparency", Sc_GUI_SetTransparency); + ccAddExternalObjectFunction("GUI::get_Visible", Sc_GUI_GetVisible); + ccAddExternalObjectFunction("GUI::set_Visible", Sc_GUI_SetVisible); + ccAddExternalObjectFunction("GUI::get_Width", Sc_GUI_GetWidth); + ccAddExternalObjectFunction("GUI::set_Width", Sc_GUI_SetWidth); + ccAddExternalObjectFunction("GUI::get_X", Sc_GUI_GetX); + ccAddExternalObjectFunction("GUI::set_X", Sc_GUI_SetX); + ccAddExternalObjectFunction("GUI::get_Y", Sc_GUI_GetY); + ccAddExternalObjectFunction("GUI::set_Y", Sc_GUI_SetY); + ccAddExternalObjectFunction("GUI::get_ZOrder", Sc_GUI_GetZOrder); + ccAddExternalObjectFunction("GUI::set_ZOrder", Sc_GUI_SetZOrder); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("GUI::Centre^0", (void*)GUI_Centre); + ccAddExternalFunctionForPlugin("GUI::GetAtScreenXY^2", (void*)GetGUIAtLocation); + ccAddExternalFunctionForPlugin("GUI::SetPosition^2", (void*)GUI_SetPosition); + ccAddExternalFunctionForPlugin("GUI::SetSize^2", (void*)GUI_SetSize); + ccAddExternalFunctionForPlugin("GUI::get_BackgroundGraphic", (void*)GUI_GetBackgroundGraphic); + ccAddExternalFunctionForPlugin("GUI::set_BackgroundGraphic", (void*)GUI_SetBackgroundGraphic); + ccAddExternalFunctionForPlugin("GUI::get_Clickable", (void*)GUI_GetClickable); + ccAddExternalFunctionForPlugin("GUI::set_Clickable", (void*)GUI_SetClickable); + ccAddExternalFunctionForPlugin("GUI::get_ControlCount", (void*)GUI_GetControlCount); + ccAddExternalFunctionForPlugin("GUI::geti_Controls", (void*)GUI_GetiControls); + ccAddExternalFunctionForPlugin("GUI::get_Height", (void*)GUI_GetHeight); + ccAddExternalFunctionForPlugin("GUI::set_Height", (void*)GUI_SetHeight); + ccAddExternalFunctionForPlugin("GUI::get_ID", (void*)GUI_GetID); + ccAddExternalFunctionForPlugin("GUI::get_Transparency", (void*)GUI_GetTransparency); + ccAddExternalFunctionForPlugin("GUI::set_Transparency", (void*)GUI_SetTransparency); + ccAddExternalFunctionForPlugin("GUI::get_Visible", (void*)GUI_GetVisible); + ccAddExternalFunctionForPlugin("GUI::set_Visible", (void*)GUI_SetVisible); + ccAddExternalFunctionForPlugin("GUI::get_Width", (void*)GUI_GetWidth); + ccAddExternalFunctionForPlugin("GUI::set_Width", (void*)GUI_SetWidth); + ccAddExternalFunctionForPlugin("GUI::get_X", (void*)GUI_GetX); + ccAddExternalFunctionForPlugin("GUI::set_X", (void*)GUI_SetX); + ccAddExternalFunctionForPlugin("GUI::get_Y", (void*)GUI_GetY); + ccAddExternalFunctionForPlugin("GUI::set_Y", (void*)GUI_SetY); + ccAddExternalFunctionForPlugin("GUI::get_ZOrder", (void*)GUI_GetZOrder); + ccAddExternalFunctionForPlugin("GUI::set_ZOrder", (void*)GUI_SetZOrder); +} diff --git a/engines/ags/engine/ac/gui.h b/engines/ags/engine/ac/gui.h new file mode 100644 index 000000000000..6bdcbdc04909 --- /dev/null +++ b/engines/ags/engine/ac/gui.h @@ -0,0 +1,88 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GUI_H +#define __AGS_EE_AC__GUI_H + +#include "ac/dynobj/scriptgui.h" +#include "gui/guimain.h" + +using AGS::Common::GUIMain; +using AGS::Common::GUIObject; + +ScriptGUI *GUI_AsTextWindow(ScriptGUI *tehgui); +int GUI_GetPopupStyle(ScriptGUI *tehgui); +void GUI_SetVisible(ScriptGUI *tehgui, int isvisible); +int GUI_GetVisible(ScriptGUI *tehgui); +int GUI_GetX(ScriptGUI *tehgui); +void GUI_SetX(ScriptGUI *tehgui, int xx); +int GUI_GetY(ScriptGUI *tehgui); +void GUI_SetY(ScriptGUI *tehgui, int yy); +void GUI_SetPosition(ScriptGUI *tehgui, int xx, int yy); +void GUI_SetSize(ScriptGUI *sgui, int widd, int hitt); +int GUI_GetWidth(ScriptGUI *sgui); +int GUI_GetHeight(ScriptGUI *sgui); +void GUI_SetWidth(ScriptGUI *sgui, int newwid); +void GUI_SetHeight(ScriptGUI *sgui, int newhit); +void GUI_SetZOrder(ScriptGUI *tehgui, int z); +int GUI_GetZOrder(ScriptGUI *tehgui); +void GUI_SetClickable(ScriptGUI *tehgui, int clickable); +int GUI_GetClickable(ScriptGUI *tehgui); +int GUI_GetID(ScriptGUI *tehgui); +GUIObject* GUI_GetiControls(ScriptGUI *tehgui, int idx); +int GUI_GetControlCount(ScriptGUI *tehgui); +void GUI_SetPopupYPos(ScriptGUI *tehgui, int newpos); +int GUI_GetPopupYPos(ScriptGUI *tehgui); +void GUI_SetTransparency(ScriptGUI *tehgui, int trans); +int GUI_GetTransparency(ScriptGUI *tehgui); +void GUI_Centre(ScriptGUI *sgui); +void GUI_SetBackgroundGraphic(ScriptGUI *tehgui, int slotn); +int GUI_GetBackgroundGraphic(ScriptGUI *tehgui); +void GUI_SetBackgroundColor(ScriptGUI *tehgui, int newcol); +int GUI_GetBackgroundColor(ScriptGUI *tehgui); +void GUI_SetBorderColor(ScriptGUI *tehgui, int newcol); +int GUI_GetBorderColor(ScriptGUI *tehgui); +void GUI_SetTextColor(ScriptGUI *tehgui, int newcol); +int GUI_GetTextColor(ScriptGUI *tehgui); +void GUI_SetTextPadding(ScriptGUI *tehgui, int newpos); +int GUI_GetTextPadding(ScriptGUI *tehgui); +ScriptGUI *GetGUIAtLocation(int xx, int yy); + +void remove_popup_interface(int ifacenum); +void process_interface_click(int ifce, int btn, int mbut); +void replace_macro_tokens(const char *text, AGS::Common::String &fixed_text); +void update_gui_zorder(); +void export_gui_controls(int ee); +void unexport_gui_controls(int ee); +int convert_gui_disabled_style(int oldStyle); +void update_gui_disabled_status(); +int adjust_x_for_guis (int xx, int yy); +int adjust_y_for_guis ( int yy); +void recreate_guibg_image(GUIMain *tehgui); + +int gui_get_interactable(int x,int y); +int gui_on_mouse_move(); +void gui_on_mouse_hold(const int wasongui, const int wasbutdown); +void gui_on_mouse_up(const int wasongui, const int wasbutdown); +void gui_on_mouse_down(const int guin, const int mbut); + +extern int ifacepopped; + +extern int ifacepopped; +extern int mouse_on_iface; + +#endif // __AGS_EE_AC__GUI_H diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp new file mode 100644 index 000000000000..b007330da022 --- /dev/null +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -0,0 +1,474 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/guicontrol.h" +#include "ac/global_gui.h" +#include "debug/debug_log.h" +#include "gui/guibutton.h" +#include "gui/guiinv.h" +#include "gui/guilabel.h" +#include "gui/guilistbox.h" +#include "gui/guimain.h" +#include "gui/guislider.h" +#include "gui/guitextbox.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_gui.h" +#include "ac/dynobj/cc_guiobject.h" + +using namespace AGS::Common; + +extern ScriptGUI*scrGui; +extern CCGUI ccDynamicGUI; +extern CCGUIObject ccDynamicGUIObject; + +GUIObject *GetGUIControlAtLocation(int xx, int yy) { + int guinum = GetGUIAt(xx, yy); + if (guinum == -1) + return nullptr; + + data_to_game_coords(&xx, &yy); + + int oldmousex = mousex, oldmousey = mousey; + mousex = xx - guis[guinum].X; + mousey = yy - guis[guinum].Y; + int toret = guis[guinum].FindControlUnderMouse(0, false); + mousex = oldmousex; + mousey = oldmousey; + if (toret < 0) + return nullptr; + + return guis[guinum].GetControl(toret); +} + +int GUIControl_GetVisible(GUIObject *guio) { + return guio->IsVisible(); +} + +void GUIControl_SetVisible(GUIObject *guio, int visible) +{ + const bool on = visible != 0; + if (on != guio->IsVisible()) + { + guio->SetVisible(on); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; + } +} + +int GUIControl_GetClickable(GUIObject *guio) { + if (guio->IsClickable()) + return 1; + return 0; +} + +void GUIControl_SetClickable(GUIObject *guio, int enabled) { + if (enabled) + guio->SetClickable(true); + else + guio->SetClickable(false); + + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; +} + +int GUIControl_GetEnabled(GUIObject *guio) { + return guio->IsEnabled() ? 1 : 0; +} + +void GUIControl_SetEnabled(GUIObject *guio, int enabled) { + const bool on = enabled != 0; + if (on != guio->IsEnabled()) + { + guio->SetEnabled(on); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; + } +} + + +int GUIControl_GetID(GUIObject *guio) { + return guio->Id; +} + +ScriptGUI* GUIControl_GetOwningGUI(GUIObject *guio) { + return &scrGui[guio->ParentId]; +} + +GUIButton* GUIControl_GetAsButton(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIButton) + return nullptr; + + return (GUIButton*)guio; +} + +GUIInvWindow* GUIControl_GetAsInvWindow(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIInvWindow) + return nullptr; + + return (GUIInvWindow*)guio; +} + +GUILabel* GUIControl_GetAsLabel(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUILabel) + return nullptr; + + return (GUILabel*)guio; +} + +GUIListBox* GUIControl_GetAsListBox(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIListBox) + return nullptr; + + return (GUIListBox*)guio; +} + +GUISlider* GUIControl_GetAsSlider(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUISlider) + return nullptr; + + return (GUISlider*)guio; +} + +GUITextBox* GUIControl_GetAsTextBox(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUITextBox) + return nullptr; + + return (GUITextBox*)guio; +} + +int GUIControl_GetX(GUIObject *guio) { + return game_to_data_coord(guio->X); +} + +void GUIControl_SetX(GUIObject *guio, int xx) { + guio->X = data_to_game_coord(xx); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; +} + +int GUIControl_GetY(GUIObject *guio) { + return game_to_data_coord(guio->Y); +} + +void GUIControl_SetY(GUIObject *guio, int yy) { + guio->Y = data_to_game_coord(yy); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; +} + +int GUIControl_GetZOrder(GUIObject *guio) +{ + return guio->ZOrder; +} + +void GUIControl_SetZOrder(GUIObject *guio, int zorder) +{ + if (guis[guio->ParentId].SetControlZOrder(guio->Id, zorder)) + guis_need_update = 1; +} + +void GUIControl_SetPosition(GUIObject *guio, int xx, int yy) { + GUIControl_SetX(guio, xx); + GUIControl_SetY(guio, yy); +} + + +int GUIControl_GetWidth(GUIObject *guio) { + return game_to_data_coord(guio->Width); +} + +void GUIControl_SetWidth(GUIObject *guio, int newwid) { + guio->Width = data_to_game_coord(newwid); + guio->OnResized(); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; +} + +int GUIControl_GetHeight(GUIObject *guio) { + return game_to_data_coord(guio->Height); +} + +void GUIControl_SetHeight(GUIObject *guio, int newhit) { + guio->Height = data_to_game_coord(newhit); + guio->OnResized(); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; +} + +void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit) { + if ((newwid < 2) || (newhit < 2)) + quit("!SetGUIObjectSize: new size is too small (must be at least 2x2)"); + + debug_script_log("SetGUIObject %d,%d size %d,%d", guio->ParentId, guio->Id, newwid, newhit); + GUIControl_SetWidth(guio, newwid); + GUIControl_SetHeight(guio, newhit); +} + +void GUIControl_SendToBack(GUIObject *guio) { + if (guis[guio->ParentId].SendControlToBack(guio->Id)) + guis_need_update = 1; +} + +void GUIControl_BringToFront(GUIObject *guio) { + if (guis[guio->ParentId].BringControlToFront(guio->Id)) + guis_need_update = 1; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// void (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_BringToFront(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(GUIObject, GUIControl_BringToFront); +} + +// GUIObject *(int xx, int yy) +RuntimeScriptValue Sc_GetGUIControlAtLocation(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(GUIObject, ccDynamicGUIObject, GetGUIControlAtLocation); +} + +// void (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_SendToBack(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(GUIObject, GUIControl_SendToBack); +} + +// void (GUIObject *guio, int xx, int yy) +RuntimeScriptValue Sc_GUIControl_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(GUIObject, GUIControl_SetPosition); +} + +// void (GUIObject *guio, int newwid, int newhit) +RuntimeScriptValue Sc_GUIControl_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(GUIObject, GUIControl_SetSize); +} + +// GUIButton* (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetAsButton(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIObject, GUIButton, ccDynamicGUI, GUIControl_GetAsButton); +} + +// GUIInvWindow* (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetAsInvWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIObject, GUIInvWindow, ccDynamicGUI, GUIControl_GetAsInvWindow); +} + +// GUILabel* (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetAsLabel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIObject, GUILabel, ccDynamicGUI, GUIControl_GetAsLabel); +} + +// GUIListBox* (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetAsListBox(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIObject, GUIListBox, ccDynamicGUI, GUIControl_GetAsListBox); +} + +// GUISlider* (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetAsSlider(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIObject, GUISlider, ccDynamicGUI, GUIControl_GetAsSlider); +} + +// GUITextBox* (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetAsTextBox(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIObject, GUITextBox, ccDynamicGUI, GUIControl_GetAsTextBox); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetClickable); +} + +// void (GUIObject *guio, int enabled) +RuntimeScriptValue Sc_GUIControl_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetClickable); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetEnabled); +} + +// void (GUIObject *guio, int enabled) +RuntimeScriptValue Sc_GUIControl_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetEnabled); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetHeight); +} + +// void (GUIObject *guio, int newhit) +RuntimeScriptValue Sc_GUIControl_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetHeight); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetID); +} + +// ScriptGUI* (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetOwningGUI(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIObject, ScriptGUI, ccDynamicGUI, GUIControl_GetOwningGUI); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetVisible); +} + +// void (GUIObject *guio, int visible) +RuntimeScriptValue Sc_GUIControl_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetVisible); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetWidth); +} + +// void (GUIObject *guio, int newwid) +RuntimeScriptValue Sc_GUIControl_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetWidth); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetX); +} + +// void (GUIObject *guio, int xx) +RuntimeScriptValue Sc_GUIControl_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetX); +} + +// int (GUIObject *guio) +RuntimeScriptValue Sc_GUIControl_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetY); +} + +// void (GUIObject *guio, int yy) +RuntimeScriptValue Sc_GUIControl_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetY); +} + +RuntimeScriptValue Sc_GUIControl_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIObject, GUIControl_GetZOrder); +} + +RuntimeScriptValue Sc_GUIControl_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetZOrder); +} + + + +void RegisterGUIControlAPI() +{ + ccAddExternalObjectFunction("GUIControl::BringToFront^0", Sc_GUIControl_BringToFront); + ccAddExternalStaticFunction("GUIControl::GetAtScreenXY^2", Sc_GetGUIControlAtLocation); + ccAddExternalObjectFunction("GUIControl::SendToBack^0", Sc_GUIControl_SendToBack); + ccAddExternalObjectFunction("GUIControl::SetPosition^2", Sc_GUIControl_SetPosition); + ccAddExternalObjectFunction("GUIControl::SetSize^2", Sc_GUIControl_SetSize); + ccAddExternalObjectFunction("GUIControl::get_AsButton", Sc_GUIControl_GetAsButton); + ccAddExternalObjectFunction("GUIControl::get_AsInvWindow", Sc_GUIControl_GetAsInvWindow); + ccAddExternalObjectFunction("GUIControl::get_AsLabel", Sc_GUIControl_GetAsLabel); + ccAddExternalObjectFunction("GUIControl::get_AsListBox", Sc_GUIControl_GetAsListBox); + ccAddExternalObjectFunction("GUIControl::get_AsSlider", Sc_GUIControl_GetAsSlider); + ccAddExternalObjectFunction("GUIControl::get_AsTextBox", Sc_GUIControl_GetAsTextBox); + ccAddExternalObjectFunction("GUIControl::get_Clickable", Sc_GUIControl_GetClickable); + ccAddExternalObjectFunction("GUIControl::set_Clickable", Sc_GUIControl_SetClickable); + ccAddExternalObjectFunction("GUIControl::get_Enabled", Sc_GUIControl_GetEnabled); + ccAddExternalObjectFunction("GUIControl::set_Enabled", Sc_GUIControl_SetEnabled); + ccAddExternalObjectFunction("GUIControl::get_Height", Sc_GUIControl_GetHeight); + ccAddExternalObjectFunction("GUIControl::set_Height", Sc_GUIControl_SetHeight); + ccAddExternalObjectFunction("GUIControl::get_ID", Sc_GUIControl_GetID); + ccAddExternalObjectFunction("GUIControl::get_OwningGUI", Sc_GUIControl_GetOwningGUI); + ccAddExternalObjectFunction("GUIControl::get_Visible", Sc_GUIControl_GetVisible); + ccAddExternalObjectFunction("GUIControl::set_Visible", Sc_GUIControl_SetVisible); + ccAddExternalObjectFunction("GUIControl::get_Width", Sc_GUIControl_GetWidth); + ccAddExternalObjectFunction("GUIControl::set_Width", Sc_GUIControl_SetWidth); + ccAddExternalObjectFunction("GUIControl::get_X", Sc_GUIControl_GetX); + ccAddExternalObjectFunction("GUIControl::set_X", Sc_GUIControl_SetX); + ccAddExternalObjectFunction("GUIControl::get_Y", Sc_GUIControl_GetY); + ccAddExternalObjectFunction("GUIControl::set_Y", Sc_GUIControl_SetY); + ccAddExternalObjectFunction("GUIControl::get_ZOrder", Sc_GUIControl_GetZOrder); + ccAddExternalObjectFunction("GUIControl::set_ZOrder", Sc_GUIControl_SetZOrder); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("GUIControl::BringToFront^0", (void*)GUIControl_BringToFront); + ccAddExternalFunctionForPlugin("GUIControl::GetAtScreenXY^2", (void*)GetGUIControlAtLocation); + ccAddExternalFunctionForPlugin("GUIControl::SendToBack^0", (void*)GUIControl_SendToBack); + ccAddExternalFunctionForPlugin("GUIControl::SetPosition^2", (void*)GUIControl_SetPosition); + ccAddExternalFunctionForPlugin("GUIControl::SetSize^2", (void*)GUIControl_SetSize); + ccAddExternalFunctionForPlugin("GUIControl::get_AsButton", (void*)GUIControl_GetAsButton); + ccAddExternalFunctionForPlugin("GUIControl::get_AsInvWindow", (void*)GUIControl_GetAsInvWindow); + ccAddExternalFunctionForPlugin("GUIControl::get_AsLabel", (void*)GUIControl_GetAsLabel); + ccAddExternalFunctionForPlugin("GUIControl::get_AsListBox", (void*)GUIControl_GetAsListBox); + ccAddExternalFunctionForPlugin("GUIControl::get_AsSlider", (void*)GUIControl_GetAsSlider); + ccAddExternalFunctionForPlugin("GUIControl::get_AsTextBox", (void*)GUIControl_GetAsTextBox); + ccAddExternalFunctionForPlugin("GUIControl::get_Clickable", (void*)GUIControl_GetClickable); + ccAddExternalFunctionForPlugin("GUIControl::set_Clickable", (void*)GUIControl_SetClickable); + ccAddExternalFunctionForPlugin("GUIControl::get_Enabled", (void*)GUIControl_GetEnabled); + ccAddExternalFunctionForPlugin("GUIControl::set_Enabled", (void*)GUIControl_SetEnabled); + ccAddExternalFunctionForPlugin("GUIControl::get_Height", (void*)GUIControl_GetHeight); + ccAddExternalFunctionForPlugin("GUIControl::set_Height", (void*)GUIControl_SetHeight); + ccAddExternalFunctionForPlugin("GUIControl::get_ID", (void*)GUIControl_GetID); + ccAddExternalFunctionForPlugin("GUIControl::get_OwningGUI", (void*)GUIControl_GetOwningGUI); + ccAddExternalFunctionForPlugin("GUIControl::get_Visible", (void*)GUIControl_GetVisible); + ccAddExternalFunctionForPlugin("GUIControl::set_Visible", (void*)GUIControl_SetVisible); + ccAddExternalFunctionForPlugin("GUIControl::get_Width", (void*)GUIControl_GetWidth); + ccAddExternalFunctionForPlugin("GUIControl::set_Width", (void*)GUIControl_SetWidth); + ccAddExternalFunctionForPlugin("GUIControl::get_X", (void*)GUIControl_GetX); + ccAddExternalFunctionForPlugin("GUIControl::set_X", (void*)GUIControl_SetX); + ccAddExternalFunctionForPlugin("GUIControl::get_Y", (void*)GUIControl_GetY); + ccAddExternalFunctionForPlugin("GUIControl::set_Y", (void*)GUIControl_SetY); +} diff --git a/engines/ags/engine/ac/guicontrol.h b/engines/ags/engine/ac/guicontrol.h new file mode 100644 index 000000000000..aa9ec3ad4c63 --- /dev/null +++ b/engines/ags/engine/ac/guicontrol.h @@ -0,0 +1,68 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__GUICONTROL_H +#define __AGS_EE_AC__GUICONTROL_H + +#include "gui/guiobject.h" +#include "gui/guibutton.h" +#include "gui/guiinv.h" +#include "gui/guilabel.h" +#include "gui/guilistbox.h" +#include "gui/guislider.h" +#include "gui/guitextbox.h" +#include "ac/dynobj/scriptgui.h" + +using AGS::Common::GUIObject; +using AGS::Common::GUIButton; +using AGS::Common::GUIInvWindow; +using AGS::Common::GUILabel; +using AGS::Common::GUIListBox; +using AGS::Common::GUISlider; +using AGS::Common::GUITextBox; + +GUIObject *GetGUIControlAtLocation(int xx, int yy); +int GUIControl_GetVisible(GUIObject *guio); +void GUIControl_SetVisible(GUIObject *guio, int visible); +int GUIControl_GetClickable(GUIObject *guio); +void GUIControl_SetClickable(GUIObject *guio, int enabled); +int GUIControl_GetEnabled(GUIObject *guio); +void GUIControl_SetEnabled(GUIObject *guio, int enabled); +int GUIControl_GetID(GUIObject *guio); +ScriptGUI* GUIControl_GetOwningGUI(GUIObject *guio); +GUIButton* GUIControl_GetAsButton(GUIObject *guio); +GUIInvWindow* GUIControl_GetAsInvWindow(GUIObject *guio); +GUILabel* GUIControl_GetAsLabel(GUIObject *guio); +GUIListBox* GUIControl_GetAsListBox(GUIObject *guio); +GUISlider* GUIControl_GetAsSlider(GUIObject *guio); +GUITextBox* GUIControl_GetAsTextBox(GUIObject *guio); +int GUIControl_GetX(GUIObject *guio); +void GUIControl_SetX(GUIObject *guio, int xx); +int GUIControl_GetY(GUIObject *guio); +void GUIControl_SetY(GUIObject *guio, int yy); +int GUIControl_GetZOrder(GUIObject *guio); +void GUIControl_SetZOrder(GUIObject *guio, int zorder); +void GUIControl_SetPosition(GUIObject *guio, int xx, int yy); +int GUIControl_GetWidth(GUIObject *guio); +void GUIControl_SetWidth(GUIObject *guio, int newwid); +int GUIControl_GetHeight(GUIObject *guio); +void GUIControl_SetHeight(GUIObject *guio, int newhit); +void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit); +void GUIControl_SendToBack(GUIObject *guio); +void GUIControl_BringToFront(GUIObject *guio); + +#endif // __AGS_EE_AC__GUICONTROL_H diff --git a/engines/ags/engine/ac/guiinv.cpp b/engines/ags/engine/ac/guiinv.cpp new file mode 100644 index 000000000000..411bca2ec058 --- /dev/null +++ b/engines/ags/engine/ac/guiinv.cpp @@ -0,0 +1,94 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gui/guiinv.h" +#include "gui/guimain.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/characterextras.h" +#include "ac/spritecache.h" +#include "gfx/bitmap.h" + + +extern GameSetupStruct game; +extern int gui_disabled_style; +extern GameState play; +extern CharacterExtras *charextra; +extern SpriteCache spriteset; + + +namespace AGS +{ +namespace Common +{ + +int GUIInvWindow::GetCharacterId() const +{ + if (CharId < 0) + return game.playercharacter; + + return CharId; +} + +void GUIInvWindow::Draw(Bitmap *ds) +{ + const bool enabled = IsGUIEnabled(this); + if (!enabled && (gui_disabled_style == GUIDIS_BLACKOUT)) + return; + + // backwards compatibility + play.inv_numinline = ColCount; + play.inv_numdisp = RowCount * ColCount; + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; + // if the user changes top_inv_item, switch into backwards + // compatibiltiy mode + if (play.inv_top) + play.inv_backwards_compatibility = 1; + if (play.inv_backwards_compatibility) + TopItem = play.inv_top; + + // draw the items + const int leftmost_x = X; + int at_x = X; + int at_y = Y; + int lastItem = TopItem + (ColCount * RowCount); + if (lastItem > charextra[GetCharacterId()].invorder_count) + lastItem = charextra[GetCharacterId()].invorder_count; + + for (int item = TopItem; item < lastItem; ++item) + { + // draw inv graphic + draw_gui_sprite(ds, game.invinfo[charextra[GetCharacterId()].invorder[item]].pic, at_x, at_y, true); + at_x += data_to_game_coord(ItemWidth); + + // go to next row when appropriate + if ((item - TopItem) % ColCount == (ColCount - 1)) + { + at_x = leftmost_x; + at_y += data_to_game_coord(ItemHeight); + } + } + + if (!enabled && + gui_disabled_style == GUIDIS_GREYOUT && + play.inventory_greys_out == 1) + { + // darken the inventory when disabled + GUI::DrawDisabledEffect(ds, RectWH(X, Y, Width, Height)); + } +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp new file mode 100644 index 000000000000..bca406d7726d --- /dev/null +++ b/engines/ags/engine/ac/hotspot.cpp @@ -0,0 +1,268 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/cc_hotspot.h" +#include "ac/hotspot.h" +#include "ac/gamestate.h" +#include "ac/global_hotspot.h" +#include "ac/global_translation.h" +#include "ac/properties.h" +#include "ac/room.h" +#include "ac/roomstatus.h" +#include "ac/string.h" +#include "game/roomstruct.h" +#include "gfx/bitmap.h" +#include "script/runtimescriptvalue.h" + +using namespace AGS::Common; + +extern RoomStruct thisroom; +extern RoomStatus*croom; +extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; +extern CCHotspot ccDynamicHotspot; + +void Hotspot_SetEnabled(ScriptHotspot *hss, int newval) { + if (newval) + EnableHotspot(hss->id); + else + DisableHotspot(hss->id); +} + +int Hotspot_GetEnabled(ScriptHotspot *hss) { + return croom->hotspot_enabled[hss->id]; +} + +int Hotspot_GetID(ScriptHotspot *hss) { + return hss->id; +} + +int Hotspot_GetWalkToX(ScriptHotspot *hss) { + return GetHotspotPointX(hss->id); +} + +int Hotspot_GetWalkToY(ScriptHotspot *hss) { + return GetHotspotPointY(hss->id); +} + +ScriptHotspot *GetHotspotAtScreen(int xx, int yy) { + return &scrHotspot[GetHotspotIDAtScreen(xx, yy)]; +} + +ScriptHotspot *GetHotspotAtRoom(int x, int y) { + return &scrHotspot[get_hotspot_at(x, y)]; +} + +void Hotspot_GetName(ScriptHotspot *hss, char *buffer) { + GetHotspotName(hss->id, buffer); +} + +const char* Hotspot_GetName_New(ScriptHotspot *hss) { + return CreateNewScriptString(get_translation(thisroom.Hotspots[hss->id].Name)); +} + +bool Hotspot_IsInteractionAvailable(ScriptHotspot *hhot, int mood) { + + play.check_interaction_only = 1; + RunHotspotInteraction(hhot->id, mood); + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + return (ciwas == 2); +} + +void Hotspot_RunInteraction (ScriptHotspot *hss, int mood) { + RunHotspotInteraction(hss->id, mood); +} + +int Hotspot_GetProperty (ScriptHotspot *hss, const char *property) +{ + return get_int_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property); +} + +void Hotspot_GetPropertyText (ScriptHotspot *hss, const char *property, char *bufer) +{ + get_text_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property, bufer); + +} + +const char* Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property) +{ + return get_text_property_dynamic_string(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property); +} + +bool Hotspot_SetProperty(ScriptHotspot *hss, const char *property, int value) +{ + return set_int_property(croom->hsProps[hss->id], property, value); +} + +bool Hotspot_SetTextProperty(ScriptHotspot *hss, const char *property, const char *value) +{ + return set_text_property(croom->hsProps[hss->id], property, value); +} + +int get_hotspot_at(int xpp,int ypp) { + int onhs=thisroom.HotspotMask->GetPixel(room_to_mask_coord(xpp), room_to_mask_coord(ypp)); + if (onhs <= 0 || onhs >= MAX_ROOM_HOTSPOTS) return 0; + if (croom->hotspot_enabled[onhs]==0) return 0; + return onhs; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +RuntimeScriptValue Sc_GetHotspotAtRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtRoom); +} + +// ScriptHotspot *(int xx, int yy) +RuntimeScriptValue Sc_GetHotspotAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtScreen); +} + +RuntimeScriptValue Sc_Hotspot_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) +{ + ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaHotspot); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +} + +// void (ScriptHotspot *hss, char *buffer) +RuntimeScriptValue Sc_Hotspot_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(ScriptHotspot, Hotspot_GetName, char); +} + +// int (ScriptHotspot *hss, const char *property) +RuntimeScriptValue Sc_Hotspot_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(ScriptHotspot, Hotspot_GetProperty, const char); +} + +// void (ScriptHotspot *hss, const char *property, char *bufer) +RuntimeScriptValue Sc_Hotspot_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ2(ScriptHotspot, Hotspot_GetPropertyText, const char, char); +} + +// const char* (ScriptHotspot *hss, const char *property) +RuntimeScriptValue Sc_Hotspot_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_POBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetTextProperty, const char); +} + +RuntimeScriptValue Sc_Hotspot_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ_PINT(ScriptHotspot, Hotspot_SetProperty, const char); +} + +RuntimeScriptValue Sc_Hotspot_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ2(ScriptHotspot, Hotspot_SetTextProperty, const char, const char); +} + +RuntimeScriptValue Sc_Hotspot_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_PINT(ScriptHotspot, Hotspot_IsInteractionAvailable); +} + +// void (ScriptHotspot *hss, int mood) +RuntimeScriptValue Sc_Hotspot_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptHotspot, Hotspot_RunInteraction); +} + +// int (ScriptHotspot *hss) +RuntimeScriptValue Sc_Hotspot_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetEnabled); +} + +// void (ScriptHotspot *hss, int newval) +RuntimeScriptValue Sc_Hotspot_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptHotspot, Hotspot_SetEnabled); +} + +// int (ScriptHotspot *hss) +RuntimeScriptValue Sc_Hotspot_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetID); +} + +// const char* (ScriptHotspot *hss) +RuntimeScriptValue Sc_Hotspot_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetName_New); +} + +// int (ScriptHotspot *hss) +RuntimeScriptValue Sc_Hotspot_GetWalkToX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetWalkToX); +} + +// int (ScriptHotspot *hss) +RuntimeScriptValue Sc_Hotspot_GetWalkToY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetWalkToY); +} + + + +void RegisterHotspotAPI() +{ + ccAddExternalStaticFunction("Hotspot::GetAtRoomXY^2", Sc_GetHotspotAtRoom); + ccAddExternalStaticFunction("Hotspot::GetAtScreenXY^2", Sc_GetHotspotAtScreen); + ccAddExternalStaticFunction("Hotspot::GetDrawingSurface", Sc_Hotspot_GetDrawingSurface); + ccAddExternalObjectFunction("Hotspot::GetName^1", Sc_Hotspot_GetName); + ccAddExternalObjectFunction("Hotspot::GetProperty^1", Sc_Hotspot_GetProperty); + ccAddExternalObjectFunction("Hotspot::GetPropertyText^2", Sc_Hotspot_GetPropertyText); + ccAddExternalObjectFunction("Hotspot::GetTextProperty^1", Sc_Hotspot_GetTextProperty); + ccAddExternalObjectFunction("Hotspot::SetProperty^2", Sc_Hotspot_SetProperty); + ccAddExternalObjectFunction("Hotspot::SetTextProperty^2", Sc_Hotspot_SetTextProperty); + ccAddExternalObjectFunction("Hotspot::IsInteractionAvailable^1", Sc_Hotspot_IsInteractionAvailable); + ccAddExternalObjectFunction("Hotspot::RunInteraction^1", Sc_Hotspot_RunInteraction); + ccAddExternalObjectFunction("Hotspot::get_Enabled", Sc_Hotspot_GetEnabled); + ccAddExternalObjectFunction("Hotspot::set_Enabled", Sc_Hotspot_SetEnabled); + ccAddExternalObjectFunction("Hotspot::get_ID", Sc_Hotspot_GetID); + ccAddExternalObjectFunction("Hotspot::get_Name", Sc_Hotspot_GetName_New); + ccAddExternalObjectFunction("Hotspot::get_WalkToX", Sc_Hotspot_GetWalkToX); + ccAddExternalObjectFunction("Hotspot::get_WalkToY", Sc_Hotspot_GetWalkToY); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Hotspot::GetAtRoomXY^2", (void*)GetHotspotAtRoom); + ccAddExternalFunctionForPlugin("Hotspot::GetAtScreenXY^2", (void*)GetHotspotAtScreen); + ccAddExternalFunctionForPlugin("Hotspot::GetName^1", (void*)Hotspot_GetName); + ccAddExternalFunctionForPlugin("Hotspot::GetProperty^1", (void*)Hotspot_GetProperty); + ccAddExternalFunctionForPlugin("Hotspot::GetPropertyText^2", (void*)Hotspot_GetPropertyText); + ccAddExternalFunctionForPlugin("Hotspot::GetTextProperty^1", (void*)Hotspot_GetTextProperty); + ccAddExternalFunctionForPlugin("Hotspot::RunInteraction^1", (void*)Hotspot_RunInteraction); + ccAddExternalFunctionForPlugin("Hotspot::get_Enabled", (void*)Hotspot_GetEnabled); + ccAddExternalFunctionForPlugin("Hotspot::set_Enabled", (void*)Hotspot_SetEnabled); + ccAddExternalFunctionForPlugin("Hotspot::get_ID", (void*)Hotspot_GetID); + ccAddExternalFunctionForPlugin("Hotspot::get_Name", (void*)Hotspot_GetName_New); + ccAddExternalFunctionForPlugin("Hotspot::get_WalkToX", (void*)Hotspot_GetWalkToX); + ccAddExternalFunctionForPlugin("Hotspot::get_WalkToY", (void*)Hotspot_GetWalkToY); +} diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h new file mode 100644 index 000000000000..d1bb46f8b23b --- /dev/null +++ b/engines/ags/engine/ac/hotspot.h @@ -0,0 +1,42 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__HOTSPOT_H +#define __AGS_EE_AC__HOTSPOT_H + +#include "ac/dynobj/scripthotspot.h" + +void Hotspot_SetEnabled(ScriptHotspot *hss, int newval); +int Hotspot_GetEnabled(ScriptHotspot *hss); +int Hotspot_GetID(ScriptHotspot *hss); +ScriptHotspot *GetHotspotAtScreen(int xx, int yy); +int Hotspot_GetWalkToX(ScriptHotspot *hss);; +int Hotspot_GetWalkToY(ScriptHotspot *hss); +void Hotspot_GetName(ScriptHotspot *hss, char *buffer); +const char* Hotspot_GetName_New(ScriptHotspot *hss); +bool Hotspot_IsInteractionAvailable(ScriptHotspot *hhot, int mood); +void Hotspot_RunInteraction (ScriptHotspot *hss, int mood); + +int Hotspot_GetProperty (ScriptHotspot *hss, const char *property); +void Hotspot_GetPropertyText (ScriptHotspot *hss, const char *property, char *bufer); +const char* Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property); + +// Gets hotspot ID at the given room coordinates; +// if hotspot is disabled or non-existing, returns 0 (no area) +int get_hotspot_at(int xpp,int ypp); + +#endif // __AGS_EE_AC__HOTSPOT_H diff --git a/engines/ags/engine/ac/interfacebutton.cpp b/engines/ags/engine/ac/interfacebutton.cpp new file mode 100644 index 000000000000..c474bb7ecb73 --- /dev/null +++ b/engines/ags/engine/ac/interfacebutton.cpp @@ -0,0 +1,21 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/interfacebutton.h" + +void InterfaceButton::set(int xx, int yy, int picc, int overpicc, int actionn) { + x = xx; y = yy; pic = picc; overpic = overpicc; leftclick = actionn; pushpic = 0; + rightclick = 0; flags = IBFLG_ENABLED; + reserved_for_future = 0; +} \ No newline at end of file diff --git a/engines/ags/engine/ac/interfaceelement.cpp b/engines/ags/engine/ac/interfaceelement.cpp new file mode 100644 index 000000000000..13abc93fdc24 --- /dev/null +++ b/engines/ags/engine/ac/interfaceelement.cpp @@ -0,0 +1,21 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/interfaceelement.h" + +InterfaceElement::InterfaceElement() { + vtextxp = 0; vtextyp = 1; strcpy(vtext,"@SCORETEXT@$r@GAMENAME@"); + numbuttons = 0; bgcol = 8; fgcol = 15; bordercol = 0; on = 1; flags = 0; +} diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp new file mode 100644 index 000000000000..8f28fd6136b8 --- /dev/null +++ b/engines/ags/engine/ac/inventoryitem.cpp @@ -0,0 +1,266 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/inventoryitem.h" +#include "ac/characterinfo.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_inventoryitem.h" +#include "ac/global_translation.h" +#include "ac/mouse.h" +#include "ac/properties.h" +#include "ac/runtime_defines.h" +#include "ac/string.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_inventory.h" + + +extern GameSetupStruct game; +extern ScriptInvItem scrInv[MAX_INV]; +extern int cur_cursor; +extern CharacterInfo*playerchar; +extern CCInventory ccDynamicInv; + + +void InventoryItem_SetCursorGraphic(ScriptInvItem *iitem, int newSprite) +{ + set_inv_item_cursorpic(iitem->id, newSprite); +} + +int InventoryItem_GetCursorGraphic(ScriptInvItem *iitem) +{ + return game.invinfo[iitem->id].cursorPic; +} + +void InventoryItem_SetGraphic(ScriptInvItem *iitem, int piccy) { + set_inv_item_pic(iitem->id, piccy); +} + +void InventoryItem_SetName(ScriptInvItem *scii, const char *newname) { + SetInvItemName(scii->id, newname); +} + +int InventoryItem_GetID(ScriptInvItem *scii) { + return scii->id; +} + +ScriptInvItem *GetInvAtLocation(int xx, int yy) { + int hsnum = GetInvAt(xx, yy); + if (hsnum <= 0) + return nullptr; + return &scrInv[hsnum]; +} + +void InventoryItem_GetName(ScriptInvItem *iitem, char *buff) { + GetInvName(iitem->id, buff); +} + +const char* InventoryItem_GetName_New(ScriptInvItem *invitem) { + return CreateNewScriptString(get_translation(game.invinfo[invitem->id].name)); +} + +int InventoryItem_GetGraphic(ScriptInvItem *iitem) { + return game.invinfo[iitem->id].pic; +} + +void InventoryItem_RunInteraction(ScriptInvItem *iitem, int mood) { + RunInventoryInteraction(iitem->id, mood); +} + +int InventoryItem_CheckInteractionAvailable(ScriptInvItem *iitem, int mood) { + return IsInventoryInteractionAvailable(iitem->id, mood); +} + +int InventoryItem_GetProperty(ScriptInvItem *scii, const char *property) { + return get_int_property (game.invProps[scii->id], play.invProps[scii->id], property); +} + +void InventoryItem_GetPropertyText(ScriptInvItem *scii, const char *property, char *bufer) { + get_text_property(game.invProps[scii->id], play.invProps[scii->id], property, bufer); +} + +const char* InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *property) { + return get_text_property_dynamic_string(game.invProps[scii->id], play.invProps[scii->id], property); +} + +bool InventoryItem_SetProperty(ScriptInvItem *scii, const char *property, int value) +{ + return set_int_property(play.invProps[scii->id], property, value); +} + +bool InventoryItem_SetTextProperty(ScriptInvItem *scii, const char *property, const char *value) +{ + return set_text_property(play.invProps[scii->id], property, value); +} + +//============================================================================= + +void set_inv_item_cursorpic(int invItemId, int piccy) +{ + game.invinfo[invItemId].cursorPic = piccy; + + if ((cur_cursor == MODE_USE) && (playerchar->activeinv == invItemId)) + { + update_inv_cursor(invItemId); + set_mouse_cursor(cur_cursor); + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// ScriptInvItem *(int xx, int yy) +RuntimeScriptValue Sc_GetInvAtLocation(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptInvItem, ccDynamicInv, GetInvAtLocation); +} + +// int (ScriptInvItem *iitem, int mood) +RuntimeScriptValue Sc_InventoryItem_CheckInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(ScriptInvItem, InventoryItem_CheckInteractionAvailable); +} + +// void (ScriptInvItem *iitem, char *buff) +RuntimeScriptValue Sc_InventoryItem_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(ScriptInvItem, InventoryItem_GetName, char); +} + +// int (ScriptInvItem *scii, const char *property) +RuntimeScriptValue Sc_InventoryItem_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(ScriptInvItem, InventoryItem_GetProperty, const char); +} + +// void (ScriptInvItem *scii, const char *property, char *bufer) +RuntimeScriptValue Sc_InventoryItem_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ2(ScriptInvItem, InventoryItem_GetPropertyText, const char, char); +} + +// const char* (ScriptInvItem *scii, const char *property) +RuntimeScriptValue Sc_InventoryItem_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_POBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetTextProperty, const char); +} + +RuntimeScriptValue Sc_InventoryItem_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ_PINT(ScriptInvItem, InventoryItem_SetProperty, const char); +} + +RuntimeScriptValue Sc_InventoryItem_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ2(ScriptInvItem, InventoryItem_SetTextProperty, const char, const char); +} + +// void (ScriptInvItem *iitem, int mood) +RuntimeScriptValue Sc_InventoryItem_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_RunInteraction); +} + +// void (ScriptInvItem *scii, const char *newname) +RuntimeScriptValue Sc_InventoryItem_SetName(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(ScriptInvItem, InventoryItem_SetName, const char); +} + +// int (ScriptInvItem *iitem) +RuntimeScriptValue Sc_InventoryItem_GetCursorGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetCursorGraphic); +} + +// void (ScriptInvItem *iitem, int newSprite) +RuntimeScriptValue Sc_InventoryItem_SetCursorGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_SetCursorGraphic); +} + +// int (ScriptInvItem *iitem) +RuntimeScriptValue Sc_InventoryItem_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetGraphic); +} + +// void (ScriptInvItem *iitem, int piccy) +RuntimeScriptValue Sc_InventoryItem_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_SetGraphic); +} + +// int (ScriptInvItem *scii) +RuntimeScriptValue Sc_InventoryItem_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetID); +} + +// const char* (ScriptInvItem *invitem) +RuntimeScriptValue Sc_InventoryItem_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetName_New); +} + + + +void RegisterInventoryItemAPI() +{ + ccAddExternalStaticFunction("InventoryItem::GetAtScreenXY^2", Sc_GetInvAtLocation); + ccAddExternalObjectFunction("InventoryItem::IsInteractionAvailable^1", Sc_InventoryItem_CheckInteractionAvailable); + ccAddExternalObjectFunction("InventoryItem::GetName^1", Sc_InventoryItem_GetName); + ccAddExternalObjectFunction("InventoryItem::GetProperty^1", Sc_InventoryItem_GetProperty); + ccAddExternalObjectFunction("InventoryItem::GetPropertyText^2", Sc_InventoryItem_GetPropertyText); + ccAddExternalObjectFunction("InventoryItem::GetTextProperty^1", Sc_InventoryItem_GetTextProperty); + ccAddExternalObjectFunction("InventoryItem::SetProperty^2", Sc_InventoryItem_SetProperty); + ccAddExternalObjectFunction("InventoryItem::SetTextProperty^2", Sc_InventoryItem_SetTextProperty); + ccAddExternalObjectFunction("InventoryItem::RunInteraction^1", Sc_InventoryItem_RunInteraction); + ccAddExternalObjectFunction("InventoryItem::SetName^1", Sc_InventoryItem_SetName); + ccAddExternalObjectFunction("InventoryItem::get_CursorGraphic", Sc_InventoryItem_GetCursorGraphic); + ccAddExternalObjectFunction("InventoryItem::set_CursorGraphic", Sc_InventoryItem_SetCursorGraphic); + ccAddExternalObjectFunction("InventoryItem::get_Graphic", Sc_InventoryItem_GetGraphic); + ccAddExternalObjectFunction("InventoryItem::set_Graphic", Sc_InventoryItem_SetGraphic); + ccAddExternalObjectFunction("InventoryItem::get_ID", Sc_InventoryItem_GetID); + ccAddExternalObjectFunction("InventoryItem::get_Name", Sc_InventoryItem_GetName_New); + ccAddExternalObjectFunction("InventoryItem::set_Name", Sc_InventoryItem_SetName); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("InventoryItem::GetAtScreenXY^2", (void*)GetInvAtLocation); + ccAddExternalFunctionForPlugin("InventoryItem::IsInteractionAvailable^1", (void*)InventoryItem_CheckInteractionAvailable); + ccAddExternalFunctionForPlugin("InventoryItem::GetName^1", (void*)InventoryItem_GetName); + ccAddExternalFunctionForPlugin("InventoryItem::GetProperty^1", (void*)InventoryItem_GetProperty); + ccAddExternalFunctionForPlugin("InventoryItem::GetPropertyText^2", (void*)InventoryItem_GetPropertyText); + ccAddExternalFunctionForPlugin("InventoryItem::GetTextProperty^1", (void*)InventoryItem_GetTextProperty); + ccAddExternalFunctionForPlugin("InventoryItem::RunInteraction^1", (void*)InventoryItem_RunInteraction); + ccAddExternalFunctionForPlugin("InventoryItem::SetName^1", (void*)InventoryItem_SetName); + ccAddExternalFunctionForPlugin("InventoryItem::get_CursorGraphic", (void*)InventoryItem_GetCursorGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::set_CursorGraphic", (void*)InventoryItem_SetCursorGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::get_Graphic", (void*)InventoryItem_GetGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::set_Graphic", (void*)InventoryItem_SetGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::get_ID", (void*)InventoryItem_GetID); + ccAddExternalFunctionForPlugin("InventoryItem::get_Name", (void*)InventoryItem_GetName_New); + ccAddExternalFunctionForPlugin("InventoryItem::set_Name", (void*)InventoryItem_SetName); +} diff --git a/engines/ags/engine/ac/inventoryitem.h b/engines/ags/engine/ac/inventoryitem.h new file mode 100644 index 000000000000..833209a65978 --- /dev/null +++ b/engines/ags/engine/ac/inventoryitem.h @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__INVENTORYITEM_H +#define __AGS_EE_AC__INVENTORYITEM_H + +#include "ac/dynobj/scriptinvitem.h" + +void InventoryItem_SetCursorGraphic(ScriptInvItem *iitem, int newSprite); +int InventoryItem_GetCursorGraphic(ScriptInvItem *iitem); +void InventoryItem_SetGraphic(ScriptInvItem *iitem, int piccy); +void InventoryItem_SetName(ScriptInvItem *scii, const char *newname); +int InventoryItem_GetID(ScriptInvItem *scii); +ScriptInvItem *GetInvAtLocation(int xx, int yy); +void InventoryItem_GetName(ScriptInvItem *iitem, char *buff); +const char* InventoryItem_GetName_New(ScriptInvItem *invitem); +int InventoryItem_GetGraphic(ScriptInvItem *iitem); +void InventoryItem_RunInteraction(ScriptInvItem *iitem, int mood); +int InventoryItem_CheckInteractionAvailable(ScriptInvItem *iitem, int mood); +int InventoryItem_GetProperty(ScriptInvItem *scii, const char *property); +void InventoryItem_GetPropertyText(ScriptInvItem *scii, const char *property, char *bufer); +const char* InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *property); + +void set_inv_item_cursorpic(int invItemId, int piccy); + +#endif // __AGS_EE_AC__INVENTORYITEM_H diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp new file mode 100644 index 000000000000..faffb294e016 --- /dev/null +++ b/engines/ags/engine/ac/invwindow.cpp @@ -0,0 +1,658 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/invwindow.h" +#include "ac/common.h" +#include "ac/characterextras.h" +#include "ac/characterinfo.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/gamestate.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_character.h" +#include "ac/global_display.h" +#include "ac/global_room.h" +#include "ac/mouse.h" +#include "ac/sys_events.h" +#include "debug/debug_log.h" +#include "gui/guidialog.h" +#include "main/game_run.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/spritecache.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_character.h" +#include "ac/dynobj/cc_inventory.h" +#include "util/math.h" +#include "media/audio/audio_system.h" +#include "ac/timer.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern GameState play; +extern CharacterExtras *charextra; +extern ScriptInvItem scrInv[MAX_INV]; +extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; +extern SpriteCache spriteset; +extern int mousex,mousey; +extern int evblocknum; +extern CharacterInfo*playerchar; +extern AGSPlatformDriver *platform; +extern CCCharacter ccDynamicCharacter; +extern CCInventory ccDynamicInv; + +int in_inv_screen = 0, inv_screen_newroom = -1; + +// *** INV WINDOW FUNCTIONS + +void InvWindow_SetCharacterToUse(GUIInvWindow *guii, CharacterInfo *chaa) { + if (chaa == nullptr) + guii->CharId = -1; + else + guii->CharId = chaa->index_id; + // reset to top of list + guii->TopItem = 0; + + guis_need_update = 1; +} + +CharacterInfo* InvWindow_GetCharacterToUse(GUIInvWindow *guii) { + if (guii->CharId < 0) + return nullptr; + + return &game.chars[guii->CharId]; +} + +void InvWindow_SetItemWidth(GUIInvWindow *guii, int newwidth) { + guii->ItemWidth = newwidth; + guii->OnResized(); +} + +int InvWindow_GetItemWidth(GUIInvWindow *guii) { + return guii->ItemWidth; +} + +void InvWindow_SetItemHeight(GUIInvWindow *guii, int newhit) { + guii->ItemHeight = newhit; + guii->OnResized(); +} + +int InvWindow_GetItemHeight(GUIInvWindow *guii) { + return guii->ItemHeight; +} + +void InvWindow_SetTopItem(GUIInvWindow *guii, int topitem) { + if (guii->TopItem != topitem) { + guii->TopItem = topitem; + guis_need_update = 1; + } +} + +int InvWindow_GetTopItem(GUIInvWindow *guii) { + return guii->TopItem; +} + +int InvWindow_GetItemsPerRow(GUIInvWindow *guii) { + return guii->ColCount; +} + +int InvWindow_GetItemCount(GUIInvWindow *guii) { + return charextra[guii->GetCharacterId()].invorder_count; +} + +int InvWindow_GetRowCount(GUIInvWindow *guii) { + return guii->RowCount; +} + +void InvWindow_ScrollDown(GUIInvWindow *guii) { + if ((charextra[guii->GetCharacterId()].invorder_count) > + (guii->TopItem + (guii->ColCount * guii->RowCount))) { + guii->TopItem += guii->ColCount; + guis_need_update = 1; + } +} + +void InvWindow_ScrollUp(GUIInvWindow *guii) { + if (guii->TopItem > 0) { + guii->TopItem -= guii->ColCount; + if (guii->TopItem < 0) + guii->TopItem = 0; + + guis_need_update = 1; + } +} + +ScriptInvItem* InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index) { + if ((index < 0) || (index >= charextra[guii->GetCharacterId()].invorder_count)) + return nullptr; + return &scrInv[charextra[guii->GetCharacterId()].invorder[index]]; +} + +//============================================================================= + +int offset_over_inv(GUIInvWindow *inv) { + if (inv->ItemWidth <= 0 || inv->ItemHeight <= 0) + return -1; + int mover = mouse_ifacebut_xoffs / data_to_game_coord(inv->ItemWidth); + // if it's off the edge of the visible items, ignore + if (mover >= inv->ColCount) + return -1; + mover += (mouse_ifacebut_yoffs / data_to_game_coord(inv->ItemHeight)) * inv->ColCount; + if (mover >= inv->ColCount * inv->RowCount) + return -1; + + mover += inv->TopItem; + if ((mover < 0) || (mover >= charextra[inv->GetCharacterId()].invorder_count)) + return -1; + + return charextra[inv->GetCharacterId()].invorder[mover]; +} + +// +// NOTE: This is an old default inventory screen implementation, +// which became completely obsolete after AGS 2.72. +// + +#define ICONSPERLINE 4 + +struct DisplayInvItem { + int num; + int sprnum; +}; + +struct InventoryScreen +{ + static const int ARROWBUTTONWID = 11; + + int BUTTONAREAHEIGHT; + int cmode; + int toret; + int top_item; + int num_visible_items; + int MAX_ITEMAREA_HEIGHT; + int wasonitem; + int bartop; + int barxp; + int numitems; + int widest; + int highest; + int windowwid; + int windowhit; + int windowxp; + int windowyp; + int buttonyp; + DisplayInvItem dii[MAX_INV]; + int btn_look_sprite; + int btn_select_sprite; + int btn_ok_sprite; + + int break_code; + + void Prepare(); + int Redraw(); + void Draw(Bitmap *ds); + void RedrawOverItem(Bitmap *ds, int isonitem); + bool Run(); + void Close(); +}; + +InventoryScreen InvScr; + +void InventoryScreen::Prepare() +{ + BUTTONAREAHEIGHT = get_fixed_pixel_size(30); + cmode=CURS_ARROW; + toret = -1; + top_item = 0; + num_visible_items = 0; + MAX_ITEMAREA_HEIGHT = ((play.GetUIViewport().GetHeight() - BUTTONAREAHEIGHT) - get_fixed_pixel_size(20)); + in_inv_screen++; + inv_screen_newroom = -1; + + // Sprites 2041, 2042 and 2043 were hardcoded in the older versions of + // the engine to be used in the built-in inventory window. + // If they did not exist engine first fell back to sprites 0, 1, 2 instead. + // Fun fact: this fallback does not seem to be intentional, and was a + // coincidental result of SpriteCache incorrectly remembering "last seeked + // sprite" as 2041/2042/2043 while in fact stream was after sprite 0. + if (spriteset[2041] == nullptr || spriteset[2042] == nullptr || spriteset[2043] == nullptr) + debug_script_warn("InventoryScreen: one or more of the inventory screen graphics (sprites 2041, 2042, 2043) does not exist, fallback to sprites 0, 1, 2 instead"); + btn_look_sprite = spriteset[2041] != nullptr ? 2041 : 0; + btn_select_sprite = spriteset[2042] != nullptr ? 2042 : (spriteset[1] != nullptr ? 1 : 0); + btn_ok_sprite = spriteset[2043] != nullptr ? 2043 : (spriteset[2] != nullptr ? 2 : 0); + + break_code = 0; +} + +int InventoryScreen::Redraw() +{ + numitems=0; + widest=0; + highest=0; + if (charextra[game.playercharacter].invorder_count < 0) + update_invorder(); + if (charextra[game.playercharacter].invorder_count == 0) { + DisplayMessage(996); + in_inv_screen--; + return -1; + } + + if (inv_screen_newroom >= 0) { + in_inv_screen--; + NewRoom(inv_screen_newroom); + return -1; + } + + for (int i = 0; i < charextra[game.playercharacter].invorder_count; ++i) { + if (game.invinfo[charextra[game.playercharacter].invorder[i]].name[0]!=0) { + dii[numitems].num = charextra[game.playercharacter].invorder[i]; + dii[numitems].sprnum = game.invinfo[charextra[game.playercharacter].invorder[i]].pic; + int snn=dii[numitems].sprnum; + if (game.SpriteInfos[snn].Width > widest) widest=game.SpriteInfos[snn].Width; + if (game.SpriteInfos[snn].Height > highest) highest= game.SpriteInfos[snn].Height; + numitems++; + } + } + if (numitems != charextra[game.playercharacter].invorder_count) + quit("inconsistent inventory calculations"); + + widest += get_fixed_pixel_size(4); + highest += get_fixed_pixel_size(4); + num_visible_items = (MAX_ITEMAREA_HEIGHT / highest) * ICONSPERLINE; + + windowhit = highest * (numitems/ICONSPERLINE) + get_fixed_pixel_size(4); + if ((numitems%ICONSPERLINE) !=0) windowhit+=highest; + if (windowhit > MAX_ITEMAREA_HEIGHT) { + windowhit = (MAX_ITEMAREA_HEIGHT / highest) * highest + get_fixed_pixel_size(4); + } + windowhit += BUTTONAREAHEIGHT; + + windowwid = widest*ICONSPERLINE + get_fixed_pixel_size(4); + if (windowwid < get_fixed_pixel_size(105)) windowwid = get_fixed_pixel_size(105); + windowxp=play.GetUIViewport().GetWidth()/2-windowwid/2; + windowyp=play.GetUIViewport().GetHeight()/2-windowhit/2; + buttonyp = windowhit - BUTTONAREAHEIGHT; + bartop = get_fixed_pixel_size(2); + barxp = get_fixed_pixel_size(2); + + Bitmap *ds = prepare_gui_screen(windowxp, windowyp, windowwid, windowhit, true); + Draw(ds); + //ags_domouse(DOMOUSE_ENABLE); + set_mouse_cursor(cmode); + wasonitem = -1; + return 0; +} + +void InventoryScreen::Draw(Bitmap *ds) +{ + color_t draw_color = ds->GetCompatibleColor(play.sierra_inv_color); + ds->FillRect(Rect(0,0,windowwid,windowhit), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->FillRect(Rect(barxp,bartop, windowwid - get_fixed_pixel_size(2),buttonyp-1), draw_color); + for (int i = top_item; i < numitems; ++i) { + if (i >= top_item + num_visible_items) + break; + Bitmap *spof=spriteset[dii[i].sprnum]; + wputblock(ds, barxp+1+((i-top_item)%4)*widest+widest/2-spof->GetWidth()/2, + bartop+1+((i-top_item)/4)*highest+highest/2-spof->GetHeight()/2,spof,1); + } +#define BUTTONWID Math::Max(1, game.SpriteInfos[btn_select_sprite].Width) + // Draw select, look and OK buttons + wputblock(ds, 2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_look_sprite], 1); + wputblock(ds, 3+BUTTONWID, buttonyp + get_fixed_pixel_size(2), spriteset[btn_select_sprite], 1); + wputblock(ds, 4+BUTTONWID*2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_ok_sprite], 1); + + // Draw Up and Down buttons if required + Bitmap *arrowblock = BitmapHelper::CreateTransparentBitmap (ARROWBUTTONWID, ARROWBUTTONWID); + draw_color = arrowblock->GetCompatibleColor(0); + if (play.sierra_inv_color == 0) + draw_color = ds->GetCompatibleColor(14); + + arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, ARROWBUTTONWID-2, 9), draw_color); + arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, 2, 9), draw_color); + arrowblock->DrawLine(Line(2, 9, ARROWBUTTONWID-2, 9), draw_color); + arrowblock->FloodFill(ARROWBUTTONWID/2, 4, draw_color); + + if (top_item > 0) + wputblock(ds, windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(2), arrowblock, 1); + if (top_item + num_visible_items < numitems) + arrowblock->FlipBlt(arrowblock, windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID, Common::kBitmap_VFlip); + delete arrowblock; +} + +void InventoryScreen::RedrawOverItem(Bitmap *ds, int isonitem) +{ + int rectxp=barxp+1+(wasonitem%4)*widest; + int rectyp=bartop+1+((wasonitem - top_item)/4)*highest; + if (wasonitem>=0) + { + color_t draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(rectxp,rectyp,rectxp+widest-1,rectyp+highest-1), draw_color); + } + if (isonitem>=0) + { + color_t draw_color = ds->GetCompatibleColor(14);//opts.invrectcol); + rectxp=barxp+1+(isonitem%4)*widest; + rectyp=bartop+1+((isonitem - top_item)/4)*highest; + ds->DrawRect(Rect(rectxp,rectyp,rectxp+widest-1,rectyp+highest-1), draw_color); + } +} + +bool InventoryScreen::Run() +{ + int kgn; + if (run_service_key_controls(kgn) && !play.IsIgnoringInput()) + { + return false; // end inventory screen loop + } + + update_audio_system_on_game_loop(); + refresh_gui_screen(); + + // NOTE: this is because old code was working with full game screen + const int mousex = ::mousex - windowxp; + const int mousey = ::mousey - windowyp; + + int isonitem=((mousey-bartop)/highest)*ICONSPERLINE+(mousex-barxp)/widest; + if (mousey<=bartop) isonitem=-1; + else if (isonitem >= 0) isonitem += top_item; + if ((isonitem<0) | (isonitem>=numitems) | (isonitem >= top_item + num_visible_items)) + isonitem=-1; + + int mclick, mwheelz; + if (!run_service_mb_controls(mclick, mwheelz) || play.IsIgnoringInput()) { + mclick = NONE; + } + + if (mclick == LEFT) { + if ((mousey<0) | (mousey>windowhit) | (mousex<0) | (mousex>windowwid)) + return true; // continue inventory screen loop + if (mouseyactiveinv; + playerchar->activeinv = toret; + + //ags_domouse(DOMOUSE_DISABLE); + run_event_block_inv(dii[clickedon].num, 3); + + // if the script didn't change it, then put it back + if (playerchar->activeinv == toret) + playerchar->activeinv = activeinvwas; + + // in case the script did anything to the screen, redraw it + UpdateGameOnce(); + + // They used the active item and lost it + if (playerchar->inv[toret] < 1) { + cmode = CURS_ARROW; + set_mouse_cursor(cmode); + toret = -1; + } + + break_code = Redraw(); + return break_code == 0; + } + toret=dii[clickedon].num; + // int plusng=play.using; play.using=toret; + update_inv_cursor(toret); + set_mouse_cursor(MODE_USE); + cmode=MODE_USE; + // play.using=plusng; + // break; + return true; // continue inventory screen loop + } + else { + if (mousex >= windowwid-ARROWBUTTONWID) { + if (mousey < buttonyp + get_fixed_pixel_size(2) + ARROWBUTTONWID) { + if (top_item > 0) { + top_item -= ICONSPERLINE; + //ags_domouse(DOMOUSE_DISABLE); + + break_code = Redraw(); + return break_code == 0; + } + } + else if ((mousey < buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID*2) && (top_item + num_visible_items < numitems)) { + top_item += ICONSPERLINE; + //ags_domouse(DOMOUSE_DISABLE); + + break_code = Redraw(); + return break_code == 0; + } + return true; // continue inventory screen loop + } + + int buton=mousex-2; + if (buton<0) return true; // continue inventory screen loop + buton/=BUTTONWID; + if (buton>=3) return true; // continue inventory screen loop + if (buton==0) { toret=-1; cmode=MODE_LOOK; } + else if (buton==1) { cmode=CURS_ARROW; toret=-1; } + else + { + return false; // end inventory screen loop + } + set_mouse_cursor(cmode); + } + } + else if (mclick == RIGHT) { + if (cmode == CURS_ARROW) + cmode = MODE_LOOK; + else + cmode = CURS_ARROW; + toret = -1; + set_mouse_cursor(cmode); + } + else if (isonitem!=wasonitem) + { + //ags_domouse(DOMOUSE_DISABLE); + RedrawOverItem(get_gui_screen(), isonitem); + //ags_domouse(DOMOUSE_ENABLE); + } + wasonitem=isonitem; + + update_polled_stuff_if_runtime(); + + WaitForNextFrame(); + + return true; // continue inventory screen loop +} + +void InventoryScreen::Close() +{ + clear_gui_screen(); + set_default_cursor(); + invalidate_screen(); + in_inv_screen--; +} + +int __actual_invscreen() +{ + InvScr.Prepare(); + InvScr.break_code = InvScr.Redraw(); + if (InvScr.break_code != 0) + { + return InvScr.break_code; + } + + while (InvScr.Run()); + + if (InvScr.break_code != 0) + { + return InvScr.break_code; + } + + ags_clear_input_buffer(); + + InvScr.Close(); + return InvScr.toret; +} + +int invscreen() { + int selt=__actual_invscreen(); + if (selt<0) return -1; + playerchar->activeinv=selt; + guis_need_update = 1; + set_cursor_mode(MODE_USE); + return selt; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// void (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(GUIInvWindow, InvWindow_ScrollDown); +} + +// void (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_ScrollUp(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(GUIInvWindow, InvWindow_ScrollUp); +} + +// CharacterInfo* (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_GetCharacterToUse(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUIInvWindow, CharacterInfo, ccDynamicCharacter, InvWindow_GetCharacterToUse); +} + +// void (GUIInvWindow *guii, CharacterInfo *chaa) +RuntimeScriptValue Sc_InvWindow_SetCharacterToUse(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUIInvWindow, InvWindow_SetCharacterToUse, CharacterInfo); +} + +// ScriptInvItem* (GUIInvWindow *guii, int index) +RuntimeScriptValue Sc_InvWindow_GetItemAtIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT(GUIInvWindow, ScriptInvItem, ccDynamicInv, InvWindow_GetItemAtIndex); +} + +// int (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemCount); +} + +// int (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_GetItemHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemHeight); +} + +// void (GUIInvWindow *guii, int newhit) +RuntimeScriptValue Sc_InvWindow_SetItemHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetItemHeight); +} + +// int (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_GetItemWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemWidth); +} + +// void (GUIInvWindow *guii, int newwidth) +RuntimeScriptValue Sc_InvWindow_SetItemWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetItemWidth); +} + +// int (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_GetItemsPerRow(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemsPerRow); +} + +// int (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_GetRowCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetRowCount); +} + +// int (GUIInvWindow *guii) +RuntimeScriptValue Sc_InvWindow_GetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetTopItem); +} + +// void (GUIInvWindow *guii, int topitem) +RuntimeScriptValue Sc_InvWindow_SetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetTopItem); +} + + + +void RegisterInventoryWindowAPI() +{ + ccAddExternalObjectFunction("InvWindow::ScrollDown^0", Sc_InvWindow_ScrollDown); + ccAddExternalObjectFunction("InvWindow::ScrollUp^0", Sc_InvWindow_ScrollUp); + ccAddExternalObjectFunction("InvWindow::get_CharacterToUse", Sc_InvWindow_GetCharacterToUse); + ccAddExternalObjectFunction("InvWindow::set_CharacterToUse", Sc_InvWindow_SetCharacterToUse); + ccAddExternalObjectFunction("InvWindow::geti_ItemAtIndex", Sc_InvWindow_GetItemAtIndex); + ccAddExternalObjectFunction("InvWindow::get_ItemCount", Sc_InvWindow_GetItemCount); + ccAddExternalObjectFunction("InvWindow::get_ItemHeight", Sc_InvWindow_GetItemHeight); + ccAddExternalObjectFunction("InvWindow::set_ItemHeight", Sc_InvWindow_SetItemHeight); + ccAddExternalObjectFunction("InvWindow::get_ItemWidth", Sc_InvWindow_GetItemWidth); + ccAddExternalObjectFunction("InvWindow::set_ItemWidth", Sc_InvWindow_SetItemWidth); + ccAddExternalObjectFunction("InvWindow::get_ItemsPerRow", Sc_InvWindow_GetItemsPerRow); + ccAddExternalObjectFunction("InvWindow::get_RowCount", Sc_InvWindow_GetRowCount); + ccAddExternalObjectFunction("InvWindow::get_TopItem", Sc_InvWindow_GetTopItem); + ccAddExternalObjectFunction("InvWindow::set_TopItem", Sc_InvWindow_SetTopItem); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("InvWindow::ScrollDown^0", (void*)InvWindow_ScrollDown); + ccAddExternalFunctionForPlugin("InvWindow::ScrollUp^0", (void*)InvWindow_ScrollUp); + ccAddExternalFunctionForPlugin("InvWindow::get_CharacterToUse", (void*)InvWindow_GetCharacterToUse); + ccAddExternalFunctionForPlugin("InvWindow::set_CharacterToUse", (void*)InvWindow_SetCharacterToUse); + ccAddExternalFunctionForPlugin("InvWindow::geti_ItemAtIndex", (void*)InvWindow_GetItemAtIndex); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemCount", (void*)InvWindow_GetItemCount); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemHeight", (void*)InvWindow_GetItemHeight); + ccAddExternalFunctionForPlugin("InvWindow::set_ItemHeight", (void*)InvWindow_SetItemHeight); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemWidth", (void*)InvWindow_GetItemWidth); + ccAddExternalFunctionForPlugin("InvWindow::set_ItemWidth", (void*)InvWindow_SetItemWidth); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemsPerRow", (void*)InvWindow_GetItemsPerRow); + ccAddExternalFunctionForPlugin("InvWindow::get_RowCount", (void*)InvWindow_GetRowCount); + ccAddExternalFunctionForPlugin("InvWindow::get_TopItem", (void*)InvWindow_GetTopItem); + ccAddExternalFunctionForPlugin("InvWindow::set_TopItem", (void*)InvWindow_SetTopItem); +} diff --git a/engines/ags/engine/ac/invwindow.h b/engines/ags/engine/ac/invwindow.h new file mode 100644 index 000000000000..7c192b11a1a1 --- /dev/null +++ b/engines/ags/engine/ac/invwindow.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__INVWINDOW_H +#define __AGS_EE_AC__INVWINDOW_H + +#include "ac/characterinfo.h" +#include "ac/dynobj/scriptinvitem.h" +#include "gui/guiinv.h" + +using AGS::Common::GUIInvWindow; + +void InvWindow_SetCharacterToUse(GUIInvWindow *guii, CharacterInfo *chaa); +CharacterInfo* InvWindow_GetCharacterToUse(GUIInvWindow *guii); +void InvWindow_SetItemWidth(GUIInvWindow *guii, int newwidth); +int InvWindow_GetItemWidth(GUIInvWindow *guii); +void InvWindow_SetItemHeight(GUIInvWindow *guii, int newhit); +int InvWindow_GetItemHeight(GUIInvWindow *guii); +void InvWindow_SetTopItem(GUIInvWindow *guii, int topitem); +int InvWindow_GetTopItem(GUIInvWindow *guii); +int InvWindow_GetItemsPerRow(GUIInvWindow *guii); +int InvWindow_GetItemCount(GUIInvWindow *guii); +int InvWindow_GetRowCount(GUIInvWindow *guii); +void InvWindow_ScrollDown(GUIInvWindow *guii); +void InvWindow_ScrollUp(GUIInvWindow *guii); +ScriptInvItem* InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index); + +//============================================================================= + +int offset_over_inv(GUIInvWindow *inv); +// NOTE: This function is valid for AGS 2.72 and lower +int invscreen(); + +#endif // __AGS_EE_AC__INVWINDOW_H diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp new file mode 100644 index 000000000000..ba6b0390a38b --- /dev/null +++ b/engines/ags/engine/ac/keycode.cpp @@ -0,0 +1,142 @@ + +#include "ac/keycode.h" + +#include + +int GetKeyForKeyPressCb(int keycode) +{ + // lower case 'a'..'z' do not exist as keycodes, only ascii. 'A'..'Z' do though! + return (keycode >= 'a' && keycode <= 'z') ? keycode - 32 : keycode; +} + +int PlatformKeyFromAgsKey(int key) +{ + int platformKey = -1; + + switch (key) { + // ctrl-[A-Z] keys are numbered 1-26 for A-Z + case eAGSKeyCodeCtrlA: platformKey = 1; break; + case eAGSKeyCodeCtrlB: platformKey = 2; break; + case eAGSKeyCodeCtrlC: platformKey = 3; break; + case eAGSKeyCodeCtrlD: platformKey = 4; break; + case eAGSKeyCodeCtrlE: platformKey = 5; break; + case eAGSKeyCodeCtrlF: platformKey = 6; break; + case eAGSKeyCodeCtrlG: platformKey = 7; break; + // case eAGSKeyCodeCtrlH: // overlap with backspace + // case eAGSKeyCodeCtrlI: // overlap with tab + case eAGSKeyCodeCtrlJ: platformKey = 10; break; + case eAGSKeyCodeCtrlK: platformKey = 11; break; + case eAGSKeyCodeCtrlL: platformKey = 12; break; + // case eAGSKeyCodeCtrlM: // overlap with return + case eAGSKeyCodeCtrlN: platformKey = 14; break; + case eAGSKeyCodeCtrlO: platformKey = 15; break; + case eAGSKeyCodeCtrlP: platformKey = 16; break; + case eAGSKeyCodeCtrlQ: platformKey = 17; break; + case eAGSKeyCodeCtrlR: platformKey = 18; break; + case eAGSKeyCodeCtrlS: platformKey = 19; break; + case eAGSKeyCodeCtrlT: platformKey = 20; break; + case eAGSKeyCodeCtrlU: platformKey = 21; break; + case eAGSKeyCodeCtrlV: platformKey = 22; break; + case eAGSKeyCodeCtrlW: platformKey = 23; break; + case eAGSKeyCodeCtrlX: platformKey = 24; break; + case eAGSKeyCodeCtrlY: platformKey = 25; break; + case eAGSKeyCodeCtrlZ: platformKey = 26; break; + + case eAGSKeyCodeBackspace: platformKey = (__allegro_KEY_BACKSPACE << 8) | 8; break; + case eAGSKeyCodeTab: platformKey = (__allegro_KEY_TAB << 8) | 9; break; + case eAGSKeyCodeReturn: platformKey = (__allegro_KEY_ENTER << 8) | 13; break; + case eAGSKeyCodeEscape: platformKey = (__allegro_KEY_ESC << 8) | 27; break; + case eAGSKeyCodeSpace: platformKey = (__allegro_KEY_SPACE << 8) | ' '; break; + case eAGSKeyCodeExclamationMark: platformKey = '!'; break; + case eAGSKeyCodeDoubleQuote: platformKey = '"'; break; + case eAGSKeyCodeHash: platformKey = '#'; break; + case eAGSKeyCodeDollar: platformKey = '$'; break; + case eAGSKeyCodePercent: platformKey = '%'; break; + case eAGSKeyCodeAmpersand: platformKey = '&'; break; + case eAGSKeyCodeSingleQuote: platformKey = '\''; break; + case eAGSKeyCodeOpenParenthesis: platformKey = '('; break; + case eAGSKeyCodeCloseParenthesis: platformKey = ')'; break; + case eAGSKeyCodeAsterisk: platformKey = '*'; break; + case eAGSKeyCodePlus: platformKey = '+'; break; + case eAGSKeyCodeComma: platformKey = ','; break; + case eAGSKeyCodeHyphen: platformKey = '-'; break; + case eAGSKeyCodePeriod: platformKey = '.'; break; + case eAGSKeyCodeForwardSlash: platformKey = '/'; break; + case eAGSKeyCodeColon: platformKey = ':'; break; + case eAGSKeyCodeSemiColon: platformKey = ';'; break; + case eAGSKeyCodeLessThan: platformKey = '<'; break; + case eAGSKeyCodeEquals: platformKey = '='; break; + case eAGSKeyCodeGreaterThan: platformKey = '>'; break; + case eAGSKeyCodeQuestionMark: platformKey = '?'; break; + case eAGSKeyCodeAt: platformKey = '@'; break; + case eAGSKeyCodeOpenBracket: platformKey = '['; break; + case eAGSKeyCodeBackSlash: platformKey = '\\'; break; + case eAGSKeyCodeCloseBracket: platformKey = ']'; break; + case eAGSKeyCodeUnderscore: platformKey = '_'; break; + + case eAGSKeyCode0: platformKey = (__allegro_KEY_0 << 8) | '0'; break; + case eAGSKeyCode1: platformKey = (__allegro_KEY_1 << 8) | '1'; break; + case eAGSKeyCode2: platformKey = (__allegro_KEY_2 << 8) | '2'; break; + case eAGSKeyCode3: platformKey = (__allegro_KEY_3 << 8) | '3'; break; + case eAGSKeyCode4: platformKey = (__allegro_KEY_4 << 8) | '4'; break; + case eAGSKeyCode5: platformKey = (__allegro_KEY_5 << 8) | '5'; break; + case eAGSKeyCode6: platformKey = (__allegro_KEY_6 << 8) | '6'; break; + case eAGSKeyCode7: platformKey = (__allegro_KEY_7 << 8) | '7'; break; + case eAGSKeyCode8: platformKey = (__allegro_KEY_8 << 8) | '8'; break; + case eAGSKeyCode9: platformKey = (__allegro_KEY_9 << 8) | '9'; break; + + case eAGSKeyCodeA: platformKey = (__allegro_KEY_A << 8) | 'a'; break; + case eAGSKeyCodeB: platformKey = (__allegro_KEY_B << 8) | 'b'; break; + case eAGSKeyCodeC: platformKey = (__allegro_KEY_C << 8) | 'c'; break; + case eAGSKeyCodeD: platformKey = (__allegro_KEY_D << 8) | 'd'; break; + case eAGSKeyCodeE: platformKey = (__allegro_KEY_E << 8) | 'e'; break; + case eAGSKeyCodeF: platformKey = (__allegro_KEY_F << 8) | 'f'; break; + case eAGSKeyCodeG: platformKey = (__allegro_KEY_G << 8) | 'g'; break; + case eAGSKeyCodeH: platformKey = (__allegro_KEY_H << 8) | 'h'; break; + case eAGSKeyCodeI: platformKey = (__allegro_KEY_I << 8) | 'i'; break; + case eAGSKeyCodeJ: platformKey = (__allegro_KEY_J << 8) | 'j'; break; + case eAGSKeyCodeK: platformKey = (__allegro_KEY_K << 8) | 'k'; break; + case eAGSKeyCodeL: platformKey = (__allegro_KEY_L << 8) | 'l'; break; + case eAGSKeyCodeM: platformKey = (__allegro_KEY_M << 8) | 'm'; break; + case eAGSKeyCodeN: platformKey = (__allegro_KEY_N << 8) | 'n'; break; + case eAGSKeyCodeO: platformKey = (__allegro_KEY_O << 8) | 'o'; break; + case eAGSKeyCodeP: platformKey = (__allegro_KEY_P << 8) | 'p'; break; + case eAGSKeyCodeQ: platformKey = (__allegro_KEY_Q << 8) | 'q'; break; + case eAGSKeyCodeR: platformKey = (__allegro_KEY_R << 8) | 'r'; break; + case eAGSKeyCodeS: platformKey = (__allegro_KEY_S << 8) | 's'; break; + case eAGSKeyCodeT: platformKey = (__allegro_KEY_T << 8) | 't'; break; + case eAGSKeyCodeU: platformKey = (__allegro_KEY_U << 8) | 'u'; break; + case eAGSKeyCodeV: platformKey = (__allegro_KEY_V << 8) | 'v'; break; + case eAGSKeyCodeW: platformKey = (__allegro_KEY_W << 8) | 'w'; break; + case eAGSKeyCodeX: platformKey = (__allegro_KEY_X << 8) | 'x'; break; + case eAGSKeyCodeY: platformKey = (__allegro_KEY_Y << 8) | 'y'; break; + case eAGSKeyCodeZ: platformKey = (__allegro_KEY_Z << 8) | 'z'; break; + + case eAGSKeyCodeF1: platformKey = __allegro_KEY_F1 << 8; break; + case eAGSKeyCodeF2: platformKey = __allegro_KEY_F2 << 8; break; + case eAGSKeyCodeF3: platformKey = __allegro_KEY_F3 << 8; break; + case eAGSKeyCodeF4: platformKey = __allegro_KEY_F4 << 8; break; + case eAGSKeyCodeF5: platformKey = __allegro_KEY_F5 << 8; break; + case eAGSKeyCodeF6: platformKey = __allegro_KEY_F6 << 8; break; + case eAGSKeyCodeF7: platformKey = __allegro_KEY_F7 << 8; break; + case eAGSKeyCodeF8: platformKey = __allegro_KEY_F8 << 8; break; + case eAGSKeyCodeF9: platformKey = __allegro_KEY_F9 << 8; break; + case eAGSKeyCodeF10: platformKey = __allegro_KEY_F10 << 8; break; + case eAGSKeyCodeF11: platformKey = __allegro_KEY_F11 << 8; break; + case eAGSKeyCodeF12: platformKey = __allegro_KEY_F12 << 8; break; + + case eAGSKeyCodeHome: platformKey = __allegro_KEY_HOME << 8; break; + case eAGSKeyCodeUpArrow: platformKey = __allegro_KEY_UP << 8; break; + case eAGSKeyCodePageUp: platformKey = __allegro_KEY_PGUP << 8; break; + case eAGSKeyCodeLeftArrow: platformKey = __allegro_KEY_LEFT << 8; break; + case eAGSKeyCodeNumPad5: platformKey = __allegro_KEY_5_PAD << 8; break; + case eAGSKeyCodeRightArrow: platformKey = __allegro_KEY_RIGHT << 8; break; + case eAGSKeyCodeEnd: platformKey = __allegro_KEY_END << 8; break; + case eAGSKeyCodeDownArrow: platformKey = __allegro_KEY_DOWN << 8; break; + case eAGSKeyCodePageDown: platformKey = __allegro_KEY_PGDN << 8; break; + case eAGSKeyCodeInsert: platformKey = __allegro_KEY_INSERT << 8; break; + case eAGSKeyCodeDelete: platformKey = __allegro_KEY_DEL << 8; break; + } + + return platformKey; +} diff --git a/engines/ags/engine/ac/keycode.h b/engines/ags/engine/ac/keycode.h new file mode 100644 index 000000000000..f2df0ac3b025 --- /dev/null +++ b/engines/ags/engine/ac/keycode.h @@ -0,0 +1,175 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__KEYCODE_H +#define __AGS_EE_AC__KEYCODE_H + +#include "core/platform.h" + +#define EXTENDED_KEY_CODE ('\0') +#define EXTENDED_KEY_CODE_MACOS ('?') + +#define AGS_EXT_KEY_SHIFT 300 + +// These are based on values in agsdefn.sh +enum eAGSKeyCode +{ + eAGSKeyCodeNone = 0, + + eAGSKeyCodeCtrlA = 1, + eAGSKeyCodeCtrlB = 2, + eAGSKeyCodeCtrlC = 3, + eAGSKeyCodeCtrlD = 4, + eAGSKeyCodeCtrlE = 5, + eAGSKeyCodeCtrlF = 6, + eAGSKeyCodeCtrlG = 7, + eAGSKeyCodeCtrlH = 8, + eAGSKeyCodeCtrlI = 9, + eAGSKeyCodeCtrlJ = 10, + eAGSKeyCodeCtrlK = 11, + eAGSKeyCodeCtrlL = 12, + eAGSKeyCodeCtrlM = 13, + eAGSKeyCodeCtrlN = 14, + eAGSKeyCodeCtrlO = 15, + eAGSKeyCodeCtrlP = 16, + eAGSKeyCodeCtrlQ = 17, + eAGSKeyCodeCtrlR = 18, + eAGSKeyCodeCtrlS = 19, + eAGSKeyCodeCtrlT = 20, + eAGSKeyCodeCtrlU = 21, + eAGSKeyCodeCtrlV = 22, + eAGSKeyCodeCtrlW = 23, + eAGSKeyCodeCtrlX = 24, + eAGSKeyCodeCtrlY = 25, + eAGSKeyCodeCtrlZ = 26, + + eAGSKeyCodeBackspace = 8, + eAGSKeyCodeTab = 9, + eAGSKeyCodeReturn = 13, + eAGSKeyCodeEscape = 27, + eAGSKeyCodeSpace = 32, + eAGSKeyCodeExclamationMark = 33, + eAGSKeyCodeDoubleQuote = 34, + eAGSKeyCodeHash = 35, + eAGSKeyCodeDollar = 36, + eAGSKeyCodePercent = 37, + eAGSKeyCodeAmpersand = 38, + eAGSKeyCodeSingleQuote = 39, + eAGSKeyCodeOpenParenthesis = 40, + eAGSKeyCodeCloseParenthesis = 41, + eAGSKeyCodeAsterisk = 42, + eAGSKeyCodePlus = 43, + eAGSKeyCodeComma = 44, + eAGSKeyCodeHyphen = 45, + eAGSKeyCodePeriod = 46, + eAGSKeyCodeForwardSlash = 47, + eAGSKeyCodeColon = 58, + eAGSKeyCodeSemiColon = 59, + eAGSKeyCodeLessThan = 60, + eAGSKeyCodeEquals = 61, + eAGSKeyCodeGreaterThan = 62, + eAGSKeyCodeQuestionMark = 63, + eAGSKeyCodeAt = 64, + eAGSKeyCodeOpenBracket = 91, + eAGSKeyCodeBackSlash = 92, + eAGSKeyCodeCloseBracket = 93, + eAGSKeyCodeUnderscore = 95, + + eAGSKeyCode0 = 48, + eAGSKeyCode1 = 49, + eAGSKeyCode2 = 50, + eAGSKeyCode3 = 51, + eAGSKeyCode4 = 52, + eAGSKeyCode5 = 53, + eAGSKeyCode6 = 54, + eAGSKeyCode7 = 55, + eAGSKeyCode8 = 56, + eAGSKeyCode9 = 57, + + eAGSKeyCodeA = 65, + eAGSKeyCodeB = 66, + eAGSKeyCodeC = 67, + eAGSKeyCodeD = 68, + eAGSKeyCodeE = 69, + eAGSKeyCodeF = 70, + eAGSKeyCodeG = 71, + eAGSKeyCodeH = 72, + eAGSKeyCodeI = 73, + eAGSKeyCodeJ = 74, + eAGSKeyCodeK = 75, + eAGSKeyCodeL = 76, + eAGSKeyCodeM = 77, + eAGSKeyCodeN = 78, + eAGSKeyCodeO = 79, + eAGSKeyCodeP = 80, + eAGSKeyCodeQ = 81, + eAGSKeyCodeR = 82, + eAGSKeyCodeS = 83, + eAGSKeyCodeT = 84, + eAGSKeyCodeU = 85, + eAGSKeyCodeV = 86, + eAGSKeyCodeW = 87, + eAGSKeyCodeX = 88, + eAGSKeyCodeY = 89, + eAGSKeyCodeZ = 90, + + eAGSKeyCodeF1 = AGS_EXT_KEY_SHIFT + 59, + eAGSKeyCodeF2 = AGS_EXT_KEY_SHIFT + 60, + eAGSKeyCodeF3 = AGS_EXT_KEY_SHIFT + 61, + eAGSKeyCodeF4 = AGS_EXT_KEY_SHIFT + 62, + eAGSKeyCodeF5 = AGS_EXT_KEY_SHIFT + 63, + eAGSKeyCodeF6 = AGS_EXT_KEY_SHIFT + 64, + eAGSKeyCodeF7 = AGS_EXT_KEY_SHIFT + 65, + eAGSKeyCodeF8 = AGS_EXT_KEY_SHIFT + 66, + eAGSKeyCodeF9 = AGS_EXT_KEY_SHIFT + 67, + eAGSKeyCodeF10 = AGS_EXT_KEY_SHIFT + 68, + eAGSKeyCodeF11 = AGS_EXT_KEY_SHIFT + 133, + eAGSKeyCodeF12 = AGS_EXT_KEY_SHIFT + 134, + + eAGSKeyCodeHome = AGS_EXT_KEY_SHIFT + 71, + eAGSKeyCodeUpArrow = AGS_EXT_KEY_SHIFT + 72, + eAGSKeyCodePageUp = AGS_EXT_KEY_SHIFT + 73, + eAGSKeyCodeLeftArrow = AGS_EXT_KEY_SHIFT + 75, + eAGSKeyCodeNumPad5 = AGS_EXT_KEY_SHIFT + 76, + eAGSKeyCodeRightArrow = AGS_EXT_KEY_SHIFT + 77, + eAGSKeyCodeEnd = AGS_EXT_KEY_SHIFT + 79, + eAGSKeyCodeDownArrow = AGS_EXT_KEY_SHIFT + 80, + eAGSKeyCodePageDown = AGS_EXT_KEY_SHIFT + 81, + eAGSKeyCodeInsert = AGS_EXT_KEY_SHIFT + 82, + eAGSKeyCodeDelete = AGS_EXT_KEY_SHIFT + 83, + + eAGSKeyCodeAltTab = AGS_EXT_KEY_SHIFT + 99, + + // These are only used by debugging and abort keys. + // They're based on allegro4 codes so I won't expand here. + eAGSKeyCodeAltV = 322, + eAGSKeyCodeAltX = 324 +}; + +#define AGS_KEYCODE_INSERT (eAGSKeyCodeInsert) +#define AGS_KEYCODE_DELETE (eAGSKeyCodeDelete) +#define AGS_KEYCODE_ALT_TAB (eAGSKeyCodeAltTab) +#define READKEY_CODE_ALT_TAB 0x4000 + +// Gets a key code for "on_key_press" script callback +int GetKeyForKeyPressCb(int keycode); + +// Allegro4 "platform" keycode from an AGS keycode. +// Returns -1 if not found. +int PlatformKeyFromAgsKey(int key); + +#endif // __AGS_EE_AC__KEYCODE_H diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp new file mode 100644 index 000000000000..d7d61850bc0c --- /dev/null +++ b/engines/ags/engine/ac/label.cpp @@ -0,0 +1,172 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/label.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_translation.h" +#include "ac/string.h" + +extern GameSetupStruct game; + +// ** LABEL FUNCTIONS + +const char* Label_GetText_New(GUILabel *labl) { + return CreateNewScriptString(labl->GetText()); +} + +void Label_GetText(GUILabel *labl, char *buffer) { + strcpy(buffer, labl->GetText()); +} + +void Label_SetText(GUILabel *labl, const char *newtx) { + newtx = get_translation(newtx); + + if (strcmp(labl->GetText(), newtx)) { + guis_need_update = 1; + labl->SetText(newtx); + } +} + +int Label_GetTextAlignment(GUILabel *labl) +{ + return labl->TextAlignment; +} + +void Label_SetTextAlignment(GUILabel *labl, int align) +{ + if (labl->TextAlignment != align) { + labl->TextAlignment = (HorAlignment)align; + guis_need_update = 1; + } +} + +int Label_GetColor(GUILabel *labl) { + return labl->TextColor; +} + +void Label_SetColor(GUILabel *labl, int colr) { + if (labl->TextColor != colr) { + labl->TextColor = colr; + guis_need_update = 1; + } +} + +int Label_GetFont(GUILabel *labl) { + return labl->Font; +} + +void Label_SetFont(GUILabel *guil, int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetLabelFont: invalid font number."); + + if (fontnum != guil->Font) { + guil->Font = fontnum; + guis_need_update = 1; + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// void (GUILabel *labl, char *buffer) +RuntimeScriptValue Sc_Label_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUILabel, Label_GetText, char); +} + +// void (GUILabel *labl, const char *newtx) +RuntimeScriptValue Sc_Label_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUILabel, Label_SetText, const char); +} + +RuntimeScriptValue Sc_Label_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUILabel, Label_GetTextAlignment); +} + +RuntimeScriptValue Sc_Label_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUILabel, Label_SetTextAlignment); +} + + +// int (GUILabel *labl) +RuntimeScriptValue Sc_Label_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUILabel, Label_GetFont); +} + +// void (GUILabel *guil, int fontnum) +RuntimeScriptValue Sc_Label_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUILabel, Label_SetFont); +} + +// const char* (GUILabel *labl) +RuntimeScriptValue Sc_Label_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUILabel, const char, myScriptStringImpl, Label_GetText_New); +} + +// int (GUILabel *labl) +RuntimeScriptValue Sc_Label_GetColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUILabel, Label_GetColor); +} + +// void (GUILabel *labl, int colr) +RuntimeScriptValue Sc_Label_SetColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUILabel, Label_SetColor); +} + + + +void RegisterLabelAPI() +{ + ccAddExternalObjectFunction("Label::GetText^1", Sc_Label_GetText); + ccAddExternalObjectFunction("Label::SetText^1", Sc_Label_SetText); + ccAddExternalObjectFunction("Label::get_TextAlignment", Sc_Label_GetTextAlignment); + ccAddExternalObjectFunction("Label::set_TextAlignment", Sc_Label_SetTextAlignment); + ccAddExternalObjectFunction("Label::get_Font", Sc_Label_GetFont); + ccAddExternalObjectFunction("Label::set_Font", Sc_Label_SetFont); + ccAddExternalObjectFunction("Label::get_Text", Sc_Label_GetText_New); + ccAddExternalObjectFunction("Label::set_Text", Sc_Label_SetText); + ccAddExternalObjectFunction("Label::get_TextColor", Sc_Label_GetColor); + ccAddExternalObjectFunction("Label::set_TextColor", Sc_Label_SetColor); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Label::GetText^1", (void*)Label_GetText); + ccAddExternalFunctionForPlugin("Label::SetText^1", (void*)Label_SetText); + ccAddExternalFunctionForPlugin("Label::get_Font", (void*)Label_GetFont); + ccAddExternalFunctionForPlugin("Label::set_Font", (void*)Label_SetFont); + ccAddExternalFunctionForPlugin("Label::get_Text", (void*)Label_GetText_New); + ccAddExternalFunctionForPlugin("Label::set_Text", (void*)Label_SetText); + ccAddExternalFunctionForPlugin("Label::get_TextColor", (void*)Label_GetColor); + ccAddExternalFunctionForPlugin("Label::set_TextColor", (void*)Label_SetColor); +} diff --git a/engines/ags/engine/ac/label.h b/engines/ags/engine/ac/label.h new file mode 100644 index 000000000000..684e4268cc32 --- /dev/null +++ b/engines/ags/engine/ac/label.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__LABEL_H +#define __AGS_EE_AC__LABEL_H + +#include "gui/guilabel.h" + +using AGS::Common::GUILabel; + +const char* Label_GetText_New(GUILabel *labl); +void Label_GetText(GUILabel *labl, char *buffer); +void Label_SetText(GUILabel *labl, const char *newtx); +int Label_GetColor(GUILabel *labl); +void Label_SetColor(GUILabel *labl, int colr); +int Label_GetFont(GUILabel *labl); +void Label_SetFont(GUILabel *guil, int fontnum); + +#endif // __AGS_EE_AC__LABEL_H diff --git a/engines/ags/engine/ac/lipsync.h b/engines/ags/engine/ac/lipsync.h new file mode 100644 index 000000000000..5272f5e11f04 --- /dev/null +++ b/engines/ags/engine/ac/lipsync.h @@ -0,0 +1,25 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_LIPSYNC_H +#define __AC_LIPSYNC_H + +struct SpeechLipSyncLine { + char filename[14]; + int *endtimeoffs; + short*frame; + short numPhonemes; +}; + +#endif // __AC_LIPSYNC_H \ No newline at end of file diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp new file mode 100644 index 000000000000..c6fe065c9b12 --- /dev/null +++ b/engines/ags/engine/ac/listbox.cpp @@ -0,0 +1,674 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/listbox.h" +#include "ac/common.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_game.h" +#include "ac/path_helper.h" +#include "ac/string.h" +#include "gui/guimain.h" +#include "debug/debug_log.h" + +using namespace AGS::Common; + +extern GameState play; +extern GameSetupStruct game; + +// *** LIST BOX FUNCTIONS + +int ListBox_AddItem(GUIListBox *lbb, const char *text) { + if (lbb->AddItem(text) < 0) + return 0; + + guis_need_update = 1; + return 1; +} + +int ListBox_InsertItemAt(GUIListBox *lbb, int index, const char *text) { + if (lbb->InsertItem(index, text) < 0) + return 0; + + guis_need_update = 1; + return 1; +} + +void ListBox_Clear(GUIListBox *listbox) { + listbox->Clear(); + guis_need_update = 1; +} + +void FillDirList(std::set &files, const String &path) +{ + al_ffblk dfb; + int dun = al_findfirst(path, &dfb, FA_SEARCH); + while (!dun) { + files.insert(dfb.name); + dun = al_findnext(&dfb); + } + al_findclose(&dfb); +} + +void ListBox_FillDirList(GUIListBox *listbox, const char *filemask) { + listbox->Clear(); + guis_need_update = 1; + + ResolvedPath rp; + if (!ResolveScriptPath(filemask, true, rp)) + return; + + std::set files; + FillDirList(files, rp.FullPath); + if (!rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) + FillDirList(files, rp.AltPath); + + for (std::set::const_iterator it = files.begin(); it != files.end(); ++it) + { + listbox->AddItem(*it); + } +} + +int ListBox_GetSaveGameSlots(GUIListBox *listbox, int index) { + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBox.SaveGameSlot: index out of range"); + + return listbox->SavedGameIndex[index]; +} + +int ListBox_FillSaveGameList(GUIListBox *listbox) { + listbox->Clear(); + + int numsaves=0; + int bufix=0; + al_ffblk ffb; + long filedates[MAXSAVEGAMES]; + char buff[200]; + + String svg_dir = get_save_game_directory(); + String searchPath = String::FromFormat("%s""agssave.*", svg_dir.GetCStr()); + + int don = al_findfirst(searchPath, &ffb, FA_SEARCH); + while (!don) { + bufix=0; + if (numsaves >= MAXSAVEGAMES) + break; + // only list games .000 to .099 (to allow higher slots for other perposes) + if (strstr(ffb.name,".0")==nullptr) { + don = al_findnext(&ffb); + continue; + } + const char *numberExtension = strstr(ffb.name, ".0") + 1; + int saveGameSlot = atoi(numberExtension); + GetSaveSlotDescription(saveGameSlot, buff); + listbox->AddItem(buff); + listbox->SavedGameIndex[numsaves] = saveGameSlot; + filedates[numsaves]=(long int)ffb.time; + numsaves++; + don = al_findnext(&ffb); + } + al_findclose(&ffb); + + int nn; + for (nn=0;nnItems[kk]; + listbox->Items[kk] = listbox->Items[kk+1]; + listbox->Items[kk+1] = tempptr; + int numtem = listbox->SavedGameIndex[kk]; + listbox->SavedGameIndex[kk] = listbox->SavedGameIndex[kk+1]; + listbox->SavedGameIndex[kk+1] = numtem; + long numted=filedates[kk]; filedates[kk]=filedates[kk+1]; + filedates[kk+1]=numted; + } + } + } + + // update the global savegameindex[] array for backward compatibilty + for (nn = 0; nn < numsaves; nn++) { + play.filenumbers[nn] = listbox->SavedGameIndex[nn]; + } + + guis_need_update = 1; + listbox->SetSvgIndex(true); + + if (numsaves >= MAXSAVEGAMES) + return 1; + return 0; +} + +int ListBox_GetItemAtLocation(GUIListBox *listbox, int x, int y) { + + if (!guis[listbox->ParentId].IsDisplayed()) + return -1; + + data_to_game_coords(&x, &y); + x = (x - listbox->X) - guis[listbox->ParentId].X; + y = (y - listbox->Y) - guis[listbox->ParentId].Y; + + if ((x < 0) || (y < 0) || (x >= listbox->Width) || (y >= listbox->Height)) + return -1; + + return listbox->GetItemAt(x, y); +} + +char *ListBox_GetItemText(GUIListBox *listbox, int index, char *buffer) { + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBoxGetItemText: invalid item specified"); + strncpy(buffer, listbox->Items[index],198); + buffer[199] = 0; + return buffer; +} + +const char* ListBox_GetItems(GUIListBox *listbox, int index) { + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBox.Items: invalid index specified"); + + return CreateNewScriptString(listbox->Items[index]); +} + +void ListBox_SetItemText(GUIListBox *listbox, int index, const char *newtext) { + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBoxSetItemText: invalid item specified"); + + if (strcmp(listbox->Items[index], newtext)) { + listbox->SetItemText(index, newtext); + guis_need_update = 1; + } +} + +void ListBox_RemoveItem(GUIListBox *listbox, int itemIndex) { + + if ((itemIndex < 0) || (itemIndex >= listbox->ItemCount)) + quit("!ListBoxRemove: invalid listindex specified"); + + listbox->RemoveItem(itemIndex); + guis_need_update = 1; +} + +int ListBox_GetItemCount(GUIListBox *listbox) { + return listbox->ItemCount; +} + +int ListBox_GetFont(GUIListBox *listbox) { + return listbox->Font; +} + +void ListBox_SetFont(GUIListBox *listbox, int newfont) { + + if ((newfont < 0) || (newfont >= game.numfonts)) + quit("!ListBox.Font: invalid font number."); + + if (newfont != listbox->Font) { + listbox->SetFont(newfont); + guis_need_update = 1; + } + +} + +bool ListBox_GetShowBorder(GUIListBox *listbox) { + return listbox->IsBorderShown(); +} + +void ListBox_SetShowBorder(GUIListBox *listbox, bool newValue) { + if (listbox->IsBorderShown() != newValue) + { + listbox->SetShowBorder(newValue); + guis_need_update = 1; + } +} + +bool ListBox_GetShowScrollArrows(GUIListBox *listbox) { + return listbox->AreArrowsShown(); +} + +void ListBox_SetShowScrollArrows(GUIListBox *listbox, bool newValue) { + if (listbox->AreArrowsShown() != newValue) + { + listbox->SetShowArrows(newValue); + guis_need_update = 1; + } +} + +int ListBox_GetHideBorder(GUIListBox *listbox) { + return !ListBox_GetShowBorder(listbox); +} + +void ListBox_SetHideBorder(GUIListBox *listbox, int newValue) { + ListBox_SetShowBorder(listbox, !newValue); +} + +int ListBox_GetHideScrollArrows(GUIListBox *listbox) { + return !ListBox_GetShowScrollArrows(listbox); +} + +void ListBox_SetHideScrollArrows(GUIListBox *listbox, int newValue) { + ListBox_SetShowScrollArrows(listbox, !newValue); +} + +int ListBox_GetSelectedBackColor(GUIListBox *listbox) { + return listbox->SelectedBgColor; +} + +void ListBox_SetSelectedBackColor(GUIListBox *listbox, int colr) { + if (listbox->SelectedBgColor != colr) { + listbox->SelectedBgColor = colr; + guis_need_update = 1; + } +} + +int ListBox_GetSelectedTextColor(GUIListBox *listbox) { + return listbox->SelectedTextColor; +} + +void ListBox_SetSelectedTextColor(GUIListBox *listbox, int colr) { + if (listbox->SelectedTextColor != colr) { + listbox->SelectedTextColor = colr; + guis_need_update = 1; + } +} + +int ListBox_GetTextAlignment(GUIListBox *listbox) { + return listbox->TextAlignment; +} + +void ListBox_SetTextAlignment(GUIListBox *listbox, int align) { + if (listbox->TextAlignment != align) { + listbox->TextAlignment = (HorAlignment)align; + guis_need_update = 1; + } +} + +int ListBox_GetTextColor(GUIListBox *listbox) { + return listbox->TextColor; +} + +void ListBox_SetTextColor(GUIListBox *listbox, int colr) { + if (listbox->TextColor != colr) { + listbox->TextColor = colr; + guis_need_update = 1; + } +} + +int ListBox_GetSelectedIndex(GUIListBox *listbox) { + if ((listbox->SelectedItem < 0) || (listbox->SelectedItem >= listbox->ItemCount)) + return -1; + return listbox->SelectedItem; +} + +void ListBox_SetSelectedIndex(GUIListBox *guisl, int newsel) { + + if (newsel >= guisl->ItemCount) + newsel = -1; + + if (guisl->SelectedItem != newsel) { + guisl->SelectedItem = newsel; + if (newsel >= 0) { + if (newsel < guisl->TopItem) + guisl->TopItem = newsel; + if (newsel >= guisl->TopItem + guisl->VisibleItemCount) + guisl->TopItem = (newsel - guisl->VisibleItemCount) + 1; + } + guis_need_update = 1; + } + +} + +int ListBox_GetTopItem(GUIListBox *listbox) { + return listbox->TopItem; +} + +void ListBox_SetTopItem(GUIListBox *guisl, int item) { + if ((guisl->ItemCount == 0) && (item == 0)) + ; // allow resetting an empty box to the top + else if ((item >= guisl->ItemCount) || (item < 0)) + quit("!ListBoxSetTopItem: tried to set top to beyond top or bottom of list"); + + guisl->TopItem = item; + guis_need_update = 1; +} + +int ListBox_GetRowCount(GUIListBox *listbox) { + return listbox->VisibleItemCount; +} + +void ListBox_ScrollDown(GUIListBox *listbox) { + if (listbox->TopItem + listbox->VisibleItemCount < listbox->ItemCount) { + listbox->TopItem++; + guis_need_update = 1; + } +} + +void ListBox_ScrollUp(GUIListBox *listbox) { + if (listbox->TopItem > 0) { + listbox->TopItem--; + guis_need_update = 1; + } +} + + +GUIListBox* is_valid_listbox (int guin, int objn) { + if ((guin<0) | (guin>=game.numgui)) quit("!ListBox: invalid GUI number"); + if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!ListBox: invalid object number"); + if (guis[guin].GetControlType(objn)!=kGUIListBox) + quit("!ListBox: specified control is not a list box"); + guis_need_update = 1; + return (GUIListBox*)guis[guin].GetControl(objn); +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// int (GUIListBox *lbb, const char *text) +RuntimeScriptValue Sc_ListBox_AddItem(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(GUIListBox, ListBox_AddItem, const char); +} + +// void (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(GUIListBox, ListBox_Clear); +} + +// void (GUIListBox *listbox, const char *filemask) +RuntimeScriptValue Sc_ListBox_FillDirList(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUIListBox, ListBox_FillDirList, const char); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_FillSaveGameList(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_FillSaveGameList); +} + +// int (GUIListBox *listbox, int x, int y) +RuntimeScriptValue Sc_ListBox_GetItemAtLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT2(GUIListBox, ListBox_GetItemAtLocation); +} + +// char *(GUIListBox *listbox, int index, char *buffer) +RuntimeScriptValue Sc_ListBox_GetItemText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT_POBJ(GUIListBox, char, myScriptStringImpl, ListBox_GetItemText, char); +} + +// int (GUIListBox *lbb, int index, const char *text) +RuntimeScriptValue Sc_ListBox_InsertItemAt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT_POBJ(GUIListBox, ListBox_InsertItemAt, const char); +} + +// void (GUIListBox *listbox, int itemIndex) +RuntimeScriptValue Sc_ListBox_RemoveItem(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_RemoveItem); +} + +// void (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(GUIListBox, ListBox_ScrollDown); +} + +// void (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_ScrollUp(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(GUIListBox, ListBox_ScrollUp); +} + +// void (GUIListBox *listbox, int index, const char *newtext) +RuntimeScriptValue Sc_ListBox_SetItemText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT_POBJ(GUIListBox, ListBox_SetItemText, const char); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetFont); +} + +// void (GUIListBox *listbox, int newfont) +RuntimeScriptValue Sc_ListBox_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetFont); +} + +RuntimeScriptValue Sc_ListBox_GetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(GUIListBox, ListBox_GetShowBorder); +} + +RuntimeScriptValue Sc_ListBox_SetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PBOOL(GUIListBox, ListBox_SetShowBorder); +} + +RuntimeScriptValue Sc_ListBox_GetShowScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(GUIListBox, ListBox_GetShowScrollArrows); +} + +RuntimeScriptValue Sc_ListBox_SetShowScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PBOOL(GUIListBox, ListBox_SetShowScrollArrows); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_GetHideBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetHideBorder); +} + +// void (GUIListBox *listbox, int newValue) +RuntimeScriptValue Sc_ListBox_SetHideBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetHideBorder); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_GetHideScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetHideScrollArrows); +} + +// void (GUIListBox *listbox, int newValue) +RuntimeScriptValue Sc_ListBox_SetHideScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetHideScrollArrows); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetItemCount); +} + +// const char* (GUIListBox *listbox, int index) +RuntimeScriptValue Sc_ListBox_GetItems(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT(GUIListBox, const char, myScriptStringImpl, ListBox_GetItems); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_GetRowCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetRowCount); +} + +// int (GUIListBox *listbox, int index) +RuntimeScriptValue Sc_ListBox_GetSaveGameSlots(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(GUIListBox, ListBox_GetSaveGameSlots); +} + +RuntimeScriptValue Sc_ListBox_GetSelectedBackColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedBackColor); +} + +// void (GUIListBox *guisl, int newsel) +RuntimeScriptValue Sc_ListBox_SetSelectedBackColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedBackColor); +} + +RuntimeScriptValue Sc_ListBox_GetSelectedTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedTextColor); +} + +// void (GUIListBox *guisl, int newsel) +RuntimeScriptValue Sc_ListBox_SetSelectedTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedTextColor); +} + +RuntimeScriptValue Sc_ListBox_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetTextAlignment); +} + +// void (GUIListBox *guisl, int newsel) +RuntimeScriptValue Sc_ListBox_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTextAlignment); +} + +RuntimeScriptValue Sc_ListBox_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetTextColor); +} + +// void (GUIListBox *guisl, int newsel) +RuntimeScriptValue Sc_ListBox_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTextColor); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_GetSelectedIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedIndex); +} + +// void (GUIListBox *guisl, int newsel) +RuntimeScriptValue Sc_ListBox_SetSelectedIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedIndex); +} + +// int (GUIListBox *listbox) +RuntimeScriptValue Sc_ListBox_GetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUIListBox, ListBox_GetTopItem); +} + +// void (GUIListBox *guisl, int item) +RuntimeScriptValue Sc_ListBox_SetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTopItem); +} + + + +void RegisterListBoxAPI() +{ + ccAddExternalObjectFunction("ListBox::AddItem^1", Sc_ListBox_AddItem); + ccAddExternalObjectFunction("ListBox::Clear^0", Sc_ListBox_Clear); + ccAddExternalObjectFunction("ListBox::FillDirList^1", Sc_ListBox_FillDirList); + ccAddExternalObjectFunction("ListBox::FillSaveGameList^0", Sc_ListBox_FillSaveGameList); + ccAddExternalObjectFunction("ListBox::GetItemAtLocation^2", Sc_ListBox_GetItemAtLocation); + ccAddExternalObjectFunction("ListBox::GetItemText^2", Sc_ListBox_GetItemText); + ccAddExternalObjectFunction("ListBox::InsertItemAt^2", Sc_ListBox_InsertItemAt); + ccAddExternalObjectFunction("ListBox::RemoveItem^1", Sc_ListBox_RemoveItem); + ccAddExternalObjectFunction("ListBox::ScrollDown^0", Sc_ListBox_ScrollDown); + ccAddExternalObjectFunction("ListBox::ScrollUp^0", Sc_ListBox_ScrollUp); + ccAddExternalObjectFunction("ListBox::SetItemText^2", Sc_ListBox_SetItemText); + ccAddExternalObjectFunction("ListBox::get_Font", Sc_ListBox_GetFont); + ccAddExternalObjectFunction("ListBox::set_Font", Sc_ListBox_SetFont); + ccAddExternalObjectFunction("ListBox::get_ShowBorder", Sc_ListBox_GetShowBorder); + ccAddExternalObjectFunction("ListBox::set_ShowBorder", Sc_ListBox_SetShowBorder); + ccAddExternalObjectFunction("ListBox::get_ShowScrollArrows", Sc_ListBox_GetShowScrollArrows); + ccAddExternalObjectFunction("ListBox::set_ShowScrollArrows", Sc_ListBox_SetShowScrollArrows); + // old "inverted" properties + ccAddExternalObjectFunction("ListBox::get_HideBorder", Sc_ListBox_GetHideBorder); + ccAddExternalObjectFunction("ListBox::set_HideBorder", Sc_ListBox_SetHideBorder); + ccAddExternalObjectFunction("ListBox::get_HideScrollArrows", Sc_ListBox_GetHideScrollArrows); + ccAddExternalObjectFunction("ListBox::set_HideScrollArrows", Sc_ListBox_SetHideScrollArrows); + // + ccAddExternalObjectFunction("ListBox::get_ItemCount", Sc_ListBox_GetItemCount); + ccAddExternalObjectFunction("ListBox::geti_Items", Sc_ListBox_GetItems); + ccAddExternalObjectFunction("ListBox::seti_Items", Sc_ListBox_SetItemText); + ccAddExternalObjectFunction("ListBox::get_RowCount", Sc_ListBox_GetRowCount); + ccAddExternalObjectFunction("ListBox::geti_SaveGameSlots", Sc_ListBox_GetSaveGameSlots); + ccAddExternalObjectFunction("ListBox::get_SelectedBackColor", Sc_ListBox_GetSelectedBackColor); + ccAddExternalObjectFunction("ListBox::set_SelectedBackColor", Sc_ListBox_SetSelectedBackColor); + ccAddExternalObjectFunction("ListBox::get_SelectedIndex", Sc_ListBox_GetSelectedIndex); + ccAddExternalObjectFunction("ListBox::set_SelectedIndex", Sc_ListBox_SetSelectedIndex); + ccAddExternalObjectFunction("ListBox::get_SelectedTextColor", Sc_ListBox_GetSelectedTextColor); + ccAddExternalObjectFunction("ListBox::set_SelectedTextColor", Sc_ListBox_SetSelectedTextColor); + ccAddExternalObjectFunction("ListBox::get_TextAlignment", Sc_ListBox_GetTextAlignment); + ccAddExternalObjectFunction("ListBox::set_TextAlignment", Sc_ListBox_SetTextAlignment); + ccAddExternalObjectFunction("ListBox::get_TextColor", Sc_ListBox_GetTextColor); + ccAddExternalObjectFunction("ListBox::set_TextColor", Sc_ListBox_SetTextColor); + ccAddExternalObjectFunction("ListBox::get_TopItem", Sc_ListBox_GetTopItem); + ccAddExternalObjectFunction("ListBox::set_TopItem", Sc_ListBox_SetTopItem); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("ListBox::AddItem^1", (void*)ListBox_AddItem); + ccAddExternalFunctionForPlugin("ListBox::Clear^0", (void*)ListBox_Clear); + ccAddExternalFunctionForPlugin("ListBox::FillDirList^1", (void*)ListBox_FillDirList); + ccAddExternalFunctionForPlugin("ListBox::FillSaveGameList^0", (void*)ListBox_FillSaveGameList); + ccAddExternalFunctionForPlugin("ListBox::GetItemAtLocation^2", (void*)ListBox_GetItemAtLocation); + ccAddExternalFunctionForPlugin("ListBox::GetItemText^2", (void*)ListBox_GetItemText); + ccAddExternalFunctionForPlugin("ListBox::InsertItemAt^2", (void*)ListBox_InsertItemAt); + ccAddExternalFunctionForPlugin("ListBox::RemoveItem^1", (void*)ListBox_RemoveItem); + ccAddExternalFunctionForPlugin("ListBox::ScrollDown^0", (void*)ListBox_ScrollDown); + ccAddExternalFunctionForPlugin("ListBox::ScrollUp^0", (void*)ListBox_ScrollUp); + ccAddExternalFunctionForPlugin("ListBox::SetItemText^2", (void*)ListBox_SetItemText); + ccAddExternalFunctionForPlugin("ListBox::get_Font", (void*)ListBox_GetFont); + ccAddExternalFunctionForPlugin("ListBox::set_Font", (void*)ListBox_SetFont); + ccAddExternalFunctionForPlugin("ListBox::get_HideBorder", (void*)ListBox_GetHideBorder); + ccAddExternalFunctionForPlugin("ListBox::set_HideBorder", (void*)ListBox_SetHideBorder); + ccAddExternalFunctionForPlugin("ListBox::get_HideScrollArrows", (void*)ListBox_GetHideScrollArrows); + ccAddExternalFunctionForPlugin("ListBox::set_HideScrollArrows", (void*)ListBox_SetHideScrollArrows); + ccAddExternalFunctionForPlugin("ListBox::get_ItemCount", (void*)ListBox_GetItemCount); + ccAddExternalFunctionForPlugin("ListBox::geti_Items", (void*)ListBox_GetItems); + ccAddExternalFunctionForPlugin("ListBox::seti_Items", (void*)ListBox_SetItemText); + ccAddExternalFunctionForPlugin("ListBox::get_RowCount", (void*)ListBox_GetRowCount); + ccAddExternalFunctionForPlugin("ListBox::geti_SaveGameSlots", (void*)ListBox_GetSaveGameSlots); + ccAddExternalFunctionForPlugin("ListBox::get_SelectedIndex", (void*)ListBox_GetSelectedIndex); + ccAddExternalFunctionForPlugin("ListBox::set_SelectedIndex", (void*)ListBox_SetSelectedIndex); + ccAddExternalFunctionForPlugin("ListBox::get_TopItem", (void*)ListBox_GetTopItem); + ccAddExternalFunctionForPlugin("ListBox::set_TopItem", (void*)ListBox_SetTopItem); +} diff --git a/engines/ags/engine/ac/listbox.h b/engines/ags/engine/ac/listbox.h new file mode 100644 index 000000000000..24ba70af11a5 --- /dev/null +++ b/engines/ags/engine/ac/listbox.h @@ -0,0 +1,53 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__LISTBOX_H +#define __AGS_EE_AC__LISTBOX_H + +#include "gui/guilistbox.h" + +using AGS::Common::GUIListBox; + +int ListBox_AddItem(GUIListBox *lbb, const char *text); +int ListBox_InsertItemAt(GUIListBox *lbb, int index, const char *text); +void ListBox_Clear(GUIListBox *listbox); +void ListBox_FillDirList(GUIListBox *listbox, const char *filemask); +int ListBox_GetSaveGameSlots(GUIListBox *listbox, int index); +int ListBox_FillSaveGameList(GUIListBox *listbox); +int ListBox_GetItemAtLocation(GUIListBox *listbox, int x, int y); +char *ListBox_GetItemText(GUIListBox *listbox, int index, char *buffer); +const char* ListBox_GetItems(GUIListBox *listbox, int index); +void ListBox_SetItemText(GUIListBox *listbox, int index, const char *newtext); +void ListBox_RemoveItem(GUIListBox *listbox, int itemIndex); +int ListBox_GetItemCount(GUIListBox *listbox); +int ListBox_GetFont(GUIListBox *listbox); +void ListBox_SetFont(GUIListBox *listbox, int newfont); +int ListBox_GetHideBorder(GUIListBox *listbox); +void ListBox_SetHideBorder(GUIListBox *listbox, int newValue); +int ListBox_GetHideScrollArrows(GUIListBox *listbox); +void ListBox_SetHideScrollArrows(GUIListBox *listbox, int newValue); +int ListBox_GetSelectedIndex(GUIListBox *listbox); +void ListBox_SetSelectedIndex(GUIListBox *guisl, int newsel); +int ListBox_GetTopItem(GUIListBox *listbox); +void ListBox_SetTopItem(GUIListBox *guisl, int item); +int ListBox_GetRowCount(GUIListBox *listbox); +void ListBox_ScrollDown(GUIListBox *listbox); +void ListBox_ScrollUp(GUIListBox *listbox); + +GUIListBox* is_valid_listbox (int guin, int objn); + +#endif // __AGS_EE_AC__LISTBOX_H diff --git a/engines/ags/engine/ac/math.cpp b/engines/ags/engine/ac/math.cpp new file mode 100644 index 000000000000..5c81231643e5 --- /dev/null +++ b/engines/ags/engine/ac/math.cpp @@ -0,0 +1,318 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/math.h" +#include "ac/common.h" // quit +#include "util/math.h" + +int FloatToInt(float value, int roundDirection) +{ + if (value >= 0.0) { + if (roundDirection == eRoundDown) + return static_cast(value); + else if (roundDirection == eRoundNearest) + return static_cast(value + 0.5); + else if (roundDirection == eRoundUp) + return static_cast(value + 0.999999); + else + quit("!FloatToInt: invalid round direction"); + } + else { + // negative number + if (roundDirection == eRoundUp) + return static_cast(value); // this just truncates + else if (roundDirection == eRoundNearest) + return static_cast(value - 0.5); + else if (roundDirection == eRoundDown) + return static_cast(value - 0.999999); + else + quit("!FloatToInt: invalid round direction"); + } + return 0; +} + +float IntToFloat(int value) +{ + return static_cast(value); +} + +float StringToFloat(const char *theString) +{ + return static_cast(atof(theString)); +} + +float Math_Cos(float value) +{ + return cos(value); +} + +float Math_Sin(float value) +{ + return sin(value); +} + +float Math_Tan(float value) +{ + return tan(value); +} + +float Math_ArcCos(float value) +{ + return acos(value); +} + +float Math_ArcSin(float value) +{ + return asin(value); +} + +float Math_ArcTan(float value) +{ + return atan(value); +} + +float Math_ArcTan2(float yval, float xval) +{ + return atan2(yval, xval); +} + +float Math_Log(float value) +{ + return log(value); +} + +float Math_Log10(float value) +{ + return ::log10(value); +} + +float Math_Exp(float value) +{ + return exp(value); +} + +float Math_Cosh(float value) +{ + return cosh(value); +} + +float Math_Sinh(float value) +{ + return sinh(value); +} + +float Math_Tanh(float value) +{ + return tanh(value); +} + +float Math_RaiseToPower(float base, float exp) +{ + return ::pow(base, exp); +} + +float Math_DegreesToRadians(float value) +{ + return static_cast(value * (M_PI / 180.0)); +} + +float Math_RadiansToDegrees(float value) +{ + return static_cast(value * (180.0 / M_PI)); +} + +float Math_GetPi() +{ + return static_cast(M_PI); +} + +float Math_Sqrt(float value) +{ + if (value < 0.0) + quit("!Sqrt: cannot perform square root of negative number"); + + return ::sqrt(value); +} + +int __Rand(int upto) +{ + upto++; + if (upto < 1) + quit("!Random: invalid parameter passed -- must be at least 0."); + return rand()%upto; +} + + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// float (float value) +RuntimeScriptValue Sc_Math_ArcCos(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_ArcCos); +} + +// float (float value) +RuntimeScriptValue Sc_Math_ArcSin(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_ArcSin); +} + +// float (float value) +RuntimeScriptValue Sc_Math_ArcTan(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_ArcTan); +} + +// float (SCRIPT_FLOAT(yval), SCRIPT_FLOAT(xval)) +RuntimeScriptValue Sc_Math_ArcTan2(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT2(Math_ArcTan2); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Cos(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Cos); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Cosh(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Cosh); +} + +// float (float value) +RuntimeScriptValue Sc_Math_DegreesToRadians(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_DegreesToRadians); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Exp(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Exp); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Log(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Log); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Log10(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Log10); +} + +// float (float value) +RuntimeScriptValue Sc_Math_RadiansToDegrees(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_RadiansToDegrees); +} + +// float (SCRIPT_FLOAT(base), SCRIPT_FLOAT(exp)) +RuntimeScriptValue Sc_Math_RaiseToPower(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT2(Math_RaiseToPower); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Sin(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Sin); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Sinh(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Sinh); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Sqrt(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Sqrt); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Tan(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Tan); +} + +// float (float value) +RuntimeScriptValue Sc_Math_Tanh(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT_PFLOAT(Math_Tanh); +} + +// float () +RuntimeScriptValue Sc_Math_GetPi(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT(Math_GetPi); +} + + +void RegisterMathAPI() +{ + ccAddExternalStaticFunction("Maths::ArcCos^1", Sc_Math_ArcCos); + ccAddExternalStaticFunction("Maths::ArcSin^1", Sc_Math_ArcSin); + ccAddExternalStaticFunction("Maths::ArcTan^1", Sc_Math_ArcTan); + ccAddExternalStaticFunction("Maths::ArcTan2^2", Sc_Math_ArcTan2); + ccAddExternalStaticFunction("Maths::Cos^1", Sc_Math_Cos); + ccAddExternalStaticFunction("Maths::Cosh^1", Sc_Math_Cosh); + ccAddExternalStaticFunction("Maths::DegreesToRadians^1", Sc_Math_DegreesToRadians); + ccAddExternalStaticFunction("Maths::Exp^1", Sc_Math_Exp); + ccAddExternalStaticFunction("Maths::Log^1", Sc_Math_Log); + ccAddExternalStaticFunction("Maths::Log10^1", Sc_Math_Log10); + ccAddExternalStaticFunction("Maths::RadiansToDegrees^1", Sc_Math_RadiansToDegrees); + ccAddExternalStaticFunction("Maths::RaiseToPower^2", Sc_Math_RaiseToPower); + ccAddExternalStaticFunction("Maths::Sin^1", Sc_Math_Sin); + ccAddExternalStaticFunction("Maths::Sinh^1", Sc_Math_Sinh); + ccAddExternalStaticFunction("Maths::Sqrt^1", Sc_Math_Sqrt); + ccAddExternalStaticFunction("Maths::Tan^1", Sc_Math_Tan); + ccAddExternalStaticFunction("Maths::Tanh^1", Sc_Math_Tanh); + ccAddExternalStaticFunction("Maths::get_Pi", Sc_Math_GetPi); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Maths::ArcCos^1", (void*)Math_ArcCos); + ccAddExternalFunctionForPlugin("Maths::ArcSin^1", (void*)Math_ArcSin); + ccAddExternalFunctionForPlugin("Maths::ArcTan^1", (void*)Math_ArcTan); + ccAddExternalFunctionForPlugin("Maths::ArcTan2^2", (void*)Math_ArcTan2); + ccAddExternalFunctionForPlugin("Maths::Cos^1", (void*)Math_Cos); + ccAddExternalFunctionForPlugin("Maths::Cosh^1", (void*)Math_Cosh); + ccAddExternalFunctionForPlugin("Maths::DegreesToRadians^1", (void*)Math_DegreesToRadians); + ccAddExternalFunctionForPlugin("Maths::Exp^1", (void*)Math_Exp); + ccAddExternalFunctionForPlugin("Maths::Log^1", (void*)Math_Log); + ccAddExternalFunctionForPlugin("Maths::Log10^1", (void*)Math_Log10); + ccAddExternalFunctionForPlugin("Maths::RadiansToDegrees^1", (void*)Math_RadiansToDegrees); + ccAddExternalFunctionForPlugin("Maths::RaiseToPower^2", (void*)Math_RaiseToPower); + ccAddExternalFunctionForPlugin("Maths::Sin^1", (void*)Math_Sin); + ccAddExternalFunctionForPlugin("Maths::Sinh^1", (void*)Math_Sinh); + ccAddExternalFunctionForPlugin("Maths::Sqrt^1", (void*)Math_Sqrt); + ccAddExternalFunctionForPlugin("Maths::Tan^1", (void*)Math_Tan); + ccAddExternalFunctionForPlugin("Maths::Tanh^1", (void*)Math_Tanh); + ccAddExternalFunctionForPlugin("Maths::get_Pi", (void*)Math_GetPi); +} diff --git a/engines/ags/engine/ac/math.h b/engines/ags/engine/ac/math.h new file mode 100644 index 000000000000..872b445c5b47 --- /dev/null +++ b/engines/ags/engine/ac/math.h @@ -0,0 +1,55 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__MATH_H +#define __AGS_EE_AC__MATH_H + +#include "core/types.h" + +enum RoundDirections { + eRoundDown = 0, + eRoundNearest = 1, + eRoundUp = 2 +}; + + +int FloatToInt(float value, int roundDirection); +float IntToFloat(int value); +float StringToFloat(const char *theString); +float Math_Cos(float value); +float Math_Sin(float value); +float Math_Tan(float value); +float Math_ArcCos(float value); +float Math_ArcSin(float value); +float Math_ArcTan(float value); +float Math_ArcTan2(float yval, float xval); +float Math_Log(float value); +float Math_Log10(float value); +float Math_Exp(float value); +float Math_Cosh(float value); +float Math_Sinh(float value); +float Math_Tanh(float value); +float Math_RaiseToPower(float base, float exp); +float Math_DegreesToRadians(float value); +float Math_RadiansToDegrees(float value); +float Math_GetPi(); +float Math_Sqrt(float value); + +int __Rand(int upto); +#define Random __Rand + +#endif // __AGS_EE_AC__MATH_H diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp new file mode 100644 index 000000000000..eceb5e680ce5 --- /dev/null +++ b/engines/ags/engine/ac/mouse.cpp @@ -0,0 +1,664 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/mouse.h" +#include "ac/common.h" +#include "ac/characterinfo.h" +#include "ac/draw.h" +#include "ac/dynobj/scriptmouse.h" +#include "ac/dynobj/scriptsystem.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_mouse.h" +#include "ac/global_plugin.h" +#include "ac/global_screen.h" +#include "ac/system.h" +#include "ac/viewframe.h" +#include "debug/debug_log.h" +#include "gui/guibutton.h" +#include "gui/guimain.h" +#include "device/mousew32.h" +#include "ac/spritecache.h" +#include "gfx/graphicsdriver.h" +#include "gfx/gfxfilter.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameState play; +extern ScriptSystem scsystem; +extern Bitmap *mousecurs[MAXCURSORS]; +extern SpriteCache spriteset; +extern CharacterInfo*playerchar; +extern IGraphicsDriver *gfxDriver; + +extern void ags_domouse(int str); +extern int misbuttondown(int buno); + +ScriptMouse scmouse; +int cur_mode,cur_cursor; +int mouse_frame=0,mouse_delay=0; +int lastmx=-1,lastmy=-1; +char alpha_blend_cursor = 0; +Bitmap *dotted_mouse_cursor = nullptr; +IDriverDependantBitmap *mouseCursor = nullptr; +Bitmap *blank_mouse_cursor = nullptr; + +// The Mouse:: functions are static so the script doesn't pass +// in an object parameter +void Mouse_SetVisible(int isOn) { + if (isOn) + ShowMouseCursor(); + else + HideMouseCursor(); +} + +int Mouse_GetVisible() { + if (play.mouse_cursor_hidden) + return 0; + return 1; +} + +void SetMouseBounds(int x1, int y1, int x2, int y2) +{ + int xmax = game_to_data_coord(play.GetMainViewport().GetWidth()) - 1; + int ymax = game_to_data_coord(play.GetMainViewport().GetHeight()) - 1; + if ((x1 == 0) && (y1 == 0) && (x2 == 0) && (y2 == 0)) + { + x2 = xmax; + y2 = ymax; + } + else + { + if (x1 < 0 || x1 > xmax || x2 < 0 || x2 > xmax || x1 > x2 || y1 < 0 || y1 > ymax || y2 < 0 || y2 > ymax || y1 > y2) + debug_script_warn("SetMouseBounds: arguments are out of range and will be corrected: (%d,%d)-(%d,%d), range is (%d,%d)-(%d,%d)", + x1, y1, x2, y2, 0, 0, xmax, ymax); + x1 = Math::Clamp(x1, 0, xmax); + x2 = Math::Clamp(x2, x1, xmax); + y1 = Math::Clamp(y1, 0, ymax); + y2 = Math::Clamp(y2, y1, ymax); + } + + debug_script_log("Mouse bounds constrained to (%d,%d)-(%d,%d)", x1, y1, x2, y2); + data_to_game_coords(&x1, &y1); + data_to_game_round_up(&x2, &y2); + + play.mboundx1 = x1; + play.mboundx2 = x2; + play.mboundy1 = y1; + play.mboundy2 = y2; + Mouse::SetMoveLimit(Rect(x1, y1, x2, y2)); +} + +// mouse cursor functions: +// set_mouse_cursor: changes visual appearance to specified cursor +void set_mouse_cursor(int newcurs) { + const int hotspotx = game.mcurs[newcurs].hotx, hotspoty = game.mcurs[newcurs].hoty; + msethotspot(hotspotx, hotspoty); + + // if it's same cursor and there's animation in progress, then don't assign a new pic just yet + if (newcurs == cur_cursor && game.mcurs[newcurs].view >= 0 && + (mouse_frame > 0 || mouse_delay > 0)) + { + return; + } + + // reset animation timing only if it's another cursor + if (newcurs != cur_cursor) + { + cur_cursor = newcurs; + mouse_frame = 0; + mouse_delay = 0; + } + + // Assign new pic + set_new_cursor_graphic(game.mcurs[newcurs].pic); + delete dotted_mouse_cursor; + dotted_mouse_cursor = nullptr; + + // If it's inventory cursor, draw hotspot crosshair sprite upon it + if ((newcurs == MODE_USE) && (game.mcurs[newcurs].pic > 0) && + ((game.hotdot > 0) || (game.invhotdotsprite > 0)) ) { + // If necessary, create a copy of the cursor and put the hotspot + // dot onto it + dotted_mouse_cursor = BitmapHelper::CreateBitmapCopy(mousecurs[0]); + + if (game.invhotdotsprite > 0) { + draw_sprite_slot_support_alpha(dotted_mouse_cursor, + (game.SpriteInfos[game.mcurs[newcurs].pic].Flags & SPF_ALPHACHANNEL) != 0, + hotspotx - game.SpriteInfos[game.invhotdotsprite].Width / 2, + hotspoty - game.SpriteInfos[game.invhotdotsprite].Height / 2, + game.invhotdotsprite); + } + else { + putpixel_compensate (dotted_mouse_cursor, hotspotx, hotspoty, MakeColor(game.hotdot)); + + if (game.hotdotouter > 0) { + int outercol = MakeColor(game.hotdotouter); + + putpixel_compensate (dotted_mouse_cursor, hotspotx + get_fixed_pixel_size(1), hotspoty, outercol); + putpixel_compensate (dotted_mouse_cursor, hotspotx, hotspoty + get_fixed_pixel_size(1), outercol); + putpixel_compensate (dotted_mouse_cursor, hotspotx - get_fixed_pixel_size(1), hotspoty, outercol); + putpixel_compensate (dotted_mouse_cursor, hotspotx, hotspoty - get_fixed_pixel_size(1), outercol); + } + } + mousecurs[0] = dotted_mouse_cursor; + update_cached_mouse_cursor(); + } +} + +// set_default_cursor: resets visual appearance to current mode (walk, look, etc) +void set_default_cursor() { + set_mouse_cursor(cur_mode); +} + +// permanently change cursor graphic +void ChangeCursorGraphic (int curs, int newslot) { + if ((curs < 0) || (curs >= game.numcursors)) + quit("!ChangeCursorGraphic: invalid mouse cursor"); + + if ((curs == MODE_USE) && (game.options[OPT_FIXEDINVCURSOR] == 0)) + debug_script_warn("Mouse.ChangeModeGraphic should not be used on the Inventory cursor when the cursor is linked to the active inventory item"); + + game.mcurs[curs].pic = newslot; + spriteset.Precache(newslot); + if (curs == cur_mode) + set_mouse_cursor (curs); +} + +int Mouse_GetModeGraphic(int curs) { + if ((curs < 0) || (curs >= game.numcursors)) + quit("!Mouse.GetModeGraphic: invalid mouse cursor"); + + return game.mcurs[curs].pic; +} + +void ChangeCursorHotspot (int curs, int x, int y) { + if ((curs < 0) || (curs >= game.numcursors)) + quit("!ChangeCursorHotspot: invalid mouse cursor"); + game.mcurs[curs].hotx = data_to_game_coord(x); + game.mcurs[curs].hoty = data_to_game_coord(y); + if (curs == cur_cursor) + set_mouse_cursor (cur_cursor); +} + +void Mouse_ChangeModeView(int curs, int newview) { + if ((curs < 0) || (curs >= game.numcursors)) + quit("!Mouse.ChangeModeView: invalid mouse cursor"); + + newview--; + + game.mcurs[curs].view = newview; + + if (newview >= 0) + { + precache_view(newview); + } + + if (curs == cur_cursor) + mouse_delay = 0; // force update +} + +void SetNextCursor () { + set_cursor_mode (find_next_enabled_cursor(cur_mode + 1)); +} + +void SetPreviousCursor() { + set_cursor_mode(find_previous_enabled_cursor(cur_mode - 1)); +} + +// set_cursor_mode: changes mode and appearance +void set_cursor_mode(int newmode) { + if ((newmode < 0) || (newmode >= game.numcursors)) + quit("!SetCursorMode: invalid cursor mode specified"); + + guis_need_update = 1; + if (game.mcurs[newmode].flags & MCF_DISABLED) { + find_next_enabled_cursor(newmode); + return; } + if (newmode == MODE_USE) { + if (playerchar->activeinv == -1) { + find_next_enabled_cursor(0); + return; + } + update_inv_cursor(playerchar->activeinv); + } + cur_mode=newmode; + set_default_cursor(); + + debug_script_log("Cursor mode set to %d", newmode); +} + +void enable_cursor_mode(int modd) { + game.mcurs[modd].flags&=~MCF_DISABLED; + // now search the interfaces for related buttons to re-enable + int uu,ww; + + for (uu=0;uuClickAction[kMouseLeft]!=kGUIAction_SetMode) continue; + if (gbpt->ClickData[kMouseLeft]!=modd) continue; + gbpt->SetEnabled(true); + } + } + guis_need_update = 1; +} + +void disable_cursor_mode(int modd) { + game.mcurs[modd].flags|=MCF_DISABLED; + // now search the interfaces for related buttons to kill + int uu,ww; + + for (uu=0;uuClickAction[kMouseLeft]!=kGUIAction_SetMode) continue; + if (gbpt->ClickData[kMouseLeft]!=modd) continue; + gbpt->SetEnabled(false); + } + } + if (cur_mode==modd) find_next_enabled_cursor(modd); + guis_need_update = 1; +} + +void RefreshMouse() { + ags_domouse(DOMOUSE_NOCURSOR); + scmouse.x = game_to_data_coord(mousex); + scmouse.y = game_to_data_coord(mousey); +} + +void SetMousePosition (int newx, int newy) { + const Rect &viewport = play.GetMainViewport(); + + if (newx < 0) + newx = 0; + if (newy < 0) + newy = 0; + if (newx >= viewport.GetWidth()) + newx = viewport.GetWidth() - 1; + if (newy >= viewport.GetHeight()) + newy = viewport.GetHeight() - 1; + + data_to_game_coords(&newx, &newy); + Mouse::SetPosition(Point(newx, newy)); + RefreshMouse(); +} + +int GetCursorMode() { + return cur_mode; +} + +int IsButtonDown(int which) { + if ((which < 1) || (which > 3)) + quit("!IsButtonDown: only works with eMouseLeft, eMouseRight, eMouseMiddle"); + if (misbuttondown(which-1)) + return 1; + return 0; +} + +int IsModeEnabled(int which) { + return (which < 0) || (which >= game.numcursors) ? 0 : + which == MODE_USE ? playerchar->activeinv > 0 : + (game.mcurs[which].flags & MCF_DISABLED) == 0; +} + +void Mouse_EnableControl(bool on) +{ + usetup.mouse_ctrl_enabled = on; // remember setting in config + + bool is_windowed = scsystem.windowed != 0; + // Whether mouse movement should be controlled by the engine - this is + // determined based on related config option. + bool should_control_mouse = usetup.mouse_ctrl_when == kMouseCtrl_Always || + (usetup.mouse_ctrl_when == kMouseCtrl_Fullscreen && !is_windowed); + // Whether mouse movement control is supported by the engine - this is + // determined on per platform basis. Some builds may not have such + // capability, e.g. because of how backend library implements mouse utils. + bool can_control_mouse = platform->IsMouseControlSupported(is_windowed); + // The resulting choice is made based on two aforementioned factors. + on &= should_control_mouse && can_control_mouse; + if (on) + Mouse::EnableControl(!is_windowed); + else + Mouse::DisableControl(); +} + +//============================================================================= + +int GetMouseCursor() { + return cur_cursor; +} + +void update_script_mouse_coords() { + scmouse.x = game_to_data_coord(mousex); + scmouse.y = game_to_data_coord(mousey); +} + +void update_inv_cursor(int invnum) { + + if ((game.options[OPT_FIXEDINVCURSOR]==0) && (invnum > 0)) { + int cursorSprite = game.invinfo[invnum].cursorPic; + + // Fall back to the inventory pic if no cursor pic is defined. + if (cursorSprite == 0) + cursorSprite = game.invinfo[invnum].pic; + + game.mcurs[MODE_USE].pic = cursorSprite; + // all cursor images must be pre-cached + spriteset.Precache(cursorSprite); + + if ((game.invinfo[invnum].hotx > 0) || (game.invinfo[invnum].hoty > 0)) { + // if the hotspot was set (unfortunately 0,0 isn't a valid co-ord) + game.mcurs[MODE_USE].hotx=game.invinfo[invnum].hotx; + game.mcurs[MODE_USE].hoty=game.invinfo[invnum].hoty; + } + else { + game.mcurs[MODE_USE].hotx = game.SpriteInfos[cursorSprite].Width / 2; + game.mcurs[MODE_USE].hoty = game.SpriteInfos[cursorSprite].Height / 2; + } + } +} + +void update_cached_mouse_cursor() +{ + if (mouseCursor != nullptr) + gfxDriver->DestroyDDB(mouseCursor); + mouseCursor = gfxDriver->CreateDDBFromBitmap(mousecurs[0], alpha_blend_cursor != 0); +} + +void set_new_cursor_graphic (int spriteslot) { + mousecurs[0] = spriteset[spriteslot]; + + // It looks like spriteslot 0 can be used in games with version 2.72 and lower. + // The NULL check should ensure that the sprite is valid anyway. + if (((spriteslot < 1) && (loaded_game_file_version > kGameVersion_272)) || (mousecurs[0] == nullptr)) + { + if (blank_mouse_cursor == nullptr) + { + blank_mouse_cursor = BitmapHelper::CreateTransparentBitmap(1, 1, game.GetColorDepth()); + } + mousecurs[0] = blank_mouse_cursor; + } + + if (game.SpriteInfos[spriteslot].Flags & SPF_ALPHACHANNEL) + alpha_blend_cursor = 1; + else + alpha_blend_cursor = 0; + + update_cached_mouse_cursor(); +} + +bool is_standard_cursor_enabled(int curs) { + if ((game.mcurs[curs].flags & MCF_DISABLED) == 0) { + // inventory cursor, and they have an active item + if (curs == MODE_USE) + { + if (playerchar->activeinv > 0) + return true; + } + // standard cursor that's not disabled, go with it + else if (game.mcurs[curs].flags & MCF_STANDARD) + return true; + } + return false; +} + +int find_next_enabled_cursor(int startwith) { + if (startwith >= game.numcursors) + startwith = 0; + int testing=startwith; + do { + if (is_standard_cursor_enabled(testing)) break; + testing++; + if (testing >= game.numcursors) testing=0; + } while (testing!=startwith); + + if (testing!=startwith) + set_cursor_mode(testing); + + return testing; +} + +int find_previous_enabled_cursor(int startwith) { + if (startwith < 0) + startwith = game.numcursors - 1; + int testing = startwith; + do { + if (is_standard_cursor_enabled(testing)) break; + testing--; + if (testing < 0) testing = game.numcursors - 1; + } while (testing != startwith); + + if (testing != startwith) + set_cursor_mode(testing); + + return testing; +} + + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/global_game.h" + +// void (int curs, int newslot) +RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(ChangeCursorGraphic); +} + +// void (int curs, int x, int y) +RuntimeScriptValue Sc_ChangeCursorHotspot(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(ChangeCursorHotspot); +} + +// void (int curs, int newview) +RuntimeScriptValue Sc_Mouse_ChangeModeView(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(Mouse_ChangeModeView); +} + +// void (int modd) +RuntimeScriptValue Sc_disable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(disable_cursor_mode); +} + +// void (int modd) +RuntimeScriptValue Sc_enable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(enable_cursor_mode); +} + +// int (int curs) +RuntimeScriptValue Sc_Mouse_GetModeGraphic(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(Mouse_GetModeGraphic); +} + +// int (int which) +RuntimeScriptValue Sc_IsButtonDown(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsButtonDown); +} + +// int (int which) +RuntimeScriptValue Sc_IsModeEnabled(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_PINT(IsModeEnabled); +} + +// void (); +RuntimeScriptValue Sc_SaveCursorForLocationChange(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(SaveCursorForLocationChange); +} + +// void () +RuntimeScriptValue Sc_SetNextCursor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(SetNextCursor); +} + +// void () +RuntimeScriptValue Sc_SetPreviousCursor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(SetPreviousCursor); +} + +// void (int x1, int y1, int x2, int y2) +RuntimeScriptValue Sc_SetMouseBounds(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT4(SetMouseBounds); +} + +// void (int newx, int newy) +RuntimeScriptValue Sc_SetMousePosition(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT2(SetMousePosition); +} + +// void () +RuntimeScriptValue Sc_RefreshMouse(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(RefreshMouse); +} + +// void () +RuntimeScriptValue Sc_set_default_cursor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID(set_default_cursor); +} + +// void (int newcurs) +RuntimeScriptValue Sc_set_mouse_cursor(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(set_mouse_cursor); +} + +// int () +RuntimeScriptValue Sc_GetCursorMode(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetCursorMode); +} + +// void (int newmode) +RuntimeScriptValue Sc_set_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(set_cursor_mode); +} + +// int () +RuntimeScriptValue Sc_Mouse_GetVisible(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Mouse_GetVisible); +} + +// void (int isOn) +RuntimeScriptValue Sc_Mouse_SetVisible(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(Mouse_SetVisible); +} + +RuntimeScriptValue Sc_Mouse_Click(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(PluginSimulateMouseClick); +} + +RuntimeScriptValue Sc_Mouse_GetControlEnabled(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_BOOL(Mouse::IsControlEnabled); +} + +RuntimeScriptValue Sc_Mouse_SetControlEnabled(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PBOOL(Mouse_EnableControl); +} + + +RuntimeScriptValue Sc_Mouse_GetSpeed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_FLOAT(Mouse::GetSpeed); +} + +RuntimeScriptValue Sc_Mouse_SetSpeed(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_VARIABLE_VALUE("Mouse::Speed"); + Mouse::SetSpeed(params[0].FValue); + return RuntimeScriptValue(); +} + +void RegisterMouseAPI() +{ + ccAddExternalStaticFunction("Mouse::ChangeModeGraphic^2", Sc_ChangeCursorGraphic); + ccAddExternalStaticFunction("Mouse::ChangeModeHotspot^3", Sc_ChangeCursorHotspot); + ccAddExternalStaticFunction("Mouse::ChangeModeView^2", Sc_Mouse_ChangeModeView); + ccAddExternalStaticFunction("Mouse::Click^1", Sc_Mouse_Click); + ccAddExternalStaticFunction("Mouse::DisableMode^1", Sc_disable_cursor_mode); + ccAddExternalStaticFunction("Mouse::EnableMode^1", Sc_enable_cursor_mode); + ccAddExternalStaticFunction("Mouse::GetModeGraphic^1", Sc_Mouse_GetModeGraphic); + ccAddExternalStaticFunction("Mouse::IsButtonDown^1", Sc_IsButtonDown); + ccAddExternalStaticFunction("Mouse::IsModeEnabled^1", Sc_IsModeEnabled); + ccAddExternalStaticFunction("Mouse::SaveCursorUntilItLeaves^0", Sc_SaveCursorForLocationChange); + ccAddExternalStaticFunction("Mouse::SelectNextMode^0", Sc_SetNextCursor); + ccAddExternalStaticFunction("Mouse::SelectPreviousMode^0", Sc_SetPreviousCursor); + ccAddExternalStaticFunction("Mouse::SetBounds^4", Sc_SetMouseBounds); + ccAddExternalStaticFunction("Mouse::SetPosition^2", Sc_SetMousePosition); + ccAddExternalStaticFunction("Mouse::Update^0", Sc_RefreshMouse); + ccAddExternalStaticFunction("Mouse::UseDefaultGraphic^0", Sc_set_default_cursor); + ccAddExternalStaticFunction("Mouse::UseModeGraphic^1", Sc_set_mouse_cursor); + ccAddExternalStaticFunction("Mouse::get_ControlEnabled", Sc_Mouse_GetControlEnabled); + ccAddExternalStaticFunction("Mouse::set_ControlEnabled", Sc_Mouse_SetControlEnabled); + ccAddExternalStaticFunction("Mouse::get_Mode", Sc_GetCursorMode); + ccAddExternalStaticFunction("Mouse::set_Mode", Sc_set_cursor_mode); + ccAddExternalStaticFunction("Mouse::get_Speed", Sc_Mouse_GetSpeed); + ccAddExternalStaticFunction("Mouse::set_Speed", Sc_Mouse_SetSpeed); + ccAddExternalStaticFunction("Mouse::get_Visible", Sc_Mouse_GetVisible); + ccAddExternalStaticFunction("Mouse::set_Visible", Sc_Mouse_SetVisible); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Mouse::ChangeModeGraphic^2", (void*)ChangeCursorGraphic); + ccAddExternalFunctionForPlugin("Mouse::ChangeModeHotspot^3", (void*)ChangeCursorHotspot); + ccAddExternalFunctionForPlugin("Mouse::ChangeModeView^2", (void*)Mouse_ChangeModeView); + ccAddExternalFunctionForPlugin("Mouse::DisableMode^1", (void*)disable_cursor_mode); + ccAddExternalFunctionForPlugin("Mouse::EnableMode^1", (void*)enable_cursor_mode); + ccAddExternalFunctionForPlugin("Mouse::GetModeGraphic^1", (void*)Mouse_GetModeGraphic); + ccAddExternalFunctionForPlugin("Mouse::IsButtonDown^1", (void*)IsButtonDown); + ccAddExternalFunctionForPlugin("Mouse::IsModeEnabled^1", (void*)IsModeEnabled); + ccAddExternalFunctionForPlugin("Mouse::SaveCursorUntilItLeaves^0", (void*)SaveCursorForLocationChange); + ccAddExternalFunctionForPlugin("Mouse::SelectNextMode^0", (void*)SetNextCursor); + ccAddExternalFunctionForPlugin("Mouse::SelectPreviousMode^0", (void*)SetPreviousCursor); + ccAddExternalFunctionForPlugin("Mouse::SetBounds^4", (void*)SetMouseBounds); + ccAddExternalFunctionForPlugin("Mouse::SetPosition^2", (void*)SetMousePosition); + ccAddExternalFunctionForPlugin("Mouse::Update^0", (void*)RefreshMouse); + ccAddExternalFunctionForPlugin("Mouse::UseDefaultGraphic^0", (void*)set_default_cursor); + ccAddExternalFunctionForPlugin("Mouse::UseModeGraphic^1", (void*)set_mouse_cursor); + ccAddExternalFunctionForPlugin("Mouse::get_Mode", (void*)GetCursorMode); + ccAddExternalFunctionForPlugin("Mouse::set_Mode", (void*)set_cursor_mode); + ccAddExternalFunctionForPlugin("Mouse::get_Visible", (void*)Mouse_GetVisible); + ccAddExternalFunctionForPlugin("Mouse::set_Visible", (void*)Mouse_SetVisible); +} diff --git a/engines/ags/engine/ac/mouse.h b/engines/ags/engine/ac/mouse.h new file mode 100644 index 000000000000..97e7467f0969 --- /dev/null +++ b/engines/ags/engine/ac/mouse.h @@ -0,0 +1,76 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__MOUSE_H +#define __AGS_EE_AC__MOUSE_H + +#include "ac/dynobj/scriptmouse.h" + +#define DOMOUSE_UPDATE 0 +#define DOMOUSE_ENABLE 1 +#define DOMOUSE_DISABLE 2 +#define DOMOUSE_NOCURSOR 5 +// are these mouse buttons? ;/ +// note: also defined in ac_cscidialog as const ints +#define NONE -1 +#define LEFT 0 +#define RIGHT 1 + +void Mouse_SetVisible(int isOn); +int Mouse_GetVisible(); +int Mouse_GetModeGraphic(int curs); +void Mouse_ChangeModeView(int curs, int newview); +// The Mouse:: functions are static so the script doesn't pass +// in an object parameter +void SetMousePosition (int newx, int newy); +int GetCursorMode(); +void SetNextCursor (); +// permanently change cursor graphic +void ChangeCursorGraphic (int curs, int newslot); +void ChangeCursorHotspot (int curs, int x, int y); +int IsButtonDown(int which); +void SetMouseBounds (int x1, int y1, int x2, int y2); +void RefreshMouse(); +// mouse cursor functions: +// set_mouse_cursor: changes visual appearance to specified cursor +void set_mouse_cursor(int newcurs); +// set_default_cursor: resets visual appearance to current mode (walk, look, etc); +void set_default_cursor(); +// set_cursor_mode: changes mode and appearance +void set_cursor_mode(int newmode); +void enable_cursor_mode(int modd); +void disable_cursor_mode(int modd); + +// Try to enable or disable mouse speed control by the engine +void Mouse_EnableControl(bool on); + +//============================================================================= + +int GetMouseCursor(); +void update_script_mouse_coords(); +void update_inv_cursor(int invnum); +void update_cached_mouse_cursor(); +void set_new_cursor_graphic (int spriteslot); +int find_next_enabled_cursor(int startwith); +int find_previous_enabled_cursor(int startwith); + +extern ScriptMouse scmouse; + +extern int cur_mode; +extern int cur_cursor; + +#endif // __AGS_EE_AC__MOUSE_H diff --git a/engines/ags/engine/ac/movelist.cpp b/engines/ags/engine/ac/movelist.cpp new file mode 100644 index 000000000000..47b9ca2b7f5f --- /dev/null +++ b/engines/ags/engine/ac/movelist.cpp @@ -0,0 +1,84 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/movelist.h" +#include "ac/common.h" +#include "util/stream.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +void MoveList::ReadFromFile_Legacy(Stream *in) +{ + in->ReadArrayOfInt32(pos, MAXNEEDSTAGES_LEGACY); + numstage = in->ReadInt32(); + in->ReadArrayOfInt32(xpermove, MAXNEEDSTAGES_LEGACY); + in->ReadArrayOfInt32(ypermove, MAXNEEDSTAGES_LEGACY); + fromx = in->ReadInt32(); + fromy = in->ReadInt32(); + onstage = in->ReadInt32(); + onpart = in->ReadInt32(); + lastx = in->ReadInt32(); + lasty = in->ReadInt32(); + doneflag = in->ReadInt8(); + direct = in->ReadInt8(); +} + +HSaveError MoveList::ReadFromFile(Stream *in, int32_t cmp_ver) +{ + if (cmp_ver < 1) + { + ReadFromFile_Legacy(in); + return HSaveError::None(); + } + + numstage = in->ReadInt32(); + // TODO: reimplement MoveList stages as vector to avoid these limits + if (numstage > MAXNEEDSTAGES) + { + return new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Incompatible number of movelist steps (count: %d, max : %d).", numstage, MAXNEEDSTAGES)); + } + + fromx = in->ReadInt32(); + fromy = in->ReadInt32(); + onstage = in->ReadInt32(); + onpart = in->ReadInt32(); + lastx = in->ReadInt32(); + lasty = in->ReadInt32(); + doneflag = in->ReadInt8(); + direct = in->ReadInt8(); + + in->ReadArrayOfInt32(pos, numstage); + in->ReadArrayOfInt32(xpermove, numstage); + in->ReadArrayOfInt32(ypermove, numstage); + return HSaveError::None(); +} + +void MoveList::WriteToFile(Stream *out) +{ + out->WriteInt32(numstage); + out->WriteInt32(fromx); + out->WriteInt32(fromy); + out->WriteInt32(onstage); + out->WriteInt32(onpart); + out->WriteInt32(lastx); + out->WriteInt32(lasty); + out->WriteInt8(doneflag); + out->WriteInt8(direct); + + out->WriteArrayOfInt32(pos, numstage); + out->WriteArrayOfInt32(xpermove, numstage); + out->WriteArrayOfInt32(ypermove, numstage); +} diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h new file mode 100644 index 000000000000..2f860dc3a814 --- /dev/null +++ b/engines/ags/engine/ac/movelist.h @@ -0,0 +1,43 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MOVE_H +#define __AC_MOVE_H + +#include "util/wgt2allg.h" // fixed type +#include "game/savegame.h" + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define MAXNEEDSTAGES 256 +#define MAXNEEDSTAGES_LEGACY 40 + +struct MoveList { + int pos[MAXNEEDSTAGES]; + int numstage; + fixed xpermove[MAXNEEDSTAGES], ypermove[MAXNEEDSTAGES]; + int fromx, fromy; + int onstage, onpart; + int lastx, lasty; + char doneflag; + char direct; // MoveCharDirect was used or not + + void ReadFromFile_Legacy(Common::Stream *in); + AGS::Engine::HSaveError ReadFromFile(Common::Stream *in, int32_t cmp_ver); + void WriteToFile(Common::Stream *out); +}; + +#endif // __AC_MOVE_H diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp new file mode 100644 index 000000000000..b33eaed3df7b --- /dev/null +++ b/engines/ags/engine/ac/object.cpp @@ -0,0 +1,1070 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/object.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/draw.h" +#include "ac/character.h" +#include "ac/global_object.h" +#include "ac/global_translation.h" +#include "ac/objectcache.h" +#include "ac/properties.h" +#include "ac/room.h" +#include "ac/roomstatus.h" +#include "ac/runtime_defines.h" +#include "ac/string.h" +#include "ac/system.h" +#include "ac/view.h" +#include "ac/walkablearea.h" +#include "debug/debug_log.h" +#include "main/game_run.h" +#include "ac/route_finder.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" +#include "gfx/gfx_def.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_object.h" +#include "ac/movelist.h" + +using namespace AGS::Common; + + +extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; +extern RoomStatus*croom; +extern RoomObject*objs; +extern ViewStruct*views; +extern RoomStruct thisroom; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; +extern MoveList *mls; +extern GameSetupStruct game; +extern Bitmap *walkable_areas_temp; +extern IGraphicsDriver *gfxDriver; +extern CCObject ccDynamicObject; + + +int Object_IsCollidingWithObject(ScriptObject *objj, ScriptObject *obj2) { + return AreObjectsColliding(objj->id, obj2->id); +} + +ScriptObject *GetObjectAtScreen(int xx, int yy) { + int hsnum = GetObjectIDAtScreen(xx, yy); + if (hsnum < 0) + return nullptr; + return &scrObj[hsnum]; +} + +ScriptObject *GetObjectAtRoom(int x, int y) +{ + int hsnum = GetObjectIDAtRoom(x, y); + if (hsnum < 0) + return nullptr; + return &scrObj[hsnum]; +} + +AGS_INLINE int is_valid_object(int obtest) { + if ((obtest < 0) || (obtest >= croom->numobj)) return 0; + return 1; +} + +void Object_Tint(ScriptObject *objj, int red, int green, int blue, int saturation, int luminance) { + SetObjectTint(objj->id, red, green, blue, saturation, luminance); +} + +void Object_RemoveTint(ScriptObject *objj) { + RemoveObjectTint(objj->id); +} + +void Object_SetView(ScriptObject *objj, int view, int loop, int frame) { + if (game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v351) + { // Previous version of SetView had negative loop and frame mean "use latest values" + auto &obj = objs[objj->id]; + if (loop < 0) loop = obj.loop; + if (frame < 0) frame = obj.frame; + const int vidx = view - 1; + if (vidx < 0 || vidx >= game.numviews) quit("!Object_SetView: invalid view number used"); + loop = Math::Clamp(loop, 0, (int)views[vidx].numLoops - 1); + frame = Math::Clamp(frame, 0, (int)views[vidx].loops[loop].numFrames - 1); + } + SetObjectFrame(objj->id, view, loop, frame); +} + +void Object_SetTransparency(ScriptObject *objj, int trans) { + SetObjectTransparency(objj->id, trans); +} + +int Object_GetTransparency(ScriptObject *objj) { + if (!is_valid_object(objj->id)) + quit("!Object.Transparent: invalid object number specified"); + + return GfxDef::LegacyTrans255ToTrans100(objs[objj->id].transparent); +} + +void Object_SetBaseline(ScriptObject *objj, int basel) { + SetObjectBaseline(objj->id, basel); +} + +int Object_GetBaseline(ScriptObject *objj) { + return GetObjectBaseline(objj->id); +} + +void Object_AnimateFrom(ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction, int sframe) { + if (direction == FORWARDS) + direction = 0; + else if (direction == BACKWARDS) + direction = 1; + else + quit("!Object.Animate: Invalid DIRECTION parameter"); + + if ((blocking == BLOCKING) || (blocking == 1)) + blocking = 1; + else if ((blocking == IN_BACKGROUND) || (blocking == 0)) + blocking = 0; + else + quit("!Object.Animate: Invalid BLOCKING parameter"); + + AnimateObjectImpl(objj->id, loop, delay, repeat, direction, blocking, sframe); +} + +void Object_Animate(ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction) { + Object_AnimateFrom(objj, loop, delay, repeat, blocking, direction, 0); +} + +void Object_StopAnimating(ScriptObject *objj) { + if (!is_valid_object(objj->id)) + quit("!Object.StopAnimating: invalid object number"); + + if (objs[objj->id].cycling) { + objs[objj->id].cycling = 0; + objs[objj->id].wait = 0; + } +} + +void Object_MergeIntoBackground(ScriptObject *objj) { + MergeObject(objj->id); +} + +void Object_StopMoving(ScriptObject *objj) { + StopObjectMoving(objj->id); +} + +void Object_SetVisible(ScriptObject *objj, int onoroff) { + if (onoroff) + ObjectOn(objj->id); + else + ObjectOff(objj->id); +} + +int Object_GetView(ScriptObject *objj) { + if (objs[objj->id].view < 0) + return 0; + return objs[objj->id].view + 1; +} + +int Object_GetLoop(ScriptObject *objj) { + if (objs[objj->id].view < 0) + return 0; + return objs[objj->id].loop; +} + +int Object_GetFrame(ScriptObject *objj) { + if (objs[objj->id].view < 0) + return 0; + return objs[objj->id].frame; +} + +int Object_GetVisible(ScriptObject *objj) { + return IsObjectOn(objj->id); +} + +void Object_SetGraphic(ScriptObject *objj, int slott) { + SetObjectGraphic(objj->id, slott); +} + +int Object_GetGraphic(ScriptObject *objj) { + return GetObjectGraphic(objj->id); +} + +int GetObjectX (int objj) { + if (!is_valid_object(objj)) quit("!GetObjectX: invalid object number"); + return objs[objj].x; +} + +int Object_GetX(ScriptObject *objj) { + return GetObjectX(objj->id); +} + +int Object_GetY(ScriptObject *objj) { + return GetObjectY(objj->id); +} + +int Object_GetAnimating(ScriptObject *objj) { + return IsObjectAnimating(objj->id); +} + +int Object_GetMoving(ScriptObject *objj) { + return IsObjectMoving(objj->id); +} + +bool Object_HasExplicitLight(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_light(); +} + +bool Object_HasExplicitTint(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_tint(); +} + +int Object_GetLightLevel(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_light() ? objs[obj->id].tint_light : 0; +} + +void Object_SetLightLevel(ScriptObject *objj, int light_level) +{ + int obj = objj->id; + if (!is_valid_object(obj)) + quit("!SetObjectTint: invalid object number specified"); + + objs[obj].tint_light = light_level; + objs[obj].flags &= ~OBJF_HASTINT; + objs[obj].flags |= OBJF_HASLIGHT; +} + +int Object_GetTintRed(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_r : 0; +} + +int Object_GetTintGreen(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_g : 0; +} + +int Object_GetTintBlue(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_b : 0; +} + +int Object_GetTintSaturation(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_level : 0; +} + +int Object_GetTintLuminance(ScriptObject *obj) +{ + return objs[obj->id].has_explicit_tint() ? ((objs[obj->id].tint_light * 10) / 25) : 0; +} + +void Object_SetPosition(ScriptObject *objj, int xx, int yy) { + SetObjectPosition(objj->id, xx, yy); +} + +void Object_SetX(ScriptObject *objj, int xx) { + SetObjectPosition(objj->id, xx, objs[objj->id].y); +} + +void Object_SetY(ScriptObject *objj, int yy) { + SetObjectPosition(objj->id, objs[objj->id].x, yy); +} + +void Object_GetName(ScriptObject *objj, char *buffer) { + GetObjectName(objj->id, buffer); +} + +const char* Object_GetName_New(ScriptObject *objj) { + if (!is_valid_object(objj->id)) + quit("!Object.Name: invalid object number"); + + return CreateNewScriptString(get_translation(thisroom.Objects[objj->id].Name)); +} + +bool Object_IsInteractionAvailable(ScriptObject *oobj, int mood) { + + play.check_interaction_only = 1; + RunObjectInteraction(oobj->id, mood); + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + return (ciwas == 2); +} + +void Object_Move(ScriptObject *objj, int x, int y, int speed, int blocking, int direct) { + if ((direct == ANYWHERE) || (direct == 1)) + direct = 1; + else if ((direct == WALKABLE_AREAS) || (direct == 0)) + direct = 0; + else + quit("Object.Move: invalid DIRECT parameter"); + + move_object(objj->id, x, y, speed, direct); + + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilValueIsZero(&objs[objj->id].moving); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("Object.Move: invalid BLOCKING paramter"); +} + +void Object_SetClickable(ScriptObject *objj, int clik) { + SetObjectClickable(objj->id, clik); +} + +int Object_GetClickable(ScriptObject *objj) { + if (!is_valid_object(objj->id)) + quit("!Object.Clickable: Invalid object specified"); + + if (objs[objj->id].flags & OBJF_NOINTERACT) + return 0; + return 1; +} + +void Object_SetManualScaling(ScriptObject *objj, bool on) +{ + if (on) objs[objj->id].flags &= ~OBJF_USEROOMSCALING; + else objs[objj->id].flags |= OBJF_USEROOMSCALING; + // clear the cache + objcache[objj->id].ywas = -9999; +} + +void Object_SetIgnoreScaling(ScriptObject *objj, int newval) { + if (!is_valid_object(objj->id)) + quit("!Object.IgnoreScaling: Invalid object specified"); + if (newval) + objs[objj->id].zoom = 100; // compatibility, for before manual scaling existed + Object_SetManualScaling(objj, newval != 0); +} + +int Object_GetIgnoreScaling(ScriptObject *objj) { + if (!is_valid_object(objj->id)) + quit("!Object.IgnoreScaling: Invalid object specified"); + + if (objs[objj->id].flags & OBJF_USEROOMSCALING) + return 0; + return 1; +} + +int Object_GetScaling(ScriptObject *objj) { + return objs[objj->id].zoom; +} + +void Object_SetScaling(ScriptObject *objj, int zoomlevel) { + if ((objs[objj->id].flags & OBJF_USEROOMSCALING) != 0) + { + debug_script_warn("Object.Scaling: cannot set property unless ManualScaling is enabled"); + return; + } + int zoom_fixed = Math::Clamp(zoomlevel, 1, (int)(INT16_MAX)); // RoomObject.zoom is int16 + if (zoomlevel != zoom_fixed) + debug_script_warn("Object.Scaling: scaling level must be between 1 and %d%%", (int)(INT16_MAX)); + objs[objj->id].zoom = zoom_fixed; +} + +void Object_SetSolid(ScriptObject *objj, int solid) { + objs[objj->id].flags &= ~OBJF_SOLID; + if (solid) + objs[objj->id].flags |= OBJF_SOLID; +} + +int Object_GetSolid(ScriptObject *objj) { + if (objs[objj->id].flags & OBJF_SOLID) + return 1; + return 0; +} + +void Object_SetBlockingWidth(ScriptObject *objj, int bwid) { + objs[objj->id].blocking_width = bwid; +} + +int Object_GetBlockingWidth(ScriptObject *objj) { + return objs[objj->id].blocking_width; +} + +void Object_SetBlockingHeight(ScriptObject *objj, int bhit) { + objs[objj->id].blocking_height = bhit; +} + +int Object_GetBlockingHeight(ScriptObject *objj) { + return objs[objj->id].blocking_height; +} + +int Object_GetID(ScriptObject *objj) { + return objj->id; +} + +void Object_SetIgnoreWalkbehinds(ScriptObject *chaa, int clik) { + SetObjectIgnoreWalkbehinds(chaa->id, clik); +} + +int Object_GetIgnoreWalkbehinds(ScriptObject *chaa) { + if (!is_valid_object(chaa->id)) + quit("!Object.IgnoreWalkbehinds: Invalid object specified"); + + if (objs[chaa->id].flags & OBJF_NOWALKBEHINDS) + return 1; + return 0; +} + +void move_object(int objj,int tox,int toy,int spee,int ignwal) { + + if (!is_valid_object(objj)) + quit("!MoveObject: invalid object number"); + + // AGS <= 2.61 uses MoveObject with spp=-1 internally instead of SetObjectPosition + if ((loaded_game_file_version <= kGameVersion_261) && (spee == -1)) + { + objs[objj].x = tox; + objs[objj].y = toy; + return; + } + + debug_script_log("Object %d start move to %d,%d", objj, tox, toy); + + int objX = room_to_mask_coord(objs[objj].x); + int objY = room_to_mask_coord(objs[objj].y); + tox = room_to_mask_coord(tox); + toy = room_to_mask_coord(toy); + + set_route_move_speed(spee, spee); + set_color_depth(8); + int mslot=find_route(objX, objY, tox, toy, prepare_walkable_areas(-1), objj+1, 1, ignwal); + set_color_depth(game.GetColorDepth()); + if (mslot>0) { + objs[objj].moving = mslot; + mls[mslot].direct = ignwal; + convert_move_path_to_room_resolution(&mls[mslot]); + } +} + +void Object_RunInteraction(ScriptObject *objj, int mode) { + RunObjectInteraction(objj->id, mode); +} + +int Object_GetProperty (ScriptObject *objj, const char *property) { + return GetObjectProperty(objj->id, property); +} + +void Object_GetPropertyText(ScriptObject *objj, const char *property, char *bufer) { + GetObjectPropertyText(objj->id, property, bufer); +} + +const char* Object_GetTextProperty(ScriptObject *objj, const char *property) +{ + return get_text_property_dynamic_string(thisroom.Objects[objj->id].Properties, croom->objProps[objj->id], property); +} + +bool Object_SetProperty(ScriptObject *objj, const char *property, int value) +{ + return set_int_property(croom->objProps[objj->id], property, value); +} + +bool Object_SetTextProperty(ScriptObject *objj, const char *property, const char *value) +{ + return set_text_property(croom->objProps[objj->id], property, value); +} + +void get_object_blocking_rect(int objid, int *x1, int *y1, int *width, int *y2) { + RoomObject *tehobj = &objs[objid]; + int cwidth, fromx; + + if (tehobj->blocking_width < 1) + cwidth = game_to_data_coord(tehobj->last_width) - 4; + else + cwidth = tehobj->blocking_width; + + fromx = tehobj->x + (game_to_data_coord(tehobj->last_width) / 2) - cwidth / 2; + if (fromx < 0) { + cwidth += fromx; + fromx = 0; + } + if (fromx + cwidth >= mask_to_room_coord(walkable_areas_temp->GetWidth())) + cwidth = mask_to_room_coord(walkable_areas_temp->GetWidth()) - fromx; + + if (x1) + *x1 = fromx; + if (width) + *width = cwidth; + if (y1) { + if (tehobj->blocking_height > 0) + *y1 = tehobj->y - tehobj->blocking_height / 2; + else + *y1 = tehobj->y - 2; + } + if (y2) { + if (tehobj->blocking_height > 0) + *y2 = tehobj->y + tehobj->blocking_height / 2; + else + *y2 = tehobj->y + 3; + } +} + +int isposinbox(int mmx,int mmy,int lf,int tp,int rt,int bt) { + if ((mmx>=lf) & (mmx<=rt) & (mmy>=tp) & (mmy<=bt)) return TRUE; + else return FALSE; +} + +// xx,yy is the position in room co-ordinates that we are checking +// arx,ary is the sprite x/y co-ordinates +int is_pos_in_sprite(int xx,int yy,int arx,int ary, Bitmap *sprit, int spww,int sphh, int flipped) { + if (spww==0) spww = game_to_data_coord(sprit->GetWidth()) - 1; + if (sphh==0) sphh = game_to_data_coord(sprit->GetHeight()) - 1; + + if (isposinbox(xx,yy,arx,ary,arx+spww,ary+sphh)==FALSE) + return FALSE; + + if (game.options[OPT_PIXPERFECT]) + { + // if it's transparent, or off the edge of the sprite, ignore + int xpos = data_to_game_coord(xx - arx); + int ypos = data_to_game_coord(yy - ary); + + if (gfxDriver->HasAcceleratedTransform()) + { + // hardware acceleration, so the sprite in memory will not have + // been stretched, it will be original size. Thus, adjust our + // calculations to compensate + data_to_game_coords(&spww, &sphh); + + if (spww != sprit->GetWidth()) + xpos = (xpos * sprit->GetWidth()) / spww; + if (sphh != sprit->GetHeight()) + ypos = (ypos * sprit->GetHeight()) / sphh; + } + + if (flipped) + xpos = (sprit->GetWidth() - 1) - xpos; + + int gpcol = my_getpixel(sprit, xpos, ypos); + + if ((gpcol == sprit->GetMaskColor()) || (gpcol == -1)) + return FALSE; + } + return TRUE; +} + +// X and Y co-ordinates must be in native format (TODO: find out if this comment is still true) +int check_click_on_object(int roomx, int roomy, int mood) +{ + int aa = GetObjectIDAtRoom(roomx, roomy); + if (aa < 0) return 0; + RunObjectInteraction(aa, mood); + return 1; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// void (ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction) +RuntimeScriptValue Sc_Object_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(ScriptObject, Object_Animate); +} + +RuntimeScriptValue Sc_Object_AnimateFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT6(ScriptObject, Object_AnimateFrom); +} + +// int (ScriptObject *objj, ScriptObject *obj2) +RuntimeScriptValue Sc_Object_IsCollidingWithObject(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(ScriptObject, Object_IsCollidingWithObject, ScriptObject); +} + +// void (ScriptObject *objj, char *buffer) +RuntimeScriptValue Sc_Object_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(ScriptObject, Object_GetName, char); +} + +// int (ScriptObject *objj, const char *property) +RuntimeScriptValue Sc_Object_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(ScriptObject, Object_GetProperty, const char); +} + +// void (ScriptObject *objj, const char *property, char *bufer) +RuntimeScriptValue Sc_Object_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ2(ScriptObject, Object_GetPropertyText, const char, char); +} + +//const char* (ScriptObject *objj, const char *property) +RuntimeScriptValue Sc_Object_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_POBJ(ScriptObject, const char, myScriptStringImpl, Object_GetTextProperty, const char); +} + +RuntimeScriptValue Sc_Object_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ_PINT(ScriptObject, Object_SetProperty, const char); +} + +RuntimeScriptValue Sc_Object_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ2(ScriptObject, Object_SetTextProperty, const char, const char); +} + +// void (ScriptObject *objj) +RuntimeScriptValue Sc_Object_MergeIntoBackground(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptObject, Object_MergeIntoBackground); +} + +RuntimeScriptValue Sc_Object_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_PINT(ScriptObject, Object_IsInteractionAvailable); +} + +// void (ScriptObject *objj, int x, int y, int speed, int blocking, int direct) +RuntimeScriptValue Sc_Object_Move(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(ScriptObject, Object_Move); +} + +// void (ScriptObject *objj) +RuntimeScriptValue Sc_Object_RemoveTint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptObject, Object_RemoveTint); +} + +// void (ScriptObject *objj, int mode) +RuntimeScriptValue Sc_Object_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_RunInteraction); +} + +RuntimeScriptValue Sc_Object_HasExplicitLight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(ScriptObject, Object_HasExplicitLight); +} + +RuntimeScriptValue Sc_Object_HasExplicitTint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(ScriptObject, Object_HasExplicitTint); +} + +RuntimeScriptValue Sc_Object_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetLightLevel); +} + +RuntimeScriptValue Sc_Object_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetLightLevel); +} + +RuntimeScriptValue Sc_Object_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetTintBlue); +} + +RuntimeScriptValue Sc_Object_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetTintGreen); +} + +RuntimeScriptValue Sc_Object_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetTintRed); +} + +RuntimeScriptValue Sc_Object_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetTintSaturation); +} + +RuntimeScriptValue Sc_Object_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetTintLuminance); +} + +// void (ScriptObject *objj, int xx, int yy) +RuntimeScriptValue Sc_Object_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptObject, Object_SetPosition); +} + +// void (ScriptObject *objj, int view, int loop, int frame) +RuntimeScriptValue Sc_Object_SetView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT3(ScriptObject, Object_SetView); +} + +// void (ScriptObject *objj) +RuntimeScriptValue Sc_Object_StopAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptObject, Object_StopAnimating); +} + +// void (ScriptObject *objj) +RuntimeScriptValue Sc_Object_StopMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptObject, Object_StopMoving); +} + +// void (ScriptObject *objj, int red, int green, int blue, int saturation, int luminance) +RuntimeScriptValue Sc_Object_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(ScriptObject, Object_Tint); +} + +RuntimeScriptValue Sc_GetObjectAtRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtRoom); +} + +// ScriptObject *(int xx, int yy) +RuntimeScriptValue Sc_GetObjectAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtScreen); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetAnimating); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetBaseline); +} + +// void (ScriptObject *objj, int basel) +RuntimeScriptValue Sc_Object_SetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBaseline); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetBlockingHeight); +} + +// void (ScriptObject *objj, int bhit) +RuntimeScriptValue Sc_Object_SetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBlockingHeight); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetBlockingWidth); +} + +// void (ScriptObject *objj, int bwid) +RuntimeScriptValue Sc_Object_SetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBlockingWidth); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetClickable); +} + +// void (ScriptObject *objj, int clik) +RuntimeScriptValue Sc_Object_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetClickable); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetFrame); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetGraphic); +} + +// void (ScriptObject *objj, int slott) +RuntimeScriptValue Sc_Object_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetGraphic); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetID); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetIgnoreScaling); +} + +// void (ScriptObject *objj, int newval) +RuntimeScriptValue Sc_Object_SetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetIgnoreScaling); +} + +// int (ScriptObject *chaa) +RuntimeScriptValue Sc_Object_GetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetIgnoreWalkbehinds); +} + +// void (ScriptObject *chaa, int clik) +RuntimeScriptValue Sc_Object_SetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetIgnoreWalkbehinds); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetLoop); +} + +RuntimeScriptValue Sc_Object_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PBOOL(ScriptObject, Object_SetManualScaling); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetMoving); +} + +// const char* (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptObject, const char, myScriptStringImpl, Object_GetName_New); +} + +RuntimeScriptValue Sc_Object_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetScaling); +} + +RuntimeScriptValue Sc_Object_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetScaling); +} + + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetSolid); +} + +// void (ScriptObject *objj, int solid) +RuntimeScriptValue Sc_Object_SetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetSolid); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetTransparency); +} + +// void (ScriptObject *objj, int trans) +RuntimeScriptValue Sc_Object_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetTransparency); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetView); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetVisible); +} + +// void (ScriptObject *objj, int onoroff) +RuntimeScriptValue Sc_Object_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetVisible); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetX); +} + +// void (ScriptObject *objj, int xx) +RuntimeScriptValue Sc_Object_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetX); +} + +// int (ScriptObject *objj) +RuntimeScriptValue Sc_Object_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptObject, Object_GetY); +} + +// void (ScriptObject *objj, int yy) +RuntimeScriptValue Sc_Object_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetY); +} + + + +void RegisterObjectAPI() +{ + ccAddExternalObjectFunction("Object::Animate^5", Sc_Object_Animate); + ccAddExternalObjectFunction("Object::Animate^6", Sc_Object_AnimateFrom); + ccAddExternalObjectFunction("Object::IsCollidingWithObject^1", Sc_Object_IsCollidingWithObject); + ccAddExternalObjectFunction("Object::GetName^1", Sc_Object_GetName); + ccAddExternalObjectFunction("Object::GetProperty^1", Sc_Object_GetProperty); + ccAddExternalObjectFunction("Object::GetPropertyText^2", Sc_Object_GetPropertyText); + ccAddExternalObjectFunction("Object::GetTextProperty^1", Sc_Object_GetTextProperty); + ccAddExternalObjectFunction("Object::SetProperty^2", Sc_Object_SetProperty); + ccAddExternalObjectFunction("Object::SetTextProperty^2", Sc_Object_SetTextProperty); + ccAddExternalObjectFunction("Object::IsInteractionAvailable^1", Sc_Object_IsInteractionAvailable); + ccAddExternalObjectFunction("Object::MergeIntoBackground^0", Sc_Object_MergeIntoBackground); + ccAddExternalObjectFunction("Object::Move^5", Sc_Object_Move); + ccAddExternalObjectFunction("Object::RemoveTint^0", Sc_Object_RemoveTint); + ccAddExternalObjectFunction("Object::RunInteraction^1", Sc_Object_RunInteraction); + ccAddExternalObjectFunction("Object::SetLightLevel^1", Sc_Object_SetLightLevel); + ccAddExternalObjectFunction("Object::SetPosition^2", Sc_Object_SetPosition); + ccAddExternalObjectFunction("Object::SetView^3", Sc_Object_SetView); + ccAddExternalObjectFunction("Object::StopAnimating^0", Sc_Object_StopAnimating); + ccAddExternalObjectFunction("Object::StopMoving^0", Sc_Object_StopMoving); + ccAddExternalObjectFunction("Object::Tint^5", Sc_Object_Tint); + + // static + ccAddExternalStaticFunction("Object::GetAtRoomXY^2", Sc_GetObjectAtRoom); + ccAddExternalStaticFunction("Object::GetAtScreenXY^2", Sc_GetObjectAtScreen); + + ccAddExternalObjectFunction("Object::get_Animating", Sc_Object_GetAnimating); + ccAddExternalObjectFunction("Object::get_Baseline", Sc_Object_GetBaseline); + ccAddExternalObjectFunction("Object::set_Baseline", Sc_Object_SetBaseline); + ccAddExternalObjectFunction("Object::get_BlockingHeight", Sc_Object_GetBlockingHeight); + ccAddExternalObjectFunction("Object::set_BlockingHeight", Sc_Object_SetBlockingHeight); + ccAddExternalObjectFunction("Object::get_BlockingWidth", Sc_Object_GetBlockingWidth); + ccAddExternalObjectFunction("Object::set_BlockingWidth", Sc_Object_SetBlockingWidth); + ccAddExternalObjectFunction("Object::get_Clickable", Sc_Object_GetClickable); + ccAddExternalObjectFunction("Object::set_Clickable", Sc_Object_SetClickable); + ccAddExternalObjectFunction("Object::get_Frame", Sc_Object_GetFrame); + ccAddExternalObjectFunction("Object::get_Graphic", Sc_Object_GetGraphic); + ccAddExternalObjectFunction("Object::set_Graphic", Sc_Object_SetGraphic); + ccAddExternalObjectFunction("Object::get_ID", Sc_Object_GetID); + ccAddExternalObjectFunction("Object::get_IgnoreScaling", Sc_Object_GetIgnoreScaling); + ccAddExternalObjectFunction("Object::set_IgnoreScaling", Sc_Object_SetIgnoreScaling); + ccAddExternalObjectFunction("Object::get_IgnoreWalkbehinds", Sc_Object_GetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Object::set_IgnoreWalkbehinds", Sc_Object_SetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Object::get_Loop", Sc_Object_GetLoop); + ccAddExternalObjectFunction("Object::get_ManualScaling", Sc_Object_GetIgnoreScaling); + ccAddExternalObjectFunction("Object::set_ManualScaling", Sc_Object_SetManualScaling); + ccAddExternalObjectFunction("Object::get_Moving", Sc_Object_GetMoving); + ccAddExternalObjectFunction("Object::get_Name", Sc_Object_GetName_New); + ccAddExternalObjectFunction("Object::get_Scaling", Sc_Object_GetScaling); + ccAddExternalObjectFunction("Object::set_Scaling", Sc_Object_SetScaling); + ccAddExternalObjectFunction("Object::get_Solid", Sc_Object_GetSolid); + ccAddExternalObjectFunction("Object::set_Solid", Sc_Object_SetSolid); + ccAddExternalObjectFunction("Object::get_Transparency", Sc_Object_GetTransparency); + ccAddExternalObjectFunction("Object::set_Transparency", Sc_Object_SetTransparency); + ccAddExternalObjectFunction("Object::get_View", Sc_Object_GetView); + ccAddExternalObjectFunction("Object::get_Visible", Sc_Object_GetVisible); + ccAddExternalObjectFunction("Object::set_Visible", Sc_Object_SetVisible); + ccAddExternalObjectFunction("Object::get_X", Sc_Object_GetX); + ccAddExternalObjectFunction("Object::set_X", Sc_Object_SetX); + ccAddExternalObjectFunction("Object::get_Y", Sc_Object_GetY); + ccAddExternalObjectFunction("Object::set_Y", Sc_Object_SetY); + + ccAddExternalObjectFunction("Object::get_HasExplicitLight", Sc_Object_HasExplicitLight); + ccAddExternalObjectFunction("Object::get_HasExplicitTint", Sc_Object_HasExplicitTint); + ccAddExternalObjectFunction("Object::get_LightLevel", Sc_Object_GetLightLevel); + ccAddExternalObjectFunction("Object::set_LightLevel", Sc_Object_SetLightLevel); + ccAddExternalObjectFunction("Object::get_TintBlue", Sc_Object_GetTintBlue); + ccAddExternalObjectFunction("Object::get_TintGreen", Sc_Object_GetTintGreen); + ccAddExternalObjectFunction("Object::get_TintRed", Sc_Object_GetTintRed); + ccAddExternalObjectFunction("Object::get_TintSaturation", Sc_Object_GetTintSaturation); + ccAddExternalObjectFunction("Object::get_TintLuminance", Sc_Object_GetTintLuminance); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Object::Animate^5", (void*)Object_Animate); + ccAddExternalFunctionForPlugin("Object::IsCollidingWithObject^1", (void*)Object_IsCollidingWithObject); + ccAddExternalFunctionForPlugin("Object::GetName^1", (void*)Object_GetName); + ccAddExternalFunctionForPlugin("Object::GetProperty^1", (void*)Object_GetProperty); + ccAddExternalFunctionForPlugin("Object::GetPropertyText^2", (void*)Object_GetPropertyText); + ccAddExternalFunctionForPlugin("Object::GetTextProperty^1", (void*)Object_GetTextProperty); + ccAddExternalFunctionForPlugin("Object::MergeIntoBackground^0", (void*)Object_MergeIntoBackground); + ccAddExternalFunctionForPlugin("Object::Move^5", (void*)Object_Move); + ccAddExternalFunctionForPlugin("Object::RemoveTint^0", (void*)Object_RemoveTint); + ccAddExternalFunctionForPlugin("Object::RunInteraction^1", (void*)Object_RunInteraction); + ccAddExternalFunctionForPlugin("Object::SetPosition^2", (void*)Object_SetPosition); + ccAddExternalFunctionForPlugin("Object::SetView^3", (void*)Object_SetView); + ccAddExternalFunctionForPlugin("Object::StopAnimating^0", (void*)Object_StopAnimating); + ccAddExternalFunctionForPlugin("Object::StopMoving^0", (void*)Object_StopMoving); + ccAddExternalFunctionForPlugin("Object::Tint^5", (void*)Object_Tint); + ccAddExternalFunctionForPlugin("Object::GetAtRoomXY^2", (void*)GetObjectAtRoom); + ccAddExternalFunctionForPlugin("Object::GetAtScreenXY^2", (void*)GetObjectAtScreen); + ccAddExternalFunctionForPlugin("Object::get_Animating", (void*)Object_GetAnimating); + ccAddExternalFunctionForPlugin("Object::get_Baseline", (void*)Object_GetBaseline); + ccAddExternalFunctionForPlugin("Object::set_Baseline", (void*)Object_SetBaseline); + ccAddExternalFunctionForPlugin("Object::get_BlockingHeight", (void*)Object_GetBlockingHeight); + ccAddExternalFunctionForPlugin("Object::set_BlockingHeight", (void*)Object_SetBlockingHeight); + ccAddExternalFunctionForPlugin("Object::get_BlockingWidth", (void*)Object_GetBlockingWidth); + ccAddExternalFunctionForPlugin("Object::set_BlockingWidth", (void*)Object_SetBlockingWidth); + ccAddExternalFunctionForPlugin("Object::get_Clickable", (void*)Object_GetClickable); + ccAddExternalFunctionForPlugin("Object::set_Clickable", (void*)Object_SetClickable); + ccAddExternalFunctionForPlugin("Object::get_Frame", (void*)Object_GetFrame); + ccAddExternalFunctionForPlugin("Object::get_Graphic", (void*)Object_GetGraphic); + ccAddExternalFunctionForPlugin("Object::set_Graphic", (void*)Object_SetGraphic); + ccAddExternalFunctionForPlugin("Object::get_ID", (void*)Object_GetID); + ccAddExternalFunctionForPlugin("Object::get_IgnoreScaling", (void*)Object_GetIgnoreScaling); + ccAddExternalFunctionForPlugin("Object::set_IgnoreScaling", (void*)Object_SetIgnoreScaling); + ccAddExternalFunctionForPlugin("Object::get_IgnoreWalkbehinds", (void*)Object_GetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Object::set_IgnoreWalkbehinds", (void*)Object_SetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Object::get_Loop", (void*)Object_GetLoop); + ccAddExternalFunctionForPlugin("Object::get_Moving", (void*)Object_GetMoving); + ccAddExternalFunctionForPlugin("Object::get_Name", (void*)Object_GetName_New); + ccAddExternalFunctionForPlugin("Object::get_Solid", (void*)Object_GetSolid); + ccAddExternalFunctionForPlugin("Object::set_Solid", (void*)Object_SetSolid); + ccAddExternalFunctionForPlugin("Object::get_Transparency", (void*)Object_GetTransparency); + ccAddExternalFunctionForPlugin("Object::set_Transparency", (void*)Object_SetTransparency); + ccAddExternalFunctionForPlugin("Object::get_View", (void*)Object_GetView); + ccAddExternalFunctionForPlugin("Object::get_Visible", (void*)Object_GetVisible); + ccAddExternalFunctionForPlugin("Object::set_Visible", (void*)Object_SetVisible); + ccAddExternalFunctionForPlugin("Object::get_X", (void*)Object_GetX); + ccAddExternalFunctionForPlugin("Object::set_X", (void*)Object_SetX); + ccAddExternalFunctionForPlugin("Object::get_Y", (void*)Object_GetY); + ccAddExternalFunctionForPlugin("Object::set_Y", (void*)Object_SetY); +} diff --git a/engines/ags/engine/ac/object.h b/engines/ags/engine/ac/object.h new file mode 100644 index 000000000000..0e044fab95ec --- /dev/null +++ b/engines/ags/engine/ac/object.h @@ -0,0 +1,89 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// [IKM] 2012-06-25: This bugs me that type is called 'Object'; in modern +// world of programming 'object' is usually a base class; should not we +// rename this to RoomObject one day? +//============================================================================= +#ifndef __AGS_EE_AC__OBJECT_H +#define __AGS_EE_AC__OBJECT_H + +#include "ac/common_defines.h" +#include "ac/dynobj/scriptobject.h" + +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; // FIXME later + +extern AGS_INLINE int is_valid_object(int obtest); +int Object_IsCollidingWithObject(ScriptObject *objj, ScriptObject *obj2); +ScriptObject *GetObjectAtScreen(int xx, int yy); +void Object_Tint(ScriptObject *objj, int red, int green, int blue, int saturation, int luminance); +void Object_RemoveTint(ScriptObject *objj); +void Object_SetView(ScriptObject *objj, int view, int loop, int frame); +void Object_SetTransparency(ScriptObject *objj, int trans); +int Object_GetTransparency(ScriptObject *objj); +void Object_SetBaseline(ScriptObject *objj, int basel); +int Object_GetBaseline(ScriptObject *objj); +void Object_Animate(ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction); +void Object_StopAnimating(ScriptObject *objj); +void Object_MergeIntoBackground(ScriptObject *objj); +void Object_StopMoving(ScriptObject *objj); +void Object_SetVisible(ScriptObject *objj, int onoroff); +int Object_GetView(ScriptObject *objj); +int Object_GetLoop(ScriptObject *objj); +int Object_GetFrame(ScriptObject *objj); +int Object_GetVisible(ScriptObject *objj); +void Object_SetGraphic(ScriptObject *objj, int slott); +int Object_GetGraphic(ScriptObject *objj); +int Object_GetX(ScriptObject *objj); +int Object_GetY(ScriptObject *objj); +int Object_GetAnimating(ScriptObject *objj); +int Object_GetMoving(ScriptObject *objj); +void Object_SetPosition(ScriptObject *objj, int xx, int yy); +void Object_SetX(ScriptObject *objj, int xx); +void Object_SetY(ScriptObject *objj, int yy); +void Object_GetName(ScriptObject *objj, char *buffer); +const char* Object_GetName_New(ScriptObject *objj); +bool Object_IsInteractionAvailable(ScriptObject *oobj, int mood); +void Object_Move(ScriptObject *objj, int x, int y, int speed, int blocking, int direct); +void Object_SetClickable(ScriptObject *objj, int clik); +int Object_GetClickable(ScriptObject *objj); +void Object_SetIgnoreScaling(ScriptObject *objj, int newval); +int Object_GetIgnoreScaling(ScriptObject *objj); +void Object_SetSolid(ScriptObject *objj, int solid); +int Object_GetSolid(ScriptObject *objj); +void Object_SetBlockingWidth(ScriptObject *objj, int bwid); +int Object_GetBlockingWidth(ScriptObject *objj); +void Object_SetBlockingHeight(ScriptObject *objj, int bhit); +int Object_GetBlockingHeight(ScriptObject *objj); +int Object_GetID(ScriptObject *objj); +void Object_SetIgnoreWalkbehinds(ScriptObject *chaa, int clik); +int Object_GetIgnoreWalkbehinds(ScriptObject *chaa); +void Object_RunInteraction(ScriptObject *objj, int mode); + +int Object_GetProperty (ScriptObject *objj, const char *property); +void Object_GetPropertyText(ScriptObject *objj, const char *property, char *bufer); +const char* Object_GetTextProperty(ScriptObject *objj, const char *property); + +void move_object(int objj,int tox,int toy,int spee,int ignwal); +void get_object_blocking_rect(int objid, int *x1, int *y1, int *width, int *y2); +int isposinbox(int mmx,int mmy,int lf,int tp,int rt,int bt); +int is_pos_in_sprite(int xx,int yy,int arx,int ary, Common::Bitmap *sprit, int spww,int sphh, int flipped = 0); +// X and Y co-ordinates must be in native format +// X and Y are ROOM coordinates +int check_click_on_object(int roomx, int roomy, int mood); + +#endif // __AGS_EE_AC__OBJECT_H + diff --git a/engines/ags/engine/ac/objectcache.h b/engines/ags/engine/ac/objectcache.h new file mode 100644 index 000000000000..78ddcede1867 --- /dev/null +++ b/engines/ags/engine/ac/objectcache.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__OBJECTCACHE_H +#define __AGS_EE_AC__OBJECTCACHE_H + +// stores cached object info +struct ObjectCache { + Common::Bitmap *image; + int sppic; + short tintredwas, tintgrnwas, tintbluwas, tintamntwas, tintlightwas; + short lightlevwas, mirroredWas, zoomWas; + // The following are used to determine if the character has moved + int xwas, ywas; +}; + +#endif // __AGS_EE_AC__OBJECTCACHE_H diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp new file mode 100644 index 000000000000..3904b795b1ad --- /dev/null +++ b/engines/ags/engine/ac/overlay.cpp @@ -0,0 +1,396 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/overlay.h" +#include "ac/common.h" +#include "ac/view.h" +#include "ac/character.h" +#include "ac/characterextras.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_overlay.h" +#include "ac/global_translation.h" +#include "ac/runtime_defines.h" +#include "ac/screenoverlay.h" +#include "ac/string.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" +#include "script/runtimescriptvalue.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern int displayed_room; +extern int face_talking; +extern ViewStruct*views; +extern CharacterExtras *charextra; +extern IGraphicsDriver *gfxDriver; + + + +std::vector screenover; +int is_complete_overlay=0,is_text_overlay=0; + +void Overlay_Remove(ScriptOverlay *sco) { + sco->Remove(); +} + +void Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int text_color, const char *text) { + int ovri=find_overlay_of_type(scover->overlayId); + if (ovri<0) + quit("!Overlay.SetText: invalid overlay ID specified"); + int xx = game_to_data_coord(screenover[ovri].x) - scover->borderWidth; + int yy = game_to_data_coord(screenover[ovri].y) - scover->borderHeight; + + RemoveOverlay(scover->overlayId); + const int disp_type = scover->overlayId; + + if (CreateTextOverlay(xx, yy, wii, fontid, text_color, get_translation(text), disp_type) != scover->overlayId) + quit("SetTextOverlay internal error: inconsistent type ids"); +} + +int Overlay_GetX(ScriptOverlay *scover) { + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); + + int tdxp, tdyp; + get_overlay_position(screenover[ovri], &tdxp, &tdyp); + + return game_to_data_coord(tdxp); +} + +void Overlay_SetX(ScriptOverlay *scover, int newx) { + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); + + screenover[ovri].x = data_to_game_coord(newx); +} + +int Overlay_GetY(ScriptOverlay *scover) { + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); + + int tdxp, tdyp; + get_overlay_position(screenover[ovri], &tdxp, &tdyp); + + return game_to_data_coord(tdyp); +} + +void Overlay_SetY(ScriptOverlay *scover, int newy) { + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); + + screenover[ovri].y = data_to_game_coord(newy); +} + +int Overlay_GetValid(ScriptOverlay *scover) { + if (scover->overlayId == -1) + return 0; + + if (!IsOverlayValid(scover->overlayId)) { + scover->overlayId = -1; + return 0; + } + + return 1; +} + +ScriptOverlay* Overlay_CreateGraphical(int x, int y, int slot, int transparent) { + ScriptOverlay *sco = new ScriptOverlay(); + sco->overlayId = CreateGraphicOverlay(x, y, slot, transparent); + sco->borderHeight = 0; + sco->borderWidth = 0; + sco->isBackgroundSpeech = 0; + + ccRegisterManagedObject(sco, sco); + return sco; +} + +ScriptOverlay* Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char* text) { + ScriptOverlay *sco = new ScriptOverlay(); + + data_to_game_coords(&x, &y); + width = data_to_game_coord(width); + + sco->overlayId = CreateTextOverlayCore(x, y, width, font, colour, text, DISPLAYTEXT_NORMALOVERLAY, 0); + + int ovri = find_overlay_of_type(sco->overlayId); + sco->borderWidth = game_to_data_coord(screenover[ovri].x - x); + sco->borderHeight = game_to_data_coord(screenover[ovri].y - y); + sco->isBackgroundSpeech = 0; + + ccRegisterManagedObject(sco, sco); + return sco; +} + +//============================================================================= + +void dispose_overlay(ScreenOverlay &over) +{ + delete over.pic; + over.pic = nullptr; + if (over.bmp != nullptr) + gfxDriver->DestroyDDB(over.bmp); + over.bmp = nullptr; + // if the script didn't actually use the Overlay* return + // value, dispose of the pointer + if (over.associatedOverlayHandle) + ccAttemptDisposeObject(over.associatedOverlayHandle); +} + +void remove_screen_overlay_index(size_t over_idx) +{ + ScreenOverlay &over = screenover[over_idx]; + dispose_overlay(over); + if (over.type==OVER_COMPLETE) is_complete_overlay--; + if (over.type==OVER_TEXTMSG) is_text_overlay--; + screenover.erase(screenover.begin() + over_idx); + // if an overlay before the sierra-style speech one is removed, + // update the index + if (face_talking >= 0 && (size_t)face_talking > over_idx) + face_talking--; +} + +void remove_screen_overlay(int type) +{ + for (size_t i = 0; i < screenover.size();) + { + if (type < 0 || screenover[i].type == type) + remove_screen_overlay_index(i); + else + i++; + } +} + +int find_overlay_of_type(int type) +{ + for (size_t i = 0; i < screenover.size(); ++i) + { + if (screenover[i].type == type) return i; + } + return -1; +} + +size_t add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChannel) +{ + return add_screen_overlay(x, y, type, piccy, 0, 0, alphaChannel); +} + +size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) +{ + if (type==OVER_COMPLETE) is_complete_overlay++; + if (type==OVER_TEXTMSG) is_text_overlay++; + if (type==OVER_CUSTOM) { + // find an unused custom ID; TODO: find a better approach! + for (int id = OVER_CUSTOM + 1; id < screenover.size() + OVER_CUSTOM + 1; ++id) { + if (find_overlay_of_type(id) == -1) { type=id; break; } + } + } + ScreenOverlay over; + over.pic=piccy; + over.bmp = gfxDriver->CreateDDBFromBitmap(piccy, alphaChannel); + over.x=x; + over.y=y; + over._offsetX = pic_offx; + over._offsetY = pic_offy; + over.type=type; + over.timeout=0; + over.bgSpeechForChar = -1; + over.associatedOverlayHandle = 0; + over.hasAlphaChannel = alphaChannel; + over.positionRelativeToScreen = true; + screenover.push_back(over); + return screenover.size() - 1; +} + + + +void get_overlay_position(const ScreenOverlay &over, int *x, int *y) { + int tdxp, tdyp; + const Rect &ui_view = play.GetUIViewport(); + + if (over.x == OVR_AUTOPLACE) { + // auto place on character + int charid = over.y; + + auto view = FindNearestViewport(charid); + const int charpic = views[game.chars[charid].view].loops[game.chars[charid].loop].frames[0].pic; + const int height = (charextra[charid].height < 1) ? game.SpriteInfos[charpic].Height : charextra[charid].height; + Point screenpt = view->RoomToScreen( + data_to_game_coord(game.chars[charid].x), + data_to_game_coord(game.chars[charid].get_effective_y()) - height).first; + tdxp = screenpt.X - over.pic->GetWidth() / 2; + if (tdxp < 0) tdxp = 0; + tdyp = screenpt.Y - get_fixed_pixel_size(5); + tdyp -= over.pic->GetHeight(); + if (tdyp < 5) tdyp = 5; + + if ((tdxp + over.pic->GetWidth()) >= ui_view.GetWidth()) + tdxp = (ui_view.GetWidth() - over.pic->GetWidth()) - 1; + if (game.chars[charid].room != displayed_room) { + tdxp = ui_view.GetWidth()/2 - over.pic->GetWidth()/2; + tdyp = ui_view.GetHeight()/2 - over.pic->GetHeight()/2; + } + } + else { + // Note: the internal offset is only needed when x,y coordinates are specified + // and only in the case where the overlay is using a GUI. See issue #1098 + tdxp = over.x + over._offsetX; + tdyp = over.y + over._offsetY; + + if (!over.positionRelativeToScreen) + { + Point tdxy = play.RoomToScreen(tdxp, tdyp); + tdxp = tdxy.X; + tdyp = tdxy.Y; + } + } + *x = tdxp; + *y = tdyp; +} + +void recreate_overlay_ddbs() +{ + for (auto &over : screenover) + { + if (over.bmp) + gfxDriver->DestroyDDB(over.bmp); + if (over.pic) + over.bmp = gfxDriver->CreateDDBFromBitmap(over.pic, false); + else + over.bmp = nullptr; + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// ScriptOverlay* (int x, int y, int slot, int transparent) +RuntimeScriptValue Sc_Overlay_CreateGraphical(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT4(ScriptOverlay, Overlay_CreateGraphical); +} + +// ScriptOverlay* (int x, int y, int width, int font, int colour, const char* text, ...) +RuntimeScriptValue Sc_Overlay_CreateTextual(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(Overlay_CreateTextual, 6); + ScriptOverlay *overlay = Overlay_CreateTextual(params[0].IValue, params[1].IValue, params[2].IValue, + params[3].IValue, params[4].IValue, scsf_buffer); + return RuntimeScriptValue().SetDynamicObject(overlay, overlay); +} + +// void (ScriptOverlay *scover, int wii, int fontid, int clr, char*texx, ...) +RuntimeScriptValue Sc_Overlay_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_SCRIPT_SPRINTF(Overlay_SetText, 4); + Overlay_SetText((ScriptOverlay*)self, params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + +// void (ScriptOverlay *sco) +RuntimeScriptValue Sc_Overlay_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptOverlay, Overlay_Remove); +} + +// int (ScriptOverlay *scover) +RuntimeScriptValue Sc_Overlay_GetValid(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptOverlay, Overlay_GetValid); +} + +// int (ScriptOverlay *scover) +RuntimeScriptValue Sc_Overlay_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptOverlay, Overlay_GetX); +} + +// void (ScriptOverlay *scover, int newx) +RuntimeScriptValue Sc_Overlay_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetX); +} + +// int (ScriptOverlay *scover) +RuntimeScriptValue Sc_Overlay_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptOverlay, Overlay_GetY); +} + +// void (ScriptOverlay *scover, int newy) +RuntimeScriptValue Sc_Overlay_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetY); +} + +//============================================================================= +// +// Exclusive API for Plugins +// +//============================================================================= + +// ScriptOverlay* (int x, int y, int width, int font, int colour, const char* text, ...) +ScriptOverlay* ScPl_Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char *text, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(text); + return Overlay_CreateTextual(x, y, width, font, colour, scsf_buffer); +} + +// void (ScriptOverlay *scover, int wii, int fontid, int clr, char*texx, ...) +void ScPl_Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + Overlay_SetText(scover, wii, fontid, clr, scsf_buffer); +} + + +void RegisterOverlayAPI() +{ + ccAddExternalStaticFunction("Overlay::CreateGraphical^4", Sc_Overlay_CreateGraphical); + ccAddExternalStaticFunction("Overlay::CreateTextual^106", Sc_Overlay_CreateTextual); + ccAddExternalObjectFunction("Overlay::SetText^104", Sc_Overlay_SetText); + ccAddExternalObjectFunction("Overlay::Remove^0", Sc_Overlay_Remove); + ccAddExternalObjectFunction("Overlay::get_Valid", Sc_Overlay_GetValid); + ccAddExternalObjectFunction("Overlay::get_X", Sc_Overlay_GetX); + ccAddExternalObjectFunction("Overlay::set_X", Sc_Overlay_SetX); + ccAddExternalObjectFunction("Overlay::get_Y", Sc_Overlay_GetY); + ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Overlay::CreateGraphical^4", (void*)Overlay_CreateGraphical); + ccAddExternalFunctionForPlugin("Overlay::CreateTextual^106", (void*)ScPl_Overlay_CreateTextual); + ccAddExternalFunctionForPlugin("Overlay::SetText^104", (void*)ScPl_Overlay_SetText); + ccAddExternalFunctionForPlugin("Overlay::Remove^0", (void*)Overlay_Remove); + ccAddExternalFunctionForPlugin("Overlay::get_Valid", (void*)Overlay_GetValid); + ccAddExternalFunctionForPlugin("Overlay::get_X", (void*)Overlay_GetX); + ccAddExternalFunctionForPlugin("Overlay::set_X", (void*)Overlay_SetX); + ccAddExternalFunctionForPlugin("Overlay::get_Y", (void*)Overlay_GetY); + ccAddExternalFunctionForPlugin("Overlay::set_Y", (void*)Overlay_SetY); +} diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h new file mode 100644 index 000000000000..073ae9c46dbf --- /dev/null +++ b/engines/ags/engine/ac/overlay.h @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__OVERLAY_H +#define __AGS_EE_AC__OVERLAY_H +#include +#include "ac/screenoverlay.h" +#include "ac/dynobj/scriptoverlay.h" + +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; // FIXME later + +void Overlay_Remove(ScriptOverlay *sco); +void Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, const char*text); +int Overlay_GetX(ScriptOverlay *scover); +void Overlay_SetX(ScriptOverlay *scover, int newx); +int Overlay_GetY(ScriptOverlay *scover); +void Overlay_SetY(ScriptOverlay *scover, int newy); +int Overlay_GetValid(ScriptOverlay *scover); +ScriptOverlay* Overlay_CreateGraphical(int x, int y, int slot, int transparent); +ScriptOverlay* Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char* text); + +int find_overlay_of_type(int type); +void remove_screen_overlay(int type); +// Calculates overlay position in screen coordinates +void get_overlay_position(const ScreenOverlay &over, int *x, int *y); +size_t add_screen_overlay(int x,int y,int type,Common::Bitmap *piccy, bool alphaChannel = false); +size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false); +void remove_screen_overlay_index(size_t over_idx); +void recreate_overlay_ddbs(); + +extern int is_complete_overlay; +extern int is_text_overlay; // blocking text overlay on screen + +extern std::vector screenover; + +#endif // __AGS_EE_AC__OVERLAY_H diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp new file mode 100644 index 000000000000..6225249a3364 --- /dev/null +++ b/engines/ags/engine/ac/parser.cpp @@ -0,0 +1,345 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include //isalnum() +#include +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/parser.h" +#include "ac/string.h" +#include "ac/wordsdictionary.h" +#include "debug/debug_log.h" +#include "util/string.h" +#include "util/string_compat.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern GameState play; + +int Parser_FindWordID(const char *wordToFind) +{ + return find_word_in_dictionary(wordToFind); +} + +const char* Parser_SaidUnknownWord() { + if (play.bad_parsed_word[0] == 0) + return nullptr; + return CreateNewScriptString(play.bad_parsed_word); +} + +void ParseText (const char*text) { + parse_sentence (text, &play.num_parsed_words, play.parsed_words, nullptr, 0); +} + +// Said: call with argument for example "get apple"; we then check +// word by word if it matches (using dictonary ID equivalence to match +// synonyms). Returns 1 if it does, 0 if not. +int Said (const char *checkwords) { + int numword = 0; + short words[MAX_PARSED_WORDS]; + return parse_sentence (checkwords, &numword, &words[0], play.parsed_words, play.num_parsed_words); +} + +//============================================================================= + +int find_word_in_dictionary (const char *lookfor) { + int j; + if (game.dict == nullptr) + return -1; + + for (j = 0; j < game.dict->num_words; j++) { + if (ags_stricmp(lookfor, game.dict->word[j]) == 0) { + return game.dict->wordnum[j]; + } + } + if (lookfor[0] != 0) { + // If the word wasn't found, but it ends in 'S', see if there's + // a non-plural version + const char *ptat = &lookfor[strlen(lookfor)-1]; + char lastletter = *ptat; + if ((lastletter == 's') || (lastletter == 'S') || (lastletter == '\'')) { + String singular = lookfor; + singular.ClipRight(1); + return find_word_in_dictionary(singular); + } + } + return -1; +} + +int is_valid_word_char(char theChar) { + if ((isalnum((unsigned char)theChar)) || (theChar == '\'') || (theChar == '-')) { + return 1; + } + return 0; +} + +int FindMatchingMultiWordWord(char *thisword, const char **text) { + // see if there are any multi-word words + // that match -- if so, use them + const char *tempptr = *text; + char tempword[150] = ""; + if (thisword != nullptr) + strcpy(tempword, thisword); + + int bestMatchFound = -1, word; + const char *tempptrAtBestMatch = tempptr; + + do { + // extract and concat the next word + strcat(tempword, " "); + while (tempptr[0] == ' ') tempptr++; + char chbuffer[2]; + while (is_valid_word_char(tempptr[0])) { + sprintf(chbuffer, "%c", tempptr[0]); + strcat(tempword, chbuffer); + tempptr++; + } + // is this it? + word = find_word_in_dictionary(tempword); + // take the longest match we find + if (word >= 0) { + bestMatchFound = word; + tempptrAtBestMatch = tempptr; + } + + } while (tempptr[0] == ' '); + + word = bestMatchFound; + + if (word >= 0) { + // yes, a word like "pick up" was found + *text = tempptrAtBestMatch; + if (thisword != nullptr) + strcpy(thisword, tempword); + } + + return word; +} + +// parse_sentence: pass compareto as NULL to parse the sentence, or +// compareto as non-null to check if it matches the passed sentence +int parse_sentence (const char *src_text, int *numwords, short*wordarray, short*compareto, int comparetonum) { + char thisword[150] = "\0"; + int i = 0, comparing = 0; + char in_optional = 0, do_word_now = 0; + int optional_start = 0; + + numwords[0] = 0; + if (compareto == nullptr) + play.bad_parsed_word[0] = 0; + + String uniform_text = src_text; + uniform_text.MakeLower(); + const char *text = uniform_text.GetCStr(); + while (1) { + if ((compareto != nullptr) && (compareto[comparing] == RESTOFLINE)) + return 1; + + if ((text[0] == ']') && (compareto != nullptr)) { + if (!in_optional) + quitprintf("!Said: unexpected ']'\nText: %s", src_text); + do_word_now = 1; + } + + if (is_valid_word_char(text[0])) { + // Part of a word, add it on + thisword[i] = text[0]; + i++; + } + else if ((text[0] == '[') && (compareto != nullptr)) { + if (in_optional) + quitprintf("!Said: nested optional words\nText: %s", src_text); + + in_optional = 1; + optional_start = comparing; + } + else if ((thisword[0] != 0) || ((text[0] == 0) && (i > 0)) || (do_word_now == 1)) { + // End of word, so process it + thisword[i] = 0; + i = 0; + int word = -1; + + if (text[0] == ' ') { + word = FindMatchingMultiWordWord(thisword, &text); + } + + if (word < 0) { + // just a normal word + word = find_word_in_dictionary(thisword); + } + + // "look rol" + if (word == RESTOFLINE) + return 1; + if (compareto) { + // check string is longer than user input + if (comparing >= comparetonum) { + if (in_optional) { + // eg. "exit [door]" - there's no more user input + // but the optional word is still there + if (do_word_now) { + in_optional = 0; + do_word_now = 0; + } + thisword[0] = 0; + text++; + continue; + } + return 0; + } + if (word <= 0) + quitprintf("!Said: supplied word '%s' is not in dictionary or is an ignored word\nText: %s", thisword, src_text); + if (word == ANYWORD) { } + else if (word != compareto[comparing]) { + // words don't match - if a comma then a list of possibles, + // so allow retry + if (text[0] == ',') + comparing--; + else { + // words don't match + if (in_optional) { + // inside an optional clause, so skip it + while (text[0] != ']') { + if (text[0] == 0) + quitprintf("!Said: unterminated [optional]\nText: %s", src_text); + text++; + } + // -1 because it's about to be ++'d again + comparing = optional_start - 1; + } + // words don't match outside an optional clause, abort + else + return 0; + } + } + else if (text[0] == ',') { + // this alternative matched, but there are more + // so skip the other alternatives + int continueSearching = 1; + while (continueSearching) { + + const char *textStart = &text[1]; + + while ((text[0] == ',') || (isalnum((unsigned char)text[0]) != 0)) + text++; + + continueSearching = 0; + + if (text[0] == ' ') { + strcpy(thisword, textStart); + thisword[text - textStart] = 0; + // forward past any multi-word alternatives + if (FindMatchingMultiWordWord(thisword, &text) >= 0) + continueSearching = 1; + } + } + + if ((text[0] == ']') && (in_optional)) { + // [go,move] we just matched "go", so skip over "move" + in_optional = 0; + text++; + } + + // go back cos it'll be ++'d in a minute + text--; + } + comparing++; + } + else if (word != 0) { + // it's not an ignore word (it's a known word, or an unknown + // word, so save its index) + wordarray[numwords[0]] = word; + numwords[0]++; + if (numwords[0] >= MAX_PARSED_WORDS) + return 0; + // if it's an unknown word, store it for use in messages like + // "you can't use the word 'xxx' in this game" + if ((word < 0) && (play.bad_parsed_word[0] == 0)) + strcpy(play.bad_parsed_word, thisword); + } + + if (do_word_now) { + in_optional = 0; + do_word_now = 0; + } + + thisword[0] = 0; + } + if (text[0] == 0) + break; + text++; + } + // If the user input is longer than the Said string, it's wrong + // eg Said("look door") and they type "look door jibble" + // rol should be used instead to enable this + if (comparing < comparetonum) + return 0; + return 1; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// int (const char *wordToFind) +RuntimeScriptValue Sc_Parser_FindWordID(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(Parser_FindWordID, const char); +} + +// void (char*text) +RuntimeScriptValue Sc_ParseText(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_POBJ(ParseText, /*const*/ char); +} + +// const char* () +RuntimeScriptValue Sc_Parser_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ(const char, myScriptStringImpl, Parser_SaidUnknownWord); +} + +// int (char*checkwords) +RuntimeScriptValue Sc_Said(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(Said, /*const*/ char); +} + + + +void RegisterParserAPI() +{ + ccAddExternalStaticFunction("Parser::FindWordID^1", Sc_Parser_FindWordID); + ccAddExternalStaticFunction("Parser::ParseText^1", Sc_ParseText); + ccAddExternalStaticFunction("Parser::SaidUnknownWord^0",Sc_Parser_SaidUnknownWord); + ccAddExternalStaticFunction("Parser::Said^1", Sc_Said); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Parser::FindWordID^1", (void*)Parser_FindWordID); + ccAddExternalFunctionForPlugin("Parser::ParseText^1", (void*)ParseText); + ccAddExternalFunctionForPlugin("Parser::SaidUnknownWord^0",(void*)Parser_SaidUnknownWord); + ccAddExternalFunctionForPlugin("Parser::Said^1", (void*)Said); +} diff --git a/engines/ags/engine/ac/parser.h b/engines/ags/engine/ac/parser.h new file mode 100644 index 000000000000..eddeaebe5c50 --- /dev/null +++ b/engines/ags/engine/ac/parser.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__PARSER_H +#define __AGS_EE_AC__PARSER_H + +int Parser_FindWordID(const char *wordToFind); +const char* Parser_SaidUnknownWord(); +void ParseText (const char*text); +int Said (const char*checkwords); + +//============================================================================= + +int find_word_in_dictionary (const char *lookfor); +int is_valid_word_char(char theChar); +int FindMatchingMultiWordWord(char *thisword, const char **text); +int parse_sentence (const char *src_text, int *numwords, short*wordarray, short*compareto, int comparetonum); + +#endif // __AGS_EE_AC__PARSER_H diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h new file mode 100644 index 000000000000..57898ac55eb8 --- /dev/null +++ b/engines/ags/engine/ac/path_helper.h @@ -0,0 +1,75 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Functions related to constructing game and script paths. +// +//============================================================================= +#ifndef __AGS_EE_AC__PATHHELPER_H +#define __AGS_EE_AC__PATHHELPER_H + +#include "util/string.h" + +using AGS::Common::String; + +// Filepath tokens, which are replaced by platform-specific directory names +extern const String UserSavedgamesRootToken; +extern const String GameSavedgamesDirToken; +extern const String GameDataDirToken; + +inline const char *PathOrCurDir(const char *path) +{ + return path ? path : "."; +} + +// Subsitutes illegal characters with '_'. This function uses illegal chars array +// specific to current platform. +void FixupFilename(char *filename); +// Checks if there is a slash after special token in the beginning of the +// file path, and adds one if it is missing. If no token is found, string is +// returned unchanged. +String FixSlashAfterToken(const String &path); +// Creates a directory path by combining absolute path to special directory with +// custom game's directory name. +// If the path is relative, keeps it unmodified (no extra subdir added). +String MakeSpecialSubDir(const String &sp_dir); + +// ResolvedPath describes an actual location pointed by a user path (e.g. from script) +struct ResolvedPath +{ + String BaseDir; // base directory, one of the special path roots + String FullPath;// full path + String AltPath; // alternative full path, for backwards compatibility +}; +// Resolves a file path provided by user (e.g. script) into actual file path, +// by substituting special keywords with actual platform-specific directory names. +// Fills in ResolvedPath object on success. +// Returns 'true' on success, and 'false' if either path is impossible to resolve +// or if the file path is forbidden to be accessed in current situation. +bool ResolveScriptPath(const String &sc_path, bool read_only, ResolvedPath &rp); +// Resolves a user file path for writing, and makes sure all the sub-directories are +// created along the actual path. +// Returns 'true' on success, and 'false' if either path is impossible to resolve, +// forbidden for writing, or if failed to create any subdirectories. +bool ResolveWritePathAndCreateDirs(const String &sc_path, ResolvedPath &rp); + +// Sets an optional path to treat like game's installation directory +void set_install_dir(const String &path, const String &audio_path, const String &voice_path); +// Returns a path to game installation directory (optionally a custom path could be set); +// does not include trailing '/' +String get_install_dir(); +String get_audio_install_dir(); +String get_voice_install_dir(); +void get_install_dir_path(char* buffer, const char *fileName); + +#endif // __AGS_EE_AC__PATHHELPER_H diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp new file mode 100644 index 000000000000..d9da238488fa --- /dev/null +++ b/engines/ags/engine/ac/properties.cpp @@ -0,0 +1,107 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/properties.h" +#include "ac/string.h" +#include "ac/dynobj/scriptstring.h" +#include "script/runtimescriptvalue.h" +#include "util/string_utils.h" + +using namespace AGS::Common; + +extern GameSetupStruct game; +extern ScriptString myScriptStringImpl; + +// begin custom property functions + +bool get_property_desc(PropertyDesc &desc, const char *property, PropertyType want_type) +{ + PropertySchema::const_iterator sch_it = game.propSchema.find(property); + if (sch_it == game.propSchema.end()) + quit("!GetProperty: no such property found in schema. Make sure you are using the property's name, and not its description, when calling this command."); + + desc = sch_it->second; + if (want_type == kPropertyString && desc.Type != kPropertyString) + quit("!GetTextProperty: need to use GetProperty for a non-text property"); + else if (want_type != kPropertyString && desc.Type == kPropertyString) + quit("!GetProperty: need to use GetTextProperty for a text property"); + return true; +} + +String get_property_value(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, const String def_val) +{ + // First check runtime properties, then static properties; + // if no matching entry was found, use default schema value + StringIMap::const_iterator it = rt_prop.find(property); + if (it != rt_prop.end()) + return it->second; + it = st_prop.find(property); + if (it != st_prop.end()) + return it->second; + return def_val; +} + +// Get an integer property +int get_int_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property) +{ + PropertyDesc desc; + if (!get_property_desc(desc, property, kPropertyInteger)) + return 0; + return StrUtil::StringToInt(get_property_value(st_prop, rt_prop, property, desc.DefaultValue)); +} + +// Get a string property +void get_text_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, char *bufer) +{ + PropertyDesc desc; + if (!get_property_desc(desc, property, kPropertyString)) + return; + + String val = get_property_value(st_prop, rt_prop, property, desc.DefaultValue); + strcpy(bufer, val); +} + +const char* get_text_property_dynamic_string(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property) +{ + PropertyDesc desc; + if (!get_property_desc(desc, property, kPropertyString)) + return nullptr; + + String val = get_property_value(st_prop, rt_prop, property, desc.DefaultValue); + return CreateNewScriptString(val); +} + +bool set_int_property(StringIMap &rt_prop, const char *property, int value) +{ + PropertyDesc desc; + if (get_property_desc(desc, property, kPropertyInteger)) + { + rt_prop[desc.Name] = StrUtil::IntToString(value); + return true; + } + return false; +} + +bool set_text_property(StringIMap &rt_prop, const char *property, const char* value) +{ + PropertyDesc desc; + if (get_property_desc(desc, property, kPropertyString)) + { + rt_prop[desc.Name] = value; + return true; + } + return false; +} diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h new file mode 100644 index 000000000000..f16831ead867 --- /dev/null +++ b/engines/ags/engine/ac/properties.h @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__PROPERTIES_H +#define __AGS_EE_AC__PROPERTIES_H + +#include "game/customproperties.h" + +using AGS::Common::StringIMap; + +// Getting a property value requires static and runtime property maps. +// Key is first searched in runtime map, if not found - static map is taken, +// which contains original property values for particular game entity. +// Lastly, if the key is still not found, then the default schema value is +// returned for the given property. +int get_int_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property); +void get_text_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, char *bufer); +const char* get_text_property_dynamic_string(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property); + +bool set_int_property(StringIMap &rt_prop, const char *property, int value); +bool set_text_property(StringIMap &rt_prop, const char *property, const char* value); + +#endif // __AGS_EE_AC__PROPERTIES_H diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp new file mode 100644 index 000000000000..6210ae387838 --- /dev/null +++ b/engines/ags/engine/ac/region.cpp @@ -0,0 +1,276 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/region.h" +#include "ac/common_defines.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_region.h" +#include "ac/room.h" +#include "ac/roomstatus.h" +#include "ac/dynobj/cc_region.h" +#include "ac/dynobj/scriptdrawingsurface.h" +#include "game/roomstruct.h" +#include "script/runtimescriptvalue.h" + +using namespace AGS::Common; + +extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; +extern RoomStruct thisroom; +extern RoomStatus*croom; +extern GameSetupStruct game; +extern COLOR_MAP maincoltable; +extern color palette[256]; +extern CCRegion ccDynamicRegion; + + +ScriptRegion *GetRegionAtRoom(int xx, int yy) { + return &scrRegion[GetRegionIDAtRoom(xx, yy)]; +} + +ScriptRegion *GetRegionAtScreen(int x, int y) +{ + VpPoint vpt = play.ScreenToRoomDivDown(x, y); + if (vpt.second < 0) + return nullptr; + return GetRegionAtRoom(vpt.first.X, vpt.first.Y); +} + +void Region_SetLightLevel(ScriptRegion *ssr, int brightness) { + SetAreaLightLevel(ssr->id, brightness); +} + +int Region_GetLightLevel(ScriptRegion *ssr) { + return thisroom.GetRegionLightLevel(ssr->id); +} + +int Region_GetTintEnabled(ScriptRegion *srr) { + if (thisroom.Regions[srr->id].Tint & 0xFF000000) + return 1; + return 0; +} + +int Region_GetTintRed(ScriptRegion *srr) { + + return thisroom.Regions[srr->id].Tint & 0x000000ff; +} + +int Region_GetTintGreen(ScriptRegion *srr) { + + return (thisroom.Regions[srr->id].Tint >> 8) & 0x000000ff; +} + +int Region_GetTintBlue(ScriptRegion *srr) { + + return (thisroom.Regions[srr->id].Tint >> 16) & 0x000000ff; +} + +int Region_GetTintSaturation(ScriptRegion *srr) { + + return (thisroom.Regions[srr->id].Tint >> 24) & 0xFF; +} + +int Region_GetTintLuminance(ScriptRegion *srr) +{ + return thisroom.GetRegionTintLuminance(srr->id); +} + +void Region_Tint(ScriptRegion *srr, int red, int green, int blue, int amount, int luminance) +{ + SetRegionTint(srr->id, red, green, blue, amount, luminance); +} + +void Region_TintNoLum(ScriptRegion *srr, int red, int green, int blue, int amount) +{ + SetRegionTint(srr->id, red, green, blue, amount); +} + +void Region_SetEnabled(ScriptRegion *ssr, int enable) { + if (enable) + EnableRegion(ssr->id); + else + DisableRegion(ssr->id); +} + +int Region_GetEnabled(ScriptRegion *ssr) { + return croom->region_enabled[ssr->id]; +} + +int Region_GetID(ScriptRegion *ssr) { + return ssr->id; +} + +void Region_RunInteraction(ScriptRegion *ssr, int mood) { + RunRegionInteraction(ssr->id, mood); +} + +//============================================================================= + +void generate_light_table() +{ + if (game.color_depth == 1 && color_map == nullptr) + { + create_light_table(&maincoltable, palette, 0, 0, 0, nullptr); + color_map = &maincoltable; + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// ScriptRegion *(int xx, int yy) +RuntimeScriptValue Sc_GetRegionAtRoom(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtRoom); +} + +RuntimeScriptValue Sc_GetRegionAtScreen(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtScreen); +} + +RuntimeScriptValue Sc_Region_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) +{ + ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaRegion); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +} + +RuntimeScriptValue Sc_Region_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT5(ScriptRegion, Region_Tint); +} + +// void (ScriptRegion *srr, int red, int green, int blue, int amount) +RuntimeScriptValue Sc_Region_TintNoLum(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(ScriptRegion, Region_TintNoLum); +} + +// void (ScriptRegion *ssr, int mood) +RuntimeScriptValue Sc_Region_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptRegion, Region_RunInteraction); +} + +// int (ScriptRegion *ssr) +RuntimeScriptValue Sc_Region_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetEnabled); +} + +// void (ScriptRegion *ssr, int enable) +RuntimeScriptValue Sc_Region_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptRegion, Region_SetEnabled); +} + +// int (ScriptRegion *ssr) +RuntimeScriptValue Sc_Region_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetID); +} + +// int (ScriptRegion *ssr) +RuntimeScriptValue Sc_Region_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetLightLevel); +} + +// void (ScriptRegion *ssr, int brightness) +RuntimeScriptValue Sc_Region_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptRegion, Region_SetLightLevel); +} + +// int (ScriptRegion *srr) +RuntimeScriptValue Sc_Region_GetTintEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetTintEnabled); +} + +// int (ScriptRegion *srr) +RuntimeScriptValue Sc_Region_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetTintBlue); +} + +// int (ScriptRegion *srr) +RuntimeScriptValue Sc_Region_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetTintGreen); +} + +// int (ScriptRegion *srr) +RuntimeScriptValue Sc_Region_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetTintRed); +} + +// int (ScriptRegion *srr) +RuntimeScriptValue Sc_Region_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetTintSaturation); +} + +RuntimeScriptValue Sc_Region_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptRegion, Region_GetTintLuminance); +} + + + +void RegisterRegionAPI() +{ + ccAddExternalStaticFunction("Region::GetAtRoomXY^2", Sc_GetRegionAtRoom); + ccAddExternalStaticFunction("Region::GetAtScreenXY^2", Sc_GetRegionAtScreen); + ccAddExternalStaticFunction("Region::GetDrawingSurface", Sc_Region_GetDrawingSurface); + ccAddExternalObjectFunction("Region::Tint^4", Sc_Region_TintNoLum); + ccAddExternalObjectFunction("Region::Tint^5", Sc_Region_Tint); + ccAddExternalObjectFunction("Region::RunInteraction^1", Sc_Region_RunInteraction); + ccAddExternalObjectFunction("Region::get_Enabled", Sc_Region_GetEnabled); + ccAddExternalObjectFunction("Region::set_Enabled", Sc_Region_SetEnabled); + ccAddExternalObjectFunction("Region::get_ID", Sc_Region_GetID); + ccAddExternalObjectFunction("Region::get_LightLevel", Sc_Region_GetLightLevel); + ccAddExternalObjectFunction("Region::set_LightLevel", Sc_Region_SetLightLevel); + ccAddExternalObjectFunction("Region::get_TintEnabled", Sc_Region_GetTintEnabled); + ccAddExternalObjectFunction("Region::get_TintBlue", Sc_Region_GetTintBlue); + ccAddExternalObjectFunction("Region::get_TintGreen", Sc_Region_GetTintGreen); + ccAddExternalObjectFunction("Region::get_TintRed", Sc_Region_GetTintRed); + ccAddExternalObjectFunction("Region::get_TintSaturation", Sc_Region_GetTintSaturation); + ccAddExternalObjectFunction("Region::get_TintLuminance", Sc_Region_GetTintLuminance); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Region::GetAtRoomXY^2", (void*)GetRegionAtRoom); + ccAddExternalFunctionForPlugin("Region::GetAtScreenXY^2", (void*)GetRegionAtScreen); + ccAddExternalFunctionForPlugin("Region::Tint^4", (void*)Region_TintNoLum); + ccAddExternalFunctionForPlugin("Region::RunInteraction^1", (void*)Region_RunInteraction); + ccAddExternalFunctionForPlugin("Region::get_Enabled", (void*)Region_GetEnabled); + ccAddExternalFunctionForPlugin("Region::set_Enabled", (void*)Region_SetEnabled); + ccAddExternalFunctionForPlugin("Region::get_ID", (void*)Region_GetID); + ccAddExternalFunctionForPlugin("Region::get_LightLevel", (void*)Region_GetLightLevel); + ccAddExternalFunctionForPlugin("Region::set_LightLevel", (void*)Region_SetLightLevel); + ccAddExternalFunctionForPlugin("Region::get_TintEnabled", (void*)Region_GetTintEnabled); + ccAddExternalFunctionForPlugin("Region::get_TintBlue", (void*)Region_GetTintBlue); + ccAddExternalFunctionForPlugin("Region::get_TintGreen", (void*)Region_GetTintGreen); + ccAddExternalFunctionForPlugin("Region::get_TintRed", (void*)Region_GetTintRed); + ccAddExternalFunctionForPlugin("Region::get_TintSaturation", (void*)Region_GetTintSaturation); +} diff --git a/engines/ags/engine/ac/region.h b/engines/ags/engine/ac/region.h new file mode 100644 index 000000000000..66ca3b3c1961 --- /dev/null +++ b/engines/ags/engine/ac/region.h @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__REGION_H +#define __AGS_EE_AC__REGION_H + +#include "ac/dynobj/scriptregion.h" + +ScriptRegion *GetRegionAtRoom(int xx, int yy); +void Region_SetLightLevel(ScriptRegion *ssr, int brightness); +int Region_GetLightLevel(ScriptRegion *ssr); +int Region_GetTintEnabled(ScriptRegion *srr); +int Region_GetTintRed(ScriptRegion *srr); +int Region_GetTintGreen(ScriptRegion *srr); +int Region_GetTintBlue(ScriptRegion *srr); +int Region_GetTintSaturation(ScriptRegion *srr); +int Region_GetTintLuminance(ScriptRegion *srr); +void Region_Tint(ScriptRegion *srr, int red, int green, int blue, int amount, int luminance); +void Region_SetEnabled(ScriptRegion *ssr, int enable); +int Region_GetEnabled(ScriptRegion *ssr); +int Region_GetID(ScriptRegion *ssr); +void Region_RunInteraction(ScriptRegion *ssr, int mood); + +void generate_light_table(); + +#endif // __AGS_EE_AC__REGION_H diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp new file mode 100644 index 000000000000..a0ed4187d039 --- /dev/null +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -0,0 +1,35 @@ + +#include "ac/richgamemedia.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +void RICH_GAME_MEDIA_HEADER::ReadFromFile(Stream *in) +{ + dwMagicNumber = in->ReadInt32(); + dwHeaderVersion = in->ReadInt32(); + dwHeaderSize = in->ReadInt32(); + dwThumbnailOffsetLowerDword = in->ReadInt32(); + dwThumbnailOffsetHigherDword = in->ReadInt32(); + dwThumbnailSize = in->ReadInt32(); + in->Read(guidGameId, 16); + in->ReadArrayOfInt16((int16_t*)szGameName, RM_MAXLENGTH); + in->ReadArrayOfInt16((int16_t*)szSaveName, RM_MAXLENGTH); + in->ReadArrayOfInt16((int16_t*)szLevelName, RM_MAXLENGTH); + in->ReadArrayOfInt16((int16_t*)szComments, RM_MAXLENGTH); +} + +void RICH_GAME_MEDIA_HEADER::WriteToFile(Stream *out) +{ + out->WriteInt32(dwMagicNumber); + out->WriteInt32(dwHeaderVersion); + out->WriteInt32(dwHeaderSize); + out->WriteInt32(dwThumbnailOffsetLowerDword); + out->WriteInt32(dwThumbnailOffsetHigherDword); + out->WriteInt32(dwThumbnailSize); + out->Write(guidGameId, 16); + out->WriteArrayOfInt16((int16_t*)szGameName, RM_MAXLENGTH); + out->WriteArrayOfInt16((int16_t*)szSaveName, RM_MAXLENGTH); + out->WriteArrayOfInt16((int16_t*)szLevelName, RM_MAXLENGTH); + out->WriteArrayOfInt16((int16_t*)szComments, RM_MAXLENGTH); +} diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h new file mode 100644 index 000000000000..0206ea841f22 --- /dev/null +++ b/engines/ags/engine/ac/richgamemedia.h @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__RICHGAMEMEDIA_H +#define __AGS_EE_AC__RICHGAMEMEDIA_H + +// Windows Vista Rich Save Games, modified to be platform-agnostic + +#define RM_MAXLENGTH 1024 +#define RM_MAGICNUMBER "RGMH" + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#pragma pack(push) +#pragma pack(1) +typedef struct _RICH_GAME_MEDIA_HEADER +{ + int dwMagicNumber; + int dwHeaderVersion; + int dwHeaderSize; + int dwThumbnailOffsetLowerDword; + int dwThumbnailOffsetHigherDword; + int dwThumbnailSize; + unsigned char guidGameId[16]; + unsigned short szGameName[RM_MAXLENGTH]; + unsigned short szSaveName[RM_MAXLENGTH]; + unsigned short szLevelName[RM_MAXLENGTH]; + unsigned short szComments[RM_MAXLENGTH]; + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); +} RICH_GAME_MEDIA_HEADER; +#pragma pack(pop) + +#endif // __AGS_EE_AC__RICHGAMEMEDIA_H diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp new file mode 100644 index 000000000000..016d2cbd004a --- /dev/null +++ b/engines/ags/engine/ac/room.cpp @@ -0,0 +1,1248 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include // for toupper + +#include "core/platform.h" +#include "util/string_utils.h" //strlwr() +#include "ac/common.h" +#include "ac/charactercache.h" +#include "ac/characterextras.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/global_character.h" +#include "ac/global_game.h" +#include "ac/global_object.h" +#include "ac/global_translation.h" +#include "ac/movelist.h" +#include "ac/mouse.h" +#include "ac/objectcache.h" +#include "ac/overlay.h" +#include "ac/properties.h" +#include "ac/region.h" +#include "ac/sys_events.h" +#include "ac/room.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "ac/screen.h" +#include "ac/string.h" +#include "ac/system.h" +#include "ac/walkablearea.h" +#include "ac/walkbehind.h" +#include "ac/dynobj/scriptobject.h" +#include "ac/dynobj/scripthotspot.h" +#include "gui/guidefines.h" +#include "script/cc_instance.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "debug/out.h" +#include "game/room_version.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "script/cc_error.h" +#include "script/script.h" +#include "script/script_runtime.h" +#include "ac/spritecache.h" +#include "util/stream.h" +#include "gfx/graphicsdriver.h" +#include "core/assetmanager.h" +#include "ac/dynobj/all_dynamicclasses.h" +#include "gfx/bitmap.h" +#include "gfx/gfxfilter.h" +#include "util/math.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetup usetup; +extern GameSetupStruct game; +extern GameState play; +extern RoomStatus*croom; +extern RoomStatus troom; // used for non-saveable rooms, eg. intro +extern int displayed_room; +extern RoomObject*objs; +extern ccInstance *roominst; +extern AGSPlatformDriver *platform; +extern int numevents; +extern CharacterCache *charcache; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; +extern CharacterExtras *charextra; +extern int done_es_error; +extern int our_eip; +extern Bitmap *walkareabackup, *walkable_areas_temp; +extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; +extern SpriteCache spriteset; +extern int in_new_room, new_room_was; // 1 in new room, 2 first time in new room, 3 loading saved game +extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; +extern int in_leaves_screen; +extern CharacterInfo*playerchar; +extern int starting_room; +extern unsigned int loopcounter; +extern IDriverDependantBitmap* roomBackgroundBmp; +extern IGraphicsDriver *gfxDriver; +extern Bitmap *raw_saved_screen; +extern int actSpsCount; +extern Bitmap **actsps; +extern IDriverDependantBitmap* *actspsbmp; +extern Bitmap **actspswb; +extern IDriverDependantBitmap* *actspswbbmp; +extern CachedActSpsData* actspswbcache; +extern color palette[256]; +extern int mouse_z_was; + +extern Bitmap **guibg; +extern IDriverDependantBitmap **guibgbmp; + +extern CCHotspot ccDynamicHotspot; +extern CCObject ccDynamicObject; + +RGB_MAP rgb_table; // for 256-col antialiasing +int new_room_flags=0; +int gs_to_newroom=-1; + +ScriptDrawingSurface* Room_GetDrawingSurfaceForBackground(int backgroundNumber) +{ + if (displayed_room < 0) + quit("!Room.GetDrawingSurfaceForBackground: no room is currently loaded"); + + if (backgroundNumber == SCR_NO_VALUE) + { + backgroundNumber = play.bg_frame; + } + + if ((backgroundNumber < 0) || ((size_t)backgroundNumber >= thisroom.BgFrameCount)) + quit("!Room.GetDrawingSurfaceForBackground: invalid background number specified"); + + + ScriptDrawingSurface *surface = new ScriptDrawingSurface(); + surface->roomBackgroundNumber = backgroundNumber; + ccRegisterManagedObject(surface, surface); + return surface; +} + +ScriptDrawingSurface* Room_GetDrawingSurfaceForMask(RoomAreaMask mask) +{ + if (displayed_room < 0) + quit("!Room_GetDrawingSurfaceForMask: no room is currently loaded"); + ScriptDrawingSurface *surface = new ScriptDrawingSurface(); + surface->roomMaskType = mask; + ccRegisterManagedObject(surface, surface); + return surface; +} + +int Room_GetObjectCount() { + return croom->numobj; +} + +int Room_GetWidth() { + return thisroom.Width; +} + +int Room_GetHeight() { + return thisroom.Height; +} + +int Room_GetColorDepth() { + return thisroom.BgFrames[0].Graphic->GetColorDepth(); +} + +int Room_GetLeftEdge() { + return thisroom.Edges.Left; +} + +int Room_GetRightEdge() { + return thisroom.Edges.Right; +} + +int Room_GetTopEdge() { + return thisroom.Edges.Top; +} + +int Room_GetBottomEdge() { + return thisroom.Edges.Bottom; +} + +int Room_GetMusicOnLoad() { + return thisroom.Options.StartupMusic; +} + +int Room_GetProperty(const char *property) +{ + return get_int_property(thisroom.Properties, croom->roomProps, property); +} + +const char* Room_GetTextProperty(const char *property) +{ + return get_text_property_dynamic_string(thisroom.Properties, croom->roomProps, property); +} + +bool Room_SetProperty(const char *property, int value) +{ + return set_int_property(croom->roomProps, property, value); +} + +bool Room_SetTextProperty(const char *property, const char *value) +{ + return set_text_property(croom->roomProps, property, value); +} + +const char* Room_GetMessages(int index) { + if ((index < 0) || ((size_t)index >= thisroom.MessageCount)) { + return nullptr; + } + char buffer[STD_BUFFER_SIZE]; + buffer[0]=0; + replace_tokens(get_translation(thisroom.Messages[index]), buffer, STD_BUFFER_SIZE); + return CreateNewScriptString(buffer); +} + + +//============================================================================= + +// Makes sure that room background and walk-behind mask are matching room size +// in game resolution coordinates; in other words makes graphics appropriate +// for display in the game. +void convert_room_background_to_game_res() +{ + if (!game.AllowRelativeRes() || !thisroom.IsRelativeRes()) + return; + + int bkg_width = thisroom.Width; + int bkg_height = thisroom.Height; + data_to_game_coords(&bkg_width, &bkg_height); + + for (size_t i = 0; i < thisroom.BgFrameCount; ++i) + thisroom.BgFrames[i].Graphic = FixBitmap(thisroom.BgFrames[i].Graphic, bkg_width, bkg_height); + + // Fix walk-behinds to match room background + // TODO: would not we need to do similar to each mask if they were 1:1 in hires room? + thisroom.WalkBehindMask = FixBitmap(thisroom.WalkBehindMask, bkg_width, bkg_height); +} + + +void save_room_data_segment () { + croom->FreeScriptData(); + + croom->tsdatasize = roominst->globaldatasize; + if (croom->tsdatasize > 0) { + croom->tsdata=(char*)malloc(croom->tsdatasize+10); + memcpy(croom->tsdata,&roominst->globaldata[0],croom->tsdatasize); + } + +} + +void unload_old_room() { + int ff; + + // if switching games on restore, don't do this + if (displayed_room < 0) + return; + + debug_script_log("Unloading room %d", displayed_room); + + current_fade_out_effect(); + + dispose_room_drawdata(); + + for (ff=0;ffnumobj;ff++) + objs[ff].moving = 0; + + if (!play.ambient_sounds_persist) { + for (ff = 1; ff < MAX_SOUND_CHANNELS; ff++) + StopAmbientSound(ff); + } + + cancel_all_scripts(); + numevents = 0; // cancel any pending room events + + if (roomBackgroundBmp != nullptr) + { + gfxDriver->DestroyDDB(roomBackgroundBmp); + roomBackgroundBmp = nullptr; + } + + if (croom==nullptr) ; + else if (roominst!=nullptr) { + save_room_data_segment(); + delete roominstFork; + delete roominst; + roominstFork = nullptr; + roominst=nullptr; + } + else croom->tsdatasize=0; + memset(&play.walkable_areas_on[0],1,MAX_WALK_AREAS+1); + play.bg_frame=0; + play.bg_frame_locked=0; + remove_screen_overlay(-1); + delete raw_saved_screen; + raw_saved_screen = nullptr; + for (ff = 0; ff < MAX_ROOM_BGFRAMES; ff++) + play.raw_modified[ff] = 0; + for (size_t i = 0; i < thisroom.LocalVariables.size() && i < MAX_GLOBAL_VARIABLES; ++i) + croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value; + + // wipe the character cache when we change rooms + for (ff = 0; ff < game.numcharacters; ff++) { + if (charcache[ff].inUse) { + delete charcache[ff].image; + charcache[ff].image = nullptr; + charcache[ff].inUse = 0; + } + // ensure that any half-moves (eg. with scaled movement) are stopped + charextra[ff].xwas = INVALID_X; + } + + play.swap_portrait_lastchar = -1; + play.swap_portrait_lastlastchar = -1; + + for (ff = 0; ff < croom->numobj; ff++) { + // un-export the object's script object + if (objectScriptObjNames[ff].IsEmpty()) + continue; + + ccRemoveExternalSymbol(objectScriptObjNames[ff]); + } + + for (ff = 0; ff < MAX_ROOM_HOTSPOTS; ff++) { + if (thisroom.Hotspots[ff].ScriptName.IsEmpty()) + continue; + + ccRemoveExternalSymbol(thisroom.Hotspots[ff].ScriptName); + } + + croom_ptr_clear(); + + // clear the object cache + for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) { + delete objcache[ff].image; + objcache[ff].image = nullptr; + } + // clear the actsps buffers to save memory, since the + // objects/characters involved probably aren't on the + // new screen. this also ensures all cached data is flushed + for (ff = 0; ff < MAX_ROOM_OBJECTS + game.numcharacters; ff++) { + delete actsps[ff]; + actsps[ff] = nullptr; + + if (actspsbmp[ff] != nullptr) + gfxDriver->DestroyDDB(actspsbmp[ff]); + actspsbmp[ff] = nullptr; + + delete actspswb[ff]; + actspswb[ff] = nullptr; + + if (actspswbbmp[ff] != nullptr) + gfxDriver->DestroyDDB(actspswbbmp[ff]); + actspswbbmp[ff] = nullptr; + + actspswbcache[ff].valid = 0; + } + + // if Hide Player Character was ticked, restore it to visible + if (play.temporarily_turned_off_character >= 0) { + game.chars[play.temporarily_turned_off_character].on = 1; + play.temporarily_turned_off_character = -1; + } + +} + +// Convert all room objects to the data resolution (only if it's different from game resolution). +// TODO: merge this into UpdateRoomData? or this is required for engine only? +void convert_room_coordinates_to_data_res(RoomStruct *rstruc) +{ + if (game.GetDataUpscaleMult() == 1) + return; + + const int mul = game.GetDataUpscaleMult(); + for (size_t i = 0; i < rstruc->ObjectCount; ++i) + { + rstruc->Objects[i].X /= mul; + rstruc->Objects[i].Y /= mul; + if (rstruc->Objects[i].Baseline > 0) + { + rstruc->Objects[i].Baseline /= mul; + } + } + + for (size_t i = 0; i < rstruc->HotspotCount; ++i) + { + rstruc->Hotspots[i].WalkTo.X /= mul; + rstruc->Hotspots[i].WalkTo.Y /= mul; + } + + for (size_t i = 0; i < rstruc->WalkBehindCount; ++i) + { + rstruc->WalkBehinds[i].Baseline /= mul; + } + + rstruc->Edges.Left /= mul; + rstruc->Edges.Top /= mul; + rstruc->Edges.Bottom /= mul; + rstruc->Edges.Right /= mul; + rstruc->Width /= mul; + rstruc->Height /= mul; +} + +extern int convert_16bit_bgr; + +void update_letterbox_mode() +{ + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + const Rect game_frame = RectWH(game.GetGameRes()); + Rect new_main_view = game_frame; + // In the original engine the letterbox feature only allowed viewports of + // either 200 or 240 (400 and 480) pixels, if the room height was equal or greater than 200 (400). + // Also, the UI viewport should be matching room viewport in that case. + // NOTE: if "OPT_LETTERBOX" is false, altsize.Height = size.Height always. + const int viewport_height = + real_room_sz.Height < game.GetLetterboxSize().Height ? real_room_sz.Height : + (real_room_sz.Height >= game.GetLetterboxSize().Height && real_room_sz.Height < game.GetGameRes().Height) ? game.GetLetterboxSize().Height : + game.GetGameRes().Height; + new_main_view.SetHeight(viewport_height); + + play.SetMainViewport(CenterInRect(game_frame, new_main_view)); + play.SetUIViewport(new_main_view); +} + +// Automatically reset primary room viewport and camera to match the new room size +static void adjust_viewport_to_room() +{ + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + const Rect main_view = play.GetMainViewport(); + Rect new_room_view = RectWH(Size::Clamp(real_room_sz, Size(1, 1), main_view.GetSize())); + + auto view = play.GetRoomViewport(0); + view->SetRect(new_room_view); + auto cam = view->GetCamera(); + if (cam) + { + cam->SetSize(new_room_view.GetSize()); + cam->SetAt(0, 0); + cam->Release(); + } +} + +// Run through all viewports and cameras to make sure they can work in new room's bounds +static void update_all_viewcams_with_newroom() +{ + for (int i = 0; i < play.GetRoomCameraCount(); ++i) + { + auto cam = play.GetRoomCamera(i); + const Rect old_pos = cam->GetRect(); + cam->SetSize(old_pos.GetSize()); + cam->SetAt(old_pos.Left, old_pos.Top); + } +} + +// forchar = playerchar on NewRoom, or NULL if restore saved game +void load_new_room(int newnum, CharacterInfo*forchar) { + + debug_script_log("Loading room %d", newnum); + + String room_filename; + int cc; + done_es_error = 0; + play.room_changes ++; + // TODO: find out why do we need to temporarily lower color depth to 8-bit. + // Or do we? There's a serious usability problem in this: if any bitmap is + // created meanwhile it will have this color depth by default, which may + // lead to unexpected errors. + set_color_depth(8); + displayed_room=newnum; + + room_filename.Format("room%d.crm", newnum); + if (newnum == 0) { + // support both room0.crm and intro.crm + // 2.70: Renamed intro.crm to room0.crm, to stop it causing confusion + if ((loaded_game_file_version < kGameVersion_270 && Common::AssetManager::DoesAssetExist("intro.crm")) || + (loaded_game_file_version >= kGameVersion_270 && !Common::AssetManager::DoesAssetExist(room_filename))) + { + room_filename = "intro.crm"; + } + } + + update_polled_stuff_if_runtime(); + + // load the room from disk + our_eip=200; + thisroom.GameID = NO_GAME_ID_IN_ROOM_FILE; + load_room(room_filename, &thisroom, game.IsLegacyHiRes(), game.SpriteInfos); + + if ((thisroom.GameID != NO_GAME_ID_IN_ROOM_FILE) && + (thisroom.GameID != game.uniqueid)) { + quitprintf("!Unable to load '%s'. This room file is assigned to a different game.", room_filename.GetCStr()); + } + + convert_room_coordinates_to_data_res(&thisroom); + + update_polled_stuff_if_runtime(); + our_eip=201; + /* // apparently, doing this stops volume spiking between tracks + if (thisroom.Options.StartupMusic>0) { + stopmusic(); + delay(100); + }*/ + + play.room_width = thisroom.Width; + play.room_height = thisroom.Height; + play.anim_background_speed = thisroom.BgAnimSpeed; + play.bg_anim_delay = play.anim_background_speed; + + // do the palette + for (cc=0;cc<256;cc++) { + if (game.paluses[cc]==PAL_BACKGROUND) + palette[cc]=thisroom.Palette[cc]; + else { + // copy the gamewide colours into the room palette + for (size_t i = 0; i < thisroom.BgFrameCount; ++i) + thisroom.BgFrames[i].Palette[cc] = palette[cc]; + } + } + + for (size_t i = 0; i < thisroom.BgFrameCount; ++i) { + update_polled_stuff_if_runtime(); + thisroom.BgFrames[i].Graphic = PrepareSpriteForUse(thisroom.BgFrames[i].Graphic, false); + } + + update_polled_stuff_if_runtime(); + + our_eip=202; + // Update game viewports + if (game.IsLegacyLetterbox()) + update_letterbox_mode(); + SetMouseBounds(0, 0, 0, 0); + + our_eip=203; + in_new_room=1; + + // walkable_areas_temp is used by the pathfinder to generate a + // copy of the walkable areas - allocate it here to save time later + delete walkable_areas_temp; + walkable_areas_temp = BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight(), 8); + + // Make a backup copy of the walkable areas prior to + // any RemoveWalkableArea commands + delete walkareabackup; + // copy the walls screen + walkareabackup=BitmapHelper::CreateBitmapCopy(thisroom.WalkAreaMask.get()); + + our_eip=204; + update_polled_stuff_if_runtime(); + redo_walkable_areas(); + update_polled_stuff_if_runtime(); + + set_color_depth(game.GetColorDepth()); + convert_room_background_to_game_res(); + recache_walk_behinds(); + update_polled_stuff_if_runtime(); + + our_eip=205; + // setup objects + if (forchar != nullptr) { + // if not restoring a game, always reset this room + troom.beenhere=0; + troom.FreeScriptData(); + troom.FreeProperties(); + memset(&troom.hotspot_enabled[0],1,MAX_ROOM_HOTSPOTS); + memset(&troom.region_enabled[0], 1, MAX_ROOM_REGIONS); + } + if ((newnum>=0) & (newnumbeenhere > 0) { + // if we've been here before, save the Times Run information + // since we will overwrite the actual NewInteraction structs + // (cos they have pointers and this might have been loaded from + // a save game) + if (thisroom.EventHandlers == nullptr) + {// legacy interactions + thisroom.Interaction->CopyTimesRun(croom->intrRoom); + for (cc=0;cc < MAX_ROOM_HOTSPOTS;cc++) + thisroom.Hotspots[cc].Interaction->CopyTimesRun(croom->intrHotspot[cc]); + for (cc=0;cc < MAX_ROOM_OBJECTS;cc++) + thisroom.Objects[cc].Interaction->CopyTimesRun(croom->intrObject[cc]); + for (cc=0;cc < MAX_ROOM_REGIONS;cc++) + thisroom.Regions[cc].Interaction->CopyTimesRun(croom->intrRegion[cc]); + } + } + if (croom->beenhere==0) { + croom->numobj=thisroom.ObjectCount; + croom->tsdatasize=0; + for (cc=0;ccnumobj;cc++) { + croom->obj[cc].x=thisroom.Objects[cc].X; + croom->obj[cc].y=thisroom.Objects[cc].Y; + croom->obj[cc].num=thisroom.Objects[cc].Sprite; + croom->obj[cc].on=thisroom.Objects[cc].IsOn; + croom->obj[cc].view=-1; + croom->obj[cc].loop=0; + croom->obj[cc].frame=0; + croom->obj[cc].wait=0; + croom->obj[cc].transparent=0; + croom->obj[cc].moving=-1; + croom->obj[cc].flags = thisroom.Objects[cc].Flags; + croom->obj[cc].baseline=-1; + croom->obj[cc].zoom = 100; + croom->obj[cc].last_width = 0; + croom->obj[cc].last_height = 0; + croom->obj[cc].blocking_width = 0; + croom->obj[cc].blocking_height = 0; + if (thisroom.Objects[cc].Baseline>=0) + // croom->obj[cc].baseoffs=thisroom.Objects.Baseline[cc]-thisroom.Objects[cc].y; + croom->obj[cc].baseline=thisroom.Objects[cc].Baseline; + } + for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i) + croom->walkbehind_base[i] = thisroom.WalkBehinds[i].Baseline; + for (cc=0;ccflagstates[cc]=0; + + /* // we copy these structs for the Score column to work + croom->misccond=thisroom.misccond; + for (cc=0;cchscond[cc]=thisroom.hscond[cc]; + for (cc=0;ccobjcond[cc]=thisroom.objcond[cc];*/ + + for (cc=0;cc < MAX_ROOM_HOTSPOTS;cc++) { + croom->hotspot_enabled[cc] = 1; + } + for (cc = 0; cc < MAX_ROOM_REGIONS; cc++) { + croom->region_enabled[cc] = 1; + } + + croom->beenhere=1; + in_new_room=2; + } + else { + // We have been here before + for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i) + thisroom.LocalVariables[i].Value = croom->interactionVariableValues[i]; + } + + update_polled_stuff_if_runtime(); + + if (thisroom.EventHandlers == nullptr) + {// legacy interactions + // copy interactions from room file into our temporary struct + croom->intrRoom = *thisroom.Interaction; + for (cc=0;ccintrHotspot[cc] = *thisroom.Hotspots[cc].Interaction; + for (cc=0;ccintrObject[cc] = *thisroom.Objects[cc].Interaction; + for (cc=0;ccintrRegion[cc] = *thisroom.Regions[cc].Interaction; + } + + objs=&croom->obj[0]; + + for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++) { + // 64 bit: Using the id instead + // scrObj[cc].obj = &croom->obj[cc]; + objectScriptObjNames[cc].Free(); + } + + for (cc = 0; cc < croom->numobj; cc++) { + // export the object's script object + if (thisroom.Objects[cc].ScriptName.IsEmpty()) + continue; + objectScriptObjNames[cc] = thisroom.Objects[cc].ScriptName; + ccAddExternalDynamicObject(objectScriptObjNames[cc], &scrObj[cc], &ccDynamicObject); + } + + for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) { + if (thisroom.Hotspots[cc].ScriptName.IsEmpty()) + continue; + + ccAddExternalDynamicObject(thisroom.Hotspots[cc].ScriptName, &scrHotspot[cc], &ccDynamicHotspot); + } + + our_eip=206; + /* THIS IS DONE IN THE EDITOR NOW + thisroom.BgFrames.IsPaletteShared[0] = 1; + for (dd = 1; dd < thisroom.BgFrameCount; dd++) { + if (memcmp (&thisroom.BgFrames.Palette[dd][0], &palette[0], sizeof(color) * 256) == 0) + thisroom.BgFrames.IsPaletteShared[dd] = 1; + else + thisroom.BgFrames.IsPaletteShared[dd] = 0; + } + // only make the first frame shared if the last is + if (thisroom.BgFrames.IsPaletteShared[thisroom.BgFrameCount - 1] == 0) + thisroom.BgFrames.IsPaletteShared[0] = 0;*/ + + update_polled_stuff_if_runtime(); + + our_eip = 210; + if (IS_ANTIALIAS_SPRITES) { + // sometimes the palette has corrupt entries, which crash + // the create_rgb_table call + // so, fix them + for (int ff = 0; ff < 256; ff++) { + if (palette[ff].r > 63) + palette[ff].r = 63; + if (palette[ff].g > 63) + palette[ff].g = 63; + if (palette[ff].b > 63) + palette[ff].b = 63; + } + create_rgb_table (&rgb_table, palette, nullptr); + rgb_map = &rgb_table; + } + our_eip = 211; + if (forchar!=nullptr) { + // if it's not a Restore Game + + // if a following character is still waiting to come into the + // previous room, force it out so that the timer resets + for (int ff = 0; ff < game.numcharacters; ff++) { + if ((game.chars[ff].following >= 0) && (game.chars[ff].room < 0)) { + if ((game.chars[ff].following == game.playercharacter) && + (forchar->prevroom == newnum)) + // the player went back to the previous room, so make sure + // the following character is still there + game.chars[ff].room = newnum; + else + game.chars[ff].room = game.chars[game.chars[ff].following].room; + } + } + + forchar->prevroom=forchar->room; + forchar->room=newnum; + // only stop moving if it's a new room, not a restore game + for (cc=0;cctsdatasize>0) { + if (croom->tsdatasize != roominst->globaldatasize) + quit("room script data segment size has changed"); + memcpy(&roominst->globaldata[0],croom->tsdata,croom->tsdatasize); + } + } + our_eip=207; + play.entered_edge = -1; + + if ((new_room_x != SCR_NO_VALUE) && (forchar != nullptr)) + { + forchar->x = new_room_x; + forchar->y = new_room_y; + + if (new_room_loop != SCR_NO_VALUE) + forchar->loop = new_room_loop; + } + new_room_x = SCR_NO_VALUE; + new_room_loop = SCR_NO_VALUE; + + if ((new_room_pos>0) & (forchar!=nullptr)) { + if (new_room_pos>=4000) { + play.entered_edge = 3; + forchar->y = thisroom.Edges.Top + get_fixed_pixel_size(1); + forchar->x=new_room_pos%1000; + if (forchar->x==0) forchar->x=thisroom.Width/2; + if (forchar->x <= thisroom.Edges.Left) + forchar->x = thisroom.Edges.Left + 3; + if (forchar->x >= thisroom.Edges.Right) + forchar->x = thisroom.Edges.Right - 3; + forchar->loop=0; + } + else if (new_room_pos>=3000) { + play.entered_edge = 2; + forchar->y = thisroom.Edges.Bottom - get_fixed_pixel_size(1); + forchar->x=new_room_pos%1000; + if (forchar->x==0) forchar->x=thisroom.Width/2; + if (forchar->x <= thisroom.Edges.Left) + forchar->x = thisroom.Edges.Left + 3; + if (forchar->x >= thisroom.Edges.Right) + forchar->x = thisroom.Edges.Right - 3; + forchar->loop=3; + } + else if (new_room_pos>=2000) { + play.entered_edge = 1; + forchar->x = thisroom.Edges.Right - get_fixed_pixel_size(1); + forchar->y=new_room_pos%1000; + if (forchar->y==0) forchar->y=thisroom.Height/2; + if (forchar->y <= thisroom.Edges.Top) + forchar->y = thisroom.Edges.Top + 3; + if (forchar->y >= thisroom.Edges.Bottom) + forchar->y = thisroom.Edges.Bottom - 3; + forchar->loop=1; + } + else if (new_room_pos>=1000) { + play.entered_edge = 0; + forchar->x = thisroom.Edges.Left + get_fixed_pixel_size(1); + forchar->y=new_room_pos%1000; + if (forchar->y==0) forchar->y=thisroom.Height/2; + if (forchar->y <= thisroom.Edges.Top) + forchar->y = thisroom.Edges.Top + 3; + if (forchar->y >= thisroom.Edges.Bottom) + forchar->y = thisroom.Edges.Bottom - 3; + forchar->loop=2; + } + // if starts on un-walkable area + if (get_walkable_area_pixel(forchar->x, forchar->y) == 0) { + if (new_room_pos>=3000) { // bottom or top of screen + int tryleft=forchar->x - 1,tryright=forchar->x + 1; + while (1) { + if (get_walkable_area_pixel(tryleft, forchar->y) > 0) { + forchar->x=tryleft; break; } + if (get_walkable_area_pixel(tryright, forchar->y) > 0) { + forchar->x=tryright; break; } + int nowhere=0; + if (tryleft>thisroom.Edges.Left) { tryleft--; nowhere++; } + if (tryright=1000) { // left or right + int tryleft=forchar->y - 1,tryright=forchar->y + 1; + while (1) { + if (get_walkable_area_pixel(forchar->x, tryleft) > 0) { + forchar->y=tryleft; break; } + if (get_walkable_area_pixel(forchar->x, tryright) > 0) { + forchar->y=tryright; break; } + int nowhere=0; + if (tryleft>thisroom.Edges.Top) { tryleft--; nowhere++; } + if (tryrightx; + play.entered_at_y=forchar->y; + if (forchar->x >= thisroom.Edges.Right) + play.entered_edge = 1; + else if (forchar->x <= thisroom.Edges.Left) + play.entered_edge = 0; + else if (forchar->y >= thisroom.Edges.Bottom) + play.entered_edge = 2; + else if (forchar->y <= thisroom.Edges.Top) + play.entered_edge = 3; + } + if (thisroom.Options.StartupMusic>0) + PlayMusicResetQueue(thisroom.Options.StartupMusic); + + our_eip=208; + if (forchar!=nullptr) { + if (thisroom.Options.PlayerCharOff==0) { forchar->on=1; + enable_cursor_mode(0); } + else { + forchar->on=0; + disable_cursor_mode(0); + // remember which character we turned off, in case they + // use SetPlyaerChracter within this room (so we re-enable + // the correct character when leaving the room) + play.temporarily_turned_off_character = game.playercharacter; + } + if (forchar->flags & CHF_FIXVIEW) ; + else if (thisroom.Options.PlayerView==0) forchar->view=forchar->defview; + else forchar->view=thisroom.Options.PlayerView-1; + forchar->frame=0; // make him standing + } + color_map = nullptr; + + our_eip = 209; + update_polled_stuff_if_runtime(); + generate_light_table(); + update_music_volume(); + + // If we are not restoring a save, update cameras to accomodate for this + // new room; otherwise this is done later when cameras are recreated. + if (forchar != nullptr) + { + if (play.IsAutoRoomViewport()) + adjust_viewport_to_room(); + update_all_viewcams_with_newroom(); + play.UpdateRoomCameras(); // update auto tracking + } + init_room_drawdata(); + + our_eip = 212; + invalidate_screen(); + for (cc=0;ccnumobj;cc++) { + if (objs[cc].on == 2) + MergeObject(cc); + } + new_room_flags=0; + play.gscript_timer=-1; // avoid screw-ups with changing screens + play.player_on_region = 0; + // trash any input which they might have done while it was loading + ags_clear_input_buffer(); + // no fade in, so set the palette immediately in case of 256-col sprites + if (game.color_depth > 1) + setpal(); + + our_eip=220; + update_polled_stuff_if_runtime(); + debug_script_log("Now in room %d", displayed_room); + guis_need_update = 1; + pl_run_plugin_hooks(AGSE_ENTERROOM, displayed_room); + // MoveToWalkableArea(game.playercharacter); + // MSS_CHECK_ALL_BLOCKS; +} + +extern int psp_clear_cache_on_room_change; + +// new_room: changes the current room number, and loads the new room from disk +void new_room(int newnum,CharacterInfo*forchar) { + EndSkippingUntilCharStops(); + + debug_script_log("Room change requested to room %d", newnum); + + update_polled_stuff_if_runtime(); + + // we are currently running Leaves Screen scripts + in_leaves_screen = newnum; + + // player leaves screen event + run_room_event(8); + // Run the global OnRoomLeave event + run_on_event (GE_LEAVE_ROOM, RuntimeScriptValue().SetInt32(displayed_room)); + + pl_run_plugin_hooks(AGSE_LEAVEROOM, displayed_room); + + // update the new room number if it has been altered by OnLeave scripts + newnum = in_leaves_screen; + in_leaves_screen = -1; + + if ((playerchar->following >= 0) && + (game.chars[playerchar->following].room != newnum)) { + // the player character is following another character, + // who is not in the new room. therefore, abort the follow + playerchar->following = -1; + } + update_polled_stuff_if_runtime(); + + // change rooms + unload_old_room(); + + if (psp_clear_cache_on_room_change) + { + // Delete all cached sprites + spriteset.DisposeAll(); + + // Delete all gui background images + for (int i = 0; i < game.numgui; i++) + { + delete guibg[i]; + guibg[i] = nullptr; + + if (guibgbmp[i]) + gfxDriver->DestroyDDB(guibgbmp[i]); + guibgbmp[i] = nullptr; + } + guis_need_update = 1; + } + + update_polled_stuff_if_runtime(); + + load_new_room(newnum,forchar); +} + +int find_highest_room_entered() { + int qq,fndas=-1; + for (qq=0;qqbeenhere != 0)) + fndas = qq; + } + // This is actually legal - they might start in room 400 and save + //if (fndas<0) quit("find_highest_room: been in no rooms?"); + return fndas; +} + +void first_room_initialization() { + starting_room = displayed_room; + set_loop_counter(0); + mouse_z_was = mouse_z; +} + +void check_new_room() { + // if they're in a new room, run Player Enters Screen and on_event(ENTER_ROOM) + if ((in_new_room>0) & (in_new_room!=3)) { + EventHappened evh; + evh.type = EV_RUNEVBLOCK; + evh.data1 = EVB_ROOM; + evh.data2 = 0; + evh.data3 = 5; + evh.player=game.playercharacter; + // make sure that any script calls don't re-call enters screen + int newroom_was = in_new_room; + in_new_room = 0; + play.disabled_user_interface ++; + process_event(&evh); + play.disabled_user_interface --; + in_new_room = newroom_was; + // setevent(EV_RUNEVBLOCK,EVB_ROOM,0,5); + } +} + +void compile_room_script() { + ccError = 0; + + roominst = ccInstance::CreateFromScript(thisroom.CompiledScript); + + if ((ccError!=0) || (roominst==nullptr)) { + quitprintf("Unable to create local script: %s", ccErrorString.GetCStr()); + } + + roominstFork = roominst->Fork(); + if (roominstFork == nullptr) + quitprintf("Unable to create forked room instance: %s", ccErrorString.GetCStr()); + + repExecAlways.roomHasFunction = true; + lateRepExecAlways.roomHasFunction = true; + getDialogOptionsDimensionsFunc.roomHasFunction = true; +} + +int bg_just_changed = 0; + +void on_background_frame_change () { + + invalidate_screen(); + mark_current_background_dirty(); + invalidate_cached_walkbehinds(); + + // get the new frame's palette + memcpy (palette, thisroom.BgFrames[play.bg_frame].Palette, sizeof(color) * 256); + + // hi-colour, update the palette. It won't have an immediate effect + // but will be drawn properly when the screen fades in + if (game.color_depth > 1) + setpal(); + + if (in_enters_screen) + return; + + // Don't update the palette if it hasn't changed + if (thisroom.BgFrames[play.bg_frame].IsPaletteShared) + return; + + // 256-colours, tell it to update the palette (will actually be done as + // close as possible to the screen update to prevent flicker problem) + if (game.color_depth == 1) + bg_just_changed = 1; +} + +void croom_ptr_clear() +{ + croom = nullptr; + objs = nullptr; +} + + +AGS_INLINE int room_to_mask_coord(int coord) +{ + return coord * game.GetDataUpscaleMult() / thisroom.MaskResolution; +} + +AGS_INLINE int mask_to_room_coord(int coord) +{ + return coord * thisroom.MaskResolution / game.GetDataUpscaleMult(); +} + +void convert_move_path_to_room_resolution(MoveList *ml) +{ + if ((game.options[OPT_WALKSPEEDABSOLUTE] != 0) && game.GetDataUpscaleMult() > 1) + { // Speeds are independent from MaskResolution + for (int i = 0; i < ml->numstage; i++) + { // ...so they are not multiplied by MaskResolution factor when converted to room coords + ml->xpermove[i] = ml->xpermove[i] / game.GetDataUpscaleMult(); + ml->ypermove[i] = ml->ypermove[i] / game.GetDataUpscaleMult(); + } + } + + if (thisroom.MaskResolution == game.GetDataUpscaleMult()) + return; + + ml->fromx = mask_to_room_coord(ml->fromx); + ml->fromy = mask_to_room_coord(ml->fromy); + ml->lastx = mask_to_room_coord(ml->lastx); + ml->lasty = mask_to_room_coord(ml->lasty); + + for (int i = 0; i < ml->numstage; i++) + { + uint16_t lowPart = mask_to_room_coord(ml->pos[i] & 0x0000ffff); + uint16_t highPart = mask_to_room_coord((ml->pos[i] >> 16) & 0x0000ffff); + ml->pos[i] = ((int)highPart << 16) | (lowPart & 0x0000ffff); + } + + if (game.options[OPT_WALKSPEEDABSOLUTE] == 0) + { // Speeds are scaling with MaskResolution + for (int i = 0; i < ml->numstage; i++) + { + ml->xpermove[i] = mask_to_room_coord(ml->xpermove[i]); + ml->ypermove[i] = mask_to_room_coord(ml->ypermove[i]); + } + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// ScriptDrawingSurface* (int backgroundNumber) +RuntimeScriptValue Sc_Room_GetDrawingSurfaceForBackground(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT(ScriptDrawingSurface, Room_GetDrawingSurfaceForBackground); +} + +// int (const char *property) +RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(Room_GetProperty, const char); +} + +// const char* (const char *property) +RuntimeScriptValue Sc_Room_GetTextProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Room_GetTextProperty, const char); +} + +RuntimeScriptValue Sc_Room_SetProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_BOOL_POBJ_PINT(Room_SetProperty, const char); +} + +// const char* (const char *property) +RuntimeScriptValue Sc_Room_SetTextProperty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_BOOL_POBJ2(Room_SetTextProperty, const char, const char); +} + +// int () +RuntimeScriptValue Sc_Room_GetBottomEdge(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetBottomEdge); +} + +// int () +RuntimeScriptValue Sc_Room_GetColorDepth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetColorDepth); +} + +// int () +RuntimeScriptValue Sc_Room_GetHeight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetHeight); +} + +// int () +RuntimeScriptValue Sc_Room_GetLeftEdge(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetLeftEdge); +} + +// const char* (int index) +RuntimeScriptValue Sc_Room_GetMessages(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Room_GetMessages); +} + +// int () +RuntimeScriptValue Sc_Room_GetMusicOnLoad(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetMusicOnLoad); +} + +// int () +RuntimeScriptValue Sc_Room_GetObjectCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetObjectCount); +} + +// int () +RuntimeScriptValue Sc_Room_GetRightEdge(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetRightEdge); +} + +// int () +RuntimeScriptValue Sc_Room_GetTopEdge(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetTopEdge); +} + +// int () +RuntimeScriptValue Sc_Room_GetWidth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Room_GetWidth); +} + +// void (int xx,int yy,int mood) +RuntimeScriptValue Sc_RoomProcessClick(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT3(RoomProcessClick); +} + + +void RegisterRoomAPI() +{ + ccAddExternalStaticFunction("Room::GetDrawingSurfaceForBackground^1", Sc_Room_GetDrawingSurfaceForBackground); + ccAddExternalStaticFunction("Room::GetProperty^1", Sc_Room_GetProperty); + ccAddExternalStaticFunction("Room::GetTextProperty^1", Sc_Room_GetTextProperty); + ccAddExternalStaticFunction("Room::SetProperty^2", Sc_Room_SetProperty); + ccAddExternalStaticFunction("Room::SetTextProperty^2", Sc_Room_SetTextProperty); + ccAddExternalStaticFunction("Room::ProcessClick^3", Sc_RoomProcessClick); + ccAddExternalStaticFunction("ProcessClick", Sc_RoomProcessClick); + ccAddExternalStaticFunction("Room::get_BottomEdge", Sc_Room_GetBottomEdge); + ccAddExternalStaticFunction("Room::get_ColorDepth", Sc_Room_GetColorDepth); + ccAddExternalStaticFunction("Room::get_Height", Sc_Room_GetHeight); + ccAddExternalStaticFunction("Room::get_LeftEdge", Sc_Room_GetLeftEdge); + ccAddExternalStaticFunction("Room::geti_Messages", Sc_Room_GetMessages); + ccAddExternalStaticFunction("Room::get_MusicOnLoad", Sc_Room_GetMusicOnLoad); + ccAddExternalStaticFunction("Room::get_ObjectCount", Sc_Room_GetObjectCount); + ccAddExternalStaticFunction("Room::get_RightEdge", Sc_Room_GetRightEdge); + ccAddExternalStaticFunction("Room::get_TopEdge", Sc_Room_GetTopEdge); + ccAddExternalStaticFunction("Room::get_Width", Sc_Room_GetWidth); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Room::GetDrawingSurfaceForBackground^1", (void*)Room_GetDrawingSurfaceForBackground); + ccAddExternalFunctionForPlugin("Room::GetProperty^1", (void*)Room_GetProperty); + ccAddExternalFunctionForPlugin("Room::GetTextProperty^1", (void*)Room_GetTextProperty); + ccAddExternalFunctionForPlugin("Room::get_BottomEdge", (void*)Room_GetBottomEdge); + ccAddExternalFunctionForPlugin("Room::get_ColorDepth", (void*)Room_GetColorDepth); + ccAddExternalFunctionForPlugin("Room::get_Height", (void*)Room_GetHeight); + ccAddExternalFunctionForPlugin("Room::get_LeftEdge", (void*)Room_GetLeftEdge); + ccAddExternalFunctionForPlugin("Room::geti_Messages", (void*)Room_GetMessages); + ccAddExternalFunctionForPlugin("Room::get_MusicOnLoad", (void*)Room_GetMusicOnLoad); + ccAddExternalFunctionForPlugin("Room::get_ObjectCount", (void*)Room_GetObjectCount); + ccAddExternalFunctionForPlugin("Room::get_RightEdge", (void*)Room_GetRightEdge); + ccAddExternalFunctionForPlugin("Room::get_TopEdge", (void*)Room_GetTopEdge); + ccAddExternalFunctionForPlugin("Room::get_Width", (void*)Room_GetWidth); +} diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h new file mode 100644 index 000000000000..c915f8f2cbdb --- /dev/null +++ b/engines/ags/engine/ac/room.h @@ -0,0 +1,74 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__ROOM_H +#define __AGS_EE_AC__ROOM_H + +#include "ac/dynobj/scriptdrawingsurface.h" +#include "ac/characterinfo.h" +#include "script/runtimescriptvalue.h" +#include "game/roomstruct.h" + +ScriptDrawingSurface* Room_GetDrawingSurfaceForBackground(int backgroundNumber); +ScriptDrawingSurface* Room_GetDrawingSurfaceForMask(RoomAreaMask mask); +int Room_GetObjectCount(); +int Room_GetWidth(); +int Room_GetHeight(); +int Room_GetColorDepth(); +int Room_GetLeftEdge(); +int Room_GetRightEdge(); +int Room_GetTopEdge(); +int Room_GetBottomEdge(); +int Room_GetMusicOnLoad(); +const char* Room_GetTextProperty(const char *property); +int Room_GetProperty(const char *property); +const char* Room_GetMessages(int index); +RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t param_count); + +//============================================================================= + +void save_room_data_segment (); +void unload_old_room(); +void load_new_room(int newnum,CharacterInfo*forchar); +void new_room(int newnum,CharacterInfo*forchar); +int find_highest_room_entered(); +void first_room_initialization(); +void check_new_room(); +void compile_room_script(); +void on_background_frame_change (); +// Clear the current room pointer if room status is no longer valid +void croom_ptr_clear(); + +// These functions convert coordinates between data resolution and region mask. +// In hi-res games region masks are 1:2 (or smaller) of the room size. +// In legacy games with low-res data resolution there's additional conversion +// between data and room coordinates. +// +// gets multiplier for converting from room mask to data coordinate +extern AGS_INLINE int get_roommask_to_data_mul(); +// coordinate conversion data ---> room ---> mask +extern AGS_INLINE int room_to_mask_coord(int coord); +// coordinate conversion mask ---> room ---> data +extern AGS_INLINE int mask_to_room_coord(int coord); + +struct MoveList; +// Convert move path from room's mask resolution to room resolution +void convert_move_path_to_room_resolution(MoveList *ml); + +extern AGS::Common::RoomStruct thisroom; + +#endif // __AGS_EE_AC__ROOM_H diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp new file mode 100644 index 000000000000..ccddc1032c74 --- /dev/null +++ b/engines/ags/engine/ac/roomobject.cpp @@ -0,0 +1,166 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/roomobject.h" +#include "ac/common.h" +#include "ac/common_defines.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/runtime_defines.h" +#include "ac/viewframe.h" +#include "main/update.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +extern ViewStruct*views; +extern GameState play; +extern GameSetupStruct game; + +RoomObject::RoomObject() +{ + x = y = 0; + transparent = 0; + tint_r = tint_g = 0; + tint_b = tint_level = 0; + tint_light = 0; + zoom = 0; + last_width = last_height = 0; + num = 0; + baseline = 0; + view = loop = frame = 0; + wait = moving = 0; + cycling = 0; + overall_speed = 0; + on = 0; + flags = 0; + blocking_width = blocking_height = 0; +} + +int RoomObject::get_width() { + if (last_width == 0) + return game.SpriteInfos[num].Width; + return last_width; +} +int RoomObject::get_height() { + if (last_height == 0) + return game.SpriteInfos[num].Height; + return last_height; +} +int RoomObject::get_baseline() { + if (baseline < 1) + return y; + return baseline; +} + +void RoomObject::UpdateCyclingView() +{ + if (on != 1) return; + if (moving>0) { + do_movelist_move(&moving,&x,&y); + } + if (cycling==0) return; + if (view<0) return; + if (wait>0) { wait--; return; } + + if (cycling >= ANIM_BACKWARDS) { + + update_cycle_view_backwards(); + + } + else { // Animate forwards + + update_cycle_view_forwards(); + + } // end if forwards + + ViewFrame*vfptr=&views[view].loops[loop].frames[frame]; + num = vfptr->pic; + + if (cycling == 0) + return; + + wait=vfptr->speed+overall_speed; + CheckViewFrame (view, loop, frame); +} + + +void RoomObject::update_cycle_view_forwards() +{ + frame++; + if (frame >= views[view].loops[loop].numFrames) { + // go to next loop thing + if (views[view].loops[loop].RunNextLoop()) { + if (loop+1 >= views[view].numLoops) + quit("!Last loop in a view requested to move to next loop"); + loop++; + frame=0; + } + else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) { + // leave it on the last frame + cycling=0; + frame--; + } + else { + if (play.no_multiloop_repeat == 0) { + // multi-loop anims, go back to start of it + while ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) + loop --; + } + if (cycling % ANIM_BACKWARDS == ANIM_ONCERESET) + cycling=0; + frame=0; + } + } +} + +void RoomObject::update_cycle_view_backwards() +{ + // animate backwards + frame--; + if (frame < 0) { + if ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) + { + // If it's a Go-to-next-loop on the previous one, then go back + loop --; + frame = views[view].loops[loop].numFrames - 1; + } + else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) { + // leave it on the first frame + cycling = 0; + frame = 0; + } + else { // repeating animation + frame = views[view].loops[loop].numFrames - 1; + } + } +} + +void RoomObject::ReadFromFile(Stream *in) +{ + in->ReadArrayOfInt32(&x, 3); + in->ReadArrayOfInt16(&tint_r, 15); + in->ReadArrayOfInt8((int8_t*)&cycling, 4); + in->ReadArrayOfInt16(&blocking_width, 2); +} + +void RoomObject::WriteToFile(Stream *out) const +{ + out->WriteArrayOfInt32(&x, 3); + out->WriteArrayOfInt16(&tint_r, 15); + out->WriteArrayOfInt8((int8_t*)&cycling, 4); + out->WriteArrayOfInt16(&blocking_width, 2); +} diff --git a/engines/ags/engine/ac/roomobject.h b/engines/ags/engine/ac/roomobject.h new file mode 100644 index 000000000000..ce5dd95134cc --- /dev/null +++ b/engines/ags/engine/ac/roomobject.h @@ -0,0 +1,62 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__ROOMOBJECT_H +#define __AGS_EE_AC__ROOMOBJECT_H + +#include "ac/common_defines.h" + +namespace AGS { namespace Common { class Stream; }} +using namespace AGS; // FIXME later + +// IMPORTANT: this struct is restricted by plugin API! +struct RoomObject { + int x,y; + int transparent; // current transparency setting + short tint_r, tint_g; // specific object tint + short tint_b, tint_level; + short tint_light; + short zoom; // zoom level, either manual or from the current area + short last_width, last_height; // width/height last time drawn + short num; // sprite slot number + short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline + short view,loop,frame; // only used to track animation - 'num' holds the current sprite + short wait,moving; + char cycling; // is it currently animating? + char overall_speed; + char on; + char flags; + short blocking_width, blocking_height; + + RoomObject(); + + int get_width(); + int get_height(); + int get_baseline(); + + inline bool has_explicit_light() const { return (flags & OBJF_HASLIGHT) != 0; } + inline bool has_explicit_tint() const { return (flags & OBJF_HASTINT) != 0; } + + void UpdateCyclingView(); + void update_cycle_view_forwards(); + void update_cycle_view_backwards(); + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out) const; +}; + +#endif // __AGS_EE_AC__ROOMOBJECT_H diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp new file mode 100644 index 000000000000..baabe5644f0c --- /dev/null +++ b/engines/ags/engine/ac/roomstatus.cpp @@ -0,0 +1,240 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include // memset +#include // free +#include "ac/common.h" +#include "ac/game_version.h" +#include "ac/roomstatus.h" +#include "game/customproperties.h" +#include "game/savegame_components.h" +#include "util/alignedstream.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +RoomStatus::RoomStatus() +{ + beenhere = 0; + numobj = 0; + memset(&flagstates, 0, sizeof(flagstates)); + tsdatasize = 0; + tsdata = nullptr; + + memset(&hotspot_enabled, 0, sizeof(hotspot_enabled)); + memset(®ion_enabled, 0, sizeof(region_enabled)); + memset(&walkbehind_base, 0, sizeof(walkbehind_base)); + memset(&interactionVariableValues, 0, sizeof(interactionVariableValues)); +} + +RoomStatus::~RoomStatus() +{ + if (tsdata) + delete [] tsdata; +} + +void RoomStatus::FreeScriptData() +{ + if (tsdata) + delete [] tsdata; + tsdata = nullptr; + tsdatasize = 0; +} + +void RoomStatus::FreeProperties() +{ + roomProps.clear(); + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) + { + hsProps[i].clear(); + } + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) + { + objProps[i].clear(); + } +} + +void RoomStatus::ReadFromFile_v321(Stream *in) +{ + beenhere = in->ReadInt32(); + numobj = in->ReadInt32(); + ReadRoomObjects_Aligned(in); + in->ReadArrayOfInt16(flagstates, MAX_FLAGS); + tsdatasize = in->ReadInt32(); + in->ReadInt32(); // tsdata + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) + { + intrHotspot[i].ReadFromSavedgame_v321(in); + } + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) + { + intrObject[i].ReadFromSavedgame_v321(in); + } + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) + { + intrRegion[i].ReadFromSavedgame_v321(in); + } + intrRoom.ReadFromSavedgame_v321(in); + in->ReadArrayOfInt8((int8_t*)hotspot_enabled, MAX_ROOM_HOTSPOTS); + in->ReadArrayOfInt8((int8_t*)region_enabled, MAX_ROOM_REGIONS); + in->ReadArrayOfInt16(walkbehind_base, MAX_WALK_BEHINDS); + in->ReadArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); + + if (loaded_game_file_version >= kGameVersion_340_4) + { + Properties::ReadValues(roomProps, in); + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) + { + Properties::ReadValues(hsProps[i], in); + } + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) + { + Properties::ReadValues(objProps[i], in); + } + } +} + +void RoomStatus::ReadRoomObjects_Aligned(Common::Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) + { + obj[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void RoomStatus::ReadFromSavegame(Stream *in) +{ + FreeScriptData(); + FreeProperties(); + + beenhere = in->ReadInt8(); + numobj = in->ReadInt32(); + for (int i = 0; i < numobj; ++i) + { + obj[i].ReadFromFile(in); + Properties::ReadValues(objProps[i], in); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::ReadInteraction272(intrObject[i], in); + } + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) + { + hotspot_enabled[i] = in->ReadInt8(); + Properties::ReadValues(hsProps[i], in); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::ReadInteraction272(intrHotspot[i], in); + } + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) + { + region_enabled[i] = in->ReadInt8(); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::ReadInteraction272(intrRegion[i], in); + } + for (int i = 0; i < MAX_WALK_BEHINDS; ++i) + { + walkbehind_base[i] = in->ReadInt32(); + } + + Properties::ReadValues(roomProps, in); + if (loaded_game_file_version <= kGameVersion_272) + { + SavegameComponents::ReadInteraction272(intrRoom, in); + in->ReadArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); + } + + tsdatasize = in->ReadInt32(); + if (tsdatasize) + { + tsdata = new char[tsdatasize]; + in->Read(tsdata, tsdatasize); + } +} + +void RoomStatus::WriteToSavegame(Stream *out) const +{ + out->WriteInt8(beenhere); + out->WriteInt32(numobj); + for (int i = 0; i < numobj; ++i) + { + obj[i].WriteToFile(out); + Properties::WriteValues(objProps[i], out); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::WriteInteraction272(intrObject[i], out); + } + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) + { + out->WriteInt8(hotspot_enabled[i]); + Properties::WriteValues(hsProps[i], out); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::WriteInteraction272(intrHotspot[i], out); + } + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) + { + out->WriteInt8(region_enabled[i]); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::WriteInteraction272(intrRegion[i], out); + } + for (int i = 0; i < MAX_WALK_BEHINDS; ++i) + { + out->WriteInt32(walkbehind_base[i]); + } + + Properties::WriteValues(roomProps, out); + if (loaded_game_file_version <= kGameVersion_272) + { + SavegameComponents::WriteInteraction272(intrRoom, out); + out->WriteArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); + } + + out->WriteInt32(tsdatasize); + if (tsdatasize) + out->Write(tsdata, tsdatasize); +} + +// JJS: Replacement for the global roomstats array in the original engine. + +RoomStatus* room_statuses[MAX_ROOMS]; + +// Replaces all accesses to the roomstats array +RoomStatus* getRoomStatus(int room) +{ + if (room_statuses[room] == nullptr) + { + // First access, allocate and initialise the status + room_statuses[room] = new RoomStatus(); + } + return room_statuses[room]; +} + +// Used in places where it is only important to know whether the player +// had previously entered the room. In this case it is not necessary +// to initialise the status because a player can only have been in +// a room if the status is already initialised. +bool isRoomStatusValid(int room) +{ + return (room_statuses[room] != nullptr); +} + +void resetRoomStatuses() +{ + for (int i = 0; i < MAX_ROOMS; i++) + { + if (room_statuses[i] != nullptr) + { + delete room_statuses[i]; + room_statuses[i] = nullptr; + } + } +} diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h new file mode 100644 index 000000000000..9e6eb2dde938 --- /dev/null +++ b/engines/ags/engine/ac/roomstatus.h @@ -0,0 +1,80 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__ROOMSTATUS_H +#define __AGS_EE_AC__ROOMSTATUS_H + +#include "ac/roomobject.h" +#include "game/roomstruct.h" +#include "game/interactions.h" +#include "util/string_types.h" + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using AGS::Common::Stream; +using AGS::Common::Interaction; + +// This struct is saved in the save games - it contains everything about +// a room that could change +struct RoomStatus { + int beenhere; + int numobj; + RoomObject obj[MAX_ROOM_OBJECTS]; + short flagstates[MAX_FLAGS]; + int tsdatasize; + char* tsdata; + Interaction intrHotspot[MAX_ROOM_HOTSPOTS]; + Interaction intrObject [MAX_ROOM_OBJECTS]; + Interaction intrRegion [MAX_ROOM_REGIONS]; + Interaction intrRoom; + + Common::StringIMap roomProps; + Common::StringIMap hsProps[MAX_ROOM_HOTSPOTS]; + Common::StringIMap objProps[MAX_ROOM_OBJECTS]; + // [IKM] 2012-06-22: not used anywhere +#ifdef UNUSED_CODE + EventBlock hscond[MAX_ROOM_HOTSPOTS]; + EventBlock objcond[MAX_ROOM_OBJECTS]; + EventBlock misccond; +#endif + char hotspot_enabled[MAX_ROOM_HOTSPOTS]; + char region_enabled[MAX_ROOM_REGIONS]; + short walkbehind_base[MAX_WALK_BEHINDS]; + int interactionVariableValues[MAX_GLOBAL_VARIABLES]; + + RoomStatus(); + ~RoomStatus(); + + void FreeScriptData(); + void FreeProperties(); + + void ReadFromFile_v321(Common::Stream *in); + void ReadRoomObjects_Aligned(Common::Stream *in); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; +}; + +// Replaces all accesses to the roomstats array +RoomStatus* getRoomStatus(int room); +// Used in places where it is only important to know whether the player +// had previously entered the room. In this case it is not necessary +// to initialise the status because a player can only have been in +// a room if the status is already initialised. +bool isRoomStatusValid(int room); +void resetRoomStatuses(); + +#endif // __AGS_EE_AC__ROOMSTATUS_H diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp new file mode 100644 index 000000000000..24663a94e474 --- /dev/null +++ b/engines/ags/engine/ac/route_finder.cpp @@ -0,0 +1,162 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/route_finder.h" + +#include "ac/route_finder_impl.h" +#include "ac/route_finder_impl_legacy.h" + +#include "debug/out.h" + +using AGS::Common::Bitmap; + +class IRouteFinder +{ + public: + virtual void init_pathfinder() = 0; + virtual void shutdown_pathfinder() = 0; + virtual void set_wallscreen(Bitmap *wallscreen) = 0; + virtual int can_see_from(int x1, int y1, int x2, int y2) = 0; + virtual void get_lastcpos(int &lastcx, int &lastcy) = 0; + virtual void set_route_move_speed(int speed_x, int speed_y) = 0; + virtual int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) = 0; + virtual void calculate_move_stage(MoveList * mlsp, int aaa) = 0; +}; + +class AGSRouteFinder : public IRouteFinder +{ + public: + void init_pathfinder() override + { + AGS::Engine::RouteFinder::init_pathfinder(); + } + void shutdown_pathfinder() override + { + AGS::Engine::RouteFinder::shutdown_pathfinder(); + } + void set_wallscreen(Bitmap *wallscreen) override + { + AGS::Engine::RouteFinder::set_wallscreen(wallscreen); + } + int can_see_from(int x1, int y1, int x2, int y2) override + { + return AGS::Engine::RouteFinder::can_see_from(x1, y1, x2, y2); + } + void get_lastcpos(int &lastcx, int &lastcy) override + { + AGS::Engine::RouteFinder::get_lastcpos(lastcx, lastcy); + } + void set_route_move_speed(int speed_x, int speed_y) override + { + AGS::Engine::RouteFinder::set_route_move_speed(speed_x, speed_y); + } + int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override + { + return AGS::Engine::RouteFinder::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); + } + void calculate_move_stage(MoveList * mlsp, int aaa) override + { + AGS::Engine::RouteFinder::calculate_move_stage(mlsp, aaa); + } +}; + +class AGSLegacyRouteFinder : public IRouteFinder +{ + public: + void init_pathfinder() override + { + AGS::Engine::RouteFinderLegacy::init_pathfinder(); + } + void shutdown_pathfinder() override + { + AGS::Engine::RouteFinderLegacy::shutdown_pathfinder(); + } + void set_wallscreen(Bitmap *wallscreen) override + { + AGS::Engine::RouteFinderLegacy::set_wallscreen(wallscreen); + } + int can_see_from(int x1, int y1, int x2, int y2) override + { + return AGS::Engine::RouteFinderLegacy::can_see_from(x1, y1, x2, y2); + } + void get_lastcpos(int &lastcx, int &lastcy) override + { + AGS::Engine::RouteFinderLegacy::get_lastcpos(lastcx, lastcy); + } + void set_route_move_speed(int speed_x, int speed_y) override + { + AGS::Engine::RouteFinderLegacy::set_route_move_speed(speed_x, speed_y); + } + int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override + { + return AGS::Engine::RouteFinderLegacy::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); + } + void calculate_move_stage(MoveList * mlsp, int aaa) override + { + AGS::Engine::RouteFinderLegacy::calculate_move_stage(mlsp, aaa); + } +}; + +static IRouteFinder *route_finder_impl = nullptr; + +void init_pathfinder(GameDataVersion game_file_version) +{ + if (game_file_version >= kGameVersion_350) + { + AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize path finder library"); + route_finder_impl = new AGSRouteFinder(); + } + else + { + AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize legacy path finder library"); + route_finder_impl = new AGSLegacyRouteFinder(); + } + + route_finder_impl->init_pathfinder(); +} + +void shutdown_pathfinder() +{ + route_finder_impl->shutdown_pathfinder(); +} + +void set_wallscreen(Bitmap *wallscreen) +{ + route_finder_impl->set_wallscreen(wallscreen); +} + +int can_see_from(int x1, int y1, int x2, int y2) +{ + return route_finder_impl->can_see_from(x1, y1, x2, y2); +} + +void get_lastcpos(int &lastcx, int &lastcy) +{ + route_finder_impl->get_lastcpos(lastcx, lastcy); +} + +void set_route_move_speed(int speed_x, int speed_y) +{ + route_finder_impl->set_route_move_speed(speed_x, speed_y); +} + +int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) +{ + return route_finder_impl->find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); +} + +void calculate_move_stage(MoveList * mlsp, int aaa) +{ + route_finder_impl->calculate_move_stage(mlsp, aaa); +} diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h new file mode 100644 index 000000000000..fafdd43530cd --- /dev/null +++ b/engines/ags/engine/ac/route_finder.h @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_ROUTEFND_H +#define __AC_ROUTEFND_H + +#include "ac/game_version.h" + +// Forward declaration +namespace AGS { namespace Common { class Bitmap; }} +struct MoveList; + +void init_pathfinder(GameDataVersion game_file_version); +void shutdown_pathfinder(); + +void set_wallscreen(AGS::Common::Bitmap *wallscreen); + +int can_see_from(int x1, int y1, int x2, int y2); +void get_lastcpos(int &lastcx, int &lastcy); +// NOTE: pathfinder implementation mostly needs to know proportion between x and y speed +void set_route_move_speed(int speed_x, int speed_y); + +int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); +void calculate_move_stage(MoveList * mlsp, int aaa); + +#endif // __AC_ROUTEFND_H \ No newline at end of file diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp new file mode 100644 index 000000000000..2e3d71bbee5b --- /dev/null +++ b/engines/ags/engine/ac/route_finder_impl.cpp @@ -0,0 +1,273 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// New jump point search (JPS) A* pathfinder by Martin Sedlak. +// +//============================================================================= + +#include "ac/route_finder_impl.h" + +#include +#include + +#include "ac/common.h" // quit() +#include "ac/movelist.h" // MoveList +#include "ac/common_defines.h" +#include "gfx/bitmap.h" +#include "debug/out.h" + +#include "route_finder_jps.inl" + +extern MoveList *mls; + +using AGS::Common::Bitmap; + +// #define DEBUG_PATHFINDER + +namespace AGS { +namespace Engine { +namespace RouteFinder { + +#define MAKE_INTCOORD(x,y) (((unsigned short)x << 16) | ((unsigned short)y)) + +static const int MAXNAVPOINTS = MAXNEEDSTAGES; +static int navpoints[MAXNAVPOINTS]; +static int num_navpoints; +static fixed move_speed_x, move_speed_y; +static Navigation nav; +static Bitmap *wallscreen; +static int lastcx, lastcy; + +void init_pathfinder() +{ +} + +void shutdown_pathfinder() +{ +} + +void set_wallscreen(Bitmap *wallscreen_) +{ + wallscreen = wallscreen_; +} + +static void sync_nav_wallscreen() +{ + // FIXME: this is dumb, but... + nav.Resize(wallscreen->GetWidth(), wallscreen->GetHeight()); + + for (int y=0; yGetHeight(); y++) + nav.SetMapRow(y, wallscreen->GetScanLine(y)); +} + +int can_see_from(int x1, int y1, int x2, int y2) +{ + lastcx = x1; + lastcy = y1; + + if ((x1 == x2) && (y1 == y2)) + return 1; + + sync_nav_wallscreen(); + + return !nav.TraceLine(x1, y1, x2, y2, lastcx, lastcy); +} + +void get_lastcpos(int &lastcx_, int &lastcy_) +{ + lastcx_ = lastcx; + lastcy_ = lastcy; +} + +// new routing using JPS +static int find_route_jps(int fromx, int fromy, int destx, int desty) +{ + sync_nav_wallscreen(); + + static std::vector path, cpath; + path.clear(); + cpath.clear(); + + if (nav.NavigateRefined(fromx, fromy, destx, desty, path, cpath) == Navigation::NAV_UNREACHABLE) + return 0; + + num_navpoints = 0; + + // new behavior: cut path if too complex rather than abort with error message + int count = std::min((int)cpath.size(), MAXNAVPOINTS); + + for (int i = 0; ipos[aaa] == mlsp->pos[aaa + 1]) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = 0; + return; + } + + short ourx = (mlsp->pos[aaa] >> 16) & 0x000ffff; + short oury = (mlsp->pos[aaa] & 0x000ffff); + short destx = ((mlsp->pos[aaa + 1] >> 16) & 0x000ffff); + short desty = (mlsp->pos[aaa + 1] & 0x000ffff); + + // Special case for vertical and horizontal movements + if (ourx == destx) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = move_speed_y; + if (desty < oury) + mlsp->ypermove[aaa] = -mlsp->ypermove[aaa]; + + return; + } + + if (oury == desty) { + mlsp->xpermove[aaa] = move_speed_x; + mlsp->ypermove[aaa] = 0; + if (destx < ourx) + mlsp->xpermove[aaa] = -mlsp->xpermove[aaa]; + + return; + } + + fixed xdist = itofix(abs(ourx - destx)); + fixed ydist = itofix(abs(oury - desty)); + + fixed useMoveSpeed; + + if (move_speed_x == move_speed_y) { + useMoveSpeed = move_speed_x; + } + else { + // different X and Y move speeds + // the X proportion of the movement is (x / (x + y)) + fixed xproportion = fixdiv(xdist, (xdist + ydist)); + + if (move_speed_x > move_speed_y) { + // speed = y + ((1 - xproportion) * (x - y)) + useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y); + } + else { + // speed = x + (xproportion * (y - x)) + useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x); + } + } + + fixed angl = fixatan(fixdiv(ydist, xdist)); + + // now, since new opp=hyp*sin, work out the Y step size + //fixed newymove = useMoveSpeed * fsin(angl); + fixed newymove = fixmul(useMoveSpeed, fixsin(angl)); + + // since adj=hyp*cos, work out X step size + //fixed newxmove = useMoveSpeed * fcos(angl); + fixed newxmove = fixmul(useMoveSpeed, fixcos(angl)); + + if (destx < ourx) + newxmove = -newxmove; + if (desty < oury) + newymove = -newymove; + + mlsp->xpermove[aaa] = newxmove; + mlsp->ypermove[aaa] = newymove; +} + + +int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) +{ + int i; + + wallscreen = onscreen; + + num_navpoints = 0; + + if (ignore_walls || can_see_from(srcx, srcy, xx, yy)) + { + num_navpoints = 2; + navpoints[0] = MAKE_INTCOORD(srcx, srcy); + navpoints[1] = MAKE_INTCOORD(xx, yy); + } else { + if ((nocross == 0) && (wallscreen->GetPixel(xx, yy) == 0)) + return 0; // clicked on a wall + + find_route_jps(srcx, srcy, xx, yy); + } + + if (!num_navpoints) + return 0; + + // FIXME: really necessary? + if (num_navpoints == 1) + navpoints[num_navpoints++] = navpoints[0]; + + assert(num_navpoints <= MAXNAVPOINTS); + +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stages", srcx,srcy,xx,yy,num_navpoints); +#endif + + int mlist = movlst; + mls[mlist].numstage = num_navpoints; + memcpy(&mls[mlist].pos[0], &navpoints[0], sizeof(int) * num_navpoints); +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("stages: %d\n",num_navpoints); +#endif + + for (i=0; i +#include + +#include "ac/common.h" // quit() +#include "ac/common_defines.h" +#include "game/roomstruct.h" +#include "ac/movelist.h" // MoveList +#include "gfx/bitmap.h" +#include "debug/out.h" + +extern void update_polled_stuff_if_runtime(); + +extern MoveList *mls; + +using AGS::Common::Bitmap; +namespace BitmapHelper = AGS::Common::BitmapHelper; + +// #define DEBUG_PATHFINDER + +#ifdef DEBUG_PATHFINDER +// extern Bitmap *mousecurs[10]; +#endif + +namespace AGS { +namespace Engine { +namespace RouteFinderLegacy { + +#define MANOBJNUM 99 + +#define MAXPATHBACK 1000 +static int *pathbackx = nullptr; +static int *pathbacky = nullptr; +static int waspossible = 1; +static int suggestx; +static int suggesty; +static fixed move_speed_x; +static fixed move_speed_y; + +void init_pathfinder() +{ + pathbackx = (int *)malloc(sizeof(int) * MAXPATHBACK); + pathbacky = (int *)malloc(sizeof(int) * MAXPATHBACK); +} + +static Bitmap *wallscreen; + +void set_wallscreen(Bitmap *wallscreen_) +{ + wallscreen = wallscreen_; +} + +static int line_failed = 0; +static int lastcx, lastcy; + +// TODO: find a way to reimpl this with Bitmap +static void line_callback(BITMAP *bmpp, int x, int y, int d) +{ +/* if ((x>=320) | (y>=200) | (x<0) | (y<0)) line_failed=1; + else */ if (getpixel(bmpp, x, y) < 1) + line_failed = 1; + else if (line_failed == 0) { + lastcx = x; + lastcy = y; + } +} + + + +int can_see_from(int x1, int y1, int x2, int y2) +{ + assert(wallscreen != nullptr); + + line_failed = 0; + lastcx = x1; + lastcy = y1; + + if ((x1 == x2) && (y1 == y2)) + return 1; + + // TODO: need some way to use Bitmap with callback + do_line((BITMAP*)wallscreen->GetAllegroBitmap(), x1, y1, x2, y2, 0, line_callback); + if (line_failed == 0) + return 1; + + return 0; +} + +void get_lastcpos(int &lastcx_, int &lastcy_) { + lastcx_ = lastcx; + lastcy_ = lastcy; +} + + +int find_nearest_walkable_area(Bitmap *tempw, int fromX, int fromY, int toX, int toY, int destX, int destY, int granularity) +{ + assert(tempw != nullptr); + + int ex, ey, nearest = 99999, thisis, nearx, neary; + if (fromX < 0) fromX = 0; + if (fromY < 0) fromY = 0; + if (toX >= tempw->GetWidth()) toX = tempw->GetWidth() - 1; + if (toY >= tempw->GetHeight()) toY = tempw->GetHeight() - 1; + + for (ex = fromX; ex < toX; ex += granularity) + { + for (ey = fromY; ey < toY; ey += granularity) + { + if (tempw->GetScanLine(ey)[ex] != 232) + continue; + + thisis = (int)::sqrt((double)((ex - destX) * (ex - destX) + (ey - destY) * (ey - destY))); + if (thisis < nearest) + { + nearest = thisis; + nearx = ex; + neary = ey; + } + } + } + + if (nearest < 90000) { + suggestx = nearx; + suggesty = neary; + return 1; + } + + return 0; +} + +#define MAX_GRANULARITY 3 +static int walk_area_granularity[MAX_WALK_AREAS + 1]; +static int is_route_possible(int fromx, int fromy, int tox, int toy, Bitmap *wss) +{ + wallscreen = wss; + suggestx = -1; + + // ensure it's a memory bitmap, so we can use direct access to line[] array + if ((wss == nullptr) || (!wss->IsMemoryBitmap()) || (wss->GetColorDepth() != 8)) + quit("is_route_possible: invalid walkable areas bitmap supplied"); + + if (wallscreen->GetPixel(fromx, fromy) < 1) + return 0; + + Bitmap *tempw = BitmapHelper::CreateBitmapCopy(wallscreen, 8); + + if (tempw == nullptr) + quit("no memory for route calculation"); + if (!tempw->IsMemoryBitmap()) + quit("tempw is not memory bitmap"); + + int dd, ff; + // initialize array for finding widths of walkable areas + int thisar, inarow = 0, lastarea = 0; + int walk_area_times[MAX_WALK_AREAS + 1]; + for (dd = 0; dd <= MAX_WALK_AREAS; dd++) { + walk_area_times[dd] = 0; + walk_area_granularity[dd] = 0; + } + + for (ff = 0; ff < tempw->GetHeight(); ff++) { + const uint8_t *tempw_scanline = tempw->GetScanLine(ff); + for (dd = 0; dd < tempw->GetWidth(); dd++) { + thisar = tempw_scanline[dd]; + // count how high the area is at this point + if ((thisar == lastarea) && (thisar > 0)) + inarow++; + else if (lastarea > MAX_WALK_AREAS) + quit("!Calculate_Route: invalid colours in walkable area mask"); + else if (lastarea != 0) { + walk_area_granularity[lastarea] += inarow; + walk_area_times[lastarea]++; + inarow = 0; + } + lastarea = thisar; + } + } + + for (dd = 0; dd < tempw->GetWidth(); dd++) { + for (ff = 0; ff < tempw->GetHeight(); ff++) { + uint8_t *tempw_scanline = tempw->GetScanLineForWriting(ff); + thisar = tempw_scanline[dd]; + if (thisar > 0) + tempw_scanline[dd] = 1; + // count how high the area is at this point + if ((thisar == lastarea) && (thisar > 0)) + inarow++; + else if (lastarea != 0) { + walk_area_granularity[lastarea] += inarow; + walk_area_times[lastarea]++; + inarow = 0; + } + lastarea = thisar; + } + } + + // find the average "width" of a path in this walkable area + for (dd = 1; dd <= MAX_WALK_AREAS; dd++) { + if (walk_area_times[dd] == 0) { + walk_area_granularity[dd] = MAX_GRANULARITY; + continue; + } + + walk_area_granularity[dd] /= walk_area_times[dd]; + if (walk_area_granularity[dd] <= 4) + walk_area_granularity[dd] = 2; + else if (walk_area_granularity[dd] <= 15) + walk_area_granularity[dd] = 3; + else + walk_area_granularity[dd] = MAX_GRANULARITY; + +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("area %d: Gran %d", dd, walk_area_granularity[dd]); +#endif + } + walk_area_granularity[0] = MAX_GRANULARITY; + + tempw->FloodFill(fromx, fromy, 232); + if (tempw->GetPixel(tox, toy) != 232) + { + // Destination pixel is not walkable + // Try the 100x100 square around the target first at 3-pixel granularity + int tryFirstX = tox - 50, tryToX = tox + 50; + int tryFirstY = toy - 50, tryToY = toy + 50; + + if (!find_nearest_walkable_area(tempw, tryFirstX, tryFirstY, tryToX, tryToY, tox, toy, 3)) + { + // Nothing found, sweep the whole room at 5 pixel granularity + find_nearest_walkable_area(tempw, 0, 0, tempw->GetWidth(), tempw->GetHeight(), tox, toy, 5); + } + + delete tempw; + return 0; + } + delete tempw; + + return 1; +} + +static int leftorright = 0; +static int nesting = 0; +static int pathbackstage = 0; +static int finalpartx = 0; +static int finalparty = 0; +static short **beenhere = nullptr; //[200][320]; +static int beenhere_array_size = 0; +static const int BEENHERE_SIZE = 2; + +#define DIR_LEFT 0 +#define DIR_RIGHT 2 +#define DIR_UP 1 +#define DIR_DOWN 3 + +static int try_this_square(int srcx, int srcy, int tox, int toy) +{ + assert(pathbackx != nullptr); + assert(pathbacky != nullptr); + assert(beenhere != nullptr); + + if (beenhere[srcy][srcx] & 0x80) + return 0; + + // nesting of 8040 leads to stack overflow + if (nesting > 7000) + return 0; + + nesting++; + if (can_see_from(srcx, srcy, tox, toy)) { + finalpartx = srcx; + finalparty = srcy; + nesting--; + pathbackstage = 0; + return 2; + } + +#ifdef DEBUG_PATHFINDER + // wputblock(lastcx, lastcy, mousecurs[C_CROSS], 1); +#endif + + int trydir = DIR_UP; + int xdiff = abs(srcx - tox), ydiff = abs(srcy - toy); + if (ydiff > xdiff) { + if (srcy > toy) + trydir = DIR_UP; + else + trydir = DIR_DOWN; + } else if (srcx > tox) + trydir = DIR_LEFT; + else if (srcx < tox) + trydir = DIR_RIGHT; + + int iterations = 0; + +try_again: + int nextx = srcx, nexty = srcy; + if (trydir == DIR_LEFT) + nextx--; + else if (trydir == DIR_RIGHT) + nextx++; + else if (trydir == DIR_DOWN) + nexty++; + else if (trydir == DIR_UP) + nexty--; + + iterations++; + if (iterations > 5) { +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("not found: %d,%d beenhere 0x%X\n",srcx,srcy,beenhere[srcy][srcx]); +#endif + nesting--; + return 0; + } + + if (((nextx < 0) | (nextx >= wallscreen->GetWidth()) | (nexty < 0) | (nexty >= wallscreen->GetHeight())) || + (wallscreen->GetPixel(nextx, nexty) == 0) || ((beenhere[srcy][srcx] & (1 << trydir)) != 0)) { + + if (leftorright == 0) { + trydir++; + if (trydir > 3) + trydir = 0; + } else { + trydir--; + if (trydir < 0) + trydir = 3; + } + goto try_again; + } + beenhere[srcy][srcx] |= (1 << trydir); +// srcx=nextx; srcy=nexty; + beenhere[srcy][srcx] |= 0x80; // being processed + + int retcod = try_this_square(nextx, nexty, tox, toy); + if (retcod == 0) + goto try_again; + + nesting--; + beenhere[srcy][srcx] &= 0x7f; + if (retcod == 2) { + pathbackx[pathbackstage] = srcx; + pathbacky[pathbackstage] = srcy; + pathbackstage++; + if (pathbackstage >= MAXPATHBACK - 1) + return 0; + + return 2; + } + return 1; +} + + +#define CHECK_MIN(cellx, celly) { \ + if (beenhere[celly][cellx] == -1) {\ + adjcount = 0; \ + if ((wallscreen->GetScanLine(celly)[cellx] != 0) && (beenhere[j][i]+modifier <= min)) {\ + if (beenhere[j][i]+modifier < min) { \ + min = beenhere[j][i]+modifier; \ + numfound = 0; } \ + if (numfound < 40) { \ + newcell[numfound] = (celly) * wallscreen->GetWidth() + (cellx);\ + cheapest[numfound] = j * wallscreen->GetWidth() + i;\ + numfound++; \ + }\ + } \ + }} + +#define MAX_TRAIL_LENGTH 5000 + +// Round down the supplied co-ordinates to the area granularity, +// and move a bit if this causes them to become non-walkable +static void round_down_coords(int &tmpx, int &tmpy) +{ + assert(wallscreen != nullptr); + + int startgran = walk_area_granularity[wallscreen->GetPixel(tmpx, tmpy)]; + tmpy = tmpy - tmpy % startgran; + + if (tmpy < 0) + tmpy = 0; + + tmpx = tmpx - tmpx % startgran; + if (tmpx < 0) + tmpx = 0; + + if (wallscreen->GetPixel(tmpx, tmpy) == 0) { + tmpx += startgran; + if ((wallscreen->GetPixel(tmpx, tmpy) == 0) && (tmpy < wallscreen->GetHeight() - startgran)) { + tmpy += startgran; + + if (wallscreen->GetPixel(tmpx, tmpy) == 0) + tmpx -= startgran; + } + } +} + +static int find_route_dijkstra(int fromx, int fromy, int destx, int desty) +{ + int i, j; + + assert(wallscreen != nullptr); + assert(pathbackx != nullptr); + assert(pathbacky != nullptr); + assert(beenhere != nullptr); + + // This algorithm doesn't behave differently the second time, so ignore + if (leftorright == 1) + return 0; + + for (i = 0; i < wallscreen->GetHeight(); i++) + memset(&beenhere[i][0], 0xff, wallscreen->GetWidth() * BEENHERE_SIZE); + + round_down_coords(fromx, fromy); + beenhere[fromy][fromx] = 0; + + int temprd = destx, tempry = desty; + round_down_coords(temprd, tempry); + if ((temprd == fromx) && (tempry == fromy)) { + // already at destination + pathbackstage = 0; + return 1; + } + + int allocsize = int (wallscreen->GetWidth()) * int (wallscreen->GetHeight()) * sizeof(int); + int *parent = (int *)malloc(allocsize); + int min = 999999, cheapest[40], newcell[40], replace[40]; + int *visited = (int *)malloc(MAX_TRAIL_LENGTH * sizeof(int)); + int iteration = 1; + visited[0] = fromy * wallscreen->GetWidth() + fromx; + parent[visited[0]] = -1; + + int granularity = 3, newx = -1, newy, foundAnswer = -1, numreplace; + int changeiter, numfound, adjcount; + int destxlow = destx - MAX_GRANULARITY; + int destylow = desty - MAX_GRANULARITY; + int destxhi = destxlow + MAX_GRANULARITY * 2; + int destyhi = destylow + MAX_GRANULARITY * 2; + int modifier = 0; + int totalfound = 0; + int DIRECTION_BONUS = 0; + + update_polled_stuff_if_runtime(); + + while (foundAnswer < 0) { + min = 29999; + changeiter = iteration; + numfound = 0; + numreplace = 0; + + for (int n = 0; n < iteration; n++) { + if (visited[n] == -1) + continue; + + i = visited[n] % wallscreen->GetWidth(); + j = visited[n] / wallscreen->GetWidth(); + granularity = walk_area_granularity[wallscreen->GetScanLine(j)[i]]; + adjcount = 1; + + if (i >= granularity) { + modifier = (destx < i) ? DIRECTION_BONUS : 0; + CHECK_MIN(i - granularity, j) + } + + if (j >= granularity) { + modifier = (desty < j) ? DIRECTION_BONUS : 0; + CHECK_MIN(i, j - granularity) + } + + if (i < wallscreen->GetWidth() - granularity) { + modifier = (destx > i) ? DIRECTION_BONUS : 0; + CHECK_MIN(i + granularity, j) + } + + if (j < wallscreen->GetHeight() - granularity) { + modifier = (desty > j) ? DIRECTION_BONUS : 0; + CHECK_MIN(i, j + granularity) + } + + // If all the adjacent cells have been done, stop checking this one + if (adjcount) { + if (numreplace < 40) { + visited[numreplace] = -1; + replace[numreplace] = n; + numreplace++; + } + } + } + + if (numfound == 0) { + free(visited); + free(parent); + return 0; + } + + totalfound += numfound; + for (int p = 0; p < numfound; p++) { + newx = newcell[p] % wallscreen->GetWidth(); + newy = newcell[p] / wallscreen->GetWidth(); + beenhere[newy][newx] = beenhere[cheapest[p] / wallscreen->GetWidth()][cheapest[p] % wallscreen->GetWidth()] + 1; +// int wal = walk_area_granularity[->GetPixel(wallscreen, newx, newy)]; +// beenhere[newy - newy%wal][newx - newx%wal] = beenhere[newy][newx]; + parent[newcell[p]] = cheapest[p]; + + // edges of screen pose a problem, so if current and dest are within + // certain distance of the edge, say we've got it + if ((newx >= wallscreen->GetWidth() - MAX_GRANULARITY) && (destx >= wallscreen->GetWidth() - MAX_GRANULARITY)) + newx = destx; + + if ((newy >= wallscreen->GetHeight() - MAX_GRANULARITY) && (desty >= wallscreen->GetHeight() - MAX_GRANULARITY)) + newy = desty; + + // Found the desination, abort loop + if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) + && (newy <= destyhi)) { + foundAnswer = newcell[p]; + break; + } + + if (totalfound >= 1000) { + //Doesn't work cos it can see the destination from the point that's + //not nearest + // every so often, check if we can see the destination + if (can_see_from(newx, newy, destx, desty)) { + DIRECTION_BONUS -= 50; + totalfound = 0; + } + + } + + if (numreplace > 0) { + numreplace--; + changeiter = replace[numreplace]; + } else + changeiter = iteration; + + visited[changeiter] = newcell[p]; + if (changeiter == iteration) + iteration++; + + changeiter = iteration; + if (iteration >= MAX_TRAIL_LENGTH) { + free(visited); + free(parent); + return 0; + } + } + if (totalfound >= 1000) { + update_polled_stuff_if_runtime(); + totalfound = 0; + } + } + free(visited); + + int on; + pathbackstage = 0; + pathbackx[pathbackstage] = destx; + pathbacky[pathbackstage] = desty; + pathbackstage++; + + for (on = parent[foundAnswer];; on = parent[on]) { + if (on == -1) + break; + + newx = on % wallscreen->GetWidth(); + newy = on / wallscreen->GetWidth(); + if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) + && (newy <= destyhi)) + break; + + pathbackx[pathbackstage] = on % wallscreen->GetWidth(); + pathbacky[pathbackstage] = on / wallscreen->GetWidth(); + pathbackstage++; + if (pathbackstage >= MAXPATHBACK) { + free(parent); + return 0; + } + } + free(parent); + return 1; +} + +static int __find_route(int srcx, int srcy, short *tox, short *toy, int noredx) +{ + assert(wallscreen != nullptr); + assert(beenhere != nullptr); + assert(tox != nullptr); + assert(toy != nullptr); + + if ((noredx == 0) && (wallscreen->GetPixel(tox[0], toy[0]) == 0)) + return 0; // clicked on a wall + + pathbackstage = 0; + + if (leftorright == 0) { + waspossible = 1; + +findroutebk: + if ((srcx == tox[0]) && (srcy == toy[0])) { + pathbackstage = 0; + return 1; + } + + if ((waspossible = is_route_possible(srcx, srcy, tox[0], toy[0], wallscreen)) == 0) { + if (suggestx >= 0) { + tox[0] = suggestx; + toy[0] = suggesty; + goto findroutebk; + } + return 0; + } + } + + if (leftorright == 1) { + if (waspossible == 0) + return 0; + } + + // Try the new pathfinding algorithm + if (find_route_dijkstra(srcx, srcy, tox[0], toy[0])) { + return 1; + } + + // if the new pathfinder failed, try the old one + pathbackstage = 0; + memset(&beenhere[0][0], 0, wallscreen->GetWidth() * wallscreen->GetHeight() * BEENHERE_SIZE); + if (try_this_square(srcx, srcy, tox[0], toy[0]) == 0) + return 0; + + return 1; +} + +void set_route_move_speed(int speed_x, int speed_y) +{ + // negative move speeds like -2 get converted to 1/2 + if (speed_x < 0) { + move_speed_x = itofix(1) / (-speed_x); + } + else { + move_speed_x = itofix(speed_x); + } + + if (speed_y < 0) { + move_speed_y = itofix(1) / (-speed_y); + } + else { + move_speed_y = itofix(speed_y); + } +} + +// Calculates the X and Y per game loop, for this stage of the +// movelist +void calculate_move_stage(MoveList * mlsp, int aaa) +{ + assert(mlsp != nullptr); + + // work out the x & y per move. First, opp/adj=tan, so work out the angle + if (mlsp->pos[aaa] == mlsp->pos[aaa + 1]) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = 0; + return; + } + + short ourx = (mlsp->pos[aaa] >> 16) & 0x000ffff; + short oury = (mlsp->pos[aaa] & 0x000ffff); + short destx = ((mlsp->pos[aaa + 1] >> 16) & 0x000ffff); + short desty = (mlsp->pos[aaa + 1] & 0x000ffff); + + // Special case for vertical and horizontal movements + if (ourx == destx) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = move_speed_y; + if (desty < oury) + mlsp->ypermove[aaa] = -mlsp->ypermove[aaa]; + + return; + } + + if (oury == desty) { + mlsp->xpermove[aaa] = move_speed_x; + mlsp->ypermove[aaa] = 0; + if (destx < ourx) + mlsp->xpermove[aaa] = -mlsp->xpermove[aaa]; + + return; + } + + fixed xdist = itofix(abs(ourx - destx)); + fixed ydist = itofix(abs(oury - desty)); + + fixed useMoveSpeed; + + if (move_speed_x == move_speed_y) { + useMoveSpeed = move_speed_x; + } + else { + // different X and Y move speeds + // the X proportion of the movement is (x / (x + y)) + fixed xproportion = fixdiv(xdist, (xdist + ydist)); + + if (move_speed_x > move_speed_y) { + // speed = y + ((1 - xproportion) * (x - y)) + useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y); + } + else { + // speed = x + (xproportion * (y - x)) + useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x); + } + } + + fixed angl = fixatan(fixdiv(ydist, xdist)); + + // now, since new opp=hyp*sin, work out the Y step size + //fixed newymove = useMoveSpeed * fsin(angl); + fixed newymove = fixmul(useMoveSpeed, fixsin(angl)); + + // since adj=hyp*cos, work out X step size + //fixed newxmove = useMoveSpeed * fcos(angl); + fixed newxmove = fixmul(useMoveSpeed, fixcos(angl)); + + if (destx < ourx) + newxmove = -newxmove; + if (desty < oury) + newymove = -newymove; + + mlsp->xpermove[aaa] = newxmove; + mlsp->ypermove[aaa] = newymove; + +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("stage %d from %d,%d to %d,%d Xpermove:%X Ypm:%X", aaa, ourx, oury, destx, desty, newxmove, newymove); + // wtextcolor(14); + // wgtprintf((reallyneed[aaa] >> 16) & 0x000ffff, reallyneed[aaa] & 0x000ffff, cbuttfont, "%d", aaa); +#endif +} + + +#define MAKE_INTCOORD(x,y) (((unsigned short)x << 16) | ((unsigned short)y)) + +int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) +{ + assert(onscreen != nullptr); + assert(mls != nullptr); + assert(pathbackx != nullptr); + assert(pathbacky != nullptr); + +#ifdef DEBUG_PATHFINDER + // __wnormscreen(); +#endif + wallscreen = onscreen; + leftorright = 0; + int aaa; + + if (wallscreen->GetHeight() > beenhere_array_size) + { + beenhere = (short**)realloc(beenhere, sizeof(short*) * wallscreen->GetHeight()); + beenhere_array_size = wallscreen->GetHeight(); + + if (beenhere == nullptr) + quit("insufficient memory to allocate pathfinder beenhere buffer"); + + for (aaa = 0; aaa < wallscreen->GetHeight(); aaa++) + { + beenhere[aaa] = nullptr; + } + } + + int orisrcx = srcx, orisrcy = srcy; + finalpartx = -1; + + if (ignore_walls) { + pathbackstage = 0; + } + else if (can_see_from(srcx, srcy, xx, yy)) { + pathbackstage = 0; + } + else { + beenhere[0] = (short *)malloc((wallscreen->GetWidth()) * (wallscreen->GetHeight()) * BEENHERE_SIZE); + + for (aaa = 1; aaa < wallscreen->GetHeight(); aaa++) + beenhere[aaa] = beenhere[0] + aaa * (wallscreen->GetWidth()); + + if (__find_route(srcx, srcy, &xx, &yy, nocross) == 0) { + leftorright = 1; + if (__find_route(srcx, srcy, &xx, &yy, nocross) == 0) + pathbackstage = -1; + } + free(beenhere[0]); + + for (aaa = 0; aaa < wallscreen->GetHeight(); aaa++) + { + beenhere[aaa] = nullptr; + } + } + + if (pathbackstage >= 0) { + int nearestpos = 0, nearestindx; + int reallyneed[MAXNEEDSTAGES], numstages = 0; + reallyneed[numstages] = MAKE_INTCOORD(srcx,srcy); + numstages++; + nearestindx = -1; + + int lastpbs = pathbackstage; + +stage_again: + nearestpos = 0; + aaa = 1; + // find the furthest point that can be seen from this stage + for (aaa = pathbackstage - 1; aaa >= 0; aaa--) { +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("stage %2d: %2d,%2d\n",aaa,pathbackx[aaa],pathbacky[aaa]); +#endif + if (can_see_from(srcx, srcy, pathbackx[aaa], pathbacky[aaa])) { + nearestpos = MAKE_INTCOORD(pathbackx[aaa], pathbacky[aaa]); + nearestindx = aaa; + } + } + + if ((nearestpos == 0) && (can_see_from(srcx, srcy, xx, yy) == 0) && + (srcx >= 0) && (srcy >= 0) && (srcx < wallscreen->GetWidth()) && (srcy < wallscreen->GetHeight()) && (pathbackstage > 0)) { + // If we couldn't see anything, we're stuck in a corner so advance + // to the next square anyway (but only if they're on the screen) + nearestindx = pathbackstage - 1; + nearestpos = MAKE_INTCOORD(pathbackx[nearestindx], pathbacky[nearestindx]); + } + + if (nearestpos > 0) { + reallyneed[numstages] = nearestpos; + numstages++; + if (numstages >= MAXNEEDSTAGES - 1) + quit("too many stages for auto-walk"); + srcx = (nearestpos >> 16) & 0x000ffff; + srcy = nearestpos & 0x000ffff; +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("Added: %d, %d pbs:%d",srcx,srcy,pathbackstage); +#endif + lastpbs = pathbackstage; + pathbackstage = nearestindx; + goto stage_again; + } + + if (finalpartx >= 0) { + reallyneed[numstages] = MAKE_INTCOORD(finalpartx, finalparty); + numstages++; + } + + // Make sure the end co-ord is in there + if (reallyneed[numstages - 1] != MAKE_INTCOORD(xx, yy)) { + reallyneed[numstages] = MAKE_INTCOORD(xx, yy); + numstages++; + } + + if ((numstages == 1) && (xx == orisrcx) && (yy == orisrcy)) { + return 0; + } +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stage, %d stages", orisrcx,orisrcy,xx,yy,pathbackstage,numstages); +#endif + int mlist = movlst; + mls[mlist].numstage = numstages; + memcpy(&mls[mlist].pos[0], &reallyneed[0], sizeof(int) * numstages); +#ifdef DEBUG_PATHFINDER + AGS::Common::Debug::Printf("stages: %d\n",numstages); +#endif + + for (aaa = 0; aaa < numstages - 1; aaa++) { + calculate_move_stage(&mls[mlist], aaa); + } + + mls[mlist].fromx = orisrcx; + mls[mlist].fromy = orisrcy; + mls[mlist].onstage = 0; + mls[mlist].onpart = 0; + mls[mlist].doneflag = 0; + mls[mlist].lastx = -1; + mls[mlist].lasty = -1; +#ifdef DEBUG_PATHFINDER + // getch(); +#endif + return mlist; + } else { + return 0; + } + +#ifdef DEBUG_PATHFINDER + // __unnormscreen(); +#endif +} + +void shutdown_pathfinder() +{ + if (pathbackx != nullptr) + { + free(pathbackx); + } + if (pathbacky != nullptr) + { + free(pathbacky); + } + if (beenhere != nullptr) + { + if (beenhere[0] != nullptr) + { + free(beenhere[0]); + } + free(beenhere); + } + + pathbackx = nullptr; + pathbacky = nullptr; + beenhere = nullptr; + beenhere_array_size = 0; +} + + + +} // namespace RouteFinderLegacy +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h new file mode 100644 index 000000000000..490182c2b134 --- /dev/null +++ b/engines/ags/engine/ac/route_finder_impl_legacy.h @@ -0,0 +1,43 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_ROUTE_FINDER_IMPL_LEGACY +#define __AC_ROUTE_FINDER_IMPL_LEGACY + +// Forward declaration +namespace AGS { namespace Common { class Bitmap; }} +struct MoveList; + +namespace AGS { +namespace Engine { +namespace RouteFinderLegacy { + +void init_pathfinder(); +void shutdown_pathfinder(); + +void set_wallscreen(AGS::Common::Bitmap *wallscreen); + +int can_see_from(int x1, int y1, int x2, int y2); +void get_lastcpos(int &lastcx, int &lastcy); + +void set_route_move_speed(int speed_x, int speed_y); + +int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); +void calculate_move_stage(MoveList * mlsp, int aaa); + +} // namespace RouteFinderLegacy +} // namespace Engine +} // namespace AGS + +#endif // __AC_ROUTE_FINDER_IMPL_LEGACY \ No newline at end of file diff --git a/engines/ags/engine/ac/route_finder_jps.inl b/engines/ags/engine/ac/route_finder_jps.inl new file mode 100644 index 000000000000..e78db1b5762e --- /dev/null +++ b/engines/ags/engine/ac/route_finder_jps.inl @@ -0,0 +1,921 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// jump point search grid navigation with navpoint refinement +// (c) 2018 Martin Sedlak +// +//============================================================================= + +#include +#include +#include +#include +#include +#include +#include + +// TODO: this could be cleaned up/simplified ... + +// further optimizations possible: +// - forward refinement should use binary search + +class Navigation +{ +public: + Navigation(); + + void Resize(int width, int height); + + enum NavResult + { + // unreachable + NAV_UNREACHABLE, + // straight line exists + NAV_STRAIGHT, + // path used + NAV_PATH + }; + + // ncpath = navpoint-compressed path + // opath = path composed of individual grid elements + NavResult NavigateRefined(int sx, int sy, int ex, int ey, std::vector &opath, + std::vector &ncpath); + + NavResult Navigate(int sx, int sy, int ex, int ey, std::vector &opath); + + bool TraceLine(int srcx, int srcy, int targx, int targy, int &lastValidX, int &lastValidY) const; + bool TraceLine(int srcx, int srcy, int targx, int targy, std::vector *rpath = nullptr) const; + + inline void SetMapRow(int y, const unsigned char *row) {map[y] = row;} + + inline static int PackSquare(int x, int y); + inline static void UnpackSquare(int sq, int &x, int &y); + +private: + // priority queue entry + struct Entry + { + float cost; + int index; + + inline Entry() = default; + + inline Entry(float ncost, int nindex) + : cost(ncost) + , index(nindex) + { + } + + inline bool operator <(const Entry &b) const + { + return cost < b.cost; + } + + inline bool operator >(const Entry &b) const + { + return cost > b.cost; + } + }; + + int mapWidth; + int mapHeight; + std::vector map; + + typedef unsigned short tFrameId; + typedef int tPrev; + + struct NodeInfo + { + // quantized min distance from origin + unsigned short dist; + // frame id (counter to detect new search) + tFrameId frameId; + // previous node index (packed, relative to current node) + tPrev prev; + + inline NodeInfo() + : dist(0) + , frameId(0) + , prev(-1) + { + } + }; + + static const float DIST_SCALE_PACK; + static const float DIST_SCALE_UNPACK; + + std::vector mapNodes; + tFrameId frameId; + + std::priority_queue, std::greater > pq; + + // temporary buffers: + mutable std::vector fpath; + std::vector ncpathIndex; + std::vector rayPath, orayPath; + + // temps for routing towards unreachable areas + int cnode; + int closest; + + // orthogonal only (this should correspond to what AGS is doing) + bool nodiag; + + bool navLock; + + void IncFrameId(); + + // outside map test + inline bool Outside(int x, int y) const; + // stronger inside test + bool Passable(int x, int y) const; + // plain access, unchecked + inline bool Walkable(int x, int y) const; + + void AddPruned(int *buf, int &bcount, int x, int y) const; + bool HasForcedNeighbor(int x, int y, int dx, int dy) const; + int FindJump(int x, int y, int dx, int dy, int ex, int ey); + int FindOrthoJump(int x, int y, int dx, int dy, int ex, int ey); + + // neighbor reachable (nodiag only) + bool Reachable(int x0, int y0, int x1, int y1) const; + + static inline int sign(int n) + { + return n < 0 ? -1 : (n > 0 ? 1 : 0); + } + + static inline int iabs(int n) + { + return n < 0 ? -n : n; + } + + static inline int iclamp(int v, int min, int max) + { + return v < min ? min : (v > max ? max : v); + } + + static inline int ClosestDist(int dx, int dy) + { + return dx*dx + dy*dy; + // Manhattan? + //return iabs(dx) + iabs(dy); + } +}; + +// Navigation + +// scale pack of 2 means we can route up to 32767 units (euclidean distance) from starting point +// this means that the maximum routing bitmap size we can handle is 23169x23169; should be more than enough! +const float Navigation::DIST_SCALE_PACK = 2.0f; +const float Navigation::DIST_SCALE_UNPACK = 1.0f / Navigation::DIST_SCALE_PACK; + +Navigation::Navigation() + : mapWidth(0) + , mapHeight(0) + , frameId(1) + , cnode(0) + , closest(0) + // no diagonal route - this should correspond to what AGS does + , nodiag(true) + , navLock(false) +{ +} + +void Navigation::Resize(int width, int height) +{ + mapWidth = width; + mapHeight = height; + + int size = mapWidth*mapHeight; + + map.resize(mapHeight); + mapNodes.resize(size); +} + +void Navigation::IncFrameId() +{ + if (++frameId == 0) + { + for (int i=0; i<(int)mapNodes.size(); i++) + mapNodes[i].frameId = 0; + + frameId = 1; + } +} + +inline int Navigation::PackSquare(int x, int y) +{ + return (y << 16) + x; +} + +inline void Navigation::UnpackSquare(int sq, int &x, int &y) +{ + y = sq >> 16; + x = sq & ((1 << 16)-1); +} + +inline bool Navigation::Outside(int x, int y) const +{ + return + (unsigned)x >= (unsigned)mapWidth || + (unsigned)y >= (unsigned)mapHeight; +} + +inline bool Navigation::Walkable(int x, int y) const +{ + // invert condition because of AGS + return map[y][x] != 0; +} + +bool Navigation::Passable(int x, int y) const +{ + return !Outside(x, y) && Walkable(x, y); +} + +bool Navigation::Reachable(int x0, int y0, int x1, int y1) const +{ + assert(nodiag); + + return Passable(x1, y1) && + (Passable(x1, y0) || Passable(x0, y1)); +} + +// A* using jump point search (JPS) +// reference: http://users.cecs.anu.edu.au/~dharabor/data/papers/harabor-grastien-aaai11.pdf +void Navigation::AddPruned(int *buf, int &bcount, int x, int y) const +{ + assert(buf && bcount < 8); + + if (Passable(x, y)) + buf[bcount++] = PackSquare(x, y); +} + +bool Navigation::HasForcedNeighbor(int x, int y, int dx, int dy) const +{ + if (!dy) + { + return (!Passable(x, y-1) && Passable(x+dx, y-1)) || + (!Passable(x, y+1) && Passable(x+dx, y+1)); + } + + if (!dx) + { + return (!Passable(x-1, y) && Passable(x-1, y+dy)) || + (!Passable(x+1, y) && Passable(x+1, y+dy)); + } + + return + (!Passable(x - dx, y) && Passable(x - dx, y + dy)) || + (!Passable(x, y - dy) && Passable(x + dx, y - dy)); +} + +int Navigation::FindOrthoJump(int x, int y, int dx, int dy, int ex, int ey) +{ + assert((!dx || !dy) && (dx || dy)); + + for (;;) + { + x += dx; + y += dy; + + if (!Passable(x, y)) + break; + + int edx = x - ex; + int edy = y - ey; + int edist = ClosestDist(edx, edy); + + if (edist < closest) + { + closest = edist; + cnode = PackSquare(x, y); + } + + if ((x == ex && y == ey) || HasForcedNeighbor(x, y, dx, dy)) + return PackSquare(x, y); + } + + return -1; +} + +int Navigation::FindJump(int x, int y, int dx, int dy, int ex, int ey) +{ + if (!(dx && dy)) + return FindOrthoJump(x, y, dx, dy, ex, ey); + + if (nodiag && !Reachable(x, y, x+dx, y+dy)) + return -1; + + x += dx; + y += dy; + + if (!Passable(x, y)) + return -1; + + int edx = x - ex; + int edy = y - ey; + int edist = ClosestDist(edx, edy); + + if (edist < closest) + { + closest = edist; + cnode = PackSquare(x, y); + } + + if ((x == ex && y == ey) || HasForcedNeighbor(x, y, dx, dy)) + return PackSquare(x, y); + + if (dx && dy) + { + if (FindOrthoJump(x, y, dx, 0, ex, ey) || + FindOrthoJump(x, y, 0, dy, ex, ey)) + return PackSquare(x, y); + } + + return nodiag ? -1 : FindJump(x, y, dx, dy, ex, ey); +} + +Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std::vector &opath) +{ + IncFrameId(); + + if (!Passable(sx, sy)) + { + opath.clear(); + return NAV_UNREACHABLE; + } + + // try ray first, if reachable, no need for A* at all + if (!TraceLine(sx, sy, ex, ey, &opath)) + return NAV_STRAIGHT; + + NodeInfo &ni = mapNodes[sy*mapWidth+sx]; + ni.dist = 0; + ni.frameId = frameId; + ni.prev = -1; + + closest = 0x7fffffff; + cnode = PackSquare(sx, sy); + + // no clear for priority queue, like, really?! + while (!pq.empty()) + pq.pop(); + + pq.push(Entry(0.0, cnode)); + + while (!pq.empty()) + { + Entry e = pq.top(); + pq.pop(); + + int x, y; + UnpackSquare(e.index, x, y); + + int dx = x - ex; + int dy = y - ey; + int edist = ClosestDist(dx, dy); + + if (edist < closest) + { + closest = edist; + cnode = e.index; + } + + if (x == ex && y == ey) + { + // done + break; + } + + const NodeInfo &node = mapNodes[y*mapWidth+x]; + + float dist = node.dist * DIST_SCALE_UNPACK; + + int pneig[8]; + int ncount = 0; + + int prev = node.prev; + + if (prev < 0) + { + for (int ny = y-1; ny <= y+1; ny++) + { + if ((unsigned)ny >= (unsigned)mapHeight) + continue; + + for (int nx = x-1; nx <= x+1; nx++) + { + if (nx == x && ny == y) + continue; + + if ((unsigned)nx >= (unsigned)mapWidth) + continue; + + if (!Walkable(nx, ny)) + continue; + + if (nodiag && !Reachable(x, y, nx, ny)) + continue; + + pneig[ncount++] = PackSquare(nx, ny); + } + } + } + else + { + // filter + int px, py; + UnpackSquare(prev, px, py); + int dx = sign(x - px); + int dy = sign(y - py); + assert(dx || dy); + + if (!dy) + { + AddPruned(pneig, ncount, x+dx, y); + + // add corners + if (!nodiag || Passable(x+dx, y)) + { + if (!Passable(x, y+1)) + AddPruned(pneig, ncount, x+dx, y+1); + + if (!Passable(x, y-1)) + AddPruned(pneig, ncount, x+dx, y-1); + } + } + else if (!dx) + { + // same as above but transposed + AddPruned(pneig, ncount, x, y+dy); + + // add corners + if (!nodiag || Passable(x, y+dy)) + { + if (!Passable(x+1, y)) + AddPruned(pneig, ncount, x+1, y+dy); + + if (!Passable(x-1, y)) + AddPruned(pneig, ncount, x-1, y+dy); + } + } + else + { + // diagonal case + AddPruned(pneig, ncount, x, y+dy); + AddPruned(pneig, ncount, x+dx, y); + + if (!nodiag || Reachable(x, y, x+dx, y+dy)) + AddPruned(pneig, ncount, x+dx, y+dy); + + if (!Passable(x - dx, y) && + (nodiag || Reachable(x, y, x-dx, y+dy))) + AddPruned(pneig, ncount, x-dx, y+dy); + + if (!Passable(x, y-dy) && + (nodiag || Reachable(x, y, x+dx, y-dy))) + AddPruned(pneig, ncount, x+dx, y-dy); + } + } + + // sort by heuristics + Entry sort[8]; + + for (int ni = 0; ni < ncount; ni++) + { + int nx, ny; + UnpackSquare(pneig[ni], nx, ny); + float edx = (float)(nx - ex); + float edy = (float)(ny - ey); + sort[ni].cost = sqrt(edx*edx + edy*edy); + sort[ni].index = pneig[ni]; + } + + std::sort(sort, sort+ncount); + + int succ[8]; + int nsucc = 0; + + for (int ni=0; ni 65535.0f) + continue; + + node.dist = (unsigned short)(ecost + 0.5f); + node.frameId = frameId; + node.prev = PackSquare(x, y); + pq.push(Entry(ecost + heur, PackSquare(nx, ny))); + } + } + } + + opath.clear(); + + // now since we allow approx routing even if dst + // isn't directly reachable + // note: not sure if this provides optimal results even if we update + // cnode during jump search + int nex, ney; + UnpackSquare(cnode, nex, ney); + + if ((nex != sx || ney != sy) && (nex != ex || ney != ey)) + { + // target not directly reachable => move closer to target + TraceLine(nex, ney, ex, ey, &opath); + UnpackSquare(opath.back(), nex, ney); + + NavResult res = NAV_PATH; + + // note: navLock => better safe than sorry + // infinite recursion should never happen but... better safe than sorry + assert(!navLock); + + if (!navLock) + { + // and re-route + opath.clear(); + + navLock = true; + res = Navigate(sx, sy, nex, ney, opath); + navLock = false; + } + + // refine this a bit further; find path point closest + // to original target and truncate + + int best = 0x7fffffff; + int bestSize = (int)opath.size(); + + for (int i=0; i<(int)opath.size(); i++) + { + int x, y; + UnpackSquare(opath[i], x, y); + int dx = x-ex, dy = y-ey; + int cost = ClosestDist(dx, dy); + + if (cost < best) + { + best = cost; + bestSize = i+1; + } + } + + opath.resize(bestSize); + + return res; + } + + if (ex < 0 || ex >= mapWidth || ey < 0 || ey >= mapHeight || + mapNodes[ey*mapWidth+ex].frameId != frameId) + { + // path not found + return NAV_UNREACHABLE; + } + + int tx = ex; + int ty = ey; + // add end + opath.push_back(PackSquare(tx, ty)); + + for (;;) + { + int prev = mapNodes[ty*mapWidth+tx].prev; + + if (prev < 0) + break; + + // unpack because we use JPS + int px, py; + UnpackSquare(prev, px, py); + int dx = sign(px - tx); + int dy = sign(py - ty); + + while (tx != px || ty != py) + { + tx += dx; + ty += dy; + opath.push_back(PackSquare(tx, ty)); + } + } + + std::reverse(opath.begin(), opath.end()); + return NAV_PATH; +} + +Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey, + std::vector &opath, std::vector &ncpath) +{ + ncpath.clear(); + + NavResult res = Navigate(sx, sy, ex, ey, opath); + + if (res != NAV_PATH) + { + if (res == NAV_STRAIGHT) + { + ncpath.push_back(opath[0]); + ncpath.push_back(opath.back()); + } + + return res; + } + + int fx = sx; + int fy = sy; + + fpath.clear(); + ncpathIndex.clear(); + + fpath.reserve(opath.size()); + fpath.push_back(opath[0]); + ncpath.push_back(opath[0]); + ncpathIndex.push_back(0); + + rayPath.clear(); + orayPath.clear(); + + rayPath.reserve(opath.size()); + orayPath.reserve(opath.size()); + + for (int i=1; i<(int)opath.size(); i++) + { + // trying to optimize path + int tx, ty; + UnpackSquare(opath[i], tx, ty); + + bool last = i == (int)opath.size()-1; + + if (!TraceLine(fx, fy, tx, ty, &rayPath)) + { + assert(rayPath.back() == opath[i]); + std::swap(rayPath, orayPath); + + if (!last) + continue; + } + + // copy orayPath + for (int j=1; j<(int)orayPath.size(); j++) + fpath.push_back(orayPath[j]); + + if (!orayPath.empty()) + { + assert(ncpath.back() == orayPath[0]); + ncpath.push_back(orayPath.back()); + ncpathIndex.push_back((int)fpath.size()-1); + + if (!last) + { + UnpackSquare(orayPath.back(), fx, fy); + orayPath.clear(); + i--; + continue; + } + } + + if (fpath.back() != opath[i]) + fpath.push_back(opath[i]); + + if (ncpath.back() != opath[i]) + { + ncpath.push_back(opath[i]); + ncpathIndex.push_back((int)fpath.size()-1); + } + + fx = tx; + fy = ty; + } + + std::swap(opath, fpath); + + // validate cpath + for (int i=0; i<(int)ncpath.size()-1; i++) + { + int tx, ty; + UnpackSquare(ncpath[i], fx, fy); + UnpackSquare(ncpath[i+1], tx, ty); + assert(!TraceLine(fx, fy, tx, ty, &rayPath)); + } + + assert(ncpath.size() == ncpathIndex.size()); + + // so now we have opath, ncpath and ncpathIndex + // we want to gradually move ncpath node towards previous to see + // if we can raycast from prev ncpath node to moved and from moved + // to the end + + bool adjusted = false; + + for (int i=(int)ncpath.size()-2; i>0; i--) + { + int px, py; + int nx, ny; + + int pidx = ncpathIndex[i-1]; + int idx = ncpathIndex[i]; + + UnpackSquare(ncpath[i-1], px, py); + UnpackSquare(ncpath[i+1], nx, ny); + + for (int j=idx-1; j >= pidx; j--) + { + int x, y; + UnpackSquare(opath[j], x, y); + + // if we can raycast px,py => x,y and x,y => nx,ny, + // we can move ncPath node! + if (TraceLine(px, py, x, y)) + continue; + + if (TraceLine(x, y, nx, ny)) + continue; + + ncpath[i] = opath[j]; + ncpathIndex[i] = j; + adjusted = true; + } + + if (ncpath[i] == ncpath[i-1]) + { + // if we get here, we need to remove ncpath[i] + // because we reached the previous node + ncpath.erase(ncpath.begin()+i); + ncpathIndex.erase(ncpathIndex.begin()+i); + adjusted = true; + } + } + + if (!adjusted) + return NAV_PATH; + + // final step (if necessary) is to reconstruct path from compressed path + + opath.clear(); + opath.push_back(ncpath[0]); + + for (int i=1; i<(int)ncpath.size(); i++) + { + int fx, fy; + int tx, ty; + + UnpackSquare(ncpath[i-1], fx, fy); + UnpackSquare(ncpath[i], tx, ty); + + TraceLine(fx, fy, tx, ty, &rayPath); + + for (int j=1; j<(int)rayPath.size(); j++) + opath.push_back(rayPath[j]); + } + + return NAV_PATH; +} + +bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, int &lastValidX, int &lastValidY) const +{ + lastValidX = srcx; + lastValidY = srcy; + + bool res = TraceLine(srcx, srcy, targx, targy, &fpath); + + if (!fpath.empty()) + UnpackSquare(fpath.back(), lastValidX, lastValidY); + + return res; +} + +bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, std::vector *rpath) const +{ + if (rpath) + rpath->clear(); + + // DDA + int x0 = (srcx << 16) + 0x8000; + int y0 = (srcy << 16) + 0x8000; + int x1 = (targx << 16) + 0x8000; + int y1 = (targy << 16) + 0x8000; + + int dx = x1 - x0; + int dy = y1 - y0; + + if (!dx && !dy) + { + if (!Passable(srcx, srcy)) + return true; + + if (rpath) + rpath->push_back(PackSquare(srcx, srcy)); + + return false; + } + + int xinc, yinc; + + if (iabs(dx) >= iabs(dy)) + { + // step along x + xinc = sign(dx) * 65536; + yinc = (int)((double)dy * 65536 / iabs(dx)); + } + else + { + // step along y + yinc = sign(dy) * 65536; + xinc = (int)((double)dx * 65536 / iabs(dy)); + } + + int fx = x0; + int fy = y0; + int x = x0 >> 16; + int y = y0 >> 16; + int ex = x1 >> 16; + int ey = y1 >> 16; + + while (x != ex || y != ey) + { + if (!Passable(x, y)) + return true; + + if (rpath) + rpath->push_back(PackSquare(x, y)); + + fx += xinc; + fy += yinc; + int ox = x; + int oy = y; + x = fx >> 16; + y = fy >> 16; + + if (nodiag && !Reachable(ox, oy, x, y)) + return true; + } + + assert(iabs(x - ex) <= 1 && iabs(y - ey) <= 1); + + if (nodiag && !Reachable(x, y, ex, ey)) + return false; + + if (!Passable(ex, ey)) + return true; + + int sq = PackSquare(ex, ey); + + if (rpath && (rpath->empty() || rpath->back() != sq)) + rpath->push_back(sq); + + return false; +} diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h new file mode 100644 index 000000000000..d868a0f3a9c5 --- /dev/null +++ b/engines/ags/engine/ac/runtime_defines.h @@ -0,0 +1,153 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_RUNTIMEDEFINES_H +#define __AC_RUNTIMEDEFINES_H + +// xalleg.h pulls in an Allegro-internal definition of MAX_TIMERS which +// conflicts with the definition in runtime_defines.h. Forget it. +#ifdef MAX_TIMERS +#undef MAX_TIMERS +#endif + +// Max script string length +#define MAX_MAXSTRLEN 200 +#define MAXGLOBALVARS 50 + +#define INVALID_X 30000 +#define MAXGSVALUES 500 +#define MAXGLOBALSTRINGS 51 +#define MAX_INVORDER 500 +#define DIALOG_NONE 0 +#define DIALOG_RUNNING 1 +#define DIALOG_STOP 2 +#define DIALOG_NEWROOM 100 +#define DIALOG_NEWTOPIC 12000 +#define MAX_TIMERS 21 +#define MAX_PARSED_WORDS 15 +#define MAXSAVEGAMES 50 +#define MAX_QUEUED_MUSIC 10 +#define GLED_INTERACTION 1 +#define GLED_EFFECTS 2 +#define QUEUED_MUSIC_REPEAT 10000 +#define PLAYMP3FILE_MAX_FILENAME_LEN 50 +#define MAX_AUDIO_TYPES 30 + +// Legacy (pre 3.5.0) alignment types used in the script API +enum LegacyScriptAlignment +{ + kLegacyScAlignLeft = 1, + kLegacyScAlignCentre = 2, + kLegacyScAlignRight = 3 +}; + +const int LegacyMusicMasterVolumeAdjustment = 60; +const int LegacyRoomVolumeFactor = 30; + +// These numbers were chosen arbitrarily -- the idea is +// to make sure that the user gets the parameters the right way round +#define ANYWHERE 304 +#define WALKABLE_AREAS 305 +#define BLOCKING 919 +#define IN_BACKGROUND 920 +#define FORWARDS 1062 +#define BACKWARDS 1063 +#define STOP_MOVING 1 +#define KEEP_MOVING 0 + +#define SCR_NO_VALUE 31998 +#define SCR_COLOR_TRANSPARENT -1 + + + +#define NUM_DIGI_VOICES 16 +#define NUM_MOD_DIGI_VOICES 12 + +#define DEBUG_CONSOLE_NUMLINES 6 +#define TXT_SCOREBAR 29 +#define MAXSCORE play.totalscore +#define CHANIM_REPEAT 2 +#define CHANIM_BACKWARDS 4 +#define ANIM_BACKWARDS 10 +#define ANIM_ONCE 1 +#define ANIM_REPEAT 2 +#define ANIM_ONCERESET 3 +#define FONT_STATUSBAR 0 +#define FONT_NORMAL play.normal_font +//#define FONT_SPEECHBACK 1 +#define FONT_SPEECH play.speech_font +#define MODE_WALK 0 +#define MODE_LOOK 1 +#define MODE_HAND 2 +#define MODE_TALK 3 +#define MODE_USE 4 +#define MODE_PICKUP 5 +#define CURS_ARROW 6 +#define CURS_WAIT 7 +#define MODE_CUSTOM1 8 +#define MODE_CUSTOM2 9 + +#define OVER_TEXTMSG 1 +#define OVER_COMPLETE 2 +#define OVER_PICTURE 3 +#define OVER_CUSTOM 100 +#define OVR_AUTOPLACE 30000 +#define FOR_ANIMATION 1 +#define FOR_SCRIPT 2 +#define FOR_EXITLOOP 3 +#define CHMLSOFFS (MAX_ROOM_OBJECTS+1) // reserve this many movelists for objects & stuff +#define abort_all_conditions restrict_until +#define MAX_SCRIPT_AT_ONCE 10 +#define EVENT_NONE 0 +#define EVENT_INPROGRESS 1 +#define EVENT_CLAIMED 2 + +// Internal skip style flags, for speech/display, wait +#define SKIP_NONE 0 +#define SKIP_AUTOTIMER 1 +#define SKIP_KEYPRESS 2 +#define SKIP_MOUSECLICK 4 + +#define MANOBJNUM 99 + +#define STD_BUFFER_SIZE 3000 + +#define TURNING_AROUND 1000 +#define TURNING_BACKWARDS 10000 + +#define MAX_PLUGIN_OBJECT_READERS 50 + +#ifndef MAX_PATH +#define MAX_PATH 260 +#endif + +#define TRANS_ALPHA_CHANNEL 20000 +#define TRANS_OPAQUE 20001 +#define TRANS_RUN_PLUGIN 20002 + + +#define LOCTYPE_HOTSPOT 1 +#define LOCTYPE_CHAR 2 +#define LOCTYPE_OBJ 3 + +#define MAX_DYNAMIC_SURFACES 20 + +#define MAX_ANIMATING_BUTTONS 15 +#define RESTART_POINT_SAVE_GAME_NUMBER 999 + +#define MAX_OPEN_SCRIPT_FILES 10 + +#include "ac/common_defines.h" + +#endif // __AC_RUNTIMEDEFINES_H diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp new file mode 100644 index 000000000000..c28ea7f9a5b5 --- /dev/null +++ b/engines/ags/engine/ac/screen.cpp @@ -0,0 +1,229 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_game.h" +#include "ac/global_screen.h" +#include "ac/screen.h" +#include "ac/dynobj/scriptviewport.h" +#include "ac/dynobj/scriptuserobject.h" +#include "script/script_runtime.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameState play; +extern IGraphicsDriver *gfxDriver; +extern AGSPlatformDriver *platform; + +void my_fade_in(PALETTE p, int speed) { + if (game.color_depth > 1) { + set_palette (p); + + play.screen_is_faded_out = 0; + + if (play.no_hicolor_fadein) { + return; + } + } + + gfxDriver->FadeIn(speed, p, play.fade_to_red, play.fade_to_green, play.fade_to_blue); +} + +Bitmap *saved_viewport_bitmap = nullptr; +color old_palette[256]; +void current_fade_out_effect () { + if (pl_run_plugin_hooks(AGSE_TRANSITIONOUT, 0)) + return; + + // get the screen transition type + int theTransition = play.fade_effect; + // was a temporary transition selected? if so, use it + if (play.next_screen_transition >= 0) + theTransition = play.next_screen_transition; + const bool ignore_transition = play.screen_tint > 0; + + if ((theTransition == FADE_INSTANT) || ignore_transition) { + if (!play.keep_screen_during_instant_transition) + set_palette_range(black_palette, 0, 255, 0); + } + else if (theTransition == FADE_NORMAL) + { + my_fade_out(5); + } + else if (theTransition == FADE_BOXOUT) + { + gfxDriver->BoxOutEffect(true, get_fixed_pixel_size(16), 1000 / GetGameSpeed()); + play.screen_is_faded_out = 1; + } + else + { + get_palette(old_palette); + const Rect &viewport = play.GetMainViewport(); + saved_viewport_bitmap = CopyScreenIntoBitmap(viewport.GetWidth(), viewport.GetHeight()); + } +} + +IDriverDependantBitmap* prepare_screen_for_transition_in() +{ + if (saved_viewport_bitmap == nullptr) + quit("Crossfade: buffer is null attempting transition"); + + saved_viewport_bitmap = ReplaceBitmapWithSupportedFormat(saved_viewport_bitmap); + const Rect &viewport = play.GetMainViewport(); + if (saved_viewport_bitmap->GetHeight() < viewport.GetHeight()) + { + Bitmap *enlargedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); + enlargedBuffer->Blit(saved_viewport_bitmap, 0, 0, 0, (viewport.GetHeight() - saved_viewport_bitmap->GetHeight()) / 2, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); + delete saved_viewport_bitmap; + saved_viewport_bitmap = enlargedBuffer; + } + else if (saved_viewport_bitmap->GetHeight() > viewport.GetHeight()) + { + Bitmap *clippedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); + clippedBuffer->Blit(saved_viewport_bitmap, 0, (saved_viewport_bitmap->GetHeight() - viewport.GetHeight()) / 2, 0, 0, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); + delete saved_viewport_bitmap; + saved_viewport_bitmap = clippedBuffer; + } + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(saved_viewport_bitmap, false); + return ddb; +} + +//============================================================================= +// +// Screen script API. +// +//============================================================================= + +int Screen_GetScreenWidth() +{ + return game.GetGameRes().Width; +} + +int Screen_GetScreenHeight() +{ + return game.GetGameRes().Height; +} + +bool Screen_GetAutoSizeViewport() +{ + return play.IsAutoRoomViewport(); +} + +void Screen_SetAutoSizeViewport(bool on) +{ + play.SetAutoRoomViewport(on); +} + +ScriptViewport* Screen_GetViewport() +{ + return play.GetScriptViewport(0); +} + +int Screen_GetViewportCount() +{ + return play.GetRoomViewportCount(); +} + +ScriptViewport* Screen_GetAnyViewport(int index) +{ + return play.GetScriptViewport(index); +} + +ScriptUserObject* Screen_ScreenToRoomPoint(int scrx, int scry) +{ + data_to_game_coords(&scrx, &scry); + + VpPoint vpt = play.ScreenToRoom(scrx, scry); + if (vpt.second < 0) + return nullptr; + + game_to_data_coords(vpt.first.X, vpt.first.Y); + return ScriptStructHelpers::CreatePoint(vpt.first.X, vpt.first.Y); +} + +ScriptUserObject *Screen_RoomToScreenPoint(int roomx, int roomy) +{ + data_to_game_coords(&roomx, &roomy); + Point pt = play.RoomToScreen(roomx, roomy); + game_to_data_coords(pt.X, pt.Y); + return ScriptStructHelpers::CreatePoint(pt.X, pt.Y); +} + +RuntimeScriptValue Sc_Screen_GetScreenHeight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Screen_GetScreenHeight); +} + +RuntimeScriptValue Sc_Screen_GetScreenWidth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Screen_GetScreenWidth); +} + +RuntimeScriptValue Sc_Screen_GetAutoSizeViewport(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_BOOL(Screen_GetAutoSizeViewport); +} + +RuntimeScriptValue Sc_Screen_SetAutoSizeViewport(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PBOOL(Screen_SetAutoSizeViewport); +} + +RuntimeScriptValue Sc_Screen_GetViewport(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO(ScriptViewport, Screen_GetViewport); +} + +RuntimeScriptValue Sc_Screen_GetViewportCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(Screen_GetViewportCount); +} + +RuntimeScriptValue Sc_Screen_GetAnyViewport(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT(ScriptViewport, Screen_GetAnyViewport); +} + +RuntimeScriptValue Sc_Screen_ScreenToRoomPoint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT2(ScriptUserObject, Screen_ScreenToRoomPoint); +} + +RuntimeScriptValue Sc_Screen_RoomToScreenPoint(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT2(ScriptUserObject, Screen_RoomToScreenPoint); +} + +void RegisterScreenAPI() +{ + ccAddExternalStaticFunction("Screen::get_Height", Sc_Screen_GetScreenHeight); + ccAddExternalStaticFunction("Screen::get_Width", Sc_Screen_GetScreenWidth); + ccAddExternalStaticFunction("Screen::get_AutoSizeViewportOnRoomLoad", Sc_Screen_GetAutoSizeViewport); + ccAddExternalStaticFunction("Screen::set_AutoSizeViewportOnRoomLoad", Sc_Screen_SetAutoSizeViewport); + ccAddExternalStaticFunction("Screen::get_Viewport", Sc_Screen_GetViewport); + ccAddExternalStaticFunction("Screen::get_ViewportCount", Sc_Screen_GetViewportCount); + ccAddExternalStaticFunction("Screen::geti_Viewports", Sc_Screen_GetAnyViewport); + ccAddExternalStaticFunction("Screen::ScreenToRoomPoint", Sc_Screen_ScreenToRoomPoint); + ccAddExternalStaticFunction("Screen::RoomToScreenPoint", Sc_Screen_RoomToScreenPoint); +} diff --git a/engines/ags/engine/ac/screen.h b/engines/ags/engine/ac/screen.h new file mode 100644 index 000000000000..4ad3e7de022f --- /dev/null +++ b/engines/ags/engine/ac/screen.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SCREEN_H +#define __AGS_EE_AC__SCREEN_H + +namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { namespace Engine { class IDriverDependantBitmap; } } + +void my_fade_in(PALETTE p, int speed); +void current_fade_out_effect (); +AGS::Engine::IDriverDependantBitmap* prepare_screen_for_transition_in(); + +// Screenshot made in the last room, used during some of the transition effects +extern AGS::Common::Bitmap *saved_viewport_bitmap; + +#endif // __AGS_EE_AC__SCREEN_H diff --git a/engines/ags/engine/ac/screenoverlay.cpp b/engines/ags/engine/ac/screenoverlay.cpp new file mode 100644 index 000000000000..205e3b0867fb --- /dev/null +++ b/engines/ags/engine/ac/screenoverlay.cpp @@ -0,0 +1,59 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "screenoverlay.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +void ScreenOverlay::ReadFromFile(Stream *in, int32_t cmp_ver) +{ + // Skipping bmp and pic pointer values + // TODO: find out if it's safe to just drop these pointers!! replace with unique_ptr? + bmp = nullptr; + pic = nullptr; + in->ReadInt32(); // bmp + hasSerializedBitmap = in->ReadInt32() != 0; + type = in->ReadInt32(); + x = in->ReadInt32(); + y = in->ReadInt32(); + timeout = in->ReadInt32(); + bgSpeechForChar = in->ReadInt32(); + associatedOverlayHandle = in->ReadInt32(); + hasAlphaChannel = in->ReadBool(); + positionRelativeToScreen = in->ReadBool(); + if (cmp_ver >= 1) + { + _offsetX = in->ReadInt32(); + _offsetY = in->ReadInt32(); + } +} + +void ScreenOverlay::WriteToFile(Stream *out) const +{ + // Writing bitmap "pointers" to correspond to full structure writing + out->WriteInt32(0); // bmp + out->WriteInt32(pic ? 1 : 0); // pic + out->WriteInt32(type); + out->WriteInt32(x); + out->WriteInt32(y); + out->WriteInt32(timeout); + out->WriteInt32(bgSpeechForChar); + out->WriteInt32(associatedOverlayHandle); + out->WriteBool(hasAlphaChannel); + out->WriteBool(positionRelativeToScreen); + // since cmp_ver = 1 + out->WriteInt32(_offsetX); + out->WriteInt32(_offsetY); +} diff --git a/engines/ags/engine/ac/screenoverlay.h b/engines/ags/engine/ac/screenoverlay.h new file mode 100644 index 000000000000..6ede440e6c28 --- /dev/null +++ b/engines/ags/engine/ac/screenoverlay.h @@ -0,0 +1,44 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SCREENOVERLAY_H +#define __AGS_EE_AC__SCREENOVERLAY_H + +#include + +// Forward declaration +namespace AGS { namespace Common { class Bitmap; class Stream; } } +namespace AGS { namespace Engine { class IDriverDependantBitmap; }} +using namespace AGS; // FIXME later + + +struct ScreenOverlay { + Engine::IDriverDependantBitmap *bmp = nullptr; + Common::Bitmap *pic = nullptr; + int type = 0, x = 0, y = 0, timeout = 0; + int bgSpeechForChar = 0; + int associatedOverlayHandle = 0; + bool hasAlphaChannel = false; + bool positionRelativeToScreen = false; + bool hasSerializedBitmap = false; + int _offsetX = 0, _offsetY = 0; + + void ReadFromFile(Common::Stream *in, int32_t cmp_ver); + void WriteToFile(Common::Stream *out) const; +}; + +#endif // __AGS_EE_AC__SCREENOVERLAY_H diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp new file mode 100644 index 000000000000..b02d53bcc467 --- /dev/null +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -0,0 +1,354 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Containers script API. +// +//============================================================================= +#include "ac/common.h" // quit +#include "ac/string.h" +#include "ac/dynobj/cc_dynamicarray.h" +#include "ac/dynobj/cc_dynamicobject.h" +#include "ac/dynobj/scriptdict.h" +#include "ac/dynobj/scriptset.h" +#include "ac/dynobj/scriptstring.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "util/bbop.h" + +extern ScriptString myScriptStringImpl; + +//============================================================================= +// +// Dictionary of strings script API. +// +//============================================================================= + +ScriptDictBase *Dict_CreateImpl(bool sorted, bool case_sensitive) +{ + ScriptDictBase *dic; + if (sorted) + { + if (case_sensitive) + dic = new ScriptDict(); + else + dic = new ScriptDictCI(); + } + else + { + if (case_sensitive) + dic = new ScriptHashDict(); + else + dic = new ScriptHashDictCI(); + } + return dic; +} + +ScriptDictBase *Dict_Create(bool sorted, bool case_sensitive) +{ + ScriptDictBase *dic = Dict_CreateImpl(sorted, case_sensitive); + ccRegisterManagedObject(dic, dic); + return dic; +} + +// TODO: we need memory streams +ScriptDictBase *Dict_Unserialize(int index, const char *serializedData, int dataSize) +{ + if (dataSize < sizeof(int32_t) * 2) + quit("Dict_Unserialize: not enough data."); + const char *ptr = serializedData; + const int sorted = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); + const int cs = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); + ScriptDictBase *dic = Dict_CreateImpl(sorted != 0, cs != 0); + dic->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); + return dic; +} + +void Dict_Clear(ScriptDictBase *dic) +{ + dic->Clear(); +} + +bool Dict_Contains(ScriptDictBase *dic, const char *key) +{ + return dic->Contains(key); +} + +const char *Dict_Get(ScriptDictBase *dic, const char *key) +{ + auto *str = dic->Get(key); + return str ? CreateNewScriptString(str) : nullptr; +} + +bool Dict_Remove(ScriptDictBase *dic, const char *key) +{ + return dic->Remove(key); +} + +bool Dict_Set(ScriptDictBase *dic, const char *key, const char *value) +{ + return dic->Set(key, value); +} + +int Dict_GetCompareStyle(ScriptDictBase *dic) +{ + return dic->IsCaseSensitive() ? 1 : 0; +} + +int Dict_GetSortStyle(ScriptDictBase *dic) +{ + return dic->IsSorted() ? 1 : 0; +} + +int Dict_GetItemCount(ScriptDictBase *dic) +{ + return dic->GetItemCount(); +} + +void *Dict_GetKeysAsArray(ScriptDictBase *dic) +{ + std::vector items; + dic->GetKeys(items); + if (items.size() == 0) + return nullptr; + DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); + return arr.second; +} + +void *Dict_GetValuesAsArray(ScriptDictBase *dic) +{ + std::vector items; + dic->GetValues(items); + if (items.size() == 0) + return nullptr; + DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); + return arr.second; +} + +RuntimeScriptValue Sc_Dict_Create(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PBOOL2(ScriptDictBase, Dict_Create); +} + +RuntimeScriptValue Sc_Dict_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptDictBase, Dict_Clear); +} + +RuntimeScriptValue Sc_Dict_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Contains, const char); +} + +RuntimeScriptValue Sc_Dict_Get(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, myScriptStringImpl, Dict_Get, const char); +} + +RuntimeScriptValue Sc_Dict_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Remove, const char); +} + +RuntimeScriptValue Sc_Dict_Set(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ2(ScriptDictBase, Dict_Set, const char, const char); +} + +RuntimeScriptValue Sc_Dict_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDictBase, Dict_GetCompareStyle); +} + +RuntimeScriptValue Sc_Dict_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDictBase, Dict_GetSortStyle); +} + +RuntimeScriptValue Sc_Dict_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptDictBase, Dict_GetItemCount); +} + +RuntimeScriptValue Sc_Dict_GetKeysAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptDictBase, void, globalDynamicArray, Dict_GetKeysAsArray); +} + +RuntimeScriptValue Sc_Dict_GetValuesAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptDictBase, void, globalDynamicArray, Dict_GetValuesAsArray); +} + +//============================================================================= +// +// Set of strings script API. +// +//============================================================================= + +ScriptSetBase *Set_CreateImpl(bool sorted, bool case_sensitive) +{ + ScriptSetBase *set; + if (sorted) + { + if (case_sensitive) + set = new ScriptSet(); + else + set = new ScriptSetCI(); + } + else + { + if (case_sensitive) + set = new ScriptHashSet(); + else + set = new ScriptHashSetCI(); + } + return set; +} + +ScriptSetBase *Set_Create(bool sorted, bool case_sensitive) +{ + ScriptSetBase *set = Set_CreateImpl(sorted, case_sensitive); + ccRegisterManagedObject(set, set); + return set; +} + +// TODO: we need memory streams +ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize) +{ + if (dataSize < sizeof(int32_t) * 2) + quit("Set_Unserialize: not enough data."); + const char *ptr = serializedData; + const int sorted = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); + const int cs = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); + ScriptSetBase *set = Set_CreateImpl(sorted != 0, cs != 0); + set->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); + return set; +} + +bool Set_Add(ScriptSetBase *set, const char *item) +{ + return set->Add(item); +} + +void Set_Clear(ScriptSetBase *set) +{ + set->Clear(); +} + +bool Set_Contains(ScriptSetBase *set, const char *item) +{ + return set->Contains(item); +} + +bool Set_Remove(ScriptSetBase *set, const char *item) +{ + return set->Remove(item); +} + +int Set_GetCompareStyle(ScriptSetBase *set) +{ + return set->IsCaseSensitive() ? 1 : 0; +} + +int Set_GetSortStyle(ScriptSetBase *set) +{ + return set->IsSorted() ? 1 : 0; +} + +int Set_GetItemCount(ScriptSetBase *set) +{ + return set->GetItemCount(); +} + +void *Set_GetItemsAsArray(ScriptSetBase *set) +{ + std::vector items; + set->GetItems(items); + if (items.size() == 0) + return nullptr; + DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); + return arr.second; +} + +RuntimeScriptValue Sc_Set_Create(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PBOOL2(ScriptSetBase, Set_Create); +} + +RuntimeScriptValue Sc_Set_Add(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Add, const char); +} + +RuntimeScriptValue Sc_Set_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptSetBase, Set_Clear); +} + +RuntimeScriptValue Sc_Set_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Contains, const char); +} + +RuntimeScriptValue Sc_Set_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Remove, const char); +} + +RuntimeScriptValue Sc_Set_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptSetBase, Set_GetCompareStyle); +} + +RuntimeScriptValue Sc_Set_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptSetBase, Set_GetSortStyle); +} + +RuntimeScriptValue Sc_Set_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptSetBase, Set_GetItemCount); +} + +RuntimeScriptValue Sc_Set_GetItemAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptSetBase, void, globalDynamicArray, Set_GetItemsAsArray); +} + + + +void RegisterContainerAPI() +{ + ccAddExternalStaticFunction("Dictionary::Create", Sc_Dict_Create); + ccAddExternalObjectFunction("Dictionary::Clear", Sc_Dict_Clear); + ccAddExternalObjectFunction("Dictionary::Contains", Sc_Dict_Contains); + ccAddExternalObjectFunction("Dictionary::Get", Sc_Dict_Get); + ccAddExternalObjectFunction("Dictionary::Remove", Sc_Dict_Remove); + ccAddExternalObjectFunction("Dictionary::Set", Sc_Dict_Set); + ccAddExternalObjectFunction("Dictionary::get_CompareStyle", Sc_Dict_GetCompareStyle); + ccAddExternalObjectFunction("Dictionary::get_SortStyle", Sc_Dict_GetSortStyle); + ccAddExternalObjectFunction("Dictionary::get_ItemCount", Sc_Dict_GetItemCount); + ccAddExternalObjectFunction("Dictionary::GetKeysAsArray", Sc_Dict_GetKeysAsArray); + ccAddExternalObjectFunction("Dictionary::GetValuesAsArray", Sc_Dict_GetValuesAsArray); + + ccAddExternalStaticFunction("Set::Create", Sc_Set_Create); + ccAddExternalObjectFunction("Set::Add", Sc_Set_Add); + ccAddExternalObjectFunction("Set::Clear", Sc_Set_Clear); + ccAddExternalObjectFunction("Set::Contains", Sc_Set_Contains); + ccAddExternalObjectFunction("Set::Remove", Sc_Set_Remove); + ccAddExternalObjectFunction("Set::get_CompareStyle", Sc_Set_GetCompareStyle); + ccAddExternalObjectFunction("Set::get_SortStyle", Sc_Set_GetSortStyle); + ccAddExternalObjectFunction("Set::get_ItemCount", Sc_Set_GetItemCount); + ccAddExternalObjectFunction("Set::GetItemsAsArray", Sc_Set_GetItemAsArray); +} diff --git a/engines/ags/engine/ac/slider.cpp b/engines/ags/engine/ac/slider.cpp new file mode 100644 index 000000000000..1f489340fd8d --- /dev/null +++ b/engines/ags/engine/ac/slider.cpp @@ -0,0 +1,223 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/slider.h" +#include "ac/common.h" + +// *** SLIDER FUNCTIONS + +void Slider_SetMax(GUISlider *guisl, int valn) { + + if (valn != guisl->MaxValue) { + guisl->MaxValue = valn; + + if (guisl->Value > guisl->MaxValue) + guisl->Value = guisl->MaxValue; + if (guisl->MinValue > guisl->MaxValue) + quit("!Slider.Max: minimum cannot be greater than maximum"); + + guis_need_update = 1; + } + +} + +int Slider_GetMax(GUISlider *guisl) { + return guisl->MaxValue; +} + +void Slider_SetMin(GUISlider *guisl, int valn) { + + if (valn != guisl->MinValue) { + guisl->MinValue = valn; + + if (guisl->Value < guisl->MinValue) + guisl->Value = guisl->MinValue; + if (guisl->MinValue > guisl->MaxValue) + quit("!Slider.Min: minimum cannot be greater than maximum"); + + guis_need_update = 1; + } + +} + +int Slider_GetMin(GUISlider *guisl) { + return guisl->MinValue; +} + +void Slider_SetValue(GUISlider *guisl, int valn) { + if (valn > guisl->MaxValue) valn = guisl->MaxValue; + if (valn < guisl->MinValue) valn = guisl->MinValue; + + if (valn != guisl->Value) { + guisl->Value = valn; + guis_need_update = 1; + } +} + +int Slider_GetValue(GUISlider *guisl) { + return guisl->Value; +} + +int Slider_GetBackgroundGraphic(GUISlider *guisl) { + return (guisl->BgImage > 0) ? guisl->BgImage : 0; +} + +void Slider_SetBackgroundGraphic(GUISlider *guisl, int newImage) +{ + if (newImage != guisl->BgImage) + { + guisl->BgImage = newImage; + guis_need_update = 1; + } +} + +int Slider_GetHandleGraphic(GUISlider *guisl) { + return (guisl->HandleImage > 0) ? guisl->HandleImage : 0; +} + +void Slider_SetHandleGraphic(GUISlider *guisl, int newImage) +{ + if (newImage != guisl->HandleImage) + { + guisl->HandleImage = newImage; + guis_need_update = 1; + } +} + +int Slider_GetHandleOffset(GUISlider *guisl) { + return guisl->HandleOffset; +} + +void Slider_SetHandleOffset(GUISlider *guisl, int newOffset) +{ + if (newOffset != guisl->HandleOffset) + { + guisl->HandleOffset = newOffset; + guis_need_update = 1; + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// int (GUISlider *guisl) +RuntimeScriptValue Sc_Slider_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUISlider, Slider_GetBackgroundGraphic); +} + +// void (GUISlider *guisl, int newImage) +RuntimeScriptValue Sc_Slider_SetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetBackgroundGraphic); +} + +// int (GUISlider *guisl) +RuntimeScriptValue Sc_Slider_GetHandleGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUISlider, Slider_GetHandleGraphic); +} + +// void (GUISlider *guisl, int newImage) +RuntimeScriptValue Sc_Slider_SetHandleGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetHandleGraphic); +} + +// int (GUISlider *guisl) +RuntimeScriptValue Sc_Slider_GetHandleOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUISlider, Slider_GetHandleOffset); +} + +// void (GUISlider *guisl, int newOffset) +RuntimeScriptValue Sc_Slider_SetHandleOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetHandleOffset); +} + +// int (GUISlider *guisl) +RuntimeScriptValue Sc_Slider_GetMax(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUISlider, Slider_GetMax); +} + +// void (GUISlider *guisl, int valn) +RuntimeScriptValue Sc_Slider_SetMax(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetMax); +} + +// int (GUISlider *guisl) +RuntimeScriptValue Sc_Slider_GetMin(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUISlider, Slider_GetMin); +} + +// void (GUISlider *guisl, int valn) +RuntimeScriptValue Sc_Slider_SetMin(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetMin); +} + +// int (GUISlider *guisl) +RuntimeScriptValue Sc_Slider_GetValue(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUISlider, Slider_GetValue); +} + +// void Slider_SetValue(GUISlider *guisl, int valn) +RuntimeScriptValue Sc_Slider_SetValue(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetValue); +} + + +void RegisterSliderAPI() +{ + ccAddExternalObjectFunction("Slider::get_BackgroundGraphic", Sc_Slider_GetBackgroundGraphic); + ccAddExternalObjectFunction("Slider::set_BackgroundGraphic", Sc_Slider_SetBackgroundGraphic); + ccAddExternalObjectFunction("Slider::get_HandleGraphic", Sc_Slider_GetHandleGraphic); + ccAddExternalObjectFunction("Slider::set_HandleGraphic", Sc_Slider_SetHandleGraphic); + ccAddExternalObjectFunction("Slider::get_HandleOffset", Sc_Slider_GetHandleOffset); + ccAddExternalObjectFunction("Slider::set_HandleOffset", Sc_Slider_SetHandleOffset); + ccAddExternalObjectFunction("Slider::get_Max", Sc_Slider_GetMax); + ccAddExternalObjectFunction("Slider::set_Max", Sc_Slider_SetMax); + ccAddExternalObjectFunction("Slider::get_Min", Sc_Slider_GetMin); + ccAddExternalObjectFunction("Slider::set_Min", Sc_Slider_SetMin); + ccAddExternalObjectFunction("Slider::get_Value", Sc_Slider_GetValue); + ccAddExternalObjectFunction("Slider::set_Value", Sc_Slider_SetValue); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Slider::get_BackgroundGraphic", (void*)Slider_GetBackgroundGraphic); + ccAddExternalFunctionForPlugin("Slider::set_BackgroundGraphic", (void*)Slider_SetBackgroundGraphic); + ccAddExternalFunctionForPlugin("Slider::get_HandleGraphic", (void*)Slider_GetHandleGraphic); + ccAddExternalFunctionForPlugin("Slider::set_HandleGraphic", (void*)Slider_SetHandleGraphic); + ccAddExternalFunctionForPlugin("Slider::get_HandleOffset", (void*)Slider_GetHandleOffset); + ccAddExternalFunctionForPlugin("Slider::set_HandleOffset", (void*)Slider_SetHandleOffset); + ccAddExternalFunctionForPlugin("Slider::get_Max", (void*)Slider_GetMax); + ccAddExternalFunctionForPlugin("Slider::set_Max", (void*)Slider_SetMax); + ccAddExternalFunctionForPlugin("Slider::get_Min", (void*)Slider_GetMin); + ccAddExternalFunctionForPlugin("Slider::set_Min", (void*)Slider_SetMin); + ccAddExternalFunctionForPlugin("Slider::get_Value", (void*)Slider_GetValue); + ccAddExternalFunctionForPlugin("Slider::set_Value", (void*)Slider_SetValue); +} diff --git a/engines/ags/engine/ac/slider.h b/engines/ags/engine/ac/slider.h new file mode 100644 index 000000000000..402b73656642 --- /dev/null +++ b/engines/ags/engine/ac/slider.h @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SLIDER_H +#define __AGS_EE_AC__SLIDER_H + +#include "gui/guislider.h" + +using AGS::Common::GUISlider; + +void Slider_SetMax(GUISlider *guisl, int valn); +int Slider_GetMax(GUISlider *guisl); +void Slider_SetMin(GUISlider *guisl, int valn); +int Slider_GetMin(GUISlider *guisl); +void Slider_SetValue(GUISlider *guisl, int valn); +int Slider_GetValue(GUISlider *guisl); +int Slider_GetBackgroundGraphic(GUISlider *guisl); +void Slider_SetBackgroundGraphic(GUISlider *guisl, int newImage); +int Slider_GetHandleGraphic(GUISlider *guisl); +void Slider_SetHandleGraphic(GUISlider *guisl, int newImage); +int Slider_GetHandleOffset(GUISlider *guisl); +void Slider_SetHandleOffset(GUISlider *guisl, int newOffset); + +#endif // __AGS_EE_AC__SLIDER_H diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp new file mode 100644 index 000000000000..dbe24beb3b1d --- /dev/null +++ b/engines/ags/engine/ac/speech.cpp @@ -0,0 +1,254 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/runtime_defines.h" +#include "ac/speech.h" +#include "debug/debug_log.h" + +int user_to_internal_skip_speech(SkipSpeechStyle userval) +{ + switch (userval) + { + case kSkipSpeechKeyMouseTime: + return SKIP_AUTOTIMER | SKIP_KEYPRESS | SKIP_MOUSECLICK; + case kSkipSpeechKeyTime: + return SKIP_AUTOTIMER | SKIP_KEYPRESS; + case kSkipSpeechTime: + return SKIP_AUTOTIMER; + case kSkipSpeechKeyMouse: + return SKIP_KEYPRESS | SKIP_MOUSECLICK; + case kSkipSpeechMouseTime: + return SKIP_AUTOTIMER | SKIP_MOUSECLICK; + case kSkipSpeechKey: + return SKIP_KEYPRESS; + case kSkipSpeechMouse: + return SKIP_MOUSECLICK; + default: + quit("user_to_internal_skip_speech: unknown userval"); + return 0; + } +} + +SkipSpeechStyle internal_skip_speech_to_user(int internal_val) +{ + if (internal_val & SKIP_AUTOTIMER) + { + internal_val &= ~SKIP_AUTOTIMER; + if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) + { + return kSkipSpeechKeyMouseTime; + } + else if (internal_val == SKIP_KEYPRESS) + { + return kSkipSpeechKeyTime; + } + else if (internal_val == SKIP_MOUSECLICK) + { + return kSkipSpeechMouseTime; + } + return kSkipSpeechTime; + } + else + { + if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) + { + return kSkipSpeechKeyMouse; + } + else if (internal_val == SKIP_KEYPRESS) + { + return kSkipSpeechKey; + } + else if (internal_val == SKIP_MOUSECLICK) + { + return kSkipSpeechMouse; + } + } + return kSkipSpeechUndefined; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/global_display.h" +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +extern GameSetupStruct game; +extern GameState play; + +RuntimeScriptValue Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.close_mouth_speech_time); +} + +RuntimeScriptValue Sc_Speech_SetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARSET_PINT(play.close_mouth_speech_time); +} + +RuntimeScriptValue Sc_Speech_GetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.speech_portrait_placement); +} + +RuntimeScriptValue Sc_Speech_SetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARSET_PINT(play.speech_portrait_placement); +} + +RuntimeScriptValue Sc_Speech_GetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.speech_display_post_time_ms); +} + +RuntimeScriptValue Sc_Speech_SetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARSET_PINT(play.speech_display_post_time_ms); +} + +RuntimeScriptValue Sc_Speech_GetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.talkanim_speed); +} + +RuntimeScriptValue Sc_Speech_SetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) +{ + if (game.options[OPT_GLOBALTALKANIMSPD] == 0) + { + debug_script_warn("Speech.GlobalSpeechAnimationDelay cannot be set when global speech animation speed is not enabled; set Speech.UseGlobalSpeechAnimationDelay first!"); + return RuntimeScriptValue(); + } + API_VARSET_PINT(play.talkanim_speed); +} + +RuntimeScriptValue Sc_Speech_GetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.speech_portrait_x); +} + +RuntimeScriptValue Sc_Speech_SetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARSET_PINT(play.speech_portrait_x); +} + +RuntimeScriptValue Sc_Speech_GetPortraitY(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.speech_portrait_y); +} + +RuntimeScriptValue Sc_Speech_SetPortraitY(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARSET_PINT(play.speech_portrait_y); +} + +RuntimeScriptValue Sc_Speech_GetStyle(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(game.options[OPT_SPEECHTYPE]); +} + +extern RuntimeScriptValue Sc_SetSpeechStyle(const RuntimeScriptValue *params, int32_t param_count); + +RuntimeScriptValue Sc_Speech_GetSkipKey(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.skip_speech_specific_key); +} + +RuntimeScriptValue Sc_Speech_SetSkipKey(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARSET_PINT(play.skip_speech_specific_key); +} + +RuntimeScriptValue Sc_Speech_GetSkipStyle(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetSkipSpeech); +} + +extern RuntimeScriptValue Sc_SetSkipSpeech(const RuntimeScriptValue *params, int32_t param_count); + +RuntimeScriptValue Sc_Speech_GetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(play.speech_text_align); +} + +RuntimeScriptValue Sc_Speech_SetTextAlignment_Old(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_VARIABLE_VALUE(play.speech_text_align); + play.speech_text_align = ReadScriptAlignment(params[0].IValue); + return RuntimeScriptValue(); +} + +RuntimeScriptValue Sc_Speech_SetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_VARIABLE_VALUE(play.speech_text_align); + play.speech_text_align = (HorAlignment)params[0].IValue; + return RuntimeScriptValue(); +} + +RuntimeScriptValue Sc_Speech_GetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARGET_INT(game.options[OPT_GLOBALTALKANIMSPD]); +} + +RuntimeScriptValue Sc_Speech_SetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) +{ + API_VARSET_PINT(game.options[OPT_GLOBALTALKANIMSPD]); +} + +RuntimeScriptValue Sc_Speech_GetVoiceMode(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(GetVoiceMode); +} + +extern RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count); + +void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) +{ + ccAddExternalStaticFunction("Speech::get_AnimationStopTimeMargin", Sc_Speech_GetAnimationStopTimeMargin); + ccAddExternalStaticFunction("Speech::set_AnimationStopTimeMargin", Sc_Speech_SetAnimationStopTimeMargin); + ccAddExternalStaticFunction("Speech::get_CustomPortraitPlacement", Sc_Speech_GetCustomPortraitPlacement); + ccAddExternalStaticFunction("Speech::set_CustomPortraitPlacement", Sc_Speech_SetCustomPortraitPlacement); + ccAddExternalStaticFunction("Speech::get_DisplayPostTimeMs", Sc_Speech_GetDisplayPostTimeMs); + ccAddExternalStaticFunction("Speech::set_DisplayPostTimeMs", Sc_Speech_SetDisplayPostTimeMs); + ccAddExternalStaticFunction("Speech::get_GlobalSpeechAnimationDelay", Sc_Speech_GetGlobalSpeechAnimationDelay); + ccAddExternalStaticFunction("Speech::set_GlobalSpeechAnimationDelay", Sc_Speech_SetGlobalSpeechAnimationDelay); + ccAddExternalStaticFunction("Speech::get_PortraitXOffset", Sc_Speech_GetPortraitXOffset); + ccAddExternalStaticFunction("Speech::set_PortraitXOffset", Sc_Speech_SetPortraitXOffset); + ccAddExternalStaticFunction("Speech::get_PortraitY", Sc_Speech_GetPortraitY); + ccAddExternalStaticFunction("Speech::set_PortraitY", Sc_Speech_SetPortraitY); + ccAddExternalStaticFunction("Speech::get_SkipKey", Sc_Speech_GetSkipKey); + ccAddExternalStaticFunction("Speech::set_SkipKey", Sc_Speech_SetSkipKey); + ccAddExternalStaticFunction("Speech::get_SkipStyle", Sc_Speech_GetSkipStyle); + ccAddExternalStaticFunction("Speech::set_SkipStyle", Sc_SetSkipSpeech); + ccAddExternalStaticFunction("Speech::get_Style", Sc_Speech_GetStyle); + ccAddExternalStaticFunction("Speech::set_Style", Sc_SetSpeechStyle); + ccAddExternalStaticFunction("Speech::get_TextAlignment", Sc_Speech_GetTextAlignment); + if (base_api < kScriptAPI_v350) + ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment_Old); + else + ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment); + ccAddExternalStaticFunction("Speech::get_UseGlobalSpeechAnimationDelay", Sc_Speech_GetUseGlobalSpeechAnimationDelay); + ccAddExternalStaticFunction("Speech::set_UseGlobalSpeechAnimationDelay", Sc_Speech_SetUseGlobalSpeechAnimationDelay); + ccAddExternalStaticFunction("Speech::get_VoiceMode", Sc_Speech_GetVoiceMode); + ccAddExternalStaticFunction("Speech::set_VoiceMode", Sc_SetVoiceMode); + + /* -- Don't register more unsafe plugin symbols until new plugin interface is designed --*/ +} diff --git a/engines/ags/engine/ac/speech.h b/engines/ags/engine/ac/speech.h new file mode 100644 index 000000000000..8e0d973af758 --- /dev/null +++ b/engines/ags/engine/ac/speech.h @@ -0,0 +1,39 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SPEECH_H +#define __AGS_EE_AC__SPEECH_H + +enum SkipSpeechStyle +{ + kSkipSpeechUndefined = -1, + kSkipSpeechKeyMouseTime = 0, + kSkipSpeechKeyTime = 1, + kSkipSpeechTime = 2, + kSkipSpeechKeyMouse = 3, + kSkipSpeechMouseTime = 4, + kSkipSpeechKey = 5, + kSkipSpeechMouse = 6, + + kSkipSpeechFirst = kSkipSpeechKeyMouseTime, + kSkipSpeechLast = kSkipSpeechMouse +}; + +int user_to_internal_skip_speech(SkipSpeechStyle userval); +SkipSpeechStyle internal_skip_speech_to_user(int internal_val); + +#endif // __AGS_EE_AC__SPEECH_H diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp new file mode 100644 index 000000000000..a14bfc577bea --- /dev/null +++ b/engines/ags/engine/ac/sprite.cpp @@ -0,0 +1,186 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/gamesetupstruct.h" +#include "ac/sprite.h" +#include "ac/system.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "ac/spritecache.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern SpriteCache spriteset; +extern int our_eip, eip_guinum, eip_guiobj; +extern color palette[256]; +extern IGraphicsDriver *gfxDriver; +extern AGSPlatformDriver *platform; + +void get_new_size_for_sprite (int ee, int ww, int hh, int &newwid, int &newhit) +{ + newwid = ww; + newhit = hh; + const SpriteInfo &spinfo = game.SpriteInfos[ee]; + if (!game.AllowRelativeRes() || !spinfo.IsRelativeRes()) + return; + ctx_data_to_game_size(newwid, newhit, spinfo.IsLegacyHiRes()); +} + +// set any alpha-transparent pixels in the image to the appropriate +// RGB mask value so that the blit calls work correctly +void set_rgb_mask_using_alpha_channel(Bitmap *image) +{ + int x, y; + + for (y=0; y < image->GetHeight(); y++) + { + unsigned int*psrc = (unsigned int *)image->GetScanLine(y); + + for (x=0; x < image->GetWidth(); x++) + { + if ((psrc[x] & 0xff000000) == 0x00000000) + psrc[x] = MASK_COLOR_32; + } + } +} + +// from is a 32-bit RGBA image, to is a 15/16/24-bit destination image +Bitmap *remove_alpha_channel(Bitmap *from) +{ + const int game_cd = game.GetColorDepth(); + Bitmap *to = BitmapHelper::CreateBitmap(from->GetWidth(), from->GetHeight(), game_cd); + const int maskcol = to->GetMaskColor(); + int y,x; + unsigned int c,b,g,r; + + if (game_cd == 24) // 32-to-24 + { + for (y=0; y < from->GetHeight(); y++) { + unsigned int*psrc = (unsigned int *)from->GetScanLine(y); + unsigned char*pdest = (unsigned char*)to->GetScanLine(y); + + for (x=0; x < from->GetWidth(); x++) { + c = psrc[x]; + // less than 50% opaque, remove the pixel + if (((c >> 24) & 0x00ff) < 128) + c = maskcol; + + // copy the RGB values across + memcpy(&pdest[x * 3], &c, 3); + } + } + } + else if (game_cd > 8) // 32 to 15 or 16 + { + for (y=0; y < from->GetHeight(); y++) { + unsigned int*psrc = (unsigned int *)from->GetScanLine(y); + unsigned short*pdest = (unsigned short *)to->GetScanLine(y); + + for (x=0; x < from->GetWidth(); x++) { + c = psrc[x]; + // less than 50% opaque, remove the pixel + if (((c >> 24) & 0x00ff) < 128) + pdest[x] = maskcol; + else { + // otherwise, copy it across + r = (c >> 16) & 0x00ff; + g = (c >> 8) & 0x00ff; + b = c & 0x00ff; + pdest[x] = makecol_depth(game_cd, r, g, b); + } + } + } + } + else // 32 to 8-bit game + { // TODO: consider similar to above approach if this becomes a wanted feature + to->Blit(from); + } + return to; +} + +void pre_save_sprite(int ee) { + // not used, we don't save +} + +// these vars are global to help with debugging +Bitmap *tmpdbl, *curspr; +int newwid, newhit; +void initialize_sprite (int ee) { + + if ((ee < 0) || (ee > spriteset.GetSpriteSlotCount())) + quit("initialize_sprite: invalid sprite number"); + + if ((spriteset[ee] == nullptr) && (ee > 0)) { + // replace empty sprites with blue cups, to avoid crashes + spriteset.RemapSpriteToSprite0(ee); + } + else if (spriteset[ee]==nullptr) { + game.SpriteInfos[ee].Width=0; + game.SpriteInfos[ee].Height=0; + } + else { + // stretch sprites to correct resolution + int oldeip = our_eip; + our_eip = 4300; + + if (game.SpriteInfos[ee].Flags & SPF_HADALPHACHANNEL) { + // we stripped the alpha channel out last time, put + // it back so that we can remove it properly again + game.SpriteInfos[ee].Flags |= SPF_ALPHACHANNEL; + } + + curspr = spriteset[ee]; + get_new_size_for_sprite (ee, curspr->GetWidth(), curspr->GetHeight(), newwid, newhit); + + eip_guinum = ee; + eip_guiobj = newwid; + + if ((newwid != curspr->GetWidth()) || (newhit != curspr->GetHeight())) { + tmpdbl = BitmapHelper::CreateTransparentBitmap(newwid,newhit,curspr->GetColorDepth()); + if (tmpdbl == nullptr) + quit("Not enough memory to load sprite graphics"); + tmpdbl->Acquire (); + curspr->Acquire (); + tmpdbl->StretchBlt(curspr,RectWH(0,0,tmpdbl->GetWidth(),tmpdbl->GetHeight()), Common::kBitmap_Transparency); + curspr->Release (); + tmpdbl->Release (); + delete curspr; + spriteset.SubstituteBitmap(ee, tmpdbl); + } + + game.SpriteInfos[ee].Width=spriteset[ee]->GetWidth(); + game.SpriteInfos[ee].Height=spriteset[ee]->GetHeight(); + + spriteset.SubstituteBitmap(ee, PrepareSpriteForUse(spriteset[ee], (game.SpriteInfos[ee].Flags & SPF_ALPHACHANNEL) != 0)); + + if (game.GetColorDepth() < 32) { + game.SpriteInfos[ee].Flags &= ~SPF_ALPHACHANNEL; + // save the fact that it had one for the next time this + // is re-loaded from disk + game.SpriteInfos[ee].Flags |= SPF_HADALPHACHANNEL; + } + + pl_run_plugin_hooks(AGSE_SPRITELOAD, ee); + update_polled_stuff_if_runtime(); + + our_eip = oldeip; + } +} diff --git a/engines/ags/engine/ac/sprite.h b/engines/ags/engine/ac/sprite.h new file mode 100644 index 000000000000..761e5af7bf3b --- /dev/null +++ b/engines/ags/engine/ac/sprite.h @@ -0,0 +1,30 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SPRITE_H +#define __AGS_EE_AC__SPRITE_H + +void get_new_size_for_sprite (int ee, int ww, int hh, int &newwid, int &newhit); +// set any alpha-transparent pixels in the image to the appropriate +// RGB mask value so that the ->Blit calls work correctly +void set_rgb_mask_using_alpha_channel(Common::Bitmap *image); +// from is a 32-bit RGBA image, to is a 15/16/24-bit destination image +Common::Bitmap *remove_alpha_channel(Common::Bitmap *from); +void pre_save_sprite(int ee); +void initialize_sprite (int ee); + +#endif // __AGS_EE_AC__SPRITE_H diff --git a/engines/ags/engine/ac/spritecache_engine.cpp b/engines/ags/engine/ac/spritecache_engine.cpp new file mode 100644 index 000000000000..adb3b03f8d3f --- /dev/null +++ b/engines/ags/engine/ac/spritecache_engine.cpp @@ -0,0 +1,43 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Implementation from sprcache.cpp specific to Engine runtime +// +//============================================================================= + +// Headers, as they are in sprcache.cpp +#ifdef _MANAGED +// ensure this doesn't get compiled to .NET IL +#pragma unmanaged +#pragma warning (disable: 4996 4312) // disable deprecation warnings +#endif + +#include "ac/gamestructdefines.h" +#include "ac/spritecache.h" +#include "util/compress.h" + +//============================================================================= +// Engine-specific implementation split out of sprcache.cpp +//============================================================================= + +void SpriteCache::InitNullSpriteParams(sprkey_t index) +{ + // make it a blue cup, to avoid crashes + _sprInfos[index].Width = _sprInfos[0].Width; + _sprInfos[index].Height = _sprInfos[0].Height; + _spriteData[index].Image = nullptr; + _spriteData[index].Offset = _spriteData[0].Offset; + _spriteData[index].Size = _spriteData[0].Size; + _spriteData[index].Flags = SPRCACHEFLAG_REMAPPED; +} diff --git a/engines/ags/engine/ac/spritelistentry.h b/engines/ags/engine/ac/spritelistentry.h new file mode 100644 index 000000000000..f9b191f2e62d --- /dev/null +++ b/engines/ags/engine/ac/spritelistentry.h @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SPRITELISTENTRY_H +#define __AGS_EE_AC__SPRITELISTENTRY_H + +#include "gfx/ddb.h" + +struct SpriteListEntry +{ + AGS::Engine::IDriverDependantBitmap *bmp; + AGS::Common::Bitmap *pic; + int baseline; + int x,y; + int transparent; + bool takesPriorityIfEqual; + bool hasAlphaChannel; + + SpriteListEntry(); +}; + +#endif // __AGS_EE_AC__SPRITELISTENTRY_H diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp new file mode 100644 index 000000000000..a06b3f6f1c7e --- /dev/null +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -0,0 +1,80 @@ + +#include +#include "ac/statobj/agsstaticobject.h" +#include "ac/game.h" +#include "ac/gamestate.h" + +AGSStaticObject GlobalStaticManager; +StaticGame GameStaticManager; + +const char* AGSStaticObject::GetFieldPtr(const char *address, intptr_t offset) +{ + return address + offset; +} + +void AGSStaticObject::Read(const char *address, intptr_t offset, void *dest, int size) +{ + memcpy(dest, address + offset, size); +} + +uint8_t AGSStaticObject::ReadInt8(const char *address, intptr_t offset) +{ + return *(uint8_t*)(address + offset); +} + +int16_t AGSStaticObject::ReadInt16(const char *address, intptr_t offset) +{ + return *(int16_t*)(address + offset); +} + +int32_t AGSStaticObject::ReadInt32(const char *address, intptr_t offset) +{ + return *(int32_t*)(address + offset); +} + +float AGSStaticObject::ReadFloat(const char *address, intptr_t offset) +{ + return *(float*)(address + offset); +} + +void AGSStaticObject::Write(const char *address, intptr_t offset, void *src, int size) +{ + memcpy((void*)(address + offset), src, size); +} + +void AGSStaticObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) +{ + *(uint8_t*)(address + offset) = val; +} + +void AGSStaticObject::WriteInt16(const char *address, intptr_t offset, int16_t val) +{ + *(int16_t*)(address + offset) = val; +} + +void AGSStaticObject::WriteInt32(const char *address, intptr_t offset, int32_t val) +{ + *(int32_t*)(address + offset) = val; +} + +void AGSStaticObject::WriteFloat(const char *address, intptr_t offset, float val) +{ + *(float*)(address + offset) = val; +} + + +void StaticGame::WriteInt32(const char *address, intptr_t offset, int32_t val) +{ + if (offset == 4 * sizeof(int32_t)) + { // game.debug_mode + set_debug_mode(val != 0); + } + else if (offset == 99 * sizeof(int32_t) || offset == 112 * sizeof(int32_t)) + { // game.text_align, game.speech_text_align + *(int32_t*)(address + offset) = ReadScriptAlignment(val); + } + else + { + *(int32_t*)(address + offset) = val; + } +} diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.h b/engines/ags/engine/ac/statobj/agsstaticobject.h new file mode 100644 index 000000000000..3a1bf4ae2343 --- /dev/null +++ b/engines/ags/engine/ac/statobj/agsstaticobject.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_STATOBJ__AGSSTATICOBJECT_H +#define __AGS_EE_STATOBJ__AGSSTATICOBJECT_H + +#include "ac/statobj/staticobject.h" + +struct AGSStaticObject : public ICCStaticObject { + ~AGSStaticObject() override = default; + + // Legacy support for reading and writing object values by their relative offset + const char* GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; +}; + +// Wrapper around script's "Game" struct, managing access to its variables +struct StaticGame : public AGSStaticObject { + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; +}; + +extern AGSStaticObject GlobalStaticManager; +extern StaticGame GameStaticManager; + +#endif // __AGS_EE_STATOBJ__AGSSTATICOBJECT_H diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp new file mode 100644 index 000000000000..004ff29f9147 --- /dev/null +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -0,0 +1,196 @@ + +#include +#include "ac/statobj/staticarray.h" +#include "ac/dynobj/cc_dynamicobject.h" + +void StaticArray::Create(int elem_legacy_size, int elem_real_size, int elem_count) +{ + _staticMgr = nullptr; + _dynamicMgr = nullptr; + _elemLegacySize = elem_legacy_size; + _elemRealSize = elem_real_size; + _elemCount = elem_count; +} + +void StaticArray::Create(ICCStaticObject *stcmgr, int elem_legacy_size, int elem_real_size, int elem_count) +{ + _staticMgr = stcmgr; + _dynamicMgr = nullptr; + _elemLegacySize = elem_legacy_size; + _elemRealSize = elem_real_size; + _elemCount = elem_count; +} + +void StaticArray::Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int elem_real_size, int elem_count) +{ + _staticMgr = nullptr; + _dynamicMgr = dynmgr; + _elemLegacySize = elem_legacy_size; + _elemRealSize = elem_real_size; + _elemCount = elem_count; +} + +const char *StaticArray::GetElementPtr(const char *address, intptr_t legacy_offset) +{ + return address + (legacy_offset / _elemLegacySize) * _elemRealSize; +} + +const char* StaticArray::GetFieldPtr(const char *address, intptr_t offset) +{ + return GetElementPtr(address, offset); +} + +void StaticArray::Read(const char *address, intptr_t offset, void *dest, int size) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->Read(el_ptr, offset % _elemLegacySize, dest, size); + } + else if (_dynamicMgr) + { + return _dynamicMgr->Read(el_ptr, offset % _elemLegacySize, dest, size); + } + memcpy(dest, el_ptr + offset % _elemLegacySize, size); +} + +uint8_t StaticArray::ReadInt8(const char *address, intptr_t offset) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->ReadInt8(el_ptr, offset % _elemLegacySize); + } + else if (_dynamicMgr) + { + return _dynamicMgr->ReadInt8(el_ptr, offset % _elemLegacySize); + } + return *(uint8_t*)(el_ptr + offset % _elemLegacySize); +} + +int16_t StaticArray::ReadInt16(const char *address, intptr_t offset) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->ReadInt16(el_ptr, offset % _elemLegacySize); + } + else if (_dynamicMgr) + { + return _dynamicMgr->ReadInt16(el_ptr, offset % _elemLegacySize); + } + return *(uint16_t*)(el_ptr + offset % _elemLegacySize); +} + +int32_t StaticArray::ReadInt32(const char *address, intptr_t offset) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->ReadInt32(el_ptr, offset % _elemLegacySize); + } + else if (_dynamicMgr) + { + return _dynamicMgr->ReadInt32(el_ptr, offset % _elemLegacySize); + } + return *(uint32_t*)(el_ptr + offset % _elemLegacySize); +} + +float StaticArray::ReadFloat(const char *address, intptr_t offset) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->ReadFloat(el_ptr, offset % _elemLegacySize); + } + else if (_dynamicMgr) + { + return _dynamicMgr->ReadFloat(el_ptr, offset % _elemLegacySize); + } + return *(float*)(el_ptr + offset % _elemLegacySize); +} + +void StaticArray::Write(const char *address, intptr_t offset, void *src, int size) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->Write(el_ptr, offset % _elemLegacySize, src, size); + } + else if (_dynamicMgr) + { + return _dynamicMgr->Write(el_ptr, offset % _elemLegacySize, src, size); + } + else + { + memcpy((void*)(el_ptr + offset % _elemLegacySize), src, size); + } +} + +void StaticArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->WriteInt8(el_ptr, offset % _elemLegacySize, val); + } + else if (_dynamicMgr) + { + return _dynamicMgr->WriteInt8(el_ptr, offset % _elemLegacySize, val); + } + else + { + *(uint8_t*)(el_ptr + offset % _elemLegacySize) = val; + } +} + +void StaticArray::WriteInt16(const char *address, intptr_t offset, int16_t val) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->WriteInt16(el_ptr, offset % _elemLegacySize, val); + } + else if (_dynamicMgr) + { + return _dynamicMgr->WriteInt16(el_ptr, offset % _elemLegacySize, val); + } + else + { + *(uint16_t*)(el_ptr + offset % _elemLegacySize) = val; + } +} + +void StaticArray::WriteInt32(const char *address, intptr_t offset, int32_t val) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->WriteInt32(el_ptr, offset % _elemLegacySize, val); + } + else if (_dynamicMgr) + { + return _dynamicMgr->WriteInt32(el_ptr, offset % _elemLegacySize, val); + } + else + { + *(uint32_t*)(el_ptr + offset % _elemLegacySize) = val; + } +} + +void StaticArray::WriteFloat(const char *address, intptr_t offset, float val) +{ + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) + { + return _staticMgr->WriteFloat(el_ptr, offset % _elemLegacySize, val); + } + else if (_dynamicMgr) + { + return _dynamicMgr->WriteFloat(el_ptr, offset % _elemLegacySize, val); + } + else + { + *(float*)(el_ptr + offset % _elemLegacySize) = val; + } +} diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h new file mode 100644 index 000000000000..4c25d3657dd9 --- /dev/null +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -0,0 +1,64 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_STATOBJ__STATICARRAY_H +#define __AGS_EE_STATOBJ__STATICARRAY_H + +#include "ac/statobj/staticobject.h" + +struct ICCDynamicObject; + +struct StaticArray : public ICCStaticObject { +public: + ~StaticArray() override = default; + + void Create(int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); + void Create(ICCStaticObject *stcmgr, int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); + void Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); + + inline ICCStaticObject *GetStaticManager() const + { + return _staticMgr; + } + inline ICCDynamicObject *GetDynamicManager() const + { + return _dynamicMgr; + } + // Legacy support for reading and writing object values by their relative offset + virtual const char *GetElementPtr(const char *address, intptr_t legacy_offset); + + const char* GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; + +private: + ICCStaticObject *_staticMgr; + ICCDynamicObject *_dynamicMgr; + int _elemLegacySize; + int _elemRealSize; + int _elemCount; +}; + +#endif // __AGS_EE_STATOBJ__STATICOBJECT_H diff --git a/engines/ags/engine/ac/statobj/staticobject.h b/engines/ags/engine/ac/statobj/staticobject.h new file mode 100644 index 000000000000..6c45a4172621 --- /dev/null +++ b/engines/ags/engine/ac/statobj/staticobject.h @@ -0,0 +1,42 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// A stub class for "managing" static global objects exported to script. +// This may be temporary solution (oh no, not again :P) that could be +// replaced by the use of dynamic objects in the future. +// +//============================================================================= +#ifndef __AGS_EE_STATOBJ__STATICOBJECT_H +#define __AGS_EE_STATOBJ__STATICOBJECT_H + +#include "core/types.h" + +struct ICCStaticObject { + virtual ~ICCStaticObject() = default; + + // Legacy support for reading and writing object values by their relative offset + virtual const char* GetFieldPtr(const char *address, intptr_t offset) = 0; + virtual void Read(const char *address, intptr_t offset, void *dest, int size)= 0; + virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; + virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; + virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; + virtual float ReadFloat(const char *address, intptr_t offset) = 0; + virtual void Write(const char *address, intptr_t offset, void *src, int size)= 0; + virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; + virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; + virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; + virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; +}; + +#endif // __AGS_EE_STATOBJ__STATICOBJECT_H diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp new file mode 100644 index 000000000000..0c1068ffea29 --- /dev/null +++ b/engines/ags/engine/ac/string.cpp @@ -0,0 +1,491 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/string.h" +#include "ac/common.h" +#include "ac/display.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_translation.h" +#include "ac/runtime_defines.h" +#include "ac/dynobj/scriptstring.h" +#include "font/fonts.h" +#include "debug/debug_log.h" +#include "script/runtimescriptvalue.h" +#include "util/string_compat.h" + +extern GameSetupStruct game; +extern GameState play; +extern int longestline; +extern ScriptString myScriptStringImpl; + +int String_IsNullOrEmpty(const char *thisString) +{ + if ((thisString == nullptr) || (thisString[0] == 0)) + return 1; + + return 0; +} + +const char* String_Copy(const char *srcString) { + return CreateNewScriptString(srcString); +} + +const char* String_Append(const char *thisString, const char *extrabit) { + char *buffer = (char*)malloc(strlen(thisString) + strlen(extrabit) + 1); + strcpy(buffer, thisString); + strcat(buffer, extrabit); + return CreateNewScriptString(buffer, false); +} + +const char* String_AppendChar(const char *thisString, char extraOne) { + char *buffer = (char*)malloc(strlen(thisString) + 2); + sprintf(buffer, "%s%c", thisString, extraOne); + return CreateNewScriptString(buffer, false); +} + +const char* String_ReplaceCharAt(const char *thisString, int index, char newChar) { + if ((index < 0) || (index >= (int)strlen(thisString))) + quit("!String.ReplaceCharAt: index outside range of string"); + + char *buffer = (char*)malloc(strlen(thisString) + 1); + strcpy(buffer, thisString); + buffer[index] = newChar; + return CreateNewScriptString(buffer, false); +} + +const char* String_Truncate(const char *thisString, int length) { + if (length < 0) + quit("!String.Truncate: invalid length"); + + if (length >= (int)strlen(thisString)) + { + return thisString; + } + + char *buffer = (char*)malloc(length + 1); + strncpy(buffer, thisString, length); + buffer[length] = 0; + return CreateNewScriptString(buffer, false); +} + +const char* String_Substring(const char *thisString, int index, int length) { + if (length < 0) + quit("!String.Substring: invalid length"); + if ((index < 0) || (index > (int)strlen(thisString))) + quit("!String.Substring: invalid index"); + + char *buffer = (char*)malloc(length + 1); + strncpy(buffer, &thisString[index], length); + buffer[length] = 0; + return CreateNewScriptString(buffer, false); +} + +int String_CompareTo(const char *thisString, const char *otherString, bool caseSensitive) { + + if (caseSensitive) { + return strcmp(thisString, otherString); + } + else { + return ags_stricmp(thisString, otherString); + } +} + +int String_StartsWith(const char *thisString, const char *checkForString, bool caseSensitive) { + + if (caseSensitive) { + return (strncmp(thisString, checkForString, strlen(checkForString)) == 0) ? 1 : 0; + } + else { + return (ags_strnicmp(thisString, checkForString, strlen(checkForString)) == 0) ? 1 : 0; + } +} + +int String_EndsWith(const char *thisString, const char *checkForString, bool caseSensitive) { + + int checkAtOffset = strlen(thisString) - strlen(checkForString); + + if (checkAtOffset < 0) + { + return 0; + } + + if (caseSensitive) + { + return (strcmp(&thisString[checkAtOffset], checkForString) == 0) ? 1 : 0; + } + else + { + return (ags_stricmp(&thisString[checkAtOffset], checkForString) == 0) ? 1 : 0; + } +} + +const char* String_Replace(const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive) +{ + char resultBuffer[STD_BUFFER_SIZE] = ""; + int thisStringLen = (int)strlen(thisString); + int outputSize = 0; + for (int i = 0; i < thisStringLen; i++) + { + bool matchHere = false; + if (caseSensitive) + { + matchHere = (strncmp(&thisString[i], lookForText, strlen(lookForText)) == 0); + } + else + { + matchHere = (ags_strnicmp(&thisString[i], lookForText, strlen(lookForText)) == 0); + } + + if (matchHere) + { + strcpy(&resultBuffer[outputSize], replaceWithText); + outputSize += strlen(replaceWithText); + i += strlen(lookForText) - 1; + } + else + { + resultBuffer[outputSize] = thisString[i]; + outputSize++; + } + } + + resultBuffer[outputSize] = 0; + + return CreateNewScriptString(resultBuffer, true); +} + +const char* String_LowerCase(const char *thisString) { + char *buffer = (char*)malloc(strlen(thisString) + 1); + strcpy(buffer, thisString); + ags_strlwr(buffer); + return CreateNewScriptString(buffer, false); +} + +const char* String_UpperCase(const char *thisString) { + char *buffer = (char*)malloc(strlen(thisString) + 1); + strcpy(buffer, thisString); + ags_strupr(buffer); + return CreateNewScriptString(buffer, false); +} + +int String_GetChars(const char *texx, int index) { + if ((index < 0) || (index >= (int)strlen(texx))) + return 0; + return texx[index]; +} + +int StringToInt(const char*stino) { + return atoi(stino); +} + +int StrContains (const char *s1, const char *s2) { + VALIDATE_STRING (s1); + VALIDATE_STRING (s2); + char *tempbuf1 = (char*)malloc(strlen(s1) + 1); + char *tempbuf2 = (char*)malloc(strlen(s2) + 1); + strcpy(tempbuf1, s1); + strcpy(tempbuf2, s2); + ags_strlwr(tempbuf1); + ags_strlwr(tempbuf2); + + char *offs = strstr (tempbuf1, tempbuf2); + free(tempbuf1); + free(tempbuf2); + + if (offs == nullptr) + return -1; + + return (offs - tempbuf1); +} + +//============================================================================= + +const char *CreateNewScriptString(const char *fromText, bool reAllocate) { + return (const char*)CreateNewScriptStringObj(fromText, reAllocate).second; +} + +DynObjectRef CreateNewScriptStringObj(const char *fromText, bool reAllocate) +{ + ScriptString *str; + if (reAllocate) { + str = new ScriptString(fromText); + } + else { + str = new ScriptString(); + str->text = (char*)fromText; + } + void *obj_ptr = str->text; + int32_t handle = ccRegisterManagedObject(obj_ptr, str); + if (handle == 0) + { + delete str; + return DynObjectRef(0, nullptr); + } + return DynObjectRef(handle, obj_ptr); +} + +size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, int fonnt, size_t max_lines) { + if (fonnt == -1) + fonnt = play.normal_font; + + // char sofar[100]; + if (todis[0]=='&') { + while ((todis[0]!=' ') & (todis[0]!=0)) todis++; + if (todis[0]==' ') todis++; + } + lines.Reset(); + longestline=0; + + // Don't attempt to display anything if the width is tiny + if (wii < 3) + return 0; + + int line_length; + + split_lines(todis, lines, wii, fonnt, max_lines); + + // Right-to-left just means reverse the text then + // write it as normal + if (game.options[OPT_RIGHTLEFTWRITE]) + for (size_t rr = 0; rr < lines.Count(); rr++) { + lines[rr].Reverse(); + line_length = wgettextwidth_compensate(lines[rr], fonnt); + if (line_length > longestline) + longestline = line_length; + } + else + for (size_t rr = 0; rr < lines.Count(); rr++) { + line_length = wgettextwidth_compensate(lines[rr], fonnt); + if (line_length > longestline) + longestline = line_length; + } + return lines.Count(); +} + +int MAXSTRLEN = MAX_MAXSTRLEN; +void check_strlen(char*ptt) { + MAXSTRLEN = MAX_MAXSTRLEN; + long charstart = (long)&game.chars[0]; + long charend = charstart + sizeof(CharacterInfo)*game.numcharacters; + if (((long)&ptt[0] >= charstart) && ((long)&ptt[0] <= charend)) + MAXSTRLEN=30; +} + +/*void GetLanguageString(int indxx,char*buffr) { +VALIDATE_STRING(buffr); +char*bptr=get_language_text(indxx); +if (bptr==NULL) strcpy(buffr,"[language string error]"); +else strncpy(buffr,bptr,199); +buffr[199]=0; +}*/ + +void my_strncpy(char *dest, const char *src, int len) { + // the normal strncpy pads out the string with zeros up to the + // max length -- we don't want that + if (strlen(src) >= (unsigned)len) { + strncpy(dest, src, len); + dest[len] = 0; + } + else + strcpy(dest, src); +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/math.h" + +// int (const char *thisString) +RuntimeScriptValue Sc_String_IsNullOrEmpty(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT_POBJ(String_IsNullOrEmpty, const char); +} + +// const char* (const char *thisString, const char *extrabit) +RuntimeScriptValue Sc_String_Append(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_POBJ(const char, const char, myScriptStringImpl, String_Append, const char); +} + +// const char* (const char *thisString, char extraOne) +RuntimeScriptValue Sc_String_AppendChar(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_AppendChar); +} + +// int (const char *thisString, const char *otherString, bool caseSensitive) +RuntimeScriptValue Sc_String_CompareTo(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ_PBOOL(const char, String_CompareTo, const char); +} + +// int (const char *s1, const char *s2) +RuntimeScriptValue Sc_StrContains(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ(const char, StrContains, const char); +} + +// const char* (const char *srcString) +RuntimeScriptValue Sc_String_Copy(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_Copy); +} + +// int (const char *thisString, const char *checkForString, bool caseSensitive) +RuntimeScriptValue Sc_String_EndsWith(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ_PBOOL(const char, String_EndsWith, const char); +} + +// const char* (const char *texx, ...) +RuntimeScriptValue Sc_String_Format(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(String_Format, 1); + return RuntimeScriptValue().SetDynamicObject((void*)CreateNewScriptString(scsf_buffer), &myScriptStringImpl); +} + +// const char* (const char *thisString) +RuntimeScriptValue Sc_String_LowerCase(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_LowerCase); +} + +// const char* (const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive) +RuntimeScriptValue Sc_String_Replace(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_POBJ2_PBOOL(const char, const char, myScriptStringImpl, String_Replace, const char, const char); +} + +// const char* (const char *thisString, int index, char newChar) +RuntimeScriptValue Sc_String_ReplaceCharAt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_ReplaceCharAt); +} + +// int (const char *thisString, const char *checkForString, bool caseSensitive) +RuntimeScriptValue Sc_String_StartsWith(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_POBJ_PBOOL(const char, String_StartsWith, const char); +} + +// const char* (const char *thisString, int index, int length) +RuntimeScriptValue Sc_String_Substring(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_Substring); +} + +// const char* (const char *thisString, int length) +RuntimeScriptValue Sc_String_Truncate(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_Truncate); +} + +// const char* (const char *thisString) +RuntimeScriptValue Sc_String_UpperCase(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_UpperCase); +} + +// FLOAT_RETURN_TYPE (const char *theString); +RuntimeScriptValue Sc_StringToFloat(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_FLOAT(const char, StringToFloat); +} + +// int (char*stino) +RuntimeScriptValue Sc_StringToInt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(const char, StringToInt); +} + +// int (const char *texx, int index) +RuntimeScriptValue Sc_String_GetChars(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT_PINT(const char, String_GetChars); +} + +RuntimeScriptValue Sc_strlen(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + ASSERT_SELF(strlen); + return RuntimeScriptValue().SetInt32(strlen((const char*)self)); +} + +//============================================================================= +// +// Exclusive API for Plugins +// +//============================================================================= + +// const char* (const char *texx, ...) +const char *ScPl_String_Format(const char *texx, ...) +{ + API_PLUGIN_SCRIPT_SPRINTF(texx); + return CreateNewScriptString(scsf_buffer); +} + + +void RegisterStringAPI() +{ + ccAddExternalStaticFunction("String::IsNullOrEmpty^1", Sc_String_IsNullOrEmpty); + ccAddExternalObjectFunction("String::Append^1", Sc_String_Append); + ccAddExternalObjectFunction("String::AppendChar^1", Sc_String_AppendChar); + ccAddExternalObjectFunction("String::CompareTo^2", Sc_String_CompareTo); + ccAddExternalObjectFunction("String::Contains^1", Sc_StrContains); + ccAddExternalObjectFunction("String::Copy^0", Sc_String_Copy); + ccAddExternalObjectFunction("String::EndsWith^2", Sc_String_EndsWith); + ccAddExternalStaticFunction("String::Format^101", Sc_String_Format); + ccAddExternalObjectFunction("String::IndexOf^1", Sc_StrContains); + ccAddExternalObjectFunction("String::LowerCase^0", Sc_String_LowerCase); + ccAddExternalObjectFunction("String::Replace^3", Sc_String_Replace); + ccAddExternalObjectFunction("String::ReplaceCharAt^2", Sc_String_ReplaceCharAt); + ccAddExternalObjectFunction("String::StartsWith^2", Sc_String_StartsWith); + ccAddExternalObjectFunction("String::Substring^2", Sc_String_Substring); + ccAddExternalObjectFunction("String::Truncate^1", Sc_String_Truncate); + ccAddExternalObjectFunction("String::UpperCase^0", Sc_String_UpperCase); + ccAddExternalObjectFunction("String::get_AsFloat", Sc_StringToFloat); + ccAddExternalObjectFunction("String::get_AsInt", Sc_StringToInt); + ccAddExternalObjectFunction("String::geti_Chars", Sc_String_GetChars); + ccAddExternalObjectFunction("String::get_Length", Sc_strlen); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("String::IsNullOrEmpty^1", (void*)String_IsNullOrEmpty); + ccAddExternalFunctionForPlugin("String::Append^1", (void*)String_Append); + ccAddExternalFunctionForPlugin("String::AppendChar^1", (void*)String_AppendChar); + ccAddExternalFunctionForPlugin("String::CompareTo^2", (void*)String_CompareTo); + ccAddExternalFunctionForPlugin("String::Contains^1", (void*)StrContains); + ccAddExternalFunctionForPlugin("String::Copy^0", (void*)String_Copy); + ccAddExternalFunctionForPlugin("String::EndsWith^2", (void*)String_EndsWith); + ccAddExternalFunctionForPlugin("String::Format^101", (void*)ScPl_String_Format); + ccAddExternalFunctionForPlugin("String::IndexOf^1", (void*)StrContains); + ccAddExternalFunctionForPlugin("String::LowerCase^0", (void*)String_LowerCase); + ccAddExternalFunctionForPlugin("String::Replace^3", (void*)String_Replace); + ccAddExternalFunctionForPlugin("String::ReplaceCharAt^2", (void*)String_ReplaceCharAt); + ccAddExternalFunctionForPlugin("String::StartsWith^2", (void*)String_StartsWith); + ccAddExternalFunctionForPlugin("String::Substring^2", (void*)String_Substring); + ccAddExternalFunctionForPlugin("String::Truncate^1", (void*)String_Truncate); + ccAddExternalFunctionForPlugin("String::UpperCase^0", (void*)String_UpperCase); + ccAddExternalFunctionForPlugin("String::get_AsFloat", (void*)StringToFloat); + ccAddExternalFunctionForPlugin("String::get_AsInt", (void*)StringToInt); + ccAddExternalFunctionForPlugin("String::geti_Chars", (void*)String_GetChars); + ccAddExternalFunctionForPlugin("String::get_Length", (void*)strlen); +} diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h new file mode 100644 index 000000000000..0ae6114d2f6a --- /dev/null +++ b/engines/ags/engine/ac/string.h @@ -0,0 +1,56 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__STRING_H +#define __AGS_EE_AC__STRING_H + +#include +#include "ac/dynobj/cc_dynamicobject.h" + +// Check that a supplied buffer from a text script function was not null +#define VALIDATE_STRING(strin) if ((unsigned long)strin <= 4096) quit("!String argument was null: make sure you pass a string, not an int, as a buffer") + +int String_IsNullOrEmpty(const char *thisString); +const char* String_Copy(const char *srcString); +const char* String_Append(const char *thisString, const char *extrabit); +const char* String_AppendChar(const char *thisString, char extraOne); +const char* String_ReplaceCharAt(const char *thisString, int index, char newChar); +const char* String_Truncate(const char *thisString, int length); +const char* String_Substring(const char *thisString, int index, int length); +int String_CompareTo(const char *thisString, const char *otherString, bool caseSensitive); +int String_StartsWith(const char *thisString, const char *checkForString, bool caseSensitive); +int String_EndsWith(const char *thisString, const char *checkForString, bool caseSensitive); +const char* String_Replace(const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive); +const char* String_LowerCase(const char *thisString); +const char* String_UpperCase(const char *thisString); +int String_GetChars(const char *texx, int index); +int StringToInt(const char*stino); +int StrContains (const char *s1, const char *s2); + +//============================================================================= + +const char* CreateNewScriptString(const char *fromText, bool reAllocate = true); +DynObjectRef CreateNewScriptStringObj(const char *fromText, bool reAllocate = true); +class SplitLines; +// Break up the text into lines restricted by the given width; +// returns number of lines, or 0 if text cannot be split well to fit in this width. +// Does additional processing, like removal of voice-over tags and text reversal if right-to-left text display is on. +size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, int fonnt, size_t max_lines = -1); +void check_strlen(char*ptt); +void my_strncpy(char *dest, const char *src, int len); + +#endif // __AGS_EE_AC__STRING_H diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp new file mode 100644 index 000000000000..ddbe0d5105e8 --- /dev/null +++ b/engines/ags/engine/ac/sys_events.cpp @@ -0,0 +1,206 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/keycode.h" +#include "ac/mouse.h" +#include "ac/sys_events.h" +#include "device/mousew32.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/timer.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameState play; + +extern volatile unsigned long globalTimerCounter; +extern int pluginSimulatedClick; +extern int displayed_room; +extern char check_dynamic_sprites_at_exit; + +extern void domouse(int str); +extern int mgetbutton(); +extern int misbuttondown(int buno); + +int mouse_z_was = 0; + +int ags_kbhit () { + return keypressed(); +} + +int ags_iskeypressed (int keycode) { + if (keycode >= 0 && keycode < __allegro_KEY_MAX) + { + return key[keycode] != 0; + } + return 0; +} + +int ags_misbuttondown (int but) { + return misbuttondown(but); +} + +int ags_mgetbutton() { + int result; + + if (pluginSimulatedClick > NONE) { + result = pluginSimulatedClick; + pluginSimulatedClick = NONE; + } + else { + result = mgetbutton(); + } + return result; +} + +void ags_domouse (int what) { + // do mouse is "update the mouse x,y and also the cursor position", unless DOMOUSE_NOCURSOR is set. + if (what == DOMOUSE_NOCURSOR) + mgetgraphpos(); + else + domouse(what); +} + +int ags_check_mouse_wheel () { + int result = 0; + if ((mouse_z != mouse_z_was) && (game.options[OPT_MOUSEWHEEL] != 0)) { + if (mouse_z > mouse_z_was) + result = 1; + else + result = -1; + mouse_z_was = mouse_z; + } + return result; +} + +int ags_getch() { + const int read_key_value = readkey(); + int gott = read_key_value; + const int scancode = ((gott >> 8) & 0x00ff); + const int ascii = (gott & 0x00ff); + + bool is_extended = (ascii == EXTENDED_KEY_CODE); + // On macos, the extended keycode is the ascii character '?' or '\0' if alt-key + // so check it's not actually the character '?' + #if AGS_PLATFORM_OS_MACOS && ! AGS_PLATFORM_OS_IOS + is_extended = is_extended || ((ascii == EXTENDED_KEY_CODE_MACOS) && (scancode != __allegro_KEY_SLASH)); + #endif + + /* char message[200]; + sprintf(message, "Scancode: %04X", gott); + Debug::Printf(message);*/ + + /*if ((scancode >= KEY_0_PAD) && (scancode <= KEY_9_PAD)) { + // fix numeric pad keys if numlock is off (allegro 4.2 changed this behaviour) + if ((key_shifts & KB_NUMLOCK_FLAG) == 0) + gott = (gott & 0xff00) | EXTENDED_KEY_CODE; + }*/ + + if (gott == READKEY_CODE_ALT_TAB) + { + // Alt+Tab, it gets stuck down unless we do this + gott = AGS_KEYCODE_ALT_TAB; + } + #if AGS_PLATFORM_OS_MACOS + else if (scancode == __allegro_KEY_BACKSPACE) + { + gott = eAGSKeyCodeBackspace; + } + #endif + else if (is_extended) + { + + // I believe we rely on a lot of keys being converted to ASCII, which is why + // the complete scan code list is not here. + + switch(scancode) + { + case __allegro_KEY_F1 : gott = eAGSKeyCodeF1 ; break; + case __allegro_KEY_F2 : gott = eAGSKeyCodeF2 ; break; + case __allegro_KEY_F3 : gott = eAGSKeyCodeF3 ; break; + case __allegro_KEY_F4 : gott = eAGSKeyCodeF4 ; break; + case __allegro_KEY_F5 : gott = eAGSKeyCodeF5 ; break; + case __allegro_KEY_F6 : gott = eAGSKeyCodeF6 ; break; + case __allegro_KEY_F7 : gott = eAGSKeyCodeF7 ; break; + case __allegro_KEY_F8 : gott = eAGSKeyCodeF8 ; break; + case __allegro_KEY_F9 : gott = eAGSKeyCodeF9 ; break; + case __allegro_KEY_F10 : gott = eAGSKeyCodeF10 ; break; + case __allegro_KEY_F11 : gott = eAGSKeyCodeF11 ; break; + case __allegro_KEY_F12 : gott = eAGSKeyCodeF12 ; break; + + case __allegro_KEY_INSERT : gott = eAGSKeyCodeInsert ; break; + case __allegro_KEY_DEL : gott = eAGSKeyCodeDelete ; break; + case __allegro_KEY_HOME : gott = eAGSKeyCodeHome ; break; + case __allegro_KEY_END : gott = eAGSKeyCodeEnd ; break; + case __allegro_KEY_PGUP : gott = eAGSKeyCodePageUp ; break; + case __allegro_KEY_PGDN : gott = eAGSKeyCodePageDown ; break; + case __allegro_KEY_LEFT : gott = eAGSKeyCodeLeftArrow ; break; + case __allegro_KEY_RIGHT : gott = eAGSKeyCodeRightArrow ; break; + case __allegro_KEY_UP : gott = eAGSKeyCodeUpArrow ; break; + case __allegro_KEY_DOWN : gott = eAGSKeyCodeDownArrow ; break; + + case __allegro_KEY_0_PAD : gott = eAGSKeyCodeInsert ; break; + case __allegro_KEY_1_PAD : gott = eAGSKeyCodeEnd ; break; + case __allegro_KEY_2_PAD : gott = eAGSKeyCodeDownArrow ; break; + case __allegro_KEY_3_PAD : gott = eAGSKeyCodePageDown ; break; + case __allegro_KEY_4_PAD : gott = eAGSKeyCodeLeftArrow ; break; + case __allegro_KEY_5_PAD : gott = eAGSKeyCodeNumPad5 ; break; + case __allegro_KEY_6_PAD : gott = eAGSKeyCodeRightArrow ; break; + case __allegro_KEY_7_PAD : gott = eAGSKeyCodeHome ; break; + case __allegro_KEY_8_PAD : gott = eAGSKeyCodeUpArrow ; break; + case __allegro_KEY_9_PAD : gott = eAGSKeyCodePageUp ; break; + case __allegro_KEY_DEL_PAD : gott = eAGSKeyCodeDelete ; break; + + default: + // no meaningful mappings + // this is how we accidentally got the alt-key mappings + gott = scancode + AGS_EXT_KEY_SHIFT; + } + } + else + { + // this includes ascii characters and ctrl-A-Z + gott = ascii; + } + + // Alt+X, abort (but only once game is loaded) + if ((gott == play.abort_key) && (displayed_room >= 0)) { + check_dynamic_sprites_at_exit = 0; + quit("!|"); + } + + //sprintf(message, "Keypress: %d", gott); + //Debug::Printf(message); + + return gott; +} + +void ags_clear_input_buffer() +{ + while (ags_kbhit()) ags_getch(); + while (mgetbutton() != NONE); +} + +void ags_wait_until_keypress() +{ + while (!ags_kbhit()) { + platform->YieldCPU(); + } + ags_getch(); +} diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h new file mode 100644 index 000000000000..bc7dfee9d05c --- /dev/null +++ b/engines/ags/engine/ac/sys_events.h @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SYS_EVENTS_H +#define __AGS_EE_AC__SYS_EVENTS_H + +int ags_getch (); +int ags_kbhit (); +int ags_iskeypressed (int keycode); + +int ags_misbuttondown (int but); +int ags_mgetbutton(); +void ags_domouse (int what); +int ags_check_mouse_wheel (); + +// Clears buffered keypresses and mouse clicks, if any +void ags_clear_input_buffer(); +// Halts execution until any user input +// TODO: seriously not a good design, replace with event listening +void ags_wait_until_keypress(); + +#endif // __AGS_EE_AC__SYS_EVENTS_H diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp new file mode 100644 index 000000000000..c03004c5b775 --- /dev/null +++ b/engines/ags/engine/ac/system.cpp @@ -0,0 +1,467 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/mouse.h" +#include "ac/string.h" +#include "ac/system.h" +#include "ac/dynobj/scriptsystem.h" +#include "debug/debug_log.h" +#include "debug/out.h" +#include "main/engine.h" +#include "main/main.h" +#include "gfx/graphicsdriver.h" +#include "ac/dynobj/cc_audiochannel.h" +#include "main/graphics_mode.h" +#include "ac/global_debug.h" +#include "ac/global_translation.h" +#include "media/audio/audio_system.h" +#include "util/string_compat.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameSetup usetup; +extern GameState play; +extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; +extern ScriptSystem scsystem; +extern IGraphicsDriver *gfxDriver; +extern CCAudioChannel ccDynamicAudio; +extern volatile bool switched_away; + +bool System_HasInputFocus() +{ + return !switched_away; +} + +int System_GetColorDepth() { + return scsystem.coldepth; +} + +int System_GetOS() { + return scsystem.os; +} + +// [IKM] 2014-09-21 +// IMPORTANT NOTE on System.ScreenWidth and System.ScreenHeight: +// It appears that in AGS these properties were not defining actual window size +// in pixels, but rather game frame size, which could include black borders, +// in 'native' (unscaled) pixels. This was due the specifics of how graphics +// modes were implemented in previous versions. +// +// Quote from the old manual: +// "Returns the actual screen width that the game is running at. If a graphic +// filter is in use, the resolution returned will be that before any +// stretching by the filter has been applied. If widescreen side borders are +// enabled, the screen width reported will include the size of these borders." +// +// The key words are "the resolution returned will be that BEFORE any +// stretching by the filter has been applied". +// +// Since now the letterbox and pillarbox borders are handled by graphics +// renderer and are not part of the game anymore, these properties should +// return strictly native game size. This is required for backwards +// compatibility. +// +int System_GetScreenWidth() { + return game.GetGameRes().Width; +} + +int System_GetScreenHeight() { + return game.GetGameRes().Height; +} + +int System_GetViewportHeight() { + return game_to_data_coord(play.GetMainViewport().GetHeight()); +} + +int System_GetViewportWidth() { + return game_to_data_coord(play.GetMainViewport().GetWidth()); +} + +const char *System_GetVersion() { + return CreateNewScriptString(EngineVersion.LongString); +} + +int System_GetHardwareAcceleration() +{ + return gfxDriver->HasAcceleratedTransform() ? 1 : 0; +} + +int System_GetNumLock() +{ + return (key_shifts & KB_NUMLOCK_FLAG) ? 1 : 0; +} + +int System_GetCapsLock() +{ + return (key_shifts & KB_CAPSLOCK_FLAG) ? 1 : 0; +} + +int System_GetScrollLock() +{ + return (key_shifts & KB_SCROLOCK_FLAG) ? 1 : 0; +} + +void System_SetNumLock(int newValue) +{ + // doesn't work ... maybe allegro doesn't implement this on windows + int ledState = key_shifts & (KB_SCROLOCK_FLAG | KB_CAPSLOCK_FLAG); + if (newValue) + { + ledState |= KB_NUMLOCK_FLAG; + } + set_leds(ledState); +} + +int System_GetVsync() { + return scsystem.vsync; +} + +void System_SetVsync(int newValue) { + if(ags_stricmp(gfxDriver->GetDriverID(), "D3D9") != 0) + scsystem.vsync = newValue; +} + +int System_GetWindowed() { + return scsystem.windowed; +} + +void System_SetWindowed(int windowed) +{ + if (windowed != scsystem.windowed) + engine_try_switch_windowed_gfxmode(); +} + +int System_GetSupportsGammaControl() { + return gfxDriver->SupportsGammaControl(); +} + +int System_GetGamma() { + return play.gamma_adjustment; +} + +void System_SetGamma(int newValue) { + if ((newValue < 0) || (newValue > 200)) + quitprintf("!System.Gamma: value must be between 0-200 (not %d)", newValue); + + if (play.gamma_adjustment != newValue) { + debug_script_log("Gamma control set to %d", newValue); + play.gamma_adjustment = newValue; + + if (gfxDriver->SupportsGammaControl()) + gfxDriver->SetGamma(newValue); + } +} + +int System_GetAudioChannelCount() +{ + return MAX_SOUND_CHANNELS; +} + +ScriptAudioChannel* System_GetAudioChannels(int index) +{ + if ((index < 0) || (index >= MAX_SOUND_CHANNELS)) + quit("!System.AudioChannels: invalid sound channel index"); + + return &scrAudioChannel[index]; +} + +int System_GetVolume() +{ + return play.digital_master_volume; +} + +void System_SetVolume(int newvol) +{ + if ((newvol < 0) || (newvol > 100)) + quit("!System.Volume: invalid volume - must be from 0-100"); + + if (newvol == play.digital_master_volume) + return; + + play.digital_master_volume = newvol; + set_volume((newvol * 255) / 100, (newvol * 255) / 100); + + // allegro's set_volume can lose the volumes of all the channels + // if it was previously set low; so restore them + AudioChannelsLock lock; + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) + { + auto* ch = lock.GetChannelIfPlaying(i); + if (ch) + ch->adjust_volume(); + } +} + +const char* System_GetRuntimeInfo() +{ + String runtimeInfo = GetRuntimeInfo(); + + return CreateNewScriptString(runtimeInfo.GetCStr()); +} + +int System_GetRenderAtScreenResolution() +{ + return usetup.RenderAtScreenRes; +} + +void System_SetRenderAtScreenResolution(int enable) +{ + usetup.RenderAtScreenRes = enable != 0; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// int () +RuntimeScriptValue Sc_System_GetAudioChannelCount(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetAudioChannelCount); +} + +// ScriptAudioChannel* (int index) +RuntimeScriptValue Sc_System_GetAudioChannels(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ_PINT(ScriptAudioChannel, ccDynamicAudio, System_GetAudioChannels); +} + +// int () +RuntimeScriptValue Sc_System_GetCapsLock(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetCapsLock); +} + +// int () +RuntimeScriptValue Sc_System_GetColorDepth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetColorDepth); +} + +// int () +RuntimeScriptValue Sc_System_GetGamma(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetGamma); +} + +// void (int newValue) +RuntimeScriptValue Sc_System_SetGamma(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(System_SetGamma); +} + +// int () +RuntimeScriptValue Sc_System_GetHardwareAcceleration(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetHardwareAcceleration); +} + +RuntimeScriptValue Sc_System_GetHasInputFocus(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_BOOL(System_HasInputFocus); +} + +// int () +RuntimeScriptValue Sc_System_GetNumLock(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetNumLock); +} + +// void (int newValue) +RuntimeScriptValue Sc_System_SetNumLock(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(System_SetNumLock); +} + +// int () +RuntimeScriptValue Sc_System_GetOS(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetOS); +} + +// int () +RuntimeScriptValue Sc_System_GetScreenHeight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetScreenHeight); +} + +// int () +RuntimeScriptValue Sc_System_GetScreenWidth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetScreenWidth); +} + +// int () +RuntimeScriptValue Sc_System_GetScrollLock(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetScrollLock); +} + +// int () +RuntimeScriptValue Sc_System_GetSupportsGammaControl(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetSupportsGammaControl); +} + +// const char *() +RuntimeScriptValue Sc_System_GetVersion(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ(const char, myScriptStringImpl, System_GetVersion); +} + +// int () +RuntimeScriptValue Sc_System_GetViewportHeight(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetViewportHeight); +} + +// int () +RuntimeScriptValue Sc_System_GetViewportWidth(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetViewportWidth); +} + +// int () +RuntimeScriptValue Sc_System_GetVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetVolume); +} + +// void (int newvol) +RuntimeScriptValue Sc_System_SetVolume(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(System_SetVolume); +} + +// int () +RuntimeScriptValue Sc_System_GetVsync(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetVsync); +} + +// void (int newValue) +RuntimeScriptValue Sc_System_SetVsync(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(System_SetVsync); +} + +RuntimeScriptValue Sc_System_GetWindowed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetWindowed); +} + +RuntimeScriptValue Sc_System_SetWindowed(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(System_SetWindowed); +} + +// const char *() +RuntimeScriptValue Sc_System_GetRuntimeInfo(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJ(const char, myScriptStringImpl, System_GetRuntimeInfo); +} + +RuntimeScriptValue Sc_System_GetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_INT(System_GetRenderAtScreenResolution); +} + +RuntimeScriptValue Sc_System_SetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_VOID_PINT(System_SetRenderAtScreenResolution); +} + +RuntimeScriptValue Sc_System_Log(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_SCRIPT_SPRINTF(Sc_System_Log, 2); + Debug::Printf(kDbgGroup_Script, (MessageType)params[0].IValue, "%s", scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + + + +void RegisterSystemAPI() +{ + ccAddExternalStaticFunction("System::get_AudioChannelCount", Sc_System_GetAudioChannelCount); + ccAddExternalStaticFunction("System::geti_AudioChannels", Sc_System_GetAudioChannels); + ccAddExternalStaticFunction("System::get_CapsLock", Sc_System_GetCapsLock); + ccAddExternalStaticFunction("System::get_ColorDepth", Sc_System_GetColorDepth); + ccAddExternalStaticFunction("System::get_Gamma", Sc_System_GetGamma); + ccAddExternalStaticFunction("System::set_Gamma", Sc_System_SetGamma); + ccAddExternalStaticFunction("System::get_HardwareAcceleration", Sc_System_GetHardwareAcceleration); + ccAddExternalStaticFunction("System::get_HasInputFocus", Sc_System_GetHasInputFocus); + ccAddExternalStaticFunction("System::get_NumLock", Sc_System_GetNumLock); + ccAddExternalStaticFunction("System::set_NumLock", Sc_System_SetNumLock); + ccAddExternalStaticFunction("System::get_OperatingSystem", Sc_System_GetOS); + ccAddExternalStaticFunction("System::get_RenderAtScreenResolution", Sc_System_GetRenderAtScreenResolution); + ccAddExternalStaticFunction("System::set_RenderAtScreenResolution", Sc_System_SetRenderAtScreenResolution); + ccAddExternalStaticFunction("System::get_RuntimeInfo", Sc_System_GetRuntimeInfo); + ccAddExternalStaticFunction("System::get_ScreenHeight", Sc_System_GetScreenHeight); + ccAddExternalStaticFunction("System::get_ScreenWidth", Sc_System_GetScreenWidth); + ccAddExternalStaticFunction("System::get_ScrollLock", Sc_System_GetScrollLock); + ccAddExternalStaticFunction("System::get_SupportsGammaControl", Sc_System_GetSupportsGammaControl); + ccAddExternalStaticFunction("System::get_Version", Sc_System_GetVersion); + ccAddExternalStaticFunction("SystemInfo::get_Version", Sc_System_GetVersion); + ccAddExternalStaticFunction("System::get_ViewportHeight", Sc_System_GetViewportHeight); + ccAddExternalStaticFunction("System::get_ViewportWidth", Sc_System_GetViewportWidth); + ccAddExternalStaticFunction("System::get_Volume", Sc_System_GetVolume); + ccAddExternalStaticFunction("System::set_Volume", Sc_System_SetVolume); + ccAddExternalStaticFunction("System::get_VSync", Sc_System_GetVsync); + ccAddExternalStaticFunction("System::set_VSync", Sc_System_SetVsync); + ccAddExternalStaticFunction("System::get_Windowed", Sc_System_GetWindowed); + ccAddExternalStaticFunction("System::set_Windowed", Sc_System_SetWindowed); + ccAddExternalStaticFunction("System::Log^102", Sc_System_Log); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("System::get_AudioChannelCount", (void*)System_GetAudioChannelCount); + ccAddExternalFunctionForPlugin("System::geti_AudioChannels", (void*)System_GetAudioChannels); + ccAddExternalFunctionForPlugin("System::get_CapsLock", (void*)System_GetCapsLock); + ccAddExternalFunctionForPlugin("System::get_ColorDepth", (void*)System_GetColorDepth); + ccAddExternalFunctionForPlugin("System::get_Gamma", (void*)System_GetGamma); + ccAddExternalFunctionForPlugin("System::set_Gamma", (void*)System_SetGamma); + ccAddExternalFunctionForPlugin("System::get_HardwareAcceleration", (void*)System_GetHardwareAcceleration); + ccAddExternalFunctionForPlugin("System::get_NumLock", (void*)System_GetNumLock); + ccAddExternalFunctionForPlugin("System::set_NumLock", (void*)System_SetNumLock); + ccAddExternalFunctionForPlugin("System::get_OperatingSystem", (void*)System_GetOS); + ccAddExternalFunctionForPlugin("System::get_RuntimeInfo", (void*)System_GetRuntimeInfo); + ccAddExternalFunctionForPlugin("System::get_ScreenHeight", (void*)System_GetScreenHeight); + ccAddExternalFunctionForPlugin("System::get_ScreenWidth", (void*)System_GetScreenWidth); + ccAddExternalFunctionForPlugin("System::get_ScrollLock", (void*)System_GetScrollLock); + ccAddExternalFunctionForPlugin("System::get_SupportsGammaControl", (void*)System_GetSupportsGammaControl); + ccAddExternalFunctionForPlugin("System::get_Version", (void*)System_GetVersion); + ccAddExternalFunctionForPlugin("SystemInfo::get_Version", (void*)System_GetVersion); + ccAddExternalFunctionForPlugin("System::get_ViewportHeight", (void*)System_GetViewportHeight); + ccAddExternalFunctionForPlugin("System::get_ViewportWidth", (void*)System_GetViewportWidth); + ccAddExternalFunctionForPlugin("System::get_Volume", (void*)System_GetVolume); + ccAddExternalFunctionForPlugin("System::set_Volume", (void*)System_SetVolume); + ccAddExternalFunctionForPlugin("System::get_VSync", (void*)System_GetVsync); + ccAddExternalFunctionForPlugin("System::set_VSync", (void*)System_SetVsync); + ccAddExternalFunctionForPlugin("System::get_Windowed", (void*)System_GetWindowed); +} diff --git a/engines/ags/engine/ac/system.h b/engines/ags/engine/ac/system.h new file mode 100644 index 000000000000..b1f42e884c48 --- /dev/null +++ b/engines/ags/engine/ac/system.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__SYSTEMAUDIO_H +#define __AGS_EE_AC__SYSTEMAUDIO_H + +#include "ac/dynobj/scriptaudiochannel.h" + +int System_GetColorDepth(); +int System_GetOS(); +int System_GetScreenWidth(); +int System_GetScreenHeight(); +int System_GetViewportHeight(); +int System_GetViewportWidth(); +const char *System_GetVersion(); +int System_GetHardwareAcceleration(); +int System_GetNumLock(); +int System_GetCapsLock(); +int System_GetScrollLock(); +void System_SetNumLock(int newValue); +int System_GetVsync(); +void System_SetVsync(int newValue); +int System_GetWindowed(); +int System_GetSupportsGammaControl(); +int System_GetGamma(); +void System_SetGamma(int newValue); +int System_GetAudioChannelCount(); +ScriptAudioChannel* System_GetAudioChannels(int index); +int System_GetVolume(); +void System_SetVolume(int newvol); +const char *System_GetRuntimeInfo(); + + +#endif // __AGS_EE_AC_SYSTEMAUDIO_H diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp new file mode 100644 index 000000000000..f821b6113c4b --- /dev/null +++ b/engines/ags/engine/ac/textbox.cpp @@ -0,0 +1,171 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/textbox.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/string.h" + +extern GameSetupStruct game; + + +// ** TEXT BOX FUNCTIONS + +const char* TextBox_GetText_New(GUITextBox *texbox) { + return CreateNewScriptString(texbox->Text); +} + +void TextBox_GetText(GUITextBox *texbox, char *buffer) { + strcpy(buffer, texbox->Text); +} + +void TextBox_SetText(GUITextBox *texbox, const char *newtex) { + if (strcmp(texbox->Text, newtex)) { + texbox->Text = newtex; + guis_need_update = 1; + } +} + +int TextBox_GetTextColor(GUITextBox *guit) { + return guit->TextColor; +} + +void TextBox_SetTextColor(GUITextBox *guit, int colr) +{ + if (guit->TextColor != colr) + { + guit->TextColor = colr; + guis_need_update = 1; + } +} + +int TextBox_GetFont(GUITextBox *guit) { + return guit->Font; +} + +void TextBox_SetFont(GUITextBox *guit, int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetTextBoxFont: invalid font number."); + + if (guit->Font != fontnum) { + guit->Font = fontnum; + guis_need_update = 1; + } +} + +bool TextBox_GetShowBorder(GUITextBox *guit) { + return guit->IsBorderShown(); +} + +void TextBox_SetShowBorder(GUITextBox *guit, bool on) +{ + if (guit->IsBorderShown() != on) + { + guit->SetShowBorder(on); + guis_need_update = 1; + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" +#include "ac/dynobj/scriptstring.h" + +extern ScriptString myScriptStringImpl; + +// void (GUITextBox *texbox, char *buffer) +RuntimeScriptValue Sc_TextBox_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUITextBox, TextBox_GetText, char); +} + +// void (GUITextBox *texbox, const char *newtex) +RuntimeScriptValue Sc_TextBox_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(GUITextBox, TextBox_SetText, const char); +} + +// int (GUITextBox *guit) +RuntimeScriptValue Sc_TextBox_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUITextBox, TextBox_GetFont); +} + +// void (GUITextBox *guit, int fontnum) +RuntimeScriptValue Sc_TextBox_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUITextBox, TextBox_SetFont); +} + +RuntimeScriptValue Sc_TextBox_GetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(GUITextBox, TextBox_GetShowBorder); +} + +// void (GUITextBox *guit, int fontnum) +RuntimeScriptValue Sc_TextBox_SetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PBOOL(GUITextBox, TextBox_SetShowBorder); +} + +// const char* (GUITextBox *texbox) +RuntimeScriptValue Sc_TextBox_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(GUITextBox, const char *, myScriptStringImpl, TextBox_GetText_New); +} + +// int (GUITextBox *guit) +RuntimeScriptValue Sc_TextBox_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(GUITextBox, TextBox_GetTextColor); +} + +// void (GUITextBox *guit, int colr) +RuntimeScriptValue Sc_TextBox_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(GUITextBox, TextBox_SetTextColor); +} + + +void RegisterTextBoxAPI() +{ + ccAddExternalObjectFunction("TextBox::GetText^1", Sc_TextBox_GetText); + ccAddExternalObjectFunction("TextBox::SetText^1", Sc_TextBox_SetText); + ccAddExternalObjectFunction("TextBox::get_Font", Sc_TextBox_GetFont); + ccAddExternalObjectFunction("TextBox::set_Font", Sc_TextBox_SetFont); + ccAddExternalObjectFunction("TextBox::get_ShowBorder", Sc_TextBox_GetShowBorder); + ccAddExternalObjectFunction("TextBox::set_ShowBorder", Sc_TextBox_SetShowBorder); + ccAddExternalObjectFunction("TextBox::get_Text", Sc_TextBox_GetText_New); + ccAddExternalObjectFunction("TextBox::set_Text", Sc_TextBox_SetText); + ccAddExternalObjectFunction("TextBox::get_TextColor", Sc_TextBox_GetTextColor); + ccAddExternalObjectFunction("TextBox::set_TextColor", Sc_TextBox_SetTextColor); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("TextBox::GetText^1", (void*)TextBox_GetText); + ccAddExternalFunctionForPlugin("TextBox::SetText^1", (void*)TextBox_SetText); + ccAddExternalFunctionForPlugin("TextBox::get_Font", (void*)TextBox_GetFont); + ccAddExternalFunctionForPlugin("TextBox::set_Font", (void*)TextBox_SetFont); + ccAddExternalFunctionForPlugin("TextBox::get_Text", (void*)TextBox_GetText_New); + ccAddExternalFunctionForPlugin("TextBox::set_Text", (void*)TextBox_SetText); + ccAddExternalFunctionForPlugin("TextBox::get_TextColor", (void*)TextBox_GetTextColor); + ccAddExternalFunctionForPlugin("TextBox::set_TextColor", (void*)TextBox_SetTextColor); +} diff --git a/engines/ags/engine/ac/textbox.h b/engines/ags/engine/ac/textbox.h new file mode 100644 index 000000000000..fce247c9e6ea --- /dev/null +++ b/engines/ags/engine/ac/textbox.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__TEXTBOX_H +#define __AGS_EE_AC__TEXTBOX_H + +#include "gui/guitextbox.h" + +using AGS::Common::GUITextBox; + +const char* TextBox_GetText_New(GUITextBox *texbox); +void TextBox_GetText(GUITextBox *texbox, char *buffer); +void TextBox_SetText(GUITextBox *texbox, const char *newtex); +int TextBox_GetTextColor(GUITextBox *guit); +void TextBox_SetTextColor(GUITextBox *guit, int colr); +int TextBox_GetFont(GUITextBox *guit); +void TextBox_SetFont(GUITextBox *guit, int fontnum); + +#endif // __AGS_EE_AC__TEXTBOX_H diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp new file mode 100644 index 000000000000..5b4b01237c19 --- /dev/null +++ b/engines/ags/engine/ac/timer.cpp @@ -0,0 +1,120 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/timer.h" + +#include "core/platform.h" +#if AGS_PLATFORM_DEBUG && defined (__GNUC__) +#include +#include +#include +#endif +#include +#include "platform/base/agsplatformdriver.h" + +namespace { + +const auto MAXIMUM_FALL_BEHIND = 3; + +auto tick_duration = std::chrono::microseconds(1000000LL/40); +auto framerate_maxed = false; + +auto last_tick_time = AGS_Clock::now(); +auto next_frame_timestamp = AGS_Clock::now(); + +} + +std::chrono::microseconds GetFrameDuration() +{ + if (framerate_maxed) { + return std::chrono::microseconds(0); + } + return tick_duration; +} + +void setTimerFps(int new_fps) +{ + tick_duration = std::chrono::microseconds(1000000LL/new_fps); + framerate_maxed = new_fps >= 1000; + + last_tick_time = AGS_Clock::now(); + next_frame_timestamp = AGS_Clock::now(); +} + +bool isTimerFpsMaxed() +{ + return framerate_maxed; +} + +void WaitForNextFrame() +{ + auto now = AGS_Clock::now(); + auto frameDuration = GetFrameDuration(); + + // early exit if we're trying to maximise framerate + if (frameDuration <= std::chrono::milliseconds::zero()) { + next_frame_timestamp = now; + return; + } + + // jump ahead if we're lagging + if (next_frame_timestamp < (now - MAXIMUM_FALL_BEHIND*frameDuration)) { + next_frame_timestamp = now; + } + + auto frame_time_remaining = next_frame_timestamp - now; + if (frame_time_remaining > std::chrono::milliseconds::zero()) { + std::this_thread::sleep_for(frame_time_remaining); + } + + next_frame_timestamp += frameDuration; +} + +bool waitingForNextTick() +{ + auto now = AGS_Clock::now(); + + if (framerate_maxed) { + last_tick_time = now; + return false; + } + + auto is_lagging = (now - last_tick_time) > (MAXIMUM_FALL_BEHIND*tick_duration); + if (is_lagging) { +#if AGS_PLATFORM_DEBUG && defined (__GNUC__) + auto missed_ticks = ((now - last_tick_time)/tick_duration); + printf("Lagging! Missed %lld ticks!\n", (long long)missed_ticks); + void *array[10]; + auto size = backtrace(array, 10); + backtrace_symbols_fd(array, size, STDOUT_FILENO); + printf("\n"); +#endif + last_tick_time = now; + return false; + } + + auto next_tick_time = last_tick_time + tick_duration; + if (next_tick_time <= now) { + last_tick_time = next_tick_time; + return false; + } + + return true; +} + +void skipMissedTicks() +{ + last_tick_time = AGS_Clock::now(); + next_frame_timestamp = AGS_Clock::now(); +} diff --git a/engines/ags/engine/ac/timer.h b/engines/ags/engine/ac/timer.h new file mode 100644 index 000000000000..5ad275f7e4ab --- /dev/null +++ b/engines/ags/engine/ac/timer.h @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__TIMER_H +#define __AGS_EE_AC__TIMER_H + +#include +#include + +// use high resolution clock only if we know it is monotonic/steady. +// refer to https://stackoverflow.com/a/38253266/84262 +using AGS_Clock = std::conditional< + std::chrono::high_resolution_clock::is_steady, + std::chrono::high_resolution_clock, std::chrono::steady_clock + >::type; + +extern void WaitForNextFrame(); + +// Sets real FPS to the given number of frames per second; pass 1000+ for maxed FPS mode +extern void setTimerFps(int new_fps); +// Tells whether maxed FPS mode is currently set +extern bool isTimerFpsMaxed(); +extern bool waitingForNextTick(); // store last tick time. +extern void skipMissedTicks(); // if more than N frames, just skip all, start a fresh. + +#endif // __AGS_EE_AC__TIMER_H diff --git a/engines/ags/engine/ac/topbarsettings.h b/engines/ags/engine/ac/topbarsettings.h new file mode 100644 index 000000000000..2060848b4ca7 --- /dev/null +++ b/engines/ags/engine/ac/topbarsettings.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__TOPBARSETTINGS_H +#define __AGS_EE_AC__TOPBARSETTINGS_H + +struct TopBarSettings { + int wantIt; + int height; + int font; + char text[200]; + + TopBarSettings() { + wantIt = 0; + height = 0; + font = 0; + text[0] = 0; + } +}; + +#endif // __AGS_EE_AC__TOPBARSETTINGS_H diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp new file mode 100644 index 000000000000..2375c8cd4034 --- /dev/null +++ b/engines/ags/engine/ac/translation.cpp @@ -0,0 +1,180 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/asset_helper.h" +#include "ac/common.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_game.h" +#include "ac/runtime_defines.h" +#include "ac/translation.h" +#include "ac/tree_map.h" +#include "ac/wordsdictionary.h" +#include "debug/out.h" +#include "util/misc.h" +#include "util/stream.h" +#include "core/assetmanager.h" + +using namespace AGS::Common; + +extern GameSetup usetup; +extern GameSetupStruct game; +extern GameState play; +extern char transFileName[MAX_PATH]; + + +TreeMap *transtree = nullptr; +long lang_offs_start = 0; +char transFileName[MAX_PATH] = "\0"; + +void close_translation () { + if (transtree != nullptr) { + delete transtree; + transtree = nullptr; + } +} + +bool parse_translation(Stream *language_file, String &parse_error); + +bool init_translation (const String &lang, const String &fallback_lang, bool quit_on_error) { + + if (lang.IsEmpty()) + return false; + sprintf(transFileName, "%s.tra", lang.GetCStr()); + + Stream *language_file = find_open_asset(transFileName); + if (language_file == nullptr) + { + Debug::Printf(kDbgMsg_Error, "Cannot open translation: %s", transFileName); + return false; + } + // in case it's inside a library file, record the offset + lang_offs_start = language_file->GetPosition(); + + char transsig[16] = {0}; + language_file->Read(transsig, 15); + if (strcmp(transsig, "AGSTranslation") != 0) { + Debug::Printf(kDbgMsg_Error, "Translation signature mismatch: %s", transFileName); + delete language_file; + return false; + } + + if (transtree != nullptr) + { + close_translation(); + } + transtree = new TreeMap(); + + String parse_error; + bool result = parse_translation(language_file, parse_error); + delete language_file; + + if (!result) + { + close_translation(); + parse_error.Prepend(String::FromFormat("Failed to read translation file: %s:\n", transFileName)); + if (quit_on_error) + { + parse_error.PrependChar('!'); + quit(parse_error); + } + else + { + Debug::Printf(kDbgMsg_Error, parse_error); + if (!fallback_lang.IsEmpty()) + { + Debug::Printf("Fallback to translation: %s", fallback_lang.GetCStr()); + init_translation(fallback_lang, "", false); + } + return false; + } + } + Debug::Printf("Translation initialized: %s", transFileName); + return true; +} + +bool parse_translation(Stream *language_file, String &parse_error) +{ + while (!language_file->EOS()) { + int blockType = language_file->ReadInt32(); + if (blockType == -1) + break; + // MACPORT FIX 9/6/5: remove warning + /* int blockSize = */ language_file->ReadInt32(); + + if (blockType == 1) { + char original[STD_BUFFER_SIZE], translation[STD_BUFFER_SIZE]; + while (1) { + read_string_decrypt (language_file, original, STD_BUFFER_SIZE); + read_string_decrypt (language_file, translation, STD_BUFFER_SIZE); + if ((strlen (original) < 1) && (strlen(translation) < 1)) + break; + if (language_file->EOS()) + { + parse_error = "Translation file is corrupt"; + return false; + } + transtree->addText (original, translation); + } + + } + else if (blockType == 2) { + int uidfrom; + char wasgamename[100]; + uidfrom = language_file->ReadInt32(); + read_string_decrypt (language_file, wasgamename, sizeof(wasgamename)); + if ((uidfrom != game.uniqueid) || (strcmp (wasgamename, game.gamename) != 0)) { + parse_error.Format("The translation file is not compatible with this game. The translation is designed for '%s'.", + wasgamename); + return false; + } + } + else if (blockType == 3) { + // game settings + int temp = language_file->ReadInt32(); + // normal font + if (temp >= 0) + SetNormalFont (temp); + temp = language_file->ReadInt32(); + // speech font + if (temp >= 0) + SetSpeechFont (temp); + temp = language_file->ReadInt32(); + // text direction + if (temp == 1) { + play.text_align = kHAlignLeft; + game.options[OPT_RIGHTLEFTWRITE] = 0; + } + else if (temp == 2) { + play.text_align = kHAlignRight; + game.options[OPT_RIGHTLEFTWRITE] = 1; + } + } + else + { + parse_error.Format("Unknown block type in translation file (%d).", blockType); + return false; + } + } + + if (transtree->text == nullptr) + { + parse_error = "The translation file was empty."; + return false; + } + + return true; +} diff --git a/engines/ags/engine/ac/translation.h b/engines/ags/engine/ac/translation.h new file mode 100644 index 000000000000..5494d89593db --- /dev/null +++ b/engines/ags/engine/ac/translation.h @@ -0,0 +1,28 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__TRANSLATION_H +#define __AGS_EE_AC__TRANSLATION_H + +#include "util/string.h" + +using AGS::Common::String; + +void close_translation (); +bool init_translation (const String &lang, const String &fallback_lang, bool quit_on_error); + +#endif // __AGS_EE_AC__TRANSLATION_H diff --git a/engines/ags/engine/ac/tree_map.cpp b/engines/ags/engine/ac/tree_map.cpp new file mode 100644 index 000000000000..7cf92bea51d3 --- /dev/null +++ b/engines/ags/engine/ac/tree_map.cpp @@ -0,0 +1,98 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "ac/common.h" +#include "ac/tree_map.h" + +TreeMap::TreeMap() { + left = nullptr; + right = nullptr; + text = nullptr; + translation = nullptr; +} + +char* TreeMap::findValue (const char* key) { + if (text == nullptr) + return nullptr; + + if (strcmp(key, text) == 0) + return translation; + //debug_script_warn("Compare: '%s' with '%s'", key, text); + + if (strcmp (key, text) < 0) { + if (left == nullptr) + return nullptr; + return left->findValue (key); + } + else { + if (right == nullptr) + return nullptr; + return right->findValue (key); + } +} + +void TreeMap::addText (const char* ntx, char *trans) { + if ((ntx == nullptr) || (ntx[0] == 0) || + ((text != nullptr) && (strcmp(ntx, text) == 0))) + // don't add if it's an empty string or if it's already here + return; + + if (text == nullptr) { + text = (char*)malloc(strlen(ntx)+1); + translation = (char*)malloc(strlen(trans)+1); + if (translation == nullptr) + quit("load_translation: out of memory"); + strcpy(text, ntx); + strcpy(translation, trans); + } + else if (strcmp(ntx, text) < 0) { + // Earlier in alphabet, add to left + if (left == nullptr) + left = new TreeMap(); + + left->addText (ntx, trans); + } + else if (strcmp(ntx, text) > 0) { + // Later in alphabet, add to right + if (right == nullptr) + right = new TreeMap(); + + right->addText (ntx, trans); + } +} + +void TreeMap::clear() { + if (left) { + left->clear(); + delete left; + } + if (right) { + right->clear(); + delete right; + } + if (text) + free(text); + if (translation) + free(translation); + left = nullptr; + right = nullptr; + text = nullptr; + translation = nullptr; +} + +TreeMap::~TreeMap() { + clear(); +} diff --git a/engines/ags/engine/ac/tree_map.h b/engines/ags/engine/ac/tree_map.h new file mode 100644 index 000000000000..c2fd0417c1d5 --- /dev/null +++ b/engines/ags/engine/ac/tree_map.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__TREEMAP_H +#define __AGS_EE_AC__TREEMAP_H + +// Binary tree structure for holding translations, allows fast +// access +struct TreeMap { + TreeMap *left, *right; + char *text; + char *translation; + + TreeMap(); + char* findValue (const char* key); + void addText (const char* ntx, char *trans); + void clear(); + ~TreeMap(); +}; + +#endif // __AGS_EE_AC__TREEMAP_H diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp new file mode 100644 index 000000000000..baaa1ecb3d02 --- /dev/null +++ b/engines/ags/engine/ac/viewframe.cpp @@ -0,0 +1,287 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/gamesetupstruct.h" +#include "ac/viewframe.h" +#include "debug/debug_log.h" +#include "ac/spritecache.h" +#include "gfx/bitmap.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_audioclip.h" +#include "ac/draw.h" +#include "ac/game_version.h" +#include "media/audio/audio_system.h" + +using AGS::Common::Bitmap; +using AGS::Common::Graphics; + +extern GameSetupStruct game; +extern ViewStruct*views; +extern SpriteCache spriteset; +extern CCAudioClip ccDynamicAudioClip; + + +int ViewFrame_GetFlipped(ScriptViewFrame *svf) { + if (views[svf->view].loops[svf->loop].frames[svf->frame].flags & VFLG_FLIPSPRITE) + return 1; + return 0; +} + +int ViewFrame_GetGraphic(ScriptViewFrame *svf) { + return views[svf->view].loops[svf->loop].frames[svf->frame].pic; +} + +void ViewFrame_SetGraphic(ScriptViewFrame *svf, int newPic) { + views[svf->view].loops[svf->loop].frames[svf->frame].pic = newPic; +} + +ScriptAudioClip* ViewFrame_GetLinkedAudio(ScriptViewFrame *svf) +{ + int soundIndex = views[svf->view].loops[svf->loop].frames[svf->frame].sound; + if (soundIndex < 0) + return nullptr; + + return &game.audioClips[soundIndex]; +} + +void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip* clip) +{ + int newSoundIndex = -1; + if (clip != nullptr) + newSoundIndex = clip->id; + + views[svf->view].loops[svf->loop].frames[svf->frame].sound = newSoundIndex; +} + +int ViewFrame_GetSound(ScriptViewFrame *svf) { + // convert audio clip to old-style sound number + return get_old_style_number_for_sound(views[svf->view].loops[svf->loop].frames[svf->frame].sound); +} + +void ViewFrame_SetSound(ScriptViewFrame *svf, int newSound) +{ + if (newSound < 1) + { + views[svf->view].loops[svf->loop].frames[svf->frame].sound = -1; + } + else + { + // convert sound number to audio clip + ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, newSound); + if (clip == nullptr) + quitprintf("!SetFrameSound: audio clip aSound%d not found", newSound); + + views[svf->view].loops[svf->loop].frames[svf->frame].sound = clip->id + (game.IsLegacyAudioSystem() ? 0x10000000 : 0); + } +} + +int ViewFrame_GetSpeed(ScriptViewFrame *svf) { + return views[svf->view].loops[svf->loop].frames[svf->frame].speed; +} + +int ViewFrame_GetView(ScriptViewFrame *svf) { + return svf->view + 1; +} + +int ViewFrame_GetLoop(ScriptViewFrame *svf) { + return svf->loop; +} + +int ViewFrame_GetFrame(ScriptViewFrame *svf) { + return svf->frame; +} + +//============================================================================= + +void precache_view(int view) +{ + if (view < 0) + return; + + for (int i = 0; i < views[view].numLoops; i++) { + for (int j = 0; j < views[view].loops[i].numFrames; j++) + spriteset.Precache(views[view].loops[i].frames[j].pic); + } +} + +// the specified frame has just appeared, see if we need +// to play a sound or whatever +void CheckViewFrame (int view, int loop, int frame, int sound_volume) { + ScriptAudioChannel *channel = nullptr; + if (game.IsLegacyAudioSystem()) + { + if (views[view].loops[loop].frames[frame].sound > 0) + { + if (views[view].loops[loop].frames[frame].sound < 0x10000000) + { + ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, views[view].loops[loop].frames[frame].sound); + if (clip) + views[view].loops[loop].frames[frame].sound = clip->id + 0x10000000; + else + { + views[view].loops[loop].frames[frame].sound = 0; + return; + } + } + channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound - 0x10000000); + } + } + else + { + if (views[view].loops[loop].frames[frame].sound >= 0) { + // play this sound (eg. footstep) + channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound); + } + } + if (sound_volume != SCR_NO_VALUE && channel != nullptr) + { + AudioChannelsLock lock; + auto* ch = lock.GetChannel(channel->id); + if (ch) + ch->set_volume_percent(ch->get_volume() * sound_volume / 100); + } + +} + +// draws a view frame, flipped if appropriate +void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend) +{ + // NOTE: DrawViewFrame supports alpha blending only since OPT_SPRITEALPHA; + // this is why there's no sense in blending if it's not set (will do no good anyway). + if (alpha_blend && game.options[OPT_SPRITEALPHA] == kSpriteAlphaRender_Proper) + { + Bitmap *vf_bmp = spriteset[vframe->pic]; + Bitmap *src = vf_bmp; + if (vframe->flags & VFLG_FLIPSPRITE) + { + src = new Bitmap(vf_bmp->GetWidth(), vf_bmp->GetHeight(), vf_bmp->GetColorDepth()); + src->FlipBlt(vf_bmp, 0, 0, Common::kBitmap_HFlip); + } + draw_sprite_support_alpha(ds, true, x, y, src, (game.SpriteInfos[vframe->pic].Flags & SPF_ALPHACHANNEL) != 0); + if (src != vf_bmp) + delete src; + } + else + { + if (vframe->flags & VFLG_FLIPSPRITE) + ds->FlipBlt(spriteset[vframe->pic], x, y, Common::kBitmap_HFlip); + else + ds->Blit(spriteset[vframe->pic], x, y, Common::kBitmap_Transparency); + } +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "debug/out.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +// int (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetFlipped(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFlipped); +} + +// int (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFrame); +} +// int (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetGraphic); +} + +// void (ScriptViewFrame *svf, int newPic) +RuntimeScriptValue Sc_ViewFrame_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetGraphic); +} + +// ScriptAudioClip* (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJ(ScriptViewFrame, ScriptAudioClip, ccDynamicAudioClip, ViewFrame_GetLinkedAudio); +} + +// void (ScriptViewFrame *svf, ScriptAudioClip* clip) +RuntimeScriptValue Sc_ViewFrame_SetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(ScriptViewFrame, ViewFrame_SetLinkedAudio, ScriptAudioClip); +} + +// int (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetLoop); +} + +// int (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSound); +} + +// void (ScriptViewFrame *svf, int newSound) +RuntimeScriptValue Sc_ViewFrame_SetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetSound); +} + +// int (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSpeed); +} + +// int (ScriptViewFrame *svf) +RuntimeScriptValue Sc_ViewFrame_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetView); +} + + +void RegisterViewFrameAPI() +{ + ccAddExternalObjectFunction("ViewFrame::get_Flipped", Sc_ViewFrame_GetFlipped); + ccAddExternalObjectFunction("ViewFrame::get_Frame", Sc_ViewFrame_GetFrame); + ccAddExternalObjectFunction("ViewFrame::get_Graphic", Sc_ViewFrame_GetGraphic); + ccAddExternalObjectFunction("ViewFrame::set_Graphic", Sc_ViewFrame_SetGraphic); + ccAddExternalObjectFunction("ViewFrame::get_LinkedAudio", Sc_ViewFrame_GetLinkedAudio); + ccAddExternalObjectFunction("ViewFrame::set_LinkedAudio", Sc_ViewFrame_SetLinkedAudio); + ccAddExternalObjectFunction("ViewFrame::get_Loop", Sc_ViewFrame_GetLoop); + ccAddExternalObjectFunction("ViewFrame::get_Sound", Sc_ViewFrame_GetSound); + ccAddExternalObjectFunction("ViewFrame::set_Sound", Sc_ViewFrame_SetSound); + ccAddExternalObjectFunction("ViewFrame::get_Speed", Sc_ViewFrame_GetSpeed); + ccAddExternalObjectFunction("ViewFrame::get_View", Sc_ViewFrame_GetView); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("ViewFrame::get_Flipped", (void*)ViewFrame_GetFlipped); + ccAddExternalFunctionForPlugin("ViewFrame::get_Frame", (void*)ViewFrame_GetFrame); + ccAddExternalFunctionForPlugin("ViewFrame::get_Graphic", (void*)ViewFrame_GetGraphic); + ccAddExternalFunctionForPlugin("ViewFrame::set_Graphic", (void*)ViewFrame_SetGraphic); + ccAddExternalFunctionForPlugin("ViewFrame::get_LinkedAudio", (void*)ViewFrame_GetLinkedAudio); + ccAddExternalFunctionForPlugin("ViewFrame::set_LinkedAudio", (void*)ViewFrame_SetLinkedAudio); + ccAddExternalFunctionForPlugin("ViewFrame::get_Loop", (void*)ViewFrame_GetLoop); + ccAddExternalFunctionForPlugin("ViewFrame::get_Sound", (void*)ViewFrame_GetSound); + ccAddExternalFunctionForPlugin("ViewFrame::set_Sound", (void*)ViewFrame_SetSound); + ccAddExternalFunctionForPlugin("ViewFrame::get_Speed", (void*)ViewFrame_GetSpeed); + ccAddExternalFunctionForPlugin("ViewFrame::get_View", (void*)ViewFrame_GetView); +} diff --git a/engines/ags/engine/ac/viewframe.h b/engines/ags/engine/ac/viewframe.h new file mode 100644 index 000000000000..353bfc74bbb3 --- /dev/null +++ b/engines/ags/engine/ac/viewframe.h @@ -0,0 +1,47 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__VIEWFRAME_H +#define __AGS_EE_AC__VIEWFRAME_H + +#include "ac/runtime_defines.h" +#include "ac/view.h" +#include "ac/dynobj/scriptaudioclip.h" +#include "ac/dynobj/scriptviewframe.h" +#include "gfx/bitmap.h" + +namespace AGS { namespace Common { class Graphics; } } +using namespace AGS; // FIXME later + +int ViewFrame_GetFlipped(ScriptViewFrame *svf); +int ViewFrame_GetGraphic(ScriptViewFrame *svf); +void ViewFrame_SetGraphic(ScriptViewFrame *svf, int newPic); +ScriptAudioClip* ViewFrame_GetLinkedAudio(ScriptViewFrame *svf); +void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip* clip); +int ViewFrame_GetSound(ScriptViewFrame *svf); +void ViewFrame_SetSound(ScriptViewFrame *svf, int newSound); +int ViewFrame_GetSpeed(ScriptViewFrame *svf); +int ViewFrame_GetView(ScriptViewFrame *svf); +int ViewFrame_GetLoop(ScriptViewFrame *svf); +int ViewFrame_GetFrame(ScriptViewFrame *svf); + +void precache_view(int view); +void CheckViewFrame (int view, int loop, int frame, int sound_volume=SCR_NO_VALUE); +// draws a view frame, flipped if appropriate +void DrawViewFrame(Common::Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend = false); + +#endif // __AGS_EE_AC__VIEWFRAME_H diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp new file mode 100644 index 000000000000..c819873ea5be --- /dev/null +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -0,0 +1,527 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Viewport and Camera script API. +// +//============================================================================= + +#include "ac/dynobj/scriptcamera.h" +#include "ac/dynobj/scriptviewport.h" +#include "ac/dynobj/scriptuserobject.h" +#include "ac/draw.h" +#include "ac/gamestate.h" +#include "debug/debug_log.h" +#include "script/script_api.h" +#include "script/script_runtime.h" + +using namespace AGS::Common; + +//============================================================================= +// +// Camera script API. +// +//============================================================================= + +ScriptCamera* Camera_Create() +{ + auto cam = play.CreateRoomCamera(); + if (!cam) + return NULL; + return play.RegisterRoomCamera(cam->GetID()); +} + +void Camera_Delete(ScriptCamera *scam) +{ + play.DeleteRoomCamera(scam->GetID()); +} + +int Camera_GetX(ScriptCamera *scam) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.X: trying to use deleted camera"); return 0; } + int x = play.GetRoomCamera(scam->GetID())->GetRect().Left; + return game_to_data_coord(x); +} + +void Camera_SetX(ScriptCamera *scam, int x) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.X: trying to use deleted camera"); return; } + x = data_to_game_coord(x); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->LockAt(x, cam->GetRect().Top); +} + +int Camera_GetY(ScriptCamera *scam) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.Y: trying to use deleted camera"); return 0; } + int y = play.GetRoomCamera(scam->GetID())->GetRect().Top; + return game_to_data_coord(y); +} + +void Camera_SetY(ScriptCamera *scam, int y) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.Y: trying to use deleted camera"); return; } + y = data_to_game_coord(y); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->LockAt(cam->GetRect().Left, y); +} + +int Camera_GetWidth(ScriptCamera *scam) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.Width: trying to use deleted camera"); return 0; } + int width = play.GetRoomCamera(scam->GetID())->GetRect().GetWidth(); + return game_to_data_coord(width); +} + +void Camera_SetWidth(ScriptCamera *scam, int width) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.Width: trying to use deleted camera"); return; } + width = data_to_game_coord(width); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->SetSize(Size(width, cam->GetRect().GetHeight())); +} + +int Camera_GetHeight(ScriptCamera *scam) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.Height: trying to use deleted camera"); return 0; } + int height = play.GetRoomCamera(scam->GetID())->GetRect().GetHeight(); + return game_to_data_coord(height); +} + +void Camera_SetHeight(ScriptCamera *scam, int height) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.Height: trying to use deleted camera"); return; } + height = data_to_game_coord(height); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->SetSize(Size(cam->GetRect().GetWidth(), height)); +} + +bool Camera_GetAutoTracking(ScriptCamera *scam) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.AutoTracking: trying to use deleted camera"); return false; } + return !play.GetRoomCamera(scam->GetID())->IsLocked(); +} + +void Camera_SetAutoTracking(ScriptCamera *scam, bool on) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.AutoTracking: trying to use deleted camera"); return; } + auto cam = play.GetRoomCamera(scam->GetID()); + if (on) + cam->Release(); + else + cam->Lock(); +} + +void Camera_SetAt(ScriptCamera *scam, int x, int y) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.SetAt: trying to use deleted camera"); return; } + data_to_game_coords(&x, &y); + play.GetRoomCamera(scam->GetID())->LockAt(x, y); +} + +void Camera_SetSize(ScriptCamera *scam, int width, int height) +{ + if (scam->GetID() < 0) { debug_script_warn("Camera.SetSize: trying to use deleted camera"); return; } + data_to_game_coords(&width, &height); + play.GetRoomCamera(scam->GetID())->SetSize(Size(width, height)); +} + +RuntimeScriptValue Sc_Camera_Create(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO(ScriptCamera, Camera_Create); +} + +RuntimeScriptValue Sc_Camera_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptCamera, Camera_Delete); +} + +RuntimeScriptValue Sc_Camera_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptCamera, Camera_GetX); +} + +RuntimeScriptValue Sc_Camera_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetX); +} + +RuntimeScriptValue Sc_Camera_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptCamera, Camera_GetY); +} + +RuntimeScriptValue Sc_Camera_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetY); +} + +RuntimeScriptValue Sc_Camera_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptCamera, Camera_GetWidth); +} + +RuntimeScriptValue Sc_Camera_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetWidth); +} + +RuntimeScriptValue Sc_Camera_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptCamera, Camera_GetHeight); +} + +RuntimeScriptValue Sc_Camera_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetHeight); +} + +RuntimeScriptValue Sc_Camera_GetAutoTracking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(ScriptCamera, Camera_GetAutoTracking); +} + +RuntimeScriptValue Sc_Camera_SetAutoTracking(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PBOOL(ScriptCamera, Camera_SetAutoTracking); +} + +RuntimeScriptValue Sc_Camera_SetAt(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptCamera, Camera_SetAt); +} + +RuntimeScriptValue Sc_Camera_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT2(ScriptCamera, Camera_SetSize); +} + + +//============================================================================= +// +// Viewport script API. +// +//============================================================================= + +ScriptViewport* Viewport_Create() +{ + auto view = play.CreateRoomViewport(); + if (!view) + return NULL; + return play.RegisterRoomViewport(view->GetID()); +} + +void Viewport_Delete(ScriptViewport *scv) +{ + play.DeleteRoomViewport(scv->GetID()); +} + +int Viewport_GetX(ScriptViewport *scv) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.X: trying to use deleted viewport"); return 0; } + int x = play.GetRoomViewport(scv->GetID())->GetRect().Left; + return game_to_data_coord(x); +} + +void Viewport_SetX(ScriptViewport *scv, int x) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.X: trying to use deleted viewport"); return; } + x = data_to_game_coord(x); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetAt(x, view->GetRect().Top); +} + +int Viewport_GetY(ScriptViewport *scv) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Y: trying to use deleted viewport"); return 0; } + int y = play.GetRoomViewport(scv->GetID())->GetRect().Top; + return game_to_data_coord(y); +} + +void Viewport_SetY(ScriptViewport *scv, int y) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Y: trying to use deleted viewport"); return; } + y = data_to_game_coord(y); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetAt(view->GetRect().Left, y); +} + +int Viewport_GetWidth(ScriptViewport *scv) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Width: trying to use deleted viewport"); return 0; } + int width = play.GetRoomViewport(scv->GetID())->GetRect().GetWidth(); + return game_to_data_coord(width); +} + +void Viewport_SetWidth(ScriptViewport *scv, int width) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Width: trying to use deleted viewport"); return; } + width = data_to_game_coord(width); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetSize(Size(width, view->GetRect().GetHeight())); +} + +int Viewport_GetHeight(ScriptViewport *scv) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Height: trying to use deleted viewport"); return 0; } + int height = play.GetRoomViewport(scv->GetID())->GetRect().GetHeight(); + return game_to_data_coord(height); +} + +void Viewport_SetHeight(ScriptViewport *scv, int height) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Height: trying to use deleted viewport"); return; } + height = data_to_game_coord(height); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetSize(Size(view->GetRect().GetWidth(), height)); +} + +ScriptCamera* Viewport_GetCamera(ScriptViewport *scv) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Camera: trying to use deleted viewport"); return nullptr; } + auto view = play.GetRoomViewport(scv->GetID()); + auto cam = view->GetCamera(); + if (!cam) + return nullptr; + return play.GetScriptCamera(cam->GetID()); +} + +void Viewport_SetCamera(ScriptViewport *scv, ScriptCamera *scam) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Camera: trying to use deleted viewport"); return; } + if (scam != nullptr && scam->GetID() < 0) { debug_script_warn("Viewport.Camera: trying to link deleted camera"); return; } + auto view = play.GetRoomViewport(scv->GetID()); + // unlink previous camera + auto cam = view->GetCamera(); + if (cam) + cam->UnlinkFromViewport(view->GetID()); + // link new one + if (scam != nullptr) + { + cam = play.GetRoomCamera(scam->GetID()); + view->LinkCamera(cam); + cam->LinkToViewport(view); + } + else + { + view->LinkCamera(nullptr); + } +} + +bool Viewport_GetVisible(ScriptViewport *scv) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Visible: trying to use deleted viewport"); return false; } + return play.GetRoomViewport(scv->GetID())->IsVisible(); +} + +void Viewport_SetVisible(ScriptViewport *scv, bool on) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.Visible: trying to use deleted viewport"); return; } + play.GetRoomViewport(scv->GetID())->SetVisible(on); +} + +int Viewport_GetZOrder(ScriptViewport *scv) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.ZOrder: trying to use deleted viewport"); return 0; } + return play.GetRoomViewport(scv->GetID())->GetZOrder(); +} + +void Viewport_SetZOrder(ScriptViewport *scv, int zorder) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.ZOrder: trying to use deleted viewport"); return; } + play.GetRoomViewport(scv->GetID())->SetZOrder(zorder); + play.InvalidateViewportZOrder(); +} + +ScriptViewport* Viewport_GetAtScreenXY(int x, int y) +{ + data_to_game_coords(&x, &y); + PViewport view = play.GetRoomViewportAt(x, y); + if (!view) + return nullptr; + return play.GetScriptViewport(view->GetID()); +} + +void Viewport_SetPosition(ScriptViewport *scv, int x, int y, int width, int height) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.SetPosition: trying to use deleted viewport"); return; } + data_to_game_coords(&x, &y); + data_to_game_coords(&width, &height); + play.GetRoomViewport(scv->GetID())->SetRect(RectWH(x, y, width, height)); +} + +ScriptUserObject *Viewport_ScreenToRoomPoint(ScriptViewport *scv, int scrx, int scry, bool clipViewport) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.ScreenToRoomPoint: trying to use deleted viewport"); return nullptr; } + data_to_game_coords(&scrx, &scry); + + VpPoint vpt = play.GetRoomViewport(scv->GetID())->ScreenToRoom(scrx, scry, clipViewport); + if (vpt.second < 0) + return nullptr; + + game_to_data_coords(vpt.first.X, vpt.first.Y); + return ScriptStructHelpers::CreatePoint(vpt.first.X, vpt.first.Y); +} + +ScriptUserObject *Viewport_RoomToScreenPoint(ScriptViewport *scv, int roomx, int roomy, bool clipViewport) +{ + if (scv->GetID() < 0) { debug_script_warn("Viewport.RoomToScreenPoint: trying to use deleted viewport"); return nullptr; } + data_to_game_coords(&roomx, &roomy); + Point pt = play.RoomToScreen(roomx, roomy); + if (clipViewport && !play.GetRoomViewport(scv->GetID())->GetRect().IsInside(pt.X, pt.Y)) + return nullptr; + + game_to_data_coords(pt.X, pt.Y); + return ScriptStructHelpers::CreatePoint(pt.X, pt.Y); +} + +RuntimeScriptValue Sc_Viewport_Create(const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO(ScriptViewport, Viewport_Create); +} + +RuntimeScriptValue Sc_Viewport_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID(ScriptViewport, Viewport_Delete); +} + +RuntimeScriptValue Sc_Viewport_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewport, Viewport_GetX); +} + +RuntimeScriptValue Sc_Viewport_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetX); +} + +RuntimeScriptValue Sc_Viewport_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewport, Viewport_GetY); +} + +RuntimeScriptValue Sc_Viewport_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetY); +} + +RuntimeScriptValue Sc_Viewport_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewport, Viewport_GetWidth); +} + +RuntimeScriptValue Sc_Viewport_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetWidth); +} + +RuntimeScriptValue Sc_Viewport_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewport, Viewport_GetHeight); +} + +RuntimeScriptValue Sc_Viewport_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetHeight); +} + +RuntimeScriptValue Sc_Viewport_GetCamera(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJAUTO(ScriptViewport, ScriptCamera, Viewport_GetCamera); +} + +RuntimeScriptValue Sc_Viewport_SetCamera(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_POBJ(ScriptViewport, Viewport_SetCamera, ScriptCamera); +} + +RuntimeScriptValue Sc_Viewport_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_BOOL(ScriptViewport, Viewport_GetVisible); +} + +RuntimeScriptValue Sc_Viewport_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PBOOL(ScriptViewport, Viewport_SetVisible); +} + +RuntimeScriptValue Sc_Viewport_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_INT(ScriptViewport, Viewport_GetZOrder); +} + +RuntimeScriptValue Sc_Viewport_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetZOrder); +} + +RuntimeScriptValue Sc_Viewport_GetAtScreenXY(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_SCALL_OBJAUTO_PINT2(ScriptViewport, Viewport_GetAtScreenXY); +} + +RuntimeScriptValue Sc_Viewport_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_VOID_PINT4(ScriptViewport, Viewport_SetPosition); +} + +RuntimeScriptValue Sc_Viewport_ScreenToRoomPoint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJAUTO_PINT2_PBOOL(ScriptViewport, ScriptUserObject, Viewport_ScreenToRoomPoint); +} + +RuntimeScriptValue Sc_Viewport_RoomToScreenPoint(void *self, const RuntimeScriptValue *params, int32_t param_count) +{ + API_OBJCALL_OBJAUTO_PINT2_PBOOL(ScriptViewport, ScriptUserObject, Viewport_RoomToScreenPoint); +} + + + +void RegisterViewportAPI() +{ + ccAddExternalStaticFunction("Camera::Create", Sc_Camera_Create); + ccAddExternalObjectFunction("Camera::Delete", Sc_Camera_Delete); + ccAddExternalObjectFunction("Camera::get_X", Sc_Camera_GetX); + ccAddExternalObjectFunction("Camera::set_X", Sc_Camera_SetX); + ccAddExternalObjectFunction("Camera::get_Y", Sc_Camera_GetY); + ccAddExternalObjectFunction("Camera::set_Y", Sc_Camera_SetY); + ccAddExternalObjectFunction("Camera::get_Width", Sc_Camera_GetWidth); + ccAddExternalObjectFunction("Camera::set_Width", Sc_Camera_SetWidth); + ccAddExternalObjectFunction("Camera::get_Height", Sc_Camera_GetHeight); + ccAddExternalObjectFunction("Camera::set_Height", Sc_Camera_SetHeight); + ccAddExternalObjectFunction("Camera::get_AutoTracking", Sc_Camera_GetAutoTracking); + ccAddExternalObjectFunction("Camera::set_AutoTracking", Sc_Camera_SetAutoTracking); + ccAddExternalObjectFunction("Camera::SetAt", Sc_Camera_SetAt); + ccAddExternalObjectFunction("Camera::SetSize", Sc_Camera_SetSize); + + ccAddExternalStaticFunction("Viewport::Create", Sc_Viewport_Create); + ccAddExternalObjectFunction("Viewport::Delete", Sc_Viewport_Delete); + ccAddExternalObjectFunction("Viewport::get_X", Sc_Viewport_GetX); + ccAddExternalObjectFunction("Viewport::set_X", Sc_Viewport_SetX); + ccAddExternalObjectFunction("Viewport::get_Y", Sc_Viewport_GetY); + ccAddExternalObjectFunction("Viewport::set_Y", Sc_Viewport_SetY); + ccAddExternalObjectFunction("Viewport::get_Width", Sc_Viewport_GetWidth); + ccAddExternalObjectFunction("Viewport::set_Width", Sc_Viewport_SetWidth); + ccAddExternalObjectFunction("Viewport::get_Height", Sc_Viewport_GetHeight); + ccAddExternalObjectFunction("Viewport::set_Height", Sc_Viewport_SetHeight); + ccAddExternalObjectFunction("Viewport::get_Camera", Sc_Viewport_GetCamera); + ccAddExternalObjectFunction("Viewport::set_Camera", Sc_Viewport_SetCamera); + ccAddExternalObjectFunction("Viewport::get_Visible", Sc_Viewport_GetVisible); + ccAddExternalObjectFunction("Viewport::set_Visible", Sc_Viewport_SetVisible); + ccAddExternalObjectFunction("Viewport::get_ZOrder", Sc_Viewport_GetZOrder); + ccAddExternalObjectFunction("Viewport::set_ZOrder", Sc_Viewport_SetZOrder); + ccAddExternalObjectFunction("Viewport::GetAtScreenXY", Sc_Viewport_GetAtScreenXY); + ccAddExternalObjectFunction("Viewport::SetPosition", Sc_Viewport_SetPosition); + ccAddExternalObjectFunction("Viewport::ScreenToRoomPoint", Sc_Viewport_ScreenToRoomPoint); + ccAddExternalObjectFunction("Viewport::RoomToScreenPoint", Sc_Viewport_RoomToScreenPoint); +} diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp new file mode 100644 index 000000000000..c6631789920d --- /dev/null +++ b/engines/ags/engine/ac/walkablearea.cpp @@ -0,0 +1,238 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "ac/object.h" +#include "ac/character.h" +#include "ac/gamestate.h" +#include "ac/gamesetupstruct.h" +#include "ac/object.h" +#include "ac/room.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "ac/walkablearea.h" +#include "game/roomstruct.h" +#include "gfx/bitmap.h" + +using namespace AGS::Common; + +extern RoomStruct thisroom; +extern GameState play; +extern GameSetupStruct game; +extern int displayed_room; +extern RoomStatus*croom; +extern RoomObject*objs; + +Bitmap *walkareabackup=nullptr, *walkable_areas_temp = nullptr; + +void redo_walkable_areas() { + + // since this is an 8-bit memory bitmap, we can just use direct + // memory access + if ((!thisroom.WalkAreaMask->IsLinearBitmap()) || (thisroom.WalkAreaMask->GetColorDepth() != 8)) + quit("Walkable areas bitmap not linear"); + + thisroom.WalkAreaMask->Blit(walkareabackup, 0, 0, 0, 0, thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight()); + + int hh,ww; + for (hh=0;hhGetHeight();hh++) { + uint8_t *walls_scanline = thisroom.WalkAreaMask->GetScanLineForWriting(hh); + for (ww=0;wwGetWidth();ww++) { + // if (play.walkable_areas_on[_getpixel(thisroom.WalkAreaMask,ww,hh)]==0) + if (play.walkable_areas_on[walls_scanline[ww]]==0) + walls_scanline[ww] = 0; + } + } + +} + +int get_walkable_area_pixel(int x, int y) +{ + return thisroom.WalkAreaMask->GetPixel(room_to_mask_coord(x), room_to_mask_coord(y)); +} + +int get_area_scaling (int onarea, int xx, int yy) { + + int zoom_level = 100; + xx = room_to_mask_coord(xx); + yy = room_to_mask_coord(yy); + + if ((onarea >= 0) && (onarea <= MAX_WALK_AREAS) && + (thisroom.WalkAreas[onarea].ScalingNear != NOT_VECTOR_SCALED)) { + // We have vector scaling! + // In case the character is off the screen, limit the Y co-ordinate + // to within the area range (otherwise we get silly zoom levels + // that cause Out Of Memory crashes) + if (yy > thisroom.WalkAreas[onarea].Bottom) + yy = thisroom.WalkAreas[onarea].Bottom; + if (yy < thisroom.WalkAreas[onarea].Top) + yy = thisroom.WalkAreas[onarea].Top; + // Work it all out without having to use floats + // Percent = ((y - top) * 100) / (areabottom - areatop) + // Zoom level = ((max - min) * Percent) / 100 + if (thisroom.WalkAreas[onarea].Bottom != thisroom.WalkAreas[onarea].Top) + { + int percent = ((yy - thisroom.WalkAreas[onarea].Top) * 100) + / (thisroom.WalkAreas[onarea].Bottom - thisroom.WalkAreas[onarea].Top); + zoom_level = ((thisroom.WalkAreas[onarea].ScalingNear - thisroom.WalkAreas[onarea].ScalingFar) * (percent)) / 100 + thisroom.WalkAreas[onarea].ScalingFar; + } + else + { + // Special case for 1px tall walkable area: take bottom line scaling + zoom_level = thisroom.WalkAreas[onarea].ScalingNear; + } + zoom_level += 100; + } + else if ((onarea >= 0) & (onarea <= MAX_WALK_AREAS)) + zoom_level = thisroom.WalkAreas[onarea].ScalingFar + 100; + + if (zoom_level == 0) + zoom_level = 100; + + return zoom_level; +} + +void scale_sprite_size(int sppic, int zoom_level, int *newwidth, int *newheight) { + newwidth[0] = (game.SpriteInfos[sppic].Width * zoom_level) / 100; + newheight[0] = (game.SpriteInfos[sppic].Height * zoom_level) / 100; + if (newwidth[0] < 1) + newwidth[0] = 1; + if (newheight[0] < 1) + newheight[0] = 1; +} + +void remove_walkable_areas_from_temp(int fromx, int cwidth, int starty, int endy) { + + fromx = room_to_mask_coord(fromx); + cwidth = room_to_mask_coord(cwidth); + starty = room_to_mask_coord(starty); + endy = room_to_mask_coord(endy); + + int yyy; + if (endy >= walkable_areas_temp->GetHeight()) + endy = walkable_areas_temp->GetHeight() - 1; + if (starty < 0) + starty = 0; + + for (; cwidth > 0; cwidth --) { + for (yyy = starty; yyy <= endy; yyy++) + walkable_areas_temp->PutPixel (fromx, yyy, 0); + fromx ++; + } + +} + +int is_point_in_rect(int x, int y, int left, int top, int right, int bottom) { + if ((x >= left) && (x < right) && (y >= top ) && (y <= bottom)) + return 1; + return 0; +} + +Bitmap *prepare_walkable_areas (int sourceChar) { + // copy the walkable areas to the temp bitmap + walkable_areas_temp->Blit(thisroom.WalkAreaMask.get(), 0,0,0,0,thisroom.WalkAreaMask->GetWidth(),thisroom.WalkAreaMask->GetHeight()); + // if the character who's moving doesn't Bitmap *, don't bother checking + if (sourceChar < 0) ; + else if (game.chars[sourceChar].flags & CHF_NOBLOCKING) + return walkable_areas_temp; + + int ww; + // for each character in the current room, make the area under + // them unwalkable + for (ww = 0; ww < game.numcharacters; ww++) { + if (game.chars[ww].on != 1) continue; + if (game.chars[ww].room != displayed_room) continue; + if (ww == sourceChar) continue; + if (game.chars[ww].flags & CHF_NOBLOCKING) continue; + if (room_to_mask_coord(game.chars[ww].y) >= walkable_areas_temp->GetHeight()) continue; + if (room_to_mask_coord(game.chars[ww].x) >= walkable_areas_temp->GetWidth()) continue; + if ((game.chars[ww].y < 0) || (game.chars[ww].x < 0)) continue; + + CharacterInfo *char1 = &game.chars[ww]; + int cwidth, fromx; + + if (is_char_on_another(sourceChar, ww, &fromx, &cwidth)) + continue; + if ((sourceChar >= 0) && (is_char_on_another(ww, sourceChar, nullptr, nullptr))) + continue; + + remove_walkable_areas_from_temp(fromx, cwidth, char1->get_blocking_top(), char1->get_blocking_bottom()); + } + + // check for any blocking objects in the room, and deal with them + // as well + for (ww = 0; ww < croom->numobj; ww++) { + if (objs[ww].on != 1) continue; + if ((objs[ww].flags & OBJF_SOLID) == 0) + continue; + if (room_to_mask_coord(objs[ww].y) >= walkable_areas_temp->GetHeight()) continue; + if (room_to_mask_coord(objs[ww].x) >= walkable_areas_temp->GetWidth()) continue; + if ((objs[ww].y < 0) || (objs[ww].x < 0)) continue; + + int x1, y1, width, y2; + get_object_blocking_rect(ww, &x1, &y1, &width, &y2); + + // if the character is currently standing on the object, ignore + // it so as to allow him to escape + if ((sourceChar >= 0) && + (is_point_in_rect(game.chars[sourceChar].x, game.chars[sourceChar].y, + x1, y1, x1 + width, y2))) + continue; + + remove_walkable_areas_from_temp(x1, width, y1, y2); + } + + return walkable_areas_temp; +} + +// return the walkable area at the character's feet, taking into account +// that he might just be off the edge of one +int get_walkable_area_at_location(int xx, int yy) { + + int onarea = get_walkable_area_pixel(xx, yy); + + if (onarea < 0) { + // the character has walked off the edge of the screen, so stop them + // jumping up to full size when leaving + if (xx >= thisroom.Width) + onarea = get_walkable_area_pixel(thisroom.Width-1, yy); + else if (xx < 0) + onarea = get_walkable_area_pixel(0, yy); + else if (yy >= thisroom.Height) + onarea = get_walkable_area_pixel(xx, thisroom.Height - 1); + else if (yy < 0) + onarea = get_walkable_area_pixel(xx, 1); + } + if (onarea==0) { + // the path finder sometimes slightly goes into non-walkable areas; + // so check for scaling in adjacent pixels + const int TRYGAP=2; + onarea = get_walkable_area_pixel(xx + TRYGAP, yy); + if (onarea<=0) + onarea = get_walkable_area_pixel(xx - TRYGAP, yy); + if (onarea<=0) + onarea = get_walkable_area_pixel(xx, yy + TRYGAP); + if (onarea<=0) + onarea = get_walkable_area_pixel(xx, yy - TRYGAP); + if (onarea < 0) + onarea = 0; + } + + return onarea; +} + +int get_walkable_area_at_character (int charnum) { + CharacterInfo *chin = &game.chars[charnum]; + return get_walkable_area_at_location(chin->x, chin->y); +} diff --git a/engines/ags/engine/ac/walkablearea.h b/engines/ags/engine/ac/walkablearea.h new file mode 100644 index 000000000000..391d93a920f0 --- /dev/null +++ b/engines/ags/engine/ac/walkablearea.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__WALKABLEAREA_H +#define __AGS_EE_AC__WALKABLEAREA_H + +void redo_walkable_areas(); +int get_walkable_area_pixel(int x, int y); +int get_area_scaling (int onarea, int xx, int yy); +void scale_sprite_size(int sppic, int zoom_level, int *newwidth, int *newheight); +void remove_walkable_areas_from_temp(int fromx, int cwidth, int starty, int endy); +int is_point_in_rect(int x, int y, int left, int top, int right, int bottom); +Common::Bitmap *prepare_walkable_areas (int sourceChar); +int get_walkable_area_at_location(int xx, int yy); +int get_walkable_area_at_character (int charnum); + +#endif // __AGS_EE_AC__WALKABLEAREA_H diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp new file mode 100644 index 000000000000..f254800f4be6 --- /dev/null +++ b/engines/ags/engine/ac/walkbehind.cpp @@ -0,0 +1,143 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/walkbehind.h" +#include "ac/common.h" +#include "ac/common_defines.h" +#include "ac/gamestate.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern RoomStruct thisroom; +extern GameState play; +extern IGraphicsDriver *gfxDriver; + + +char *walkBehindExists = nullptr; // whether a WB area is in this column +int *walkBehindStartY = nullptr, *walkBehindEndY = nullptr; +char noWalkBehindsAtAll = 0; +int walkBehindLeft[MAX_WALK_BEHINDS], walkBehindTop[MAX_WALK_BEHINDS]; +int walkBehindRight[MAX_WALK_BEHINDS], walkBehindBottom[MAX_WALK_BEHINDS]; +IDriverDependantBitmap *walkBehindBitmap[MAX_WALK_BEHINDS]; +int walkBehindsCachedForBgNum = 0; +WalkBehindMethodEnum walkBehindMethod = DrawOverCharSprite; +int walk_behind_baselines_changed = 0; + +void update_walk_behind_images() +{ + int ee, rr; + int bpp = (thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth() + 7) / 8; + Bitmap *wbbmp; + for (ee = 1; ee < MAX_WALK_BEHINDS; ee++) + { + update_polled_stuff_if_runtime(); + + if (walkBehindRight[ee] > 0) + { + wbbmp = BitmapHelper::CreateTransparentBitmap( + (walkBehindRight[ee] - walkBehindLeft[ee]) + 1, + (walkBehindBottom[ee] - walkBehindTop[ee]) + 1, + thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth()); + int yy, startX = walkBehindLeft[ee], startY = walkBehindTop[ee]; + for (rr = startX; rr <= walkBehindRight[ee]; rr++) + { + for (yy = startY; yy <= walkBehindBottom[ee]; yy++) + { + if (thisroom.WalkBehindMask->GetScanLine(yy)[rr] == ee) + { + for (int ii = 0; ii < bpp; ii++) + wbbmp->GetScanLineForWriting(yy - startY)[(rr - startX) * bpp + ii] = thisroom.BgFrames[play.bg_frame].Graphic->GetScanLine(yy)[rr * bpp + ii]; + } + } + } + + update_polled_stuff_if_runtime(); + + if (walkBehindBitmap[ee] != nullptr) + { + gfxDriver->DestroyDDB(walkBehindBitmap[ee]); + } + walkBehindBitmap[ee] = gfxDriver->CreateDDBFromBitmap(wbbmp, false); + delete wbbmp; + } + } + + walkBehindsCachedForBgNum = play.bg_frame; +} + + +void recache_walk_behinds () { + if (walkBehindExists) { + free (walkBehindExists); + free (walkBehindStartY); + free (walkBehindEndY); + } + + walkBehindExists = (char*)malloc (thisroom.WalkBehindMask->GetWidth()); + walkBehindStartY = (int*)malloc (thisroom.WalkBehindMask->GetWidth() * sizeof(int)); + walkBehindEndY = (int*)malloc (thisroom.WalkBehindMask->GetWidth() * sizeof(int)); + noWalkBehindsAtAll = 1; + + int ee,rr,tmm; + const int NO_WALK_BEHIND = 100000; + for (ee = 0; ee < MAX_WALK_BEHINDS; ee++) + { + walkBehindLeft[ee] = NO_WALK_BEHIND; + walkBehindTop[ee] = NO_WALK_BEHIND; + walkBehindRight[ee] = 0; + walkBehindBottom[ee] = 0; + + if (walkBehindBitmap[ee] != nullptr) + { + gfxDriver->DestroyDDB(walkBehindBitmap[ee]); + walkBehindBitmap[ee] = nullptr; + } + } + + update_polled_stuff_if_runtime(); + + // since this is an 8-bit memory bitmap, we can just use direct + // memory access + if ((!thisroom.WalkBehindMask->IsLinearBitmap()) || (thisroom.WalkBehindMask->GetColorDepth() != 8)) + quit("Walk behinds bitmap not linear"); + + for (ee=0;eeGetWidth();ee++) { + walkBehindExists[ee] = 0; + for (rr=0;rrGetHeight();rr++) { + tmm = thisroom.WalkBehindMask->GetScanLine(rr)[ee]; + //tmm = _getpixel(thisroom.WalkBehindMask,ee,rr); + if ((tmm >= 1) && (tmm < MAX_WALK_BEHINDS)) { + if (!walkBehindExists[ee]) { + walkBehindStartY[ee] = rr; + walkBehindExists[ee] = tmm; + noWalkBehindsAtAll = 0; + } + walkBehindEndY[ee] = rr + 1; // +1 to allow bottom line of screen to work + + if (ee < walkBehindLeft[tmm]) walkBehindLeft[tmm] = ee; + if (rr < walkBehindTop[tmm]) walkBehindTop[tmm] = rr; + if (ee > walkBehindRight[tmm]) walkBehindRight[tmm] = ee; + if (rr > walkBehindBottom[tmm]) walkBehindBottom[tmm] = rr; + } + } + } + + if (walkBehindMethod == DrawAsSeparateSprite) + { + update_walk_behind_images(); + } +} diff --git a/engines/ags/engine/ac/walkbehind.h b/engines/ags/engine/ac/walkbehind.h new file mode 100644 index 000000000000..01d1565a27b9 --- /dev/null +++ b/engines/ags/engine/ac/walkbehind.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_AC__WALKBEHIND_H +#define __AGS_EE_AC__WALKBEHIND_H + +enum WalkBehindMethodEnum +{ + DrawOverCharSprite, + DrawAsSeparateSprite, + DrawAsSeparateCharSprite +}; + +void update_walk_behind_images(); +void recache_walk_behinds (); + +#endif // __AGS_EE_AC__WALKBEHIND_H diff --git a/engines/ags/engine/debugging/agseditordebugger.h b/engines/ags/engine/debugging/agseditordebugger.h new file mode 100644 index 000000000000..f53b4d4fc3e8 --- /dev/null +++ b/engines/ags/engine/debugging/agseditordebugger.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H +#define __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H + +struct IAGSEditorDebugger +{ +public: + virtual ~IAGSEditorDebugger() = default; + + virtual bool Initialize() = 0; + virtual void Shutdown() = 0; + virtual bool SendMessageToEditor(const char *message) = 0; + virtual bool IsMessageAvailable() = 0; + // Message will be allocated on heap with malloc + virtual char* GetNextMessage() = 0; +}; + +#endif // __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H diff --git a/engines/ags/engine/debugging/consoleoutputtarget.cpp b/engines/ags/engine/debugging/consoleoutputtarget.cpp new file mode 100644 index 000000000000..2442e9533659 --- /dev/null +++ b/engines/ags/engine/debugging/consoleoutputtarget.cpp @@ -0,0 +1,42 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "consoleoutputtarget.h" +#include "debug/debug_log.h" + +namespace AGS +{ +namespace Engine +{ + +ConsoleOutputTarget::ConsoleOutputTarget() +{ +} + +ConsoleOutputTarget::~ConsoleOutputTarget() = default; + +void ConsoleOutputTarget::PrintMessage(const DebugMessage &msg) +{ + // limit number of characters for console + // TODO: is there a way to find out how many characters can fit in? + debug_line[last_debug_line] = msg.Text.Left(99); + + last_debug_line = (last_debug_line + 1) % DEBUG_CONSOLE_NUMLINES; + if (last_debug_line == first_debug_line) + first_debug_line = (first_debug_line + 1) % DEBUG_CONSOLE_NUMLINES; +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/debugging/consoleoutputtarget.h b/engines/ags/engine/debugging/consoleoutputtarget.h new file mode 100644 index 000000000000..13ae01a394a3 --- /dev/null +++ b/engines/ags/engine/debugging/consoleoutputtarget.h @@ -0,0 +1,44 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// ConsoleOutputTarget prints messages onto in-game console GUI (available +// only if the game was compiled in debug mode). +// +//============================================================================= +#ifndef __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H +#define __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H + +#include "debug/outputhandler.h" + +namespace AGS +{ +namespace Engine +{ + +using Common::String; +using Common::DebugMessage; + +class ConsoleOutputTarget : public AGS::Common::IOutputHandler +{ +public: + ConsoleOutputTarget(); + virtual ~ConsoleOutputTarget(); + + void PrintMessage(const DebugMessage &msg) override; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp new file mode 100644 index 000000000000..4c0807cd1f79 --- /dev/null +++ b/engines/ags/engine/debugging/debug.cpp @@ -0,0 +1,629 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "core/platform.h" +#include "ac/common.h" +#include "ac/gamesetupstruct.h" +#include "ac/runtime_defines.h" +#include "debug/agseditordebugger.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "debug/debugmanager.h" +#include "debug/out.h" +#include "debug/consoleoutputtarget.h" +#include "debug/logfile.h" +#include "debug/messagebuffer.h" +#include "main/config.h" +#include "media/audio/audio_system.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/plugin_engine.h" +#include "script/script.h" +#include "script/script_common.h" +#include "script/cc_error.h" +#include "util/string_utils.h" +#include "util/textstreamwriter.h" + +#if AGS_PLATFORM_OS_WINDOWS +#include +#endif + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern char check_dynamic_sprites_at_exit; +extern int displayed_room; +extern RoomStruct thisroom; +extern char pexbuf[STD_BUFFER_SIZE]; +extern volatile char want_exit, abort_engine; +extern GameSetupStruct game; + + +int editor_debugging_enabled = 0; +int editor_debugging_initialized = 0; +char editor_debugger_instance_token[100]; +IAGSEditorDebugger *editor_debugger = nullptr; +int break_on_next_script_step = 0; +volatile int game_paused_in_debugger = 0; + +#if AGS_PLATFORM_OS_WINDOWS + +#include "platform/windows/debug/namedpipesagsdebugger.h" + +HWND editor_window_handle = 0; + +IAGSEditorDebugger *GetEditorDebugger(const char *instanceToken) +{ + return new NamedPipesAGSDebugger(instanceToken); +} + +#else // AGS_PLATFORM_OS_WINDOWS + +IAGSEditorDebugger *GetEditorDebugger(const char *instanceToken) +{ + return nullptr; +} + +#endif + +int debug_flags=0; + +String debug_line[DEBUG_CONSOLE_NUMLINES]; +int first_debug_line = 0, last_debug_line = 0, display_console = 0; + +float fps = std::numeric_limits::quiet_NaN(); +FPSDisplayMode display_fps = kFPS_Hide; + +std::unique_ptr DebugMsgBuff; +std::unique_ptr DebugLogFile; +std::unique_ptr DebugConsole; + +const String OutputMsgBufID = "buffer"; +const String OutputFileID = "file"; +const String OutputSystemID = "stdout"; +const String OutputGameConsoleID = "console"; + + + +PDebugOutput create_log_output(const String &name, const String &path = "", LogFile::OpenMode open_mode = LogFile::kLogFile_Overwrite) +{ + // Else create new one, if we know this ID + if (name.CompareNoCase(OutputSystemID) == 0) + { + return DbgMgr.RegisterOutput(OutputSystemID, AGSPlatformDriver::GetDriver(), kDbgMsg_None); + } + else if (name.CompareNoCase(OutputFileID) == 0) + { + DebugLogFile.reset(new LogFile()); + String logfile_path = !path.IsEmpty() ? path : String::FromFormat("%s/ags.log", platform->GetAppOutputDirectory()); + if (!DebugLogFile->OpenFile(logfile_path, open_mode)) + return nullptr; + platform->WriteStdOut("Logging to %s", logfile_path.GetCStr()); + auto dbgout = DbgMgr.RegisterOutput(OutputFileID, DebugLogFile.get(), kDbgMsg_None); + return dbgout; + } + else if (name.CompareNoCase(OutputGameConsoleID) == 0) + { + DebugConsole.reset(new ConsoleOutputTarget()); + return DbgMgr.RegisterOutput(OutputGameConsoleID, DebugConsole.get(), kDbgMsg_None); + } + return nullptr; +} + +// Parses a string where each character defines a single log group; returns list of real group names. +std::vector parse_log_multigroup(const String &group_str) +{ + std::vector grplist; + for (size_t i = 0; i < group_str.GetLength(); ++i) + { + switch (group_str[i]) + { + case 'm': grplist.push_back("main"); break; + case 'g': grplist.push_back("game"); break; + case 's': grplist.push_back("script"); break; + case 'c': grplist.push_back("sprcache"); break; + case 'o': grplist.push_back("manobj"); break; + } + } + return grplist; +} + +MessageType get_messagetype_from_string(const String &mt) +{ + int mtype; + if (StrUtil::StringToInt(mt, mtype, 0) == StrUtil::kNoError) + return (MessageType)mtype; + + if (mt.CompareNoCase("alert") == 0) return kDbgMsg_Alert; + else if (mt.CompareNoCase("fatal") == 0) return kDbgMsg_Fatal; + else if (mt.CompareNoCase("error") == 0) return kDbgMsg_Error; + else if (mt.CompareNoCase("warn") == 0) return kDbgMsg_Warn; + else if (mt.CompareNoCase("info") == 0) return kDbgMsg_Info; + else if (mt.CompareNoCase("debug") == 0) return kDbgMsg_Debug; + else if (mt.CompareNoCase("all") == 0) return kDbgMsg_All; + return kDbgMsg_None; +} + +typedef std::pair DbgGroupOption; + +void apply_log_config(const ConfigTree &cfg, const String &log_id, + bool def_enabled, + std::initializer_list def_opts) +{ + String value = INIreadstring(cfg, "log", log_id); + if (value.IsEmpty() && !def_enabled) + return; + + // First test if already registered, if not then try create it + auto dbgout = DbgMgr.GetOutput(log_id); + const bool was_created_earlier = dbgout != nullptr; + if (!dbgout) + { + String path = INIreadstring(cfg, "log", String::FromFormat("%s-path", log_id.GetCStr())); + dbgout = create_log_output(log_id, path); + if (!dbgout) + return; // unknown output type + } + dbgout->ClearGroupFilters(); + + if (value.IsEmpty() || value.CompareNoCase("default") == 0) + { + for (const auto opt : def_opts) + dbgout->SetGroupFilter(opt.first, opt.second); + } + else + { + const auto options = value.Split(','); + for (const auto &opt : options) + { + String groupname = opt.LeftSection(':'); + MessageType msgtype = kDbgMsg_All; + if (opt.GetLength() >= groupname.GetLength() + 1) + { + String msglevel = opt.Mid(groupname.GetLength() + 1); + msglevel.Trim(); + if (msglevel.GetLength() > 0) + msgtype = get_messagetype_from_string(msglevel); + } + groupname.Trim(); + if (groupname.CompareNoCase("all") == 0 || groupname.IsEmpty()) + { + dbgout->SetAllGroupFilters(msgtype); + } + else if (groupname[0u] != '+') + { + dbgout->SetGroupFilter(groupname, msgtype); + } + else + { + const auto groups = parse_log_multigroup(groupname); + for (const auto &g : groups) + dbgout->SetGroupFilter(g, msgtype); + } + } + } + + // Delegate buffered messages to this new output + if (DebugMsgBuff && !was_created_earlier) + DebugMsgBuff->Send(log_id); +} + +void init_debug(const ConfigTree &cfg, bool stderr_only) +{ + // Register outputs + apply_debug_config(cfg); + platform->SetOutputToErr(stderr_only); + + if (stderr_only) + return; + + // Message buffer to save all messages in case we read different log settings from config file + DebugMsgBuff.reset(new MessageBuffer()); + DbgMgr.RegisterOutput(OutputMsgBufID, DebugMsgBuff.get(), kDbgMsg_All); +} + +void apply_debug_config(const ConfigTree &cfg) +{ + apply_log_config(cfg, OutputSystemID, /* defaults */ true, { DbgGroupOption(kDbgGroup_Main, kDbgMsg_Info) }); + bool legacy_log_enabled = INIreadint(cfg, "misc", "log", 0) != 0; + apply_log_config(cfg, OutputFileID, + /* defaults */ + legacy_log_enabled, + { DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Game, kDbgMsg_Info), + DbgGroupOption(kDbgGroup_Script, kDbgMsg_All), +#ifdef DEBUG_SPRITECACHE + DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_All), +#else + DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_Info), +#endif +#ifdef DEBUG_MANAGED_OBJECTS + DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_All), +#else + DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_Info), +#endif + }); + + // Init game console if the game was compiled in Debug mode + if (game.options[OPT_DEBUGMODE] != 0) + { + apply_log_config(cfg, OutputGameConsoleID, + /* defaults */ + true, + { DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Game, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Script, kDbgMsg_All) + }); + debug_set_console(true); + } + + // If the game was compiled in Debug mode *and* there's no regular file log, + // then open "warnings.log" for printing script warnings. + if (game.options[OPT_DEBUGMODE] != 0 && !DebugLogFile) + { + auto dbgout = create_log_output(OutputFileID, "warnings.log", LogFile::kLogFile_OverwriteAtFirstMessage); + if (dbgout) + { + dbgout->SetGroupFilter(kDbgGroup_Game, kDbgMsg_Warn); + dbgout->SetGroupFilter(kDbgGroup_Script, kDbgMsg_Warn); + } + } + + // We don't need message buffer beyond this point + DbgMgr.UnregisterOutput(OutputMsgBufID); + DebugMsgBuff.reset(); +} + +void shutdown_debug() +{ + // Shutdown output subsystem + DbgMgr.UnregisterAll(); + + DebugMsgBuff.reset(); + DebugLogFile.reset(); + DebugConsole.reset(); +} + +void debug_set_console(bool enable) +{ + if (DebugConsole) + DbgMgr.GetOutput(OutputGameConsoleID)->SetEnabled(enable); +} + +// Prepends message text with current room number and running script info, then logs result +void debug_script_print(const String &msg, MessageType mt) +{ + String script_ref; + ccInstance *curinst = ccInstance::GetCurrentInstance(); + if (curinst != nullptr) { + String scriptname; + if (curinst->instanceof == gamescript) + scriptname = "G "; + else if (curinst->instanceof == thisroom.CompiledScript) + scriptname = "R "; + else if (curinst->instanceof == dialogScriptsScript) + scriptname = "D "; + else + scriptname = "? "; + script_ref.Format("[%s%d]", scriptname.GetCStr(), currentline); + } + + Debug::Printf(kDbgGroup_Game, mt, "(room:%d)%s %s", displayed_room, script_ref.GetCStr(), msg.GetCStr()); +} + +void debug_script_warn(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + String full_msg = String::FromFormatV(msg, ap); + va_end(ap); + debug_script_print(full_msg, kDbgMsg_Warn); +} + +void debug_script_log(const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + String full_msg = String::FromFormatV(msg, ap); + va_end(ap); + debug_script_print(full_msg, kDbgMsg_Debug); +} + + +String get_cur_script(int numberOfLinesOfCallStack) +{ + String callstack; + ccInstance *sci = ccInstance::GetCurrentInstance(); + if (sci) + callstack = sci->GetCallStack(numberOfLinesOfCallStack); + if (callstack.IsEmpty()) + callstack = ccErrorCallStack; + return callstack; +} + +bool get_script_position(ScriptPosition &script_pos) +{ + ccInstance *cur_instance = ccInstance::GetCurrentInstance(); + if (cur_instance) + { + cur_instance->GetScriptPosition(script_pos); + return true; + } + return false; +} + +struct Breakpoint +{ + char scriptName[80]; + int lineNumber; +}; + +std::vector breakpoints; +int numBreakpoints = 0; + +bool send_message_to_editor(const char *msg, const char *errorMsg) +{ + String callStack = get_cur_script(25); + if (callStack.IsEmpty()) + return false; + + char messageToSend[STD_BUFFER_SIZE]; + sprintf(messageToSend, "", msg); +#if AGS_PLATFORM_OS_WINDOWS + sprintf(&messageToSend[strlen(messageToSend)], " %d ", (int)win_get_window()); +#endif + sprintf(&messageToSend[strlen(messageToSend)], " ", callStack.GetCStr()); + if (errorMsg != nullptr) + { + sprintf(&messageToSend[strlen(messageToSend)], " ", errorMsg); + } + strcat(messageToSend, ""); + + editor_debugger->SendMessageToEditor(messageToSend); + + return true; +} + +bool send_message_to_editor(const char *msg) +{ + return send_message_to_editor(msg, nullptr); +} + +bool init_editor_debugging() +{ +#if AGS_PLATFORM_OS_WINDOWS + editor_debugger = GetEditorDebugger(editor_debugger_instance_token); +#else + // Editor isn't ported yet + editor_debugger = nullptr; +#endif + + if (editor_debugger == nullptr) + quit("editor_debugger is NULL but debugger enabled"); + + if (editor_debugger->Initialize()) + { + editor_debugging_initialized = 1; + + // Wait for the editor to send the initial breakpoints + // and then its READY message + while (check_for_messages_from_editor() != 2) + { + platform->Delay(10); + } + + send_message_to_editor("START"); + return true; + } + + return false; +} + +int check_for_messages_from_editor() +{ + if (editor_debugger->IsMessageAvailable()) + { + char *msg = editor_debugger->GetNextMessage(); + if (msg == nullptr) + { + return 0; + } + + if (strncmp(msg, "Delay(10); + } +#endif + return true; +} + + +void break_into_debugger() +{ +#if AGS_PLATFORM_OS_WINDOWS + + if (editor_window_handle != NULL) + SetForegroundWindow(editor_window_handle); + + send_message_to_editor("BREAK"); + game_paused_in_debugger = 1; + + while (game_paused_in_debugger) + { + update_polled_stuff_if_runtime(); + platform->YieldCPU(); + } + +#endif +} + +int scrDebugWait = 0; +extern int pluginsWantingDebugHooks; + +// allow LShift to single-step, RShift to pause flow +void scriptDebugHook (ccInstance *ccinst, int linenum) { + + if (pluginsWantingDebugHooks > 0) { + // a plugin is handling the debugging + String scname = GetScriptName(ccinst); + pl_run_plugin_debug_hooks(scname, linenum); + return; + } + + // no plugin, use built-in debugger + + if (ccinst == nullptr) + { + // come out of script + return; + } + + if (break_on_next_script_step) + { + break_on_next_script_step = 0; + break_into_debugger(); + return; + } + + const char *scriptName = ccinst->runningInst->instanceof->GetSectionName(ccinst->pc); + + for (int i = 0; i < numBreakpoints; i++) + { + if ((breakpoints[i].lineNumber == linenum) && + (strcmp(breakpoints[i].scriptName, scriptName) == 0)) + { + break_into_debugger(); + break; + } + } +} + +int scrlockWasDown = 0; + +void check_debug_keys() { + if (play.debug_mode) { + // do the run-time script debugging + + if ((!key[KEY_SCRLOCK]) && (scrlockWasDown)) + scrlockWasDown = 0; + else if ((key[KEY_SCRLOCK]) && (!scrlockWasDown)) { + + break_on_next_script_step = 1; + scrlockWasDown = 1; + } + + } + +} diff --git a/engines/ags/engine/debugging/debug_log.h b/engines/ags/engine/debugging/debug_log.h new file mode 100644 index 000000000000..268b846aecb1 --- /dev/null +++ b/engines/ags/engine/debugging/debug_log.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_DEBUG_LOG_H +#define __AC_DEBUG_LOG_H + +#include "script/cc_instance.h" +#include "ac/runtime_defines.h" +#include "ac/gamestate.h" +#include "platform/base/agsplatformdriver.h" +#include "util/ini_util.h" + +void init_debug(const AGS::Common::ConfigTree &cfg, bool stderr_only); +void apply_debug_config(const AGS::Common::ConfigTree &cfg); +void shutdown_debug(); + +void debug_set_console(bool enable); + +// debug_script_log prints debug warnings tagged with kDbgGroup_Script, +// prepending it with current room number and script position identification +void debug_script_warn(const char *texx, ...); +// debug_script_log prints debug message tagged with kDbgGroup_Script, +// prepending it with current room number and script position identification +void debug_script_log(const char *msg, ...); +void quitprintf(const char *texx, ...); +bool init_editor_debugging(); + +// allow LShift to single-step, RShift to pause flow +void scriptDebugHook (ccInstance *ccinst, int linenum) ; + +extern AGS::Common::String debug_line[DEBUG_CONSOLE_NUMLINES]; +extern int first_debug_line, last_debug_line, display_console; + + +extern AGSPlatformDriver *platform; + +#endif // __AC_DEBUG_LOG_H diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h new file mode 100644 index 000000000000..77c85d6a9aef --- /dev/null +++ b/engines/ags/engine/debugging/debugger.h @@ -0,0 +1,60 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_DEBUGGER_H +#define __AC_DEBUGGER_H + +#include "util/string.h" + +struct IAGSEditorDebugger; +struct ScriptPosition; + +extern int editor_debugging_enabled; +extern int editor_debugging_initialized; +extern char editor_debugger_instance_token[100]; +extern IAGSEditorDebugger *editor_debugger; +extern int break_on_next_script_step; + +int check_for_messages_from_editor(); +bool send_message_to_editor(const char *msg); +bool send_exception_to_editor(const char *qmsg); +// Returns current script's location and callstack +AGS::Common::String get_cur_script(int numberOfLinesOfCallStack); +bool get_script_position(ScriptPosition &script_pos); +void check_debug_keys(); + +#define DBG_NOIFACE 1 +#define DBG_NODRAWSPRITES 2 +#define DBG_NOOBJECTS 4 +#define DBG_NOUPDATE 8 +#define DBG_NOSFX 0x10 +#define DBG_NOMUSIC 0x20 +#define DBG_NOSCRIPT 0x40 +#define DBG_DBGSCRIPT 0x80 +#define DBG_DEBUGMODE 0x100 +#define DBG_REGONLY 0x200 +#define DBG_NOVIDEO 0x400 + +enum FPSDisplayMode +{ + kFPS_Hide = 0, // hid by the script/user command + kFPS_Display = 1, // shown by the script/user command + kFPS_Forced = 2 // forced shown by the engine arg +}; + +extern float fps; +extern FPSDisplayMode display_fps; +extern int debug_flags; + +#endif // __AC_DEBUGGER_H diff --git a/engines/ags/engine/debugging/dummyagsdebugger.h b/engines/ags/engine/debugging/dummyagsdebugger.h new file mode 100644 index 000000000000..38c026348117 --- /dev/null +++ b/engines/ags/engine/debugging/dummyagsdebugger.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_DUMMYAGSDEBUGGER_H +#define __AC_DUMMYAGSDEBUGGER_H + +#include "debug/debugger.h" + +struct DummyAGSDebugger : IAGSEditorDebugger +{ +public: + + virtual bool Initialize() override { return false; } + virtual void Shutdown() override { } + virtual bool SendMessageToEditor(const char *message) override { return false; } + virtual bool IsMessageAvailable() override { return false; } + virtual char* GetNextMessage() override { return NULL; } +}; + +#endif // __AC_DUMMYAGSDEBUGGER_H diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.cpp b/engines/ags/engine/debugging/filebasedagsdebugger.cpp new file mode 100644 index 000000000000..263798725e0d --- /dev/null +++ b/engines/ags/engine/debugging/filebasedagsdebugger.cpp @@ -0,0 +1,77 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "debug/filebasedagsdebugger.h" +#include "ac/file.h" // filelength() +#include "util/stream.h" +#include "util/textstreamwriter.h" +#include "util/wgt2allg.h" // exists() +#include "platform/base/agsplatformdriver.h" + +using AGS::Common::Stream; +using AGS::Common::TextStreamWriter; + +const char* SENT_MESSAGE_FILE_NAME = "dbgrecv.tmp"; + +bool FileBasedAGSDebugger::Initialize() +{ + if (exists(SENT_MESSAGE_FILE_NAME)) + { + ::remove(SENT_MESSAGE_FILE_NAME); + } + return true; +} + +void FileBasedAGSDebugger::Shutdown() +{ +} + +bool FileBasedAGSDebugger::SendMessageToEditor(const char *message) +{ + while (exists(SENT_MESSAGE_FILE_NAME)) + { + platform->YieldCPU(); + } + + Stream *out = Common::File::CreateFile(SENT_MESSAGE_FILE_NAME); + // CHECKME: originally the file was opened as "wb" for some reason, + // which means the message should be written as a binary array; + // or shouldn't it? + out->Write(message, strlen(message)); + delete out; + return true; +} + +bool FileBasedAGSDebugger::IsMessageAvailable() +{ + return (exists("dbgsend.tmp") != 0); +} + +char* FileBasedAGSDebugger::GetNextMessage() +{ + Stream *in = Common::File::OpenFileRead("dbgsend.tmp"); + if (in == nullptr) + { + // check again, because the editor might have deleted the file in the meantime + return nullptr; + } + int fileSize = in->GetLength(); + char *msg = (char*)malloc(fileSize + 1); + in->Read(msg, fileSize); + delete in; + ::remove("dbgsend.tmp"); + msg[fileSize] = 0; + return msg; +} diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.h b/engines/ags/engine/debugging/filebasedagsdebugger.h new file mode 100644 index 000000000000..3fcda091b541 --- /dev/null +++ b/engines/ags/engine/debugging/filebasedagsdebugger.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_FILEBASEDAGSDEBUGGER_H +#define __AC_FILEBASEDAGSDEBUGGER_H + +#include "debug/agseditordebugger.h" + +struct FileBasedAGSDebugger : IAGSEditorDebugger +{ +public: + + bool Initialize() override; + void Shutdown() override; + bool SendMessageToEditor(const char *message) override; + bool IsMessageAvailable() override; + char* GetNextMessage() override; + +}; + +extern const char* SENT_MESSAGE_FILE_NAME; + +#endif // __AC_FILEBASEDAGSDEBUGGER_H diff --git a/engines/ags/engine/debugging/logfile.cpp b/engines/ags/engine/debugging/logfile.cpp new file mode 100644 index 000000000000..4dad1cc4fda7 --- /dev/null +++ b/engines/ags/engine/debugging/logfile.cpp @@ -0,0 +1,88 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "debug/logfile.h" +#include "util/file.h" +#include "util/stream.h" + + +namespace AGS +{ +namespace Engine +{ + +using namespace Common; + +LogFile::LogFile() + : _openMode(kLogFile_Overwrite) +{ +} + +void LogFile::PrintMessage(const DebugMessage &msg) +{ + if (!_file.get()) + { + if (_filePath.IsEmpty()) + return; + _file.reset(File::OpenFile(_filePath, _openMode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, + Common::kFile_Write)); + if (!_file) + { + Debug::Printf("Unable to write log to '%s'.", _filePath.GetCStr()); + _filePath = ""; + return; + } + } + + if (!msg.GroupName.IsEmpty()) + { + _file->Write(msg.GroupName, msg.GroupName.GetLength()); + _file->Write(" : ", 3); + } + _file->Write(msg.Text, msg.Text.GetLength()); + _file->WriteInt8('\n'); + // We should flush after every write to the log; this will make writing + // bit slower, but will increase the chances that all latest output + // will get to the disk in case of program crash. + _file->Flush(); +} + +bool LogFile::OpenFile(const String &file_path, OpenMode open_mode) +{ + CloseFile(); + + _filePath = file_path; + _openMode = open_mode; + if (open_mode == OpenMode::kLogFile_OverwriteAtFirstMessage) + { + return File::TestWriteFile(_filePath); + } + else + { + _file.reset(File::OpenFile(file_path, + open_mode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, + Common::kFile_Write)); + return _file.get() != nullptr; + } +} + +void LogFile::CloseFile() +{ + _file.reset(); + _filePath.Empty(); +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h new file mode 100644 index 000000000000..702842891fdc --- /dev/null +++ b/engines/ags/engine/debugging/logfile.h @@ -0,0 +1,78 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// LogFile, the IOutputHandler implementation that writes to file. +// +// When created LogFile may open file right away or delay doing this. +// In the latter case it will buffer output up to certain size limit. +// When told to open the file, it will first flush its buffer. This allows to +// log events even before the log path is decided (for example, before or +// during reading configuration and/or parsing command line). +// +//============================================================================= +#ifndef __AGS_EE_DEBUG__LOGFILE_H +#define __AGS_EE_DEBUG__LOGFILE_H + +#include +#include "debug/outputhandler.h" + +namespace AGS +{ + +namespace Common { class Stream; } + +namespace Engine +{ + +using Common::DebugMessage; +using Common::Stream; +using Common::String; + +class LogFile : public AGS::Common::IOutputHandler +{ +public: + enum OpenMode + { + kLogFile_Overwrite, + kLogFile_OverwriteAtFirstMessage, + kLogFile_Append + }; + +public: + LogFile(); + + void PrintMessage(const Common::DebugMessage &msg) override; + + // Open file using given file path, optionally appending if one exists + // + // TODO: filepath parameter here may be actually used as a pattern + // or prefix, while the actual filename could be made by combining + // this prefix with current date, game name, and similar additional + // useful information. Whether this is to be determined here or on + // high-level side remains a question. + // + bool OpenFile(const String &file_path, OpenMode open_mode = kLogFile_Overwrite); + // Close file + void CloseFile(); + +private: + std::unique_ptr _file; + String _filePath; + OpenMode _openMode; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_DEBUG__LOGFILE_H diff --git a/engines/ags/engine/debugging/messagebuffer.cpp b/engines/ags/engine/debugging/messagebuffer.cpp new file mode 100644 index 000000000000..dc336e7a60b8 --- /dev/null +++ b/engines/ags/engine/debugging/messagebuffer.cpp @@ -0,0 +1,67 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "debug/debugmanager.h" +#include "debug/messagebuffer.h" + +namespace AGS +{ +namespace Engine +{ + +using namespace Common; + +MessageBuffer::MessageBuffer(size_t buffer_limit) + : _bufferLimit(buffer_limit) + , _msgLost(0) +{ +} + +void MessageBuffer::PrintMessage(const DebugMessage &msg) +{ + if (_buffer.size() < _bufferLimit) + _buffer.push_back(msg); + else + _msgLost++; +} + +void MessageBuffer::Clear() +{ + _buffer.clear(); + _msgLost = 0; +} + +void MessageBuffer::Send(const String &out_id) +{ + if (_buffer.empty()) + return; + if (_msgLost > 0) + { + DebugGroup gr = DbgMgr.GetGroup(kDbgGroup_Main); + DbgMgr.SendMessage(out_id, DebugMessage(String::FromFormat("WARNING: output %s lost exceeding buffer: %u debug messages\n", out_id.GetCStr(), (unsigned)_msgLost), + gr.UID.ID, gr.OutputName, kDbgMsg_All)); + } + for (std::vector::const_iterator it = _buffer.begin(); it != _buffer.end(); ++it) + { + DbgMgr.SendMessage(out_id, *it); + } +} + +void MessageBuffer::Flush(const String &out_id) +{ + Send(out_id); + Clear(); +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h new file mode 100644 index 000000000000..b8a31a2cb826 --- /dev/null +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -0,0 +1,57 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// MessageBuffer, the IOutputHandler implementation that stores debug messages +// in a vector. Could be handy if you need to temporarily buffer debug log +// while specifying how to actually print it. +// +//============================================================================= +#ifndef __AGS_EE_DEBUG__MESSAGEBUFFER_H +#define __AGS_EE_DEBUG__MESSAGEBUFFER_H + +#include +#include "debug/outputhandler.h" + +namespace AGS +{ +namespace Engine +{ + +using Common::String; +using Common::DebugMessage; + +class MessageBuffer : public AGS::Common::IOutputHandler +{ +public: + MessageBuffer(size_t buffer_limit = 1024); + + void PrintMessage(const DebugMessage &msg) override; + + // Clears buffer + void Clear(); + // Sends buffered messages into given output target + void Send(const String &out_id); + // Sends buffered messages into given output target and clears buffer + void Flush(const String &out_id); + +private: + const size_t _bufferLimit; + std::vector _buffer; + size_t _msgLost; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_DEBUG__MESSAGEBUFFER_H diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp new file mode 100644 index 000000000000..b939916fe99b --- /dev/null +++ b/engines/ags/engine/device/mousew32.cpp @@ -0,0 +1,387 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// MOUSELIBW32.CPP +// +// Library of mouse functions for graphics and text mode +// +// (c) 1994 Chris Jones +// Win32 (allegro) update (c) 1999 Chris Jones +// +//============================================================================= + +#include "core/platform.h" + +#define AGS_SIMULATE_RIGHT_CLICK (AGS_PLATFORM_OS_MACOS) + +#if AGS_PLATFORM_OS_WINDOWS +#include +#include +#include +#endif + +#include "util/wgt2allg.h" + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#include "ac/gamestate.h" +#include "debug/out.h" +#include "device/mousew32.h" +#include "gfx/bitmap.h" +#include "gfx/gfx_util.h" +#include "main/graphics_mode.h" +#include "platform/base/agsplatformdriver.h" +#include "util/math.h" +#if AGS_SIMULATE_RIGHT_CLICK +#include "ac/sys_events.h" // j for ags_iskeypressed +#endif + +using namespace AGS::Common; +using namespace AGS::Engine; + + +extern char lib_file_name[13]; + +const char *mouselibcopyr = "MouseLib32 (c) 1994, 1998 Chris Jones"; +const int NONE = -1, LEFT = 0, RIGHT = 1, MIDDLE = 2; +char currentcursor = 0; +// virtual mouse cursor coordinates +int mousex = 0, mousey = 0, numcurso = -1, hotx = 0, hoty = 0; +// real mouse coordinates and bounds +int real_mouse_x = 0, real_mouse_y = 0; +int boundx1 = 0, boundx2 = 99999, boundy1 = 0, boundy2 = 99999; +int disable_mgetgraphpos = 0; +char ignore_bounds = 0; +extern char alpha_blend_cursor ; +Bitmap *mousecurs[MAXCURSORS]; +extern color palette[256]; +extern volatile bool switched_away; + +namespace Mouse +{ + // Tells whether mouse was locked to the game window + bool LockedToWindow = false; + + // Screen rectangle, in which the mouse movement is controlled by engine + Rect ControlRect; + // Mouse control enabled flag + bool ControlEnabled = false; + // Flag that tells whether the mouse must be forced to stay inside control rect + bool ConfineInCtrlRect = false; + // Mouse speed value provided by user + float SpeedVal = 1.f; + // Mouse speed unit + float SpeedUnit = 1.f; + // Actual speed factor (cached) + float Speed = 1.f; + + + void AdjustPosition(int &x, int &y); +} + +void mgraphconfine(int x1, int y1, int x2, int y2) +{ + Mouse::ControlRect = Rect(x1, y1, x2, y2); + set_mouse_range(Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom); + Debug::Printf("Mouse confined: (%d,%d)-(%d,%d) (%dx%d)", + Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom, + Mouse::ControlRect.GetWidth(), Mouse::ControlRect.GetHeight()); +} + +void mgetgraphpos() +{ + poll_mouse(); + if (disable_mgetgraphpos) + { + // The cursor coordinates are provided from alternate source; + // in this case we completely ignore actual cursor movement. + if (!ignore_bounds && + (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) + { + mousex = Math::Clamp(mousex, boundx1, boundx2); + mousey = Math::Clamp(mousey, boundy1, boundy2); + msetgraphpos(mousex, mousey); + } + return; + } + + if (!switched_away && Mouse::ControlEnabled) + { + // Control mouse movement by querying mouse mickeys (movement deltas) + // and applying them to saved mouse coordinates. + int mickey_x, mickey_y; + get_mouse_mickeys(&mickey_x, &mickey_y); + + // Apply mouse speed + int dx = Mouse::Speed * mickey_x; + int dy = Mouse::Speed * mickey_y; + + // + // Perform actual cursor update + //--------------------------------------------------------------------- + // If the real cursor is inside the control rectangle (read - game window), + // then apply sensitivity factors and adjust real cursor position + if (Mouse::ControlRect.IsInside(real_mouse_x + dx, real_mouse_y + dy)) + { + real_mouse_x += dx; + real_mouse_y += dy; + position_mouse(real_mouse_x, real_mouse_y); + } + // Otherwise, if real cursor was moved outside the control rect, yet we + // are required to confine cursor inside one, then adjust cursor position + // to stay inside the rect's bounds. + else if (Mouse::ConfineInCtrlRect) + { + real_mouse_x = Math::Clamp(real_mouse_x + dx, Mouse::ControlRect.Left, Mouse::ControlRect.Right); + real_mouse_y = Math::Clamp(real_mouse_y + dy, Mouse::ControlRect.Top, Mouse::ControlRect.Bottom); + position_mouse(real_mouse_x, real_mouse_y); + } + // Lastly, if the real cursor is out of the control rect, simply add + // actual movement to keep up with the system cursor coordinates. + else + { + real_mouse_x += mickey_x; + real_mouse_y += mickey_y; + } + + // Do not update the game cursor if the real cursor is beyond the control rect + if (!Mouse::ControlRect.IsInside(real_mouse_x, real_mouse_y)) + return; + } + else + { + // Save real cursor coordinates provided by system + real_mouse_x = mouse_x; + real_mouse_y = mouse_y; + } + + // Set new in-game cursor position + mousex = real_mouse_x; + mousey = real_mouse_y; + + if (!ignore_bounds && + (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) + { + mousex = Math::Clamp(mousex, boundx1, boundx2); + mousey = Math::Clamp(mousey, boundy1, boundy2); + msetgraphpos(mousex, mousey); + } + + // Convert to virtual coordinates + Mouse::AdjustPosition(mousex, mousey); +} + +void msetcursorlimit(int x1, int y1, int x2, int y2) +{ + boundx1 = x1; + boundy1 = y1; + boundx2 = x2; + boundy2 = y2; +} + +int hotxwas = 0, hotywas = 0; +void domouse(int str) +{ + /* + TO USE THIS ROUTINE YOU MUST LOAD A MOUSE CURSOR USING mloadcursor. + YOU MUST ALSO REMEMBER TO CALL mfreemem AT THE END OF THE PROGRAM. + */ + int poow = mousecurs[currentcursor]->GetWidth(); + int pooh = mousecurs[currentcursor]->GetHeight(); + int smx = mousex - hotxwas, smy = mousey - hotywas; + const Rect &viewport = play.GetMainViewport(); + + mgetgraphpos(); + mousex -= hotx; + mousey -= hoty; + + if (mousex + poow >= viewport.GetWidth()) + poow = viewport.GetWidth() - mousex; + + if (mousey + pooh >= viewport.GetHeight()) + pooh = viewport.GetHeight() - mousey; + + mousex += hotx; + mousey += hoty; + hotxwas = hotx; + hotywas = hoty; +} + +int ismouseinbox(int lf, int tp, int rt, int bt) +{ + if ((mousex >= lf) & (mousex <= rt) & (mousey >= tp) & (mousey <= bt)) + return TRUE; + else + return FALSE; +} + +void mfreemem() +{ + for (int re = 0; re < numcurso; re++) { + delete mousecurs[re]; + } +} + + + + +void mloadwcursor(char *namm) +{ + color dummypal[256]; + if (wloadsprites(&dummypal[0], namm, mousecurs, 0, MAXCURSORS)) { + //printf("C_Load_wCursor: Error reading mouse cursor file\n"); + exit(1); + } +} + +int butwas = 0; +int mgetbutton() +{ + int toret = NONE; + poll_mouse(); + int butis = mouse_b; + + if ((butis > 0) & (butwas > 0)) + return NONE; // don't allow holding button down + + if (butis & 1) + { + toret = LEFT; +#if AGS_SIMULATE_RIGHT_CLICK + // j Ctrl-left click should be right-click + if (ags_iskeypressed(__allegro_KEY_LCONTROL) || ags_iskeypressed(__allegro_KEY_RCONTROL)) + { + toret = RIGHT; + } +#endif + } + else if (butis & 2) + toret = RIGHT; + else if (butis & 4) + toret = MIDDLE; + + butwas = butis; + return toret; +} + +const int MB_ARRAY[3] = { 1, 2, 4 }; +int misbuttondown(int buno) +{ + poll_mouse(); + if (mouse_b & MB_ARRAY[buno]) + return TRUE; + return FALSE; +} + +void msetgraphpos(int xa, int ya) +{ + real_mouse_x = xa; + real_mouse_y = ya; + position_mouse(real_mouse_x, real_mouse_y); +} + +void msethotspot(int xx, int yy) +{ + hotx = xx; // mousex -= hotx; mousey -= hoty; + hoty = yy; // mousex += hotx; mousey += hoty; +} + +int minstalled() +{ + return install_mouse(); +} + +void Mouse::AdjustPosition(int &x, int &y) +{ + x = GameScaling.X.UnScalePt(x) - play.GetMainViewport().Left; + y = GameScaling.Y.UnScalePt(y) - play.GetMainViewport().Top; +} + +void Mouse::SetGraphicArea() +{ + Rect dst_r = GameScaling.ScaleRange(play.GetMainViewport()); + mgraphconfine(dst_r.Left, dst_r.Top, dst_r.Right, dst_r.Bottom); +} + +void Mouse::SetMoveLimit(const Rect &r) +{ + Rect src_r = OffsetRect(r, play.GetMainViewport().GetLT()); + Rect dst_r = GameScaling.ScaleRange(src_r); + msetcursorlimit(dst_r.Left, dst_r.Top, dst_r.Right, dst_r.Bottom); +} + +void Mouse::SetPosition(const Point p) +{ + msetgraphpos(GameScaling.X.ScalePt(p.X + play.GetMainViewport().Left), GameScaling.Y.ScalePt(p.Y + play.GetMainViewport().Top)); +} + +bool Mouse::IsLockedToWindow() +{ + return LockedToWindow; +} + +bool Mouse::TryLockToWindow() +{ + if (!LockedToWindow) + LockedToWindow = platform->LockMouseToWindow(); + return LockedToWindow; +} + +void Mouse::UnlockFromWindow() +{ + platform->UnlockMouse(); + LockedToWindow = false; +} + +void Mouse::EnableControl(bool confine) +{ + ControlEnabled = true; + ConfineInCtrlRect = confine; +} + +void Mouse::DisableControl() +{ + ControlEnabled = false; + ConfineInCtrlRect = false; +} + +bool Mouse::IsControlEnabled() +{ + return ControlEnabled; +} + +void Mouse::SetSpeedUnit(float f) +{ + SpeedUnit = f; + Speed = SpeedVal / SpeedUnit; +} + +float Mouse::GetSpeedUnit() +{ + return SpeedUnit; +} + +void Mouse::SetSpeed(float speed) +{ + SpeedVal = Math::Max(0.f, speed); + Speed = SpeedUnit * SpeedVal; +} + +float Mouse::GetSpeed() +{ + return SpeedVal; +} diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h new file mode 100644 index 000000000000..165dfd80db27 --- /dev/null +++ b/engines/ags/engine/device/mousew32.h @@ -0,0 +1,90 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// MOUSELIBW32.CPP +// +// Library of mouse functions for graphics and text mode +// +// (c) 1994 Chris Jones +// Win32 (allegro) update (c) 1999 Chris Jones +// +//============================================================================= + +#include "util/geometry.h" + +#define MAXCURSORS 20 + +#include "util/geometry.h" + +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; // FIXME later + +void msetgraphpos(int,int); +// Sets the area of the screen within which the mouse can move +void mgraphconfine(int x1, int y1, int x2, int y2); +void mgetgraphpos(); +// Sets the area of the game frame (zero-based coordinates) where the mouse cursor is allowed to move; +// this function was meant to be used to achieve gameplay effect +void msetcursorlimit(int x1, int y1, int x2, int y2); +int ismouseinbox(int lf, int tp, int rt, int bt); +void mfreemem(); +void mloadwcursor(char *namm); +void msetgraphpos(int xa, int ya); +void msethotspot(int xx, int yy); +int minstalled(); + +namespace Mouse +{ + // Get if mouse is locked to the game window + bool IsLockedToWindow(); + // Try locking mouse to the game window + bool TryLockToWindow(); + // Unlock mouse from the game window + void UnlockFromWindow(); + + // Enable mouse movement control + void EnableControl(bool confine); + // Disable mouse movement control + void DisableControl(); + // Tell if the mouse movement control is enabled + bool IsControlEnabled(); + // Set base speed factor, which would serve as a mouse speed unit + void SetSpeedUnit(float f); + // Get base speed factor + float GetSpeedUnit(); + // Set speed factors + void SetSpeed(float speed); + // Get speed factor + float GetSpeed(); +} + +namespace Mouse +{ + // Updates limits of the area inside which the standard OS cursor is not shown; + // uses game's main viewport (in native coordinates) to calculate real area on screen + void SetGraphicArea(); + // Limits the area where the game cursor can move on virtual screen; + // parameter must be in native game coordinates + void SetMoveLimit(const Rect &r); + // Set actual OS cursor position on screen; parameter must be in native game coordinates + void SetPosition(const Point p); +} + + +extern int mousex, mousey; +extern int hotx, hoty; +extern int disable_mgetgraphpos; +extern char currentcursor; + +extern Common::Bitmap *mousecurs[MAXCURSORS]; diff --git a/engines/ags/engine/font/fonts_engine.cpp b/engines/ags/engine/font/fonts_engine.cpp new file mode 100644 index 000000000000..ebb17c04497b --- /dev/null +++ b/engines/ags/engine/font/fonts_engine.cpp @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Implementation from acfonts.cpp specific to Engine runtime +// +//============================================================================= + +#include +#include "ac/gamesetupstruct.h" + +extern int our_eip; +extern GameSetupStruct game; + +//============================================================================= +// Engine-specific implementation split out of acfonts.cpp +//============================================================================= + +void set_our_eip(int eip) +{ + our_eip = eip; +} + +int get_our_eip() +{ + return our_eip; +} diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp new file mode 100644 index 000000000000..4aabcacbcb6e --- /dev/null +++ b/engines/ags/engine/game/game_init.cpp @@ -0,0 +1,477 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/character.h" +#include "ac/charactercache.h" +#include "ac/dialog.h" +#include "ac/draw.h" +#include "ac/file.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/gui.h" +#include "ac/movelist.h" +#include "ac/dynobj/all_dynamicclasses.h" +#include "ac/dynobj/all_scriptclasses.h" +#include "ac/statobj/agsstaticobject.h" +#include "ac/statobj/staticarray.h" +#include "debug/debug_log.h" +#include "debug/out.h" +#include "font/agsfontrenderer.h" +#include "font/fonts.h" +#include "game/game_init.h" +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "gui/guilabel.h" +#include "plugin/plugin_engine.h" +#include "script/cc_error.h" +#include "script/exports.h" +#include "script/script.h" +#include "script/script_runtime.h" +#include "util/string_utils.h" +#include "media/audio/audio_system.h" + +using namespace Common; +using namespace Engine; + +extern GameSetupStruct game; +extern int actSpsCount; +extern Bitmap **actsps; +extern IDriverDependantBitmap* *actspsbmp; +extern Bitmap **actspswb; +extern IDriverDependantBitmap* *actspswbbmp; +extern CachedActSpsData* actspswbcache; +extern CharacterCache *charcache; + +extern CCGUIObject ccDynamicGUIObject; +extern CCCharacter ccDynamicCharacter; +extern CCHotspot ccDynamicHotspot; +extern CCRegion ccDynamicRegion; +extern CCInventory ccDynamicInv; +extern CCGUI ccDynamicGUI; +extern CCObject ccDynamicObject; +extern CCDialog ccDynamicDialog; +extern CCAudioChannel ccDynamicAudio; +extern CCAudioClip ccDynamicAudioClip; +extern ScriptString myScriptStringImpl; +extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; +extern ScriptGUI *scrGui; +extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; +extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; +extern ScriptInvItem scrInv[MAX_INV]; +extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; + +extern ScriptDialogOptionsRendering ccDialogOptionsRendering; +extern ScriptDrawingSurface* dialogOptionsRenderingSurface; + +extern AGSStaticObject GlobalStaticManager; + +extern StaticArray StaticCharacterArray; +extern StaticArray StaticObjectArray; +extern StaticArray StaticGUIArray; +extern StaticArray StaticHotspotArray; +extern StaticArray StaticRegionArray; +extern StaticArray StaticInventoryArray; +extern StaticArray StaticDialogArray; + +extern std::vector moduleInst; +extern std::vector moduleInstFork; +extern std::vector moduleRepExecAddr; + +// Old dialog support (defined in ac/dialog) +extern std::vector< std::shared_ptr > old_dialog_scripts; +extern std::vector old_speech_lines; + +StaticArray StaticCharacterArray; +StaticArray StaticObjectArray; +StaticArray StaticGUIArray; +StaticArray StaticHotspotArray; +StaticArray StaticRegionArray; +StaticArray StaticInventoryArray; +StaticArray StaticDialogArray; + + +namespace AGS +{ +namespace Engine +{ + +String GetGameInitErrorText(GameInitErrorType err) +{ + switch (err) + { + case kGameInitErr_NoError: + return "No error."; + case kGameInitErr_NoFonts: + return "No fonts specified to be used in this game."; + case kGameInitErr_TooManyAudioTypes: + return "Too many audio types for this engine to handle."; + case kGameInitErr_EntityInitFail: + return "Failed to initialize game entities."; + case kGameInitErr_TooManyPlugins: + return "Too many plugins for this engine to handle."; + case kGameInitErr_PluginNameInvalid: + return "Plugin name is invalid."; + case kGameInitErr_ScriptLinkFailed: + return "Script link failed."; + } + return "Unknown error."; +} + +// Initializes audio channels and clips and registers them in the script system +void InitAndRegisterAudioObjects() +{ + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) + { + scrAudioChannel[i].id = i; + ccRegisterManagedObject(&scrAudioChannel[i], &ccDynamicAudio); + } + + for (size_t i = 0; i < game.audioClips.size(); ++i) + { + // Note that as of 3.5.0 data format the clip IDs are still restricted + // to actual item index in array, so we don't make any difference + // between game versions, for now. + game.audioClips[i].id = i; + ccRegisterManagedObject(&game.audioClips[i], &ccDynamicAudioClip); + ccAddExternalDynamicObject(game.audioClips[i].scriptName, &game.audioClips[i], &ccDynamicAudioClip); + } +} + +// Initializes characters and registers them in the script system +void InitAndRegisterCharacters() +{ + characterScriptObjNames.resize(game.numcharacters); + for (int i = 0; i < game.numcharacters; ++i) + { + game.chars[i].walking = 0; + game.chars[i].animating = 0; + game.chars[i].pic_xoffs = 0; + game.chars[i].pic_yoffs = 0; + game.chars[i].blinkinterval = 140; + game.chars[i].blinktimer = game.chars[i].blinkinterval; + game.chars[i].index_id = i; + game.chars[i].blocking_width = 0; + game.chars[i].blocking_height = 0; + game.chars[i].prevroom = -1; + game.chars[i].loop = 0; + game.chars[i].frame = 0; + game.chars[i].walkwait = -1; + ccRegisterManagedObject(&game.chars[i], &ccDynamicCharacter); + + // export the character's script object + characterScriptObjNames[i] = game.chars[i].scrname; + ccAddExternalDynamicObject(characterScriptObjNames[i], &game.chars[i], &ccDynamicCharacter); + } +} + +// Initializes dialog and registers them in the script system +void InitAndRegisterDialogs() +{ + scrDialog = new ScriptDialog[game.numdialog]; + for (int i = 0; i < game.numdialog; ++i) + { + scrDialog[i].id = i; + scrDialog[i].reserved = 0; + ccRegisterManagedObject(&scrDialog[i], &ccDynamicDialog); + + if (!game.dialogScriptNames[i].IsEmpty()) + ccAddExternalDynamicObject(game.dialogScriptNames[i], &scrDialog[i], &ccDynamicDialog); + } +} + +// Initializes dialog options rendering objects and registers them in the script system +void InitAndRegisterDialogOptions() +{ + ccRegisterManagedObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + + dialogOptionsRenderingSurface = new ScriptDrawingSurface(); + dialogOptionsRenderingSurface->isLinkedBitmapOnly = true; + long dorsHandle = ccRegisterManagedObject(dialogOptionsRenderingSurface, dialogOptionsRenderingSurface); + ccAddObjectReference(dorsHandle); +} + +// Initializes gui and registers them in the script system +HError InitAndRegisterGUI() +{ + scrGui = (ScriptGUI*)malloc(sizeof(ScriptGUI) * game.numgui); + for (int i = 0; i < game.numgui; ++i) + { + scrGui[i].id = -1; + } + + guiScriptObjNames.resize(game.numgui); + for (int i = 0; i < game.numgui; ++i) + { + // link controls to their parent guis + HError err = guis[i].RebuildArray(); + if (!err) + return err; + // export all the GUI's controls + export_gui_controls(i); + // copy the script name to its own memory location + // because ccAddExtSymbol only keeps a reference + guiScriptObjNames[i] = guis[i].Name; + scrGui[i].id = i; + ccAddExternalDynamicObject(guiScriptObjNames[i], &scrGui[i], &ccDynamicGUI); + ccRegisterManagedObject(&scrGui[i], &ccDynamicGUI); + } + return HError::None(); +} + +// Initializes inventory items and registers them in the script system +void InitAndRegisterInvItems() +{ + for (int i = 0; i < MAX_INV; ++i) + { + scrInv[i].id = i; + scrInv[i].reserved = 0; + ccRegisterManagedObject(&scrInv[i], &ccDynamicInv); + + if (!game.invScriptNames[i].IsEmpty()) + ccAddExternalDynamicObject(game.invScriptNames[i], &scrInv[i], &ccDynamicInv); + } +} + +// Initializes room hotspots and registers them in the script system +void InitAndRegisterHotspots() +{ + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) + { + scrHotspot[i].id = i; + scrHotspot[i].reserved = 0; + ccRegisterManagedObject(&scrHotspot[i], &ccDynamicHotspot); + } +} + +// Initializes room objects and registers them in the script system +void InitAndRegisterRoomObjects() +{ + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) + { + ccRegisterManagedObject(&scrObj[i], &ccDynamicObject); + } +} + +// Initializes room regions and registers them in the script system +void InitAndRegisterRegions() +{ + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) + { + scrRegion[i].id = i; + scrRegion[i].reserved = 0; + ccRegisterManagedObject(&scrRegion[i], &ccDynamicRegion); + } +} + +// Registers static entity arrays in the script system +void RegisterStaticArrays() +{ + StaticCharacterArray.Create(&ccDynamicCharacter, sizeof(CharacterInfo), sizeof(CharacterInfo)); + StaticObjectArray.Create(&ccDynamicObject, sizeof(ScriptObject), sizeof(ScriptObject)); + StaticGUIArray.Create(&ccDynamicGUI, sizeof(ScriptGUI), sizeof(ScriptGUI)); + StaticHotspotArray.Create(&ccDynamicHotspot, sizeof(ScriptHotspot), sizeof(ScriptHotspot)); + StaticRegionArray.Create(&ccDynamicRegion, sizeof(ScriptRegion), sizeof(ScriptRegion)); + StaticInventoryArray.Create(&ccDynamicInv, sizeof(ScriptInvItem), sizeof(ScriptInvItem)); + StaticDialogArray.Create(&ccDynamicDialog, sizeof(ScriptDialog), sizeof(ScriptDialog)); + + ccAddExternalStaticArray("character",&game.chars[0], &StaticCharacterArray); + ccAddExternalStaticArray("object",&scrObj[0], &StaticObjectArray); + ccAddExternalStaticArray("gui",&scrGui[0], &StaticGUIArray); + ccAddExternalStaticArray("hotspot",&scrHotspot[0], &StaticHotspotArray); + ccAddExternalStaticArray("region",&scrRegion[0], &StaticRegionArray); + ccAddExternalStaticArray("inventory",&scrInv[0], &StaticInventoryArray); + ccAddExternalStaticArray("dialog", &scrDialog[0], &StaticDialogArray); +} + +// Initializes various game entities and registers them in the script system +HError InitAndRegisterGameEntities() +{ + InitAndRegisterAudioObjects(); + InitAndRegisterCharacters(); + InitAndRegisterDialogs(); + InitAndRegisterDialogOptions(); + HError err = InitAndRegisterGUI(); + if (!err) + return err; + InitAndRegisterInvItems(); + + InitAndRegisterHotspots(); + InitAndRegisterRegions(); + InitAndRegisterRoomObjects(); + play.CreatePrimaryViewportAndCamera(); + + RegisterStaticArrays(); + + setup_player_character(game.playercharacter); + if (loaded_game_file_version >= kGameVersion_270) + ccAddExternalStaticObject("player", &_sc_PlayerCharPtr, &GlobalStaticManager); + return HError::None(); +} + +void LoadFonts(GameDataVersion data_ver) +{ + for (int i = 0; i < game.numfonts; ++i) + { + if (!wloadfont_size(i, game.fonts[i])) + quitprintf("Unable to load font %d, no renderer could load a matching file", i); + } +} + +void AllocScriptModules() +{ + moduleInst.resize(numScriptModules, nullptr); + moduleInstFork.resize(numScriptModules, nullptr); + moduleRepExecAddr.resize(numScriptModules); + repExecAlways.moduleHasFunction.resize(numScriptModules, true); + lateRepExecAlways.moduleHasFunction.resize(numScriptModules, true); + getDialogOptionsDimensionsFunc.moduleHasFunction.resize(numScriptModules, true); + renderDialogOptionsFunc.moduleHasFunction.resize(numScriptModules, true); + getDialogOptionUnderCursorFunc.moduleHasFunction.resize(numScriptModules, true); + runDialogOptionMouseClickHandlerFunc.moduleHasFunction.resize(numScriptModules, true); + runDialogOptionKeyPressHandlerFunc.moduleHasFunction.resize(numScriptModules, true); + runDialogOptionRepExecFunc.moduleHasFunction.resize(numScriptModules, true); + for (int i = 0; i < numScriptModules; ++i) + { + moduleRepExecAddr[i].Invalidate(); + } +} + +HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion data_ver) +{ + const ScriptAPIVersion base_api = (ScriptAPIVersion)game.options[OPT_BASESCRIPTAPI]; + const ScriptAPIVersion compat_api = (ScriptAPIVersion)game.options[OPT_SCRIPTCOMPATLEV]; + if (data_ver >= kGameVersion_341) + { + // TODO: find a way to either automate this list of strings or make it more visible (shared & easier to find in engine code) + // TODO: stack-allocated strings, here and in other similar places + const String scapi_names[kScriptAPI_Current + 1] = {"v3.2.1", "v3.3.0", "v3.3.4", "v3.3.5", "v3.4.0", "v3.4.1", "v3.5.0", "v3.5.0.7"}; + Debug::Printf(kDbgMsg_Info, "Requested script API: %s (%d), compat level: %s (%d)", + base_api >= 0 && base_api <= kScriptAPI_Current ? scapi_names[base_api].GetCStr() : "unknown", base_api, + compat_api >= 0 && compat_api <= kScriptAPI_Current ? scapi_names[compat_api].GetCStr() : "unknown", compat_api); + } + // If the game was compiled using unsupported version of the script API, + // we warn about potential incompatibilities but proceed further. + if (game.options[OPT_BASESCRIPTAPI] > kScriptAPI_Current) + platform->DisplayAlert("Warning: this game requests a higher version of AGS script API, it may not run correctly or run at all."); + + // + // 1. Check that the loaded data is valid and compatible with the current + // engine capabilities. + // + if (game.numfonts == 0) + return new GameInitError(kGameInitErr_NoFonts); + if (game.audioClipTypes.size() > MAX_AUDIO_TYPES) + return new GameInitError(kGameInitErr_TooManyAudioTypes, String::FromFormat("Required: %u, max: %d", game.audioClipTypes.size(), MAX_AUDIO_TYPES)); + + // + // 2. Apply overriding config settings + // + // The earlier versions of AGS provided support for "upscaling" low-res + // games (320x200 and 320x240) to hi-res (640x400 and 640x480 + // respectively). The script API has means for detecting if the game is + // running upscaled, and game developer could use this opportunity to setup + // game accordingly (e.g. assign hi-res fonts, etc). + // This feature is officially deprecated since 3.1.0, however the engine + // itself still supports it, technically. + // This overriding option re-enables "upscaling". It works ONLY for low-res + // resolutions, such as 320x200 and 320x240. + if (usetup.override_upscale) + { + if (game.GetResolutionType() == kGameResolution_320x200) + game.SetGameResolution(kGameResolution_640x400); + else if (game.GetResolutionType() == kGameResolution_320x240) + game.SetGameResolution(kGameResolution_640x480); + } + + // + // 3. Allocate and init game objects + // + charextra = (CharacterExtras*)calloc(game.numcharacters, sizeof(CharacterExtras)); + charcache = (CharacterCache*)calloc(1,sizeof(CharacterCache)*game.numcharacters+5); + mls = (MoveList*)calloc(game.numcharacters + MAX_ROOM_OBJECTS + 1, sizeof(MoveList)); + actSpsCount = game.numcharacters + MAX_ROOM_OBJECTS + 2; + actsps = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *)); + actspsbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*)); + actspswb = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *)); + actspswbbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*)); + actspswbcache = (CachedActSpsData*)calloc(actSpsCount, sizeof(CachedActSpsData)); + play.charProps.resize(game.numcharacters); + old_dialog_scripts = ents.OldDialogScripts; + old_speech_lines = ents.OldSpeechLines; + HError err = InitAndRegisterGameEntities(); + if (!err) + return new GameInitError(kGameInitErr_EntityInitFail, err); + LoadFonts(data_ver); + + // + // 4. Initialize certain runtime variables + // + game_paused = 0; // reset the game paused flag + ifacepopped = -1; + + String svg_suffix; + if (game.saveGameFileExtension[0] != 0) + svg_suffix.Format(".%s", game.saveGameFileExtension); + set_save_game_suffix(svg_suffix); + + play.score_sound = game.scoreClipID; + play.fade_effect = game.options[OPT_FADETYPE]; + + // + // 5. Initialize runtime state of certain game objects + // + for (int i = 0; i < numguilabels; ++i) + { + // labels are not clickable by default + guilabels[i].SetClickable(false); + } + play.gui_draw_order = (int*)calloc(game.numgui * sizeof(int), 1); + update_gui_zorder(); + calculate_reserved_channel_count(); + + // + // 6. Register engine API exports + // NOTE: we must do this before plugin start, because some plugins may + // require access to script API at initialization time. + // + ccSetScriptAliveTimer(150000); + ccSetStringClassImpl(&myScriptStringImpl); + setup_script_exports(base_api, compat_api); + + // + // 7. Start up plugins + // + pl_register_plugins(ents.PluginInfos); + pl_startup_plugins(); + + // + // 8. Create script modules + // NOTE: we must do this after plugins, because some plugins may export + // script symbols too. + // + gamescript = ents.GlobalScript; + dialogScriptsScript = ents.DialogScript; + numScriptModules = ents.ScriptModules.size(); + scriptModules = ents.ScriptModules; + AllocScriptModules(); + if (create_global_script()) + return new GameInitError(kGameInitErr_ScriptLinkFailed, ccErrorString); + + return HGameInitError::None(); +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/game/game_init.h b/engines/ags/engine/game/game_init.h new file mode 100644 index 000000000000..64f3fcad4956 --- /dev/null +++ b/engines/ags/engine/game/game_init.h @@ -0,0 +1,57 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// This unit provides game initialization routine, which takes place after +// main game file was successfully loaded. +// +//============================================================================= + +#ifndef __AGS_EE_GAME__GAMEINIT_H +#define __AGS_EE_GAME__GAMEINIT_H + +#include "game/main_game_file.h" +#include "util/string.h" + +namespace AGS +{ +namespace Engine +{ + +using namespace Common; + +// Error codes for initializing the game +enum GameInitErrorType +{ + kGameInitErr_NoError, + // currently AGS requires at least one font to be present in game + kGameInitErr_NoFonts, + kGameInitErr_TooManyAudioTypes, + kGameInitErr_EntityInitFail, + kGameInitErr_TooManyPlugins, + kGameInitErr_PluginNameInvalid, + kGameInitErr_ScriptLinkFailed +}; + +String GetGameInitErrorText(GameInitErrorType err); + +typedef TypedCodeError GameInitError; +typedef ErrorHandle HGameInitError; + +// Sets up game state for play using preloaded data +HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion data_ver); + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GAME__GAMEINIT_H diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp new file mode 100644 index 000000000000..006ef030f87b --- /dev/null +++ b/engines/ags/engine/game/savegame.cpp @@ -0,0 +1,798 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/character.h" +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/dynamicsprite.h" +#include "ac/event.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/gamesetup.h" +#include "ac/global_audio.h" +#include "ac/global_character.h" +#include "ac/gui.h" +#include "ac/mouse.h" +#include "ac/overlay.h" +#include "ac/region.h" +#include "ac/richgamemedia.h" +#include "ac/room.h" +#include "ac/roomstatus.h" +#include "ac/spritecache.h" +#include "ac/system.h" +#include "ac/timer.h" +#include "debug/out.h" +#include "device/mousew32.h" +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "gfx/graphicsdriver.h" +#include "game/savegame.h" +#include "game/savegame_components.h" +#include "game/savegame_internal.h" +#include "main/engine.h" +#include "main/main.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "script/script.h" +#include "script/cc_error.h" +#include "util/alignedstream.h" +#include "util/file.h" +#include "util/stream.h" +#include "util/string_utils.h" +#include "media/audio/audio_system.h" + +using namespace Common; +using namespace Engine; + +// function is currently implemented in game.cpp +HSaveError restore_game_data(Stream *in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data); + +extern GameSetupStruct game; +extern Bitmap **guibg; +extern AGS::Engine::IDriverDependantBitmap **guibgbmp; +extern AGS::Engine::IGraphicsDriver *gfxDriver; +extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; +extern Bitmap *raw_saved_screen; +extern RoomStatus troom; +extern RoomStatus *croom; + + +namespace AGS +{ +namespace Engine +{ + +const String SavegameSource::LegacySignature = "Adventure Game Studio saved game"; +const String SavegameSource::Signature = "Adventure Game Studio saved game v2"; + +SavegameSource::SavegameSource() + : Version(kSvgVersion_Undefined) +{ +} + +SavegameDescription::SavegameDescription() + : MainDataVersion(kGameVersion_Undefined) + , ColorDepth(0) +{ +} + +PreservedParams::PreservedParams() + : SpeechVOX(0) + , MusicVOX(0) + , GlScDataSize(0) +{ +} + +RestoredData::ScriptData::ScriptData() + : Len(0) +{ +} + +RestoredData::RestoredData() + : FPS(0) + , RoomVolume(kRoomVolumeNormal) + , CursorID(0) + , CursorMode(0) +{ + memset(RoomLightLevels, 0, sizeof(RoomLightLevels)); + memset(RoomTintLevels, 0, sizeof(RoomTintLevels)); + memset(RoomZoomLevels1, 0, sizeof(RoomZoomLevels1)); + memset(RoomZoomLevels2, 0, sizeof(RoomZoomLevels2)); + memset(DoAmbient, 0, sizeof(DoAmbient)); +} + +String GetSavegameErrorText(SavegameErrorType err) +{ + switch (err) + { + case kSvgErr_NoError: + return "No error."; + case kSvgErr_FileOpenFailed: + return "File not found or could not be opened."; + case kSvgErr_SignatureFailed: + return "Not an AGS saved game or unsupported format."; + case kSvgErr_FormatVersionNotSupported: + return "Save format version not supported."; + case kSvgErr_IncompatibleEngine: + return "Save was written by incompatible engine, or file is corrupted."; + case kSvgErr_GameGuidMismatch: + return "Game GUID does not match, saved by a different game."; + case kSvgErr_ComponentListOpeningTagFormat: + return "Failed to parse opening tag of the components list."; + case kSvgErr_ComponentListClosingTagMissing: + return "Closing tag of the components list was not met."; + case kSvgErr_ComponentOpeningTagFormat: + return "Failed to parse opening component tag."; + case kSvgErr_ComponentClosingTagFormat: + return "Failed to parse closing component tag."; + case kSvgErr_ComponentSizeMismatch: + return "Component data size mismatch."; + case kSvgErr_UnsupportedComponent: + return "Unknown and/or unsupported component."; + case kSvgErr_ComponentSerialization: + return "Failed to write the savegame component."; + case kSvgErr_ComponentUnserialization: + return "Failed to restore the savegame component."; + case kSvgErr_InconsistentFormat: + return "Inconsistent format, or file is corrupted."; + case kSvgErr_UnsupportedComponentVersion: + return "Component data version not supported."; + case kSvgErr_GameContentAssertion: + return "Saved content does not match current game."; + case kSvgErr_InconsistentData: + return "Inconsistent save data, or file is corrupted."; + case kSvgErr_InconsistentPlugin: + return "One of the game plugins did not restore its game data correctly."; + case kSvgErr_DifferentColorDepth: + return "Saved with the engine running at a different colour depth."; + case kSvgErr_GameObjectInitFailed: + return "Game object initialization failed after save restoration."; + } + return "Unknown error."; +} + +Bitmap *RestoreSaveImage(Stream *in) +{ + if (in->ReadInt32()) + return read_serialized_bitmap(in); + return nullptr; +} + +void SkipSaveImage(Stream *in) +{ + if (in->ReadInt32()) + skip_serialized_bitmap(in); +} + +HSaveError ReadDescription(Stream *in, SavegameVersion &svg_ver, SavegameDescription &desc, SavegameDescElem elems) +{ + svg_ver = (SavegameVersion)in->ReadInt32(); + if (svg_ver < kSvgVersion_LowestSupported || svg_ver > kSvgVersion_Current) + return new SavegameError(kSvgErr_FormatVersionNotSupported, + String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); + + // Enviroment information + if (elems & kSvgDesc_EnvInfo) + { + desc.EngineName = StrUtil::ReadString(in); + desc.EngineVersion.SetFromString(StrUtil::ReadString(in)); + desc.GameGuid = StrUtil::ReadString(in); + desc.GameTitle = StrUtil::ReadString(in); + desc.MainDataFilename = StrUtil::ReadString(in); + if (svg_ver >= kSvgVersion_Cmp_64bit) + desc.MainDataVersion = (GameDataVersion)in->ReadInt32(); + desc.ColorDepth = in->ReadInt32(); + } + else + { + StrUtil::SkipString(in); + StrUtil::SkipString(in); + StrUtil::SkipString(in); + StrUtil::SkipString(in); + StrUtil::SkipString(in); + if (svg_ver >= kSvgVersion_Cmp_64bit) + in->ReadInt32(); // game data version + in->ReadInt32(); // color depth + } + // User description + if (elems & kSvgDesc_UserText) + desc.UserText = StrUtil::ReadString(in); + else + StrUtil::SkipString(in); + if (elems & kSvgDesc_UserImage) + desc.UserImage.reset(RestoreSaveImage(in)); + else + SkipSaveImage(in); + + return HSaveError::None(); +} + +HSaveError ReadDescription_v321(Stream *in, SavegameVersion &svg_ver, SavegameDescription &desc, SavegameDescElem elems) +{ + // Legacy savegame header + if (elems & kSvgDesc_UserText) + desc.UserText.Read(in); + else + StrUtil::SkipCStr(in); + svg_ver = (SavegameVersion)in->ReadInt32(); + + // Check saved game format version + if (svg_ver < kSvgVersion_LowestSupported || + svg_ver > kSvgVersion_Current) + { + return new SavegameError(kSvgErr_FormatVersionNotSupported, + String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); + } + + if (elems & kSvgDesc_UserImage) + desc.UserImage.reset(RestoreSaveImage(in)); + else + SkipSaveImage(in); + + String version_str = String::FromStream(in); + Version eng_version(version_str); + if (eng_version > EngineVersion || + eng_version < SavedgameLowestBackwardCompatVersion) + { + // Engine version is either non-forward or non-backward compatible + return new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Required: %s, supported: %s - %s.", eng_version.LongString.GetCStr(), SavedgameLowestBackwardCompatVersion.LongString.GetCStr(), EngineVersion.LongString.GetCStr())); + } + if (elems & kSvgDesc_EnvInfo) + { + desc.MainDataFilename.Read(in); + in->ReadInt32(); // unscaled game height with borders, now obsolete + desc.ColorDepth = in->ReadInt32(); + } + else + { + StrUtil::SkipCStr(in); + in->ReadInt32(); // unscaled game height with borders, now obsolete + in->ReadInt32(); // color depth + } + + return HSaveError::None(); +} + +HSaveError OpenSavegameBase(const String &filename, SavegameSource *src, SavegameDescription *desc, SavegameDescElem elems) +{ + UStream in(File::OpenFileRead(filename)); + if (!in.get()) + return new SavegameError(kSvgErr_FileOpenFailed, String::FromFormat("Requested filename: %s.", filename.GetCStr())); + + // Skip MS Windows Vista rich media header + RICH_GAME_MEDIA_HEADER rich_media_header; + rich_media_header.ReadFromFile(in.get()); + + // Check saved game signature + bool is_new_save = false; + size_t pre_sig_pos = in->GetPosition(); + String svg_sig = String::FromStreamCount(in.get(), SavegameSource::Signature.GetLength()); + if (svg_sig.Compare(SavegameSource::Signature) == 0) + { + is_new_save = true; + } + else + { + in->Seek(pre_sig_pos, kSeekBegin); + svg_sig = String::FromStreamCount(in.get(), SavegameSource::LegacySignature.GetLength()); + if (svg_sig.Compare(SavegameSource::LegacySignature) != 0) + return new SavegameError(kSvgErr_SignatureFailed); + } + + SavegameVersion svg_ver; + SavegameDescription temp_desc; + HSaveError err; + if (is_new_save) + err = ReadDescription(in.get(), svg_ver, temp_desc, desc ? elems : kSvgDesc_None); + else + err = ReadDescription_v321(in.get(), svg_ver, temp_desc, desc ? elems : kSvgDesc_None); + if (!err) + return err; + + if (src) + { + src->Filename = filename; + src->Version = svg_ver; + src->InputStream.reset(in.release()); // give the stream away to the caller + } + if (desc) + { + if (elems & kSvgDesc_EnvInfo) + { + desc->EngineName = temp_desc.EngineName; + desc->EngineVersion = temp_desc.EngineVersion; + desc->GameGuid = temp_desc.GameGuid; + desc->GameTitle = temp_desc.GameTitle; + desc->MainDataFilename = temp_desc.MainDataFilename; + desc->MainDataVersion = temp_desc.MainDataVersion; + desc->ColorDepth = temp_desc.ColorDepth; + } + if (elems & kSvgDesc_UserText) + desc->UserText = temp_desc.UserText; + if (elems & kSvgDesc_UserImage) + desc->UserImage.reset(temp_desc.UserImage.release()); + } + return err; +} + +HSaveError OpenSavegame(const String &filename, SavegameSource &src, SavegameDescription &desc, SavegameDescElem elems) +{ + return OpenSavegameBase(filename, &src, &desc, elems); +} + +HSaveError OpenSavegame(const String &filename, SavegameDescription &desc, SavegameDescElem elems) +{ + return OpenSavegameBase(filename, nullptr, &desc, elems); +} + +// Prepares engine for actual save restore (stops processes, cleans up memory) +void DoBeforeRestore(PreservedParams &pp) +{ + pp.SpeechVOX = play.want_speech; + pp.MusicVOX = play.separate_music_lib; + + unload_old_room(); + delete raw_saved_screen; + raw_saved_screen = nullptr; + remove_screen_overlay(-1); + is_complete_overlay = 0; + is_text_overlay = 0; + + // cleanup dynamic sprites + // NOTE: sprite 0 is a special constant sprite that cannot be dynamic + for (int i = 1; i < spriteset.GetSpriteSlotCount(); ++i) + { + if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) + { + // do this early, so that it changing guibuts doesn't + // affect the restored data + free_dynamic_sprite(i); + } + } + + // cleanup GUI backgrounds + for (int i = 0; i < game.numgui; ++i) + { + delete guibg[i]; + guibg[i] = nullptr; + + if (guibgbmp[i]) + gfxDriver->DestroyDDB(guibgbmp[i]); + guibgbmp[i] = nullptr; + } + + // preserve script data sizes and cleanup scripts + pp.GlScDataSize = gameinst->globaldatasize; + delete gameinstFork; + delete gameinst; + gameinstFork = nullptr; + gameinst = nullptr; + pp.ScMdDataSize.resize(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) + { + pp.ScMdDataSize[i] = moduleInst[i]->globaldatasize; + delete moduleInstFork[i]; + delete moduleInst[i]; + moduleInst[i] = nullptr; + } + + play.FreeProperties(); + play.FreeViewportsAndCameras(); + + delete roominstFork; + delete roominst; + roominstFork = nullptr; + roominst = nullptr; + + delete dialogScriptsInst; + dialogScriptsInst = nullptr; + + resetRoomStatuses(); + troom.FreeScriptData(); + troom.FreeProperties(); + free_do_once_tokens(); + + // unregister gui controls from API exports + // TODO: find out why are we doing this here? is this really necessary? + for (int i = 0; i < game.numgui; ++i) + { + unexport_gui_controls(i); + } + // Clear the managed object pool + ccUnregisterAllObjects(); + + // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) + { + stop_and_destroy_channel_ex(i, false); + } + + clear_music_cache(); +} + +void RestoreViewportsAndCameras(const RestoredData &r_data) +{ + for (size_t i = 0; i < r_data.Cameras.size(); ++i) + { + const auto &cam_dat = r_data.Cameras[i]; + auto cam = play.GetRoomCamera(i); + cam->SetID(cam_dat.ID); + if ((cam_dat.Flags & kSvgCamPosLocked) != 0) + cam->Lock(); + else + cam->Release(); + cam->SetAt(cam_dat.Left, cam_dat.Top); + cam->SetSize(Size(cam_dat.Width, cam_dat.Height)); + } + for (size_t i = 0; i < r_data.Viewports.size(); ++i) + { + const auto &view_dat = r_data.Viewports[i]; + auto view = play.GetRoomViewport(i); + view->SetID(view_dat.ID); + view->SetVisible((view_dat.Flags & kSvgViewportVisible) != 0); + view->SetRect(RectWH(view_dat.Left, view_dat.Top, view_dat.Width, view_dat.Height)); + view->SetZOrder(view_dat.ZOrder); + // Restore camera link + int cam_index = view_dat.CamID; + if (cam_index < 0) continue; + auto cam = play.GetRoomCamera(cam_index); + view->LinkCamera(cam); + cam->LinkToViewport(view); + } + play.InvalidateViewportZOrder(); +} + +// Final processing after successfully restoring from save +HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) +{ + // Use a yellow dialog highlight for older game versions + // CHECKME: it is dubious that this should be right here + if(loaded_game_file_version < kGameVersion_331) + play.dialog_options_highlight_color = DIALOG_OPTIONS_HIGHLIGHT_COLOR_DEFAULT; + + // Preserve whether the music vox is available + play.separate_music_lib = pp.MusicVOX; + // If they had the vox when they saved it, but they don't now + if ((pp.SpeechVOX < 0) && (play.want_speech >= 0)) + play.want_speech = (-play.want_speech) - 1; + // If they didn't have the vox before, but now they do + else if ((pp.SpeechVOX >= 0) && (play.want_speech < 0)) + play.want_speech = (-play.want_speech) - 1; + + // recache queued clips + for (int i = 0; i < play.new_music_queue_size; ++i) + { + play.new_music_queue[i].cachedClip = nullptr; + } + + // restore these to the ones retrieved from the save game + const size_t dynsurf_num = Math::Min((size_t)MAX_DYNAMIC_SURFACES, r_data.DynamicSurfaces.size()); + for (size_t i = 0; i < dynsurf_num; ++i) + { + dynamicallyCreatedSurfaces[i] = r_data.DynamicSurfaces[i]; + } + + for (int i = 0; i < game.numgui; ++i) + export_gui_controls(i); + update_gui_zorder(); + + if (create_global_script()) + { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Unable to recreate global script: %s", ccErrorString.GetCStr())); + } + + // read the global data into the newly created script + if (r_data.GlobalScript.Data.get()) + memcpy(gameinst->globaldata, r_data.GlobalScript.Data.get(), + Math::Min((size_t)gameinst->globaldatasize, r_data.GlobalScript.Len)); + + // restore the script module data + for (int i = 0; i < numScriptModules; ++i) + { + if (r_data.ScriptModules[i].Data.get()) + memcpy(moduleInst[i]->globaldata, r_data.ScriptModules[i].Data.get(), + Math::Min((size_t)moduleInst[i]->globaldatasize, r_data.ScriptModules[i].Len)); + } + + setup_player_character(game.playercharacter); + + // Save some parameters to restore them after room load + int gstimer=play.gscript_timer; + int oldx1 = play.mboundx1, oldx2 = play.mboundx2; + int oldy1 = play.mboundy1, oldy2 = play.mboundy2; + + // disable the queue momentarily + int queuedMusicSize = play.music_queue_size; + play.music_queue_size = 0; + + update_polled_stuff_if_runtime(); + + // load the room the game was saved in + if (displayed_room >= 0) + load_new_room(displayed_room, nullptr); + + update_polled_stuff_if_runtime(); + + play.gscript_timer=gstimer; + // restore the correct room volume (they might have modified + // it with SetMusicVolume) + thisroom.Options.MusicVolume = r_data.RoomVolume; + + Mouse::SetMoveLimit(Rect(oldx1, oldy1, oldx2, oldy2)); + + set_cursor_mode(r_data.CursorMode); + set_mouse_cursor(r_data.CursorID); + if (r_data.CursorMode == MODE_USE) + SetActiveInventory(playerchar->activeinv); + // ensure that the current cursor is locked + spriteset.Precache(game.mcurs[r_data.CursorID].pic); + + set_window_title(play.game_name); + + update_polled_stuff_if_runtime(); + + if (displayed_room >= 0) + { + for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) + { + if (r_data.RoomBkgScene[i]) + { + thisroom.BgFrames[i].Graphic = r_data.RoomBkgScene[i]; + } + } + + in_new_room=3; // don't run "enters screen" events + // now that room has loaded, copy saved light levels in + for (size_t i = 0; i < MAX_ROOM_REGIONS; ++i) + { + thisroom.Regions[i].Light = r_data.RoomLightLevels[i]; + thisroom.Regions[i].Tint = r_data.RoomTintLevels[i]; + } + generate_light_table(); + + for (size_t i = 0; i < MAX_WALK_AREAS + 1; ++i) + { + thisroom.WalkAreas[i].ScalingFar = r_data.RoomZoomLevels1[i]; + thisroom.WalkAreas[i].ScalingNear = r_data.RoomZoomLevels2[i]; + } + + on_background_frame_change(); + } + + gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); + + // restore the queue now that the music is playing + play.music_queue_size = queuedMusicSize; + + if (play.digital_master_volume >= 0) + System_SetVolume(play.digital_master_volume); + + // Run audio clips on channels + // these two crossfading parameters have to be temporarily reset + const int cf_in_chan = play.crossfading_in_channel; + const int cf_out_chan = play.crossfading_out_channel; + play.crossfading_in_channel = 0; + play.crossfading_out_channel = 0; + + { + AudioChannelsLock lock; + // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) + { + const RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; + if (chan_info.ClipID < 0) + continue; + if ((size_t)chan_info.ClipID >= game.audioClips.size()) + { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Invalid audio clip index: %d (clip count: %u).", chan_info.ClipID, game.audioClips.size())); + } + play_audio_clip_on_channel(i, &game.audioClips[chan_info.ClipID], + chan_info.Priority, chan_info.Repeat, chan_info.Pos); + + auto* ch = lock.GetChannel(i); + if (ch != nullptr) + { + ch->set_volume_direct(chan_info.VolAsPercent, chan_info.Vol); + ch->set_speed(chan_info.Speed); + ch->set_panning(chan_info.Pan); + ch->panningAsPercentage = chan_info.PanAsPercent; + ch->xSource = chan_info.XSource; + ch->ySource = chan_info.YSource; + ch->maximumPossibleDistanceAway = chan_info.MaxDist; + } + } + if ((cf_in_chan > 0) && (lock.GetChannel(cf_in_chan) != nullptr)) + play.crossfading_in_channel = cf_in_chan; + if ((cf_out_chan > 0) && (lock.GetChannel(cf_out_chan) != nullptr)) + play.crossfading_out_channel = cf_out_chan; + + // If there were synced audio tracks, the time taken to load in the + // different channels will have thrown them out of sync, so re-time it + // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) + { + auto* ch = lock.GetChannelIfPlaying(i); + int pos = r_data.AudioChans[i].Pos; + if ((pos > 0) && (ch != nullptr)) + { + ch->seek(pos); + } + } + } // -- AudioChannelsLock + + // TODO: investigate loop range + for (int i = 1; i < MAX_SOUND_CHANNELS; ++i) + { + if (r_data.DoAmbient[i]) + PlayAmbientSound(i, r_data.DoAmbient[i], ambient[i].vol, ambient[i].x, ambient[i].y); + } + update_directional_sound_vol(); + + for (int i = 0; i < game.numgui; ++i) + { + guibg[i] = BitmapHelper::CreateBitmap(guis[i].Width, guis[i].Height, game.GetColorDepth()); + guibg[i] = ReplaceBitmapWithSupportedFormat(guibg[i]); + } + + recreate_overlay_ddbs(); + + guis_need_update = 1; + + RestoreViewportsAndCameras(r_data); + + play.ClearIgnoreInput(); // don't keep ignored input after save restore + update_polled_stuff_if_runtime(); + + pl_run_plugin_hooks(AGSE_POSTRESTOREGAME, 0); + + if (displayed_room < 0) + { + // the restart point, no room was loaded + load_new_room(playerchar->room, playerchar); + playerchar->prevroom = -1; + + first_room_initialization(); + } + + if ((play.music_queue_size > 0) && (cachedQueuedMusic == nullptr)) + { + cachedQueuedMusic = load_music_from_disk(play.music_queue[0], 0); + } + + // Test if the old-style audio had playing music and it was properly loaded + if (current_music_type > 0) + { + AudioChannelsLock lock; + + if ((crossFading > 0 && !lock.GetChannelIfPlaying(crossFading)) || + (crossFading <= 0 && !lock.GetChannelIfPlaying(SCHAN_MUSIC))) + { + current_music_type = 0; // playback failed, reset flag + } + } + + set_game_speed(r_data.FPS); + + return HSaveError::None(); +} + +HSaveError RestoreGameState(PStream in, SavegameVersion svg_version) +{ + PreservedParams pp; + RestoredData r_data; + DoBeforeRestore(pp); + HSaveError err; + if (svg_version >= kSvgVersion_Components) + err = SavegameComponents::ReadAll(in, svg_version, pp, r_data); + else + err = restore_game_data(in.get(), svg_version, pp, r_data); + if (!err) + return err; + return DoAfterRestore(pp, r_data); +} + + +void WriteSaveImage(Stream *out, const Bitmap *screenshot) +{ + // store the screenshot at the start to make it easily accesible + out->WriteInt32((screenshot == nullptr) ? 0 : 1); + + if (screenshot) + serialize_bitmap(screenshot, out); +} + +void WriteDescription(Stream *out, const String &user_text, const Bitmap *user_image) +{ + // Data format version + out->WriteInt32(kSvgVersion_Current); + // Enviroment information + StrUtil::WriteString("Adventure Game Studio run-time engine", out); + StrUtil::WriteString(EngineVersion.LongString, out); + StrUtil::WriteString(game.guid, out); + StrUtil::WriteString(game.gamename, out); + StrUtil::WriteString(ResPaths.GamePak.Name, out); + out->WriteInt32(loaded_game_file_version); + out->WriteInt32(game.GetColorDepth()); + // User description + StrUtil::WriteString(user_text, out); + WriteSaveImage(out, user_image); +} + +PStream StartSavegame(const String &filename, const String &user_text, const Bitmap *user_image) +{ + Stream *out = Common::File::CreateFile(filename); + if (!out) + return PStream(); + + // Initialize and write Vista header + RICH_GAME_MEDIA_HEADER vistaHeader; + memset(&vistaHeader, 0, sizeof(RICH_GAME_MEDIA_HEADER)); + memcpy(&vistaHeader.dwMagicNumber, RM_MAGICNUMBER, sizeof(int)); + vistaHeader.dwHeaderVersion = 1; + vistaHeader.dwHeaderSize = sizeof(RICH_GAME_MEDIA_HEADER); + vistaHeader.dwThumbnailOffsetHigherDword = 0; + vistaHeader.dwThumbnailOffsetLowerDword = 0; + vistaHeader.dwThumbnailSize = 0; + convert_guid_from_text_to_binary(game.guid, &vistaHeader.guidGameId[0]); + uconvert(game.gamename, U_ASCII, (char*)&vistaHeader.szGameName[0], U_UNICODE, RM_MAXLENGTH); + uconvert(user_text, U_ASCII, (char*)&vistaHeader.szSaveName[0], U_UNICODE, RM_MAXLENGTH); + vistaHeader.szLevelName[0] = 0; + vistaHeader.szComments[0] = 0; + // MS Windows Vista rich media header + vistaHeader.WriteToFile(out); + + // Savegame signature + out->Write(SavegameSource::Signature.GetCStr(), SavegameSource::Signature.GetLength()); + + // CHECKME: what is this plugin hook suppose to mean, and if it is called here correctly + pl_run_plugin_hooks(AGSE_PRESAVEGAME, 0); + + // Write descrition block + WriteDescription(out, user_text, user_image); + return PStream(out); +} + +void DoBeforeSave() +{ + if (play.cur_music_number >= 0) + { + if (IsMusicPlaying() == 0) + play.cur_music_number = -1; + } + + if (displayed_room >= 0) + { + // update the current room script's data segment copy + if (roominst) + save_room_data_segment(); + + // Update the saved interaction variable values + for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i) + croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value; + } +} + +void SaveGameState(PStream out) +{ + DoBeforeSave(); + SavegameComponents::WriteAllCommon(out); +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h new file mode 100644 index 000000000000..2feacc41a6f3 --- /dev/null +++ b/engines/ags/engine/game/savegame.h @@ -0,0 +1,169 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_GAME__SAVEGAME_H +#define __AGS_EE_GAME__SAVEGAME_H + +#include +#include "ac/game_version.h" +#include "util/error.h" +#include "util/version.h" + + +namespace AGS +{ + +namespace Common { class Bitmap; class Stream; } + +namespace Engine +{ + +using Common::Bitmap; +using Common::ErrorHandle; +using Common::TypedCodeError; +using Common::Stream; +using Common::String; +using Common::Version; + +typedef std::shared_ptr PStream; + +//----------------------------------------------------------------------------- +// Savegame version history +// +// 8 last old style saved game format (of AGS 3.2.1) +// 9 first new style (self-descriptive block-based) format version +//----------------------------------------------------------------------------- +enum SavegameVersion +{ + kSvgVersion_Undefined = 0, + kSvgVersion_321 = 8, + kSvgVersion_Components= 9, + kSvgVersion_Cmp_64bit = 10, + kSvgVersion_350_final = 11, + kSvgVersion_350_final2= 12, + kSvgVersion_Current = kSvgVersion_350_final2, + kSvgVersion_LowestSupported = kSvgVersion_321 // change if support dropped +}; + +// Error codes for save restoration routine +enum SavegameErrorType +{ + kSvgErr_NoError, + kSvgErr_FileOpenFailed, + kSvgErr_SignatureFailed, + kSvgErr_FormatVersionNotSupported, + kSvgErr_IncompatibleEngine, + kSvgErr_GameGuidMismatch, + kSvgErr_ComponentListOpeningTagFormat, + kSvgErr_ComponentListClosingTagMissing, + kSvgErr_ComponentOpeningTagFormat, + kSvgErr_ComponentClosingTagFormat, + kSvgErr_ComponentSizeMismatch, + kSvgErr_UnsupportedComponent, + kSvgErr_ComponentSerialization, + kSvgErr_ComponentUnserialization, + kSvgErr_InconsistentFormat, + kSvgErr_UnsupportedComponentVersion, + kSvgErr_GameContentAssertion, + kSvgErr_InconsistentData, + kSvgErr_InconsistentPlugin, + kSvgErr_DifferentColorDepth, + kSvgErr_GameObjectInitFailed, + kNumSavegameError +}; + +String GetSavegameErrorText(SavegameErrorType err); + +typedef TypedCodeError SavegameError; +typedef ErrorHandle HSaveError; +typedef std::unique_ptr UStream; +typedef std::unique_ptr UBitmap; + +// SavegameSource defines a successfully opened savegame stream +struct SavegameSource +{ + // Signature of the current savegame format + static const String Signature; + // Signature of the legacy savegame format + static const String LegacySignature; + + // Name of the savefile + String Filename; + // Savegame format version + SavegameVersion Version; + // A ponter to the opened stream + PStream InputStream; + + SavegameSource(); +}; + +// Supported elements of savegame description; +// these may be used as flags to define valid fields +enum SavegameDescElem +{ + kSvgDesc_None = 0, + kSvgDesc_EnvInfo = 0x0001, + kSvgDesc_UserText = 0x0002, + kSvgDesc_UserImage = 0x0004, + kSvgDesc_All = kSvgDesc_EnvInfo | kSvgDesc_UserText | kSvgDesc_UserImage +}; + +// SavegameDescription describes savegame with information about the enviroment +// it was created in, and custom data provided by user +struct SavegameDescription +{ + // Name of the engine that saved the game + String EngineName; + // Version of the engine that saved the game + Version EngineVersion; + // Guid of the game which made this save + String GameGuid; + // Title of the game which made this save + String GameTitle; + // Name of the main data file used; this is needed to properly + // load saves made by "minigames" + String MainDataFilename; + // Game's main data version; should be checked early to know + // if the save was made for the supported game format + GameDataVersion MainDataVersion; + // Native color depth of the game; this is required to + // properly restore dynamic graphics from the save + int ColorDepth; + + String UserText; + UBitmap UserImage; + + SavegameDescription(); +}; + + +// Opens savegame for reading; optionally reads description, if any is provided +HSaveError OpenSavegame(const String &filename, SavegameSource &src, + SavegameDescription &desc, SavegameDescElem elems = kSvgDesc_All); +// Opens savegame and reads the savegame description +HSaveError OpenSavegame(const String &filename, SavegameDescription &desc, SavegameDescElem elems = kSvgDesc_All); + +// Reads the game data from the save stream and reinitializes game state +HSaveError RestoreGameState(PStream in, SavegameVersion svg_version); + +// Opens savegame for writing and puts in savegame description +PStream StartSavegame(const String &filename, const String &user_text, const Bitmap *user_image); + +// Prepares game for saving state and writes game data into the save stream +void SaveGameState(PStream out); + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GAME__SAVEGAME_H diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp new file mode 100644 index 000000000000..d309ed0ed6ef --- /dev/null +++ b/engines/ags/engine/game/savegame_components.cpp @@ -0,0 +1,1392 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include + +#include "ac/audiocliptype.h" +#include "ac/character.h" +#include "ac/common.h" +#include "ac/dialogtopic.h" +#include "ac/draw.h" +#include "ac/dynamicsprite.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/gui.h" +#include "ac/mouse.h" +#include "ac/movelist.h" +#include "ac/overlay.h" +#include "ac/roomstatus.h" +#include "ac/screenoverlay.h" +#include "ac/spritecache.h" +#include "ac/view.h" +#include "ac/system.h" +#include "ac/dynobj/cc_serializer.h" +#include "debug/out.h" +#include "game/savegame_components.h" +#include "game/savegame_internal.h" +#include "gfx/bitmap.h" +#include "gui/animatingguibutton.h" +#include "gui/guibutton.h" +#include "gui/guiinv.h" +#include "gui/guilabel.h" +#include "gui/guilistbox.h" +#include "gui/guimain.h" +#include "gui/guislider.h" +#include "gui/guitextbox.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "script/cc_error.h" +#include "script/script.h" +#include "util/filestream.h" // TODO: needed only because plugins expect file handle +#include "media/audio/audio_system.h" + +using namespace Common; + +extern GameSetupStruct game; +extern color palette[256]; +extern DialogTopic *dialog; +extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; +extern int numAnimButs; +extern ViewStruct *views; +extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; +extern RoomStruct thisroom; +extern RoomStatus troom; +extern Bitmap *raw_saved_screen; +extern MoveList *mls; + + +namespace AGS +{ +namespace Engine +{ + +namespace SavegameComponents +{ + +const String ComponentListTag = "Components"; + +void WriteFormatTag(PStream out, const String &tag, bool open = true) +{ + String full_tag = String::FromFormat(open ? "<%s>" : "", tag.GetCStr()); + out->Write(full_tag.GetCStr(), full_tag.GetLength()); +} + +bool ReadFormatTag(PStream in, String &tag, bool open = true) +{ + if (in->ReadByte() != '<') + return false; + if (!open && in->ReadByte() != '/') + return false; + tag.Empty(); + while (!in->EOS()) + { + char c = in->ReadByte(); + if (c == '>') + return true; + tag.AppendChar(c); + } + return false; // reached EOS before closing symbol +} + +bool AssertFormatTag(PStream in, const String &tag, bool open = true) +{ + String read_tag; + if (!ReadFormatTag(in, read_tag, open)) + return false; + return read_tag.Compare(tag) == 0; +} + +bool AssertFormatTagStrict(HSaveError &err, PStream in, const String &tag, bool open = true) +{ + + String read_tag; + if (!ReadFormatTag(in, read_tag, open) || read_tag.Compare(tag) != 0) + { + err = new SavegameError(kSvgErr_InconsistentFormat, + String::FromFormat("Mismatching tag: %s.", tag.GetCStr())); + return false; + } + return true; +} + +inline bool AssertCompatLimit(HSaveError &err, int count, int max_count, const char *content_name) +{ + if (count > max_count) + { + err = new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Incompatible number of %s (count: %d, max: %d).", + content_name, count, max_count)); + return false; + } + return true; +} + +inline bool AssertCompatRange(HSaveError &err, int value, int min_value, int max_value, const char *content_name) +{ + if (value < min_value || value > max_value) + { + err = new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Restore game error: incompatible %s (id: %d, range: %d - %d).", + content_name, value, min_value, max_value)); + return false; + } + return true; +} + +inline bool AssertGameContent(HSaveError &err, int new_val, int original_val, const char *content_name) +{ + if (new_val != original_val) + { + err = new SavegameError(kSvgErr_GameContentAssertion, + String::FromFormat("Mismatching number of %s (game: %d, save: %d).", + content_name, original_val, new_val)); + return false; + } + return true; +} + +inline bool AssertGameObjectContent(HSaveError &err, int new_val, int original_val, const char *content_name, + const char *obj_type, int obj_id) +{ + if (new_val != original_val) + { + err = new SavegameError(kSvgErr_GameContentAssertion, + String::FromFormat("Mismatching number of %s, %s #%d (game: %d, save: %d).", + content_name, obj_type, obj_id, original_val, new_val)); + return false; + } + return true; +} + +inline bool AssertGameObjectContent2(HSaveError &err, int new_val, int original_val, const char *content_name, + const char *obj1_type, int obj1_id, const char *obj2_type, int obj2_id) +{ + if (new_val != original_val) + { + err = new SavegameError(kSvgErr_GameContentAssertion, + String::FromFormat("Mismatching number of %s, %s #%d, %s #%d (game: %d, save: %d).", + content_name, obj1_type, obj1_id, obj2_type, obj2_id, original_val, new_val)); + return false; + } + return true; +} + + +void WriteCameraState(const Camera &cam, Stream *out) +{ + int flags = 0; + if (cam.IsLocked()) flags |= kSvgCamPosLocked; + out->WriteInt32(flags); + const Rect &rc = cam.GetRect(); + out->WriteInt32(rc.Left); + out->WriteInt32(rc.Top); + out->WriteInt32(rc.GetWidth()); + out->WriteInt32(rc.GetHeight()); +} + +void WriteViewportState(const Viewport &view, Stream *out) +{ + int flags = 0; + if (view.IsVisible()) flags |= kSvgViewportVisible; + out->WriteInt32(flags); + const Rect &rc = view.GetRect(); + out->WriteInt32(rc.Left); + out->WriteInt32(rc.Top); + out->WriteInt32(rc.GetWidth()); + out->WriteInt32(rc.GetHeight()); + out->WriteInt32(view.GetZOrder()); + auto cam = view.GetCamera(); + if (cam) + out->WriteInt32(cam->GetID()); + else + out->WriteInt32(-1); +} + +HSaveError WriteGameState(PStream out) +{ + // Game base + game.WriteForSavegame(out); + // Game palette + // TODO: probably no need to save this for hi/true-res game + out->WriteArray(palette, sizeof(color), 256); + + if (loaded_game_file_version <= kGameVersion_272) + { + // Global variables + out->WriteInt32(numGlobalVars); + for (int i = 0; i < numGlobalVars; ++i) + globalvars[i].Write(out.get()); + } + + // Game state + play.WriteForSavegame(out.get()); + // Other dynamic values + out->WriteInt32(frames_per_second); + out->WriteInt32(loopcounter); + out->WriteInt32(ifacepopped); + out->WriteInt32(game_paused); + // Mouse cursor + out->WriteInt32(cur_mode); + out->WriteInt32(cur_cursor); + out->WriteInt32(mouse_on_iface); + + // Viewports and cameras + int viewcam_flags = 0; + if (play.IsAutoRoomViewport()) + viewcam_flags |= kSvgGameAutoRoomView; + out->WriteInt32(viewcam_flags); + out->WriteInt32(play.GetRoomCameraCount()); + for (int i = 0; i < play.GetRoomCameraCount(); ++i) + WriteCameraState(*play.GetRoomCamera(i), out.get()); + out->WriteInt32(play.GetRoomViewportCount()); + for (int i = 0; i < play.GetRoomViewportCount(); ++i) + WriteViewportState(*play.GetRoomViewport(i), out.get()); + + return HSaveError::None(); +} + +void ReadLegacyCameraState(Stream *in, RestoredData &r_data) +{ + // Precreate viewport and camera and save data in temp structs + int camx = in->ReadInt32(); + int camy = in->ReadInt32(); + play.CreateRoomCamera(); + play.CreateRoomViewport(); + const auto &main_view = play.GetMainViewport(); + RestoredData::CameraData cam_dat; + cam_dat.ID = 0; + cam_dat.Left = camx; + cam_dat.Top = camy; + cam_dat.Width = main_view.GetWidth(); + cam_dat.Height = main_view.GetHeight(); + r_data.Cameras.push_back(cam_dat); + RestoredData::ViewportData view_dat; + view_dat.ID = 0; + view_dat.Width = main_view.GetWidth(); + view_dat.Height = main_view.GetHeight(); + view_dat.Flags = kSvgViewportVisible; + view_dat.CamID = 0; + r_data.Viewports.push_back(view_dat); +} + +void ReadCameraState(RestoredData &r_data, Stream *in) +{ + RestoredData::CameraData cam; + cam.ID = r_data.Cameras.size(); + cam.Flags = in->ReadInt32(); + cam.Left = in->ReadInt32(); + cam.Top = in->ReadInt32(); + cam.Width = in->ReadInt32(); + cam.Height = in->ReadInt32(); + r_data.Cameras.push_back(cam); +} + +void ReadViewportState(RestoredData &r_data, Stream *in) +{ + RestoredData::ViewportData view; + view.ID = r_data.Viewports.size(); + view.Flags = in->ReadInt32(); + view.Left = in->ReadInt32(); + view.Top = in->ReadInt32(); + view.Width = in->ReadInt32(); + view.Height = in->ReadInt32(); + view.ZOrder = in->ReadInt32(); + view.CamID = in->ReadInt32(); + r_data.Viewports.push_back(view); +} + +HSaveError ReadGameState(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + GameStateSvgVersion svg_ver = (GameStateSvgVersion)cmp_ver; + // Game base + game.ReadFromSavegame(in); + // Game palette + in->ReadArray(palette, sizeof(color), 256); + + if (loaded_game_file_version <= kGameVersion_272) + { + // Legacy interaction global variables + if (!AssertGameContent(err, in->ReadInt32(), numGlobalVars, "Global Variables")) + return err; + for (int i = 0; i < numGlobalVars; ++i) + globalvars[i].Read(in.get()); + } + + // Game state + play.ReadFromSavegame(in.get(), svg_ver, r_data); + + // Other dynamic values + r_data.FPS = in->ReadInt32(); + set_loop_counter(in->ReadInt32()); + ifacepopped = in->ReadInt32(); + game_paused = in->ReadInt32(); + // Mouse cursor state + r_data.CursorMode = in->ReadInt32(); + r_data.CursorID = in->ReadInt32(); + mouse_on_iface = in->ReadInt32(); + + // Viewports and cameras + if (svg_ver < kGSSvgVersion_3510) + { + ReadLegacyCameraState(in.get(), r_data); + r_data.Cameras[0].Flags = r_data.Camera0_Flags; + } + else + { + int viewcam_flags = in->ReadInt32(); + play.SetAutoRoomViewport((viewcam_flags & kSvgGameAutoRoomView) != 0); + // TODO: we create viewport and camera objects here because they are + // required for the managed pool deserialization, but read actual + // data into temp structs because we need to apply it after active + // room is loaded. + // See comments to RestoredData struct for further details. + int cam_count = in->ReadInt32(); + for (int i = 0; i < cam_count; ++i) + { + play.CreateRoomCamera(); + ReadCameraState(r_data, in.get()); + } + int view_count = in->ReadInt32(); + for (int i = 0; i < view_count; ++i) + { + play.CreateRoomViewport(); + ReadViewportState(r_data, in.get()); + } + } + return err; +} + +HSaveError WriteAudio(PStream out) +{ + AudioChannelsLock lock; + + // Game content assertion + out->WriteInt32(game.audioClipTypes.size()); + out->WriteInt32(game.audioClips.size()); // [ivan-mogilko] not necessary, kept only to avoid changing save format + // Audio types + for (size_t i = 0; i < game.audioClipTypes.size(); ++i) + { + game.audioClipTypes[i].WriteToSavegame(out.get()); + out->WriteInt32(play.default_audio_type_volumes[i]); + } + + // Audio clips and crossfade + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) + { + auto* ch = lock.GetChannelIfPlaying(i); + if ((ch != nullptr) && (ch->sourceClip != nullptr)) + { + out->WriteInt32(((ScriptAudioClip*)ch->sourceClip)->id); + out->WriteInt32(ch->get_pos()); + out->WriteInt32(ch->priority); + out->WriteInt32(ch->repeat ? 1 : 0); + out->WriteInt32(ch->vol); + out->WriteInt32(ch->panning); + out->WriteInt32(ch->volAsPercentage); + out->WriteInt32(ch->panningAsPercentage); + out->WriteInt32(ch->get_speed()); + // since version 1 + out->WriteInt32(ch->xSource); + out->WriteInt32(ch->ySource); + out->WriteInt32(ch->maximumPossibleDistanceAway); + } + else + { + out->WriteInt32(-1); + } + } + out->WriteInt32(crossFading); + out->WriteInt32(crossFadeVolumePerStep); + out->WriteInt32(crossFadeStep); + out->WriteInt32(crossFadeVolumeAtStart); + // CHECKME: why this needs to be saved? + out->WriteInt32(current_music_type); + + // Ambient sound + for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) + ambient[i].WriteToFile(out.get()); + return HSaveError::None(); +} + +HSaveError ReadAudio(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + // Game content assertion + if (!AssertGameContent(err, in->ReadInt32(), game.audioClipTypes.size(), "Audio Clip Types")) + return err; + in->ReadInt32(); // audio clip count + /* [ivan-mogilko] looks like it's not necessary to assert, as there's no data serialized for clips + if (!AssertGameContent(err, in->ReadInt32(), game.audioClips.size(), "Audio Clips")) + return err;*/ + + // Audio types + for (size_t i = 0; i < game.audioClipTypes.size(); ++i) + { + game.audioClipTypes[i].ReadFromSavegame(in.get()); + play.default_audio_type_volumes[i] = in->ReadInt32(); + } + + // Audio clips and crossfade + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) + { + RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; + chan_info.Pos = 0; + chan_info.ClipID = in->ReadInt32(); + if (chan_info.ClipID >= 0) + { + chan_info.Pos = in->ReadInt32(); + if (chan_info.Pos < 0) + chan_info.Pos = 0; + chan_info.Priority = in->ReadInt32(); + chan_info.Repeat = in->ReadInt32(); + chan_info.Vol = in->ReadInt32(); + chan_info.Pan = in->ReadInt32(); + chan_info.VolAsPercent = in->ReadInt32(); + chan_info.PanAsPercent = in->ReadInt32(); + chan_info.Speed = 1000; + chan_info.Speed = in->ReadInt32(); + if (cmp_ver >= 1) + { + chan_info.XSource = in->ReadInt32(); + chan_info.YSource = in->ReadInt32(); + chan_info.MaxDist = in->ReadInt32(); + } + } + } + crossFading = in->ReadInt32(); + crossFadeVolumePerStep = in->ReadInt32(); + crossFadeStep = in->ReadInt32(); + crossFadeVolumeAtStart = in->ReadInt32(); + // preserve legacy music type setting + current_music_type = in->ReadInt32(); + + // Ambient sound + for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) + ambient[i].ReadFromFile(in.get()); + for (int i = 1; i < MAX_SOUND_CHANNELS; ++i) + { + if (ambient[i].channel == 0) + { + r_data.DoAmbient[i] = 0; + } + else + { + r_data.DoAmbient[i] = ambient[i].num; + ambient[i].channel = 0; + } + } + return err; +} + +void WriteTimesRun272(const Interaction &intr, Stream *out) +{ + for (size_t i = 0; i < intr.Events.size(); ++i) + out->WriteInt32(intr.Events[i].TimesRun); +} + +void WriteInteraction272(const Interaction &intr, Stream *out) +{ + const size_t evt_count = intr.Events.size(); + out->WriteInt32(evt_count); + for (size_t i = 0; i < evt_count; ++i) + out->WriteInt32(intr.Events[i].Type); + WriteTimesRun272(intr, out); +} + +void ReadTimesRun272(Interaction &intr, Stream *in) +{ + for (size_t i = 0; i < intr.Events.size(); ++i) + intr.Events[i].TimesRun = in->ReadInt32(); +} + +HSaveError ReadInteraction272(Interaction &intr, Stream *in) +{ + HSaveError err; + const size_t evt_count = in->ReadInt32(); + if (!AssertCompatLimit(err, evt_count, MAX_NEWINTERACTION_EVENTS, "interactions")) + return err; + intr.Events.resize(evt_count); + for (size_t i = 0; i < evt_count; ++i) + intr.Events[i].Type = in->ReadInt32(); + ReadTimesRun272(intr, in); + return err; +} + +HSaveError WriteCharacters(PStream out) +{ + out->WriteInt32(game.numcharacters); + for (int i = 0; i < game.numcharacters; ++i) + { + game.chars[i].WriteToFile(out.get()); + charextra[i].WriteToFile(out.get()); + Properties::WriteValues(play.charProps[i], out.get()); + if (loaded_game_file_version <= kGameVersion_272) + WriteTimesRun272(*game.intrChar[i], out.get()); + // character movement path cache + mls[CHMLSOFFS + i].WriteToFile(out.get()); + } + return HSaveError::None(); +} + +HSaveError ReadCharacters(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numcharacters, "Characters")) + return err; + for (int i = 0; i < game.numcharacters; ++i) + { + game.chars[i].ReadFromFile(in.get()); + charextra[i].ReadFromFile(in.get()); + Properties::ReadValues(play.charProps[i], in.get()); + if (loaded_game_file_version <= kGameVersion_272) + ReadTimesRun272(*game.intrChar[i], in.get()); + // character movement path cache + err = mls[CHMLSOFFS + i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0); + if (!err) + return err; + } + return err; +} + +HSaveError WriteDialogs(PStream out) +{ + out->WriteInt32(game.numdialog); + for (int i = 0; i < game.numdialog; ++i) + { + dialog[i].WriteToSavegame(out.get()); + } + return HSaveError::None(); +} + +HSaveError ReadDialogs(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numdialog, "Dialogs")) + return err; + for (int i = 0; i < game.numdialog; ++i) + { + dialog[i].ReadFromSavegame(in.get()); + } + return err; +} + +HSaveError WriteGUI(PStream out) +{ + // GUI state + WriteFormatTag(out, "GUIs"); + out->WriteInt32(game.numgui); + for (int i = 0; i < game.numgui; ++i) + guis[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUIButtons"); + out->WriteInt32(numguibuts); + for (int i = 0; i < numguibuts; ++i) + guibuts[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUILabels"); + out->WriteInt32(numguilabels); + for (int i = 0; i < numguilabels; ++i) + guilabels[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUIInvWindows"); + out->WriteInt32(numguiinv); + for (int i = 0; i < numguiinv; ++i) + guiinv[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUISliders"); + out->WriteInt32(numguislider); + for (int i = 0; i < numguislider; ++i) + guislider[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUITextBoxes"); + out->WriteInt32(numguitext); + for (int i = 0; i < numguitext; ++i) + guitext[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUIListBoxes"); + out->WriteInt32(numguilist); + for (int i = 0; i < numguilist; ++i) + guilist[i].WriteToSavegame(out.get()); + + // Animated buttons + WriteFormatTag(out, "AnimatedButtons"); + out->WriteInt32(numAnimButs); + for (int i = 0; i < numAnimButs; ++i) + animbuts[i].WriteToFile(out.get()); + return HSaveError::None(); +} + +HSaveError ReadGUI(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + const GuiSvgVersion svg_ver = (GuiSvgVersion)cmp_ver; + // GUI state + if (!AssertFormatTagStrict(err, in, "GUIs")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), game.numgui, "GUIs")) + return err; + for (int i = 0; i < game.numgui; ++i) + guis[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUIButtons")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguibuts, "GUI Buttons")) + return err; + for (int i = 0; i < numguibuts; ++i) + guibuts[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUILabels")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguilabels, "GUI Labels")) + return err; + for (int i = 0; i < numguilabels; ++i) + guilabels[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUIInvWindows")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguiinv, "GUI InvWindows")) + return err; + for (int i = 0; i < numguiinv; ++i) + guiinv[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUISliders")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguislider, "GUI Sliders")) + return err; + for (int i = 0; i < numguislider; ++i) + guislider[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUITextBoxes")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguitext, "GUI TextBoxes")) + return err; + for (int i = 0; i < numguitext; ++i) + guitext[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUIListBoxes")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguilist, "GUI ListBoxes")) + return err; + for (int i = 0; i < numguilist; ++i) + guilist[i].ReadFromSavegame(in.get(), svg_ver); + + // Animated buttons + if (!AssertFormatTagStrict(err, in, "AnimatedButtons")) + return err; + int anim_count = in->ReadInt32(); + if (!AssertCompatLimit(err, anim_count, MAX_ANIMATING_BUTTONS, "animated buttons")) + return err; + numAnimButs = anim_count; + for (int i = 0; i < numAnimButs; ++i) + animbuts[i].ReadFromFile(in.get()); + return err; +} + +HSaveError WriteInventory(PStream out) +{ + out->WriteInt32(game.numinvitems); + for (int i = 0; i < game.numinvitems; ++i) + { + game.invinfo[i].WriteToSavegame(out.get()); + Properties::WriteValues(play.invProps[i], out.get()); + if (loaded_game_file_version <= kGameVersion_272) + WriteTimesRun272(*game.intrInv[i], out.get()); + } + return HSaveError::None(); +} + +HSaveError ReadInventory(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numinvitems, "Inventory Items")) + return err; + for (int i = 0; i < game.numinvitems; ++i) + { + game.invinfo[i].ReadFromSavegame(in.get()); + Properties::ReadValues(play.invProps[i], in.get()); + if (loaded_game_file_version <= kGameVersion_272) + ReadTimesRun272(*game.intrInv[i], in.get()); + } + return err; +} + +HSaveError WriteMouseCursors(PStream out) +{ + out->WriteInt32(game.numcursors); + for (int i = 0; i < game.numcursors; ++i) + { + game.mcurs[i].WriteToSavegame(out.get()); + } + return HSaveError::None(); +} + +HSaveError ReadMouseCursors(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numcursors, "Mouse Cursors")) + return err; + for (int i = 0; i < game.numcursors; ++i) + { + game.mcurs[i].ReadFromSavegame(in.get()); + } + return err; +} + +HSaveError WriteViews(PStream out) +{ + out->WriteInt32(game.numviews); + for (int view = 0; view < game.numviews; ++view) + { + out->WriteInt32(views[view].numLoops); + for (int loop = 0; loop < views[view].numLoops; ++loop) + { + out->WriteInt32(views[view].loops[loop].numFrames); + for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) + { + out->WriteInt32(views[view].loops[loop].frames[frame].sound); + out->WriteInt32(views[view].loops[loop].frames[frame].pic); + } + } + } + return HSaveError::None(); +} + +HSaveError ReadViews(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numviews, "Views")) + return err; + for (int view = 0; view < game.numviews; ++view) + { + if (!AssertGameObjectContent(err, in->ReadInt32(), views[view].numLoops, + "Loops", "View", view)) + return err; + for (int loop = 0; loop < views[view].numLoops; ++loop) + { + if (!AssertGameObjectContent2(err, in->ReadInt32(), views[view].loops[loop].numFrames, + "Frame", "View", view, "Loop", loop)) + return err; + for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) + { + views[view].loops[loop].frames[frame].sound = in->ReadInt32(); + views[view].loops[loop].frames[frame].pic = in->ReadInt32(); + } + } + } + return err; +} + +HSaveError WriteDynamicSprites(PStream out) +{ + const soff_t ref_pos = out->GetPosition(); + out->WriteInt32(0); // number of dynamic sprites + out->WriteInt32(0); // top index + int count = 0; + int top_index = 1; + for (int i = 1; i < spriteset.GetSpriteSlotCount(); ++i) + { + if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) + { + count++; + top_index = i; + out->WriteInt32(i); + out->WriteInt32(game.SpriteInfos[i].Flags); + serialize_bitmap(spriteset[i], out.get()); + } + } + const soff_t end_pos = out->GetPosition(); + out->Seek(ref_pos, kSeekBegin); + out->WriteInt32(count); + out->WriteInt32(top_index); + out->Seek(end_pos, kSeekBegin); + return HSaveError::None(); +} + +HSaveError ReadDynamicSprites(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + const int spr_count = in->ReadInt32(); + // ensure the sprite set is at least large enough + // to accomodate top dynamic sprite index + const int top_index = in->ReadInt32(); + spriteset.EnlargeTo(top_index); + for (int i = 0; i < spr_count; ++i) + { + int id = in->ReadInt32(); + int flags = in->ReadInt32(); + add_dynamic_sprite(id, read_serialized_bitmap(in.get())); + game.SpriteInfos[id].Flags = flags; + } + return err; +} + +HSaveError WriteOverlays(PStream out) +{ + out->WriteInt32(screenover.size()); + for (const auto &over : screenover) + { + over.WriteToFile(out.get()); + serialize_bitmap(over.pic, out.get()); + } + return HSaveError::None(); +} + +HSaveError ReadOverlays(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + size_t over_count = in->ReadInt32(); + for (size_t i = 0; i < over_count; ++i) + { + ScreenOverlay over; + over.ReadFromFile(in.get(), cmp_ver); + if (over.hasSerializedBitmap) + over.pic = read_serialized_bitmap(in.get()); + screenover.push_back(over); + } + return err; +} + +HSaveError WriteDynamicSurfaces(PStream out) +{ + out->WriteInt32(MAX_DYNAMIC_SURFACES); + for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) + { + if (dynamicallyCreatedSurfaces[i] == nullptr) + { + out->WriteInt8(0); + } + else + { + out->WriteInt8(1); + serialize_bitmap(dynamicallyCreatedSurfaces[i], out.get()); + } + } + return HSaveError::None(); +} + +HSaveError ReadDynamicSurfaces(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + if (!AssertCompatLimit(err, in->ReadInt32(), MAX_DYNAMIC_SURFACES, "Drawing Surfaces")) + return err; + // Load the surfaces into a temporary array since ccUnserialiseObjects will destroy them otherwise + r_data.DynamicSurfaces.resize(MAX_DYNAMIC_SURFACES); + for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) + { + if (in->ReadInt8() == 0) + r_data.DynamicSurfaces[i] = nullptr; + else + r_data.DynamicSurfaces[i] = read_serialized_bitmap(in.get()); + } + return err; +} + +HSaveError WriteScriptModules(PStream out) +{ + // write the data segment of the global script + int data_len = gameinst->globaldatasize; + out->WriteInt32(data_len); + if (data_len > 0) + out->Write(gameinst->globaldata, data_len); + // write the script modules data segments + out->WriteInt32(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) + { + data_len = moduleInst[i]->globaldatasize; + out->WriteInt32(data_len); + if (data_len > 0) + out->Write(moduleInst[i]->globaldata, data_len); + } + return HSaveError::None(); +} + +HSaveError ReadScriptModules(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + // read the global script data segment + int data_len = in->ReadInt32(); + if (!AssertGameContent(err, data_len, pp.GlScDataSize, "global script data")) + return err; + r_data.GlobalScript.Len = data_len; + r_data.GlobalScript.Data.reset(new char[data_len]); + in->Read(r_data.GlobalScript.Data.get(), data_len); + + if (!AssertGameContent(err, in->ReadInt32(), numScriptModules, "Script Modules")) + return err; + r_data.ScriptModules.resize(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) + { + data_len = in->ReadInt32(); + if (!AssertGameObjectContent(err, data_len, pp.ScMdDataSize[i], "script module data", "module", i)) + return err; + r_data.ScriptModules[i].Len = data_len; + r_data.ScriptModules[i].Data.reset(new char[data_len]); + in->Read(r_data.ScriptModules[i].Data.get(), data_len); + } + return err; +} + +HSaveError WriteRoomStates(PStream out) +{ + // write the room state for all the rooms the player has been in + out->WriteInt32(MAX_ROOMS); + for (int i = 0; i < MAX_ROOMS; ++i) + { + if (isRoomStatusValid(i)) + { + RoomStatus *roomstat = getRoomStatus(i); + if (roomstat->beenhere) + { + out->WriteInt32(i); + WriteFormatTag(out, "RoomState", true); + roomstat->WriteToSavegame(out.get()); + WriteFormatTag(out, "RoomState", false); + } + else + out->WriteInt32(-1); + } + else + out->WriteInt32(-1); + } + return HSaveError::None(); +} + +HSaveError ReadRoomStates(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + int roomstat_count = in->ReadInt32(); + for (; roomstat_count > 0; --roomstat_count) + { + int id = in->ReadInt32(); + // If id == -1, then the player has not been there yet (or room state was reset) + if (id != -1) + { + if (!AssertCompatRange(err, id, 0, MAX_ROOMS - 1, "room index")) + return err; + if (!AssertFormatTagStrict(err, in, "RoomState", true)) + return err; + RoomStatus *roomstat = getRoomStatus(id); + roomstat->ReadFromSavegame(in.get()); + if (!AssertFormatTagStrict(err, in, "RoomState", false)) + return err; + } + } + return HSaveError::None(); +} + +HSaveError WriteThisRoom(PStream out) +{ + out->WriteInt32(displayed_room); + if (displayed_room < 0) + return HSaveError::None(); + + // modified room backgrounds + for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) + { + out->WriteBool(play.raw_modified[i] != 0); + if (play.raw_modified[i]) + serialize_bitmap(thisroom.BgFrames[i].Graphic.get(), out.get()); + } + out->WriteBool(raw_saved_screen != nullptr); + if (raw_saved_screen) + serialize_bitmap(raw_saved_screen, out.get()); + + // room region state + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) + { + out->WriteInt32(thisroom.Regions[i].Light); + out->WriteInt32(thisroom.Regions[i].Tint); + } + for (int i = 0; i < MAX_WALK_AREAS + 1; ++i) + { + out->WriteInt32(thisroom.WalkAreas[i].ScalingFar); + out->WriteInt32(thisroom.WalkAreas[i].ScalingNear); + } + + // room object movement paths cache + out->WriteInt32(thisroom.ObjectCount + 1); + for (size_t i = 0; i < thisroom.ObjectCount + 1; ++i) + { + mls[i].WriteToFile(out.get()); + } + + // room music volume + out->WriteInt32(thisroom.Options.MusicVolume); + + // persistent room's indicator + const bool persist = displayed_room < MAX_ROOMS; + out->WriteBool(persist); + // write the current troom state, in case they save in temporary room + if (!persist) + troom.WriteToSavegame(out.get()); + return HSaveError::None(); +} + +HSaveError ReadThisRoom(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + HSaveError err; + displayed_room = in->ReadInt32(); + if (displayed_room < 0) + return err; + + // modified room backgrounds + for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) + { + play.raw_modified[i] = in->ReadBool(); + if (play.raw_modified[i]) + r_data.RoomBkgScene[i].reset(read_serialized_bitmap(in.get())); + else + r_data.RoomBkgScene[i] = nullptr; + } + if (in->ReadBool()) + raw_saved_screen = read_serialized_bitmap(in.get()); + + // room region state + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) + { + r_data.RoomLightLevels[i] = in->ReadInt32(); + r_data.RoomTintLevels[i] = in->ReadInt32(); + } + for (int i = 0; i < MAX_WALK_AREAS + 1; ++i) + { + r_data.RoomZoomLevels1[i] = in->ReadInt32(); + r_data.RoomZoomLevels2[i] = in->ReadInt32(); + } + + // room object movement paths cache + int objmls_count = in->ReadInt32(); + if (!AssertCompatLimit(err, objmls_count, CHMLSOFFS, "room object move lists")) + return err; + for (int i = 0; i < objmls_count; ++i) + { + err = mls[i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0); + if (!err) + return err; + } + + // save the new room music vol for later use + r_data.RoomVolume = (RoomVolumeMod)in->ReadInt32(); + + // read the current troom state, in case they saved in temporary room + if (!in->ReadBool()) + troom.ReadFromSavegame(in.get()); + + return HSaveError::None(); +} + +HSaveError WriteManagedPool(PStream out) +{ + ccSerializeAllObjects(out.get()); + return HSaveError::None(); +} + +HSaveError ReadManagedPool(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + if (ccUnserializeAllObjects(in.get(), &ccUnserializer)) + { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Managed pool deserialization failed: %s", ccErrorString.GetCStr())); + } + return HSaveError::None(); +} + +HSaveError WritePluginData(PStream out) +{ + auto pluginFileHandle = AGSE_SAVEGAME; + pl_set_file_handle(pluginFileHandle, out.get()); + pl_run_plugin_hooks(AGSE_SAVEGAME, pluginFileHandle); + pl_clear_file_handle(); + return HSaveError::None(); +} + +HSaveError ReadPluginData(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) +{ + auto pluginFileHandle = AGSE_RESTOREGAME; + pl_set_file_handle(pluginFileHandle, in.get()); + pl_run_plugin_hooks(AGSE_RESTOREGAME, pluginFileHandle); + pl_clear_file_handle(); + return HSaveError::None(); +} + + +// Description of a supported game state serialization component +struct ComponentHandler +{ + String Name; // internal component's ID + int32_t Version; // current version to write and the highest supported version + int32_t LowestVersion; // lowest supported version that the engine can read + HSaveError (*Serialize) (PStream); + HSaveError (*Unserialize)(PStream, int32_t cmp_ver, const PreservedParams&, RestoredData&); +}; + +// Array of supported components +ComponentHandler ComponentHandlers[] = +{ + { + "Game State", + kGSSvgVersion_3510, + kGSSvgVersion_Initial, + WriteGameState, + ReadGameState + }, + { + "Audio", + 1, + 0, + WriteAudio, + ReadAudio + }, + { + "Characters", + 1, + 0, + WriteCharacters, + ReadCharacters + }, + { + "Dialogs", + 0, + 0, + WriteDialogs, + ReadDialogs + }, + { + "GUI", + kGuiSvgVersion_350, + kGuiSvgVersion_Initial, + WriteGUI, + ReadGUI + }, + { + "Inventory Items", + 0, + 0, + WriteInventory, + ReadInventory + }, + { + "Mouse Cursors", + 0, + 0, + WriteMouseCursors, + ReadMouseCursors + }, + { + "Views", + 0, + 0, + WriteViews, + ReadViews + }, + { + "Dynamic Sprites", + 0, + 0, + WriteDynamicSprites, + ReadDynamicSprites + }, + { + "Overlays", + 1, + 0, + WriteOverlays, + ReadOverlays + }, + { + "Drawing Surfaces", + 0, + 0, + WriteDynamicSurfaces, + ReadDynamicSurfaces + }, + { + "Script Modules", + 0, + 0, + WriteScriptModules, + ReadScriptModules + }, + { + "Room States", + 0, + 0, + WriteRoomStates, + ReadRoomStates + }, + { + "Loaded Room State", + 1, + 0, + WriteThisRoom, + ReadThisRoom + }, + { + "Managed Pool", + 1, + 0, + WriteManagedPool, + ReadManagedPool + }, + { + "Plugin Data", + 0, + 0, + WritePluginData, + ReadPluginData + }, + { nullptr, 0, 0, nullptr, nullptr } // end of array +}; + + +typedef std::map HandlersMap; +void GenerateHandlersMap(HandlersMap &map) +{ + map.clear(); + for (int i = 0; !ComponentHandlers[i].Name.IsEmpty(); ++i) + map[ComponentHandlers[i].Name] = ComponentHandlers[i]; +} + +// A helper struct to pass to (de)serialization handlers +struct SvgCmpReadHelper +{ + SavegameVersion Version; // general savegame version + const PreservedParams &PP; // previous game state kept for reference + RestoredData &RData; // temporary storage for loaded data, that + // will be applied after loading is done + // The map of serialization handlers, one per supported component type ID + HandlersMap Handlers; + + SvgCmpReadHelper(SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) + : Version(svg_version) + , PP(pp) + , RData(r_data) + { + } +}; + +// The basic information about deserialized component, used for debugging purposes +struct ComponentInfo +{ + String Name; // internal component's ID + int32_t Version; // data format version + soff_t Offset; // offset at which an opening tag is located + soff_t DataOffset; // offset at which component data begins + soff_t DataSize; // expected size of component data + + ComponentInfo() : Version(-1), Offset(0), DataOffset(0), DataSize(0) {} +}; + +HSaveError ReadComponent(PStream in, SvgCmpReadHelper &hlp, ComponentInfo &info) +{ + info = ComponentInfo(); // reset in case of early error + info.Offset = in->GetPosition(); + if (!ReadFormatTag(in, info.Name, true)) + return new SavegameError(kSvgErr_ComponentOpeningTagFormat); + info.Version = in->ReadInt32(); + info.DataSize = hlp.Version >= kSvgVersion_Cmp_64bit ? in->ReadInt64() : in->ReadInt32(); + info.DataOffset = in->GetPosition(); + + const ComponentHandler *handler = nullptr; + std::map::const_iterator it_hdr = hlp.Handlers.find(info.Name); + if (it_hdr != hlp.Handlers.end()) + handler = &it_hdr->second; + + if (!handler || !handler->Unserialize) + return new SavegameError(kSvgErr_UnsupportedComponent); + if (info.Version > handler->Version || info.Version < handler->LowestVersion) + return new SavegameError(kSvgErr_UnsupportedComponentVersion, String::FromFormat("Saved version: %d, supported: %d - %d", info.Version, handler->LowestVersion, handler->Version)); + HSaveError err = handler->Unserialize(in, info.Version, hlp.PP, hlp.RData); + if (!err) + return err; + if (in->GetPosition() - info.DataOffset != info.DataSize) + return new SavegameError(kSvgErr_ComponentSizeMismatch, String::FromFormat("Expected: %lld, actual: %lld", info.DataSize, in->GetPosition() - info.DataOffset)); + if (!AssertFormatTag(in, info.Name, false)) + return new SavegameError(kSvgErr_ComponentClosingTagFormat); + return HSaveError::None(); +} + +HSaveError ReadAll(PStream in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) +{ + // Prepare a helper struct we will be passing to the block reading proc + SvgCmpReadHelper hlp(svg_version, pp, r_data); + GenerateHandlersMap(hlp.Handlers); + + size_t idx = 0; + if (!AssertFormatTag(in, ComponentListTag, true)) + return new SavegameError(kSvgErr_ComponentListOpeningTagFormat); + do + { + // Look out for the end of the component list: + // this is the only way how this function ends with success + soff_t off = in->GetPosition(); + if (AssertFormatTag(in, ComponentListTag, false)) + return HSaveError::None(); + // If the list's end was not detected, then seek back and continue reading + in->Seek(off, kSeekBegin); + + ComponentInfo info; + HSaveError err = ReadComponent(in, hlp, info); + if (!err) + { + return new SavegameError(kSvgErr_ComponentUnserialization, + String::FromFormat("(#%d) %s, version %i, at offset %u.", + idx, info.Name.IsEmpty() ? "unknown" : info.Name.GetCStr(), info.Version, info.Offset), + err); + } + update_polled_stuff_if_runtime(); + idx++; + } + while (!in->EOS()); + return new SavegameError(kSvgErr_ComponentListClosingTagMissing); +} + +HSaveError WriteComponent(PStream out, ComponentHandler &hdlr) +{ + WriteFormatTag(out, hdlr.Name, true); + out->WriteInt32(hdlr.Version); + soff_t ref_pos = out->GetPosition(); + out->WriteInt64(0); // placeholder for the component size + HSaveError err = hdlr.Serialize(out); + soff_t end_pos = out->GetPosition(); + out->Seek(ref_pos, kSeekBegin); + out->WriteInt64(end_pos - ref_pos - sizeof(int64_t)); // size of serialized component data + out->Seek(end_pos, kSeekBegin); + if (err) + WriteFormatTag(out, hdlr.Name, false); + return err; +} + +HSaveError WriteAllCommon(PStream out) +{ + WriteFormatTag(out, ComponentListTag, true); + for (int type = 0; !ComponentHandlers[type].Name.IsEmpty(); ++type) + { + HSaveError err = WriteComponent(out, ComponentHandlers[type]); + if (!err) + { + return new SavegameError(kSvgErr_ComponentSerialization, + String::FromFormat("Component: (#%d) %s", type, ComponentHandlers[type].Name.GetCStr()), + err); + } + update_polled_stuff_if_runtime(); + } + WriteFormatTag(out, ComponentListTag, false); + return HSaveError::None(); +} + +} // namespace SavegameBlocks +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h new file mode 100644 index 000000000000..7f44872bdd89 --- /dev/null +++ b/engines/ags/engine/game/savegame_components.h @@ -0,0 +1,56 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_GAME__SAVEGAMECOMPONENTS_H +#define __AGS_EE_GAME__SAVEGAMECOMPONENTS_H + +#include "game/savegame.h" +#include "util/stream.h" + +namespace AGS +{ + +namespace Common { struct Interaction; } + +namespace Engine +{ + +using Common::Stream; +typedef std::shared_ptr PStream; + +struct PreservedParams; +struct RestoredData; + +namespace SavegameComponents +{ + // Reads all available components from the stream + HSaveError ReadAll(PStream in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data); + // Writes a full list of common components to the stream + HSaveError WriteAllCommon(PStream out); + + // Utility functions for reading and writing legacy interactions, + // or their "times run" counters separately. + void ReadTimesRun272(Interaction &intr, Stream *in); + HSaveError ReadInteraction272(Interaction &intr, Stream *in); + void WriteTimesRun272(const Interaction &intr, Stream *out); + void WriteInteraction272(const Interaction &intr, Stream *out); + + // Precreates primary camera and viewport and reads legacy camera data + void ReadLegacyCameraState(Stream *in, RestoredData &r_data); +} + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GAME__SAVEGAMECOMPONENTS_H diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h new file mode 100644 index 000000000000..8a0d08b45fe3 --- /dev/null +++ b/engines/ags/engine/game/savegame_internal.h @@ -0,0 +1,144 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_GAME__SAVEGAMEINTERNAL_H +#define __AGS_EE_GAME__SAVEGAMEINTERNAL_H + +#include +#include +#include "ac/common_defines.h" +#include "gfx/bitmap.h" +#include "media/audio/audiodefines.h" + + +namespace AGS +{ +namespace Engine +{ + +using AGS::Common::Bitmap; + +typedef std::shared_ptr PBitmap; + +// PreservedParams keeps old values of particular gameplay +// parameters that are saved before the save restoration +// and either applied or compared to new values after +// loading save data +struct PreservedParams +{ + // Whether speech and audio packages available + int SpeechVOX; + int MusicVOX; + // Script global data sizes + int GlScDataSize; + std::vector ScMdDataSize; + + PreservedParams(); +}; + +enum GameViewCamFlags +{ + kSvgGameAutoRoomView = 0x01 +}; + +enum CameraSaveFlags +{ + kSvgCamPosLocked = 0x01 +}; + +enum ViewportSaveFlags +{ + kSvgViewportVisible = 0x01 +}; + +// RestoredData keeps certain temporary data to help with +// the restoration process +struct RestoredData +{ + int FPS; + // Unserialized bitmaps for dynamic surfaces + std::vector DynamicSurfaces; + // Scripts global data + struct ScriptData + { + std::shared_ptr Data; + size_t Len; + + ScriptData(); + }; + ScriptData GlobalScript; + std::vector ScriptModules; + // Room data (has to be be preserved until room is loaded) + PBitmap RoomBkgScene[MAX_ROOM_BGFRAMES]; + short RoomLightLevels[MAX_ROOM_REGIONS]; + int RoomTintLevels[MAX_ROOM_REGIONS]; + short RoomZoomLevels1[MAX_WALK_AREAS + 1]; + short RoomZoomLevels2[MAX_WALK_AREAS + 1]; + RoomVolumeMod RoomVolume; + // Mouse cursor parameters + int CursorID; + int CursorMode; + // General audio + struct ChannelInfo + { + int ClipID = 0; + int Pos = 0; + int Priority = 0; + int Repeat = 0; + int Vol = 0; + int VolAsPercent = 0; + int Pan = 0; + int PanAsPercent = 0; + int Speed = 0; + // since version 1 + int XSource = -1; + int YSource = -1; + int MaxDist = 0; + }; + ChannelInfo AudioChans[MAX_SOUND_CHANNELS + 1]; + // Ambient sounds + int DoAmbient[MAX_SOUND_CHANNELS]; + // Viewport and camera data, has to be preserved and applied only after + // room gets loaded, because we must clamp these to room parameters. + struct ViewportData + { + int ID = -1; + int Flags = 0; + int Left = 0; + int Top = 0; + int Width = 0; + int Height = 0; + int ZOrder = 0; + int CamID = -1; + }; + struct CameraData + { + int ID = -1; + int Flags = 0; + int Left = 0; + int Top = 0; + int Width = 0; + int Height = 0; + }; + std::vector Viewports; + std::vector Cameras; + int32_t Camera0_Flags = 0; // flags for primary camera, when data is read in legacy order + + RestoredData(); +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GAME__SAVEGAMEINTERNAL_H diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp new file mode 100644 index 000000000000..eea1d980f167 --- /dev/null +++ b/engines/ags/engine/game/viewport.cpp @@ -0,0 +1,224 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "ac/draw.h" +#include "ac/gamestate.h" +#include "debug/debug_log.h" +#include "game/roomstruct.h" +#include "game/viewport.h" + +using namespace AGS::Common; + +extern RoomStruct thisroom; + +void Camera::SetID(int id) +{ + _id = id; +} + +// Returns Room camera position and size inside the room (in room coordinates) +const Rect &Camera::GetRect() const +{ + return _position; +} + +// Sets explicit room camera's orthographic size +void Camera::SetSize(const Size cam_size) +{ + // TODO: currently we don't support having camera larger than room background + // (or rather - looking outside of the room background); look into this later + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + Size real_size = Size::Clamp(cam_size, Size(1, 1), real_room_sz); + + _position.SetWidth(real_size.Width); + _position.SetHeight(real_size.Height); + for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) + { + auto locked_vp = vp->lock(); + if (locked_vp) + locked_vp->AdjustTransformation(); + } + _hasChangedSize = true; +} + +// Puts room camera to the new location in the room +void Camera::SetAt(int x, int y) +{ + int cw = _position.GetWidth(); + int ch = _position.GetHeight(); + int room_width = data_to_game_coord(thisroom.Width); + int room_height = data_to_game_coord(thisroom.Height); + x = Math::Clamp(x, 0, room_width - cw); + y = Math::Clamp(y, 0, room_height - ch); + _position.MoveTo(Point(x, y)); + _hasChangedPosition = true; +} + +// Tells if camera is currently locked at custom position +bool Camera::IsLocked() const +{ + return _locked; +} + +// Locks room camera at its current position +void Camera::Lock() +{ + debug_script_log("Room camera locked"); + _locked = true; +} + +// Similar to SetAt, but also locks camera preventing it from following player character +void Camera::LockAt(int x, int y) +{ + debug_script_log("Room camera locked to %d,%d", x, y); + SetAt(x, y); + _locked = true; +} + +// Releases camera lock, letting it follow player character +void Camera::Release() +{ + _locked = false; + debug_script_log("Room camera released back to engine control"); +} + +// Link this camera to a new viewport; this does not unlink any linked ones +void Camera::LinkToViewport(ViewportRef viewport) +{ + auto new_locked = viewport.lock(); + if (!new_locked) + return; + for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) + { + auto old_locked = vp->lock(); + if (old_locked->GetID() == new_locked->GetID()) + return; + } + _viewportRefs.push_back(viewport); +} + +// Unlinks this camera from a given viewport; does nothing if link did not exist +void Camera::UnlinkFromViewport(int id) +{ + for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) + { + auto locked = vp->lock(); + if (locked && locked->GetID() == id) + { + _viewportRefs.erase(vp); + return; + } + } +} + +const std::vector &Camera::GetLinkedViewports() const +{ + return _viewportRefs; +} + +void Viewport::SetID(int id) +{ + _id = id; +} + +void Viewport::SetRect(const Rect &rc) +{ + // TODO: consider allowing size 0,0, in which case viewport is considered not visible + Size fix_size = rc.GetSize().IsNull() ? Size(1, 1) : rc.GetSize(); + _position = RectWH(rc.Left, rc.Top, fix_size.Width, fix_size.Height); + AdjustTransformation(); + _hasChangedPosition = true; + _hasChangedSize = true; +} + +void Viewport::SetSize(const Size sz) +{ + // TODO: consider allowing size 0,0, in which case viewport is considered not visible + Size fix_size = sz.IsNull() ? Size(1, 1) : sz; + _position = RectWH(_position.Left, _position.Top, fix_size.Width, fix_size.Height); + AdjustTransformation(); + _hasChangedSize = true; +} + +void Viewport::SetAt(int x, int y) +{ + _position.MoveTo(Point(x, y)); + AdjustTransformation(); + _hasChangedPosition = true; +} + +void Viewport::SetVisible(bool on) +{ + _visible = on; + _hasChangedVisible = true; +} + +void Viewport::SetZOrder(int zorder) +{ + _zorder = zorder; + _hasChangedVisible = true; +} + +void Viewport::AdjustTransformation() +{ + auto locked_cam = _camera.lock(); + if (locked_cam) + _transform.Init(locked_cam->GetRect().GetSize(), _position); +} + +PCamera Viewport::GetCamera() const +{ + return _camera.lock(); +} + +void Viewport::LinkCamera(PCamera cam) +{ + _camera = cam; + AdjustTransformation(); +} + +VpPoint Viewport::RoomToScreen(int roomx, int roomy, bool clip) const +{ + auto cam = _camera.lock(); + if (!cam) + return std::make_pair(Point(), -1); + const Rect &camr = cam->GetRect(); + Point screen_pt = _transform.Scale(Point(roomx - camr.Left, roomy - camr.Top)); + if (clip && !_position.IsInside(screen_pt)) + return std::make_pair(Point(), -1); + return std::make_pair(screen_pt, _id); +} + +VpPoint Viewport::ScreenToRoom(int scrx, int scry, bool clip, bool convert_cam_to_data) const +{ + Point screen_pt(scrx, scry); + if (clip && !_position.IsInside(screen_pt)) + return std::make_pair(Point(), -1); + auto cam = _camera.lock(); + if (!cam) + return std::make_pair(Point(), -1); + + const Rect &camr = cam->GetRect(); + Point p = _transform.UnScale(screen_pt); + if (convert_cam_to_data) + { + p.X += game_to_data_coord(camr.Left); + p.Y += game_to_data_coord(camr.Top); + } + else + { + p.X += camr.Left; + p.Y += camr.Top; + } + return std::make_pair(p, _id); +} diff --git a/engines/ags/engine/game/viewport.h b/engines/ags/engine/game/viewport.h new file mode 100644 index 000000000000..4fcc6abc7384 --- /dev/null +++ b/engines/ags/engine/game/viewport.h @@ -0,0 +1,192 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Definition for the game viewports and cameras. +// +//============================================================================= +#ifndef __AGS_EE_AC__VIEWPORT_H +#define __AGS_EE_AC__VIEWPORT_H + +#include +#include +#include "util/geometry.h" +#include "util/scaling.h" + +class Camera; +class Viewport; + +typedef std::shared_ptr PCamera; +typedef std::shared_ptr PViewport; +typedef std::weak_ptr CameraRef; +typedef std::weak_ptr ViewportRef; + +// TODO: move to utility header +// From https://stackoverflow.com/questions/45507041/how-to-check-if-weak-ptr-is-empty-non-assigned +// Tests that weak_ptr is empty (was not initialized with valid reference) +template +bool is_uninitialized(std::weak_ptr const& weak) { + using wt = std::weak_ptr; + return !weak.owner_before(wt{}) && !wt{}.owner_before(weak); +} + + +// Camera defines a "looking eye" inside the room, its position and size. +// It does not render anywhere on its own, instead it is linked to a viewport +// and latter draws what that camera sees. +// One camera may be linked to multiple viewports. +// Camera does not move on its own, this is performed by separate behavior +// algorithm. But it provides "lock" property that tells if its position is +// currently owned by user script. +class Camera +{ +public: + // Gets camera ID (serves as an index) + inline int GetID() const { return _id; } + // Sets new camera ID + void SetID(int id); + // Returns Room camera position and size inside the room (in room coordinates) + const Rect &GetRect() const; + // Sets explicit room camera's orthographic size + void SetSize(const Size sz); + // Puts room camera to the new location in the room + void SetAt(int x, int y); + // Tells if camera is currently locked at custom position + bool IsLocked() const; + // Locks room camera at its current position + void Lock(); + // Similar to SetAt, but also locks camera preventing it from following player character + void LockAt(int x, int y); + // Releases camera lock, letting it follow player character + void Release(); + + // Link this camera to a new viewport; this does not unlink any linked ones + void LinkToViewport(ViewportRef viewport); + // Unlinks this camera from a given viewport; does nothing if link did not exist + void UnlinkFromViewport(int id); + // Get the array of linked viewport references + const std::vector &GetLinkedViewports() const; + + // Tell if this camera has changed recently + inline bool HasChangedPosition() const { return _hasChangedPosition; } + inline bool HasChangedSize() const { return _hasChangedSize; } + // Clears the changed flags + void ClearChangedFlags() + { + _hasChangedPosition = false; + _hasChangedSize = false; + } + +private: + int _id = -1; + // Actual position and orthographic size + Rect _position; + // Locked or following player automatically + bool _locked = false; + // Linked viewport refs, used to notify viewports of camera changes + std::vector _viewportRefs; + // Flags that tell whether this camera's position on screen has changed recently + bool _hasChangedPosition = false; + bool _hasChangedSize = false; +}; + + +// A result of coordinate conversion between screen and the room, +// tells which viewport was used to pass the "touch" through. +typedef std::pair VpPoint; + + +// Viewport class defines a rectangular area on game screen where the contents +// of a Camera are rendered. +// Viewport may have one linked camera at a time. +class Viewport +{ +public: + // Gets viewport ID (serves as an index) + inline int GetID() const { return _id; } + // Sets new viewport ID + void SetID(int id); + // Returns viewport's position on screen + inline const Rect &GetRect() const { return _position; } + // Returns viewport's room-to-screen transformation + inline const AGS::Engine::PlaneScaling &GetTransform() const { return _transform; } + // Set viewport's rectangle on screen + void SetRect(const Rect &rc); + // Sets viewport size + void SetSize(const Size sz); + // Sets viewport's position on screen + void SetAt(int x, int y); + + // Tells whether viewport content is rendered on screen + bool IsVisible() const { return _visible; } + // Changes viewport visibility + void SetVisible(bool on); + // Gets the order viewport is displayed on screen + int GetZOrder() const { return _zorder; } + // Sets the viewport's z-order on screen + void SetZOrder(int zorder); + + // Calculates room-to-viewport coordinate conversion. + void AdjustTransformation(); + // Returns linked camera + PCamera GetCamera() const; + // Links new camera to this viewport, overriding existing link; + // pass nullptr to leave viewport without a camera link + void LinkCamera(PCamera cam); + + // TODO: provide a Transform object here that does these conversions instead + // Converts room coordinates to the game screen coordinates through this viewport; + // if clipping is on, the function will fail for room coordinates outside of camera + VpPoint RoomToScreen(int roomx, int roomy, bool clip = false) const; + // Converts game screen coordinates to the room coordinates through this viewport; + // if clipping is on, the function will fail for screen coordinates outside of viewport; + // convert_cam_to_data parameter converts camera "game" coordinates to "data" units (legacy mode) + VpPoint ScreenToRoom(int scrx, int scry, bool clip = false, bool convert_cam_to_data = false) const; + + // Following functions tell if this viewport has changed recently + inline bool HasChangedPosition() const { return _hasChangedPosition; } + inline bool HasChangedSize() const { return _hasChangedSize; } + inline bool HasChangedVisible() const { return _hasChangedVisible; } + inline void SetChangedVisible() { _hasChangedVisible = true; } + // Clears the changed flags + inline void ClearChangedFlags() + { + _hasChangedPosition = false; + _hasChangedSize = false; + _hasChangedVisible = false; + } + +private: + // Parameterized implementation of screen-to-room coordinate conversion + VpPoint ScreenToRoomImpl(int scrx, int scry, bool clip, bool convert_cam_to_data); + + int _id = -1; + // Position of the viewport on screen + Rect _position; + // TODO: Camera reference (when supporting multiple cameras) + // Coordinate tranform between camera and viewport + // TODO: need to add rotate conversion to let script API support that; + // (maybe use full 3D matrix for that) + AGS::Engine::PlaneScaling _transform; + // Linked camera reference + CameraRef _camera; + bool _visible = true; + int _zorder = 0; + // Flags that tell whether this viewport's position on screen has changed recently + bool _hasChangedPosition = false; + bool _hasChangedOffscreen = false; + bool _hasChangedSize = false; + bool _hasChangedVisible = false; +}; + +#endif // __AGS_EE_AC__VIEWPORT_H diff --git a/engines/ags/engine/gfx/ali3dexception.h b/engines/ags/engine/gfx/ali3dexception.h new file mode 100644 index 000000000000..8c9580330dab --- /dev/null +++ b/engines/ags/engine/gfx/ali3dexception.h @@ -0,0 +1,49 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Graphics driver exception class +// +//============================================================================= + +#ifndef __AGS_EE_GFX__ALI3DEXCEPTION_H +#define __AGS_EE_GFX__ALI3DEXCEPTION_H + +namespace AGS +{ +namespace Engine +{ + +class Ali3DException +{ +public: + Ali3DException(const char *message) + { + _message = message; + } + + const char *_message; +}; + +class Ali3DFullscreenLostException : public Ali3DException +{ +public: + Ali3DFullscreenLostException() : Ali3DException("User has switched away from application") + { + } +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__ALI3DEXCEPTION_H diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp new file mode 100644 index 000000000000..cab864e668d9 --- /dev/null +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -0,0 +1,2065 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX + +#include +#include "gfx/ali3dexception.h" +#include "gfx/ali3dogl.h" +#include "gfx/gfxfilter_ogl.h" +#include "gfx/gfxfilter_aaogl.h" +#include "gfx/gfx_util.h" +#include "main/main_allegro.h" +#include "platform/base/agsplatformdriver.h" +#include "util/math.h" +#include "ac/timer.h" + +#if AGS_PLATFORM_OS_ANDROID + +#define glOrtho glOrthof +#define GL_CLAMP GL_CLAMP_TO_EDGE + +// Defined in Allegro +extern "C" +{ + void android_swap_buffers(); + void android_create_screen(int width, int height, int color_depth); + void android_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); +} + +extern "C" void android_debug_printf(char* format, ...); + +extern unsigned int android_screen_physical_width; +extern unsigned int android_screen_physical_height; +extern int android_screen_initialized; + +#define device_screen_initialized android_screen_initialized +#define device_mouse_setup android_mouse_setup +#define device_swap_buffers android_swap_buffers + +const char* fbo_extension_string = "GL_OES_framebuffer_object"; + +#define glGenFramebuffersEXT glGenFramebuffersOES +#define glDeleteFramebuffersEXT glDeleteFramebuffersOES +#define glBindFramebufferEXT glBindFramebufferOES +#define glCheckFramebufferStatusEXT glCheckFramebufferStatusOES +#define glGetFramebufferAttachmentParameterivEXT glGetFramebufferAttachmentParameterivOES +#define glGenerateMipmapEXT glGenerateMipmapOES +#define glFramebufferTexture2DEXT glFramebufferTexture2DOES +#define glFramebufferRenderbufferEXT glFramebufferRenderbufferOES +// TODO: probably should use EGL and function eglSwapInterval on Android to support setting swap interval +// For now this is a dummy function pointer which is only used to test that function is not supported +const void (*glSwapIntervalEXT)(int) = NULL; + +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES +#define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES + +#elif AGS_PLATFORM_OS_IOS + +extern "C" +{ + void ios_swap_buffers(); + void ios_select_buffer(); + void ios_create_screen(); + float get_device_scale(); + void ios_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); +} + +#define glOrtho glOrthof +#define GL_CLAMP GL_CLAMP_TO_EDGE + +extern unsigned int ios_screen_physical_width; +extern unsigned int ios_screen_physical_height; +extern int ios_screen_initialized; + +#define device_screen_initialized ios_screen_initialized +#define device_mouse_setup ios_mouse_setup +#define device_swap_buffers ios_swap_buffers + +const char* fbo_extension_string = "GL_OES_framebuffer_object"; + +#define glGenFramebuffersEXT glGenFramebuffersOES +#define glDeleteFramebuffersEXT glDeleteFramebuffersOES +#define glBindFramebufferEXT glBindFramebufferOES +#define glCheckFramebufferStatusEXT glCheckFramebufferStatusOES +#define glGetFramebufferAttachmentParameterivEXT glGetFramebufferAttachmentParameterivOES +#define glGenerateMipmapEXT glGenerateMipmapOES +#define glFramebufferTexture2DEXT glFramebufferTexture2DOES +#define glFramebufferRenderbufferEXT glFramebufferRenderbufferOES +// TODO: find out how to support swap interval setting on iOS +// For now this is a dummy function pointer which is only used to test that function is not supported +const void (*glSwapIntervalEXT)(int) = NULL; + +#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES +#define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES + +#endif + +// Necessary to update textures from 8-bit bitmaps +extern RGB palette[256]; + + +namespace AGS +{ +namespace Engine +{ +namespace OGL +{ + +using namespace AGS::Common; + +void ogl_dummy_vsync() { } + +#define GFX_OPENGL AL_ID('O','G','L',' ') + +GFX_DRIVER gfx_opengl = +{ + GFX_OPENGL, + empty_string, + empty_string, + "OpenGL", + nullptr, // init + nullptr, // exit + nullptr, // AL_METHOD(int, scroll, (int x, int y)); + ogl_dummy_vsync, // vsync + nullptr, // setpalette + nullptr, // AL_METHOD(int, request_scroll, (int x, int y)); + nullptr, // AL_METHOD(int, poll_scroll, (void)); + nullptr, // AL_METHOD(void, enable_triple_buffer, (void)); + nullptr, //create_video_bitmap + nullptr, //destroy_video_bitmap + nullptr, //show_video_bitmap + nullptr, + nullptr, //gfx_directx_create_system_bitmap, + nullptr, //gfx_directx_destroy_system_bitmap, + nullptr, //gfx_directx_set_mouse_sprite, + nullptr, //gfx_directx_show_mouse, + nullptr, //gfx_directx_hide_mouse, + nullptr, //gfx_directx_move_mouse, + nullptr, // AL_METHOD(void, drawing_mode, (void)); + nullptr, // AL_METHOD(void, save_video_state, (void*)); + nullptr, // AL_METHOD(void, restore_video_state, (void*)); + nullptr, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); + nullptr, // AL_METHOD(int, fetch_mode_list, (void)); + 0, 0, // int w, h; + FALSE, // int linear; + 0, // long bank_size; + 0, // long bank_gran; + 0, // long vid_mem; + 0, // long vid_phys_base; + TRUE // int windowed; +}; + +void OGLBitmap::Dispose() +{ + if (_tiles != nullptr) + { + for (int i = 0; i < _numTiles; i++) + glDeleteTextures(1, &(_tiles[i].texture)); + + free(_tiles); + _tiles = nullptr; + _numTiles = 0; + } + if (_vertex != nullptr) + { + free(_vertex); + _vertex = nullptr; + } +} + + +OGLGraphicsDriver::ShaderProgram::ShaderProgram() : Program(0), SamplerVar(0), ColorVar(0), AuxVar(0) {} + + +OGLGraphicsDriver::OGLGraphicsDriver() +{ +#if AGS_PLATFORM_OS_WINDOWS + _hDC = NULL; + _hRC = NULL; + _hWnd = NULL; + _hInstance = NULL; + device_screen_physical_width = 0; + device_screen_physical_height = 0; +#elif AGS_PLATFORM_OS_LINUX + device_screen_physical_width = 0; + device_screen_physical_height = 0; + _glxContext = nullptr; + _have_window = false; +#elif AGS_PLATFORM_OS_ANDROID + device_screen_physical_width = android_screen_physical_width; + device_screen_physical_height = android_screen_physical_height; +#elif AGS_PLATFORM_OS_IOS + device_screen_physical_width = ios_screen_physical_width; + device_screen_physical_height = ios_screen_physical_height; +#endif + + _firstTimeInit = false; + _backbuffer = 0; + _fbo = 0; + _legacyPixelShader = false; + _can_render_to_texture = false; + _do_render_to_texture = false; + _super_sampling = 1; + SetupDefaultVertices(); + + // Shifts comply to GL_RGBA + _vmem_r_shift_32 = 0; + _vmem_g_shift_32 = 8; + _vmem_b_shift_32 = 16; + _vmem_a_shift_32 = 24; +} + + +void OGLGraphicsDriver::SetupDefaultVertices() +{ + std::fill(_backbuffer_vertices, _backbuffer_vertices + sizeof(_backbuffer_vertices) / sizeof(GLfloat), 0.0f); + std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); + + defaultVertices[0].position.x = 0.0f; + defaultVertices[0].position.y = 0.0f; + defaultVertices[0].tu=0.0; + defaultVertices[0].tv=0.0; + + defaultVertices[1].position.x = 1.0f; + defaultVertices[1].position.y = 0.0f; + defaultVertices[1].tu=1.0; + defaultVertices[1].tv=0.0; + + defaultVertices[2].position.x = 0.0f; + defaultVertices[2].position.y = -1.0f; + defaultVertices[2].tu=0.0; + defaultVertices[2].tv=1.0; + + defaultVertices[3].position.x = 1.0f; + defaultVertices[3].position.y = -1.0f; + defaultVertices[3].tu=1.0; + defaultVertices[3].tv=1.0; +} + +#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX + +void OGLGraphicsDriver::CreateDesktopScreen(int width, int height, int depth) +{ + device_screen_physical_width = width; + device_screen_physical_height = height; +} + +#elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS + +void OGLGraphicsDriver::UpdateDeviceScreen() +{ +#if AGS_PLATFORM_OS_ANDROID + device_screen_physical_width = android_screen_physical_width; + device_screen_physical_height = android_screen_physical_height; +#elif AGS_PLATFORM_OS_IOS + device_screen_physical_width = ios_screen_physical_width; + device_screen_physical_height = ios_screen_physical_height; +#endif + + Debug::Printf("OGL: notified of device screen updated to %d x %d, resizing viewport", device_screen_physical_width, device_screen_physical_height); + _mode.Width = device_screen_physical_width; + _mode.Height = device_screen_physical_height; + InitGlParams(_mode); + if (_initSurfaceUpdateCallback) + _initSurfaceUpdateCallback(); +} + +#endif + +void OGLGraphicsDriver::Vsync() +{ + // do nothing on OpenGL +} + +void OGLGraphicsDriver::RenderSpritesAtScreenResolution(bool enabled, int supersampling) +{ + if (_can_render_to_texture) + { + _do_render_to_texture = !enabled; + _super_sampling = supersampling; + TestSupersampling(); + } + + if (_do_render_to_texture) + glDisable(GL_SCISSOR_TEST); +} + +bool OGLGraphicsDriver::IsModeSupported(const DisplayMode &mode) +{ + if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) + { + set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); + return false; + } + return true; +} + +bool OGLGraphicsDriver::SupportsGammaControl() +{ + return false; +} + +void OGLGraphicsDriver::SetGamma(int newGamma) +{ +} + +void OGLGraphicsDriver::SetGraphicsFilter(POGLFilter filter) +{ + _filter = filter; + OnSetFilter(); +} + +void OGLGraphicsDriver::SetTintMethod(TintMethod method) +{ + _legacyPixelShader = (method == TintReColourise); +} + +void OGLGraphicsDriver::FirstTimeInit() +{ + String ogl_v_str; +#ifdef GLAPI + ogl_v_str.Format("%d.%d", GLVersion.major, GLVersion.minor); +#else + ogl_v_str = (const char*)glGetString(GL_VERSION); +#endif + Debug::Printf(kDbgMsg_Info, "Running OpenGL: %s", ogl_v_str.GetCStr()); + + // Initialize default sprite batch, it will be used when no other batch was activated + OGLGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); + + TestRenderToTexture(); + CreateShaders(); + _firstTimeInit = true; +} + +#if AGS_PLATFORM_OS_LINUX +Atom get_x_atom (const char *atom_name) +{ + Atom atom = XInternAtom(_xwin.display, atom_name, False); + if (atom == None) + { + Debug::Printf(kDbgMsg_Error, "ERROR: X11 atom \"%s\" not found.\n", atom_name); + } + return atom; +} +#endif + +bool OGLGraphicsDriver::InitGlScreen(const DisplayMode &mode) +{ +#if AGS_PLATFORM_OS_ANDROID + android_create_screen(mode.Width, mode.Height, mode.ColorDepth); +#elif AGS_PLATFORM_OS_IOS + ios_create_screen(); + ios_select_buffer(); +#elif AGS_PLATFORM_OS_WINDOWS + if (mode.Windowed) + { + platform->AdjustWindowStyleForWindowed(); + } + else + { + if (platform->EnterFullscreenMode(mode)) + platform->AdjustWindowStyleForFullscreen(); + } + + // NOTE: adjust_window may leave task bar visible, so we do not use it for fullscreen mode + if (mode.Windowed && adjust_window(mode.Width, mode.Height) != 0) + { + set_allegro_error("Window size not supported"); + return false; + } + + _hWnd = win_get_window(); + if (!(_hDC = GetDC(_hWnd))) + return false; + + // First check if we need to recreate GL context, this will only be + // required if different color depth is requested. + if (_hRC) + { + GLuint pixel_fmt = GetPixelFormat(_hDC); + PIXELFORMATDESCRIPTOR pfd; + DescribePixelFormat(_hDC, pixel_fmt, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + if (pfd.cColorBits != mode.ColorDepth) + { + DeleteGlContext(); + } + } + + if (!_hRC) + { + if (!CreateGlContext(mode)) + return false; + } + + if (!gladLoadWGL(_hDC)) { + Debug::Printf(kDbgMsg_Error, "Failed to load WGL."); + return false; + } + + if (!gladLoadGL()) { + Debug::Printf(kDbgMsg_Error, "Failed to load GL."); + return false; + } + + CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); + win_grab_input(); +#elif AGS_PLATFORM_OS_LINUX + if (!_have_window) + { + // Use Allegro to create our window. We don't care what size Allegro uses + // here, we will set that ourselves below by manipulating members of + // Allegro's_xwin structure. We need to use the Allegro routine here (rather + // than create our own X window) to remain compatible with Allegro's mouse & + // keyboard handling. + // + // Note that although _xwin contains a special "fullscreen" Window member + // (_xwin.fs_window), we do not use it for going fullscreen. Instead we ask + // the window manager to take the "managed" Window (_xwin.wm_window) + // fullscreen for us. All drawing goes to the "real" Window (_xwin.window). + if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 0, 0, 0, 0) != 0) + return false; + _have_window = true; + } + + if (!gladLoadGLX(_xwin.display, DefaultScreen(_xwin.display))) { + Debug::Printf(kDbgMsg_Error, "Failed to load GLX."); + return false; + } + + if (!_glxContext && !CreateGlContext(mode)) + return false; + + if(!gladLoadGL()) { + Debug::Printf(kDbgMsg_Error, "Failed to load GL."); + return false; + } + + { + // Set the size of our "managed" window. + XSizeHints *hints = XAllocSizeHints(); + + if (hints) + { + if (mode.Windowed) + { + // Set a fixed-size window. This is copied from Allegro 4's + // _xwin_private_create_screen(). + hints->flags = PMinSize | PMaxSize | PBaseSize; + hints->min_width = hints->max_width = hints->base_width = mode.Width; + hints->min_height = hints->max_height = hints->base_height = mode.Height; + } + else + { + // Clear any previously set demand for a fixed-size window, otherwise + // the window manager will ignore our request to go full-screen. + hints->flags = 0; + } + + XSetWMNormalHints(_xwin.display, _xwin.wm_window, hints); + } + + XFree(hints); + } + + // Set the window we are actually drawing into to the desired size. + XResizeWindow(_xwin.display, _xwin.window, mode.Width, mode.Height); + + // Make Allegro aware of the new window size, otherwise the mouse cursor + // movement may be erratic. + _xwin.window_width = mode.Width; + _xwin.window_height = mode.Height; + + { + // Ask the window manager to add (or remove) the "fullscreen" property on + // our top-level window. + const Atom wm_state = get_x_atom("_NET_WM_STATE"); + const Atom fullscreen = get_x_atom("_NET_WM_STATE_FULLSCREEN"); + const long remove_property = 0; + const long add_property = 1; + + XEvent xev; + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = _xwin.wm_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = mode.Windowed ? remove_property : add_property; + xev.xclient.data.l[1] = fullscreen; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 1; // Message source is a regular application. + Status status = XSendEvent(_xwin.display, DefaultRootWindow(_xwin.display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + if (status == 0) + { + Debug::Printf(kDbgMsg_Error, "ERROR: Failed to encode window state message.\n"); + } + } + + CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); +#endif + + gfx_driver = &gfx_opengl; + return true; +} + +void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) +{ + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glShadeModel(GL_FLAT); + + glEnable(GL_TEXTURE_2D); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, device_screen_physical_width, device_screen_physical_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, device_screen_physical_width, 0, device_screen_physical_height, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + auto interval = mode.Vsync ? 1 : 0; + bool vsyncEnabled = false; + +#if AGS_PLATFORM_OS_WINDOWS + if (GLAD_WGL_EXT_swap_control) { + vsyncEnabled = wglSwapIntervalEXT(interval) != FALSE; + } +#endif + +#if AGS_PLATFORM_OS_LINUX + if (GLAD_GLX_EXT_swap_control) { + glXSwapIntervalEXT(_xwin.display, _xwin.window, interval); + // glx requires hooking into XSetErrorHandler to test for BadWindow or BadValue + vsyncEnabled = true; + } else if (GLAD_GLX_MESA_swap_control) { + vsyncEnabled = glXSwapIntervalMESA(interval) == 0; + } else if (GLAD_GLX_SGI_swap_control) { + vsyncEnabled = glXSwapIntervalSGI(interval) == 0; + } +#endif + + // TODO: find out how to implement SwapInterval on other platforms, and how to check if it's supported + + if (mode.Vsync && !vsyncEnabled) { + Debug::Printf(kDbgMsg_Warn, "WARNING: Vertical sync could not be enabled. Setting will be kept at driver default."); + } + +#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS + // Setup library mouse to have 1:1 coordinate transformation. + // NOTE: cannot move this call to general mouse handling mode. Unfortunately, much of the setup and rendering + // is duplicated in the Android/iOS ports' Allegro library patches, and is run when the Software renderer + // is selected in AGS. This ugly situation causes trouble... + float device_scale = 1.0f; + + #if AGS_PLATFORM_OS_IOS + device_scale = get_device_scale(); + #endif + + device_mouse_setup(0, device_screen_physical_width - 1, 0, device_screen_physical_height - 1, device_scale, device_scale); +#endif +} + +bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) +{ +#if AGS_PLATFORM_OS_WINDOWS + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + (BYTE)mode.ColorDepth, + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 0, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + _oldPixelFormat = GetPixelFormat(_hDC); + DescribePixelFormat(_hDC, _oldPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &_oldPixelFormatDesc); + + GLuint pixel_fmt; + if (!(pixel_fmt = ChoosePixelFormat(_hDC, &pfd))) + return false; + + if (!SetPixelFormat(_hDC, pixel_fmt, &pfd)) + return false; + + if (!(_hRC = wglCreateContext(_hDC))) + return false; + + if(!wglMakeCurrent(_hDC, _hRC)) + return false; +#endif // AGS_PLATFORM_OS_WINDOWS +#if AGS_PLATFORM_OS_LINUX + int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; + XVisualInfo *vi = glXChooseVisual(_xwin.display, DefaultScreen(_xwin.display), attrib); + if (!vi) + { + Debug::Printf(kDbgMsg_Error, "ERROR: glXChooseVisual() failed.\n"); + return false; + } + + if (!(_glxContext = glXCreateContext(_xwin.display, vi, None, True))) + { + Debug::Printf(kDbgMsg_Error, "ERROR: glXCreateContext() failed.\n"); + return false; + } + + if (!glXMakeCurrent(_xwin.display, _xwin.window, _glxContext)) + { + Debug::Printf(kDbgMsg_Error, "ERROR: glXMakeCurrent() failed.\n"); + return false; + } +#endif + return true; +} + +void OGLGraphicsDriver::DeleteGlContext() +{ +#if AGS_PLATFORM_OS_WINDOWS + if (_hRC) + { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(_hRC); + _hRC = NULL; + } + + if (_oldPixelFormat > 0) + SetPixelFormat(_hDC, _oldPixelFormat, &_oldPixelFormatDesc); +#elif AGS_PLATFORM_OS_LINUX + if (_glxContext) + { + glXMakeCurrent(_xwin.display, None, nullptr); + glXDestroyContext(_xwin.display, _glxContext); + _glxContext = nullptr; + } +#endif +} + +inline bool CanDoFrameBuffer() +{ +#ifdef GLAPI + return GLAD_GL_EXT_framebuffer_object != 0; +#else +#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS + const char* fbo_extension_string = "GL_OES_framebuffer_object"; +#else + const char* fbo_extension_string = "GL_EXT_framebuffer_object"; +#endif + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + return extensions && strstr(extensions, fbo_extension_string) != NULL; +#endif +} + +void OGLGraphicsDriver::TestRenderToTexture() +{ + if (CanDoFrameBuffer()) { + _can_render_to_texture = true; + TestSupersampling(); + } else { + _can_render_to_texture = false; + Debug::Printf(kDbgMsg_Warn, "WARNING: OpenGL extension 'GL_EXT_framebuffer_object' not supported, rendering to texture mode will be disabled."); + } + + if (!_can_render_to_texture) + _do_render_to_texture = false; +} + +void OGLGraphicsDriver::TestSupersampling() +{ + if (!_can_render_to_texture) + return; + // Disable super-sampling if it would cause a too large texture size + if (_super_sampling > 1) + { + int max = 1024; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); + if ((max < _srcRect.GetWidth() * _super_sampling) || (max < _srcRect.GetHeight() * _super_sampling)) + _super_sampling = 1; + } +} + +void OGLGraphicsDriver::CreateShaders() +{ + if (!GLAD_GL_VERSION_2_0) { + Debug::Printf(kDbgMsg_Error, "ERROR: Shaders require a minimum of OpenGL 2.0 support."); + return; + } + CreateTintShader(); + CreateLightShader(); +} + +void OGLGraphicsDriver::CreateTintShader() +{ + const char *fragment_shader_src = + // NOTE: this shader emulates "historical" AGS software tinting; it is not + // necessarily "proper" tinting in modern terms. + // The RGB-HSV-RGB conversion found in the Internet (copyright unknown); + // Color processing is replicated from Direct3D shader by Chris Jones + // (Engine/resource/tintshaderLegacy.fx). + // Uniforms: + // textID - texture index (usually 0), + // tintHSV - tint color in HSV, + // tintAmnTrsLum - tint parameters: amount, translucence (alpha), luminance. + "\ + #version 120\n\ + uniform sampler2D textID;\n\ + uniform vec3 tintHSV;\n\ + uniform vec3 tintAmnTrsLum;\n\ + \ + vec3 rgb2hsv(vec3 c)\n\ + {\n\ + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n\ + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n\ + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n\ + \ + float d = q.x - min(q.w, q.y);\n\ + const float e = 1.0e-10;\n\ + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n\ + }\n\ + \ + vec3 hsv2rgb(vec3 c)\n\ + {\n\ + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n\ + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n\ + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n\ + }\n\ + \ + float getValue(vec3 color)\n\ + {\n\ + float colorMax = max (color[0], color[1]);\n\ + colorMax = max (colorMax, color[2]);\n\ + return colorMax;\n\ + }\n\ + \ + void main()\n\ + {\n\ + vec4 src_col = texture2D(textID, gl_TexCoord[0].xy);\n\ + float amount = tintAmnTrsLum[0];\n\ + float lum = getValue(src_col.xyz);\n\ + lum = max(lum - (1.0 - tintAmnTrsLum[2]), 0.0);\n\ + vec3 new_col = (hsv2rgb(vec3(tintHSV[0], tintHSV[1], lum)) * amount + src_col.xyz * (1.0 - amount));\n\ + gl_FragColor = vec4(new_col, src_col.w * tintAmnTrsLum[1]);\n\ + }\n\ + "; + CreateShaderProgram(_tintShader, "Tinting", fragment_shader_src, "textID", "tintHSV", "tintAmnTrsLum"); +} + +void OGLGraphicsDriver::CreateLightShader() +{ + const char *fragment_shader_src = + // NOTE: due to how the lighting works in AGS, this is combined MODULATE / ADD shader. + // if the light is < 0, then MODULATE operation is used, otherwise ADD is used. + // NOTE: it's been said that using branching in shaders produces inefficient code. + // If that will ever become a real problem, we can easily split this shader in two. + // Uniforms: + // textID - texture index (usually 0), + // light - light level, + // alpha - color alpha value. + "\ + #version 120\n\ + uniform sampler2D textID;\n\ + uniform float light;\n\ + uniform float alpha;\n\ + \ + void main()\n\ + {\n\ + vec4 src_col = texture2D(textID, gl_TexCoord[0].xy);\n\ + if (light >= 0.0)\n\ + gl_FragColor = vec4(src_col.xyz + vec3(light, light, light), src_col.w * alpha);\n\ + else\n\ + gl_FragColor = vec4(src_col.xyz * abs(light), src_col.w * alpha);\n\ + }\n\ + "; + CreateShaderProgram(_lightShader, "Lighting", fragment_shader_src, "textID", "light", "alpha"); +} + +void OGLGraphicsDriver::CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, + const char *sampler_var, const char *color_var, const char *aux_var) +{ + GLint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr); + glCompileShader(fragment_shader); + GLint result; + glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) + { + OutputShaderError(fragment_shader, String::FromFormat("%s program's fragment shader", name), true); + glDeleteShader(fragment_shader); + return; + } + + GLuint program = glCreateProgram(); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &result); + if(result == GL_FALSE) + { + OutputShaderError(program, String::FromFormat("%s program", name), false); + glDeleteProgram(program); + glDeleteShader(fragment_shader); + return; + } + glDetachShader(program, fragment_shader); + glDeleteShader(fragment_shader); + + prg.Program = program; + prg.SamplerVar = glGetUniformLocation(program, sampler_var); + prg.ColorVar = glGetUniformLocation(program, color_var); + prg.AuxVar = glGetUniformLocation(program, aux_var); + Debug::Printf("OGL: %s shader program created successfully", name); +} + +void OGLGraphicsDriver::DeleteShaderProgram(ShaderProgram &prg) +{ + if (prg.Program) + glDeleteProgram(prg.Program); + prg.Program = 0; +} + +void OGLGraphicsDriver::OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader) +{ + GLint log_len; + if (is_shader) + glGetShaderiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); + else + glGetProgramiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); + std::vector errorLog(log_len); + if (log_len > 0) + { + if (is_shader) + glGetShaderInfoLog(obj_id, log_len, &log_len, &errorLog[0]); + else + glGetProgramInfoLog(obj_id, log_len, &log_len, &errorLog[0]); + } + + Debug::Printf(kDbgMsg_Error, "ERROR: OpenGL: %s %s:", obj_name.GetCStr(), is_shader ? "failed to compile" : "failed to link"); + if (errorLog.size() > 0) + { + Debug::Printf(kDbgMsg_Error, "----------------------------------------"); + Debug::Printf(kDbgMsg_Error, "%s", &errorLog[0]); + Debug::Printf(kDbgMsg_Error, "----------------------------------------"); + } + else + { + Debug::Printf(kDbgMsg_Error, "Shader info log was empty."); + } +} + +void OGLGraphicsDriver::SetupBackbufferTexture() +{ + // NOTE: ability to render to texture depends on OGL context, which is + // created in SetDisplayMode, therefore creation of textures require + // both native size set and context capabilities test passed. + if (!IsNativeSizeValid() || !_can_render_to_texture) + return; + + DeleteBackbufferTexture(); + + // _backbuffer_texture_coordinates defines translation from wanted texture size to actual supported texture size + _backRenderSize = _srcRect.GetSize() * _super_sampling; + _backTextureSize = _backRenderSize; + AdjustSizeToNearestSupportedByCard(&_backTextureSize.Width, &_backTextureSize.Height); + const float back_ratio_w = (float)_backRenderSize.Width / (float)_backTextureSize.Width; + const float back_ratio_h = (float)_backRenderSize.Height / (float)_backTextureSize.Height; + std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); + _backbuffer_texture_coordinates[2] = _backbuffer_texture_coordinates[6] = back_ratio_w; + _backbuffer_texture_coordinates[5] = _backbuffer_texture_coordinates[7] = back_ratio_h; + + glGenTextures(1, &_backbuffer); + glBindTexture(GL_TEXTURE_2D, _backbuffer); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backTextureSize.Width, _backTextureSize.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glBindTexture(GL_TEXTURE_2D, 0); + + glGenFramebuffersEXT(1, &_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _backbuffer, 0); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + // Assign vertices of the backbuffer texture position in the scene + _backbuffer_vertices[0] = _backbuffer_vertices[4] = 0; + _backbuffer_vertices[2] = _backbuffer_vertices[6] = _srcRect.GetWidth(); + _backbuffer_vertices[5] = _backbuffer_vertices[7] = _srcRect.GetHeight(); + _backbuffer_vertices[1] = _backbuffer_vertices[3] = 0; +} + +void OGLGraphicsDriver::DeleteBackbufferTexture() +{ + if (_backbuffer) + glDeleteTextures(1, &_backbuffer); + if (_fbo) + glDeleteFramebuffersEXT(1, &_fbo); + _backbuffer = 0; + _fbo = 0; +} + +void OGLGraphicsDriver::SetupViewport() +{ + if (!IsModeSet() || !IsRenderFrameValid()) + return; + + // Setup viewport rect and scissor + _viewportRect = ConvertTopDownRect(_dstRect, device_screen_physical_height); + glScissor(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); +} + +Rect OGLGraphicsDriver::ConvertTopDownRect(const Rect &rect, int surface_height) +{ + return RectWH(rect.Left, surface_height - 1 - rect.Bottom, rect.GetWidth(), rect.GetHeight()); +} + +bool OGLGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) +{ + ReleaseDisplayMode(); + + if (mode.ColorDepth < 15) + { + set_allegro_error("OpenGL driver does not support 256-color display mode"); + return false; + } + + try + { + if (!InitGlScreen(mode)) + return false; + if (!_firstTimeInit) + FirstTimeInit(); + InitGlParams(mode); + } + catch (Ali3DException exception) + { + if (exception._message != get_allegro_error()) + set_allegro_error(exception._message); + return false; + } + + OnInit(loopTimer); + + // On certain platforms OpenGL renderer ignores requested screen sizes + // and uses values imposed by the operating system (device). + DisplayMode final_mode = mode; + final_mode.Width = device_screen_physical_width; + final_mode.Height = device_screen_physical_height; + OnModeSet(final_mode); + + // If we already have a native size set, then update virtual screen and setup backbuffer texture immediately + CreateVirtualScreen(); + SetupBackbufferTexture(); + // If we already have a render frame configured, then setup viewport and backbuffer mappings immediately + SetupViewport(); + return true; +} + +void OGLGraphicsDriver::CreateVirtualScreen() +{ + if (!IsModeSet() || !IsNativeSizeValid()) + return; + // create initial stage screen for plugin raw drawing + _stageVirtualScreen = CreateStageScreen(0, _srcRect.GetSize()); + // we must set Allegro's screen pointer to **something** + screen = (BITMAP*)_stageVirtualScreen->GetAllegroBitmap(); +} + +bool OGLGraphicsDriver::SetNativeSize(const Size &src_size) +{ + OnSetNativeSize(src_size); + SetupBackbufferTexture(); + // If we already have a gfx mode set, then update virtual screen immediately + CreateVirtualScreen(); + TestSupersampling(); + return !_srcRect.IsEmpty(); +} + +bool OGLGraphicsDriver::SetRenderFrame(const Rect &dst_rect) +{ + if (!IsNativeSizeValid()) + return false; + OnSetRenderFrame(dst_rect); + // Also make sure viewport and backbuffer mappings are updated using new native & destination rectangles + SetupViewport(); + return !_dstRect.IsEmpty(); +} + +int OGLGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const +{ + // TODO: check for device caps to know which depth is supported? + return 32; +} + +IGfxModeList *OGLGraphicsDriver::GetSupportedModeList(int color_depth) +{ + std::vector modes; + platform->GetSystemDisplayModes(modes); + return new OGLDisplayModeList(modes); +} + +PGfxFilter OGLGraphicsDriver::GetGraphicsFilter() const +{ + return _filter; +} + +void OGLGraphicsDriver::ReleaseDisplayMode() +{ + if (!IsModeSet()) + return; + + OnModeReleased(); + ClearDrawLists(); + ClearDrawBackups(); + DeleteBackbufferTexture(); + DestroyFxPool(); + DestroyAllStageScreens(); + + gfx_driver = nullptr; + + platform->ExitFullscreenMode(); +} + +void OGLGraphicsDriver::UnInit() +{ + OnUnInit(); + ReleaseDisplayMode(); + + DeleteGlContext(); +#if AGS_PLATFORM_OS_WINDOWS + _hWnd = NULL; + _hDC = NULL; +#endif + + DeleteShaderProgram(_tintShader); + DeleteShaderProgram(_lightShader); +} + +OGLGraphicsDriver::~OGLGraphicsDriver() +{ + OGLGraphicsDriver::UnInit(); +} + +void OGLGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) +{ + // NOTE: this function is practically useless at the moment, because OGL redraws whole game frame each time +} + +bool OGLGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) +{ + (void)at_native_res; // TODO: support this at some point + + // TODO: following implementation currently only reads GL pixels in 32-bit RGBA. + // this **should** work regardless of actual display mode because OpenGL is + // responsible to convert and fill pixel buffer correctly. + // If you like to support writing directly into 16-bit bitmap, please take + // care of ammending the pixel reading code below. + const int read_in_colordepth = 32; + Size need_size = _do_render_to_texture ? _backRenderSize : _dstRect.GetSize(); + if (destination->GetColorDepth() != read_in_colordepth || destination->GetSize() != need_size) + { + if (want_fmt) + *want_fmt = GraphicResolution(need_size.Width, need_size.Height, read_in_colordepth); + return false; + } + + Rect retr_rect; + if (_do_render_to_texture) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); + retr_rect = RectWH(0, 0, _backRenderSize.Width, _backRenderSize.Height); + } + else + { +#if AGS_PLATFORM_OS_IOS + ios_select_buffer(); +#elif AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX + glReadBuffer(GL_FRONT); +#endif + retr_rect = _dstRect; + } + + int bpp = read_in_colordepth / 8; + int bufferSize = retr_rect.GetWidth() * retr_rect.GetHeight() * bpp; + + unsigned char* buffer = new unsigned char[bufferSize]; + if (buffer) + { + glReadPixels(retr_rect.Left, retr_rect.Top, retr_rect.GetWidth(), retr_rect.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + unsigned char* sourcePtr = buffer; + for (int y = destination->GetHeight() - 1; y >= 0; y--) + { + unsigned int * destPtr = reinterpret_cast(&destination->GetScanLineForWriting(y)[0]); + for (int dx = 0, sx = 0; dx < destination->GetWidth(); ++dx, sx = dx * bpp) + { + destPtr[dx] = makeacol32(sourcePtr[sx + 0], sourcePtr[sx + 1], sourcePtr[sx + 2], sourcePtr[sx + 3]); + } + sourcePtr += retr_rect.GetWidth() * bpp; + } + + if (_pollingCallback) + _pollingCallback(); + + delete [] buffer; + } + return true; +} + +void OGLGraphicsDriver::RenderToBackBuffer() +{ + throw Ali3DException("OGL driver does not have a back buffer"); +} + +void OGLGraphicsDriver::Render() +{ + Render(0, 0, kFlip_None); +} + +void OGLGraphicsDriver::Render(int /*xoff*/, int /*yoff*/, GlobalFlipType /*flip*/) +{ + _render(true); +} + +void OGLGraphicsDriver::_reDrawLastFrame() +{ + RestoreDrawLists(); +} + +void OGLGraphicsDriver::_renderSprite(const OGLDrawListEntry *drawListEntry, const GLMATRIX &matGlobal) +{ + OGLBitmap *bmpToDraw = drawListEntry->bitmap; + + if (bmpToDraw->_transparency >= 255) + return; + + const bool do_tint = bmpToDraw->_tintSaturation > 0 && _tintShader.Program > 0; + const bool do_light = bmpToDraw->_tintSaturation == 0 && bmpToDraw->_lightLevel > 0 && _lightShader.Program > 0; + if (do_tint) + { + // Use tinting shader + glUseProgram(_tintShader.Program); + float rgb[3]; + float sat_trs_lum[3]; // saturation / transparency / luminance + if (_legacyPixelShader) + { + rgb_to_hsv(bmpToDraw->_red, bmpToDraw->_green, bmpToDraw->_blue, &rgb[0], &rgb[1], &rgb[2]); + rgb[0] /= 360.0; // In HSV, Hue is 0-360 + } + else + { + rgb[0] = (float)bmpToDraw->_red / 255.0; + rgb[1] = (float)bmpToDraw->_green / 255.0; + rgb[2] = (float)bmpToDraw->_blue / 255.0; + } + + sat_trs_lum[0] = (float)bmpToDraw->_tintSaturation / 255.0; + + if (bmpToDraw->_transparency > 0) + sat_trs_lum[1] = (float)bmpToDraw->_transparency / 255.0; + else + sat_trs_lum[1] = 1.0f; + + if (bmpToDraw->_lightLevel > 0) + sat_trs_lum[2] = (float)bmpToDraw->_lightLevel / 255.0; + else + sat_trs_lum[2] = 1.0f; + + glUniform1i(_tintShader.SamplerVar, 0); + glUniform3f(_tintShader.ColorVar, rgb[0], rgb[1], rgb[2]); + glUniform3f(_tintShader.AuxVar, sat_trs_lum[0], sat_trs_lum[1], sat_trs_lum[2]); + } + else if (do_light) + { + // Use light shader + glUseProgram(_lightShader.Program); + float light_lev = 1.0f; + float alpha = 1.0f; + + // Light level parameter in DDB is weird, it is measured in units of + // 1/255 (although effectively 1/250, see draw.cpp), but contains two + // ranges: 1-255 is darker range and 256-511 is brighter range. + // (light level of 0 means "default color") + if ((bmpToDraw->_lightLevel > 0) && (bmpToDraw->_lightLevel < 256)) + { + // darkening the sprite... this stupid calculation is for + // consistency with the allegro software-mode code that does + // a trans blend with a (8,8,8) sprite + light_lev = -((bmpToDraw->_lightLevel * 192) / 256 + 64) / 255.f; // darker, uses MODULATE op + } + else if (bmpToDraw->_lightLevel > 256) + { + light_lev = ((bmpToDraw->_lightLevel - 256) / 2) / 255.f; // brighter, uses ADD op + } + + if (bmpToDraw->_transparency > 0) + alpha = bmpToDraw->_transparency / 255.f; + + glUniform1i(_lightShader.SamplerVar, 0); + glUniform1f(_lightShader.ColorVar, light_lev); + glUniform1f(_lightShader.AuxVar, alpha); + } + else + { + // Use default processing + if (bmpToDraw->_transparency == 0) + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + else + glColor4f(1.0f, 1.0f, 1.0f, bmpToDraw->_transparency / 255.0f); + } + + float width = bmpToDraw->GetWidthToRender(); + float height = bmpToDraw->GetHeightToRender(); + float xProportion = (float)width / (float)bmpToDraw->_width; + float yProportion = (float)height / (float)bmpToDraw->_height; + int drawAtX = drawListEntry->x; + int drawAtY = drawListEntry->y; + + for (int ti = 0; ti < bmpToDraw->_numTiles; ti++) + { + width = bmpToDraw->_tiles[ti].width * xProportion; + height = bmpToDraw->_tiles[ti].height * yProportion; + float xOffs; + float yOffs = bmpToDraw->_tiles[ti].y * yProportion; + if (bmpToDraw->_flipped) + xOffs = (bmpToDraw->_width - (bmpToDraw->_tiles[ti].x + bmpToDraw->_tiles[ti].width)) * xProportion; + else + xOffs = bmpToDraw->_tiles[ti].x * xProportion; + int thisX = drawAtX + xOffs; + int thisY = drawAtY + yOffs; + thisX = (-(_srcRect.GetWidth() / 2)) + thisX; + thisY = (_srcRect.GetHeight() / 2) - thisY; + + //Setup translation and scaling matrices + float widthToScale = (float)width; + float heightToScale = (float)height; + if (bmpToDraw->_flipped) + { + // The usual transform changes 0..1 into 0..width + // So first negate it (which changes 0..w into -w..0) + widthToScale = -widthToScale; + // and now shift it over to make it 0..w again + thisX += width; + } + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // + // IMPORTANT: in OpenGL order of transformation is REVERSE to the order of commands! + // + // Origin is at the middle of the surface + if (_do_render_to_texture) + glTranslatef(_backRenderSize.Width / 2.0f, _backRenderSize.Height / 2.0f, 0.0f); + else + glTranslatef(_srcRect.GetWidth() / 2.0f, _srcRect.GetHeight() / 2.0f, 0.0f); + + // Global batch transform + glMultMatrixf(matGlobal.m); + // Self sprite transform (first scale, then rotate and then translate, reversed) + glTranslatef((float)thisX, (float)thisY, 0.0f); + glRotatef(0.f, 0.f, 0.f, 1.f); + glScalef(widthToScale, heightToScale, 1.0f); + + glBindTexture(GL_TEXTURE_2D, bmpToDraw->_tiles[ti].texture); + + if ((_smoothScaling) && bmpToDraw->_useResampler && (bmpToDraw->_stretchToHeight > 0) && + ((bmpToDraw->_stretchToHeight != bmpToDraw->_height) || + (bmpToDraw->_stretchToWidth != bmpToDraw->_width))) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else if (_do_render_to_texture) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + else + { + _filter->SetFilteringForStandardSprite(); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + if (bmpToDraw->_vertex != nullptr) + { + glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].tu)); + glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].position)); + } + else + { + glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].tu); + glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].position); + } + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + glUseProgram(0); +} + +void OGLGraphicsDriver::_render(bool clearDrawListAfterwards) +{ +#if AGS_PLATFORM_OS_IOS + ios_select_buffer(); +#endif + +#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS + // TODO: + // For some reason, mobile ports initialize actual display size after a short delay. + // This is why we update display mode and related parameters (projection, viewport) + // at the first render pass. + // Ofcourse this is not a good thing, ideally the display size should be made + // known before graphic mode is initialized. This would require analysis and rewrite + // of the platform-specific part of the code (Java app for Android / XCode for iOS). + if (!device_screen_initialized) + { + UpdateDeviceScreen(); + device_screen_initialized = 1; + } +#endif + + if (_do_render_to_texture) + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); + + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, _backRenderSize.Width, _backRenderSize.Height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _backRenderSize.Width, 0, _backRenderSize.Height, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + else + { + glDisable(GL_SCISSOR_TEST); + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_SCISSOR_TEST); + + glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + + RenderSpriteBatches(); + + if (_do_render_to_texture) + { + // Texture is ready, now create rectangle in the world space and draw texture upon it +#if AGS_PLATFORM_OS_IOS + ios_select_buffer(); +#else + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +#endif + + glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisable(GL_BLEND); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + // use correct sampling method when stretching buffer to the final rect + _filter->SetFilteringForStandardSprite(); + + glBindTexture(GL_TEXTURE_2D, _backbuffer); + + glTexCoordPointer(2, GL_FLOAT, 0, _backbuffer_texture_coordinates); + glVertexPointer(2, GL_FLOAT, 0, _backbuffer_vertices); + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glEnable(GL_BLEND); + } + + glFinish(); + +#if AGS_PLATFORM_OS_WINDOWS + SwapBuffers(_hDC); +#elif AGS_PLATFORM_OS_LINUX + glXSwapBuffers(_xwin.display, _xwin.window); +#elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS + device_swap_buffers(); +#endif + + if (clearDrawListAfterwards) + { + BackupDrawLists(); + ClearDrawLists(); + } + ResetFxPool(); +} + +void OGLGraphicsDriver::RenderSpriteBatches() +{ + // Render all the sprite batches with necessary transformations + Rect main_viewport = _do_render_to_texture ? _srcRect : _viewportRect; + int surface_height = _do_render_to_texture ? _srcRect.GetHeight() : device_screen_physical_height; + // TODO: see if it's possible to refactor and not enable/disable scissor test + // TODO: also maybe sync scissor code logic with D3D renderer + if (_do_render_to_texture) + glEnable(GL_SCISSOR_TEST); + + for (size_t i = 0; i <= _actSpriteBatch; ++i) + { + const Rect &viewport = _spriteBatches[i].Viewport; + const OGLSpriteBatch &batch = _spriteBatches[i]; + if (!viewport.IsEmpty()) + { + Rect scissor = _do_render_to_texture ? viewport : _scaling.ScaleRange(viewport); + scissor = ConvertTopDownRect(scissor, surface_height); + glScissor(scissor.Left, scissor.Top, scissor.GetWidth(), scissor.GetHeight()); + } + else + { + glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); + } + _stageVirtualScreen = GetStageScreen(i); + RenderSpriteBatch(batch); + } + + _stageVirtualScreen = GetStageScreen(0); + glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); + if (_do_render_to_texture) + glDisable(GL_SCISSOR_TEST); +} + +void OGLGraphicsDriver::RenderSpriteBatch(const OGLSpriteBatch &batch) +{ + OGLDrawListEntry stageEntry; // raw-draw plugin support + + const std::vector &listToDraw = batch.List; + for (size_t i = 0; i < listToDraw.size(); i++) + { + if (listToDraw[i].skip) + continue; + + const OGLDrawListEntry *sprite = &listToDraw[i]; + if (listToDraw[i].bitmap == nullptr) + { + if (DoNullSpriteCallback(listToDraw[i].x, listToDraw[i].y)) + stageEntry = OGLDrawListEntry((OGLBitmap*)_stageVirtualScreenDDB); + else + continue; + sprite = &stageEntry; + } + + this->_renderSprite(sprite, batch.Matrix); + } +} + +void OGLGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) +{ + if (_spriteBatches.size() <= index) + _spriteBatches.resize(index + 1); + _spriteBatches[index].List.clear(); + + Rect orig_viewport = desc.Viewport; + Rect node_viewport = desc.Viewport; + // Combine both world transform and viewport transform into one matrix for faster perfomance + // NOTE: in OpenGL order of transformation is REVERSE to the order of commands! + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + // Global node transformation (flip and offset) + int node_tx = desc.Offset.X, node_ty = desc.Offset.Y; + float node_sx = 1.f, node_sy = 1.f; + if ((desc.Flip == kFlip_Vertical) || (desc.Flip == kFlip_Both)) + { + int left = _srcRect.GetWidth() - (orig_viewport.Right + 1); + node_viewport.MoveToX(left); + node_sx = -1.f; + } + if ((desc.Flip == kFlip_Horizontal) || (desc.Flip == kFlip_Both)) + { + int top = _srcRect.GetHeight() - (orig_viewport.Bottom + 1); + node_viewport.MoveToY(top); + node_sy = -1.f; + } + _spriteBatches[index].Viewport = Rect::MoveBy(node_viewport, node_tx, node_ty); + glTranslatef(node_tx, -(node_ty), 0.0f); + glScalef(node_sx, node_sy, 1.f); + // NOTE: before node, translate to viewport position; remove this if this + // is changed to a separate operation at some point + // TODO: find out if this is an optimal way to translate scaled room into Top-Left screen coordinates + float scaled_offx = (_srcRect.GetWidth() - desc.Transform.ScaleX * (float)_srcRect.GetWidth()) / 2.f; + float scaled_offy = (_srcRect.GetHeight() - desc.Transform.ScaleY * (float)_srcRect.GetHeight()) / 2.f; + glTranslatef((float)(orig_viewport.Left - scaled_offx), (float)-(orig_viewport.Top - scaled_offy), 0.0f); + // IMPORTANT: while the sprites are usually transformed in the order of Scale-Rotate-Translate, + // the camera's transformation is essentially reverse world transformation. And the operations + // are inverse: Translate-Rotate-Scale (here they are double inverse because OpenGL). + glScalef(desc.Transform.ScaleX, desc.Transform.ScaleY, 1.f); // scale camera + glRotatef(Math::RadiansToDegrees(desc.Transform.Rotate), 0.f, 0.f, 1.f); // rotate camera + glTranslatef((float)desc.Transform.X, (float)-desc.Transform.Y, 0.0f); // translate camera + glGetFloatv(GL_MODELVIEW_MATRIX, _spriteBatches[index].Matrix.m); + glLoadIdentity(); + + // create stage screen for plugin raw drawing + int src_w = orig_viewport.GetWidth() / desc.Transform.ScaleX; + int src_h = orig_viewport.GetHeight() / desc.Transform.ScaleY; + CreateStageScreen(index, Size(src_w, src_h)); +} + +void OGLGraphicsDriver::ResetAllBatches() +{ + for (size_t i = 0; i < _spriteBatches.size(); ++i) + _spriteBatches[i].List.clear(); +} + +void OGLGraphicsDriver::ClearDrawBackups() +{ + _backupBatchDescs.clear(); + _backupBatches.clear(); +} + +void OGLGraphicsDriver::BackupDrawLists() +{ + ClearDrawBackups(); + for (size_t i = 0; i <= _actSpriteBatch; ++i) + { + _backupBatchDescs.push_back(_spriteBatchDesc[i]); + _backupBatches.push_back(_spriteBatches[i]); + } +} + +void OGLGraphicsDriver::RestoreDrawLists() +{ + if (_backupBatchDescs.size() == 0) + { + ClearDrawLists(); + return; + } + _spriteBatchDesc = _backupBatchDescs; + _spriteBatches = _backupBatches; + _actSpriteBatch = _backupBatchDescs.size() - 1; +} + +void OGLGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) +{ + _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry((OGLBitmap*)bitmap, x, y)); +} + +void OGLGraphicsDriver::DestroyDDB(IDriverDependantBitmap* bitmap) +{ + // Remove deleted DDB from backups + for (OGLSpriteBatches::iterator it = _backupBatches.begin(); it != _backupBatches.end(); ++it) + { + std::vector &drawlist = it->List; + for (size_t i = 0; i < drawlist.size(); i++) + { + if (drawlist[i].bitmap == bitmap) + drawlist[i].skip = true; + } + } + delete bitmap; +} + + +void OGLGraphicsDriver::UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha) +{ + int textureHeight = tile->height; + int textureWidth = tile->width; + + // TODO: this seem to be tad overcomplicated, these conversions were made + // when texture is just created. Check later if this operation here may be removed. + AdjustSizeToNearestSupportedByCard(&textureWidth, &textureHeight); + + int tilex = 0, tiley = 0, tileWidth = tile->width, tileHeight = tile->height; + if (textureWidth > tile->width) + { + int texxoff = Math::Min(textureWidth - tile->width - 1, 1); + tilex = texxoff; + tileWidth += 1 + texxoff; + } + if (textureHeight > tile->height) + { + int texyoff = Math::Min(textureHeight - tile->height - 1, 1); + tiley = texyoff; + tileHeight += 1 + texyoff; + } + + const bool usingLinearFiltering = _filter->UseLinearFiltering(); + char *origPtr = (char*)malloc(sizeof(int) * tileWidth * tileHeight); + const int pitch = tileWidth * sizeof(int); + char *memPtr = origPtr + pitch * tiley + tilex * sizeof(int); + + TextureTile fixedTile; + fixedTile.x = tile->x; + fixedTile.y = tile->y; + fixedTile.width = Math::Min(tile->width, tileWidth); + fixedTile.height = Math::Min(tile->height, tileHeight); + if (target->_opaque) + BitmapToVideoMemOpaque(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch); + else + BitmapToVideoMem(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch, usingLinearFiltering); + + // Mimic the behaviour of GL_CLAMP_EDGE for the tile edges + // NOTE: on some platforms GL_CLAMP_EDGE does not work with the version of OpenGL we're using. + if (tile->width < tileWidth) + { + if (tilex > 0) + { + for (int y = 0; y < tileHeight; y++) + { + unsigned int* edge_left_col = (unsigned int*)(origPtr + y * pitch + (tilex - 1) * sizeof(int)); + unsigned int* bm_left_col = (unsigned int*)(origPtr + y * pitch + (tilex) * sizeof(int)); + *edge_left_col = *bm_left_col & 0x00FFFFFF; + } + } + for (int y = 0; y < tileHeight; y++) + { + unsigned int* edge_right_col = (unsigned int*)(origPtr + y * pitch + (tilex + tile->width) * sizeof(int)); + unsigned int* bm_right_col = edge_right_col - 1; + *edge_right_col = *bm_right_col & 0x00FFFFFF; + } + } + if (tile->height < tileHeight) + { + if (tiley > 0) + { + unsigned int* edge_top_row = (unsigned int*)(origPtr + pitch * (tiley - 1)); + unsigned int* bm_top_row = (unsigned int*)(origPtr + pitch * (tiley)); + for (int x = 0; x < tileWidth; x++) + { + edge_top_row[x] = bm_top_row[x] & 0x00FFFFFF; + } + } + unsigned int* edge_bottom_row = (unsigned int*)(origPtr + pitch * (tiley + tile->height)); + unsigned int* bm_bottom_row = (unsigned int*)(origPtr + pitch * (tiley + tile->height - 1)); + for (int x = 0; x < tileWidth; x++) + { + edge_bottom_row[x] = bm_bottom_row[x] & 0x00FFFFFF; + } + } + + glBindTexture(GL_TEXTURE_2D, tile->texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tileWidth, tileHeight, GL_RGBA, GL_UNSIGNED_BYTE, origPtr); + + free(origPtr); +} + +void OGLGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) +{ + OGLBitmap *target = (OGLBitmap*)bitmapToUpdate; + if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) + throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); + const int color_depth = bitmap->GetColorDepth(); + if (color_depth != target->_colDepth) + throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); + + target->_hasAlpha = hasAlpha; + if (color_depth == 8) + select_palette(palette); + + for (int i = 0; i < target->_numTiles; i++) + { + UpdateTextureRegion(&target->_tiles[i], bitmap, target, hasAlpha); + } + + if (color_depth == 8) + unselect_palette(); +} + +int OGLGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) +{ + if (color_depth == 8) + return 8; + if (color_depth > 8 && color_depth <= 16) + return 16; + return 32; +} + +void OGLGraphicsDriver::AdjustSizeToNearestSupportedByCard(int *width, int *height) +{ + int allocatedWidth = *width, allocatedHeight = *height; + + bool foundWidth = false, foundHeight = false; + int tryThis = 2; + while ((!foundWidth) || (!foundHeight)) + { + if ((tryThis >= allocatedWidth) && (!foundWidth)) + { + allocatedWidth = tryThis; + foundWidth = true; + } + + if ((tryThis >= allocatedHeight) && (!foundHeight)) + { + allocatedHeight = tryThis; + foundHeight = true; + } + + tryThis = tryThis << 1; + } + + *width = allocatedWidth; + *height = allocatedHeight; +} + + + +IDriverDependantBitmap* OGLGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) +{ + int allocatedWidth = bitmap->GetWidth(); + int allocatedHeight = bitmap->GetHeight(); + // NOTE: original bitmap object is not modified in this function + if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) + throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); + int colourDepth = bitmap->GetColorDepth(); + + OGLBitmap *ddb = new OGLBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); + + AdjustSizeToNearestSupportedByCard(&allocatedWidth, &allocatedHeight); + int tilesAcross = 1, tilesDown = 1; + + // Calculate how many textures will be necessary to + // store this image + + int MaxTextureWidth = 512; + int MaxTextureHeight = 512; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTextureWidth); + MaxTextureHeight = MaxTextureWidth; + + tilesAcross = (allocatedWidth + MaxTextureWidth - 1) / MaxTextureWidth; + tilesDown = (allocatedHeight + MaxTextureHeight - 1) / MaxTextureHeight; + int tileWidth = bitmap->GetWidth() / tilesAcross; + int lastTileExtraWidth = bitmap->GetWidth() % tilesAcross; + int tileHeight = bitmap->GetHeight() / tilesDown; + int lastTileExtraHeight = bitmap->GetHeight() % tilesDown; + int tileAllocatedWidth = tileWidth; + int tileAllocatedHeight = tileHeight; + + AdjustSizeToNearestSupportedByCard(&tileAllocatedWidth, &tileAllocatedHeight); + + int numTiles = tilesAcross * tilesDown; + OGLTextureTile *tiles = (OGLTextureTile*)malloc(sizeof(OGLTextureTile) * numTiles); + memset(tiles, 0, sizeof(OGLTextureTile) * numTiles); + + OGLCUSTOMVERTEX *vertices = nullptr; + + if ((numTiles == 1) && + (allocatedWidth == bitmap->GetWidth()) && + (allocatedHeight == bitmap->GetHeight())) + { + // use default whole-image vertices + } + else + { + // The texture is not the same as the bitmap, so create some custom vertices + // so that only the relevant portion of the texture is rendered + int vertexBufferSize = numTiles * 4 * sizeof(OGLCUSTOMVERTEX); + + ddb->_vertex = vertices = (OGLCUSTOMVERTEX*)malloc(vertexBufferSize); + } + + for (int x = 0; x < tilesAcross; x++) + { + for (int y = 0; y < tilesDown; y++) + { + OGLTextureTile *thisTile = &tiles[y * tilesAcross + x]; + int thisAllocatedWidth = tileAllocatedWidth; + int thisAllocatedHeight = tileAllocatedHeight; + thisTile->x = x * tileWidth; + thisTile->y = y * tileHeight; + thisTile->width = tileWidth; + thisTile->height = tileHeight; + if (x == tilesAcross - 1) + { + thisTile->width += lastTileExtraWidth; + thisAllocatedWidth = thisTile->width; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + if (y == tilesDown - 1) + { + thisTile->height += lastTileExtraHeight; + thisAllocatedHeight = thisTile->height; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + + if (vertices != nullptr) + { + const int texxoff = (thisAllocatedWidth - thisTile->width) > 1 ? 1 : 0; + const int texyoff = (thisAllocatedHeight - thisTile->height) > 1 ? 1 : 0; + for (int vidx = 0; vidx < 4; vidx++) + { + int i = (y * tilesAcross + x) * 4 + vidx; + vertices[i] = defaultVertices[vidx]; + if (vertices[i].tu > 0.0) + { + vertices[i].tu = (float)(texxoff + thisTile->width) / (float)thisAllocatedWidth; + } + else + { + vertices[i].tu = (float)(texxoff) / (float)thisAllocatedWidth; + } + if (vertices[i].tv > 0.0) + { + vertices[i].tv = (float)(texyoff + thisTile->height) / (float)thisAllocatedHeight; + } + else + { + vertices[i].tv = (float)(texyoff) / (float)thisAllocatedHeight; + } + } + } + + glGenTextures(1, &thisTile->texture); + glBindTexture(GL_TEXTURE_2D, thisTile->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + // NOTE: pay attention that the texture format depends on the **display mode**'s format, + // rather than source bitmap's color depth! + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, thisAllocatedWidth, thisAllocatedHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + } + } + + ddb->_numTiles = numTiles; + ddb->_tiles = tiles; + + UpdateDDBFromBitmap(ddb, bitmap, hasAlpha); + + return ddb; +} + +void OGLGraphicsDriver::do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + // Construct scene in order: game screen, fade fx, post game overlay + // NOTE: please keep in mind: redrawing last saved frame here instead of constructing new one + // is done because of backwards-compatibility issue: originally AGS faded out using frame + // drawn before the script that triggers blocking fade (e.g. instigated by ChangeRoom). + // Unfortunately some existing games were changing looks of the screen during same function, + // but these were not supposed to get on screen until before fade-in. + if (fadingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != nullptr) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(makecol32(targetColourRed, targetColourGreen, targetColourBlue)); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + if (speed <= 0) speed = 16; + speed *= 2; // harmonise speeds with software driver which is faster + for (int a = 1; a < 255; a += speed) + { + d3db->SetTransparency(fadingOut ? a : (255 - a)); + this->_render(false); + + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + + if (fadingOut) + { + d3db->SetTransparency(0); + this->_render(false); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); +} + +void OGLGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + do_fade(true, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void OGLGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + do_fade(false, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void OGLGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) +{ + // Construct scene in order: game screen, fade fx, post game overlay + if (blackingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != nullptr) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + size_t fx_batch = _actSpriteBatch; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (!blackingOut) + { + // when fading in, draw four black boxes, one + // across each side of the screen + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + } + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); + int boxWidth = speed; + int boxHeight = yspeed; + + while (boxWidth < _srcRect.GetWidth()) + { + boxWidth += speed; + boxHeight += yspeed; + OGLSpriteBatch &batch = _spriteBatches[fx_batch]; + std::vector &drawList = batch.List; + size_t last = drawList.size() - 1; + if (blackingOut) + { + drawList[last].x = _srcRect.GetWidth() / 2- boxWidth / 2; + drawList[last].y = _srcRect.GetHeight() / 2 - boxHeight / 2; + d3db->SetStretch(boxWidth, boxHeight, false); + } + else + { + drawList[last - 3].x = _srcRect.GetWidth() / 2 - boxWidth / 2 - _srcRect.GetWidth(); + drawList[last - 2].y = _srcRect.GetHeight() / 2 - boxHeight / 2 - _srcRect.GetHeight(); + drawList[last - 1].x = _srcRect.GetWidth() / 2 + boxWidth / 2; + drawList[last ].y = _srcRect.GetHeight() / 2 + boxHeight / 2; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + } + + this->_render(false); + + if (_pollingCallback) + _pollingCallback(); + platform->Delay(delay); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); +} + +void OGLGraphicsDriver::SetScreenFade(int red, int green, int blue) +{ + OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(0); + _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); +} + +void OGLGraphicsDriver::SetScreenTint(int red, int green, int blue) +{ + if (red == 0 && green == 0 && blue == 0) return; + OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(128); + _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); +} + + +OGLGraphicsFactory *OGLGraphicsFactory::_factory = nullptr; + +OGLGraphicsFactory::~OGLGraphicsFactory() +{ + _factory = nullptr; +} + +size_t OGLGraphicsFactory::GetFilterCount() const +{ + return 2; +} + +const GfxFilterInfo *OGLGraphicsFactory::GetFilterInfo(size_t index) const +{ + switch (index) + { + case 0: + return &OGLGfxFilter::FilterInfo; + case 1: + return &AAOGLGfxFilter::FilterInfo; + default: + return nullptr; + } +} + +String OGLGraphicsFactory::GetDefaultFilterID() const +{ + return OGLGfxFilter::FilterInfo.Id; +} + +/* static */ OGLGraphicsFactory *OGLGraphicsFactory::GetFactory() +{ + if (!_factory) + _factory = new OGLGraphicsFactory(); + return _factory; +} + +OGLGraphicsDriver *OGLGraphicsFactory::EnsureDriverCreated() +{ + if (!_driver) + _driver = new OGLGraphicsDriver(); + return _driver; +} + +OGLGfxFilter *OGLGraphicsFactory::CreateFilter(const String &id) +{ + if (OGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new OGLGfxFilter(); + else if (AAOGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new AAOGLGfxFilter(); + return nullptr; +} + +} // namespace OGL +} // namespace Engine +} // namespace AGS + +#endif // only on Windows, Android and iOS diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h new file mode 100644 index 000000000000..019073df14c5 --- /dev/null +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -0,0 +1,362 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// OpenGL graphics factory +// +//============================================================================= + +#ifndef __AGS_EE_GFX__ALI3DOGL_H +#define __AGS_EE_GFX__ALI3DOGL_H + +#include +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "gfx/gfxdriverfactorybase.h" +#include "gfx/gfxdriverbase.h" +#include "util/string.h" +#include "util/version.h" + +#include "ogl_headers.h" + +namespace AGS +{ +namespace Engine +{ + +namespace OGL +{ + +using Common::Bitmap; +using Common::String; +using Common::Version; + +typedef struct _OGLVECTOR { + float x; + float y; +} OGLVECTOR2D; + + +struct OGLCUSTOMVERTEX +{ + OGLVECTOR2D position; + float tu; + float tv; +}; + +struct OGLTextureTile : public TextureTile +{ + unsigned int texture; +}; + +class OGLBitmap : public VideoMemDDB +{ +public: + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + void SetTransparency(int transparency) override { _transparency = transparency; } + void SetFlippedLeftRight(bool isFlipped) override { _flipped = isFlipped; } + void SetStretch(int width, int height, bool useResampler = true) override + { + _stretchToWidth = width; + _stretchToHeight = height; + _useResampler = useResampler; + } + void SetLightLevel(int lightLevel) override { _lightLevel = lightLevel; } + void SetTint(int red, int green, int blue, int tintSaturation) override + { + _red = red; + _green = green; + _blue = blue; + _tintSaturation = tintSaturation; + } + + bool _flipped; + int _stretchToWidth, _stretchToHeight; + bool _useResampler; + int _red, _green, _blue; + int _tintSaturation; + int _lightLevel; + bool _hasAlpha; + int _transparency; + OGLCUSTOMVERTEX* _vertex; + OGLTextureTile *_tiles; + int _numTiles; + + OGLBitmap(int width, int height, int colDepth, bool opaque) + { + _width = width; + _height = height; + _colDepth = colDepth; + _flipped = false; + _hasAlpha = false; + _stretchToWidth = 0; + _stretchToHeight = 0; + _useResampler = false; + _red = _green = _blue = 0; + _tintSaturation = 0; + _lightLevel = 0; + _transparency = 0; + _opaque = opaque; + _vertex = nullptr; + _tiles = nullptr; + _numTiles = 0; + } + + int GetWidthToRender() const { return (_stretchToWidth > 0) ? _stretchToWidth : _width; } + int GetHeightToRender() const { return (_stretchToHeight > 0) ? _stretchToHeight : _height; } + + void Dispose(); + + ~OGLBitmap() override + { + Dispose(); + } +}; + +typedef SpriteDrawListEntry OGLDrawListEntry; +typedef struct GLMATRIX { GLfloat m[16]; } GLMATRIX; +struct OGLSpriteBatch +{ + // List of sprites to render + std::vector List; + // Clipping viewport + Rect Viewport; + // Transformation matrix, built from the batch description + GLMATRIX Matrix; +}; +typedef std::vector OGLSpriteBatches; + + +class OGLDisplayModeList : public IGfxModeList +{ +public: + OGLDisplayModeList(const std::vector &modes) + : _modes(modes) + { + } + + int GetModeCount() const override + { + return _modes.size(); + } + + bool GetMode(int index, DisplayMode &mode) const override + { + if (index >= 0 && (size_t)index < _modes.size()) + { + mode = _modes[index]; + return true; + } + return false; + } + +private: + std::vector _modes; +}; + + +class OGLGfxFilter; + +class OGLGraphicsDriver : public VideoMemoryGraphicsDriver +{ +public: + const char*GetDriverName() override { return "OpenGL"; } + const char*GetDriverID() override { return "OGL"; } + void SetTintMethod(TintMethod method) override; + bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; + bool SetNativeSize(const Size &src_size) override; + bool SetRenderFrame(const Rect &dst_rect) override; + int GetDisplayDepthForNativeDepth(int native_color_depth) const override; + IGfxModeList *GetSupportedModeList(int color_depth) override; + bool IsModeSupported(const DisplayMode &mode) override; + PGfxFilter GetGraphicsFilter() const override; + void UnInit(); + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; + int GetCompatibleBitmapFormat(int color_depth) override; + IDriverDependantBitmap* CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; + void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; + void DestroyDDB(IDriverDependantBitmap* bitmap) override; + void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) override; + void RenderToBackBuffer() override; + void Render() override; + void Render(int xoff, int yoff, GlobalFlipType flip) override; + bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; + void EnableVsyncBeforeRender(bool enabled) override { } + void Vsync() override; + void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override; + void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void BoxOutEffect(bool blackingOut, int speed, int delay) override; + bool SupportsGammaControl() override; + void SetGamma(int newGamma) override; + void UseSmoothScaling(bool enabled) override { _smoothScaling = enabled; } + bool RequiresFullRedrawEachFrame() override { return true; } + bool HasAcceleratedTransform() override { return true; } + void SetScreenFade(int red, int green, int blue) override; + void SetScreenTint(int red, int green, int blue) override; + + typedef std::shared_ptr POGLFilter; + + void SetGraphicsFilter(POGLFilter filter); + + OGLGraphicsDriver(); + ~OGLGraphicsDriver() override; + +private: + POGLFilter _filter; + +#if AGS_PLATFORM_OS_WINDOWS + HDC _hDC; + HGLRC _hRC; + HWND _hWnd; + HINSTANCE _hInstance; + GLuint _oldPixelFormat; + PIXELFORMATDESCRIPTOR _oldPixelFormatDesc; +#endif +#if AGS_PLATFORM_OS_LINUX + bool _have_window; + GLXContext _glxContext; +#endif + bool _firstTimeInit; + // Position of backbuffer texture in world space + GLfloat _backbuffer_vertices[8]; + // Relative position of source image on the backbuffer texture, + // in local coordinates + GLfloat _backbuffer_texture_coordinates[8]; + OGLCUSTOMVERTEX defaultVertices[4]; + String previousError; + bool _smoothScaling; + bool _legacyPixelShader; + // Shader program and its variable references; + // the variables are rather specific for AGS use (sprite tinting). + struct ShaderProgram + { + GLuint Program; + GLuint SamplerVar; // texture ID + GLuint ColorVar; // primary operation variable + GLuint AuxVar; // auxiliary variable + + ShaderProgram(); + }; + ShaderProgram _tintShader; + ShaderProgram _lightShader; + + int device_screen_physical_width; + int device_screen_physical_height; + + // Viewport and scissor rect, in OpenGL screen coordinates (0,0 is at left-bottom) + Rect _viewportRect; + + // These two flags define whether driver can, and should (respectively) + // render sprites to texture, and then texture to screen, as opposed to + // rendering to screen directly. This is known as supersampling mode + bool _can_render_to_texture; + bool _do_render_to_texture; + // Backbuffer texture multiplier, used to determine a size of texture + // relative to the native game size. + int _super_sampling; + unsigned int _backbuffer; + unsigned int _fbo; + // Size of the backbuffer drawing area, equals to native size + // multiplied by _super_sampling + Size _backRenderSize; + // Actual size of the backbuffer texture, created by OpenGL + Size _backTextureSize; + + OGLSpriteBatches _spriteBatches; + // TODO: these draw list backups are needed only for the fade-in/out effects + // find out if it's possible to reimplement these effects in main drawing routine. + SpriteBatchDescs _backupBatchDescs; + OGLSpriteBatches _backupBatches; + + void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; + void ResetAllBatches() override; + + // Sets up GL objects not related to particular display mode + void FirstTimeInit(); + // Initializes Gl rendering context + bool InitGlScreen(const DisplayMode &mode); + bool CreateGlContext(const DisplayMode &mode); + void DeleteGlContext(); + // Sets up general rendering parameters + void InitGlParams(const DisplayMode &mode); + void SetupDefaultVertices(); + // Test if rendering to texture is supported + void TestRenderToTexture(); + // Test if supersampling should be allowed with the current setup + void TestSupersampling(); + // Create shader programs for sprite tinting and changing light level + void CreateShaders(); + void CreateTintShader(); + void CreateLightShader(); + void CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, + const char *sampler_var, const char *color_var, const char *aux_var); + void DeleteShaderProgram(ShaderProgram &prg); + void OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader); + // Configure backbuffer texture, that is used in render-to-texture mode + void SetupBackbufferTexture(); + void DeleteBackbufferTexture(); +#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX + void CreateDesktopScreen(int width, int height, int depth); +#elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS + void UpdateDeviceScreen(); +#endif + // Unset parameters and release resources related to the display mode + void ReleaseDisplayMode(); + void AdjustSizeToNearestSupportedByCard(int *width, int *height); + void UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha); + void CreateVirtualScreen(); + void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + void _renderSprite(const OGLDrawListEntry *entry, const GLMATRIX &matGlobal); + void SetupViewport(); + // Converts rectangle in top->down coordinates into OpenGL's native bottom->up coordinates + Rect ConvertTopDownRect(const Rect &top_down_rect, int surface_height); + + // Backup all draw lists in the temp storage + void BackupDrawLists(); + // Restore draw lists from the temp storage + void RestoreDrawLists(); + // Deletes draw list backups + void ClearDrawBackups(); + void _render(bool clearDrawListAfterwards); + void RenderSpriteBatches(); + void RenderSpriteBatch(const OGLSpriteBatch &batch); + void _reDrawLastFrame(); +}; + + +class OGLGraphicsFactory : public GfxDriverFactoryBase +{ +public: + ~OGLGraphicsFactory() override; + + size_t GetFilterCount() const override; + const GfxFilterInfo *GetFilterInfo(size_t index) const override; + String GetDefaultFilterID() const override; + + static OGLGraphicsFactory *GetFactory(); + +private: + OGLGraphicsDriver *EnsureDriverCreated() override; + OGLGfxFilter *CreateFilter(const String &id) override; + + static OGLGraphicsFactory *_factory; +}; + +} // namespace OGL +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__ALI3DOGL_H diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp new file mode 100644 index 000000000000..ddc09b3342ba --- /dev/null +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -0,0 +1,911 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Allegro Interface for 3D; Software mode Allegro driver +// +//============================================================================= + +#include "gfx/ali3dsw.h" + +#include "core/platform.h" +#include "gfx/ali3dexception.h" +#include "gfx/gfxfilter_allegro.h" +#include "gfx/gfxfilter_hqx.h" +#include "gfx/gfx_util.h" +#include "main/main_allegro.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/timer.h" + +#if AGS_DDRAW_GAMMA_CONTROL +// NOTE: this struct and variables are defined internally in Allegro +typedef struct DDRAW_SURFACE { + LPDIRECTDRAWSURFACE2 id; + int flags; + int lock_nesting; + BITMAP *parent_bmp; + struct DDRAW_SURFACE *next; + struct DDRAW_SURFACE *prev; +} DDRAW_SURFACE; + +extern "C" extern LPDIRECTDRAW2 directdraw; +extern "C" DDRAW_SURFACE *gfx_directx_primary_surface; +#endif // AGS_DDRAW_GAMMA_CONTROL + +#ifndef AGS_NO_VIDEO_PLAYER +extern int dxmedia_play_video (const char*, bool, int, int); +#endif + +namespace AGS +{ +namespace Engine +{ +namespace ALSW +{ + +using namespace Common; + +bool ALSoftwareGfxModeList::GetMode(int index, DisplayMode &mode) const +{ + if (_gfxModeList && index >= 0 && index < _gfxModeList->num_modes) + { + mode.Width = _gfxModeList->mode[index].width; + mode.Height = _gfxModeList->mode[index].height; + mode.ColorDepth = _gfxModeList->mode[index].bpp; + return true; + } + return false; +} + +unsigned long _trans_alpha_blender32(unsigned long x, unsigned long y, unsigned long n); +RGB faded_out_palette[256]; + + +ALSoftwareGraphicsDriver::ALSoftwareGraphicsDriver() +{ + _tint_red = 0; + _tint_green = 0; + _tint_blue = 0; + _autoVsync = false; + //_spareTintingScreen = nullptr; + _gfxModeList = nullptr; +#if AGS_DDRAW_GAMMA_CONTROL + dxGammaControl = nullptr; +#endif + _allegroScreenWrapper = nullptr; + _origVirtualScreen = nullptr; + virtualScreen = nullptr; + _stageVirtualScreen = nullptr; + + // Initialize default sprite batch, it will be used when no other batch was activated + ALSoftwareGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); +} + +bool ALSoftwareGraphicsDriver::IsModeSupported(const DisplayMode &mode) +{ + if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) + { + set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); + return false; + } +#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_MACOS + // Everything is drawn to a virtual screen, so all resolutions are supported. + return true; +#endif + + if (mode.Windowed) + { + return true; + } + if (_gfxModeList == nullptr) + { + _gfxModeList = get_gfx_mode_list(GetAllegroGfxDriverID(mode.Windowed)); + } + if (_gfxModeList != nullptr) + { + // if a list is available, check if the mode exists. This prevents the screen flicking + // between loads of unsupported resolutions + for (int i = 0; i < _gfxModeList->num_modes; i++) + { + if ((_gfxModeList->mode[i].width == mode.Width) && + (_gfxModeList->mode[i].height == mode.Height) && + (_gfxModeList->mode[i].bpp == mode.ColorDepth)) + { + return true; + } + } + set_allegro_error("This graphics mode is not supported"); + return false; + } + return true; +} + +int ALSoftwareGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const +{ + // TODO: check for device caps to know which depth is supported? + if (native_color_depth > 8) + return 32; + return native_color_depth; +} + +IGfxModeList *ALSoftwareGraphicsDriver::GetSupportedModeList(int color_depth) +{ + if (_gfxModeList == nullptr) + { + _gfxModeList = get_gfx_mode_list(GetAllegroGfxDriverID(false)); + } + if (_gfxModeList == nullptr) + { + return nullptr; + } + return new ALSoftwareGfxModeList(_gfxModeList); +} + +PGfxFilter ALSoftwareGraphicsDriver::GetGraphicsFilter() const +{ + return _filter; +} + +int ALSoftwareGraphicsDriver::GetAllegroGfxDriverID(bool windowed) +{ +#if AGS_PLATFORM_OS_WINDOWS + if (windowed) + return GFX_DIRECTX_WIN; + return GFX_DIRECTX; +#elif AGS_PLATFORM_OS_LINUX && (!defined (ALLEGRO_MAGIC_DRV)) + if (windowed) + return GFX_XWINDOWS; + return GFX_XWINDOWS_FULLSCREEN; +#elif AGS_PLATFORM_OS_MACOS + if (windowed) { + return GFX_COCOAGL_WINDOW; + } + return GFX_COCOAGL_FULLSCREEN; +#else + if (windowed) + return GFX_AUTODETECT_WINDOWED; + return GFX_AUTODETECT_FULLSCREEN; +#endif +} + +void ALSoftwareGraphicsDriver::SetGraphicsFilter(PALSWFilter filter) +{ + _filter = filter; + OnSetFilter(); + + // If we already have a gfx mode set, then use the new filter to update virtual screen immediately + CreateVirtualScreen(); +} + +void ALSoftwareGraphicsDriver::SetTintMethod(TintMethod method) +{ + // TODO: support new D3D-style tint method +} + +bool ALSoftwareGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) +{ + ReleaseDisplayMode(); + + const int driver = GetAllegroGfxDriverID(mode.Windowed); + + set_color_depth(mode.ColorDepth); + + if (_initGfxCallback != nullptr) + _initGfxCallback(nullptr); + + if (!IsModeSupported(mode) || set_gfx_mode(driver, mode.Width, mode.Height, 0, 0) != 0) + return false; + + OnInit(loopTimer); + OnModeSet(mode); + // set_gfx_mode is an allegro function that creates screen bitmap; + // following code assumes the screen is already created, therefore we should + // ensure global bitmap wraps over existing allegro screen bitmap. + _allegroScreenWrapper = BitmapHelper::CreateRawBitmapWrapper(screen); + _allegroScreenWrapper->Clear(); + + // If we already have a gfx filter, then use it to update virtual screen immediately + CreateVirtualScreen(); + +#if AGS_DDRAW_GAMMA_CONTROL + if (!mode.Windowed) + { + memset(&ddrawCaps, 0, sizeof(ddrawCaps)); + ddrawCaps.dwSize = sizeof(ddrawCaps); + IDirectDraw2_GetCaps(directdraw, &ddrawCaps, NULL); + + if ((ddrawCaps.dwCaps2 & DDCAPS2_PRIMARYGAMMA) == 0) { } + else if (IDirectDrawSurface2_QueryInterface(gfx_directx_primary_surface->id, IID_IDirectDrawGammaControl, (void **)&dxGammaControl) == 0) + { + dxGammaControl->GetGammaRamp(0, &defaultGammaRamp); + } + } +#endif + + return true; +} + +void ALSoftwareGraphicsDriver::CreateVirtualScreen() +{ + if (!IsModeSet() || !IsRenderFrameValid() || !IsNativeSizeValid() || !_filter) + return; + DestroyVirtualScreen(); + // Adjust clipping so nothing gets drawn outside the game frame + _allegroScreenWrapper->SetClip(_dstRect); + // Initialize scaling filter and receive virtual screen pointer + // (which may or not be the same as real screen) + _origVirtualScreen = _filter->InitVirtualScreen(_allegroScreenWrapper, _srcRect.GetSize(), _dstRect); + // Apparently we must still create a virtual screen even if its same size and color depth, + // because drawing sprites directly on real screen bitmap causes blinking (unless I missed something here...) + if (_origVirtualScreen == _allegroScreenWrapper) + { + _origVirtualScreen = BitmapHelper::CreateBitmap(_srcRect.GetWidth(), _srcRect.GetHeight(), _mode.ColorDepth); + } + virtualScreen = _origVirtualScreen; + _stageVirtualScreen = virtualScreen; + // Set Allegro's screen pointer to what may be the real or virtual screen + screen = (BITMAP*)_origVirtualScreen->GetAllegroBitmap(); +} + +void ALSoftwareGraphicsDriver::DestroyVirtualScreen() +{ + if (_filter && _origVirtualScreen) + { + screen = (BITMAP*)_filter->ShutdownAndReturnRealScreen()->GetAllegroBitmap(); + } + _origVirtualScreen = nullptr; + virtualScreen = nullptr; + _stageVirtualScreen = nullptr; +} + +void ALSoftwareGraphicsDriver::ReleaseDisplayMode() +{ + OnModeReleased(); + ClearDrawLists(); + +#if AGS_DDRAW_GAMMA_CONTROL + if (dxGammaControl != NULL) + { + dxGammaControl->Release(); + dxGammaControl = NULL; + } +#endif + + DestroyVirtualScreen(); + + // Note this does not destroy the underlying allegro screen bitmap, only wrapper. + delete _allegroScreenWrapper; + _allegroScreenWrapper = nullptr; +} + +bool ALSoftwareGraphicsDriver::SetNativeSize(const Size &src_size) +{ + OnSetNativeSize(src_size); + // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately + CreateVirtualScreen(); + return !_srcRect.IsEmpty(); +} + +bool ALSoftwareGraphicsDriver::SetRenderFrame(const Rect &dst_rect) +{ + OnSetRenderFrame(dst_rect); + // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately + CreateVirtualScreen(); + return !_dstRect.IsEmpty(); +} + +void ALSoftwareGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) +{ + if (!_filter) return; + int color = 0; + if (colorToUse != nullptr) + color = makecol_depth(_mode.ColorDepth, colorToUse->r, colorToUse->g, colorToUse->b); + // NOTE: filter will do coordinate scaling for us + _filter->ClearRect(x1, y1, x2, y2, color); +} + +ALSoftwareGraphicsDriver::~ALSoftwareGraphicsDriver() +{ + ALSoftwareGraphicsDriver::UnInit(); +} + +void ALSoftwareGraphicsDriver::UnInit() +{ + OnUnInit(); + ReleaseDisplayMode(); + + if (_gfxModeList != nullptr) + { + destroy_gfx_mode_list(_gfxModeList); + _gfxModeList = nullptr; + } +} + +bool ALSoftwareGraphicsDriver::SupportsGammaControl() +{ +#if AGS_DDRAW_GAMMA_CONTROL + + if (dxGammaControl != NULL) + { + return 1; + } + +#endif + + return 0; +} + +void ALSoftwareGraphicsDriver::SetGamma(int newGamma) +{ +#if AGS_DDRAW_GAMMA_CONTROL + for (int i = 0; i < 256; i++) { + int newValue = ((int)defaultGammaRamp.red[i] * newGamma) / 100; + if (newValue >= 65535) + newValue = 65535; + gammaRamp.red[i] = newValue; + gammaRamp.green[i] = newValue; + gammaRamp.blue[i] = newValue; + } + + dxGammaControl->SetGammaRamp(0, &gammaRamp); +#endif +} + +int ALSoftwareGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) +{ + return color_depth; +} + +IDriverDependantBitmap* ALSoftwareGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) +{ + ALSoftwareBitmap* newBitmap = new ALSoftwareBitmap(bitmap, opaque, hasAlpha); + return newBitmap; +} + +void ALSoftwareGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) +{ + ALSoftwareBitmap* alSwBmp = (ALSoftwareBitmap*)bitmapToUpdate; + alSwBmp->_bmp = bitmap; + alSwBmp->_hasAlpha = hasAlpha; +} + +void ALSoftwareGraphicsDriver::DestroyDDB(IDriverDependantBitmap* bitmap) +{ + delete bitmap; +} + +void ALSoftwareGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) +{ + if (_spriteBatches.size() <= index) + _spriteBatches.resize(index + 1); + ALSpriteBatch &batch = _spriteBatches[index]; + batch.List.clear(); + // TODO: correct offsets to have pre-scale (source) and post-scale (dest) offsets! + const int src_w = desc.Viewport.GetWidth() / desc.Transform.ScaleX; + const int src_h = desc.Viewport.GetHeight() / desc.Transform.ScaleY; + // Surface was prepared externally (common for room cameras) + if (desc.Surface != nullptr) + { + batch.Surface = std::static_pointer_cast(desc.Surface); + batch.Opaque = true; + batch.IsVirtualScreen = false; + } + // In case something was not initialized + else if (desc.Viewport.IsEmpty() || !virtualScreen) + { + batch.Surface.reset(); + batch.Opaque = false; + batch.IsVirtualScreen = false; + } + // Drawing directly on a viewport without transformation (other than offset) + else if (desc.Transform.ScaleX == 1.f && desc.Transform.ScaleY == 1.f) + { + if (!batch.Surface || !batch.IsVirtualScreen || batch.Surface->GetWidth() != src_w || batch.Surface->GetHeight() != src_h) + { + Rect rc = RectWH(desc.Viewport.Left, desc.Viewport.Top, desc.Viewport.GetWidth(), desc.Viewport.GetHeight()); + batch.Surface.reset(BitmapHelper::CreateSubBitmap(virtualScreen, rc)); + } + batch.Opaque = true; + batch.IsVirtualScreen = true; + } + // No surface prepared and has transformation other than offset + else if (!batch.Surface || batch.IsVirtualScreen || batch.Surface->GetWidth() != src_w || batch.Surface->GetHeight() != src_h) + { + batch.Surface.reset(new Bitmap(src_w, src_h)); + batch.Opaque = false; + batch.IsVirtualScreen = false; + } +} + +void ALSoftwareGraphicsDriver::ResetAllBatches() +{ + for (ALSpriteBatches::iterator it = _spriteBatches.begin(); it != _spriteBatches.end(); ++it) + it->List.clear(); +} + +void ALSoftwareGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) +{ + _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap*)bitmap, x, y)); +} + +void ALSoftwareGraphicsDriver::SetScreenFade(int red, int green, int blue) +{ + // TODO: was not necessary atm +} + +void ALSoftwareGraphicsDriver::SetScreenTint(int red, int green, int blue) +{ + _tint_red = red; _tint_green = green; _tint_blue = blue; + if (((_tint_red > 0) || (_tint_green > 0) || (_tint_blue > 0)) && (_mode.ColorDepth > 8)) + { + _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap*)0x1, 0, 0)); + } +} + +void ALSoftwareGraphicsDriver::RenderToBackBuffer() +{ + // Render all the sprite batches with necessary transformations + // + // NOTE: that's not immediately clear whether it would be faster to first draw upon a camera-sized + // surface then stretch final result to the viewport on screen, or stretch-blit each individual + // sprite right onto screen bitmap. We'd need to do proper profiling to know that. + // An important thing is that Allegro does not provide stretching functions for drawing sprites + // with blending and translucency; it seems you'd have to first stretch the original sprite onto a + // temp buffer and then TransBlendBlt / LitBlendBlt it to the final destination. Of course, doing + // that here would slow things down significantly, so if we ever go that way sprite caching will + // be required (similarily to how AGS caches flipped/scaled object sprites now for). + // + for (size_t i = 0; i <= _actSpriteBatch; ++i) + { + const Rect &viewport = _spriteBatchDesc[i].Viewport; + const SpriteTransform &transform = _spriteBatchDesc[i].Transform; + const ALSpriteBatch &batch = _spriteBatches[i]; + + virtualScreen->SetClip(viewport); + Bitmap *surface = batch.Surface.get(); + const int view_offx = viewport.Left; + const int view_offy = viewport.Top; + if (surface) + { + if (!batch.Opaque) + surface->ClearTransparent(); + _stageVirtualScreen = surface; + RenderSpriteBatch(batch, surface, transform.X, transform.Y); + if (!batch.IsVirtualScreen) + virtualScreen->StretchBlt(surface, RectWH(view_offx, view_offy, viewport.GetWidth(), viewport.GetHeight()), + batch.Opaque ? kBitmap_Copy : kBitmap_Transparency); + } + else + { + RenderSpriteBatch(batch, virtualScreen, view_offx + transform.X, view_offy + transform.Y); + } + _stageVirtualScreen = virtualScreen; + } + ClearDrawLists(); +} + +void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy) +{ + const std::vector &drawlist = batch.List; + for (size_t i = 0; i < drawlist.size(); i++) + { + if (drawlist[i].bitmap == nullptr) + { + if (_nullSpriteCallback) + _nullSpriteCallback(drawlist[i].x, drawlist[i].y); + else + throw Ali3DException("Unhandled attempt to draw null sprite"); + + continue; + } + else if (drawlist[i].bitmap == (ALSoftwareBitmap*)0x1) + { + // draw screen tint fx + set_trans_blender(_tint_red, _tint_green, _tint_blue, 0); + surface->LitBlendBlt(surface, 0, 0, 128); + continue; + } + + ALSoftwareBitmap* bitmap = drawlist[i].bitmap; + int drawAtX = drawlist[i].x + surf_offx; + int drawAtY = drawlist[i].y + surf_offy; + + if (bitmap->_transparency >= 255) {} // fully transparent, do nothing + else if ((bitmap->_opaque) && (bitmap->_bmp == surface) && (bitmap->_transparency == 0)) {} + else if (bitmap->_opaque) + { + surface->Blit(bitmap->_bmp, 0, 0, drawAtX, drawAtY, bitmap->_bmp->GetWidth(), bitmap->_bmp->GetHeight()); + // TODO: we need to also support non-masked translucent blend, but... + // Allegro 4 **does not have such function ready** :( (only masked blends, where it skips magenta pixels); + // I am leaving this problem for the future, as coincidentally software mode does not need this atm. + } + else if (bitmap->_hasAlpha) + { + if (bitmap->_transparency == 0) // no global transparency, simple alpha blend + set_alpha_blender(); + else + // here _transparency is used as alpha (between 1 and 254) + set_blender_mode(nullptr, nullptr, _trans_alpha_blender32, 0, 0, 0, bitmap->_transparency); + + surface->TransBlendBlt(bitmap->_bmp, drawAtX, drawAtY); + } + else + { + // here _transparency is used as alpha (between 1 and 254), but 0 means opaque! + GfxUtil::DrawSpriteWithTransparency(surface, bitmap->_bmp, drawAtX, drawAtY, + bitmap->_transparency ? bitmap->_transparency : 255); + } + } + // NOTE: following is experimental tint code (currently unused) +/* This alternate method gives the correct (D3D-style) result, but is just too slow! + if ((_spareTintingScreen != NULL) && + ((_spareTintingScreen->GetWidth() != surface->GetWidth()) || (_spareTintingScreen->GetHeight() != surface->GetHeight()))) + { + destroy_bitmap(_spareTintingScreen); + _spareTintingScreen = NULL; + } + if (_spareTintingScreen == NULL) + { + _spareTintingScreen = BitmapHelper::CreateBitmap_(GetColorDepth(surface), surface->GetWidth(), surface->GetHeight()); + } + tint_image(surface, _spareTintingScreen, _tint_red, _tint_green, _tint_blue, 100, 255); + Blit(_spareTintingScreen, surface, 0, 0, 0, 0, _spareTintingScreen->GetWidth(), _spareTintingScreen->GetHeight());*/ +} + +void ALSoftwareGraphicsDriver::Render(int xoff, int yoff, GlobalFlipType flip) +{ + RenderToBackBuffer(); + + if (_autoVsync) + this->Vsync(); + + if (flip == kFlip_None) + _filter->RenderScreen(virtualScreen, xoff, yoff); + else + _filter->RenderScreenFlipped(virtualScreen, xoff, yoff, flip); +} + +void ALSoftwareGraphicsDriver::Render() +{ + Render(0, 0, kFlip_None); +} + +void ALSoftwareGraphicsDriver::Vsync() +{ + vsync(); +} + +Bitmap *ALSoftwareGraphicsDriver::GetMemoryBackBuffer() +{ + return virtualScreen; +} + +void ALSoftwareGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) +{ + if (backBuffer) + { + virtualScreen = backBuffer; + } + else + { + virtualScreen = _origVirtualScreen; + } + _stageVirtualScreen = virtualScreen; + + // Reset old virtual screen's subbitmaps + for (auto &batch : _spriteBatches) + { + if (batch.IsVirtualScreen) + batch.Surface.reset(); + } +} + +Bitmap *ALSoftwareGraphicsDriver::GetStageBackBuffer() +{ + return _stageVirtualScreen; +} + +bool ALSoftwareGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) +{ + (void)at_native_res; // software driver always renders at native resolution at the moment + // software filter is taught to copy to any size + if (destination->GetColorDepth() != _mode.ColorDepth) + { + if (want_fmt) + *want_fmt = GraphicResolution(destination->GetWidth(), destination->GetHeight(), _mode.ColorDepth); + return false; + } + _filter->GetCopyOfScreenIntoBitmap(destination); + return true; +} + +/** + fade.c - High Color Fading Routines + + Last Revision: 21 June, 2002 + + Author: Matthew Leverton +**/ +void ALSoftwareGraphicsDriver::highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + Bitmap *bmp_orig = vs; + const int col_depth = bmp_orig->GetColorDepth(); + const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); + if (speed <= 0) speed = 16; + + Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), col_depth); + SetMemoryBackBuffer(bmp_buff); + for (int a = 0; a < 256; a+=speed) + { + bmp_buff->Fill(clearColor); + set_trans_blender(0,0,0,a); + bmp_buff->TransBlendBlt(bmp_orig, 0, 0); + if (draw_callback) + { + draw_callback(); + RenderToBackBuffer(); + } + this->Vsync(); + _filter->RenderScreen(bmp_buff, offx, offy); + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + delete bmp_buff; + + SetMemoryBackBuffer(vs); + if (draw_callback) + { + draw_callback(); + RenderToBackBuffer(); + } + _filter->RenderScreen(vs, offx, offy); +} + +void ALSoftwareGraphicsDriver::highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + Bitmap *bmp_orig = vs; + const int col_depth = vs->GetColorDepth(); + const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); + if (speed <= 0) speed = 16; + + Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), col_depth); + SetMemoryBackBuffer(bmp_buff); + for (int a = 255 - speed; a > 0; a -= speed) + { + bmp_buff->Fill(clearColor); + set_trans_blender(0, 0, 0, a); + bmp_buff->TransBlendBlt(bmp_orig, 0, 0); + if (draw_callback) + { + draw_callback(); + RenderToBackBuffer(); + } + this->Vsync(); + _filter->RenderScreen(bmp_buff, offx, offy); + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + delete bmp_buff; + + SetMemoryBackBuffer(vs); + vs->Clear(clearColor); + if (draw_callback) + { + draw_callback(); + RenderToBackBuffer(); + } + _filter->RenderScreen(vs, offx, offy); +} +/** END FADE.C **/ + +// palette fading routiens +// from allegro, modified for mp3 +void initialize_fade_256(int r, int g, int b) { + int a; + for (a = 0; a < 256; a++) { + faded_out_palette[a].r = r / 4; + faded_out_palette[a].g = g / 4; + faded_out_palette[a].b = b / 4; + } +} + +void ALSoftwareGraphicsDriver::__fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) +{ + PALETTE temp; + int c; + + for (c=0; c 8) + { + highcolor_fade_out(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue); + } + else + { + __fade_out_range(speed, 0, 255, targetColourRed, targetColourGreen, targetColourBlue); + } +} + +void ALSoftwareGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) { + if (_drawScreenCallback) + { + _drawScreenCallback(); + RenderToBackBuffer(); + } + if (_mode.ColorDepth > 8) + { + highcolor_fade_in(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue); + } + else + { + initialize_fade_256(targetColourRed, targetColourGreen, targetColourBlue); + __fade_from_range(faded_out_palette, p, speed, 0,255); + } +} + +void ALSoftwareGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) +{ + if (blackingOut) + { + int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); + int boxwid = speed, boxhit = yspeed; + Bitmap *bmp_orig = virtualScreen; + Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), bmp_orig->GetColorDepth()); + SetMemoryBackBuffer(bmp_buff); + + while (boxwid < _srcRect.GetWidth()) { + boxwid += speed; + boxhit += yspeed; + int vcentre = _srcRect.GetHeight() / 2; + bmp_orig->FillRect(Rect(_srcRect.GetWidth() / 2 - boxwid / 2, vcentre - boxhit / 2, + _srcRect.GetWidth() / 2 + boxwid / 2, vcentre + boxhit / 2), 0); + bmp_buff->Fill(0); + bmp_buff->Blit(bmp_orig); + if (_drawPostScreenCallback) + { + _drawPostScreenCallback(); + RenderToBackBuffer(); + } + this->Vsync(); + _filter->RenderScreen(bmp_buff, 0, 0); + + if (_pollingCallback) + _pollingCallback(); + + platform->Delay(delay); + } + delete bmp_buff; + SetMemoryBackBuffer(bmp_orig); + } + else + { + throw Ali3DException("BoxOut fade-in not implemented in sw gfx driver"); + } +} +// end fading routines + +#ifndef AGS_NO_VIDEO_PLAYER + +bool ALSoftwareGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) +{ +#if AGS_PLATFORM_OS_WINDOWS + int result = dxmedia_play_video(filename, useAVISound, skipType, stretchToFullScreen ? 1 : 0); + return (result == 0); +#else + return 0; +#endif +} + +#endif + +// add the alpha values together, used for compositing alpha images +unsigned long _trans_alpha_blender32(unsigned long x, unsigned long y, unsigned long n) +{ + unsigned long res, g; + + n = (n * geta32(x)) / 256; + + if (n) + n++; + + res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y; + y &= 0xFF00; + x &= 0xFF00; + g = (x - y) * n / 256 + y; + + res &= 0xFF00FF; + g &= 0xFF00; + + return res | g; +} + + +ALSWGraphicsFactory *ALSWGraphicsFactory::_factory = nullptr; + +ALSWGraphicsFactory::~ALSWGraphicsFactory() +{ + _factory = nullptr; +} + +size_t ALSWGraphicsFactory::GetFilterCount() const +{ + return 2; +} + +const GfxFilterInfo *ALSWGraphicsFactory::GetFilterInfo(size_t index) const +{ + switch (index) + { + case 0: + return &AllegroGfxFilter::FilterInfo; + case 1: + return &HqxGfxFilter::FilterInfo; + default: + return nullptr; + } +} + +String ALSWGraphicsFactory::GetDefaultFilterID() const +{ + return AllegroGfxFilter::FilterInfo.Id; +} + +/* static */ ALSWGraphicsFactory *ALSWGraphicsFactory::GetFactory() +{ + if (!_factory) + _factory = new ALSWGraphicsFactory(); + return _factory; +} + +ALSoftwareGraphicsDriver *ALSWGraphicsFactory::EnsureDriverCreated() +{ + if (!_driver) + _driver = new ALSoftwareGraphicsDriver(); + return _driver; +} + +AllegroGfxFilter *ALSWGraphicsFactory::CreateFilter(const String &id) +{ + if (AllegroGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new AllegroGfxFilter(); + else if (HqxGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new HqxGfxFilter(); + return nullptr; +} + +} // namespace ALSW +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h new file mode 100644 index 000000000000..8cb4f0fb9e05 --- /dev/null +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -0,0 +1,270 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Software graphics factory, based on Allegro +// +//============================================================================= + +#ifndef __AGS_EE_GFX__ALI3DSW_H +#define __AGS_EE_GFX__ALI3DSW_H + +#include + +#include "core/platform.h" +#define AGS_DDRAW_GAMMA_CONTROL (AGS_PLATFORM_OS_WINDOWS) + +#include + +#if AGS_DDRAW_GAMMA_CONTROL +#include +#include +#endif + +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "gfx/gfxdriverfactorybase.h" +#include "gfx/gfxdriverbase.h" + +namespace AGS +{ +namespace Engine +{ +namespace ALSW +{ + +class AllegroGfxFilter; +using AGS::Common::Bitmap; + +class ALSoftwareBitmap : public IDriverDependantBitmap +{ +public: + // NOTE by CJ: + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + void SetTransparency(int transparency) override { _transparency = transparency; } + void SetFlippedLeftRight(bool isFlipped) override { _flipped = isFlipped; } + void SetStretch(int width, int height, bool useResampler = true) override + { + _stretchToWidth = width; + _stretchToHeight = height; + } + int GetWidth() override { return _width; } + int GetHeight() override { return _height; } + int GetColorDepth() override { return _colDepth; } + void SetLightLevel(int lightLevel) override { } + void SetTint(int red, int green, int blue, int tintSaturation) override { } + + Bitmap *_bmp; + int _width, _height; + int _colDepth; + bool _flipped; + int _stretchToWidth, _stretchToHeight; + bool _opaque; // no mask color + bool _hasAlpha; + int _transparency; + + ALSoftwareBitmap(Bitmap *bmp, bool opaque, bool hasAlpha) + { + _bmp = bmp; + _width = bmp->GetWidth(); + _height = bmp->GetHeight(); + _colDepth = bmp->GetColorDepth(); + _flipped = false; + _stretchToWidth = 0; + _stretchToHeight = 0; + _transparency = 0; + _opaque = opaque; + _hasAlpha = hasAlpha; + } + + int GetWidthToRender() { return (_stretchToWidth > 0) ? _stretchToWidth : _width; } + int GetHeightToRender() { return (_stretchToHeight > 0) ? _stretchToHeight : _height; } + + void Dispose() + { + // do we want to free the bitmap? + } + + ~ALSoftwareBitmap() override + { + Dispose(); + } +}; + + +class ALSoftwareGfxModeList : public IGfxModeList +{ +public: + ALSoftwareGfxModeList(GFX_MODE_LIST *alsw_gfx_mode_list) + : _gfxModeList(alsw_gfx_mode_list) + { + } + + int GetModeCount() const override + { + return _gfxModeList ? _gfxModeList->num_modes : 0; + } + + bool GetMode(int index, DisplayMode &mode) const override; + +private: + GFX_MODE_LIST *_gfxModeList; +}; + + +typedef SpriteDrawListEntry ALDrawListEntry; +// Software renderer's sprite batch +struct ALSpriteBatch +{ + // List of sprites to render + std::vector List; + // Intermediate surface which will be drawn upon and transformed if necessary + std::shared_ptr Surface; + // Whether surface is a virtual screen's region + bool IsVirtualScreen; + // Tells whether the surface is treated as opaque or transparent + bool Opaque; +}; +typedef std::vector ALSpriteBatches; + + +class ALSoftwareGraphicsDriver : public GraphicsDriverBase +{ +public: + ALSoftwareGraphicsDriver(); + + const char*GetDriverName() override { return "Software renderer"; } + const char*GetDriverID() override { return "Software"; } + void SetTintMethod(TintMethod method) override; + bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; + bool SetNativeSize(const Size &src_size) override; + bool SetRenderFrame(const Rect &dst_rect) override; + bool IsModeSupported(const DisplayMode &mode) override; + int GetDisplayDepthForNativeDepth(int native_color_depth) const override; + IGfxModeList *GetSupportedModeList(int color_depth) override; + PGfxFilter GetGraphicsFilter() const override; + void UnInit(); + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; + int GetCompatibleBitmapFormat(int color_depth) override; + IDriverDependantBitmap* CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; + void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; + void DestroyDDB(IDriverDependantBitmap* bitmap) override; + + void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) override; + void SetScreenFade(int red, int green, int blue) override; + void SetScreenTint(int red, int green, int blue) override; + + void RenderToBackBuffer() override; + void Render() override; + void Render(int xoff, int yoff, GlobalFlipType flip) override; + bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; + void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void FadeIn(int speed, PALETTE pal, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void BoxOutEffect(bool blackingOut, int speed, int delay) override; +#ifndef AGS_NO_VIDEO_PLAYER + bool PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) override; +#endif + bool SupportsGammaControl() override ; + void SetGamma(int newGamma) override; + void UseSmoothScaling(bool enabled) override { } + void EnableVsyncBeforeRender(bool enabled) override { _autoVsync = enabled; } + void Vsync() override; + void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override { } + bool RequiresFullRedrawEachFrame() override { return false; } + bool HasAcceleratedTransform() override { return false; } + bool UsesMemoryBackBuffer() override { return true; } + Bitmap *GetMemoryBackBuffer() override; + void SetMemoryBackBuffer(Bitmap *backBuffer) override; + Bitmap *GetStageBackBuffer() override; + ~ALSoftwareGraphicsDriver() override; + + typedef std::shared_ptr PALSWFilter; + + void SetGraphicsFilter(PALSWFilter filter); + +private: + PALSWFilter _filter; + + bool _autoVsync; + Bitmap *_allegroScreenWrapper; + // Virtual screen bitmap is either a wrapper over Allegro's real screen + // bitmap, or bitmap provided by the graphics filter. It should not be + // disposed by the renderer: it is up to filter object to manage it. + Bitmap *_origVirtualScreen; + // Current virtual screen bitmap; may be provided either by graphics + // filter or by external user. It should not be disposed by the renderer. + Bitmap *virtualScreen; + // Stage screen meant for particular rendering stages, may be referencing + // actual virtual screen or separate bitmap of different size that is + // blitted to virtual screen at the stage finalization. + Bitmap *_stageVirtualScreen; + //Bitmap *_spareTintingScreen; + int _tint_red, _tint_green, _tint_blue; + + ALSpriteBatches _spriteBatches; + GFX_MODE_LIST *_gfxModeList; + +#if AGS_DDRAW_GAMMA_CONTROL + IDirectDrawGammaControl* dxGammaControl; + // The gamma ramp is a lookup table for each possible R, G and B value + // in 32-bit colour (from 0-255) it maps them to a brightness value + // from 0-65535. The default gamma ramp just multiplies each value by 256 + DDGAMMARAMP gammaRamp; + DDGAMMARAMP defaultGammaRamp; + DDCAPS ddrawCaps; +#endif + + void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; + void ResetAllBatches() override; + + // Use gfx filter to create a new virtual screen + void CreateVirtualScreen(); + void DestroyVirtualScreen(); + // Unset parameters and release resources related to the display mode + void ReleaseDisplayMode(); + // Renders single sprite batch on the precreated surface + void RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy); + + void highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + void highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + void __fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) ; + void __fade_out_range(int speed, int from, int to, int targetColourRed, int targetColourGreen, int targetColourBlue) ; + int GetAllegroGfxDriverID(bool windowed); +}; + + +class ALSWGraphicsFactory : public GfxDriverFactoryBase +{ +public: + ~ALSWGraphicsFactory() override; + + size_t GetFilterCount() const override; + const GfxFilterInfo *GetFilterInfo(size_t index) const override; + String GetDefaultFilterID() const override; + + static ALSWGraphicsFactory *GetFactory(); + +private: + ALSoftwareGraphicsDriver *EnsureDriverCreated() override; + AllegroGfxFilter *CreateFilter(const String &id) override; + + static ALSWGraphicsFactory *_factory; +}; + +} // namespace ALSW +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__ALI3DSW_H diff --git a/engines/ags/engine/gfx/blender.cpp b/engines/ags/engine/gfx/blender.cpp new file mode 100644 index 000000000000..18a48cf6c10c --- /dev/null +++ b/engines/ags/engine/gfx/blender.cpp @@ -0,0 +1,300 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/types.h" +#include "gfx/blender.h" +#include "util/wgt2allg.h" + +extern "C" { + // Fallback routine for when we don't have anything better to do. + unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n); + // Standard Allegro 4 trans blenders for 16 and 15-bit color modes + unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n); + unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n); + // Standard Allegro 4 alpha blenders for 16 and 15-bit color modes + unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n); + unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n); + unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n); +} + +// the allegro "inline" ones are not actually inline, so #define +// over them to speed it up +#define getr32(xx) ((xx >> _rgb_r_shift_32) & 0xFF) +#define getg32(xx) ((xx >> _rgb_g_shift_32) & 0xFF) +#define getb32(xx) ((xx >> _rgb_b_shift_32) & 0xFF) +#define geta32(xx) ((xx >> _rgb_a_shift_32) & 0xFF) +#define makeacol32(r,g,b,a) ((r << _rgb_r_shift_32) | (g << _rgb_g_shift_32) | (b << _rgb_b_shift_32) | (a << _rgb_a_shift_32)) + +// Take hue and saturation of blend colour, luminance of image +unsigned long _myblender_color15_light(unsigned long x, unsigned long y, unsigned long n) +{ + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; + + rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv); + rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv); + + // adjust luminance + yv -= (1.0 - ((float)n / 250.0)); + if (yv < 0.0) yv = 0.0; + + hsv_to_rgb(xh, xs, yv, &r, &g, &b); + + return makecol15(r, g, b); +} + +// Take hue and saturation of blend colour, luminance of image +// n is the last parameter passed to draw_lit_sprite +unsigned long _myblender_color16_light(unsigned long x, unsigned long y, unsigned long n) +{ + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; + + rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv); + rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv); + + // adjust luminance + yv -= (1.0 - ((float)n / 250.0)); + if (yv < 0.0) yv = 0.0; + + hsv_to_rgb(xh, xs, yv, &r, &g, &b); + + return makecol16(r, g, b); +} + +// Take hue and saturation of blend colour, luminance of image +unsigned long _myblender_color32_light(unsigned long x, unsigned long y, unsigned long n) +{ + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; + + rgb_to_hsv(getr32(x), getg32(x), getb32(x), &xh, &xs, &xv); + rgb_to_hsv(getr32(y), getg32(y), getb32(y), &yh, &ys, &yv); + + // adjust luminance + yv -= (1.0 - ((float)n / 250.0)); + if (yv < 0.0) yv = 0.0; + + hsv_to_rgb(xh, xs, yv, &r, &g, &b); + + return makeacol32(r, g, b, geta32(y)); +} + +// Take hue and saturation of blend colour, luminance of image +unsigned long _myblender_color15(unsigned long x, unsigned long y, unsigned long n) +{ + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; + + rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv); + rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv); + + hsv_to_rgb(xh, xs, yv, &r, &g, &b); + + return makecol15(r, g, b); +} + +// Take hue and saturation of blend colour, luminance of image +unsigned long _myblender_color16(unsigned long x, unsigned long y, unsigned long n) +{ + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; + + rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv); + rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv); + + hsv_to_rgb(xh, xs, yv, &r, &g, &b); + + return makecol16(r, g, b); +} + +// Take hue and saturation of blend colour, luminance of image +unsigned long _myblender_color32(unsigned long x, unsigned long y, unsigned long n) +{ + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; + + rgb_to_hsv(getr32(x), getg32(x), getb32(x), &xh, &xs, &xv); + rgb_to_hsv(getr32(y), getg32(y), getb32(y), &yh, &ys, &yv); + + hsv_to_rgb(xh, xs, yv, &r, &g, &b); + + return makeacol32(r, g, b, geta32(y)); +} + +// trans24 blender, but preserve alpha channel from image +unsigned long _myblender_alpha_trans24(unsigned long x, unsigned long y, unsigned long n) +{ + unsigned long res, g, alph; + + if (n) + n++; + + alph = y & 0xff000000; + y &= 0x00ffffff; + + res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y; + y &= 0xFF00; + x &= 0xFF00; + g = (x - y) * n / 256 + y; + + res &= 0xFF00FF; + g &= 0xFF00; + + return res | g | alph; +} + +void set_my_trans_blender(int r, int g, int b, int a) +{ + // use standard allegro 15 and 16 bit blenders, but customize + // the 32-bit one to preserve the alpha channel + set_blender_mode(_blender_trans15, _blender_trans16, _myblender_alpha_trans24, r, g, b, a); +} + +// plain copy source to destination +// assign new alpha value as a summ of alphas. +unsigned long _additive_alpha_copysrc_blender(unsigned long x, unsigned long y, unsigned long n) +{ + unsigned long newAlpha = ((x & 0xff000000) >> 24) + ((y & 0xff000000) >> 24); + + if (newAlpha > 0xff) newAlpha = 0xff; + + return (newAlpha << 24) | (x & 0x00ffffff); +} + +FORCEINLINE unsigned long argb2argb_blend_core(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) +{ + unsigned long dst_g, dst_alpha; + src_alpha++; + dst_alpha = geta32(dst_col); + if (dst_alpha) + dst_alpha++; + + // dst_g now contains the green hue from destination color + dst_g = (dst_col & 0x00FF00) * dst_alpha / 256; + // dst_col now contains the red & blue hues from destination color + dst_col = (dst_col & 0xFF00FF) * dst_alpha / 256; + + // res_g now contains the green hue of the pre-final color + dst_g = (((src_col & 0x00FF00) - (dst_g & 0x00FF00)) * src_alpha / 256 + dst_g) & 0x00FF00; + // res_rb now contains the red & blue hues of the pre-final color + dst_col = (((src_col & 0xFF00FF) - (dst_col & 0xFF00FF)) * src_alpha / 256 + dst_col) & 0xFF00FF; + + // dst_alpha now contains the final alpha + // we assume that final alpha will never be zero + dst_alpha = 256 - (256 - src_alpha) * (256 - dst_alpha) / 256; + // src_alpha is now the final alpha factor made for being multiplied by, + // instead of divided by: this makes it possible to use it in faster + // calculation below + src_alpha = /* 256 * 256 == */ 0x10000 / dst_alpha; + + // setting up final color hues + dst_g = (dst_g * src_alpha / 256) & 0x00FF00; + dst_col = (dst_col * src_alpha / 256) & 0xFF00FF; + return dst_col | dst_g | (--dst_alpha << 24); +} + +// blend source to destination with respect to source and destination alphas; +// assign new alpha value as a multiplication of translucenses. +// combined_alpha = front.alpha + back.alpha * (1 - front.alpha); +// combined_rgb = (front.rgb * front.alpha + back.rgb * (1 - front.alpha) * back.alpha) / combined_alpha; +unsigned long _argb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) +{ + if (src_alpha > 0) + src_alpha = geta32(src_col) * ((src_alpha & 0xFF) + 1) / 256; + else + src_alpha = geta32(src_col); + if (src_alpha == 0) + return dst_col; + return argb2argb_blend_core(src_col, dst_col, src_alpha); +} + +unsigned long _rgb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) +{ + if (src_alpha == 0 || src_alpha == 0xFF) + return src_col | 0xFF000000; + return argb2argb_blend_core(src_col | 0xFF000000, dst_col, src_alpha); +} + +unsigned long _argb2rgb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) +{ + unsigned long res, g; + + if (src_alpha > 0) + src_alpha = geta32(src_col) * ((src_alpha & 0xFF) + 1) / 256; + else + src_alpha = geta32(src_col); + if (src_alpha) + src_alpha++; + + res = ((src_col & 0xFF00FF) - (dst_col & 0xFF00FF)) * src_alpha / 256 + dst_col; + dst_col &= 0xFF00; + src_col &= 0xFF00; + g = (src_col - dst_col) * src_alpha / 256 + dst_col; + + res &= 0xFF00FF; + g &= 0xFF00; + + return res | g; +} + +// Based on _blender_alpha16, but keep source pixel if dest is transparent +unsigned long skiptranspixels_blender_alpha16(unsigned long x, unsigned long y, unsigned long n) +{ + unsigned long result; + if ((y & 0xFFFF) == 0xF81F) + return x; + n = geta32(x); + if (n) + n = (n + 1) / 8; + x = makecol16(getr32(x), getg32(x), getb32(x)); + x = (x | (x << 16)) & 0x7E0F81F; + y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F; + result = ((x - y) * n / 32 + y) & 0x7E0F81F; + return ((result & 0xFFFF) | (result >> 16)); +} + +void set_additive_alpha_blender() +{ + set_blender_mode(nullptr, nullptr, _additive_alpha_copysrc_blender, 0, 0, 0, 0); +} + +void set_argb2argb_blender(int alpha) +{ + set_blender_mode(nullptr, nullptr, _argb2argb_blender, 0, 0, 0, alpha); +} + +// sets the alpha channel to opaque. used when drawing a non-alpha sprite onto an alpha-sprite +unsigned long _opaque_alpha_blender(unsigned long x, unsigned long y, unsigned long n) +{ + return x | 0xff000000; +} + +void set_opaque_alpha_blender() +{ + set_blender_mode(nullptr, nullptr, _opaque_alpha_blender, 0, 0, 0, 0); +} + +void set_argb2any_blender() +{ + set_blender_mode_ex(_blender_black, _blender_black, _blender_black, _argb2argb_blender, + _blender_alpha15, skiptranspixels_blender_alpha16, _blender_alpha24, + 0, 0, 0, 0xff); // TODO: do we need to support proper 15- and 24-bit here? +} diff --git a/engines/ags/engine/gfx/blender.h b/engines/ags/engine/gfx/blender.h new file mode 100644 index 000000000000..fcefa935eb7a --- /dev/null +++ b/engines/ags/engine/gfx/blender.h @@ -0,0 +1,65 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS specific color blending routines for transparency and tinting effects +// +//============================================================================= + +#ifndef __AC_BLENDER_H +#define __AC_BLENDER_H + +// +// Allegro's standard alpha blenders result in: +// - src and dst RGB are combined proportionally to src alpha +// (src.rgb * src.alpha + dst.rgb * (1 - dst.alpha)); +// - final alpha is zero. +// This blender is suggested for use with opaque destinations +// (ones without alpha channel). +// +/* Declared in Allegro's color.h: +void set_alpha_blender(); +*/ + +unsigned long _myblender_color15(unsigned long x, unsigned long y, unsigned long n); +unsigned long _myblender_color16(unsigned long x, unsigned long y, unsigned long n); +unsigned long _myblender_color32(unsigned long x, unsigned long y, unsigned long n); +unsigned long _myblender_color15_light(unsigned long x, unsigned long y, unsigned long n); +unsigned long _myblender_color16_light(unsigned long x, unsigned long y, unsigned long n); +unsigned long _myblender_color32_light(unsigned long x, unsigned long y, unsigned long n); +// Customizable alpha blender that uses the supplied alpha value as src alpha, +// and preserves destination's alpha channel (if there was one); +void set_my_trans_blender(int r, int g, int b, int a); +// Argb2argb alpha blender combines RGBs proportionally to src alpha, but also +// applies dst alpha factor to the dst RGB used in the merge; +// The final alpha is calculated by multiplying two translucences (1 - .alpha). +// Custom alpha parameter, when not zero, is treated as fraction of source +// alpha that has to be used in color blending. +unsigned long _argb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha); +// Argb2rgb blender combines RGBs proportionally to src alpha, but discards alpha in the end. +// It is almost a clone of Allegro's _blender_alpha32, except it also applies optional overall alpha. +unsigned long _argb2rgb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha); +// Rgb2argb blender treats all src pixels as if having opaque alpha. +unsigned long _rgb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha); +// Sets the alpha channel to opaque. Used when drawing a non-alpha sprite onto an alpha-sprite. +unsigned long _opaque_alpha_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha); + +// Additive alpha blender plain copies src over, applying a summ of src and +// dst alpha values. +void set_additive_alpha_blender(); +// Opaque alpha blender plain copies src over, applying opaque alpha value. +void set_opaque_alpha_blender(); +// Sets argb2argb for 32-bit mode, and provides appropriate funcs for blending 32-bit onto 15/16/24-bit destination +void set_argb2any_blender(); + +#endif // __AC_BLENDER_H diff --git a/engines/ags/engine/gfx/color_engine.cpp b/engines/ags/engine/gfx/color_engine.cpp new file mode 100644 index 000000000000..4946b2b4bf53 --- /dev/null +++ b/engines/ags/engine/gfx/color_engine.cpp @@ -0,0 +1,59 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Implementation from wgt2allg.cpp specific to Engine runtime +// +//============================================================================= + +#include "core/platform.h" + +#include "util/wgt2allg.h" +#include "gfx/bitmap.h" + +void __my_setcolor(int *ctset, int newcol, int wantColDep) + { + if (wantColDep == 8) + ctset[0] = newcol; + else if (newcol & 0x40000000) // already calculated it + ctset[0] = newcol; + else if ((newcol >= 32) && (wantColDep > 16)) { + // true-color +#ifdef SWAP_RB_HICOL_FOR_32to24_32 + ctset[0] = makeacol32(getb16(newcol), getg16(newcol), getr16(newcol), 255); +#else + ctset[0] = makeacol32(getr16(newcol), getg16(newcol), getb16(newcol), 255); +#endif + } + else if (newcol >= 32) { + + // If it's 15-bit, convert the color + if (wantColDep == 15) + ctset[0] = (newcol & 0x001f) | ((newcol >> 1) & 0x7fe0); + else + ctset[0] = newcol; + } + else + { + ctset[0] = makecol_depth(wantColDep, col_lookups[newcol] >> 16, + (col_lookups[newcol] >> 8) & 0x000ff, col_lookups[newcol] & 0x000ff); + + // in case it's used on an alpha-channel sprite, make sure it's visible + if (wantColDep > 16) + ctset[0] |= 0xff000000; + } + + // if it's 32-bit color, signify that the colour has been calculated + //if (wantColDep >= 24) +// ctset[0] |= 0x40000000; + } diff --git a/engines/ags/engine/gfx/ddb.h b/engines/ags/engine/gfx/ddb.h new file mode 100644 index 000000000000..553b36f17d04 --- /dev/null +++ b/engines/ags/engine/gfx/ddb.h @@ -0,0 +1,45 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Driver-dependant bitmap interface +// +//============================================================================= +#ifndef __AGS_EE_GFX__DDB_H +#define __AGS_EE_GFX__DDB_H + +namespace AGS +{ +namespace Engine +{ + +class IDriverDependantBitmap +{ +public: + virtual ~IDriverDependantBitmap() = default; + + virtual void SetTransparency(int transparency) = 0; // 0-255 + virtual void SetFlippedLeftRight(bool isFlipped) = 0; + virtual void SetStretch(int width, int height, bool useResampler = true) = 0; + virtual void SetLightLevel(int light_level) = 0; // 0-255 + virtual void SetTint(int red, int green, int blue, int tintSaturation) = 0; // 0-255 + + virtual int GetWidth() = 0; + virtual int GetHeight() = 0; + virtual int GetColorDepth() = 0; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__DDB_H diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp new file mode 100644 index 000000000000..04b76d0b803a --- /dev/null +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -0,0 +1,190 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" +#include "gfx/gfx_util.h" +#include "gfx/blender.h" + +// CHECKME: is this hack still relevant? +#if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID +extern int psp_gfx_renderer; +#endif + +namespace AGS +{ +namespace Engine +{ + +using namespace Common; + +namespace GfxUtil +{ + +Bitmap *ConvertBitmap(Bitmap *src, int dst_color_depth) +{ + int src_col_depth = src->GetColorDepth(); + if (src_col_depth != dst_color_depth) + { + int old_conv = get_color_conversion(); + // TODO: find out what is this, and why do we need to call this every time (do we?) + set_color_conversion(COLORCONV_KEEP_TRANS | COLORCONV_TOTAL); + Bitmap *dst = BitmapHelper::CreateBitmapCopy(src, dst_color_depth); + set_color_conversion(old_conv); + return dst; + } + return src; +} + + +typedef BLENDER_FUNC PfnBlenderCb; + +struct BlendModeSetter +{ + // Blender setter for destination with and without alpha channel; + // assign null pointer if not supported + PfnBlenderCb AllAlpha; // src w alpha -> dst w alpha + PfnBlenderCb AlphaToOpaque; // src w alpha -> dst w/o alpha + PfnBlenderCb OpaqueToAlpha; // src w/o alpha -> dst w alpha + PfnBlenderCb OpaqueToAlphaNoTrans; // src w/o alpha -> dst w alpha (opt-ed for no transparency) + PfnBlenderCb AllOpaque; // src w/o alpha -> dst w/o alpha +}; + +// Array of blender descriptions +// NOTE: set NULL function pointer to fallback to common image blitting +static const BlendModeSetter BlendModeSets[kNumBlendModes] = +{ + { nullptr, nullptr, nullptr, nullptr, nullptr }, // kBlendMode_NoAlpha + { _argb2argb_blender, _argb2rgb_blender, _rgb2argb_blender, _opaque_alpha_blender, nullptr }, // kBlendMode_Alpha + // NOTE: add new modes here +}; + +bool SetBlender(BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) +{ + if (blend_mode < 0 || blend_mode > kNumBlendModes) + return false; + const BlendModeSetter &set = BlendModeSets[blend_mode]; + PfnBlenderCb blender; + if (dst_has_alpha) + blender = src_has_alpha ? set.AllAlpha : + (blend_alpha == 0xFF ? set.OpaqueToAlphaNoTrans : set.OpaqueToAlpha); + else + blender = src_has_alpha ? set.AlphaToOpaque : set.AllOpaque; + + if (blender) + { + set_blender_mode(nullptr, nullptr, blender, 0, 0, 0, blend_alpha); + return true; + } + return false; +} + +void DrawSpriteBlend(Bitmap *ds, const Point &ds_at, Bitmap *sprite, + BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) +{ + if (blend_alpha <= 0) + return; // do not draw 100% transparent image + + if (// support only 32-bit blending at the moment + ds->GetColorDepth() == 32 && sprite->GetColorDepth() == 32 && + // set blenders if applicable and tell if succeeded + SetBlender(blend_mode, dst_has_alpha, src_has_alpha, blend_alpha)) + { + ds->TransBlendBlt(sprite, ds_at.X, ds_at.Y); + } + else + { + GfxUtil::DrawSpriteWithTransparency(ds, sprite, ds_at.X, ds_at.Y, blend_alpha); + } +} + +void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int alpha) +{ + if (alpha <= 0) + { + // fully transparent, don't draw it at all + return; + } + + int surface_depth = ds->GetColorDepth(); + int sprite_depth = sprite->GetColorDepth(); + + if (sprite_depth < surface_depth + // CHECKME: what is the purpose of this hack and is this still relevant? +#if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID + || (ds->GetBPP() < surface_depth && psp_gfx_renderer > 0) // Fix for corrupted speechbox outlines with the OGL driver +#endif + ) + { + // If sprite is lower color depth than destination surface, e.g. + // 8-bit sprites drawn on 16/32-bit surfaces. + if (sprite_depth == 8 && surface_depth >= 24) + { + // 256-col sprite -> truecolor background + // this is automatically supported by allegro, no twiddling needed + ds->Blit(sprite, x, y, kBitmap_Transparency); + return; + } + + // 256-col sprite -> hi-color background, or + // 16-bit sprite -> 32-bit background + Bitmap hctemp; + hctemp.CreateCopy(sprite, surface_depth); + if (sprite_depth == 8) + { + // only do this for 256-col -> hi-color, cos the Blit call converts + // transparency for 16->32 bit + color_t mask_color = hctemp.GetMaskColor(); + for (int scan_y = 0; scan_y < hctemp.GetHeight(); ++scan_y) + { + // we know this must be 1 bpp source and 2 bpp pixel destination + const uint8_t *src_scanline = sprite->GetScanLine(scan_y); + uint16_t *dst_scanline = (uint16_t*)hctemp.GetScanLineForWriting(scan_y); + for (int scan_x = 0; scan_x < hctemp.GetWidth(); ++scan_x) + { + if (src_scanline[scan_x] == 0) + { + dst_scanline[scan_x] = mask_color; + } + } + } + } + + if (alpha < 0xFF) + { + set_trans_blender(0, 0, 0, alpha); + ds->TransBlendBlt(&hctemp, x, y); + } + else + { + ds->Blit(&hctemp, x, y, kBitmap_Transparency); + } + } + else + { + if (alpha < 0xFF && surface_depth > 8 && sprite_depth > 8) + { + set_trans_blender(0, 0, 0, alpha); + ds->TransBlendBlt(sprite, x, y); + } + else + { + ds->Blit(sprite, x, y, kBitmap_Transparency); + } + } +} + +} // namespace GfxUtil + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfx_util.h b/engines/ags/engine/gfx/gfx_util.h new file mode 100644 index 000000000000..924e3cc755d6 --- /dev/null +++ b/engines/ags/engine/gfx/gfx_util.h @@ -0,0 +1,59 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Intermediate level drawing utility functions. +// +// GfxUtil namespace is meant for intermediate-to-lower level functions, that +// implement specific conversions, tricks and hacks for drawing bitmaps and +// geometry. +// The suggested convention is to add only those functions, that do not require +// any knowledge of higher-level engine types and objects. +// +//============================================================================= +#ifndef __AGS_EE_GFX__GFXUTIL_H +#define __AGS_EE_GFX__GFXUTIL_H + +#include "gfx/bitmap.h" +#include "gfx/gfx_def.h" + +namespace AGS +{ +namespace Engine +{ + +using Common::Bitmap; + +namespace GfxUtil +{ + // Creates a COPY of the source bitmap, converted to the given format. + Bitmap *ConvertBitmap(Bitmap *src, int dst_color_depth); + + // Considers the given information about source and destination surfaces, + // then draws a bimtap over another either using requested blending mode, + // or fallbacks to common "magic pink" transparency mode; + // optionally uses blending alpha (overall image transparency). + void DrawSpriteBlend(Bitmap *ds, const Point &ds_at, Bitmap *sprite, + Common::BlendMode blend_mode, bool dst_has_alpha = true, bool src_has_alpha = true, int blend_alpha = 0xFF); + + // Draws a bitmap over another one with given alpha level (0 - 255), + // takes account of the bitmap's mask color, + // ignores image's alpha channel, even if there's one; + // does proper conversion depending on respected color depths. + void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int alpha = 0xFF); +} // namespace GfxUtil + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GFXUTIL_H diff --git a/engines/ags/engine/gfx/gfxdefines.h b/engines/ags/engine/gfx/gfxdefines.h new file mode 100644 index 000000000000..0efa99e07506 --- /dev/null +++ b/engines/ags/engine/gfx/gfxdefines.h @@ -0,0 +1,82 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_GFX__GFXDEFINES_H +#define __AGS_EE_GFX__GFXDEFINES_H + +#include "core/types.h" + +namespace AGS +{ +namespace Engine +{ + +// TODO: find the way to merge this with sprite batch transform +enum GlobalFlipType +{ + kFlip_None, + kFlip_Horizontal, // this means - mirror over horizontal middle line + kFlip_Vertical, // this means - mirror over vertical middle line + kFlip_Both +}; + +// GraphicResolution struct determines image size and color depth +struct GraphicResolution +{ + int32_t Width; + int32_t Height; + int32_t ColorDepth; + + GraphicResolution() + : Width(0) + , Height(0) + , ColorDepth(0) + { + } + + GraphicResolution(int32_t width, int32_t height, int32_t color_depth) + { + Width = width; + Height = height; + ColorDepth = color_depth; + } + + inline bool IsValid() const { return Width > 0 && Height > 0 && ColorDepth > 0; } +}; + +// DisplayMode struct provides extended description of display mode +struct DisplayMode : public GraphicResolution +{ + int32_t RefreshRate; + bool Vsync; + bool Windowed; + + DisplayMode() + : RefreshRate(0) + , Vsync(false) + , Windowed(false) + {} + + DisplayMode(const GraphicResolution &res, bool windowed = false, int32_t refresh = 0, bool vsync = false) + : GraphicResolution(res) + , RefreshRate(refresh) + , Vsync(vsync) + , Windowed(windowed) + {} +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GFXDEFINES_H diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp new file mode 100644 index 000000000000..737d6a5071b6 --- /dev/null +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -0,0 +1,498 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/wgt2allg.h" +#include "gfx/ali3dexception.h" +#include "gfx/bitmap.h" +#include "gfx/gfxfilter.h" +#include "gfx/gfxdriverbase.h" +#include "gfx/gfx_util.h" + +using namespace AGS::Common; + +namespace AGS +{ +namespace Engine +{ + +GraphicsDriverBase::GraphicsDriverBase() + : _pollingCallback(nullptr) + , _drawScreenCallback(nullptr) + , _nullSpriteCallback(nullptr) + , _initGfxCallback(nullptr) + , _initSurfaceUpdateCallback(nullptr) +{ + // Initialize default sprite batch, it will be used when no other batch was activated + _actSpriteBatch = 0; + _spriteBatchDesc.push_back(SpriteBatchDesc()); +} + +bool GraphicsDriverBase::IsModeSet() const +{ + return _mode.Width != 0 && _mode.Height != 0 && _mode.ColorDepth != 0; +} + +bool GraphicsDriverBase::IsNativeSizeValid() const +{ + return !_srcRect.IsEmpty(); +} + +bool GraphicsDriverBase::IsRenderFrameValid() const +{ + return !_srcRect.IsEmpty() && !_dstRect.IsEmpty(); +} + +DisplayMode GraphicsDriverBase::GetDisplayMode() const +{ + return _mode; +} + +Size GraphicsDriverBase::GetNativeSize() const +{ + return _srcRect.GetSize(); +} + +Rect GraphicsDriverBase::GetRenderDestination() const +{ + return _dstRect; +} + +void GraphicsDriverBase::BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, + const Point offset, GlobalFlipType flip, PBitmap surface) +{ + _actSpriteBatch++; + _spriteBatchDesc.push_back(SpriteBatchDesc(viewport, transform, offset, flip, surface)); + InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]); +} + +void GraphicsDriverBase::ClearDrawLists() +{ + ResetAllBatches(); + _actSpriteBatch = 0; + _spriteBatchDesc.resize(1); +} + +void GraphicsDriverBase::OnInit(volatile int *loopTimer) +{ +} + +void GraphicsDriverBase::OnUnInit() +{ +} + +void GraphicsDriverBase::OnModeSet(const DisplayMode &mode) +{ + _mode = mode; +} + +void GraphicsDriverBase::OnModeReleased() +{ + _mode = DisplayMode(); + _dstRect = Rect(); +} + +void GraphicsDriverBase::OnScalingChanged() +{ + PGfxFilter filter = GetGraphicsFilter(); + if (filter) + _filterRect = filter->SetTranslation(_srcRect.GetSize(), _dstRect); + else + _filterRect = Rect(); + _scaling.Init(_srcRect.GetSize(), _dstRect); +} + +void GraphicsDriverBase::OnSetNativeSize(const Size &src_size) +{ + _srcRect = RectWH(0, 0, src_size.Width, src_size.Height); + OnScalingChanged(); + + // Adjust default sprite batch making it comply to native size + _spriteBatchDesc[0].Viewport = RectWH(src_size); + InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]); +} + +void GraphicsDriverBase::OnSetRenderFrame(const Rect &dst_rect) +{ + _dstRect = dst_rect; + OnScalingChanged(); +} + +void GraphicsDriverBase::OnSetFilter() +{ + _filterRect = GetGraphicsFilter()->SetTranslation(Size(_srcRect.GetSize()), _dstRect); +} + + +VideoMemoryGraphicsDriver::VideoMemoryGraphicsDriver() + : _stageVirtualScreenDDB(nullptr) + , _stageScreenDirty(false) + , _fxIndex(0) +{ + // Only to have something meaningful as default + _vmem_a_shift_32 = 24; + _vmem_r_shift_32 = 16; + _vmem_g_shift_32 = 8; + _vmem_b_shift_32 = 0; +} + +VideoMemoryGraphicsDriver::~VideoMemoryGraphicsDriver() +{ + DestroyAllStageScreens(); +} + +bool VideoMemoryGraphicsDriver::UsesMemoryBackBuffer() +{ + // Although we do use ours, we do not let engine draw upon it; + // only plugin handling are allowed to request our mem buffer. + // TODO: find better workaround? + return false; +} + +Bitmap *VideoMemoryGraphicsDriver::GetMemoryBackBuffer() +{ + return nullptr; +} + +void VideoMemoryGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) +{ // do nothing, video-memory drivers don't use main back buffer, only stage bitmaps they pass to plugins +} + +Bitmap *VideoMemoryGraphicsDriver::GetStageBackBuffer() +{ + _stageScreenDirty = true; + return _stageVirtualScreen.get(); +} + +PBitmap VideoMemoryGraphicsDriver::CreateStageScreen(size_t index, const Size &sz) +{ + if (_stageScreens.size() <= index) + _stageScreens.resize(index + 1); + if (sz.IsNull()) + _stageScreens[index].reset(); + else if (_stageScreens[index] == nullptr || _stageScreens[index]->GetSize() != sz) + _stageScreens[index].reset(new Bitmap(sz.Width, sz.Height, _mode.ColorDepth)); + return _stageScreens[index]; +} + +PBitmap VideoMemoryGraphicsDriver::GetStageScreen(size_t index) +{ + if (index < _stageScreens.size()) + return _stageScreens[index]; + return nullptr; +} + +void VideoMemoryGraphicsDriver::DestroyAllStageScreens() +{ + if (_stageVirtualScreenDDB) + this->DestroyDDB(_stageVirtualScreenDDB); + _stageVirtualScreenDDB = nullptr; + + for (size_t i = 0; i < _stageScreens.size(); ++i) + _stageScreens[i].reset(); + _stageVirtualScreen.reset(); +} + +bool VideoMemoryGraphicsDriver::DoNullSpriteCallback(int x, int y) +{ + if (!_nullSpriteCallback) + throw Ali3DException("Unhandled attempt to draw null sprite"); + _stageScreenDirty = false; + _stageVirtualScreen->ClearTransparent(); + // NOTE: this is not clear whether return value of callback may be + // relied on. Existing plugins do not seem to return anything but 0, + // even if they handle this event. + _nullSpriteCallback(x, y); + if (_stageScreenDirty) + { + if (_stageVirtualScreenDDB) + UpdateDDBFromBitmap(_stageVirtualScreenDDB, _stageVirtualScreen.get(), true); + else + _stageVirtualScreenDDB = CreateDDBFromBitmap(_stageVirtualScreen.get(), true); + return true; + } + return false; +} + +IDriverDependantBitmap *VideoMemoryGraphicsDriver::MakeFx(int r, int g, int b) +{ + if (_fxIndex == _fxPool.size()) _fxPool.push_back(ScreenFx()); + ScreenFx &fx = _fxPool[_fxIndex]; + if (fx.DDB == nullptr) + { + fx.Raw = BitmapHelper::CreateBitmap(16, 16, _mode.ColorDepth); + fx.DDB = CreateDDBFromBitmap(fx.Raw, false, true); + } + if (r != fx.Red || g != fx.Green || b != fx.Blue) + { + fx.Raw->Clear(makecol_depth(fx.Raw->GetColorDepth(), r, g, b)); + this->UpdateDDBFromBitmap(fx.DDB, fx.Raw, false); + fx.Red = r; + fx.Green = g; + fx.Blue = b; + } + _fxIndex++; + return fx.DDB; +} + +void VideoMemoryGraphicsDriver::ResetFxPool() +{ + _fxIndex = 0; +} + +void VideoMemoryGraphicsDriver::DestroyFxPool() +{ + for (auto &fx : _fxPool) + { + if (fx.DDB) + DestroyDDB(fx.DDB); + delete fx.Raw; + } + _fxPool.clear(); + _fxIndex = 0; +} + + +#define algetr32(c) getr32(c) +#define algetg32(c) getg32(c) +#define algetb32(c) getb32(c) +#define algeta32(c) geta32(c) + +#define algetr16(c) getr16(c) +#define algetg16(c) getg16(c) +#define algetb16(c) getb16(c) + +#define algetr8(c) getr8(c) +#define algetg8(c) getg8(c) +#define algetb8(c) getb8(c) + + +__inline void get_pixel_if_not_transparent8(unsigned char *pixel, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *divisor) +{ + if (pixel[0] != MASK_COLOR_8) + { + *red += algetr8(pixel[0]); + *green += algetg8(pixel[0]); + *blue += algetb8(pixel[0]); + divisor[0]++; + } +} + +__inline void get_pixel_if_not_transparent16(unsigned short *pixel, unsigned short *red, unsigned short *green, unsigned short *blue, unsigned short *divisor) +{ + if (pixel[0] != MASK_COLOR_16) + { + *red += algetr16(pixel[0]); + *green += algetg16(pixel[0]); + *blue += algetb16(pixel[0]); + divisor[0]++; + } +} + +__inline void get_pixel_if_not_transparent32(unsigned int *pixel, unsigned int *red, unsigned int *green, unsigned int *blue, unsigned int *divisor) +{ + if (pixel[0] != MASK_COLOR_32) + { + *red += algetr32(pixel[0]); + *green += algetg32(pixel[0]); + *blue += algetb32(pixel[0]); + divisor[0]++; + } +} + + +#define VMEMCOLOR_RGBA(r,g,b,a) \ + ( (((a) & 0xFF) << _vmem_a_shift_32) | (((r) & 0xFF) << _vmem_r_shift_32) | (((g) & 0xFF) << _vmem_g_shift_32) | (((b) & 0xFF) << _vmem_b_shift_32) ) + + +void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, + char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering) +{ + const int src_depth = bitmap->GetColorDepth(); + bool lastPixelWasTransparent = false; + for (int y = 0; y < tile->height; y++) + { + lastPixelWasTransparent = false; + const uint8_t *scanline_before = bitmap->GetScanLine(y + tile->y - 1); + const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); + const uint8_t *scanline_after = bitmap->GetScanLine(y + tile->y + 1); + unsigned int* memPtrLong = (unsigned int*)dst_ptr; + + for (int x = 0; x < tile->width; x++) + { + if (src_depth == 8) + { + unsigned char* srcData = (unsigned char*)&scanline_at[(x + tile->x) * sizeof(char)]; + if (*srcData == MASK_COLOR_8) + { + if (!usingLinearFiltering) + memPtrLong[x] = 0; + // set to transparent, but use the colour from the neighbouring + // pixel to stop the linear filter doing black outlines + else + { + unsigned char red = 0, green = 0, blue = 0, divisor = 0; + if (x > 0) + get_pixel_if_not_transparent8(&srcData[-1], &red, &green, &blue, &divisor); + if (x < tile->width - 1) + get_pixel_if_not_transparent8(&srcData[1], &red, &green, &blue, &divisor); + if (y > 0) + get_pixel_if_not_transparent8((unsigned char*)&scanline_before[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); + if (y < tile->height - 1) + get_pixel_if_not_transparent8((unsigned char*)&scanline_after[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); + if (divisor > 0) + memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); + else + memPtrLong[x] = 0; + } + lastPixelWasTransparent = true; + } + else + { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr8(*srcData), algetg8(*srcData), algetb8(*srcData), 0xFF); + if (lastPixelWasTransparent) + { + // update the colour of the previous tranparent pixel, to + // stop black outlines when linear filtering + memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; + lastPixelWasTransparent = false; + } + } + } + else if (src_depth == 16) + { + unsigned short* srcData = (unsigned short*)&scanline_at[(x + tile->x) * sizeof(short)]; + if (*srcData == MASK_COLOR_16) + { + if (!usingLinearFiltering) + memPtrLong[x] = 0; + // set to transparent, but use the colour from the neighbouring + // pixel to stop the linear filter doing black outlines + else + { + unsigned short red = 0, green = 0, blue = 0, divisor = 0; + if (x > 0) + get_pixel_if_not_transparent16(&srcData[-1], &red, &green, &blue, &divisor); + if (x < tile->width - 1) + get_pixel_if_not_transparent16(&srcData[1], &red, &green, &blue, &divisor); + if (y > 0) + get_pixel_if_not_transparent16((unsigned short*)&scanline_before[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); + if (y < tile->height - 1) + get_pixel_if_not_transparent16((unsigned short*)&scanline_after[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); + if (divisor > 0) + memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); + else + memPtrLong[x] = 0; + } + lastPixelWasTransparent = true; + } + else + { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); + if (lastPixelWasTransparent) + { + // update the colour of the previous tranparent pixel, to + // stop black outlines when linear filtering + memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; + lastPixelWasTransparent = false; + } + } + } + else if (src_depth == 32) + { + unsigned int* memPtrLong = (unsigned int*)dst_ptr; + unsigned int* srcData = (unsigned int*)&scanline_at[(x + tile->x) * sizeof(int)]; + if (*srcData == MASK_COLOR_32) + { + if (!usingLinearFiltering) + memPtrLong[x] = 0; + // set to transparent, but use the colour from the neighbouring + // pixel to stop the linear filter doing black outlines + else + { + unsigned int red = 0, green = 0, blue = 0, divisor = 0; + if (x > 0) + get_pixel_if_not_transparent32(&srcData[-1], &red, &green, &blue, &divisor); + if (x < tile->width - 1) + get_pixel_if_not_transparent32(&srcData[1], &red, &green, &blue, &divisor); + if (y > 0) + get_pixel_if_not_transparent32((unsigned int*)&scanline_before[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); + if (y < tile->height - 1) + get_pixel_if_not_transparent32((unsigned int*)&scanline_after[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); + if (divisor > 0) + memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); + else + memPtrLong[x] = 0; + } + lastPixelWasTransparent = true; + } + else if (has_alpha) + { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); + } + else + { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); + if (lastPixelWasTransparent) + { + // update the colour of the previous tranparent pixel, to + // stop black outlines when linear filtering + memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; + lastPixelWasTransparent = false; + } + } + } + } + + dst_ptr += dst_pitch; + } +} + +void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, + char *dst_ptr, const int dst_pitch) +{ + const int src_depth = bitmap->GetColorDepth(); + for (int y = 0; y < tile->height; y++) + { + const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); + unsigned int* memPtrLong = (unsigned int*)dst_ptr; + + for (int x = 0; x < tile->width; x++) + { + if (src_depth == 8) + { + unsigned char* srcData = (unsigned char*)&scanline_at[(x + tile->x) * sizeof(char)]; + memPtrLong[x] = VMEMCOLOR_RGBA(algetr8(*srcData), algetg8(*srcData), algetb8(*srcData), 0xFF); + } + else if (src_depth == 16) + { + unsigned short* srcData = (unsigned short*)&scanline_at[(x + tile->x) * sizeof(short)]; + memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); + } + else if (src_depth == 32) + { + unsigned int* memPtrLong = (unsigned int*)dst_ptr; + unsigned int* srcData = (unsigned int*)&scanline_at[(x + tile->x) * sizeof(int)]; + if (has_alpha) + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); + else + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); + } + } + + dst_ptr += dst_pitch; + } +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfxdriverbase.h b/engines/ags/engine/gfx/gfxdriverbase.h new file mode 100644 index 000000000000..a44534e52795 --- /dev/null +++ b/engines/ags/engine/gfx/gfxdriverbase.h @@ -0,0 +1,251 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Implementation base for graphics driver +// +//============================================================================= +#ifndef __AGS_EE_GFX__GFXDRIVERBASE_H +#define __AGS_EE_GFX__GFXDRIVERBASE_H + +#include +#include "gfx/ddb.h" +#include "gfx/graphicsdriver.h" +#include "util/scaling.h" + +namespace AGS +{ +namespace Engine +{ + +using Common::Bitmap; + +// Sprite batch, defines viewport and an optional model transformation for the list of sprites +struct SpriteBatchDesc +{ + // View rectangle for positioning and clipping, in resolution coordinates + // (this may be screen or game frame resolution, depending on circumstances) + Rect Viewport; + // Optional model transformation, to be applied to each sprite + SpriteTransform Transform; + // Global node offset applied to the whole batch as the last transform + Point Offset; + // Global node flip applied to the whole batch as the last transform + GlobalFlipType Flip; + // Optional bitmap to draw sprites upon. Used exclusively by the software rendering mode. + PBitmap Surface; + + SpriteBatchDesc() : Flip(kFlip_None) {} + SpriteBatchDesc(const Rect viewport, const SpriteTransform &transform, const Point offset = Point(), + GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) + : Viewport(viewport) + , Transform(transform) + , Offset(offset) + , Flip(flip) + , Surface(surface) + { + } +}; + +typedef std::vector SpriteBatchDescs; + +// The single sprite entry in the render list +template +struct SpriteDrawListEntry +{ + T_DDB *bitmap; // TODO: use shared pointer? + int x, y; // sprite position, in camera coordinates + bool skip; + + SpriteDrawListEntry() + : bitmap(nullptr) + , x(0) + , y(0) + , skip(false) + { + } + + SpriteDrawListEntry(T_DDB *ddb, int x_ = 0, int y_ = 0) + : bitmap(ddb) + , x(x_) + , y(y_) + , skip(false) + { + } +}; + + +// GraphicsDriverBase - is the parent class for all graphics drivers in AGS, +// that incapsulates the most common functionality. +class GraphicsDriverBase : public IGraphicsDriver +{ +public: + GraphicsDriverBase(); + + bool IsModeSet() const override; + bool IsNativeSizeValid() const override; + bool IsRenderFrameValid() const override; + DisplayMode GetDisplayMode() const override; + Size GetNativeSize() const override; + Rect GetRenderDestination() const override; + + void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, + const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) override; + void ClearDrawLists() override; + + void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) override { _pollingCallback = callback; } + void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) override + { _drawScreenCallback = callback; _drawPostScreenCallback = post_callback; } + void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) override { _initGfxCallback = callback; } + void SetCallbackOnSurfaceUpdate(GFXDRV_CLIENTCALLBACKSURFACEUPDATE callback) override { _initSurfaceUpdateCallback = callback; } + void SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback) override { _nullSpriteCallback = callback; } + +protected: + // Called after graphics driver was initialized for use for the first time + virtual void OnInit(volatile int *loopTimer); + // Called just before graphics mode is going to be uninitialized and its + // resources released + virtual void OnUnInit(); + // Called after new mode was successfully initialized + virtual void OnModeSet(const DisplayMode &mode); + // Called when the new native size is set + virtual void OnSetNativeSize(const Size &src_size); + // Called before display mode is going to be released + virtual void OnModeReleased(); + // Called when new render frame is set + virtual void OnSetRenderFrame(const Rect &dst_rect); + // Called when the new filter is set + virtual void OnSetFilter(); + // Initialize sprite batch and allocate necessary resources + virtual void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) = 0; + // Clears sprite lists + virtual void ResetAllBatches() = 0; + + void OnScalingChanged(); + + DisplayMode _mode; // display mode settings + Rect _srcRect; // rendering source rect + Rect _dstRect; // rendering destination rect + Rect _filterRect; // filter scaling destination rect (before final scaling) + PlaneScaling _scaling; // native -> render dest coordinate transformation + + // Callbacks + GFXDRV_CLIENTCALLBACK _pollingCallback; + GFXDRV_CLIENTCALLBACK _drawScreenCallback; + GFXDRV_CLIENTCALLBACK _drawPostScreenCallback; + GFXDRV_CLIENTCALLBACKXY _nullSpriteCallback; + GFXDRV_CLIENTCALLBACKINITGFX _initGfxCallback; + GFXDRV_CLIENTCALLBACKSURFACEUPDATE _initSurfaceUpdateCallback; + + // Sprite batch parameters + SpriteBatchDescs _spriteBatchDesc; // sprite batches list + size_t _actSpriteBatch; // active batch index +}; + + + +// Generic TextureTile base +struct TextureTile +{ + int x, y; + int width, height; +}; + +// Parent class for the video memory DDBs +class VideoMemDDB : public IDriverDependantBitmap +{ +public: + int GetWidth() override { return _width; } + int GetHeight() override { return _height; } + int GetColorDepth() override { return _colDepth; } + + int _width, _height; + int _colDepth; + bool _opaque; // no mask color +}; + +// VideoMemoryGraphicsDriver - is the parent class for the graphic drivers +// which drawing method is based on passing the sprite stack into GPU, +// rather than blitting to flat screen bitmap. +class VideoMemoryGraphicsDriver : public GraphicsDriverBase +{ +public: + VideoMemoryGraphicsDriver(); + ~VideoMemoryGraphicsDriver() override; + + bool UsesMemoryBackBuffer() override; + Bitmap *GetMemoryBackBuffer() override; + void SetMemoryBackBuffer(Bitmap *backBuffer) override; + Bitmap* GetStageBackBuffer() override; + +protected: + // Stage screens are raw bitmap buffers meant to be sent to plugins on demand + // at certain drawing stages. If used at least once these buffers are then + // rendered as additional sprites in their respected order. + PBitmap CreateStageScreen(size_t index, const Size &sz); + PBitmap GetStageScreen(size_t index); + void DestroyAllStageScreens(); + // Use engine callback to acquire replacement for the null sprite; + // returns true if the sprite was provided onto the virtual screen, + // and false if this entry should be skipped. + bool DoNullSpriteCallback(int x, int y); + + // Prepare and get fx item from the pool + IDriverDependantBitmap *MakeFx(int r, int g, int b); + // Resets fx pool counter + void ResetFxPool(); + // Disposes all items in the fx pool + void DestroyFxPool(); + + // Prepares bitmap to be applied to the texture, copies pixels to the provided buffer + void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, + char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering); + // Same but optimized for opaque source bitmaps which ignore transparent "mask color" + void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, + char *dst_ptr, const int dst_pitch); + + // Stage virtual screen is used to let plugins draw custom graphics + // in between render stages (between room and GUI, after GUI, and so on) + PBitmap _stageVirtualScreen; + IDriverDependantBitmap *_stageVirtualScreenDDB; + + // Color component shifts in video bitmap format (set by implementations) + int _vmem_a_shift_32; + int _vmem_r_shift_32; + int _vmem_g_shift_32; + int _vmem_b_shift_32; + +private: + // Virtual screens for rendering stages (sprite batches) + std::vector _stageScreens; + // Flag which indicates whether stage screen was drawn upon during engine + // callback and has to be inserted into sprite stack. + bool _stageScreenDirty; + + // Fx quads pool (for screen overlay effects) + struct ScreenFx + { + Bitmap *Raw = nullptr; + IDriverDependantBitmap *DDB = nullptr; + int Red = -1; + int Green = -1; + int Blue = -1; + }; + std::vector _fxPool; + size_t _fxIndex; // next free pool item +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GFXDRIVERBASE_H diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp new file mode 100644 index 000000000000..8dc58b927640 --- /dev/null +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -0,0 +1,70 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gfx/gfxdriverfactory.h" + +#include "core/platform.h" + +#define AGS_HAS_DIRECT3D (AGS_PLATFORM_OS_WINDOWS) +#define AGS_HAS_OPENGL (AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX) + +#include "gfx/ali3dsw.h" +#include "gfx/gfxfilter_allegro.h" + +#if AGS_HAS_OPENGL +#include "gfx/ali3dogl.h" +#include "gfx/gfxfilter_ogl.h" +#endif + +#if AGS_HAS_DIRECT3D +#include "platform/windows/gfx/ali3dd3d.h" +#include "gfx/gfxfilter_d3d.h" +#endif + +#include "main/main_allegro.h" + +namespace AGS +{ +namespace Engine +{ + +void GetGfxDriverFactoryNames(StringV &ids) +{ +#if AGS_HAS_DIRECT3D + ids.push_back("D3D9"); +#endif +#if AGS_HAS_OPENGL + ids.push_back("OGL"); +#endif + ids.push_back("Software"); +} + +IGfxDriverFactory *GetGfxDriverFactory(const String id) +{ +#if AGS_HAS_DIRECT3D + if (id.CompareNoCase("D3D9") == 0) + return D3D::D3DGraphicsFactory::GetFactory(); +#endif +#if AGS_HAS_OPENGL + if (id.CompareNoCase("OGL") == 0) + return OGL::OGLGraphicsFactory::GetFactory(); +#endif + if (id.CompareNoCase("Software") == 0) + return ALSW::ALSWGraphicsFactory::GetFactory(); + set_allegro_error("No graphics factory with such id: %s", id.GetCStr()); + return nullptr; +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfxdriverfactory.h b/engines/ags/engine/gfx/gfxdriverfactory.h new file mode 100644 index 000000000000..fac4b36bf225 --- /dev/null +++ b/engines/ags/engine/gfx/gfxdriverfactory.h @@ -0,0 +1,77 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Graphics driver factory interface +// +// Graphics factory is supposed to be singleton. Factory implementation must +// guarantee that it may be created and destroyed any number of times during +// program execution. +// +//============================================================================= + +#ifndef __AGS_EE_GFX__GFXDRIVERFACTORY_H +#define __AGS_EE_GFX__GFXDRIVERFACTORY_H + +#include +#include "util/string.h" +#include "util/string_types.h" + +namespace AGS +{ +namespace Engine +{ + +using Common::String; +using Common::StringV; +class IGraphicsDriver; +class IGfxFilter; +struct GfxFilterInfo; +typedef std::shared_ptr PGfxFilter; + + +class IGfxDriverFactory +{ +public: + virtual ~IGfxDriverFactory() = default; + + // Shutdown graphics factory and deallocate any resources it owns; + // graphics factory will be unusable after calling this function. + virtual void Shutdown() = 0; + // Get graphics driver associated with this factory; creates one if + // it does not exist. + virtual IGraphicsDriver * GetDriver() = 0; + // Destroy graphics driver associated with this factory; does nothing + // if one was not created yet, + virtual void DestroyDriver() = 0; + + // Get number of supported filters + virtual size_t GetFilterCount() const = 0; + // Get filter description + virtual const GfxFilterInfo *GetFilterInfo(size_t index) const = 0; + // Get ID of the default filter + virtual String GetDefaultFilterID() const = 0; + + // Assign specified filter to graphics driver + virtual PGfxFilter SetFilter(const String &id, String &filter_error) = 0; +}; + +// Query the available graphics factory names +void GetGfxDriverFactoryNames(StringV &ids); +// Acquire the graphics factory singleton object by its id +IGfxDriverFactory *GetGfxDriverFactory(const String id); + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GFXDRIVERFACTORY_H diff --git a/engines/ags/engine/gfx/gfxdriverfactorybase.h b/engines/ags/engine/gfx/gfxdriverfactorybase.h new file mode 100644 index 000000000000..c85b2afbb2b8 --- /dev/null +++ b/engines/ags/engine/gfx/gfxdriverfactorybase.h @@ -0,0 +1,110 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Base implementation of IGfxDriverFactory +// +// GfxDriverFactoryBase is a template implementation of basic driver factory +// functionality, such as creating and destruction of graphics driver, and +// managing graphic filters. +// +//============================================================================= + +#ifndef __AGS_EE_GFX__GFXDRIVERFACTORYBASE_H +#define __AGS_EE_GFX__GFXDRIVERFACTORYBASE_H + +#include +#include "gfx/gfxdriverfactory.h" +#include "gfx/gfxfilter.h" + +namespace AGS +{ +namespace Engine +{ + +template +class GfxDriverFactoryBase : public IGfxDriverFactory +{ +protected: + ~GfxDriverFactoryBase() override + { + delete _driver; + } + +public: + void Shutdown() override + { + delete this; + } + + IGraphicsDriver *GetDriver() override + { + if (!_driver) + _driver = EnsureDriverCreated(); + return _driver; + } + + void DestroyDriver() override + { + delete _driver; + _driver = nullptr; + } + + PGfxFilter SetFilter(const String &id, String &filter_error) override + { + TGfxDriverClass *driver = EnsureDriverCreated(); + if (!driver) + { + filter_error = "Graphics driver was not created"; + return PGfxFilter(); + } + + const int color_depth = driver->GetDisplayMode().ColorDepth; + if (color_depth == 0) + { + filter_error = "Graphics mode is not set"; + return PGfxFilter(); + } + + std::shared_ptr filter(CreateFilter(id)); + if (!filter) + { + filter_error = "Filter does not exist"; + return PGfxFilter(); + } + + if (!filter->Initialize(color_depth, filter_error)) + { + return PGfxFilter(); + } + + driver->SetGraphicsFilter(filter); + return filter; + } + +protected: + GfxDriverFactoryBase() + : _driver(nullptr) + { + } + + virtual TGfxDriverClass *EnsureDriverCreated() = 0; + virtual TGfxFilterClass *CreateFilter(const String &id) = 0; + + TGfxDriverClass *_driver; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GFXDRIVERFACTORYBASE_H diff --git a/engines/ags/engine/gfx/gfxfilter.h b/engines/ags/engine/gfx/gfxfilter.h new file mode 100644 index 000000000000..12d37bdfe8bd --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter.h @@ -0,0 +1,71 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Graphics filter interface +// +//============================================================================= + +#ifndef __AGS_EE_GFX__GFXFILTER_H +#define __AGS_EE_GFX__GFXFILTER_H + +#include +#include "util/geometry.h" +#include "util/string.h" + +namespace AGS +{ +namespace Engine +{ + +using Common::String; + +struct GfxFilterInfo +{ + String Id; + String Name; + int MinScale; + int MaxScale; + + GfxFilterInfo() + {} + GfxFilterInfo(String id, String name, int min_scale = 0, int max_scale = 0) + : Id(id) + , Name(name) + , MinScale(min_scale) + , MaxScale(max_scale) + {} +}; + +class IGfxFilter +{ +public: + virtual ~IGfxFilter() = default; + + virtual const GfxFilterInfo &GetInfo() const = 0; + + // Init filter for the specified color depth + virtual bool Initialize(const int color_depth, String &err_str) = 0; + virtual void UnInitialize() = 0; + // Try to set rendering translation; returns actual supported destination rect + virtual Rect SetTranslation(const Size src_size, const Rect dst_rect) = 0; + // Get defined destination rect for this filter + virtual Rect GetDestination() const = 0; +}; + +typedef std::shared_ptr PGfxFilter; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp new file mode 100644 index 000000000000..48da032ae4f2 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp @@ -0,0 +1,53 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" +#include "stdio.h" +#include "gfx/gfxfilter_aad3d.h" + +#if AGS_PLATFORM_OS_WINDOWS +#include +#endif + +namespace AGS +{ +namespace Engine +{ +namespace D3D +{ + +const GfxFilterInfo AAD3DGfxFilter::FilterInfo = GfxFilterInfo("Linear", "Linear interpolation"); + +const GfxFilterInfo &AAD3DGfxFilter::GetInfo() const +{ + return FilterInfo; +} + +void AAD3DGfxFilter::SetSamplerStateForStandardSprite(void *direct3ddevice9) +{ +#if AGS_PLATFORM_OS_WINDOWS + IDirect3DDevice9* d3d9 = ((IDirect3DDevice9*)direct3ddevice9); + d3d9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + d3d9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); +#endif +} + +bool AAD3DGfxFilter::NeedToColourEdgeLines() +{ + return true; +} + +} // namespace D3D +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.h b/engines/ags/engine/gfx/gfxfilter_aad3d.h new file mode 100644 index 000000000000..1e990799f927 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Anti-aliased D3D filter +// +//============================================================================= + +#ifndef __AGS_EE_GFX__AAD3DGFXFILTER_H +#define __AGS_EE_GFX__AAD3DGFXFILTER_H + +#include "gfx/gfxfilter_d3d.h" + +namespace AGS +{ +namespace Engine +{ +namespace D3D +{ + +class AAD3DGfxFilter : public D3DGfxFilter +{ +public: + const GfxFilterInfo &GetInfo() const override; + + void SetSamplerStateForStandardSprite(void *direct3ddevice9) override; + bool NeedToColourEdgeLines() override; + + static const GfxFilterInfo FilterInfo; +}; + +} // namespace D3D +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__AAD3DGFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp new file mode 100644 index 000000000000..8b2fc4096462 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX + +#include "gfx/gfxfilter_aaogl.h" +#include "ogl_headers.h" + +namespace AGS +{ +namespace Engine +{ +namespace OGL +{ + +const GfxFilterInfo AAOGLGfxFilter::FilterInfo = GfxFilterInfo("Linear", "Linear interpolation"); + +bool AAOGLGfxFilter::UseLinearFiltering() const +{ + return true; +} + +void AAOGLGfxFilter::SetFilteringForStandardSprite() +{ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +const GfxFilterInfo &AAOGLGfxFilter::GetInfo() const +{ + return FilterInfo; +} + +} // namespace OGL +} // namespace Engine +} // namespace AGS + +#endif // only on Windows, Android and iOS diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.h b/engines/ags/engine/gfx/gfxfilter_aaogl.h new file mode 100644 index 000000000000..064c5ba4c25a --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Anti-aliased OGL filter +// +//============================================================================= + +#ifndef __AGS_EE_GFX__AAOGLGFXFILTER_H +#define __AGS_EE_GFX__AAOGLGFXFILTER_H + +#include "gfx/gfxfilter_ogl.h" + +namespace AGS +{ +namespace Engine +{ +namespace OGL +{ + +class AAOGLGfxFilter : public OGLGfxFilter +{ +public: + const GfxFilterInfo &GetInfo() const override; + + bool UseLinearFiltering() const override; + void SetFilteringForStandardSprite() override; + + static const GfxFilterInfo FilterInfo; +}; + +} // namespace OGL +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__AAOGLGFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp new file mode 100644 index 000000000000..274163c1e8ce --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -0,0 +1,172 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gfx/gfxfilter_allegro.h" + +namespace AGS +{ +namespace Engine +{ +namespace ALSW +{ + +using namespace Common; + +const GfxFilterInfo AllegroGfxFilter::FilterInfo = GfxFilterInfo("StdScale", "Nearest-neighbour"); + +AllegroGfxFilter::AllegroGfxFilter() + : realScreen(nullptr) + , virtualScreen(nullptr) + , realScreenSizedBuffer(nullptr) + , lastBlitFrom(nullptr) + , lastBlitX(0) + , lastBlitY(0) +{ +} + +const GfxFilterInfo &AllegroGfxFilter::GetInfo() const +{ + return FilterInfo; +} + +Bitmap* AllegroGfxFilter::InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) +{ + ShutdownAndReturnRealScreen(); + + realScreen = screen; + SetTranslation(src_size, dst_rect); + + if (src_size == dst_rect.GetSize() && dst_rect.Top == 0 && dst_rect.Left == 0) + { + // Speed up software rendering if no scaling is performed + realScreenSizedBuffer = nullptr; + virtualScreen = realScreen; + } + else + { + realScreenSizedBuffer = BitmapHelper::CreateBitmap(screen->GetWidth(), screen->GetHeight(), screen->GetColorDepth()); + virtualScreen = BitmapHelper::CreateBitmap(src_size.Width, src_size.Height, screen->GetColorDepth()); + } + return virtualScreen; +} + +Bitmap *AllegroGfxFilter::ShutdownAndReturnRealScreen() +{ + if (virtualScreen != realScreen) + delete virtualScreen; + delete realScreenSizedBuffer; + virtualScreen = nullptr; + realScreenSizedBuffer = nullptr; + Bitmap *real_scr = realScreen; + realScreen = nullptr; + return real_scr; +} + +void AllegroGfxFilter::RenderScreen(Bitmap *toRender, int x, int y) { + + if (toRender != realScreen) + { + x = _scaling.X.ScalePt(x); + y = _scaling.Y.ScalePt(y); + const int width = _scaling.X.ScaleDistance(toRender->GetWidth()); + const int height = _scaling.Y.ScaleDistance(toRender->GetHeight()); + Bitmap *render_src = PreRenderPass(toRender); + if (render_src->GetSize() == _dstRect.GetSize()) + realScreen->Blit(render_src, 0, 0, x, y, width, height); + else + { + realScreen->StretchBlt(render_src, RectWH(x, y, width, height)); + } + } + lastBlitFrom = toRender; + lastBlitX = x; + lastBlitY = y; +} + +void AllegroGfxFilter::RenderScreenFlipped(Bitmap *toRender, int x, int y, GlobalFlipType flipType) { + + if (toRender == virtualScreen) + return; + + switch (flipType) + { + case kFlip_Horizontal: + virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HFlip); + break; + case kFlip_Vertical: + virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_VFlip); + break; + case kFlip_Both: + virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HVFlip); + break; + default: + virtualScreen->Blit(toRender, 0, 0); + break; + } + + RenderScreen(virtualScreen, x, y); +} + +void AllegroGfxFilter::ClearRect(int x1, int y1, int x2, int y2, int color) +{ + if (!realScreen) return; + Rect r = _scaling.ScaleRange(Rect(x1, y1, x2, y2)); + realScreen->FillRect(r, color); +} + +void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap) +{ + GetCopyOfScreenIntoBitmap(copyBitmap, true); +} + +void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_with_yoffset) +{ + if (copyBitmap == realScreen) + return; + + if (!copy_with_yoffset) + { + if (copyBitmap->GetSize() == _dstRect.GetSize()) + copyBitmap->Blit(realScreen, _dstRect.Left, _dstRect.Top, 0, 0, _dstRect.GetWidth(), _dstRect.GetHeight()); + else + { + // Can't stretch_blit from Video Memory to normal memory, + // so copy the screen to a buffer first. + realScreenSizedBuffer->Blit(realScreen, 0, 0); + copyBitmap->StretchBlt(realScreenSizedBuffer, + _dstRect, + RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); + } + } + else if (!lastBlitFrom) + copyBitmap->Fill(0); + else if (copyBitmap->GetSize() == _dstRect.GetSize()) + copyBitmap->Blit(realScreen, lastBlitX, lastBlitY, 0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight()); + else + { + copyBitmap->StretchBlt(lastBlitFrom, + RectWH(0, 0, lastBlitFrom->GetWidth(), lastBlitFrom->GetHeight()), + RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); + } +} + +Bitmap *AllegroGfxFilter::PreRenderPass(Bitmap *toRender) +{ + // do nothing by default + return toRender; +} + +} // namespace ALSW +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h new file mode 100644 index 000000000000..53f52c4faed0 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -0,0 +1,71 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Standard software scaling filter +// +//============================================================================= + +#ifndef __AGS_EE_GFX__ALLEGROGFXFILTER_H +#define __AGS_EE_GFX__ALLEGROGFXFILTER_H + +#include "gfx/bitmap.h" +#include "gfx/gfxfilter_scaling.h" +#include "gfx/gfxdefines.h" + +namespace AGS +{ +namespace Engine +{ +namespace ALSW +{ + +using Common::Bitmap; + +class AllegroGfxFilter : public ScalingGfxFilter +{ +public: + AllegroGfxFilter(); + + const GfxFilterInfo &GetInfo() const override; + + virtual Bitmap *InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect); + virtual Bitmap *ShutdownAndReturnRealScreen(); + virtual void RenderScreen(Bitmap *toRender, int x, int y); + virtual void RenderScreenFlipped(Bitmap *toRender, int x, int y, GlobalFlipType flipType); + virtual void ClearRect(int x1, int y1, int x2, int y2, int color); + virtual void GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap); + virtual void GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_with_yoffset); + + static const GfxFilterInfo FilterInfo; + +protected: + virtual Bitmap *PreRenderPass(Bitmap *toRender); + + // pointer to real screen bitmap + Bitmap *realScreen; + // bitmap the size of game resolution + Bitmap *virtualScreen; + // buffer for making a copy of video memory before stretching + // for screen capture + Bitmap *realScreenSizedBuffer; + Bitmap *lastBlitFrom; + int lastBlitX; + int lastBlitY; +}; + +} // namespace ALSW +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__ALLEGROGFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.cpp b/engines/ags/engine/gfx/gfxfilter_d3d.cpp new file mode 100644 index 000000000000..7e9ac6fd5223 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_d3d.cpp @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" +#include "gfx/gfxfilter_d3d.h" +#if AGS_PLATFORM_OS_WINDOWS +#include +#endif + +namespace AGS +{ +namespace Engine +{ +namespace D3D +{ + +const GfxFilterInfo D3DGfxFilter::FilterInfo = GfxFilterInfo("StdScale", "Nearest-neighbour"); + +const GfxFilterInfo &D3DGfxFilter::GetInfo() const +{ + return FilterInfo; +} + +void D3DGfxFilter::SetSamplerStateForStandardSprite(void *direct3ddevice9) +{ +#if AGS_PLATFORM_OS_WINDOWS + IDirect3DDevice9* d3d9 = ((IDirect3DDevice9*)direct3ddevice9); + d3d9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + d3d9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); +#endif +} + +bool D3DGfxFilter::NeedToColourEdgeLines() +{ + return false; +} + +} // namespace D3D +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.h b/engines/ags/engine/gfx/gfxfilter_d3d.h new file mode 100644 index 000000000000..dee22e5c7757 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_d3d.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Standard 3D-accelerated filter +// +//============================================================================= + +#ifndef __AGS_EE_GFX__D3DGFXFILTER_H +#define __AGS_EE_GFX__D3DGFXFILTER_H + +#include "gfx/gfxfilter_scaling.h" + +namespace AGS +{ +namespace Engine +{ +namespace D3D +{ + +class D3DGfxFilter : public ScalingGfxFilter +{ +public: + const GfxFilterInfo &GetInfo() const override; + + virtual void SetSamplerStateForStandardSprite(void *direct3ddevice9); + virtual bool NeedToColourEdgeLines(); + + static const GfxFilterInfo FilterInfo; +}; + +} // namespace D3D +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__D3DGFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp new file mode 100644 index 000000000000..6b7f843ba660 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -0,0 +1,92 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gfx/bitmap.h" +#include "gfx/gfxfilter_hqx.h" +#include "gfx/hq2x3x.h" + +namespace AGS +{ +namespace Engine +{ +namespace ALSW +{ + +using namespace Common; + +const GfxFilterInfo HqxGfxFilter::FilterInfo = GfxFilterInfo("Hqx", "Hqx (High Quality)", 2, 3); + +HqxGfxFilter::HqxGfxFilter() + : _pfnHqx(nullptr) + , _hqxScalingBuffer(nullptr) +{ +} + +HqxGfxFilter::~HqxGfxFilter() +{ + delete _hqxScalingBuffer; +} + +const GfxFilterInfo &HqxGfxFilter::GetInfo() const +{ + return FilterInfo; +} + +bool HqxGfxFilter::Initialize(const int color_depth, String &err_str) +{ + if (color_depth < 32) + { + err_str = "Only supports 32-bit colour games"; + return false; + } + return AllegroGfxFilter::Initialize(color_depth, err_str); +} + +Bitmap* HqxGfxFilter::InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) +{ + Bitmap *virtual_screen = AllegroGfxFilter::InitVirtualScreen(screen, src_size, dst_rect); + + // Choose used algorithm depending on minimal required integer scaling + int min_scaling = Math::Min(dst_rect.GetWidth() / src_size.Width, dst_rect.GetHeight() / src_size.Height); + min_scaling = Math::Clamp(min_scaling, 2, 3); + if (min_scaling == 2) + _pfnHqx = hq2x_32; + else + _pfnHqx = hq3x_32; + _hqxScalingBuffer = BitmapHelper::CreateBitmap(src_size.Width * min_scaling, src_size.Height * min_scaling); + + InitLUTs(); + return virtual_screen; +} + +Bitmap *HqxGfxFilter::ShutdownAndReturnRealScreen() +{ + Bitmap *real_screen = AllegroGfxFilter::ShutdownAndReturnRealScreen(); + delete _hqxScalingBuffer; + _hqxScalingBuffer = nullptr; + return real_screen; +} + +Bitmap *HqxGfxFilter::PreRenderPass(Bitmap *toRender) +{ + _hqxScalingBuffer->Acquire(); + _pfnHqx(toRender->GetDataForWriting(), _hqxScalingBuffer->GetDataForWriting(), + toRender->GetWidth(), toRender->GetHeight(), _hqxScalingBuffer->GetLineLength()); + _hqxScalingBuffer->Release(); + return _hqxScalingBuffer; +} + +} // namespace ALSW +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h new file mode 100644 index 000000000000..d4a0f0de61ad --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -0,0 +1,58 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// High quality x2 scaling filter +// +//============================================================================= + +#ifndef __AGS_EE_GFX__HQ2XGFXFILTER_H +#define __AGS_EE_GFX__HQ2XGFXFILTER_H + +#include "gfx/gfxfilter_allegro.h" + +namespace AGS +{ +namespace Engine +{ +namespace ALSW +{ + +class HqxGfxFilter : public AllegroGfxFilter +{ +public: + HqxGfxFilter(); + ~HqxGfxFilter() override; + + const GfxFilterInfo &GetInfo() const override; + + bool Initialize(const int color_depth, String &err_str) override; + Bitmap *InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) override; + Bitmap *ShutdownAndReturnRealScreen() override; + + static const GfxFilterInfo FilterInfo; + +protected: + Bitmap *PreRenderPass(Bitmap *toRender) override; + + typedef void (*PfnHqx)(unsigned char *in, unsigned char *out, int src_w, int src_h, int bpl); + + PfnHqx _pfnHqx; + Bitmap *_hqxScalingBuffer; +}; + +} // namespace ALSW +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__HQ2XGFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.cpp b/engines/ags/engine/gfx/gfxfilter_ogl.cpp new file mode 100644 index 000000000000..e6cb85777a78 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_ogl.cpp @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX + +#include "gfx/gfxfilter_ogl.h" +#include "ogl_headers.h" + +namespace AGS +{ +namespace Engine +{ +namespace OGL +{ + +const GfxFilterInfo OGLGfxFilter::FilterInfo = GfxFilterInfo("StdScale", "Nearest-neighbour"); + +bool OGLGfxFilter::UseLinearFiltering() const +{ + return false; +} + +void OGLGfxFilter::SetFilteringForStandardSprite() +{ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +} + +const GfxFilterInfo &OGLGfxFilter::GetInfo() const +{ + return FilterInfo; +} + +} // namespace OGL +} // namespace Engine +} // namespace AGS + +#endif // only on Windows, Android and iOS diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.h b/engines/ags/engine/gfx/gfxfilter_ogl.h new file mode 100644 index 000000000000..d863fa42f8f0 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_ogl.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Dummy OpenGL filter; does nothing useful at the moment +// +//============================================================================= + +#ifndef __AGS_EE_GFX__OGLGFXFILTER_H +#define __AGS_EE_GFX__OGLGFXFILTER_H + +#include "gfx/gfxfilter_scaling.h" + +namespace AGS +{ +namespace Engine +{ +namespace OGL +{ + +class OGLGfxFilter : public ScalingGfxFilter +{ +public: + const GfxFilterInfo &GetInfo() const override; + + virtual bool UseLinearFiltering() const; + virtual void SetFilteringForStandardSprite(); + + static const GfxFilterInfo FilterInfo; +}; + +} // namespace D3D +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__OGLGFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.cpp b/engines/ags/engine/gfx/gfxfilter_scaling.cpp new file mode 100644 index 000000000000..50e1834460e4 --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_scaling.cpp @@ -0,0 +1,47 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gfx/gfxfilter_scaling.h" + +namespace AGS +{ +namespace Engine +{ + +bool ScalingGfxFilter::Initialize(const int color_depth, String &err_str) +{ + // succeed by default + return true; +} + +void ScalingGfxFilter::UnInitialize() +{ + // do nothing by default +} + +Rect ScalingGfxFilter::SetTranslation(const Size src_size, const Rect dst_rect) +{ + // do not restrict scaling by default + _dstRect = dst_rect; + _scaling.Init(src_size, dst_rect); + return _dstRect; +} + +Rect ScalingGfxFilter::GetDestination() const +{ + return _dstRect; +} + +} // namespace Engine +} // namespace AGS diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.h b/engines/ags/engine/gfx/gfxfilter_scaling.h new file mode 100644 index 000000000000..80290400320c --- /dev/null +++ b/engines/ags/engine/gfx/gfxfilter_scaling.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Base class for graphic filter which provides virtual screen scaling +// +//============================================================================= + +#ifndef __AGS_EE_GFX__SCALINGGFXFILTER_H +#define __AGS_EE_GFX__SCALINGGFXFILTER_H + +#include "gfx/gfxfilter.h" +#include "util/scaling.h" + +namespace AGS +{ +namespace Engine +{ + +class ScalingGfxFilter : public IGfxFilter +{ +public: + bool Initialize(const int color_depth, String &err_str) override; + void UnInitialize() override; + Rect SetTranslation(const Size src_size, const Rect dst_rect) override; + Rect GetDestination() const override; + +protected: + Rect _dstRect; + PlaneScaling _scaling; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__SCALINGGFXFILTER_H diff --git a/engines/ags/engine/gfx/gfxmodelist.h b/engines/ags/engine/gfx/gfxmodelist.h new file mode 100644 index 000000000000..281c5c06ddda --- /dev/null +++ b/engines/ags/engine/gfx/gfxmodelist.h @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Supported graphics mode interface +// +//============================================================================= +#ifndef __AGS_EE_GFX__GFXMODELIST_H +#define __AGS_EE_GFX__GFXMODELIST_H + +#include "core/types.h" +#include "gfx/gfxdefines.h" + +namespace AGS +{ +namespace Engine +{ + +class IGfxModeList +{ +public: + virtual ~IGfxModeList() = default; + virtual int GetModeCount() const = 0; + virtual bool GetMode(int index, DisplayMode &mode) const = 0; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GFXMODELIST_H diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h new file mode 100644 index 000000000000..f2d4e0d4759d --- /dev/null +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -0,0 +1,190 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Graphics driver interface +// +//============================================================================= + +#ifndef __AGS_EE_GFX__GRAPHICSDRIVER_H +#define __AGS_EE_GFX__GRAPHICSDRIVER_H + +#include +#include "gfx/gfxdefines.h" +#include "gfx/gfxmodelist.h" +#include "util/geometry.h" + +namespace AGS +{ + +namespace Common +{ + class Bitmap; + typedef std::shared_ptr PBitmap; +} + +namespace Engine +{ + +// Forward declaration +class IDriverDependantBitmap; +class IGfxFilter; +typedef std::shared_ptr PGfxFilter; +using Common::PBitmap; + +enum TintMethod +{ + TintReColourise = 0, + TintSpecifyMaximum = 1 +}; + +enum VideoSkipType +{ + VideoSkipNone = 0, + VideoSkipEscape = 1, + VideoSkipAnyKey = 2, + VideoSkipKeyOrMouse = 3 +}; + +// Sprite transformation +// TODO: combine with stretch parameters in the IDriverDependantBitmap? +struct SpriteTransform +{ + // Translate + int X, Y; + float ScaleX, ScaleY; + float Rotate; // angle, in radians + + SpriteTransform() + : X(0), Y(0), ScaleX(1.f), ScaleY(1.f), Rotate(0.f) {} + + SpriteTransform(int x, int y, float scalex = 1.0f, float scaley = 1.0f, float rotate = 0.0f) + : X(x), Y(y), ScaleX(scalex), ScaleY(scaley), Rotate(rotate) {} +}; + +typedef void (*GFXDRV_CLIENTCALLBACK)(); +typedef bool (*GFXDRV_CLIENTCALLBACKXY)(int x, int y); +typedef void (*GFXDRV_CLIENTCALLBACKINITGFX)(void *data); +// Called if the rendering surface was resized by the external code (library). +// Mainly for Android and iOS ports; they are currently written in such way that +// the actual rendering surface size is redefined after IGraphicsDriver initialization. +typedef void (*GFXDRV_CLIENTCALLBACKSURFACEUPDATE)(); + +class IGraphicsDriver +{ +public: + virtual const char*GetDriverName() = 0; + virtual const char*GetDriverID() = 0; + virtual void SetTintMethod(TintMethod method) = 0; + // Initialize given display mode + virtual bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) = 0; + // Gets if a graphics mode was initialized + virtual bool IsModeSet() const = 0; + // Set the size of the native image size + virtual bool SetNativeSize(const Size &src_size) = 0; + virtual bool IsNativeSizeValid() const = 0; + // Set game render frame and translation + virtual bool SetRenderFrame(const Rect &dst_rect) = 0; + virtual bool IsRenderFrameValid() const = 0; + // Report which color depth options are best suited for the given native color depth + virtual int GetDisplayDepthForNativeDepth(int native_color_depth) const = 0; + virtual IGfxModeList *GetSupportedModeList(int color_depth) = 0; + virtual bool IsModeSupported(const DisplayMode &mode) = 0; + virtual DisplayMode GetDisplayMode() const = 0; + virtual PGfxFilter GetGraphicsFilter() const = 0; + virtual Size GetNativeSize() const = 0; + virtual Rect GetRenderDestination() const = 0; + virtual void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) = 0; + // TODO: get rid of draw screen callback at some point when all fade functions are more or less grouped in one + virtual void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) = 0; + virtual void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) = 0; + virtual void SetCallbackOnSurfaceUpdate(GFXDRV_CLIENTCALLBACKSURFACEUPDATE) = 0; + // The NullSprite callback is called in the main render loop when a + // null sprite is encountered. You can use this to hook into the rendering + // process. + virtual void SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback) = 0; + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + virtual void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) = 0; + // Gets closest recommended bitmap format (currently - only color depth) for the given original format. + // Engine needs to have game bitmaps brought to the certain range of formats, easing conversion into the video bitmaps. + virtual int GetCompatibleBitmapFormat(int color_depth) = 0; + virtual IDriverDependantBitmap* CreateDDBFromBitmap(Common::Bitmap *bitmap, bool hasAlpha, bool opaque = false) = 0; + virtual void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Common::Bitmap *bitmap, bool hasAlpha) = 0; + virtual void DestroyDDB(IDriverDependantBitmap* bitmap) = 0; + + // Prepares next sprite batch, a list of sprites with defined viewport and optional + // global model transformation; all subsequent calls to DrawSprite will be adding + // sprites to this batch's list. + virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, + const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) = 0; + // Adds sprite to the active batch + virtual void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) = 0; + // Adds fade overlay fx to the active batch + virtual void SetScreenFade(int red, int green, int blue) = 0; + // Adds tint overlay fx to the active batch + // TODO: redesign this to allow various post-fx per sprite batch? + virtual void SetScreenTint(int red, int green, int blue) = 0; + // Clears all sprite batches, resets batch counter + virtual void ClearDrawLists() = 0; + virtual void RenderToBackBuffer() = 0; + virtual void Render() = 0; + // Renders with additional final offset and flip + // TODO: leftover from old code, solely for software renderer; remove when + // software mode either discarded or scene node graph properly implemented. + virtual void Render(int xoff, int yoff, GlobalFlipType flip) = 0; + // Copies contents of the game screen into bitmap using simple blit or pixel copy. + // Bitmap must be of supported size and pixel format. If it's not the method will + // fail and optionally write wanted destination format into 'want_fmt' pointer. + virtual bool GetCopyOfScreenIntoBitmap(Common::Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt = nullptr) = 0; + virtual void EnableVsyncBeforeRender(bool enabled) = 0; + virtual void Vsync() = 0; + // Enables or disables rendering mode that draws sprite list directly into + // the final resolution, as opposed to drawing to native-resolution buffer + // and scaling to final frame. The effect may be that sprites that are + // drawn with additional fractional scaling will appear more detailed than + // the rest of the game. The effect is stronger for the low-res games being + // rendered in the high-res mode. + virtual void RenderSpritesAtScreenResolution(bool enabled, int supersampling = 1) = 0; + // TODO: move fade-in/out/boxout functions out of the graphics driver!! make everything render through + // main drawing procedure. Since currently it does not - we need to init our own sprite batch + // internally to let it set up correct viewport settings instead of relying on a chance. + // Runs fade-out animation in a blocking manner. + virtual void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) = 0; + // Runs fade-in animation in a blocking manner. + virtual void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) = 0; + // Runs box-out animation in a blocking manner. + virtual void BoxOutEffect(bool blackingOut, int speed, int delay) = 0; + virtual bool PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) { return false; } + virtual void UseSmoothScaling(bool enabled) = 0; + virtual bool SupportsGammaControl() = 0; + virtual void SetGamma(int newGamma) = 0; + // Returns the virtual screen. Will return NULL if renderer does not support memory backbuffer. + // In normal case you should use GetStageBackBuffer() instead. + virtual Common::Bitmap* GetMemoryBackBuffer() = 0; + // Sets custom backbuffer bitmap to render to. + // Passing NULL pointer will tell renderer to switch back to its original virtual screen. + // Note that only software renderer supports this. + virtual void SetMemoryBackBuffer(Common::Bitmap *backBuffer) = 0; + // Returns memory backbuffer for the current rendering stage (or base virtual screen if called outside of render pass). + // All renderers should support this. + virtual Common::Bitmap* GetStageBackBuffer() = 0; + virtual bool RequiresFullRedrawEachFrame() = 0; + virtual bool HasAcceleratedTransform() = 0; + virtual bool UsesMemoryBackBuffer() = 0; + virtual ~IGraphicsDriver() = default; +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__GRAPHICSDRIVER_H diff --git a/engines/ags/engine/gfx/hq2x3x.h b/engines/ags/engine/gfx/hq2x3x.h new file mode 100644 index 000000000000..3560d1689104 --- /dev/null +++ b/engines/ags/engine/gfx/hq2x3x.h @@ -0,0 +1,30 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_HQ2X3X_H +#define __AC_HQ2X3X_H + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_ANDROID +void InitLUTs(){} +void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ){} +void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ){} +#else +void InitLUTs(); +void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); +void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); +#endif + +#endif // __AC_HQ2X3X_H \ No newline at end of file diff --git a/engines/ags/engine/gfx/ogl_headers.h b/engines/ags/engine/gfx/ogl_headers.h new file mode 100644 index 000000000000..5cf20136c5d2 --- /dev/null +++ b/engines/ags/engine/gfx/ogl_headers.h @@ -0,0 +1,78 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// OpenGL includes and definitions for various platforms +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS +#include +#include +#include + +#include "glad/glad.h" +#include "glad/glad_wgl.h" + +#elif AGS_PLATFORM_OS_LINUX +#include +#include +#include + +#include "glad/glad.h" +#include "glad/glad_glx.h" + +#elif AGS_PLATFORM_OS_ANDROID + +#include +#include + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +// TODO: we probably should not use GLExt since we use GLES2 +#include + +#define HDC void* +#define HGLRC void* +#define HWND void* +#define HINSTANCE void* + +#elif AGS_PLATFORM_OS_IOS + +#include +#include + +#ifndef GL_GLEXT_PROTOTYPES +#define GL_GLEXT_PROTOTYPES +#endif + +#include + +#define HDC void* +#define HGLRC void* +#define HWND void* +#define HINSTANCE void* + +#else + +#error "opengl: unsupported platform" + +#endif + +#ifndef GLAPI +#define GLAD_GL_VERSION_2_0 (0) +#endif diff --git a/engines/ags/engine/gui/animatingguibutton.cpp b/engines/ags/engine/gui/animatingguibutton.cpp new file mode 100644 index 000000000000..fb370df53b5d --- /dev/null +++ b/engines/ags/engine/gui/animatingguibutton.cpp @@ -0,0 +1,44 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gui/animatingguibutton.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +void AnimatingGUIButton::ReadFromFile(Stream *in) +{ + buttonid = in->ReadInt16(); + ongui = in->ReadInt16(); + onguibut = in->ReadInt16(); + view = in->ReadInt16(); + loop = in->ReadInt16(); + frame = in->ReadInt16(); + speed = in->ReadInt16(); + repeat = in->ReadInt16(); + wait = in->ReadInt16(); +} + +void AnimatingGUIButton::WriteToFile(Stream *out) +{ + out->WriteInt16(buttonid); + out->WriteInt16(ongui); + out->WriteInt16(onguibut); + out->WriteInt16(view); + out->WriteInt16(loop); + out->WriteInt16(frame); + out->WriteInt16(speed); + out->WriteInt16(repeat); + out->WriteInt16(wait); +} diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h new file mode 100644 index 000000000000..7cf5fc7b1c3d --- /dev/null +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_GUI__ANIMATINGGUIBUTTON_H +#define __AGS_EE_GUI__ANIMATINGGUIBUTTON_H + +#include "ac/runtime_defines.h" + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +struct AnimatingGUIButton { + // index into guibuts array, GUI, button + short buttonid, ongui, onguibut; + // current animation status + short view, loop, frame; + short speed, repeat, wait; + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); +}; + +#endif // __AGS_EE_GUI__ANIMATINGGUIBUTTON_H diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp new file mode 100644 index 000000000000..c190bf3257e0 --- /dev/null +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -0,0 +1,315 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "util/wgt2allg.h" +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/gamesetup.h" +#include "ac/gamestate.h" +#include "ac/gui.h" +#include "ac/keycode.h" +#include "ac/mouse.h" +#include "ac/sys_events.h" +#include "ac/runtime_defines.h" +#include "font/fonts.h" +#include "gui/cscidialog.h" +#include "gui/guidialog.h" +#include "gui/guimain.h" +#include "gui/mycontrols.h" +#include "main/game_run.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" +#include "media/audio/audio_system.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/timer.h" + +using AGS::Common::Bitmap; +namespace BitmapHelper = AGS::Common::BitmapHelper; + +extern char ignore_bounds; // from mousew32 +extern IGraphicsDriver *gfxDriver; +extern GameSetup usetup; + + +//----------------------------------------------------------------------------- +// DIALOG SYSTEM STUFF below + +int windowbackgroundcolor = COL254, pushbuttondarkcolor = COL255; +int pushbuttonlightcolor = COL253; +int topwindowhandle = -1; +int cbuttfont; + +int acdialog_font; + +int smcode = 0; + +#define MAXCONTROLS 20 +#define MAXSCREENWINDOWS 5 +NewControl *vobjs[MAXCONTROLS]; +OnScreenWindow oswi[MAXSCREENWINDOWS]; + +int controlid = 0; + + +//----------------------------------------------------------------------------- + +void __my_wbutt(Bitmap *ds, int x1, int y1, int x2, int y2) +{ + color_t draw_color = ds->GetCompatibleColor(COL254); //wsetcolor(15); + ds->FillRect(Rect(x1, y1, x2, y2), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(x1, y1, x2, y2), draw_color); +} + +//----------------------------------------------------------------------------- + +OnScreenWindow::OnScreenWindow() +{ + x = y = 0; + handle = -1; + oldtop = -1; +} + +int CSCIGetVersion() +{ + return 0x0100; +} + +int windowcount = 0, curswas = 0; +int win_x = 0, win_y = 0, win_width = 0, win_height = 0; +int CSCIDrawWindow(int xx, int yy, int wid, int hit) +{ + ignore_bounds++; + multiply_up(&xx, &yy, &wid, &hit); + int drawit = -1; + for (int aa = 0; aa < MAXSCREENWINDOWS; aa++) { + if (oswi[aa].handle < 0) { + drawit = aa; + break; + } + } + + if (drawit < 0) + quit("Too many windows created."); + + windowcount++; + // ags_domouse(DOMOUSE_DISABLE); + xx -= 2; + yy -= 2; + wid += 4; + hit += 4; + Bitmap *ds = prepare_gui_screen(xx, yy, wid, hit, true); + oswi[drawit].x = xx; + oswi[drawit].y = yy; + __my_wbutt(ds, 0, 0, wid - 1, hit - 1); // wbutt goes outside its area + // ags_domouse(DOMOUSE_ENABLE); + oswi[drawit].oldtop = topwindowhandle; + topwindowhandle = drawit; + oswi[drawit].handle = topwindowhandle; + win_x = xx; + win_y = yy; + win_width = wid; + win_height = hit; + return drawit; +} + +void CSCIEraseWindow(int handl) +{ + // ags_domouse(DOMOUSE_DISABLE); + ignore_bounds--; + topwindowhandle = oswi[handl].oldtop; + oswi[handl].handle = -1; + // ags_domouse(DOMOUSE_ENABLE); + windowcount--; + clear_gui_screen(); +} + +int CSCIWaitMessage(CSCIMessage * cscim) +{ + for (int uu = 0; uu < MAXCONTROLS; uu++) { + if (vobjs[uu] != nullptr) { + // ags_domouse(DOMOUSE_DISABLE); + vobjs[uu]->drawifneeded(); + // ags_domouse(DOMOUSE_ENABLE); + } + } + + prepare_gui_screen(win_x, win_y, win_width, win_height, true); + + while (1) { + update_audio_system_on_game_loop(); + refresh_gui_screen(); + + cscim->id = -1; + cscim->code = 0; + smcode = 0; + int keywas; + if (run_service_key_controls(keywas) && !play.IsIgnoringInput()) { + if (keywas == 13) { + cscim->id = finddefaultcontrol(CNF_DEFAULT); + cscim->code = CM_COMMAND; + } else if (keywas == 27) { + cscim->id = finddefaultcontrol(CNF_CANCEL); + cscim->code = CM_COMMAND; + } else if ((keywas < 32) && (keywas != 8)) ; + else if ((keywas >= 372) & (keywas <= 381) & (finddefaultcontrol(CNT_LISTBOX) >= 0)) + vobjs[finddefaultcontrol(CNT_LISTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0); + else if (finddefaultcontrol(CNT_TEXTBOX) >= 0) + vobjs[finddefaultcontrol(CNT_TEXTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0); + + if (cscim->id < 0) { + cscim->code = CM_KEYPRESS; + cscim->wParam = keywas; + } + } + + int mbut, mwheelz; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !play.IsIgnoringInput()) { + if (checkcontrols()) { + cscim->id = controlid; + cscim->code = CM_COMMAND; + } + } + + if (smcode) { + cscim->code = smcode; + cscim->id = controlid; + } + + if (cscim->code > 0) + break; + + WaitForNextFrame(); + } + + return 0; +} + +int CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title) +{ + multiply_up(&xx, &yy, &wii, &hii); + int usec = -1; + for (int hh = 1; hh < MAXCONTROLS; hh++) { + if (vobjs[hh] == nullptr) { + usec = hh; + break; + } + } + + if (usec < 0) + quit("Too many controls created"); + + int type = typeandflags & 0x00ff; // 256 control types + if (type == CNT_PUSHBUTTON) { + if (wii == -1) + wii = wgettextwidth(title, cbuttfont) + 20; + + vobjs[usec] = new MyPushButton(xx, yy, wii, hii, title); + + } else if (type == CNT_LISTBOX) { + vobjs[usec] = new MyListBox(xx, yy, wii, hii); + } else if (type == CNT_LABEL) { + vobjs[usec] = new MyLabel(xx, yy, wii, title); + } else if (type == CNT_TEXTBOX) { + vobjs[usec] = new MyTextBox(xx, yy, wii, title); + } else + quit("Unknown control type requested"); + + vobjs[usec]->typeandflags = typeandflags; + vobjs[usec]->wlevel = topwindowhandle; + // ags_domouse(DOMOUSE_DISABLE); + vobjs[usec]->draw( get_gui_screen() ); + // ags_domouse(DOMOUSE_ENABLE); + return usec; +} + +void CSCIDeleteControl(int haa) +{ + delete vobjs[haa]; + vobjs[haa] = nullptr; +} + +int CSCISendControlMessage(int haa, int mess, int wPar, long lPar) +{ + if (vobjs[haa] == nullptr) + return -1; + return vobjs[haa]->processmessage(mess, wPar, lPar); +} + +void multiply_up_to_game_res(int *x, int *y) +{ + x[0] = get_fixed_pixel_size(x[0]); + y[0] = get_fixed_pixel_size(y[0]); +} + +// TODO: this is silly, make a uniform formula +void multiply_up(int *x1, int *y1, int *x2, int *y2) +{ + multiply_up_to_game_res(x1, y1); + multiply_up_to_game_res(x2, y2); + + // adjust for 800x600 + if ((GetBaseWidth() == 400) || (GetBaseWidth() == 800)) { + x1[0] = (x1[0] * 5) / 4; + x2[0] = (x2[0] * 5) / 4; + y1[0] = (y1[0] * 3) / 2; + y2[0] = (y2[0] * 3) / 2; + } + else if (GetBaseWidth() == 1024) + { + x1[0] = (x1[0] * 16) / 10; + x2[0] = (x2[0] * 16) / 10; + y1[0] = (y1[0] * 384) / 200; + y2[0] = (y2[0] * 384) / 200; + } +} + +int checkcontrols() +{ + // NOTE: this is because old code was working with full game screen + const int mousex = ::mousex - win_x; + const int mousey = ::mousey - win_y; + + smcode = 0; + for (int kk = 0; kk < MAXCONTROLS; kk++) { + if (vobjs[kk] != nullptr) { + if (vobjs[kk]->mouseisinarea(mousex, mousey)) { + controlid = kk; + return vobjs[kk]->pressedon(mousex, mousey); + } + } + } + return 0; +} + +int finddefaultcontrol(int flagmask) +{ + for (int ff = 0; ff < MAXCONTROLS; ff++) { + if (vobjs[ff] == nullptr) + continue; + + if (vobjs[ff]->wlevel != topwindowhandle) + continue; + + if (vobjs[ff]->typeandflags & flagmask) + return ff; + } + + return -1; +} + +int GetBaseWidth () { + return play.GetUIViewport().GetWidth(); +} diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h new file mode 100644 index 000000000000..17fbcb6bab40 --- /dev/null +++ b/engines/ags/engine/gui/cscidialog.h @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Legacy built-in GUI dialogs and controls. +// +//============================================================================= +#ifndef __AGS_EE_GUI__CSCIDIALOG_H +#define __AGS_EE_GUI__CSCIDIALOG_H + +#include "gui/guidialoginternaldefs.h" + +int CSCIGetVersion(); +int CSCIDrawWindow(int xx, int yy, int wid, int hit); +void CSCIEraseWindow(int handl); +int CSCIWaitMessage(CSCIMessage * cscim); +int CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title); +void CSCIDeleteControl(int haa); +int CSCISendControlMessage(int haa, int mess, int wPar, long lPar); +void multiply_up_to_game_res(int *x, int *y); +void multiply_up(int *x1, int *y1, int *x2, int *y2); +int checkcontrols(); +int finddefaultcontrol(int flagmask); +int GetBaseWidth (); + +#endif // __AGS_EE_GUI__CSCIDIALOG_H diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp new file mode 100644 index 000000000000..3cd5aad16cee --- /dev/null +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -0,0 +1,170 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Implementation from acgui.h and acgui.cpp specific to Engine runtime +// +//============================================================================= + +// Headers, as they are in acgui.cpp +#pragma unmanaged +#include "ac/game_version.h" +#include "ac/system.h" +#include "font/fonts.h" +#include "gui/guimain.h" +#include "gui/guibutton.h" +#include "gui/guilabel.h" +#include "gui/guilistbox.h" +#include "gui/guitextbox.h" +#include +#include "ac/gamesetupstruct.h" +#include "ac/global_translation.h" +#include "ac/string.h" +#include "ac/spritecache.h" +#include "gfx/bitmap.h" +#include "gfx/blender.h" + +using namespace AGS::Common; + +// For engine these are defined in ac.cpp +extern int eip_guiobj; +extern void replace_macro_tokens(const char*, String&); + +// For engine these are defined in acfonts.cpp +extern void ensure_text_valid_for_font(char *, int); +// + +extern SpriteCache spriteset; // in ac_runningame +extern GameSetupStruct game; + +bool GUIMain::HasAlphaChannel() const +{ + if (this->BgImage > 0) + { + // alpha state depends on background image + return is_sprite_alpha(this->BgImage); + } + if (this->BgColor > 0) + { + // not alpha transparent if there is a background color + return false; + } + // transparent background, enable alpha blending + return game.GetColorDepth() >= 24 && + // transparent background have alpha channel only since 3.2.0; + // "classic" gui rendering mode historically had non-alpha transparent backgrounds + // (3.2.0 broke the compatibility, now we restore it) + loaded_game_file_version >= kGameVersion_320 && game.options[OPT_NEWGUIALPHA] != kGuiAlphaRender_Legacy; +} + +//============================================================================= +// Engine-specific implementation split out of acgui.h +//============================================================================= + +void check_font(int *fontnum) +{ + // do nothing +} + +//============================================================================= +// Engine-specific implementation split out of acgui.cpp +//============================================================================= + +int get_adjusted_spritewidth(int spr) +{ + return spriteset[spr]->GetWidth(); +} + +int get_adjusted_spriteheight(int spr) +{ + return spriteset[spr]->GetHeight(); +} + +bool is_sprite_alpha(int spr) +{ + return ((game.SpriteInfos[spr].Flags & SPF_ALPHACHANNEL) != 0); +} + +void set_eip_guiobj(int eip) +{ + eip_guiobj = eip; +} + +int get_eip_guiobj() +{ + return eip_guiobj; +} + +bool outlineGuiObjects = false; + +namespace AGS +{ +namespace Common +{ + +bool GUIObject::IsClickable() const +{ + return (Flags & kGUICtrl_Clickable) != 0; +} + +void GUILabel::PrepareTextToDraw() +{ + replace_macro_tokens(Flags & kGUICtrl_Translated ? String(get_translation(Text)) : Text, _textToDraw); +} + +size_t GUILabel::SplitLinesForDrawing(SplitLines &lines) +{ + // Use the engine's word wrap tool, to have hebrew-style writing and other features + return break_up_text_into_lines(_textToDraw, lines, Width, Font); +} + +void GUITextBox::DrawTextBoxContents(Bitmap *ds, color_t text_color) +{ + wouttext_outline(ds, X + 1 + get_fixed_pixel_size(1), Y + 1 + get_fixed_pixel_size(1), Font, text_color, Text); + if (IsGUIEnabled(this)) + { + // draw a cursor + int draw_at_x = wgettextwidth(Text, Font) + X + 3; + int draw_at_y = Y + 1 + getfontheight(Font); + ds->DrawRect(Rect(draw_at_x, draw_at_y, draw_at_x + get_fixed_pixel_size(5), draw_at_y + (get_fixed_pixel_size(1) - 1)), text_color); + } +} + +void GUIListBox::DrawItemsFix() +{ + // do nothing +} + +void GUIListBox::DrawItemsUnfix() +{ + // do nothing +} + +void GUIListBox::PrepareTextToDraw(const String &text) +{ + if (Flags & kGUICtrl_Translated) + _textToDraw = get_translation(text); + else + _textToDraw = text; +} + +void GUIButton::PrepareTextToDraw() +{ + if (Flags & kGUICtrl_Translated) + _textToDraw = get_translation(_text); + else + _textToDraw = _text; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp new file mode 100644 index 000000000000..7baa314387b7 --- /dev/null +++ b/engines/ags/engine/gui/guidialog.cpp @@ -0,0 +1,533 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "gui/guidialog.h" + +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "gui/cscidialog.h" +#include //isdigit() +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" +#include "debug/debug_log.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern IGraphicsDriver *gfxDriver; +extern GameSetup usetup; +extern GameSetupStruct game; + +namespace { + +// TODO: store drawing surface inside old gui classes instead +int windowPosX, windowPosY, windowPosWidth, windowPosHeight; +Bitmap *windowBuffer; +IDriverDependantBitmap *dialogDDB; + +#undef MAXSAVEGAMES +#define MAXSAVEGAMES 20 +DisplayProperties dispp; +char *lpTemp, *lpTemp2; +char bufTemp[260], buffer2[260]; +int numsaves = 0, toomanygames; +int filenumbers[MAXSAVEGAMES]; +unsigned long filedates[MAXSAVEGAMES]; + +CSCIMessage smes; + +char buff[200]; +int myscrnwid = 320, myscrnhit = 200; + +} + +char *get_gui_dialog_buffer() +{ + return buffer2; +} + +// +// TODO: rewrite the whole thing to work inside the main game update and render loop! +// + +Bitmap *prepare_gui_screen(int x, int y, int width, int height, bool opaque) +{ + windowPosX = x; + windowPosY = y; + windowPosWidth = width; + windowPosHeight = height; + if (windowBuffer) + { + windowBuffer = recycle_bitmap(windowBuffer, windowBuffer->GetColorDepth(), windowPosWidth, windowPosHeight, !opaque); + } + else + { + windowBuffer = BitmapHelper::CreateBitmap(windowPosWidth, windowPosHeight, game.GetColorDepth()); + windowBuffer = ReplaceBitmapWithSupportedFormat(windowBuffer); + } + dialogDDB = recycle_ddb_bitmap(dialogDDB, windowBuffer, false, opaque); + return windowBuffer; +} + +Bitmap *get_gui_screen() +{ + return windowBuffer; +} + +void clear_gui_screen() +{ + if (dialogDDB) + gfxDriver->DestroyDDB(dialogDDB); + dialogDDB = nullptr; + delete windowBuffer; + windowBuffer = nullptr; +} + +void refresh_gui_screen() +{ + gfxDriver->UpdateDDBFromBitmap(dialogDDB, windowBuffer, false); + render_graphics(dialogDDB, windowPosX, windowPosY); +} + +int loadgamedialog() +{ + const int wnd_width = 200; + const int wnd_height = 120; + const int boxleft = myscrnwid / 2 - wnd_width / 2; + const int boxtop = myscrnhit / 2 - wnd_height / 2; + const int buttonhit = usetup.textheight + 5; + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrlok = + CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, get_global_message(MSG_RESTORE)); + int ctrlcancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, + get_global_message(MSG_CANCEL)); + int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 30, 120, 80, nullptr); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, 5, 120, 0, get_global_message(MSG_SELECTLOAD)); + CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); + + preparesavegamelist(ctrllist); + CSCIMessage mes; + lpTemp = nullptr; + int toret = -1; + while (1) { + CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); + if (mes.code == CM_COMMAND) { + if (mes.id == ctrlok) { + int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + if ((cursel >= numsaves) | (cursel < 0)) + lpTemp = nullptr; + else { + toret = filenumbers[cursel]; + String path = get_save_game_path(toret); + strcpy(bufTemp, path); + lpTemp = &bufTemp[0]; + } + } else if (mes.id == ctrlcancel) { + lpTemp = nullptr; + } + + break; + } + } + + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrllist); + CSCIDeleteControl(ctrlok); + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + return toret; +} + +int savegamedialog() +{ + char okbuttontext[50]; + strcpy(okbuttontext, get_global_message(MSG_SAVEBUTTON)); + char labeltext[200]; + strcpy(labeltext, get_global_message(MSG_SAVEDIALOG)); + const int wnd_width = 200; + const int wnd_height = 120; + const int boxleft = myscrnwid / 2 - wnd_width / 2; + const int boxtop = myscrnhit / 2 - wnd_height / 2; + const int buttonhit = usetup.textheight + 5; + int labeltop = 5; + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrlcancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, + get_global_message(MSG_CANCEL)); + int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 120, 80, nullptr); + int ctrltbox = 0; + + CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box + preparesavegamelist(ctrllist); + if (toomanygames) { + strcpy(okbuttontext, get_global_message(MSG_REPLACE)); + strcpy(labeltext, get_global_message(MSG_MUSTREPLACE)); + labeltop = 2; + } else + ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); + + int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, okbuttontext); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, labeltop, 120, 0, labeltext); + CSCIMessage mes; + + lpTemp = nullptr; + if (numsaves > 0) + CSCISendControlMessage(ctrllist, CLB_GETTEXT, 0, (long)&buffer2[0]); + else + buffer2[0] = 0; + + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + + int toret = -1; + while (1) { + CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); + if (mes.code == CM_COMMAND) { + if (mes.id == ctrlok) { + int cursell = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + + if (numsaves > 0) + CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursell, (long)&bufTemp[0]); + else + strcpy(bufTemp, "_NOSAVEGAMENAME"); + + if (toomanygames) { + int nwhand = CSCIDrawWindow(boxleft + 5, boxtop + 20, 190, 65); + int lbl1 = + CSCICreateControl(CNT_LABEL, 15, 5, 160, 0, get_global_message(MSG_REPLACEWITH1)); + int lbl2 = CSCICreateControl(CNT_LABEL, 25, 14, 160, 0, bufTemp); + int lbl3 = + CSCICreateControl(CNT_LABEL, 15, 25, 160, 0, get_global_message(MSG_REPLACEWITH2)); + int txt1 = CSCICreateControl(CNT_TEXTBOX, 15, 35, 160, 0, bufTemp); + int btnOk = + CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 25, 50, 60, 10, + get_global_message(MSG_REPLACE)); + int btnCancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 95, 50, 60, 10, + get_global_message(MSG_CANCEL)); + + CSCIMessage cmes; + do { + CSCIWaitMessage(&cmes); + } while (cmes.code != CM_COMMAND); + + CSCISendControlMessage(txt1, CTB_GETTEXT, 0, (long)&buffer2[0]); + CSCIDeleteControl(btnCancel); + CSCIDeleteControl(btnOk); + CSCIDeleteControl(txt1); + CSCIDeleteControl(lbl3); + CSCIDeleteControl(lbl2); + CSCIDeleteControl(lbl1); + CSCIEraseWindow(nwhand); + bufTemp[0] = 0; + + if (cmes.id == btnCancel) { + lpTemp = nullptr; + break; + } else + toret = filenumbers[cursell]; + + } + else if (strcmp(buffer2, bufTemp) != 0) { // create a new game (description different) + int highestnum = 0; + for (int pp = 0; pp < numsaves; pp++) { + if (filenumbers[pp] > highestnum) + highestnum = filenumbers[pp]; + } + + if (highestnum > 90) + quit("Save game directory overflow"); + + toret = highestnum + 1; + String path = get_save_game_path(toret); + strcpy(bufTemp, path); + } + else { + toret = filenumbers[cursell]; + bufTemp[0] = 0; + } + + if (bufTemp[0] == 0) + { + String path = get_save_game_path(toret); + strcpy(bufTemp, path); + } + + lpTemp = &bufTemp[0]; + lpTemp2 = &buffer2[0]; + } else if (mes.id == ctrlcancel) { + lpTemp = nullptr; + } + break; + } else if (mes.code == CM_SELCHANGE) { + int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + if (cursel >= 0) { + CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursel, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + } + } + } + + CSCIDeleteControl(ctrltbox); + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrllist); + CSCIDeleteControl(ctrlok); + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + return toret; +} + +void preparesavegamelist(int ctrllist) +{ + numsaves = 0; + toomanygames = 0; + al_ffblk ffb; + int bufix = 0; + + String svg_dir = get_save_game_directory(); + String svg_suff = get_save_game_suffix(); + String searchPath = String::FromFormat("%s""agssave.*%s", svg_dir.GetCStr(), svg_suff.GetCStr()); + + int don = al_findfirst(searchPath, &ffb, -1); + while (!don) { + bufix = 0; + if (numsaves >= MAXSAVEGAMES) { + toomanygames = 1; + break; + } + + // only list games .000 to .099 (to allow higher slots for other purposes) + if (strstr(ffb.name, ".0") == nullptr) { + don = al_findnext(&ffb); + continue; + } + + const char *numberExtension = strstr(ffb.name, ".0") + 1; + int sgNumber = atoi(numberExtension); + + String thisGamePath = get_save_game_path(sgNumber); + + // get description + String description; + read_savedgame_description(thisGamePath, description); + + CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)description.GetCStr()); + // Select the first item + CSCISendControlMessage(ctrllist, CLB_SETCURSEL, 0, 0); + filenumbers[numsaves] = sgNumber; + filedates[numsaves] = (long int)ffb.time; + numsaves++; + don = al_findnext(&ffb); + } + + al_findclose(&ffb); + if (numsaves >= MAXSAVEGAMES) + toomanygames = 1; + + for (int nn = 0; nn < numsaves - 1; nn++) { + for (int kk = 0; kk < numsaves - 1; kk++) { // Date order the games + if (filedates[kk] < filedates[kk + 1]) { // swap them round + CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk, (long)&buff[0]); + CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk + 1, (long)&buffer2[0]); + CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk + 1, (long)&buff[0]); + CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk, (long)&buffer2[0]); + int numtem = filenumbers[kk]; + filenumbers[kk] = filenumbers[kk + 1]; + filenumbers[kk + 1] = numtem; + long numted = filedates[kk]; + filedates[kk] = filedates[kk + 1]; + filedates[kk + 1] = numted; + } + } + } +} + +void enterstringwindow(const char *prompttext, char *stouse) +{ + const int wnd_width = 200; + const int wnd_height = 40; + const int boxleft = 60, boxtop = 80; + int wantCancel = 0; + if (prompttext[0] == '!') { + wantCancel = 1; + prompttext++; + } + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, "OK"); + int ctrlcancel = -1; + if (wantCancel) + ctrlcancel = CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 20, 60, 10, get_global_message(MSG_CANCEL)); + int ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, 5, 120, 0, prompttext); + CSCIMessage mes; + + while (1) { + CSCIWaitMessage(&mes); + if (mes.code == CM_COMMAND) { + if (mes.id == ctrlcancel) + buffer2[0] = 0; + else + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + break; + } + } + + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrltbox); + CSCIDeleteControl(ctrlok); + if (wantCancel) + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + strcpy(stouse, buffer2); +} + +int enternumberwindow(char *prompttext) +{ + char ourbuf[200]; + enterstringwindow(prompttext, ourbuf); + if (ourbuf[0] == 0) + return -9999; + return atoi(ourbuf); +} + +int roomSelectorWindow(int currentRoom, int numRooms, int*roomNumbers, char**roomNames) +{ + char labeltext[200]; + strcpy(labeltext, get_global_message(MSG_SAVEDIALOG)); + const int wnd_width = 240; + const int wnd_height = 160; + const int boxleft = myscrnwid / 2 - wnd_width / 2; + const int boxtop = myscrnhit / 2 - wnd_height / 2; + const int labeltop = 5; + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 220, 100, nullptr); + int ctrlcancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 80, 145, 60, 10, "Cancel"); + + CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box + for (int aa = 0; aa < numRooms; aa++) + { + sprintf(buff, "%3d %s", roomNumbers[aa], roomNames[aa]); + CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)&buff[0]); + if (roomNumbers[aa] == currentRoom) + { + CSCISendControlMessage(ctrllist, CLB_SETCURSEL, aa, 0); + } + } + + int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 10, 145, 60, 10, "OK"); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, labeltop, 180, 0, "Choose which room to go to:"); + CSCIMessage mes; + + lpTemp = nullptr; + buffer2[0] = 0; + + int ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + + int toret = -1; + while (1) { + CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); + if (mes.code == CM_COMMAND) + { + if (mes.id == ctrlok) + { + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + if (isdigit(buffer2[0])) + { + toret = atoi(buffer2); + } + } + else if (mes.id == ctrlcancel) + { + } + break; + } + else if (mes.code == CM_SELCHANGE) + { + int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + if (cursel >= 0) + { + sprintf(buffer2, "%d", roomNumbers[cursel]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + } + } + } + + CSCIDeleteControl(ctrltbox); + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrllist); + CSCIDeleteControl(ctrlok); + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + return toret; +} + +int myscimessagebox(const char *lpprompt, char *btn1, char *btn2) +{ + const int wnd_width = 240 - 80; + const int wnd_height = 120 - 80; + const int boxleft = 80; + const int boxtop = 80; + + int windl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int lbl1 = CSCICreateControl(CNT_LABEL, 10, 5, 150, 0, lpprompt); + int btflag = CNT_PUSHBUTTON; + + if (btn2 == nullptr) + btflag |= CNF_DEFAULT | CNF_CANCEL; + else + btflag |= CNF_DEFAULT; + + int btnQuit = CSCICreateControl(btflag, 10, 25, 60, 10, btn1); + int btnPlay = 0; + + if (btn2 != nullptr) + btnPlay = CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 85, 25, 60, 10, btn2); + + smes.code = 0; + + do { + CSCIWaitMessage(&smes); + } while (smes.code != CM_COMMAND); + + if (btnPlay) + CSCIDeleteControl(btnPlay); + + CSCIDeleteControl(btnQuit); + CSCIDeleteControl(lbl1); + CSCIEraseWindow(windl); + + if (smes.id == btnQuit) + return 1; + + return 0; +} + +int quitdialog() +{ + char quitbut[50], playbut[50]; + strcpy(quitbut, get_global_message(MSG_QUITBUTTON)); + strcpy(playbut, get_global_message(MSG_PLAYBUTTON)); + return myscimessagebox(get_global_message(MSG_QUITDIALOG), quitbut, playbut); +} diff --git a/engines/ags/engine/gui/guidialog.h b/engines/ags/engine/gui/guidialog.h new file mode 100644 index 000000000000..752edde64d56 --- /dev/null +++ b/engines/ags/engine/gui/guidialog.h @@ -0,0 +1,44 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_GUI__GUIDIALOG_H +#define __AGS_EE_GUI__GUIDIALOG_H + +namespace AGS { namespace Common { class Bitmap; } } + +// Functions for handling hard-coded GUIs +// Prepares GUI bitmaps which will be passed to the renderer's draw chain +AGS::Common::Bitmap *prepare_gui_screen(int x, int y, int width, int height, bool opaque); +AGS::Common::Bitmap *get_gui_screen(); +// Deletes GUI bitmaps +void clear_gui_screen(); +// Draws virtual screen contents on the GUI bitmaps and assignes them to +// the renderer's draw chain +void refresh_gui_screen(); +int loadgamedialog(); +int savegamedialog(); +void preparesavegamelist(int ctrllist); +void enterstringwindow(const char *prompttext, char *stouse); +int enternumberwindow(char *prompttext); +int roomSelectorWindow(int currentRoom, int numRooms, int*roomNumbers, char**roomNames); +int myscimessagebox(const char *lpprompt, char *btn1, char *btn2); +int quitdialog(); + +// last string value in gui dialog. +char *get_gui_dialog_buffer(); + +#endif // __AGS_EE_GUI__GUIDIALOG_H diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h new file mode 100644 index 000000000000..548c32ff1f7e --- /dev/null +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -0,0 +1,111 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_GUI__GUIDIALOGDEFINES_H +#define __AGS_EE_GUI__GUIDIALOGDEFINES_H + +#define MSG_RESTORE 984 +#define MSG_CANCEL 985 // "Cancel" +#define MSG_SELECTLOAD 986 // "Select game to restore" +#define MSG_SAVEBUTTON 987 // "Save" +#define MSG_SAVEDIALOG 988 // "Save game name:" +#define MSG_REPLACE 989 // "Replace" +#define MSG_MUSTREPLACE 990 // "The folder is full. you must replace" +#define MSG_REPLACEWITH1 991 // "Replace:" +#define MSG_REPLACEWITH2 992 // "With:" +#define MSG_QUITBUTTON 993 // "Quit" +#define MSG_PLAYBUTTON 994 // "Play" +#define MSG_QUITDIALOG 995 // "Do you want to quit?" + +#include "ac/gamesetup.h" + +/*#define COL251 26 +#define COL252 28 +#define COL253 29 +#define COL254 27 +#define COL255 24*/ +#define COL253 15 +#define COL254 7 +#define COL255 8 + +// ========= DEFINES ======== +// Control types +#define CNT_PUSHBUTTON 0x001 +#define CNT_LISTBOX 0x002 +#define CNT_LABEL 0x003 +#define CNT_TEXTBOX 0x004 +// Control properties +#define CNF_DEFAULT 0x100 +#define CNF_CANCEL 0x200 + +// Dialog messages +#define CM_COMMAND 1 +#define CM_KEYPRESS 2 +#define CM_SELCHANGE 3 +// System messages +#define SM_SAVEGAME 100 +#define SM_LOADGAME 101 +#define SM_QUIT 102 +// System messages (to ADVEN) +#define SM_SETTRANSFERMEM 120 +#define SM_GETINIVALUE 121 +// System messages (to driver) +#define SM_QUERYQUIT 110 +#define SM_KEYPRESS 111 +#define SM_TIMER 112 +// ListBox messages +#define CLB_ADDITEM 1 +#define CLB_CLEAR 2 +#define CLB_GETCURSEL 3 +#define CLB_GETTEXT 4 +#define CLB_SETTEXT 5 +#define CLB_SETCURSEL 6 +// TextBox messages +#define CTB_GETTEXT 1 +#define CTB_SETTEXT 2 + +#define CTB_KEYPRESS 91 + +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; // FIXME later + +// ========= STRUCTS ======== +struct DisplayProperties +{ + int width; + int height; + int colors; + int textheight; +}; + +struct CSCIMessage +{ + int code; + int id; + int wParam; +}; + +struct OnScreenWindow +{ + int x, y; + int handle; + int oldtop; + + OnScreenWindow(); +}; + +#endif // __AGS_EE_GUI__GUIDIALOGDEFINES_H \ No newline at end of file diff --git a/engines/ags/engine/gui/guidialoginternaldefs.h b/engines/ags/engine/gui/guidialoginternaldefs.h new file mode 100644 index 000000000000..53755d139a11 --- /dev/null +++ b/engines/ags/engine/gui/guidialoginternaldefs.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H +#define __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H + +#include "gui/guidialogdefines.h" + +#define _export +#ifdef WINAPI +#undef WINAPI +#endif +#define WINAPI +extern int ags_misbuttondown (int but); +#define mbutrelease(X) (!ags_misbuttondown(X)) +#define TEXT_HT usetup.textheight + +#endif // __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H diff --git a/engines/ags/engine/gui/mycontrols.h b/engines/ags/engine/gui/mycontrols.h new file mode 100644 index 000000000000..89383e5c4b3d --- /dev/null +++ b/engines/ags/engine/gui/mycontrols.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Legacy built-in GUI dialogs and controls. +// +//============================================================================= +#ifndef __AGS_EE_GUI__MYCONTROLS_H +#define __AGS_EE_GUI__MYCONTROLS_H + +#include "gui/mylabel.h" +#include "gui/mylistbox.h" +#include "gui/mypushbutton.h" +#include "gui/mytextbox.h" + +#endif // __AGS_EE_GUI__MYCONTROLS_H diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp new file mode 100644 index 000000000000..1ce06d8f7521 --- /dev/null +++ b/engines/ags/engine/gui/mylabel.cpp @@ -0,0 +1,62 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/display.h" +#include "ac/gamesetup.h" +#include "ac/string.h" +#include "font/fonts.h" +#include "gui/guidefines.h" +#include "gui/mylabel.h" +#include "gui/guidialoginternaldefs.h" + +using namespace Common; + +extern GameSetup usetup; + +extern int acdialog_font; + +MyLabel::MyLabel(int xx, int yy, int wii, const char *tee) +{ + strncpy(text, tee, 150); + text[149] = 0; + x = xx; + y = yy; + wid = wii; + hit = TEXT_HT; +} + +void MyLabel::draw(Bitmap *ds) +{ + int cyp = y; + char *teptr = &text[0]; + color_t text_color = ds->GetCompatibleColor(0); + + if (break_up_text_into_lines(teptr, Lines, wid, acdialog_font) == 0) + return; + for (size_t ee = 0; ee < Lines.Count(); ee++) { + wouttext_outline(ds, x, cyp, acdialog_font, text_color, Lines[ee]); + cyp += TEXT_HT; + } +} + +int MyLabel::pressedon(int mousex, int mousey) +{ + return 0; +} + +int MyLabel::processmessage(int mcode, int wParam, long lParam) +{ + return -1; // doesn't support messages +} diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h new file mode 100644 index 000000000000..c700790fa0e0 --- /dev/null +++ b/engines/ags/engine/gui/mylabel.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYLABEL_H +#define __AC_MYLABEL_H + +#include "gui/newcontrol.h" + +struct MyLabel:public NewControl +{ + char text[150]; + MyLabel(int xx, int yy, int wii, const char *tee); + + void draw(Common::Bitmap *ds) override; + + int pressedon(int mousex, int mousey) override; + + int processmessage(int mcode, int wParam, long lParam) override; +}; + +#endif // __AC_MYLABEL_H \ No newline at end of file diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp new file mode 100644 index 000000000000..66bba59d663b --- /dev/null +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -0,0 +1,198 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "util/wgt2allg.h" +#include "ac/common.h" +#include "ac/gamesetup.h" +#include "font/fonts.h" +#include "gfx/bitmap.h" +#include "gui/guidialog.h" +#include "gui/guidialoginternaldefs.h" +#include "gui/mylistbox.h" + +using AGS::Common::Bitmap; + +extern GameSetup usetup; +extern int numcurso, hotx, hoty; + +extern int windowbackgroundcolor; +extern int cbuttfont; +extern int smcode; + + MyListBox::MyListBox(int xx, int yy, int wii, int hii) + { + x = xx; + y = yy; + wid = wii; + hit = hii; + hit -= (hit - 4) % TEXT_HT; // resize to multiple of text height + numonscreen = (hit - 4) / TEXT_HT; + items = 0; + topitem = 0; + selected = -1; + memset(itemnames, 0, sizeof(itemnames)); + } + + void MyListBox::clearlist() + { + for (int kk = 0; kk < items; kk++) + free(itemnames[kk]); + + items = 0; + } + + MyListBox::~MyListBox() { + clearlist(); + } + + void MyListBox::draw(Bitmap *ds) + { + color_t draw_color = ds->GetCompatibleColor(windowbackgroundcolor); + ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); + + int widwas = wid; + wid -= ARROWWIDTH; + ds->DrawLine(Line(x + wid, y, x + wid, y + hit), draw_color); // draw the up/down arrows + ds->DrawLine(Line(x + wid, y + hit / 2, x + widwas, y + hit / 2), draw_color); + + int xmidd = x + wid + (widwas - wid) / 2; + if (topitem < 1) + draw_color = ds->GetCompatibleColor(7); + + ds->DrawLine(Line(xmidd, y + 2, xmidd, y + 10), draw_color); // up arrow + ds->DrawLine(Line(xmidd - 1, y + 3, xmidd + 1, y + 3), draw_color); + ds->DrawLine(Line(xmidd - 2, y + 4, xmidd + 2, y + 4), draw_color); + draw_color = ds->GetCompatibleColor(0); + if (topitem + numonscreen >= items) + draw_color = ds->GetCompatibleColor(7); + + ds->DrawLine(Line(xmidd, y + hit - 10, xmidd, y + hit - 3), draw_color); // down arrow + ds->DrawLine(Line(xmidd - 1, y + hit - 4, xmidd + 1, y + hit - 4), draw_color); + ds->DrawLine(Line(xmidd - 2, y + hit - 5, xmidd + 2, y + hit - 5), draw_color); + draw_color = ds->GetCompatibleColor(0); + + for (int tt = 0; tt < numonscreen; tt++) { + int inum = tt + topitem; + if (inum >= items) + break; + + int thisypos = y + 2 + tt * TEXT_HT; + color_t text_color; + if (inum == selected) { + draw_color = ds->GetCompatibleColor(0); + ds->FillRect(Rect(x, thisypos, x + wid, thisypos + TEXT_HT - 1), draw_color); + text_color = ds->GetCompatibleColor(7); + } + else text_color = ds->GetCompatibleColor(0); + + wouttextxy(ds, x + 2, thisypos, cbuttfont, text_color, itemnames[inum]); + } + wid = widwas; + } + + int MyListBox::pressedon(int mousex, int mousey) + { + if (mousex > x + wid - ARROWWIDTH) { + if ((mousey - y < hit / 2) & (topitem > 0)) + topitem--; + else if ((mousey - y > hit / 2) & (topitem + numonscreen < items)) + topitem++; + + } else { + selected = ((mousey - y) - 2) / TEXT_HT + topitem; + if (selected >= items) + selected = items - 1; + + } + +// ags_domouse(DOMOUSE_DISABLE); + draw(get_gui_screen()); + // ags_domouse(DOMOUSE_ENABLE); + smcode = CM_SELCHANGE; + return 0; + } + + void MyListBox::additem(char *texx) + { + if (items >= MAXLISTITEM) + quit("!CSCIUSER16: Too many items added to listbox"); + itemnames[items] = (char *)malloc(strlen(texx) + 1); + strcpy(itemnames[items], texx); + items++; + needredraw = 1; + } + + int MyListBox::processmessage(int mcode, int wParam, long lParam) + { + if (mcode == CLB_ADDITEM) { + additem((char *)lParam); + } else if (mcode == CLB_CLEAR) + clearlist(); + else if (mcode == CLB_GETCURSEL) + return selected; + else if (mcode == CLB_SETCURSEL) + { + selected = wParam; + + if ((selected < topitem) && (selected >= 0)) + topitem = selected; + + if (topitem + numonscreen <= selected) + topitem = (selected + 1) - numonscreen; + } + else if (mcode == CLB_GETTEXT) + strcpy((char *)lParam, itemnames[wParam]); + else if (mcode == CLB_SETTEXT) { + if (wParam < items) + free(itemnames[wParam]); + + char *newstri = (char *)lParam; + itemnames[wParam] = (char *)malloc(strlen(newstri) + 2); + strcpy(itemnames[wParam], newstri); + + } else if (mcode == CTB_KEYPRESS) { + if ((wParam == 380) && (selected < items - 1)) + selected++; + + if ((wParam == 372) && (selected > 0)) + selected--; + + if (wParam == 373) + selected -= (numonscreen - 1); + + if (wParam == 381) + selected += (numonscreen - 1); + + if ((selected < 0) && (items > 0)) + selected = 0; + + if (selected >= items) + selected = items - 1; + + if ((selected < topitem) & (selected >= 0)) + topitem = selected; + + if (topitem + numonscreen <= selected) + topitem = (selected + 1) - numonscreen; + + drawandmouse(); + smcode = CM_SELCHANGE; + } else + return -1; + + return 0; + } diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h new file mode 100644 index 000000000000..4ce657bcab6f --- /dev/null +++ b/engines/ags/engine/gui/mylistbox.h @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYLISTBOX_H +#define __AC_MYLISTBOX_H + +#include "gui/newcontrol.h" + +#define MAXLISTITEM 300 +#define ARROWWIDTH 8 + +struct MyListBox:public NewControl +{ + int items, topitem, numonscreen, selected; + char *itemnames[MAXLISTITEM]; + MyListBox(int xx, int yy, int wii, int hii); + void clearlist(); + ~MyListBox() override; + + void draw(Common::Bitmap *ds) override; + int pressedon(int mousex, int mousey) override; + void additem(char *texx); + int processmessage(int mcode, int wParam, long lParam) override; +}; + +#endif // __AC_MYLISTBOX_H \ No newline at end of file diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp new file mode 100644 index 000000000000..449c6ac8a8bd --- /dev/null +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -0,0 +1,106 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "util/wgt2allg.h" +#include "ac/common.h" +#include "ac/mouse.h" +#include "font/fonts.h" +#include "gui/mypushbutton.h" +#include "gui/guidialog.h" +#include "gui/guidialoginternaldefs.h" +#include "main/game_run.h" +#include "gfx/bitmap.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/timer.h" + +using AGS::Common::Bitmap; + +extern int windowbackgroundcolor, pushbuttondarkcolor; +extern int pushbuttonlightcolor; +extern int cbuttfont; + +MyPushButton::MyPushButton(int xx, int yy, int wi, int hi, const char *tex) +{ //wlevel=2; + x = xx; + y = yy; + wid = wi; + hit = hi + 1; //hit=hi; + state = 0; + strncpy(text, tex, 50); + text[49] = 0; +}; + +void MyPushButton::draw(Bitmap *ds) +{ + color_t text_color = ds->GetCompatibleColor(0); + color_t draw_color = ds->GetCompatibleColor(COL254); + ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); + if (state == 0) + draw_color = ds->GetCompatibleColor(pushbuttondarkcolor); + else + draw_color = ds->GetCompatibleColor(pushbuttonlightcolor); + + ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); + if (state == 0) + draw_color = ds->GetCompatibleColor(pushbuttonlightcolor); + else + draw_color = ds->GetCompatibleColor(pushbuttondarkcolor); + + ds->DrawLine(Line(x, y, x + wid - 1, y), draw_color); + ds->DrawLine(Line(x, y, x, y + hit - 1), draw_color); + wouttextxy(ds, x + (wid / 2 - wgettextwidth(text, cbuttfont) / 2), y + 2, cbuttfont, text_color, text); + if (typeandflags & CNF_DEFAULT) + draw_color = ds->GetCompatibleColor(0); + else + draw_color = ds->GetCompatibleColor(windowbackgroundcolor); + + ds->DrawRect(Rect(x - 1, y - 1, x + wid + 1, y + hit + 1), draw_color); +} + +//extern const int LEFT; // in mousew32 + +int MyPushButton::pressedon(int mousex, int mousey) +{ + int wasstat; + while (mbutrelease(LEFT) == 0) { + + wasstat = state; + state = mouseisinarea(mousex, mousey); + // stop mp3 skipping if button held down + update_polled_stuff_if_runtime(); + if (wasstat != state) { + // ags_domouse(DOMOUSE_DISABLE); + draw(get_gui_screen()); + //ags_domouse(DOMOUSE_ENABLE); + } + + // ags_domouse(DOMOUSE_UPDATE); + + refresh_gui_screen(); + + WaitForNextFrame(); + } + wasstat = state; + state = 0; + // ags_domouse(DOMOUSE_DISABLE); + draw(get_gui_screen()); + // ags_domouse(DOMOUSE_ENABLE); + return wasstat; +} + +int MyPushButton::processmessage(int mcode, int wParam, long lParam) +{ + return -1; // doesn't support messages +} \ No newline at end of file diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h new file mode 100644 index 000000000000..14bca4de80e1 --- /dev/null +++ b/engines/ags/engine/gui/mypushbutton.h @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_PUSHBUTTON_H +#define __AC_PUSHBUTTON_H + +#include "gui/newcontrol.h" + +struct MyPushButton:public NewControl +{ + char text[50]; + MyPushButton(int xx, int yy, int wi, int hi, const char *tex); + void draw(Common::Bitmap *ds) override; + int pressedon(int mousex, int mousey) override; + int processmessage(int mcode, int wParam, long lParam) override; +}; + +#endif // __AC_PUSHBUTTON_H \ No newline at end of file diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp new file mode 100644 index 000000000000..e6a5ee30b46b --- /dev/null +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -0,0 +1,88 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "util/wgt2allg.h" +#include "font/fonts.h" +#include "gui/mytextbox.h" +#include "gui/guidialoginternaldefs.h" +#include "gfx/bitmap.h" + +using AGS::Common::Bitmap; + +extern GameSetup usetup; + +extern int windowbackgroundcolor; +extern int cbuttfont; + +MyTextBox::MyTextBox(int xx, int yy, int wii, const char *tee) +{ + x = xx; + y = yy; + wid = wii; + if (tee != nullptr) + strcpy(text, tee); + else + text[0] = 0; + + hit = TEXT_HT + 1; +} + +void MyTextBox::draw(Bitmap *ds) +{ + color_t draw_color = ds->GetCompatibleColor(windowbackgroundcolor); + ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); + color_t text_color = ds->GetCompatibleColor(0); + wouttextxy(ds, x + 2, y + 1, cbuttfont, text_color, text); + + char tbu[2] = "_"; + wouttextxy(ds, x + 2 + wgettextwidth(text, cbuttfont), y + 1, cbuttfont, text_color, tbu); +} + +int MyTextBox::pressedon(int mousex, int mousey) +{ + return 0; +} + +int MyTextBox::processmessage(int mcode, int wParam, long lParam) +{ + if (mcode == CTB_SETTEXT) { + strcpy(text, (char *)lParam); + needredraw = 1; + } else if (mcode == CTB_GETTEXT) + strcpy((char *)lParam, text); + else if (mcode == CTB_KEYPRESS) { + if (wParam == 8) { + if (text[0] != 0) + text[strlen(text) - 1] = 0; + + drawandmouse(); + } else if (strlen(text) >= TEXTBOX_MAXLEN - 1) + ; + else if (wgettextwidth(text, cbuttfont) >= wid - 5) + ; + else if (wParam > 127) + ; // font only has 128 chars + else { + text[strlen(text) + 1] = 0; + text[strlen(text)] = wParam; + drawandmouse(); + } + } else + return -1; + + return 0; +} diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h new file mode 100644 index 000000000000..264c2bcc32f5 --- /dev/null +++ b/engines/ags/engine/gui/mytextbox.h @@ -0,0 +1,30 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYTEXTBOX_H +#define __AC_MYTEXTBOX_H + +#include "gui/newcontrol.h" + +#define TEXTBOX_MAXLEN 49 +struct MyTextBox:public NewControl +{ + char text[TEXTBOX_MAXLEN + 1]; + MyTextBox(int xx, int yy, int wii, const char *tee); + void draw(Common::Bitmap *ds) override; + int pressedon(int mousex, int mousey) override; + int processmessage(int mcode, int wParam, long lParam) override; +}; + +#endif // __AC_MYTEXTBOX_H \ No newline at end of file diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp new file mode 100644 index 000000000000..29e683aa9653 --- /dev/null +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -0,0 +1,67 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gui/newcontrol.h" +#include "gui/guidialog.h" +#include "gui/guidialoginternaldefs.h" + +extern int topwindowhandle; + +NewControl::NewControl(int xx, int yy, int wi, int hi) +{ + x = xx; + y = yy; + wid = wi; + hit = hi; + state = 0; + typeandflags = 0; + wlevel = 0; + visible = 1; + enabled = 1; + needredraw = 1; +}; +NewControl::NewControl() { + x = y = wid = hit = 0; + state = 0; + typeandflags = 0; + wlevel = 0; + visible = 1; + enabled = 1; + needredraw = 1; +} +int NewControl::mouseisinarea(int mousex, int mousey) +{ + if (topwindowhandle != wlevel) + return 0; + + if ((mousex > x) & (mousex < x + wid) & (mousey > y) & (mousey < y + hit)) + return 1; + + return 0; +} +void NewControl::drawifneeded() +{ + if (topwindowhandle != wlevel) + return; + if (needredraw) { + needredraw = 0; + draw(get_gui_screen()); + } +} +void NewControl::drawandmouse() +{ + // ags_domouse(DOMOUSE_DISABLE); + draw(get_gui_screen()); + // ags_domouse(DOMOUSE_ENABLE); +} diff --git a/engines/ags/engine/gui/newcontrol.h b/engines/ags/engine/gui/newcontrol.h new file mode 100644 index 000000000000..e308bff881aa --- /dev/null +++ b/engines/ags/engine/gui/newcontrol.h @@ -0,0 +1,42 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_GUI__NEWCONTROL_H +#define __AGS_EE_GUI__NEWCONTROL_H + +#include "gfx/bitmap.h" + +using namespace AGS; // FIXME later + +struct NewControl +{ + int x, y, wid, hit, state, typeandflags, wlevel; + char visible, enabled; // not implemented + char needredraw; + virtual void draw(Common::Bitmap *ds) = 0; + virtual int pressedon(int mousex, int mousey) = 0; + virtual int processmessage(int, int, long) = 0; + + NewControl(int xx, int yy, int wi, int hi); + NewControl(); + virtual ~NewControl() = default; + int mouseisinarea(int mousex, int mousey); + void drawifneeded(); + void drawandmouse(); +}; + +#endif // __AGS_EE_GUI__NEWCONTROL_H \ No newline at end of file diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp new file mode 100644 index 000000000000..558d67ca9237 --- /dev/null +++ b/engines/ags/engine/main/config.cpp @@ -0,0 +1,672 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Game configuration +// +#include // toupper + +#include "core/platform.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_translation.h" +#include "ac/path_helper.h" +#include "ac/spritecache.h" +#include "ac/system.h" +#include "debug/debugger.h" +#include "debug/debug_log.h" +#include "main/mainheader.h" +#include "main/config.h" +#include "platform/base/agsplatformdriver.h" +#include "util/directory.h" +#include "util/ini_util.h" +#include "util/textstreamreader.h" +#include "util/path.h" +#include "util/string_utils.h" +#include "media/audio/audio_system.h" + + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameSetup usetup; +extern SpriteCache spriteset; +extern int force_window; +extern GameState play; + +// Filename of the default config file, the one found in the game installation +const String DefaultConfigFileName = "acsetup.cfg"; + +// Replace the filename part of complete path WASGV with INIFIL +// TODO: get rid of this and use proper lib path function instead +void INIgetdirec(char *wasgv, const char *inifil) { + int u = strlen(wasgv) - 1; + + for (u = strlen(wasgv) - 1; u >= 0; u--) { + if ((wasgv[u] == '\\') || (wasgv[u] == '/')) { + memcpy(&wasgv[u + 1], inifil, strlen(inifil) + 1); + break; + } + } + + if (u <= 0) { + // no slashes - either the path is just "f:acwin.exe" + if (strchr(wasgv, ':') != nullptr) + memcpy(strchr(wasgv, ':') + 1, inifil, strlen(inifil) + 1); + // or it's just "acwin.exe" (unlikely) + else + strcpy(wasgv, inifil); + } + +} + +bool INIreaditem(const ConfigTree &cfg, const String §n, const String &item, String &value) +{ + ConfigNode sec_it = cfg.find(sectn); + if (sec_it != cfg.end()) + { + StrStrOIter item_it = sec_it->second.find(item); + if (item_it != sec_it->second.end()) + { + value = item_it->second; + return true; + } + } + return false; +} + +int INIreadint(const ConfigTree &cfg, const String §n, const String &item, int def_value) +{ + String str; + if (!INIreaditem(cfg, sectn, item, str)) + return def_value; + + return atoi(str); +} + +float INIreadfloat(const ConfigTree &cfg, const String §n, const String &item, float def_value) +{ + String str; + if (!INIreaditem(cfg, sectn, item, str)) + return def_value; + + return atof(str); +} + +String INIreadstring(const ConfigTree &cfg, const String §n, const String &item, const String &def_value) +{ + String str; + if (!INIreaditem(cfg, sectn, item, str)) + return def_value; + return str; +} + +void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int value) +{ + cfg[sectn][item] = StrUtil::IntToString(value); +} + +void INIwritestring(ConfigTree &cfg, const String §n, const String &item, const String &value) +{ + cfg[sectn][item] = value; +} + +void parse_scaling_option(const String &scaling_option, FrameScaleDefinition &scale_def, int &scale_factor) +{ + const char *game_scale_options[kNumFrameScaleDef - 1] = { "max_round", "stretch", "proportional" }; + scale_def = kFrame_IntScale; + for (int i = 0; i < kNumFrameScaleDef - 1; ++i) + { + if (scaling_option.CompareNoCase(game_scale_options[i]) == 0) + { + scale_def = (FrameScaleDefinition)(i + 1); + break; + } + } + + if (scale_def == kFrame_IntScale) + scale_factor = StrUtil::StringToInt(scaling_option); + else + scale_factor = 0; +} + +void parse_scaling_option(const String &scaling_option, GameFrameSetup &frame_setup) +{ + parse_scaling_option(scaling_option, frame_setup.ScaleDef, frame_setup.ScaleFactor); +} + +// Parses legacy filter ID and converts it into current scaling options +bool parse_legacy_frame_config(const String &scaling_option, String &filter_id, GameFrameSetup &frame) +{ + struct + { + String LegacyName; + String CurrentName; + int Scaling; + } legacy_filters[6] = { {"none", "none", -1}, {"max", "StdScale", 0}, {"StdScale", "StdScale", -1}, + {"AAx", "Linear", -1}, {"Hq2x", "Hqx", 2}, {"Hq3x", "Hqx", 3} }; + + for (int i = 0; i < 6; i++) + { + if (scaling_option.CompareLeftNoCase(legacy_filters[i].LegacyName) == 0) + { + filter_id = legacy_filters[i].CurrentName; + frame.ScaleDef = legacy_filters[i].Scaling == 0 ? kFrame_MaxRound : kFrame_IntScale; + frame.ScaleFactor = legacy_filters[i].Scaling >= 0 ? legacy_filters[i].Scaling : + scaling_option.Mid(legacy_filters[i].LegacyName.GetLength()).ToInt(); + return true; + } + } + return false; +} + +String make_scaling_option(FrameScaleDefinition scale_def, int scale_factor) +{ + switch (scale_def) + { + case kFrame_MaxRound: + return "max_round"; + case kFrame_MaxStretch: + return "stretch"; + case kFrame_MaxProportional: + return "proportional"; + } + return String::FromFormat("%d", scale_factor); +} + +String make_scaling_option(const GameFrameSetup &frame_setup) +{ + return make_scaling_option(frame_setup.ScaleDef, frame_setup.ScaleFactor); +} + +uint32_t convert_scaling_to_fp(int scale_factor) +{ + if (scale_factor >= 0) + return scale_factor <<= kShift; + else + return kUnit / abs(scale_factor); +} + +int convert_fp_to_scaling(uint32_t scaling) +{ + if (scaling == 0) + return 0; + return scaling >= kUnit ? (scaling >> kShift) : -kUnit / (int32_t)scaling; +} + +AlIDStr AlIDToChars(int al_id) +{ + if (al_id == 0) + return AlIDStr {{ 'N', 'O', 'N', 'E', '\0' }}; + else if (al_id == -1) + return AlIDStr {{ 'A', 'U', 'T', 'O', '\0' }}; + else + return AlIDStr {{ + static_cast((al_id >> 24) & 0xFF), + static_cast((al_id >> 16) & 0xFF), + static_cast((al_id >> 8) & 0xFF), + static_cast((al_id) & 0xFF), + '\0' + }}; +} + +AlIDStr AlIDToChars(const String &s) +{ + AlIDStr id_str; + size_t i = 0; + for (; i < s.GetLength(); ++i) + id_str.s[i] = toupper(s[i]); + for (; i < 4; ++i) + id_str.s[i] = ' '; + id_str.s[4] = 0; + return id_str; +} + +int StringToAlID(const char *cstr) +{ + return (int)(AL_ID(cstr[0u], cstr[1u], cstr[2u], cstr[3u])); +} + +// Parses a config string which may hold plain driver's ID or 4-char ID packed +// as a 32-bit integer. +int parse_driverid(const String &id) +{ + int asint; + if (StrUtil::StringToInt(id, asint, 0) == StrUtil::kNoError) + return asint; + if (id.GetLength() > 4) + return -1; // autodetect + if (id.CompareNoCase("AUTO") == 0) + return -1; // autodetect + if (id.CompareNoCase("NONE") == 0) + return 0; // no driver + return StringToAlID(AlIDToChars(id).s); +} + +// Reads driver ID from config, where it may be represented as string or number +int read_driverid(const ConfigTree &cfg, const String §n, const String &item, int def_value) +{ + String s = INIreadstring(cfg, sectn, item); + if (s.IsEmpty()) + return def_value; + return parse_driverid(s); +} + +void write_driverid(ConfigTree &cfg, const String §n, const String &item, int value) +{ + INIwritestring(cfg, sectn, item, AlIDToChars(value).s); +} + +void graphics_mode_get_defaults(bool windowed, ScreenSizeSetup &scsz_setup, GameFrameSetup &frame_setup) +{ + scsz_setup.Size = Size(); + if (windowed) + { + // For the windowed we define mode by the scaled game. + scsz_setup.SizeDef = kScreenDef_ByGameScaling; + scsz_setup.MatchDeviceRatio = false; + frame_setup = usetup.Screen.WinGameFrame; + } + else + { + // For the fullscreen we set current desktop resolution, which + // corresponds to most comfortable fullscreen mode for the driver. + scsz_setup.SizeDef = kScreenDef_MaxDisplay; + scsz_setup.MatchDeviceRatio = true; + frame_setup = usetup.Screen.FsGameFrame; + } +} + +String find_default_cfg_file(const char *alt_cfg_file) +{ + // Try current directory for config first; else try exe dir + String filename = String::FromFormat("%s/%s", Directory::GetCurrentDirectory().GetCStr(), DefaultConfigFileName.GetCStr()); + if (!Common::File::TestReadFile(filename)) + { + char conffilebuf[512]; + strcpy(conffilebuf, alt_cfg_file); + fix_filename_case(conffilebuf); + fix_filename_slashes(conffilebuf); + INIgetdirec(conffilebuf, DefaultConfigFileName); + filename = conffilebuf; + } + return filename; +} + +String find_user_global_cfg_file() +{ + String parent_dir = PathOrCurDir(platform->GetUserGlobalConfigDirectory()); + return String::FromFormat("%s/%s", parent_dir.GetCStr(), DefaultConfigFileName.GetCStr()); +} + +String find_user_cfg_file() +{ + String parent_dir = MakeSpecialSubDir(PathOrCurDir(platform->GetUserConfigDirectory())); + return String::FromFormat("%s/%s", parent_dir.GetCStr(), DefaultConfigFileName.GetCStr()); +} + +void config_defaults() +{ +#if AGS_PLATFORM_OS_WINDOWS + usetup.Screen.DriverID = "D3D9"; +#else + usetup.Screen.DriverID = "OGL"; +#endif +#if AGS_PLATFORM_OS_WINDOWS + usetup.digicard = DIGI_DIRECTAMX(0); +#endif + usetup.midicard = MIDI_AUTODETECT; + usetup.translation = ""; +} + +void read_game_data_location(const ConfigTree &cfg) +{ + usetup.data_files_dir = INIreadstring(cfg, "misc", "datadir", usetup.data_files_dir); + if (!usetup.data_files_dir.IsEmpty()) + { + // strip any trailing slash + // TODO: move this to Path namespace later + AGS::Common::Path::FixupPath(usetup.data_files_dir); +#if AGS_PLATFORM_OS_WINDOWS + // if the path is just x:\ don't strip the slash + if (!(usetup.data_files_dir.GetLength() == 3 && usetup.data_files_dir[1u] == ':')) + { + usetup.data_files_dir.TrimRight('/'); + } +#else + usetup.data_files_dir.TrimRight('/'); +#endif + } + usetup.main_data_filename = INIreadstring(cfg, "misc", "datafile", usetup.main_data_filename); +} + +void read_legacy_audio_config(const ConfigTree &cfg) +{ +#if AGS_PLATFORM_OS_WINDOWS + int idx = INIreadint(cfg, "sound", "digiwinindx", -1); + if (idx == 0) + idx = DIGI_DIRECTAMX(0); + else if (idx == 1) + idx = DIGI_WAVOUTID(0); + else if (idx == 2) + idx = DIGI_NONE; + else if (idx == 3) + idx = DIGI_DIRECTX(0); + else + idx = DIGI_AUTODETECT; + usetup.digicard = idx; + + idx = INIreadint(cfg, "sound", "midiwinindx", -1); + if (idx == 1) + idx = MIDI_NONE; + else if (idx == 2) + idx = MIDI_WIN32MAPPER; + else + idx = MIDI_AUTODETECT; + usetup.midicard = idx; +#endif +} + +void read_legacy_graphics_config(const ConfigTree &cfg) +{ + usetup.Screen.DisplayMode.Windowed = INIreadint(cfg, "misc", "windowed") > 0; + usetup.Screen.DriverID = INIreadstring(cfg, "misc", "gfxdriver", usetup.Screen.DriverID); + + { + String legacy_filter = INIreadstring(cfg, "misc", "gfxfilter"); + if (!legacy_filter.IsEmpty()) + { + // NOTE: legacy scaling config is applied only to windowed setting + if (usetup.Screen.DisplayMode.Windowed) + usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_ByGameScaling; + parse_legacy_frame_config(legacy_filter, usetup.Screen.Filter.ID, usetup.Screen.WinGameFrame); + + // AGS 3.2.1 and 3.3.0 aspect ratio preferences + if (!usetup.Screen.DisplayMode.Windowed) + { + usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = + (INIreadint(cfg, "misc", "sideborders") > 0 || INIreadint(cfg, "misc", "forceletterbox") > 0 || + INIreadint(cfg, "misc", "prefer_sideborders") > 0 || INIreadint(cfg, "misc", "prefer_letterbox") > 0); + } + } + + // AGS 3.4.0 - 3.4.1-rc uniform scaling option + String uniform_frame_scale = INIreadstring(cfg, "graphics", "game_scale"); + if (!uniform_frame_scale.IsEmpty()) + { + GameFrameSetup frame_setup; + parse_scaling_option(uniform_frame_scale, frame_setup); + usetup.Screen.FsGameFrame = frame_setup; + usetup.Screen.WinGameFrame = frame_setup; + } + } + + usetup.Screen.DisplayMode.RefreshRate = INIreadint(cfg, "misc", "refresh"); +} + +// Variables used for mobile port configs +extern int psp_gfx_renderer; +extern int psp_gfx_scaling; +extern int psp_gfx_super_sampling; +extern int psp_gfx_smoothing; +extern int psp_gfx_smooth_sprites; +extern int psp_audio_enabled; +extern int psp_midi_enabled; +extern char psp_translation[]; + +void override_config_ext(ConfigTree &cfg) +{ + // Mobile ports always run in fullscreen mode +#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS + INIwriteint(cfg, "graphics", "windowed", 0); +#endif + + // psp_gfx_renderer - rendering mode + // * 0 - software renderer + // * 1 - hardware, render to screen + // * 2 - hardware, render to texture + if (psp_gfx_renderer == 0) + { + INIwritestring(cfg, "graphics", "driver", "Software"); + INIwriteint(cfg, "graphics", "render_at_screenres", 1); + } + else + { + INIwritestring(cfg, "graphics", "driver", "OGL"); + INIwriteint(cfg, "graphics", "render_at_screenres", psp_gfx_renderer == 1); + } + + // psp_gfx_scaling - scaling style: + // * 0 - no scaling + // * 1 - stretch and preserve aspect ratio + // * 2 - stretch to whole screen + if (psp_gfx_scaling == 0) + INIwritestring(cfg, "graphics", "game_scale_fs", "1"); + else if (psp_gfx_scaling == 1) + INIwritestring(cfg, "graphics", "game_scale_fs", "proportional"); + else + INIwritestring(cfg, "graphics", "game_scale_fs", "stretch"); + + // psp_gfx_smoothing - scaling filter: + // * 0 - nearest-neighbour + // * 1 - linear + if (psp_gfx_smoothing == 0) + INIwritestring(cfg, "graphics", "filter", "StdScale"); + else + INIwritestring(cfg, "graphics", "filter", "Linear"); + + // psp_gfx_super_sampling - enable super sampling + // * 0 - x1 + // * 1 - x2 + if (psp_gfx_renderer == 2) + INIwriteint(cfg, "graphics", "supersampling", psp_gfx_super_sampling + 1); + else + INIwriteint(cfg, "graphics", "supersampling", 0); + + INIwriteint(cfg, "misc", "antialias", psp_gfx_smooth_sprites != 0); + INIwritestring(cfg, "language", "translation", psp_translation); +} + +void apply_config(const ConfigTree &cfg) +{ + { + // Legacy settings has to be translated into new options; + // they must be read first, to let newer options override them, if ones are present + read_legacy_audio_config(cfg); + if (psp_audio_enabled) + { + usetup.digicard = read_driverid(cfg, "sound", "digiid", usetup.digicard); + if (psp_midi_enabled) + usetup.midicard = read_driverid(cfg, "sound", "midiid", usetup.midicard); + else + usetup.midicard = MIDI_NONE; + } + else + { + usetup.digicard = DIGI_NONE; + usetup.midicard = MIDI_NONE; + } + + psp_audio_multithreaded = INIreadint(cfg, "sound", "threaded", psp_audio_multithreaded); + + // Legacy graphics settings has to be translated into new options; + // they must be read first, to let newer options override them, if ones are present + read_legacy_graphics_config(cfg); + + // Graphics mode + usetup.Screen.DriverID = INIreadstring(cfg, "graphics", "driver", usetup.Screen.DriverID); + + usetup.Screen.DisplayMode.Windowed = INIreadint(cfg, "graphics", "windowed") > 0; + const char *screen_sz_def_options[kNumScreenDef] = { "explicit", "scaling", "max" }; + usetup.Screen.DisplayMode.ScreenSize.SizeDef = usetup.Screen.DisplayMode.Windowed ? kScreenDef_ByGameScaling : kScreenDef_MaxDisplay; + String screen_sz_def_str = INIreadstring(cfg, "graphics", "screen_def"); + for (int i = 0; i < kNumScreenDef; ++i) + { + if (screen_sz_def_str.CompareNoCase(screen_sz_def_options[i]) == 0) + { + usetup.Screen.DisplayMode.ScreenSize.SizeDef = (ScreenSizeDefinition)i; + break; + } + } + + usetup.Screen.DisplayMode.ScreenSize.Size = Size(INIreadint(cfg, "graphics", "screen_width"), + INIreadint(cfg, "graphics", "screen_height")); + usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = INIreadint(cfg, "graphics", "match_device_ratio", 1) != 0; + // TODO: move to config overrides (replace values during config load) +#if AGS_PLATFORM_OS_MACOS + usetup.Screen.Filter.ID = "none"; +#else + usetup.Screen.Filter.ID = INIreadstring(cfg, "graphics", "filter", "StdScale"); + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_fs", "proportional"), usetup.Screen.FsGameFrame); + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_win", "max_round"), usetup.Screen.WinGameFrame); +#endif + + usetup.Screen.DisplayMode.RefreshRate = INIreadint(cfg, "graphics", "refresh"); + usetup.Screen.DisplayMode.VSync = INIreadint(cfg, "graphics", "vsync") > 0; + usetup.RenderAtScreenRes = INIreadint(cfg, "graphics", "render_at_screenres") > 0; + usetup.Supersampling = INIreadint(cfg, "graphics", "supersampling", 1); + + usetup.enable_antialiasing = INIreadint(cfg, "misc", "antialias") > 0; + + // This option is backwards (usevox is 0 if no_speech_pack) + usetup.no_speech_pack = INIreadint(cfg, "sound", "usespeech", 1) == 0; + + usetup.user_data_dir = INIreadstring(cfg, "misc", "user_data_dir"); + usetup.shared_data_dir = INIreadstring(cfg, "misc", "shared_data_dir"); + + usetup.translation = INIreadstring(cfg, "language", "translation"); + + int cache_size_kb = INIreadint(cfg, "misc", "cachemax", DEFAULTCACHESIZE_KB); + if (cache_size_kb > 0) + spriteset.SetMaxCacheSize((size_t)cache_size_kb * 1024); + + usetup.mouse_auto_lock = INIreadint(cfg, "mouse", "auto_lock") > 0; + + usetup.mouse_speed = INIreadfloat(cfg, "mouse", "speed", 1.f); + if (usetup.mouse_speed <= 0.f) + usetup.mouse_speed = 1.f; + const char *mouse_ctrl_options[kNumMouseCtrlOptions] = { "never", "fullscreen", "always" }; + String mouse_str = INIreadstring(cfg, "mouse", "control_when", "fullscreen"); + for (int i = 0; i < kNumMouseCtrlOptions; ++i) + { + if (mouse_str.CompareNoCase(mouse_ctrl_options[i]) == 0) + { + usetup.mouse_ctrl_when = (MouseControlWhen)i; + break; + } + } + usetup.mouse_ctrl_enabled = INIreadint(cfg, "mouse", "control_enabled", 1) > 0; + const char *mouse_speed_options[kNumMouseSpeedDefs] = { "absolute", "current_display" }; + mouse_str = INIreadstring(cfg, "mouse", "speed_def", "current_display"); + for (int i = 0; i < kNumMouseSpeedDefs; ++i) + { + if (mouse_str.CompareNoCase(mouse_speed_options[i]) == 0) + { + usetup.mouse_speed_def = (MouseSpeedDef)i; + break; + } + } + + usetup.override_multitasking = INIreadint(cfg, "override", "multitasking", -1); + String override_os = INIreadstring(cfg, "override", "os"); + usetup.override_script_os = -1; + if (override_os.CompareNoCase("dos") == 0) + { + usetup.override_script_os = eOS_DOS; + } + else if (override_os.CompareNoCase("win") == 0) + { + usetup.override_script_os = eOS_Win; + } + else if (override_os.CompareNoCase("linux") == 0) + { + usetup.override_script_os = eOS_Linux; + } + else if (override_os.CompareNoCase("mac") == 0) + { + usetup.override_script_os = eOS_Mac; + } + usetup.override_upscale = INIreadint(cfg, "override", "upscale") > 0; + } + + // Apply logging configuration + apply_debug_config(cfg); +} + +void post_config() +{ + if (usetup.Screen.DriverID.IsEmpty() || usetup.Screen.DriverID.CompareNoCase("DX5") == 0) + usetup.Screen.DriverID = "Software"; + + // FIXME: this correction is needed at the moment because graphics driver + // implementation requires some filter to be created anyway + usetup.Screen.Filter.UserRequest = usetup.Screen.Filter.ID; + if (usetup.Screen.Filter.ID.IsEmpty() || usetup.Screen.Filter.ID.CompareNoCase("none") == 0) + { + usetup.Screen.Filter.ID = "StdScale"; + } + + if (!usetup.Screen.FsGameFrame.IsValid()) + usetup.Screen.FsGameFrame = GameFrameSetup(kFrame_MaxProportional); + if (!usetup.Screen.WinGameFrame.IsValid()) + usetup.Screen.WinGameFrame = GameFrameSetup(kFrame_MaxRound); + + // TODO: helper functions to remove slash in paths (or distinct path type) + if (usetup.user_data_dir.GetLast() == '/' || usetup.user_data_dir.GetLast() == '\\') + usetup.user_data_dir.ClipRight(1); + if (usetup.shared_data_dir.GetLast() == '/' || usetup.shared_data_dir.GetLast() == '\\') + usetup.shared_data_dir.ClipRight(1); +} + +void save_config_file() +{ + ConfigTree cfg; + + // Last display mode + // TODO: force_window check is a temporary workaround (see comment below) + if (force_window == 0) + { + bool is_windowed = System_GetWindowed() != 0; + cfg["graphics"]["windowed"] = String::FromFormat("%d", is_windowed ? 1 : 0); + // TODO: this is a hack, necessary because the original config system was designed when + // switching mode at runtime was not considered a possibility. + // Normally, two changes need to be done here: + // * the display setup needs to be reviewed and simplified a bit. + // * perhaps there should be two saved setups for fullscreen and windowed saved in memory + // (like ActiveDisplaySetting is saved currently), to know how the window size is defined + // in each modes (by explicit width/height values or from game scaling). + // This specifically *must* be done if there will be script API for modifying fullscreen + // resolution, or size of the window could be changed any way at runtime. + if (is_windowed != usetup.Screen.DisplayMode.Windowed) + { + if (is_windowed) + cfg["graphics"]["screen_def"] = "scaling"; + else + cfg["graphics"]["screen_def"] = "max"; + } + } + + // Other game options that could be changed at runtime + if (game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_UserDefined) + cfg["graphics"]["render_at_screenres"] = String::FromFormat("%d", usetup.RenderAtScreenRes ? 1 : 0); + cfg["mouse"]["control_enabled"] = String::FromFormat("%d", usetup.mouse_ctrl_enabled ? 1 : 0); + cfg["mouse"]["speed"] = String::FromFormat("%f", Mouse::GetSpeed()); + cfg["language"]["translation"] = usetup.translation; + + String cfg_file = find_user_cfg_file(); + if (!cfg_file.IsEmpty()) + IniUtil::Merge(cfg_file, cfg); +} diff --git a/engines/ags/engine/main/config.h b/engines/ags/engine/main/config.h new file mode 100644 index 000000000000..5398a148b215 --- /dev/null +++ b/engines/ags/engine/main/config.h @@ -0,0 +1,76 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__CONFIG_H +#define __AGS_EE_MAIN__CONFIG_H + +#include "main/graphics_mode.h" +#include "util/ini_util.h" + +using AGS::Common::String; +using AGS::Common::ConfigTree; + +// Set up default config settings +void config_defaults(); +// Find and default configuration file (usually located in the game installation directory) +String find_default_cfg_file(const char *alt_cfg_file); +// Find all-games user configuration file +String find_user_global_cfg_file(); +// Find and game-specific user configuration file (located into writable user directory) +String find_user_cfg_file(); +// Read optional data file name and location from config +void read_game_data_location(const AGS::Common::ConfigTree &cfg); +// Apply overriding values from the external config (e.g. for mobile ports) +void override_config_ext(ConfigTree &cfg); +// Setup game using final config tree +void apply_config(const ConfigTree &cfg); +// Fixup game setup parameters +void post_config(); + +void save_config_file(); + +void parse_scaling_option(const String &scaling_option, FrameScaleDefinition &scale_def, int &scale_factor); +void parse_scaling_option(const String &scaling_option, GameFrameSetup &frame_setup); +String make_scaling_option(FrameScaleDefinition scale_def, int scale_factor = 0); +String make_scaling_option(const GameFrameSetup &frame_setup); +uint32_t convert_scaling_to_fp(int scale_factor); +int convert_fp_to_scaling(uint32_t scaling); +// Fill in setup structs with default settings for the given mode (windowed or fullscreen) +void graphics_mode_get_defaults(bool windowed, ScreenSizeSetup &scsz_setup, GameFrameSetup &frame_setup); + +typedef struct { char s[5]; } AlIDStr; +// Converts Allegro driver ID type to 4-char string +AlIDStr AlIDToChars(int al_id); +AlIDStr AlIDToChars(const String &s); +// Converts C-string into Allegro's driver ID; string must be at least 4 character long +int StringToAlID(const char *cstr); +// Reads driver ID from config, where it may be represented as string or number +int read_driverid(const ConfigTree &cfg, const String §n, const String &item, int def_value); +// Writes driver ID to config +void write_driverid(ConfigTree &cfg, const String §n, const String &item, int value); + + +bool INIreaditem(const ConfigTree &cfg, const String §n, const String &item, String &value); +int INIreadint(const ConfigTree &cfg, const String §n, const String &item, int def_value = 0); +float INIreadfloat(const ConfigTree &cfg, const String §n, const String &item, float def_value = 0.f); +String INIreadstring(const ConfigTree &cfg, const String §n, const String &item, const String &def_value = ""); +void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int value); +void INIwritestring(ConfigTree &cfg, const String §n, const String &item, const String &value); +void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int value); + + +#endif // __AGS_EE_MAIN__CONFIG_H diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp new file mode 100644 index 000000000000..4532275d40bd --- /dev/null +++ b/engines/ags/engine/main/engine.cpp @@ -0,0 +1,1677 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Engine initialization +// + +#include "core/platform.h" + +#include +#if AGS_PLATFORM_OS_WINDOWS +#include // _spawnl +#endif + +#include "main/mainheader.h" +#include "ac/asset_helper.h" +#include "ac/common.h" +#include "ac/character.h" +#include "ac/characterextras.h" +#include "ac/characterinfo.h" +#include "ac/draw.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_character.h" +#include "ac/global_game.h" +#include "ac/gui.h" +#include "ac/lipsync.h" +#include "ac/objectcache.h" +#include "ac/path_helper.h" +#include "ac/sys_events.h" +#include "ac/roomstatus.h" +#include "ac/speech.h" +#include "ac/spritecache.h" +#include "ac/translation.h" +#include "ac/viewframe.h" +#include "ac/dynobj/scriptobject.h" +#include "ac/dynobj/scriptsystem.h" +#include "core/assetmanager.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "debug/out.h" +#include "font/agsfontrenderer.h" +#include "font/fonts.h" +#include "gfx/graphicsdriver.h" +#include "gfx/gfxdriverfactory.h" +#include "gfx/ddb.h" +#include "main/config.h" +#include "main/game_file.h" +#include "main/game_start.h" +#include "main/engine.h" +#include "main/engine_setup.h" +#include "main/graphics_mode.h" +#include "main/main.h" +#include "main/main_allegro.h" +#include "media/audio/audio_system.h" +#include "platform/util/pe.h" +#include "util/directory.h" +#include "util/error.h" +#include "util/misc.h" +#include "util/path.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern char check_dynamic_sprites_at_exit; +extern int our_eip; +extern volatile char want_exit, abort_engine; +extern bool justRunSetup; +extern GameSetup usetup; +extern GameSetupStruct game; +extern int proper_exit; +extern char pexbuf[STD_BUFFER_SIZE]; +extern SpriteCache spriteset; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; +extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; +extern ViewStruct*views; +extern int displayed_room; +extern int eip_guinum; +extern int eip_guiobj; +extern SpeechLipSyncLine *splipsync; +extern int numLipLines, curLipLine, curLipLinePhoneme; +extern ScriptSystem scsystem; +extern IGraphicsDriver *gfxDriver; +extern Bitmap **actsps; +extern color palette[256]; +extern CharacterExtras *charextra; +extern CharacterInfo*playerchar; +extern Bitmap **guibg; +extern IDriverDependantBitmap **guibgbmp; + +ResourcePaths ResPaths; + +t_engine_pre_init_callback engine_pre_init_callback = nullptr; + +#define ALLEGRO_KEYBOARD_HANDLER + +bool engine_init_allegro() +{ + Debug::Printf(kDbgMsg_Info, "Initializing allegro"); + + our_eip = -199; + // Initialize allegro + set_uformat(U_ASCII); + if (install_allegro(SYSTEM_AUTODETECT, &errno, atexit)) + { + const char *al_err = get_allegro_error(); + const char *user_hint = platform->GetAllegroFailUserHint(); + platform->DisplayAlert("Unable to initialize Allegro system driver.\n%s\n\n%s", + al_err[0] ? al_err : "Allegro library provided no further information on the problem.", + user_hint); + return false; + } + return true; +} + +void engine_setup_allegro() +{ + // Setup allegro using constructed config string + const char *al_config_data = "[mouse]\n" + "mouse_accel_factor = 0\n"; + override_config_data(al_config_data, ustrsize(al_config_data)); +} + +void winclosehook() { + want_exit = 1; + abort_engine = 1; + check_dynamic_sprites_at_exit = 0; +} + +void engine_setup_window() +{ + Debug::Printf(kDbgMsg_Info, "Setting up window"); + + our_eip = -198; + set_window_title("Adventure Game Studio"); + set_close_button_callback (winclosehook); + our_eip = -197; + + platform->SetGameWindowIcon(); +} + +// Starts up setup application, if capable. +// Returns TRUE if should continue running the game, otherwise FALSE. +bool engine_run_setup(const String &exe_path, ConfigTree &cfg, int &app_res) +{ + app_res = EXIT_NORMAL; +#if AGS_PLATFORM_OS_WINDOWS + { + String cfg_file = find_user_cfg_file(); + if (cfg_file.IsEmpty()) + { + app_res = EXIT_ERROR; + return false; + } + + Debug::Printf(kDbgMsg_Info, "Running Setup"); + + ConfigTree cfg_out; + SetupReturnValue res = platform->RunSetup(cfg, cfg_out); + if (res != kSetup_Cancel) + { + if (!IniUtil::Merge(cfg_file, cfg_out)) + { + platform->DisplayAlert("Unable to write to the configuration file (error code 0x%08X).\n%s", + platform->GetLastSystemError(), platform->GetDiskWriteAccessTroubleshootingText()); + } + } + if (res != kSetup_RunGame) + return false; + + // TODO: investigate if the full program restart may (should) be avoided + + // Just re-reading the config file seems to cause a caching + // problem on Win9x, so let's restart the process. + allegro_exit(); + char quotedpath[MAX_PATH]; + snprintf(quotedpath, MAX_PATH, "\"%s\"", exe_path.GetCStr()); + _spawnl (_P_OVERLAY, exe_path, quotedpath, NULL); + } +#endif + return true; +} + +void engine_force_window() +{ + // Force to run in a window, override the config file + // TODO: actually overwrite config tree instead + if (force_window == 1) + { + usetup.Screen.DisplayMode.Windowed = true; + usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_ByGameScaling; + } + else if (force_window == 2) + { + usetup.Screen.DisplayMode.Windowed = false; + usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_MaxDisplay; + } +} + +String find_game_data_in_directory(const String &path) +{ + al_ffblk ff; + String test_file; + String first_nonstd_fn; + String pattern = path; + pattern.Append("/*"); + + if (al_findfirst(pattern, &ff, FA_ALL & ~(FA_DIREC)) != 0) + return ""; + // Select first found data file; files with standart names (*.ags) have + // higher priority over files with custom names. + do + { + test_file = ff.name; + // Add a bit of sanity and do not parse contents of the 10k-files-large + // digital sound libraries. + // NOTE: we could certainly benefit from any kind of flag in file lib + // that would tell us this is the main lib without extra parsing. + if (test_file.CompareRightNoCase(".vox") == 0) + continue; + + // *.ags is a standart cross-platform file pattern for AGS games, + // ac2game.dat is a legacy file name for very old games, + // *.exe is a MS Win executable; it is included to this case because + // users often run AGS ports with Windows versions of games. + bool is_std_name = test_file.CompareRightNoCase(".ags") == 0 || + test_file.CompareNoCase("ac2game.dat") == 0 || + test_file.CompareRightNoCase(".exe") == 0; + if (is_std_name || first_nonstd_fn.IsEmpty()) + { + test_file.Format("%s/%s", path.GetCStr(), ff.name); + if (IsMainGameLibrary(test_file)) + { + if (is_std_name) + { + al_findclose(&ff); + return test_file; + } + else + first_nonstd_fn = test_file; + } + } + } + while(al_findnext(&ff) == 0); + al_findclose(&ff); + return first_nonstd_fn; +} + +bool search_for_game_data_file(String &filename, String &search_path) +{ + Debug::Printf("Looking for the game data file"); + // 1. From command line argument, treated as a directory + if (!cmdGameDataPath.IsEmpty()) + { + // set from cmd arg (do any conversions if needed) + filename = cmdGameDataPath; + if (!filename.IsEmpty() && Path::IsDirectory(filename)) + { + search_path = filename; + filename = find_game_data_in_directory(search_path); + } + } + // 2.2. Search in the provided data dir + else if (!usetup.data_files_dir.IsEmpty()) + { + search_path = usetup.data_files_dir; + filename = find_game_data_in_directory(search_path); + } + // 3. Look in known locations + else + { + // 3.1. Look for attachment in the running executable + // + // this will use argument zero, the executable's name + filename = GetPathFromCmdArg(0); + if (filename.IsEmpty() || !Common::AssetManager::IsDataFile(filename)) + { + // 3.2 Look in current directory + search_path = Directory::GetCurrentDirectory(); + filename = find_game_data_in_directory(search_path); + if (filename.IsEmpty()) + { + // 3.3 Look in executable's directory (if it's different from current dir) + if (Path::ComparePaths(appDirectory, search_path)) + { + search_path = appDirectory; + filename = find_game_data_in_directory(search_path); + } + } + } + } + + // Finally, store game file's absolute path, or report error + if (filename.IsEmpty()) + { + Debug::Printf(kDbgMsg_Error, "Game data file could not be found. Search path used: '%s'", search_path.GetCStr()); + return false; + } + filename = Path::MakeAbsolutePath(filename); + Debug::Printf(kDbgMsg_Info, "Located game data file: %s", filename.GetCStr()); + return true; +} + +// Try to initialize main game package found at the given path +bool engine_try_init_gamedata(String gamepak_path) +{ + // Search for an available game package in the known locations + AssetError err = AssetManager::SetDataFile(gamepak_path); + if (err != kAssetNoError) + { + platform->DisplayAlert("ERROR: The game data is missing, is of unsupported format or corrupt.\nFile: '%s'", gamepak_path.GetCStr()); + return false; + } + return true; +} + +void engine_init_fonts() +{ + Debug::Printf(kDbgMsg_Info, "Initializing TTF renderer"); + + init_font_renderer(); +} + +void engine_init_mouse() +{ + int res = minstalled(); + if (res < 0) + Debug::Printf(kDbgMsg_Info, "Initializing mouse: failed"); + else + Debug::Printf(kDbgMsg_Info, "Initializing mouse: number of buttons reported is %d", res); + Mouse::SetSpeed(usetup.mouse_speed); +} + +void engine_locate_speech_pak() +{ + play.want_speech=-2; + + if (!usetup.no_speech_pack) { + String speech_file = "speech.vox"; + String speech_filepath = find_assetlib(speech_file); + if (!speech_filepath.IsEmpty()) { + Debug::Printf("Initializing speech vox"); + if (AssetManager::SetDataFile(speech_filepath)!=Common::kAssetNoError) { + platform->DisplayAlert("Unable to read voice pack, file could be corrupted or of unknown format.\nSpeech voice-over will be disabled."); + AssetManager::SetDataFile(ResPaths.GamePak.Path); // switch back to the main data pack + return; + } + // TODO: why is this read right here??? move this to InitGameState! + Stream *speechsync = AssetManager::OpenAsset("syncdata.dat"); + if (speechsync != nullptr) { + // this game has voice lip sync + int lipsync_fmt = speechsync->ReadInt32(); + if (lipsync_fmt != 4) + { + Debug::Printf(kDbgMsg_Info, "Unknown speech lip sync format (%d).\nLip sync disabled.", lipsync_fmt); + } + else { + numLipLines = speechsync->ReadInt32(); + splipsync = (SpeechLipSyncLine*)malloc (sizeof(SpeechLipSyncLine) * numLipLines); + for (int ee = 0; ee < numLipLines; ee++) + { + splipsync[ee].numPhonemes = speechsync->ReadInt16(); + speechsync->Read(splipsync[ee].filename, 14); + splipsync[ee].endtimeoffs = (int*)malloc(splipsync[ee].numPhonemes * sizeof(int)); + speechsync->ReadArrayOfInt32(splipsync[ee].endtimeoffs, splipsync[ee].numPhonemes); + splipsync[ee].frame = (short*)malloc(splipsync[ee].numPhonemes * sizeof(short)); + speechsync->ReadArrayOfInt16(splipsync[ee].frame, splipsync[ee].numPhonemes); + } + } + delete speechsync; + } + AssetManager::SetDataFile(ResPaths.GamePak.Path); // switch back to the main data pack + Debug::Printf(kDbgMsg_Info, "Voice pack found and initialized."); + play.want_speech=1; + } + else if (Path::ComparePaths(ResPaths.DataDir, get_voice_install_dir()) != 0) + { + // If we have custom voice directory set, we will enable voice-over even if speech.vox does not exist + Debug::Printf(kDbgMsg_Info, "Voice pack was not found, but voice installation directory is defined: enabling voice-over."); + play.want_speech=1; + } + ResPaths.SpeechPak.Name = speech_file; + ResPaths.SpeechPak.Path = speech_filepath; + } +} + +void engine_locate_audio_pak() +{ + play.separate_music_lib = 0; + String music_file = game.GetAudioVOXName(); + String music_filepath = find_assetlib(music_file); + if (!music_filepath.IsEmpty()) + { + if (AssetManager::SetDataFile(music_filepath) == kAssetNoError) + { + AssetManager::SetDataFile(ResPaths.GamePak.Path); + Debug::Printf(kDbgMsg_Info, "%s found and initialized.", music_file.GetCStr()); + play.separate_music_lib = 1; + ResPaths.AudioPak.Name = music_file; + ResPaths.AudioPak.Path = music_filepath; + } + else + { + platform->DisplayAlert("Unable to initialize digital audio pack '%s', file could be corrupt or of unsupported format.", + music_file.GetCStr()); + } + } +} + +void engine_init_keyboard() +{ +#ifdef ALLEGRO_KEYBOARD_HANDLER + Debug::Printf(kDbgMsg_Info, "Initializing keyboard"); + + install_keyboard(); +#endif +#if AGS_PLATFORM_OS_LINUX + setlocale(LC_NUMERIC, "C"); // needed in X platform because install keyboard affects locale of printfs +#endif +} + +void engine_init_timer() +{ + Debug::Printf(kDbgMsg_Info, "Install timer"); + + skipMissedTicks(); +} + +bool try_install_sound(int digi_id, int midi_id, String *p_err_msg = nullptr) +{ + Debug::Printf(kDbgMsg_Info, "Trying to init: digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", + AlIDToChars(digi_id).s, digi_id, AlIDToChars(midi_id).s, midi_id); + + if (install_sound(digi_id, midi_id, nullptr) == 0) + return true; + // Allegro does not let you try digital and MIDI drivers separately, + // and does not indicate which driver failed by return value. + // Therefore we try to guess. + if (p_err_msg) + *p_err_msg = get_allegro_error(); + if (midi_id != MIDI_NONE) + { + Debug::Printf(kDbgMsg_Error, "Failed to init one of the drivers; Error: '%s'.\nWill try to start without MIDI", get_allegro_error()); + if (install_sound(digi_id, MIDI_NONE, nullptr) == 0) + return true; + } + if (digi_id != DIGI_NONE) + { + Debug::Printf(kDbgMsg_Error, "Failed to init one of the drivers; Error: '%s'.\nWill try to start without DIGI", get_allegro_error()); + if (install_sound(DIGI_NONE, midi_id, nullptr) == 0) + return true; + } + Debug::Printf(kDbgMsg_Error, "Failed to init sound drivers. Error: %s", get_allegro_error()); + return false; +} + +// Attempts to predict a digital driver Allegro would chose, and get its maximal voices +std::pair autodetect_driver(_DRIVER_INFO *driver_list, int (*detect_audio_driver)(int), const char *type) +{ + for (int i = 0; driver_list[i].driver; ++i) + { + if (driver_list[i].autodetect) + { + int voices = detect_audio_driver(driver_list[i].id); + if (voices != 0) + return std::make_pair(driver_list[i].id, voices); + Debug::Printf(kDbgMsg_Warn, "Failed to detect %s driver %s; Error: '%s'.", + type, AlIDToChars(driver_list[i].id).s, get_allegro_error()); + } + } + return std::make_pair(0, 0); +} + +// Decides which audio driver to request from Allegro. +// Returns a pair of audio card ID and max available voices. +std::pair decide_audiodriver(int try_id, _DRIVER_INFO *driver_list, + int(*detect_audio_driver)(int), int &al_drv_id, const char *type) +{ + if (try_id == 0) // no driver + return std::make_pair(0, 0); + al_drv_id = 0; // the driver id will be set by library if one was found + if (try_id > 0) + { + int voices = detect_audio_driver(try_id); + if (al_drv_id == try_id && voices != 0) // found and detected + return std::make_pair(try_id, voices); + if (voices == 0) // found in list but detect failed + Debug::Printf(kDbgMsg_Error, "Failed to detect %s driver %s; Error: '%s'.", type, AlIDToChars(try_id).s, get_allegro_error()); + else // not found at all + Debug::Printf(kDbgMsg_Error, "Unknown %s driver: %s, will try to find suitable one.", type, AlIDToChars(try_id).s); + } + return autodetect_driver(driver_list, detect_audio_driver, type); +} + +void engine_init_audio() +{ + Debug::Printf("Initializing sound drivers"); + int digi_id = usetup.digicard; + int midi_id = usetup.midicard; + int digi_voices = -1; + int midi_voices = -1; + // MOD player would need certain minimal number of voices + // TODO: find out if this is still relevant? + if (usetup.mod_player) + digi_voices = NUM_DIGI_VOICES; + + Debug::Printf(kDbgMsg_Info, "Sound settings: digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", + AlIDToChars(digi_id).s, digi_id, AlIDToChars(midi_id).s, midi_id); + + // First try if drivers are supported, and switch to autodetect if explicit option failed + _DRIVER_INFO *digi_drivers = system_driver->digi_drivers ? system_driver->digi_drivers() : _digi_driver_list; + std::pair digi_drv = decide_audiodriver(digi_id, digi_drivers, detect_digi_driver, digi_card, "digital"); + _DRIVER_INFO *midi_drivers = system_driver->midi_drivers ? system_driver->midi_drivers() : _midi_driver_list; + std::pair midi_drv = decide_audiodriver(midi_id, midi_drivers, detect_midi_driver, midi_card, "MIDI"); + + // Now, knowing which drivers we suppose to install, decide on which voices we reserve + digi_id = digi_drv.first; + midi_id = midi_drv.first; + const int max_digi_voices = digi_drv.second; + const int max_midi_voices = midi_drv.second; + if (digi_voices > max_digi_voices) + digi_voices = max_digi_voices; + // NOTE: we do not specify number of MIDI voices, so don't have to calculate available here + + reserve_voices(digi_voices, midi_voices); + // maybe this line will solve the sound volume? [??? wth is this] + set_volume_per_voice(1); + + String err_msg; + bool sound_res = try_install_sound(digi_id, midi_id, &err_msg); + if (!sound_res) + { + Debug::Printf(kDbgMsg_Error, "Everything failed, disabling sound."); + reserve_voices(0, 0); + install_sound(DIGI_NONE, MIDI_NONE, nullptr); + } + // Only display a warning if they wanted a sound card + const bool digi_failed = usetup.digicard != DIGI_NONE && digi_card == DIGI_NONE; + const bool midi_failed = usetup.midicard != MIDI_NONE && midi_card == MIDI_NONE; + if (digi_failed || midi_failed) + { + platform->DisplayAlert("Warning: cannot enable %s.\nProblem: %s.\n\nYou may supress this message by disabling %s in the game setup.", + (digi_failed && midi_failed ? "game audio" : (digi_failed ? "digital audio" : "MIDI audio") ), + (err_msg.IsEmpty() ? "No compatible drivers found in the system" : err_msg.GetCStr()), + (digi_failed && midi_failed ? "sound" : (digi_failed ? "digital sound" : "MIDI sound") )); + } + + usetup.digicard = digi_card; + usetup.midicard = midi_card; + + Debug::Printf(kDbgMsg_Info, "Installed digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", + AlIDToChars(digi_card).s, digi_card, AlIDToChars(midi_card).s, midi_card); + + if (digi_card == DIGI_NONE) + { + // disable speech and music if no digital sound + // therefore the MIDI soundtrack will be used if present, + // and the voice mode should not go to Voice Only + play.want_speech = -2; + play.separate_music_lib = 0; + } + if (usetup.mod_player && digi_driver->voices < NUM_DIGI_VOICES) + { + // disable MOD player if there's not enough digital voices + // TODO: find out if this is still relevant? + usetup.mod_player = 0; + } + +#if AGS_PLATFORM_OS_WINDOWS + if (digi_card == DIGI_DIRECTX(0)) + { + // DirectX mixer seems to buffer an extra sample itself + use_extra_sound_offset = 1; + } +#endif +} + +void engine_init_debug() +{ + //set_volume(255,-1); + if ((debug_flags & (~DBG_DEBUGMODE)) >0) { + platform->DisplayAlert("Engine debugging enabled.\n" + "\nNOTE: You have selected to enable one or more engine debugging options.\n" + "These options cause many parts of the game to behave abnormally, and you\n" + "may not see the game as you are used to it. The point is to test whether\n" + "the engine passes a point where it is crashing on you normally.\n" + "[Debug flags enabled: 0x%02X]",debug_flags); + } +} + +void atexit_handler() { + if (proper_exit==0) { + platform->DisplayAlert("Error: the program has exited without requesting it.\n" + "Program pointer: %+03d (write this number down), ACI version %s\n" + "If you see a list of numbers above, please write them down and contact\n" + "developers. Otherwise, note down any other information displayed.", + our_eip, EngineVersion.LongString.GetCStr()); + } +} + +void engine_init_exit_handler() +{ + Debug::Printf(kDbgMsg_Info, "Install exit handler"); + + atexit(atexit_handler); +} + +void engine_init_rand() +{ + play.randseed = time(nullptr); + srand (play.randseed); +} + +void engine_init_pathfinder() +{ + init_pathfinder(loaded_game_file_version); +} + +void engine_pre_init_gfx() +{ + //Debug::Printf("Initialize gfx"); + + //platform->InitialiseAbufAtStartup(); +} + +int engine_load_game_data() +{ + Debug::Printf("Load game data"); + our_eip=-17; + HError err = load_game_file(); + if (!err) + { + proper_exit=1; + platform->FinishedUsingGraphicsMode(); + display_game_file_error(err); + return EXIT_ERROR; + } + return 0; +} + +int engine_check_register_game() +{ + if (justRegisterGame) + { + platform->RegisterGameWithGameExplorer(); + proper_exit = 1; + return EXIT_NORMAL; + } + + if (justUnRegisterGame) + { + platform->UnRegisterGameWithGameExplorer(); + proper_exit = 1; + return EXIT_NORMAL; + } + + return 0; +} + +void engine_init_title() +{ + our_eip=-91; + set_window_title(game.gamename); + Debug::Printf(kDbgMsg_Info, "Game title: '%s'", game.gamename); +} + +void engine_init_directories() +{ + Debug::Printf(kDbgMsg_Info, "Data directory: %s", usetup.data_files_dir.GetCStr()); + if (!usetup.install_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Optional install directory: %s", usetup.install_dir.GetCStr()); + if (!usetup.install_audio_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Optional audio directory: %s", usetup.install_audio_dir.GetCStr()); + if (!usetup.install_voice_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Optional voice-over directory: %s", usetup.install_voice_dir.GetCStr()); + if (!usetup.user_data_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "User data directory: %s", usetup.user_data_dir.GetCStr()); + if (!usetup.shared_data_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Shared data directory: %s", usetup.shared_data_dir.GetCStr()); + + ResPaths.DataDir = usetup.data_files_dir; + ResPaths.GamePak.Path = usetup.main_data_filepath; + ResPaths.GamePak.Name = get_filename(usetup.main_data_filepath); + + set_install_dir(usetup.install_dir, usetup.install_audio_dir, usetup.install_voice_dir); + if (!usetup.install_dir.IsEmpty()) + { + // running in debugger: don't redirect to the game exe folder (_Debug) + // TODO: find out why we need to do this (and do we?) + ResPaths.DataDir = "."; + } + + // if end-user specified custom save path, use it + bool res = false; + if (!usetup.user_data_dir.IsEmpty()) + { + res = SetCustomSaveParent(usetup.user_data_dir); + if (!res) + { + Debug::Printf(kDbgMsg_Warn, "WARNING: custom user save path failed, using default system paths"); + res = false; + } + } + // if there is no custom path, or if custom path failed, use default system path + if (!res) + { + char newDirBuffer[MAX_PATH]; + sprintf(newDirBuffer, "%s/%s", UserSavedgamesRootToken.GetCStr(), game.saveGameFolderName); + SetSaveGameDirectoryPath(newDirBuffer); + } +} + +#if AGS_PLATFORM_OS_ANDROID +extern char android_base_directory[256]; +#endif // AGS_PLATFORM_OS_ANDROID + +int check_write_access() { + + if (platform->GetDiskFreeSpaceMB() < 2) + return 0; + + our_eip = -1895; + + // The Save Game Dir is the only place that we should write to + String svg_dir = get_save_game_directory(); + String tempPath = String::FromFormat("%s""tmptest.tmp", svg_dir.GetCStr()); + Stream *temp_s = Common::File::CreateFile(tempPath); + if (!temp_s) + // TODO: move this somewhere else (Android platform driver init?) +#if AGS_PLATFORM_OS_ANDROID + { + put_backslash(android_base_directory); + tempPath.Format("%s""tmptest.tmp", android_base_directory); + temp_s = Common::File::CreateFile(tempPath); + if (temp_s == NULL) return 0; + else SetCustomSaveParent(android_base_directory); + } +#else + return 0; +#endif // AGS_PLATFORM_OS_ANDROID + + our_eip = -1896; + + temp_s->Write("just to test the drive free space", 30); + delete temp_s; + + our_eip = -1897; + + if (::remove(tempPath)) + return 0; + + return 1; +} + +int engine_check_disk_space() +{ + Debug::Printf(kDbgMsg_Info, "Checking for disk space"); + + if (check_write_access()==0) { + platform->DisplayAlert("Unable to write in the savegame directory.\n%s", platform->GetDiskWriteAccessTroubleshootingText()); + proper_exit = 1; + return EXIT_ERROR; + } + + return 0; +} + +int engine_check_font_was_loaded() +{ + if (!font_first_renderer_loaded()) + { + platform->DisplayAlert("No game fonts found. At least one font is required to run the game."); + proper_exit = 1; + return EXIT_ERROR; + } + + return 0; +} + +void engine_init_modxm_player() +{ +#ifndef PSP_NO_MOD_PLAYBACK + if (game.options[OPT_NOMODMUSIC]) + usetup.mod_player = 0; + + if (usetup.mod_player) { + Debug::Printf(kDbgMsg_Info, "Initializing MOD/XM player"); + + if (init_mod_player(NUM_MOD_DIGI_VOICES) < 0) { + platform->DisplayAlert("Warning: install_mod: MOD player failed to initialize."); + usetup.mod_player=0; + } + } +#else + usetup.mod_player = 0; + Debug::Printf(kDbgMsg_Info, "Compiled without MOD/XM player"); +#endif +} + +// Do the preload graphic if available +void show_preload() +{ + color temppal[256]; + Bitmap *splashsc = BitmapHelper::CreateRawBitmapOwner( load_pcx("preload.pcx",temppal) ); + if (splashsc != nullptr) + { + Debug::Printf("Displaying preload image"); + if (splashsc->GetColorDepth() == 8) + set_palette_range(temppal, 0, 255, 0); + if (gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->GetMemoryBackBuffer()->Clear(); + + const Rect &view = play.GetMainViewport(); + Bitmap *tsc = BitmapHelper::CreateBitmapCopy(splashsc, game.GetColorDepth()); + if (!gfxDriver->HasAcceleratedTransform() && view.GetSize() != tsc->GetSize()) + { + Bitmap *stretched = new Bitmap(view.GetWidth(), view.GetHeight(), tsc->GetColorDepth()); + stretched->StretchBlt(tsc, RectWH(0, 0, view.GetWidth(), view.GetHeight())); + delete tsc; + tsc = stretched; + } + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(tsc, false, true); + ddb->SetStretch(view.GetWidth(), view.GetHeight()); + gfxDriver->ClearDrawLists(); + gfxDriver->DrawSprite(0, 0, ddb); + render_to_screen(); + gfxDriver->DestroyDDB(ddb); + delete splashsc; + delete tsc; + platform->Delay(500); + } +} + +int engine_init_sprites() +{ + Debug::Printf(kDbgMsg_Info, "Initialize sprites"); + + HError err = spriteset.InitFile(SpriteCache::DefaultSpriteFileName, SpriteCache::DefaultSpriteIndexName); + if (!err) + { + platform->FinishedUsingGraphicsMode(); + allegro_exit(); + proper_exit=1; + platform->DisplayAlert("Could not load sprite set file %s\n%s", + SpriteCache::DefaultSpriteFileName.GetCStr(), + err->FullMessage().GetCStr()); + return EXIT_ERROR; + } + + return 0; +} + +void engine_init_game_settings() +{ + our_eip=-7; + Debug::Printf("Initialize game settings"); + + int ee; + + for (ee = 0; ee < MAX_ROOM_OBJECTS + game.numcharacters; ee++) + actsps[ee] = nullptr; + + for (ee=0;ee<256;ee++) { + if (game.paluses[ee]!=PAL_BACKGROUND) + palette[ee]=game.defpal[ee]; + } + + for (ee = 0; ee < game.numcursors; ee++) + { + // The cursor graphics are assigned to mousecurs[] and so cannot + // be removed from memory + if (game.mcurs[ee].pic >= 0) + spriteset.Precache(game.mcurs[ee].pic); + + // just in case they typed an invalid view number in the editor + if (game.mcurs[ee].view >= game.numviews) + game.mcurs[ee].view = -1; + + if (game.mcurs[ee].view >= 0) + precache_view (game.mcurs[ee].view); + } + // may as well preload the character gfx + if (playerchar->view >= 0) + precache_view (playerchar->view); + + for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++) + objcache[ee].image = nullptr; + + /* dummygui.guiId = -1; + dummyguicontrol.guin = -1; + dummyguicontrol.objn = -1;*/ + + our_eip=-6; + // game.chars[0].talkview=4; + //init_language_text(game.langcodes[0]); + + for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++) { + scrObj[ee].id = ee; + // 64 bit: Using the id instead + // scrObj[ee].obj = NULL; + } + + for (ee=0;ee= 0) { + // set initial loop to 0 + game.chars[ee].loop = 0; + // or to 1 if they don't have up/down frames + if (views[game.chars[ee].view].loops[0].numFrames < 1) + game.chars[ee].loop = 1; + } + charextra[ee].process_idle_this_time = 0; + charextra[ee].invorder_count = 0; + charextra[ee].slow_move_counter = 0; + charextra[ee].animwait = 0; + } + // multiply up gui positions + guibg = (Bitmap **)malloc(sizeof(Bitmap *) * game.numgui); + guibgbmp = (IDriverDependantBitmap**)malloc(sizeof(IDriverDependantBitmap*) * game.numgui); + for (ee=0;eeinv[ee]=1; + else playerchar->inv[ee]=0; + } + play.score=0; + play.sierra_inv_color=7; + // copy the value set by the editor + if (game.options[OPT_GLOBALTALKANIMSPD] >= 0) + { + play.talkanim_speed = game.options[OPT_GLOBALTALKANIMSPD]; + game.options[OPT_GLOBALTALKANIMSPD] = 1; + } + else + { + play.talkanim_speed = -game.options[OPT_GLOBALTALKANIMSPD] - 1; + game.options[OPT_GLOBALTALKANIMSPD] = 0; + } + play.inv_item_wid = 40; + play.inv_item_hit = 22; + play.messagetime=-1; + play.disabled_user_interface=0; + play.gscript_timer=-1; + play.debug_mode=game.options[OPT_DEBUGMODE]; + play.inv_top=0; + play.inv_numdisp=0; + play.obsolete_inv_numorder=0; + play.text_speed=15; + play.text_min_display_time_ms = 1000; + play.ignore_user_input_after_text_timeout_ms = 500; + play.ClearIgnoreInput(); + play.lipsync_speed = 15; + play.close_mouth_speech_time = 10; + play.disable_antialiasing = 0; + play.rtint_enabled = false; + play.rtint_level = 0; + play.rtint_light = 0; + play.text_speed_modifier = 0; + play.text_align = kHAlignLeft; + // Make the default alignment to the right with right-to-left text + if (game.options[OPT_RIGHTLEFTWRITE]) + play.text_align = kHAlignRight; + + play.speech_bubble_width = get_fixed_pixel_size(100); + play.bg_frame=0; + play.bg_frame_locked=0; + play.bg_anim_delay=0; + play.anim_background_speed = 0; + play.silent_midi = 0; + play.current_music_repeating = 0; + play.skip_until_char_stops = -1; + play.get_loc_name_last_time = -1; + play.get_loc_name_save_cursor = -1; + play.restore_cursor_mode_to = -1; + play.restore_cursor_image_to = -1; + play.ground_level_areas_disabled = 0; + play.next_screen_transition = -1; + play.temporarily_turned_off_character = -1; + play.inv_backwards_compatibility = 0; + play.gamma_adjustment = 100; + play.do_once_tokens.resize(0); + play.music_queue_size = 0; + play.shakesc_length = 0; + play.wait_counter=0; + play.key_skip_wait = SKIP_NONE; + play.cur_music_number=-1; + play.music_repeat=1; + play.music_master_volume=100 + LegacyMusicMasterVolumeAdjustment; + play.digital_master_volume = 100; + play.screen_flipped=0; + play.cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)game.options[OPT_NOSKIPTEXT]); + play.sound_volume = 255; + play.speech_volume = 255; + play.normal_font = 0; + play.speech_font = 1; + play.speech_text_shadow = 16; + play.screen_tint = -1; + play.bad_parsed_word[0] = 0; + play.swap_portrait_side = 0; + play.swap_portrait_lastchar = -1; + play.swap_portrait_lastlastchar = -1; + play.in_conversation = 0; + play.skip_display = 3; + play.no_multiloop_repeat = 0; + play.in_cutscene = 0; + play.fast_forward = 0; + play.totalscore = game.totalscore; + play.roomscript_finished = 0; + play.no_textbg_when_voice = 0; + play.max_dialogoption_width = get_fixed_pixel_size(180); + play.no_hicolor_fadein = 0; + play.bgspeech_game_speed = 0; + play.bgspeech_stay_on_display = 0; + play.unfactor_speech_from_textlength = 0; + play.mp3_loop_before_end = 70; + play.speech_music_drop = 60; + play.room_changes = 0; + play.check_interaction_only = 0; + play.replay_hotkey_unused = -1; // StartRecording: not supported. + play.dialog_options_x = 0; + play.dialog_options_y = 0; + play.min_dialogoption_width = 0; + play.disable_dialog_parser = 0; + play.ambient_sounds_persist = 0; + play.screen_is_faded_out = 0; + play.player_on_region = 0; + play.top_bar_backcolor = 8; + play.top_bar_textcolor = 16; + play.top_bar_bordercolor = 8; + play.top_bar_borderwidth = 1; + play.top_bar_ypos = 25; + play.top_bar_font = -1; + play.screenshot_width = 160; + play.screenshot_height = 100; + play.speech_text_align = kHAlignCenter; + play.auto_use_walkto_points = 1; + play.inventory_greys_out = 0; + play.skip_speech_specific_key = 0; + play.abort_key = 324; // Alt+X + play.fade_to_red = 0; + play.fade_to_green = 0; + play.fade_to_blue = 0; + play.show_single_dialog_option = 0; + play.keep_screen_during_instant_transition = 0; + play.read_dialog_option_colour = -1; + play.speech_portrait_placement = 0; + play.speech_portrait_x = 0; + play.speech_portrait_y = 0; + play.speech_display_post_time_ms = 0; + play.dialog_options_highlight_color = DIALOG_OPTIONS_HIGHLIGHT_COLOR_DEFAULT; + play.speech_has_voice = false; + play.speech_voice_blocking = false; + play.speech_in_post_state = false; + play.narrator_speech = game.playercharacter; + play.crossfading_out_channel = 0; + play.speech_textwindow_gui = game.options[OPT_TWCUSTOM]; + if (play.speech_textwindow_gui == 0) + play.speech_textwindow_gui = -1; + strcpy(play.game_name, game.gamename); + play.lastParserEntry[0] = 0; + play.follow_change_room_timer = 150; + for (ee = 0; ee < MAX_ROOM_BGFRAMES; ee++) + play.raw_modified[ee] = 0; + play.game_speed_modifier = 0; + if (debug_flags & DBG_DEBUGMODE) + play.debug_mode = 1; + gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); + play.shake_screen_yoff = 0; + + memset(&play.walkable_areas_on[0],1,MAX_WALK_AREAS+1); + memset(&play.script_timers[0],0,MAX_TIMERS * sizeof(int)); + memset(&play.default_audio_type_volumes[0], -1, MAX_AUDIO_TYPES * sizeof(int)); + + // reset graphical script vars (they're still used by some games) + for (ee = 0; ee < MAXGLOBALVARS; ee++) + play.globalvars[ee] = 0; + + for (ee = 0; ee < MAXGLOBALSTRINGS; ee++) + play.globalstrings[ee][0] = 0; + + if (!usetup.translation.IsEmpty()) + init_translation (usetup.translation, "", true); + + update_invorder(); + displayed_room = -10; + + currentcursor=0; + our_eip=-4; + mousey=100; // stop icon bar popping up + + // We use same variable to read config and be used at runtime for now, + // so update it here with regards to game design option + usetup.RenderAtScreenRes = + (game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_UserDefined && usetup.RenderAtScreenRes) || + game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_Enabled; +} + +void engine_setup_scsystem_auxiliary() +{ + // ScriptSystem::aci_version is only 10 chars long + strncpy(scsystem.aci_version, EngineVersion.LongString, 10); + if (usetup.override_script_os >= 0) + { + scsystem.os = usetup.override_script_os; + } + else + { + scsystem.os = platform->GetSystemOSID(); + } +} + +void engine_update_mp3_thread() +{ + update_mp3_thread(); + platform->Delay(50); +} + +void engine_start_multithreaded_audio() +{ + // PSP: Initialize the sound cache. + clear_sound_cache(); + + // Create sound update thread. This is a workaround for sound stuttering. + if (psp_audio_multithreaded) + { + if (!audioThread.CreateAndStart(engine_update_mp3_thread, true)) + { + Debug::Printf(kDbgMsg_Info, "Failed to start audio thread, audio will be processed on the main thread"); + psp_audio_multithreaded = 0; + } + else + { + Debug::Printf(kDbgMsg_Info, "Audio thread started"); + } + } + else + { + Debug::Printf(kDbgMsg_Info, "Audio is processed on the main thread"); + } +} + +void engine_prepare_to_start_game() +{ + Debug::Printf("Prepare to start game"); + + engine_setup_scsystem_auxiliary(); + engine_start_multithreaded_audio(); + +#if AGS_PLATFORM_OS_ANDROID + if (psp_load_latest_savegame) + selectLatestSavegame(); +#endif +} + +// TODO: move to test unit +Bitmap *test_allegro_bitmap; +IDriverDependantBitmap *test_allegro_ddb; +void allegro_bitmap_test_init() +{ + test_allegro_bitmap = nullptr; + // Switched the test off for now + //test_allegro_bitmap = AllegroBitmap::CreateBitmap(320,200,32); +} + +// Only allow searching around for game data on desktop systems; +// otherwise use explicit argument either from program wrapper, command-line +// or read from default config. +#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX || AGS_PLATFORM_OS_MACOS + #define AGS_SEARCH_FOR_GAME_ON_LAUNCH +#endif + +// Define location of the game data either using direct settings or searching +// for the available resource packs in common locations +HError define_gamedata_location_checkall(const String &exe_path) +{ + // First try if they provided a startup option + if (!cmdGameDataPath.IsEmpty()) + { + // If not a valid path - bail out + if (!Path::IsFileOrDir(cmdGameDataPath)) + return new Error(String::FromFormat("Defined game location is not a valid path.\nPath: '%s'", cmdGameDataPath.GetCStr())); + // Switch working dir to this path to be able to look for config and other assets there + Directory::SetCurrentDirectory(Path::GetDirectoryPath(cmdGameDataPath)); + // If it's a file, then keep it and proceed + if (Path::IsFile(cmdGameDataPath)) + { + usetup.main_data_filepath = cmdGameDataPath; + return HError::None(); + } + } + // Read game data location from the default config file. + // This is an optional setting that may instruct which game file to use as a primary asset library. + ConfigTree cfg; + String def_cfg_file = find_default_cfg_file(exe_path); + IniUtil::Read(def_cfg_file, cfg); + read_game_data_location(cfg); + if (!usetup.main_data_filename.IsEmpty()) + return HError::None(); + +#if defined (AGS_SEARCH_FOR_GAME_ON_LAUNCH) + // No direct filepath provided, search in common locations. + String path, search_path; + if (search_for_game_data_file(path, search_path)) + { + usetup.main_data_filepath = path; + return HError::None(); + } + return new Error("Engine was not able to find any compatible game data.", + search_path.IsEmpty() ? String() : String::FromFormat("Searched in: %s", search_path.GetCStr())); +#else + return new Error("The game location was not defined by startup settings."); +#endif +} + +// Define location of the game data +bool define_gamedata_location(const String &exe_path) +{ + HError err = define_gamedata_location_checkall(exe_path); + if (!err) + { + platform->DisplayAlert("ERROR: Unable to determine game data.\n%s", err->FullMessage().GetCStr()); + main_print_help(); + return false; + } + + // On success: set all the necessary path and filename settings, + // derive missing ones from available. + if (usetup.main_data_filename.IsEmpty()) + { + usetup.main_data_filename = get_filename(usetup.main_data_filepath); + } + else if (usetup.main_data_filepath.IsEmpty()) + { + if (usetup.data_files_dir.IsEmpty() || !is_relative_filename(usetup.main_data_filename)) + usetup.main_data_filepath = usetup.main_data_filename; + else + usetup.main_data_filepath = Path::ConcatPaths(usetup.data_files_dir, usetup.main_data_filename); + } + if (usetup.data_files_dir.IsEmpty()) + usetup.data_files_dir = Path::GetDirectoryPath(usetup.main_data_filepath); + return true; +} + +// Find and preload main game data +bool engine_init_gamedata(const String &exe_path) +{ + Debug::Printf(kDbgMsg_Info, "Initializing game data"); + if (!define_gamedata_location(exe_path)) + return false; + if (!engine_try_init_gamedata(usetup.main_data_filepath)) + return false; + + // Pre-load game name and savegame folder names from data file + // TODO: research if that is possible to avoid this step and just + // read the full head game data at this point. This might require + // further changes of the order of initialization. + HError err = preload_game_data(); + if (!err) + { + display_game_file_error(err); + return false; + } + return true; +} + +void engine_read_config(const String &exe_path, ConfigTree &cfg) +{ + // Read default configuration file + String def_cfg_file = find_default_cfg_file(exe_path); + IniUtil::Read(def_cfg_file, cfg); + + // Disabled on Windows because people were afraid that this config could be mistakenly + // created by some installer and screw up their games. Until any kind of solution is found. + String user_global_cfg_file; +#if ! AGS_PLATFORM_OS_WINDOWS + // Read user global configuration file + user_global_cfg_file = find_user_global_cfg_file(); + if (Path::ComparePaths(user_global_cfg_file, def_cfg_file) != 0) + IniUtil::Read(user_global_cfg_file, cfg); +#endif + + // Read user configuration file + String user_cfg_file = find_user_cfg_file(); + if (Path::ComparePaths(user_cfg_file, def_cfg_file) != 0 && + Path::ComparePaths(user_cfg_file, user_global_cfg_file) != 0) + IniUtil::Read(user_cfg_file, cfg); + + // Apply overriding options from mobile port settings + // TODO: normally, those should be instead stored in the same config file in a uniform way + // NOTE: the variable is historically called "ignore" but we use it in "override" meaning here + if (psp_ignore_acsetup_cfg_file) + override_config_ext(cfg); +} + +// Gathers settings from all available sources into single ConfigTree +void engine_prepare_config(ConfigTree &cfg, const String &exe_path, const ConfigTree &startup_opts) +{ + Debug::Printf(kDbgMsg_Info, "Setting up game configuration"); + // Read configuration files + engine_read_config(exe_path, cfg); + // Merge startup options in + for (const auto §n : startup_opts) + for (const auto &opt : sectn.second) + cfg[sectn.first][opt.first] = opt.second; + + // Add "meta" config settings to let setup application(s) + // display correct properties to the user + INIwriteint(cfg, "misc", "defaultres", game.GetResolutionType()); + INIwriteint(cfg, "misc", "letterbox", game.options[OPT_LETTERBOX]); + INIwriteint(cfg, "misc", "game_width", game.GetDefaultRes().Width); + INIwriteint(cfg, "misc", "game_height", game.GetDefaultRes().Height); + INIwriteint(cfg, "misc", "gamecolordepth", game.color_depth * 8); + if (game.options[OPT_RENDERATSCREENRES] != kRenderAtScreenRes_UserDefined) + { + // force enabled/disabled + INIwriteint(cfg, "graphics", "render_at_screenres", game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_Enabled); + INIwriteint(cfg, "disabled", "render_at_screenres", 1); + } +} + +// Applies configuration to the running game +void engine_set_config(const ConfigTree cfg) +{ + config_defaults(); + apply_config(cfg); + post_config(); +} + +// +// --tell command support: printing engine/game info by request +// +extern std::set tellInfoKeys; +static bool print_info_needs_game(const std::set &keys) +{ + return keys.count("all") > 0 || keys.count("config") > 0 || keys.count("configpath") > 0 || + keys.count("data") > 0; +} + +static void engine_print_info(const std::set &keys, const String &exe_path, ConfigTree *user_cfg) +{ + const bool all = keys.count("all") > 0; + ConfigTree data; + if (all || keys.count("engine") > 0) + { + data["engine"]["name"] = get_engine_name(); + data["engine"]["version"] = get_engine_version(); + } + if (all || keys.count("graphicdriver") > 0) + { + StringV drv; + AGS::Engine::GetGfxDriverFactoryNames(drv); + for (size_t i = 0; i < drv.size(); ++i) + { + data["graphicdriver"][String::FromFormat("%u", i)] = drv[i]; + } + } + if (all || keys.count("configpath") > 0) + { + String def_cfg_file = find_default_cfg_file(exe_path); + String gl_cfg_file = find_user_global_cfg_file(); + String user_cfg_file = find_user_cfg_file(); + data["config-path"]["default"] = def_cfg_file; + data["config-path"]["global"] = gl_cfg_file; + data["config-path"]["user"] = user_cfg_file; + } + if ((all || keys.count("config") > 0) && user_cfg) + { + for (const auto §n : *user_cfg) + { + String cfg_sectn = String::FromFormat("config@%s", sectn.first.GetCStr()); + for (const auto &opt : sectn.second) + data[cfg_sectn][opt.first] = opt.second; + } + } + if (all || keys.count("data") > 0) + { + data["data"]["gamename"] = game.gamename; + data["data"]["version"] = String::FromFormat("%d", loaded_game_file_version); + data["data"]["compiledwith"] = game.compiled_with; + data["data"]["basepack"] = usetup.main_data_filepath; + } + String full; + IniUtil::WriteToString(full, data); + platform->WriteStdOut("%s", full.GetCStr()); +} + +// Custom resource search callback for Allegro's system driver. +// It helps us direct Allegro to our game data location, because it won't know. +static int al_find_resource(char *dest, const char* resource, int dest_size) +{ + String path = Path::ConcatPaths(get_install_dir(), resource); + if (File::TestReadFile(path)) + { + snprintf(dest, dest_size, "%s", path.GetCStr()); + return 0; + } + return -1; +} + +// TODO: this function is still a big mess, engine/system-related initialization +// is mixed with game-related data adjustments. Divide it in parts, move game +// data init into either InitGameState() or other game method as appropriate. +int initialize_engine(const ConfigTree &startup_opts) +{ + if (engine_pre_init_callback) { + engine_pre_init_callback(); + } + + //----------------------------------------------------- + // Install backend + if (!engine_init_allegro()) + return EXIT_ERROR; + + //----------------------------------------------------- + // Locate game data and assemble game config + const String exe_path = global_argv[0]; + if (justTellInfo && !print_info_needs_game(tellInfoKeys)) + { + engine_print_info(tellInfoKeys, exe_path, nullptr); + return EXIT_NORMAL; + } + + if (!engine_init_gamedata(exe_path)) + return EXIT_ERROR; + ConfigTree cfg; + engine_prepare_config(cfg, exe_path, startup_opts); + if (justTellInfo) + { + engine_print_info(tellInfoKeys, exe_path, &cfg); + return EXIT_NORMAL; + } + // Test if need to run built-in setup program (where available) + if (justRunSetup) + { + int res; + if (!engine_run_setup(exe_path, cfg, res)) + return res; + } + // Set up game options from user config + engine_set_config(cfg); + engine_setup_allegro(); + engine_force_window(); + + our_eip = -190; + + //----------------------------------------------------- + // Init data paths and other directories, locate general data files + engine_init_directories(); + + our_eip = -191; + + engine_locate_speech_pak(); + + our_eip = -192; + + engine_locate_audio_pak(); + + our_eip = -193; + + // Assign custom find resource callback for limited Allegro operations + system_driver->find_resource = al_find_resource; + + //----------------------------------------------------- + // Begin setting up systems + engine_setup_window(); + + our_eip = -194; + + engine_init_fonts(); + + our_eip = -195; + + engine_init_keyboard(); + + our_eip = -196; + + engine_init_mouse(); + + our_eip = -197; + + engine_init_timer(); + + our_eip = -198; + + engine_init_audio(); + + our_eip = -199; + + engine_init_debug(); + + our_eip = -10; + + engine_init_exit_handler(); + + engine_init_rand(); + + engine_init_pathfinder(); + + set_game_speed(40); + + our_eip=-20; + our_eip=-19; + + int res = engine_load_game_data(); + if (res != 0) + return res; + + res = engine_check_register_game(); + if (res != 0) + return res; + + engine_init_title(); + + our_eip = -189; + + res = engine_check_disk_space(); + if (res != 0) + return res; + + // Make sure that at least one font was loaded in the process of loading + // the game data. + // TODO: Fold this check into engine_load_game_data() + res = engine_check_font_was_loaded(); + if (res != 0) + return res; + + our_eip = -179; + + engine_init_modxm_player(); + + engine_init_resolution_settings(game.GetGameRes()); + + // Attempt to initialize graphics mode + if (!engine_try_set_gfxmode_any(usetup.Screen)) + return EXIT_ERROR; + + SetMultitasking(0); + + // [ER] 2014-03-13 + // Hide the system cursor via allegro + show_os_cursor(MOUSE_CURSOR_NONE); + + show_preload(); + + res = engine_init_sprites(); + if (res != 0) + return res; + + engine_init_game_settings(); + + engine_prepare_to_start_game(); + + allegro_bitmap_test_init(); + + initialize_start_and_play_game(override_start_room, loadSaveGameOnStartup); + + quit("|bye!"); + return EXIT_NORMAL; +} + +bool engine_try_set_gfxmode_any(const ScreenSetup &setup) +{ + engine_shutdown_gfxmode(); + + const Size init_desktop = get_desktop_size(); + if (!graphics_mode_init_any(game.GetGameRes(), setup, ColorDepthOption(game.GetColorDepth()))) + return false; + + engine_post_gfxmode_setup(init_desktop); + return true; +} + +bool engine_try_switch_windowed_gfxmode() +{ + if (!gfxDriver || !gfxDriver->IsModeSet()) + return false; + + // Keep previous mode in case we need to revert back + DisplayMode old_dm = gfxDriver->GetDisplayMode(); + GameFrameSetup old_frame = graphics_mode_get_render_frame(); + + // Release engine resources that depend on display mode + engine_pre_gfxmode_release(); + + Size init_desktop = get_desktop_size(); + bool switch_to_windowed = !old_dm.Windowed; + ActiveDisplaySetting setting = graphics_mode_get_last_setting(switch_to_windowed); + DisplayMode last_opposite_mode = setting.Dm; + GameFrameSetup use_frame_setup = setting.FrameSetup; + + // If there are saved parameters for given mode (fullscreen/windowed) + // then use them, if there are not, get default setup for the new mode. + bool res; + if (last_opposite_mode.IsValid()) + { + res = graphics_mode_set_dm(last_opposite_mode); + } + else + { + // we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults() + DisplayModeSetup dm_setup = usetup.Screen.DisplayMode; + dm_setup.Windowed = !old_dm.Windowed; + graphics_mode_get_defaults(dm_setup.Windowed, dm_setup.ScreenSize, use_frame_setup); + res = graphics_mode_set_dm_any(game.GetGameRes(), dm_setup, old_dm.ColorDepth, use_frame_setup); + } + + // Apply corresponding frame render method + if (res) + res = graphics_mode_set_render_frame(use_frame_setup); + + if (!res) + { + // If failed, try switching back to previous gfx mode + res = graphics_mode_set_dm(old_dm) && + graphics_mode_set_render_frame(old_frame); + } + + if (res) + { + // If succeeded (with any case), update engine objects that rely on + // active display mode. + if (gfxDriver->GetDisplayMode().Windowed) + init_desktop = get_desktop_size(); + engine_post_gfxmode_setup(init_desktop); + } + ags_clear_input_buffer(); + return res; +} + +void engine_shutdown_gfxmode() +{ + if (!gfxDriver) + return; + + engine_pre_gfxsystem_shutdown(); + graphics_mode_shutdown(); +} + +const char *get_engine_name() +{ + return "Adventure Game Studio run-time engine"; +} + +const char *get_engine_version() { + return EngineVersion.LongString.GetCStr(); +} + +void engine_set_pre_init_callback(t_engine_pre_init_callback callback) { + engine_pre_init_callback = callback; +} diff --git a/engines/ags/engine/main/engine.h b/engines/ags/engine/main/engine.h new file mode 100644 index 000000000000..d5c2079a3064 --- /dev/null +++ b/engines/ags/engine/main/engine.h @@ -0,0 +1,58 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_EE_MAIN__ENGINE_H +#define __AGS_EE_MAIN__ENGINE_H + +#include "util/ini_util.h" + +const char *get_engine_name(); +const char *get_engine_version(); +void show_preload(); +void engine_init_game_settings(); +int initialize_engine(const AGS::Common::ConfigTree &startup_opts); + +struct ScreenSetup; +// Try to set new graphics mode deduced from given configuration; +// if requested mode fails, tries to find any compatible mode close to the +// requested one. +bool engine_try_set_gfxmode_any(const ScreenSetup &setup); +// Tries to switch between fullscreen and windowed mode; uses previously saved +// setup if it is available, or default settings for the new mode +bool engine_try_switch_windowed_gfxmode(); +// Shutdown graphics mode (used before shutting down tha application) +void engine_shutdown_gfxmode(); + +using AGS::Common::String; +// Defines a package file location +struct PackLocation +{ + String Name; // filename, for the reference or to use as an ID + String Path; // full path +}; +// Game resource paths +struct ResourcePaths +{ + String DataDir; // path to the data directory + PackLocation GamePak; // main game package + PackLocation AudioPak; // audio package + PackLocation SpeechPak; // voice-over package +}; +extern ResourcePaths ResPaths; + +// Register a callback that will be called before engine is initialised. +// Used for apps to register their own plugins and other configuration +typedef void (*t_engine_pre_init_callback)(void); +extern void engine_set_pre_init_callback(t_engine_pre_init_callback callback); + +#endif // __AGS_EE_MAIN__ENGINE_H diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp new file mode 100644 index 000000000000..ba9780030da4 --- /dev/null +++ b/engines/ags/engine/main/engine_setup.cpp @@ -0,0 +1,367 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" +#include "ac/common.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/game_version.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/mouse.h" +#include "ac/runtime_defines.h" +#include "ac/walkbehind.h" +#include "ac/dynobj/scriptsystem.h" +#include "debug/out.h" +#include "device/mousew32.h" +#include "font/fonts.h" +#include "gfx/ali3dexception.h" +#include "gfx/graphicsdriver.h" +#include "gui/guimain.h" +#include "gui/guiinv.h" +#include "main/graphics_mode.h" +#include "main/engine_setup.h" +#include "media/video/video.h" +#include "platform/base/agsplatformdriver.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern ScriptSystem scsystem; +extern int _places_r, _places_g, _places_b; +extern IGraphicsDriver *gfxDriver; + +int convert_16bit_bgr = 0; + +// Convert guis position and size to proper game resolution. +// Necessary for pre 3.1.0 games only to sync with modern engine. +void convert_gui_to_game_resolution(GameDataVersion filever) +{ + if (filever > kGameVersion_310) + return; + + const int mul = game.GetDataUpscaleMult(); + for (int i = 0; i < game.numcursors; ++i) + { + game.mcurs[i].hotx *= mul; + game.mcurs[i].hoty *= mul; + } + + for (int i = 0; i < game.numinvitems; ++i) + { + game.invinfo[i].hotx *= mul; + game.invinfo[i].hoty *= mul; + } + + for (int i = 0; i < game.numgui; ++i) + { + GUIMain*cgp = &guis[i]; + cgp->X *= mul; + cgp->Y *= mul; + if (cgp->Width < 1) + cgp->Width = 1; + if (cgp->Height < 1) + cgp->Height = 1; + // This is probably a way to fix GUIs meant to be covering whole screen + if (cgp->Width == game.GetDataRes().Width - 1) + cgp->Width = game.GetDataRes().Width; + + cgp->Width *= mul; + cgp->Height *= mul; + + cgp->PopupAtMouseY *= mul; + + for (int j = 0; j < cgp->GetControlCount(); ++j) + { + GUIObject *guio = cgp->GetControl(j); + guio->X *= mul; + guio->Y *= mul; + guio->Width *= mul; + guio->Height *= mul; + guio->IsActivated = false; + guio->OnResized(); + } + } +} + +// Convert certain coordinates to data resolution (only if it's different from game resolution). +// Necessary for 3.1.0 and above games with legacy "low-res coordinates" setting. +void convert_objects_to_data_resolution(GameDataVersion filever) +{ + if (filever < kGameVersion_310 || game.GetDataUpscaleMult() == 1) + return; + + const int mul = game.GetDataUpscaleMult(); + for (int i = 0; i < game.numcharacters; ++i) + { + game.chars[i].x /= mul; + game.chars[i].y /= mul; + } + + for (int i = 0; i < numguiinv; ++i) + { + guiinv[i].ItemWidth /= mul; + guiinv[i].ItemHeight /= mul; + guiinv[i].OnResized(); + } +} + +void engine_setup_system_gamesize() +{ + scsystem.width = game.GetGameRes().Width; + scsystem.height = game.GetGameRes().Height; + scsystem.viewport_width = game_to_data_coord(play.GetMainViewport().GetWidth()); + scsystem.viewport_height = game_to_data_coord(play.GetMainViewport().GetHeight()); +} + +void engine_init_resolution_settings(const Size game_size) +{ + Debug::Printf("Initializing resolution settings"); + usetup.textheight = getfontheight_outlined(0) + 1; + + Debug::Printf(kDbgMsg_Info, "Game native resolution: %d x %d (%d bit)%s", game_size.Width, game_size.Height, game.color_depth * 8, + game.IsLegacyLetterbox() ? " letterbox-by-design" : ""); + + convert_gui_to_game_resolution(loaded_game_file_version); + convert_objects_to_data_resolution(loaded_game_file_version); + + Rect viewport = RectWH(game_size); + play.SetMainViewport(viewport); + play.SetUIViewport(viewport); + engine_setup_system_gamesize(); +} + +// Setup gfx driver callbacks and options +void engine_post_gfxmode_driver_setup() +{ + gfxDriver->SetCallbackForPolling(update_polled_stuff_if_runtime); + gfxDriver->SetCallbackToDrawScreen(draw_game_screen_callback, construct_engine_overlay); + gfxDriver->SetCallbackForNullSprite(GfxDriverNullSpriteCallback); +} + +// Reset gfx driver callbacks +void engine_pre_gfxmode_driver_cleanup() +{ + gfxDriver->SetCallbackForPolling(nullptr); + gfxDriver->SetCallbackToDrawScreen(nullptr, nullptr); + gfxDriver->SetCallbackForNullSprite(nullptr); + gfxDriver->SetMemoryBackBuffer(nullptr); +} + +// Setup virtual screen +void engine_post_gfxmode_screen_setup(const DisplayMode &dm, bool recreate_bitmaps) +{ + if (recreate_bitmaps) + { + // TODO: find out if + // - we need to support this case at all; + // - if yes then which bitmaps need to be recreated (probably only video bitmaps and textures?) + } +} + +void engine_pre_gfxmode_screen_cleanup() +{ +} + +// Release virtual screen +void engine_pre_gfxsystem_screen_destroy() +{ +} + +// Setup color conversion parameters +void engine_setup_color_conversions(int coldepth) +{ + // default shifts for how we store the sprite data1 + _rgb_r_shift_32 = 16; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 0; + _rgb_r_shift_16 = 11; + _rgb_g_shift_16 = 5; + _rgb_b_shift_16 = 0; + _rgb_r_shift_15 = 10; + _rgb_g_shift_15 = 5; + _rgb_b_shift_15 = 0; + + // Most cards do 5-6-5 RGB, which is the format the files are saved in + // Some do 5-6-5 BGR, or 6-5-5 RGB, in which case convert the gfx + if ((coldepth == 16) && ((_rgb_b_shift_16 != 0) || (_rgb_r_shift_16 != 11))) + { + convert_16bit_bgr = 1; + if (_rgb_r_shift_16 == 10) { + // some very old graphics cards lie about being 16-bit when they + // are in fact 15-bit ... get around this + _places_r = 3; + _places_g = 3; + } + } + if (coldepth > 16) + { + // when we're using 32-bit colour, it converts hi-color images + // the wrong way round - so fix that + +#if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID + _rgb_b_shift_16 = 0; + _rgb_g_shift_16 = 5; + _rgb_r_shift_16 = 11; + + _rgb_b_shift_15 = 0; + _rgb_g_shift_15 = 5; + _rgb_r_shift_15 = 10; + + _rgb_r_shift_32 = 0; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 16; +#else + _rgb_r_shift_16 = 11; + _rgb_g_shift_16 = 5; + _rgb_b_shift_16 = 0; +#endif + } + else if (coldepth == 16) + { + // ensure that any 32-bit graphics displayed are converted + // properly to the current depth + _rgb_r_shift_32 = 16; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 0; + } + else if (coldepth < 16) + { + // ensure that any 32-bit graphics displayed are converted + // properly to the current depth +#if AGS_PLATFORM_OS_WINDOWS + _rgb_r_shift_32 = 16; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 0; +#else + _rgb_r_shift_32 = 0; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 16; + + _rgb_b_shift_15 = 0; + _rgb_g_shift_15 = 5; + _rgb_r_shift_15 = 10; +#endif + } + + set_color_conversion(COLORCONV_MOST | COLORCONV_EXPAND_256); +} + +// Setup drawing modes and color conversions; +// they depend primarily on gfx driver capabilities and new color depth +void engine_post_gfxmode_draw_setup(const DisplayMode &dm) +{ + engine_setup_color_conversions(dm.ColorDepth); + init_draw_method(); +} + +// Cleanup auxiliary drawing objects +void engine_pre_gfxmode_draw_cleanup() +{ + dispose_draw_method(); +} + +// Setup mouse control mode and graphic area +void engine_post_gfxmode_mouse_setup(const DisplayMode &dm, const Size &init_desktop) +{ + // Assign mouse control parameters. + // + // NOTE that we setup speed and other related properties regardless of + // whether mouse control was requested because it may be enabled later. + Mouse::SetSpeedUnit(1.f); + if (usetup.mouse_speed_def == kMouseSpeed_CurrentDisplay) + { + Size cur_desktop; + if (get_desktop_resolution(&cur_desktop.Width, &cur_desktop.Height) == 0) + Mouse::SetSpeedUnit(Math::Max((float)cur_desktop.Width / (float)init_desktop.Width, + (float)cur_desktop.Height / (float)init_desktop.Height)); + } + + Mouse_EnableControl(usetup.mouse_ctrl_enabled); + Debug::Printf(kDbgMsg_Info, "Mouse control: %s, base: %f, speed: %f", Mouse::IsControlEnabled() ? "on" : "off", + Mouse::GetSpeedUnit(), Mouse::GetSpeed()); + + on_coordinates_scaling_changed(); + + // If auto lock option is set, lock mouse to the game window + if (usetup.mouse_auto_lock && scsystem.windowed != 0) + Mouse::TryLockToWindow(); +} + +// Reset mouse controls before changing gfx mode +void engine_pre_gfxmode_mouse_cleanup() +{ + // Always disable mouse control and unlock mouse when releasing down gfx mode + Mouse::DisableControl(); + Mouse::UnlockFromWindow(); +} + +// Fill in scsystem struct with display mode parameters +void engine_setup_scsystem_screen(const DisplayMode &dm) +{ + scsystem.coldepth = dm.ColorDepth; + scsystem.windowed = dm.Windowed; + scsystem.vsync = dm.Vsync; +} + +void engine_post_gfxmode_setup(const Size &init_desktop) +{ + DisplayMode dm = gfxDriver->GetDisplayMode(); + // If color depth has changed (or graphics mode was inited for the + // very first time), we also need to recreate bitmaps + bool has_driver_changed = scsystem.coldepth != dm.ColorDepth; + + engine_setup_scsystem_screen(dm); + engine_post_gfxmode_driver_setup(); + engine_post_gfxmode_screen_setup(dm, has_driver_changed); + if (has_driver_changed) + engine_post_gfxmode_draw_setup(dm); + engine_post_gfxmode_mouse_setup(dm, init_desktop); + + // TODO: the only reason this call was put here is that it requires + // "windowed" flag to be specified. Find out whether this function + // has anything to do with graphics mode at all. It is quite possible + // that we may split it into two functions, or remove parameter. + platform->PostAllegroInit(scsystem.windowed != 0); + + video_on_gfxmode_changed(); + invalidate_screen(); +} + +void engine_pre_gfxmode_release() +{ + engine_pre_gfxmode_mouse_cleanup(); + engine_pre_gfxmode_driver_cleanup(); + engine_pre_gfxmode_screen_cleanup(); +} + +void engine_pre_gfxsystem_shutdown() +{ + engine_pre_gfxmode_release(); + engine_pre_gfxmode_draw_cleanup(); + engine_pre_gfxsystem_screen_destroy(); +} + +void on_coordinates_scaling_changed() +{ + // Reset mouse graphic area and bounds + Mouse::SetGraphicArea(); + // If mouse bounds do not have valid values yet, then limit cursor to viewport + if (play.mboundx1 == 0 && play.mboundy1 == 0 && play.mboundx2 == 0 && play.mboundy2 == 0) + Mouse::SetMoveLimit(play.GetMainViewport()); + else + Mouse::SetMoveLimit(Rect(play.mboundx1, play.mboundy1, play.mboundx2, play.mboundy2)); +} diff --git a/engines/ags/engine/main/engine_setup.h b/engines/ags/engine/main/engine_setup.h new file mode 100644 index 000000000000..ad5e6fa4078b --- /dev/null +++ b/engines/ags/engine/main/engine_setup.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_EE_MAIN__ENGINESETUP_H +#define __AGS_EE_MAIN__ENGINESETUP_H + +#include "util/geometry.h" +#include "gfx/gfxdefines.h" + +// Sets up game viewport and object scaling parameters depending on game. +// TODO: this is part of the game init, not engine init, move it later +void engine_init_resolution_settings(const Size game_size); +// Setup engine after the graphics mode has changed +void engine_post_gfxmode_setup(const Size &init_desktop); +// Prepare engine for graphics mode release; could be called before switching display mode too +void engine_pre_gfxmode_release(); +// Prepare engine to the graphics mode shutdown and gfx driver destruction +void engine_pre_gfxsystem_shutdown(); +// Applies necessary changes after screen<->virtual coordinate transformation has changed +void on_coordinates_scaling_changed(); + +#endif // __AGS_EE_MAIN__ENGINESETUP_H diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp new file mode 100644 index 000000000000..82973f510266 --- /dev/null +++ b/engines/ags/engine/main/game_file.cpp @@ -0,0 +1,161 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Game data file management +// + +#include "main/mainheader.h" +#include "main/game_file.h" +#include "ac/common.h" +#include "ac/character.h" +#include "ac/charactercache.h" +#include "ac/dialogtopic.h" +#include "ac/draw.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/gamestructdefines.h" +#include "ac/gui.h" +#include "ac/viewframe.h" +#include "debug/debug_log.h" +#include "debug/out.h" +#include "gui/guilabel.h" +#include "main/main.h" +#include "platform/base/agsplatformdriver.h" +#include "util/stream.h" +#include "gfx/bitmap.h" +#include "gfx/blender.h" +#include "core/assetmanager.h" +#include "util/alignedstream.h" +#include "ac/gamesetup.h" +#include "game/main_game_file.h" +#include "game/game_init.h" +#include "plugin/agsplugin.h" +#include "script/script.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern int ifacepopped; + +extern GameSetupStruct game; +extern ViewStruct*views; +extern DialogTopic *dialog; + +extern AGSPlatformDriver *platform; +extern int numScriptModules; + + +// Test if engine supports extended capabilities required to run the game +bool test_game_caps(const std::set &caps, std::set &failed_caps) +{ + // Currently we support nothing special + failed_caps = caps; + return caps.size() == 0; +} + +// Forms a simple list of capability names +String get_caps_list(const std::set &caps) +{ + String caps_list; + for (std::set::const_iterator it = caps.begin(); it != caps.end(); ++it) + { + caps_list.Append("\n\t"); + caps_list.Append(*it); + } + return caps_list; +} + +// Called when the game file is opened for the first time (when preloading game data); +// it logs information on data version and reports first found errors, if any. +HGameFileError game_file_first_open(MainGameSource &src) +{ + HGameFileError err = OpenMainGameFileFromDefaultAsset(src); + if (err || + err->Code() == kMGFErr_SignatureFailed || + err->Code() == kMGFErr_FormatVersionTooOld || + err->Code() == kMGFErr_FormatVersionNotSupported) + { + // Log data description for debugging + Debug::Printf(kDbgMsg_Info, "Opened game data file: %s", src.Filename.GetCStr()); + Debug::Printf(kDbgMsg_Info, "Game data version: %d", src.DataVersion); + Debug::Printf(kDbgMsg_Info, "Compiled with: %s", src.CompiledWith.GetCStr()); + if (src.Caps.size() > 0) + { + String caps_list = get_caps_list(src.Caps); + Debug::Printf(kDbgMsg_Info, "Requested engine caps: %s", caps_list.GetCStr()); + } + } + // Quit in case of error + if (!err) + return err; + + // Test the extended caps + std::set failed_caps; + if (!test_game_caps(src.Caps, failed_caps)) + { + String caps_list = get_caps_list(failed_caps); + return new MainGameFileError(kMGFErr_CapsNotSupported, String::FromFormat("Missing engine caps: %s", caps_list.GetCStr())); + } + return HGameFileError::None(); +} + +void PreReadSaveFileInfo(Stream *in, GameDataVersion data_ver) +{ + AlignedStream align_s(in, Common::kAligned_Read); + game.ReadFromFile(&align_s); + // Discard game messages we do not need here + delete [] game.load_messages; + game.load_messages = nullptr; + game.read_savegame_info(in, data_ver); +} + +HError preload_game_data() +{ + MainGameSource src; + HGameFileError err = game_file_first_open(src); + if (!err) + return (HError)err; + // Read only the particular data we need for preliminary game analysis + PreReadSaveFileInfo(src.InputStream.get(), src.DataVersion); + game.compiled_with = src.CompiledWith; + FixupSaveDirectory(game); + return HError::None(); +} + +HError load_game_file() +{ + MainGameSource src; + LoadedGameEntities ents(game, dialog, views); + HGameFileError load_err = OpenMainGameFileFromDefaultAsset(src); + if (load_err) + { + load_err = ReadGameData(ents, src.InputStream.get(), src.DataVersion); + if (load_err) + load_err = UpdateGameData(ents, src.DataVersion); + } + if (!load_err) + return (HError)load_err; + HGameInitError init_err = InitGameState(ents, src.DataVersion); + if (!init_err) + return (HError)init_err; + return HError::None(); +} + +void display_game_file_error(HError err) +{ + platform->DisplayAlert("Loading game failed with error:\n%s.\n\nThe game files may be incomplete, corrupt or from unsupported version of AGS.", + err->FullMessage().GetCStr()); +} diff --git a/engines/ags/engine/main/game_file.h b/engines/ags/engine/main/game_file.h new file mode 100644 index 000000000000..d0a50a7c6c94 --- /dev/null +++ b/engines/ags/engine/main/game_file.h @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__GAMEFILE_H +#define __AGS_EE_MAIN__GAMEFILE_H + +#include "util/error.h" +#include "util/string.h" + +using AGS::Common::HError; + +// Preload particular game-describing parameters from the game data header (title, save game dir name, etc) +HError preload_game_data(); +// Loads game data and reinitializes the game state; assigns error message in case of failure +HError load_game_file(); +void display_game_file_error(HError err); + +#endif // __AGS_EE_MAIN__GAMEFILE_H diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp new file mode 100644 index 000000000000..173d2db1803a --- /dev/null +++ b/engines/ags/engine/main/game_run.cpp @@ -0,0 +1,1050 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Game loop +// + +#include +#include +#include "ac/common.h" +#include "ac/characterextras.h" +#include "ac/characterinfo.h" +#include "ac/draw.h" +#include "ac/event.h" +#include "ac/game.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_debug.h" +#include "ac/global_display.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/global_region.h" +#include "ac/gui.h" +#include "ac/hotspot.h" +#include "ac/keycode.h" +#include "ac/mouse.h" +#include "ac/overlay.h" +#include "ac/sys_events.h" +#include "ac/room.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "debug/debugger.h" +#include "debug/debug_log.h" +#include "gui/guiinv.h" +#include "gui/guimain.h" +#include "gui/guitextbox.h" +#include "main/mainheader.h" +#include "main/engine.h" +#include "main/game_run.h" +#include "main/update.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "script/script.h" +#include "ac/spritecache.h" +#include "media/audio/audio_system.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/timer.h" +#include "ac/keycode.h" + +using namespace AGS::Common; + +extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; +extern int numAnimButs; +extern int mouse_on_iface; // mouse cursor is over this interface +extern int ifacepopped; +extern int is_text_overlay; +extern volatile char want_exit, abort_engine; +extern int proper_exit,our_eip; +extern int displayed_room, starting_room, in_new_room, new_room_was; +extern GameSetupStruct game; +extern RoomStruct thisroom; +extern int game_paused; +extern int getloctype_index; +extern int in_enters_screen,done_es_error; +extern int in_leaves_screen; +extern int inside_script,in_graph_script; +extern int no_blocking_functions; +extern CharacterInfo*playerchar; +extern GameState play; +extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; +extern int cur_mode; +extern RoomObject*objs; +extern char noWalkBehindsAtAll; +extern RoomStatus*croom; +extern CharacterExtras *charextra; +extern SpriteCache spriteset; +extern int cur_mode,cur_cursor; + +// Checks if user interface should remain disabled for now +static int ShouldStayInWaitMode(); + +static int numEventsAtStartOfFunction; +static auto t1 = AGS_Clock::now(); // timer for FPS // ... 't1'... how very appropriate.. :) + +#define UNTIL_ANIMEND 1 +#define UNTIL_MOVEEND 2 +#define UNTIL_CHARIS0 3 +#define UNTIL_NOOVERLAY 4 +#define UNTIL_NEGATIVE 5 +#define UNTIL_INTIS0 6 +#define UNTIL_SHORTIS0 7 +#define UNTIL_INTISNEG 8 + +// Following 3 parameters instruct the engine to run game loops until +// certain condition is not fullfilled. +static int restrict_until=0; +static int user_disabled_for = 0; +static const void *user_disabled_data = nullptr; + +unsigned int loopcounter=0; +static unsigned int lastcounter=0; + +static void ProperExit() +{ + want_exit = 0; + proper_exit = 1; + quit("||exit!"); +} + +static void game_loop_check_problems_at_start() +{ + if ((in_enters_screen != 0) & (displayed_room == starting_room)) + quit("!A text script run in the Player Enters Screen event caused the\n" + "screen to be updated. If you need to use Wait(), do so in After Fadein"); + if ((in_enters_screen != 0) && (done_es_error == 0)) { + debug_script_warn("Wait() was used in Player Enters Screen - use Enters Screen After Fadein instead"); + done_es_error = 1; + } + if (no_blocking_functions) + quit("!A blocking function was called from within a non-blocking event such as " REP_EXEC_ALWAYS_NAME); +} + +static void game_loop_check_new_room() +{ + if (in_new_room == 0) { + // Run the room and game script repeatedly_execute + run_function_on_non_blocking_thread(&repExecAlways); + setevent(EV_TEXTSCRIPT,TS_REPEAT); + setevent(EV_RUNEVBLOCK,EVB_ROOM,0,6); + } + // run this immediately to make sure it gets done before fade-in + // (player enters screen) + check_new_room (); +} + +static void game_loop_do_late_update() +{ + if (in_new_room == 0) + { + // Run the room and game script late_repeatedly_execute + run_function_on_non_blocking_thread(&lateRepExecAlways); + } +} + +static int game_loop_check_ground_level_interactions() +{ + if ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0) { + // check if he's standing on a hotspot + int hotspotThere = get_hotspot_at(playerchar->x, playerchar->y); + // run Stands on Hotspot event + setevent(EV_RUNEVBLOCK, EVB_HOTSPOT, hotspotThere, 0); + + // check current region + int onRegion = GetRegionIDAtRoom(playerchar->x, playerchar->y); + int inRoom = displayed_room; + + if (onRegion != play.player_on_region) { + // we need to save this and set play.player_on_region + // now, so it's correct going into RunRegionInteraction + int oldRegion = play.player_on_region; + + play.player_on_region = onRegion; + // Walks Off last region + if (oldRegion > 0) + RunRegionInteraction (oldRegion, 2); + // Walks Onto new region + if (onRegion > 0) + RunRegionInteraction (onRegion, 1); + } + if (play.player_on_region > 0) // player stands on region + RunRegionInteraction (play.player_on_region, 0); + + // one of the region interactions sent us to another room + if (inRoom != displayed_room) { + check_new_room(); + } + + // if in a Wait loop which is no longer valid (probably + // because the Region interaction did a NewRoom), abort + // the rest of the loop + if ((restrict_until) && (!ShouldStayInWaitMode())) { + // cancel the Rep Exec and Stands on Hotspot events that + // we just added -- otherwise the event queue gets huge + numevents = numEventsAtStartOfFunction; + return 0; + } + } // end if checking ground level interactions + + return RETURN_CONTINUE; +} + +static void lock_mouse_on_click() +{ + if (usetup.mouse_auto_lock && scsystem.windowed) + Mouse::TryLockToWindow(); +} + +static void toggle_mouse_lock() +{ + if (scsystem.windowed) + { + if (Mouse::IsLockedToWindow()) + Mouse::UnlockFromWindow(); + else + Mouse::TryLockToWindow(); + } +} + +// Runs default mouse button handling +static void check_mouse_controls() +{ + int mongu=-1; + + mongu = gui_on_mouse_move(); + + mouse_on_iface=mongu; + if ((ifacepopped>=0) && (mousey>=guis[ifacepopped].Y+guis[ifacepopped].Height)) + remove_popup_interface(ifacepopped); + + // check mouse clicks on GUIs + static int wasbutdown=0,wasongui=0; + + if ((wasbutdown>0) && (ags_misbuttondown(wasbutdown-1))) { + gui_on_mouse_hold(wasongui, wasbutdown); + } + else if ((wasbutdown>0) && (!ags_misbuttondown(wasbutdown-1))) { + gui_on_mouse_up(wasongui, wasbutdown); + wasbutdown=0; + } + + int mbut = NONE; + int mwheelz = 0; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) { + + check_skip_cutscene_mclick(mbut); + + if (play.fast_forward || play.IsIgnoringInput()) { /* do nothing if skipping cutscene or input disabled */ } + else if ((play.wait_counter != 0) && (play.key_skip_wait & SKIP_MOUSECLICK) != 0) { + play.wait_counter = 0; + play.wait_skipped_by = SKIP_MOUSECLICK; + play.wait_skipped_by_data = mbut; + } + else if (is_text_overlay > 0) { + if (play.cant_skip_speech & SKIP_MOUSECLICK) + remove_screen_overlay(OVER_TEXTMSG); + } + else if (!IsInterfaceEnabled()) ; // blocking cutscene, ignore mouse + else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut+1)) { + // plugin took the click + debug_script_log("Plugin handled mouse button %d", mbut+1); + } + else if (mongu>=0) { + if (wasbutdown==0) { + gui_on_mouse_down(mongu, mbut+1); + } + wasongui=mongu; + wasbutdown=mbut+1; + } + else setevent(EV_TEXTSCRIPT,TS_MCLICK,mbut+1); + // else RunTextScriptIParam(gameinst,"on_mouse_click",aa+1); + } + + if (mwheelz < 0) + setevent (EV_TEXTSCRIPT, TS_MCLICK, 9); + else if (mwheelz > 0) + setevent (EV_TEXTSCRIPT, TS_MCLICK, 8); +} + +// Returns current key modifiers; +// NOTE: annoyingly enough, on Windows (not sure about other platforms) +// Allegro API's 'key_shifts' variable seem to be always one step behind real +// situation: if first modifier gets pressed, 'key_shifts' will be zero, +// when second modifier gets pressed it will only contain first one, and so on. +static int get_active_shifts() +{ + int shifts = 0; + if (key[KEY_LSHIFT] || key[KEY_RSHIFT]) + shifts |= KB_SHIFT_FLAG; + if (key[KEY_LCONTROL] || key[KEY_RCONTROL]) + shifts |= KB_CTRL_FLAG; + if (key[KEY_ALT] || key[KEY_ALTGR]) + shifts |= KB_ALT_FLAG; + return shifts; +} + +// Special flags to OR saved shift flags with: +// Shifts key combination already fired (wait until full shifts release) +#define KEY_SHIFTS_FIRED 0x80000000 + +// Runs service key controls, returns false if service key combinations were handled +// and no more processing required, otherwise returns true and provides current keycode and key shifts. +bool run_service_key_controls(int &kgn) +{ + // check keypresses + static int old_key_shifts = 0; // for saving shift modes + + bool handled = false; + int kbhit_res = ags_kbhit(); + // First, check shifts + const int act_shifts = get_active_shifts(); + // If shifts combination have already triggered an action, then do nothing + // until new shifts are empty, in which case reset saved shifts + if (old_key_shifts & KEY_SHIFTS_FIRED) + { + if (act_shifts == 0) + old_key_shifts = 0; + } + else + { + // If any non-shift key is pressed, add fired flag to indicate that + // this is no longer a pure shifts key combination + if (kbhit_res) + { + old_key_shifts = act_shifts | KEY_SHIFTS_FIRED; + } + // If all the previously registered shifts are still pressed, + // then simply resave new shift state. + else if ((old_key_shifts & act_shifts) == old_key_shifts) + { + old_key_shifts = act_shifts; + } + // Otherwise some of the shifts were released, then run key combo action + // and set KEY_COMBO_FIRED flag to prevent multiple execution + else if (old_key_shifts) + { + // Toggle mouse lock on Ctrl + Alt + if (old_key_shifts == (KB_ALT_FLAG | KB_CTRL_FLAG)) + { + toggle_mouse_lock(); + handled = true; + } + old_key_shifts |= KEY_SHIFTS_FIRED; + } + } + + if (!kbhit_res || handled) + return false; + + int keycode = ags_getch(); + // NS: I'm still not sure why we read a second key. + // Perhaps it's of a time when we read the keyboard one byte at a time? + // if (keycode == 0) + // keycode = ags_getch() + AGS_EXT_KEY_SHIFT; + if (keycode == 0) + return false; + + // LAlt or RAlt + Enter + // NOTE: for some reason LAlt + Enter produces same code as F9 + if (act_shifts == KB_ALT_FLAG && ((keycode == eAGSKeyCodeF9 && !key[KEY_F9]) || keycode == eAGSKeyCodeReturn)) + { + engine_try_switch_windowed_gfxmode(); + return false; + } + + // No service operation triggered? return active keypress and shifts to caller + kgn = keycode; + return true; +} + +bool run_service_mb_controls(int &mbut, int &mwheelz) +{ + int mb = ags_mgetbutton(); + int mz = ags_check_mouse_wheel(); + if (mb == NONE && mz == 0) + return false; + lock_mouse_on_click(); // do not claim + mbut = mb; + mwheelz = mz; + return true; +} + +// Runs default keyboard handling +static void check_keyboard_controls() +{ + // First check for service engine's combinations (mouse lock, display mode switch, and so forth) + int kgn; + if (!run_service_key_controls(kgn)) { + return; + } + // Then, check cutscene skip + check_skip_cutscene_keypress(kgn); + if (play.fast_forward) { + return; + } + if (play.IsIgnoringInput()) { + return; + } + // Now check for in-game controls + if (pl_run_plugin_hooks(AGSE_KEYPRESS, kgn)) { + // plugin took the keypress + debug_script_log("Keypress code %d taken by plugin", kgn); + return; + } + + // debug console + if ((kgn == '`') && (play.debug_mode > 0)) { + display_console = !display_console; + return; + } + + // skip speech if desired by Speech.SkipStyle + if ((is_text_overlay > 0) && (play.cant_skip_speech & SKIP_KEYPRESS)) { + // only allow a key to remove the overlay if the icon bar isn't up + if (IsGamePaused() == 0) { + // check if it requires a specific keypress + if ((play.skip_speech_specific_key > 0) && + (kgn != play.skip_speech_specific_key)) { } + else + remove_screen_overlay(OVER_TEXTMSG); + } + + return; + } + + if ((play.wait_counter != 0) && (play.key_skip_wait & SKIP_KEYPRESS) != 0) { + play.wait_counter = 0; + play.wait_skipped_by = SKIP_KEYPRESS; + play.wait_skipped_by_data = kgn; + debug_script_log("Keypress code %d ignored - in Wait", kgn); + return; + } + + if ((kgn == eAGSKeyCodeCtrlE) && (display_fps == kFPS_Forced)) { + // if --fps paramter is used, Ctrl+E will max out frame rate + setTimerFps( isTimerFpsMaxed() ? frames_per_second : 1000 ); + return; + } + + if ((kgn == eAGSKeyCodeCtrlD) && (play.debug_mode > 0)) { + // ctrl+D - show info + char infobuf[900]; + int ff; + // MACPORT FIX 9/6/5: added last %s + sprintf(infobuf,"In room %d %s[Player at %d, %d (view %d, loop %d, frame %d)%s%s%s", + displayed_room, (noWalkBehindsAtAll ? "(has no walk-behinds)" : ""), playerchar->x,playerchar->y, + playerchar->view + 1, playerchar->loop,playerchar->frame, + (IsGamePaused() == 0) ? "" : "[Game paused.", + (play.ground_level_areas_disabled == 0) ? "" : "[Ground areas disabled.", + (IsInterfaceEnabled() == 0) ? "[Game in Wait state" : ""); + for (ff=0;ffnumobj;ff++) { + if (ff >= 8) break; // buffer not big enough for more than 7 + sprintf(&infobuf[strlen(infobuf)], + "[Object %d: (%d,%d) size (%d x %d) on:%d moving:%s animating:%d slot:%d trnsp:%d clkble:%d", + ff, objs[ff].x, objs[ff].y, + (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Width : 0, + (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Height : 0, + objs[ff].on, + (objs[ff].moving > 0) ? "yes" : "no", objs[ff].cycling, + objs[ff].num, objs[ff].transparent, + ((objs[ff].flags & OBJF_NOINTERACT) != 0) ? 0 : 1 ); + } + Display(infobuf); + int chd = game.playercharacter; + char bigbuffer[STD_BUFFER_SIZE] = "CHARACTERS IN THIS ROOM:["; + for (ff = 0; ff < game.numcharacters; ff++) { + if (game.chars[ff].room != displayed_room) continue; + if (strlen(bigbuffer) > 430) { + strcat(bigbuffer, "and more..."); + Display(bigbuffer); + strcpy(bigbuffer, "CHARACTERS IN THIS ROOM (cont'd):["); + } + chd = ff; + sprintf(&bigbuffer[strlen(bigbuffer)], + "%s (view/loop/frm:%d,%d,%d x/y/z:%d,%d,%d idleview:%d,time:%d,left:%d walk:%d anim:%d follow:%d flags:%X wait:%d zoom:%d)[", + game.chars[chd].scrname, game.chars[chd].view+1, game.chars[chd].loop, game.chars[chd].frame, + game.chars[chd].x, game.chars[chd].y, game.chars[chd].z, + game.chars[chd].idleview, game.chars[chd].idletime, game.chars[chd].idleleft, + game.chars[chd].walking, game.chars[chd].animating, game.chars[chd].following, + game.chars[chd].flags, game.chars[chd].wait, charextra[chd].zoom); + } + Display(bigbuffer); + + return; + } + + // if (kgn == key_ctrl_u) { + // play.debug_mode++; + // script_debug(5,0); + // play.debug_mode--; + // return; + // } + + if ((kgn == eAGSKeyCodeAltV) && (key[KEY_LCONTROL] || key[KEY_RCONTROL]) && (play.wait_counter < 1) && (is_text_overlay == 0) && (restrict_until == 0)) { + // make sure we can't interrupt a Wait() + // and desync the music to cutscene + play.debug_mode++; + script_debug (1,0); + play.debug_mode--; + + return; + } + + if (inside_script) { + // Don't queue up another keypress if it can't be run instantly + debug_script_log("Keypress %d ignored (game blocked)", kgn); + return; + } + + int keywasprocessed = 0; + + // determine if a GUI Text Box should steal the click + // it should do if a displayable character (32-255) is + // pressed, but exclude control characters (<32) and + // extended keys (eg. up/down arrow; 256+) + if ( (((kgn >= 32) && (kgn <= 255) && (kgn != '[')) || (kgn == eAGSKeyCodeReturn) || (kgn == eAGSKeyCodeBackspace)) + && !all_buttons_disabled) { + for (int guiIndex = 0; guiIndex < game.numgui; guiIndex++) { + auto &gui = guis[guiIndex]; + + if (!gui.IsDisplayed()) continue; + + for (int controlIndex = 0; controlIndex < gui.GetControlCount(); controlIndex++) { + // not a text box, ignore it + if (gui.GetControlType(controlIndex) != kGUITextBox) { continue; } + + auto *guitex = static_cast(gui.GetControl(controlIndex)); + if (guitex == nullptr) { continue; } + + // if the text box is disabled, it cannot accept keypresses + if (!guitex->IsEnabled()) { continue; } + if (!guitex->IsVisible()) { continue; } + + keywasprocessed = 1; + + guitex->OnKeyPress(kgn); + + if (guitex->IsActivated) { + guitex->IsActivated = false; + setevent(EV_IFACECLICK, guiIndex, controlIndex, 1); + } + } + } + } + + if (!keywasprocessed) { + kgn = GetKeyForKeyPressCb(kgn); + debug_script_log("Running on_key_press keycode %d", kgn); + setevent(EV_TEXTSCRIPT,TS_KEYPRESS,kgn); + } + + // RunTextScriptIParam(gameinst,"on_key_press",kgn); +} + +// check_controls: checks mouse & keyboard interface +static void check_controls() { + our_eip = 1007; + + check_mouse_controls(); + check_keyboard_controls(); +} + +static void check_room_edges(int numevents_was) +{ + if ((IsInterfaceEnabled()) && (IsGamePaused() == 0) && + (in_new_room == 0) && (new_room_was == 0)) { + // Only allow walking off edges if not in wait mode, and + // if not in Player Enters Screen (allow walking in from off-screen) + int edgesActivated[4] = {0, 0, 0, 0}; + // Only do it if nothing else has happened (eg. mouseclick) + if ((numevents == numevents_was) && + ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0)) { + + if (playerchar->x <= thisroom.Edges.Left) + edgesActivated[0] = 1; + else if (playerchar->x >= thisroom.Edges.Right) + edgesActivated[1] = 1; + if (playerchar->y >= thisroom.Edges.Bottom) + edgesActivated[2] = 1; + else if (playerchar->y <= thisroom.Edges.Top) + edgesActivated[3] = 1; + + if ((play.entered_edge >= 0) && (play.entered_edge <= 3)) { + // once the player is no longer outside the edge, forget the stored edge + if (edgesActivated[play.entered_edge] == 0) + play.entered_edge = -10; + // if we are walking in from off-screen, don't activate edges + else + edgesActivated[play.entered_edge] = 0; + } + + for (int ii = 0; ii < 4; ii++) { + if (edgesActivated[ii]) + setevent(EV_RUNEVBLOCK, EVB_ROOM, 0, ii); + } + } + } + our_eip = 1008; + +} + +static void game_loop_check_controls(bool checkControls) +{ + // don't let the player do anything before the screen fades in + if ((in_new_room == 0) && (checkControls)) { + int inRoom = displayed_room; + int numevents_was = numevents; + check_controls(); + check_room_edges(numevents_was); + // If an inventory interaction changed the room + if (inRoom != displayed_room) + check_new_room(); + } +} + +static void game_loop_do_update() +{ + if (debug_flags & DBG_NOUPDATE) ; + else if (game_paused==0) update_stuff(); +} + +static void game_loop_update_animated_buttons() +{ + // update animating GUI buttons + // this bit isn't in update_stuff because it always needs to + // happen, even when the game is paused + for (int aa = 0; aa < numAnimButs; aa++) { + if (UpdateAnimatingButton(aa)) { + StopButtonAnimation(aa); + aa--; + } + } +} + +static void game_loop_do_render_and_check_mouse(IDriverDependantBitmap *extraBitmap, int extraX, int extraY) +{ + if (!play.fast_forward) { + int mwasatx=mousex,mwasaty=mousey; + + // Only do this if we are not skipping a cutscene + render_graphics(extraBitmap, extraX, extraY); + + // Check Mouse Moves Over Hotspot event + // TODO: move this out of render related function? find out why we remember mwasatx and mwasaty before render + // TODO: do not use static variables! + // TODO: if we support rotation then we also need to compare full transform! + if (displayed_room < 0) + return; + auto view = play.GetRoomViewportAt(mousex, mousey); + auto cam = view ? view->GetCamera() : nullptr; + if (cam) + { + // NOTE: all cameras are in same room right now, so their positions are in same coordinate system; + // therefore we may use this as an indication that mouse is over different camera too. + static int offsetxWas = -1000, offsetyWas = -1000; + int offsetx = cam->GetRect().Left; + int offsety = cam->GetRect().Top; + + if (((mwasatx!=mousex) || (mwasaty!=mousey) || + (offsetxWas != offsetx) || (offsetyWas != offsety))) + { + // mouse moves over hotspot + if (__GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey), 1) == LOCTYPE_HOTSPOT) { + int onhs = getloctype_index; + + setevent(EV_RUNEVBLOCK,EVB_HOTSPOT,onhs,6); + } + } + + offsetxWas = offsetx; + offsetyWas = offsety; + } // camera found under mouse + } +} + +static void game_loop_update_events() +{ + new_room_was = in_new_room; + if (in_new_room>0) + setevent(EV_FADEIN,0,0,0); + in_new_room=0; + update_events(); + if ((new_room_was > 0) && (in_new_room == 0)) { + // if in a new room, and the room wasn't just changed again in update_events, + // then queue the Enters Screen scripts + // run these next time round, when it's faded in + if (new_room_was==2) // first time enters screen + setevent(EV_RUNEVBLOCK,EVB_ROOM,0,4); + if (new_room_was!=3) // enters screen after fadein + setevent(EV_RUNEVBLOCK,EVB_ROOM,0,7); + } +} + +static void game_loop_update_background_animation() +{ + if (play.bg_anim_delay > 0) play.bg_anim_delay--; + else if (play.bg_frame_locked) ; + else { + play.bg_anim_delay = play.anim_background_speed; + play.bg_frame++; + if ((size_t)play.bg_frame >= thisroom.BgFrameCount) + play.bg_frame=0; + if (thisroom.BgFrameCount >= 2) { + // get the new frame's palette + on_background_frame_change(); + } + } +} + +static void game_loop_update_loop_counter() +{ + loopcounter++; + + if (play.wait_counter > 0) play.wait_counter--; + if (play.shakesc_length > 0) play.shakesc_length--; + + if (loopcounter % 5 == 0) + { + update_ambient_sound_vol(); + update_directional_sound_vol(); + } +} + +static void game_loop_update_fps() +{ + auto t2 = AGS_Clock::now(); + auto duration = std::chrono::duration_cast(t2 - t1); + auto frames = loopcounter - lastcounter; + + if (duration >= std::chrono::milliseconds(1000) && frames > 0) { + fps = 1000.0f * frames / duration.count(); + t1 = t2; + lastcounter = loopcounter; + } +} + +float get_current_fps() { + // if we have maxed out framerate then return the frame rate we're seeing instead + // fps must be greater that 0 or some timings will take forever. + if (isTimerFpsMaxed() && fps > 0.0f) { + return fps; + } + return frames_per_second; +} + +void set_loop_counter(unsigned int new_counter) { + loopcounter = new_counter; + t1 = AGS_Clock::now(); + lastcounter = loopcounter; + fps = std::numeric_limits::quiet_NaN(); +} + +void UpdateGameOnce(bool checkControls, IDriverDependantBitmap *extraBitmap, int extraX, int extraY) { + + int res; + + update_polled_mp3(); + + numEventsAtStartOfFunction = numevents; + + if (want_exit) { + ProperExit(); + } + + ccNotifyScriptStillAlive (); + our_eip=1; + + game_loop_check_problems_at_start(); + + // if we're not fading in, don't count the fadeouts + if ((play.no_hicolor_fadein) && (game.options[OPT_FADETYPE] == FADE_NORMAL)) + play.screen_is_faded_out = 0; + + our_eip = 1014; + + update_gui_disabled_status(); + + our_eip = 1004; + + game_loop_check_new_room(); + + our_eip = 1005; + + res = game_loop_check_ground_level_interactions(); + if (res != RETURN_CONTINUE) { + return; + } + + mouse_on_iface=-1; + + check_debug_keys(); + + game_loop_check_controls(checkControls); + + our_eip=2; + + game_loop_do_update(); + + game_loop_update_animated_buttons(); + + game_loop_do_late_update(); + + update_audio_system_on_game_loop(); + + game_loop_do_render_and_check_mouse(extraBitmap, extraX, extraY); + + our_eip=6; + + game_loop_update_events(); + + our_eip=7; + + // if (ags_mgetbutton()>NONE) break; + update_polled_stuff_if_runtime(); + + game_loop_update_background_animation(); + + game_loop_update_loop_counter(); + + // Immediately start the next frame if we are skipping a cutscene + if (play.fast_forward) + return; + + our_eip=72; + + game_loop_update_fps(); + + update_polled_stuff_if_runtime(); + + WaitForNextFrame(); +} + +static void UpdateMouseOverLocation() +{ + // Call GetLocationName - it will internally force a GUI refresh + // if the result it returns has changed from last time + char tempo[STD_BUFFER_SIZE]; + GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + + if ((play.get_loc_name_save_cursor >= 0) && + (play.get_loc_name_save_cursor != play.get_loc_name_last_time) && + (mouse_on_iface < 0) && (ifacepopped < 0)) { + // we have saved the cursor, but the mouse location has changed + // and it's time to restore it + play.get_loc_name_save_cursor = -1; + set_cursor_mode(play.restore_cursor_mode_to); + + if (cur_mode == play.restore_cursor_mode_to) + { + // make sure it changed -- the new mode might have been disabled + // in which case don't change the image + set_mouse_cursor(play.restore_cursor_image_to); + } + debug_script_log("Restore mouse to mode %d cursor %d", play.restore_cursor_mode_to, play.restore_cursor_image_to); + } +} + +// Checks if user interface should remain disabled for now +static int ShouldStayInWaitMode() { + if (restrict_until == 0) + quit("end_wait_loop called but game not in loop_until state"); + int retval = restrict_until; + + if (restrict_until==UNTIL_MOVEEND) { + short*wkptr=(short*)user_disabled_data; + if (wkptr[0]<1) retval=0; + } + else if (restrict_until==UNTIL_CHARIS0) { + char*chptr=(char*)user_disabled_data; + if (chptr[0]==0) retval=0; + } + else if (restrict_until==UNTIL_NEGATIVE) { + short*wkptr=(short*)user_disabled_data; + if (wkptr[0]<0) retval=0; + } + else if (restrict_until==UNTIL_INTISNEG) { + int*wkptr=(int*)user_disabled_data; + if (wkptr[0]<0) retval=0; + } + else if (restrict_until==UNTIL_NOOVERLAY) { + if (is_text_overlay < 1) retval=0; + } + else if (restrict_until==UNTIL_INTIS0) { + int*wkptr=(int*)user_disabled_data; + if (wkptr[0]==0) retval=0; + } + else if (restrict_until==UNTIL_SHORTIS0) { + short*wkptr=(short*)user_disabled_data; + if (wkptr[0]==0) retval=0; + } + else quit("loop_until: unknown until event"); + + return retval; +} + +static int UpdateWaitMode() +{ + if (restrict_until==0) { return RETURN_CONTINUE; } + + restrict_until = ShouldStayInWaitMode(); + our_eip = 77; + + if (restrict_until!=0) { return RETURN_CONTINUE; } + + auto was_disabled_for = user_disabled_for; + + set_default_cursor(); + guis_need_update = 1; + play.disabled_user_interface--; + user_disabled_for = 0; + + switch (was_disabled_for) { + // case FOR_ANIMATION: + // run_animation((FullAnimation*)user_disabled_data2,user_disabled_data3); + // break; + case FOR_EXITLOOP: + return -1; + case FOR_SCRIPT: + quit("err: for_script obsolete (v2.1 and earlier only)"); + break; + default: + quit("Unknown user_disabled_for in end restrict_until"); + } + + // we shouldn't get here. + return RETURN_CONTINUE; +} + +// Run single game iteration; calls UpdateGameOnce() internally +static int GameTick() +{ + if (displayed_room < 0) + quit("!A blocking function was called before the first room has been loaded"); + + UpdateGameOnce(true); + UpdateMouseOverLocation(); + + our_eip=76; + + int res = UpdateWaitMode(); + if (res == RETURN_CONTINUE) { return 0; } // continue looping + return res; +} + +static void SetupLoopParameters(int untilwhat,const void* udata) { + play.disabled_user_interface++; + guis_need_update = 1; + // Only change the mouse cursor if it hasn't been specifically changed first + // (or if it's speech, always change it) + if (((cur_cursor == cur_mode) || (untilwhat == UNTIL_NOOVERLAY)) && + (cur_mode != CURS_WAIT)) + set_mouse_cursor(CURS_WAIT); + + restrict_until=untilwhat; + user_disabled_data=udata; + user_disabled_for=FOR_EXITLOOP; +} + +// This function is called from lot of various functions +// in the game core, character, room object etc +static void GameLoopUntilEvent(int untilwhat,const void* daaa) { + // blocking cutscene - end skipping + EndSkippingUntilCharStops(); + + // this function can get called in a nested context, so + // remember the state of these vars in case a higher level + // call needs them + auto cached_restrict_until = restrict_until; + auto cached_user_disabled_data = user_disabled_data; + auto cached_user_disabled_for = user_disabled_for; + + SetupLoopParameters(untilwhat,daaa); + while (GameTick()==0); + + our_eip = 78; + + restrict_until = cached_restrict_until; + user_disabled_data = cached_user_disabled_data; + user_disabled_for = cached_user_disabled_for; +} + +void GameLoopUntilValueIsZero(const char *value) +{ + GameLoopUntilEvent(UNTIL_CHARIS0, value); +} + +void GameLoopUntilValueIsZero(const short *value) +{ + GameLoopUntilEvent(UNTIL_SHORTIS0, value); +} + +void GameLoopUntilValueIsZero(const int *value) +{ + GameLoopUntilEvent(UNTIL_INTIS0, value); +} + +void GameLoopUntilValueIsZeroOrLess(const short *value) +{ + GameLoopUntilEvent(UNTIL_MOVEEND, value); +} + +void GameLoopUntilValueIsNegative(const short *value) +{ + GameLoopUntilEvent(UNTIL_NEGATIVE, value); +} + +void GameLoopUntilValueIsNegative(const int *value) +{ + GameLoopUntilEvent(UNTIL_INTISNEG, value); +} + +void GameLoopUntilNotMoving(const short *move) +{ + GameLoopUntilEvent(UNTIL_MOVEEND, move); +} + +void GameLoopUntilNoOverlay() +{ + GameLoopUntilEvent(UNTIL_NOOVERLAY, 0); +} + + +extern unsigned int load_new_game; +void RunGameUntilAborted() +{ + // skip ticks to account for time spent starting game. + skipMissedTicks(); + + while (!abort_engine) { + GameTick(); + + if (load_new_game) { + RunAGSGame (nullptr, load_new_game, 0); + load_new_game = 0; + } + } +} + +void update_polled_stuff_if_runtime() +{ + if (want_exit) { + want_exit = 0; + quit("||exit!"); + } + + update_polled_mp3(); + + if (editor_debugging_initialized) + check_for_messages_from_editor(); +} diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h new file mode 100644 index 000000000000..450cd3ba7508 --- /dev/null +++ b/engines/ags/engine/main/game_run.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__GAMERUN_H +#define __AGS_EE_MAIN__GAMERUN_H + +namespace AGS { namespace Engine { class IDriverDependantBitmap; }} +using namespace AGS::Engine; // FIXME later + +// Loops game frames until certain event takes place (for blocking actions) +void GameLoopUntilValueIsZero(const char *value); +void GameLoopUntilValueIsZero(const short *value); +void GameLoopUntilValueIsZero(const int *value); +void GameLoopUntilValueIsZeroOrLess(const short *move); +void GameLoopUntilValueIsNegative(const short *value); +void GameLoopUntilValueIsNegative(const int *value); +void GameLoopUntilNotMoving(const short *move); +void GameLoopUntilNoOverlay(); + +// Run the actual game until it ends, or aborted by player/error; loops GameTick() internally +void RunGameUntilAborted(); +// Update everything game related +void UpdateGameOnce(bool checkControls = false, IDriverDependantBitmap *extraBitmap = nullptr, int extraX = 0, int extraY = 0); +// Gets current logical game FPS, this is normally a fixed number set in script; +// in case of "maxed fps" mode this function returns real measured FPS. +float get_current_fps(); +// Runs service key controls, returns false if key input was claimed by the engine, +// otherwise returns true and provides a keycode. +bool run_service_key_controls(int &kgn); +// Runs service mouse controls, returns false if mouse input was claimed by the engine, +// otherwise returns true and provides mouse button code. +bool run_service_mb_controls(int &mbut, int &mwheelz); + +#endif // __AGS_EE_MAIN__GAMERUN_H diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp new file mode 100644 index 000000000000..43a46cbfdd87 --- /dev/null +++ b/engines/ags/engine/main/game_start.cpp @@ -0,0 +1,159 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Game initialization +// + +#include "ac/common.h" +#include "ac/characterinfo.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_game.h" +#include "ac/mouse.h" +#include "ac/room.h" +#include "ac/screen.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "debug/out.h" +#include "gfx/ali3dexception.h" +#include "main/mainheader.h" +#include "main/game_run.h" +#include "main/game_start.h" +#include "script/script.h" +#include "media/audio/audio_system.h" +#include "ac/timer.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern int our_eip, displayed_room; +extern volatile char want_exit, abort_engine; +extern GameSetupStruct game; +extern GameState play; +extern const char *loadSaveGameOnStartup; +extern std::vector moduleInst; +extern int numScriptModules; +extern CharacterInfo*playerchar; +extern int convert_16bit_bgr; + +void start_game_init_editor_debugging() +{ + if (editor_debugging_enabled) + { + SetMultitasking(1); + if (init_editor_debugging()) + { + auto waitUntil = AGS_Clock::now() + std::chrono::milliseconds(500); + while (waitUntil > AGS_Clock::now()) + { + // pick up any breakpoints in game_start + check_for_messages_from_editor(); + } + + ccSetDebugHook(scriptDebugHook); + } + } +} + +void start_game_load_savegame_on_startup() +{ + if (loadSaveGameOnStartup != nullptr) + { + int saveGameNumber = 1000; + const char *sgName = strstr(loadSaveGameOnStartup, "agssave."); + if (sgName != nullptr) + { + sscanf(sgName, "agssave.%03d", &saveGameNumber); + } + current_fade_out_effect(); + try_restore_save(loadSaveGameOnStartup, saveGameNumber); + } +} + +void start_game() { + set_cursor_mode(MODE_WALK); + Mouse::SetPosition(Point(160, 100)); + newmusic(0); + + our_eip = -42; + + // skip ticks to account for initialisation or a restored game. + skipMissedTicks(); + + for (int kk = 0; kk < numScriptModules; kk++) + RunTextScript(moduleInst[kk], "game_start"); + + RunTextScript(gameinst, "game_start"); + + our_eip = -43; + + SetRestartPoint(); + + our_eip=-3; + + if (displayed_room < 0) { + current_fade_out_effect(); + load_new_room(playerchar->room,playerchar); + // load_new_room updates it, but it should be -1 in the first room + playerchar->prevroom = -1; + } + + first_room_initialization(); +} + +void do_start_game() +{ + // only start if replay playback hasn't loaded a game + if (displayed_room < 0) + start_game(); +} + +void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup) +{ + try { // BEGIN try for ALI3DEXception + + set_cursor_mode (MODE_WALK); + + if (convert_16bit_bgr) { + // Disable text as speech while displaying the warning message + // This happens if the user's graphics card does BGR order 16-bit colour + int oldalways = game.options[OPT_ALWAYSSPCH]; + game.options[OPT_ALWAYSSPCH] = 0; + // PSP: This is normal. Don't show a warning. + //Display ("WARNING: AGS has detected that you have an incompatible graphics card for this game. You may experience colour problems during the game. Try running the game with \"--15bit\" command line parameter and see if that helps.[[Click the mouse to continue."); + game.options[OPT_ALWAYSSPCH] = oldalways; + } + + srand (play.randseed); + if (override_start_room) + playerchar->room = override_start_room; + + Debug::Printf(kDbgMsg_Info, "Engine initialization complete"); + Debug::Printf(kDbgMsg_Info, "Starting game"); + + start_game_init_editor_debugging(); + + start_game_load_savegame_on_startup(); + + do_start_game(); + + RunGameUntilAborted(); + + } catch (Ali3DException gfxException) + { + quit((char*)gfxException._message); + } +} diff --git a/engines/ags/engine/main/game_start.h b/engines/ags/engine/main/game_start.h new file mode 100644 index 000000000000..b732e2d4c0cd --- /dev/null +++ b/engines/ags/engine/main/game_start.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__GAMESTART_H +#define __AGS_EE_MAIN__GAMESTART_H + +void start_game(); +void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup); + +#endif // __AGS_EE_MAIN__GAMESTART_H diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp new file mode 100644 index 000000000000..1c853bce8a78 --- /dev/null +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -0,0 +1,679 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Graphics initialization +// + +#include +#include "core/platform.h" +#include "ac/draw.h" +#include "debug/debugger.h" +#include "debug/out.h" +#include "gfx/ali3dexception.h" +#include "gfx/bitmap.h" +#include "gfx/gfxdriverfactory.h" +#include "gfx/gfxfilter.h" +#include "gfx/graphicsdriver.h" +#include "main/config.h" +#include "main/engine_setup.h" +#include "main/graphics_mode.h" +#include "main/main_allegro.h" +#include "platform/base/agsplatformdriver.h" + +// Don't try to figure out the window size on the mac because the port resizes itself. +#if AGS_PLATFORM_OS_MACOS || defined(ALLEGRO_SDL2) || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID +#define USE_SIMPLE_GFX_INIT +#endif + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern int proper_exit; +extern AGSPlatformDriver *platform; +extern IGraphicsDriver *gfxDriver; + + +IGfxDriverFactory *GfxFactory = nullptr; + +// Last saved fullscreen and windowed configs; they are used when switching +// between between fullscreen and windowed modes at runtime. +// If particular mode is modified, e.g. by script command, related config should be overwritten. +ActiveDisplaySetting SavedFullscreenSetting; +ActiveDisplaySetting SavedWindowedSetting; +// Current frame scaling setup +GameFrameSetup CurFrameSetup; +// The game-to-screen transformation +PlaneScaling GameScaling; + + +GameFrameSetup::GameFrameSetup() + : ScaleDef(kFrame_IntScale) + , ScaleFactor(1) +{ +} + +GameFrameSetup::GameFrameSetup(FrameScaleDefinition def, int factor) + : ScaleDef(def) + , ScaleFactor(factor) +{ +} + +bool GameFrameSetup::IsValid() const +{ + return ScaleDef != kFrame_IntScale || ScaleFactor > 0; +} + +ScreenSizeSetup::ScreenSizeSetup() + : SizeDef(kScreenDef_MaxDisplay) + , MatchDeviceRatio(true) +{ +} + +DisplayModeSetup::DisplayModeSetup() + : RefreshRate(0) + , VSync(false) + , Windowed(false) +{ +} + + +Size get_desktop_size() +{ + Size sz; + get_desktop_resolution(&sz.Width, &sz.Height); + return sz; +} + +Size get_max_display_size(bool windowed) +{ + Size device_size = get_desktop_size(); + if (windowed) + platform->ValidateWindowSize(device_size.Width, device_size.Height, false); + return device_size; +} + +bool create_gfx_driver(const String &gfx_driver_id) +{ + GfxFactory = GetGfxDriverFactory(gfx_driver_id); + if (!GfxFactory) + { + Debug::Printf(kDbgMsg_Error, "Failed to initialize %s graphics factory. Error: %s", gfx_driver_id.GetCStr(), get_allegro_error()); + return false; + } + Debug::Printf("Using graphics factory: %s", gfx_driver_id.GetCStr()); + gfxDriver = GfxFactory->GetDriver(); + if (!gfxDriver) + { + Debug::Printf(kDbgMsg_Error, "Failed to create graphics driver. Error: %s", get_allegro_error()); + return false; + } + Debug::Printf("Created graphics driver: %s", gfxDriver->GetDriverName()); + return true; +} + +// Set requested graphics filter, or default filter if the requested one failed +bool graphics_mode_set_filter_any(const GfxFilterSetup &setup) +{ + Debug::Printf("Requested gfx filter: %s", setup.UserRequest.GetCStr()); + if (!graphics_mode_set_filter(setup.ID)) + { + String def_filter = GfxFactory->GetDefaultFilterID(); + if (def_filter.CompareNoCase(setup.ID) == 0) + return false; + Debug::Printf(kDbgMsg_Error, "Failed to apply gfx filter: %s; will try to use factory default filter '%s' instead", + setup.UserRequest.GetCStr(), def_filter.GetCStr()); + if (!graphics_mode_set_filter(def_filter)) + return false; + } + Debug::Printf("Using gfx filter: %s", GfxFactory->GetDriver()->GetGraphicsFilter()->GetInfo().Id.GetCStr()); + return true; +} + +bool find_nearest_supported_mode(const IGfxModeList &modes, const Size &wanted_size, const int color_depth, + const Size *ratio_reference, const Size *upper_bound, DisplayMode &dm, int *mode_index) +{ + uint32_t wanted_ratio = 0; + if (ratio_reference && !ratio_reference->IsNull()) + { + wanted_ratio = (ratio_reference->Height << kShift) / ratio_reference->Width; + } + + int nearest_width = 0; + int nearest_height = 0; + int nearest_width_diff = 0; + int nearest_height_diff = 0; + DisplayMode nearest_mode; + int nearest_mode_index = -1; + int mode_count = modes.GetModeCount(); + for (int i = 0; i < mode_count; ++i) + { + DisplayMode mode; + if (!modes.GetMode(i, mode)) + { + continue; + } + if (mode.ColorDepth != color_depth) + { + continue; + } + if (wanted_ratio > 0) + { + uint32_t mode_ratio = (mode.Height << kShift) / mode.Width; + if (mode_ratio != wanted_ratio) + { + continue; + } + } + if (upper_bound && (mode.Width > upper_bound->Width || mode.Height > upper_bound->Height)) + continue; + if (mode.Width == wanted_size.Width && mode.Height == wanted_size.Height) + { + nearest_width = mode.Width; + nearest_height = mode.Height; + nearest_mode_index = i; + nearest_mode = mode; + break; + } + + int diff_w = abs(wanted_size.Width - mode.Width); + int diff_h = abs(wanted_size.Height - mode.Height); + bool same_diff_w_higher = (diff_w == nearest_width_diff && nearest_width < wanted_size.Width); + bool same_diff_h_higher = (diff_h == nearest_height_diff && nearest_height < wanted_size.Height); + + if (nearest_width == 0 || + ((diff_w < nearest_width_diff || same_diff_w_higher) && diff_h <= nearest_height_diff) || + ((diff_h < nearest_height_diff || same_diff_h_higher) && diff_w <= nearest_width_diff)) + { + nearest_width = mode.Width; + nearest_width_diff = diff_w; + nearest_height = mode.Height; + nearest_height_diff = diff_h; + nearest_mode = mode; + nearest_mode_index = i; + } + } + + if (nearest_width > 0 && nearest_height > 0) + { + dm = nearest_mode; + if (mode_index) + *mode_index = nearest_mode_index; + return true; + } + return false; +} + +Size set_game_frame_after_screen_size(const Size &game_size, const Size screen_size, const GameFrameSetup &setup) +{ + // Set game frame as native game resolution scaled by particular method + Size frame_size; + if (setup.ScaleDef == kFrame_MaxStretch) + { + frame_size = screen_size; + } + else if (setup.ScaleDef == kFrame_MaxProportional) + { + frame_size = ProportionalStretch(screen_size, game_size); + } + else + { + int scale; + if (setup.ScaleDef == kFrame_MaxRound) + scale = Math::Min((screen_size.Width / game_size.Width) << kShift, + (screen_size.Height / game_size.Height) << kShift); + else + scale = convert_scaling_to_fp(setup.ScaleFactor); + + // Ensure scaling factors are sane + if (scale <= 0) + scale = kUnit; + + frame_size = Size((game_size.Width * scale) >> kShift, (game_size.Height * scale) >> kShift); + // If the scaled game size appear larger than the screen, + // use "proportional stretch" method instead + if (frame_size.ExceedsByAny(screen_size)) + frame_size = ProportionalStretch(screen_size, game_size); + } + return frame_size; +} + +Size precalc_screen_size(const Size &game_size, const DisplayModeSetup &dm_setup, const GameFrameSetup &frame_setup) +{ + Size screen_size, frame_size; + Size device_size = get_max_display_size(dm_setup.Windowed); + + // Set requested screen (window) size, depending on screen definition option + ScreenSizeSetup scsz = dm_setup.ScreenSize; + switch (scsz.SizeDef) + { + case kScreenDef_Explicit: + // Use resolution from user config + screen_size = scsz.Size; + if (screen_size.IsNull()) + { + // If the configuration did not define proper screen size, + // use the scaled game size instead + frame_size = set_game_frame_after_screen_size(game_size, device_size, frame_setup); + if (screen_size.Width <= 0) + screen_size.Width = frame_size.Width; + if (screen_size.Height <= 0) + screen_size.Height = frame_size.Height; + } + break; + case kScreenDef_ByGameScaling: + // Use game frame (scaled game) size + frame_size = set_game_frame_after_screen_size(game_size, device_size, frame_setup); + screen_size = frame_size; + break; + case kScreenDef_MaxDisplay: + // Set as big as current device size + screen_size = device_size; + break; + } + return screen_size; +} + +// Find closest possible compatible display mode and initialize it +bool try_init_compatible_mode(const DisplayMode &dm, const bool match_device_ratio) +{ + const Size &screen_size = Size(dm.Width, dm.Height); + // Find nearest compatible mode and init that + Debug::Printf("Attempting to find nearest supported resolution for screen size %d x %d (%d-bit) %s", + dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); + const Size device_size = get_max_display_size(dm.Windowed); + if (dm.Windowed) + Debug::Printf("Maximal allowed window size: %d x %d", device_size.Width, device_size.Height); + DisplayMode dm_compat = dm; + + std::unique_ptr modes(gfxDriver->GetSupportedModeList(dm.ColorDepth)); // TODO: use unique_ptr when available + + // Windowed mode + if (dm.Windowed) + { + // If windowed mode, make the resolution stay in the generally supported limits + dm_compat.Width = Math::Min(dm_compat.Width, device_size.Width); + dm_compat.Height = Math::Min(dm_compat.Height, device_size.Height); + } + // Fullscreen mode + else + { + // If told to find mode with aspect ratio matching current desktop resolution, then first + // try find matching one, and if failed then try any compatible one + bool mode_found = false; + if (modes.get()) + { + if (match_device_ratio) + mode_found = find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, &device_size, nullptr, dm_compat); + if (!mode_found) + mode_found = find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, nullptr, nullptr, dm_compat); + } + if (!mode_found) + Debug::Printf("Could not find compatible fullscreen mode. Will try to force-set mode requested by user and fallback to windowed mode if that fails."); + dm_compat.Vsync = dm.Vsync; + dm_compat.Windowed = false; + } + + bool result = graphics_mode_set_dm(dm_compat); + if (!result && dm.Windowed) + { + // When initializing windowed mode we could start with any random window size; + // if that did not work, try to find nearest supported mode, as with fullscreen mode, + // except refering to max window size as an upper bound + if (find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, nullptr, &device_size, dm_compat)) + { + dm_compat.Vsync = dm.Vsync; + dm_compat.Windowed = true; + result = graphics_mode_set_dm(dm_compat); + } + } + return result; +} + +// Try to find and initialize compatible display mode as close to given setup as possible +bool try_init_mode_using_setup(const Size &game_size, const DisplayModeSetup &dm_setup, + const int col_depth, const GameFrameSetup &frame_setup, + const GfxFilterSetup &filter_setup) +{ + // We determine the requested size of the screen using setup options + const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); + DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, col_depth), + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + if (!try_init_compatible_mode(dm, dm_setup.ScreenSize.SizeDef == kScreenDef_Explicit ? false : dm_setup.ScreenSize.MatchDeviceRatio)) + return false; + + // Set up native size and render frame + if (!graphics_mode_set_native_size(game_size) || !graphics_mode_set_render_frame(frame_setup)) + return false; + + // Set up graphics filter + if (!graphics_mode_set_filter_any(filter_setup)) + return false; + return true; +} + +void log_out_driver_modes(const int color_depth) +{ + IGfxModeList *modes = gfxDriver->GetSupportedModeList(color_depth); + if (!modes) + { + Debug::Printf(kDbgMsg_Error, "Couldn't get a list of supported resolutions for color depth = %d", color_depth); + return; + } + const int mode_count = modes->GetModeCount(); + DisplayMode mode; + String mode_str; + for (int i = 0, in_str = 0; i < mode_count; ++i) + { + if (!modes->GetMode(i, mode) || mode.ColorDepth != color_depth) + continue; + mode_str.Append(String::FromFormat("%dx%d;", mode.Width, mode.Height)); + if (++in_str % 8 == 0) + mode_str.Append("\n\t"); + } + delete modes; + + String out_str = String::FromFormat("Supported gfx modes (%d-bit): ", color_depth); + if (!mode_str.IsEmpty()) + { + out_str.Append("\n\t"); + out_str.Append(mode_str); + } + else + out_str.Append("none"); + Debug::Printf(out_str); +} + +// Create requested graphics driver and try to find and initialize compatible display mode as close to user setup as possible; +// if the given setup fails, gets default setup for the opposite type of mode (fullscreen/windowed) and tries that instead. +bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id, const Size &game_size, const DisplayModeSetup &dm_setup, + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup, const GfxFilterSetup &filter_setup) +{ + if (!graphics_mode_create_renderer(gfx_driver_id)) + return false; + + const int use_col_depth = + color_depth.Forced ? color_depth.Bits : gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); + // Log out supported driver modes + log_out_driver_modes(use_col_depth); + + bool result = try_init_mode_using_setup(game_size, dm_setup, use_col_depth, frame_setup, filter_setup); + // Try windowed mode if fullscreen failed, and vice versa + if (!result && editor_debugging_enabled == 0) + { + // we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults() + DisplayModeSetup dm_setup_alt = dm_setup; + dm_setup_alt.Windowed = !dm_setup.Windowed; + GameFrameSetup frame_setup_alt; + graphics_mode_get_defaults(dm_setup_alt.Windowed, dm_setup_alt.ScreenSize, frame_setup_alt); + result = try_init_mode_using_setup(game_size, dm_setup_alt, use_col_depth, frame_setup_alt, filter_setup); + } + return result; +} + +bool simple_create_gfx_driver_and_init_mode(const String &gfx_driver_id, + const Size &game_size, + const DisplayModeSetup &dm_setup, + const ColorDepthOption &color_depth, + const GameFrameSetup &frame_setup, + const GfxFilterSetup &filter_setup) +{ + if (!graphics_mode_create_renderer(gfx_driver_id)) { return false; } + + const int col_depth = gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); + + DisplayMode dm(GraphicResolution(game_size.Width, game_size.Height, col_depth), + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + + if (!graphics_mode_set_dm(dm)) { return false; } + if (!graphics_mode_set_native_size(game_size)) { return false; } + if (!graphics_mode_set_render_frame(frame_setup)) { return false; } + if (!graphics_mode_set_filter_any(filter_setup)) { return false; } + + return true; +} + + +void display_gfx_mode_error(const Size &game_size, const ScreenSetup &setup, const int color_depth) +{ + proper_exit=1; + platform->FinishedUsingGraphicsMode(); + + String main_error; + ScreenSizeSetup scsz = setup.DisplayMode.ScreenSize; + PGfxFilter filter = gfxDriver ? gfxDriver->GetGraphicsFilter() : PGfxFilter(); + Size wanted_screen; + if (scsz.SizeDef == kScreenDef_Explicit) + main_error.Format("There was a problem initializing graphics mode %d x %d (%d-bit), or finding nearest compatible mode, with game size %d x %d and filter '%s'.", + scsz.Size.Width, scsz.Size.Height, color_depth, game_size.Width, game_size.Height, filter ? filter->GetInfo().Id.GetCStr() : "Undefined"); + else + main_error.Format("There was a problem finding and/or creating valid graphics mode for game size %d x %d (%d-bit) and requested filter '%s'.", + game_size.Width, game_size.Height, color_depth, setup.Filter.UserRequest.IsEmpty() ? "Undefined" : setup.Filter.UserRequest.GetCStr()); + + platform->DisplayAlert("%s\n" + "(Problem: '%s')\n" + "Try to correct the problem, or seek help from the AGS homepage." + "%s", + main_error.GetCStr(), get_allegro_error(), platform->GetGraphicsTroubleshootingText()); +} + +bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, const ColorDepthOption &color_depth) +{ + // Log out display information + Size device_size; + if (get_desktop_resolution(&device_size.Width, &device_size.Height) == 0) + Debug::Printf("Device display resolution: %d x %d", device_size.Width, device_size.Height); + else + Debug::Printf(kDbgMsg_Error, "Unable to obtain device resolution"); + + const char *screen_sz_def_options[kNumScreenDef] = { "explicit", "scaling", "max" }; + ScreenSizeSetup scsz = setup.DisplayMode.ScreenSize; + const bool ignore_device_ratio = setup.DisplayMode.Windowed || scsz.SizeDef == kScreenDef_Explicit; + GameFrameSetup gameframe = setup.DisplayMode.Windowed ? setup.WinGameFrame : setup.FsGameFrame; + const String scale_option = make_scaling_option(gameframe); + Debug::Printf(kDbgMsg_Info, "Graphic settings: driver: %s, windowed: %s, screen def: %s, screen size: %d x %d, match device ratio: %s, game scale: %s", + setup.DriverID.GetCStr(), + setup.DisplayMode.Windowed ? "yes" : "no", screen_sz_def_options[scsz.SizeDef], + scsz.Size.Width, scsz.Size.Height, + ignore_device_ratio ? "ignore" : (scsz.MatchDeviceRatio ? "yes" : "no"), scale_option.GetCStr()); + + // Prepare the list of available gfx factories, having the one requested by user at first place + // TODO: make factory & driver IDs case-insensitive! + StringV ids; + GetGfxDriverFactoryNames(ids); + StringV::iterator it = ids.begin(); + for (; it != ids.end(); ++it) + { + if (it->CompareNoCase(setup.DriverID) == 0) break; + } + if (it != ids.end()) + std::rotate(ids.begin(), it, ids.end()); + else + Debug::Printf(kDbgMsg_Error, "Requested graphics driver '%s' not found, will try existing drivers instead", setup.DriverID.GetCStr()); + + // Try to create renderer and init gfx mode, choosing one factory at a time + bool result = false; + for (StringV::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + result = +#ifdef USE_SIMPLE_GFX_INIT + simple_create_gfx_driver_and_init_mode +#else + create_gfx_driver_and_init_mode_any +#endif + (*it, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter); + + if (result) + break; + graphics_mode_shutdown(); + } + // If all possibilities failed, display error message and quit + if (!result) + { + display_gfx_mode_error(game_size, setup, color_depth.Bits); + return false; + } + return true; +} + +ActiveDisplaySetting graphics_mode_get_last_setting(bool windowed) +{ + return windowed ? SavedWindowedSetting : SavedFullscreenSetting; +} + +bool graphics_mode_update_render_frame(); +void GfxDriverOnSurfaceUpdate() +{ + // Resize render frame using current scaling settings + graphics_mode_update_render_frame(); + on_coordinates_scaling_changed(); +} + +bool graphics_mode_create_renderer(const String &driver_id) +{ + if (!create_gfx_driver(driver_id)) + return false; + + gfxDriver->SetCallbackOnInit(GfxDriverOnInitCallback); + gfxDriver->SetCallbackOnSurfaceUpdate(GfxDriverOnSurfaceUpdate); + // TODO: this is remains of the old code; find out if this is really + // the best time and place to set the tint method + gfxDriver->SetTintMethod(TintReColourise); + return true; +} + +bool graphics_mode_set_dm_any(const Size &game_size, const DisplayModeSetup &dm_setup, + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup) +{ + // We determine the requested size of the screen using setup options + const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); + DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, color_depth.Bits), + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + return try_init_compatible_mode(dm, dm_setup.ScreenSize.MatchDeviceRatio); +} + +bool graphics_mode_set_dm(const DisplayMode &dm) +{ + Debug::Printf("Attempt to switch gfx mode to %d x %d (%d-bit) %s", + dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); + + // Tell Allegro new default bitmap color depth (must be done before set_gfx_mode) + // TODO: this is also done inside ALSoftwareGraphicsDriver implementation; can remove one? + set_color_depth(dm.ColorDepth); + // TODO: this is remains of the old code; find out what it means and do we + // need this if we are not using allegro software driver? + if (dm.RefreshRate >= 50) + request_refresh_rate(dm.RefreshRate); + + if (!gfxDriver->SetDisplayMode(dm, nullptr)) + { + Debug::Printf(kDbgMsg_Error, "Failed to init gfx mode. Error: %s", get_allegro_error()); + return false; + } + + DisplayMode rdm = gfxDriver->GetDisplayMode(); + if (rdm.Windowed) + SavedWindowedSetting.Dm = rdm; + else + SavedFullscreenSetting.Dm = rdm; + Debug::Printf("Succeeded. Using gfx mode %d x %d (%d-bit) %s", + rdm.Width, rdm.Height, rdm.ColorDepth, rdm.Windowed ? "windowed" : "fullscreen"); + return true; +} + +bool graphics_mode_update_render_frame() +{ + if (!gfxDriver || !gfxDriver->IsModeSet() || !gfxDriver->IsNativeSizeValid()) + return false; + + DisplayMode dm = gfxDriver->GetDisplayMode(); + Size screen_size = Size(dm.Width, dm.Height); + Size native_size = gfxDriver->GetNativeSize(); + Size frame_size = set_game_frame_after_screen_size(native_size, screen_size, CurFrameSetup); + Rect render_frame = CenterInRect(RectWH(screen_size), RectWH(frame_size)); + + if (!gfxDriver->SetRenderFrame(render_frame)) + { + Debug::Printf(kDbgMsg_Error, "Failed to set render frame (%d, %d, %d, %d : %d x %d). Error: %s", + render_frame.Left, render_frame.Top, render_frame.Right, render_frame.Bottom, + render_frame.GetWidth(), render_frame.GetHeight(), get_allegro_error()); + return false; + } + + Rect dst_rect = gfxDriver->GetRenderDestination(); + Debug::Printf("Render frame set, render dest (%d, %d, %d, %d : %d x %d)", + dst_rect.Left, dst_rect.Top, dst_rect.Right, dst_rect.Bottom, dst_rect.GetWidth(), dst_rect.GetHeight()); + // init game scaling transformation + GameScaling.Init(native_size, gfxDriver->GetRenderDestination()); + return true; +} + +bool graphics_mode_set_native_size(const Size &native_size) +{ + if (!gfxDriver || native_size.IsNull()) + return false; + if (!gfxDriver->SetNativeSize(native_size)) + return false; + // if render frame translation was already set, then update it with new native size + if (gfxDriver->IsRenderFrameValid()) + graphics_mode_update_render_frame(); + return true; +} + +GameFrameSetup graphics_mode_get_render_frame() +{ + return CurFrameSetup; +} + +bool graphics_mode_set_render_frame(const GameFrameSetup &frame_setup) +{ + if (!frame_setup.IsValid()) + return false; + CurFrameSetup = frame_setup; + if (gfxDriver->GetDisplayMode().Windowed) + SavedWindowedSetting.FrameSetup = frame_setup; + else + SavedFullscreenSetting.FrameSetup = frame_setup; + graphics_mode_update_render_frame(); + return true; +} + +bool graphics_mode_set_filter(const String &filter_id) +{ + if (!GfxFactory) + return false; + + String filter_error; + PGfxFilter filter = GfxFactory->SetFilter(filter_id, filter_error); + if (!filter) + { + Debug::Printf(kDbgMsg_Error, "Unable to set graphics filter '%s'. Error: %s", filter_id.GetCStr(), filter_error.GetCStr()); + return false; + } + Rect filter_rect = filter->GetDestination(); + Debug::Printf("Graphics filter set: '%s', filter dest (%d, %d, %d, %d : %d x %d)", filter->GetInfo().Id.GetCStr(), + filter_rect.Left, filter_rect.Top, filter_rect.Right, filter_rect.Bottom, filter_rect.GetWidth(), filter_rect.GetHeight()); + return true; +} + +void graphics_mode_shutdown() +{ + if (GfxFactory) + GfxFactory->Shutdown(); + GfxFactory = nullptr; + gfxDriver = nullptr; + + // Tell Allegro that we are no longer in graphics mode + set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); +} diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h new file mode 100644 index 000000000000..8329e407120b --- /dev/null +++ b/engines/ags/engine/main/graphics_mode.h @@ -0,0 +1,158 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__GRAPHICSMODE_H +#define __AGS_EE_MAIN__GRAPHICSMODE_H + +#include "gfx/gfxdefines.h" +#include "util/scaling.h" +#include "util/string.h" + +using AGS::Common::String; +using AGS::Engine::DisplayMode; + +Size get_desktop_size(); +String make_scaling_factor_string(uint32_t scaling); + +namespace AGS { namespace Engine { class IGfxModeList; }} +bool find_nearest_supported_mode(const AGS::Engine::IGfxModeList &modes, const Size &wanted_size, + const int color_depth, const Size *ratio_reference, const Size *upper_bound, + AGS::Engine::DisplayMode &dm, int *mode_index = nullptr); + + +// The game-to-screen transformation +// TODO: this is only required for low-level mouse processing; +// when possible, move to mouse "manager" object, and assign at gfxmode init +extern AGS::Engine::PlaneScaling GameScaling; + + +// Filter configuration +struct GfxFilterSetup +{ + String ID; // internal filter ID + String UserRequest; // filter name, requested by user +}; + +enum FrameScaleDefinition +{ + kFrame_IntScale, // explicit integer scaling x/y factors + kFrame_MaxRound, // calculate max round uniform scaling factor + kFrame_MaxStretch, // resize to maximal possible inside the display box + kFrame_MaxProportional, // same as stretch, but keep game's aspect ratio + kNumFrameScaleDef +}; + +// Game frame configuration +struct GameFrameSetup +{ + FrameScaleDefinition ScaleDef; // a method used to determine game frame scaling + int ScaleFactor; // explicit scale factor + + GameFrameSetup(); + GameFrameSetup(FrameScaleDefinition def, int factor = 0); + bool IsValid() const; +}; + +enum ScreenSizeDefinition +{ + kScreenDef_Explicit, // define by width & height + kScreenDef_ByGameScaling, // define by game scale factor + kScreenDef_MaxDisplay, // set to maximal supported (desktop/device screen size) + kNumScreenDef +}; + +// Configuration that is used to determine the size of the screen +struct ScreenSizeSetup +{ + ScreenSizeDefinition SizeDef; // a method used to determine screen size + ::Size Size; // explicitly defined screen metrics + bool MatchDeviceRatio; // whether to choose resolution matching device aspect ratio + + ScreenSizeSetup(); +}; + +// Display mode configuration +struct DisplayModeSetup +{ + ScreenSizeSetup ScreenSize; + + int RefreshRate; // gfx mode refresh rate + bool VSync; // vertical sync + bool Windowed; // is mode windowed + + DisplayModeSetup(); +}; + +// Full graphics configuration +struct ScreenSetup +{ + String DriverID; // graphics driver ID + DisplayModeSetup DisplayMode; // definition of the initial display mode + + // Definitions for the fullscreen and windowed scaling methods. + // When the initial display mode is set, corresponding scaling method from this pair is used. + // The second method is meant to be saved and used if display mode is switched at runtime. + GameFrameSetup FsGameFrame; // how the game frame should be scaled/positioned in fullscreen mode + GameFrameSetup WinGameFrame; // how the game frame should be scaled/positioned in windowed mode + + GfxFilterSetup Filter; // graphics filter definition +}; + +// Display mode color depth variants suggested for the use +struct ColorDepthOption +{ + int Bits; // color depth value in bits + bool Forced; // whether the depth should be forced, or driver's recommendation used + + ColorDepthOption() : Bits(0), Forced(false) {} + ColorDepthOption(int bits, bool forced = false) : Bits(bits), Forced(forced) {} +}; + +// ActiveDisplaySetting struct merges DisplayMode and GameFrameSetup, +// which is useful if you need to save active settings and reapply them later. +struct ActiveDisplaySetting +{ + DisplayMode Dm; + GameFrameSetup FrameSetup; +}; + +// Initializes any possible gfx mode, using user config as a recommendation; +// may try all available renderers and modes before succeeding (or failing) +bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, const ColorDepthOption &color_depth); +// Return last saved display mode of the given kind +ActiveDisplaySetting graphics_mode_get_last_setting(bool windowed); +// Creates graphics driver of given id +bool graphics_mode_create_renderer(const String &driver_id); +// Try to find and initialize compatible display mode as close to given setup as possible +bool graphics_mode_set_dm_any(const Size &game_size, const DisplayModeSetup &dm_setup, + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup); +// Set the display mode with given parameters +bool graphics_mode_set_dm(const AGS::Engine::DisplayMode &dm); +// Set the native image size +bool graphics_mode_set_native_size(const Size &native_size); +// Get current render frame setup +GameFrameSetup graphics_mode_get_render_frame(); +// Set the render frame position inside the window +bool graphics_mode_set_render_frame(const GameFrameSetup &frame_setup); +// Set requested graphics filter, or default filter if the requested one failed +bool graphics_mode_set_filter_any(const GfxFilterSetup &setup); +// Set the scaling filter with given ID +bool graphics_mode_set_filter(const String &filter_id); +// Releases current graphic mode and shuts down renderer +void graphics_mode_shutdown(); + +#endif // __AGS_EE_MAIN__GRAPHICSMODE_H diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp new file mode 100644 index 000000000000..5ac2f6a903df --- /dev/null +++ b/engines/ags/engine/main/main.cpp @@ -0,0 +1,495 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Entry point of the application here. +// +// +// For Windows main() function is really called _mangled_main and is called +// not by system, but from insides of allegro library. +// (See allegro\platform\alwin.h) +// What about other platforms? +// + +#include "core/platform.h" +#define AGS_PLATFORM_DEFINES_PSP_VARS (AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID) + +#include +#include "ac/common.h" +#include "ac/gamesetup.h" +#include "ac/gamestate.h" +#include "core/def_version.h" +#include "debug/debugger.h" +#include "debug/debug_log.h" +#include "debug/out.h" +#include "main/config.h" +#include "main/engine.h" +#include "main/mainheader.h" +#include "main/main.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/route_finder.h" +#include "core/assetmanager.h" +#include "util/directory.h" +#include "util/path.h" +#include "util/string_compat.h" + +#if AGS_PLATFORM_OS_WINDOWS +#include "platform/windows/win_ex_handling.h" +#endif +#if AGS_PLATFORM_DEBUG +#include "test/test_all.h" +#endif + +#if AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG +#define USE_CUSTOM_EXCEPTION_HANDLER +#endif + +using namespace AGS::Common; +using namespace AGS::Engine; + +String appDirectory; // Needed for library loading +String cmdGameDataPath; + +char **global_argv = nullptr; +int global_argc = 0; + + +extern GameSetup usetup; +extern GameState play; +extern int our_eip; +extern AGSPlatformDriver *platform; +extern int convert_16bit_bgr; +extern int editor_debugging_enabled; +extern int editor_debugging_initialized; +extern char editor_debugger_instance_token[100]; + + +// Startup flags, set from parameters to engine +int force_window = 0; +int override_start_room = 0; +bool justDisplayHelp = false; +bool justDisplayVersion = false; +bool justRunSetup = false; +bool justRegisterGame = false; +bool justUnRegisterGame = false; +bool justTellInfo = false; +bool attachToParentConsole = false; +bool hideMessageBoxes = false; +std::set tellInfoKeys; +const char *loadSaveGameOnStartup = nullptr; + +#if ! AGS_PLATFORM_DEFINES_PSP_VARS +int psp_video_framedrop = 1; +int psp_audio_enabled = 1; +int psp_midi_enabled = 1; +int psp_ignore_acsetup_cfg_file = 0; +int psp_clear_cache_on_room_change = 0; + +int psp_midi_preload_patches = 0; +int psp_audio_cachesize = 10; +char psp_game_file_name[] = ""; +char psp_translation[] = "default"; + +int psp_gfx_renderer = 0; +int psp_gfx_scaling = 1; +int psp_gfx_smoothing = 0; +int psp_gfx_super_sampling = 1; +int psp_gfx_smooth_sprites = 0; +#endif + + +void main_pre_init() +{ + our_eip = -999; + Common::AssetManager::SetSearchPriority(Common::kAssetPriorityDir); + play.takeover_data = 0; +} + +void main_create_platform_driver() +{ + platform = AGSPlatformDriver::GetDriver(); +} + +// this needs to be updated if the "play" struct changes +#define SVG_VERSION_BWCOMPAT_MAJOR 3 +#define SVG_VERSION_BWCOMPAT_MINOR 2 +#define SVG_VERSION_BWCOMPAT_RELEASE 0 +#define SVG_VERSION_BWCOMPAT_REVISION 1103 +// CHECKME: we may lower this down, if we find that earlier versions may still +// load new savedgames +#define SVG_VERSION_FWCOMPAT_MAJOR 3 +#define SVG_VERSION_FWCOMPAT_MINOR 2 +#define SVG_VERSION_FWCOMPAT_RELEASE 1 +#define SVG_VERSION_FWCOMPAT_REVISION 1111 + +// Current engine version +AGS::Common::Version EngineVersion; +// Lowest savedgame version, accepted by this engine +AGS::Common::Version SavedgameLowestBackwardCompatVersion; +// Lowest engine version, which would accept current savedgames +AGS::Common::Version SavedgameLowestForwardCompatVersion; + +void main_init(int argc, char*argv[]) +{ + EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); +#if defined (BUILD_STR) + EngineVersion.BuildInfo = BUILD_STR; +#endif + SavedgameLowestBackwardCompatVersion = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); + SavedgameLowestForwardCompatVersion = Version(SVG_VERSION_FWCOMPAT_MAJOR, SVG_VERSION_FWCOMPAT_MINOR, SVG_VERSION_FWCOMPAT_RELEASE, SVG_VERSION_FWCOMPAT_REVISION); + + Common::AssetManager::CreateInstance(); + main_pre_init(); + main_create_platform_driver(); + + global_argv = argv; + global_argc = argc; +} + +String get_engine_string() +{ + return String::FromFormat("Adventure Game Studio v%s Interpreter\n" + "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" +#ifdef BUILD_STR + "ACI version %s (Build: %s)\n", + EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr(), EngineVersion.BuildInfo.GetCStr()); +#else + "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); +#endif +} + +extern char return_to_roomedit[30]; +extern char return_to_room[150]; + +void main_print_help() { + platform->WriteStdOut( + "Usage: ags [OPTIONS] [GAMEFILE or DIRECTORY]\n\n" + //--------------------------------------------------------------------------------| + "Options:\n" +#if AGS_PLATFORM_OS_WINDOWS + " --console-attach Write output to the parent process's console\n" +#endif + " --fps Display fps counter\n" + " --fullscreen Force display mode to fullscreen\n" + " --gfxdriver Request graphics driver. Available options:\n" +#if AGS_PLATFORM_OS_WINDOWS + " d3d9, ogl, software\n" +#else + " ogl, software\n" +#endif + " --gfxfilter FILTER [SCALING]\n" + " Request graphics filter. Available options:\n" + " hqx, linear, none, stdscale\n" + " (support differs between graphic drivers);\n" + " scaling is specified by integer number\n" + " --help Print this help message and stop\n" + " --log-OUTPUT=GROUP[:LEVEL][,GROUP[:LEVEL]][,...]\n" + " --log-OUTPUT=+GROUPLIST[:LEVEL]\n" + " Setup logging to the chosen OUTPUT with given\n" + " log groups and verbosity levels. Groups may\n" + " be also defined by a LIST of one-letter IDs,\n" + " preceded by '+', e.g. +ABCD:LEVEL. Verbosity may\n" + " be also defined by a numberic ID.\n" + " OUTPUTs are\n" + " stdout, file, console\n" + " (where \"console\" is internal engine's console)\n" + " GROUPs are:\n" + " all, main (m), game (g), manobj (o),\n" + " script (s), sprcache (c)\n" + " LEVELs are:\n" + " all, alert (1), fatal (2), error (3), warn (4),\n" + " info (5), debug (6)\n" + " Examples:\n" + " --log-stdout=+mgs:debug\n" + " --log-file=all:warn\n" + " --log-file-path=PATH Define custom path for the log file\n" + //--------------------------------------------------------------------------------| +#if AGS_PLATFORM_OS_WINDOWS + " --no-message-box Disable reporting of alerts to message boxes\n" + " --setup Run setup application\n" +#endif + " --tell Print various information concerning engine\n" + " and the game; for selected output use:\n" + " --tell-config Print contents of merged game config\n" + " --tell-configpath Print paths to available config files\n" + " --tell-data Print information on game data and its location\n" + " --tell-engine Print engine name and version\n" + " --tell-graphicdriver Print list of supported graphic drivers\n" + "\n" + " --version Print engine's version and stop\n" + " --windowed Force display mode to windowed\n" + "\n" + "Gamefile options:\n" + " /dir/path/game/ Launch the game in specified directory\n" + " /dir/path/game/penguin.exe Launch penguin.exe\n" + " [nothing] Launch the game in the current directory\n" + //--------------------------------------------------------------------------------| + ); +} + +static int main_process_cmdline(ConfigTree &cfg, int argc, char *argv[]) +{ + int datafile_argv = 0; + for (int ee = 1; ee < argc; ++ee) + { + const char *arg = argv[ee]; + // + // Startup options + // + if (ags_stricmp(arg,"--help") == 0 || ags_stricmp(arg,"/?") == 0 || ags_stricmp(arg,"-?") == 0) + { + justDisplayHelp = true; + return 0; + } + if (ags_stricmp(arg, "-v") == 0 || ags_stricmp(arg, "--version") == 0) + { + justDisplayVersion = true; + return 0; + } + else if (ags_stricmp(arg,"-updatereg") == 0) + debug_flags |= DBG_REGONLY; +#if AGS_PLATFORM_DEBUG + else if ((ags_stricmp(arg,"--startr") == 0) && (ee < argc-1)) { + override_start_room = atoi(argv[ee+1]); + ee++; + } +#endif + else if ((ags_stricmp(arg,"--testre") == 0) && (ee < argc-2)) { + strcpy(return_to_roomedit, argv[ee+1]); + strcpy(return_to_room, argv[ee+2]); + ee+=2; + } + else if (ags_stricmp(arg,"-noexceptionhandler")==0) usetup.disable_exception_handling = true; + else if (ags_stricmp(arg, "--setup") == 0) + { + justRunSetup = true; + } + else if (ags_stricmp(arg,"-registergame") == 0) + { + justRegisterGame = true; + } + else if (ags_stricmp(arg,"-unregistergame") == 0) + { + justUnRegisterGame = true; + } + else if ((ags_stricmp(arg,"-loadsavedgame") == 0) && (argc > ee + 1)) + { + loadSaveGameOnStartup = argv[ee + 1]; + ee++; + } + else if ((ags_stricmp(arg,"--enabledebugger") == 0) && (argc > ee + 1)) + { + strcpy(editor_debugger_instance_token, argv[ee + 1]); + editor_debugging_enabled = 1; + force_window = 1; + ee++; + } + else if (ags_stricmp(arg, "--runfromide") == 0 && (argc > ee + 3)) + { + usetup.install_dir = argv[ee + 1]; + usetup.install_audio_dir = argv[ee + 2]; + usetup.install_voice_dir = argv[ee + 3]; + ee += 3; + } + else if (ags_stricmp(arg,"--takeover")==0) { + if (argc < ee+2) + break; + play.takeover_data = atoi (argv[ee + 1]); + strncpy (play.takeover_from, argv[ee + 2], 49); + play.takeover_from[49] = 0; + ee += 2; + } + else if (ags_strnicmp(arg, "--tell", 6) == 0) { + if (arg[6] == 0) + tellInfoKeys.insert(String("all")); + else if (arg[6] == '-' && arg[7] != 0) + tellInfoKeys.insert(String(arg + 7)); + } + // + // Config overrides + // + else if (ags_stricmp(arg, "-windowed") == 0 || ags_stricmp(arg, "--windowed") == 0) + force_window = 1; + else if (ags_stricmp(arg, "-fullscreen") == 0 || ags_stricmp(arg, "--fullscreen") == 0) + force_window = 2; + else if ((ags_stricmp(arg, "-gfxdriver") == 0 || ags_stricmp(arg, "--gfxdriver") == 0) && (argc > ee + 1)) + { + INIwritestring(cfg, "graphics", "driver", argv[++ee]); + } + else if ((ags_stricmp(arg, "-gfxfilter") == 0 || ags_stricmp(arg, "--gfxfilter") == 0) && (argc > ee + 1)) + { + // NOTE: we make an assumption here that if user provides scaling factor, + // this factor means to be applied to windowed mode only. + INIwritestring(cfg, "graphics", "filter", argv[++ee]); + if (argc > ee + 1 && argv[ee + 1][0] != '-') + INIwritestring(cfg, "graphics", "game_scale_win", argv[++ee]); + else + INIwritestring(cfg, "graphics", "game_scale_win", "max_round"); + } + else if (ags_stricmp(arg, "--fps") == 0) display_fps = kFPS_Forced; + else if (ags_stricmp(arg, "--test") == 0) debug_flags |= DBG_DEBUGMODE; + else if (ags_stricmp(arg, "-noiface") == 0) debug_flags |= DBG_NOIFACE; + else if (ags_stricmp(arg, "-nosprdisp") == 0) debug_flags |= DBG_NODRAWSPRITES; + else if (ags_stricmp(arg, "-nospr") == 0) debug_flags |= DBG_NOOBJECTS; + else if (ags_stricmp(arg, "-noupdate") == 0) debug_flags |= DBG_NOUPDATE; + else if (ags_stricmp(arg, "-nosound") == 0) debug_flags |= DBG_NOSFX; + else if (ags_stricmp(arg, "-nomusic") == 0) debug_flags |= DBG_NOMUSIC; + else if (ags_stricmp(arg, "-noscript") == 0) debug_flags |= DBG_NOSCRIPT; + else if (ags_stricmp(arg, "-novideo") == 0) debug_flags |= DBG_NOVIDEO; + else if (ags_stricmp(arg, "-dbgscript") == 0) debug_flags |= DBG_DBGSCRIPT; + else if (ags_strnicmp(arg, "--log-", 6) == 0 && arg[6] != 0) + { + String logarg = arg + 6; + size_t split_at = logarg.FindChar('='); + if (split_at >= 0) + cfg["log"][logarg.Left(split_at)] = logarg.Mid(split_at + 1); + else + cfg["log"][logarg] = ""; + } + else if (ags_stricmp(arg, "--console-attach") == 0) attachToParentConsole = true; + else if (ags_stricmp(arg, "--no-message-box") == 0) hideMessageBoxes = true; + // + // Special case: data file location + // + else if (arg[0]!='-') datafile_argv=ee; + } + + if (datafile_argv > 0) + { + cmdGameDataPath = GetPathFromCmdArg(datafile_argv); + } + else + { + // assign standard path for mobile/consoles (defined in their own platform implementation) + cmdGameDataPath = psp_game_file_name; + } + + if (tellInfoKeys.size() > 0) + justTellInfo = true; + + return 0; +} + +void main_set_gamedir(int argc, char*argv[]) +{ + appDirectory = Path::GetDirectoryPath(GetPathFromCmdArg(0)); + + if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) + { + // When launched by double-clicking a save game file, the curdir will + // be the save game folder unless we correct it + Directory::SetCurrentDirectory(appDirectory); + } + else + { + // It looks like Allegro library does not like ANSI (ACP) paths. + // When *not* working in U_UNICODE filepath mode, whenever it gets + // current directory for its own operations, it "fixes" it by + // substituting non-ASCII symbols with '^'. + // Here we explicitly set current directory to ASCII path. + String cur_dir = Directory::GetCurrentDirectory(); + String path = Path::GetPathInASCII(cur_dir); + if (!path.IsEmpty()) + Directory::SetCurrentDirectory(Path::MakeAbsolutePath(path)); + else + Debug::Printf(kDbgMsg_Error, "Unable to determine current directory: GetPathInASCII failed.\nArg: %s", cur_dir.GetCStr()); + } +} + +String GetPathFromCmdArg(int arg_index) +{ + if (arg_index < 0 || arg_index >= global_argc) + return ""; + String path = Path::GetCmdLinePathInASCII(global_argv[arg_index], arg_index); + if (!path.IsEmpty()) + return Path::MakeAbsolutePath(path); + Debug::Printf(kDbgMsg_Error, "Unable to determine path: GetCmdLinePathInASCII failed.\nCommand line argument %i: %s", arg_index, global_argv[arg_index]); + return global_argv[arg_index]; +} + +const char *get_allegro_error() +{ + return allegro_error; +} + +const char *set_allegro_error(const char *format, ...) +{ + va_list argptr; + va_start(argptr, format); + uvszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(format), argptr); + va_end(argptr); + return allegro_error; +} + +int ags_entry_point(int argc, char *argv[]) { + +#ifdef AGS_RUN_TESTS + Test_DoAllTests(); +#endif + main_init(argc, argv); + +#if AGS_PLATFORM_OS_WINDOWS + setup_malloc_handling(); +#endif + debug_flags=0; + + ConfigTree startup_opts; + int res = main_process_cmdline(startup_opts, argc, argv); + if (res != 0) + return res; + + if (attachToParentConsole) + platform->AttachToParentConsole(); + + if (justDisplayVersion) + { + platform->WriteStdOut(get_engine_string()); + return EXIT_NORMAL; + } + + if (justDisplayHelp) + { + main_print_help(); + return EXIT_NORMAL; + } + + if (!justTellInfo && !hideMessageBoxes) + platform->SetGUIMode(true); + + init_debug(startup_opts, justTellInfo); + Debug::Printf(kDbgMsg_Alert, get_engine_string()); + + main_set_gamedir(argc, argv); + + // Update shell associations and exit + if (debug_flags & DBG_REGONLY) + exit(EXIT_NORMAL); + +#ifdef USE_CUSTOM_EXCEPTION_HANDLER + if (usetup.disable_exception_handling) +#endif + { + int result = initialize_engine(startup_opts); + // TODO: refactor engine shutdown routine (must shutdown and delete everything started and created) + allegro_exit(); + platform->PostAllegroExit(); + return result; + } +#ifdef USE_CUSTOM_EXCEPTION_HANDLER + else + { + return initialize_engine_with_exception_handling(initialize_engine, startup_opts); + } +#endif +} diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h new file mode 100644 index 000000000000..1f5116d342b9 --- /dev/null +++ b/engines/ags/engine/main/main.h @@ -0,0 +1,65 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__MAIN_H +#define __AGS_EE_MAIN__MAIN_H + +#include "core/platform.h" +#include "util/version.h" + +// Current engine version +extern AGS::Common::Version EngineVersion; +// Lowest savedgame version, accepted by this engine +extern AGS::Common::Version SavedgameLowestBackwardCompatVersion; +// Lowest engine version, which would accept current savedgames +extern AGS::Common::Version SavedgameLowestForwardCompatVersion; + +//============================================================================= + +extern char **global_argv; + +// Location of the engine executable +extern AGS::Common::String appDirectory; +// Game path from the startup options (before reading config) +extern AGS::Common::String cmdGameDataPath; + +AGS::Common::String GetPathFromCmdArg(int arg_index); + +// Startup flags, set from parameters to engine +extern int force_window; +extern int override_start_room; +extern bool justRegisterGame; +extern bool justUnRegisterGame; +extern bool justTellInfo; +extern const char *loadSaveGameOnStartup; + +extern int psp_video_framedrop; +extern int psp_audio_enabled; +extern int psp_midi_enabled; +extern int psp_ignore_acsetup_cfg_file; +extern int psp_clear_cache_on_room_change; + +extern int psp_midi_preload_patches; +extern int psp_audio_cachesize; +extern char psp_game_file_name[]; +extern char psp_translation[]; + +void main_print_help(); + +int ags_entry_point(int argc, char *argv[]); + +#endif // __AGS_EE_MAIN__MAIN_H \ No newline at end of file diff --git a/engines/ags/engine/main/main_allegro.cpp b/engines/ags/engine/main/main_allegro.cpp new file mode 100644 index 000000000000..5a43762f44e1 --- /dev/null +++ b/engines/ags/engine/main/main_allegro.cpp @@ -0,0 +1,7 @@ +#include "allegro.h" +#include "main/main.h" + +int main(int argc, char *argv[]) { + return ags_entry_point(argc, argv); +} +END_OF_MAIN() diff --git a/engines/ags/engine/main/main_allegro.h b/engines/ags/engine/main/main_allegro.h new file mode 100644 index 000000000000..bbf7bcf6e8a0 --- /dev/null +++ b/engines/ags/engine/main/main_allegro.h @@ -0,0 +1,31 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__MAINALLEGRO_H +#define __AGS_EE_MAIN__MAINALLEGRO_H + +// Gets allegro_error as a const string. +// Please, use this getter to acquire error text, do not use allegro_error +// global variable directly. +const char *get_allegro_error(); +// Sets allegro_error global variable and returns a resulting string. +// The maximal allowed text length is defined by ALLEGRO_ERROR_SIZE macro +// (usually 256). If the formatted message is larger than that it will be +// truncated. Null terminator is always guaranteed. +const char *set_allegro_error(const char *format, ...); + +#endif // __AGS_EE_MAIN__MAINALLEGRO_H diff --git a/engines/ags/engine/main/maindefines_ex.h b/engines/ags/engine/main/maindefines_ex.h new file mode 100644 index 000000000000..d2b8729f47d3 --- /dev/null +++ b/engines/ags/engine/main/maindefines_ex.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__MAINDEFINES_H +#define __AGS_EE_MAIN__MAINDEFINES_H + +#define RETURN_CONTINUE 1 + +#endif // __AGS_EE_MAIN__MAINDEFINES_H diff --git a/engines/ags/engine/main/mainheader.h b/engines/ags/engine/main/mainheader.h new file mode 100644 index 000000000000..7b1d23f6a3a9 --- /dev/null +++ b/engines/ags/engine/main/mainheader.h @@ -0,0 +1,47 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__MAINHEADER_H +#define __AGS_EE_MAIN__MAINHEADER_H + +#include "core/platform.h" + +#include "main/maindefines_ex.h" + +#include "ac/math.h" +#include "script/script_runtime.h" +#include "gui/animatingguibutton.h" +#include "gui/guibutton.h" +#include "gfx/gfxfilter.h" +#include "util/string_utils.h" +#include "device/mousew32.h" +#include "ac/route_finder.h" +#include "util/misc.h" +#include "script/cc_error.h" + +// include last since we affect windows includes +#include "ac/file.h" + +#if AGS_PLATFORM_OS_ANDROID +#include +#include + +extern "C" void selectLatestSavegame(); +extern bool psp_load_latest_savegame; +#endif + +#endif // __AGS_EE_MAIN__MAINHEADER_H diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp new file mode 100644 index 000000000000..678b376eef29 --- /dev/null +++ b/engines/ags/engine/main/quit.cpp @@ -0,0 +1,320 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Quit game procedure +// + +#include "core/platform.h" +#include "ac/cdaudio.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/roomstatus.h" +#include "ac/translation.h" +#include "debug/agseditordebugger.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "debug/out.h" +#include "font/fonts.h" +#include "main/config.h" +#include "main/engine.h" +#include "main/main.h" +#include "main/mainheader.h" +#include "main/quit.h" +#include "ac/spritecache.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" +#include "core/assetmanager.h" +#include "plugin/plugin_engine.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern SpriteCache spriteset; +extern RoomStruct thisroom; +extern RoomStatus troom; // used for non-saveable rooms, eg. intro +extern int our_eip; +extern GameSetup usetup; +extern char pexbuf[STD_BUFFER_SIZE]; +extern int proper_exit; +extern char check_dynamic_sprites_at_exit; +extern int editor_debugging_initialized; +extern IAGSEditorDebugger *editor_debugger; +extern int need_to_stop_cd; +extern int use_cdplayer; +extern IGraphicsDriver *gfxDriver; + +bool handledErrorInEditor; + +void quit_tell_editor_debugger(const String &qmsg, QuitReason qreason) +{ + if (editor_debugging_initialized) + { + if (qreason & kQuitKind_GameException) + handledErrorInEditor = send_exception_to_editor(qmsg); + send_message_to_editor("EXIT"); + editor_debugger->Shutdown(); + } +} + +void quit_stop_cd() +{ + if (need_to_stop_cd) + cd_manager(3,0); +} + +void quit_shutdown_scripts() +{ + ccUnregisterAllObjects(); +} + +void quit_check_dynamic_sprites(QuitReason qreason) +{ + if ((qreason & kQuitKind_NormalExit) && (check_dynamic_sprites_at_exit) && + (game.options[OPT_DEBUGMODE] != 0)) { + // game exiting normally -- make sure the dynamic sprites + // have been deleted + for (int i = 1; i < spriteset.GetSpriteSlotCount(); i++) { + if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) + debug_script_warn("Dynamic sprite %d was never deleted", i); + } + } +} + +void quit_shutdown_platform(QuitReason qreason) +{ + // Be sure to unlock mouse on exit, or users will hate us + platform->UnlockMouse(); + platform->AboutToQuitGame(); + + our_eip = 9016; + + pl_stop_plugins(); + + quit_check_dynamic_sprites(qreason); + + platform->FinishedUsingGraphicsMode(); + + if (use_cdplayer) + platform->ShutdownCDPlayer(); +} + +void quit_shutdown_audio() +{ + our_eip = 9917; + game.options[OPT_CROSSFADEMUSIC] = 0; + stopmusic(); +#ifndef PSP_NO_MOD_PLAYBACK + if (usetup.mod_player) + remove_mod_player(); +#endif + + // Quit the sound thread. + audioThread.Stop(); + + remove_sound(); +} + +QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) +{ + if (qmsg[0]=='|') + { + return kQuit_GameRequest; + } + else if (qmsg[0]=='!') + { + QuitReason qreason; + qmsg++; + + if (qmsg[0] == '|') + { + qreason = kQuit_UserAbort; + alertis = "Abort key pressed.\n\n"; + } + else if (qmsg[0] == '?') + { + qmsg++; + qreason = kQuit_ScriptAbort; + alertis = "A fatal error has been generated by the script using the AbortGame function. Please contact the game author for support.\n\n"; + } + else + { + qreason = kQuit_GameError; + alertis.Format("An error has occurred. Please contact the game author for support, as this " + "is likely to be a scripting error and not a bug in AGS.\n" + "(ACI version %s)\n\n", EngineVersion.LongString.GetCStr()); + } + + alertis.Append(get_cur_script(5)); + + if (qreason != kQuit_UserAbort) + alertis.Append("\nError: "); + else + qmsg = ""; + return qreason; + } + else if (qmsg[0] == '%') + { + qmsg++; + alertis.Format("A warning has been generated. This is not normally fatal, but you have selected " + "to treat warnings as errors.\n" + "(ACI version %s)\n\n%s\n", EngineVersion.LongString.GetCStr(), get_cur_script(5).GetCStr()); + return kQuit_GameWarning; + } + else + { + alertis.Format("An internal error has occurred. Please note down the following information.\n" + "If the problem persists, post the details on the AGS Technical Forum.\n" + "(ACI version %s)\n" + "\nError: ", EngineVersion.LongString.GetCStr()); + return kQuit_FatalError; + } +} + +void quit_message_on_exit(const char *qmsg, String &alertis, QuitReason qreason) +{ + // successful exit displays no messages (because Windoze closes the dos-box + // if it is empty). + if ((qreason & kQuitKind_NormalExit) == 0 && !handledErrorInEditor) + { + // Display the message (at this point the window still exists) + sprintf(pexbuf,"%s\n",qmsg); + alertis.Append(pexbuf); + platform->DisplayAlert("%s", alertis.GetCStr()); + } +} + +void quit_release_data() +{ + resetRoomStatuses(); + thisroom.Free(); + play.Free(); + + /* _CrtMemState memstart; + _CrtMemCheckpoint(&memstart); + _CrtMemDumpStatistics( &memstart );*/ + + Common::AssetManager::DestroyInstance(); +} + +void quit_delete_temp_files() +{ + al_ffblk dfb; + int dun = al_findfirst("~ac*.tmp",&dfb,FA_SEARCH); + while (!dun) { + ::remove(dfb.name); + dun = al_findnext(&dfb); + } + al_findclose (&dfb); +} + +// TODO: move to test unit +extern Bitmap *test_allegro_bitmap; +extern IDriverDependantBitmap *test_allegro_ddb; +void allegro_bitmap_test_release() +{ + delete test_allegro_bitmap; + if (test_allegro_ddb) + gfxDriver->DestroyDDB(test_allegro_ddb); +} + +char return_to_roomedit[30] = "\0"; +char return_to_room[150] = "\0"; +// quit - exits the engine, shutting down everything gracefully +// The parameter is the message to print. If this message begins with +// an '!' character, then it is printed as a "contact game author" error. +// If it begins with a '|' then it is treated as a "thanks for playing" type +// message. If it begins with anything else, it is treated as an internal +// error. +// "!|" is a special code used to mean that the player has aborted (Alt+X) +void quit(const char *quitmsg) +{ + String alertis; + QuitReason qreason = quit_check_for_error_state(quitmsg, alertis); + // Need to copy it in case it's from a plugin (since we're + // about to free plugins) + String qmsg = quitmsg; + + if (qreason & kQuitKind_NormalExit) + save_config_file(); + + allegro_bitmap_test_release(); + + handledErrorInEditor = false; + + quit_tell_editor_debugger(qmsg, qreason); + + our_eip = 9900; + + quit_stop_cd(); + + our_eip = 9020; + + quit_shutdown_scripts(); + + quit_shutdown_platform(qreason); + + our_eip = 9019; + + quit_shutdown_audio(); + + our_eip = 9901; + + shutdown_font_renderer(); + our_eip = 9902; + + spriteset.Reset(); + + our_eip = 9907; + + close_translation(); + + our_eip = 9908; + + shutdown_pathfinder(); + + engine_shutdown_gfxmode(); + + quit_message_on_exit(qmsg, alertis, qreason); + + quit_release_data(); + + // release backed library + // WARNING: no Allegro objects should remain in memory after this, + // if their destruction is called later, program will crash! + allegro_exit(); + + platform->PostAllegroExit(); + + our_eip = 9903; + + quit_delete_temp_files(); + + proper_exit=1; + + Debug::Printf(kDbgMsg_Alert, "***** ENGINE HAS SHUTDOWN"); + + shutdown_debug(); + + our_eip = 9904; + exit(EXIT_NORMAL); +} + +extern "C" { + void quit_c(char*msg) { + quit(msg); + } +} diff --git a/engines/ags/engine/main/quit.h b/engines/ags/engine/main/quit.h new file mode 100644 index 000000000000..4eac73fdf684 --- /dev/null +++ b/engines/ags/engine/main/quit.h @@ -0,0 +1,45 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__QUIT_H +#define __AGS_EE_MAIN__QUIT_H + +enum QuitReason +{ + kQuitKind_NormalExit = 0x01, + kQuitKind_DeliberateAbort = 0x02, + kQuitKind_GameException = 0x04, + kQuitKind_EngineException = 0x08, + + // user closed the window or script command QuitGame was executed + kQuit_GameRequest = kQuitKind_NormalExit | 0x10, + + // user pressed abort game key + kQuit_UserAbort = kQuitKind_DeliberateAbort | 0x20, + + // script command AbortGame was executed + kQuit_ScriptAbort = kQuitKind_GameException | 0x10, + // game logic has generated a warning and warnings are treated as error + kQuit_GameWarning = kQuitKind_GameException | 0x20, + // game logic has generated an error (often script error) + kQuit_GameError = kQuitKind_GameException | 0x30, + + // any kind of a fatal engine error + kQuit_FatalError = kQuitKind_EngineException +}; + +#endif // __AGS_EE_MAIN__QUIT_H diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp new file mode 100644 index 000000000000..c7ede5321970 --- /dev/null +++ b/engines/ags/engine/main/update.cpp @@ -0,0 +1,497 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +// +// Game update procedure +// + +#include +#include "ac/common.h" +#include "ac/character.h" +#include "ac/characterextras.h" +#include "ac/draw.h" +#include "ac/gamestate.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_character.h" +#include "ac/lipsync.h" +#include "ac/overlay.h" +#include "ac/sys_events.h" +#include "ac/roomobject.h" +#include "ac/roomstatus.h" +#include "main/mainheader.h" +#include "main/update.h" +#include "ac/screenoverlay.h" +#include "ac/viewframe.h" +#include "ac/walkablearea.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" +#include "media/audio/audio_system.h" +#include "ac/timer.h" +#include "main/game_run.h" +#include "ac/movelist.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern MoveList *mls; +extern RoomStatus*croom; +extern GameSetupStruct game; +extern GameState play; +extern RoomStruct thisroom; +extern RoomObject*objs; +extern ViewStruct*views; +extern int our_eip; +extern CharacterInfo*playerchar; +extern CharacterExtras *charextra; +extern CharacterInfo *facetalkchar; +extern int face_talking,facetalkview,facetalkwait,facetalkframe; +extern int facetalkloop, facetalkrepeat, facetalkAllowBlink; +extern int facetalkBlinkLoop; +extern bool facetalk_qfg4_override_placement_x, facetalk_qfg4_override_placement_y; +extern SpeechLipSyncLine *splipsync; +extern int numLipLines, curLipLine, curLipLinePhoneme; +extern int is_text_overlay; +extern IGraphicsDriver *gfxDriver; + +int do_movelist_move(short*mlnum,int*xx,int*yy) { + int need_to_fix_sprite=0; + if (mlnum[0]<1) quit("movelist_move: attempted to move on a non-exist movelist"); + MoveList*cmls; cmls=&mls[mlnum[0]]; + fixed xpermove=cmls->xpermove[cmls->onstage],ypermove=cmls->ypermove[cmls->onstage]; + + short targetx=short((cmls->pos[cmls->onstage+1] >> 16) & 0x00ffff); + short targety=short(cmls->pos[cmls->onstage+1] & 0x00ffff); + int xps=xx[0],yps=yy[0]; + if (cmls->doneflag & 1) { + // if the X-movement has finished, and the Y-per-move is < 1, finish + // This can cause jump at the end, but without it the character will + // walk on the spot for a while if the Y-per-move is for example 0.2 +// if ((ypermove & 0xfffff000) == 0) cmls->doneflag|=2; +// int ypmm=(ypermove >> 16) & 0x0000ffff; + + // NEW 2.15 SR-1 plan: if X-movement has finished, and Y-per-move is < 1, + // allow it to finish more easily by moving target zone + + int adjAmnt = 3; + // 2.70: if the X permove is also <=1, don't do the skipping + if (((xpermove & 0xffff0000) == 0xffff0000) || + ((xpermove & 0xffff0000) == 0x00000000)) + adjAmnt = 2; + + // 2.61 RC1: correct this to work with > -1 as well as < 1 + if (ypermove == 0) { } + // Y per move is < 1, so finish the move + else if ((ypermove & 0xffff0000) == 0) + targety -= adjAmnt; + // Y per move is -1 exactly, don't snap to finish + else if (ypermove == 0xffff0000) { } + // Y per move is > -1, so finish the move + else if ((ypermove & 0xffff0000) == 0xffff0000) + targety += adjAmnt; + } + else xps=cmls->fromx+(int)(fixtof(xpermove)*(float)cmls->onpart); + + if (cmls->doneflag & 2) { + // Y-movement has finished + + int adjAmnt = 3; + + // if the Y permove is also <=1, don't skip as far + if (((ypermove & 0xffff0000) == 0xffff0000) || + ((ypermove & 0xffff0000) == 0x00000000)) + adjAmnt = 2; + + if (xpermove == 0) { } + // Y per move is < 1, so finish the move + else if ((xpermove & 0xffff0000) == 0) + targetx -= adjAmnt; + // X per move is -1 exactly, don't snap to finish + else if (xpermove == 0xffff0000) { } + // X per move is > -1, so finish the move + else if ((xpermove & 0xffff0000) == 0xffff0000) + targetx += adjAmnt; + +/* int xpmm=(xpermove >> 16) & 0x0000ffff; +// if ((xpmm==0) | (xpmm==0xffff)) cmls->doneflag|=1; + if (xpmm==0) cmls->doneflag|=1;*/ + } + else yps=cmls->fromy+(int)(fixtof(ypermove)*(float)cmls->onpart); + // check if finished horizontal movement + if (((xpermove > 0) && (xps >= targetx)) || + ((xpermove < 0) && (xps <= targetx))) { + cmls->doneflag|=1; + xps = targetx; + // if the Y is almost there too, finish it + // this is new in v2.40 + // removed in 2.70 + /*if (abs(yps - targety) <= 2) + yps = targety;*/ + } + else if (xpermove == 0) + cmls->doneflag|=1; + // check if finished vertical movement + if ((ypermove > 0) & (yps>=targety)) { + cmls->doneflag|=2; + yps = targety; + } + else if ((ypermove < 0) & (yps<=targety)) { + cmls->doneflag|=2; + yps = targety; + } + else if (ypermove == 0) + cmls->doneflag|=2; + + if ((cmls->doneflag & 0x03)==3) { + // this stage is done, go on to the next stage + // signed shorts to ensure that numbers like -20 do not become 65515 + cmls->fromx=(signed short)((cmls->pos[cmls->onstage+1] >> 16) & 0x000ffff); + cmls->fromy=(signed short)(cmls->pos[cmls->onstage+1] & 0x000ffff); + if ((cmls->fromx > 65000) || (cmls->fromy > 65000)) + quit("do_movelist: int to short rounding error"); + + cmls->onstage++; cmls->onpart=-1; cmls->doneflag&=0xf0; + cmls->lastx=-1; + if (cmls->onstage < cmls->numstage) { + xps=cmls->fromx; yps=cmls->fromy; } + if (cmls->onstage>=cmls->numstage-1) { // last stage is just dest pos + cmls->numstage=0; + mlnum[0]=0; + need_to_fix_sprite=1; + } + else need_to_fix_sprite=2; + } + cmls->onpart++; + xx[0]=xps; yy[0]=yps; + return need_to_fix_sprite; + } + + +void update_script_timers() +{ + if (play.gscript_timer > 0) play.gscript_timer--; + for (int aa=0;aa 1) play.script_timers[aa]--; + } +} + +void update_cycling_views() +{ + // update graphics for object if cycling view + for (int aa=0;aanumobj;aa++) { + + RoomObject * obj = &objs[aa]; + + obj->UpdateCyclingView(); + } +} + +void update_shadow_areas() +{ + // shadow areas + int onwalkarea = get_walkable_area_at_character (game.playercharacter); + if (onwalkarea<0) ; + else if (playerchar->flags & CHF_FIXVIEW) ; + else { onwalkarea=thisroom.WalkAreas[onwalkarea].Light; + if (onwalkarea>0) playerchar->view=onwalkarea-1; + else if (thisroom.Options.PlayerView==0) playerchar->view=playerchar->defview; + else playerchar->view=thisroom.Options.PlayerView-1; + } +} + +void update_character_move_and_anim(int &numSheep, int *followingAsSheep) +{ + // move & animate characters + for (int aa=0;aaUpdateMoveAndAnim(aa, chex, numSheep, followingAsSheep); + } +} + +void update_following_exactly_characters(int &numSheep, int *followingAsSheep) +{ + // update location of all following_exactly characters + for (int aa = 0; aa < numSheep; aa++) { + CharacterInfo *chi = &game.chars[followingAsSheep[aa]]; + + chi->UpdateFollowingExactlyCharacter(); + } +} + +void update_overlay_timers() +{ + // update overlay timers + for (size_t i = 0; i < screenover.size();) { + if (screenover[i].timeout > 0) { + screenover[i].timeout--; + if (screenover[i].timeout == 0) + { + remove_screen_overlay_index(i); + continue; + } + } + i++; + } +} + +void update_speech_and_messages() +{ + bool is_voice_playing = false; + if (play.speech_has_voice) + { + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_SPEECH); + is_voice_playing = ch && ch->is_playing(); + } + // determine if speech text should be removed + if (play.messagetime>=0) { + play.messagetime--; + // extend life of text if the voice hasn't finished yet + if (play.speech_has_voice && !play.speech_in_post_state) { + if ((is_voice_playing) && (play.fast_forward == 0)) { + if (play.messagetime <= 1) + play.messagetime = 1; + } + else // if the voice has finished, remove the speech + play.messagetime = 0; + } + + if (play.messagetime < 1 && play.speech_display_post_time_ms > 0 && + play.fast_forward == 0) + { + if (!play.speech_in_post_state) + { + play.messagetime = ::lround(play.speech_display_post_time_ms * get_current_fps() / 1000.0f); + } + play.speech_in_post_state = !play.speech_in_post_state; + } + + if (play.messagetime < 1) + { + if (play.fast_forward > 0) + { + remove_screen_overlay(OVER_TEXTMSG); + } + else if (play.cant_skip_speech & SKIP_AUTOTIMER) + { + remove_screen_overlay(OVER_TEXTMSG); + play.SetIgnoreInput(play.ignore_user_input_after_text_timeout_ms); + } + } + } +} + +// update sierra-style speech +void update_sierra_speech() +{ + int voice_pos_ms = -1; + if (play.speech_has_voice) + { + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_SPEECH); + voice_pos_ms = ch ? ch->get_pos_ms() : -1; + } + if ((face_talking >= 0) && (play.fast_forward == 0)) + { + int updatedFrame = 0; + + if ((facetalkchar->blinkview > 0) && (facetalkAllowBlink)) { + if (facetalkchar->blinktimer > 0) { + // countdown to playing blink anim + facetalkchar->blinktimer--; + if (facetalkchar->blinktimer == 0) { + facetalkchar->blinkframe = 0; + facetalkchar->blinktimer = -1; + updatedFrame = 2; + } + } + else if (facetalkchar->blinktimer < 0) { + // currently playing blink anim + if (facetalkchar->blinktimer < ( (0 - 6) - views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe].speed)) { + // time to advance to next frame + facetalkchar->blinktimer = -1; + facetalkchar->blinkframe++; + updatedFrame = 2; + if (facetalkchar->blinkframe >= views[facetalkchar->blinkview].loops[facetalkBlinkLoop].numFrames) + { + facetalkchar->blinkframe = 0; + facetalkchar->blinktimer = facetalkchar->blinkinterval; + } + } + else + facetalkchar->blinktimer--; + } + + } + + if (curLipLine >= 0) { + // check voice lip sync + if (curLipLinePhoneme >= splipsync[curLipLine].numPhonemes) { + // the lip-sync has finished, so just stay idle + } + else + { + while ((curLipLinePhoneme < splipsync[curLipLine].numPhonemes) && + ((curLipLinePhoneme < 0) || (voice_pos_ms >= splipsync[curLipLine].endtimeoffs[curLipLinePhoneme]))) + { + curLipLinePhoneme ++; + if (curLipLinePhoneme >= splipsync[curLipLine].numPhonemes) + facetalkframe = game.default_lipsync_frame; + else + facetalkframe = splipsync[curLipLine].frame[curLipLinePhoneme]; + + if (facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) + facetalkframe = 0; + + updatedFrame |= 1; + } + } + } + else if (facetalkwait>0) facetalkwait--; + // don't animate if the speech has finished + else if ((play.messagetime < 1) && (facetalkframe == 0) && + // if play.close_mouth_speech_time = 0, this means animation should play till + // the speech ends; but this should not work in voice mode, and also if the + // speech is in the "post" state + (play.speech_has_voice || play.speech_in_post_state || play.close_mouth_speech_time > 0)) + ; + else { + // Close mouth at end of sentence: if speech has entered the "post" state, + // or if this is a text only mode and close_mouth_speech_time is set + if (play.speech_in_post_state || + (!play.speech_has_voice && + (play.messagetime < play.close_mouth_speech_time) && + (play.close_mouth_speech_time > 0))) { + facetalkframe = 0; + facetalkwait = play.messagetime; + } + else if ((game.options[OPT_LIPSYNCTEXT]) && (facetalkrepeat > 0)) { + // lip-sync speech (and not a thought) + facetalkwait = update_lip_sync (facetalkview, facetalkloop, &facetalkframe); + // It is actually displayed for facetalkwait+1 loops + // (because when it's 1, it gets --'d then wait for next time) + facetalkwait --; + } + else { + // normal non-lip-sync + facetalkframe++; + if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) || + (!play.speech_has_voice && (play.messagetime < 1) && (play.close_mouth_speech_time > 0))) { + + if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) && + (views[facetalkview].loops[facetalkloop].RunNextLoop())) + { + facetalkloop++; + } + else + { + facetalkloop = 0; + } + facetalkframe = 0; + if (!facetalkrepeat) + facetalkwait = 999999; + } + if ((facetalkframe != 0) || (facetalkrepeat == 1)) + facetalkwait = views[facetalkview].loops[facetalkloop].frames[facetalkframe].speed + GetCharacterSpeechAnimationDelay(facetalkchar); + } + updatedFrame |= 1; + } + + // is_text_overlay might be 0 if it was only just destroyed this loop + if ((updatedFrame) && (is_text_overlay > 0)) { + + if (updatedFrame & 1) + CheckViewFrame (facetalkview, facetalkloop, facetalkframe); + if (updatedFrame & 2) + CheckViewFrame (facetalkchar->blinkview, facetalkBlinkLoop, facetalkchar->blinkframe); + + int thisPic = views[facetalkview].loops[facetalkloop].frames[facetalkframe].pic; + int view_frame_x = 0; + int view_frame_y = 0; + + if (game.options[OPT_SPEECHTYPE] == 3) { + // QFG4-style fullscreen dialog + if (facetalk_qfg4_override_placement_x) + { + view_frame_x = play.speech_portrait_x; + } + if (facetalk_qfg4_override_placement_y) + { + view_frame_y = play.speech_portrait_y; + } + else + { + view_frame_y = (screenover[face_talking].pic->GetHeight() / 2) - (game.SpriteInfos[thisPic].Height / 2); + } + screenover[face_talking].pic->Clear(0); + } + else { + screenover[face_talking].pic->ClearTransparent(); + } + + Bitmap *frame_pic = screenover[face_talking].pic; + const ViewFrame *face_vf = &views[facetalkview].loops[facetalkloop].frames[facetalkframe]; + bool face_has_alpha = (game.SpriteInfos[face_vf->pic].Flags & SPF_ALPHACHANNEL) != 0; + DrawViewFrame(frame_pic, face_vf, view_frame_x, view_frame_y); + + if ((facetalkchar->blinkview > 0) && (facetalkchar->blinktimer < 0)) { + ViewFrame *blink_vf = &views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe]; + face_has_alpha |= (game.SpriteInfos[blink_vf->pic].Flags & SPF_ALPHACHANNEL) != 0; + // draw the blinking sprite on top + DrawViewFrame(frame_pic, blink_vf, view_frame_x, view_frame_y, face_has_alpha); + } + + gfxDriver->UpdateDDBFromBitmap(screenover[face_talking].bmp, screenover[face_talking].pic, face_has_alpha); + } // end if updatedFrame + } +} + +// update_stuff: moves and animates objects, executes repeat scripts, and +// the like. +void update_stuff() { + + our_eip = 20; + + update_script_timers(); + + update_cycling_views(); + + our_eip = 21; + + update_shadow_areas(); + + our_eip = 22; + + int numSheep = 0; + int followingAsSheep[MAX_SHEEP]; + + update_character_move_and_anim(numSheep, followingAsSheep); + + update_following_exactly_characters(numSheep, followingAsSheep); + + our_eip = 23; + + update_overlay_timers(); + + update_speech_and_messages(); + + our_eip = 24; + + update_sierra_speech(); + + our_eip = 25; +} diff --git a/engines/ags/engine/main/update.h b/engines/ags/engine/main/update.h new file mode 100644 index 000000000000..0017787ae452 --- /dev/null +++ b/engines/ags/engine/main/update.h @@ -0,0 +1,26 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MAIN__UPDATE_H +#define __AGS_EE_MAIN__UPDATE_H + +#define MAX_SHEEP 30 // sheep == follower + +int do_movelist_move(short*mlnum,int*xx,int*yy); +void update_stuff(); + +#endif // __AGS_EE_MAIN__UPDATE_H diff --git a/engines/ags/engine/media/audio/ambientsound.cpp b/engines/ags/engine/media/audio/ambientsound.cpp new file mode 100644 index 000000000000..f5b0e7ff0d1c --- /dev/null +++ b/engines/ags/engine/media/audio/ambientsound.cpp @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/ambientsound.h" +#include "media/audio/audio.h" +#include "media/audio/soundclip.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +bool AmbientSound::IsPlaying () { + if (channel <= 0) + return false; + return channel_is_playing(channel); +} + +void AmbientSound::ReadFromFile(Stream *in) +{ + channel = in->ReadInt32(); + x = in->ReadInt32(); + y = in->ReadInt32(); + vol = in->ReadInt32(); + num = in->ReadInt32(); + maxdist = in->ReadInt32(); +} + +void AmbientSound::WriteToFile(Stream *out) +{ + out->WriteInt32(channel); + out->WriteInt32(x); + out->WriteInt32(y); + out->WriteInt32(vol); + out->WriteInt32(num); + out->WriteInt32(maxdist); +} diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h new file mode 100644 index 000000000000..7117d3647947 --- /dev/null +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_AMBIENTSOUND_H +#define __AC_AMBIENTSOUND_H + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define AMBIENCE_FULL_DIST 25 + +struct AmbientSound { + int channel; // channel number, 1 upwards + int x,y; + int vol; + int num; // sound number, eg. 3 = sound3.wav + int maxdist; + + bool IsPlaying(); + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); +}; + +#endif // __AC_AMBIENTSOUND_H diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp new file mode 100644 index 000000000000..2a0a7d073c7d --- /dev/null +++ b/engines/ags/engine/media/audio/audio.cpp @@ -0,0 +1,1228 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include + +#include "core/platform.h" +#include "util/wgt2allg.h" +#include "media/audio/audio.h" +#include "ac/audiocliptype.h" +#include "ac/gamesetupstruct.h" +#include "ac/dynobj/cc_audioclip.h" +#include "ac/dynobj/cc_audiochannel.h" +#include "ac/gamestate.h" +#include "script/script_runtime.h" +#include "ac/audiochannel.h" +#include "ac/audioclip.h" +#include "ac/gamesetup.h" +#include "ac/path_helper.h" +#include "media/audio/sound.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "ac/common.h" +#include "ac/file.h" +#include "ac/global_audio.h" +#include +#include "util/stream.h" +#include "core/assetmanager.h" +#include "ac/timer.h" +#include "main/game_run.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +//----------------------- +//sound channel management; all access goes through here, which can't be done without a lock + +static std::array _channels; +AGS::Engine::Mutex AudioChannelsLock::s_mutex; + +SOUNDCLIP *AudioChannelsLock::GetChannel(int index) +{ + return _channels[index]; +} + +SOUNDCLIP *AudioChannelsLock::GetChannelIfPlaying(int index) +{ + auto *ch = _channels[index]; + return (ch != nullptr && ch->is_playing()) ? ch : nullptr; +} + +SOUNDCLIP *AudioChannelsLock::SetChannel(int index, SOUNDCLIP* ch) +{ + // TODO: store clips in smart pointers + if (_channels[index] == ch) + Debug::Printf(kDbgMsg_Warn, "WARNING: channel %d - same clip assigned", index); + else if (_channels[index] != nullptr && ch != nullptr) + Debug::Printf(kDbgMsg_Warn, "WARNING: channel %d - clip overwritten", index); + _channels[index] = ch; + return ch; +} + +SOUNDCLIP *AudioChannelsLock::MoveChannel(int to, int from) +{ + auto from_ch = _channels[from]; + _channels[from] = nullptr; + return SetChannel(to, from_ch); +} + +//----------------------- +// Channel helpers + +bool channel_has_clip(int chanid) +{ + AudioChannelsLock lock; + return lock.GetChannel(chanid) != nullptr; +} + +bool channel_is_playing(int chanid) +{ + AudioChannelsLock lock; + return lock.GetChannelIfPlaying(chanid) != nullptr; +} + +void set_clip_to_channel(int chanid, SOUNDCLIP *clip) +{ + AudioChannelsLock lock; + lock.SetChannel(chanid, clip); +} +//----------------------- + +volatile bool _audio_doing_crossfade; + +extern GameSetupStruct game; +extern GameSetup usetup; +extern GameState play; +extern RoomStruct thisroom; +extern CharacterInfo*playerchar; + +extern volatile int switching_away_from_game; + +#if ! AGS_PLATFORM_OS_IOS && ! AGS_PLATFORM_OS_ANDROID +volatile int psp_audio_multithreaded = 0; +#endif + +ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; +char acaudio_buffer[256]; +int reserved_channel_count = 0; + +AGS::Engine::Thread audioThread; + +void calculate_reserved_channel_count() +{ + int reservedChannels = 0; + for (size_t i = 0; i < game.audioClipTypes.size(); i++) + { + reservedChannels += game.audioClipTypes[i].reservedChannels; + } + reserved_channel_count = reservedChannels; +} + +void update_clip_default_volume(ScriptAudioClip *audioClip) +{ + if (play.default_audio_type_volumes[audioClip->type] >= 0) + { + audioClip->defaultVolume = play.default_audio_type_volumes[audioClip->type]; + } +} + +void start_fading_in_new_track_if_applicable(int fadeInChannel, ScriptAudioClip *newSound) +{ + int crossfadeSpeed = game.audioClipTypes[newSound->type].crossfadeSpeed; + if (crossfadeSpeed > 0) + { + update_clip_default_volume(newSound); + play.crossfade_in_volume_per_step = crossfadeSpeed; + play.crossfade_final_volume_in = newSound->defaultVolume; + play.crossfading_in_channel = fadeInChannel; + } +} + +static void move_track_to_crossfade_channel(int currentChannel, int crossfadeSpeed, int fadeInChannel, ScriptAudioClip *newSound) +{ + AudioChannelsLock lock; + stop_and_destroy_channel(SPECIAL_CROSSFADE_CHANNEL); + auto *cfade_clip = lock.MoveChannel(SPECIAL_CROSSFADE_CHANNEL, currentChannel); + if (!cfade_clip) + return; + + play.crossfading_out_channel = SPECIAL_CROSSFADE_CHANNEL; + play.crossfade_step = 0; + play.crossfade_initial_volume_out = cfade_clip->get_volume(); + play.crossfade_out_volume_per_step = crossfadeSpeed; + + play.crossfading_in_channel = fadeInChannel; + if (newSound != nullptr) + { + start_fading_in_new_track_if_applicable(fadeInChannel, newSound); + } +} + +void stop_or_fade_out_channel(int fadeOutChannel, int fadeInChannel, ScriptAudioClip *newSound) +{ + ScriptAudioClip *sourceClip = AudioChannel_GetPlayingClip(&scrAudioChannel[fadeOutChannel]); + if ((sourceClip != nullptr) && (game.audioClipTypes[sourceClip->type].crossfadeSpeed > 0)) + { + move_track_to_crossfade_channel(fadeOutChannel, game.audioClipTypes[sourceClip->type].crossfadeSpeed, fadeInChannel, newSound); + } + else + { + stop_and_destroy_channel(fadeOutChannel); + } +} + +static int find_free_audio_channel(ScriptAudioClip *clip, int priority, bool interruptEqualPriority) +{ + AudioChannelsLock lock; + + int lowestPrioritySoFar = 9999999; + int lowestPriorityID = -1; + int channelToUse = -1; + + if (!interruptEqualPriority) + priority--; + + int startAtChannel = reserved_channel_count; + int endBeforeChannel = MAX_SOUND_CHANNELS; + + if (game.audioClipTypes[clip->type].reservedChannels > 0) + { + startAtChannel = 0; + for (int i = 0; i < clip->type; i++) + { + startAtChannel += game.audioClipTypes[i].reservedChannels; + } + endBeforeChannel = startAtChannel + game.audioClipTypes[clip->type].reservedChannels; + } + + for (int i = startAtChannel; i < endBeforeChannel; i++) + { + auto* ch = lock.GetChannelIfPlaying(i); + if (ch == nullptr) + { + channelToUse = i; + stop_and_destroy_channel(i); + break; + } + if ((ch->priority < lowestPrioritySoFar) && + (ch->sourceClipType == clip->type)) + { + lowestPrioritySoFar = ch->priority; + lowestPriorityID = i; + } + } + + if ((channelToUse < 0) && (lowestPriorityID >= 0) && + (lowestPrioritySoFar <= priority)) + { + stop_or_fade_out_channel(lowestPriorityID, lowestPriorityID, clip); + channelToUse = lowestPriorityID; + } + else if ((channelToUse >= 0) && (play.crossfading_in_channel < 1)) + { + start_fading_in_new_track_if_applicable(channelToUse, clip); + } + return channelToUse; +} + +bool is_audiotype_allowed_to_play(AudioFileType type) +{ + return (type == eAudioFileMIDI && usetup.midicard != MIDI_NONE) || + (type != eAudioFileMIDI && usetup.digicard != DIGI_NONE); +} + +SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat) +{ + if (!is_audiotype_allowed_to_play((AudioFileType)audioClip->fileType)) + { + return nullptr; + } + + update_clip_default_volume(audioClip); + + SOUNDCLIP *soundClip = nullptr; + AssetPath asset_name = get_audio_clip_assetpath(audioClip->bundlingType, audioClip->fileName); + switch (audioClip->fileType) + { + case eAudioFileOGG: + soundClip = my_load_static_ogg(asset_name, audioClip->defaultVolume, repeat); + break; + case eAudioFileMP3: + soundClip = my_load_static_mp3(asset_name, audioClip->defaultVolume, repeat); + break; + case eAudioFileWAV: + case eAudioFileVOC: + soundClip = my_load_wave(asset_name, audioClip->defaultVolume, repeat); + break; + case eAudioFileMIDI: + soundClip = my_load_midi(asset_name, repeat); + break; + case eAudioFileMOD: +#ifndef PSP_NO_MOD_PLAYBACK + soundClip = my_load_mod(asset_name, repeat); +#else + soundClip = NULL; +#endif + break; + default: + quitprintf("AudioClip.Play: invalid audio file type encountered: %d", audioClip->fileType); + } + if (soundClip != nullptr) + { + soundClip->set_volume_percent(audioClip->defaultVolume); + soundClip->sourceClip = audioClip; + soundClip->sourceClipType = audioClip->type; + } + return soundClip; +} + +static void audio_update_polled_stuff() +{ + /////////////////////////////////////////////////////////////////////////// + // Do crossfade + play.crossfade_step++; + + AudioChannelsLock lock; + + if (play.crossfading_out_channel > 0 && !lock.GetChannelIfPlaying(play.crossfading_out_channel)) + play.crossfading_out_channel = 0; + + if (play.crossfading_out_channel > 0) + { + SOUNDCLIP* ch = lock.GetChannel(play.crossfading_out_channel); + int newVolume = ch ? ch->get_volume() - play.crossfade_out_volume_per_step : 0; + if (newVolume > 0) + { + AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_out_channel], newVolume); + } + else + { + stop_and_destroy_channel(play.crossfading_out_channel); + play.crossfading_out_channel = 0; + } + } + + if (play.crossfading_in_channel > 0 && !lock.GetChannelIfPlaying(play.crossfading_in_channel)) + play.crossfading_in_channel = 0; + + if (play.crossfading_in_channel > 0) + { + SOUNDCLIP* ch = lock.GetChannel(play.crossfading_in_channel); + int newVolume = ch ? ch->get_volume() + play.crossfade_in_volume_per_step : 0; + if (newVolume > play.crossfade_final_volume_in) + { + newVolume = play.crossfade_final_volume_in; + } + + AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_in_channel], newVolume); + + if (newVolume >= play.crossfade_final_volume_in) + { + play.crossfading_in_channel = 0; + } + } + + /////////////////////////////////////////////////////////////////////////// + // Do audio queue + if (play.new_music_queue_size > 0) + { + for (int i = 0; i < play.new_music_queue_size; i++) + { + ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[i].audioClipIndex]; + int channel = find_free_audio_channel(clip, clip->defaultPriority, false); + if (channel >= 0) + { + QueuedAudioItem itemToPlay = play.new_music_queue[i]; + + play.new_music_queue_size--; + for (int j = i; j < play.new_music_queue_size; j++) + { + play.new_music_queue[j] = play.new_music_queue[j + 1]; + } + + play_audio_clip_on_channel(channel, clip, itemToPlay.priority, itemToPlay.repeat, 0, itemToPlay.cachedClip); + i--; + } + } + } + + /////////////////////////////////////////////////////////////////////////// + // Do non-blocking voice speech + // NOTE: there's only one speech channel, therefore it's either blocking + // or non-blocking at any given time. If it's changed, we'd need to keep + // record of every channel, or keep a count of active channels. + if (play.IsNonBlockingVoiceSpeech()) + { + if (!channel_is_playing(SCHAN_SPEECH)) + { + stop_voice_nonblocking(); + } + } +} + +// Applies a volume drop modifier to the clip, in accordance to its audio type +static void apply_volume_drop_to_clip(SOUNDCLIP *clip) +{ + int audiotype = clip->sourceClipType; + clip->apply_volume_modifier(-(game.audioClipTypes[audiotype].volume_reduction_while_speech_playing * 255 / 100)); +} + +static void queue_audio_clip_to_play(ScriptAudioClip *clip, int priority, int repeat) +{ + if (play.new_music_queue_size >= MAX_QUEUED_MUSIC) { + debug_script_log("Too many queued music, cannot add %s", clip->scriptName.GetCStr()); + return; + } + + SOUNDCLIP *cachedClip = load_sound_clip(clip, (repeat != 0)); + if (cachedClip != nullptr) + { + play.new_music_queue[play.new_music_queue_size].audioClipIndex = clip->id; + play.new_music_queue[play.new_music_queue_size].priority = priority; + play.new_music_queue[play.new_music_queue_size].repeat = (repeat != 0); + play.new_music_queue[play.new_music_queue_size].cachedClip = cachedClip; + play.new_music_queue_size++; + } + + update_polled_mp3(); +} + +ScriptAudioChannel* play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *soundfx) +{ + if (soundfx == nullptr) + { + soundfx = load_sound_clip(clip, (repeat) ? true : false); + } + if (soundfx == nullptr) + { + debug_script_log("AudioClip.Play: unable to load sound file"); + if (play.crossfading_in_channel == channel) + { + play.crossfading_in_channel = 0; + } + return nullptr; + } + soundfx->priority = priority; + + if (play.crossfading_in_channel == channel) + { + soundfx->set_volume_percent(0); + } + + // Mute the audio clip if fast-forwarding the cutscene + if (play.fast_forward) + { + soundfx->set_mute(true); + + // CHECKME!! + // [IKM] According to the 3.2.1 logic the clip will restore + // its value after cutscene, but only if originalVolAsPercentage + // is not zeroed. Something I am not sure about: why does it + // disable the clip under condition that there's more than one + // channel for this audio type? It does not even check if + // anything of this type is currently playing. + if (game.audioClipTypes[clip->type].reservedChannels != 1) + soundfx->set_volume_percent(0); + } + + if (soundfx->play_from(fromOffset) == 0) + { + // not assigned to a channel, so clean up manually. + soundfx->destroy(); + delete soundfx; + soundfx = nullptr; + debug_script_log("AudioClip.Play: failed to play sound file"); + return nullptr; + } + + // Apply volume drop if any speech voice-over is currently playing + // NOTE: there is a confusing logic in sound clip classes, that they do not use + // any modifiers when begin playing, therefore we must apply this only after + // playback was started. + if (!play.fast_forward && play.speech_has_voice) + apply_volume_drop_to_clip(soundfx); + + set_clip_to_channel(channel, soundfx); + return &scrAudioChannel[channel]; +} + +void remove_clips_of_type_from_queue(int audioType) +{ + int aa; + for (aa = 0; aa < play.new_music_queue_size; aa++) + { + ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[aa].audioClipIndex]; + if (clip->type == audioType) + { + play.new_music_queue_size--; + for (int bb = aa; bb < play.new_music_queue_size; bb++) + play.new_music_queue[bb] = play.new_music_queue[bb + 1]; + aa--; + } + } +} + +void update_queued_clips_volume(int audioType, int new_vol) +{ + for (int i = 0; i < play.new_music_queue_size; ++i) + { + // NOTE: if clip is uncached, the volume will be set from defaults when it is loaded + SOUNDCLIP *sndclip = play.new_music_queue[i].cachedClip; + if (sndclip) + { + ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[i].audioClipIndex]; + if (clip->type == audioType) + sndclip->set_volume_percent(new_vol); + } + } +} + +ScriptAudioChannel* play_audio_clip(ScriptAudioClip *clip, int priority, int repeat, int fromOffset, bool queueIfNoChannel) +{ + if (!queueIfNoChannel) + remove_clips_of_type_from_queue(clip->type); + + if (priority == SCR_NO_VALUE) + priority = clip->defaultPriority; + if (repeat == SCR_NO_VALUE) + repeat = clip->defaultRepeat; + + int channel = find_free_audio_channel(clip, priority, !queueIfNoChannel); + if (channel < 0) + { + if (queueIfNoChannel) + queue_audio_clip_to_play(clip, priority, repeat); + else + debug_script_log("AudioClip.Play: no channels available to interrupt PRI:%d TYPE:%d", priority, clip->type); + + return nullptr; + } + + return play_audio_clip_on_channel(channel, clip, priority, repeat, fromOffset); +} + +ScriptAudioChannel* play_audio_clip_by_index(int audioClipIndex) +{ + if ((audioClipIndex >= 0) && ((size_t)audioClipIndex < game.audioClips.size())) + return AudioClip_Play(&game.audioClips[audioClipIndex], SCR_NO_VALUE, SCR_NO_VALUE); + else + return nullptr; +} + +void stop_and_destroy_channel_ex(int chid, bool resetLegacyMusicSettings) +{ + if ((chid < 0) || (chid > MAX_SOUND_CHANNELS)) + quit("!StopChannel: invalid channel ID"); + + AudioChannelsLock lock; + SOUNDCLIP* ch = lock.GetChannel(chid); + + if (ch != nullptr) { + ch->destroy(); + delete ch; + lock.SetChannel(chid, nullptr); + ch = nullptr; + } + + if (play.crossfading_in_channel == chid) + play.crossfading_in_channel = 0; + if (play.crossfading_out_channel == chid) + play.crossfading_out_channel = 0; + // don't update 'crossFading' here as it is updated in all the cross-fading functions. + + // destroyed an ambient sound channel + if (ambient[chid].channel > 0) + ambient[chid].channel = 0; + + if ((chid == SCHAN_MUSIC) && (resetLegacyMusicSettings)) + { + play.cur_music_number = -1; + current_music_type = 0; + } +} + +void stop_and_destroy_channel(int chid) +{ + stop_and_destroy_channel_ex(chid, true); +} + + + +// ***** BACKWARDS COMPATIBILITY WITH OLD AUDIO SYSTEM ***** // + +int get_old_style_number_for_sound(int sound_number) +{ + int audio_clip_id = 0; + + if (game.IsLegacyAudioSystem()) + { + // No sound assigned. + if (sound_number < 1) + return 0; + + // Sound number is not yet updated to audio clip id. + if (sound_number <= 0x10000000) + return sound_number; + + // Remove audio clip id flag. + audio_clip_id = sound_number - 0x10000000; + } + else + audio_clip_id = sound_number; + + if (audio_clip_id >= 0) + { + int old_style_number = 0; + if (sscanf(game.audioClips[audio_clip_id].scriptName.GetCStr(), "aSound%d", &old_style_number) == 1) + return old_style_number; + } + return 0; +} + +SOUNDCLIP *load_sound_clip_from_old_style_number(bool isMusic, int indexNumber, bool repeat) +{ + ScriptAudioClip* audioClip = GetAudioClipForOldStyleNumber(game, isMusic, indexNumber); + + if (audioClip != nullptr) + { + return load_sound_clip(audioClip, repeat); + } + + return nullptr; +} + +//============================================================================= + +void force_audiostream_include() { + // This should never happen, but the call is here to make it + // link the audiostream libraries + stop_audio_stream(nullptr); +} + +// TODO: double check that ambient sounds array actually needs +1 +std::array ambient; + +int get_volume_adjusted_for_distance(int volume, int sndX, int sndY, int sndMaxDist) +{ + int distx = playerchar->x - sndX; + int disty = playerchar->y - sndY; + // it uses Allegro's "fix" sqrt without the :: + int dist = (int)::sqrt((double)(distx*distx + disty*disty)); + + // if they're quite close, full volume + int wantvol = volume; + + if (dist >= AMBIENCE_FULL_DIST) + { + // get the relative volume + wantvol = ((dist - AMBIENCE_FULL_DIST) * volume) / sndMaxDist; + // closer is louder + wantvol = volume - wantvol; + } + + return wantvol; +} + +void update_directional_sound_vol() +{ + AudioChannelsLock lock; + + for (int chnum = 1; chnum < MAX_SOUND_CHANNELS; chnum++) + { + auto* ch = lock.GetChannelIfPlaying(chnum); + if ((ch != nullptr) && (ch->xSource >= 0)) + { + ch->apply_directional_modifier( + get_volume_adjusted_for_distance(ch->vol, + ch->xSource, + ch->ySource, + ch->maximumPossibleDistanceAway) - + ch->vol); + } + } +} + +void update_ambient_sound_vol () +{ + AudioChannelsLock lock; + + for (int chan = 1; chan < MAX_SOUND_CHANNELS; chan++) { + + AmbientSound *thisSound = &ambient[chan]; + + if (thisSound->channel == 0) + continue; + + int sourceVolume = thisSound->vol; + + if (play.speech_has_voice) { + // Negative value means set exactly; positive means drop that amount + if (play.speech_music_drop < 0) + sourceVolume = -play.speech_music_drop; + else + sourceVolume -= play.speech_music_drop; + + if (sourceVolume < 0) + sourceVolume = 0; + if (sourceVolume > 255) + sourceVolume = 255; + } + + // Adjust ambient volume so it maxes out at overall sound volume + int ambientvol = (sourceVolume * play.sound_volume) / 255; + + int wantvol; + + if ((thisSound->x == 0) && (thisSound->y == 0)) { + wantvol = ambientvol; + } + else { + wantvol = get_volume_adjusted_for_distance(ambientvol, thisSound->x, thisSound->y, thisSound->maxdist); + } + + auto *ch = lock.GetChannelIfPlaying(thisSound->channel); + if (ch) + ch->set_volume(wantvol); + } +} + +SOUNDCLIP *load_sound_and_play(ScriptAudioClip *aclip, bool repeat) +{ + SOUNDCLIP *soundfx = load_sound_clip(aclip, repeat); + if (!soundfx) { return nullptr; } + + if (soundfx->play() == 0) { + // not assigned to a channel, so clean up manually. + soundfx->destroy(); + delete soundfx; + return nullptr; + } + + return soundfx; +} + +void stop_all_sound_and_music() +{ + int a; + stopmusic(); + stop_voice_nonblocking(); + // make sure it doesn't start crossfading when it comes back + crossFading = 0; + // any ambient sound will be aborted + for (a = 0; a <= MAX_SOUND_CHANNELS; a++) + stop_and_destroy_channel(a); +} + +void shutdown_sound() +{ + stop_all_sound_and_music(); + +#ifndef PSP_NO_MOD_PLAYBACK + if (usetup.mod_player) + remove_mod_player(); +#endif + remove_sound(); +} + +// the sound will only be played if there is a free channel or +// it has a priority >= an existing sound to override +static int play_sound_priority (int val1, int priority) { + int lowest_pri = 9999, lowest_pri_id = -1; + + AudioChannelsLock lock; + + // find a free channel to play it on + for (int i = SCHAN_NORMAL; i < MAX_SOUND_CHANNELS; i++) { + auto* ch = lock.GetChannelIfPlaying(i); + if (val1 < 0) { + // Playing sound -1 means iterate through and stop all sound + if (ch) + stop_and_destroy_channel (i); + } + else if (ch == nullptr || !ch->is_playing()) { + // PlaySoundEx will destroy the previous channel value. + const int usechan = PlaySoundEx(val1, i); + if (usechan >= 0) + { // channel will hold a different clip here + assert(usechan == i); + auto *ch = lock.GetChannel(usechan); + if (ch) + ch->priority = priority; + } + return usechan; + } + else if (ch->priority < lowest_pri) { + lowest_pri = ch->priority; + lowest_pri_id = i; + } + + } + if (val1 < 0) + return -1; + + // no free channels, see if we have a high enough priority + // to override one + if (priority >= lowest_pri) { + const int usechan = PlaySoundEx(val1, lowest_pri_id); + if (usechan >= 0) { + assert(usechan == lowest_pri_id); + auto *ch = lock.GetChannel(usechan); + if (ch) + ch->priority = priority; + return usechan; + } + } + + return -1; +} + +int play_sound(int val1) { + return play_sound_priority(val1, 10); +} + + +//============================================================================= + + +// This is an indicator of a music played by an old audio system +// (to distinguish from the new system API) +int current_music_type = 0; +// crossFading is >0 (channel number of new track), or -1 (old +// track fading out, no new track) +int crossFading = 0, crossFadeVolumePerStep = 0, crossFadeStep = 0; +int crossFadeVolumeAtStart = 0; +SOUNDCLIP *cachedQueuedMusic = nullptr; + +//============================================================================= +// Music update is scheduled when the voice speech stops; +// we do a small delay before reverting any volume adjustments +static bool music_update_scheduled = false; +static auto music_update_at = AGS_Clock::now(); + +void cancel_scheduled_music_update() { + music_update_scheduled = false; +} + +void schedule_music_update_at(AGS_Clock::time_point at) { + music_update_scheduled = true; + music_update_at = at; +} + +void postpone_scheduled_music_update_by(std::chrono::milliseconds duration) { + if (!music_update_scheduled) { return; } + music_update_at += duration; +} + +void process_scheduled_music_update() { + if (!music_update_scheduled) { return; } + if (music_update_at > AGS_Clock::now()) { return; } + cancel_scheduled_music_update(); + update_music_volume(); + apply_volume_drop_modifier(false); + update_ambient_sound_vol(); +} +// end scheduled music update functions +//============================================================================= + +void clear_music_cache() { + + if (cachedQueuedMusic != nullptr) { + cachedQueuedMusic->destroy(); + delete cachedQueuedMusic; + cachedQueuedMusic = nullptr; + } + +} + +static void play_new_music(int mnum, SOUNDCLIP *music); + +void play_next_queued() { + // check if there's a queued one to play + if (play.music_queue_size > 0) { + + int tuneToPlay = play.music_queue[0]; + + if (tuneToPlay >= QUEUED_MUSIC_REPEAT) { + // Loop it! + play.music_repeat++; + play_new_music(tuneToPlay - QUEUED_MUSIC_REPEAT, cachedQueuedMusic); + play.music_repeat--; + } + else { + // Don't loop it! + int repeatWas = play.music_repeat; + play.music_repeat = 0; + play_new_music(tuneToPlay, cachedQueuedMusic); + play.music_repeat = repeatWas; + } + + // don't free the memory, as it has been transferred onto the + // main music channel + cachedQueuedMusic = nullptr; + + play.music_queue_size--; + for (int i = 0; i < play.music_queue_size; i++) + play.music_queue[i] = play.music_queue[i + 1]; + + if (play.music_queue_size > 0) + cachedQueuedMusic = load_music_from_disk(play.music_queue[0], 0); + } + +} + +int calculate_max_volume() { + // quieter so that sounds can be heard better + int newvol=play.music_master_volume + ((int)thisroom.Options.MusicVolume) * LegacyRoomVolumeFactor; + if (newvol>255) newvol=255; + if (newvol<0) newvol=0; + + if (play.fast_forward) + newvol = 0; + + return newvol; +} + +// add/remove the volume drop to the audio channels while speech is playing +void apply_volume_drop_modifier(bool applyModifier) +{ + AudioChannelsLock lock; + + for (int i = 0; i < MAX_SOUND_CHANNELS; i++) + { + auto* ch = lock.GetChannelIfPlaying(i); + if (ch && ch->sourceClip != nullptr) + { + if (applyModifier) + apply_volume_drop_to_clip(ch); + else + ch->apply_volume_modifier(0); // reset modifier + } + } +} + +// Checks if speech voice-over is currently playing, and reapply volume drop to all other active clips +void update_volume_drop_if_voiceover() +{ + apply_volume_drop_modifier(play.speech_has_voice); +} + +extern volatile char want_exit; + +void update_mp3_thread() +{ + if (switching_away_from_game) { return; } + + AudioChannelsLock lock; + + for(int i = 0; i <= MAX_SOUND_CHANNELS; ++i) + { + auto* ch = lock.GetChannel(i); + if (ch) + ch->poll(); + } +} + +//this is called at various points to give streaming logic a chance to update +//it seems those calls have been littered around and points where it ameliorated skipping +//a better solution would be to forcibly thread the streaming logic +void update_polled_mp3() +{ + if (psp_audio_multithreaded) { return; } + update_mp3_thread(); +} + +// Update the music, and advance the crossfade on a step +// (this should only be called once per game loop) +void update_audio_system_on_game_loop () +{ + update_polled_stuff_if_runtime (); + + AudioChannelsLock lock; + + process_scheduled_music_update(); + + _audio_doing_crossfade = true; + + audio_update_polled_stuff(); + + if (crossFading) { + crossFadeStep++; + update_music_volume(); + } + + // Check if the current music has finished playing + if ((play.cur_music_number >= 0) && (play.fast_forward == 0)) { + if (IsMusicPlaying() == 0) { + // The current music has finished + play.cur_music_number = -1; + play_next_queued(); + } + else if ((game.options[OPT_CROSSFADEMUSIC] > 0) && + (play.music_queue_size > 0) && (!crossFading)) { + // want to crossfade, and new tune in the queue + auto *ch = lock.GetChannel(SCHAN_MUSIC); + if (ch) { + int curpos = ch->get_pos_ms(); + int muslen = ch->get_length_ms(); + if ((curpos > 0) && (muslen > 0)) { + // we want to crossfade, and we know how far through + // the tune we are + int takesSteps = calculate_max_volume() / game.options[OPT_CROSSFADEMUSIC]; + int takesMs = ::lround(takesSteps * 1000.0f / get_current_fps()); + if (curpos >= muslen - takesMs) + play_next_queued(); + } + } + } + } + + _audio_doing_crossfade = false; + +} + +void stopmusic() +{ + AudioChannelsLock lock; + + if (crossFading > 0) { + // stop in the middle of a new track fading in + // Abort the new track, and let the old one finish fading out + stop_and_destroy_channel (crossFading); + crossFading = -1; + } + else if (crossFading < 0) { + // the music is already fading out + if (game.options[OPT_CROSSFADEMUSIC] <= 0) { + // If they have since disabled crossfading, stop the fadeout + stop_and_destroy_channel(SCHAN_MUSIC); + crossFading = 0; + crossFadeStep = 0; + update_music_volume(); + } + } + else if ((game.options[OPT_CROSSFADEMUSIC] > 0) + && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) + && (current_music_type != 0) + && (current_music_type != MUS_MIDI) + && (current_music_type != MUS_MOD)) { + + crossFading = -1; + crossFadeStep = 0; + crossFadeVolumePerStep = game.options[OPT_CROSSFADEMUSIC]; + crossFadeVolumeAtStart = calculate_max_volume(); + } + else + stop_and_destroy_channel (SCHAN_MUSIC); + + play.cur_music_number = -1; + current_music_type = 0; +} + +void update_music_volume() +{ + AudioChannelsLock lock; + + if ((current_music_type) || (crossFading < 0)) + { + // targetVol is the maximum volume we're fading in to + // newvol is the starting volume that we faded out from + int targetVol = calculate_max_volume(); + int newvol; + if (crossFading) + newvol = crossFadeVolumeAtStart; + else + newvol = targetVol; + + // fading out old track, target volume is silence + if (crossFading < 0) + targetVol = 0; + + if (crossFading) { + int curvol = crossFadeVolumePerStep * crossFadeStep; + + if ((curvol > targetVol) && (curvol > newvol)) { + // it has fully faded to the new track + newvol = targetVol; + stop_and_destroy_channel_ex(SCHAN_MUSIC, false); + if (crossFading > 0) { + lock.MoveChannel(SCHAN_MUSIC, crossFading); + } + crossFading = 0; + } + else { + if (crossFading > 0) + { + auto *ch = lock.GetChannel(crossFading); + if (ch) + ch->set_volume((curvol > targetVol) ? targetVol : curvol); + } + + newvol -= curvol; + if (newvol < 0) + newvol = 0; + } + } + auto *ch = lock.GetChannel(SCHAN_MUSIC); + if (ch) + ch->set_volume(newvol); + } +} + +// Ensures crossfader is stable after loading (or failing to load) +// new music +void post_new_music_check (int newchannel) +{ + AudioChannelsLock lock; + if ((crossFading > 0) && (lock.GetChannel(crossFading) == nullptr)) { + crossFading = 0; + // Was fading out but then they played invalid music, continue to fade out + if (lock.GetChannel(SCHAN_MUSIC) != nullptr) + crossFading = -1; + } + +} + +int prepare_for_new_music () +{ + AudioChannelsLock lock; + + int useChannel = SCHAN_MUSIC; + + if ((game.options[OPT_CROSSFADEMUSIC] > 0) + && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) + && (current_music_type != MUS_MIDI) + && (current_music_type != MUS_MOD)) { + + if (crossFading > 0) { + // It's still crossfading to the previous track + stop_and_destroy_channel_ex(SCHAN_MUSIC, false); + lock.MoveChannel(SCHAN_MUSIC, crossFading); + crossFading = 0; + update_music_volume(); + } + else if (crossFading < 0) { + // an old track is still fading out, no new music yet + // Do nothing, and keep the current crossfade step + } + else { + // start crossfading + crossFadeStep = 0; + crossFadeVolumePerStep = game.options[OPT_CROSSFADEMUSIC]; + crossFadeVolumeAtStart = calculate_max_volume(); + } + useChannel = SPECIAL_CROSSFADE_CHANNEL; + crossFading = useChannel; + } + else { + // crossfading is now turned off + stopmusic(); + // ensure that any traces of old tunes fading are eliminated + // (otherwise the new track will be faded out) + crossFading = 0; + } + + // Just make sure, because it will be overwritten in a sec + if (lock.GetChannel(useChannel) != nullptr) + stop_and_destroy_channel (useChannel); + + return useChannel; +} + +ScriptAudioClip *get_audio_clip_for_music(int mnum) +{ + if (mnum >= QUEUED_MUSIC_REPEAT) + mnum -= QUEUED_MUSIC_REPEAT; + return GetAudioClipForOldStyleNumber(game, true, mnum); +} + +SOUNDCLIP *load_music_from_disk(int mnum, bool doRepeat) { + + if (mnum >= QUEUED_MUSIC_REPEAT) { + mnum -= QUEUED_MUSIC_REPEAT; + doRepeat = true; + } + + SOUNDCLIP *loaded = load_sound_clip_from_old_style_number(true, mnum, doRepeat); + + if ((loaded == nullptr) && (mnum > 0)) + { + debug_script_warn("Music %d not found",mnum); + debug_script_log("FAILED to load music %d", mnum); + } + + return loaded; +} + +static void play_new_music(int mnum, SOUNDCLIP *music) +{ + if (debug_flags & DBG_NOMUSIC) + return; + + if ((play.cur_music_number == mnum) && (music == nullptr)) { + debug_script_log("PlayMusic %d but already playing", mnum); + return; // don't play the music if it's already playing + } + + ScriptAudioClip *aclip = get_audio_clip_for_music(mnum); + if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) + return; + + int useChannel = SCHAN_MUSIC; + debug_script_log("Playing music %d", mnum); + + if (mnum<0) { + stopmusic(); + return; + } + + if (play.fast_forward) { + // while skipping cutscene, don't change the music + play.end_cutscene_music = mnum; + return; + } + + useChannel = prepare_for_new_music(); + play.cur_music_number = mnum; + current_music_type = 0; + + play.current_music_repeating = play.music_repeat; + // now that all the previous music is unloaded, load in the new one + + SOUNDCLIP *new_clip; + if (music != nullptr) + new_clip = music; + else + new_clip = load_music_from_disk(mnum, (play.music_repeat > 0)); + + AudioChannelsLock lock; + auto* ch = lock.SetChannel(useChannel, new_clip); + if (ch != nullptr) { + if (!ch->play()) { + // previous behavior was to set channel[] to null on error, so continue to do that here. + ch->destroy(); + delete ch; + ch = nullptr; + lock.SetChannel(useChannel, nullptr); + } else + current_music_type = ch->get_sound_type(); + } + + post_new_music_check(useChannel); + update_music_volume(); +} + +void newmusic(int mnum) +{ + play_new_music(mnum, nullptr); +} diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h new file mode 100644 index 000000000000..05600c9d53d5 --- /dev/null +++ b/engines/ags/engine/media/audio/audio.h @@ -0,0 +1,153 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_AUDIO_H +#define __AC_AUDIO_H + +#include +#include "media/audio/audiodefines.h" +#include "ac/dynobj/scriptaudioclip.h" +#include "ac/dynobj/scriptaudiochannel.h" +#include "media/audio/ambientsound.h" +#include "util/mutex.h" +#include "util/mutex_lock.h" +#include "util/thread.h" +#include "ac/timer.h" + +struct SOUNDCLIP; + +//controls access to the channels, since that's the main point of synchronization between the streaming thread and the user code +//this is going to be dependent on the underlying mutexes being recursive +//yes, we will have more recursive traffic on mutexes than we need +//however this should mostly be happening only when playing sounds, and possibly when sounds numbering only several +//the load should not be high +class AudioChannelsLock : public AGS::Engine::MutexLock +{ +private: + AudioChannelsLock(AudioChannelsLock const &); // non-copyable + AudioChannelsLock& operator=(AudioChannelsLock const &); // not copy-assignable + +public: + static AGS::Engine::Mutex s_mutex; + AudioChannelsLock() + : MutexLock(s_mutex) + { + } + + // Gets a clip from the channel + SOUNDCLIP *GetChannel(int index); + // Gets a clip from the channel but only if it's in playback state + SOUNDCLIP *GetChannelIfPlaying(int index); + // Assign new clip to the channel + SOUNDCLIP *SetChannel(int index, SOUNDCLIP *clip); + // Move clip from one channel to another, clearing the first channel + SOUNDCLIP *MoveChannel(int to, int from); +}; + +// +// Channel helpers, autolock and perform a simple action on a channel. +// +// Tells if channel has got a clip; does not care about its state +bool channel_has_clip(int chanid); +// Tells if channel has got a clip and clip is in playback state +bool channel_is_playing(int chanid); +// Sets new clip to the channel +void set_clip_to_channel(int chanid, SOUNDCLIP *clip); + + +void calculate_reserved_channel_count(); +void update_clip_default_volume(ScriptAudioClip *audioClip); +void start_fading_in_new_track_if_applicable(int fadeInChannel, ScriptAudioClip *newSound); +void stop_or_fade_out_channel(int fadeOutChannel, int fadeInChannel = -1, ScriptAudioClip *newSound = nullptr); +SOUNDCLIP* load_sound_clip(ScriptAudioClip *audioClip, bool repeat); +ScriptAudioChannel* play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *cachedClip = nullptr); +void remove_clips_of_type_from_queue(int audioType); +void update_queued_clips_volume(int audioType, int new_vol); +// Checks if speech voice-over is currently playing, and reapply volume drop to all other active clips +void update_volume_drop_if_voiceover(); +ScriptAudioChannel* play_audio_clip(ScriptAudioClip *clip, int priority, int repeat, int fromOffset, bool queueIfNoChannel); +ScriptAudioChannel* play_audio_clip_by_index(int audioClipIndex); +void stop_and_destroy_channel_ex(int chid, bool resetLegacyMusicSettings); +void stop_and_destroy_channel (int chid); + +// ***** BACKWARDS COMPATIBILITY WITH OLD AUDIO SYSTEM ***** // +int get_old_style_number_for_sound(int sound_number); +SOUNDCLIP * load_sound_clip_from_old_style_number(bool isMusic, int indexNumber, bool repeat); + +//============================================================================= + +int init_mod_player(int numVoices); +void remove_mod_player(); +void force_audiostream_include(); +int get_volume_adjusted_for_distance(int volume, int sndX, int sndY, int sndMaxDist); +void update_directional_sound_vol(); +void update_ambient_sound_vol (); +// Tells if the audio type is allowed to play with regards to current sound config +bool is_audiotype_allowed_to_play(AudioFileType type); +// Loads sound data referenced by audio clip item, and starts playback; +// returns NULL on failure +SOUNDCLIP * load_sound_and_play(ScriptAudioClip *aclip, bool repeat); +void stop_all_sound_and_music(); +void shutdown_sound(); +int play_sound(int val1); + +//============================================================================= + +// This is an indicator of a music played by an old audio system +// (to distinguish from the new system API); if it is not set, then old API +// should "think" that no music is played regardless of channel state +// TODO: refactor this and hide behind some good interface to prevent misuse! +extern int current_music_type; + +void clear_music_cache(); +void play_next_queued(); +int calculate_max_volume(); +// add/remove the volume drop to the audio channels while speech is playing +void apply_volume_drop_modifier(bool applyModifier); +// Update the music, and advance the crossfade on a step +// (this should only be called once per game loop); +void update_audio_system_on_game_loop (); +void stopmusic(); +void update_music_volume(); +void post_new_music_check (int newchannel); +// Sets up the crossfading for playing the new music track, +// and returns the channel number to use; the channel is guaranteed to be free +int prepare_for_new_music (); +// Gets audio clip from legacy music number, which also may contain queue flag +ScriptAudioClip *get_audio_clip_for_music(int mnum); +SOUNDCLIP * load_music_from_disk(int mnum, bool doRepeat); +void newmusic(int mnum); + +extern AGS::Engine::Thread audioThread; +extern volatile bool _audio_doing_crossfade; +extern volatile int psp_audio_multithreaded; + +void update_polled_mp3(); +void update_mp3_thread(); + +extern void cancel_scheduled_music_update(); +extern void schedule_music_update_at(AGS_Clock::time_point); +extern void postpone_scheduled_music_update_by(std::chrono::milliseconds); + +// crossFading is >0 (channel number of new track), or -1 (old +// track fading out, no new track) +extern int crossFading, crossFadeVolumePerStep, crossFadeStep; +extern int crossFadeVolumeAtStart; + +extern SOUNDCLIP *cachedQueuedMusic; + +// TODO: double check that ambient sounds array actually needs +1 +extern std::array ambient; + +#endif // __AC_AUDIO_H diff --git a/engines/ags/engine/media/audio/audio_system.h b/engines/ags/engine/media/audio/audio_system.h new file mode 100644 index 000000000000..4cb910c65720 --- /dev/null +++ b/engines/ags/engine/media/audio/audio_system.h @@ -0,0 +1,16 @@ +#ifndef __AC_MEDIA_AUDIO_SYSTEM_H +#define __AC_MEDIA_AUDIO_SYSTEM_H + +#include "media/audio/audiodefines.h" +#include "media/audio/ambientsound.h" + +#include "media/audio/audio.h" + +#include "media/audio/soundcache.h" + +#include "media/audio/soundclip.h" +#include "media/audio/sound.h" + +#include "media/audio/queuedaudioitem.h" + +#endif \ No newline at end of file diff --git a/engines/ags/engine/media/audio/audiodefines.h b/engines/ags/engine/media/audio/audiodefines.h new file mode 100644 index 000000000000..13effae234bc --- /dev/null +++ b/engines/ags/engine/media/audio/audiodefines.h @@ -0,0 +1,39 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_AUDIODEFINES_H +#define __AC_AUDIODEFINES_H + +#define MUS_MIDI 1 +#define MUS_MP3 2 +#define MUS_WAVE 3 +#define MUS_MOD 4 +#define MUS_OGG 5 + +#ifndef PSP_NO_MOD_PLAYBACK +#define DUMB_MOD_PLAYER +#endif + +#define MAX_SOUND_CHANNELS 8 +#define SPECIAL_CROSSFADE_CHANNEL 8 + +#define SCHAN_SPEECH 0 +#define SCHAN_AMBIENT 1 +#define SCHAN_MUSIC 2 +#define SCHAN_NORMAL 3 +#define AUDIOTYPE_LEGACY_AMBIENT_SOUND 1 +#define AUDIOTYPE_LEGACY_MUSIC 2 +#define AUDIOTYPE_LEGACY_SOUND 3 + +#endif // __AC_AUDIODEFINES_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/audiointernaldefs.h b/engines/ags/engine/media/audio/audiointernaldefs.h new file mode 100644 index 000000000000..0d7c0174fb26 --- /dev/null +++ b/engines/ags/engine/media/audio/audiointernaldefs.h @@ -0,0 +1,21 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SOUNDINTERNALDEFS_H +#define __AC_SOUNDINTERNALDEFS_H + +//#define MP3CHUNKSIZE 100000 +#define MP3CHUNKSIZE 32768 + +#endif // __AC_SOUNDINTERNALDEFS_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp new file mode 100644 index 000000000000..8c040626588f --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mydumbmod.cpp @@ -0,0 +1,163 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/audiodefines.h" + +#ifdef DUMB_MOD_PLAYER + +#include "media/audio/clip_mydumbmod.h" +#include "media/audio/audiointernaldefs.h" + +void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop) { + DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(dp); + DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); + if (itsr == nullptr) + return; + + if (loop) + dumb_it_set_loop_callback(itsr, nullptr, nullptr); + else + dumb_it_set_loop_callback(itsr, dumb_it_callback_terminate, itsr); +} + +void MYMOD::poll() +{ + if (state_ != SoundClipPlaying) { return; } + + if (al_poll_duh(duhPlayer)) { + state_ = SoundClipStopped; + } +} + +void MYMOD::adjust_volume() +{ + if (!is_playing()) { return; } + al_duh_set_volume(duhPlayer, VOLUME_TO_DUMB_VOL(get_final_volume())); +} + +void MYMOD::set_volume(int newvol) +{ + vol = newvol; + adjust_volume(); +} + +void MYMOD::destroy() +{ + if (duhPlayer) { + al_stop_duh(duhPlayer); + } + duhPlayer = nullptr; + + if (tune) { + unload_duh(tune); + } + tune = nullptr; + + state_ = SoundClipStopped; +} + +void MYMOD::seek(int patnum) +{ + if (!is_playing()) { return; } + + al_stop_duh(duhPlayer); + state_ = SoundClipInitial; + + DUH_SIGRENDERER *sr = dumb_it_start_at_order(tune, 2, patnum); + duhPlayer = al_duh_encapsulate_sigrenderer(sr, VOLUME_TO_DUMB_VOL(vol), 8192, 22050); + if (!duhPlayer) { + duh_end_sigrenderer(sr); + return; + } + + al_duh_set_loop(duhPlayer, repeat); + state_ = SoundClipPlaying; +} + +int MYMOD::get_pos() +{ + if (!is_playing()) { return -1; } + + // determine the current track number (DUMB calls them 'orders') + DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(duhPlayer); + DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); + if (itsr == nullptr) + return -1; + + return dumb_it_sr_get_current_order(itsr); +} + +int MYMOD::get_real_mod_pos() +{ + if (!is_playing()) { return -1; } + return al_duh_get_position(duhPlayer); +} + +int MYMOD::get_pos_ms() +{ + if (!is_playing()) { return -1; } + return (get_real_mod_pos() * 10) / 655; +} + +int MYMOD::get_length_ms() +{ + if (tune == nullptr) + return 0; + + // duh_get_length represents time as 65536ths of a second + return (duh_get_length(tune) * 10) / 655; +} + +int MYMOD::get_voice() +{ + // MOD uses so many different voices it's not practical to keep track + return -1; +} + +void MYMOD::pause() { + if (state_ != SoundClipPlaying) { return; } + al_pause_duh(duhPlayer); + state_ = SoundClipPaused; +} + +void MYMOD::resume() { + if (state_ != SoundClipPaused) { return; } + al_resume_duh(duhPlayer); + state_ = SoundClipPlaying; +} + +int MYMOD::get_sound_type() { + return MUS_MOD; +} + +int MYMOD::play() { + if (tune == nullptr) { return 0; } + + duhPlayer = al_start_duh(tune, 2, 0, 1.0, 8192, 22050); + if (!duhPlayer) { + return 0; + } + al_duh_set_loop(duhPlayer, repeat); + set_volume(vol); + + state_ = SoundClipPlaying; + return 1; +} + +MYMOD::MYMOD() : SOUNDCLIP() { + tune = nullptr; + duhPlayer = nullptr; +} + +#endif // DUMB_MOD_PLAYER \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h new file mode 100644 index 000000000000..193c7f4567ca --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -0,0 +1,69 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYDUMBMOD_H +#define __AC_MYDUMBMOD_H + +#include "aldumb.h" +#include "media/audio/soundclip.h" + +#define VOLUME_TO_DUMB_VOL(vol) ((float)vol) / 256.0 + +void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop); + +// MOD/XM (DUMB) +struct MYMOD : public SOUNDCLIP +{ + DUH *tune; + AL_DUH_PLAYER *duhPlayer; + + void poll() override; + + void set_volume(int newvol) override; + + void destroy() override; + + void seek(int patnum) override; + + // NOTE: this implementation of the virtual function returns a MOD/XM + // "order" index, not actual playing position; + // this does not make much sense in the context of the interface itself, + // and, as it seems, was implemented so solely for the purpose of emulating + // deprecated "GetMODPattern" script function. + // (see Game_GetMODPattern(), and documentation for AudioChannel.Position property) + // TODO: find a way to redesign this behavior + int get_pos() override; + + int get_pos_ms() override; + + int get_length_ms() override; + + void pause() override; + + void resume() override; + + int get_sound_type() override; + + int play() override; + + MYMOD(); + +protected: + int get_voice() override; + void adjust_volume() override; + // Returns real MOD/XM playing position + int get_real_mod_pos(); +}; + +#endif // __AC_MYDUMBMOD_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_myjgmod.cpp b/engines/ags/engine/media/audio/clip_myjgmod.cpp new file mode 100644 index 000000000000..45209551e7d3 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_myjgmod.cpp @@ -0,0 +1,89 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/audiodefines.h" + +#ifdef JGMOD_MOD_PLAYER + +#include "media/audio/clip_myjgmod.h" +#include "media/audio/audiointernaldefs.h" + +int MYMOD::poll() +{ + if (done) + return done; + + if (is_mod_playing() == 0) + done = 1; + + return done; +} + +void MYMOD::set_volume(int newvol) +{ + vol = newvol; + if (!done) + set_mod_volume(newvol); +} + +void MYMOD::destroy() +{ + stop_mod(); + destroy_mod(tune); + tune = NULL; +} + +void MYMOD::seek(int patnum) +{ + if (is_mod_playing() != 0) + goto_mod_track(patnum); +} + +int MYMOD::get_pos() +{ + if (!is_mod_playing()) + return -1; + return mi.trk; +} + +int MYMOD::get_pos_ms() +{ + return 0; // we don't know ms offset +} + +int MYMOD::get_length_ms() +{ // we don't know ms + return 0; +} + +int MYMOD::get_voice() +{ + // MOD uses so many different voices it's not practical to keep track + return -1; +} + +int MYMOD::get_sound_type() { + return MUS_MOD; +} + +int MYMOD::play() { + play_mod(tune, repeat); + + return 1; +} + +MYMOD::MYMOD() : SOUNDCLIP() { +} + +#endif // #ifdef JGMOD_MOD_PLAYER \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_myjgmod.h b/engines/ags/engine/media/audio/clip_myjgmod.h new file mode 100644 index 000000000000..6870b67503cf --- /dev/null +++ b/engines/ags/engine/media/audio/clip_myjgmod.h @@ -0,0 +1,49 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYJGMOD_H +#define __AC_MYJGMOD_H + +#include "jgmod.h" +#include "media/audio/soundclip.h" + +// MOD/XM (JGMOD) +struct MYMOD:public SOUNDCLIP +{ + JGMOD *tune; + + int poll(); + + void set_volume(int newvol); + + void destroy(); + + void seek(int patnum); + + int get_pos(); + + int get_pos_ms(); + + int get_length_ms(); + + int get_voice(); + + int get_sound_type(); + + int play(); + + MYMOD(); +}; + +#endif // __AC_MYJGMOD_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp new file mode 100644 index 000000000000..1175bab306d1 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -0,0 +1,111 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/audiodefines.h" +#include "util/wgt2allg.h" +#include "media/audio/clip_mymidi.h" +#include "media/audio/audiointernaldefs.h" + +void MYMIDI::poll() +{ + if (state_ != SoundClipPlaying) { return; } + + if (midi_pos < 0) + state_ = SoundClipStopped; +} + +void MYMIDI::adjust_volume() +{ + if (!is_playing()) { return; } + ::set_volume(-1, get_final_volume()); +} + +void MYMIDI::set_volume(int newvol) +{ + vol = newvol; + adjust_volume(); +} + +void MYMIDI::destroy() +{ + stop_midi(); + + if (tune) { + destroy_midi(tune); + } + tune = nullptr; + + state_ = SoundClipStopped; +} + +void MYMIDI::seek(int pos) +{ + if (!is_playing()) { return; } + midi_seek(pos); +} + +int MYMIDI::get_pos() +{ + if (!is_playing()) { return -1; } + return midi_pos; +} + +int MYMIDI::get_pos_ms() +{ + return 0; // we don't know ms with midi +} + +int MYMIDI::get_length_ms() +{ + return lengthInSeconds * 1000; +} + +int MYMIDI::get_voice() +{ + // voice is N/A for midi + return -1; +} + +void MYMIDI::pause() { + if (state_ != SoundClipPlaying) { return; } + midi_pause(); + state_ = SoundClipPaused; +} + +void MYMIDI::resume() { + if (state_ != SoundClipPaused) { return; } + midi_resume(); + state_ = SoundClipPlaying; +} + +int MYMIDI::get_sound_type() { + return MUS_MIDI; +} + +int MYMIDI::play() { + if (tune == nullptr) { return 0; } + + lengthInSeconds = get_midi_length(tune); + if (::play_midi(tune, repeat)) { + return 0; + } + + state_ = SoundClipPlaying; + return 1; +} + +MYMIDI::MYMIDI() : SOUNDCLIP() { + tune = nullptr; + lengthInSeconds = 0; +} diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h new file mode 100644 index 000000000000..5799f5ab88e7 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -0,0 +1,55 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYMIDI_H +#define __AC_MYMIDI_H + +#include "media/audio/soundclip.h" + +// MIDI +struct MYMIDI:public SOUNDCLIP +{ + MIDI *tune; + int lengthInSeconds; + + void poll() override; + + void set_volume(int newvol) override; + + void destroy() override; + + void seek(int pos) override; + + int get_pos() override; + + int get_pos_ms() override; + + int get_length_ms() override; + + void pause() override; + + void resume() override; + + int get_sound_type() override; + + int play() override; + + MYMIDI(); + +protected: + int get_voice() override; + void adjust_volume() override; +}; + +#endif // __AC_MYMIDI_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp new file mode 100644 index 000000000000..b4c98d849ea2 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -0,0 +1,173 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/audiodefines.h" + +#ifndef NO_MP3_PLAYER + +#include "media/audio/clip_mymp3.h" +#include "media/audio/audiointernaldefs.h" +#include "ac/common.h" // quit() +#include "ac/asset_helper.h" +#include "util/mutex_lock.h" + +#include "platform/base/agsplatformdriver.h" + + +void MYMP3::poll() +{ + if (state_ != SoundClipPlaying) { return; } + + // update the buffer + char *tempbuf = nullptr; + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + tempbuf = (char *)almp3_get_mp3stream_buffer(stream); + } + + if (tempbuf != nullptr) { + AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)in->userdata; + int free_val = -1; + if (chunksize >= obj->remains) { + chunksize = obj->remains; + free_val = chunksize; + } + pack_fread(tempbuf, chunksize, in); + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_free_mp3stream_buffer(stream, free_val); + } + } + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + if (almp3_poll_mp3stream(stream) == ALMP3_POLL_PLAYJUSTFINISHED) { + state_ = SoundClipStopped; + } + } +} + +void MYMP3::adjust_stream() +{ + if (!is_playing()) { return; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_adjust_mp3stream(stream, get_final_volume(), panning, speed); +} + +void MYMP3::adjust_volume() +{ + adjust_stream(); +} + +void MYMP3::set_volume(int newvol) +{ + // boost MP3 volume + newvol += 20; + if (newvol > 255) + newvol = 255; + + vol = newvol; + adjust_stream(); +} + +void MYMP3::set_speed(int new_speed) +{ + speed = new_speed; + adjust_stream(); +} + +void MYMP3::destroy() +{ + if (stream) { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_stop_mp3stream(stream); + almp3_destroy_mp3stream(stream); + } + stream = nullptr; + + if (buffer) + free(buffer); + buffer = nullptr; + + pack_fclose(in); + + state_ = SoundClipStopped; +} + +void MYMP3::seek(int pos) +{ + if (!is_playing()) { return; } + quit("Tried to seek an mp3stream"); +} + +int MYMP3::get_pos() +{ + return 0; // Return 0 to signify that Seek is not supported + // return almp3_get_pos_msecs_mp3stream (stream); +} + +int MYMP3::get_pos_ms() +{ + if (!is_playing()) { return -1; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + return almp3_get_pos_msecs_mp3stream(stream); +} + +int MYMP3::get_length_ms() +{ + if (!is_playing()) { return -1; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + return almp3_get_length_msecs_mp3stream(stream, filesize); +} + +int MYMP3::get_voice() +{ + if (!is_playing()) { return -1; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AUDIOSTREAM *ast = almp3_get_audiostream_mp3stream(stream); + return (ast != nullptr ? ast->voice : -1); +} + +int MYMP3::get_sound_type() { + return MUS_MP3; +} + +int MYMP3::play() { + if (in == nullptr) { return 0; } + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + if (almp3_play_mp3stream(stream, chunksize, (vol > 230) ? vol : vol + 20, panning) != ALMP3_OK) { + return 0; + } + } + + state_ = SoundClipPlaying; + + if (!psp_audio_multithreaded) + poll(); + + return 1; +} + +MYMP3::MYMP3() : SOUNDCLIP() { + stream = nullptr; + in = nullptr; + filesize = 0; + buffer = nullptr; + chunksize = 0; +} + +#endif // !NO_MP3_PLAYER \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h new file mode 100644 index 000000000000..58448149d7c4 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -0,0 +1,50 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYMP3_H +#define __AC_MYMP3_H + +#include "almp3.h" +#include "media/audio/soundclip.h" + +extern AGS::Engine::Mutex _mp3_mutex; + +struct MYMP3:public SOUNDCLIP +{ + ALMP3_MP3STREAM *stream; + PACKFILE *in; + size_t filesize; + char *buffer; + int chunksize; + + void poll() override; + void set_volume(int newvol) override; + void set_speed(int new_speed) override; + void destroy() override; + void seek(int pos) override; + int get_pos() override; + int get_pos_ms() override; + int get_length_ms() override; + int get_sound_type() override; + int play() override; + MYMP3(); + +protected: + int get_voice() override; + void adjust_volume() override; +private: + void adjust_stream(); +}; + +#endif // __AC_MYMP3_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp new file mode 100644 index 000000000000..da16c94162af --- /dev/null +++ b/engines/ags/engine/media/audio/clip_myogg.cpp @@ -0,0 +1,203 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/audiodefines.h" +#include "media/audio/clip_myogg.h" +#include "media/audio/audiointernaldefs.h" +#include "ac/common.h" // quit() +#include "ac/asset_helper.h" +#include "util/mutex_lock.h" + +#include "platform/base/agsplatformdriver.h" + +extern "C" { + extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); + extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); + extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); + extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); +} + +void MYOGG::poll() +{ + if (state_ != SoundClipPlaying) { return; } + + AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)in->userdata; + if (obj->remains > 0) + { + // update the buffer + char *tempbuf = (char *)alogg_get_oggstream_buffer(stream); + if (tempbuf != nullptr) + { + int free_val = -1; + if (chunksize >= obj->remains) + { + chunksize = obj->remains; + free_val = chunksize; + } + pack_fread(tempbuf, chunksize, in); + alogg_free_oggstream_buffer(stream, free_val); + } + } + + int ret = alogg_poll_oggstream(stream); + if (ret == ALOGG_OK || ret == ALOGG_POLL_BUFFERUNDERRUN) + get_pos_ms(); // call this to keep the last_but_one stuff up to date + else { + // finished playing or error + state_ = SoundClipStopped; + } +} + +void MYOGG::adjust_stream() +{ + if (!is_playing()) { return; } + alogg_adjust_oggstream(stream, get_final_volume(), panning, speed); +} + +void MYOGG::adjust_volume() +{ + adjust_stream(); +} + +void MYOGG::set_volume(int newvol) +{ + // boost MP3 volume + newvol += 20; + if (newvol > 255) + newvol = 255; + vol = newvol; + adjust_stream(); +} + +void MYOGG::set_speed(int new_speed) +{ + speed = new_speed; + adjust_stream(); +} + +void MYOGG::destroy() +{ + if (stream) { + alogg_stop_oggstream(stream); + alogg_destroy_oggstream(stream); + } + stream = nullptr; + + if (buffer) + free(buffer); + buffer = nullptr; + + pack_fclose(in); + + state_ = SoundClipStopped; +} + +void MYOGG::seek(int pos) +{ + if (!is_playing()) { return; } + quit("Attempted to seek an oggstream; operation not permitted"); +} + +int MYOGG::get_pos() +{ + return 0; +} + +int MYOGG::get_pos_ms() +{ + // Unfortunately the alogg_get_pos_msecs_oggstream function + // returns the ms offset that was last decoded, so it's always + // ahead of the actual playback. Therefore we have this + // hideous hack below to sort it out. + if ((!is_playing()) || (!alogg_is_playing_oggstream(stream))) + return 0; + + AUDIOSTREAM *str = alogg_get_audiostream_oggstream(stream); + long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; + + if (last_ms_offs != alogg_get_pos_msecs_oggstream(stream)) { + last_but_one_but_one = last_but_one; + last_but_one = last_ms_offs; + last_ms_offs = alogg_get_pos_msecs_oggstream(stream); + } + + // just about to switch buffers + if (offs < 0) + return last_but_one; + + int end_of_stream = alogg_is_end_of_oggstream(stream); + + if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { + switch (end_of_stream) { +case 0: +case 2: + offs -= (last_but_one - last_but_one_but_one); + break; +case 1: + offs -= (last_but_one - last_but_one_but_one); + break; + } + } + + if (end_of_stream == 1) { + + return offs + last_but_one; + } + + return offs + last_but_one_but_one; +} + +int MYOGG::get_length_ms() +{ // streamed OGG is variable bitrate so we don't know + return 0; +} + +int MYOGG::get_voice() +{ + if (!is_playing()) { return -1; } + + AUDIOSTREAM *ast = alogg_get_audiostream_oggstream(stream); + if (ast) + return ast->voice; + return -1; +} + +int MYOGG::get_sound_type() { + return MUS_OGG; +} + +int MYOGG::play() { + if (in == nullptr) { return 0; } + + if (alogg_play_oggstream(stream, MP3CHUNKSIZE, (vol > 230) ? vol : vol + 20, panning) != ALOGG_OK) { + return 0; + } + + state_ = SoundClipPlaying; + + if (!psp_audio_multithreaded) + poll(); + + return 1; +} + +MYOGG::MYOGG() : SOUNDCLIP() { + stream = nullptr; + in = nullptr; + buffer = nullptr; + chunksize = 0; + last_but_one_but_one = 0; + last_but_one = 0; + last_ms_offs = 0; +} diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h new file mode 100644 index 000000000000..093920476afb --- /dev/null +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -0,0 +1,60 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYOGG_H +#define __AC_MYOGG_H + +#include "alogg.h" +#include "media/audio/soundclip.h" + +struct MYOGG:public SOUNDCLIP +{ + ALOGG_OGGSTREAM *stream; + PACKFILE *in; + char *buffer; + int chunksize; + + int last_but_one_but_one; + int last_but_one; + int last_ms_offs; + + void poll() override; + + void set_volume(int newvol) override; + void set_speed(int new_speed) override; + + void destroy() override; + + void seek(int pos) override; + + int get_pos() override; + + int get_pos_ms() override; + + int get_length_ms() override; + + int get_sound_type() override; + + int play() override; + + MYOGG(); + +protected: + int get_voice() override; + void adjust_volume() override; +private: + void adjust_stream(); +}; + +#endif // __AC_MYOGG_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp new file mode 100644 index 000000000000..1c0c0c46bcca --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -0,0 +1,156 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/audiodefines.h" + +#ifndef NO_MP3_PLAYER + +#include "media/audio/clip_mystaticmp3.h" +#include "media/audio/audiointernaldefs.h" +#include "media/audio/soundcache.h" +#include "util/mutex_lock.h" + +#include "platform/base/agsplatformdriver.h" + +extern int our_eip; + +// ALMP3 functions are not reentrant! This mutex should be locked before calling any +// of the mp3 functions and unlocked afterwards. +AGS::Engine::Mutex _mp3_mutex; + +void MYSTATICMP3::poll() +{ + if (state_ != SoundClipPlaying) { return; } + + int oldeip = our_eip; + our_eip = 5997; + + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + int result = almp3_poll_mp3(tune); + + if (result == ALMP3_POLL_PLAYJUSTFINISHED) + { + if (!repeat) + { + state_ = SoundClipStopped; + } + } + our_eip = oldeip; +} + +void MYSTATICMP3::adjust_stream() +{ + if (!is_playing()) { return; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_adjust_mp3(tune, get_final_volume(), panning, speed, repeat); +} + +void MYSTATICMP3::adjust_volume() +{ + adjust_stream(); +} + +void MYSTATICMP3::set_volume(int newvol) +{ + vol = newvol; + adjust_stream(); +} + +void MYSTATICMP3::set_speed(int new_speed) +{ + speed = new_speed; + adjust_stream(); +} + +void MYSTATICMP3::destroy() +{ + if (tune) { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_stop_mp3(tune); + almp3_destroy_mp3(tune); + } + tune = nullptr; + + if (mp3buffer) { + sound_cache_free(mp3buffer, false); + } + mp3buffer = nullptr; + + state_ = SoundClipStopped; +} + +void MYSTATICMP3::seek(int pos) +{ + if (!is_playing()) { return; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_seek_abs_msecs_mp3(tune, pos); +} + +int MYSTATICMP3::get_pos() +{ + if (!is_playing()) { return -1; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + return almp3_get_pos_msecs_mp3(tune); +} + +int MYSTATICMP3::get_pos_ms() +{ + int result = get_pos(); + return result; +} + +int MYSTATICMP3::get_length_ms() +{ + if (tune == nullptr) { return -1; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + return almp3_get_length_msecs_mp3(tune); +} + +int MYSTATICMP3::get_voice() +{ + if (!is_playing()) { return -1; } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AUDIOSTREAM *ast = almp3_get_audiostream_mp3(tune); + return (ast != nullptr ? ast->voice : -1); +} + +int MYSTATICMP3::get_sound_type() { + return MUS_MP3; +} + +int MYSTATICMP3::play() { + if (tune == nullptr) { return 0; } + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + int result = almp3_play_ex_mp3(tune, 16384, vol, panning, 1000, repeat); + if (result != ALMP3_OK) { + return 0; + } + } + + state_ = SoundClipPlaying; + + if (!psp_audio_multithreaded) + poll(); + + return 1; +} + +MYSTATICMP3::MYSTATICMP3() : SOUNDCLIP() { + tune = nullptr; + mp3buffer = nullptr; +} + +#endif // !NO_MP3_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h new file mode 100644 index 000000000000..20f79e4711d2 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -0,0 +1,57 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYSTATICMP3_H +#define __AC_MYSTATICMP3_H + +#include "almp3.h" +#include "media/audio/soundclip.h" + +extern AGS::Engine::Mutex _mp3_mutex; + +// pre-loaded (non-streaming) MP3 file +struct MYSTATICMP3:public SOUNDCLIP +{ + ALMP3_MP3 *tune; + char *mp3buffer; + + void poll() override; + + void set_volume(int newvol) override; + void set_speed(int new_speed) override; + + void destroy() override; + + void seek(int pos) override; + + int get_pos() override; + + int get_pos_ms() override; + + int get_length_ms() override; + + int get_sound_type() override; + + int play() override; + + MYSTATICMP3(); + +protected: + int get_voice() override; + void adjust_volume() override; +private: + void adjust_stream(); +}; + +#endif // __AC_MYSTATICMP3_H diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp new file mode 100644 index 000000000000..5a744e499fdd --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mystaticogg.cpp @@ -0,0 +1,205 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/audiodefines.h" +#include "media/audio/clip_mystaticogg.h" +#include "media/audio/audiointernaldefs.h" +#include "media/audio/soundcache.h" +#include "util/mutex_lock.h" + +#include "platform/base/agsplatformdriver.h" + +extern "C" { + extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); + extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); + extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); + extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); +} + +extern int use_extra_sound_offset; // defined in ac.cpp + +void MYSTATICOGG::poll() +{ + if (state_ != SoundClipPlaying) { return; } + + if (alogg_poll_ogg(tune) == ALOGG_POLL_PLAYJUSTFINISHED) { + if (!repeat) + { + state_ = SoundClipStopped; + } + } + else get_pos(); // call this to keep the last_but_one stuff up to date +} + +void MYSTATICOGG::adjust_stream() +{ + if (!is_playing()) { return; } + alogg_adjust_ogg(tune, get_final_volume(), panning, speed, repeat); +} + +void MYSTATICOGG::adjust_volume() +{ + adjust_stream(); +} + +void MYSTATICOGG::set_volume(int newvol) +{ + vol = newvol; + adjust_stream(); +} + +void MYSTATICOGG::set_speed(int new_speed) +{ + speed = new_speed; + adjust_stream(); +} + +void MYSTATICOGG::destroy() +{ + if (tune) { + alogg_stop_ogg(tune); + alogg_destroy_ogg(tune); + } + tune = nullptr; + + if (mp3buffer) { + sound_cache_free(mp3buffer, false); + } + mp3buffer = nullptr; + + state_ = SoundClipStopped; +} + +void MYSTATICOGG::seek(int pos) +{ + if (!is_playing()) { return; } + + // we stop and restart it because otherwise the buffer finishes + // playing first and the seek isn't quite accurate + alogg_stop_ogg(tune); + state_ = SoundClipInitial; + play_from(pos); +} + +int MYSTATICOGG::get_pos() +{ + if (!is_playing()) { return -1; } + return get_pos_ms(); +} + +int MYSTATICOGG::get_pos_ms() +{ + if (!is_playing()) { return -1; } + + // Unfortunately the alogg_get_pos_msecs function + // returns the ms offset that was last decoded, so it's always + // ahead of the actual playback. Therefore we have this + // hideous hack below to sort it out. + if (!alogg_is_playing_ogg(tune)) + return 0; + + AUDIOSTREAM *str = alogg_get_audiostream_ogg(tune); + long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; + + if (last_ms_offs != alogg_get_pos_msecs_ogg(tune)) { + last_but_one_but_one = last_but_one; + last_but_one = last_ms_offs; + last_ms_offs = alogg_get_pos_msecs_ogg(tune); + } + + // just about to switch buffers + if (offs < 0) + return last_but_one; + + int end_of_stream = alogg_is_end_of_ogg(tune); + + if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { + switch (end_of_stream) { +case 0: +case 2: + offs -= (last_but_one - last_but_one_but_one); + break; +case 1: + offs -= (last_but_one - last_but_one_but_one); + break; + } + } + + if (end_of_stream == 1) { + return offs + last_but_one + extraOffset; + } + + return offs + last_but_one_but_one + extraOffset; +} + +int MYSTATICOGG::get_length_ms() +{ + if (tune == nullptr) { return -1; } + return alogg_get_length_msecs_ogg(tune); +} + +int MYSTATICOGG::get_voice() +{ + if (!is_playing()) { return -1; } + AUDIOSTREAM *ast = alogg_get_audiostream_ogg(tune); + if (ast) + return ast->voice; + return -1; +} + +int MYSTATICOGG::get_sound_type() { + return MUS_OGG; +} + +int MYSTATICOGG::play_from(int position) +{ + if (tune == nullptr) { return 0; } + + if (use_extra_sound_offset) + extraOffset = ((16384 / (alogg_get_wave_is_stereo_ogg(tune) ? 2 : 1)) * 1000) / alogg_get_wave_freq_ogg(tune); + else + extraOffset = 0; + + if (alogg_play_ex_ogg(tune, 16384, vol, panning, 1000, repeat) != ALOGG_OK) { + return 0; + } + + last_ms_offs = position; + last_but_one = position; + last_but_one_but_one = position; + + if (position > 0) + alogg_seek_abs_msecs_ogg(tune, position); + + state_ = SoundClipPlaying; + + if (!psp_audio_multithreaded) + poll(); + + return 1; +} + +int MYSTATICOGG::play() { + return play_from(0); +} + +MYSTATICOGG::MYSTATICOGG() : SOUNDCLIP() { + tune = nullptr; + mp3buffer = nullptr; + mp3buffersize = 0; + extraOffset = 0; + last_but_one = 0; + last_ms_offs = 0; + last_but_one_but_one = 0; +} diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h new file mode 100644 index 000000000000..a57250857ddc --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -0,0 +1,63 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYSTATICOGG_H +#define __AC_MYSTATICOGG_H + +#include "alogg.h" +#include "media/audio/soundclip.h" + +// pre-loaded (non-streaming) OGG file +struct MYSTATICOGG:public SOUNDCLIP +{ + ALOGG_OGG *tune; + char *mp3buffer; + int mp3buffersize; + int extraOffset; + + int last_but_one_but_one; + int last_but_one; + int last_ms_offs; + + void poll() override; + + void set_volume(int newvol) override; + void set_speed(int new_speed) override; + + void destroy() override; + + void seek(int pos) override; + + int get_pos() override; + + int get_pos_ms() override; + + int get_length_ms() override; + + int get_sound_type() override; + + int play_from(int position) override; + + int play() override; + + MYSTATICOGG(); + +protected: + int get_voice() override; + void adjust_volume() override; +private: + void adjust_stream(); +}; + +#endif // __AC_MYSTATICOGG_H diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp new file mode 100644 index 000000000000..4ab79f061364 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mywave.cpp @@ -0,0 +1,116 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/wgt2allg.h" +#include "media/audio/audiodefines.h" +#include "media/audio/clip_mywave.h" +#include "media/audio/audiointernaldefs.h" +#include "media/audio/soundcache.h" +#include "util/mutex_lock.h" + +#include "platform/base/agsplatformdriver.h" + +void MYWAVE::poll() +{ + if (state_ != SoundClipPlaying) { return; } + + if (voice_get_position(voice) < 0) + { + state_ = SoundClipStopped; + } +} + +void MYWAVE::adjust_volume() +{ + if (!is_playing()) { return; } + if (voice < 0) { return; } + voice_set_volume(voice, get_final_volume()); +} + +void MYWAVE::set_volume(int newvol) +{ + vol = newvol; + adjust_volume(); +} + +void MYWAVE::destroy() +{ + // Stop sound and decrease reference count. + if (wave) { + stop_sample(wave); + sound_cache_free((char*)wave, true); + } + wave = nullptr; + + state_ = SoundClipStopped; +} + +void MYWAVE::seek(int pos) +{ + if (!is_playing()) { return; } + voice_set_position(voice, pos); +} + +int MYWAVE::get_pos() +{ + if (!is_playing()) { return -1; } + return voice_get_position(voice); +} + +int MYWAVE::get_pos_ms() +{ + // convert the offset in samples into the offset in ms + //return ((1000000 / voice_get_frequency(voice)) * voice_get_position(voice)) / 1000; + + if (voice_get_frequency(voice) < 100) + return 0; + // (number of samples / (samples per second / 100)) * 10 = ms + return (voice_get_position(voice) / (voice_get_frequency(voice) / 100)) * 10; +} + +int MYWAVE::get_length_ms() +{ + if (wave == nullptr) { return -1; } + if (wave->freq < 100) + return 0; + return (wave->len / (wave->freq / 100)) * 10; +} + +int MYWAVE::get_voice() +{ + if (!is_playing()) { return -1; } + return voice; +} + +int MYWAVE::get_sound_type() { + return MUS_WAVE; +} + +int MYWAVE::play() { + if (wave == nullptr) { return 0; } + + voice = play_sample(wave, vol, panning, 1000, repeat); + if (voice < 0) { + return 0; + } + + state_ = SoundClipPlaying; + + return 1; +} + +MYWAVE::MYWAVE() : SOUNDCLIP() { + wave = nullptr; + voice = -1; +} diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h new file mode 100644 index 000000000000..b78c5ed29b69 --- /dev/null +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -0,0 +1,50 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MYWAVE_H +#define __AC_MYWAVE_H + +#include "media/audio/soundclip.h" + +// My new MP3STREAM wrapper +struct MYWAVE:public SOUNDCLIP +{ + SAMPLE *wave; + int voice; + + void poll() override; + + void set_volume(int new_speed) override; + + void destroy() override; + + void seek(int pos) override; + + int get_pos() override; + int get_pos_ms() override; + + int get_length_ms() override; + + int get_sound_type() override; + + int play() override; + + MYWAVE(); + +protected: + int get_voice() override; + void adjust_volume() override; +}; + +#endif // __AC_MYWAVE_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/queuedaudioitem.cpp b/engines/ags/engine/media/audio/queuedaudioitem.cpp new file mode 100644 index 000000000000..0656a1025524 --- /dev/null +++ b/engines/ags/engine/media/audio/queuedaudioitem.cpp @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/audio/queuedaudioitem.h" +#include "ac/common_defines.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +// [IKM] 2012-07-02: these functions are used during load/save game, +// and read/written as-is, hence cachedClip pointer should be serialized +// simply like pointer (although that probably does not mean much sense?) +void QueuedAudioItem::ReadFromFile(Stream *in) +{ + audioClipIndex = in->ReadInt16(); + priority = in->ReadInt16(); + repeat = in->ReadBool(); + in->ReadInt32(); // cachedClip +} + +void QueuedAudioItem::WriteToFile(Stream *out) const +{ + out->WriteInt16(audioClipIndex); + out->WriteInt16(priority); + out->WriteBool(repeat); + out->WriteInt32(0); // cachedClip +} diff --git a/engines/ags/engine/media/audio/queuedaudioitem.h b/engines/ags/engine/media/audio/queuedaudioitem.h new file mode 100644 index 000000000000..0e7313e61600 --- /dev/null +++ b/engines/ags/engine/media/audio/queuedaudioitem.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_QUEUEDAUDIOITEM_H +#define __AC_QUEUEDAUDIOITEM_H + +struct SOUNDCLIP; + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +struct QueuedAudioItem { + short audioClipIndex; + short priority; + bool repeat; + SOUNDCLIP *cachedClip; + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out) const; +}; + +#endif // __AC_QUEUEDAUDIOITEM_H \ No newline at end of file diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp new file mode 100644 index 000000000000..4bc3348a3973 --- /dev/null +++ b/engines/ags/engine/media/audio/sound.cpp @@ -0,0 +1,356 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// ACSOUND - AGS sound system wrapper +// +//============================================================================= + +#include // for toupper + +#include "core/platform.h" +#include "util/wgt2allg.h" +#include "ac/file.h" +#include "media/audio/audiodefines.h" +#include "media/audio/sound.h" +#include "media/audio/audiointernaldefs.h" +#include "media/audio/clip_mywave.h" +#ifndef NO_MP3_PLAYER +#include "media/audio/clip_mymp3.h" +#include "media/audio/clip_mystaticmp3.h" +#endif +#include "media/audio/clip_myogg.h" +#include "media/audio/clip_mystaticogg.h" +#include "media/audio/clip_mymidi.h" +#ifdef JGMOD_MOD_PLAYER +#include "media/audio/clip_myjgmod.h" +#endif +#ifdef DUMB_MOD_PLAYER +#include "media/audio/clip_mydumbmod.h" +#endif +#include "media/audio/soundcache.h" +#include "util/mutex_lock.h" + +#if defined JGMOD_MOD_PLAYER && defined DUMB_MOD_PLAYER +#error JGMOD_MOD_PLAYER and DUMB_MOD_PLAYER macros cannot be defined at the same time. +#endif + +#if !defined PSP_NO_MOD_PLAYBACK && !defined JGMOD_MOD_PLAYER && !defined DUMB_MOD_PLAYER +#error Either JGMOD_MOD_PLAYER or DUMB_MOD_PLAYER should be defined. +#endif + +extern "C" +{ +// Load MIDI from PACKFILE stream +MIDI *load_midi_pf(PACKFILE *pf); +} + + +int use_extra_sound_offset = 0; + + + +MYWAVE *thiswave; +SOUNDCLIP *my_load_wave(const AssetPath &asset_name, int voll, int loop) +{ + // Load via soundcache. + size_t dummy; + SAMPLE *new_sample = (SAMPLE*)get_cached_sound(asset_name, true, dummy); + + if (new_sample == nullptr) + return nullptr; + + thiswave = new MYWAVE(); + thiswave->wave = new_sample; + thiswave->vol = voll; + thiswave->repeat = (loop != 0); + + return thiswave; +} + +PACKFILE *mp3in; + +#ifndef NO_MP3_PLAYER + +MYMP3 *thistune; +SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) +{ + size_t asset_size; + mp3in = PackfileFromAsset(asset_name, asset_size); + if (mp3in == nullptr) + return nullptr; + + char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); + if (tmpbuffer == nullptr) { + pack_fclose(mp3in); + return nullptr; + } + thistune = new MYMP3(); + thistune->in = mp3in; + thistune->chunksize = MP3CHUNKSIZE; + thistune->filesize = asset_size; + thistune->vol = voll; + + if (thistune->chunksize > thistune->filesize) + thistune->chunksize = thistune->filesize; + + pack_fread(tmpbuffer, thistune->chunksize, mp3in); + + thistune->buffer = (char *)tmpbuffer; + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + thistune->stream = almp3_create_mp3stream(tmpbuffer, thistune->chunksize, (thistune->filesize < 1)); + } + + if (thistune->stream == nullptr) { + free(tmpbuffer); + pack_fclose(mp3in); + delete thistune; + return nullptr; + } + + return thistune; +} + + + +MYSTATICMP3 *thismp3; +SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) +{ + // Load via soundcache. + size_t muslen = 0; + char* mp3buffer = get_cached_sound(asset_name, false, muslen); + if (mp3buffer == nullptr) + return nullptr; + + // now, create an MP3 structure for it + thismp3 = new MYSTATICMP3(); + if (thismp3 == nullptr) { + free(mp3buffer); + return nullptr; + } + thismp3->vol = voll; + thismp3->mp3buffer = nullptr; + thismp3->repeat = loop; + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + thismp3->tune = almp3_create_mp3(mp3buffer, muslen); + } + + if (thismp3->tune == nullptr) { + free(mp3buffer); + delete thismp3; + return nullptr; + } + + thismp3->mp3buffer = mp3buffer; + + return thismp3; +} + +#else // NO_MP3_PLAYER + +SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) +{ + return NULL; +} + +SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) +{ + return NULL; +} + +#endif // NO_MP3_PLAYER + + + +MYSTATICOGG *thissogg; +SOUNDCLIP *my_load_static_ogg(const AssetPath &asset_name, int voll, bool loop) +{ + // Load via soundcache. + size_t muslen = 0; + char* mp3buffer = get_cached_sound(asset_name, false, muslen); + if (mp3buffer == nullptr) + return nullptr; + + // now, create an OGG structure for it + thissogg = new MYSTATICOGG(); + thissogg->vol = voll; + thissogg->repeat = loop; + thissogg->mp3buffer = mp3buffer; + thissogg->mp3buffersize = muslen; + + thissogg->tune = alogg_create_ogg_from_buffer(mp3buffer, muslen); + + if (thissogg->tune == nullptr) { + thissogg->destroy(); + delete thissogg; + return nullptr; + } + + return thissogg; +} + +MYOGG *thisogg; +SOUNDCLIP *my_load_ogg(const AssetPath &asset_name, int voll) +{ + size_t asset_size; + mp3in = PackfileFromAsset(asset_name, asset_size); + if (mp3in == nullptr) + return nullptr; + + char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); + if (tmpbuffer == nullptr) { + pack_fclose(mp3in); + return nullptr; + } + + thisogg = new MYOGG(); + thisogg->in = mp3in; + thisogg->vol = voll; + thisogg->chunksize = MP3CHUNKSIZE; + thisogg->last_but_one = 0; + thisogg->last_ms_offs = 0; + thisogg->last_but_one_but_one = 0; + + if (thisogg->chunksize > asset_size) + thisogg->chunksize = asset_size; + + pack_fread(tmpbuffer, thisogg->chunksize, mp3in); + + thisogg->buffer = (char *)tmpbuffer; + thisogg->stream = alogg_create_oggstream(tmpbuffer, thisogg->chunksize, (asset_size < 1)); + + if (thisogg->stream == nullptr) { + free(tmpbuffer); + pack_fclose(mp3in); + delete thisogg; + return nullptr; + } + + return thisogg; +} + + + +MYMIDI *thismidi; +SOUNDCLIP *my_load_midi(const AssetPath &asset_name, int repet) +{ + // The first a midi is played, preload all patches. + if (!thismidi && psp_midi_preload_patches) + load_midi_patches(); + + size_t asset_size; + PACKFILE *pf = PackfileFromAsset(asset_name, asset_size); + if (!pf) + return nullptr; + + MIDI* midiPtr = load_midi_pf(pf); + pack_fclose(pf); + + if (midiPtr == nullptr) + return nullptr; + + thismidi = new MYMIDI(); + thismidi->tune = midiPtr; + thismidi->repeat = (repet != 0); + + return thismidi; +} + + +#ifdef JGMOD_MOD_PLAYER + +MYMOD *thismod = NULL; +SOUNDCLIP *my_load_mod(const char *filname, int repet) +{ + + JGMOD *modPtr = load_mod((char *)filname); + if (modPtr == NULL) + return NULL; + + thismod = new MYMOD(); + thismod->tune = modPtr; + thismod->repeat = (repet != 0); + + return thismod; +} + +int init_mod_player(int numVoices) { + return install_mod(numVoices); +} + +void remove_mod_player() { + remove_mod(); +} + +//#endif // JGMOD_MOD_PLAYER +#elif defined DUMB_MOD_PLAYER + +MYMOD *thismod = nullptr; +SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet) +{ + size_t asset_size; + DUMBFILE *df = DUMBfileFromAsset(asset_name, asset_size); + if (!df) + return nullptr; + + DUH *modPtr = nullptr; + // determine the file extension + const char *lastDot = strrchr(asset_name.second, '.'); + if (lastDot == nullptr) + { + dumbfile_close(df); + return nullptr; + } + // get the first char of the extensin + int charAfterDot = toupper(lastDot[1]); + + // use the appropriate loader + if (charAfterDot == 'I') { + modPtr = dumb_read_it(df); + } + else if (charAfterDot == 'X') { + modPtr = dumb_read_xm(df); + } + else if (charAfterDot == 'S') { + modPtr = dumb_read_s3m(df); + } + else if (charAfterDot == 'M') { + modPtr = dumb_read_mod(df); + } + + dumbfile_close(df); + if (modPtr == nullptr) + return nullptr; + + thismod = new MYMOD(); + thismod->tune = modPtr; + thismod->vol = 255; + thismod->repeat = (repet != 0); + + return thismod; +} + +int init_mod_player(int numVoices) { + dumb_register_packfiles(); + return 0; +} + +void remove_mod_player() { + dumb_exit(); +} + +#endif // DUMB_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/sound.h b/engines/ags/engine/media/audio/sound.h new file mode 100644 index 000000000000..2a644159fb79 --- /dev/null +++ b/engines/ags/engine/media/audio/sound.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// ACSOUND - AGS sound system wrapper +// +//============================================================================= + +#ifndef __AC_SOUND_H +#define __AC_SOUND_H + +#include "ac/asset_helper.h" +#include "media/audio/soundclip.h" + +SOUNDCLIP *my_load_wave(const AssetPath &asset_name, int voll, int loop); +SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll); +SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop); +SOUNDCLIP *my_load_static_ogg(const AssetPath &asset_name, int voll, bool loop); +SOUNDCLIP *my_load_ogg(const AssetPath &asset_name, int voll); +SOUNDCLIP *my_load_midi(const AssetPath &asset_name, int repet); +SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet); + +extern int use_extra_sound_offset; + +#endif // __AC_SOUND_H diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp new file mode 100644 index 000000000000..3f59917c120c --- /dev/null +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -0,0 +1,234 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "ac/file.h" +#include "util/wgt2allg.h" +#include "media/audio/soundcache.h" +#include "media/audio/audiointernaldefs.h" +#include "util/mutex.h" +#include "util/mutex_lock.h" +#include "util/string.h" +#include "debug/out.h" + +using namespace Common; + +sound_cache_entry_t* sound_cache_entries = nullptr; +unsigned int sound_cache_counter = 0; + +AGS::Engine::Mutex _sound_cache_mutex; + + +void clear_sound_cache() +{ + AGS::Engine::MutexLock _lock(_sound_cache_mutex); + + if (sound_cache_entries) + { + int i; + for (i = 0; i < psp_audio_cachesize; i++) + { + if (sound_cache_entries[i].data) + { + free(sound_cache_entries[i].data); + sound_cache_entries[i].data = nullptr; + free(sound_cache_entries[i].file_name); + sound_cache_entries[i].file_name = nullptr; + sound_cache_entries[i].reference = 0; + } + } + } + else + { + sound_cache_entries = (sound_cache_entry_t*)malloc(psp_audio_cachesize * sizeof(sound_cache_entry_t)); + memset(sound_cache_entries, 0, psp_audio_cachesize * sizeof(sound_cache_entry_t)); + } +} + +void sound_cache_free(char* buffer, bool is_wave) +{ + AGS::Engine::MutexLock _lock(_sound_cache_mutex); + +#ifdef SOUND_CACHE_DEBUG + Debug::Printf("sound_cache_free(%p %d)\n", buffer, (unsigned int)is_wave); +#endif + int i; + for (i = 0; i < psp_audio_cachesize; i++) + { + if (sound_cache_entries[i].data == buffer) + { + if (sound_cache_entries[i].reference > 0) + sound_cache_entries[i].reference--; + +#ifdef SOUND_CACHE_DEBUG + Debug::Printf("..decreased reference count of slot %d to %d\n", i, sound_cache_entries[i].reference); +#endif + return; + } + } + +#ifdef SOUND_CACHE_DEBUG + Debug::Printf("..freeing uncached sound\n"); +#endif + + // Sound is uncached + if (i == psp_audio_cachesize) + { + if (is_wave) + destroy_sample((SAMPLE*)buffer); + else + free(buffer); + } +} + + +char* get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) +{ + AGS::Engine::MutexLock _lock(_sound_cache_mutex); + +#ifdef SOUND_CACHE_DEBUG + Debug::Printf("get_cached_sound(%s %d)\n", asset_name.first.GetCStr(), (unsigned int)is_wave); +#endif + + size = 0; + + int i; + for (i = 0; i < psp_audio_cachesize; i++) + { + if (sound_cache_entries[i].data == nullptr) + continue; + + if (strcmp(asset_name.second, sound_cache_entries[i].file_name) == 0) + { +#ifdef SOUND_CACHE_DEBUG + Debug::Printf("..found in slot %d\n", i); +#endif + sound_cache_entries[i].reference++; + sound_cache_entries[i].last_used = sound_cache_counter++; + size = sound_cache_entries[i].size; + + return sound_cache_entries[i].data; + } + } + + // Not found + PACKFILE *mp3in = nullptr; + SAMPLE* wave = nullptr; + + if (is_wave) + { + PACKFILE *wavin = PackfileFromAsset(asset_name, size); + if (wavin != nullptr) + { + wave = load_wav_pf(wavin); + pack_fclose(wavin); + } + } + else + { + mp3in = PackfileFromAsset(asset_name, size); + if (mp3in == nullptr) + { + return nullptr; + } + } + + // Find free slot + for (i = 0; i < psp_audio_cachesize; i++) + { + if (sound_cache_entries[i].data == nullptr) + break; + } + + // No free slot? + if (i == psp_audio_cachesize) + { + unsigned int oldest = sound_cache_counter; + int index = -1; + + for (i = 0; i < psp_audio_cachesize; i++) + { + if (sound_cache_entries[i].reference == 0) + { + if (sound_cache_entries[i].last_used < oldest) + { + oldest = sound_cache_entries[i].last_used; + index = i; + } + } + } + + i = index; + } + + // Load new file + char* newdata; + + if (is_wave) + { + size = 0; // ??? CHECKME + newdata = (char*)wave; + } + else + { + newdata = (char *)malloc(size); + + if (newdata == nullptr) + { + pack_fclose(mp3in); + return nullptr; + } + + pack_fread(newdata, size, mp3in); + pack_fclose(mp3in); + } + + if (i == -1) + { + // No cache slot empty, return uncached data +#ifdef SOUND_CACHE_DEBUG + Debug::Printf("..loading uncached\n"); +#endif + return newdata; + } + else + { + // Add to cache, free old sound first +#ifdef SOUND_CACHE_DEBUG + Debug::Printf("..loading cached in slot %d\n", i); +#endif + + if (sound_cache_entries[i].data) { + if (sound_cache_entries[i].is_wave) + destroy_sample((SAMPLE*)sound_cache_entries[i].data); + else + free(sound_cache_entries[i].data); + } + + sound_cache_entries[i].size = size; + sound_cache_entries[i].data = newdata; + + if (sound_cache_entries[i].file_name) + free(sound_cache_entries[i].file_name); + sound_cache_entries[i].file_name = (char*)malloc(strlen(asset_name.second) + 1); + strcpy(sound_cache_entries[i].file_name, asset_name.second); + sound_cache_entries[i].reference = 1; + sound_cache_entries[i].last_used = sound_cache_counter++; + sound_cache_entries[i].is_wave = is_wave; + + return sound_cache_entries[i].data; + } + +} diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h new file mode 100644 index 000000000000..ebdb67c69a92 --- /dev/null +++ b/engines/ags/engine/media/audio/soundcache.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_SOUNDCACHE_H +#define __AC_SOUNDCACHE_H + +#include "ac/asset_helper.h" + +// PSP: A simple sound cache. The size can be configured in the config file. +// The data rate while reading from disk on the PSP is usually between 500 to 900 kiB/s, +// caching the last used sound files therefore improves game performance. + +//#define SOUND_CACHE_DEBUG + +typedef struct +{ + char* file_name; + int number; + int free; + unsigned int last_used; + unsigned int size; + char* data; + int reference; + bool is_wave; +} sound_cache_entry_t; + +extern int psp_use_sound_cache; +extern int psp_sound_cache_max_size; +extern int psp_audio_cachesize; +extern int psp_midi_preload_patches; + +void clear_sound_cache(); +void sound_cache_free(char* buffer, bool is_wave); +char* get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size); + + +#endif // __AC_SOUNDCACHE_H diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp new file mode 100644 index 000000000000..844eb0fa9182 --- /dev/null +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -0,0 +1,80 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/wgt2allg.h" +#include "media/audio/audio.h" +#include "media/audio/audiodefines.h" +#include "media/audio/soundclip.h" +#include "media/audio/audiointernaldefs.h" + +int SOUNDCLIP::play_from(int position) +{ + int retVal = play(); + if ((retVal != 0) && (position > 0)) + { + seek(position); + } + return retVal; +} + +void SOUNDCLIP::set_panning(int newPanning) { + if (!is_playing()) { return; } + + int voice = get_voice(); + if (voice >= 0) { + voice_set_pan(voice, newPanning); + panning = newPanning; + } +} + +void SOUNDCLIP::pause() { + if (state_ != SoundClipPlaying) { return; } + + int voice = get_voice(); + if (voice >= 0) { + voice_stop(voice); + state_ = SoundClipPaused; + } +} + +void SOUNDCLIP::resume() { + if (state_ != SoundClipPaused) { return; } + + int voice = get_voice(); + if (voice >= 0) { + voice_start(voice); + state_ = SoundClipPlaying; + } +} + +SOUNDCLIP::SOUNDCLIP() { + state_ = SoundClipInitial; + priority = 50; + panning = 128; + panningAsPercentage = 0; + speed = 1000; + sourceClipType = 0; + sourceClip = nullptr; + vol = 0; + volAsPercentage = 0; + volModifier = 0; + muted = false; + repeat = false; + xSource = -1; + ySource = -1; + maximumPossibleDistanceAway = 0; + directionalVolModifier = 0; +} + +SOUNDCLIP::~SOUNDCLIP() = default; diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h new file mode 100644 index 000000000000..36a1166929d7 --- /dev/null +++ b/engines/ags/engine/media/audio/soundclip.h @@ -0,0 +1,170 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// ACSOUND - AGS sound system wrapper +// +//============================================================================= + +#ifndef __AC_SOUNDCLIP_H +#define __AC_SOUNDCLIP_H + +#include "util/mutex.h" + +// JJS: This is needed for the derieved classes +extern volatile int psp_audio_multithreaded; + +// TODO: one of the biggest problems with sound clips currently is that it +// provides several methods of applying volume, which may ignore or override +// each other, and does not shape a consistent interface. +// Improving this situation is only possible with massive refactory of +// sound clip use, taking backwards-compatible audio system in account. + +enum SoundClipState { SoundClipInitial, SoundClipPlaying, SoundClipPaused, SoundClipStopped }; + +struct SOUNDCLIP +{ + int priority; + int sourceClipType; + // absolute volume, set by implementations only! + int vol; + // current relative volume, in percents + int volAsPercentage; + // volModifier is used when there's a need to temporarily change and + // the restore the clip's absolute volume (vol) + int volModifier; + int panning; + int panningAsPercentage; + int xSource, ySource; + int maximumPossibleDistanceAway; + int directionalVolModifier; + bool repeat; + void *sourceClip; + + virtual void poll() = 0; + virtual void destroy() = 0; + // apply volume directly to playback; volume is given in units of 255 + // NOTE: this completely ignores volAsPercentage and muted property + virtual void set_volume(int) = 0; + virtual void seek(int) = 0; + virtual int get_pos() = 0; // return 0 to indicate seek not supported + virtual int get_pos_ms() = 0; // this must always return valid value if poss + virtual int get_length_ms() = 0; // return total track length in ms (or 0) + virtual int get_sound_type() = 0; + virtual int play() = 0; + + virtual int play_from(int position); + + virtual void set_panning(int newPanning); + virtual void set_speed(int new_speed) { speed = new_speed; } + + virtual void pause(); + virtual void resume(); + + inline bool is_playing() const { return state_ == SoundClipPlaying || state_ == SoundClipPaused; } + + inline int get_speed() const + { + return speed; + } + + // Gets clip's volume property, as percentage (0 - 100); + // note this may not be the real volume of playback (which could e.g. be muted) + inline int get_volume() const + { + return volAsPercentage; + } + + inline bool is_muted() const + { + return muted; + } + + // Sets the current volume property, as percentage (0 - 100). + inline void set_volume_percent(int volume) + { + volAsPercentage = volume; + if (!muted) + set_volume((volume * 255) / 100); + } + + // Explicitly defines both percentage and absolute volume value, + // without calculating it from given percentage. + // NOTE: this overrides the mute + inline void set_volume_direct(int vol_percent, int vol_absolute) + { + muted = false; + volAsPercentage = vol_percent; + set_volume(vol_absolute); + } + + // Mutes sound clip, while preserving current volume property + // for the future reference; when unmuted, that property is + // used to restart previous volume. + inline void set_mute(bool enable) + { + muted = enable; + if (enable) + set_volume(0); + else + set_volume((volAsPercentage * 255) / 100); + } + + // Apply arbitrary permanent volume modifier, in absolute units (0 - 255); + // this is distinct value that is used in conjunction with current volume + // (can be both positive and negative). + inline void apply_volume_modifier(int mod) + { + volModifier = mod; + adjust_volume(); + } + + // Apply permanent directional volume modifier, in absolute units (0 - 255) + // this is distinct value that is used in conjunction with current volume + // (can be both positive and negative). + inline void apply_directional_modifier(int mod) + { + directionalVolModifier = mod; + adjust_volume(); + } + + virtual void adjust_volume() = 0; + + SOUNDCLIP(); + virtual ~SOUNDCLIP(); + + +protected: + + SoundClipState state_; + + // mute mode overrides the volume; if set, any volume assigned is stored + // in properties, but not applied to playback itself + bool muted; + + // speed of playback, in clip ms per real second + int speed; + + // Return the allegro voice number (or -1 if none) + // Used by generic pause/resume functions. + virtual int get_voice() = 0; + + // helper function for calculating volume with applied modifiers + inline int get_final_volume() const + { + int final_vol = vol + volModifier + directionalVolModifier; + return final_vol >= 0 ? final_vol : 0; + } +}; + +#endif // __AC_SOUNDCLIP_H diff --git a/engines/ags/engine/media/video/VMR9Graph.h b/engines/ags/engine/media/video/VMR9Graph.h new file mode 100644 index 000000000000..4b91ac02ff3d --- /dev/null +++ b/engines/ags/engine/media/video/VMR9Graph.h @@ -0,0 +1,150 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// VMR9Graph.h: interface for the CVMR9Graph class. +// +//============================================================================= + +#if !defined(AFX_VMR9GRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_) +#define AFX_VMR9GRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include +#include + +//#pragma comment( lib, "strmiids.lib" ) +//#pragma comment( lib, "Quartz.lib" ) +//#pragma comment( lib, "d3d9.lib" ) +//#pragma comment( lib, "d3dx9.lib" ) + +#define WM_MEDIA_NOTIF (WM_APP + 777) + +class CVMR9Graph +{ + // Constructor / destructor +public: + CVMR9Graph(); + CVMR9Graph(HWND MediaWindow, IDirect3DDevice9 *device, int NumberOfStream = 4); + ~CVMR9Graph(); + + // Methods +public: + // Graph configuration + void SetNumberOfLayer(int nNumberOfLayer); + BOOL SetMediaWindow(HWND MediaWindow); + BOOL SetMediaFile(const char* pszFileName, bool withSound, int nLayer = 0); + BOOL PreserveAspectRatio(BOOL bPreserve = TRUE); + IBaseFilter* AddFilter(const char* pszName, const GUID& clsid); + + // Graph control + BOOL PlayGraph(); + BOOL StopGraph(); + BOOL ResetGraph(); + OAFilterState GetState(); + IMediaEvent* GetPtrMediaEvent(); + IMediaControl* GetPtrMediaControl(); + IMediaSeeking* GetPtrMediaSeeking(); + IBasicAudio* GetPtrBasicAudio(); + + + // Layer control + BOOL GetVideoRect(LPRECT pRect); + int GetAlphaLayer(int nLayer); + BOOL SetAlphaLayer(int nLayer, int nAlpha); + DWORD GetLayerZOrder(int nLayer); + BOOL SetLayerZOrder(int nLayer, DWORD dwZOrder); + BOOL SetLayerRect(int nLayer, RECT layerRect); + + // Bitmap control + BOOL SetBitmapParams(int nAlpha, COLORREF cTransColor, RECT bitmapRect); + + // Reflected from window + BOOL Repaint(); + BOOL Resize(); + + // helper + LPCTSTR GetLastError(); + + // Internal + BOOL BuildAndRenderGraph(bool withSound); + +protected: + // INIT helper methods + void InitDefaultValues(); + void ReleaseAllInterfaces(); + + // GRAPH methods + BOOL BuildFilterGraph(bool withSound); + BOOL BuildVMR(); + BOOL BuildSoundRenderer(); + BOOL RenderGraph(); + + // DIRECT3D methods + BOOL BuildDirect3d(); + + + // LAYER helper methods + BOOL IsValidLayer(int nLayer); + VMR9NormalizedRect NormalizeRect(LPRECT pRect); + + // DSOW helper methods + HRESULT AddToRot(IUnknown *pUnkGraph); + void RemoveFromRot(); + IPin* GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir); + void ReportError(const char* pszError, HRESULT hrCode); + HRESULT GetNextFilter(IBaseFilter *pFilter, PIN_DIRECTION Dir, IBaseFilter **ppNext); + BOOL RemoveFilterChain(IBaseFilter* pFilter, IBaseFilter* pStopFilter); + HRESULT AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, const GUID& clsid, IBaseFilter **ppF); + + // Attributes +public: + bool UseAVISound; + +protected: + DWORD m_dwRotId; + char m_pszErrorDescription[1024+MAX_ERROR_TEXT_LEN]; + int m_nNumberOfStream; + const char* m_pszFileName; + long m_oldWndProc; + // MEDIA WINDOW + HWND m_hMediaWindow; + // SRC interfaces array + IBaseFilter* m_srcFilterArray[10]; + // SOUND interfaces + IBaseFilter* m_pDirectSoundFilter; + // GRAPH interfaces + IUnknown* m_pGraphUnknown; + IGraphBuilder* m_pGraphBuilder; + IFilterGraph* m_pFilterGraph; + IFilterGraph2* m_pFilterGraph2; + IMediaControl* m_pMediaControl; + IMediaSeeking* m_pMediaSeeking; + //IMediaEvent* m_pMediaEvent; + IMediaEventEx* m_pMediaEventEx; + // VMR9 interfaces + IBaseFilter* m_pVMRBaseFilter; + IVMRFilterConfig9* m_pVMRFilterConfig; + IVMRMixerBitmap9* m_pVMRMixerBitmap; + IVMRMixerControl9* m_pVMRMixerControl; + IVMRMonitorConfig9* m_pVMRMonitorConfig; + IVMRWindowlessControl9* m_pVMRWindowlessControl; + // DIRECT3D interfaces + //IDirect3DDevice9* m_pD3DDevice; + IDirect3DSurface9* m_pD3DSurface; +}; + +#endif // !defined(AFX_VMR9GRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_) diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp new file mode 100644 index 000000000000..e2e1ebfc62cd --- /dev/null +++ b/engines/ags/engine/media/video/video.cpp @@ -0,0 +1,431 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "media/video/video.h" + +#ifndef AGS_NO_VIDEO_PLAYER + +#include "apeg.h" +#include "core/platform.h" +#define AGS_FLI_FROM_PACK_FILE ((ALLEGRO_DATE >= 20190303) || \ + AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_MACOS) + +#include "debug/debug_log.h" +#include "debug/out.h" +#include "ac/asset_helper.h" +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/game_version.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_display.h" +#include "ac/mouse.h" +#include "ac/sys_events.h" +#include "ac/runtime_defines.h" +#include "ac/system.h" +#include "core/assetmanager.h" +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "gfx/graphicsdriver.h" +#include "main/game_run.h" +#include "util/stream.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + + +extern GameSetupStruct game; +extern IGraphicsDriver *gfxDriver; +extern int psp_video_framedrop; + +enum VideoPlaybackType +{ + kVideoNone, + kVideoFlic, + kVideoTheora +}; + +VideoPlaybackType video_type = kVideoNone; + +// FLIC player start +Bitmap *fli_buffer = nullptr; +short fliwidth,fliheight; +int canabort=0, stretch_flc = 1; +Bitmap *hicol_buf=nullptr; +IDriverDependantBitmap *fli_ddb = nullptr; +Bitmap *fli_target = nullptr; +int fliTargetWidth, fliTargetHeight; +int check_if_user_input_should_cancel_video() +{ + int key, mbut, mwheelz; + if (run_service_key_controls(key)) { + if ((key==27) && (canabort==1)) + return 1; + if (canabort >= 2) + return 1; // skip on any key + } + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && canabort == 3) { + return 1; // skip on mouse click + } + return 0; +} + +#if AGS_PLATFORM_OS_WINDOWS +int __cdecl fli_callback() { +#else +extern "C" int fli_callback() { +#endif + Bitmap *usebuf = fli_buffer; + + update_audio_system_on_game_loop (); + + if (game.color_depth > 1) { + hicol_buf->Blit(fli_buffer,0,0,0,0,fliwidth,fliheight); + usebuf=hicol_buf; + } + + const Rect &view = play.GetMainViewport(); + if (stretch_flc == 0) + fli_target->Blit(usebuf, 0,0, view.GetWidth()/2-fliwidth/2, view.GetHeight()/2-fliheight/2, view.GetWidth(), view.GetHeight()); + else + fli_target->StretchBlt(usebuf, RectWH(0,0,fliwidth,fliheight), RectWH(0,0, view.GetWidth(), view.GetHeight())); + + gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); + gfxDriver->DrawSprite(0, 0, fli_ddb); + render_to_screen(); + + return check_if_user_input_should_cancel_video(); +} + +void play_flc_file(int numb,int playflags) { + color oldpal[256]; + + // AGS 2.x: If the screen is faded out, fade in again when playing a movie. + if (loaded_game_file_version <= kGameVersion_272) + play.screen_is_faded_out = 0; + + if (play.fast_forward) + return; + + get_palette_range(oldpal, 0, 255); + + int clearScreenAtStart = 1; + canabort = playflags % 10; + playflags -= canabort; + + if (canabort == 2) // convert to PlayVideo-compatible setting + canabort = 3; + + if (playflags % 100 == 0) + stretch_flc = 1; + else + stretch_flc = 0; + + if (playflags / 100) + clearScreenAtStart = 0; + + String flicname = String::FromFormat("flic%d.flc", numb); + Stream *in = AssetManager::OpenAsset(flicname); + if (!in) + { + flicname.Format("flic%d.fli", numb); + in = AssetManager::OpenAsset(flicname); + } + if (!in) + { + debug_script_warn("FLIC animation flic%d.flc nor flic%d.fli not found", numb, numb); + return; + } + + in->Seek(8); + fliwidth = in->ReadInt16(); + fliheight = in->ReadInt16(); + delete in; + + if (game.color_depth > 1) { + hicol_buf=BitmapHelper::CreateBitmap(fliwidth,fliheight,game.GetColorDepth()); + hicol_buf->Clear(); + } + // override the stretch option if necessary + const Rect &view = play.GetMainViewport(); + if ((fliwidth == view.GetWidth()) && (fliheight == view.GetHeight())) + stretch_flc = 0; + else if ((fliwidth > view.GetWidth()) || (fliheight >view.GetHeight())) + stretch_flc = 1; + fli_buffer=BitmapHelper::CreateBitmap(fliwidth,fliheight,8); + if (fli_buffer==nullptr) quit("Not enough memory to play animation"); + fli_buffer->Clear(); + + if (clearScreenAtStart) + { + if (gfxDriver->UsesMemoryBackBuffer()) + { + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + screen_bmp->Clear(); + } + render_to_screen(); + } + + video_type = kVideoFlic; + fli_target = BitmapHelper::CreateBitmap(view.GetWidth(), view.GetHeight(), game.GetColorDepth()); + fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); + + // TODO: find a better solution. + // Make only certain versions of the engineuse play_fli_pf from the patched version of Allegro for now. + // Add more versions as their Allegro lib becomes patched too, or they use newer version of Allegro 4. + // Ports can still play FLI if separate file is put into game's directory. +#if AGS_FLI_FROM_PACK_FILE + size_t asset_size; + PACKFILE *pf = PackfileFromAsset(AssetPath("", flicname), asset_size); + if (play_fli_pf(pf, (BITMAP*)fli_buffer->GetAllegroBitmap(), fli_callback)==FLI_ERROR) +#else + if (play_fli(flicname, (BITMAP*)fli_buffer->GetAllegroBitmap(), 0, fli_callback)==FLI_ERROR) +#endif + { + // This is not a fatal error that should prevent the game from continuing + Debug::Printf("FLI/FLC animation play error"); + } +#if AGS_FLI_FROM_PACK_FILE + pack_fclose(pf); +#endif + + video_type = kVideoNone; + delete fli_buffer; + fli_buffer = nullptr; + // NOTE: the screen bitmap could change in the meanwhile, if the display mode has changed + if (gfxDriver->UsesMemoryBackBuffer()) + { + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + screen_bmp->Clear(); + } + set_palette_range(oldpal, 0, 255, 0); + render_to_screen(); + + delete fli_target; + gfxDriver->DestroyDDB(fli_ddb); + fli_target = nullptr; + fli_ddb = nullptr; + + + delete hicol_buf; + hicol_buf=nullptr; + // SetVirtualScreen(screen); wputblock(0,0,backbuffer,0); + while (ags_mgetbutton()!=NONE) { } // clear any queued mouse events. + invalidate_screen(); +} + +// FLIC player end + +// Theora player begin +// TODO: find a way to take Bitmap here? +Bitmap gl_TheoraBuffer; +int theora_playing_callback(BITMAP *theoraBuffer) +{ + if (theoraBuffer == nullptr) + { + // No video, only sound + return check_if_user_input_should_cancel_video(); + } + + gl_TheoraBuffer.WrapAllegroBitmap(theoraBuffer, true); + + int drawAtX = 0, drawAtY = 0; + const Rect &viewport = play.GetMainViewport(); + if (fli_ddb == nullptr) + { + fli_ddb = gfxDriver->CreateDDBFromBitmap(&gl_TheoraBuffer, false, true); + } + if (stretch_flc) + { + drawAtX = viewport.GetWidth() / 2 - fliTargetWidth / 2; + drawAtY = viewport.GetHeight() / 2 - fliTargetHeight / 2; + if (!gfxDriver->HasAcceleratedTransform()) + { + fli_target->StretchBlt(&gl_TheoraBuffer, RectWH(0, 0, gl_TheoraBuffer.GetWidth(), gl_TheoraBuffer.GetHeight()), + RectWH(drawAtX, drawAtY, fliTargetWidth, fliTargetHeight)); + gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); + drawAtX = 0; + drawAtY = 0; + } + else + { + gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); + fli_ddb->SetStretch(fliTargetWidth, fliTargetHeight, false); + } + } + else + { + gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); + drawAtX = viewport.GetWidth() / 2 - gl_TheoraBuffer.GetWidth() / 2; + drawAtY = viewport.GetHeight() / 2 - gl_TheoraBuffer.GetHeight() / 2; + } + + gfxDriver->DrawSprite(drawAtX, drawAtY, fli_ddb); + update_audio_system_on_game_loop (); + render_to_screen(); + + return check_if_user_input_should_cancel_video(); +} + +// +// Theora stream reader callbacks. We need these because APEG library does not +// provide means to supply user's PACKFILE directly. +// +// Open stream for reading (return suggested cache buffer size). +int apeg_stream_init(void *ptr) +{ + return ptr != nullptr ? F_BUF_SIZE : 0; +} +// Read requested number of bytes into provided buffer, +// return actual number of bytes managed to read. +int apeg_stream_read(void *buffer, int bytes, void *ptr) +{ + return ((Stream*)ptr)->Read(buffer, bytes); +} +// Skip requested number of bytes +void apeg_stream_skip(int bytes, void *ptr) +{ + ((Stream*)ptr)->Seek(bytes); +} +// + +APEG_STREAM* get_theora_size(Stream *video_stream, int *width, int *height) +{ + APEG_STREAM* oggVid = apeg_open_stream_ex(video_stream); + if (oggVid != nullptr) + { + apeg_get_video_size(oggVid, width, height); + } + else + { + *width = 0; + *height = 0; + } + return oggVid; +} + +// TODO: use shared utility function for placing rect in rect +void calculate_destination_size_maintain_aspect_ratio(int vidWidth, int vidHeight, int *targetWidth, int *targetHeight) +{ + const Rect &viewport = play.GetMainViewport(); + float aspectRatioVideo = (float)vidWidth / (float)vidHeight; + float aspectRatioScreen = (float)viewport.GetWidth() / (float)viewport.GetHeight(); + + if (aspectRatioVideo == aspectRatioScreen) + { + *targetWidth = viewport.GetWidth(); + *targetHeight = viewport.GetHeight(); + } + else if (aspectRatioVideo > aspectRatioScreen) + { + *targetWidth = viewport.GetWidth(); + *targetHeight = (int)(((float)viewport.GetWidth() / aspectRatioVideo) + 0.5f); + } + else + { + *targetHeight = viewport.GetHeight(); + *targetWidth = (float)viewport.GetHeight() * aspectRatioVideo; + } + +} + +void play_theora_video(const char *name, int skip, int flags) +{ + std::unique_ptr video_stream(AssetManager::OpenAsset(name)); + apeg_set_stream_reader(apeg_stream_init, apeg_stream_read, apeg_stream_skip); + apeg_set_display_depth(game.GetColorDepth()); + // we must disable length detection, otherwise it takes ages to start + // playing if the file is large because it seeks through the whole thing + apeg_disable_length_detection(TRUE); + // Disable framedrop because it can lead to the PSP not playing the video at all. + apeg_enable_framedrop(psp_video_framedrop); + update_polled_stuff_if_runtime(); + + stretch_flc = (flags % 10); + canabort = skip; + apeg_ignore_audio((flags >= 10) ? 1 : 0); + + int videoWidth, videoHeight; + APEG_STREAM *oggVid = get_theora_size(video_stream.get(), &videoWidth, &videoHeight); + + if (videoWidth == 0) + { + Display("Unable to load theora video '%s'", name); + return; + } + + if (flags < 10) + { + stop_all_sound_and_music(); + } + + //fli_buffer = BitmapHelper::CreateBitmap_(scsystem.coldepth, videoWidth, videoHeight); + calculate_destination_size_maintain_aspect_ratio(videoWidth, videoHeight, &fliTargetWidth, &fliTargetHeight); + + if ((fliTargetWidth == videoWidth) && (fliTargetHeight == videoHeight) && (stretch_flc)) + { + // don't need to stretch after all + stretch_flc = 0; + } + + if ((stretch_flc) && (!gfxDriver->HasAcceleratedTransform())) + { + fli_target = BitmapHelper::CreateBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight(), game.GetColorDepth()); + fli_target->Clear(); + fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); + } + else + { + fli_ddb = nullptr; + } + + update_polled_stuff_if_runtime(); + + if (gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->GetMemoryBackBuffer()->Clear(); + + video_type = kVideoTheora; + if (apeg_play_apeg_stream(oggVid, nullptr, 0, theora_playing_callback) == APEG_ERROR) + { + Display("Error playing theora video '%s'", name); + } + apeg_close_stream(oggVid); + video_type = kVideoNone; + + //destroy_bitmap(fli_buffer); + delete fli_target; + gfxDriver->DestroyDDB(fli_ddb); + fli_target = nullptr; + fli_ddb = nullptr; + invalidate_screen(); +} +// Theora player end + +void video_on_gfxmode_changed() +{ + if (video_type == kVideoFlic) + { + // If the FLIC video is playing, restore its palette + set_palette_range(fli_palette, 0, 255, 0); + } +} + +#else + +void play_theora_video(const char *name, int skip, int flags) {} +void play_flc_file(int numb,int playflags) {} +void video_on_gfxmode_changed() {} + +#endif \ No newline at end of file diff --git a/engines/ags/engine/media/video/video.h b/engines/ags/engine/media/video/video.h new file mode 100644 index 000000000000..1110260968c5 --- /dev/null +++ b/engines/ags/engine/media/video/video.h @@ -0,0 +1,27 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_MEDIA__VIDEO_H +#define __AGS_EE_MEDIA__VIDEO_H + +void play_theora_video(const char *name, int skip, int flags); +void play_flc_file(int numb,int playflags); + +// Update video playback if the display mode has changed +void video_on_gfxmode_changed(); + +#endif // __AGS_EE_MEDIA__VIDEO_H diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp new file mode 100644 index 000000000000..596c4aae5771 --- /dev/null +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -0,0 +1,757 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_ANDROID + +#include +#include "platform/base/agsplatformdriver.h" +#include "ac/runtime_defines.h" +#include "main/config.h" +#include "plugin/agsplugin.h" +#include +#include +#include +#include +#include +#include "util/string_compat.h" + + + +#include +#include + +using namespace AGS::Common; + +#define ANDROID_CONFIG_FILENAME "android.cfg" + +bool ReadConfiguration(char* filename, bool read_everything); +void ResetConfiguration(); + +struct AGSAndroid : AGSPlatformDriver { + + virtual int CDPlayerCommand(int cmdd, int datt); + virtual void Delay(int millis); + virtual void DisplayAlert(const char*, ...); + virtual const char *GetAppOutputDirectory(); + virtual unsigned long GetDiskFreeSpaceMB(); + virtual const char* GetNoMouseErrorString(); + virtual bool IsBackendResponsibleForMouseScaling() { return true; } + virtual eScriptSystemOSID GetSystemOSID(); + virtual int InitializeCDPlayer(); + virtual void PostAllegroExit(); + virtual void SetGameWindowIcon(); + virtual void ShutdownCDPlayer(); + virtual void WriteStdOut(const char *fmt, ...); + virtual void WriteStdErr(const char *fmt, ...); +}; + + +//int psp_return_to_menu = 1; +int psp_ignore_acsetup_cfg_file = 1; +int psp_clear_cache_on_room_change = 0; +int psp_rotation = 0; +int psp_config_enabled = 0; +char psp_translation[100]; +char* psp_translations[100]; + +// Mouse option from Allegro. +extern int config_mouse_control_mode; + + +// Graphic options from the Allegro library. +extern int psp_gfx_scaling; +extern int psp_gfx_smoothing; + + +// Audio options from the Allegro library. +unsigned int psp_audio_samplerate = 44100; +int psp_audio_enabled = 1; +volatile int psp_audio_multithreaded = 1; +int psp_audio_cachesize = 10; +int psp_midi_enabled = 1; +int psp_midi_preload_patches = 0; + +int psp_video_framedrop = 0; + +int psp_gfx_renderer = 0; +int psp_gfx_super_sampling = 0; +int psp_gfx_smooth_sprites = 0; + +int psp_debug_write_to_logcat = 0; + +int config_mouse_longclick = 0; + +extern int display_fps; +extern int want_exit; +extern void PauseGame(); +extern void UnPauseGame(); +extern int main(int argc,char*argv[]); + +char android_base_directory[256]; +char android_app_directory[256]; +char psp_game_file_name[256]; +char* psp_game_file_name_pointer = psp_game_file_name; + +bool psp_load_latest_savegame = false; +extern char saveGameDirectory[260]; +extern const char *loadSaveGameOnStartup; +char lastSaveGameName[200]; + + +extern JavaVM* android_jni_vm; +JNIEnv *java_environment; +jobject java_object; +jclass java_class; +jmethodID java_messageCallback; +jmethodID java_blockExecution; +jmethodID java_swapBuffers; +jmethodID java_setRotation; +jmethodID java_enableLongclick; + +bool reset_configuration = false; + +extern "C" +{ + +const int CONFIG_IGNORE_ACSETUP = 0; +const int CONFIG_CLEAR_CACHE = 1; +const int CONFIG_AUDIO_RATE = 2; +const int CONFIG_AUDIO_ENABLED = 3; +const int CONFIG_AUDIO_THREADED = 4; +const int CONFIG_AUDIO_CACHESIZE = 5; +const int CONFIG_MIDI_ENABLED = 6; +const int CONFIG_MIDI_PRELOAD = 7; +const int CONFIG_VIDEO_FRAMEDROP = 8; +const int CONFIG_GFX_RENDERER = 9; +const int CONFIG_GFX_SMOOTHING = 10; +const int CONFIG_GFX_SCALING = 11; +const int CONFIG_GFX_SS = 12; +const int CONFIG_ROTATION = 13; +const int CONFIG_ENABLED = 14; +const int CONFIG_DEBUG_FPS = 15; +const int CONFIG_GFX_SMOOTH_SPRITES = 16; +const int CONFIG_TRANSLATION = 17; +const int CONFIG_DEBUG_LOGCAT = 18; +const int CONFIG_MOUSE_METHOD = 19; +const int CONFIG_MOUSE_LONGCLICK = 20; + +extern void android_debug_printf(const char* format, ...); + +JNIEXPORT jboolean JNICALL + Java_com_bigbluecup_android_PreferencesActivity_readConfigFile(JNIEnv* env, jobject object, jstring directory) +{ + const char* cdirectory = env->GetStringUTFChars(directory, NULL); + chdir(cdirectory); + env->ReleaseStringUTFChars(directory, cdirectory); + + ResetConfiguration(); + + return ReadConfiguration(ANDROID_CONFIG_FILENAME, true); +} + + +JNIEXPORT jboolean JNICALL + Java_com_bigbluecup_android_PreferencesActivity_writeConfigFile(JNIEnv* env, jobject object) +{ + FILE* config = fopen(ANDROID_CONFIG_FILENAME, "wb"); + if (config) + { + fprintf(config, "[misc]\n"); + fprintf(config, "config_enabled = %d\n", psp_config_enabled); + fprintf(config, "rotation = %d\n", psp_rotation); + fprintf(config, "translation = %s\n", psp_translation); + + fprintf(config, "[controls]\n"); + fprintf(config, "mouse_method = %d\n", config_mouse_control_mode); + fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick); + + fprintf(config, "[compatibility]\n"); +// fprintf(config, "ignore_acsetup_cfg_file = %d\n", psp_ignore_acsetup_cfg_file); + fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change); + + fprintf(config, "[sound]\n"); + fprintf(config, "samplerate = %d\n", psp_audio_samplerate ); + fprintf(config, "enabled = %d\n", psp_audio_enabled); + fprintf(config, "threaded = %d\n", psp_audio_multithreaded); + fprintf(config, "cache_size = %d\n", psp_audio_cachesize); + + fprintf(config, "[midi]\n"); + fprintf(config, "enabled = %d\n", psp_midi_enabled); + fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches); + + fprintf(config, "[video]\n"); + fprintf(config, "framedrop = %d\n", psp_video_framedrop); + + fprintf(config, "[graphics]\n"); + fprintf(config, "renderer = %d\n", psp_gfx_renderer); + fprintf(config, "smoothing = %d\n", psp_gfx_smoothing); + fprintf(config, "scaling = %d\n", psp_gfx_scaling); + fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling); + fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites); + + fprintf(config, "[debug]\n"); + fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0); + fprintf(config, "logging = %d\n", psp_debug_write_to_logcat); + + fclose(config); + + return true; + } + + return false; +} + + +JNIEXPORT jint JNICALL + Java_com_bigbluecup_android_PreferencesActivity_readIntConfigValue(JNIEnv* env, jobject object, jint id) +{ + switch (id) + { + case CONFIG_IGNORE_ACSETUP: + return psp_ignore_acsetup_cfg_file; + break; + case CONFIG_CLEAR_CACHE: + return psp_clear_cache_on_room_change; + break; + case CONFIG_AUDIO_RATE: + return psp_audio_samplerate; + break; + case CONFIG_AUDIO_ENABLED: + return psp_audio_enabled; + break; + case CONFIG_AUDIO_THREADED: + return psp_audio_multithreaded; + break; + case CONFIG_AUDIO_CACHESIZE: + return psp_audio_cachesize; + break; + case CONFIG_MIDI_ENABLED: + return psp_midi_enabled; + break; + case CONFIG_MIDI_PRELOAD: + return psp_midi_preload_patches; + break; + case CONFIG_VIDEO_FRAMEDROP: + return psp_video_framedrop; + break; + case CONFIG_GFX_RENDERER: + return psp_gfx_renderer; + break; + case CONFIG_GFX_SMOOTHING: + return psp_gfx_smoothing; + break; + case CONFIG_GFX_SCALING: + return psp_gfx_scaling; + break; + case CONFIG_GFX_SS: + return psp_gfx_super_sampling; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + return psp_gfx_smooth_sprites; + break; + case CONFIG_ROTATION: + return psp_rotation; + break; + case CONFIG_ENABLED: + return psp_config_enabled; + break; + case CONFIG_DEBUG_FPS: + return (display_fps == 2) ? 1 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + return psp_debug_write_to_logcat; + break; + case CONFIG_MOUSE_METHOD: + return config_mouse_control_mode; + break; + case CONFIG_MOUSE_LONGCLICK: + return config_mouse_longclick; + break; + default: + return 0; + break; + } +} + + +JNIEXPORT jstring JNICALL + Java_com_bigbluecup_android_PreferencesActivity_readStringConfigValue(JNIEnv* env, jobject object, jint id, jstring value) +{ + switch (id) + { + case CONFIG_TRANSLATION: + return env->NewStringUTF(&psp_translation[0]); + break; + } +} + + +JNIEXPORT void JNICALL + Java_com_bigbluecup_android_PreferencesActivity_setIntConfigValue(JNIEnv* env, jobject object, jint id, jint value) +{ + switch (id) + { + case CONFIG_IGNORE_ACSETUP: + psp_ignore_acsetup_cfg_file = value; + break; + case CONFIG_CLEAR_CACHE: + psp_clear_cache_on_room_change = value; + break; + case CONFIG_AUDIO_RATE: + psp_audio_samplerate = value; + break; + case CONFIG_AUDIO_ENABLED: + psp_audio_enabled = value; + break; + case CONFIG_AUDIO_THREADED: + psp_audio_multithreaded = value; + break; + case CONFIG_AUDIO_CACHESIZE: + psp_audio_cachesize = value; + break; + case CONFIG_MIDI_ENABLED: + psp_midi_enabled = value; + break; + case CONFIG_MIDI_PRELOAD: + psp_midi_preload_patches = value; + break; + case CONFIG_VIDEO_FRAMEDROP: + psp_video_framedrop = value; + break; + case CONFIG_GFX_RENDERER: + psp_gfx_renderer = value; + break; + case CONFIG_GFX_SMOOTHING: + psp_gfx_smoothing = value; + break; + case CONFIG_GFX_SCALING: + psp_gfx_scaling = value; + break; + case CONFIG_GFX_SS: + psp_gfx_super_sampling = value; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + psp_gfx_smooth_sprites = value; + break; + case CONFIG_ROTATION: + psp_rotation = value; + break; + case CONFIG_ENABLED: + psp_config_enabled = value; + break; + case CONFIG_DEBUG_FPS: + display_fps = (value == 1) ? 2 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + psp_debug_write_to_logcat = value; + break; + case CONFIG_MOUSE_METHOD: + config_mouse_control_mode = value; + break; + case CONFIG_MOUSE_LONGCLICK: + config_mouse_longclick = value; + break; + default: + break; + } +} + + +JNIEXPORT void JNICALL + Java_com_bigbluecup_android_PreferencesActivity_setStringConfigValue(JNIEnv* env, jobject object, jint id, jstring value) +{ + const char* cstring = env->GetStringUTFChars(value, NULL); + + switch (id) + { + case CONFIG_TRANSLATION: + strcpy(psp_translation, cstring); + break; + default: + break; + } + + env->ReleaseStringUTFChars(value, cstring); +} + + +JNIEXPORT jint JNICALL +Java_com_bigbluecup_android_PreferencesActivity_getAvailableTranslations(JNIEnv* env, jobject object, jobjectArray translations) +{ + int i = 0; + int length; + DIR* dir; + struct dirent* entry; + char buffer[200]; + + dir = opendir("."); + if (dir) + { + while ((entry = readdir(dir)) != 0) + { + length = strlen(entry->d_name); + if (length > 4) + { + if (ags_stricmp(&entry->d_name[length - 4], ".tra") == 0) + { + memset(buffer, 0, 200); + strncpy(buffer, entry->d_name, length - 4); + psp_translations[i] = (char*)malloc(strlen(buffer) + 1); + strcpy(psp_translations[i], buffer); + env->SetObjectArrayElement(translations, i, env->NewStringUTF(&buffer[0])); + i++; + } + } + } + closedir(dir); + } + + return i; +} + + +JNIEXPORT void JNICALL + Java_com_bigbluecup_android_EngineGlue_pauseEngine(JNIEnv* env, jobject object) +{ + PauseGame(); +} + +JNIEXPORT void JNICALL + Java_com_bigbluecup_android_EngineGlue_resumeEngine(JNIEnv* env, jobject object) +{ + UnPauseGame(); +} + + +JNIEXPORT void JNICALL + Java_com_bigbluecup_android_EngineGlue_shutdownEngine(JNIEnv* env, jobject object) +{ + want_exit = 1; +} + + +JNIEXPORT jboolean JNICALL + Java_com_bigbluecup_android_EngineGlue_startEngine(JNIEnv* env, jobject object, jclass stringclass, jstring filename, jstring directory, jstring appDirectory, jboolean loadLastSave) +{ + // Get JNI interfaces. + java_object = env->NewGlobalRef(object); + java_environment = env; + java_class = (jclass)java_environment->NewGlobalRef(java_environment->GetObjectClass(object)); + java_messageCallback = java_environment->GetMethodID(java_class, "showMessage", "(Ljava/lang/String;)V"); + java_blockExecution = java_environment->GetMethodID(java_class, "blockExecution", "()V"); + java_setRotation = java_environment->GetMethodID(java_class, "setRotation", "(I)V"); + java_enableLongclick = java_environment->GetMethodID(java_class, "enableLongclick", "()V"); + + // Initialize JNI for Allegro. + android_allegro_initialize_jni(java_environment, java_class, java_object); + + // Get the file to run from Java. + const char* cpath = java_environment->GetStringUTFChars(filename, NULL); + strcpy(psp_game_file_name, cpath); + java_environment->ReleaseStringUTFChars(filename, cpath); + + // Get the base directory (usually "/sdcard/ags"). + const char* cdirectory = java_environment->GetStringUTFChars(directory, NULL); + chdir(cdirectory); + strcpy(android_base_directory, cdirectory); + java_environment->ReleaseStringUTFChars(directory, cdirectory); + + // Get the app directory (something like "/data/data/com.bigbluecup.android.launcher") + const char* cappDirectory = java_environment->GetStringUTFChars(appDirectory, NULL); + strcpy(android_app_directory, cappDirectory); + java_environment->ReleaseStringUTFChars(appDirectory, cappDirectory); + + // Reset configuration. + ResetConfiguration(); + + // Read general configuration. + ReadConfiguration(ANDROID_CONFIG_FILENAME, true); + + // Get the games path. + char path[256]; + strcpy(path, psp_game_file_name); + int lastindex = strlen(path) - 1; + while (path[lastindex] != '/') + { + path[lastindex] = 0; + lastindex--; + } + chdir(path); + + setenv("ULTRADIR", "..", 1); + + // Read game specific configuration. + ReadConfiguration(ANDROID_CONFIG_FILENAME, false); + + // Set the screen rotation. + if (psp_rotation > 0) + java_environment->CallVoidMethod(java_object, java_setRotation, psp_rotation); + + if (config_mouse_longclick > 0) + java_environment->CallVoidMethod(java_object, java_enableLongclick); + + psp_load_latest_savegame = loadLastSave; + + // Start the engine main function. + main(1, &psp_game_file_name_pointer); + + // Explicitly quit here, otherwise the app will hang forever. + exit(0); + + return true; +} + + +void selectLatestSavegame() +{ + DIR* dir; + struct dirent* entry; + struct stat statBuffer; + char buffer[200]; + time_t lastTime = 0; + + dir = opendir(saveGameDirectory); + + if (dir) + { + while ((entry = readdir(dir)) != 0) + { + if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) + { + if (ags_stricmp(entry->d_name, "agssave.999") != 0) + { + strcpy(buffer, saveGameDirectory); + strcat(buffer, entry->d_name); + stat(buffer, &statBuffer); + if (statBuffer.st_mtime > lastTime) + { + strcpy(lastSaveGameName, buffer); + loadSaveGameOnStartup = lastSaveGameName; + lastTime = statBuffer.st_mtime; + } + } + } + } + closedir(dir); + } +} + +} + + +int ReadInteger(int* variable, const ConfigTree &cfg, char* section, char* name, int minimum, int maximum, int default_value) +{ + if (reset_configuration) + { + *variable = default_value; + return 0; + } + + int temp = INIreadint(cfg, section, name); + + if (temp == -1) + return 0; + + if ((temp < minimum) || (temp > maximum)) + temp = default_value; + + *variable = temp; + + return 1; +} + + + +int ReadString(char* variable, const ConfigTree &cfg, char* section, char* name, char* default_value) +{ + if (reset_configuration) + { + strcpy(variable, default_value); + return 0; + } + + String temp; + if (!INIreaditem(cfg, section, name, temp)) + temp = default_value; + + strcpy(variable, temp); + + return 1; +} + + + +void ResetConfiguration() +{ + reset_configuration = true; + + ReadConfiguration(ANDROID_CONFIG_FILENAME, true); + + reset_configuration = false; +} + + + +bool ReadConfiguration(char* filename, bool read_everything) +{ + ConfigTree cfg; + if (IniUtil::Read(filename, cfg) || reset_configuration) + { +// ReadInteger((int*)&psp_disable_powersaving, "misc", "disable_power_saving", 0, 1, 1); + +// ReadInteger((int*)&psp_return_to_menu, "misc", "return_to_menu", 0, 1, 1); + + ReadString(&psp_translation[0], cfg, "misc", "translation", "default"); + + ReadInteger((int*)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0); + if (!psp_config_enabled && !read_everything) + return true; + + ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0); + ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0); + if (display_fps == 1) + display_fps = 2; + + ReadInteger((int*)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0); + +// ReadInteger((int*)&psp_ignore_acsetup_cfg_file, "compatibility", "ignore_acsetup_cfg_file", 0, 1, 0); + ReadInteger((int*)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0); + + ReadInteger((int*)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100); + ReadInteger((int*)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1); + ReadInteger((int*)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1); + ReadInteger((int*)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10); + + ReadInteger((int*)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1); + ReadInteger((int*)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0); + + ReadInteger((int*)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0); + + ReadInteger((int*)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0); + ReadInteger((int*)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1); + ReadInteger((int*)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1); + ReadInteger((int*)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0); + ReadInteger((int*)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0); + + ReadInteger((int*)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0); + ReadInteger((int*)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1); + + return true; + } + + return false; +} + + + +int AGSAndroid::CDPlayerCommand(int cmdd, int datt) { + return 1;//cd_player_control(cmdd, datt); +} + +void AGSAndroid::DisplayAlert(const char *text, ...) { + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + + // It is possible that this is called from a thread that is not yet known + // to the Java VM. So attach it first before displaying the message. + JNIEnv* thread_env; + android_jni_vm->AttachCurrentThread(&thread_env, NULL); + + __android_log_print(ANDROID_LOG_DEBUG, "AGSNative", "%s", displbuf); + + jstring java_string = thread_env->NewStringUTF(displbuf); + thread_env->CallVoidMethod(java_object, java_messageCallback, java_string); + usleep(1000 * 1000); + thread_env->CallVoidMethod(java_object, java_blockExecution); + +// android_jni_vm->DetachCurrentThread(); +} + +void AGSAndroid::Delay(int millis) { + usleep(millis * 1000); +} + +unsigned long AGSAndroid::GetDiskFreeSpaceMB() { + // placeholder + return 100; +} + +const char* AGSAndroid::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +} + +eScriptSystemOSID AGSAndroid::GetSystemOSID() { + return eOS_Android; +} + +int AGSAndroid::InitializeCDPlayer() { + return 1;//cd_player_init(); +} + +void AGSAndroid::PostAllegroExit() { + java_environment->DeleteGlobalRef(java_class); +} + +void AGSAndroid::SetGameWindowIcon() { + // do nothing +} + +void AGSAndroid::WriteStdOut(const char *fmt, ...) +{ + // TODO: this check should probably be done once when setting up output targets for logging + if (psp_debug_write_to_logcat) + { + va_list args; + va_start(args, fmt); + __android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args); + // NOTE: __android_log_* functions add trailing '\n' + va_end(args); + } +} + +void AGSAndroid::WriteStdErr(const char *fmt, ...) +{ + // TODO: find out if Android needs separate implementation for stderr + if (psp_debug_write_to_logcat) + { + va_list args; + va_start(args, fmt); + __android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args); + // NOTE: __android_log_* functions add trailing '\n' + va_end(args); + } +} + +void AGSAndroid::ShutdownCDPlayer() { + //cd_exit(); +} + +const char *AGSAndroid::GetAppOutputDirectory() +{ + return android_base_directory; +} + +AGSPlatformDriver* AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSAndroid(); + + return instance; +} + +#endif diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp new file mode 100644 index 000000000000..970611540d77 --- /dev/null +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -0,0 +1,236 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS Platform-specific functions +// +//============================================================================= + +#include +#include "util/wgt2allg.h" +#include "platform/base/agsplatformdriver.h" +#include "ac/common.h" +#include "ac/runtime_defines.h" +#include "util/string_utils.h" +#include "util/stream.h" +#include "gfx/bitmap.h" +#include "plugin/agsplugin.h" +#include "ac/timer.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +#if defined (AGS_HAS_CD_AUDIO) +#include "libcda.h" +#endif + +// We don't have many places where we delay longer than a frame, but where we +// do, we should give the audio layer a chance to update. +// 16 milliseconds is rough period for 60fps +const auto MaximumDelayBetweenPolling = std::chrono::milliseconds(16); + +AGSPlatformDriver* AGSPlatformDriver::instance = nullptr; +AGSPlatformDriver *platform = nullptr; + +// ******** DEFAULT IMPLEMENTATIONS ******* + +void AGSPlatformDriver::AboutToQuitGame() { } +void AGSPlatformDriver::PostAllegroInit(bool windowed) { } +void AGSPlatformDriver::AttachToParentConsole() { } +void AGSPlatformDriver::DisplaySwitchOut() { } +void AGSPlatformDriver::DisplaySwitchIn() { } +void AGSPlatformDriver::PauseApplication() { } +void AGSPlatformDriver::ResumeApplication() { } +void AGSPlatformDriver::GetSystemDisplayModes(std::vector &dms) { } +bool AGSPlatformDriver::EnterFullscreenMode(const DisplayMode &dm) { return true; } +bool AGSPlatformDriver::ExitFullscreenMode() { return true; } +void AGSPlatformDriver::AdjustWindowStyleForFullscreen() { } +void AGSPlatformDriver::AdjustWindowStyleForWindowed() { } +void AGSPlatformDriver::RegisterGameWithGameExplorer() { } +void AGSPlatformDriver::UnRegisterGameWithGameExplorer() { } +void AGSPlatformDriver::PlayVideo(const char* name, int skip, int flags) {} + +const char* AGSPlatformDriver::GetAllegroFailUserHint() +{ + return "Make sure you have latest version of Allegro 4 libraries installed, and your system is running in graphical mode."; +} + +const char *AGSPlatformDriver::GetDiskWriteAccessTroubleshootingText() +{ + return "Make sure you have write permissions, and also check the disk's free space."; +} + +void AGSPlatformDriver::GetSystemTime(ScriptDateTime *sdt) { + time_t t = time(nullptr); + + //note: subject to year 2038 problem due to shoving time_t in an integer + sdt->rawUnixTime = static_cast(t); + + struct tm *newtime = localtime(&t); + sdt->hour = newtime->tm_hour; + sdt->minute = newtime->tm_min; + sdt->second = newtime->tm_sec; + sdt->day = newtime->tm_mday; + sdt->month = newtime->tm_mon + 1; + sdt->year = newtime->tm_year + 1900; +} + +void AGSPlatformDriver::WriteStdOut(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + printf("\n"); + fflush(stdout); +} + +void AGSPlatformDriver::WriteStdErr(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + fflush(stdout); +} + +void AGSPlatformDriver::YieldCPU() { + // NOTE: this is called yield, but if we actually yield instead of delay, + // we get a massive increase in CPU usage. + this->Delay(1); + //std::this_thread::yield(); +} + +void AGSPlatformDriver::InitialiseAbufAtStartup() +{ + // because loading the game file accesses abuf, it must exist + // No no no, David Blain, no magic here :P + //abuf = BitmapHelper::CreateBitmap(10,10,8); +} + +void AGSPlatformDriver::FinishedUsingGraphicsMode() +{ + // don't need to do anything on any OS except DOS +} + +SetupReturnValue AGSPlatformDriver::RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out) +{ + return kSetup_Cancel; +} + +void AGSPlatformDriver::SetGameWindowIcon() { + // do nothing +} + +int AGSPlatformDriver::ConvertKeycodeToScanCode(int keycode) +{ + keycode -= ('A' - KEY_A); + return keycode; +} + +bool AGSPlatformDriver::LockMouseToWindow() { return false; } +void AGSPlatformDriver::UnlockMouse() { } + +//----------------------------------------------- +// IOutputHandler implementation +//----------------------------------------------- +void AGSPlatformDriver::PrintMessage(const Common::DebugMessage &msg) +{ + if (_logToStdErr) + { + if (msg.GroupName.IsEmpty()) + WriteStdErr("%s", msg.Text.GetCStr()); + else + WriteStdErr("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr()); + } + else + { + if (msg.GroupName.IsEmpty()) + WriteStdOut("%s", msg.Text.GetCStr()); + else + WriteStdOut("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr()); + } +} + +// ********** CD Player Functions common to Win and Linux ******** + +#if defined (AGS_HAS_CD_AUDIO) + +// from ac_cdplayer +extern int use_cdplayer; +extern int need_to_stop_cd; + +int numcddrives=0; + +int cd_player_init() { + int erro = cd_init(); + if (erro) return -1; + numcddrives=1; + use_cdplayer=1; + return 0; +} + +int cd_player_control(int cmdd, int datt) { + // WINDOWS & LINUX VERSION + if (cmdd==1) { + if (cd_current_track() > 0) return 1; + return 0; + } + else if (cmdd==2) { + cd_play_from(datt); + need_to_stop_cd=1; + } + else if (cmdd==3) + cd_pause(); + else if (cmdd==4) + cd_resume(); + else if (cmdd==5) { + int first,last; + if (cd_get_tracks(&first,&last)==0) + return (last-first)+1; + else return 0; + } + else if (cmdd==6) + cd_eject(); + else if (cmdd==7) + cd_close(); + else if (cmdd==8) + return numcddrives; + else if (cmdd==9) ; + else quit("!CDAudio: Unknown command code"); + + return 0; +} + +#endif // AGS_HAS_CD_AUDIO + +void AGSPlatformDriver::Delay(int millis) { + auto now = AGS_Clock::now(); + auto delayUntil = now + std::chrono::milliseconds(millis); + + for (;;) { + if (now >= delayUntil) { break; } + + auto duration = std::min(delayUntil - now, MaximumDelayBetweenPolling); + std::this_thread::sleep_for(duration); + now = AGS_Clock::now(); // update now + + if (now >= delayUntil) { break; } + + // don't allow it to check for debug messages, since this Delay() + // call might be from within a debugger polling loop + update_polled_mp3(); + now = AGS_Clock::now(); // update now + } +} diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h new file mode 100644 index 000000000000..208d9afca624 --- /dev/null +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -0,0 +1,170 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS Cross-Platform Header +// +//============================================================================= + +#ifndef __AGS_EE_PLATFORM__AGSPLATFORMDRIVER_H +#define __AGS_EE_PLATFORM__AGSPLATFORMDRIVER_H + +#include +#include +#include "ac/datetime.h" +#include "debug/outputhandler.h" +#include "util/ini_util.h" + +namespace AGS +{ + namespace Common { class Stream; } + namespace Engine { struct DisplayMode; } +} +using namespace AGS; // FIXME later + +enum eScriptSystemOSID +{ + eOS_DOS = 1, + eOS_Win, + eOS_Linux, + eOS_Mac, + eOS_Android, + eOS_iOS, + eOS_PSP +}; + +enum SetupReturnValue +{ + kSetup_Cancel, + kSetup_Done, + kSetup_RunGame +}; + +struct AGSPlatformDriver + // be used as a output target for logging system + : public AGS::Common::IOutputHandler +{ + virtual void AboutToQuitGame(); + virtual void Delay(int millis); + virtual void DisplayAlert(const char*, ...) = 0; + virtual void AttachToParentConsole(); + virtual int GetLastSystemError() { return errno; } + // Get root directory for storing per-game shared data + virtual const char *GetAllUsersDataDirectory() { return "."; } + // Get root directory for storing per-game saved games + virtual const char *GetUserSavedgamesDirectory() { return "."; } + // Get root directory for storing per-game user configuration files + virtual const char *GetUserConfigDirectory() { return "."; } + // Get directory for storing all-games user configuration files + virtual const char *GetUserGlobalConfigDirectory() { return "."; } + // Get default directory for program output (logs) + virtual const char *GetAppOutputDirectory() { return "."; } + // Returns array of characters illegal to use in file names + virtual const char *GetIllegalFileChars() { return "\\/"; } + virtual const char *GetDiskWriteAccessTroubleshootingText(); + virtual const char *GetGraphicsTroubleshootingText() { return ""; } + virtual unsigned long GetDiskFreeSpaceMB() = 0; + virtual const char* GetNoMouseErrorString() = 0; + // Tells whether build is capable of controlling mouse movement properly + virtual bool IsMouseControlSupported(bool windowed) { return false; } + // Tells whether this platform's backend library deals with mouse cursor + // virtual->real coordinate transformation itself (otherwise AGS engine should do it) + virtual bool IsBackendResponsibleForMouseScaling() { return false; } + virtual const char* GetAllegroFailUserHint(); + virtual eScriptSystemOSID GetSystemOSID() = 0; + virtual void GetSystemTime(ScriptDateTime*); + virtual void PlayVideo(const char* name, int skip, int flags); + virtual void InitialiseAbufAtStartup(); + virtual void PostAllegroInit(bool windowed); + virtual void PostAllegroExit() = 0; + virtual void FinishedUsingGraphicsMode(); + virtual SetupReturnValue RunSetup(const Common::ConfigTree &cfg_in, Common::ConfigTree &cfg_out); + virtual void SetGameWindowIcon(); + // Formats message and writes to standard platform's output; + // Always adds trailing '\n' after formatted string + virtual void WriteStdOut(const char *fmt, ...); + // Formats message and writes to platform's error output; + // Always adds trailing '\n' after formatted string + virtual void WriteStdErr(const char *fmt, ...); + virtual void YieldCPU(); + // Called when the game window is being switch out from + virtual void DisplaySwitchOut(); + // Called when the game window is being switch back to + virtual void DisplaySwitchIn(); + // Called when the application is being paused completely (e.g. when player alt+tabbed from it). + // This function should suspend any platform-specific realtime processing. + virtual void PauseApplication(); + // Called when the application is being resumed. + virtual void ResumeApplication(); + // Returns a list of supported display modes + virtual void GetSystemDisplayModes(std::vector &dms); + // Switch to system fullscreen mode; store previous mode parameters + virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm); + // Return back to the mode was before switching to fullscreen + virtual bool ExitFullscreenMode(); + // Adjust application window's parameters to suit fullscreen mode + virtual void AdjustWindowStyleForFullscreen(); + // Adjust application window's parameters to suit windowed mode + virtual void AdjustWindowStyleForWindowed(); + virtual void RegisterGameWithGameExplorer(); + virtual void UnRegisterGameWithGameExplorer(); + virtual int ConvertKeycodeToScanCode(int keyCode); + // Adjust window size to ensure it is in the supported limits + virtual void ValidateWindowSize(int &x, int &y, bool borderless) const {} + + virtual int InitializeCDPlayer() = 0; // return 0 on success + virtual int CDPlayerCommand(int cmdd, int datt) = 0; + virtual void ShutdownCDPlayer() = 0; + + virtual bool LockMouseToWindow(); + virtual void UnlockMouse(); + + static AGSPlatformDriver *GetDriver(); + + // Set whether PrintMessage should output to stdout or stderr + void SetOutputToErr(bool on) { _logToStdErr = on; } + // Set whether DisplayAlert is allowed to show modal GUIs on some systems; + // it will print to either stdout or stderr otherwise, depending on above flag + void SetGUIMode(bool on) { _guiMode = on; } + + //----------------------------------------------- + // IOutputHandler implementation + //----------------------------------------------- + // Writes to the standard platform's output, prepending "AGS: " prefix to the message + void PrintMessage(const AGS::Common::DebugMessage &msg) override; + +protected: + // TODO: this is a quick solution for IOutputHandler implementation + // logging either to stdout or stderr. Normally there should be + // separate implementation, one for each kind of output, but + // with both going through PlatformDriver need to figure a better + // design first. + bool _logToStdErr = false; + // Defines whether engine is allowed to display important warnings + // and errors by showing a message box kind of GUI. + bool _guiMode = false; + +private: + static AGSPlatformDriver *instance; +}; + +#if defined (AGS_HAS_CD_AUDIO) +int cd_player_init(); +int cd_player_control(int cmdd, int datt); +#endif + +// [IKM] What is a need to have this global var if you can get AGSPlatformDriver +// instance by calling AGSPlatformDriver::GetDriver()? +extern AGSPlatformDriver *platform; + +#endif // __AGS_EE_PLATFORM__AGSPLATFORMDRIVER_H diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp new file mode 100644 index 000000000000..96bbe432509d --- /dev/null +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -0,0 +1,644 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_IOS + +#include +#include +#include +#include + +#include +#include "platform/base/agsplatformdriver.h" +#include "ac/runtime_defines.h" +#include "main/config.h" +#include "plugin/agsplugin.h" +#include "util/string_utils.h" + +using namespace AGS::Common; + +#define IOS_CONFIG_FILENAME "ios.cfg" + +extern char* ios_document_directory; + +bool ReadConfiguration(char* filename, bool read_everything); +void ResetConfiguration(); + +//int psp_return_to_menu = 1; +int psp_ignore_acsetup_cfg_file = 1; +int psp_clear_cache_on_room_change = 0; +int psp_rotation = 0; +int psp_config_enabled = 0; +char psp_translation[100]; +char* psp_translations[100]; + +// Mouse option from Allegro. +extern int config_mouse_control_mode; + + +// Graphic options from the Allegro library. +extern int psp_gfx_scaling; +extern int psp_gfx_smoothing; + + +// Audio options from the Allegro library. +unsigned int psp_audio_samplerate = 44100; +int psp_audio_enabled = 1; +volatile int psp_audio_multithreaded = 1; +int psp_audio_cachesize = 10; +int psp_midi_enabled = 1; +int psp_midi_preload_patches = 0; + +int psp_video_framedrop = 0; + +int psp_gfx_renderer = 0; +int psp_gfx_super_sampling = 0; +int psp_gfx_smooth_sprites = 0; + +int psp_debug_write_to_logcat = 0; + +int config_mouse_longclick = 0; + +extern int display_fps; +extern int want_exit; +extern void PauseGame(); +extern void UnPauseGame(); +extern int main(int argc,char*argv[]); + +char psp_game_file_name[256]; +char* psp_game_file_name_pointer = psp_game_file_name; + +bool psp_load_latest_savegame = false; +extern char saveGameDirectory[260]; +extern const char *loadSaveGameOnStartup; +char lastSaveGameName[200]; + +bool reset_configuration = false; + +const int CONFIG_IGNORE_ACSETUP = 0; +const int CONFIG_CLEAR_CACHE = 1; +const int CONFIG_AUDIO_RATE = 2; +const int CONFIG_AUDIO_ENABLED = 3; +const int CONFIG_AUDIO_THREADED = 4; +const int CONFIG_AUDIO_CACHESIZE = 5; +const int CONFIG_MIDI_ENABLED = 6; +const int CONFIG_MIDI_PRELOAD = 7; +const int CONFIG_VIDEO_FRAMEDROP = 8; +const int CONFIG_GFX_RENDERER = 9; +const int CONFIG_GFX_SMOOTHING = 10; +const int CONFIG_GFX_SCALING = 11; +const int CONFIG_GFX_SS = 12; +const int CONFIG_ROTATION = 13; +const int CONFIG_ENABLED = 14; +const int CONFIG_DEBUG_FPS = 15; +const int CONFIG_GFX_SMOOTH_SPRITES = 16; +const int CONFIG_TRANSLATION = 17; +const int CONFIG_DEBUG_LOGCAT = 18; +const int CONFIG_MOUSE_METHOD = 19; +const int CONFIG_MOUSE_LONGCLICK = 20; + + + +struct AGSIOS : AGSPlatformDriver { + + virtual int CDPlayerCommand(int cmdd, int datt); + virtual void Delay(int millis); + virtual void DisplayAlert(const char*, ...); + virtual const char *GetAppOutputDirectory(); + virtual unsigned long GetDiskFreeSpaceMB(); + virtual const char* GetNoMouseErrorString(); + virtual bool IsBackendResponsibleForMouseScaling() { return true; } + virtual eScriptSystemOSID GetSystemOSID(); + virtual int InitializeCDPlayer(); + virtual void PostAllegroExit(); + virtual void SetGameWindowIcon(); + virtual void ShutdownCDPlayer(); +}; + + + +bool readConfigFile(char* directory) +{ + chdir(directory); + + ResetConfiguration(); + + return ReadConfiguration(IOS_CONFIG_FILENAME, true); +} + + +bool writeConfigFile() +{ + FILE* config = fopen(IOS_CONFIG_FILENAME, "wb"); + if (config) + { + fprintf(config, "[misc]\n"); + fprintf(config, "config_enabled = %d\n", psp_config_enabled); + fprintf(config, "rotation = %d\n", psp_rotation); + fprintf(config, "translation = %s\n", psp_translation); + + fprintf(config, "[controls]\n"); + fprintf(config, "mouse_method = %d\n", config_mouse_control_mode); + fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick); + + fprintf(config, "[compatibility]\n"); + fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change); + + fprintf(config, "[sound]\n"); + fprintf(config, "samplerate = %d\n", psp_audio_samplerate ); + fprintf(config, "enabled = %d\n", psp_audio_enabled); + fprintf(config, "threaded = %d\n", psp_audio_multithreaded); + fprintf(config, "cache_size = %d\n", psp_audio_cachesize); + + fprintf(config, "[midi]\n"); + fprintf(config, "enabled = %d\n", psp_midi_enabled); + fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches); + + fprintf(config, "[video]\n"); + fprintf(config, "framedrop = %d\n", psp_video_framedrop); + + fprintf(config, "[graphics]\n"); + fprintf(config, "renderer = %d\n", psp_gfx_renderer); + fprintf(config, "smoothing = %d\n", psp_gfx_smoothing); + fprintf(config, "scaling = %d\n", psp_gfx_scaling); + fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling); + fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites); + + fprintf(config, "[debug]\n"); + fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0); + fprintf(config, "logging = %d\n", psp_debug_write_to_logcat); + + fclose(config); + + return true; + } + + return false; +} + + +int readIntConfigValue(int id) +{ + switch (id) + { + case CONFIG_IGNORE_ACSETUP: + return psp_ignore_acsetup_cfg_file; + break; + case CONFIG_CLEAR_CACHE: + return psp_clear_cache_on_room_change; + break; + case CONFIG_AUDIO_RATE: + return psp_audio_samplerate; + break; + case CONFIG_AUDIO_ENABLED: + return psp_audio_enabled; + break; + case CONFIG_AUDIO_THREADED: + return psp_audio_multithreaded; + break; + case CONFIG_AUDIO_CACHESIZE: + return psp_audio_cachesize; + break; + case CONFIG_MIDI_ENABLED: + return psp_midi_enabled; + break; + case CONFIG_MIDI_PRELOAD: + return psp_midi_preload_patches; + break; + case CONFIG_VIDEO_FRAMEDROP: + return psp_video_framedrop; + break; + case CONFIG_GFX_RENDERER: + return psp_gfx_renderer; + break; + case CONFIG_GFX_SMOOTHING: + return psp_gfx_smoothing; + break; + case CONFIG_GFX_SCALING: + return psp_gfx_scaling; + break; + case CONFIG_GFX_SS: + return psp_gfx_super_sampling; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + return psp_gfx_smooth_sprites; + break; + case CONFIG_ROTATION: + return psp_rotation; + break; + case CONFIG_ENABLED: + return psp_config_enabled; + break; + case CONFIG_DEBUG_FPS: + return (display_fps == 2) ? 1 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + return psp_debug_write_to_logcat; + break; + case CONFIG_MOUSE_METHOD: + return config_mouse_control_mode; + break; + case CONFIG_MOUSE_LONGCLICK: + return config_mouse_longclick; + break; + default: + return 0; + break; + } +} + + +char* readStringConfigValue(int id) +{ + switch (id) + { + case CONFIG_TRANSLATION: + return &psp_translation[0]; + break; + } +} + + +void setIntConfigValue(int id, int value) +{ + switch (id) + { + case CONFIG_IGNORE_ACSETUP: + psp_ignore_acsetup_cfg_file = value; + break; + case CONFIG_CLEAR_CACHE: + psp_clear_cache_on_room_change = value; + break; + case CONFIG_AUDIO_RATE: + psp_audio_samplerate = value; + break; + case CONFIG_AUDIO_ENABLED: + psp_audio_enabled = value; + break; + case CONFIG_AUDIO_THREADED: + psp_audio_multithreaded = value; + break; + case CONFIG_AUDIO_CACHESIZE: + psp_audio_cachesize = value; + break; + case CONFIG_MIDI_ENABLED: + psp_midi_enabled = value; + break; + case CONFIG_MIDI_PRELOAD: + psp_midi_preload_patches = value; + break; + case CONFIG_VIDEO_FRAMEDROP: + psp_video_framedrop = value; + break; + case CONFIG_GFX_RENDERER: + psp_gfx_renderer = value; + break; + case CONFIG_GFX_SMOOTHING: + psp_gfx_smoothing = value; + break; + case CONFIG_GFX_SCALING: + psp_gfx_scaling = value; + break; + case CONFIG_GFX_SS: + psp_gfx_super_sampling = value; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + psp_gfx_smooth_sprites = value; + break; + case CONFIG_ROTATION: + psp_rotation = value; + break; + case CONFIG_ENABLED: + psp_config_enabled = value; + break; + case CONFIG_DEBUG_FPS: + display_fps = (value == 1) ? 2 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + psp_debug_write_to_logcat = value; + break; + case CONFIG_MOUSE_METHOD: + config_mouse_control_mode = value; + break; + case CONFIG_MOUSE_LONGCLICK: + config_mouse_longclick = value; + break; + default: + break; + } +} + + +void setStringConfigValue(int id, char* value) +{ + switch (id) + { + case CONFIG_TRANSLATION: + strcpy(psp_translation, value); + break; + default: + break; + } +} + +/* +int getAvailableTranslations(char* translations) +{ + int i = 0; + int length; + DIR* dir; + struct dirent* entry; + char buffer[200]; + + dir = opendir("."); + if (dir) + { + while ((entry = readdir(dir)) != 0) + { + length = strlen(entry->d_name); + if (length > 4) + { + if (ags_stricmp(&entry->d_name[length - 4], ".tra") == 0) + { + memset(buffer, 0, 200); + strncpy(buffer, entry->d_name, length - 4); + psp_translations[i] = (char*)malloc(strlen(buffer) + 1); + strcpy(psp_translations[i], buffer); + env->SetObjectArrayElement(translations, i, env->NewStringUTF(&buffer[0])); + i++; + } + } + } + closedir(dir); + } + + return i; +} +*/ + + + + +void selectLatestSavegame() +{ + DIR* dir; + struct dirent* entry; + struct stat statBuffer; + char buffer[200]; + time_t lastTime = 0; + + dir = opendir(saveGameDirectory); + + if (dir) + { + while ((entry = readdir(dir)) != 0) + { + if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) + { + if (ags_stricmp(entry->d_name, "agssave.999") != 0) + { + strcpy(buffer, saveGameDirectory); + strcat(buffer, entry->d_name); + stat(buffer, &statBuffer); + if (statBuffer.st_mtime > lastTime) + { + strcpy(lastSaveGameName, buffer); + loadSaveGameOnStartup = lastSaveGameName; + lastTime = statBuffer.st_mtime; + } + } + } + } + closedir(dir); + } +} + + +int ReadInteger(int* variable, const ConfigTree &cfg, char* section, char* name, int minimum, int maximum, int default_value) +{ + if (reset_configuration) + { + *variable = default_value; + return 0; + } + + int temp = INIreadint(cfg, section, name); + + if (temp == -1) + return 0; + + if ((temp < minimum) || (temp > maximum)) + temp = default_value; + + *variable = temp; + + return 1; +} + + + +int ReadString(char* variable, const ConfigTree &cfg, char* section, char* name, char* default_value) +{ + if (reset_configuration) + { + strcpy(variable, default_value); + return 0; + } + + String temp; + if (!INIreaditem(cfg, section, name, temp)) + temp = default_value; + + strcpy(variable, temp); + + return 1; +} + + + +void ResetConfiguration() +{ + reset_configuration = true; + + ReadConfiguration(IOS_CONFIG_FILENAME, true); + + reset_configuration = false; +} + + +bool ReadConfiguration(char* filename, bool read_everything) +{ + ConfigTree cfg; + if (IniUtil::Read(filename, cfg) || reset_configuration) + { +// ReadInteger((int*)&psp_disable_powersaving, "misc", "disable_power_saving", 0, 1, 1); + +// ReadInteger((int*)&psp_return_to_menu, "misc", "return_to_menu", 0, 1, 1); + + ReadString(&psp_translation[0], cfg, "misc", "translation", "default"); + + ReadInteger((int*)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0); + if (!psp_config_enabled && !read_everything) + return true; + + ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0); + ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0); + if (display_fps == 1) + display_fps = 2; + + ReadInteger((int*)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0); + +// ReadInteger((int*)&psp_ignore_acsetup_cfg_file, "compatibility", "ignore_acsetup_cfg_file", 0, 1, 0); + ReadInteger((int*)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0); + + ReadInteger((int*)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100); + ReadInteger((int*)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1); + ReadInteger((int*)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1); + ReadInteger((int*)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10); + + ReadInteger((int*)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1); + ReadInteger((int*)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0); + + ReadInteger((int*)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0); + + ReadInteger((int*)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0); + ReadInteger((int*)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1); + ReadInteger((int*)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1); + ReadInteger((int*)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0); + ReadInteger((int*)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0); + + ReadInteger((int*)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0); + ReadInteger((int*)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1); + + return true; + } + + return false; +} + + + +extern void ios_show_message_box(char* buffer); +volatile int ios_wait_for_ui = 0; + + +void startEngine(char* filename, char* directory, int loadLastSave) +{ + strcpy(psp_game_file_name, filename); + + // Get the base directory (usually "/sdcard/ags"). + chdir(directory); + + // Reset configuration. + ResetConfiguration(); + + // Read general configuration. + ReadConfiguration(IOS_CONFIG_FILENAME, true); + + // Get the games path. + char path[256]; + strcpy(path, psp_game_file_name); + int lastindex = strlen(path) - 1; + while (path[lastindex] != '/') + { + path[lastindex] = 0; + lastindex--; + } + chdir(path); + + setenv("ULTRADIR", "..", 1); + + // Read game specific configuration. + ReadConfiguration(IOS_CONFIG_FILENAME, false); + + psp_load_latest_savegame = loadLastSave; + + // Start the engine main function. + main(1, &psp_game_file_name_pointer); + + // Explicitly quit here, otherwise the app will hang forever. + exit(0); +} + + + + +int AGSIOS::CDPlayerCommand(int cmdd, int datt) { + return 0;//cd_player_control(cmdd, datt); +} + + + +void AGSIOS::DisplayAlert(const char *text, ...) { + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + printf("%s", displbuf); + ios_show_message_box(displbuf); + + while (ios_wait_for_ui) + usleep(200); +} + +void AGSIOS::Delay(int millis) { + usleep(millis); +} + +unsigned long AGSIOS::GetDiskFreeSpaceMB() { + // placeholder + return 100; +} + +const char* AGSIOS::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +} + +eScriptSystemOSID AGSIOS::GetSystemOSID() { + return eOS_iOS; +} + +int AGSIOS::InitializeCDPlayer() { + return 0;//cd_player_init(); +} + +void AGSIOS::PostAllegroExit() { + // do nothing +} + +void AGSIOS::SetGameWindowIcon() { + // do nothing +} + + + +void AGSIOS::ShutdownCDPlayer() { + //cd_exit(); +} + +const char *AGSIOS::GetAppOutputDirectory() +{ + return ios_document_directory; +} + +AGSPlatformDriver* AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSIOS(); + return instance; +} + +#endif diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp new file mode 100644 index 000000000000..07297a9fdfff --- /dev/null +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -0,0 +1,211 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_LINUX + +// ********* LINUX PLACEHOLDER DRIVER ********* + +#include +#include +#include +#include "ac/runtime_defines.h" +#include "gfx/gfxdefines.h" +#include "platform/base/agsplatformdriver.h" +#include "plugin/agsplugin.h" +#include "util/string.h" +#include + +#include +#include + +using AGS::Common::String; + + +// Replace the default Allegro icon. The original defintion is in the +// Allegro 4.4 source under "src/x/xwin.c". +#include "icon.xpm" +void* allegro_icon = icon_xpm; +String CommonDataDirectory; +String UserDataDirectory; + +struct AGSLinux : AGSPlatformDriver { + + int CDPlayerCommand(int cmdd, int datt) override; + void DisplayAlert(const char*, ...) override; + const char *GetAllUsersDataDirectory() override; + const char *GetUserSavedgamesDirectory() override; + const char *GetUserConfigDirectory() override; + const char *GetUserGlobalConfigDirectory() override; + const char *GetAppOutputDirectory() override; + unsigned long GetDiskFreeSpaceMB() override; + const char* GetNoMouseErrorString() override; + const char* GetAllegroFailUserHint() override; + eScriptSystemOSID GetSystemOSID() override; + int InitializeCDPlayer() override; + void PostAllegroExit() override; + void SetGameWindowIcon() override; + void ShutdownCDPlayer() override; + bool LockMouseToWindow() override; + void UnlockMouse() override; + void GetSystemDisplayModes(std::vector &dms) override; +}; + + +int AGSLinux::CDPlayerCommand(int cmdd, int datt) { + return cd_player_control(cmdd, datt); +} + +void AGSLinux::DisplayAlert(const char *text, ...) { + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + if (_logToStdErr) + fprintf(stderr, "%s\n", displbuf); + else + fprintf(stdout, "%s\n", displbuf); +} + +size_t BuildXDGPath(char *destPath, size_t destSize) +{ + // Check to see if XDG_DATA_HOME is set in the enviroment + const char* home_dir = getenv("XDG_DATA_HOME"); + size_t l = 0; + if (home_dir) + { + l = snprintf(destPath, destSize, "%s", home_dir); + } + else + { + // No evironment variable, so we fall back to home dir in /etc/passwd + struct passwd *p = getpwuid(getuid()); + l = snprintf(destPath, destSize, "%s/.local", p->pw_dir); + if (mkdir(destPath, 0755) != 0 && errno != EEXIST) + return 0; + l += snprintf(destPath + l, destSize - l, "/share"); + if (mkdir(destPath, 0755) != 0 && errno != EEXIST) + return 0; + } + return l; +} + +void DetermineDataDirectories() +{ + if (!UserDataDirectory.IsEmpty()) + return; + char xdg_path[256]; + if (BuildXDGPath(xdg_path, sizeof(xdg_path)) == 0) + sprintf(xdg_path, "%s", "/tmp"); + UserDataDirectory.Format("%s/ags", xdg_path); + mkdir(UserDataDirectory.GetCStr(), 0755); + CommonDataDirectory.Format("%s/ags-common", xdg_path); + mkdir(CommonDataDirectory.GetCStr(), 0755); +} + +const char *AGSLinux::GetAllUsersDataDirectory() +{ + DetermineDataDirectories(); + return CommonDataDirectory; +} + +const char *AGSLinux::GetUserSavedgamesDirectory() +{ + DetermineDataDirectories(); + return UserDataDirectory; +} + +const char *AGSLinux::GetUserConfigDirectory() +{ + return GetUserSavedgamesDirectory(); +} + +const char *AGSLinux::GetUserGlobalConfigDirectory() +{ + return GetUserSavedgamesDirectory(); +} + +const char *AGSLinux::GetAppOutputDirectory() +{ + DetermineDataDirectories(); + return UserDataDirectory; +} + +unsigned long AGSLinux::GetDiskFreeSpaceMB() { + // placeholder + return 100; +} + +const char* AGSLinux::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +} + +const char* AGSLinux::GetAllegroFailUserHint() +{ + return "Make sure you have latest version of Allegro 4 libraries installed, and X server is running."; +} + +eScriptSystemOSID AGSLinux::GetSystemOSID() { + return eOS_Linux; +} + +int AGSLinux::InitializeCDPlayer() { + return cd_player_init(); +} + +void AGSLinux::PostAllegroExit() { + // do nothing +} + +void AGSLinux::SetGameWindowIcon() { + // do nothing +} + +void AGSLinux::ShutdownCDPlayer() { + cd_exit(); +} + +AGSPlatformDriver* AGSPlatformDriver::GetDriver() { + if (instance == nullptr) + instance = new AGSLinux(); + return instance; +} + +bool AGSLinux::LockMouseToWindow() +{ + return XGrabPointer(_xwin.display, _xwin.window, False, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, _xwin.window, None, CurrentTime) == GrabSuccess; +} + +void AGSLinux::UnlockMouse() +{ + XUngrabPointer(_xwin.display, CurrentTime); +} + +void AGSLinux::GetSystemDisplayModes(std::vector &dms) +{ + dms.clear(); + GFX_MODE_LIST *gmlist = get_gfx_mode_list(GFX_XWINDOWS_FULLSCREEN); + for (int i = 0; i < gmlist->num_modes; ++i) + { + const GFX_MODE &m = gmlist->mode[i]; + dms.push_back(Engine::DisplayMode(Engine::GraphicResolution(m.width, m.height, m.bpp))); + } + destroy_gfx_mode_list(gmlist); +} + +#endif diff --git a/engines/ags/engine/platform/linux/icon.xpm b/engines/ags/engine/platform/linux/icon.xpm new file mode 100644 index 000000000000..61854643f83f --- /dev/null +++ b/engines/ags/engine/platform/linux/icon.xpm @@ -0,0 +1,1103 @@ +/* XPM */ +static const char * icon_xpm[] = { +"48 48 1052 2", +" c None", +". c #5258BE", +"+ c #4449B4", +"@ c #2E33AA", +"# c #2226A6", +"$ c #2527A8", +"% c #282CAA", +"& c #3539AF", +"* c #464CB5", +"= c #4C51B6", +"- c #4D53BE", +"; c #2B2EA8", +"> c #090B8C", +", c #010180", +"' c #000079", +") c #00007B", +"! c #010187", +"~ c #060894", +"{ c #1B1FA7", +"] c #3138B2", +"^ c #2D33B0", +"/ c #262CAE", +"( c #3036B0", +"_ c #2E33B0", +": c #282EAC", +"< c #2F34AD", +"[ c #4C51BC", +"} c #121398", +"| c #00007D", +"1 c #000072", +"2 c #04046C", +"3 c #06066C", +"4 c #0A0A74", +"5 c #0C0C81", +"6 c #0C0D8D", +"7 c #0E1199", +"8 c #292EAC", +"9 c #474EB8", +"0 c #474EB9", +"a c #444BB9", +"b c #5861C2", +"c c #666FCA", +"d c #6770CC", +"e c #555FC4", +"f c #292EB1", +"g c #1F20A6", +"h c #585DBB", +"i c #1E20A6", +"j c #000081", +"k c #060473", +"l c #070674", +"m c #090977", +"n c #090975", +"o c #090974", +"p c #0A0A79", +"q c #0C0C83", +"r c #0F1198", +"s c #2C31AA", +"t c #4B51B6", +"u c #474EB6", +"v c #3F44B5", +"w c #5058BC", +"x c #636BC4", +"y c #6C75CB", +"z c #717AD1", +"A c #5C66CD", +"B c #2B30BA", +"C c #0C0EA2", +"D c #2023A8", +"E c #070A9B", +"F c #010179", +"G c #0C0A75", +"H c #0A0A7D", +"I c #09097A", +"J c #090978", +"K c #090976", +"L c #0C0C86", +"M c #0C0C8D", +"N c #0F1196", +"O c #2B2FA7", +"P c #4A51B3", +"Q c #484FB4", +"R c #3B41B2", +"S c #4A52BA", +"T c #6069C2", +"U c #6A73CA", +"V c #6F78CF", +"W c #5E66CC", +"X c #3A40C1", +"Y c #2A2DB3", +"Z c #11139C", +"` c #1F22A6", +" . c #2C2FB2", +".. c #00007C", +"+. c #09096F", +"@. c #0B0C7E", +"#. c #0A0A7E", +"$. c #09097C", +"%. c #08086F", +"&. c #080870", +"*. c #0B0B77", +"=. c #0C0C7D", +"-. c #0C0D84", +";. c #1C1F92", +">. c #31369E", +",. c #3338A3", +"'. c #282CA5", +"). c #363BAC", +"!. c #4E55B8", +"~. c #5E67C2", +"{. c #6A73CC", +"]. c #5D65CD", +"^. c #3C42C1", +"/. c #2B31B7", +"(. c #2A2FA1", +"_. c #090A94", +":. c #4247B3", +"<. c #0D0F9B", +"[. c #04056D", +"}. c #0C0C82", +"|. c #0A0A80", +"1. c #080874", +"2. c #07076A", +"3. c #070765", +"4. c #060663", +"5. c #060665", +"6. c #0B0B6C", +"7. c #0C0C74", +"8. c #0C0E7B", +"9. c #131585", +"0. c #1D1F91", +"a. c #1F2295", +"b. c #1B1D99", +"c. c #22249E", +"d. c #3134A7", +"e. c #3F45B0", +"f. c #4E55BA", +"g. c #5056C3", +"h. c #3A40C2", +"i. c #2B30B9", +"j. c #2A30A5", +"k. c #12158D", +"l. c #1E21A5", +"m. c #101299", +"n. c #06066F", +"o. c #09097D", +"p. c #060664", +"q. c #05055E", +"r. c #060662", +"s. c #060661", +"t. c #0A0A69", +"u. c #0C0C6F", +"v. c #0C0E76", +"w. c #101280", +"x. c #14168A", +"y. c #181990", +"z. c #151695", +"A. c #1A1A9B", +"B. c #2527A1", +"C. c #2E33A9", +"D. c #363BAE", +"E. c #353BB2", +"F. c #2C31B4", +"G. c #272BB6", +"H. c #272AA6", +"I. c #14178C", +"J. c #1B1DA3", +"K. c #1B1EAB", +"L. c #05057C", +"M. c #050560", +"N. c #050552", +"O. c #050556", +"P. c #06065C", +"Q. c #06065E", +"R. c #06065F", +"S. c #080862", +"T. c #090967", +"U. c #0B0D6E", +"V. c #0D0F77", +"W. c #101281", +"X. c #111388", +"Y. c #0F118E", +"Z. c #131495", +"`. c #1A1C9C", +" + c #2325A3", +".+ c #292DAA", +"++ c #2A2DAD", +"@+ c #2225AC", +"#+ c #1D20AA", +"$+ c #20229F", +"%+ c #131597", +"&+ c #1B1CAE", +"*+ c #3F46C0", +"=+ c #131598", +"-+ c #00003C", +";+ c #03033F", +">+ c #050550", +",+ c #050554", +"'+ c #050558", +")+ c #05055B", +"!+ c #05055A", +"~+ c #05055C", +"{+ c #080860", +"]+ c #080863", +"^+ c #0A0967", +"/+ c #0C0E6F", +"(+ c #0F1178", +"_+ c #0E107F", +":+ c #0D0F85", +"<+ c #0E108D", +"[+ c #141694", +"}+ c #1A1C9B", +"|+ c #2022A2", +"1+ c #2024A6", +"2+ c #1E21A6", +"3+ c #181BA0", +"4+ c #181A98", +"5+ c #0E10A6", +"6+ c #1B1DB5", +"7+ c #525CB3", +"8+ c #6069D4", +"9+ c #14168E", +"0+ c #000036", +"a+ c #00002F", +"b+ c #040442", +"c+ c #05054D", +"d+ c #060657", +"e+ c #070759", +"f+ c #07075C", +"g+ c #08085F", +"h+ c #0A0A66", +"i+ c #0C0D6D", +"j+ c #0C0F74", +"k+ c #0C0F7A", +"l+ c #0E1081", +"m+ c #13158E", +"n+ c #181B95", +"o+ c #1B1C97", +"p+ c #1B1C96", +"q+ c #171899", +"r+ c #1719A8", +"s+ c #0B0CAE", +"t+ c #1A1AB8", +"u+ c #2C329B", +"v+ c #7A86CB", +"w+ c #7985E4", +"x+ c #262BB0", +"y+ c #000059", +"z+ c #01002A", +"A+ c #020236", +"B+ c #040441", +"C+ c #05054A", +"D+ c #05054C", +"E+ c #05054E", +"F+ c #060651", +"G+ c #080856", +"H+ c #09085B", +"I+ c #0A0A5F", +"J+ c #010565", +"K+ c #03076C", +"L+ c #0C0F6B", +"M+ c #0F126C", +"N+ c #121374", +"O+ c #141685", +"P+ c #17199B", +"Q+ c #1719AC", +"R+ c #1314AE", +"S+ c #0607A9", +"T+ c #1E1FB2", +"U+ c #34356C", +"V+ c #0D0D68", +"W+ c #0E1180", +"X+ c #262798", +"Y+ c #262A98", +"Z+ c #4249AF", +"`+ c #7D88CF", +" @ c #919DE8", +".@ c #5C64DB", +"+@ c #2326A8", +"@@ c #070775", +"#@ c #00004C", +"$@ c #000034", +"%@ c #00002B", +"&@ c #000028", +"*@ c #010029", +"=@ c #01002C", +"-@ c #030230", +";@ c #020334", +">@ c #010239", +",@ c #2C183D", +"'@ c #251642", +")@ c #02075B", +"!@ c #0F1276", +"~@ c #151793", +"{@ c #1518AC", +"]@ c #1314B2", +"^@ c #1011A4", +"/@ c #0D0D9C", +"(@ c #0D0DA8", +"_@ c #0D0EA2", +":@ c #070954", +"<@ c #000054", +"[@ c #171A81", +"}@ c #3941AA", +"|@ c #3942B7", +"1@ c #232BA8", +"2@ c #575CAF", +"3@ c #2E319C", +"4@ c #3B41AC", +"5@ c #5259BC", +"6@ c #7580CE", +"7@ c #9AA9E3", +"8@ c #95A3EB", +"9@ c #6973DF", +"0@ c #3A40C7", +"a@ c #2125AD", +"b@ c #161797", +"c@ c #0F1188", +"d@ c #0B0D7A", +"e@ c #0A0B71", +"f@ c #0A0B70", +"g@ c #0A0B75", +"h@ c #0B0D82", +"i@ c #3B2A90", +"j@ c #744763", +"k@ c #322684", +"l@ c #131BC1", +"m@ c #1618B6", +"n@ c #0F10A4", +"o@ c #0C0B93", +"p@ c #0D0D94", +"q@ c #0D0DAA", +"r@ c #0D0DA0", +"s@ c #090B5C", +"t@ c #171A7F", +"u@ c #3F47B7", +"v@ c #383FC1", +"w@ c #2A2FBA", +"x@ c #3037BC", +"y@ c #1F24A6", +"z@ c #6569B4", +"A@ c #2A2E99", +"B@ c #3940AA", +"C@ c #575FBE", +"D@ c #6D76CC", +"E@ c #828DD8", +"F@ c #919FE1", +"G@ c #95A3E3", +"H@ c #8995E1", +"I@ c #7984DC", +"J@ c #6C76D9", +"K@ c #5B64D3", +"L@ c #4F57CF", +"M@ c #464CCD", +"N@ c #3F45C7", +"O@ c #3C42C3", +"P@ c #3D42C1", +"Q@ c #2F3ECA", +"R@ c #51489D", +"S@ c #58426E", +"T@ c #1C239E", +"U@ c #12148D", +"V@ c #090981", +"W@ c #0A0A88", +"X@ c #0D0D95", +"Y@ c #0D0EAB", +"Z@ c #0E109E", +"`@ c #10126B", +" # c #20239F", +".# c #2D31BC", +"+# c #2529B9", +"@# c #2528BA", +"## c #1F23B1", +"$# c #24269F", +"%# c #242896", +"&# c #383EA9", +"*# c #565DBC", +"=# c #717BCF", +"-# c #8E9BDC", +";# c #97A5E1", +"># c #8895DE", +",# c #727CD8", +"'# c #646CD3", +")# c #626BCF", +"!# c #636DCA", +"~# c #626BC3", +"{# c #5E66BA", +"]# c #5960B5", +"^# c #525AB0", +"/# c #4E54AB", +"(# c #3F4AAA", +"_# c #4D4889", +":# c #4E3961", +"<# c #141A81", +"[# c #0C117D", +"}# c #0B0C78", +"|# c #0D0D96", +"1# c #0E109C", +"2# c #14167C", +"3# c #2125AF", +"4# c #2226B9", +"5# c #1D21B5", +"6# c #252AB9", +"7# c #2B2FBF", +"8# c #262BBA", +"9# c #0A0D9D", +"0# c #252994", +"a# c #333AA6", +"b# c #545BBC", +"c# c #747ECF", +"d# c #96A3DF", +"e# c #A3B2E6", +"f# c #96A4E2", +"g# c #7984DA", +"h# c #6068D2", +"i# c #535BCA", +"j# c #4E55C2", +"k# c #484FB9", +"l# c #454CB1", +"m# c #4147AB", +"n# c #3D44A7", +"o# c #343CA0", +"p# c #20289D", +"q# c #372E7E", +"r# c #422C57", +"s# c #080B76", +"t# c #090972", +"u# c #09097B", +"v# c #0F10AC", +"w# c #0F119E", +"x# c #161986", +"y# c #4145AC", +"z# c #1D1D75", +"A# c #181B87", +"B# c #2C32B8", +"C# c #1316AC", +"D# c #4244A5", +"E# c #2E3198", +"F# c #2E34A4", +"G# c #7580CF", +"H# c #9AA7E0", +"I# c #ACB8E8", +"J# c #9DAAE3", +"K# c #7D87DA", +"L# c #636AD2", +"M# c #545CCA", +"N# c #4A51C0", +"O# c #4046B6", +"P# c #333AAC", +"Q# c #2A30A4", +"R# c #22269E", +"S# c #1A1D97", +"T# c #090E95", +"U# c #291E76", +"V# c #3F2851", +"W# c #040770", +"X# c #060871", +"Y# c #090971", +"Z# c #090985", +"`# c #0C0C91", +" $ c #1010AC", +".$ c #0F119C", +"+$ c #171A88", +"@$ c #1417A6", +"#$ c #292FB7", +"$$ c #323381", +"%$ c #090B7F", +"&$ c #2027B6", +"*$ c #2A2CA1", +"=$ c #3C409F", +"-$ c #272CA1", +";$ c #7681D1", +">$ c #9EAAE0", +",$ c #B1BDE9", +"'$ c #A2AFE5", +")$ c #808CDB", +"!$ c #646DD2", +"~$ c #535AC9", +"{$ c #474EBF", +"]$ c #383FB4", +"^$ c #282DA8", +"/$ c #1A1C9E", +"($ c #131399", +"_$ c #0F1092", +":$ c #020790", +"<$ c #271871", +"[$ c #3E254C", +"}$ c #03066B", +"|$ c #05076C", +"1$ c #09096D", +"2$ c #0C0C90", +"3$ c #1213AF", +"4$ c #0E0E98", +"5$ c #0A0E81", +"6$ c #2224AA", +"7$ c #4D5098", +"8$ c #07088C", +"9$ c #3236AD", +"0$ c #3940BC", +"a$ c #1B1E9F", +"b$ c #34389B", +"c$ c #292FA2", +"d$ c #545ABC", +"e$ c #7782D0", +"f$ c #A0ACE2", +"g$ c #B5C0EA", +"h$ c #A6B2E6", +"i$ c #838FDC", +"j$ c #666FD1", +"k$ c #454CBF", +"l$ c #353BB3", +"m$ c #2325A7", +"n$ c #16179D", +"o$ c #101297", +"p$ c #0C0F90", +"q$ c #00018D", +"r$ c #20126F", +"s$ c #372048", +"t$ c #000067", +"u$ c #020468", +"v$ c #070769", +"w$ c #09097F", +"x$ c #0C0B8E", +"y$ c #1112AE", +"z$ c #13149B", +"A$ c #181B7F", +"B$ c #434588", +"C$ c #3D3F8E", +"D$ c #101197", +"E$ c #3035B2", +"F$ c #4D54C3", +"G$ c #1D20A1", +"H$ c #36399B", +"I$ c #2A30A2", +"J$ c #535BBC", +"K$ c #7783D0", +"L$ c #A1ADE1", +"M$ c #B8C1EB", +"N$ c #A9B5E7", +"O$ c #8592DD", +"P$ c #6770D2", +"Q$ c #343BB3", +"R$ c #15189D", +"S$ c #0E1296", +"T$ c #06078E", +"U$ c #00038A", +"V$ c #6C5D7D", +"W$ c #967A53", +"X$ c #333068", +"Y$ c #000065", +"Z$ c #020366", +"`$ c #09097E", +" % c #0B0B8D", +".% c #1011B3", +"+% c #282988", +"@% c #3C3D8F", +"#% c #13149E", +"$% c #2F35B7", +"%% c #5861C8", +"&% c #2427A4", +"*% c #474AA4", +"=% c #262BA1", +"-% c #535ABC", +";% c #A1AEE1", +">% c #B9C0EB", +",% c #ABB7E7", +"'% c #8794DD", +")% c #6972D2", +"!% c #555CC9", +"~% c #454DBF", +"{% c #343CB3", +"]% c #2327A7", +"^% c #0E0F96", +"/% c #000089", +"(% c #62609E", +"_% c #CDC18D", +":% c #A49567", +"<% c #E7D376", +"[% c #57506A", +"}% c #000064", +"|% c #040471", +"1% c #0C0C8E", +"2% c #1213B7", +"3% c #272A7A", +"4% c #1314A2", +"5% c #343ABC", +"6% c #626DCC", +"7% c #2529A6", +"8% c #4245A1", +"9% c #262BA0", +"0% c #5259BB", +"a% c #7681CF", +"b% c #A1ACE1", +"c% c #B9C1EB", +"d% c #ADB9E7", +"e% c #8A97DD", +"f% c #6B75D3", +"g% c #575FC9", +"h% c #363CB4", +"i% c #2427A8", +"j% c #17199E", +"k% c #000092", +"l% c #33329C", +"m% c #ECE4B3", +"n% c #F9E78D", +"o% c #E8D67D", +"p% c #EEDA7C", +"q% c #F5E17D", +"r% c #61596F", +"s% c #00006F", +"t% c #06057E", +"u% c #0D0E91", +"v% c #1313B7", +"w% c #131563", +"x% c #1315A6", +"y% c #3D45C1", +"z% c #6873D1", +"A% c #22259D", +"B% c #5356A8", +"C% c #22289D", +"D% c #5058B9", +"E% c #9FACE0", +"F% c #B9C1EA", +"G% c #AEB9E6", +"H% c #8B98DD", +"I% c #6C76D2", +"J% c #5760C9", +"K% c #484FBE", +"L% c #373EB4", +"M% c #262AA8", +"N% c #0E0F9D", +"O% c #151899", +"P% c #CBCABE", +"Q% c #FFFAAA", +"R% c #E7D484", +"S% c #E4D17C", +"T% c #E0CE81", +"U% c #FBE884", +"V% c #AE9F74", +"W% c #05056F", +"X% c #00017E", +"Y% c #1416B8", +"Z% c #111371", +"`% c #1417A7", +" & c #5159C8", +".& c #616CCF", +"+& c #161980", +"@& c #7B7EBC", +"#& c #1B2196", +"$& c #4E55B7", +"%& c #737ECC", +"&& c #B8C2EA", +"*& c #AFBAE8", +"=& c #8D99DC", +"-& c #6D77D1", +";& c #474FBE", +">& c #262CA9", +",& c #05089A", +"'& c #3636A0", +")& c #EEEABC", +"!& c #F7E99D", +"~& c #E5D381", +"{& c #E4D27F", +"]& c #E3D386", +"^& c #F2DF86", +"/& c #BAAA74", +"(& c #0E0D71", +"_& c #00007F", +":& c #0F1099", +"<& c #090949", +"[& c #08092A", +"}& c #121388", +"|& c #6C79D2", +"1& c #4B53C5", +"2& c #070959", +"3& c #212696", +"4& c #4C53B3", +"5& c #717CC9", +"6& c #9CA9DC", +"7& c #B8C1E8", +"8& c #B0BAE4", +"9& c #6D77D0", +"0& c #575FC8", +"a& c #474FBF", +"b& c #383FB5", +"c& c #272CAA", +"d& c #06099B", +"e& c #3030A0", +"f& c #E6DFB4", +"g& c #F5E594", +"h& c #E5D586", +"i& c #E4D48C", +"j& c #EDDA85", +"k& c #CDB96E", +"l& c #181671", +"m& c #000080", +"n& c #10109A", +"o& c #1314B7", +"p& c #121391", +"q& c #07081B", +"r& c #02030E", +"s& c #101268", +"t& c #101295", +"u& c #3A41BC", +"v& c #727FD4", +"w& c #2227AB", +"x& c #272B97", +"y& c #4A4FB0", +"z& c #6F78C5", +"A& c #99A6DA", +"B& c #B5BFE6", +"C& c #AEB8E4", +"D& c #8D99DA", +"E& c #6D76CE", +"F& c #575EC5", +"G& c #474EBD", +"H& c #090B9B", +"I& c #2D2D9E", +"J& c #E4DAAB", +"K& c #F5E38D", +"L& c #E5D384", +"M& c #E9D98F", +"N& c #ECDE96", +"O& c #EFDE88", +"P& c #E2D06E", +"Q& c #2A286F", +"R& c #000082", +"S& c #11119D", +"T& c #1415B2", +"U& c #141599", +"V& c #0E1051", +"W& c #03051D", +"X& c #0D105C", +"Y& c #13148B", +"Z& c #1B1CA4", +"`& c #626BCD", +" * c #484FC4", +".* c #0C0D7A", +"+* c #232895", +"@* c #454CAD", +"#* c #6C75C1", +"$* c #95A2D6", +"%* c #B1BCE4", +"&* c #ACB6E4", +"** c #8C98D8", +"=* c #6C75CC", +"-* c #565DC3", +";* c #474EBC", +">* c #282CA9", +",* c #090C9D", +"'* c #27299B", +")* c #DFD4A3", +"!* c #EDDD90", +"~* c #E7D78F", +"{* c #D3BF7D", +"]* c #CFB96D", +"^* c #C5AD4E", +"/* c #3F3A70", +"(* c #000085", +"_* c #11119F", +":* c #161897", +"<* c #161981", +"[* c #0B0D5D", +"}* c #0F127A", +"|* c #16189A", +"1* c #474DBD", +"2* c #555DC9", +"3* c #181CA7", +"4* c #060735", +"5* c #242799", +"6* c #4248AA", +"7* c #6771BD", +"8* c #909CD1", +"9* c #ACB6E0", +"0* c #A8B3E1", +"a* c #8A97D6", +"b* c #6B75CA", +"c* c #555DC0", +"d* c #474EBA", +"e* c #383FB2", +"f* c #282DA9", +"g* c #0B0E9D", +"h* c #222499", +"i* c #DED69F", +"j* c #B69B52", +"k* c #B49B5F", +"l* c #B0985E", +"m* c #967A44", +"n* c #92763C", +"o* c #B6983B", +"p* c #574F73", +"q* c #000087", +"r* c #1111A1", +"s* c #1316B1", +"t* c #181B97", +"u* c #1A1D8D", +"v* c #0D0F68", +"w* c #141786", +"x* c #383FB0", +"y* c #4B53C4", +"z* c #2225B5", +"A* c #0B0C5E", +"B* c #000000", +"C* c #212799", +"D* c #3E45A7", +"E* c #626AB9", +"F* c #8894CD", +"G* c #A0ADDB", +"H* c #A0ADDA", +"I* c #8794D2", +"J* c #6973C5", +"K* c #454BB6", +"L* c #383EAF", +"M* c #282CA6", +"N* c #0B0E9B", +"O* c #242596", +"P* c #D8CA8F", +"Q* c #9D7D3A", +"R* c #7D5C2E", +"S* c #967944", +"T* c #C3AB6A", +"U* c #987A3D", +"V* c #A7852C", +"W* c #5C5063", +"X* c #00008C", +"Y* c #1111A3", +"Z* c #1315AF", +"`* c #181993", +" = c #1F22A1", +".= c #1A1C8A", +"+= c #2A2FA5", +"@= c #2F36BA", +"#= c #1B1EAD", +"$= c #0B0D65", +"%= c #010108", +"&= c #212599", +"*= c #3A40A5", +"== c #5A63B4", +"-= c #7D88C5", +";= c #94A0D3", +">= c #95A4D6", +",= c #818ECD", +"'= c #6670C0", +")= c #525AB9", +"!= c #444AB2", +"~= c #363DAC", +"{= c #272CA4", +"]= c #0B0D99", +"^= c #2A2A96", +"/= c #BEAA72", +"(= c #825D21", +"_= c #81602E", +":= c #8E6D36", +"<= c #926F33", +"[= c #C0A147", +"}= c #C9AB41", +"|= c #554C66", +"1= c #00008B", +"2= c #1011A6", +"3= c #1313AE", +"4= c #12137E", +"5= c #1D1EA0", +"6= c #2022AD", +"7= c #1C1FA7", +"8= c #12138B", +"9= c #080947", +"0= c #000002", +"a= c #1E2292", +"b= c #343AA3", +"c= c #525AAE", +"d= c #6F78BD", +"e= c #8591C8", +"f= c #8A95CD", +"g= c #7983C7", +"h= c #636BBD", +"i= c #5057B5", +"j= c #4349B0", +"k= c #363CA9", +"l= c #282BA1", +"m= c #0A0C97", +"n= c #252895", +"o= c #BDA666", +"p= c #DCC261", +"q= c #DED282", +"r= c #B9A86E", +"s= c #92855F", +"t= c #58514E", +"u= c #222051", +"v= c #040470", +"w= c #08088B", +"x= c #100FA9", +"y= c #1012A8", +"z= c #0D0E5B", +"A= c #0D0E5F", +"B= c #0C0E5C", +"C= c #08093F", +"D= c #01010E", +"E= c #191C7E", +"F= c #3035A5", +"G= c #4A50A9", +"H= c #626BB6", +"I= c #757FBF", +"J= c #7A85C2", +"K= c #6F78BF", +"L= c #5D64B6", +"M= c #4D54B1", +"N= c #4146AC", +"O= c #343AA5", +"P= c #252A9E", +"Q= c #131595", +"R= c #0D0F8C", +"S= c #686286", +"T= c #625C78", +"U= c #1F1D63", +"V= c #000057", +"W= c #00005A", +"X= c #00016C", +"Y= c #07087E", +"Z= c #0E0EB1", +"`= c #0B0B7C", +" - c #000102", +".- c #121463", +"+- c #4248A4", +"@- c #565DAE", +"#- c #646CB7", +"$- c #6870B9", +"%- c #636AB7", +"&- c #555CB1", +"*- c #484EAB", +"=- c #3E44A7", +"-- c #3238A3", +";- c #24289C", +">- c #171993", +",- c #0C0E8A", +"'- c #000073", +")- c #00006B", +"!- c #000167", +"~- c #050567", +"{- c #07086C", +"]- c #0A0A75", +"^- c #0A0A83", +"/- c #0D0DB6", +"(- c #07074F", +"_- c #0E104E", +":- c #2529A1", +"<- c #393FA0", +"[- c #4A51A8", +"}- c #565EAF", +"|- c #5B63B2", +"1- c #575FB1", +"2- c #4D54AD", +"3- c #4248A7", +"4- c #393EA4", +"5- c #2F34A0", +"6- c #222598", +"7- c #141691", +"8- c #0E1089", +"9- c #0B0C7F", +"0- c #08086C", +"a- c #060667", +"b- c #060668", +"c- c #0B0B88", +"d- c #0C0DB7", +"e- c #050537", +"f- c #03041D", +"g- c #1C2093", +"h- c #3138A4", +"i- c #4047A2", +"j- c #4950A9", +"k- c #4E55AC", +"l- c #4C53AB", +"m- c #454BA9", +"n- c #3B42A5", +"o- c #3339A1", +"p- c #2A2F9C", +"q- c #1E2096", +"r- c #13158F", +"s- c #0D0F86", +"t- c #0B0B7E", +"u- c #0B0B8C", +"v- c #0D0DAE", +"w- c #0A0B93", +"x- c #01010D", +"y- c #0E0F4E", +"z- c #272BA8", +"A- c #353BA1", +"B- c #3D45A1", +"C- c #4248A5", +"D- c #4147A7", +"E- c #3C42A5", +"F- c #353AA1", +"G- c #2E339E", +"H- c #252999", +"I- c #1C1E94", +"J- c #13148C", +"K- c #0D0E83", +"L- c #0C0B7B", +"M- c #09096C", +"N- c #0C0C9E", +"O- c #040539", +"P- c #0E1150", +"Q- c #23279E", +"R- c #2F34A3", +"S- c #353C9F", +"T- c #3238A1", +"U- c #2D339D", +"V- c #272A9A", +"W- c #1F2196", +"X- c #171991", +"Y- c #111288", +"Z- c #0C0D80", +"`- c #090970", +" ; c #090982", +".; c #0B0B99", +"+; c #0A0B99", +"@; c #04043B", +"#; c #060726", +"$; c #151870", +"%; c #212597", +"&; c #282C9F", +"*; c #262B9E", +"=; c #24279B", +"-; c #202397", +";; c #1B1C93", +">; c #0E1186", +",; c #0C0D7F", +"'; c #090980", +"); c #080889", +"!; c #090987", +"~; c #070761", +"{; c #020215", +"]; c #050622", +"^; c #0D0E4A", +"/; c #131467", +"(; c #16177F", +"_; c #15188A", +":; c #0F138A", +"<; c #0C0E85", +"[; c #0B0B81", +"}; c #08087A", +"|; c #07076F", +"1; c #050540", +"2; c #030318", +"3; c #01020F", +"4; c #02031B", +"5; c #040524", +"6; c #040526", +"7; c #030427", +"8; c #030327", +"9; c #030322", +"0; c #020318", +"a; c #010100", +" ", +" ", +" ", +" . + @ # $ % & * = ", +" - ; > , ' ) ! ~ { ] ^ / ( _ : < ", +" [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h ", +" i j k l m n o p q 6 r s t u v w x y z A B C D ", +" E F G H I J K n I L M N O P Q R S T U V W X Y Z ` ", +" ...+.@.#.$.I o %.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:. ", +" <.[.K }.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l. ", +" m.n.o.m p.q.r.r.s.r.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J. ", +" K.L.M.N.O.P.Q.R.q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+&+ ", +" *+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+1+2+3+4+5+6+ ", +" 7+8+9+0+a+b+c+,+O.d+e+f+g+h+i+j+k+l+X.m+n+o+p+q+r+s+t+ ", +" u+v+w+x+y+a+z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+ U+V+W+X+ ", +" Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@}@|@1@2@ ", +" 3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@M p@q@r@s@t@u@v@w@x@y@z@ ", +" A@B@C@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@5 V@W@X@Y@Z@`@ #.#+#+#@###$# ", +" %#&#*#=#-#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#$.W@|#Y@1#2#3#4#5#6#7#8#9# ", +" 0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#g@t#u#W@X@v#w#x###+#y#z#A#B#C#D# ", +" E#F#b#G#H#I#J#K#L#M#N#O#P#Q#R#S#T#U#V#W#X#Y#J Z#`# $.$+$@$#$ $$%$C.&$*$ ", +" =$-$b#;$>$,$'$)$!$~${$]$^$/$($_$:$<$[$}$|$1$n V@2$3$4$5$6$ 7$8$9$0$a$ ", +" b$c$d$e$f$g$h$i$j$~$k$l$m$n$o$p$q$r$s$t$u$v$t#w$x$y$z$A$B$ C$D$E$F$G$ ", +" H$I$J$K$L$M$N$O$P$~$k$Q$# R$S$T$U$V$W$X$Y$Z$Y#`$ %.%+% @%#%$%%%&% ", +" *%=%-%e$;%>%,%'%)%!%~%{%]%R$^%/%(%_%:%<%[%}%|%o.1%2% 3%4%5%6%7% ", +" 8%9%0%a%b%c%d%e%f%g%{$h%i%j%k%l%m%n%o%p%q%r%s%t%u%v% w%x%y%z%A% ", +" B%C%D%6@E%F%G%H%I%J%K%L%M%N%O%P%Q%R%S%T%U%V%W%X%^%Y% Z%`% &.&+& ", +" @&#&$&%&>$&&*&=&-&g%;&]$>&,&'&)&!&~&{&]&^&/&(&_&:&Y%<& [&}&K.|&1&2& ", +" 3&4&5&6&7&8&=&9&0&a&b&c&d&e&f&g&~&h&i&j&k&l&m&n&o&p&q& r&s&t&u&v&w& ", +" x&y&z&A&B&C&D&E&F&G&]$% H&I&J&K&L&M&N&O&P&Q&R&S&T&U&V&W&X&Y&Z&`& *.* ", +" +*@*#*$*%*&***=*-*;*]$>*,*'*)*n%!*~*{*]*^*/*(*_*T&:*<*[*}*|*1*2*3*4* ", +" 5*6*7*8*9*0*a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*A*B*B* ", +" C*D*E*F*G*H*I*J*b#K*L*M*N*O*P*Q*R*S*T*U*V*W*X*Y*Z*`* =.=+=@=#=$=%=B* ", +" &=*===-=;=>=,='=)=!=~={=]=^=/=(=_=:=<=[=}=|=1=2=3=4=5=6=7=8=9=0=B* ", +" a=b=c=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z=A=B=C=D=B*B* ", +" E=F=G=H=I=J=K=L=M=N=O=P=Q=R=S=T=U=V=<@W=X=Y=1%Z=`= -B*B*B*B*B* ", +" .-Q#+-@-#-$-%-&-*-=---;->-,-_&'-)-!-~-{-]-^-X@/-(-B*B*B*B* ", +" _-:-<-[-}-|-1-2-3-4-5-6-7-8-9-n 0-a-b-1$J c-/@d-e-B*B*B* ", +" f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-o 0-v$0-t#`$u-v-w-x-B*B* ", +" y-z-A-B-C-D-E-F-G-H-I-J-K-L-t#M-1$+.J ^-N-v-O-B* ", +" P-Q-R-S-A-T-U-V-W-X-Y-Z-}#t#+.`-K ;.;+;@;B* ", +" #;$;%;&;*;=;-;;;9+>;,;*.K I ';);!;~;{;B* ", +" ];^;/;(;_;J-:;<;[;#.};|;P.1;2;B* ", +" 3;4;5;6;7;8;9;0;x-a; ", +" ", +" ", +" ", +" "}; diff --git a/engines/ags/engine/platform/osx/acplmac.cpp b/engines/ags/engine/platform/osx/acplmac.cpp new file mode 100644 index 000000000000..64c590a65179 --- /dev/null +++ b/engines/ags/engine/platform/osx/acplmac.cpp @@ -0,0 +1,149 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_MACOS + +// ********* MacOS PLACEHOLDER DRIVER ********* + +//#include "util/wgt2allg.h" +//#include "gfx/ali3d.h" +//#include "ac/runtime_defines.h" +//#include "main/config.h" +//#include "plugin/agsplugin.h" +//#include +//#include +//#include +#include "platform/base/agsplatformdriver.h" +#include "util/directory.h" +#include "ac/common.h" +#include "main/main.h" + +void AGSMacInitPaths(char gamename[256], char appdata[PATH_MAX]); +void AGSMacGetBundleDir(char gamepath[PATH_MAX]); +//bool PlayMovie(char const *name, int skipType); + +static char libraryApplicationSupport[PATH_MAX]; +static char commonDataPath[PATH_MAX]; + +struct AGSMac : AGSPlatformDriver { + AGSMac(); + + virtual int CDPlayerCommand(int cmdd, int datt) override; + virtual void DisplayAlert(const char*, ...) override; + virtual unsigned long GetDiskFreeSpaceMB() override; + virtual const char* GetNoMouseErrorString() override; + virtual eScriptSystemOSID GetSystemOSID() override; + virtual int InitializeCDPlayer() override; + virtual void PostAllegroExit() override; + virtual void SetGameWindowIcon() override; + virtual void ShutdownCDPlayer() override; + + virtual const char *GetUserSavedgamesDirectory() override; + virtual const char *GetAllUsersDataDirectory() override; + virtual const char *GetUserConfigDirectory() override; + virtual const char *GetAppOutputDirectory() override; + virtual const char *GetIllegalFileChars() override; +}; + +AGSMac::AGSMac() +{ + AGSMacInitPaths(psp_game_file_name, libraryApplicationSupport); + + snprintf(commonDataPath, PATH_MAX, "%s/uk.co.adventuregamestudio", libraryApplicationSupport); + AGS::Common::Directory::CreateDirectory(commonDataPath); + + strcpy(psp_translation, "default"); +} + +int AGSMac::CDPlayerCommand(int cmdd, int datt) { + return 0;//cd_player_control(cmdd, datt); +} + +void AGSMac::DisplayAlert(const char *text, ...) { + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + if (_logToStdErr) + fprintf(stderr, "%s\n", displbuf); + else + fprintf(stdout, "%s\n", displbuf); +} + +unsigned long AGSMac::GetDiskFreeSpaceMB() { + // placeholder + return 100; +} + +const char* AGSMac::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +} + +eScriptSystemOSID AGSMac::GetSystemOSID() { + // override performed if `override.os` is set in config. + return eOS_Mac; +} + +int AGSMac::InitializeCDPlayer() { + //return cd_player_init(); + return 0; +} + +void AGSMac::PostAllegroExit() { + // do nothing +} + +void AGSMac::SetGameWindowIcon() { + // do nothing +} + +void AGSMac::ShutdownCDPlayer() { + //cd_exit(); +} + +const char* AGSMac::GetAllUsersDataDirectory() +{ + return commonDataPath; +} + +const char *AGSMac::GetUserSavedgamesDirectory() +{ + return libraryApplicationSupport; +} + +const char *AGSMac::GetUserConfigDirectory() +{ + return libraryApplicationSupport; +} + +const char *AGSMac::GetAppOutputDirectory() +{ + return commonDataPath; +} + +const char *AGSMac::GetIllegalFileChars() +{ + return "\\/:?\"<>|*"; // keep same as Windows so we can sync. +} + +AGSPlatformDriver* AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSMac(); + return instance; +} + +#endif diff --git a/engines/ags/engine/platform/osx/alplmac.mm b/engines/ags/engine/platform/osx/alplmac.mm new file mode 100644 index 000000000000..c245aec1b931 --- /dev/null +++ b/engines/ags/engine/platform/osx/alplmac.mm @@ -0,0 +1,30 @@ +#import + +#include + +void AGSMacInitPaths(char gamename[256], char appdata[PATH_MAX]) +{ + strcpy(gamename, "game.ags"); + + @autoreleasepool { + NSBundle *bundle = [NSBundle mainBundle]; + NSString *resourcedir = [bundle resourcePath]; + [[NSFileManager defaultManager] changeCurrentDirectoryPath:resourcedir]; + + NSURL *path = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL]; + + snprintf(appdata, PATH_MAX, "%s", [[path path] UTF8String]); + } +} + +// e.g. "/Users//Library/Application Support/Steam/steamapps/common/" +void AGSMacGetBundleDir(char gamepath[PATH_MAX]) +{ + @autoreleasepool { + NSBundle *bundle = [NSBundle mainBundle]; + NSString *bundleDir = [bundle bundlePath]; + + NSString *parentDir = [bundleDir stringByDeletingLastPathComponent]; + strcpy(gamepath, [parentDir UTF8String]); + } +} diff --git a/engines/ags/engine/platform/util/libc.c b/engines/ags/engine/platform/util/libc.c new file mode 100644 index 000000000000..f88f89cc4bd5 --- /dev/null +++ b/engines/ags/engine/platform/util/libc.c @@ -0,0 +1,54 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Implementations for missing libc functions +// +//============================================================================= + +#include "core/platform.h" + +#if ! AGS_PLATFORM_OS_WINDOWS + +#include +#include +#include +#include +#include + +size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t max) +{ + int count = 0; + + while ((count < max) && (*mbstr != 0)) + { + *wcstr++ = *mbstr++; + count++; + } + return count; + +} + +size_t wcstombs(char* mbstr, const wchar_t *wcstr, size_t max) +{ + int count = 0; + + while ((count < max) && (*wcstr != 0)) + { + *mbstr++ = *wcstr++; + count++; + } + return count; +} + +#endif // ! AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/util/pe.c b/engines/ags/engine/platform/util/pe.c new file mode 100644 index 000000000000..de7f65287787 --- /dev/null +++ b/engines/ags/engine/platform/util/pe.c @@ -0,0 +1,311 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Functions for reading version information from PE (Windows EXE) files +// +//============================================================================= + +#if defined(ANDROID) || defined(PSP) + +#include "pe.h" + +#include +#include +#include "util/stdio_compat.h" + + +// Simplified structs for PE files + +typedef struct { + char padding[60]; + unsigned int e_lfanew; +} IMAGE_DOS_HEADER; + +typedef struct { + char padding[2]; + unsigned short NumberOfSections; + char padding1[16]; +} IMAGE_FILE_HEADER; + +typedef struct { + unsigned int Signature; + IMAGE_FILE_HEADER FileHeader; + char padding[224]; +} IMAGE_NT_HEADERS; + +typedef struct { + char Name[8]; + char padding[4]; + unsigned int VirtualAddress; + char padding1[4]; + unsigned int PointerToRawData; + char padding2[16]; +} IMAGE_SECTION_HEADER; + + +// These structs are original + +typedef struct { + unsigned int Characteristics; + unsigned int TimeDateStamp; + unsigned short MajorVersion; + unsigned short MinorVersion; + unsigned short NumberOfNamedEntries; + unsigned short NumberOfIdEntries; +} IMAGE_RESOURCE_DIRECTORY; + +typedef struct { + union { + struct { + unsigned int NameOffset:31; + unsigned int NameIsString:1; + }; + unsigned int Name; + unsigned short Id; + }; + union { + unsigned int OffsetToData; + struct { + unsigned int OffsetToDirectory:31; + unsigned int DataIsDirectory:1; + }; + }; +} IMAGE_RESOURCE_DIRECTORY_ENTRY; + +typedef struct { + unsigned int OffsetToData; + unsigned int Size; + unsigned int CodePage; + unsigned int Reserved; +} IMAGE_RESOURCE_DATA_ENTRY; + + + +// Version information + +typedef struct { + unsigned int dwSignature; + unsigned int dwStrucVersion; + unsigned int dwFileVersionMS; + unsigned int dwFileVersionLS; + unsigned int dwProductVersionMS; + unsigned int dwProductVersionLS; + unsigned int dwFileFlagsMask; + unsigned int dwFileFlags; + unsigned int dwFileOS; + unsigned int dwFileType; + unsigned int dwFileSubtype; + unsigned int dwFileDateMS; + unsigned int dwFileDateLS; +} VS_FIXEDFILEINFO; + +typedef struct { + unsigned short wLength; + unsigned short wValueLength; + unsigned short wType; +} STRINGFILEINFO_HEADER; + + + +IMAGE_DOS_HEADER dos_header; +IMAGE_NT_HEADERS nt_headers; +IMAGE_SECTION_HEADER section_header; +IMAGE_RESOURCE_DIRECTORY resource_directory; +IMAGE_RESOURCE_DIRECTORY_ENTRY resource_directory_entry; +IMAGE_RESOURCE_DATA_ENTRY resource_data_entry; + +unsigned int resource_virtual_address; +unsigned int resource_start; + + + + +void fillBufferFromWidechar(unsigned short* inputBuffer, char* outputText) +{ + unsigned short* input = inputBuffer; + char* output = outputText; + + while (*input) + *output++ = *input++; + + *output = '\0'; +} + + + +int getVersionString(char* version_data, unsigned int size, char* buffer, char* name) +{ + char* current = version_data; + char* last = version_data + size; + + char temp[200]; + + // Skip header + current += 0x28; + + // Skip VS_FIXEDFILEINFO + current += sizeof(VS_FIXEDFILEINFO); + + // Now comes either "StringFileInfo" or "VarFileInfo" + STRINGFILEINFO_HEADER* stringfileinfo_header = (STRINGFILEINFO_HEADER*)current; + current += sizeof(STRINGFILEINFO_HEADER); + fillBufferFromWidechar((unsigned short*)current, temp); + if (strcmp(temp, "VarFileInfo") == 0) + { + current += (stringfileinfo_header->wLength - sizeof(STRINGFILEINFO_HEADER)); + + // Skip "StringFileInfo" header too + stringfileinfo_header = (STRINGFILEINFO_HEADER*)current; + current += 0x3C; + } + else + current += (0x3C - sizeof(STRINGFILEINFO_HEADER)); + + while (current < last) + { + STRINGFILEINFO_HEADER* header = (STRINGFILEINFO_HEADER*)current; + current += sizeof(STRINGFILEINFO_HEADER); + + // Read name + fillBufferFromWidechar((unsigned short*)current, temp); + + if (strcmp(temp, name) == 0) + { + current += (2 + 2 * strlen(temp)); + + // Next value is 32 bit aligned + current = (char*)((unsigned long)(current + 3) & (~3)); + + // Read value + fillBufferFromWidechar((unsigned short*)current, buffer); + + return 1; + } + else + current += (header->wLength - sizeof(STRINGFILEINFO_HEADER)); + + // Next value is 32 bit aligned + current = (char*)((unsigned long)(current + 3) & (~3)); + } + + return 0; +} + + + +int seekToResource(FILE* pe, int id) +{ + int i; + + // Read in resource directory + fread(&resource_directory, sizeof(IMAGE_RESOURCE_DIRECTORY), 1, pe); + + // Loop through root node entries till we find the entry with the given id + for (i = 0; i < resource_directory.NumberOfIdEntries + resource_directory.NumberOfNamedEntries; i++) + { + // Read in resource node + fread(&resource_directory_entry, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, pe); + + if ((!resource_directory_entry.NameIsString) && (resource_directory_entry.Id == id)) + { + // Seek to end of subdirectory + ags_fseek(pe, resource_start + resource_directory_entry.OffsetToDirectory, SEEK_SET); + return 1; + } + } + + return 0; +} + + + +int getVersionInformation(char* filename, version_info_t* version_info) +{ + FILE* pe = fopen(filename, "rb"); + + if (!pe) + return 0; + + // Read in the DOS header, get the offset to the PE header and seek + fread(&dos_header, sizeof(IMAGE_DOS_HEADER), 1, pe); + ags_fseek(pe, dos_header.e_lfanew, SEEK_SET); + + // Read in the PE header + fread(&nt_headers, sizeof(IMAGE_NT_HEADERS), 1, pe); + + // Loop through sections till we find the resource section + int i; + for (i = 0; i < nt_headers.FileHeader.NumberOfSections; i++) + { + fread(§ion_header, sizeof(IMAGE_SECTION_HEADER), 1, pe); + + if (strcmp(".rsrc", (char*)section_header.Name) == 0) + break; + } + + if (i == nt_headers.FileHeader.NumberOfSections) + goto error_exit; + + // Save virtual address of the resource section + resource_virtual_address = section_header.VirtualAddress; + + // Seek to the resource section + ags_fseek(pe, section_header.PointerToRawData, SEEK_SET); + + // Save file offset to the resource section + resource_start = section_header.PointerToRawData; + + // Search for the version resource in the resource tree + if (!seekToResource(pe, 16)) + goto error_exit; + + // Enter the first subdirectory in the version resource + if (!seekToResource(pe, 1)) + goto error_exit; + + // Hopefully found the resource + fread(&resource_directory, sizeof(IMAGE_RESOURCE_DATA_ENTRY), 1, pe); + + // Read in resource node + fread(&resource_directory_entry, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, pe); + + // Seek to the resource data + ags_fseek(pe, resource_start + resource_directory_entry.OffsetToData, SEEK_SET); + + // Read in version info + fread(&resource_data_entry, sizeof(IMAGE_RESOURCE_DATA_ENTRY), 1, pe); + + // Finally we got a virtual address of the resource, now seek to it + ags_fseek(pe, resource_start + resource_data_entry.OffsetToData - resource_virtual_address, SEEK_SET); + + // Read version resource + char* version_data = (char*)malloc(resource_data_entry.Size); + fread(version_data, resource_data_entry.Size, 1, pe); + + memset(version_info, 0, sizeof(version_info_t)); + getVersionString(version_data, resource_data_entry.Size, version_info->version, "FileVersion"); + getVersionString(version_data, resource_data_entry.Size, version_info->description, "FileDescription"); + getVersionString(version_data, resource_data_entry.Size, version_info->internal_name, "InternalName"); + + free(version_data); + fclose(pe); + + return 1; + +error_exit: + fclose(pe); + return 0; +} + +#endif \ No newline at end of file diff --git a/engines/ags/engine/platform/util/pe.h b/engines/ags/engine/platform/util/pe.h new file mode 100644 index 000000000000..97b5e646462c --- /dev/null +++ b/engines/ags/engine/platform/util/pe.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_PLATFORM_UTIL_PE_H +#define __AGS_EE_PLATFORM_UTIL_PE_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char version[15]; + char description[100]; + char internal_name[100]; +} version_info_t; + +int getVersionInformation(char* filename, version_info_t* version_info); + +#ifdef __cplusplus +} +#endif + +#endif // __AGS_EE_PLATFORM_UTIL_PE_H diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp new file mode 100644 index 000000000000..8e3b91d62520 --- /dev/null +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -0,0 +1,1149 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS + +// ********* WINDOWS ********* + +#include +#include +#include +#include "ac/common.h" +#include "ac/draw.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_display.h" +#include "ac/runtime_defines.h" +#include "ac/string.h" +#include "debug/out.h" +#include "gfx/graphicsdriver.h" +#include "gfx/bitmap.h" +#include "main/engine.h" +#include "platform/base/agsplatformdriver.h" +#include "platform/windows/setup/winsetup.h" +#include "plugin/agsplugin.h" +#include "util/file.h" +#include "util/stream.h" +#include "util/string_compat.h" +#include "media/audio/audio_system.h" + +#ifndef AGS_NO_VIDEO_PLAYER +extern void dxmedia_abort_video(); +extern void dxmedia_pause_video(); +extern void dxmedia_resume_video(); +extern char lastError[200]; +#endif + +using namespace AGS::Common; +using namespace AGS::Engine; + +extern GameSetupStruct game; +extern GameSetup usetup; +extern int our_eip; +extern IGraphicsDriver *gfxDriver; +extern color palette[256]; + +#include +#include +#include +#include +#include +#include + +#include + + +#ifndef CSIDL_LOCAL_APPDATA +#define CSIDL_LOCAL_APPDATA 0x001C +#define CSIDL_COMMON_APPDATA 0x0023 +#endif + +typedef struct BMP_EXTRA_INFO { + LPDIRECTDRAWSURFACE2 surf; + struct BMP_EXTRA_INFO *next; + struct BMP_EXTRA_INFO *prev; + int flags; + int lock_nesting; +} BMP_EXTRA_INFO; + +// from Allegro DDraw driver +extern "C" extern LPDIRECTDRAW2 directdraw; +extern "C" extern LPDIRECTSOUND directsound; +extern "C" extern LPDIRECTINPUTDEVICE mouse_dinput_device; +extern "C" extern LPDIRECTINPUTDEVICE key_dinput_device; + +char win32SavedGamesDirectory[MAX_PATH] = "\0"; +char win32AppDataDirectory[MAX_PATH] = "\0"; +String win32OutputDirectory; + +const unsigned int win32TimerPeriod = 1; + +extern SetupReturnValue acwsetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &game_data_dir, const char*, const char*); + +struct AGSWin32 : AGSPlatformDriver { + AGSWin32(); + ~AGSWin32(); + + virtual void AboutToQuitGame(); + virtual int CDPlayerCommand(int cmdd, int datt); + virtual void AttachToParentConsole(); + virtual void DisplayAlert(const char*, ...); + virtual int GetLastSystemError(); + virtual const char *GetAllUsersDataDirectory(); + virtual const char *GetUserSavedgamesDirectory(); + virtual const char *GetUserConfigDirectory(); + virtual const char *GetUserGlobalConfigDirectory(); + virtual const char *GetAppOutputDirectory(); + virtual const char *GetIllegalFileChars(); + virtual const char *GetGraphicsTroubleshootingText(); + virtual unsigned long GetDiskFreeSpaceMB(); + virtual const char* GetNoMouseErrorString(); + virtual bool IsMouseControlSupported(bool windowed); + virtual const char* GetAllegroFailUserHint(); + virtual eScriptSystemOSID GetSystemOSID(); + virtual int InitializeCDPlayer(); + virtual void PostAllegroInit(bool windowed); + virtual void PostAllegroExit(); + virtual SetupReturnValue RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out); + virtual void SetGameWindowIcon(); + virtual void ShutdownCDPlayer(); + virtual void WriteStdOut(const char *fmt, ...); + virtual void WriteStdErr(const char *fmt, ...); + virtual void DisplaySwitchOut(); + virtual void DisplaySwitchIn(); + virtual void PauseApplication(); + virtual void ResumeApplication(); + virtual void GetSystemDisplayModes(std::vector &dms); + virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm); + virtual bool ExitFullscreenMode(); + virtual void AdjustWindowStyleForFullscreen(); + virtual void AdjustWindowStyleForWindowed(); + virtual void RegisterGameWithGameExplorer(); + virtual void UnRegisterGameWithGameExplorer(); + virtual int ConvertKeycodeToScanCode(int keyCode); + virtual void ValidateWindowSize(int &x, int &y, bool borderless) const; + virtual bool LockMouseToWindow(); + virtual void UnlockMouse(); + +#ifndef AGS_NO_VIDEO_PLAYER + virtual void PlayVideo(const char* name, int skip, int flags); +#endif + + +private: + void add_game_to_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers); + void remove_game_from_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers); + void add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers); + void get_tasks_directory(char *directoryNameBuffer, const char *guidAsText, bool allUsers); + void update_game_explorer(bool add); + void create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath); + void register_file_extension(const char *exePath); + void unregister_file_extension(); + + bool SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen); + + bool _isDebuggerPresent; // indicates if the win app is running in the context of a debugger + DisplayMode _preFullscreenMode; // saved display mode before switching system to fullscreen + bool _isAttachedToParentConsole; // indicates if the win app is attached to the parent console +}; + +AGSWin32::AGSWin32() : + _isDebuggerPresent(::IsDebuggerPresent() != FALSE), + _isAttachedToParentConsole(false) +{ + // Do nothing. +} + +AGSWin32::~AGSWin32() { + if (_isAttachedToParentConsole) + { + ::FreeConsole(); + } +} + +void check_parental_controls() { + /* this doesn't work, it always just returns access depedning + on whether unrated games are allowed because of digital signature + BOOL bHasAccess = FALSE; + IGameExplorer* pFwGameExplorer = NULL; + + CoInitialize(NULL); + // Create an instance of the Game Explorer Interface + HRESULT hr = CoCreateInstance( __uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void**)&pFwGameExplorer); + if( FAILED(hr) || pFwGameExplorer == NULL ) { + // not Vista, do nothing + } + else { + char theexename[MAX_PATH] = "e:\\code\\ags\\acwin\\release\\acwin.exe"; + WCHAR wstrBinPath[MAX_PATH] = {0}; + MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrBinPath, MAX_PATH); + BSTR bstrGDFBinPath = SysAllocString(wstrBinPath); + + hr = pFwGameExplorer->VerifyAccess( bstrGDFBinPath, &bHasAccess ); + SysFreeString(bstrGDFBinPath); + + if( FAILED(hr) || !bHasAccess ) { + char buff[300]; + sprintf(buff, "Parental controls block: %X b: %d", hr, bHasAccess); + quit(buff); + } + else { + platform->DisplayAlert("Parental controls: Access granted."); + } + + } + + if( pFwGameExplorer ) pFwGameExplorer->Release(); + CoUninitialize(); + */ +} + +void AGSWin32::create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath) +{ + IShellLink* pShellLink = NULL; + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pShellLink); + + if ((SUCCEEDED(hr)) && (pShellLink != NULL)) + { + IPersistFile *pPersistFile = NULL; + if (FAILED(pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile))) + { + this->DisplayAlert("Unable to add game tasks: QueryInterface for IPersistFile failed"); + pShellLink->Release(); + return; + } + + // Set the path to the shortcut target and add the description + if (FAILED(pShellLink->SetPath(pathToEXE))) + { + this->DisplayAlert("Unable to add game tasks: SetPath failed"); + } + else if (FAILED(pShellLink->SetWorkingDirectory(workingFolder))) + { + this->DisplayAlert("Unable to add game tasks: SetWorkingDirectory failed"); + } + else if ((arguments != NULL) && (FAILED(pShellLink->SetArguments(arguments)))) + { + this->DisplayAlert("Unable to add game tasks: SetArguments failed"); + } + else + { + WCHAR wstrTemp[MAX_PATH] = {0}; + MultiByteToWideChar(CP_ACP, 0, shortcutPath, -1, wstrTemp, MAX_PATH); + + if (FAILED(pPersistFile->Save(wstrTemp, TRUE))) + { + this->DisplayAlert("Unable to add game tasks: IPersistFile::Save failed"); + } + } + + pPersistFile->Release(); + } + + if (pShellLink) pShellLink->Release(); +} + +void CopyStringAndRemoveInvalidFilenameChars(const char *source, char *destinationBuffer) +{ + int destIdx = 0; + for (int i = 0; i < (int)strlen(source); i++) + { + if ((source[i] != '/') && + (source[i] != '\\') && + (source[i] != ':') && + (source[i] != '*') && + (source[i] != '?') && + (source[i] != '"') && + (source[i] != '<') && + (source[i] != '>') && + (source[i] != '|') && + (source[i] >= 32)) + { + destinationBuffer[destIdx] = source[i]; + destIdx++; + } + } + destinationBuffer[destIdx] = 0; +} + +void AGSWin32::get_tasks_directory(char *pathBuffer, const char *guidAsText, bool allUsers) +{ + if (SHGetSpecialFolderPath(NULL, pathBuffer, allUsers ? CSIDL_COMMON_APPDATA : CSIDL_LOCAL_APPDATA, FALSE) == FALSE) + { + this->DisplayAlert("Unable to register game: SHGetSpecialFolderPath failed"); + return; + } + + if (pathBuffer[strlen(pathBuffer) - 1] != '\\') + { + strcat(pathBuffer, "\\"); + } + + strcat(pathBuffer, "Microsoft\\Windows\\GameExplorer\\"); + strcat(pathBuffer, guidAsText); + mkdir(pathBuffer); + strcat(pathBuffer, "\\"); + strcat(pathBuffer, "PlayTasks"); + mkdir(pathBuffer); +} + +void AGSWin32::add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers) +{ + char pathBuffer[MAX_PATH]; + get_tasks_directory(pathBuffer, guidAsText, allUsers); + strcat(pathBuffer, "\\"); + strcat(pathBuffer, "0"); + mkdir(pathBuffer); + + // Remove any existing "Play.lnk" from a previous version + char shortcutLocation[MAX_PATH]; + sprintf(shortcutLocation, "%s\\Play.lnk", pathBuffer); + ::remove(shortcutLocation); + + // Generate the shortcut file name (because it can appear on + // the start menu's Recent area) + char sanitisedGameName[MAX_PATH]; + CopyStringAndRemoveInvalidFilenameChars(game.gamename, sanitisedGameName); + if (sanitisedGameName[0] == 0) + strcpy(sanitisedGameName, "Play"); + sprintf(shortcutLocation, "%s\\%s.lnk", pathBuffer, sanitisedGameName); + + create_shortcut(gameEXE, workingFolder, NULL, shortcutLocation); + + pathBuffer[strlen(pathBuffer) - 1] = '1'; + mkdir(pathBuffer); + + sprintf(shortcutLocation, "%s\\Setup game.lnk", pathBuffer); + create_shortcut(gameEXE, workingFolder, "--setup", shortcutLocation); +} + +void AGSWin32::add_game_to_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) +{ + WCHAR wstrTemp[MAX_PATH] = {0}; + bool hadError = false; + + char theexename[MAX_PATH]; + GetModuleFileName(NULL, theexename, MAX_PATH); + + MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrTemp, MAX_PATH); + BSTR bstrGDFBinPath = SysAllocString(wstrTemp); + + char gameDirectory[MAX_PATH]; + strcpy(gameDirectory, theexename); + strrchr(gameDirectory, '\\')[0] = 0; + + MultiByteToWideChar(CP_ACP, 0, gameDirectory, MAX_PATH, wstrTemp, MAX_PATH); + BSTR bstrGameDirectory = SysAllocString(wstrTemp); + + HRESULT hr = pFwGameExplorer->AddGame(bstrGDFBinPath, bstrGameDirectory, allUsers ? GIS_ALL_USERS : GIS_CURRENT_USER, guid); + if ((FAILED(hr)) || (hr == S_FALSE)) + { + if (hr == 0x80070715) + { + // No GDF XML -- do nothing. This means the game was compiled + // without Game Explorer support. + hadError = true; + } + else + { + // Game already exists or error + HRESULT updateHr = pFwGameExplorer->UpdateGame(*guid); + if (FAILED(updateHr)) + { + this->DisplayAlert("Failed to add the game to the game explorer: %08X, %08X", hr, updateHr); + hadError = true; + } + } + } + else + { + add_tasks_for_game(guidAsText, theexename, gameDirectory, allUsers); + } + + BOOL bHasAccess = FALSE; + hr = pFwGameExplorer->VerifyAccess( bstrGDFBinPath, &bHasAccess ); + + if (( FAILED(hr) || !bHasAccess ) && (!hadError)) + { + this->DisplayAlert("Windows Parental Controls will not allow you to run this game."); + } + + SysFreeString(bstrGDFBinPath); + SysFreeString(bstrGameDirectory); +} + +#define FA_SEARCH -1 +void delete_files_in_directory(const char *directoryName, const char *fileMask) +{ + char srchBuffer[MAX_PATH]; + sprintf(srchBuffer, "%s\\%s", directoryName, fileMask); + al_ffblk dfb; + int dun = al_findfirst(srchBuffer, &dfb, FA_SEARCH); + while (!dun) { + ::remove(dfb.name); + dun = al_findnext(&dfb); + } + al_findclose(&dfb); +} + +void AGSWin32::remove_game_from_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) +{ + HRESULT hr = pFwGameExplorer->RemoveGame(*guid); + if (FAILED(hr)) + { + this->DisplayAlert("Failed to un-register game: 0x%08X", hr); + } +} + +void AGSWin32::update_game_explorer(bool add) +{ + IGameExplorer* pFwGameExplorer = NULL; + + CoInitialize(NULL); + // Create an instance of the Game Explorer Interface + HRESULT hr = CoCreateInstance( __uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void**)&pFwGameExplorer); + if( FAILED(hr) || pFwGameExplorer == NULL ) + { + Debug::Printf(kDbgMsg_Warn, "Game Explorer not found to register game, Windows Vista required"); + } + else + { + ags_strupr(game.guid); + WCHAR wstrTemp[MAX_PATH] = {0}; + GUID guid = GUID_NULL; + MultiByteToWideChar(CP_ACP, 0, game.guid, MAX_GUID_LENGTH, wstrTemp, MAX_GUID_LENGTH); + if (IIDFromString(wstrTemp, &guid) != S_OK) + { + this->DisplayAlert("Failed to register game: IIDFromString failed"); + } + else if (add) + { + add_game_to_game_explorer(pFwGameExplorer, &guid, game.guid, true); + } + else + { + remove_game_from_game_explorer(pFwGameExplorer, &guid, game.guid, true); + } + } + + if( pFwGameExplorer ) pFwGameExplorer->Release(); + CoUninitialize(); +} + +void AGSWin32::unregister_file_extension() +{ + char keyname[MAX_PATH]; + sprintf(keyname, ".%s", game.saveGameFileExtension); + if (SHDeleteKey(HKEY_CLASSES_ROOT, keyname) != ERROR_SUCCESS) + { + this->DisplayAlert("Unable to un-register the file extension. Make sure you are running this with admin rights."); + return; + } + + sprintf(keyname, "AGS.SaveGames.%s", game.saveGameFileExtension); + SHDeleteKey(HKEY_CLASSES_ROOT, keyname); + + sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension); + SHDeleteKey(HKEY_LOCAL_MACHINE, keyname); + + // Tell Explorer to refresh its file association data + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); +} + +void AGSWin32::register_file_extension(const char *exePath) +{ + DWORD valType, valBufLen = MAX_PATH; + valType = REG_SZ; + char valBuf[MAX_PATH], keyname[MAX_PATH]; + char saveGameRegistryType[MAX_PATH]; + sprintf(saveGameRegistryType, "AGS.SaveGames.%s", game.saveGameFileExtension); + + // write HKEY_CLASSES_ROOT\.Extension = AGS.SaveGames.Extension + strcpy(valBuf, saveGameRegistryType); + sprintf(keyname, ".%s", game.saveGameFileExtension); + if (RegSetValue(HKEY_CLASSES_ROOT, keyname, valType, valBuf, valBufLen)) + { + this->DisplayAlert("Unable to register file type. Make sure you are running this with Administrator rights."); + return; + } + + // create HKEY_CLASSES_ROOT\AGS.SaveGames.Extension + strcpy(keyname, saveGameRegistryType); + sprintf(valBuf, "%s Saved Game", game.gamename); + RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\DefaultIcon + sprintf(keyname, "%s\\DefaultIcon", saveGameRegistryType); + sprintf(valBuf, "\"%s\", 0", exePath); + RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\Shell\Open\Command + sprintf(keyname, "%s\\Shell\\Open\\Command", saveGameRegistryType); + sprintf(valBuf, "\"%s\" -loadSavedGame \"%%1\"", exePath); + RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // ** BELOW IS VISTA-ONLY + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewTitle + strcpy(keyname, saveGameRegistryType); + strcpy(valBuf, "prop:System.Game.RichSaveName;System.Game.RichApplicationName"); + SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewTitle", REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewDetails + strcpy(keyname, saveGameRegistryType); + strcpy(valBuf, "prop:System.Game.RichLevel;System.DateChanged;System.Game.RichComment;System.DisplayName;System.DisplayType"); + SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewDetails", REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\.Extension\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1} + sprintf(keyname, ".%s\\ShellEx\\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}", game.saveGameFileExtension); + strcpy(valBuf, "{4E5BFBF8-F59A-4E87-9805-1F9B42CC254A}"); + RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.Extension + sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension); + strcpy(valBuf, "{ECDD6472-2B9B-4B4B-AE36-F316DF3C8D60}"); + RegSetValue (HKEY_LOCAL_MACHINE, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // Tell Explorer to refresh its file association data + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); +} + +void AGSWin32::RegisterGameWithGameExplorer() +{ + update_game_explorer(true); + + if (game.saveGameFileExtension[0] != 0) + { + char theexename[MAX_PATH]; + GetModuleFileName(NULL, theexename, MAX_PATH); + + register_file_extension(theexename); + } +} + +void AGSWin32::UnRegisterGameWithGameExplorer() +{ + update_game_explorer(false); + + if (game.saveGameFileExtension[0] != 0) + { + unregister_file_extension(); + } +} + +void AGSWin32::PostAllegroInit(bool windowed) +{ + check_parental_controls(); + + // Set the Windows timer resolution to 1 ms so that calls to + // Sleep() don't take more time than specified + MMRESULT result = timeBeginPeriod(win32TimerPeriod); + if (result != TIMERR_NOERROR) + Debug::Printf(kDbgMsg_Error, "Failed to set the timer resolution to %d ms", win32TimerPeriod); +} + +typedef UINT (CALLBACK* Dynamic_SHGetKnownFolderPathType) (GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); +GUID FOLDERID_SAVEDGAMES = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}}; +#define _WIN32_WINNT_VISTA 0x0600 +#define VER_MINORVERSION 0x0000001 +#define VER_MAJORVERSION 0x0000002 +#define VER_SERVICEPACKMAJOR 0x0000020 +#define VER_GREATER_EQUAL 3 + +// These helpers copied from VersionHelpers.h in the Windows 8.1 SDK +bool IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +bool IsWindowsVistaOrGreater() { + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +void determine_app_data_folder() +{ + if (win32AppDataDirectory[0] != 0) + { + // already discovered + return; + } + + WCHAR unicodePath[MAX_PATH]; + WCHAR unicodeShortPath[MAX_PATH]; + SHGetSpecialFolderPathW(NULL, unicodePath, CSIDL_COMMON_APPDATA, FALSE); + if (GetShortPathNameW(unicodePath, unicodeShortPath, MAX_PATH) == 0) + { + platform->DisplayAlert("Unable to get App Data dir: GetShortPathNameW failed"); + return; + } + WideCharToMultiByte(CP_ACP, 0, unicodeShortPath, -1, win32AppDataDirectory, MAX_PATH, NULL, NULL); + + strcat(win32AppDataDirectory, "\\Adventure Game Studio"); + mkdir(win32AppDataDirectory); +} + +void determine_saved_games_folder() +{ + if (win32SavedGamesDirectory[0] != 0) + { + // already discovered + return; + } + + WCHAR unicodeSaveGameDir[MAX_PATH] = L""; + WCHAR unicodeShortSaveGameDir[MAX_PATH] = L""; + + if (IsWindowsVistaOrGreater()) + { + HINSTANCE hShellDLL = LoadLibrary("shell32.dll"); + Dynamic_SHGetKnownFolderPathType Dynamic_SHGetKnownFolderPath = (Dynamic_SHGetKnownFolderPathType)GetProcAddress(hShellDLL, "SHGetKnownFolderPath"); + + if (Dynamic_SHGetKnownFolderPath != NULL) + { + PWSTR path = NULL; + if (SUCCEEDED(Dynamic_SHGetKnownFolderPath(FOLDERID_SAVEDGAMES, 0, NULL, &path))) + { + if (GetShortPathNameW(path, unicodeShortSaveGameDir, MAX_PATH) > 0) { + WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL); + } + CoTaskMemFree(path); + } + } + + FreeLibrary(hShellDLL); + } + else + { + // Windows XP didn't have a "My Saved Games" folder, so create one under "My Documents" + SHGetSpecialFolderPathW(NULL, unicodeSaveGameDir, CSIDL_PERSONAL, FALSE); + // workaround for case where My Documents path has unicode chars (eg. + // with Russian Windows) -- so use Short File Name instead + if (GetShortPathNameW(unicodeSaveGameDir, unicodeShortSaveGameDir, MAX_PATH) > 0) + { + WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL); + strcat(win32SavedGamesDirectory, "\\My Saved Games"); + mkdir(win32SavedGamesDirectory); + } + } + + // Fallback to a subdirectory of the app data directory + if (win32SavedGamesDirectory[0] == '\0') + { + determine_app_data_folder(); + strcpy(win32SavedGamesDirectory, win32AppDataDirectory); + strcat(win32SavedGamesDirectory, "\\Saved Games"); + mkdir(win32SavedGamesDirectory); + } +} + +void DetermineAppOutputDirectory() +{ + if (!win32OutputDirectory.IsEmpty()) + { + return; + } + + determine_saved_games_folder(); + bool log_to_saves_dir = false; + if (win32SavedGamesDirectory[0]) + { + win32OutputDirectory = win32SavedGamesDirectory; + win32OutputDirectory.Append("\\.ags"); + log_to_saves_dir = mkdir(win32OutputDirectory) == 0 || errno == EEXIST; + } + + if (!log_to_saves_dir) + { + char theexename[MAX_PATH + 1] = {0}; + GetModuleFileName(NULL, theexename, MAX_PATH); + PathRemoveFileSpec(theexename); + win32OutputDirectory = theexename; + } +} + +const char* AGSWin32::GetAllUsersDataDirectory() +{ + determine_app_data_folder(); + return &win32AppDataDirectory[0]; +} + +const char *AGSWin32::GetUserSavedgamesDirectory() +{ + determine_saved_games_folder(); + return win32SavedGamesDirectory; +} + +const char *AGSWin32::GetUserConfigDirectory() +{ + determine_saved_games_folder(); + return win32SavedGamesDirectory; +} + +const char *AGSWin32::GetUserGlobalConfigDirectory() +{ + DetermineAppOutputDirectory(); + return win32OutputDirectory; +} + +const char *AGSWin32::GetAppOutputDirectory() +{ + DetermineAppOutputDirectory(); + return win32OutputDirectory; +} + +const char *AGSWin32::GetIllegalFileChars() +{ + return "\\/:?\"<>|*"; +} + +const char *AGSWin32::GetGraphicsTroubleshootingText() +{ + return "\n\nPossible causes:\n" + "* your graphics card drivers do not support requested resolution. " + "Run the game setup program and try another resolution.\n" + "* the graphics driver you have selected does not work. Try switching to another graphics driver.\n" + "* the graphics filter you have selected does not work. Try another filter.\n" + "* your graphics card drivers are out of date. " + "Try downloading updated graphics card drivers from your manufacturer's website.\n" + "* there is a problem with your graphics card driver configuration. " + "Run DXDiag using the Run command (Start->Run, type \"dxdiag.exe\") and correct any problems reported there."; +} + +void AGSWin32::DisplaySwitchOut() +{ + // If we have explicitly set up fullscreen mode then minimize the window + if (_preFullscreenMode.IsValid()) + ShowWindow(win_get_window(), SW_MINIMIZE); +} + +void AGSWin32::DisplaySwitchIn() { + // If we have explicitly set up fullscreen mode then restore the window + if (_preFullscreenMode.IsValid()) + ShowWindow(win_get_window(), SW_RESTORE); +} + +void AGSWin32::PauseApplication() +{ +#ifndef AGS_NO_VIDEO_PLAYER + dxmedia_pause_video(); +#endif +} + +void AGSWin32::ResumeApplication() +{ +#ifndef AGS_NO_VIDEO_PLAYER + dxmedia_resume_video(); +#endif +} + +void AGSWin32::GetSystemDisplayModes(std::vector &dms) +{ + dms.clear(); + GFX_MODE_LIST *gmlist = get_gfx_mode_list(GFX_DIRECTX); + for (int i = 0; i < gmlist->num_modes; ++i) + { + const GFX_MODE &m = gmlist->mode[i]; + dms.push_back(DisplayMode(GraphicResolution(m.width, m.height, m.bpp))); + } + destroy_gfx_mode_list(gmlist); +} + +bool AGSWin32::SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen) +{ + DEVMODE devmode; + memset(&devmode, 0, sizeof(devmode)); + devmode.dmSize = sizeof(devmode); + devmode.dmPelsWidth = dm.Width; + devmode.dmPelsHeight = dm.Height; + devmode.dmBitsPerPel = dm.ColorDepth; + devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + return ChangeDisplaySettings(&devmode, fullscreen ? CDS_FULLSCREEN : 0) == DISP_CHANGE_SUCCESSFUL; +} + +bool AGSWin32::EnterFullscreenMode(const DisplayMode &dm) +{ + // Remember current mode + get_desktop_resolution(&_preFullscreenMode.Width, &_preFullscreenMode.Height); + _preFullscreenMode.ColorDepth = desktop_color_depth(); + + // Set requested desktop mode + return SetSystemDisplayMode(dm, true); +} + +bool AGSWin32::ExitFullscreenMode() +{ + if (!_preFullscreenMode.IsValid()) + return false; + + DisplayMode dm = _preFullscreenMode; + _preFullscreenMode = DisplayMode(); + return SetSystemDisplayMode(dm, false); +} + +void AGSWin32::AdjustWindowStyleForFullscreen() +{ + // Remove the border in full-screen mode + Size sz; + get_desktop_resolution(&sz.Width, &sz.Height); + HWND allegro_wnd = win_get_window(); + LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE); + SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_OVERLAPPEDWINDOW) | WS_POPUP); + SetWindowPos(allegro_wnd, HWND_TOP, 0, 0, sz.Width, sz.Height, 0); +} + +void AGSWin32::AdjustWindowStyleForWindowed() +{ + // Make a regular window with a border + HWND allegro_wnd = win_get_window(); + LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE); + SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_POPUP) | (WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX)); + // Make window go on top, but at the same time remove WS_EX_TOPMOST style (applied by Direct3D fullscreen mode) + SetWindowPos(allegro_wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); +} + +int AGSWin32::CDPlayerCommand(int cmdd, int datt) { +#if defined (AGS_HAS_CD_AUDIO) + return cd_player_control(cmdd, datt); +#else + return -1; +#endif +} + +void AGSWin32::AttachToParentConsole() { + if (_isAttachedToParentConsole) + return; + + _isAttachedToParentConsole = ::AttachConsole(ATTACH_PARENT_PROCESS) != FALSE; + if (_isAttachedToParentConsole) + { + // Require that both STDOUT and STDERR are valid handles from the parent process. + if (::GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE && + ::GetStdHandle(STD_ERROR_HANDLE) != INVALID_HANDLE_VALUE) + { + // Re-open STDOUT and STDERR to the parent's. + FILE* fp = NULL; + freopen_s(&fp, "CONOUT$", "w", stdout); + setvbuf(stdout, NULL, _IONBF, 0); + + freopen_s(&fp, "CONOUT$", "w", stderr); + setvbuf(stderr, NULL, _IONBF, 0); + } + else + { + ::FreeConsole(); + _isAttachedToParentConsole = false; + } + } +} + +void AGSWin32::DisplayAlert(const char *text, ...) { + char displbuf[2500]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + if (_guiMode) + MessageBox(win_get_window(), displbuf, "Adventure Game Studio", MB_OK | MB_ICONEXCLAMATION); + + // Always write to either stderr or stdout, even if message boxes are enabled. + if (_logToStdErr) + AGSWin32::WriteStdErr("%s", displbuf); + else + AGSWin32::WriteStdOut("%s", displbuf); +} + +int AGSWin32::GetLastSystemError() +{ + return ::GetLastError(); +} + +unsigned long AGSWin32::GetDiskFreeSpaceMB() { + DWORD returnMb = 0; + BOOL fResult; + our_eip = -1891; + + // On Win9x, the last 3 params cannot be null, so need to supply values for all + __int64 i64FreeBytesToCaller, i64Unused1, i64Unused2; + + // Win95 OSR2 or higher - use GetDiskFreeSpaceEx, since the + // normal GetDiskFreeSpace returns erroneous values if the + // free space is > 2 GB + fResult = GetDiskFreeSpaceEx(NULL, + (PULARGE_INTEGER)&i64FreeBytesToCaller, + (PULARGE_INTEGER)&i64Unused1, + (PULARGE_INTEGER)&i64Unused2); + + our_eip = -1893; + + // convert down to MB so we can fit it in a 32-bit long + i64FreeBytesToCaller /= 1000000; + returnMb = i64FreeBytesToCaller; + + return returnMb; +} + +const char* AGSWin32::GetNoMouseErrorString() { + return "No mouse was detected on your system, or your mouse is not configured to work with DirectInput. You must have a mouse to play this game."; +} + +bool AGSWin32::IsMouseControlSupported(bool windowed) +{ + return true; // supported for both fullscreen and windowed modes +} + +const char* AGSWin32::GetAllegroFailUserHint() +{ + return "Make sure you have DirectX 5 or above installed."; +} + +eScriptSystemOSID AGSWin32::GetSystemOSID() { + return eOS_Win; +} + +int AGSWin32::InitializeCDPlayer() { +#if defined (AGS_HAS_CD_AUDIO) + return cd_player_init(); +#else + return -1; +#endif +} + +#ifndef AGS_NO_VIDEO_PLAYER + +void AGSWin32::PlayVideo(const char *name, int skip, int flags) { + + char useloc[250]; + sprintf(useloc, "%s\\%s", ResPaths.DataDir.GetCStr(), name); + + bool useSound = true; + if (flags >= 10) { + flags -= 10; + useSound = false; + } + else { + // for some reason DirectSound can't be shared, so uninstall + // allegro sound before playing the video + shutdown_sound(); + } + + bool isError = false; + if (Common::File::TestReadFile(useloc)) + { + isError = (gfxDriver->PlayVideo(useloc, useSound, (VideoSkipType)skip, (flags > 0)) == 0); + } + else + { + isError = true; + sprintf(lastError, "File not found: %s", useloc); + } + + if (isError) { + // turn "Always display as speech" off, to make sure error + // gets displayed correctly + int oldalways = game.options[OPT_ALWAYSSPCH]; + game.options[OPT_ALWAYSSPCH] = 0; + Display("Video playing error: %s", lastError); + game.options[OPT_ALWAYSSPCH] = oldalways; + } + + if (useSound) + { + // Restore sound system + install_sound(usetup.digicard,usetup.midicard,NULL); + if (usetup.mod_player) + init_mod_player(NUM_MOD_DIGI_VOICES); + } + + set_palette_range(palette, 0, 255, 0); +} + +#endif + +void AGSWin32::AboutToQuitGame() +{ +#ifndef AGS_NO_VIDEO_PLAYER + dxmedia_abort_video(); +#endif +} + +void AGSWin32::PostAllegroExit() { + // Release the timer setting + timeEndPeriod(win32TimerPeriod); +} + +SetupReturnValue AGSWin32::RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out) +{ + String version_str = String::FromFormat("Adventure Game Studio v%s setup", get_engine_version()); + return AGS::Engine::WinSetup(cfg_in, cfg_out, usetup.data_files_dir, version_str); +} + +void AGSWin32::SetGameWindowIcon() { + SetWinIcon(); +} + +void AGSWin32::WriteStdOut(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + if (_isDebuggerPresent) + { + // Add "AGS:" prefix when outputting to debugger, to make it clear that this + // is a text from the program log + char buf[STD_BUFFER_SIZE] = "AGS: "; + vsnprintf(buf + 5, STD_BUFFER_SIZE - 5, fmt, ap); + OutputDebugString(buf); + OutputDebugString("\n"); + } + else + { + vprintf(fmt, ap); + printf("\n"); + } + va_end(ap); +} + +void AGSWin32::WriteStdErr(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + if (_isDebuggerPresent) + { + // Add "AGS:" prefix when outputting to debugger, to make it clear that this + // is a text from the program log + char buf[STD_BUFFER_SIZE] = "AGS ERR: "; + vsnprintf(buf + 9, STD_BUFFER_SIZE - 9, fmt, ap); + OutputDebugString(buf); + OutputDebugString("\n"); + } + else + { + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + } + va_end(ap); +} + +void AGSWin32::ShutdownCDPlayer() { + cd_exit(); +} + +extern "C" const unsigned char hw_to_mycode[256]; + +int AGSWin32::ConvertKeycodeToScanCode(int keycode) +{ + // ** HIDEOUS HACK TO WORK AROUND ALLEGRO BUG + // the key[] array is hardcoded to qwerty keyboards, so we + // have to re-map it to make it work on other keyboard layouts + keycode += ('a' - 'A'); + int vkey = VkKeyScan(keycode); + int scancode = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + if ((scancode >= 0) && (scancode < 256)) + keycode = hw_to_mycode[scancode]; + return keycode; +} + +void AGSWin32::ValidateWindowSize(int &x, int &y, bool borderless) const +{ + RECT wa_rc, nc_rc; + // This is the size of the available workspace on user's desktop + SystemParametersInfo(SPI_GETWORKAREA, 0, &wa_rc, 0); + // This is the maximal size that OS can reliably resize the window to (including any frame) + const Size max_win(GetSystemMetrics(SM_CXMAXTRACK), GetSystemMetrics(SM_CYMAXTRACK)); + // This is the size of window's non-client area (frame, caption, etc) + HWND allegro_wnd = win_get_window(); + LONG winstyle = borderless ? WS_POPUP : WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX; + LONG winstyle_al = GetWindowLong(allegro_wnd, GWL_STYLE); + SetRectEmpty(&nc_rc); + AdjustWindowRect(&nc_rc, winstyle, FALSE); + // Limit the window's full size to the system's window size limit, + // and limit window's client size to the work space (visible area) + x = Math::Min(x, (int)(max_win.Width - (nc_rc.right - nc_rc.left))); + y = Math::Min(y, (int)(max_win.Height - (nc_rc.bottom - nc_rc.top))); + x = Math::Clamp(x, 1, (int)(wa_rc.right - wa_rc.left)); + y = Math::Clamp(y, 1, (int)(wa_rc.bottom - wa_rc.top)); +} + +bool AGSWin32::LockMouseToWindow() +{ + RECT rc; + HWND allegro_wnd = win_get_window(); + GetClientRect(allegro_wnd, &rc); + ClientToScreen(allegro_wnd, (POINT*)&rc); + ClientToScreen(allegro_wnd, (POINT*)&rc.right); + --rc.right; + --rc.bottom; + return ::ClipCursor(&rc) != 0; +} + +void AGSWin32::UnlockMouse() +{ + ::ClipCursor(NULL); +} + +AGSPlatformDriver* AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSWin32(); + return instance; +} + + +// *********** WINDOWS-SPECIFIC PLUGIN API FUNCTIONS ************* + +HWND IAGSEngine::GetWindowHandle () { + return win_get_window(); +} +LPDIRECTDRAW2 IAGSEngine::GetDirectDraw2 () { + if (directdraw == NULL) + quit("!This plugin requires DirectDraw based graphics driver (software driver)."); + + return directdraw; +} +LPDIRECTDRAWSURFACE2 IAGSEngine::GetBitmapSurface (BITMAP *bmp) +{ + if (directdraw == NULL) + quit("!This plugin requires DirectDraw based graphics driver (software driver)."); + + BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO*)bmp->extra; + + if (bmp == gfxDriver->GetMemoryBackBuffer()->GetAllegroBitmap()) + invalidate_screen(); + + return bei->surf; +} + +LPDIRECTSOUND IAGSEngine::GetDirectSound() { + return directsound; +} + +LPDIRECTINPUTDEVICE IAGSEngine::GetDirectInputKeyboard() { + return key_dinput_device; +} + +LPDIRECTINPUTDEVICE IAGSEngine::GetDirectInputMouse() { + return mouse_dinput_device; +} + +#endif diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp new file mode 100644 index 000000000000..b96a10c798ba --- /dev/null +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -0,0 +1,2090 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Allegro Interface for 3D; Direct 3D 9 driver +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS + +#include "platform/windows/gfx/ali3dd3d.h" + +#include +#include +#include "ac/timer.h" +#include "debug/assert.h" +#include "debug/out.h" +#include "gfx/ali3dexception.h" +#include "gfx/gfxfilter_d3d.h" +#include "gfx/gfxfilter_aad3d.h" +#include "gfx/gfx_util.h" +#include "main/main_allegro.h" +#include "platform/base/agsplatformdriver.h" +#include "util/library.h" + +#ifndef AGS_NO_VIDEO_PLAYER +extern int dxmedia_play_video_3d(const char*filename, IDirect3DDevice9 *device, bool useAVISound, int canskip, int stretch); +extern void dxmedia_shutdown_3d(); +#endif + +using namespace AGS::Common; + +// Necessary to update textures from 8-bit bitmaps +extern RGB palette[256]; + +// +// Following functions implement various matrix operations. Normally they are found in the auxiliary d3d9x.dll, +// but we do not want AGS to be dependent on it. +// +// Setup identity matrix +void MatrixIdentity(D3DMATRIX &m) +{ + m = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; +} +// Setup translation matrix +void MatrixTranslate(D3DMATRIX &m, float x, float y, float z) +{ + MatrixIdentity(m); + m.m[3][0] = x; + m.m[3][1] = y; + m.m[3][2] = z; +} +// Setup scaling matrix +void MatrixScale(D3DMATRIX &m, float sx, float sy, float sz) +{ + MatrixIdentity(m); + m.m[0][0] = sx; + m.m[1][1] = sy; + m.m[2][2] = sz; +} +// Setup rotation around Z axis; angle is in radians +void MatrixRotateZ(D3DMATRIX &m, float angle) +{ + MatrixIdentity(m); + m.m[0][0] = cos(angle); + m.m[1][1] = cos(angle); + m.m[0][1] = sin(angle); + m.m[1][0] = -sin(angle); +} +// Matrix multiplication +void MatrixMultiply(D3DMATRIX &mr, const D3DMATRIX &m1, const D3DMATRIX &m2) +{ + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + mr.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j]; +} +// Setup full 2D transformation matrix +void MatrixTransform2D(D3DMATRIX &m, float x, float y, float sx, float sy, float anglez) +{ + D3DMATRIX translate; + D3DMATRIX rotate; + D3DMATRIX scale; + MatrixTranslate(translate, x, y, 0.f); + MatrixRotateZ(rotate, anglez); + MatrixScale(scale, sx, sy, 1.f); + + D3DMATRIX tr1; + MatrixMultiply(tr1, scale, rotate); + MatrixMultiply(m, tr1, translate); +} +// Setup inverse 2D transformation matrix +void MatrixTransformInverse2D(D3DMATRIX &m, float x, float y, float sx, float sy, float anglez) +{ + D3DMATRIX translate; + D3DMATRIX rotate; + D3DMATRIX scale; + MatrixTranslate(translate, x, y, 0.f); + MatrixRotateZ(rotate, anglez); + MatrixScale(scale, sx, sy, 1.f); + + D3DMATRIX tr1; + MatrixMultiply(tr1, translate, rotate); + MatrixMultiply(m, tr1, scale); +} + + +namespace AGS +{ +namespace Engine +{ +namespace D3D +{ + +using namespace Common; + +void D3DBitmap::Dispose() +{ + if (_tiles != NULL) + { + for (int i = 0; i < _numTiles; i++) + _tiles[i].texture->Release(); + + free(_tiles); + _tiles = NULL; + _numTiles = 0; + } + if (_vertex != NULL) + { + _vertex->Release(); + _vertex = NULL; + } +} + +static D3DFORMAT color_depth_to_d3d_format(int color_depth, bool wantAlpha); +static int d3d_format_to_color_depth(D3DFORMAT format, bool secondary); + +bool D3DGfxModeList::GetMode(int index, DisplayMode &mode) const +{ + if (_direct3d && index >= 0 && index < _modeCount) + { + D3DDISPLAYMODE d3d_mode; + if (SUCCEEDED(_direct3d->EnumAdapterModes(D3DADAPTER_DEFAULT, _pixelFormat, index, &d3d_mode))) + { + mode.Width = d3d_mode.Width; + mode.Height = d3d_mode.Height; + mode.ColorDepth = d3d_format_to_color_depth(d3d_mode.Format, false); + mode.RefreshRate = d3d_mode.RefreshRate; + return true; + } + } + return false; +} + + +void dummy_vsync() { } + +#define GFX_DIRECT3D_WIN AL_ID('D','X','3','W') +#define GFX_DIRECT3D_FULL AL_ID('D','X','3','D') + +GFX_DRIVER gfx_direct3d_win = +{ + GFX_DIRECT3D_WIN, + empty_string, + empty_string, + "Direct3D windowed", + NULL, // init + NULL, // exit + NULL, // AL_METHOD(int, scroll, (int x, int y)); + dummy_vsync, // vsync + NULL, // setpalette + NULL, // AL_METHOD(int, request_scroll, (int x, int y)); + NULL, // AL_METHOD(int, poll_scroll, (void)); + NULL, // AL_METHOD(void, enable_triple_buffer, (void)); + NULL, //create_video_bitmap + NULL, //destroy_video_bitmap + NULL, //show_video_bitmap + NULL, + NULL, //gfx_directx_create_system_bitmap, + NULL, //gfx_directx_destroy_system_bitmap, + NULL, //gfx_directx_set_mouse_sprite, + NULL, //gfx_directx_show_mouse, + NULL, //gfx_directx_hide_mouse, + NULL, //gfx_directx_move_mouse, + NULL, // AL_METHOD(void, drawing_mode, (void)); + NULL, // AL_METHOD(void, save_video_state, (void*)); + NULL, // AL_METHOD(void, restore_video_state, (void*)); + NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); + NULL, // AL_METHOD(int, fetch_mode_list, (void)); + 0, 0, // int w, h; + FALSE, // int linear; + 0, // long bank_size; + 0, // long bank_gran; + 0, // long vid_mem; + 0, // long vid_phys_base; + TRUE // int windowed; +}; + +GFX_DRIVER gfx_direct3d_full = +{ + GFX_DIRECT3D_FULL, + empty_string, + empty_string, + "Direct3D fullscreen", + NULL, // init + NULL, // exit + NULL, // AL_METHOD(int, scroll, (int x, int y)); + dummy_vsync, // sync + NULL, // setpalette + NULL, // AL_METHOD(int, request_scroll, (int x, int y)); + NULL, // AL_METHOD(int, poll_scroll, (void)); + NULL, // AL_METHOD(void, enable_triple_buffer, (void)); + NULL, //create_video_bitmap + NULL, //destroy_video_bitmap + NULL, //show_video_bitmap + NULL, + NULL, //gfx_directx_create_system_bitmap, + NULL, //gfx_directx_destroy_system_bitmap, + NULL, //gfx_directx_set_mouse_sprite, + NULL, //gfx_directx_show_mouse, + NULL, //gfx_directx_hide_mouse, + NULL, //gfx_directx_move_mouse, + NULL, // AL_METHOD(void, drawing_mode, (void)); + NULL, // AL_METHOD(void, save_video_state, (void*)); + NULL, // AL_METHOD(void, restore_video_state, (void*)); + NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); + NULL, // AL_METHOD(int, fetch_mode_list, (void)); + 0, 0, // int w, h; + FALSE, // int linear; + 0, // long bank_size; + 0, // long bank_gran; + 0, // long vid_mem; + 0, // long vid_phys_base; + FALSE // int windowed; +}; + +// The custom FVF, which describes the custom vertex structure. +#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1) + +static int wnd_create_device(); +// TODO: is there better way to not have this mode as a global static variable? +// wnd_create_device() is being called using wnd_call_proc, which does not take +// user parameters. +static DisplayMode d3d_mode_to_init; + +D3DGraphicsDriver::D3DGraphicsDriver(IDirect3D9 *d3d) +{ + direct3d = d3d; + direct3ddevice = NULL; + vertexbuffer = NULL; + pixelShader = NULL; + _legacyPixelShader = false; + set_up_default_vertices(); + pNativeSurface = NULL; + pNativeTexture = NULL; + availableVideoMemory = 0; + _smoothScaling = false; + _pixelRenderXOffset = 0; + _pixelRenderYOffset = 0; + _renderSprAtScreenRes = false; + + // Shifts comply to D3DFMT_A8R8G8B8 + _vmem_a_shift_32 = 24; + _vmem_r_shift_32 = 16; + _vmem_g_shift_32 = 8; + _vmem_b_shift_32 = 0; + + // Initialize default sprite batch, it will be used when no other batch was activated + D3DGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); +} + +void D3DGraphicsDriver::set_up_default_vertices() +{ + defaultVertices[0].position.x = 0.0f; + defaultVertices[0].position.y = 0.0f; + defaultVertices[0].position.z = 0.0f; + defaultVertices[0].normal.x = 0.0f; + defaultVertices[0].normal.y = 0.0f; + defaultVertices[0].normal.z = -1.0f; + //defaultVertices[0].color=0xffffffff; + defaultVertices[0].tu=0.0; + defaultVertices[0].tv=0.0; + defaultVertices[1].position.x = 1.0f; + defaultVertices[1].position.y = 0.0f; + defaultVertices[1].position.z = 0.0f; + defaultVertices[1].normal.x = 0.0f; + defaultVertices[1].normal.y = 0.0f; + defaultVertices[1].normal.z = -1.0f; + //defaultVertices[1].color=0xffffffff; + defaultVertices[1].tu=1.0; + defaultVertices[1].tv=0.0; + defaultVertices[2].position.x = 0.0f; + defaultVertices[2].position.y = -1.0f; + defaultVertices[2].position.z = 0.0f; + defaultVertices[2].normal.x = 0.0f; + defaultVertices[2].normal.y = 0.0f; + defaultVertices[2].normal.z = -1.0f; + //defaultVertices[2].color=0xffffffff; + defaultVertices[2].tu=0.0; + defaultVertices[2].tv=1.0; + defaultVertices[3].position.x = 1.0f; + defaultVertices[3].position.y = -1.0f; + defaultVertices[3].position.z = 0.0f; + defaultVertices[3].normal.x = 0.0f; + defaultVertices[3].normal.y = 0.0f; + defaultVertices[3].normal.z = -1.0f; + //defaultVertices[3].color=0xffffffff; + defaultVertices[3].tu=1.0; + defaultVertices[3].tv=1.0; +} + +void D3DGraphicsDriver::Vsync() +{ + // do nothing on D3D +} + +void D3DGraphicsDriver::OnModeSet(const DisplayMode &mode) +{ + GraphicsDriverBase::OnModeSet(mode); + + // The display mode has been set up successfully, save the + // final refresh rate that we are using + D3DDISPLAYMODE final_display_mode; + if (direct3ddevice->GetDisplayMode(0, &final_display_mode) == D3D_OK) { + _mode.RefreshRate = final_display_mode.RefreshRate; + } + else { + _mode.RefreshRate = 0; + } +} + +void D3DGraphicsDriver::ReleaseDisplayMode() +{ + if (!IsModeSet()) + return; + + OnModeReleased(); + ClearDrawLists(); + ClearDrawBackups(); + DestroyFxPool(); + DestroyAllStageScreens(); + + gfx_driver = NULL; +} + +int D3DGraphicsDriver::FirstTimeInit() +{ + HRESULT hr; + + direct3ddevice->GetDeviceCaps(&direct3ddevicecaps); + + // the PixelShader.fx uses ps_1_4 + // the PixelShaderLegacy.fx needs ps_2_0 + int requiredPSMajorVersion = 1; + int requiredPSMinorVersion = 4; + if (_legacyPixelShader) { + requiredPSMajorVersion = 2; + requiredPSMinorVersion = 0; + } + + if (direct3ddevicecaps.PixelShaderVersion < D3DPS_VERSION(requiredPSMajorVersion, requiredPSMinorVersion)) + { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = + set_allegro_error("Graphics card does not support Pixel Shader %d.%d", requiredPSMajorVersion, requiredPSMinorVersion); + return -1; + } + + // Load the pixel shader!! + HMODULE exeHandle = GetModuleHandle(NULL); + HRSRC hRes = FindResource(exeHandle, (_legacyPixelShader) ? "PIXEL_SHADER_LEGACY" : "PIXEL_SHADER", "DATA"); + if (hRes) + { + HGLOBAL hGlobal = LoadResource(exeHandle, hRes); + if (hGlobal) + { + DWORD resourceSize = SizeofResource(exeHandle, hRes); + DWORD *dataPtr = (DWORD*)LockResource(hGlobal); + hr = direct3ddevice->CreatePixelShader(dataPtr, &pixelShader); + if (hr != D3D_OK) + { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = set_allegro_error("Failed to create pixel shader: 0x%08X", hr); + return -1; + } + UnlockResource(hGlobal); + } + } + + if (pixelShader == NULL) + { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = set_allegro_error("Failed to load pixel shader resource"); + return -1; + } + + if (direct3ddevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, + D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &vertexbuffer, NULL) != D3D_OK) + { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = set_allegro_error("Failed to create vertex buffer"); + return -1; + } + + // This line crashes because my card doesn't support 8-bit textures + //direct3ddevice->SetCurrentTexturePalette(0); + + CUSTOMVERTEX *vertices; + vertexbuffer->Lock(0, 0, (void**)&vertices, D3DLOCK_DISCARD); + + for (int i = 0; i < 4; i++) + { + vertices[i] = defaultVertices[i]; + } + + vertexbuffer->Unlock(); + + direct3ddevice->GetGammaRamp(0, &defaultgammaramp); + + if (defaultgammaramp.red[255] < 256) + { + // correct bug in some gfx drivers that returns gamma ramp + // values from 0-255 instead of 0-65535 + for (int i = 0; i < 256; i++) + { + defaultgammaramp.red[i] *= 256; + defaultgammaramp.green[i] *= 256; + defaultgammaramp.blue[i] *= 256; + } + } + currentgammaramp = defaultgammaramp; + + return 0; +} + +void D3DGraphicsDriver::initD3DDLL(const DisplayMode &mode) +{ + if (!IsModeSupported(mode)) + { + throw Ali3DException(get_allegro_error()); + } + + _enter_critical(); + + d3d_mode_to_init = mode; + // Set the display mode in the window's thread + if (wnd_call_proc(wnd_create_device)) { + _exit_critical(); + throw Ali3DException(get_allegro_error()); + } + + availableVideoMemory = direct3ddevice->GetAvailableTextureMem(); + + _exit_critical(); + + // Set up a fake allegro gfx driver so that things like + // the allegro mouse handler still work + if (mode.Windowed) + gfx_driver = &gfx_direct3d_win; + else + gfx_driver = &gfx_direct3d_full; + + return; +} + +/* color_depth_to_d3d_format: + * Convert a colour depth into the appropriate D3D tag + */ +static D3DFORMAT color_depth_to_d3d_format(int color_depth, bool wantAlpha) +{ + if (wantAlpha) + { + switch (color_depth) + { + case 8: + return D3DFMT_P8; + case 15: + case 16: + return D3DFMT_A1R5G5B5; + case 24: + case 32: + return D3DFMT_A8R8G8B8; + } + } + else + { + switch (color_depth) + { + case 8: + return D3DFMT_P8; + case 15: // don't use X1R5G5B5 because some cards don't support it + return D3DFMT_A1R5G5B5; + case 16: + return D3DFMT_R5G6B5; + case 24: + return D3DFMT_R8G8B8; + case 32: + return D3DFMT_X8R8G8B8; + } + } + return D3DFMT_UNKNOWN; +} + +/* d3d_format_to_color_depth: + * Convert a D3D tag to colour depth + * + * TODO: this is currently an inversion of color_depth_to_d3d_format; + * check later if more formats should be handled + */ +static int d3d_format_to_color_depth(D3DFORMAT format, bool secondary) +{ + switch (format) + { + case D3DFMT_P8: + return 8; + case D3DFMT_A1R5G5B5: + return secondary ? 15 : 16; + case D3DFMT_X1R5G5B5: + return secondary ? 15 : 16; + case D3DFMT_R5G6B5: + return 16; + case D3DFMT_R8G8B8: + return secondary ? 24 : 32; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + return 32; + } + return 0; +} + +bool D3DGraphicsDriver::IsModeSupported(const DisplayMode &mode) +{ + if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) + { + set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); + return false; + } + + if (mode.Windowed) + { + return true; + } + + D3DFORMAT pixelFormat = color_depth_to_d3d_format(mode.ColorDepth, false); + D3DDISPLAYMODE d3d_mode; + + int mode_count = direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, pixelFormat); + for (int i = 0; i < mode_count; i++) + { + if (FAILED(direct3d->EnumAdapterModes(D3DADAPTER_DEFAULT, pixelFormat, i, &d3d_mode))) + { + set_allegro_error("IDirect3D9::EnumAdapterModes failed"); + return false; + } + + if ((d3d_mode.Width == mode.Width) && (d3d_mode.Height == mode.Height)) + { + return true; + } + } + + set_allegro_error("The requested adapter mode is not supported"); + return false; +} + +bool D3DGraphicsDriver::SupportsGammaControl() +{ + if ((direct3ddevicecaps.Caps2 & D3DCAPS2_FULLSCREENGAMMA) == 0) + return false; + + if (_mode.Windowed) + return false; + + return true; +} + +void D3DGraphicsDriver::SetGamma(int newGamma) +{ + for (int i = 0; i < 256; i++) + { + int newValue = ((int)defaultgammaramp.red[i] * newGamma) / 100; + if (newValue >= 65535) + newValue = 65535; + currentgammaramp.red[i] = newValue; + currentgammaramp.green[i] = newValue; + currentgammaramp.blue[i] = newValue; + } + + direct3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, ¤tgammaramp); +} + +/* wnd_set_video_mode: + * Called by window thread to set a gfx mode; this is needed because DirectDraw can only + * change the mode in the thread that handles the window. + */ +static int wnd_create_device() +{ + return D3DGraphicsFactory::GetD3DDriver()->_initDLLCallback(d3d_mode_to_init); +} + +static int wnd_reset_device() +{ + return D3DGraphicsFactory::GetD3DDriver()->_resetDeviceIfNecessary(); +} + +int D3DGraphicsDriver::_resetDeviceIfNecessary() +{ + HRESULT hr = direct3ddevice->TestCooperativeLevel(); + + if (hr == D3DERR_DEVICELOST) + { + Debug::Printf("D3DGraphicsDriver: D3D Device Lost"); + // user has alt+tabbed away from the game + return 1; + } + + if (hr == D3DERR_DEVICENOTRESET) + { + Debug::Printf("D3DGraphicsDriver: D3D Device Not Reset"); + hr = ResetD3DDevice(); + if (hr != D3D_OK) + { + Debug::Printf("D3DGraphicsDriver: Failed to reset D3D device"); + // can't throw exception because we're in the wrong thread, + // so just return a value instead + return 2; + } + + InitializeD3DState(); + CreateVirtualScreen(); + direct3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, ¤tgammaramp); + } + + return 0; +} + +int D3DGraphicsDriver::_initDLLCallback(const DisplayMode &mode) +{ + HWND allegro_wnd = win_get_window(); + + if (mode.Windowed) + platform->AdjustWindowStyleForWindowed(); + else + platform->AdjustWindowStyleForFullscreen(); + + memset( &d3dpp, 0, sizeof(d3dpp) ); + d3dpp.BackBufferWidth = mode.Width; + d3dpp.BackBufferHeight = mode.Height; + d3dpp.BackBufferFormat = color_depth_to_d3d_format(mode.ColorDepth, false); + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + // THIS MUST BE SWAPEFFECT_COPY FOR PlayVideo TO WORK + d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; //D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = allegro_wnd; + d3dpp.Windowed = mode.Windowed; + d3dpp.EnableAutoDepthStencil = FALSE; + d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; // we need this flag to access the backbuffer with lockrect + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + if(mode.Vsync) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + else + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + /* If full screen, specify the refresh rate */ + // TODO find a way to avoid the wrong refreshrate to be set on mode.RefreshRate + // for now it's best to let it set automatically, so we prevent alt tab delays due to mismatching refreshrates + //if ((d3dpp.Windowed == FALSE) && (mode.RefreshRate > 0)) + // d3dpp.FullScreen_RefreshRateInHz = mode.RefreshRate; + + if (_initGfxCallback != NULL) + _initGfxCallback(&d3dpp); + + bool first_time_init = direct3ddevice == NULL; + HRESULT hr = 0; + if (direct3ddevice) + { + hr = ResetD3DDevice(); + } + else + hr = direct3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, allegro_wnd, + D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, // multithreaded required for AVI player + &d3dpp, &direct3ddevice); + if (hr != D3D_OK) + { + if (!previousError.IsEmpty()) + set_allegro_error(previousError); + else + set_allegro_error("Failed to create Direct3D Device: 0x%08X", hr); + return -1; + } + + if (mode.Windowed) + { + if (adjust_window(mode.Width, mode.Height) != 0) + { + direct3ddevice->Release(); + direct3ddevice = NULL; + set_allegro_error("Window size not supported"); + return -1; + } + } + + win_grab_input(); + + if (first_time_init) + { + int ft_res = FirstTimeInit(); + if (ft_res != 0) + return ft_res; + } + return 0; +} + +void D3DGraphicsDriver::InitializeD3DState() +{ + direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); + + // set the render flags. + direct3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + direct3ddevice->SetRenderState(D3DRS_LIGHTING, true); + direct3ddevice->SetRenderState(D3DRS_ZENABLE, FALSE); + + direct3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + direct3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + direct3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + direct3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + direct3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + direct3ddevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)0); + + direct3ddevice->SetFVF(D3DFVF_CUSTOMVERTEX); + + D3DMATERIAL9 material; + ZeroMemory(&material, sizeof(material)); //zero memory ( NEW ) + material.Diffuse.r = 1.0f; //diffuse color ( NEW ) + material.Diffuse.g = 1.0f; + material.Diffuse.b = 1.0f; + direct3ddevice->SetMaterial(&material); + + D3DLIGHT9 d3dLight; + ZeroMemory(&d3dLight, sizeof(D3DLIGHT9)); + + // Set up a white point light. + d3dLight.Type = D3DLIGHT_DIRECTIONAL; + d3dLight.Diffuse.r = 1.0f; + d3dLight.Diffuse.g = 1.0f; + d3dLight.Diffuse.b = 1.0f; + d3dLight.Diffuse.a = 1.0f; + d3dLight.Ambient.r = 1.0f; + d3dLight.Ambient.g = 1.0f; + d3dLight.Ambient.b = 1.0f; + d3dLight.Specular.r = 1.0f; + d3dLight.Specular.g = 1.0f; + d3dLight.Specular.b = 1.0f; + + // Position it high in the scene and behind the user. + // Remember, these coordinates are in world space, so + // the user could be anywhere in world space, too. + // For the purposes of this example, assume the user + // is at the origin of world space. + d3dLight.Direction.x = 0.0f; + d3dLight.Direction.y = 0.0f; + d3dLight.Direction.z = 1.0f; + + // Don't attenuate. + d3dLight.Attenuation0 = 1.0f; + d3dLight.Range = 1000.0f; + + // Set the property information for the first light. + direct3ddevice->SetLight(0, &d3dLight); + direct3ddevice->LightEnable(0, TRUE); + + // If we already have a render frame configured, then setup viewport immediately + SetupViewport(); +} + +void D3DGraphicsDriver::SetupViewport() +{ + if (!IsModeSet() || !IsRenderFrameValid() || !IsNativeSizeValid()) + return; + + const float src_width = _srcRect.GetWidth(); + const float src_height = _srcRect.GetHeight(); + const float disp_width = _mode.Width; + const float disp_height = _mode.Height; + + // Setup orthographic projection matrix + D3DMATRIX matOrtho = { + (2.0f / src_width), 0.0, 0.0, 0.0, + 0.0, (2.0f / src_height), 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + D3DMATRIX matIdentity = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + direct3ddevice->SetTransform(D3DTS_PROJECTION, &matOrtho); + direct3ddevice->SetTransform(D3DTS_WORLD, &matIdentity); + direct3ddevice->SetTransform(D3DTS_VIEW, &matIdentity); + + // See "Directly Mapping Texels to Pixels" MSDN article for why this is necessary + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb219690.aspx + _pixelRenderXOffset = (src_width / disp_width) / 2.0f; + _pixelRenderYOffset = (src_height / disp_height) / 2.0f; + + // Clear the screen before setting a viewport. + ClearScreenRect(RectWH(0, 0, _mode.Width, _mode.Height), nullptr); + + // Set Viewport. + ZeroMemory(&_d3dViewport, sizeof(D3DVIEWPORT9)); + _d3dViewport.X = _dstRect.Left; + _d3dViewport.Y = _dstRect.Top; + _d3dViewport.Width = _dstRect.GetWidth(); + _d3dViewport.Height = _dstRect.GetHeight(); + _d3dViewport.MinZ = 0.0f; + _d3dViewport.MaxZ = 1.0f; + direct3ddevice->SetViewport(&_d3dViewport); + + viewport_rect.left = _dstRect.Left; + viewport_rect.right = _dstRect.Right + 1; + viewport_rect.top = _dstRect.Top; + viewport_rect.bottom = _dstRect.Bottom + 1; +} + +void D3DGraphicsDriver::SetGraphicsFilter(PD3DFilter filter) +{ + _filter = filter; + OnSetFilter(); +} + +void D3DGraphicsDriver::SetTintMethod(TintMethod method) +{ + _legacyPixelShader = (method == TintReColourise); +} + +bool D3DGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) +{ + ReleaseDisplayMode(); + + if (mode.ColorDepth < 15) + { + set_allegro_error("Direct3D driver does not support 256-color display mode"); + return false; + } + + try + { + initD3DDLL(mode); + } + catch (Ali3DException exception) + { + if (exception._message != get_allegro_error()) + set_allegro_error(exception._message); + return false; + } + OnInit(loopTimer); + OnModeSet(mode); + InitializeD3DState(); + CreateVirtualScreen(); + return true; +} + +void D3DGraphicsDriver::CreateVirtualScreen() +{ + if (!IsModeSet() || !IsNativeSizeValid()) + return; + + // set up native surface + if (pNativeSurface != NULL) + { + pNativeSurface->Release(); + pNativeSurface = NULL; + } + if (pNativeTexture != NULL) + { + pNativeTexture->Release(); + pNativeTexture = NULL; + } + if (direct3ddevice->CreateTexture( + _srcRect.GetWidth(), + _srcRect.GetHeight(), + 1, + D3DUSAGE_RENDERTARGET, + color_depth_to_d3d_format(_mode.ColorDepth, false), + D3DPOOL_DEFAULT, + &pNativeTexture, + NULL) != D3D_OK) + { + throw Ali3DException("CreateTexture failed"); + } + if (pNativeTexture->GetSurfaceLevel(0, &pNativeSurface) != D3D_OK) + { + throw Ali3DException("GetSurfaceLevel failed"); + } + + direct3ddevice->ColorFill(pNativeSurface, NULL, 0); + + // create initial stage screen for plugin raw drawing + _stageVirtualScreen = CreateStageScreen(0, _srcRect.GetSize()); + // we must set Allegro's screen pointer to **something** + screen = (BITMAP*)_stageVirtualScreen->GetAllegroBitmap(); +} + +HRESULT D3DGraphicsDriver::ResetD3DDevice() +{ + // Direct3D documentation: + // Before calling the IDirect3DDevice9::Reset method for a device, + // an application should release any explicit render targets, depth stencil + // surfaces, additional swap chains, state blocks, and D3DPOOL_DEFAULT + // resources associated with the device. + if (pNativeSurface != NULL) + { + pNativeSurface->Release(); + pNativeSurface = NULL; + } + if (pNativeTexture != NULL) + { + pNativeTexture->Release(); + pNativeTexture = NULL; + } + return direct3ddevice->Reset(&d3dpp); +} + +bool D3DGraphicsDriver::SetNativeSize(const Size &src_size) +{ + OnSetNativeSize(src_size); + // Also make sure viewport is updated using new native & destination rectangles + SetupViewport(); + CreateVirtualScreen(); + return !_srcRect.IsEmpty(); +} + +bool D3DGraphicsDriver::SetRenderFrame(const Rect &dst_rect) +{ + OnSetRenderFrame(dst_rect); + // Also make sure viewport is updated using new native & destination rectangles + SetupViewport(); + return !_dstRect.IsEmpty(); +} + +int D3DGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const +{ + // TODO: check for device caps to know which depth is supported? + return 32; +} + +IGfxModeList *D3DGraphicsDriver::GetSupportedModeList(int color_depth) +{ + direct3d->AddRef(); + return new D3DGfxModeList(direct3d, color_depth_to_d3d_format(color_depth, false)); +} + +PGfxFilter D3DGraphicsDriver::GetGraphicsFilter() const +{ + return _filter; +} + +void D3DGraphicsDriver::UnInit() +{ +#ifndef AGS_NO_VIDEO_PLAYER + // TODO: this should not be done inside the graphics driver! + dxmedia_shutdown_3d(); +#endif + + OnUnInit(); + ReleaseDisplayMode(); + + if (pNativeSurface) + { + pNativeSurface->Release(); + pNativeSurface = NULL; + } + if (pNativeTexture) + { + pNativeTexture->Release(); + pNativeTexture = NULL; + } + + if (vertexbuffer) + { + vertexbuffer->Release(); + vertexbuffer = NULL; + } + + if (pixelShader) + { + pixelShader->Release(); + pixelShader = NULL; + } + + if (direct3ddevice) + { + direct3ddevice->Release(); + direct3ddevice = NULL; + } +} + +D3DGraphicsDriver::~D3DGraphicsDriver() +{ + D3DGraphicsDriver::UnInit(); + + if (direct3d) + direct3d->Release(); +} + +void D3DGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) +{ + // NOTE: this function is practically useless at the moment, because D3D redraws whole game frame each time + if (!direct3ddevice) return; + Rect r(x1, y1, x2, y2); + r = _scaling.ScaleRange(r); + ClearScreenRect(r, colorToUse); +} + +void D3DGraphicsDriver::ClearScreenRect(const Rect &r, RGB *colorToUse) +{ + D3DRECT rectToClear; + rectToClear.x1 = r.Left; + rectToClear.y1 = r.Top; + rectToClear.x2 = r.Right + 1; + rectToClear.y2 = r.Bottom + 1; + DWORD colorDword = 0; + if (colorToUse != NULL) + colorDword = D3DCOLOR_XRGB(colorToUse->r, colorToUse->g, colorToUse->b); + direct3ddevice->Clear(1, &rectToClear, D3DCLEAR_TARGET, colorDword, 0.5f, 0); +} + +bool D3DGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) +{ + // Currently don't support copying in screen resolution when we are rendering in native + if (!_renderSprAtScreenRes) + at_native_res = true; + Size need_size = at_native_res ? _srcRect.GetSize() : _dstRect.GetSize(); + if (destination->GetColorDepth() != _mode.ColorDepth || destination->GetSize() != need_size) + { + if (want_fmt) + *want_fmt = GraphicResolution(need_size.Width, need_size.Height, _mode.ColorDepth); + return false; + } + // If we are rendering sprites at the screen resolution, and requested native res, + // re-render last frame to the native surface + if (at_native_res && _renderSprAtScreenRes) + { + _renderSprAtScreenRes = false; + _reDrawLastFrame(); + _render(true); + _renderSprAtScreenRes = true; + } + + IDirect3DSurface9* surface = NULL; + { + if (_pollingCallback) + _pollingCallback(); + + if (at_native_res) + { + // with render to texture the texture mipmap surface can't be locked directly + // we have to create a surface with D3DPOOL_SYSTEMMEM for GetRenderTargetData + if (direct3ddevice->CreateOffscreenPlainSurface( + _srcRect.GetWidth(), + _srcRect.GetHeight(), + color_depth_to_d3d_format(_mode.ColorDepth, false), + D3DPOOL_SYSTEMMEM, + &surface, + NULL) != D3D_OK) + { + throw Ali3DException("CreateOffscreenPlainSurface failed"); + } + if (direct3ddevice->GetRenderTargetData(pNativeSurface, surface) != D3D_OK) + { + throw Ali3DException("GetRenderTargetData failed"); + } + + } + // Get the back buffer surface + else if (direct3ddevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface) != D3D_OK) + { + throw Ali3DException("IDirect3DDevice9::GetBackBuffer failed"); + } + + if (_pollingCallback) + _pollingCallback(); + + D3DLOCKED_RECT lockedRect; + if (surface->LockRect(&lockedRect, (at_native_res ? NULL : &viewport_rect), D3DLOCK_READONLY ) != D3D_OK) + { + throw Ali3DException("IDirect3DSurface9::LockRect failed"); + } + + BitmapHelper::ReadPixelsFromMemory(destination, (uint8_t*)lockedRect.pBits, lockedRect.Pitch); + + surface->UnlockRect(); + surface->Release(); + + if (_pollingCallback) + _pollingCallback(); + } + return true; +} + +void D3DGraphicsDriver::RenderToBackBuffer() +{ + throw Ali3DException("D3D driver does not have a back buffer"); +} + +void D3DGraphicsDriver::Render() +{ + Render(0, 0, kFlip_None); +} + +void D3DGraphicsDriver::Render(int /*xoff*/, int /*yoff*/, GlobalFlipType /*flip*/) +{ + if (wnd_call_proc(wnd_reset_device)) + { + throw Ali3DFullscreenLostException(); + } + + _renderAndPresent(true); +} + +void D3DGraphicsDriver::_reDrawLastFrame() +{ + RestoreDrawLists(); +} + +void D3DGraphicsDriver::_renderSprite(const D3DDrawListEntry *drawListEntry, const D3DMATRIX &matGlobal) +{ + HRESULT hr; + D3DBitmap *bmpToDraw = drawListEntry->bitmap; + D3DMATRIX matSelfTransform; + D3DMATRIX matTransform; + + if (bmpToDraw->_transparency >= 255) + return; + + if (bmpToDraw->_tintSaturation > 0) + { + // Use custom pixel shader + float vector[8]; + if (_legacyPixelShader) + { + rgb_to_hsv(bmpToDraw->_red, bmpToDraw->_green, bmpToDraw->_blue, &vector[0], &vector[1], &vector[2]); + vector[0] /= 360.0; // In HSV, Hue is 0-360 + } + else + { + vector[0] = (float)bmpToDraw->_red / 256.0; + vector[1] = (float)bmpToDraw->_green / 256.0; + vector[2] = (float)bmpToDraw->_blue / 256.0; + } + + vector[3] = (float)bmpToDraw->_tintSaturation / 256.0; + + if (bmpToDraw->_transparency > 0) + vector[4] = (float)bmpToDraw->_transparency / 256.0; + else + vector[4] = 1.0f; + + if (bmpToDraw->_lightLevel > 0) + vector[5] = (float)bmpToDraw->_lightLevel / 256.0; + else + vector[5] = 1.0f; + + direct3ddevice->SetPixelShaderConstantF(0, &vector[0], 2); + direct3ddevice->SetPixelShader(pixelShader); + } + else + { + // Not using custom pixel shader; set up the default one + direct3ddevice->SetPixelShader(NULL); + int useTintRed = 255; + int useTintGreen = 255; + int useTintBlue = 255; + int useTransparency = 0xff; + int textureColorOp = D3DTOP_MODULATE; + + if ((bmpToDraw->_lightLevel > 0) && (bmpToDraw->_lightLevel < 256)) + { + // darkening the sprite... this stupid calculation is for + // consistency with the allegro software-mode code that does + // a trans blend with a (8,8,8) sprite + useTintRed = (bmpToDraw->_lightLevel * 192) / 256 + 64; + useTintGreen = useTintRed; + useTintBlue = useTintRed; + } + else if (bmpToDraw->_lightLevel > 256) + { + // ideally we would use a multi-stage operation here + // because we need to do TEXTURE + (TEXTURE x LIGHT) + // but is it worth having to set the device to 2-stage? + textureColorOp = D3DTOP_ADD; + useTintRed = (bmpToDraw->_lightLevel - 256) / 2; + useTintGreen = useTintRed; + useTintBlue = useTintRed; + } + + if (bmpToDraw->_transparency > 0) + { + useTransparency = bmpToDraw->_transparency; + } + + direct3ddevice->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(useTintRed, useTintGreen, useTintBlue, useTransparency)); + direct3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, textureColorOp); + direct3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + direct3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + + if (bmpToDraw->_transparency == 0) + { + // No transparency, use texture alpha component + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + } + else + { + // Fixed transparency, use (TextureAlpha x FixedTranslucency) + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + } + } + + if (bmpToDraw->_vertex == NULL) + { + hr = direct3ddevice->SetStreamSource(0, vertexbuffer, 0, sizeof(CUSTOMVERTEX)); + } + else + { + hr = direct3ddevice->SetStreamSource(0, bmpToDraw->_vertex, 0, sizeof(CUSTOMVERTEX)); + } + if (hr != D3D_OK) + { + throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); + } + + float width = bmpToDraw->GetWidthToRender(); + float height = bmpToDraw->GetHeightToRender(); + float xProportion = width / (float)bmpToDraw->_width; + float yProportion = height / (float)bmpToDraw->_height; + float drawAtX = drawListEntry->x; + float drawAtY = drawListEntry->y; + + for (int ti = 0; ti < bmpToDraw->_numTiles; ti++) + { + width = bmpToDraw->_tiles[ti].width * xProportion; + height = bmpToDraw->_tiles[ti].height * yProportion; + float xOffs; + float yOffs = bmpToDraw->_tiles[ti].y * yProportion; + if (bmpToDraw->_flipped) + xOffs = (bmpToDraw->_width - (bmpToDraw->_tiles[ti].x + bmpToDraw->_tiles[ti].width)) * xProportion; + else + xOffs = bmpToDraw->_tiles[ti].x * xProportion; + float thisX = drawAtX + xOffs; + float thisY = drawAtY + yOffs; + thisX = (-(_srcRect.GetWidth() / 2)) + thisX; + thisY = (_srcRect.GetHeight() / 2) - thisY; + + //Setup translation and scaling matrices + float widthToScale = (float)width; + float heightToScale = (float)height; + if (bmpToDraw->_flipped) + { + // The usual transform changes 0..1 into 0..width + // So first negate it (which changes 0..w into -w..0) + widthToScale = -widthToScale; + // and now shift it over to make it 0..w again + thisX += width; + } + + // Multiply object's own and global matrixes + MatrixTransform2D(matSelfTransform, (float)thisX - _pixelRenderXOffset, (float)thisY + _pixelRenderYOffset, widthToScale, heightToScale, 0.f); + MatrixMultiply(matTransform, matSelfTransform, matGlobal); + + if ((_smoothScaling) && bmpToDraw->_useResampler && (bmpToDraw->_stretchToHeight > 0) && + ((bmpToDraw->_stretchToHeight != bmpToDraw->_height) || + (bmpToDraw->_stretchToWidth != bmpToDraw->_width))) + { + direct3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + direct3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + } + else if (!_renderSprAtScreenRes) + { + direct3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + direct3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + } + else + { + _filter->SetSamplerStateForStandardSprite(direct3ddevice); + } + + direct3ddevice->SetTransform(D3DTS_WORLD, &matTransform); + direct3ddevice->SetTexture(0, bmpToDraw->_tiles[ti].texture); + + hr = direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, ti * 4, 2); + if (hr != D3D_OK) + { + throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); + } + + } +} + +void D3DGraphicsDriver::_renderFromTexture() +{ + if (direct3ddevice->SetStreamSource(0, vertexbuffer, 0, sizeof(CUSTOMVERTEX)) != D3D_OK) + { + throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); + } + + float width = _srcRect.GetWidth(); + float height = _srcRect.GetHeight(); + float drawAtX = -(_srcRect.GetWidth() / 2); + float drawAtY = _srcRect.GetHeight() / 2; + + D3DMATRIX matrix; + MatrixTransform2D(matrix, (float)drawAtX - _pixelRenderXOffset, (float)drawAtY + _pixelRenderYOffset, width, height, 0.f); + + direct3ddevice->SetTransform(D3DTS_WORLD, &matrix); + + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + + _filter->SetSamplerStateForStandardSprite(direct3ddevice); + + direct3ddevice->SetTexture(0, pNativeTexture); + + if (direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2) != D3D_OK) + { + throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); + } +} + +void D3DGraphicsDriver::_renderAndPresent(bool clearDrawListAfterwards) +{ + _render(clearDrawListAfterwards); + direct3ddevice->Present(NULL, NULL, NULL, NULL); +} + +void D3DGraphicsDriver::_render(bool clearDrawListAfterwards) +{ + IDirect3DSurface9 *pBackBuffer = NULL; + + if (direct3ddevice->GetRenderTarget(0, &pBackBuffer) != D3D_OK) { + throw Ali3DException("IDirect3DSurface9::GetRenderTarget failed"); + } + direct3ddevice->ColorFill(pBackBuffer, nullptr, D3DCOLOR_RGBA(0, 0, 0, 255)); + + if (!_renderSprAtScreenRes) { + if (direct3ddevice->SetRenderTarget(0, pNativeSurface) != D3D_OK) + { + throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); + } + } + + direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); + if (direct3ddevice->BeginScene() != D3D_OK) + throw Ali3DException("IDirect3DDevice9::BeginScene failed"); + + // if showing at 2x size, the sprite can get distorted otherwise + direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP); + + RenderSpriteBatches(); + + if (!_renderSprAtScreenRes) { + if (direct3ddevice->SetRenderTarget(0, pBackBuffer)!= D3D_OK) + { + throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); + } + direct3ddevice->SetViewport(&_d3dViewport); + _renderFromTexture(); + } + + direct3ddevice->EndScene(); + + pBackBuffer->Release(); + + if (clearDrawListAfterwards) + { + BackupDrawLists(); + ClearDrawLists(); + } + ResetFxPool(); +} + +void D3DGraphicsDriver::RenderSpriteBatches() +{ + // Render all the sprite batches with necessary transformations + for (size_t i = 0; i <= _actSpriteBatch; ++i) + { + const Rect &viewport = _spriteBatches[i].Viewport; + const D3DSpriteBatch &batch = _spriteBatches[i]; + if (!viewport.IsEmpty()) + { + direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + RECT scissor; + if (_renderSprAtScreenRes) + { + scissor.left = _scaling.X.ScalePt(viewport.Left); + scissor.top = _scaling.Y.ScalePt(viewport.Top); + scissor.right = _scaling.X.ScalePt(viewport.Right + 1); + scissor.bottom = _scaling.Y.ScalePt(viewport.Bottom + 1); + } + else + { + scissor.left = viewport.Left; + scissor.top = viewport.Top; + scissor.right = viewport.Right + 1; + scissor.bottom = viewport.Bottom + 1; + } + direct3ddevice->SetScissorRect(&scissor); + } + else + { + direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + } + _stageVirtualScreen = GetStageScreen(i); + RenderSpriteBatch(batch); + } + + _stageVirtualScreen = GetStageScreen(0); + direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); +} + +void D3DGraphicsDriver::RenderSpriteBatch(const D3DSpriteBatch &batch) +{ + D3DDrawListEntry stageEntry; // raw-draw plugin support + + const std::vector &listToDraw = batch.List; + for (size_t i = 0; i < listToDraw.size(); ++i) + { + if (listToDraw[i].skip) + continue; + + const D3DDrawListEntry *sprite = &listToDraw[i]; + if (listToDraw[i].bitmap == NULL) + { + if (DoNullSpriteCallback(listToDraw[i].x, (int)direct3ddevice)) + stageEntry = D3DDrawListEntry((D3DBitmap*)_stageVirtualScreenDDB); + else + continue; + sprite = &stageEntry; + } + + this->_renderSprite(sprite, batch.Matrix); + } +} + +void D3DGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) +{ + if (_spriteBatches.size() <= index) + _spriteBatches.resize(index + 1); + _spriteBatches[index].List.clear(); + + Rect viewport = desc.Viewport; + // Combine both world transform and viewport transform into one matrix for faster perfomance + D3DMATRIX matRoomToViewport, matViewport, matViewportFinal; + // IMPORTANT: while the sprites are usually transformed in the order of Scale-Rotate-Translate, + // the camera's transformation is essentially reverse world transformation. And the operations + // are inverse: Translate-Rotate-Scale + MatrixTransformInverse2D(matRoomToViewport, + desc.Transform.X, -(desc.Transform.Y), + desc.Transform.ScaleX, desc.Transform.ScaleY, desc.Transform.Rotate); + // Next step is translate to viewport position; remove this if this is + // changed to a separate operation at some point + // TODO: find out if this is an optimal way to translate scaled room into Top-Left screen coordinates + float scaled_offx = (_srcRect.GetWidth() - desc.Transform.ScaleX * (float)_srcRect.GetWidth()) / 2.f; + float scaled_offy = (_srcRect.GetHeight() - desc.Transform.ScaleY * (float)_srcRect.GetHeight()) / 2.f; + MatrixTranslate(matViewport, viewport.Left - scaled_offx, -(viewport.Top - scaled_offy), 0.f); + MatrixMultiply(matViewportFinal, matRoomToViewport, matViewport); + + // Then apply global node transformation (flip and offset) + int node_tx = desc.Offset.X, node_ty = desc.Offset.Y; + float node_sx = 1.f, node_sy = 1.f; + if ((desc.Flip == kFlip_Vertical) || (desc.Flip == kFlip_Both)) + { + int left = _srcRect.GetWidth() - (viewport.Right + 1); + viewport.MoveToX(left); + node_sx = -1.f; + } + if ((desc.Flip == kFlip_Horizontal) || (desc.Flip == kFlip_Both)) + { + int top = _srcRect.GetHeight() - (viewport.Bottom + 1); + viewport.MoveToY(top); + node_sy = -1.f; + } + viewport = Rect::MoveBy(viewport, node_tx, node_ty); + D3DMATRIX matFlip; + MatrixTransform2D(matFlip, node_tx, -(node_ty), node_sx, node_sy, 0.f); + MatrixMultiply(_spriteBatches[index].Matrix, matViewportFinal, matFlip); + _spriteBatches[index].Viewport = viewport; + + // create stage screen for plugin raw drawing + int src_w = viewport.GetWidth() / desc.Transform.ScaleX; + int src_h = viewport.GetHeight() / desc.Transform.ScaleY; + CreateStageScreen(index, Size(src_w, src_h)); +} + +void D3DGraphicsDriver::ResetAllBatches() +{ + for (size_t i = 0; i < _spriteBatches.size(); ++i) + _spriteBatches[i].List.clear(); +} + +void D3DGraphicsDriver::ClearDrawBackups() +{ + _backupBatchDescs.clear(); + _backupBatches.clear(); +} + +void D3DGraphicsDriver::BackupDrawLists() +{ + ClearDrawBackups(); + for (size_t i = 0; i <= _actSpriteBatch; ++i) + { + _backupBatchDescs.push_back(_spriteBatchDesc[i]); + _backupBatches.push_back(_spriteBatches[i]); + } +} + +void D3DGraphicsDriver::RestoreDrawLists() +{ + if (_backupBatchDescs.size() == 0) + { + ClearDrawLists(); + return; + } + _spriteBatchDesc = _backupBatchDescs; + _spriteBatches = _backupBatches; + _actSpriteBatch = _backupBatchDescs.size() - 1; +} + +void D3DGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) +{ + _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry((D3DBitmap*)bitmap, x, y)); +} + +void D3DGraphicsDriver::DestroyDDB(IDriverDependantBitmap* bitmap) +{ + // Remove deleted DDB from backups + for (D3DSpriteBatches::iterator it = _backupBatches.begin(); it != _backupBatches.end(); ++it) + { + std::vector &drawlist = it->List; + for (size_t i = 0; i < drawlist.size(); i++) + { + if (drawlist[i].bitmap == bitmap) + drawlist[i].skip = true; + } + } + delete bitmap; +} + +void D3DGraphicsDriver::UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap, D3DBitmap *target, bool hasAlpha) +{ + IDirect3DTexture9* newTexture = tile->texture; + + D3DLOCKED_RECT lockedRegion; + HRESULT hr = newTexture->LockRect(0, &lockedRegion, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD); + if (hr != D3D_OK) + { + throw Ali3DException("Unable to lock texture"); + } + + bool usingLinearFiltering = _filter->NeedToColourEdgeLines(); + char *memPtr = (char*)lockedRegion.pBits; + + if (target->_opaque) + BitmapToVideoMemOpaque(bitmap, hasAlpha, tile, target, memPtr, lockedRegion.Pitch); + else + BitmapToVideoMem(bitmap, hasAlpha, tile, target, memPtr, lockedRegion.Pitch, usingLinearFiltering); + + newTexture->UnlockRect(0); +} + +void D3DGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) +{ + D3DBitmap *target = (D3DBitmap*)bitmapToUpdate; + if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) + throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); + const int color_depth = bitmap->GetColorDepth(); + if (color_depth != target->_colDepth) + throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); + + target->_hasAlpha = hasAlpha; + if (color_depth == 8) + select_palette(palette); + + for (int i = 0; i < target->_numTiles; i++) + { + UpdateTextureRegion(&target->_tiles[i], bitmap, target, hasAlpha); + } + + if (color_depth == 8) + unselect_palette(); +} + +int D3DGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) +{ + if (color_depth == 8) + return 8; + if (color_depth > 8 && color_depth <= 16) + return 16; + return 32; +} + +void D3DGraphicsDriver::AdjustSizeToNearestSupportedByCard(int *width, int *height) +{ + int allocatedWidth = *width, allocatedHeight = *height; + + if (direct3ddevicecaps.TextureCaps & D3DPTEXTURECAPS_POW2) + { + bool foundWidth = false, foundHeight = false; + int tryThis = 2; + while ((!foundWidth) || (!foundHeight)) + { + if ((tryThis >= allocatedWidth) && (!foundWidth)) + { + allocatedWidth = tryThis; + foundWidth = true; + } + + if ((tryThis >= allocatedHeight) && (!foundHeight)) + { + allocatedHeight = tryThis; + foundHeight = true; + } + + tryThis = tryThis << 1; + } + } + + if (direct3ddevicecaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) + { + if (allocatedWidth > allocatedHeight) + { + allocatedHeight = allocatedWidth; + } + else + { + allocatedWidth = allocatedHeight; + } + } + + *width = allocatedWidth; + *height = allocatedHeight; +} + +bool D3DGraphicsDriver::IsTextureFormatOk( D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat ) +{ + HRESULT hr = direct3d->CheckDeviceFormat( D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + AdapterFormat, + 0, + D3DRTYPE_TEXTURE, + TextureFormat); + + return SUCCEEDED( hr ); +} + +IDriverDependantBitmap* D3DGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) +{ + int allocatedWidth = bitmap->GetWidth(); + int allocatedHeight = bitmap->GetHeight(); + if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) + throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); + int colourDepth = bitmap->GetColorDepth(); + + D3DBitmap *ddb = new D3DBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); + + AdjustSizeToNearestSupportedByCard(&allocatedWidth, &allocatedHeight); + int tilesAcross = 1, tilesDown = 1; + + // *************** REMOVE THESE LINES ************* + //direct3ddevicecaps.MaxTextureWidth = 64; + //direct3ddevicecaps.MaxTextureHeight = 256; + // *************** END REMOVE THESE LINES ************* + + // Calculate how many textures will be necessary to + // store this image + tilesAcross = (allocatedWidth + direct3ddevicecaps.MaxTextureWidth - 1) / direct3ddevicecaps.MaxTextureWidth; + tilesDown = (allocatedHeight + direct3ddevicecaps.MaxTextureHeight - 1) / direct3ddevicecaps.MaxTextureHeight; + int tileWidth = bitmap->GetWidth() / tilesAcross; + int lastTileExtraWidth = bitmap->GetWidth() % tilesAcross; + int tileHeight = bitmap->GetHeight() / tilesDown; + int lastTileExtraHeight = bitmap->GetHeight() % tilesDown; + int tileAllocatedWidth = tileWidth; + int tileAllocatedHeight = tileHeight; + + AdjustSizeToNearestSupportedByCard(&tileAllocatedWidth, &tileAllocatedHeight); + + int numTiles = tilesAcross * tilesDown; + D3DTextureTile *tiles = (D3DTextureTile*)malloc(sizeof(D3DTextureTile) * numTiles); + memset(tiles, 0, sizeof(D3DTextureTile) * numTiles); + + CUSTOMVERTEX *vertices = NULL; + + if ((numTiles == 1) && + (allocatedWidth == bitmap->GetWidth()) && + (allocatedHeight == bitmap->GetHeight())) + { + // use default whole-image vertices + } + else + { + // The texture is not the same as the bitmap, so create some custom vertices + // so that only the relevant portion of the texture is rendered + int vertexBufferSize = numTiles * 4 * sizeof(CUSTOMVERTEX); + HRESULT hr = direct3ddevice->CreateVertexBuffer(vertexBufferSize, 0, + D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &ddb->_vertex, NULL); + + if (hr != D3D_OK) + { + free(tiles); + char errorMessage[200]; + sprintf(errorMessage, "Direct3DDevice9::CreateVertexBuffer(Length=%d) for texture failed: error code %08X", vertexBufferSize, hr); + throw Ali3DException(errorMessage); + } + + if (ddb->_vertex->Lock(0, 0, (void**)&vertices, D3DLOCK_DISCARD) != D3D_OK) + { + free(tiles); + throw Ali3DException("Failed to lock vertex buffer"); + } + } + + for (int x = 0; x < tilesAcross; x++) + { + for (int y = 0; y < tilesDown; y++) + { + D3DTextureTile *thisTile = &tiles[y * tilesAcross + x]; + int thisAllocatedWidth = tileAllocatedWidth; + int thisAllocatedHeight = tileAllocatedHeight; + thisTile->x = x * tileWidth; + thisTile->y = y * tileHeight; + thisTile->width = tileWidth; + thisTile->height = tileHeight; + if (x == tilesAcross - 1) + { + thisTile->width += lastTileExtraWidth; + thisAllocatedWidth = thisTile->width; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + if (y == tilesDown - 1) + { + thisTile->height += lastTileExtraHeight; + thisAllocatedHeight = thisTile->height; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + + if (vertices != NULL) + { + for (int vidx = 0; vidx < 4; vidx++) + { + int i = (y * tilesAcross + x) * 4 + vidx; + vertices[i] = defaultVertices[vidx]; + if (vertices[i].tu > 0.0) + { + vertices[i].tu = (float)thisTile->width / (float)thisAllocatedWidth; + } + if (vertices[i].tv > 0.0) + { + vertices[i].tv = (float)thisTile->height / (float)thisAllocatedHeight; + } + } + } + + // NOTE: pay attention that the texture format depends on the **display mode**'s color format, + // rather than source bitmap's color depth! + D3DFORMAT textureFormat = color_depth_to_d3d_format(_mode.ColorDepth, !opaque); + HRESULT hr = direct3ddevice->CreateTexture(thisAllocatedWidth, thisAllocatedHeight, 1, 0, + textureFormat, + D3DPOOL_MANAGED, &thisTile->texture, NULL); + if (hr != D3D_OK) + { + char errorMessage[200]; + sprintf(errorMessage, "Direct3DDevice9::CreateTexture(X=%d, Y=%d, FMT=%d) failed: error code %08X", thisAllocatedWidth, thisAllocatedHeight, textureFormat, hr); + throw Ali3DException(errorMessage); + } + + } + } + + if (vertices != NULL) + { + ddb->_vertex->Unlock(); + } + + ddb->_numTiles = numTiles; + ddb->_tiles = tiles; + + UpdateDDBFromBitmap(ddb, bitmap, hasAlpha); + + return ddb; +} + +void D3DGraphicsDriver::do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + // Construct scene in order: game screen, fade fx, post game overlay + // NOTE: please keep in mind: redrawing last saved frame here instead of constructing new one + // is done because of backwards-compatibility issue: originally AGS faded out using frame + // drawn before the script that triggers blocking fade (e.g. instigated by ChangeRoom). + // Unfortunately some existing games were changing looks of the screen during same function, + // but these were not supposed to get on screen until before fade-in. + if (fadingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != NULL) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(makecol32(targetColourRed, targetColourGreen, targetColourBlue)); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + if (speed <= 0) speed = 16; + speed *= 2; // harmonise speeds with software driver which is faster + for (int a = 1; a < 255; a += speed) + { + d3db->SetTransparency(fadingOut ? a : (255 - a)); + this->_renderAndPresent(false); + + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + + if (fadingOut) + { + d3db->SetTransparency(0); + this->_renderAndPresent(false); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); +} + +void D3DGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + do_fade(true, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void D3DGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) +{ + do_fade(false, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void D3DGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) +{ + // Construct scene in order: game screen, fade fx, post game overlay + if (blackingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != NULL) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + size_t fx_batch = _actSpriteBatch; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (!blackingOut) + { + // when fading in, draw four black boxes, one + // across each side of the screen + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + } + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); + int boxWidth = speed; + int boxHeight = yspeed; + + while (boxWidth < _srcRect.GetWidth()) + { + boxWidth += speed; + boxHeight += yspeed; + D3DSpriteBatch &batch = _spriteBatches[fx_batch]; + std::vector &drawList = batch.List; + const size_t last = drawList.size() - 1; + if (blackingOut) + { + drawList[last].x = _srcRect.GetWidth() / 2- boxWidth / 2; + drawList[last].y = _srcRect.GetHeight() / 2 - boxHeight / 2; + d3db->SetStretch(boxWidth, boxHeight, false); + } + else + { + drawList[last - 3].x = _srcRect.GetWidth() / 2 - boxWidth / 2 - _srcRect.GetWidth(); + drawList[last - 2].y = _srcRect.GetHeight() / 2 - boxHeight / 2 - _srcRect.GetHeight(); + drawList[last - 1].x = _srcRect.GetWidth() / 2 + boxWidth / 2; + drawList[last ].y = _srcRect.GetHeight() / 2 + boxHeight / 2; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + } + + this->_renderAndPresent(false); + + if (_pollingCallback) + _pollingCallback(); + platform->Delay(delay); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); +} + +#ifndef AGS_NO_VIDEO_PLAYER + +bool D3DGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) +{ + direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); + + int result = dxmedia_play_video_3d(filename, direct3ddevice, useAVISound, skipType, stretchToFullScreen ? 1 : 0); + return (result == 0); +} + +#endif + +void D3DGraphicsDriver::SetScreenFade(int red, int green, int blue) +{ + D3DBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(0); + _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry(ddb)); +} + +void D3DGraphicsDriver::SetScreenTint(int red, int green, int blue) +{ + if (red == 0 && green == 0 && blue == 0) return; + D3DBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(128); + _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry(ddb)); +} + + +D3DGraphicsFactory *D3DGraphicsFactory::_factory = NULL; +Library D3DGraphicsFactory::_library; + +D3DGraphicsFactory::~D3DGraphicsFactory() +{ + DestroyDriver(); // driver must be destroyed before d3d library is disposed + ULONG ref_cnt = _direct3d->Release(); + if (ref_cnt > 0) + Debug::Printf(kDbgMsg_Warn, "WARNING: Not all of the Direct3D resources have been disposed; ID3D ref count: %d", ref_cnt); + _factory = NULL; +} + +size_t D3DGraphicsFactory::GetFilterCount() const +{ + return 2; +} + +const GfxFilterInfo *D3DGraphicsFactory::GetFilterInfo(size_t index) const +{ + switch (index) + { + case 0: + return &D3DGfxFilter::FilterInfo; + case 1: + return &AAD3DGfxFilter::FilterInfo; + default: + return NULL; + } +} + +String D3DGraphicsFactory::GetDefaultFilterID() const +{ + return D3DGfxFilter::FilterInfo.Id; +} + +/* static */ D3DGraphicsFactory *D3DGraphicsFactory::GetFactory() +{ + if (!_factory) + { + _factory = new D3DGraphicsFactory(); + if (!_factory->Init()) + { + delete _factory; + _factory = NULL; + } + } + return _factory; +} + +/* static */ D3DGraphicsDriver *D3DGraphicsFactory::GetD3DDriver() +{ + if (!_factory) + _factory = GetFactory(); + if (_factory) + return _factory->EnsureDriverCreated(); + return NULL; +} + + +D3DGraphicsFactory::D3DGraphicsFactory() + : _direct3d(NULL) +{ +} + +D3DGraphicsDriver *D3DGraphicsFactory::EnsureDriverCreated() +{ + if (!_driver) + { + _factory->_direct3d->AddRef(); + _driver = new D3DGraphicsDriver(_factory->_direct3d); + } + return _driver; +} + +D3DGfxFilter *D3DGraphicsFactory::CreateFilter(const String &id) +{ + if (D3DGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new D3DGfxFilter(); + else if (AAD3DGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new AAD3DGfxFilter(); + return NULL; +} + +bool D3DGraphicsFactory::Init() +{ + assert(_direct3d == NULL); + if (_direct3d) + return true; + + if (!_library.Load("d3d9")) + { + set_allegro_error("Direct3D 9 is not installed"); + return false; + } + + typedef IDirect3D9 * WINAPI D3D9CreateFn(UINT); + D3D9CreateFn *lpDirect3DCreate9 = (D3D9CreateFn*)_library.GetFunctionAddress("Direct3DCreate9"); + if (!lpDirect3DCreate9) + { + _library.Unload(); + set_allegro_error("Entry point not found in d3d9.dll"); + return false; + } + _direct3d = lpDirect3DCreate9(D3D_SDK_VERSION); + if (!_direct3d) + { + _library.Unload(); + set_allegro_error("Direct3DCreate failed!"); + return false; + } + return true; +} + +} // namespace D3D +} // namespace Engine +} // namespace AGS + +#endif // AGS_PLATFORM_OS_WINDOWS \ No newline at end of file diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h new file mode 100644 index 000000000000..a8cc442f0a69 --- /dev/null +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -0,0 +1,336 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Direct3D graphics factory +// +//============================================================================= + +#ifndef __AGS_EE_GFX__ALI3DD3D_H +#define __AGS_EE_GFX__ALI3DD3D_H + +#include "core/platform.h" + +#if ! AGS_PLATFORM_OS_WINDOWS +#error This file should only be included on the Windows build +#endif + +#include +#include +#include +#include +#include "gfx/bitmap.h" +#include "gfx/ddb.h" +#include "gfx/gfxdriverfactorybase.h" +#include "gfx/gfxdriverbase.h" +#include "util/library.h" +#include "util/string.h" + +namespace AGS +{ +namespace Engine +{ +namespace D3D +{ + +using AGS::Common::Bitmap; +using AGS::Common::String; +class D3DGfxFilter; + +struct D3DTextureTile : public TextureTile +{ + IDirect3DTexture9* texture; +}; + +class D3DBitmap : public VideoMemDDB +{ +public: + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + void SetTransparency(int transparency) override { _transparency = transparency; } + void SetFlippedLeftRight(bool isFlipped) override { _flipped = isFlipped; } + void SetStretch(int width, int height, bool useResampler = true) override + { + _stretchToWidth = width; + _stretchToHeight = height; + _useResampler = useResampler; + } + void SetLightLevel(int lightLevel) override { _lightLevel = lightLevel; } + void SetTint(int red, int green, int blue, int tintSaturation) override + { + _red = red; + _green = green; + _blue = blue; + _tintSaturation = tintSaturation; + } + + bool _flipped; + int _stretchToWidth, _stretchToHeight; + bool _useResampler; + int _red, _green, _blue; + int _tintSaturation; + int _lightLevel; + bool _hasAlpha; + int _transparency; + IDirect3DVertexBuffer9* _vertex; + D3DTextureTile *_tiles; + int _numTiles; + + D3DBitmap(int width, int height, int colDepth, bool opaque) + { + _width = width; + _height = height; + _colDepth = colDepth; + _flipped = false; + _hasAlpha = false; + _stretchToWidth = 0; + _stretchToHeight = 0; + _useResampler = false; + _red = _green = _blue = 0; + _tintSaturation = 0; + _lightLevel = 0; + _transparency = 0; + _opaque = opaque; + _vertex = NULL; + _tiles = NULL; + _numTiles = 0; + } + + int GetWidthToRender() { return (_stretchToWidth > 0) ? _stretchToWidth : _width; } + int GetHeightToRender() { return (_stretchToHeight > 0) ? _stretchToHeight : _height; } + + void Dispose(); + + ~D3DBitmap() override + { + Dispose(); + } +}; + +class D3DGfxModeList : public IGfxModeList +{ +public: + D3DGfxModeList(IDirect3D9 *direct3d, D3DFORMAT d3dformat) + : _direct3d(direct3d) + , _pixelFormat(d3dformat) + { + _modeCount = _direct3d ? _direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, _pixelFormat) : 0; + } + + ~D3DGfxModeList() override + { + if (_direct3d) + _direct3d->Release(); + } + + int GetModeCount() const override + { + return _modeCount; + } + + bool GetMode(int index, DisplayMode &mode) const override; + +private: + IDirect3D9 *_direct3d; + D3DFORMAT _pixelFormat; + int _modeCount; +}; + +struct CUSTOMVERTEX +{ + D3DVECTOR position; // The position. + D3DVECTOR normal; + FLOAT tu, tv; // The texture coordinates. +}; + +typedef SpriteDrawListEntry D3DDrawListEntry; +// D3D renderer's sprite batch +struct D3DSpriteBatch +{ + // List of sprites to render + std::vector List; + // Clipping viewport + Rect Viewport; + // Transformation matrix, built from the batch description + D3DMATRIX Matrix; +}; +typedef std::vector D3DSpriteBatches; + + +class D3DGraphicsDriver : public VideoMemoryGraphicsDriver +{ +public: + const char*GetDriverName() override { return "Direct3D 9"; } + const char*GetDriverID() override { return "D3D9"; } + void SetTintMethod(TintMethod method) override; + bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; + bool SetNativeSize(const Size &src_size) override; + bool SetRenderFrame(const Rect &dst_rect) override; + int GetDisplayDepthForNativeDepth(int native_color_depth) const override; + IGfxModeList *GetSupportedModeList(int color_depth) override; + bool IsModeSupported(const DisplayMode &mode) override; + PGfxFilter GetGraphicsFilter() const override; + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; + int GetCompatibleBitmapFormat(int color_depth) override; + IDriverDependantBitmap* CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; + void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; + void DestroyDDB(IDriverDependantBitmap* bitmap) override; + void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) override; + void SetScreenFade(int red, int green, int blue) override; + void SetScreenTint(int red, int green, int blue) override; + void RenderToBackBuffer() override; + void Render() override; + void Render(int xoff, int yoff, GlobalFlipType flip) override; + bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; + void EnableVsyncBeforeRender(bool enabled) override { } + void Vsync() override; + void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override { _renderSprAtScreenRes = enabled; }; + void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void BoxOutEffect(bool blackingOut, int speed, int delay) override; +#ifndef AGS_NO_VIDEO_PLAYER + bool PlayVideo(const char *filename, bool useSound, VideoSkipType skipType, bool stretchToFullScreen) override; +#endif + bool SupportsGammaControl() override; + void SetGamma(int newGamma) override; + void UseSmoothScaling(bool enabled) override { _smoothScaling = enabled; } + bool RequiresFullRedrawEachFrame() override { return true; } + bool HasAcceleratedTransform() override { return true; } + + typedef std::shared_ptr PD3DFilter; + + // Clears screen rect, coordinates are expected in display resolution + void ClearScreenRect(const Rect &r, RGB *colorToUse); + void UnInit(); + void SetGraphicsFilter(PD3DFilter filter); + + // Internal; TODO: find a way to hide these + int _initDLLCallback(const DisplayMode &mode); + int _resetDeviceIfNecessary(); + + D3DGraphicsDriver(IDirect3D9 *d3d); + ~D3DGraphicsDriver() override; + +private: + PD3DFilter _filter; + + IDirect3D9 *direct3d; + D3DPRESENT_PARAMETERS d3dpp; + IDirect3DDevice9* direct3ddevice; + D3DGAMMARAMP defaultgammaramp; + D3DGAMMARAMP currentgammaramp; + D3DCAPS9 direct3ddevicecaps; + IDirect3DVertexBuffer9* vertexbuffer; + IDirect3DSurface9 *pNativeSurface; + IDirect3DTexture9 *pNativeTexture; + RECT viewport_rect; + UINT availableVideoMemory; + CUSTOMVERTEX defaultVertices[4]; + String previousError; + IDirect3DPixelShader9* pixelShader; + bool _smoothScaling; + bool _legacyPixelShader; + float _pixelRenderXOffset; + float _pixelRenderYOffset; + bool _renderSprAtScreenRes; + + D3DSpriteBatches _spriteBatches; + // TODO: these draw list backups are needed only for the fade-in/out effects + // find out if it's possible to reimplement these effects in main drawing routine. + SpriteBatchDescs _backupBatchDescs; + D3DSpriteBatches _backupBatches; + + D3DVIEWPORT9 _d3dViewport; + + // Called after new mode was successfully initialized + void OnModeSet(const DisplayMode &mode) override; + void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; + void ResetAllBatches() override; + // Called when the direct3d device is created for the first time + int FirstTimeInit(); + void initD3DDLL(const DisplayMode &mode); + void InitializeD3DState(); + void SetupViewport(); + HRESULT ResetD3DDevice(); + // Unset parameters and release resources related to the display mode + void ReleaseDisplayMode(); + void set_up_default_vertices(); + void AdjustSizeToNearestSupportedByCard(int *width, int *height); + void UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap, D3DBitmap *target, bool hasAlpha); + void CreateVirtualScreen(); + void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + bool IsTextureFormatOk( D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat ); + // Backup all draw lists in the temp storage + void BackupDrawLists(); + // Restore draw lists from the temp storage + void RestoreDrawLists(); + // Deletes draw list backups + void ClearDrawBackups(); + void _renderAndPresent(bool clearDrawListAfterwards); + void _render(bool clearDrawListAfterwards); + void _reDrawLastFrame(); + void RenderSpriteBatches(); + void RenderSpriteBatch(const D3DSpriteBatch &batch); + void _renderSprite(const D3DDrawListEntry *entry, const D3DMATRIX &matGlobal); + void _renderFromTexture(); +}; + + +class D3DGraphicsFactory : public GfxDriverFactoryBase +{ +public: + ~D3DGraphicsFactory() override; + + size_t GetFilterCount() const override; + const GfxFilterInfo *GetFilterInfo(size_t index) const override; + String GetDefaultFilterID() const override; + + static D3DGraphicsFactory *GetFactory(); + static D3DGraphicsDriver *GetD3DDriver(); + +private: + D3DGraphicsFactory(); + + D3DGraphicsDriver *EnsureDriverCreated() override; + D3DGfxFilter *CreateFilter(const String &id) override; + + bool Init(); + + static D3DGraphicsFactory *_factory; + // + // IMPORTANT NOTE: since the Direct3d9 device is created with + // D3DCREATE_MULTITHREADED behavior flag, once it is created the d3d9.dll may + // only be unloaded after window is destroyed, as noted in the MSDN's article + // on "D3DCREATE" + // (http://msdn.microsoft.com/en-us/library/windows/desktop/bb172527.aspx). + // Otherwise window becomes either destroyed prematurely or broken (details + // are unclear), which causes errors during Allegro deinitialization. + // + // Curiously, this problem was only confirmed under WinXP so far. + // + // For the purpose of avoiding this problem, we have a static library wrapper + // that unloads library only at the very program exit (except cases of device + // creation failure). + // + // TODO: find out if there is better solution. + // + static Library _library; + IDirect3D9 *_direct3d; +}; + +} // namespace D3D +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_GFX__ALI3DD3D_H diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp new file mode 100644 index 000000000000..de682a804004 --- /dev/null +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -0,0 +1,434 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AVI/MPG player for AGS +// Adapted from MS DirectX Media example program to work with allegro +// 2002 Chris Jones +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) + +//#define ALLEGRO_STATICLINK // already defined in project settings +#include +#include +#include +#include +#include +#include // Multimedia stream interfaces +#include // DirectDraw multimedia stream interfaces +#include // Defines DEFINE_GUID macro and enables GUID initialization +#include "ac/draw.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" +#include "main/game_run.h" +#include "platform/base/agsplatformdriver.h" + +using namespace AGS::Common; +using namespace AGS::Engine; + +//link with the following libraries under project/settings/link... +//amstrmid.lib quartz.lib strmbase.lib ddraw.lib + +extern void update_audio_system_on_game_loop(); +extern void update_polled_stuff_if_runtime(); +extern int ags_mgetbutton(); +extern volatile char want_exit; +extern IGraphicsDriver *gfxDriver; +//int errno; +char lastError[300]; + +//Global variables +HWND ghWnd; +BOOL g_bAppactive = FALSE; // The window is active +bool useSound = true; +volatile bool currentlyPlaying = false; +volatile bool currentlyPaused = false; + +//DirectDrawEx Global interfaces +extern "C" extern LPDIRECTDRAW2 directdraw; +//extern "C" extern IUnknown* directsound; +extern "C" extern BITMAP *gfx_directx_create_system_bitmap(int width, int height); + +//Global MultiMedia streaming interfaces +IMultiMediaStream *g_pMMStream=NULL; +IMediaStream *g_pPrimaryVidStream=NULL; +IDirectDrawMediaStream *g_pDDStream=NULL; +IDirectDrawStreamSample *g_pSample=NULL; + +Bitmap *vscreen = NULL; +Bitmap *vsMemory = NULL; + +//Function prototypes +HRESULT RenderFileToMMStream(LPCTSTR szFilename); +HRESULT InitRenderToSurface(); +void RenderToSurface(); + +void ExitCode() { + //Release MultiMedia streaming Objects + if (g_pMMStream != NULL) { + g_pMMStream->Release(); + g_pMMStream= NULL; + } + if (g_pSample != NULL) { + g_pSample->Release(); + g_pSample = NULL; + } + if (g_pDDStream != NULL) { + g_pDDStream->Release(); + g_pDDStream= NULL; + } + if (g_pPrimaryVidStream != NULL) { + g_pPrimaryVidStream->Release(); + g_pPrimaryVidStream= NULL; + } +} + +typedef struct BMP_EXTRA_INFO { + LPDIRECTDRAWSURFACE2 surf; + struct BMP_EXTRA_INFO *next; + struct BMP_EXTRA_INFO *prev; + int flags; + int lock_nesting; +} BMP_EXTRA_INFO; + +LPDIRECTDRAWSURFACE get_bitmap_surface (Bitmap *bmp) { + BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO*)((BITMAP*)bmp->GetAllegroBitmap())->extra; + + // convert the DDSurface2 back to a standard DDSurface + return (LPDIRECTDRAWSURFACE)bei->surf; +} +LPDIRECTDRAWSURFACE2 get_bitmap_surface2 (Bitmap *bmp) { + BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO*)((BITMAP*)bmp->GetAllegroBitmap())->extra; + + return bei->surf; +} + +//Create the stream sample which will be used to call updates on the video +HRESULT InitRenderToSurface() { + + HRESULT hr; + DDSURFACEDESC ddsd; + + //Use the multimedia stream to get the primary video media stream + hr = g_pMMStream->GetMediaStream(MSPID_PrimaryVideo, &g_pPrimaryVidStream); + if (FAILED(hr)) { + strcpy (lastError, "MMStream::GetMediaStream failed to create the primary video stream."); + return E_FAIL; + } + + //Use the media stream to get the IDirectDrawMediaStream + hr = g_pPrimaryVidStream->QueryInterface(IID_IDirectDrawMediaStream, (void **)&g_pDDStream); + if (FAILED(hr)) { + strcpy(lastError, "The video stream does not support the IDirectDrawMediaStream interface; ensure you have the latest DirectX version installed."); + return E_FAIL; + } + + //Must set dwSize before calling GetFormat + ddsd.dwSize = sizeof(ddsd); + hr = g_pDDStream->GetFormat(&ddsd, NULL, NULL, NULL); + if (FAILED(hr)) { + strcpy(lastError, "IDirectDrawMediaStream::GetFormat failed"); + return E_FAIL; + } + + RECT rect; + rect.top = rect.left = 0; + // these are the width and height of the video + rect.bottom = ddsd.dwHeight; + rect.right = ddsd.dwWidth; + + if (vscreen == NULL) + vscreen = BitmapHelper::CreateRawBitmapOwner(gfx_directx_create_system_bitmap(ddsd.dwWidth, ddsd.dwHeight)); + + if (vscreen == NULL) { + strcpy(lastError, "Unable to create the DX Video System Bitmap"); + return E_FAIL; + } + + vsMemory = BitmapHelper::CreateBitmap(vscreen->GetWidth(), vscreen->GetHeight(), vscreen->GetColorDepth()); + + IDirectDrawSurface *g_pDDSOffscreen; + g_pDDSOffscreen = get_bitmap_surface (vscreen); + + //Create the stream sample + hr = g_pDDStream->CreateSample(g_pDDSOffscreen, &rect, 0, &g_pSample); + if (FAILED(hr)) { + strcpy (lastError, "VideoStream::CreateSample failed"); + return E_FAIL; + } + + return NOERROR; +} + +//Renders a file to a multimedia stream +HRESULT RenderFileToMMStream(LPCTSTR szFilename) { + HRESULT hr; + IAMMultiMediaStream *pAMStream=NULL; + + //Convert filename to Unicode + WCHAR wFile[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, szFilename, -1, wFile, + sizeof(wFile)/sizeof(wFile[0])); + + //Create the AMMultiMediaStream object + hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, + IID_IAMMultiMediaStream, (void **)&pAMStream); + + if (FAILED(hr)) { + strcpy(lastError, "Could not create a CLSID_MultiMediaStream object. " + "Make sure you have the latest version of DirectX installed."); + return E_FAIL; + } + + //Initialize stream + hr = pAMStream->Initialize(STREAMTYPE_READ, 0, NULL); + if (FAILED(hr)) { + strcpy(lastError, "AMStream::Initialize failed."); + return E_FAIL; + } + //Add primary video stream + hr = pAMStream->AddMediaStream(directdraw, &MSPID_PrimaryVideo, 0, NULL); + if (FAILED(hr)) { + strcpy(lastError, "AddMediaStream failed."); + return E_FAIL; + } + //Add primary audio stream + if (useSound) { + //hr = pAMStream->AddMediaStream(directsound, &MSPID_PrimaryAudio, 0, NULL); + hr = pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL); + if (FAILED(hr)) { + strcpy(lastError, "AddMediaStream failed."); + return E_FAIL; + } + } + //Opens and automatically creates a filter graph for the specified media file + hr = pAMStream->OpenFile(wFile, 0); + if (FAILED(hr)) { + pAMStream->Release(); + sprintf(lastError, "File not found or format not supported: %s", szFilename); + return E_FAIL; + } + + //save the local stream to the global variable + g_pMMStream = pAMStream; + // Add a reference to the file + //pAMStream->AddRef(); + + return NOERROR; +} + +int newWidth, newHeight; + +//Perform frame by frame updates and blits. Set the stream +//state to STOP if there are no more frames to update. +void RenderToSurface(Bitmap *vscreen) { + //update each frame + if (g_pSample->Update(0, NULL, NULL, 0) != S_OK) { + g_bAppactive = FALSE; + g_pMMStream->SetState(STREAMSTATE_STOP); + } + else { + g_bAppactive = TRUE; + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + // TODO: don't render on screen bitmap, use gfxDriver->DrawSprite instead! + screen_bmp->Acquire(); + // Because vscreen is a DX Video Bitmap, it can be stretched + // onto the screen (also a Video Bmp) but not onto a memory + // bitmap (which is what "screen" is when using gfx filters) + if (screen_bmp->IsVideoBitmap()) + { + screen_bmp->StretchBlt(vscreen, + RectWH(0, 0, vscreen->GetWidth(), vscreen->GetHeight()), + RectWH(screen_bmp->GetWidth() / 2 - newWidth / 2, + screen_bmp->GetHeight() / 2 - newHeight / 2, + newWidth, newHeight)); + } + else + { + vsMemory->Blit(vscreen, 0, 0, 0, 0, vscreen->GetWidth(), vscreen->GetHeight()); + screen_bmp->StretchBlt(vsMemory, + RectWH(0, 0, vscreen->GetWidth(), vscreen->GetHeight()), + RectWH(screen_bmp->GetWidth() / 2 - newWidth / 2, + screen_bmp->GetHeight() / 2 - newHeight / 2, + newWidth, newHeight)); + } + screen_bmp->Release(); + + // if we're not playing AVI sound, poll the audio system + if (!useSound) + update_audio_system_on_game_loop(); + + render_to_screen(); + } +} + +void dxmedia_pause_video() { + + if (currentlyPlaying) { + currentlyPaused = true; + g_pMMStream->SetState(STREAMSTATE_STOP); + } + +} + +void dxmedia_resume_video() { + + if (currentlyPlaying) { + currentlyPaused = false; + g_pMMStream->SetState(STREAMSTATE_RUN); + } + +} + +void dxmedia_abort_video() { + + if (currentlyPlaying) { + + currentlyPlaying = false; + g_pMMStream->SetState(STREAMSTATE_STOP); + + ExitCode(); + CoUninitialize(); + delete vscreen; + vscreen = NULL; + if (vsMemory != NULL) + { + delete vsMemory; + vsMemory = NULL; + } + strcpy (lastError, "Played successfully."); + } + +} + +int dxmedia_play_video(const char* filename, bool pUseSound, int canskip, int stretch) { + HRESULT hr; + + useSound = pUseSound; + ghWnd = win_get_window(); + + CoInitialize(NULL); + + if (!useSound) + update_polled_stuff_if_runtime(); + + hr = RenderFileToMMStream(filename); + if (FAILED(hr)) { + ExitCode(); + CoUninitialize(); + return -1; + } + + if (!useSound) + update_polled_stuff_if_runtime(); + + hr = InitRenderToSurface(); + if (FAILED(hr)) { + ExitCode(); + CoUninitialize(); + return -1; + } + + newWidth = vscreen->GetWidth(); + newHeight = vscreen->GetHeight(); + + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + + if ((stretch == 1) || + (vscreen->GetWidth() > screen_bmp->GetWidth()) || + (vscreen->GetHeight() > screen_bmp->GetHeight())) { + // If they want to stretch, or if it's bigger than the screen, then stretch + float widthRatio = (float)vscreen->GetWidth() / (float)screen_bmp->GetWidth(); + float heightRatio = (float)vscreen->GetHeight() / (float)screen_bmp->GetHeight(); + + if (widthRatio > heightRatio) { + newWidth = vscreen->GetWidth() / widthRatio; + newHeight = vscreen->GetHeight() / widthRatio; + } + else { + newWidth = vscreen->GetWidth() / heightRatio; + newHeight = vscreen->GetHeight() / heightRatio; + } + } + + //Now set the multimedia stream to RUN + hr = g_pMMStream->SetState(STREAMSTATE_RUN); + g_bAppactive = TRUE; + + if (FAILED(hr)) { + sprintf(lastError, "Unable to play stream: 0x%08X", hr); + ExitCode(); + CoUninitialize(); + delete vscreen; + return -1; + } + // in case we're not full screen, clear the background + screen_bmp->Clear(); + + currentlyPlaying = true; + + gfxDriver->ClearDrawLists(); + + while ((g_bAppactive) && (!want_exit)) { + + while (currentlyPaused) { + platform->YieldCPU(); + } + + RenderToSurface(vscreen); + //Sleep(0); + int key, mbut, mwheelz; + if (run_service_key_controls(key)) { + if ((canskip == 1) && (key == 27)) + break; + if (canskip >= 2) + break; + } + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && (canskip == 3)) + break; + } + + dxmedia_abort_video(); + + return 0; +} + +#if 0 + +int WINAPI WinMain( + HINSTANCE hInstance, // handle to current instance + HINSTANCE hPrevInstance, // handle to previous instance + LPSTR lpCmdLine, // pointer to command line + int nCmdShow) { + + install_allegro(SYSTEM_AUTODETECT, &errno, atexit); + + install_keyboard(); + + set_color_depth(16); + set_gfx_mode (GFX_DIRECTX_WIN, 640, 480, 0,0); + + set_display_switch_mode(SWITCH_BACKGROUND); + + dxmedia_play_video ("f:\\download\\Seinfeld S05E04 - The Sniffing Accountant.mpg", 1, 1); + dxmedia_play_video ("f:\\download\\Family Guy S02E16 - There's Something About Paulie.mpg", 2, 1); + + return 0; +} +#endif + +#endif // AGS_PLATFORM_OS_WINDOWS \ No newline at end of file diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp new file mode 100644 index 000000000000..79adf85b4637 --- /dev/null +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -0,0 +1,962 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AVI/MPG player for AGS +// VMR9-based player to work with D3D +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) + +//#define ALLEGRO_STATICLINK // already defined in project settings +#include +#include +#include +#include +#include +#define DWORD_PTR DWORD* +#define LONG_PTR LONG* +#define LPD3DVECTOR D3DVECTOR* +#define _D3DTYPES_H_ +#define _STRSAFE_H_INCLUDED_ +typedef float D3DVALUE, *LPD3DVALUE; +#include "ac/common.h" +#include "main/game_run.h" +#include "media/video/VMR9Graph.h" +#include "platform/base/agsplatformdriver.h" +//#include +#include "media/audio/audio_system.h" + +#define USES_CONVERSION int _convert = 0; _convert; UINT _acp = CP_ACP; _acp; LPCWSTR _lpw = NULL; _lpw; LPCSTR _lpa = NULL; _lpa + +inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp) +{ + // verify that no illegal character present + // since lpw was allocated based on the size of lpa + // don't worry about the number of chars + lpw[0] = '\0'; + MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars); + return lpw; +} +inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars) +{ + return AtlA2WHelper(lpw, lpa, nChars, CP_ACP); +} +#define ATLA2WHELPER AtlA2WHelper + + #define A2W(lpa) (\ + ((_lpa = lpa) == NULL) ? NULL : (\ + _convert = (lstrlenA(_lpa)+1),\ + ATLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert))) + + +// Interface from main game + +extern int ags_mgetbutton(); +extern void update_audio_system_on_game_loop(); +extern volatile char want_exit; +extern char lastError[300]; +CVMR9Graph *graph = NULL; + +void dxmedia_shutdown_3d() +{ + if (graph != NULL) + { + delete graph; + graph = NULL; + } +} + +int dxmedia_play_video_3d(const char* filename, IDirect3DDevice9 *device, bool useAVISound, int canskip, int stretch) +{ + HWND gameWindow = win_get_window(); + + if (graph == NULL) + { + graph = new CVMR9Graph(gameWindow, device); + } + + if (!useAVISound) + update_audio_system_on_game_loop(); + + if (!graph->SetMediaFile(filename, useAVISound)) + { + dxmedia_shutdown_3d(); + return -1; + } + graph->SetLayerZOrder(0, 0); + + if (!useAVISound) + update_audio_system_on_game_loop(); + + if (!graph->PlayGraph()) + { + dxmedia_shutdown_3d(); + return -1; + } + + + OAFilterState filterState = State_Running; + while ((filterState != State_Stopped) && (!want_exit)) + { + WaitForNextFrame(); + + if (!useAVISound) + update_audio_system_on_game_loop(); + + filterState = graph->GetState(); + + int key, mbut, mwheelz; + if (run_service_key_controls(key)) { + if ((canskip == 1) && (key == 27)) + break; + if (canskip >= 2) + break; + } + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && (canskip == 3)) + break; + + //device->Present(NULL, NULL, 0, NULL); + } + + graph->StopGraph(); + + dxmedia_shutdown_3d(); + return 0; +} + + +// VMR9Graph.cpp: implementation of the CVMR9Graph class. +// +////////////////////////////////////////////////////////////////////// + + +//#include + +#if AGS_PLATFORM_DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +// Function name : CVMR9Graph::CVMR9Graph +// Description : constructor +// Return type : +CVMR9Graph::CVMR9Graph() +{ + InitDefaultValues(); +} + + +// Function name : CVMR9Graph +// Description : constructor +// Return type : +// Argument : HWND MediaWindow +// Argument : int NumberOfStream +CVMR9Graph::CVMR9Graph(HWND MediaWindow, IDirect3DDevice9 *device, int NumberOfStream) +{ + InitDefaultValues(); + + if (MediaWindow != NULL) + { + m_hMediaWindow = MediaWindow; + } + + if (NumberOfStream > 0 && NumberOfStream < 11) { + m_nNumberOfStream = NumberOfStream; + } + + //m_pD3DDevice = device; + m_oldWndProc = GetWindowLong(m_hMediaWindow, GWL_WNDPROC); +} + +// Function name : CVMR9Graph::~CVMR9Graph +// Description : destructor +// Return type : +CVMR9Graph::~CVMR9Graph() +{ + ReleaseAllInterfaces(); + long newProc = GetWindowLong(m_hMediaWindow, GWL_WNDPROC); +} + + +// Function name : CVMR9Graph::InitDefaultValues +// Description : initialize all default values +// Return type : void +void CVMR9Graph::InitDefaultValues() +{ + ZeroMemory(m_pszErrorDescription, 1024); + m_dwRotId = -1; + m_nNumberOfStream = 4; // default VMR9 config + m_hMediaWindow = NULL; + // SRC interfaces + for (int i=0; i<10; i++) { + m_srcFilterArray[i] = NULL; + } + // SOUND interface + m_pDirectSoundFilter = NULL; + // GRAPH interfaces + m_pGraphUnknown = NULL; + m_pGraphBuilder = NULL; + m_pFilterGraph = NULL; + m_pFilterGraph2 = NULL; + m_pMediaControl = NULL; + m_pMediaSeeking = NULL; + //m_pMediaEvent = NULL; + m_pMediaEventEx = NULL; + // VMR9 interfaces + m_pVMRBaseFilter = NULL; + m_pVMRFilterConfig = NULL; + m_pVMRMixerBitmap = NULL; + m_pVMRMixerControl = NULL; + m_pVMRMonitorConfig = NULL; + m_pVMRWindowlessControl = NULL; + // DIRECT3D interfaces + m_pD3DSurface = NULL; +} + +// Function name : CVMR9Graph::ReleaseAllInterfaces +// Description : release all of the graph interfaces +// Return type : void +void CVMR9Graph::ReleaseAllInterfaces() +{ + // CALLBACK handle + /*if (m_pMediaEventEx != NULL) { + m_pMediaEventEx->SetNotifyWindow(NULL, WM_MEDIA_NOTIF, NULL); + }*/ + // SRC interfaces + for (int i=0; i<10; i++) { + IBaseFilter* pSrcFilter = m_srcFilterArray[i]; + if (pSrcFilter != NULL) { + pSrcFilter->Release(); + m_srcFilterArray[i] = NULL; + } + } + // SOUND interfaces + if (m_pDirectSoundFilter != NULL) { + m_pDirectSoundFilter->Release(); + m_pDirectSoundFilter = NULL; + } + // VMR9 interfaces + if (m_pVMRFilterConfig != NULL) { + m_pVMRFilterConfig->Release(); + m_pVMRFilterConfig = NULL; + } + if (m_pVMRMixerBitmap != NULL) { + m_pVMRMixerBitmap->Release(); + m_pVMRMixerBitmap = NULL; + } + if (m_pVMRMixerControl != NULL) { + m_pVMRMixerControl->Release(); + m_pVMRMixerControl = NULL; + } + if (m_pVMRMonitorConfig != NULL) { + m_pVMRMonitorConfig->Release(); + m_pVMRMonitorConfig = NULL; + } + if (m_pVMRWindowlessControl != NULL) { + m_pVMRWindowlessControl->Release(); + m_pVMRWindowlessControl = NULL; + } + if (m_pVMRBaseFilter != NULL) { + m_pVMRBaseFilter->Release(); + m_pVMRBaseFilter = NULL; + } + // GRAPH interfaces + if (m_pGraphBuilder != NULL) { + m_pGraphBuilder->Release(); + m_pGraphBuilder = NULL; + } + if (m_pFilterGraph != NULL) { + m_pFilterGraph->Release(); + m_pFilterGraph = NULL; + } + if (m_pFilterGraph2 != NULL) { + m_pFilterGraph2->Release(); + m_pFilterGraph2 = NULL; + } + if (m_pMediaControl != NULL) { + m_pMediaControl->Release(); + m_pMediaControl = NULL; + } + if (m_pMediaSeeking!= NULL) { + m_pMediaSeeking->Release(); + m_pMediaSeeking = NULL; + } + /*if (m_pMediaEvent != NULL) { + m_pMediaEvent->Release(); + m_pMediaEvent = NULL; + }*/ + /*if (m_pMediaEventEx != NULL) { + m_pMediaEventEx->Release(); + m_pMediaEventEx = NULL; + }*/ + if (m_pGraphUnknown != NULL) { + m_pGraphUnknown->Release(); + m_pGraphUnknown = NULL; + } + // DIRECT3D interfaces + if (m_pD3DSurface != NULL) { + m_pD3DSurface->Release(); + m_pD3DSurface = NULL; + } +} + +////////////////////////////////////////////////////////////////////// +// Helper Functions +////////////////////////////////////////////////////////////////////// + + +// Function name : CVMR9Graph::GetLastError +// Description : get the last error description +// Return type : LPCTSTR +LPCTSTR CVMR9Graph::GetLastError() +{ + return (const char*)m_pszErrorDescription; +} + + +// Function name : CVMR9Graph::AddToRot +// Description : let the graph instance be accessible from graphedit +// Return type : HRESULT +// Argument : IUnknown *pUnkGraph +// Argument : DWORD *pdwRegister +HRESULT CVMR9Graph::AddToRot(IUnknown *pUnkGraph) +{ + if (pUnkGraph == NULL) { + return E_INVALIDARG; + } + + IMoniker * pMoniker; + IRunningObjectTable *pROT; + if (FAILED(GetRunningObjectTable(0, &pROT))) { + return E_FAIL; + } + WCHAR wsz[256]; + wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); + HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); + if (SUCCEEDED(hr)) { + hr = pROT->Register(0, pUnkGraph, pMoniker, &m_dwRotId); + pMoniker->Release(); + } + pROT->Release(); + + return hr; +} + + +// Function name : CVMR9Graph::RemoveFromRot +// Description : remove the graph instance accessibility from graphedit +// Return type : void +void CVMR9Graph::RemoveFromRot() +{ + if (m_dwRotId != -1) { + IRunningObjectTable *pROT; + if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) { + pROT->Revoke(m_dwRotId); + m_dwRotId = -1; + pROT->Release(); + } + } +} + + +// Function name : CVMR9Graph::GetPin +// Description : return the desired pin +// Return type : IPin* +// Argument : IBaseFilter *pFilter +// Argument : PIN_DIRECTION PinDir +IPin* CVMR9Graph::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) +{ + BOOL bFound = FALSE; + IEnumPins *pEnum; + IPin *pPin; + + pFilter->EnumPins(&pEnum); + while(pEnum->Next(1, &pPin, 0) == S_OK) { + PIN_DIRECTION PinDirThis; + pPin->QueryDirection(&PinDirThis); + if (PinDir == PinDirThis) + { + IPin *pTmp = 0; + if (SUCCEEDED(pPin->ConnectedTo(&pTmp))) // Already connected, not the pin we want. + { + pTmp->Release(); + } + else // Unconnected, this is the pin we want. + { + bFound = true; + break; + } + } + pPin->Release(); + } + pEnum->Release(); + + return (bFound ? pPin : 0); +} + + +// Function name : CVMR9Graph::ReportError +// Description : report an error in the dump device +// Return type : void +// Argument : const char* pszError +// Argument : HRESULT hrCode +void CVMR9Graph::ReportError(const char* pszError, HRESULT hrCode) +{ + TCHAR szErr[MAX_ERROR_TEXT_LEN]; + DWORD res = AMGetErrorText(hrCode, szErr, MAX_ERROR_TEXT_LEN); + if (res != 0) { + sprintf(m_pszErrorDescription, "[ERROR in %s, line %d] %s : COM Error 0x%x, %s", __FILE__, __LINE__, pszError, hrCode, szErr); + } else { + sprintf(m_pszErrorDescription, "[ERROR in %s, line %d] %s : COM Error 0x%x", __FILE__, __LINE__, pszError, hrCode); + } + strcpy(lastError, m_pszErrorDescription); + //TRACE("%s \r\n", m_pszErrorDescription); +} + + +// Function name : CVMR9Graph::GetNextFilter +// Description : +// Return type : HRESULT +// Argument : IBaseFilter *pFilter +// Argument : PIN_DIRECTION Dir +// Argument : IBaseFilter **ppNext +HRESULT CVMR9Graph::GetNextFilter(IBaseFilter *pFilter, PIN_DIRECTION Dir, IBaseFilter **ppNext) +{ + if (!pFilter || !ppNext) return E_POINTER; + + IEnumPins *pEnum = 0; + IPin *pPin = 0; + HRESULT hr = pFilter->EnumPins(&pEnum); + if (FAILED(hr)) return hr; + while (S_OK == pEnum->Next(1, &pPin, 0)) { + // See if this pin matches the specified direction. + PIN_DIRECTION ThisPinDir; + hr = pPin->QueryDirection(&ThisPinDir); + if (FAILED(hr)) { + // Something strange happened. + hr = E_UNEXPECTED; + pPin->Release(); + break; + } + if (ThisPinDir == Dir) { + // Check if the pin is connected to another pin. + IPin *pPinNext = 0; + hr = pPin->ConnectedTo(&pPinNext); + if (SUCCEEDED(hr)) + { + // Get the filter that owns that pin. + PIN_INFO PinInfo; + hr = pPinNext->QueryPinInfo(&PinInfo); + pPinNext->Release(); + pPin->Release(); + pEnum->Release(); + if (FAILED(hr) || (PinInfo.pFilter == NULL)) + { + // Something strange happened. + return E_UNEXPECTED; + } + // This is the filter we're looking for. + *ppNext = PinInfo.pFilter; // Client must release. + return S_OK; + } + } + pPin->Release(); + } + pEnum->Release(); + // Did not find a matching filter. + return E_FAIL; +} + + +// Function name : CVMR9Graph::RemoveFilterChain +// Description : remove a chain of filter, stopping at pStopFilter +// Return type : BOOL +// Argument : IBaseFilter* pFilter +// Argument : IBaseFilter* pStopFilter +BOOL CVMR9Graph::RemoveFilterChain(IBaseFilter* pFilter, IBaseFilter* pStopFilter) +{ + HRESULT hr; + + IBaseFilter* pFilterFound = NULL; + + hr = GetNextFilter(pFilter, PINDIR_OUTPUT, &pFilterFound); + if (SUCCEEDED(hr) && pFilterFound != pStopFilter) { + RemoveFilterChain(pFilterFound, pStopFilter); + pFilterFound->Release(); + } + + m_pFilterGraph->RemoveFilter(pFilter); + + return TRUE; +} + + +// Function name : CVMR9Graph::AddFilterByClsid +// Description : add a filter in the chain +// Return type : HRESULT +// Argument : IGraphBuilder *pGraph +// Argument : LPCWSTR wszName +// Argument : const GUID& clsid +// Argument : IBaseFilter **ppF +HRESULT CVMR9Graph::AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, const GUID& clsid, IBaseFilter **ppF) +{ + *ppF = NULL; + HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)ppF); + if (SUCCEEDED(hr)) + { + hr = pGraph->AddFilter((*ppF), wszName); + } + return hr; +} + + +////////////////////////////////////////////////////////////////////// +// Layer helper methods +////////////////////////////////////////////////////////////////////// + + +// Function name : CVMR9Graph::IsValidLayer +// Description : check for valid layer +// Return type : BOOL +// Argument : int nLayer +BOOL CVMR9Graph::IsValidLayer(int nLayer) +{ + if (nLayer > 9 || nLayer < 0) return FALSE; + + IBaseFilter* pBaseFilter = m_srcFilterArray[nLayer]; + if (pBaseFilter == NULL) + return FALSE; + else + return TRUE; +} + + + +////////////////////////////////////////////////////////////////////// +// Graph Construction / Render +////////////////////////////////////////////////////////////////////// + + +// We need this because the filter graph must be built +// on the D3D thread +static int wndproc_build_filter_graph() +{ + return graph->BuildAndRenderGraph(graph->UseAVISound); +} + +BOOL CVMR9Graph::BuildAndRenderGraph(bool withSound) +{ + USES_CONVERSION; + + int nLayer = 0; + HRESULT hr; + + // ENSURE that a valid graph builder is available + if (m_pGraphBuilder == NULL) { + BOOL bRet = BuildFilterGraph(withSound); + if (!bRet) return bRet; + } + + // ENSURE that the filter graph is in a stop state + OAFilterState filterState; + m_pMediaControl->GetState(500, &filterState); + if (filterState != State_Stopped) { + m_pMediaControl->Stop(); + } + + // CHECK a source filter availaibility for the layer + if (m_srcFilterArray[nLayer] == NULL) { + char pszFilterName[10]; + sprintf(pszFilterName, "SRC%02d", nLayer); + IBaseFilter* pBaseFilter = NULL; + hr = m_pGraphBuilder->AddSourceFilter(A2W(m_pszFileName), A2W(pszFilterName), &pBaseFilter); + if (FAILED(hr)) { + ReportError("Could not find a source filter for this file", hr); + return FALSE; + } + m_srcFilterArray[nLayer] = pBaseFilter; + } else { + // suppress the old src filter + IBaseFilter* pBaseFilter = m_srcFilterArray[nLayer]; + RemoveFilterChain(pBaseFilter, m_pVMRBaseFilter); + pBaseFilter->Release(); + m_srcFilterArray[nLayer] = NULL; + // create a new src filter + char pszFilterName[10]; + sprintf(pszFilterName, "SRC%02d", nLayer); + hr = m_pGraphBuilder->AddSourceFilter(A2W(m_pszFileName), A2W(pszFilterName), &pBaseFilter); + m_srcFilterArray[nLayer] = pBaseFilter; + if (FAILED(hr)) { + m_srcFilterArray[nLayer] = NULL; + ReportError("Could not load the file", hr); + return FALSE; + } + } + + // RENDER the graph + BOOL bRet = RenderGraph(); + if (!bRet) return bRet; + + return TRUE; +} + +// Function name : CVMR9Graph::SetMediaFile +// Description : set a media source +// Return type : BOOL +// Argument : const char* pszFileName +// Argument : int nLayer = 0 +BOOL CVMR9Graph::SetMediaFile(const char* pszFileName, bool withSound, int nLayer) +{ + + if (pszFileName == NULL) { + ReportError("Could not load a file with an empty file name", E_INVALIDARG); + return FALSE; + } + + UseAVISound = withSound; + m_pszFileName = pszFileName; + + if (!wnd_call_proc(wndproc_build_filter_graph)) + return FALSE; + + + return TRUE; +} + +// Function name : CVMR9Graph::BuildFilterGraph +// Description : construct the filter graph +// Return type : BOOL +BOOL CVMR9Graph::BuildFilterGraph(bool withSound) +{ + HRESULT hr; + + ReleaseAllInterfaces(); + RemoveFromRot(); + + // BUILD the filter graph + hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IUnknown, (void**) &m_pGraphUnknown); + if (FAILED(hr)) { + ReportError("Could not build the graph", hr); + return FALSE; + } + // QUERY the filter graph interfaces + hr = m_pGraphUnknown->QueryInterface(IID_IGraphBuilder, (void**) &m_pGraphBuilder); + hr = m_pGraphUnknown->QueryInterface(IID_IFilterGraph, (void**) &m_pFilterGraph); + hr = m_pGraphUnknown->QueryInterface(IID_IFilterGraph2, (void**) &m_pFilterGraph2); + hr = m_pGraphUnknown->QueryInterface(IID_IMediaControl, (void**) & m_pMediaControl); + hr = m_pGraphUnknown->QueryInterface(IID_IMediaSeeking, (void**) & m_pMediaSeeking); + //hr = m_pGraphUnknown->QueryInterface(IID_IMediaEvent, (void**) &m_pMediaEvent); + //hr = m_pGraphUnknown->QueryInterface(IID_IMediaEventEx, (void**) &m_pMediaEventEx); + +/* // SET the graph state window callback + if (m_pMediaEventEx != NULL) { + m_pMediaEventEx->SetNotifyWindow((OAHWND)m_hMediaWindow, WM_MEDIA_NOTIF, NULL); + //m_pMediaEventEx->SetNotifyWindow(NULL, NULL, NULL); + }*/ + + if (withSound) + BuildSoundRenderer(); + +// Don't known what's wrong... but RenderEx crash when playing whith graphedit build 021204 ... + //do we need this?? + //AddToRot(m_pGraphUnknown); + + return BuildVMR(); +} + + +// Function name : CVMR9Graph::BuildVMR +// Description : construct and add the VMR9 renderer to the graph +// Return type : BOOL +BOOL CVMR9Graph::BuildVMR() +{ + HRESULT hr; + + if (m_hMediaWindow == NULL) { + ReportError("Could not operate without a Window", E_FAIL); + return FALSE; + } + + if (m_pGraphBuilder == NULL) { + ReportError("Could not build the VMR, the graph isn't valid", E_FAIL); + return FALSE; + } + + // BUILD the VMR9 + IBaseFilter *pVmr = NULL; + hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**) &m_pVMRBaseFilter); + if (FAILED(hr)) { + ReportError("Could not create an instance ofthe VMR9", hr); + return FALSE; + } + + // ADD the VMR9 to the graph + hr = m_pGraphBuilder->AddFilter(m_pVMRBaseFilter, L"VMR9"); + if (FAILED(hr)) { + ReportError("Could not add the VMR9 to the Graph", hr); + return FALSE; + } + + // DIRECT3D + //BOOL bD3D = BuildDirect3d(); + + // QUERY the VMR9 interfaces + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRFilterConfig9, (void**) &m_pVMRFilterConfig); + if (SUCCEEDED(hr)) { + // CONFIGURE the VMR9 + m_pVMRFilterConfig->SetRenderingMode(VMR9Mode_Windowless); + m_pVMRFilterConfig->SetNumberOfStreams(m_nNumberOfStream); + } + + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRWindowlessControl9, (void**) &m_pVMRWindowlessControl); + if (SUCCEEDED(hr)) { + // CONFIGURE the VMR9 + m_pVMRWindowlessControl->SetVideoClippingWindow(m_hMediaWindow); + m_pVMRWindowlessControl->SetAspectRatioMode(VMR9ARMode_LetterBox); + } + + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMixerBitmap9, (void**) &m_pVMRMixerBitmap); + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMixerControl9, (void**) &m_pVMRMixerControl); + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMonitorConfig9, (void**) &m_pVMRMonitorConfig); + + return TRUE; +} + + +// Function name : CVMR9Graph::BuildSoundRendered +// Description : build the DirectSound renderer +// Return type : BOOL +BOOL CVMR9Graph::BuildSoundRenderer() +{ + HRESULT hr; + + hr = AddFilterByClsid(m_pGraphBuilder, L"DirectSound", CLSID_DSoundRender, &m_pDirectSoundFilter); + if (FAILED(hr)) { + ReportError("Could not add the DirectSoundRenderer", hr); + return FALSE; + } + return TRUE; +} + +// Function name : CVMR9Graph::RenderGraph +// Description : render the graph +// Return type : BOOL +BOOL CVMR9Graph::RenderGraph() +{ + HRESULT hr; + + if (m_pFilterGraph2 == NULL) { + ReportError("Could not render the graph because it is not fully constructed", E_FAIL); + return FALSE; + } + + for (int i=0; i<10; i++) { + IBaseFilter* pBaseFilter = m_srcFilterArray[i]; + if (pBaseFilter != NULL) { + IPin* pPin; + while ((pPin = GetPin(pBaseFilter, PINDIR_OUTPUT)) != NULL) + { + hr = m_pFilterGraph2->RenderEx(pPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL); + if (FAILED(hr)) + { + ReportError("Unable to render the pin", hr); + return FALSE; + } + } + } + } + return TRUE; +} + + +// Function name : CVMR9Graph::PreserveAspectRatio +// Description : set aspect ratio mode +// Return type : BOOL +// Argument : BOOL bPreserve +BOOL CVMR9Graph::PreserveAspectRatio(BOOL bPreserve) +{ + if (m_pVMRWindowlessControl == NULL) { + ReportError("Can't set aspect ratio, no VMR", E_FAIL); + return FALSE; + } + + if (bPreserve) + m_pVMRWindowlessControl->SetAspectRatioMode(VMR9ARMode_LetterBox); + else + m_pVMRWindowlessControl->SetAspectRatioMode(VMR9ARMode_None); + + return TRUE; +} + + +// Function name : CVMR9Graph::AddFilter +// Description : manually add a filter in the graph +// Return type : IBaseFilter* : caller responsible of release +// Argument : const char* pszName +// Argument : const GUID& clsid +IBaseFilter* CVMR9Graph::AddFilter(const char* pszName, const GUID& clsid) +{ + USES_CONVERSION; + + HRESULT hr; + + IBaseFilter* pBaseFilter = NULL; + + if (pszName == NULL) { + ReportError("Can't add filter, no valid name", E_INVALIDARG); + return NULL; + } + + hr = AddFilterByClsid(m_pGraphBuilder, A2W(pszName), clsid, &pBaseFilter); + if (FAILED(hr)) { + ReportError("Can't add filter", hr); + return NULL; + } + + return pBaseFilter; +} + +// Function name : CVMR9Graph::PlayGraph +// Description : run the graph +// Return type : BOOL +BOOL CVMR9Graph::PlayGraph() +{ + if (m_pMediaControl == NULL) { + ReportError("Can't play, no graph", E_FAIL); + return FALSE; + } + if (m_pVMRWindowlessControl == NULL) { + ReportError("Can't play, no VMR", E_FAIL); + return FALSE; + } + + // MEDIA SIZE + LONG Width; + LONG Height; + LONG ARWidth; + LONG ARHeight; + m_pVMRWindowlessControl->GetNativeVideoSize(&Width, &Height, &ARWidth, &ARHeight); + + RECT mediaRect; + mediaRect.left = 0; + mediaRect.top = 0; + mediaRect.right = Width; + mediaRect.bottom = Height; + + RECT wndRect; + GetClientRect(m_hMediaWindow, &wndRect); + + m_pVMRWindowlessControl->SetVideoPosition(&mediaRect, &wndRect); + + // RUN + m_pMediaControl->Run(); + + return TRUE; +} + + +// Function name : CVMR9Graph::StopGraph +// Description : stop the graph +// Return type : BOOL +BOOL CVMR9Graph::StopGraph() +{ + if (m_pMediaControl == NULL) { + ReportError("Can't stop, no graph", E_FAIL); + return FALSE; + } + + m_pMediaControl->Stop(); + + return TRUE; +} + +OAFilterState CVMR9Graph::GetState() +{ + OAFilterState filterState; + m_pMediaControl->GetState(500, &filterState); + if (filterState == State_Running) + { + LONGLONG curPos; + m_pMediaSeeking->GetCurrentPosition(&curPos); + LONGLONG length; + m_pMediaSeeking->GetDuration(&length); + + if (curPos >= length) + { + filterState = State_Stopped; + } + } + + return filterState; +} + + +// Function name : CVMR9Graph::ResetGraph +// Description : reset the graph - clean interfaces +// Return type : BOOL +BOOL CVMR9Graph::ResetGraph() +{ + // STOP the graph + if (m_pMediaControl != NULL) { + m_pMediaControl->Stop(); + } + + try { + ReleaseAllInterfaces(); + } catch(...) { + ReportError("Can't reset graph, we have serious bugs...", E_FAIL); + return FALSE; + } + + return TRUE; +} + + +// Function name : SetLayerZOrder +// Description : set z order of the layer +// Return type : BOOL +// Argument : int nLayer +// Argument : DWORD dwZOrder : bigger is away +BOOL CVMR9Graph::SetLayerZOrder(int nLayer, DWORD dwZOrder) +{ + HRESULT hr; + + if (!IsValidLayer(nLayer)) { + ReportError("Can't set order, incorect layer", E_INVALIDARG); + return FALSE; + } + + if (m_pVMRMixerControl == NULL) { + ReportError("Can't set order, no VMR", E_FAIL); + return FALSE; + } + + hr = m_pVMRMixerControl->SetZOrder(nLayer, dwZOrder); + if (FAILED(hr)) { + ReportError("Can't set ZOrder", hr); + return FALSE; + } + + return TRUE; +} + +#endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/windows/minidump.cpp b/engines/ags/engine/platform/windows/minidump.cpp new file mode 100644 index 000000000000..b71dde460d8a --- /dev/null +++ b/engines/ags/engine/platform/windows/minidump.cpp @@ -0,0 +1,111 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG +#define UNICODE +#include // sprintf +#include "windows.h" +#include +#include "main/main.h" + +CONTEXT cpustate; +EXCEPTION_RECORD excinfo; +int miniDumpResultCode = 0; + +typedef enum _MINIDUMP_TYPE { + MiniDumpNormal = 0x0000, + MiniDumpWithDataSegs = 0x0001, + MiniDumpWithFullMemory = 0x0002, + MiniDumpWithHandleData = 0x0004, + MiniDumpFilterMemory = 0x0008, + MiniDumpScanMemory = 0x0010, + MiniDumpWithUnloadedModules = 0x0020, + MiniDumpWithIndirectlyReferencedMemory = 0x0040, + MiniDumpFilterModulePaths = 0x0080, + MiniDumpWithProcessThreadData = 0x0100, + MiniDumpWithPrivateReadWriteMemory = 0x0200, + MiniDumpWithoutOptionalData = 0x0400, +} MINIDUMP_TYPE; + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION { + DWORD ThreadId; + PEXCEPTION_POINTERS ExceptionPointers; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; + +typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, + HANDLE hFile, MINIDUMP_TYPE DumpType, + CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + CONST void* UserStreamParam, + CONST void* CallbackParam); + +MINIDUMPWRITEDUMP _MiniDumpWriteDump; + + +void CreateMiniDump( EXCEPTION_POINTERS* pep ) +{ + HMODULE dllHandle = LoadLibrary(L"dbghelp.dll"); + if (dllHandle == NULL) + { + miniDumpResultCode = 1; + return; + } + + _MiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress(dllHandle, "MiniDumpWriteDump"); + if (_MiniDumpWriteDump == NULL) + { + FreeLibrary(dllHandle); + miniDumpResultCode = 2; + return; + } + + char fileName[80]; + sprintf(fileName, "CrashInfo.%s.dmp", EngineVersion.LongString.GetCStr()); + HANDLE hFile = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, + 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) + { + MINIDUMP_EXCEPTION_INFORMATION mdei; + + mdei.ThreadId = GetCurrentThreadId(); + mdei.ExceptionPointers = pep; + mdei.ClientPointers = FALSE; + + MINIDUMP_TYPE mdt = MiniDumpNormal; //MiniDumpWithPrivateReadWriteMemory; + + BOOL rv = _MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), + hFile, mdt, (pep != 0) ? &mdei : 0, NULL, NULL); + + if (!rv) + miniDumpResultCode = 4; + + CloseHandle(hFile); + } + else + miniDumpResultCode = 3; + + FreeLibrary(dllHandle); +} + +int CustomExceptionHandler (LPEXCEPTION_POINTERS exinfo) { + cpustate = exinfo->ContextRecord[0]; + excinfo = exinfo->ExceptionRecord[0]; + CreateMiniDump(exinfo); + + return EXCEPTION_EXECUTE_HANDLER; +} + +#endif // AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG diff --git a/engines/ags/engine/platform/windows/setup/winsetup.cpp b/engines/ags/engine/platform/windows/setup/winsetup.cpp new file mode 100644 index 000000000000..ea4f77fc7ecb --- /dev/null +++ b/engines/ags/engine/platform/windows/setup/winsetup.cpp @@ -0,0 +1,1255 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ac/gamestructdefines.h" +#undef RGB +#undef PALETTE +#define RGB void* +#define PALETTE void* +#include "gfx/gfxdriverfactory.h" +#include "gfx/gfxfilter.h" +#include "gfx/graphicsdriver.h" +#include "main/config.h" +#include "main/graphics_mode.h" +#include "platform/base/agsplatformdriver.h" +#include "resource/resource.h" +#include "util/file.h" +#include "util/string_utils.h" + +#define AL_ID(a,b,c,d) (((a)<<24) | ((b)<<16) | ((c)<<8) | (d)) + +#define DIGI_DIRECTAMX(n) AL_ID('A','X','A'+(n),' ') +// This DirectX hardware mixer is crap, it crashes the program +// when two sound effects are played at once +#define DIGI_DIRECTX(n) AL_ID('D','X','A'+(n),' ') +#define DIGI_WAVOUTID(n) AL_ID('W','O','A'+(n),' ') +#define DIGI_NONE 0 +#define MIDI_AUTODETECT -1 +#define MIDI_NONE 0 +#define MIDI_WIN32MAPPER AL_ID('W','3','2','M') + +extern "C" +{ + HWND win_get_window(); +} + +namespace AGS +{ +namespace Engine +{ + +using namespace AGS::Common; + +//============================================================================= +// +// WinConfig struct, keeps all configurable data. +// +//============================================================================= +struct WinConfig +{ + String Title; + String VersionString; + + String DataDirectory; + String UserSaveDir; + GameResolutionType GameResType; + Size GameResolution; + int GameColourDepth; + bool LetterboxByDesign; + + String GfxDriverId; + String GfxFilterId; + Size ScreenSize; + GameFrameSetup FsGameFrame; + GameFrameSetup WinGameFrame; + int RefreshRate; + bool Windowed; + bool VSync; + bool RenderAtScreenRes; + bool AntialiasSprites; + + int DigiID; + int MidiID; + bool ThreadedAudio; + bool UseVoicePack; + + bool MouseAutoLock; + float MouseSpeed; + + int SpriteCacheSize; + String DefaultLanguageName; + String Language; + + WinConfig(); + void SetDefaults(); + void Load(const ConfigTree &cfg); + void Save(ConfigTree &cfg); +}; + +WinConfig::WinConfig() +{ + SetDefaults(); +} + +void WinConfig::SetDefaults() +{ + DataDirectory = "."; + GameResType = kGameResolution_Undefined; + GameColourDepth = 0; + LetterboxByDesign = false; + + GfxFilterId = "StdScale"; + GfxDriverId = "D3D9"; + ScreenSize = get_desktop_size(); + FsGameFrame.ScaleDef = kFrame_MaxProportional; + WinGameFrame.ScaleDef = kFrame_MaxRound; + RefreshRate = 0; + Windowed = false; + VSync = false; + RenderAtScreenRes = false; + AntialiasSprites = false; + + MouseAutoLock = false; + MouseSpeed = 1.f; + + DigiID = -1; // autodetect + MidiID = -1; + ThreadedAudio = false; + UseVoicePack = true; + + SpriteCacheSize = 1024 * 128; + DefaultLanguageName = "Game Default"; + + Title = "Game Setup"; +} + +void WinConfig::Load(const ConfigTree &cfg) +{ + DataDirectory = INIreadstring(cfg, "misc", "datadir", DataDirectory); + UserSaveDir = INIreadstring(cfg, "misc", "user_data_dir"); + // Backward-compatible resolution type + GameResType = (GameResolutionType)INIreadint(cfg, "misc", "defaultres", GameResType); + if (GameResType < kGameResolution_Undefined || GameResType >= kNumGameResolutions) + GameResType = kGameResolution_Undefined; + GameResolution.Width = INIreadint(cfg, "misc", "game_width", GameResolution.Width); + GameResolution.Height = INIreadint(cfg, "misc", "game_height", GameResolution.Height); + GameColourDepth = INIreadint(cfg, "misc", "gamecolordepth", GameColourDepth); + LetterboxByDesign = INIreadint(cfg, "misc", "letterbox", 0) != 0; + + GfxDriverId = INIreadstring(cfg, "graphics", "driver", GfxDriverId); + GfxFilterId = INIreadstring(cfg, "graphics", "filter", GfxFilterId); + ScreenSize.Width = INIreadint(cfg, "graphics", "screen_width", ScreenSize.Width); + ScreenSize.Height = INIreadint(cfg, "graphics", "screen_height", ScreenSize.Height); + + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_fs", make_scaling_option(FsGameFrame)), FsGameFrame); + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_win", make_scaling_option(WinGameFrame)), WinGameFrame); + + RefreshRate = INIreadint(cfg, "graphics", "refresh", RefreshRate); + Windowed = INIreadint(cfg, "graphics", "windowed", Windowed ? 1 : 0) != 0; + VSync = INIreadint(cfg, "graphics", "vsync", VSync ? 1 : 0) != 0; + RenderAtScreenRes = INIreadint(cfg, "graphics", "render_at_screenres", RenderAtScreenRes ? 1 : 0) != 0; + + AntialiasSprites = INIreadint(cfg, "misc", "antialias", AntialiasSprites ? 1 : 0) != 0; + + DigiID = read_driverid(cfg, "sound", "digiid", DigiID); + MidiID = read_driverid(cfg, "sound", "midiid", MidiID); + ThreadedAudio = INIreadint(cfg, "sound", "threaded", ThreadedAudio ? 1 : 0) != 0; + UseVoicePack = INIreadint(cfg, "sound", "usespeech", UseVoicePack ? 1 : 0) != 0; + + MouseAutoLock = INIreadint(cfg, "mouse", "auto_lock", MouseAutoLock ? 1 : 0) != 0; + MouseSpeed = INIreadfloat(cfg, "mouse", "speed", 1.f); + if (MouseSpeed <= 0.f) + MouseSpeed = 1.f; + + SpriteCacheSize = INIreadint(cfg, "misc", "cachemax", SpriteCacheSize); + Language = INIreadstring(cfg, "language", "translation", Language); + DefaultLanguageName = INIreadstring(cfg, "language", "default_translation_name", DefaultLanguageName); + + Title = INIreadstring(cfg, "misc", "titletext", Title); +} + +void WinConfig::Save(ConfigTree &cfg) +{ + INIwritestring(cfg, "misc", "user_data_dir", UserSaveDir); + + INIwritestring(cfg, "graphics", "driver", GfxDriverId); + INIwritestring(cfg, "graphics", "filter", GfxFilterId); + INIwritestring(cfg, "graphics", "screen_def", Windowed ? "scaling" : "explicit"); + INIwriteint(cfg, "graphics", "screen_width", ScreenSize.Width); + INIwriteint(cfg, "graphics", "screen_height", ScreenSize.Height); + INIwritestring(cfg, "graphics", "game_scale_fs", make_scaling_option(FsGameFrame)); + INIwritestring(cfg, "graphics", "game_scale_win", make_scaling_option(WinGameFrame)); + INIwriteint(cfg, "graphics", "refresh", RefreshRate); + INIwriteint(cfg, "graphics", "windowed", Windowed ? 1 : 0); + INIwriteint(cfg, "graphics", "vsync", VSync ? 1 : 0); + INIwriteint(cfg, "graphics", "render_at_screenres", RenderAtScreenRes ? 1 : 0); + + INIwriteint(cfg, "misc", "antialias", AntialiasSprites ? 1 : 0); + + write_driverid(cfg, "sound", "digiid", DigiID); + write_driverid(cfg, "sound", "midiid", MidiID); + INIwriteint(cfg, "sound", "threaded", ThreadedAudio ? 1 : 0); + INIwriteint(cfg, "sound", "usespeech", UseVoicePack ? 1 : 0); + + INIwriteint(cfg, "mouse", "auto_lock", MouseAutoLock ? 1 : 0); + INIwritestring(cfg, "mouse", "speed", String::FromFormat("%0.1f", MouseSpeed)); + + INIwriteint(cfg, "misc", "cachemax", SpriteCacheSize); + INIwritestring(cfg, "language", "translation", Language); +} + + +//============================================================================= +// +// WinAPI interaction helpers +// +//============================================================================= + +int AddString(HWND hwnd, LPCTSTR text, DWORD_PTR data = 0L) +{ + int index = SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)text); + if (index >= 0) + SendMessage(hwnd, CB_SETITEMDATA, index, data); + return index; +} + +int InsertString(HWND hwnd, LPCTSTR text, int at_index, DWORD_PTR data = 0L) +{ + int index = SendMessage(hwnd, CB_INSERTSTRING, at_index, (LPARAM)text); + if (index >= 0) + SendMessage(hwnd, CB_SETITEMDATA, index, data); + return index; +} + +int GetItemCount(HWND hwnd) +{ + return SendMessage(hwnd, CB_GETCOUNT, 0, 0L); +} + +bool GetCheck(HWND hwnd) +{ + return SendMessage(hwnd, BM_GETCHECK, 0, 0) != FALSE; +} + +void SetCheck(HWND hwnd, bool check) +{ + SendMessage(hwnd, BM_SETCHECK, check ? BST_CHECKED : BST_UNCHECKED, 0); +} + +int GetCurSel(HWND hwnd) +{ + return SendMessage(hwnd, CB_GETCURSEL, 0, 0); +} + +void SetCurSel(HWND hwnd, int cur_sel) +{ + SendMessage(hwnd, CB_SETCURSEL, cur_sel, 0); +} + +typedef bool (*PfnCompareCBItemData)(DWORD_PTR data1, DWORD_PTR data2); + +bool CmpICBItemDataAsStr(DWORD_PTR data1, DWORD_PTR data2) +{ + LPCTSTR text_ptr1 = (LPCTSTR)data1; + LPCTSTR text_ptr2 = (LPCTSTR)data2; + return text_ptr1 && text_ptr2 && StrCmpI(text_ptr1, text_ptr2) == 0 || !text_ptr1 && !text_ptr2; +} + +int SetCurSelToItemData(HWND hwnd, DWORD_PTR data, PfnCompareCBItemData pfn_cmp = NULL, int def_sel = -1) +{ + int count = SendMessage(hwnd, CB_GETCOUNT, 0, 0); + for (int i = 0; i < count; ++i) + { + DWORD_PTR item_data = SendMessage(hwnd, CB_GETITEMDATA, i, 0); + if (pfn_cmp && pfn_cmp(item_data, data) || !pfn_cmp && item_data == data) + { + LRESULT res = SendMessage(hwnd, CB_SETCURSEL, i, 0); + if (res != CB_ERR) + return res; + break; + } + } + return SendMessage(hwnd, CB_SETCURSEL, def_sel, 0); +} + +int SetCurSelToItemDataStr(HWND hwnd, LPCTSTR text, int def_sel = -1) +{ + return SetCurSelToItemData(hwnd, (DWORD_PTR)text, CmpICBItemDataAsStr, def_sel); +} + +DWORD_PTR GetCurItemData(HWND hwnd, DWORD_PTR def_value = 0) +{ + int index = SendMessage(hwnd, CB_GETCURSEL, 0, 0); + if (index >= 0) + return SendMessage(hwnd, CB_GETITEMDATA, index, 0); + return def_value; +} + +String GetText(HWND hwnd) +{ + TCHAR short_buf[MAX_PATH + 1]; + int len = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); + if (len > 0) + { + TCHAR *buf = len >= sizeof(short_buf) ? new TCHAR[len + 1] : short_buf; + SendMessage(hwnd, WM_GETTEXT, len + 1, (LPARAM)buf); + String s = buf; + if (buf != short_buf) + delete [] buf; + return s; + } + return ""; +} + +void SetText(HWND hwnd, LPCTSTR text) +{ + SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)text); +} + +void ResetContent(HWND hwnd) +{ + SendMessage(hwnd, CB_RESETCONTENT, 0, 0); +} + +void SetSliderRange(HWND hwnd, int min, int max) +{ + SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(min, max)); +} + +int GetSliderPos(HWND hwnd) +{ + return SendMessage(hwnd, TBM_GETPOS, 0, 0); +} + +void SetSliderPos(HWND hwnd, int pos) +{ + SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); +} + +void MakeFullLongPath(const char *path, char *out_buf, int buf_len) +{ + GetFullPathName(path, buf_len, out_buf, NULL); + GetLongPathName(out_buf, out_buf, buf_len); +} + + +//============================================================================= +// +// Browse-for-folder dialog +// +//============================================================================= + +int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + if (uMsg == BFFM_INITIALIZED) + { + // Set initial selection + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpData); + } + return 0; +} + +bool BrowseForFolder(String &dir_buf) +{ + bool res = false; + CoInitialize(NULL); + + BROWSEINFO bi = { 0 }; + bi.lpszTitle = "Select location for game saves and custom data files"; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS; + bi.lpfn = BrowseCallbackProc; + bi.lParam = (LPARAM)dir_buf.GetCStr(); + LPITEMIDLIST pidl = SHBrowseForFolder ( &bi ); + if (pidl) + { + char path[MAX_PATH]; + if (SHGetPathFromIDList(pidl, path) != FALSE) + { + dir_buf = path; + res = true; + } + CoTaskMemFree(pidl); + } + + CoUninitialize(); + return res; +} + + +//============================================================================= +// +// WinSetupDialog, handles the dialog UI. +// +//============================================================================= +class WinSetupDialog +{ +public: + enum GfxModeSpecial + { + kGfxMode_None = -1, + kGfxMode_Desktop = -2, + kGfxMode_GameRes = -3, + }; + + static const int MouseSpeedMin = 1; + static const int MouseSpeedMax = 100; + +public: + WinSetupDialog(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &data_dir, const String &version_str); + ~WinSetupDialog(); + static SetupReturnValue ShowModal(const ConfigTree &cfg_in, ConfigTree &cfg_out, + const String &data_dir, const String &version_str); + +private: + static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + + // Event handlers + INT_PTR OnInitDialog(HWND hwnd); + INT_PTR OnCommand(WORD id); + INT_PTR OnListSelection(WORD id); + void OnCustomSaveDirBtn(); + void OnCustomSaveDirCheck(); + void OnGfxDriverUpdate(); + void OnGfxFilterUpdate(); + void OnGfxModeUpdate(); + void OnScalingUpdate(HWND hlist, GameFrameSetup &frame_setup, bool windowed); + void OnWindowedUpdate(); + void ShowAdvancedOptions(); + + // Helper structs + typedef std::vector VDispModes; + // NOTE: we have to implement IGfxModeList for now because we are using + // few engine functions that take IGfxModeList as parameter + struct GfxModes : public IGfxModeList + { + VDispModes Modes; + + virtual int GetModeCount() const; + virtual bool GetMode(int index, DisplayMode &mode) const; + }; + + typedef std::vector VFilters; + struct DriverDesc + { + String Id; // internal id + String UserName; // human-friendly driver name + GfxModes GfxModeList; // list of supported modes + VFilters FilterList; // list of supported filters + int UseColorDepth; // recommended display depth + }; + + // Operations + void AddScalingString(HWND hlist, int scaling_factor); + void FillGfxFilterList(); + void FillGfxModeList(); + void FillLanguageList(); + void FillScalingList(HWND hlist, GameFrameSetup &frame_setup, bool windowed); + void InitGfxModes(); + void InitDriverDescFromFactory(const String &id); + void SaveSetup(); + void SelectNearestGfxMode(const Size screen_size); + void SetGfxModeText(); + void UpdateMouseSpeedText(); + + // Dialog singleton and properties + static WinSetupDialog *_dlg; + HWND _hwnd; + WinConfig _winCfg; + const ConfigTree &_cfgIn; + ConfigTree &_cfgOut; + // Window size + Size _winSize; + Size _baseSize; + // Driver descriptions + typedef std::shared_ptr PDriverDesc; + typedef std::map DriverDescMap; + DriverDescMap _drvDescMap; + PDriverDesc _drvDesc; + GfxFilterInfo _gfxFilterInfo; + // Resolution limits + Size _desktopSize; + Size _maxWindowSize; + Size _minGameSize; + int _maxGameScale = 0; + int _minGameScale = 0; + + // Dialog controls + HWND _hVersionText = NULL; + HWND _hCustomSaveDir = NULL; + HWND _hCustomSaveDirBtn = NULL; + HWND _hCustomSaveDirCheck = NULL; + HWND _hGfxDriverList = NULL; + HWND _hGfxModeList = NULL; + HWND _hGfxFilterList = NULL; + HWND _hFsScalingList = NULL; + HWND _hWinScalingList = NULL; + HWND _hDigiDriverList = NULL; + HWND _hMidiDriverList = NULL; + HWND _hLanguageList = NULL; + HWND _hSpriteCacheList = NULL; + HWND _hWindowed = NULL; + HWND _hVSync = NULL; + HWND _hRenderAtScreenRes = NULL; + HWND _hRefresh85Hz = NULL; + HWND _hAntialiasSprites = NULL; + HWND _hThreadedAudio = NULL; + HWND _hUseVoicePack = NULL; + HWND _hAdvanced = NULL; + HWND _hGameResolutionText = NULL; + HWND _hGfxModeText = NULL; + HWND _hMouseLock = NULL; + HWND _hMouseSpeed = NULL; + HWND _hMouseSpeedText = NULL; +}; + +WinSetupDialog *WinSetupDialog::_dlg = NULL; + +WinSetupDialog::WinSetupDialog(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &data_dir, const String &version_str) + : _hwnd(NULL) + , _cfgIn(cfg_in) + , _cfgOut(cfg_out) +{ + _winCfg.DataDirectory = data_dir; + _winCfg.VersionString = version_str; +} + +WinSetupDialog::~WinSetupDialog() +{ +} + +SetupReturnValue WinSetupDialog::ShowModal(const ConfigTree &cfg_in, ConfigTree &cfg_out, + const String &data_dir, const String &version_str) +{ + _dlg = new WinSetupDialog(cfg_in, cfg_out, data_dir, version_str); + INT_PTR dlg_res = DialogBoxParam(GetModuleHandle(NULL), (LPCTSTR)IDD_SETUP, win_get_window(), + (DLGPROC)WinSetupDialog::DialogProc, 0L); + delete _dlg; + _dlg = NULL; + + switch (dlg_res) + { + case IDOKRUN: return kSetup_RunGame; + case IDOK: return kSetup_Done; + default: return kSetup_Cancel; + } +} + +INT_PTR WinSetupDialog::OnInitDialog(HWND hwnd) +{ + _hwnd = hwnd; + _hVersionText = GetDlgItem(_hwnd, IDC_VERSION); + _hCustomSaveDir = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIR); + _hCustomSaveDirBtn = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIRBTN); + _hCustomSaveDirCheck = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIRCHECK); + _hGfxDriverList = GetDlgItem(_hwnd, IDC_GFXDRIVER); + _hGfxModeList = GetDlgItem(_hwnd, IDC_GFXMODE); + _hGfxFilterList = GetDlgItem(_hwnd, IDC_GFXFILTER); + _hFsScalingList = GetDlgItem(_hwnd, IDC_FSSCALING); + _hWinScalingList = GetDlgItem(_hwnd, IDC_WINDOWSCALING); + _hDigiDriverList = GetDlgItem(_hwnd, IDC_DIGISOUND); + _hMidiDriverList = GetDlgItem(_hwnd, IDC_MIDIMUSIC); + _hLanguageList = GetDlgItem(_hwnd, IDC_LANGUAGE); + _hSpriteCacheList = GetDlgItem(_hwnd, IDC_SPRITECACHE); + _hWindowed = GetDlgItem(_hwnd, IDC_WINDOWED); + _hVSync = GetDlgItem(_hwnd, IDC_VSYNC); + _hRenderAtScreenRes = GetDlgItem(_hwnd, IDC_RENDERATSCREENRES); + _hRefresh85Hz = GetDlgItem(_hwnd, IDC_REFRESH_85HZ); + _hAntialiasSprites = GetDlgItem(_hwnd, IDC_ANTIALIAS); + _hThreadedAudio = GetDlgItem(_hwnd, IDC_THREADEDAUDIO); + _hUseVoicePack = GetDlgItem(_hwnd, IDC_VOICEPACK); + _hAdvanced = GetDlgItem(_hwnd, IDC_ADVANCED); + _hGameResolutionText = GetDlgItem(_hwnd, IDC_RESOLUTION); + _hGfxModeText = GetDlgItem(_hwnd, IDC_GFXMODETEXT); + _hMouseLock = GetDlgItem(_hwnd, IDC_MOUSE_AUTOLOCK); + _hMouseSpeed = GetDlgItem(_hwnd, IDC_MOUSESPEED); + _hMouseSpeedText = GetDlgItem(_hwnd, IDC_MOUSESPEED_TEXT); + + _desktopSize = get_desktop_size(); + _maxWindowSize = _desktopSize; + AGSPlatformDriver::GetDriver()->ValidateWindowSize(_maxWindowSize.Width, _maxWindowSize.Height, false); + _minGameSize = Size(320, 200); + _maxGameScale = 1; + _minGameScale = 1; + + _winCfg.Load(_cfgIn); + + // Custom save dir controls + String custom_save_dir = _winCfg.UserSaveDir; + bool has_save_dir = !custom_save_dir.IsEmpty(); + if (!has_save_dir) + custom_save_dir = _winCfg.DataDirectory; + SetCheck(_hCustomSaveDirCheck, has_save_dir); + char full_save_dir[MAX_PATH] = {0}; + MakeFullLongPath(custom_save_dir, full_save_dir, MAX_PATH); + SetText(_hCustomSaveDir, full_save_dir); + EnableWindow(_hCustomSaveDir, has_save_dir ? TRUE : FALSE); + EnableWindow(_hCustomSaveDirBtn, has_save_dir ? TRUE : FALSE); + + // Resolution controls + if (_winCfg.GameResolution.IsNull() && + (_winCfg.GameResType == kGameResolution_Undefined || _winCfg.GameResType == kGameResolution_Custom) || + _winCfg.GameColourDepth == 0) + MessageBox(_hwnd, "Essential information about the game is missing in the configuration file. Setup program may be unable to deduce graphic modes properly.", "Initialization error", MB_OK | MB_ICONWARNING); + + if (_winCfg.GameResolution.IsNull()) + _winCfg.GameResolution = ResolutionTypeToSize(_winCfg.GameResType, _winCfg.LetterboxByDesign); + + SetText(_hwnd, _winCfg.Title); + SetText(win_get_window(), _winCfg.Title); + SetText(_hGameResolutionText, String::FromFormat("Native game resolution: %d x %d x %d", + _winCfg.GameResolution.Width, _winCfg.GameResolution.Height, _winCfg.GameColourDepth)); + + SetText(_hVersionText, _winCfg.VersionString); + + InitGfxModes(); + + for (DriverDescMap::const_iterator it = _drvDescMap.begin(); it != _drvDescMap.end(); ++it) + AddString(_hGfxDriverList, it->second->UserName, (DWORD_PTR)it->second->Id.GetCStr()); + SetCurSelToItemDataStr(_hGfxDriverList, _winCfg.GfxDriverId.GetCStr(), 0); + OnGfxDriverUpdate(); + + SetCheck(_hWindowed, _winCfg.Windowed); + OnWindowedUpdate(); + + FillScalingList(_hFsScalingList, _winCfg.FsGameFrame, false); + FillScalingList(_hWinScalingList, _winCfg.WinGameFrame, true); + + SetCheck(_hVSync, _winCfg.VSync); + + SetCheck(_hRenderAtScreenRes, _winCfg.RenderAtScreenRes); + + AddString(_hDigiDriverList, "No Digital Sound", DIGI_NONE); + AddString(_hDigiDriverList, "Default device (auto)", MIDI_AUTODETECT); + AddString(_hDigiDriverList, "Default DirectSound Device", DIGI_DIRECTAMX(0)); + AddString(_hDigiDriverList, "Default WaveOut Device", DIGI_WAVOUTID(0)); + AddString(_hDigiDriverList, "DirectSound (Hardware mixer)", DIGI_DIRECTX(0)); + SetCurSelToItemData(_hDigiDriverList, _winCfg.DigiID); + + AddString(_hMidiDriverList, "No MIDI music", MIDI_NONE); + AddString(_hMidiDriverList, "Default device (auto)", MIDI_AUTODETECT); + AddString(_hMidiDriverList, "Win32 MIDI Mapper", MIDI_WIN32MAPPER); + SetCurSelToItemData(_hMidiDriverList, _winCfg.MidiID); + + FillLanguageList(); + + SetCheck(_hMouseLock, _winCfg.MouseAutoLock); + + SetSliderRange(_hMouseSpeed, MouseSpeedMin, MouseSpeedMax); + int slider_pos = (int)(_winCfg.MouseSpeed * 10.f + .5f); + SetSliderPos(_hMouseSpeed, slider_pos); + UpdateMouseSpeedText(); + + AddString(_hSpriteCacheList, "16 MB", 16); + AddString(_hSpriteCacheList, "32 MB", 32); + AddString(_hSpriteCacheList, "64 MB", 64); + AddString(_hSpriteCacheList, "128 MB (default)", 128); + AddString(_hSpriteCacheList, "256 MB", 256); + AddString(_hSpriteCacheList, "384 MB", 384); + AddString(_hSpriteCacheList, "512 MB", 512); + SetCurSelToItemData(_hSpriteCacheList, _winCfg.SpriteCacheSize / 1024, NULL, 3); + + SetCheck(_hRefresh85Hz, _winCfg.RefreshRate == 85); + SetCheck(_hAntialiasSprites, _winCfg.AntialiasSprites); + SetCheck(_hThreadedAudio, _winCfg.ThreadedAudio); + SetCheck(_hUseVoicePack, _winCfg.UseVoicePack); + if (!File::TestReadFile("speech.vox")) + EnableWindow(_hUseVoicePack, FALSE); + + if (INIreadint(_cfgIn, "disabled", "threaded_audio", 0) != 0) + EnableWindow(_hThreadedAudio, FALSE); + if (INIreadint(_cfgIn, "disabled", "speechvox", 0) != 0) + EnableWindow(_hUseVoicePack, FALSE); + if (INIreadint(_cfgIn, "disabled", "filters", 0) != 0) + EnableWindow(_hGfxFilterList, FALSE); + if (INIreadint(_cfgIn, "disabled", "render_at_screenres", 0) != 0) + EnableWindow(_hRenderAtScreenRes, FALSE); + + RECT win_rect, gfx_rect, adv_rect, border; + GetWindowRect(_hwnd, &win_rect); + GetWindowRect(GetDlgItem(_hwnd, IDC_GFXOPTIONS), &gfx_rect); + _winSize.Width = win_rect.right - win_rect.left; + _winSize.Height = win_rect.bottom - win_rect.top; + GetWindowRect(_hAdvanced, &adv_rect); + border.left = border.top = border.right = border.bottom = 9; + MapDialogRect(_hwnd, &border); + _baseSize.Width = (adv_rect.right + (gfx_rect.left - win_rect.left)) - win_rect.left; + _baseSize.Height = adv_rect.bottom - win_rect.top + border.bottom; + + MoveWindow(_hwnd, max(0, win_rect.left + (_winSize.Width - _baseSize.Width) / 2), + max(0, win_rect.top + (_winSize.Height - _baseSize.Height) / 2), + _baseSize.Width, _baseSize.Height, TRUE); + SetFocus(GetDlgItem(_hwnd, IDOK)); + return FALSE; // notify WinAPI that we set focus ourselves +} + +INT_PTR WinSetupDialog::OnCommand(WORD id) +{ + switch (id) + { + case IDC_ADVANCED: ShowAdvancedOptions(); break; + case IDC_WINDOWED: OnWindowedUpdate(); break; + case IDC_CUSTOMSAVEDIRBTN: OnCustomSaveDirBtn(); break; + case IDC_CUSTOMSAVEDIRCHECK: OnCustomSaveDirCheck(); break; + case IDOK: + case IDOKRUN: + SaveSetup(); + // fall-through intended + case IDCANCEL: + EndDialog(_hwnd, id); + return TRUE; + default: + return FALSE; + } + return TRUE; +} + +INT_PTR WinSetupDialog::OnListSelection(WORD id) +{ + switch (id) + { + case IDC_GFXDRIVER: OnGfxDriverUpdate(); break; + case IDC_GFXFILTER: OnGfxFilterUpdate(); break; + case IDC_GFXMODE: OnGfxModeUpdate(); break; + case IDC_FSSCALING: OnScalingUpdate(_hFsScalingList, _winCfg.FsGameFrame, false); break; + case IDC_WINDOWSCALING: OnScalingUpdate(_hWinScalingList, _winCfg.WinGameFrame, true); break; + default: + return FALSE; + } + return TRUE; +} + +void WinSetupDialog::OnCustomSaveDirBtn() +{ + String save_dir = GetText(_hCustomSaveDir); + if (BrowseForFolder(save_dir)) + { + SetText(_hCustomSaveDir, save_dir); + } +} + +void WinSetupDialog::OnCustomSaveDirCheck() +{ + bool custom_save_dir = GetCheck(_hCustomSaveDirCheck); + EnableWindow(_hCustomSaveDir, custom_save_dir ? TRUE : FALSE); + EnableWindow(_hCustomSaveDirBtn, custom_save_dir ? TRUE : FALSE); +} + +void WinSetupDialog::OnGfxDriverUpdate() +{ + _winCfg.GfxDriverId = (LPCTSTR)GetCurItemData(_hGfxDriverList); + + DriverDescMap::const_iterator it = _drvDescMap.find(_winCfg.GfxDriverId); + if (it != _drvDescMap.end()) + _drvDesc = it->second; + else + _drvDesc.reset(); + + FillGfxModeList(); + FillGfxFilterList(); +} + +void WinSetupDialog::OnGfxFilterUpdate() +{ + _winCfg.GfxFilterId = (LPCTSTR)GetCurItemData(_hGfxFilterList); + + _gfxFilterInfo = GfxFilterInfo(); + for (size_t i = 0; i < _drvDesc->FilterList.size(); ++i) + { + if (_drvDesc->FilterList[i].Id.CompareNoCase(_winCfg.GfxFilterId) == 0) + { + _gfxFilterInfo = _drvDesc->FilterList[i]; + break; + } + } +} + +void WinSetupDialog::OnGfxModeUpdate() +{ + DWORD_PTR sel = GetCurItemData(_hGfxModeList); + if (sel == kGfxMode_Desktop) + _winCfg.ScreenSize = _desktopSize; + else if (sel == kGfxMode_GameRes) + _winCfg.ScreenSize = _winCfg.GameResolution; + else + { + const DisplayMode &mode = _drvDesc->GfxModeList.Modes[sel]; + _winCfg.ScreenSize = Size(mode.Width, mode.Height); + } +} + +void WinSetupDialog::OnScalingUpdate(HWND hlist, GameFrameSetup &frame_setup, bool windowed) +{ + int scale = GetCurItemData(hlist); + if (scale >= 0 && scale < kNumFrameScaleDef) + { + frame_setup.ScaleDef = (FrameScaleDefinition)scale; + frame_setup.ScaleFactor = 0; + } + else + { + frame_setup.ScaleDef = kFrame_IntScale; + frame_setup.ScaleFactor = scale >= 0 ? scale - kNumFrameScaleDef : scale; + } + + if (windowed) + SetGfxModeText(); +} + +void WinSetupDialog::OnWindowedUpdate() +{ + _winCfg.Windowed = GetCheck(_hWindowed); + + if (_winCfg.Windowed) + { + ShowWindow(_hGfxModeList, SW_HIDE); + ShowWindow(_hGfxModeText, SW_SHOW); + SetGfxModeText(); + } + else + { + ShowWindow(_hGfxModeList, SW_SHOW); + ShowWindow(_hGfxModeText, SW_HIDE); + } + + SelectNearestGfxMode(_winCfg.ScreenSize); +} + +void WinSetupDialog::ShowAdvancedOptions() +{ + // Reveal the advanced bit of the window + ShowWindow(_hAdvanced, SW_HIDE); + + RECT win_rect; + GetWindowRect(_hwnd, &win_rect); + MoveWindow(_hwnd, max(0, win_rect.left + (_baseSize.Width - _winSize.Width) / 2), + max(0, win_rect.top + (_baseSize.Height - _winSize.Height) / 2), + _winSize.Width, _winSize.Height, TRUE); + + int offset = _winSize.Height - _baseSize.Height; + RECT rc; + int ctrl_ids[] = { IDC_VERSION, IDOK, IDOKRUN, IDCANCEL, 0 }; + for (int i = 0; ctrl_ids[i]; ++i) + { + HWND hctrl = GetDlgItem(_hwnd, ctrl_ids[i]); + GetWindowRect(hctrl, &rc); + ScreenToClient(_hwnd, (POINT*)&rc); + ScreenToClient(_hwnd, (POINT*)&rc.right); + MoveWindow(hctrl, rc.left, rc.top + offset, rc.right - rc.left, rc.bottom - rc.top, TRUE); + } +} + +INT_PTR CALLBACK WinSetupDialog::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + _ASSERT(_dlg != NULL && _dlg->_hwnd == NULL); + return _dlg->OnInitDialog(hwndDlg); + case WM_COMMAND: + _ASSERT(_dlg != NULL && _dlg->_hwnd != NULL); + if (HIWORD(wParam) == CBN_SELCHANGE) + return _dlg->OnListSelection(LOWORD(wParam)); + return _dlg->OnCommand(LOWORD(wParam)); + case WM_HSCROLL: + _ASSERT(_dlg != NULL && _dlg->_hwnd != NULL); + _dlg->UpdateMouseSpeedText(); + return TRUE; + default: + return FALSE; + } +} + +int WinSetupDialog::GfxModes::GetModeCount() const +{ + return Modes.size(); +} + +bool WinSetupDialog::GfxModes::GetMode(int index, DisplayMode &mode) const +{ + if (index >= 0 && (size_t)index < Modes.size()) + { + mode = Modes[index]; + return true; + } + return false; +} + +void WinSetupDialog::AddScalingString(HWND hlist, int scaling_factor) +{ + String s; + if (scaling_factor >= 0) + s = String::FromFormat("x%d", scaling_factor); + else + s = String::FromFormat("1/%d", -scaling_factor); + AddString(hlist, s, (DWORD_PTR)(scaling_factor >= 0 ? scaling_factor + kNumFrameScaleDef : scaling_factor)); +} + +void WinSetupDialog::FillGfxFilterList() +{ + ResetContent(_hGfxFilterList); + + if (!_drvDesc) + { + _gfxFilterInfo = GfxFilterInfo(); + return; + } + + for (size_t i = 0; i < _drvDesc->FilterList.size(); ++i) + { + const GfxFilterInfo &info = _drvDesc->FilterList[i]; + if (INIreadint(_cfgIn, "disabled", info.Id, 0) == 0) + AddString(_hGfxFilterList, info.Name, (DWORD_PTR)info.Id.GetCStr()); + } + + SetCurSelToItemDataStr(_hGfxFilterList, _winCfg.GfxFilterId, 0); + OnGfxFilterUpdate(); +} + +void WinSetupDialog::FillGfxModeList() +{ + ResetContent(_hGfxModeList); + + if (!_drvDesc) + { + OnGfxModeUpdate(); + return; + } + + const VDispModes &modes = _drvDesc->GfxModeList.Modes; + bool has_desktop_mode = false; + bool has_native_mode = false; + String buf; + for (VDispModes::const_iterator mode = modes.begin(); mode != modes.end(); ++mode) + { + if (mode->Width == _desktopSize.Width && mode->Height == _desktopSize.Height) + { + has_desktop_mode = true; + continue; + } + else if (mode->Width == _winCfg.GameResolution.Width && mode->Height == _winCfg.GameResolution.Height) + { + has_native_mode = true; + continue; + } + buf.Format("%d x %d", mode->Width, mode->Height); + AddString(_hGfxModeList, buf, (DWORD_PTR)(mode - modes.begin())); + } + + int spec_mode_idx = 0; + if (has_desktop_mode) + InsertString(_hGfxModeList, String::FromFormat("Desktop resolution (%d x %d)", + _desktopSize.Width, _desktopSize.Height), spec_mode_idx++, (DWORD_PTR)kGfxMode_Desktop); + if (has_native_mode) + InsertString(_hGfxModeList, String::FromFormat("Native game resolution (%d x %d)", + _winCfg.GameResolution.Width, _winCfg.GameResolution.Height), spec_mode_idx++, (DWORD_PTR)kGfxMode_GameRes); + + SelectNearestGfxMode(_winCfg.ScreenSize); +} + +void WinSetupDialog::FillLanguageList() +{ + ResetContent(_hLanguageList); + AddString(_hLanguageList, _winCfg.DefaultLanguageName.GetCStr()); + SetCurSel(_hLanguageList, 0); + + String path_mask = String::FromFormat("%s\\*.tra", _winCfg.DataDirectory.GetCStr()); + WIN32_FIND_DATAA file_data; + HANDLE find_handle = FindFirstFile(path_mask, &file_data); + if (find_handle != INVALID_HANDLE_VALUE) + { + bool found_sel = false; + do + { + LPTSTR ext = PathFindExtension(file_data.cFileName); + if (ext && StrCmpI(ext, ".tra") == 0) + { + file_data.cFileName[0] = toupper(file_data.cFileName[0]); + *ext = 0; + int index = AddString(_hLanguageList, file_data.cFileName); + if (!found_sel && _winCfg.Language.CompareNoCase(file_data.cFileName) == 0) + { + SetCurSel(_hLanguageList, index); + found_sel = true; + } + } + } + while (FindNextFileA(find_handle, &file_data) != FALSE); + FindClose(find_handle); + } +} + +void WinSetupDialog::FillScalingList(HWND hlist, GameFrameSetup &frame_setup, bool windowed) +{ + ResetContent(hlist); + + const int min_scale = min(_winCfg.GameResolution.Width / _minGameSize.Width, _winCfg.GameResolution.Height / _minGameSize.Height); + const Size max_size = windowed ? _maxWindowSize : _winCfg.ScreenSize; + const int max_scale = _winCfg.GameResolution.IsNull() ? 1 : + min(max_size.Width / _winCfg.GameResolution.Width, max_size.Height / _winCfg.GameResolution.Height); + _maxGameScale = max(1, max_scale); + _minGameScale = -max(1, min_scale); + + if (windowed) + AddString(hlist, "None (original game size)", 1 + kNumFrameScaleDef); + + AddString(hlist, "Max round multiplier", kFrame_MaxRound); + AddString(hlist, "Fill whole screen", kFrame_MaxStretch); + AddString(hlist, "Stretch, preserving aspect ratio", kFrame_MaxProportional); + + if (windowed && !_winCfg.GameResolution.IsNull()) + { + // Add integer multipliers + for (int scale = 2; scale <= _maxGameScale; ++scale) + AddScalingString(hlist, scale); + } + + SetCurSelToItemData(hlist, + frame_setup.ScaleDef == kFrame_IntScale ? frame_setup.ScaleFactor + kNumFrameScaleDef : frame_setup.ScaleDef, NULL, 0); + + EnableWindow(hlist, SendMessage(hlist, CB_GETCOUNT, 0, 0) > 1 ? TRUE : FALSE); + OnScalingUpdate(hlist, frame_setup, windowed); +} + +void WinSetupDialog::InitGfxModes() +{ + InitDriverDescFromFactory("D3D9"); + InitDriverDescFromFactory("OGL"); + InitDriverDescFromFactory("Software"); + + if (_drvDescMap.size() == 0) + MessageBox(_hwnd, "Unable to detect any supported graphic drivers!", "Initialization error", MB_OK | MB_ICONERROR); +} + +// "Less" predicate that compares two display modes only by their screen metrics +bool SizeLess(const DisplayMode &first, const DisplayMode &second) +{ + return Size(first.Width, first.Height) < Size(second.Width, second.Height); +} + +void WinSetupDialog::InitDriverDescFromFactory(const String &id) +{ + IGfxDriverFactory *gfx_factory = GetGfxDriverFactory(id); + if (!gfx_factory) + return; + IGraphicsDriver *gfx_driver = gfx_factory->GetDriver(); + if (!gfx_driver) + { + gfx_factory->Shutdown(); + return; + } + + PDriverDesc drv_desc(new DriverDesc()); + drv_desc->Id = gfx_driver->GetDriverID(); + drv_desc->UserName = gfx_driver->GetDriverName(); + drv_desc->UseColorDepth = + gfx_driver->GetDisplayDepthForNativeDepth(_winCfg.GameColourDepth ? _winCfg.GameColourDepth : 32); + + IGfxModeList *gfxm_list = gfx_driver->GetSupportedModeList(drv_desc->UseColorDepth); + VDispModes &modes = drv_desc->GfxModeList.Modes; + if (gfxm_list) + { + std::set unique_sizes; // trying to hide modes which only have different refresh rates + for (int i = 0; i < gfxm_list->GetModeCount(); ++i) + { + DisplayMode mode; + gfxm_list->GetMode(i, mode); + if (mode.ColorDepth != drv_desc->UseColorDepth || unique_sizes.count(Size(mode.Width, mode.Height)) != 0) + continue; + unique_sizes.insert(Size(mode.Width, mode.Height)); + modes.push_back(mode); + } + std::sort(modes.begin(), modes.end(), SizeLess); + delete gfxm_list; + } + if (modes.size() == 0) + { + // Add two default modes in hope that engine will be able to handle them (or fallbacks to something else) + modes.push_back(DisplayMode(GraphicResolution(_desktopSize.Width, _desktopSize.Height, drv_desc->UseColorDepth))); + modes.push_back(DisplayMode(GraphicResolution(_winCfg.GameResolution.Width, _winCfg.GameResolution.Height, drv_desc->UseColorDepth))); + } + + drv_desc->FilterList.resize(gfx_factory->GetFilterCount()); + for (size_t i = 0; i < drv_desc->FilterList.size(); ++i) + { + drv_desc->FilterList[i] = *gfx_factory->GetFilterInfo(i); + } + + gfx_factory->Shutdown(); + _drvDescMap[drv_desc->Id] = drv_desc; +} + +void WinSetupDialog::SaveSetup() +{ + const bool custom_save_dir = GetCheck(_hCustomSaveDirCheck); + if (custom_save_dir) + { + // Compare user path with the game data directory. If user chose + // path pointing inside game's directory, then store relative + // path instead; thus the path will keep pointing at game's + // directory if user moves game elsewhere. + String save_dir; + save_dir = GetText(_hCustomSaveDir); + char full_data_dir[MAX_PATH] = {0}; + char full_save_dir[MAX_PATH] = {0}; + MakeFullLongPath(_winCfg.DataDirectory, full_data_dir, MAX_PATH); + MakeFullLongPath(save_dir, full_save_dir, MAX_PATH); + char rel_save_dir[MAX_PATH] = {0}; + if (PathRelativePathTo(rel_save_dir, full_data_dir, FILE_ATTRIBUTE_DIRECTORY, full_save_dir, FILE_ATTRIBUTE_DIRECTORY) && + strstr(rel_save_dir, "..") == NULL) + { + _winCfg.UserSaveDir = rel_save_dir; + } + else + { + _winCfg.UserSaveDir = save_dir; + } + } + else + { + _winCfg.UserSaveDir = ""; + } + + _winCfg.DigiID = GetCurItemData(_hDigiDriverList); + _winCfg.MidiID = GetCurItemData(_hMidiDriverList); + + if (GetCurSel(_hLanguageList) == 0) + _winCfg.Language.Empty(); + else + _winCfg.Language = GetText(_hLanguageList); + _winCfg.SpriteCacheSize = GetCurItemData(_hSpriteCacheList) * 1024; + _winCfg.ThreadedAudio = GetCheck(_hThreadedAudio); + _winCfg.UseVoicePack = GetCheck(_hUseVoicePack); + _winCfg.VSync = GetCheck(_hVSync); + _winCfg.RenderAtScreenRes = GetCheck(_hRenderAtScreenRes); + _winCfg.AntialiasSprites = GetCheck(_hAntialiasSprites); + _winCfg.RefreshRate = GetCheck(_hRefresh85Hz) ? 85 : 0; + _winCfg.GfxFilterId = (LPCTSTR)GetCurItemData(_hGfxFilterList); + + _winCfg.MouseAutoLock = GetCheck(_hMouseLock); + int slider_pos = GetSliderPos(_hMouseSpeed); + _winCfg.MouseSpeed = (float)slider_pos / 10.f; + + _winCfg.Save(_cfgOut); +} + +void WinSetupDialog::SelectNearestGfxMode(const Size screen_size) +{ + if (!_drvDesc) + { + OnGfxModeUpdate(); + return; + } + + // First check two special modes + if (screen_size == _desktopSize) + { + SetCurSelToItemData(_hGfxModeList, kGfxMode_Desktop); + } + else if (screen_size == _winCfg.GameResolution) + { + SetCurSelToItemData(_hGfxModeList, kGfxMode_GameRes); + } + else + { + // Look up for the nearest supported mode + int index = -1; + DisplayMode dm; + if (find_nearest_supported_mode(_drvDesc->GfxModeList, screen_size, _drvDesc->UseColorDepth, + NULL, NULL, dm, &index)) + { + SetCurSelToItemData(_hGfxModeList, index, NULL, kGfxMode_Desktop); + } + else + SetCurSelToItemData(_hGfxModeList, kGfxMode_Desktop); + } + OnGfxModeUpdate(); +} + +void WinSetupDialog::SetGfxModeText() +{ + Size sz; + const GameFrameSetup &frame_setup = _winCfg.WinGameFrame; + if (frame_setup.ScaleDef == kFrame_MaxStretch) + { + sz = _maxWindowSize; + } + else if (frame_setup.ScaleDef == kFrame_MaxProportional) + { + sz = ProportionalStretch(_maxWindowSize, _winCfg.GameResolution); + } + else + { + int scale = 0; + if (frame_setup.ScaleDef == kFrame_MaxRound) + scale = _maxGameScale; + else + scale = frame_setup.ScaleFactor; + + if (scale >= 0) + { + sz.Width = _winCfg.GameResolution.Width * scale; + sz.Height = _winCfg.GameResolution.Height * scale; + } + else + { + sz.Width = _winCfg.GameResolution.Width / (-scale); + sz.Height = _winCfg.GameResolution.Height / (-scale); + } + } + String text = String::FromFormat("%d x %d", sz.Width, sz.Height); + SetText(_hGfxModeText, text); +} + +void WinSetupDialog::UpdateMouseSpeedText() +{ + int slider_pos = GetSliderPos(_hMouseSpeed); + float mouse_speed = (float)slider_pos / 10.f; + String text = mouse_speed == 1.f ? "Mouse speed: x 1.0 (Default)" : String::FromFormat("Mouse speed: x %0.1f", mouse_speed); + SetText(_hMouseSpeedText, text); +} + +//============================================================================= +// +// Windows setup entry point. +// +//============================================================================= +void SetWinIcon() +{ + SetClassLong(win_get_window(),GCL_HICON, + (LONG) LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON))); +} + +SetupReturnValue WinSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, + const String &game_data_dir, const String &version_str) +{ + return WinSetupDialog::ShowModal(cfg_in, cfg_out, game_data_dir, version_str); +} + +} // namespace Engine +} // namespace AGS + +#endif // AGS_PLATFORM_OS_WINDOWS \ No newline at end of file diff --git a/engines/ags/engine/platform/windows/setup/winsetup.h b/engines/ags/engine/platform/windows/setup/winsetup.h new file mode 100644 index 000000000000..e030cf33b92a --- /dev/null +++ b/engines/ags/engine/platform/windows/setup/winsetup.h @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Built-in setup dialog for Windows version +// +//============================================================================= + +#ifndef __AGS_EE_SETUP__WINSETUP_H +#define __AGS_EE_SETUP__WINSETUP_H + +#include "util/ini_util.h" + +namespace AGS +{ +namespace Engine +{ + +using namespace Common; + +void SetWinIcon(); +SetupReturnValue WinSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, + const String &game_data_dir, const String &version_str); + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_SETUP__WINSETUP_H diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp new file mode 100644 index 000000000000..27d56c67fe09 --- /dev/null +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -0,0 +1,97 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS +#include +#include +#include +#include "ac/common.h" +#include "ac/common_defines.h" +#include "debug/debugger.h" +#include "debug/out.h" +#include "main/main.h" +#include "util/ini_util.h" + +#if !AGS_PLATFORM_DEBUG +#define USE_CUSTOM_EXCEPTION_HANDLER +#endif + +using namespace AGS::Common; + +extern int our_eip; +extern int eip_guinum; +extern int eip_guiobj; +extern int proper_exit; + +char tempmsg[100]; +char *printfworkingspace; + +#ifdef USE_CUSTOM_EXCEPTION_HANDLER +void CreateMiniDump(EXCEPTION_POINTERS *pep); + +extern int CustomExceptionHandler(LPEXCEPTION_POINTERS exinfo); +extern EXCEPTION_RECORD excinfo; +extern int miniDumpResultCode; + +static void DisplayException() +{ + String script_callstack = get_cur_script(5); + sprintf(printfworkingspace, "An exception 0x%X occurred in ACWIN.EXE at EIP = 0x%08X; program pointer is %+d, ACI version %s, gtags (%d,%d)\n\n" + "AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and post the details on the AGS Technical Forum.\n\n%s\n\n" + "Most versions of Windows allow you to press Ctrl+C now to copy this entire message to the clipboard for easy reporting.\n\n%s (code %d)", + excinfo.ExceptionCode, (intptr_t)excinfo.ExceptionAddress, our_eip, EngineVersion.LongString.GetCStr(), eip_guinum, eip_guiobj, script_callstack.GetCStr(), + (miniDumpResultCode == 0) ? "An error file CrashInfo.dmp has been created. You may be asked to upload this file when reporting this problem on the AGS Forums." : + "Unable to create an error dump file.", miniDumpResultCode); + MessageBoxA(win_get_window(), printfworkingspace, "Illegal exception", MB_ICONSTOP | MB_OK); +} + +int initialize_engine_with_exception_handling( + int (initialize_engine)(const AGS::Common::ConfigTree &startup_opts), + const ConfigTree &startup_opts) +{ + __try + { + Debug::Printf(kDbgMsg_Info, "Installing exception handler"); + return initialize_engine(startup_opts); + } + __except (CustomExceptionHandler(GetExceptionInformation())) + { + DisplayException(); + proper_exit = 1; + } + return EXIT_CRASH; +} +#endif // USE_CUSTOM_EXCEPTION_HANDLER + + +int malloc_fail_handler(size_t amountwanted) +{ +#ifdef USE_CUSTOM_EXCEPTION_HANDLER + CreateMiniDump(NULL); +#endif + free(printfworkingspace); + sprintf(tempmsg, "Out of memory: failed to allocate %ld bytes (at PP=%d)", amountwanted, our_eip); + quit(tempmsg); + return 0; +} + +void setup_malloc_handling() +{ + _set_new_handler(malloc_fail_handler); + _set_new_mode(1); + printfworkingspace = (char*)malloc(7000); +} + +#endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/windows/win_ex_handling.h b/engines/ags/engine/platform/windows/win_ex_handling.h new file mode 100644 index 000000000000..30f458945d26 --- /dev/null +++ b/engines/ags/engine/platform/windows/win_ex_handling.h @@ -0,0 +1,24 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_EE_PLATFORM__WIN_EXCEPTION_HANDLING_H +#define __AGS_EE_PLATFORM__WIN_EXCEPTION_HANDLING_H + +#include "util/ini_util.h" + +void setup_malloc_handling(); +int initialize_engine_with_exception_handling( + int (initialize_engine)(const AGS::Common::ConfigTree &startup_opts), + const AGS::Common::ConfigTree &startup_opts); + +#endif // __AGS_EE_PLATFORM__WIN_EXCEPTION_HANDLING_H diff --git a/engines/ags/engine/platform/windows/winapi_exclusive.h b/engines/ags/engine/platform/windows/winapi_exclusive.h new file mode 100644 index 000000000000..e82c4175f9d8 --- /dev/null +++ b/engines/ags/engine/platform/windows/winapi_exclusive.h @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// An excerpt from , declaring most commonly used WinAPI types +// and attributes. Meant to avoid including itself when it may +// cause naming conflicts with its dreaded heap of macros. +// +//============================================================================= +#ifndef __AGS_EE_PLATFORM__WINAPI_EXCLUSIVE_H +#define __AGS_EE_PLATFORM__WINAPI_EXCLUSIVE_H + +#ifndef _WINDOWS_ // do not include if windows.h was included first +#define _WINDOWS_ // there can be only one + +typedef unsigned long DWORD; +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef char CHAR; +#define CONST const +typedef CONST CHAR *LPCSTR, *PCSTR; + +#define DECLSPEC_IMPORT __declspec(dllimport) +#define WINBASEAPI DECLSPEC_IMPORT +#define WINAPI __stdcall + +typedef void *PVOID; +typedef PVOID HANDLE; +typedef HANDLE HINSTANCE; +typedef HANDLE HMODULE; +typedef HANDLE HWND; + +#define FAR +#define NEAR + +typedef int (FAR WINAPI *FARPROC)(); + +#endif // _WINDOWS_ + +#endif // __AGS_EE_PLATFORM__WINAPI_EXCLUSIVE_H diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp new file mode 100644 index 000000000000..240f0d14fcff --- /dev/null +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -0,0 +1,1109 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "core/platform.h" +#if AGS_PLATFORM_OS_WINDOWS +#include "platform/windows/winapi_exclusive.h" +#endif +#include "util/wgt2allg.h" +#include "ac/common.h" +#include "ac/view.h" +#include "ac/charactercache.h" +#include "ac/display.h" +#include "ac/draw.h" +#include "ac/dynamicsprite.h" +#include "ac/gamesetup.h" +#include "ac/gamesetupstruct.h" +#include "ac/global_audio.h" +#include "ac/global_plugin.h" +#include "ac/global_walkablearea.h" +#include "ac/keycode.h" +#include "ac/mouse.h" +#include "ac/movelist.h" +#include "ac/objectcache.h" +#include "ac/parser.h" +#include "ac/path_helper.h" +#include "ac/roomstatus.h" +#include "ac/string.h" +#include "ac/dynobj/cc_dynamicobject_addr_and_manager.h" +#include "font/fonts.h" +#include "util/string_compat.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" +#include "device/mousew32.h" +#include "gui/guidefines.h" +#include "main/game_run.h" +#include "main/engine.h" +#include "plugin/agsplugin.h" +#include "plugin/plugin_engine.h" +#include "plugin/plugin_builtin.h" +#include "plugin/pluginobjectreader.h" +#include "script/script.h" +#include "script/script_runtime.h" +#include "ac/spritecache.h" +#include "util/stream.h" +#include "gfx/bitmap.h" +#include "gfx/graphicsdriver.h" +#include "gfx/gfxfilter.h" +#include "script/runtimescriptvalue.h" +#include "debug/out.h" +#include "ac/dynobj/scriptstring.h" +#include "main/graphics_mode.h" +#include "gfx/gfx_util.h" +#include "util/memory.h" +#include "util/filestream.h" +#include "media/audio/audio_system.h" + +using namespace AGS::Common; +using namespace AGS::Common::Memory; +using namespace AGS::Engine; + + +#if defined(BUILTIN_PLUGINS) +#include "../Plugins/AGSflashlight/agsflashlight.h" +#include "../Plugins/agsblend/agsblend.h" +#include "../Plugins/ags_snowrain/ags_snowrain.h" +#include "../Plugins/ags_parallax/ags_parallax.h" +#include "../Plugins/agspalrender/agspalrender.h" +#if AGS_PLATFORM_OS_IOS +#include "../Plugins/agstouch/agstouch.h" +#endif // AGS_PLATFORM_OS_IOS +#endif // BUILTIN_PLUGINS + + +extern IGraphicsDriver *gfxDriver; +extern int mousex, mousey; +extern int displayed_room; +extern RoomStruct thisroom; +extern GameSetupStruct game; +extern RoomStatus*croom; +extern SpriteCache spriteset; +extern ViewStruct*views; +extern int game_paused; +extern GameSetup usetup; +extern int inside_script; +extern ccInstance *gameinst, *roominst; +extern CharacterCache *charcache; +extern ObjectCache objcache[MAX_ROOM_OBJECTS]; +extern MoveList *mls; +extern color palette[256]; +extern PluginObjectReader pluginReaders[MAX_PLUGIN_OBJECT_READERS]; +extern int numPluginReaders; +extern RuntimeScriptValue GlobalReturnValue; +extern ScriptString myScriptStringImpl; + +// **************** PLUGIN IMPLEMENTATION **************** + + +#include "util/library.h" + + + + +struct EnginePlugin { + char filename[PLUGIN_FILENAME_MAX+1]; + AGS::Engine::Library library; + bool available; + char *savedata; + int savedatasize; + int wantHook; + int invalidatedRegion; + void (*engineStartup) (IAGSEngine *) = nullptr; + void (*engineShutdown) () = nullptr; + int (*onEvent) (int, int) = nullptr; + void (*initGfxHook) (const char *driverName, void *data) = nullptr; + int (*debugHook) (const char * whichscript, int lineNumber, int reserved) = nullptr; + IAGSEngine eiface; + bool builtin; + + EnginePlugin() { + filename[0] = 0; + wantHook = 0; + invalidatedRegion = 0; + savedata = nullptr; + savedatasize = 0; + builtin = false; + available = false; + eiface.version = 0; + eiface.pluginId = 0; + } +}; +#define MAXPLUGINS 20 +EnginePlugin plugins[MAXPLUGINS]; +int numPlugins = 0; +int pluginsWantingDebugHooks = 0; + +std::vector _registered_builtin_plugins; + +void IAGSEngine::AbortGame (const char *reason) { + quit ((char*)reason); +} +const char* IAGSEngine::GetEngineVersion () { + return get_engine_version(); +} +void IAGSEngine::RegisterScriptFunction (const char*name, void*addy) { + ccAddExternalPluginFunction (name, addy); +} +const char* IAGSEngine::GetGraphicsDriverID() +{ + if (gfxDriver == nullptr) + return nullptr; + + return gfxDriver->GetDriverID(); +} + +BITMAP *IAGSEngine::GetScreen () +{ + // TODO: we could actually return stage buffer here, will that make a difference? + if (!gfxDriver->UsesMemoryBackBuffer()) + quit("!This plugin requires software graphics driver."); + + Bitmap *buffer = gfxDriver->GetMemoryBackBuffer(); + return buffer ? (BITMAP*)buffer->GetAllegroBitmap() : nullptr; +} + +BITMAP *IAGSEngine::GetVirtualScreen () +{ + Bitmap *stage = gfxDriver->GetStageBackBuffer(); + return stage ? (BITMAP*)stage->GetAllegroBitmap() : nullptr; +} + +void IAGSEngine::RequestEventHook (int32 event) { + if (event >= AGSE_TOOHIGH) + quit("!IAGSEngine::RequestEventHook: invalid event requested"); + + if (plugins[this->pluginId].onEvent == nullptr) + quit("!IAGSEngine::RequestEventHook: no callback AGS_EngineOnEvent function exported from plugin"); + + if ((event & AGSE_SCRIPTDEBUG) && + ((plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG) == 0)) { + pluginsWantingDebugHooks++; + ccSetDebugHook(scriptDebugHook); + } + + if (event & AGSE_AUDIODECODE) { + quit("Plugin requested AUDIODECODE, which is no longer supported"); + } + + + plugins[this->pluginId].wantHook |= event; +} + +void IAGSEngine::UnrequestEventHook(int32 event) { + if (event >= AGSE_TOOHIGH) + quit("!IAGSEngine::UnrequestEventHook: invalid event requested"); + + if ((event & AGSE_SCRIPTDEBUG) && + (plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG)) { + pluginsWantingDebugHooks--; + if (pluginsWantingDebugHooks < 1) + ccSetDebugHook(nullptr); + } + + plugins[this->pluginId].wantHook &= ~event; +} + +int IAGSEngine::GetSavedData (char *buffer, int32 bufsize) { + int savedatasize = plugins[this->pluginId].savedatasize; + + if (bufsize < savedatasize) + quit("!IAGSEngine::GetSavedData: buffer too small"); + + if (savedatasize > 0) + memcpy (buffer, plugins[this->pluginId].savedata, savedatasize); + + return savedatasize; +} + +void IAGSEngine::DrawText (int32 x, int32 y, int32 font, int32 color, char *text) +{ + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + color_t text_color = ds->GetCompatibleColor(color); + draw_and_invalidate_text(ds, x, y, font, text_color, text); +} + +void IAGSEngine::GetScreenDimensions (int32 *width, int32 *height, int32 *coldepth) { + if (width != nullptr) + width[0] = play.GetMainViewport().GetWidth(); + if (height != nullptr) + height[0] = play.GetMainViewport().GetHeight(); + if (coldepth != nullptr) + coldepth[0] = scsystem.coldepth; +} + +unsigned char ** IAGSEngine::GetRawBitmapSurface (BITMAP *bmp) +{ + if (!is_linear_bitmap(bmp)) + quit("!IAGSEngine::GetRawBitmapSurface: invalid bitmap for access to surface"); + acquire_bitmap(bmp); + + Bitmap *stage = gfxDriver->GetStageBackBuffer(); + if (stage && bmp == stage->GetAllegroBitmap()) + plugins[this->pluginId].invalidatedRegion = 0; + + return bmp->line; +} + +void IAGSEngine::ReleaseBitmapSurface (BITMAP *bmp) +{ + release_bitmap (bmp); + + Bitmap *stage = gfxDriver->GetStageBackBuffer(); + if (stage && bmp == stage->GetAllegroBitmap()) + { + // plugin does not manaually invalidate stuff, so + // we must invalidate the whole screen to be safe + if (!plugins[this->pluginId].invalidatedRegion) + invalidate_screen(); + } +} + +void IAGSEngine::GetMousePosition (int32 *x, int32 *y) { + if (x) x[0] = mousex; + if (y) y[0] = mousey; +} +int IAGSEngine::GetCurrentRoom () { + return displayed_room; +} +int IAGSEngine::GetNumBackgrounds () { + return thisroom.BgFrameCount; +} +int IAGSEngine::GetCurrentBackground () { + return play.bg_frame; +} +BITMAP *IAGSEngine::GetBackgroundScene (int32 index) { + return (BITMAP*)thisroom.BgFrames[index].Graphic->GetAllegroBitmap(); +} +void IAGSEngine::GetBitmapDimensions (BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth) { + if (bmp == nullptr) + return; + + if (width != nullptr) + width[0] = bmp->w; + if (height != nullptr) + height[0] = bmp->h; + if (coldepth != nullptr) + coldepth[0] = bitmap_color_depth(bmp); +} + +// On save/restore, the Engine will provide the plugin with a handle. Because we only ever save to one file at a time, +// we can reuse the same handle. + +static long pl_file_handle = -1; +static Stream *pl_file_stream = nullptr; + +void pl_set_file_handle(long data, Stream *stream) { + pl_file_handle = data; + pl_file_stream = stream; +} + +void pl_clear_file_handle() { + pl_file_handle = -1; + pl_file_stream = nullptr; +} + +int IAGSEngine::FRead (void *buffer, int32 len, int32 handle) { + if (handle != pl_file_handle) { + quitprintf("IAGSEngine::FRead: invalid file handle: %d", handle); + } + if (!pl_file_stream) { + quit("IAGSEngine::FRead: file stream not set"); + } + return pl_file_stream->Read(buffer, len); +} + +int IAGSEngine::FWrite (void *buffer, int32 len, int32 handle) { + if (handle != pl_file_handle) { + quitprintf("IAGSEngine::FWrite: invalid file handle: %d", handle); + } + if (!pl_file_stream) { + quit("IAGSEngine::FWrite: file stream not set"); + } + return pl_file_stream->Write(buffer, len); +} + +void IAGSEngine::DrawTextWrapped (int32 xx, int32 yy, int32 wid, int32 font, int32 color, const char*text) +{ + // TODO: use generic function from the engine instead of having copy&pasted code here + int linespacing = getfontspacing_outlined(font); + + if (break_up_text_into_lines(text, Lines, wid, font) == 0) + return; + + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + color_t text_color = ds->GetCompatibleColor(color); + data_to_game_coords((int*)&xx, (int*)&yy); // stupid! quick tweak + for (size_t i = 0; i < Lines.Count(); i++) + draw_and_invalidate_text(ds, xx, yy + linespacing*i, font, text_color, Lines[i]); +} + +Bitmap glVirtualScreenWrap; +void IAGSEngine::SetVirtualScreen (BITMAP *bmp) +{ + if (!gfxDriver->UsesMemoryBackBuffer()) + { + debug_script_warn("SetVirtualScreen: this plugin requires software graphics driver to work correctly."); + // we let it continue since gfxDriver is supposed to ignore this request without throwing an exception + } + + if (bmp) + { + glVirtualScreenWrap.WrapAllegroBitmap(bmp, true); + gfxDriver->SetMemoryBackBuffer(&glVirtualScreenWrap); + } + else + { + glVirtualScreenWrap.Destroy(); + gfxDriver->SetMemoryBackBuffer(nullptr); + } +} + +int IAGSEngine::LookupParserWord (const char *word) { + return find_word_in_dictionary ((char*)word); +} + +void IAGSEngine::BlitBitmap (int32 x, int32 y, BITMAP *bmp, int32 masked) +{ + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + wputblock_raw(ds, x, y, bmp, masked); + invalidate_rect(x, y, x + bmp->w, y + bmp->h, false); +} + +void IAGSEngine::BlitSpriteTranslucent(int32 x, int32 y, BITMAP *bmp, int32 trans) +{ + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + Bitmap wrap(bmp, true); + if (gfxDriver->UsesMemoryBackBuffer()) + GfxUtil::DrawSpriteWithTransparency(ds, &wrap, x, y, trans); + else + GfxUtil::DrawSpriteBlend(ds, Point(x,y), &wrap, kBlendMode_Alpha, true, false, trans); +} + +void IAGSEngine::BlitSpriteRotated(int32 x, int32 y, BITMAP *bmp, int32 angle) +{ + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + // FIXME: call corresponding Graphics Blit + rotate_sprite(ds->GetAllegroBitmap(), bmp, x, y, itofix(angle)); +} + +extern void domouse(int); + +void IAGSEngine::PollSystem () { + + domouse(DOMOUSE_NOCURSOR); + update_polled_stuff_if_runtime(); + int mbut, mwheelz; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !play.IsIgnoringInput()) + pl_run_plugin_hooks (AGSE_MOUSECLICK, mbut); + int kp; + if (run_service_key_controls(kp) && !play.IsIgnoringInput()) { + pl_run_plugin_hooks (AGSE_KEYPRESS, kp); + } + +} +AGSCharacter* IAGSEngine::GetCharacter (int32 charnum) { + if (charnum >= game.numcharacters) + quit("!AGSEngine::GetCharacter: invalid character request"); + + return (AGSCharacter*)&game.chars[charnum]; +} +AGSGameOptions* IAGSEngine::GetGameOptions () { + return (AGSGameOptions*)&play; +} +AGSColor* IAGSEngine::GetPalette () { + return (AGSColor*)&palette[0]; +} +void IAGSEngine::SetPalette (int32 start, int32 finish, AGSColor *cpl) { + set_palette_range((color*)cpl, start, finish, 0); +} +int IAGSEngine::GetNumCharacters () { + return game.numcharacters; +} +int IAGSEngine::GetPlayerCharacter () { + return game.playercharacter; +} +void IAGSEngine::RoomToViewport (int32 *x, int32 *y) { + Point scrp = play.RoomToScreen(x ? data_to_game_coord(*x) : 0, y ? data_to_game_coord(*y) : 0); + if (x) + *x = scrp.X; + if (y) + *y = scrp.Y; +} +void IAGSEngine::ViewportToRoom (int32 *x, int32 *y) { + // NOTE: This is an old function that did not account for custom/multiple viewports + // and does not expect to fail, therefore we always use primary viewport here. + // (Not sure if it's good though) + VpPoint vpt = play.ScreenToRoom(x ? game_to_data_coord(*x) : 0, y ? game_to_data_coord(*y) : 0); + if (x) + *x = vpt.first.X; + if (y) + *y = vpt.first.Y; +} +int IAGSEngine::GetNumObjects () { + return croom->numobj; +} +AGSObject *IAGSEngine::GetObject (int32 num) { + if (num >= croom->numobj) + quit("!IAGSEngine::GetObject: invalid object"); + + return (AGSObject*)&croom->obj[num]; +} +BITMAP *IAGSEngine::CreateBlankBitmap (int32 width, int32 height, int32 coldep) { + // [IKM] We should not create Bitmap object here, because + // a) we are returning raw allegro bitmap and therefore loosing control over it + // b) plugin won't use Bitmap anyway + BITMAP *tempb = create_bitmap_ex(coldep, width, height); + clear_to_color(tempb, bitmap_mask_color(tempb)); + return tempb; +} +void IAGSEngine::FreeBitmap (BITMAP *tofree) { + if (tofree) + destroy_bitmap (tofree); +} +BITMAP *IAGSEngine::GetSpriteGraphic (int32 num) { + return (BITMAP*)spriteset[num]->GetAllegroBitmap(); +} +BITMAP *IAGSEngine::GetRoomMask (int32 index) { + if (index == MASK_WALKABLE) + return (BITMAP*)thisroom.WalkAreaMask->GetAllegroBitmap(); + else if (index == MASK_WALKBEHIND) + return (BITMAP*)thisroom.WalkBehindMask->GetAllegroBitmap(); + else if (index == MASK_HOTSPOT) + return (BITMAP*)thisroom.HotspotMask->GetAllegroBitmap(); + else if (index == MASK_REGIONS) + return (BITMAP*)thisroom.RegionMask->GetAllegroBitmap(); + else + quit("!IAGSEngine::GetRoomMask: invalid mask requested"); + return nullptr; +} +AGSViewFrame *IAGSEngine::GetViewFrame (int32 view, int32 loop, int32 frame) { + view--; + if ((view < 0) || (view >= game.numviews)) + quit("!IAGSEngine::GetViewFrame: invalid view"); + if ((loop < 0) || (loop >= views[view].numLoops)) + quit("!IAGSEngine::GetViewFrame: invalid loop"); + if ((frame < 0) || (frame >= views[view].loops[loop].numFrames)) + return nullptr; + + return (AGSViewFrame*)&views[view].loops[loop].frames[frame]; +} + +int IAGSEngine::GetRawPixelColor(int32 color) +{ + // Convert the standardized colour to the local gfx mode color + // NOTE: it is unclear whether this has to be game colour depth or display color depth. + // there was no difference in the original engine, but there is now. + int result; + __my_setcolor(&result, color, game.GetColorDepth()); + return result; +} + +int IAGSEngine::GetWalkbehindBaseline (int32 wa) { + if ((wa < 1) || (wa >= MAX_WALK_BEHINDS)) + quit("!IAGSEngine::GetWalkBehindBase: invalid walk-behind area specified"); + return croom->walkbehind_base[wa]; +} +void* IAGSEngine::GetScriptFunctionAddress (const char *funcName) { + return ccGetSymbolAddressForPlugin ((char*)funcName); +} +int IAGSEngine::GetBitmapTransparentColor(BITMAP *bmp) { + return bitmap_mask_color (bmp); +} +// get the character scaling level at a particular point +int IAGSEngine::GetAreaScaling (int32 x, int32 y) { + return GetScalingAt(x,y); +} +int IAGSEngine::IsGamePaused () { + return game_paused; +} +int IAGSEngine::GetSpriteWidth (int32 slot) { + return game.SpriteInfos[slot].Width; +} +int IAGSEngine::GetSpriteHeight (int32 slot) { + return game.SpriteInfos[slot].Height; +} +void IAGSEngine::GetTextExtent (int32 font, const char *text, int32 *width, int32 *height) { + if ((font < 0) || (font >= game.numfonts)) { + if (width != nullptr) width[0] = 0; + if (height != nullptr) height[0] = 0; + return; + } + + if (width != nullptr) + width[0] = wgettextwidth_compensate (text, font); + if (height != nullptr) + height[0] = wgettextheight ((char*)text, font); +} +void IAGSEngine::PrintDebugConsole (const char *text) { + debug_script_log("[PLUGIN] %s", text); + platform->WriteStdOut("[PLUGIN] %s", text); +} +int IAGSEngine::IsChannelPlaying (int32 channel) { + return ::IsChannelPlaying (channel); +} +void IAGSEngine::PlaySoundChannel (int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename) { + stop_and_destroy_channel (channel); + // Not sure if it's right to let it play on *any* channel, but this is plugin so let it go... + // we must correctly stop background voice speech if it takes over speech chan + if (channel == SCHAN_SPEECH && play.IsNonBlockingVoiceSpeech()) + stop_voice_nonblocking(); + + SOUNDCLIP *newcha = nullptr; + + if (((soundType == PSND_MP3STREAM) || (soundType == PSND_OGGSTREAM)) + && (loop != 0)) + quit("IAGSEngine::PlaySoundChannel: streamed samples cannot loop"); + + // TODO: find out how engine was supposed to decide on where to load the sound from + AssetPath asset_name("", filename); + + if (soundType == PSND_WAVE) + newcha = my_load_wave (asset_name, volume, loop); + else if (soundType == PSND_MP3STREAM) + newcha = my_load_mp3 (asset_name, volume); + else if (soundType == PSND_OGGSTREAM) + newcha = my_load_ogg (asset_name, volume); + else if (soundType == PSND_MP3STATIC) + newcha = my_load_static_mp3 (asset_name, volume, (loop != 0)); + else if (soundType == PSND_OGGSTATIC) + newcha = my_load_static_ogg (asset_name, volume, (loop != 0)); + else if (soundType == PSND_MIDI) { + if (midi_pos >= 0) + quit("!IAGSEngine::PlaySoundChannel: MIDI already in use"); + newcha = my_load_midi (asset_name, loop); + newcha->set_volume (volume); + } +#ifndef PSP_NO_MOD_PLAYBACK + else if (soundType == PSND_MOD) { + newcha = my_load_mod (asset_name, loop); + newcha->set_volume (volume); + } +#endif + else + quit("!IAGSEngine::PlaySoundChannel: unknown sound type"); + + set_clip_to_channel(channel, newcha); +} +// Engine interface 12 and above are below +void IAGSEngine::MarkRegionDirty(int32 left, int32 top, int32 right, int32 bottom) { + invalidate_rect(left, top, right, bottom, false); + plugins[this->pluginId].invalidatedRegion++; +} +AGSMouseCursor * IAGSEngine::GetMouseCursor(int32 cursor) { + if ((cursor < 0) || (cursor >= game.numcursors)) + return nullptr; + + return (AGSMouseCursor*)&game.mcurs[cursor]; +} +void IAGSEngine::GetRawColorComponents(int32 coldepth, int32 color, int32 *red, int32 *green, int32 *blue, int32 *alpha) { + if (red) + *red = getr_depth(coldepth, color); + if (green) + *green = getg_depth(coldepth, color); + if (blue) + *blue = getb_depth(coldepth, color); + if (alpha) + *alpha = geta_depth(coldepth, color); +} +int IAGSEngine::MakeRawColorPixel(int32 coldepth, int32 red, int32 green, int32 blue, int32 alpha) { + return makeacol_depth(coldepth, red, green, blue, alpha); +} +int IAGSEngine::GetFontType(int32 fontNum) { + if ((fontNum < 0) || (fontNum >= game.numfonts)) + return FNT_INVALID; + + if (font_supports_extended_characters(fontNum)) + return FNT_TTF; + + return FNT_SCI; +} +int IAGSEngine::CreateDynamicSprite(int32 coldepth, int32 width, int32 height) { + + // TODO: why is this implemented right here, should not an existing + // script handling implementation be called instead? + + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return 0; + + if ((width < 1) || (height < 1)) + quit("!IAGSEngine::CreateDynamicSprite: invalid width/height requested by plugin"); + + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, coldepth); + if (newPic == nullptr) + return 0; + + // add it into the sprite set + add_dynamic_sprite(gotSlot, newPic); + return gotSlot; +} +void IAGSEngine::DeleteDynamicSprite(int32 slot) { + free_dynamic_sprite(slot); +} +int IAGSEngine::IsSpriteAlphaBlended(int32 slot) { + if (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) + return 1; + return 0; +} + +// disable AGS's sound engine +void IAGSEngine::DisableSound() { + shutdown_sound(); + usetup.digicard = DIGI_NONE; + usetup.midicard = MIDI_NONE; + reserve_voices(0, 0); + install_sound(DIGI_NONE, MIDI_NONE, nullptr); +} +int IAGSEngine::CanRunScriptFunctionNow() { + if (inside_script) + return 0; + return 1; +} +int IAGSEngine::CallGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1, long arg2, long arg3) { + if (inside_script) + return -300; + + ccInstance *toRun = GetScriptInstanceByType(globalScript ? kScInstGame : kScInstRoom); + + RuntimeScriptValue params[3]; + params[0].SetPluginArgument(arg1); + params[1].SetPluginArgument(arg2); + params[2].SetPluginArgument(arg3); + int toret = RunScriptFunctionIfExists(toRun, (char*)name, numArgs, params); + return toret; +} + +void IAGSEngine::NotifySpriteUpdated(int32 slot) { + int ff; + // wipe the character cache when we change rooms + for (ff = 0; ff < game.numcharacters; ff++) { + if ((charcache[ff].inUse) && (charcache[ff].sppic == slot)) { + delete charcache[ff].image; + charcache[ff].image = nullptr; + charcache[ff].inUse = 0; + } + } + + // clear the object cache + for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) { + if ((objcache[ff].image != nullptr) && (objcache[ff].sppic == slot)) { + delete objcache[ff].image; + objcache[ff].image = nullptr; + } + } +} + +void IAGSEngine::SetSpriteAlphaBlended(int32 slot, int32 isAlphaBlended) { + + game.SpriteInfos[slot].Flags &= ~SPF_ALPHACHANNEL; + + if (isAlphaBlended) + game.SpriteInfos[slot].Flags |= SPF_ALPHACHANNEL; +} + +void IAGSEngine::QueueGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1, long arg2) { + if (!inside_script) { + this->CallGameScriptFunction(name, globalScript, numArgs, arg1, arg2, 0); + return; + } + + if (numArgs < 0 || numArgs > 2) + quit("IAGSEngine::QueueGameScriptFunction: invalid number of arguments"); + + curscript->run_another(name, globalScript ? kScInstGame : kScInstRoom, numArgs, + RuntimeScriptValue().SetPluginArgument(arg1), RuntimeScriptValue().SetPluginArgument(arg2)); +} + +int IAGSEngine::RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback) { + GlobalReturnValue.SetPluginObject((void*)object, (ICCDynamicObject*)callback); + return ccRegisterManagedObject(object, (ICCDynamicObject*)callback, true); +} + +void IAGSEngine::AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader) { + if (numPluginReaders >= MAX_PLUGIN_OBJECT_READERS) + quit("Plugin error: IAGSEngine::AddObjectReader: Too many object readers added"); + + if ((typeName == nullptr) || (typeName[0] == 0)) + quit("Plugin error: IAGSEngine::AddObjectReader: invalid name for type"); + + for (int ii = 0; ii < numPluginReaders; ii++) { + if (strcmp(pluginReaders[ii].type, typeName) == 0) + quitprintf("Plugin error: IAGSEngine::AddObjectReader: type '%s' has been registered already", typeName); + } + + pluginReaders[numPluginReaders].reader = reader; + pluginReaders[numPluginReaders].type = typeName; + numPluginReaders++; +} + +void IAGSEngine::RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback) { + GlobalReturnValue.SetPluginObject((void*)object, (ICCDynamicObject*)callback); + ccRegisterUnserializedObject(key, object, (ICCDynamicObject*)callback, true); +} + +int IAGSEngine::GetManagedObjectKeyByAddress(const char *address) { + return ccGetObjectHandleFromAddress(address); +} + +void* IAGSEngine::GetManagedObjectAddressByKey(int key) { + void *object; + ICCDynamicObject *manager; + ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(key, object, manager); + if (obj_type == kScValPluginObject) + { + GlobalReturnValue.SetPluginObject(object, manager); + } + else + { + GlobalReturnValue.SetDynamicObject(object, manager); + } + return object; +} + +const char* IAGSEngine::CreateScriptString(const char *fromText) { + const char *string = CreateNewScriptString(fromText); + // Should be still standard dynamic object, because not managed by plugin + GlobalReturnValue.SetDynamicObject((void*)string, &myScriptStringImpl); + return string; +} + +int IAGSEngine::IncrementManagedObjectRefCount(const char *address) { + return ccAddObjectReference(GetManagedObjectKeyByAddress(address)); +} + +int IAGSEngine::DecrementManagedObjectRefCount(const char *address) { + return ccReleaseObjectReference(GetManagedObjectKeyByAddress(address)); +} + +void IAGSEngine::SetMousePosition(int32 x, int32 y) { + Mouse::SetPosition(Point(x, y)); + RefreshMouse(); +} + +void IAGSEngine::SimulateMouseClick(int32 button) { + PluginSimulateMouseClick(button); +} + +int IAGSEngine::GetMovementPathWaypointCount(int32 pathId) { + return mls[pathId % TURNING_AROUND].numstage; +} + +int IAGSEngine::GetMovementPathLastWaypoint(int32 pathId) { + return mls[pathId % TURNING_AROUND].onstage; +} + +void IAGSEngine::GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y) { + *x = (mls[pathId % TURNING_AROUND].pos[waypoint] >> 16) & 0x0000ffff; + *y = (mls[pathId % TURNING_AROUND].pos[waypoint] & 0x0000ffff); +} + +void IAGSEngine::GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed) { + *xSpeed = mls[pathId % TURNING_AROUND].xpermove[waypoint]; + *ySpeed = mls[pathId % TURNING_AROUND].ypermove[waypoint]; +} + +int IAGSEngine::IsRunningUnderDebugger() +{ + return (editor_debugging_enabled != 0) ? 1 : 0; +} + +void IAGSEngine::GetPathToFileInCompiledFolder(const char*fileName, char *buffer) +{ + get_install_dir_path(buffer, fileName); +} + +void IAGSEngine::BreakIntoDebugger() +{ + break_on_next_script_step = 1; +} + +IAGSFontRenderer* IAGSEngine::ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer) +{ + return font_replace_renderer(fontNumber, newRenderer); +} + + +// *********** General plugin implementation ********** + +void pl_stop_plugins() { + int a; + ccSetDebugHook(nullptr); + + for (a = 0; a < numPlugins; a++) { + if (plugins[a].available) { + if (plugins[a].engineShutdown != nullptr) + plugins[a].engineShutdown(); + plugins[a].wantHook = 0; + if (plugins[a].savedata) { + free(plugins[a].savedata); + plugins[a].savedata = nullptr; + } + if (!plugins[a].builtin) { + plugins[a].library.Unload(); + } + } + } + numPlugins = 0; +} + +void pl_startup_plugins() { + int i; + for (i = 0; i < numPlugins; i++) { + if (plugins[i].available) + plugins[i].engineStartup (&plugins[i].eiface); + } +} + +int pl_run_plugin_hooks (int event, int data) { + int i, retval = 0; + for (i = 0; i < numPlugins; i++) { + if (plugins[i].wantHook & event) { + retval = plugins[i].onEvent (event, data); + if (retval) + return retval; + } + } + return 0; +} + +int pl_run_plugin_debug_hooks (const char *scriptfile, int linenum) { + int i, retval = 0; + for (i = 0; i < numPlugins; i++) { + if (plugins[i].wantHook & AGSE_SCRIPTDEBUG) { + retval = plugins[i].debugHook(scriptfile, linenum, 0); + if (retval) + return retval; + } + } + return 0; +} + +void pl_run_plugin_init_gfx_hooks (const char *driverName, void *data) { + for (int i = 0; i < numPlugins; i++) + { + if (plugins[i].initGfxHook != nullptr) + { + plugins[i].initGfxHook(driverName, data); + } + } +} + +int pl_register_builtin_plugin(InbuiltPluginDetails const &details) { + _registered_builtin_plugins.push_back(details); + return 0; +} + +bool pl_use_builtin_plugin(EnginePlugin* apl) +{ +#if defined(BUILTIN_PLUGINS) + if (ags_stricmp(apl->filename, "agsflashlight") == 0) + { + apl->engineStartup = agsflashlight::AGS_EngineStartup; + apl->engineShutdown = agsflashlight::AGS_EngineShutdown; + apl->onEvent = agsflashlight::AGS_EngineOnEvent; + apl->debugHook = agsflashlight::AGS_EngineDebugHook; + apl->initGfxHook = agsflashlight::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } + else if (ags_stricmp(apl->filename, "agsblend") == 0) + { + apl->engineStartup = agsblend::AGS_EngineStartup; + apl->engineShutdown = agsblend::AGS_EngineShutdown; + apl->onEvent = agsblend::AGS_EngineOnEvent; + apl->debugHook = agsblend::AGS_EngineDebugHook; + apl->initGfxHook = agsblend::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } + else if (ags_stricmp(apl->filename, "ags_snowrain") == 0) + { + apl->engineStartup = ags_snowrain::AGS_EngineStartup; + apl->engineShutdown = ags_snowrain::AGS_EngineShutdown; + apl->onEvent = ags_snowrain::AGS_EngineOnEvent; + apl->debugHook = ags_snowrain::AGS_EngineDebugHook; + apl->initGfxHook = ags_snowrain::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } + else if (ags_stricmp(apl->filename, "ags_parallax") == 0) + { + apl->engineStartup = ags_parallax::AGS_EngineStartup; + apl->engineShutdown = ags_parallax::AGS_EngineShutdown; + apl->onEvent = ags_parallax::AGS_EngineOnEvent; + apl->debugHook = ags_parallax::AGS_EngineDebugHook; + apl->initGfxHook = ags_parallax::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } + else if (ags_stricmp(apl->filename, "agspalrender") == 0) + { + apl->engineStartup = agspalrender::AGS_EngineStartup; + apl->engineShutdown = agspalrender::AGS_EngineShutdown; + apl->onEvent = agspalrender::AGS_EngineOnEvent; + apl->debugHook = agspalrender::AGS_EngineDebugHook; + apl->initGfxHook = agspalrender::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } +#if AGS_PLATFORM_OS_IOS + else if (ags_stricmp(apl->filename, "agstouch") == 0) + { + apl->engineStartup = agstouch::AGS_EngineStartup; + apl->engineShutdown = agstouch::AGS_EngineShutdown; + apl->onEvent = agstouch::AGS_EngineOnEvent; + apl->debugHook = agstouch::AGS_EngineDebugHook; + apl->initGfxHook = agstouch::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } +#endif // IOS_VERSION +#endif // BUILTIN_PLUGINS + + for(std::vector::iterator it = _registered_builtin_plugins.begin(); it != _registered_builtin_plugins.end(); ++it) { + if (ags_stricmp(apl->filename, it->filename) == 0) { + apl->engineStartup = it->engineStartup; + apl->engineShutdown = it->engineShutdown; + apl->onEvent = it->onEvent; + apl->debugHook = it->debugHook; + apl->initGfxHook = it->initGfxHook; + apl->available = true; + apl->builtin = true; + return true; + } + } + return false; +} + +Engine::GameInitError pl_register_plugins(const std::vector &infos) +{ + numPlugins = 0; + for (size_t inf_index = 0; inf_index < infos.size(); ++inf_index) + { + const Common::PluginInfo &info = infos[inf_index]; + String name = info.Name; + if (name.GetLast() == '!') + continue; // editor-only plugin, ignore it + if (numPlugins == MAXPLUGINS) + return kGameInitErr_TooManyPlugins; + // AGS Editor currently saves plugin names in game data with + // ".dll" extension appended; we need to take care of that + const String name_ext = ".dll"; + if (name.GetLength() <= name_ext.GetLength() || name.GetLength() > PLUGIN_FILENAME_MAX + name_ext.GetLength() || + name.CompareRightNoCase(name_ext, name_ext.GetLength())) { + return kGameInitErr_PluginNameInvalid; + } + // remove ".dll" from plugin's name + name.ClipRight(name_ext.GetLength()); + + EnginePlugin *apl = &plugins[numPlugins++]; + // Copy plugin info + snprintf(apl->filename, sizeof(apl->filename), "%s", name.GetCStr()); + if (info.DataLen) + { + apl->savedata = (char*)malloc(info.DataLen); + memcpy(apl->savedata, info.Data.get(), info.DataLen); + } + apl->savedatasize = info.DataLen; + + // Compatibility with the old SnowRain module + if (ags_stricmp(apl->filename, "ags_SnowRain20") == 0) { + strcpy(apl->filename, "ags_snowrain"); + } + + String expect_filename = apl->library.GetFilenameForLib(apl->filename); + if (apl->library.Load(apl->filename)) + { + AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' loaded as '%s', resolving imports...", apl->filename, expect_filename.GetCStr()); + + if (apl->library.GetFunctionAddress("AGS_PluginV2") == nullptr) { + quitprintf("Plugin '%s' is an old incompatible version.", apl->filename); + } + apl->engineStartup = (void(*)(IAGSEngine*))apl->library.GetFunctionAddress("AGS_EngineStartup"); + apl->engineShutdown = (void(*)())apl->library.GetFunctionAddress("AGS_EngineShutdown"); + + if (apl->engineStartup == nullptr) { + quitprintf("Plugin '%s' is not a valid AGS plugin (no engine startup entry point)", apl->filename); + } + apl->onEvent = (int(*)(int,int))apl->library.GetFunctionAddress("AGS_EngineOnEvent"); + apl->debugHook = (int(*)(const char*,int,int))apl->library.GetFunctionAddress("AGS_EngineDebugHook"); + apl->initGfxHook = (void(*)(const char*, void*))apl->library.GetFunctionAddress("AGS_EngineInitGfx"); + } + else + { + AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' could not be loaded (expected '%s'), trying built-in plugins...", + apl->filename, expect_filename.GetCStr()); + if (pl_use_builtin_plugin(apl)) + { + AGS::Common::Debug::Printf(kDbgMsg_Info, "Build-in plugin '%s' found and being used.", apl->filename); + } + else + { + // Plugin loading has failed at this point, try using built-in plugin function stubs + if (RegisterPluginStubs((const char*)apl->filename)) + AGS::Common::Debug::Printf(kDbgMsg_Info, "Placeholder functions for the plugin '%s' found.", apl->filename); + else + AGS::Common::Debug::Printf(kDbgMsg_Info, "No placeholder functions for the plugin '%s' found. The game might fail to load!", apl->filename); + continue; + } + } + + apl->eiface.pluginId = numPlugins - 1; + apl->eiface.version = 24; + apl->wantHook = 0; + apl->available = true; + } + return kGameInitErr_NoError; +} + +bool pl_is_plugin_loaded(const char *pl_name) +{ + if (!pl_name) + return false; + + for (int i = 0; i < numPlugins; ++i) + { + if (ags_stricmp(pl_name, plugins[i].filename) == 0) + return plugins[i].available; + } + return false; +} + +bool pl_any_want_hook(int event) +{ + for (int i = 0; i < numPlugins; ++i) + { + if(plugins[i].wantHook & event) + return true; + } + return false; +} \ No newline at end of file diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/engine/plugin/agsplugin.h new file mode 100644 index 000000000000..6a09ee93a92c --- /dev/null +++ b/engines/ags/engine/plugin/agsplugin.h @@ -0,0 +1,570 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS Plugin interface header file +// +// #define THIS_IS_THE_PLUGIN beforehand if including from the plugin +// +//============================================================================= + +#ifndef _AGS_PLUGIN_H +#define _AGS_PLUGIN_H + +// If the plugin isn't using DDraw, don't require the headers +#ifndef DIRECTDRAW_VERSION +typedef void *LPDIRECTDRAW2; +typedef void *LPDIRECTDRAWSURFACE2; +#endif + +#ifndef DIRECTSOUND_VERSION +typedef void *LPDIRECTSOUND; +#endif + +#ifndef DIRECTINPUT_VERSION +typedef void *LPDIRECTINPUTDEVICE; +#endif + +// If the user isn't using Allegro or WinGDI, define the BITMAP into something +#if !defined(ALLEGRO_H) && !defined(_WINGDI_) && !defined(BITMAP_DEFINED) +typedef char BITMAP; +#endif + +// If not using windows.h, define HWND +#if !defined(_WINDOWS_) +typedef int HWND; +#endif + +// This file is distributed as part of the Plugin API docs, so +// ensure that WINDOWS_VERSION is defined (if applicable) +#if defined(_WIN32) + #undef WINDOWS_VERSION + #define WINDOWS_VERSION +#endif + +// DOS engine doesn't know about stdcall / neither does Linux version +#if !defined (_WIN32) + #define __stdcall +#endif + +#ifndef int32 +#define int32 int +#endif + +#define AGSIFUNC(type) virtual type __stdcall + +#define MASK_WALKABLE 1 +#define MASK_WALKBEHIND 2 +#define MASK_HOTSPOT 3 +// MASK_REGIONS is interface version 11 and above only +#define MASK_REGIONS 4 + +// **** WARNING: DO NOT ALTER THESE CLASSES IN ANY WAY! +// **** CHANGING THE ORDER OF THE FUNCTIONS OR ADDING ANY VARIABLES +// **** WILL CRASH THE SYSTEM. + +struct AGSColor { + unsigned char r,g,b; + unsigned char padding; +}; + +struct AGSGameOptions { + int32 score; // player's current score + int32 usedmode; // set by ProcessClick to last cursor mode used + int32 disabled_user_interface; // >0 while in cutscene/etc + int32 gscript_timer; // obsolete + int32 debug_mode; // whether we're in debug mode + int32 globalvars[50]; // obsolete + int32 messagetime; // time left for auto-remove messages + int32 usedinv; // inventory item last used + int32 inv_top,inv_numdisp,inv_numorder,inv_numinline; + int32 text_speed; // how quickly text is removed + int32 sierra_inv_color; // background used to paint defualt inv window + int32 talkanim_speed; // animation speed of talking anims + int32 inv_item_wid,inv_item_hit; // set by SetInvDimensions + int32 speech_text_shadow; // colour of outline fonts (default black) + int32 swap_portrait_side; // sierra-style speech swap sides + int32 speech_textwindow_gui; // textwindow used for sierra-style speech + int32 follow_change_room_timer; // delay before moving following characters into new room + int32 totalscore; // maximum possible score + int32 skip_display; // how the user can skip normal Display windows + int32 no_multiloop_repeat; // for backwards compatibility + int32 roomscript_finished; // on_call finished in room + int32 used_inv_on; // inv item they clicked on + int32 no_textbg_when_voice; // no textwindow bgrnd when voice speech is used + int32 max_dialogoption_width; // max width of dialog options text window + int32 no_hicolor_fadein; // fade out but instant in for hi-color + int32 bgspeech_game_speed; // is background speech relative to game speed + int32 bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used + int32 unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay + int32 mp3_loop_before_end; // loop this time before end of track (ms) + int32 speech_music_drop; // how much to drop music volume by when speech is played + int32 in_cutscene; // we are between a StartCutscene and EndCutscene + int32 fast_forward; // player has elected to skip cutscene + int32 room_width; // width of current room + int32 room_height; // height of current room +}; + +// AGSCharacter.flags +#define CHF_NOSCALING 1 +#define CHF_FIXVIEW 2 // between SetCharView and ReleaseCharView +#define CHF_NOINTERACT 4 +#define CHF_NODIAGONAL 8 +#define CHF_ALWAYSIDLE 0x10 +#define CHF_NOLIGHTING 0x20 +#define CHF_NOTURNING 0x40 +#define CHF_NOWALKBEHINDS 0x80 + +struct AGSCharacter { + int32 defview; + int32 talkview; + int32 view; + int32 room, prevroom; + int32 x, y, wait; + int32 flags; + short following; + short followinfo; + int32 idleview; // the loop will be randomly picked + short idletime, idleleft; // num seconds idle before playing anim + short transparency; // if character is transparent + short baseline; + int32 activeinv; + int32 talkcolor; + int32 thinkview; + int32 reserved[2]; + short walkspeed_y, pic_yoffs; + int32 z; + int32 reserved2[5]; + short loop, frame; + short walking, animating; + short walkspeed, animspeed; + short inv[301]; + short actx, acty; + char name[40]; + char scrname[20]; + char on; +}; + +// AGSObject.flags +#define OBJF_NOINTERACT 1 // not clickable +#define OBJF_NOWALKBEHINDS 2 // ignore walk-behinds + +struct AGSObject { + int32 x,y; + int32 transparent; // current transparency setting + int32 reserved[4]; + short num; // sprite slot number + short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline + short view,loop,frame; // only used to track animation - 'num' holds the current sprite + short wait,moving; + char cycling; // is it currently animating? + char overall_speed; + char on; + char flags; +}; + +// AGSViewFrame.flags +#define FRAF_MIRRORED 1 // flipped left to right + +struct AGSViewFrame { + int32 pic; // sprite slot number + short xoffs, yoffs; + short speed; + int32 flags; + int32 sound; // play sound when this frame comes round + int32 reserved_for_future[2]; +}; + +// AGSMouseCursor.flags +#define MCF_ANIMATEMOVE 1 +#define MCF_DISABLED 2 +#define MCF_STANDARD 4 +#define MCF_ONLYANIMOVERHOTSPOT 8 + +struct AGSMouseCursor { + int32 pic; // sprite slot number + short hotx, hoty; // x,y hotspot co-ordinates + short view; // view (for animating cursors) or -1 + char name[10]; // name of cursor mode + char flags; // MCF_flags above +}; + +// The editor-to-plugin interface +class IAGSEditor { +public: + int32 version; + int32 pluginId; // used internally, do not touch this + +public: + // get the HWND of the main editor frame + AGSIFUNC(HWND) GetEditorHandle (); + // get the HWND of the current active window + AGSIFUNC(HWND) GetWindowHandle (); + // add some script to the default header + AGSIFUNC(void) RegisterScriptHeader (const char *header); + // de-register a script header (pass same pointer as when added) + AGSIFUNC(void) UnregisterScriptHeader (const char *header); + +}; + + +// Below are interface 3 and later +#define AGSE_KEYPRESS 1 +#define AGSE_MOUSECLICK 2 +#define AGSE_POSTSCREENDRAW 4 +// Below are interface 4 and later +#define AGSE_PRESCREENDRAW 8 +// Below are interface 5 and later +#define AGSE_SAVEGAME 0x10 +#define AGSE_RESTOREGAME 0x20 +// Below are interface 6 and later +#define AGSE_PREGUIDRAW 0x40 +#define AGSE_LEAVEROOM 0x80 +#define AGSE_ENTERROOM 0x100 +#define AGSE_TRANSITIONIN 0x200 +#define AGSE_TRANSITIONOUT 0x400 +// Below are interface 12 and later +#define AGSE_FINALSCREENDRAW 0x800 +#define AGSE_TRANSLATETEXT 0x1000 +// Below are interface 13 and later +#define AGSE_SCRIPTDEBUG 0x2000 +#define AGSE_AUDIODECODE 0x4000 // obsolete, no longer supported +// Below are interface 18 and later +#define AGSE_SPRITELOAD 0x8000 +// Below are interface 21 and later +#define AGSE_PRERENDER 0x10000 +// Below are interface 24 and later +#define AGSE_PRESAVEGAME 0x20000 +#define AGSE_POSTRESTOREGAME 0x40000 +#define AGSE_TOOHIGH 0x80000 + +// GetFontType font types +#define FNT_INVALID 0 +#define FNT_SCI 1 +#define FNT_TTF 2 + +// PlaySoundChannel sound types +#define PSND_WAVE 1 +#define PSND_MP3STREAM 2 +#define PSND_MP3STATIC 3 +#define PSND_OGGSTREAM 4 +#define PSND_OGGSTATIC 5 +#define PSND_MIDI 6 +#define PSND_MOD 7 + +class IAGSScriptManagedObject { +public: + // when a ref count reaches 0, this is called with the address + // of the object. Return 1 to remove the object from memory, 0 to + // leave it + virtual int Dispose(const char *address, bool force) = 0; + // return the type name of the object + virtual const char *GetType() = 0; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; +protected: + IAGSScriptManagedObject() {}; + ~IAGSScriptManagedObject() {}; +}; + +class IAGSManagedObjectReader { +public: + virtual void Unserialize(int key, const char *serializedData, int dataSize) = 0; +protected: + IAGSManagedObjectReader() {}; + ~IAGSManagedObjectReader() {}; +}; + +class IAGSFontRenderer { +public: + virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; + virtual void FreeMemory(int fontNumber) = 0; + virtual bool SupportsExtendedCharacters(int fontNumber) = 0; + virtual int GetTextWidth(const char *text, int fontNumber) = 0; + virtual int GetTextHeight(const char *text, int fontNumber) = 0; + virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; + virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; + virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; +protected: + IAGSFontRenderer() {}; + ~IAGSFontRenderer() {}; +}; + +// The plugin-to-engine interface +class IAGSEngine { +public: + int32 version; + int32 pluginId; // used internally, do not touch + +public: + // quit the game + AGSIFUNC(void) AbortGame (const char *reason); + // get engine version + AGSIFUNC(const char*) GetEngineVersion (); + // register a script function with the system + AGSIFUNC(void) RegisterScriptFunction (const char *name, void *address); +#ifdef WINDOWS_VERSION + // get game window handle + AGSIFUNC(HWND) GetWindowHandle(); + // get reference to main DirectDraw interface + AGSIFUNC(LPDIRECTDRAW2) GetDirectDraw2 (); + // get the DDraw surface associated with a bitmap + AGSIFUNC(LPDIRECTDRAWSURFACE2) GetBitmapSurface (BITMAP *); +#endif + // get a reference to the screen bitmap + AGSIFUNC(BITMAP *) GetScreen (); + + // *** BELOW ARE INTERFACE VERSION 2 AND ABOVE ONLY + // ask the engine to call back when a certain event happens + AGSIFUNC(void) RequestEventHook (int32 event); + // get the options data saved in the editor + AGSIFUNC(int) GetSavedData (char *buffer, int32 bufsize); + + // *** BELOW ARE INTERFACE VERSION 3 AND ABOVE ONLY + // get the virtual screen + AGSIFUNC(BITMAP *) GetVirtualScreen (); + // write text to the screen in the specified font and colour + AGSIFUNC(void) DrawText (int32 x, int32 y, int32 font, int32 color, char *text); + // get screen dimensions + AGSIFUNC(void) GetScreenDimensions (int32 *width, int32 *height, int32 *coldepth); + // get screen surface to draw on + AGSIFUNC(unsigned char**) GetRawBitmapSurface (BITMAP *); + // release the surface + AGSIFUNC(void) ReleaseBitmapSurface (BITMAP *); + // get the current mouse co-ordinates + AGSIFUNC(void) GetMousePosition (int32 *x, int32 *y); + + // *** BELOW ARE INTERFACE VERSION 4 AND ABOVE ONLY + // get the current room number + AGSIFUNC(int) GetCurrentRoom (); + // get the number of background scenes in this room + AGSIFUNC(int) GetNumBackgrounds (); + // get the current background frame + AGSIFUNC(int) GetCurrentBackground (); + // get a background scene bitmap + AGSIFUNC(BITMAP *) GetBackgroundScene (int32); + // get dimensions of a bitmap + AGSIFUNC(void) GetBitmapDimensions (BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth); + + // *** BELOW ARE INTERFACE VERSION 5 AND ABOVE ONLY + // similar to fwrite - buffer, size, filehandle + AGSIFUNC(int) FWrite (void *, int32, int32); + // similar to fread - buffer, size, filehandle + AGSIFUNC(int) FRead (void *, int32, int32); + // print text, wrapping as usual + AGSIFUNC(void) DrawTextWrapped (int32 x, int32 y, int32 width, int32 font, int32 color, const char *text); + // set the current active 'screen' + AGSIFUNC(void) SetVirtualScreen (BITMAP *); + // look up a word in the parser dictionary + AGSIFUNC(int) LookupParserWord (const char *word); + // draw a bitmap to the active screen + AGSIFUNC(void) BlitBitmap (int32 x, int32 y, BITMAP *, int32 masked); + // update the mouse and music + AGSIFUNC(void) PollSystem (); + + // *** BELOW ARE INTERFACE VERSION 6 AND ABOVE ONLY + // get number of characters in game + AGSIFUNC(int) GetNumCharacters (); + // get reference to specified character struct + AGSIFUNC(AGSCharacter*) GetCharacter (int32); + // get reference to game struct + AGSIFUNC(AGSGameOptions*) GetGameOptions (); + // get reference to current palette + AGSIFUNC(AGSColor*) GetPalette(); + // update palette + AGSIFUNC(void) SetPalette (int32 start, int32 finish, AGSColor*); + + // *** BELOW ARE INTERFACE VERSION 7 AND ABOVE ONLY + // get the current player character + AGSIFUNC(int) GetPlayerCharacter (); + // adjust to main viewport co-ordinates + AGSIFUNC(void) RoomToViewport (int32 *x, int32 *y); + // adjust from main viewport co-ordinates (ignores viewport bounds) + AGSIFUNC(void) ViewportToRoom (int32 *x, int32 *y); + // number of objects in current room + AGSIFUNC(int) GetNumObjects (); + // get reference to specified object + AGSIFUNC(AGSObject*) GetObject (int32); + // get sprite graphic + AGSIFUNC(BITMAP *) GetSpriteGraphic (int32); + // create a new blank bitmap + AGSIFUNC(BITMAP *) CreateBlankBitmap (int32 width, int32 height, int32 coldep); + // free a created bitamp + AGSIFUNC(void) FreeBitmap (BITMAP *); + + // *** BELOW ARE INTERFACE VERSION 8 AND ABOVE ONLY + // get one of the room area masks + AGSIFUNC(BITMAP *) GetRoomMask(int32); + + // *** BELOW ARE INTERFACE VERSION 9 AND ABOVE ONLY + // get a particular view frame + AGSIFUNC(AGSViewFrame *) GetViewFrame(int32 view, int32 loop, int32 frame); + // get the walk-behind baseline of a specific WB area + AGSIFUNC(int) GetWalkbehindBaseline(int32 walkbehind); + // get the address of a script function + AGSIFUNC(void *) GetScriptFunctionAddress(const char * funcName); + // get the transparent colour of a bitmap + AGSIFUNC(int) GetBitmapTransparentColor(BITMAP *); + // get the character scaling level at a particular point + AGSIFUNC(int) GetAreaScaling (int32 x, int32 y); + // equivalent to the text script function + AGSIFUNC(int) IsGamePaused(); + + // *** BELOW ARE INTERFACE VERSION 10 AND ABOVE ONLY + // get the raw pixel value to use for the specified AGS colour + AGSIFUNC(int) GetRawPixelColor (int32 color); + + // *** BELOW ARE INTERFACE VERSION 11 AND ABOVE ONLY + // get the width / height of the specified sprite + AGSIFUNC(int) GetSpriteWidth (int32); + AGSIFUNC(int) GetSpriteHeight (int32); + // get the dimensions of the specified string in the specified font + AGSIFUNC(void) GetTextExtent (int32 font, const char *text, int32 *width, int32 *height); + // print a message to the debug console + AGSIFUNC(void) PrintDebugConsole (const char *text); + // play a sound on the specified channel + AGSIFUNC(void) PlaySoundChannel (int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename); + // same as text script function + AGSIFUNC(int) IsChannelPlaying (int32 channel); + + // *** BELOW ARE INTERFACE VERSION 12 AND ABOVE ONLY + // invalidate a region of the virtual screen + AGSIFUNC(void) MarkRegionDirty(int32 left, int32 top, int32 right, int32 bottom); + // get mouse cursor details + AGSIFUNC(AGSMouseCursor *) GetMouseCursor(int32 cursor); + // get the various components of a pixel + AGSIFUNC(void) GetRawColorComponents(int32 coldepth, int32 color, int32 *red, int32 *green, int32 *blue, int32 *alpha); + // make a pixel colour from the supplied components + AGSIFUNC(int) MakeRawColorPixel(int32 coldepth, int32 red, int32 green, int32 blue, int32 alpha); + // get whether the font is TTF or SCI + AGSIFUNC(int) GetFontType(int32 fontNum); + // create a new dynamic sprite slot + AGSIFUNC(int) CreateDynamicSprite(int32 coldepth, int32 width, int32 height); + // free a created dynamic sprite + AGSIFUNC(void) DeleteDynamicSprite(int32 slot); + // check if a sprite has an alpha channel + AGSIFUNC(int) IsSpriteAlphaBlended(int32 slot); + + // *** BELOW ARE INTERFACE VERSION 13 AND ABOVE ONLY + // un-request an event, requested earlier with RequestEventHook + AGSIFUNC(void) UnrequestEventHook(int32 event); + // draw a translucent bitmap to the active screen + AGSIFUNC(void) BlitSpriteTranslucent(int32 x, int32 y, BITMAP *, int32 trans); + // draw a sprite to the screen, but rotated around its centre + AGSIFUNC(void) BlitSpriteRotated(int32 x, int32 y, BITMAP *, int32 angle); + + // *** BELOW ARE INTERFACE VERSION 14 AND ABOVE ONLY +#ifdef WINDOWS_VERSION + // get reference to main DirectSound interface + AGSIFUNC(LPDIRECTSOUND) GetDirectSound(); +#endif + // disable AGS sound engine + AGSIFUNC(void) DisableSound(); + // check whether a script function can be run now + AGSIFUNC(int) CanRunScriptFunctionNow(); + // call a user-defined script function + AGSIFUNC(int) CallGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0, long arg3 = 0); + + // *** BELOW ARE INTERFACE VERSION 15 AND ABOVE ONLY + // force any sprites on-screen using the slot to be updated + AGSIFUNC(void) NotifySpriteUpdated(int32 slot); + // change whether the specified sprite is a 32-bit alpha blended image + AGSIFUNC(void) SetSpriteAlphaBlended(int32 slot, int32 isAlphaBlended); + // run the specified script function whenever script engine is available + AGSIFUNC(void) QueueGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0); + // register a new dynamic managed script object + AGSIFUNC(int) RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback); + // add an object reader for the specified object type + AGSIFUNC(void) AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader); + // register an un-serialized managed script object + AGSIFUNC(void) RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback); + + // *** BELOW ARE INTERFACE VERSION 16 AND ABOVE ONLY + // get the address of a managed object based on its key + AGSIFUNC(void*) GetManagedObjectAddressByKey(int key); + // get managed object's key from its address + AGSIFUNC(int) GetManagedObjectKeyByAddress(const char *address); + + // *** BELOW ARE INTERFACE VERSION 17 AND ABOVE ONLY + // create a new script string + AGSIFUNC(const char*) CreateScriptString(const char *fromText); + + // *** BELOW ARE INTERFACE VERSION 18 AND ABOVE ONLY + // increment reference count + AGSIFUNC(int) IncrementManagedObjectRefCount(const char *address); + // decrement reference count + AGSIFUNC(int) DecrementManagedObjectRefCount(const char *address); + // set mouse position + AGSIFUNC(void) SetMousePosition(int32 x, int32 y); + // simulate the mouse being clicked + AGSIFUNC(void) SimulateMouseClick(int32 button); + // get number of waypoints on this movement path + AGSIFUNC(int) GetMovementPathWaypointCount(int32 pathId); + // get the last waypoint that the char/obj passed + AGSIFUNC(int) GetMovementPathLastWaypoint(int32 pathId); + // get the co-ordinates of the specified waypoint + AGSIFUNC(void) GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y); + // get the speeds of the specified waypoint + AGSIFUNC(void) GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed); + + // *** BELOW ARE INTERFACE VERSION 19 AND ABOVE ONLY + // get the current graphics driver ID + AGSIFUNC(const char*) GetGraphicsDriverID(); + + // *** BELOW ARE INTERFACE VERSION 22 AND ABOVE ONLY + // get whether we are running under the editor's debugger + AGSIFUNC(int) IsRunningUnderDebugger(); + // tells the engine to break into the debugger when the next line of script is run + AGSIFUNC(void) BreakIntoDebugger(); + // fills buffer with \fileName, as appropriate + AGSIFUNC(void) GetPathToFileInCompiledFolder(const char* fileName, char* buffer); + + // *** BELOW ARE INTERFACE VERSION 23 AND ABOVE ONLY +#ifdef WINDOWS_VERSION + // get reference to keyboard Direct Input device + AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputKeyboard(); + // get reference to mouse Direct Input device + AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputMouse(); +#endif + // install a replacement renderer for the specified font number + AGSIFUNC(IAGSFontRenderer*) ReplaceFontRenderer(int fontNumber, IAGSFontRenderer* newRenderer); +}; + +#ifdef THIS_IS_THE_PLUGIN + +#ifdef WINDOWS_VERSION +#define DLLEXPORT extern "C" __declspec(dllexport) +#else +// MAC VERSION: compile with -fvisibility=hidden +// gcc -dynamiclib -std=gnu99 agsplugin.c -fvisibility=hidden -o agsplugin.dylib +#define DLLEXPORT extern "C" __attribute__((visibility("default"))) +#endif + +DLLEXPORT const char * AGS_GetPluginName(void); +DLLEXPORT int AGS_EditorStartup (IAGSEditor *); +DLLEXPORT void AGS_EditorShutdown (void); +DLLEXPORT void AGS_EditorProperties (HWND); +DLLEXPORT int AGS_EditorSaveGame (char *, int); +DLLEXPORT void AGS_EditorLoadGame (char *, int); +DLLEXPORT void AGS_EngineStartup (IAGSEngine *); +DLLEXPORT void AGS_EngineShutdown (void); +DLLEXPORT int AGS_EngineOnEvent (int, int); +DLLEXPORT int AGS_EngineDebugHook(const char *, int, int); +DLLEXPORT void AGS_EngineInitGfx(const char* driverID, void *data); +// We export this to verify that we are an AGS Plugin +DLLEXPORT int AGS_PluginV2 ( ) { return 1; } + +#endif // THIS_IS_THE_PLUGIN + +#endif diff --git a/engines/ags/engine/plugin/global_plugin.cpp b/engines/ags/engine/plugin/global_plugin.cpp new file mode 100644 index 000000000000..001841fe2d4e --- /dev/null +++ b/engines/ags/engine/plugin/global_plugin.cpp @@ -0,0 +1,260 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Stubs for plugin functions. +// +//============================================================================= + +#include +#include "ac/global_plugin.h" +#include "ac/mouse.h" +#include "util/string_compat.h" + +int pluginSimulatedClick = NONE; + +void PluginSimulateMouseClick(int pluginButtonID) { + pluginSimulatedClick = pluginButtonID - 1; +} + +//============================================================================= +// +// Script API Functions +// +//============================================================================= + +#include "script/script_runtime.h" + +RuntimeScriptValue Sc_PluginStub_Void(const RuntimeScriptValue *params, int32_t param_count) +{ + return RuntimeScriptValue((int32_t)0); +} + +RuntimeScriptValue Sc_PluginStub_Int0(const RuntimeScriptValue *params, int32_t param_count) +{ + return RuntimeScriptValue().SetInt32(0); +} + +RuntimeScriptValue Sc_PluginStub_IntNeg1(const RuntimeScriptValue *params, int32_t param_count) +{ + return RuntimeScriptValue().SetInt32(-1); +} + +RuntimeScriptValue Sc_PluginStub_NullStr(const RuntimeScriptValue *params, int32_t param_count) +{ + return RuntimeScriptValue().SetStringLiteral(NULL); +} + +bool RegisterPluginStubs(const char* name) +{ + // Stubs for plugin functions. + + bool is_agsteam = (ags_stricmp(name, "agsteam") == 0) || (ags_stricmp(name, "agsteam-unified") == 0) || + (ags_stricmp(name, "agsteam-disjoint") == 0); + bool is_agsgalaxy = (ags_stricmp(name, "agsgalaxy") == 0) || (ags_stricmp(name, "agsgalaxy-unified") == 0) || + (ags_stricmp(name, "agsgalaxy-disjoint") == 0); + + if (ags_stricmp(name, "ags_shell") == 0) + { + // ags_shell.dll + ccAddExternalStaticFunction("ShellExecute", Sc_PluginStub_Void); + return true; + } + else if (ags_stricmp(name, "ags_snowrain") == 0) + { + // ags_snowrain.dll + ccAddExternalStaticFunction("srSetSnowDriftRange", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowDriftSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowFallSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srChangeSnowAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowBaseline", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowTransparency", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowDefaultView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srChangeRainAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainDefaultView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainTransparency", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainBaseline", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainFallSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetBaseline", Sc_PluginStub_Void); + return true; + } + else if (ags_stricmp(name, "agsjoy") == 0) + { + // agsjoy.dll + ccAddExternalStaticFunction("JoystickCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("JoystickName", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("JoystickRescan", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Open^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsOpen^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Click^1", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::Close^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::Valid^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Unplugged^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::GetName^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::GetAxis^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsButtonDown^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsJoyBtnDown^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Update^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::DisableEvents^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::EnableEvents^1", Sc_PluginStub_Void); + return true; + } + else if (ags_stricmp(name, "agsblend") == 0) + { + // agsblend.dll + ccAddExternalStaticFunction("DrawAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("PutAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Blur", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("HighPass", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("DrawAdd", Sc_PluginStub_Int0); + return true; + } + else if (ags_stricmp(name, "agsflashlight") == 0) + { + // agsflashlight.dll + ccAddExternalStaticFunction("SetFlashlightTint", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightTintRed", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightTintGreen", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightTintBlue", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightMinLightLevel", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightMaxLightLevel", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightDarkness", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightDarkness", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightDarknessSize", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightDarknessSize", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightBrightness", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightBrightness", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightBrightnessSize", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightBrightnessSize", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightPosition", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightPositionX", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightPositionY", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightFollowMouse", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightFollowMouse", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightFollowCharacter", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightFollowCharacter", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterDX", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterDY", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterHorz", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterVert", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightMask", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightMask", Sc_PluginStub_Int0); + return true; + } + else if (ags_stricmp(name, "agswadjetutil") == 0) + { + // agswadjetutil.dll + ccAddExternalStaticFunction("IsOnPhone", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("FakeKeypress", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosSetAchievementValue", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosGetAchievementValue", Sc_PluginStub_IntNeg1); + ccAddExternalStaticFunction("IosShowAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosResetAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("MobileGetAchievement", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("MobileSetAchievement", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("MobileShowAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("MobileResetAchievements", Sc_PluginStub_Void); + return true; + } + else if (ags_stricmp(name, "agsspritefont") == 0) + { + ccAddExternalStaticFunction("SetSpriteFont", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetVariableSpriteFont", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetGlyph", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetSpacing", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetLineHeightAdjust", Sc_PluginStub_Void); + return true; + } + else if (is_agsteam || is_agsgalaxy) + { + // agsteam.dll or agsgalaxy.dll + ccAddExternalStaticFunction("AGS2Client::IsAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::SetAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::ResetAchievement^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetIntStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetFloatStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetAverageRateStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::SetIntStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::SetFloatStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::UpdateAverageRateStat^3", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::ResetStatsAndAchievements^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGS2Client::get_Initialized", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::RequestLeaderboard^3", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGS2Client::UploadScore^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::geti_LeaderboardNames", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::geti_LeaderboardScores", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::get_LeaderboardCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetUserName^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::FindLeaderboard^1", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGS2Client::Initialize^2", Sc_PluginStub_Int0); + if (is_agsteam) + { + ccAddExternalStaticFunction("AGSteam::IsAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::SetAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::ResetAchievement^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetIntStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetFloatStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetAverageRateStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::SetIntStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::SetFloatStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::UpdateAverageRateStat^3", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::ResetStatsAndAchievements^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSteam::get_Initialized", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::RequestLeaderboard^3", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSteam::UploadScore^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::geti_LeaderboardNames", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::geti_LeaderboardScores", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::get_LeaderboardCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetUserName^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::FindLeaderboard^1", Sc_PluginStub_Void); + } + else // agsgalaxy + { + ccAddExternalStaticFunction("AGSGalaxy::IsAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::SetAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::ResetAchievement^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetIntStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetFloatStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetAverageRateStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::SetIntStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::SetFloatStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::UpdateAverageRateStat^3", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::ResetStatsAndAchievements^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSGalaxy::get_Initialized", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::RequestLeaderboard^3", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSGalaxy::UploadScore^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::geti_LeaderboardNames", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::geti_LeaderboardScores", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::get_LeaderboardCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetUserName^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::Initialize^2", Sc_PluginStub_Int0); + } + return true; + } + + return false; +} diff --git a/engines/ags/engine/plugin/plugin_builtin.h b/engines/ags/engine/plugin/plugin_builtin.h new file mode 100644 index 000000000000..a25d8f03a2bf --- /dev/null +++ b/engines/ags/engine/plugin/plugin_builtin.h @@ -0,0 +1,41 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Plugin system functions. +// +//============================================================================= +#ifndef __AGS_EE_PLUGIN__PLUGINBUILTIN_H +#define __AGS_EE_PLUGIN__PLUGINBUILTIN_H + +#define PLUGIN_FILENAME_MAX (49) + +class IAGSEngine; + +using namespace AGS; // FIXME later + +// Initial implementation for apps to register their own inbuilt plugins + +struct InbuiltPluginDetails { + char filename[PLUGIN_FILENAME_MAX+1]; + void (*engineStartup) (IAGSEngine *); + void (*engineShutdown) (); + int (*onEvent) (int, int); + void (*initGfxHook) (const char *driverName, void *data); + int (*debugHook) (const char * whichscript, int lineNumber, int reserved); +}; + +// Register a builtin plugin. +int pl_register_builtin_plugin(InbuiltPluginDetails const &details); + +#endif // __AGS_EE_PLUGIN__PLUGINBUILTIN_H diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/engine/plugin/plugin_engine.h new file mode 100644 index 000000000000..d5b3cb265698 --- /dev/null +++ b/engines/ags/engine/plugin/plugin_engine.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Plugin system functions. +// +//============================================================================= +#ifndef __AGS_EE_PLUGIN__PLUGINENGINE_H +#define __AGS_EE_PLUGIN__PLUGINENGINE_H + +#include +#include "game/game_init.h" +#include "game/plugininfo.h" + +#define PLUGIN_FILENAME_MAX (49) + +class IAGSEngine; +namespace AGS { namespace Common { class Stream; }} +using namespace AGS; // FIXME later + +void pl_stop_plugins(); +void pl_startup_plugins(); +int pl_run_plugin_hooks (int event, int data); +void pl_run_plugin_init_gfx_hooks(const char *driverName, void *data); +int pl_run_plugin_debug_hooks (const char *scriptfile, int linenum); +// Tries to register plugins, either by loading dynamic libraries, or getting any kind of replacement +Engine::GameInitError pl_register_plugins(const std::vector &infos); +bool pl_is_plugin_loaded(const char *pl_name); + +//returns whether _any_ plugins want a particular event +bool pl_any_want_hook(int event); + +void pl_set_file_handle(long data, AGS::Common::Stream *stream); +void pl_clear_file_handle(); + +#endif // __AGS_EE_PLUGIN__PLUGINENGINE_H diff --git a/engines/ags/engine/plugin/pluginobjectreader.cpp b/engines/ags/engine/plugin/pluginobjectreader.cpp new file mode 100644 index 000000000000..2d2700b31d5b --- /dev/null +++ b/engines/ags/engine/plugin/pluginobjectreader.cpp @@ -0,0 +1,19 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "plugin/pluginobjectreader.h" +#include "ac/runtime_defines.h" + +PluginObjectReader pluginReaders[MAX_PLUGIN_OBJECT_READERS]; +int numPluginReaders = 0; diff --git a/engines/ags/engine/plugin/pluginobjectreader.h b/engines/ags/engine/plugin/pluginobjectreader.h new file mode 100644 index 000000000000..7add04c40ccd --- /dev/null +++ b/engines/ags/engine/plugin/pluginobjectreader.h @@ -0,0 +1,28 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H +#define __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H + +class IAGSManagedObjectReader; + +struct PluginObjectReader { + IAGSManagedObjectReader *reader; + const char *type; +}; + +#endif // __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H diff --git a/engines/ags/engine/resource/DefaultGDF.gdf.xml b/engines/ags/engine/resource/DefaultGDF.gdf.xml new file mode 100644 index 000000000000..df90691861f3 --- /dev/null +++ b/engines/ags/engine/resource/DefaultGDF.gdf.xml @@ -0,0 +1,18 @@ + + + + Gfx Driver 4 + This is an example GDF for the DirectX SDK. + 2006-03-03 + + Action/Adventure + + + + + + + Microsoft DirectX SDK + + + \ No newline at end of file diff --git a/engines/ags/engine/resource/game-1.ICO b/engines/ags/engine/resource/game-1.ICO new file mode 100644 index 0000000000000000000000000000000000000000..d26793b00360870930f8c82129caac0aa54ae73d GIT binary patch literal 33126 zcmeIb2VB-i@;|BwqRdU$-yc?o&R`=d&|AJ3BKwy9gm8olm4#R;gjl$c-|Gu=8zDZ&XO@;v-q)H4p|w&BT(2)`HH0`5CWJYDgIfsvOmZJo z0=NBJk-;eX6<*oGe%u6MZ?{4? z4H+Vwh7S`?R;z{6tm(oXpfi2wyf5vZgr0t13Y(BQ!$7~cnv z&=J9C$2N6U5vrmhLiI+9P<;at>bOdT;aOor28%GSgCat6nAq;&BqBjWWW}o@N>@un zEtxN(0s=%deiv=OTI^7h7dzJYix|}*B34OB#G&oGhN_8Oxc@GLQDXNfJ+XVk1`)qI zUnHm~iv+YGK}}I4`Fe;w8$3kvs8M3CoSfJ@TvP1BJ@?_+`=?D6DQH`Y&IoZ3ZB5nE z6sg9BBGtrPq}nYKhe7M%(YoUBf_dWb{{13NRz{@Z*=a-7MVg_$NV6C((l)FWN6_AM ztH~nW+Dc^1oh35C<4pb0;wboi6xSXdr7MnZ_ZLTZhl_0RD|@7t$Tl$)$7E#1v2~6j zXPk-1#pk(}79t;f%LhO5S1lF=2BSrRsj(=qFaySm!i950;aW#gxWz*hfe%HvZ_#us zQ8de16uYk%C5EF#$=+B|8ssI)G}J`-cvDe<_EzBD6`;Ff#S&4eI!IKG))SQz$BW9@ z)}qpOp{TN&D5@6C6;*3iiR$T=qGrKNQHTDnGtw7zriP*}Jz3NbQW5o_tA2)+s9!u! z)T7-EQznWAzfGc{zD_i*v=xnO?M2hMGI(aS!XX=yf=$hWo6Nd zwzjUa6Rj@JqHXCy(J^s?=$JQCbZl}J9c?Y*r0xiDa*Vz>X>1@)nv4-Ar%e(kZRU$k zhZUmBbDij3Z7X{Gy+qG8U(q{xqUc?2BYM|6iry`5;*^PjI2G(I`qr)#eICx@G}?M* zq@FknKAg3gBhEr@`y=DTIqNCnoZm)qe)Upu-rY%DL|7C5#p`Ped6u90`YcRm3XJQOuUEsy^b33{=IwR!_#fz z!~PEO;oaYfPwETACl|WKCzpD~r@5)()3@IdpXVGBpP%m$U%hlg5D}#0d6jsdRW>$` z@jr39D1YxzKZgb8`qp0m;EF8&%&g;ONp7nbT39ahJoTe1ywhqLT3siP)flF4IeTOD z55G?ftNGp8S(>_YY>gC#S}u!zgX0l8D%H$QzzRMkf(2alRGS4UBH`cgUTfV$Aw{3O;~17-W^FDjH(M@}54 ztu$!f5OcS>Bt55B(xu-D5qI&A@2RN_HCw!Vy|dReeD7y4KIx5J-(L{-!XLgGKKlKL zsV+h3yT_V46z&ni?oR9X-)G$a;_-gfZ~int?C`Z(ZUyji;=a-*Gv#q2e?8v}({*IPXBeQCzS z&;Rh@n=kcMX76&JZ!y~~cSrhdU-!ZN~GUco&M`hLwOk#d3luyp>;)tJJgm` zOP?-8=?AN1WK@QZ7%|3d{vvy)p!B9T=}#r~-AytoBSwtS8#86mTEC?Hyrcuy|L*%< zYm*UrdU}Ra7OnG3$|!ED56%0#@0-n+*;yLvna#HkOFGzk_r+envcLOYthQWcH+%Ln zhnU0+H~w5Mu|R{F@X&{tf?@A-xw~{#O@iJGt#l1Jei(LJS7ffT4gU zFdWc&3fg!*V&HSWhOZq0@Nbz%%o`~`_!<9gh1E^yx1(@d10Mjr9m;)>URsm}P z7r-6x1U3y|BkB!+8?X*o11tsR1I#B@-D3de1wVu3;y=v?rk!PyWs_x<+s1vy{W}j} zdR>7nKoGDUh=)6NNJ&OELrF#)Rg#g(9>7sq8JQy(<@<0A+iFojDBuS$U+jSe0NfOmQC&(ZrdWj8Sn27b)#3coOR}V}NDc3D^q6YRSu&uF_DuyF+`#pAU{2Nk_-%QTCWol!@0z zMrzZc5t@{uIh6Kjs8alp!L)PmV2V{ypCej*6<-D~8gbt=AP!(Y zI07>OLx9`x?;H=Tdsq+gb4>v5a}OX~Q(msnQ*-ER8TzBB(A<~`EX*lyqB$KOZ%W7U zKHJ!Uvc`_4jFCE&3Lfkms!j=NLuluaAru83M1Tj|fkPEup2l46o5y^1`qmfj)MGUJTDta0DORD0FS*Nj)#8*516+s_agyofc16EBDEox zN=*!@$Z`S|f#$MBv#Daqe5zVJk17|AHv2;vVhte?y4x<0} zfVS8{Px?Ouv~B|sd!uk521o=BfP35)=sCvZ`s$IR5YF7cv7eC>{+!<75ZAoPq z4_PJ#bPzJIM{5M_#u#AvkAtkoC@4^1?|dDMy$KCm3{I7kB0KzlxL5`5S>Ncl57zYAd9$RWr?z!z8!SOU*`JV?j>Fx;ER zo0G1RV(!t=x|BO<9F@$UMb+r`Euy9I0rP9R)i((59{4v~^n$ zg#`FfsMkgcadoBeO`f!Es}F7P-b_mz*U&=iskBy2m4aksBs{?UDA5Hh13U(DKzj{% z&443Yzsa38ZtrXAUjU)Fgj7ISN!#lIQ}S9}xqmqoBWRKnBJuD7=hz@HjXRbOW_O z7QpiZ+n9?09uGReZygUzKg&Olf1dXiuF%xzDl*ZB&YMa#D{bk-Mi=S=-F-Vk=;F>W zstFG!|L`dC4UZ(388gTMG`Wo!K|$ljQL^1K$_KqI`}R_QK>;p%8G^nj_sIwM{v!n|HOZzk2RT}d7Oo9Hy?zI-5#E*#iJNlD2RymL3XPM%E8>gu#X zTbsN`kEUQFBZ@FFp(xb5z>BQKHq@7#KzADIsMyJg4$qxKA>k2ZJk6RMAoJnSi)<4l z0Eh8D7qoY%snI^QA)l$r%U#isle?uND|-Vr^d+=Q%7Y@j=K0|tjR$3X&V9*!`b!Fr zA09`lDvAn|l1GjFqyTezh0Pplc3VrmVg7U>Wf$E&mO>3VS(KQ1m^Ln2L>}n(Eh9(L z7SO*{M~6begJ=Uoio+Zbuc=BAYMK-}d@SXzUQ2h%i>YFT9UWP|jJEBJq1hJW$rm!f z^8nidhcFN13{j;MLx)o1Fb(ojSA86)q5e2XL;YJH4b^W}4H@*QzJkJSw6O&!2GW5Y zz|;1UHr@{gm=>n#Sqt+^a=oUqvPIgMQGYF(Jf5nTE}}N*y0dZNbSpcB?v~|HerY)c z1qPF=mKFt!8bv|e?|OO^g!duChtn?oF_dC%MxM6YXl`f)S#7SO$xDw>SVR?d7uHaQ z)fC$6>rIwRmXbaCI|}nb9Oyp)`m-?xPJpLvu%99@f2QeZQyJ{*a_Hhh*w;s3Tl%Q0 zemPoR;df|nIdB}{@!$>E0h54{0P6%P51v&PB=nnWXiQ8WJNmm4*fe!3Y^ihWM!L8+ zmR>5!q^nI;bfma~T&7Pa7sxBq&V3#ZK12c$kb`J-W!f^+pKK0%OdHx>Ci{k4G&|`$ zt%&KNW7Rh(eR~@1bPpmYZ*Q7EQkS+X$V+VE{op|+?s;OwaB9PRnE+H9>Qe)3>uOUY zYMnTan#~NULT@A;#&%7hAdvCyBSC>M@jDftXlB>ZITCnX7Ib=Ve z^$oAms+#+>wCp~47T%@E+DEi8pqTuFL&?g_jJClp;5lF~kk0hOcIse13VdiZF`_6f z*bc+gDb;u^b-@1YSpc16G?ogqN6^B-gC2s$YJhFVWMC`6axf8)&JC;&xNo0H4gxJF z+hpVZrO^E+)~=#6VSaQob059cTt@xfofI0oo9u^ckqgGD3-mbaKIVZh^gsX*u5Uo$ znuEzp&x%&NG|Hfmq15L|@2c_HMc82%J)NlmHcI?3jjvT?WePzb zj{&Bi<4=nLwq>O(d4)KUgqW<^5prArWKYIQ+}jaVB&- zW*eP`FH${Hi);rEIt%((_I&}i5f=bVKkETiKoOAWH`G5{>Njjy$9{e_##yI_GhL1i zrI!kh(7T-t^v;zt)CWD_g1EEA07i=(uNJCOuRpU`)-&!odRU#C;p`~V;Qe7Rmy=#>UO z*Djn*-Ja{{D(s$DiZbZEu15Os(rLPTriDV`1LHyDh<>l%zn?yP_g#9iw-n99SDN2SO$c7A@fb74R98DLuxKTM|#!^{{^`8O2b}`p%3$RZo z^%0&){;wX(j!Yjhj2dj_(ka-z*LOwGgW^njzq^?}Ip0ffUOq*6Nzt?d{bet&NLN~0 zrOR;i@xzCdGGz+Iq5UbC3yzJSKv|4=$}=L-*1Wsm0ug+%?qM zK4u%1>1Msh^PiOVXV!lwqr&$c)zhLT__L=st*0CD+v&B^EPB891bx!qMIT(~rHdzP zXgkKPEo2~O-aLB$!2<~o9zT9ed60oP4K+&D8$~&$CRBv6QKmVZnzeMOM-%Oak9;6y zC;4E0@xt!|;0H-~F~@G$C@*Iw zQ#WLFkM@YSl$BMuzj>@P-CRrOzGt5QsvPa}at%h&iKPqZ4D{@+gh+Z=mMx+GhGYwh63_N{0oyUg_)XBePkrn`TNrz*a3TZ%tH_4qt7eR=S>(7y{hWeFlQzm zN(`qUS9|hQQ6_KnJ=4!IF-a^0bv|_FDd;|5HPr$kBg1{jvOE^h1(b|b2d_8;9Z>@M zI}mSrF)@<*UF<1ePlt>&hcS=1FuhOXnPi`T*x>0=aeT~3YFW03&Te)C{ZaIK#WDJz zw}qJg_d9CotGg8Z ze+u-U?V|TP>*>whRC+ZzmR@Npr_-DV;TFnDZ;<2j$uq+EpBf}x-X2x$7unruf zOV@ln=n`~bCE|{eR#Vs)`c0*1!QB1=Q+;YhY)e8vbe)8LjQ@|%c1rsH&4M&~3G>1& z#6)f<$I%NdRdlYslA56>N>k%0Z%-8E?~9>=^dvf#l}xEI!IZFY7HwBjp;q(j{tk?Rqxxfee?W+&Kf@N=$Q4^py_1W1pb7L}^l+l{9&4!x?`v1BWZUOA zmE%(;-7Fk$L~RoKJ?I7Q|B7t-pr@HWI@3Y#w^d8}|0T=|w|qCyWwu8hR)AL?bb8lz z>N%81Z3pA2HZFn+p+7UNCQ%AvS_zovqCqdmJ~;-sbpRX_mBvC@|1tfokdgA?ntzEg zH@zKUV$>77!j9uok`laZsY2=8+4qk@M(QE|=MabMcd(PtU$$&1+W^11eEr=wa{1Gz zJ}5LZpf<#Mx&I~fmqY(`H4*aS=)IN-dgIu^C;boK@Ct0i{#CZrHP@P&#+y(DY@=f6 zfIQHg4ck5g{>>q!Cu=_(^XAw$)66_za7>)%f64sEJ}`V@_Ww8*wgc-(hoC3hS1o__ z-q}7$|DWsaR@-N6@Iel)seo^M8oI9!W3K=@qsrOQ^;Z**AO7j%PX-;IIR4|p2`1mu ze>*XX9zw3)gWmtJx0&8;DxueprqD~U-){SQ(iOx<`W=^3&(ej|GTVx3CYVww)=LWE zyB|jzvk=QTjJQTJd>bC)+}A7v9RFn6c};}lz*76~80hC1K()FW#SR}vxtK@tV2`~L z8nTpWd-t_hjdy8jesc`+UV^oWKJdQN!i@4TCpP$avG4b*%dO^m?JP5+FH0twQyb!b z-2b=YG5;0A{)61J?t7;$pB|>~rTfv_=(dk1UFGrTw32#PE}=HWiyAPmS6W$6Db~gc z;78>kc98)-9Dw~E51EJtA0p7t9RHTC2eJRl{tw5%I1b#5`Lhl-#4gZS2%oQBPn()d z4LKet$^v}nMW_yztTX1B8PRFT-3g3?ys@MIdcCT`=vNbuA9lsY7-txa`K}ChMH~1k zp?^2*ALu*eh|+tl74&xHF?xu2!2PITN&jE-bfF9IM^7V8*a?56Ww{MCV7-9t=SsA# z2>0SO!gSEF4}G)?e24}gwh!=uZGWlm=NKr*02`tI8i%S;9QvQ>?|>hC0^{m}hf7?6 zk5{rM;)Xk6^EM(zbqe->HTYCEclHavg?9dJwTJ7348t*xD-io=2QB^3@3#>9dT{Ij zy;YlszAvChMMvnh{k!Ns;sUoJAJ;alql?f1XTXCV_{;5xmA5$AQxo`6x7v=XU`LcL zoI`ojr%(pQ#(vNd4|#}1|3>o|hb(aXk9B_r-sgk08PiGhbqD0B z5i(x~es)YAM}1hA>%{BA!79}5@5}M=-&Crc)=oNVq)(Mt+iYL6ocet>(9M`odL?5o zy@B}GqoQhFw#QoY3|LO*vT|h5<-#)}< zdojMc@cION^=!4lbf>0Lq91+>1I`^fFykorTZP!iN%Y@2(0>DRes6yqJGUu)kzU0dct6yaZX*_P6Et44T}W3K%%+Q2FFZeUDxJrD`sYliv(V3d^Wjh9 z^9HP`6r(@0;KQVV#yy~)$3FW$(*Can{jK;e5QxDTsD__-3NqOVdYNWMCqC<9*&nM* zl{WLQ{1&>Uzdd&#Wqvkdj5XX=r&V;8{lCaSdMz&v^Ikc<3p?<&UE%Zs^!@p%lc^nX zvMTgX9_AkGL!dp}pFkYIeY+R7Y&!gz0?2zM=7SdK!fxaVoWi`-f#20?YG9sJMciu$ zbl(ul!fTfQDuCAkf)Mxd!F>+1ud@R7=py*!7(<;H3*FGM-H1`-!B)Rka2&4KZ!cBr z99QRH&9e@=>!jlfx&j^lMnw+2m7hkh`fa337{fJacOvw!JLdHTu;r$~u9=KAy$Qg0 z*tH0{&?LOJ!gtp2Z{}dlb20SQa@hInS?{AyIgZW#Ya7rG-qb_i6=Tfjs;W@|Xs-m? zK)=6|0yz&EMBDJ2bo6(-y)B(xV@GFKE~Zn<7EsX`9qI}XWxxNql>U@`>#|1cPy>A5 z8_;o&Dv#3xtb6q%_RRge8gxtsy-cemFcY-R0~X-(g#goO3#@>Bvl>_ftOeEqE`Td! z+zq_*M85{HjSoMr2=S{%pc$`gAuAQ2TS7l{;hu@(A2?`ge2c^*@u`Y#p zT0U&wjv&9(=R)|vO>UQ#1ZHBcy#$~4b@({9RxCywN`scl$P$7oG#P!$^xA>Ol>qZ& z4d5_U0X-?8`zXdnCFH6J zIDxTLkNL3yvU5Hp*eBI*>*T%mtBaz|&ED9pJMz;k6XW+Q7u%fZiU{R6*K;kG(hkSg zESXF9_C(Wp$qqfc1<4dOZec_5$5onP%iNNN83^9uSa# zKHmphkaJ^L{0_H`D9}xDUVs^(O9Xzz6c}hd$rN z_6=)_{qgsCo6~ktV9f>67yjhKFbB|CE!al>?EfDrl0S@ z=S}0!-S1S;)`E7#(uxt&_5xkY<>V!FJL5Ie%`|TSHV)Kmhw*Es-CIIC?0U>++qus{ zdm`xNK0gGx&w&2O0qq5#v&;bV2G(}!#+g!snF-do^r;qhUfC#J%E8=FiC9LBqC8!7 zbv^cT?S0u`N$0{F+@DjVjR^YU#c0lU@P(qI$$GpT1}*GTQV1fOxdj$=1c+Bt@UJ*E=cci`IH zpno6hIOw*cknXS@=)nQjDap=3fc;j6B##kv z?*|USR?UQ-D+Il@@B7XonBnwrCc0A)asse&L0n&2$ZP--K;_Ga`VlY;dNt&;^~4 zm1@ib`3iE>zRafglh^NZ%=bT1?i}5(c6z;2QxW{?WQ=b~Un7Rcv`cvMH2niQg6Yq| z9MAOEK$o?zTtb}~+nu1h1NpK&$d}~4zr^_zp#K)=zZKz6SKZfAAAGwy*n-8d8`|c~ zXuNau0Iy^H$IIo&V81#OgZGcZ_TCM9e>>KEBQWMUhRLxjmVup5(VqqS3ow7y!9VS= zTSQ&<%iy;yp)SOOPC*vVbG$Ivhi*m%(F=$lUiaTfU6>0>;p5bp7`}Ht$k*#XPV^5N z@WzRnVb^0L;u8$3_OLH}V7KV`ti&&S+XXKFwvZJ^U2 z1KrCOQa5zKS;Rsvc)Qbi#KbvP)`I!JQdf&=%#GhT?XxlJVN*4)^ZeJA_xih)U)UdS zchT3gu+d`NqtcPu-{rt(JqSIqA2G=9!kaOl*CB6*ZMz!e6x3oa ztTq_^ZOwR-2OSQ}bFb}A+N7Hu%a?R_t+OvX7vvM$KXL2- zef&QT{Eq|wkR1HEU-~X_d8TedUgE5lpz$i%##&N9(Msh9X-?P+- zxL(S4uKV$RENbqT1k}txRNMiQe!~T0`Ta8%bNt*A@B(CnKK>UX(L_=`@Be--_vYum zd*1DM*86dr7@T9neiz$hyqALg5GgpPj6dV=_?lmpUxnX2k0Na^w}IQtZPWlp0HXi{ zzzjgxUa~iT{J?8d)cOGDl5vh8=f*NkoMXiI`gas=J3otUK+bO)32?hOXO;Jt+X40f zmOUhUoi?CmxC85eHNa9}F2MP2Oe@pEJYZh%z4;mcio*A0UU3Ybc{mAJ2ylD106W!X zWioZ;WUGu6}RoTEC$?wXhTJXx|M3G_x*-zew3uG_3dHg792s`HdRxd_VYeg_;(2$ z1A(uHz1v@JP*nVIk%GcqZ8^C*{5}~72AqJY0QV>Ng|r`@7cI*2 zk$1rPB6+-@8nM%(h#wz99DNV^AQtWCxPx^6uyo&CK0Yr*yb|lIzr%e~0hTKsAKb^! zOP+XKab7X=CUlL4+U*ALyBuvUvz><=4;!jMyrU91)BG9Eu%j~UAIyaxd<1cU6y$*= zDJWteFz0&>lH@*d{Dk94dmvY(h#j?I&3C4P{59M^2Z#lD{7dDDbuah-uPMxXCBOi% zABA%pj=>kNoQZwC$jPWfT&fXq=mx}Rnh>*VL@YW3xeKAlS=ns6h}^M9!(o~wtXO zl;h$`>C0BoUWYZb$k`{R<5_L8S>0IkK|k9FYZ zRwBrTmTuW#-29LKZpm)$Bd>{%p(nm-5thz zTV>_9(8xx#H3Q&vdDi3O0oJih!$0kZHQHM1^AH=YMLf7WaEoL=?LFktA2^yrE3ik# z4e}cZxe3M|vT)|VD%PLpC(+VsBDXVd(4yiO$i3(u?X7v0!nfl$jt;aAypKnGn)Amh z(f$^!9UaA5V>#AY`HYro@R*S5ShhWQK7A${c36zxoXhz^ z%NEmVjM-O_7kck(H%0DDpykNjafS?gfDYad$onC~kW1n>Vk9}(?x$5rZ_@0Xk7#P* zB?{OOPoW!(S5a z!9y?J)5YyaU&QH;M4lqfZkT9C0jr|PZ;B&Dj;|+75tX> zE*?idPZH*CPpk#*L_9nn_S9Ld1>D%=g8e@_G*walJle|kMkv62FcBCIuwME}IV!WW z4bDM+S_^U$FJbIHtj?!TZ=IuN1U^LLG^oa}BtO^pwaVO_G%W){7a6v?^7G)_ju<9ic; z+ddj#|49k>$@cf{-n}mec~^*MOZG)QsxPMBU+SYr*U!>U$mdM7zbz~KdvCnZ#f75K z4@b}kS^5UZrP8DZLnCS)HHMC3?(l^iZozN1^Be&F=i@AaUdYdK73B>02y@UDmJO?M zD$4r~K{gxFS1-ne&=u#EQ>KiuW2w*#d)J1Kpq@d<&0S$jiP+2I z3H{=O_Ol(t?LUtBi`&0+kV-h(!u}E4Z@OyoauXvohd!vm8sAmy)wqMbpGi8}ugJ^G zv!B57&UElx#=QR-`Cn39g8a8r$hp6beJQ*r`IB=!^zq3CdjCu-oj{JRgU)brWH}l) zfp{;{evFCZ+B#IDqf4E5-8gq9?cWngTV_q6jksVHk?LV-Sf?)fx z+-!jjg!9F|Z$IxJ?}m(F9^Cz;NfLRGybLrnDB-=8eVF@S2=S&0bK|dk%*@!9c;=FC zZFROBdjtN~e(?W%4}H*Ck39i<=x%@)-Hnf?TTSKEQ(r)p*ehI!Il3?{fpRkT(7`Yt z?0+_*ZD_k6bSCGK_zkq5bD(+ucMEiAo{4ex9BnPu=iisKSu<0Mp@+KQFI~Zz43(xv ze`&X0&GCX~E+q@*UYGFS-C4r_x0_1o<8#>4)Lw)3Cqph-zpbFNwhQPK_P%#`xl`lD z^;CkrYgw=ZQqb;QKsaQb^FDYFk97YQ+i;x6+X5Y$&$frI&Yx12EW%Hol&s};*~j6> zwZV40fbm1KL+P%(;eg}K7y=#bcXljl+$b2lW;fK z8|&%LbO!mc?eHTjM`=?5+LSA=Kv~GwJ)}Gcw&ozox;5MW?89))>-+2zbN=-S?7hh4 z945>s^{^p6ZD}@T3Q9M5wj9DbXA^uQ&gCu{t@~w_n~T)|dH=L}q3y)bbxA$JpFE;LC?Y zuS$Jk_F>q5$VB^_F$WYv*QX$dt_r#cdE{DH!E|nAFh(#uF9bY@B!{3_n-55&aGQb-D{RnEA)E< zWQTJ~OXp6bT+Sm#u45AR7e^ykg!h23|H3f|$@w49KaI#4FGBnGqy4SOjqDj`@>z$g z^U)|HgSV1Lj-X!n){UU6YTlYSydu;sQ|hs4Rj=7zhNxe83VhC_pWmL zdGAsq=qg0MV;o{HEy(BV<$W92pTqkW&Q2Lmy&R(%qC!1U5mFudOf>ZDjx*1-nDA9S zo_~h-B_n_2m9#zBi<(LAq95Kqo=UIpi=ziIA#~r*lkTi{pxem3xe8nR65 z-QA1VO^~a6&a=Zfdwae?78 zHGJTr-uPXXd6pJ`X+$oNWd6dw!guS7=(DQh^ay(lE+ey=&AYU^QbLdLwMJNMF zp12umGx)Y}jwCtbycb|P^!(vW0LLKefO0j}$4<(M zl6gD<*EArPR#DH;8h4_m(x zXa*g1(6jAhMnB5l4;x*a;yc4b*hc=v`3Tz&O=XvY#l(37U!TJgUx*$anc+h z5BcYHOao}_(bIXSEiBZS8`+hSuG76I*`VFmhi%MXUAngU2cN^dnuq7kLc8Zf9vsnL z&aHL@IFDSKU(Gr6-T>#4hk|!8&@%~W_df7F4K?SG7r-B3AD46H_)L^i(2@(CRDgj%QFTnqq=hkN->Riy)utq#{7kmxQ1(xh}K#f>9Z3H+sm~+9o-Xdu`@?{|_JJ4p% zg_iIfbR0w972-Y>u!HKMN1G;&m+Wb)$GlJsdX9rXO?tY2y6)~_^DOOp)@#nWxkThb zSA?RCY-@2WoO78uhn;hI8Pc5Q0G?Z+Poly5M6{jH8{o4|kKz280{F#c@Ez-L7HBi} zcC{hidvb~ebs=V5J>HB`ac%iXoj;%T@UVT>wmr*r_frq7&&OO74E}T5lUZ-0osr-* z+hV=|)5H15oP*E#xN(sCec)#%a*vNem*+um78@B*jrA02VHd%5Oxx`JvNMPz{WTS{&!#;6kx1Wn;AZO`$G5Vryl!UUtZl2;#i|U=F>#b5P>|# zNaS>~JTd*`(7!W9fGbJJWk!XJs=1^{b9{Asg z{PP~zqCK$PdXS5H9=_8xoac8VY%5(r44C&ERF56?(J4>Y)Sfjf*dPD5m6wjB%)K1o zomyu#>6KK>y$IM47Ji6n+7BE&Y>j|CRr7;J=CkMDd7WVgP<2lq5A`b6h`0D-%$EJ5X~v zk~-c?>o4$L3GcahxtW#kAIS6G3p=S=NFu| z#ouxHam_(RePAIVBY7o6q6Xglf3I*{R~6tmi!Lw<7&B1opk}IA2g(A^vkb<~_*s^~ zQotPu0=7fEc31Wxz;-8}xyfe^!FGOcxU5V$e!B&j3~--;Rllh4Zx)y+ zDOBd;oQfvcbhXF{sa`yn@OKO)F}w`;273{g*a_b+41NdO!E8Skz}|&z|E->^EU$HQ z|11P}J?WS92lIXFPF?LkHXzBe1x2AOfKSGb=X6F($9;|Zu6xytdo0e z*g)=c=TJD#Og`kfk&-rgk{j|eY;59eL z_*7}=gJ$e!nWe1s0Dq6-J`6!_M+p!H%msLTQWp5hVymXMw*hBFbi=;CSCU1US()T+ zU_gO*b_j9`cH+F>O}1NUiE9d_?<%E|z#v+_XaV^n_L2g>htGaaLrmou{No(JU3JJu zXh%C9m;kH>SiX6!{U4TXWAxH$v6t=wVt_AqHBo3#h-AOMAAHsj>@^A+u1CuvFVMo4 zKa)-2Biec3BsscnCHKKfv=6p(J!0Qwh=Cl1&y|P#r3>KI;gQva!E#3FONM=aFy2T6Q@4Aqnf32XIDlp3!JZ2fveWZjUdXACK|K=TFq& z^~6Cc?Gu$0&$2Ik8UETu?Bkm7L>?F6xs!mQz>mgelc#%iE#lmF4<*nSS8-NqRX#1i z^Uu}P(w{#2?8!Os$PGwGe^f&j>aC_wG}gqu@$5MG?~Qmq;yl;D+2y$ZqSb>{PB&vb zy%ym|!CJ$+@foZJ$$BTp(0)w+;)UHOpl|LU*@Jb>PWtd_A0=&arjY3~=*8AH%9%4) zvYu9jwZLwiVVoPVi8f=rY(*P+UtD9VI+K)JCApDp_tgC0^EX1n0v#|c_ML{?d zkJljmKtDgflJkFt4K3vda2cnqWt68i;_-EyH`8u2@0+>9hf88|Prm)}|3%hQ?zVsb ze5`9VmC-BPvDXl56+H*ysTw+=ctdvnBnYI$Ogu~KgJ&GAdbJ5jnsK@k&gCC zzI&M6QjLN!dVe?#o_5Tg{!N*U&G;Wb^~opS5y_X%nehmJM;7!aV_mA9-ov`iz3l;X znSIasGZ4QWhxpM*N(a43cs6oLCHu*FFEy{f79dty1|4)5@yXNiyH@mfw5g|I&gj5d z91Rv`-!!&g!~{JeAAXd)NcM)FXz%d7`<9 zwedL|d=^;>^;{hY1X%U3gT-1`>_^I7ixVJUZ9 zqn$g!^s6q+JA7W!+c+ofQC=#&g7cGKK(5af=-V^!y*r?r8~D6FjMD?gV`>7tJvT zJinOvk9p|`&J4ic&!r}F<3HC!{#&u`)3n0wXJb0uF*`;TO`ZIgF07s1-M5oIYAm9U zac=c%Sj)M#9%tm?Oq=#uI4ceQb31f&CwSTh*~dOcNo3+55|0mCgZxbkttS5U3Uto<8Ob;k&5=@&ui$}m3}Ao}CJ>qp*Z`|B z|MU4Uv4}_Jqkrq68_Th7R|5JgAOq{MPPZHD0xh$wuupUxop4)M@Keu~ett1MeQF!d zLcEW-(k`4MVvXlm0`rltxfC+K9QxG(I^GS>^}^bwKd=q)@K`*X&uOSY{JROf@6guz zp_cyFv6DEDe&()`6BA1-SnUR55+kgRu=gEH`*Y?D7`HT>M^m8Qi zdIHYJIEZH*1MS6_Ys#_C$1&kD$X(}1?XUW_Y=$@U%gWh}?)ID);|qE@mda?Qu|~(|NA@9}EZO_7t@YiF_}zxT z?CC;$eC>i_(~M~^go5`wv2MVzNsjArZU@ID6EW7)pjRqpPNP~rt8(rPobS6Hal9b9 zfqnTskoR23ef#R=KReETu3fL!mY9|pjJY3+HiQG5*TcGn&kr~Zo)kgOPJ-Sp=)+#* z3tinFNOuyV=?d11>(Tev1AhMP^Ie>a_p8h0Aa9McUhXM4N9LnAj58!@5u6L!ha9^i z(0>wtx2kIi)<` E52uwf9{>OV literal 0 HcmV?d00001 diff --git a/engines/ags/engine/resource/resource.h b/engines/ags/engine/resource/resource.h new file mode 100644 index 000000000000..bfacb7632ecc --- /dev/null +++ b/engines/ags/engine/resource/resource.h @@ -0,0 +1,46 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by version.rc +// +#define IDOKRUN 3 +#define IDI_ICON 101 +#define IDD_SETUP 102 +#define IDC_DIGISOUND 1003 +#define IDC_MIDIMUSIC 1006 +#define IDC_WINDOWED 1007 +#define IDC_VERSION 1008 +#define IDC_LANGUAGE 1009 +#define IDC_SPRITECACHE 1010 +#define IDC_RENDERATSCREENRES 1011 +#define IDC_ADVANCED 1012 +#define IDC_VOICEPACK 1016 +#define IDC_REFRESH_85HZ 1017 +#define IDC_THREADEDAUDIO 1018 +#define IDC_ANTIALIAS 1021 +#define IDC_REDUCE32TO16 1022 +#define IDC_GFXFILTER 1023 +#define IDC_GFXDRIVER 1024 +#define IDC_RESOLUTION 1025 +#define IDC_GFXMODE 1028 +#define IDC_GFXMODETEXT 1029 +#define IDC_VSYNC 1031 +#define IDC_FSSCALING 1033 +#define IDC_WINDOWSCALING 1034 +#define IDC_GFXOPTIONS 1035 +#define IDC_MOUSESPEED 1036 +#define IDC_MOUSESPEED_TEXT 1037 +#define IDC_MOUSE_AUTOLOCK 1038 +#define IDC_CUSTOMSAVEDIRCHECK 1039 +#define IDC_CUSTOMSAVEDIR 1040 +#define IDC_CUSTOMSAVEDIRBTN 1041 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 109 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1039 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/engines/ags/engine/resource/tintshader.fx b/engines/ags/engine/resource/tintshader.fx new file mode 100644 index 000000000000..90ad5000a03f --- /dev/null +++ b/engines/ags/engine/resource/tintshader.fx @@ -0,0 +1,53 @@ + +float GetLuminance(float4 color) +{ + float colorMax = max (color[0], color[1]); + colorMax = max (colorMax, color[2]); + + return colorMax; +} + + +// Pixel shader input structure +struct PS_INPUT +{ + float2 Texture : TEXCOORD0; +}; + +// Pixel shader output structure +struct PS_OUTPUT +{ + float4 Color : COLOR0; +}; + +// Global variables +sampler2D Tex0; + +// tintHSV: parameters from AGS engine +// [0] = tint colour R +// [1] = tint colour G +// [2] = tint colour B +// [3] = tint saturation +const float4 tintRGB: register( c0 ); +// [0] = object transparency +// [1] = light level +const float4 transparency: register( c1 ); + +// Name: Simple Pixel Shader +// Type: Pixel shader +// Desc: Fetch texture and blend with constant color +// +PS_OUTPUT main( in PS_INPUT In ) +{ + PS_OUTPUT Out; //create an output pixel + + float amount = tintRGB[3]; + float4 pixel = tex2D(Tex0, In.Texture); // tint should be the RGB conversion of the HSL value, with 100% L + float lum = GetLuminance(pixel); + + // scale the colour by the luma, alpha blend it with the tint + Out.Color = (tintRGB * lum * amount + pixel*(1-amount)) * transparency[1]; + Out.Color[3] = pixel[3] * transparency[0]; + + return Out; //return output pixel +} diff --git a/engines/ags/engine/resource/tintshader.fxo b/engines/ags/engine/resource/tintshader.fxo new file mode 100644 index 0000000000000000000000000000000000000000..20667ce81a63fc25312a686b3a48ee80799d5356 GIT binary patch literal 524 zcmZWlF;2rk5ZpT(B?VGGK;aS^D-lGIE5M0FML~$AbioQnSOVL!U4-uF_y8S+>$u4e z_>8{+$E?ppNUSuz-Pze$-`PUzZ#|~z;?h4Nq7T3ZXW`_U1kpQ=CBPg?x&t^eKmr2a z4HJkrK!W+pEuzhk>bkb+u1^paw~yg{lsnV(Ig6i=c?94U&bB+$C-c^S{@iaB z14Y#A%)R=^2?$>K{(|~SkpATqYvi8W?llq`quZ*3PD7+C@D=I{LA|cuRD5T=7d&}} zbE$a#OPja0;Ez3BkMn?Q;=Qc1j3<~LJeroXQE@F$^Iqn8FJT6H_Tv9Qm>EGqrLpe^ DySQMZ literal 0 HcmV?d00001 diff --git a/engines/ags/engine/resource/tintshaderLegacy.fx b/engines/ags/engine/resource/tintshaderLegacy.fx new file mode 100644 index 000000000000..82f89077c3f2 --- /dev/null +++ b/engines/ags/engine/resource/tintshaderLegacy.fx @@ -0,0 +1,72 @@ + +float GetValue(float4 color) +{ + float colorMax = max (color[0], color[1]); + colorMax = max (colorMax, color[2]); + + return colorMax; +} + +float4 hsv_to_rgb(float3 HSV) +{ + float4 RGB = HSV.z; + if ( HSV.y != 0 ) { + float var_h = HSV.x * 6; + float var_i = floor(var_h); // Or ... var_i = floor( var_h ) + float var_1 = HSV.z * (1.0 - HSV.y); + float var_2 = HSV.z * (1.0 - HSV.y * (var_h-var_i)); + float var_3 = HSV.z * (1.0 - HSV.y * (1-(var_h-var_i))); + if (var_i < 1.0) { RGB = float4(HSV.z, var_3, var_1, 1.0); } + else if (var_i < 2.0) { RGB = float4(var_2, HSV.z, var_1, 1.0); } + else if (var_i < 3.0) { RGB = float4(var_1, HSV.z, var_3, 1.0); } + else if (var_i < 4.0) { RGB = float4(var_1, var_2, HSV.z, 1.0); } + else if (var_i < 5.0) { RGB = float4(var_3, var_1, HSV.z, 1.0); } + else { RGB = float4(HSV.z, var_1, var_2, 1.0); } + } + return (RGB); +} + +// Pixel shader input structure +struct PS_INPUT +{ + float2 Texture : TEXCOORD0; +}; + +// Pixel shader output structure +struct PS_OUTPUT +{ + float4 Color : COLOR0; +}; + +// Global variables +sampler2D Tex0; + +// tintHSV: parameters from AGS engine +// [0] = tint colour H +// [1] = tint colour S +// [2] = tint colour V +// [3] = tint saturation +const float4 tintHSV: register( c0 ); +// [0] = object transparency +// [1] = light level +const float4 transparency: register( c1 ); + +// Name: Simple Pixel Shader +// Type: Pixel shader +// Desc: Fetch texture and blend with constant color +// +PS_OUTPUT main( in PS_INPUT In ) +{ + PS_OUTPUT Out; //create an output pixel + + float amount = tintHSV[3]; + float4 pixel = tex2D(Tex0, In.Texture); + float lum = GetValue(pixel); + lum = max(lum - (1.0 - transparency[1]), 0.0); + + // scale the colour by the luma, alpha blend it with the tint + Out.Color = (hsv_to_rgb(float3(tintHSV[0],tintHSV[1],lum)) * amount + pixel*(1-amount)); + Out.Color[3] = pixel[3] * transparency[0]; + + return Out; //return output pixel +} diff --git a/engines/ags/engine/resource/tintshaderLegacy.fxo b/engines/ags/engine/resource/tintshaderLegacy.fxo new file mode 100644 index 0000000000000000000000000000000000000000..cf4cd7392c1ff7e24f5e3f2e2af4acc37627c28c GIT binary patch literal 892 zcmZWnJx>Bb5Pi3MD2XN{+L}nI4MB}DRDNJ#W8udcJ0*&dM1cT>c1vezV`s6p(D)Ce zwe>gL@9=yxt72rsusd(wyq%dnm@NCu)=@p)-dO$csv;h|DmSubsDR7zzoUU&fH3<@4_ zn^bndXp7sM;8t;rfGwJ%`O#u%$FbAb@AD(_1;0ZeLVr!lbN`<#v??>GnA zz|X5jp0Uiu0Dt2cvA$sDAI4m370dcOt9~3fUSc_(W9mgnUS{Y|(Ps_fJMo1(rSXB( zp?*&93N-}n#93mZFF7nzH4PF!t|?)D;7DJV9Okf>#DzX1J(HvNggz404Dom(E_0xU z_QY4#xXjN&xC6)Uiu0J3d+EQE`~IsPatHn|#~>x|;~yuP;MfTcyv#=4Lv(rHL=NBc yx1PXBSx@@iyW}Na?57@b`Z61-X-?mITC{mj%C{NkMZAwa>kRlkk(0VC1HJ&sI;+ +#define IDC_STATIC -1 +#include "../../Common/core/def_version.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United Kingdom) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// DATA +// + +__GDF_XML DATA "DefaultGDF.gdf.xml" + +PIXEL_SHADER DATA "tintshader.fxo" + +PIXEL_SHADER_LEGACY DATA "tintshaderLegacy.fxo" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION ACI_VERSION_MSRC_DEF + PRODUCTVERSION ACI_VERSION_MSRC_DEF + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "Comments", "This game was created using AGS - http://www.adventuregamestudio.co.uk/" + VALUE "CompanyName", "AGS Engine by Chris Jones et al. " + VALUE "FileDescription", "Adventure Game Studio run-time engine " + VALUE "FileVersion", ACI_VERSION_STR + VALUE "InternalName", "acwin" + VALUE "LegalCopyright", "AGS Copyright (c) 1999-2010 Chris Jones and " ACI_COPYRIGHT_YEARS " others." + VALUE "OriginalFilename", "acwin.exe" + VALUE "ProductName", "Made with Adventure Game Studio" + VALUE "ProductVersion", ACI_VERSION_STR + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include \r\n" + "#define IDC_STATIC -1\r\n" + "#include ""../../Common/core/def_version.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON ICON "game-1.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_SETUP DIALOGEX 0, 0, 518, 295 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "AGS Game Settings" +FONT 8, "Tahoma", 400, 0, 0x0 +BEGIN + GROUPBOX "Graphics settings",IDC_GFXOPTIONS,7,7,247,131 + CONTROL "Game resolution: XXXX x XXXX",IDC_RESOLUTION,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,15,19,161,10 + CONTROL "Driver:",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,14,34,35,10 + COMBOBOX IDC_GFXDRIVER,50,32,136,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "&Start in a windowed mode",IDC_WINDOWED,"Button",BS_AUTOCHECKBOX | BS_LEFT | BS_VCENTER | WS_TABSTOP,14,49,172,9 + CONTROL "Mode:",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,14,66,21,8 + LTEXT "",IDC_GFXMODETEXT,50,66,135,8 + CONTROL "Fullscreen scale:",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,14,84,56,10 + COMBOBOX IDC_FSSCALING,75,82,166,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Windowed scale:",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,14,101,54,10 + COMBOBOX IDC_WINDOWSCALING,75,99,166,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Scaling method:",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,14,118,56,10 + COMBOBOX IDC_GFXFILTER,75,116,166,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Gameplay settings",IDC_STATIC,7,141,247,33 + CONTROL "Game language:",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,15,155,56,10 + COMBOBOX IDC_LANGUAGE,71,153,170,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CTEXT "Static",IDC_VERSION,7,190,247,9 + DEFPUSHBUTTON "S&ave",IDOK,7,207,56,14 + PUSHBUTTON "&Save and Run",IDOKRUN,67,207,56,14 + PUSHBUTTON "Cancel",IDCANCEL,127,207,56,14 + PUSHBUTTON "Ad&vanced >>>",IDC_ADVANCED,188,207,67,14 + GROUPBOX "Graphics options",IDC_STATIC,264,7,247,69 + CONTROL "Vertical sync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,271,20,135,9 + CONTROL "Use 85 Hz display (CRT monitors only)",IDC_REFRESH_85HZ, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,271,33,138,9 + CONTROL "Smooth scaled sprites",IDC_ANTIALIAS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,271,46,138,9 + CONTROL "Render sprites at screen resolution",IDC_RENDERATSCREENRES, + "Button",BS_AUTOCHECKBOX | BS_LEFT | BS_VCENTER | WS_TABSTOP,271,59,172,9 + GROUPBOX "Sound options",IDC_STATIC,264,79,247,76 + LTEXT "Digital Sound:",IDC_STATIC,271,94,46,9 + COMBOBOX IDC_DIGISOUND,320,92,176,70,CBS_DROPDOWNLIST | WS_GROUP | WS_TABSTOP + LTEXT "MIDI music:",IDC_STATIC,271,110,47,10 + COMBOBOX IDC_MIDIMUSIC,320,108,176,70,CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "Enable threaded audio",IDC_THREADEDAUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,271,126,160,9 + CONTROL "Use voice pack if available",IDC_VOICEPACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,271,140,160,9 + GROUPBOX "Mouse options",IDC_STATIC,264,158,247,58 + CONTROL "Auto lock to window",IDC_MOUSE_AUTOLOCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,271,173,80,10 + LTEXT "Cursor speed: Default",IDC_MOUSESPEED_TEXT,271,187,176,8 + CONTROL "",IDC_MOUSESPEED,"msctls_trackbar32",WS_TABSTOP,271,198,226,14 + GROUPBOX "Sprite cache",IDC_STATIC,264,219,247,33 + CONTROL "Maximum size:",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,271,233,50,10 + COMBOBOX IDC_SPRITECACHE,325,231,118,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "",IDC_STATIC,264,250,247,36 + CONTROL "Custom game saves path",IDC_CUSTOMSAVEDIRCHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,271,256,165,10,WS_EX_TRANSPARENT + EDITTEXT IDC_CUSTOMSAVEDIR,271,269,202,14,ES_AUTOHSCROLL | ES_READONLY + PUSHBUTTON "...",IDC_CUSTOMSAVEDIRBTN,477,269,20,14 + COMBOBOX IDC_GFXMODE,50,64,191,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_SETUP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 511 + VERTGUIDE, 254 + VERTGUIDE, 264 + TOPMARGIN, 7 + BOTTOMMARGIN, 288 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +IDD_SETUP AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +#endif // English (United Kingdom) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/engines/ags/engine/script/cc_error_engine.cpp b/engines/ags/engine/script/cc_error_engine.cpp new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp new file mode 100644 index 000000000000..affee68e773a --- /dev/null +++ b/engines/ags/engine/script/cc_instance.cpp @@ -0,0 +1,2003 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "ac/common.h" +#include "ac/dynobj/cc_dynamicarray.h" +#include "ac/dynobj/managedobjectpool.h" +#include "gui/guidefines.h" +#include "script/cc_error.h" +#include "script/cc_instance.h" +#include "debug/debug_log.h" +#include "debug/out.h" +#include "script/cc_options.h" +#include "script/script.h" +#include "script/script_runtime.h" +#include "script/systemimports.h" +#include "util/bbop.h" +#include "util/stream.h" +#include "util/misc.h" +#include "util/textstreamwriter.h" +#include "ac/dynobj/scriptstring.h" +#include "ac/dynobj/scriptuserobject.h" +#include "ac/statobj/agsstaticobject.h" +#include "ac/statobj/staticarray.h" +#include "ac/dynobj/cc_dynamicobject_addr_and_manager.h" +#include "util/memory.h" +#include "util/string_utils.h" // linux strnicmp definition + +using namespace AGS::Common; +using namespace AGS::Common::Memory; + +extern ccInstance *loadedInstances[MAX_LOADED_INSTANCES]; // in script/script_runtime +extern int gameHasBeenRestored; // in ac/game +extern ExecutingScript*curscript; // in script/script +extern int maxWhileLoops; +extern new_line_hook_type new_line_hook; + +extern ScriptString myScriptStringImpl; + +enum ScriptOpArgIsReg +{ + kScOpNoArgIsReg = 0, + kScOpArg1IsReg = 0x0001, + kScOpArg2IsReg = 0x0002, + kScOpArg3IsReg = 0x0004, + kScOpOneArgIsReg = kScOpArg1IsReg, + kScOpTwoArgsAreReg = kScOpArg1IsReg | kScOpArg2IsReg, + kScOpTreeArgsAreReg = kScOpArg1IsReg | kScOpArg2IsReg | kScOpArg3IsReg +}; + +struct ScriptCommandInfo +{ + ScriptCommandInfo(int32_t code, const char *cmdname, int arg_count, ScriptOpArgIsReg arg_is_reg) + { + Code = code; + CmdName = cmdname; + ArgCount = arg_count; + ArgIsReg[0] = (arg_is_reg & kScOpArg1IsReg) != 0; + ArgIsReg[1] = (arg_is_reg & kScOpArg2IsReg) != 0; + ArgIsReg[2] = (arg_is_reg & kScOpArg3IsReg) != 0; + } + + int32_t Code; + const char *CmdName; + int ArgCount; + bool ArgIsReg[3]; +}; + +const ScriptCommandInfo sccmd_info[CC_NUM_SCCMDS] = +{ + ScriptCommandInfo( 0 , "NULL" , 0, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_ADD , "addi" , 2, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_SUB , "subi" , 2, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_REGTOREG , "mov" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_WRITELIT , "memwritelit" , 2, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_RET , "ret" , 0, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_LITTOREG , "movl" , 2, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMREAD , "memread4" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMWRITE , "memwrite4" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MULREG , "mul" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_DIVREG , "div" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_ADDREG , "add" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_SUBREG , "sub" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_BITAND , "and" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_BITOR , "or" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_ISEQUAL , "cmpeq" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_NOTEQUAL , "cmpne" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_GREATER , "gt" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_LESSTHAN , "lt" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_GTE , "gte" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_LTE , "lte" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_AND , "land" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_OR , "lor" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_CALL , "call" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMREADB , "memread1" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMREADW , "memread2" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMWRITEB , "memwrite1" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMWRITEW , "memwrite2" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_JZ , "jzi" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_PUSHREG , "push" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_POPREG , "pop" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_JMP , "jmpi" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_MUL , "muli" , 2, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_CALLEXT , "farcall" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_PUSHREAL , "farpush" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_SUBREALSTACK , "farsubsp" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_LINENUM , "sourceline" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_CALLAS , "callscr" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_THISBASE , "thisaddr" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_NUMFUNCARGS , "setfuncargs" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_MODREG , "mod" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_XORREG , "xor" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_NOTREG , "not" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_SHIFTLEFT , "shl" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_SHIFTRIGHT , "shr" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_CALLOBJ , "callobj" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_CHECKBOUNDS , "checkbounds" , 2, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMWRITEPTR , "memwrite.ptr" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMREADPTR , "memread.ptr" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_MEMZEROPTR , "memwrite.ptr.0" , 0, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_MEMINITPTR , "meminit.ptr" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_LOADSPOFFS , "load.sp.offs" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_CHECKNULL , "checknull.ptr" , 0, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_FADD , "faddi" , 2, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_FSUB , "fsubi" , 2, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_FMULREG , "fmul" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_FDIVREG , "fdiv" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_FADDREG , "fadd" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_FSUBREG , "fsub" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_FGREATER , "fgt" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_FLESSTHAN , "flt" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_FGTE , "fgte" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_FLTE , "flte" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_ZEROMEMORY , "zeromem" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_CREATESTRING , "newstring" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_STRINGSEQUAL , "streq" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_STRINGSNOTEQ , "strne" , 2, kScOpTwoArgsAreReg ), + ScriptCommandInfo( SCMD_CHECKNULLREG , "checknull" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_LOOPCHECKOFF , "loopcheckoff" , 0, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_MEMZEROPTRND , "memwrite.ptr.0.nd" , 0, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_JNZ , "jnzi" , 1, kScOpNoArgIsReg ), + ScriptCommandInfo( SCMD_DYNAMICBOUNDS , "dynamicbounds" , 1, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_NEWARRAY , "newarray" , 3, kScOpOneArgIsReg ), + ScriptCommandInfo( SCMD_NEWUSEROBJECT , "newuserobject" , 2, kScOpOneArgIsReg ), +}; + +const char *regnames[] = { "null", "sp", "mar", "ax", "bx", "cx", "op", "dx" }; + +const char *fixupnames[] = { "null", "fix_gldata", "fix_func", "fix_string", "fix_import", "fix_datadata", "fix_stack" }; + +ccInstance *current_instance; +// [IKM] 2012-10-21: +// NOTE: This is temporary solution (*sigh*, one of many) which allows certain +// exported functions return value as a RuntimeScriptValue object; +// Of 2012-12-20: now used only for plugin exports +RuntimeScriptValue GlobalReturnValue; + +// Function call stack is used to temporarily store +// values before passing them to script function +#define MAX_FUNC_PARAMS 20 +// An inverted parameter stack +struct FunctionCallStack +{ + FunctionCallStack() + { + Head = MAX_FUNC_PARAMS - 1; + Count = 0; + } + + inline RuntimeScriptValue *GetHead() + { + return &Entries[Head]; + } + inline RuntimeScriptValue *GetTail() + { + return &Entries[Head + Count]; + } + + RuntimeScriptValue Entries[MAX_FUNC_PARAMS + 1]; + int Head; + int Count; +}; + + +ccInstance *ccInstance::GetCurrentInstance() +{ + return current_instance; +} + +ccInstance *ccInstance::CreateFromScript(PScript scri) +{ + return CreateEx(scri, nullptr); +} + +ccInstance *ccInstance::CreateEx(PScript scri, ccInstance * joined) +{ + // allocate and copy all the memory with data, code and strings across + ccInstance *cinst = new ccInstance(); + if (!cinst->_Create(scri, joined)) + { + delete cinst; + return nullptr; + } + + return cinst; +} + +ccInstance::ccInstance() +{ + flags = 0; + globaldata = nullptr; + globaldatasize = 0; + code = nullptr; + runningInst = nullptr; + codesize = 0; + strings = nullptr; + stringssize = 0; + exports = nullptr; + stack = nullptr; + num_stackentries = 0; + stackdata = nullptr; + stackdatasize = 0; + stackdata_ptr = nullptr; + pc = 0; + line_number = 0; + callStackSize = 0; + loadedInstanceId = 0; + returnValue = 0; + numimports = 0; + resolved_imports = nullptr; + code_fixups = nullptr; + + memset(callStackLineNumber, 0, sizeof(callStackLineNumber)); + memset(callStackAddr, 0, sizeof(callStackAddr)); + memset(callStackCodeInst, 0, sizeof(callStackCodeInst)); +} + +ccInstance::~ccInstance() +{ + Free(); +} + +ccInstance *ccInstance::Fork() +{ + return CreateEx(instanceof, this); +} + +void ccInstance::Abort() +{ + if ((this != nullptr) && (pc != 0)) + flags |= INSTF_ABORTED; +} + +void ccInstance::AbortAndDestroy() +{ + if (this != nullptr) { + Abort(); + flags |= INSTF_FREE; + } +} + +#define ASSERT_STACK_SPACE_AVAILABLE(N) \ + if (registers[SREG_SP].RValue + N - &stack[0] >= CC_STACK_SIZE) \ + { \ + cc_error("stack overflow"); \ + return -1; \ + } + +#define ASSERT_STACK_SIZE(N) \ + if (registers[SREG_SP].RValue - N < &stack[0]) \ + { \ + cc_error("stack underflow"); \ + return -1; \ + } + +int ccInstance::CallScriptFunction(const char *funcname, int32_t numargs, const RuntimeScriptValue *params) +{ + ccError = 0; + currentline = 0; + + if (numargs > 0 && !params) + { + cc_error("internal error in ccInstance::CallScriptFunction"); + return -1; // TODO: correct error value + } + + if ((numargs >= 20) || (numargs < 0)) { + cc_error("too many arguments to function"); + return -3; + } + + if (pc != 0) { + cc_error("instance already being executed"); + return -4; + } + + int32_t startat = -1; + int k; + char mangledName[200]; + sprintf(mangledName, "%s$", funcname); + + for (k = 0; k < instanceof->numexports; k++) { + char *thisExportName = instanceof->exports[k]; + int match = 0; + + // check for a mangled name match + if (strncmp(thisExportName, mangledName, strlen(mangledName)) == 0) { + // found, compare the number of parameters + char *numParams = thisExportName + strlen(mangledName); + if (atoi(numParams) != numargs) { + cc_error("wrong number of parameters to exported function '%s' (expected %d, supplied %d)", funcname, atoi(numParams), numargs); + return -1; + } + match = 1; + } + // check for an exact match (if the script was compiled with + // an older version) + if ((match == 1) || (strcmp(thisExportName, funcname) == 0)) { + int32_t etype = (instanceof->export_addr[k] >> 24L) & 0x000ff; + if (etype != EXPORT_FUNCTION) { + cc_error("symbol is not a function"); + return -1; + } + startat = (instanceof->export_addr[k] & 0x00ffffff); + break; + } + } + + if (startat < 0) { + cc_error("function '%s' not found", funcname); + return -2; + } + + //numargs++; // account for return address + flags &= ~INSTF_ABORTED; + + // object pointer needs to start zeroed + registers[SREG_OP].SetDynamicObject(nullptr, nullptr); + + ccInstance* currentInstanceWas = current_instance; + registers[SREG_SP].SetStackPtr( &stack[0] ); + stackdata_ptr = stackdata; + // NOTE: Pushing parameters to stack in reverse order + ASSERT_STACK_SPACE_AVAILABLE(numargs + 1 /* return address */) + for (int i = numargs - 1; i >= 0; --i) + { + PushValueToStack(params[i]); + } + PushValueToStack(RuntimeScriptValue().SetInt32(0)); // return address on stack + if (ccError) + { + return -1; + } + runningInst = this; + + int reterr = Run(startat); + ASSERT_STACK_SIZE(numargs); + PopValuesFromStack(numargs); + pc = 0; + current_instance = currentInstanceWas; + + // NOTE that if proper multithreading is added this will need + // to be reconsidered, since the GC could be run in the middle + // of a RET from a function or something where there is an + // object with ref count 0 that is in use + pool.RunGarbageCollectionIfAppropriate(); + + if (new_line_hook) + new_line_hook(nullptr, 0); + + if (reterr) + return -6; + + if (flags & INSTF_ABORTED) { + flags &= ~INSTF_ABORTED; + + if (flags & INSTF_FREE) + Free(); + return 100; + } + + if (registers[SREG_SP].RValue != &stack[0]) { + cc_error("stack pointer was not zero at completion of script"); + return -5; + } + return ccError; +} + +// Macros to maintain the call stack +#define PUSH_CALL_STACK \ + if (callStackSize >= MAX_CALL_STACK) { \ + cc_error("CallScriptFunction stack overflow (recursive call error?)"); \ + return -1; \ + } \ + callStackLineNumber[callStackSize] = line_number; \ + callStackCodeInst[callStackSize] = runningInst; \ + callStackAddr[callStackSize] = pc; \ + callStackSize++ + +#define POP_CALL_STACK \ + if (callStackSize < 1) { \ + cc_error("CallScriptFunction stack underflow -- internal error"); \ + return -1; \ + } \ + callStackSize--;\ + line_number = callStackLineNumber[callStackSize];\ + currentline = line_number + +#define MAXNEST 50 // number of recursive function calls allowed +int ccInstance::Run(int32_t curpc) +{ + pc = curpc; + returnValue = -1; + + if ((curpc < 0) || (curpc >= runningInst->codesize)) { + cc_error("specified code offset is not valid"); + return -1; + } + + int32_t thisbase[MAXNEST], funcstart[MAXNEST]; + int was_just_callas = -1; + int curnest = 0; + int loopIterations = 0; + int num_args_to_func = -1; + int next_call_needs_object = 0; + int loopIterationCheckDisabled = 0; + thisbase[0] = 0; + funcstart[0] = pc; + current_instance = this; + ccInstance *codeInst = runningInst; + int write_debug_dump = ccGetOption(SCOPT_DEBUGRUN); + ScriptOperation codeOp; + + FunctionCallStack func_callstack; + + while (1) { + + /* + if (!codeInst->ReadOperation(codeOp, pc)) + { + return -1; + } + */ + /* ReadOperation */ + //===================================================================== + codeOp.Instruction.Code = codeInst->code[pc]; + codeOp.Instruction.InstanceId = (codeOp.Instruction.Code >> INSTANCE_ID_SHIFT) & INSTANCE_ID_MASK; + codeOp.Instruction.Code &= INSTANCE_ID_REMOVEMASK; // now this is pure instruction code + + if (codeOp.Instruction.Code < 0 || codeOp.Instruction.Code >= CC_NUM_SCCMDS) + { + cc_error("invalid instruction %d found in code stream", codeOp.Instruction.Code); + return -1; + } + + codeOp.ArgCount = sccmd_info[codeOp.Instruction.Code].ArgCount; + if (pc + codeOp.ArgCount >= codeInst->codesize) + { + cc_error("unexpected end of code data (%d; %d)", pc + codeOp.ArgCount, codeInst->codesize); + return -1; + } + + int pc_at = pc + 1; + for (int i = 0; i < codeOp.ArgCount; ++i, ++pc_at) + { + char fixup = codeInst->code_fixups[pc_at]; + if (fixup > 0) + { + // could be relative pointer or import address + /* + if (!FixupArgument(code[pc], fixup, codeOp.Args[i])) + { + return -1; + } + */ + /* FixupArgument */ + //===================================================================== + switch (fixup) + { + case FIXUP_GLOBALDATA: + { + ScriptVariable *gl_var = (ScriptVariable*)codeInst->code[pc_at]; + codeOp.Args[i].SetGlobalVar(&gl_var->RValue); + } + break; + case FIXUP_FUNCTION: + // originally commented -- CHECKME: could this be used in very old versions of AGS? + // code[fixup] += (long)&code[0]; + // This is a program counter value, presumably will be used as SCMD_CALL argument + codeOp.Args[i].SetInt32((int32_t)codeInst->code[pc_at]); + break; + case FIXUP_STRING: + codeOp.Args[i].SetStringLiteral(&codeInst->strings[0] + codeInst->code[pc_at]); + break; + case FIXUP_IMPORT: + { + const ScriptImport *import = simp.getByIndex((int32_t)codeInst->code[pc_at]); + if (import) + { + codeOp.Args[i] = import->Value; + } + else + { + cc_error("cannot resolve import, key = %ld", codeInst->code[pc_at]); + return -1; + } + } + break; + case FIXUP_STACK: + codeOp.Args[i] = GetStackPtrOffsetFw((int32_t)codeInst->code[pc_at]); + break; + default: + cc_error("internal fixup type error: %d", fixup); + return -1; + } + /* End FixupArgument */ + //===================================================================== + } + else + { + // should be a numeric literal (int32 or float) + codeOp.Args[i].SetInt32( (int32_t)codeInst->code[pc_at] ); + } + } + /* End ReadOperation */ + //===================================================================== + + // save the arguments for quick access + RuntimeScriptValue &arg1 = codeOp.Args[0]; + RuntimeScriptValue &arg2 = codeOp.Args[1]; + RuntimeScriptValue &arg3 = codeOp.Args[2]; + RuntimeScriptValue ®1 = + registers[arg1.IValue >= 0 && arg1.IValue < CC_NUM_REGISTERS ? arg1.IValue : 0]; + RuntimeScriptValue ®2 = + registers[arg2.IValue >= 0 && arg2.IValue < CC_NUM_REGISTERS ? arg2.IValue : 0]; + + const char *direct_ptr1; + const char *direct_ptr2; + + if (write_debug_dump) + { + DumpInstruction(codeOp); + } + + switch (codeOp.Instruction.Code) { + case SCMD_LINENUM: + line_number = arg1.IValue; + currentline = arg1.IValue; + if (new_line_hook) + new_line_hook(this, currentline); + break; + case SCMD_ADD: + // If the the register is SREG_SP, we are allocating new variable on the stack + if (arg1.IValue == SREG_SP) + { + // Only allocate new data if current stack entry is invalid; + // in some cases this may be advancing over value that was written by MEMWRITE* + ASSERT_STACK_SPACE_AVAILABLE(1); + if (reg1.RValue->IsValid()) + { + // TODO: perhaps should add a flag here to ensure this happens only after MEMWRITE-ing to stack + registers[SREG_SP].RValue++; + } + else + { + PushDataToStack(arg2.IValue); + if (ccError) + { + return -1; + } + } + } + else + { + reg1.IValue += arg2.IValue; + } + break; + case SCMD_SUB: + if (reg1.Type == kScValStackPtr) + { + // If this is SREG_SP, this is stack pop, which frees local variables; + // Other than SREG_SP this may be AGS 2.x method to offset stack in SREG_MAR; + // quote JJS: + // // AGS 2.x games also perform relative stack access by copying SREG_SP to SREG_MAR + // // and then subtracting from that. + if (arg1.IValue == SREG_SP) + { + PopDataFromStack(arg2.IValue); + } + else + { + // This is practically LOADSPOFFS + reg1 = GetStackPtrOffsetRw(arg2.IValue); + } + if (ccError) + { + return -1; + } + } + else + { + reg1.IValue -= arg2.IValue; + } + break; + case SCMD_REGTOREG: + reg2 = reg1; + break; + case SCMD_WRITELIT: + // Take the data address from reg[MAR] and copy there arg1 bytes from arg2 address + // + // NOTE: since it reads directly from arg2 (which originally was + // long, or rather int32 due x32 build), written value may normally + // be only up to 4 bytes large; + // I guess that's an obsolete way to do WRITE, WRITEW and WRITEB + switch (arg1.IValue) + { + case sizeof(char): + registers[SREG_MAR].WriteByte(arg2.IValue); + break; + case sizeof(int16_t): + registers[SREG_MAR].WriteInt16(arg2.IValue); + break; + case sizeof(int32_t): + // We do not know if this is math integer or some pointer, etc + registers[SREG_MAR].WriteValue(arg2); + break; + default: + cc_error("unexpected data size for WRITELIT op: %d", arg1.IValue); + break; + } + break; + case SCMD_RET: + { + if (loopIterationCheckDisabled > 0) + loopIterationCheckDisabled--; + + ASSERT_STACK_SIZE(1); + RuntimeScriptValue rval = PopValueFromStack(); + curnest--; + pc = rval.IValue; + if (pc == 0) + { + returnValue = registers[SREG_AX].IValue; + return 0; + } + current_instance = this; + POP_CALL_STACK; + continue; // continue so that the PC doesn't get overwritten + } + case SCMD_LITTOREG: + reg1 = arg2; + break; + case SCMD_MEMREAD: + // Take the data address from reg[MAR] and copy int32_t to reg[arg1] + reg1 = registers[SREG_MAR].ReadValue(); + break; + case SCMD_MEMWRITE: + // Take the data address from reg[MAR] and copy there int32_t from reg[arg1] + registers[SREG_MAR].WriteValue(reg1); + break; + case SCMD_LOADSPOFFS: + registers[SREG_MAR] = GetStackPtrOffsetRw(arg1.IValue); + if (ccError) + { + return -1; + } + break; + + // 64 bit: Force 32 bit math + case SCMD_MULREG: + reg1.SetInt32(reg1.IValue * reg2.IValue); + break; + case SCMD_DIVREG: + if (reg2.IValue == 0) { + cc_error("!Integer divide by zero"); + return -1; + } + reg1.SetInt32(reg1.IValue / reg2.IValue); + break; + case SCMD_ADDREG: + // This may be pointer arithmetics, in which case IValue stores offset from base pointer + reg1.IValue += reg2.IValue; + break; + case SCMD_SUBREG: + // This may be pointer arithmetics, in which case IValue stores offset from base pointer + reg1.IValue -= reg2.IValue; + break; + case SCMD_BITAND: + reg1.SetInt32(reg1.IValue & reg2.IValue); + break; + case SCMD_BITOR: + reg1.SetInt32(reg1.IValue | reg2.IValue); + break; + case SCMD_ISEQUAL: + reg1.SetInt32AsBool(reg1 == reg2); + break; + case SCMD_NOTEQUAL: + reg1.SetInt32AsBool(reg1 != reg2); + break; + case SCMD_GREATER: + reg1.SetInt32AsBool(reg1.IValue > reg2.IValue); + break; + case SCMD_LESSTHAN: + reg1.SetInt32AsBool(reg1.IValue < reg2.IValue); + break; + case SCMD_GTE: + reg1.SetInt32AsBool(reg1.IValue >= reg2.IValue); + break; + case SCMD_LTE: + reg1.SetInt32AsBool(reg1.IValue <= reg2.IValue); + break; + case SCMD_AND: + reg1.SetInt32AsBool(reg1.IValue && reg2.IValue); + break; + case SCMD_OR: + reg1.SetInt32AsBool(reg1.IValue || reg2.IValue); + break; + case SCMD_XORREG: + reg1.SetInt32(reg1.IValue ^ reg2.IValue); + break; + case SCMD_MODREG: + if (reg2.IValue == 0) { + cc_error("!Integer divide by zero"); + return -1; + } + reg1.SetInt32(reg1.IValue % reg2.IValue); + break; + case SCMD_NOTREG: + reg1 = !(reg1); + break; + case SCMD_CALL: + // CallScriptFunction another function within same script, just save PC + // and continue from there + if (curnest >= MAXNEST - 1) { + cc_error("!call stack overflow, recursive call problem?"); + return -1; + } + + PUSH_CALL_STACK; + + ASSERT_STACK_SPACE_AVAILABLE(1); + PushValueToStack(RuntimeScriptValue().SetInt32(pc + codeOp.ArgCount + 1)); + if (ccError) + { + return -1; + } + + if (thisbase[curnest] == 0) + pc = reg1.IValue; + else { + pc = funcstart[curnest]; + pc += (reg1.IValue - thisbase[curnest]); + } + + next_call_needs_object = 0; + + if (loopIterationCheckDisabled) + loopIterationCheckDisabled++; + + curnest++; + thisbase[curnest] = 0; + funcstart[curnest] = pc; + continue; // continue so that the PC doesn't get overwritten + case SCMD_MEMREADB: + // Take the data address from reg[MAR] and copy byte to reg[arg1] + reg1.SetUInt8(registers[SREG_MAR].ReadByte()); + break; + case SCMD_MEMREADW: + // Take the data address from reg[MAR] and copy int16_t to reg[arg1] + reg1.SetInt16(registers[SREG_MAR].ReadInt16()); + break; + case SCMD_MEMWRITEB: + // Take the data address from reg[MAR] and copy there byte from reg[arg1] + registers[SREG_MAR].WriteByte(reg1.IValue); + break; + case SCMD_MEMWRITEW: + // Take the data address from reg[MAR] and copy there int16_t from reg[arg1] + registers[SREG_MAR].WriteInt16(reg1.IValue); + break; + case SCMD_JZ: + if (registers[SREG_AX].IsNull()) + pc += arg1.IValue; + break; + case SCMD_JNZ: + if (!registers[SREG_AX].IsNull()) + pc += arg1.IValue; + break; + case SCMD_PUSHREG: + // Push reg[arg1] value to the stack + ASSERT_STACK_SPACE_AVAILABLE(1); + PushValueToStack(reg1); + if (ccError) + { + return -1; + } + break; + case SCMD_POPREG: + ASSERT_STACK_SIZE(1); + reg1 = PopValueFromStack(); + break; + case SCMD_JMP: + pc += arg1.IValue; + + if ((arg1.IValue < 0) && (maxWhileLoops > 0) && (loopIterationCheckDisabled == 0)) { + // Make sure it's not stuck in a While loop + loopIterations ++; + if (flags & INSTF_RUNNING) { + loopIterations = 0; + flags &= ~INSTF_RUNNING; + } + else if (loopIterations > maxWhileLoops) { + cc_error("!Script appears to be hung (a while loop ran %d times). The problem may be in a calling function; check the call stack.", loopIterations); + return -1; + } + } + break; + case SCMD_MUL: + reg1.IValue *= arg2.IValue; + break; + case SCMD_CHECKBOUNDS: + if ((reg1.IValue < 0) || + (reg1.IValue >= arg2.IValue)) { + cc_error("!Array index out of bounds (index: %d, bounds: 0..%d)", reg1.IValue, arg2.IValue - 1); + return -1; + } + break; + case SCMD_DYNAMICBOUNDS: + { + // TODO: test reg[MAR] type here; + // That might be dynamic object, but also a non-managed dynamic array, "allocated" + // on global or local memspace (buffer) + int32_t upperBoundInBytes = *((int32_t *)(registers[SREG_MAR].GetPtrWithOffset() - 4)); + if ((reg1.IValue < 0) || + (reg1.IValue >= upperBoundInBytes)) { + int32_t upperBound = *((int32_t *)(registers[SREG_MAR].GetPtrWithOffset() - 8)) & (~ARRAY_MANAGED_TYPE_FLAG); + if (upperBound <= 0) + { + cc_error("!Array has an invalid size (%d) and cannot be accessed", upperBound); + } + else + { + int elementSize = (upperBoundInBytes / upperBound); + cc_error("!Array index out of bounds (index: %d, bounds: 0..%d)", reg1.IValue / elementSize, upperBound - 1); + } + return -1; + } + break; + } + + // 64 bit: Handles are always 32 bit values. They are not C pointer. + + case SCMD_MEMREADPTR: { + ccError = 0; + + int32_t handle = registers[SREG_MAR].ReadInt32(); + void *object; + ICCDynamicObject *manager; + ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(handle, object, manager); + if (obj_type == kScValPluginObject) + { + reg1.SetPluginObject( object, manager ); + } + else + { + reg1.SetDynamicObject( object, manager ); + } + + // if error occurred, cc_error will have been set + if (ccError) + return -1; + break; } + case SCMD_MEMWRITEPTR: { + + int32_t handle = registers[SREG_MAR].ReadInt32(); + char *address = nullptr; + + if (reg1.Type == kScValStaticArray && reg1.StcArr->GetDynamicManager()) + { + address = (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); + } + else if (reg1.Type == kScValDynamicObject || + reg1.Type == kScValPluginObject) + { + address = reg1.Ptr; + } + else if (reg1.Type == kScValPluginArg) + {// TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems + address = Int32ToPtr(reg1.IValue); + } + // There's one possible case when the reg1 is 0, which means writing nullptr + else if (!reg1.IsNull()) + { + cc_error("internal error: MEMWRITEPTR argument is not dynamic object"); + return -1; + } + + int32_t newHandle = ccGetObjectHandleFromAddress(address); + if (newHandle == -1) + return -1; + + if (handle != newHandle) { + ccReleaseObjectReference(handle); + ccAddObjectReference(newHandle); + registers[SREG_MAR].WriteInt32(newHandle); + } + break; + } + case SCMD_MEMINITPTR: { + char *address = nullptr; + + if (reg1.Type == kScValStaticArray && reg1.StcArr->GetDynamicManager()) + { + address = (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); + } + else if (reg1.Type == kScValDynamicObject || + reg1.Type == kScValPluginObject) + { + address = reg1.Ptr; + } + else if (reg1.Type == kScValPluginArg) + {// TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems + address = Int32ToPtr(reg1.IValue); + } + // There's one possible case when the reg1 is 0, which means writing nullptr + else if (!reg1.IsNull()) + { + cc_error("internal error: SCMD_MEMINITPTR argument is not dynamic object"); + return -1; + } + // like memwriteptr, but doesn't attempt to free the old one + int32_t newHandle = ccGetObjectHandleFromAddress(address); + if (newHandle == -1) + return -1; + + ccAddObjectReference(newHandle); + registers[SREG_MAR].WriteInt32(newHandle); + break; + } + case SCMD_MEMZEROPTR: { + int32_t handle = registers[SREG_MAR].ReadInt32(); + ccReleaseObjectReference(handle); + registers[SREG_MAR].WriteInt32(0); + break; + } + case SCMD_MEMZEROPTRND: { + int32_t handle = registers[SREG_MAR].ReadInt32(); + + // don't do the Dispose check for the object being returned -- this is + // for returning a String (or other pointer) from a custom function. + // Note: we might be freeing a dynamic array which contains the DisableDispose + // object, that will be handled inside the recursive call to SubRef. + // CHECKME!! what type of data may reg1 point to? + pool.disableDisposeForObject = (const char*)registers[SREG_AX].Ptr; + ccReleaseObjectReference(handle); + pool.disableDisposeForObject = nullptr; + registers[SREG_MAR].WriteInt32(0); + break; + } + case SCMD_CHECKNULL: + if (registers[SREG_MAR].IsNull()) { + cc_error("!Null pointer referenced"); + return -1; + } + break; + case SCMD_CHECKNULLREG: + if (reg1.IsNull()) { + cc_error("!Null string referenced"); + return -1; + } + break; + case SCMD_NUMFUNCARGS: + num_args_to_func = arg1.IValue; + break; + case SCMD_CALLAS:{ + PUSH_CALL_STACK; + + // CallScriptFunction to a function in another script + + // If there are nested CALLAS calls, the stack might + // contain 2 calls worth of parameters, so only + // push args for this call + if (num_args_to_func < 0) + { + num_args_to_func = func_callstack.Count; + } + ASSERT_STACK_SPACE_AVAILABLE(num_args_to_func + 1 /* return address */); + for (const RuntimeScriptValue *prval = func_callstack.GetHead() + num_args_to_func; + prval > func_callstack.GetHead(); --prval) + { + PushValueToStack(*prval); + } + + // 0, so that the cc_run_code returns + RuntimeScriptValue oldstack = registers[SREG_SP]; + PushValueToStack(RuntimeScriptValue().SetInt32(0)); + if (ccError) + { + return -1; + } + + int oldpc = pc; + ccInstance *wasRunning = runningInst; + + // extract the instance ID + int32_t instId = codeOp.Instruction.InstanceId; + // determine the offset into the code of the instance we want + runningInst = loadedInstances[instId]; + intptr_t callAddr = reg1.Ptr - (char*)&runningInst->code[0]; + if (callAddr % sizeof(intptr_t) != 0) { + cc_error("call address not aligned"); + return -1; + } + callAddr /= sizeof(intptr_t); // size of ccScript::code elements + + if (Run((int32_t)callAddr)) + return -1; + + runningInst = wasRunning; + + if (flags & INSTF_ABORTED) + return 0; + + if (oldstack != registers[SREG_SP]) { + cc_error("stack corrupt after function call"); + return -1; + } + + next_call_needs_object = 0; + + pc = oldpc; + was_just_callas = func_callstack.Count; + num_args_to_func = -1; + POP_CALL_STACK; + break; + } + case SCMD_CALLEXT: { + // CallScriptFunction to a real 'C' code function + was_just_callas = -1; + if (num_args_to_func < 0) + { + num_args_to_func = func_callstack.Count; + } + + // Convert pointer arguments to simple types + for (RuntimeScriptValue *prval = func_callstack.GetHead() + num_args_to_func; + prval > func_callstack.GetHead(); --prval) + { + prval->DirectPtr(); + } + + RuntimeScriptValue return_value; + + if (reg1.Type == kScValPluginFunction) + { + GlobalReturnValue.Invalidate(); + int32_t int_ret_val; + if (next_call_needs_object) + { + RuntimeScriptValue obj_rval = registers[SREG_OP]; + obj_rval.DirectPtrObj(); + int_ret_val = call_function((intptr_t)reg1.Ptr, &obj_rval, num_args_to_func, func_callstack.GetHead() + 1); + } + else + { + int_ret_val = call_function((intptr_t)reg1.Ptr, nullptr, num_args_to_func, func_callstack.GetHead() + 1); + } + + if (GlobalReturnValue.IsValid()) + { + return_value = GlobalReturnValue; + } + else + { + return_value.SetPluginArgument(int_ret_val); + } + } + else if (next_call_needs_object) + { + // member function call + if (reg1.Type == kScValObjectFunction) + { + RuntimeScriptValue obj_rval = registers[SREG_OP]; + obj_rval.DirectPtrObj(); + return_value = reg1.ObjPfn(obj_rval.Ptr, func_callstack.GetHead() + 1, num_args_to_func); + } + else + { + cc_error("invalid pointer type for object function call: %d", reg1.Type); + } + } + else if (reg1.Type == kScValStaticFunction) + { + return_value = reg1.SPfn(func_callstack.GetHead() + 1, num_args_to_func); + } + else if (reg1.Type == kScValObjectFunction) + { + cc_error("unexpected object function pointer on SCMD_CALLEXT"); + } + else + { + cc_error("invalid pointer type for function call: %d", reg1.Type); + } + + if (ccError) + { + return -1; + } + + registers[SREG_AX] = return_value; + current_instance = this; + next_call_needs_object = 0; + num_args_to_func = -1; + break; + } + case SCMD_PUSHREAL: + PushToFuncCallStack(func_callstack, reg1); + break; + case SCMD_SUBREALSTACK: + PopFromFuncCallStack(func_callstack, arg1.IValue); + if (was_just_callas >= 0) + { + ASSERT_STACK_SIZE(arg1.IValue); + PopValuesFromStack(arg1.IValue); + was_just_callas = -1; + } + break; + case SCMD_CALLOBJ: + // set the OP register + if (reg1.IsNull()) { + cc_error("!Null pointer referenced"); + return -1; + } + switch (reg1.Type) + { + // This might be a static object, passed to the user-defined extender function + case kScValStaticObject: + case kScValDynamicObject: + case kScValPluginObject: + case kScValPluginArg: + // This might be an object of USER-DEFINED type, calling its MEMBER-FUNCTION. + // Note, that this is the only case known when such object is written into reg[SREG_OP]; + // in any other case that would count as error. + case kScValGlobalVar: + case kScValStackPtr: + registers[SREG_OP] = reg1; + break; + case kScValStaticArray: + if (reg1.StcArr->GetDynamicManager()) + { + registers[SREG_OP].SetDynamicObject( + (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue), + reg1.StcArr->GetDynamicManager()); + break; + } + // fall-through intended + default: + cc_error("internal error: SCMD_CALLOBJ argument is not an object of built-in or user-defined type"); + return -1; + } + next_call_needs_object = 1; + break; + case SCMD_SHIFTLEFT: + reg1.SetInt32(reg1.IValue << reg2.IValue); + break; + case SCMD_SHIFTRIGHT: + reg1.SetInt32(reg1.IValue >> reg2.IValue); + break; + case SCMD_THISBASE: + thisbase[curnest] = arg1.IValue; + break; + case SCMD_NEWARRAY: + { + int numElements = reg1.IValue; + if (numElements < 1) + { + cc_error("invalid size for dynamic array; requested: %d, range: 1..%d", numElements, INT32_MAX); + return -1; + } + DynObjectRef ref = globalDynamicArray.Create(numElements, arg2.IValue, arg3.GetAsBool()); + reg1.SetDynamicObject(ref.second, &globalDynamicArray); + break; + } + case SCMD_NEWUSEROBJECT: + { + const int32_t size = arg2.IValue; + if (size < 0) + { + cc_error("Invalid size for user object; requested: %u (or %d), range: 0..%d", (uint32_t)size, size, INT_MAX); + return -1; + } + ScriptUserObject *suo = ScriptUserObject::CreateManaged(size); + reg1.SetDynamicObject(suo, suo); + break; + } + case SCMD_FADD: + reg1.SetFloat(reg1.FValue + arg2.IValue); // arg2 was used as int here originally + break; + case SCMD_FSUB: + reg1.SetFloat(reg1.FValue - arg2.IValue); // arg2 was used as int here originally + break; + case SCMD_FMULREG: + reg1.SetFloat(reg1.FValue * reg2.FValue); + break; + case SCMD_FDIVREG: + if (reg2.FValue == 0.0) { + cc_error("!Floating point divide by zero"); + return -1; + } + reg1.SetFloat(reg1.FValue / reg2.FValue); + break; + case SCMD_FADDREG: + reg1.SetFloat(reg1.FValue + reg2.FValue); + break; + case SCMD_FSUBREG: + reg1.SetFloat(reg1.FValue - reg2.FValue); + break; + case SCMD_FGREATER: + reg1.SetFloatAsBool(reg1.FValue > reg2.FValue); + break; + case SCMD_FLESSTHAN: + reg1.SetFloatAsBool(reg1.FValue < reg2.FValue); + break; + case SCMD_FGTE: + reg1.SetFloatAsBool(reg1.FValue >= reg2.FValue); + break; + case SCMD_FLTE: + reg1.SetFloatAsBool(reg1.FValue <= reg2.FValue); + break; + case SCMD_ZEROMEMORY: + // Check if we are zeroing at stack tail + if (registers[SREG_MAR] == registers[SREG_SP]) { + // creating a local variable -- check the stack to ensure no mem overrun + int currentStackSize = registers[SREG_SP].RValue - &stack[0]; + int currentDataSize = stackdata_ptr - stackdata; + if (currentStackSize + 1 >= CC_STACK_SIZE || + currentDataSize + arg1.IValue >= CC_STACK_DATA_SIZE) + { + cc_error("stack overflow, attempted grow to %d bytes", currentDataSize + arg1.IValue); + return -1; + } + // NOTE: according to compiler's logic, this is always followed + // by SCMD_ADD, and that is where the data is "allocated", here we + // just clean the place. + // CHECKME -- since we zero memory in PushDataToStack anyway, this is not needed at all? + memset(stackdata_ptr, 0, arg1.IValue); + } + else + { + cc_error("internal error: stack tail address expected on SCMD_ZEROMEMORY instruction, reg[MAR] type is %d", + registers[SREG_MAR].Type); + return -1; + } + break; + case SCMD_CREATESTRING: + if (stringClassImpl == nullptr) { + cc_error("No string class implementation set, but opcode was used"); + return -1; + } + direct_ptr1 = (const char*)reg1.GetDirectPtr(); + reg1.SetDynamicObject( + stringClassImpl->CreateString(direct_ptr1).second, + &myScriptStringImpl); + break; + case SCMD_STRINGSEQUAL: + if ((reg1.IsNull()) || (reg2.IsNull())) { + cc_error("!Null pointer referenced"); + return -1; + } + direct_ptr1 = (const char*)reg1.GetDirectPtr(); + direct_ptr2 = (const char*)reg2.GetDirectPtr(); + reg1.SetInt32AsBool(strcmp(direct_ptr1, direct_ptr2) == 0); + + break; + case SCMD_STRINGSNOTEQ: + if ((reg1.IsNull()) || (reg2.IsNull())) { + cc_error("!Null pointer referenced"); + return -1; + } + direct_ptr1 = (const char*)reg1.GetDirectPtr(); + direct_ptr2 = (const char*)reg2.GetDirectPtr(); + reg1.SetInt32AsBool(strcmp(direct_ptr1, direct_ptr2) != 0 ); + break; + case SCMD_LOOPCHECKOFF: + if (loopIterationCheckDisabled == 0) + loopIterationCheckDisabled++; + break; + default: + cc_error("instruction %d is not implemented", codeOp.Instruction.Code); + return -1; + } + + if (flags & INSTF_ABORTED) + return 0; + + pc += codeOp.ArgCount + 1; + } +} + +String ccInstance::GetCallStack(int maxLines) +{ + String buffer = String::FromFormat("in \"%s\", line %d\n", runningInst->instanceof->GetSectionName(pc), line_number); + + int linesDone = 0; + for (int j = callStackSize - 1; (j >= 0) && (linesDone < maxLines); j--, linesDone++) + { + String lineBuffer = String::FromFormat("from \"%s\", line %d\n", + callStackCodeInst[j]->instanceof->GetSectionName(callStackAddr[j]), callStackLineNumber[j]); + buffer.Append(lineBuffer); + if (linesDone == maxLines - 1) + buffer.Append("(and more...)\n"); + } + return buffer; +} + +void ccInstance::GetScriptPosition(ScriptPosition &script_pos) +{ + script_pos.Section = runningInst->instanceof->GetSectionName(pc); + script_pos.Line = line_number; +} + +// get a pointer to a variable or function exported by the script +RuntimeScriptValue ccInstance::GetSymbolAddress(const char *symname) +{ + int k; + char altName[200]; + sprintf(altName, "%s$", symname); + RuntimeScriptValue rval_null; + + for (k = 0; k < instanceof->numexports; k++) { + if (strcmp(instanceof->exports[k], symname) == 0) + return exports[k]; + // mangled function name + if (strncmp(instanceof->exports[k], altName, strlen(altName)) == 0) + return exports[k]; + } + return rval_null; +} + +void ccInstance::DumpInstruction(const ScriptOperation &op) +{ + // line_num local var should be shared between all the instances + static int line_num = 0; + + if (op.Instruction.Code == SCMD_LINENUM) + { + line_num = op.Args[0].IValue; + return; + } + + Stream *data_s = ci_fopen("script.log", kFile_Create, kFile_Write); + TextStreamWriter writer(data_s); + writer.WriteFormat("Line %3d, IP:%8d (SP:%p) ", line_num, pc, registers[SREG_SP].RValue); + + const ScriptCommandInfo &cmd_info = sccmd_info[op.Instruction.Code]; + writer.WriteString(cmd_info.CmdName); + + for (int i = 0; i < cmd_info.ArgCount; ++i) + { + if (i > 0) + { + writer.WriteChar(','); + } + if (cmd_info.ArgIsReg[i]) + { + writer.WriteFormat(" %s", regnames[op.Args[i].IValue]); + } + else + { + // MACPORT FIX 9/6/5: changed %d to %ld + // FIXME: check type and write appropriate values + writer.WriteFormat(" %ld", op.Args[i].GetPtrWithOffset()); + } + } + writer.WriteLineBreak(); + // the writer will delete data stream internally +} + +bool ccInstance::IsBeingRun() const +{ + return pc != 0; +} + +bool ccInstance::_Create(PScript scri, ccInstance * joined) +{ + int i; + currentline = -1; + if ((scri == nullptr) && (joined != nullptr)) + scri = joined->instanceof; + + if (scri == nullptr) { + cc_error("null pointer passed"); + return false; + } + + if (joined != nullptr) { + // share memory space with an existing instance (ie. this is a thread/fork) + globalvars = joined->globalvars; + globaldatasize = joined->globaldatasize; + globaldata = joined->globaldata; + code = joined->code; + codesize = joined->codesize; + } + else { + // create own memory space + // NOTE: globalvars are created in CreateGlobalVars() + globalvars.reset(new ScVarMap()); + globaldatasize = scri->globaldatasize; + globaldata = nullptr; + if (globaldatasize > 0) + { + globaldata = (char *)malloc(globaldatasize); + memcpy(globaldata, scri->globaldata, globaldatasize); + } + + codesize = scri->codesize; + code = nullptr; + if (codesize > 0) + { + code = (intptr_t*)malloc(codesize * sizeof(intptr_t)); + // 64 bit: Read code into 8 byte array, necessary for being able to perform + // relocations on the references. + for (int i = 0; i < codesize; ++i) + code[i] = scri->code[i]; + } + } + + // just use the pointer to the strings since they don't change + strings = scri->strings; + stringssize = scri->stringssize; + // create a stack + stackdatasize = CC_STACK_DATA_SIZE; + // This is quite a random choice; there's no way to deduce number of stack + // entries needed without knowing amount of local variables (at least) + num_stackentries = CC_STACK_SIZE; + stack = new RuntimeScriptValue[num_stackentries]; + stackdata = new char[stackdatasize]; + if (stack == nullptr || stackdata == nullptr) { + cc_error("not enough memory to allocate stack"); + return false; + } + + // find a LoadedInstance slot for it + for (i = 0; i < MAX_LOADED_INSTANCES; i++) { + if (loadedInstances[i] == nullptr) { + loadedInstances[i] = this; + loadedInstanceId = i; + break; + } + if (i == MAX_LOADED_INSTANCES - 1) { + cc_error("too many active instances"); + return false; + } + } + + if (joined) + { + resolved_imports = joined->resolved_imports; + code_fixups = joined->code_fixups; + } + else + { + if (!ResolveScriptImports(scri)) + { + return false; + } + if (!CreateGlobalVars(scri)) + { + return false; + } + if (!CreateRuntimeCodeFixups(scri)) + { + return false; + } + } + + exports = new RuntimeScriptValue[scri->numexports]; + + // find the real address of the exports + for (i = 0; i < scri->numexports; i++) { + int32_t etype = (scri->export_addr[i] >> 24L) & 0x000ff; + int32_t eaddr = (scri->export_addr[i] & 0x00ffffff); + if (etype == EXPORT_FUNCTION) + { + // NOTE: unfortunately, there seems to be no way to know if + // that's an extender function that expects object pointer + exports[i].SetCodePtr((char *)((intptr_t)eaddr * sizeof(intptr_t) + (char*)(&code[0]))); + } + else if (etype == EXPORT_DATA) + { + ScriptVariable *gl_var = FindGlobalVar(eaddr); + if (gl_var) + { + exports[i].SetGlobalVar(&gl_var->RValue); + } + else + { + cc_error("cannot resolve global variable, key = %d", eaddr); + return false; + } + } + else { + cc_error("internal export fixup error"); + return false; + } + } + instanceof = scri; + pc = 0; + flags = 0; + if (joined != nullptr) + flags = INSTF_SHAREDATA; + scri->instances++; + + if ((scri->instances == 1) && (ccGetOption(SCOPT_AUTOIMPORT) != 0)) { + // import all the exported stuff from this script + for (i = 0; i < scri->numexports; i++) { + if (!ccAddExternalScriptSymbol(scri->exports[i], exports[i], this)) { + cc_error("Export table overflow at '%s'", scri->exports[i]); + return false; + } + } + } + return true; +} + +void ccInstance::Free() +{ + if (instanceof != nullptr) { + instanceof->instances--; + if (instanceof->instances == 0) + { + simp.RemoveScriptExports(this); + } + } + + // remove from the Active Instances list + if (loadedInstances[loadedInstanceId] == this) + loadedInstances[loadedInstanceId] = nullptr; + + if ((flags & INSTF_SHAREDATA) == 0) + { + nullfree(globaldata); + nullfree(code); + } + globalvars.reset(); + globaldata = nullptr; + code = nullptr; + strings = nullptr; + + delete [] stack; + delete [] stackdata; + delete [] exports; + stack = nullptr; + stackdata = nullptr; + exports = nullptr; + + if ((flags & INSTF_SHAREDATA) == 0) + { + delete [] resolved_imports; + delete [] code_fixups; + } + resolved_imports = nullptr; + code_fixups = nullptr; +} + +bool ccInstance::ResolveScriptImports(PScript scri) +{ + // When the import is referenced in code, it's being addressed + // by it's index in the script imports array. That index is + // NOT unique and relative to script only. + // Script keeps information of used imports as an array of + // names. + // To allow real-time import use we should put resolved imports + // to the array keeping the order of their names in script's + // array of names. + + // resolve all imports referenced in the script + numimports = scri->numimports; + if (numimports == 0) + { + resolved_imports = nullptr; + return false; + } + resolved_imports = new int[numimports]; + + for (int i = 0; i < scri->numimports; ++i) { + // MACPORT FIX 9/6/5: changed from NULL TO 0 + if (scri->imports[i] == nullptr) { + continue; + } + + resolved_imports[i] = simp.get_index_of(scri->imports[i]); + if (resolved_imports[i] < 0) { + cc_error("unresolved import '%s'", scri->imports[i]); + return false; + } + } + return true; +} + +// TODO: it is possible to deduce global var's size at start with +// certain accuracy after all global vars are registered. Each +// global var's size would be limited by closest next var's ScAddress +// and globaldatasize. +bool ccInstance::CreateGlobalVars(PScript scri) +{ + ScriptVariable glvar; + + // Step One: deduce global variables from fixups + for (int i = 0; i < scri->numfixups; ++i) + { + switch (scri->fixuptypes[i]) + { + case FIXUP_GLOBALDATA: + // GLOBALDATA fixup takes relative address of global data element from code array; + // this is the address of actual data + glvar.ScAddress = (int32_t)code[scri->fixups[i]]; + glvar.RValue.SetData(globaldata + glvar.ScAddress, 0); + break; + case FIXUP_DATADATA: + { + // DATADATA fixup takes relative address of global data element from fixups array; + // this is the address of element, which stores address of actual data + glvar.ScAddress = scri->fixups[i]; + int32_t data_addr = BBOp::Int32FromLE(*(int32_t*)&globaldata[glvar.ScAddress]); + if (glvar.ScAddress - data_addr != 200 /* size of old AGS string */) + { + // CHECKME: probably replace with mere warning in the log? + cc_error("unexpected old-style string's alignment"); + return false; + } + // TODO: register this explicitly as a string instead (can do this later) + glvar.RValue.SetStaticObject(globaldata + data_addr, &GlobalStaticManager); + } + break; + default: + // other fixups are of no use here + continue; + } + + AddGlobalVar(glvar); + } + + // Step Two: deduce global variables from exports + for (int i = 0; i < scri->numexports; ++i) + { + int32_t etype = (scri->export_addr[i] >> 24L) & 0x000ff; + int32_t eaddr = (scri->export_addr[i] & 0x00ffffff); + if (etype == EXPORT_DATA) + { + // NOTE: old-style strings could not be exported in AGS, + // no need to worry about these here + glvar.ScAddress = eaddr; + glvar.RValue.SetData(globaldata + glvar.ScAddress, 0); + AddGlobalVar(glvar); + } + } + + return true; +} + +bool ccInstance::AddGlobalVar(const ScriptVariable &glvar) +{ + // [IKM] 2013-02-23: + // !!! TODO + // "Metal Dead" game (built with AGS 3.21.1115) fails to pass this check, + // because one of its fixups in script creates reference beyond global + // data buffer. The error will be suppressed until root of the problem is + // found, and some proper workaround invented. + if (glvar.ScAddress < 0 || glvar.ScAddress >= globaldatasize) + { + /* + return false; + */ + Debug::Printf(kDbgMsg_Warn, "WARNING: global variable refers to data beyond allocated buffer (%d, %d)", glvar.ScAddress, globaldatasize); + } + globalvars->insert(std::make_pair(glvar.ScAddress, glvar)); + return true; +} + +ScriptVariable *ccInstance::FindGlobalVar(int32_t var_addr) +{ + // NOTE: see comment for AddGlobalVar() + if (var_addr < 0 || var_addr >= globaldatasize) + { + /* + return NULL; + */ + Debug::Printf(kDbgMsg_Warn, "WARNING: looking up for global variable beyond allocated buffer (%d, %d)", var_addr, globaldatasize); + } + ScVarMap::iterator it = globalvars->find(var_addr); + return it != globalvars->end() ? &it->second : nullptr; +} + +bool ccInstance::CreateRuntimeCodeFixups(PScript scri) +{ + code_fixups = new char[scri->codesize]; + memset(code_fixups, 0, scri->codesize); + for (int i = 0; i < scri->numfixups; ++i) + { + if (scri->fixuptypes[i] == FIXUP_DATADATA) + { + continue; + } + + int32_t fixup = scri->fixups[i]; + code_fixups[fixup] = scri->fixuptypes[i]; + + switch (scri->fixuptypes[i]) + { + case FIXUP_GLOBALDATA: + { + ScriptVariable *gl_var = FindGlobalVar((int32_t)code[fixup]); + if (!gl_var) + { + cc_error("cannot resolve global variable, key = %d", (int32_t)code[fixup]); + return false; + } + code[fixup] = (intptr_t)gl_var; + } + break; + case FIXUP_FUNCTION: + case FIXUP_STRING: + case FIXUP_STACK: + break; // do nothing yet + case FIXUP_IMPORT: + // we do not need to save import's address now when we have + // resolved imports kept so far as instance exists, but we + // must fixup the following instruction in certain case + { + int import_index = resolved_imports[code[fixup]]; + const ScriptImport *import = simp.getByIndex(import_index); + if (!import) + { + cc_error("cannot resolve import, key = %d", import_index); + return false; + } + code[fixup] = import_index; + // If the call is to another script function next CALLEXT + // must be replaced with CALLAS + if (import->InstancePtr != nullptr && (code[fixup + 1] & INSTANCE_ID_REMOVEMASK) == SCMD_CALLEXT) + { + code[fixup + 1] = SCMD_CALLAS | (import->InstancePtr->loadedInstanceId << INSTANCE_ID_SHIFT); + } + } + break; + default: + cc_error("internal fixup index error: %d", scri->fixuptypes[i]); + return false; + } + } + return true; +} + +/* +bool ccInstance::ReadOperation(ScriptOperation &op, int32_t at_pc) +{ + op.Instruction.Code = code[at_pc]; + op.Instruction.InstanceId = (op.Instruction.Code >> INSTANCE_ID_SHIFT) & INSTANCE_ID_MASK; + op.Instruction.Code &= INSTANCE_ID_REMOVEMASK; // now this is pure instruction code + + int want_args = sccmd_info[op.Instruction.Code].ArgCount; + if (at_pc + want_args >= codesize) + { + cc_error("unexpected end of code data at %d", at_pc + want_args); + return false; + } + op.ArgCount = want_args; + + at_pc++; + for (int i = 0; i < op.ArgCount; ++i, ++at_pc) + { + char fixup = code_fixups[at_pc]; + if (fixup > 0) + { + // could be relative pointer or import address + if (!FixupArgument(code[at_pc], fixup, op.Args[i])) + { + return false; + } + } + else + { + // should be a numeric literal (int32 or float) + op.Args[i].SetInt32( (int32_t)code[at_pc] ); + } + } + + return true; +} +*/ +/* +bool ccInstance::FixupArgument(intptr_t code_value, char fixup_type, RuntimeScriptValue &argument) +{ + switch (fixup_type) + { + case FIXUP_GLOBALDATA: + { + ScriptVariable *gl_var = (ScriptVariable*)code_value; + argument.SetGlobalVar(&gl_var->RValue); + } + break; + case FIXUP_FUNCTION: + // originally commented -- CHECKME: could this be used in very old versions of AGS? + // code[fixup] += (long)&code[0]; + // This is a program counter value, presumably will be used as SCMD_CALL argument + argument.SetInt32((int32_t)code_value); + break; + case FIXUP_STRING: + argument.SetStringLiteral(&strings[0] + code_value); + break; + case FIXUP_IMPORT: + { + const ScriptImport *import = simp.getByIndex((int32_t)code_value); + if (import) + { + argument = import->Value; + } + else + { + cc_error("cannot resolve import, key = %ld", code_value); + return false; + } + } + break; + case FIXUP_STACK: + argument = GetStackPtrOffsetFw((int32_t)code_value); + break; + default: + cc_error("internal fixup type error: %d", fixup_type); + return false;; + } + return true; +} +*/ +//----------------------------------------------------------------------------- + +void ccInstance::PushValueToStack(const RuntimeScriptValue &rval) +{ + // Write value to the stack tail and advance stack ptr + registers[SREG_SP].WriteValue(rval); + registers[SREG_SP].RValue++; +} + +void ccInstance::PushDataToStack(int32_t num_bytes) +{ + if (registers[SREG_SP].RValue->IsValid()) + { + cc_error("internal error: valid data beyond stack ptr"); + return; + } + // Zero memory, assign pointer to data block to the stack tail, advance both stack ptr and stack data ptr + memset(stackdata_ptr, 0, num_bytes); + registers[SREG_SP].RValue->SetData(stackdata_ptr, num_bytes); + stackdata_ptr += num_bytes; + registers[SREG_SP].RValue++; +} + +RuntimeScriptValue ccInstance::PopValueFromStack() +{ + // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail + registers[SREG_SP].RValue--; + RuntimeScriptValue rval = *registers[SREG_SP].RValue; + if (rval.Type == kScValData) + { + stackdata_ptr -= rval.Size; + } + registers[SREG_SP].RValue->Invalidate(); + return rval; +} + +void ccInstance::PopValuesFromStack(int32_t num_entries = 1) +{ + for (int i = 0; i < num_entries; ++i) + { + // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail + registers[SREG_SP].RValue--; + if (registers[SREG_SP].RValue->Type == kScValData) + { + stackdata_ptr -= registers[SREG_SP].RValue->Size; + } + registers[SREG_SP].RValue->Invalidate(); + } +} + +void ccInstance::PopDataFromStack(int32_t num_bytes) +{ + int32_t total_pop = 0; + while (total_pop < num_bytes && registers[SREG_SP].RValue > &stack[0]) + { + // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail + registers[SREG_SP].RValue--; + // remember popped bytes count + total_pop += registers[SREG_SP].RValue->Size; + if (registers[SREG_SP].RValue->Type == kScValData) + { + stackdata_ptr -= registers[SREG_SP].RValue->Size; + } + registers[SREG_SP].RValue->Invalidate(); + } + if (total_pop < num_bytes) + { + cc_error("stack underflow"); + } + else if (total_pop > num_bytes) + { + cc_error("stack pointer points inside local variable after pop, stack corrupted?"); + } +} + +RuntimeScriptValue ccInstance::GetStackPtrOffsetFw(int32_t fw_offset) +{ + int32_t total_off = 0; + RuntimeScriptValue *stack_entry = &stack[0]; + while (total_off < fw_offset && stack_entry - &stack[0] < CC_STACK_SIZE ) + { + if (stack_entry->Size > 0) + { + total_off += stack_entry->Size; + } + stack_entry++; + } + if (total_off < fw_offset) + { + cc_error("accessing address beyond stack's tail"); + return RuntimeScriptValue(); + } + RuntimeScriptValue stack_ptr; + stack_ptr.SetStackPtr(stack_entry); + if (total_off > fw_offset) + { + // Forward offset should always set ptr at the beginning of stack entry + cc_error("stack offset forward: trying to access stack data inside stack entry, stack corrupted?"); + } + return stack_ptr; +} + +RuntimeScriptValue ccInstance::GetStackPtrOffsetRw(int32_t rw_offset) +{ + int32_t total_off = 0; + RuntimeScriptValue *stack_entry = registers[SREG_SP].RValue; + while (total_off < rw_offset && stack_entry >= &stack[0]) + { + stack_entry--; + total_off += stack_entry->Size; + } + if (total_off < rw_offset) + { + cc_error("accessing address before stack's head"); + return RuntimeScriptValue(); + } + RuntimeScriptValue stack_ptr; + stack_ptr.SetStackPtr(stack_entry); + if (total_off > rw_offset) + { + // Could be accessing array element, so state error only if stack entry does not refer to data array + if (stack_entry->Type == kScValData) + { + stack_ptr.IValue += total_off - rw_offset; + } + else + { + cc_error("stack offset backward: trying to access stack data inside stack entry, stack corrupted?"); + } + } + return stack_ptr; +} + +void ccInstance::PushToFuncCallStack(FunctionCallStack &func_callstack, const RuntimeScriptValue &rval) +{ + if (func_callstack.Count >= MAX_FUNC_PARAMS) + { + cc_error("function callstack overflow"); + return; + } + + func_callstack.Entries[func_callstack.Head] = rval; + func_callstack.Head--; + func_callstack.Count++; +} + +void ccInstance::PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries) +{ + if (func_callstack.Count == 0) + { + cc_error("function callstack underflow"); + return; + } + + func_callstack.Head += num_entries; + func_callstack.Count -= num_entries; +} diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h new file mode 100644 index 000000000000..7f6be855433e --- /dev/null +++ b/engines/ags/engine/script/cc_instance.h @@ -0,0 +1,221 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// 'C'-style script interpreter +// +//============================================================================= + +#ifndef __CC_INSTANCE_H +#define __CC_INSTANCE_H + +#include +#include + +#include "script/script_common.h" +#include "script/cc_script.h" // ccScript +#include "script/nonblockingscriptfunction.h" +#include "util/string.h" + +using namespace AGS; + +#define INSTF_SHAREDATA 1 +#define INSTF_ABORTED 2 +#define INSTF_FREE 4 +#define INSTF_RUNNING 8 // set by main code to confirm script isn't stuck +#define CC_STACK_SIZE 250 +#define CC_STACK_DATA_SIZE (1000 * sizeof(int32_t)) +#define MAX_CALL_STACK 100 + +// 256 because we use 8 bits to hold instance number +#define MAX_LOADED_INSTANCES 256 + +#define INSTANCE_ID_SHIFT 24LL +#define INSTANCE_ID_MASK 0x00000000000000ffLL +#define INSTANCE_ID_REMOVEMASK 0x0000000000ffffffLL + +struct ccInstance; +struct ScriptImport; + +struct ScriptInstruction +{ + ScriptInstruction() + { + Code = 0; + InstanceId = 0; + } + + int32_t Code; + int32_t InstanceId; +}; + +struct ScriptOperation +{ + ScriptOperation() + { + ArgCount = 0; + } + + ScriptInstruction Instruction; + RuntimeScriptValue Args[MAX_SCMD_ARGS]; + int ArgCount; +}; + +struct ScriptVariable +{ + ScriptVariable() + { + ScAddress = -1; // address = 0 is valid one, -1 means undefined + } + + int32_t ScAddress; // original 32-bit relative data address, written in compiled script; + // if we are to use Map or HashMap, this could be used as Key + RuntimeScriptValue RValue; +}; + +struct FunctionCallStack; + +struct ScriptPosition +{ + ScriptPosition() + : Line(0) + { + } + + ScriptPosition(const Common::String §ion, int32_t line) + : Section(section) + , Line(line) + { + } + + Common::String Section; + int32_t Line; +}; + +// Running instance of the script +struct ccInstance +{ +public: + // TODO: change to std:: if moved to C++11 + typedef std::unordered_map ScVarMap; + typedef std::shared_ptr PScVarMap; +public: + int32_t flags; + PScVarMap globalvars; + char *globaldata; + int32_t globaldatasize; + // Executed byte-code. Unlike ccScript's code array which is int32_t, the one + // in ccInstance must be intptr_t to accomodate real pointers placed after + // performing fixups. + intptr_t *code; + ccInstance *runningInst; // might point to another instance if in far call + int32_t codesize; + char *strings; + int32_t stringssize; + RuntimeScriptValue *exports; + RuntimeScriptValue *stack; + int num_stackentries; + // An array for keeping stack data; stack entries reference unknown data from here + // TODO: probably change to dynamic array later + char *stackdata; // for storing stack data of unknown type + char *stackdata_ptr;// works similar to original stack pointer, points to the next unused byte in stack data array + int32_t stackdatasize; // conventional size of stack data in bytes + // + RuntimeScriptValue registers[CC_NUM_REGISTERS]; + int32_t pc; // program counter + int32_t line_number; // source code line number + PScript instanceof; + int loadedInstanceId; + int returnValue; + + int callStackSize; + int32_t callStackLineNumber[MAX_CALL_STACK]; + int32_t callStackAddr[MAX_CALL_STACK]; + ccInstance *callStackCodeInst[MAX_CALL_STACK]; + + // array of real import indexes used in script + int *resolved_imports; + int numimports; + + char *code_fixups; + + // returns the currently executing instance, or NULL if none + static ccInstance *GetCurrentInstance(void); + // create a runnable instance of the supplied script + static ccInstance *CreateFromScript(PScript script); + static ccInstance *CreateEx(PScript scri, ccInstance * joined); + + ccInstance(); + ~ccInstance(); + // Create a runnable instance of the same script, sharing global memory + ccInstance *Fork(); + // Specifies that when the current function returns to the script, it + // will stop and return from CallInstance + void Abort(); + // Aborts instance, then frees the memory later when it is done with + void AbortAndDestroy(); + + // Call an exported function in the script + int CallScriptFunction(const char *funcname, int32_t num_params, const RuntimeScriptValue *params); + // Begin executing script starting from the given bytecode index + int Run(int32_t curpc); + + // Get the script's execution position and callstack as human-readable text + Common::String GetCallStack(int maxLines); + // Get the script's execution position + void GetScriptPosition(ScriptPosition &script_pos); + // Get the address of an exported symbol (function or variable) in the script + RuntimeScriptValue GetSymbolAddress(const char *symname); + void DumpInstruction(const ScriptOperation &op); + // Tells whether this instance is in the process of executing the byte-code + bool IsBeingRun() const; + +protected: + bool _Create(PScript scri, ccInstance * joined); + // free the memory associated with the instance + void Free(); + + bool ResolveScriptImports(PScript scri); + bool CreateGlobalVars(PScript scri); + bool AddGlobalVar(const ScriptVariable &glvar); + ScriptVariable *FindGlobalVar(int32_t var_addr); + bool CreateRuntimeCodeFixups(PScript scri); + //bool ReadOperation(ScriptOperation &op, int32_t at_pc); + + // Runtime fixups + //bool FixupArgument(intptr_t code_value, char fixup_type, RuntimeScriptValue &argument); + + // Stack processing + // Push writes new value and increments stack ptr; + // stack ptr now points to the __next empty__ entry + void PushValueToStack(const RuntimeScriptValue &rval); + void PushDataToStack(int32_t num_bytes); + // Pop decrements stack ptr, returns last stored value and invalidates! stack tail; + // stack ptr now points to the __next empty__ entry + RuntimeScriptValue PopValueFromStack(); + // helper function to pop & dump several values + void PopValuesFromStack(int32_t num_entries); + void PopDataFromStack(int32_t num_bytes); + // Return stack ptr at given offset from stack head; + // Offset is in data bytes; program stack ptr is __not__ changed + RuntimeScriptValue GetStackPtrOffsetFw(int32_t fw_offset); + // Return stack ptr at given offset from stack tail; + // Offset is in data bytes; program stack ptr is __not__ changed + RuntimeScriptValue GetStackPtrOffsetRw(int32_t rw_offset); + + // Function call stack processing + void PushToFuncCallStack(FunctionCallStack &func_callstack, const RuntimeScriptValue &rval); + void PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries); +}; + +#endif // __CC_INSTANCE_H diff --git a/engines/ags/engine/script/executingscript.cpp b/engines/ags/engine/script/executingscript.cpp new file mode 100644 index 000000000000..ba1fb22f3f2e --- /dev/null +++ b/engines/ags/engine/script/executingscript.cpp @@ -0,0 +1,88 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "executingscript.h" +#include "debug/debug_log.h" +#include "debug/debugger.h" + +QueuedScript::QueuedScript() + : Instance(kScInstGame) + , ParamCount(0) +{ +} + +int ExecutingScript::queue_action(PostScriptAction act, int data, const char *aname) { + if (numPostScriptActions >= MAX_QUEUED_ACTIONS) + quitprintf("!%s: Cannot queue action, post-script queue full", aname); + + if (numPostScriptActions > 0) { + // if something that will terminate the room has already + // been queued, don't allow a second thing to be queued + switch (postScriptActions[numPostScriptActions - 1]) { + case ePSANewRoom: + case ePSARestoreGame: + case ePSARestoreGameDialog: + case ePSARunAGSGame: + case ePSARestartGame: + quitprintf("!%s: Cannot run this command, since there was a %s command already queued to run in \"%s\", line %d", + aname, postScriptActionNames[numPostScriptActions - 1], + postScriptActionPositions[numPostScriptActions - 1].Section.GetCStr(), postScriptActionPositions[numPostScriptActions - 1].Line); + break; + // MACPORT FIX 9/6/5: added default clause to remove warning + default: + break; + } + } + + postScriptActions[numPostScriptActions] = act; + postScriptActionData[numPostScriptActions] = data; + postScriptActionNames[numPostScriptActions] = aname; + get_script_position(postScriptActionPositions[numPostScriptActions]); + numPostScriptActions++; + return numPostScriptActions - 1; +} + +void ExecutingScript::run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) { + if (numanother < MAX_QUEUED_SCRIPTS) + numanother++; + else { + /*debug_script_warn("Warning: too many scripts to run, ignored %s(%d,%d)", + script_run_another[numanother - 1], run_another_p1[numanother - 1], + run_another_p2[numanother - 1]);*/ + } + int thisslot = numanother - 1; + QueuedScript &script = ScFnQueue[thisslot]; + script.FnName.SetString(namm, MAX_FUNCTION_NAME_LEN); + script.Instance = scinst; + script.ParamCount = param_count; + script.Param1 = p1; + script.Param2 = p2; +} + +void ExecutingScript::init() { + inst = nullptr; + forked = 0; + numanother = 0; + numPostScriptActions = 0; + + memset(postScriptActions, 0, sizeof(postScriptActions)); + memset(postScriptActionNames, 0, sizeof(postScriptActionNames)); + memset(postScriptSaveSlotDescription, 0, sizeof(postScriptSaveSlotDescription)); + memset(postScriptActionData, 0, sizeof(postScriptActionData)); +} + +ExecutingScript::ExecutingScript() { + init(); +} diff --git a/engines/ags/engine/script/executingscript.h b/engines/ags/engine/script/executingscript.h new file mode 100644 index 000000000000..52f7b02e622d --- /dev/null +++ b/engines/ags/engine/script/executingscript.h @@ -0,0 +1,74 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H +#define __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H + +#include "script/cc_instance.h" + +enum PostScriptAction { + ePSANewRoom, + ePSAInvScreen, + ePSARestoreGame, + ePSARestoreGameDialog, + ePSARunAGSGame, + ePSARunDialog, + ePSARestartGame, + ePSASaveGame, + ePSASaveGameDialog +}; + +#define MAX_QUEUED_SCRIPTS 4 +#define MAX_QUEUED_ACTIONS 5 +#define MAX_FUNCTION_NAME_LEN 60 + +enum ScriptInstType +{ + kScInstGame, + kScInstRoom +}; + +struct QueuedScript +{ + Common::String FnName; + ScriptInstType Instance; + size_t ParamCount; + RuntimeScriptValue Param1; + RuntimeScriptValue Param2; + + QueuedScript(); +}; + +struct ExecutingScript { + ccInstance *inst; + PostScriptAction postScriptActions[MAX_QUEUED_ACTIONS]; + const char *postScriptActionNames[MAX_QUEUED_ACTIONS]; + ScriptPosition postScriptActionPositions[MAX_QUEUED_ACTIONS]; + char postScriptSaveSlotDescription[MAX_QUEUED_ACTIONS][100]; + int postScriptActionData[MAX_QUEUED_ACTIONS]; + int numPostScriptActions; + QueuedScript ScFnQueue[MAX_QUEUED_SCRIPTS]; + int numanother; + char forked; + + int queue_action(PostScriptAction act, int data, const char *aname); + void run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2); + void init(); + ExecutingScript(); +}; + +#endif // __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H diff --git a/engines/ags/engine/script/exports.cpp b/engines/ags/engine/script/exports.cpp new file mode 100644 index 000000000000..5bad7b5d706d --- /dev/null +++ b/engines/ags/engine/script/exports.cpp @@ -0,0 +1,98 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Registering symbols for the script system +// +//============================================================================= + +#include "ac/gamestructdefines.h" + +extern void RegisterAudioChannelAPI(); +extern void RegisterAudioClipAPI(); +extern void RegisterButtonAPI(); +extern void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api); +extern void RegisterContainerAPI(); +extern void RegisterDateTimeAPI(); +extern void RegisterDialogAPI(); +extern void RegisterDialogOptionsRenderingAPI(); +extern void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api); +extern void RegisterDynamicSpriteAPI(); +extern void RegisterFileAPI(); +extern void RegisterGameAPI(); +extern void RegisterGlobalAPI(); +extern void RegisterGUIAPI(); +extern void RegisterGUIControlAPI(); +extern void RegisterHotspotAPI(); +extern void RegisterInventoryItemAPI(); +extern void RegisterInventoryWindowAPI(); +extern void RegisterLabelAPI(); +extern void RegisterListBoxAPI(); +extern void RegisterMathAPI(); +extern void RegisterMouseAPI(); +extern void RegisterObjectAPI(); +extern void RegisterOverlayAPI(); +extern void RegisterParserAPI(); +extern void RegisterRegionAPI(); +extern void RegisterRoomAPI(); +extern void RegisterScreenAPI(); +extern void RegisterSliderAPI(); +extern void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api); +extern void RegisterStringAPI(); +extern void RegisterSystemAPI(); +extern void RegisterTextBoxAPI(); +extern void RegisterViewFrameAPI(); +extern void RegisterViewportAPI(); + +extern void RegisterStaticObjects(); + +void setup_script_exports(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) +{ + RegisterAudioChannelAPI(); + RegisterAudioClipAPI(); + RegisterButtonAPI(); + RegisterCharacterAPI(base_api, compat_api); + RegisterContainerAPI(); + RegisterDateTimeAPI(); + RegisterDialogAPI(); + RegisterDialogOptionsRenderingAPI(); + RegisterDrawingSurfaceAPI(base_api, compat_api); + RegisterDynamicSpriteAPI(); + RegisterFileAPI(); + RegisterGameAPI(); + RegisterGlobalAPI(); + RegisterGUIAPI(); + RegisterGUIControlAPI(); + RegisterHotspotAPI(); + RegisterInventoryItemAPI(); + RegisterInventoryWindowAPI(); + RegisterLabelAPI(); + RegisterListBoxAPI(); + RegisterMathAPI(); + RegisterMouseAPI(); + RegisterObjectAPI(); + RegisterOverlayAPI(); + RegisterParserAPI(); + RegisterRegionAPI(); + RegisterRoomAPI(); + RegisterScreenAPI(); + RegisterSliderAPI(); + RegisterSpeechAPI(base_api, compat_api); + RegisterStringAPI(); + RegisterSystemAPI(); + RegisterTextBoxAPI(); + RegisterViewFrameAPI(); + RegisterViewportAPI(); + + RegisterStaticObjects(); +} diff --git a/engines/ags/engine/script/exports.h b/engines/ags/engine/script/exports.h new file mode 100644 index 000000000000..cfb8ffcc159f --- /dev/null +++ b/engines/ags/engine/script/exports.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Registering symbols for the script system +// +//============================================================================= +#ifndef __AGS_EE_SCRIPT__EXPORTS_H +#define __AGS_EE_SCRIPT__EXPORTS_H + +void setup_script_exports(ScriptAPIVersion base_api, ScriptAPIVersion compat_api); + +#endif // __AGS_EE_SCRIPT__EXPORTS_H diff --git a/engines/ags/engine/script/nonblockingscriptfunction.h b/engines/ags/engine/script/nonblockingscriptfunction.h new file mode 100644 index 000000000000..6c49e1b42df0 --- /dev/null +++ b/engines/ags/engine/script/nonblockingscriptfunction.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H +#define __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H + +#include "ac/runtime_defines.h" +#include "script/runtimescriptvalue.h" + +#include + +struct NonBlockingScriptFunction +{ + const char* functionName; + int numParameters; + //void* param1; + //void* param2; + RuntimeScriptValue params[2]; + bool roomHasFunction; + bool globalScriptHasFunction; + std::vector moduleHasFunction; + bool atLeastOneImplementationExists; + + NonBlockingScriptFunction(const char*funcName, int numParams) + { + this->functionName = funcName; + this->numParameters = numParams; + atLeastOneImplementationExists = false; + roomHasFunction = true; + globalScriptHasFunction = true; + } +}; + +#endif // __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H diff --git a/engines/ags/engine/script/runtimescriptvalue.cpp b/engines/ags/engine/script/runtimescriptvalue.cpp new file mode 100644 index 000000000000..f74e8d15b783 --- /dev/null +++ b/engines/ags/engine/script/runtimescriptvalue.cpp @@ -0,0 +1,321 @@ + +#include "script/cc_error.h" +#include "script/runtimescriptvalue.h" +#include "ac/dynobj/cc_dynamicobject.h" +#include "ac/statobj/staticobject.h" +#include "util/memory.h" + +#include // for memcpy() + +using namespace AGS::Common; + +// +// NOTE to future optimizers: I am using 'this' ptr here to better +// distinguish Runtime Values. +// + +// TODO: test again if stack entry really can hold an offset itself + +// TODO: use endian-agnostic method to access global vars + +uint8_t RuntimeScriptValue::ReadByte() +{ + if (this->Type == kScValStackPtr || this->Type == kScValGlobalVar) + { + if (RValue->Type == kScValData) + { + return *(uint8_t*)(RValue->GetPtrWithOffset() + this->IValue); + } + else + { + return RValue->IValue; // get RValue as int + } + } + else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) + { + return this->StcMgr->ReadInt8(this->Ptr, this->IValue); + } + else if (this->Type == kScValDynamicObject) + { + return this->DynMgr->ReadInt8(this->Ptr, this->IValue); + } + return *((uint8_t*)this->GetPtrWithOffset()); +} + +int16_t RuntimeScriptValue::ReadInt16() +{ + if (this->Type == kScValStackPtr) + { + if (RValue->Type == kScValData) + { + return *(int16_t*)(RValue->GetPtrWithOffset() + this->IValue); + } + else + { + return RValue->IValue; // get RValue as int + } + } + else if (this->Type == kScValGlobalVar) + { + if (RValue->Type == kScValData) + { + return Memory::ReadInt16LE(RValue->GetPtrWithOffset() + this->IValue); + } + else + { + return RValue->IValue; // get RValue as int + } + } + else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) + { + return this->StcMgr->ReadInt16(this->Ptr, this->IValue); + } + else if (this->Type == kScValDynamicObject) + { + return this->DynMgr->ReadInt16(this->Ptr, this->IValue); + } + return *((int16_t*)this->GetPtrWithOffset()); +} + +int32_t RuntimeScriptValue::ReadInt32() +{ + if (this->Type == kScValStackPtr) + { + if (RValue->Type == kScValData) + { + return *(int32_t*)(RValue->GetPtrWithOffset() + this->IValue); + } + else + { + return RValue->IValue; // get RValue as int + } + } + else if (this->Type == kScValGlobalVar) + { + if (RValue->Type == kScValData) + { + return Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue); + } + else + { + return RValue->IValue; // get RValue as int + } + } + else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) + { + return this->StcMgr->ReadInt32(this->Ptr, this->IValue); + } + else if (this->Type == kScValDynamicObject) + { + return this->DynMgr->ReadInt32(this->Ptr, this->IValue); + } + return *((int32_t*)this->GetPtrWithOffset()); +} + +bool RuntimeScriptValue::WriteByte(uint8_t val) +{ + if (this->Type == kScValStackPtr || this->Type == kScValGlobalVar) + { + if (RValue->Type == kScValData) + { + *(uint8_t*)(RValue->GetPtrWithOffset() + this->IValue) = val; + } + else + { + RValue->SetUInt8(val); // set RValue as int + } + } + else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) + { + this->StcMgr->WriteInt8(this->Ptr, this->IValue, val); + } + else if (this->Type == kScValDynamicObject) + { + this->DynMgr->WriteInt8(this->Ptr, this->IValue, val); + } + else + { + *((uint8_t*)this->GetPtrWithOffset()) = val; + } + return true; +} + +bool RuntimeScriptValue::WriteInt16(int16_t val) +{ + if (this->Type == kScValStackPtr) + { + if (RValue->Type == kScValData) + { + *(int16_t*)(RValue->GetPtrWithOffset() + this->IValue) = val; + } + else + { + RValue->SetInt16(val); // set RValue as int + } + } + else if (this->Type == kScValGlobalVar) + { + if (RValue->Type == kScValData) + { + Memory::WriteInt16LE(RValue->GetPtrWithOffset() + this->IValue, val); + } + else + { + RValue->SetInt16(val); // set RValue as int + } + } + else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) + { + this->StcMgr->WriteInt16(this->Ptr, this->IValue, val); + } + else if (this->Type == kScValDynamicObject) + { + this->DynMgr->WriteInt16(this->Ptr, this->IValue, val); + } + else + { + *((int16_t*)this->GetPtrWithOffset()) = val; + } + return true; +} + +bool RuntimeScriptValue::WriteInt32(int32_t val) +{ + if (this->Type == kScValStackPtr) + { + if (RValue->Type == kScValData) + { + *(int32_t*)(RValue->GetPtrWithOffset() + this->IValue) = val; + } + else + { + RValue->SetInt32(val); // set RValue as int + } + } + else if (this->Type == kScValGlobalVar) + { + if (RValue->Type == kScValData) + { + Memory::WriteInt32LE(RValue->GetPtrWithOffset() + this->IValue, val); + } + else + { + RValue->SetInt32(val); // set RValue as int + } + } + else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) + { + this->StcMgr->WriteInt32(this->Ptr, this->IValue, val); + } + else if (this->Type == kScValDynamicObject) + { + this->DynMgr->WriteInt32(this->Ptr, this->IValue, val); + } + else + { + *((int32_t*)this->GetPtrWithOffset()) = val; + } + return true; +} + +// Notice, that there are only two valid cases when a pointer may be written: +// when the destination is a stack entry or global variable of free type +// (not kScValData type). +// In any other case, only the numeric value (integer/float) will be written. +bool RuntimeScriptValue::WriteValue(const RuntimeScriptValue &rval) +{ + if (this->Type == kScValStackPtr) + { + if (RValue->Type == kScValData) + { + *(int32_t*)(RValue->GetPtrWithOffset() + this->IValue) = rval.IValue; + } + else + { + // NOTE: we cannot just WriteValue here because when an integer + // is pushed to the stack, script assumes that it is always 4 + // bytes and uses that size when calculating offsets to local + // variables; + // Therefore if pushed value is of integer type, we should rather + // act as WriteInt32 (for int8, int16 and int32). + if (rval.Type == kScValInteger) + { + RValue->SetInt32(rval.IValue); + } + else + { + *RValue = rval; + } + } + } + else if (this->Type == kScValGlobalVar) + { + if (RValue->Type == kScValData) + { + Memory::WriteInt32LE(RValue->GetPtrWithOffset() + this->IValue, rval.IValue); + } + else + { + *RValue = rval; + } + } + else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) + { + this->StcMgr->WriteInt32(this->Ptr, this->IValue, rval.IValue); + } + else if (this->Type == kScValDynamicObject) + { + this->DynMgr->WriteInt32(this->Ptr, this->IValue, rval.IValue); + } + else + { + *((int32_t*)this->GetPtrWithOffset()) = rval.IValue; + } + return true; +} + +RuntimeScriptValue &RuntimeScriptValue::DirectPtr() +{ + if (Type == kScValGlobalVar || Type == kScValStackPtr) + { + int ival = IValue; + *this = *RValue; + IValue += ival; + } + + if (Ptr) + { + if (Type == kScValDynamicObject) + Ptr = const_cast(DynMgr->GetFieldPtr(Ptr, IValue)); + else if (Type == kScValStaticObject) + Ptr = const_cast(StcMgr->GetFieldPtr(Ptr, IValue)); + else + Ptr += IValue; + IValue = 0; + } + return *this; +} + +RuntimeScriptValue &RuntimeScriptValue::DirectPtrObj() +{ + if (Type == kScValGlobalVar || Type == kScValStackPtr) + *this = *RValue; + return *this; +} + +intptr_t RuntimeScriptValue::GetDirectPtr() const +{ + const RuntimeScriptValue *temp_val = this; + int ival = temp_val->IValue; + if (temp_val->Type == kScValGlobalVar || temp_val->Type == kScValStackPtr) + { + temp_val = temp_val->RValue; + ival += temp_val->IValue; + } + if (temp_val->Type == kScValDynamicObject) + return (intptr_t)temp_val->DynMgr->GetFieldPtr(temp_val->Ptr, ival); + else if (temp_val->Type == kScValStaticObject) + return (intptr_t)temp_val->StcMgr->GetFieldPtr(temp_val->Ptr, ival); + else + return (intptr_t)(temp_val->Ptr + ival); +} diff --git a/engines/ags/engine/script/runtimescriptvalue.h b/engines/ags/engine/script/runtimescriptvalue.h new file mode 100644 index 000000000000..133267d203b3 --- /dev/null +++ b/engines/ags/engine/script/runtimescriptvalue.h @@ -0,0 +1,385 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Runtime script value struct +// +//============================================================================= +#ifndef __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H +#define __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H + +#include "script/script_api.h" +#include "util/memory.h" +#include "ac/dynobj/cc_dynamicobject.h" + +struct ICCStaticObject; +struct StaticArray; + +enum ScriptValueType +{ + kScValUndefined, // to detect errors + kScValInteger, // as strictly 32-bit integer (for integer math) + kScValFloat, // as float (for floating point math), 32-bit + kScValPluginArg, // an 32-bit value, passed to a script function when called + // directly by plugin; is allowed to represent object pointer + kScValStackPtr, // as a pointer to stack entry + kScValData, // as a container for randomly sized data (usually array) + kScValGlobalVar, // as a pointer to script variable; used only for global vars, + // as pointer to local vars must have StackPtr type so that the + // stack allocation could work + kScValStringLiteral,// as a pointer to literal string (array of chars) + kScValStaticObject, // as a pointer to static global script object + kScValStaticArray, // as a pointer to static global array (of static or dynamic objects) + kScValDynamicObject,// as a pointer to managed script object + kScValPluginObject, // as a pointer to object managed by plugin (similar to + // kScValDynamicObject, but has backward-compatible limitations) + kScValStaticFunction,// as a pointer to static function + kScValPluginFunction,// temporary workaround for plugins (unsafe function ptr) + kScValObjectFunction,// as a pointer to object member function, gets object pointer as + // first parameter + kScValCodePtr, // as a pointer to element in byte-code array +}; + +struct RuntimeScriptValue +{ +public: + RuntimeScriptValue() + { + Type = kScValUndefined; + IValue = 0; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 0; + } + + RuntimeScriptValue(int32_t val) + { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + } + + ScriptValueType Type; + // The 32-bit value used for integer/float math and for storing + // variable/element offset relative to object (and array) address + union + { + int32_t IValue; // access Value as int32 type + float FValue; // access Value as float type + }; + // Pointer is used for storing... pointers - to objects, arrays, + // functions and stack entries (other RSV) + union + { + char *Ptr; // generic data pointer + RuntimeScriptValue *RValue;// access ptr as a pointer to Runtime Value + ScriptAPIFunction *SPfn; // access ptr as a pointer to Script API Static Function + ScriptAPIObjectFunction *ObjPfn; // access ptr as a pointer to Script API Object Function + }; + // TODO: separation to Ptr and MgrPtr is only needed so far as there's + // a separation between Script*, Dynamic* and game entity classes. + // Once those classes are merged, it will no longer be needed. + union + { + void *MgrPtr;// generic object manager pointer + ICCStaticObject *StcMgr;// static object manager + StaticArray *StcArr;// static array manager + ICCDynamicObject *DynMgr;// dynamic object manager + }; + // The "real" size of data, either one stored in I/FValue, + // or the one referenced by Ptr. Used for calculating stack + // offsets. + // Original AGS scripts always assumed pointer is 32-bit. + // Therefore for stored pointers Size is always 4 both for x32 + // and x64 builds, so that the script is interpreted correctly. + int Size; + + inline bool IsValid() const + { + return Type != kScValUndefined; + } + inline bool IsNull() const + { + return Ptr == nullptr && IValue == 0; + } + + inline bool GetAsBool() const + { + return !IsNull(); + } + inline char* GetPtrWithOffset() const + { + return Ptr + IValue; + } + + inline RuntimeScriptValue &Invalidate() + { + Type = kScValUndefined; + IValue = 0; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 0; + return *this; + } + inline RuntimeScriptValue &SetUInt8(uint8_t val) + { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 1; + return *this; + } + inline RuntimeScriptValue &SetInt16(int16_t val) + { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 2; + return *this; + } + inline RuntimeScriptValue &SetInt32(int32_t val) + { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetFloat(float val) + { + Type = kScValFloat; + FValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetInt32AsBool(bool val) + { + return SetInt32(val ? 1 : 0); + } + inline RuntimeScriptValue &SetFloatAsBool(bool val) + { + return SetFloat(val ? 1.0F : 0.0F); + } + inline RuntimeScriptValue &SetPluginArgument(int32_t val) + { + Type = kScValPluginArg; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStackPtr(RuntimeScriptValue *stack_entry) + { + Type = kScValStackPtr; + IValue = 0; + RValue = stack_entry; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetData(char *data, int size) + { + Type = kScValData; + IValue = 0; + Ptr = data; + MgrPtr = nullptr; + Size = size; + return *this; + } + inline RuntimeScriptValue &SetGlobalVar(RuntimeScriptValue *glvar_value) + { + Type = kScValGlobalVar; + IValue = 0; + RValue = glvar_value; + MgrPtr = nullptr; + Size = 4; + return *this; + } + // TODO: size? + inline RuntimeScriptValue &SetStringLiteral(const char *str) + { + Type = kScValStringLiteral; + IValue = 0; + Ptr = const_cast(str); + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStaticObject(void *object, ICCStaticObject *manager) + { + Type = kScValStaticObject; + IValue = 0; + Ptr = (char*)object; + StcMgr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStaticArray(void *object, StaticArray *manager) + { + Type = kScValStaticArray; + IValue = 0; + Ptr = (char*)object; + StcArr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetDynamicObject(void *object, ICCDynamicObject *manager) + { + Type = kScValDynamicObject; + IValue = 0; + Ptr = (char*)object; + DynMgr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetPluginObject(void *object, ICCDynamicObject *manager) + { + Type = kScValPluginObject; + IValue = 0; + Ptr = (char*)object; + DynMgr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStaticFunction(ScriptAPIFunction *pfn) + { + Type = kScValStaticFunction; + IValue = 0; + SPfn = pfn; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetPluginFunction(void *pfn) + { + Type = kScValPluginFunction; + IValue = 0; + Ptr = (char*)pfn; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetObjectFunction(ScriptAPIObjectFunction *pfn) + { + Type = kScValObjectFunction; + IValue = 0; + ObjPfn = pfn; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetCodePtr(char *ptr) + { + Type = kScValCodePtr; + IValue = 0; + Ptr = ptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } + + inline RuntimeScriptValue operator !() const + { + return RuntimeScriptValue().SetInt32AsBool(!GetAsBool()); + } + + inline bool operator ==(const RuntimeScriptValue &rval) + { + return ((intptr_t)Ptr + (intptr_t)IValue) == ((intptr_t)rval.Ptr + (intptr_t)rval.IValue); + } + inline bool operator !=(const RuntimeScriptValue &rval) + { + return !(*this == rval); + } + + // FIXME: find out all certain cases when we are reading a pointer and store it + // as 32-bit value here. There should be a solution to distinct these cases and + // store value differently, otherwise it won't work for 64-bit build. + inline RuntimeScriptValue ReadValue() + { + RuntimeScriptValue rval; + switch(this->Type) { + case kScValStackPtr: + { + if (RValue->Type == kScValData) + { + rval.SetInt32(*(int32_t*)(RValue->GetPtrWithOffset() + this->IValue)); + } + else + { + rval = *RValue; + } + } + break; + case kScValGlobalVar: + { + if (RValue->Type == kScValData) + { + rval.SetInt32(AGS::Common::Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue)); + } + else + { + rval = *RValue; + } + } + break; + case kScValStaticObject: case kScValStaticArray: + { + rval.SetInt32(this->StcMgr->ReadInt32(this->Ptr, this->IValue)); + } + break; + case kScValDynamicObject: + { + rval.SetInt32(this->DynMgr->ReadInt32(this->Ptr, this->IValue)); + } + break; + default: + { + // 64 bit: Memory reads are still 32 bit + rval.SetInt32(*(int32_t*)this->GetPtrWithOffset()); + } + } + return rval; + } + + + // Helper functions for reading or writing values from/to + // object, referenced by this Runtime Value. + // Copy implementation depends on value type. + uint8_t ReadByte(); + int16_t ReadInt16(); + int32_t ReadInt32(); + bool WriteByte(uint8_t val); + bool WriteInt16(int16_t val); + bool WriteInt32(int32_t val); + bool WriteValue(const RuntimeScriptValue &rval); + + // Convert to most simple pointer type by resolving RValue ptrs and applying offsets; + // non pointer types are left unmodified + RuntimeScriptValue &DirectPtr(); + // Similar to above, a slightly speed-optimised version for situations when we can + // tell for certain that we are expecting a pointer to the object and not its (first) field. + RuntimeScriptValue &DirectPtrObj(); + // Resolve and return direct pointer to the referenced data; non pointer types return IValue + intptr_t GetDirectPtr() const; +}; + +#endif // __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp new file mode 100644 index 000000000000..40f3fb915f9a --- /dev/null +++ b/engines/ags/engine/script/script.cpp @@ -0,0 +1,929 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "script/script.h" +#include "ac/common.h" +#include "ac/character.h" +#include "ac/dialog.h" +#include "ac/event.h" +#include "ac/game.h" +#include "ac/gamesetupstruct.h" +#include "ac/gamestate.h" +#include "ac/global_audio.h" +#include "ac/global_character.h" +#include "ac/global_dialog.h" +#include "ac/global_display.h" +#include "ac/global_game.h" +#include "ac/global_gui.h" +#include "ac/global_hotspot.h" +#include "ac/global_object.h" +#include "ac/global_room.h" +#include "ac/invwindow.h" +#include "ac/mouse.h" +#include "ac/room.h" +#include "ac/roomobject.h" +#include "script/cc_error.h" +#include "script/cc_options.h" +#include "debug/debugger.h" +#include "debug/debug_log.h" +#include "main/game_run.h" +#include "media/video/video.h" +#include "script/script_runtime.h" +#include "util/string_compat.h" +#include "media/audio/audio_system.h" + +extern GameSetupStruct game; +extern GameState play; +extern int gameHasBeenRestored, displayed_room; +extern unsigned int load_new_game; +extern RoomObject*objs; +extern int our_eip; +extern CharacterInfo*playerchar; + +ExecutingScript scripts[MAX_SCRIPT_AT_ONCE]; +ExecutingScript*curscript = nullptr; + +PScript gamescript; +PScript dialogScriptsScript; +ccInstance *gameinst = nullptr, *roominst = nullptr; +ccInstance *dialogScriptsInst = nullptr; +ccInstance *gameinstFork = nullptr, *roominstFork = nullptr; + +int num_scripts=0; +int post_script_cleanup_stack = 0; + +int inside_script=0,in_graph_script=0; +int no_blocking_functions = 0; // set to 1 while in rep_Exec_always + +NonBlockingScriptFunction repExecAlways(REP_EXEC_ALWAYS_NAME, 0); +NonBlockingScriptFunction lateRepExecAlways(LATE_REP_EXEC_ALWAYS_NAME, 0); +NonBlockingScriptFunction getDialogOptionsDimensionsFunc("dialog_options_get_dimensions", 1); +NonBlockingScriptFunction renderDialogOptionsFunc("dialog_options_render", 1); +NonBlockingScriptFunction getDialogOptionUnderCursorFunc("dialog_options_get_active", 1); +NonBlockingScriptFunction runDialogOptionMouseClickHandlerFunc("dialog_options_mouse_click", 2); +NonBlockingScriptFunction runDialogOptionKeyPressHandlerFunc("dialog_options_key_press", 2); +NonBlockingScriptFunction runDialogOptionRepExecFunc("dialog_options_repexec", 1); + +ScriptSystem scsystem; + +std::vector scriptModules; +std::vector moduleInst; +std::vector moduleInstFork; +std::vector moduleRepExecAddr; +int numScriptModules = 0; + +std::vector characterScriptObjNames; +String objectScriptObjNames[MAX_ROOM_OBJECTS]; +std::vector guiScriptObjNames; + + +int run_dialog_request (int parmtr) { + play.stop_dialog_at_end = DIALOG_RUNNING; + RunTextScriptIParam(gameinst, "dialog_request", RuntimeScriptValue().SetInt32(parmtr)); + + if (play.stop_dialog_at_end == DIALOG_STOP) { + play.stop_dialog_at_end = DIALOG_NONE; + return -2; + } + if (play.stop_dialog_at_end >= DIALOG_NEWTOPIC) { + int tval = play.stop_dialog_at_end - DIALOG_NEWTOPIC; + play.stop_dialog_at_end = DIALOG_NONE; + return tval; + } + if (play.stop_dialog_at_end >= DIALOG_NEWROOM) { + int roomnum = play.stop_dialog_at_end - DIALOG_NEWROOM; + play.stop_dialog_at_end = DIALOG_NONE; + NewRoom(roomnum); + return -2; + } + play.stop_dialog_at_end = DIALOG_NONE; + return -1; +} + +void run_function_on_non_blocking_thread(NonBlockingScriptFunction* funcToRun) { + + update_script_mouse_coords(); + + int room_changes_was = play.room_changes; + funcToRun->atLeastOneImplementationExists = false; + + // run modules + // modules need a forkedinst for this to work + for (int kk = 0; kk < numScriptModules; kk++) { + funcToRun->moduleHasFunction[kk] = DoRunScriptFuncCantBlock(moduleInstFork[kk], funcToRun, funcToRun->moduleHasFunction[kk]); + + if (room_changes_was != play.room_changes) + return; + } + + funcToRun->globalScriptHasFunction = DoRunScriptFuncCantBlock(gameinstFork, funcToRun, funcToRun->globalScriptHasFunction); + + if (room_changes_was != play.room_changes) + return; + + funcToRun->roomHasFunction = DoRunScriptFuncCantBlock(roominstFork, funcToRun, funcToRun->roomHasFunction); +} + +//----------------------------------------------------------- +// [IKM] 2012-06-22 +// +// run_interaction_event() and run_interaction_script() +// are *almost* identical, except for the first parameter +// type. +// May these types be made children of the same base? +//----------------------------------------------------------- + + +// Returns 0 normally, or -1 to indicate that the NewInteraction has +// become invalid and don't run another interaction on it +// (eg. a room change occured) +int run_interaction_event (Interaction *nint, int evnt, int chkAny, int isInv) { + + if (evnt < 0 || (size_t)evnt >= nint->Events.size() || + (nint->Events[evnt].Response.get() == nullptr) || (nint->Events[evnt].Response->Cmds.size() == 0)) { + // no response defined for this event + // If there is a response for "Any Click", then abort now so as to + // run that instead + if (chkAny < 0) ; + else if ((size_t)chkAny < nint->Events.size() && + (nint->Events[chkAny].Response.get() != nullptr) && (nint->Events[chkAny].Response->Cmds.size() > 0)) + return 0; + + // Otherwise, run unhandled_event + run_unhandled_event(evnt); + + return 0; + } + + if (play.check_interaction_only) { + play.check_interaction_only = 2; + return -1; + } + + int cmdsrun = 0, retval = 0; + // Right, so there were some commands defined in response to the event. + retval = run_interaction_commandlist (nint->Events[evnt].Response.get(), &nint->Events[evnt].TimesRun, &cmdsrun); + + // An inventory interaction, but the wrong item was used + if ((isInv) && (cmdsrun == 0)) + run_unhandled_event (evnt); + + return retval; +} + +// Returns 0 normally, or -1 to indicate that the NewInteraction has +// become invalid and don't run another interaction on it +// (eg. a room change occured) +int run_interaction_script(InteractionScripts *nint, int evnt, int chkAny, int isInv) { + + if ((nint->ScriptFuncNames[evnt] == nullptr) || (nint->ScriptFuncNames[evnt][0u] == 0)) { + // no response defined for this event + // If there is a response for "Any Click", then abort now so as to + // run that instead + if (chkAny < 0) ; + else if ((nint->ScriptFuncNames[chkAny] != nullptr) && (nint->ScriptFuncNames[chkAny][0u] != 0)) + return 0; + + // Otherwise, run unhandled_event + run_unhandled_event(evnt); + + return 0; + } + + if (play.check_interaction_only) { + play.check_interaction_only = 2; + return -1; + } + + int room_was = play.room_changes; + + RuntimeScriptValue rval_null; + + update_polled_mp3(); + if ((strstr(evblockbasename,"character")!=nullptr) || (strstr(evblockbasename,"inventory")!=nullptr)) { + // Character or Inventory (global script) + QueueScriptFunction(kScInstGame, nint->ScriptFuncNames[evnt]); + } + else { + // Other (room script) + QueueScriptFunction(kScInstRoom, nint->ScriptFuncNames[evnt]); + } + update_polled_mp3(); + + int retval = 0; + // if the room changed within the action + if (room_was != play.room_changes) + retval = -1; + + return retval; +} + +int create_global_script() { + ccSetOption(SCOPT_AUTOIMPORT, 1); + for (int kk = 0; kk < numScriptModules; kk++) { + moduleInst[kk] = ccInstance::CreateFromScript(scriptModules[kk]); + if (moduleInst[kk] == nullptr) + return -3; + // create a forked instance for rep_exec_always + moduleInstFork[kk] = moduleInst[kk]->Fork(); + if (moduleInstFork[kk] == nullptr) + return -3; + + moduleRepExecAddr[kk] = moduleInst[kk]->GetSymbolAddress(REP_EXEC_NAME); + } + gameinst = ccInstance::CreateFromScript(gamescript); + if (gameinst == nullptr) + return -3; + // create a forked instance for rep_exec_always + gameinstFork = gameinst->Fork(); + if (gameinstFork == nullptr) + return -3; + + if (dialogScriptsScript != nullptr) + { + dialogScriptsInst = ccInstance::CreateFromScript(dialogScriptsScript); + if (dialogScriptsInst == nullptr) + return -3; + } + + ccSetOption(SCOPT_AUTOIMPORT, 0); + return 0; +} + +void cancel_all_scripts() { + int aa; + + for (aa = 0; aa < num_scripts; aa++) { + if (scripts[aa].forked) + scripts[aa].inst->AbortAndDestroy(); + else + scripts[aa].inst->Abort(); + scripts[aa].numanother = 0; + } + num_scripts = 0; + /* if (gameinst!=NULL) ->Abort(gameinst); + if (roominst!=NULL) ->Abort(roominst);*/ +} + +ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst) +{ + if (sc_inst == kScInstGame) + return gameinst; + else if (sc_inst == kScInstRoom) + return roominst; + return nullptr; +} + +void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) +{ + if (inside_script) + // queue the script for the run after current script is finished + curscript->run_another (fn_name, sc_inst, param_count, p1, p2); + else + // if no script is currently running, run the requested script right away + RunScriptFunction(sc_inst, fn_name, param_count, p1, p2); +} + +void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) +{ + ccInstance *sci = GetScriptInstanceByType(sc_inst); + if (sci) + { + if (param_count == 2) + RunTextScript2IParam(sci, fn_name, p1, p2); + else if (param_count == 1) + RunTextScriptIParam(sci, fn_name, p1); + else if (param_count == 0) + RunTextScript(sci, fn_name); + } +} + +bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction* funcToRun, bool hasTheFunc) +{ + if (!hasTheFunc) + return(false); + + no_blocking_functions++; + int result = 0; + + if (funcToRun->numParameters < 3) + { + result = sci->CallScriptFunction((char*)funcToRun->functionName, funcToRun->numParameters, funcToRun->params); + } + else + quit("DoRunScriptFuncCantBlock called with too many parameters"); + + if (result == -2) { + // the function doens't exist, so don't try and run it again + hasTheFunc = false; + } + else if ((result != 0) && (result != 100)) { + quit_with_script_error(funcToRun->functionName); + } + else + { + funcToRun->atLeastOneImplementationExists = true; + } + // this might be nested, so don't disrupt blocked scripts + ccErrorString = ""; + ccError = 0; + no_blocking_functions--; + return(hasTheFunc); +} + +char scfunctionname[MAX_FUNCTION_NAME_LEN + 1]; +int PrepareTextScript(ccInstance *sci, const char**tsname) +{ + ccError = 0; + // FIXME: try to make it so this function is not called with NULL sci + if (sci == nullptr) return -1; + if (sci->GetSymbolAddress(tsname[0]).IsNull()) { + ccErrorString = "no such function in script"; + return -2; + } + if (sci->IsBeingRun()) { + ccErrorString = "script is already in execution"; + return -3; + } + scripts[num_scripts].init(); + scripts[num_scripts].inst = sci; + // CHECKME: this conditional block will never run, because + // function would have quit earlier (deprecated functionality?) + if (sci->IsBeingRun()) { + scripts[num_scripts].inst = sci->Fork(); + if (scripts[num_scripts].inst == nullptr) + quit("unable to fork instance for secondary script"); + scripts[num_scripts].forked = 1; + } + curscript = &scripts[num_scripts]; + num_scripts++; + if (num_scripts >= MAX_SCRIPT_AT_ONCE) + quit("too many nested text script instances created"); + // in case script_run_another is the function name, take a backup + strncpy(scfunctionname, tsname[0], MAX_FUNCTION_NAME_LEN); + tsname[0] = &scfunctionname[0]; + update_script_mouse_coords(); + inside_script++; + // aborted_ip=0; + // abort_executor=0; + return 0; +} + +int RunScriptFunctionIfExists(ccInstance *sci, const char*tsname, int numParam, const RuntimeScriptValue *params) +{ + int oldRestoreCount = gameHasBeenRestored; + // First, save the current ccError state + // This is necessary because we might be attempting + // to run Script B, while Script A is still running in the + // background. + // If CallInstance here has an error, it would otherwise + // also abort Script A because ccError is a global variable. + int cachedCcError = ccError; + ccError = 0; + + int toret = PrepareTextScript(sci, &tsname); + if (toret) { + ccError = cachedCcError; + return -18; + } + + // Clear the error message + ccErrorString = ""; + + if (numParam < 3) + { + toret = curscript->inst->CallScriptFunction(tsname, numParam, params); + } + else + quit("Too many parameters to RunScriptFunctionIfExists"); + + // 100 is if Aborted (eg. because we are LoadAGSGame'ing) + if ((toret != 0) && (toret != -2) && (toret != 100)) { + quit_with_script_error(tsname); + } + + post_script_cleanup_stack++; + + if (post_script_cleanup_stack > 50) + quitprintf("!post_script_cleanup call stack exceeded: possible recursive function call? running %s", tsname); + + post_script_cleanup(); + + post_script_cleanup_stack--; + + // restore cached error state + ccError = cachedCcError; + + // if the game has been restored, ensure that any further scripts are not run + if ((oldRestoreCount != gameHasBeenRestored) && (eventClaimed == EVENT_INPROGRESS)) + eventClaimed = EVENT_CLAIMED; + + return toret; +} + +int RunTextScript(ccInstance *sci, const char *tsname) +{ + if (strcmp(tsname, REP_EXEC_NAME) == 0) { + // run module rep_execs + // FIXME: in theory the function may be already called for moduleInst[i], + // in which case this should not be executed; need to rearrange the code somehow + int room_changes_was = play.room_changes; + int restore_game_count_was = gameHasBeenRestored; + + for (int kk = 0; kk < numScriptModules; kk++) { + if (!moduleRepExecAddr[kk].IsNull()) + RunScriptFunctionIfExists(moduleInst[kk], tsname, 0, nullptr); + + if ((room_changes_was != play.room_changes) || + (restore_game_count_was != gameHasBeenRestored)) + return 0; + } + } + + int toret = RunScriptFunctionIfExists(sci, tsname, 0, nullptr); + if ((toret == -18) && (sci == roominst)) { + // functions in room script must exist + quitprintf("prepare_script: error %d (%s) trying to run '%s' (Room %d)", toret, ccErrorString.GetCStr(), tsname, displayed_room); + } + return toret; +} + +int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam) +{ + if ((strcmp(tsname, "on_key_press") == 0) || (strcmp(tsname, "on_mouse_click") == 0)) { + bool eventWasClaimed; + int toret = run_claimable_event(tsname, true, 1, &iparam, &eventWasClaimed); + + if (eventWasClaimed) + return toret; + } + + return RunScriptFunctionIfExists(sci, tsname, 1, &iparam); +} + +int RunTextScript2IParam(ccInstance *sci, const char*tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2) +{ + RuntimeScriptValue params[2]; + params[0] = iparam; + params[1] = param2; + + if (strcmp(tsname, "on_event") == 0) { + bool eventWasClaimed; + int toret = run_claimable_event(tsname, true, 2, params, &eventWasClaimed); + + if (eventWasClaimed) + return toret; + } + + // response to a button click, better update guis + if (ags_strnicmp(tsname, "interface_click", 15) == 0) + guis_need_update = 1; + + return RunScriptFunctionIfExists(sci, tsname, 2, params); +} + +String GetScriptName(ccInstance *sci) +{ + // TODO: have script name a ccScript's member? + // TODO: check script modules too? + if (!sci) + return "Not in a script"; + else if (sci->instanceof == gamescript) + return "Global script"; + else if (sci->instanceof == thisroom.CompiledScript) + return String::FromFormat("Room %d script", displayed_room); + return "Unknown script"; +} + +//============================================================================= + + +char bname[MAX_FUNCTION_NAME_LEN+1],bne[MAX_FUNCTION_NAME_LEN+1]; +char* make_ts_func_name(const char*base,int iii,int subd) { + int err = snprintf(bname,MAX_FUNCTION_NAME_LEN,base,iii); + if (err >= sizeof(bname)) + debug_script_warn("Function name length limit exceeded: %s (%d)", base, iii); + err = snprintf(bne,MAX_FUNCTION_NAME_LEN,"%s_%c",bname,subd+'a'); + if (err >= sizeof(bne)) + debug_script_warn("Function name length limit exceeded: %s", bname); + return &bne[0]; +} + +void post_script_cleanup() { + // should do any post-script stuff here, like go to new room + if (ccError) quit(ccErrorString); + ExecutingScript copyof = scripts[num_scripts-1]; + if (scripts[num_scripts-1].forked) + delete scripts[num_scripts-1].inst; + num_scripts--; + inside_script--; + + if (num_scripts > 0) + curscript = &scripts[num_scripts-1]; + else { + curscript = nullptr; + } + // if (abort_executor) user_disabled_data2=aborted_ip; + + int old_room_number = displayed_room; + + // run the queued post-script actions + for (int ii = 0; ii < copyof.numPostScriptActions; ii++) { + int thisData = copyof.postScriptActionData[ii]; + + switch (copyof.postScriptActions[ii]) { + case ePSANewRoom: + // only change rooms when all scripts are done + if (num_scripts == 0) { + new_room(thisData, playerchar); + // don't allow any pending room scripts from the old room + // in run_another to be executed + return; + } + else + curscript->queue_action(ePSANewRoom, thisData, "NewRoom"); + break; + case ePSAInvScreen: + invscreen(); + break; + case ePSARestoreGame: + cancel_all_scripts(); + try_restore_save(thisData); + return; + case ePSARestoreGameDialog: + restore_game_dialog(); + return; + case ePSARunAGSGame: + cancel_all_scripts(); + load_new_game = thisData; + return; + case ePSARunDialog: + do_conversation(thisData); + break; + case ePSARestartGame: + cancel_all_scripts(); + restart_game(); + return; + case ePSASaveGame: + save_game(thisData, copyof.postScriptSaveSlotDescription[ii]); + break; + case ePSASaveGameDialog: + save_game_dialog(); + break; + default: + quitprintf("undefined post script action found: %d", copyof.postScriptActions[ii]); + } + // if the room changed in a conversation, for example, abort + if (old_room_number != displayed_room) { + return; + } + } + + + int jj; + for (jj = 0; jj < copyof.numanother; jj++) { + old_room_number = displayed_room; + QueuedScript &script = copyof.ScFnQueue[jj]; + RunScriptFunction(script.Instance, script.FnName, script.ParamCount, script.Param1, script.Param2); + if (script.Instance == kScInstRoom && script.ParamCount == 1) + { + // some bogus hack for "on_call" event handler + play.roomscript_finished = 1; + } + + // if they've changed rooms, cancel any further pending scripts + if ((displayed_room != old_room_number) || (load_new_game)) + break; + } + copyof.numanother = 0; + +} + +void quit_with_script_error(const char *functionName) +{ + // TODO: clean up the error reporting logic. Now engine will append call + // stack info in quit_check_for_error_state() but only in case of explicit + // script error ("!" type), and not in other case. + if (ccErrorIsUserError) + quitprintf("!Error running function '%s':\n%s", functionName, ccErrorString.GetCStr()); + else + quitprintf("Error running function '%s':\n%s\n\n%s", functionName, ccErrorString.GetCStr(), get_cur_script(5).GetCStr()); +} + +int get_nivalue (InteractionCommandList *nic, int idx, int parm) { + if (nic->Cmds[idx].Data[parm].Type == AGS::Common::kInterValVariable) { + // return the value of the variable + return get_interaction_variable(nic->Cmds[idx].Data[parm].Value)->Value; + } + return nic->Cmds[idx].Data[parm].Value; +} + +InteractionVariable *get_interaction_variable (int varindx) { + + if ((varindx >= LOCAL_VARIABLE_OFFSET) && ((size_t)varindx < LOCAL_VARIABLE_OFFSET + thisroom.LocalVariables.size())) + return &thisroom.LocalVariables[varindx - LOCAL_VARIABLE_OFFSET]; + + if ((varindx < 0) || (varindx >= numGlobalVars)) + quit("!invalid interaction variable specified"); + + return &globalvars[varindx]; +} + +InteractionVariable *FindGraphicalVariable(const char *varName) { + int ii; + for (ii = 0; ii < numGlobalVars; ii++) { + if (ags_stricmp (globalvars[ii].Name, varName) == 0) + return &globalvars[ii]; + } + for (size_t i = 0; i < thisroom.LocalVariables.size(); ++i) { + if (ags_stricmp (thisroom.LocalVariables[i].Name, varName) == 0) + return &thisroom.LocalVariables[i]; + } + return nullptr; +} + +#define IPARAM1 get_nivalue(nicl, i, 0) +#define IPARAM2 get_nivalue(nicl, i, 1) +#define IPARAM3 get_nivalue(nicl, i, 2) +#define IPARAM4 get_nivalue(nicl, i, 3) +#define IPARAM5 get_nivalue(nicl, i, 4) + +struct TempEip { + int oldval; + TempEip (int newval) { + oldval = our_eip; + our_eip = newval; + } + ~TempEip () { our_eip = oldval; } +}; + +// the 'cmdsrun' parameter counts how many commands are run. +// if a 'Inv Item Was Used' check does not pass, it doesn't count +// so cmdsrun remains 0 if no inventory items matched +int run_interaction_commandlist (InteractionCommandList *nicl, int *timesrun, int*cmdsrun) { + size_t i; + + if (nicl == nullptr) + return -1; + + for (i = 0; i < nicl->Cmds.size(); i++) { + cmdsrun[0] ++; + int room_was = play.room_changes; + + switch (nicl->Cmds[i].Type) { + case 0: // Do nothing + break; + case 1: // Run script + { + TempEip tempip(4001); + RuntimeScriptValue rval_null; + update_polled_mp3(); + if ((strstr(evblockbasename,"character")!=nullptr) || (strstr(evblockbasename,"inventory")!=nullptr)) { + // Character or Inventory (global script) + const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); + // we are already inside the mouseclick event of the script, can't nest calls + QueueScriptFunction(kScInstGame, torun); + } + else { + // Other (room script) + const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); + QueueScriptFunction(kScInstRoom, torun); + } + update_polled_mp3(); + break; + } + case 2: // Add score (first time) + if (timesrun[0] > 0) + break; + timesrun[0] ++; + case 3: // Add score + GiveScore (IPARAM1); + break; + case 4: // Display Message + /* if (comprdata<0) + display_message_aschar=evb->data[ss];*/ + DisplayMessage(IPARAM1); + break; + case 5: // Play Music + PlayMusicResetQueue(IPARAM1); + break; + case 6: // Stop Music + stopmusic (); + break; + case 7: // Play Sound + play_sound (IPARAM1); + break; + case 8: // Play Flic + play_flc_file(IPARAM1, IPARAM2); + break; + case 9: // Run Dialog + { int room_was = play.room_changes; + RunDialog(IPARAM1); + // if they changed room within the dialog script, + // the interaction command list is no longer valid + if (room_was != play.room_changes) + return -1; + } + break; + case 10: // Enable Dialog Option + SetDialogOption (IPARAM1, IPARAM2, 1); + break; + case 11: // Disable Dialog Option + SetDialogOption (IPARAM1, IPARAM2, 0); + break; + case 12: // Go To Screen + Character_ChangeRoomAutoPosition(playerchar, IPARAM1, IPARAM2); + return -1; + case 13: // Add Inventory + add_inventory (IPARAM1); + break; + case 14: // Move Object + MoveObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); + // if they want to wait until finished, do so + if (IPARAM5) + GameLoopUntilNotMoving(&objs[IPARAM1].moving); + break; + case 15: // Object Off + ObjectOff (IPARAM1); + break; + case 16: // Object On + ObjectOn (IPARAM1); + break; + case 17: // Set Object View + SetObjectView (IPARAM1, IPARAM2); + break; + case 18: // Animate Object + AnimateObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); + break; + case 19: // Move Character + if (IPARAM4) + MoveCharacterBlocking (IPARAM1, IPARAM2, IPARAM3, 0); + else + MoveCharacter (IPARAM1, IPARAM2, IPARAM3); + break; + case 20: // If Inventory Item was used + if (play.usedinv == IPARAM1) { + if (game.options[OPT_NOLOSEINV] == 0) + lose_inventory (play.usedinv); + if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + } + else + cmdsrun[0] --; + break; + case 21: // if player has inventory item + if (playerchar->inv[IPARAM1] > 0) + if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 22: // if a character is moving + if (game.chars[IPARAM1].walking) + if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 23: // if two variables are equal + if (IPARAM1 == IPARAM2) + if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 24: // Stop character walking + StopMoving (IPARAM1); + break; + case 25: // Go to screen at specific co-ordinates + NewRoomEx (IPARAM1, IPARAM2, IPARAM3); + return -1; + case 26: // Move NPC to different room + if (!is_valid_character(IPARAM1)) + quit("!Move NPC to different room: invalid character specified"); + game.chars[IPARAM1].room = IPARAM2; + break; + case 27: // Set character view + SetCharacterView (IPARAM1, IPARAM2); + break; + case 28: // Release character view + ReleaseCharacterView (IPARAM1); + break; + case 29: // Follow character + FollowCharacter (IPARAM1, IPARAM2); + break; + case 30: // Stop following + FollowCharacter (IPARAM1, -1); + break; + case 31: // Disable hotspot + DisableHotspot (IPARAM1); + break; + case 32: // Enable hotspot + EnableHotspot (IPARAM1); + break; + case 33: // Set variable value + get_interaction_variable(nicl->Cmds[i].Data[0].Value)->Value = IPARAM2; + break; + case 34: // Run animation + scAnimateCharacter(IPARAM1, IPARAM2, IPARAM3, 0); + GameLoopUntilValueIsZero(&game.chars[IPARAM1].animating); + break; + case 35: // Quick animation + SetCharacterView (IPARAM1, IPARAM2); + scAnimateCharacter(IPARAM1, IPARAM3, IPARAM4, 0); + GameLoopUntilValueIsZero(&game.chars[IPARAM1].animating); + ReleaseCharacterView (IPARAM1); + break; + case 36: // Set idle animation + SetCharacterIdle (IPARAM1, IPARAM2, IPARAM3); + break; + case 37: // Disable idle animation + SetCharacterIdle (IPARAM1, -1, -1); + break; + case 38: // Lose inventory item + lose_inventory (IPARAM1); + break; + case 39: // Show GUI + InterfaceOn (IPARAM1); + break; + case 40: // Hide GUI + InterfaceOff (IPARAM1); + break; + case 41: // Stop running more commands + return -1; + case 42: // Face location + FaceLocation (IPARAM1, IPARAM2, IPARAM3); + break; + case 43: // Pause command processor + scrWait (IPARAM1); + break; + case 44: // Change character view + ChangeCharacterView (IPARAM1, IPARAM2); + break; + case 45: // If player character is + if (GetPlayerCharacter() == IPARAM1) + if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 46: // if cursor mode is + if (GetCursorMode() == IPARAM1) + if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 47: // if player has been to room + if (HasBeenToRoom(IPARAM1)) + if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + default: + quit("unknown new interaction command"); + break; + } + + // if the room changed within the action, nicl is no longer valid + if (room_was != play.room_changes) + return -1; + } + return 0; + +} + +// check and abort game if the script is currently +// inside the rep_exec_always function +void can_run_delayed_command() { + if (no_blocking_functions) + quit("!This command cannot be used within non-blocking events such as " REP_EXEC_ALWAYS_NAME); +} + +void run_unhandled_event (int evnt) { + + if (play.check_interaction_only) + return; + + int evtype=0; + if (ags_strnicmp(evblockbasename,"hotspot",7)==0) evtype=1; + else if (ags_strnicmp(evblockbasename,"object",6)==0) evtype=2; + else if (ags_strnicmp(evblockbasename,"character",9)==0) evtype=3; + else if (ags_strnicmp(evblockbasename,"inventory",9)==0) evtype=5; + else if (ags_strnicmp(evblockbasename,"region",6)==0) + return; // no unhandled_events for regions + + // clicked Hotspot 0, so change the type code + if ((evtype == 1) & (evblocknum == 0) & (evnt != 0) & (evnt != 5) & (evnt != 6)) + evtype = 4; + if ((evtype==1) & ((evnt==0) | (evnt==5) | (evnt==6))) + ; // character stands on hotspot, mouse moves over hotspot, any click + else if ((evtype==2) & (evnt==4)) ; // any click on object + else if ((evtype==3) & (evnt==4)) ; // any click on character + else if (evtype > 0) { + can_run_delayed_command(); + + QueueScriptFunction(kScInstGame, "unhandled_event", 2, RuntimeScriptValue().SetInt32(evtype), RuntimeScriptValue().SetInt32(evnt)); + } +} diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h new file mode 100644 index 000000000000..521bf78298fe --- /dev/null +++ b/engines/ags/engine/script/script.h @@ -0,0 +1,119 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_EE_SCRIPT__SCRIPT_H +#define __AGS_EE_SCRIPT__SCRIPT_H + +#include + +#include "game/roomstruct.h" // MAX_ROOM_OBJECTS +#include "script/cc_instance.h" +#include "script/executingscript.h" +#include "script/nonblockingscriptfunction.h" +#include "ac/dynobj/scriptsystem.h" +#include "game/interactions.h" +#include "util/string.h" + +using AGS::Common::Interaction; +using AGS::Common::InteractionCommandList; +using AGS::Common::InteractionScripts; +using AGS::Common::InteractionVariable; + +#define LATE_REP_EXEC_ALWAYS_NAME "late_repeatedly_execute_always" +#define REP_EXEC_ALWAYS_NAME "repeatedly_execute_always" +#define REP_EXEC_NAME "repeatedly_execute" + +int run_dialog_request (int parmtr); +void run_function_on_non_blocking_thread(NonBlockingScriptFunction* funcToRun); +int run_interaction_event (Interaction *nint, int evnt, int chkAny = -1, int isInv = 0); +int run_interaction_script(InteractionScripts *nint, int evnt, int chkAny = -1, int isInv = 0); +int create_global_script(); +void cancel_all_scripts(); + +ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst); +// Queues a script function to be run either called by the engine or from another script +void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0, + const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue()); +// Try to run a script function right away +void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0, + const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue()); + +int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, int numParam, const RuntimeScriptValue *params); +int RunTextScript(ccInstance *sci, const char *tsname); +int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam); +int RunTextScript2IParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2); + +int PrepareTextScript(ccInstance *sci, const char **tsname); +bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction* funcToRun, bool hasTheFunc); + +AGS::Common::String GetScriptName(ccInstance *sci); + +//============================================================================= + +char* make_ts_func_name(const char*base,int iii,int subd); +// Performs various updates to the game after script interpreter returns control to the engine. +// Executes actions and does changes that are not executed immediately at script command, for +// optimisation and other reasons. +void post_script_cleanup(); +void quit_with_script_error(const char *functionName); +int get_nivalue (InteractionCommandList *nic, int idx, int parm); +int run_interaction_commandlist (InteractionCommandList *nicl, int *timesrun, int*cmdsrun); +InteractionVariable *get_interaction_variable (int varindx); +InteractionVariable *FindGraphicalVariable(const char *varName); +void run_unhandled_event (int evnt); +void can_run_delayed_command(); + + +extern ExecutingScript scripts[MAX_SCRIPT_AT_ONCE]; +extern ExecutingScript*curscript; + +extern PScript gamescript; +extern PScript dialogScriptsScript; +extern ccInstance *gameinst, *roominst; +extern ccInstance *dialogScriptsInst; +extern ccInstance *gameinstFork, *roominstFork; + +extern int num_scripts; +extern int post_script_cleanup_stack; + +extern int inside_script,in_graph_script; +extern int no_blocking_functions; // set to 1 while in rep_Exec_always + +extern NonBlockingScriptFunction repExecAlways; +extern NonBlockingScriptFunction lateRepExecAlways; +extern NonBlockingScriptFunction getDialogOptionsDimensionsFunc; +extern NonBlockingScriptFunction renderDialogOptionsFunc; +extern NonBlockingScriptFunction getDialogOptionUnderCursorFunc; +extern NonBlockingScriptFunction runDialogOptionMouseClickHandlerFunc; +extern NonBlockingScriptFunction runDialogOptionKeyPressHandlerFunc; +extern NonBlockingScriptFunction runDialogOptionRepExecFunc; + +extern ScriptSystem scsystem; + +extern std::vector scriptModules; +extern std::vector moduleInst; +extern std::vector moduleInstFork; +extern std::vector moduleRepExecAddr; +extern int numScriptModules; + +// TODO: find out if these extra arrays are really necessary. This may be remains from the +// time when the symbol import table was holding raw pointers to char array. +extern std::vector characterScriptObjNames; +extern AGS::Common::String objectScriptObjNames[MAX_ROOM_OBJECTS]; +extern std::vector guiScriptObjNames; + +#endif // __AGS_EE_SCRIPT__SCRIPT_H diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp new file mode 100644 index 000000000000..efc6ee92590e --- /dev/null +++ b/engines/ags/engine/script/script_api.cpp @@ -0,0 +1,243 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "ac/game_version.h" +#include "script/cc_error.h" +#include "script/runtimescriptvalue.h" +#include "script/script_api.h" +#include "util/math.h" + +namespace Math = AGS::Common::Math; + +enum FormatParseResult +{ + kFormatParseNone, + kFormatParseInvalid, + kFormatParseLiteralPercent, + kFormatParseArgInteger, + kFormatParseArgFloat, + kFormatParseArgString, + kFormatParseArgPointer, + + kFormatParseArgFirst = kFormatParseArgInteger, + kFormatParseArgLast = kFormatParseArgPointer +}; + +// Helper functions for getting parameter value either from script val array or va_list +inline int GetArgInt(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) +{ + if (varg_ptr) + return va_arg(*varg_ptr, int); + else + return sc_args[arg_idx].IValue; +} + +inline float GetArgFloat(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) +{ + // note that script variables store only floats, but va_list has floats promoted to double + if (varg_ptr) + return (float)va_arg(*varg_ptr, double); + else + return sc_args[arg_idx].FValue; +} + +inline const char *GetArgPtr(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) +{ + if (varg_ptr) + return va_arg(*varg_ptr, const char*); + else + return sc_args[arg_idx].Ptr; +} + + +// TODO: this implementation can be further optimised by either not calling +// snprintf but formatting values ourselves, or by using some library method +// that supports customizing, such as getting arguments in a custom way. +const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, + const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr) +{ + if (!buffer || buf_length == 0) + { + cc_error("Internal error in ScriptSprintf: buffer is null"); + return ""; + } + if (!format) + {// NOTE: interpreter (usually) catches null-pointer sent as format at some stage earlier + cc_error("Internal error in ScriptSprintf: format string is null"); + return ""; + } + if (!varg_ptr && sc_argc > 0 && !sc_args) + { + cc_error("Internal error in ScriptSprintf: args pointer is null"); + return ""; + } + + // Expected format character count: + // percent sign: 1 + // flag: 1 + // field width 10 (an uint32 number) + // precision sign 1 + // precision 10 (an uint32 number) + // length modifier 2 + // type 1 + // NOTE: although width and precision will + // not likely be defined by a 10-digit + // number, such case is theoretically valid. + const size_t fmtbuf_size = 27; + char fmtbuf[fmtbuf_size]; + char *fmt_bufptr; + char *fmt_bufendptr = &fmtbuf[fmtbuf_size - 1]; + + char *out_ptr = buffer; + // save 1 character for null terminator + const char *out_endptr = buffer + buf_length - 1; + const char *fmt_ptr = format; + int32_t arg_idx = 0; + + ptrdiff_t avail_outbuf; + int snprintf_res; + FormatParseResult fmt_done; + + // Parse the format string, looking for argument placeholders + while (*fmt_ptr && out_ptr != out_endptr) + { + // Try to put argument into placeholder + if (*fmt_ptr == '%') + { + avail_outbuf = out_endptr - out_ptr; + fmt_bufptr = fmtbuf; + *(fmt_bufptr++) = '%'; + snprintf_res = 0; + fmt_done = kFormatParseNone; + + // Parse placeholder + while (*(++fmt_ptr) && fmt_done == kFormatParseNone && fmt_bufptr != fmt_bufendptr) + { + *(fmt_bufptr++) = *fmt_ptr; + switch (*fmt_ptr) + { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + fmt_done = kFormatParseArgInteger; + break; + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'a': + case 'A': + fmt_done = kFormatParseArgFloat; + break; + case 'p': + fmt_done = kFormatParseArgPointer; + break; + case 's': + fmt_done = kFormatParseArgString; + break; + case '%': + // This may be a literal percent sign ('%%') + if (fmt_bufptr - fmtbuf == 2) + { + fmt_done = kFormatParseLiteralPercent; + } + // ...Otherwise we reached the next placeholder + else + { + fmt_ptr--; + fmt_bufptr--; + fmt_done = kFormatParseInvalid; + } + break; + } + } + + // Deal with the placeholder parsing results + if (fmt_done == kFormatParseLiteralPercent) + { + // literal percent sign + *(out_ptr++) = '%'; + continue; + } + else if (fmt_done >= kFormatParseArgFirst && fmt_done <= kFormatParseArgLast && + (varg_ptr || arg_idx < sc_argc)) + { + // Print the actual value + // NOTE: snprintf is called with avail_outbuf + 1 here, because we let it use our reserved + // character for null-terminator, in case we are at the end of the buffer + *fmt_bufptr = 0; // terminate the format buffer, we are going to use it + if (fmt_done == kFormatParseArgInteger) + snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgInt(sc_args, varg_ptr, arg_idx)); + else if (fmt_done == kFormatParseArgFloat) + snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgFloat(sc_args, varg_ptr, arg_idx)); + else + { + const char *p = GetArgPtr(sc_args, varg_ptr, arg_idx); + // Do extra checks for %s placeholder + if (fmt_done == kFormatParseArgString && !p) + { + if (loaded_game_file_version < kGameVersion_320) + { + // explicitly put "(null)" into the placeholder + p = "(null)"; + } + else + { + cc_error("!ScriptSprintf: formatting argument %d is expected to be a string, but it is a null pointer", arg_idx + 1); + return ""; + } + } + else if (fmt_done == kFormatParseArgString && p == buffer) + { + cc_error("!ScriptSprintf: formatting argument %d is a pointer to output buffer", arg_idx + 1); + return ""; + } + snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, p); + } + + arg_idx++; + if (snprintf_res >= 0) + { + // snprintf returns maximal number of characters, so limit it with buffer size + out_ptr += Math::Min(snprintf_res, avail_outbuf); + continue; + } + // -- pass further to invalid format case + } + + // If format was not valid, or there are no available + // parameters, just copy stored format buffer as it is + size_t copy_len = Math::Min(Math::Min(fmt_bufptr - fmtbuf, fmtbuf_size - 1), avail_outbuf); + memcpy(out_ptr, fmtbuf, copy_len); + out_ptr += copy_len; + } + // If there's no placeholder, simply copy the character to output buffer + else + { + *(out_ptr++) = *(fmt_ptr++); + } + } + + // Terminate the string + *out_ptr = 0; + return buffer; +} diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h new file mode 100644 index 000000000000..f17183850e23 --- /dev/null +++ b/engines/ags/engine/script/script_api.h @@ -0,0 +1,550 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Script API function type and helper macros for forwarding runtime script +// values to real engine functions. +// +//============================================================================= +#ifndef __AGS_EE_SCRIPT__SCRIPTAPI_H +#define __AGS_EE_SCRIPT__SCRIPTAPI_H + +#include +#include "core/types.h" +#include "ac/runtime_defines.h" +#include "ac/statobj/agsstaticobject.h" +#include "debug/out.h" + +struct RuntimeScriptValue; + +// TODO: replace void* with base object class when possible; also put array class for parameters +typedef RuntimeScriptValue ScriptAPIFunction(const RuntimeScriptValue *params, int32_t param_count); +typedef RuntimeScriptValue ScriptAPIObjectFunction(void *self, const RuntimeScriptValue *params, int32_t param_count); + +// Sprintf that takes either script values or common argument list from plugin. +// Uses EITHER sc_args/sc_argc or varg_ptr as parameter list, whichever is not +// NULL, with varg_ptr having HIGHER priority. +const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, + const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr); +// Sprintf that takes script values as arguments +inline const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, const RuntimeScriptValue *args, int32_t argc) +{ + return ScriptSprintf(buffer, buf_length, format, args, argc, nullptr); +} +// Variadic sprintf (needed, because all arguments are pushed as pointer-sized values). Currently used only when plugin calls +// exported engine function. Should be removed when this plugin issue is resolved. +inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *format, va_list &arg_ptr) +{ + return ScriptSprintf(buffer, buf_length, format, nullptr, 0, &arg_ptr); +} + +// Helper macros for script functions +#define ASSERT_SELF(METHOD) \ + assert((self != NULL) && "Object pointer is null in call to API function") +#define ASSERT_PARAM_COUNT(FUNCTION, X) \ + assert((params != NULL && param_count >= X) && "Not enough parameters in call to API function") +#define ASSERT_VARIABLE_VALUE(VARIABLE) \ + assert((params != NULL && param_count >= 1) && "Not enough parameters to set API property") +#define ASSERT_OBJ_PARAM_COUNT(METHOD, X) \ + ASSERT_SELF(METHOD); \ + ASSERT_PARAM_COUNT(METHOD, X) + +//----------------------------------------------------------------------------- +// Get/set variables + +#define API_VARGET_INT(VARIABLE) \ + return RuntimeScriptValue().SetInt32(VARIABLE) + +#define API_VARSET_PINT(VARIABLE) \ + ASSERT_VARIABLE_VALUE(VARIABLE); \ + VARIABLE = params[0].IValue; \ + return RuntimeScriptValue() + +//----------------------------------------------------------------------------- +// Calls to ScriptSprintf + +#define API_SCALL_SCRIPT_SPRINTF(FUNCTION, PARAM_COUNT) \ + ASSERT_PARAM_COUNT(FUNCTION, PARAM_COUNT); \ + char ScSfBuffer[STD_BUFFER_SIZE]; \ + const char *scsf_buffer = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(params[PARAM_COUNT - 1].Ptr), params + PARAM_COUNT, param_count - PARAM_COUNT) + +#define API_OBJCALL_SCRIPT_SPRINTF(METHOD, PARAM_COUNT) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, PARAM_COUNT); \ + char ScSfBuffer[STD_BUFFER_SIZE]; \ + const char *scsf_buffer = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(params[PARAM_COUNT - 1].Ptr), params + PARAM_COUNT, param_count - PARAM_COUNT) + +//----------------------------------------------------------------------------- +// Calls to ScriptSprintfV (unsafe plugin variant) + +#define API_PLUGIN_SCRIPT_SPRINTF(FORMAT_STR) \ + va_list args; \ + va_start(args, FORMAT_STR); \ + char ScSfBuffer[STD_BUFFER_SIZE]; \ + const char *scsf_buffer = ScriptVSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(FORMAT_STR), args); \ + va_end(args) + +//----------------------------------------------------------------------------- +// Calls to static functions +// +// IMPORTANT: please note following: historically AGS compiler did not have +// proper "void" type and allowed to store the return value of "void" API +// functions as an integer (although that value did not have any practical +// meaning). For backwards compatibility we actually return integer value +// of '0' in all the VOID script API functions! +// + +#define API_SCALL_VOID(FUNCTION) \ + FUNCTION(); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PBOOL(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + FUNCTION(params[0].GetAsBool()); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + FUNCTION(params[0].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT2(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION(params[0].IValue, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT3(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT4(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT5(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT6(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 6); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT_POBJ(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr, (P2CLASS*)params[2].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT2_POBJ(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION(params[0].IValue, params[1].IValue, (P1CLASS*)params[2].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT3_POBJ_PINT(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr, params[4].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PINT4_POBJ(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, (P1CLASS*)params[4].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_PFLOAT2(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION(params[0].FValue, params[1].FValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_POBJ(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + FUNCTION((P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_POBJ_PINT(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_POBJ_PINT2(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_VOID_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_SCALL_INT(FUNCTION) \ + return RuntimeScriptValue().SetInt32(FUNCTION()) + +#define API_SCALL_INT_PINT(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue)) + +#define API_SCALL_INT_PINT2(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue)) + +#define API_SCALL_INT_PINT3(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue)) + +#define API_SCALL_INT_PINT4(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue)) + +#define API_SCALL_INT_PINT4_PFLOAT(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 5) \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[3].FValue)) + +#define API_SCALL_INT_PINT5(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue)) + +#define API_SCALL_INT_PFLOAT_PINT(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].FValue, params[1].IValue)) + +#define API_SCALL_INT_POBJ(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr)) + +#define API_SCALL_INT_POBJ_PINT(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue)) + +#define API_SCALL_INT_POBJ_PINT2(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue)) + +#define API_SCALL_INT_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) + +#define API_SCALL_INT_PINT_POBJ(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr)) + +#define API_SCALL_FLOAT(FUNCTION) \ + return RuntimeScriptValue().SetFloat(FUNCTION()) + +#define API_SCALL_FLOAT_PINT(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetFloat(FUNCTION(params[0].IValue)) + +#define API_SCALL_FLOAT_PFLOAT(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetFloat(FUNCTION(params[0].FValue)) + +#define API_SCALL_FLOAT_PFLOAT2(FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetFloat(FUNCTION(params[0].FValue, params[1].FValue)) + +#define API_SCALL_BOOL(FUNCTION) \ + return RuntimeScriptValue().SetInt32AsBool(FUNCTION()) + +#define API_SCALL_BOOL_OBJ(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr)) + +#define API_SCALL_BOOL_POBJ_PINT(FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue)) + +#define API_SCALL_BOOL_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) + +#define API_SCALL_OBJ(RET_CLASS, RET_MGR, FUNCTION) \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(), &RET_MGR) + +#define API_SCALL_OBJ_PINT(RET_CLASS, RET_MGR, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue), &RET_MGR) + +#define API_SCALL_OBJ_POBJ_PINT_PBOOL(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].GetAsBool()), &RET_MGR) + +#define API_SCALL_OBJ_PINT2(RET_CLASS, RET_MGR, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue), &RET_MGR) + +#define API_SCALL_OBJ_PINT3_POBJ(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr), &RET_MGR) + +#define API_SCALL_OBJ_POBJ(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr), &RET_MGR) + +#define API_SCALL_OBJAUTO(RET_CLASS, FUNCTION) \ + RET_CLASS* ret_obj = FUNCTION(); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_PINT(RET_CLASS, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_PINT2(RET_CLASS, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_PINT3(RET_CLASS, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_PINT4(RET_CLASS, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_PINT5(RET_CLASS, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_PBOOL2(RET_CLASS, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = FUNCTION(params[0].GetAsBool(), params[1].GetAsBool()); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_POBJ(RET_CLASS, FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_POBJ_PINT(RET_CLASS, FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = (RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_SCALL_OBJAUTO_POBJ_PINT4(RET_CLASS, FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + + +#define API_SCALL_STOBJ_POBJ2(RET_CLASS, FUNCTION, P1CLASS, P2CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ + return RuntimeScriptValue().SetStaticObject(ret_obj, &GlobalStaticManager) + +//----------------------------------------------------------------------------- +// Calls to object functions + +#define API_OBJCALL_VOID(CLASS, METHOD) \ + ASSERT_SELF(METHOD); \ + METHOD((CLASS*)self); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, params[0].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT2(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT3(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT4(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 4); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT5(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 5); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT6(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 6); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PFLOAT(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, params[0].FValue); \ + return RuntimeScriptValue() + +#define API_OBJCALL_VOID_PFLOAT2(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].FValue, params[1].FValue); \ + return RuntimeScriptValue() + +#define API_OBJCALL_VOID_PBOOL(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, params[0].GetAsBool()); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT_PBOOL(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].IValue, params[1].GetAsBool()); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT_POBJ(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].IValue, (P1CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT3_POBJ(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 4); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_PINT5_POBJ(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 6); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, (P1CLASS*)params[5].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_POBJ(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_POBJ_PINT(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_POBJ_PINT2(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_VOID_POBJ2(CLASS, METHOD, P1CLASS, P2CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) + +#define API_OBJCALL_INT(CLASS, METHOD) \ + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self)) + +#define API_OBJCALL_INT_PINT(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue)) + +#define API_OBJCALL_INT_PINT_POBJ(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue, params[1].Ptr)) + +#define API_OBJCALL_INT_PINT2(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue, params[1].IValue)) + +#define API_OBJCALL_INT_POBJ(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr)) + +#define API_OBJCALL_INT_POBJ_PINT(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue)) + +#define API_OBJCALL_INT_POBJ_PBOOL(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].GetAsBool())) + +#define API_OBJCALL_FLOAT(CLASS, METHOD) \ + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetFloat(METHOD((CLASS*)self)) + +#define API_OBJCALL_BOOL(CLASS, METHOD) \ + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self)) + +#define API_OBJCALL_BOOL_PINT(CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, params[0].IValue)) + +#define API_OBJCALL_BOOL_POBJ(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr)) + +#define API_OBJCALL_BOOL_POBJ_PINT(CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue)) + +#define API_OBJCALL_BOOL_POBJ2(CLASS, METHOD, P1CLASS, P2CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) + +#define API_OBJCALL_BOOL(CLASS, METHOD) \ + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self)) + +#define API_OBJCALL_OBJ_PINT_POBJ(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, params[0].IValue, (P1CLASS*)params[1].Ptr), &RET_MGR) + +#define API_OBJCALL_OBJ_POBJ2_PINT(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS, P2CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].IValue), &RET_MGR) + +#define API_OBJCALL_OBJ_POBJ2_PBOOL(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS, P2CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].GetAsBool()), &RET_MGR) + +#define API_OBJCALL_OBJ(CLASS, RET_CLASS, RET_MGR, METHOD) \ + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self), &RET_MGR) + +#define API_OBJCALL_OBJ_PINT(CLASS, RET_CLASS, RET_MGR, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue), &RET_MGR) + +#define API_OBJCALL_OBJ_PINT2(CLASS, RET_CLASS, RET_MGR, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue), &RET_MGR) + +#define API_OBJCALL_OBJ_PINT3(CLASS, RET_CLASS, RET_MGR, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue), &RET_MGR) + +#define API_OBJCALL_OBJ_POBJ(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr), &RET_MGR) + +#define API_OBJCALL_OBJAUTO(CLASS, RET_CLASS, METHOD) \ + ASSERT_SELF(METHOD); \ + RET_CLASS* ret_obj = METHOD((CLASS*)self); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_OBJCALL_OBJAUTO_PINT2_PBOOL(CLASS, RET_CLASS, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + RET_CLASS* ret_obj = METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].GetAsBool()); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#define API_OBJCALL_OBJAUTO_POBJ(CLASS, RET_CLASS, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + RET_CLASS* ret_obj = METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + +#endif // __AGS_EE_SCRIPT__SCRIPTAPI_H diff --git a/engines/ags/engine/script/script_engine.cpp b/engines/ags/engine/script/script_engine.cpp new file mode 100644 index 000000000000..eefd707fe062 --- /dev/null +++ b/engines/ags/engine/script/script_engine.cpp @@ -0,0 +1,52 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Script Editor run-time engine component (c) 1998 Chris Jones +// script chunk format: +// 00h 1 dword version - should be 2 +// 04h 1 dword sizeof(scriptblock) +// 08h 1 dword number of ScriptBlocks +// 0Ch n STRUCTs ScriptBlocks +// +//============================================================================= + +#include +#include "script/cc_instance.h" +#include "script/cc_error.h" +#include "util/file.h" +#include "util/stream.h" + +namespace AGS { namespace Common { class RoomStruct; } } +using namespace AGS::Common; + +extern void quit(const char *); +extern int currentline; // in script/script_common + +std::pair cc_error_at_line(const char *error_msg) +{ + ccInstance *sci = ccInstance::GetCurrentInstance(); + if (!sci) + { + return std::make_pair(String::FromFormat("Error (line %d): %s", currentline, error_msg), String()); + } + else + { + return std::make_pair(String::FromFormat("Error: %s\n", error_msg), ccInstance::GetCurrentInstance()->GetCallStack(5)); + } +} + +String cc_error_without_line(const char *error_msg) +{ + return String::FromFormat("Runtime error: %s", error_msg); +} diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp new file mode 100644 index 000000000000..81a6d881bc5f --- /dev/null +++ b/engines/ags/engine/script/script_runtime.cpp @@ -0,0 +1,291 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// C-Script run-time interpreter (c) 2001 Chris Jones +// +// You must DISABLE OPTIMIZATIONS AND REGISTER VARIABLES in your compiler +// when compiling this, or strange results can happen. +// +// There is a problem with importing functions on 16-bit compilers: the +// script system assumes that all parameters are passed as 4 bytes, which +// ints are not on 16-bit systems. Be sure to define all parameters as longs, +// or join the 21st century and switch to DJGPP or Visual C++. +// +//============================================================================= + +#include +#include +#include +#include "script/script_runtime.h" +#include "script/script_common.h" +#include "script/cc_error.h" +#include "script/cc_options.h" +#include "ac/dynobj/cc_dynamicarray.h" +#include "script/systemimports.h" +#include "ac/statobj/staticobject.h" + +extern ccInstance *current_instance; // in script/cc_instance + +bool ccAddExternalStaticFunction(const String &name, ScriptAPIFunction *pfn) +{ + return simp.add(name, RuntimeScriptValue().SetStaticFunction(pfn), nullptr) == 0; +} + +bool ccAddExternalPluginFunction(const String &name, void *pfn) +{ + return simp.add(name, RuntimeScriptValue().SetPluginFunction(pfn), nullptr) == 0; +} + +bool ccAddExternalStaticObject(const String &name, void *ptr, ICCStaticObject *manager) +{ + return simp.add(name, RuntimeScriptValue().SetStaticObject(ptr, manager), nullptr) == 0; +} + +bool ccAddExternalStaticArray(const String &name, void *ptr, StaticArray *array_mgr) +{ + return simp.add(name, RuntimeScriptValue().SetStaticArray(ptr, array_mgr), nullptr) == 0; +} + +bool ccAddExternalDynamicObject(const String &name, void *ptr, ICCDynamicObject *manager) +{ + return simp.add(name, RuntimeScriptValue().SetDynamicObject(ptr, manager), nullptr) == 0; +} + +bool ccAddExternalObjectFunction(const String &name, ScriptAPIObjectFunction *pfn) +{ + return simp.add(name, RuntimeScriptValue().SetObjectFunction(pfn), nullptr) == 0; +} + +bool ccAddExternalScriptSymbol(const String &name, const RuntimeScriptValue &prval, ccInstance *inst) +{ + return simp.add(name, prval, inst) == 0; +} + +void ccRemoveExternalSymbol(const String &name) +{ + simp.remove(name); +} + +void ccRemoveAllSymbols() +{ + simp.clear(); +} + +ccInstance *loadedInstances[MAX_LOADED_INSTANCES] = {nullptr, +nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, +nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; + +void nullfree(void *data) +{ + if (data != nullptr) + free(data); +} + +void *ccGetSymbolAddress(const String &name) +{ + const ScriptImport *import = simp.getByName(name); + if (import) + { + return import->Value.Ptr; + } + return nullptr; +} + +bool ccAddExternalFunctionForPlugin(const String &name, void *pfn) +{ + return simp_for_plugin.add(name, RuntimeScriptValue().SetPluginFunction(pfn), nullptr) == 0; +} + +void *ccGetSymbolAddressForPlugin(const String &name) +{ + const ScriptImport *import = simp_for_plugin.getByName(name); + if (import) + { + return import->Value.Ptr; + } + else + { + // Also search the internal symbol table for non-function symbols + import = simp.getByName(name); + if (import) + { + return import->Value.Ptr; + } + } + return nullptr; +} + +new_line_hook_type new_line_hook = nullptr; + +char ccRunnerCopyright[] = "ScriptExecuter32 v" SCOM_VERSIONSTR " (c) 2001 Chris Jones"; +int maxWhileLoops = 0; + +// If a while loop does this many iterations without the +// NofityScriptAlive function getting called, the script +// aborts. Set to 0 to disable. +void ccSetScriptAliveTimer (int numloop) { + maxWhileLoops = numloop; +} + +void ccNotifyScriptStillAlive () { + if (current_instance != nullptr) + current_instance->flags |= INSTF_RUNNING; +} + +void ccSetDebugHook(new_line_hook_type jibble) +{ + new_line_hook = jibble; +} + +int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms) +{ + if (!addr) + { + cc_error("null function pointer in call_function"); + return -1; + } + if (numparm > 0 && !parms) + { + cc_error("invalid parameters array in call_function"); + return -1; + } + + intptr_t parm_value[9]; + if (object) + { + parm_value[0] = (intptr_t)object->GetPtrWithOffset(); + numparm++; + } + + for (int ival = object ? 1 : 0, iparm = 0; ival < numparm; ++ival, ++iparm) + { + switch (parms[iparm].Type) + { + case kScValInteger: + case kScValFloat: // AGS passes floats, copying their values into long variable + case kScValPluginArg: + parm_value[ival] = (intptr_t)parms[iparm].IValue; + break; + break; + default: + parm_value[ival] = (intptr_t)parms[iparm].GetPtrWithOffset(); + break; + } + } + + // + // AN IMPORTANT NOTE ON PARAM TYPE + // of 2012-11-10 + // + //// NOTE of 2012-12-20: + //// Everything said below is applicable only for calling + //// exported plugin functions. + // + // Here we are sending parameters of type intptr_t to registered + // function of unknown kind. Intptr_t is 32-bit for x32 build and + // 64-bit for x64 build. + // The exported functions usually have two types of parameters: + // pointer and 'int' (32-bit). For x32 build those two have the + // same size, but for x64 build first has 64-bit size while the + // second remains 32-bit. + // In formal case that would cause 'overflow' - function will + // receive more data than needed (written to stack), with some + // values shifted further by 32 bits. + // + // Upon testing, however, it was revealed that AMD64 processor, + // the only platform we support x64 Linux AGS build on right now, + // treats all the function parameters pushed to stack as 64-bit + // values (few first parameters are sent via registers, and hence + // are least concern anyway). Therefore, no 'overflow' occurs, + // and 64-bit values are being effectively truncated to 32-bit + // integers in the callee. + // + // Since this is still quite unreliable, this should be + // reimplemented when there's enough free time available for + // developers both for coding & testing. + // + // Most basic idea is to pass array of RuntimeScriptValue + // objects (that hold type description) and get same RSV as a + // return result. Keep in mind, though, that this solution will + // require fixing ALL exported functions, so a good amount of + // time and energy should be allocated for this task. + // + + switch (numparm) + { + case 0: + { + int (*fparam) (); + fparam = (int (*)())addr; + return fparam(); + } + case 1: + { + int (*fparam) (intptr_t); + fparam = (int (*)(intptr_t))addr; + return fparam(parm_value[0]); + } + case 2: + { + int (*fparam) (intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1]); + } + case 3: + { + int (*fparam) (intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2]); + } + case 4: + { + int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3]); + } + case 5: + { + int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4]); + } + case 6: + { + int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5]); + } + case 7: + { + int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6]); + } + case 8: + { + int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7]); + } + case 9: + { + int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7], parm_value[8]); + } + } + + cc_error("too many arguments in call to function"); + return -1; +} diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h new file mode 100644 index 000000000000..5a7e69c142de --- /dev/null +++ b/engines/ags/engine/script/script_runtime.h @@ -0,0 +1,75 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// C-Script run-time interpreter (c) 2001 Chris Jones +// +// You must DISABLE OPTIMIZATIONS AND REGISTER VARIABLES in your compiler +// when compiling this, or strange results can happen. +// +// There is a problem with importing functions on 16-bit compilers: the +// script system assumes that all parameters are passed as 4 bytes, which +// ints are not on 16-bit systems. Be sure to define all parameters as longs, +// or join the 21st century and switch to DJGPP or Visual C++. +// +//============================================================================= + +#ifndef __CS_RUNTIME_H +#define __CS_RUNTIME_H + +#include "script/cc_script.h" // ccScript +#include "script/cc_instance.h" // ccInstance + +struct ICCStaticObject; +struct ICCDynamicObject; +struct StaticArray; + +using AGS::Common::String; +using AGS::Common::String; + +// ************ SCRIPT LOADING AND RUNNING FUNCTIONS ************ + +// give the script access to a variable or function in your program +extern bool ccAddExternalStaticFunction(const String &name, ScriptAPIFunction *pfn); +// temporary workaround for plugins +extern bool ccAddExternalPluginFunction(const String &name, void *pfn); +extern bool ccAddExternalStaticObject(const String &name, void *ptr, ICCStaticObject *manager); +extern bool ccAddExternalStaticArray(const String &name, void *ptr, StaticArray *array_mgr); +extern bool ccAddExternalDynamicObject(const String &name, void *ptr, ICCDynamicObject *manager); +extern bool ccAddExternalObjectFunction(const String &name, ScriptAPIObjectFunction *pfn); +extern bool ccAddExternalScriptSymbol(const String &name, const RuntimeScriptValue &prval, ccInstance *inst); +// remove the script access to a variable or function in your program +extern void ccRemoveExternalSymbol(const String &name); +// removes all external symbols, allowing you to start from scratch +extern void ccRemoveAllSymbols(); + +// get the address of an exported variable in the script +extern void *ccGetSymbolAddress(const String &name); + +// registering functions, compatible with old unsafe call style; +// this is to be used solely by plugins until plugin inteface is redone +extern bool ccAddExternalFunctionForPlugin(const String &name, void *pfn); +extern void *ccGetSymbolAddressForPlugin(const String &name); + +// DEBUG HOOK +typedef void (*new_line_hook_type) (ccInstance *, int); +extern void ccSetDebugHook(new_line_hook_type jibble); +#endif + +// Set the number of while loop iterations that aborts the script +extern void ccSetScriptAliveTimer (int); +// reset the current while loop counter +extern void ccNotifyScriptStillAlive (); +// for calling exported plugin functions old-style +extern int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms); +extern void nullfree(void *data); // in script/script_runtime diff --git a/engines/ags/engine/script/systemimports.cpp b/engines/ags/engine/script/systemimports.cpp new file mode 100644 index 000000000000..41a53766d924 --- /dev/null +++ b/engines/ags/engine/script/systemimports.cpp @@ -0,0 +1,136 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "script/systemimports.h" + + +extern void quit(const char *); + +SystemImports simp; +SystemImports simp_for_plugin; + +int SystemImports::add(const String &name, const RuntimeScriptValue &value, ccInstance *anotherscr) +{ + int ixof; + + if ((ixof = get_index_of(name)) >= 0) { + // Only allow override if not a script-exported function + if (anotherscr == nullptr) { + imports[ixof].Value = value; + imports[ixof].InstancePtr = anotherscr; + } + return 0; + } + + ixof = imports.size(); + for (size_t i = 0; i < imports.size(); ++i) + { + if (imports[i].Name == nullptr) + { + ixof = i; + break; + } + } + + btree[name] = ixof; + if (ixof == imports.size()) + imports.push_back(ScriptImport()); + imports[ixof].Name = name; // TODO: rather make a string copy here for safety reasons + imports[ixof].Value = value; + imports[ixof].InstancePtr = anotherscr; + return 0; +} + +void SystemImports::remove(const String &name) { + int idx = get_index_of(name); + if (idx < 0) + return; + btree.erase(imports[idx].Name); + imports[idx].Name = nullptr; + imports[idx].Value.Invalidate(); + imports[idx].InstancePtr = nullptr; +} + +const ScriptImport *SystemImports::getByName(const String &name) +{ + int o = get_index_of(name); + if (o < 0) + return nullptr; + + return &imports[o]; +} + +const ScriptImport *SystemImports::getByIndex(int index) +{ + if ((size_t)index >= imports.size()) + return nullptr; + + return &imports[index]; +} + +int SystemImports::get_index_of(const String &name) +{ + IndexMap::const_iterator it = btree.find(name); + if (it != btree.end()) + return it->second; + + // CHECKME: what are "mangled names" and where do they come from? + String mangled_name = String::FromFormat("%s$", name.GetCStr()); + // if it's a function with a mangled name, allow it + it = btree.lower_bound(mangled_name); + if (it != btree.end() && it->first.CompareLeft(mangled_name) == 0) + return it->second; + + if (name.GetLength() > 3) + { + size_t c = name.FindCharReverse('^'); + if (c != -1 && (c == name.GetLength() - 2 || c == name.GetLength() - 3)) + { + // Function with number of prametrs on the end + // attempt to find it without the param count + return get_index_of(name.Left(c)); + } + } + return -1; +} + +void SystemImports::RemoveScriptExports(ccInstance *inst) +{ + if (!inst) + { + return; + } + + for (size_t i = 0; i < imports.size(); ++i) + { + if (imports[i].Name == nullptr) + continue; + + if (imports[i].InstancePtr == inst) + { + btree.erase(imports[i].Name); + imports[i].Name = nullptr; + imports[i].Value.Invalidate(); + imports[i].InstancePtr = nullptr; + } + } +} + +void SystemImports::clear() +{ + btree.clear(); + imports.clear(); +} diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h new file mode 100644 index 000000000000..b6a0873864f1 --- /dev/null +++ b/engines/ags/engine/script/systemimports.h @@ -0,0 +1,63 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __CC_SYSTEMIMPORTS_H +#define __CC_SYSTEMIMPORTS_H + +#include +#include "script/cc_instance.h" // ccInstance + +struct ICCDynamicObject; +struct ICCStaticObject; + +using AGS::Common::String; + +struct ScriptImport +{ + ScriptImport() + { + InstancePtr = nullptr; + } + + String Name; // import's uid + RuntimeScriptValue Value; + ccInstance *InstancePtr; // script instance +}; + +struct SystemImports +{ +private: + // Note we can't use a hash-map here, because we sometimes need to search + // by partial keys. + typedef std::map IndexMap; + + std::vector imports; + IndexMap btree; + +public: + int add(const String &name, const RuntimeScriptValue &value, ccInstance *inst); + void remove(const String &name); + const ScriptImport *getByName(const String &name); + int get_index_of(const String &name); + const ScriptImport *getByIndex(int index); + void RemoveScriptExports(ccInstance *inst); + void clear(); +}; + +extern SystemImports simp; +// This is to register symbols exclusively for plugins, to allow them +// perform old style unsafe function calls +extern SystemImports simp_for_plugin; + +#endif // __CC_SYSTEMIMPORTS_H \ No newline at end of file diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h new file mode 100644 index 000000000000..07c037a55086 --- /dev/null +++ b/engines/ags/engine/util/library.h @@ -0,0 +1,62 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__LIBRARY_H +#define __AGS_EE_UTIL__LIBRARY_H + +#include "core/platform.h" +#include "util/string.h" + +namespace AGS +{ +namespace Engine +{ + + +class BaseLibrary +{ +public: + BaseLibrary() = default; + + virtual ~BaseLibrary() = default; + + virtual AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) = 0; + + virtual bool Load(AGS::Common::String libraryName) = 0; + + virtual bool Unload() = 0; + + virtual void *GetFunctionAddress(AGS::Common::String functionName) = 0; +}; + + +} // namespace Engine +} // namespace AGS + + +#if AGS_PLATFORM_OS_WINDOWS +#include "library_windows.h" + +#elif AGS_PLATFORM_OS_LINUX \ + || AGS_PLATFORM_OS_MACOS \ + || AGS_PLATFORM_OS_ANDROID +#include "library_posix.h" + +#elif AGS_PLATFORM_OS_IOS +#include "library_dummy.h" + +#endif + + +#endif // __AGS_EE_UTIL__MUTEX_H diff --git a/engines/ags/engine/util/library_dummy.h b/engines/ags/engine/util/library_dummy.h new file mode 100644 index 000000000000..d91d06d34657 --- /dev/null +++ b/engines/ags/engine/util/library_dummy.h @@ -0,0 +1,67 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__LIBRARY_DUMMY_H +#define __AGS_EE_UTIL__LIBRARY_DUMMY_H + + +namespace AGS +{ +namespace Engine +{ + + +class DummyLibrary : BaseLibrary +{ +public: + DummyLibrary() + { + }; + + ~DummyLibrary() override + { + }; + + AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override + { + return libraryName; + } + + bool Load(AGS::Common::String libraryName) override + { + return false; + } + + bool Unload() override + { + return true; + } + + void *GetFunctionAddress(AGS::Common::String functionName) override + { + return NULL; + } +}; + + +typedef DummyLibrary Library; + + + +} // namespace Engine +} // namespace AGS + + + +#endif // __AGS_EE_UTIL__LIBRARY_DUMMY_H diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h new file mode 100644 index 000000000000..a11cdb2cecbc --- /dev/null +++ b/engines/ags/engine/util/library_posix.h @@ -0,0 +1,153 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__LIBRARY_POSIX_H +#define __AGS_EE_UTIL__LIBRARY_POSIX_H + +#include +#include "core/platform.h" +#include "util/string.h" +#include "debug/out.h" + +// FIXME: Replace with a unified way to get the directory which contains the engine binary +#if AGS_PLATFORM_OS_ANDROID +extern char android_app_directory[256]; +#else +extern AGS::Common::String appDirectory; +#endif + + +namespace AGS +{ +namespace Engine +{ + + +class PosixLibrary : BaseLibrary +{ +public: + PosixLibrary() + : _library(nullptr) + { + }; + + ~PosixLibrary() override + { + Unload(); + }; + + AGS::Common::String BuildFilename(AGS::Common::String libraryName) + { + return String::FromFormat( +#if AGS_PLATFORM_OS_MACOS + "lib%s.dylib" +#else + "lib%s.so" +#endif + , libraryName.GetCStr()); + } + + AGS::Common::String BuildPath(const char *path, AGS::Common::String libraryName) + { + AGS::Common::String platformLibraryName = ""; + if (path) + { + platformLibraryName = path; + platformLibraryName.Append("/"); + } + platformLibraryName.Append(BuildFilename(libraryName)); + + AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + return platformLibraryName; + } + + AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override + { + return BuildFilename(libraryName); + } + + bool Load(AGS::Common::String libraryName) override + { + Unload(); + + // Try rpath first + _library = dlopen(BuildPath(nullptr, libraryName).GetCStr(), RTLD_LAZY); + AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + if (_library != nullptr) + { + return true; + } + + // Try current path + _library = dlopen(BuildPath(".", libraryName).GetCStr(), RTLD_LAZY); + + AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + + if (_library == nullptr) + { + // Try the engine directory + +#if AGS_PLATFORM_OS_ANDROID + char buffer[200]; + sprintf(buffer, "%s%s", android_app_directory, "/lib"); + _library = dlopen(BuildPath(buffer, libraryName).GetCStr(), RTLD_LAZY); +#else + _library = dlopen(BuildPath(appDirectory, libraryName).GetCStr(), RTLD_LAZY); +#endif + + AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + } + + return (_library != nullptr); + } + + bool Unload() override + { + if (_library) + { + return (dlclose(_library) == 0); + } + else + { + return true; + } + } + + void *GetFunctionAddress(AGS::Common::String functionName) override + { + if (_library) + { + return dlsym(_library, functionName.GetCStr()); + } + else + { + return nullptr; + } + } + +private: + void *_library; +}; + + +typedef PosixLibrary Library; + + + +} // namespace Engine +} // namespace AGS + + + +#endif // __AGS_EE_UTIL__LIBRARY_POSIX_H diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h new file mode 100644 index 000000000000..54f52098b464 --- /dev/null +++ b/engines/ags/engine/util/library_psp.h @@ -0,0 +1,158 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + + +#ifndef __AGS_EE_UTIL__LIBRARY_PSP_H +#define __AGS_EE_UTIL__LIBRARY_PSP_H + +#include +#include "util/string.h" +#include "debug/out.h" + +namespace AGS +{ +namespace Engine +{ + +class PSPLibrary : BaseLibrary +{ +public: + PSPLibrary() + : _library(-1) + { + }; + + virtual ~PSPLibrary() + { + Unload(); + }; + + AGS::Common::String BuildPath(char *path, AGS::Common::String libraryName) + { + AGS::Common::String platformLibraryName = path; + platformLibraryName.Append(libraryName); + platformLibraryName.Append(".prx"); + + AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + + return platformLibraryName; + } + + bool Load(AGS::Common::String libraryName) + { + Unload(); + + // Try current path + _library = pspSdkLoadStartModule(BuildPath("./", libraryName).GetCStr(), PSP_MEMORY_PARTITION_USER); + + if (_library < 0) + { + // Try one directory higher, usually the AGS base directory + _library = pspSdkLoadStartModule(BuildPath("../", libraryName).GetCStr(), PSP_MEMORY_PARTITION_USER); + } + + // The PSP module and PSP library name are assumed to be the same as the file name + _moduleName = libraryName; + _moduleName.MakeLower(); + + AGS::Common::Debug::Printf("Result is %s %d", _moduleName.GetCStr(), _library); + + return (_library > -1); + } + + bool Unload() + { + if (_library > -1) + { + return (sceKernelUnloadModule(_library) > -1); + } + else + { + return true; + } + } + + void *GetFunctionAddress(AGS::Common::String functionName) + { + if (_library > -1) + { + // On the PSP functions are identified by an ID that is the first 4 byte of the SHA1 of the name. + int functionId; + +#if 1 + // Hardcoded values for plugin loading. + if (functionName == "AGS_PluginV2") + { + functionId = 0x960C49BD; + } + else if (functionName == "AGS_EngineStartup") + { + functionId = 0x0F13D9E8; + } + else if (functionName == "AGS_EngineShutdown") + { + functionId = 0x2F131C76; + } + else if (functionName == "AGS_EngineOnEvent") + { + functionId = 0xE3DFFC5A; + } + else if (functionName == "AGS_EngineDebugHook") + { + functionId = 0xC37D6879; + } + else if (functionName == "AGS_EngineInitGfx") + { + functionId = 0xA428D254; + } + else + { + AGS::Common::Debug::Printf("Function ID not found: %s", functionName.GetCStr()); + functionId = -1; + } +#else + // This is a possible SHA1 implementation. + SceKernelUtilsSha1Context ctx; + uint8_t digest[20]; + sceKernelUtilsSha1BlockInit(&ctx); + sceKernelUtilsSha1BlockUpdate(&ctx, (uint8_t *)functionName.GetCStr(), functionName.GetLength()); + sceKernelUtilsSha1BlockResult(&ctx, digest); + + functionId = strtol(digest, NULL, 8); +#endif + + return (void *)kernel_sctrlHENFindFunction((char *)_moduleName.GetCStr(), (char *)_moduleName.GetCStr(), functionId); + } + else + { + return NULL; + } + } + +private: + SceUID _library; + AGS::Common::String _moduleName; +}; + + +typedef PSPLibrary Library; + + + +} // namespace Engine +} // namespace AGS + + + +#endif // __AGS_EE_UTIL__LIBRARY_PSP_H diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h new file mode 100644 index 000000000000..7d4e5a7454e6 --- /dev/null +++ b/engines/ags/engine/util/library_windows.h @@ -0,0 +1,114 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_EE_UTIL__LIBRARY_WINDOWS_H +#define __AGS_EE_UTIL__LIBRARY_WINDOWS_H + +#include "debug/out.h" +#include "platform/windows/winapi_exclusive.h" +#include "util/string.h" + +// Because this class may be exposed to generic code in sake of inlining, +// we should avoid including full of macros with common names. +#ifdef __cplusplus +extern "C" { +#endif + + WINBASEAPI BOOL WINAPI FreeLibrary(HMODULE hLibModule); + WINBASEAPI FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName); + WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName); + +#ifdef __cplusplus +} // extern "C" +#endif + + +namespace AGS +{ +namespace Engine +{ + + +class WindowsLibrary : BaseLibrary +{ +public: + WindowsLibrary() + : _library(NULL) + { + }; + + virtual ~WindowsLibrary() + { + Unload(); + }; + + AGS::Common::String BuildFilename(AGS::Common::String libraryName) + { + return String::FromFormat("%s.dll", libraryName.GetCStr()); + } + + AGS::Common::String BuildPath(AGS::Common::String libraryName) + { + AGS::Common::String platformLibraryName = BuildFilename(libraryName); + + AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + + return platformLibraryName; + } + + AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override + { + return BuildFilename(libraryName); + } + + bool Load(AGS::Common::String libraryName) + { + Unload(); + + _library = LoadLibraryA(BuildPath(libraryName).GetCStr()); + + return (_library != NULL); + } + + bool Unload() + { + if (_library) + { + return (FreeLibrary(_library) != 0); + } + else + { + return true; + } + } + + void *GetFunctionAddress(AGS::Common::String functionName) + { + return GetProcAddress(_library, functionName.GetCStr()); + } + +private: + HANDLE _library; +}; + + +typedef WindowsLibrary Library; + + + +} // namespace Engine +} // namespace AGS + + + +#endif // __AGS_EE_UTIL__LIBRARY_WINDOWS_H diff --git a/engines/ags/engine/util/mutex.h b/engines/ags/engine/util/mutex.h new file mode 100644 index 000000000000..f7e8535f4b9f --- /dev/null +++ b/engines/ags/engine/util/mutex.h @@ -0,0 +1,50 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__MUTEX_H +#define __AGS_EE_UTIL__MUTEX_H + +namespace AGS +{ +namespace Engine +{ + + +class BaseMutex +{ +public: + BaseMutex() = default; + + virtual ~BaseMutex() = default; + + BaseMutex &operator=(const BaseMutex &) = delete; + BaseMutex(const BaseMutex &) = delete; + + virtual void Lock() = 0; + + virtual void Unlock() = 0; +}; + + +} // namespace Engine +} // namespace AGS + + +#if 0 + // insert platforms here +#else +#include "mutex_std.h" +#endif + +#endif // __AGS_EE_UTIL__MUTEX_H diff --git a/engines/ags/engine/util/mutex_base.h b/engines/ags/engine/util/mutex_base.h new file mode 100644 index 000000000000..51684f4b3ce6 --- /dev/null +++ b/engines/ags/engine/util/mutex_base.h @@ -0,0 +1,38 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_PLATFORM__MUTEX_BASE_H +#define __AGS_EE_PLATFORM__MUTEX_BASE_H + + +namespace AGS +{ +namespace Common +{ + + +class BaseMutex +{ +public: + BaseMutex() = 0; + virtual ~BaseMutex() = 0; + virtual void Lock() = 0; + virtual void Unlock() = 0; +}; + + +} // namespace Common +} // namespace AGS + +#endif // __AGS_EE_PLATFORM__MUTEX_BASE_H diff --git a/engines/ags/engine/util/mutex_lock.h b/engines/ags/engine/util/mutex_lock.h new file mode 100644 index 000000000000..6164abbf9094 --- /dev/null +++ b/engines/ags/engine/util/mutex_lock.h @@ -0,0 +1,66 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__MUTEX_LOCK_H +#define __AGS_EE_UTIL__MUTEX_LOCK_H + +#include "util/mutex.h" + +namespace AGS +{ +namespace Engine +{ + + +class MutexLock +{ +private: + BaseMutex *_m; + MutexLock(MutexLock const &); // non-copyable + MutexLock& operator=(MutexLock const &); // not copy-assignable + +public: + void Release() + { + if (_m != nullptr) _m->Unlock(); + _m = nullptr; + } + + void Acquire(BaseMutex &mutex) + { + Release(); + _m = &mutex; + _m->Lock(); + } + + MutexLock() : _m(nullptr) + { + } + + explicit MutexLock(BaseMutex &mutex) : _m(nullptr) + { + Acquire(mutex); + } + + ~MutexLock() + { + Release(); + } +}; // class MutexLock + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__MUTEX_LOCK_H diff --git a/engines/ags/engine/util/mutex_psp.h b/engines/ags/engine/util/mutex_psp.h new file mode 100644 index 000000000000..72ab28384514 --- /dev/null +++ b/engines/ags/engine/util/mutex_psp.h @@ -0,0 +1,62 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__PSP_MUTEX_H +#define __AGS_EE_UTIL__PSP_MUTEX_H + +#include +#include +#include + +namespace AGS +{ +namespace Engine +{ + + +class PSPMutex : public BaseMutex +{ +public: + PSPMutex() + { + _mutex = sceKernelCreateSema("", 0, 1, 1, 0); + } + + ~PSPMutex() + { + sceKernelDeleteSema(_mutex); + } + + inline void Lock() + { + sceKernelWaitSema(_mutex, 1, 0); + } + + inline void Unlock() + { + sceKernelSignalSema(_mutex, 1); + } + +private: + SceUID _mutex; +}; + + +typedef PSPMutex Mutex; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__PSP_MUTEX_H diff --git a/engines/ags/engine/util/mutex_pthread.h b/engines/ags/engine/util/mutex_pthread.h new file mode 100644 index 000000000000..cb3183fd13fa --- /dev/null +++ b/engines/ags/engine/util/mutex_pthread.h @@ -0,0 +1,59 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__MUTEX_PTHREAD_H +#define __AGS_EE_UTIL__MUTEX_PTHREAD_H + +#include + +namespace AGS +{ +namespace Engine +{ + + +class PThreadMutex : public BaseMutex +{ +public: + inline PThreadMutex() + { + pthread_mutex_init(&_mutex, NULL); + } + + inline ~PThreadMutex() + { + pthread_mutex_destroy(&_mutex); + } + + inline void Lock() + { + pthread_mutex_lock(&_mutex); + } + + inline void Unlock() + { + pthread_mutex_unlock(&_mutex); + } + +private: + pthread_mutex_t _mutex; +}; + +typedef PThreadMutex Mutex; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__MUTEX_PTHREAD_H diff --git a/engines/ags/engine/util/mutex_std.h b/engines/ags/engine/util/mutex_std.h new file mode 100644 index 000000000000..d86607956cf4 --- /dev/null +++ b/engines/ags/engine/util/mutex_std.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__MUTEX_STD_H +#define __AGS_EE_UTIL__MUTEX_STD_H + +#include + +namespace AGS +{ +namespace Engine +{ + +class StdMutex : public BaseMutex +{ + public: + inline StdMutex() : mutex_() {} + inline ~StdMutex() override = default; + + StdMutex &operator=(const StdMutex &) = delete; + StdMutex(const StdMutex &) = delete; + + inline void Lock() override { mutex_.lock(); } + inline void Unlock() override { mutex_.unlock(); } + + private: + std::recursive_mutex mutex_; +}; + +typedef StdMutex Mutex; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__MUTEX_STD_H diff --git a/engines/ags/engine/util/mutex_wii.h b/engines/ags/engine/util/mutex_wii.h new file mode 100644 index 000000000000..6aa376b2f477 --- /dev/null +++ b/engines/ags/engine/util/mutex_wii.h @@ -0,0 +1,60 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__WII_MUTEX_H +#define __AGS_EE_UTIL__WII_MUTEX_H + +#include + +namespace AGS +{ +namespace Engine +{ + + +class WiiMutex : public BaseMutex +{ +public: + inline WiiMutex() + { + LWP_MutexInit(&_mutex, 0); + } + + inline ~WiiMutex() + { + LWP_MutexDestroy(_mutex); + } + + inline void Lock() + { + LWP_MutexLock(_mutex); + } + + inline void Unlock() + { + LWP_MutexUnlock(_mutex); + } + +private: + mutex_t _mutex; +}; + + +typedef WiiMutex Mutex; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__WII_MUTEX_H diff --git a/engines/ags/engine/util/mutex_windows.h b/engines/ags/engine/util/mutex_windows.h new file mode 100644 index 000000000000..cf4c9157657f --- /dev/null +++ b/engines/ags/engine/util/mutex_windows.h @@ -0,0 +1,65 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_EE_UTIL__WINDOWS_MUTEX_H +#define __AGS_EE_UTIL__WINDOWS_MUTEX_H + +namespace AGS +{ +namespace Engine +{ + + +class WindowsMutex : public BaseMutex +{ +public: + WindowsMutex() + { + _mutex = CreateMutex(NULL, FALSE, NULL); + + _ASSERT(_mutex != NULL); + } + + ~WindowsMutex() + { + _ASSERT(_mutex != NULL); + + CloseHandle(_mutex); + } + + inline void Lock() + { + _ASSERT(_mutex != NULL); + + WaitForSingleObject(_mutex, INFINITE); + } + + inline void Unlock() + { + _ASSERT(_mutex != NULL); + + ReleaseMutex(_mutex); + } + +private: + HANDLE _mutex; +}; + + +typedef WindowsMutex Mutex; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__WINDOWS_MUTEX_H diff --git a/engines/ags/engine/util/scaling.h b/engines/ags/engine/util/scaling.h new file mode 100644 index 000000000000..a8f784754691 --- /dev/null +++ b/engines/ags/engine/util/scaling.h @@ -0,0 +1,173 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Helper struct for scaling coordinates +// +// TODO: rewrite into proper Transform class. +// Maybe implement as real matrix and/or floats if that is better/runs faster. +// +//============================================================================= +#ifndef __AGS_EE_UTIL__SCALING_H +#define __AGS_EE_UTIL__SCALING_H + +#include "core/types.h" +#include "util/geometry.h" + +namespace AGS +{ +namespace Engine +{ + +class AxisScaling +{ +public: + AxisScaling() + : _scale(kUnit) + , _unscale(kUnit) + , _srcOffset(0) + , _dstOffset(0) + { + } + + bool IsIdentity() const + { + return _scale == kUnit && _srcOffset == 0 && _dstOffset == 0; + } + + bool IsTranslateOnly() const + { + return _scale == kUnit; + } + + void Init(const int32_t src_length, const int32_t dst_length, const int32_t src_offset = 0, const int32_t dst_offset = 0) + { + _scale = kUnit; + _unscale = kUnit; + _srcOffset = src_offset; + _dstOffset = dst_offset; + + if (src_length != 0) + { + int32_t scale = (dst_length << kShift) / src_length; + if (scale != 0) + { + _scale = scale; + _unscale = scale; + int32_t scaled_val = ScaleDistance(src_length); + if (scaled_val < dst_length) + _scale++; + } + } + } + + void SetSrcOffset(int32_t x) + { + _srcOffset = x; + } + + void SetDstOffset(int32_t x) + { + _dstOffset = x; + } + + inline int32_t GetSrcOffset() const { return _srcOffset; } + + inline int32_t ScalePt(int32_t x) const + { + return (((x - _srcOffset) * _scale) >> kShift) + _dstOffset; + } + inline int32_t ScaleDistance(int32_t x) const + { + return ((x * _scale) >> kShift); + } + inline int32_t UnScalePt(int32_t x) const + { + return ((x - _dstOffset) << kShift) / _unscale + _srcOffset; + } + inline int32_t UnScaleDistance(int32_t x) const + { + return (x << kShift) / _unscale; + } + +private: + int32_t _scale; + int32_t _unscale; + int32_t _srcOffset; + int32_t _dstOffset; +}; + +struct PlaneScaling +{ + AxisScaling X; + AxisScaling Y; + + bool IsIdentity() const + { + return X.IsIdentity() && Y.IsIdentity(); + } + + bool IsTranslateOnly() const + { + return X.IsTranslateOnly() && Y.IsTranslateOnly(); + } + + void Init(const Size &src_size, const Rect &dst_rect) + { + X.Init(src_size.Width, dst_rect.GetWidth(), 0, dst_rect.Left); + Y.Init(src_size.Height, dst_rect.GetHeight(), 0, dst_rect.Top); + } + + void Init(const Rect &src_rect, const Rect &dst_rect) + { + X.Init(src_rect.GetWidth(), dst_rect.GetWidth(), src_rect.Left, dst_rect.Left); + Y.Init(src_rect.GetHeight(), dst_rect.GetHeight(), src_rect.Top, dst_rect.Top); + } + + void SetSrcOffsets(int x, int y) + { + X.SetSrcOffset(x); + Y.SetSrcOffset(y); + } + + void SetDestOffsets(int x, int y) + { + X.SetDstOffset(x); + Y.SetDstOffset(y); + } + + inline Point Scale(const Point p) const + { + return Point(X.ScalePt(p.X), Y.ScalePt(p.Y)); + } + + inline Rect ScaleRange(const Rect r) const + { + return RectWH(X.ScalePt(r.Left), Y.ScalePt(r.Top), X.ScaleDistance(r.GetWidth()), Y.ScaleDistance(r.GetHeight())); + } + + inline Point UnScale(const Point p) const + { + return Point(X.UnScalePt(p.X), Y.UnScalePt(p.Y)); + } + + inline Rect UnScaleRange(const Rect r) const + { + return RectWH(X.UnScalePt(r.Left), Y.UnScalePt(r.Top), X.UnScaleDistance(r.GetWidth()), Y.UnScaleDistance(r.GetHeight())); + } +}; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__SCALING_H diff --git a/engines/ags/engine/util/thread.h b/engines/ags/engine/util/thread.h new file mode 100644 index 000000000000..0f2bc1c16111 --- /dev/null +++ b/engines/ags/engine/util/thread.h @@ -0,0 +1,56 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__THREAD_H +#define __AGS_EE_UTIL__THREAD_H + +namespace AGS +{ +namespace Engine +{ + + +class BaseThread +{ +public: + typedef void(* AGSThreadEntry)(); + + BaseThread() = default; + virtual ~BaseThread() = default; + + BaseThread &operator=(const BaseThread &) = delete; + BaseThread(const BaseThread &) = delete; + + virtual bool Create(AGSThreadEntry entryPoint, bool looping) = 0; + virtual bool Start() = 0; + virtual bool Stop() = 0; + + inline bool CreateAndStart(AGSThreadEntry entryPoint, bool looping) + { + if (!Create(entryPoint, looping)) { return false; } + return Start(); + } +}; + +} // namespace Engine +} // namespace AGS + +#if 0 + // insert platforms here +#else +#include "thread_std.h" +#endif + + +#endif // __AGS_EE_UTIL__THREAD_H diff --git a/engines/ags/engine/util/thread_psp.h b/engines/ags/engine/util/thread_psp.h new file mode 100644 index 000000000000..eb4890425f06 --- /dev/null +++ b/engines/ags/engine/util/thread_psp.h @@ -0,0 +1,115 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_UTIL__PSP_THREAD_H +#define __AGS_EE_UTIL__PSP_THREAD_H + +#include +#include +#include + +namespace AGS +{ +namespace Engine +{ + + +class PSPThread : public BaseThread +{ +public: + PSPThread() + { + _thread = -1; + _entry = NULL; + _running = false; + _looping = false; + } + + ~PSPThread() + { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) + { + _looping = looping; + _entry = entryPoint; + _thread = sceKernelCreateThread("ags", _thread_start, 0x20, 0x10000, THREAD_ATTR_USER, 0); + + return (_thread > -1); + } + + inline bool Start() + { + if ((_thread > -1) && (!_running)) + { + PSPThread* thisPointer = this; + SceUID result = sceKernelStartThread(_thread, sizeof(this), &thisPointer); + + _running = (result > -1); + return _running; + } + else + { + return false; + } + } + + bool Stop() + { + if ((_thread > -1) && (_running)) + { + if (_looping) + { + _looping = false; + sceKernelWaitThreadEnd(_thread, 0); + } + + _running = false; + return (sceKernelTerminateDeleteThread(_thread) > -1); + } + else + { + return false; + } + } + +private: + SceUID _thread; + bool _running; + bool _looping; + + AGSThreadEntry _entry; + + static int _thread_start(SceSize args, void *argp) + { + AGSThreadEntry entry = (*(PSPThread **)argp)->_entry; + bool *looping = &(*(PSPThread **)argp)->_looping; + + do + { + entry(); + } + while (*looping); + } +}; + + +typedef PSPThread Thread; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_UTIL__PSP_THREAD_H diff --git a/engines/ags/engine/util/thread_pthread.h b/engines/ags/engine/util/thread_pthread.h new file mode 100644 index 000000000000..c1b1a95b7fea --- /dev/null +++ b/engines/ags/engine/util/thread_pthread.h @@ -0,0 +1,114 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_PLATFORM__THREAD_PTHREAD_H +#define __AGS_EE_PLATFORM__THREAD_PTHREAD_H + +#include + +namespace AGS +{ +namespace Engine +{ + + +class PThreadThread : public BaseThread +{ +public: + PThreadThread() + { + _thread = 0; + _entry = NULL; + _running = false; + _looping = false; + } + + ~PThreadThread() + { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) + { + _looping = looping; + _entry = entryPoint; + + // Thread creation is delayed till the thread is started + return true; + } + + inline bool Start() + { + if (!_running) + { + _running = (pthread_create(&_thread, NULL, _thread_start, this) == 0); + + return _running; + } + else + { + return false; + } + } + + bool Stop() + { + if (_running) + { + if (_looping) + { + _looping = false; + } + + pthread_join(_thread, NULL); + + _running = false; + return true; + } + else + { + return false; + } + } + +private: + pthread_t _thread; + bool _running; + bool _looping; + + AGSThreadEntry _entry; + + static void *_thread_start(void *arg) + { + AGSThreadEntry entry = ((PThreadThread *)arg)->_entry; + bool *looping = &((PThreadThread *)arg)->_looping; + + do + { + entry(); + } + while (*looping); + + return NULL; + } +}; + + +typedef PThreadThread Thread; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_PLATFORM__THREAD_PTHREAD_H diff --git a/engines/ags/engine/util/thread_std.h b/engines/ags/engine/util/thread_std.h new file mode 100644 index 000000000000..1868ff92263f --- /dev/null +++ b/engines/ags/engine/util/thread_std.h @@ -0,0 +1,97 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_PLATFORM__THREAD_STD_H +#define __AGS_EE_PLATFORM__THREAD_STD_H + +#include +#include + +namespace AGS +{ +namespace Engine +{ + +class StdThread : public BaseThread +{ +public: + StdThread() : thread_(), entry_(nullptr), looping_(false) + { + } + + ~StdThread() override + { + Stop(); + } + + StdThread &operator=(const StdThread &) = delete; + StdThread(const StdThread &) = delete; + + bool Create(AGSThreadEntry entryPoint, bool looping) override + { + if (!entryPoint) { return false; } + + entry_ = entryPoint; + looping_ = looping; + return true; + } + + bool Start() override + { + if (thread_.joinable()) { return true; } + if (!entry_) { return false; } + + try { + thread_ = std::thread(thread_start_, this); + } catch (std::system_error) { + return false; + } + return thread_.joinable(); + } + + bool Stop() override + { + if (!thread_.joinable()) { return true; } + + looping_ = false; // signal thread to stop + thread_.join(); + return true; + } + +private: + std::thread thread_; + AGSThreadEntry entry_; + bool looping_; + + static void thread_start_(StdThread *self) + { + auto entry = self->entry_; + for (;;) + { + entry(); + if (!self->looping_) + { + break; + } + std::this_thread::yield(); + } + } +}; + +typedef StdThread Thread; + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_PLATFORM__THREAD_STD_H diff --git a/engines/ags/engine/util/thread_wii.h b/engines/ags/engine/util/thread_wii.h new file mode 100644 index 000000000000..713a5e1ae471 --- /dev/null +++ b/engines/ags/engine/util/thread_wii.h @@ -0,0 +1,114 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_EE_PLATFORM__THREAD_WII_H +#define __AGS_EE_PLATFORM__THREAD_WII_H + +#include + +namespace AGS +{ +namespace Engine +{ + + +class WiiThread : public BaseThread +{ +public: + WiiThread() + { + _thread = (lwp_t)NULL; + _entry = NULL; + _running = false; + _looping = false; + } + + ~WiiThread() + { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) + { + _looping = looping; + _entry = entryPoint; + + // Thread creation is delayed till the thread is started + return true; + } + + inline bool Start() + { + if (!_running) + { + _running = (LWP_CreateThread(&_thread, _thread_start, this, 0, 8 * 1024, 64) != 0); + + return _running; + } + else + { + return false; + } + } + + bool Stop() + { + if (_running) + { + if (_looping) + { + _looping = false; + } + + LWP_JoinThread(_thread, NULL); + + _running = false; + return true; + } + else + { + return false; + } + } + +private: + lwp_t _thread; + bool _running; + bool _looping; + + AGSThreadEntry _entry; + + static void *_thread_start(void *arg) + { + AGSThreadEntry entry = ((WiiThread *)arg)->_entry; + bool *looping = &((WiiThread *)arg)->_looping; + + do + { + entry(); + } + while (*looping); + + return NULL; + } +}; + + +typedef WiiThread Thread; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_PLATFORM__THREAD_WII_H diff --git a/engines/ags/engine/util/thread_windows.h b/engines/ags/engine/util/thread_windows.h new file mode 100644 index 000000000000..c3938f12b671 --- /dev/null +++ b/engines/ags/engine/util/thread_windows.h @@ -0,0 +1,114 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_EE_PLATFORM__THREAD_WINDOWS_H +#define __AGS_EE_PLATFORM__THREAD_WINDOWS_H + +namespace AGS +{ +namespace Engine +{ + + +class WindowsThread : public BaseThread +{ +public: + WindowsThread() + { + _thread = NULL; + _entry = NULL; + _running = false; + _looping = false; + } + + ~WindowsThread() + { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) + { + _looping = looping; + _entry = entryPoint; + _thread = CreateThread(NULL, 0, _thread_start, this, CREATE_SUSPENDED, NULL); + + return (_thread != NULL); + } + + inline bool Start() + { + if ((_thread != NULL) && (!_running)) + { + DWORD result = ResumeThread(_thread); + + _running = (result != (DWORD) - 1); + return _running; + } + else + { + return false; + } + } + + bool Stop() + { + if ((_thread != NULL) && (_running)) + { + if (_looping) + { + _looping = false; + WaitForSingleObject(_thread, INFINITE); + } + + CloseHandle(_thread); + + _running = false; + _thread = NULL; + return true; + } + else + { + return false; + } + } + +private: + HANDLE _thread; + bool _running; + bool _looping; + + AGSThreadEntry _entry; + + static DWORD __stdcall _thread_start(LPVOID lpParam) + { + AGSThreadEntry entry = ((WindowsThread *)lpParam)->_entry; + bool *looping = &((WindowsThread *)lpParam)->_looping; + + do + { + entry(); + } + while (*looping); + + return 0; + } +}; + + +typedef WindowsThread Thread; + + +} // namespace Engine +} // namespace AGS + +#endif // __AGS_EE_PLATFORM__THREAD_WINDOWS_H diff --git a/engines/ags/shared/ac/audiocliptype.cpp b/engines/ags/shared/ac/audiocliptype.cpp new file mode 100644 index 000000000000..b2b6df92879c --- /dev/null +++ b/engines/ags/shared/ac/audiocliptype.cpp @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/audiocliptype.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +void AudioClipType::ReadFromFile(Stream *in) +{ + id = in->ReadInt32(); + reservedChannels = in->ReadInt32(); + volume_reduction_while_speech_playing = in->ReadInt32(); + crossfadeSpeed = in->ReadInt32(); + reservedForFuture = in->ReadInt32(); +} + +void AudioClipType::WriteToFile(Stream *out) +{ + out->WriteInt32(id); + out->WriteInt32(reservedChannels); + out->WriteInt32(volume_reduction_while_speech_playing); + out->WriteInt32(crossfadeSpeed); + out->WriteInt32(reservedForFuture); +} + +void AudioClipType::ReadFromSavegame(Common::Stream *in) +{ + volume_reduction_while_speech_playing = in->ReadInt32(); + crossfadeSpeed = in->ReadInt32(); +} + +void AudioClipType::WriteToSavegame(Common::Stream *out) const +{ + out->WriteInt32(volume_reduction_while_speech_playing); + out->WriteInt32(crossfadeSpeed); +} diff --git a/engines/ags/shared/ac/audiocliptype.h b/engines/ags/shared/ac/audiocliptype.h new file mode 100644 index 000000000000..66185a6fc012 --- /dev/null +++ b/engines/ags/shared/ac/audiocliptype.h @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_AUDIOCLIPTYPE_H +#define __AC_AUDIOCLIPTYPE_H + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define AUDIO_CLIP_TYPE_SOUND 1 +struct AudioClipType { + int id; + int reservedChannels; + int volume_reduction_while_speech_playing; + int crossfadeSpeed; + int reservedForFuture; + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; +}; + +#endif // __AC_AUDIOCLIPTYPE_H \ No newline at end of file diff --git a/engines/ags/shared/ac/characterinfo.cpp b/engines/ags/shared/ac/characterinfo.cpp new file mode 100644 index 000000000000..dbcbcf393476 --- /dev/null +++ b/engines/ags/shared/ac/characterinfo.cpp @@ -0,0 +1,155 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/characterinfo.h" +#include "util/stream.h" + +using AGS::Common::Stream; + + +void CharacterInfo::ReadFromFile(Stream *in) +{ + defview = in->ReadInt32(); + talkview = in->ReadInt32(); + view = in->ReadInt32(); + room = in->ReadInt32(); + prevroom = in->ReadInt32(); + x = in->ReadInt32(); + y = in->ReadInt32(); + wait = in->ReadInt32(); + flags = in->ReadInt32(); + following = in->ReadInt16(); + followinfo = in->ReadInt16(); + idleview = in->ReadInt32(); + idletime = in->ReadInt16(); + idleleft = in->ReadInt16(); + transparency = in->ReadInt16(); + baseline = in->ReadInt16(); + activeinv = in->ReadInt32(); + talkcolor = in->ReadInt32(); + thinkview = in->ReadInt32(); + blinkview = in->ReadInt16(); + blinkinterval = in->ReadInt16(); + blinktimer = in->ReadInt16(); + blinkframe = in->ReadInt16(); + walkspeed_y = in->ReadInt16(); + pic_yoffs = in->ReadInt16(); + z = in->ReadInt32(); + walkwait = in->ReadInt32(); + speech_anim_speed = in->ReadInt16(); + reserved1 = in->ReadInt16(); + blocking_width = in->ReadInt16(); + blocking_height = in->ReadInt16();; + index_id = in->ReadInt32(); + pic_xoffs = in->ReadInt16(); + walkwaitcounter = in->ReadInt16(); + loop = in->ReadInt16(); + frame = in->ReadInt16(); + walking = in->ReadInt16(); + animating = in->ReadInt16(); + walkspeed = in->ReadInt16(); + animspeed = in->ReadInt16(); + in->ReadArrayOfInt16(inv, MAX_INV); + actx = in->ReadInt16(); + acty = in->ReadInt16(); + in->Read(name, 40); + in->Read(scrname, MAX_SCRIPT_NAME_LEN); + on = in->ReadInt8(); +} + +void CharacterInfo::WriteToFile(Stream *out) +{ + out->WriteInt32(defview); + out->WriteInt32(talkview); + out->WriteInt32(view); + out->WriteInt32(room); + out->WriteInt32(prevroom); + out->WriteInt32(x); + out->WriteInt32(y); + out->WriteInt32(wait); + out->WriteInt32(flags); + out->WriteInt16(following); + out->WriteInt16(followinfo); + out->WriteInt32(idleview); + out->WriteInt16(idletime); + out->WriteInt16(idleleft); + out->WriteInt16(transparency); + out->WriteInt16(baseline); + out->WriteInt32(activeinv); + out->WriteInt32(talkcolor); + out->WriteInt32(thinkview); + out->WriteInt16(blinkview); + out->WriteInt16(blinkinterval); + out->WriteInt16(blinktimer); + out->WriteInt16(blinkframe); + out->WriteInt16(walkspeed_y); + out->WriteInt16(pic_yoffs); + out->WriteInt32(z); + out->WriteInt32(walkwait); + out->WriteInt16(speech_anim_speed); + out->WriteInt16(reserved1); + out->WriteInt16(blocking_width); + out->WriteInt16(blocking_height);; + out->WriteInt32(index_id); + out->WriteInt16(pic_xoffs); + out->WriteInt16(walkwaitcounter); + out->WriteInt16(loop); + out->WriteInt16(frame); + out->WriteInt16(walking); + out->WriteInt16(animating); + out->WriteInt16(walkspeed); + out->WriteInt16(animspeed); + out->WriteArrayOfInt16(inv, MAX_INV); + out->WriteInt16(actx); + out->WriteInt16(acty); + out->Write(name, 40); + out->Write(scrname, MAX_SCRIPT_NAME_LEN); + out->WriteInt8(on); +} + +void ConvertOldCharacterToNew (OldCharacterInfo *oci, CharacterInfo *ci) { + COPY_CHAR_VAR (defview); + COPY_CHAR_VAR (talkview); + COPY_CHAR_VAR (view); + COPY_CHAR_VAR (room); + COPY_CHAR_VAR (prevroom); + COPY_CHAR_VAR (x); + COPY_CHAR_VAR (y); + COPY_CHAR_VAR (wait); + COPY_CHAR_VAR (flags); + COPY_CHAR_VAR (following); + COPY_CHAR_VAR (followinfo); + COPY_CHAR_VAR (idleview); + COPY_CHAR_VAR (idletime); + COPY_CHAR_VAR (idleleft); + COPY_CHAR_VAR (transparency); + COPY_CHAR_VAR (baseline); + COPY_CHAR_VAR (activeinv); + COPY_CHAR_VAR (loop); + COPY_CHAR_VAR (frame); + COPY_CHAR_VAR (walking); + COPY_CHAR_VAR (animating); + COPY_CHAR_VAR (walkspeed); + COPY_CHAR_VAR (animspeed); + COPY_CHAR_VAR (actx); + COPY_CHAR_VAR (acty); + COPY_CHAR_VAR (on); + strcpy (ci->name, oci->name); + strcpy (ci->scrname, oci->scrname); + memcpy (&ci->inv[0], &oci->inv[0], sizeof(short) * 100); + // move the talking colour into the struct and remove from flags + ci->talkcolor = (oci->flags & OCHF_SPEECHCOL) >> OCHF_SPEECHCOLSHIFT; + ci->flags = ci->flags & (~OCHF_SPEECHCOL); +} diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h new file mode 100644 index 000000000000..f3140d156397 --- /dev/null +++ b/engines/ags/shared/ac/characterinfo.h @@ -0,0 +1,144 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_CHARACTERINFO_H +#define __AC_CHARACTERINFO_H + +#include "ac/common_defines.h" // constants + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define MAX_INV 301 +#define CHF_MANUALSCALING 1 +#define CHF_FIXVIEW 2 // between SetCharView and ReleaseCharView +#define CHF_NOINTERACT 4 +#define CHF_NODIAGONAL 8 +#define CHF_ALWAYSIDLE 0x10 +#define CHF_NOLIGHTING 0x20 +#define CHF_NOTURNING 0x40 +#define CHF_NOWALKBEHINDS 0x80 +#define CHF_FLIPSPRITE 0x100 // ?? Is this used?? +#define CHF_NOBLOCKING 0x200 +#define CHF_SCALEMOVESPEED 0x400 +#define CHF_NOBLINKANDTHINK 0x800 +#define CHF_SCALEVOLUME 0x1000 +#define CHF_HASTINT 0x2000 // engine only +#define CHF_BEHINDSHEPHERD 0x4000 // engine only +#define CHF_AWAITINGMOVE 0x8000 // engine only +#define CHF_MOVENOTWALK 0x10000 // engine only - do not do walk anim +#define CHF_ANTIGLIDE 0x20000 +#define CHF_HASLIGHT 0x40000 +// Speechcol is no longer part of the flags as of v2.5 +#define OCHF_SPEECHCOL 0xff000000 +#define OCHF_SPEECHCOLSHIFT 24 +#define UNIFORM_WALK_SPEED 0 +#define FOLLOW_ALWAYSONTOP 0x7ffe + +struct CharacterExtras; // forward declaration +// remember - if change this struct, also change AGSDEFNS.SH and +// plugin header file struct +struct CharacterInfo { + int defview; + int talkview; + int view; + int room, prevroom; + int x, y, wait; + int flags; + short following; + short followinfo; + int idleview; // the loop will be randomly picked + short idletime, idleleft; // num seconds idle before playing anim + short transparency; // if character is transparent + short baseline; + int activeinv; + int talkcolor; + int thinkview; + short blinkview, blinkinterval; // design time + short blinktimer, blinkframe; // run time + short walkspeed_y; + short pic_yoffs; // this is fixed in screen coordinates + int z; // z-location, for flying etc + int walkwait; + short speech_anim_speed, reserved1; // only 1 reserved left!! + short blocking_width, blocking_height; + int index_id; // used for object functions to know the id + short pic_xoffs; // this is fixed in screen coordinates + short walkwaitcounter; + short loop, frame; + short walking, animating; + short walkspeed, animspeed; + short inv[MAX_INV]; + short actx, acty; + char name[40]; + char scrname[MAX_SCRIPT_NAME_LEN]; + char on; + + int get_effective_y(); // return Y - Z + int get_baseline(); // return baseline, or Y if not set + int get_blocking_top(); // return Y - BlockingHeight/2 + int get_blocking_bottom(); // return Y + BlockingHeight/2 + + inline bool has_explicit_light() const { return (flags & CHF_HASLIGHT) != 0; } + inline bool has_explicit_tint() const { return (flags & CHF_HASTINT) != 0; } + + // [IKM] 2012-06-28: I still have to pass char_index to some of those functions + // either because they use it to set some variables with it, + // or because they pass it further to other functions, that are called from various places + // and it would be too much to change them all simultaneously + // + // [IKM] 2016-08-26: these methods should NOT be in CharacterInfo class, + // bit in distinct runtime character class! + void UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, int &numSheep, int *followingAsSheep); + void UpdateFollowingExactlyCharacter(); + + int update_character_walking(CharacterExtras *chex); + void update_character_moving(int &char_index, CharacterExtras *chex, int &doing_nothing); + int update_character_animating(int &char_index, int &doing_nothing); + void update_character_idle(CharacterExtras *chex, int &doing_nothing); + void update_character_follower(int &char_index, int &numSheep, int *followingAsSheep, int &doing_nothing); + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); +}; + + +struct OldCharacterInfo { + int defview; + int talkview; + int view; + int room, prevroom; + int x, y, wait; + int flags; + short following; + short followinfo; + int idleview; // the loop will be randomly picked + short idletime, idleleft; // num seconds idle before playing anim + short transparency; // if character is transparent + short baseline; + int activeinv; // this is an INT to support SeeR (no signed shorts) + short loop, frame; + short walking, animating; + short walkspeed, animspeed; + short inv[100]; + short actx, acty; + char name[30]; + char scrname[16]; + char on; +}; + +#define COPY_CHAR_VAR(name) ci->name = oci->name +void ConvertOldCharacterToNew (OldCharacterInfo *oci, CharacterInfo *ci); + +#endif // __AC_CHARACTERINFO_H \ No newline at end of file diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp new file mode 100644 index 000000000000..5db922c15a00 --- /dev/null +++ b/engines/ags/shared/ac/common.cpp @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" +#include "util/string.h" + +using namespace AGS::Common; + +const char *game_file_sig = "Adventure Creator Game File v2"; + +void quitprintf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + String text = String::FromFormatV(fmt, ap); + va_end(ap); + quit(text); +} diff --git a/engines/ags/shared/ac/common.h b/engines/ags/shared/ac/common.h new file mode 100644 index 000000000000..469605c32058 --- /dev/null +++ b/engines/ags/shared/ac/common.h @@ -0,0 +1,27 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_COMMON_H +#define __AC_COMMON_H + +// These are the project-dependent functions, they are defined both in Engine.App and AGS.Native. +void quit(const char *); +void quitprintf(const char *fmt, ...); +void update_polled_stuff_if_runtime(); +void set_our_eip(int eip); +int get_our_eip(); + +extern const char *game_file_sig; + +#endif // __AC_COMMON_H diff --git a/engines/ags/shared/ac/common_defines.h b/engines/ags/shared/ac/common_defines.h new file mode 100644 index 000000000000..dd70970dbb69 --- /dev/null +++ b/engines/ags/shared/ac/common_defines.h @@ -0,0 +1,123 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_DEFINES_H +#define __AC_DEFINES_H + +#include "core/platform.h" + +#define EXIT_NORMAL 0 +#define EXIT_CRASH 92 +#define EXIT_ERROR 93 + + +#if defined (OBSOLETE) +#define NUM_MISC 20 +#define NUMOTCON 7 // number of conditions before standing on +#define NUM_CONDIT (120 + NUMOTCON) +#endif + + + + +#define MAX_SCRIPT_NAME_LEN 20 + +//const int MISC_COND = MAX_WALK_BEHINDS * 4 + NUMOTCON + MAX_ROOM_OBJECTS * 4; + +// NUMCONDIT : whataction[0]: Char walks off left +// [1]: Char walks off right +// [2]: Char walks off bottom +// [3]: Char walks off top +// [4]: First enters screen +// [5]: Every time enters screen +// [6]: execute every loop +// [5]...[19]: Char stands on lookat type +// [20]...[35]: Look at type +// [36]...[49]: Action on type +// [50]...[65]: Use inv on type +// [66]...[75]: Look at object +// [76]...[85]: Action on object +// [86]...[95]: Speak to object +// [96]...[105]: Use inv on object +// [106]...[124]: Misc conditions 1-20 + +// game ver whataction[]= +// v1.00 0 : Go to screen +// 1 : Don't do anything +// 2 : Can't walk +// 3 : Man dies +// 4 : Run animation +// 5 : Display message +// 6 : Remove an object (set object.on=0) +// 7 : Remove object & add Val2 to inventory +// 8 : Add Val1 to inventory (Val2=num times) +// 9 : Run a script +// v1.00 SR-1 10 : Run graphical script +// v1.1 11 : Play sound effect SOUND%d.WAV +// v1.12 12 : Play FLI/FLC animation FLIC%d.FLC or FLIC%d.FLI +// 13 : Turn object on +// v2.00 14 : Run conversation +#define NUMRESPONSE 14 +#define NUMCOMMANDS 15 +#define GO_TO_SCREEN 0 +#define NO_ACTION 1 +#define NO_WALK 2 +#define MAN_DIES 3 +#define RUN_ANIMATE 4 +#define SHOW_MESSAGE 5 +#define OBJECT_OFF 6 +#define OBJECT_INV 7 +#define ADD_INV 8 +#define RUNSCRIPT 9 +#define GRAPHSCRIPT 10 +#define PLAY_SOUND 11 +#define PLAY_FLI 12 +#define OBJECT_ON 13 +#define RUN_DIALOG 14 + + +#define MAX_ROOMS 300 + +#define MAX_FLAGS 15 +#define LEGACY_MAXOBJNAMELEN 30 + +#define LEGACY_MAX_SPRITES_V25 6000 +#define LEGACY_MAX_SPRITES 30000 +#define MAX_CURSOR 20 + +#ifndef int32 +#define int32 int +#endif + +#if AGS_PLATFORM_OS_WINDOWS +#define AGS_INLINE inline +#else +// the linux compiler won't allow extern inline +#define AGS_INLINE +#endif + +// The game to screen coordinate conversion multiplier in hi-res type games +#define HIRES_COORD_MULTIPLIER 2 + +// object flags (currently only a char) +#define OBJF_NOINTERACT 1 // not clickable +#define OBJF_NOWALKBEHINDS 2 // ignore walk-behinds +#define OBJF_HASTINT 4 // the tint_* members are valid +#define OBJF_USEREGIONTINTS 8 // obey region tints/light areas +#define OBJF_USEROOMSCALING 0x10 // obey room scaling areas +#define OBJF_SOLID 0x20 // blocks characters from moving +#define OBJF_LEGACY_LOCKED 0x40 // object position is locked in the editor (OBSOLETE since 3.5.0) +#define OBJF_HASLIGHT 0x80 // the tint_light is valid and treated as brightness + +#endif // __AC_DEFINES_H diff --git a/engines/ags/shared/ac/dialogtopic.cpp b/engines/ags/shared/ac/dialogtopic.cpp new file mode 100644 index 000000000000..86d5dcd1836b --- /dev/null +++ b/engines/ags/shared/ac/dialogtopic.cpp @@ -0,0 +1,42 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dialogtopic.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +void DialogTopic::ReadFromFile(Stream *in) +{ + in->ReadArray(optionnames, 150*sizeof(char), MAXTOPICOPTIONS); + in->ReadArrayOfInt32(optionflags, MAXTOPICOPTIONS); + // optionscripts pointer is not used anywhere in the engine + optionscripts = nullptr; + in->ReadInt32(); // optionscripts 32-bit pointer + in->ReadArrayOfInt16(entrypoints, MAXTOPICOPTIONS); + startupentrypoint = in->ReadInt16(); + codesize = in->ReadInt16(); + numoptions = in->ReadInt32(); + topicFlags = in->ReadInt32(); +} + +void DialogTopic::ReadFromSavegame(Common::Stream *in) +{ + in->ReadArrayOfInt32(optionflags, MAXTOPICOPTIONS); +} + +void DialogTopic::WriteToSavegame(Common::Stream *out) const +{ + out->WriteArrayOfInt32(optionflags, MAXTOPICOPTIONS); +} diff --git a/engines/ags/shared/ac/dialogtopic.h b/engines/ags/shared/ac/dialogtopic.h new file mode 100644 index 000000000000..df259811bf47 --- /dev/null +++ b/engines/ags/shared/ac/dialogtopic.h @@ -0,0 +1,68 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_AC__DIALOGTOPIC_H +#define __AGS_CN_AC__DIALOGTOPIC_H + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +// [IKM] This is *conversation* dialog, not *gui* dialog, mind you! + +#define MAXTOPICOPTIONS 30 +#define DFLG_ON 1 // currently enabled +#define DFLG_OFFPERM 2 // off forever (can't be trurned on) +#define DFLG_NOREPEAT 4 // character doesn't repeat it when clicked +#define DFLG_HASBEENCHOSEN 8 // dialog option is 'read' +#define DTFLG_SHOWPARSER 1 // show parser in this topic +#define DCMD_SAY 1 +#define DCMD_OPTOFF 2 +#define DCMD_OPTON 3 +#define DCMD_RETURN 4 +#define DCMD_STOPDIALOG 5 +#define DCMD_OPTOFFFOREVER 6 +#define DCMD_RUNTEXTSCRIPT 7 +#define DCMD_GOTODIALOG 8 +#define DCMD_PLAYSOUND 9 +#define DCMD_ADDINV 10 +#define DCMD_SETSPCHVIEW 11 +#define DCMD_NEWROOM 12 +#define DCMD_SETGLOBALINT 13 +#define DCMD_GIVESCORE 14 +#define DCMD_GOTOPREVIOUS 15 +#define DCMD_LOSEINV 16 +#define DCMD_ENDSCRIPT 0xff +#define DCHAR_NARRATOR 999 +#define DCHAR_PLAYER 998 +struct DialogTopic { + char optionnames[MAXTOPICOPTIONS][150]; + int optionflags[MAXTOPICOPTIONS]; + unsigned char *optionscripts; + short entrypoints[MAXTOPICOPTIONS]; + short startupentrypoint; + short codesize; + int numoptions; + int topicFlags; + + void ReadFromFile(Common::Stream *in); + + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; +}; + + +#endif // __AGS_CN_AC__DIALOGTOPIC_H \ No newline at end of file diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp new file mode 100644 index 000000000000..0f1115d29e36 --- /dev/null +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp @@ -0,0 +1,32 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/dynobj/scriptaudioclip.h" +#include "util/stream.h" + +using namespace AGS::Common; + +void ScriptAudioClip::ReadFromFile(Stream *in) +{ + id = in->ReadInt32(); + scriptName.ReadCount(in, SCRIPTAUDIOCLIP_SCRIPTNAMELENGTH); + fileName.ReadCount(in, SCRIPTAUDIOCLIP_FILENAMELENGTH); + bundlingType = in->ReadInt8(); + type = in->ReadInt8(); + fileType = in->ReadInt8(); + defaultRepeat = in->ReadInt8(); + defaultPriority = in->ReadInt16(); + defaultVolume = in->ReadInt16(); + in->ReadInt32(); // reserved +} diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h new file mode 100644 index 000000000000..1349054ab70c --- /dev/null +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -0,0 +1,54 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H +#define __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H + +#include "util/string.h" + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +enum AudioFileType { + eAudioFileOGG = 1, + eAudioFileMP3 = 2, + eAudioFileWAV = 3, + eAudioFileVOC = 4, + eAudioFileMIDI = 5, + eAudioFileMOD = 6 +}; + +#define AUCL_BUNDLE_EXE 1 +#define AUCL_BUNDLE_VOX 2 + +#define SCRIPTAUDIOCLIP_SCRIPTNAMELENGTH 30 +#define SCRIPTAUDIOCLIP_FILENAMELENGTH 15 +struct ScriptAudioClip { + int id = 0; + Common::String scriptName; + Common::String fileName; + char bundlingType = AUCL_BUNDLE_EXE; + char type = 0; + char fileType = eAudioFileOGG; + char defaultRepeat = 0; + short defaultPriority = 50; + short defaultVolume = 100; + + void ReadFromFile(Common::Stream *in); +}; + +#endif // __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H diff --git a/engines/ags/shared/ac/game_version.h b/engines/ags/shared/ac/game_version.h new file mode 100644 index 000000000000..1c7ddeab52b9 --- /dev/null +++ b/engines/ags/shared/ac/game_version.h @@ -0,0 +1,146 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Game version constants and information +// +//============================================================================= + +#ifndef __AGS_CN_AC__GAMEVERSION_H +#define __AGS_CN_AC__GAMEVERSION_H + +/* + +Game data versions and changes: +------------------------------- + +12 : 2.3 + 2.4 + +Versions above are incompatible at the moment. + +18 : 2.5.0 +19 : 2.5.1 + 2.52 +20 : 2.5.3 + +Lip sync data added. +21 : 2.5.4 +22 : 2.5.5 + +Variable number of sprites. +24 : 2.5.6 +25 : 2.6.0 + +Encrypted global messages and dialogs. +26 : 2.6.1 + +Wait() must be called with parameter > 0 +GetRegionAt() clips the input values to the screen size +Color 0 now means transparent instead of black for text windows +SetPlayerCharacter() does nothing if the new character is already the player character. +27 : 2.6.2 + +Script modules. Fixes bug in the inventory display. +Clickable GUI is selected with regard for the drawing order. +Pointer to the "player" variable is now accessed via a dynamic object. +31 : 2.7.0 +32 : 2.7.2 + +35 : 3.0.0 + +Room names are serialized when game is compiled in "debug" mode. +36 : 3.0.1 + +Interactions are now scripts. The number for "not set" changed from 0 to -1 for +a lot of variables (views, sounds). +37 : 3.1.0 + +Dialogs are now scripts. New character animation speed. +39 : 3.1.1 + +Individual character speech animation speed. +40 : 3.1.2 + +Audio clips +41 : 3.2.0 +42 : 3.2.1 + +43 : 3.3.0 +Added few more game options. + +44 : 3.3.1 +Added custom dialog option highlight colour. + +45 : 3.4.0.1 +Support for custom game resolution. + +46 : 3.4.0.2-.3 +Audio playback speed. +Custom dialog option rendering extension. + +47 : 3.4.0.4 +Custom properties changed at runtime. +Ambient lighting + +48 : 3.4.1 +OPT_RENDERATSCREENRES, extended engine caps check, font vertical offset. + +49 : 3.4.1.2 +Font custom line spacing. + +50 : 3.5.0.8 +Sprites have "real" resolution. Expanded FontInfo data format. +Option to allow legacy relative asset resolutions. + +51 : +Fonts have adjustable outline + +*/ + +enum GameDataVersion +{ + kGameVersion_Undefined = 0, + kGameVersion_230 = 12, + kGameVersion_240 = 12, + kGameVersion_250 = 18, + kGameVersion_251 = 19, // same as 2.52 + kGameVersion_253 = 20, + kGameVersion_254 = 21, + kGameVersion_255 = 22, + kGameVersion_256 = 24, + kGameVersion_260 = 25, + kGameVersion_261 = 26, + kGameVersion_262 = 27, + kGameVersion_270 = 31, + kGameVersion_272 = 32, + kGameVersion_300 = 35, + kGameVersion_301 = 36, + kGameVersion_310 = 37, + kGameVersion_311 = 39, + kGameVersion_312 = 40, + kGameVersion_320 = 41, + kGameVersion_321 = 42, + kGameVersion_330 = 43, + kGameVersion_331 = 44, + kGameVersion_340_1 = 45, + kGameVersion_340_2 = 46, + kGameVersion_340_4 = 47, + kGameVersion_341 = 48, + kGameVersion_341_2 = 49, + kGameVersion_350 = 50, + kGameVersion_351 = 51, + kGameVersion_Current = kGameVersion_351 +}; + +extern GameDataVersion loaded_game_file_version; + +#endif // __AGS_CN_AC__GAMEVERSION_H diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp new file mode 100644 index 000000000000..1c8a2cbae3f1 --- /dev/null +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -0,0 +1,498 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/audiocliptype.h" +#include "ac/gamesetupstruct.h" +#include "ac/oldgamesetupstruct.h" +#include "ac/wordsdictionary.h" +#include "ac/dynobj/scriptaudioclip.h" +#include "game/interactions.h" +#include "util/alignedstream.h" + +using namespace AGS::Common; + +GameSetupStruct::GameSetupStruct() + : filever(0) + , roomCount(0) + , roomNumbers(nullptr) + , roomNames(nullptr) + , scoreClipID(0) +{ + memset(invinfo, 0, sizeof(invinfo)); + memset(mcurs, 0, sizeof(mcurs)); + memset(lipSyncFrameLetters, 0, sizeof(lipSyncFrameLetters)); + memset(guid, 0, sizeof(guid)); + memset(saveGameFileExtension, 0, sizeof(saveGameFileExtension)); + memset(saveGameFolderName, 0, sizeof(saveGameFolderName)); +} + +GameSetupStruct::~GameSetupStruct() +{ + Free(); +} + +void GameSetupStruct::Free() +{ + GameSetupStructBase::Free(); + + intrChar.clear(); + charScripts.clear(); + numcharacters = 0; + + // TODO: find out if it really needs to begin with 1 here? + for (size_t i = 1; i < (size_t)MAX_INV; i++) + intrInv[i].reset(); + invScripts.clear(); + numinvitems = 0; + + for (int i = 0; i < roomCount; i++) + delete roomNames[i]; + delete[] roomNames; + delete[] roomNumbers; + roomCount = 0; + + audioClips.clear(); + audioClipTypes.clear(); + + charProps.clear(); + viewNames.clear(); +} + +// Assigns font info parameters using legacy flags value read from the game data +void SetFontInfoFromLegacyFlags(FontInfo &finfo, const uint8_t data) +{ + finfo.Flags = (data >> 6) & 0xFF; + finfo.SizePt = data & FFLG_LEGACY_SIZEMASK; +} + +void AdjustFontInfoUsingFlags(FontInfo &finfo, const uint32_t flags) +{ + finfo.Flags = flags; + if ((flags & FFLG_SIZEMULTIPLIER) != 0) + { + finfo.SizeMultiplier = finfo.SizePt; + finfo.SizePt = 0; + } +} + +ScriptAudioClip* GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num) +{ + String clip_name; + if (is_music) + clip_name.Format("aMusic%d", num); + else + clip_name.Format("aSound%d", num); + + for (size_t i = 0; i < game.audioClips.size(); ++i) + { + if (clip_name.Compare(game.audioClips[i].scriptName) == 0) + return &game.audioClips[i]; + } + return nullptr; +} + +//----------------------------------------------------------------------------- +// Reading Part 1 + +void GameSetupStruct::read_savegame_info(Common::Stream *in, GameDataVersion data_ver) +{ + if (data_ver > kGameVersion_272) // only 3.x + { + in->Read(&guid[0], MAX_GUID_LENGTH); + in->Read(&saveGameFileExtension[0], MAX_SG_EXT_LENGTH); + in->Read(&saveGameFolderName[0], MAX_SG_FOLDER_LEN); + } +} + +void GameSetupStruct::read_font_infos(Common::Stream *in, GameDataVersion data_ver) +{ + fonts.resize(numfonts); + if (data_ver < kGameVersion_350) + { + for (int i = 0; i < numfonts; ++i) + SetFontInfoFromLegacyFlags(fonts[i], in->ReadInt8()); + for (int i = 0; i < numfonts; ++i) + fonts[i].Outline = in->ReadInt8(); // size of char + if (data_ver < kGameVersion_341) + return; + for (int i = 0; i < numfonts; ++i) + { + fonts[i].YOffset = in->ReadInt32(); + if (data_ver >= kGameVersion_341_2) + fonts[i].LineSpacing = Math::Max(0, in->ReadInt32()); + } + } + else + { + for (int i = 0; i < numfonts; ++i) + { + uint32_t flags = in->ReadInt32(); + fonts[i].SizePt = in->ReadInt32(); + fonts[i].Outline = in->ReadInt32(); + fonts[i].YOffset = in->ReadInt32(); + fonts[i].LineSpacing = Math::Max(0, in->ReadInt32()); + AdjustFontInfoUsingFlags(fonts[i], flags); + if (data_ver >= kGameVersion_351) + { + fonts[i].AutoOutlineThickness = in->ReadInt32(); + fonts[i].AutoOutlineStyle = + static_cast(in->ReadInt32()); + } + } + } +} + +void GameSetupStruct::ReadInvInfo_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) + { + invinfo[iteratorCount].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void GameSetupStruct::WriteInvInfo_Aligned(Stream *out) +{ + AlignedStream align_s(out, Common::kAligned_Write); + for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) + { + invinfo[iteratorCount].WriteToFile(&align_s); + align_s.Reset(); + } +} + +HGameFileError GameSetupStruct::read_cursors(Common::Stream *in, GameDataVersion data_ver) +{ + if (numcursors > MAX_CURSOR) + return new MainGameFileError(kMGFErr_TooManyCursors, String::FromFormat("Count: %d, max: %d", numcursors, MAX_CURSOR)); + + ReadMouseCursors_Aligned(in); + return HGameFileError::None(); +} + +void GameSetupStruct::read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver) +{ + numGlobalVars = 0; + + if (data_ver > kGameVersion_272) // 3.x + { + charScripts.resize(numcharacters); + invScripts.resize(numinvitems); + for (size_t i = 0; i < (size_t)numcharacters; ++i) + charScripts[i].reset(InteractionScripts::CreateFromStream(in)); + // NOTE: new inventory items' events are loaded starting from 1 for some reason + for (size_t i = 1; i < (size_t)numinvitems; ++i) + invScripts[i].reset(InteractionScripts::CreateFromStream(in)); + } + else // 2.x + { + intrChar.resize(numcharacters); + for (size_t i = 0; i < (size_t)numcharacters; ++i) + intrChar[i].reset(Interaction::CreateFromStream(in)); + for (size_t i = 0; i < (size_t)numinvitems; ++i) + intrInv[i].reset(Interaction::CreateFromStream(in)); + + numGlobalVars = in->ReadInt32(); + for (size_t i = 0; i < (size_t)numGlobalVars; ++i) + globalvars[i].Read(in); + } +} + +void GameSetupStruct::read_words_dictionary(Common::Stream *in) +{ + if (load_dictionary) { + dict = new WordsDictionary(); + read_dictionary (dict, in); + } +} + +void GameSetupStruct::ReadMouseCursors_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) + { + mcurs[iteratorCount].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void GameSetupStruct::WriteMouseCursors_Aligned(Stream *out) +{ + AlignedStream align_s(out, Common::kAligned_Write); + for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) + { + mcurs[iteratorCount].WriteToFile(&align_s); + align_s.Reset(); + } +} + +//----------------------------------------------------------------------------- +// Reading Part 2 + +void GameSetupStruct::read_characters(Common::Stream *in, GameDataVersion data_ver) +{ + chars = new CharacterInfo[numcharacters + 5]; // TODO: why +5, is this really needed? + + ReadCharacters_Aligned(in); +} + +void GameSetupStruct::read_lipsync(Common::Stream *in, GameDataVersion data_ver) +{ + if (data_ver >= kGameVersion_254) // lip syncing was introduced in 2.54 + in->ReadArray(&lipSyncFrameLetters[0][0], MAXLIPSYNCFRAMES, 50); +} + +void GameSetupStruct::read_messages(Common::Stream *in, GameDataVersion data_ver) +{ + for (int ee=0;eeReadInt8(); + if (*nextchar == 0) + break; + nextchar++; + } + } + else + read_string_decrypt(in, messages[ee], GLOBALMESLENGTH); + } + delete [] load_messages; + load_messages = nullptr; +} + +void GameSetupStruct::ReadCharacters_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) + { + chars[iteratorCount].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void GameSetupStruct::WriteCharacters_Aligned(Stream *out) +{ + AlignedStream align_s(out, Common::kAligned_Write); + for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) + { + chars[iteratorCount].WriteToFile(&align_s); + align_s.Reset(); + } +} + +//----------------------------------------------------------------------------- +// Reading Part 3 + +HGameFileError GameSetupStruct::read_customprops(Common::Stream *in, GameDataVersion data_ver) +{ + dialogScriptNames.resize(numdialog); + viewNames.resize(numviews); + if (data_ver >= kGameVersion_260) // >= 2.60 + { + if (Properties::ReadSchema(propSchema, in) != kPropertyErr_NoError) + return new MainGameFileError(kMGFErr_InvalidPropertySchema); + + int errors = 0; + + charProps.resize(numcharacters); + for (int i = 0; i < numcharacters; ++i) + { + errors += Properties::ReadValues(charProps[i], in); + } + for (int i = 0; i < numinvitems; ++i) + { + errors += Properties::ReadValues(invProps[i], in); + } + + if (errors > 0) + return new MainGameFileError(kMGFErr_InvalidPropertyValues); + + for (int i = 0; i < numviews; ++i) + viewNames[i] = String::FromStream(in); + + for (int i = 0; i < numinvitems; ++i) + invScriptNames[i] = String::FromStream(in); + + for (int i = 0; i < numdialog; ++i) + dialogScriptNames[i] = String::FromStream(in); + } + return HGameFileError::None(); +} + +HGameFileError GameSetupStruct::read_audio(Common::Stream *in, GameDataVersion data_ver) +{ + if (data_ver >= kGameVersion_320) + { + size_t audiotype_count = in->ReadInt32(); + audioClipTypes.resize(audiotype_count); + for (size_t i = 0; i < audiotype_count; ++i) + { + audioClipTypes[i].ReadFromFile(in); + } + + size_t audioclip_count = in->ReadInt32(); + audioClips.resize(audioclip_count); + ReadAudioClips_Aligned(in, audioclip_count); + + scoreClipID = in->ReadInt32(); + } + return HGameFileError::None(); +} + +// Temporarily copied this from acruntim.h; +// it is unknown if this should be defined for all solution, or only runtime +#define STD_BUFFER_SIZE 3000 + +void GameSetupStruct::read_room_names(Stream *in, GameDataVersion data_ver) +{ + if ((data_ver >= kGameVersion_301) && (options[OPT_DEBUGMODE] != 0)) + { + roomCount = in->ReadInt32(); + roomNumbers = new int[roomCount]; + roomNames = new char*[roomCount]; + String pexbuf; + for (int bb = 0; bb < roomCount; bb++) + { + roomNumbers[bb] = in->ReadInt32(); + pexbuf.Read(in, STD_BUFFER_SIZE); + roomNames[bb] = new char[pexbuf.GetLength() + 1]; + strcpy(roomNames[bb], pexbuf); + } + } + else + { + roomCount = 0; + } +} + +void GameSetupStruct::ReadAudioClips_Aligned(Common::Stream *in, size_t count) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (size_t i = 0; i < count; ++i) + { + audioClips[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void GameSetupStruct::ReadFromSaveGame_v321(Stream *in, char* gswas, ccScript* compsc, CharacterInfo* chwas, + WordsDictionary *olddict, char** mesbk) +{ + int bb; + + ReadInvInfo_Aligned(in); + ReadMouseCursors_Aligned(in); + + if (loaded_game_file_version <= kGameVersion_272) + { + for (bb = 0; bb < numinvitems; bb++) + intrInv[bb]->ReadTimesRunFromSave_v321(in); + for (bb = 0; bb < numcharacters; bb++) + intrChar[bb]->ReadTimesRunFromSave_v321(in); + } + + // restore pointer members + globalscript=gswas; + compiled_script=compsc; + chars=chwas; + dict = olddict; + for (int vv=0;vvReadArrayOfInt32(&options[0], OPT_HIGHESTOPTION_321 + 1); + options[OPT_LIPSYNCTEXT] = in->ReadByte(); + + ReadCharacters_Aligned(in); +} + +//============================================================================= + +void ConvertOldGameStruct (OldGameSetupStruct *ogss, GameSetupStruct *gss) { + strcpy (gss->gamename, ogss->gamename); + for (int i = 0; i < 20; i++) + gss->options[i] = ogss->options[i]; + memcpy (&gss->paluses[0], &ogss->paluses[0], 256); + memcpy (&gss->defpal[0], &ogss->defpal[0], 256 * sizeof(color)); + gss->numviews = ogss->numviews; + gss->numcharacters = ogss->numcharacters; + gss->playercharacter = ogss->playercharacter; + gss->totalscore = ogss->totalscore; + gss->numinvitems = ogss->numinvitems; + gss->numdialog = ogss->numdialog; + gss->numdlgmessage = ogss->numdlgmessage; + gss->numfonts = ogss->numfonts; + gss->color_depth = ogss->color_depth; + gss->target_win = ogss->target_win; + gss->dialog_bullet = ogss->dialog_bullet; + gss->hotdot = ogss->hotdot; + gss->hotdotouter = ogss->hotdotouter; + gss->uniqueid = ogss->uniqueid; + gss->numgui = ogss->numgui; + for (int i = 0; i < 10; ++i) + { + SetFontInfoFromLegacyFlags(gss->fonts[i], ogss->fontflags[i]); + gss->fonts[i].Outline = ogss->fontoutline[i]; + } + + for (int i = 0; i < LEGACY_MAX_SPRITES_V25; ++i) + { + gss->SpriteInfos[i].Flags = ogss->spriteflags[i]; + } + + memcpy (&gss->invinfo[0], &ogss->invinfo[0], 100 * sizeof(InventoryItemInfo)); + memcpy (&gss->mcurs[0], &ogss->mcurs[0], 10 * sizeof(MouseCursor)); + for (int i = 0; i < MAXGLOBALMES; i++) + gss->messages[i] = ogss->messages[i]; + gss->dict = ogss->dict; + gss->globalscript = ogss->globalscript; + gss->chars = nullptr; //ogss->chars; + gss->compiled_script = ogss->compiled_script; + gss->numcursors = 10; +} + +void GameSetupStruct::ReadFromSavegame(PStream in) +{ + // of GameSetupStruct + in->ReadArrayOfInt32(options, OPT_HIGHESTOPTION_321 + 1); + options[OPT_LIPSYNCTEXT] = in->ReadInt32(); + // of GameSetupStructBase + playercharacter = in->ReadInt32(); + dialog_bullet = in->ReadInt32(); + hotdot = in->ReadInt16(); + hotdotouter = in->ReadInt16(); + invhotdotsprite = in->ReadInt32(); + default_lipsync_frame = in->ReadInt32(); +} + +void GameSetupStruct::WriteForSavegame(PStream out) +{ + // of GameSetupStruct + out->WriteArrayOfInt32(options, OPT_HIGHESTOPTION_321 + 1); + out->WriteInt32(options[OPT_LIPSYNCTEXT]); + // of GameSetupStructBase + out->WriteInt32(playercharacter); + out->WriteInt32(dialog_bullet); + out->WriteInt16(hotdot); + out->WriteInt16(hotdotouter); + out->WriteInt32(invhotdotsprite); + out->WriteInt32(default_lipsync_frame); +} diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h new file mode 100644 index 000000000000..322fd4f453ed --- /dev/null +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -0,0 +1,165 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_AC__GAMESETUPSTRUCT_H +#define __AGS_CN_AC__GAMESETUPSTRUCT_H + +#include +#include "ac/audiocliptype.h" +#include "ac/characterinfo.h" // TODO: constants to separate header +#include "ac/gamesetupstructbase.h" +#include "ac/inventoryiteminfo.h" +#include "ac/mousecursor.h" +#include "ac/dynobj/scriptaudioclip.h" +#include "game/customproperties.h" +#include "game/main_game_file.h" // TODO: constants to separate header or split out reading functions + +namespace AGS +{ + namespace Common + { + struct AssetLibInfo; + struct Interaction; + struct InteractionScripts; + typedef std::shared_ptr PInteraction; + typedef std::shared_ptr PInteractionScripts; + } +} + +using AGS::Common::PInteraction; +using AGS::Common::PInteractionScripts; +using AGS::Common::HGameFileError; +struct OldGameSetupStruct; + + +// TODO: split GameSetupStruct into struct used to hold loaded game data, and actual runtime object +struct GameSetupStruct: public GameSetupStructBase { + // This array is used only to read data into; + // font parameters are then put and queried in the fonts module + // TODO: split into installation params (used only when reading) and runtime params + std::vector fonts; + InventoryItemInfo invinfo[MAX_INV]; + MouseCursor mcurs[MAX_CURSOR]; + std::vector intrChar; + PInteraction intrInv[MAX_INV]; + std::vector charScripts; + std::vector invScripts; + // TODO: why we do not use this in the engine instead of + // loaded_game_file_version? + int filever; // just used by editor + Common::String compiled_with; // version of AGS this data was created by + char lipSyncFrameLetters[MAXLIPSYNCFRAMES][50]; + AGS::Common::PropertySchema propSchema; + std::vector charProps; + AGS::Common::StringIMap invProps[MAX_INV]; + // NOTE: although the view names are stored in game data, they are never + // used, nor registered as script exports; numeric IDs are used to + // reference views instead. + std::vector viewNames; + Common::String invScriptNames[MAX_INV]; + std::vector dialogScriptNames; + char guid[MAX_GUID_LENGTH]; + char saveGameFileExtension[MAX_SG_EXT_LENGTH]; + char saveGameFolderName[MAX_SG_FOLDER_LEN]; + int roomCount; + int *roomNumbers; + char **roomNames; + std::vector audioClips; + std::vector audioClipTypes; + // A clip to play when player gains score in game + // TODO: find out why OPT_SCORESOUND option cannot be used to store this in >=3.2 games + int scoreClipID; + + // TODO: I converted original array of sprite infos to vector here, because + // statistically in most games sprites go in long continious sequences with minimal + // gaps, and standard hash-map will have relatively big memory overhead compared. + // Of course vector will not behave very well if user has created e.g. only + // sprite #1 and sprite #1000000. For that reason I decided to still limit static + // sprite count to some reasonable number for the time being. Dynamic sprite IDs are + // added in sequence, so there won't be any issue with these. + // There could be other collection types, more optimal for this case. For example, + // we could use a kind of hash map containing fixed-sized arrays, where size of + // array is calculated based on key spread factor. + std::vector SpriteInfos; + + // Get game's native color depth (bits per pixel) + inline int GetColorDepth() const { return color_depth * 8; } + + + GameSetupStruct(); + ~GameSetupStruct(); + + void Free(); + + // [IKM] Game struct loading code is moved here from Engine's load_game_file + // function; for now it is not supposed to be called by Editor; although it + // is possible that eventually will be. + // + // Since reading game data is made in a bit inconvenient way I had to + // a) divide process into three functions (there's some extra stuff + // being read between them; + // b) use a helper struct to pass some arguments + // + // I also had to move BuildAudioClipArray from the engine and make it + // GameSetupStruct member. + + //-------------------------------------------------------------------- + // Do not call these directly + //------------------------------ + // Part 1 + void read_savegame_info(Common::Stream *in, GameDataVersion data_ver); + void read_font_infos(Common::Stream *in, GameDataVersion data_ver); + HGameFileError read_cursors(Common::Stream *in, GameDataVersion data_ver); + void read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver); + void read_words_dictionary(Common::Stream *in); + + void ReadInvInfo_Aligned(Common::Stream *in); + void WriteInvInfo_Aligned(Common::Stream *out); + void ReadMouseCursors_Aligned(Common::Stream *in); + void WriteMouseCursors_Aligned(Common::Stream *out); + //------------------------------ + // Part 2 + void read_characters(Common::Stream *in, GameDataVersion data_ver); + void read_lipsync(Common::Stream *in, GameDataVersion data_ver); + void read_messages(Common::Stream *in, GameDataVersion data_ver); + + void ReadCharacters_Aligned(Common::Stream *in); + void WriteCharacters_Aligned(Common::Stream *out); + //------------------------------ + // Part 3 + HGameFileError read_customprops(Common::Stream *in, GameDataVersion data_ver); + HGameFileError read_audio(Common::Stream *in, GameDataVersion data_ver); + void read_room_names(Common::Stream *in, GameDataVersion data_ver); + + void ReadAudioClips_Aligned(Common::Stream *in, size_t count); + //-------------------------------------------------------------------- + + // Functions for reading and writing appropriate data from/to save game + void ReadFromSaveGame_v321(Common::Stream *in, char* gswas, ccScript* compsc, CharacterInfo* chwas, + WordsDictionary *olddict, char** mesbk); + + void ReadFromSavegame(Common::PStream in); + void WriteForSavegame(Common::PStream out); +}; + +//============================================================================= +// TODO: find out how this function was supposed to be used +void ConvertOldGameStruct (OldGameSetupStruct *ogss, GameSetupStruct *gss); +// Finds an audio clip using legacy convention index +ScriptAudioClip* GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num); + +#endif // __AGS_CN_AC__GAMESETUPSTRUCT_H diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp new file mode 100644 index 000000000000..f3cbe33b803f --- /dev/null +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -0,0 +1,267 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/characterinfo.h" +#include "ac/gamesetupstructbase.h" +#include "ac/game_version.h" +#include "ac/wordsdictionary.h" +#include "script/cc_script.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +GameSetupStructBase::GameSetupStructBase() + : numviews(0) + , numcharacters(0) + , playercharacter(-1) + , totalscore(0) + , numinvitems(0) + , numdialog(0) + , numdlgmessage(0) + , numfonts(0) + , color_depth(0) + , target_win(0) + , dialog_bullet(0) + , hotdot(0) + , hotdotouter(0) + , uniqueid(0) + , numgui(0) + , numcursors(0) + , default_lipsync_frame(0) + , invhotdotsprite(0) + , dict(nullptr) + , globalscript(nullptr) + , chars(nullptr) + , compiled_script(nullptr) + , load_messages(nullptr) + , load_dictionary(false) + , load_compiled_script(false) + , _resolutionType(kGameResolution_Undefined) + , _dataUpscaleMult(1) + , _screenUpscaleMult(1) +{ + memset(gamename, 0, sizeof(gamename)); + memset(options, 0, sizeof(options)); + memset(paluses, 0, sizeof(paluses)); + memset(defpal, 0, sizeof(defpal)); + memset(reserved, 0, sizeof(reserved)); + memset(messages, 0, sizeof(messages)); +} + +GameSetupStructBase::~GameSetupStructBase() +{ + Free(); +} + +void GameSetupStructBase::Free() +{ + for (int i = 0; i < MAXGLOBALMES; ++i) + { + delete[] messages[i]; + messages[i] = nullptr; + } + delete[] load_messages; + load_messages = nullptr; + delete dict; + dict = nullptr; + delete globalscript; + globalscript = nullptr; + delete compiled_script; + compiled_script = nullptr; + delete[] chars; + chars = nullptr; +} + +void GameSetupStructBase::SetDefaultResolution(GameResolutionType type) +{ + SetDefaultResolution(type, Size()); +} + +void GameSetupStructBase::SetDefaultResolution(Size size) +{ + SetDefaultResolution(kGameResolution_Custom, size); +} + +void GameSetupStructBase::SetDefaultResolution(GameResolutionType type, Size size) +{ + // Calculate native res first then remember it + SetNativeResolution(type, size); + _defGameResolution = _gameResolution; + // Setup data resolution according to legacy settings (if set) + _dataResolution = _defGameResolution; + if (IsLegacyHiRes() && options[OPT_NATIVECOORDINATES] == 0) + { + _dataResolution = _defGameResolution / HIRES_COORD_MULTIPLIER; + } + OnResolutionSet(); +} + +void GameSetupStructBase::SetNativeResolution(GameResolutionType type, Size game_res) +{ + if (type == kGameResolution_Custom) + { + _resolutionType = kGameResolution_Custom; + _gameResolution = game_res; + _letterboxSize = _gameResolution; + } + else + { + _resolutionType = type; + _gameResolution = ResolutionTypeToSize(_resolutionType, IsLegacyLetterbox()); + _letterboxSize = ResolutionTypeToSize(_resolutionType, false); + } +} + +void GameSetupStructBase::SetGameResolution(GameResolutionType type) +{ + SetNativeResolution(type, Size()); + OnResolutionSet(); +} + +void GameSetupStructBase::SetGameResolution(Size game_res) +{ + SetNativeResolution(kGameResolution_Custom, game_res); + OnResolutionSet(); +} + +void GameSetupStructBase::OnResolutionSet() +{ + // The final data-to-game multiplier is always set after actual game resolution (not default one) + if (!_dataResolution.IsNull()) + _dataUpscaleMult = _gameResolution.Width / _dataResolution.Width; + else + _dataUpscaleMult = 1; + if (!_defGameResolution.IsNull()) + _screenUpscaleMult = _gameResolution.Width / _defGameResolution.Width; + else + _screenUpscaleMult = 1; + _relativeUIMult = IsLegacyHiRes() ? HIRES_COORD_MULTIPLIER : 1; +} + +void GameSetupStructBase::ReadFromFile(Stream *in) +{ + in->Read(&gamename[0], GAME_NAME_LENGTH); + in->ReadArrayOfInt32(options, MAX_OPTIONS); + if (loaded_game_file_version < kGameVersion_340_4) + { // TODO: this should probably be possible to deduce script API level + // using game data version and other options like OPT_STRICTSCRIPTING + options[OPT_BASESCRIPTAPI] = kScriptAPI_Undefined; + options[OPT_SCRIPTCOMPATLEV] = kScriptAPI_Undefined; + } + in->Read(&paluses[0], 256); + // colors are an array of chars + in->Read(&defpal[0], sizeof(color)*256); + numviews = in->ReadInt32(); + numcharacters = in->ReadInt32(); + playercharacter = in->ReadInt32(); + totalscore = in->ReadInt32(); + numinvitems = in->ReadInt16(); + numdialog = in->ReadInt32(); + numdlgmessage = in->ReadInt32(); + numfonts = in->ReadInt32(); + color_depth = in->ReadInt32(); + target_win = in->ReadInt32(); + dialog_bullet = in->ReadInt32(); + hotdot = in->ReadInt16(); + hotdotouter = in->ReadInt16(); + uniqueid = in->ReadInt32(); + numgui = in->ReadInt32(); + numcursors = in->ReadInt32(); + GameResolutionType resolution_type = (GameResolutionType)in->ReadInt32(); + Size game_size; + if (resolution_type == kGameResolution_Custom && loaded_game_file_version >= kGameVersion_330) + { + game_size.Width = in->ReadInt32(); + game_size.Height = in->ReadInt32(); + } + SetDefaultResolution(resolution_type, game_size); + + default_lipsync_frame = in->ReadInt32(); + invhotdotsprite = in->ReadInt32(); + in->ReadArrayOfInt32(reserved, NUM_INTS_RESERVED); + load_messages = new int32_t[MAXGLOBALMES]; + in->ReadArrayOfInt32(load_messages, MAXGLOBALMES); + + // - GameSetupStruct::read_words_dictionary() checks load_dictionary + // - load_game_file() checks load_compiled_script + load_dictionary = in->ReadInt32() != 0; + in->ReadInt32(); // globalscript + in->ReadInt32(); // chars + load_compiled_script = in->ReadInt32() != 0; +} + +void GameSetupStructBase::WriteToFile(Stream *out) +{ + out->Write(&gamename[0], 50); + out->WriteArrayOfInt32(options, 100); + out->Write(&paluses[0], 256); + // colors are an array of chars + out->Write(&defpal[0], sizeof(color)*256); + out->WriteInt32(numviews); + out->WriteInt32(numcharacters); + out->WriteInt32(playercharacter); + out->WriteInt32(totalscore); + out->WriteInt16(numinvitems); + out->WriteInt32(numdialog); + out->WriteInt32(numdlgmessage); + out->WriteInt32(numfonts); + out->WriteInt32(color_depth); + out->WriteInt32(target_win); + out->WriteInt32(dialog_bullet); + out->WriteInt16(hotdot); + out->WriteInt16(hotdotouter); + out->WriteInt32(uniqueid); + out->WriteInt32(numgui); + out->WriteInt32(numcursors); + out->WriteInt32(_resolutionType); + if (_resolutionType == kGameResolution_Custom) + { + out->WriteInt32(_defGameResolution.Width); + out->WriteInt32(_defGameResolution.Height); + } + out->WriteInt32(default_lipsync_frame); + out->WriteInt32(invhotdotsprite); + out->WriteArrayOfInt32(reserved, 17); + for (int i = 0; i < MAXGLOBALMES; ++i) + { + out->WriteInt32(messages[i] ? 1 : 0); + } + out->WriteInt32(dict ? 1 : 0); + out->WriteInt32(0); // globalscript + out->WriteInt32(0); // chars + out->WriteInt32(compiled_script ? 1 : 0); +} + +Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox) +{ + switch (resolution) + { + case kGameResolution_Default: + case kGameResolution_320x200: + return letterbox ? Size(320, 240) : Size(320, 200); + case kGameResolution_320x240: + return Size(320, 240); + case kGameResolution_640x400: + return letterbox ? Size(640, 480) : Size(640, 400); + case kGameResolution_640x480: + return Size(640, 480); + case kGameResolution_800x600: + return Size(800, 600); + case kGameResolution_1024x768: + return Size(1024, 768); + case kGameResolution_1280x720: + return Size(1280,720); + } + return Size(); +} diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h new file mode 100644 index 000000000000..1b075834e7f0 --- /dev/null +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -0,0 +1,222 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_AC__GAMESETUPSTRUCTBASE_H +#define __AGS_CN_AC__GAMESETUPSTRUCTBASE_H + +#include "ac/game_version.h" +#include "ac/gamestructdefines.h" +#include "util/string.h" +#include "util/wgt2allg.h" // color (allegro RGB) + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +struct WordsDictionary; +struct CharacterInfo; +struct ccScript; + + +struct GameSetupStructBase { + static const int GAME_NAME_LENGTH = 50; + static const int MAX_OPTIONS = 100; + static const int NUM_INTS_RESERVED = 17; + + char gamename[GAME_NAME_LENGTH]; + int options[MAX_OPTIONS]; + unsigned char paluses[256]; + color defpal[256]; + int numviews; + int numcharacters; + int playercharacter; + int totalscore; + short numinvitems; + int numdialog, numdlgmessage; + int numfonts; + int color_depth; // in bytes per pixel (ie. 1 or 2) + int target_win; + int dialog_bullet; // 0 for none, otherwise slot num of bullet point + unsigned short hotdot, hotdotouter; // inv cursor hotspot dot color + int uniqueid; // random key identifying the game + int numgui; + int numcursors; + int default_lipsync_frame; // used for unknown chars + int invhotdotsprite; + int reserved[NUM_INTS_RESERVED]; + char *messages[MAXGLOBALMES]; + WordsDictionary *dict; + char *globalscript; + CharacterInfo *chars; + ccScript *compiled_script; + + int *load_messages; + bool load_dictionary; + bool load_compiled_script; + // [IKM] 2013-03-30 + // NOTE: it looks like nor 'globalscript', not 'compiled_script' are used + // to store actual script data anytime; 'ccScript* gamescript' global + // pointer is used for that instead. + + GameSetupStructBase(); + ~GameSetupStructBase(); + void Free(); + void SetDefaultResolution(GameResolutionType type); + void SetDefaultResolution(Size game_res); + void SetGameResolution(GameResolutionType type); + void SetGameResolution(Size game_res); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + + + // + // ** On game resolution. + // + // Game resolution is a size of a native game screen in pixels. + // This is the "game resolution" that developer sets up in AGS Editor. + // It is in the same units in which sprite and font sizes are defined. + // + // Graphic renderer may scale and stretch game's frame as requested by + // player or system, which will not affect native coordinates in any way. + // + // ** Legacy upscale mode. + // + // In the past engine had a separation between logical and native screen + // coordinates and supported running games "upscaled". E.g. 320x200 games + // could be run as 640x400. This was not done by simply stretching final + // game's drawn frame to the larger window, but by multiplying all data + // containing coordinates and graphics either on load or real-time. + // Games of 640x400 and above were scripted and set up in coordinate units + // that were always x2 times smaller than the one developer chose. + // For example, choosing a 640x400 resolution would make game draw itself + // as 640x400, but all the game logic (object properties, script commands) + // would work in 320x200 (this also let run 640x400 downscaled to 320x200). + // Ignoring the obvious complications, the known benefit from such approach + // was that developers could supply separate sets of fonts and sprites for + // low-res and high-res modes. + // The 3rd generation of AGS still allows to achieve same effect by using + // backwards-compatible option (although it is not recommended except when + // importing and continuing old projects). + // + // In order to support this legacy behavior we have a set of functions for + // coordinate conversion. They are required to move from "data" resolution + // to "final game" resolution and back. + // + // Some of the script commands, as well as some internal engine data use + // coordinates in "game resolution" instead (this should be documented). + // In such case there's another conversion which translates these from + // default to actual resolution; e.g. when 320x200 game is run as 640x400 + // they should be multiplied by 2. + // + // ** TODO. + // + // Truth be told, all this is still implemented incorrectly, because no one + // found time to rewrite the thing. The correct way would perhaps be: + // 1) treat old games as x2 lower resolution than they say. + // 2) support drawing particular sprites and texts in x2 higher resolution + // (assuming display resolution allows). The latter is potentially enabled + // by "sprite batches" system in the engine and will benefit new games too. + + inline GameResolutionType GetResolutionType() const + { + return _resolutionType; + } + + // Get actual game's resolution + const Size &GetGameRes() const { return _gameResolution; } + // Get default resolution the game was created for; + // this is usually equal to GetGameRes except for legacy modes. + const Size &GetDefaultRes() const { return _defGameResolution; } + // Get data & script resolution; + // this is usually equal to GetGameRes except for legacy modes. + const Size &GetDataRes() const { return _dataResolution; } + // Get game data-->final game resolution coordinate multiplier + inline int GetDataUpscaleMult() const { return _dataUpscaleMult; } + // Get multiplier for various default UI sizes, meant to keep UI looks + // more or less readable in any game resolution. + // TODO: find a better solution for UI sizes, perhaps make variables. + inline int GetRelativeUIMult() const { return _relativeUIMult; } + // Get game default res-->final game resolution coordinate multiplier; + // used to convert coordinates from original game res to actual one + inline int GetScreenUpscaleMult() const { return _screenUpscaleMult; } + // Tells if game allows assets defined in relative resolution; + // that is - have to be converted to this game resolution type + inline bool AllowRelativeRes() const { return options[OPT_RELATIVEASSETRES] != 0; } + // Legacy definition of high and low game resolution. + // Used to determine certain hardcoded coordinate conversion logic, but + // does not make much sense today when the resolution is arbitrary. + inline bool IsLegacyHiRes() const + { + if (_resolutionType == kGameResolution_Custom) + return (_gameResolution.Width * _gameResolution.Height) > (320 * 240); + return ::IsLegacyHiRes(_resolutionType); + } + // Tells if data has coordinates in default game resolution + inline bool IsDataInNativeCoordinates() const { return options[OPT_NATIVECOORDINATES] != 0; } + + // Tells if game runs in native letterbox mode (legacy option) + inline bool IsLegacyLetterbox() const { return options[OPT_LETTERBOX] != 0; } + // Get letterboxed frame size + const Size &GetLetterboxSize() const { return _letterboxSize; } + + // Room region/hotspot masks are traditionally 1:1 of the room's size in + // low-resolution games and 1:2 of the room size in high-resolution games. + // This also means that mask relation to data resolution is 1:1 if the + // game uses low-res coordinates in script and 1:2 if high-res. + + // Test if the game is built around old audio system + inline bool IsLegacyAudioSystem() const + { + return loaded_game_file_version < kGameVersion_320; + } + + // Returns the expected filename of a digital audio package + inline AGS::Common::String GetAudioVOXName() const + { + return IsLegacyAudioSystem() ? "music.vox" : "audio.vox"; + } + +private: + void SetDefaultResolution(GameResolutionType type, Size game_res); + void SetNativeResolution(GameResolutionType type, Size game_res); + void OnResolutionSet(); + + // Game's native resolution ID, used to init following values. + GameResolutionType _resolutionType; + + // Determines game's default screen resolution. Use for the reference + // when comparing with actual screen resolution, which may be modified + // by certain overriding game modes. + Size _defGameResolution; + // Determines game's actual resolution. + Size _gameResolution; + // Determines resolution in which loaded data and script define coordinates + // and sizes (with very little exception). + Size _dataResolution; + // Letterboxed frame size. Used when old game is run in native letterbox + // mode. In all other situations is equal to game's resolution. + Size _letterboxSize; + + // Game logic to game resolution coordinate factor + int _dataUpscaleMult; + // Multiplier for various UI drawin sizes, meant to keep UI elements readable + int _relativeUIMult; + // Game default resolution to actual game resolution factor + int _screenUpscaleMult; +}; + +#endif // __AGS_CN_AC__GAMESETUPSTRUCTBASE_H \ No newline at end of file diff --git a/engines/ags/shared/ac/gamestructdefines.h b/engines/ags/shared/ac/gamestructdefines.h new file mode 100644 index 000000000000..77ccee094d6d --- /dev/null +++ b/engines/ags/shared/ac/gamestructdefines.h @@ -0,0 +1,256 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_AC__GAMESTRUCTDEFINES_H +#define __AGS_CN_AC__GAMESTRUCTDEFINES_H + +#include "util/geometry.h" +#include "core/types.h" + +#define PAL_GAMEWIDE 0 +#define PAL_LOCKED 1 +#define PAL_BACKGROUND 2 +#define MAXGLOBALMES 500 +#define GLOBALMESLENGTH 500 +#define MAXLANGUAGE 5 +#define LEGACY_MAX_FONTS 30 +#define OPT_DEBUGMODE 0 +#define OPT_SCORESOUND 1 +#define OPT_WALKONLOOK 2 +#define OPT_DIALOGIFACE 3 +#define OPT_ANTIGLIDE 4 +#define OPT_TWCUSTOM 5 +#define OPT_DIALOGGAP 6 +#define OPT_NOSKIPTEXT 7 +#define OPT_DISABLEOFF 8 +#define OPT_ALWAYSSPCH 9 +#define OPT_SPEECHTYPE 10 +#define OPT_PIXPERFECT 11 +#define OPT_NOWALKMODE 12 +#define OPT_LETTERBOX 13 +#define OPT_FIXEDINVCURSOR 14 +#define OPT_NOLOSEINV 15 +#define OPT_HIRES_FONTS 16 +#define OPT_SPLITRESOURCES 17 +#define OPT_ROTATECHARS 18 +#define OPT_FADETYPE 19 +#define OPT_HANDLEINVCLICKS 20 +#define OPT_MOUSEWHEEL 21 +#define OPT_DIALOGNUMBERED 22 +#define OPT_DIALOGUPWARDS 23 +#define OPT_CROSSFADEMUSIC 24 +#define OPT_ANTIALIASFONTS 25 +#define OPT_THOUGHTGUI 26 +#define OPT_TURNTOFACELOC 27 +#define OPT_RIGHTLEFTWRITE 28 // right-to-left text writing +#define OPT_DUPLICATEINV 29 // if they have 2 of the item, draw it twice +#define OPT_SAVESCREENSHOT 30 +#define OPT_PORTRAITSIDE 31 +#define OPT_STRICTSCRIPTING 32 // don't allow MoveCharacter-style commands +#define OPT_LEFTTORIGHTEVAL 33 // left-to-right operator evaluation +#define OPT_COMPRESSSPRITES 34 +#define OPT_STRICTSTRINGS 35 // don't allow old-style strings +#define OPT_NEWGUIALPHA 36 +#define OPT_RUNGAMEDLGOPTS 37 +#define OPT_NATIVECOORDINATES 38 // defines coordinate relation between game logic and game screen +#define OPT_GLOBALTALKANIMSPD 39 +#define OPT_HIGHESTOPTION_321 39 +#define OPT_SPRITEALPHA 40 +#define OPT_HIGHESTOPTION_330 OPT_SPRITEALPHA +#define OPT_SAFEFILEPATHS 41 +#define OPT_HIGHESTOPTION_335 OPT_SAFEFILEPATHS +#define OPT_DIALOGOPTIONSAPI 42 // version of dialog options API (-1 for pre-3.4.0 API) +#define OPT_BASESCRIPTAPI 43 // version of the Script API (ScriptAPIVersion) used to compile game script +#define OPT_SCRIPTCOMPATLEV 44 // level of API compatibility (ScriptAPIVersion) used to compile game script +#define OPT_RENDERATSCREENRES 45 // scale sprites at the (final) screen resolution +#define OPT_RELATIVEASSETRES 46 // relative asset resolution mode (where sprites are resized to match game type) +#define OPT_WALKSPEEDABSOLUTE 47 // if movement speeds are independent of walkable mask resolution +#define OPT_HIGHESTOPTION OPT_WALKSPEEDABSOLUTE +#define OPT_NOMODMUSIC 98 +#define OPT_LIPSYNCTEXT 99 +#define PORTRAIT_LEFT 0 +#define PORTRAIT_RIGHT 1 +#define PORTRAIT_ALTERNATE 2 +#define PORTRAIT_XPOSITION 3 +#define FADE_NORMAL 0 +#define FADE_INSTANT 1 +#define FADE_DISSOLVE 2 +#define FADE_BOXOUT 3 +#define FADE_CROSSFADE 4 +#define FADE_LAST 4 // this should equal the last one + +// Legacy font flags +//#define FFLG_LEGACY_NOSCALE 0x01 // TODO: is this from legacy format, ever used? +#define FFLG_LEGACY_SIZEMASK 0x3f +#define MAX_LEGACY_FONT_SIZE 63 +// Contemporary font flags +#define FFLG_SIZEMULTIPLIER 0x01 // size data means multiplier +// Font outline types +#define FONT_OUTLINE_NONE -1 +#define FONT_OUTLINE_AUTO -10 + +#define DIALOG_OPTIONS_HIGHLIGHT_COLOR_DEFAULT 14 // Yellow + +#define MAXVIEWNAMELENGTH 15 +#define MAXLIPSYNCFRAMES 20 +#define MAX_GUID_LENGTH 40 +#define MAX_SG_EXT_LENGTH 20 +#define MAX_SG_FOLDER_LEN 50 + +enum GameResolutionType +{ + kGameResolution_Undefined = -1, + // definition of 320x200 in very old versions of the engine (somewhere pre-2.56) + kGameResolution_Default = 0, + kGameResolution_320x200 = 1, + kGameResolution_320x240 = 2, + kGameResolution_640x400 = 3, + kGameResolution_640x480 = 4, + kGameResolution_800x600 = 5, + kGameResolution_1024x768 = 6, + kGameResolution_1280x720 = 7, + kGameResolution_Custom = 8, + kNumGameResolutions, + + kGameResolution_LastLoRes = kGameResolution_320x240, + kGameResolution_FirstHiRes = kGameResolution_640x400 +}; + +inline bool IsLegacyHiRes(GameResolutionType resolution) +{ + return resolution > kGameResolution_LastLoRes; +} + +Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox = false); + +// Automatic numbering of dialog options (OPT_DIALOGNUMBERED) +enum DialogOptionNumbering +{ + kDlgOptNoNumbering = -1, + kDlgOptKeysOnly = 0, // implicit key shortcuts + kDlgOptNumbering = 1 // draw option indices and use key shortcuts +}; + +// Version of the script api (OPT_BASESCRIPTAPI and OPT_SCRIPTCOMPATLEV). +// If the existing script function meaning had changed, that may be +// possible to find out which implementation to use by checking one of those +// two options. +// NOTE: please remember that those values are valid only for games made with +// 3.4.0 final and above. +enum ScriptAPIVersion +{ + kScriptAPI_Undefined = INT32_MIN, + kScriptAPI_v321 = 0, + kScriptAPI_v330 = 1, + kScriptAPI_v334 = 2, + kScriptAPI_v335 = 3, + kScriptAPI_v340 = 4, + kScriptAPI_v341 = 5, + kScriptAPI_v350 = 6, + kScriptAPI_v3507= 7, + kScriptAPI_v351 = 8, + kScriptAPI_Current = kScriptAPI_v351 +}; + +// Determines whether the graphics renderer should scale sprites at the final +// screen resolution, as opposed to native resolution +enum RenderAtScreenRes +{ + kRenderAtScreenRes_UserDefined = 0, + kRenderAtScreenRes_Enabled = 1, + kRenderAtScreenRes_Disabled = 2, +}; + +// Method to use when blending two sprites with alpha channel +enum GameSpriteAlphaRenderingStyle +{ + kSpriteAlphaRender_Legacy = 0, + kSpriteAlphaRender_Proper +}; + +// Method to use when blending two GUI elements with alpha channel +enum GameGuiAlphaRenderingStyle +{ + kGuiAlphaRender_Legacy = 0, + kGuiAlphaRender_AdditiveAlpha, + kGuiAlphaRender_Proper +}; + + +// Sprite flags (serialized as 8-bit) +#define SPF_HIRES 0x01 // sized for high native resolution (legacy option) +#define SPF_HICOLOR 0x02 // is 16-bit +#define SPF_DYNAMICALLOC 0x04 // created by runtime script +#define SPF_TRUECOLOR 0x08 // is 32-bit +#define SPF_ALPHACHANNEL 0x10 // has alpha-channel +#define SPF_VAR_RESOLUTION 0x20 // variable resolution (refer to SPF_HIRES) +#define SPF_HADALPHACHANNEL 0x80 // the saved sprite on disk has one + +// General information about sprite (properties, size) +struct SpriteInfo +{ + uint32_t Flags; + int Width; + int Height; + + SpriteInfo(); + + // + // Legacy game support + // + // Gets if sprite should adjust its base size depending on game's resolution + inline bool IsRelativeRes() const { return (Flags & SPF_VAR_RESOLUTION) != 0; } + // Gets if sprite belongs to high resolution; hi-res sprites should be + // downscaled in low-res games, and low-res sprites should be upscaled + // in hi-res games + inline bool IsLegacyHiRes() const { return (Flags & SPF_HIRES) != 0; } +}; + +// Various font parameters, defining and extending font rendering behavior. +// While FontRenderer object's main goal is to render single line of text at +// the strictly determined position on canvas, FontInfo may additionally +// provide instructions on adjusting drawing position, as well as arranging +// multiple lines, and similar cases. +struct FontInfo +{ + enum AutoOutlineStyle : int + { + kRounded = 0, + kSquared = 1, + }; + + // General font's loading and rendering flags + uint32_t Flags; + // Font size, in points (basically means pixels in AGS) + int SizePt; + // Factor to multiply base font size by + int SizeMultiplier; + // Outlining font index, or auto-outline flag + char Outline; + // Custom vertical render offset, used mainly for fixing broken fonts + int YOffset; + // custom line spacing between two lines of text (0 = use font height) + int LineSpacing; + // When automatic outlining, thickness of the outline (0 = use legacy thickness) + int AutoOutlineThickness; + // When automatic outlining, style of the outline + AutoOutlineStyle AutoOutlineStyle; + + FontInfo(); +}; + +#endif // __AGS_CN_AC__GAMESTRUCTDEFINES_H diff --git a/engines/ags/shared/ac/interfacebutton.h b/engines/ags/shared/ac/interfacebutton.h new file mode 100644 index 000000000000..6a97a61d50c0 --- /dev/null +++ b/engines/ags/shared/ac/interfacebutton.h @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_INTERFACEBUTTON_H +#define __AC_INTERFACEBUTTON_H + +#define MAXBUTTON 20 +#define IBFLG_ENABLED 1 +#define IBFLG_INVBOX 2 +struct InterfaceButton { + int x, y, pic, overpic, pushpic, leftclick; + int rightclick; // if inv, then leftclick = wid, rightclick = hit + int reserved_for_future; + char flags; + void set(int xx, int yy, int picc, int overpicc, int actionn); +}; + +#endif // __AC_INTERFACEBUTTON_H \ No newline at end of file diff --git a/engines/ags/shared/ac/interfaceelement.h b/engines/ags/shared/ac/interfaceelement.h new file mode 100644 index 000000000000..4c3094be2d7e --- /dev/null +++ b/engines/ags/shared/ac/interfaceelement.h @@ -0,0 +1,51 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_INTERFACEELEMENT_H +#define __AC_INTERFACEELEMENT_H + +#include "ac/interfacebutton.h" // InterfaceButton + +// this struct should go in a Game struct, not the room structure. +struct InterfaceElement { + int x, y, x2, y2; + int bgcol, fgcol, bordercol; + int vtextxp, vtextyp, vtextalign; // X & Y relative to topleft of interface + char vtext[40]; + int numbuttons; + InterfaceButton button[MAXBUTTON]; + int flags; + int reserved_for_future; + int popupyp; // pops up when mousey < this + char popup; // does it pop up? (like sierra icon bar) + char on; + InterfaceElement(); +}; + +/*struct InterfaceStyle { +int playareax1,playareay1,playareax2,playareay2; // where the game takes place +int vtextxp,vtextyp; +char vtext[40]; +int numbuttons,popupbuttons; +InterfaceButton button[MAXBUTTON]; +int invx1,invy1,invx2,invy2; // set invx1=-1 for Sierra-style inventory +InterfaceStyle() { // sierra interface +playareax1=0; playareay1=13; playareax2=319; playareay2=199; +vtextxp=160; vtextyp=2; strcpy(vtext,"@SCORETEXT@$r@GAMENAME@"); +invx1=-1; numbuttons=2; popupbuttons=1; +button[0].set(0,13,3,-1,0); +} +};*/ + +#endif // __AC_INTERFACEELEMENT_H \ No newline at end of file diff --git a/engines/ags/shared/ac/inventoryiteminfo.cpp b/engines/ags/shared/ac/inventoryiteminfo.cpp new file mode 100644 index 000000000000..910392dc321e --- /dev/null +++ b/engines/ags/shared/ac/inventoryiteminfo.cpp @@ -0,0 +1,55 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/inventoryiteminfo.h" +#include "util/stream.h" +#include "util/string_utils.h" + +using namespace AGS::Common; + +void InventoryItemInfo::ReadFromFile(Stream *in) +{ + in->Read(name, 25); + pic = in->ReadInt32(); + cursorPic = in->ReadInt32(); + hotx = in->ReadInt32(); + hoty = in->ReadInt32(); + in->ReadArrayOfInt32(reserved, 5); + flags = in->ReadInt8(); +} + +void InventoryItemInfo::WriteToFile(Stream *out) +{ + out->Write(name, 25); + out->WriteInt32(pic); + out->WriteInt32(cursorPic); + out->WriteInt32(hotx); + out->WriteInt32(hoty); + out->WriteArrayOfInt32(reserved, 5); + out->WriteInt8(flags); +} + +void InventoryItemInfo::ReadFromSavegame(Stream *in) +{ + StrUtil::ReadString(name, in, 25); + pic = in->ReadInt32(); + cursorPic = in->ReadInt32(); +} + +void InventoryItemInfo::WriteToSavegame(Stream *out) const +{ + StrUtil::WriteString(name, out); + out->WriteInt32(pic); + out->WriteInt32(cursorPic); +} diff --git a/engines/ags/shared/ac/inventoryiteminfo.h b/engines/ags/shared/ac/inventoryiteminfo.h new file mode 100644 index 000000000000..3936ce6f087e --- /dev/null +++ b/engines/ags/shared/ac/inventoryiteminfo.h @@ -0,0 +1,35 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_INVENTORYITEMINFO_H +#define __AC_INVENTORYITEMINFO_H + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define IFLG_STARTWITH 1 +struct InventoryItemInfo { + char name[25]; + int pic; + int cursorPic, hotx, hoty; + int reserved[5]; + char flags; + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; +}; + +#endif // __AC_INVENTORYITEMINFO_H \ No newline at end of file diff --git a/engines/ags/shared/ac/mousecursor.cpp b/engines/ags/shared/ac/mousecursor.cpp new file mode 100644 index 000000000000..1da9225e4069 --- /dev/null +++ b/engines/ags/shared/ac/mousecursor.cpp @@ -0,0 +1,58 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/mousecursor.h" +#include "util/stream.h" + +using AGS::Common::Stream; + +MouseCursor::MouseCursor() { pic = 2054; hotx = 0; hoty = 0; name[0] = 0; flags = 0; view = -1; } + +void MouseCursor::ReadFromFile(Stream *in) +{ + pic = in->ReadInt32(); + hotx = in->ReadInt16(); + hoty = in->ReadInt16(); + view = in->ReadInt16(); + in->Read(name, 10); + flags = in->ReadInt8(); +} + +void MouseCursor::WriteToFile(Stream *out) +{ + out->WriteInt32(pic); + out->WriteInt16(hotx); + out->WriteInt16(hoty); + out->WriteInt16(view); + out->Write(name, 10); + out->WriteInt8(flags); +} + +void MouseCursor::ReadFromSavegame(Stream *in) +{ + pic = in->ReadInt32(); + hotx = in->ReadInt32(); + hoty = in->ReadInt32(); + view = in->ReadInt32(); + flags = in->ReadInt32(); +} + +void MouseCursor::WriteToSavegame(Stream *out) const +{ + out->WriteInt32(pic); + out->WriteInt32(hotx); + out->WriteInt32(hoty); + out->WriteInt32(view); + out->WriteInt32(flags); +} diff --git a/engines/ags/shared/ac/mousecursor.h b/engines/ags/shared/ac/mousecursor.h new file mode 100644 index 000000000000..4207ccf5d455 --- /dev/null +++ b/engines/ags/shared/ac/mousecursor.h @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_MOUSECURSOR_H +#define __AC_MOUSECURSOR_H + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define MCF_ANIMMOVE 1 +#define MCF_DISABLED 2 +#define MCF_STANDARD 4 +#define MCF_HOTSPOT 8 // only animate when over hotspot +// this struct is also in the plugin header file +struct MouseCursor { + int pic; + short hotx, hoty; + short view; + char name[10]; + char flags; + MouseCursor(); + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; +}; + +#endif // __AC_MOUSECURSOR_H \ No newline at end of file diff --git a/engines/ags/shared/ac/oldgamesetupstruct.h b/engines/ags/shared/ac/oldgamesetupstruct.h new file mode 100644 index 000000000000..40dbfb7555f5 --- /dev/null +++ b/engines/ags/shared/ac/oldgamesetupstruct.h @@ -0,0 +1,78 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_AC__OLDGAMESETUPSTRUCT_H +#define __AGS_CN_AC__OLDGAMESETUPSTRUCT_H + +#include "ac/characterinfo.h" // OldCharacterInfo, CharacterInfo +#ifdef UNUSED_CODE +#include "ac/eventblock.h" // EventBlock +#endif +#include "ac/interfaceelement.h" // InterfaceElement +#include "ac/inventoryiteminfo.h" // InventoryItemInfo +#include "ac/mousecursor.h" // MouseCursor +#include "ac/wordsdictionary.h" // WordsDictionary +#include "script/cc_script.h" // ccScript + +struct OriGameSetupStruct { + char gamename[30]; + char options[20]; + unsigned char paluses[256]; + color defpal[256]; + InterfaceElement iface[10]; + int numiface; + int numviews; + MouseCursor mcurs[10]; + char *globalscript; + int numcharacters; + OldCharacterInfo *chars; +#ifdef UNUSED_CODE + EventBlock __charcond[50]; // [IKM] 2012-06-22: does not seem to be used anywhere + EventBlock __invcond[100]; // same +#endif + ccScript *compiled_script; + int playercharacter; + unsigned char __old_spriteflags[2100]; + int totalscore; + short numinvitems; + InventoryItemInfo invinfo[100]; + int numdialog, numdlgmessage; + int numfonts; + int color_depth; // in bytes per pixel (ie. 1 or 2) + int target_win; + int dialog_bullet; // 0 for none, otherwise slot num of bullet point + short hotdot, hotdotouter; // inv cursor hotspot dot + int uniqueid; // random key identifying the game + int reserved[2]; + short numlang; + char langcodes[MAXLANGUAGE][3]; + char *messages[MAXGLOBALMES]; +}; + +struct OriGameSetupStruct2 : public OriGameSetupStruct { + unsigned char fontflags[10]; + char fontoutline[10]; + int numgui; + WordsDictionary *dict; + int reserved2[8]; +}; + +struct OldGameSetupStruct : public OriGameSetupStruct2 { + unsigned char spriteflags[LEGACY_MAX_SPRITES_V25]; +}; + +#endif // __AGS_CN_AC__OLDGAMESETUPSTRUCT_H diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp new file mode 100644 index 000000000000..eecf492e6d62 --- /dev/null +++ b/engines/ags/shared/ac/spritecache.cpp @@ -0,0 +1,983 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// sprite caching system +// +//============================================================================= + +#ifdef _MANAGED +// ensure this doesn't get compiled to .NET IL +#pragma unmanaged +#pragma warning (disable: 4996 4312) // disable deprecation warnings +#endif + +#include "ac/common.h" // quit +#include "ac/gamestructdefines.h" +#include "ac/spritecache.h" +#include "core/assetmanager.h" +#include "debug/out.h" +#include "gfx/bitmap.h" +#include "util/compress.h" +#include "util/file.h" +#include "util/stream.h" + +using namespace AGS::Common; + +// [IKM] We have to forward-declare these because their implementations are in the Engine +extern void initialize_sprite(int); +extern void pre_save_sprite(int); +extern void get_new_size_for_sprite(int, int, int, int &, int &); + +#define START_OF_LIST -1 +#define END_OF_LIST -1 + +const char *spindexid = "SPRINDEX"; + +// TODO: should not be part of SpriteCache, but rather some asset management class? +const String SpriteCache::DefaultSpriteFileName = "acsprset.spr"; +const String SpriteCache::DefaultSpriteIndexName = "sprindex.dat"; + + +SpriteInfo::SpriteInfo() + : Flags(0) + , Width(0) + , Height(0) +{ +} + +SpriteCache::SpriteData::SpriteData() + : Offset(0) + , Size(0) + , Flags(0) + , Image(nullptr) +{ +} + +SpriteCache::SpriteData::~SpriteData() +{ + // TODO: investigate, if it's actually safe/preferred to delete bitmap here + // (some of these bitmaps may be assigned from outside of the cache) +} + + +SpriteCache::SpriteCache(std::vector &sprInfos) + : _sprInfos(sprInfos) +{ + _compressed = false; + Init(); +} + +SpriteCache::~SpriteCache() +{ + Reset(); +} + +size_t SpriteCache::GetCacheSize() const +{ + return _cacheSize; +} + +size_t SpriteCache::GetLockedSize() const +{ + return _lockedSize; +} + +size_t SpriteCache::GetMaxCacheSize() const +{ + return _maxCacheSize; +} + +sprkey_t SpriteCache::GetSpriteSlotCount() const +{ + return _spriteData.size(); +} + +sprkey_t SpriteCache::FindTopmostSprite() const +{ + sprkey_t topmost = -1; + for (sprkey_t i = 0; i < static_cast(_spriteData.size()); ++i) + if (DoesSpriteExist(i)) + topmost = i; + return topmost; +} + +void SpriteCache::SetMaxCacheSize(size_t size) +{ + _maxCacheSize = size; +} + +void SpriteCache::Init() +{ + _cacheSize = 0; + _lockedSize = 0; + _maxCacheSize = (size_t)DEFAULTCACHESIZE_KB * 1024; + _liststart = -1; + _listend = -1; + _lastLoad = -2; +} + +void SpriteCache::Reset() +{ + _stream.reset(); + // TODO: find out if it's safe to simply always delete _spriteData.Image with array element + for (size_t i = 0; i < _spriteData.size(); ++i) + { + if (_spriteData[i].Image) + { + delete _spriteData[i].Image; + _spriteData[i].Image = nullptr; + } + } + _spriteData.clear(); + + _mrulist.clear(); + _mrubacklink.clear(); + + Init(); +} + +void SpriteCache::SetSprite(sprkey_t index, Bitmap *sprite) +{ + if (index < 0 || EnlargeTo(index) != index) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetSprite: unable to use index %d", index); + return; + } + if (!sprite) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetSprite: attempt to assign nullptr to index %d", index); + return; + } + _spriteData[index].Image = sprite; + _spriteData[index].Flags = SPRCACHEFLAG_LOCKED; // NOT from asset file + _spriteData[index].Offset = 0; + _spriteData[index].Size = 0; +#ifdef DEBUG_SPRITECACHE + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "SetSprite: (external) %d", index); +#endif +} + +void SpriteCache::SetEmptySprite(sprkey_t index, bool as_asset) +{ + if (index < 0 || EnlargeTo(index) != index) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetEmptySprite: unable to use index %d", index); + return; + } + if (as_asset) + _spriteData[index].Flags = SPRCACHEFLAG_ISASSET; + RemapSpriteToSprite0(index); +} + +void SpriteCache::SubstituteBitmap(sprkey_t index, Common::Bitmap *sprite) +{ + if (!DoesSpriteExist(index)) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SubstituteBitmap: attempt to set for non-existing sprite %d", index); + return; + } + _spriteData[index].Image = sprite; +#ifdef DEBUG_SPRITECACHE + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "SubstituteBitmap: %d", index); +#endif +} + +void SpriteCache::RemoveSprite(sprkey_t index, bool freeMemory) +{ + if (freeMemory) + delete _spriteData[index].Image; + InitNullSpriteParams(index); +#ifdef DEBUG_SPRITECACHE + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "RemoveSprite: %d", index); +#endif +} + +sprkey_t SpriteCache::EnlargeTo(sprkey_t topmost) +{ + if (topmost < 0 || topmost > MAX_SPRITE_INDEX) + return -1; + if ((size_t)topmost < _spriteData.size()) + return topmost; + + size_t newsize = topmost + 1; + _sprInfos.resize(newsize); + _spriteData.resize(newsize); + _mrulist.resize(newsize); + _mrubacklink.resize(newsize); + return topmost; +} + +sprkey_t SpriteCache::GetFreeIndex() +{ + for (size_t i = MIN_SPRITE_INDEX; i < _spriteData.size(); ++i) + { + // slot empty + if (!DoesSpriteExist(i)) + { + _sprInfos[i] = SpriteInfo(); + _spriteData[i] = SpriteData(); + return i; + } + } + // enlarge the sprite bank to find a free slot and return the first new free slot + return EnlargeTo(_spriteData.size()); +} + +bool SpriteCache::SpriteData::DoesSpriteExist() const +{ + return (Image != nullptr) || // HAS loaded bitmap + ((Flags & SPRCACHEFLAG_ISASSET) != 0); // OR found in the game resources +} + +bool SpriteCache::SpriteData::IsAssetSprite() const +{ + return (Flags & SPRCACHEFLAG_ISASSET) != 0; // found in game resources +} + +bool SpriteCache::SpriteData::IsExternalSprite() const +{ + return (Image != nullptr) && // HAS loaded bitmap + ((Flags & SPRCACHEFLAG_ISASSET) == 0) && // AND NOT found in game resources + ((Flags & SPRCACHEFLAG_REMAPPED) == 0); // AND was NOT remapped to another sprite +} + +bool SpriteCache::SpriteData::IsLocked() const +{ + return (Flags & SPRCACHEFLAG_LOCKED) != 0; +} + +bool SpriteCache::DoesSpriteExist(sprkey_t index) const +{ + return index >= 0 && (size_t)index < _spriteData.size() && _spriteData[index].DoesSpriteExist(); +} + +Bitmap *SpriteCache::operator [] (sprkey_t index) +{ + // invalid sprite slot + if (index < 0 || (size_t)index >= _spriteData.size()) + return nullptr; + + // Externally added sprite, don't put it into MRU list + if (_spriteData[index].IsExternalSprite()) + return _spriteData[index].Image; + + // Sprite exists in file but is not in mem, load it + if ((_spriteData[index].Image == nullptr) && _spriteData[index].IsAssetSprite()) + LoadSprite(index); + + // Locked sprite that shouldn't be put into MRU list + if (_spriteData[index].IsLocked()) + return _spriteData[index].Image; + + if (_liststart < 0) + { + _liststart = index; + _listend = index; + _mrulist[index] = END_OF_LIST; + _mrubacklink[index] = START_OF_LIST; + } + else if (_listend != index) + { + // this is the oldest element being bumped to newest, so update start link + if (index == _liststart) + { + _liststart = _mrulist[index]; + _mrubacklink[_liststart] = START_OF_LIST; + } + // already in list, link previous to next + else if (_mrulist[index] > 0) + { + _mrulist[_mrubacklink[index]] = _mrulist[index]; + _mrubacklink[_mrulist[index]] = _mrubacklink[index]; + } + + // set this as the newest element in the list + _mrulist[index] = END_OF_LIST; + _mrulist[_listend] = index; + _mrubacklink[index] = _listend; + _listend = index; + } + + return _spriteData[index].Image; +} + +void SpriteCache::DisposeOldest() +{ + if (_liststart < 0) + return; + + sprkey_t sprnum = _liststart; + + if ((_spriteData[sprnum].Image != nullptr) && !_spriteData[sprnum].IsLocked()) + { + // Free the memory + // Sprites that are not from the game resources should not normally be in a MRU list; + // if such is met here there's something wrong with the internal cache logic! + if (!_spriteData[sprnum].IsAssetSprite()) + { + quitprintf("SpriteCache::DisposeOldest: attempted to remove sprite %d that was added externally or does not exist", sprnum); + } + _cacheSize -= _spriteData[sprnum].Size; + + delete _spriteData[sprnum].Image; + _spriteData[sprnum].Image = nullptr; + } + + if (_liststart == _listend) + { + // there was one huge sprite, removing it has now emptied the cache completely + if (_cacheSize > 0) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SPRITE CACHE ERROR: Sprite cache should be empty, but still has %d bytes", _cacheSize); + } + _mrulist[_liststart] = 0; + _liststart = -1; + _listend = -1; + } + else + { + sprkey_t oldstart = _liststart; + _liststart = _mrulist[_liststart]; + _mrulist[oldstart] = 0; + _mrubacklink[_liststart] = START_OF_LIST; + if (oldstart == _liststart) + { + // Somehow, we have got a recursive link to itself, so we + // the game will freeze (since it is not actually freeing any + // memory) + // There must be a bug somewhere causing this, but for now + // let's just reset the cache + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: CACHE INCONSISTENT: RESETTING\n\tAt size %d (of %d), start %d end %d fwdlink=%d", + _cacheSize, _maxCacheSize, oldstart, _listend, _liststart); + DisposeAll(); + } + } + +#ifdef DEBUG_SPRITECACHE + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "DisposeOldest: disposed %d, size now %d KB", sprnum, _cacheSize / 1024); +#endif +} + +void SpriteCache::DisposeAll() +{ + _liststart = -1; + _listend = -1; + for (size_t i = 0; i < _spriteData.size(); ++i) + { + if (!_spriteData[i].IsLocked() && // not locked + _spriteData[i].IsAssetSprite()) // sprite from game resource + { + delete _spriteData[i].Image; + _spriteData[i].Image = nullptr; + } + _mrulist[i] = 0; + _mrubacklink[i] = 0; + } + _cacheSize = _lockedSize; +} + +void SpriteCache::Precache(sprkey_t index) +{ + if (index < 0 || (size_t)index >= _spriteData.size()) + return; + + soff_t sprSize = 0; + + if (_spriteData[index].Image == nullptr) + sprSize = LoadSprite(index); + else if (!_spriteData[index].IsLocked()) + sprSize = _spriteData[index].Size; + + // make sure locked sprites can't fill the cache + _maxCacheSize += sprSize; + _lockedSize += sprSize; + + _spriteData[index].Flags |= SPRCACHEFLAG_LOCKED; + +#ifdef DEBUG_SPRITECACHE + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "Precached %d", index); +#endif +} + +sprkey_t SpriteCache::GetDataIndex(sprkey_t index) +{ + return (_spriteData[index].Flags & SPRCACHEFLAG_REMAPPED) == 0 ? index : 0; +} + +void SpriteCache::SeekToSprite(sprkey_t index) +{ + // If we didn't just load the previous sprite, seek to it + if (index - 1 != _lastLoad) + _stream->Seek(_spriteData[index].Offset, kSeekBegin); +} + +size_t SpriteCache::LoadSprite(sprkey_t index) +{ + int hh = 0; + + while (_cacheSize > _maxCacheSize) + { + DisposeOldest(); + hh++; + if (hh > 1000) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: STUCK IN FREE_UP_MEM; RESETTING CACHE"); + DisposeAll(); + } + } + + if (index < 0 || (size_t)index >= _spriteData.size()) + quit("sprite cache array index out of bounds"); + + sprkey_t load_index = GetDataIndex(index); + SeekToSprite(load_index); + + int coldep = _stream->ReadInt16(); + + if (coldep == 0) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "LoadSprite: asked to load sprite %d (for slot %d) which does not exist.", load_index, index); + _lastLoad = load_index; + return 0; + } + + int wdd = _stream->ReadInt16(); + int htt = _stream->ReadInt16(); + // update the stored width/height + _sprInfos[index].Width = wdd; + _sprInfos[index].Height = htt; + + _spriteData[index].Image = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); + if (_spriteData[index].Image == nullptr) + { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Warn, "LoadSprite: failed to init sprite %d, remapping to sprite 0.", index); + RemapSpriteToSprite0(index); + return 0; + } + + Bitmap *image = _spriteData[index].Image; + if (this->_compressed) + { + _stream->ReadInt32(); // skip data size + UnCompressSprite(image, _stream.get()); + } + else + { + if (coldep == 1) + { + for (hh = 0; hh < htt; hh++) + _stream->ReadArray(&image->GetScanLineForWriting(hh)[0], coldep, wdd); + } + else if (coldep == 2) + { + for (hh = 0; hh < htt; hh++) + _stream->ReadArrayOfInt16((int16_t*)&image->GetScanLineForWriting(hh)[0], wdd); + } + else + { + for (hh = 0; hh < htt; hh++) + _stream->ReadArrayOfInt32((int32_t*)&image->GetScanLineForWriting(hh)[0], wdd); + } + } + + _lastLoad = load_index; + + // Stop it adding the sprite to the used list just because it's loaded + // TODO: this messy hack is required, because initialize_sprite calls operator[] + // which puts the sprite to the MRU list. + _spriteData[index].Flags |= SPRCACHEFLAG_LOCKED; + + // TODO: this is ugly: asks the engine to convert the sprite using its own knowledge. + // And engine assigns new bitmap using SpriteCache::SubstituteBitmap(). + // Perhaps change to the callback function pointer? + initialize_sprite(index); + + if (index != 0) // leave sprite 0 locked + _spriteData[index].Flags &= ~SPRCACHEFLAG_LOCKED; + + // we need to store this because the main program might + // alter spritewidth/height if it resizes stuff + size_t size = _sprInfos[index].Width * _sprInfos[index].Height * coldep; + _spriteData[index].Size = size; + _cacheSize += size; + +#ifdef DEBUG_SPRITECACHE + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "Loaded %d, size now %u KB", index, _cacheSize / 1024); +#endif + + return size; +} + +void SpriteCache::RemapSpriteToSprite0(sprkey_t index) +{ + _sprInfos[index].Flags = _sprInfos[0].Flags; + _sprInfos[index].Width = _sprInfos[0].Width; + _sprInfos[index].Height = _sprInfos[0].Height; + _spriteData[index].Image = nullptr; + _spriteData[index].Offset = _spriteData[0].Offset; + _spriteData[index].Size = _spriteData[0].Size; + _spriteData[index].Flags |= SPRCACHEFLAG_REMAPPED; +#ifdef DEBUG_SPRITECACHE + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "RemapSpriteToSprite0: %d", index); +#endif +} + +const char *spriteFileSig = " Sprite File "; + +void SpriteCache::CompressSprite(Bitmap *sprite, Stream *out) +{ + const int depth = sprite->GetBPP(); + if (depth == 1) + { + for (int y = 0; y < sprite->GetHeight(); y++) + cpackbitl(&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), out); + } + else if (depth == 2) + { + for (int y = 0; y < sprite->GetHeight(); y++) + cpackbitl16((unsigned short *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); + } + else + { + for (int y = 0; y < sprite->GetHeight(); y++) + cpackbitl32((unsigned int *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); + } +} + +void SpriteCache::UnCompressSprite(Bitmap *sprite, Stream *in) +{ + const int depth = sprite->GetBPP(); + if (depth == 1) + { + for (int y = 0; y < sprite->GetHeight(); y++) + cunpackbitl(&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); + } + else if (depth == 2) + { + for (int y = 0; y < sprite->GetHeight(); y++) + cunpackbitl16((unsigned short*)&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); + } + else + { + for (int y = 0; y < sprite->GetHeight(); y++) + cunpackbitl32((unsigned int*)&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); + } +} + +int SpriteCache::SaveToFile(const char *filename, bool compressOutput, SpriteFileIndex &index) +{ + Stream *output = Common::File::CreateFile(filename); + if (output == nullptr) + return -1; + + if (compressOutput) + { + // re-open the file so that it can be seeked + delete output; + output = File::OpenFile(filename, Common::kFile_Open, Common::kFile_ReadWrite); // CHECKME why mode was "r+" here? + if (output == nullptr) + return -1; + } + + int spriteFileIDCheck = (int)time(nullptr); + + // sprite file version + output->WriteInt16(kSprfVersion_Current); + + output->WriteArray(spriteFileSig, strlen(spriteFileSig), 1); + + output->WriteInt8(compressOutput ? 1 : 0); + output->WriteInt32(spriteFileIDCheck); + + sprkey_t lastslot = FindTopmostSprite(); + output->WriteInt32(lastslot); + + // allocate buffers to store the indexing info + sprkey_t numsprits = lastslot + 1; + std::vector spritewidths, spriteheights; + std::vector spriteoffs; + spritewidths.resize(numsprits); + spriteheights.resize(numsprits); + spriteoffs.resize(numsprits); + + const int memBufferSize = 100000; + char *memBuffer = new char[memBufferSize]; + + for (sprkey_t i = 0; i <= lastslot; ++i) + { + spriteoffs[i] = output->GetPosition(); + + // if compressing uncompressed sprites, load the sprite into memory + if ((_spriteData[i].Image == nullptr) && (this->_compressed != compressOutput)) + (*this)[i]; + + if (_spriteData[i].Image != nullptr) + { + // image in memory -- write it out + pre_save_sprite(i); + Bitmap *image = _spriteData[i].Image; + int bpss = image->GetColorDepth() / 8; + spritewidths[i] = image->GetWidth(); + spriteheights[i] = image->GetHeight(); + output->WriteInt16(bpss); + output->WriteInt16(spritewidths[i]); + output->WriteInt16(spriteheights[i]); + + if (compressOutput) + { + size_t lenloc = output->GetPosition(); + // write some space for the length data + output->WriteInt32(0); + + CompressSprite(image, output); + + size_t fileSizeSoFar = output->GetPosition(); + // write the length of the compressed data + output->Seek(lenloc, kSeekBegin); + output->WriteInt32((fileSizeSoFar - lenloc) - 4); + output->Seek(0, kSeekEnd); + } + else + { + output->WriteArray(image->GetDataForWriting(), spritewidths[i] * bpss, spriteheights[i]); + } + continue; + } + + if (_spriteData[i].Offset == 0) + { + // sprite doesn't exist + output->WriteInt16(0); // colour depth + spritewidths[i] = 0; + spriteheights[i] = 0; + spriteoffs[i] = 0; + continue; + } + + // not in memory -- seek to it in the source file + sprkey_t load_index = GetDataIndex(i); + SeekToSprite(load_index); + _lastLoad = load_index; + + short colDepth = _stream->ReadInt16(); + output->WriteInt16(colDepth); + + if (colDepth == 0) + continue; + + if (this->_compressed != compressOutput) + { + // shouldn't be able to get here + delete [] memBuffer; + delete output; + return -2; + } + + // and copy the data across + int width = _stream->ReadInt16(); + int height = _stream->ReadInt16(); + + spritewidths[i] = width; + spriteheights[i] = height; + + output->WriteInt16(width); + output->WriteInt16(height); + + int sizeToCopy; + if (this->_compressed) + { + sizeToCopy = _stream->ReadInt32(); + output->WriteInt32(sizeToCopy); + } + else + { + sizeToCopy = width * height * (int)colDepth; + } + + while (sizeToCopy > memBufferSize) + { + _stream->ReadArray(memBuffer, memBufferSize, 1); + output->WriteArray(memBuffer, memBufferSize, 1); + sizeToCopy -= memBufferSize; + } + + _stream->ReadArray(memBuffer, sizeToCopy, 1); + output->WriteArray(memBuffer, sizeToCopy, 1); + } + + delete [] memBuffer; + delete output; + + index.SpriteFileIDCheck = spriteFileIDCheck; + index.LastSlot = lastslot; + index.SpriteCount = numsprits; + index.Widths = spritewidths; + index.Heights = spriteheights; + index.Offsets = spriteoffs; + return 0; +} + +int SpriteCache::SaveSpriteIndex(const char *filename, const SpriteFileIndex &index) +{ + // write the sprite index file + Stream *out = File::CreateFile(filename); + if (!out) + return -1; + // write "SPRINDEX" id + out->WriteArray(spindexid, strlen(spindexid), 1); + // write version + out->WriteInt32(kSpridxfVersion_Current); + out->WriteInt32(index.SpriteFileIDCheck); + // write last sprite number and num sprites, to verify that + // it matches the spr file + out->WriteInt32(index.LastSlot); + out->WriteInt32(index.SpriteCount); + if (index.SpriteCount > 0) + { + out->WriteArrayOfInt16(&index.Widths.front(), index.Widths.size()); + out->WriteArrayOfInt16(&index.Heights.front(), index.Heights.size()); + out->WriteArrayOfInt64(&index.Offsets.front(), index.Offsets.size()); + } + delete out; + return 0; +} + +HError SpriteCache::InitFile(const char *filename, const char *sprindex_filename) +{ + SpriteFileVersion vers; + char buff[20]; + soff_t spr_initial_offs = 0; + int spriteFileID = 0; + + _stream.reset(Common::AssetManager::OpenAsset(filename)); + if (_stream == nullptr) + return new Error(String::FromFormat("Failed to open spriteset file '%s'.", filename)); + + spr_initial_offs = _stream->GetPosition(); + + vers = (SpriteFileVersion)_stream->ReadInt16(); + // read the "Sprite File" signature + _stream->ReadArray(&buff[0], 13, 1); + + if (vers < kSprfVersion_Uncompressed || vers > kSprfVersion_Current) + { + _stream.reset(); + return new Error(String::FromFormat("Unsupported spriteset format (requested %d, supported %d - %d).", vers, kSprfVersion_Uncompressed, kSprfVersion_Current)); + } + + // unknown version + buff[13] = 0; + if (strcmp(buff, spriteFileSig)) + { + _stream.reset(); + return new Error("Uknown spriteset format."); + } + + if (vers == kSprfVersion_Uncompressed) + { + this->_compressed = false; + } + else if (vers == kSprfVersion_Compressed) + { + this->_compressed = true; + } + else if (vers >= kSprfVersion_Last32bit) + { + this->_compressed = (_stream->ReadInt8() == 1); + spriteFileID = _stream->ReadInt32(); + } + + if (vers < kSprfVersion_Compressed) + { + // skip the palette + _stream->Seek(256 * 3); // sizeof(RGB) * 256 + } + + sprkey_t topmost; + if (vers < kSprfVersion_HighSpriteLimit) + topmost = _stream->ReadInt16(); + else + topmost = _stream->ReadInt32(); + if (vers < kSprfVersion_Uncompressed) + topmost = 200; + + EnlargeTo(topmost); + + // if there is a sprite index file, use it + if (LoadSpriteIndexFile(sprindex_filename, spriteFileID, spr_initial_offs, topmost)) + { + // Succeeded + return HError::None(); + } + + // Failed, index file is invalid; index sprites manually + return RebuildSpriteIndex(_stream.get(), topmost, vers); +} + +HError SpriteCache::RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers) +{ + for (sprkey_t i = 0; i <= topmost; ++i) + { + _spriteData[i].Offset = in->GetPosition(); + _spriteData[i].Flags = 0; + + int coldep = in->ReadInt16(); + + if (coldep == 0) + { + // Empty slot + if (i > 0) + InitNullSpriteParams(i); + + if (in->EOS()) + break; + continue; + } + + if (in->EOS()) + break; + + if ((size_t)i >= _spriteData.size()) + break; + + _spriteData[i].Flags = SPRCACHEFLAG_ISASSET; + _spriteData[i].Image = nullptr; + + int wdd = in->ReadInt16(); + int htt = in->ReadInt16(); + _sprInfos[i].Width = wdd; + _sprInfos[i].Height = htt; + get_new_size_for_sprite(i, wdd, htt, _sprInfos[i].Width, _sprInfos[i].Height); + + size_t spriteDataSize; + if (vers == kSprfVersion_Compressed) + { + spriteDataSize = in->ReadInt32(); + } + else if (vers >= kSprfVersion_Last32bit) + { + spriteDataSize = this->_compressed ? in->ReadInt32() : wdd * coldep * htt; + } + else + { + spriteDataSize = wdd * coldep * htt; + } + in->Seek(spriteDataSize); + } + return HError::None(); +} + +bool SpriteCache::LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost) +{ + Stream *fidx = Common::AssetManager::OpenAsset(filename); + if (fidx == nullptr) + { + return false; + } + + char buffer[9]; + // check "SPRINDEX" id + fidx->ReadArray(&buffer[0], strlen(spindexid), 1); + buffer[8] = 0; + if (strcmp(buffer, spindexid)) + { + delete fidx; + return false; + } + // check version + SpriteIndexFileVersion vers = (SpriteIndexFileVersion)fidx->ReadInt32(); + if (vers < kSpridxfVersion_Initial || vers > kSpridxfVersion_Current) + { + delete fidx; + return false; + } + if (vers >= kSpridxfVersion_Last32bit) + { + if (fidx->ReadInt32() != expectedFileID) + { + delete fidx; + return false; + } + } + + sprkey_t topmost_index = fidx->ReadInt32(); + // end index+1 should be the same as num sprites + if (fidx->ReadInt32() != topmost_index + 1) + { + delete fidx; + return false; + } + + if (topmost_index != topmost) + { + delete fidx; + return false; + } + + sprkey_t numsprits = topmost_index + 1; + short *rspritewidths = new short[numsprits]; + short *rspriteheights = new short[numsprits]; + soff_t *spriteoffs = new soff_t[numsprits]; + + fidx->ReadArrayOfInt16(&rspritewidths[0], numsprits); + fidx->ReadArrayOfInt16(&rspriteheights[0], numsprits); + if (vers <= kSpridxfVersion_Last32bit) + { + for (sprkey_t i = 0; i < numsprits; ++i) + spriteoffs[i] = fidx->ReadInt32(); + } + else // large file support + { + fidx->ReadArrayOfInt64(spriteoffs, numsprits); + } + + for (sprkey_t i = 0; i <= topmost_index; ++i) + { + if (spriteoffs[i] != 0) + { + _spriteData[i].Flags = SPRCACHEFLAG_ISASSET; + _spriteData[i].Offset = spriteoffs[i] + spr_initial_offs; + get_new_size_for_sprite(i, rspritewidths[i], rspriteheights[i], _sprInfos[i].Width, _sprInfos[i].Height); + } + else if (i > 0) + { + InitNullSpriteParams(i); + } + } + + delete [] rspritewidths; + delete [] rspriteheights; + delete [] spriteoffs; + delete fidx; + return true; +} + +void SpriteCache::DetachFile() +{ + _stream.reset(); + _lastLoad = -2; +} + +int SpriteCache::AttachFile(const char *filename) +{ + _stream.reset(Common::AssetManager::OpenAsset((char *)filename)); + if (_stream == nullptr) + return -1; + return 0; +} + +bool SpriteCache::IsFileCompressed() const +{ + return _compressed; +} diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h new file mode 100644 index 000000000000..7296d227df71 --- /dev/null +++ b/engines/ags/shared/ac/spritecache.h @@ -0,0 +1,240 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Sprite caching system. +// +// TODO: split out sprite serialization into something like "SpriteFile" class. +// SpriteCache should only manage caching and provide bitmaps by demand. +// There should be a separate unit which manages streaming and decompressing. +// Perhaps an interface which would allow multiple implementation depending +// on compression type. +// +// TODO: store sprite data in a specialized container type that is optimized +// for having most keys allocated in large continious sequences by default. +// +// Only for the reference: one of the ideas is for container to have a table +// of arrays of fixed size internally. When getting an item the hash would be +// first divided on array size to find the array the item resides in, then the +// item is taken from item from slot index = (hash - arrsize * arrindex). +// TODO: find out if there is already a hash table kind that follows similar +// principle. +// +//============================================================================= + +#ifndef __SPRCACHE_H +#define __SPRCACHE_H + +#include +#include +#include "core/platform.h" +#include "util/error.h" + +namespace AGS { namespace Common { class Stream; class Bitmap; } } +using namespace AGS; // FIXME later +typedef AGS::Common::HError HAGSError; + +struct SpriteInfo; + +// Tells that the sprite is found in the game resources. +#define SPRCACHEFLAG_ISASSET 0x01 +// Tells that the sprite index was remapped to another existing sprite. +#define SPRCACHEFLAG_REMAPPED 0x02 +// Locked sprites are ones that should not be freed when out of cache space. +#define SPRCACHEFLAG_LOCKED 0x04 + +// Max size of the sprite cache, in bytes +#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS +#define DEFAULTCACHESIZE_KB (32 * 1024) +#else +#define DEFAULTCACHESIZE_KB (128 * 1024) +#endif + +// TODO: research old version differences +enum SpriteFileVersion +{ + kSprfVersion_Uncompressed = 4, + kSprfVersion_Compressed = 5, + kSprfVersion_Last32bit = 6, + kSprfVersion_64bit = 10, + kSprfVersion_HighSpriteLimit = 11, + kSprfVersion_Current = kSprfVersion_HighSpriteLimit +}; + +enum SpriteIndexFileVersion +{ + kSpridxfVersion_Initial = 1, + kSpridxfVersion_Last32bit = 2, + kSpridxfVersion_64bit = 10, + kSpridxfVersion_HighSpriteLimit = 11, + kSpridxfVersion_Current = kSpridxfVersion_HighSpriteLimit +}; + + +typedef int32_t sprkey_t; + +// SpriteFileIndex contains sprite file's table of contents +struct SpriteFileIndex +{ + int SpriteFileIDCheck = 0; // tag matching sprite file and index file + sprkey_t LastSlot = -1; + sprkey_t SpriteCount = 0; + std::vector Widths; + std::vector Heights; + std::vector Offsets; +}; + + +class SpriteCache +{ +public: + static const sprkey_t MIN_SPRITE_INDEX = 1; // 0 is reserved for "empty sprite" + static const sprkey_t MAX_SPRITE_INDEX = INT32_MAX - 1; + static const size_t MAX_SPRITE_SLOTS = INT32_MAX; + + // Standart sprite file and sprite index names + static const Common::String DefaultSpriteFileName; + static const Common::String DefaultSpriteIndexName; + + SpriteCache(std::vector &sprInfos); + ~SpriteCache(); + + // Tells if there is a sprite registered for the given index; + // this includes sprites that were explicitly assigned but failed to init and were remapped + bool DoesSpriteExist(sprkey_t index) const; + // Makes sure sprite cache has allocated slots for all sprites up to the given inclusive limit; + // returns requested index on success, or -1 on failure. + sprkey_t EnlargeTo(sprkey_t topmost); + // Finds a free slot index, if all slots are occupied enlarges sprite bank; returns index + sprkey_t GetFreeIndex(); + // Returns current size of the cache, in bytes + size_t GetCacheSize() const; + // Gets the total size of the locked sprites, in bytes + size_t GetLockedSize() const; + // Returns maximal size limit of the cache, in bytes + size_t GetMaxCacheSize() const; + // Returns number of sprite slots in the bank (this includes both actual sprites and free slots) + sprkey_t GetSpriteSlotCount() const; + // Finds the topmost occupied slot index. Warning: may be slow. + sprkey_t FindTopmostSprite() const; + // Loads sprite and and locks in memory (so it cannot get removed implicitly) + void Precache(sprkey_t index); + // Remap the given index to the sprite 0 + void RemapSpriteToSprite0(sprkey_t index); + // Unregisters sprite from the bank and optionally deletes bitmap + void RemoveSprite(sprkey_t index, bool freeMemory); + // Deletes all loaded (non-locked, non-external) images from the cache; + // this keeps all the auxiliary sprite information intact + void DisposeAll(); + // Deletes all data and resets cache to the clear state + void Reset(); + // Assigns new sprite for the given index; this sprite won't be auto disposed + void SetSprite(sprkey_t index, Common::Bitmap *); + // Assigns new sprite for the given index, remapping it to sprite 0; + // optionally marks it as an asset placeholder + void SetEmptySprite(sprkey_t index, bool as_asset); + // Assigns new bitmap for the *registered* sprite without changing its properties + void SubstituteBitmap(sprkey_t index, Common::Bitmap *); + // Sets max cache size in bytes + void SetMaxCacheSize(size_t size); + + // Loads sprite reference information and inits sprite stream + HAGSError InitFile(const char *filename, const char *sprindex_filename); + // Tells if bitmaps in the file are compressed + bool IsFileCompressed() const; + // Opens file stream + int AttachFile(const char *filename); + // Closes file stream + void DetachFile(); + // Saves all sprites to file; fills in index data for external use + // TODO: refactor to be able to save main file and index file separately (separate function for gather data?) + int SaveToFile(const char *filename, bool compressOutput, SpriteFileIndex &index); + // Saves sprite index table in a separate file + int SaveSpriteIndex(const char *filename, const SpriteFileIndex &index); + + // Loads (if it's not in cache yet) and returns bitmap by the sprite index + Common::Bitmap *operator[] (sprkey_t index); + +private: + void Init(); + // Gets the index of a sprite which data is used for the given slot; + // in case of remapped sprite this will return the one given sprite is remapped to + sprkey_t GetDataIndex(sprkey_t index); + // Load sprite from game resource + size_t LoadSprite(sprkey_t index); + // Seek stream to sprite + void SeekToSprite(sprkey_t index); + // Delete the oldest image in cache + void DisposeOldest(); + + // Information required for the sprite streaming + // TODO: split into sprite cache and sprite stream data + struct SpriteData + { + soff_t Offset; // data offset + soff_t Size; // cache size of element, in bytes + uint32_t Flags; + // TODO: investigate if we may safely use unique_ptr here + // (some of these bitmaps may be assigned from outside of the cache) + Common::Bitmap *Image; // actual bitmap + + // Tells if there actually is a registered sprite in this slot + bool DoesSpriteExist() const; + // Tells if there's a game resource corresponding to this slot + bool IsAssetSprite() const; + // Tells if sprite was added externally, not loaded from game resources + bool IsExternalSprite() const; + // Tells if sprite is locked and should not be disposed by cache logic + bool IsLocked() const; + + SpriteData(); + ~SpriteData(); + }; + + // Provided map of sprite infos, to fill in loaded sprite properties + std::vector &_sprInfos; + // Array of sprite references + std::vector _spriteData; + bool _compressed; // are sprites compressed + + std::unique_ptr _stream; // the sprite stream + sprkey_t _lastLoad; // last loaded sprite index + + size_t _maxCacheSize; // cache size limit + size_t _lockedSize; // size in bytes of currently locked images + size_t _cacheSize; // size in bytes of currently cached images + + // MRU list: the way to track which sprites were used recently. + // When clearing up space for new sprites, cache first deletes the sprites + // that were last time used long ago. + std::vector _mrulist; + std::vector _mrubacklink; + int _liststart; + int _listend; + + // Loads sprite index file + bool LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost); + // Rebuilds sprite index from the main sprite file + HAGSError RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers); + // Writes compressed sprite to the stream + void CompressSprite(Common::Bitmap *sprite, Common::Stream *out); + // Uncompresses sprite from stream into the given bitmap + void UnCompressSprite(Common::Bitmap *sprite, Common::Stream *in); + + // Initialize the empty sprite slot + void InitNullSpriteParams(sprkey_t index); +}; + +extern SpriteCache spriteset; + +#endif // __SPRCACHE_H diff --git a/engines/ags/shared/ac/view.cpp b/engines/ags/shared/ac/view.cpp new file mode 100644 index 000000000000..f3699cb8da02 --- /dev/null +++ b/engines/ags/shared/ac/view.cpp @@ -0,0 +1,214 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/view.h" +#include "util/alignedstream.h" + +using AGS::Common::AlignedStream; +using AGS::Common::Stream; + +ViewFrame::ViewFrame() + : pic(0) + , xoffs(0) + , yoffs(0) + , speed(0) + , flags(0) + , sound(0) +{ + reserved_for_future[0] = 0; + reserved_for_future[1] = 0; +} + +void ViewFrame::ReadFromFile(Stream *in) +{ + pic = in->ReadInt32(); + xoffs = in->ReadInt16(); + yoffs = in->ReadInt16(); + speed = in->ReadInt16(); + flags = in->ReadInt32(); + sound = in->ReadInt32(); + reserved_for_future[0] = in->ReadInt32(); + reserved_for_future[1] = in->ReadInt32(); +} + +void ViewFrame::WriteToFile(Stream *out) +{ + out->WriteInt32(pic); + out->WriteInt16(xoffs); + out->WriteInt16(yoffs); + out->WriteInt16(speed); + out->WriteInt32(flags); + out->WriteInt32(sound); + out->WriteInt32(reserved_for_future[0]); + out->WriteInt32(reserved_for_future[1]); +} + +ViewLoopNew::ViewLoopNew() + : numFrames(0) + , flags(0) + , frames(nullptr) +{ +} + +bool ViewLoopNew::RunNextLoop() +{ + return (flags & LOOPFLAG_RUNNEXTLOOP); +} + +void ViewLoopNew::Initialize(int frameCount) +{ + numFrames = frameCount; + flags = 0; + frames = (ViewFrame*)calloc(numFrames + 1, sizeof(ViewFrame)); +} + +void ViewLoopNew::Dispose() +{ + if (frames != nullptr) + { + free(frames); + frames = nullptr; + numFrames = 0; + } +} + +void ViewLoopNew::WriteToFile_v321(Stream *out) +{ + out->WriteInt16(numFrames); + out->WriteInt32(flags); + WriteFrames_Aligned(out); +} + +void ViewLoopNew::WriteFrames_Aligned(Stream *out) +{ + AlignedStream align_s(out, Common::kAligned_Write); + for (int i = 0; i < numFrames; ++i) + { + frames[i].WriteToFile(&align_s); + align_s.Reset(); + } +} + +void ViewLoopNew::ReadFromFile_v321(Stream *in) +{ + Initialize(in->ReadInt16()); + flags = in->ReadInt32(); + ReadFrames_Aligned(in); + + // an extra frame is allocated in memory to prevent + // crashes with empty loops -- set its picture to teh BLUE CUP!! + frames[numFrames].pic = 0; +} + +void ViewLoopNew::ReadFrames_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < numFrames; ++i) + { + frames[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +ViewStruct::ViewStruct() + : numLoops(0) + , loops(nullptr) +{ +} + +void ViewStruct::Initialize(int loopCount) +{ + numLoops = loopCount; + if (numLoops > 0) + { + loops = (ViewLoopNew*)calloc(numLoops, sizeof(ViewLoopNew)); + } +} + +void ViewStruct::Dispose() +{ + if (numLoops > 0) + { + free(loops); + numLoops = 0; + } +} + +void ViewStruct::WriteToFile(Stream *out) +{ + out->WriteInt16(numLoops); + for (int i = 0; i < numLoops; i++) + { + loops[i].WriteToFile_v321(out); + } +} + +void ViewStruct::ReadFromFile(Stream *in) +{ + Initialize(in->ReadInt16()); + + for (int i = 0; i < numLoops; i++) + { + loops[i].ReadFromFile_v321(in); + } +} + +ViewStruct272::ViewStruct272() + : numloops(0) +{ + memset(numframes, 0, sizeof(numframes)); + memset(loopflags, 0, sizeof(loopflags)); +} + +void ViewStruct272::ReadFromFile(Stream *in) +{ + numloops = in->ReadInt16(); + for (int i = 0; i < 16; ++i) + { + numframes[i] = in->ReadInt16(); + } + in->ReadArrayOfInt32(loopflags, 16); + for (int j = 0; j < 16; ++j) + { + for (int i = 0; i < 20; ++i) + { + frames[j][i].ReadFromFile(in); + } + } +} + +void Convert272ViewsToNew (const std::vector &oldv, ViewStruct *newv) +{ + for (size_t a = 0; a < oldv.size(); a++) { + newv[a].Initialize(oldv[a].numloops); + + for (int b = 0; b < oldv[a].numloops; b++) + { + newv[a].loops[b].Initialize(oldv[a].numframes[b]); + + if ((oldv[a].numframes[b] > 0) && + (oldv[a].frames[b][oldv[a].numframes[b] - 1].pic == -1)) + { + newv[a].loops[b].flags = LOOPFLAG_RUNNEXTLOOP; + newv[a].loops[b].numFrames--; + } + else + newv[a].loops[b].flags = 0; + + for (int c = 0; c < newv[a].loops[b].numFrames; c++) + newv[a].loops[b].frames[c] = oldv[a].frames[b][c]; + } + } +} diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h new file mode 100644 index 000000000000..14afd2b2a7ec --- /dev/null +++ b/engines/ags/shared/ac/view.h @@ -0,0 +1,80 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_VIEW_H +#define __AC_VIEW_H + +#include + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define VFLG_FLIPSPRITE 1 + +struct ViewFrame { + int pic; + short xoffs, yoffs; + short speed; + int flags; + int sound; // play sound when this frame comes round + int reserved_for_future[2]; + ViewFrame(); + + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); +}; + +#define LOOPFLAG_RUNNEXTLOOP 1 + +struct ViewLoopNew +{ + short numFrames; + int flags; + ViewFrame *frames; + + ViewLoopNew(); + void Initialize(int frameCount); + void Dispose(); + bool RunNextLoop(); + void WriteToFile_v321(Common::Stream *out); + void ReadFromFile_v321(Common::Stream *in); + void WriteFrames_Aligned(Common::Stream *out); + void ReadFrames_Aligned(Common::Stream *in); +}; + +struct ViewStruct +{ + short numLoops; + ViewLoopNew *loops; + + ViewStruct(); + void Initialize(int loopCount); + void Dispose(); + void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); +}; + +struct ViewStruct272 { + short numloops; + short numframes[16]; + int loopflags[16]; + ViewFrame frames[16][20]; + + ViewStruct272(); + void ReadFromFile(Common::Stream *in); +}; + +void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *newv); + +#endif // __AC_VIEW_H \ No newline at end of file diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp new file mode 100644 index 000000000000..a50bd46e3517 --- /dev/null +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -0,0 +1,173 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "ac/wordsdictionary.h" +#include "util/stream.h" +#include "util/string_compat.h" + +using AGS::Common::Stream; + +WordsDictionary::WordsDictionary() + : num_words(0) + , word(nullptr) + , wordnum(nullptr) +{ +} + +WordsDictionary::~WordsDictionary() +{ + free_memory(); +} + +void WordsDictionary::allocate_memory(int wordCount) +{ + num_words = wordCount; + if (num_words > 0) + { + word = new char*[wordCount]; + word[0] = new char[wordCount * MAX_PARSER_WORD_LENGTH]; + wordnum = new short[wordCount]; + for (int i = 1; i < wordCount; i++) + { + word[i] = word[0] + MAX_PARSER_WORD_LENGTH * i; + } + } +} + +void WordsDictionary::free_memory() +{ + if (num_words > 0) + { + delete [] word[0]; + delete [] word; + delete [] wordnum; + word = nullptr; + wordnum = nullptr; + num_words = 0; + } +} + +void WordsDictionary::sort () { + int aa, bb; + for (aa = 0; aa < num_words; aa++) { + for (bb = aa + 1; bb < num_words; bb++) { + if (((wordnum[aa] == wordnum[bb]) && (ags_stricmp(word[aa], word[bb]) > 0)) + || (wordnum[aa] > wordnum[bb])) { + short temp = wordnum[aa]; + char tempst[30]; + + wordnum[aa] = wordnum[bb]; + wordnum[bb] = temp; + strcpy(tempst, word[aa]); + strcpy(word[aa], word[bb]); + strcpy(word[bb], tempst); + bb = aa; + } + } + } +} + +int WordsDictionary::find_index (const char*wrem) { + int aa; + for (aa = 0; aa < num_words; aa++) { + if (ags_stricmp (wrem, word[aa]) == 0) + return aa; + } + return -1; +} + +const char *passwencstring = "Avis Durgan"; + +void decrypt_text(char*toenc) { + int adx = 0; + + while (1) { + toenc[0] -= passwencstring[adx]; + if (toenc[0] == 0) + break; + + adx++; + toenc++; + + if (adx > 10) + adx = 0; + } +} + +void read_string_decrypt(Stream *in, char *buf, size_t buf_sz) { + size_t len = in->ReadInt32(); + size_t slen = std::min(buf_sz - 1, len); + in->Read(buf, slen); + if (len > slen) + in->Seek(len - slen); + buf[slen] = 0; + decrypt_text(buf); +} + +void read_dictionary (WordsDictionary *dict, Stream *out) { + int ii; + + dict->allocate_memory(out->ReadInt32()); + for (ii = 0; ii < dict->num_words; ii++) { + read_string_decrypt (out, dict->word[ii], MAX_PARSER_WORD_LENGTH); + dict->wordnum[ii] = out->ReadInt16(); + } +} + +#if defined (OBSOLETE) +// TODO: not a part of wordsdictionary, move to obsoletes +void freadmissout(short *pptr, Stream *in) { + in->ReadArrayOfInt16(&pptr[0], 5); + in->ReadArrayOfInt16(&pptr[7], NUM_CONDIT - 7); + pptr[5] = pptr[6] = 0; +} +#endif + +void encrypt_text(char *toenc) { + int adx = 0, tobreak = 0; + + while (tobreak == 0) { + if (toenc[0] == 0) + tobreak = 1; + + toenc[0] += passwencstring[adx]; + adx++; + toenc++; + + if (adx > 10) + adx = 0; + } +} + +void write_string_encrypt(Stream *out, const char *s) { + int stlent = (int)strlen(s) + 1; + + out->WriteInt32(stlent); + char *enc = ags_strdup(s); + encrypt_text(enc); + out->WriteArray(enc, stlent, 1); + free(enc); +} + +void write_dictionary (WordsDictionary *dict, Stream *out) { + int ii; + + out->WriteInt32(dict->num_words); + for (ii = 0; ii < dict->num_words; ii++) { + write_string_encrypt (out, dict->word[ii]); + out->WriteInt16(dict->wordnum[ii]);//__putshort__lilendian(dict->wordnum[ii], writeto); + } +} diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h new file mode 100644 index 000000000000..bfb7247709fc --- /dev/null +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -0,0 +1,55 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_WORDSDICTIONARY_H +#define __AC_WORDSDICTIONARY_H + +#include "core/types.h" + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +#define MAX_PARSER_WORD_LENGTH 30 +#define ANYWORD 29999 +#define RESTOFLINE 30000 + +struct WordsDictionary { + int num_words; + char**word; + short*wordnum; + + WordsDictionary(); + ~WordsDictionary(); + void allocate_memory(int wordCount); + void free_memory(); + void sort(); + int find_index (const char *); +}; + +extern const char *passwencstring; + +extern void decrypt_text(char*toenc); +extern void read_string_decrypt(Common::Stream *in, char *buf, size_t buf_sz); +extern void read_dictionary (WordsDictionary *dict, Common::Stream *in); + +#if defined (OBSOLETE) +// TODO: not a part of wordsdictionary, move to obsoletes +extern void freadmissout(short *pptr, Common::Stream *in); +#endif + +extern void encrypt_text(char *toenc); +extern void write_string_encrypt(Common::Stream *out, const char *s); +extern void write_dictionary (WordsDictionary *dict, Common::Stream *out); + +#endif // __AC_WORDSDICTIONARY_H \ No newline at end of file diff --git a/engines/ags/shared/api/stream_api.h b/engines/ags/shared/api/stream_api.h new file mode 100644 index 000000000000..d78e08c7cc32 --- /dev/null +++ b/engines/ags/shared/api/stream_api.h @@ -0,0 +1,90 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// IAGSStream is a contract for stream class, provided by engine to plugin +// on the need, such as saving/restoring the game. +// The user is advised to use advanced helper methods, such as Read/WriteX +// and Read/WriteArrayOfX to allow the stream implementation properly control +// endianness conversions and data padding, when needed. +// +//============================================================================= +#ifndef __AGS_CN_API__IAGSSTREAM_H +#define __AGS_CN_API__IAGSSTREAM_H + +// TODO: it would probably be better to not include core definition headers +// in API class headers, but make separate core headers specifically for +// plugins, and let plugin developers include them manually in plugin sources. +#include "core/types.h" + +namespace AGS +{ +namespace Common +{ + +enum StreamSeek +{ + kSeekBegin, + kSeekCurrent, + kSeekEnd +}; + +class IAGSStream +{ +public: + virtual ~IAGSStream() = default; + + virtual void Close() = 0; + + virtual bool IsValid() const = 0; + virtual bool EOS() const = 0; + virtual soff_t GetLength() const = 0; + virtual soff_t GetPosition() const = 0; + virtual bool CanRead() const = 0; + virtual bool CanWrite() const = 0; + virtual bool CanSeek() const = 0; + + virtual size_t Read(void *buffer, size_t size) = 0; + virtual int32_t ReadByte() = 0; + virtual size_t Write(const void *buffer, size_t size) = 0; + virtual int32_t WriteByte(uint8_t b) = 0; + + virtual int8_t ReadInt8() = 0; + virtual int16_t ReadInt16() = 0; + virtual int32_t ReadInt32() = 0; + virtual int64_t ReadInt64() = 0; + virtual bool ReadBool() = 0; + virtual size_t ReadArray(void *buffer, size_t elem_size, size_t count) = 0; + virtual size_t ReadArrayOfInt8(int8_t *buffer, size_t count) = 0; + virtual size_t ReadArrayOfInt16(int16_t *buffer, size_t count) = 0; + virtual size_t ReadArrayOfInt32(int32_t *buffer, size_t count) = 0; + virtual size_t ReadArrayOfInt64(int64_t *buffer, size_t count) = 0; + + virtual size_t WriteInt8(int8_t val) = 0;; + virtual size_t WriteInt16(int16_t val) = 0; + virtual size_t WriteInt32(int32_t val) = 0; + virtual size_t WriteInt64(int64_t val) = 0; + virtual size_t WriteBool(bool val) = 0; + virtual size_t WriteArray(const void *buffer, size_t elem_size, size_t count) = 0; + virtual size_t WriteArrayOfInt8(const int8_t *buffer, size_t count) = 0; + virtual size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) = 0; + virtual size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) = 0; + virtual size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) = 0; + + virtual bool Seek(soff_t offset, StreamSeek origin = kSeekCurrent) = 0; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_API__IAGSSTREAM_H diff --git a/engines/ags/shared/core/asset.cpp b/engines/ags/shared/core/asset.cpp new file mode 100644 index 000000000000..86483b9352c3 --- /dev/null +++ b/engines/ags/shared/core/asset.cpp @@ -0,0 +1,37 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/asset.h" + +namespace AGS +{ +namespace Common +{ + +AssetInfo::AssetInfo() + : LibUid(0) + , Offset(0) + , Size(0) +{ +} +void AssetLibInfo::Unload() +{ + BaseFileName = ""; + BaseFilePath = ""; + LibFileNames.clear(); + AssetInfos.clear(); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h new file mode 100644 index 000000000000..e619491e2e88 --- /dev/null +++ b/engines/ags/shared/core/asset.h @@ -0,0 +1,60 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AssetInfo and AssetLibInfo - classes describing generic asset library. +// +//============================================================================= + +#ifndef __AGS_CN_CORE__ASSET_H +#define __AGS_CN_CORE__ASSET_H + +#include +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +// Information on single asset +struct AssetInfo +{ + // A pair of filename and libuid is assumed to be unique in game scope + String FileName; // filename associated with asset + int32_t LibUid; // uid of library, containing this asset + soff_t Offset; // asset's position in library file (in bytes) + soff_t Size; // asset's size (in bytes) + + AssetInfo(); +}; + +typedef std::vector AssetVec; + +// Information on multifile asset library +struct AssetLibInfo +{ + String BaseFileName; // library's base (head) filename + String BaseFilePath; // full path to the base filename + std::vector LibFileNames; // filename for each library part + + // Library contents + AssetVec AssetInfos; // information on contained assets + + void Unload(); +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_CORE__ASSET_H diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp new file mode 100644 index 000000000000..26c5ca26c46b --- /dev/null +++ b/engines/ags/shared/core/assetmanager.cpp @@ -0,0 +1,428 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/assetmanager.h" +#include "util/misc.h" // ci_fopen +#include "util/multifilelib.h" +#include "util/path.h" +#include "util/string_utils.h" + + +namespace AGS +{ +namespace Common +{ + +AssetLocation::AssetLocation() + : Offset(0) + , Size(0) +{ +} + + +AssetManager *AssetManager::_theAssetManager = nullptr; + +/* static */ bool AssetManager::CreateInstance() +{ + // Issue a warning - recreating asset manager is not a normal behavior + assert(_theAssetManager == NULL); + delete _theAssetManager; + _theAssetManager = new AssetManager(); + _theAssetManager->SetSearchPriority(kAssetPriorityDir); + return _theAssetManager != nullptr; // well, we should return _something_ +} + +/* static */ void AssetManager::DestroyInstance() +{ + delete _theAssetManager; + _theAssetManager = nullptr; +} + +AssetManager::~AssetManager() +{ + delete &_assetLib; +} + +/* static */ bool AssetManager::SetSearchPriority(AssetSearchPriority priority) +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_SetSearchPriority(priority) : false; +} + +/* static */ AssetSearchPriority AssetManager::GetSearchPriority() +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetSearchPriority() : kAssetPriorityUndefined; +} + +/* static */ bool AssetManager::IsDataFile(const String &data_file) +{ + Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + if (in) + { + MFLUtil::MFLError err = MFLUtil::TestIsMFL(in, true); + delete in; + return err == MFLUtil::kMFLNoError; + } + return false; +} + +AssetError AssetManager::ReadDataFileTOC(const String &data_file, AssetLibInfo &lib) +{ + Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + if (in) + { + MFLUtil::MFLError err = MFLUtil::ReadHeader(lib, in); + delete in; + return (err != MFLUtil::kMFLNoError) ? kAssetErrLibParse : kAssetNoError; + } + return kAssetErrNoLibFile; +} + +/* static */ AssetError AssetManager::SetDataFile(const String &data_file) +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_SetDataFile(data_file) : kAssetErrNoManager; +} + +/* static */ String AssetManager::GetLibraryForAsset(const String &asset_name) +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetLibraryForAsset(asset_name) : ""; +} + +/* static */ soff_t AssetManager::GetAssetOffset(const String &asset_name) +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetOffset(asset_name) : 0; +} + +/* static */ soff_t AssetManager::GetAssetSize(const String &asset_name) +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetSize(asset_name) : 0; +} + +/* static */ soff_t AssetManager::GetLastAssetSize() +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetLastAssetSize() : 0; +} + +/* static */ int AssetManager::GetAssetCount() +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetCount() : 0; +} + +/* static */ String AssetManager::GetAssetFileByIndex(int index) +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetFileByIndex(index) : ""; +} + +/* static */ String AssetManager::GetLibraryBaseFile() +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetLibraryBaseFile() : ""; +} + +/* static */ const AssetLibInfo *AssetManager::GetLibraryTOC() +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? &_theAssetManager->_GetLibraryTOC() : nullptr; +} + +/* static */ bool AssetManager::GetAssetLocation(const String &asset_name, AssetLocation &loc) +{ + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->GetAssetByPriority(asset_name, loc, kFile_Open, kFile_Read) : false; +} + +/* static */ bool AssetManager::DoesAssetExist(const String &asset_name) +{ + assert(_theAssetManager != NULL); + if (!_theAssetManager) + { + return false; + } + return _theAssetManager->_DoesAssetExist(asset_name); +} + +/* static */ Stream *AssetManager::OpenAsset(const String &asset_name, + FileOpenMode open_mode, + FileWorkMode work_mode) +{ + assert(_theAssetManager != NULL); + if (!_theAssetManager) + { + return nullptr; + } + return _theAssetManager->OpenAssetAsStream(asset_name, open_mode, work_mode); +} + +AssetManager::AssetManager() + : _assetLib(*new AssetLibInfo()) + , _searchPriority(kAssetPriorityDir) + , _lastAssetSize(0) +{ +} + +bool AssetManager::_SetSearchPriority(AssetSearchPriority priority) +{ + _searchPriority = priority; + return true; +} + +AssetSearchPriority AssetManager::_GetSearchPriority() +{ + return _searchPriority; +} + +AssetError AssetManager::_SetDataFile(const String &data_file) +{ + if (data_file.IsEmpty()) + { + return kAssetErrNoLibFile; + } + if (Path::ComparePaths(_assetLib.BaseFilePath, data_file) == 0) + { + return kAssetNoError; + } + AssetError err = RegisterAssetLib(data_file, ""); + return err; +} + +String AssetManager::_GetLibraryForAsset(const String &asset_name) +{ + if (asset_name.IsEmpty()) + { + return ""; + } + AssetInfo *asset = FindAssetByFileName(asset_name); + if (!asset) + { + // asset not found + return ""; + } + + return MakeLibraryFileNameForAsset(asset); +} + +soff_t AssetManager::_GetAssetOffset(const String &asset_name) +{ + if (asset_name.IsEmpty()) + { + return -1; + } + AssetInfo *asset = FindAssetByFileName(asset_name); + if (asset) + { + return asset->Offset; + } + return -1; +} + +soff_t AssetManager::_GetAssetSize(const String &asset_name) +{ + if (asset_name.IsEmpty()) + { + return -1; + } + AssetInfo *asset = FindAssetByFileName(asset_name); + if (asset) + { + return asset->Size; + } + return -1; +} + +soff_t AssetManager::_GetLastAssetSize() +{ + return _lastAssetSize; +} + +int AssetManager::_GetAssetCount() +{ + return _assetLib.AssetInfos.size(); +} + +String AssetManager::_GetAssetFileByIndex(int index) +{ + if ((index < 0) || ((size_t)index >= _assetLib.AssetInfos.size())) + return nullptr; + + return _assetLib.AssetInfos[index].FileName; +} + +String AssetManager::_GetLibraryBaseFile() +{ + return _assetLib.BaseFileName; +} + +const AssetLibInfo &AssetManager::_GetLibraryTOC() const +{ + return _assetLib; +} + +bool AssetManager::_DoesAssetExist(const String &asset_name) +{ + return FindAssetByFileName(asset_name) != nullptr || + File::TestReadFile(asset_name); +} + +AssetError AssetManager::RegisterAssetLib(const String &data_file, const String &password) +{ + // base path is current directory + _basePath = "."; + + // open data library + Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + if (!in) + return kAssetErrNoLibFile; // can't be opened, return error code + + // read MultiFileLibrary header (CLIB) + // PSP: allocate struct on the heap to avoid overflowing the stack. + MFLUtil::MFLError mfl_err = MFLUtil::ReadHeader(_assetLib, in); + delete in; + + if (mfl_err != MFLUtil::kMFLNoError) + { + _assetLib.Unload(); + return kAssetErrLibParse; + } + + // fixup base library filename + String nammwas = data_file; + String data_file_fixed = data_file; + // TODO: this algorythm should be in path/string utils + data_file_fixed.TruncateToRightSection('\\'); + data_file_fixed.TruncateToRightSection('/'); + if (data_file_fixed.Compare(nammwas) != 0) + { + // store complete path + _basePath = nammwas; + _basePath.TruncateToLeft(nammwas.GetLength() - data_file_fixed.GetLength()); + _basePath.TrimRight('\\'); + _basePath.TrimRight('/'); + } + + // set library filename + _assetLib.LibFileNames[0] = data_file_fixed; + // make a lowercase backup of the original file name + _assetLib.BaseFileName = data_file_fixed; + _assetLib.BaseFileName.MakeLower(); + _assetLib.BaseFilePath = Path::MakeAbsolutePath(data_file); + return kAssetNoError; +} + +AssetInfo *AssetManager::FindAssetByFileName(const String &asset_name) +{ + for (size_t i = 0; i < _assetLib.AssetInfos.size(); ++i) + { + if (_assetLib.AssetInfos[i].FileName.CompareNoCase(asset_name) == 0) + { + return &_assetLib.AssetInfos[i]; + } + } + return nullptr; +} + +String AssetManager::MakeLibraryFileNameForAsset(const AssetInfo *asset) +{ + // deduce asset library file containing this asset + return String::FromFormat("%s/%s",_basePath.GetCStr(), _assetLib.LibFileNames[asset->LibUid].GetCStr()); +} + +bool AssetManager::GetAssetFromLib(const String &asset_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) +{ + if (open_mode != Common::kFile_Open || work_mode != Common::kFile_Read) + return false; // creating/writing is allowed only for common files on disk + + AssetInfo *asset = FindAssetByFileName(asset_name); + if (!asset) + return false; // asset not found + + String libfile = cbuf_to_string_and_free( ci_find_file(nullptr, MakeLibraryFileNameForAsset(asset)) ); + if (libfile.IsEmpty()) + return false; + loc.FileName = libfile; + loc.Offset = asset->Offset; + loc.Size = asset->Size; + return true; +} + +bool AssetManager::GetAssetFromDir(const String &file_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) +{ + String exfile = cbuf_to_string_and_free( ci_find_file(nullptr, file_name) ); + if (exfile.IsEmpty() || !Path::IsFile(exfile)) + return false; + loc.FileName = exfile; + loc.Offset = 0; + loc.Size = File::GetFileSize(exfile); + return true; +} + +bool AssetManager::GetAssetByPriority(const String &asset_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) +{ + if (_searchPriority == kAssetPriorityDir) + { + // check for disk, otherwise use datafile + return GetAssetFromDir(asset_name, loc, open_mode, work_mode) || + GetAssetFromLib(asset_name, loc, open_mode, work_mode); + } + else if (_searchPriority == kAssetPriorityLib) + { + // check datafile first, then scan directory + return GetAssetFromLib(asset_name, loc, open_mode, work_mode) || + GetAssetFromDir(asset_name, loc, open_mode, work_mode); + } + return false; +} + +Stream *AssetManager::OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode) +{ + AssetLocation loc; + if (GetAssetByPriority(asset_name, loc, open_mode, work_mode)) + { + Stream *s = File::OpenFile(loc.FileName, open_mode, work_mode); + if (s) + { + s->Seek(loc.Offset, kSeekBegin); + _lastAssetSize = loc.Size; + } + return s; + } + return nullptr; +} + + +String GetAssetErrorText(AssetError err) +{ + switch (err) + { + case kAssetNoError: + return "No error."; + case kAssetErrNoLibFile: + return "Asset library file not found or could not be opened."; + case kAssetErrLibParse: + return "Not an asset library or unsupported format."; + case kAssetErrNoManager: + return "Asset manager is not initialized."; + } + return "Unknown error."; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h new file mode 100644 index 000000000000..8a765679ad2d --- /dev/null +++ b/engines/ags/shared/core/assetmanager.h @@ -0,0 +1,155 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Asset manager class fore reading and writing game resources +// Asset manager is a singleton +//----------------------------------------------------------------------------- +// +// The code is based on CLIB32, by Chris Jones (1998-99), DJGPP implementation +// of the CLIB reader. +// +//----------------------------------------------------------------------------- +// +// TODO: +// Ideally AssetManager should take care of enumerating all existing data +// packages and all files in them, while the game itself should not know where +// it receives the data from. +// Files should be registered based on their source package and their types. +// The user must not have access to this information, but is allowed to query +// all files of certain type (perhaps, filtered and ordered by their id). +// +//============================================================================= + +#ifndef __AGS_CN_CORE__ASSETMANAGER_H +#define __AGS_CN_CORE__ASSETMANAGER_H + +#include "util/file.h" // TODO: extract filestream mode constants or introduce generic ones + +namespace AGS +{ +namespace Common +{ + +class Stream; +struct MultiFileLib; +struct AssetLibInfo; +struct AssetInfo; + +enum AssetSearchPriority +{ + // TODO: rename this to something more obvious + kAssetPriorityUndefined, + kAssetPriorityLib, + kAssetPriorityDir +}; + +enum AssetError +{ + kAssetNoError = 0, + kAssetErrNoLibFile = -1, // library file not found or can't be read + kAssetErrLibParse = -2, // bad library file format or read error + kAssetErrNoManager = -6, // asset manager not initialized +}; + +// Explicit location of asset data +struct AssetLocation +{ + String FileName; // file where asset is located + soff_t Offset; // asset's position in file (in bytes) + soff_t Size; // asset's size (in bytes) + + AssetLocation(); +}; + + +class AssetManager +{ +public: + static bool CreateInstance(); + static void DestroyInstance(); + ~AssetManager(); + + static bool SetSearchPriority(AssetSearchPriority priority); + static AssetSearchPriority GetSearchPriority(); + + // Test if given file is main data file + static bool IsDataFile(const String &data_file); + // Read data file table of contents into provided struct + static AssetError ReadDataFileTOC(const String &data_file, AssetLibInfo &lib); + + // NOTE: this group of methods are only temporarily public + static AssetError SetDataFile(const String &data_file); + static String GetLibraryBaseFile(); + static const AssetLibInfo *GetLibraryTOC(); + static int GetAssetCount(); + static String GetLibraryForAsset(const String &asset_name); + static String GetAssetFileByIndex(int index); + static soff_t GetAssetOffset(const String &asset_name); + static soff_t GetAssetSize(const String &asset_name); + // TODO: instead of this support streams that work in a file subsection, limited by size + static soff_t GetLastAssetSize(); + // TODO: this is a workaround that lets us use back-end specific kind of streams + // to read the asset data. This is not ideal, because it limits us to reading from file. + // The better solution could be returning a standart stream object (like std::stream, + // or even std::streambuf), which is used to initialize both AGS and back-end compatible + // stream wrappers. + static bool GetAssetLocation(const String &asset_name, AssetLocation &loc); + + static bool DoesAssetExist(const String &asset_name); + static Stream *OpenAsset(const String &asset_name, + FileOpenMode open_mode = kFile_Open, + FileWorkMode work_mode = kFile_Read); + +private: + AssetManager(); + + bool _SetSearchPriority(AssetSearchPriority priority); + AssetSearchPriority _GetSearchPriority(); + AssetError _SetDataFile(const String &data_file); + String _GetLibraryBaseFile(); + const AssetLibInfo &_GetLibraryTOC() const; + int _GetAssetCount(); + String _GetLibraryForAsset(const String &asset_name); + String _GetAssetFileByIndex(int index); + soff_t _GetAssetOffset(const String &asset_name); + soff_t _GetAssetSize(const String &asset_name); + soff_t _GetLastAssetSize(); + + AssetError RegisterAssetLib(const String &data_file, const String &password); + + bool _DoesAssetExist(const String &asset_name); + + AssetInfo *FindAssetByFileName(const String &asset_name); + String MakeLibraryFileNameForAsset(const AssetInfo *asset); + + bool GetAssetFromLib(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); + bool GetAssetFromDir(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); + bool GetAssetByPriority(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); + Stream *OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode); + + static AssetManager *_theAssetManager; + AssetSearchPriority _searchPriority; + + AssetLibInfo &_assetLib; + String _basePath; // library's parent path (directory) + soff_t _lastAssetSize; // size of asset that was opened last time +}; + + +String GetAssetErrorText(AssetError err); + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_CORE__ASSETMANAGER_H diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h new file mode 100644 index 000000000000..05857771caa4 --- /dev/null +++ b/engines/ags/shared/core/def_version.h @@ -0,0 +1,17 @@ +#ifndef __AGS_CN_CORE__DEFVERSION_H +#define __AGS_CN_CORE__DEFVERSION_H + +#define ACI_VERSION_STR "3.5.1.0" +#if defined (RC_INVOKED) // for MSVC resource compiler +#define ACI_VERSION_MSRC_DEF 3,5,1,0 +#endif + +#ifdef NO_MP3_PLAYER +#define SPECIAL_VERSION "NMP" +#else +#define SPECIAL_VERSION "" +#endif + +#define ACI_COPYRIGHT_YEARS "2011-2020" + +#endif // __AGS_CN_CORE__DEFVERSION_H diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h new file mode 100644 index 000000000000..b4ded89ed9f5 --- /dev/null +++ b/engines/ags/shared/core/platform.h @@ -0,0 +1,105 @@ +#ifndef __AC_PLATFORM_H +#define __AC_PLATFORM_H + +// platform definitions. Not intended for replacing types or checking for libraries. + +// check Android first because sometimes it can get confused with host OS +#if defined(__ANDROID__) || defined(ANDROID) + #define AGS_PLATFORM_OS_WINDOWS (0) + #define AGS_PLATFORM_OS_LINUX (0) + #define AGS_PLATFORM_OS_MACOS (0) + #define AGS_PLATFORM_OS_ANDROID (1) + #define AGS_PLATFORM_OS_IOS (0) + #define AGS_PLATFORM_OS_PSP (0) +#elif defined(_WIN32) + //define something for Windows (32-bit and 64-bit) + #define AGS_PLATFORM_OS_WINDOWS (1) + #define AGS_PLATFORM_OS_LINUX (0) + #define AGS_PLATFORM_OS_MACOS (0) + #define AGS_PLATFORM_OS_ANDROID (0) + #define AGS_PLATFORM_OS_IOS (0) + #define AGS_PLATFORM_OS_PSP (0) +#elif defined(__APPLE__) + #include "TargetConditionals.h" + #ifndef TARGET_OS_SIMULATOR + #define TARGET_OS_SIMULATOR (0) + #endif + #ifndef TARGET_OS_IOS + #define TARGET_OS_IOS (0) + #endif + #ifndef TARGET_OS_OSX + #define TARGET_OS_OSX (0) + #endif + + #if TARGET_OS_SIMULATOR || TARGET_IPHONE_SIMULATOR + #define AGS_PLATFORM_OS_WINDOWS (0) + #define AGS_PLATFORM_OS_LINUX (0) + #define AGS_PLATFORM_OS_MACOS (0) + #define AGS_PLATFORM_OS_ANDROID (0) + #define AGS_PLATFORM_OS_IOS (1) + #define AGS_PLATFORM_OS_PSP (0) + #elif TARGET_OS_IOS || TARGET_OS_IPHONE + #define AGS_PLATFORM_OS_WINDOWS (0) + #define AGS_PLATFORM_OS_LINUX (0) + #define AGS_PLATFORM_OS_MACOS (0) + #define AGS_PLATFORM_OS_ANDROID (0) + #define AGS_PLATFORM_OS_IOS (1) + #define AGS_PLATFORM_OS_PSP (0) + #elif TARGET_OS_OSX || TARGET_OS_MAC + #define AGS_PLATFORM_OS_WINDOWS (0) + #define AGS_PLATFORM_OS_LINUX (0) + #define AGS_PLATFORM_OS_MACOS (1) + #define AGS_PLATFORM_OS_ANDROID (0) + #define AGS_PLATFORM_OS_IOS (0) + #define AGS_PLATFORM_OS_PSP (0) + #else + #error "Unknown Apple platform" + #endif +#elif defined(__linux__) + #define AGS_PLATFORM_OS_WINDOWS (0) + #define AGS_PLATFORM_OS_LINUX (1) + #define AGS_PLATFORM_OS_MACOS (0) + #define AGS_PLATFORM_OS_ANDROID (0) + #define AGS_PLATFORM_OS_IOS (0) + #define AGS_PLATFORM_OS_PSP (0) +#else + #error "Unknown platform" +#endif + + +#if defined(__LP64__) + // LP64 machine, OS X or Linux + // int 32bit | long 64bit | long long 64bit | void* 64bit + #define AGS_PLATFORM_64BIT (1) +#elif defined(_WIN64) + // LLP64 machine, Windows + // int 32bit | long 32bit | long long 64bit | void* 64bit + #define AGS_PLATFORM_64BIT (1) +#else + // 32-bit machine, Windows or Linux or OS X + // int 32bit | long 32bit | long long 64bit | void* 32bit + #define AGS_PLATFORM_64BIT (0) +#endif + +#if defined(_WIN32) + #define AGS_PLATFORM_ENDIAN_LITTLE (1) + #define AGS_PLATFORM_ENDIAN_BIG (0) +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define AGS_PLATFORM_ENDIAN_LITTLE (1) + #define AGS_PLATFORM_ENDIAN_BIG (0) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define AGS_PLATFORM_ENDIAN_LITTLE (0) + #define AGS_PLATFORM_ENDIAN_BIG (1) +#else + #error "Unknown platform" +#endif + +#if defined(_DEBUG) + #define AGS_PLATFORM_DEBUG (1) +#elif ! defined(NDEBUG) + #define AGS_PLATFORM_DEBUG (1) +#else + #define AGS_PLATFORM_DEBUG (0) +#endif + +#endif // __AC_PLATFORM_H \ No newline at end of file diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h new file mode 100644 index 000000000000..eadeb6ee34f0 --- /dev/null +++ b/engines/ags/shared/core/types.h @@ -0,0 +1,61 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Basic types definition +// +//============================================================================= +#ifndef __AGS_CN_CORE__TYPES_H +#define __AGS_CN_CORE__TYPES_H + +#include +#include +#include // for size_t +#include // for _WORDSIZE + +#ifndef NULL +#define NULL nullptr +#endif + +// Not all compilers have this. Added in clang and gcc followed +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef FORCEINLINE + #ifdef _MSC_VER + #define FORCEINLINE __forceinline + + #elif defined (__GNUC__) || __has_attribute(__always_inline__) + #define FORCEINLINE inline __attribute__((__always_inline__)) + + #else + #define FORCEINLINE inline + + #endif +#endif + +// Stream offset type +typedef int64_t soff_t; + +#define fixed_t int32_t // fixed point type +#define color_t int32_t + +// TODO: use distinct fixed point class +enum +{ + kShift = 16, + kUnit = 1 << kShift +}; + +#endif // __AGS_CN_CORE__TYPES_H diff --git a/engines/ags/shared/debugging/assert.h b/engines/ags/shared/debugging/assert.h new file mode 100644 index 000000000000..34b1eb043f52 --- /dev/null +++ b/engines/ags/shared/debugging/assert.h @@ -0,0 +1,23 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Debug assertion tools +// +//============================================================================= +#ifndef __AGS_CN_DEBUG__ASSERT_H +#define __AGS_CN_DEBUG__ASSERT_H + +#include + +#endif // __AGS_CN_DEBUG__ASSERT_H diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp new file mode 100644 index 000000000000..30558fe0e550 --- /dev/null +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -0,0 +1,254 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include +#include "debug/debugmanager.h" +#include "util/string_types.h" + +namespace AGS +{ +namespace Common +{ + +DebugOutput::DebugOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity, bool enabled) + : _id(id) + , _handler(handler) + , _enabled(enabled) + , _defaultVerbosity(def_verbosity) +{ + _groupFilter.resize(DbgMgr._lastGroupID + 1, _defaultVerbosity); +} + +String DebugOutput::GetID() const +{ + return _id; +} + +IOutputHandler *DebugOutput::GetHandler() const +{ + return _handler; +} + +bool DebugOutput::IsEnabled() const +{ + return _enabled; +} + +void DebugOutput::SetEnabled(bool enable) +{ + _enabled = enable; +} + +void DebugOutput::SetGroupFilter(DebugGroupID id, MessageType verbosity) +{ + uint32_t key = DbgMgr.GetGroup(id).UID.ID; + if (key != kDbgGroup_None) + _groupFilter[key] = verbosity; + else + _unresolvedGroups.insert(std::make_pair(id.SID, verbosity)); +} + +void DebugOutput::SetAllGroupFilters(MessageType verbosity) +{ + for (auto &group : _groupFilter) + group = verbosity; + for (auto &group : _unresolvedGroups) + group.second = verbosity; +} + +void DebugOutput::ClearGroupFilters() +{ + for (auto &gf : _groupFilter) + gf = kDbgMsg_None; + _unresolvedGroups.clear(); +} + +void DebugOutput::ResolveGroupID(DebugGroupID id) +{ + if (!id.IsValid()) + return; + + DebugGroupID real_id = DbgMgr.GetGroup(id).UID; + if (real_id.IsValid()) + { + if (_groupFilter.size() <= id.ID) + _groupFilter.resize(id.ID + 1, _defaultVerbosity); + GroupNameToMTMap::const_iterator it = _unresolvedGroups.find(real_id.SID); + if (it != _unresolvedGroups.end()) + { + _groupFilter[real_id.ID] = it->second; + _unresolvedGroups.erase(it); + } + } +} + +bool DebugOutput::TestGroup(DebugGroupID id, MessageType mt) const +{ + DebugGroupID real_id = DbgMgr.GetGroup(id).UID; + if (real_id.ID == kDbgGroup_None || real_id.ID >= _groupFilter.size()) + return false; + return (_groupFilter[real_id.ID] >= mt) != 0; +} + +DebugManager::DebugManager() +{ + // Add hardcoded groups + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Main, "main"), "")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Game, "game"), "Game")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Script, "script"), "Script")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_SprCache, "sprcache"), "Sprite cache")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_ManObj, "manobj"), "Managed obj")); + _firstFreeGroupID = _groups.size(); + _lastGroupID = _firstFreeGroupID; +} + +DebugGroup DebugManager::GetGroup(DebugGroupID id) +{ + if (id.ID != kDbgGroup_None) + { + return id.ID < _groups.size() ? _groups[id.ID] : DebugGroup(); + } + else if (!id.SID.IsEmpty()) + { + GroupByStringMap::const_iterator it = _groupByStrLookup.find(id.SID); + return it != _groupByStrLookup.end() ? _groups[it->second.ID] : DebugGroup(); + } + return DebugGroup(); +} + +PDebugOutput DebugManager::GetOutput(const String &id) +{ + OutMap::const_iterator it = _outputs.find(id); + return it != _outputs.end() ? it->second.Target : PDebugOutput(); +} + +DebugGroup DebugManager::RegisterGroup(const String &id, const String &out_name) +{ + DebugGroup group = GetGroup(id); + if (group.UID.IsValid()) + return group; + group = DebugGroup(DebugGroupID(++DbgMgr._lastGroupID, id), out_name); + _groups.push_back(group); + _groupByStrLookup[group.UID.SID] = group.UID; + + // Resolve group reference on every output target + for (OutMap::const_iterator it = _outputs.begin(); it != _outputs.end(); ++it) + { + it->second.Target->ResolveGroupID(group.UID); + } + return group; +} + +void DebugManager::RegisterGroup(const DebugGroup &group) +{ + _groups.push_back(group); + _groupByStrLookup[group.UID.SID] = group.UID; +} + +PDebugOutput DebugManager::RegisterOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity, bool enabled) +{ + _outputs[id].Target = PDebugOutput(new DebugOutput(id, handler, def_verbosity, enabled)); + _outputs[id].Suppressed = false; + return _outputs[id].Target; +} + +void DebugManager::UnregisterAll() +{ + _lastGroupID = _firstFreeGroupID; + _groups.clear(); + _groupByStrLookup.clear(); + _outputs.clear(); +} + +void DebugManager::UnregisterGroup(DebugGroupID id) +{ + DebugGroup group = GetGroup(id); + if (!group.UID.IsValid()) + return; + _groups[group.UID.ID] = DebugGroup(); + _groupByStrLookup.erase(group.UID.SID); +} + +void DebugManager::UnregisterOutput(const String &id) +{ + _outputs.erase(id); +} + +void DebugManager::Print(DebugGroupID group_id, MessageType mt, const String &text) +{ + const DebugGroup &group = GetGroup(group_id); + DebugMessage msg(text, group.UID.ID, group.OutputName, mt); + + for (OutMap::iterator it = _outputs.begin(); it != _outputs.end(); ++it) + { + SendMessage(it->second, msg); + } +} + +void DebugManager::SendMessage(const String &out_id, const DebugMessage &msg) +{ + OutMap::iterator it = _outputs.find(out_id); + if (it != _outputs.end()) + SendMessage(it->second, msg); +} + +void DebugManager::SendMessage(OutputSlot &out, const DebugMessage &msg) +{ + IOutputHandler *handler = out.Target->GetHandler(); + if (!handler || !out.Target->IsEnabled() || out.Suppressed) + return; + if (!out.Target->TestGroup(msg.GroupID, msg.MT)) + return; + // We suppress current target before the call so that if it makes + // a call to output system itself, message would not print to the + // same target + out.Suppressed = true; + handler->PrintMessage(msg); + out.Suppressed = false; +} + +// TODO: move this to the dynamically allocated engine object whenever it is implemented +DebugManager DbgMgr; + + +namespace Debug +{ + +void Printf(const char *fmt, ...) +{ + va_list argptr; + va_start(argptr, fmt); + DbgMgr.Print(kDbgGroup_Main, kDbgMsg_Default, String::FromFormatV(fmt, argptr)); + va_end(argptr); +} + +void Printf(MessageType mt, const char *fmt, ...) +{ + va_list argptr; + va_start(argptr, fmt); + DbgMgr.Print(kDbgGroup_Main, mt, String::FromFormatV(fmt, argptr)); + va_end(argptr); +} + +void Printf(DebugGroupID group, MessageType mt, const char *fmt, ...) +{ + va_list argptr; + va_start(argptr, fmt); + DbgMgr.Print(group, mt, String::FromFormatV(fmt, argptr)); + va_end(argptr); +} + +} // namespace Debug + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h new file mode 100644 index 000000000000..48c8c9d17f84 --- /dev/null +++ b/engines/ags/shared/debugging/debugmanager.h @@ -0,0 +1,162 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS logging system is built with idea that the engine components should not +// be bothered with specifying particular output method. Instead they use +// generic logging interface, and the actual message printing is done by one +// or more registered handlers. +// Firstly this makes logging functions independent of running platform or +// back-end, secondly it grants end-users ability to configure output according +// to their preference. +// +// To make the logging work we need to register two sets of "entities": +// debug groups and output targets. +// Debug group is an arbitrary object with a name that describes message +// sender. +// Output target defines printing handler and a set of verbosity rules +// one per each known group. +// +// When the message is sent, it is tagged with one of the existing group IDs +// and a message type (debug info, warning, error). This message is sent onto +// each of the registered output targets, which do checks to find out whether +// the message is permitted to be sent further to the printing handler, or not. +// +//============================================================================= +#ifndef __AGS_CN_DEBUG__DEBUGMANAGER_H +#define __AGS_CN_DEBUG__DEBUGMANAGER_H + +#include +#include +#include "debug/out.h" +#include "debug/outputhandler.h" +#include "util/string.h" +#include "util/string_types.h" + +namespace AGS +{ +namespace Common +{ + +// DebugGroup is a message sender definition, identified by DebugGroupID +// and providing OutputName that could be used when printing its messages. +// OutputName may or may not be same as DebugGroupID.SID. +struct DebugGroup +{ + DebugGroupID UID; + String OutputName; + + DebugGroup() {} + DebugGroup(DebugGroupID id, String out_name) : UID(id), OutputName(out_name) {} +}; + +// DebugOutput is a slot for IOutputHandler with its own group filter +class DebugOutput +{ +public: + DebugOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true); + + String GetID() const; + IOutputHandler *GetHandler() const; + + bool IsEnabled() const; + void SetEnabled(bool enable); + // Setup group filter: either allow or disallow a group with the given ID + void SetGroupFilter(DebugGroupID id, MessageType verbosity); + // Assign same verbosity level to all known groups + void SetAllGroupFilters(MessageType verbosity); + // Clear all group filters; this efficiently disables everything + void ClearGroupFilters(); + // Try to resolve group filter unknown IDs + void ResolveGroupID(DebugGroupID id); + // Test if given group id is permitted + bool TestGroup(DebugGroupID id, MessageType mt) const; + +private: + String _id; + IOutputHandler *_handler; + bool _enabled; + MessageType _defaultVerbosity; + // Set of permitted groups' numeric IDs + std::vector _groupFilter; + // Set of unresolved groups, which numeric IDs are not yet known + typedef std::unordered_map GroupNameToMTMap; + GroupNameToMTMap _unresolvedGroups; +}; + +typedef std::shared_ptr PDebugOutput; + + +class DebugManager +{ + friend class DebugOutput; + +public: + DebugManager(); + + // Gets full group ID for any partial one; if the group is not registered returns unset ID + DebugGroup GetGroup(DebugGroupID id); + // Gets output control interface for the given ID + PDebugOutput GetOutput(const String &id); + // Registers debugging group with the given string ID; numeric ID + // will be assigned internally. Returns full ID pair. + // If the group with such string id already exists, returns existing ID. + DebugGroup RegisterGroup(const String &id, const String &out_name); + // Registers output delegate for passing debug messages to; + // if the output with such id already exists, replaces the old one + PDebugOutput RegisterOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true); + // Unregisters all groups and all targets + void UnregisterAll(); + // Unregisters debugging group with the given ID + void UnregisterGroup(DebugGroupID id); + // Unregisters output delegate with the given ID + void UnregisterOutput(const String &id); + + // Output message of given group and message type + void Print(DebugGroupID group_id, MessageType mt, const String &text); + // Send message directly to the output with given id; the message + // must pass the output's message filter though + void SendMessage(const String &out_id, const DebugMessage &msg); + +private: + // OutputSlot struct wraps over output target and adds a flag which indicates + // that this target is temporarily disabled (for internal use only) + struct OutputSlot + { + PDebugOutput Target; + bool Suppressed; + + OutputSlot() : Suppressed(false) {} + }; + + typedef std::vector GroupVector; + typedef std::unordered_map GroupByStringMap; + typedef std::unordered_map OutMap; + + void RegisterGroup(const DebugGroup &id); + void SendMessage(OutputSlot &out, const DebugMessage &msg); + + uint32_t _firstFreeGroupID; + uint32_t _lastGroupID; + GroupVector _groups; + GroupByStringMap _groupByStrLookup; + OutMap _outputs; +}; + +// TODO: move this to the dynamically allocated engine object whenever it is implemented +extern DebugManager DbgMgr; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_DEBUG__DEBUGMANAGER_H diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h new file mode 100644 index 000000000000..383b31a481f2 --- /dev/null +++ b/engines/ags/shared/debugging/out.h @@ -0,0 +1,154 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Debug output interface provides functions which send a formatted message +// tagged with group ID and message type to the registered output handlers. +// +// Depending on configuration this message may be printed by any of those +// handlers, or none of them. The calling unit should not worry about where the +// message goes. +// +//----------------------------------------------------------------------------- +// +// On using message types. +// +// Please keep in mind, that there are different levels of errors. AGS logging +// system allows to classify debug message by two parameters: debug group and +// message type. Sometimes message type alone is not enough. Debug groups can +// also be used to distinct messages that has less (or higher) importance. +// +// For example, there are engine errors and user (game-dev) mistakes. Script +// commands that cannot be executed under given circumstances are user +// mistakes, and usually are not as severe as internal engine errors. This is +// why it is advised to use a separate debug group for mistakes like that to +// distinct them from reports on the internal engine's problems and make +// verbosity configuration flexible. +// +// kDbgMsg_Debug - is the most mundane type of message (if the printing function +// argument list does not specify message type, it is probably kDbgMsg_Debug). +// You can use it for almost anything, from noting some process steps to +// displaying current object state. If certain messages are meant to be printed +// very often, consider using another distinct debug group so that it may be +// disabled to reduce log verbosity. +// +// kDbgMsg_Info - is a type for important notifications, such as initialization +// and stopping of engine components. +// +// kDbgMsg_Warn - this is suggested for more significant cases, when you find +// out that something is not right, but is not immediately affecting engine +// processing. For example: certain object was constructed in a way that +// would make them behave unexpectedly, or certain common files are missing but +// it is not clear yet whether the game will be accessing them. +// In other words: use kDbgMsg_Warn when there is no problem right away, but +// you are *anticipating* that one may happen under certain circumstances. +// +// kDbgMsg_Error - use this kind of message is for actual serious problems. +// If certain operation assumes both positive and negative results are +// acceptable, it is preferred to report such negative result with simple +// kDbgMsg_Debug message. kDbgMsg_Error is for negative results that are not +// considered acceptable for normal run. +// +// kDbgMsg_Fatal - is the message type to be reported when the program or +// component abortion is imminent. +// +//============================================================================= +#ifndef __AGS_CN_DEBUG__OUT_H +#define __AGS_CN_DEBUG__OUT_H + +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +// Message types provide distinction for debug messages by their intent. +enum MessageType +{ + kDbgMsg_None = 0, + // Alerts may be informative messages with topmost level of importance, + // such as reporting engine startup and shutdown. + kDbgMsg_Alert , + // Fatal errors are ones that make program abort immediately. + kDbgMsg_Fatal , + // Error messages are about engine not being able to perform requested + // operation in a situation when that will affect game playability and + // further execution. + kDbgMsg_Error , + // Warnings are made when unexpected or non-standart behavior + // is detected in program, which is not immediately critical, + // but may be a symptom of a bigger problem. + kDbgMsg_Warn , + // General information messages. + kDbgMsg_Info , + // Debug reason is for arbitrary information about events and current + // game state. + kDbgMsg_Debug , + + + // Convenient aliases + kDbgMsg_Default = kDbgMsg_Debug, + kDbgMsg_All = kDbgMsg_Debug +}; + +// This enumeration is a list of common hard-coded groups, but more could +// be added via debugging configuration interface (see 'debug/debug.h'). +enum CommonDebugGroup +{ + kDbgGroup_None = -1, + // Main debug group is for reporting general engine status and issues + kDbgGroup_Main = 0, + // Game group is for logging game logic state and issues + kDbgGroup_Game, + // Log from the game script + kDbgGroup_Script, + // Sprite cache logging + kDbgGroup_SprCache, + // Group for debugging managed object state (can slow engine down!) + kDbgGroup_ManObj +}; + +// Debug group identifier defining either numeric or string id, or both +struct DebugGroupID +{ + uint32_t ID; + String SID; + + DebugGroupID() : ID(kDbgGroup_None) {} + DebugGroupID(uint32_t id, const String &sid = "") : ID(id), SID(sid) {} + DebugGroupID(const String &sid) : ID(kDbgGroup_None), SID(sid) {} + // Tells if any of the id components is valid + bool IsValid() const { return ID != kDbgGroup_None || !SID.IsEmpty(); } + // Tells if both id components are properly set + bool IsComplete() const { return ID != kDbgGroup_None && !SID.IsEmpty(); } +}; + +namespace Debug +{ + // + // Debug output + // + // Output formatted message of default group and default type + void Printf(const char *fmt, ...); + // Output formatted message of default group and given type + void Printf(MessageType mt, const char *fmt, ...); + // Output formatted message of given group and type + void Printf(DebugGroupID group_id, MessageType mt, const char *fmt, ...); + +} // namespace Debug + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_DEBUG__OUT_H diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h new file mode 100644 index 000000000000..d77bcc7e520b --- /dev/null +++ b/engines/ags/shared/debugging/outputhandler.h @@ -0,0 +1,59 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// IOutputHandler is a debug printing interface. Its implementations can be +// registered as potential output for the debug log. +// +//============================================================================= +#ifndef __AGS_CN_DEBUG__OUTPUTHANDLER_H +#define __AGS_CN_DEBUG__OUTPUTHANDLER_H + +#include "debug/out.h" +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +struct DebugMessage +{ + String Text; + uint32_t GroupID; + String GroupName; + MessageType MT; + + DebugMessage() : GroupID(kDbgGroup_None), MT(kDbgMsg_None) {} + DebugMessage(const String &text, uint32_t group_id, const String &group_name, MessageType mt) + : Text(text) + , GroupID(group_id) + , GroupName(group_name) + , MT(mt) + {} +}; + +class IOutputHandler +{ +public: + virtual ~IOutputHandler() = default; + + // Print the given text sent from the debug group. + // Implementations are free to decide which message components are to be printed, and how. + virtual void PrintMessage(const DebugMessage &msg) = 0; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_DEBUG__OUTPUTHANDLER_H diff --git a/engines/ags/shared/font/agsfontrenderer.h b/engines/ags/shared/font/agsfontrenderer.h new file mode 100644 index 000000000000..2f27fcb6786a --- /dev/null +++ b/engines/ags/shared/font/agsfontrenderer.h @@ -0,0 +1,59 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_AGSFONTRENDERER_H +#define __AC_AGSFONTRENDERER_H + +struct BITMAP; + +// WARNING: this interface is exposed for plugins and declared for the second time in agsplugin.h +class IAGSFontRenderer +{ +public: + virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; + virtual void FreeMemory(int fontNumber) = 0; + virtual bool SupportsExtendedCharacters(int fontNumber) = 0; + virtual int GetTextWidth(const char *text, int fontNumber) = 0; + // Get actual height of the given line of text + virtual int GetTextHeight(const char *text, int fontNumber) = 0; + virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; + virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; + virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; +protected: + IAGSFontRenderer() = default; + ~IAGSFontRenderer() = default; +}; + +// Font render params, mainly for dealing with various compatibility issues and +// broken fonts. NOTE: currently left empty as a result of rewrite, but may be +// used again in the future. +struct FontRenderParams +{ + // Font's render multiplier + int SizeMultiplier = 1; +}; + +// NOTE: this extending interface is not yet exposed to plugins +class IAGSFontRenderer2 +{ +public: + virtual bool IsBitmapFont() = 0; + // Load font, applying extended font rendering parameters + virtual bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) = 0; +protected: + IAGSFontRenderer2() = default; + ~IAGSFontRenderer2() = default; +}; + +#endif // __AC_AGSFONTRENDERER_H diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp new file mode 100644 index 000000000000..68167f3f4bfe --- /dev/null +++ b/engines/ags/shared/font/fonts.cpp @@ -0,0 +1,400 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include +#include "ac/common.h" // set_our_eip +#include "ac/gamestructdefines.h" +#include "font/fonts.h" +#include "font/ttffontrenderer.h" +#include "font/wfnfontrenderer.h" +#include "gfx/bitmap.h" +#include "gui/guidefines.h" // MAXLINE +#include "util/string_utils.h" + +#define STD_BUFFER_SIZE 3000 + +using namespace AGS::Common; + +namespace AGS +{ +namespace Common +{ + +struct Font +{ + IAGSFontRenderer *Renderer; + IAGSFontRenderer2 *Renderer2; + FontInfo Info; + + Font(); +}; + +Font::Font() + : Renderer(nullptr) + , Renderer2(nullptr) +{} + +} // Common +} // AGS + +static std::vector fonts; +static TTFFontRenderer ttfRenderer; +static WFNFontRenderer wfnRenderer; + + +FontInfo::FontInfo() + : Flags(0) + , SizePt(0) + , SizeMultiplier(1) + , Outline(FONT_OUTLINE_NONE) + , YOffset(0) + , LineSpacing(0) + , AutoOutlineStyle(kRounded) + , AutoOutlineThickness(1) +{} + + +void init_font_renderer() +{ + alfont_init(); + alfont_text_mode(-1); +} + +void shutdown_font_renderer() +{ + set_our_eip(9919); + alfont_exit(); +} + +void adjust_y_coordinate_for_text(int* ypos, size_t fontnum) +{ + if (fontnum >= fonts.size() || !fonts[fontnum].Renderer) + return; + fonts[fontnum].Renderer->AdjustYCoordinateForFont(ypos, fontnum); +} + +bool font_first_renderer_loaded() +{ + return fonts.size() > 0 && fonts[0].Renderer != nullptr; +} + +bool is_font_loaded(size_t fontNumber) +{ + return fontNumber < fonts.size() && fonts[fontNumber].Renderer != nullptr;; +} + +IAGSFontRenderer* font_replace_renderer(size_t fontNumber, IAGSFontRenderer* renderer) +{ + if (fontNumber >= fonts.size()) + return nullptr; + IAGSFontRenderer* oldRender = fonts[fontNumber].Renderer; + fonts[fontNumber].Renderer = renderer; + fonts[fontNumber].Renderer2 = nullptr; + return oldRender; +} + +bool is_bitmap_font(size_t fontNumber) +{ + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer2) + return false; + return fonts[fontNumber].Renderer2->IsBitmapFont(); +} + +bool font_supports_extended_characters(size_t fontNumber) +{ + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return false; + return fonts[fontNumber].Renderer->SupportsExtendedCharacters(fontNumber); +} + +void ensure_text_valid_for_font(char *text, size_t fontnum) +{ + if (fontnum >= fonts.size() || !fonts[fontnum].Renderer) + return; + fonts[fontnum].Renderer->EnsureTextValidForFont(text, fontnum); +} + +int get_font_scaling_mul(size_t fontNumber) +{ + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + return fonts[fontNumber].Info.SizeMultiplier; +} + +int wgettextwidth(const char *texx, size_t fontNumber) +{ + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + return fonts[fontNumber].Renderer->GetTextWidth(texx, fontNumber); +} + +int wgettextheight(const char *text, size_t fontNumber) +{ + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + return fonts[fontNumber].Renderer->GetTextHeight(text, fontNumber); +} + +int get_font_outline(size_t font_number) +{ + if (font_number >= fonts.size()) + return FONT_OUTLINE_NONE; + return fonts[font_number].Info.Outline; +} + +int get_font_outline_thickness(size_t font_number) +{ + if (font_number >= fonts.size()) + return 0; + return fonts[font_number].Info.AutoOutlineThickness; +} + +void set_font_outline(size_t font_number, int outline_type) +{ + if (font_number >= fonts.size()) + return; + fonts[font_number].Info.Outline = FONT_OUTLINE_AUTO; +} + +int getfontheight(size_t fontNumber) +{ + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + // There is no explicit method for getting maximal possible height of any + // random font renderer at the moment; the implementations of GetTextHeight + // are allowed to return varied results depending on the text parameter. + // We use special line of text to get more or less reliable font height. + const char *height_test_string = "ZHwypgfjqhkilIK"; + return fonts[fontNumber].Renderer->GetTextHeight(height_test_string, fontNumber); +} + +int getfontlinespacing(size_t fontNumber) +{ + if (fontNumber >= fonts.size()) + return 0; + int spacing = fonts[fontNumber].Info.LineSpacing; + // If the spacing parameter is not provided, then return default + // spacing, that is font's height. + return spacing > 0 ? spacing : getfontheight(fontNumber); +} + +bool use_default_linespacing(size_t fontNumber) +{ + if (fontNumber >= fonts.size()) + return false; + return fonts[fontNumber].Info.LineSpacing == 0; +} + +// Project-dependent implementation +extern int wgettextwidth_compensate(const char *tex, int font); + +namespace AGS { namespace Common { SplitLines Lines; } } + +// Replaces AGS-specific linebreak tags with common '\n' +void unescape_script_string(const char *cstr, std::vector &out) +{ + out.clear(); + // Handle the special case of the first char + if (cstr[0] == '[') + { + out.push_back('\n'); + cstr++; + } + // Replace all other occurrences as they're found + const char *off; + for (off = cstr; *off; ++off) + { + if (*off != '[') continue; + if (*(off - 1) == '\\') + { + // convert \[ into [ + out.insert(out.end(), cstr, off - 1); + out.push_back('['); + } + else + { + // convert [ into \n + out.insert(out.end(), cstr, off); + out.push_back('\n'); + } + cstr = off + 1; + } + out.insert(out.end(), cstr, off + 1); +} + +// Break up the text into lines +size_t split_lines(const char *todis, SplitLines &lines, int wii, int fonnt, size_t max_lines) { + // NOTE: following hack accomodates for the legacy math mistake in split_lines. + // It's hard to tell how cruicial it is for the game looks, so research may be needed. + // TODO: IMHO this should rely not on game format, but script API level, because it + // defines necessary adjustments to game scripts. If you want to fix this, find a way to + // pass this flag here all the way from game.options[OPT_BASESCRIPTAPI] (or game format). + // + // if (game.options[OPT_BASESCRIPTAPI] < $Your current version$) + wii -= 1; + + lines.Reset(); + unescape_script_string(todis, lines.LineBuf); + char *theline = &lines.LineBuf.front(); + + size_t i = 0; + size_t splitAt; + char nextCharWas; + while (1) { + splitAt = -1; + + if (theline[i] == 0) { + // end of the text, add the last line if necessary + if (i > 0) { + lines.Add(theline); + } + break; + } + + // temporarily terminate the line here and test its width + nextCharWas = theline[i + 1]; + theline[i + 1] = 0; + + // force end of line with the \n character + if (theline[i] == '\n') + splitAt = i; + // otherwise, see if we are too wide + else if (wgettextwidth_compensate(theline, fonnt) > wii) { + int endline = i; + while ((theline[endline] != ' ') && (endline > 0)) + endline--; + + // single very wide word, display as much as possible + if (endline == 0) + endline = i - 1; + + splitAt = endline; + } + + // restore the character that was there before + theline[i + 1] = nextCharWas; + + if (splitAt != -1) { + if (splitAt == 0 && !((theline[0] == ' ') || (theline[0] == '\n'))) { + // cannot split with current width restriction + lines.Reset(); + break; + } + // add this line + nextCharWas = theline[splitAt]; + theline[splitAt] = 0; + lines.Add(theline); + theline[splitAt] = nextCharWas; + if (lines.Count() >= max_lines) { + lines[lines.Count() - 1].Append("..."); + break; + } + // the next line starts from here + theline += splitAt; + // skip the space or new line that caused the line break + if ((theline[0] == ' ') || (theline[0] == '\n')) + theline++; + i = -1; + } + + i++; + } + return lines.Count(); +} + +void wouttextxy(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx) +{ + if (fontNumber >= fonts.size()) + return; + yyy += fonts[fontNumber].Info.YOffset; + if (yyy > ds->GetClip().Bottom) + return; // each char is clipped but this speeds it up + + if (fonts[fontNumber].Renderer != nullptr) + { + fonts[fontNumber].Renderer->RenderText(texx, fontNumber, (BITMAP*)ds->GetAllegroBitmap(), xxx, yyy, text_color); + } +} + +void set_fontinfo(size_t fontNumber, const FontInfo &finfo) +{ + if (fontNumber < fonts.size() && fonts[fontNumber].Renderer) + fonts[fontNumber].Info = finfo; +} + +// Loads a font from disk +bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) +{ + if (fonts.size() <= fontNumber) + fonts.resize(fontNumber + 1); + else + wfreefont(fontNumber); + FontRenderParams params; + params.SizeMultiplier = font_info.SizeMultiplier; + + if (ttfRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) + { + fonts[fontNumber].Renderer = &ttfRenderer; + fonts[fontNumber].Renderer2 = &ttfRenderer; + } + else if (wfnRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) + { + fonts[fontNumber].Renderer = &wfnRenderer; + fonts[fontNumber].Renderer2 = &wfnRenderer; + } + + if (fonts[fontNumber].Renderer) + { + fonts[fontNumber].Info = font_info; + return true; + } + return false; +} + +void wgtprintf(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...) +{ + if (fontNumber >= fonts.size()) + return; + + char tbuffer[2000]; + va_list ap; + + va_start(ap, fmt); + vsprintf(tbuffer, fmt, ap); + va_end(ap); + wouttextxy(ds, xxx, yyy, fontNumber, text_color, tbuffer); +} + +void wfreefont(size_t fontNumber) +{ + if (fontNumber >= fonts.size()) + return; + + if (fonts[fontNumber].Renderer != nullptr) + fonts[fontNumber].Renderer->FreeMemory(fontNumber); + + fonts[fontNumber].Renderer = nullptr; +} + +void free_all_fonts() +{ + for (size_t i = 0; i < fonts.size(); ++i) + { + if (fonts[i].Renderer != nullptr) + fonts[i].Renderer->FreeMemory(i); + } + fonts.clear(); +} diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h new file mode 100644 index 000000000000..f9004c980b44 --- /dev/null +++ b/engines/ags/shared/font/fonts.h @@ -0,0 +1,112 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_FONT_H +#define __AC_FONT_H + +#include +#include "core/types.h" +#include "util/string.h" + +// TODO: we need to make some kind of TextManager class of this module + +namespace AGS { namespace Common { class Bitmap; } } +using namespace AGS; + +class IAGSFontRenderer; +class IAGSFontRenderer2; +struct FontInfo; +struct FontRenderParams; + +void init_font_renderer(); +void shutdown_font_renderer(); +void adjust_y_coordinate_for_text(int* ypos, size_t fontnum); +IAGSFontRenderer* font_replace_renderer(size_t fontNumber, IAGSFontRenderer* renderer); +bool font_first_renderer_loaded(); +bool is_font_loaded(size_t fontNumber); +bool is_bitmap_font(size_t fontNumber); +bool font_supports_extended_characters(size_t fontNumber); +// TODO: with changes to WFN font renderer that implemented safe rendering of +// strings containing invalid chars (since 3.3.1) this function is not +// important, except for (maybe) few particular cases. +// Furthermore, its use complicated things, because AGS could modify some texts +// at random times (usually - drawing routines). +// Need to check whether it is safe to completely remove it. +void ensure_text_valid_for_font(char *text, size_t fontnum); +// Get font's scaling multiplier +int get_font_scaling_mul(size_t fontNumber); +// Calculate actual width of a line of text +int wgettextwidth(const char *texx, size_t fontNumber); +// Calculates actual height of a line of text +int wgettextheight(const char *text, size_t fontNumber); +// Get font's height (maximal height of any line of text printed with this font) +int getfontheight(size_t fontNumber); +// Get font's line spacing +int getfontlinespacing(size_t fontNumber); +// Get is font is meant to use default line spacing +bool use_default_linespacing(size_t fontNumber); +// Get font's outline type +int get_font_outline(size_t font_number); +// Get font's automatic outline thickness (if set) +int get_font_outline_thickness(size_t font_number); +// Set font's outline type +void set_font_outline(size_t font_number, int outline_type); +// Outputs a single line of text on the defined position on bitmap, using defined font, color and parameters +int getfontlinespacing(size_t fontNumber); +// Print text on a surface using a given font +void wouttextxy(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx); +// Assigns FontInfo to the font +void set_fontinfo(size_t fontNumber, const FontInfo &finfo); +// Loads a font from disk +bool wloadfont_size(size_t fontNumber, const FontInfo &font_info); +void wgtprintf(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...); +// Free particular font's data +void wfreefont(size_t fontNumber); +// Free all fonts data +void free_all_fonts(); + +// SplitLines class represents a list of lines and is meant to reduce +// subsequent memory (de)allocations if used often during game loops +// and drawing. For that reason it is not equivalent to std::vector, +// but keeps constructed String buffers intact for most time. +// TODO: implement proper strings pool. +class SplitLines +{ +public: + inline size_t Count() const { return _count; } + inline const Common::String &operator[](size_t i) const { return _pool[i]; } + inline Common::String &operator[](size_t i) { return _pool[i]; } + inline void Clear() { _pool.clear(); _count = 0; } + inline void Reset() { _count = 0; } + inline void Add(const char *cstr) + { + if (_pool.size() == _count) _pool.resize(_count + 1); + _pool[_count++].SetString(cstr); + } + + // An auxiliary line processing buffer + std::vector LineBuf; + +private: + std::vector _pool; + size_t _count; // actual number of lines in use +}; + +// Break up the text into lines restricted by the given width; +// returns number of lines, or 0 if text cannot be split well to fit in this width +size_t split_lines(const char *texx, SplitLines &lines, int width, int fontNumber, size_t max_lines = -1); + +namespace AGS { namespace Common { extern SplitLines Lines; } } + +#endif // __AC_FONT_H diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp new file mode 100644 index 000000000000..61a7ded323be --- /dev/null +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -0,0 +1,142 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "core/platform.h" + +#define AGS_OUTLINE_FONT_FIX (!AGS_PLATFORM_OS_WINDOWS) + +#include "core/assetmanager.h" +#include "font/ttffontrenderer.h" +#include "util/stream.h" + +#if AGS_OUTLINE_FONT_FIX // TODO: factor out the hack in LoadFromDiskEx +#include "ac/gamestructdefines.h" +#include "font/fonts.h" +#endif + +using namespace AGS::Common; + +// project-specific implementation +extern bool ShouldAntiAliasText(); + +ALFONT_FONT *tempttffnt; +ALFONT_FONT *get_ttf_block(unsigned char* fontptr) +{ + memcpy(&tempttffnt, &fontptr[4], sizeof(tempttffnt)); + return tempttffnt; +} + + +// ***** TTF RENDERER ***** +void TTFFontRenderer::AdjustYCoordinateForFont(int *ycoord, int fontNumber) +{ + // TTF fonts already have space at the top, so try to remove the gap + // TODO: adding -1 was here before (check the comment above), + // but how universal is this "space at the top"? + // Also, why is this function used only in one case of text rendering? + // Review this after we upgrade the font library. + ycoord[0]--; +} + +void TTFFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) +{ + // do nothing, TTF can handle all characters +} + +int TTFFontRenderer::GetTextWidth(const char *text, int fontNumber) +{ + return alfont_text_length(_fontData[fontNumber].AlFont, text); +} + +int TTFFontRenderer::GetTextHeight(const char *text, int fontNumber) +{ + return alfont_text_height(_fontData[fontNumber].AlFont); +} + +void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) +{ + if (y > destination->cb) // optimisation + return; + + // Y - 1 because it seems to get drawn down a bit + if ((ShouldAntiAliasText()) && (bitmap_color_depth(destination) > 8)) + alfont_textout_aa(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour); + else + alfont_textout(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour); +} + +bool TTFFontRenderer::LoadFromDisk(int fontNumber, int fontSize) +{ + return LoadFromDiskEx(fontNumber, fontSize, nullptr); +} + +bool TTFFontRenderer::IsBitmapFont() +{ + return false; +} + +bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) +{ + String file_name = String::FromFormat("agsfnt%d.ttf", fontNumber); + Stream *reader = AssetManager::OpenAsset(file_name); + char *membuffer; + + if (reader == nullptr) + return false; + + long lenof = AssetManager::GetLastAssetSize(); + + membuffer = (char *)malloc(lenof); + reader->ReadArray(membuffer, lenof, 1); + delete reader; + + ALFONT_FONT *alfptr = alfont_load_font_from_mem(membuffer, lenof); + free(membuffer); + + if (alfptr == nullptr) + return false; + + // TODO: move this somewhere, should not be right here +#if AGS_OUTLINE_FONT_FIX + // FIXME: (!!!) this fix should be done differently: + // 1. Find out which OUTLINE font was causing troubles; + // 2. Replace outline method ONLY if that troublesome font is used as outline. + // 3. Move this fix somewhere else!! (right after game load routine?) + // + // Check for the LucasFan font since it comes with an outline font that + // is drawn incorrectly with Freetype versions > 2.1.3. + // A simple workaround is to disable outline fonts for it and use + // automatic outline drawing. + if (get_font_outline(fontNumber) >=0 && + strcmp(alfont_get_name(alfptr), "LucasFan-Font") == 0) + set_font_outline(fontNumber, FONT_OUTLINE_AUTO); +#endif + if (fontSize == 0) + fontSize = 8; // compatibility fix + if (params && params->SizeMultiplier > 1) + fontSize *= params->SizeMultiplier; + if (fontSize > 0) + alfont_set_font_size(alfptr, fontSize); + + _fontData[fontNumber].AlFont = alfptr; + _fontData[fontNumber].Params = params ? *params : FontRenderParams(); + return true; +} + +void TTFFontRenderer::FreeMemory(int fontNumber) +{ + alfont_destroy_font(_fontData[fontNumber].AlFont); + _fontData.erase(fontNumber); +} diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h new file mode 100644 index 000000000000..156c46d9bad9 --- /dev/null +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_TTFFONTRENDERER_H +#define __AC_TTFFONTRENDERER_H + +#include +#include "font/agsfontrenderer.h" + +struct ALFONT_FONT; + +class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { +public: + // IAGSFontRenderer implementation + bool LoadFromDisk(int fontNumber, int fontSize) override; + void FreeMemory(int fontNumber) override; + bool SupportsExtendedCharacters(int fontNumber) override { return true; } + int GetTextWidth(const char *text, int fontNumber) override; + int GetTextHeight(const char *text, int fontNumber) override; + void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override ; + void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override; + void EnsureTextValidForFont(char *text, int fontNumber) override; + + // IAGSFontRenderer2 implementation + bool IsBitmapFont() override; + bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override; + +private: + struct FontData + { + ALFONT_FONT *AlFont; + FontRenderParams Params; + }; + std::map _fontData; +}; + +#endif // __AC_TTFFONTRENDERER_H diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp new file mode 100644 index 000000000000..8f429f29ad86 --- /dev/null +++ b/engines/ags/shared/font/wfnfont.cpp @@ -0,0 +1,193 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "font/wfnfont.h" +#include "debug/out.h" +#include "util/memory.h" +#include "util/stream.h" + +using namespace AGS::Common; + +static const char *WFN_FILE_SIGNATURE = "WGT Font File "; +static const size_t WFN_FILE_SIG_LENGTH = 15; +static const size_t MinCharDataSize = sizeof(uint16_t) * 2; + +WFNChar::WFNChar() + : Width(0) + , Height(0) + , Data(nullptr) +{ +} + +void WFNChar::RestrictToBytes(size_t bytes) +{ + if (bytes < GetRequiredPixelSize()) + Height = static_cast(bytes / GetRowByteCount()); +} + +const WFNChar WFNFont::_emptyChar; + +void WFNFont::Clear() +{ + _refs.clear(); + _items.clear(); + _pixelData.clear(); +} + +WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) +{ + Clear(); + + const soff_t used_data_size = data_size > 0 ? data_size : in->GetLength(); + + // Read font header + char sig[WFN_FILE_SIG_LENGTH]; + in->Read(sig, WFN_FILE_SIG_LENGTH); + if (strncmp(sig, WFN_FILE_SIGNATURE, WFN_FILE_SIG_LENGTH) != 0) + { + Debug::Printf(kDbgMsg_Error, "\tWFN: bad format signature"); + return kWFNErr_BadSignature; // bad format + } + + const soff_t table_addr = static_cast(in->ReadInt16()); // offset table relative address + if (table_addr < WFN_FILE_SIG_LENGTH + sizeof(uint16_t) || table_addr >= used_data_size) + { + Debug::Printf(kDbgMsg_Error, "\tWFN: bad table address: %lld (%d - %d)", table_addr, WFN_FILE_SIG_LENGTH + sizeof(uint16_t), used_data_size); + return kWFNErr_BadTableAddress; // bad table address + } + + const soff_t offset_table_size = used_data_size - table_addr; + const soff_t raw_data_offset = WFN_FILE_SIG_LENGTH + sizeof(uint16_t); + const size_t total_char_data = static_cast(table_addr - raw_data_offset); + const size_t char_count = static_cast(offset_table_size / sizeof(uint16_t)); + + // We process character data in three steps: + // 1. For every character store offset of character item, excluding + // duplicates. + // 2. Allocate memory for character items and pixel array and copy + // appropriate data; test for possible format corruption. + // 3. Create array of references from characters to items; same item may be + // referenced by many characters. + WFNError err = kWFNErr_NoError; + + // Read character data array + uint8_t *raw_data = new uint8_t[total_char_data]; + in->Read(raw_data, total_char_data); + + // Read offset table + uint16_t *offset_table = new uint16_t[char_count]; + in->ReadArrayOfInt16((int16_t*)offset_table, char_count); + + // Read all referenced offsets in an unsorted vector + std::vector offs; + offs.reserve(char_count); // reserve max possible offsets + for (size_t i = 0; i < char_count; ++i) + { + const uint16_t off = offset_table[i]; + if (off < raw_data_offset || off + MinCharDataSize > table_addr) + { + Debug::Printf("\tWFN: character %d -- bad item offset: %d (%d - %d, +%d)", + i, off, raw_data_offset, table_addr, MinCharDataSize); + err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format + continue; // bad character offset + } + offs.push_back(off); + } + // sort offsets vector and remove any duplicates + std::sort(offs.begin(), offs.end()); + std::vector(offs.begin(), std::unique(offs.begin(), offs.end())).swap(offs); + + // Now that we know number of valid character items, parse and store character data + WFNChar init_ch; + _items.resize(offs.size()); + size_t total_pixel_size = 0; + for (size_t i = 0; i < _items.size(); ++i) + { + const uint8_t *p_data = raw_data + offs[i] - raw_data_offset; + init_ch.Width = Memory::ReadInt16LE(p_data); + init_ch.Height = Memory::ReadInt16LE(p_data + sizeof(uint16_t)); + total_pixel_size += init_ch.GetRequiredPixelSize(); + _items[i] = init_ch; + } + + // Now that we know actual size of pixels in use, create pixel data array; + // since the items are sorted, the pixel data will be stored sequentially as well. + // At this point offs and _items have related elements in the same order. + _pixelData.resize(total_pixel_size); + std::vector::iterator pixel_it = _pixelData.begin(); // write ptr + for (size_t i = 0; i < _items.size(); ++i) + { + const size_t pixel_data_size = _items[i].GetRequiredPixelSize(); + if (pixel_data_size == 0) + { + Debug::Printf("\tWFN: item at off %d -- null size", offs[i]); + err = kWFNErr_HasBadCharacters; + continue; // just an empty character + } + const uint16_t raw_off = offs[i] - raw_data_offset + MinCharDataSize; // offset in raw array + size_t src_size = pixel_data_size; + if (i + 1 != _items.size() && raw_off + src_size > offs[i + 1] - raw_data_offset) + { // character pixel data overlaps next character + Debug::Printf("\tWFN: item at off %d -- pixel data overlaps next known item (at %d, +%d)", + offs[i], offs[i + 1], MinCharDataSize + src_size); + err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format + src_size = offs[i + 1] - offs[i] - MinCharDataSize; + } + + if (raw_off + src_size > total_char_data) + { // character pixel data overflow buffer + Debug::Printf("\tWFN: item at off %d -- pixel data exceeds available data (at %d, +%d)", + offs[i], table_addr, MinCharDataSize + src_size); + err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format + src_size = total_char_data - raw_off; + } + _items[i].RestrictToBytes(src_size); + + assert(pixel_it + pixel_data_size <= _pixelData.end()); // should not normally fail + std::copy(raw_data + raw_off, raw_data + raw_off + src_size, pixel_it); + _items[i].Data = &(*pixel_it); + pixel_it += pixel_data_size; + } + + // Create final reference array + _refs.resize(char_count); + for (size_t i = 0; i < char_count; ++i) + { + const uint16_t off = offset_table[i]; + // if bad character offset - reference empty character + if (off < raw_data_offset || off + MinCharDataSize > table_addr) + { + _refs[i] = &_emptyChar; + } + else + { + // in usual case the offset table references items in strict order + if (i < _items.size() && offs[i] == off) + _refs[i] = &_items[i]; + else + { + // we know beforehand that such item must exist + std::vector::const_iterator at = std::lower_bound(offs.begin(), offs.end(), off); + assert(at != offs.end() && *at == off && // should not normally fail + at - offs.begin() >= 0 && static_cast(at - offs.begin()) < _items.size()); + _refs[i] = &_items[at - offs.begin()]; // set up reference to item + } + } + } + + delete [] raw_data; + delete [] offset_table; + return err; +} diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h new file mode 100644 index 000000000000..7b7099957ffc --- /dev/null +++ b/engines/ags/shared/font/wfnfont.h @@ -0,0 +1,102 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// WFNFont - an immutable AGS font object. +// +//----------------------------------------------------------------------------- +// +// WFN format: +// - signature ( 15 ) +// - offsets table offset ( 2 ) +// - characters table (for unknown number of char items): +// - width ( 2 ) +// - height ( 2 ) +// - pixel bits ( (width / 8 + 1) * height ) +// - any unknown data +// - offsets table (for X chars): +// - character offset ( 2 ) +// +// NOTE: unfortunately, at the moment the format does not provide means to +// know the number of supported characters for certain, and the size of the +// data (file) is used to determine that. +// +//============================================================================= + +#ifndef __AGS_CN_FONT__WFNFONT_H +#define __AGS_CN_FONT__WFNFONT_H + +#include +#include "core/types.h" + +namespace AGS { namespace Common { class Stream; } } + +enum WFNError +{ + kWFNErr_NoError, + kWFNErr_BadSignature, + kWFNErr_BadTableAddress, + kWFNErr_HasBadCharacters +}; + +struct WFNChar +{ + uint16_t Width; + uint16_t Height; + const uint8_t *Data; + + WFNChar(); + + inline size_t GetRowByteCount() const + { + return (Width + 7) / 8; + } + + inline size_t GetRequiredPixelSize() const + { + return GetRowByteCount() * Height; + } + + // Ensure character's width & height fit in given number of pixel bytes + void RestrictToBytes(size_t bytes); +}; + + +class WFNFont +{ +public: + inline uint16_t GetCharCount() const + { + return static_cast(_refs.size()); + } + + // Get WFN character for the given code; if the character is missing, returns empty character + inline const WFNChar &GetChar(uint8_t code) const + { + return code < _refs.size() ? *_refs[code] : _emptyChar; + } + + void Clear(); + // Reads WFNFont object, using data_size bytes from stream; if data_size = 0, + // the available stream's length is used instead. Returns error code. + WFNError ReadFromFile(AGS::Common::Stream *in, const soff_t data_size = 0); + +protected: + std::vector _refs; // reference array, contains pointers to elements of _items + std::vector _items; // actual character items + std::vector _pixelData; // pixel data array + + static const WFNChar _emptyChar; // a dummy character to substitute bad symbols +}; + +#endif // __AGS_CN_FONT__WFNFONT_H diff --git a/engines/ags/shared/font/wfnfontrenderer.cpp b/engines/ags/shared/font/wfnfontrenderer.cpp new file mode 100644 index 000000000000..165539f17ea9 --- /dev/null +++ b/engines/ags/shared/font/wfnfontrenderer.cpp @@ -0,0 +1,179 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" // our_eip +#include "core/assetmanager.h" +#include "debug/out.h" +#include "font/wfnfont.h" +#include "font/wfnfontrenderer.h" +#include "gfx/bitmap.h" +#include "util/stream.h" + +using namespace AGS::Common; + +static unsigned char GetCharCode(unsigned char wanted_code, const WFNFont* font) +{ + return wanted_code < font->GetCharCount() ? wanted_code : '?'; +} + +static int RenderChar(Bitmap *ds, const int at_x, const int at_y, const WFNChar &wfn_char, const int scale, const color_t text_color); + +void WFNFontRenderer::AdjustYCoordinateForFont(int *ycoord, int fontNumber) +{ + // Do nothing +} + +void WFNFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) +{ + const WFNFont* font = _fontData[fontNumber].Font; + // replace any extended characters with question marks + for (; *text; ++text) + { + if ((unsigned char)*text >= font->GetCharCount()) + { + *text = '?'; + } + } +} + +int WFNFontRenderer::GetTextWidth(const char *text, int fontNumber) +{ + const WFNFont* font = _fontData[fontNumber].Font; + const FontRenderParams ¶ms = _fontData[fontNumber].Params; + int text_width = 0; + + for (; *text; ++text) + { + const WFNChar &wfn_char = font->GetChar(GetCharCode(*text, font)); + text_width += wfn_char.Width; + } + return text_width * params.SizeMultiplier; +} + +int WFNFontRenderer::GetTextHeight(const char *text, int fontNumber) +{ + const WFNFont* font = _fontData[fontNumber].Font; + const FontRenderParams ¶ms = _fontData[fontNumber].Params; + int max_height = 0; + + for (; *text; ++text) + { + const WFNChar &wfn_char = font->GetChar(GetCharCode(*text, font)); + const uint16_t height = wfn_char.Height; + if (height > max_height) + max_height = height; + } + return max_height * params.SizeMultiplier; +} + +Bitmap render_wrapper; +void WFNFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) +{ + int oldeip = get_our_eip(); + set_our_eip(415); + + const WFNFont* font = _fontData[fontNumber].Font; + const FontRenderParams ¶ms = _fontData[fontNumber].Params; + render_wrapper.WrapAllegroBitmap(destination, true); + + for (; *text; ++text) + x += RenderChar(&render_wrapper, x, y, font->GetChar(GetCharCode(*text, font)), params.SizeMultiplier, colour); + + set_our_eip(oldeip); +} + +int RenderChar(Bitmap *ds, const int at_x, const int at_y, const WFNChar &wfn_char, const int scale, const color_t text_color) +{ + const int width = wfn_char.Width; + const int height = wfn_char.Height; + const unsigned char *actdata = wfn_char.Data; + const int bytewid = wfn_char.GetRowByteCount(); + + int x = at_x; + int y = at_y; + for (int h = 0; h < height; ++h) + { + for (int w = 0; w < width; ++w) + { + if (((actdata[h * bytewid + (w / 8)] & (0x80 >> (w % 8))) != 0)) { + if (scale > 1) + { + ds->FillRect(Rect(x + w, y + h, x + w + (scale - 1), + y + h + (scale - 1)), text_color); + } + else + { + ds->PutPixel(x + w, y + h, text_color); + } + } + + x += scale - 1; + } + y += scale - 1; + x = at_x; + } + return width * scale; +} + +bool WFNFontRenderer::LoadFromDisk(int fontNumber, int fontSize) +{ + return LoadFromDiskEx(fontNumber, fontSize, nullptr); +} + +bool WFNFontRenderer::IsBitmapFont() +{ + return true; +} + +bool WFNFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) +{ + String file_name; + Stream *ffi = nullptr; + + file_name.Format("agsfnt%d.wfn", fontNumber); + ffi = AssetManager::OpenAsset(file_name); + if (ffi == nullptr) + { + // actual font not found, try font 0 instead + file_name = "agsfnt0.wfn"; + ffi = AssetManager::OpenAsset(file_name); + if (ffi == nullptr) + return false; + } + + WFNFont *font = new WFNFont(); + WFNError err = font->ReadFromFile(ffi, AssetManager::GetLastAssetSize()); + delete ffi; + if (err == kWFNErr_HasBadCharacters) + Debug::Printf(kDbgMsg_Warn, "WARNING: font '%s' has mistakes in data format, some characters may be displayed incorrectly", file_name.GetCStr()); + else if (err != kWFNErr_NoError) + { + delete font; + return false; + } + _fontData[fontNumber].Font = font; + _fontData[fontNumber].Params = params ? *params : FontRenderParams(); + return true; +} + +void WFNFontRenderer::FreeMemory(int fontNumber) +{ + delete _fontData[fontNumber].Font; + _fontData.erase(fontNumber); +} + +bool WFNFontRenderer::SupportsExtendedCharacters(int fontNumber) +{ + return _fontData[fontNumber].Font->GetCharCount() > 128; +} diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h new file mode 100644 index 000000000000..740c15d8958c --- /dev/null +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -0,0 +1,46 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_WFNFONTRENDERER_H +#define __AC_WFNFONTRENDERER_H + +#include +#include "font/agsfontrenderer.h" + +class WFNFont; + +class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { +public: + bool LoadFromDisk(int fontNumber, int fontSize) override; + void FreeMemory(int fontNumber) override; + bool SupportsExtendedCharacters(int fontNumber) override; + int GetTextWidth(const char *text, int fontNumber) override; + int GetTextHeight(const char *text, int fontNumber) override; + void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override; + void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override; + void EnsureTextValidForFont(char *text, int fontNumber) override; + + bool IsBitmapFont() override; + bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override; + +private: + struct FontData + { + WFNFont *Font; + FontRenderParams Params; + }; + std::map _fontData; +}; + +#endif // __AC_WFNFONTRENDERER_H diff --git a/engines/ags/shared/game/customproperties.cpp b/engines/ags/shared/game/customproperties.cpp new file mode 100644 index 000000000000..fd39cc36df09 --- /dev/null +++ b/engines/ags/shared/game/customproperties.cpp @@ -0,0 +1,136 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "game/customproperties.h" +#include "util/stream.h" +#include "util/string_utils.h" + +namespace AGS +{ +namespace Common +{ + +PropertyDesc::PropertyDesc() +{ + Type = kPropertyBoolean; +} + +PropertyDesc::PropertyDesc(const String &name, PropertyType type, const String &desc, const String &def_value) +{ + Name = name; + Type = type; + Description = desc; + DefaultValue = def_value; +} + + +namespace Properties +{ + +PropertyError ReadSchema(PropertySchema &schema, Stream *in) +{ + PropertyVersion version = (PropertyVersion)in->ReadInt32(); + if (version < kPropertyVersion_Initial || + version > kPropertyVersion_Current) + { + return kPropertyErr_UnsupportedFormat; + } + + PropertyDesc prop; + int count = in->ReadInt32(); + if (version == kPropertyVersion_Initial) + { + for (int i = 0; i < count; ++i) + { + prop.Name.Read(in, LEGACY_MAX_CUSTOM_PROP_SCHEMA_NAME_LENGTH); + prop.Description.Read(in, LEGACY_MAX_CUSTOM_PROP_DESC_LENGTH); + prop.DefaultValue.Read(in, LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH); + prop.Type = (PropertyType)in->ReadInt32(); + schema[prop.Name] = prop; + } + } + else + { + for (int i = 0; i < count; ++i) + { + prop.Name = StrUtil::ReadString(in); + prop.Type = (PropertyType)in->ReadInt32(); + prop.Description = StrUtil::ReadString(in); + prop.DefaultValue = StrUtil::ReadString(in); + schema[prop.Name] = prop; + } + } + return kPropertyErr_NoError; +} + +void WriteSchema(const PropertySchema &schema, Stream *out) +{ + out->WriteInt32(kPropertyVersion_Current); + out->WriteInt32(schema.size()); + for (PropertySchema::const_iterator it = schema.begin(); + it != schema.end(); ++it) + { + const PropertyDesc &prop = it->second; + StrUtil::WriteString(prop.Name, out); + out->WriteInt32(prop.Type); + StrUtil::WriteString(prop.Description, out); + StrUtil::WriteString(prop.DefaultValue, out); + } +} + +PropertyError ReadValues(StringIMap &map, Stream *in) +{ + PropertyVersion version = (PropertyVersion)in->ReadInt32(); + if (version < kPropertyVersion_Initial || + version > kPropertyVersion_Current) + { + return kPropertyErr_UnsupportedFormat; + } + + int count = in->ReadInt32(); + if (version == kPropertyVersion_Initial) + { + for (int i = 0; i < count; ++i) + { + String name = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_NAME_LENGTH); + map[name] = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH); + } + } + else + { + for (int i = 0; i < count; ++i) + { + String name = StrUtil::ReadString(in); + map[name] = StrUtil::ReadString(in); + } + } + return kPropertyErr_NoError; +} + +void WriteValues(const StringIMap &map, Stream *out) +{ + out->WriteInt32(kPropertyVersion_Current); + out->WriteInt32(map.size()); + for (StringIMap::const_iterator it = map.begin(); + it != map.end(); ++it) + { + StrUtil::WriteString(it->first, out); + StrUtil::WriteString(it->second, out); + } +} + +} // namespace Properties + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h new file mode 100644 index 000000000000..afd819cd8550 --- /dev/null +++ b/engines/ags/shared/game/customproperties.h @@ -0,0 +1,102 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Custom property structs +// +//----------------------------------------------------------------------------- +// +// Custom property schema is kept by GameSetupStruct object as a single +// instance and defines property type and default value. Every game entity that +// has properties implemented keeps CustomProperties object, which stores +// actual property values only if ones are different from defaults. +// +//============================================================================= +#ifndef __AGS_CN_GAME__CUSTOMPROPERTIES_H +#define __AGS_CN_GAME__CUSTOMPROPERTIES_H + +#include +#include "util/string.h" +#include "util/string_types.h" + +#define LEGACY_MAX_CUSTOM_PROPERTIES 30 +// NOTE: for some reason the property name stored in schema object was limited +// to only 20 characters, while the custom properties map could hold up to 200. +// Whether this was an error or design choice is unknown. +#define LEGACY_MAX_CUSTOM_PROP_SCHEMA_NAME_LENGTH 20 +#define LEGACY_MAX_CUSTOM_PROP_NAME_LENGTH 200 +#define LEGACY_MAX_CUSTOM_PROP_DESC_LENGTH 100 +#define LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH 500 + +namespace AGS +{ +namespace Common +{ + +enum PropertyVersion +{ + kPropertyVersion_Initial = 1, + kPropertyVersion_340, + kPropertyVersion_Current = kPropertyVersion_340 +}; + +enum PropertyType +{ + kPropertyUndefined = 0, + kPropertyBoolean, + kPropertyInteger, + kPropertyString +}; + +enum PropertyError +{ + kPropertyErr_NoError, + kPropertyErr_UnsupportedFormat +}; + +// +// PropertyDesc - a description of a single custom property +// +struct PropertyDesc +{ + String Name; + PropertyType Type; + String Description; + String DefaultValue; + + PropertyDesc(); + PropertyDesc(const String &name, PropertyType type, const String &desc, const String &def_value); +}; + +// NOTE: AGS has case-insensitive property IDs +// Schema - a map of property descriptions +typedef std::unordered_map PropertySchema; + + +namespace Properties +{ + PropertyError ReadSchema(PropertySchema &schema, Stream *in); + void WriteSchema(const PropertySchema &schema, Stream *out); + + // Reads property values from the stream and assign them to map. + // The non-matching existing map items, if any, are NOT erased. + PropertyError ReadValues(StringIMap &map, Stream *in); + // Writes property values chunk to the stream + void WriteValues(const StringIMap &map, Stream *out); + +} // namespace Properties + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GAME__CUSTOMPROPERTIES_H diff --git a/engines/ags/shared/game/interactions.cpp b/engines/ags/shared/game/interactions.cpp new file mode 100644 index 000000000000..0786c805b0cd --- /dev/null +++ b/engines/ags/shared/game/interactions.cpp @@ -0,0 +1,429 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/common.h" // quit +#include "game/interactions.h" +#include "util/alignedstream.h" +#include "util/math.h" + +using namespace AGS::Common; + +InteractionVariable globalvars[MAX_GLOBAL_VARIABLES] = {InteractionVariable("Global 1", 0, 0)}; +int numGlobalVars = 1; + +namespace AGS +{ +namespace Common +{ + +InteractionValue::InteractionValue() +{ + Type = kInterValLiteralInt; + Value = 0; + Extra = 0; +} + +void InteractionValue::Read(Stream *in) +{ + Type = (InterValType)in->ReadInt8(); + Value = in->ReadInt32(); + Extra = in->ReadInt32(); +} + +void InteractionValue::Write(Stream *out) const +{ + out->WriteInt8(Type); + out->WriteInt32(Value); + out->WriteInt32(Extra); +} + +//----------------------------------------------------------------------------- + +InteractionCommand::InteractionCommand() + : Type(0) + , Parent(nullptr) +{ +} + +InteractionCommand::InteractionCommand(const InteractionCommand &ic) +{ + *this = ic; +} + +void InteractionCommand::Assign(const InteractionCommand &ic, InteractionCommandList *parent) +{ + Type = ic.Type; + memcpy(Data, ic.Data, sizeof(Data)); + Children.reset(ic.Children.get() ? new InteractionCommandList(*ic.Children) : nullptr); + Parent = parent; +} + +void InteractionCommand::Reset() +{ + Type = 0; + memset(Data, 0, sizeof(Data)); + Children.reset(); + Parent = nullptr; +} + +void InteractionCommand::ReadValues_Aligned(Stream *in) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < MAX_ACTION_ARGS; ++i) + { + Data[i].Read(&align_s); + align_s.Reset(); + } +} + +void InteractionCommand::Read_v321(Stream *in, bool &has_children) +{ + in->ReadInt32(); // skip the 32-bit vtbl ptr (the old serialization peculiarity) + Type = in->ReadInt32(); + ReadValues_Aligned(in); + has_children = in->ReadInt32() != 0; + in->ReadInt32(); // skip 32-bit Parent pointer +} + +void InteractionCommand::WriteValues_Aligned(Stream *out) const +{ + AlignedStream align_s(out, Common::kAligned_Write); + for (int i = 0; i < MAX_ACTION_ARGS; ++i) + { + Data[i].Write(&align_s); + align_s.Reset(); + } +} + +void InteractionCommand::Write_v321(Stream *out) const +{ + out->WriteInt32(0); // write dummy 32-bit vtbl ptr + out->WriteInt32(Type); + WriteValues_Aligned(out); + out->WriteInt32(Children.get() ? 1 : 0); + out->WriteInt32(Parent ? 1 : 0); +} + +InteractionCommand &InteractionCommand::operator = (const InteractionCommand &ic) +{ + Type = ic.Type; + memcpy(Data, ic.Data, sizeof(Data)); + Children.reset(ic.Children.get() ? new InteractionCommandList(*ic.Children) : nullptr); + Parent = ic.Parent; + return *this; +} + +//----------------------------------------------------------------------------- + +InteractionCommandList::InteractionCommandList() + : TimesRun(0) +{ +} + +InteractionCommandList::InteractionCommandList(const InteractionCommandList &icmd_list) +{ + TimesRun = icmd_list.TimesRun; + Cmds.resize(icmd_list.Cmds.size()); + for (size_t i = 0; i < icmd_list.Cmds.size(); ++i) + { + Cmds[i].Assign(icmd_list.Cmds[i], this); + } +} + +void InteractionCommandList::Reset() +{ + Cmds.clear(); + TimesRun = 0; +} + +void InteractionCommandList::Read_Aligned(Stream *in, std::vector &cmd_children) +{ + AlignedStream align_s(in, Common::kAligned_Read); + for (size_t i = 0; i < Cmds.size(); ++i) + { + bool has_children; + Cmds[i].Read_v321(&align_s, has_children); + cmd_children[i] = has_children; + align_s.Reset(); + } +} + +void InteractionCommandList::Read_v321(Stream *in) +{ + size_t cmd_count = in->ReadInt32(); + TimesRun = in->ReadInt32(); + + std::vector cmd_children; + Cmds.resize(cmd_count); + cmd_children.resize(cmd_count); + Read_Aligned(in, cmd_children); + + for (size_t i = 0; i < cmd_count; ++i) + { + if (cmd_children[i]) + { + Cmds[i].Children.reset(new InteractionCommandList()); + Cmds[i].Children->Read_v321(in); + } + Cmds[i].Parent = this; + } +} + +void InteractionCommandList::Write_Aligned(Stream *out) const +{ + AlignedStream align_s(out, Common::kAligned_Write); + for (InterCmdVector::const_iterator it = Cmds.begin(); it != Cmds.end(); ++it) + { + it->Write_v321(&align_s); + align_s.Reset(); + } +} + +void InteractionCommandList::Write_v321(Stream *out) const +{ + size_t cmd_count = Cmds.size(); + out->WriteInt32(cmd_count); + out->WriteInt32(TimesRun); + + Write_Aligned(out); + + for (size_t i = 0; i < cmd_count; ++i) + { + if (Cmds[i].Children.get() != nullptr) + Cmds[i].Children->Write_v321(out); + } +} + +//----------------------------------------------------------------------------- + +InteractionEvent::InteractionEvent() + : Type(0) + , TimesRun(0) +{ +} + +InteractionEvent::InteractionEvent(const InteractionEvent &ie) +{ + *this = ie; +} + +InteractionEvent &InteractionEvent::operator = (const InteractionEvent &ie) +{ + Type = ie.Type; + TimesRun = ie.TimesRun; + Response.reset(ie.Response.get() ? new InteractionCommandList(*ie.Response) : nullptr); + return *this; +} + +//----------------------------------------------------------------------------- + +Interaction::Interaction() +{ +} + +Interaction::Interaction(const Interaction &ni) +{ + *this = ni; +} + +Interaction &Interaction::operator =(const Interaction &ni) +{ + Events.resize(ni.Events.size()); + for (size_t i = 0; i < ni.Events.size(); ++i) + { + Events[i] = InteractionEvent(ni.Events[i]); + } + return *this; +} + +void Interaction::CopyTimesRun(const Interaction &inter) +{ + assert(Events.size() == inter.Events.size()); + size_t count = Math::Min(Events.size(), inter.Events.size()); + for (size_t i = 0; i < count; ++i) + { + Events[i].TimesRun = inter.Events[i].TimesRun; + } +} + +void Interaction::Reset() +{ + Events.clear(); +} + +Interaction *Interaction::CreateFromStream(Stream *in) +{ + if (in->ReadInt32() != kInteractionVersion_Initial) + return nullptr; // unsupported format + + const size_t evt_count = in->ReadInt32(); + if (evt_count > MAX_NEWINTERACTION_EVENTS) + quit("Can't deserialize interaction: too many events"); + + int types[MAX_NEWINTERACTION_EVENTS]; + int load_response[MAX_NEWINTERACTION_EVENTS]; + in->ReadArrayOfInt32(types, evt_count); + in->ReadArrayOfInt32(load_response, evt_count); + + Interaction *inter = new Interaction(); + inter->Events.resize(evt_count); + for (size_t i = 0; i < evt_count; ++i) + { + InteractionEvent &evt = inter->Events[i]; + evt.Type = types[i]; + if (load_response[i] != 0) + { + evt.Response.reset(new InteractionCommandList()); + evt.Response->Read_v321(in); + } + } + return inter; +} + +void Interaction::Write(Stream *out) const +{ + out->WriteInt32(kInteractionVersion_Initial); // Version + const size_t evt_count = Events.size(); + out->WriteInt32(evt_count); + for (size_t i = 0; i < evt_count; ++i) + { + out->WriteInt32(Events[i].Type); + } + + // The pointer is only checked against NULL to determine whether the event exists + for (size_t i = 0; i < evt_count; ++i) + { + out->WriteInt32 (Events[i].Response.get() ? 1 : 0); + } + + for (size_t i = 0; i < evt_count; ++i) + { + if (Events[i].Response.get()) + Events[i].Response->Write_v321(out); + } +} + +void Interaction::ReadFromSavedgame_v321(Stream *in) +{ + const size_t evt_count = in->ReadInt32(); + if (evt_count > MAX_NEWINTERACTION_EVENTS) + quit("Can't deserialize interaction: too many events"); + + Events.resize(evt_count); + for (size_t i = 0; i < evt_count; ++i) + { + Events[i].Type = in->ReadInt32(); + } + const size_t padding = (MAX_NEWINTERACTION_EVENTS - evt_count); + for (size_t i = 0; i < padding; ++i) + in->ReadInt32(); // cannot skip when reading aligned structs + ReadTimesRunFromSave_v321(in); + + // Skip an array of dummy 32-bit pointers + for (size_t i = 0; i < MAX_NEWINTERACTION_EVENTS; ++i) + in->ReadInt32(); +} + +void Interaction::WriteToSavedgame_v321(Stream *out) const +{ + const size_t evt_count = Events.size(); + out->WriteInt32(evt_count); + + for (size_t i = 0; i < evt_count; ++i) + { + out->WriteInt32(Events[i].Type); + } + out->WriteByteCount(0, (MAX_NEWINTERACTION_EVENTS - evt_count) * sizeof(int32_t)); + WriteTimesRunToSave_v321(out); + + // Array of dummy 32-bit pointers + out->WriteByteCount(0, MAX_NEWINTERACTION_EVENTS * sizeof(int32_t)); +} + +void Interaction::ReadTimesRunFromSave_v321(Stream *in) +{ + const size_t evt_count = Events.size(); + for (size_t i = 0; i < evt_count; ++i) + { + Events[i].TimesRun = in->ReadInt32(); + } + const size_t padding = (MAX_NEWINTERACTION_EVENTS - evt_count); + for (size_t i = 0; i < padding; ++i) + in->ReadInt32(); // cannot skip when reading aligned structs +} + +void Interaction::WriteTimesRunToSave_v321(Stream *out) const +{ + const size_t evt_count = Events.size(); + for (size_t i = 0; i < Events.size(); ++i) + { + out->WriteInt32(Events[i].TimesRun); + } + out->WriteByteCount(0, (MAX_NEWINTERACTION_EVENTS - evt_count) * sizeof(int32_t)); +} + +//----------------------------------------------------------------------------- + +#define INTER_VAR_NAME_LENGTH 23 + +InteractionVariable::InteractionVariable() + : Type(0) + , Value(0) +{ +} + +InteractionVariable::InteractionVariable(const String &name, char type, int val) + : Name(name) + , Type(type) + , Value(val) +{ +} + +void InteractionVariable::Read(Stream *in) +{ + Name.ReadCount(in, INTER_VAR_NAME_LENGTH); + Type = in->ReadInt8(); + Value = in->ReadInt32(); +} + +void InteractionVariable::Write(Common::Stream *out) const +{ + out->Write(Name, INTER_VAR_NAME_LENGTH); + out->WriteInt8(Type); + out->WriteInt32(Value); +} + +//----------------------------------------------------------------------------- + +InteractionScripts *InteractionScripts::CreateFromStream(Stream *in) +{ + const size_t evt_count = in->ReadInt32(); + if (evt_count > MAX_NEWINTERACTION_EVENTS) + { + quit("Can't deserialize interaction scripts: too many events"); + return nullptr; + } + + InteractionScripts *scripts = new InteractionScripts(); + for (size_t i = 0; i < evt_count; ++i) + { + String name = String::FromStream(in); + scripts->ScriptFuncNames.push_back(name); + } + return scripts; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h new file mode 100644 index 000000000000..92e9320200cb --- /dev/null +++ b/engines/ags/shared/game/interactions.h @@ -0,0 +1,212 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Interaction structs. +// +//----------------------------------------------------------------------------- +// +// Most of the interaction types here were used before the script and have +// very limited capabilities. They were removed from AGS completely in +// generation 3.0. The code is left for backwards compatibility. +// +//----------------------------------------------------------------------------- +// +/* THE WAY THIS WORKS: +* +* Interaction (Hotspot 1) +* | +* +-- eventTypes [NUM_EVENTS] +* +-- InteractionCommandList [NUM_EVENTS] (Look at hotspot) +* | +* +-- InteractionCommand [NUM_COMMANDS] (Display message) +* | +* +-- InteractionValue [NUM_ARGUMENTS] (5) +*/ +// +//============================================================================= +#ifndef __AGS_CN_GAME__INTEREACTIONS_H +#define __AGS_CN_GAME__INTEREACTIONS_H + +#include +#include "util/string_types.h" + +#define LOCAL_VARIABLE_OFFSET 10000 +#define MAX_GLOBAL_VARIABLES 100 +#define MAX_ACTION_ARGS 5 +#define MAX_NEWINTERACTION_EVENTS 30 +#define MAX_COMMANDS_PER_LIST 40 + +namespace AGS +{ +namespace Common +{ + +enum InterValType +{ + kInterValLiteralInt = 1, + kInterValVariable = 2, + kInterValBoolean = 3, + kInterValCharnum = 4 +}; + +enum InteractionVersion +{ + kInteractionVersion_Initial = 1 +}; + +// InteractionValue represents an argument of interaction command +struct InteractionValue +{ + InterValType Type; // value type + int Value; // value definition + int Extra; + + InteractionValue(); + + void Read(Stream *in); + void Write(Stream *out) const; +}; + + +struct InteractionCommandList; +typedef std::unique_ptr UInterCmdList; + +// InteractionCommand represents a single command (action), an item of Command List +struct InteractionCommand +{ + int Type; // type of action + InteractionValue Data[MAX_ACTION_ARGS]; // action arguments + UInterCmdList Children; // list of sub-actions + InteractionCommandList *Parent; // action parent (optional) + + InteractionCommand(); + InteractionCommand(const InteractionCommand &ic); + + void Assign(const InteractionCommand &ic, InteractionCommandList *parent); + void Reset(); + + void Read_v321(Stream *in, bool &has_children); + void Write_v321(Stream *out) const; + + InteractionCommand &operator = (const InteractionCommand &ic); + +private: + void ReadValues_Aligned(Stream *in); + void WriteValues_Aligned(Stream *out) const; +}; + + +typedef std::vector InterCmdVector; +// InteractionCommandList represents a list of commands (actions) that need to be +// performed on particular game event +struct InteractionCommandList +{ + InterCmdVector Cmds; // actions to run + int TimesRun; // used by engine to track score changes + + InteractionCommandList(); + InteractionCommandList(const InteractionCommandList &icmd_list); + + void Reset(); + + void Read_v321(Stream *in); + void Write_v321(Stream *out) const; + +protected: + void Read_Aligned(Common::Stream *in, std::vector &cmd_children); + void Write_Aligned(Common::Stream *out) const; +}; + + +// InteractionEvent is a single event with a list of commands to performed +struct InteractionEvent +{ + int Type; // type of event + int TimesRun; // used by engine to track score changes + UInterCmdList Response; // list of commands to run + + InteractionEvent(); + InteractionEvent(const InteractionEvent &ie); + + InteractionEvent &operator = (const InteractionEvent &ic); +}; + +typedef std::vector InterEvtVector; +// Interaction is the list of events and responses for a game or game object +struct Interaction +{ + // The first few event types depend on the item - ID's of 100+ are + // custom events (used for subroutines) + InterEvtVector Events; + + Interaction(); + Interaction(const Interaction &inter); + + // Copy information on number of times events of this interaction were fired + void CopyTimesRun(const Interaction &inter); + void Reset(); + + // Game static data (de)serialization + static Interaction *CreateFromStream(Stream *in); + void Write(Stream *out) const; + + // Reading and writing runtime data from/to savedgame; + // NOTE: these are backwards-compatible methods, that do not always + // have practical sense + void ReadFromSavedgame_v321(Stream *in); + void WriteToSavedgame_v321(Stream *out) const; + void ReadTimesRunFromSave_v321(Stream *in); + void WriteTimesRunToSave_v321(Stream *out) const; + + Interaction &operator =(const Interaction &inter); +}; + +typedef std::shared_ptr PInteraction; + + +// Legacy pre-3.0 kind of global and local room variables +struct InteractionVariable +{ + String Name {}; + char Type {'\0'}; + int Value {0}; + + InteractionVariable(); + InteractionVariable(const String &name, char type, int val); + + void Read(Stream *in); + void Write(Stream *out) const; +}; + +typedef std::vector InterVarVector; + + +// A list of script function names for all supported events +struct InteractionScripts +{ + StringV ScriptFuncNames; + + static InteractionScripts *CreateFromStream(Stream *in); +}; + +typedef std::shared_ptr PInteractionScripts; + +} // namespace Common +} // namespace AGS + +// Legacy global variables +extern AGS::Common::InteractionVariable globalvars[MAX_GLOBAL_VARIABLES]; +extern int numGlobalVars; + +#endif // __AGS_CN_GAME__INTEREACTIONS_H diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp new file mode 100644 index 000000000000..94339a11f70d --- /dev/null +++ b/engines/ags/shared/game/main_game_file.cpp @@ -0,0 +1,831 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/audiocliptype.h" +#include "ac/dialogtopic.h" +#include "ac/gamesetupstruct.h" +#include "ac/spritecache.h" +#include "ac/view.h" +#include "ac/wordsdictionary.h" +#include "ac/dynobj/scriptaudioclip.h" +#include "core/asset.h" +#include "core/assetmanager.h" +#include "game/main_game_file.h" +#include "gui/guimain.h" +#include "script/cc_error.h" +#include "util/alignedstream.h" +#include "util/path.h" +#include "util/string_compat.h" +#include "util/string_utils.h" +#include "font/fonts.h" + +namespace AGS +{ +namespace Common +{ + +const String MainGameSource::DefaultFilename_v3 = "game28.dta"; +const String MainGameSource::DefaultFilename_v2 = "ac2game.dta"; +const String MainGameSource::Signature = "Adventure Creator Game File v2"; + +MainGameSource::MainGameSource() + : DataVersion(kGameVersion_Undefined) +{ +} + +String GetMainGameFileErrorText(MainGameFileErrorType err) +{ + switch (err) + { + case kMGFErr_NoError: + return "No error."; + case kMGFErr_FileOpenFailed: + return "Main game file not found or could not be opened."; + case kMGFErr_SignatureFailed: + return "Not an AGS main game file or unsupported format."; + case kMGFErr_FormatVersionTooOld: + return "Format version is too old; this engine can only run games made with AGS 2.5 or later."; + case kMGFErr_FormatVersionNotSupported: + return "Format version not supported."; + case kMGFErr_CapsNotSupported: + return "The game requires extended capabilities which aren't supported by the engine."; + case kMGFErr_InvalidNativeResolution: + return "Unable to determine native game resolution."; + case kMGFErr_TooManySprites: + return "Too many sprites for this engine to handle."; + case kMGFErr_TooManyCursors: + return "Too many cursors for this engine to handle."; + case kMGFErr_InvalidPropertySchema: + return "Failed to deserialize custom properties schema."; + case kMGFErr_InvalidPropertyValues: + return "Errors encountered when reading custom properties."; + case kMGFErr_NoGlobalScript: + return "No global script in game."; + case kMGFErr_CreateGlobalScriptFailed: + return "Failed to load global script."; + case kMGFErr_CreateDialogScriptFailed: + return "Failed to load dialog script."; + case kMGFErr_CreateScriptModuleFailed: + return "Failed to load script module."; + case kMGFErr_GameEntityFailed: + return "Failed to load one or more game entities."; + case kMGFErr_PluginDataFmtNotSupported: + return "Format version of plugin data is not supported."; + case kMGFErr_PluginDataSizeTooLarge: + return "Plugin data size is too large."; + } + return "Unknown error."; +} + +LoadedGameEntities::LoadedGameEntities(GameSetupStruct &game, DialogTopic *&dialogs, ViewStruct *&views) + : Game(game) + , Dialogs(dialogs) + , Views(views) + , SpriteCount(0) +{ +} + +LoadedGameEntities::~LoadedGameEntities() = default; + +bool IsMainGameLibrary(const String &filename) +{ + // We must not only detect if the given file is a correct AGS data library, + // we also have to assure that this library contains main game asset. + // Library may contain some optional data (digital audio, speech etc), but + // that is not what we want. + AssetLibInfo lib; + if (AssetManager::ReadDataFileTOC(filename, lib) != kAssetNoError) + return false; + for (size_t i = 0; i < lib.AssetInfos.size(); ++i) + { + if (lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v3) == 0 || + lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v2) == 0) + { + return true; + } + } + return false; +} + +// Begins reading main game file from a generic stream +HGameFileError OpenMainGameFileBase(PStream &in, MainGameSource &src) +{ + // Check data signature + String data_sig = String::FromStreamCount(in.get(), MainGameSource::Signature.GetLength()); + if (data_sig.Compare(MainGameSource::Signature)) + return new MainGameFileError(kMGFErr_SignatureFailed); + // Read data format version and requested engine version + src.DataVersion = (GameDataVersion)in->ReadInt32(); + if (src.DataVersion >= kGameVersion_230) + src.CompiledWith = StrUtil::ReadString(in.get()); + if (src.DataVersion < kGameVersion_250) + return new MainGameFileError(kMGFErr_FormatVersionTooOld, String::FromFormat("Required format version: %d, supported %d - %d", src.DataVersion, kGameVersion_250, kGameVersion_Current)); + if (src.DataVersion > kGameVersion_Current) + return new MainGameFileError(kMGFErr_FormatVersionNotSupported, + String::FromFormat("Game was compiled with %s. Required format version: %d, supported %d - %d", src.CompiledWith.GetCStr(), src.DataVersion, kGameVersion_250, kGameVersion_Current)); + // Read required capabilities + if (src.DataVersion >= kGameVersion_341) + { + size_t count = in->ReadInt32(); + for (size_t i = 0; i < count; ++i) + src.Caps.insert(StrUtil::ReadString(in.get())); + } + // Everything is fine, return opened stream + src.InputStream = in; + // Remember loaded game data version + // NOTE: this global variable is embedded in the code too much to get + // rid of it too easily; the easy way is to set it whenever the main + // game file is opened. + loaded_game_file_version = src.DataVersion; + return HGameFileError::None(); +} + +HGameFileError OpenMainGameFile(const String &filename, MainGameSource &src) +{ + // Cleanup source struct + src = MainGameSource(); + // Try to open given file + PStream in(File::OpenFileRead(filename)); + if (!in) + return new MainGameFileError(kMGFErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); + src.Filename = filename; + return OpenMainGameFileBase(in, src); +} + +HGameFileError OpenMainGameFileFromDefaultAsset(MainGameSource &src) +{ + // Cleanup source struct + src = MainGameSource(); + // Try to find and open main game file + String filename = MainGameSource::DefaultFilename_v3; + PStream in(AssetManager::OpenAsset(filename)); + if (!in) + { + filename = MainGameSource::DefaultFilename_v2; + in = PStream(AssetManager::OpenAsset(filename)); + } + if (!in) + return new MainGameFileError(kMGFErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); + src.Filename = filename; + return OpenMainGameFileBase(in, src); +} + +HGameFileError ReadDialogScript(PScript &dialog_script, Stream *in, GameDataVersion data_ver) +{ + if (data_ver > kGameVersion_310) // 3.1.1+ dialog script + { + dialog_script.reset(ccScript::CreateFromStream(in)); + if (dialog_script == nullptr) + return new MainGameFileError(kMGFErr_CreateDialogScriptFailed, ccErrorString); + } + else // 2.x and < 3.1.1 dialog + { + dialog_script.reset(); + } + return HGameFileError::None(); +} + +HGameFileError ReadScriptModules(std::vector &sc_mods, Stream *in, GameDataVersion data_ver) +{ + if (data_ver >= kGameVersion_270) // 2.7.0+ script modules + { + int count = in->ReadInt32(); + sc_mods.resize(count); + for (int i = 0; i < count; ++i) + { + sc_mods[i].reset(ccScript::CreateFromStream(in)); + if (sc_mods[i] == nullptr) + return new MainGameFileError(kMGFErr_CreateScriptModuleFailed, ccErrorString); + } + } + else + { + sc_mods.resize(0); + } + return HGameFileError::None(); +} + +void ReadViewStruct272_Aligned(std::vector &oldv, Stream *in, size_t count) +{ + AlignedStream align_s(in, Common::kAligned_Read); + oldv.resize(count); + for (size_t i = 0; i < count; ++i) + { + oldv[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void ReadViews(GameSetupStruct &game, ViewStruct *&views, Stream *in, GameDataVersion data_ver) +{ + int count = game.numviews; + views = (ViewStruct*)calloc(sizeof(ViewStruct) * count, 1); + if (data_ver > kGameVersion_272) // 3.x views + { + for (int i = 0; i < game.numviews; ++i) + { + views[i].ReadFromFile(in); + } + } + else // 2.x views + { + std::vector oldv; + ReadViewStruct272_Aligned(oldv, in, count); + Convert272ViewsToNew(oldv, views); + } +} + +void ReadDialogs(DialogTopic *&dialog, + std::vector< std::shared_ptr > &old_dialog_scripts, + std::vector &old_dialog_src, + std::vector &old_speech_lines, + Stream *in, GameDataVersion data_ver, int dlg_count) +{ + // TODO: I suspect +5 was a hacky way to "supress" memory access mistakes; + // double check and remove if proved unnecessary + dialog = (DialogTopic*)malloc(sizeof(DialogTopic) * dlg_count + 5); + for (int i = 0; i < dlg_count; ++i) + { + dialog[i].ReadFromFile(in); + } + + if (data_ver > kGameVersion_310) + return; + + old_dialog_scripts.resize(dlg_count); + old_dialog_src.resize(dlg_count); + for (int i = 0; i < dlg_count; ++i) + { + // NOTE: originally this was read into dialog[i].optionscripts + old_dialog_scripts[i].reset(new unsigned char[dialog[i].codesize]); + in->Read(old_dialog_scripts[i].get(), dialog[i].codesize); + + // Encrypted text script + int script_text_len = in->ReadInt32(); + if (script_text_len > 1) + { + // Originally in the Editor +20000 bytes more were allocated, with comment: + // "add a large buffer because it will get added to if another option is added" + // which probably refered to this data used by old editor directly to edit dialogs + char *buffer = new char[script_text_len]; + in->Read(buffer, script_text_len); + if (data_ver > kGameVersion_260) + decrypt_text(buffer); + old_dialog_src[i] = buffer; + delete [] buffer; + } + else + { + in->Seek(script_text_len); + } + } + + // Read the dialog lines + // + // TODO: investigate this: these strings were read much simplier in the editor, see code: + /* + char stringbuffer[1000]; + for (bb=0;bb= 26) && (encrypted)) + read_string_decrypt(iii, stringbuffer); + else + fgetstring(stringbuffer, iii); + } + */ + int i = 0; + char buffer[1000]; + if (data_ver <= kGameVersion_260) + { + // Plain text on <= 2.60 + bool end_reached = false; + + while (!end_reached) + { + char* nextchar = buffer; + + while (1) + { + *nextchar = in->ReadInt8(); + if (*nextchar == 0) + break; + + if ((unsigned char)*nextchar == 0xEF) + { + end_reached = true; + in->Seek(-1); + break; + } + + nextchar++; + } + + if (end_reached) + break; + + old_speech_lines.push_back(buffer); + i++; + } + } + else + { + // Encrypted text on > 2.60 + while (1) + { + size_t newlen = in->ReadInt32(); + if (static_cast(newlen) == 0xCAFEBEEF) // GUI magic + { + in->Seek(-4); + break; + } + + newlen = Math::Min(newlen, sizeof(buffer) - 1); + in->Read(buffer, newlen); + buffer[newlen] = 0; + decrypt_text(buffer); + old_speech_lines.push_back(buffer); + i++; + } + } +} + +HGameFileError ReadPlugins(std::vector &infos, Stream *in) +{ + int fmt_ver = in->ReadInt32(); + if (fmt_ver != 1) + return new MainGameFileError(kMGFErr_PluginDataFmtNotSupported, String::FromFormat("Version: %d, supported: %d", fmt_ver, 1)); + + int pl_count = in->ReadInt32(); + for (int i = 0; i < pl_count; ++i) + { + String name = String::FromStream(in); + size_t datasize = in->ReadInt32(); + // just check for silly datasizes + if (datasize > PLUGIN_SAVEBUFFERSIZE) + return new MainGameFileError(kMGFErr_PluginDataSizeTooLarge, String::FromFormat("Required: %u, max: %u", datasize, PLUGIN_SAVEBUFFERSIZE)); + + PluginInfo info; + info.Name = name; + if (datasize > 0) + { + info.Data.reset(new char[datasize]); + in->Read(info.Data.get(), datasize); + } + info.DataLen = datasize; + infos.push_back(info); + } + return HGameFileError::None(); +} + +// Create the missing audioClips data structure for 3.1.x games. +// This is done by going through the data files and adding all music*.* +// and sound*.* files to it. +void BuildAudioClipArray(const std::vector &assets, std::vector &audioclips) +{ + char temp_name[30]; + int temp_number; + char temp_extension[10]; + + for (const String &asset : assets) + { + if (sscanf(asset.GetCStr(), "%5s%d.%3s", temp_name, &temp_number, temp_extension) != 3) + continue; + + ScriptAudioClip clip; + if (ags_stricmp(temp_extension, "mp3") == 0) + clip.fileType = eAudioFileMP3; + else if (ags_stricmp(temp_extension, "wav") == 0) + clip.fileType = eAudioFileWAV; + else if (ags_stricmp(temp_extension, "voc") == 0) + clip.fileType = eAudioFileVOC; + else if (ags_stricmp(temp_extension, "mid") == 0) + clip.fileType = eAudioFileMIDI; + else if ((ags_stricmp(temp_extension, "mod") == 0) || (ags_stricmp(temp_extension, "xm") == 0) + || (ags_stricmp(temp_extension, "s3m") == 0) || (ags_stricmp(temp_extension, "it") == 0)) + clip.fileType = eAudioFileMOD; + else if (ags_stricmp(temp_extension, "ogg") == 0) + clip.fileType = eAudioFileOGG; + else + continue; + + if (ags_stricmp(temp_name, "music") == 0) + { + clip.scriptName.Format("aMusic%d", temp_number); + clip.fileName.Format("music%d.%s", temp_number, temp_extension); + clip.bundlingType = (ags_stricmp(temp_extension, "mid") == 0) ? AUCL_BUNDLE_EXE : AUCL_BUNDLE_VOX; + clip.type = 2; + clip.defaultRepeat = 1; + } + else if (ags_stricmp(temp_name, "sound") == 0) + { + clip.scriptName.Format("aSound%d", temp_number); + clip.fileName.Format("sound%d.%s", temp_number, temp_extension); + clip.bundlingType = AUCL_BUNDLE_EXE; + clip.type = 3; + clip.defaultRepeat = 0; + } + else + { + continue; + } + + clip.defaultVolume = 100; + clip.defaultPriority = 50; + clip.id = audioclips.size(); + audioclips.push_back(clip); + } +} + +void ApplySpriteData(GameSetupStruct &game, const LoadedGameEntities &ents, GameDataVersion data_ver) +{ + // Apply sprite flags read from original format (sequential array) + spriteset.EnlargeTo(ents.SpriteCount - 1); + for (size_t i = 0; i < ents.SpriteCount; ++i) + { + game.SpriteInfos[i].Flags = ents.SpriteFlags[i]; + } + + // Promote sprite resolutions and mark legacy resolution setting + if (data_ver < kGameVersion_350) + { + for (size_t i = 0; i < ents.SpriteCount; ++i) + { + SpriteInfo &info = game.SpriteInfos[i]; + if (game.IsLegacyHiRes() == info.IsLegacyHiRes()) + info.Flags &= ~(SPF_HIRES | SPF_VAR_RESOLUTION); + else + info.Flags |= SPF_VAR_RESOLUTION; + } + } +} + +void UpgradeFonts(GameSetupStruct &game, GameDataVersion data_ver) +{ + if (data_ver < kGameVersion_350) + { + for (int i = 0; i < game.numfonts; ++i) + { + FontInfo &finfo = game.fonts[i]; + // If the game is hi-res but font is designed for low-res, then scale it up + if (game.IsLegacyHiRes() && game.options[OPT_HIRES_FONTS] == 0) + { + finfo.SizeMultiplier = HIRES_COORD_MULTIPLIER; + } + else + { + finfo.SizeMultiplier = 1; + } + } + } + if (data_ver < kGameVersion_351) + { + for (size_t font = 0; font < game.numfonts; font++) + { + FontInfo &finfo = game.fonts[font]; + // Thickness that corresponds to 1 game pixel + finfo.AutoOutlineThickness = + // if it's a scaled up bitmap font, move the outline out more + (is_bitmap_font(font) && get_font_scaling_mul(font) > 1) ? + get_fixed_pixel_size(1) : 1; + finfo.AutoOutlineStyle = FontInfo::kSquared; + } + } +} + +// Convert audio data to the current version +void UpgradeAudio(GameSetupStruct &game, GameDataVersion data_ver) +{ + if (data_ver >= kGameVersion_320) + return; + + // An explanation of building audio clips array for pre-3.2 games. + // + // When AGS version 3.2 was released, it contained new audio system. + // In the nutshell, prior to 3.2 audio files had to be manually put + // to game project directory and their IDs were taken out of filenames. + // Since 3.2 this information is stored inside the game data. + // To make the modern engine compatible with pre-3.2 games, we have + // to scan game data packages for audio files, and enumerate them + // ourselves, then add this information to game struct. + + // Create soundClips and audioClipTypes structures. + std::vector audiocliptypes; + std::vector audioclips; + + // TODO: find out what is 4 (maybe music, sound, ambient sound, voice?) + audiocliptypes.resize(4); + for (int i = 0; i < 4; i++) + { + audiocliptypes[i].reservedChannels = 1; + audiocliptypes[i].id = i; + audiocliptypes[i].volume_reduction_while_speech_playing = 10; + } + audiocliptypes[3].reservedChannels = 0; + + audioclips.reserve(1000); + // Read audio clip names from "music.vox", then from main library + // TODO: this may become inconvenient that this code has to know about + // "music.vox"; there might be better ways to handle this. + // possibly making AssetManager download several libraries at once will + // resolve this (as well as make it unnecessary to switch between them) + std::vector assets; + // Append contents of "music.vox" + AssetLibInfo music_lib; + if (AssetManager::ReadDataFileTOC("music.vox", music_lib) == kAssetNoError) + { + for (const AssetInfo &info : music_lib.AssetInfos) + { + if (info.FileName.CompareLeftNoCase("music", 5) == 0 || info.FileName.CompareLeftNoCase("sound", 5) == 0) + assets.push_back(info.FileName); + } + } + // Append contents of the main game file + const AssetLibInfo *game_lib = AssetManager::GetLibraryTOC(); + if (game_lib) + { + for (const AssetInfo &info : game_lib->AssetInfos) + { + if (info.FileName.CompareLeftNoCase("music", 5) == 0 || info.FileName.CompareLeftNoCase("sound", 5) == 0) + assets.push_back(info.FileName); + } + } + // Append contents of the game directory + // TODO: use explicit path instead of cwd? keep this consistent with AssetManager! + { + al_ffblk ff; + if (al_findfirst("*.*", &ff, FA_ALL & ~(FA_DIREC)) == 0) + { + do + { + if (ags_strnicmp(ff.name, "music", 5) == 0 || ags_strnicmp(ff.name, "sound", 5) == 0) + assets.push_back(ff.name); + } + while (al_findnext(&ff) == 0); + al_findclose(&ff); + } + } + BuildAudioClipArray(assets, audioclips); + + // Copy gathered data over to game + game.audioClipTypes = audiocliptypes; + game.audioClips = audioclips; + + // Setup sound clip played on score event + game.scoreClipID = -1; +} + +// Convert character data to the current version +void UpgradeCharacters(GameSetupStruct &game, GameDataVersion data_ver) +{ + // TODO: this was done to simplify code transition; ideally we should be + // working with GameSetupStruct's getters and setters here + CharacterInfo *&chars = game.chars; + const int numcharacters = game.numcharacters; + + // Fixup charakter script names for 2.x (EGO -> cEgo) + if (data_ver <= kGameVersion_272) + { + String tempbuffer; + for (int i = 0; i < numcharacters; i++) + { + if (chars[i].scrname[0] == 0) + continue; + tempbuffer.Format("c%c%s", chars[i].scrname[0], ags_strlwr(&chars[i].scrname[1])); + snprintf(chars[i].scrname, MAX_SCRIPT_NAME_LEN, "%s", tempbuffer.GetCStr()); + } + } + + // Fix character walk speed for < 3.1.1 + if (data_ver <= kGameVersion_310) + { + for (int i = 0; i < numcharacters; i++) + { + if (game.options[OPT_ANTIGLIDE]) + chars[i].flags |= CHF_ANTIGLIDE; + } + } + + // Characters can always walk through each other on < 2.54 + if (data_ver < kGameVersion_254) + { + for (int i = 0; i < numcharacters; i++) + { + chars[i].flags |= CHF_NOBLOCKING; + } + } +} + +void UpgradeMouseCursors(GameSetupStruct &game, GameDataVersion data_ver) +{ + if (data_ver <= kGameVersion_272) + { + // Change cursor.view from 0 to -1 for non-animating cursors. + for (int i = 0; i < game.numcursors; ++i) + { + if (game.mcurs[i].view == 0) + game.mcurs[i].view = -1; + } + } +} + +// Adjusts score clip id, depending on game data version +void AdjustScoreSound(GameSetupStruct &game, GameDataVersion data_ver) +{ + if (data_ver < kGameVersion_320) + { + game.scoreClipID = -1; + if (game.options[OPT_SCORESOUND] > 0) + { + ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, game.options[OPT_SCORESOUND]); + if (clip) + game.scoreClipID = clip->id; + else + game.scoreClipID = -1; + } + } +} + +// Assigns default global message at given index +void SetDefaultGlmsg(GameSetupStruct &game, int msgnum, const char *val) +{ + // TODO: find out why the index should be lowered by 500 + // (or rather if we may pass correct index right away) + msgnum -= 500; + if (game.messages[msgnum] == nullptr) + game.messages[msgnum] = ags_strdup(val); +} + +// Sets up default global messages (these are used mainly in older games) +void SetDefaultGlobalMessages(GameSetupStruct &game) +{ + SetDefaultGlmsg(game, 983, "Sorry, not now."); + SetDefaultGlmsg(game, 984, "Restore"); + SetDefaultGlmsg(game, 985, "Cancel"); + SetDefaultGlmsg(game, 986, "Select a game to restore:"); + SetDefaultGlmsg(game, 987, "Save"); + SetDefaultGlmsg(game, 988, "Type a name to save as:"); + SetDefaultGlmsg(game, 989, "Replace"); + SetDefaultGlmsg(game, 990, "The save directory is full. You must replace an existing game:"); + SetDefaultGlmsg(game, 991, "Replace:"); + SetDefaultGlmsg(game, 992, "With:"); + SetDefaultGlmsg(game, 993, "Quit"); + SetDefaultGlmsg(game, 994, "Play"); + SetDefaultGlmsg(game, 995, "Are you sure you want to quit?"); + SetDefaultGlmsg(game, 996, "You are carrying nothing."); +} + +void FixupSaveDirectory(GameSetupStruct &game) +{ + // If the save game folder was not specified by game author, create one of + // the game name, game GUID, or uniqueid, as a last resort + if (!game.saveGameFolderName[0]) + { + if (game.gamename[0]) + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", game.gamename); + else if (game.guid[0]) + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", game.guid); + else + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "AGS-Game-%d", game.uniqueid); + } + // Lastly, fixup folder name by removing any illegal characters + String s = Path::FixupSharedFilename(game.saveGameFolderName); + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", s.GetCStr()); +} + +HGameFileError ReadSpriteFlags(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver) +{ + uint32_t sprcount; + if (data_ver < kGameVersion_256) + sprcount = LEGACY_MAX_SPRITES_V25; + else + sprcount = in->ReadInt32(); + if (sprcount > (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1) + return new MainGameFileError(kMGFErr_TooManySprites, String::FromFormat("Count: %u, max: %u", sprcount, (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1)); + + ents.SpriteCount = sprcount; + ents.SpriteFlags.reset(new char[sprcount]); + in->Read(ents.SpriteFlags.get(), sprcount); + return HGameFileError::None(); +} + +HGameFileError ReadGameData(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver) +{ + GameSetupStruct &game = ents.Game; + + { + AlignedStream align_s(in, Common::kAligned_Read); + game.GameSetupStructBase::ReadFromFile(&align_s); + } + + if (game.GetGameRes().IsNull()) + return new MainGameFileError(kMGFErr_InvalidNativeResolution); + + game.read_savegame_info(in, data_ver); + game.read_font_infos(in, data_ver); + HGameFileError err = ReadSpriteFlags(ents, in, data_ver); + if (!err) + return err; + game.ReadInvInfo_Aligned(in); + err = game.read_cursors(in, data_ver); + if (!err) + return err; + game.read_interaction_scripts(in, data_ver); + game.read_words_dictionary(in); + + if (!game.load_compiled_script) + return new MainGameFileError(kMGFErr_NoGlobalScript); + ents.GlobalScript.reset(ccScript::CreateFromStream(in)); + if (!ents.GlobalScript) + return new MainGameFileError(kMGFErr_CreateGlobalScriptFailed, ccErrorString); + err = ReadDialogScript(ents.DialogScript, in, data_ver); + if (!err) + return err; + err = ReadScriptModules(ents.ScriptModules, in, data_ver); + if (!err) + return err; + + ReadViews(game, ents.Views, in, data_ver); + + if (data_ver <= kGameVersion_251) + { + // skip unknown data + int count = in->ReadInt32(); + in->Seek(count * 0x204); + } + + game.read_characters(in, data_ver); + game.read_lipsync(in, data_ver); + game.read_messages(in, data_ver); + + ReadDialogs(ents.Dialogs, ents.OldDialogScripts, ents.OldDialogSources, ents.OldSpeechLines, + in, data_ver, game.numdialog); + HError err2 = GUI::ReadGUI(guis, in); + if (!err2) + return new MainGameFileError(kMGFErr_GameEntityFailed, err2); + game.numgui = guis.size(); + + if (data_ver >= kGameVersion_260) + { + err = ReadPlugins(ents.PluginInfos, in); + if (!err) + return err; + } + + err = game.read_customprops(in, data_ver); + if (!err) + return err; + err = game.read_audio(in, data_ver); + if (!err) + return err; + game.read_room_names(in, data_ver); + return err; +} + +HGameFileError UpdateGameData(LoadedGameEntities &ents, GameDataVersion data_ver) +{ + GameSetupStruct &game = ents.Game; + ApplySpriteData(game, ents, data_ver); + UpgradeFonts(game, data_ver); + UpgradeAudio(game, data_ver); + AdjustScoreSound(game, data_ver); + UpgradeCharacters(game, data_ver); + UpgradeMouseCursors(game, data_ver); + SetDefaultGlobalMessages(game); + // Global talking animation speed + if (data_ver < kGameVersion_312) + { + // Fix animation speed for old formats + game.options[OPT_GLOBALTALKANIMSPD] = 5; + } + else if (data_ver < kGameVersion_330) + { + // Convert game option for 3.1.2 - 3.2 games + game.options[OPT_GLOBALTALKANIMSPD] = game.options[OPT_GLOBALTALKANIMSPD] != 0 ? 5 : (-5 - 1); + } + // Old dialog options API for pre-3.4.0.2 games + if (data_ver < kGameVersion_340_2) + { + game.options[OPT_DIALOGOPTIONSAPI] = -1; + } + // Relative asset resolution in pre-3.5.0.8 (always enabled) + if (data_ver < kGameVersion_350) + { + game.options[OPT_RELATIVEASSETRES] = 1; + } + FixupSaveDirectory(game); + return HGameFileError::None(); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h new file mode 100644 index 000000000000..a5084003a84d --- /dev/null +++ b/engines/ags/shared/game/main_game_file.h @@ -0,0 +1,147 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// This unit provides functions for reading main game file into appropriate +// data structures. Main game file contains general game data, such as global +// options, lists of static game entities and compiled scripts modules. +// +//============================================================================= + +#ifndef __AGS_CN_GAME__MAINGAMEFILE_H +#define __AGS_CN_GAME__MAINGAMEFILE_H + +#include +#include +#include +#include "ac/game_version.h" +#include "game/plugininfo.h" +#include "script/cc_script.h" +#include "util/error.h" +#include "util/stream.h" +#include "util/string.h" +#include "util/version.h" + +struct GameSetupStruct; +struct DialogTopic; +struct ViewStruct; + +namespace AGS +{ +namespace Common +{ + +// Error codes for main game file reading +enum MainGameFileErrorType +{ + kMGFErr_NoError, + kMGFErr_FileOpenFailed, + kMGFErr_SignatureFailed, + // separate error given for "too old" format to provide clarifying message + kMGFErr_FormatVersionTooOld, + kMGFErr_FormatVersionNotSupported, + kMGFErr_CapsNotSupported, + kMGFErr_InvalidNativeResolution, + kMGFErr_TooManySprites, + kMGFErr_TooManyCursors, + kMGFErr_InvalidPropertySchema, + kMGFErr_InvalidPropertyValues, + kMGFErr_NoGlobalScript, + kMGFErr_CreateGlobalScriptFailed, + kMGFErr_CreateDialogScriptFailed, + kMGFErr_CreateScriptModuleFailed, + kMGFErr_GameEntityFailed, + kMGFErr_PluginDataFmtNotSupported, + kMGFErr_PluginDataSizeTooLarge +}; + +String GetMainGameFileErrorText(MainGameFileErrorType err); + +typedef TypedCodeError MainGameFileError; +typedef ErrorHandle HGameFileError; +typedef std::shared_ptr PStream; + +// MainGameSource defines a successfully opened main game file +struct MainGameSource +{ + // Standart main game file names for 3.* and 2.* games respectively + static const String DefaultFilename_v3; + static const String DefaultFilename_v2; + // Signature of the current game format + static const String Signature; + + // Name of the asset file + String Filename; + // Game file format version + GameDataVersion DataVersion; + // Tool identifier (like version) this game was compiled with + String CompiledWith; + // Extended engine capabilities required by the game; their primary use + // currently is to let "alternate" game formats indicate themselves + std::set Caps; + // A ponter to the opened stream + PStream InputStream; + + MainGameSource(); +}; + +// LoadedGameEntities is meant for keeping objects loaded from the game file. +// Because copying/assignment methods are not properly implemented for some +// of these objects yet, they have to be attached using references to be read +// directly. This is temporary solution that has to be resolved by the future +// code refactoring. +struct LoadedGameEntities +{ + GameSetupStruct &Game; + DialogTopic *&Dialogs; + ViewStruct *&Views; + PScript GlobalScript; + PScript DialogScript; + std::vector ScriptModules; + std::vector PluginInfos; + + // Original sprite data (when it was read into const-sized arrays) + size_t SpriteCount; + std::unique_ptr SpriteFlags; + + // Old dialog support + // legacy compiled dialog script of its own format, + // requires separate interpreting + std::vector< std::shared_ptr > OldDialogScripts; + // probably, actual dialog script sources kept within some older games + std::vector OldDialogSources; + // speech texts displayed during dialog + std::vector OldSpeechLines; + + LoadedGameEntities(GameSetupStruct &game, DialogTopic *&dialogs, ViewStruct *&views); + ~LoadedGameEntities(); +}; + +// Tells if the given path (library filename) contains main game file +bool IsMainGameLibrary(const String &filename); +// Opens main game file for reading from an arbitrary file +HGameFileError OpenMainGameFile(const String &filename, MainGameSource &src); +// Opens main game file for reading from the asset library (uses default asset name) +HGameFileError OpenMainGameFileFromDefaultAsset(MainGameSource &src); +// Reads game data, applies necessary conversions to match current format version +HGameFileError ReadGameData(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver); +// Applies necessary updates, conversions and fixups to the loaded data +// making it compatible with current engine +HGameFileError UpdateGameData(LoadedGameEntities &ents, GameDataVersion data_ver); +// Ensures that the game saves directory path is valid +void FixupSaveDirectory(GameSetupStruct &game); + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GAME__MAINGAMEFILE_H diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h new file mode 100644 index 000000000000..bf75cde7f9c6 --- /dev/null +++ b/engines/ags/shared/game/plugininfo.h @@ -0,0 +1,47 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// PluginInfo - a struct defining general information on game plugin. +// +//============================================================================= + +#ifndef __AGS_CN_GAME__PLUGININFO_H +#define __AGS_CN_GAME__PLUGININFO_H + +#include +#include "util/string.h" + +// TODO: why 10 MB limit? +#define PLUGIN_SAVEBUFFERSIZE 10247680 + +namespace AGS +{ +namespace Common +{ + +struct PluginInfo +{ + // (File)name of plugin + String Name; + // Custom data for plugin + std::shared_ptr Data; + size_t DataLen; + + PluginInfo() : DataLen(0) {} +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GAME__PLUGININFO_H diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp new file mode 100644 index 000000000000..65a65e69c3e6 --- /dev/null +++ b/engines/ags/shared/game/room_file.cpp @@ -0,0 +1,966 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" // update_polled_stuff +#include "ac/common_defines.h" +#include "ac/gamestructdefines.h" +#include "ac/wordsdictionary.h" // TODO: extract string decryption +#include "core/assetmanager.h" +#include "debug/out.h" +#include "game/customproperties.h" +#include "game/room_file.h" +#include "game/roomstruct.h" +#include "gfx/bitmap.h" +#include "script/cc_error.h" +#include "script/cc_script.h" +#include "util/compress.h" +#include "util/string_utils.h" + +// default number of hotspots to read from the room file +#define MIN_ROOM_HOTSPOTS 20 +#define LEGACY_HOTSPOT_NAME_LEN 30 +#define LEGACY_ROOM_PASSWORD_LENGTH 11 +#define LEGACY_ROOM_PASSWORD_SALT 60 +#define ROOM_MESSAGE_FLAG_DISPLAYNEXT 200 +#define ROOM_LEGACY_OPTIONS_SIZE 10 +#define LEGACY_TINT_IS_ENABLED 0x80000000 + +namespace AGS +{ +namespace Common +{ + +RoomDataSource::RoomDataSource() + : DataVersion(kRoomVersion_Undefined) +{ +} + +String GetRoomFileErrorText(RoomFileErrorType err) +{ + switch (err) + { + case kRoomFileErr_NoError: + return "No error."; + case kRoomFileErr_FileOpenFailed: + return "Room file was not found or could not be opened."; + case kRoomFileErr_FormatNotSupported: + return "Format version not supported."; + case kRoomFileErr_UnexpectedEOF: + return "Unexpected end of file."; + case kRoomFileErr_UnknownBlockType: + return "Unknown block type."; + case kRoomFileErr_OldBlockNotSupported: + return "Block type is too old and not supported by this version of the engine."; + case kRoomFileErr_BlockDataOverlapping: + return "Block data overlapping."; + case kRoomFileErr_IncompatibleEngine: + return "This engine cannot handle requested room content."; + case kRoomFileErr_ScriptLoadFailed: + return "Script load failed."; + case kRoomFileErr_InconsistentData: + return "Inconsistent room data, or file is corrupted."; + case kRoomFileErr_PropertiesBlockFormat: + return "Unknown format of the custom properties block."; + case kRoomFileErr_InvalidPropertyValues: + return "Errors encountered when reading custom properties."; + case kRoomFileErr_BlockNotFound: + return "Required block was not found."; + } + return "Unknown error."; +} + +HRoomFileError OpenRoomFile(const String &filename, RoomDataSource &src) +{ + // Cleanup source struct + src = RoomDataSource(); + // Try to open room file + Stream *in = AssetManager::OpenAsset(filename); + if (in == nullptr) + return new RoomFileError(kRoomFileErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); + // Read room header + src.Filename = filename; + src.DataVersion = (RoomFileVersion)in->ReadInt16(); + if (src.DataVersion < kRoomVersion_250b || src.DataVersion > kRoomVersion_Current) + return new RoomFileError(kRoomFileErr_FormatNotSupported, String::FromFormat("Required format version: %d, supported %d - %d", src.DataVersion, kRoomVersion_250b, kRoomVersion_Current)); + // Everything is fine, return opened stream + src.InputStream.reset(in); + return HRoomFileError::None(); +} + + +enum RoomFileBlock +{ + kRoomFblk_None = 0, + // Main room data + kRoomFblk_Main = 1, + // Room script text source (was present in older room formats) + kRoomFblk_Script = 2, + // Old versions of compiled script (no longer supported) + kRoomFblk_CompScript = 3, + kRoomFblk_CompScript2 = 4, + // Names of the room objects + kRoomFblk_ObjectNames = 5, + // Secondary room backgrounds + kRoomFblk_AnimBg = 6, + // Contemporary compiled script + kRoomFblk_CompScript3 = 7, + // Custom properties + kRoomFblk_Properties = 8, + // Script names of the room objects + kRoomFblk_ObjectScNames = 9, + // End of room data tag + kRoomFile_EOF = 0xFF +}; + + +void ReadRoomObject(RoomObjectInfo &obj, Stream *in) +{ + obj.Sprite = in->ReadInt16(); + obj.X = in->ReadInt16(); + obj.Y = in->ReadInt16(); + obj.Room = in->ReadInt16(); + obj.IsOn = in->ReadInt16() != 0; +} + +void WriteRoomObject(const RoomObjectInfo &obj, Stream *out) +{ + // TODO: expand serialization into 32-bit values at least for the sprite index!! + out->WriteInt16((int16_t)obj.Sprite); + out->WriteInt16((int16_t)obj.X); + out->WriteInt16((int16_t)obj.Y); + out->WriteInt16((int16_t)obj.Room); + out->WriteInt16(obj.IsOn ? 1 : 0); +} + + +// Main room data +HRoomFileError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) +{ + int bpp; + if (data_ver >= kRoomVersion_208) + bpp = in->ReadInt32(); + else + bpp = 1; + + if (bpp < 1) + bpp = 1; + + room->BackgroundBPP = bpp; + room->WalkBehindCount = in->ReadInt16(); + if (room->WalkBehindCount > MAX_WALK_BEHINDS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many walk-behinds (in room: %d, max: %d).", room->WalkBehindCount, MAX_WALK_BEHINDS)); + + // Walk-behinds baselines + for (size_t i = 0; i < room->WalkBehindCount; ++i) + room->WalkBehinds[i].Baseline = in->ReadInt16(); + + room->HotspotCount = in->ReadInt32(); + if (room->HotspotCount == 0) + room->HotspotCount = MIN_ROOM_HOTSPOTS; + if (room->HotspotCount > MAX_ROOM_HOTSPOTS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many hotspots (in room: %d, max: %d).", room->HotspotCount, MAX_ROOM_HOTSPOTS)); + + // Hotspots walk-to points + for (size_t i = 0; i < room->HotspotCount; ++i) + { + room->Hotspots[i].WalkTo.X = in->ReadInt16(); + room->Hotspots[i].WalkTo.Y = in->ReadInt16(); + } + + // Hotspots names and script names + for (size_t i = 0; i < room->HotspotCount; ++i) + { + if (data_ver >= kRoomVersion_3415) + room->Hotspots[i].Name = StrUtil::ReadString(in); + else if (data_ver >= kRoomVersion_303a) + room->Hotspots[i].Name = String::FromStream(in); + else + room->Hotspots[i].Name = String::FromStreamCount(in, LEGACY_HOTSPOT_NAME_LEN); + } + + if (data_ver >= kRoomVersion_270) + { + for (size_t i = 0; i < room->HotspotCount; ++i) + { + if (data_ver >= kRoomVersion_3415) + room->Hotspots[i].ScriptName = StrUtil::ReadString(in); + else + room->Hotspots[i].ScriptName = String::FromStreamCount(in, MAX_SCRIPT_NAME_LEN); + } + } + + // TODO: remove from format later + size_t polypoint_areas = in->ReadInt32(); + if (polypoint_areas > 0) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Legacy poly-point areas are no longer supported."); + /* NOTE: implementation hidden in room_file_deprecated.cpp + for (size_t i = 0; i < polypoint_areas; ++i) + wallpoints[i].Read(in); + */ + + update_polled_stuff_if_runtime(); + + room->Edges.Top = in->ReadInt16(); + room->Edges.Bottom = in->ReadInt16(); + room->Edges.Left = in->ReadInt16(); + room->Edges.Right = in->ReadInt16(); + + // Room objects + room->ObjectCount = in->ReadInt16(); + if (room->ObjectCount > MAX_ROOM_OBJECTS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many objects (in room: %d, max: %d).", room->ObjectCount, MAX_ROOM_OBJECTS)); + + for (size_t i = 0; i < room->ObjectCount; ++i) + ReadRoomObject(room->Objects[i], in); + + // Legacy interactions + if (data_ver >= kRoomVersion_253) + { + size_t localvar_count = in->ReadInt32(); + if (localvar_count > 0) + { + room->LocalVariables.resize(localvar_count); + for (size_t i = 0; i < localvar_count; ++i) + room->LocalVariables[i].Read(in); + } + } + + if (data_ver >= kRoomVersion_241 && data_ver < kRoomVersion_300a) + { + for (size_t i = 0; i < room->HotspotCount; ++i) + room->Hotspots[i].Interaction.reset(Interaction::CreateFromStream(in)); + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Interaction.reset(Interaction::CreateFromStream(in)); + room->Interaction.reset(Interaction::CreateFromStream(in)); + } + + if (data_ver >= kRoomVersion_255b) + { + room->RegionCount = in->ReadInt32(); + if (room->RegionCount > MAX_ROOM_REGIONS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many regions (in room: %d, max: %d).", room->RegionCount, MAX_ROOM_REGIONS)); + + if (data_ver < kRoomVersion_300a) + { + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].Interaction.reset(Interaction::CreateFromStream(in)); + } + } + + // Event script links + if (data_ver >= kRoomVersion_300a) + { + room->EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + for (size_t i = 0; i < room->HotspotCount; ++i) + room->Hotspots[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + } + + if (data_ver >= kRoomVersion_200_alpha) + { + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Baseline = in->ReadInt32(); + room->Width = in->ReadInt16(); + room->Height = in->ReadInt16(); + } + + if (data_ver >= kRoomVersion_262) + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Flags = in->ReadInt16(); + + if (data_ver >= kRoomVersion_200_final) + room->MaskResolution = in->ReadInt16(); + + room->WalkAreaCount = MAX_WALK_AREAS; + if (data_ver >= kRoomVersion_240) + room->WalkAreaCount = in->ReadInt32(); + if (room->WalkAreaCount > MAX_WALK_AREAS + 1) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many walkable areas (in room: %d, max: %d).", room->WalkAreaCount, MAX_WALK_AREAS + 1)); + + if (data_ver >= kRoomVersion_200_alpha7) + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].ScalingFar = in->ReadInt16(); + if (data_ver >= kRoomVersion_214) + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].Light = in->ReadInt16(); + if (data_ver >= kRoomVersion_251) + { + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].ScalingNear = in->ReadInt16(); + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].Top = in->ReadInt16(); + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].Bottom = in->ReadInt16(); + } + + in->Seek(LEGACY_ROOM_PASSWORD_LENGTH); // skip password + room->Options.StartupMusic = in->ReadInt8(); + room->Options.SaveLoadDisabled = in->ReadInt8() != 0; + room->Options.PlayerCharOff = in->ReadInt8() != 0; + room->Options.PlayerView = in->ReadInt8(); + room->Options.MusicVolume = (RoomVolumeMod)in->ReadInt8(); + in->Seek(ROOM_LEGACY_OPTIONS_SIZE - 5); + + room->MessageCount = in->ReadInt16(); + if (room->MessageCount > MAX_MESSAGES) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many room messages (in room: %d, max: %d).", room->MessageCount, MAX_MESSAGES)); + + if (data_ver >= kRoomVersion_272) + room->GameID = in->ReadInt32(); + + if (data_ver >= kRoomVersion_pre114_3) + { + for (size_t i = 0; i < room->MessageCount; ++i) + { + room->MessageInfos[i].DisplayAs = in->ReadInt8(); + room->MessageInfos[i].Flags = in->ReadInt8(); + } + } + + char buffer[3000]; + for (size_t i = 0; i < room->MessageCount; ++i) + { + if (data_ver >= kRoomVersion_261) + read_string_decrypt(in, buffer, sizeof(buffer)); + else + StrUtil::ReadCStr(buffer, in, sizeof(buffer)); + room->Messages[i] = buffer; + } + + // Very old format legacy room animations (FullAnimation) + if (data_ver >= kRoomVersion_pre114_6) + { + // TODO: remove from format later + size_t fullanim_count = in->ReadInt16(); + if (fullanim_count > 0) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Room animations are no longer supported."); + /* NOTE: implementation hidden in room_file_deprecated.cpp + in->ReadArray(&fullanims[0], sizeof(FullAnimation), fullanim_count); + */ + } + + // Ancient "graphical scripts". We currently don't support them because + // there's no knowledge on how to convert them to modern engine. + if ((data_ver >= kRoomVersion_pre114_4) && (data_ver < kRoomVersion_250a)) + { + return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Pre-2.5 graphical scripts are no longer supported."); + /* NOTE: implementation hidden in room_file_deprecated.cpp + ReadPre250Scripts(in); + */ + } + + if (data_ver >= kRoomVersion_114) + { + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + room->WalkAreas[i].Light = in->ReadInt16(); + } + if (data_ver >= kRoomVersion_255b) + { + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].Light = in->ReadInt16(); + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].Tint = in->ReadInt32(); + } + + update_polled_stuff_if_runtime(); + // Primary background + Bitmap *mask = nullptr; + if (data_ver >= kRoomVersion_pre114_5) + load_lzw(in, &mask, room->BackgroundBPP, room->Palette); + else + loadcompressed_allegro(in, &mask, room->Palette); + room->BgFrames[0].Graphic.reset(mask); + + update_polled_stuff_if_runtime(); + // Mask bitmaps + if (data_ver >= kRoomVersion_255b) + { + loadcompressed_allegro(in, &mask, room->Palette); + } + else if (data_ver >= kRoomVersion_114) + { + // an old version - clear the 'shadow' area into a blank regions bmp + loadcompressed_allegro(in, &mask, room->Palette); + delete mask; + mask = nullptr; + } + room->RegionMask.reset(mask); + update_polled_stuff_if_runtime(); + loadcompressed_allegro(in, &mask, room->Palette); + room->WalkAreaMask.reset(mask); + update_polled_stuff_if_runtime(); + loadcompressed_allegro(in, &mask, room->Palette); + room->WalkBehindMask.reset(mask); + update_polled_stuff_if_runtime(); + loadcompressed_allegro(in, &mask, room->Palette); + room->HotspotMask.reset(mask); + return HRoomFileError::None(); +} + +// Room script sources (original text) +HRoomFileError ReadScriptBlock(char *&buf, Stream *in, RoomFileVersion data_ver) +{ + size_t len = in->ReadInt32(); + buf = new char[len + 1]; + in->Read(buf, len); + buf[len] = 0; + for (size_t i = 0; i < len; ++i) + buf[i] += passwencstring[i % 11]; + return HRoomFileError::None(); +} + +// Compiled room script +HRoomFileError ReadCompSc3Block(RoomStruct *room, Stream *in, RoomFileVersion data_ver) +{ + room->CompiledScript.reset(ccScript::CreateFromStream(in)); + if (room->CompiledScript == nullptr) + return new RoomFileError(kRoomFileErr_ScriptLoadFailed, ccErrorString); + return HRoomFileError::None(); +} + +// Room object names +HRoomFileError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) +{ + int name_count = in->ReadByte(); + if (name_count != room->ObjectCount) + return new RoomFileError(kRoomFileErr_InconsistentData, + String::FromFormat("In the object names block, expected name count: %d, got %d", room->ObjectCount, name_count)); + + for (size_t i = 0; i < room->ObjectCount; ++i) + { + if (data_ver >= kRoomVersion_3415) + room->Objects[i].Name = StrUtil::ReadString(in); + else + room->Objects[i].Name.ReadCount(in, LEGACY_MAXOBJNAMELEN); + } + return HRoomFileError::None(); +} + +// Room object script names +HRoomFileError ReadObjScNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) +{ + int name_count = in->ReadByte(); + if (name_count != room->ObjectCount) + return new RoomFileError(kRoomFileErr_InconsistentData, + String::FromFormat("In the object script names block, expected name count: %d, got %d", room->ObjectCount, name_count)); + + for (size_t i = 0; i < room->ObjectCount; ++i) + { + if (data_ver >= kRoomVersion_3415) + room->Objects[i].ScriptName = StrUtil::ReadString(in); + else + room->Objects[i].ScriptName.ReadCount(in, MAX_SCRIPT_NAME_LEN); + } + return HRoomFileError::None(); +} + +// Secondary backgrounds +HRoomFileError ReadAnimBgBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) +{ + room->BgFrameCount = in->ReadByte(); + if (room->BgFrameCount > MAX_ROOM_BGFRAMES) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many room backgrounds (in room: %d, max: %d).", room->BgFrameCount, MAX_ROOM_BGFRAMES)); + + room->BgAnimSpeed = in->ReadByte(); + if (data_ver >= kRoomVersion_255a) + { + for (size_t i = 0; i < room->BgFrameCount; ++i) + room->BgFrames[i].IsPaletteShared = in->ReadInt8() != 0; + } + + for (size_t i = 1; i < room->BgFrameCount; ++i) + { + update_polled_stuff_if_runtime(); + Bitmap *frame = nullptr; + load_lzw(in, &frame, room->BackgroundBPP, room->BgFrames[i].Palette); + room->BgFrames[i].Graphic.reset(frame); + } + return HRoomFileError::None(); +} + +// Read custom properties +HRoomFileError ReadPropertiesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) +{ + int prop_ver = in->ReadInt32(); + if (prop_ver != 1) + return new RoomFileError(kRoomFileErr_PropertiesBlockFormat, String::FromFormat("Expected version %d, got %d", 1, prop_ver)); + + int errors = 0; + errors += Properties::ReadValues(room->Properties, in); + for (size_t i = 0; i < room->HotspotCount; ++i) + errors += Properties::ReadValues(room->Hotspots[i].Properties, in); + for (size_t i = 0; i < room->ObjectCount; ++i) + errors += Properties::ReadValues(room->Objects[i].Properties, in); + + if (errors > 0) + return new RoomFileError(kRoomFileErr_InvalidPropertyValues); + return HRoomFileError::None(); +} + +HRoomFileError ReadRoomBlock(RoomStruct *room, Stream *in, RoomFileBlock block, RoomFileVersion data_ver) +{ + soff_t block_len = data_ver < kRoomVersion_350 ? in->ReadInt32() : in->ReadInt64(); + soff_t block_end = in->GetPosition() + block_len; + + HRoomFileError err; + switch (block) + { + case kRoomFblk_Main: + err = ReadMainBlock(room, in, data_ver); + break; + case kRoomFblk_Script: + in->Seek(block_len); // no longer read source script text into RoomStruct + break; + case kRoomFblk_CompScript3: + err = ReadCompSc3Block(room, in, data_ver); + break; + case kRoomFblk_ObjectNames: + err = ReadObjNamesBlock(room, in, data_ver); + break; + case kRoomFblk_ObjectScNames: + err = ReadObjScNamesBlock(room, in, data_ver); + break; + case kRoomFblk_AnimBg: + err = ReadAnimBgBlock(room, in, data_ver); + break; + case kRoomFblk_Properties: + err = ReadPropertiesBlock(room, in, data_ver); + break; + case kRoomFblk_CompScript: + case kRoomFblk_CompScript2: + return new RoomFileError(kRoomFileErr_OldBlockNotSupported, + String::FromFormat("Type: %d.", block)); + default: + return new RoomFileError(kRoomFileErr_UnknownBlockType, + String::FromFormat("Type: %d, known range: %d - %d.", block, kRoomFblk_Main, kRoomFblk_ObjectScNames)); + } + + if (!err) + return err; + + soff_t cur_pos = in->GetPosition(); + if (cur_pos > block_end) + { + return new RoomFileError(kRoomFileErr_BlockDataOverlapping, + String::FromFormat("Type: %d, expected to end at offset: %u, finished reading at %u.", block, block_end, cur_pos)); + } + else if (cur_pos < block_end) + { + Debug::Printf(kDbgMsg_Warn, "WARNING: room data blocks nonsequential, block type %d expected to end at %u, finished reading at %u", + block, block_end, cur_pos); + in->Seek(block_end, Common::kSeekBegin); + } + return HRoomFileError::None(); +} + + +HRoomFileError ReadRoomData(RoomStruct *room, Stream *in, RoomFileVersion data_ver) +{ + room->DataVersion = data_ver; + + RoomFileBlock block; + do + { + update_polled_stuff_if_runtime(); + int b = in->ReadByte(); + if (b < 0) + return new RoomFileError(kRoomFileErr_UnexpectedEOF); + block = (RoomFileBlock)b; + if (block != kRoomFile_EOF) + { + HRoomFileError err = ReadRoomBlock(room, in, block, data_ver); + if (!err) + return err; + } + } + while (block != kRoomFile_EOF); + return HRoomFileError::None(); +} + +HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool game_is_hires, const std::vector &sprinfos) +{ + if (data_ver < kRoomVersion_200_final) + room->MaskResolution = room->BgFrames[0].Graphic->GetWidth() > 320 ? kRoomHiRes : kRoomLoRes; + if (data_ver < kRoomVersion_3508) + { + // Save legacy resolution if it DOES NOT match game's; + // otherwise it gets promoted to "real resolution" + if (room->MaskResolution == 1 && game_is_hires) + room->SetResolution(kRoomLoRes); + else if (room->MaskResolution > 1 && !game_is_hires) + room->SetResolution(kRoomHiRes); + } + + // Old version - copy walkable areas to regions + if (data_ver < kRoomVersion_255b) + { + if (!room->RegionMask) + room->RegionMask.reset(BitmapHelper::CreateBitmap(room->WalkAreaMask->GetWidth(), room->WalkAreaMask->GetHeight(), 8)); + room->RegionMask->Blit(room->WalkAreaMask.get(), 0, 0, 0, 0, room->RegionMask->GetWidth(), room->RegionMask->GetHeight()); + for (size_t i = 0; i < MAX_ROOM_REGIONS; ++i) + { + room->Regions[i].Light = room->WalkAreas[i].Light; + room->Regions[i].Tint = 255; + } + } + + // Fill in dummy interaction objects into unused slots + // TODO: remove this later, need to rework the legacy interaction usage around the engine code to prevent crashes + if (data_ver < kRoomVersion_300a) + { + if (!room->Interaction) + room->Interaction.reset(new Interaction()); + for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) + if (!room->Hotspots[i].Interaction) + room->Hotspots[i].Interaction.reset(new Interaction()); + for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) + if (!room->Objects[i].Interaction) + room->Objects[i].Interaction.reset(new Interaction()); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + if (!room->Regions[i].Interaction) + room->Regions[i].Interaction.reset(new Interaction()); + } + + // Upgade room object script names + if (data_ver < kRoomVersion_300a) + { + for (size_t i = 0; i < room->ObjectCount; ++i) + { + if (room->Objects[i].ScriptName.GetLength() > 0) + { + String jibbledScriptName; + jibbledScriptName.Format("o%s", room->Objects[i].ScriptName.GetCStr()); + jibbledScriptName.MakeLower(); + if (jibbledScriptName.GetLength() >= 2) + jibbledScriptName.SetAt(1, toupper(jibbledScriptName[1u])); + room->Objects[i].ScriptName = jibbledScriptName; + } + } + } + + // Pre-3.0.3, multiply up co-ordinates for high-res games to bring them + // to the proper game coordinate system. + // If you change this, also change convert_room_coordinates_to_data_res + // function in the engine + if (data_ver < kRoomVersion_303b && game_is_hires) + { + const int mul = HIRES_COORD_MULTIPLIER; + for (size_t i = 0; i < room->ObjectCount; ++i) + { + room->Objects[i].X *= mul; + room->Objects[i].Y *= mul; + if (room->Objects[i].Baseline > 0) + { + room->Objects[i].Baseline *= mul; + } + } + + for (size_t i = 0; i < room->HotspotCount; ++i) + { + room->Hotspots[i].WalkTo.X *= mul; + room->Hotspots[i].WalkTo.Y *= mul; + } + + for (size_t i = 0; i < room->WalkBehindCount; ++i) + { + room->WalkBehinds[i].Baseline *= mul; + } + + room->Edges.Left *= mul; + room->Edges.Top *= mul; + room->Edges.Bottom *= mul; + room->Edges.Right *= mul; + room->Width *= mul; + room->Height *= mul; + } + + // Adjust object Y coordinate by adding sprite's height + // NOTE: this is impossible to do without game sprite information loaded beforehand + // NOTE: this should be done after coordinate conversion above for simplicity + if (data_ver < kRoomVersion_300a) + { + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Y += sprinfos[room->Objects[i].Sprite].Height; + } + + if (data_ver >= kRoomVersion_251) + { + // if they set a contiuously scaled area where the top + // and bottom zoom levels are identical, set it as a normal + // scaled area + for (size_t i = 0; i < room->WalkAreaCount; ++i) + { + if (room->WalkAreas[i].ScalingFar == room->WalkAreas[i].ScalingNear) + room->WalkAreas[i].ScalingNear = NOT_VECTOR_SCALED; + } + } + + // Convert the old format region tint saturation + if (data_ver < kRoomVersion_3404) + { + for (size_t i = 0; i < room->RegionCount; ++i) + { + if ((room->Regions[i].Tint & LEGACY_TINT_IS_ENABLED) != 0) + { + room->Regions[i].Tint &= ~LEGACY_TINT_IS_ENABLED; + // older versions of the editor had a bug - work around it + int tint_amount = (room->Regions[i].Light > 0 ? room->Regions[i].Light : 50); + room->Regions[i].Tint |= (tint_amount & 0xFF) << 24; + room->Regions[i].Light = 255; + } + } + } + + // Older format room messages had flags appended to the message string + // TODO: find out which data versions had these; is it safe to assume this was before kRoomVersion_pre114_3? + for (size_t i = 0; i < room->MessageCount; ++i) + { + if (!room->Messages[i].IsEmpty() && room->Messages[i].GetLast() == (char)ROOM_MESSAGE_FLAG_DISPLAYNEXT) + { + room->Messages[i].ClipRight(1); + room->MessageInfos[i].Flags |= MSG_DISPLAYNEXT; + } + } + + // sync bpalettes[0] with room.pal + memcpy(room->BgFrames[0].Palette, room->Palette, sizeof(color) * 256); + return HRoomFileError::None(); +} + +HRoomFileError ExtractScriptText(String &script, Stream *in, RoomFileVersion data_ver) +{ + RoomFileBlock block; + do + { + int b = in->ReadByte(); + if (b < 0) + return new RoomFileError(kRoomFileErr_UnexpectedEOF); + block = (RoomFileBlock)b; + soff_t block_len = data_ver < kRoomVersion_350 ? in->ReadInt32() : in->ReadInt64(); + if (block == kRoomFblk_Script) + { + char *buf = nullptr; + HRoomFileError err = ReadScriptBlock(buf, in, data_ver); + if (err) + { + script = buf; + delete buf; + } + return err; + } + if (block != kRoomFile_EOF) + in->Seek(block_len); // skip block + } while (block != kRoomFile_EOF); + return new RoomFileError(kRoomFileErr_BlockNotFound); +} + + +// Type of function that writes single room block. +typedef void(*PfnWriteBlock)(const RoomStruct *room, Stream *out); +// Generic function that saves a block and automatically adds its size into header +void WriteBlock(const RoomStruct *room, RoomFileBlock block, PfnWriteBlock writer, Stream *out) +{ + // Write block's header + out->WriteByte(block); + soff_t sz_at = out->GetPosition(); + out->WriteInt64(0); // block size placeholder + // Call writer to save actual block contents + writer(room, out); + + // Now calculate the block's size... + soff_t end_at = out->GetPosition(); + soff_t block_size = (end_at - sz_at) - sizeof(int64_t); + // ...return back and write block's size in the placeholder + out->Seek(sz_at, Common::kSeekBegin); + out->WriteInt64(block_size); + // ...and get back to the end of the file + out->Seek(0, Common::kSeekEnd); +} + +void WriteInteractionScripts(const InteractionScripts *interactions, Stream *out) +{ + out->WriteInt32(interactions->ScriptFuncNames.size()); + for (size_t i = 0; i < interactions->ScriptFuncNames.size(); ++i) + interactions->ScriptFuncNames[i].Write(out); +} + +void WriteMainBlock(const RoomStruct *room, Stream *out) +{ + out->WriteInt32(room->BackgroundBPP); + out->WriteInt16((int16_t)room->WalkBehindCount); + for (size_t i = 0; i < room->WalkBehindCount; ++i) + out->WriteInt16(room->WalkBehinds[i].Baseline); + + out->WriteInt32(room->HotspotCount); + for (size_t i = 0; i < room->HotspotCount; ++i) + { + out->WriteInt16(room->Hotspots[i].WalkTo.X); + out->WriteInt16(room->Hotspots[i].WalkTo.Y); + } + for (size_t i = 0; i < room->HotspotCount; ++i) + Common::StrUtil::WriteString(room->Hotspots[i].Name, out); + for (size_t i = 0; i < room->HotspotCount; ++i) + Common::StrUtil::WriteString(room->Hotspots[i].ScriptName, out); + + out->WriteInt32(0); // legacy poly-point areas + + out->WriteInt16(room->Edges.Top); + out->WriteInt16(room->Edges.Bottom); + out->WriteInt16(room->Edges.Left); + out->WriteInt16(room->Edges.Right); + + out->WriteInt16((int16_t)room->ObjectCount); + for (size_t i = 0; i < room->ObjectCount; ++i) + { + WriteRoomObject(room->Objects[i], out); + } + + out->WriteInt32(0); // legacy interaction vars + out->WriteInt32(MAX_ROOM_REGIONS); + + WriteInteractionScripts(room->EventHandlers.get(), out); + for (size_t i = 0; i < room->HotspotCount; ++i) + WriteInteractionScripts(room->Hotspots[i].EventHandlers.get(), out); + for (size_t i = 0; i < room->ObjectCount; ++i) + WriteInteractionScripts(room->Objects[i].EventHandlers.get(), out); + for (size_t i = 0; i < room->RegionCount; ++i) + WriteInteractionScripts(room->Regions[i].EventHandlers.get(), out); + + for (size_t i = 0; i < room->ObjectCount; ++i) + out->WriteInt32(room->Objects[i].Baseline); + out->WriteInt16(room->Width); + out->WriteInt16(room->Height); + for (size_t i = 0; i < room->ObjectCount; ++i) + out->WriteInt16(room->Objects[i].Flags); + out->WriteInt16(room->MaskResolution); + + out->WriteInt32(MAX_WALK_AREAS + 1); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].ScalingFar); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Light); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].ScalingNear); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Top); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Bottom); + + out->WriteByteCount(0, LEGACY_ROOM_PASSWORD_LENGTH); + out->WriteInt8(room->Options.StartupMusic); + out->WriteInt8(room->Options.SaveLoadDisabled ? 1 : 0); + out->WriteInt8(room->Options.PlayerCharOff ? 1 : 0); + out->WriteInt8(room->Options.PlayerView); + out->WriteInt8(room->Options.MusicVolume); + out->WriteByteCount(0, ROOM_LEGACY_OPTIONS_SIZE - 5); + out->WriteInt16((int16_t)room->MessageCount); + out->WriteInt32(room->GameID); + for (size_t i = 0; i < room->MessageCount; ++i) + { + out->WriteInt8(room->MessageInfos[i].DisplayAs); + out->WriteInt8(room->MessageInfos[i].Flags); + } + for (size_t i = 0; i < room->MessageCount; ++i) + write_string_encrypt(out, room->Messages[i]); + + out->WriteInt16(0); // legacy room animations + + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Light); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + out->WriteInt16(room->Regions[i].Light); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + out->WriteInt32(room->Regions[i].Tint); + + save_lzw(out, room->BgFrames[0].Graphic.get(), room->Palette); + savecompressed_allegro(out, room->RegionMask.get(), room->Palette); + savecompressed_allegro(out, room->WalkAreaMask.get(), room->Palette); + savecompressed_allegro(out, room->WalkBehindMask.get(), room->Palette); + savecompressed_allegro(out, room->HotspotMask.get(), room->Palette); +} + +void WriteCompSc3Block(const RoomStruct *room, Stream *out) +{ + room->CompiledScript->Write(out); +} + +void WriteObjNamesBlock(const RoomStruct *room, Stream *out) +{ + out->WriteByte((int8_t)room->ObjectCount); + for (size_t i = 0; i < room->ObjectCount; ++i) + Common::StrUtil::WriteString(room->Objects[i].Name, out); +} + +void WriteObjScNamesBlock(const RoomStruct *room, Stream *out) +{ + out->WriteByte((int8_t)room->ObjectCount); + for (size_t i = 0; i < room->ObjectCount; ++i) + Common::StrUtil::WriteString(room->Objects[i].ScriptName, out); +} + +void WriteAnimBgBlock(const RoomStruct *room, Stream *out) +{ + out->WriteByte((int8_t)room->BgFrameCount); + out->WriteByte(room->BgAnimSpeed); + + for (size_t i = 0; i < room->BgFrameCount; ++i) + out->WriteInt8(room->BgFrames[i].IsPaletteShared ? 1 : 0); + for (size_t i = 1; i < room->BgFrameCount; ++i) + save_lzw(out, room->BgFrames[i].Graphic.get(), room->BgFrames[i].Palette); +} + +void WritePropertiesBlock(const RoomStruct *room, Stream *out) +{ + out->WriteInt32(1); // Version 1 of properties block + Properties::WriteValues(room->Properties, out); + for (size_t i = 0; i < room->HotspotCount; ++i) + Properties::WriteValues(room->Hotspots[i].Properties, out); + for (size_t i = 0; i < room->ObjectCount; ++i) + Properties::WriteValues(room->Objects[i].Properties, out); +} + +HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersion data_ver) +{ + if (data_ver < kRoomVersion_Current) + return new RoomFileError(kRoomFileErr_FormatNotSupported, "We no longer support saving room in the older format."); + + // Header + out->WriteInt16(data_ver); + // Main data + WriteBlock(room, kRoomFblk_Main, WriteMainBlock, out); + // Compiled script + if (room->CompiledScript) + WriteBlock(room, kRoomFblk_CompScript3, WriteCompSc3Block, out); + // Object names + if (room->ObjectCount > 0) + { + WriteBlock(room, kRoomFblk_ObjectNames, WriteObjNamesBlock, out); + WriteBlock(room, kRoomFblk_ObjectScNames, WriteObjScNamesBlock, out); + } + // Secondary background frames + if (room->BgFrameCount > 1) + WriteBlock(room, kRoomFblk_AnimBg, WriteAnimBgBlock, out); + // Custom properties + WriteBlock(room, kRoomFblk_Properties, WritePropertiesBlock, out); + + // Write end of room file + out->WriteByte(kRoomFile_EOF); + return HRoomFileError::None(); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h new file mode 100644 index 000000000000..ce894721ce99 --- /dev/null +++ b/engines/ags/shared/game/room_file.h @@ -0,0 +1,92 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// This unit provides functions for reading main game file into appropriate +// data structures. Main game file contains general game data, such as global +// options, lists of static game entities and compiled scripts modules. +// +//============================================================================= + +#ifndef __AGS_CN_GAME_ROOMFILE_H +#define __AGS_CN_GAME_ROOMFILE_H + +#include +#include +#include "game/room_version.h" +#include "util/error.h" +#include "util/stream.h" +#include "util/string.h" + +struct SpriteInfo; +namespace AGS +{ +namespace Common +{ + +class RoomStruct; + +enum RoomFileErrorType +{ + kRoomFileErr_NoError, + kRoomFileErr_FileOpenFailed, + kRoomFileErr_FormatNotSupported, + kRoomFileErr_UnexpectedEOF, + kRoomFileErr_UnknownBlockType, + kRoomFileErr_OldBlockNotSupported, + kRoomFileErr_BlockDataOverlapping, + kRoomFileErr_IncompatibleEngine, + kRoomFileErr_ScriptLoadFailed, + kRoomFileErr_InconsistentData, + kRoomFileErr_PropertiesBlockFormat, + kRoomFileErr_InvalidPropertyValues, + kRoomFileErr_BlockNotFound +}; + +String GetRoomFileErrorText(RoomFileErrorType err); + +typedef TypedCodeError RoomFileError; +typedef ErrorHandle HRoomFileError; +typedef std::shared_ptr PStream; + + +// RoomDataSource defines a successfully opened room file +struct RoomDataSource +{ + // Name of the asset file + String Filename; + // Room file format version + RoomFileVersion DataVersion; + // A ponter to the opened stream + PStream InputStream; + + RoomDataSource(); +}; + +// Opens room file for reading from an arbitrary file +HRoomFileError OpenRoomFile(const String &filename, RoomDataSource &src); +// Reads room data +HRoomFileError ReadRoomData(RoomStruct *room, Stream *in, RoomFileVersion data_ver); +// Applies necessary updates, conversions and fixups to the loaded data +// making it compatible with current engine +HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool game_is_hires, const std::vector &sprinfos); +// Extracts text script from the room file, if it's available. +// Historically, text sources were kept inside packed room files before AGS 3.*. +HRoomFileError ExtractScriptText(String &script, Stream *in, RoomFileVersion data_ver); + +HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersion data_ver); + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GAME_ROOMFILE_H diff --git a/engines/ags/shared/game/room_file_deprecated.cpp b/engines/ags/shared/game/room_file_deprecated.cpp new file mode 100644 index 000000000000..4424ddbdc03f --- /dev/null +++ b/engines/ags/shared/game/room_file_deprecated.cpp @@ -0,0 +1,135 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Deprecated room stuff. Removed from room class and load routine because this +// data is no longer supported in the engine. Perhaps move to some legacy +// knowledge base; or restore when it's possible to support ancient games. +// +//============================================================================= + +#if defined (OBSOLETE) + +#include "ac/common.h" +#include "util/stream.h" + +using namespace AGS::Common; + +#define AE_WAITFLAG 0x80000000 +#define MAXANIMSTAGES 10 +struct AnimationStruct +{ + int x, y; + int data; + int object; + int speed; + char action; + char wait; + AnimationStruct() { action = 0; object = 0; wait = 1; speed = 5; } +}; + +struct FullAnimation +{ + AnimationStruct stage[MAXANIMSTAGES]; + int numstages; + FullAnimation() { numstages = 0; } +}; + +#define MAXPOINTS 30 +struct PolyPoints +{ + int x[MAXPOINTS]; + int y[MAXPOINTS]; + int numpoints; + void add_point(int x, int y); + PolyPoints() { numpoints = 0; } + + void Read(AGS::Common::Stream *in); +}; + + +#define MAXANIMS 10 +// Just a list of cut out data +struct DeprecatedRoomStruct +{ + // Full-room animations + int16_t numanims; + FullAnimation anims[MAXANIMS]; + // Polygonal walkable areas (unknown version) + int32_t numwalkareas; + PolyPoints wallpoints[MAX_WALK_AREAS]; + // Unknown flags + int16_t flagstates[MAX_FLAGS]; +}; + + + +void PolyPoints::add_point(int x, int y) +{ + x[numpoints] = x; + y[numpoints] = y; + numpoints++; + + if (numpoints >= MAXPOINTS) + quit("too many poly points added"); +} + +void PolyPoints::Read(Stream *in) +{ + in->ReadArrayOfInt32(x, MAXPOINTS); + in->ReadArrayOfInt32(y, MAXPOINTS); + numpoints = in->ReadInt32(); +} + + +// +// Pre-2.5 scripts (we don't know how to convert them for the modern engine) +// +#define SCRIPT_CONFIG_VERSION 1 +HRoomFileError ReadAncientScriptConfig(Stream *in) +{ + int fmt = in->ReadInt32(); + if (fmt != SCRIPT_CONFIG_VERSION) + return new RoomFileError(kRoomFileErr_FormatNotSupported, String::FromFormat("Invalid script configuration format (in room: %d, expected: %d).", fmt, SCRIPT_CONFIG_VERSION)); + + size_t var_count = in->ReadInt32(); + for (size_t i = 0; i < var_count; ++i) + { + size_t len = in->ReadByte(); + in->Seek(len); + } + return HRoomFileError::None(); +} + +HRoomFileError ReadAncientGraphicalScripts(Stream *in) +{ + do + { + int ct = in->ReadInt32(); + if (ct == -1 || in->EOS()) + break; + size_t len = in->ReadInt32(); + in->Seek(len); + } while (true); + return HRoomFileError::None(); +} + +HRoomFileError ReadPre250Scripts(Stream *in) +{ + HRoomFileError err = ReadAncientScriptConfig(in); + if (err) + err = ReadAncientGraphicalScripts(in); + return err; +} + +#endif // OBSOLETE diff --git a/engines/ags/shared/game/room_version.h b/engines/ags/shared/game/room_version.h new file mode 100644 index 000000000000..0fdd0ea60201 --- /dev/null +++ b/engines/ags/shared/game/room_version.h @@ -0,0 +1,86 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Room version constants and information +// +//============================================================================= + +#ifndef __AGS_CN_AC__ROOMVERSION_H +#define __AGS_CN_AC__ROOMVERSION_H + +/* room file versions history +8: final v1.14 release +9: intermediate v2 alpha releases +10: v2 alpha-7 release +11: final v2.00 release +12: v2.08, to add colour depth byte +13: v2.14, add walkarea light levels +14: v2.4, fixed so it saves walkable area 15 +15: v2.41, supports NewInteraction +16: v2.5 +17: v2.5 - just version change to force room re-compile for new charctr struct +18: v2.51 - vector scaling +19: v2.53 - interaction variables +20: v2.55 - shared palette backgrounds +21: v2.55 - regions +22: v2.61 - encrypt room messages +23: v2.62 - object flags +24: v2.7 - hotspot script names +25: v2.72 - game id embedded +26: v3.0 - new interaction format, and no script source +27: v3.0 - store Y of bottom of object, not top +28: v3.0.3 - remove hotspot name length limit +29: v3.0.3 - high-res coords for object x/y, edges and hotspot walk-to point +30: v3.4.0.4 - tint luminance for regions +31: v3.4.1.5 - removed room object and hotspot name length limits +32: v3.5.0 - 64-bit file offsets +33: v3.5.0.8 - deprecated room resolution, added mask resolution +*/ +enum RoomFileVersion +{ + kRoomVersion_Undefined = 0, + kRoomVersion_pre114_3 = 3, // exact version unknown + kRoomVersion_pre114_4 = 4, // exact version unknown + kRoomVersion_pre114_5 = 5, // exact version unknown + kRoomVersion_pre114_6 = 6, // exact version unknown + kRoomVersion_114 = 8, + kRoomVersion_200_alpha = 9, + kRoomVersion_200_alpha7 = 10, + kRoomVersion_200_final = 11, + kRoomVersion_208 = 12, + kRoomVersion_214 = 13, + kRoomVersion_240 = 14, + kRoomVersion_241 = 15, + kRoomVersion_250a = 16, + kRoomVersion_250b = 17, + kRoomVersion_251 = 18, + kRoomVersion_253 = 19, + kRoomVersion_255a = 20, + kRoomVersion_255b = 21, + kRoomVersion_261 = 22, + kRoomVersion_262 = 23, + kRoomVersion_270 = 24, + kRoomVersion_272 = 25, + kRoomVersion_300a = 26, + kRoomVersion_300b = 27, + kRoomVersion_303a = 28, + kRoomVersion_303b = 29, + kRoomVersion_3404 = 30, + kRoomVersion_3415 = 31, + kRoomVersion_350 = 32, + kRoomVersion_3508 = 33, + kRoomVersion_Current = kRoomVersion_3508 +}; + +#endif // __AGS_CN_AC__ROOMVERSION_H diff --git a/engines/ags/shared/game/roomstruct.cpp b/engines/ags/shared/game/roomstruct.cpp new file mode 100644 index 000000000000..168ed3875143 --- /dev/null +++ b/engines/ags/shared/game/roomstruct.cpp @@ -0,0 +1,325 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" // update_polled_stuff_if_runtime +#include "game/room_file.h" +#include "game/roomstruct.h" +#include "gfx/bitmap.h" + +namespace AGS +{ +namespace Common +{ + +RoomOptions::RoomOptions() + : StartupMusic(0) + , SaveLoadDisabled(false) + , PlayerCharOff(false) + , PlayerView(0) + , MusicVolume(kRoomVolumeNormal) +{ +} + +RoomBgFrame::RoomBgFrame() + : IsPaletteShared(false) +{ + memset(Palette, 0, sizeof(Palette)); +} + +RoomEdges::RoomEdges() + : Left(0) + , Right(0) + , Top(0) + , Bottom(0) +{ +} + +RoomEdges::RoomEdges(int l, int r, int t, int b) + : Left(l) + , Right(r) + , Top(t) + , Bottom(b) +{ +} + +RoomObjectInfo::RoomObjectInfo() + : Sprite(0) + , X(0) + , Y(0) + , Room(-1) + , IsOn(false) + , Baseline(0xFF) + , Flags(0) +{ +} + +RoomRegion::RoomRegion() + : Light(0) + , Tint(0) +{ +} + +WalkArea::WalkArea() + : CharacterView(0) + , ScalingFar(0) + , ScalingNear(NOT_VECTOR_SCALED) + , Light(0) + , Top(-1) + , Bottom(-1) +{ +} + +WalkBehind::WalkBehind() + : Baseline(0) +{ +} + +MessageInfo::MessageInfo() + : DisplayAs(0) + , Flags(0) +{ +} + +RoomStruct::RoomStruct() +{ + InitDefaults(); +} + +RoomStruct::~RoomStruct() +{ + Free(); +} + +void RoomStruct::Free() +{ + for (size_t i = 0; i < (size_t)MAX_ROOM_BGFRAMES; ++i) + BgFrames[i].Graphic.reset(); + HotspotMask.reset(); + RegionMask.reset(); + WalkAreaMask.reset(); + WalkBehindMask.reset(); + + LocalVariables.clear(); + Interaction.reset(); + Properties.clear(); + for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) + { + Hotspots[i].Interaction.reset(); + Hotspots[i].Properties.clear(); + } + for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) + { + Objects[i].Interaction.reset(); + Objects[i].Properties.clear(); + } + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + { + Regions[i].Interaction.reset(); + Regions[i].Properties.clear(); + } + + FreeMessages(); + FreeScripts(); +} + +void RoomStruct::FreeMessages() +{ + for (size_t i = 0; i < MessageCount; ++i) + { + Messages[i].Free(); + MessageInfos[i] = MessageInfo(); + } + MessageCount = 0; +} + +void RoomStruct::FreeScripts() +{ + CompiledScript.reset(); + + EventHandlers.reset(); + for (size_t i = 0; i < HotspotCount; ++i) + Hotspots[i].EventHandlers.reset(); + for (size_t i = 0; i < ObjectCount; ++i) + Objects[i].EventHandlers.reset(); + for (size_t i = 0; i < RegionCount; ++i) + Regions[i].EventHandlers.reset(); +} + +void RoomStruct::InitDefaults() +{ + DataVersion = kRoomVersion_Current; + GameID = NO_GAME_ID_IN_ROOM_FILE; + + _resolution = kRoomRealRes; + MaskResolution = 1; + Width = 320; + Height = 200; + + Options = RoomOptions(); + Edges = RoomEdges(0, 317, 40, 199); + + BgFrameCount = 1; + HotspotCount = 0; + ObjectCount = 0; + RegionCount = 0; + WalkAreaCount = 0; + WalkBehindCount = 0; + MessageCount = 0; + + for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) + { + Hotspots[i] = RoomHotspot(); + if (i == 0) + Hotspots[i].Name = "No hotspot"; + else + Hotspots[i].Name.Format("Hotspot %u", i); + } + for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) + Objects[i] = RoomObjectInfo(); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + Regions[i] = RoomRegion(); + for (size_t i = 0; i <= (size_t)MAX_WALK_AREAS; ++i) + WalkAreas[i] = WalkArea(); + for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i) + WalkBehinds[i] = WalkBehind(); + + BackgroundBPP = 1; + BgAnimSpeed = 5; + + memset(Palette, 0, sizeof(Palette)); +} + +void RoomStruct::SetResolution(RoomResolutionType type) +{ + _resolution = type; +} + +Bitmap *RoomStruct::GetMask(RoomAreaMask mask) const +{ + switch (mask) + { + case kRoomAreaHotspot: return HotspotMask.get(); + case kRoomAreaWalkBehind: return WalkBehindMask.get(); + case kRoomAreaWalkable: return WalkAreaMask.get(); + case kRoomAreaRegion: return RegionMask.get(); + } + return nullptr; +} + +float RoomStruct::GetMaskScale(RoomAreaMask mask) const +{ + switch (mask) + { + case kRoomAreaWalkBehind: return 1.f; // walk-behinds always 1:1 with room size + case kRoomAreaHotspot: + case kRoomAreaWalkable: + case kRoomAreaRegion: + return 1.f / MaskResolution; + } + return 0.f; +} + +bool RoomStruct::HasRegionLightLevel(int id) const +{ + if (id >= 0 && id < MAX_ROOM_REGIONS) + return Regions[id].Tint == 0; + return false; +} + +bool RoomStruct::HasRegionTint(int id) const +{ + if (id >= 0 && id < MAX_ROOM_REGIONS) + return Regions[id].Tint != 0; + return false; +} + +int RoomStruct::GetRegionLightLevel(int id) const +{ + if (id >= 0 && id < MAX_ROOM_REGIONS) + return HasRegionLightLevel(id) ? Regions[id].Light : 0; + return 0; +} + +int RoomStruct::GetRegionTintLuminance(int id) const +{ + if (id >= 0 && id < MAX_ROOM_REGIONS) + return HasRegionTint(id) ? (Regions[id].Light * 10) / 25 : 0; + return 0; +} + +void load_room(const char *filename, RoomStruct *room, bool game_is_hires, const std::vector &sprinfos) +{ + room->Free(); + room->InitDefaults(); + + update_polled_stuff_if_runtime(); + + RoomDataSource src; + HRoomFileError err = OpenRoomFile(filename, src); + if (err) + { + update_polled_stuff_if_runtime(); // it can take a while to load the file sometimes + err = ReadRoomData(room, src.InputStream.get(), src.DataVersion); + if (err) + err = UpdateRoomData(room, src.DataVersion, game_is_hires, sprinfos); + } + if (!err) + quitprintf("Unable to load the room file '%s'.\n%s.", filename, err->FullMessage().GetCStr()); +} + +PBitmap FixBitmap(PBitmap bmp, int width, int height) +{ + Bitmap *new_bmp = BitmapHelper::AdjustBitmapSize(bmp.get(), width, height); + if (new_bmp != bmp.get()) + return PBitmap(new_bmp); + return bmp; +} + +void UpscaleRoomBackground(RoomStruct *room, bool game_is_hires) +{ + if (room->DataVersion >= kRoomVersion_303b || !game_is_hires) + return; + for (size_t i = 0; i < room->BgFrameCount; ++i) + room->BgFrames[i].Graphic = FixBitmap(room->BgFrames[i].Graphic, room->Width, room->Height); + FixRoomMasks(room); +} + +void FixRoomMasks(RoomStruct *room) +{ + if (room->MaskResolution <= 0) + return; + Bitmap *bkg = room->BgFrames[0].Graphic.get(); + if (bkg == nullptr) + return; + // TODO: this issue is somewhat complicated. Original code was relying on + // room->Width and Height properties. But in the engine these are saved + // already converted to data resolution which may be "low-res". Since this + // function is shared between engine and editor we do not know if we need + // to upscale them. + // For now room width/height is always equal to background bitmap. + int base_width = bkg->GetWidth(); + int base_height = bkg->GetHeight(); + int low_width = base_width / room->MaskResolution; + int low_height = base_height / room->MaskResolution; + + // Walk-behinds are always 1:1 of the primary background. + // Other masks are 1:x where X is MaskResolution. + room->WalkBehindMask = FixBitmap(room->WalkBehindMask, base_width, base_height); + room->HotspotMask = FixBitmap(room->HotspotMask, low_width, low_height); + room->RegionMask = FixBitmap(room->RegionMask, low_width, low_height); + room->WalkAreaMask = FixBitmap(room->WalkAreaMask, low_width, low_height); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h new file mode 100644 index 000000000000..95e2f151d151 --- /dev/null +++ b/engines/ags/shared/game/roomstruct.h @@ -0,0 +1,386 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// RoomStruct, a class describing initial room data. +// +// Because of the imperfect implementation there is inconsistency in how +// this data is interpreted at the runtime. +// Some of that data is never supposed to be changed at runtime. Another +// may be changed, but these changes are lost as soon as room is unloaded. +// The changes that must remain in memory are kept as separate classes: +// see RoomStatus, RoomObject etc. +// +// Partially this is because same class was used for both engine and editor, +// while runtime code was not available for the editor. +// +// This is also the reason why some classes here are named with the "Info" +// postfix. For example, RoomObjectInfo is the initial object data, and +// there is also RoomObject runtime-only class for mutable data. +// +// [ivan-mogilko] In my opinion, eventually there should be only one room class +// and one class per room entity, regardless of whether code is shared with +// the editor or not. But that would require extensive refactor/rewrite of +// the engine code, and savegame read/write code. +// +//============================================================================= +#ifndef __AGS_CN_GAME__ROOMINFO_H +#define __AGS_CN_GAME__ROOMINFO_H + +#include +#include "ac/common_defines.h" +#include "game/interactions.h" +#include "util/geometry.h" +#include "util/wgt2allg.h" // color (allegro RGB) + +struct ccScript; +struct SpriteInfo; +typedef std::shared_ptr PScript; + +// TODO: move the following enums under AGS::Common namespace +// later, when more engine source is put in AGS namespace and +// refactored. + +// Room's area mask type +enum RoomAreaMask +{ + kRoomAreaNone = 0, + kRoomAreaHotspot, + kRoomAreaWalkBehind, + kRoomAreaWalkable, + kRoomAreaRegion +}; + +// Room's audio volume modifier +enum RoomVolumeMod +{ + kRoomVolumeQuietest = -3, + kRoomVolumeQuieter = -2, + kRoomVolumeQuiet = -1, + kRoomVolumeNormal = 0, + kRoomVolumeLoud = 1, + kRoomVolumeLouder = 2, + kRoomVolumeLoudest = 3, + // These two options are only settable at runtime by SetMusicVolume() + kRoomVolumeExtra1 = 4, + kRoomVolumeExtra2 = 5, + + kRoomVolumeMin = kRoomVolumeQuietest, + kRoomVolumeMax = kRoomVolumeExtra2, +}; + +// Flag tells that walkable area does not have continious zoom +#define NOT_VECTOR_SCALED -10000 +// Flags tells that room is not linked to particular game ID +#define NO_GAME_ID_IN_ROOM_FILE 16325 + +#define MAX_ROOM_BGFRAMES 5 // max number of frames in animating bg scene + +#define MAX_ROOM_HOTSPOTS 50 // v2.62 increased from 20 to 30; v2.8 to 50 +#define MAX_ROOM_OBJECTS 40 +#define MAX_ROOM_REGIONS 16 +// TODO: this is remains of the older code, MAX_WALK_AREAS = real number - 1, where +// -1 is for the solid wall. When fixing this you need to be careful, because some +// walk-area indexes are 0-based and some 1-based (and some arrays have MAX_WALK_AREAS + 1 size) +#define MAX_WALK_AREAS 15 +#define MAX_WALK_BEHINDS 16 + +#define MAX_MESSAGES 100 + + +namespace AGS +{ +namespace Common +{ + +class Bitmap; +class Stream; + +typedef std::shared_ptr PBitmap; + +// Various room options +struct RoomOptions +{ + // Index of the startup music in the room + int StartupMusic; + // If saving and loading game is disabled in the room + bool SaveLoadDisabled; + // If player character is turned off in the room + bool PlayerCharOff; + // Apply player character's normal view when entering this room + int PlayerView; + // Room's music volume modifier + RoomVolumeMod MusicVolume; + + RoomOptions(); +}; + +// Single room background frame +struct RoomBgFrame +{ + PBitmap Graphic; + // Palette is only valid in 8-bit games + color Palette[256]; + // Tells if this frame should keep previous frame palette instead of using its own + bool IsPaletteShared; + + RoomBgFrame(); +}; + +// Describes room edges (coordinates of four edges) +struct RoomEdges +{ + int32_t Left; + int32_t Right; + int32_t Top; + int32_t Bottom; + + RoomEdges(); + RoomEdges(int l, int r, int t, int b); +}; + +// Room hotspot description +struct RoomHotspot +{ + String Name; + String ScriptName; + // Custom properties + StringIMap Properties; + // Old-style interactions + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + + // Player will automatically walk here when interacting with hotspot + Point WalkTo; +}; + +// Room object description +struct RoomObjectInfo +{ + int32_t Room; + int32_t X; + int32_t Y; + int32_t Sprite; + bool IsOn; + // Object's z-order in the room, or -1 (use Y) + int32_t Baseline; + int32_t Flags; + String Name; + String ScriptName; + // Custom properties + StringIMap Properties; + // Old-style interactions + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + + RoomObjectInfo(); +}; + +// Room region description +struct RoomRegion +{ + // Light level (-100 -> +100) or Tint luminance (0 - 255) + int32_t Light; + // Tint setting (R-B-G-S) + int32_t Tint; + // Custom properties + StringIMap Properties; + // Old-style interactions + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + + RoomRegion(); +}; + +// Walkable area description +struct WalkArea +{ + // Apply player character's normal view on this area + int32_t CharacterView; + // Character's scaling (-100 -> +100 %) + // General scaling, or scaling at the farthest point + int32_t ScalingFar; + // Scaling at the nearest point, or NOT_VECTOR_SCALED for uniform scaling + int32_t ScalingNear; + // Light level (-100 -> +100) + int32_t Light; + // Top and bottom Y of the area + int32_t Top; + int32_t Bottom; + + WalkArea(); +}; + +// Walk-behind description +struct WalkBehind +{ + // Object's z-order in the room + int32_t Baseline; + + WalkBehind(); +}; + +// Room messages + +#define MSG_DISPLAYNEXT 0x01 // supercedes using alt-200 at end of message +#define MSG_TIMELIMIT 0x02 + +struct MessageInfo +{ + char DisplayAs; // 0 - std display window, >=1 - as character's speech + char Flags; // combination of MSG_xxx flags + + MessageInfo(); +}; + + +// Room's legacy resolution type +enum RoomResolutionType +{ + kRoomRealRes = 0, // room should always be treated as-is + kRoomLoRes = 1, // created for low-resolution game + kRoomHiRes = 2 // created for high-resolution game +}; + + +// +// Description of a single room. +// This class contains initial room data. Some of it may still be modified +// at the runtime, but then these changes get lost as soon as room is unloaded. +// +class RoomStruct +{ +public: + RoomStruct(); + ~RoomStruct(); + + // Gets if room should adjust its base size depending on game's resolution + inline bool IsRelativeRes() const { return _resolution != kRoomRealRes; } + // Gets if room belongs to high resolution + inline bool IsLegacyHiRes() const { return _resolution == kRoomHiRes; } + // Gets legacy resolution type + inline RoomResolutionType GetResolutionType() const { return _resolution; } + + // Releases room resources + void Free(); + // Release room messages and scripts correspondingly. These two functions are needed + // at very specific occasion when only part of the room resources has to be freed. + void FreeMessages(); + void FreeScripts(); + // Init default room state + void InitDefaults(); + // Set legacy resolution type + void SetResolution(RoomResolutionType type); + + // Gets bitmap of particular mask layer + Bitmap *GetMask(RoomAreaMask mask) const; + // Gets mask's scale relative to the room's background size + float GetMaskScale(RoomAreaMask mask) const; + + // TODO: see later whether it may be more convenient to move these to the Region class instead. + // Gets if the given region has light level set + bool HasRegionLightLevel(int id) const; + // Gets if the given region has a tint set + bool HasRegionTint(int id) const; + // Gets region's light level in -100 to 100 range value; returns 0 (default level) if region's tint is set + int GetRegionLightLevel(int id) const; + // Gets region's tint luminance in 0 to 100 range value; returns 0 if region's light level is set + int GetRegionTintLuminance(int id) const; + +// TODO: all members are currently public because they are used everywhere; hide them later +public: + // Game's unique ID, corresponds to GameSetupStructBase::uniqueid. + // If this field has a valid value and does not match actual game's id, + // then engine will refuse to start this room. + // May be set to NO_GAME_ID_IN_ROOM_FILE to let it run within any game. + int32_t GameID; + // Loaded room file's data version. This value may be used to know when + // the room must have behavior specific to certain version of AGS. + int32_t DataVersion; + + // Room region masks resolution. Defines the relation between room and mask units. + // Mask point is calculated as roompt / MaskResolution. Must be >= 1. + int32_t MaskResolution; + // Size of the room, in logical coordinates (= pixels) + int32_t Width; + int32_t Height; + // Primary room palette (8-bit games) + color Palette[256]; + + // Basic room options + RoomOptions Options; + + // Background frames + int32_t BackgroundBPP; // bytes per pixel + size_t BgFrameCount; + RoomBgFrame BgFrames[MAX_ROOM_BGFRAMES]; + // Speed at which background frames are changing, 0 - no auto animation + int32_t BgAnimSpeed; + // Edges + RoomEdges Edges; + // Region masks + PBitmap HotspotMask; + PBitmap RegionMask; + PBitmap WalkAreaMask; + PBitmap WalkBehindMask; + // Room entities + size_t HotspotCount; + RoomHotspot Hotspots[MAX_ROOM_HOTSPOTS]; + size_t ObjectCount; + RoomObjectInfo Objects[MAX_ROOM_OBJECTS]; + size_t RegionCount; + RoomRegion Regions[MAX_ROOM_REGIONS]; + size_t WalkAreaCount; + WalkArea WalkAreas[MAX_WALK_AREAS + 1]; + size_t WalkBehindCount; + WalkBehind WalkBehinds[MAX_WALK_BEHINDS]; + + // Old numbered room messages (used with DisplayMessage, etc) + size_t MessageCount; + String Messages[MAX_MESSAGES]; + MessageInfo MessageInfos[MAX_MESSAGES]; + + // Custom properties + StringIMap Properties; + // Old-style interactions + InterVarVector LocalVariables; + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + // Compiled room script + PScript CompiledScript; + +private: + // Room's legacy resolution type, defines relation room and game's resolution + RoomResolutionType _resolution; +}; + + +// Loads new room data into the given RoomStruct object +void load_room(const char *filename, RoomStruct *room, bool game_is_hires, const std::vector &sprinfos); +// Checks if it's necessary and upscales low-res room backgrounds and masks for the high resolution game +// NOTE: it does not upscale object coordinates, because that is usually done when the room is loaded +void UpscaleRoomBackground(RoomStruct *room, bool game_is_hires); +// Ensures that all existing room masks match room background size and +// MaskResolution property, resizes mask bitmaps if necessary. +void FixRoomMasks(RoomStruct *room); +// Adjusts bitmap size if necessary and returns either new or old bitmap. +PBitmap FixBitmap(PBitmap bmp, int dst_width, int dst_height); + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GAME__ROOMINFO_H diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp new file mode 100644 index 000000000000..f5ac74787dba --- /dev/null +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -0,0 +1,502 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "gfx/allegrobitmap.h" +#include "debug/assert.h" + +extern void __my_setcolor(int *ctset, int newcol, int wantColDep); + +namespace AGS +{ +namespace Common +{ + +Bitmap::Bitmap() + : _alBitmap(nullptr) + , _isDataOwner(false) +{ +} + +Bitmap::Bitmap(int width, int height, int color_depth) + : _alBitmap(nullptr) + , _isDataOwner(false) +{ + Create(width, height, color_depth); +} + +Bitmap::Bitmap(Bitmap *src, const Rect &rc) + : _alBitmap(nullptr) + , _isDataOwner(false) +{ + CreateSubBitmap(src, rc); +} + +Bitmap::Bitmap(BITMAP *al_bmp, bool shared_data) + : _alBitmap(nullptr) + , _isDataOwner(false) +{ + WrapAllegroBitmap(al_bmp, shared_data); +} + +Bitmap::~Bitmap() +{ + Destroy(); +} + +//============================================================================= +// Creation and destruction +//============================================================================= + +bool Bitmap::Create(int width, int height, int color_depth) +{ + Destroy(); + if (color_depth) + { + _alBitmap = create_bitmap_ex(color_depth, width, height); + } + else + { + _alBitmap = create_bitmap(width, height); + } + _isDataOwner = true; + return _alBitmap != nullptr; +} + +bool Bitmap::CreateTransparent(int width, int height, int color_depth) +{ + if (Create(width, height, color_depth)) + { + clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); + return true; + } + return false; +} + +bool Bitmap::CreateSubBitmap(Bitmap *src, const Rect &rc) +{ + Destroy(); + _alBitmap = create_sub_bitmap(src->_alBitmap, rc.Left, rc.Top, rc.GetWidth(), rc.GetHeight()); + _isDataOwner = true; + return _alBitmap != nullptr; +} + +bool Bitmap::CreateCopy(Bitmap *src, int color_depth) +{ + if (Create(src->_alBitmap->w, src->_alBitmap->h, color_depth ? color_depth : bitmap_color_depth(src->_alBitmap))) + { + blit(src->_alBitmap, _alBitmap, 0, 0, 0, 0, _alBitmap->w, _alBitmap->h); + return true; + } + return false; +} + +bool Bitmap::WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data) +{ + Destroy(); + _alBitmap = al_bmp; + _isDataOwner = !shared_data; + return _alBitmap != nullptr; +} + +void Bitmap::Destroy() +{ + if (_isDataOwner && _alBitmap) + { + destroy_bitmap(_alBitmap); + } + _alBitmap = nullptr; + _isDataOwner = false; +} + +bool Bitmap::LoadFromFile(const char *filename) +{ + Destroy(); + + BITMAP *al_bmp = load_bitmap(filename, nullptr); + if (al_bmp) + { + _alBitmap = al_bmp; + _isDataOwner = true; + } + return _alBitmap != nullptr; +} + +bool Bitmap::SaveToFile(const char *filename, const void *palette) +{ + return save_bitmap(filename, _alBitmap, (const RGB*)palette) == 0; +} + +void Bitmap::SetMaskColor(color_t color) +{ + // not supported? CHECKME +} + +void Bitmap::Acquire() +{ + acquire_bitmap(_alBitmap); +} + +void Bitmap::Release() +{ + release_bitmap(_alBitmap); +} + +color_t Bitmap::GetCompatibleColor(color_t color) +{ + color_t compat_color = 0; + __my_setcolor(&compat_color, color, bitmap_color_depth(_alBitmap)); + return compat_color; +} + +//============================================================================= +// Clipping +//============================================================================= + +void Bitmap::SetClip(const Rect &rc) +{ + set_clip_rect(_alBitmap, rc.Left, rc.Top, rc.Right, rc.Bottom); +} + +Rect Bitmap::GetClip() const +{ + Rect temp; + get_clip_rect(_alBitmap, &temp.Left, &temp.Top, &temp.Right, &temp.Bottom); + return temp; +} + +//============================================================================= +// Blitting operations (drawing one bitmap over another) +//============================================================================= + +void Bitmap::Blit(Bitmap *src, int dst_x, int dst_y, BitmapMaskOption mask) +{ + BITMAP *al_src_bmp = src->_alBitmap; + // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite + if (mask == kBitmap_Transparency) + { + draw_sprite(_alBitmap, al_src_bmp, dst_x, dst_y); + } + else + { + blit(al_src_bmp, _alBitmap, 0, 0, dst_x, dst_y, al_src_bmp->w, al_src_bmp->h); + } +} + +void Bitmap::Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask) +{ + BITMAP *al_src_bmp = src->_alBitmap; + if (mask == kBitmap_Transparency) + { + masked_blit(al_src_bmp, _alBitmap, src_x, src_y, dst_x, dst_y, width, height); + } + else + { + blit(al_src_bmp, _alBitmap, src_x, src_y, dst_x, dst_y, width, height); + } +} + +void Bitmap::MaskedBlit(Bitmap *src, int dst_x, int dst_y) +{ + draw_sprite(_alBitmap, src->_alBitmap, dst_x, dst_y); +} + +void Bitmap::StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask) +{ + BITMAP *al_src_bmp = src->_alBitmap; + // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite + if (mask == kBitmap_Transparency) + { + stretch_sprite(_alBitmap, al_src_bmp, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } + else + { + stretch_blit(al_src_bmp, _alBitmap, + 0, 0, al_src_bmp->w, al_src_bmp->h, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } +} + +void Bitmap::StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask) +{ + BITMAP *al_src_bmp = src->_alBitmap; + if (mask == kBitmap_Transparency) + { + masked_stretch_blit(al_src_bmp, _alBitmap, + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } + else + { + stretch_blit(al_src_bmp, _alBitmap, + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } +} + +void Bitmap::AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask) +{ + BITMAP *al_src_bmp = src->_alBitmap; + // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite + if (mask == kBitmap_Transparency) + { + aa_stretch_sprite(_alBitmap, al_src_bmp, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } + else + { + aa_stretch_blit(al_src_bmp, _alBitmap, + 0, 0, al_src_bmp->w, al_src_bmp->h, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } +} + +void Bitmap::AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask) +{ + BITMAP *al_src_bmp = src->_alBitmap; + if (mask == kBitmap_Transparency) + { + // TODO: aastr lib does not expose method for masked stretch blit; should do that at some point since + // the source code is a gift-ware anyway + // aa_masked_blit(_alBitmap, al_src_bmp, src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + throw "aa_masked_blit is not yet supported!"; + } + else + { + aa_stretch_blit(al_src_bmp, _alBitmap, + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } +} + +void Bitmap::TransBlendBlt(Bitmap *src, int dst_x, int dst_y) +{ + BITMAP *al_src_bmp = src->_alBitmap; + draw_trans_sprite(_alBitmap, al_src_bmp, dst_x, dst_y); +} + +void Bitmap::LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount) +{ + BITMAP *al_src_bmp = src->_alBitmap; + draw_lit_sprite(_alBitmap, al_src_bmp, dst_x, dst_y, light_amount); +} + +void Bitmap::FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip) +{ + BITMAP *al_src_bmp = src->_alBitmap; + if (flip == kBitmap_HFlip) + { + draw_sprite_h_flip(_alBitmap, al_src_bmp, dst_x, dst_y); + } + else if (flip == kBitmap_VFlip) + { + draw_sprite_v_flip(_alBitmap, al_src_bmp, dst_x, dst_y); + } + else if (flip == kBitmap_HVFlip) + { + draw_sprite_vh_flip(_alBitmap, al_src_bmp, dst_x, dst_y); + } +} + +void Bitmap::RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle) +{ + BITMAP *al_src_bmp = src->_alBitmap; + rotate_sprite(_alBitmap, al_src_bmp, dst_x, dst_y, angle); +} + +void Bitmap::RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle) +{ + BITMAP *al_src_bmp = src->_alBitmap; + pivot_sprite(_alBitmap, al_src_bmp, dst_x, dst_y, pivot_x, pivot_y, angle); +} + +//============================================================================= +// Pixel operations +//============================================================================= + +void Bitmap::Clear(color_t color) +{ + if (color) + { + clear_to_color(_alBitmap, color); + } + else + { + clear_bitmap(_alBitmap); + } +} + +void Bitmap::ClearTransparent() +{ + clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); +} + +void Bitmap::PutPixel(int x, int y, color_t color) +{ + if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h) + { + return; + } + + switch (bitmap_color_depth(_alBitmap)) + { + case 8: + return _putpixel(_alBitmap, x, y, color); + case 15: + return _putpixel15(_alBitmap, x, y, color); + case 16: + return _putpixel16(_alBitmap, x, y, color); + case 24: + return _putpixel24(_alBitmap, x, y, color); + case 32: + return _putpixel32(_alBitmap, x, y, color); + } + assert(0); // this should not normally happen + return putpixel(_alBitmap, x, y, color); +} + +int Bitmap::GetPixel(int x, int y) const +{ + if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h) + { + return -1; // Allegros getpixel() implementation returns -1 in this case + } + + switch (bitmap_color_depth(_alBitmap)) + { + case 8: + return _getpixel(_alBitmap, x, y); + case 15: + return _getpixel15(_alBitmap, x, y); + case 16: + return _getpixel16(_alBitmap, x, y); + case 24: + return _getpixel24(_alBitmap, x, y); + case 32: + return _getpixel32(_alBitmap, x, y); + } + assert(0); // this should not normally happen + return getpixel(_alBitmap, x, y); +} + +//============================================================================= +// Vector drawing operations +//============================================================================= + +void Bitmap::DrawLine(const Line &ln, color_t color) +{ + line(_alBitmap, ln.X1, ln.Y1, ln.X2, ln.Y2, color); +} + +void Bitmap::DrawTriangle(const Triangle &tr, color_t color) +{ + triangle(_alBitmap, + tr.X1, tr.Y1, tr.X2, tr.Y2, tr.X3, tr.Y3, color); +} + +void Bitmap::DrawRect(const Rect &rc, color_t color) +{ + rect(_alBitmap, rc.Left, rc.Top, rc.Right, rc.Bottom, color); +} + +void Bitmap::FillRect(const Rect &rc, color_t color) +{ + rectfill(_alBitmap, rc.Left, rc.Top, rc.Right, rc.Bottom, color); +} + +void Bitmap::FillCircle(const Circle &circle, color_t color) +{ + circlefill(_alBitmap, circle.X, circle.Y, circle.Radius, color); +} + +void Bitmap::Fill(color_t color) +{ + if (color) + { + clear_to_color(_alBitmap, color); + } + else + { + clear_bitmap(_alBitmap); + } +} + +void Bitmap::FillTransparent() +{ + clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); +} + +void Bitmap::FloodFill(int x, int y, color_t color) +{ + floodfill(_alBitmap, x, y, color); +} + +//============================================================================= +// Direct access operations +//============================================================================= + +void Bitmap::SetScanLine(int index, unsigned char *data, int data_size) +{ + if (index < 0 || index >= GetHeight()) + { + return; + } + + int copy_length = data_size; + if (copy_length < 0) + { + copy_length = GetLineLength(); + } + else // TODO: use Math namespace here + if (copy_length > GetLineLength()) + { + copy_length = GetLineLength(); + } + + memcpy(_alBitmap->line[index], data, copy_length); +} + + + +namespace BitmapHelper +{ + +Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp) +{ + Bitmap *bitmap = new Bitmap(); + if (!bitmap->WrapAllegroBitmap(al_bmp, false)) + { + delete bitmap; + bitmap = nullptr; + } + return bitmap; +} + +Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp) +{ + Bitmap *bitmap = new Bitmap(); + if (!bitmap->WrapAllegroBitmap(al_bmp, true)) + { + delete bitmap; + bitmap = nullptr; + } + return bitmap; +} + +} // namespace BitmapHelper + + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h new file mode 100644 index 000000000000..66adc149f4c7 --- /dev/null +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -0,0 +1,249 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Allegro lib based bitmap +// +// TODO: probably should be moved to the Engine; check again when (if) it is +// clear that AGS.Native does not need allegro for drawing. +// +//============================================================================= +#ifndef __AGS_CN_GFX__ALLEGROBITMAP_H +#define __AGS_CN_GFX__ALLEGROBITMAP_H + +#include +#include "core/types.h" +#include "gfx/bitmap.h" + +namespace AGS +{ +namespace Common +{ + +class Bitmap +{ +public: + Bitmap(); + Bitmap(int width, int height, int color_depth = 0); + Bitmap(Bitmap *src, const Rect &rc); + Bitmap(BITMAP *al_bmp, bool shared_data); + ~Bitmap(); + + // Allocate new bitmap + // CHECKME: color_depth = 0 is used to call Allegro's create_bitmap, which uses + // some global color depth setting; not sure if this is OK to use for generic class, + // revise this in future + bool Create(int width, int height, int color_depth = 0); + bool CreateTransparent(int width, int height, int color_depth = 0); + // Allow this object to share existing bitmap data + bool CreateSubBitmap(Bitmap *src, const Rect &rc); + // Create a copy of given bitmap + bool CreateCopy(Bitmap *src, int color_depth = 0); + // TODO: a temporary solution for plugin support + bool WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data); + // Deallocate bitmap + void Destroy(); + + bool LoadFromFile(const char *filename); + bool SaveToFile(const char *filename, const void *palette); + + // TODO: This is temporary solution for cases when we cannot replace + // use of raw BITMAP struct with Bitmap + inline BITMAP *GetAllegroBitmap() + { + return _alBitmap; + } + + // Is this a "normal" bitmap created by application which data can be directly accessed for reading and writing + inline bool IsMemoryBitmap() const + { + return is_memory_bitmap(_alBitmap) != 0; + } + // Is this a video bitmap + inline bool IsVideoBitmap() const + { + return is_video_bitmap(_alBitmap) != 0; + } + // Is this a linear bitmap, the one that can be accessed linearly within each scanline + inline bool IsLinearBitmap() const + { + return is_linear_bitmap(_alBitmap) != 0; + } + + // Checks if bitmap cannot be used + inline bool IsNull() const + { + return !_alBitmap; + } + // Checks if bitmap has zero size: either width or height (or both) is zero + inline bool IsEmpty() const + { + return GetWidth() == 0 || GetHeight() == 0; + } + inline int GetWidth() const + { + return _alBitmap->w; + } + inline int GetHeight() const + { + return _alBitmap->h; + } + inline Size GetSize() const + { + return Size(_alBitmap->w, _alBitmap->h); + } + inline int GetColorDepth() const + { + return bitmap_color_depth(_alBitmap); + } + // BPP: bytes per pixel + inline int GetBPP() const + { + return (GetColorDepth() + 7) / 8; + } + + // CHECKME: probably should not be exposed, see comment to GetData() + inline int GetDataSize() const + { + return GetWidth() * GetHeight() * GetBPP(); + } + // Gets scanline length in bytes (is the same for any scanline) + inline int GetLineLength() const + { + return GetWidth() * GetBPP(); + } + + // TODO: replace with byte * + // Gets a pointer to underlying graphic data + // FIXME: actually not a very good idea, since there's no 100% guarantee the scanline positions in memory are sequential + inline const unsigned char *GetData() const + { + return _alBitmap->line[0]; + } + + // Get scanline for direct reading + inline const unsigned char *GetScanLine(int index) const + { + return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; + } + + void SetMaskColor(color_t color); + inline color_t GetMaskColor() const + { + return bitmap_mask_color(_alBitmap); + } + + // FIXME: allegro manual states these should not be used externally; + // should hide or totally remove those later + void Acquire(); + void Release(); + + // Converts AGS color-index into RGB color according to the bitmap format. + // TODO: this method was added to the Bitmap class during large refactoring, + // but that's a mistake, because in retrospect is has nothing to do with + // bitmap itself and should rather be a part of the game data logic. + color_t GetCompatibleColor(color_t color); + + //========================================================================= + // Clipping + //========================================================================= + void SetClip(const Rect &rc); + Rect GetClip() const; + + //========================================================================= + // Blitting operations (drawing one bitmap over another) + //========================================================================= + // Draw other bitmap over current one + void Blit(Bitmap *src, int dst_x = 0, int dst_y = 0, BitmapMaskOption mask = kBitmap_Copy); + void Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask = kBitmap_Copy); + // Draw other bitmap in a masked mode (kBitmap_Transparency) + void MaskedBlit(Bitmap *src, int dst_x, int dst_y); + // Draw other bitmap, stretching or shrinking its size to given values + void StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + void StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + // Antia-aliased stretch-blit + void AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + void AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + // TODO: find more general way to call these operations, probably require pointer to Blending data struct? + // Draw bitmap using translucency preset + void TransBlendBlt(Bitmap *src, int dst_x, int dst_y); + // Draw bitmap using lighting preset + void LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount); + // TODO: generic "draw transformed" function? What about mask option? + void FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip); + void RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle); + void RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle); + + //========================================================================= + // Pixel operations + //========================================================================= + // Fills the whole bitmap with given color (black by default) + void Clear(color_t color = 0); + void ClearTransparent(); + // The PutPixel and GetPixel are supposed to be safe and therefore + // relatively slow operations. They should not be used for changing large + // blocks of bitmap memory - reading/writing from/to scan lines should be + // done in such cases. + void PutPixel(int x, int y, color_t color); + int GetPixel(int x, int y) const; + + //========================================================================= + // Vector drawing operations + //========================================================================= + void DrawLine(const Line &ln, color_t color); + void DrawTriangle(const Triangle &tr, color_t color); + void DrawRect(const Rect &rc, color_t color); + void FillRect(const Rect &rc, color_t color); + void FillCircle(const Circle &circle, color_t color); + // Fills the whole bitmap with given color + void Fill(color_t color); + void FillTransparent(); + // Floodfills an enclosed area, starting at point + void FloodFill(int x, int y, color_t color); + + //========================================================================= + // Direct access operations + //========================================================================= + // TODO: think how to increase safety over this (some fixed memory buffer class with iterator?) + // Gets scanline for directly writing into it + inline unsigned char *GetScanLineForWriting(int index) + { + return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; + } + inline unsigned char *GetDataForWriting() + { + return _alBitmap->line[0]; + } + // Copies buffer contents into scanline + void SetScanLine(int index, unsigned char *data, int data_size = -1); + +private: + BITMAP *_alBitmap; + bool _isDataOwner; +}; + + + +namespace BitmapHelper +{ + // TODO: revise those functions later (currently needed in a few very specific cases) + // NOTE: the resulting object __owns__ bitmap data from now on + Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp); + // NOTE: the resulting object __does not own__ bitmap data + Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp); +} // namespace BitmapHelper + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GFX__ALLEGROBITMAP_H diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp new file mode 100644 index 000000000000..c5dbcf843e72 --- /dev/null +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -0,0 +1,195 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "gfx/bitmap.h" +#include "util/memory.h" + +namespace AGS +{ +namespace Common +{ + +// TODO: revise this construction later +namespace BitmapHelper +{ + +Bitmap *CreateBitmap(int width, int height, int color_depth) +{ + Bitmap *bitmap = new Bitmap(); + if (!bitmap->Create(width, height, color_depth)) + { + delete bitmap; + bitmap = nullptr; + } + return bitmap; +} + +Bitmap *CreateTransparentBitmap(int width, int height, int color_depth) +{ + Bitmap *bitmap = new Bitmap(); + if (!bitmap->CreateTransparent(width, height, color_depth)) + { + delete bitmap; + bitmap = nullptr; + } + return bitmap; +} + +Bitmap *CreateSubBitmap(Bitmap *src, const Rect &rc) +{ + Bitmap *bitmap = new Bitmap(); + if (!bitmap->CreateSubBitmap(src, rc)) + { + delete bitmap; + bitmap = nullptr; + } + return bitmap; +} + +Bitmap *CreateBitmapCopy(Bitmap *src, int color_depth) +{ + Bitmap *bitmap = new Bitmap(); + if (!bitmap->CreateCopy(src, color_depth)) + { + delete bitmap; + bitmap = nullptr; + } + return bitmap; +} + +Bitmap *LoadFromFile(const char *filename) +{ + Bitmap *bitmap = new Bitmap(); + if (!bitmap->LoadFromFile(filename)) + { + delete bitmap; + bitmap = nullptr; + } + return bitmap; +} + +Bitmap *AdjustBitmapSize(Bitmap *src, int width, int height) +{ + int oldw = src->GetWidth(), oldh = src->GetHeight(); + if ((oldw == width) && (oldh == height)) + return src; + Bitmap *bmp = BitmapHelper::CreateBitmap(width, height, src->GetColorDepth()); + bmp->StretchBlt(src, RectWH(0, 0, oldw, oldh), RectWH(0, 0, width, height)); + return bmp; +} + +template +struct PixelTransCpy +{ + static const size_t BPP = BPP_; + inline void operator ()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const + { + if (*(TPx*)src == mask_color) + *(TPx*)dst = mask_color; + } +}; + +struct PixelNoSkip +{ + inline bool operator ()(uint8_t *data, color_t mask_color, bool use_alpha) const + { + return false; + } +}; + +typedef PixelTransCpy PixelTransCpy8; +typedef PixelTransCpy PixelTransCpy16; + +struct PixelTransCpy24 +{ + static const size_t BPP = 3; + inline void operator ()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const + { + const uint8_t *mcol_ptr = (const uint8_t*)&mask_color; + if (src[0] == mcol_ptr[0] && src[1] == mcol_ptr[1] && src[2] == mcol_ptr[2]) + { + dst[0] = mcol_ptr[0]; + dst[1] = mcol_ptr[1]; + dst[2] = mcol_ptr[2]; + } + } +}; + +struct PixelTransCpy32 +{ + static const size_t BPP = 4; + inline void operator ()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const + { + if (*(const uint32_t*)src == mask_color) + *(uint32_t*)dst = mask_color; + else if (use_alpha) + dst[3] = src[3]; // copy alpha channel + else + dst[3] = 0xFF; // set the alpha channel byte to opaque + } +}; + +struct PixelTransSkip32 +{ + inline bool operator ()(uint8_t *data, color_t mask_color, bool use_alpha) const + { + return *(uint32_t*)data == mask_color || (use_alpha && data[3] == 0); + } +}; + +template +void ApplyMask(uint8_t *dst, const uint8_t *src, size_t pitch, size_t height, FnPxProc proc, FnSkip skip, color_t mask_color, bool dst_has_alpha, bool mask_has_alpha) +{ + for (size_t y = 0; y < height; ++y) + { + for (size_t x = 0; x < pitch; x += FnPxProc::BPP, src += FnPxProc::BPP, dst += FnPxProc::BPP) + { + if (!skip(dst, mask_color, dst_has_alpha)) + proc(dst, src, mask_color, mask_has_alpha); + } + } +} + +void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bool mask_has_alpha) +{ + color_t mask_color = mask->GetMaskColor(); + uint8_t *dst_ptr = dst->GetDataForWriting(); + const uint8_t *src_ptr = mask->GetData(); + const size_t bpp = mask->GetBPP(); + const size_t pitch = mask->GetLineLength(); + const size_t height = mask->GetHeight(); + + if (bpp == 1) + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy8(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); + else if (bpp == 2) + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy16(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); + else if (bpp == 3) + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy24(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); + else + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy32(), PixelTransSkip32(), mask_color, dst_has_alpha, mask_has_alpha); +} + +void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t src_pitch, const size_t src_px_offset) +{ + const size_t bpp = dst->GetBPP(); + const size_t src_px_pitch = src_pitch / bpp; + if (src_px_offset >= src_px_pitch) + return; // nothing to copy + Memory::BlockCopy(dst->GetDataForWriting(), dst->GetLineLength(), 0, src_buffer, src_pitch, src_px_offset * bpp, dst->GetHeight()); +} + +} // namespace BitmapHelper + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gfx/bitmap.h b/engines/ags/shared/gfx/bitmap.h new file mode 100644 index 000000000000..12eaca7d4430 --- /dev/null +++ b/engines/ags/shared/gfx/bitmap.h @@ -0,0 +1,87 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Base bitmap header +// +//============================================================================= +#ifndef __AGS_CN_GFX__BITMAP_H +#define __AGS_CN_GFX__BITMAP_H + +#include "util/geometry.h" + +namespace AGS +{ +namespace Common +{ + +// Mask option for blitting one bitmap on another +enum BitmapMaskOption +{ + // Plain copies bitmap pixels + kBitmap_Copy, + // Consider mask color fully transparent and do not copy pixels having it + kBitmap_Transparency +}; + +enum BitmapFlip +{ + kBitmap_HFlip, + kBitmap_VFlip, + kBitmap_HVFlip +}; + +} // namespace Common +} // namespace AGS + + +// Declare the actual bitmap class +#include "gfx/allegrobitmap.h" + +namespace AGS +{ +namespace Common +{ + +class Bitmap; + +// TODO: revise this construction later +namespace BitmapHelper +{ + // Helper functions, that delete faulty bitmaps automatically, and return + // NULL if bitmap could not be created. + Bitmap *CreateBitmap(int width, int height, int color_depth = 0); + Bitmap *CreateTransparentBitmap(int width, int height, int color_depth = 0); + Bitmap *CreateSubBitmap(Bitmap *src, const Rect &rc); + Bitmap *CreateBitmapCopy(Bitmap *src, int color_depth = 0); + Bitmap *LoadFromFile(const char *filename); + + // Stretches bitmap to the requested size. The new bitmap will have same + // colour depth. Returns original bitmap if no changes are necessary. + Bitmap *AdjustBitmapSize(Bitmap *src, int width, int height); + // Copy transparency mask and/or alpha channel from one bitmap into another. + // Destination and mask bitmaps must be of the same pixel format. + // Transparency is merged, meaning that fully transparent pixels on + // destination should remain such regardless of mask pixel values. + void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bool mask_has_alpha); + // Copy pixel data into bitmap from memory buffer. It is required that the + // source matches bitmap format and has enough data. + // Pitch is given in bytes and defines the length of the source scan line. + // Offset is optional and defines horizontal offset, in pixels. + void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t src_pitch, const size_t src_px_offset = 0); +} // namespace BitmapHelper + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GFX__BITMAP_H diff --git a/engines/ags/shared/gfx/gfx_def.h b/engines/ags/shared/gfx/gfx_def.h new file mode 100644 index 000000000000..e883c1695e93 --- /dev/null +++ b/engines/ags/shared/gfx/gfx_def.h @@ -0,0 +1,117 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Graphic definitions and type/unit conversions. +// +//============================================================================= +#ifndef __AGS_CN_GFX__GFXDEF_H +#define __AGS_CN_GFX__GFXDEF_H + +namespace AGS +{ +namespace Common +{ + +enum BlendMode +{ + // free blending (ARGB -> ARGB) modes + kBlendMode_NoAlpha = 0, // ignore alpha channel + kBlendMode_Alpha, // alpha-blend src to dest, combining src & dest alphas + // NOTE: add new modes here + + kNumBlendModes +}; + +namespace GfxDef +{ + inline int Trans100ToAlpha255(int transparency) + { + return ((100 - transparency) * 255) / 100; + } + + inline int Alpha255ToTrans100(int alpha) + { + return 100 - ((alpha * 100) / 255); + } + + // Special formulae to reduce precision loss and support flawless forth & + // reverse conversion for multiplies of 10% + inline int Trans100ToAlpha250(int transparency) + { + return ((100 - transparency) * 25) / 10; + } + + inline int Alpha250ToTrans100(int alpha) + { + return 100 - ((alpha * 10) / 25); + } + + // Convert correct 100-ranged transparency into legacy 255-ranged + // transparency; legacy inconsistent transparency value range: + // 0 = opaque, + // 255 = invisible, + // 1 -to- 254 = barely visible -to- mostly visible (as proper alpha) + inline int Trans100ToLegacyTrans255(int transparency) + { + if (transparency == 0) + { + return 0; // this means opaque + } + else if (transparency == 100) + { + return 255; // this means invisible + } + // the rest of the range works as alpha + return Trans100ToAlpha250(transparency); + } + + // Convert legacy 255-ranged "incorrect" transparency into proper + // 100-ranged transparency. + inline int LegacyTrans255ToTrans100(int legacy_transparency) + { + if (legacy_transparency == 0) + { + return 0; // this means opaque + } + else if (legacy_transparency == 255) + { + return 100; // this means invisible + } + // the rest of the range works as alpha + return Alpha250ToTrans100(legacy_transparency); + } + + // Convert legacy 100-ranged transparency into proper 255-ranged alpha + // 0 => alpha 255 + // 100 => alpha 0 + // 1 - 99 => alpha 1 - 244 + inline int LegacyTrans100ToAlpha255(int legacy_transparency) + { + if (legacy_transparency == 0) + { + return 255; // this means opaque + } + else if (legacy_transparency == 100) + { + return 0; // this means invisible + } + // the rest of the range works as alpha (only 100-ranged) + return legacy_transparency * 255 / 100; + } +} // namespace GfxDef + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_GFX__GFXDEF_H diff --git a/engines/ags/shared/gui/guibutton.cpp b/engines/ags/shared/gui/guibutton.cpp new file mode 100644 index 000000000000..3ea836cdcb49 --- /dev/null +++ b/engines/ags/shared/gui/guibutton.cpp @@ -0,0 +1,384 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/spritecache.h" +#include "gui/guibutton.h" +#include "gui/guimain.h" // TODO: extract helper functions +#include "util/stream.h" +#include "util/string_utils.h" + +std::vector guibuts; +int numguibuts = 0; + +namespace AGS +{ +namespace Common +{ + +FrameAlignment ConvertLegacyButtonAlignment(LegacyButtonAlignment align) +{ + switch (align) + { + case kLegacyButtonAlign_TopCenter: + return kAlignTopCenter; + case kLegacyButtonAlign_TopLeft: + return kAlignTopLeft; + case kLegacyButtonAlign_TopRight: + return kAlignTopRight; + case kLegacyButtonAlign_CenterLeft: + return kAlignMiddleLeft; + case kLegacyButtonAlign_Centered: + return kAlignMiddleCenter; + case kLegacyButtonAlign_CenterRight: + return kAlignMiddleRight; + case kLegacyButtonAlign_BottomLeft: + return kAlignBottomLeft; + case kLegacyButtonAlign_BottomCenter: + return kAlignBottomCenter; + case kLegacyButtonAlign_BottomRight: + return kAlignBottomRight; + } + return kAlignNone; +} + + +GUIButton::GUIButton() +{ + Image = -1; + MouseOverImage = -1; + PushedImage = -1; + CurrentImage = -1; + Font = 0; + TextColor = 0; + TextAlignment = kAlignTopCenter; + ClickAction[kMouseLeft] = kGUIAction_RunScript; + ClickAction[kMouseRight] = kGUIAction_RunScript; + ClickData[kMouseLeft] = 0; + ClickData[kMouseRight] = 0; + + IsPushed = false; + IsMouseOver = false; + _placeholder = kButtonPlace_None; + _unnamed = false; + + _scEventCount = 1; + _scEventNames[0] = "Click"; + _scEventArgs[0] = "GUIControl *control, MouseButton button"; +} + +const String &GUIButton::GetText() const +{ + return _text; +} + +bool GUIButton::IsClippingImage() const +{ + return (Flags & kGUICtrl_Clip) != 0; +} + +void GUIButton::Draw(Bitmap *ds) +{ + bool draw_disabled = !IsGUIEnabled(this); + + check_font(&Font); + // if it's "Unchanged when disabled" or "GUI Off", don't grey out + if (gui_disabled_style == GUIDIS_UNCHANGED || + gui_disabled_style == GUIDIS_GUIOFF) + { + draw_disabled = false; + } + // TODO: should only change properties in reaction to particular events + if (CurrentImage <= 0 || draw_disabled) + CurrentImage = Image; + + if (draw_disabled && gui_disabled_style == GUIDIS_BLACKOUT) + // buttons off when disabled - no point carrying on + return; + + // CHECKME: why testing both CurrentImage and Image? + if (CurrentImage > 0 && Image > 0) + DrawImageButton(ds, draw_disabled); + // CHECKME: why don't draw frame if no Text? this will make button completely invisible! + else if (!_text.IsEmpty()) + DrawTextButton(ds, draw_disabled); +} + +void GUIButton::SetClipImage(bool on) +{ + if (on) + Flags |= kGUICtrl_Clip; + else + Flags &= ~kGUICtrl_Clip; +} + +void GUIButton::SetText(const String &text) +{ + _text = text; + // Active inventory item placeholders + if (_text.CompareNoCase("(INV)") == 0) + // Stretch to fit button + _placeholder = kButtonPlace_InvItemStretch; + else if (_text.CompareNoCase("(INVNS)") == 0) + // Draw at actual size + _placeholder = kButtonPlace_InvItemCenter; + else if (_text.CompareNoCase("(INVSHR)") == 0) + // Stretch if too big, actual size if not + _placeholder = kButtonPlace_InvItemAuto; + else + _placeholder = kButtonPlace_None; + + // TODO: find a way to remove this bogus limitation ("New Button" is a valid Text too) + _unnamed = _text.Compare("New Button") == 0; +} + +bool GUIButton::OnMouseDown() +{ + if (PushedImage > 0) + CurrentImage = PushedImage; + IsPushed = true; + return false; +} + +void GUIButton::OnMouseEnter() +{ + CurrentImage = IsPushed ? PushedImage : MouseOverImage; + IsMouseOver = true; +} + +void GUIButton::OnMouseLeave() +{ + CurrentImage = Image; + IsMouseOver = false; +} + +void GUIButton::OnMouseUp() +{ + if (IsMouseOver) + { + CurrentImage = MouseOverImage; + if (IsGUIEnabled(this) && IsClickable()) + IsActivated = true; + } + else + { + CurrentImage = Image; + } + + IsPushed = false; +} + +// TODO: replace string serialization with StrUtil::ReadString and WriteString +// methods in the future, to keep this organized. +void GUIButton::WriteToFile(Stream *out) const +{ + GUIObject::WriteToFile(out); + + out->WriteInt32(Image); + out->WriteInt32(MouseOverImage); + out->WriteInt32(PushedImage); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(ClickAction[kMouseLeft]); + out->WriteInt32(ClickAction[kMouseRight]); + out->WriteInt32(ClickData[kMouseLeft]); + out->WriteInt32(ClickData[kMouseRight]); + + StrUtil::WriteString(_text, out); + out->WriteInt32(TextAlignment); +} + +void GUIButton::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + GUIObject::ReadFromFile(in, gui_version); + + Image = in->ReadInt32(); + MouseOverImage = in->ReadInt32(); + PushedImage = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + { // NOTE: reading into actual variables only for old savegame support + CurrentImage = in->ReadInt32(); + IsPushed = in->ReadInt32() != 0; + IsMouseOver = in->ReadInt32() != 0; + } + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + ClickAction[kMouseLeft] = (GUIClickAction)in->ReadInt32(); + ClickAction[kMouseRight] = (GUIClickAction)in->ReadInt32(); + ClickData[kMouseLeft] = in->ReadInt32(); + ClickData[kMouseRight] = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + SetText(String::FromStreamCount(in, GUIBUTTON_LEGACY_TEXTLENGTH)); + else + SetText(StrUtil::ReadString(in)); + + if (gui_version >= kGuiVersion_272a) + { + if (gui_version < kGuiVersion_350) + { + TextAlignment = ConvertLegacyButtonAlignment((LegacyButtonAlignment)in->ReadInt32()); + in->ReadInt32(); // reserved1 + } + else + { + TextAlignment = (FrameAlignment)in->ReadInt32(); + } + } + else + { + TextAlignment = kAlignTopCenter; + } + + if (TextColor == 0) + TextColor = 16; + CurrentImage = Image; + // All buttons are translated at the moment + Flags |= kGUICtrl_Translated; +} + +void GUIButton::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) +{ + GUIObject::ReadFromSavegame(in, svg_ver); + // Properties + Image = in->ReadInt32(); + MouseOverImage = in->ReadInt32(); + PushedImage = in->ReadInt32(); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + SetText(StrUtil::ReadString(in)); + if (svg_ver >= kGuiSvgVersion_350) + TextAlignment = (FrameAlignment)in->ReadInt32(); + // Dynamic state + Image = in->ReadInt32(); +} + +void GUIButton::WriteToSavegame(Stream *out) const +{ + // Properties + GUIObject::WriteToSavegame(out); + out->WriteInt32(Image); + out->WriteInt32(MouseOverImage); + out->WriteInt32(PushedImage); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + StrUtil::WriteString(GetText(), out); + out->WriteInt32(TextAlignment); + // Dynamic state + out->WriteInt32(Image); +} + +void GUIButton::DrawImageButton(Bitmap *ds, bool draw_disabled) +{ + // NOTE: the CLIP flag only clips the image, not the text + if (IsClippingImage()) + ds->SetClip(Rect(X, Y, X + Width - 1, Y + Height - 1)); + if (spriteset[CurrentImage] != nullptr) + draw_gui_sprite(ds, CurrentImage, X, Y, true); + + // Draw active inventory item + if (_placeholder != kButtonPlace_None && gui_inv_pic >= 0) + { + GUIButtonPlaceholder place = _placeholder; + if (place == kButtonPlace_InvItemAuto) + { + if ((get_adjusted_spritewidth(gui_inv_pic) > Width - 6) || + (get_adjusted_spriteheight(gui_inv_pic) > Height - 6)) + { + place = kButtonPlace_InvItemStretch; + } + else + { + place = kButtonPlace_InvItemCenter; + } + } + + if (place == kButtonPlace_InvItemStretch) + { + ds->StretchBlt(spriteset[gui_inv_pic], RectWH(X + 3, Y + 3, Width - 6, Height - 6), Common::kBitmap_Transparency); + } + else if (place == kButtonPlace_InvItemCenter) + { + draw_gui_sprite(ds, gui_inv_pic, + X + Width / 2 - get_adjusted_spritewidth(gui_inv_pic) / 2, + Y + Height / 2 - get_adjusted_spriteheight(gui_inv_pic) / 2, + true); + } + } + + if ((draw_disabled) && (gui_disabled_style == GUIDIS_GREYOUT)) + { + // darken the button when disabled + GUI::DrawDisabledEffect(ds, RectWH(X, Y, + spriteset[CurrentImage]->GetWidth(), + spriteset[CurrentImage]->GetHeight())); + } + ds->SetClip(Rect(0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1)); + + // Don't print Text of (INV) (INVSHR) (INVNS) + if (_placeholder == kButtonPlace_None && !_unnamed) + DrawText(ds, draw_disabled); +} + +void GUIButton::DrawText(Bitmap *ds, bool draw_disabled) +{ + if (_text.IsEmpty()) + return; + // TODO: need to find a way to cache Text prior to drawing; + // but that will require to update all gui controls when translation is changed in game + PrepareTextToDraw(); + + Rect frame = RectWH(X + 2, Y + 2, Width - 4, Height - 4); + if (IsPushed && IsMouseOver) + { + // move the Text a bit while pushed + frame.Left++; + frame.Top++; + } + color_t text_color = ds->GetCompatibleColor(TextColor); + if (draw_disabled) + text_color = ds->GetCompatibleColor(8); + GUI::DrawTextAligned(ds, _textToDraw, Font, text_color, frame, TextAlignment); +} + +void GUIButton::DrawTextButton(Bitmap *ds, bool draw_disabled) +{ + color_t draw_color = ds->GetCompatibleColor(7); + ds->FillRect(Rect(X, Y, X + Width - 1, Y + Height - 1), draw_color); + if (Flags & kGUICtrl_Default) + { + draw_color = ds->GetCompatibleColor(16); + ds->DrawRect(Rect(X - 1, Y - 1, X + Width, Y + Height), draw_color); + } + + // TODO: use color constants instead of literal numbers + if (!draw_disabled && IsMouseOver && IsPushed) + draw_color = ds->GetCompatibleColor(15); + else + draw_color = ds->GetCompatibleColor(8); + + ds->DrawLine(Line(X, Y + Height - 1, X + Width - 1, Y + Height - 1), draw_color); + ds->DrawLine(Line(X + Width - 1, Y, X + Width - 1, Y + Height - 1), draw_color); + + if (draw_disabled || (IsMouseOver && IsPushed)) + draw_color = ds->GetCompatibleColor(8); + else + draw_color = ds->GetCompatibleColor(15); + + ds->DrawLine(Line(X, Y, X + Width - 1, Y), draw_color); + ds->DrawLine(Line(X, Y, X, Y + Height - 1), draw_color); + + DrawText(ds, draw_disabled); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h new file mode 100644 index 000000000000..1ff172b20318 --- /dev/null +++ b/engines/ags/shared/gui/guibutton.h @@ -0,0 +1,136 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUIBUTTON_H +#define __AC_GUIBUTTON_H + +#include +#include "gui/guiobject.h" +#include "util/string.h" + +#define GUIBUTTON_LEGACY_TEXTLENGTH 50 + +namespace AGS +{ +namespace Common +{ + +enum MouseButton +{ + kMouseNone = -1, + kMouseLeft = 0, + kMouseRight = 1, +}; + +enum GUIClickAction +{ + kGUIAction_None = 0, + kGUIAction_SetMode = 1, + kGUIAction_RunScript = 2, +}; + +enum LegacyButtonAlignment +{ + kLegacyButtonAlign_TopCenter = 0, + kLegacyButtonAlign_TopLeft = 1, + kLegacyButtonAlign_TopRight = 2, + kLegacyButtonAlign_CenterLeft = 3, + kLegacyButtonAlign_Centered = 4, + kLegacyButtonAlign_CenterRight = 5, + kLegacyButtonAlign_BottomLeft = 6, + kLegacyButtonAlign_BottomCenter = 7, + kLegacyButtonAlign_BottomRight = 8, +}; + +class GUIButton : public GUIObject +{ +public: + GUIButton(); + + const String &GetText() const; + bool IsClippingImage() const; + + // Operations + void Draw(Bitmap *ds) override; + void SetClipImage(bool on); + void SetText(const String &text); + + // Events + bool OnMouseDown() override; + void OnMouseEnter() override; + void OnMouseLeave() override; + void OnMouseUp() override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; + +// TODO: these members are currently public; hide them later +public: + int32_t Image; + int32_t MouseOverImage; + int32_t PushedImage; + int32_t CurrentImage; + int32_t Font; + color_t TextColor; + FrameAlignment TextAlignment; + // Click actions for left and right mouse buttons + // NOTE: only left click is currently in use + static const int ClickCount = kMouseRight + 1; + GUIClickAction ClickAction[ClickCount]; + int32_t ClickData[ClickCount]; + + bool IsPushed; + bool IsMouseOver; + +private: + void DrawImageButton(Bitmap *ds, bool draw_disabled); + void DrawText(Bitmap *ds, bool draw_disabled); + void DrawTextButton(Bitmap *ds, bool draw_disabled); + void PrepareTextToDraw(); + + // Defines button placeholder mode; the mode is set + // depending on special tags found in button text + enum GUIButtonPlaceholder + { + kButtonPlace_None, + kButtonPlace_InvItemStretch, + kButtonPlace_InvItemCenter, + kButtonPlace_InvItemAuto + }; + + // Text property set by user + String _text; + // type of content placeholder, if any + GUIButtonPlaceholder _placeholder; + // A flag indicating unnamed button; this is a convenience trick: + // buttons are created named "New Button" in the editor, and users + // often do not clear text when they want a graphic button. + bool _unnamed; + // Prepared text buffer/cache + String _textToDraw; +}; + +} // namespace Common +} // namespace AGS + +extern std::vector guibuts; +extern int numguibuts; + +int UpdateAnimatingButton(int bu); +void StopButtonAnimation(int idxn); + +#endif // __AC_GUIBUTTON_H diff --git a/engines/ags/shared/gui/guidefines.h b/engines/ags/shared/gui/guidefines.h new file mode 100644 index 000000000000..e57451d6991e --- /dev/null +++ b/engines/ags/shared/gui/guidefines.h @@ -0,0 +1,185 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUIDEFINES_H +#define __AC_GUIDEFINES_H + +#define GUIMAGIC 0xcafebeef +#define MAX_GUIOBJ_EVENTS 10 +#define TEXTWINDOW_PADDING_DEFAULT 3 +//#define MAX_OBJ_EACH_TYPE 251 + +// TODO: find out more about gui version history +//============================================================================= +// GUI Version history +//----------------------------------------------------------------------------- +// +// 2.1.4..... (100): Introduced Slider gui control. Gui count is now serialized +// in game file. +// 2.2.2..... (101): Introduced TextBox gui control. +// 2.3.0..... (102): Introduced ListBox gui control. +// 2.6.0..... (105): GUI custom Z-order support. +// 2.7.0..... (110): Added GUI OnClick handler. +// 2.7.2.???? (111): Added text alignment property to buttons. +// 2.7.2.???? (112): Added text alignment property to list boxes. +// 2.7.2.???? (113): Increased permitted length of GUI label text from 200 to +// 2048 characters. +// 2.7.2.???? (114): Obsoleted savegameindex[] array, and added +// ListBox.SaveGameSlots[] array instead. +// 2.7.2.???? (115): Added GUI Control z-order support. +// +// 3.3.0.1132 (116): Added kGUICtrl_Translated flag. +// 3.3.1.???? (117): Added padding variable for text window GUIs. +// 3.4.0 (118): Removed GUI limits +// 3.5.0 (119): Game data contains GUI properties that previously +// could be set only at runtime. +// +//============================================================================= + +enum GuiVersion +{ + // TODO: find out all corresponding engine version numbers + kGuiVersion_Initial = 0, + kGuiVersion_214 = 100, + kGuiVersion_222 = 101, + kGuiVersion_230 = 102, + kGuiVersion_unkn_103 = 103, + kGuiVersion_unkn_104 = 104, + kGuiVersion_260 = 105, + kGuiVersion_unkn_106 = 106, + kGuiVersion_unkn_107 = 107, + kGuiVersion_unkn_108 = 108, + kGuiVersion_unkn_109 = 109, + kGuiVersion_270 = 110, + kGuiVersion_272a = 111, + kGuiVersion_272b = 112, + kGuiVersion_272c = 113, + kGuiVersion_272d = 114, + kGuiVersion_272e = 115, + + kGuiVersion_330 = 116, + kGuiVersion_331 = 117, + kGuiVersion_340 = 118, + kGuiVersion_350 = 119, + kGuiVersion_Current = kGuiVersion_350, +}; + +namespace AGS +{ +namespace Common +{ + +// GUIMain's style and behavior flags +enum GUIMainFlags +{ + kGUIMain_Clickable = 0x0001, + kGUIMain_TextWindow = 0x0002, + kGUIMain_Visible = 0x0004, + kGUIMain_Concealed = 0x0008, + + // NOTE: currently default state is Visible to keep this backwards compatible; + // check later if this is still a wanted behavior + kGUIMain_DefFlags = kGUIMain_Clickable | kGUIMain_Visible, + // flags that had inverse meaning in old formats + kGUIMain_OldFmtXorMask = kGUIMain_Clickable +}; + +// GUIMain's legacy flags, now converted to GUIMainFlags on load +enum GUIMainLegacyFlags +{ + kGUIMain_LegacyTextWindow = 5 +}; + +// GUIMain's style of getting displayed on screen +enum GUIPopupStyle +{ + // Normal GUI + kGUIPopupNormal = 0, + // Shown when the mouse cursor moves to the top of the screen + kGUIPopupMouseY = 1, + // Same as Normal, but pauses the game when shown + kGUIPopupModal = 2, + // Same as Normal, but is not removed when interface is off + kGUIPopupNoAutoRemove = 3, + // (legacy option) Normal GUI, initially off + // converts to kGUIPopupNormal with Visible = false + kGUIPopupLegacyNormalOff = 4 +}; + +// The type of GUIControl +enum GUIControlType +{ + kGUIControlUndefined = -1, + kGUIButton = 1, + kGUILabel = 2, + kGUIInvWindow = 3, + kGUISlider = 4, + kGUITextBox = 5, + kGUIListBox = 6 +}; + +// GUIControl general style and behavior flags +enum GUIControlFlags +{ + kGUICtrl_Default = 0x0001, // only button + kGUICtrl_Cancel = 0x0002, // unused + kGUICtrl_Enabled = 0x0004, + kGUICtrl_TabStop = 0x0008, // unused + kGUICtrl_Visible = 0x0010, + kGUICtrl_Clip = 0x0020, // only button + kGUICtrl_Clickable = 0x0040, + kGUICtrl_Translated = 0x0080, // 3.3.0.1132 + kGUICtrl_Deleted = 0x8000, // unused (probably remains from the old editor?) + + kGUICtrl_DefFlags = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable, + // flags that had inverse meaning in old formats + kGUICtrl_OldFmtXorMask = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable +}; + +// GUIListBox style and behavior flags +enum GUIListBoxFlags +{ + kListBox_ShowBorder = 0x01, + kListBox_ShowArrows = 0x02, + kListBox_SvgIndex = 0x04, + + kListBox_DefFlags = kListBox_ShowBorder | kListBox_ShowArrows, + // flags that had inverse meaning in old formats + kListBox_OldFmtXorMask = kListBox_ShowBorder | kListBox_ShowArrows +}; + +// GUITextBox style and behavior flags +enum GUITextBoxFlags +{ + kTextBox_ShowBorder = 0x0001, + + kTextBox_DefFlags = kTextBox_ShowBorder, + // flags that had inverse meaning in old formats + kTextBox_OldFmtXorMask = kTextBox_ShowBorder +}; + +// Savegame data format +// TODO: move to the engine code +enum GuiSvgVersion +{ + kGuiSvgVersion_Initial = 0, + kGuiSvgVersion_350 = 1 +}; + +} // namespace Common +} // namespace AGS + +extern int guis_need_update; + +#endif // __AC_GUIDEFINES_H diff --git a/engines/ags/shared/gui/guiinv.cpp b/engines/ags/shared/gui/guiinv.cpp new file mode 100644 index 000000000000..662ccb479b84 --- /dev/null +++ b/engines/ags/shared/gui/guiinv.cpp @@ -0,0 +1,144 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/game_version.h" +#include "gui/guiinv.h" +#include "gui/guimain.h" +#include "util/stream.h" + +std::vector guiinv; +int numguiinv = 0; + +namespace AGS +{ +namespace Common +{ + +GUIInvWindow::GUIInvWindow() +{ + IsMouseOver = false; + CharId = -1; + ItemWidth = 40; + ItemHeight = 22; + ColCount = 0; + RowCount = 0; + TopItem = 0; + CalculateNumCells(); + + _scEventCount = 0; +} + +void GUIInvWindow::OnMouseEnter() +{ + IsMouseOver = true; +} + +void GUIInvWindow::OnMouseLeave() +{ + IsMouseOver = false; +} + +void GUIInvWindow::OnMouseUp() +{ + if (IsMouseOver) + IsActivated = true; +} + +void GUIInvWindow::OnResized() +{ + CalculateNumCells(); +} + +void GUIInvWindow::WriteToFile(Stream *out) const +{ + GUIObject::WriteToFile(out); + out->WriteInt32(CharId); + out->WriteInt32(ItemWidth); + out->WriteInt32(ItemHeight); +} + +void GUIInvWindow::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + GUIObject::ReadFromFile(in, gui_version); + if (gui_version >= kGuiVersion_unkn_109) + { + CharId = in->ReadInt32(); + ItemWidth = in->ReadInt32(); + ItemHeight = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + { // NOTE: reading into actual variables only for old savegame support + TopItem = in->ReadInt32(); + } + } + else + { + CharId = -1; + ItemWidth = 40; + ItemHeight = 22; + TopItem = 0; + } + + if (loaded_game_file_version >= kGameVersion_270) + { + // ensure that some items are visible + if (ItemWidth > Width) + ItemWidth = Width; + if (ItemHeight > Height) + ItemHeight = Height; + } + + CalculateNumCells(); +} + +void GUIInvWindow::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) +{ + GUIObject::ReadFromSavegame(in, svg_ver); + ItemWidth = in->ReadInt32(); + ItemHeight = in->ReadInt32(); + CharId = in->ReadInt32(); + TopItem = in->ReadInt32(); + CalculateNumCells(); +} + +void GUIInvWindow::WriteToSavegame(Stream *out) const +{ + GUIObject::WriteToSavegame(out); + out->WriteInt32(ItemWidth); + out->WriteInt32(ItemHeight); + out->WriteInt32(CharId); + out->WriteInt32(TopItem); +} + +void GUIInvWindow::CalculateNumCells() +{ + if (ItemWidth <= 0 || ItemHeight <= 0) + { + ColCount = 0; + RowCount = 0; + } + else if (loaded_game_file_version >= kGameVersion_270) + { + ColCount = Width / data_to_game_coord(ItemWidth); + RowCount = Height / data_to_game_coord(ItemHeight); + } + else + { + ColCount = floor((float)Width / (float)data_to_game_coord(ItemWidth) + 0.5f); + RowCount = floor((float)Height / (float)data_to_game_coord(ItemHeight) + 0.5f); + } +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h new file mode 100644 index 000000000000..2fdad85a2c09 --- /dev/null +++ b/engines/ags/shared/gui/guiinv.h @@ -0,0 +1,70 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUIINV_H +#define __AC_GUIINV_H + +#include +#include "gui/guiobject.h" + +namespace AGS +{ +namespace Common +{ + +class GUIInvWindow : public GUIObject +{ +public: + GUIInvWindow(); + + // This function has distinct implementations in Engine and Editor + int GetCharacterId() const; + + // Operations + // This function has distinct implementations in Engine and Editor + void Draw(Bitmap *ds) override; + + // Events + void OnMouseEnter() override; + void OnMouseLeave() override; + void OnMouseUp() override; + void OnResized() override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; + +// TODO: these members are currently public; hide them later +public: + bool IsMouseOver; + int32_t CharId; // whose inventory (-1 = current player) + int32_t ItemWidth; + int32_t ItemHeight; + int32_t ColCount; + int32_t RowCount; + int32_t TopItem; + +private: + void CalculateNumCells(); +}; + +} // namespace Common +} // namespace AGS + +extern std::vector guiinv; +extern int numguiinv; + +#endif // __AC_GUIINV_H diff --git a/engines/ags/shared/gui/guilabel.cpp b/engines/ags/shared/gui/guilabel.cpp new file mode 100644 index 000000000000..698a9abc47f0 --- /dev/null +++ b/engines/ags/shared/gui/guilabel.cpp @@ -0,0 +1,128 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/game_version.h" +#include "font/fonts.h" +#include "gui/guilabel.h" +#include "gui/guimain.h" +#include "util/stream.h" +#include "util/string_utils.h" + +std::vector guilabels; +int numguilabels = 0; + +#define GUILABEL_TEXTLENGTH_PRE272 200 + +namespace AGS +{ +namespace Common +{ + +GUILabel::GUILabel() +{ + Font = 0; + TextColor = 0; + TextAlignment = kHAlignLeft; + + _scEventCount = 0; +} + +String GUILabel::GetText() const +{ + return Text; +} + +void GUILabel::Draw(Common::Bitmap *ds) +{ + check_font(&Font); + + // TODO: need to find a way to cache text prior to drawing; + // but that will require to update all gui controls when translation is changed in game + PrepareTextToDraw(); + if (SplitLinesForDrawing(Lines) == 0) + return; + + color_t text_color = ds->GetCompatibleColor(TextColor); + const int linespacing = getfontlinespacing(Font) + 1; + // < 2.72 labels did not limit vertical size of text + const bool limit_by_label_frame = loaded_game_file_version >= kGameVersion_272; + int at_y = Y; + for (size_t i = 0; + i < Lines.Count() && (!limit_by_label_frame || at_y <= Y + Height); + ++i, at_y += linespacing) + { + GUI::DrawTextAlignedHor(ds, Lines[i], Font, text_color, X, X + Width - 1, at_y, + (FrameAlignment)TextAlignment); + } +} + +void GUILabel::SetText(const String &text) +{ + Text = text; +} + +// TODO: replace string serialization with StrUtil::ReadString and WriteString +// methods in the future, to keep this organized. +void GUILabel::WriteToFile(Stream *out) const +{ + GUIObject::WriteToFile(out); + StrUtil::WriteString(Text, out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(TextAlignment); +} + +void GUILabel::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + GUIObject::ReadFromFile(in, gui_version); + + if (gui_version < kGuiVersion_272c) + Text.ReadCount(in, GUILABEL_TEXTLENGTH_PRE272); + else + Text = StrUtil::ReadString(in); + + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + TextAlignment = ConvertLegacyGUIAlignment((LegacyGUIAlignment)in->ReadInt32()); + else + TextAlignment = (HorAlignment)in->ReadInt32(); + + if (TextColor == 0) + TextColor = 16; + // All labels are translated at the moment + Flags |= kGUICtrl_Translated; +} + +void GUILabel::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) +{ + GUIObject::ReadFromSavegame(in, svg_ver); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + Text = StrUtil::ReadString(in); + if (svg_ver >= kGuiSvgVersion_350) + TextAlignment = (HorAlignment)in->ReadInt32(); +} + +void GUILabel::WriteToSavegame(Stream *out) const +{ + GUIObject::WriteToSavegame(out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + StrUtil::WriteString(Text, out); + out->WriteInt32(TextAlignment); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h new file mode 100644 index 000000000000..97665d65ff02 --- /dev/null +++ b/engines/ags/shared/gui/guilabel.h @@ -0,0 +1,67 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUILABEL_H +#define __AC_GUILABEL_H + +#include +#include "gui/guiobject.h" +#include "util/string.h" + +class SplitLines; + +namespace AGS +{ +namespace Common +{ + +class GUILabel:public GUIObject +{ +public: + GUILabel(); + + String GetText() const; + + // Operations + void Draw(Bitmap *ds) override; + void SetText(const String &text); + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; + +// TODO: these members are currently public; hide them later +public: + String Text; + int32_t Font; + color_t TextColor; + HorAlignment TextAlignment; + +private: + void PrepareTextToDraw(); + size_t SplitLinesForDrawing(SplitLines &lines); + + // prepared text buffer/cache + String _textToDraw; +}; + +} // namespace Common +} // namespace AGS + +extern std::vector guilabels; +extern int numguilabels; + +#endif // __AC_GUILABEL_H diff --git a/engines/ags/shared/gui/guilistbox.cpp b/engines/ags/shared/gui/guilistbox.cpp new file mode 100644 index 000000000000..aa57ca0b3e2f --- /dev/null +++ b/engines/ags/shared/gui/guilistbox.cpp @@ -0,0 +1,433 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "font/fonts.h" +#include "gui/guilistbox.h" +#include "gui/guimain.h" +#include "util/stream.h" +#include "util/string_utils.h" + +std::vector guilist; +int numguilist = 0; + +namespace AGS +{ +namespace Common +{ + +GUIListBox::GUIListBox() +{ + ItemCount = 0; + SelectedItem = 0; + TopItem = 0; + RowHeight = 0; + VisibleItemCount = 0; + Font = 0; + TextColor = 0; + SelectedTextColor = 7; + ListBoxFlags = kListBox_DefFlags; + SelectedBgColor = 16; + TextAlignment = kHAlignLeft; + + _scEventCount = 1; + _scEventNames[0] = "SelectionChanged"; + _scEventArgs[0] = "GUIControl *control"; +} + +int GUIListBox::GetItemAt(int x, int y) const +{ + if (RowHeight <= 0 || IsInRightMargin(x)) + return -1; + + int index = y / RowHeight + TopItem; + if (index < 0 || index >= ItemCount) + return -1; + return index; +} + +bool GUIListBox::AreArrowsShown() const +{ + return (ListBoxFlags & kListBox_ShowArrows) != 0; +} + +bool GUIListBox::IsBorderShown() const +{ + return (ListBoxFlags & kListBox_ShowBorder) != 0; +} + +bool GUIListBox::IsSvgIndex() const +{ + return (ListBoxFlags & kListBox_SvgIndex) != 0; +} + +bool GUIListBox::IsInRightMargin(int x) const +{ + if (x >= (Width - get_fixed_pixel_size(6)) && IsBorderShown() && AreArrowsShown()) + return 1; + return 0; +} + +int GUIListBox::AddItem(const String &text) +{ + guis_need_update = 1; + Items.push_back(text); + SavedGameIndex.push_back(-1); + ItemCount++; + return ItemCount - 1; +} + +void GUIListBox::Clear() +{ + Items.clear(); + SavedGameIndex.clear(); + ItemCount = 0; + SelectedItem = 0; + TopItem = 0; + guis_need_update = 1; +} + +void GUIListBox::Draw(Common::Bitmap *ds) +{ + const int width = Width - 1; + const int height = Height - 1; + const int pixel_size = get_fixed_pixel_size(1); + + check_font(&Font); + color_t text_color = ds->GetCompatibleColor(TextColor); + color_t draw_color = ds->GetCompatibleColor(TextColor); + if (IsBorderShown()) + { + ds->DrawRect(Rect(X, Y, X + width + (pixel_size - 1), Y + height + (pixel_size - 1)), draw_color); + if (pixel_size > 1) + ds->DrawRect(Rect(X + 1, Y + 1, X + width, Y + height), draw_color); + } + + int right_hand_edge = (X + width) - pixel_size - 1; + + // use SetFont to update the RowHeight and VisibleItemCount + SetFont(Font); + + // draw the scroll bar in if necessary + if (ItemCount > VisibleItemCount && IsBorderShown() && AreArrowsShown()) + { + int xstrt, ystrt; + ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y, (X + (pixel_size - 1) + width) - get_fixed_pixel_size(7), Y + height), draw_color); + ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y + height / 2, X + width, Y + height / 2 + (pixel_size - 1)), draw_color); + + xstrt = (X + width - get_fixed_pixel_size(6)) + (pixel_size - 1); + ystrt = (Y + height - 3) - get_fixed_pixel_size(5); + + draw_color = ds->GetCompatibleColor(TextColor); + ds->DrawTriangle(Triangle(xstrt, ystrt, xstrt + get_fixed_pixel_size(4), ystrt, + xstrt + get_fixed_pixel_size(2), + ystrt + get_fixed_pixel_size(5)), draw_color); + + ystrt = Y + 3; + ds->DrawTriangle(Triangle(xstrt, ystrt + get_fixed_pixel_size(5), + xstrt + get_fixed_pixel_size(4), + ystrt + get_fixed_pixel_size(5), + xstrt + get_fixed_pixel_size(2), ystrt), draw_color); + + right_hand_edge -= get_fixed_pixel_size(7); + } + + DrawItemsFix(); + + for (int item = 0; item < VisibleItemCount; ++item) + { + if (item + TopItem >= ItemCount) + break; + + int at_y = Y + pixel_size + item * RowHeight; + if (item + TopItem == SelectedItem) + { + text_color = ds->GetCompatibleColor(SelectedTextColor); + if (SelectedBgColor > 0) + { + int stretch_to = (X + width) - pixel_size; + // draw the SelectedItem item bar (if colour not transparent) + draw_color = ds->GetCompatibleColor(SelectedBgColor); + if ((VisibleItemCount < ItemCount) && IsBorderShown() && AreArrowsShown()) + stretch_to -= get_fixed_pixel_size(7); + + ds->FillRect(Rect(X + pixel_size, at_y, stretch_to, at_y + RowHeight - pixel_size), draw_color); + } + } + else + text_color = ds->GetCompatibleColor(TextColor); + + int item_index = item + TopItem; + PrepareTextToDraw(Items[item_index]); + + GUI::DrawTextAlignedHor(ds, _textToDraw, Font, text_color, X + 1 + pixel_size, right_hand_edge, at_y + 1, + (FrameAlignment)TextAlignment); + } + + DrawItemsUnfix(); +} + +int GUIListBox::InsertItem(int index, const String &text) +{ + if (index < 0 || index > ItemCount) + return -1; + + Items.insert(Items.begin() + index, text); + SavedGameIndex.insert(SavedGameIndex.begin() + index, -1); + if (SelectedItem >= index) + SelectedItem++; + + ItemCount++; + guis_need_update = 1; + return ItemCount - 1; +} + +void GUIListBox::RemoveItem(int index) +{ + if (index < 0 || index >= ItemCount) + return; + + Items.erase(Items.begin() + index); + SavedGameIndex.erase(SavedGameIndex.begin() + index); + ItemCount--; + + if (SelectedItem > index) + SelectedItem--; + if (SelectedItem >= ItemCount) + SelectedItem = -1; + guis_need_update = 1; +} + +void GUIListBox::SetShowArrows(bool on) +{ + if (on) + ListBoxFlags |= kListBox_ShowArrows; + else + ListBoxFlags &= ~kListBox_ShowArrows; +} + +void GUIListBox::SetShowBorder(bool on) +{ + if (on) + ListBoxFlags |= kListBox_ShowBorder; + else + ListBoxFlags &= ~kListBox_ShowBorder; +} + +void GUIListBox::SetSvgIndex(bool on) +{ + if (on) + ListBoxFlags |= kListBox_SvgIndex; + else + ListBoxFlags &= ~kListBox_SvgIndex; +} + +void GUIListBox::SetFont(int font) +{ + Font = font; + RowHeight = getfontheight(Font) + get_fixed_pixel_size(2); + VisibleItemCount = Height / RowHeight; +} + +void GUIListBox::SetItemText(int index, const String &text) +{ + if (index >= 0 && index < ItemCount) + { + guis_need_update = 1; + Items[index] = text; + } +} + +bool GUIListBox::OnMouseDown() +{ + if (IsInRightMargin(MousePos.X)) + { + if (MousePos.Y < Height / 2 && TopItem > 0) + TopItem--; + if (MousePos.Y >= Height / 2 && ItemCount > TopItem + VisibleItemCount) + TopItem++; + return false; + } + + int sel = GetItemAt(MousePos.X, MousePos.Y); + if (sel < 0) + return false; + SelectedItem = sel; + IsActivated = true; + return false; +} + +void GUIListBox::OnMouseMove(int x_, int y_) +{ + MousePos.X = x_ - X; + MousePos.Y = y_ - Y; +} + +void GUIListBox::OnResized() +{ + if (RowHeight == 0) + { + check_font(&Font); + SetFont(Font); + } + if (RowHeight > 0) + VisibleItemCount = Height / RowHeight; +} + +// TODO: replace string serialization with StrUtil::ReadString and WriteString +// methods in the future, to keep this organized. +void GUIListBox::WriteToFile(Stream *out) const +{ + GUIObject::WriteToFile(out); + out->WriteInt32(ItemCount); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(SelectedTextColor); + out->WriteInt32(ListBoxFlags); + out->WriteInt32(TextAlignment); + out->WriteInt32(SelectedBgColor); + for (int i = 0; i < ItemCount; ++i) + Items[i].Write(out); +} + +void GUIListBox::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + Clear(); + + GUIObject::ReadFromFile(in, gui_version); + ItemCount = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + { // NOTE: reading into actual variables only for old savegame support + SelectedItem = in->ReadInt32(); + TopItem = in->ReadInt32(); + MousePos.X = in->ReadInt32(); + MousePos.Y = in->ReadInt32(); + RowHeight = in->ReadInt32(); + VisibleItemCount = in->ReadInt32(); + } + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + SelectedTextColor = in->ReadInt32(); + ListBoxFlags = in->ReadInt32(); + // reverse particular flags from older format + if (gui_version < kGuiVersion_350) + ListBoxFlags ^= kListBox_OldFmtXorMask; + + if (gui_version >= kGuiVersion_272b) + { + if (gui_version < kGuiVersion_350) + { + TextAlignment = ConvertLegacyGUIAlignment((LegacyGUIAlignment)in->ReadInt32()); + in->ReadInt32(); // reserved1 + } + else + { + TextAlignment = (HorAlignment)in->ReadInt32(); + } + } + else + { + TextAlignment = kHAlignLeft; + } + + if (gui_version >= kGuiVersion_unkn_107) + { + SelectedBgColor = in->ReadInt32(); + } + else + { + SelectedBgColor = TextColor; + if (SelectedBgColor == 0) + SelectedBgColor = 16; + } + + // NOTE: we leave items in game data format as a potential support for defining + // ListBox contents at design-time, although Editor does not support it as of 3.5.0. + Items.resize(ItemCount); + SavedGameIndex.resize(ItemCount, -1); + for (int i = 0; i < ItemCount; ++i) + { + Items[i].Read(in); + } + + if (gui_version >= kGuiVersion_272d && gui_version < kGuiVersion_350 && + (ListBoxFlags & kListBox_SvgIndex)) + { // NOTE: reading into actual variables only for old savegame support + for (int i = 0; i < ItemCount; ++i) + SavedGameIndex[i] = in->ReadInt16(); + } + + if (TextColor == 0) + TextColor = 16; +} + +void GUIListBox::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) +{ + GUIObject::ReadFromSavegame(in, svg_ver); + // Properties + ListBoxFlags = in->ReadInt32(); + Font = in->ReadInt32(); + if (svg_ver < kGuiSvgVersion_350) + { + // reverse particular flags from older format + ListBoxFlags ^= kListBox_OldFmtXorMask; + } + else + { + SelectedBgColor = in->ReadInt32(); + SelectedTextColor = in->ReadInt32(); + TextAlignment = (HorAlignment)in->ReadInt32(); + TextColor = in->ReadInt32(); + } + + // Items + ItemCount = in->ReadInt32(); + Items.resize(ItemCount); + SavedGameIndex.resize(ItemCount); + for (int i = 0; i < ItemCount; ++i) + Items[i] = StrUtil::ReadString(in); + // TODO: investigate this, it might be unreasonable to save and read + // savegame index like that because list of savegames may easily change + // in between writing and restoring the game. Perhaps clearing and forcing + // this list to update on load somehow may make more sense. + if (ListBoxFlags & kListBox_SvgIndex) + for (int i = 0; i < ItemCount; ++i) + SavedGameIndex[i] = in->ReadInt16(); + TopItem = in->ReadInt32(); + SelectedItem = in->ReadInt32(); +} + +void GUIListBox::WriteToSavegame(Stream *out) const +{ + GUIObject::WriteToSavegame(out); + // Properties + out->WriteInt32(ListBoxFlags); + out->WriteInt32(Font); + out->WriteInt32(SelectedBgColor); + out->WriteInt32(SelectedTextColor); + out->WriteInt32(TextAlignment); + out->WriteInt32(TextColor); + + // Items + out->WriteInt32(ItemCount); + for (int i = 0; i < ItemCount; ++i) + StrUtil::WriteString(Items[i], out); + if (ListBoxFlags & kListBox_SvgIndex) + for (int i = 0; i < ItemCount; ++i) + out->WriteInt16(SavedGameIndex[i]); + out->WriteInt32(TopItem); + out->WriteInt32(SelectedItem); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h new file mode 100644 index 000000000000..c919ac2d5a48 --- /dev/null +++ b/engines/ags/shared/gui/guilistbox.h @@ -0,0 +1,98 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUILISTBOX_H +#define __AC_GUILISTBOX_H + +#include +#include "gui/guiobject.h" +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +class GUIListBox : public GUIObject +{ +public: + GUIListBox(); + + bool AreArrowsShown() const; + bool IsBorderShown() const; + bool IsSvgIndex() const; + bool IsInRightMargin(int x) const; + int GetItemAt(int x, int y) const; + + // Operations + int AddItem(const String &text); + void Clear(); + void Draw(Bitmap *ds) override; + int InsertItem(int index, const String &text); + void RemoveItem(int index); + void SetShowArrows(bool on); + void SetShowBorder(bool on); + void SetSvgIndex(bool on); // TODO: work around this + void SetFont(int font); + void SetItemText(int index, const String &textt); + + // Events + bool OnMouseDown() override; + void OnMouseMove(int x, int y) override; + void OnResized() override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; + +// TODO: these members are currently public; hide them later +public: + int32_t Font; + color_t TextColor; + HorAlignment TextAlignment; + color_t SelectedBgColor; + color_t SelectedTextColor; + int32_t RowHeight; + int32_t VisibleItemCount; + + std::vector Items; + std::vector SavedGameIndex; + int32_t SelectedItem; + int32_t TopItem; + Point MousePos; + + // TODO: remove these later + int32_t ItemCount; + +private: + int32_t ListBoxFlags; + + // A temporary solution for special drawing in the Editor + void DrawItemsFix(); + void DrawItemsUnfix(); + void PrepareTextToDraw(const String &text); + + // prepared text buffer/cache + String _textToDraw; +}; + +} // namespace Common +} // namespace AGS + +extern std::vector guilist; +extern int numguilist; + +#endif // __AC_GUILISTBOX_H diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp new file mode 100644 index 000000000000..3e08125a64b1 --- /dev/null +++ b/engines/ags/shared/gui/guimain.cpp @@ -0,0 +1,919 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "ac/game_version.h" +#include "ac/spritecache.h" +#include "debug/out.h" +#include "font/fonts.h" +#include "gui/guibutton.h" +#include "gui/guiinv.h" +#include "gui/guilabel.h" +#include "gui/guilistbox.h" +#include "gui/guimain.h" +#include "gui/guislider.h" +#include "gui/guitextbox.h" +#include "util/stream.h" +#include "util/string_utils.h" + +using namespace AGS::Common; + +#define MOVER_MOUSEDOWNLOCKED -4000 + +int guis_need_update = 1; +int all_buttons_disabled = 0, gui_inv_pic = -1; +int gui_disabled_style = 0; + +namespace AGS +{ +namespace Common +{ + +/* static */ String GUIMain::FixupGUIName(const String &name) +{ + if (name.GetLength() > 0 && name[0u] != 'g') + return String::FromFormat("g%c%s", name[0u], name.Mid(1).Lower().GetCStr()); + return name; +} + +GUIMain::GUIMain() +{ + InitDefaults(); +} + +void GUIMain::InitDefaults() +{ + ID = 0; + Name.Empty(); + _flags = kGUIMain_DefFlags; + + X = 0; + Y = 0; + Width = 0; + Height = 0; + BgColor = 8; + BgImage = 0; + FgColor = 1; + Padding = TEXTWINDOW_PADDING_DEFAULT; + PopupStyle = kGUIPopupNormal; + PopupAtMouseY = -1; + Transparency = 0; + ZOrder = -1; + + FocusCtrl = 0; + HighlightCtrl = -1; + MouseOverCtrl = -1; + MouseDownCtrl = -1; + MouseWasAt.X = -1; + MouseWasAt.Y = -1; + + OnClickHandler.Empty(); + + _controls.clear(); + _ctrlRefs.clear(); + _ctrlDrawOrder.clear(); +} + +int GUIMain::FindControlUnderMouse(int leeway, bool must_be_clickable) const +{ + if (loaded_game_file_version <= kGameVersion_262) + { + // Ignore draw order On 2.6.2 and lower + for (size_t i = 0; i < _controls.size(); ++i) + { + if (!_controls[i]->IsVisible()) + continue; + if (!_controls[i]->IsClickable() && must_be_clickable) + continue; + if (_controls[i]->IsOverControl(mousex, mousey, leeway)) + return i; + } + } + else + { + for (size_t i = _controls.size(); i-- > 0;) + { + const int ctrl_index = _ctrlDrawOrder[i]; + if (!_controls[ctrl_index]->IsVisible()) + continue; + if (!_controls[ctrl_index]->IsClickable() && must_be_clickable) + continue; + if (_controls[ctrl_index]->IsOverControl(mousex, mousey, leeway)) + return ctrl_index; + } + } + return -1; +} + +int GUIMain::FindControlUnderMouse() const +{ + return FindControlUnderMouse(0, true); +} + +int GUIMain::FindControlUnderMouse(int leeway) const +{ + return FindControlUnderMouse(leeway, true); +} + +int GUIMain::GetControlCount() const +{ + return (int32_t)_controls.size(); +} + +GUIObject *GUIMain::GetControl(int index) const +{ + if (index < 0 || (size_t)index >= _controls.size()) + return nullptr; + return _controls[index]; +} + +GUIControlType GUIMain::GetControlType(int index) const +{ + if (index < 0 || (size_t)index >= _ctrlRefs.size()) + return kGUIControlUndefined; + return _ctrlRefs[index].first; +} + +int32_t GUIMain::GetControlID(int index) const +{ + if (index < 0 || (size_t)index >= _ctrlRefs.size()) + return -1; + return _ctrlRefs[index].second; +} + +bool GUIMain::IsClickable() const +{ + return (_flags & kGUIMain_Clickable) != 0; +} + +bool GUIMain::IsConcealed() const +{ + return (_flags & kGUIMain_Concealed) != 0; +} + +bool GUIMain::IsDisplayed() const +{ + if(!IsVisible()) return false; + if(IsConcealed()) return false; + if(Transparency == 255) return false; + return true; +} + +bool GUIMain::IsInteractableAt(int x, int y) const +{ + if (!IsDisplayed()) + return false; + if (!IsClickable()) + return false; + if ((x >= X) & (y >= Y) & (x < X + Width) & (y < Y + Height)) + return true; + return false; +} + +bool GUIMain::IsTextWindow() const +{ + return (_flags & kGUIMain_TextWindow) != 0; +} + +bool GUIMain::IsVisible() const +{ + return (_flags & kGUIMain_Visible) != 0; +} + +void GUIMain::AddControl(GUIControlType type, int id, GUIObject *control) +{ + _ctrlRefs.push_back(std::make_pair(type, id)); + _controls.push_back(control); +} + +void GUIMain::RemoveAllControls() +{ + _ctrlRefs.clear(); + _controls.clear(); +} + +bool GUIMain::BringControlToFront(int index) +{ + return SetControlZOrder(index, (int)_controls.size() - 1); +} + +void GUIMain::Draw(Bitmap *ds) +{ + DrawAt(ds, X, Y); +} + +void GUIMain::DrawAt(Bitmap *ds, int x, int y) +{ + SET_EIP(375) + + if ((Width < 1) || (Height < 1)) + return; + + Bitmap subbmp; + subbmp.CreateSubBitmap(ds, RectWH(x, y, Width, Height)); + + SET_EIP(376) + // stop border being transparent, if the whole GUI isn't + if ((FgColor == 0) && (BgColor != 0)) + FgColor = 16; + + if (BgColor != 0) + subbmp.Fill(subbmp.GetCompatibleColor(BgColor)); + + SET_EIP(377) + + color_t draw_color; + if (FgColor != BgColor) + { + draw_color = subbmp.GetCompatibleColor(FgColor); + subbmp.DrawRect(Rect(0, 0, subbmp.GetWidth() - 1, subbmp.GetHeight() - 1), draw_color); + if (get_fixed_pixel_size(1) > 1) + subbmp.DrawRect(Rect(1, 1, subbmp.GetWidth() - 2, subbmp.GetHeight() - 2), draw_color); + } + + SET_EIP(378) + + if (BgImage > 0 && spriteset[BgImage] != nullptr) + draw_gui_sprite(&subbmp, BgImage, 0, 0, false); + + SET_EIP(379) + + if (all_buttons_disabled && gui_disabled_style == GUIDIS_BLACKOUT) + return; // don't draw GUI controls + + for (size_t ctrl_index = 0; ctrl_index < _controls.size(); ++ctrl_index) + { + set_eip_guiobj(_ctrlDrawOrder[ctrl_index]); + + GUIObject *objToDraw = _controls[_ctrlDrawOrder[ctrl_index]]; + + if (!objToDraw->IsEnabled() && gui_disabled_style == GUIDIS_BLACKOUT) + continue; + if (!objToDraw->IsVisible()) + continue; + + objToDraw->Draw(&subbmp); + + int selectedColour = 14; + + if (HighlightCtrl == _ctrlDrawOrder[ctrl_index]) + { + if (outlineGuiObjects) + selectedColour = 13; + draw_color = subbmp.GetCompatibleColor(selectedColour); + DrawBlob(&subbmp, objToDraw->X + objToDraw->Width - get_fixed_pixel_size(1) - 1, objToDraw->Y, draw_color); + DrawBlob(&subbmp, objToDraw->X, objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); + DrawBlob(&subbmp, objToDraw->X, objToDraw->Y, draw_color); + DrawBlob(&subbmp, objToDraw->X + objToDraw->Width - get_fixed_pixel_size(1) - 1, + objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); + } + if (outlineGuiObjects) + { + // draw a dotted outline round all objects + draw_color = subbmp.GetCompatibleColor(selectedColour); + for (int i = 0; i < objToDraw->Width; i += 2) + { + subbmp.PutPixel(i + objToDraw->X, objToDraw->Y, draw_color); + subbmp.PutPixel(i + objToDraw->X, objToDraw->Y + objToDraw->Height - 1, draw_color); + } + for (int i = 0; i < objToDraw->Height; i += 2) + { + subbmp.PutPixel(objToDraw->X, i + objToDraw->Y, draw_color); + subbmp.PutPixel(objToDraw->X + objToDraw->Width - 1, i + objToDraw->Y, draw_color); + } + } + } + + SET_EIP(380) +} + +void GUIMain::DrawBlob(Bitmap *ds, int x, int y, color_t draw_color) +{ + ds->FillRect(Rect(x, y, x + get_fixed_pixel_size(1), y + get_fixed_pixel_size(1)), draw_color); +} + +void GUIMain::Poll() +{ + int mxwas = mousex, mywas = mousey; + + mousex -= X; + mousey -= Y; + if (mousex != MouseWasAt.X || mousey != MouseWasAt.Y) + { + int ctrl_index = FindControlUnderMouse(); + + if (MouseOverCtrl == MOVER_MOUSEDOWNLOCKED) + _controls[MouseDownCtrl]->OnMouseMove(mousex, mousey); + else if (ctrl_index != MouseOverCtrl) + { + if (MouseOverCtrl >= 0) + _controls[MouseOverCtrl]->OnMouseLeave(); + + if (ctrl_index >= 0 && !IsGUIEnabled(_controls[ctrl_index])) + // the control is disabled - ignore it + MouseOverCtrl = -1; + else if (ctrl_index >= 0 && !_controls[ctrl_index]->IsClickable()) + // the control is not clickable - ignore it + MouseOverCtrl = -1; + else + { + // over a different control + MouseOverCtrl = ctrl_index; + if (MouseOverCtrl >= 0) + { + _controls[MouseOverCtrl]->OnMouseEnter(); + _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); + } + } + guis_need_update = 1; + } + else if (MouseOverCtrl >= 0) + _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); + } + + MouseWasAt.X = mousex; + MouseWasAt.Y = mousey; + mousex = mxwas; + mousey = mywas; +} + +HError GUIMain::RebuildArray() +{ + GUIControlType thistype; + int32_t thisnum; + + _controls.resize(_ctrlRefs.size()); + for (size_t i = 0; i < _controls.size(); ++i) + { + thistype = _ctrlRefs[i].first; + thisnum = _ctrlRefs[i].second; + + if (thisnum < 0) + return new Error(String::FromFormat("GUIMain (%d): invalid control ID %d in ref #%d", ID, thisnum, i)); + + if (thistype == kGUIButton) + _controls[i] = &guibuts[thisnum]; + else if (thistype == kGUILabel) + _controls[i] = &guilabels[thisnum]; + else if (thistype == kGUIInvWindow) + _controls[i] = &guiinv[thisnum]; + else if (thistype == kGUISlider) + _controls[i] = &guislider[thisnum]; + else if (thistype == kGUITextBox) + _controls[i] = &guitext[thisnum]; + else if (thistype == kGUIListBox) + _controls[i] = &guilist[thisnum]; + else + return new Error(String::FromFormat("GUIMain (%d): unknown control type %d in ref #%d", ID, thistype, i)); + + _controls[i]->ParentId = ID; + _controls[i]->Id = i; + } + + ResortZOrder(); + return HError::None(); +} + +bool GUIControlZOrder(const GUIObject *e1, const GUIObject *e2) +{ + return e1->ZOrder < e2->ZOrder; +} + +void GUIMain::ResortZOrder() +{ + std::vector ctrl_sort = _controls; + std::sort(ctrl_sort.begin(), ctrl_sort.end(), GUIControlZOrder); + + _ctrlDrawOrder.resize(ctrl_sort.size()); + for (size_t i = 0; i < ctrl_sort.size(); ++i) + _ctrlDrawOrder[i] = ctrl_sort[i]->Id; +} + +void GUIMain::SetClickable(bool on) +{ + if (on) + _flags |= kGUIMain_Clickable; + else + _flags &= ~kGUIMain_Clickable; +} + +void GUIMain::SetConceal(bool on) +{ + if (on) + _flags |= kGUIMain_Concealed; + else + _flags &= ~kGUIMain_Concealed; +} + +bool GUIMain::SendControlToBack(int index) +{ + return SetControlZOrder(index, 0); +} + +bool GUIMain::SetControlZOrder(int index, int zorder) +{ + if (index < 0 || (size_t)index >= _controls.size()) + return false; // no such control + + zorder = Math::Clamp(zorder, 0, (int)_controls.size() - 1); + const int old_zorder = _controls[index]->ZOrder; + if (old_zorder == zorder) + return false; // no change + + const bool move_back = zorder < old_zorder; // back is at zero index + const int left = move_back ? zorder : old_zorder; + const int right = move_back ? old_zorder : zorder; + for (size_t i = 0; i < _controls.size(); ++i) + { + const int i_zorder = _controls[i]->ZOrder; + if (i_zorder == old_zorder) + _controls[i]->ZOrder = zorder; // the control we are moving + else if (i_zorder >= left && i_zorder <= right) + { + // controls in between old and new positions shift towards free place + if (move_back) + _controls[i]->ZOrder++; // move to front + else + _controls[i]->ZOrder--; // move to back + } + } + ResortZOrder(); + OnControlPositionChanged(); + return true; +} + +void GUIMain::SetTextWindow(bool on) +{ + if (on) + _flags |= kGUIMain_TextWindow; + else + _flags &= ~kGUIMain_TextWindow; +} + +void GUIMain::SetTransparencyAsPercentage(int percent) +{ + Transparency = GfxDef::Trans100ToLegacyTrans255(percent); + guis_need_update = 1; +} + +void GUIMain::SetVisible(bool on) +{ + if (on) + _flags |= kGUIMain_Visible; + else + _flags &= ~kGUIMain_Visible; +} + +void GUIMain::OnControlPositionChanged() +{ + // force it to re-check for which control is under the mouse + MouseWasAt.X = -1; + MouseWasAt.Y = -1; +} + +void GUIMain::OnMouseButtonDown() +{ + if (MouseOverCtrl < 0) + return; + + // don't activate disabled buttons + if (!IsGUIEnabled(_controls[MouseOverCtrl]) || !_controls[MouseOverCtrl]->IsVisible() || + !_controls[MouseOverCtrl]->IsClickable()) + return; + + MouseDownCtrl = MouseOverCtrl; + if (_controls[MouseOverCtrl]->OnMouseDown()) + MouseOverCtrl = MOVER_MOUSEDOWNLOCKED; + _controls[MouseDownCtrl]->OnMouseMove(mousex - X, mousey - Y); + guis_need_update = 1; +} + +void GUIMain::OnMouseButtonUp() +{ + // FocusCtrl was locked - reset it back to normal, but On the + // locked object so that a OnMouseLeave gets fired if necessary + if (MouseOverCtrl == MOVER_MOUSEDOWNLOCKED) + { + MouseOverCtrl = MouseDownCtrl; + MouseWasAt.X = -1; // force update + } + + if (MouseDownCtrl < 0) + return; + + _controls[MouseDownCtrl]->OnMouseUp(); + MouseDownCtrl = -1; + guis_need_update = 1; +} + +void GUIMain::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + // Legacy text window tag + char tw_flags[GUIMAIN_LEGACY_TW_FLAGS_SIZE] = {0}; + if (gui_version < kGuiVersion_350) + in->Read(tw_flags, sizeof(tw_flags)); + + if (gui_version < kGuiVersion_340) + { + Name.ReadCount(in, GUIMAIN_LEGACY_NAME_LENGTH); + OnClickHandler.ReadCount(in, GUIMAIN_LEGACY_EVENTHANDLER_LENGTH); + } + else + { + Name = StrUtil::ReadString(in); + OnClickHandler = StrUtil::ReadString(in); + } + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + { // NOTE: reading into actual variables only for old savegame support + FocusCtrl = in->ReadInt32(); + } + const size_t ctrl_count = in->ReadInt32(); + PopupStyle = (GUIPopupStyle)in->ReadInt32(); + PopupAtMouseY = in->ReadInt32(); + BgColor = in->ReadInt32(); + BgImage = in->ReadInt32(); + FgColor = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + { // NOTE: reading into actual variables only for old savegame support + MouseOverCtrl = in->ReadInt32(); + MouseWasAt.X = in->ReadInt32(); + MouseWasAt.Y = in->ReadInt32(); + MouseDownCtrl = in->ReadInt32(); + HighlightCtrl = in->ReadInt32(); + } + _flags = in->ReadInt32(); + Transparency = in->ReadInt32(); + ZOrder = in->ReadInt32(); + ID = in->ReadInt32(); + Padding = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + in->Seek(sizeof(int32_t) * GUIMAIN_LEGACY_RESERVED_INTS); + + if (gui_version < kGuiVersion_350) + { + if (tw_flags[0] == kGUIMain_LegacyTextWindow) + _flags |= kGUIMain_TextWindow; + // reverse particular flags from older format + _flags ^= kGUIMain_OldFmtXorMask; + GUI::ApplyLegacyVisibility(*this, (LegacyGUIVisState)in->ReadInt32()); + } + + // pre-3.4.0 games contained array of 32-bit pointers; these values are unused + // TODO: error if ctrl_count > LEGACY_MAX_OBJS_ON_GUI + if (gui_version < kGuiVersion_340) + in->Seek(LEGACY_MAX_OBJS_ON_GUI * sizeof(int32_t)); + if (ctrl_count > 0) + { + _ctrlRefs.resize(ctrl_count); + for (size_t i = 0; i < ctrl_count; ++i) + { + const int32_t ref_packed = in->ReadInt32(); + _ctrlRefs[i].first = (GUIControlType)((ref_packed >> 16) & 0xFFFF); + _ctrlRefs[i].second = ref_packed & 0xFFFF; + } + } + // Skip unused control slots in pre-3.4.0 games + if (gui_version < kGuiVersion_340 && ctrl_count < LEGACY_MAX_OBJS_ON_GUI) + in->Seek((LEGACY_MAX_OBJS_ON_GUI - ctrl_count) * sizeof(int32_t)); +} + +void GUIMain::WriteToFile(Stream *out) const +{ + StrUtil::WriteString(Name, out); + StrUtil::WriteString(OnClickHandler, out); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(_ctrlRefs.size()); + out->WriteInt32(PopupStyle); + out->WriteInt32(PopupAtMouseY); + out->WriteInt32(BgColor); + out->WriteInt32(BgImage); + out->WriteInt32(FgColor); + out->WriteInt32(_flags); + out->WriteInt32(Transparency); + out->WriteInt32(ZOrder); + out->WriteInt32(ID); + out->WriteInt32(Padding); + for (size_t i = 0; i < _ctrlRefs.size(); ++i) + { + int32_t ref_packed = ((_ctrlRefs[i].first & 0xFFFF) << 16) | (_ctrlRefs[i].second & 0xFFFF); + out->WriteInt32(ref_packed); + } +} + +void GUIMain::ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_version) +{ + // Properties + _flags = in->ReadInt32(); + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + BgImage = in->ReadInt32(); + Transparency = in->ReadInt32(); + if (svg_version < kGuiSvgVersion_350) + { + // reverse particular flags from older format + _flags ^= kGUIMain_OldFmtXorMask; + GUI::ApplyLegacyVisibility(*this, (LegacyGUIVisState)in->ReadInt32()); + } + ZOrder = in->ReadInt32(); + + if (svg_version >= kGuiSvgVersion_350) + { + BgColor = in->ReadInt32(); + FgColor = in->ReadInt32(); + Padding = in->ReadInt32(); + PopupAtMouseY = in->ReadInt32(); + } + + // Dynamic values + FocusCtrl = in->ReadInt32(); + HighlightCtrl = in->ReadInt32(); + MouseOverCtrl = in->ReadInt32(); + MouseDownCtrl = in->ReadInt32(); + MouseWasAt.X = in->ReadInt32(); + MouseWasAt.Y = in->ReadInt32(); +} + +void GUIMain::WriteToSavegame(Common::Stream *out) const +{ + // Properties + out->WriteInt32(_flags); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(BgImage); + out->WriteInt32(Transparency); + out->WriteInt32(ZOrder); + out->WriteInt32(BgColor); + out->WriteInt32(FgColor); + out->WriteInt32(Padding); + out->WriteInt32(PopupAtMouseY); + // Dynamic values + out->WriteInt32(FocusCtrl); + out->WriteInt32(HighlightCtrl); + out->WriteInt32(MouseOverCtrl); + out->WriteInt32(MouseDownCtrl); + out->WriteInt32(MouseWasAt.X); + out->WriteInt32(MouseWasAt.Y); +} + + +namespace GUI +{ + +GuiVersion GameGuiVersion = kGuiVersion_Initial; + +void DrawDisabledEffect(Bitmap *ds, const Rect &rc) +{ + color_t draw_color = ds->GetCompatibleColor(8); + for (int at_x = rc.Left; at_x <= rc.Right; ++at_x) + { + for (int at_y = rc.Top + at_x % 2; at_y <= rc.Bottom; at_y += 2) + { + ds->PutPixel(at_x, at_y, draw_color); + } + } +} + +void DrawTextAligned(Bitmap *ds, const char *text, int font, color_t text_color, const Rect &frame, FrameAlignment align) +{ + int text_height = wgettextheight(text, font); + if (align & kMAlignVCenter) + text_height++; // CHECKME + Rect item = AlignInRect(frame, RectWH(0, 0, wgettextwidth(text, font), text_height), align); + wouttext_outline(ds, item.Left, item.Top, font, text_color, text); +} + +void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_color, int x1, int x2, int y, FrameAlignment align) +{ + int x = AlignInHRange(x1, x2, 0, wgettextwidth(text, font), align); + wouttext_outline(ds, x, y, font, text_color, text); +} + +HError ResortGUI(std::vector &guis, bool bwcompat_ctrl_zorder = false) +{ + // set up the reverse-lookup array + for (size_t gui_index = 0; gui_index < guis.size(); ++gui_index) + { + GUIMain &gui = guis[gui_index]; + HError err = gui.RebuildArray(); + if (!err) + return err; + for (int ctrl_index = 0; ctrl_index < gui.GetControlCount(); ++ctrl_index) + { + GUIObject *gui_ctrl = gui.GetControl(ctrl_index); + gui_ctrl->ParentId = gui_index; + gui_ctrl->Id = ctrl_index; + if (bwcompat_ctrl_zorder) + gui_ctrl->ZOrder = ctrl_index; + } + gui.ResortZOrder(); + } + guis_need_update = 1; + return HError::None(); +} + +HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame) +{ + if (in->ReadInt32() != (int)GUIMAGIC) + return new Error("ReadGUI: unknown format or file is corrupt"); + + GameGuiVersion = (GuiVersion)in->ReadInt32(); + Debug::Printf(kDbgMsg_Info, "Game GUI version: %d", GameGuiVersion); + size_t gui_count; + if (GameGuiVersion < kGuiVersion_214) + { + gui_count = (size_t)GameGuiVersion; + GameGuiVersion = kGuiVersion_Initial; + } + else if (GameGuiVersion > kGuiVersion_Current) + return new Error(String::FromFormat("ReadGUI: format version not supported (required %d, supported %d - %d)", + GameGuiVersion, kGuiVersion_Initial, kGuiVersion_Current)); + else + gui_count = in->ReadInt32(); + guis.resize(gui_count); + + // import the main GUI elements + for (size_t i = 0; i < gui_count; ++i) + { + GUIMain &gui = guis[i]; + gui.InitDefaults(); + gui.ReadFromFile(in, GameGuiVersion); + + // perform fixups + if (gui.Height < 2) + gui.Height = 2; + if (GameGuiVersion < kGuiVersion_unkn_103) + gui.Name.Format("GUI%d", i); + if (GameGuiVersion < kGuiVersion_260) + gui.ZOrder = i; + if (GameGuiVersion < kGuiVersion_270) + gui.OnClickHandler.Empty(); + if (GameGuiVersion < kGuiVersion_331) + gui.Padding = TEXTWINDOW_PADDING_DEFAULT; + // fix names for 2.x: "GUI" -> "gGui" + if (loaded_game_file_version <= kGameVersion_272) + gui.Name = GUIMain::FixupGUIName(gui.Name); + + // GUI popup style and visibility + if (GameGuiVersion < kGuiVersion_350 && !is_savegame) + { + // Convert legacy normal-off style into normal one + if (gui.PopupStyle == kGUIPopupLegacyNormalOff) + { + gui.PopupStyle = kGUIPopupNormal; + gui.SetVisible(false); + } + // Normal GUIs and PopupMouseY GUIs should start with Visible = true + else + { + gui.SetVisible(gui.PopupStyle != kGUIPopupModal); + } + } + + // PopupMouseY GUIs should be initially concealed + if (gui.PopupStyle == kGUIPopupMouseY) + gui.SetConceal(true); + // Assign ID to order in array + gui.ID = i; + } + + // buttons + numguibuts = in->ReadInt32(); + guibuts.resize(numguibuts); + for (int i = 0; i < numguibuts; ++i) + { + guibuts[i].ReadFromFile(in, GameGuiVersion); + } + // labels + numguilabels = in->ReadInt32(); + guilabels.resize(numguilabels); + for (int i = 0; i < numguilabels; ++i) + { + guilabels[i].ReadFromFile(in, GameGuiVersion); + } + // inv controls + numguiinv = in->ReadInt32(); + guiinv.resize(numguiinv); + for (int i = 0; i < numguiinv; ++i) + { + guiinv[i].ReadFromFile(in, GameGuiVersion); + } + + if (GameGuiVersion >= kGuiVersion_214) + { + // sliders + numguislider = in->ReadInt32(); + guislider.resize(numguislider); + for (int i = 0; i < numguislider; ++i) + { + guislider[i].ReadFromFile(in, GameGuiVersion); + } + } + if (GameGuiVersion >= kGuiVersion_222) + { + // text boxes + numguitext = in->ReadInt32(); + guitext.resize(numguitext); + for (int i = 0; i < numguitext; ++i) + { + guitext[i].ReadFromFile(in, GameGuiVersion); + } + } + if (GameGuiVersion >= kGuiVersion_230) + { + // list boxes + numguilist = in->ReadInt32(); + guilist.resize(numguilist); + for (int i = 0; i < numguilist; ++i) + { + guilist[i].ReadFromFile(in, GameGuiVersion); + } + } + return ResortGUI(guis, GameGuiVersion < kGuiVersion_272e); +} + +void WriteGUI(const std::vector &guis, Stream *out) +{ + out->WriteInt32(GUIMAGIC); + out->WriteInt32(kGuiVersion_Current); + out->WriteInt32(guis.size()); + + for (size_t i = 0; i < guis.size(); ++i) + { + guis[i].WriteToFile(out); + } + out->WriteInt32(numguibuts); + for (int i = 0; i < numguibuts; ++i) + { + guibuts[i].WriteToFile(out); + } + out->WriteInt32(numguilabels); + for (int i = 0; i < numguilabels; ++i) + { + guilabels[i].WriteToFile(out); + } + out->WriteInt32(numguiinv); + for (int i = 0; i < numguiinv; ++i) + { + guiinv[i].WriteToFile(out); + } + out->WriteInt32(numguislider); + for (int i = 0; i < numguislider; ++i) + { + guislider[i].WriteToFile(out); + } + out->WriteInt32(numguitext); + for (int i = 0; i < numguitext; ++i) + { + guitext[i].WriteToFile(out); + } + out->WriteInt32(numguilist); + for (int i = 0; i < numguilist; ++i) + { + guilist[i].WriteToFile(out); + } +} + +void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis) +{ + // kGUIPopupMouseY had its own rules, which we practically reverted now + if (gui.PopupStyle == kGUIPopupMouseY) + { + // it was only !Visible if the legacy Visibility was Concealed + gui.SetVisible(vis != kGUIVisibility_Concealed); + // and you could tell it's overridden by behavior when legacy Visibility is Off + gui.SetConceal(vis == kGUIVisibility_Off); + } + // Other GUI styles were simple + else + { + gui.SetVisible(vis != kGUIVisibility_Off); + gui.SetConceal(false); + } +} + +} // namespace GUI + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h new file mode 100644 index 000000000000..b7aeb5b9140f --- /dev/null +++ b/engines/ags/shared/gui/guimain.h @@ -0,0 +1,241 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUIMAIN_H +#define __AC_GUIMAIN_H + +#include +#include "ac/common_defines.h" // TODO: split out gui drawing helpers +#include "gfx/gfx_def.h" // TODO: split out gui drawing helpers +#include "gui/guidefines.h" +#include "util/error.h" +#include "util/geometry.h" +#include "util/string.h" + +// Forward declaration +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +// There were issues when including header caused conflicts +struct GameSetupStruct; + +#define LEGACY_MAX_OBJS_ON_GUI 30 + +#define GUIMAIN_LEGACY_RESERVED_INTS 5 +#define GUIMAIN_LEGACY_NAME_LENGTH 16 +#define GUIMAIN_LEGACY_EVENTHANDLER_LENGTH 20 +#define GUIMAIN_LEGACY_TW_FLAGS_SIZE 4 + +namespace AGS +{ +namespace Common +{ + +// Legacy GUIMain visibility state, which combined Visible property and override factor +enum LegacyGUIVisState +{ + kGUIVisibility_Concealed = -1, // gui is hidden by command + kGUIVisibility_Off = 0, // gui is disabled (won't show up by command) + kGUIVisibility_On = 1 // gui is shown by command +}; + +class Bitmap; +class GUIObject; + + +class GUIMain +{ +public: + static String FixupGUIName(const String &name); + +public: + GUIMain(); + + void InitDefaults(); + + // Tells if the gui background supports alpha channel + bool HasAlphaChannel() const; + // Tells if GUI will react on clicking on it + bool IsClickable() const; + // Tells if GUI's visibility is overridden and it won't be displayed on + // screen regardless of Visible property (until concealed mode is off). + bool IsConcealed() const; + // Tells if gui is actually displayed on screen. Normally Visible property + // determines whether GUI is allowed to be seen, but there may be other + // settings that override GUI's visibility. + bool IsDisplayed() const; + // Tells if given coordinates are within interactable area of gui + // NOTE: this currently tests for actual visibility and Clickable property + bool IsInteractableAt(int x, int y) const; + // Tells if gui is a text window + bool IsTextWindow() const; + // Tells if GUI is *allowed* to be displayed and interacted with. + // This does not necessarily mean that it is displayed right now, because + // GUI may be hidden for other reasons, including overriding behavior. + // For example GUI with kGUIPopupMouseY style will not be shown unless + // mouse cursor is at certain position on screen. + bool IsVisible() const; + + int32_t FindControlUnderMouse() const; + // this version allows some extra leeway in the Editor so that + // the user can grab tiny controls + int32_t FindControlUnderMouse(int leeway) const; + int32_t FindControlUnderMouse(int leeway, bool must_be_clickable) const; + // Gets the number of the GUI child controls + int32_t GetControlCount() const; + // Gets control by its child's index + GUIObject *GetControl(int index) const; + // Gets child control's type, looks up with child's index + GUIControlType GetControlType(int index) const; + // Gets child control's global ID, looks up with child's index + int32_t GetControlID(int index) const; + + // Child control management + // Note that currently GUIMain does not own controls (should not delete them) + void AddControl(GUIControlType type, int id, GUIObject *control); + void RemoveAllControls(); + + // Operations + bool BringControlToFront(int index); + void Draw(Bitmap *ds); + void DrawAt(Bitmap *ds, int x, int y); + void Poll(); + HError RebuildArray(); + void ResortZOrder(); + bool SendControlToBack(int index); + // Sets whether GUI should react to player clicking on it + void SetClickable(bool on); + // Override GUI visibility; when in concealed mode GUI won't show up + // even if Visible = true + void SetConceal(bool on); + // Attempts to change control's zorder; returns if zorder changed + bool SetControlZOrder(int index, int zorder); + // Changes GUI style to the text window or back + void SetTextWindow(bool on); + // Sets GUI transparency as a percentage (0 - 100) where 100 = invisible + void SetTransparencyAsPercentage(int percent); + // Sets whether GUI is allowed to be displayed on screen + void SetVisible(bool on); + + // Events + void OnMouseButtonDown(); + void OnMouseButtonUp(); + void OnControlPositionChanged(); + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version); + void WriteToFile(Stream *out) const; + // TODO: move to engine, into gui savegame component unit + // (should read/write GUI properties accessing them by interface) + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_version); + void WriteToSavegame(Stream *out) const; + +private: + void DrawBlob(Bitmap *ds, int x, int y, color_t draw_color); + + // TODO: all members are currently public; hide them later +public: + int32_t ID; // GUI identifier + String Name; // the name of the GUI + + int32_t X; + int32_t Y; + int32_t Width; + int32_t Height; + color_t BgColor; // background color + int32_t BgImage; // background sprite index + color_t FgColor; // foreground color (used as border color in normal GUIs, + // and text color in text windows) + int32_t Padding; // padding surrounding a GUI text window + GUIPopupStyle PopupStyle; // GUI popup behavior + int32_t PopupAtMouseY; // popup when mousey < this + int32_t Transparency; // "incorrect" alpha (in legacy 255-range units) + int32_t ZOrder; + + int32_t FocusCtrl; // which control has the focus + int32_t HighlightCtrl; // which control has the bounding selection rect + int32_t MouseOverCtrl; // which control has the mouse cursor over it + int32_t MouseDownCtrl; // which control has the mouse button pressed on it + Point MouseWasAt; // last mouse cursor position + + String OnClickHandler; // script function name + +private: + int32_t _flags; // style and behavior flags + + // Array of types and control indexes in global GUI object arrays; + // maps GUI child slots to actual controls and used for rebuilding Controls array + typedef std::pair ControlRef; + std::vector _ctrlRefs; + // Array of child control references (not exclusively owned!) + std::vector _controls; + // Sorted array of controls in z-order. + std::vector _ctrlDrawOrder; +}; + + +namespace GUI +{ + extern GuiVersion GameGuiVersion; + + // Draw standart "shading" effect over rectangle + void DrawDisabledEffect(Bitmap *ds, const Rect &rc); + // Draw text aligned inside rectangle + void DrawTextAligned(Bitmap *ds, const char *text, int font, color_t text_color, const Rect &frame, FrameAlignment align); + // Draw text aligned horizontally inside given bounds + void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_color, int x1, int x2, int y, FrameAlignment align); + + // TODO: remove is_savegame param after dropping support for old saves + // because only they use ReadGUI to read runtime GUI data + HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame = false); + void WriteGUI(const std::vector &guis, Stream *out); + // Converts legacy GUIVisibility into appropriate GUIMain properties + void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis); +} + +} // namespace Common +} // namespace AGS + +extern std::vector guis; +extern int all_buttons_disabled, gui_inv_pic; +extern int gui_disabled_style; + +extern int mousex, mousey; + +extern int get_adjusted_spritewidth(int spr); +extern int get_adjusted_spriteheight(int spr); +extern bool is_sprite_alpha(int spr); + +// This function has distinct implementations in Engine and Editor +extern void draw_gui_sprite(Common::Bitmap *ds, int spr, int x, int y, bool use_alpha = true, + Common::BlendMode blend_mode = Common::kBlendMode_Alpha); + +extern AGS_INLINE int game_to_data_coord(int coord); +extern AGS_INLINE int data_to_game_coord(int coord); +extern AGS_INLINE void data_to_game_coords(int *x, int *y); +extern AGS_INLINE int get_fixed_pixel_size(int pixels); + +// Those function have distinct implementations in Engine and Editor +extern void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); +extern int wgettextwidth_compensate(Common::Bitmap *ds, const char *tex, int font) ; +extern void check_font(int *fontnum); + +extern void set_our_eip(int eip); +#define SET_EIP(x) set_our_eip(x); +extern void set_eip_guiobj(int eip); +extern int get_eip_guiobj(); + +extern bool outlineGuiObjects; + +#endif // __AC_GUIMAIN_H diff --git a/engines/ags/shared/gui/guiobject.cpp b/engines/ags/shared/gui/guiobject.cpp new file mode 100644 index 000000000000..0e14b0ce590d --- /dev/null +++ b/engines/ags/shared/gui/guiobject.cpp @@ -0,0 +1,214 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/common.h" // quit +#include "gui/guimain.h" +#include "gui/guiobject.h" +#include "util/stream.h" + +namespace AGS +{ +namespace Common +{ + +GUIObject::GUIObject() +{ + Id = 0; + ParentId = 0; + Flags = kGUICtrl_DefFlags; + X = 0; + Y = 0; + Width = 0; + Height = 0; + ZOrder = -1; + IsActivated = false; + _scEventCount = 0; +} + +int GUIObject::GetEventCount() const +{ + return _scEventCount; +} + +String GUIObject::GetEventName(int event) const +{ + if (event < 0 || event >= _scEventCount) + return ""; + return _scEventNames[event]; +} + +String GUIObject::GetEventArgs(int event) const +{ + if (event < 0 || event >= _scEventCount) + return ""; + return _scEventArgs[event]; +} + +bool GUIObject::IsDeleted() const +{ + return (Flags & kGUICtrl_Deleted) != 0; +} + +bool GUIObject::IsEnabled() const +{ + return (Flags & kGUICtrl_Enabled) != 0; +} + +bool GUIObject::IsOverControl(int x, int y, int leeway) const +{ + return x >= X && y >= Y && x < (X + Width + leeway) && y < (Y + Height + leeway); +} + +bool GUIObject::IsTranslated() const +{ + return (Flags & kGUICtrl_Translated) != 0; +} + +bool GUIObject::IsVisible() const +{ + return (Flags & kGUICtrl_Visible) != 0; +} + +void GUIObject::SetClickable(bool on) +{ + if (on) + Flags |= kGUICtrl_Clickable; + else + Flags &= ~kGUICtrl_Clickable; +} + +void GUIObject::SetEnabled(bool on) +{ + if (on) + Flags |= kGUICtrl_Enabled; + else + Flags &= ~kGUICtrl_Enabled; +} + +void GUIObject::SetTranslated(bool on) +{ + if (on) + Flags |= kGUICtrl_Translated; + else + Flags &= ~kGUICtrl_Translated; +} + +void GUIObject::SetVisible(bool on) +{ + if (on) + Flags |= kGUICtrl_Visible; + else + Flags &= ~kGUICtrl_Visible; +} + +// TODO: replace string serialization with StrUtil::ReadString and WriteString +// methods in the future, to keep this organized. +void GUIObject::WriteToFile(Stream *out) const +{ + out->WriteInt32(Flags); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(ZOrder); + Name.Write(out); + out->WriteInt32(_scEventCount); + for (int i = 0; i < _scEventCount; ++i) + EventHandlers[i].Write(out); +} + +void GUIObject::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + Flags = in->ReadInt32(); + // reverse particular flags from older format + if (gui_version < kGuiVersion_350) + Flags ^= kGUICtrl_OldFmtXorMask; + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + ZOrder = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + { // NOTE: reading into actual variables only for old savegame support + IsActivated = in->ReadInt32() != 0; + } + + if (gui_version >= kGuiVersion_unkn_106) + Name.Read(in); + else + Name.Free(); + + for (int i = 0; i < _scEventCount; ++i) + { + EventHandlers[i].Free(); + } + + if (gui_version >= kGuiVersion_unkn_108) + { + int evt_count = in->ReadInt32(); + if (evt_count > _scEventCount) + quit("Error: too many control events, need newer version"); + for (int i = 0; i < evt_count; ++i) + { + EventHandlers[i].Read(in); + } + } +} + +void GUIObject::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) +{ + // Properties + Flags = in->ReadInt32(); + // reverse particular flags from older format + if (svg_ver < kGuiSvgVersion_350) + Flags ^= kGUICtrl_OldFmtXorMask; + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + ZOrder = in->ReadInt32(); + // Dynamic state + IsActivated = in->ReadBool() ? 1 : 0; +} + +void GUIObject::WriteToSavegame(Stream *out) const +{ + // Properties + out->WriteInt32(Flags); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(ZOrder); + // Dynamic state + out->WriteBool(IsActivated != 0); +} + + +HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align) +{ + switch (align) + { + case kLegacyGUIAlign_Left: + return kHAlignLeft; + case kLegacyGUIAlign_Right: + return kHAlignRight; + case kLegacyGUIAlign_Center: + return kHAlignCenter; + } + return kHAlignNone; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h new file mode 100644 index 000000000000..4067a1b8985f --- /dev/null +++ b/engines/ags/shared/gui/guiobject.h @@ -0,0 +1,126 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUIOBJECT_H +#define __AC_GUIOBJECT_H + +#include "core/types.h" +#include "gfx/bitmap.h" +#include "gui/guidefines.h" +#include "util/string.h" + +#define GUIDIS_GREYOUT 1 +#define GUIDIS_BLACKOUT 2 +#define GUIDIS_UNCHANGED 4 +#define GUIDIS_GUIOFF 0x80 + + + + +namespace AGS +{ +namespace Common +{ + +enum LegacyGUIAlignment +{ + kLegacyGUIAlign_Left = 0, + kLegacyGUIAlign_Right = 1, + kLegacyGUIAlign_Center = 2 +}; + +class GUIObject +{ +public: + GUIObject(); + virtual ~GUIObject() = default; + + String GetEventArgs(int event) const; + int GetEventCount() const; + String GetEventName(int event) const; + bool IsDeleted() const; + // tells if control itself is enabled + bool IsEnabled() const; + // overridable routine to determine whether the mouse is over the control + virtual bool IsOverControl(int x, int y, int leeway) const; + bool IsTranslated() const; + bool IsVisible() const; + // implemented separately in engine and editor + bool IsClickable() const; + + // Operations + virtual void Draw(Bitmap *ds) { } + void SetClickable(bool on); + void SetEnabled(bool on); + void SetTranslated(bool on); + void SetVisible(bool on); + + // Events + // Key pressed for control + virtual void OnKeyPress(int keycode) { } + // Mouse button down - return 'True' to lock focus + virtual bool OnMouseDown() { return false; } + // Mouse moves onto control + virtual void OnMouseEnter() { } + // Mouse moves off control + virtual void OnMouseLeave() { } + // Mouse moves over control - x,y relative to gui + virtual void OnMouseMove(int x, int y) { } + // Mouse button up + virtual void OnMouseUp() { } + // Control was resized + virtual void OnResized() { } + + // Serialization + virtual void ReadFromFile(Common::Stream *in, GuiVersion gui_version); + virtual void WriteToFile(Common::Stream *out) const; + virtual void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver); + virtual void WriteToSavegame(Common::Stream *out) const; + +// TODO: these members are currently public; hide them later +public: + int32_t Id; // GUI object's identifier + int32_t ParentId; // id of parent GUI + String Name; // script name + + int32_t X; + int32_t Y; + int32_t Width; + int32_t Height; + int32_t ZOrder; + bool IsActivated; // signals user interaction + + String EventHandlers[MAX_GUIOBJ_EVENTS]; // script function names + +protected: + uint32_t Flags; // generic style and behavior flags + + // TODO: explicit event names & handlers for every event + int32_t _scEventCount; // number of supported script events + String _scEventNames[MAX_GUIOBJ_EVENTS]; // script event names + String _scEventArgs[MAX_GUIOBJ_EVENTS]; // script handler params +}; + +// Converts legacy alignment type used in GUI Label/ListBox data (only left/right/center) +HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align); + +} // namespace Common +} // namespace AGS + +// Tells if all controls are disabled +extern int all_buttons_disabled; +// Tells if the given control is considered enabled, taking global flag into account +inline bool IsGUIEnabled(AGS::Common::GUIObject *g) { return !all_buttons_disabled && g->IsEnabled(); } + +#endif // __AC_GUIOBJECT_H diff --git a/engines/ags/shared/gui/guislider.cpp b/engines/ags/shared/gui/guislider.cpp new file mode 100644 index 000000000000..492f70b41f0c --- /dev/null +++ b/engines/ags/shared/gui/guislider.cpp @@ -0,0 +1,267 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "ac/spritecache.h" +#include "gui/guimain.h" +#include "gui/guislider.h" +#include "util/stream.h" + +std::vector guislider; +int numguislider = 0; + +namespace AGS +{ +namespace Common +{ + +GUISlider::GUISlider() +{ + MinValue = 0; + MaxValue = 10; + Value = 0; + BgImage = 0; + HandleImage = 0; + HandleOffset = 0; + IsMousePressed = false; + + _scEventCount = 1; + _scEventNames[0] = "Change"; + _scEventArgs[0] = "GUIControl *control"; +} + +bool GUISlider::IsHorizontal() const +{ + return Width > Height; +} + +bool GUISlider::IsOverControl(int X, int Y, int leeway) const +{ + // check the overall boundary + if (GUIObject::IsOverControl(X, Y, leeway)) + return true; + // now check the handle too + return _cachedHandle.IsInside(Point(X, Y)); +} + +void GUISlider::Draw(Common::Bitmap *ds) +{ + Rect bar; + Rect handle; + int thickness; + + if (MinValue >= MaxValue) + MaxValue = MinValue + 1; + Value = Math::Clamp(Value, MinValue, MaxValue); + + // it's a horizontal slider + if (IsHorizontal()) + { + thickness = Height / 3; + bar.Left = X + 1; + bar.Top = Y + Height / 2 - thickness; + bar.Right = X + Width - 1; + bar.Bottom = Y + Height / 2 + thickness + 1; + handle.Left = (int)(((float)(Value - MinValue) / (float)(MaxValue - MinValue)) * (float)(Width - 4) - 2) + bar.Left + 1; + handle.Top = bar.Top - (thickness - 1); + handle.Right = handle.Left + get_fixed_pixel_size(4); + handle.Bottom = bar.Bottom + (thickness - 1); + if (HandleImage > 0) + { + // store the centre of the pic rather than the top + handle.Top = bar.Top + (bar.Bottom - bar.Top) / 2 + get_fixed_pixel_size(1); + handle.Left += get_fixed_pixel_size(2); + } + handle.Top += data_to_game_coord(HandleOffset); + handle.Bottom += data_to_game_coord(HandleOffset); + } + // vertical slider + else + { + thickness = Width / 3; + bar.Left = X + Width / 2 - thickness; + bar.Top = Y + 1; + bar.Right = X + Width / 2 + thickness + 1; + bar.Bottom = Y + Height - 1; + handle.Top = (int)(((float)(MaxValue - Value) / (float)(MaxValue - MinValue)) * (float)(Height - 4) - 2) + bar.Top + 1; + handle.Left = bar.Left - (thickness - 1); + handle.Bottom = handle.Top + get_fixed_pixel_size(4); + handle.Right = bar.Right + (thickness - 1); + if (HandleImage > 0) + { + // store the centre of the pic rather than the left + handle.Left = bar.Left + (bar.Right - bar.Left) / 2 + get_fixed_pixel_size(1); + handle.Top += get_fixed_pixel_size(2); + } + handle.Left += data_to_game_coord(HandleOffset); + handle.Right += data_to_game_coord(HandleOffset); + } + + color_t draw_color; + if (BgImage > 0) + { + // tiled image as slider background + int x_inc = 0; + int y_inc = 0; + if (IsHorizontal()) + { + x_inc = get_adjusted_spritewidth(BgImage); + // centre the image vertically + bar.Top = Y + (Height / 2) - get_adjusted_spriteheight(BgImage) / 2; + } + else + { + y_inc = get_adjusted_spriteheight(BgImage); + // centre the image horizontally + bar.Left = X + (Width / 2) - get_adjusted_spritewidth(BgImage) / 2; + } + int cx = bar.Left; + int cy = bar.Top; + // draw the tiled background image + do + { + draw_gui_sprite(ds, BgImage, cx, cy, true); + cx += x_inc; + cy += y_inc; + // done as a do..while so that at least one of the image is drawn + } + while ((cx + x_inc <= bar.Right) && (cy + y_inc <= bar.Bottom)); + } + else + { + // normal grey background + draw_color = ds->GetCompatibleColor(16); + ds->FillRect(Rect(bar.Left + 1, bar.Top + 1, bar.Right - 1, bar.Bottom - 1), draw_color); + draw_color = ds->GetCompatibleColor(8); + ds->DrawLine(Line(bar.Left, bar.Top, bar.Left, bar.Bottom), draw_color); + ds->DrawLine(Line(bar.Left, bar.Top, bar.Right, bar.Top), draw_color); + draw_color = ds->GetCompatibleColor(15); + ds->DrawLine(Line(bar.Right, bar.Top + 1, bar.Right, bar.Bottom), draw_color); + ds->DrawLine(Line(bar.Left, bar.Bottom, bar.Right, bar.Bottom), draw_color); + } + + if (HandleImage > 0) + { + // an image for the slider handle + // TODO: react to sprites initialization/deletion instead! + if (spriteset[HandleImage] == nullptr) + HandleImage = 0; + + handle.Left -= get_adjusted_spritewidth(HandleImage) / 2; + handle.Top -= get_adjusted_spriteheight(HandleImage) / 2; + draw_gui_sprite(ds, HandleImage, handle.Left, handle.Top, true); + handle.Right = handle.Left + get_adjusted_spritewidth(HandleImage); + handle.Bottom = handle.Top + get_adjusted_spriteheight(HandleImage); + } + else + { + // normal grey tracker handle + draw_color = ds->GetCompatibleColor(7); + ds->FillRect(Rect(handle.Left, handle.Top, handle.Right, handle.Bottom), draw_color); + draw_color = ds->GetCompatibleColor(15); + ds->DrawLine(Line(handle.Left, handle.Top, handle.Right, handle.Top), draw_color); + ds->DrawLine(Line(handle.Left, handle.Top, handle.Left, handle.Bottom), draw_color); + draw_color = ds->GetCompatibleColor(16); + ds->DrawLine(Line(handle.Right, handle.Top + 1, handle.Right, handle.Bottom), draw_color); + ds->DrawLine(Line(handle.Left + 1, handle.Bottom, handle.Right, handle.Bottom), draw_color); + } + + _cachedHandle = handle; +} + +bool GUISlider::OnMouseDown() +{ + IsMousePressed = true; + // lock focus to ourselves + return true; +} + +void GUISlider::OnMouseMove(int x, int y) +{ + if (!IsMousePressed) + return; + + if (IsHorizontal()) + Value = (int)(((float)((x - X) - 2) / (float)(Width - 4)) * (float)(MaxValue - MinValue)) + MinValue; + else + Value = (int)(((float)(((Y + Height) - y) - 2) / (float)(Height - 4)) * (float)(MaxValue - MinValue)) + MinValue; + + Value = Math::Clamp(Value, MinValue, MaxValue); + guis_need_update = 1; + IsActivated = true; +} + +void GUISlider::OnMouseUp() +{ + IsMousePressed = false; +} + +void GUISlider::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + GUIObject::ReadFromFile(in, gui_version); + MinValue = in->ReadInt32(); + MaxValue = in->ReadInt32(); + Value = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + { // NOTE: reading into actual variables only for old savegame support + IsMousePressed = in->ReadInt32() != 0; + } + if (gui_version >= kGuiVersion_unkn_104) + { + HandleImage = in->ReadInt32(); + HandleOffset = in->ReadInt32(); + BgImage = in->ReadInt32(); + } + else + { + HandleImage = -1; + HandleOffset = 0; + BgImage = 0; + } +} + +void GUISlider::WriteToFile(Stream *out) const +{ + GUIObject::WriteToFile(out); + out->WriteInt32(MinValue); + out->WriteInt32(MaxValue); + out->WriteInt32(Value); + out->WriteInt32(HandleImage); + out->WriteInt32(HandleOffset); + out->WriteInt32(BgImage); +} + +void GUISlider::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) +{ + GUIObject::ReadFromSavegame(in, svg_ver); + BgImage = in->ReadInt32(); + HandleImage = in->ReadInt32(); + HandleOffset = in->ReadInt32(); + MinValue = in->ReadInt32(); + MaxValue = in->ReadInt32(); + Value = in->ReadInt32(); +} + +void GUISlider::WriteToSavegame(Stream *out) const +{ + GUIObject::WriteToSavegame(out); + out->WriteInt32(BgImage); + out->WriteInt32(HandleImage); + out->WriteInt32(HandleOffset); + out->WriteInt32(MinValue); + out->WriteInt32(MaxValue); + out->WriteInt32(Value); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h new file mode 100644 index 000000000000..86078a29e05d --- /dev/null +++ b/engines/ags/shared/gui/guislider.h @@ -0,0 +1,71 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUISLIDER_H +#define __AC_GUISLIDER_H + +#include +#include "gui/guiobject.h" + +namespace AGS +{ +namespace Common +{ + +class GUISlider : public GUIObject +{ +public: + GUISlider(); + + // Tells if the slider is horizontal (otherwise - vertical) + bool IsHorizontal() const; + bool IsOverControl(int x, int y, int leeway) const override; + + // Operations + void Draw(Bitmap *ds) override; + + // Events + bool OnMouseDown() override; + void OnMouseMove(int xp, int yp) override; + void OnMouseUp() override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; + +// TODO: these members are currently public; hide them later +public: + int32_t MinValue; + int32_t MaxValue; + int32_t Value; + int32_t BgImage; + int32_t HandleImage; + int32_t HandleOffset; + bool IsMousePressed; + +private: + // The following variables are not persisted on disk + // Cached coordinates of slider handle + Rect _cachedHandle; +}; + +} // namespace Common +} // namespace AGS + +extern std::vector guislider; +extern int numguislider; + +#endif // __AC_GUISLIDER_H diff --git a/engines/ags/shared/gui/guitextbox.cpp b/engines/ags/shared/gui/guitextbox.cpp new file mode 100644 index 000000000000..5e05e289d6a8 --- /dev/null +++ b/engines/ags/shared/gui/guitextbox.cpp @@ -0,0 +1,146 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "font/fonts.h" +#include "gui/guimain.h" +#include "gui/guitextbox.h" +#include "util/stream.h" +#include "util/string_utils.h" + +#define GUITEXTBOX_LEGACY_TEXTLEN 200 + +std::vector guitext; +int numguitext = 0; + +namespace AGS +{ +namespace Common +{ + +GUITextBox::GUITextBox() +{ + Font = 0; + TextColor = 0; + TextBoxFlags = kTextBox_DefFlags; + + _scEventCount = 1; + _scEventNames[0] = "Activate"; + _scEventArgs[0] = "GUIControl *control"; +} + +bool GUITextBox::IsBorderShown() const +{ + return (TextBoxFlags & kTextBox_ShowBorder) != 0; +} + +void GUITextBox::Draw(Bitmap *ds) +{ + check_font(&Font); + color_t text_color = ds->GetCompatibleColor(TextColor); + color_t draw_color = ds->GetCompatibleColor(TextColor); + if (IsBorderShown()) + { + ds->DrawRect(RectWH(X, Y, Width, Height), draw_color); + if (get_fixed_pixel_size(1) > 1) + { + ds->DrawRect(Rect(X + 1, Y + 1, X + Width - get_fixed_pixel_size(1), Y + Height - get_fixed_pixel_size(1)), draw_color); + } + } + DrawTextBoxContents(ds, text_color); +} + +void GUITextBox::OnKeyPress(int keycode) +{ + guis_need_update = 1; + // TODO: use keycode constants + // backspace, remove character + if (keycode == 8) + { + Text.ClipRight(1); + return; + } + // other key, continue + if ((keycode >= 128) && (!font_supports_extended_characters(Font))) + return; + // return/enter + if (keycode == 13) + { + IsActivated = true; + return; + } + + Text.AppendChar(keycode); + // if the new string is too long, remove the new character + if (wgettextwidth(Text, Font) > (Width - (6 + get_fixed_pixel_size(5)))) + Text.ClipRight(1); +} + +void GUITextBox::SetShowBorder(bool on) +{ + if (on) + TextBoxFlags |= kTextBox_ShowBorder; + else + TextBoxFlags &= ~kTextBox_ShowBorder; +} + +// TODO: replace string serialization with StrUtil::ReadString and WriteString +// methods in the future, to keep this organized. +void GUITextBox::WriteToFile(Stream *out) const +{ + GUIObject::WriteToFile(out); + StrUtil::WriteString(Text, out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(TextBoxFlags); +} + +void GUITextBox::ReadFromFile(Stream *in, GuiVersion gui_version) +{ + GUIObject::ReadFromFile(in, gui_version); + if (gui_version < kGuiVersion_350) + Text.ReadCount(in, GUITEXTBOX_LEGACY_TEXTLEN); + else + Text = StrUtil::ReadString(in); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + TextBoxFlags = in->ReadInt32(); + // reverse particular flags from older format + if (gui_version < kGuiVersion_350) + TextBoxFlags ^= kTextBox_OldFmtXorMask; + + if (TextColor == 0) + TextColor = 16; +} + +void GUITextBox::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) +{ + GUIObject::ReadFromSavegame(in, svg_ver); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + Text = StrUtil::ReadString(in); + if (svg_ver >= kGuiSvgVersion_350) + TextBoxFlags = in->ReadInt32(); +} + +void GUITextBox::WriteToSavegame(Stream *out) const +{ + GUIObject::WriteToSavegame(out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + StrUtil::WriteString(Text, out); + out->WriteInt32(TextBoxFlags); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h new file mode 100644 index 000000000000..cdbad55ad856 --- /dev/null +++ b/engines/ags/shared/gui/guitextbox.h @@ -0,0 +1,65 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_GUITEXTBOX_H +#define __AC_GUITEXTBOX_H + +#include +#include "gui/guiobject.h" +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +class GUITextBox : public GUIObject +{ +public: + GUITextBox(); + + bool IsBorderShown() const; + + // Operations + void Draw(Bitmap *ds) override; + void SetShowBorder(bool on); + + // Events + void OnKeyPress(int keycode) override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; + +// TODO: these members are currently public; hide them later +public: + int32_t Font; + String Text; + color_t TextColor; + +private: + int32_t TextBoxFlags; + + void DrawTextBoxContents(Bitmap *ds, color_t text_color); +}; + +} // namespace Common +} // namespace AGS + +extern std::vector guitext; +extern int numguitext; + +#endif // __AC_GUITEXTBOX_H diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp new file mode 100644 index 000000000000..8f420b905896 --- /dev/null +++ b/engines/ags/shared/script/cc_error.cpp @@ -0,0 +1,63 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "script/script_common.h" // current_line +#include "util/string.h" + +using namespace AGS::Common; + +// Returns full script error message and callstack (if possible) +extern std::pair cc_error_at_line(const char *error_msg); +// Returns script error message without location or callstack +extern String cc_error_without_line(const char *error_msg); + +int ccError = 0; +int ccErrorLine = 0; +String ccErrorString; +String ccErrorCallStack; +bool ccErrorIsUserError = false; +const char *ccCurScriptName = ""; + +void cc_error(const char *descr, ...) +{ + ccErrorIsUserError = false; + if (descr[0] == '!') + { + ccErrorIsUserError = true; + descr++; + } + + va_list ap; + va_start(ap, descr); + String displbuf = String::FromFormatV(descr, ap); + va_end(ap); + + if (currentline > 0) + { + // [IKM] Implementation is project-specific + std::pair errinfo = cc_error_at_line(displbuf); + ccErrorString = errinfo.first; + ccErrorCallStack = errinfo.second; + } + else + { + ccErrorString = cc_error_without_line(displbuf); + ccErrorCallStack = ""; + } + + ccError = 1; + ccErrorLine = currentline; +} diff --git a/engines/ags/shared/script/cc_error.h b/engines/ags/shared/script/cc_error.h new file mode 100644 index 000000000000..4b322379d102 --- /dev/null +++ b/engines/ags/shared/script/cc_error.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// 'C'-style script compiler +// +//============================================================================= + +#ifndef __CC_ERROR_H +#define __CC_ERROR_H + +#include "util/string.h" + +extern void cc_error(const char *, ...); + +// error reporting +extern int ccError; // set to non-zero if error occurs +extern int ccErrorLine; // line number of the error +extern AGS::Common::String ccErrorString; // description of the error +extern AGS::Common::String ccErrorCallStack; // callstack where error happened +extern bool ccErrorIsUserError; +extern const char *ccCurScriptName; // name of currently compiling script + +#endif // __CC_ERROR_H diff --git a/engines/ags/shared/script/cc_options.cpp b/engines/ags/shared/script/cc_options.cpp new file mode 100644 index 000000000000..556fdc7e798f --- /dev/null +++ b/engines/ags/shared/script/cc_options.cpp @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "cc_options.h" + +int ccCompOptions = SCOPT_LEFTTORIGHT; + +void ccSetOption(int optbit, int onoroff) +{ + if (onoroff) + ccCompOptions |= optbit; + else + ccCompOptions &= ~optbit; +} + +int ccGetOption(int optbit) +{ + if (ccCompOptions & optbit) + return 1; + + return 0; +} diff --git a/engines/ags/shared/script/cc_options.h b/engines/ags/shared/script/cc_options.h new file mode 100644 index 000000000000..fd179605d4db --- /dev/null +++ b/engines/ags/shared/script/cc_options.h @@ -0,0 +1,34 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// 'C'-style script compiler +// +//============================================================================= + +#ifndef __CC_OPTIONS_H +#define __CC_OPTIONS_H + +#define SCOPT_EXPORTALL 1 // export all functions automatically +#define SCOPT_SHOWWARNINGS 2 // printf warnings to console +#define SCOPT_LINENUMBERS 4 // include line numbers in compiled code +#define SCOPT_AUTOIMPORT 8 // when creating instance, export funcs to other scripts +#define SCOPT_DEBUGRUN 0x10 // write instructions as they are procssed to log file +#define SCOPT_NOIMPORTOVERRIDE 0x20 // do not allow an import to be re-declared +#define SCOPT_LEFTTORIGHT 0x40 // left-to-right operator precedance +#define SCOPT_OLDSTRINGS 0x80 // allow old-style strings + +extern void ccSetOption(int, int); +extern int ccGetOption(int); + +#endif diff --git a/engines/ags/shared/script/cc_script.cpp b/engines/ags/shared/script/cc_script.cpp new file mode 100644 index 000000000000..b2383e21c2d4 --- /dev/null +++ b/engines/ags/shared/script/cc_script.cpp @@ -0,0 +1,404 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "script/cc_error.h" +#include "script/cc_script.h" +#include "script/script_common.h" +#include "util/stream.h" +#include "util/string_compat.h" + +using AGS::Common::Stream; + +// currently executed line +int currentline; +// script file format signature +const char scfilesig[5] = "SCOM"; + +// [IKM] I reckon this function is almost identical to fgetstring in string_utils +void freadstring(char **strptr, Stream *in) +{ + static char ibuffer[300]; + int idxx = 0; + + while ((ibuffer[idxx] = in->ReadInt8()) != 0) + idxx++; + + if (ibuffer[0] == 0) { + strptr[0] = nullptr; + return; + } + + strptr[0] = (char *)malloc(strlen(ibuffer) + 1); + strcpy(strptr[0], ibuffer); +} + +void fwritestring(const char *strptr, Stream *out) +{ + if(strptr == nullptr){ + out->WriteByte(0); + } else { + out->Write(strptr, strlen(strptr) + 1); + } +} + +ccScript *ccScript::CreateFromStream(Stream *in) +{ + ccScript *scri = new ccScript(); + if (!scri->Read(in)) + { + delete scri; + return nullptr; + } + return scri; +} + +ccScript::ccScript() +{ + globaldata = nullptr; + globaldatasize = 0; + code = nullptr; + codesize = 0; + strings = nullptr; + stringssize = 0; + fixuptypes = nullptr; + fixups = nullptr; + numfixups = 0; + importsCapacity = 0; + imports = nullptr; + numimports = 0; + exportsCapacity = 0; + exports = nullptr; + export_addr = nullptr; + numexports = 0; + instances = 0; + sectionNames = nullptr; + sectionOffsets = nullptr; + numSections = 0; + capacitySections = 0; +} + +ccScript::ccScript(const ccScript &src) +{ + globaldatasize = src.globaldatasize; + if (globaldatasize > 0) + { + globaldata = (char*)malloc(globaldatasize); + memcpy(globaldata, src.globaldata, globaldatasize); + } + else + { + globaldata = nullptr; + } + + codesize = src.codesize; + if (codesize > 0) + { + code = (int32_t*)malloc(codesize * sizeof(int32_t)); + memcpy(code, src.code, sizeof(int32_t) * codesize); + } + else + { + code = nullptr; + } + + stringssize = src.stringssize; + if (stringssize > 0) + { + strings = (char*)malloc(stringssize); + memcpy(strings, src.strings, stringssize); + } + else + { + strings = nullptr; + } + + numfixups = src.numfixups; + if (numfixups > 0) + { + fixuptypes = (char*)malloc(numfixups); + fixups = (int32_t*)malloc(numfixups * sizeof(int32_t)); + memcpy(fixuptypes, src.fixuptypes, numfixups); + memcpy(fixups, src.fixups, numfixups * sizeof(int32_t)); + } + else + { + fixups = nullptr; + fixuptypes = nullptr; + } + + importsCapacity = src.numimports; + numimports = src.numimports; + if (numimports > 0) + { + imports = (char**)malloc(sizeof(char*) * numimports); + for (int i = 0; i < numimports; ++i) + imports[i] = ags_strdup(src.imports[i]); + } + else + { + imports = nullptr; + } + + exportsCapacity = src.numexports; + numexports = src.numexports; + if (numexports > 0) + { + exports = (char**)malloc(sizeof(char*) * numexports); + export_addr = (int32_t*)malloc(sizeof(int32_t) * numexports); + for (int i = 0; i < numexports; ++i) + { + exports[i] = ags_strdup(src.exports[i]); + export_addr[i] = src.export_addr[i]; + } + } + else + { + exports = nullptr; + export_addr = nullptr; + } + + capacitySections = src.numSections; + numSections = src.numSections; + if (numSections > 0) + { + sectionNames = (char**)malloc(numSections * sizeof(char*)); + sectionOffsets = (int32_t*)malloc(numSections * sizeof(int32_t)); + for (int i = 0; i < numSections; ++i) + { + sectionNames[i] = ags_strdup(src.sectionNames[i]); + sectionOffsets[i] = src.sectionOffsets[i]; + } + } + else + { + numSections = 0; + sectionNames = nullptr; + sectionOffsets = nullptr; + } + + instances = 0; +} + +ccScript::~ccScript() +{ + Free(); +} + +void ccScript::Write(Stream *out) { + int n; + out->Write(scfilesig,4); + out->WriteInt32(SCOM_VERSION); + out->WriteInt32(globaldatasize); + out->WriteInt32(codesize); + out->WriteInt32(stringssize); + if (globaldatasize > 0) + out->WriteArray(globaldata,globaldatasize,1); + if (codesize > 0) + out->WriteArrayOfInt32(code,codesize); + if (stringssize > 0) + out->WriteArray(strings,stringssize,1); + out->WriteInt32(numfixups); + if (numfixups > 0) { + out->WriteArray(fixuptypes,numfixups,1); + out->WriteArrayOfInt32(fixups,numfixups); + } + out->WriteInt32(numimports); + for (n=0;nWriteInt32(numexports); + for (n=0;nWriteInt32(export_addr[n]); + } + out->WriteInt32(numSections); + for (n = 0; n < numSections; n++) { + fwritestring(sectionNames[n], out); + out->WriteInt32(sectionOffsets[n]); + } + out->WriteInt32(ENDFILESIG); +} + +bool ccScript::Read(Stream *in) +{ + instances = 0; + int n; + char gotsig[5]; + currentline = -1; + // MACPORT FIX: swap 'size' and 'nmemb' + in->Read(gotsig, 4); + gotsig[4] = 0; + + int fileVer = in->ReadInt32(); + + if ((strcmp(gotsig, scfilesig) != 0) || (fileVer > SCOM_VERSION)) { + cc_error("file was not written by ccScript::Write or seek position is incorrect"); + return false; + } + + globaldatasize = in->ReadInt32(); + codesize = in->ReadInt32(); + stringssize = in->ReadInt32(); + + if (globaldatasize > 0) { + globaldata = (char *)malloc(globaldatasize); + // MACPORT FIX: swap + in->Read(globaldata, globaldatasize); + } + else + globaldata = nullptr; + + if (codesize > 0) { + code = (int32_t *)malloc(codesize * sizeof(int32_t)); + // MACPORT FIX: swap + + // 64 bit: Read code into 8 byte array, necessary for being able to perform + // relocations on the references. + in->ReadArrayOfInt32(code, codesize); + } + else + code = nullptr; + + if (stringssize > 0) { + strings = (char *)malloc(stringssize); + // MACPORT FIX: swap + in->Read(strings, stringssize); + } + else + strings = nullptr; + + numfixups = in->ReadInt32(); + if (numfixups > 0) { + fixuptypes = (char *)malloc(numfixups); + fixups = (int32_t *)malloc(numfixups * sizeof(int32_t)); + // MACPORT FIX: swap 'size' and 'nmemb' + in->Read(fixuptypes, numfixups); + in->ReadArrayOfInt32(fixups, numfixups); + } + else { + fixups = nullptr; + fixuptypes = nullptr; + } + + numimports = in->ReadInt32(); + + imports = (char**)malloc(sizeof(char*) * numimports); + for (n = 0; n < numimports; n++) + freadstring(&imports[n], in); + + numexports = in->ReadInt32(); + exports = (char**)malloc(sizeof(char*) * numexports); + export_addr = (int32_t*)malloc(sizeof(int32_t) * numexports); + for (n = 0; n < numexports; n++) { + freadstring(&exports[n], in); + export_addr[n] = in->ReadInt32(); + } + + if (fileVer >= 83) { + // read in the Sections + numSections = in->ReadInt32(); + sectionNames = (char**)malloc(numSections * sizeof(char*)); + sectionOffsets = (int32_t*)malloc(numSections * sizeof(int32_t)); + for (n = 0; n < numSections; n++) { + freadstring(§ionNames[n], in); + sectionOffsets[n] = in->ReadInt32(); + } + } + else + { + numSections = 0; + sectionNames = nullptr; + sectionOffsets = nullptr; + } + + if (in->ReadInt32() != ENDFILESIG) { + cc_error("internal error rebuilding script"); + return false; + } + return true; +} + +void ccScript::Free() +{ + if (globaldata != nullptr) + free(globaldata); + + if (code != nullptr) + free(code); + + if (strings != nullptr) + free(strings); + + if (fixups != nullptr && numfixups > 0) + free(fixups); + + if (fixuptypes != nullptr && numfixups > 0) + free(fixuptypes); + + globaldata = nullptr; + code = nullptr; + strings = nullptr; + fixups = nullptr; + fixuptypes = nullptr; + + int aa; + for (aa = 0; aa < numimports; aa++) { + if (imports[aa] != nullptr) + free(imports[aa]); + } + + for (aa = 0; aa < numexports; aa++) + free(exports[aa]); + + for (aa = 0; aa < numSections; aa++) + free(sectionNames[aa]); + + if (sectionNames != nullptr) + { + free(sectionNames); + free(sectionOffsets); + sectionNames = nullptr; + sectionOffsets = nullptr; + } + + if (imports != nullptr) + { + free(imports); + free(exports); + free(export_addr); + imports = nullptr; + exports = nullptr; + export_addr = nullptr; + } + numimports = 0; + numexports = 0; + numSections = 0; +} + +const char* ccScript::GetSectionName(int32_t offs) { + + int i; + for (i = 0; i < numSections; i++) { + if (sectionOffsets[i] < offs) + continue; + break; + } + + // if no sections in script, return unknown + if (i == 0) + return "(unknown section)"; + + return sectionNames[i - 1]; +} diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h new file mode 100644 index 000000000000..e422893af795 --- /dev/null +++ b/engines/ags/shared/script/cc_script.h @@ -0,0 +1,75 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// 'C'-style script compiler +// +//============================================================================= + +#ifndef __CC_SCRIPT_H +#define __CC_SCRIPT_H + +#include +#include "core/types.h" + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +struct ccScript +{ +public: + char *globaldata; + int32_t globaldatasize; + int32_t *code; // executable byte-code, 32-bit per op or arg + int32_t codesize; // TODO: find out if we can make it size_t + char *strings; + int32_t stringssize; + char *fixuptypes; // global data/string area/ etc + int32_t *fixups; // code array index to fixup (in ints) + int numfixups; + int importsCapacity; + char **imports; + int numimports; + int exportsCapacity; + char **exports; // names of exports + int32_t *export_addr; // high byte is type; low 24-bits are offset + int numexports; + int instances; + // 'sections' allow the interpreter to find out which bit + // of the code came from header files, and which from the main file + char **sectionNames; + int32_t *sectionOffsets; + int numSections; + int capacitySections; + + static ccScript *CreateFromStream(Common::Stream *in); + + ccScript(); + ccScript(const ccScript &src); + virtual ~ccScript(); // there are few derived classes, so dtor should be virtual + + // write the script to disk (after compiling) + void Write(Common::Stream *out); + // read back a script written with Write + bool Read(Common::Stream *in); + const char* GetSectionName(int32_t offset); + +protected: + // free the memory occupied by the script - do NOT attempt to run the + // script after calling this function + void Free(); +}; + +typedef std::shared_ptr PScript; + +#endif // __CC_SCRIPT_H diff --git a/engines/ags/shared/script/script_common.h b/engines/ags/shared/script/script_common.h new file mode 100644 index 000000000000..5dcf0b5d7d26 --- /dev/null +++ b/engines/ags/shared/script/script_common.h @@ -0,0 +1,131 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// 'C'-style script compiler +// +//============================================================================= + +#ifndef __CS_COMMON_H +#define __CS_COMMON_H + +#define SCOM_VERSION 90 +#define SCOM_VERSIONSTR "0.90" + +// virtual CPU registers +#define SREG_SP 1 // stack pointer +#define SREG_MAR 2 // memory address register +#define SREG_AX 3 // general purpose +#define SREG_BX 4 +#define SREG_CX 5 +#define SREG_OP 6 // object pointer for member func calls +#define SREG_DX 7 +#define CC_NUM_REGISTERS 8 + +// virtual CPU commands +#define SCMD_ADD 1 // reg1 += arg2 +#define SCMD_SUB 2 // reg1 -= arg2 +#define SCMD_REGTOREG 3 // reg2 = reg1 +#define SCMD_WRITELIT 4 // m[MAR] = arg2 (copy arg1 bytes) +#define SCMD_RET 5 // return from subroutine +#define SCMD_LITTOREG 6 // set reg1 to literal value arg2 +#define SCMD_MEMREAD 7 // reg1 = m[MAR] +#define SCMD_MEMWRITE 8 // m[MAR] = reg1 +#define SCMD_MULREG 9 // reg1 *= reg2 +#define SCMD_DIVREG 10 // reg1 /= reg2 +#define SCMD_ADDREG 11 // reg1 += reg2 +#define SCMD_SUBREG 12 // reg1 -= reg2 +#define SCMD_BITAND 13 // bitwise reg1 & reg2 +#define SCMD_BITOR 14 // bitwise reg1 | reg2 +#define SCMD_ISEQUAL 15 // reg1 == reg2 reg1=1 if true, =0 if not +#define SCMD_NOTEQUAL 16 // reg1 != reg2 +#define SCMD_GREATER 17 // reg1 > reg2 +#define SCMD_LESSTHAN 18 // reg1 < reg2 +#define SCMD_GTE 19 // reg1 >= reg2 +#define SCMD_LTE 20 // reg1 <= reg2 +#define SCMD_AND 21 // (reg1!=0) && (reg2!=0) -> reg1 +#define SCMD_OR 22 // (reg1!=0) || (reg2!=0) -> reg1 +#define SCMD_CALL 23 // jump to subroutine at reg1 +#define SCMD_MEMREADB 24 // reg1 = m[MAR] (1 byte) +#define SCMD_MEMREADW 25 // reg1 = m[MAR] (2 bytes) +#define SCMD_MEMWRITEB 26 // m[MAR] = reg1 (1 byte) +#define SCMD_MEMWRITEW 27 // m[MAR] = reg1 (2 bytes) +#define SCMD_JZ 28 // jump if ax==0 to arg1 +#define SCMD_PUSHREG 29 // m[sp]=reg1; sp++ +#define SCMD_POPREG 30 // sp--; reg1=m[sp] +#define SCMD_JMP 31 // jump to arg1 +#define SCMD_MUL 32 // reg1 *= arg2 +#define SCMD_CALLEXT 33 // call external (imported) function reg1 +#define SCMD_PUSHREAL 34 // push reg1 onto real stack +#define SCMD_SUBREALSTACK 35 // decrement stack ptr by literal +#define SCMD_LINENUM 36 // debug info - source code line number +#define SCMD_CALLAS 37 // call external script function +#define SCMD_THISBASE 38 // current relative address +#define SCMD_NUMFUNCARGS 39 // number of arguments for ext func call +#define SCMD_MODREG 40 // reg1 %= reg2 +#define SCMD_XORREG 41 // reg1 ^= reg2 +#define SCMD_NOTREG 42 // reg1 = !reg1 +#define SCMD_SHIFTLEFT 43 // reg1 = reg1 << reg2 +#define SCMD_SHIFTRIGHT 44 // reg1 = reg1 >> reg2 +#define SCMD_CALLOBJ 45 // next call is member function of reg1 +#define SCMD_CHECKBOUNDS 46 // check reg1 is between 0 and arg2 +#define SCMD_MEMWRITEPTR 47 // m[MAR] = reg1 (adjust ptr addr) +#define SCMD_MEMREADPTR 48 // reg1 = m[MAR] (adjust ptr addr) +#define SCMD_MEMZEROPTR 49 // m[MAR] = 0 (blank ptr) +#define SCMD_MEMINITPTR 50 // m[MAR] = reg1 (but don't free old one) +#define SCMD_LOADSPOFFS 51 // MAR = SP - arg1 (optimization for local var access) +#define SCMD_CHECKNULL 52 // error if MAR==0 +#define SCMD_FADD 53 // reg1 += arg2 (float,int) +#define SCMD_FSUB 54 // reg1 -= arg2 (float,int) +#define SCMD_FMULREG 55 // reg1 *= reg2 (float) +#define SCMD_FDIVREG 56 // reg1 /= reg2 (float) +#define SCMD_FADDREG 57 // reg1 += reg2 (float) +#define SCMD_FSUBREG 58 // reg1 -= reg2 (float) +#define SCMD_FGREATER 59 // reg1 > reg2 (float) +#define SCMD_FLESSTHAN 60 // reg1 < reg2 (float) +#define SCMD_FGTE 61 // reg1 >= reg2 (float) +#define SCMD_FLTE 62 // reg1 <= reg2 (float) +#define SCMD_ZEROMEMORY 63 // m[MAR]..m[MAR+(arg1-1)] = 0 +#define SCMD_CREATESTRING 64 // reg1 = new String(reg1) +#define SCMD_STRINGSEQUAL 65 // (char*)reg1 == (char*)reg2 reg1=1 if true, =0 if not +#define SCMD_STRINGSNOTEQ 66 // (char*)reg1 != (char*)reg2 +#define SCMD_CHECKNULLREG 67 // error if reg1 == NULL +#define SCMD_LOOPCHECKOFF 68 // no loop checking for this function +#define SCMD_MEMZEROPTRND 69 // m[MAR] = 0 (blank ptr, no dispose if = ax) +#define SCMD_JNZ 70 // jump to arg1 if ax!=0 +#define SCMD_DYNAMICBOUNDS 71 // check reg1 is between 0 and m[MAR-4] +#define SCMD_NEWARRAY 72 // reg1 = new array of reg1 elements, each of size arg2 (arg3=managed type?) +#define SCMD_NEWUSEROBJECT 73 // reg1 = new user object of arg1 size + +#define CC_NUM_SCCMDS 74 +#define MAX_SCMD_ARGS 3 // maximal possible number of arguments + +#define EXPORT_FUNCTION 1 +#define EXPORT_DATA 2 + +#define FIXUP_GLOBALDATA 1 // code[fixup] += &globaldata[0] +#define FIXUP_FUNCTION 2 // code[fixup] += &code[0] +#define FIXUP_STRING 3 // code[fixup] += &strings[0] +#define FIXUP_IMPORT 4 // code[fixup] = &imported_thing[code[fixup]] +#define FIXUP_DATADATA 5 // globaldata[fixup] += &globaldata[0] +#define FIXUP_STACK 6 // code[fixup] += &stack[0] + + + + +extern int currentline; +// Script file signature +extern const char scfilesig[5]; +#define ENDFILESIG 0xbeefcafe + +#endif // __CS_COMMON_H diff --git a/engines/ags/shared/util/alignedstream.cpp b/engines/ags/shared/util/alignedstream.cpp new file mode 100644 index 000000000000..b60a00e0baa6 --- /dev/null +++ b/engines/ags/shared/util/alignedstream.cpp @@ -0,0 +1,389 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "debug/assert.h" +#include "util/alignedstream.h" +#include "util/math.h" + +namespace AGS +{ +namespace Common +{ + +AlignedStream::AlignedStream(Stream *stream, AlignedStreamMode mode, ObjectOwnershipPolicy stream_ownership_policy, + size_t base_alignment) + : ProxyStream(stream, stream_ownership_policy) + , _mode(mode) + , _baseAlignment(base_alignment) + , _maxAlignment(0) + , _block(0) +{ +} + +AlignedStream::~AlignedStream() +{ + AlignedStream::Close(); +} + +void AlignedStream::Reset() +{ + if (!_stream) + { + return; + } + + FinalizeBlock(); +} + +void AlignedStream::Close() +{ + if (!_stream) + { + return; + } + + FinalizeBlock(); + ProxyStream::Close(); +} + +bool AlignedStream::CanRead() const +{ + return _stream ? (_mode == kAligned_Read && _stream->CanRead()) : false; +} + +bool AlignedStream::CanWrite() const +{ + return _stream ? (_mode == kAligned_Write && _stream->CanWrite()) : false; +} + +bool AlignedStream::CanSeek() const +{ + // Aligned stream does not support seeking, hence that will break padding count + return false; +} + +size_t AlignedStream::Read(void *buffer, size_t size) +{ + if (_stream) + { + ReadPadding(sizeof(int8_t)); + size = _stream->Read(buffer, size); + _block += size; + return size; + } + return 0; +} + +int32_t AlignedStream::ReadByte() +{ + uint8_t b = 0; + if (_stream) + { + ReadPadding(sizeof(uint8_t)); + b = _stream->ReadByte(); + _block += sizeof(uint8_t); + } + return b; +} + +int16_t AlignedStream::ReadInt16() +{ + int16_t val = 0; + if (_stream) + { + ReadPadding(sizeof(int16_t)); + val = _stream->ReadInt16(); + _block += sizeof(int16_t); + } + return val; +} + +int32_t AlignedStream::ReadInt32() +{ + int32_t val = 0; + if (_stream) + { + ReadPadding(sizeof(int32_t)); + val = _stream->ReadInt32(); + _block += sizeof(int32_t); + } + return val; +} + +int64_t AlignedStream::ReadInt64() +{ + int64_t val = 0; + if (_stream) + { + ReadPadding(sizeof(int64_t)); + val = _stream->ReadInt64(); + _block += sizeof(int64_t); + } + return val; +} + +size_t AlignedStream::ReadArray(void *buffer, size_t elem_size, size_t count) +{ + if (_stream) + { + ReadPadding(elem_size); + count = _stream->ReadArray(buffer, elem_size, count); + _block += count * elem_size; + return count; + } + return 0; +} + +size_t AlignedStream::ReadArrayOfInt16(int16_t *buffer, size_t count) +{ + if (_stream) + { + ReadPadding(sizeof(int16_t)); + count = _stream->ReadArrayOfInt16(buffer, count); + _block += count * sizeof(int16_t); + return count; + } + return 0; +} + +size_t AlignedStream::ReadArrayOfInt32(int32_t *buffer, size_t count) +{ + if (_stream) + { + ReadPadding(sizeof(int32_t)); + count = _stream->ReadArrayOfInt32(buffer, count); + _block += count * sizeof(int32_t); + return count; + } + return 0; +} + +size_t AlignedStream::ReadArrayOfInt64(int64_t *buffer, size_t count) +{ + if (_stream) + { + ReadPadding(sizeof(int64_t)); + count = _stream->ReadArrayOfInt64(buffer, count); + _block += count * sizeof(int64_t); + return count; + } + return 0; +} + +size_t AlignedStream::Write(const void *buffer, size_t size) +{ + if (_stream) + { + WritePadding(sizeof(int8_t)); + size = _stream->Write(buffer, size); + _block += size; + return size; + } + return 0; +} + +int32_t AlignedStream::WriteByte(uint8_t b) +{ + if (_stream) + { + WritePadding(sizeof(uint8_t)); + b = _stream->WriteByte(b); + _block += sizeof(uint8_t); + return b; + } + return 0; +} + +size_t AlignedStream::WriteInt16(int16_t val) +{ + if (_stream) + { + WritePadding(sizeof(int16_t)); + size_t size = _stream->WriteInt16(val); + _block += sizeof(int16_t); + return size; + } + return 0; +} + +size_t AlignedStream::WriteInt32(int32_t val) +{ + if (_stream) + { + WritePadding(sizeof(int32_t)); + size_t size = _stream->WriteInt32(val); + _block += sizeof(int32_t); + return size; + } + return 0; +} + +size_t AlignedStream::WriteInt64(int64_t val) +{ + if (_stream) + { + WritePadding(sizeof(int64_t)); + size_t size = _stream->WriteInt64(val); + _block += sizeof(int64_t); + return size; + } + return 0; +} + +size_t AlignedStream::WriteArray(const void *buffer, size_t elem_size, size_t count) +{ + if (_stream) + { + WritePadding(elem_size); + count = _stream->WriteArray(buffer, elem_size, count); + _block += count * elem_size; + return count; + } + return 0; +} + +size_t AlignedStream::WriteArrayOfInt16(const int16_t *buffer, size_t count) +{ + if (_stream) + { + WritePadding(sizeof(int16_t)); + count = _stream->WriteArrayOfInt16(buffer, count); + _block += count * sizeof(int16_t); + return count; + } + return 0; +} + +size_t AlignedStream::WriteArrayOfInt32(const int32_t *buffer, size_t count) +{ + if (_stream) + { + WritePadding(sizeof(int32_t)); + count = _stream->WriteArrayOfInt32(buffer, count); + _block += count * sizeof(int32_t); + return count; + } + return 0; +} + +size_t AlignedStream::WriteArrayOfInt64(const int64_t *buffer, size_t count) +{ + if (_stream) + { + WritePadding(sizeof(int64_t)); + count = _stream->WriteArrayOfInt64(buffer, count); + _block += count * sizeof(int64_t); + return count; + } + return 0; +} + +bool AlignedStream::Seek(soff_t offset, StreamSeek origin) +{ + // TODO: split out Seekable Stream interface + return false; +} + +void AlignedStream::ReadPadding(size_t next_type) +{ + if (!IsValid()) + { + return; + } + + if (next_type == 0) + { + return; + } + + // The next is going to be evenly aligned data type, + // therefore a padding check must be made + if (next_type % _baseAlignment == 0) + { + int pad = _block % next_type; + // Read padding only if have to + if (pad) + { + // We do not know and should not care if the underlying stream + // supports seek, so use read to skip the padding instead. + for (size_t i = next_type - pad; i > 0; --i) + _stream->ReadByte(); + _block += next_type - pad; + } + + _maxAlignment = Math::Max(_maxAlignment, next_type); + // Data is evenly aligned now + if (_block % LargestPossibleType == 0) + { + _block = 0; + } + } +} + +void AlignedStream::WritePadding(size_t next_type) +{ + if (!IsValid()) + { + return; + } + + if (next_type == 0) + { + return; + } + + // The next is going to be evenly aligned data type, + // therefore a padding check must be made + if (next_type % _baseAlignment == 0) + { + int pad = _block % next_type; + // Write padding only if have to + if (pad) + { + _stream->WriteByteCount(0, next_type - pad); + _block += next_type - pad; + } + + _maxAlignment = Math::Max(_maxAlignment, next_type); + // Data is evenly aligned now + if (_block % LargestPossibleType == 0) + { + _block = 0; + } + } +} + +void AlignedStream::FinalizeBlock() +{ + if (!IsValid()) + { + return; + } + + // Force the stream to read or write remaining padding to match the alignment + if (_mode == kAligned_Read) + { + ReadPadding(_maxAlignment); + } + else if (_mode == kAligned_Write) + { + WritePadding(_maxAlignment); + } + + _maxAlignment = 0; + _block = 0; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/alignedstream.h b/engines/ags/shared/util/alignedstream.h new file mode 100644 index 000000000000..c0aed86d7cfa --- /dev/null +++ b/engines/ags/shared/util/alignedstream.h @@ -0,0 +1,106 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Class AlignedStream +// A simple wrapper around stream that controls data padding. +// +// Originally, a number of objects in AGS were read and written directly +// as a data struct in a whole. In order to support backwards compatibility +// with games made by older versions of AGS, some of the game objects must +// be read having automatic data alignment in mind. +//----------------------------------------------------------------------------- +// +// AlignedStream uses the underlying stream, it overrides the reading and +// writing, and inserts extra data padding when needed. +// +// Aligned stream works either in read or write mode, it cannot be opened in +// combined mode. +// +// AlignedStream does not support seek, hence moving stream pointer to random +// position will break padding count logic. +// +//============================================================================= +#ifndef __AGS_CN_UTIL__ALIGNEDSTREAM_H +#define __AGS_CN_UTIL__ALIGNEDSTREAM_H + +#include "util/proxystream.h" + +namespace AGS +{ +namespace Common +{ + +enum AlignedStreamMode +{ + kAligned_Read, + kAligned_Write +}; + +class AlignedStream : public ProxyStream +{ +public: + AlignedStream(Stream *stream, AlignedStreamMode mode, + ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse, + size_t base_alignment = sizeof(int16_t)); + ~AlignedStream() override; + + // Read/Write cumulated padding and reset block counter + void Reset(); + + void Close() override; + + bool CanRead() const override; + bool CanWrite() const override; + bool CanSeek() const override; + + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + int16_t ReadInt16() override; + int32_t ReadInt32() override; + int64_t ReadInt64() override; + size_t ReadArray(void *buffer, size_t elem_size, size_t count) override; + size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override; + size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override; + size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override; + + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; + size_t WriteInt16(int16_t val) override; + size_t WriteInt32(int32_t val) override; + size_t WriteInt64(int64_t val) override; + size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override; + size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override; + size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override; + size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override; + + bool Seek(soff_t offset, StreamSeek origin) override; + +protected: + void ReadPadding(size_t next_type); + void WritePadding(size_t next_type); + void FinalizeBlock(); + +private: + static const size_t LargestPossibleType = sizeof(int64_t); + + AlignedStreamMode _mode; + size_t _baseAlignment; + size_t _maxAlignment; + int64_t _block; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__ALIGNEDSTREAM_H diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h new file mode 100644 index 000000000000..398ca7dad45f --- /dev/null +++ b/engines/ags/shared/util/bbop.h @@ -0,0 +1,158 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Various utility bit and byte operations +// +//============================================================================= +#ifndef __AGS_CN_UTIL__BBOP_H +#define __AGS_CN_UTIL__BBOP_H + +#include "core/platform.h" +#include "core/types.h" + +#if AGS_PLATFORM_ENDIAN_BIG || defined (TEST_BIGENDIAN) +#define BITBYTE_BIG_ENDIAN +#endif + +namespace AGS +{ +namespace Common +{ + +enum DataEndianess +{ + kBigEndian, + kLittleEndian, +#if defined (BITBYTE_BIG_ENDIAN) + kDefaultSystemEndianess = kBigEndian +#else + kDefaultSystemEndianess = kLittleEndian +#endif +}; + +namespace BitByteOperations +{ + inline int16_t SwapBytesInt16(const int16_t val) + { + return ((val >> 8) & 0xFF) | ((val << 8) & 0xFF00); + } + + inline int32_t SwapBytesInt32(const int32_t val) + { + return ((val >> 24) & 0xFF) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | ((val << 24) & 0xFF000000); + } + + inline int64_t SwapBytesInt64(const int64_t val) + { + return ((val >> 56) & 0xFF) | ((val >> 40) & 0xFF00) | ((val >> 24) & 0xFF0000) | + ((val >> 8) & 0xFF000000) | ((val << 8) & 0xFF00000000LL) | + ((val << 24) & 0xFF0000000000LL) | ((val << 40) & 0xFF000000000000LL) | ((val << 56) & 0xFF00000000000000LL); + } + + inline float SwapBytesFloat(const float val) + { + // (c) SDL2 + union + { + float f; + uint32_t ui32; + } swapper; + swapper.f = val; + swapper.ui32 = SwapBytesInt32(swapper.ui32); + return swapper.f; + } + + inline int16_t Int16FromLE(const int16_t val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return SwapBytesInt16(val); +#else + return val; +#endif + } + + inline int32_t Int32FromLE(const int32_t val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return SwapBytesInt32(val); +#else + return val; +#endif + } + + inline int64_t Int64FromLE(const int64_t val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return SwapBytesInt64(val); +#else + return val; +#endif + } + + inline float FloatFromLE(const float val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return SwapBytesFloat(val); +#else + return val; +#endif + } + + inline int16_t Int16FromBE(const int16_t val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return val; +#else + return SwapBytesInt16(val); +#endif + } + + inline int32_t Int32FromBE(const int32_t val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return val; +#else + return SwapBytesInt32(val); +#endif + } + + inline int64_t Int64FromBE(const int64_t val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return val; +#else + return SwapBytesInt64(val); +#endif + } + + inline float FloatFromBE(const float val) + { +#if defined (BITBYTE_BIG_ENDIAN) + return val; +#else + return SwapBytesFloat(val); +#endif + } + +} // namespace BitByteOperations + + +// Aliases for easier calling +namespace BBOp = BitByteOperations; + + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__BBOP_H diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp new file mode 100644 index 000000000000..a67d95415f1c --- /dev/null +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -0,0 +1,134 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include +#include +#include +#include "util/bufferedstream.h" +#include "util/stdio_compat.h" +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +BufferedStream::BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) + : FileStream(file_name, open_mode, work_mode, stream_endianess), _buffer(BufferStreamSize), _bufferPosition(0), _position(0) +{ + if (FileStream::Seek(0, kSeekEnd) == false) + throw std::runtime_error("Error determining stream end."); + + _end = FileStream::GetPosition(); + if (_end == -1) + throw std::runtime_error("Error determining stream end."); + + if (FileStream::Seek(0, kSeekBegin) == false) + throw std::runtime_error("Error determining stream end."); + + _buffer.resize(0); + +} + +void BufferedStream::FillBufferFromPosition(soff_t position) +{ + FileStream::Seek(position, kSeekBegin); + + _buffer.resize(BufferStreamSize); + auto sz = FileStream::Read(_buffer.data(), BufferStreamSize); + _buffer.resize(sz); + + _bufferPosition = position; +} + +bool BufferedStream::EOS() const +{ + return _position == _end; +} + +soff_t BufferedStream::GetPosition() const +{ + return _position; +} + +size_t BufferedStream::Read(void *toBuffer, size_t toSize) +{ + auto to = static_cast(toBuffer); + + while(toSize > 0) + { + if (_position < _bufferPosition || _position >= _bufferPosition + _buffer.size()) + { + FillBufferFromPosition(_position); + } + if (_buffer.size() <= 0) { break; } // reached EOS + assert(_position >= _bufferPosition && _position < _bufferPosition + _buffer.size()); // sanity check only, should be checked by above. + + soff_t bufferOffset = _position - _bufferPosition; + assert(bufferOffset >= 0); + size_t bytesLeft = _buffer.size() - (size_t)bufferOffset; + size_t chunkSize = std::min(bytesLeft, toSize); + + std::memcpy(to, _buffer.data()+bufferOffset, chunkSize); + + to += chunkSize; + _position += chunkSize; + toSize -= chunkSize; + } + + return to - (char*)toBuffer; +} + +int32_t BufferedStream::ReadByte() +{ + uint8_t ch; + auto bytesRead = Read(&ch, 1); + if (bytesRead != 1) { return EOF; } + return ch; +} + +size_t BufferedStream::Write(const void *buffer, size_t size) +{ + FileStream::Seek(_position, kSeekBegin); + auto sz = FileStream::Write(buffer, size); + if (_position == _end) + _end += sz; + _position += sz; + return sz; +} + +int32_t BufferedStream::WriteByte(uint8_t val) +{ + auto sz = Write(&val, 1); + if (sz != 1) { return -1; } + return sz; +} + +bool BufferedStream::Seek(soff_t offset, StreamSeek origin) +{ + soff_t want_pos = -1; + switch(origin) + { + case StreamSeek::kSeekCurrent: want_pos = _position + offset; break; + case StreamSeek::kSeekBegin: want_pos = 0 + offset; break; + case StreamSeek::kSeekEnd: want_pos = _end + offset; break; + break; + } + + // clamp + _position = std::min(std::max(want_pos, (soff_t)0), _end); + return _position == want_pos; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h new file mode 100644 index 000000000000..10e36dc9a79a --- /dev/null +++ b/engines/ags/shared/util/bufferedstream.h @@ -0,0 +1,69 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_UTIL__BUFFEREDSTREAM_H +#define __AGS_CN_UTIL__BUFFEREDSTREAM_H + +#include +#include "util/filestream.h" +#include "util/file.h" // TODO: extract filestream mode constants + +namespace AGS +{ +namespace Common +{ + +// Needs tuning depending on the platform. +const auto BufferStreamSize = 8*1024; + +class BufferedStream : public FileStream +{ +public: + // Represents an open _buffered_ file object + // The constructor may raise std::runtime_error if + // - there is an issue opening the file (does not exist, locked, permissions, etc) + // - the open mode could not be determined + // - could not determine the length of the stream + // It is recommended to use File::OpenFile to safely construct this object. + BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess = kLittleEndian); + + bool EOS() const override; ///< Is end of stream + soff_t GetPosition() const override; ///< Current position (if known) + + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; + + bool Seek(soff_t offset, StreamSeek origin) override; + + +private: + + soff_t _bufferPosition; + std::vector _buffer; + + soff_t _position; + soff_t _end; + + void FillBufferFromPosition(soff_t position); +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__BUFFEREDSTREAM_H diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp new file mode 100644 index 000000000000..8561fb687592 --- /dev/null +++ b/engines/ags/shared/util/compress.cpp @@ -0,0 +1,434 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifdef _MANAGED +// ensure this doesn't get compiled to .NET IL +#pragma unmanaged +#endif + +#include +#include +#include "ac/common.h" // quit, update_polled_stuff +#include "gfx/bitmap.h" +#include "util/compress.h" +#include "util/lzw.h" +#include "util/misc.h" +#include "util/stream.h" +#if AGS_PLATFORM_ENDIAN_BIG +#include "util/bbop.h" +#endif + +using namespace AGS::Common; + +void cpackbitl(const uint8_t *line, int size, Stream *out) +{ + int cnt = 0; // bytes encoded + + while (cnt < size) { + int i = cnt; + int j = i + 1; + int jmax = i + 126; + if (jmax >= size) + jmax = size - 1; + + if (i == size - 1) { //................last byte alone + out->WriteInt8(0); + out->WriteInt8(line[i]); + cnt++; + + } else if (line[i] == line[j]) { //....run + while ((j < jmax) && (line[j] == line[j + 1])) + j++; + + out->WriteInt8(i - j); + out->WriteInt8(line[i]); + cnt += j - i + 1; + + } else { //.............................sequence + while ((j < jmax) && (line[j] != line[j + 1])) + j++; + + out->WriteInt8(j - i); + out->WriteArray(line + i, j - i + 1, 1); + cnt += j - i + 1; + + } + } // end while +} + +void cpackbitl16(const uint16_t *line, int size, Stream *out) +{ + int cnt = 0; // bytes encoded + + while (cnt < size) { + int i = cnt; + int j = i + 1; + int jmax = i + 126; + if (jmax >= size) + jmax = size - 1; + + if (i == size - 1) { //................last byte alone + out->WriteInt8(0); + out->WriteInt16(line[i]); + cnt++; + + } else if (line[i] == line[j]) { //....run + while ((j < jmax) && (line[j] == line[j + 1])) + j++; + + out->WriteInt8(i - j); + out->WriteInt16(line[i]); + cnt += j - i + 1; + + } else { //.............................sequence + while ((j < jmax) && (line[j] != line[j + 1])) + j++; + + out->WriteInt8(j - i); + out->WriteArray(line + i, j - i + 1, 2); + cnt += j - i + 1; + + } + } // end while +} + +void cpackbitl32(const uint32_t *line, int size, Stream *out) +{ + int cnt = 0; // bytes encoded + + while (cnt < size) { + int i = cnt; + int j = i + 1; + int jmax = i + 126; + if (jmax >= size) + jmax = size - 1; + + if (i == size - 1) { //................last byte alone + out->WriteInt8(0); + out->WriteInt32(line[i]); + cnt++; + + } else if (line[i] == line[j]) { //....run + while ((j < jmax) && (line[j] == line[j + 1])) + j++; + + out->WriteInt8(i - j); + out->WriteInt32(line[i]); + cnt += j - i + 1; + + } else { //.............................sequence + while ((j < jmax) && (line[j] != line[j + 1])) + j++; + + out->WriteInt8(j - i); + out->WriteArray(line + i, j - i + 1, 4); + cnt += j - i + 1; + + } + } // end while +} + + +void csavecompressed(Stream *out, const unsigned char * tobesaved, const color pala[256]) +{ + int widt, hit; + widt = *tobesaved++; + widt += (*tobesaved++) * 256; + hit = *tobesaved++; + hit += (*tobesaved++) * 256; + // Those were originally written as shorts, although they are ints + out->WriteInt16(widt); + out->WriteInt16(hit); + + unsigned char *ress = (unsigned char *)malloc(widt + 1); + int ww; + + for (ww = 0; ww < hit; ww++) { + for (int ss = 0; ss < widt; ss++) + (*ress++) = (*tobesaved++); + + ress -= widt; + cpackbitl(ress, widt, out); + } + + for (ww = 0; ww < 256; ww++) { + out->WriteInt8(pala[ww].r); + out->WriteInt8(pala[ww].g); + out->WriteInt8(pala[ww].b); + } + free(ress); +} + +int cunpackbitl(uint8_t *line, int size, Stream *in) +{ + int n = 0; // number of bytes decoded + + while (n < size) { + int ix = in->ReadByte(); // get index byte + if (in->HasErrors()) + break; + + char cx = ix; + if (cx == -128) + cx = 0; + + if (cx < 0) { //.............run + int i = 1 - cx; + char ch = in->ReadInt8(); + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = ch; + } + } else { //.....................seq + int i = cx + 1; + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = in->ReadByte(); + } + } + } + + return in->HasErrors() ? -1 : 0; +} + +int cunpackbitl16(uint16_t *line, int size, Stream *in) +{ + int n = 0; // number of bytes decoded + + while (n < size) { + int ix = in->ReadByte(); // get index byte + if (in->HasErrors()) + break; + + char cx = ix; + if (cx == -128) + cx = 0; + + if (cx < 0) { //.............run + int i = 1 - cx; + unsigned short ch = in->ReadInt16(); + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = ch; + } + } else { //.....................seq + int i = cx + 1; + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = in->ReadInt16(); + } + } + } + + return in->HasErrors() ? -1 : 0; +} + +int cunpackbitl32(uint32_t *line, int size, Stream *in) +{ + int n = 0; // number of bytes decoded + + while (n < size) { + int ix = in->ReadByte(); // get index byte + if (in->HasErrors()) + break; + + char cx = ix; + if (cx == -128) + cx = 0; + + if (cx < 0) { //.............run + int i = 1 - cx; + unsigned int ch = in->ReadInt32(); + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = ch; + } + } else { //.....................seq + int i = cx + 1; + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = (unsigned int)in->ReadInt32(); + } + } + } + + return in->HasErrors() ? -1 : 0; +} + +//============================================================================= + +const char *lztempfnm = "~aclzw.tmp"; + +void save_lzw(Stream *out, const Bitmap *bmpp, const color *pall) +{ + // First write original bitmap into temporary file + Stream *lz_temp_s = ci_fopen(lztempfnm, kFile_CreateAlways, kFile_Write); + lz_temp_s->WriteInt32(bmpp->GetWidth() * bmpp->GetBPP()); + lz_temp_s->WriteInt32(bmpp->GetHeight()); + lz_temp_s->WriteArray(bmpp->GetData(), bmpp->GetLineLength(), bmpp->GetHeight()); + delete lz_temp_s; + + // Now open same file for reading, and begin writing compressed data into required output stream + lz_temp_s = ci_fopen(lztempfnm); + soff_t temp_sz = lz_temp_s->GetLength(); + out->WriteArray(&pall[0], sizeof(color), 256); + out->WriteInt32(temp_sz); + soff_t gobacto = out->GetPosition(); + + // reserve space for compressed size + out->WriteInt32(temp_sz); + lzwcompress(lz_temp_s, out); + soff_t toret = out->GetPosition(); + out->Seek(gobacto, kSeekBegin); + soff_t compressed_sz = (toret - gobacto) - 4; + out->WriteInt32(compressed_sz); // write compressed size + + // Delete temp file + delete lz_temp_s; + ::remove(lztempfnm); + + // Seek back to the end of the output stream + out->Seek(toret, kSeekBegin); +} + +void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, color *pall) { + soff_t uncompsiz; + int *loptr; + unsigned char *membuffer; + int arin; + + in->Read(&pall[0], sizeof(color)*256); + maxsize = in->ReadInt32(); + uncompsiz = in->ReadInt32(); + + uncompsiz += in->GetPosition(); + outbytes = 0; putbytes = 0; + + update_polled_stuff_if_runtime(); + membuffer = lzwexpand_to_mem(in); + update_polled_stuff_if_runtime(); + + loptr = (int *)&membuffer[0]; + membuffer += 8; +#if AGS_PLATFORM_ENDIAN_BIG + loptr[0] = BBOp::SwapBytesInt32(loptr[0]); + loptr[1] = BBOp::SwapBytesInt32(loptr[1]); + int bitmapNumPixels = loptr[0]*loptr[1]/ dst_bpp; + switch (dst_bpp) // bytes per pixel! + { + case 1: + { + // all done + break; + } + case 2: + { + short *sp = (short *)membuffer; + for (int i = 0; i < bitmapNumPixels; ++i) + { + sp[i] = BBOp::SwapBytesInt16(sp[i]); + } + // all done + break; + } + case 4: + { + int *ip = (int *)membuffer; + for (int i = 0; i < bitmapNumPixels; ++i) + { + ip[i] = BBOp::SwapBytesInt32(ip[i]); + } + // all done + break; + } + } +#endif // AGS_PLATFORM_ENDIAN_BIG + + update_polled_stuff_if_runtime(); + + Bitmap *bmm = BitmapHelper::CreateBitmap((loptr[0] / dst_bpp), loptr[1], dst_bpp * 8); + if (bmm == nullptr) + quit("!load_room: not enough memory to load room background"); + + update_polled_stuff_if_runtime(); + + bmm->Acquire (); + + for (arin = 0; arin < loptr[1]; arin++) + memcpy(&bmm->GetScanLineForWriting(arin)[0], &membuffer[arin * loptr[0]], loptr[0]); + + bmm->Release (); + + update_polled_stuff_if_runtime(); + + free(membuffer-8); + + if (in->GetPosition() != uncompsiz) + in->Seek(uncompsiz, kSeekBegin); + + update_polled_stuff_if_runtime(); + + *dst_bmp = bmm; +} + +void savecompressed_allegro(Stream *out, const Bitmap *bmpp, const color *pall) { + unsigned char *wgtbl = (unsigned char *)malloc(bmpp->GetWidth() * bmpp->GetHeight() + 4); + short *sss = (short *)wgtbl; + + sss[0] = bmpp->GetWidth(); + sss[1] = bmpp->GetHeight(); + + memcpy(&wgtbl[4], bmpp->GetData(), bmpp->GetWidth() * bmpp->GetHeight()); + + csavecompressed(out, wgtbl, pall); + free(wgtbl); +} + +void loadcompressed_allegro(Stream *in, Bitmap **bimpp, color *pall) { + short widd,hitt; + int ii; + + widd = in->ReadInt16(); + hitt = in->ReadInt16(); + Bitmap *bim = BitmapHelper::CreateBitmap(widd, hitt, 8); + if (bim == nullptr) + quit("!load_room: not enough memory to decompress masks"); + + for (ii = 0; ii < hitt; ii++) { + cunpackbitl(&bim->GetScanLineForWriting(ii)[0], widd, in); + if (ii % 20 == 0) + update_polled_stuff_if_runtime(); + } + + in->Seek(768); // skip palette + *bimpp = bim; +} diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h new file mode 100644 index 000000000000..356f8782e000 --- /dev/null +++ b/engines/ags/shared/util/compress.h @@ -0,0 +1,40 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AC_COMPRESS_H +#define __AC_COMPRESS_H + +#include "util/wgt2allg.h" // color (allegro RGB) + +namespace AGS { namespace Common { class Stream; class Bitmap; } } +using namespace AGS; // FIXME later + +void csavecompressed(Common::Stream *out, const unsigned char * tobesaved, const color pala[256]); +// RLE compression +void cpackbitl(const uint8_t *line, int size, Common::Stream *out); +void cpackbitl16(const uint16_t *line, int size, Common::Stream *out); +void cpackbitl32(const uint32_t *line, int size, Common::Stream *out); +// RLE decompression +int cunpackbitl(uint8_t *line, int size, Common::Stream *in); +int cunpackbitl16(uint16_t *line, int size, Common::Stream *in); +int cunpackbitl32(uint32_t *line, int size, Common::Stream *in); + +//============================================================================= + +void save_lzw(Common::Stream *out, const Common::Bitmap *bmpp, const color *pall); +void load_lzw(Common::Stream *in, Common::Bitmap **bmm, int dst_bpp, color *pall); +void savecompressed_allegro(Common::Stream *out, const Common::Bitmap *bmpp, const color *pall); +void loadcompressed_allegro(Common::Stream *in, Common::Bitmap **bimpp, color *pall); + +#endif // __AC_COMPRESS_H diff --git a/engines/ags/shared/util/datastream.cpp b/engines/ags/shared/util/datastream.cpp new file mode 100644 index 000000000000..4348da9e837b --- /dev/null +++ b/engines/ags/shared/util/datastream.cpp @@ -0,0 +1,177 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/datastream.h" + +namespace AGS +{ +namespace Common +{ + +DataStream::DataStream(DataEndianess stream_endianess) + : _streamEndianess(stream_endianess) +{ +} + +DataStream::~DataStream() = default; + +int16_t DataStream::ReadInt16() +{ + int16_t val = 0; + Read(&val, sizeof(int16_t)); + ConvertInt16(val); + return val; +} + +int32_t DataStream::ReadInt32() +{ + int32_t val = 0; + Read(&val, sizeof(int32_t)); + ConvertInt32(val); + return val; +} + +int64_t DataStream::ReadInt64() +{ + int64_t val = 0; + Read(&val, sizeof(int64_t)); + ConvertInt64(val); + return val; +} + +size_t DataStream::WriteInt16(int16_t val) +{ + ConvertInt16(val); + return Write(&val, sizeof(int16_t)); +} + +size_t DataStream::WriteInt32(int32_t val) +{ + ConvertInt32(val); + return Write(&val, sizeof(int32_t)); +} + +size_t DataStream::WriteInt64(int64_t val) +{ + ConvertInt64(val); + return Write(&val, sizeof(int64_t)); +} + +size_t DataStream::ReadAndConvertArrayOfInt16(int16_t *buffer, size_t count) +{ + if (!CanRead() || !buffer) + { + return 0; + } + + count = ReadArray(buffer, sizeof(int16_t), count); + for (size_t i = 0; i < count; ++i, ++buffer) + { + *buffer = BBOp::SwapBytesInt16(*buffer); + } + return count; +} + +size_t DataStream::ReadAndConvertArrayOfInt32(int32_t *buffer, size_t count) +{ + if (!CanRead() || !buffer) + { + return 0; + } + + count = ReadArray(buffer, sizeof(int32_t), count); + for (size_t i = 0; i < count; ++i, ++buffer) + { + *buffer = BBOp::SwapBytesInt32(*buffer); + } + return count; +} + +size_t DataStream::ReadAndConvertArrayOfInt64(int64_t *buffer, size_t count) +{ + if (!CanRead() || !buffer) + { + return 0; + } + + count = ReadArray(buffer, sizeof(int64_t), count); + for (size_t i = 0; i < count; ++i, ++buffer) + { + *buffer = BBOp::SwapBytesInt64(*buffer); + } + return count; +} + +size_t DataStream::WriteAndConvertArrayOfInt16(const int16_t *buffer, size_t count) +{ + if (!CanWrite() || !buffer) + { + return 0; + } + + size_t elem; + for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) + { + int16_t val = *buffer; + ConvertInt16(val); + if (Write(&val, sizeof(int16_t)) < sizeof(int16_t)) + { + break; + } + } + return elem; +} + +size_t DataStream::WriteAndConvertArrayOfInt32(const int32_t *buffer, size_t count) +{ + if (!CanWrite() || !buffer) + { + return 0; + } + + size_t elem; + for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) + { + int32_t val = *buffer; + ConvertInt32(val); + if (Write(&val, sizeof(int32_t)) < sizeof(int32_t)) + { + break; + } + } + return elem; +} + +size_t DataStream::WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t count) +{ + if (!CanWrite() || !buffer) + { + return 0; + } + + size_t elem; + for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) + { + int64_t val = *buffer; + ConvertInt64(val); + if (Write(&val, sizeof(int64_t)) < sizeof(int64_t)) + { + break; + } + } + return elem; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/datastream.h b/engines/ags/shared/util/datastream.h new file mode 100644 index 000000000000..2d1f489c8528 --- /dev/null +++ b/engines/ags/shared/util/datastream.h @@ -0,0 +1,132 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Standard AGS stream implementation for reading raw data with support for +// converting to opposite endianess. Most I/O devices should inherit this +// class and provide implementation for basic reading and writing only. +// +//============================================================================= +#ifndef __AGS_CN_UTIL__DATASTREAM_H +#define __AGS_CN_UTIL__DATASTREAM_H + +#include "util/bbop.h" +#include "util/stream.h" + +namespace AGS +{ +namespace Common +{ + +class DataStream : public Stream +{ +public: + DataStream(DataEndianess stream_endianess = kLittleEndian); + ~DataStream() override; + + int16_t ReadInt16() override; + int32_t ReadInt32() override; + int64_t ReadInt64() override; + + // + // Read- and WriteArray methods return number of full elements (NOT bytes) + // read or written, or -1 if end of stream is reached + // + // Note that ReadArray and WriteArray do NOT convert byte order even when + // work with data of different endianess; they are meant for optimal + // reading and writing blocks of raw bytes + inline size_t ReadArray(void *buffer, size_t elem_size, size_t count) override + { + return Read(buffer, elem_size * count) / elem_size; + } + + inline size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override + { + return MustSwapBytes() ? + ReadAndConvertArrayOfInt16(buffer, count) : ReadArray(buffer, sizeof(int16_t), count); + } + + inline size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override + { + return MustSwapBytes() ? + ReadAndConvertArrayOfInt32(buffer, count) : ReadArray(buffer, sizeof(int32_t), count); + } + + inline size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override + { + return MustSwapBytes() ? + ReadAndConvertArrayOfInt64(buffer, count) : ReadArray(buffer, sizeof(int64_t), count); + } + + size_t WriteInt16(int16_t val) override; + size_t WriteInt32(int32_t val) override; + size_t WriteInt64(int64_t val) override; + + inline size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override + { + return Write(buffer, elem_size * count) / elem_size; + } + + inline size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override + { + return MustSwapBytes() ? + WriteAndConvertArrayOfInt16(buffer, count) : WriteArray(buffer, sizeof(int16_t), count); + } + + inline size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override + { + return MustSwapBytes() ? + WriteAndConvertArrayOfInt32(buffer, count) : WriteArray(buffer, sizeof(int32_t), count); + } + + inline size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override + { + return MustSwapBytes() ? + WriteAndConvertArrayOfInt64(buffer, count) : WriteArray(buffer, sizeof(int64_t), count); + } + +protected: + DataEndianess _streamEndianess; + + // Helper methods for reading/writing arrays of basic types and + // converting their elements to opposite endianess (swapping bytes). + size_t ReadAndConvertArrayOfInt16(int16_t *buffer, size_t count); + size_t ReadAndConvertArrayOfInt32(int32_t *buffer, size_t count); + size_t ReadAndConvertArrayOfInt64(int64_t *buffer, size_t count); + size_t WriteAndConvertArrayOfInt16(const int16_t *buffer, size_t count); + size_t WriteAndConvertArrayOfInt32(const int32_t *buffer, size_t count); + size_t WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t count); + + inline bool MustSwapBytes() + { + return kDefaultSystemEndianess != _streamEndianess; + } + + inline void ConvertInt16(int16_t &val) + { + if (MustSwapBytes()) val = BBOp::SwapBytesInt16(val); + } + inline void ConvertInt32(int32_t &val) + { + if (MustSwapBytes()) val = BBOp::SwapBytesInt32(val); + } + inline void ConvertInt64(int64_t &val) + { + if (MustSwapBytes()) val = BBOp::SwapBytesInt64(val); + } +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__DATASTREAM_H diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp new file mode 100644 index 000000000000..acea430a9e3e --- /dev/null +++ b/engines/ags/shared/util/directory.cpp @@ -0,0 +1,72 @@ + +#include "core/platform.h" +#include +#if AGS_PLATFORM_OS_WINDOWS +#include +#else +#include +#include +#endif +#include "util/directory.h" +#include "util/path.h" +#include "stdio_compat.h" + +namespace AGS +{ +namespace Common +{ + +namespace Directory +{ + +bool CreateDirectory(const String &path) +{ + return mkdir(path +#if ! AGS_PLATFORM_OS_WINDOWS + , 0755 +#endif + ) == 0 || errno == EEXIST; +} + +bool CreateAllDirectories(const String &parent, const String &path) +{ + if (!ags_directory_exists(parent.GetCStr())) + return false; + if (path.IsEmpty()) + return true; + if (!Path::IsSameOrSubDir(parent, path)) + return false; + + String sub_path = Path::MakeRelativePath(parent, path); + String make_path = parent; + std::vector dirs = sub_path.Split('/'); + for (const String &dir : dirs) + { + if (dir.IsEmpty() || dir.Compare(".") == 0) continue; + make_path.AppendChar('/'); + make_path.Append(dir); + if (!CreateDirectory(make_path)) + return false; + } + return true; +} + +String SetCurrentDirectory(const String &path) +{ + chdir(path); + return GetCurrentDirectory(); +} + +String GetCurrentDirectory() +{ + char buf[512]; + getcwd(buf, 512); + String str(buf); + Path::FixupPath(str); + return str; +} + +} // namespace Directory + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h new file mode 100644 index 000000000000..b5a634975663 --- /dev/null +++ b/engines/ags/shared/util/directory.h @@ -0,0 +1,45 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Platform-independent Directory functions +// +//============================================================================= +#ifndef __AGS_CN_UTIL__DIRECTORY_H +#define __AGS_CN_UTIL__DIRECTORY_H + +#include "core/platform.h" +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +namespace Directory +{ + // Creates new directory (if it does not exist) + bool CreateDirectory(const String &path); + // Makes sure all directories in the path are created. Parent path is + // not touched, and function must fail if parent path is not accessible. + bool CreateAllDirectories(const String &parent, const String &path); + // Sets current working directory, returns the resulting path + String SetCurrentDirectory(const String &path); + // Gets current working directory + String GetCurrentDirectory(); +} // namespace Directory + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__DIRECTORY_H diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h new file mode 100644 index 000000000000..1ada93918ce7 --- /dev/null +++ b/engines/ags/shared/util/error.h @@ -0,0 +1,134 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Universal error class, that may be used both as a return value or +// thrown as an exception. +// +//============================================================================= +#ifndef __AGS_CN_UTIL__ERROR_H +#define __AGS_CN_UTIL__ERROR_H + +#include +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +class Error; +typedef std::shared_ptr PError; + +// +// A simple struct, that provides several fields to describe an error in the program. +// If wanted, may be reworked into subclass of std::exception. +// +class Error +{ +public: + Error(int code, String general, PError inner_error = PError()) : _code(code), _general(general), _innerError(inner_error) {} + Error(int code, String general, String comment, PError inner_error = PError()) : _code(code), _general(general), _comment(comment), _innerError(inner_error) {} + Error(String general, PError inner_error = PError()) : _code(0), _general(general), _innerError(inner_error) {} + Error(String general, String comment, PError inner_error = PError()) : _code(0), _general(general), _comment(comment), _innerError(inner_error) {} + + + // Error code is a number, defining error subtype. It is not much use to the end-user, + // but may be checked in the program to know more precise cause of the error. + int Code() const { return _code; } + // General description of this error type and subtype. + String General() const { return _general; } + // Any complementary information. + String Comment() const { return _comment; } + PError InnerError() const { return _innerError; } + // Full error message combines general description and comment. + // NOTE: if made a child of std::exception, FullMessage may be substituted + // or complemented with virtual const char* what(). + String FullMessage() const + { + String msg; + const Error *err = this; + do + { + msg.Append(err->General()); + if (!err->Comment().IsEmpty()) + { + msg.AppendChar('\n'); + msg.Append(err->Comment()); + } + err = err->InnerError().get(); + if (err) + msg.AppendChar('\n'); + } while (err); + return msg; + } + +private: + int _code; // numeric code, for specific uses + String _general; // general description of this error class + String _comment; // additional information about particular case + PError _innerError; // previous error that caused this one +}; + + +// ErrorHandle is a helper class that lets you have an Error object +// wrapped in a smart pointer. ErrorHandle's only data member is a +// shared_ptr, which means that it does not cause too much data copying +// when used as a function's return value. +// Note, that the reason to have distinct class instead of a shared_ptr's +// typedef is an inverted boolean comparison: +// shared_ptr converts to 'true' when it contains an object, but ErrorHandle +// returns 'true' when it *does NOT* contain an object, meaning there +// is no error. +template class ErrorHandle +{ +public: + static ErrorHandle None() { return ErrorHandle(); } + + ErrorHandle() = default; + ErrorHandle(T *err) : _error(err) {} + ErrorHandle(std::shared_ptr err) : _error(err) {} + + bool HasError() const { return _error.get() != NULL; } + explicit operator bool() const { return _error.get() == nullptr; } + operator PError() const { return _error; } + T *operator ->() const { return _error.operator->(); } + T &operator *() const { return _error.operator*(); } + +private: + std::shared_ptr _error; +}; + + +// Basic error handle, containing Error object +typedef ErrorHandle HError; + + +// TypedCodeError is the Error's subclass, which only purpose is to override +// error code type in constructor and Code() getter, that may be useful if +// you'd like to restrict code values to particular enumerator. +template +class TypedCodeError : public Error +{ +public: + TypedCodeError(CodeType code, PError inner_error = PError()) : Error(code, GetErrorText(code), inner_error) {} + TypedCodeError(CodeType code, String comment, PError inner_error = PError()) : + Error(code, GetErrorText(code), comment, inner_error) {} + + CodeType Code() const { return (CodeType)Error::Code(); } +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__ERROR_H diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp new file mode 100644 index 000000000000..8f1fb3f6febf --- /dev/null +++ b/engines/ags/shared/util/file.cpp @@ -0,0 +1,177 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/file.h" + +#include +#include "core/platform.h" +#include "util/stdio_compat.h" +#include +#include "util/filestream.h" +#include "util/bufferedstream.h" + +namespace AGS +{ +namespace Common +{ + +soff_t File::GetFileSize(const String &filename) +{ + return ags_file_size(filename.GetCStr()); +} + +bool File::TestReadFile(const String &filename) +{ + FILE *test_file = fopen(filename, "rb"); + if (test_file) + { + fclose(test_file); + return true; + } + return false; +} + +bool File::TestWriteFile(const String &filename) +{ + FILE *test_file = fopen(filename, "r+"); + if (test_file) + { + fclose(test_file); + return true; + } + return TestCreateFile(filename); +} + +bool File::TestCreateFile(const String &filename) +{ + FILE *test_file = fopen(filename, "wb"); + if (test_file) + { + fclose(test_file); + ::remove(filename); + return true; + } + return false; +} + +bool File::DeleteFile(const String &filename) +{ + if (::remove(filename) != 0) + { + int err; +#if AGS_PLATFORM_OS_WINDOWS + _get_errno(&err); +#else + err = errno; +#endif + if (err == EACCES) + { + return false; + } + } + return true; +} + +bool File::GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, FileWorkMode &work_mode) +{ + // We do not test for 'b' and 't' here, because text mode reading/writing should be done with + // the use of ITextReader and ITextWriter implementations. + // The number of supported variants here is quite limited due the restrictions AGS makes on them. + bool read_base_mode = false; + // Default mode is open/read for safety reasons + open_mode = kFile_Open; + work_mode = kFile_Read; + for (size_t c = 0; c < cmode.GetLength(); ++c) + { + if (read_base_mode) + { + if (cmode[c] == '+') + { + work_mode = kFile_ReadWrite; + } + break; + } + else + { + if (cmode[c] == 'r') + { + open_mode = kFile_Open; + work_mode = kFile_Read; + read_base_mode = true; + } + else if (cmode[c] == 'a') + { + open_mode = kFile_Create; + work_mode = kFile_Write; + read_base_mode = true; + } + else if (cmode[c] == 'w') + { + open_mode = kFile_CreateAlways; + work_mode = kFile_Write; + read_base_mode = true; + } + } + } + return read_base_mode; +} + +String File::GetCMode(FileOpenMode open_mode, FileWorkMode work_mode) +{ + String mode; + if (open_mode == kFile_Open) + { + if (work_mode == kFile_Read) + mode.AppendChar('r'); + else if (work_mode == kFile_Write || work_mode == kFile_ReadWrite) + mode.Append("r+"); + } + else if (open_mode == kFile_Create) + { + if (work_mode == kFile_Write) + mode.AppendChar('a'); + else if (work_mode == kFile_Read || work_mode == kFile_ReadWrite) + mode.Append("a+"); + } + else if (open_mode == kFile_CreateAlways) + { + if (work_mode == kFile_Write) + mode.AppendChar('w'); + else if (work_mode == kFile_Read || work_mode == kFile_ReadWrite) + mode.Append("w+"); + } + mode.AppendChar('b'); + return mode; +} + +Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode) +{ + FileStream *fs = nullptr; + try { + if (work_mode == kFile_Read) // NOTE: BufferedStream does not work correctly in the write mode + fs = new BufferedStream(filename, open_mode, work_mode); + else + fs = new FileStream(filename, open_mode, work_mode); + if (fs != nullptr && !fs->IsValid()) { + delete fs; + fs = nullptr; + } + } catch(std::runtime_error) { + fs = nullptr; + } + return fs; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h new file mode 100644 index 000000000000..c81e4140aa97 --- /dev/null +++ b/engines/ags/shared/util/file.h @@ -0,0 +1,86 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Platform-independent File functions +// +//============================================================================= +#ifndef __AGS_CN_UTIL__FILE_H +#define __AGS_CN_UTIL__FILE_H + +#include "core/platform.h" +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +// Forward declarations +class Stream; + +enum FileOpenMode +{ + kFile_Open, // Open existing file + kFile_Create, // Create new file, or open existing one + kFile_CreateAlways // Always create a new file, replacing any existing one +}; + +enum FileWorkMode +{ + kFile_Read, + kFile_Write, + kFile_ReadWrite +}; + +namespace File +{ + // Returns size of a file, or -1 if no such file found + soff_t GetFileSize(const String &filename); + // Tests if file could be opened for reading + bool TestReadFile(const String &filename); + // Opens a file for writing or creates new one if it does not exist; deletes file if it was created during test + bool TestWriteFile(const String &filename); + // Create new empty file and deletes it; returns TRUE if was able to create file + bool TestCreateFile(const String &filename); + // Deletes existing file; returns TRUE if was able to delete one + bool DeleteFile(const String &filename); + + // Sets FileOpenMode and FileWorkMode values corresponding to C-style file open mode string + bool GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, FileWorkMode &work_mode); + // Gets C-style file mode from FileOpenMode and FileWorkMode + String GetCMode(FileOpenMode open_mode, FileWorkMode work_mode); + + Stream *OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode); + // Convenience helpers + // Create a totally new file, overwrite existing one + inline Stream *CreateFile(const String &filename) + { + return OpenFile(filename, kFile_CreateAlways, kFile_Write); + } + // Open existing file for reading + inline Stream *OpenFileRead(const String &filename) + { + return OpenFile(filename, kFile_Open, kFile_Read); + } + // Open existing file for writing (append) or create if it does not exist + inline Stream *OpenFileWrite(const String &filename) + { + return OpenFile(filename, kFile_Create, kFile_Write); + } +} // namespace File + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__FILE_H diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp new file mode 100644 index 000000000000..6c681285b940 --- /dev/null +++ b/engines/ags/shared/util/filestream.cpp @@ -0,0 +1,180 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/filestream.h" + +#include +#include "util/stdio_compat.h" +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +FileStream::FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, + DataEndianess stream_endianess) + : DataStream(stream_endianess) + , _file(nullptr) + , _openMode(open_mode) + , _workMode(work_mode) +{ + Open(file_name, open_mode, work_mode); +} + +FileStream::~FileStream() +{ + FileStream::Close(); +} + +bool FileStream::HasErrors() const +{ + return IsValid() && ferror(_file) != 0; +} + +void FileStream::Close() +{ + if (_file) + { + fclose(_file); + } + _file = nullptr; +} + +bool FileStream::Flush() +{ + if (_file) + { + return fflush(_file) == 0; + } + return false; +} + +bool FileStream::IsValid() const +{ + return _file != nullptr; +} + +bool FileStream::EOS() const +{ + return !IsValid() || feof(_file) != 0; +} + +soff_t FileStream::GetLength() const +{ + if (IsValid()) + { + soff_t pos = (soff_t)ags_ftell(_file); + ags_fseek(_file, 0, SEEK_END); + soff_t end = (soff_t)ags_ftell(_file); + ags_fseek(_file, pos, SEEK_SET); + return end; + } + + return 0; +} + +soff_t FileStream::GetPosition() const +{ + if (IsValid()) + { + return (soff_t) ags_ftell(_file); + } + return -1; +} + +bool FileStream::CanRead() const +{ + return IsValid() && _workMode != kFile_Write; +} + +bool FileStream::CanWrite() const +{ + return IsValid() && _workMode != kFile_Read; +} + +bool FileStream::CanSeek() const +{ + return IsValid(); +} + +size_t FileStream::Read(void *buffer, size_t size) +{ + if (_file && buffer) + { + return fread(buffer, sizeof(uint8_t), size, _file); + } + return 0; +} + +int32_t FileStream::ReadByte() +{ + if (_file) + { + return fgetc(_file); + } + return -1; +} + +size_t FileStream::Write(const void *buffer, size_t size) +{ + if (_file && buffer) + { + return fwrite(buffer, sizeof(uint8_t), size, _file); + } + return 0; +} + +int32_t FileStream::WriteByte(uint8_t val) +{ + if (_file) + { + return fputc(val, _file); + } + return -1; +} + +bool FileStream::Seek(soff_t offset, StreamSeek origin) +{ + if (!_file) + { + return false; + } + + int stdclib_origin; + switch (origin) + { + case kSeekBegin: stdclib_origin = SEEK_SET; break; + case kSeekCurrent: stdclib_origin = SEEK_CUR; break; + case kSeekEnd: stdclib_origin = SEEK_END; break; + default: + // TODO: warning to the log + return false; + } + + return ags_fseek(_file, (file_off_t)offset, stdclib_origin) == 0; +} + +void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode) +{ + String mode = File::GetCMode(open_mode, work_mode); + if (mode.IsEmpty()) + throw std::runtime_error("Error determining open mode"); + _file = fopen(file_name, mode); + if (_file == nullptr) + throw std::runtime_error("Error opening file."); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h new file mode 100644 index 000000000000..d083da355f29 --- /dev/null +++ b/engines/ags/shared/util/filestream.h @@ -0,0 +1,77 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_UTIL__FILESTREAM_H +#define __AGS_CN_UTIL__FILESTREAM_H + +#include + +#include "util/datastream.h" +#include "util/file.h" // TODO: extract filestream mode constants + +namespace AGS +{ +namespace Common +{ + +class FileStream : public DataStream +{ +public: + + // Represents an open file object + // The constructor may raise std::runtime_error if + // - there is an issue opening the file (does not exist, locked, permissions, etc) + // - the open mode could not be determined + FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, + DataEndianess stream_endianess = kLittleEndian); + ~FileStream() override; + + bool HasErrors() const override; + void Close() override; + bool Flush() override; + + // Is stream valid (underlying data initialized properly) + bool IsValid() const override; + // Is end of stream + bool EOS() const override; + // Total length of stream (if known) + soff_t GetLength() const override; + // Current position (if known) + soff_t GetPosition() const override; + bool CanRead() const override; + bool CanWrite() const override; + bool CanSeek() const override; + + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; + + bool Seek(soff_t offset, StreamSeek origin) override; + +private: + void Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode); + + FILE *_file; + const FileOpenMode _openMode; + const FileWorkMode _workMode; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__FILESTREAM_H diff --git a/engines/ags/shared/util/geometry.cpp b/engines/ags/shared/util/geometry.cpp new file mode 100644 index 000000000000..06f9358df228 --- /dev/null +++ b/engines/ags/shared/util/geometry.cpp @@ -0,0 +1,133 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "util/geometry.h" +#include +#include + +//namespace AGS +//{ +//namespace Common +//{ + +bool AreRectsIntersecting(const Rect &r1, const Rect &r2) +{ // NOTE: remember that in AGS Y axis is pointed downwards + return r1.Left <= r2.Right && r1.Right >= r2.Left && + r1.Top <= r2.Bottom && r1.Bottom >= r2.Top; +} + +bool IsRectInsideRect(const Rect &place, const Rect &item) +{ + return item.Left >= place.Left && item.Right <= place.Right && + item.Top >= place.Top && item.Bottom <= place.Bottom; +} + +float DistanceBetween(const Rect &r1, const Rect &r2) +{ + // https://gamedev.stackexchange.com/a/154040 + Rect rect_outer( + std::min(r1.Left, r2.Left), + std::min(r1.Top, r2.Top), + std::max(r1.Right, r2.Right), + std::max(r1.Bottom, r2.Bottom) + ); + int inner_width = std::max(0, rect_outer.GetWidth() - r1.GetWidth() - r2.GetWidth()); + int inner_height = std::max(0, rect_outer.GetHeight() - r1.GetHeight() - r2.GetHeight()); + return std::sqrt(inner_width ^ 2 + inner_height ^ 2); +} + +Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h) +{ + int width = item_w ? dest_w : 0; + int height = item_w ? (dest_w * item_h / item_w) : 0; + if (height > dest_h) + { + width = item_h ? (dest_h * item_w / item_h) : 0; + height = dest_h; + } + return Size(width, height); +} + +Size ProportionalStretch(const Size &dest, const Size &item) +{ + return ProportionalStretch(dest.Width, dest.Height, item.Width, item.Height); +} + +int AlignInHRange(int x1, int x2, int off_x, int width, FrameAlignment align) +{ + if (align & kMAlignRight) + return off_x + x2 - width; + else if (align & kMAlignHCenter) + return off_x + x1 + ((x2 - x1 + 1) >> 1) - (width >> 1); + return off_x + x1; // kAlignLeft is default +} + +int AlignInVRange(int y1, int y2, int off_y, int height, FrameAlignment align) +{ + if (align & kMAlignBottom) + return off_y + y2 - height; + else if (align & kMAlignVCenter) + return off_y + y1 + ((y2 - y1 + 1) >> 1) - (height >> 1); + return off_y + y1; // kAlignTop is default +} + +Rect AlignInRect(const Rect &frame, const Rect &item, FrameAlignment align) +{ + int x = AlignInHRange(frame.Left, frame.Right, item.Left, item.GetWidth(), align); + int y = AlignInVRange(frame.Top, frame.Bottom, item.Top, item.GetHeight(), align); + + Rect dst_item = item; + dst_item.MoveTo(Point(x, y)); + return dst_item; +} + +Rect OffsetRect(const Rect &r, const Point off) +{ + return Rect(r.Left + off.X, r.Top + off.Y, r.Right + off.X, r.Bottom + off.Y); +} + +Rect CenterInRect(const Rect &place, const Rect &item) +{ + return RectWH((place.GetWidth() >> 1) - (item.GetWidth() >> 1), + (place.GetHeight() >> 1) - (item.GetHeight() >> 1), + item.GetWidth(), item.GetHeight()); +} + +Rect ClampToRect(const Rect &place, const Rect &item) +{ + return Rect( + AGSMath::Clamp(item.Left, place.Left, place.Right), + AGSMath::Clamp(item.Top, place.Top, place.Bottom), + AGSMath::Clamp(item.Right, place.Left, place.Right), + AGSMath::Clamp(item.Bottom, place.Top, place.Bottom) + ); +} + +Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement) +{ + switch (placement) + { + case kPlaceCenter: + return CenterInRect(place, item); + case kPlaceStretch: + return place; + case kPlaceStretchProportional: + return CenterInRect(place, + RectWH(ProportionalStretch(place.GetWidth(), place.GetHeight(), item.GetWidth(), item.GetHeight()))); + default: + return RectWH(place.Left + item.Left, place.Top + item.Top, item.GetWidth(), item.GetHeight()); + } +} + +//} // namespace Common +//} // namespace AGS diff --git a/engines/ags/shared/util/geometry.h b/engines/ags/shared/util/geometry.h new file mode 100644 index 000000000000..a3e3906736e0 --- /dev/null +++ b/engines/ags/shared/util/geometry.h @@ -0,0 +1,405 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Geometry data structures and helper functions +// +//============================================================================= +#ifndef __AGS_CN_UTIL__GEOMETRY_H +#define __AGS_CN_UTIL__GEOMETRY_H + +#include "util/math.h" + +namespace AGSMath = AGS::Common::Math; +//namespace AGS +//{ +//namespace Common +//{ + +// Type of alignment of a geometric item of rectangular boundaries. +enum FrameAlignment +{ + kAlignNone = 0, + + // Alignment options are representing 8 sides of a frame (rectangle); + // they are implemented as flags that may be combined together if it + // is wanted to define alignment to multiple sides at once. + kAlignTopLeft = 0x0001, + kAlignTopCenter = 0x0002, + kAlignTopRight = 0x0004, + kAlignMiddleLeft = 0x0008, + kAlignMiddleCenter = 0x0010, + kAlignMiddleRight = 0x0020, + kAlignBottomLeft = 0x0040, + kAlignBottomCenter = 0x0080, + kAlignBottomRight = 0x0100, + + // Masks are helping to determine whether alignment parameter contains + // particular horizontal or vertical component (for example: left side + // or bottom side) + kMAlignLeft = kAlignTopLeft | kAlignMiddleLeft | kAlignBottomLeft, + kMAlignRight = kAlignTopRight | kAlignMiddleRight | kAlignBottomRight, + kMAlignTop = kAlignTopLeft | kAlignTopCenter | kAlignTopRight, + kMAlignBottom = kAlignBottomLeft | kAlignBottomCenter | kAlignBottomRight, + kMAlignHCenter = kAlignTopCenter | kAlignMiddleCenter | kAlignBottomCenter, + kMAlignVCenter = kAlignMiddleLeft | kAlignMiddleCenter | kAlignMiddleRight +}; + +// Horizontal alignment; based on FrameAlignment, used to restrict alignment +// setting to left/right/center option, while keeping compatibility with any +// alignment in case it will be supported in the future. +enum HorAlignment +{ + kHAlignNone = kAlignNone, + kHAlignLeft = kAlignTopLeft, + kHAlignRight = kAlignTopRight, + kHAlignCenter = kAlignTopCenter +}; + +enum RectPlacement +{ + kPlaceOffset, + kPlaceCenter, + kPlaceStretch, + kPlaceStretchProportional, + kNumRectPlacement +}; + +struct Point +{ + int X; + int Y; + + Point() + { + X = 0; + Y = 0; + } + + Point(int x, int y) + { + X = x; + Y = y; + } + + inline bool operator ==(const Point &p) const + { + return X == p.X && Y == p.Y; + } + + inline bool operator !=(const Point &p) const + { + return X != p.X || Y != p.Y; + } + + inline Point operator +(const Point &p) const + { + return Point(X + p.X, Y + p.Y); + } +}; + +struct Line +{ + int X1; + int Y1; + int X2; + int Y2; + + Line() + { + X1 = 0; + Y1 = 0; + X2 = 0; + Y2 = 0; + } + + Line(int x1, int y1, int x2, int y2) + { + X1 = x1; + Y1 = y1; + X2 = x2; + Y2 = y2; + } +}; + +// Helper factory functions +inline Line HLine(int x1, int x2, int y) +{ + return Line(x1, y, x2, y); +} + +inline Line VLine(int x, int y1, int y2) +{ + return Line(x, y1, x, y2); +} + +struct Size +{ + int Width; + int Height; + + Size() + { + Width = 0; + Height = 0; + } + + Size(int width, int height) + { + Width = width; + Height = height; + } + + inline bool IsNull() const + { + return Width <= 0 || Height <= 0; + } + + inline static Size Clamp(const Size &sz, const Size &floor, const Size &ceil) + { + return Size(AGSMath::Clamp(sz.Width, floor.Width, ceil.Width), + AGSMath::Clamp(sz.Height, floor.Height, ceil.Height)); + } + + // Indicates if current size exceeds other size by any metric + inline bool ExceedsByAny(const Size size) const + { + return Width > size.Width || Height > size.Height; + } + + inline bool operator==(const Size size) const + { + return Width == size.Width && Height == size.Height; + } + + inline bool operator!=(const Size size) const + { + return Width != size.Width || Height != size.Height; + } + + inline bool operator<(const Size &other) const + { // TODO: this implementation is silly and not universally useful; make a realistic one and replace with another function where necessary + return Width < other.Width || (Width == other.Width && Height < other.Height); + } + + inline Size operator *(int x) const + { + return Size(Width * x, Height * x); + } + + inline Size operator /(int x) const + { + return Size(Width / x, Height / x); + } + + inline Size &operator *=(int x) + { + Width *= x; + Height *= x; + return *this; + } + + inline Size &operator /=(int x) + { + Width /= x; + Height /= x; + return *this; + } +}; + +// TODO: consider making Rect have right-bottom coordinate with +1 offset +// to comply with many other libraries (i.e. Right - Left == Width) +struct Rect +{ + int Left; + int Top; + int Right; + int Bottom; + + Rect() + { + Left = 0; + Top = 0; + Right = -1; + Bottom = -1; + } + + Rect(int l, int t, int r, int b) + { + Left = l; + Top = t; + Right = r; + Bottom = b; + } + + inline Point GetLT() const + { + return Point(Left, Top); + } + + inline Point GetCenter() const + { + return Point(Left + GetWidth() / 2, Top + GetHeight() / 2); + } + + inline int GetWidth() const + { + return Right - Left + 1; + } + + inline int GetHeight() const + { + return Bottom - Top + 1; + } + + inline Size GetSize() const + { + return Size(GetWidth(), GetHeight()); + } + + inline bool IsEmpty() const + { + return Right < Left || Bottom < Top; + } + + inline bool IsInside(int x, int y) const + { + return x >= Left && y >= Top && (x <= Right) && (y <= Bottom); + } + + inline bool IsInside(const Point &pt) const + { + return IsInside(pt.X, pt.Y); + } + + inline void MoveToX(int x) + { + Right += x - Left; + Left = x; + } + + inline void MoveToY(int y) + { + Bottom += y - Top; + Top = y; + } + + inline void MoveTo(const Point &pt) + { + MoveToX(pt.X); + MoveToY(pt.Y); + } + + inline void SetWidth(int width) + { + Right = Left + width - 1; + } + + inline void SetHeight(int height) + { + Bottom = Top + height - 1; + } + + inline static Rect MoveBy(const Rect &r, int x, int y) + { + return Rect(r.Left + x, r.Top + y, r.Right + x, r.Bottom + y); + } +}; + +// Helper factory function +inline Rect RectWH(int x, int y, int width, int height) +{ + return Rect(x, y, x + width - 1, y + height - 1); +} + +inline Rect RectWH(const Size &sz) +{ + return Rect(0, 0, sz.Width - 1, sz.Height - 1); +} + + +struct Triangle +{ + int X1; + int Y1; + int X2; + int Y2; + int X3; + int Y3; + + Triangle() + { + X1 = 0; + Y1 = 0; + X2 = 0; + Y2 = 0; + X3 = 0; + Y3 = 0; + } + + Triangle(int x1, int y1, int x2, int y2, int x3, int y3) + { + X1 = x1; + Y1 = y1; + X2 = x2; + Y2 = y2; + X3 = x3; + Y3 = y3; + } +}; + +struct Circle +{ + int X; + int Y; + int Radius; + + Circle() + { + X = 0; + Y = 0; + Radius = 0; + } + + Circle(int x, int y, int radius) + { + X = x; + Y = y; + Radius = radius; + } + +}; + + +// Tells if two rectangles intersect (overlap) at least partially +bool AreRectsIntersecting(const Rect &r1, const Rect &r2); +// Tells if the item is completely inside place +bool IsRectInsideRect(const Rect &place, const Rect &item); +// Calculates a distance between two axis-aligned rectangles +float DistanceBetween(const Rect &r1, const Rect &r2); + +int AlignInHRange(int x1, int x2, int off_x, int width, FrameAlignment align); +int AlignInVRange(int y1, int y2, int off_y, int height, FrameAlignment align); +Rect AlignInRect(const Rect &frame, const Rect &item, FrameAlignment align); + +Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h); +Size ProportionalStretch(const Size &dest, const Size &item); + +Rect OffsetRect(const Rect &r, const Point off); +Rect CenterInRect(const Rect &place, const Rect &item); +Rect ClampToRect(const Rect &place, const Rect &item); +Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement); +//} // namespace Common +//} // namespace AGS + +#endif // __AGS_CN_UTIL__GEOMETRY_H diff --git a/engines/ags/shared/util/ini_util.cpp b/engines/ags/shared/util/ini_util.cpp new file mode 100644 index 000000000000..2ee0943d9e45 --- /dev/null +++ b/engines/ags/shared/util/ini_util.cpp @@ -0,0 +1,194 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "util/file.h" +#include "util/ini_util.h" +#include "util/inifile.h" +#include "util/stream.h" +#include "util/textstreamwriter.h" + +namespace AGS +{ +namespace Common +{ + +typedef std::unique_ptr UStream; +typedef IniFile::SectionIterator SectionIterator; +typedef IniFile::ConstSectionIterator CSectionIterator; +typedef IniFile::ItemIterator ItemIterator; +typedef IniFile::ConstItemIterator CItemIterator; + +static bool ReadIni(const String &file, IniFile &ini) +{ + UStream fs(File::OpenFileRead(file)); + if (fs.get()) + { + ini.Read(fs.get()); + return true; + } + return false; +} + +bool IniUtil::Read(const String &file, ConfigTree &tree) +{ + // Read ini content + IniFile ini; + if (!ReadIni(file, ini)) + return false; + + // Copy items into key-value tree + for (CSectionIterator sec = ini.CBegin(); sec != ini.CEnd(); ++sec) + { + if (!sec->GetItemCount()) + continue; // skip empty sections + StringOrderMap &subtree = tree[sec->GetName()]; + for (CItemIterator item = sec->CBegin(); item != sec->CEnd(); ++item) + { + if (!item->IsKeyValue()) + continue; // skip non key-value items + subtree[item->GetKey()] = item->GetValue(); + } + } + return true; +} + +void IniUtil::Write(const String &file, const ConfigTree &tree) +{ + UStream fs(File::CreateFile(file)); + TextStreamWriter writer(fs.get()); + + for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) + { + const String &sec_key = it_sec->first; + const StringOrderMap &sec_tree = it_sec->second; + + if (!sec_tree.size()) + continue; // skip empty sections + // write section name + if (!sec_key.IsEmpty()) + { + writer.WriteFormat("[%s]", sec_key.GetCStr()); + writer.WriteLineBreak(); + } + // write all items + for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) + { + const String &item_key = keyval->first; + const String &item_value = keyval->second; + + writer.WriteFormat("%s = %s", item_key.GetCStr(), item_value.GetCStr()); + writer.WriteLineBreak(); + } + } + + writer.ReleaseStream(); +} + +void IniUtil::WriteToString(String &s, const ConfigTree &tree) +{ + for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) + { + const String &sec_key = it_sec->first; + const StringOrderMap &sec_tree = it_sec->second; + if (!sec_tree.size()) + continue; // skip empty sections + // write section name + if (!sec_key.IsEmpty()) + s.Append(String::FromFormat("[%s]\n", sec_key.GetCStr())); + // write all items + for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) + s.Append(String::FromFormat("%s = %s\n", keyval->first.GetCStr(), keyval->second.GetCStr())); + } +} + +bool IniUtil::Merge(const String &file, const ConfigTree &tree) +{ + // Read ini content + IniFile ini; + ReadIni(file, ini); // NOTE: missing file is a valid case + + // Remember the sections we find in file, if some sections are not found, + // they will be appended to the end of file. + std::map sections_found; + for (ConfigNode it = tree.begin(); it != tree.end(); ++it) + sections_found[it->first] = false; + + // Merge existing sections + for (SectionIterator sec = ini.Begin(); sec != ini.End(); ++sec) + { + if (!sec->GetItemCount()) + continue; // skip empty sections + String secname = sec->GetName(); + ConfigNode tree_node = tree.find(secname); + if (tree_node == tree.end()) + continue; // this section is not interesting for us + + // Remember the items we find in this section, if some items are not found, + // they will be appended to the end of section. + const StringOrderMap &subtree = tree_node->second; + std::map items_found; + for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) + items_found[keyval->first] = false; + + // Replace matching items + for (ItemIterator item = sec->Begin(); item != sec->End(); ++item) + { + String key = item->GetKey(); + StrStrOIter keyval = subtree.find(key); + if (keyval == subtree.end()) + continue; // this item is not interesting for us + + String old_value = item->GetValue(); + String new_value = keyval->second; + if (old_value != new_value) + item->SetValue(new_value); + items_found[key] = true; + } + + // Append new items + if (!sections_found[secname]) + { + for (std::map::const_iterator item_f = items_found.begin(); item_f != items_found.end(); ++item_f) + { + if (item_f->second) + continue; // item was already found + StrStrOIter keyval = subtree.find(item_f->first); + ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); + } + sections_found[secname] = true; // mark section as known + } + } + + // Add new sections + for (std::map::const_iterator sec_f = sections_found.begin(); sec_f != sections_found.end(); ++sec_f) + { + if (sec_f->second) + continue; + SectionIterator sec = ini.InsertSection(ini.End(), sec_f->first); + const StringOrderMap &subtree = tree.find(sec_f->first)->second; + for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) + ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); + } + + // Write the resulting set of lines + UStream fs(File::CreateFile(file)); + if (!fs.get()) + return false; + ini.Write(fs.get()); + return true; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h new file mode 100644 index 000000000000..50eca7f2a580 --- /dev/null +++ b/engines/ags/shared/util/ini_util.h @@ -0,0 +1,66 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Functions for exchanging configuration data between key-value tree and +// INI file. +// +//============================================================================= +#ifndef __AGS_CN_UTIL__INIUTIL_H +#define __AGS_CN_UTIL__INIUTIL_H + +#include +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +typedef std::map StringOrderMap; +typedef StringOrderMap::const_iterator StrStrOIter; + +typedef std::map ConfigTree; +typedef ConfigTree::const_iterator ConfigNode; + +namespace IniUtil +{ + // Parse the contents of given file as INI format and insert values + // into the tree. The pre-existing tree items, if any, are NOT erased. + // Returns FALSE if the file could not be opened. + bool Read(const String &file, ConfigTree &tree); + // Serialize given tree to the stream in INI text format. + // The INI format suggests only one nested level (group - items). + // The first level values are treated as a global section items. + // The sub-nodes beyond 2nd level are ignored completely. + void Write(const String &file, const ConfigTree &tree); + // Serialize given tree to the string in INI text format. + // TODO: implement proper memory/string stream compatible with base Stream + // class and merge this with Write function. + void WriteToString(String &s, const ConfigTree &tree); + // Parse the contents of given source stream as INI format and merge + // with values of the given tree while doing only minimal replaces; + // write the result into destination stream. + // If item already exists, only value is overwrited, if section exists, + // new items are appended to the end of it; completely new sections are + // appended to the end of text. + // Source and destination streams may refer either to different objects, + // or same stream opened for both reading and writing. + // Returns FALSE if the file could not be opened for writing. + bool Merge(const String &file, const ConfigTree &tree); +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__INIUTIL_H diff --git a/engines/ags/shared/util/inifile.cpp b/engines/ags/shared/util/inifile.cpp new file mode 100644 index 000000000000..10665dd2dc70 --- /dev/null +++ b/engines/ags/shared/util/inifile.cpp @@ -0,0 +1,301 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include +#include "util/inifile.h" +#include "util/textstreamreader.h" +#include "util/textstreamwriter.h" + +// TODO: replace with C++11 std::isblank library function +namespace agsstd +{ +inline int isblank(int ch) +{ + return ch == ' ' || ch == '\t'; +} +} // std + +namespace AGS +{ +namespace Common +{ + +inline static void ReplaceSubString(String &line, IniFile::StrPos &sub_pos, const String &new_sub) +{ + line.ReplaceMid(sub_pos.first, sub_pos.second - sub_pos.first, new_sub); +} + +IniFile::ItemDef::ItemDef(const String &key, const String &value) +{ + Line = String::FromFormat("%s=%s", key.GetCStr(), value.GetCStr()); + Key.first = 0; + Key.second = Key.first + key.GetLength(); + SepAt = Key.second; + Value.first = Key.second + 1; + Value.second = Value.first + value.GetLength(); +} + +IniFile::ItemDef::ItemDef(const String &line, const StrPos &key, const StrPos &value, int sep_at) +{ + Line = line; + Key = key; + Value = value; + SepAt = sep_at; +} + +void IniFile::ItemDef::SetKey(const String &key) +{ + if (key.IsEmpty()) + return; + + if (IsKeyValue()) + { + int diff = key.GetLength() - (Key.second - Key.first); + ReplaceSubString(Line, Key, key); + Key.second += diff; + Value.first += diff; + Value.second += diff; + } + else + { + *this = ItemDef(key, ""); + } +} + +void IniFile::ItemDef::SetValue(const String &value) +{ + if (!IsKeyValue()) + return; // no key + + if (SepAt > 0) + { // replacing existing value + int diff = static_cast(value.GetLength()) - (Value.second - Value.first); + ReplaceSubString(Line, Value, value); + Value.second += diff; + } + else + { // inserting value behind the key + StrPos valpos(Key.second, Key.second); + ReplaceSubString(Line, valpos, String::FromFormat("=%s", value.GetCStr())); + } +} + +IniFile::SectionDef::SectionDef(const String &name) +{ + if (name.IsEmpty()) + { + // global section + Name = StrPos(0,0); + } + else + { + // named section + Header = String::FromFormat("[%s]", name.GetCStr()); + Name.first = 1; + Name.second = 1 + Header.GetLength(); + } +} + +IniFile::SectionDef::SectionDef(const String &line, const StrPos &name) +{ + Header = line; + Name = name; +} + +void IniFile::SectionDef::SetName(const String &sec_name) +{ + if (sec_name.IsEmpty()) + return; + + int diff = sec_name.GetLength() - (Name.second - Name.first); + ReplaceSubString(Header, Name, sec_name); + Name.second += diff; +} + +void IniFile::SectionDef::Clear() +{ + Items.clear(); +} + +IniFile::ItemIterator IniFile::SectionDef::InsertItem(ItemIterator item, const ItemDef &itemdef) +{ + return Items.insert(item, itemdef); +} + +void IniFile::SectionDef::EraseItem(ItemIterator item) +{ + Items.erase(item); +} + +IniFile::ItemIterator IniFile::InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value) +{ + ItemDef itemdef(key, value); + return sec->InsertItem(item, itemdef); +} + +IniFile::SectionIterator IniFile::InsertSection(SectionIterator sec, const String &name) +{ + if (name.IsEmpty()) + return _sections.end(); // do not allow adding random global sections + + SectionDef secdef(name); + return _sections.insert(sec, secdef); +} + +void IniFile::RemoveItem(SectionIterator sec, ItemIterator item) +{ + sec->EraseItem(item); +} + +void IniFile::RemoveSection(SectionIterator sec) +{ + if (sec == _sections.begin()) + // do not remove global section, clear items instead + sec->Clear(); + else + _sections.erase(sec); +} + + +// Moves string pointer forward to the first non-space character +const char *SkipSpace(const char *line, const char *endl) +{ + for (; line != endl && isspace(*line); ++line); + return line; +} + +// Parse given line and extract a meaningful string; +// Parses line from 'line' to 'endl', skips padding (spaces) +// at the beginning and the end. Assignes the starting and ending +// pointers of the string. Returns pointer to where parsing stopped. +// The 'endl' must point beyond the last character of the string +// (e.g. terminator). +const char *ParsePaddedString(const char *line, const char *endl, + const char *&str_at, const char *&str_end) +{ + // skip left padding + for (; line != endl && agsstd::isblank(*line); ++line); + str_at = line; + // skip right padding + const char *p_value = line; + for (line = endl; line != p_value && agsstd::isblank(*(line - 1)); --line); + str_end = line; + return line; +} + +IniFile::IniFile() +{ + // precreate global section + _sections.push_back(SectionDef("")); +} + +void IniFile::Read(Stream *in) +{ + TextStreamReader reader(in); + + _sections.clear(); + // Create a global section; + // all the items we meet before explicit section declaration + // will be treated as "global" items. + _sections.push_back(SectionDef("")); + SectionDef *cur_section = &_sections.back(); + + do + { + String line = reader.ReadLine(); + if (line.IsEmpty() && reader.EOS()) + break; + + const char *cstr = line.GetCStr(); + const char *pstr = cstr; + const char *endl = cstr + line.GetLength(); + + // Find first non-space character + pstr = SkipSpace(pstr, endl); + if (pstr == endl) + continue; // empty line + + // Detect the kind of string we found + if ((endl - pstr >= 2 && *pstr == '/' && *(pstr + 1) == '/') || + (endl - pstr >= 1 && (*pstr == '#' || *pstr == ';'))) + { + StrPos nullpos(0,0); + cur_section->InsertItem(cur_section->End(), ItemDef(line, nullpos, nullpos, -1)); + continue; + } + + if (*pstr == '[') + { + // Parse this as section + const char *pstr_end = strrchr(pstr, ']'); + if (pstr_end < pstr) + continue; // no closing bracket + // Parse the section name + const char *str_at, *str_end; + ParsePaddedString(++pstr, pstr_end, str_at, str_end); + if (str_end == str_at) + continue; // inappropriate data or empty string + StrPos namepos(str_at - cstr, str_end - cstr); + _sections.push_back(SectionDef(line, namepos)); + cur_section = &_sections.back(); + } + else + { + // Parse this as a key-value pair + const char *pstr_end = strchr(pstr, '='); + if (pstr_end == pstr) + continue; // no key part, skip the line + if (!pstr_end) + pstr_end = endl; // no value part + // Parse key + const char *str_at, *str_end; + ParsePaddedString(pstr, pstr_end, str_at, str_end); + pstr = pstr_end; + if (str_end == str_at) + continue; // inappropriate data or empty string + // Create an item and parse value, if any + StrPos keypos(str_at - cstr, str_end - cstr); + StrPos valpos(0, 0); + int sep_at = -1; + if (pstr != endl) + { + sep_at = pstr - cstr; + ParsePaddedString(++pstr, endl, str_at, str_end); + valpos.first = str_at - cstr; + valpos.second = str_end - cstr; + } + cur_section->InsertItem(cur_section->End(), ItemDef(line, keypos, valpos, sep_at)); + } + } + while (!reader.EOS()); + + reader.ReleaseStream(); +} + +void IniFile::Write(Stream *out) const +{ + TextStreamWriter writer(out); + for (ConstSectionIterator sec = _sections.begin(); sec != _sections.end(); ++sec) + { + if (sec != _sections.begin()) // do not write global section's name + writer.WriteLine(sec->GetLine()); + for (ConstItemIterator item = sec->CBegin(); item != sec->CEnd(); ++item) + writer.WriteLine(item->GetLine()); + } + writer.ReleaseStream(); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h new file mode 100644 index 000000000000..0f26ce5cfb80 --- /dev/null +++ b/engines/ags/shared/util/inifile.h @@ -0,0 +1,134 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// IniFile class defines contents of the configuration file. +// It serves as a INI parser and plain enumerator of all the sections and items +// found in file, or, oppositely, as INI file constructor. +// But is not much suitable for regular key/value lookup. It is suggested to +// create a proper map to store items, from IniFile contents. +// +//============================================================================= +#ifndef __AGS_CN_UTIL__INIFILE_H +#define __AGS_CN_UTIL__INIFILE_H + +#include +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +class IniFile +{ +public: + // Position of a string in the line of text: + // is defined by a pair of first and next-after-last character indices + typedef std::pair StrPos; + // Location of section in the array of text lines: + // is defined by a pair of first and next-after-last line indices + typedef std::pair SectionPos; + + // Item definition + // Valid key indicates a key-value line; no key means unparsed + // line of text, e.g. comment or incorrectly formatted item. + class ItemDef + { + public: + ItemDef(const String &key, const String &value); + ItemDef(const String &line, const StrPos &key, const StrPos &value, int sep_at); + String GetLine() const { return Line; } + String GetKey() const { return SubString(Line, Key); } + String GetValue() const { return SubString(Line, Value); } + bool IsKeyValue() const { return Key.second - Key.first > 0; } + void SetKey(const String &key); + void SetValue(const String &value); + + private: + String Line; // actual text + StrPos Key; // position of item key + int SepAt; // position of the separator (assignment) symbol + StrPos Value; // position of item value + }; + // Linked list of items + typedef std::list LItems; + typedef LItems::iterator ItemIterator; + typedef LItems::const_iterator ConstItemIterator; + + // Section definition + class SectionDef + { + public: + SectionDef(const String &name); + SectionDef(const String &line, const StrPos &name); + String GetLine() const { return Header; } + String GetName() const { return SubString(Header, Name); } + size_t GetItemCount() const { return Items.size(); } + bool IsGlobal() const { return Name.second - Name.first <= 0; } + ItemIterator Begin() { return Items.begin(); } + ItemIterator End() { return Items.end(); } + ConstItemIterator CBegin() const { return Items.begin(); } + ConstItemIterator CEnd() const { return Items.end(); } + void SetName(const String &sec_name); + void Clear(); + ItemIterator InsertItem(ItemIterator item, const ItemDef &itemdef); + void EraseItem(ItemIterator item); + + private: + String Header;// section's heading line + StrPos Name; // location of section name in the header line + LItems Items; // linked list of items belonging to the section + }; + // Linked list of sections + typedef std::list LSections; + typedef LSections::iterator SectionIterator; + typedef LSections::const_iterator ConstSectionIterator; + +private: + inline static String SubString(const String &line, const StrPos &pos) + { + return line.Mid(pos.first, pos.second - pos.first); + } + +public: + IniFile(); + + SectionIterator Begin() { return _sections.begin(); } + SectionIterator End() { return _sections.end(); } + ConstSectionIterator CBegin() const { return _sections.begin(); } + ConstSectionIterator CEnd() const { return _sections.end(); } + + void Read(Stream *in); + void Write(Stream *out) const; + + // Return number of sections + size_t GetSectionCount() const { return _sections.size(); } + // Insert new item *before* existing item + ItemIterator InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value); + // Insert new section *before* existing section + SectionIterator InsertSection(SectionIterator sec, const String &name); + // Remove a single item + void RemoveItem(SectionIterator sec, ItemIterator item); + // Completely remove whole section; this removes all lines between section + // header and the last item found in that section (inclusive). + void RemoveSection(SectionIterator sec); + +private: + LSections _sections; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__INIFILE_H diff --git a/engines/ags/shared/util/lzw.cpp b/engines/ags/shared/util/lzw.cpp new file mode 100644 index 000000000000..7eadcd8e281f --- /dev/null +++ b/engines/ags/shared/util/lzw.cpp @@ -0,0 +1,271 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// LZW compression -- the LZW/GIF patent has expired, so we can use it now!!! +// +//============================================================================= + +#include +#include "ac/common.h" // quit +#include "util/stream.h" + +using namespace AGS::Common; + +#ifdef _MANAGED +// ensure this doesn't get compiled to .NET IL +#pragma unmanaged +#endif + +int insert(int, int); +void _delete(int); + +#define N 4096 +#define F 16 +#define THRESHOLD 3 +#define min(xx,yy) ((yy match) { + match = n; + pos = j; + } + + if (c < 0) { + p = &lson[j]; + k = n; + } else if (c > 0) { + p = &rson[j]; + l = n; + } else { + dad[j] = NIL; + dad[lson[j]] = lson + i - node; + dad[rson[j]] = rson + i - node; + lson[i] = lson[j]; + rson[i] = rson[j]; + break; + } + } + + dad[i] = p - node; + *p = i; + return match; +} + +void _delete(int z) +{ + int j; + + if (dad[z] != NIL) { + if (rson[z] == NIL) + j = lson[z]; + else if (lson[z] == NIL) + j = rson[z]; + else { + j = lson[z]; + if (rson[j] != NIL) { + do { + j = rson[j]; + } while (rson[j] != NIL); + + node[dad[j]] = lson[j]; + dad[lson[j]] = dad[j]; + lson[j] = lson[z]; + dad[lson[z]] = lson + j - node; + } + + rson[j] = rson[z]; + dad[rson[z]] = rson + j - node; + } + + dad[j] = dad[z]; + node[dad[z]] = j; + dad[z] = NIL; + } +} + +void lzwcompress(Stream *lzw_in, Stream *out) +{ + int ch, i, run, len, match, size, mask; + char buf[17]; + + lzbuffer = (char *)malloc(N + F + (N + 1 + N + N + 256) * sizeof(int)); // 28.5 k ! + if (lzbuffer == nullptr) { + quit("unable to compress: out of memory"); + } + + node = (int *)(lzbuffer + N + F); + for (i = 0; i < 256; i++) + root[i] = NIL; + + for (i = NIL; i < N; i++) + dad[i] = NIL; + + size = mask = 1; + buf[0] = 0; + i = N - F - F; + + for (len = 0; len < F && (ch = lzw_in->ReadByte()) != -1; len++) { + lzbuffer[i + F] = ch; + i = (i + 1) & (N - 1); + } + + run = len; + + do { + ch = lzw_in->ReadByte(); + if (i >= N - F) { + _delete(i + F - N); + lzbuffer[i + F] = lzbuffer[i + F - N] = ch; + } else { + _delete(i + F); + lzbuffer[i + F] = ch; + } + + match = insert(i, run); + if (ch == -1) { + run--; + len--; + } + + if (len++ >= run) { + if (match >= THRESHOLD) { + buf[0] |= mask; + // possible fix: change int* to short* ?? + *(short *)(buf + size) = ((match - 3) << 12) | ((i - pos - 1) & (N - 1)); + size += 2; + len -= match; + } else { + buf[size++] = lzbuffer[i]; + len--; + } + + if (!((mask += mask) & 0xFF)) { + out->WriteArray(buf, size, 1); + outbytes += size; + size = mask = 1; + buf[0] = 0; + } + } + i = (i + 1) & (N - 1); + } while (len > 0); + + if (size > 1) { + out->WriteArray(buf, size, 1); + outbytes += size; + } + + free(lzbuffer); +} + +int expand_to_mem = 0; +unsigned char *membfptr = nullptr; +void myputc(int ccc, Stream *out) +{ + if (maxsize > 0) { + putbytes++; + if (putbytes > maxsize) + return; + } + + outbytes++; + if (expand_to_mem) { + membfptr[0] = ccc; + membfptr++; + } else + out->WriteInt8(ccc); +} + +void lzwexpand(Stream *lzw_in, Stream *out) +{ + int bits, ch, i, j, len, mask; + char *lzbuffer; +// printf(" UnShrinking: %s ",filena); + putbytes = 0; + + lzbuffer = (char *)malloc(N); + if (lzbuffer == nullptr) { + quit("compress.cpp: unable to decompress: insufficient memory"); + } + i = N - F; + + // this end condition just checks for EOF, which is no good to us + while ((bits = lzw_in->ReadByte()) != -1) { + for (mask = 0x01; mask & 0xFF; mask <<= 1) { + if (bits & mask) { + // MACPORT FIX: read to short and expand + short jshort = 0; + jshort = lzw_in->ReadInt16(); + j = jshort; + + len = ((j >> 12) & 15) + 3; + j = (i - j - 1) & (N - 1); + + while (len--) { + myputc(lzbuffer[i] = lzbuffer[j], out); + j = (j + 1) & (N - 1); + i = (i + 1) & (N - 1); + } + } else { + ch = lzw_in->ReadByte(); + myputc(lzbuffer[i] = ch, out); + i = (i + 1) & (N - 1); + } + + if ((putbytes >= maxsize) && (maxsize > 0)) + break; + + if ((lzw_in->EOS()) && (maxsize > 0)) + quit("Read error decompressing image - file is corrupt"); + } // end for mask + + if ((putbytes >= maxsize) && (maxsize > 0)) + break; + } + + free(lzbuffer); + expand_to_mem = 0; +} + +unsigned char *lzwexpand_to_mem(Stream *in) +{ + unsigned char *membuff = (unsigned char *)malloc(maxsize + 10); + expand_to_mem = 1; + membfptr = membuff; + lzwexpand(in, nullptr); + return membuff; +} diff --git a/engines/ags/shared/util/lzw.h b/engines/ags/shared/util/lzw.h new file mode 100644 index 000000000000..b3c1af849b27 --- /dev/null +++ b/engines/ags/shared/util/lzw.h @@ -0,0 +1,29 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_UTIL__LZW_H +#define __AGS_CN_UTIL__LZW_H + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +void lzwcompress(Common::Stream *lzw_in, Common::Stream *out); +unsigned char *lzwexpand_to_mem(Common::Stream *in); + +extern long outbytes, maxsize, putbytes; + +#endif // __AGS_CN_UTIL__LZW_H diff --git a/engines/ags/shared/util/math.h b/engines/ags/shared/util/math.h new file mode 100644 index 000000000000..07367591984b --- /dev/null +++ b/engines/ags/shared/util/math.h @@ -0,0 +1,90 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Helper math functions +// +//============================================================================= +#ifndef __AGS_CN_UTIL__MATH_H +#define __AGS_CN_UTIL__MATH_H + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +namespace AGS +{ +namespace Common +{ + +namespace Math +{ + template + inline const T &Max(const T &a, const T &b) + { + return a < b ? b : a; + } + + template + inline const T &Min(const T &a, const T &b) + { + return a < b ? a : b; + } + + template + inline const T &Clamp(const T &val, const T &floor, const T &ceil) + { + return Max(floor, Min(val, ceil)); + } + + template + inline void ClampLength(T &from, T &length, const T &floor, const T &height) + { + if (from < floor) + { + length -= floor - from; + from = floor; + } + else if (from >= floor + height) + { + from = floor + height; + length = 0; + } + + length = Max(length, 0); + length = Min(length, height - from); + } + + // Get a measure of how value A is greater than value B; + // if A is smaller than or equal to B, returns 0. + template + inline T Surplus(const T &larger, const T &smaller) + { + return larger > smaller ? larger - smaller : 0; + } + + inline float RadiansToDegrees(float rads) + { + return rads * (float)(180.0 / M_PI); + } + + inline float DegreesToRadians(float deg) + { + return deg * (float)(M_PI / 180.0); + } +} // namespace Math + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__MATH_H diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h new file mode 100644 index 000000000000..5e049d74e595 --- /dev/null +++ b/engines/ags/shared/util/memory.h @@ -0,0 +1,245 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Memory utils and algorithms +// +//============================================================================= +#ifndef __AGS_CN_UTIL__MEMORY_H +#define __AGS_CN_UTIL__MEMORY_H + +#include +#include "util/bbop.h" +#include "util/math.h" + +#if defined (AGS_STRICT_ALIGNMENT) || defined (TEST_STRICT_ALIGNMENT) +#define MEMORY_STRICT_ALIGNMENT +#endif + +namespace AGS +{ +namespace Common +{ + +namespace Memory +{ + //------------------------------------------------------------------------- + // Converts pointer to 32-bit integer value and vice-versa. + // Only for use in special cases for compatibility with 32-bit plugin API. + // Dangerous on 64-bit systems. + //------------------------------------------------------------------------- + template + inline int32_t PtrToInt32(T *ptr) + { + return static_cast(reinterpret_cast(ptr)); + } + template + inline T *Int32ToPtr(int32_t value) + { + return reinterpret_cast(static_cast(value)); + } + + //------------------------------------------------------------------------- + // Functions for reading and writing basic types from/to the memory. + // Implement safety workaround for CPUs with alignment restrictions + // (e.g. MIPS). + //------------------------------------------------------------------------- + inline int16_t ReadInt16(const void *ptr) + { + #if defined (MEMORY_STRICT_ALIGNMENT) + const uint8_t *b = (const uint8_t *)ptr; + #if defined (BITBYTE_BIG_ENDIAN) + return (b[0] << 8) | b[1]; + #else + return (b[1] << 8) | b[0]; + #endif + #else + return *(int16_t*)ptr; + #endif + } + + inline int32_t ReadInt32(const void *ptr) + { + #if defined (MEMORY_STRICT_ALIGNMENT) + const uint8_t *b = (const uint8_t *)ptr; + #if defined (BITBYTE_BIG_ENDIAN) + return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; + #else + return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; + #endif + #else + return *(int32_t*)ptr; + #endif + } + + inline int64_t ReadInt64(const void *ptr) + { + #if defined (MEMORY_STRICT_ALIGNMENT) + const uint8_t *b = (const uint8_t *)ptr; + #if defined (BITBYTE_BIG_ENDIAN) + return ((uint64_t)b[0] << 56) | ((uint64_t)b[1] << 48) | ((uint64_t)b[2] << 40) | ((uint64_t)b[3] << 32) | + (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; + #else + return ((uint64_t)b[7] << 56) | ((uint64_t)b[6] << 48) | ((uint64_t)b[5] << 40) | ((uint64_t)b[4] << 32) | + (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; + #endif + #else + return *(int64_t*)ptr; + #endif + } + + inline void WriteInt16(void *ptr, int16_t value) + { + #if defined (MEMORY_STRICT_ALIGNMENT) + uint8_t *b = (uint8_t *)ptr; + #if defined (BITBYTE_BIG_ENDIAN) + b[0] = (uint8_t)(value >> 8); + b[1] = (uint8_t)(value); + #else + b[1] = (uint8_t)(value >> 8); + b[0] = (uint8_t)(value); + #endif + #else + *(int16_t*)ptr = value; + #endif + } + + inline void WriteInt32(void *ptr, int32_t value) + { + #if defined (MEMORY_STRICT_ALIGNMENT) + uint8_t *b = (uint8_t *)ptr; + #if defined (BITBYTE_BIG_ENDIAN) + b[0] = (uint8_t)(value >> 24); + b[1] = (uint8_t)(value >> 16); + b[2] = (uint8_t)(value >> 8); + b[3] = (uint8_t)(value); + #else + b[3] = (uint8_t)(value >> 24); + b[2] = (uint8_t)(value >> 16); + b[1] = (uint8_t)(value >> 8); + b[0] = (uint8_t)(value); + #endif + #else + *(int32_t*)ptr = value; + #endif + } + + inline void WriteInt64(void *ptr, int64_t value) + { + #if defined (MEMORY_STRICT_ALIGNMENT) + uint8_t *b = (uint8_t *)ptr; + #if defined (BITBYTE_BIG_ENDIAN) + b[0] = (uint8_t)(value >> 56); + b[1] = (uint8_t)(value >> 48); + b[2] = (uint8_t)(value >> 40); + b[3] = (uint8_t)(value >> 32); + b[4] = (uint8_t)(value >> 24); + b[5] = (uint8_t)(value >> 16); + b[6] = (uint8_t)(value >> 8); + b[7] = (uint8_t)(value); + #else + b[7] = (uint8_t)(value >> 56); + b[6] = (uint8_t)(value >> 48); + b[5] = (uint8_t)(value >> 40); + b[4] = (uint8_t)(value >> 32); + b[3] = (uint8_t)(value >> 24); + b[2] = (uint8_t)(value >> 16); + b[1] = (uint8_t)(value >> 8); + b[0] = (uint8_t)(value); + #endif + #else + *(int64_t*)ptr = value; + #endif + } + + //------------------------------------------------------------------------- + // Helpers for reading and writing from memory with respect for endianess. + //------------------------------------------------------------------------- + inline int16_t ReadInt16LE(const void *ptr) + { + return BBOp::Int16FromLE(ReadInt16(ptr)); + } + + inline int32_t ReadInt32LE(const void *ptr) + { + return BBOp::Int32FromLE(ReadInt32(ptr)); + } + + inline int64_t ReadInt64LE(const void *ptr) + { + return BBOp::Int64FromLE(ReadInt64(ptr)); + } + + inline void WriteInt16LE(void *ptr, int16_t value) + { + WriteInt16(ptr, BBOp::Int16FromLE(value)); + } + + inline void WriteInt32LE(void *ptr, int32_t value) + { + WriteInt32(ptr, BBOp::Int32FromLE(value)); + } + + inline void WriteInt64LE(void *ptr, int64_t value) + { + WriteInt64(ptr, BBOp::Int64FromLE(value)); + } + + inline int16_t ReadInt16BE(const void *ptr) + { + return BBOp::Int16FromBE(ReadInt16(ptr)); + } + + inline int32_t ReadInt32BE(const void *ptr) + { + return BBOp::Int32FromBE(ReadInt32(ptr)); + } + + inline int64_t ReadInt64BE(const void *ptr) + { + return BBOp::Int64FromBE(ReadInt64(ptr)); + } + + inline void WriteInt16BE(void *ptr, int16_t value) + { + WriteInt16(ptr, BBOp::Int16FromBE(value)); + } + + inline void WriteInt32BE(void *ptr, int32_t value) + { + WriteInt32(ptr, BBOp::Int32FromBE(value)); + } + + inline void WriteInt64BE(void *ptr, int64_t value) + { + WriteInt64(ptr, BBOp::Int64FromBE(value)); + } + + //------------------------------------------------------------------------- + // Memory data manipulation + //------------------------------------------------------------------------- + // Copies block of 2d data from source into destination. + inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_offset, + const uint8_t *src, const size_t src_pitch, const size_t src_offset, + const size_t height) + { + for (size_t y = 0; y < height; ++y, src += src_pitch, dst += dst_pitch) + memcpy(dst + dst_offset, src + src_offset, Math::Min(dst_pitch - dst_offset, src_pitch - src_offset)); + } + +} // namespace Memory + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__MEMORY_H diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp new file mode 100644 index 000000000000..8848b7e02550 --- /dev/null +++ b/engines/ags/shared/util/misc.cpp @@ -0,0 +1,200 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +/* + Copyright (c) 2003, Shawn R. Walker + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Shawn R. Walker nor names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "core/platform.h" + +#include +#include +#include +#if !AGS_PLATFORM_OS_WINDOWS +#include +#endif + +#include "allegro.h" +#include "util/file.h" +#include "util/stream.h" + + +using namespace AGS::Common; + +#if !defined (AGS_CASE_SENSITIVE_FILESYSTEM) +#include +/* File Name Concatenator basically on Windows / DOS */ +char *ci_find_file(const char *dir_name, const char *file_name) +{ + char *diamond = NULL; + + if (dir_name == NULL && file_name == NULL) + return NULL; + + if (dir_name == NULL) { + diamond = (char *)malloc(strlen(file_name) + 3); + strcpy(diamond, file_name); + } else { + diamond = (char *)malloc(strlen(dir_name) + strlen(file_name) + 2); + append_filename(diamond, dir_name, file_name, strlen(dir_name) + strlen(file_name) + 2); + } + fix_filename_case(diamond); + fix_filename_slashes(diamond); + return diamond; +} + +#else +/* Case Insensitive File Find */ +char *ci_find_file(const char *dir_name, const char *file_name) +{ + struct stat statbuf; + struct dirent *entry = nullptr; + DIR *rough = nullptr; + DIR *prevdir = nullptr; + char *diamond = nullptr; + char *directory = nullptr; + char *filename = nullptr; + + if (dir_name == nullptr && file_name == nullptr) + return nullptr; + + if (dir_name != nullptr) { + directory = (char *)malloc(strlen(dir_name) + 1); + strcpy(directory, dir_name); + + fix_filename_case(directory); + fix_filename_slashes(directory); + } + + if (file_name != nullptr) { + filename = (char *)malloc(strlen(file_name) + 1); + strcpy(filename, file_name); + + fix_filename_case(filename); + fix_filename_slashes(filename); + } + + if (directory == nullptr) { + char *match = nullptr; + int match_len = 0; + int dir_len = 0; + + match = get_filename(filename); + if (match == nullptr) + return nullptr; + + match_len = strlen(match); + dir_len = (match - filename); + + if (dir_len == 0) { + directory = (char *)malloc(2); + strcpy(directory,"."); + } else { + directory = (char *)malloc(dir_len + 1); + strncpy(directory, file_name, dir_len); + directory[dir_len] = '\0'; + } + + filename = (char *)malloc(match_len + 1); + strncpy(filename, match, match_len); + filename[match_len] = '\0'; + } + + if ((prevdir = opendir(".")) == nullptr) { + fprintf(stderr, "ci_find_file: cannot open current working directory\n"); + return nullptr; + } + + if (chdir(directory) == -1) { + fprintf(stderr, "ci_find_file: cannot change to directory: %s\n", directory); + return nullptr; + } + + if ((rough = opendir(directory)) == nullptr) { + fprintf(stderr, "ci_find_file: cannot open directory: %s\n", directory); + return nullptr; + } + + while ((entry = readdir(rough)) != nullptr) { + lstat(entry->d_name, &statbuf); + if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { + if (strcasecmp(filename, entry->d_name) == 0) { +#if AGS_PLATFORM_DEBUG + fprintf(stderr, "ci_find_file: Looked for %s in rough %s, found diamond %s.\n", filename, directory, entry->d_name); +#endif // AGS_PLATFORM_DEBUG + diamond = (char *)malloc(strlen(directory) + strlen(entry->d_name) + 2); + append_filename(diamond, directory, entry->d_name, strlen(directory) + strlen(entry->d_name) + 2); + break; + } + } + } + closedir(rough); + + fchdir(dirfd(prevdir)); + closedir(prevdir); + + free(directory); + free(filename); + + return diamond; +} +#endif + + +/* Case Insensitive fopen */ +Stream *ci_fopen(const char *file_name, FileOpenMode open_mode, FileWorkMode work_mode) +{ +#if !defined (AGS_CASE_SENSITIVE_FILESYSTEM) + return File::OpenFile(file_name, open_mode, work_mode); +#else + Stream *fs = nullptr; + char *fullpath = ci_find_file(nullptr, (char*)file_name); + + /* If I didn't find a file, this could be writing a new file, + so use whatever file_name they passed */ + if (fullpath == nullptr) { + fs = File::OpenFile(file_name, open_mode, work_mode); + } else { + fs = File::OpenFile(fullpath, open_mode, work_mode); + free(fullpath); + } + + return fs; +#endif +} diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h new file mode 100644 index 000000000000..8e5e5916c105 --- /dev/null +++ b/engines/ags/shared/util/misc.h @@ -0,0 +1,65 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +/* + Copyright (c) 2003, Shawn R. Walker + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Shawn R. Walker nor names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __MISC_H +#define __MISC_H + +#include "util/file.h" // TODO: extract filestream mode constants + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +// Case-insensitive file lookup functions. On case-insensitive systems +// (like MS Windows) they simply return given file, but on case-sensitive +// systems (like Linux) they search the directory for files with matching +// names in different character case. +// They are used as a system-independent way to open a file when its name +// case can be ignored. +Common::Stream *ci_fopen(const char *file_name, + Common::FileOpenMode open_mode = Common::kFile_Open, + Common::FileWorkMode work_mode = Common::kFile_Read); +// TODO: return String object +char *ci_find_file(const char *dir_name, const char *file_name); + + +#endif // __MISC_H diff --git a/engines/ags/shared/util/multifilelib.h b/engines/ags/shared/util/multifilelib.h new file mode 100644 index 000000000000..a0e1192c04f8 --- /dev/null +++ b/engines/ags/shared/util/multifilelib.h @@ -0,0 +1,73 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// A packed data file header and functions for reading it from the stream. +// +//----------------------------------------------------------------------------- +// +// The code is based on CLIB32, by Chris Jones (1998-99), DJGPP implementation +// of the CLIB reader. +// +//============================================================================= + +#ifndef __AGS_CN_UTIL__MULTIFILELIB_H +#define __AGS_CN_UTIL__MULTIFILELIB_H + +#include "core/asset.h" +#include "util/stream.h" + +namespace AGS +{ +namespace Common +{ + +// +// MultiFileLib utilities: (de)serialization of asset library in MFL format +// +namespace MFLUtil +{ + enum MFLError + { + kMFLNoError = 0, + kMFLErrNoLibSig = -1, // library signature does not match + kMFLErrLibVersion = -2, // library version unsupported + kMFLErrNoLibBase = -3, // file is not library base (head) + kMFLErrLibAssetCount = -4, // too many assets in library + }; + + enum MFLVersion + { + kMFLVersion_SingleLib = 6, + kMFLVersion_MultiV10 = 10, + kMFLVersion_MultiV11 = 11, + kMFLVersion_MultiV15 = 15, // unknown differences + kMFLVersion_MultiV20 = 20, + kMFLVersion_MultiV21 = 21, + kMFLVersion_MultiV30 = 30 // 64-bit file support, loose limits + }; + + // Maximal number of the data files in one library chain (1-byte index) + const size_t MaxMultiLibFiles = 256; + + MFLError TestIsMFL(Stream *in, bool test_is_main = false); + MFLError ReadHeader(AssetLibInfo &lib, Stream *in); + + void WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_index, Stream *out); + void WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out); +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__MULTIFILELIB_H diff --git a/engines/ags/shared/util/mutifilelib.cpp b/engines/ags/shared/util/mutifilelib.cpp new file mode 100644 index 000000000000..d0154662ddea --- /dev/null +++ b/engines/ags/shared/util/mutifilelib.cpp @@ -0,0 +1,466 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/bbop.h" +#include "util/multifilelib.h" +#include "util/stream.h" +#include "util/string_utils.h" + +namespace AGS +{ +namespace Common +{ + +namespace MFLUtil +{ + const String HeadSig = "CLIB\x1a"; + const String TailSig = "CLIB\x1\x2\x3\x4SIGE"; + + static const size_t SingleFilePswLen = 13; + + static const size_t MaxAssetFileLen = 100; + static const size_t MaxDataFileLen = 50; + static const size_t V10LibFileLen = 20; + static const size_t V10AssetFileLen = 25; + + static const int EncryptionRandSeed = 9338638; + static const String EncryptionString = "My\x1\xde\x4Jibzle"; + + MFLError ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_version, soff_t *p_abs_offset); + MFLError ReadSingleFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); + MFLError ReadMultiFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); + MFLError ReadV10(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); + MFLError ReadV20(AssetLibInfo &lib, Stream *in); + MFLError ReadV21(AssetLibInfo &lib, Stream *in); + MFLError ReadV30(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); + + void WriteV30(const AssetLibInfo &lib, MFLVersion lib_version, Stream *out); + + // Encryption / decryption + int GetNextPseudoRand(int &rand_val); + void DecryptText(char *text); + void ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &rand_val); + int8_t ReadEncInt8(Stream *in, int &rand_val); + int32_t ReadEncInt32(Stream *in, int &rand_val); + void ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_val); +}; + + +MFLUtil::MFLError MFLUtil::TestIsMFL(Stream *in, bool test_is_main) +{ + MFLVersion lib_version; + MFLError err = ReadSigsAndVersion(in, &lib_version, nullptr); + if (err == kMFLNoError) + { + if (lib_version >= kMFLVersion_MultiV10 && test_is_main) + { + // this version supports multiple data files, check if it is the first one + if (in->ReadByte() != 0) + return kMFLErrNoLibBase; // not first datafile in chain + } + } + return err; +} + +MFLUtil::MFLError MFLUtil::ReadHeader(AssetLibInfo &lib, Stream *in) +{ + MFLVersion lib_version; + soff_t abs_offset; + MFLError err = ReadSigsAndVersion(in, &lib_version, &abs_offset); + if (err != kMFLNoError) + return err; + + if (lib_version >= kMFLVersion_MultiV10) + { + // read newer clib versions (versions 10+) + err = ReadMultiFileLib(lib, in, lib_version); + } + else + { + // read older clib versions (versions 1 to 9) + err = ReadSingleFileLib(lib, in, lib_version); + } + + // apply absolute offset for the assets contained in base data file + // (since only base data file may be EXE file, other clib parts are always on their own) + if (abs_offset > 0) + { + for (AssetVec::iterator it = lib.AssetInfos.begin(); + it != lib.AssetInfos.end(); ++it) + { + if (it->LibUid == 0) + it->Offset += abs_offset; + } + } + return err; +} + +MFLUtil::MFLError MFLUtil::ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_version, soff_t *p_abs_offset) +{ + soff_t abs_offset = 0; // library offset in this file + String sig; + // check multifile lib signature at the beginning of file + sig.ReadCount(in, HeadSig.GetLength()); + if (HeadSig.Compare(sig) != 0) + { + // signature not found, check signature at the end of file + in->Seek(-(soff_t)TailSig.GetLength(), kSeekEnd); + // by definition, tail marks the max absolute offset value + auto tail_abs_offset = in->GetPosition(); + sig.ReadCount(in, TailSig.GetLength()); + // signature not found, return error code + if (TailSig.Compare(sig) != 0) + return kMFLErrNoLibSig; + + // it's an appended-to-end-of-exe thing; + // now we need to read multifile lib offset value, but we do not know + // if its 32-bit or 64-bit yet, so we'll have to test both + in->Seek(-(soff_t)TailSig.GetLength() - sizeof(int64_t), kSeekEnd); + abs_offset = in->ReadInt64(); + in->Seek(-(soff_t)sizeof(int32_t), kSeekCurrent); + soff_t abs_offset_32 = in->ReadInt32(); + + // test for header signature again, with 64-bit and 32-bit offsets if necessary + if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) + { + in->Seek(abs_offset, kSeekBegin); + sig.ReadCount(in, HeadSig.GetLength()); + } + + // try again with 32-bit offset + if (HeadSig.Compare(sig) != 0) + { + abs_offset = abs_offset_32; + if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) + { + in->Seek(abs_offset, kSeekBegin); + sig.ReadCount(in, HeadSig.GetLength()); + } + if (HeadSig.Compare(sig) != 0) + { + // nope, no luck, bad / unknown format + return kMFLErrNoLibSig; + } + } + } + // if we've reached this point we must be right behind the header signature + + // read library header + MFLVersion lib_version = (MFLVersion)in->ReadByte(); + if ((lib_version != kMFLVersion_SingleLib) && (lib_version != kMFLVersion_MultiV10) && + (lib_version != kMFLVersion_MultiV11) && (lib_version != kMFLVersion_MultiV15) && + (lib_version != kMFLVersion_MultiV20) && (lib_version != kMFLVersion_MultiV21) && + lib_version != kMFLVersion_MultiV30) + return kMFLErrLibVersion; // unsupported version + + if (p_lib_version) + *p_lib_version = lib_version; + if (p_abs_offset) + *p_abs_offset = abs_offset; + return kMFLNoError; +} + +MFLUtil::MFLError MFLUtil::ReadSingleFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) +{ + int passwmodifier = in->ReadByte(); + in->ReadInt8(); // unused byte + lib.LibFileNames.resize(1); // only one library part + size_t asset_count = in->ReadInt16(); + lib.AssetInfos.resize(asset_count); + + in->Seek(SingleFilePswLen, kSeekCurrent); // skip password dooberry + char fn_buf[SingleFilePswLen + 1]; + // read information on contents + for (size_t i = 0; i < asset_count; ++i) + { + in->Read(fn_buf, SingleFilePswLen); + fn_buf[SingleFilePswLen] = 0; + for (char *c = fn_buf; *c; ++c) + *c -= passwmodifier; + lib.AssetInfos[i].FileName = fn_buf; + lib.AssetInfos[i].LibUid = 0; + } + for (size_t i = 0; i < asset_count; ++i) + { + lib.AssetInfos[i].Size = in->ReadInt32(); + } + in->Seek(2 * asset_count, kSeekCurrent); // skip flags & ratio + lib.AssetInfos[0].Offset = in->GetPosition(); + // set offsets (assets are positioned in sequence) + for (size_t i = 1; i < asset_count; ++i) + { + lib.AssetInfos[i].Offset = lib.AssetInfos[i - 1].Offset + lib.AssetInfos[i - 1].Size; + } + // return success + return kMFLNoError; +} + +MFLUtil::MFLError MFLUtil::ReadMultiFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) +{ + if (in->ReadByte() != 0) + return kMFLErrNoLibBase; // not first datafile in chain + + if (lib_version >= kMFLVersion_MultiV30) + { + // read new clib format with 64-bit files support + return ReadV30(lib, in, lib_version); + } + if (lib_version >= kMFLVersion_MultiV21) + { + // read new clib format with encoding support (versions 21+) + return ReadV21(lib, in); + } + else if (lib_version == kMFLVersion_MultiV20) + { + // read new clib format without encoding support (version 20) + return ReadV20(lib, in); + } + // read older clib format (versions 10 to 19), the ones with shorter filenames + return ReadV10(lib, in, lib_version); +} + +MFLUtil::MFLError MFLUtil::ReadV10(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) +{ + // number of clib parts + size_t mf_count = in->ReadInt32(); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts; filenames are only 20 chars long in this format version + for (size_t i = 0; i < mf_count; ++i) + { + lib.LibFileNames[i].ReadCount(in, V10LibFileLen); + } + + // number of files in clib + size_t asset_count = in->ReadInt32(); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + // filename array is only 25 chars long in this format version + char fn_buf[V10AssetFileLen]; + for (size_t i = 0; i < asset_count; ++i) + { + in->Read(fn_buf, V10AssetFileLen); + if (lib_version >= kMFLVersion_MultiV11) + DecryptText(fn_buf); + lib.AssetInfos[i].FileName = fn_buf; + } + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Offset = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Size = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].LibUid = in->ReadInt8(); + return kMFLNoError; +} + +MFLUtil::MFLError MFLUtil::ReadV20(AssetLibInfo &lib, Stream *in) +{ + // number of clib parts + size_t mf_count = in->ReadInt32(); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts + for (size_t i = 0; i < mf_count; ++i) + { + lib.LibFileNames[i].Read(in, MaxDataFileLen); + } + + // number of files in clib + size_t asset_count = in->ReadInt32(); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + char fn_buf[MaxAssetFileLen]; + for (size_t i = 0; i < asset_count; ++i) + { + short len = in->ReadInt16(); + len /= 5; // CHECKME: why 5? + in->Read(fn_buf, len); + // decrypt filenames + DecryptText(fn_buf); + lib.AssetInfos[i].FileName = fn_buf; + } + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Offset = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Size = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].LibUid = in->ReadInt8(); + return kMFLNoError; +} + +MFLUtil::MFLError MFLUtil::ReadV21(AssetLibInfo &lib, Stream *in) +{ + // init randomizer + int rand_val = in->ReadInt32() + EncryptionRandSeed; + // number of clib parts + size_t mf_count = ReadEncInt32(in, rand_val); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts + char fn_buf[MaxDataFileLen > MaxAssetFileLen ? MaxDataFileLen : MaxAssetFileLen]; + for (size_t i = 0; i < mf_count; ++i) + { + ReadEncString(fn_buf, MaxDataFileLen, in, rand_val); + lib.LibFileNames[i] = fn_buf; + } + + // number of files in clib + size_t asset_count = ReadEncInt32(in, rand_val); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + for (size_t i = 0; i < asset_count; ++i) + { + ReadEncString(fn_buf, MaxAssetFileLen, in, rand_val); + lib.AssetInfos[i].FileName = fn_buf; + } + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Offset = ReadEncInt32(in, rand_val); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Size = ReadEncInt32(in, rand_val); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].LibUid = ReadEncInt8(in, rand_val); + return kMFLNoError; +} + +MFLUtil::MFLError MFLUtil::ReadV30(AssetLibInfo &lib, Stream *in, MFLVersion /* lib_version */) +{ + // NOTE: removed encryption like in v21, because it makes little sense + // with open-source program. But if really wanted it may be restored + // as one of the options here. + /* int flags = */ in->ReadInt32(); // reserved options + // number of clib parts + size_t mf_count = in->ReadInt32(); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts + for (size_t i = 0; i < mf_count; ++i) + lib.LibFileNames[i] = String::FromStream(in); + + // number of files in clib + size_t asset_count = in->ReadInt32(); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + for (AssetVec::iterator it = lib.AssetInfos.begin(); it != lib.AssetInfos.end(); ++it) + { + it->FileName = String::FromStream(in); + it->LibUid = in->ReadInt8(); + it->Offset = in->ReadInt64(); + it->Size = in->ReadInt64(); + } + return kMFLNoError; +} + +void MFLUtil::WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_index, Stream *out) +{ + out->Write(MFLUtil::HeadSig, MFLUtil::HeadSig.GetLength()); + out->WriteByte(lib_version); + out->WriteByte(lib_index); // file number + + // First datafile in chain: write the table of contents + if (lib_index == 0) + { + WriteV30(lib, lib_version, out); + } +} + +void MFLUtil::WriteV30(const AssetLibInfo &lib, MFLVersion lib_version, Stream *out) +{ + out->WriteInt32(0); // reserved options + // filenames for all library parts + out->WriteInt32(lib.LibFileNames.size()); + for (size_t i = 0; i < lib.LibFileNames.size(); ++i) + { + StrUtil::WriteCStr(lib.LibFileNames[i], out); + } + + // table of contents for all assets in library + out->WriteInt32(lib.AssetInfos.size()); + for (AssetVec::const_iterator it = lib.AssetInfos.begin(); it != lib.AssetInfos.end(); ++it) + { + StrUtil::WriteCStr(it->FileName, out); + out->WriteInt8(it->LibUid); + out->WriteInt64(it->Offset); + out->WriteInt64(it->Size); + } +} + +void MFLUtil::WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out) +{ + if (lib_index < kMFLVersion_MultiV30) + out->WriteInt32((int32_t)lib_offset); + else + out->WriteInt64(lib_offset); + out->Write(TailSig, TailSig.GetLength()); +} + +void MFLUtil::DecryptText(char *text) +{ + size_t adx = 0; + while (true) + { + text[0] -= EncryptionString[adx]; + if (text[0] == 0) + break; + + adx++; + text++; + + if (adx > 10) // CHECKME: why 10? + adx = 0; + } +} + +int MFLUtil::GetNextPseudoRand(int &rand_val) +{ + return( ((rand_val = rand_val * 214013L + + 2531011L) >> 16) & 0x7fff ); +} + +void MFLUtil::ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &rand_val) +{ + in->ReadArray(data, size, count); + uint8_t *ch = (uint8_t*)data; + const size_t len = size * count; + for (size_t i = 0; i < len; ++i) + { + ch[i] -= GetNextPseudoRand(rand_val); + } +} + +int8_t MFLUtil::ReadEncInt8(Stream *in, int &rand_val) +{ + return in->ReadByte() - GetNextPseudoRand(rand_val); +} + +int32_t MFLUtil::ReadEncInt32(Stream *in, int &rand_val) +{ + int val; + ReadEncArray(&val, sizeof(int32_t), 1, in, rand_val); +#if AGS_PLATFORM_ENDIAN_BIG + AGS::Common::BitByteOperations::SwapBytesInt32(val); +#endif + return val; +} + +void MFLUtil::ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_val) +{ + size_t i = 0; + while ((i == 0) || (buffer[i - 1] != 0)) + { + buffer[i] = in->ReadByte() - GetNextPseudoRand(rand_val); + if (i < max_len - 1) + i++; + else + break; // avoid an endless loop + } +} + +} // namespace AGS +} // namespace Common diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp new file mode 100644 index 000000000000..88e305f05f65 --- /dev/null +++ b/engines/ags/shared/util/path.cpp @@ -0,0 +1,250 @@ + +#include "core/platform.h" +#if AGS_PLATFORM_OS_WINDOWS +#include +#endif +#include "allegro/file.h" +#include "util/path.h" +#include "util/stdio_compat.h" + +// TODO: implement proper portable path length +#ifndef MAX_PATH +#define MAX_PATH 512 +#endif + +namespace AGS +{ +namespace Common +{ + +namespace Path +{ + +bool IsDirectory(const String &filename) +{ + // stat() does not like trailing slashes, remove them + String fixed_path = MakePathNoSlash(filename); + return ags_directory_exists(fixed_path.GetCStr()) != 0; +} + +bool IsFile(const String &filename) +{ + return ags_file_exists(filename.GetCStr()) != 0; +} + +bool IsFileOrDir(const String &filename) +{ + // stat() does not like trailing slashes, remove them + String fixed_path = MakePathNoSlash(filename); + return ags_path_exists(fixed_path.GetCStr()) != 0; +} + +int ComparePaths(const String &path1, const String &path2) +{ + // Make minimal absolute paths + String fixed_path1 = MakeAbsolutePath(path1); + String fixed_path2 = MakeAbsolutePath(path2); + + fixed_path1.TrimRight('/'); + fixed_path2.TrimRight('/'); + + int cmp_result = +#if defined AGS_CASE_SENSITIVE_FILESYSTEM + fixed_path1.Compare(fixed_path2); +#else + fixed_path1.CompareNoCase(fixed_path2); +#endif // AGS_CASE_SENSITIVE_FILESYSTEM + return cmp_result; +} + +String GetDirectoryPath(const String &path) +{ + if (IsDirectory(path)) + return path; + + String dir = path; + FixupPath(dir); + size_t slash_at = dir.FindCharReverse('/'); + if (slash_at != -1) + { + dir.ClipMid(slash_at + 1); + return dir; + } + return "./"; +} + +bool IsSameOrSubDir(const String &parent, const String &path) +{ + char can_parent[MAX_PATH]; + char can_path[MAX_PATH]; + char relative[MAX_PATH]; + // canonicalize_filename treats "." as "./." (file in working dir) + const char *use_parent = parent == "." ? "./" : parent; + const char *use_path = path == "." ? "./" : path; + canonicalize_filename(can_parent, use_parent, MAX_PATH); + canonicalize_filename(can_path, use_path, MAX_PATH); + const char *pstr = make_relative_filename(relative, can_parent, can_path, MAX_PATH); + if (!pstr) + return false; + for (pstr = strstr(pstr, ".."); pstr && *pstr; pstr = strstr(pstr, "..")) + { + pstr += 2; + if (*pstr == '/' || *pstr == '\\' || *pstr == 0) + return false; + } + return true; +} + +void FixupPath(String &path) +{ +#if AGS_PLATFORM_OS_WINDOWS + path.Replace('\\', '/'); // bring Windows path separators to uniform style +#endif +} + +String MakePathNoSlash(const String &path) +{ + String dir_path = path; + FixupPath(dir_path); +#if AGS_PLATFORM_OS_WINDOWS + // if the path is 'x:/' don't strip the slash + if (path.GetLength() == 3 && path[1u] == ':') + ; + else +#endif + // if the path is '/' don't strip the slash + if (dir_path.GetLength() > 1) + dir_path.TrimRight('/'); + return dir_path; +} + +String MakeTrailingSlash(const String &path) +{ + String dir_path = path; + FixupPath(dir_path); + if (dir_path.GetLast() != '/') + dir_path.AppendChar('/'); + return dir_path; +} + +String MakeAbsolutePath(const String &path) +{ + if (path.IsEmpty()) + { + return ""; + } + // canonicalize_filename treats "." as "./." (file in working dir) + String abs_path = path == "." ? "./" : path; +#if AGS_PLATFORM_OS_WINDOWS + // NOTE: cannot use long path names in the engine, because it does not have unicode strings support + // + //char long_path_buffer[MAX_PATH]; + //if (GetLongPathNameA(path, long_path_buffer, MAX_PATH) > 0) + //{ + // abs_path = long_path_buffer; + //} +#endif + char buf[MAX_PATH]; + canonicalize_filename(buf, abs_path, MAX_PATH); + abs_path = buf; + FixupPath(abs_path); + return abs_path; +} + +String MakeRelativePath(const String &base, const String &path) +{ + char can_parent[MAX_PATH]; + char can_path[MAX_PATH]; + char relative[MAX_PATH]; + // canonicalize_filename treats "." as "./." (file in working dir) + const char *use_parent = base == "." ? "./" : base; + const char *use_path = path == "." ? "./" : path; + canonicalize_filename(can_parent, use_parent, MAX_PATH); + canonicalize_filename(can_path, use_path, MAX_PATH); + String rel_path = make_relative_filename(relative, can_parent, can_path, MAX_PATH); + FixupPath(rel_path); + return rel_path; +} + +String ConcatPaths(const String &parent, const String &child) +{ + String path = parent; + FixupPath(path); + if (path.GetLast() != '/') + path.AppendChar('/'); + path.Append(child); + return path; +} + +String FixupSharedFilename(const String &filename) +{ + const char *illegal_chars = "\\/:?\"<>|*"; + String fixed_name = filename; + for (size_t i = 0; i < filename.GetLength(); ++i) + { + if (filename[i] < ' ') + { + fixed_name.SetAt(i, '_'); + } + else + { + for (const char *ch_ptr = illegal_chars; *ch_ptr; ++ch_ptr) + if (filename[i] == *ch_ptr) + fixed_name.SetAt(i, '_'); + } + } + return fixed_name; +} + +String GetPathInASCII(const String &path) +{ +#if AGS_PLATFORM_OS_WINDOWS + char ascii_buffer[MAX_PATH]; + if (GetShortPathNameA(path, ascii_buffer, MAX_PATH) == 0) + return ""; + return ascii_buffer; +#else + // TODO: implement conversion for other platforms! + return path; +#endif +} + +#if AGS_PLATFORM_OS_WINDOWS +String WidePathNameToAnsi(LPCWSTR pathw) +{ + WCHAR short_path[MAX_PATH]; + char ascii_buffer[MAX_PATH]; + LPCWSTR arg_path = pathw; + if (GetShortPathNameW(arg_path, short_path, MAX_PATH) == 0) + return ""; + WideCharToMultiByte(CP_ACP, 0, short_path, -1, ascii_buffer, MAX_PATH, NULL, NULL); + return ascii_buffer; +} +#endif + +String GetCmdLinePathInASCII(const char *arg, int arg_index) +{ +#if AGS_PLATFORM_OS_WINDOWS + // Hack for Windows in case there are unicode chars in the path. + // The normal argv[] array has ????? instead of the unicode chars + // and fails, so instead we manually get the short file name, which + // is always using ASCII chars. + int wargc = 0; + LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); + if (wargv == nullptr) + return ""; + String path; + if (arg_index <= wargc) + path = WidePathNameToAnsi(wargv[arg_index]); + LocalFree(wargv); + return path; +#else + // TODO: implement conversion for other platforms! + return arg; +#endif +} + +} // namespace Path + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h new file mode 100644 index 000000000000..edcb82d1da93 --- /dev/null +++ b/engines/ags/shared/util/path.h @@ -0,0 +1,82 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Platform-independent Path functions +// +//============================================================================= +#ifndef __AGS_CN_UTIL__PATH_H +#define __AGS_CN_UTIL__PATH_H + +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +namespace Path +{ + // Tells if the given path is a directory + bool IsDirectory(const String &directory); + // Tells if the given path is a file + bool IsFile(const String &filename); + // Tells if the given path is file or directory; + // may be used to check if it's valid to use + bool IsFileOrDir(const String &filename); + + // Makes a platform-dependant path comparison. + // This takes into consideration platform's filename case (in)sensivity and + // DOS-compatible 8.3 filenames; + // The result value corresponds to stdlib strcmp function. + int ComparePaths(const String &path1, const String &path2); + + // Returns path to the actual directory, referenced by given path; + // if path is a directory, returns path unchanged, if path is a file, returns + // parent directory containing that file. + String GetDirectoryPath(const String &path); + // Tells if the path points to the parent path's location or lower directory; + // return FALSE if the path points to outside of the parent location. + bool IsSameOrSubDir(const String &parent, const String &path); + + // Makes a path have only '/' slashes; this is to make it easier to work + // with path, knowing it contains only one type of directory separators + void FixupPath(String &path); + // Fixups path and removes trailing slash + String MakePathNoSlash(const String &path); + // Fixups path and adds trailing slash if it's missing + String MakeTrailingSlash(const String &path); + // Converts any path to an absolute path; relative paths are assumed to + // refer to the current working directory. + String MakeAbsolutePath(const String &path); + // Tries to create a relative path that would point to 'path' location + // if walking out of the 'base'. Returns empty string on failure. + String MakeRelativePath(const String &base, const String &path); + // Concatenates parent and relative paths + String ConcatPaths(const String &parent, const String &child); + + // Subsitutes illegal characters with '_'. This function uses a combined set + // of illegal chars from all the supported platforms to make a name that + // could be copied across systems without problems. + String FixupSharedFilename(const String &filename); + + // Converts filepath into ASCII variant; returns empty string on failure + String GetPathInASCII(const String &path); + // Converts filepath from command line's argument into ASCII variant + String GetCmdLinePathInASCII(const char *arg, int arg_index); +} // namespace Path + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__PATH_H diff --git a/engines/ags/shared/util/proxystream.cpp b/engines/ags/shared/util/proxystream.cpp new file mode 100644 index 000000000000..164ca737ebb0 --- /dev/null +++ b/engines/ags/shared/util/proxystream.cpp @@ -0,0 +1,182 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/proxystream.h" + +namespace AGS +{ +namespace Common +{ + +ProxyStream::ProxyStream(Stream *stream, ObjectOwnershipPolicy stream_ownership_policy) + : _stream(stream) + , _streamOwnershipPolicy(stream_ownership_policy) +{ +} + +ProxyStream::~ProxyStream() +{ + ProxyStream::Close(); +} + +void ProxyStream::Close() +{ + if (_stream && _streamOwnershipPolicy == kDisposeAfterUse) + { + delete _stream; + } + _stream = nullptr; +} + +bool ProxyStream::Flush() +{ + if (_stream) + { + return _stream->Flush(); + } + return false; +} + +bool ProxyStream::IsValid() const +{ + return _stream && _stream->IsValid(); +} + +bool ProxyStream::EOS() const +{ + return _stream ? _stream->EOS() : true; +} + +soff_t ProxyStream::GetLength() const +{ + return _stream ? _stream->GetLength() : 0; +} + +soff_t ProxyStream::GetPosition() const +{ + return _stream ? _stream->GetPosition() : -1; +} + +bool ProxyStream::CanRead() const +{ + return _stream ? _stream->CanRead() : false; +} + +bool ProxyStream::CanWrite() const +{ + return _stream ? _stream->CanWrite() : false; +} + +bool ProxyStream::CanSeek() const +{ + return _stream ? _stream->CanSeek() : false; +} + +size_t ProxyStream::Read(void *buffer, size_t size) +{ + return _stream ? _stream->Read(buffer, size) : 0; +} + +int32_t ProxyStream::ReadByte() +{ + return _stream ? _stream->ReadByte() : 0; +} + +int16_t ProxyStream::ReadInt16() +{ + return _stream ? _stream->ReadInt16() : 0; +} + +int32_t ProxyStream::ReadInt32() +{ + return _stream ? _stream->ReadInt32() : 0; +} + +int64_t ProxyStream::ReadInt64() +{ + return _stream ? _stream->ReadInt64() : 0; +} + +size_t ProxyStream::ReadArray(void *buffer, size_t elem_size, size_t count) +{ + return _stream ? _stream->ReadArray(buffer, elem_size, count) : 0; +} + +size_t ProxyStream::ReadArrayOfInt16(int16_t *buffer, size_t count) +{ + return _stream ? _stream->ReadArrayOfInt16(buffer, count) : 0; +} + +size_t ProxyStream::ReadArrayOfInt32(int32_t *buffer, size_t count) +{ + return _stream ? _stream->ReadArrayOfInt32(buffer, count) : 0; +} + +size_t ProxyStream::ReadArrayOfInt64(int64_t *buffer, size_t count) +{ + return _stream ? _stream->ReadArrayOfInt64(buffer, count) : 0; +} + +size_t ProxyStream::Write(const void *buffer, size_t size) +{ + return _stream ? _stream->Write(buffer, size) : 0; +} + +int32_t ProxyStream::WriteByte(uint8_t b) +{ + return _stream ? _stream->WriteByte(b) : 0; +} + +size_t ProxyStream::WriteInt16(int16_t val) +{ + return _stream ? _stream->WriteInt16(val) : 0; +} + +size_t ProxyStream::WriteInt32(int32_t val) +{ + return _stream ? _stream->WriteInt32(val) : 0; +} + +size_t ProxyStream::WriteInt64(int64_t val) +{ + return _stream ? _stream->WriteInt64(val) : 0; +} + +size_t ProxyStream::WriteArray(const void *buffer, size_t elem_size, size_t count) +{ + return _stream ? _stream->WriteArray(buffer, elem_size, count) : 0; +} + +size_t ProxyStream::WriteArrayOfInt16(const int16_t *buffer, size_t count) +{ + return _stream ? _stream->WriteArrayOfInt16(buffer, count) : 0; +} + +size_t ProxyStream::WriteArrayOfInt32(const int32_t *buffer, size_t count) +{ + return _stream ? _stream->WriteArrayOfInt32(buffer, count) : 0; +} + +size_t ProxyStream::WriteArrayOfInt64(const int64_t *buffer, size_t count) +{ + return _stream ? _stream->WriteArrayOfInt64(buffer, count) : 0; +} + +bool ProxyStream::Seek(soff_t offset, StreamSeek origin) +{ + return _stream ? _stream->Seek(offset, origin) : false; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/proxystream.h b/engines/ags/shared/util/proxystream.h new file mode 100644 index 000000000000..fa09ed627d51 --- /dev/null +++ b/engines/ags/shared/util/proxystream.h @@ -0,0 +1,87 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_UTIL__PROXYSTREAM_H +#define __AGS_CN_UTIL__PROXYSTREAM_H + +#include "util/stream.h" + +namespace AGS +{ +namespace Common +{ + +// TODO: replace with std::shared_ptr!!! +enum ObjectOwnershipPolicy +{ + kReleaseAfterUse, + kDisposeAfterUse +}; + +class ProxyStream : public Stream +{ +public: + ProxyStream(Stream *stream, ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse); + ~ProxyStream() override; + + void Close() override; + bool Flush() override; + + // Is stream valid (underlying data initialized properly) + bool IsValid() const override; + // Is end of stream + bool EOS() const override; + // Total length of stream (if known) + soff_t GetLength() const override; + // Current position (if known) + soff_t GetPosition() const override; + + bool CanRead() const override; + bool CanWrite() const override; + bool CanSeek() const override; + + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + int16_t ReadInt16() override; + int32_t ReadInt32() override; + int64_t ReadInt64() override; + size_t ReadArray(void *buffer, size_t elem_size, size_t count) override; + size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override; + size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override; + size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override; + + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; + size_t WriteInt16(int16_t val) override; + size_t WriteInt32(int32_t val) override; + size_t WriteInt64(int64_t val) override; + size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override; + size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override; + size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override; + size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override; + + bool Seek(soff_t offset, StreamSeek origin) override; + +protected: + Stream *_stream; + ObjectOwnershipPolicy _streamOwnershipPolicy; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__PROXYSTREAM_H diff --git a/engines/ags/shared/util/stdio_compat.c b/engines/ags/shared/util/stdio_compat.c new file mode 100644 index 000000000000..d3c7e25e3b70 --- /dev/null +++ b/engines/ags/shared/util/stdio_compat.c @@ -0,0 +1,95 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/stdio_compat.h" + +#include "core/platform.h" +#include +#include +#include + +#if AGS_PLATFORM_OS_WINDOWS +#include +#include +#endif + +int ags_fseek(FILE * stream, file_off_t offset, int whence) +{ +#if defined(HAVE_FSEEKO) // Contemporary POSIX libc + return fseeko(stream, offset, whence); +#elif AGS_PLATFORM_OS_WINDOWS // MSVC + return _fseeki64(stream, offset, whence); +#else // No distinct interface with off_t + return fseek(stream, offset, whence); +#endif +} + +file_off_t ags_ftell(FILE * stream) +{ + #if defined(HAVE_FSEEKO) // Contemporary POSIX libc + return ftello(stream); + #elif AGS_PLATFORM_OS_WINDOWS // MSVC + return _ftelli64(stream); + #else // No distinct interface with off_t + return ftell(stream); + #endif +} + +int ags_file_exists(const char *path) +{ +#if AGS_PLATFORM_OS_WINDOWS + return PathFileExistsA(path) && ! PathIsDirectoryA(path); +#else + struct stat path_stat; + if (stat(path, &path_stat) != 0) { + return 0; + } + return S_ISREG(path_stat.st_mode); +#endif +} + +int ags_directory_exists(const char *path) +{ +#if AGS_PLATFORM_OS_WINDOWS + return PathFileExistsA(path) && PathIsDirectoryA(path); +#else + struct stat path_stat; + if (stat(path, &path_stat) != 0) { + return 0; + } + return S_ISDIR(path_stat.st_mode); +#endif +} + +int ags_path_exists(const char *path) +{ + #if AGS_PLATFORM_OS_WINDOWS + return PathFileExistsA(path); + #else + struct stat path_stat; + if (stat(path, &path_stat) != 0) { + return 0; + } + return S_ISREG(path_stat.st_mode) || S_ISDIR(path_stat.st_mode); + #endif +} + +file_off_t ags_file_size(const char *path) +{ + struct stat path_stat; + if (stat(path, &path_stat) != 0) { + return -1; + } + return path_stat.st_size; +} diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h new file mode 100644 index 000000000000..4ba211088b40 --- /dev/null +++ b/engines/ags/shared/util/stdio_compat.h @@ -0,0 +1,39 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#ifndef __AGS_CN_UTIL__STDIOCOMPAT_H +#define __AGS_CN_UTIL__STDIOCOMPAT_H + +#include +#include + +typedef int64_t file_off_t; + +#ifdef __cplusplus +extern "C" { +#endif + +int ags_fseek(FILE * stream, file_off_t offset, int whence); +file_off_t ags_ftell(FILE * stream); + +int ags_file_exists(const char *path); +int ags_directory_exists(const char *path); +int ags_path_exists(const char *path); +file_off_t ags_file_size(const char *path); + +#ifdef __cplusplus +} +#endif + +#endif // __AGS_CN_UTIL__STDIOCOMPAT_H diff --git a/engines/ags/shared/util/stream.cpp b/engines/ags/shared/util/stream.cpp new file mode 100644 index 000000000000..c991cdfff69f --- /dev/null +++ b/engines/ags/shared/util/stream.cpp @@ -0,0 +1,36 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/stream.h" + +namespace AGS +{ +namespace Common +{ + +size_t Stream::WriteByteCount(uint8_t b, size_t count) +{ + if (!CanWrite()) + return 0; + size_t size = 0; + for (; count > 0; --count, ++size) + { + if (WriteByte(b) < 0) + break; + } + return size; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h new file mode 100644 index 000000000000..26ad90321881 --- /dev/null +++ b/engines/ags/shared/util/stream.h @@ -0,0 +1,84 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Base stream class. +// +// Provides default implementation for a few helper methods. +// +// Only streams with uncommon behavior should be derived directly from Stream. +// Most I/O devices should inherit DataStream instead. +// Streams that wrap other streams should inherit ProxyStream. +// +//============================================================================= +#ifndef __AGS_CN_UTIL__STREAM_H +#define __AGS_CN_UTIL__STREAM_H + +#include "api/stream_api.h" + +namespace AGS +{ +namespace Common +{ + +class Stream : public IAGSStream +{ +public: + // Tells if the stream has errors + virtual bool HasErrors() const { return false; } + // Flush stream buffer to the underlying device + virtual bool Flush() = 0; + + //----------------------------------------------------- + // Helper methods + //----------------------------------------------------- + inline int8_t ReadInt8() override + { + return ReadByte(); + } + + inline size_t WriteInt8(int8_t val) override + { + int32_t ival = WriteByte(val); + return ival >= 0 ? ival : 0; + } + + inline bool ReadBool() override + { + return ReadInt8() != 0; + } + + inline size_t WriteBool(bool val) override + { + return WriteInt8(val ? 1 : 0); + } + + // Practically identical to Read() and Write(), these two helpers' only + // meaning is to underline the purpose of data being (de)serialized + inline size_t ReadArrayOfInt8(int8_t *buffer, size_t count) override + { + return Read(buffer, count); + } + inline size_t WriteArrayOfInt8(const int8_t *buffer, size_t count) override + { + return Write(buffer, count); + } + + // Fill the requested number of bytes with particular value + size_t WriteByteCount(uint8_t b, size_t count); +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__STREAM_H diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp new file mode 100644 index 000000000000..8f37fb2c5bfd --- /dev/null +++ b/engines/ags/shared/util/string.cpp @@ -0,0 +1,1021 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include +#include +#include +#include "util/math.h" +#include "util/stream.h" +#include "util/string.h" +#include "util/string_compat.h" + +namespace AGS +{ +namespace Common +{ + +String::String() + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) +{ +} + +String::String(const String &str) + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) +{ + *this = str; +} + +String::String(const char *cstr) + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) +{ + *this = cstr; +} + +String::String(const char *cstr, size_t length) + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) +{ + SetString(cstr, length); +} + +String::String(char c, size_t count) + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) +{ + FillString(c, count); +} + +String::~String() +{ + Free(); +} + +void String::Read(Stream *in, size_t max_chars, bool stop_at_limit) +{ + Empty(); + if (!in) + { + return; + } + if (max_chars == 0 && stop_at_limit) + { + return; + } + + char buffer[1024]; + char *read_ptr = buffer; + size_t read_size = 0; + int ichar; + do + { + ichar = in->ReadByte(); + read_size++; + if (read_size > max_chars) + { + continue; + } + *read_ptr = (char)(ichar >= 0 ? ichar : 0); + if (!*read_ptr || ((read_ptr - buffer) == (sizeof(buffer) - 1 - 1))) + { + buffer[sizeof(buffer) - 1] = 0; + Append(buffer); + read_ptr = buffer; + } + else + { + read_ptr++; + } + } + while(ichar > 0 && !(stop_at_limit && read_size == max_chars)); +} + +void String::ReadCount(Stream *in, size_t count) +{ + Empty(); + if (in && count > 0) + { + ReserveAndShift(false, count); + count = in->Read(_cstr, count); + _cstr[count] = 0; + _len = strlen(_cstr); + } +} + +void String::Write(Stream *out) const +{ + if (out) + { + out->Write(GetCStr(), GetLength() + 1); + } +} + +void String::WriteCount(Stream *out, size_t count) const +{ + if (out) + { + size_t str_out_len = Math::Min(count - 1, GetLength()); + if (str_out_len > 0) + out->Write(GetCStr(), str_out_len); + size_t null_out_len = count - str_out_len; + if (null_out_len > 0) + out->WriteByteCount(0, null_out_len); + } +} + +/* static */ void String::WriteString(const char *cstr, Stream *out) +{ + if (out) + { + cstr = cstr ? cstr : ""; + out->Write(cstr, strlen(cstr) + 1); + } +} + +int String::Compare(const char *cstr) const +{ + return strcmp(GetCStr(), cstr ? cstr : ""); +} + +int String::CompareNoCase(const char *cstr) const +{ + return ags_stricmp(GetCStr(), cstr ? cstr : ""); +} + +int String::CompareLeft(const char *cstr, size_t count) const +{ + cstr = cstr ? cstr : ""; + return strncmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); +} + +int String::CompareLeftNoCase(const char *cstr, size_t count) const +{ + cstr = cstr ? cstr : ""; + return ags_strnicmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); +} + +int String::CompareMid(const char *cstr, size_t from, size_t count) const +{ + cstr = cstr ? cstr : ""; + from = Math::Min(from, GetLength()); + return strncmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); +} + +int String::CompareMidNoCase(const char *cstr, size_t from, size_t count) const +{ + cstr = cstr ? cstr : ""; + from = Math::Min(from, GetLength()); + return ags_strnicmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); +} + +int String::CompareRight(const char *cstr, size_t count) const +{ + cstr = cstr ? cstr : ""; + count = count != -1 ? count : strlen(cstr); + size_t off = Math::Min(GetLength(), count); + return strncmp(GetCStr() + GetLength() - off, cstr, count); +} + +int String::CompareRightNoCase(const char *cstr, size_t count) const +{ + cstr = cstr ? cstr : ""; + count = count != -1 ? count : strlen(cstr); + size_t off = Math::Min(GetLength(), count); + return ags_strnicmp(GetCStr() + GetLength() - off, cstr, count); +} + +size_t String::FindChar(char c, size_t from) const +{ + if (c && from < _len) + { + const char * found_cstr = strchr(_cstr + from, c); + return found_cstr ? found_cstr - _cstr : -1; + } + return -1; +} + +size_t String::FindCharReverse(char c, size_t from) const +{ + if (!_cstr || !c) + { + return -1; + } + + from = Math::Min(from, _len - 1); + const char *seek_ptr = _cstr + from; + while (seek_ptr >= _cstr) + { + if (*seek_ptr == c) + { + return seek_ptr - _cstr; + } + seek_ptr--; + } + return -1; +} + +size_t String::FindString(const char *cstr, size_t from) const +{ + if (cstr && from < _len) + { + const char * found_cstr = strstr(_cstr + from, cstr); + return found_cstr ? found_cstr - _cstr : -1; + } + return -1; +} + +bool String::FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, + size_t &from, size_t &to) const +{ + if (!_cstr || !separator) + { + return false; + } + if (first > last) + { + return false; + } + + size_t this_field = 0; + size_t slice_from = 0; + size_t slice_to = _len; + size_t slice_at = -1; + do + { + slice_at = FindChar(separator, slice_at + 1); + if (slice_at == -1) + slice_at = _len; + // found where previous field ends + if (this_field == last) + { + // if previous field is the last one to be included, + // then set the section tail + slice_to = exclude_last_sep ? slice_at : slice_at + 1; + } + if (slice_at != _len) + { + this_field++; + if (this_field == first) + { + // if the new field is the first one to be included, + // then set the section head + slice_from = exclude_first_sep ? slice_at + 1 : slice_at; + } + } + } + while (slice_at < _len && this_field <= last); + + // the search is a success if at least the first field was found + if (this_field >= first) + { + // correct the indices to stay in the [0; length] range + assert(slice_from <= slice_to); + from = Math::Clamp(slice_from, (size_t)0, _len); + to = Math::Clamp(slice_to, (size_t)0, _len); + return true; + } + return false; +} + +int String::ToInt() const +{ + return atoi(GetCStr()); +} + +String String::Wrapper(const char *cstr) +{ + String str; + str.Wrap(cstr); + return str; +} + +/* static */ String String::FromFormat(const char *fcstr, ...) +{ + fcstr = fcstr ? fcstr : ""; + String str; + va_list argptr; + va_start(argptr, fcstr); + str.FormatV(fcstr, argptr); + va_end(argptr); + return str; +} + +/* static */ String String::FromFormatV(const char *fcstr, va_list argptr) +{ + String str; + str.FormatV(fcstr, argptr); + return str; +} + +/* static */ String String::FromStream(Stream *in, size_t max_chars, bool stop_at_limit) +{ + String str; + str.Read(in, max_chars, stop_at_limit); + return str; +} + +/* static */ String String::FromStreamCount(Stream *in, size_t count) +{ + String str; + str.ReadCount(in, count); + return str; +} + +String String::Lower() const +{ + String str = *this; + str.MakeLower(); + return str; +} + +String String::Upper() const +{ + String str = *this; + str.MakeUpper(); + return str; +} + +String String::Left(size_t count) const +{ + count = Math::Min(count, GetLength()); + return count == GetLength() ? *this : String(GetCStr(), count); +} + +String String::Mid(size_t from, size_t count) const +{ + Math::ClampLength(from, count, (size_t)0, GetLength()); + return count == GetLength() ? *this : String(GetCStr() + from, count); +} + +String String::Right(size_t count) const +{ + count = Math::Min(count, GetLength()); + return count == GetLength() ? *this : String(GetCStr() + GetLength() - count, count); +} + +String String::LeftSection(char separator, bool exclude_separator) const +{ + if (_cstr && separator) + { + size_t slice_at = FindChar(separator); + if (slice_at != -1) + { + slice_at = exclude_separator ? slice_at : slice_at + 1; + return Left(slice_at); + } + } + return *this; +} + +String String::RightSection(char separator, bool exclude_separator) const +{ + if (_cstr && separator) + { + size_t slice_at = FindCharReverse(separator); + if (slice_at != -1) + { + size_t count = exclude_separator ? _len - slice_at - 1 : _len - slice_at; + return Right(count); + } + } + return *this; +} + +String String::Section(char separator, size_t first, size_t last, + bool exclude_first_sep, bool exclude_last_sep) const +{ + if (!_cstr || !separator) + { + return String(); + } + + size_t slice_from; + size_t slice_to; + if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, + slice_from, slice_to)) + { + return Mid(slice_from, slice_to - slice_from); + } + return String(); +} + +std::vector String::Split(char separator) const +{ + std::vector result; + if (!_cstr || !separator) + return result; + const char *ptr = _cstr; + while (*ptr) + { + const char *found_cstr = strchr(ptr, separator); + if (!found_cstr) break; + result.push_back(String(ptr, found_cstr - ptr)); + ptr = found_cstr + 1; + } + result.push_back(String(ptr)); + return result; +} + +void String::Reserve(size_t max_length) +{ + if (_bufHead) + { + if (max_length > _bufHead->Capacity) + { + // grow by 50% + size_t grow_length = _bufHead->Capacity + (_bufHead->Capacity / 2); + Copy(Math::Max(max_length, grow_length)); + } + } + else + { + Create(max_length); + } +} + +void String::ReserveMore(size_t more_length) +{ + Reserve(GetLength() + more_length); +} + +void String::Compact() +{ + if (_bufHead && _bufHead->Capacity > _len) + { + Copy(_len); + } +} + +void String::Append(const char *cstr) +{ + if (cstr) + { + size_t length = strlen(cstr); + if (length > 0) + { + ReserveAndShift(false, length); + memcpy(_cstr + _len, cstr, length); + _len += length; + _cstr[_len] = 0; + } + } +} + +void String::AppendChar(char c) +{ + if (c) + { + ReserveAndShift(false, 1); + _cstr[_len++] = c; + _cstr[_len] = 0; + } +} + +void String::ClipLeft(size_t count) +{ + if (_len > 0 && count > 0) + { + count = Math::Min(count, _len); + BecomeUnique(); + _len -= count; + _cstr += count; + } +} + +void String::ClipMid(size_t from, size_t count) +{ + if (from < _len) + { + count = Math::Min(count, _len - from); + if (count > 0) + { + BecomeUnique(); + if (!from) + { + _len -= count; + _cstr += count; + } + else if (from + count == _len) + { + _len -= count; + _cstr[_len] = 0; + } + else + { + char *cstr_mid = _cstr + from; + memmove(cstr_mid, _cstr + from + count, _len - from - count + 1); + _len -= count; + } + } + } +} + +void String::ClipRight(size_t count) +{ + if (count > 0) + { + count = Math::Min(count, GetLength()); + BecomeUnique(); + _len -= count; + _cstr[_len] = 0; + } +} + +void String::ClipLeftSection(char separator, bool include_separator) +{ + if (_cstr && separator) + { + size_t slice_at = FindChar(separator); + if (slice_at != -1) + { + ClipLeft(include_separator ? slice_at + 1 : slice_at); + } + else + Empty(); + } +} + +void String::ClipRightSection(char separator, bool include_separator) +{ + if (_cstr && separator) + { + size_t slice_at = FindCharReverse(separator); + if (slice_at != -1) + { + ClipRight(include_separator ? _len - slice_at : _len - slice_at - 1); + } + else + Empty(); + } +} + +void String::ClipSection(char separator, size_t first, size_t last, + bool include_first_sep, bool include_last_sep) +{ + if (!_cstr || !separator) + { + return; + } + + size_t slice_from; + size_t slice_to; + if (FindSection(separator, first, last, !include_first_sep, !include_last_sep, + slice_from, slice_to)) + { + ClipMid(slice_from, slice_to - slice_from); + } +} + +void String::Empty() +{ + if (_cstr) + { + BecomeUnique(); + _len = 0; + _cstr[0] = 0; + } +} + +void String::FillString(char c, size_t count) +{ + Empty(); + if (count > 0) + { + ReserveAndShift(false, count); + memset(_cstr, c, count); + _len = count; + _cstr[count] = 0; + } +} + +void String::Format(const char *fcstr, ...) +{ + va_list argptr; + va_start(argptr, fcstr); + FormatV(fcstr, argptr); + va_end(argptr); +} + +void String::FormatV(const char *fcstr, va_list argptr) +{ + fcstr = fcstr ? fcstr : ""; + va_list argptr_cpy; + va_copy(argptr_cpy, argptr); + size_t length = vsnprintf(nullptr, 0u, fcstr, argptr); + ReserveAndShift(false, Math::Surplus(length, GetLength())); + vsprintf(_cstr, fcstr, argptr_cpy); + va_end(argptr_cpy); + _len = length; + _cstr[_len] = 0; +} + +void String::Free() +{ + if (_bufHead) + { + assert(_bufHead->RefCount > 0); + _bufHead->RefCount--; + if (!_bufHead->RefCount) + { + delete [] _buf; + } + } + _buf = nullptr; + _cstr = nullptr; + _len = 0; +} + +void String::MakeLower() +{ + if (_cstr) + { + BecomeUnique(); + ags_strlwr(_cstr); + } +} + +void String::MakeUpper() +{ + if (_cstr) + { + BecomeUnique(); + ags_strupr(_cstr); + } +} + +void String::Prepend(const char *cstr) +{ + if (cstr) + { + size_t length = strlen(cstr); + if (length > 0) + { + ReserveAndShift(true, length); + memcpy(_cstr - length, cstr, length); + _len += length; + _cstr -= length; + } + } +} + +void String::PrependChar(char c) +{ + if (c) + { + ReserveAndShift(true, 1); + _len++; + _cstr--; + _cstr[0] = c; + } +} + +void String::Replace(char what, char with) +{ + if (_cstr && what && with && what != with) + { + BecomeUnique(); + char *rep_ptr = _cstr; + while (*rep_ptr) + { + if (*rep_ptr == what) + { + *rep_ptr = with; + } + rep_ptr++; + } + } +} + +void String::ReplaceMid(size_t from, size_t count, const char *cstr) +{ + if (!cstr) + cstr = ""; + size_t length = strlen(cstr); + Math::ClampLength(from, count, (size_t)0, GetLength()); + ReserveAndShift(false, Math::Surplus(length, count)); + memmove(_cstr + from + length, _cstr + from + count, GetLength() - (from + count) + 1); + memcpy(_cstr + from, cstr, length); + _len += length - count; +} + +void String::Reverse() +{ + if (!_cstr || GetLength() <= 1) + return; + for (char *fw = _cstr, *bw = _cstr + _len - 1; + *fw; ++fw, --bw) + { + std::swap(*fw, *bw); + } +} + +void String::SetAt(size_t index, char c) +{ + if (_cstr && index < GetLength() && c) + { + BecomeUnique(); + _cstr[index] = c; + } +} + +void String::SetString(const char *cstr, size_t length) +{ + if (cstr) + { + length = Math::Min(length, strlen(cstr)); + if (length > 0) + { + ReserveAndShift(false, Math::Surplus(length, GetLength())); + memcpy(_cstr, cstr, length); + _len = length; + _cstr[length] = 0; + } + else + { + Empty(); + } + } + else + { + Empty(); + } +} + +void String::Trim(char c) +{ + TrimLeft(c); + TrimRight(c); +} + +void String::TrimLeft(char c) +{ + if (!_cstr || !_len) + { + return; + } + + const char *trim_ptr = _cstr; + for (;;) + { + auto t = *trim_ptr; + if (t == 0) { break; } + if (c && t != c) { break; } + if (!c && !isspace(t)) { break; } + trim_ptr++; + } + size_t trimmed = trim_ptr - _cstr; + if (trimmed > 0) + { + BecomeUnique(); + _len -= trimmed; + _cstr += trimmed; + } +} + +void String::TrimRight(char c) +{ + if (!_cstr || !_len) + { + return; + } + + const char *trim_ptr = _cstr + _len - 1; + for (;;) + { + if (trim_ptr < _cstr) { break; } + auto t = *trim_ptr; + if (c && t != c) { break; } + if (!c && !isspace(t)) { break; } + trim_ptr--; + } + size_t trimmed = (_cstr + _len - 1) - trim_ptr; + if (trimmed > 0) + { + BecomeUnique(); + _len -= trimmed; + _cstr[_len] = 0; + } +} + +void String::TruncateToLeft(size_t count) +{ + if (_cstr) + { + count = Math::Min(count, _len); + if (count < _len) + { + BecomeUnique(); + _len = count; + _cstr[_len] = 0; + } + } +} + +void String::TruncateToMid(size_t from, size_t count) +{ + if (_cstr) + { + Math::ClampLength(from, count, (size_t)0, _len); + if (from > 0 || count < _len) + { + BecomeUnique(); + _len = count; + _cstr += from; + _cstr[_len] = 0; + } + } +} + +void String::TruncateToRight(size_t count) +{ + if (_cstr) + { + count = Math::Min(count, GetLength()); + if (count < _len) + { + BecomeUnique(); + _cstr += _len - count; + _len = count; + } + } +} + +void String::TruncateToLeftSection(char separator, bool exclude_separator) +{ + if (_cstr && separator) + { + size_t slice_at = FindChar(separator); + if (slice_at != -1) + { + TruncateToLeft(exclude_separator ? slice_at : slice_at + 1); + } + } +} + +void String::TruncateToRightSection(char separator, bool exclude_separator) +{ + if (_cstr && separator) + { + size_t slice_at = FindCharReverse(separator); + if (slice_at != -1) + { + TruncateToRight(exclude_separator ? _len - slice_at - 1 : _len - slice_at); + } + } +} + +void String::TruncateToSection(char separator, size_t first, size_t last, + bool exclude_first_sep, bool exclude_last_sep) +{ + if (!_cstr || !separator) + { + return; + } + + size_t slice_from; + size_t slice_to; + if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, + slice_from, slice_to)) + { + TruncateToMid(slice_from, slice_to - slice_from); + } + else + { + Empty(); + } +} + +void String::Wrap(const char *cstr) +{ + Free(); + _buf = nullptr; + // Note that String is NOT supposed to *modify* the const buffer. + // Any non-read operation on the buffer is preceded by a call to BecomeUnique, + // which in turn will allocate a reference-counted buffer copy. + _cstr = const_cast(cstr); + _len = strlen(cstr); +} + +String &String::operator=(const String& str) +{ + if (_cstr != str._cstr) + { + Free(); + _buf = str._buf; + _cstr = str._cstr; + _len = str._len; + if (_bufHead) + { + _bufHead->RefCount++; + } + } + return *this; +} + +String &String::operator=(const char *cstr) +{ + SetString(cstr); + return *this; +} + +void String::Create(size_t max_length) +{ + _buf = new char[sizeof(String::BufHeader) + max_length + 1]; + _bufHead->RefCount = 1; + _bufHead->Capacity = max_length; + _len = 0; + _cstr = _buf + sizeof(String::BufHeader); + _cstr[_len] = 0; +} + +void String::Copy(size_t max_length, size_t offset) +{ + if (!_cstr) + { + return; + } + + char *new_data = new char[sizeof(String::BufHeader) + max_length + 1]; + // remember, that _cstr may point to any address in buffer + char *cstr_head = new_data + sizeof(String::BufHeader) + offset; + size_t copy_length = Math::Min(_len, max_length); + memcpy(cstr_head, _cstr, copy_length); + Free(); + _buf = new_data; + _bufHead->RefCount = 1; + _bufHead->Capacity = max_length; + _len = copy_length; + _cstr = cstr_head; + _cstr[_len] = 0; +} + +void String::Align(size_t offset) +{ + char *cstr_head = _buf + sizeof(String::BufHeader) + offset; + memmove(cstr_head, _cstr, _len + 1); + _cstr = cstr_head; +} + +void String::BecomeUnique() +{ + if (_cstr && (_bufHead && _bufHead->RefCount > 1 || !_bufHead)) + { + Copy(_len); + } +} + +void String::ReserveAndShift(bool left, size_t more_length) +{ + if (_bufHead) + { + size_t total_length = _len + more_length; + if (_bufHead->Capacity < total_length) + { + // grow by 50% or at least to total_size + size_t grow_length = _bufHead->Capacity + (_bufHead->Capacity >> 1); + Copy(Math::Max(total_length, grow_length), left ? more_length : 0u); + } + else if (_bufHead->RefCount > 1) + { + Copy(total_length, left ? more_length : 0u); + } + else + { + // make sure we make use of all of our space + const char *cstr_head = _buf + sizeof(String::BufHeader); + size_t free_space = left ? + _cstr - cstr_head : + (cstr_head + _bufHead->Capacity) - (_cstr + _len); + if (free_space < more_length) + { + Align((left ? + _cstr + (more_length - free_space) : + _cstr - (more_length - free_space)) - cstr_head); + } + } + } + else + { + Create(more_length); + } +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h new file mode 100644 index 000000000000..f96208a1df75 --- /dev/null +++ b/engines/ags/shared/util/string.h @@ -0,0 +1,379 @@ + +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// String class with simple memory management and copy-on-write behavior. +// +// String objects do reference counting and share data buffer on assignment. +// The reallocation and copying is done only when the string is modified. +// +// The copying of memory inside buffer is reduced to minimum. If the string is +// truncated, it is not aligned to buffer head each time, instead the c-str +// pointer is advanced, or null-terminator is put on the new place. Similarly, +// when string is enlarged and new characters are prepended or appended, only +// c-str pointer and null-terminator's position are changed, if there's enough +// space before and after meaningful string data. +// +// The class provides means to reserve large amount of buffer space before +// making modifications, as well as compacting buffer to minimal size. +// +// For all methods that expect C-string as parameter - if the null pointer is +// passed in place of C-string it is treated in all aspects as a valid empty +// string. +// +//============================================================================= +#ifndef __AGS_CN_UTIL__STRING_H +#define __AGS_CN_UTIL__STRING_H + +#include +#include +#include "core/platform.h" +#include "core/types.h" +#include "debug/assert.h" + +namespace AGS +{ +namespace Common +{ + +class Stream; + +class String +{ +public: + // Standard constructor: intialize empty string + String(); + // Copy constructor + String(const String&); + // Initialize with C-string + String(const char *cstr); + // Initialize by copying up to N chars from C-string + String(const char *cstr, size_t length); + // Initialize by filling N chars with certain value + String(char c, size_t count); + ~String(); + + // Get underlying C-string for reading; this method guarantees valid C-string + inline const char *GetCStr() const + { + return _cstr ? _cstr : ""; + } + // Get C-string or nullptr + inline const char *GetNullableCStr() const + { + return _cstr ? _cstr : nullptr; + } + // Get character count + inline size_t GetLength() const + { + return _len; + } + // Know if the string is empty (has no meaningful characters) + inline bool IsEmpty() const + { + return _len == 0; + } + + // Those getters are for tests only, hence if AGS_PLATFORM_DEBUG +#if AGS_PLATFORM_DEBUG + inline const char *GetBuffer() const + { + return _buf; + } + + inline size_t GetCapacity() const + { + return _bufHead ? _bufHead->Capacity : 0; + } + + inline size_t GetRefCount() const + { + return _bufHead ? _bufHead->RefCount : 0; + } +#endif + + // Read() method implies that string length is initially unknown. + // max_chars parameter determine the buffer size limit. + // If stop_at_limit flag is set, it will read only up to the max_chars. + // Otherwise (by default) hitting the limit won't stop stream reading; + // the data will be read until null-terminator or EOS is met, and buffer + // will contain only leftmost part of the longer string that fits in. + // This method is better fit for reading from binary streams. + void Read(Stream *in, size_t max_chars = 5 * 1024 * 1024, bool stop_at_limit = false); + // ReadCount() reads up to N characters from stream, ignoring null- + // terminator. This method is better fit for reading from text + // streams, or when the length of string is known beforehand. + void ReadCount(Stream *in, size_t count); + // Write() puts the null-terminated string into the stream. + void Write(Stream *out) const; + // WriteCount() writes N characters to stream, filling the remaining + // space with null-terminators when needed. + void WriteCount(Stream *out, size_t count) const; + + static void WriteString(const char *cstr, Stream *out); + + //------------------------------------------------------------------------- + // String analysis methods + //------------------------------------------------------------------------- + + // Compares with given C-string + int Compare(const char *cstr) const; + int CompareNoCase(const char *cstr) const; + // Compares the leftmost part of this string with given C-string + int CompareLeft(const char *cstr, size_t count = -1) const; + int CompareLeftNoCase(const char *cstr, size_t count = -1) const; + // Compares any part of this string with given C-string + int CompareMid(const char *cstr, size_t from, size_t count = -1) const; + int CompareMidNoCase(const char *cstr, size_t from, size_t count = -1) const; + // Compares the rightmost part of this string with given C-string + int CompareRight(const char *cstr, size_t count = -1) const; + int CompareRightNoCase(const char *cstr, size_t count = -1) const; + + // These functions search for character or substring inside this string + // and return the index of the (first) character, or -1 if nothing found. + size_t FindChar(char c, size_t from = 0) const; + size_t FindCharReverse(char c, size_t from = -1) const; + size_t FindString(const char *cstr, size_t from = 0) const; + + // Section methods treat string as a sequence of 'fields', separated by + // special character. They search for a substring consisting of all such + // 'fields' from the 'first' to the 'last', inclusive; the bounding + // separators are optionally included too. + // Section indexes are zero-based. The first (0th) section is always + // located before the first separator and the last section is always + // located after the last separator, meaning that if the outermost + // character in string is separator char, there's still an empty trailing + // field beyond that. + // This also means that there's always at least one section in any string, + // even if there are no separating chars. + bool FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, + size_t &from, size_t &to) const; + + // Get Nth character with bounds check (as opposed to subscript operator) + inline char GetAt(size_t index) const + { + return (index < _len) ? _cstr[index] : 0; + } + inline char GetLast() const + { + return (_len > 0) ? _cstr[_len - 1] : 0; + } + + //------------------------------------------------------------------------- + // Value cast methods + //------------------------------------------------------------------------- + + int ToInt() const; + + //------------------------------------------------------------------------- + // Factory methods + //------------------------------------------------------------------------- + + // Wraps the given string buffer without owning it, won't count references, + // won't delete it at destruction. Can be used with string literals. + static String Wrapper(const char *cstr); + + static String FromFormat(const char *fcstr, ...); + static String FromFormatV(const char *fcstr, va_list argptr); + // Reads stream until null-terminator or EOS + static String FromStream(Stream *in, size_t max_chars = 5 * 1024 * 1024, bool stop_at_limit = false); + // Reads up to N chars from stream + static String FromStreamCount(Stream *in, size_t count); + + // Creates a lowercased copy of the string + String Lower() const; + // Creates an uppercased copy of the string + String Upper() const; + + // Extract N leftmost characters as a new string + String Left(size_t count) const; + // Extract up to N characters starting from given index + String Mid(size_t from, size_t count = -1) const; + // Extract N rightmost characters + String Right(size_t count) const; + + // Extract leftmost part, separated by the given char; if no separator was + // found returns the whole string + String LeftSection(char separator, bool exclude_separator = true) const; + // Extract rightmost part, separated by the given char; if no separator was + // found returns the whole string + String RightSection(char separator, bool exclude_separator = true) const; + // Extract the range of Xth to Yth fields, separated by the given character + String Section(char separator, size_t first, size_t last, + bool exclude_first_sep = true, bool exclude_last_sep = true) const; + // Splits the string into segments divided by the instances of a given character, + // including empty segments e.g. if separators follow each other; + // returns at least one segment (equal to full string if no separator was found) + std::vector Split(char separator) const; + + //------------------------------------------------------------------------- + // String modification methods + //------------------------------------------------------------------------- + + // Ensure string has at least space to store N chars; + // this does not change string contents, nor length + void Reserve(size_t max_length); + // Ensure string has at least space to store N additional chars + void ReserveMore(size_t more_length); + // Make string's buffer as small as possible to hold current data + void Compact(); + + // Append* methods add content at the string's end, increasing its length + // Add C-string at string's end + void Append(const char *cstr); + // Add single character at string's end + void AppendChar(char c); + // Clip* methods decrease the string, removing defined part + // Cuts off leftmost N characters + void ClipLeft(size_t count); + // Cuts out N characters starting from given index + void ClipMid(size_t from, size_t count = -1); + // Cuts off rightmost N characters + void ClipRight(size_t count); + // Cuts off leftmost part, separated by the given char; if no separator was + // found cuts whole string, leaving empty string + void ClipLeftSection(char separator, bool include_separator = true); + // Cuts off rightmost part, separated by the given char; if no separator + // was found cuts whole string, leaving empty string + void ClipRightSection(char separator, bool include_separator = true); + // Cuts out the range of Xth to Yth fields separated by the given character + void ClipSection(char separator, size_t first, size_t last, + bool include_first_sep = true, bool include_last_sep = true); + // Sets string length to zero + void Empty(); + // Makes a new string by filling N chars with certain value + void FillString(char c, size_t count); + // Makes a new string by putting in parameters according to format string + void Format(const char *fcstr, ...); + void FormatV(const char *fcstr, va_list argptr); + // Decrement ref counter and deallocate data if must. + // Free() should be called only when buffer is not needed anymore; + // if string must be truncated to zero length, but retain the allocated + // memory, call Empty() instead. + void Free(); + // Convert string to lowercase equivalent + void MakeLower(); + // Convert string to uppercase equivalent + void MakeUpper(); + // Prepend* methods add content before the string's head, increasing its length + // Add C-string before string's head + void Prepend(const char *cstr); + // Add single character before string's head + void PrependChar(char c); + // Replaces all occurences of one character with another character + void Replace(char what, char with); + // Replaces particular substring with another substring; new substring + // may have different length + void ReplaceMid(size_t from, size_t count, const char *cstr); + // Reverses the string + void Reverse(); + // Overwrite the Nth character of the string; does not change string's length + void SetAt(size_t index, char c); + // Makes a new string by copying up to N chars from C-string + void SetString(const char *cstr, size_t length = -1); + // For all Trim functions, if given character value is 0, all whitespace + // characters (space, tabs, CRLF) are removed. + // Remove heading and trailing characters from the string + void Trim(char c = 0); + // Remove heading characters from the string; + void TrimLeft(char c = 0); + // Remove trailing characters from the string + void TrimRight(char c = 0); + // Truncate* methods decrease the string to the part of itself + // Truncate the string to the leftmost N characters + void TruncateToLeft(size_t count); + // Truncate the string to the middle N characters + void TruncateToMid(size_t from, size_t count = -1); + // Truncate the string to the rightmost N characters + void TruncateToRight(size_t count); + // Truncate the string to the leftmost part, separated by the given char; + // if no separator was found leaves string unchanged + void TruncateToLeftSection(char separator, bool exclude_separator = true); + // Truncate the string to the rightmost part, separated by the given char; + // if no separator was found leaves string unchanged + void TruncateToRightSection(char separator, bool exclude_separator = true); + // Truncate the string to range of Xth to Yth fields separated by the + // given character + void TruncateToSection(char separator, size_t first, size_t last, + bool exclude_first_sep = true, bool exclude_last_sep = true); + // Wraps the given string buffer without owning it, won't count references, + // won't delete it at destruction. Can be used with string literals. + void Wrap(const char *cstr); + + //------------------------------------------------------------------------- + // Operators + //------------------------------------------------------------------------- + + inline operator const char *() const + { + return GetCStr(); + } + // Assign String by sharing data reference + String &operator=(const String&); + // Assign C-string by copying contents + String &operator=(const char *cstr); + inline char operator[](size_t index) const + { + assert(index < _len); + return _cstr[index]; + } + inline bool operator==(const char *cstr) const + { + return Compare(cstr) == 0; + } + inline bool operator!=(const char *cstr) const + { + return Compare(cstr) != 0; + } + inline bool operator <(const char *cstr) const + { + return Compare(cstr) < 0; + } + +private: + // Creates new empty string with buffer enough to fit given length + void Create(size_t buffer_length); + // Release string and copy data to the new buffer + void Copy(size_t buffer_length, size_t offset = 0); + // Aligns data at given offset + void Align(size_t offset); + + // Ensure this string is a compact independent copy, with ref counter = 1 + void BecomeUnique(); + // Ensure this string is independent, and there's enough space before + // or after the current string data + void ReserveAndShift(bool left, size_t more_length); + + char *_cstr; // pointer to actual string data + size_t _len; // valid string length, in characters, excluding null-term + + // Header of a reference-counted buffer + struct BufHeader + { + size_t RefCount = 0; // reference count + size_t Capacity = 0; // available space, in characters + }; + + // Union that groups mutually exclusive data (currently only ref counted buffer) + union + { + char *_buf; // reference-counted data (raw ptr) + BufHeader *_bufHead; // the header of a reference-counted data + }; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__STRING_H diff --git a/engines/ags/shared/util/string_compat.c b/engines/ags/shared/util/string_compat.c new file mode 100644 index 000000000000..0f925e3ce934 --- /dev/null +++ b/engines/ags/shared/util/string_compat.c @@ -0,0 +1,58 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include "util/string_compat.h" +#include +#include +#include "core/platform.h" + +char *ags_strlwr(char *s) +{ + char *p = s; + for (; *p; p++) + *p = tolower(*p); + return s; +} + +char *ags_strupr(char *s) +{ + char *p = s; + for (; *p; p++) + *p = toupper(*p); + return s; +} + +int ags_stricmp(const char *s1, const char *s2) +{ +#if AGS_PLATFORM_OS_WINDOWS + return stricmp(s1, s2); +#else + return strcasecmp(s1, s2); +#endif +} + +int ags_strnicmp(const char *s1, const char *s2, size_t n) +{ +#if AGS_PLATFORM_OS_WINDOWS + return strnicmp(s1, s2, n); +#else + return strncasecmp(s1, s2, n); +#endif +} + +char *ags_strdup(const char *s) +{ + char *result = (char *)malloc(strlen(s) + 1); + strcpy(result, s); + return result; +} diff --git a/engines/ags/shared/util/string_compat.h b/engines/ags/shared/util/string_compat.h new file mode 100644 index 000000000000..209fab8bb37d --- /dev/null +++ b/engines/ags/shared/util/string_compat.h @@ -0,0 +1,33 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_CN_UTIL__STRINGCOMPAT_H +#define __AGS_CN_UTIL__STRINGCOMPAT_H + +#include "core/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +char *ags_strlwr(char *s); +char *ags_strupr(char *s); +int ags_stricmp(const char *, const char *); +int ags_strnicmp(const char *, const char *, size_t); +char *ags_strdup(const char *s); + +#ifdef __cplusplus +} +#endif + +#endif // __AGS_CN_UTIL__STRINGCOMPAT_H diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h new file mode 100644 index 000000000000..2795be49e87a --- /dev/null +++ b/engines/ags/shared/util/string_types.h @@ -0,0 +1,114 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#ifndef __AGS_CN_UTIL__STRINGTYPES_H +#define __AGS_CN_UTIL__STRINGTYPES_H + +#include +#include +#include + +#include +#include "util/string.h" + +namespace FNV +{ + +const uint32_t PRIME_NUMBER = 2166136261U; +const uint32_t SECONDARY_NUMBER = 16777619U; + +inline size_t Hash(const char *data, const size_t len) +{ + uint32_t hash = PRIME_NUMBER; + for (size_t i = 0; i < len; ++i) + hash = (SECONDARY_NUMBER * hash) ^ (uint8_t)(data[i]); + return hash; +} + +inline size_t Hash_LowerCase(const char *data, const size_t len) +{ + uint32_t hash = PRIME_NUMBER; + for (size_t i = 0; i < len; ++i) + hash = (SECONDARY_NUMBER * hash) ^ (uint8_t)(tolower(data[i])); + return hash; +} + +} // namespace FNV + + +// A std::hash specialization for AGS String +namespace std +{ +#ifdef AGS_NEEDS_TR1 +namespace tr1 +{ +#endif +// std::hash for String object +template<> +struct hash : public unary_function +{ + size_t operator ()(const AGS::Common::String &key) const + { + return FNV::Hash(key.GetCStr(), key.GetLength()); + } +}; +#ifdef AGS_NEEDS_TR1 +} +#endif +} + + +namespace AGS +{ +namespace Common +{ + +// +// Various comparison functors +// + +// Test case-insensitive String equality +struct StrEqNoCase : public std::binary_function +{ + bool operator()(const String &s1, const String &s2) const + { + return s1.CompareNoCase(s2) == 0; + } +}; + +// Case-insensitive String less +struct StrLessNoCase : public std::binary_function +{ + bool operator()(const String &s1, const String &s2) const + { + return s1.CompareNoCase(s2) < 0; + } +}; + +// Compute case-insensitive hash for a String object +struct HashStrNoCase : public std::unary_function +{ + size_t operator ()(const String &key) const + { + return FNV::Hash_LowerCase(key.GetCStr(), key.GetLength()); + } +}; + +typedef std::vector StringV; +typedef std::unordered_map StringMap; +typedef std::unordered_map StringIMap; + +} // namespace Common +} // namespace AGS + +#endif //__AGS_CN_UTIL__STRINGTYPES_H diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp new file mode 100644 index 000000000000..c022f0c81abb --- /dev/null +++ b/engines/ags/shared/util/string_utils.cpp @@ -0,0 +1,171 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +#include +#include +#include "core/platform.h" +#include "util/math.h" +#include "util/string_utils.h" +#include "util/stream.h" + +using namespace AGS::Common; + +String cbuf_to_string_and_free(char *char_buf) +{ + String s = char_buf; + free(char_buf); + return s; +} + + +namespace AGS +{ +namespace Common +{ + +String StrUtil::IntToString(int d) +{ + return String::FromFormat("%d", d); +} + +int StrUtil::StringToInt(const String &s, int def_val) +{ + if (!s.GetCStr()) + return def_val; + char *stop_ptr; + int val = strtol(s.GetCStr(), &stop_ptr, 0); + return (stop_ptr == s.GetCStr() + s.GetLength()) ? val : def_val; +} + +StrUtil::ConversionError StrUtil::StringToInt(const String &s, int &val, int def_val) +{ + val = def_val; + if (!s.GetCStr()) + return StrUtil::kFailed; + char *stop_ptr; + errno = 0; + long lval = strtol(s.GetCStr(), &stop_ptr, 0); + if (stop_ptr != s.GetCStr() + s.GetLength()) + return StrUtil::kFailed; + if (lval > INT_MAX || lval < INT_MIN || errno == ERANGE) + return StrUtil::kOutOfRange; + val = (int)lval; + return StrUtil::kNoError; +} + +String StrUtil::ReadString(Stream *in) +{ + size_t len = in->ReadInt32(); + if (len > 0) + return String::FromStreamCount(in, len); + return String(); +} + +void StrUtil::ReadString(char *cstr, Stream *in, size_t buf_limit) +{ + size_t len = in->ReadInt32(); + if (buf_limit == 0) + { + in->Seek(len); + return; + } + + len = Math::Min(len, buf_limit - 1); + if (len > 0) + in->Read(cstr, len); + cstr[len] = 0; +} + +void StrUtil::ReadString(String &s, Stream *in) +{ + size_t len = in->ReadInt32(); + s.ReadCount(in, len); +} + +void StrUtil::ReadString(char **cstr, Stream *in) +{ + size_t len = in->ReadInt32(); + *cstr = new char[len + 1]; + if (len > 0) + in->Read(*cstr, len); + (*cstr)[len] = 0; +} + +void StrUtil::SkipString(Stream *in) +{ + size_t len = in->ReadInt32(); + in->Seek(len); +} + +void StrUtil::WriteString(const String &s, Stream *out) +{ + size_t len = s.GetLength(); + out->WriteInt32(len); + if (len > 0) + out->Write(s.GetCStr(), len); +} + +void StrUtil::WriteString(const char *cstr, Stream *out) +{ + size_t len = strlen(cstr); + out->WriteInt32(len); + if (len > 0) + out->Write(cstr, len); +} + +void StrUtil::ReadCStr(char *buf, Stream *in, size_t buf_limit) +{ + if (buf_limit == 0) + { + while (in->ReadByte() > 0); + return; + } + + auto ptr = buf; + auto last = buf + buf_limit - 1; + for (;;) + { + if (ptr >= last) { + *ptr = 0; + while (in->ReadByte() > 0); // must still read until 0 + break; + } + + auto ichar = in->ReadByte(); + if (ichar <= 0) { + *ptr = 0; + break; + } + *ptr = static_cast(ichar); + ptr++; + } +} + +void StrUtil::SkipCStr(Stream *in) +{ + while (in->ReadByte() > 0); +} + +void StrUtil::WriteCStr(const char *cstr, Stream *out) +{ + size_t len = strlen(cstr); + out->Write(cstr, len + 1); +} + +void StrUtil::WriteCStr(const String &s, Stream *out) +{ + out->Write(s.GetCStr(), s.GetLength() + 1); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h new file mode 100644 index 000000000000..b0dbdae9406f --- /dev/null +++ b/engines/ags/shared/util/string_utils.h @@ -0,0 +1,76 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// +// +//============================================================================= +#ifndef __AGS_CN_UTIL__STRINGUTILS_H +#define __AGS_CN_UTIL__STRINGUTILS_H + +#include "util/string.h" + +namespace AGS { namespace Common { class Stream; } } +using namespace AGS; // FIXME later + +//============================================================================= + +// Converts char* to string and frees original malloc-ed array; +// This is used when we get a malloc'd char array from some utility function. +Common::String cbuf_to_string_and_free(char *char_buf); + +namespace AGS +{ +namespace Common +{ +namespace StrUtil +{ + enum ConversionError + { + kNoError, // conversion successful + kFailed, // conversion failed (e.g. wrong format) + kOutOfRange // the resulting value is out of range + }; + + // Convert integer to string, by printing its value + String IntToString(int val); + // Tries to convert whole string into integer value; + // returns def_val on failure + int StringToInt(const String &s, int def_val = 0); + // Tries to convert whole string into integer value; + // Returns error code if any non-digit character was met or if value is out + // of range; the 'val' variable will be set with resulting integer, or + // def_val on failure + ConversionError StringToInt(const String &s, int &val, int def_val); + + // Serialize and unserialize unterminated string prefixed with 32-bit length; + // length is presented as 32-bit integer integer + String ReadString(Stream *in); + void ReadString(char *cstr, Stream *in, size_t buf_limit); + void ReadString(char **cstr, Stream *in); + void ReadString(String &s, Stream *in); + void SkipString(Stream *in); + void WriteString(const String &s, Stream *out); + void WriteString(const char *cstr, Stream *out); + + // Serialize and unserialize string as c-string (null-terminated sequence) + void ReadCStr(char *buf, Stream *in, size_t buf_limit); + void SkipCStr(Stream *in); + void WriteCStr(const char *cstr, Stream *out); + void WriteCStr(const String &s, Stream *out); +} +} // namespace Common +} // namespace AGS + + +#endif // __AGS_CN_UTIL__STRINGUTILS_H diff --git a/engines/ags/shared/util/textreader.h b/engines/ags/shared/util/textreader.h new file mode 100644 index 000000000000..f7273ced30da --- /dev/null +++ b/engines/ags/shared/util/textreader.h @@ -0,0 +1,48 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Specialized interface for reading plain text from the underlying source +// +//============================================================================= +#ifndef __AGS_CN_UTIL__TEXTREADER_H +#define __AGS_CN_UTIL__TEXTREADER_H + +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +class TextReader +{ +public: + virtual ~TextReader() = default; + + virtual bool IsValid() const = 0; + + // Read single character + virtual char ReadChar() = 0; + // Read defined number of characters + virtual String ReadString(size_t length) = 0; + // Read till line break + virtual String ReadLine() = 0; + // Read till end of available data + virtual String ReadAll() = 0; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__TEXTSTREAM_H diff --git a/engines/ags/shared/util/textstreamreader.cpp b/engines/ags/shared/util/textstreamreader.cpp new file mode 100644 index 000000000000..d0f4e5dc2e6e --- /dev/null +++ b/engines/ags/shared/util/textstreamreader.cpp @@ -0,0 +1,154 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "util/math.h" +#include "util/stream.h" +#include "util/textstreamreader.h" + +namespace AGS +{ +namespace Common +{ + +TextStreamReader::TextStreamReader(Stream *stream) + : _stream(stream) +{ +} + +TextStreamReader::~TextStreamReader() +{ + // TODO: use shared ptr + delete _stream; +} + +bool TextStreamReader::IsValid() const +{ + return _stream && _stream->CanRead(); +} + +const Stream *TextStreamReader::GetStream() const +{ + return _stream; +} + +void TextStreamReader::ReleaseStream() +{ + _stream = nullptr; +} + +bool TextStreamReader::EOS() const +{ + return _stream ? _stream->EOS() : true; +} + +char TextStreamReader::ReadChar() +{ + if (_stream) + { + // Skip carriage-returns + char c; + do + { + c = _stream->ReadByte(); + } + while (!_stream->EOS() && c == '\r'); + return c; + } + return '\0'; +} + +String TextStreamReader::ReadString(size_t length) +{ + if (!_stream) + { + return ""; + } + // TODO: remove carriage-return characters + return String::FromStreamCount(_stream, length); +} + +String TextStreamReader::ReadLine() +{ + // TODO + // Probably it is possible to group Stream::ReadString with this, + // both use similar algorythm, difference is only in terminator chars + + if (!_stream) + { + return ""; + } + + String str; + int chars_read_last = 0; + int line_break_position = -1; + // Read a chunk of memory to buffer and seek for null-terminator, + // if not found, repeat until EOS + const int single_chunk_length = 3000; + const int max_chars = 5000000; + char char_buffer[single_chunk_length + 1]; + do + { + chars_read_last = _stream->Read(char_buffer, single_chunk_length); + char *seek_ptr = char_buffer; + int c; + for (c = 0; c < chars_read_last && *seek_ptr != '\n'; ++c, ++seek_ptr); + + int append_length = 0; + int str_len = str.GetLength(); + if (c < chars_read_last && *seek_ptr == '\n') + { + line_break_position = seek_ptr - char_buffer; + if (str_len < max_chars) + { + append_length = Math::Min(line_break_position, max_chars - str_len); + } + } + else + { + append_length = Math::Min(chars_read_last, max_chars - str_len); + } + + if (append_length > 0) + { + char_buffer[append_length] = '\0'; + str.Append(char_buffer); + } + } + while (!EOS() && line_break_position < 0); + + // If null-terminator was found make sure stream is positioned at the next + // byte after line end + if (line_break_position >= 0) + { + // CHECKME: what if stream does not support seek? need an algorythm fork for that + // the seek offset should be negative + _stream->Seek(line_break_position - chars_read_last + 1 /* beyond line feed */); + } + + str.TrimRight('\r'); // skip carriage-return, if any + return str; +} + +String TextStreamReader::ReadAll() +{ + if (_stream) + { + soff_t len = _stream->GetLength() - _stream->GetPosition(); + return ReadString(len > SIZE_MAX ? SIZE_MAX : (size_t)len); + } + return ""; +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/textstreamreader.h b/engines/ags/shared/util/textstreamreader.h new file mode 100644 index 000000000000..4f69dc02b004 --- /dev/null +++ b/engines/ags/shared/util/textstreamreader.h @@ -0,0 +1,60 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Class for reading plain text from the stream +// +//============================================================================= +#ifndef __AGS_CN_UTIL__TEXTSTREAMREADER_H +#define __AGS_CN_UTIL__TEXTSTREAMREADER_H + +#include "util/textreader.h" + +namespace AGS +{ +namespace Common +{ + +class Stream; + +class TextStreamReader : public TextReader +{ +public: + // TODO: use shared ptr + TextStreamReader(Stream *stream); + ~TextStreamReader() override; + + bool IsValid() const override; + const Stream *GetStream() const; + // TODO: use shared ptr instead + void ReleaseStream(); + + bool EOS() const; + + // Read single character + char ReadChar() override; + // Read defined number of characters + String ReadString(size_t length) override; + // Read till line break + String ReadLine() override; + // Read till end of available data + String ReadAll() override; + +private: + Stream *_stream; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__TEXTSTREAM_H diff --git a/engines/ags/shared/util/textstreamwriter.cpp b/engines/ags/shared/util/textstreamwriter.cpp new file mode 100644 index 000000000000..6345c52fb6f3 --- /dev/null +++ b/engines/ags/shared/util/textstreamwriter.cpp @@ -0,0 +1,121 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include // sprintf +#include "core/platform.h" +#include "util/textstreamwriter.h" +#include "util/stream.h" + +namespace AGS +{ +namespace Common +{ + +#if AGS_PLATFORM_OS_WINDOWS +static const char Endl[2] = {'\r', '\n'}; +#else +static const char Endl[1] = {'\n'}; +#endif + + +TextStreamWriter::TextStreamWriter(Stream *stream) + : _stream(stream) +{ +} + +TextStreamWriter::~TextStreamWriter() +{ + // TODO use shared ptr + delete _stream; +} + +bool TextStreamWriter::IsValid() const +{ + return _stream && _stream->CanWrite(); +} + +const Stream *TextStreamWriter::GetStream() const +{ + return _stream; +} + +void TextStreamWriter::ReleaseStream() +{ + _stream = nullptr; +} + +bool TextStreamWriter::EOS() const +{ + return _stream ? _stream->EOS() : true; +} + +void TextStreamWriter::WriteChar(char c) +{ + if (_stream) + { + _stream->WriteByte(c); + } +} + +void TextStreamWriter::WriteString(const String &str) +{ + if (_stream) + { + // TODO: replace line-feed characters in string with platform-specific line break + _stream->Write(str.GetCStr(), str.GetLength()); + } +} + +void TextStreamWriter::WriteLine(const String &str) +{ + if (!_stream) + { + return; + } + + // TODO: replace line-feed characters in string with platform-specific line break + _stream->Write(str.GetCStr(), str.GetLength()); + _stream->Write(Endl, sizeof(Endl)); +} + +void TextStreamWriter::WriteFormat(const char *fmt, ...) +{ + if (!_stream) + { + return; + } + + // TODO: replace line-feed characters in format string with platform-specific line break + + va_list argptr; + va_start(argptr, fmt); + int need_length = vsnprintf(nullptr, 0, fmt, argptr); + va_start(argptr, fmt); // Reset argptr + char *buffer = new char[need_length + 1]; + vsprintf(buffer, fmt, argptr); + va_end(argptr); + + _stream->Write(buffer, need_length); + delete [] buffer; +} + +void TextStreamWriter::WriteLineBreak() +{ + if (_stream) + _stream->Write(Endl, sizeof(Endl)); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/textstreamwriter.h b/engines/ags/shared/util/textstreamwriter.h new file mode 100644 index 000000000000..4024a05df399 --- /dev/null +++ b/engines/ags/shared/util/textstreamwriter.h @@ -0,0 +1,61 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Class for writing plain text to the stream +// +//============================================================================= +#ifndef __AGS_CN_UTIL__TEXTSTREAMWRITER_H +#define __AGS_CN_UTIL__TEXTSTREAMWRITER_H + +#include "util/textwriter.h" + +namespace AGS +{ +namespace Common +{ + +class Stream; + +class TextStreamWriter : public TextWriter +{ +public: + // TODO: use shared ptr + TextStreamWriter(Stream *stream); + ~TextStreamWriter() override; + + bool IsValid() const override; + const Stream *GetStream() const; + // TODO: use shared ptr instead + void ReleaseStream(); + + bool EOS() const; + + // Write single character + void WriteChar(char c) override; + // Write string as a plain text (without null-terminator) + void WriteString(const String &str) override; + // Write string and add line break at the end + void WriteLine(const String &str) override; + // Write formatted string (see *printf) + void WriteFormat(const char *fmt, ...) override; + void WriteLineBreak() override; + +private: + Stream *_stream; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__TEXTSTREAMWRITER_H diff --git a/engines/ags/shared/util/textwriter.h b/engines/ags/shared/util/textwriter.h new file mode 100644 index 000000000000..b254202ee9ea --- /dev/null +++ b/engines/ags/shared/util/textwriter.h @@ -0,0 +1,49 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Specialized interface for writing plain text to the underlying source +// +//============================================================================= +#ifndef __AGS_CN_UTIL__TEXTWRITER_H +#define __AGS_CN_UTIL__TEXTWRITER_H + +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +class TextWriter +{ +public: + virtual ~TextWriter() = default; + + virtual bool IsValid() const = 0; + + // Write single character + virtual void WriteChar(char c) = 0; + // Write string as a plain text (without null-terminator) + virtual void WriteString(const String &str) = 0; + // Write string and add line break at the end + virtual void WriteLine(const String &str) = 0; + // Write formatted string (see *printf) + virtual void WriteFormat(const char *fmt, ...) = 0; + virtual void WriteLineBreak() = 0; +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_UTIL__TEXTWRITER_H diff --git a/engines/ags/shared/util/version.cpp b/engines/ags/shared/util/version.cpp new file mode 100644 index 000000000000..2f8df6110e9f --- /dev/null +++ b/engines/ags/shared/util/version.cpp @@ -0,0 +1,150 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include +#include "util/version.h" + +namespace AGS +{ +namespace Common +{ + +const Version Version::LastOldFormatVersion(3, 2, 2, 1120); + +Version::Version() + : Major(0) + , Minor(0) + , Release(0) + , Revision(0) +{ + MakeString(); +} + +Version::Version(int32_t major, int32_t minor, int32_t release) + : Major(major) + , Minor(minor) + , Release(release) + , Revision(0) +{ + MakeString(); +} + +Version::Version(int32_t major, int32_t minor, int32_t release, int32_t revision) + : Major(major) + , Minor(minor) + , Release(release) + , Revision(revision) +{ + MakeString(); +} + +Version::Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special) + : Major(major) + , Minor(minor) + , Release(release) + , Revision(revision) + , Special(special) +{ + MakeString(); +} + +Version::Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special, const String &build_info) + : Major(major) + , Minor(minor) + , Release(release) + , Revision(revision) + , Special(special) + , BuildInfo(build_info) +{ + MakeString(); +} + +Version::Version(const String &version_string) + : Major(0) + , Minor(0) + , Release(0) + , Revision(0) +{ + SetFromString(version_string); +} + +void Version::SetFromString(const String &version_string) +{ + Major = version_string.LeftSection('.').ToInt(); + String second_section = version_string.Section('.', 1, 1); + Minor = second_section.ToInt(); + String third_section = version_string.Section('.', 2, 2); + String fourth_section = version_string.Section('.', 3, 3); + String revision_section; + + bool old_version_format = Major < 3 || fourth_section.IsEmpty(); + if (old_version_format) + { + if (second_section.GetLength() > 1) + { + Release = Minor % 10; + Minor /= 10; + } + else + { + Release = 0; + } + revision_section = third_section; + } + else + { + Release = third_section.ToInt(); + revision_section = fourth_section; + } + + int revision_length = 0; + if (!revision_section.IsEmpty()) + { + const char *seek_ptr = revision_section.GetCStr(); + const char *end_ptr = revision_section.GetCStr() + revision_section.GetLength(); + while (seek_ptr != end_ptr) + { + if (!isdigit(*seek_ptr)) + { + break; + } + revision_length++; + seek_ptr++; + } + } + + Revision = revision_section.Left(revision_length).ToInt(); + // In old version format a special tag was added right after revision digits. + // In new version format a special tag is separated from revision digits with single space char. + Special = revision_section.Mid(revision_length + (old_version_format ? 0 : 1)); + + MakeString(); +} + +void Version::MakeString() +{ + if (Special.IsEmpty()) + { + LongString.Format("%d.%d.%d.%d", Major, Minor, Release, Revision); + } + else + { + LongString.Format("%d.%d.%d.%d %s", Major, Minor, Release, Revision, Special.GetCStr()); + } + BackwardCompatibleString.Format("%d.%02d.%d%s", Major, Minor * 10 + Release, Revision, Special.GetCStr()); + ShortString.Format("%d.%d", Major, Minor); +} + +} // namespace Common +} // namespace AGS diff --git a/engines/ags/shared/util/version.h b/engines/ags/shared/util/version.h new file mode 100644 index 000000000000..69696ac681fe --- /dev/null +++ b/engines/ags/shared/util/version.h @@ -0,0 +1,107 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// Class, depicting version of the AGS engine +// +//============================================================================= +#ifndef __AGS_CN_MAIN__VERSION_H +#define __AGS_CN_MAIN__VERSION_H + +#include "util/string.h" + +namespace AGS +{ +namespace Common +{ + +using Common::String; + +struct Version +{ + int32_t Major; + int32_t Minor; + int32_t Release; + int32_t Revision; + String Special; + String BuildInfo; + + String LongString; + String ShortString; + String BackwardCompatibleString; + + // Last engine version, using different version format than AGS Editor (3.22.1120 / 3.2.2.1120) + static const Version LastOldFormatVersion; + + Version(); + Version(int32_t major, int32_t minor, int32_t release); + Version(int32_t major, int32_t minor, int32_t release, int32_t revision); + Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special); + Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special, const String &build_info); + Version(const String &version_string); + + inline int32_t AsNumber() const + { + return Major * 10000 + Minor * 100 + Release; + } + + inline int64_t AsLongNumber() const + { + return (int64_t)Major * 100000000L + (int64_t)Minor * 1000000L + (int64_t)Release * 10000L + Revision; + } + + inline int32_t AsSmallNumber() const + { + return Major * 100 + Minor; + } + + void SetFromString(const String &version_string); + + inline bool operator < (const Version &other) const + { + return AsLongNumber() < other.AsLongNumber(); + } + + inline bool operator <= (const Version &other) const + { + return AsLongNumber() <= other.AsLongNumber(); + } + + inline bool operator > (const Version &other) const + { + return AsLongNumber() > other.AsLongNumber(); + } + + inline bool operator >= (const Version &other) const + { + return AsLongNumber() >= other.AsLongNumber(); + } + + inline bool operator == (const Version &other) const + { + return AsLongNumber() == other.AsLongNumber(); + } + + inline bool operator != (const Version &other) const + { + return AsLongNumber() != other.AsLongNumber(); + } + +private: + void MakeString(); +}; + +} // namespace Common +} // namespace AGS + +#endif // __AGS_CN_MAIN__VERSION_H diff --git a/engines/ags/shared/util/wgt2allg.cpp b/engines/ags/shared/util/wgt2allg.cpp new file mode 100644 index 000000000000..31a81523d102 --- /dev/null +++ b/engines/ags/shared/util/wgt2allg.cpp @@ -0,0 +1,216 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= + +#include "core/assetmanager.h" +#include "gfx/bitmap.h" +#include "util/stream.h" +#include "util/wgt2allg.h" + +using namespace AGS::Common; + +#ifdef __cplusplus +extern "C" +{ +#endif + + void wsetrgb(int coll, int r, int g, int b, color * pall) + { + pall[coll].r = r; + pall[coll].g = g; + pall[coll].b = b; + } + + void wcolrotate(unsigned char start, unsigned char finish, int dir, color * pall) + { + int jj; + if (dir == 0) { + // rotate left + color tempp = pall[start]; + + for (jj = start; jj < finish; jj++) + pall[jj] = pall[jj + 1]; + + pall[finish] = tempp; + } + else { + // rotate right + color tempp = pall[finish]; + + for (jj = finish - 1; jj >= start; jj--) + pall[jj + 1] = pall[jj]; + + pall[start] = tempp; + } + } + + Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2) + { + Bitmap *tempbitm; + int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; + + if (twid < 1) + twid = 1; + + if (thit < 1) + thit = 1; + + tempbitm = BitmapHelper::CreateBitmap(twid, thit); + + if (tempbitm == nullptr) + return nullptr; + + tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); + return tempbitm; + } + + int wloadsprites(color * pall, char *filnam, Bitmap ** sarray, int strt, int eend) + { + int vers; + char buff[20]; + int numspri = 0, vv, hh, wdd, htt; + + Stream *in = Common::AssetManager::OpenAsset(filnam); + if (in == nullptr) + return -1; + + vers = in->ReadInt16(); + in->ReadArray(&buff[0], 13, 1); + for (vv = 0; vv < 256; vv++) // there's a filler byte + in->ReadArray(&pall[vv], 3, 1); + + if (vers > 4) + return -1; + + if (vers == 4) + numspri = in->ReadInt16(); + else { + numspri = in->ReadInt16(); + if ((numspri < 2) || (numspri > 200)) + numspri = 200; + } + + for (vv = strt; vv <= eend; vv++) + sarray[vv] = nullptr; + + for (vv = 0; vv <= numspri; vv++) { + int coldep = in->ReadInt16(); + + if (coldep == 0) { + sarray[vv] = nullptr; + if (in->EOS()) + break; + + continue; + } + + if (in->EOS()) + break; + + if (vv > eend) + break; + + wdd = in->ReadInt16(); + htt = in->ReadInt16(); + if (vv < strt) { + in->Seek(wdd * htt); + continue; + } + sarray[vv] = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); + + if (sarray[vv] == nullptr) { + delete in; + return -1; + } + + for (hh = 0; hh < htt; hh++) + in->ReadArray(&sarray[vv]->GetScanLineForWriting(hh)[0], wdd * coldep, 1); + } + delete in; + return 0; + } + + void wputblock(Common::Bitmap *ds, int xx, int yy, Bitmap *bll, int xray) + { + if (xray) + ds->Blit(bll, xx, yy, Common::kBitmap_Transparency); + else + ds->Blit(bll, 0, 0, xx, yy, bll->GetWidth(), bll->GetHeight()); + } + + Bitmap wputblock_wrapper; // [IKM] argh! :[ + void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray) + { + wputblock_wrapper.WrapAllegroBitmap(bll, true); + if (xray) + ds->Blit(&wputblock_wrapper, xx, yy, Common::kBitmap_Transparency); + else + ds->Blit(&wputblock_wrapper, 0, 0, xx, yy, wputblock_wrapper.GetWidth(), wputblock_wrapper.GetHeight()); + } + + const int col_lookups[32] = { + 0x000000, 0x0000A0, 0x00A000, 0x00A0A0, 0xA00000, // 4 + 0xA000A0, 0xA05000, 0xA0A0A0, 0x505050, 0x5050FF, 0x50FF50, 0x50FFFF, // 11 + 0xFF5050, 0xFF50FF, 0xFFFF50, 0xFFFFFF, 0x000000, 0x101010, 0x202020, // 18 + 0x303030, 0x404040, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, // 25 + 0xA0A0A0, 0xB0B0B0, 0xC0C0C0, 0xD0D0D0, 0xE0E0E0, 0xF0F0F0 + }; + + int __wremap_keep_transparent = 1; + + void wremap(color * pal1, Bitmap *picc, color * pal2) + { + int jj; + unsigned char color_mapped_table[256]; + + for (jj = 0; jj < 256; jj++) + { + if ((pal1[jj].r == 0) && (pal1[jj].g == 0) && (pal1[jj].b == 0)) + { + color_mapped_table[jj] = 0; + } + else + { + color_mapped_table[jj] = bestfit_color(pal2, pal1[jj].r, pal1[jj].g, pal1[jj].b); + } + } + + if (__wremap_keep_transparent > 0) { + // keep transparency + color_mapped_table[0] = 0; + // any other pixels which are being mapped to 0, map to 16 instead + for (jj = 1; jj < 256; jj++) { + if (color_mapped_table[jj] == 0) + color_mapped_table[jj] = 16; + } + } + + int pic_size = picc->GetWidth() * picc->GetHeight(); + for (jj = 0; jj < pic_size; jj++) { + int xxl = jj % (picc->GetWidth()), yyl = jj / (picc->GetWidth()); + int rr = picc->GetPixel(xxl, yyl); + picc->PutPixel(xxl, yyl, color_mapped_table[rr]); + } + } + + void wremapall(color * pal1, Bitmap *picc, color * pal2) + { + __wremap_keep_transparent--; + wremap(pal1, picc, pal2); + __wremap_keep_transparent++; + } + + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h new file mode 100644 index 000000000000..8036d4ffb13e --- /dev/null +++ b/engines/ags/shared/util/wgt2allg.h @@ -0,0 +1,79 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// WGT -> Allegro portability interface +// +// wsavesprites and wloadsprites are hi-color compliant +// +//============================================================================= + +#include "core/platform.h" + +#define _WGT45_ + +#ifndef __WGT4_H +#define __WGT4_H + +#include "allegro.h" + +namespace AGS { namespace Common { class Bitmap; }} +using namespace AGS; // FIXME later + + +#if defined WGT2ALLEGRO_NOFUNCTIONS +#error WGT2ALLEGRO_NOFUNCTIONS macro is obsolete and should not be defined anymore. +#endif + +#define color RGB + +//============================================================================= + +// [IKM] 2012-09-13: this function is now defined in engine and editor separately +extern void __my_setcolor(int *ctset, int newcol, int wantColDep); + +#ifdef __cplusplus +extern "C" +{ +#endif + + extern void wsetrgb(int coll, int r, int g, int b, color * pall); + extern void wcolrotate(unsigned char start, unsigned char finish, int dir, color * pall); + + extern Common::Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2); + + extern int wloadsprites(color * pall, char *filnam, Common::Bitmap ** sarray, int strt, int eend); + + extern void wputblock(Common::Bitmap *ds, int xx, int yy, Common::Bitmap *bll, int xray); + // CHECKME: temporary solution for plugin system + extern void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray); + extern const int col_lookups[32]; + + //extern void wsetcolor(int nval); + + extern int __wremap_keep_transparent; + extern void wremap(color * pal1, Common::Bitmap *picc, color * pal2); + extern void wremapall(color * pal1, Common::Bitmap *picc, color * pal2); + +#ifdef __cplusplus +} +#endif + +#define XRAY 1 +#define NORMAL 0 + +// archive attributes to search for - al_findfirst breaks with 0 +#define FA_SEARCH -1 + + +#endif // __WGT4_H From 0185d6f583a4ae05f07f0d1e5b74133cc9c917b6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 08:58:42 -0800 Subject: [PATCH 004/215] AGS: Adding ScummVM comment headers --- engines/ags/engine/ac/asset_helper.h | 35 ++++++++++------ engines/ags/engine/ac/audiochannel.cpp | 34 +++++++++------ engines/ags/engine/ac/audiochannel.h | 39 ++++++++++-------- engines/ags/engine/ac/audioclip.cpp | 34 +++++++++------ engines/ags/engine/ac/audioclip.h | 39 ++++++++++-------- engines/ags/engine/ac/button.cpp | 34 +++++++++------ engines/ags/engine/ac/button.h | 34 +++++++++------ engines/ags/engine/ac/cdaudio.cpp | 34 +++++++++------ engines/ags/engine/ac/cdaudio.h | 39 ++++++++++-------- engines/ags/engine/ac/character.cpp | 34 +++++++++------ engines/ags/engine/ac/character.h | 39 ++++++++++-------- engines/ags/engine/ac/charactercache.h | 39 ++++++++++-------- engines/ags/engine/ac/characterextras.cpp | 34 +++++++++------ engines/ags/engine/ac/characterextras.h | 39 ++++++++++-------- .../ags/engine/ac/characterinfo_engine.cpp | 34 +++++++++------ engines/ags/engine/ac/datetime.cpp | 34 +++++++++------ engines/ags/engine/ac/datetime.h | 39 ++++++++++-------- engines/ags/engine/ac/dialog.cpp | 34 +++++++++------ engines/ags/engine/ac/dialog.h | 39 ++++++++++-------- .../ags/engine/ac/dialogoptionsrendering.cpp | 34 +++++++++------ .../ags/engine/ac/dialogoptionsrendering.h | 39 ++++++++++-------- engines/ags/engine/ac/display.cpp | 34 +++++++++------ engines/ags/engine/ac/display.h | 39 ++++++++++-------- engines/ags/engine/ac/draw.cpp | 34 +++++++++------ engines/ags/engine/ac/draw.h | 39 ++++++++++-------- engines/ags/engine/ac/draw_software.cpp | 34 +++++++++------ engines/ags/engine/ac/draw_software.h | 35 ++++++++++------ engines/ags/engine/ac/drawingsurface.cpp | 34 +++++++++------ engines/ags/engine/ac/drawingsurface.h | 39 ++++++++++-------- engines/ags/engine/ac/dynamicsprite.cpp | 34 +++++++++------ engines/ags/engine/ac/dynamicsprite.h | 39 ++++++++++-------- .../ags/engine/ac/dynobj/all_dynamicclasses.h | 39 ++++++++++-------- .../ags/engine/ac/dynobj/all_scriptclasses.h | 39 ++++++++++-------- .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 34 +++++++++------ .../engine/ac/dynobj/cc_agsdynamicobject.h | 36 +++++++++------- .../ags/engine/ac/dynobj/cc_audiochannel.cpp | 34 +++++++++------ .../ags/engine/ac/dynobj/cc_audiochannel.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/cc_audioclip.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_audioclip.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/cc_character.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_character.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_dialog.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_dialog.h | 34 +++++++++------ .../ags/engine/ac/dynobj/cc_dynamicarray.cpp | 34 +++++++++------ .../ags/engine/ac/dynobj/cc_dynamicarray.h | 37 ++++++++++------- .../ags/engine/ac/dynobj/cc_dynamicobject.cpp | 34 +++++++++------ .../ags/engine/ac/dynobj/cc_dynamicobject.h | 34 +++++++++------ .../cc_dynamicobject_addr_and_manager.h | 22 ++++++++++ engines/ags/engine/ac/dynobj/cc_gui.cpp | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_gui.h | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_guiobject.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_hotspot.cpp | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_hotspot.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_inventory.cpp | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_inventory.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_object.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_object.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/cc_region.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_region.h | 36 +++++++++------- .../ags/engine/ac/dynobj/cc_serializer.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/cc_serializer.h | 36 +++++++++------- .../engine/ac/dynobj/managedobjectpool.cpp | 35 ++++++++++------ .../ags/engine/ac/dynobj/managedobjectpool.h | 34 +++++++++------ .../ags/engine/ac/dynobj/scriptaudiochannel.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scriptcamera.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/scriptcamera.h | 34 +++++++++------ .../ags/engine/ac/dynobj/scriptcontainers.h | 35 ++++++++++------ .../ags/engine/ac/dynobj/scriptdatetime.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/scriptdatetime.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scriptdialog.h | 39 ++++++++++-------- .../dynobj/scriptdialogoptionsrendering.cpp | 34 +++++++++------ .../ac/dynobj/scriptdialogoptionsrendering.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/scriptdict.cpp | 35 ++++++++++------ engines/ags/engine/ac/dynobj/scriptdict.h | 35 ++++++++++------ .../engine/ac/dynobj/scriptdrawingsurface.cpp | 34 +++++++++------ .../engine/ac/dynobj/scriptdrawingsurface.h | 36 +++++++++------- .../engine/ac/dynobj/scriptdynamicsprite.cpp | 34 +++++++++------ .../engine/ac/dynobj/scriptdynamicsprite.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/scriptfile.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/scriptfile.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scriptgui.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scripthotspot.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scriptinvitem.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scriptmouse.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scriptobject.h | 39 ++++++++++-------- .../ags/engine/ac/dynobj/scriptoverlay.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/scriptoverlay.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/scriptregion.h | 39 ++++++++++-------- engines/ags/engine/ac/dynobj/scriptset.cpp | 35 ++++++++++------ engines/ags/engine/ac/dynobj/scriptset.h | 35 ++++++++++------ engines/ags/engine/ac/dynobj/scriptstring.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/scriptstring.h | 36 +++++++++------- engines/ags/engine/ac/dynobj/scriptsystem.h | 39 ++++++++++-------- .../ags/engine/ac/dynobj/scriptuserobject.cpp | 34 +++++++++------ .../ags/engine/ac/dynobj/scriptuserobject.h | 35 ++++++++++------ .../ags/engine/ac/dynobj/scriptviewframe.cpp | 34 +++++++++------ .../ags/engine/ac/dynobj/scriptviewframe.h | 36 +++++++++------- .../ags/engine/ac/dynobj/scriptviewport.cpp | 34 +++++++++------ engines/ags/engine/ac/dynobj/scriptviewport.h | 34 +++++++++------ engines/ags/engine/ac/event.cpp | 34 +++++++++------ engines/ags/engine/ac/event.h | 39 ++++++++++-------- engines/ags/engine/ac/file.cpp | 34 +++++++++------ engines/ags/engine/ac/file.h | 35 ++++++++++------ engines/ags/engine/ac/game.cpp | 34 +++++++++------ engines/ags/engine/ac/game.h | 34 +++++++++------ engines/ags/engine/ac/gamesetup.cpp | 34 +++++++++------ engines/ags/engine/ac/gamesetup.h | 36 +++++++++------- engines/ags/engine/ac/gamestate.cpp | 35 ++++++++++------ engines/ags/engine/ac/gamestate.h | 34 +++++++++------ engines/ags/engine/ac/global_api.cpp | 34 +++++++++------ engines/ags/engine/ac/global_audio.cpp | 34 +++++++++------ engines/ags/engine/ac/global_audio.h | 39 ++++++++++-------- engines/ags/engine/ac/global_button.cpp | 34 +++++++++------ engines/ags/engine/ac/global_button.h | 39 ++++++++++-------- engines/ags/engine/ac/global_character.cpp | 34 +++++++++------ engines/ags/engine/ac/global_character.h | 39 ++++++++++-------- engines/ags/engine/ac/global_datetime.cpp | 34 +++++++++------ engines/ags/engine/ac/global_datetime.h | 39 ++++++++++-------- engines/ags/engine/ac/global_debug.cpp | 34 +++++++++------ engines/ags/engine/ac/global_debug.h | 39 ++++++++++-------- engines/ags/engine/ac/global_dialog.cpp | 34 +++++++++------ engines/ags/engine/ac/global_dialog.h | 39 ++++++++++-------- engines/ags/engine/ac/global_display.cpp | 34 +++++++++------ engines/ags/engine/ac/global_display.h | 39 ++++++++++-------- .../ags/engine/ac/global_drawingsurface.cpp | 34 +++++++++------ engines/ags/engine/ac/global_drawingsurface.h | 39 ++++++++++-------- .../ags/engine/ac/global_dynamicsprite.cpp | 34 +++++++++------ engines/ags/engine/ac/global_dynamicsprite.h | 39 ++++++++++-------- engines/ags/engine/ac/global_file.cpp | 34 +++++++++------ engines/ags/engine/ac/global_file.h | 39 ++++++++++-------- engines/ags/engine/ac/global_game.cpp | 34 +++++++++------ engines/ags/engine/ac/global_game.h | 39 ++++++++++-------- engines/ags/engine/ac/global_gui.cpp | 34 +++++++++------ engines/ags/engine/ac/global_gui.h | 39 ++++++++++-------- engines/ags/engine/ac/global_hotspot.cpp | 34 +++++++++------ engines/ags/engine/ac/global_hotspot.h | 39 ++++++++++-------- .../ags/engine/ac/global_inventoryitem.cpp | 34 +++++++++------ engines/ags/engine/ac/global_inventoryitem.h | 39 ++++++++++-------- engines/ags/engine/ac/global_invwindow.cpp | 34 +++++++++------ engines/ags/engine/ac/global_invwindow.h | 39 ++++++++++-------- engines/ags/engine/ac/global_label.cpp | 34 +++++++++------ engines/ags/engine/ac/global_label.h | 39 ++++++++++-------- engines/ags/engine/ac/global_listbox.cpp | 34 +++++++++------ engines/ags/engine/ac/global_listbox.h | 39 ++++++++++-------- engines/ags/engine/ac/global_mouse.cpp | 34 +++++++++------ engines/ags/engine/ac/global_mouse.h | 39 ++++++++++-------- engines/ags/engine/ac/global_object.cpp | 34 +++++++++------ engines/ags/engine/ac/global_object.h | 39 ++++++++++-------- engines/ags/engine/ac/global_overlay.cpp | 34 +++++++++------ engines/ags/engine/ac/global_overlay.h | 39 ++++++++++-------- engines/ags/engine/ac/global_palette.cpp | 34 +++++++++------ engines/ags/engine/ac/global_palette.h | 39 ++++++++++-------- engines/ags/engine/ac/global_parser.cpp | 34 +++++++++------ engines/ags/engine/ac/global_parser.h | 39 ++++++++++-------- engines/ags/engine/ac/global_plugin.h | 39 ++++++++++-------- engines/ags/engine/ac/global_record.cpp | 34 +++++++++------ engines/ags/engine/ac/global_record.h | 39 ++++++++++-------- engines/ags/engine/ac/global_region.cpp | 34 +++++++++------ engines/ags/engine/ac/global_region.h | 39 ++++++++++-------- engines/ags/engine/ac/global_room.cpp | 34 +++++++++------ engines/ags/engine/ac/global_room.h | 39 ++++++++++-------- engines/ags/engine/ac/global_screen.cpp | 34 +++++++++------ engines/ags/engine/ac/global_screen.h | 39 ++++++++++-------- engines/ags/engine/ac/global_slider.cpp | 34 +++++++++------ engines/ags/engine/ac/global_slider.h | 39 ++++++++++-------- engines/ags/engine/ac/global_string.cpp | 34 +++++++++------ engines/ags/engine/ac/global_string.h | 39 ++++++++++-------- engines/ags/engine/ac/global_textbox.cpp | 34 +++++++++------ engines/ags/engine/ac/global_textbox.h | 39 ++++++++++-------- engines/ags/engine/ac/global_timer.cpp | 34 +++++++++------ engines/ags/engine/ac/global_timer.h | 39 ++++++++++-------- engines/ags/engine/ac/global_translation.cpp | 34 +++++++++------ engines/ags/engine/ac/global_translation.h | 39 ++++++++++-------- engines/ags/engine/ac/global_video.cpp | 36 +++++++++------- engines/ags/engine/ac/global_video.h | 39 ++++++++++-------- engines/ags/engine/ac/global_viewframe.cpp | 34 +++++++++------ engines/ags/engine/ac/global_viewframe.h | 39 ++++++++++-------- engines/ags/engine/ac/global_viewport.cpp | 34 +++++++++------ engines/ags/engine/ac/global_viewport.h | 39 ++++++++++-------- engines/ags/engine/ac/global_walkablearea.cpp | 34 +++++++++------ engines/ags/engine/ac/global_walkablearea.h | 39 ++++++++++-------- engines/ags/engine/ac/global_walkbehind.cpp | 34 +++++++++------ engines/ags/engine/ac/global_walkbehind.h | 39 ++++++++++-------- engines/ags/engine/ac/gui.cpp | 34 +++++++++------ engines/ags/engine/ac/gui.h | 39 ++++++++++-------- engines/ags/engine/ac/guicontrol.cpp | 34 +++++++++------ engines/ags/engine/ac/guicontrol.h | 39 ++++++++++-------- engines/ags/engine/ac/guiinv.cpp | 34 +++++++++------ engines/ags/engine/ac/hotspot.cpp | 34 +++++++++------ engines/ags/engine/ac/hotspot.h | 39 ++++++++++-------- engines/ags/engine/ac/interfacebutton.cpp | 36 +++++++++------- engines/ags/engine/ac/interfaceelement.cpp | 34 +++++++++------ engines/ags/engine/ac/inventoryitem.cpp | 34 +++++++++------ engines/ags/engine/ac/inventoryitem.h | 39 ++++++++++-------- engines/ags/engine/ac/invwindow.cpp | 34 +++++++++------ engines/ags/engine/ac/invwindow.h | 39 ++++++++++-------- engines/ags/engine/ac/keycode.cpp | 21 ++++++++++ engines/ags/engine/ac/keycode.h | 39 ++++++++++-------- engines/ags/engine/ac/label.cpp | 34 +++++++++------ engines/ags/engine/ac/label.h | 39 ++++++++++-------- engines/ags/engine/ac/lipsync.h | 36 +++++++++------- engines/ags/engine/ac/listbox.cpp | 34 +++++++++------ engines/ags/engine/ac/listbox.h | 39 ++++++++++-------- engines/ags/engine/ac/math.cpp | 34 +++++++++------ engines/ags/engine/ac/math.h | 39 ++++++++++-------- engines/ags/engine/ac/mouse.cpp | 34 +++++++++------ engines/ags/engine/ac/mouse.h | 39 ++++++++++-------- engines/ags/engine/ac/movelist.cpp | 34 +++++++++------ engines/ags/engine/ac/movelist.h | 34 +++++++++------ engines/ags/engine/ac/object.cpp | 34 +++++++++------ engines/ags/engine/ac/object.h | 35 ++++++++++------ engines/ags/engine/ac/objectcache.h | 39 ++++++++++-------- engines/ags/engine/ac/overlay.cpp | 34 +++++++++------ engines/ags/engine/ac/overlay.h | 39 ++++++++++-------- engines/ags/engine/ac/parser.cpp | 34 +++++++++------ engines/ags/engine/ac/parser.h | 39 ++++++++++-------- engines/ags/engine/ac/path_helper.h | 35 ++++++++++------ engines/ags/engine/ac/properties.cpp | 34 +++++++++------ engines/ags/engine/ac/properties.h | 39 ++++++++++-------- engines/ags/engine/ac/region.cpp | 34 +++++++++------ engines/ags/engine/ac/region.h | 39 ++++++++++-------- engines/ags/engine/ac/richgamemedia.cpp | 21 ++++++++++ engines/ags/engine/ac/richgamemedia.h | 39 ++++++++++-------- engines/ags/engine/ac/room.cpp | 34 +++++++++------ engines/ags/engine/ac/room.h | 39 ++++++++++-------- engines/ags/engine/ac/roomobject.cpp | 34 +++++++++------ engines/ags/engine/ac/roomobject.h | 39 ++++++++++-------- engines/ags/engine/ac/roomstatus.cpp | 34 +++++++++------ engines/ags/engine/ac/roomstatus.h | 39 ++++++++++-------- engines/ags/engine/ac/route_finder.cpp | 34 +++++++++------ engines/ags/engine/ac/route_finder.h | 36 +++++++++------- engines/ags/engine/ac/route_finder_impl.cpp | 34 +++++++++------ engines/ags/engine/ac/route_finder_impl.h | 36 +++++++++------- .../engine/ac/route_finder_impl_legacy.cpp | 34 +++++++++------ .../ags/engine/ac/route_finder_impl_legacy.h | 36 +++++++++------- engines/ags/engine/ac/runtime_defines.h | 34 +++++++++------ engines/ags/engine/ac/screen.cpp | 34 +++++++++------ engines/ags/engine/ac/screen.h | 39 ++++++++++-------- engines/ags/engine/ac/screenoverlay.cpp | 34 +++++++++------ engines/ags/engine/ac/screenoverlay.h | 39 ++++++++++-------- engines/ags/engine/ac/scriptcontainers.cpp | 35 ++++++++++------ engines/ags/engine/ac/slider.cpp | 34 +++++++++------ engines/ags/engine/ac/slider.h | 39 ++++++++++-------- engines/ags/engine/ac/speech.cpp | 34 +++++++++------ engines/ags/engine/ac/speech.h | 39 ++++++++++-------- engines/ags/engine/ac/sprite.cpp | 34 +++++++++------ engines/ags/engine/ac/sprite.h | 39 ++++++++++-------- engines/ags/engine/ac/spritecache_engine.cpp | 34 +++++++++------ engines/ags/engine/ac/spritelistentry.h | 39 ++++++++++-------- .../ags/engine/ac/statobj/agsstaticobject.cpp | 21 ++++++++++ .../ags/engine/ac/statobj/agsstaticobject.h | 39 ++++++++++-------- engines/ags/engine/ac/statobj/staticarray.cpp | 21 ++++++++++ engines/ags/engine/ac/statobj/staticarray.h | 39 ++++++++++-------- engines/ags/engine/ac/statobj/staticobject.h | 35 ++++++++++------ engines/ags/engine/ac/string.cpp | 34 +++++++++------ engines/ags/engine/ac/string.h | 39 ++++++++++-------- engines/ags/engine/ac/sys_events.cpp | 34 +++++++++------ engines/ags/engine/ac/sys_events.h | 39 ++++++++++-------- engines/ags/engine/ac/system.cpp | 34 +++++++++------ engines/ags/engine/ac/system.h | 39 ++++++++++-------- engines/ags/engine/ac/textbox.cpp | 34 +++++++++------ engines/ags/engine/ac/textbox.h | 39 ++++++++++-------- engines/ags/engine/ac/timer.cpp | 34 +++++++++------ engines/ags/engine/ac/timer.h | 39 ++++++++++-------- engines/ags/engine/ac/topbarsettings.h | 39 ++++++++++-------- engines/ags/engine/ac/translation.cpp | 34 +++++++++------ engines/ags/engine/ac/translation.h | 39 ++++++++++-------- engines/ags/engine/ac/tree_map.cpp | 34 +++++++++------ engines/ags/engine/ac/tree_map.h | 39 ++++++++++-------- engines/ags/engine/ac/viewframe.cpp | 34 +++++++++------ engines/ags/engine/ac/viewframe.h | 39 ++++++++++-------- engines/ags/engine/ac/viewport_script.cpp | 34 +++++++++------ engines/ags/engine/ac/walkablearea.cpp | 34 +++++++++------ engines/ags/engine/ac/walkablearea.h | 39 ++++++++++-------- engines/ags/engine/ac/walkbehind.cpp | 34 +++++++++------ engines/ags/engine/ac/walkbehind.h | 39 ++++++++++-------- .../ags/engine/debugging/agseditordebugger.h | 39 ++++++++++-------- .../engine/debugging/consoleoutputtarget.cpp | 34 +++++++++------ .../engine/debugging/consoleoutputtarget.h | 35 ++++++++++------ engines/ags/engine/debugging/debug.cpp | 34 +++++++++------ engines/ags/engine/debugging/debug_log.h | 34 +++++++++------ engines/ags/engine/debugging/debugger.h | 34 +++++++++------ .../ags/engine/debugging/dummyagsdebugger.h | 34 +++++++++------ .../engine/debugging/filebasedagsdebugger.cpp | 34 +++++++++------ .../engine/debugging/filebasedagsdebugger.h | 34 +++++++++------ engines/ags/engine/debugging/logfile.cpp | 34 +++++++++------ engines/ags/engine/debugging/logfile.h | 35 ++++++++++------ .../ags/engine/debugging/messagebuffer.cpp | 35 ++++++++++------ engines/ags/engine/debugging/messagebuffer.h | 35 ++++++++++------ engines/ags/engine/device/mousew32.cpp | 34 +++++++++------ engines/ags/engine/device/mousew32.h | 34 +++++++++------ engines/ags/engine/font/fonts_engine.cpp | 34 +++++++++------ engines/ags/engine/game/game_init.cpp | 34 +++++++++------ engines/ags/engine/game/game_init.h | 34 +++++++++------ engines/ags/engine/game/savegame.cpp | 34 +++++++++------ engines/ags/engine/game/savegame.h | 34 +++++++++------ .../ags/engine/game/savegame_components.cpp | 34 +++++++++------ engines/ags/engine/game/savegame_components.h | 34 +++++++++------ engines/ags/engine/game/savegame_internal.h | 34 +++++++++------ engines/ags/engine/game/viewport.cpp | 35 ++++++++++------ engines/ags/engine/game/viewport.h | 35 ++++++++++------ engines/ags/engine/gfx/ali3dexception.h | 34 +++++++++------ engines/ags/engine/gfx/ali3dogl.cpp | 34 +++++++++------ engines/ags/engine/gfx/ali3dogl.h | 34 +++++++++------ engines/ags/engine/gfx/ali3dsw.cpp | 34 +++++++++------ engines/ags/engine/gfx/ali3dsw.h | 34 +++++++++------ engines/ags/engine/gfx/blender.cpp | 34 +++++++++------ engines/ags/engine/gfx/blender.h | 34 +++++++++------ engines/ags/engine/gfx/color_engine.cpp | 34 +++++++++------ engines/ags/engine/gfx/ddb.h | 35 ++++++++++------ engines/ags/engine/gfx/gfx_util.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfx_util.h | 35 ++++++++++------ engines/ags/engine/gfx/gfxdefines.h | 34 +++++++++------ engines/ags/engine/gfx/gfxdriverbase.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxdriverbase.h | 35 ++++++++++------ engines/ags/engine/gfx/gfxdriverfactory.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxdriverfactory.h | 34 +++++++++------ engines/ags/engine/gfx/gfxdriverfactorybase.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_aad3d.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_aad3d.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_aaogl.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_aaogl.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_allegro.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_allegro.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_d3d.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_d3d.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_hqx.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_hqx.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_ogl.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_ogl.h | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_scaling.cpp | 34 +++++++++------ engines/ags/engine/gfx/gfxfilter_scaling.h | 34 +++++++++------ engines/ags/engine/gfx/gfxmodelist.h | 34 +++++++++------ engines/ags/engine/gfx/graphicsdriver.h | 34 +++++++++------ engines/ags/engine/gfx/hq2x3x.h | 36 +++++++++------- engines/ags/engine/gfx/ogl_headers.h | 34 +++++++++------ engines/ags/engine/gui/animatingguibutton.cpp | 34 +++++++++------ engines/ags/engine/gui/animatingguibutton.h | 39 ++++++++++-------- engines/ags/engine/gui/cscidialog.cpp | 34 +++++++++------ engines/ags/engine/gui/cscidialog.h | 35 ++++++++++------ engines/ags/engine/gui/gui_engine.cpp | 34 +++++++++------ engines/ags/engine/gui/guidialog.cpp | 34 +++++++++------ engines/ags/engine/gui/guidialog.h | 39 ++++++++++-------- engines/ags/engine/gui/guidialogdefines.h | 41 +++++++++++-------- .../ags/engine/gui/guidialoginternaldefs.h | 39 ++++++++++-------- engines/ags/engine/gui/mycontrols.h | 35 ++++++++++------ engines/ags/engine/gui/mylabel.cpp | 34 +++++++++------ engines/ags/engine/gui/mylabel.h | 36 +++++++++------- engines/ags/engine/gui/mylistbox.cpp | 34 +++++++++------ engines/ags/engine/gui/mylistbox.h | 36 +++++++++------- engines/ags/engine/gui/mypushbutton.cpp | 36 +++++++++------- engines/ags/engine/gui/mypushbutton.h | 36 +++++++++------- engines/ags/engine/gui/mytextbox.cpp | 34 +++++++++------ engines/ags/engine/gui/mytextbox.h | 36 +++++++++------- engines/ags/engine/gui/newcontrol.cpp | 34 +++++++++------ engines/ags/engine/gui/newcontrol.h | 41 +++++++++++-------- engines/ags/engine/main/config.cpp | 34 +++++++++------ engines/ags/engine/main/config.h | 39 ++++++++++-------- engines/ags/engine/main/engine.cpp | 34 +++++++++------ engines/ags/engine/main/engine.h | 35 ++++++++++------ engines/ags/engine/main/engine_setup.cpp | 34 +++++++++------ engines/ags/engine/main/engine_setup.h | 35 ++++++++++------ engines/ags/engine/main/game_file.cpp | 34 +++++++++------ engines/ags/engine/main/game_file.h | 39 ++++++++++-------- engines/ags/engine/main/game_run.cpp | 34 +++++++++------ engines/ags/engine/main/game_run.h | 39 ++++++++++-------- engines/ags/engine/main/game_start.cpp | 34 +++++++++------ engines/ags/engine/main/game_start.h | 39 ++++++++++-------- engines/ags/engine/main/graphics_mode.cpp | 34 +++++++++------ engines/ags/engine/main/graphics_mode.h | 39 ++++++++++-------- engines/ags/engine/main/main.cpp | 34 +++++++++------ engines/ags/engine/main/main.h | 41 +++++++++++-------- engines/ags/engine/main/main_allegro.cpp | 7 ---- engines/ags/engine/main/main_allegro.h | 39 ++++++++++-------- engines/ags/engine/main/maindefines_ex.h | 39 ++++++++++-------- engines/ags/engine/main/mainheader.h | 39 ++++++++++-------- engines/ags/engine/main/quit.cpp | 34 +++++++++------ engines/ags/engine/main/quit.h | 39 ++++++++++-------- engines/ags/engine/main/update.cpp | 34 +++++++++------ engines/ags/engine/main/update.h | 39 ++++++++++-------- .../ags/engine/media/audio/ambientsound.cpp | 34 +++++++++------ engines/ags/engine/media/audio/ambientsound.h | 34 +++++++++------ engines/ags/engine/media/audio/audio.cpp | 34 +++++++++------ engines/ags/engine/media/audio/audio.h | 34 +++++++++------ engines/ags/engine/media/audio/audio_system.h | 24 ++++++++++- engines/ags/engine/media/audio/audiodefines.h | 36 +++++++++------- .../engine/media/audio/audiointernaldefs.h | 36 +++++++++------- .../ags/engine/media/audio/clip_mydumbmod.cpp | 36 +++++++++------- .../ags/engine/media/audio/clip_mydumbmod.h | 36 +++++++++------- .../ags/engine/media/audio/clip_myjgmod.cpp | 36 +++++++++------- engines/ags/engine/media/audio/clip_myjgmod.h | 36 +++++++++------- .../ags/engine/media/audio/clip_mymidi.cpp | 34 +++++++++------ engines/ags/engine/media/audio/clip_mymidi.h | 36 +++++++++------- engines/ags/engine/media/audio/clip_mymp3.cpp | 36 +++++++++------- engines/ags/engine/media/audio/clip_mymp3.h | 36 +++++++++------- engines/ags/engine/media/audio/clip_myogg.cpp | 34 +++++++++------ engines/ags/engine/media/audio/clip_myogg.h | 36 +++++++++------- .../engine/media/audio/clip_mystaticmp3.cpp | 34 +++++++++------ .../ags/engine/media/audio/clip_mystaticmp3.h | 34 +++++++++------ .../engine/media/audio/clip_mystaticogg.cpp | 34 +++++++++------ .../ags/engine/media/audio/clip_mystaticogg.h | 34 +++++++++------ .../ags/engine/media/audio/clip_mywave.cpp | 34 +++++++++------ engines/ags/engine/media/audio/clip_mywave.h | 36 +++++++++------- .../engine/media/audio/queuedaudioitem.cpp | 34 +++++++++------ .../ags/engine/media/audio/queuedaudioitem.h | 36 +++++++++------- engines/ags/engine/media/audio/sound.cpp | 34 +++++++++------ engines/ags/engine/media/audio/sound.h | 34 +++++++++------ engines/ags/engine/media/audio/soundcache.cpp | 34 +++++++++------ engines/ags/engine/media/audio/soundcache.h | 34 +++++++++------ engines/ags/engine/media/audio/soundclip.cpp | 34 +++++++++------ engines/ags/engine/media/audio/soundclip.h | 34 +++++++++------ engines/ags/engine/media/video/VMR9Graph.h | 34 +++++++++------ engines/ags/engine/media/video/video.cpp | 36 +++++++++------- engines/ags/engine/media/video/video.h | 39 ++++++++++-------- .../ags/engine/platform/android/acpland.cpp | 34 +++++++++------ .../platform/base/agsplatformdriver.cpp | 34 +++++++++------ .../engine/platform/base/agsplatformdriver.h | 34 +++++++++------ engines/ags/engine/platform/ios/acplios.cpp | 34 +++++++++------ engines/ags/engine/platform/linux/acpllnx.cpp | 34 +++++++++------ engines/ags/engine/platform/osx/acplmac.cpp | 34 +++++++++------ engines/ags/engine/platform/util/pe.h | 34 +++++++++------ .../ags/engine/platform/windows/acplwin.cpp | 34 +++++++++------ .../engine/platform/windows/gfx/ali3dd3d.cpp | 36 ++++++++++------ .../engine/platform/windows/gfx/ali3dd3d.h | 34 +++++++++------ .../platform/windows/media/video/acwavi.cpp | 36 ++++++++++------ .../platform/windows/media/video/acwavi3d.cpp | 34 +++++++++------ .../ags/engine/platform/windows/minidump.cpp | 35 ++++++++++------ .../platform/windows/setup/winsetup.cpp | 36 +++++++++------- .../engine/platform/windows/setup/winsetup.h | 34 +++++++++------ .../platform/windows/win_ex_handling.cpp | 35 ++++++++++------ .../engine/platform/windows/win_ex_handling.h | 35 ++++++++++------ .../platform/windows/winapi_exclusive.h | 35 ++++++++++------ engines/ags/engine/plugin/agsplugin.cpp | 36 +++++++++------- engines/ags/engine/plugin/agsplugin.h | 34 +++++++++------ engines/ags/engine/plugin/global_plugin.cpp | 34 +++++++++------ engines/ags/engine/plugin/plugin_builtin.h | 35 ++++++++++------ engines/ags/engine/plugin/plugin_engine.h | 35 ++++++++++------ .../ags/engine/plugin/pluginobjectreader.cpp | 34 +++++++++------ .../ags/engine/plugin/pluginobjectreader.h | 39 ++++++++++-------- engines/ags/engine/resource/resource.h | 22 ++++++++++ engines/ags/engine/script/cc_instance.cpp | 34 +++++++++------ engines/ags/engine/script/cc_instance.h | 34 +++++++++------ engines/ags/engine/script/executingscript.cpp | 34 +++++++++------ engines/ags/engine/script/executingscript.h | 39 ++++++++++-------- engines/ags/engine/script/exports.cpp | 34 +++++++++------ engines/ags/engine/script/exports.h | 35 ++++++++++------ .../engine/script/nonblockingscriptfunction.h | 39 ++++++++++-------- .../ags/engine/script/runtimescriptvalue.cpp | 21 ++++++++++ .../ags/engine/script/runtimescriptvalue.h | 35 ++++++++++------ engines/ags/engine/script/script.cpp | 34 +++++++++------ engines/ags/engine/script/script.h | 39 ++++++++++-------- engines/ags/engine/script/script_api.cpp | 34 +++++++++------ engines/ags/engine/script/script_api.h | 35 ++++++++++------ engines/ags/engine/script/script_engine.cpp | 34 +++++++++------ engines/ags/engine/script/script_runtime.cpp | 34 +++++++++------ engines/ags/engine/script/script_runtime.h | 34 +++++++++------ engines/ags/engine/script/systemimports.cpp | 34 +++++++++------ engines/ags/engine/script/systemimports.h | 36 +++++++++------- engines/ags/engine/util/library.h | 34 +++++++++------ engines/ags/engine/util/library_dummy.h | 34 +++++++++------ engines/ags/engine/util/library_posix.h | 34 +++++++++------ engines/ags/engine/util/library_psp.h | 35 +++++++++------- engines/ags/engine/util/library_windows.h | 35 ++++++++++------ engines/ags/engine/util/mutex.h | 34 +++++++++------ engines/ags/engine/util/mutex_base.h | 34 +++++++++------ engines/ags/engine/util/mutex_lock.h | 34 +++++++++------ engines/ags/engine/util/mutex_psp.h | 34 +++++++++------ engines/ags/engine/util/mutex_pthread.h | 34 +++++++++------ engines/ags/engine/util/mutex_std.h | 34 +++++++++------ engines/ags/engine/util/mutex_wii.h | 34 +++++++++------ engines/ags/engine/util/mutex_windows.h | 35 ++++++++++------ engines/ags/engine/util/scaling.h | 35 ++++++++++------ engines/ags/engine/util/thread.h | 34 +++++++++------ engines/ags/engine/util/thread_psp.h | 34 +++++++++------ engines/ags/engine/util/thread_pthread.h | 34 +++++++++------ engines/ags/engine/util/thread_std.h | 34 +++++++++------ engines/ags/engine/util/thread_wii.h | 34 +++++++++------ engines/ags/engine/util/thread_windows.h | 35 ++++++++++------ engines/ags/shared/ac/audiocliptype.cpp | 34 +++++++++------ engines/ags/shared/ac/audiocliptype.h | 36 +++++++++------- engines/ags/shared/ac/characterinfo.cpp | 34 +++++++++------ engines/ags/shared/ac/characterinfo.h | 36 +++++++++------- engines/ags/shared/ac/common.cpp | 34 +++++++++------ engines/ags/shared/ac/common.h | 34 +++++++++------ engines/ags/shared/ac/common_defines.h | 34 +++++++++------ engines/ags/shared/ac/dialogtopic.cpp | 34 +++++++++------ engines/ags/shared/ac/dialogtopic.h | 41 +++++++++++-------- .../ags/shared/ac/dynobj/scriptaudioclip.cpp | 34 +++++++++------ .../ags/shared/ac/dynobj/scriptaudioclip.h | 39 ++++++++++-------- engines/ags/shared/ac/game_version.h | 34 +++++++++------ engines/ags/shared/ac/gamesetupstruct.cpp | 34 +++++++++------ engines/ags/shared/ac/gamesetupstruct.h | 39 ++++++++++-------- engines/ags/shared/ac/gamesetupstructbase.cpp | 34 +++++++++------ engines/ags/shared/ac/gamesetupstructbase.h | 41 +++++++++++-------- engines/ags/shared/ac/gamestructdefines.h | 39 ++++++++++-------- engines/ags/shared/ac/interfacebutton.h | 36 +++++++++------- engines/ags/shared/ac/interfaceelement.h | 36 +++++++++------- engines/ags/shared/ac/inventoryiteminfo.cpp | 34 +++++++++------ engines/ags/shared/ac/inventoryiteminfo.h | 36 +++++++++------- engines/ags/shared/ac/mousecursor.cpp | 34 +++++++++------ engines/ags/shared/ac/mousecursor.h | 36 +++++++++------- engines/ags/shared/ac/oldgamesetupstruct.h | 39 ++++++++++-------- engines/ags/shared/ac/spritecache.cpp | 34 +++++++++------ engines/ags/shared/ac/spritecache.h | 34 +++++++++------ engines/ags/shared/ac/view.cpp | 34 +++++++++------ engines/ags/shared/ac/view.h | 36 +++++++++------- engines/ags/shared/ac/wordsdictionary.cpp | 34 +++++++++------ engines/ags/shared/ac/wordsdictionary.h | 36 +++++++++------- engines/ags/shared/api/stream_api.h | 35 ++++++++++------ engines/ags/shared/core/asset.cpp | 34 +++++++++------ engines/ags/shared/core/asset.h | 34 +++++++++------ engines/ags/shared/core/assetmanager.cpp | 34 +++++++++------ engines/ags/shared/core/assetmanager.h | 34 +++++++++------ engines/ags/shared/core/def_version.h | 22 ++++++++++ engines/ags/shared/core/platform.h | 24 ++++++++++- engines/ags/shared/core/types.h | 35 ++++++++++------ engines/ags/shared/debugging/assert.h | 35 ++++++++++------ engines/ags/shared/debugging/debugmanager.cpp | 35 ++++++++++------ engines/ags/shared/debugging/debugmanager.h | 35 ++++++++++------ engines/ags/shared/debugging/out.h | 35 ++++++++++------ engines/ags/shared/debugging/outputhandler.h | 35 ++++++++++------ engines/ags/shared/font/agsfontrenderer.h | 34 +++++++++------ engines/ags/shared/font/fonts.cpp | 34 +++++++++------ engines/ags/shared/font/fonts.h | 34 +++++++++------ engines/ags/shared/font/ttffontrenderer.cpp | 34 +++++++++------ engines/ags/shared/font/ttffontrenderer.h | 34 +++++++++------ engines/ags/shared/font/wfnfont.cpp | 34 +++++++++------ engines/ags/shared/font/wfnfont.h | 34 +++++++++------ engines/ags/shared/font/wfnfontrenderer.cpp | 34 +++++++++------ engines/ags/shared/font/wfnfontrenderer.h | 34 +++++++++------ engines/ags/shared/game/customproperties.cpp | 34 +++++++++------ engines/ags/shared/game/customproperties.h | 35 ++++++++++------ engines/ags/shared/game/interactions.cpp | 34 +++++++++------ engines/ags/shared/game/interactions.h | 35 ++++++++++------ engines/ags/shared/game/main_game_file.cpp | 34 +++++++++------ engines/ags/shared/game/main_game_file.h | 34 +++++++++------ engines/ags/shared/game/plugininfo.h | 34 +++++++++------ engines/ags/shared/game/room_file.cpp | 34 +++++++++------ engines/ags/shared/game/room_file.h | 34 +++++++++------ .../ags/shared/game/room_file_deprecated.cpp | 34 +++++++++------ engines/ags/shared/game/room_version.h | 34 +++++++++------ engines/ags/shared/game/roomstruct.cpp | 34 +++++++++------ engines/ags/shared/game/roomstruct.h | 35 ++++++++++------ engines/ags/shared/gfx/allegrobitmap.cpp | 34 +++++++++------ engines/ags/shared/gfx/allegrobitmap.h | 35 ++++++++++------ engines/ags/shared/gfx/bitmap.cpp | 34 +++++++++------ engines/ags/shared/gfx/bitmap.h | 34 +++++++++------ engines/ags/shared/gfx/gfx_def.h | 35 ++++++++++------ engines/ags/shared/gui/guibutton.cpp | 34 +++++++++------ engines/ags/shared/gui/guibutton.h | 34 +++++++++------ engines/ags/shared/gui/guidefines.h | 34 +++++++++------ engines/ags/shared/gui/guiinv.cpp | 34 +++++++++------ engines/ags/shared/gui/guiinv.h | 34 +++++++++------ engines/ags/shared/gui/guilabel.cpp | 34 +++++++++------ engines/ags/shared/gui/guilabel.h | 34 +++++++++------ engines/ags/shared/gui/guilistbox.cpp | 34 +++++++++------ engines/ags/shared/gui/guilistbox.h | 34 +++++++++------ engines/ags/shared/gui/guimain.cpp | 34 +++++++++------ engines/ags/shared/gui/guimain.h | 34 +++++++++------ engines/ags/shared/gui/guiobject.cpp | 34 +++++++++------ engines/ags/shared/gui/guiobject.h | 34 +++++++++------ engines/ags/shared/gui/guislider.cpp | 34 +++++++++------ engines/ags/shared/gui/guislider.h | 34 +++++++++------ engines/ags/shared/gui/guitextbox.cpp | 34 +++++++++------ engines/ags/shared/gui/guitextbox.h | 34 +++++++++------ engines/ags/shared/script/cc_error.cpp | 34 +++++++++------ engines/ags/shared/script/cc_error.h | 34 +++++++++------ engines/ags/shared/script/cc_options.cpp | 34 +++++++++------ engines/ags/shared/script/cc_options.h | 34 +++++++++------ engines/ags/shared/script/cc_script.cpp | 34 +++++++++------ engines/ags/shared/script/cc_script.h | 34 +++++++++------ engines/ags/shared/script/script_common.h | 34 +++++++++------ engines/ags/shared/util/alignedstream.cpp | 34 +++++++++------ engines/ags/shared/util/alignedstream.h | 35 ++++++++++------ engines/ags/shared/util/bbop.h | 34 +++++++++------ engines/ags/shared/util/bufferedstream.cpp | 35 ++++++++++------ engines/ags/shared/util/bufferedstream.h | 34 +++++++++------ engines/ags/shared/util/compress.cpp | 34 +++++++++------ engines/ags/shared/util/compress.h | 34 +++++++++------ engines/ags/shared/util/datastream.cpp | 34 +++++++++------ engines/ags/shared/util/datastream.h | 35 ++++++++++------ engines/ags/shared/util/directory.cpp | 21 ++++++++++ engines/ags/shared/util/directory.h | 35 ++++++++++------ engines/ags/shared/util/error.h | 35 ++++++++++------ engines/ags/shared/util/file.cpp | 34 +++++++++------ engines/ags/shared/util/file.h | 35 ++++++++++------ engines/ags/shared/util/filestream.cpp | 34 +++++++++------ engines/ags/shared/util/filestream.h | 39 ++++++++++-------- engines/ags/shared/util/geometry.cpp | 35 ++++++++++------ engines/ags/shared/util/geometry.h | 35 ++++++++++------ engines/ags/shared/util/ini_util.cpp | 34 +++++++++------ engines/ags/shared/util/ini_util.h | 35 ++++++++++------ engines/ags/shared/util/inifile.cpp | 34 +++++++++------ engines/ags/shared/util/inifile.h | 35 ++++++++++------ engines/ags/shared/util/lzw.cpp | 34 +++++++++------ engines/ags/shared/util/lzw.h | 39 ++++++++++-------- engines/ags/shared/util/math.h | 35 ++++++++++------ engines/ags/shared/util/memory.h | 35 ++++++++++------ engines/ags/shared/util/misc.cpp | 34 +++++++++------ engines/ags/shared/util/misc.h | 34 +++++++++------ engines/ags/shared/util/multifilelib.h | 34 +++++++++------ engines/ags/shared/util/mutifilelib.cpp | 34 +++++++++------ engines/ags/shared/util/path.cpp | 21 ++++++++++ engines/ags/shared/util/path.h | 35 ++++++++++------ engines/ags/shared/util/proxystream.cpp | 34 +++++++++------ engines/ags/shared/util/proxystream.h | 39 ++++++++++-------- engines/ags/shared/util/stdio_compat.h | 34 +++++++++------ engines/ags/shared/util/stream.cpp | 34 +++++++++------ engines/ags/shared/util/stream.h | 35 ++++++++++------ engines/ags/shared/util/string.cpp | 35 ++++++++++------ engines/ags/shared/util/string.h | 34 +++++++++------ engines/ags/shared/util/string_compat.h | 35 ++++++++++------ engines/ags/shared/util/string_types.h | 35 ++++++++++------ engines/ags/shared/util/string_utils.cpp | 35 ++++++++++------ engines/ags/shared/util/string_utils.h | 39 ++++++++++-------- engines/ags/shared/util/textreader.h | 35 ++++++++++------ engines/ags/shared/util/textstreamreader.cpp | 34 +++++++++------ engines/ags/shared/util/textstreamreader.h | 35 ++++++++++------ engines/ags/shared/util/textstreamwriter.cpp | 34 +++++++++------ engines/ags/shared/util/textstreamwriter.h | 35 ++++++++++------ engines/ags/shared/util/textwriter.h | 35 ++++++++++------ engines/ags/shared/util/version.cpp | 34 +++++++++------ engines/ags/shared/util/version.h | 35 ++++++++++------ engines/ags/shared/util/wgt2allg.cpp | 36 +++++++++------- engines/ags/shared/util/wgt2allg.h | 34 +++++++++------ 627 files changed, 13559 insertions(+), 8469 deletions(-) delete mode 100644 engines/ags/engine/main/main_allegro.cpp diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index 9c6c442166cd..fa62fecc2b72 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Functions related to finding and opening game assets. // //============================================================================= + #ifndef __AGS_EE_AC__ASSETHELPER_H #define __AGS_EE_AC__ASSETHELPER_H #include diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp index 4ac75c4e7a76..3f1190b01785 100644 --- a/engines/ags/engine/ac/audiochannel.cpp +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/audiochannel.h" #include "ac/gamestate.h" diff --git a/engines/ags/engine/ac/audiochannel.h b/engines/ags/engine/ac/audiochannel.h index de655725ad47..1955cc146c4d 100644 --- a/engines/ags/engine/ac/audiochannel.h +++ b/engines/ags/engine/ac/audiochannel.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__AUDIOCHANNEL_H #define __AGS_EE_AC__AUDIOCHANNEL_H diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp index 5489ee5a3b34..2a02f1fd95f4 100644 --- a/engines/ags/engine/ac/audioclip.cpp +++ b/engines/ags/engine/ac/audioclip.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/asset_helper.h" #include "ac/audioclip.h" diff --git a/engines/ags/engine/ac/audioclip.h b/engines/ags/engine/ac/audioclip.h index ffb4a100b5e9..113ed78423d5 100644 --- a/engines/ags/engine/ac/audioclip.h +++ b/engines/ags/engine/ac/audioclip.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__AUDIOCLIP_H #define __AGS_EE_AC__AUDIOCLIP_H diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp index ecbcb1b1bc1f..f235292a3a53 100644 --- a/engines/ags/engine/ac/button.cpp +++ b/engines/ags/engine/ac/button.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/button.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h index 5f94aaea18d7..7a36b2455247 100644 --- a/engines/ags/engine/ac/button.h +++ b/engines/ags/engine/ac/button.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // diff --git a/engines/ags/engine/ac/cdaudio.cpp b/engines/ags/engine/ac/cdaudio.cpp index 866d797f50cc..b8f3a1e5acc4 100644 --- a/engines/ags/engine/ac/cdaudio.cpp +++ b/engines/ags/engine/ac/cdaudio.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/cdaudio.h" #include "platform/base/agsplatformdriver.h" diff --git a/engines/ags/engine/ac/cdaudio.h b/engines/ags/engine/ac/cdaudio.h index 4009b520fbe4..feda127c91af 100644 --- a/engines/ags/engine/ac/cdaudio.h +++ b/engines/ags/engine/ac/cdaudio.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__CDAUDIO_H #define __AGS_EE_AC__CDAUDIO_H diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index 526c9705acfa..533810146964 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS Character functions diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h index cb678fda3a1b..32016da90656 100644 --- a/engines/ags/engine/ac/character.h +++ b/engines/ags/engine/ac/character.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__CHARACTER_H #define __AGS_EE_AC__CHARACTER_H diff --git a/engines/ags/engine/ac/charactercache.h b/engines/ags/engine/ac/charactercache.h index f4b5c640120f..ca914d3f47bd 100644 --- a/engines/ags/engine/ac/charactercache.h +++ b/engines/ags/engine/ac/charactercache.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__CHARACTERCACHE_H #define __AGS_EE_AC__CHARACTERCACHE_H diff --git a/engines/ags/engine/ac/characterextras.cpp b/engines/ags/engine/ac/characterextras.cpp index 13c8f8135057..211534e07563 100644 --- a/engines/ags/engine/ac/characterextras.cpp +++ b/engines/ags/engine/ac/characterextras.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/characterextras.h" #include "util/stream.h" diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h index 2e9d6e6098d2..c694b2c96489 100644 --- a/engines/ags/engine/ac/characterextras.h +++ b/engines/ags/engine/ac/characterextras.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__CHARACTEREXTRAS_H #define __AGS_EE_AC__CHARACTEREXTRAS_H diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp index 8f6f1a5a8376..819b92fc11a8 100644 --- a/engines/ags/engine/ac/characterinfo_engine.cpp +++ b/engines/ags/engine/ac/characterinfo_engine.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/characterinfo.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/datetime.cpp b/engines/ags/engine/ac/datetime.cpp index d2f8b230b21a..e11d967b747e 100644 --- a/engines/ags/engine/ac/datetime.cpp +++ b/engines/ags/engine/ac/datetime.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/datetime.h" diff --git a/engines/ags/engine/ac/datetime.h b/engines/ags/engine/ac/datetime.h index 76d474ee0062..34be0b0e68e7 100644 --- a/engines/ags/engine/ac/datetime.h +++ b/engines/ags/engine/ac/datetime.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__DATETIME_H #define __AGS_EE_AC__DATETIME_H diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index d27fe02f9425..4cf2f530bf0d 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dialog.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h index 93fcf4868c28..817c3ac1cc50 100644 --- a/engines/ags/engine/ac/dialog.h +++ b/engines/ags/engine/ac/dialog.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__DIALOG_H #define __AGS_EE_AC__DIALOG_H diff --git a/engines/ags/engine/ac/dialogoptionsrendering.cpp b/engines/ags/engine/ac/dialogoptionsrendering.cpp index 08f2e876abff..686de549b0d9 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dialogoptionsrendering.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dialog.h" #include "ac/dialogtopic.h" diff --git a/engines/ags/engine/ac/dialogoptionsrendering.h b/engines/ags/engine/ac/dialogoptionsrendering.h index f08366df3d95..7917ae15b0e3 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.h +++ b/engines/ags/engine/ac/dialogoptionsrendering.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__DIALOGOPTIONSRENDERING_H #define __AGS_EE_AC__DIALOGOPTIONSRENDERING_H diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp index f31db0641400..dbf7b27ad5e6 100644 --- a/engines/ags/engine/ac/display.cpp +++ b/engines/ags/engine/ac/display.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h index 68b00bfdad28..69e980ecc721 100644 --- a/engines/ags/engine/ac/display.h +++ b/engines/ags/engine/ac/display.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__DISPLAY_H #define __AGS_EE_AC__DISPLAY_H diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index fe24f1c4534f..96b420cf5ac2 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index af6e8e935493..19e2274319d2 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__DRAW_H #define __AGS_EE_AC__DRAW_H diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index 721b676924f6..014713495a21 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Software drawing component. Optimizes drawing for software renderer using diff --git a/engines/ags/engine/ac/draw_software.h b/engines/ags/engine/ac/draw_software.h index 47db5b227f2a..e0e59339eb20 100644 --- a/engines/ags/engine/ac/draw_software.h +++ b/engines/ags/engine/ac/draw_software.h @@ -1,21 +1,32 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Software drawing component. Optimizes drawing for software renderer using // dirty rectangles technique. // //============================================================================= + #ifndef __AGS_EE_AC__DRAWSOFTWARE_H #define __AGS_EE_AC__DRAWSOFTWARE_H diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp index 5dc0ccdf9e27..3e8fc26de12f 100644 --- a/engines/ags/engine/ac/drawingsurface.cpp +++ b/engines/ags/engine/ac/drawingsurface.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/draw.h" #include "ac/drawingsurface.h" diff --git a/engines/ags/engine/ac/drawingsurface.h b/engines/ags/engine/ac/drawingsurface.h index 5bd6b7aac716..511cf1b441b3 100644 --- a/engines/ags/engine/ac/drawingsurface.h +++ b/engines/ags/engine/ac/drawingsurface.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__DRAWINGSURFACE_H #define __AGS_EE_AC__DRAWINGSURFACE_H diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp index 480a233e1ae1..18e5b2c264bb 100644 --- a/engines/ags/engine/ac/dynamicsprite.cpp +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/dynamicsprite.h" diff --git a/engines/ags/engine/ac/dynamicsprite.h b/engines/ags/engine/ac/dynamicsprite.h index 6602c8540285..0f644f4aed45 100644 --- a/engines/ags/engine/ac/dynamicsprite.h +++ b/engines/ags/engine/ac/dynamicsprite.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__DYNAMICSPRITE_H #define __AGS_EE_AC__DYNAMICSPRITE_H diff --git a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h index cc6cb71c13be..d4687da0a924 100644 --- a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h +++ b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H #define __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H diff --git a/engines/ags/engine/ac/dynobj/all_scriptclasses.h b/engines/ags/engine/ac/dynobj/all_scriptclasses.h index bcaf7a1d4737..6a703be07efc 100644 --- a/engines/ags/engine/ac/dynobj/all_scriptclasses.h +++ b/engines/ags/engine/ac/dynobj/all_scriptclasses.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__ALLSCRIPTCLASSES_H #define __AGS_EE_DYNOBJ__ALLSCRIPTCLASSES_H diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp index e1d0e6e6ee6e..ef775fcb987d 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "core/types.h" diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h index 3c2d795e1b9a..c0a0eab4dc90 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCDYNAMICOBJECT_H #define __AC_CCDYNAMICOBJECT_H @@ -57,4 +65,4 @@ struct AGSCCDynamicObject : ICCDynamicObject { }; -#endif // __AC_CCDYNAMICOBJECT_H \ No newline at end of file +#endif // __AC_CCDYNAMICOBJECT_H diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp index 40f96af17017..e93da266f5e9 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_audiochannel.h" #include "ac/dynobj/scriptaudiochannel.h" diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.h b/engines/ags/engine/ac/dynobj/cc_audiochannel.h index d13dd4cd0910..b7c0eb0ef3bb 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.h +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H #define __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp index 31e4a0105bc9..90607a3c5cbc 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_audioclip.h" #include "ac/dynobj/scriptaudioclip.h" diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.h b/engines/ags/engine/ac/dynobj/cc_audioclip.h index b8b633a63c27..6439ec35db30 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.h +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__CCAUDIOCLIP_H #define __AGS_EE_DYNOBJ__CCAUDIOCLIP_H diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index 00478f2b08b6..f54087b0f209 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_character.h" #include "ac/characterinfo.h" diff --git a/engines/ags/engine/ac/dynobj/cc_character.h b/engines/ags/engine/ac/dynobj/cc_character.h index d610cb914f2a..06ff2e28d4ba 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.h +++ b/engines/ags/engine/ac/dynobj/cc_character.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCCHARACTER_H #define __AC_CCCHARACTER_H @@ -31,4 +39,4 @@ struct CCCharacter final : AGSCCDynamicObject { void WriteInt16(const char *address, intptr_t offset, int16_t val) override; }; -#endif // __AC_CCCHARACTER_H \ No newline at end of file +#endif // __AC_CCCHARACTER_H diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp index 5c52802cae38..1b9cdfc0be68 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_dialog.h" #include "ac/dialog.h" diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.h b/engines/ags/engine/ac/dynobj/cc_dialog.h index bf1a95e122af..0e7a7017893f 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.h +++ b/engines/ags/engine/ac/dynobj/cc_dialog.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCDIALOG_H #define __AC_CCDIALOG_H diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp index 694ef902132a..9bf273b14b47 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "cc_dynamicarray.h" diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index 4619ff7137de..ed2916724458 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __CC_DYNAMICARRAY_H #define __CC_DYNAMICARRAY_H @@ -55,4 +64,4 @@ namespace DynamicArrayHelpers DynObjectRef CreateStringArray(const std::vector); }; -#endif \ No newline at end of file +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp index 7c9a1039d4d0..0bc70e3aee75 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // C-Script run-time interpreter (c) 2001 Chris Jones diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index 2d417d5018af..aeca72f4d007 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Managed script object interface. diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h index 0f22f30f174f..4323d976524f 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h @@ -1,3 +1,25 @@ +/* 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 ADDR_AND_MANAGER_H #define ADDR_AND_MANAGER_H diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp index 40ff70c4a1e3..e453edd45b24 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.cpp +++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_gui.h" #include "ac/dynobj/scriptgui.h" @@ -35,4 +43,4 @@ void CCGUI::Unserialize(int index, const char *serializedData, int dataSize) { StartUnserialize(serializedData, dataSize); int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrGui[num], this); -} \ No newline at end of file +} diff --git a/engines/ags/engine/ac/dynobj/cc_gui.h b/engines/ags/engine/ac/dynobj/cc_gui.h index b29f5171bce1..39c892d48dfa 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.h +++ b/engines/ags/engine/ac/dynobj/cc_gui.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCGUI_H #define __AC_CCGUI_H diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp index a4d615332709..5983f6561bfc 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_guiobject.h" #include "ac/dynobj/scriptgui.h" diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.h b/engines/ags/engine/ac/dynobj/cc_guiobject.h index 2d261956f242..a6bf88165426 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.h +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCGUIOBJECT_H #define __AC_CCGUIOBJECT_H @@ -30,4 +38,4 @@ struct CCGUIObject final : AGSCCDynamicObject { }; -#endif // __AC_CCGUIOBJECT_H \ No newline at end of file +#endif // __AC_CCGUIOBJECT_H diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp index cc109cd228f2..073cd657142a 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_hotspot.h" #include "ac/dynobj/scripthotspot.h" @@ -37,4 +45,4 @@ void CCHotspot::Unserialize(int index, const char *serializedData, int dataSize) StartUnserialize(serializedData, dataSize); int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrHotspot[num], this); -} \ No newline at end of file +} diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.h b/engines/ags/engine/ac/dynobj/cc_hotspot.h index 8137cd374077..05722895fba6 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.h +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCHOTSPOT_H #define __AC_CCHOTSPOT_H @@ -30,4 +38,4 @@ struct CCHotspot final : AGSCCDynamicObject { }; -#endif // __AC_CCHOTSPOT_H \ No newline at end of file +#endif // __AC_CCHOTSPOT_H diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp index cf9268c997d7..9333b5d96cf5 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.cpp +++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_inventory.h" #include "ac/dynobj/scriptinvitem.h" @@ -36,4 +44,4 @@ void CCInventory::Unserialize(int index, const char *serializedData, int dataSiz StartUnserialize(serializedData, dataSize); int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrInv[num], this); -} \ No newline at end of file +} diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.h b/engines/ags/engine/ac/dynobj/cc_inventory.h index 4e668aff7068..aba9dc7c8afb 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.h +++ b/engines/ags/engine/ac/dynobj/cc_inventory.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCINVENTORY_H #define __AC_CCINVENTORY_H @@ -30,4 +38,4 @@ struct CCInventory final : AGSCCDynamicObject { }; -#endif // __AC_CCINVENTORY_H \ No newline at end of file +#endif // __AC_CCINVENTORY_H diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp index 215ad0e469c0..355456e78cf3 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.cpp +++ b/engines/ags/engine/ac/dynobj/cc_object.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_object.h" #include "ac/dynobj/scriptobject.h" diff --git a/engines/ags/engine/ac/dynobj/cc_object.h b/engines/ags/engine/ac/dynobj/cc_object.h index 6e654441325b..f81b0d5cdfc4 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.h +++ b/engines/ags/engine/ac/dynobj/cc_object.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCOBJECT_H #define __AC_CCOBJECT_H @@ -30,4 +38,4 @@ struct CCObject final : AGSCCDynamicObject { }; -#endif // __AC_CCOBJECT_H \ No newline at end of file +#endif // __AC_CCOBJECT_H diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp index 92ba34911827..31130c9b5e59 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.cpp +++ b/engines/ags/engine/ac/dynobj/cc_region.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_region.h" #include "ac/dynobj/scriptregion.h" diff --git a/engines/ags/engine/ac/dynobj/cc_region.h b/engines/ags/engine/ac/dynobj/cc_region.h index 626ee4e2bc5f..6abb7df1532b 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.h +++ b/engines/ags/engine/ac/dynobj/cc_region.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CCREGION_H #define __AC_CCREGION_H @@ -30,4 +38,4 @@ struct CCRegion final : AGSCCDynamicObject { }; -#endif // __AC_CCREGION_H \ No newline at end of file +#endif // __AC_CCREGION_H diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp index 140613116a61..f183747b983a 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.cpp +++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/dynobj/cc_serializer.h" diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h index d30a8f477d43..9de17b54d535 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.h +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SERIALIZER_H #define __AC_SERIALIZER_H @@ -24,4 +32,4 @@ struct AGSDeSerializer : ICCObjectReader { extern AGSDeSerializer ccUnserializer; -#endif // __AC_SERIALIZER_H \ No newline at end of file +#endif // __AC_SERIALIZER_H diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index 422aff050fee..2d430147437a 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include #include "ac/dynobj/managedobjectpool.h" diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index 6107cadb81c0..6697592d9b39 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __CC_MANAGEDOBJECTPOOL_H #define __CC_MANAGEDOBJECTPOOL_H diff --git a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h index c256ead6e2fc..c8ecb6fbf871 100644 --- a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h +++ b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H #define __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp index e9db1cb99861..a4f44f881b49 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.cpp +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptcamera.h" #include "ac/gamestate.h" diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.h b/engines/ags/engine/ac/dynobj/scriptcamera.h index 4aa25304e58f..292e02216051 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.h +++ b/engines/ags/engine/ac/dynobj/scriptcamera.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTCAMERA_H #define __AC_SCRIPTCAMERA_H diff --git a/engines/ags/engine/ac/dynobj/scriptcontainers.h b/engines/ags/engine/ac/dynobj/scriptcontainers.h index a0a374831a9b..5159a237ef5f 100644 --- a/engines/ags/engine/ac/dynobj/scriptcontainers.h +++ b/engines/ags/engine/ac/dynobj/scriptcontainers.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTCONTAINERS_H #define __AC_SCRIPTCONTAINERS_H diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp index eb57fbdf7651..45836d06e483 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptdatetime.h" diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.h b/engines/ags/engine/ac/dynobj/scriptdatetime.h index bc12bf27972d..c898e93fa6e6 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.h +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTDATETIME_H #define __AGS_EE_DYNOBJ__SCRIPTDATETIME_H diff --git a/engines/ags/engine/ac/dynobj/scriptdialog.h b/engines/ags/engine/ac/dynobj/scriptdialog.h index 9d8222e55035..f549afcd1e0f 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialog.h +++ b/engines/ags/engine/ac/dynobj/scriptdialog.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTDIALOG_H #define __AGS_EE_DYNOBJ__SCRIPTDIALOG_H diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp index d05f63890527..d844282b7806 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptdialogoptionsrendering.h" diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h index a50d9d02e294..d13ab0e8c32c 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTDIALOGOPTIONSRENDERING_H #define __AC_SCRIPTDIALOGOPTIONSRENDERING_H @@ -44,4 +52,4 @@ struct ScriptDialogOptionsRendering final : AGSCCDynamicObject { }; -#endif // __AC_SCRIPTDIALOGOPTIONSRENDERING_H \ No newline at end of file +#endif // __AC_SCRIPTDIALOGOPTIONSRENDERING_H diff --git a/engines/ags/engine/ac/dynobj/scriptdict.cpp b/engines/ags/engine/ac/dynobj/scriptdict.cpp index 5676ae260391..4bec65ce42a8 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdict.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptdict.h" int ScriptDictBase::Dispose(const char *address, bool force) diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index e89d22c10e7d..62039f4c7639 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Managed script object wrapping std::map and @@ -22,6 +32,7 @@ // types as keys; need to research what perfomance impact that would make. // //============================================================================= + #ifndef __AC_SCRIPTDICT_H #define __AC_SCRIPTDICT_H diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp index 1f68eb1ec571..14e66298f42c 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptdrawingsurface.h" #include "ac/spritecache.h" diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h index 4751be333a98..8cf35a6d93a2 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTDRAWINGSURFACE_H #define __AC_SCRIPTDRAWINGSURFACE_H @@ -52,4 +60,4 @@ struct ScriptDrawingSurface final : AGSCCDynamicObject { ScriptDrawingSurface(); }; -#endif // __AC_SCRIPTDRAWINGSURFACE_H \ No newline at end of file +#endif // __AC_SCRIPTDRAWINGSURFACE_H diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp index 6023eb607f9c..0063e7ae87a2 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptdynamicsprite.h" #include "ac/dynamicsprite.h" diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h index 11a53ed68da2..fccb51ba3849 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTDYNAMICSPRITE_H #define __AC_SCRIPTDYNAMICSPRITE_H @@ -29,4 +37,4 @@ struct ScriptDynamicSprite final : AGSCCDynamicObject { ScriptDynamicSprite(); }; -#endif // __AC_SCRIPTDYNAMICSPRITE_H \ No newline at end of file +#endif // __AC_SCRIPTDYNAMICSPRITE_H diff --git a/engines/ags/engine/ac/dynobj/scriptfile.cpp b/engines/ags/engine/ac/dynobj/scriptfile.cpp index d52000c7d516..9341c5d00442 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.cpp +++ b/engines/ags/engine/ac/dynobj/scriptfile.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptfile.h" #include "ac/global_file.h" diff --git a/engines/ags/engine/ac/dynobj/scriptfile.h b/engines/ags/engine/ac/dynobj/scriptfile.h index f039e9768e90..538d79c20623 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.h +++ b/engines/ags/engine/ac/dynobj/scriptfile.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTFILE_H #define __AGS_EE_DYNOBJ__SCRIPTFILE_H diff --git a/engines/ags/engine/ac/dynobj/scriptgui.h b/engines/ags/engine/ac/dynobj/scriptgui.h index c6651a22c50b..6dffd085c3af 100644 --- a/engines/ags/engine/ac/dynobj/scriptgui.h +++ b/engines/ags/engine/ac/dynobj/scriptgui.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTGUI_H #define __AGS_EE_DYNOBJ__SCRIPTGUI_H diff --git a/engines/ags/engine/ac/dynobj/scripthotspot.h b/engines/ags/engine/ac/dynobj/scripthotspot.h index 1af83a772ac5..181b3b2bcaac 100644 --- a/engines/ags/engine/ac/dynobj/scripthotspot.h +++ b/engines/ags/engine/ac/dynobj/scripthotspot.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H #define __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H diff --git a/engines/ags/engine/ac/dynobj/scriptinvitem.h b/engines/ags/engine/ac/dynobj/scriptinvitem.h index a614a5f5bfd6..e55e98dbf97b 100644 --- a/engines/ags/engine/ac/dynobj/scriptinvitem.h +++ b/engines/ags/engine/ac/dynobj/scriptinvitem.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTINVITEM_H #define __AGS_EE_DYNOBJ__SCRIPTINVITEM_H diff --git a/engines/ags/engine/ac/dynobj/scriptmouse.h b/engines/ags/engine/ac/dynobj/scriptmouse.h index d0ee4316eaf2..2eb0697aba79 100644 --- a/engines/ags/engine/ac/dynobj/scriptmouse.h +++ b/engines/ags/engine/ac/dynobj/scriptmouse.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTMOUSE_H #define __AGS_EE_DYNOBJ__SCRIPTMOUSE_H diff --git a/engines/ags/engine/ac/dynobj/scriptobject.h b/engines/ags/engine/ac/dynobj/scriptobject.h index 57a9ee98686c..37545d2c78f7 100644 --- a/engines/ags/engine/ac/dynobj/scriptobject.h +++ b/engines/ags/engine/ac/dynobj/scriptobject.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTOBJECT_H #define __AGS_EE_DYNOBJ__SCRIPTOBJECT_H diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp index d640ab8eb6d3..f165a0bbcc08 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptoverlay.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.h b/engines/ags/engine/ac/dynobj/scriptoverlay.h index 0b027b62bb7d..8b678605f567 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.h +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTOVERLAY_H #define __AC_SCRIPTOVERLAY_H @@ -31,4 +39,4 @@ struct ScriptOverlay final : AGSCCDynamicObject { ScriptOverlay(); }; -#endif // __AC_SCRIPTOVERLAY_H \ No newline at end of file +#endif // __AC_SCRIPTOVERLAY_H diff --git a/engines/ags/engine/ac/dynobj/scriptregion.h b/engines/ags/engine/ac/dynobj/scriptregion.h index 9e2aff4fb392..4bf38a95c72b 100644 --- a/engines/ags/engine/ac/dynobj/scriptregion.h +++ b/engines/ags/engine/ac/dynobj/scriptregion.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTREGION_H #define __AGS_EE_DYNOBJ__SCRIPTREGION_H diff --git a/engines/ags/engine/ac/dynobj/scriptset.cpp b/engines/ags/engine/ac/dynobj/scriptset.cpp index 472671add1aa..a17a48c1ffae 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.cpp +++ b/engines/ags/engine/ac/dynobj/scriptset.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptset.h" int ScriptSetBase::Dispose(const char *address, bool force) diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index 12dc89c914fc..d5ad8a91553f 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Managed script object wrapping std::set and unordered_set. @@ -21,6 +31,7 @@ // types as keys; need to research what perfomance impact that would make. // //============================================================================= + #ifndef __AC_SCRIPTSET_H #define __AC_SCRIPTSET_H diff --git a/engines/ags/engine/ac/dynobj/scriptstring.cpp b/engines/ags/engine/ac/dynobj/scriptstring.cpp index d130d63e5b4f..be95335bd8f8 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.cpp +++ b/engines/ags/engine/ac/dynobj/scriptstring.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptstring.h" #include "ac/string.h" diff --git a/engines/ags/engine/ac/dynobj/scriptstring.h b/engines/ags/engine/ac/dynobj/scriptstring.h index 916d48998d59..041f3b3f3299 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.h +++ b/engines/ags/engine/ac/dynobj/scriptstring.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTSTRING_H #define __AC_SCRIPTSTRING_H @@ -31,4 +39,4 @@ struct ScriptString final : AGSCCDynamicObject, ICCStringClass { ScriptString(const char *fromText); }; -#endif // __AC_SCRIPTSTRING_H \ No newline at end of file +#endif // __AC_SCRIPTSTRING_H diff --git a/engines/ags/engine/ac/dynobj/scriptsystem.h b/engines/ags/engine/ac/dynobj/scriptsystem.h index e7c29b3d7a3b..815d30cb021c 100644 --- a/engines/ags/engine/ac/dynobj/scriptsystem.h +++ b/engines/ags/engine/ac/dynobj/scriptsystem.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H #define __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp index 4b70941a13d8..b3cdb00bcf63 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "scriptuserobject.h" diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h index 931bdaa23c5b..36bfe2890990 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.h +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Managed object, which size and contents are defined by user script // //============================================================================= + #ifndef __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H #define __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp index 803269a46f48..955af85f631e 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptviewframe.h" diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.h b/engines/ags/engine/ac/dynobj/scriptviewframe.h index 1abb47e6d9d8..83ad44b88f06 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.h +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTVIEWFRAME_H #define __AC_SCRIPTVIEWFRAME_H @@ -29,4 +37,4 @@ struct ScriptViewFrame final : AGSCCDynamicObject { ScriptViewFrame(); }; -#endif // __AC_SCRIPTVIEWFRAME_H \ No newline at end of file +#endif // __AC_SCRIPTVIEWFRAME_H diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp index 0bd8a0af4f95..f2563a566299 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptviewport.h" #include "ac/gamestate.h" diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.h b/engines/ags/engine/ac/dynobj/scriptviewport.h index d742dfe12d0f..a9fe88628336 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.h +++ b/engines/ags/engine/ac/dynobj/scriptviewport.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SCRIPTVIEWPORT_H #define __AC_SCRIPTVIEWPORT_H diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp index dc3bf6f6f84e..c2960351c434 100644 --- a/engines/ags/engine/ac/event.cpp +++ b/engines/ags/engine/ac/event.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "event.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h index 6c4b843de53a..78e7b486e9aa 100644 --- a/engines/ags/engine/ac/event.h +++ b/engines/ags/engine/ac/event.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__EVENT_H #define __AGS_EE_AC__EVENT_H diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index ebb1fec45afc..99a18b531d91 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "aldumb.h" #include "ac/asset_helper.h" diff --git a/engines/ags/engine/ac/file.h b/engines/ags/engine/ac/file.h index cc12e7520624..0f0b2aeac815 100644 --- a/engines/ags/engine/ac/file.h +++ b/engines/ags/engine/ac/file.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Script File API implementation. // //============================================================================= + #ifndef __AGS_EE_AC__FILE_H #define __AGS_EE_AC__FILE_H diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index ac3f6dc70a5e..220349f2c0bc 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/game.h" diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h index 9bed7f02c217..c09fc59b24ba 100644 --- a/engines/ags/engine/ac/game.h +++ b/engines/ags/engine/ac/game.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS Runtime header diff --git a/engines/ags/engine/ac/gamesetup.cpp b/engines/ags/engine/ac/gamesetup.cpp index 88a22f4fceee..6dc749f38135 100644 --- a/engines/ags/engine/ac/gamesetup.cpp +++ b/engines/ags/engine/ac/gamesetup.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/wgt2allg.h" // DIGI_AUTODETECT & MIDI_AUTODETECT #include "ac/gamesetup.h" diff --git a/engines/ags/engine/ac/gamesetup.h b/engines/ags/engine/ac/gamesetup.h index 672eb66d9124..54708a26cd6f 100644 --- a/engines/ags/engine/ac/gamesetup.h +++ b/engines/ags/engine/ac/gamesetup.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GAMESETUP_H #define __AC_GAMESETUP_H @@ -83,4 +91,4 @@ struct GameSetup { // Perhaps it makes sense to separate those two group of vars at some point. extern GameSetup usetup; -#endif // __AC_GAMESETUP_H \ No newline at end of file +#endif // __AC_GAMESETUP_H diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index da4ec8079da4..0366ec5e686e 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/draw.h" #include "ac/game_version.h" diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h index b5843c130ce9..413b508b4650 100644 --- a/engines/ags/engine/ac/gamestate.h +++ b/engines/ags/engine/ac/gamestate.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GAMESTATE_H #define __AC_GAMESTATE_H diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp index f7e6d4474d35..ce838680e899 100644 --- a/engines/ags/engine/ac/global_api.cpp +++ b/engines/ags/engine/ac/global_api.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Script API Functions diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp index cf232e91f553..85899b47c311 100644 --- a/engines/ags/engine/ac/global_audio.cpp +++ b/engines/ags/engine/ac/global_audio.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/game.h" diff --git a/engines/ags/engine/ac/global_audio.h b/engines/ags/engine/ac/global_audio.h index 9c9b55767801..9bf1c5b95b6b 100644 --- a/engines/ags/engine/ac/global_audio.h +++ b/engines/ags/engine/ac/global_audio.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALAUDIO_H #define __AGS_EE_AC__GLOBALAUDIO_H diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp index f2d66f585a2c..e122ad6201ee 100644 --- a/engines/ags/engine/ac/global_button.cpp +++ b/engines/ags/engine/ac/global_button.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_button.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_button.h b/engines/ags/engine/ac/global_button.h index cb98cb53e29b..d4f2561e91c9 100644 --- a/engines/ags/engine/ac/global_button.h +++ b/engines/ags/engine/ac/global_button.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALBUTTON_H #define __AGS_EE_AC__GLOBALBUTTON_H diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp index 39f018ce68b1..6788617f2bd0 100644 --- a/engines/ags/engine/ac/global_character.cpp +++ b/engines/ags/engine/ac/global_character.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS Character functions diff --git a/engines/ags/engine/ac/global_character.h b/engines/ags/engine/ac/global_character.h index ad066c3ad212..48483a03a3c0 100644 --- a/engines/ags/engine/ac/global_character.h +++ b/engines/ags/engine/ac/global_character.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALCHARACTER_H #define __AGS_EE_AC__GLOBALCHARACTER_H diff --git a/engines/ags/engine/ac/global_datetime.cpp b/engines/ags/engine/ac/global_datetime.cpp index e89311efc00b..700005ceb23c 100644 --- a/engines/ags/engine/ac/global_datetime.cpp +++ b/engines/ags/engine/ac/global_datetime.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/global_datetime.h" diff --git a/engines/ags/engine/ac/global_datetime.h b/engines/ags/engine/ac/global_datetime.h index 59080d1a7a48..caf287111c18 100644 --- a/engines/ags/engine/ac/global_datetime.h +++ b/engines/ags/engine/ac/global_datetime.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALDATETIME_H #define __AGS_EE_AC__GLOBALDATETIME_H diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp index 582e1d200947..41f9ac5d231e 100644 --- a/engines/ags/engine/ac/global_debug.cpp +++ b/engines/ags/engine/ac/global_debug.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_debug.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_debug.h b/engines/ags/engine/ac/global_debug.h index a4d50d0d4fd5..bdaabba917d5 100644 --- a/engines/ags/engine/ac/global_debug.h +++ b/engines/ags/engine/ac/global_debug.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALDEBUG_H #define __AGS_EE_AC__GLOBALDEBUG_H diff --git a/engines/ags/engine/ac/global_dialog.cpp b/engines/ags/engine/ac/global_dialog.cpp index dbab9333a729..5115355e9db5 100644 --- a/engines/ags/engine/ac/global_dialog.cpp +++ b/engines/ags/engine/ac/global_dialog.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_dialog.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_dialog.h b/engines/ags/engine/ac/global_dialog.h index feb16ae10f50..7dc7e0e72476 100644 --- a/engines/ags/engine/ac/global_dialog.h +++ b/engines/ags/engine/ac/global_dialog.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALDIALOG_H #define __AGS_EE_AC__GLOBALDIALOG_H diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp index dfcd76bcc40e..06398c1ef8c0 100644 --- a/engines/ags/engine/ac/global_display.cpp +++ b/engines/ags/engine/ac/global_display.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/ac/global_display.h b/engines/ags/engine/ac/global_display.h index 538d293924a1..226e5fa9869a 100644 --- a/engines/ags/engine/ac/global_display.h +++ b/engines/ags/engine/ac/global_display.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALDISPLAY_H #define __AGS_EE_AC__GLOBALDISPLAY_H diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp index 4003c78f654e..2c5dea5b3d03 100644 --- a/engines/ags/engine/ac/global_drawingsurface.cpp +++ b/engines/ags/engine/ac/global_drawingsurface.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/display.h" diff --git a/engines/ags/engine/ac/global_drawingsurface.h b/engines/ags/engine/ac/global_drawingsurface.h index d62ea61909e7..c755113faac8 100644 --- a/engines/ags/engine/ac/global_drawingsurface.h +++ b/engines/ags/engine/ac/global_drawingsurface.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALDRAWINGSURFACE_H #define __AGS_EE_AC__GLOBALDRAWINGSURFACE_H diff --git a/engines/ags/engine/ac/global_dynamicsprite.cpp b/engines/ags/engine/ac/global_dynamicsprite.cpp index b77a3f3c7ac4..00898e7cfc13 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.cpp +++ b/engines/ags/engine/ac/global_dynamicsprite.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_dynamicsprite.h" #include "util/wgt2allg.h" // Allegro RGB, PALETTE diff --git a/engines/ags/engine/ac/global_dynamicsprite.h b/engines/ags/engine/ac/global_dynamicsprite.h index a6f3ea8cca68..82b264c1678c 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.h +++ b/engines/ags/engine/ac/global_dynamicsprite.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALDYNAMICSPRITE_H #define __AGS_EE_AC__GLOBALDYNAMICSPRITE_H diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index d88a295cbbde..d2fb8775b4b7 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/global_file.h" diff --git a/engines/ags/engine/ac/global_file.h b/engines/ags/engine/ac/global_file.h index 1e827088eed8..be67d1288c21 100644 --- a/engines/ags/engine/ac/global_file.h +++ b/engines/ags/engine/ac/global_file.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALFILE_H #define __AGS_EE_AC__GLOBALFILE_H diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 40e263122c0c..1939308192c4 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h index 25e471a73342..93c309bfc9b1 100644 --- a/engines/ags/engine/ac/global_game.h +++ b/engines/ags/engine/ac/global_game.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALGAME_H #define __AGS_EE_AC__GLOBALGAME_H diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp index 3c8e6250ac31..ba3134ab590e 100644 --- a/engines/ags/engine/ac/global_gui.cpp +++ b/engines/ags/engine/ac/global_gui.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/display.h" diff --git a/engines/ags/engine/ac/global_gui.h b/engines/ags/engine/ac/global_gui.h index 2047fecc4b4a..ef18f75eabeb 100644 --- a/engines/ags/engine/ac/global_gui.h +++ b/engines/ags/engine/ac/global_gui.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALGUI_H #define __AGS_EE_AC__GLOBALGUI_H diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp index cab508f5628e..55da38845490 100644 --- a/engines/ags/engine/ac/global_hotspot.cpp +++ b/engines/ags/engine/ac/global_hotspot.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_hotspot.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_hotspot.h b/engines/ags/engine/ac/global_hotspot.h index ec595042eadd..b19c05f587c8 100644 --- a/engines/ags/engine/ac/global_hotspot.h +++ b/engines/ags/engine/ac/global_hotspot.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALHOTSPOT_H #define __AGS_EE_AC__GLOBALHOTSPOT_H diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp index 4180cc283c42..680b6afd4704 100644 --- a/engines/ags/engine/ac/global_inventoryitem.cpp +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/gamesetupstruct.h" diff --git a/engines/ags/engine/ac/global_inventoryitem.h b/engines/ags/engine/ac/global_inventoryitem.h index 840bb73e0ea8..af2590db7796 100644 --- a/engines/ags/engine/ac/global_inventoryitem.h +++ b/engines/ags/engine/ac/global_inventoryitem.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALINVENTORYITEM_H #define __AGS_EE_AC__GLOBALINVENTORYITEM_H diff --git a/engines/ags/engine/ac/global_invwindow.cpp b/engines/ags/engine/ac/global_invwindow.cpp index edd4ed926b4c..d09043e99adf 100644 --- a/engines/ags/engine/ac/global_invwindow.cpp +++ b/engines/ags/engine/ac/global_invwindow.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/gamestate.h" #include "ac/global_invwindow.h" diff --git a/engines/ags/engine/ac/global_invwindow.h b/engines/ags/engine/ac/global_invwindow.h index afa1d25c5cb4..02a51d9f4b79 100644 --- a/engines/ags/engine/ac/global_invwindow.h +++ b/engines/ags/engine/ac/global_invwindow.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALINVWINDOW_H #define __AGS_EE_AC__GLOBALINVWINDOW_H diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp index 7a0335e93747..a7e4cad662a0 100644 --- a/engines/ags/engine/ac/global_label.cpp +++ b/engines/ags/engine/ac/global_label.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_label.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_label.h b/engines/ags/engine/ac/global_label.h index fa96942f759b..c3f0cb49f0a8 100644 --- a/engines/ags/engine/ac/global_label.h +++ b/engines/ags/engine/ac/global_label.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALLABEL_H #define __AGS_EE_AC__GLOBALLABEL_H diff --git a/engines/ags/engine/ac/global_listbox.cpp b/engines/ags/engine/ac/global_listbox.cpp index 546eac2e0088..f5d93df57fae 100644 --- a/engines/ags/engine/ac/global_listbox.cpp +++ b/engines/ags/engine/ac/global_listbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_listbox.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_listbox.h b/engines/ags/engine/ac/global_listbox.h index d6be2f449fd8..f49cc5bd7c39 100644 --- a/engines/ags/engine/ac/global_listbox.h +++ b/engines/ags/engine/ac/global_listbox.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALLISTBOX_H #define __AGS_EE_AC__GLOBALLISTBOX_H diff --git a/engines/ags/engine/ac/global_mouse.cpp b/engines/ags/engine/ac/global_mouse.cpp index 206f50297737..a17871e8289f 100644 --- a/engines/ags/engine/ac/global_mouse.cpp +++ b/engines/ags/engine/ac/global_mouse.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_mouse.h" #include "ac/gamestate.h" diff --git a/engines/ags/engine/ac/global_mouse.h b/engines/ags/engine/ac/global_mouse.h index dbff7fa38637..5a0345518d80 100644 --- a/engines/ags/engine/ac/global_mouse.h +++ b/engines/ags/engine/ac/global_mouse.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALMOUSE_H #define __AGS_EE_AC__GLOBALMOUSE_H diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp index aa43d906b707..1132b8184a23 100644 --- a/engines/ags/engine/ac/global_object.cpp +++ b/engines/ags/engine/ac/global_object.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_object.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_object.h b/engines/ags/engine/ac/global_object.h index ac4a8776572b..4eed9fd27c4a 100644 --- a/engines/ags/engine/ac/global_object.h +++ b/engines/ags/engine/ac/global_object.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALOBJECT_H #define __AGS_EE_AC__GLOBALOBJECT_H diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp index d9525810342f..99f67a9fc543 100644 --- a/engines/ags/engine/ac/global_overlay.cpp +++ b/engines/ags/engine/ac/global_overlay.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_overlay.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_overlay.h b/engines/ags/engine/ac/global_overlay.h index 0282bdc86858..4e43a54b5199 100644 --- a/engines/ags/engine/ac/global_overlay.h +++ b/engines/ags/engine/ac/global_overlay.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALOVERLAY_H #define __AGS_EE_AC__GLOBALOVERLAY_H diff --git a/engines/ags/engine/ac/global_palette.cpp b/engines/ags/engine/ac/global_palette.cpp index 89048897657d..0fb925f0506a 100644 --- a/engines/ags/engine/ac/global_palette.cpp +++ b/engines/ags/engine/ac/global_palette.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/draw.h" diff --git a/engines/ags/engine/ac/global_palette.h b/engines/ags/engine/ac/global_palette.h index 95b03d449d90..9a131d52ce1d 100644 --- a/engines/ags/engine/ac/global_palette.h +++ b/engines/ags/engine/ac/global_palette.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALPALETTE_H #define __AGS_EE_AC__GLOBALPALETTE_H diff --git a/engines/ags/engine/ac/global_parser.cpp b/engines/ags/engine/ac/global_parser.cpp index eae49baf92ff..a51a151e20df 100644 --- a/engines/ags/engine/ac/global_parser.cpp +++ b/engines/ags/engine/ac/global_parser.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 //strcpy() #include "ac/global_parser.h" diff --git a/engines/ags/engine/ac/global_parser.h b/engines/ags/engine/ac/global_parser.h index 07ceebd3a6d4..427723dff6a3 100644 --- a/engines/ags/engine/ac/global_parser.h +++ b/engines/ags/engine/ac/global_parser.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALPARSER_H #define __AGS_EE_AC__GLOBALPARSER_H diff --git a/engines/ags/engine/ac/global_plugin.h b/engines/ags/engine/ac/global_plugin.h index e3e1a9c2818c..9fdae6e20e55 100644 --- a/engines/ags/engine/ac/global_plugin.h +++ b/engines/ags/engine/ac/global_plugin.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_PLUGIN__PLUGINFUNC_H #define __AGS_EE_PLUGIN__PLUGINFUNC_H diff --git a/engines/ags/engine/ac/global_record.cpp b/engines/ags/engine/ac/global_record.cpp index afada9a47ec8..5b799f5290c0 100644 --- a/engines/ags/engine/ac/global_record.cpp +++ b/engines/ags/engine/ac/global_record.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_record.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_record.h b/engines/ags/engine/ac/global_record.h index 51c4972f56c4..adc9f60946ae 100644 --- a/engines/ags/engine/ac/global_record.h +++ b/engines/ags/engine/ac/global_record.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALRECORD_H #define __AGS_EE_AC__GLOBALRECORD_H diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp index 6c1442131267..1ee83973fe8e 100644 --- a/engines/ags/engine/ac/global_region.cpp +++ b/engines/ags/engine/ac/global_region.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_region.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_region.h b/engines/ags/engine/ac/global_region.h index 40c65e0eeb75..5dbfdd382f3f 100644 --- a/engines/ags/engine/ac/global_region.h +++ b/engines/ags/engine/ac/global_region.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALREGION_H #define __AGS_EE_AC__GLOBALREGION_H diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp index daccbd40bb19..e3f35b833a74 100644 --- a/engines/ags/engine/ac/global_room.cpp +++ b/engines/ags/engine/ac/global_room.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_room.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_room.h b/engines/ags/engine/ac/global_room.h index 4028423a17b3..f19a849f67d5 100644 --- a/engines/ags/engine/ac/global_room.h +++ b/engines/ags/engine/ac/global_room.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALROOM_H #define __AGS_EE_AC__GLOBALROOM_H diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp index 2a77a129146a..7b6846ee7e19 100644 --- a/engines/ags/engine/ac/global_screen.cpp +++ b/engines/ags/engine/ac/global_screen.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/gamesetup.h" diff --git a/engines/ags/engine/ac/global_screen.h b/engines/ags/engine/ac/global_screen.h index 7158285d8a3d..a412ae37d9aa 100644 --- a/engines/ags/engine/ac/global_screen.h +++ b/engines/ags/engine/ac/global_screen.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALSCREEN_H #define __AGS_EE_AC__GLOBALSCREEN_H diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp index 613f2a1283aa..d8847ec22b3a 100644 --- a/engines/ags/engine/ac/global_slider.cpp +++ b/engines/ags/engine/ac/global_slider.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_slider.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_slider.h b/engines/ags/engine/ac/global_slider.h index 27e0edf9b34a..bf6b59f336bd 100644 --- a/engines/ags/engine/ac/global_slider.h +++ b/engines/ags/engine/ac/global_slider.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALSLIDER_H #define __AGS_EE_AC__GLOBALSLIDER_H diff --git a/engines/ags/engine/ac/global_string.cpp b/engines/ags/engine/ac/global_string.cpp index 7851ae91d21c..598e9ec767a5 100644 --- a/engines/ags/engine/ac/global_string.cpp +++ b/engines/ags/engine/ac/global_string.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_string.h b/engines/ags/engine/ac/global_string.h index 919666619161..6369fae8fa0a 100644 --- a/engines/ags/engine/ac/global_string.h +++ b/engines/ags/engine/ac/global_string.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALSTRING_H #define __AGS_EE_AC__GLOBALSTRING_H diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp index 672c0807e2a0..ddd6f1fe1295 100644 --- a/engines/ags/engine/ac/global_textbox.cpp +++ b/engines/ags/engine/ac/global_textbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_textbox.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_textbox.h b/engines/ags/engine/ac/global_textbox.h index 1962f4f30c22..f5e6f9cf853e 100644 --- a/engines/ags/engine/ac/global_textbox.h +++ b/engines/ags/engine/ac/global_textbox.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALTEXTBOX_H #define __AGS_EE_AC__GLOBALTEXTBOX_H diff --git a/engines/ags/engine/ac/global_timer.cpp b/engines/ags/engine/ac/global_timer.cpp index 4f197d889a77..86c080a10ff1 100644 --- a/engines/ags/engine/ac/global_timer.cpp +++ b/engines/ags/engine/ac/global_timer.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_timer.h" #include "ac/runtime_defines.h" diff --git a/engines/ags/engine/ac/global_timer.h b/engines/ags/engine/ac/global_timer.h index 589a97ee8d5f..b244766b822b 100644 --- a/engines/ags/engine/ac/global_timer.h +++ b/engines/ags/engine/ac/global_timer.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALTIMER_H #define __AGS_EE_AC__GLOBALTIMER_H diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index f793e111943f..fb86e11e68e6 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_translation.h b/engines/ags/engine/ac/global_translation.h index b506fd9498a4..0e6d0b1008b1 100644 --- a/engines/ags/engine/ac/global_translation.h +++ b/engines/ags/engine/ac/global_translation.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALTRANSLATION_H #define __AGS_EE_AC__GLOBALTRANSLATION_H diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp index 438fcc833711..89da7e59ff31 100644 --- a/engines/ags/engine/ac/global_video.cpp +++ b/engines/ags/engine/ac/global_video.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/gamesetup.h" @@ -82,4 +90,4 @@ void pause_sound_if_necessary_and_play_video(const char *name, int skip, int fla void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags) {} -#endif \ No newline at end of file +#endif diff --git a/engines/ags/engine/ac/global_video.h b/engines/ags/engine/ac/global_video.h index c3fa993847bd..a297fa215141 100644 --- a/engines/ags/engine/ac/global_video.h +++ b/engines/ags/engine/ac/global_video.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALVIDEO_H #define __AGS_EE_AC__GLOBALVIDEO_H diff --git a/engines/ags/engine/ac/global_viewframe.cpp b/engines/ags/engine/ac/global_viewframe.cpp index 81d55ca1b013..08a4486b0efb 100644 --- a/engines/ags/engine/ac/global_viewframe.cpp +++ b/engines/ags/engine/ac/global_viewframe.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_viewframe.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_viewframe.h b/engines/ags/engine/ac/global_viewframe.h index b92c3400b706..140c09ddbdac 100644 --- a/engines/ags/engine/ac/global_viewframe.h +++ b/engines/ags/engine/ac/global_viewframe.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALVIEWFRAME_H #define __AGS_EE_AC__GLOBALVIEWFRAME_H diff --git a/engines/ags/engine/ac/global_viewport.cpp b/engines/ags/engine/ac/global_viewport.cpp index ea2b1dd8a2ef..88397ecd205e 100644 --- a/engines/ags/engine/ac/global_viewport.cpp +++ b/engines/ags/engine/ac/global_viewport.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_viewport.h" #include "ac/draw.h" diff --git a/engines/ags/engine/ac/global_viewport.h b/engines/ags/engine/ac/global_viewport.h index 5c3903cb5e06..d56d7efc8a24 100644 --- a/engines/ags/engine/ac/global_viewport.h +++ b/engines/ags/engine/ac/global_viewport.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALVIEWPORT_H #define __AGS_EE_AC__GLOBALVIEWPORT_H diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp index 219333f3dddb..584b6a702fb5 100644 --- a/engines/ags/engine/ac/global_walkablearea.cpp +++ b/engines/ags/engine/ac/global_walkablearea.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_walkablearea.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_walkablearea.h b/engines/ags/engine/ac/global_walkablearea.h index 87f6ab811d8f..4e4b7aeb2a37 100644 --- a/engines/ags/engine/ac/global_walkablearea.h +++ b/engines/ags/engine/ac/global_walkablearea.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALWALKABLEAREA_H #define __AGS_EE_AC__GLOBALWALKABLEAREA_H diff --git a/engines/ags/engine/ac/global_walkbehind.cpp b/engines/ags/engine/ac/global_walkbehind.cpp index 4e0181a475a5..3a14fde331a8 100644 --- a/engines/ags/engine/ac/global_walkbehind.cpp +++ b/engines/ags/engine/ac/global_walkbehind.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/global_walkbehind.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/global_walkbehind.h b/engines/ags/engine/ac/global_walkbehind.h index acf56b9472fa..9c3d554cb20f 100644 --- a/engines/ags/engine/ac/global_walkbehind.h +++ b/engines/ags/engine/ac/global_walkbehind.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GLOBALWALKBEHIND_H #define __AGS_EE_AC__GLOBALWALKBEHIND_H diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp index 330674102d1d..deb12cf0ed1e 100644 --- a/engines/ags/engine/ac/gui.cpp +++ b/engines/ags/engine/ac/gui.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/gui.h" diff --git a/engines/ags/engine/ac/gui.h b/engines/ags/engine/ac/gui.h index 6bdcbdc04909..371fc7a9c57b 100644 --- a/engines/ags/engine/ac/gui.h +++ b/engines/ags/engine/ac/gui.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GUI_H #define __AGS_EE_AC__GUI_H diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp index b007330da022..2587cac7ebaa 100644 --- a/engines/ags/engine/ac/guicontrol.cpp +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/guicontrol.h" diff --git a/engines/ags/engine/ac/guicontrol.h b/engines/ags/engine/ac/guicontrol.h index aa9ec3ad4c63..03b11b8dbd3e 100644 --- a/engines/ags/engine/ac/guicontrol.h +++ b/engines/ags/engine/ac/guicontrol.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__GUICONTROL_H #define __AGS_EE_AC__GUICONTROL_H diff --git a/engines/ags/engine/ac/guiinv.cpp b/engines/ags/engine/ac/guiinv.cpp index 411bca2ec058..cb56307b1d80 100644 --- a/engines/ags/engine/ac/guiinv.cpp +++ b/engines/ags/engine/ac/guiinv.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gui/guiinv.h" #include "gui/guimain.h" diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp index bca406d7726d..a013cbffa8c1 100644 --- a/engines/ags/engine/ac/hotspot.cpp +++ b/engines/ags/engine/ac/hotspot.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/cc_hotspot.h" #include "ac/hotspot.h" diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h index d1bb46f8b23b..4e69030e2ed3 100644 --- a/engines/ags/engine/ac/hotspot.h +++ b/engines/ags/engine/ac/hotspot.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__HOTSPOT_H #define __AGS_EE_AC__HOTSPOT_H diff --git a/engines/ags/engine/ac/interfacebutton.cpp b/engines/ags/engine/ac/interfacebutton.cpp index c474bb7ecb73..080f85296a5e 100644 --- a/engines/ags/engine/ac/interfacebutton.cpp +++ b/engines/ags/engine/ac/interfacebutton.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/interfacebutton.h" @@ -18,4 +26,4 @@ void InterfaceButton::set(int xx, int yy, int picc, int overpicc, int actionn) { x = xx; y = yy; pic = picc; overpic = overpicc; leftclick = actionn; pushpic = 0; rightclick = 0; flags = IBFLG_ENABLED; reserved_for_future = 0; -} \ No newline at end of file +} diff --git a/engines/ags/engine/ac/interfaceelement.cpp b/engines/ags/engine/ac/interfaceelement.cpp index 13abc93fdc24..229b9e05d71e 100644 --- a/engines/ags/engine/ac/interfaceelement.cpp +++ b/engines/ags/engine/ac/interfaceelement.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/interfaceelement.h" diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp index 8f28fd6136b8..9eb8ff499d9d 100644 --- a/engines/ags/engine/ac/inventoryitem.cpp +++ b/engines/ags/engine/ac/inventoryitem.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/inventoryitem.h" #include "ac/characterinfo.h" diff --git a/engines/ags/engine/ac/inventoryitem.h b/engines/ags/engine/ac/inventoryitem.h index 833209a65978..76733125f42c 100644 --- a/engines/ags/engine/ac/inventoryitem.h +++ b/engines/ags/engine/ac/inventoryitem.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__INVENTORYITEM_H #define __AGS_EE_AC__INVENTORYITEM_H diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp index faffb294e016..cb124cf406f5 100644 --- a/engines/ags/engine/ac/invwindow.cpp +++ b/engines/ags/engine/ac/invwindow.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/invwindow.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/invwindow.h b/engines/ags/engine/ac/invwindow.h index 7c192b11a1a1..72802c2572ae 100644 --- a/engines/ags/engine/ac/invwindow.h +++ b/engines/ags/engine/ac/invwindow.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__INVWINDOW_H #define __AGS_EE_AC__INVWINDOW_H diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp index ba6b0390a38b..c4442eb5a8e9 100644 --- a/engines/ags/engine/ac/keycode.cpp +++ b/engines/ags/engine/ac/keycode.cpp @@ -1,3 +1,24 @@ +/* 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 "ac/keycode.h" diff --git a/engines/ags/engine/ac/keycode.h b/engines/ags/engine/ac/keycode.h index f2df0ac3b025..6269dafca35d 100644 --- a/engines/ags/engine/ac/keycode.h +++ b/engines/ags/engine/ac/keycode.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__KEYCODE_H #define __AGS_EE_AC__KEYCODE_H diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp index d7d61850bc0c..d16026956c5f 100644 --- a/engines/ags/engine/ac/label.cpp +++ b/engines/ags/engine/ac/label.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/label.h" diff --git a/engines/ags/engine/ac/label.h b/engines/ags/engine/ac/label.h index 684e4268cc32..26464eefcf94 100644 --- a/engines/ags/engine/ac/label.h +++ b/engines/ags/engine/ac/label.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__LABEL_H #define __AGS_EE_AC__LABEL_H diff --git a/engines/ags/engine/ac/lipsync.h b/engines/ags/engine/ac/lipsync.h index 5272f5e11f04..2301ef2d38b0 100644 --- a/engines/ags/engine/ac/lipsync.h +++ b/engines/ags/engine/ac/lipsync.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_LIPSYNC_H #define __AC_LIPSYNC_H @@ -22,4 +30,4 @@ struct SpeechLipSyncLine { short numPhonemes; }; -#endif // __AC_LIPSYNC_H \ No newline at end of file +#endif // __AC_LIPSYNC_H diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index c6fe065c9b12..142b75e2aa19 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/listbox.h" diff --git a/engines/ags/engine/ac/listbox.h b/engines/ags/engine/ac/listbox.h index 24ba70af11a5..eb6c5d06ab90 100644 --- a/engines/ags/engine/ac/listbox.h +++ b/engines/ags/engine/ac/listbox.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__LISTBOX_H #define __AGS_EE_AC__LISTBOX_H diff --git a/engines/ags/engine/ac/math.cpp b/engines/ags/engine/ac/math.cpp index 5c81231643e5..48e27b7edcec 100644 --- a/engines/ags/engine/ac/math.cpp +++ b/engines/ags/engine/ac/math.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/math.h" diff --git a/engines/ags/engine/ac/math.h b/engines/ags/engine/ac/math.h index 872b445c5b47..ce047992deaf 100644 --- a/engines/ags/engine/ac/math.h +++ b/engines/ags/engine/ac/math.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__MATH_H #define __AGS_EE_AC__MATH_H diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp index eceb5e680ce5..1c6e8e1a9725 100644 --- a/engines/ags/engine/ac/mouse.cpp +++ b/engines/ags/engine/ac/mouse.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/mouse.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/mouse.h b/engines/ags/engine/ac/mouse.h index 97e7467f0969..f49e2e9f796a 100644 --- a/engines/ags/engine/ac/mouse.h +++ b/engines/ags/engine/ac/mouse.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__MOUSE_H #define __AGS_EE_AC__MOUSE_H diff --git a/engines/ags/engine/ac/movelist.cpp b/engines/ags/engine/ac/movelist.cpp index 47b9ca2b7f5f..4020726e5463 100644 --- a/engines/ags/engine/ac/movelist.cpp +++ b/engines/ags/engine/ac/movelist.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/movelist.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h index 2f860dc3a814..cff9328138f5 100644 --- a/engines/ags/engine/ac/movelist.h +++ b/engines/ags/engine/ac/movelist.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MOVE_H #define __AC_MOVE_H diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp index b33eaed3df7b..289d06090011 100644 --- a/engines/ags/engine/ac/object.cpp +++ b/engines/ags/engine/ac/object.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/object.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/object.h b/engines/ags/engine/ac/object.h index 0e044fab95ec..5679ec5d9e53 100644 --- a/engines/ags/engine/ac/object.h +++ b/engines/ags/engine/ac/object.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // @@ -17,6 +27,7 @@ // world of programming 'object' is usually a base class; should not we // rename this to RoomObject one day? //============================================================================= + #ifndef __AGS_EE_AC__OBJECT_H #define __AGS_EE_AC__OBJECT_H diff --git a/engines/ags/engine/ac/objectcache.h b/engines/ags/engine/ac/objectcache.h index 78ddcede1867..cff0fcb8f607 100644 --- a/engines/ags/engine/ac/objectcache.h +++ b/engines/ags/engine/ac/objectcache.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__OBJECTCACHE_H #define __AGS_EE_AC__OBJECTCACHE_H diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp index 3904b795b1ad..f74603f0acae 100644 --- a/engines/ags/engine/ac/overlay.cpp +++ b/engines/ags/engine/ac/overlay.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/overlay.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h index 073ae9c46dbf..ed315510e633 100644 --- a/engines/ags/engine/ac/overlay.h +++ b/engines/ags/engine/ac/overlay.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__OVERLAY_H #define __AGS_EE_AC__OVERLAY_H #include diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp index 6225249a3364..1f62782c952c 100644 --- a/engines/ags/engine/ac/parser.cpp +++ b/engines/ags/engine/ac/parser.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 //isalnum() #include diff --git a/engines/ags/engine/ac/parser.h b/engines/ags/engine/ac/parser.h index eddeaebe5c50..e13edaf89ad6 100644 --- a/engines/ags/engine/ac/parser.h +++ b/engines/ags/engine/ac/parser.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__PARSER_H #define __AGS_EE_AC__PARSER_H diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h index 57898ac55eb8..9efb1190d3c6 100644 --- a/engines/ags/engine/ac/path_helper.h +++ b/engines/ags/engine/ac/path_helper.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Functions related to constructing game and script paths. // //============================================================================= + #ifndef __AGS_EE_AC__PATHHELPER_H #define __AGS_EE_AC__PATHHELPER_H diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp index d9da238488fa..5c773c93bcf7 100644 --- a/engines/ags/engine/ac/properties.cpp +++ b/engines/ags/engine/ac/properties.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/gamesetupstruct.h" diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h index f16831ead867..428265777afc 100644 --- a/engines/ags/engine/ac/properties.h +++ b/engines/ags/engine/ac/properties.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__PROPERTIES_H #define __AGS_EE_AC__PROPERTIES_H diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp index 6210ae387838..39fd7f233abb 100644 --- a/engines/ags/engine/ac/region.cpp +++ b/engines/ags/engine/ac/region.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/region.h" #include "ac/common_defines.h" diff --git a/engines/ags/engine/ac/region.h b/engines/ags/engine/ac/region.h index 66ca3b3c1961..f12636f4650c 100644 --- a/engines/ags/engine/ac/region.h +++ b/engines/ags/engine/ac/region.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__REGION_H #define __AGS_EE_AC__REGION_H diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp index a0ed4187d039..dd8313ab1d79 100644 --- a/engines/ags/engine/ac/richgamemedia.cpp +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -1,3 +1,24 @@ +/* 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 "ac/richgamemedia.h" #include "util/stream.h" diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index 0206ea841f22..c0570e89f072 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__RICHGAMEMEDIA_H #define __AGS_EE_AC__RICHGAMEMEDIA_H diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index 016d2cbd004a..f62d72e90ce5 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 // for toupper diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h index c915f8f2cbdb..d091369a7499 100644 --- a/engines/ags/engine/ac/room.h +++ b/engines/ags/engine/ac/room.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__ROOM_H #define __AGS_EE_AC__ROOM_H diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp index ccddc1032c74..41f18b7fd7b2 100644 --- a/engines/ags/engine/ac/roomobject.cpp +++ b/engines/ags/engine/ac/roomobject.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/roomobject.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/roomobject.h b/engines/ags/engine/ac/roomobject.h index ce5dd95134cc..3fb614807327 100644 --- a/engines/ags/engine/ac/roomobject.h +++ b/engines/ags/engine/ac/roomobject.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__ROOMOBJECT_H #define __AGS_EE_AC__ROOMOBJECT_H diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp index baabe5644f0c..1a37d53110f5 100644 --- a/engines/ags/engine/ac/roomstatus.cpp +++ b/engines/ags/engine/ac/roomstatus.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 // memset #include // free diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h index 9e6eb2dde938..6e6dad69bde3 100644 --- a/engines/ags/engine/ac/roomstatus.h +++ b/engines/ags/engine/ac/roomstatus.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__ROOMSTATUS_H #define __AGS_EE_AC__ROOMSTATUS_H diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index 24663a94e474..68ec56d740d9 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/route_finder.h" diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h index fafdd43530cd..60a7748e2708 100644 --- a/engines/ags/engine/ac/route_finder.h +++ b/engines/ags/engine/ac/route_finder.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_ROUTEFND_H #define __AC_ROUTEFND_H @@ -34,4 +42,4 @@ void set_route_move_speed(int speed_x, int speed_y); int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); void calculate_move_stage(MoveList * mlsp, int aaa); -#endif // __AC_ROUTEFND_H \ No newline at end of file +#endif // __AC_ROUTEFND_H diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp index 2e3d71bbee5b..2fcf218f2b93 100644 --- a/engines/ags/engine/ac/route_finder_impl.cpp +++ b/engines/ags/engine/ac/route_finder_impl.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // New jump point search (JPS) A* pathfinder by Martin Sedlak. diff --git a/engines/ags/engine/ac/route_finder_impl.h b/engines/ags/engine/ac/route_finder_impl.h index 81677835b747..9c71d4606a34 100644 --- a/engines/ags/engine/ac/route_finder_impl.h +++ b/engines/ags/engine/ac/route_finder_impl.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_ROUTE_FINDER_IMPL #define __AC_ROUTE_FINDER_IMPL @@ -42,4 +50,4 @@ void calculate_move_stage(MoveList * mlsp, int aaa); } // namespace Engine } // namespace AGS -#endif // __AC_ROUTE_FINDER_IMPL \ No newline at end of file +#endif // __AC_ROUTE_FINDER_IMPL diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp index 085a75b28a19..ab57c49b8f68 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp +++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // PathFinder v2.00 (AC2 customized version) diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h index 490182c2b134..e87ad590664d 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.h +++ b/engines/ags/engine/ac/route_finder_impl_legacy.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_ROUTE_FINDER_IMPL_LEGACY #define __AC_ROUTE_FINDER_IMPL_LEGACY @@ -40,4 +48,4 @@ void calculate_move_stage(MoveList * mlsp, int aaa); } // namespace Engine } // namespace AGS -#endif // __AC_ROUTE_FINDER_IMPL_LEGACY \ No newline at end of file +#endif // __AC_ROUTE_FINDER_IMPL_LEGACY diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h index d868a0f3a9c5..95c43b85a0a4 100644 --- a/engines/ags/engine/ac/runtime_defines.h +++ b/engines/ags/engine/ac/runtime_defines.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_RUNTIMEDEFINES_H #define __AC_RUNTIMEDEFINES_H diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index c28ea7f9a5b5..8ab98f8b8d9e 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/draw.h" diff --git a/engines/ags/engine/ac/screen.h b/engines/ags/engine/ac/screen.h index 4ad3e7de022f..d0898bc73ab3 100644 --- a/engines/ags/engine/ac/screen.h +++ b/engines/ags/engine/ac/screen.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SCREEN_H #define __AGS_EE_AC__SCREEN_H diff --git a/engines/ags/engine/ac/screenoverlay.cpp b/engines/ags/engine/ac/screenoverlay.cpp index 205e3b0867fb..9fd69b2367d1 100644 --- a/engines/ags/engine/ac/screenoverlay.cpp +++ b/engines/ags/engine/ac/screenoverlay.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "screenoverlay.h" #include "util/stream.h" diff --git a/engines/ags/engine/ac/screenoverlay.h b/engines/ags/engine/ac/screenoverlay.h index 6ede440e6c28..18657baf2146 100644 --- a/engines/ags/engine/ac/screenoverlay.h +++ b/engines/ags/engine/ac/screenoverlay.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SCREENOVERLAY_H #define __AGS_EE_AC__SCREENOVERLAY_H diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index b02d53bcc467..c22f8622f239 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Containers script API. // //============================================================================= + #include "ac/common.h" // quit #include "ac/string.h" #include "ac/dynobj/cc_dynamicarray.h" diff --git a/engines/ags/engine/ac/slider.cpp b/engines/ags/engine/ac/slider.cpp index 1f489340fd8d..f1b6b07c4e2b 100644 --- a/engines/ags/engine/ac/slider.cpp +++ b/engines/ags/engine/ac/slider.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/slider.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/slider.h b/engines/ags/engine/ac/slider.h index 402b73656642..e0e87e497f84 100644 --- a/engines/ags/engine/ac/slider.h +++ b/engines/ags/engine/ac/slider.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SLIDER_H #define __AGS_EE_AC__SLIDER_H diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp index dbe24beb3b1d..ebe0db73be24 100644 --- a/engines/ags/engine/ac/speech.cpp +++ b/engines/ags/engine/ac/speech.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/runtime_defines.h" diff --git a/engines/ags/engine/ac/speech.h b/engines/ags/engine/ac/speech.h index 8e0d973af758..11dfe6896104 100644 --- a/engines/ags/engine/ac/speech.h +++ b/engines/ags/engine/ac/speech.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SPEECH_H #define __AGS_EE_AC__SPEECH_H diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp index a14bfc577bea..f5b10160041c 100644 --- a/engines/ags/engine/ac/sprite.cpp +++ b/engines/ags/engine/ac/sprite.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/draw.h" diff --git a/engines/ags/engine/ac/sprite.h b/engines/ags/engine/ac/sprite.h index 761e5af7bf3b..e2ba8cdc90a6 100644 --- a/engines/ags/engine/ac/sprite.h +++ b/engines/ags/engine/ac/sprite.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SPRITE_H #define __AGS_EE_AC__SPRITE_H diff --git a/engines/ags/engine/ac/spritecache_engine.cpp b/engines/ags/engine/ac/spritecache_engine.cpp index adb3b03f8d3f..df0a8dec6e4a 100644 --- a/engines/ags/engine/ac/spritecache_engine.cpp +++ b/engines/ags/engine/ac/spritecache_engine.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Implementation from sprcache.cpp specific to Engine runtime diff --git a/engines/ags/engine/ac/spritelistentry.h b/engines/ags/engine/ac/spritelistentry.h index f9b191f2e62d..aa0be21f2e6b 100644 --- a/engines/ags/engine/ac/spritelistentry.h +++ b/engines/ags/engine/ac/spritelistentry.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SPRITELISTENTRY_H #define __AGS_EE_AC__SPRITELISTENTRY_H diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp index a06b3f6f1c7e..376dd0e4cea4 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.cpp +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -1,3 +1,24 @@ +/* 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 #include "ac/statobj/agsstaticobject.h" diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.h b/engines/ags/engine/ac/statobj/agsstaticobject.h index 3a1bf4ae2343..efccc6c2c0d4 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.h +++ b/engines/ags/engine/ac/statobj/agsstaticobject.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_STATOBJ__AGSSTATICOBJECT_H #define __AGS_EE_STATOBJ__AGSSTATICOBJECT_H diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp index 004ff29f9147..774e3bc47185 100644 --- a/engines/ags/engine/ac/statobj/staticarray.cpp +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -1,3 +1,24 @@ +/* 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 #include "ac/statobj/staticarray.h" diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h index 4c25d3657dd9..a4cf70e7115f 100644 --- a/engines/ags/engine/ac/statobj/staticarray.h +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_STATOBJ__STATICARRAY_H #define __AGS_EE_STATOBJ__STATICARRAY_H diff --git a/engines/ags/engine/ac/statobj/staticobject.h b/engines/ags/engine/ac/statobj/staticobject.h index 6c45a4172621..e9fdabde4f66 100644 --- a/engines/ags/engine/ac/statobj/staticobject.h +++ b/engines/ags/engine/ac/statobj/staticobject.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // A stub class for "managing" static global objects exported to script. @@ -17,6 +27,7 @@ // replaced by the use of dynamic objects in the future. // //============================================================================= + #ifndef __AGS_EE_STATOBJ__STATICOBJECT_H #define __AGS_EE_STATOBJ__STATICOBJECT_H diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index 0c1068ffea29..117e619ce379 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/string.h" diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h index 0ae6114d2f6a..a045e937774f 100644 --- a/engines/ags/engine/ac/string.h +++ b/engines/ags/engine/ac/string.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__STRING_H #define __AGS_EE_AC__STRING_H diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index ddbe0d5105e8..4293d6163b33 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h index bc7dfee9d05c..001ef11bed63 100644 --- a/engines/ags/engine/ac/sys_events.h +++ b/engines/ags/engine/ac/sys_events.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SYS_EVENTS_H #define __AGS_EE_AC__SYS_EVENTS_H diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index c03004c5b775..eb91e8c62998 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/draw.h" diff --git a/engines/ags/engine/ac/system.h b/engines/ags/engine/ac/system.h index b1f42e884c48..ff096eb4872a 100644 --- a/engines/ags/engine/ac/system.h +++ b/engines/ags/engine/ac/system.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__SYSTEMAUDIO_H #define __AGS_EE_AC__SYSTEMAUDIO_H diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp index f821b6113c4b..100d936c73b0 100644 --- a/engines/ags/engine/ac/textbox.cpp +++ b/engines/ags/engine/ac/textbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/textbox.h" diff --git a/engines/ags/engine/ac/textbox.h b/engines/ags/engine/ac/textbox.h index fce247c9e6ea..844f87b7d6ac 100644 --- a/engines/ags/engine/ac/textbox.h +++ b/engines/ags/engine/ac/textbox.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__TEXTBOX_H #define __AGS_EE_AC__TEXTBOX_H diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index 5b4b01237c19..8dc1915437cb 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/timer.h" diff --git a/engines/ags/engine/ac/timer.h b/engines/ags/engine/ac/timer.h index 5ad275f7e4ab..44460d051b70 100644 --- a/engines/ags/engine/ac/timer.h +++ b/engines/ags/engine/ac/timer.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__TIMER_H #define __AGS_EE_AC__TIMER_H diff --git a/engines/ags/engine/ac/topbarsettings.h b/engines/ags/engine/ac/topbarsettings.h index 2060848b4ca7..cf815fb7cd02 100644 --- a/engines/ags/engine/ac/topbarsettings.h +++ b/engines/ags/engine/ac/topbarsettings.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__TOPBARSETTINGS_H #define __AGS_EE_AC__TOPBARSETTINGS_H diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp index 2375c8cd4034..f7d49331842c 100644 --- a/engines/ags/engine/ac/translation.cpp +++ b/engines/ags/engine/ac/translation.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/asset_helper.h" diff --git a/engines/ags/engine/ac/translation.h b/engines/ags/engine/ac/translation.h index 5494d89593db..2f65f56df899 100644 --- a/engines/ags/engine/ac/translation.h +++ b/engines/ags/engine/ac/translation.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__TRANSLATION_H #define __AGS_EE_AC__TRANSLATION_H diff --git a/engines/ags/engine/ac/tree_map.cpp b/engines/ags/engine/ac/tree_map.cpp index 7cf92bea51d3..b4be592cc831 100644 --- a/engines/ags/engine/ac/tree_map.cpp +++ b/engines/ags/engine/ac/tree_map.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/ac/tree_map.h b/engines/ags/engine/ac/tree_map.h index c2fd0417c1d5..7e907fb06fab 100644 --- a/engines/ags/engine/ac/tree_map.h +++ b/engines/ags/engine/ac/tree_map.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__TREEMAP_H #define __AGS_EE_AC__TREEMAP_H diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp index baaa1ecb3d02..2c65e247b74a 100644 --- a/engines/ags/engine/ac/viewframe.cpp +++ b/engines/ags/engine/ac/viewframe.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/gamesetupstruct.h" #include "ac/viewframe.h" diff --git a/engines/ags/engine/ac/viewframe.h b/engines/ags/engine/ac/viewframe.h index 353bfc74bbb3..d195b4fcdcdb 100644 --- a/engines/ags/engine/ac/viewframe.h +++ b/engines/ags/engine/ac/viewframe.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__VIEWFRAME_H #define __AGS_EE_AC__VIEWFRAME_H diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp index c819873ea5be..e144ed440c29 100644 --- a/engines/ags/engine/ac/viewport_script.cpp +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Viewport and Camera script API. diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp index c6631789920d..1666b21b162d 100644 --- a/engines/ags/engine/ac/walkablearea.cpp +++ b/engines/ags/engine/ac/walkablearea.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "ac/object.h" diff --git a/engines/ags/engine/ac/walkablearea.h b/engines/ags/engine/ac/walkablearea.h index 391d93a920f0..8d024b948f11 100644 --- a/engines/ags/engine/ac/walkablearea.h +++ b/engines/ags/engine/ac/walkablearea.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__WALKABLEAREA_H #define __AGS_EE_AC__WALKABLEAREA_H diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp index f254800f4be6..5a067a586b7b 100644 --- a/engines/ags/engine/ac/walkbehind.cpp +++ b/engines/ags/engine/ac/walkbehind.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/walkbehind.h" #include "ac/common.h" diff --git a/engines/ags/engine/ac/walkbehind.h b/engines/ags/engine/ac/walkbehind.h index 01d1565a27b9..458081f76b37 100644 --- a/engines/ags/engine/ac/walkbehind.h +++ b/engines/ags/engine/ac/walkbehind.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_AC__WALKBEHIND_H #define __AGS_EE_AC__WALKBEHIND_H diff --git a/engines/ags/engine/debugging/agseditordebugger.h b/engines/ags/engine/debugging/agseditordebugger.h index f53b4d4fc3e8..b94fd496f7b7 100644 --- a/engines/ags/engine/debugging/agseditordebugger.h +++ b/engines/ags/engine/debugging/agseditordebugger.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H #define __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H diff --git a/engines/ags/engine/debugging/consoleoutputtarget.cpp b/engines/ags/engine/debugging/consoleoutputtarget.cpp index 2442e9533659..9f53eb120843 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.cpp +++ b/engines/ags/engine/debugging/consoleoutputtarget.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "consoleoutputtarget.h" diff --git a/engines/ags/engine/debugging/consoleoutputtarget.h b/engines/ags/engine/debugging/consoleoutputtarget.h index 13ae01a394a3..c3913772d24d 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.h +++ b/engines/ags/engine/debugging/consoleoutputtarget.h @@ -1,21 +1,32 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // ConsoleOutputTarget prints messages onto in-game console GUI (available // only if the game was compiled in debug mode). // //============================================================================= + #ifndef __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H #define __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index 4c0807cd1f79..4c3a99fe85b8 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/debugging/debug_log.h b/engines/ags/engine/debugging/debug_log.h index 268b846aecb1..afd62a973a0b 100644 --- a/engines/ags/engine/debugging/debug_log.h +++ b/engines/ags/engine/debugging/debug_log.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_DEBUG_LOG_H #define __AC_DEBUG_LOG_H diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h index 77c85d6a9aef..9d57120cc775 100644 --- a/engines/ags/engine/debugging/debugger.h +++ b/engines/ags/engine/debugging/debugger.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_DEBUGGER_H #define __AC_DEBUGGER_H diff --git a/engines/ags/engine/debugging/dummyagsdebugger.h b/engines/ags/engine/debugging/dummyagsdebugger.h index 38c026348117..448b3b21a47c 100644 --- a/engines/ags/engine/debugging/dummyagsdebugger.h +++ b/engines/ags/engine/debugging/dummyagsdebugger.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_DUMMYAGSDEBUGGER_H #define __AC_DUMMYAGSDEBUGGER_H diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.cpp b/engines/ags/engine/debugging/filebasedagsdebugger.cpp index 263798725e0d..d00edf7711ae 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.cpp +++ b/engines/ags/engine/debugging/filebasedagsdebugger.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "debug/filebasedagsdebugger.h" diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.h b/engines/ags/engine/debugging/filebasedagsdebugger.h index 3fcda091b541..25e7a177a1a4 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.h +++ b/engines/ags/engine/debugging/filebasedagsdebugger.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_FILEBASEDAGSDEBUGGER_H #define __AC_FILEBASEDAGSDEBUGGER_H diff --git a/engines/ags/engine/debugging/logfile.cpp b/engines/ags/engine/debugging/logfile.cpp index 4dad1cc4fda7..dae1d4478cba 100644 --- a/engines/ags/engine/debugging/logfile.cpp +++ b/engines/ags/engine/debugging/logfile.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "debug/logfile.h" diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h index 702842891fdc..976121656374 100644 --- a/engines/ags/engine/debugging/logfile.h +++ b/engines/ags/engine/debugging/logfile.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // LogFile, the IOutputHandler implementation that writes to file. @@ -21,6 +31,7 @@ // during reading configuration and/or parsing command line). // //============================================================================= + #ifndef __AGS_EE_DEBUG__LOGFILE_H #define __AGS_EE_DEBUG__LOGFILE_H diff --git a/engines/ags/engine/debugging/messagebuffer.cpp b/engines/ags/engine/debugging/messagebuffer.cpp index dc336e7a60b8..0ef84d5806b3 100644 --- a/engines/ags/engine/debugging/messagebuffer.cpp +++ b/engines/ags/engine/debugging/messagebuffer.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "debug/debugmanager.h" #include "debug/messagebuffer.h" diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h index b8a31a2cb826..effde36a4cde 100644 --- a/engines/ags/engine/debugging/messagebuffer.h +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // MessageBuffer, the IOutputHandler implementation that stores debug messages @@ -17,6 +27,7 @@ // while specifying how to actually print it. // //============================================================================= + #ifndef __AGS_EE_DEBUG__MESSAGEBUFFER_H #define __AGS_EE_DEBUG__MESSAGEBUFFER_H diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index b939916fe99b..1a7d1f32f403 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // MOUSELIBW32.CPP diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h index 165dfd80db27..66c5565ef74f 100644 --- a/engines/ags/engine/device/mousew32.h +++ b/engines/ags/engine/device/mousew32.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // MOUSELIBW32.CPP diff --git a/engines/ags/engine/font/fonts_engine.cpp b/engines/ags/engine/font/fonts_engine.cpp index ebb17c04497b..813c4eb073ef 100644 --- a/engines/ags/engine/font/fonts_engine.cpp +++ b/engines/ags/engine/font/fonts_engine.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Implementation from acfonts.cpp specific to Engine runtime diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp index 4aabcacbcb6e..fec45ef7a58d 100644 --- a/engines/ags/engine/game/game_init.cpp +++ b/engines/ags/engine/game/game_init.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/character.h" #include "ac/charactercache.h" diff --git a/engines/ags/engine/game/game_init.h b/engines/ags/engine/game/game_init.h index 64f3fcad4956..2ad5752ce827 100644 --- a/engines/ags/engine/game/game_init.h +++ b/engines/ags/engine/game/game_init.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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 unit provides game initialization routine, which takes place after diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index 006ef030f87b..5cfd5407ba97 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/character.h" #include "ac/common.h" diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h index 2feacc41a6f3..d6b4cd49f15c 100644 --- a/engines/ags/engine/game/savegame.h +++ b/engines/ags/engine/game/savegame.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_GAME__SAVEGAME_H #define __AGS_EE_GAME__SAVEGAME_H diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index d309ed0ed6ef..c95a3e108ec4 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h index 7f44872bdd89..95b8555b1a69 100644 --- a/engines/ags/engine/game/savegame_components.h +++ b/engines/ags/engine/game/savegame_components.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_GAME__SAVEGAMECOMPONENTS_H #define __AGS_EE_GAME__SAVEGAMECOMPONENTS_H diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index 8a0d08b45fe3..8633fc53f3d8 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_GAME__SAVEGAMEINTERNAL_H #define __AGS_EE_GAME__SAVEGAMEINTERNAL_H diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp index eea1d980f167..33ef5e6af432 100644 --- a/engines/ags/engine/game/viewport.cpp +++ b/engines/ags/engine/game/viewport.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/draw.h" #include "ac/gamestate.h" #include "debug/debug_log.h" diff --git a/engines/ags/engine/game/viewport.h b/engines/ags/engine/game/viewport.h index 4fcc6abc7384..6f4604d228ef 100644 --- a/engines/ags/engine/game/viewport.h +++ b/engines/ags/engine/game/viewport.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Definition for the game viewports and cameras. // //============================================================================= + #ifndef __AGS_EE_AC__VIEWPORT_H #define __AGS_EE_AC__VIEWPORT_H diff --git a/engines/ags/engine/gfx/ali3dexception.h b/engines/ags/engine/gfx/ali3dexception.h index 8c9580330dab..f27d24194b55 100644 --- a/engines/ags/engine/gfx/ali3dexception.h +++ b/engines/ags/engine/gfx/ali3dexception.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Graphics driver exception class diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index cab864e668d9..69e36007c086 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h index 019073df14c5..d3d6268fa4e6 100644 --- a/engines/ags/engine/gfx/ali3dogl.h +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // OpenGL graphics factory diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index ddc09b3342ba..252d7e9c9bf6 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Allegro Interface for 3D; Software mode Allegro driver diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index 8cb4f0fb9e05..4d8327d75aa4 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Software graphics factory, based on Allegro diff --git a/engines/ags/engine/gfx/blender.cpp b/engines/ags/engine/gfx/blender.cpp index 18a48cf6c10c..a647a9da8a15 100644 --- a/engines/ags/engine/gfx/blender.cpp +++ b/engines/ags/engine/gfx/blender.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/types.h" #include "gfx/blender.h" diff --git a/engines/ags/engine/gfx/blender.h b/engines/ags/engine/gfx/blender.h index fcefa935eb7a..084d937d2bf1 100644 --- a/engines/ags/engine/gfx/blender.h +++ b/engines/ags/engine/gfx/blender.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS specific color blending routines for transparency and tinting effects diff --git a/engines/ags/engine/gfx/color_engine.cpp b/engines/ags/engine/gfx/color_engine.cpp index 4946b2b4bf53..a204add5957d 100644 --- a/engines/ags/engine/gfx/color_engine.cpp +++ b/engines/ags/engine/gfx/color_engine.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Implementation from wgt2allg.cpp specific to Engine runtime diff --git a/engines/ags/engine/gfx/ddb.h b/engines/ags/engine/gfx/ddb.h index 553b36f17d04..442fa3d2180a 100644 --- a/engines/ags/engine/gfx/ddb.h +++ b/engines/ags/engine/gfx/ddb.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Driver-dependant bitmap interface // //============================================================================= + #ifndef __AGS_EE_GFX__DDB_H #define __AGS_EE_GFX__DDB_H diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp index 04b76d0b803a..ec87092750a7 100644 --- a/engines/ags/engine/gfx/gfx_util.cpp +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" #include "gfx/gfx_util.h" diff --git a/engines/ags/engine/gfx/gfx_util.h b/engines/ags/engine/gfx/gfx_util.h index 924e3cc755d6..a459a1b4e05c 100644 --- a/engines/ags/engine/gfx/gfx_util.h +++ b/engines/ags/engine/gfx/gfx_util.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Intermediate level drawing utility functions. @@ -21,6 +31,7 @@ // any knowledge of higher-level engine types and objects. // //============================================================================= + #ifndef __AGS_EE_GFX__GFXUTIL_H #define __AGS_EE_GFX__GFXUTIL_H diff --git a/engines/ags/engine/gfx/gfxdefines.h b/engines/ags/engine/gfx/gfxdefines.h index 0efa99e07506..a40e5f6f9ad9 100644 --- a/engines/ags/engine/gfx/gfxdefines.h +++ b/engines/ags/engine/gfx/gfxdefines.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_GFX__GFXDEFINES_H #define __AGS_EE_GFX__GFXDEFINES_H diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index 737d6a5071b6..e43510fcc9e8 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/wgt2allg.h" #include "gfx/ali3dexception.h" diff --git a/engines/ags/engine/gfx/gfxdriverbase.h b/engines/ags/engine/gfx/gfxdriverbase.h index a44534e52795..64d8dad05c09 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.h +++ b/engines/ags/engine/gfx/gfxdriverbase.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Implementation base for graphics driver // //============================================================================= + #ifndef __AGS_EE_GFX__GFXDRIVERBASE_H #define __AGS_EE_GFX__GFXDRIVERBASE_H diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp index 8dc58b927640..a6b379e2c817 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.cpp +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gfx/gfxdriverfactory.h" diff --git a/engines/ags/engine/gfx/gfxdriverfactory.h b/engines/ags/engine/gfx/gfxdriverfactory.h index fac4b36bf225..63d6479e705b 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.h +++ b/engines/ags/engine/gfx/gfxdriverfactory.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Graphics driver factory interface diff --git a/engines/ags/engine/gfx/gfxdriverfactorybase.h b/engines/ags/engine/gfx/gfxdriverfactorybase.h index c85b2afbb2b8..93710a3ad828 100644 --- a/engines/ags/engine/gfx/gfxdriverfactorybase.h +++ b/engines/ags/engine/gfx/gfxdriverfactorybase.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Base implementation of IGfxDriverFactory diff --git a/engines/ags/engine/gfx/gfxfilter.h b/engines/ags/engine/gfx/gfxfilter.h index 12d37bdfe8bd..5f6554dda279 100644 --- a/engines/ags/engine/gfx/gfxfilter.h +++ b/engines/ags/engine/gfx/gfxfilter.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Graphics filter interface diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp index 48da032ae4f2..57c76eef9343 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" #include "stdio.h" diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.h b/engines/ags/engine/gfx/gfxfilter_aad3d.h index 1e990799f927..5ae4af25c5a2 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.h +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Anti-aliased D3D filter diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp index 8b2fc4096462..3ad5aa9001e0 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.h b/engines/ags/engine/gfx/gfxfilter_aaogl.h index 064c5ba4c25a..d1f5f93d1af4 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.h +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Anti-aliased OGL filter diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index 274163c1e8ce..0d3e5ebc8ff4 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gfx/gfxfilter_allegro.h" diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h index 53f52c4faed0..74f01b341bc6 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.h +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Standard software scaling filter diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.cpp b/engines/ags/engine/gfx/gfxfilter_d3d.cpp index 7e9ac6fd5223..b3a8dd84d7ad 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_d3d.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" #include "gfx/gfxfilter_d3d.h" diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.h b/engines/ags/engine/gfx/gfxfilter_d3d.h index dee22e5c7757..c688ddfec39f 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.h +++ b/engines/ags/engine/gfx/gfxfilter_d3d.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Standard 3D-accelerated filter diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp index 6b7f843ba660..d25347bf4cbd 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.cpp +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gfx/bitmap.h" #include "gfx/gfxfilter_hqx.h" diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h index d4a0f0de61ad..97c0d0ef73fb 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.h +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // High quality x2 scaling filter diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.cpp b/engines/ags/engine/gfx/gfxfilter_ogl.cpp index e6cb85777a78..42697b736ba0 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_ogl.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.h b/engines/ags/engine/gfx/gfxfilter_ogl.h index d863fa42f8f0..c41bc6f56b69 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.h +++ b/engines/ags/engine/gfx/gfxfilter_ogl.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Dummy OpenGL filter; does nothing useful at the moment diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.cpp b/engines/ags/engine/gfx/gfxfilter_scaling.cpp index 50e1834460e4..923b36621b40 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.cpp +++ b/engines/ags/engine/gfx/gfxfilter_scaling.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gfx/gfxfilter_scaling.h" diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.h b/engines/ags/engine/gfx/gfxfilter_scaling.h index 80290400320c..228e934dd519 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.h +++ b/engines/ags/engine/gfx/gfxfilter_scaling.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Base class for graphic filter which provides virtual screen scaling diff --git a/engines/ags/engine/gfx/gfxmodelist.h b/engines/ags/engine/gfx/gfxmodelist.h index 281c5c06ddda..62eb38f690ac 100644 --- a/engines/ags/engine/gfx/gfxmodelist.h +++ b/engines/ags/engine/gfx/gfxmodelist.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Supported graphics mode interface diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h index f2d4e0d4759d..0af51ecd1c41 100644 --- a/engines/ags/engine/gfx/graphicsdriver.h +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Graphics driver interface diff --git a/engines/ags/engine/gfx/hq2x3x.h b/engines/ags/engine/gfx/hq2x3x.h index 3560d1689104..d569a642c630 100644 --- a/engines/ags/engine/gfx/hq2x3x.h +++ b/engines/ags/engine/gfx/hq2x3x.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_HQ2X3X_H #define __AC_HQ2X3X_H @@ -27,4 +35,4 @@ void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); #endif -#endif // __AC_HQ2X3X_H \ No newline at end of file +#endif // __AC_HQ2X3X_H diff --git a/engines/ags/engine/gfx/ogl_headers.h b/engines/ags/engine/gfx/ogl_headers.h index 5cf20136c5d2..9c41aa6f14f4 100644 --- a/engines/ags/engine/gfx/ogl_headers.h +++ b/engines/ags/engine/gfx/ogl_headers.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // OpenGL includes and definitions for various platforms diff --git a/engines/ags/engine/gui/animatingguibutton.cpp b/engines/ags/engine/gui/animatingguibutton.cpp index fb370df53b5d..23a3df226ce8 100644 --- a/engines/ags/engine/gui/animatingguibutton.cpp +++ b/engines/ags/engine/gui/animatingguibutton.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gui/animatingguibutton.h" #include "util/stream.h" diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h index 7cf5fc7b1c3d..fccdd7432831 100644 --- a/engines/ags/engine/gui/animatingguibutton.h +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_GUI__ANIMATINGGUIBUTTON_H #define __AGS_EE_GUI__ANIMATINGGUIBUTTON_H diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index c190bf3257e0..9adeb3a436cd 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "util/wgt2allg.h" diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h index 17fbcb6bab40..0246479e76bb 100644 --- a/engines/ags/engine/gui/cscidialog.h +++ b/engines/ags/engine/gui/cscidialog.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Legacy built-in GUI dialogs and controls. // //============================================================================= + #ifndef __AGS_EE_GUI__CSCIDIALOG_H #define __AGS_EE_GUI__CSCIDIALOG_H diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp index 3cd5aad16cee..b896a816e8f8 100644 --- a/engines/ags/engine/gui/gui_engine.cpp +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Implementation from acgui.h and acgui.cpp specific to Engine runtime diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index 7baa314387b7..42b37a9ab501 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "gui/guidialog.h" diff --git a/engines/ags/engine/gui/guidialog.h b/engines/ags/engine/gui/guidialog.h index 752edde64d56..aedca8609977 100644 --- a/engines/ags/engine/gui/guidialog.h +++ b/engines/ags/engine/gui/guidialog.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_GUI__GUIDIALOG_H #define __AGS_EE_GUI__GUIDIALOG_H diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h index 548c32ff1f7e..82d783d5027b 100644 --- a/engines/ags/engine/gui/guidialogdefines.h +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_GUI__GUIDIALOGDEFINES_H #define __AGS_EE_GUI__GUIDIALOGDEFINES_H @@ -108,4 +113,4 @@ struct OnScreenWindow OnScreenWindow(); }; -#endif // __AGS_EE_GUI__GUIDIALOGDEFINES_H \ No newline at end of file +#endif // __AGS_EE_GUI__GUIDIALOGDEFINES_H diff --git a/engines/ags/engine/gui/guidialoginternaldefs.h b/engines/ags/engine/gui/guidialoginternaldefs.h index 53755d139a11..2de4f5639ae7 100644 --- a/engines/ags/engine/gui/guidialoginternaldefs.h +++ b/engines/ags/engine/gui/guidialoginternaldefs.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H #define __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H diff --git a/engines/ags/engine/gui/mycontrols.h b/engines/ags/engine/gui/mycontrols.h index 89383e5c4b3d..df6b2b178d66 100644 --- a/engines/ags/engine/gui/mycontrols.h +++ b/engines/ags/engine/gui/mycontrols.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Legacy built-in GUI dialogs and controls. // //============================================================================= + #ifndef __AGS_EE_GUI__MYCONTROLS_H #define __AGS_EE_GUI__MYCONTROLS_H diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp index 1ce06d8f7521..0efed9968488 100644 --- a/engines/ags/engine/gui/mylabel.cpp +++ b/engines/ags/engine/gui/mylabel.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/display.h" diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h index c700790fa0e0..efa6ec8b43fa 100644 --- a/engines/ags/engine/gui/mylabel.h +++ b/engines/ags/engine/gui/mylabel.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYLABEL_H #define __AC_MYLABEL_H @@ -29,4 +37,4 @@ struct MyLabel:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_MYLABEL_H \ No newline at end of file +#endif // __AC_MYLABEL_H diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index 66bba59d663b..7253ecdde4c6 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "util/wgt2allg.h" diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h index 4ce657bcab6f..271bdbd94fc9 100644 --- a/engines/ags/engine/gui/mylistbox.h +++ b/engines/ags/engine/gui/mylistbox.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYLISTBOX_H #define __AC_MYLISTBOX_H @@ -34,4 +42,4 @@ struct MyListBox:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_MYLISTBOX_H \ No newline at end of file +#endif // __AC_MYLISTBOX_H diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index 449c6ac8a8bd..a44755418843 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "util/wgt2allg.h" @@ -103,4 +111,4 @@ int MyPushButton::pressedon(int mousex, int mousey) int MyPushButton::processmessage(int mcode, int wParam, long lParam) { return -1; // doesn't support messages -} \ No newline at end of file +} diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h index 14bca4de80e1..56832759cc51 100644 --- a/engines/ags/engine/gui/mypushbutton.h +++ b/engines/ags/engine/gui/mypushbutton.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_PUSHBUTTON_H #define __AC_PUSHBUTTON_H @@ -26,4 +34,4 @@ struct MyPushButton:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_PUSHBUTTON_H \ No newline at end of file +#endif // __AC_PUSHBUTTON_H diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp index e6a5ee30b46b..945b04706ff1 100644 --- a/engines/ags/engine/gui/mytextbox.cpp +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "util/wgt2allg.h" diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h index 264c2bcc32f5..6fb47c258861 100644 --- a/engines/ags/engine/gui/mytextbox.h +++ b/engines/ags/engine/gui/mytextbox.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYTEXTBOX_H #define __AC_MYTEXTBOX_H @@ -27,4 +35,4 @@ struct MyTextBox:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_MYTEXTBOX_H \ No newline at end of file +#endif // __AC_MYTEXTBOX_H diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp index 29e683aa9653..f3cc9cdede39 100644 --- a/engines/ags/engine/gui/newcontrol.cpp +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gui/newcontrol.h" #include "gui/guidialog.h" diff --git a/engines/ags/engine/gui/newcontrol.h b/engines/ags/engine/gui/newcontrol.h index e308bff881aa..550e6619889a 100644 --- a/engines/ags/engine/gui/newcontrol.h +++ b/engines/ags/engine/gui/newcontrol.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_GUI__NEWCONTROL_H #define __AGS_EE_GUI__NEWCONTROL_H @@ -39,4 +44,4 @@ struct NewControl void drawandmouse(); }; -#endif // __AGS_EE_GUI__NEWCONTROL_H \ No newline at end of file +#endif // __AGS_EE_GUI__NEWCONTROL_H diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 558d67ca9237..5be0cc92564b 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Game configuration diff --git a/engines/ags/engine/main/config.h b/engines/ags/engine/main/config.h index 5398a148b215..98ae4214375a 100644 --- a/engines/ags/engine/main/config.h +++ b/engines/ags/engine/main/config.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__CONFIG_H #define __AGS_EE_MAIN__CONFIG_H diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 4532275d40bd..af9140e25903 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Engine initialization diff --git a/engines/ags/engine/main/engine.h b/engines/ags/engine/main/engine.h index d5c2079a3064..5a83b4788393 100644 --- a/engines/ags/engine/main/engine.h +++ b/engines/ags/engine/main/engine.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_MAIN__ENGINE_H #define __AGS_EE_MAIN__ENGINE_H diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp index ba9780030da4..ef4f7c1887ab 100644 --- a/engines/ags/engine/main/engine_setup.cpp +++ b/engines/ags/engine/main/engine_setup.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" #include "ac/common.h" diff --git a/engines/ags/engine/main/engine_setup.h b/engines/ags/engine/main/engine_setup.h index ad5e6fa4078b..a1d9dd2c3b2c 100644 --- a/engines/ags/engine/main/engine_setup.h +++ b/engines/ags/engine/main/engine_setup.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_MAIN__ENGINESETUP_H #define __AGS_EE_MAIN__ENGINESETUP_H diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp index 82973f510266..4b38de3fd13b 100644 --- a/engines/ags/engine/main/game_file.cpp +++ b/engines/ags/engine/main/game_file.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Game data file management diff --git a/engines/ags/engine/main/game_file.h b/engines/ags/engine/main/game_file.h index d0a50a7c6c94..6422096f42d3 100644 --- a/engines/ags/engine/main/game_file.h +++ b/engines/ags/engine/main/game_file.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__GAMEFILE_H #define __AGS_EE_MAIN__GAMEFILE_H diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 173d2db1803a..744680bbe3bd 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Game loop diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h index 450cd3ba7508..2a87af861bd9 100644 --- a/engines/ags/engine/main/game_run.h +++ b/engines/ags/engine/main/game_run.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__GAMERUN_H #define __AGS_EE_MAIN__GAMERUN_H diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 43a46cbfdd87..99e799948715 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Game initialization diff --git a/engines/ags/engine/main/game_start.h b/engines/ags/engine/main/game_start.h index b732e2d4c0cd..4f79e4e71dcb 100644 --- a/engines/ags/engine/main/game_start.h +++ b/engines/ags/engine/main/game_start.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__GAMESTART_H #define __AGS_EE_MAIN__GAMESTART_H diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp index 1c853bce8a78..e99adca30018 100644 --- a/engines/ags/engine/main/graphics_mode.cpp +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Graphics initialization diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h index 8329e407120b..426f3d2200f8 100644 --- a/engines/ags/engine/main/graphics_mode.h +++ b/engines/ags/engine/main/graphics_mode.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__GRAPHICSMODE_H #define __AGS_EE_MAIN__GRAPHICSMODE_H diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp index 5ac2f6a903df..ef135fd15813 100644 --- a/engines/ags/engine/main/main.cpp +++ b/engines/ags/engine/main/main.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Entry point of the application here. diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index 1f5116d342b9..9dc115506d85 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__MAIN_H #define __AGS_EE_MAIN__MAIN_H @@ -62,4 +67,4 @@ void main_print_help(); int ags_entry_point(int argc, char *argv[]); -#endif // __AGS_EE_MAIN__MAIN_H \ No newline at end of file +#endif // __AGS_EE_MAIN__MAIN_H diff --git a/engines/ags/engine/main/main_allegro.cpp b/engines/ags/engine/main/main_allegro.cpp deleted file mode 100644 index 5a43762f44e1..000000000000 --- a/engines/ags/engine/main/main_allegro.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "allegro.h" -#include "main/main.h" - -int main(int argc, char *argv[]) { - return ags_entry_point(argc, argv); -} -END_OF_MAIN() diff --git a/engines/ags/engine/main/main_allegro.h b/engines/ags/engine/main/main_allegro.h index bbf7bcf6e8a0..177c7d932831 100644 --- a/engines/ags/engine/main/main_allegro.h +++ b/engines/ags/engine/main/main_allegro.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__MAINALLEGRO_H #define __AGS_EE_MAIN__MAINALLEGRO_H diff --git a/engines/ags/engine/main/maindefines_ex.h b/engines/ags/engine/main/maindefines_ex.h index d2b8729f47d3..32e214464702 100644 --- a/engines/ags/engine/main/maindefines_ex.h +++ b/engines/ags/engine/main/maindefines_ex.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__MAINDEFINES_H #define __AGS_EE_MAIN__MAINDEFINES_H diff --git a/engines/ags/engine/main/mainheader.h b/engines/ags/engine/main/mainheader.h index 7b1d23f6a3a9..1739068bcbb0 100644 --- a/engines/ags/engine/main/mainheader.h +++ b/engines/ags/engine/main/mainheader.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__MAINHEADER_H #define __AGS_EE_MAIN__MAINHEADER_H diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 678b376eef29..ce039abe1586 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Quit game procedure diff --git a/engines/ags/engine/main/quit.h b/engines/ags/engine/main/quit.h index 4eac73fdf684..2afd0eeaa57a 100644 --- a/engines/ags/engine/main/quit.h +++ b/engines/ags/engine/main/quit.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__QUIT_H #define __AGS_EE_MAIN__QUIT_H diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp index c7ede5321970..e7eeb09e6ba4 100644 --- a/engines/ags/engine/main/update.cpp +++ b/engines/ags/engine/main/update.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ // // Game update procedure diff --git a/engines/ags/engine/main/update.h b/engines/ags/engine/main/update.h index 0017787ae452..ff89a549e2b0 100644 --- a/engines/ags/engine/main/update.h +++ b/engines/ags/engine/main/update.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MAIN__UPDATE_H #define __AGS_EE_MAIN__UPDATE_H diff --git a/engines/ags/engine/media/audio/ambientsound.cpp b/engines/ags/engine/media/audio/ambientsound.cpp index f5b0e7ff0d1c..89a353a81b28 100644 --- a/engines/ags/engine/media/audio/ambientsound.cpp +++ b/engines/ags/engine/media/audio/ambientsound.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/ambientsound.h" #include "media/audio/audio.h" diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h index 7117d3647947..1144eda9ad29 100644 --- a/engines/ags/engine/media/audio/ambientsound.h +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_AMBIENTSOUND_H #define __AC_AMBIENTSOUND_H diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 2a0a7d073c7d..656e06d5dc50 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index 05600c9d53d5..1d0a239dce30 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_AUDIO_H #define __AC_AUDIO_H diff --git a/engines/ags/engine/media/audio/audio_system.h b/engines/ags/engine/media/audio/audio_system.h index 4cb910c65720..9bb5e1cb1afa 100644 --- a/engines/ags/engine/media/audio/audio_system.h +++ b/engines/ags/engine/media/audio/audio_system.h @@ -1,3 +1,25 @@ +/* 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 __AC_MEDIA_AUDIO_SYSTEM_H #define __AC_MEDIA_AUDIO_SYSTEM_H @@ -13,4 +35,4 @@ #include "media/audio/queuedaudioitem.h" -#endif \ No newline at end of file +#endif diff --git a/engines/ags/engine/media/audio/audiodefines.h b/engines/ags/engine/media/audio/audiodefines.h index 13effae234bc..ee7757cc9054 100644 --- a/engines/ags/engine/media/audio/audiodefines.h +++ b/engines/ags/engine/media/audio/audiodefines.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_AUDIODEFINES_H #define __AC_AUDIODEFINES_H @@ -36,4 +44,4 @@ #define AUDIOTYPE_LEGACY_MUSIC 2 #define AUDIOTYPE_LEGACY_SOUND 3 -#endif // __AC_AUDIODEFINES_H \ No newline at end of file +#endif // __AC_AUDIODEFINES_H diff --git a/engines/ags/engine/media/audio/audiointernaldefs.h b/engines/ags/engine/media/audio/audiointernaldefs.h index 0d7c0174fb26..3dce5d80cae8 100644 --- a/engines/ags/engine/media/audio/audiointernaldefs.h +++ b/engines/ags/engine/media/audio/audiointernaldefs.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SOUNDINTERNALDEFS_H #define __AC_SOUNDINTERNALDEFS_H @@ -18,4 +26,4 @@ //#define MP3CHUNKSIZE 100000 #define MP3CHUNKSIZE 32768 -#endif // __AC_SOUNDINTERNALDEFS_H \ No newline at end of file +#endif // __AC_SOUNDINTERNALDEFS_H diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp index 8c040626588f..3efe1c3ef3dc 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.cpp +++ b/engines/ags/engine/media/audio/clip_mydumbmod.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/audiodefines.h" @@ -160,4 +168,4 @@ MYMOD::MYMOD() : SOUNDCLIP() { duhPlayer = nullptr; } -#endif // DUMB_MOD_PLAYER \ No newline at end of file +#endif // DUMB_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index 193c7f4567ca..8c20a135aeac 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYDUMBMOD_H #define __AC_MYDUMBMOD_H @@ -66,4 +74,4 @@ struct MYMOD : public SOUNDCLIP int get_real_mod_pos(); }; -#endif // __AC_MYDUMBMOD_H \ No newline at end of file +#endif // __AC_MYDUMBMOD_H diff --git a/engines/ags/engine/media/audio/clip_myjgmod.cpp b/engines/ags/engine/media/audio/clip_myjgmod.cpp index 45209551e7d3..be3758aa264e 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.cpp +++ b/engines/ags/engine/media/audio/clip_myjgmod.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/audiodefines.h" @@ -86,4 +94,4 @@ int MYMOD::play() { MYMOD::MYMOD() : SOUNDCLIP() { } -#endif // #ifdef JGMOD_MOD_PLAYER \ No newline at end of file +#endif // #ifdef JGMOD_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/clip_myjgmod.h b/engines/ags/engine/media/audio/clip_myjgmod.h index 6870b67503cf..9ddb82bbf214 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.h +++ b/engines/ags/engine/media/audio/clip_myjgmod.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYJGMOD_H #define __AC_MYJGMOD_H @@ -46,4 +54,4 @@ struct MYMOD:public SOUNDCLIP MYMOD(); }; -#endif // __AC_MYJGMOD_H \ No newline at end of file +#endif // __AC_MYJGMOD_H diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index 1175bab306d1..5241c9471b62 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/audiodefines.h" #include "util/wgt2allg.h" diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index 5799f5ab88e7..0eccf714a85f 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYMIDI_H #define __AC_MYMIDI_H @@ -52,4 +60,4 @@ struct MYMIDI:public SOUNDCLIP void adjust_volume() override; }; -#endif // __AC_MYMIDI_H \ No newline at end of file +#endif // __AC_MYMIDI_H diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp index b4c98d849ea2..d4aff270c58b 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/audiodefines.h" @@ -170,4 +178,4 @@ MYMP3::MYMP3() : SOUNDCLIP() { chunksize = 0; } -#endif // !NO_MP3_PLAYER \ No newline at end of file +#endif // !NO_MP3_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index 58448149d7c4..cf5ee292fdba 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYMP3_H #define __AC_MYMP3_H @@ -47,4 +55,4 @@ struct MYMP3:public SOUNDCLIP void adjust_stream(); }; -#endif // __AC_MYMP3_H \ No newline at end of file +#endif // __AC_MYMP3_H diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp index da16c94162af..6cc9be62813a 100644 --- a/engines/ags/engine/media/audio/clip_myogg.cpp +++ b/engines/ags/engine/media/audio/clip_myogg.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/audiodefines.h" #include "media/audio/clip_myogg.h" diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h index 093920476afb..26625f5c5272 100644 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYOGG_H #define __AC_MYOGG_H @@ -57,4 +65,4 @@ struct MYOGG:public SOUNDCLIP void adjust_stream(); }; -#endif // __AC_MYOGG_H \ No newline at end of file +#endif // __AC_MYOGG_H diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp index 1c0c0c46bcca..aef22b4d1537 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/audiodefines.h" diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index 20f79e4711d2..a5b803135349 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYSTATICMP3_H #define __AC_MYSTATICMP3_H diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp index 5a744e499fdd..759559643fbc 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticogg.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/audiodefines.h" #include "media/audio/clip_mystaticogg.h" diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h index a57250857ddc..4e2f3a1de2a3 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYSTATICOGG_H #define __AC_MYSTATICOGG_H diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp index 4ab79f061364..d298f174bed7 100644 --- a/engines/ags/engine/media/audio/clip_mywave.cpp +++ b/engines/ags/engine/media/audio/clip_mywave.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/wgt2allg.h" #include "media/audio/audiodefines.h" diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h index b78c5ed29b69..094f36eedbdc 100644 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MYWAVE_H #define __AC_MYWAVE_H @@ -47,4 +55,4 @@ struct MYWAVE:public SOUNDCLIP void adjust_volume() override; }; -#endif // __AC_MYWAVE_H \ No newline at end of file +#endif // __AC_MYWAVE_H diff --git a/engines/ags/engine/media/audio/queuedaudioitem.cpp b/engines/ags/engine/media/audio/queuedaudioitem.cpp index 0656a1025524..c8fe331ef147 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.cpp +++ b/engines/ags/engine/media/audio/queuedaudioitem.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/audio/queuedaudioitem.h" #include "ac/common_defines.h" diff --git a/engines/ags/engine/media/audio/queuedaudioitem.h b/engines/ags/engine/media/audio/queuedaudioitem.h index 0e7313e61600..d5024de57cf0 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.h +++ b/engines/ags/engine/media/audio/queuedaudioitem.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_QUEUEDAUDIOITEM_H #define __AC_QUEUEDAUDIOITEM_H @@ -30,4 +38,4 @@ struct QueuedAudioItem { void WriteToFile(Common::Stream *out) const; }; -#endif // __AC_QUEUEDAUDIOITEM_H \ No newline at end of file +#endif // __AC_QUEUEDAUDIOITEM_H diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index 4bc3348a3973..43f398a7d2b3 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // ACSOUND - AGS sound system wrapper diff --git a/engines/ags/engine/media/audio/sound.h b/engines/ags/engine/media/audio/sound.h index 2a644159fb79..67c9438e1afd 100644 --- a/engines/ags/engine/media/audio/sound.h +++ b/engines/ags/engine/media/audio/sound.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // ACSOUND - AGS sound system wrapper diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index 3f59917c120c..e32526604726 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h index ebdb67c69a92..21bb6b6b67f4 100644 --- a/engines/ags/engine/media/audio/soundcache.h +++ b/engines/ags/engine/media/audio/soundcache.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_SOUNDCACHE_H #define __AC_SOUNDCACHE_H diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index 844eb0fa9182..86ae041863f8 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/wgt2allg.h" #include "media/audio/audio.h" diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index 36a1166929d7..5a0d6e9a6049 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // ACSOUND - AGS sound system wrapper diff --git a/engines/ags/engine/media/video/VMR9Graph.h b/engines/ags/engine/media/video/VMR9Graph.h index 4b91ac02ff3d..3f424dd556c5 100644 --- a/engines/ags/engine/media/video/VMR9Graph.h +++ b/engines/ags/engine/media/video/VMR9Graph.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // VMR9Graph.h: interface for the CVMR9Graph class. diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index e2e1ebfc62cd..0ecf7e965f53 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "media/video/video.h" @@ -428,4 +436,4 @@ void play_theora_video(const char *name, int skip, int flags) {} void play_flc_file(int numb,int playflags) {} void video_on_gfxmode_changed() {} -#endif \ No newline at end of file +#endif diff --git a/engines/ags/engine/media/video/video.h b/engines/ags/engine/media/video/video.h index 1110260968c5..b627fe13ba06 100644 --- a/engines/ags/engine/media/video/video.h +++ b/engines/ags/engine/media/video/video.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_MEDIA__VIDEO_H #define __AGS_EE_MEDIA__VIDEO_H diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp index 596c4aae5771..64e21ea45943 100644 --- a/engines/ags/engine/platform/android/acpland.cpp +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index 970611540d77..94649d08aacf 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS Platform-specific functions diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 208d9afca624..5ce00e0e9062 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS Cross-Platform Header diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp index 96bbe432509d..e01dd821ce44 100644 --- a/engines/ags/engine/platform/ios/acplios.cpp +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 07297a9fdfff..3d041962bfd0 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/platform/osx/acplmac.cpp b/engines/ags/engine/platform/osx/acplmac.cpp index 64c590a65179..f859e2243b78 100644 --- a/engines/ags/engine/platform/osx/acplmac.cpp +++ b/engines/ags/engine/platform/osx/acplmac.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/platform/util/pe.h b/engines/ags/engine/platform/util/pe.h index 97b5e646462c..060968f7765e 100644 --- a/engines/ags/engine/platform/util/pe.h +++ b/engines/ags/engine/platform/util/pe.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_PLATFORM_UTIL_PE_H #define __AGS_EE_PLATFORM_UTIL_PE_H diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index 8e3b91d62520..37244d32e4c0 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index b96a10c798ba..bf1003698b1b 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Allegro Interface for 3D; Direct 3D 9 driver @@ -2087,4 +2097,4 @@ bool D3DGraphicsFactory::Init() } // namespace Engine } // namespace AGS -#endif // AGS_PLATFORM_OS_WINDOWS \ No newline at end of file +#endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index a8cc442f0a69..cd04214f6871 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Direct3D graphics factory diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp index de682a804004..f17b55be5088 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AVI/MPG player for AGS @@ -431,4 +441,4 @@ int WINAPI WinMain( } #endif -#endif // AGS_PLATFORM_OS_WINDOWS \ No newline at end of file +#endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp index 79adf85b4637..a7cd8f38c3a5 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AVI/MPG player for AGS diff --git a/engines/ags/engine/platform/windows/minidump.cpp b/engines/ags/engine/platform/windows/minidump.cpp index b71dde460d8a..75e5df3bc1d5 100644 --- a/engines/ags/engine/platform/windows/minidump.cpp +++ b/engines/ags/engine/platform/windows/minidump.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" #if AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG diff --git a/engines/ags/engine/platform/windows/setup/winsetup.cpp b/engines/ags/engine/platform/windows/setup/winsetup.cpp index ea4f77fc7ecb..a0147381b46c 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.cpp +++ b/engines/ags/engine/platform/windows/setup/winsetup.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" @@ -1252,4 +1260,4 @@ SetupReturnValue WinSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, } // namespace Engine } // namespace AGS -#endif // AGS_PLATFORM_OS_WINDOWS \ No newline at end of file +#endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/windows/setup/winsetup.h b/engines/ags/engine/platform/windows/setup/winsetup.h index e030cf33b92a..ac02d809f0a0 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.h +++ b/engines/ags/engine/platform/windows/setup/winsetup.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Built-in setup dialog for Windows version diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index 27d56c67fe09..ad1a159a492c 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/platform.h" #if AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/windows/win_ex_handling.h b/engines/ags/engine/platform/windows/win_ex_handling.h index 30f458945d26..211fcd36f148 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.h +++ b/engines/ags/engine/platform/windows/win_ex_handling.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_PLATFORM__WIN_EXCEPTION_HANDLING_H #define __AGS_EE_PLATFORM__WIN_EXCEPTION_HANDLING_H diff --git a/engines/ags/engine/platform/windows/winapi_exclusive.h b/engines/ags/engine/platform/windows/winapi_exclusive.h index e82c4175f9d8..6b8a26f9dc5f 100644 --- a/engines/ags/engine/platform/windows/winapi_exclusive.h +++ b/engines/ags/engine/platform/windows/winapi_exclusive.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // An excerpt from , declaring most commonly used WinAPI types @@ -17,6 +27,7 @@ // cause naming conflicts with its dreaded heap of macros. // //============================================================================= + #ifndef __AGS_EE_PLATFORM__WINAPI_EXCLUSIVE_H #define __AGS_EE_PLATFORM__WINAPI_EXCLUSIVE_H diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 240f0d14fcff..ac078a95d00d 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "core/platform.h" @@ -1106,4 +1114,4 @@ bool pl_any_want_hook(int event) return true; } return false; -} \ No newline at end of file +} diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/engine/plugin/agsplugin.h index 6a09ee93a92c..0b640d84ccae 100644 --- a/engines/ags/engine/plugin/agsplugin.h +++ b/engines/ags/engine/plugin/agsplugin.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS Plugin interface header file diff --git a/engines/ags/engine/plugin/global_plugin.cpp b/engines/ags/engine/plugin/global_plugin.cpp index 001841fe2d4e..6d7b5282a103 100644 --- a/engines/ags/engine/plugin/global_plugin.cpp +++ b/engines/ags/engine/plugin/global_plugin.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Stubs for plugin functions. diff --git a/engines/ags/engine/plugin/plugin_builtin.h b/engines/ags/engine/plugin/plugin_builtin.h index a25d8f03a2bf..0bfe0c4e496b 100644 --- a/engines/ags/engine/plugin/plugin_builtin.h +++ b/engines/ags/engine/plugin/plugin_builtin.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Plugin system functions. // //============================================================================= + #ifndef __AGS_EE_PLUGIN__PLUGINBUILTIN_H #define __AGS_EE_PLUGIN__PLUGINBUILTIN_H diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/engine/plugin/plugin_engine.h index d5b3cb265698..3c90f3775cf2 100644 --- a/engines/ags/engine/plugin/plugin_engine.h +++ b/engines/ags/engine/plugin/plugin_engine.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Plugin system functions. // //============================================================================= + #ifndef __AGS_EE_PLUGIN__PLUGINENGINE_H #define __AGS_EE_PLUGIN__PLUGINENGINE_H diff --git a/engines/ags/engine/plugin/pluginobjectreader.cpp b/engines/ags/engine/plugin/pluginobjectreader.cpp index 2d2700b31d5b..7cf0d2b8b011 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.cpp +++ b/engines/ags/engine/plugin/pluginobjectreader.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "plugin/pluginobjectreader.h" #include "ac/runtime_defines.h" diff --git a/engines/ags/engine/plugin/pluginobjectreader.h b/engines/ags/engine/plugin/pluginobjectreader.h index 7add04c40ccd..00cb03c5697b 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.h +++ b/engines/ags/engine/plugin/pluginobjectreader.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H #define __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H diff --git a/engines/ags/engine/resource/resource.h b/engines/ags/engine/resource/resource.h index bfacb7632ecc..84d5685e83f0 100644 --- a/engines/ags/engine/resource/resource.h +++ b/engines/ags/engine/resource/resource.h @@ -1,3 +1,25 @@ +/* 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. + * + */ + //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by version.rc diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index affee68e773a..75a2c37162da 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h index 7f6be855433e..f01ac4a9752b 100644 --- a/engines/ags/engine/script/cc_instance.h +++ b/engines/ags/engine/script/cc_instance.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // 'C'-style script interpreter diff --git a/engines/ags/engine/script/executingscript.cpp b/engines/ags/engine/script/executingscript.cpp index ba1fb22f3f2e..634b5352cb78 100644 --- a/engines/ags/engine/script/executingscript.cpp +++ b/engines/ags/engine/script/executingscript.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "executingscript.h" diff --git a/engines/ags/engine/script/executingscript.h b/engines/ags/engine/script/executingscript.h index 52f7b02e622d..ffe68fcc37f9 100644 --- a/engines/ags/engine/script/executingscript.h +++ b/engines/ags/engine/script/executingscript.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H #define __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H diff --git a/engines/ags/engine/script/exports.cpp b/engines/ags/engine/script/exports.cpp index 5bad7b5d706d..2832902275d2 100644 --- a/engines/ags/engine/script/exports.cpp +++ b/engines/ags/engine/script/exports.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Registering symbols for the script system diff --git a/engines/ags/engine/script/exports.h b/engines/ags/engine/script/exports.h index cfb8ffcc159f..0829c9557e75 100644 --- a/engines/ags/engine/script/exports.h +++ b/engines/ags/engine/script/exports.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Registering symbols for the script system // //============================================================================= + #ifndef __AGS_EE_SCRIPT__EXPORTS_H #define __AGS_EE_SCRIPT__EXPORTS_H diff --git a/engines/ags/engine/script/nonblockingscriptfunction.h b/engines/ags/engine/script/nonblockingscriptfunction.h index 6c49e1b42df0..d924296809d2 100644 --- a/engines/ags/engine/script/nonblockingscriptfunction.h +++ b/engines/ags/engine/script/nonblockingscriptfunction.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H #define __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H diff --git a/engines/ags/engine/script/runtimescriptvalue.cpp b/engines/ags/engine/script/runtimescriptvalue.cpp index f74e8d15b783..e69a7b0825e5 100644 --- a/engines/ags/engine/script/runtimescriptvalue.cpp +++ b/engines/ags/engine/script/runtimescriptvalue.cpp @@ -1,3 +1,24 @@ +/* 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 "script/cc_error.h" #include "script/runtimescriptvalue.h" diff --git a/engines/ags/engine/script/runtimescriptvalue.h b/engines/ags/engine/script/runtimescriptvalue.h index 133267d203b3..85b1b716a699 100644 --- a/engines/ags/engine/script/runtimescriptvalue.h +++ b/engines/ags/engine/script/runtimescriptvalue.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Runtime script value struct // //============================================================================= + #ifndef __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H #define __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp index 40f3fb915f9a..3762be9509f1 100644 --- a/engines/ags/engine/script/script.cpp +++ b/engines/ags/engine/script/script.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "script/script.h" diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h index 521bf78298fe..7404f776ac32 100644 --- a/engines/ags/engine/script/script.h +++ b/engines/ags/engine/script/script.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_EE_SCRIPT__SCRIPT_H #define __AGS_EE_SCRIPT__SCRIPT_H diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp index efc6ee92590e..706a44877910 100644 --- a/engines/ags/engine/script/script_api.cpp +++ b/engines/ags/engine/script/script_api.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h index f17183850e23..601ace14f75f 100644 --- a/engines/ags/engine/script/script_api.h +++ b/engines/ags/engine/script/script_api.h @@ -1,21 +1,32 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Script API function type and helper macros for forwarding runtime script // values to real engine functions. // //============================================================================= + #ifndef __AGS_EE_SCRIPT__SCRIPTAPI_H #define __AGS_EE_SCRIPT__SCRIPTAPI_H diff --git a/engines/ags/engine/script/script_engine.cpp b/engines/ags/engine/script/script_engine.cpp index eefd707fe062..7dbb6cc0f755 100644 --- a/engines/ags/engine/script/script_engine.cpp +++ b/engines/ags/engine/script/script_engine.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Script Editor run-time engine component (c) 1998 Chris Jones diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp index 81a6d881bc5f..939c9fb76d0d 100644 --- a/engines/ags/engine/script/script_runtime.cpp +++ b/engines/ags/engine/script/script_runtime.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // C-Script run-time interpreter (c) 2001 Chris Jones diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h index 5a7e69c142de..af636ab774e6 100644 --- a/engines/ags/engine/script/script_runtime.h +++ b/engines/ags/engine/script/script_runtime.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // C-Script run-time interpreter (c) 2001 Chris Jones diff --git a/engines/ags/engine/script/systemimports.cpp b/engines/ags/engine/script/systemimports.cpp index 41a53766d924..980e191e43e5 100644 --- a/engines/ags/engine/script/systemimports.cpp +++ b/engines/ags/engine/script/systemimports.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index b6a0873864f1..90dc7ea968b5 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __CC_SYSTEMIMPORTS_H #define __CC_SYSTEMIMPORTS_H @@ -60,4 +68,4 @@ extern SystemImports simp; // perform old style unsafe function calls extern SystemImports simp_for_plugin; -#endif // __CC_SYSTEMIMPORTS_H \ No newline at end of file +#endif // __CC_SYSTEMIMPORTS_H diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h index 07c037a55086..7e4f7ac70729 100644 --- a/engines/ags/engine/util/library.h +++ b/engines/ags/engine/util/library.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__LIBRARY_H #define __AGS_EE_UTIL__LIBRARY_H diff --git a/engines/ags/engine/util/library_dummy.h b/engines/ags/engine/util/library_dummy.h index d91d06d34657..dd22849d5b41 100644 --- a/engines/ags/engine/util/library_dummy.h +++ b/engines/ags/engine/util/library_dummy.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__LIBRARY_DUMMY_H #define __AGS_EE_UTIL__LIBRARY_DUMMY_H diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index a11cdb2cecbc..1b738d230f03 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__LIBRARY_POSIX_H #define __AGS_EE_UTIL__LIBRARY_POSIX_H diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h index 54f52098b464..0ab345d4afda 100644 --- a/engines/ags/engine/util/library_psp.h +++ b/engines/ags/engine/util/library_psp.h @@ -1,17 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= - +/* 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 __AGS_EE_UTIL__LIBRARY_PSP_H #define __AGS_EE_UTIL__LIBRARY_PSP_H diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h index 7d4e5a7454e6..7b811689fec7 100644 --- a/engines/ags/engine/util/library_windows.h +++ b/engines/ags/engine/util/library_windows.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__LIBRARY_WINDOWS_H #define __AGS_EE_UTIL__LIBRARY_WINDOWS_H diff --git a/engines/ags/engine/util/mutex.h b/engines/ags/engine/util/mutex.h index f7e8535f4b9f..b559680af4e5 100644 --- a/engines/ags/engine/util/mutex.h +++ b/engines/ags/engine/util/mutex.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__MUTEX_H #define __AGS_EE_UTIL__MUTEX_H diff --git a/engines/ags/engine/util/mutex_base.h b/engines/ags/engine/util/mutex_base.h index 51684f4b3ce6..9329f1c2a9f7 100644 --- a/engines/ags/engine/util/mutex_base.h +++ b/engines/ags/engine/util/mutex_base.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_PLATFORM__MUTEX_BASE_H #define __AGS_EE_PLATFORM__MUTEX_BASE_H diff --git a/engines/ags/engine/util/mutex_lock.h b/engines/ags/engine/util/mutex_lock.h index 6164abbf9094..c9561d95c95d 100644 --- a/engines/ags/engine/util/mutex_lock.h +++ b/engines/ags/engine/util/mutex_lock.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__MUTEX_LOCK_H #define __AGS_EE_UTIL__MUTEX_LOCK_H diff --git a/engines/ags/engine/util/mutex_psp.h b/engines/ags/engine/util/mutex_psp.h index 72ab28384514..81920a28afac 100644 --- a/engines/ags/engine/util/mutex_psp.h +++ b/engines/ags/engine/util/mutex_psp.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__PSP_MUTEX_H #define __AGS_EE_UTIL__PSP_MUTEX_H diff --git a/engines/ags/engine/util/mutex_pthread.h b/engines/ags/engine/util/mutex_pthread.h index cb3183fd13fa..940531b19e03 100644 --- a/engines/ags/engine/util/mutex_pthread.h +++ b/engines/ags/engine/util/mutex_pthread.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__MUTEX_PTHREAD_H #define __AGS_EE_UTIL__MUTEX_PTHREAD_H diff --git a/engines/ags/engine/util/mutex_std.h b/engines/ags/engine/util/mutex_std.h index d86607956cf4..137c1321089a 100644 --- a/engines/ags/engine/util/mutex_std.h +++ b/engines/ags/engine/util/mutex_std.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__MUTEX_STD_H #define __AGS_EE_UTIL__MUTEX_STD_H diff --git a/engines/ags/engine/util/mutex_wii.h b/engines/ags/engine/util/mutex_wii.h index 6aa376b2f477..93ae9f3b74a3 100644 --- a/engines/ags/engine/util/mutex_wii.h +++ b/engines/ags/engine/util/mutex_wii.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__WII_MUTEX_H #define __AGS_EE_UTIL__WII_MUTEX_H diff --git a/engines/ags/engine/util/mutex_windows.h b/engines/ags/engine/util/mutex_windows.h index cf4c9157657f..0e3c4c0ba545 100644 --- a/engines/ags/engine/util/mutex_windows.h +++ b/engines/ags/engine/util/mutex_windows.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__WINDOWS_MUTEX_H #define __AGS_EE_UTIL__WINDOWS_MUTEX_H diff --git a/engines/ags/engine/util/scaling.h b/engines/ags/engine/util/scaling.h index a8f784754691..8ccf81e9bc14 100644 --- a/engines/ags/engine/util/scaling.h +++ b/engines/ags/engine/util/scaling.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Helper struct for scaling coordinates @@ -18,6 +28,7 @@ // Maybe implement as real matrix and/or floats if that is better/runs faster. // //============================================================================= + #ifndef __AGS_EE_UTIL__SCALING_H #define __AGS_EE_UTIL__SCALING_H diff --git a/engines/ags/engine/util/thread.h b/engines/ags/engine/util/thread.h index 0f2bc1c16111..8a64b3caa5ee 100644 --- a/engines/ags/engine/util/thread.h +++ b/engines/ags/engine/util/thread.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__THREAD_H #define __AGS_EE_UTIL__THREAD_H diff --git a/engines/ags/engine/util/thread_psp.h b/engines/ags/engine/util/thread_psp.h index eb4890425f06..1439f6a76823 100644 --- a/engines/ags/engine/util/thread_psp.h +++ b/engines/ags/engine/util/thread_psp.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_UTIL__PSP_THREAD_H #define __AGS_EE_UTIL__PSP_THREAD_H diff --git a/engines/ags/engine/util/thread_pthread.h b/engines/ags/engine/util/thread_pthread.h index c1b1a95b7fea..ebfad040b9d4 100644 --- a/engines/ags/engine/util/thread_pthread.h +++ b/engines/ags/engine/util/thread_pthread.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_PLATFORM__THREAD_PTHREAD_H #define __AGS_EE_PLATFORM__THREAD_PTHREAD_H diff --git a/engines/ags/engine/util/thread_std.h b/engines/ags/engine/util/thread_std.h index 1868ff92263f..bb56882d0a1a 100644 --- a/engines/ags/engine/util/thread_std.h +++ b/engines/ags/engine/util/thread_std.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_PLATFORM__THREAD_STD_H #define __AGS_EE_PLATFORM__THREAD_STD_H diff --git a/engines/ags/engine/util/thread_wii.h b/engines/ags/engine/util/thread_wii.h index 713a5e1ae471..f4baec16aecc 100644 --- a/engines/ags/engine/util/thread_wii.h +++ b/engines/ags/engine/util/thread_wii.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_PLATFORM__THREAD_WII_H #define __AGS_EE_PLATFORM__THREAD_WII_H diff --git a/engines/ags/engine/util/thread_windows.h b/engines/ags/engine/util/thread_windows.h index c3938f12b671..d8a09cf1be98 100644 --- a/engines/ags/engine/util/thread_windows.h +++ b/engines/ags/engine/util/thread_windows.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_EE_PLATFORM__THREAD_WINDOWS_H #define __AGS_EE_PLATFORM__THREAD_WINDOWS_H diff --git a/engines/ags/shared/ac/audiocliptype.cpp b/engines/ags/shared/ac/audiocliptype.cpp index b2b6df92879c..935b3b5e8c30 100644 --- a/engines/ags/shared/ac/audiocliptype.cpp +++ b/engines/ags/shared/ac/audiocliptype.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/audiocliptype.h" #include "util/stream.h" diff --git a/engines/ags/shared/ac/audiocliptype.h b/engines/ags/shared/ac/audiocliptype.h index 66185a6fc012..80628d3f05b8 100644 --- a/engines/ags/shared/ac/audiocliptype.h +++ b/engines/ags/shared/ac/audiocliptype.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_AUDIOCLIPTYPE_H #define __AC_AUDIOCLIPTYPE_H @@ -33,4 +41,4 @@ struct AudioClipType { void WriteToSavegame(Common::Stream *out) const; }; -#endif // __AC_AUDIOCLIPTYPE_H \ No newline at end of file +#endif // __AC_AUDIOCLIPTYPE_H diff --git a/engines/ags/shared/ac/characterinfo.cpp b/engines/ags/shared/ac/characterinfo.cpp index dbcbcf393476..efc3d87af7bb 100644 --- a/engines/ags/shared/ac/characterinfo.cpp +++ b/engines/ags/shared/ac/characterinfo.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/characterinfo.h" diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h index f3140d156397..adafa53d82c8 100644 --- a/engines/ags/shared/ac/characterinfo.h +++ b/engines/ags/shared/ac/characterinfo.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_CHARACTERINFO_H #define __AC_CHARACTERINFO_H @@ -141,4 +149,4 @@ struct OldCharacterInfo { #define COPY_CHAR_VAR(name) ci->name = oci->name void ConvertOldCharacterToNew (OldCharacterInfo *oci, CharacterInfo *ci); -#endif // __AC_CHARACTERINFO_H \ No newline at end of file +#endif // __AC_CHARACTERINFO_H diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index 5db922c15a00..cb5dc92f270d 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" #include "util/string.h" diff --git a/engines/ags/shared/ac/common.h b/engines/ags/shared/ac/common.h index 469605c32058..54b7e87edef3 100644 --- a/engines/ags/shared/ac/common.h +++ b/engines/ags/shared/ac/common.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_COMMON_H #define __AC_COMMON_H diff --git a/engines/ags/shared/ac/common_defines.h b/engines/ags/shared/ac/common_defines.h index dd70970dbb69..9cf5bfa55d04 100644 --- a/engines/ags/shared/ac/common_defines.h +++ b/engines/ags/shared/ac/common_defines.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_DEFINES_H #define __AC_DEFINES_H diff --git a/engines/ags/shared/ac/dialogtopic.cpp b/engines/ags/shared/ac/dialogtopic.cpp index 86d5dcd1836b..0def805ee250 100644 --- a/engines/ags/shared/ac/dialogtopic.cpp +++ b/engines/ags/shared/ac/dialogtopic.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dialogtopic.h" #include "util/stream.h" diff --git a/engines/ags/shared/ac/dialogtopic.h b/engines/ags/shared/ac/dialogtopic.h index df259811bf47..e26b7284b9fc 100644 --- a/engines/ags/shared/ac/dialogtopic.h +++ b/engines/ags/shared/ac/dialogtopic.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_AC__DIALOGTOPIC_H #define __AGS_CN_AC__DIALOGTOPIC_H @@ -65,4 +70,4 @@ struct DialogTopic { }; -#endif // __AGS_CN_AC__DIALOGTOPIC_H \ No newline at end of file +#endif // __AGS_CN_AC__DIALOGTOPIC_H diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp index 0f1115d29e36..820a67d31cb0 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/dynobj/scriptaudioclip.h" #include "util/stream.h" diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index 1349054ab70c..a9165dadbb15 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H #define __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H diff --git a/engines/ags/shared/ac/game_version.h b/engines/ags/shared/ac/game_version.h index 1c7ddeab52b9..745f181e8cf0 100644 --- a/engines/ags/shared/ac/game_version.h +++ b/engines/ags/shared/ac/game_version.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Game version constants and information diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp index 1c8a2cbae3f1..b5c0d9fbceb0 100644 --- a/engines/ags/shared/ac/gamesetupstruct.cpp +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/audiocliptype.h" #include "ac/gamesetupstruct.h" diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index 322fd4f453ed..b7f97cf632b8 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_AC__GAMESETUPSTRUCT_H #define __AGS_CN_AC__GAMESETUPSTRUCT_H diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp index f3cbe33b803f..e3faab100650 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.cpp +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/characterinfo.h" #include "ac/gamesetupstructbase.h" diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h index 1b075834e7f0..bb3fdaffa87f 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.h +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_AC__GAMESETUPSTRUCTBASE_H #define __AGS_CN_AC__GAMESETUPSTRUCTBASE_H @@ -219,4 +224,4 @@ struct GameSetupStructBase { int _screenUpscaleMult; }; -#endif // __AGS_CN_AC__GAMESETUPSTRUCTBASE_H \ No newline at end of file +#endif // __AGS_CN_AC__GAMESETUPSTRUCTBASE_H diff --git a/engines/ags/shared/ac/gamestructdefines.h b/engines/ags/shared/ac/gamestructdefines.h index 77ccee094d6d..4458a7de4970 100644 --- a/engines/ags/shared/ac/gamestructdefines.h +++ b/engines/ags/shared/ac/gamestructdefines.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_AC__GAMESTRUCTDEFINES_H #define __AGS_CN_AC__GAMESTRUCTDEFINES_H diff --git a/engines/ags/shared/ac/interfacebutton.h b/engines/ags/shared/ac/interfacebutton.h index 6a97a61d50c0..1f0caa63c2fa 100644 --- a/engines/ags/shared/ac/interfacebutton.h +++ b/engines/ags/shared/ac/interfacebutton.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_INTERFACEBUTTON_H #define __AC_INTERFACEBUTTON_H @@ -26,4 +34,4 @@ struct InterfaceButton { void set(int xx, int yy, int picc, int overpicc, int actionn); }; -#endif // __AC_INTERFACEBUTTON_H \ No newline at end of file +#endif // __AC_INTERFACEBUTTON_H diff --git a/engines/ags/shared/ac/interfaceelement.h b/engines/ags/shared/ac/interfaceelement.h index 4c3094be2d7e..0a899d0bcc36 100644 --- a/engines/ags/shared/ac/interfaceelement.h +++ b/engines/ags/shared/ac/interfaceelement.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_INTERFACEELEMENT_H #define __AC_INTERFACEELEMENT_H @@ -48,4 +56,4 @@ button[0].set(0,13,3,-1,0); } };*/ -#endif // __AC_INTERFACEELEMENT_H \ No newline at end of file +#endif // __AC_INTERFACEELEMENT_H diff --git a/engines/ags/shared/ac/inventoryiteminfo.cpp b/engines/ags/shared/ac/inventoryiteminfo.cpp index 910392dc321e..308178bbd970 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.cpp +++ b/engines/ags/shared/ac/inventoryiteminfo.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/inventoryiteminfo.h" #include "util/stream.h" diff --git a/engines/ags/shared/ac/inventoryiteminfo.h b/engines/ags/shared/ac/inventoryiteminfo.h index 3936ce6f087e..79d7e8360d19 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.h +++ b/engines/ags/shared/ac/inventoryiteminfo.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_INVENTORYITEMINFO_H #define __AC_INVENTORYITEMINFO_H @@ -32,4 +40,4 @@ struct InventoryItemInfo { void WriteToSavegame(Common::Stream *out) const; }; -#endif // __AC_INVENTORYITEMINFO_H \ No newline at end of file +#endif // __AC_INVENTORYITEMINFO_H diff --git a/engines/ags/shared/ac/mousecursor.cpp b/engines/ags/shared/ac/mousecursor.cpp index 1da9225e4069..f9d8c9f30dd2 100644 --- a/engines/ags/shared/ac/mousecursor.cpp +++ b/engines/ags/shared/ac/mousecursor.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/mousecursor.h" #include "util/stream.h" diff --git a/engines/ags/shared/ac/mousecursor.h b/engines/ags/shared/ac/mousecursor.h index 4207ccf5d455..fc7294fe7f0b 100644 --- a/engines/ags/shared/ac/mousecursor.h +++ b/engines/ags/shared/ac/mousecursor.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_MOUSECURSOR_H #define __AC_MOUSECURSOR_H @@ -37,4 +45,4 @@ struct MouseCursor { void WriteToSavegame(Common::Stream *out) const; }; -#endif // __AC_MOUSECURSOR_H \ No newline at end of file +#endif // __AC_MOUSECURSOR_H diff --git a/engines/ags/shared/ac/oldgamesetupstruct.h b/engines/ags/shared/ac/oldgamesetupstruct.h index 40dbfb7555f5..fa24eb727f95 100644 --- a/engines/ags/shared/ac/oldgamesetupstruct.h +++ b/engines/ags/shared/ac/oldgamesetupstruct.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_AC__OLDGAMESETUPSTRUCT_H #define __AGS_CN_AC__OLDGAMESETUPSTRUCT_H diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp index eecf492e6d62..bce6796b3764 100644 --- a/engines/ags/shared/ac/spritecache.cpp +++ b/engines/ags/shared/ac/spritecache.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // sprite caching system diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index 7296d227df71..8d547ae80fe7 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Sprite caching system. diff --git a/engines/ags/shared/ac/view.cpp b/engines/ags/shared/ac/view.cpp index f3699cb8da02..5130b23e3b09 100644 --- a/engines/ags/shared/ac/view.cpp +++ b/engines/ags/shared/ac/view.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/view.h" diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index 14afd2b2a7ec..65fb8bf89a93 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_VIEW_H #define __AC_VIEW_H @@ -77,4 +85,4 @@ struct ViewStruct272 { void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *newv); -#endif // __AC_VIEW_H \ No newline at end of file +#endif // __AC_VIEW_H diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp index a50bd46e3517..a90b0bf02f1d 100644 --- a/engines/ags/shared/ac/wordsdictionary.cpp +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h index bfb7247709fc..667b987145a4 100644 --- a/engines/ags/shared/ac/wordsdictionary.h +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_WORDSDICTIONARY_H #define __AC_WORDSDICTIONARY_H @@ -52,4 +60,4 @@ extern void encrypt_text(char *toenc); extern void write_string_encrypt(Common::Stream *out, const char *s); extern void write_dictionary (WordsDictionary *dict, Common::Stream *out); -#endif // __AC_WORDSDICTIONARY_H \ No newline at end of file +#endif // __AC_WORDSDICTIONARY_H diff --git a/engines/ags/shared/api/stream_api.h b/engines/ags/shared/api/stream_api.h index d78e08c7cc32..09db657444bb 100644 --- a/engines/ags/shared/api/stream_api.h +++ b/engines/ags/shared/api/stream_api.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // IAGSStream is a contract for stream class, provided by engine to plugin @@ -19,6 +29,7 @@ // endianness conversions and data padding, when needed. // //============================================================================= + #ifndef __AGS_CN_API__IAGSSTREAM_H #define __AGS_CN_API__IAGSSTREAM_H diff --git a/engines/ags/shared/core/asset.cpp b/engines/ags/shared/core/asset.cpp index 86483b9352c3..aded7d497ce6 100644 --- a/engines/ags/shared/core/asset.cpp +++ b/engines/ags/shared/core/asset.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/asset.h" diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index e619491e2e88..07505adeec77 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AssetInfo and AssetLibInfo - classes describing generic asset library. diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp index 26c5ca26c46b..1f38a81d1250 100644 --- a/engines/ags/shared/core/assetmanager.cpp +++ b/engines/ags/shared/core/assetmanager.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/assetmanager.h" #include "util/misc.h" // ci_fopen diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h index 8a765679ad2d..b1e4f5e0b00e 100644 --- a/engines/ags/shared/core/assetmanager.h +++ b/engines/ags/shared/core/assetmanager.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Asset manager class fore reading and writing game resources diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h index 05857771caa4..45a3dc9bdf10 100644 --- a/engines/ags/shared/core/def_version.h +++ b/engines/ags/shared/core/def_version.h @@ -1,3 +1,25 @@ +/* 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 __AGS_CN_CORE__DEFVERSION_H #define __AGS_CN_CORE__DEFVERSION_H diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h index b4ded89ed9f5..f1494d09399c 100644 --- a/engines/ags/shared/core/platform.h +++ b/engines/ags/shared/core/platform.h @@ -1,3 +1,25 @@ +/* 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 __AC_PLATFORM_H #define __AC_PLATFORM_H @@ -102,4 +124,4 @@ #define AGS_PLATFORM_DEBUG (0) #endif -#endif // __AC_PLATFORM_H \ No newline at end of file +#endif // __AC_PLATFORM_H diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index eadeb6ee34f0..03da2bbb7498 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Basic types definition // //============================================================================= + #ifndef __AGS_CN_CORE__TYPES_H #define __AGS_CN_CORE__TYPES_H diff --git a/engines/ags/shared/debugging/assert.h b/engines/ags/shared/debugging/assert.h index 34b1eb043f52..fd02a7f0bc73 100644 --- a/engines/ags/shared/debugging/assert.h +++ b/engines/ags/shared/debugging/assert.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Debug assertion tools // //============================================================================= + #ifndef __AGS_CN_DEBUG__ASSERT_H #define __AGS_CN_DEBUG__ASSERT_H diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp index 30558fe0e550..d474241d4c3e 100644 --- a/engines/ags/shared/debugging/debugmanager.cpp +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "debug/debugmanager.h" #include "util/string_types.h" diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index 48c8c9d17f84..fa100f746a63 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // AGS logging system is built with idea that the engine components should not @@ -33,6 +43,7 @@ // the message is permitted to be sent further to the printing handler, or not. // //============================================================================= + #ifndef __AGS_CN_DEBUG__DEBUGMANAGER_H #define __AGS_CN_DEBUG__DEBUGMANAGER_H diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h index 383b31a481f2..d77d4ba68d0d 100644 --- a/engines/ags/shared/debugging/out.h +++ b/engines/ags/shared/debugging/out.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Debug output interface provides functions which send a formatted message @@ -63,6 +73,7 @@ // component abortion is imminent. // //============================================================================= + #ifndef __AGS_CN_DEBUG__OUT_H #define __AGS_CN_DEBUG__OUT_H diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h index d77bcc7e520b..35eadc595d70 100644 --- a/engines/ags/shared/debugging/outputhandler.h +++ b/engines/ags/shared/debugging/outputhandler.h @@ -1,21 +1,32 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // IOutputHandler is a debug printing interface. Its implementations can be // registered as potential output for the debug log. // //============================================================================= + #ifndef __AGS_CN_DEBUG__OUTPUTHANDLER_H #define __AGS_CN_DEBUG__OUTPUTHANDLER_H diff --git a/engines/ags/shared/font/agsfontrenderer.h b/engines/ags/shared/font/agsfontrenderer.h index 2f27fcb6786a..f738a11effa7 100644 --- a/engines/ags/shared/font/agsfontrenderer.h +++ b/engines/ags/shared/font/agsfontrenderer.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_AGSFONTRENDERER_H #define __AC_AGSFONTRENDERER_H diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 68167f3f4bfe..9a9648fdaa88 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index f9004c980b44..8502109b87c1 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_FONT_H #define __AC_FONT_H diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp index 61a7ded323be..668b3ea57993 100644 --- a/engines/ags/shared/font/ttffontrenderer.cpp +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "core/platform.h" diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 156c46d9bad9..4a7cf6722bed 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_TTFFONTRENDERER_H #define __AC_TTFFONTRENDERER_H diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index 8f429f29ad86..341fe3a06d3e 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "font/wfnfont.h" diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index 7b7099957ffc..dd83c60b4736 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // WFNFont - an immutable AGS font object. diff --git a/engines/ags/shared/font/wfnfontrenderer.cpp b/engines/ags/shared/font/wfnfontrenderer.cpp index 165539f17ea9..828a4d9fad80 100644 --- a/engines/ags/shared/font/wfnfontrenderer.cpp +++ b/engines/ags/shared/font/wfnfontrenderer.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" // our_eip #include "core/assetmanager.h" diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index 740c15d8958c..a7cb943d1ee1 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_WFNFONTRENDERER_H #define __AC_WFNFONTRENDERER_H diff --git a/engines/ags/shared/game/customproperties.cpp b/engines/ags/shared/game/customproperties.cpp index fd39cc36df09..db1071874723 100644 --- a/engines/ags/shared/game/customproperties.cpp +++ b/engines/ags/shared/game/customproperties.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "game/customproperties.h" #include "util/stream.h" diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index afd819cd8550..e875cd9416e9 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Custom property structs @@ -22,6 +32,7 @@ // actual property values only if ones are different from defaults. // //============================================================================= + #ifndef __AGS_CN_GAME__CUSTOMPROPERTIES_H #define __AGS_CN_GAME__CUSTOMPROPERTIES_H diff --git a/engines/ags/shared/game/interactions.cpp b/engines/ags/shared/game/interactions.cpp index 0786c805b0cd..be596c8279d5 100644 --- a/engines/ags/shared/game/interactions.cpp +++ b/engines/ags/shared/game/interactions.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/common.h" // quit diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index 92e9320200cb..aae290ec8ebe 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Interaction structs. @@ -35,6 +45,7 @@ */ // //============================================================================= + #ifndef __AGS_CN_GAME__INTEREACTIONS_H #define __AGS_CN_GAME__INTEREACTIONS_H diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 94339a11f70d..a64e4c235b93 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/audiocliptype.h" diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index a5084003a84d..48d08ba1ec07 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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 unit provides functions for reading main game file into appropriate diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index bf75cde7f9c6..4d1a461d8a86 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // PluginInfo - a struct defining general information on game plugin. diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index 65a65e69c3e6..6f4670633f3f 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" // update_polled_stuff #include "ac/common_defines.h" diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index ce894721ce99..bf7244fac824 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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 unit provides functions for reading main game file into appropriate diff --git a/engines/ags/shared/game/room_file_deprecated.cpp b/engines/ags/shared/game/room_file_deprecated.cpp index 4424ddbdc03f..d902751ad7bf 100644 --- a/engines/ags/shared/game/room_file_deprecated.cpp +++ b/engines/ags/shared/game/room_file_deprecated.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Deprecated room stuff. Removed from room class and load routine because this diff --git a/engines/ags/shared/game/room_version.h b/engines/ags/shared/game/room_version.h index 0fdd0ea60201..47507757f12e 100644 --- a/engines/ags/shared/game/room_version.h +++ b/engines/ags/shared/game/room_version.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Room version constants and information diff --git a/engines/ags/shared/game/roomstruct.cpp b/engines/ags/shared/game/roomstruct.cpp index 168ed3875143..4dbbd5326326 100644 --- a/engines/ags/shared/game/roomstruct.cpp +++ b/engines/ags/shared/game/roomstruct.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" // update_polled_stuff_if_runtime #include "game/room_file.h" diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index 95e2f151d151..a6895058eb1d 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // RoomStruct, a class describing initial room data. @@ -34,6 +44,7 @@ // the engine code, and savegame read/write code. // //============================================================================= + #ifndef __AGS_CN_GAME__ROOMINFO_H #define __AGS_CN_GAME__ROOMINFO_H diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index f5ac74787dba..806976bad145 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "gfx/allegrobitmap.h" diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 66adc149f4c7..c7f437daa668 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Allegro lib based bitmap @@ -18,6 +28,7 @@ // clear that AGS.Native does not need allegro for drawing. // //============================================================================= + #ifndef __AGS_CN_GFX__ALLEGROBITMAP_H #define __AGS_CN_GFX__ALLEGROBITMAP_H diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp index c5dbcf843e72..8f55ef9ddc86 100644 --- a/engines/ags/shared/gfx/bitmap.cpp +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "gfx/bitmap.h" #include "util/memory.h" diff --git a/engines/ags/shared/gfx/bitmap.h b/engines/ags/shared/gfx/bitmap.h index 12eaca7d4430..6e58b95b729b 100644 --- a/engines/ags/shared/gfx/bitmap.h +++ b/engines/ags/shared/gfx/bitmap.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Base bitmap header diff --git a/engines/ags/shared/gfx/gfx_def.h b/engines/ags/shared/gfx/gfx_def.h index e883c1695e93..99254cc8b354 100644 --- a/engines/ags/shared/gfx/gfx_def.h +++ b/engines/ags/shared/gfx/gfx_def.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Graphic definitions and type/unit conversions. // //============================================================================= + #ifndef __AGS_CN_GFX__GFXDEF_H #define __AGS_CN_GFX__GFXDEF_H diff --git a/engines/ags/shared/gui/guibutton.cpp b/engines/ags/shared/gui/guibutton.cpp index 3ea836cdcb49..171a203d1213 100644 --- a/engines/ags/shared/gui/guibutton.cpp +++ b/engines/ags/shared/gui/guibutton.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/spritecache.h" #include "gui/guibutton.h" diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index 1ff172b20318..b32efe8ac865 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUIBUTTON_H #define __AC_GUIBUTTON_H diff --git a/engines/ags/shared/gui/guidefines.h b/engines/ags/shared/gui/guidefines.h index e57451d6991e..3d43b88b708f 100644 --- a/engines/ags/shared/gui/guidefines.h +++ b/engines/ags/shared/gui/guidefines.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUIDEFINES_H #define __AC_GUIDEFINES_H diff --git a/engines/ags/shared/gui/guiinv.cpp b/engines/ags/shared/gui/guiinv.cpp index 662ccb479b84..cd354b780546 100644 --- a/engines/ags/shared/gui/guiinv.cpp +++ b/engines/ags/shared/gui/guiinv.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/game_version.h" diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index 2fdad85a2c09..ee3959300e8b 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUIINV_H #define __AC_GUIINV_H diff --git a/engines/ags/shared/gui/guilabel.cpp b/engines/ags/shared/gui/guilabel.cpp index 698a9abc47f0..d814e04691bd 100644 --- a/engines/ags/shared/gui/guilabel.cpp +++ b/engines/ags/shared/gui/guilabel.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/game_version.h" #include "font/fonts.h" diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index 97665d65ff02..f9f5a70f0289 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUILABEL_H #define __AC_GUILABEL_H diff --git a/engines/ags/shared/gui/guilistbox.cpp b/engines/ags/shared/gui/guilistbox.cpp index aa57ca0b3e2f..831177466397 100644 --- a/engines/ags/shared/gui/guilistbox.cpp +++ b/engines/ags/shared/gui/guilistbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "font/fonts.h" #include "gui/guilistbox.h" diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index c919ac2d5a48..ce68c495a2c0 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUILISTBOX_H #define __AC_GUILISTBOX_H diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index 3e08125a64b1..1b87cf1829ad 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "ac/game_version.h" diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index b7aeb5b9140f..8166edc8760b 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUIMAIN_H #define __AC_GUIMAIN_H diff --git a/engines/ags/shared/gui/guiobject.cpp b/engines/ags/shared/gui/guiobject.cpp index 0e14b0ce590d..7ec7d4cf20e9 100644 --- a/engines/ags/shared/gui/guiobject.cpp +++ b/engines/ags/shared/gui/guiobject.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/common.h" // quit #include "gui/guimain.h" diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h index 4067a1b8985f..0d85a68f8212 100644 --- a/engines/ags/shared/gui/guiobject.h +++ b/engines/ags/shared/gui/guiobject.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUIOBJECT_H #define __AC_GUIOBJECT_H diff --git a/engines/ags/shared/gui/guislider.cpp b/engines/ags/shared/gui/guislider.cpp index 492f70b41f0c..a58864572837 100644 --- a/engines/ags/shared/gui/guislider.cpp +++ b/engines/ags/shared/gui/guislider.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "ac/spritecache.h" #include "gui/guimain.h" diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index 86078a29e05d..93b124130271 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUISLIDER_H #define __AC_GUISLIDER_H diff --git a/engines/ags/shared/gui/guitextbox.cpp b/engines/ags/shared/gui/guitextbox.cpp index 5e05e289d6a8..1fae191f3c3f 100644 --- a/engines/ags/shared/gui/guitextbox.cpp +++ b/engines/ags/shared/gui/guitextbox.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "font/fonts.h" #include "gui/guimain.h" diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index cdbad55ad856..8c37567dd3f8 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_GUITEXTBOX_H #define __AC_GUITEXTBOX_H diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp index 8f420b905896..23c511cce67e 100644 --- a/engines/ags/shared/script/cc_error.cpp +++ b/engines/ags/shared/script/cc_error.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/shared/script/cc_error.h b/engines/ags/shared/script/cc_error.h index 4b322379d102..7f9c49ae4b0a 100644 --- a/engines/ags/shared/script/cc_error.h +++ b/engines/ags/shared/script/cc_error.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // 'C'-style script compiler diff --git a/engines/ags/shared/script/cc_options.cpp b/engines/ags/shared/script/cc_options.cpp index 556fdc7e798f..f56579d4bf33 100644 --- a/engines/ags/shared/script/cc_options.cpp +++ b/engines/ags/shared/script/cc_options.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "cc_options.h" diff --git a/engines/ags/shared/script/cc_options.h b/engines/ags/shared/script/cc_options.h index fd179605d4db..beeef080701e 100644 --- a/engines/ags/shared/script/cc_options.h +++ b/engines/ags/shared/script/cc_options.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // 'C'-style script compiler diff --git a/engines/ags/shared/script/cc_script.cpp b/engines/ags/shared/script/cc_script.cpp index b2383e21c2d4..cf405d3e47c2 100644 --- a/engines/ags/shared/script/cc_script.cpp +++ b/engines/ags/shared/script/cc_script.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index e422893af795..c8a69186d59b 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // 'C'-style script compiler diff --git a/engines/ags/shared/script/script_common.h b/engines/ags/shared/script/script_common.h index 5dcf0b5d7d26..cd6a0ce2ed36 100644 --- a/engines/ags/shared/script/script_common.h +++ b/engines/ags/shared/script/script_common.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // 'C'-style script compiler diff --git a/engines/ags/shared/util/alignedstream.cpp b/engines/ags/shared/util/alignedstream.cpp index b60a00e0baa6..c65a54ed6b31 100644 --- a/engines/ags/shared/util/alignedstream.cpp +++ b/engines/ags/shared/util/alignedstream.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "debug/assert.h" #include "util/alignedstream.h" diff --git a/engines/ags/shared/util/alignedstream.h b/engines/ags/shared/util/alignedstream.h index c0aed86d7cfa..6b1a4576c880 100644 --- a/engines/ags/shared/util/alignedstream.h +++ b/engines/ags/shared/util/alignedstream.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Class AlignedStream @@ -31,6 +41,7 @@ // position will break padding count logic. // //============================================================================= + #ifndef __AGS_CN_UTIL__ALIGNEDSTREAM_H #define __AGS_CN_UTIL__ALIGNEDSTREAM_H diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h index 398ca7dad45f..6081aef91704 100644 --- a/engines/ags/shared/util/bbop.h +++ b/engines/ags/shared/util/bbop.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Various utility bit and byte operations diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index a67d95415f1c..5198b49b571b 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include #include diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h index 10e36dc9a79a..3652c3fe0de1 100644 --- a/engines/ags/shared/util/bufferedstream.h +++ b/engines/ags/shared/util/bufferedstream.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp index 8561fb687592..cf542ea7ad1f 100644 --- a/engines/ags/shared/util/compress.cpp +++ b/engines/ags/shared/util/compress.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ #ifdef _MANAGED // ensure this doesn't get compiled to .NET IL diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h index 356f8782e000..eb8e6c7d9346 100644 --- a/engines/ags/shared/util/compress.h +++ b/engines/ags/shared/util/compress.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AC_COMPRESS_H #define __AC_COMPRESS_H diff --git a/engines/ags/shared/util/datastream.cpp b/engines/ags/shared/util/datastream.cpp index 4348da9e837b..a05c4a7821f5 100644 --- a/engines/ags/shared/util/datastream.cpp +++ b/engines/ags/shared/util/datastream.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/datastream.h" diff --git a/engines/ags/shared/util/datastream.h b/engines/ags/shared/util/datastream.h index 2d1f489c8528..c3b530bba029 100644 --- a/engines/ags/shared/util/datastream.h +++ b/engines/ags/shared/util/datastream.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Standard AGS stream implementation for reading raw data with support for @@ -17,6 +27,7 @@ // class and provide implementation for basic reading and writing only. // //============================================================================= + #ifndef __AGS_CN_UTIL__DATASTREAM_H #define __AGS_CN_UTIL__DATASTREAM_H diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp index acea430a9e3e..8ed1095f7a8e 100644 --- a/engines/ags/shared/util/directory.cpp +++ b/engines/ags/shared/util/directory.cpp @@ -1,3 +1,24 @@ +/* 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 "core/platform.h" #include diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h index b5a634975663..881c8aa59dbb 100644 --- a/engines/ags/shared/util/directory.h +++ b/engines/ags/shared/util/directory.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Platform-independent Directory functions // //============================================================================= + #ifndef __AGS_CN_UTIL__DIRECTORY_H #define __AGS_CN_UTIL__DIRECTORY_H diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h index 1ada93918ce7..599ab1aeb205 100644 --- a/engines/ags/shared/util/error.h +++ b/engines/ags/shared/util/error.h @@ -1,21 +1,32 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Universal error class, that may be used both as a return value or // thrown as an exception. // //============================================================================= + #ifndef __AGS_CN_UTIL__ERROR_H #define __AGS_CN_UTIL__ERROR_H diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp index 8f1fb3f6febf..71f2a6368d43 100644 --- a/engines/ags/shared/util/file.cpp +++ b/engines/ags/shared/util/file.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/file.h" diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h index c81e4140aa97..8a513eeafd06 100644 --- a/engines/ags/shared/util/file.h +++ b/engines/ags/shared/util/file.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Platform-independent File functions // //============================================================================= + #ifndef __AGS_CN_UTIL__FILE_H #define __AGS_CN_UTIL__FILE_H diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index 6c681285b940..2ce838035772 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/filestream.h" diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index d083da355f29..55dba895db01 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_UTIL__FILESTREAM_H #define __AGS_CN_UTIL__FILESTREAM_H diff --git a/engines/ags/shared/util/geometry.cpp b/engines/ags/shared/util/geometry.cpp index 06f9358df228..5bde02d5b7b1 100644 --- a/engines/ags/shared/util/geometry.cpp +++ b/engines/ags/shared/util/geometry.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/geometry.h" #include #include diff --git a/engines/ags/shared/util/geometry.h b/engines/ags/shared/util/geometry.h index a3e3906736e0..acfc8536cd9b 100644 --- a/engines/ags/shared/util/geometry.h +++ b/engines/ags/shared/util/geometry.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Geometry data structures and helper functions // //============================================================================= + #ifndef __AGS_CN_UTIL__GEOMETRY_H #define __AGS_CN_UTIL__GEOMETRY_H diff --git a/engines/ags/shared/util/ini_util.cpp b/engines/ags/shared/util/ini_util.cpp index 2ee0943d9e45..5557da9cf268 100644 --- a/engines/ags/shared/util/ini_util.cpp +++ b/engines/ags/shared/util/ini_util.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "util/file.h" diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h index 50eca7f2a580..7ca76ca51425 100644 --- a/engines/ags/shared/util/ini_util.h +++ b/engines/ags/shared/util/ini_util.h @@ -1,21 +1,32 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Functions for exchanging configuration data between key-value tree and // INI file. // //============================================================================= + #ifndef __AGS_CN_UTIL__INIUTIL_H #define __AGS_CN_UTIL__INIUTIL_H diff --git a/engines/ags/shared/util/inifile.cpp b/engines/ags/shared/util/inifile.cpp index 10665dd2dc70..07f43025c22d 100644 --- a/engines/ags/shared/util/inifile.cpp +++ b/engines/ags/shared/util/inifile.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h index 0f26ce5cfb80..b77bf5ed05f9 100644 --- a/engines/ags/shared/util/inifile.h +++ b/engines/ags/shared/util/inifile.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // IniFile class defines contents of the configuration file. @@ -19,6 +29,7 @@ // create a proper map to store items, from IniFile contents. // //============================================================================= + #ifndef __AGS_CN_UTIL__INIFILE_H #define __AGS_CN_UTIL__INIFILE_H diff --git a/engines/ags/shared/util/lzw.cpp b/engines/ags/shared/util/lzw.cpp index 7eadcd8e281f..85ca1454a04f 100644 --- a/engines/ags/shared/util/lzw.cpp +++ b/engines/ags/shared/util/lzw.cpp @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // LZW compression -- the LZW/GIF patent has expired, so we can use it now!!! diff --git a/engines/ags/shared/util/lzw.h b/engines/ags/shared/util/lzw.h index b3c1af849b27..46af7bbcc2ab 100644 --- a/engines/ags/shared/util/lzw.h +++ b/engines/ags/shared/util/lzw.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_UTIL__LZW_H #define __AGS_CN_UTIL__LZW_H diff --git a/engines/ags/shared/util/math.h b/engines/ags/shared/util/math.h index 07367591984b..85be2a33c847 100644 --- a/engines/ags/shared/util/math.h +++ b/engines/ags/shared/util/math.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Helper math functions // //============================================================================= + #ifndef __AGS_CN_UTIL__MATH_H #define __AGS_CN_UTIL__MATH_H diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h index 5e049d74e595..f84666b090b2 100644 --- a/engines/ags/shared/util/memory.h +++ b/engines/ags/shared/util/memory.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Memory utils and algorithms // //============================================================================= + #ifndef __AGS_CN_UTIL__MEMORY_H #define __AGS_CN_UTIL__MEMORY_H diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp index 8848b7e02550..ea6c4c96c481 100644 --- a/engines/ags/shared/util/misc.cpp +++ b/engines/ags/shared/util/misc.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ /* Copyright (c) 2003, Shawn R. Walker diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h index 8e5e5916c105..cd97e50379c6 100644 --- a/engines/ags/shared/util/misc.h +++ b/engines/ags/shared/util/misc.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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. + * + */ /* Copyright (c) 2003, Shawn R. Walker diff --git a/engines/ags/shared/util/multifilelib.h b/engines/ags/shared/util/multifilelib.h index a0e1192c04f8..5f73e386d4f7 100644 --- a/engines/ags/shared/util/multifilelib.h +++ b/engines/ags/shared/util/multifilelib.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // A packed data file header and functions for reading it from the stream. diff --git a/engines/ags/shared/util/mutifilelib.cpp b/engines/ags/shared/util/mutifilelib.cpp index d0154662ddea..7f053bb74cf5 100644 --- a/engines/ags/shared/util/mutifilelib.cpp +++ b/engines/ags/shared/util/mutifilelib.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/bbop.h" #include "util/multifilelib.h" diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp index 88e305f05f65..cd007457983b 100644 --- a/engines/ags/shared/util/path.cpp +++ b/engines/ags/shared/util/path.cpp @@ -1,3 +1,24 @@ +/* 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 "core/platform.h" #if AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h index edcb82d1da93..9083f5c88634 100644 --- a/engines/ags/shared/util/path.h +++ b/engines/ags/shared/util/path.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Platform-independent Path functions // //============================================================================= + #ifndef __AGS_CN_UTIL__PATH_H #define __AGS_CN_UTIL__PATH_H diff --git a/engines/ags/shared/util/proxystream.cpp b/engines/ags/shared/util/proxystream.cpp index 164ca737ebb0..f22465a9b27b 100644 --- a/engines/ags/shared/util/proxystream.cpp +++ b/engines/ags/shared/util/proxystream.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/proxystream.h" diff --git a/engines/ags/shared/util/proxystream.h b/engines/ags/shared/util/proxystream.h index fa09ed627d51..7587e779f74f 100644 --- a/engines/ags/shared/util/proxystream.h +++ b/engines/ags/shared/util/proxystream.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_UTIL__PROXYSTREAM_H #define __AGS_CN_UTIL__PROXYSTREAM_H diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h index 4ba211088b40..726b809fac7c 100644 --- a/engines/ags/shared/util/stdio_compat.h +++ b/engines/ags/shared/util/stdio_compat.h @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_CN_UTIL__STDIOCOMPAT_H #define __AGS_CN_UTIL__STDIOCOMPAT_H diff --git a/engines/ags/shared/util/stream.cpp b/engines/ags/shared/util/stream.cpp index c991cdfff69f..48c6388ad796 100644 --- a/engines/ags/shared/util/stream.cpp +++ b/engines/ags/shared/util/stream.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/stream.h" diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index 26ad90321881..80c25a1df7a6 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Base stream class. @@ -21,6 +31,7 @@ // Streams that wrap other streams should inherit ProxyStream. // //============================================================================= + #ifndef __AGS_CN_UTIL__STREAM_H #define __AGS_CN_UTIL__STREAM_H diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp index 8f37fb2c5bfd..37db3ead1264 100644 --- a/engines/ags/shared/util/string.cpp +++ b/engines/ags/shared/util/string.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include #include diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index f96208a1df75..94a84ab180ab 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -1,16 +1,25 @@ +/* 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. + * + */ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// //============================================================================= // // String class with simple memory management and copy-on-write behavior. @@ -33,6 +42,7 @@ // string. // //============================================================================= + #ifndef __AGS_CN_UTIL__STRING_H #define __AGS_CN_UTIL__STRING_H diff --git a/engines/ags/shared/util/string_compat.h b/engines/ags/shared/util/string_compat.h index 209fab8bb37d..48a06f4312a5 100644 --- a/engines/ags/shared/util/string_compat.h +++ b/engines/ags/shared/util/string_compat.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_CN_UTIL__STRINGCOMPAT_H #define __AGS_CN_UTIL__STRINGCOMPAT_H diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index 2795be49e87a..7359913190dc 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 __AGS_CN_UTIL__STRINGTYPES_H #define __AGS_CN_UTIL__STRINGTYPES_H diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp index c022f0c81abb..67c22b4556c8 100644 --- a/engines/ags/shared/util/string_utils.cpp +++ b/engines/ags/shared/util/string_utils.cpp @@ -1,16 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include #include "core/platform.h" diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h index b0dbdae9406f..95028808c774 100644 --- a/engines/ags/shared/util/string_utils.h +++ b/engines/ags/shared/util/string_utils.h @@ -1,20 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// -// -//============================================================================= +/* 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 __AGS_CN_UTIL__STRINGUTILS_H #define __AGS_CN_UTIL__STRINGUTILS_H diff --git a/engines/ags/shared/util/textreader.h b/engines/ags/shared/util/textreader.h index f7273ced30da..f8fb7b23903e 100644 --- a/engines/ags/shared/util/textreader.h +++ b/engines/ags/shared/util/textreader.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Specialized interface for reading plain text from the underlying source // //============================================================================= + #ifndef __AGS_CN_UTIL__TEXTREADER_H #define __AGS_CN_UTIL__TEXTREADER_H diff --git a/engines/ags/shared/util/textstreamreader.cpp b/engines/ags/shared/util/textstreamreader.cpp index d0f4e5dc2e6e..90e01d84f0e9 100644 --- a/engines/ags/shared/util/textstreamreader.cpp +++ b/engines/ags/shared/util/textstreamreader.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "util/math.h" #include "util/stream.h" diff --git a/engines/ags/shared/util/textstreamreader.h b/engines/ags/shared/util/textstreamreader.h index 4f69dc02b004..8301f5236b8c 100644 --- a/engines/ags/shared/util/textstreamreader.h +++ b/engines/ags/shared/util/textstreamreader.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Class for reading plain text from the stream // //============================================================================= + #ifndef __AGS_CN_UTIL__TEXTSTREAMREADER_H #define __AGS_CN_UTIL__TEXTSTREAMREADER_H diff --git a/engines/ags/shared/util/textstreamwriter.cpp b/engines/ags/shared/util/textstreamwriter.cpp index 6345c52fb6f3..927788cf9158 100644 --- a/engines/ags/shared/util/textstreamwriter.cpp +++ b/engines/ags/shared/util/textstreamwriter.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include // sprintf diff --git a/engines/ags/shared/util/textstreamwriter.h b/engines/ags/shared/util/textstreamwriter.h index 4024a05df399..72f0fdad1aea 100644 --- a/engines/ags/shared/util/textstreamwriter.h +++ b/engines/ags/shared/util/textstreamwriter.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Class for writing plain text to the stream // //============================================================================= + #ifndef __AGS_CN_UTIL__TEXTSTREAMWRITER_H #define __AGS_CN_UTIL__TEXTSTREAMWRITER_H diff --git a/engines/ags/shared/util/textwriter.h b/engines/ags/shared/util/textwriter.h index b254202ee9ea..ce07cb6b91b0 100644 --- a/engines/ags/shared/util/textwriter.h +++ b/engines/ags/shared/util/textwriter.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Specialized interface for writing plain text to the underlying source // //============================================================================= + #ifndef __AGS_CN_UTIL__TEXTWRITER_H #define __AGS_CN_UTIL__TEXTWRITER_H diff --git a/engines/ags/shared/util/version.cpp b/engines/ags/shared/util/version.cpp index 2f8df6110e9f..ab14ea0c7ab0 100644 --- a/engines/ags/shared/util/version.cpp +++ b/engines/ags/shared/util/version.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 #include "util/version.h" diff --git a/engines/ags/shared/util/version.h b/engines/ags/shared/util/version.h index 69696ac681fe..c74ccdd29114 100644 --- a/engines/ags/shared/util/version.h +++ b/engines/ags/shared/util/version.h @@ -1,20 +1,31 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // Class, depicting version of the AGS engine // //============================================================================= + #ifndef __AGS_CN_MAIN__VERSION_H #define __AGS_CN_MAIN__VERSION_H diff --git a/engines/ags/shared/util/wgt2allg.cpp b/engines/ags/shared/util/wgt2allg.cpp index 31a81523d102..0dff3610a3ff 100644 --- a/engines/ags/shared/util/wgt2allg.cpp +++ b/engines/ags/shared/util/wgt2allg.cpp @@ -1,16 +1,24 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= +/* 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 "core/assetmanager.h" #include "gfx/bitmap.h" @@ -213,4 +221,4 @@ extern "C" #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index 8036d4ffb13e..82e954bdcbc8 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // WGT -> Allegro portability interface From 5130eb34c701982f2031046adf89d627788214fc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 09:50:04 -0800 Subject: [PATCH 005/215] AGS: Cleaning up header file guard defines --- engines/ags/engine/ac/asset_helper.h | 7 +- engines/ags/engine/ac/audiochannel.h | 6 +- engines/ags/engine/ac/audioclip.h | 6 +- engines/ags/engine/ac/button.h | 11 +- engines/ags/engine/ac/cdaudio.h | 6 +- engines/ags/engine/ac/character.h | 6 +- engines/ags/engine/ac/charactercache.h | 6 +- engines/ags/engine/ac/characterextras.h | 6 +- engines/ags/engine/ac/datetime.h | 6 +- engines/ags/engine/ac/dialog.h | 6 +- .../ags/engine/ac/dialogoptionsrendering.h | 6 +- engines/ags/engine/ac/display.h | 6 +- engines/ags/engine/ac/draw.h | 6 +- engines/ags/engine/ac/draw_software.h | 6 +- engines/ags/engine/ac/drawingsurface.h | 6 +- engines/ags/engine/ac/dynamicsprite.h | 6 +- .../ags/engine/ac/dynobj/all_dynamicclasses.h | 6 +- .../ags/engine/ac/dynobj/all_scriptclasses.h | 6 +- .../engine/ac/dynobj/cc_agsdynamicobject.h | 6 +- .../ags/engine/ac/dynobj/cc_audiochannel.h | 6 +- engines/ags/engine/ac/dynobj/cc_audioclip.h | 6 +- engines/ags/engine/ac/dynobj/cc_character.h | 6 +- engines/ags/engine/ac/dynobj/cc_dialog.h | 6 +- .../ags/engine/ac/dynobj/cc_dynamicarray.h | 4 +- .../ags/engine/ac/dynobj/cc_dynamicobject.h | 7 +- .../cc_dynamicobject_addr_and_manager.h | 4 +- engines/ags/engine/ac/dynobj/cc_gui.h | 6 +- engines/ags/engine/ac/dynobj/cc_guiobject.h | 6 +- engines/ags/engine/ac/dynobj/cc_hotspot.h | 6 +- engines/ags/engine/ac/dynobj/cc_inventory.h | 6 +- engines/ags/engine/ac/dynobj/cc_object.h | 6 +- engines/ags/engine/ac/dynobj/cc_region.h | 6 +- engines/ags/engine/ac/dynobj/cc_serializer.h | 6 +- .../ags/engine/ac/dynobj/managedobjectpool.h | 6 +- .../ags/engine/ac/dynobj/scriptaudiochannel.h | 6 +- engines/ags/engine/ac/dynobj/scriptcamera.h | 6 +- .../ags/engine/ac/dynobj/scriptcontainers.h | 6 +- engines/ags/engine/ac/dynobj/scriptdatetime.h | 6 +- engines/ags/engine/ac/dynobj/scriptdialog.h | 6 +- .../ac/dynobj/scriptdialogoptionsrendering.h | 6 +- engines/ags/engine/ac/dynobj/scriptdict.h | 6 +- .../engine/ac/dynobj/scriptdrawingsurface.h | 6 +- .../engine/ac/dynobj/scriptdynamicsprite.h | 6 +- engines/ags/engine/ac/dynobj/scriptfile.h | 6 +- engines/ags/engine/ac/dynobj/scriptgui.h | 6 +- engines/ags/engine/ac/dynobj/scripthotspot.h | 6 +- engines/ags/engine/ac/dynobj/scriptinvitem.h | 6 +- engines/ags/engine/ac/dynobj/scriptmouse.h | 6 +- engines/ags/engine/ac/dynobj/scriptobject.h | 6 +- engines/ags/engine/ac/dynobj/scriptoverlay.h | 6 +- engines/ags/engine/ac/dynobj/scriptregion.h | 6 +- engines/ags/engine/ac/dynobj/scriptset.h | 6 +- engines/ags/engine/ac/dynobj/scriptstring.h | 6 +- engines/ags/engine/ac/dynobj/scriptsystem.h | 6 +- .../ags/engine/ac/dynobj/scriptuserobject.h | 6 +- .../ags/engine/ac/dynobj/scriptviewframe.h | 6 +- engines/ags/engine/ac/dynobj/scriptviewport.h | 6 +- engines/ags/engine/ac/event.h | 7 +- engines/ags/engine/ac/file.h | 6 +- engines/ags/engine/ac/game.h | 6 +- engines/ags/engine/ac/gamesetup.h | 6 +- engines/ags/engine/ac/gamestate.h | 7 +- engines/ags/engine/ac/global_audio.h | 6 +- engines/ags/engine/ac/global_button.h | 6 +- engines/ags/engine/ac/global_character.h | 6 +- engines/ags/engine/ac/global_datetime.h | 6 +- engines/ags/engine/ac/global_debug.h | 6 +- engines/ags/engine/ac/global_dialog.h | 6 +- engines/ags/engine/ac/global_display.h | 6 +- engines/ags/engine/ac/global_drawingsurface.h | 6 +- engines/ags/engine/ac/global_dynamicsprite.h | 6 +- engines/ags/engine/ac/global_file.h | 6 +- engines/ags/engine/ac/global_game.h | 6 +- engines/ags/engine/ac/global_gui.h | 6 +- engines/ags/engine/ac/global_hotspot.h | 6 +- engines/ags/engine/ac/global_inventoryitem.h | 6 +- engines/ags/engine/ac/global_invwindow.h | 6 +- engines/ags/engine/ac/global_label.h | 6 +- engines/ags/engine/ac/global_listbox.h | 6 +- engines/ags/engine/ac/global_mouse.h | 6 +- engines/ags/engine/ac/global_object.h | 6 +- engines/ags/engine/ac/global_overlay.h | 6 +- engines/ags/engine/ac/global_palette.h | 6 +- engines/ags/engine/ac/global_parser.h | 6 +- engines/ags/engine/ac/global_plugin.h | 6 +- engines/ags/engine/ac/global_record.h | 6 +- engines/ags/engine/ac/global_region.h | 6 +- engines/ags/engine/ac/global_room.h | 6 +- engines/ags/engine/ac/global_screen.h | 6 +- engines/ags/engine/ac/global_slider.h | 6 +- engines/ags/engine/ac/global_string.h | 6 +- engines/ags/engine/ac/global_textbox.h | 6 +- engines/ags/engine/ac/global_timer.h | 6 +- engines/ags/engine/ac/global_translation.h | 6 +- engines/ags/engine/ac/global_video.h | 6 +- engines/ags/engine/ac/global_viewframe.h | 6 +- engines/ags/engine/ac/global_viewport.h | 6 +- engines/ags/engine/ac/global_walkablearea.h | 6 +- engines/ags/engine/ac/global_walkbehind.h | 6 +- engines/ags/engine/ac/gui.h | 6 +- engines/ags/engine/ac/guicontrol.h | 6 +- engines/ags/engine/ac/hotspot.h | 6 +- engines/ags/engine/ac/inventoryitem.h | 6 +- engines/ags/engine/ac/invwindow.h | 6 +- engines/ags/engine/ac/keycode.h | 6 +- engines/ags/engine/ac/label.h | 6 +- engines/ags/engine/ac/lipsync.h | 6 +- engines/ags/engine/ac/listbox.h | 6 +- engines/ags/engine/ac/math.h | 6 +- engines/ags/engine/ac/mouse.h | 6 +- engines/ags/engine/ac/movelist.h | 6 +- engines/ags/engine/ac/object.h | 7 +- engines/ags/engine/ac/objectcache.h | 6 +- engines/ags/engine/ac/overlay.h | 7 +- engines/ags/engine/ac/parser.h | 6 +- engines/ags/engine/ac/path_helper.h | 6 +- engines/ags/engine/ac/properties.h | 6 +- engines/ags/engine/ac/region.h | 6 +- engines/ags/engine/ac/richgamemedia.h | 6 +- engines/ags/engine/ac/room.h | 6 +- engines/ags/engine/ac/roomobject.h | 6 +- engines/ags/engine/ac/roomstatus.h | 6 +- engines/ags/engine/ac/route_finder.h | 6 +- engines/ags/engine/ac/route_finder_impl.h | 6 +- .../ags/engine/ac/route_finder_impl_legacy.h | 6 +- engines/ags/engine/ac/runtime_defines.h | 6 +- engines/ags/engine/ac/screen.h | 6 +- engines/ags/engine/ac/screenoverlay.h | 6 +- engines/ags/engine/ac/slider.h | 6 +- engines/ags/engine/ac/speech.h | 6 +- engines/ags/engine/ac/sprite.h | 6 +- engines/ags/engine/ac/spritelistentry.h | 6 +- .../ags/engine/ac/statobj/agsstaticobject.h | 6 +- engines/ags/engine/ac/statobj/staticarray.h | 6 +- engines/ags/engine/ac/statobj/staticobject.h | 6 +- engines/ags/engine/ac/string.h | 6 +- engines/ags/engine/ac/sys_events.h | 6 +- engines/ags/engine/ac/system.h | 6 +- engines/ags/engine/ac/textbox.h | 6 +- engines/ags/engine/ac/timer.h | 6 +- engines/ags/engine/ac/topbarsettings.h | 6 +- engines/ags/engine/ac/translation.h | 6 +- engines/ags/engine/ac/tree_map.h | 6 +- engines/ags/engine/ac/viewframe.h | 6 +- engines/ags/engine/ac/walkablearea.h | 6 +- engines/ags/engine/ac/walkbehind.h | 6 +- .../ags/engine/debugging/agseditordebugger.h | 6 +- .../engine/debugging/consoleoutputtarget.h | 6 +- engines/ags/engine/debugging/debug_log.h | 6 +- engines/ags/engine/debugging/debugger.h | 6 +- .../ags/engine/debugging/dummyagsdebugger.h | 6 +- .../engine/debugging/filebasedagsdebugger.h | 6 +- engines/ags/engine/debugging/logfile.h | 6 +- engines/ags/engine/debugging/messagebuffer.h | 6 +- engines/ags/engine/game/game_init.h | 6 +- engines/ags/engine/game/savegame.h | 6 +- engines/ags/engine/game/savegame_components.h | 6 +- engines/ags/engine/game/savegame_internal.h | 6 +- engines/ags/engine/game/viewport.h | 6 +- engines/ags/engine/gfx/ali3dexception.h | 6 +- engines/ags/engine/gfx/ali3dogl.h | 6 +- engines/ags/engine/gfx/ali3dsw.h | 6 +- engines/ags/engine/gfx/blender.h | 6 +- engines/ags/engine/gfx/ddb.h | 6 +- engines/ags/engine/gfx/gfx_util.h | 6 +- engines/ags/engine/gfx/gfxdefines.h | 6 +- engines/ags/engine/gfx/gfxdriverbase.h | 6 +- engines/ags/engine/gfx/gfxdriverfactory.h | 6 +- engines/ags/engine/gfx/gfxdriverfactorybase.h | 6 +- engines/ags/engine/gfx/gfxfilter.h | 6 +- engines/ags/engine/gfx/gfxfilter_aad3d.h | 6 +- engines/ags/engine/gfx/gfxfilter_aaogl.h | 6 +- engines/ags/engine/gfx/gfxfilter_allegro.h | 6 +- engines/ags/engine/gfx/gfxfilter_d3d.h | 6 +- engines/ags/engine/gfx/gfxfilter_hqx.h | 6 +- engines/ags/engine/gfx/gfxfilter_ogl.h | 6 +- engines/ags/engine/gfx/gfxfilter_scaling.h | 6 +- engines/ags/engine/gfx/gfxmodelist.h | 7 +- engines/ags/engine/gfx/graphicsdriver.h | 6 +- engines/ags/engine/gfx/hq2x3x.h | 6 +- engines/ags/engine/gui/animatingguibutton.h | 6 +- engines/ags/engine/gui/cscidialog.h | 6 +- engines/ags/engine/gui/guidialog.h | 6 +- engines/ags/engine/gui/guidialogdefines.h | 6 +- .../ags/engine/gui/guidialoginternaldefs.h | 6 +- engines/ags/engine/gui/mycontrols.h | 6 +- engines/ags/engine/gui/mylabel.h | 6 +- engines/ags/engine/gui/mylistbox.h | 6 +- engines/ags/engine/gui/mypushbutton.h | 6 +- engines/ags/engine/gui/mytextbox.h | 6 +- engines/ags/engine/gui/newcontrol.h | 6 +- engines/ags/engine/main/config.h | 6 +- engines/ags/engine/main/engine.h | 6 +- engines/ags/engine/main/engine_setup.h | 6 +- engines/ags/engine/main/game_file.h | 6 +- engines/ags/engine/main/game_run.h | 6 +- engines/ags/engine/main/game_start.h | 6 +- engines/ags/engine/main/graphics_mode.h | 6 +- engines/ags/engine/main/main.h | 6 +- engines/ags/engine/main/main_allegro.h | 6 +- engines/ags/engine/main/maindefines_ex.h | 6 +- engines/ags/engine/main/mainheader.h | 6 +- engines/ags/engine/main/quit.h | 6 +- engines/ags/engine/main/update.h | 6 +- engines/ags/engine/media/audio/ambientsound.h | 6 +- engines/ags/engine/media/audio/audio.h | 6 +- engines/ags/engine/media/audio/audio_system.h | 4 +- engines/ags/engine/media/audio/audiodefines.h | 6 +- .../engine/media/audio/audiointernaldefs.h | 6 +- .../ags/engine/media/audio/clip_mydumbmod.h | 6 +- engines/ags/engine/media/audio/clip_myjgmod.h | 6 +- engines/ags/engine/media/audio/clip_mymidi.h | 6 +- engines/ags/engine/media/audio/clip_mymp3.h | 6 +- engines/ags/engine/media/audio/clip_myogg.h | 6 +- .../ags/engine/media/audio/clip_mystaticmp3.h | 6 +- .../ags/engine/media/audio/clip_mystaticogg.h | 6 +- engines/ags/engine/media/audio/clip_mywave.h | 6 +- .../ags/engine/media/audio/queuedaudioitem.h | 6 +- engines/ags/engine/media/audio/sound.h | 6 +- engines/ags/engine/media/audio/soundcache.h | 6 +- engines/ags/engine/media/audio/soundclip.h | 6 +- engines/ags/engine/media/video/VMR9Graph.h | 4 +- engines/ags/engine/media/video/video.h | 6 +- .../engine/platform/base/agsplatformdriver.h | 6 +- engines/ags/engine/platform/util/pe.h | 6 +- .../debugging/namedpipesagsdebugger.cpp | 108 ++++++++++++++++++ .../windows/debugging/namedpipesagsdebugger.h | 48 ++++++++ .../engine/platform/windows/gfx/ali3dd3d.h | 6 +- .../engine/platform/windows/setup/winsetup.h | 6 +- .../engine/platform/windows/win_ex_handling.h | 6 +- .../platform/windows/winapi_exclusive.h | 8 +- engines/ags/engine/plugin/agsplugin.h | 4 +- engines/ags/engine/plugin/plugin_builtin.h | 6 +- engines/ags/engine/plugin/plugin_engine.h | 6 +- .../ags/engine/plugin/pluginobjectreader.h | 6 +- engines/ags/engine/script/cc_instance.h | 6 +- engines/ags/engine/script/executingscript.h | 6 +- engines/ags/engine/script/exports.h | 6 +- .../engine/script/nonblockingscriptfunction.h | 6 +- .../ags/engine/script/runtimescriptvalue.h | 6 +- engines/ags/engine/script/script.h | 6 +- engines/ags/engine/script/script_api.h | 6 +- engines/ags/engine/script/script_runtime.h | 7 +- engines/ags/engine/script/systemimports.h | 6 +- engines/ags/engine/util/library.h | 8 +- engines/ags/engine/util/library_dummy.h | 9 +- engines/ags/engine/util/library_posix.h | 8 +- engines/ags/engine/util/library_psp.h | 10 +- engines/ags/engine/util/library_windows.h | 8 +- engines/ags/engine/util/mutex.h | 6 +- engines/ags/engine/util/mutex_base.h | 7 +- engines/ags/engine/util/mutex_lock.h | 6 +- engines/ags/engine/util/mutex_psp.h | 6 +- engines/ags/engine/util/mutex_pthread.h | 6 +- engines/ags/engine/util/mutex_std.h | 6 +- engines/ags/engine/util/mutex_wii.h | 6 +- engines/ags/engine/util/mutex_windows.h | 6 +- engines/ags/engine/util/scaling.h | 6 +- engines/ags/engine/util/thread.h | 6 +- engines/ags/engine/util/thread_psp.h | 6 +- engines/ags/engine/util/thread_pthread.h | 6 +- engines/ags/engine/util/thread_std.h | 6 +- engines/ags/engine/util/thread_wii.h | 6 +- engines/ags/engine/util/thread_windows.h | 6 +- engines/ags/shared/ac/audiocliptype.h | 6 +- engines/ags/shared/ac/characterinfo.h | 6 +- engines/ags/shared/ac/common.h | 6 +- engines/ags/shared/ac/common_defines.h | 6 +- engines/ags/shared/ac/dialogtopic.h | 6 +- .../ags/shared/ac/dynobj/scriptaudioclip.h | 6 +- engines/ags/shared/ac/game_version.h | 6 +- engines/ags/shared/ac/gamesetupstruct.h | 6 +- engines/ags/shared/ac/gamesetupstructbase.h | 6 +- engines/ags/shared/ac/gamestructdefines.h | 6 +- engines/ags/shared/ac/interfacebutton.h | 6 +- engines/ags/shared/ac/interfaceelement.h | 6 +- engines/ags/shared/ac/inventoryiteminfo.h | 6 +- engines/ags/shared/ac/mousecursor.h | 6 +- engines/ags/shared/ac/oldgamesetupstruct.h | 6 +- engines/ags/shared/ac/spritecache.h | 6 +- engines/ags/shared/ac/view.h | 6 +- engines/ags/shared/ac/wordsdictionary.h | 6 +- engines/ags/shared/api/stream_api.h | 6 +- engines/ags/shared/core/asset.h | 6 +- engines/ags/shared/core/assetmanager.h | 6 +- engines/ags/shared/core/def_version.h | 6 +- engines/ags/shared/core/platform.h | 6 +- engines/ags/shared/core/types.h | 6 +- engines/ags/shared/debugging/assert.h | 6 +- engines/ags/shared/debugging/debugmanager.h | 6 +- engines/ags/shared/debugging/out.h | 6 +- engines/ags/shared/debugging/outputhandler.h | 6 +- engines/ags/shared/font/agsfontrenderer.h | 6 +- engines/ags/shared/font/fonts.h | 6 +- engines/ags/shared/font/ttffontrenderer.h | 6 +- engines/ags/shared/font/wfnfont.h | 6 +- engines/ags/shared/font/wfnfontrenderer.h | 6 +- engines/ags/shared/game/customproperties.h | 6 +- engines/ags/shared/game/interactions.h | 6 +- engines/ags/shared/game/main_game_file.h | 6 +- engines/ags/shared/game/plugininfo.h | 6 +- engines/ags/shared/game/room_file.h | 6 +- engines/ags/shared/game/room_version.h | 6 +- engines/ags/shared/game/roomstruct.h | 6 +- engines/ags/shared/gfx/allegrobitmap.h | 6 +- engines/ags/shared/gfx/bitmap.h | 7 +- engines/ags/shared/gfx/gfx_def.h | 6 +- engines/ags/shared/gui/guibutton.h | 6 +- engines/ags/shared/gui/guidefines.h | 6 +- engines/ags/shared/gui/guiinv.h | 6 +- engines/ags/shared/gui/guilabel.h | 6 +- engines/ags/shared/gui/guilistbox.h | 6 +- engines/ags/shared/gui/guimain.h | 6 +- engines/ags/shared/gui/guiobject.h | 6 +- engines/ags/shared/gui/guislider.h | 6 +- engines/ags/shared/gui/guitextbox.h | 6 +- engines/ags/shared/script/cc_error.h | 6 +- engines/ags/shared/script/cc_options.h | 4 +- engines/ags/shared/script/cc_script.h | 6 +- engines/ags/shared/script/script_common.h | 6 +- engines/ags/shared/util/alignedstream.h | 6 +- engines/ags/shared/util/bbop.h | 7 +- engines/ags/shared/util/bufferedstream.h | 11 +- engines/ags/shared/util/compress.h | 6 +- engines/ags/shared/util/datastream.h | 6 +- engines/ags/shared/util/directory.h | 6 +- engines/ags/shared/util/error.h | 6 +- engines/ags/shared/util/file.h | 6 +- engines/ags/shared/util/filestream.h | 6 +- engines/ags/shared/util/geometry.h | 6 +- engines/ags/shared/util/ini_util.h | 6 +- engines/ags/shared/util/inifile.h | 6 +- engines/ags/shared/util/lzw.h | 6 +- engines/ags/shared/util/math.h | 6 +- engines/ags/shared/util/memory.h | 6 +- engines/ags/shared/util/misc.h | 4 +- engines/ags/shared/util/multifilelib.h | 6 +- engines/ags/shared/util/path.h | 6 +- engines/ags/shared/util/proxystream.h | 6 +- engines/ags/shared/util/stdio_compat.h | 6 +- engines/ags/shared/util/stream.h | 6 +- engines/ags/shared/util/string.h | 6 +- engines/ags/shared/util/string_compat.h | 6 +- engines/ags/shared/util/string_types.h | 6 +- engines/ags/shared/util/string_utils.h | 6 +- engines/ags/shared/util/textreader.h | 6 +- engines/ags/shared/util/textstreamreader.h | 6 +- engines/ags/shared/util/textstreamwriter.h | 6 +- engines/ags/shared/util/textwriter.h | 6 +- engines/ags/shared/util/version.h | 6 +- engines/ags/shared/util/wgt2allg.h | 7 +- 351 files changed, 1204 insertions(+), 1069 deletions(-) create mode 100644 engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp create mode 100644 engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index fa62fecc2b72..bfe4130c314b 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -26,8 +26,9 @@ // //============================================================================= -#ifndef __AGS_EE_AC__ASSETHELPER_H -#define __AGS_EE_AC__ASSETHELPER_H +#ifndef AGS_ENGINE_AC_ASSETHELPER_H +#define AGS_ENGINE_AC_ASSETHELPER_H + #include #include #include "util/string.h" @@ -75,4 +76,4 @@ PACKFILE *PackfileFromAsset(const AssetPath &path, size_t &asset_size); DUMBFILE *DUMBfileFromAsset(const AssetPath &path, size_t &asset_size); bool DoesAssetExistInLib(const AssetPath &assetname); -#endif // __AGS_EE_AC__ASSETHELPER_H +#endif diff --git a/engines/ags/engine/ac/audiochannel.h b/engines/ags/engine/ac/audiochannel.h index 1955cc146c4d..e3f4a82853d8 100644 --- a/engines/ags/engine/ac/audiochannel.h +++ b/engines/ags/engine/ac/audiochannel.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__AUDIOCHANNEL_H -#define __AGS_EE_AC__AUDIOCHANNEL_H +#ifndef AGS_ENGINE_AC_AUDIOCHANNEL_H +#define AGS_ENGINE_AC_AUDIOCHANNEL_H #include "ac/dynobj/scriptaudioclip.h" #include "ac/dynobj/scriptaudiochannel.h" @@ -40,4 +40,4 @@ void AudioChannel_Stop(ScriptAudioChannel *channel); void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition); void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos); -#endif // __AGS_EE_AC__AUDIOCHANNEL_H +#endif diff --git a/engines/ags/engine/ac/audioclip.h b/engines/ags/engine/ac/audioclip.h index 113ed78423d5..7c66b2e0577b 100644 --- a/engines/ags/engine/ac/audioclip.h +++ b/engines/ags/engine/ac/audioclip.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__AUDIOCLIP_H -#define __AGS_EE_AC__AUDIOCLIP_H +#ifndef AGS_ENGINE_AC_AUDIOCLIP_H +#define AGS_ENGINE_AC_AUDIOCLIP_H #include "ac/dynobj/scriptaudioclip.h" #include "ac/dynobj/scriptaudiochannel.h" @@ -34,4 +34,4 @@ ScriptAudioChannel* AudioClip_Play(ScriptAudioClip *clip, int priority, int repe ScriptAudioChannel* AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat); ScriptAudioChannel* AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat); -#endif // __AGS_EE_AC__AUDIOCLIP_H +#endif diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h index 7a36b2455247..47022d8ce1de 100644 --- a/engines/ags/engine/ac/button.h +++ b/engines/ags/engine/ac/button.h @@ -20,13 +20,8 @@ * */ -//============================================================================= -// -// -// -//============================================================================= -#ifndef __AGS_EE_AC__BUTTON_H -#define __AGS_EE_AC__BUTTON_H +#ifndef AGS_ENGINE_AC_BUTTON_H +#define AGS_ENGINE_AC_BUTTON_H #include "gui/guibutton.h" @@ -54,4 +49,4 @@ int UpdateAnimatingButton(int bu); void StopButtonAnimation(int idxn); void FindAndRemoveButtonAnimation(int guin, int objn); -#endif // __AGS_EE_AC__BUTTON_H +#endif diff --git a/engines/ags/engine/ac/cdaudio.h b/engines/ags/engine/ac/cdaudio.h index feda127c91af..62852277ee22 100644 --- a/engines/ags/engine/ac/cdaudio.h +++ b/engines/ags/engine/ac/cdaudio.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__CDAUDIO_H -#define __AGS_EE_AC__CDAUDIO_H +#ifndef AGS_ENGINE_AC_CDAUDIO_H +#define AGS_ENGINE_AC_CDAUDIO_H // CD Player functions // flags returned with cd_getstatus @@ -33,4 +33,4 @@ int init_cd_player() ; int cd_manager(int cmdd,int datt) ; -#endif // __AGS_EE_AC__CDAUDIO_H +#endif diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h index 32016da90656..948465e55468 100644 --- a/engines/ags/engine/ac/character.h +++ b/engines/ags/engine/ac/character.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__CHARACTER_H -#define __AGS_EE_AC__CHARACTER_H +#ifndef AGS_ENGINE_AC_CHARACTER_H +#define AGS_ENGINE_AC_CHARACTER_H #include "ac/characterinfo.h" #include "ac/characterextras.h" @@ -221,4 +221,4 @@ extern int32_t _sc_PlayerCharPtr; // order of loops to turn character in circle from down to down extern int turnlooporder[8]; -#endif // __AGS_EE_AC__CHARACTER_H +#endif diff --git a/engines/ags/engine/ac/charactercache.h b/engines/ags/engine/ac/charactercache.h index ca914d3f47bd..2ba84e66ed51 100644 --- a/engines/ags/engine/ac/charactercache.h +++ b/engines/ags/engine/ac/charactercache.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__CHARACTERCACHE_H -#define __AGS_EE_AC__CHARACTERCACHE_H +#ifndef AGS_ENGINE_AC_CHARACTERCACHE_H +#define AGS_ENGINE_AC_CHARACTERCACHE_H namespace AGS { namespace Common { class Bitmap; } } using namespace AGS; // FIXME later @@ -37,4 +37,4 @@ struct CharacterCache { // no mirroredWas is required, since the code inverts the sprite number }; -#endif // __AGS_EE_AC__CHARACTERCACHE_H +#endif diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h index c694b2c96489..d5d86dcfe457 100644 --- a/engines/ags/engine/ac/characterextras.h +++ b/engines/ags/engine/ac/characterextras.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__CHARACTEREXTRAS_H -#define __AGS_EE_AC__CHARACTEREXTRAS_H +#ifndef AGS_ENGINE_AC_CHARACTEREXTRAS_H +#define AGS_ENGINE_AC_CHARACTEREXTRAS_H #include "ac/runtime_defines.h" @@ -54,4 +54,4 @@ struct CharacterExtras { void WriteToFile(Common::Stream *out); }; -#endif // __AGS_EE_AC__CHARACTEREXTRAS_H +#endif diff --git a/engines/ags/engine/ac/datetime.h b/engines/ags/engine/ac/datetime.h index 34be0b0e68e7..612870825fab 100644 --- a/engines/ags/engine/ac/datetime.h +++ b/engines/ags/engine/ac/datetime.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__DATETIME_H -#define __AGS_EE_AC__DATETIME_H +#ifndef AGS_ENGINE_AC_DATETIME_H +#define AGS_ENGINE_AC_DATETIME_H #include "ac/dynobj/scriptdatetime.h" @@ -35,4 +35,4 @@ int DateTime_GetMinute(ScriptDateTime *sdt); int DateTime_GetSecond(ScriptDateTime *sdt); int DateTime_GetRawTime(ScriptDateTime *sdt); -#endif // __AGS_EE_AC__DATETIME_H +#endif diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h index 817c3ac1cc50..076c8d05c1c6 100644 --- a/engines/ags/engine/ac/dialog.h +++ b/engines/ags/engine/ac/dialog.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__DIALOG_H -#define __AGS_EE_AC__DIALOG_H +#ifndef AGS_ENGINE_AC_DIALOG_H +#define AGS_ENGINE_AC_DIALOG_H #include #include "ac/dynobj/scriptdialog.h" @@ -41,4 +41,4 @@ int show_dialog_options(int dlgnum, int sayChosenOption, bool runGameLoopsInBac extern ScriptDialog *scrDialog; -#endif // __AGS_EE_AC__DIALOG_H +#endif diff --git a/engines/ags/engine/ac/dialogoptionsrendering.h b/engines/ags/engine/ac/dialogoptionsrendering.h index 7917ae15b0e3..a4d0aab4b22b 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.h +++ b/engines/ags/engine/ac/dialogoptionsrendering.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__DIALOGOPTIONSRENDERING_H -#define __AGS_EE_AC__DIALOGOPTIONSRENDERING_H +#ifndef AGS_ENGINE_AC_DIALOGOPTIONSRENDERING_H +#define AGS_ENGINE_AC_DIALOGOPTIONSRENDERING_H #include "ac/dynobj/scriptdialog.h" #include "ac/dynobj/scriptdialogoptionsrendering.h" @@ -47,4 +47,4 @@ ScriptDrawingSurface* DialogOptionsRendering_GetSurface(ScriptDialogOptionsRende int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender); void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID); -#endif // __AGS_EE_AC__DIALOGOPTIONSRENDERING_H +#endif diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h index 69e980ecc721..72bd83c57134 100644 --- a/engines/ags/engine/ac/display.h +++ b/engines/ags/engine/ac/display.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__DISPLAY_H -#define __AGS_EE_AC__DISPLAY_H +#ifndef AGS_ENGINE_AC_DISPLAY_H +#define AGS_ENGINE_AC_DISPLAY_H #include "gui/guimain.h" @@ -82,4 +82,4 @@ int get_textwindow_padding(int ifnum); // The efficient length of the last source text prepared for display extern int source_text_length; -#endif // __AGS_EE_AC__DISPLAY_H +#endif diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index 19e2274319d2..63bcb7432a6f 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__DRAW_H -#define __AGS_EE_AC__DRAW_H +#ifndef AGS_ENGINE_AC_DRAW_H +#define AGS_ENGINE_AC_DRAW_H #include #include "core/types.h" @@ -177,4 +177,4 @@ Common::PBitmap PrepareSpriteForUse(Common::PBitmap bitmap, bool has_alpha); // of the requested width and height and game's native color depth. Common::Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res = false); -#endif // __AGS_EE_AC__DRAW_H +#endif diff --git a/engines/ags/engine/ac/draw_software.h b/engines/ags/engine/ac/draw_software.h index e0e59339eb20..b27a8c3412a3 100644 --- a/engines/ags/engine/ac/draw_software.h +++ b/engines/ags/engine/ac/draw_software.h @@ -27,8 +27,8 @@ // //============================================================================= -#ifndef __AGS_EE_AC__DRAWSOFTWARE_H -#define __AGS_EE_AC__DRAWSOFTWARE_H +#ifndef AGS_ENGINE_AC_DRAWSOFTWARE_H +#define AGS_ENGINE_AC_DRAWSOFTWARE_H #include "gfx/bitmap.h" #include "gfx/ddb.h" @@ -54,4 +54,4 @@ void update_black_invreg_and_reset(AGS::Common::Bitmap *ds); // no_transform flag tells the system that the regions should be plain copied to the ds. void update_room_invreg_and_reset(int view_index, AGS::Common::Bitmap *ds, AGS::Common::Bitmap *src, bool no_transform); -#endif // __AGS_EE_AC__DRAWSOFTWARE_H +#endif diff --git a/engines/ags/engine/ac/drawingsurface.h b/engines/ags/engine/ac/drawingsurface.h index 511cf1b441b3..20737be5a4aa 100644 --- a/engines/ags/engine/ac/drawingsurface.h +++ b/engines/ags/engine/ac/drawingsurface.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__DRAWINGSURFACE_H -#define __AGS_EE_AC__DRAWINGSURFACE_H +#ifndef AGS_ENGINE_AC_DRAWINGSURFACE_H +#define AGS_ENGINE_AC_DRAWINGSURFACE_H #include "ac/dynobj/scriptdrawingsurface.h" @@ -47,4 +47,4 @@ void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, in void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y); int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y); -#endif // __AGS_EE_AC__DRAWINGSURFACE_H +#endif diff --git a/engines/ags/engine/ac/dynamicsprite.h b/engines/ags/engine/ac/dynamicsprite.h index 0f644f4aed45..f6d7674780f2 100644 --- a/engines/ags/engine/ac/dynamicsprite.h +++ b/engines/ags/engine/ac/dynamicsprite.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__DYNAMICSPRITE_H -#define __AGS_EE_AC__DYNAMICSPRITE_H +#ifndef AGS_ENGINE_AC_DYNAMICSPRITE_H +#define AGS_ENGINE_AC_DYNAMICSPRITE_H #include "ac/dynobj/scriptdynamicsprite.h" #include "ac/dynobj/scriptdrawingsurface.h" @@ -53,4 +53,4 @@ ScriptDynamicSprite* DynamicSprite_CreateFromBackground(int frame, int x1, int y void add_dynamic_sprite(int gotSlot, Common::Bitmap *redin, bool hasAlpha = false); void free_dynamic_sprite (int gotSlot); -#endif // __AGS_EE_AC__DYNAMICSPRITE_H +#endif diff --git a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h index d4687da0a924..e9d32a155703 100644 --- a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h +++ b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H -#define __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H +#ifndef AGS_ENGINE_AC_DYNOBJ_ALLDYNAMICCLASSES_H +#define AGS_ENGINE_AC_DYNOBJ_ALLDYNAMICCLASSES_H #include "ac/dynobj/cc_agsdynamicobject.h" #include "ac/dynobj/cc_audiochannel.h" @@ -37,4 +37,4 @@ #include "ac/dynobj/cc_serializer.h" -#endif // __AGS_EE_DYNOBJ__ALLDYNAMICCLASSES_H +#endif diff --git a/engines/ags/engine/ac/dynobj/all_scriptclasses.h b/engines/ags/engine/ac/dynobj/all_scriptclasses.h index 6a703be07efc..7c9776d2cb51 100644 --- a/engines/ags/engine/ac/dynobj/all_scriptclasses.h +++ b/engines/ags/engine/ac/dynobj/all_scriptclasses.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__ALLSCRIPTCLASSES_H -#define __AGS_EE_DYNOBJ__ALLSCRIPTCLASSES_H +#ifndef AGS_ENGINE_AC_DYNOBJ_ALLSCRIPTCLASSES_H +#define AGS_ENGINE_AC_DYNOBJ_ALLSCRIPTCLASSES_H #include "ac/dynobj/scriptdatetime.h" #include "ac/dynobj/scriptdialog.h" @@ -39,4 +39,4 @@ #include "ac/dynobj/scriptsystem.h" #include "ac/dynobj/scriptviewframe.h" -#endif // __AGS_EE_DYNOBJ__ALLSCRIPTOBJECTS_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h index c0a0eab4dc90..30f83e8a5a42 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCDYNAMICOBJECT_H -#define __AC_CCDYNAMICOBJECT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CC_AGSDYNAMICOBJECT_H +#define AGS_ENGINE_AC_DYNOBJ_CC_AGSDYNAMICOBJECT_H #include "ac/dynobj/cc_dynamicobject.h" @@ -65,4 +65,4 @@ struct AGSCCDynamicObject : ICCDynamicObject { }; -#endif // __AC_CCDYNAMICOBJECT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.h b/engines/ags/engine/ac/dynobj/cc_audiochannel.h index b7c0eb0ef3bb..8f5b2a05d8ec 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.h +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H -#define __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CC_AUDIOCHANNEL_H +#define AGS_ENGINE_AC_DYNOBJ_CC_AUDIOCHANNEL_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -31,4 +31,4 @@ struct CCAudioChannel final : AGSCCDynamicObject { void Unserialize(int index, const char *serializedData, int dataSize) override; }; -#endif // __AGS_EE_DYNOBJ__CCAUDIOCHANNEL_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.h b/engines/ags/engine/ac/dynobj/cc_audioclip.h index 6439ec35db30..5d715bbe9b7e 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.h +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__CCAUDIOCLIP_H -#define __AGS_EE_DYNOBJ__CCAUDIOCLIP_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCAUDIOCLIP_H +#define AGS_ENGINE_AC_DYNOBJ_CCAUDIOCLIP_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -31,4 +31,4 @@ struct CCAudioClip final : AGSCCDynamicObject { void Unserialize(int index, const char *serializedData, int dataSize) override; }; -#endif // __AGS_EE_DYNOBJ__CCAUDIOCLIP_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_character.h b/engines/ags/engine/ac/dynobj/cc_character.h index 06ff2e28d4ba..e9d461e4165c 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.h +++ b/engines/ags/engine/ac/dynobj/cc_character.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCCHARACTER_H -#define __AC_CCCHARACTER_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCCHARACTER_H +#define AGS_ENGINE_AC_DYNOBJ_CCCHARACTER_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -39,4 +39,4 @@ struct CCCharacter final : AGSCCDynamicObject { void WriteInt16(const char *address, intptr_t offset, int16_t val) override; }; -#endif // __AC_CCCHARACTER_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.h b/engines/ags/engine/ac/dynobj/cc_dialog.h index 0e7a7017893f..6146522622fe 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.h +++ b/engines/ags/engine/ac/dynobj/cc_dialog.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCDIALOG_H -#define __AC_CCDIALOG_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCDIALOG_H +#define AGS_ENGINE_AC_DYNOBJ_CCDIALOG_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -38,4 +38,4 @@ struct CCDialog final : AGSCCDynamicObject { }; -#endif // __AC_CCDIALOG_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index ed2916724458..8ee984eb39d7 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -20,8 +20,8 @@ * */ -#ifndef __CC_DYNAMICARRAY_H -#define __CC_DYNAMICARRAY_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCDYNAMICARRAY_H +#define AGS_ENGINE_AC_DYNOBJ_CCDYNAMICARRAY_H #include #include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index aeca72f4d007..ada26fd3ffc4 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -25,8 +25,9 @@ // Managed script object interface. // //============================================================================= -#ifndef __CC_DYNAMICOBJECT_H -#define __CC_DYNAMICOBJECT_H + +#ifndef AGS_ENGINE_AC_DYNOBJ_CCDYNAMICOBJECT_H +#define AGS_ENGINE_AC_DYNOBJ_CCDYNAMICOBJECT_H #include #include "core/types.h" @@ -123,4 +124,4 @@ extern int ccReleaseObjectReference(int32_t handle); extern ICCStringClass *stringClassImpl; -#endif // __CC_DYNAMICOBJECT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h index 4323d976524f..99d55e5f0e1a 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h @@ -20,8 +20,8 @@ * */ -#ifndef ADDR_AND_MANAGER_H -#define ADDR_AND_MANAGER_H +#ifndef AGS_ENGINE_AC_DYNOBJ_ADDR_AND_MANAGER_H +#define AGS_ENGINE_AC_DYNOBJ_ADDR_AND_MANAGER_H #include "script/runtimescriptvalue.h" #include "ac/dynobj/cc_dynamicobject.h" diff --git a/engines/ags/engine/ac/dynobj/cc_gui.h b/engines/ags/engine/ac/dynobj/cc_gui.h index 39c892d48dfa..8d1b60838714 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.h +++ b/engines/ags/engine/ac/dynobj/cc_gui.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCGUI_H -#define __AC_CCGUI_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCGUI_H +#define AGS_ENGINE_AC_DYNOBJ_CCGUI_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -37,4 +37,4 @@ struct CCGUI final : AGSCCDynamicObject { void Unserialize(int index, const char *serializedData, int dataSize) override; }; -#endif // __AC_CCGUI_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.h b/engines/ags/engine/ac/dynobj/cc_guiobject.h index a6bf88165426..bb457bed10c0 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.h +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCGUIOBJECT_H -#define __AC_CCGUIOBJECT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCGUI_H +#define AGS_ENGINE_AC_DYNOBJ_CCGUI_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -38,4 +38,4 @@ struct CCGUIObject final : AGSCCDynamicObject { }; -#endif // __AC_CCGUIOBJECT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.h b/engines/ags/engine/ac/dynobj/cc_hotspot.h index 05722895fba6..e5ca7a7756a6 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.h +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCHOTSPOT_H -#define __AC_CCHOTSPOT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCHOTSPOT_H +#define AGS_ENGINE_AC_DYNOBJ_CCHOTSPOT_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -38,4 +38,4 @@ struct CCHotspot final : AGSCCDynamicObject { }; -#endif // __AC_CCHOTSPOT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.h b/engines/ags/engine/ac/dynobj/cc_inventory.h index aba9dc7c8afb..4b793b339426 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.h +++ b/engines/ags/engine/ac/dynobj/cc_inventory.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCINVENTORY_H -#define __AC_CCINVENTORY_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCINVENTORY_H +#define AGS_ENGINE_AC_DYNOBJ_CCINVENTORY_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -38,4 +38,4 @@ struct CCInventory final : AGSCCDynamicObject { }; -#endif // __AC_CCINVENTORY_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_object.h b/engines/ags/engine/ac/dynobj/cc_object.h index f81b0d5cdfc4..88533aaebe99 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.h +++ b/engines/ags/engine/ac/dynobj/cc_object.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCOBJECT_H -#define __AC_CCOBJECT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCOBJECT_H +#define AGS_ENGINE_AC_DYNOBJ_CCOBJECT_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -38,4 +38,4 @@ struct CCObject final : AGSCCDynamicObject { }; -#endif // __AC_CCOBJECT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_region.h b/engines/ags/engine/ac/dynobj/cc_region.h index 6abb7df1532b..c16136d599a3 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.h +++ b/engines/ags/engine/ac/dynobj/cc_region.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CCREGION_H -#define __AC_CCREGION_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCREGION_H +#define AGS_ENGINE_AC_DYNOBJ_CCREGION_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -38,4 +38,4 @@ struct CCRegion final : AGSCCDynamicObject { }; -#endif // __AC_CCREGION_H +#endif diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h index 9de17b54d535..655138738b55 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.h +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SERIALIZER_H -#define __AC_SERIALIZER_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCSERIALIZER_H +#define AGS_ENGINE_AC_DYNOBJ_CCSERIALIZER_H #include "ac/dynobj/cc_dynamicobject.h" @@ -32,4 +32,4 @@ struct AGSDeSerializer : ICCObjectReader { extern AGSDeSerializer ccUnserializer; -#endif // __AC_SERIALIZER_H +#endif diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index 6697592d9b39..b08284222520 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -20,8 +20,8 @@ * */ -#ifndef __CC_MANAGEDOBJECTPOOL_H -#define __CC_MANAGEDOBJECTPOOL_H +#ifndef AGS_ENGINE_AC_DYNOBJ_MANAGEDOBJECTPOOL_H +#define AGS_ENGINE_AC_DYNOBJ_MANAGEDOBJECTPOOL_H #include #include @@ -93,4 +93,4 @@ extern ManagedObjectPool pool; #define ManagedObjectLog(...) #endif -#endif // __CC_MANAGEDOBJECTPOOL_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h index c8ecb6fbf871..8b762f7ec34c 100644 --- a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h +++ b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H -#define __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTAUDIOCHANNEL_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTAUDIOCHANNEL_H struct ScriptAudioChannel { @@ -29,4 +29,4 @@ struct ScriptAudioChannel int reserved; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTAUDIOCHANNEL_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.h b/engines/ags/engine/ac/dynobj/scriptcamera.h index 292e02216051..16708a1e8366 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.h +++ b/engines/ags/engine/ac/dynobj/scriptcamera.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTCAMERA_H -#define __AC_SCRIPTCAMERA_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTCAMERA_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTCAMERA_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -49,4 +49,4 @@ struct ScriptCamera final : AGSCCDynamicObject // Unserialize camera from the memory stream ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dataSize); -#endif // __AC_SCRIPTCAMERA_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptcontainers.h b/engines/ags/engine/ac/dynobj/scriptcontainers.h index 5159a237ef5f..f735c6514bf2 100644 --- a/engines/ags/engine/ac/dynobj/scriptcontainers.h +++ b/engines/ags/engine/ac/dynobj/scriptcontainers.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTCONTAINERS_H -#define __AC_SCRIPTCONTAINERS_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTCONTAINERS_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTCONTAINERS_H class ScriptDictBase; class ScriptSetBase; @@ -35,4 +35,4 @@ ScriptSetBase *Set_Create(bool sorted, bool case_sensitive); // Unserialize set from the memory stream ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize); -#endif // __AC_SCRIPTCONTAINERS_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.h b/engines/ags/engine/ac/dynobj/scriptdatetime.h index c898e93fa6e6..e65661a3198b 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.h +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTDATETIME_H -#define __AGS_EE_DYNOBJ__SCRIPTDATETIME_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDATETIME_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTDATETIME_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -38,4 +38,4 @@ struct ScriptDateTime final : AGSCCDynamicObject { ScriptDateTime(); }; -#endif // __AGS_EE_DYNOBJ__SCRIPTDATETIME_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptdialog.h b/engines/ags/engine/ac/dynobj/scriptdialog.h index f549afcd1e0f..9668fa4d62ef 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialog.h +++ b/engines/ags/engine/ac/dynobj/scriptdialog.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTDIALOG_H -#define __AGS_EE_DYNOBJ__SCRIPTDIALOG_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOG_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOG_H struct ScriptDialog { int id; int reserved; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTDIALOG_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h index d13ab0e8c32c..bc09dd8d8c89 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTDIALOGOPTIONSRENDERING_H -#define __AC_SCRIPTDIALOGOPTIONSRENDERING_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOGOPTIONSRENDERING_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOGOPTIONSRENDERING_H #include "ac/dynobj/scriptdrawingsurface.h" @@ -52,4 +52,4 @@ struct ScriptDialogOptionsRendering final : AGSCCDynamicObject { }; -#endif // __AC_SCRIPTDIALOGOPTIONSRENDERING_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index 62039f4c7639..da8062ed08a2 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -33,8 +33,8 @@ // //============================================================================= -#ifndef __AC_SCRIPTDICT_H -#define __AC_SCRIPTDICT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDICT_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTDICT_H #include #include @@ -194,4 +194,4 @@ typedef ScriptDictImpl< std::map, true, false > S typedef ScriptDictImpl< std::unordered_map, false, true > ScriptHashDict; typedef ScriptDictImpl< std::unordered_map, false, false > ScriptHashDictCI; -#endif // __AC_SCRIPTDICT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h index 8cf35a6d93a2..b3f4a190e429 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTDRAWINGSURFACE_H -#define __AC_SCRIPTDRAWINGSURFACE_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDRAWINGSURFACE_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTDRAWINGSURFACE_H #include "ac/dynobj/cc_agsdynamicobject.h" #include "game/roomstruct.h" @@ -60,4 +60,4 @@ struct ScriptDrawingSurface final : AGSCCDynamicObject { ScriptDrawingSurface(); }; -#endif // __AC_SCRIPTDRAWINGSURFACE_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h index fccb51ba3849..0104d759b168 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTDYNAMICSPRITE_H -#define __AC_SCRIPTDYNAMICSPRITE_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDYNAMICSPRITE_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTDYNAMICSPRITE_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -37,4 +37,4 @@ struct ScriptDynamicSprite final : AGSCCDynamicObject { ScriptDynamicSprite(); }; -#endif // __AC_SCRIPTDYNAMICSPRITE_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptfile.h b/engines/ags/engine/ac/dynobj/scriptfile.h index 538d79c20623..3a1571fb617f 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.h +++ b/engines/ags/engine/ac/dynobj/scriptfile.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTFILE_H -#define __AGS_EE_DYNOBJ__SCRIPTFILE_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTFILE_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTFILE_H #include "ac/dynobj/cc_dynamicobject.h" #include "util/file.h" @@ -63,4 +63,4 @@ struct sc_File final : ICCDynamicObject { void WriteFloat(const char *address, intptr_t offset, float val) override; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTFILE_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptgui.h b/engines/ags/engine/ac/dynobj/scriptgui.h index 6dffd085c3af..690a803ef278 100644 --- a/engines/ags/engine/ac/dynobj/scriptgui.h +++ b/engines/ags/engine/ac/dynobj/scriptgui.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTGUI_H -#define __AGS_EE_DYNOBJ__SCRIPTGUI_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTGUI_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTGUI_H // 64 bit: This struct must be 8 byte long struct ScriptGUI { @@ -29,4 +29,4 @@ struct ScriptGUI { int __padding; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTGUI_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scripthotspot.h b/engines/ags/engine/ac/dynobj/scripthotspot.h index 181b3b2bcaac..dd93e1aa7052 100644 --- a/engines/ags/engine/ac/dynobj/scripthotspot.h +++ b/engines/ags/engine/ac/dynobj/scripthotspot.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H -#define __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTHOTSPOT_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTHOTSPOT_H struct ScriptHotspot { int id; int reserved; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTHOTSPOT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptinvitem.h b/engines/ags/engine/ac/dynobj/scriptinvitem.h index e55e98dbf97b..b6da8b17ab75 100644 --- a/engines/ags/engine/ac/dynobj/scriptinvitem.h +++ b/engines/ags/engine/ac/dynobj/scriptinvitem.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTINVITEM_H -#define __AGS_EE_DYNOBJ__SCRIPTINVITEM_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTINVITEM_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTINVITEM_H struct ScriptInvItem { int id; int reserved; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTINVITEM_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptmouse.h b/engines/ags/engine/ac/dynobj/scriptmouse.h index 2eb0697aba79..c2cc4f75d930 100644 --- a/engines/ags/engine/ac/dynobj/scriptmouse.h +++ b/engines/ags/engine/ac/dynobj/scriptmouse.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTMOUSE_H -#define __AGS_EE_DYNOBJ__SCRIPTMOUSE_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTMOUSE_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTMOUSE_H // The text script's "mouse" struct struct ScriptMouse { int x,y; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTMOUSE_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptobject.h b/engines/ags/engine/ac/dynobj/scriptobject.h index 37545d2c78f7..154393ce1e19 100644 --- a/engines/ags/engine/ac/dynobj/scriptobject.h +++ b/engines/ags/engine/ac/dynobj/scriptobject.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTOBJECT_H -#define __AGS_EE_DYNOBJ__SCRIPTOBJECT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTOBJECT_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTOBJECT_H #include "ac/roomobject.h" @@ -32,4 +32,4 @@ struct ScriptObject { int __padding; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTOBJECT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.h b/engines/ags/engine/ac/dynobj/scriptoverlay.h index 8b678605f567..76785cd922af 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.h +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTOVERLAY_H -#define __AC_SCRIPTOVERLAY_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTOVERLAY_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTOVERLAY_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -39,4 +39,4 @@ struct ScriptOverlay final : AGSCCDynamicObject { ScriptOverlay(); }; -#endif // __AC_SCRIPTOVERLAY_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptregion.h b/engines/ags/engine/ac/dynobj/scriptregion.h index 4bf38a95c72b..86deb65f0b1d 100644 --- a/engines/ags/engine/ac/dynobj/scriptregion.h +++ b/engines/ags/engine/ac/dynobj/scriptregion.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTREGION_H -#define __AGS_EE_DYNOBJ__SCRIPTREGION_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTREGION_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTREGION_H struct ScriptRegion { int id; int reserved; }; -#endif // __AGS_EE_DYNOBJ__SCRIPTREGION_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index d5ad8a91553f..3f71b19b8f03 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -32,8 +32,8 @@ // //============================================================================= -#ifndef __AC_SCRIPTSET_H -#define __AC_SCRIPTSET_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H #include #include @@ -152,4 +152,4 @@ typedef ScriptSetImpl< std::set, true, false > ScriptSetC typedef ScriptSetImpl< std::unordered_set, false, true > ScriptHashSet; typedef ScriptSetImpl< std::unordered_set, false, false > ScriptHashSetCI; -#endif // __AC_SCRIPTSET_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptstring.h b/engines/ags/engine/ac/dynobj/scriptstring.h index 041f3b3f3299..b59595b0943d 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.h +++ b/engines/ags/engine/ac/dynobj/scriptstring.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTSTRING_H -#define __AC_SCRIPTSTRING_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSTRING_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTSTRING_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -39,4 +39,4 @@ struct ScriptString final : AGSCCDynamicObject, ICCStringClass { ScriptString(const char *fromText); }; -#endif // __AC_SCRIPTSTRING_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptsystem.h b/engines/ags/engine/ac/dynobj/scriptsystem.h index 815d30cb021c..4b5d19a8fdb0 100644 --- a/engines/ags/engine/ac/dynobj/scriptsystem.h +++ b/engines/ags/engine/ac/dynobj/scriptsystem.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H -#define __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSYSTEM_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTSYSTEM_H // The text script's "system" struct struct ScriptSystem { @@ -35,4 +35,4 @@ struct ScriptSystem { int reserved[5]; // so that future scripts don't overwrite data }; -#endif // __AGS_EE_DYNOBJ__SCRIPTSYSTEM_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h index 36bfe2890990..f89ac7fe762b 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.h +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H -#define __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTUSERSTRUCT_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTUSERSTRUCT_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -83,4 +83,4 @@ namespace ScriptStructHelpers ScriptUserObject *CreatePoint(int x, int y); }; -#endif // __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.h b/engines/ags/engine/ac/dynobj/scriptviewframe.h index 83ad44b88f06..b625328b0223 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.h +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTVIEWFRAME_H -#define __AC_SCRIPTVIEWFRAME_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWFRAME_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWFRAME_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -37,4 +37,4 @@ struct ScriptViewFrame final : AGSCCDynamicObject { ScriptViewFrame(); }; -#endif // __AC_SCRIPTVIEWFRAME_H +#endif diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.h b/engines/ags/engine/ac/dynobj/scriptviewport.h index a9fe88628336..26ca3cde8c3c 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.h +++ b/engines/ags/engine/ac/dynobj/scriptviewport.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SCRIPTVIEWPORT_H -#define __AC_SCRIPTVIEWPORT_H +#ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWPORT_H +#define AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWPORT_H #include "ac/dynobj/cc_agsdynamicobject.h" @@ -48,4 +48,4 @@ struct ScriptViewport final : AGSCCDynamicObject // Unserialize viewport from the memory stream ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int dataSize); -#endif // __AC_SCRIPTVIEWPORT_H +#endif diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h index 78e7b486e9aa..d22acd0979f8 100644 --- a/engines/ags/engine/ac/event.h +++ b/engines/ags/engine/ac/event.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__EVENT_H -#define __AGS_EE_AC__EVENT_H +#ifndef AGS_ENGINE_AC_EVENT_H +#define AGS_ENGINE_AC_EVENT_H #include "ac/runtime_defines.h" #include "script/runtimescriptvalue.h" @@ -84,5 +84,4 @@ extern int eventClaimed; extern const char*tsnames[4]; -#endif // __AGS_EE_AC__EVENT_H - +#endif diff --git a/engines/ags/engine/ac/file.h b/engines/ags/engine/ac/file.h index 0f0b2aeac815..dd00616365e9 100644 --- a/engines/ags/engine/ac/file.h +++ b/engines/ags/engine/ac/file.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_AC__FILE_H -#define __AGS_EE_AC__FILE_H +#ifndef AGS_ENGINE_AC_FILE_H +#define AGS_ENGINE_AC_FILE_H #include "ac/dynobj/scriptfile.h" #include "ac/runtime_defines.h" @@ -65,4 +65,4 @@ ScriptFileHandle *check_valid_file_handle_ptr(Stream *stream_ptr, const char *op ScriptFileHandle *check_valid_file_handle_int32(int32_t handle, const char *operation_name); Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_name); -#endif // __AGS_EE_AC__FILE_H +#endif diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h index c09fc59b24ba..a3e9b4cbee73 100644 --- a/engines/ags/engine/ac/game.h +++ b/engines/ags/engine/ac/game.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_AC__GAME_H -#define __AGS_EE_AC__GAME_H +#ifndef AGS_ENGINE_AC_GAME_H +#define AGS_ENGINE_AC_GAME_H #include "ac/dynobj/scriptviewframe.h" #include "main/game_file.h" @@ -199,4 +199,4 @@ extern unsigned int loopcounter; extern void set_loop_counter(unsigned int new_counter); extern int game_paused; -#endif // __AGS_EE_AC__GAME_H +#endif diff --git a/engines/ags/engine/ac/gamesetup.h b/engines/ags/engine/ac/gamesetup.h index 54708a26cd6f..9f204c624d2a 100644 --- a/engines/ags/engine/ac/gamesetup.h +++ b/engines/ags/engine/ac/gamesetup.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GAMESETUP_H -#define __AC_GAMESETUP_H +#ifndef AGS_ENGINE_AC_GAMESETUP_H +#define AGS_ENGINE_AC_GAMESETUP_H #include "main/graphics_mode.h" #include "util/string.h" @@ -91,4 +91,4 @@ struct GameSetup { // Perhaps it makes sense to separate those two group of vars at some point. extern GameSetup usetup; -#endif // __AC_GAMESETUP_H +#endif diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h index 413b508b4650..24d6b64ff887 100644 --- a/engines/ags/engine/ac/gamestate.h +++ b/engines/ags/engine/ac/gamestate.h @@ -20,9 +20,8 @@ * */ -#ifndef __AC_GAMESTATE_H -#define __AC_GAMESTATE_H - +#ifndef AGS_ENGINE_AC_GAMESTATE_H +#define AGS_ENGINE_AC_GAMESTATE_H #include #include @@ -401,4 +400,4 @@ HorAlignment ReadScriptAlignment(int32_t align); extern GameState play; -#endif // __AC_GAMESTATE_H +#endif diff --git a/engines/ags/engine/ac/global_audio.h b/engines/ags/engine/ac/global_audio.h index 9bf1c5b95b6b..0f6a7f61bddc 100644 --- a/engines/ags/engine/ac/global_audio.h +++ b/engines/ags/engine/ac/global_audio.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALAUDIO_H -#define __AGS_EE_AC__GLOBALAUDIO_H +#ifndef AGS_ENGINE_AC_GLOBALAUDIO_H +#define AGS_ENGINE_AC_GLOBALAUDIO_H void StopAmbientSound (int channel); void PlayAmbientSound (int channel, int sndnum, int vol, int x, int y); @@ -73,4 +73,4 @@ void stop_voice_speech(); // Stop non-blocking voice-over and revert audio volumes if necessary void stop_voice_nonblocking(); -#endif // __AGS_EE_AC__GLOBALAUDIO_H +#endif diff --git a/engines/ags/engine/ac/global_button.h b/engines/ags/engine/ac/global_button.h index d4f2561e91c9..518e73c63f4e 100644 --- a/engines/ags/engine/ac/global_button.h +++ b/engines/ags/engine/ac/global_button.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_AC__GLOBALBUTTON_H -#define __AGS_EE_AC__GLOBALBUTTON_H +#ifndef AGS_ENGINE_AC_GLOBALBUTTON_H +#define AGS_ENGINE_AC_GLOBALBUTTON_H void SetButtonText(int guin,int objn, const char*newtx); void AnimateButton(int guin, int objn, int view, int loop, int speed, int repeat); int GetButtonPic(int guin, int objn, int ptype); void SetButtonPic(int guin,int objn,int ptype,int slotn); -#endif // __AGS_EE_AC__GLOBALBUTTON_H +#endif diff --git a/engines/ags/engine/ac/global_character.h b/engines/ags/engine/ac/global_character.h index 48483a03a3c0..e9d19b4c21a0 100644 --- a/engines/ags/engine/ac/global_character.h +++ b/engines/ags/engine/ac/global_character.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALCHARACTER_H -#define __AGS_EE_AC__GLOBALCHARACTER_H +#ifndef AGS_ENGINE_AC_GLOBALCHARACTER_H +#define AGS_ENGINE_AC_GLOBALCHARACTER_H #include "ac/characterinfo.h" @@ -89,4 +89,4 @@ void __sc_displayspeech(int chid, const char *text); void DisplaySpeechAt (int xx, int yy, int wii, int aschar, const char*spch); int DisplaySpeechBackground(int charid, const char*speel); -#endif // __AGS_EE_AC__CHARACTEREXTRAS_H +#endif diff --git a/engines/ags/engine/ac/global_datetime.h b/engines/ags/engine/ac/global_datetime.h index caf287111c18..55fd3abe6349 100644 --- a/engines/ags/engine/ac/global_datetime.h +++ b/engines/ags/engine/ac/global_datetime.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_AC__GLOBALDATETIME_H -#define __AGS_EE_AC__GLOBALDATETIME_H +#ifndef AGS_ENGINE_AC_GLOBALDATETIME_H +#define AGS_ENGINE_AC_GLOBALDATETIME_H int sc_GetTime(int whatti) ; int GetRawTime (); -#endif // __AGS_EE_AC__GLOBALDATETIME_H +#endif diff --git a/engines/ags/engine/ac/global_debug.h b/engines/ags/engine/ac/global_debug.h index bdaabba917d5..2f4e4445156d 100644 --- a/engines/ags/engine/ac/global_debug.h +++ b/engines/ags/engine/ac/global_debug.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALDEBUG_H -#define __AGS_EE_AC__GLOBALDEBUG_H +#ifndef AGS_ENGINE_AC_GLOBALDEBUG_H +#define AGS_ENGINE_AC_GLOBALDEBUG_H #include #include "util/string.h" @@ -29,4 +29,4 @@ AGS::Common::String GetRuntimeInfo(); void script_debug(int cmdd,int dataa); -#endif // __AGS_EE_AC__GLOBALDEBUG_H +#endif diff --git a/engines/ags/engine/ac/global_dialog.h b/engines/ags/engine/ac/global_dialog.h index 7dc7e0e72476..faf0539b838f 100644 --- a/engines/ags/engine/ac/global_dialog.h +++ b/engines/ags/engine/ac/global_dialog.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_AC__GLOBALDIALOG_H -#define __AGS_EE_AC__GLOBALDIALOG_H +#ifndef AGS_ENGINE_AC_GLOBALDIALOG_H +#define AGS_ENGINE_AC_GLOBALDIALOG_H void RunDialog(int tum); int GetDialogOption (int dlg, int opt); void SetDialogOption(int dlg, int opt, int onoroff, bool dlg_script = false); void StopDialog(); -#endif // __AGS_EE_AC__GLOBALDIALOG_H +#endif diff --git a/engines/ags/engine/ac/global_display.h b/engines/ags/engine/ac/global_display.h index 226e5fa9869a..f71803675ca0 100644 --- a/engines/ags/engine/ac/global_display.h +++ b/engines/ags/engine/ac/global_display.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALDISPLAY_H -#define __AGS_EE_AC__GLOBALDISPLAY_H +#ifndef AGS_ENGINE_AC_GLOBALDISPLAY_H +#define AGS_ENGINE_AC_GLOBALDISPLAY_H #include "ac/speech.h" @@ -39,4 +39,4 @@ void SetSpeechStyle (int newstyle); void SetSkipSpeech (SkipSpeechStyle newval); SkipSpeechStyle GetSkipSpeech(); -#endif // __AGS_EE_AC__GLOBALDISPLAY_H +#endif diff --git a/engines/ags/engine/ac/global_drawingsurface.h b/engines/ags/engine/ac/global_drawingsurface.h index c755113faac8..a65fe88a793e 100644 --- a/engines/ags/engine/ac/global_drawingsurface.h +++ b/engines/ags/engine/ac/global_drawingsurface.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALDRAWINGSURFACE_H -#define __AGS_EE_AC__GLOBALDRAWINGSURFACE_H +#ifndef AGS_ENGINE_AC_GLOBALDRAWINGSURFACE_H +#define AGS_ENGINE_AC_GLOBALDRAWINGSURFACE_H void RawSaveScreen (); // RawRestoreScreen: copy backup bitmap back to screen; we @@ -46,4 +46,4 @@ void RawDrawCircle (int xx, int yy, int rad); void RawDrawRectangle(int x1, int y1, int x2, int y2); void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3); -#endif // __AGS_EE_AC__GLOBALDRAWINGSURFACE_H +#endif diff --git a/engines/ags/engine/ac/global_dynamicsprite.h b/engines/ags/engine/ac/global_dynamicsprite.h index 82b264c1678c..db6fe2d06dce 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.h +++ b/engines/ags/engine/ac/global_dynamicsprite.h @@ -20,9 +20,9 @@ * */ -#ifndef __AGS_EE_AC__GLOBALDYNAMICSPRITE_H -#define __AGS_EE_AC__GLOBALDYNAMICSPRITE_H +#ifndef AGS_ENGINE_AC_GLOBAL_DYNAMICSPRITE_H +#define AGS_ENGINE_AC_GLOBAL_DYNAMICSPRITE_H int LoadImageFile(const char *filename); -#endif // __AGS_EE_AC__GLOBALDYNAMICSPRITE_H +#endif diff --git a/engines/ags/engine/ac/global_file.h b/engines/ags/engine/ac/global_file.h index be67d1288c21..7f5b59ee5dbe 100644 --- a/engines/ags/engine/ac/global_file.h +++ b/engines/ags/engine/ac/global_file.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALFILE_H -#define __AGS_EE_AC__GLOBALFILE_H +#ifndef AGS_ENGINE_AC_GLOBAL_FILE_H +#define AGS_ENGINE_AC_GLOBAL_FILE_H #include "util/file.h" @@ -43,4 +43,4 @@ char FileReadRawChar(int32_t handle); int FileReadRawInt(int32_t handle); void FileWriteRawChar(int32_t handle, int chartoWrite); -#endif // __AGS_EE_AC__GLOBALFILE_H +#endif diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h index 93c309bfc9b1..a7a4418c99dd 100644 --- a/engines/ags/engine/ac/global_game.h +++ b/engines/ags/engine/ac/global_game.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALGAME_H -#define __AGS_EE_AC__GLOBALGAME_H +#ifndef AGS_ENGINE_AC_GLOBAL_GAME_H +#define AGS_ENGINE_AC_GLOBAL_GAME_H #include "util/string.h" using namespace AGS; // FIXME later @@ -90,4 +90,4 @@ int WaitMouse(int nloops); int WaitMouseKey(int nloops); void SkipWait(); -#endif // __AGS_EE_AC__GLOBALGAME_H +#endif diff --git a/engines/ags/engine/ac/global_gui.h b/engines/ags/engine/ac/global_gui.h index ef18f75eabeb..680021442a25 100644 --- a/engines/ags/engine/ac/global_gui.h +++ b/engines/ags/engine/ac/global_gui.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALGUI_H -#define __AGS_EE_AC__GLOBALGUI_H +#ifndef AGS_ENGINE_AC_GLOBAL_GUI_H +#define AGS_ENGINE_AC_GLOBAL_GUI_H // IsGUIOn tells whether GUI is actually displayed on screen right now int IsGUIOn (int guinum); @@ -56,4 +56,4 @@ int GetGUIObjectAt (int xx, int yy); int GetGUIAt (int xx,int yy); void SetTextWindowGUI (int guinum); -#endif // __AGS_EE_AC__GLOBALGUI_H +#endif diff --git a/engines/ags/engine/ac/global_hotspot.h b/engines/ags/engine/ac/global_hotspot.h index b19c05f587c8..339322b9c317 100644 --- a/engines/ags/engine/ac/global_hotspot.h +++ b/engines/ags/engine/ac/global_hotspot.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALHOTSPOT_H -#define __AGS_EE_AC__GLOBALHOTSPOT_H +#ifndef AGS_ENGINE_AC_GLOBAL_HOTSPOT_H +#define AGS_ENGINE_AC_GLOBAL_HOTSPOT_H void DisableHotspot(int hsnum); void EnableHotspot(int hsnum); @@ -37,4 +37,4 @@ int GetHotspotProperty (int hss, const char *property); void GetHotspotPropertyText (int item, const char *property, char *bufer); -#endif // __AGS_EE_AC__GLOBALHOTSPOT_H +#endif diff --git a/engines/ags/engine/ac/global_inventoryitem.h b/engines/ags/engine/ac/global_inventoryitem.h index af2590db7796..56dad5c651c1 100644 --- a/engines/ags/engine/ac/global_inventoryitem.h +++ b/engines/ags/engine/ac/global_inventoryitem.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALINVENTORYITEM_H -#define __AGS_EE_AC__GLOBALINVENTORYITEM_H +#ifndef AGS_ENGINE_AC_GLOBAL_INVENTORYITEM_H +#define AGS_ENGINE_AC_GLOBAL_INVENTORYITEM_H void set_inv_item_pic(int invi, int piccy); void SetInvItemName(int invi, const char *newName); @@ -33,4 +33,4 @@ int IsInventoryInteractionAvailable (int item, int mood); int GetInvProperty (int item, const char *property); void GetInvPropertyText (int item, const char *property, char *bufer); -#endif // __AGS_EE_AC__GLOBALINVENTORYITEM_H +#endif diff --git a/engines/ags/engine/ac/global_invwindow.h b/engines/ags/engine/ac/global_invwindow.h index 02a51d9f4b79..fa2e5b6752dc 100644 --- a/engines/ags/engine/ac/global_invwindow.h +++ b/engines/ags/engine/ac/global_invwindow.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_AC__GLOBALINVWINDOW_H -#define __AGS_EE_AC__GLOBALINVWINDOW_H +#ifndef AGS_ENGINE_AC_GLOBAL_INVWINDOW_H +#define AGS_ENGINE_AC_GLOBAL_INVWINDOW_H void sc_invscreen(); void SetInvDimensions(int ww,int hh); -#endif // __AGS_EE_AC__GLOBALINVWINDOW_H +#endif diff --git a/engines/ags/engine/ac/global_label.h b/engines/ags/engine/ac/global_label.h index c3f0cb49f0a8..f3553a53938e 100644 --- a/engines/ags/engine/ac/global_label.h +++ b/engines/ags/engine/ac/global_label.h @@ -20,11 +20,11 @@ * */ -#ifndef __AGS_EE_AC__GLOBALLABEL_H -#define __AGS_EE_AC__GLOBALLABEL_H +#ifndef AGS_ENGINE_AC_GLOBAL_LABEL_H +#define AGS_ENGINE_AC_GLOBAL_LABEL_H void SetLabelColor(int guin,int objn, int colr); void SetLabelText(int guin,int objn, const char*newtx); void SetLabelFont(int guin,int objn, int fontnum); -#endif // __AGS_EE_AC__GLOBALLABEL_H +#endif diff --git a/engines/ags/engine/ac/global_listbox.h b/engines/ags/engine/ac/global_listbox.h index f49cc5bd7c39..df48eadd77ad 100644 --- a/engines/ags/engine/ac/global_listbox.h +++ b/engines/ags/engine/ac/global_listbox.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALLISTBOX_H -#define __AGS_EE_AC__GLOBALLISTBOX_H +#ifndef AGS_ENGINE_AC_GLOBAL_LISTBOX_H +#define AGS_ENGINE_AC_GLOBAL_LISTBOX_H void ListBoxClear(int guin, int objn); void ListBoxAdd(int guin, int objn, const char*newitem); @@ -34,4 +34,4 @@ void ListBoxSetTopItem (int guin, int objn, int item); int ListBoxSaveGameList (int guin, int objn); void ListBoxDirList (int guin, int objn, const char*filemask); -#endif // __AGS_EE_AC__GLOBALLISTBOX_H +#endif diff --git a/engines/ags/engine/ac/global_mouse.h b/engines/ags/engine/ac/global_mouse.h index 5a0345518d80..dacbf5e8ee6a 100644 --- a/engines/ags/engine/ac/global_mouse.h +++ b/engines/ags/engine/ac/global_mouse.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_AC__GLOBALMOUSE_H -#define __AGS_EE_AC__GLOBALMOUSE_H +#ifndef AGS_ENGINE_AC_GLOBAL_MOUSE_H +#define AGS_ENGINE_AC_GLOBAL_MOUSE_H void HideMouseCursor (); void ShowMouseCursor (); -#endif // __AGS_EE_AC__GLOBALMOUSE_H +#endif diff --git a/engines/ags/engine/ac/global_object.h b/engines/ags/engine/ac/global_object.h index 4eed9fd27c4a..65b364fd29ee 100644 --- a/engines/ags/engine/ac/global_object.h +++ b/engines/ags/engine/ac/global_object.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALOBJECT_H -#define __AGS_EE_AC__GLOBALOBJECT_H +#ifndef AGS_ENGINE_AC_GLOBAL_OBJECT_H +#define AGS_ENGINE_AC_GLOBAL_OBJECT_H namespace AGS { namespace Common { class Bitmap; } } using namespace AGS; // FIXME later @@ -73,4 +73,4 @@ void GetObjectPropertyText (int item, const char *property, char *bufer); Common::Bitmap *GetObjectImage(int obj, int *isFlipped); -#endif // __AGS_EE_AC__GLOBALOBJECT_H +#endif diff --git a/engines/ags/engine/ac/global_overlay.h b/engines/ags/engine/ac/global_overlay.h index 4e43a54b5199..3cb71b53f65c 100644 --- a/engines/ags/engine/ac/global_overlay.h +++ b/engines/ags/engine/ac/global_overlay.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALOVERLAY_H -#define __AGS_EE_AC__GLOBALOVERLAY_H +#ifndef AGS_ENGINE_AC_GLOBALOVERLAY_H +#define AGS_ENGINE_AC_GLOBALOVERLAY_H void RemoveOverlay(int ovrid); int CreateGraphicOverlay(int xx, int yy, int slott, int trans); @@ -31,4 +31,4 @@ void SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int text_col void MoveOverlay(int ovrid, int newx, int newy); int IsOverlayValid(int ovrid); -#endif // __AGS_EE_AC__GLOBALOVERLAY_H +#endif diff --git a/engines/ags/engine/ac/global_palette.h b/engines/ags/engine/ac/global_palette.h index 9a131d52ce1d..9005c166191f 100644 --- a/engines/ags/engine/ac/global_palette.h +++ b/engines/ags/engine/ac/global_palette.h @@ -20,11 +20,11 @@ * */ -#ifndef __AGS_EE_AC__GLOBALPALETTE_H -#define __AGS_EE_AC__GLOBALPALETTE_H +#ifndef AGS_ENGINE_AC_GLOBAL_PALETTE_H +#define AGS_ENGINE_AC_GLOBAL_PALETTE_H void CyclePalette(int strt,int eend); void SetPalRGB(int inndx,int rr,int gg,int bb); void UpdatePalette(); -#endif // __AGS_EE_AC__GLOBALPALETTE_H +#endif diff --git a/engines/ags/engine/ac/global_parser.h b/engines/ags/engine/ac/global_parser.h index 427723dff6a3..92772678093d 100644 --- a/engines/ags/engine/ac/global_parser.h +++ b/engines/ags/engine/ac/global_parser.h @@ -20,9 +20,9 @@ * */ -#ifndef __AGS_EE_AC__GLOBALPARSER_H -#define __AGS_EE_AC__GLOBALPARSER_H +#ifndef AGS_ENGINE_AC_GLOBAL_PARSER_H +#define AGS_ENGINE_AC_GLOBAL_PARSER_H int SaidUnknownWord (char*buffer); -#endif // __AGS_EE_AC__GLOBALPARSER_H +#endif diff --git a/engines/ags/engine/ac/global_plugin.h b/engines/ags/engine/ac/global_plugin.h index 9fdae6e20e55..7d14d7f8ad99 100644 --- a/engines/ags/engine/ac/global_plugin.h +++ b/engines/ags/engine/ac/global_plugin.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_PLUGIN__PLUGINFUNC_H -#define __AGS_EE_PLUGIN__PLUGINFUNC_H +#ifndef AGS_ENGINE_AC_GLOBAL_PLUGIN_H +#define AGS_ENGINE_AC_GLOBAL_PLUGIN_H void PluginSimulateMouseClick(int pluginButtonID); bool RegisterPluginStubs(const char* name); -#endif // __AGS_EE_PLUGIN__PLUGINFUNC_H +#endif diff --git a/engines/ags/engine/ac/global_record.h b/engines/ags/engine/ac/global_record.h index adc9f60946ae..1a924b37018d 100644 --- a/engines/ags/engine/ac/global_record.h +++ b/engines/ags/engine/ac/global_record.h @@ -20,9 +20,9 @@ * */ -#ifndef __AGS_EE_AC__GLOBALRECORD_H -#define __AGS_EE_AC__GLOBALRECORD_H +#ifndef AGS_ENGINE_AC_GLOBAL_RECORD_H +#define AGS_ENGINE_AC_GLOBAL_RECORD_H void scStartRecording (int keyToStop); -#endif // __AGS_EE_AC__GLOBALRECORD_H +#endif diff --git a/engines/ags/engine/ac/global_region.h b/engines/ags/engine/ac/global_region.h index 5dbfdd382f3f..0c69239d8531 100644 --- a/engines/ags/engine/ac/global_region.h +++ b/engines/ags/engine/ac/global_region.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALREGION_H -#define __AGS_EE_AC__GLOBALREGION_H +#ifndef AGS_ENGINE_AC_GLOBAL_REGION_H +#define AGS_ENGINE_AC_GLOBAL_REGION_H // Gets region ID at the given room coordinates; // if region is disabled or non-existing, returns 0 (no area) @@ -34,4 +34,4 @@ void DisableGroundLevelAreas(int alsoEffects); void EnableGroundLevelAreas(); void RunRegionInteraction (int regnum, int mood); -#endif // __AGS_EE_AC__GLOBALREGION_H +#endif diff --git a/engines/ags/engine/ac/global_room.h b/engines/ags/engine/ac/global_room.h index f19a849f67d5..e469d7a34ff5 100644 --- a/engines/ags/engine/ac/global_room.h +++ b/engines/ags/engine/ac/global_room.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALROOM_H -#define __AGS_EE_AC__GLOBALROOM_H +#ifndef AGS_ENGINE_AC_GLOBAL_ROOM_H +#define AGS_ENGINE_AC_GLOBAL_ROOM_H void SetAmbientTint (int red, int green, int blue, int opacity, int luminance); void SetAmbientLightLevel(int light_level); @@ -37,4 +37,4 @@ void GetRoomPropertyText (const char *property, char *bufer); void SetBackgroundFrame(int frnum); int GetBackgroundFrame() ; -#endif // __AGS_EE_AC__GLOBALROOM_H +#endif diff --git a/engines/ags/engine/ac/global_screen.h b/engines/ags/engine/ac/global_screen.h index a412ae37d9aa..ea6d5f1be606 100644 --- a/engines/ags/engine/ac/global_screen.h +++ b/engines/ags/engine/ac/global_screen.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALSCREEN_H -#define __AGS_EE_AC__GLOBALSCREEN_H +#ifndef AGS_ENGINE_AC_GLOBAL_SCREEN_H +#define AGS_ENGINE_AC_GLOBAL_SCREEN_H void FlipScreen(int amount); void ShakeScreen(int severe); @@ -33,4 +33,4 @@ void SetNextScreenTransition(int newtrans); void SetFadeColor(int red, int green, int blue); void FadeIn(int sppd); -#endif // __AGS_EE_AC__GLOBALSCREEN_H +#endif diff --git a/engines/ags/engine/ac/global_slider.h b/engines/ags/engine/ac/global_slider.h index bf6b59f336bd..a904619574f4 100644 --- a/engines/ags/engine/ac/global_slider.h +++ b/engines/ags/engine/ac/global_slider.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_AC__GLOBALSLIDER_H -#define __AGS_EE_AC__GLOBALSLIDER_H +#ifndef AGS_ENGINE_AC_GLOBAL_SLIDER_H +#define AGS_ENGINE_AC_GLOBAL_SLIDER_H void SetSliderValue(int guin,int objn, int valn); int GetSliderValue(int guin,int objn); -#endif // __AGS_EE_AC__GLOBALSLIDER_H +#endif diff --git a/engines/ags/engine/ac/global_string.h b/engines/ags/engine/ac/global_string.h index 6369fae8fa0a..a78b30b552ef 100644 --- a/engines/ags/engine/ac/global_string.h +++ b/engines/ags/engine/ac/global_string.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALSTRING_H -#define __AGS_EE_AC__GLOBALSTRING_H +#ifndef AGS_ENGINE_AC_GLOBAL_STRING_H +#define AGS_ENGINE_AC_GLOBAL_STRING_H int StrGetCharAt (const char *strin, int posn); void StrSetCharAt (char *strin, int posn, int nchar); @@ -30,4 +30,4 @@ void _sc_strlower (char *desbuf); void _sc_strupper (char *desbuf); void _sc_strcpy(char*destt, const char*text); -#endif // __AGS_EE_AC__GLOBALSTRING_H +#endif diff --git a/engines/ags/engine/ac/global_textbox.h b/engines/ags/engine/ac/global_textbox.h index f5e6f9cf853e..d42f1ddd3b24 100644 --- a/engines/ags/engine/ac/global_textbox.h +++ b/engines/ags/engine/ac/global_textbox.h @@ -20,11 +20,11 @@ * */ -#ifndef __AGS_EE_AC__GLOBALTEXTBOX_H -#define __AGS_EE_AC__GLOBALTEXTBOX_H +#ifndef AGS_ENGINE_AC_GLOBAL_TEXTBOX_H +#define AGS_ENGINE_AC_GLOBAL_TEXTBOX_H void SetTextBoxFont(int guin,int objn, int fontnum); void GetTextBoxText(int guin, int objn, char*txbuf); void SetTextBoxText(int guin, int objn, const char*txbuf); -#endif // __AGS_EE_AC__GLOBALTEXTBOX_H +#endif diff --git a/engines/ags/engine/ac/global_timer.h b/engines/ags/engine/ac/global_timer.h index b244766b822b..b387bd8955dc 100644 --- a/engines/ags/engine/ac/global_timer.h +++ b/engines/ags/engine/ac/global_timer.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_AC__GLOBALTIMER_H -#define __AGS_EE_AC__GLOBALTIMER_H +#ifndef AGS_ENGINE_AC_GLOBAL_TIMER_H +#define AGS_ENGINE_AC_GLOBAL_TIMER_H void script_SetTimer(int tnum,int timeout); int IsTimerExpired(int tnum); -#endif // __AGS_EE_AC__GLOBALTIMER_H +#endif diff --git a/engines/ags/engine/ac/global_translation.h b/engines/ags/engine/ac/global_translation.h index 0e6d0b1008b1..ab462602cd79 100644 --- a/engines/ags/engine/ac/global_translation.h +++ b/engines/ags/engine/ac/global_translation.h @@ -20,11 +20,11 @@ * */ -#ifndef __AGS_EE_AC__GLOBALTRANSLATION_H -#define __AGS_EE_AC__GLOBALTRANSLATION_H +#ifndef AGS_ENGINE_AC_GLOBAL_TRANSLATION_H +#define AGS_ENGINE_AC_GLOBAL_TRANSLATION_H const char *get_translation (const char *text); int IsTranslationAvailable (); int GetTranslationName (char* buffer); -#endif // __AGS_EE_AC__GLOBALTRANSLATION_H +#endif diff --git a/engines/ags/engine/ac/global_video.h b/engines/ags/engine/ac/global_video.h index a297fa215141..ac381da671e8 100644 --- a/engines/ags/engine/ac/global_video.h +++ b/engines/ags/engine/ac/global_video.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_AC__GLOBALVIDEO_H -#define __AGS_EE_AC__GLOBALVIDEO_H +#ifndef AGS_ENGINE_AC_GLOBAL_VIDEO_H +#define AGS_ENGINE_AC_GLOBAL_VIDEO_H void scrPlayVideo(const char* name, int skip, int flags); void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags); -#endif // __AGS_EE_AC__GLOBALVIDEO_H +#endif diff --git a/engines/ags/engine/ac/global_viewframe.h b/engines/ags/engine/ac/global_viewframe.h index 140c09ddbdac..ca0100e8eae7 100644 --- a/engines/ags/engine/ac/global_viewframe.h +++ b/engines/ags/engine/ac/global_viewframe.h @@ -20,9 +20,9 @@ * */ -#ifndef __AGS_EE_AC__GLOBALVIEWFRAME_H -#define __AGS_EE_AC__GLOBALVIEWFRAME_H +#ifndef AGS_ENGINE_AC_GLOBAL_VIEWFRAME_H +#define AGS_ENGINE_AC_GLOBAL_VIEWFRAME_H void SetFrameSound (int vii, int loop, int frame, int sound); -#endif // __AGS_EE_AC__GLOBALVIEWFRAME_H +#endif diff --git a/engines/ags/engine/ac/global_viewport.h b/engines/ags/engine/ac/global_viewport.h index d56d7efc8a24..4e68532410dd 100644 --- a/engines/ags/engine/ac/global_viewport.h +++ b/engines/ags/engine/ac/global_viewport.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_AC__GLOBALVIEWPORT_H -#define __AGS_EE_AC__GLOBALVIEWPORT_H +#ifndef AGS_ENGINE_AC_GLOBAL_VIEWPORT_H +#define AGS_ENGINE_AC_GLOBAL_VIEWPORT_H void SetViewport(int offsx,int offsy); void ReleaseViewport(); int GetViewportX (); int GetViewportY (); -#endif // __AGS_EE_AC__GLOBAL_VIEWPORT_H +#endif diff --git a/engines/ags/engine/ac/global_walkablearea.h b/engines/ags/engine/ac/global_walkablearea.h index 4e4b7aeb2a37..7ab0e1188114 100644 --- a/engines/ags/engine/ac/global_walkablearea.h +++ b/engines/ags/engine/ac/global_walkablearea.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GLOBALWALKABLEAREA_H -#define __AGS_EE_AC__GLOBALWALKABLEAREA_H +#ifndef AGS_ENGINE_AC_GLOBAL_WALKABLEAREA_H +#define AGS_ENGINE_AC_GLOBAL_WALKABLEAREA_H int GetScalingAt (int x, int y); void SetAreaScaling(int area, int min, int max); @@ -34,4 +34,4 @@ int GetWalkableAreaAtRoom(int x, int y); // if area is disabled or non-existing, returns 0 (no area) int GetWalkableAreaAtScreen(int x, int y); -#endif // __AGS_EE_AC__GLOBALWALKABLEAREA_H +#endif diff --git a/engines/ags/engine/ac/global_walkbehind.h b/engines/ags/engine/ac/global_walkbehind.h index 9c3d554cb20f..0e9b1efabedf 100644 --- a/engines/ags/engine/ac/global_walkbehind.h +++ b/engines/ags/engine/ac/global_walkbehind.h @@ -20,9 +20,9 @@ * */ -#ifndef __AGS_EE_AC__GLOBALWALKBEHIND_H -#define __AGS_EE_AC__GLOBALWALKBEHIND_H +#ifndef AGS_ENGINE_AC_GLOBAL_WALKBEHIND_H +#define AGS_ENGINE_AC_GLOBAL_WALKBEHIND_H void SetWalkBehindBase(int wa,int bl); -#endif // __AGS_EE_AC__GLOBALWALKBEHIND_H +#endif diff --git a/engines/ags/engine/ac/gui.h b/engines/ags/engine/ac/gui.h index 371fc7a9c57b..a80f8843578a 100644 --- a/engines/ags/engine/ac/gui.h +++ b/engines/ags/engine/ac/gui.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GUI_H -#define __AGS_EE_AC__GUI_H +#ifndef AGS_ENGINE_AC_GUI_H +#define AGS_ENGINE_AC_GUI_H #include "ac/dynobj/scriptgui.h" #include "gui/guimain.h" @@ -90,4 +90,4 @@ extern int ifacepopped; extern int ifacepopped; extern int mouse_on_iface; -#endif // __AGS_EE_AC__GUI_H +#endif diff --git a/engines/ags/engine/ac/guicontrol.h b/engines/ags/engine/ac/guicontrol.h index 03b11b8dbd3e..fd2d0c2452e0 100644 --- a/engines/ags/engine/ac/guicontrol.h +++ b/engines/ags/engine/ac/guicontrol.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__GUICONTROL_H -#define __AGS_EE_AC__GUICONTROL_H +#ifndef AGS_ENGINE_AC_GUICONTROL_H +#define AGS_ENGINE_AC_GUICONTROL_H #include "gui/guiobject.h" #include "gui/guibutton.h" @@ -70,4 +70,4 @@ void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit); void GUIControl_SendToBack(GUIObject *guio); void GUIControl_BringToFront(GUIObject *guio); -#endif // __AGS_EE_AC__GUICONTROL_H +#endif diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h index 4e69030e2ed3..e1c7804b27ff 100644 --- a/engines/ags/engine/ac/hotspot.h +++ b/engines/ags/engine/ac/hotspot.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__HOTSPOT_H -#define __AGS_EE_AC__HOTSPOT_H +#ifndef AGS_ENGINE_AC_HOTSPOT_H +#define AGS_ENGINE_AC_HOTSPOT_H #include "ac/dynobj/scripthotspot.h" @@ -44,4 +44,4 @@ const char* Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property); // if hotspot is disabled or non-existing, returns 0 (no area) int get_hotspot_at(int xpp,int ypp); -#endif // __AGS_EE_AC__HOTSPOT_H +#endif diff --git a/engines/ags/engine/ac/inventoryitem.h b/engines/ags/engine/ac/inventoryitem.h index 76733125f42c..1fedcabd5a05 100644 --- a/engines/ags/engine/ac/inventoryitem.h +++ b/engines/ags/engine/ac/inventoryitem.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__INVENTORYITEM_H -#define __AGS_EE_AC__INVENTORYITEM_H +#ifndef AGS_ENGINE_AC_INVENTORYITEM_H +#define AGS_ENGINE_AC_INVENTORYITEM_H #include "ac/dynobj/scriptinvitem.h" @@ -42,4 +42,4 @@ const char* InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *prope void set_inv_item_cursorpic(int invItemId, int piccy); -#endif // __AGS_EE_AC__INVENTORYITEM_H +#endif diff --git a/engines/ags/engine/ac/invwindow.h b/engines/ags/engine/ac/invwindow.h index 72802c2572ae..fe1e9a8105c2 100644 --- a/engines/ags/engine/ac/invwindow.h +++ b/engines/ags/engine/ac/invwindow.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__INVWINDOW_H -#define __AGS_EE_AC__INVWINDOW_H +#ifndef AGS_ENGINE_AC_INVWINDOW_H +#define AGS_ENGINE_AC_INVWINDOW_H #include "ac/characterinfo.h" #include "ac/dynobj/scriptinvitem.h" @@ -50,4 +50,4 @@ int offset_over_inv(GUIInvWindow *inv); // NOTE: This function is valid for AGS 2.72 and lower int invscreen(); -#endif // __AGS_EE_AC__INVWINDOW_H +#endif diff --git a/engines/ags/engine/ac/keycode.h b/engines/ags/engine/ac/keycode.h index 6269dafca35d..292274b60e7d 100644 --- a/engines/ags/engine/ac/keycode.h +++ b/engines/ags/engine/ac/keycode.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__KEYCODE_H -#define __AGS_EE_AC__KEYCODE_H +#ifndef AGS_ENGINE_AC_KEYCODE_H +#define AGS_ENGINE_AC_KEYCODE_H #include "core/platform.h" @@ -177,4 +177,4 @@ int GetKeyForKeyPressCb(int keycode); // Returns -1 if not found. int PlatformKeyFromAgsKey(int key); -#endif // __AGS_EE_AC__KEYCODE_H +#endif diff --git a/engines/ags/engine/ac/label.h b/engines/ags/engine/ac/label.h index 26464eefcf94..8aa5976cd5cc 100644 --- a/engines/ags/engine/ac/label.h +++ b/engines/ags/engine/ac/label.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__LABEL_H -#define __AGS_EE_AC__LABEL_H +#ifndef AGS_ENGINE_AC_LABEL_H +#define AGS_ENGINE_AC_LABEL_H #include "gui/guilabel.h" @@ -35,4 +35,4 @@ void Label_SetColor(GUILabel *labl, int colr); int Label_GetFont(GUILabel *labl); void Label_SetFont(GUILabel *guil, int fontnum); -#endif // __AGS_EE_AC__LABEL_H +#endif diff --git a/engines/ags/engine/ac/lipsync.h b/engines/ags/engine/ac/lipsync.h index 2301ef2d38b0..694d02489f7b 100644 --- a/engines/ags/engine/ac/lipsync.h +++ b/engines/ags/engine/ac/lipsync.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_LIPSYNC_H -#define __AC_LIPSYNC_H +#ifndef AGS_ENGINE_AC_LIPSYNC_H +#define AGS_ENGINE_AC_LIPSYNC_H struct SpeechLipSyncLine { char filename[14]; @@ -30,4 +30,4 @@ struct SpeechLipSyncLine { short numPhonemes; }; -#endif // __AC_LIPSYNC_H +#endif diff --git a/engines/ags/engine/ac/listbox.h b/engines/ags/engine/ac/listbox.h index eb6c5d06ab90..2b0c07af264f 100644 --- a/engines/ags/engine/ac/listbox.h +++ b/engines/ags/engine/ac/listbox.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__LISTBOX_H -#define __AGS_EE_AC__LISTBOX_H +#ifndef AGS_ENGINE_AC_LISTBOX_H +#define AGS_ENGINE_AC_LISTBOX_H #include "gui/guilistbox.h" @@ -55,4 +55,4 @@ void ListBox_ScrollUp(GUIListBox *listbox); GUIListBox* is_valid_listbox (int guin, int objn); -#endif // __AGS_EE_AC__LISTBOX_H +#endif diff --git a/engines/ags/engine/ac/math.h b/engines/ags/engine/ac/math.h index ce047992deaf..8dd7d8f55e7c 100644 --- a/engines/ags/engine/ac/math.h +++ b/engines/ags/engine/ac/math.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__MATH_H -#define __AGS_EE_AC__MATH_H +#ifndef AGS_ENGINE_AC_MATH_H +#define AGS_ENGINE_AC_MATH_H #include "core/types.h" @@ -57,4 +57,4 @@ float Math_Sqrt(float value); int __Rand(int upto); #define Random __Rand -#endif // __AGS_EE_AC__MATH_H +#endif diff --git a/engines/ags/engine/ac/mouse.h b/engines/ags/engine/ac/mouse.h index f49e2e9f796a..a38abde70682 100644 --- a/engines/ags/engine/ac/mouse.h +++ b/engines/ags/engine/ac/mouse.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__MOUSE_H -#define __AGS_EE_AC__MOUSE_H +#ifndef AGS_ENGINE_AC_MOUSE_H +#define AGS_ENGINE_AC_MOUSE_H #include "ac/dynobj/scriptmouse.h" @@ -78,4 +78,4 @@ extern ScriptMouse scmouse; extern int cur_mode; extern int cur_cursor; -#endif // __AGS_EE_AC__MOUSE_H +#endif diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h index cff9328138f5..ce47eb45cbc4 100644 --- a/engines/ags/engine/ac/movelist.h +++ b/engines/ags/engine/ac/movelist.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MOVE_H -#define __AC_MOVE_H +#ifndef AGS_ENGINE_AC_MOVE_H +#define AGS_ENGINE_AC_MOVE_H #include "util/wgt2allg.h" // fixed type #include "game/savegame.h" @@ -48,4 +48,4 @@ struct MoveList { void WriteToFile(Common::Stream *out); }; -#endif // __AC_MOVE_H +#endif diff --git a/engines/ags/engine/ac/object.h b/engines/ags/engine/ac/object.h index 5679ec5d9e53..0d7262a78ad9 100644 --- a/engines/ags/engine/ac/object.h +++ b/engines/ags/engine/ac/object.h @@ -28,8 +28,8 @@ // rename this to RoomObject one day? //============================================================================= -#ifndef __AGS_EE_AC__OBJECT_H -#define __AGS_EE_AC__OBJECT_H +#ifndef AGS_ENGINE_AC_OBJECT_H +#define AGS_ENGINE_AC_OBJECT_H #include "ac/common_defines.h" #include "ac/dynobj/scriptobject.h" @@ -96,5 +96,4 @@ int is_pos_in_sprite(int xx,int yy,int arx,int ary, Common::Bitmap *sprit, i // X and Y are ROOM coordinates int check_click_on_object(int roomx, int roomy, int mood); -#endif // __AGS_EE_AC__OBJECT_H - +#endif diff --git a/engines/ags/engine/ac/objectcache.h b/engines/ags/engine/ac/objectcache.h index cff0fcb8f607..916b47c46216 100644 --- a/engines/ags/engine/ac/objectcache.h +++ b/engines/ags/engine/ac/objectcache.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__OBJECTCACHE_H -#define __AGS_EE_AC__OBJECTCACHE_H +#ifndef AGS_ENGINE_AC_OBJECTCACHE_H +#define AGS_ENGINE_AC_OBJECTCACHE_H // stores cached object info struct ObjectCache { @@ -33,4 +33,4 @@ struct ObjectCache { int xwas, ywas; }; -#endif // __AGS_EE_AC__OBJECTCACHE_H +#endif diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h index ed315510e633..96f5b388757a 100644 --- a/engines/ags/engine/ac/overlay.h +++ b/engines/ags/engine/ac/overlay.h @@ -20,8 +20,9 @@ * */ -#ifndef __AGS_EE_AC__OVERLAY_H -#define __AGS_EE_AC__OVERLAY_H +#ifndef AGS_ENGINE_AC_OVERLAY_H +#define AGS_ENGINE_AC_OVERLAY_H + #include #include "ac/screenoverlay.h" #include "ac/dynobj/scriptoverlay.h" @@ -53,4 +54,4 @@ extern int is_text_overlay; // blocking text overlay on screen extern std::vector screenover; -#endif // __AGS_EE_AC__OVERLAY_H +#endif diff --git a/engines/ags/engine/ac/parser.h b/engines/ags/engine/ac/parser.h index e13edaf89ad6..6da49934ab60 100644 --- a/engines/ags/engine/ac/parser.h +++ b/engines/ags/engine/ac/parser.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__PARSER_H -#define __AGS_EE_AC__PARSER_H +#ifndef AGS_ENGINE_AC_PARSER_H +#define AGS_ENGINE_AC_PARSER_H int Parser_FindWordID(const char *wordToFind); const char* Parser_SaidUnknownWord(); @@ -35,4 +35,4 @@ int is_valid_word_char(char theChar); int FindMatchingMultiWordWord(char *thisword, const char **text); int parse_sentence (const char *src_text, int *numwords, short*wordarray, short*compareto, int comparetonum); -#endif // __AGS_EE_AC__PARSER_H +#endif diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h index 9efb1190d3c6..a5cd9d89dacb 100644 --- a/engines/ags/engine/ac/path_helper.h +++ b/engines/ags/engine/ac/path_helper.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_AC__PATHHELPER_H -#define __AGS_EE_AC__PATHHELPER_H +#ifndef AGS_ENGINE_AC_PATHHELPER_H +#define AGS_ENGINE_AC_PATHHELPER_H #include "util/string.h" @@ -83,4 +83,4 @@ String get_audio_install_dir(); String get_voice_install_dir(); void get_install_dir_path(char* buffer, const char *fileName); -#endif // __AGS_EE_AC__PATHHELPER_H +#endif diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h index 428265777afc..f0d233a8c828 100644 --- a/engines/ags/engine/ac/properties.h +++ b/engines/ags/engine/ac/properties.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__PROPERTIES_H -#define __AGS_EE_AC__PROPERTIES_H +#ifndef AGS_ENGINE_AC_PROPERTIES_H +#define AGS_ENGINE_AC_PROPERTIES_H #include "game/customproperties.h" @@ -39,4 +39,4 @@ const char* get_text_property_dynamic_string(const StringIMap &st_prop, const St bool set_int_property(StringIMap &rt_prop, const char *property, int value); bool set_text_property(StringIMap &rt_prop, const char *property, const char* value); -#endif // __AGS_EE_AC__PROPERTIES_H +#endif diff --git a/engines/ags/engine/ac/region.h b/engines/ags/engine/ac/region.h index f12636f4650c..9deb80b13369 100644 --- a/engines/ags/engine/ac/region.h +++ b/engines/ags/engine/ac/region.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__REGION_H -#define __AGS_EE_AC__REGION_H +#ifndef AGS_ENGINE_AC_REGION_H +#define AGS_ENGINE_AC_REGION_H #include "ac/dynobj/scriptregion.h" @@ -42,4 +42,4 @@ void Region_RunInteraction(ScriptRegion *ssr, int mood); void generate_light_table(); -#endif // __AGS_EE_AC__REGION_H +#endif diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index c0570e89f072..28acaf2cbbed 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__RICHGAMEMEDIA_H -#define __AGS_EE_AC__RICHGAMEMEDIA_H +#ifndef AGS_ENGINE_AC_RICHGAMEMEDIA_H +#define AGS_ENGINE_AC_RICHGAMEMEDIA_H // Windows Vista Rich Save Games, modified to be platform-agnostic @@ -53,4 +53,4 @@ typedef struct _RICH_GAME_MEDIA_HEADER } RICH_GAME_MEDIA_HEADER; #pragma pack(pop) -#endif // __AGS_EE_AC__RICHGAMEMEDIA_H +#endif diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h index d091369a7499..e34e1f9506ba 100644 --- a/engines/ags/engine/ac/room.h +++ b/engines/ags/engine/ac/room.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__ROOM_H -#define __AGS_EE_AC__ROOM_H +#ifndef AGS_ENGINE_AC_ROOM_H +#define AGS_ENGINE_AC_ROOM_H #include "ac/dynobj/scriptdrawingsurface.h" #include "ac/characterinfo.h" @@ -76,4 +76,4 @@ void convert_move_path_to_room_resolution(MoveList *ml); extern AGS::Common::RoomStruct thisroom; -#endif // __AGS_EE_AC__ROOM_H +#endif diff --git a/engines/ags/engine/ac/roomobject.h b/engines/ags/engine/ac/roomobject.h index 3fb614807327..af648ba35fc1 100644 --- a/engines/ags/engine/ac/roomobject.h +++ b/engines/ags/engine/ac/roomobject.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__ROOMOBJECT_H -#define __AGS_EE_AC__ROOMOBJECT_H +#ifndef AGS_ENGINE_AC_ROOMOBJECT_H +#define AGS_ENGINE_AC_ROOMOBJECT_H #include "ac/common_defines.h" @@ -64,4 +64,4 @@ struct RoomObject { void WriteToFile(Common::Stream *out) const; }; -#endif // __AGS_EE_AC__ROOMOBJECT_H +#endif diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h index 6e6dad69bde3..a57036815199 100644 --- a/engines/ags/engine/ac/roomstatus.h +++ b/engines/ags/engine/ac/roomstatus.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__ROOMSTATUS_H -#define __AGS_EE_AC__ROOMSTATUS_H +#ifndef AGS_ENGINE_AC_ROOMSTATUS_H +#define AGS_ENGINE_AC_ROOMSTATUS_H #include "ac/roomobject.h" #include "game/roomstruct.h" @@ -82,4 +82,4 @@ RoomStatus* getRoomStatus(int room); bool isRoomStatusValid(int room); void resetRoomStatuses(); -#endif // __AGS_EE_AC__ROOMSTATUS_H +#endif diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h index 60a7748e2708..35dc05fc24a2 100644 --- a/engines/ags/engine/ac/route_finder.h +++ b/engines/ags/engine/ac/route_finder.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_ROUTEFND_H -#define __AC_ROUTEFND_H +#ifndef AGS_ENGINE_AC_ROUTEFND_H +#define AGS_ENGINE_AC_ROUTEFND_H #include "ac/game_version.h" @@ -42,4 +42,4 @@ void set_route_move_speed(int speed_x, int speed_y); int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); void calculate_move_stage(MoveList * mlsp, int aaa); -#endif // __AC_ROUTEFND_H +#endif diff --git a/engines/ags/engine/ac/route_finder_impl.h b/engines/ags/engine/ac/route_finder_impl.h index 9c71d4606a34..147733899dee 100644 --- a/engines/ags/engine/ac/route_finder_impl.h +++ b/engines/ags/engine/ac/route_finder_impl.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_ROUTE_FINDER_IMPL -#define __AC_ROUTE_FINDER_IMPL +#ifndef AGS_ENGINE_AC_ROUTE_FINDER_IMPL +#define AGS_ENGINE_AC_ROUTE_FINDER_IMPL #include "ac/game_version.h" @@ -50,4 +50,4 @@ void calculate_move_stage(MoveList * mlsp, int aaa); } // namespace Engine } // namespace AGS -#endif // __AC_ROUTE_FINDER_IMPL +#endif diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h index e87ad590664d..26e9f69730ec 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.h +++ b/engines/ags/engine/ac/route_finder_impl_legacy.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_ROUTE_FINDER_IMPL_LEGACY -#define __AC_ROUTE_FINDER_IMPL_LEGACY +#ifndef AGS_ENGINE_AC_ROUTE_FINDER_IMPL_LEGACY +#define AGS_ENGINE_AC_ROUTE_FINDER_IMPL_LEGACY // Forward declaration namespace AGS { namespace Common { class Bitmap; }} @@ -48,4 +48,4 @@ void calculate_move_stage(MoveList * mlsp, int aaa); } // namespace Engine } // namespace AGS -#endif // __AC_ROUTE_FINDER_IMPL_LEGACY +#endif diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h index 95c43b85a0a4..b48320eb30c9 100644 --- a/engines/ags/engine/ac/runtime_defines.h +++ b/engines/ags/engine/ac/runtime_defines.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_RUNTIMEDEFINES_H -#define __AC_RUNTIMEDEFINES_H +#ifndef AGS_ENGINE_AC_RUNTIMEDEFINES_H +#define AGS_ENGINE_AC_RUNTIMEDEFINES_H // xalleg.h pulls in an Allegro-internal definition of MAX_TIMERS which // conflicts with the definition in runtime_defines.h. Forget it. @@ -158,4 +158,4 @@ const int LegacyRoomVolumeFactor = 30; #include "ac/common_defines.h" -#endif // __AC_RUNTIMEDEFINES_H +#endif diff --git a/engines/ags/engine/ac/screen.h b/engines/ags/engine/ac/screen.h index d0898bc73ab3..a89012f50e0f 100644 --- a/engines/ags/engine/ac/screen.h +++ b/engines/ags/engine/ac/screen.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SCREEN_H -#define __AGS_EE_AC__SCREEN_H +#ifndef AGS_ENGINE_AC_SCREEN_H +#define AGS_ENGINE_AC_SCREEN_H namespace AGS { namespace Common { class Bitmap; } } namespace AGS { namespace Engine { class IDriverDependantBitmap; } } @@ -33,4 +33,4 @@ AGS::Engine::IDriverDependantBitmap* prepare_screen_for_transition_in(); // Screenshot made in the last room, used during some of the transition effects extern AGS::Common::Bitmap *saved_viewport_bitmap; -#endif // __AGS_EE_AC__SCREEN_H +#endif diff --git a/engines/ags/engine/ac/screenoverlay.h b/engines/ags/engine/ac/screenoverlay.h index 18657baf2146..3f772edb49a8 100644 --- a/engines/ags/engine/ac/screenoverlay.h +++ b/engines/ags/engine/ac/screenoverlay.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SCREENOVERLAY_H -#define __AGS_EE_AC__SCREENOVERLAY_H +#ifndef AGS_ENGINE_AC_SCREENOVERLAY_H +#define AGS_ENGINE_AC_SCREENOVERLAY_H #include @@ -46,4 +46,4 @@ struct ScreenOverlay { void WriteToFile(Common::Stream *out) const; }; -#endif // __AGS_EE_AC__SCREENOVERLAY_H +#endif diff --git a/engines/ags/engine/ac/slider.h b/engines/ags/engine/ac/slider.h index e0e87e497f84..3ce4329cc24e 100644 --- a/engines/ags/engine/ac/slider.h +++ b/engines/ags/engine/ac/slider.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SLIDER_H -#define __AGS_EE_AC__SLIDER_H +#ifndef AGS_ENGINE_AC_SLIDER_H +#define AGS_ENGINE_AC_SLIDER_H #include "gui/guislider.h" @@ -40,4 +40,4 @@ void Slider_SetHandleGraphic(GUISlider *guisl, int newImage); int Slider_GetHandleOffset(GUISlider *guisl); void Slider_SetHandleOffset(GUISlider *guisl, int newOffset); -#endif // __AGS_EE_AC__SLIDER_H +#endif diff --git a/engines/ags/engine/ac/speech.h b/engines/ags/engine/ac/speech.h index 11dfe6896104..58179f8327cc 100644 --- a/engines/ags/engine/ac/speech.h +++ b/engines/ags/engine/ac/speech.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SPEECH_H -#define __AGS_EE_AC__SPEECH_H +#ifndef AGS_ENGINE_AC_SPEECH_H +#define AGS_ENGINE_AC_SPEECH_H enum SkipSpeechStyle { @@ -41,4 +41,4 @@ enum SkipSpeechStyle int user_to_internal_skip_speech(SkipSpeechStyle userval); SkipSpeechStyle internal_skip_speech_to_user(int internal_val); -#endif // __AGS_EE_AC__SPEECH_H +#endif diff --git a/engines/ags/engine/ac/sprite.h b/engines/ags/engine/ac/sprite.h index e2ba8cdc90a6..d97d00f74a56 100644 --- a/engines/ags/engine/ac/sprite.h +++ b/engines/ags/engine/ac/sprite.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SPRITE_H -#define __AGS_EE_AC__SPRITE_H +#ifndef AGS_ENGINE_AC_SPRITE_H +#define AGS_ENGINE_AC_SPRITE_H void get_new_size_for_sprite (int ee, int ww, int hh, int &newwid, int &newhit); // set any alpha-transparent pixels in the image to the appropriate @@ -32,4 +32,4 @@ Common::Bitmap *remove_alpha_channel(Common::Bitmap *from); void pre_save_sprite(int ee); void initialize_sprite (int ee); -#endif // __AGS_EE_AC__SPRITE_H +#endif diff --git a/engines/ags/engine/ac/spritelistentry.h b/engines/ags/engine/ac/spritelistentry.h index aa0be21f2e6b..aa45aad77c6c 100644 --- a/engines/ags/engine/ac/spritelistentry.h +++ b/engines/ags/engine/ac/spritelistentry.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SPRITELISTENTRY_H -#define __AGS_EE_AC__SPRITELISTENTRY_H +#ifndef AGS_ENGINE_AC_SPRITELISTENTRY_H +#define AGS_ENGINE_AC_SPRITELISTENTRY_H #include "gfx/ddb.h" @@ -38,4 +38,4 @@ struct SpriteListEntry SpriteListEntry(); }; -#endif // __AGS_EE_AC__SPRITELISTENTRY_H +#endif diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.h b/engines/ags/engine/ac/statobj/agsstaticobject.h index efccc6c2c0d4..49e00f0653f7 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.h +++ b/engines/ags/engine/ac/statobj/agsstaticobject.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_STATOBJ__AGSSTATICOBJECT_H -#define __AGS_EE_STATOBJ__AGSSTATICOBJECT_H +#ifndef _AGS_ENGINE_AC_STATICOBJ_AGSSTATICOBJECT_H +#define _AGS_ENGINE_AC_STATICOBJ_AGSSTATICOBJECT_H #include "ac/statobj/staticobject.h" @@ -50,4 +50,4 @@ struct StaticGame : public AGSStaticObject { extern AGSStaticObject GlobalStaticManager; extern StaticGame GameStaticManager; -#endif // __AGS_EE_STATOBJ__AGSSTATICOBJECT_H +#endif diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h index a4cf70e7115f..950894a72120 100644 --- a/engines/ags/engine/ac/statobj/staticarray.h +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_STATOBJ__STATICARRAY_H -#define __AGS_EE_STATOBJ__STATICARRAY_H +#ifndef _AGS_ENGINE_AC_STATICOBJ_STATICARRAY_H +#define _AGS_ENGINE_AC_STATICOBJ_STATICARRAY_H #include "ac/statobj/staticobject.h" @@ -66,4 +66,4 @@ struct StaticArray : public ICCStaticObject { int _elemCount; }; -#endif // __AGS_EE_STATOBJ__STATICOBJECT_H +#endif diff --git a/engines/ags/engine/ac/statobj/staticobject.h b/engines/ags/engine/ac/statobj/staticobject.h index e9fdabde4f66..3580f0c678cf 100644 --- a/engines/ags/engine/ac/statobj/staticobject.h +++ b/engines/ags/engine/ac/statobj/staticobject.h @@ -28,8 +28,8 @@ // //============================================================================= -#ifndef __AGS_EE_STATOBJ__STATICOBJECT_H -#define __AGS_EE_STATOBJ__STATICOBJECT_H +#ifndef AGS_ENGINE_AC_STATICOBJ_STATICOBJECT_H +#define AGS_ENGINE_AC_STATICOBJ_STATICOBJECT_H #include "core/types.h" @@ -50,4 +50,4 @@ struct ICCStaticObject { virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; }; -#endif // __AGS_EE_STATOBJ__STATICOBJECT_H +#endif diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h index a045e937774f..3a2865e637fc 100644 --- a/engines/ags/engine/ac/string.h +++ b/engines/ags/engine/ac/string.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__STRING_H -#define __AGS_EE_AC__STRING_H +#ifndef AGS_ENGINE_AC_STRING_H +#define AGS_ENGINE_AC_STRING_H #include #include "ac/dynobj/cc_dynamicobject.h" @@ -58,4 +58,4 @@ size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, i void check_strlen(char*ptt); void my_strncpy(char *dest, const char *src, int len); -#endif // __AGS_EE_AC__STRING_H +#endif diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h index 001ef11bed63..42e34f9c86be 100644 --- a/engines/ags/engine/ac/sys_events.h +++ b/engines/ags/engine/ac/sys_events.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SYS_EVENTS_H -#define __AGS_EE_AC__SYS_EVENTS_H +#ifndef AGS_ENGINE_AC_SYS_EVENTS_H +#define AGS_ENGINE_AC_SYS_EVENTS_H int ags_getch (); int ags_kbhit (); @@ -38,4 +38,4 @@ void ags_clear_input_buffer(); // TODO: seriously not a good design, replace with event listening void ags_wait_until_keypress(); -#endif // __AGS_EE_AC__SYS_EVENTS_H +#endif diff --git a/engines/ags/engine/ac/system.h b/engines/ags/engine/ac/system.h index ff096eb4872a..ba372a379745 100644 --- a/engines/ags/engine/ac/system.h +++ b/engines/ags/engine/ac/system.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__SYSTEMAUDIO_H -#define __AGS_EE_AC__SYSTEMAUDIO_H +#ifndef AGS_ENGINE_AC_SYSTEMAUDIO_H +#define AGS_ENGINE_AC_SYSTEMAUDIO_H #include "ac/dynobj/scriptaudiochannel.h" @@ -50,4 +50,4 @@ void System_SetVolume(int newvol); const char *System_GetRuntimeInfo(); -#endif // __AGS_EE_AC_SYSTEMAUDIO_H +#endif diff --git a/engines/ags/engine/ac/textbox.h b/engines/ags/engine/ac/textbox.h index 844f87b7d6ac..2f671e9988ec 100644 --- a/engines/ags/engine/ac/textbox.h +++ b/engines/ags/engine/ac/textbox.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__TEXTBOX_H -#define __AGS_EE_AC__TEXTBOX_H +#ifndef AGS_ENGINE_AC_TEXTBOX_H +#define AGS_ENGINE_AC_TEXTBOX_H #include "gui/guitextbox.h" @@ -35,4 +35,4 @@ void TextBox_SetTextColor(GUITextBox *guit, int colr); int TextBox_GetFont(GUITextBox *guit); void TextBox_SetFont(GUITextBox *guit, int fontnum); -#endif // __AGS_EE_AC__TEXTBOX_H +#endif diff --git a/engines/ags/engine/ac/timer.h b/engines/ags/engine/ac/timer.h index 44460d051b70..f6f1f0947bf7 100644 --- a/engines/ags/engine/ac/timer.h +++ b/engines/ags/engine/ac/timer.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__TIMER_H -#define __AGS_EE_AC__TIMER_H +#ifndef AGS_ENGINE_AC_TIMER_H +#define AGS_ENGINE_AC_TIMER_H #include #include @@ -42,4 +42,4 @@ extern bool isTimerFpsMaxed(); extern bool waitingForNextTick(); // store last tick time. extern void skipMissedTicks(); // if more than N frames, just skip all, start a fresh. -#endif // __AGS_EE_AC__TIMER_H +#endif diff --git a/engines/ags/engine/ac/topbarsettings.h b/engines/ags/engine/ac/topbarsettings.h index cf815fb7cd02..5a23efb1f837 100644 --- a/engines/ags/engine/ac/topbarsettings.h +++ b/engines/ags/engine/ac/topbarsettings.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__TOPBARSETTINGS_H -#define __AGS_EE_AC__TOPBARSETTINGS_H +#ifndef AGS_ENGINE_AC_TOPBARSETTINGS_H +#define AGS_ENGINE_AC_TOPBARSETTINGS_H struct TopBarSettings { int wantIt; @@ -37,4 +37,4 @@ struct TopBarSettings { } }; -#endif // __AGS_EE_AC__TOPBARSETTINGS_H +#endif diff --git a/engines/ags/engine/ac/translation.h b/engines/ags/engine/ac/translation.h index 2f65f56df899..a7692089c3bd 100644 --- a/engines/ags/engine/ac/translation.h +++ b/engines/ags/engine/ac/translation.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__TRANSLATION_H -#define __AGS_EE_AC__TRANSLATION_H +#ifndef AGS_ENGINE_AC_TRANSLATION_H +#define AGS_ENGINE_AC_TRANSLATION_H #include "util/string.h" @@ -30,4 +30,4 @@ using AGS::Common::String; void close_translation (); bool init_translation (const String &lang, const String &fallback_lang, bool quit_on_error); -#endif // __AGS_EE_AC__TRANSLATION_H +#endif diff --git a/engines/ags/engine/ac/tree_map.h b/engines/ags/engine/ac/tree_map.h index 7e907fb06fab..6c181f8e2cfb 100644 --- a/engines/ags/engine/ac/tree_map.h +++ b/engines/ags/engine/ac/tree_map.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__TREEMAP_H -#define __AGS_EE_AC__TREEMAP_H +#ifndef AGS_ENGINE_AC_TREEMAP_H +#define AGS_ENGINE_AC_TREEMAP_H // Binary tree structure for holding translations, allows fast // access @@ -37,4 +37,4 @@ struct TreeMap { ~TreeMap(); }; -#endif // __AGS_EE_AC__TREEMAP_H +#endif diff --git a/engines/ags/engine/ac/viewframe.h b/engines/ags/engine/ac/viewframe.h index d195b4fcdcdb..6b5e3b838897 100644 --- a/engines/ags/engine/ac/viewframe.h +++ b/engines/ags/engine/ac/viewframe.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__VIEWFRAME_H -#define __AGS_EE_AC__VIEWFRAME_H +#ifndef AGS_ENGINE_AC_VIEWFRAME_H +#define AGS_ENGINE_AC_VIEWFRAME_H #include "ac/runtime_defines.h" #include "ac/view.h" @@ -49,4 +49,4 @@ void CheckViewFrame (int view, int loop, int frame, int sound_volume=SCR_NO_VALU // draws a view frame, flipped if appropriate void DrawViewFrame(Common::Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend = false); -#endif // __AGS_EE_AC__VIEWFRAME_H +#endif diff --git a/engines/ags/engine/ac/walkablearea.h b/engines/ags/engine/ac/walkablearea.h index 8d024b948f11..b5694934bb3f 100644 --- a/engines/ags/engine/ac/walkablearea.h +++ b/engines/ags/engine/ac/walkablearea.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__WALKABLEAREA_H -#define __AGS_EE_AC__WALKABLEAREA_H +#ifndef AGS_ENGINE_AC_WALKABLEAREA_H +#define AGS_ENGINE_AC_WALKABLEAREA_H void redo_walkable_areas(); int get_walkable_area_pixel(int x, int y); @@ -33,4 +33,4 @@ Common::Bitmap *prepare_walkable_areas (int sourceChar); int get_walkable_area_at_location(int xx, int yy); int get_walkable_area_at_character (int charnum); -#endif // __AGS_EE_AC__WALKABLEAREA_H +#endif diff --git a/engines/ags/engine/ac/walkbehind.h b/engines/ags/engine/ac/walkbehind.h index 458081f76b37..a2210ede876f 100644 --- a/engines/ags/engine/ac/walkbehind.h +++ b/engines/ags/engine/ac/walkbehind.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_AC__WALKBEHIND_H -#define __AGS_EE_AC__WALKBEHIND_H +#ifndef AGS_ENGINE_AC_WALKBEHIND_H +#define AGS_ENGINE_AC_WALKBEHIND_H enum WalkBehindMethodEnum { @@ -33,4 +33,4 @@ enum WalkBehindMethodEnum void update_walk_behind_images(); void recache_walk_behinds (); -#endif // __AGS_EE_AC__WALKBEHIND_H +#endif diff --git a/engines/ags/engine/debugging/agseditordebugger.h b/engines/ags/engine/debugging/agseditordebugger.h index b94fd496f7b7..fdee2419e96a 100644 --- a/engines/ags/engine/debugging/agseditordebugger.h +++ b/engines/ags/engine/debugging/agseditordebugger.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H -#define __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H +#ifndef AGS_ENGINE_DEBUGGING_AGSEDITORDEBUGGER_H +#define AGS_ENGINE_DEBUGGING_AGSEDITORDEBUGGER_H struct IAGSEditorDebugger { @@ -36,4 +36,4 @@ struct IAGSEditorDebugger virtual char* GetNextMessage() = 0; }; -#endif // __AGS_EE_DEBUG__AGSEDITORDEBUGGER_H +#endif diff --git a/engines/ags/engine/debugging/consoleoutputtarget.h b/engines/ags/engine/debugging/consoleoutputtarget.h index c3913772d24d..d6cab71dcef9 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.h +++ b/engines/ags/engine/debugging/consoleoutputtarget.h @@ -27,8 +27,8 @@ // //============================================================================= -#ifndef __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H -#define __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H +#ifndef AGS_ENGINE_DEBUGGING_CONSOLEOUTPUTTARGET_H +#define AGS_ENGINE_DEBUGGING_CONSOLEOUTPUTTARGET_H #include "debug/outputhandler.h" @@ -52,4 +52,4 @@ class ConsoleOutputTarget : public AGS::Common::IOutputHandler } // namespace Engine } // namespace AGS -#endif // __AGS_EE_DEBUG__CONSOLEOUTPUTTARGET_H +#endif diff --git a/engines/ags/engine/debugging/debug_log.h b/engines/ags/engine/debugging/debug_log.h index afd62a973a0b..f5b677da8442 100644 --- a/engines/ags/engine/debugging/debug_log.h +++ b/engines/ags/engine/debugging/debug_log.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_DEBUG_LOG_H -#define __AC_DEBUG_LOG_H +#ifndef AGS_ENGINE_DEBUGGING_LOG_H +#define AGS_ENGINE_DEBUGGING_LOG_H #include "script/cc_instance.h" #include "ac/runtime_defines.h" @@ -53,4 +53,4 @@ extern int first_debug_line, last_debug_line, display_console; extern AGSPlatformDriver *platform; -#endif // __AC_DEBUG_LOG_H +#endif diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h index 9d57120cc775..5f8cb21a0e14 100644 --- a/engines/ags/engine/debugging/debugger.h +++ b/engines/ags/engine/debugging/debugger.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_DEBUGGER_H -#define __AC_DEBUGGER_H +#ifndef AGS_ENGINE_DEBUGGING_DEBUGGER_H +#define AGS_ENGINE_DEBUGGING_DEBUGGER_H #include "util/string.h" @@ -65,4 +65,4 @@ extern float fps; extern FPSDisplayMode display_fps; extern int debug_flags; -#endif // __AC_DEBUGGER_H +#endif diff --git a/engines/ags/engine/debugging/dummyagsdebugger.h b/engines/ags/engine/debugging/dummyagsdebugger.h index 448b3b21a47c..140baffc30dc 100644 --- a/engines/ags/engine/debugging/dummyagsdebugger.h +++ b/engines/ags/engine/debugging/dummyagsdebugger.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_DUMMYAGSDEBUGGER_H -#define __AC_DUMMYAGSDEBUGGER_H +#ifndef AGS_ENGINE_DEBUGGING_DUMMYAGSDEBUGGER_H +#define AGS_ENGINE_DEBUGGING_DUMMYAGSDEBUGGER_H #include "debug/debugger.h" @@ -36,4 +36,4 @@ struct DummyAGSDebugger : IAGSEditorDebugger virtual char* GetNextMessage() override { return NULL; } }; -#endif // __AC_DUMMYAGSDEBUGGER_H +#endif diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.h b/engines/ags/engine/debugging/filebasedagsdebugger.h index 25e7a177a1a4..1caeee702e3f 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.h +++ b/engines/ags/engine/debugging/filebasedagsdebugger.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_FILEBASEDAGSDEBUGGER_H -#define __AC_FILEBASEDAGSDEBUGGER_H +#ifndef AGS_ENGINE_DEBUGGING_FILEBASEDAGSDEBUGGER_H +#define AGS_ENGINE_DEBUGGING_FILEBASEDAGSDEBUGGER_H #include "debug/agseditordebugger.h" @@ -39,4 +39,4 @@ struct FileBasedAGSDebugger : IAGSEditorDebugger extern const char* SENT_MESSAGE_FILE_NAME; -#endif // __AC_FILEBASEDAGSDEBUGGER_H +#endif diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h index 976121656374..4bf8d8a96a0c 100644 --- a/engines/ags/engine/debugging/logfile.h +++ b/engines/ags/engine/debugging/logfile.h @@ -32,8 +32,8 @@ // //============================================================================= -#ifndef __AGS_EE_DEBUG__LOGFILE_H -#define __AGS_EE_DEBUG__LOGFILE_H +#ifndef AGS_ENGINE_DEBUGGING_LOGFILE_H +#define AGS_ENGINE_DEBUGGING_LOGFILE_H #include #include "debug/outputhandler.h" @@ -86,4 +86,4 @@ class LogFile : public AGS::Common::IOutputHandler } // namespace Engine } // namespace AGS -#endif // __AGS_EE_DEBUG__LOGFILE_H +#endif diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h index effde36a4cde..e8f986f1118e 100644 --- a/engines/ags/engine/debugging/messagebuffer.h +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -28,8 +28,8 @@ // //============================================================================= -#ifndef __AGS_EE_DEBUG__MESSAGEBUFFER_H -#define __AGS_EE_DEBUG__MESSAGEBUFFER_H +#ifndef AGS_ENGINE_DEBUGGING_MESSAGEBUFFER_H +#define AGS_ENGINE_DEBUGGING_MESSAGEBUFFER_H #include #include "debug/outputhandler.h" @@ -65,4 +65,4 @@ class MessageBuffer : public AGS::Common::IOutputHandler } // namespace Engine } // namespace AGS -#endif // __AGS_EE_DEBUG__MESSAGEBUFFER_H +#endif diff --git a/engines/ags/engine/game/game_init.h b/engines/ags/engine/game/game_init.h index 2ad5752ce827..89ce79c917bd 100644 --- a/engines/ags/engine/game/game_init.h +++ b/engines/ags/engine/game/game_init.h @@ -27,8 +27,8 @@ // //============================================================================= -#ifndef __AGS_EE_GAME__GAMEINIT_H -#define __AGS_EE_GAME__GAMEINIT_H +#ifndef AGS_ENGINE_GAME_GAMEINIT_H +#define AGS_ENGINE_GAME_GAMEINIT_H #include "game/main_game_file.h" #include "util/string.h" @@ -64,4 +64,4 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion da } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GAME__GAMEINIT_H +#endif diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h index d6b4cd49f15c..d13ddebe8b18 100644 --- a/engines/ags/engine/game/savegame.h +++ b/engines/ags/engine/game/savegame.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GAME__SAVEGAME_H -#define __AGS_EE_GAME__SAVEGAME_H +#ifndef AGS_ENGINE_GAME_SAVEGAME_H +#define AGS_ENGINE_GAME_SAVEGAME_H #include #include "ac/game_version.h" @@ -174,4 +174,4 @@ void SaveGameState(PStream out); } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GAME__SAVEGAME_H +#endif diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h index 95b8555b1a69..7f99fe7d501d 100644 --- a/engines/ags/engine/game/savegame_components.h +++ b/engines/ags/engine/game/savegame_components.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GAME__SAVEGAMECOMPONENTS_H -#define __AGS_EE_GAME__SAVEGAMECOMPONENTS_H +#ifndef AGS_ENGINE_GAME_SAVEGAMECOMPONENTS_H +#define AGS_ENGINE_GAME_SAVEGAMECOMPONENTS_H #include "game/savegame.h" #include "util/stream.h" @@ -61,4 +61,4 @@ namespace SavegameComponents } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GAME__SAVEGAMECOMPONENTS_H +#endif diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index 8633fc53f3d8..bfbda8f0b46a 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GAME__SAVEGAMEINTERNAL_H -#define __AGS_EE_GAME__SAVEGAMEINTERNAL_H +#ifndef AGS_ENGINE_GAME_SAVEGAMEINTERNAL_H +#define AGS_ENGINE_GAME_SAVEGAMEINTERNAL_H #include #include @@ -149,4 +149,4 @@ struct RestoredData } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GAME__SAVEGAMEINTERNAL_H +#endif diff --git a/engines/ags/engine/game/viewport.h b/engines/ags/engine/game/viewport.h index 6f4604d228ef..f6f820f14dbf 100644 --- a/engines/ags/engine/game/viewport.h +++ b/engines/ags/engine/game/viewport.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_AC__VIEWPORT_H -#define __AGS_EE_AC__VIEWPORT_H +#ifndef AGS_ENGINE_GAME_VIEWPORT_H +#define AGS_ENGINE_GAME_VIEWPORT_H #include #include @@ -200,4 +200,4 @@ class Viewport bool _hasChangedVisible = false; }; -#endif // __AGS_EE_AC__VIEWPORT_H +#endif diff --git a/engines/ags/engine/gfx/ali3dexception.h b/engines/ags/engine/gfx/ali3dexception.h index f27d24194b55..ab5fc9423050 100644 --- a/engines/ags/engine/gfx/ali3dexception.h +++ b/engines/ags/engine/gfx/ali3dexception.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__ALI3DEXCEPTION_H -#define __AGS_EE_GFX__ALI3DEXCEPTION_H +#ifndef AGS_ENGINE_GFX_ALI3DEXCEPTION_H +#define AGS_ENGINE_GFX_ALI3DEXCEPTION_H namespace AGS { @@ -56,4 +56,4 @@ class Ali3DFullscreenLostException : public Ali3DException } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__ALI3DEXCEPTION_H +#endif diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h index d3d6268fa4e6..2b3a6eece983 100644 --- a/engines/ags/engine/gfx/ali3dogl.h +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__ALI3DOGL_H -#define __AGS_EE_GFX__ALI3DOGL_H +#ifndef AGS_ENGINE_GFX_ALI3DOGL_H +#define AGS_ENGINE_GFX_ALI3DOGL_H #include #include "gfx/bitmap.h" @@ -369,4 +369,4 @@ class OGLGraphicsFactory : public GfxDriverFactoryBase @@ -277,4 +277,4 @@ class ALSWGraphicsFactory : public GfxDriverFactoryBase #include "gfx/ddb.h" @@ -259,4 +259,4 @@ class VideoMemoryGraphicsDriver : public GraphicsDriverBase } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__GFXDRIVERBASE_H +#endif diff --git a/engines/ags/engine/gfx/gfxdriverfactory.h b/engines/ags/engine/gfx/gfxdriverfactory.h index 63d6479e705b..75e10ef402a4 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.h +++ b/engines/ags/engine/gfx/gfxdriverfactory.h @@ -30,8 +30,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__GFXDRIVERFACTORY_H -#define __AGS_EE_GFX__GFXDRIVERFACTORY_H +#ifndef AGS_ENGINE_GFX_GFXDRIVERFACTORY_H +#define AGS_ENGINE_GFX_GFXDRIVERFACTORY_H #include #include "util/string.h" @@ -84,4 +84,4 @@ IGfxDriverFactory *GetGfxDriverFactory(const String id); } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__GFXDRIVERFACTORY_H +#endif diff --git a/engines/ags/engine/gfx/gfxdriverfactorybase.h b/engines/ags/engine/gfx/gfxdriverfactorybase.h index 93710a3ad828..7962d35d8d85 100644 --- a/engines/ags/engine/gfx/gfxdriverfactorybase.h +++ b/engines/ags/engine/gfx/gfxdriverfactorybase.h @@ -30,8 +30,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__GFXDRIVERFACTORYBASE_H -#define __AGS_EE_GFX__GFXDRIVERFACTORYBASE_H +#ifndef AGS_ENGINE_GFX_GFXDRIVERFACTORYBASE_H +#define AGS_ENGINE_GFX_GFXDRIVERFACTORYBASE_H #include #include "gfx/gfxdriverfactory.h" @@ -117,4 +117,4 @@ class GfxDriverFactoryBase : public IGfxDriverFactory } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__GFXDRIVERFACTORYBASE_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter.h b/engines/ags/engine/gfx/gfxfilter.h index 5f6554dda279..04e937ac845c 100644 --- a/engines/ags/engine/gfx/gfxfilter.h +++ b/engines/ags/engine/gfx/gfxfilter.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__GFXFILTER_H -#define __AGS_EE_GFX__GFXFILTER_H +#ifndef AGS_ENGINE_GFX_GFXFILTER_H +#define AGS_ENGINE_GFX_GFXFILTER_H #include #include "util/geometry.h" @@ -78,4 +78,4 @@ typedef std::shared_ptr PGfxFilter; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__GFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.h b/engines/ags/engine/gfx/gfxfilter_aad3d.h index 5ae4af25c5a2..e730cde9b27e 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.h +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__AAD3DGFXFILTER_H -#define __AGS_EE_GFX__AAD3DGFXFILTER_H +#ifndef AGS_ENGINE_GFX_AAD3DGFXFILTER_H +#define AGS_ENGINE_GFX_AAD3DGFXFILTER_H #include "gfx/gfxfilter_d3d.h" @@ -53,4 +53,4 @@ class AAD3DGfxFilter : public D3DGfxFilter } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__AAD3DGFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.h b/engines/ags/engine/gfx/gfxfilter_aaogl.h index d1f5f93d1af4..d8939efce879 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.h +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__AAOGLGFXFILTER_H -#define __AGS_EE_GFX__AAOGLGFXFILTER_H +#ifndef AGS_ENGINE_GFX_AAOGLGFXFILTER_H +#define AGS_ENGINE_GFX_AAOGLGFXFILTER_H #include "gfx/gfxfilter_ogl.h" @@ -53,4 +53,4 @@ class AAOGLGfxFilter : public OGLGfxFilter } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__AAOGLGFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h index 74f01b341bc6..9c2497740ead 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.h +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__ALLEGROGFXFILTER_H -#define __AGS_EE_GFX__ALLEGROGFXFILTER_H +#ifndef AGS_ENGINE_GFX_ALLEGROGFXFILTER_H +#define AGS_ENGINE_GFX_ALLEGROGFXFILTER_H #include "gfx/bitmap.h" #include "gfx/gfxfilter_scaling.h" @@ -78,4 +78,4 @@ class AllegroGfxFilter : public ScalingGfxFilter } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__ALLEGROGFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.h b/engines/ags/engine/gfx/gfxfilter_d3d.h index c688ddfec39f..1b1798c2cc92 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.h +++ b/engines/ags/engine/gfx/gfxfilter_d3d.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__D3DGFXFILTER_H -#define __AGS_EE_GFX__D3DGFXFILTER_H +#ifndef AGS_ENGINE_GFX_D3DGFXFILTER_H +#define AGS_ENGINE_GFX_D3DGFXFILTER_H #include "gfx/gfxfilter_scaling.h" @@ -53,4 +53,4 @@ class D3DGfxFilter : public ScalingGfxFilter } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__D3DGFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h index 97c0d0ef73fb..fc3db3c64f38 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.h +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__HQ2XGFXFILTER_H -#define __AGS_EE_GFX__HQ2XGFXFILTER_H +#ifndef AGS_ENGINE_GFX_HQ2XGFXFILTER_H +#define AGS_ENGINE_GFX_HQ2XGFXFILTER_H #include "gfx/gfxfilter_allegro.h" @@ -65,4 +65,4 @@ class HqxGfxFilter : public AllegroGfxFilter } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__HQ2XGFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.h b/engines/ags/engine/gfx/gfxfilter_ogl.h index c41bc6f56b69..4b90e56c9a9e 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.h +++ b/engines/ags/engine/gfx/gfxfilter_ogl.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__OGLGFXFILTER_H -#define __AGS_EE_GFX__OGLGFXFILTER_H +#ifndef AGS_ENGINE_GFX_OGLGFXFILTER_H +#define AGS_ENGINE_GFX_OGLGFXFILTER_H #include "gfx/gfxfilter_scaling.h" @@ -53,4 +53,4 @@ class OGLGfxFilter : public ScalingGfxFilter } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__OGLGFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.h b/engines/ags/engine/gfx/gfxfilter_scaling.h index 228e934dd519..fb1e2f342818 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.h +++ b/engines/ags/engine/gfx/gfxfilter_scaling.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__SCALINGGFXFILTER_H -#define __AGS_EE_GFX__SCALINGGFXFILTER_H +#ifndef AGS_ENGINE_GFX_SCALINGGFXFILTER_H +#define AGS_ENGINE_GFX_SCALINGGFXFILTER_H #include "gfx/gfxfilter.h" #include "util/scaling.h" @@ -53,4 +53,4 @@ class ScalingGfxFilter : public IGfxFilter } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__SCALINGGFXFILTER_H +#endif diff --git a/engines/ags/engine/gfx/gfxmodelist.h b/engines/ags/engine/gfx/gfxmodelist.h index 62eb38f690ac..7ae841776ed8 100644 --- a/engines/ags/engine/gfx/gfxmodelist.h +++ b/engines/ags/engine/gfx/gfxmodelist.h @@ -25,8 +25,9 @@ // Supported graphics mode interface // //============================================================================= -#ifndef __AGS_EE_GFX__GFXMODELIST_H -#define __AGS_EE_GFX__GFXMODELIST_H + +#ifndef AGS_ENGINE_GFX_GFXMODELIST_H +#define AGS_ENGINE_GFX_GFXMODELIST_H #include "core/types.h" #include "gfx/gfxdefines.h" @@ -47,4 +48,4 @@ class IGfxModeList } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__GFXMODELIST_H +#endif diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h index 0af51ecd1c41..52fb9061983c 100644 --- a/engines/ags/engine/gfx/graphicsdriver.h +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__GRAPHICSDRIVER_H -#define __AGS_EE_GFX__GRAPHICSDRIVER_H +#ifndef AGS_ENGINE_GFX_GRAPHICSDRIVER_H +#define AGS_ENGINE_GFX_GRAPHICSDRIVER_H #include #include "gfx/gfxdefines.h" @@ -197,4 +197,4 @@ class IGraphicsDriver } // namespace Engine } // namespace AGS -#endif // __AGS_EE_GFX__GRAPHICSDRIVER_H +#endif diff --git a/engines/ags/engine/gfx/hq2x3x.h b/engines/ags/engine/gfx/hq2x3x.h index d569a642c630..b6d2595936f8 100644 --- a/engines/ags/engine/gfx/hq2x3x.h +++ b/engines/ags/engine/gfx/hq2x3x.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_HQ2X3X_H -#define __AC_HQ2X3X_H +#ifndef AGS_ENGINE_GFX_HQ2X3X_H +#define AGS_ENGINE_GFX_HQ2X3X_H #include "core/platform.h" @@ -35,4 +35,4 @@ void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); #endif -#endif // __AC_HQ2X3X_H +#endif diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h index fccdd7432831..7fb060da90fa 100644 --- a/engines/ags/engine/gui/animatingguibutton.h +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GUI__ANIMATINGGUIBUTTON_H -#define __AGS_EE_GUI__ANIMATINGGUIBUTTON_H +#ifndef AGS_ENGINE_GUI_ANIMATINGGUIBUTTON_H +#define AGS_ENGINE_GUI_ANIMATINGGUIBUTTON_H #include "ac/runtime_defines.h" @@ -40,4 +40,4 @@ struct AnimatingGUIButton { void WriteToFile(Common::Stream *out); }; -#endif // __AGS_EE_GUI__ANIMATINGGUIBUTTON_H +#endif diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h index 0246479e76bb..ebee093d29fc 100644 --- a/engines/ags/engine/gui/cscidialog.h +++ b/engines/ags/engine/gui/cscidialog.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GUI__CSCIDIALOG_H -#define __AGS_EE_GUI__CSCIDIALOG_H +#ifndef AGS_ENGINE_GUI_CSCIDIALOG_H +#define AGS_ENGINE_GUI_CSCIDIALOG_H #include "gui/guidialoginternaldefs.h" @@ -44,4 +44,4 @@ int checkcontrols(); int finddefaultcontrol(int flagmask); int GetBaseWidth (); -#endif // __AGS_EE_GUI__CSCIDIALOG_H +#endif diff --git a/engines/ags/engine/gui/guidialog.h b/engines/ags/engine/gui/guidialog.h index aedca8609977..1c605e3cc192 100644 --- a/engines/ags/engine/gui/guidialog.h +++ b/engines/ags/engine/gui/guidialog.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GUI__GUIDIALOG_H -#define __AGS_EE_GUI__GUIDIALOG_H +#ifndef AGS_ENGINE_GUI_GUIDIALOG_H +#define AGS_ENGINE_GUI_GUIDIALOG_H namespace AGS { namespace Common { class Bitmap; } } @@ -46,4 +46,4 @@ int quitdialog(); // last string value in gui dialog. char *get_gui_dialog_buffer(); -#endif // __AGS_EE_GUI__GUIDIALOG_H +#endif diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h index 82d783d5027b..c805a77f3e2d 100644 --- a/engines/ags/engine/gui/guidialogdefines.h +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GUI__GUIDIALOGDEFINES_H -#define __AGS_EE_GUI__GUIDIALOGDEFINES_H +#ifndef AGS_ENGINE_GUI_GUIDIALOGDEFINES_H +#define AGS_ENGINE_GUI_GUIDIALOGDEFINES_H #define MSG_RESTORE 984 #define MSG_CANCEL 985 // "Cancel" @@ -113,4 +113,4 @@ struct OnScreenWindow OnScreenWindow(); }; -#endif // __AGS_EE_GUI__GUIDIALOGDEFINES_H +#endif diff --git a/engines/ags/engine/gui/guidialoginternaldefs.h b/engines/ags/engine/gui/guidialoginternaldefs.h index 2de4f5639ae7..c00842cdde16 100644 --- a/engines/ags/engine/gui/guidialoginternaldefs.h +++ b/engines/ags/engine/gui/guidialoginternaldefs.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H -#define __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H +#ifndef AGS_ENGINE_GUI_GUIDIALOGINTERNALDEFS_H +#define AGS_ENGINE_GUI_GUIDIALOGINTERNALDEFS_H #include "gui/guidialogdefines.h" @@ -34,4 +34,4 @@ extern int ags_misbuttondown (int but); #define mbutrelease(X) (!ags_misbuttondown(X)) #define TEXT_HT usetup.textheight -#endif // __AGS_EE_GUI__GUIDIALOGINTERNALDEFS_H +#endif diff --git a/engines/ags/engine/gui/mycontrols.h b/engines/ags/engine/gui/mycontrols.h index df6b2b178d66..d0fd99a8086b 100644 --- a/engines/ags/engine/gui/mycontrols.h +++ b/engines/ags/engine/gui/mycontrols.h @@ -26,12 +26,12 @@ // //============================================================================= -#ifndef __AGS_EE_GUI__MYCONTROLS_H -#define __AGS_EE_GUI__MYCONTROLS_H +#ifndef AGS_ENGINE_GUI_MYCONTROLS_H +#define AGS_ENGINE_GUI_MYCONTROLS_H #include "gui/mylabel.h" #include "gui/mylistbox.h" #include "gui/mypushbutton.h" #include "gui/mytextbox.h" -#endif // __AGS_EE_GUI__MYCONTROLS_H +#endif diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h index efa6ec8b43fa..49f891b28d8e 100644 --- a/engines/ags/engine/gui/mylabel.h +++ b/engines/ags/engine/gui/mylabel.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYLABEL_H -#define __AC_MYLABEL_H +#ifndef AGS_ENGINE_GUI_MYLABEL_H +#define AGS_ENGINE_GUI_MYLABEL_H #include "gui/newcontrol.h" @@ -37,4 +37,4 @@ struct MyLabel:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_MYLABEL_H +#endif diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h index 271bdbd94fc9..d65a6b69cd1b 100644 --- a/engines/ags/engine/gui/mylistbox.h +++ b/engines/ags/engine/gui/mylistbox.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYLISTBOX_H -#define __AC_MYLISTBOX_H +#ifndef AGS_ENGINE_GUI_MYLISTBOX_H +#define AGS_ENGINE_GUI_MYLISTBOX_H #include "gui/newcontrol.h" @@ -42,4 +42,4 @@ struct MyListBox:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_MYLISTBOX_H +#endif diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h index 56832759cc51..00b21f624e97 100644 --- a/engines/ags/engine/gui/mypushbutton.h +++ b/engines/ags/engine/gui/mypushbutton.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_PUSHBUTTON_H -#define __AC_PUSHBUTTON_H +#ifndef AGS_ENGINE_GUI_PUSHBUTTON_H +#define AGS_ENGINE_GUI_PUSHBUTTON_H #include "gui/newcontrol.h" @@ -34,4 +34,4 @@ struct MyPushButton:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_PUSHBUTTON_H +#endif diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h index 6fb47c258861..0dd68f4a6327 100644 --- a/engines/ags/engine/gui/mytextbox.h +++ b/engines/ags/engine/gui/mytextbox.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYTEXTBOX_H -#define __AC_MYTEXTBOX_H +#ifndef AGS_ENGINE_GUI_MYTEXTBOX_H +#define AGS_ENGINE_GUI_MYTEXTBOX_H #include "gui/newcontrol.h" @@ -35,4 +35,4 @@ struct MyTextBox:public NewControl int processmessage(int mcode, int wParam, long lParam) override; }; -#endif // __AC_MYTEXTBOX_H +#endif diff --git a/engines/ags/engine/gui/newcontrol.h b/engines/ags/engine/gui/newcontrol.h index 550e6619889a..a0b7e2081341 100644 --- a/engines/ags/engine/gui/newcontrol.h +++ b/engines/ags/engine/gui/newcontrol.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_GUI__NEWCONTROL_H -#define __AGS_EE_GUI__NEWCONTROL_H +#ifndef AGS_ENGINE_GUI_NEWCONTROL_H +#define AGS_ENGINE_GUI_NEWCONTROL_H #include "gfx/bitmap.h" @@ -44,4 +44,4 @@ struct NewControl void drawandmouse(); }; -#endif // __AGS_EE_GUI__NEWCONTROL_H +#endif diff --git a/engines/ags/engine/main/config.h b/engines/ags/engine/main/config.h index 98ae4214375a..77dab9e32328 100644 --- a/engines/ags/engine/main/config.h +++ b/engines/ags/engine/main/config.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__CONFIG_H -#define __AGS_EE_MAIN__CONFIG_H +#ifndef AGS_ENGINE_MAIN_CONFIG_H +#define AGS_ENGINE_MAIN_CONFIG_H #include "main/graphics_mode.h" #include "util/ini_util.h" @@ -78,4 +78,4 @@ void INIwritestring(ConfigTree &cfg, const String §n, const String &item, co void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int value); -#endif // __AGS_EE_MAIN__CONFIG_H +#endif diff --git a/engines/ags/engine/main/engine.h b/engines/ags/engine/main/engine.h index 5a83b4788393..ef3e96796e0e 100644 --- a/engines/ags/engine/main/engine.h +++ b/engines/ags/engine/main/engine.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__ENGINE_H -#define __AGS_EE_MAIN__ENGINE_H +#ifndef AGS_ENGINE_MAIN_ENGINE_H +#define AGS_ENGINE_MAIN_ENGINE_H #include "util/ini_util.h" @@ -64,4 +64,4 @@ extern ResourcePaths ResPaths; typedef void (*t_engine_pre_init_callback)(void); extern void engine_set_pre_init_callback(t_engine_pre_init_callback callback); -#endif // __AGS_EE_MAIN__ENGINE_H +#endif diff --git a/engines/ags/engine/main/engine_setup.h b/engines/ags/engine/main/engine_setup.h index a1d9dd2c3b2c..9c4a42451727 100644 --- a/engines/ags/engine/main/engine_setup.h +++ b/engines/ags/engine/main/engine_setup.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__ENGINESETUP_H -#define __AGS_EE_MAIN__ENGINESETUP_H +#ifndef AGS_ENGINE_MAIN_ENGINESETUP_H +#define AGS_ENGINE_MAIN_ENGINESETUP_H #include "util/geometry.h" #include "gfx/gfxdefines.h" @@ -38,4 +38,4 @@ void engine_pre_gfxsystem_shutdown(); // Applies necessary changes after screen<->virtual coordinate transformation has changed void on_coordinates_scaling_changed(); -#endif // __AGS_EE_MAIN__ENGINESETUP_H +#endif diff --git a/engines/ags/engine/main/game_file.h b/engines/ags/engine/main/game_file.h index 6422096f42d3..d63929bff52a 100644 --- a/engines/ags/engine/main/game_file.h +++ b/engines/ags/engine/main/game_file.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__GAMEFILE_H -#define __AGS_EE_MAIN__GAMEFILE_H +#ifndef AGS_ENGINE_MAIN_GAMEFILE_H +#define AGS_ENGINE_MAIN_GAMEFILE_H #include "util/error.h" #include "util/string.h" @@ -34,4 +34,4 @@ HError preload_game_data(); HError load_game_file(); void display_game_file_error(HError err); -#endif // __AGS_EE_MAIN__GAMEFILE_H +#endif diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h index 2a87af861bd9..58ddaa6ddb2f 100644 --- a/engines/ags/engine/main/game_run.h +++ b/engines/ags/engine/main/game_run.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__GAMERUN_H -#define __AGS_EE_MAIN__GAMERUN_H +#ifndef AGS_ENGINE_MAIN_GAME_RUN_H +#define AGS_ENGINE_MAIN_GAME_RUN_H namespace AGS { namespace Engine { class IDriverDependantBitmap; }} using namespace AGS::Engine; // FIXME later @@ -50,4 +50,4 @@ bool run_service_key_controls(int &kgn); // otherwise returns true and provides mouse button code. bool run_service_mb_controls(int &mbut, int &mwheelz); -#endif // __AGS_EE_MAIN__GAMERUN_H +#endif diff --git a/engines/ags/engine/main/game_start.h b/engines/ags/engine/main/game_start.h index 4f79e4e71dcb..d672229c98a7 100644 --- a/engines/ags/engine/main/game_start.h +++ b/engines/ags/engine/main/game_start.h @@ -20,10 +20,10 @@ * */ -#ifndef __AGS_EE_MAIN__GAMESTART_H -#define __AGS_EE_MAIN__GAMESTART_H +#ifndef AGS_ENGINE_MAIN_GAME_START_H +#define AGS_ENGINE_MAIN_GAME_START_H void start_game(); void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup); -#endif // __AGS_EE_MAIN__GAMESTART_H +#endif diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h index 426f3d2200f8..8e5f7a23e619 100644 --- a/engines/ags/engine/main/graphics_mode.h +++ b/engines/ags/engine/main/graphics_mode.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__GRAPHICSMODE_H -#define __AGS_EE_MAIN__GRAPHICSMODE_H +#ifndef AGS_ENGINE_MAIN_GRAPHICSMODE_H +#define AGS_ENGINE_MAIN_GRAPHICSMODE_H #include "gfx/gfxdefines.h" #include "util/scaling.h" @@ -160,4 +160,4 @@ bool graphics_mode_set_filter(const String &filter_id); // Releases current graphic mode and shuts down renderer void graphics_mode_shutdown(); -#endif // __AGS_EE_MAIN__GRAPHICSMODE_H +#endif diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index 9dc115506d85..cd3a27e9b933 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__MAIN_H -#define __AGS_EE_MAIN__MAIN_H +#ifndef AGS_ENGINE_MAIN_MAIN_H +#define AGS_ENGINE_MAIN_MAIN_H #include "core/platform.h" #include "util/version.h" @@ -67,4 +67,4 @@ void main_print_help(); int ags_entry_point(int argc, char *argv[]); -#endif // __AGS_EE_MAIN__MAIN_H +#endif diff --git a/engines/ags/engine/main/main_allegro.h b/engines/ags/engine/main/main_allegro.h index 177c7d932831..c6f0d3e7dbd2 100644 --- a/engines/ags/engine/main/main_allegro.h +++ b/engines/ags/engine/main/main_allegro.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__MAINALLEGRO_H -#define __AGS_EE_MAIN__MAINALLEGRO_H +#ifndef AGS_ENGINE_MAIN_MAINALLEGRO_H +#define AGS_ENGINE_MAIN_MAINALLEGRO_H // Gets allegro_error as a const string. // Please, use this getter to acquire error text, do not use allegro_error @@ -33,4 +33,4 @@ const char *get_allegro_error(); // truncated. Null terminator is always guaranteed. const char *set_allegro_error(const char *format, ...); -#endif // __AGS_EE_MAIN__MAINALLEGRO_H +#endif diff --git a/engines/ags/engine/main/maindefines_ex.h b/engines/ags/engine/main/maindefines_ex.h index 32e214464702..6c66b3ed1129 100644 --- a/engines/ags/engine/main/maindefines_ex.h +++ b/engines/ags/engine/main/maindefines_ex.h @@ -20,9 +20,9 @@ * */ -#ifndef __AGS_EE_MAIN__MAINDEFINES_H -#define __AGS_EE_MAIN__MAINDEFINES_H +#ifndef AGS_ENGINE_MAIN_MAINDEFINES_H +#define AGS_ENGINE_MAIN_MAINDEFINES_H #define RETURN_CONTINUE 1 -#endif // __AGS_EE_MAIN__MAINDEFINES_H +#endif diff --git a/engines/ags/engine/main/mainheader.h b/engines/ags/engine/main/mainheader.h index 1739068bcbb0..406e5c0787b8 100644 --- a/engines/ags/engine/main/mainheader.h +++ b/engines/ags/engine/main/mainheader.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__MAINHEADER_H -#define __AGS_EE_MAIN__MAINHEADER_H +#ifndef AGS_ENGINE_MAIN_MAINHEADER_H +#define AGS_ENGINE_MAIN_MAINHEADER_H #include "core/platform.h" @@ -49,4 +49,4 @@ extern "C" void selectLatestSavegame(); extern bool psp_load_latest_savegame; #endif -#endif // __AGS_EE_MAIN__MAINHEADER_H +#endif diff --git a/engines/ags/engine/main/quit.h b/engines/ags/engine/main/quit.h index 2afd0eeaa57a..569aa90e5e06 100644 --- a/engines/ags/engine/main/quit.h +++ b/engines/ags/engine/main/quit.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MAIN__QUIT_H -#define __AGS_EE_MAIN__QUIT_H +#ifndef AGS_ENGINE_MAIN_QUIT_H +#define AGS_ENGINE_MAIN_QUIT_H enum QuitReason { @@ -47,4 +47,4 @@ enum QuitReason kQuit_FatalError = kQuitKind_EngineException }; -#endif // __AGS_EE_MAIN__QUIT_H +#endif diff --git a/engines/ags/engine/main/update.h b/engines/ags/engine/main/update.h index ff89a549e2b0..c7bcde862e54 100644 --- a/engines/ags/engine/main/update.h +++ b/engines/ags/engine/main/update.h @@ -20,12 +20,12 @@ * */ -#ifndef __AGS_EE_MAIN__UPDATE_H -#define __AGS_EE_MAIN__UPDATE_H +#ifndef AGS_ENGINE_MAIN_UPDATE_H +#define AGS_ENGINE_MAIN_UPDATE_H #define MAX_SHEEP 30 // sheep == follower int do_movelist_move(short*mlnum,int*xx,int*yy); void update_stuff(); -#endif // __AGS_EE_MAIN__UPDATE_H +#endif diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h index 1144eda9ad29..edefea665ca7 100644 --- a/engines/ags/engine/media/audio/ambientsound.h +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_AMBIENTSOUND_H -#define __AC_AMBIENTSOUND_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_AMBIENTSOUND_H +#define AGS_ENGINE_MEDIA_AUDIO_AMBIENTSOUND_H // Forward declaration namespace AGS { namespace Common { class Stream; } } @@ -42,4 +42,4 @@ struct AmbientSound { void WriteToFile(Common::Stream *out); }; -#endif // __AC_AMBIENTSOUND_H +#endif diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index 1d0a239dce30..eff2c5dd6a50 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_AUDIO_H -#define __AC_AUDIO_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_AUDIO_H +#define AGS_ENGINE_MEDIA_AUDIO_AUDIO_H #include #include "media/audio/audiodefines.h" @@ -158,4 +158,4 @@ extern SOUNDCLIP *cachedQueuedMusic; // TODO: double check that ambient sounds array actually needs +1 extern std::array ambient; -#endif // __AC_AUDIO_H +#endif diff --git a/engines/ags/engine/media/audio/audio_system.h b/engines/ags/engine/media/audio/audio_system.h index 9bb5e1cb1afa..202f0238d2ce 100644 --- a/engines/ags/engine/media/audio/audio_system.h +++ b/engines/ags/engine/media/audio/audio_system.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MEDIA_AUDIO_SYSTEM_H -#define __AC_MEDIA_AUDIO_SYSTEM_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_AUDIO_SYSTEM_H +#define AGS_ENGINE_MEDIA_AUDIO_AUDIO_SYSTEM_H #include "media/audio/audiodefines.h" #include "media/audio/ambientsound.h" diff --git a/engines/ags/engine/media/audio/audiodefines.h b/engines/ags/engine/media/audio/audiodefines.h index ee7757cc9054..9f8cf7d7bed9 100644 --- a/engines/ags/engine/media/audio/audiodefines.h +++ b/engines/ags/engine/media/audio/audiodefines.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_AUDIODEFINES_H -#define __AC_AUDIODEFINES_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_AUDIODEFINES_H +#define AGS_ENGINE_MEDIA_AUDIO_AUDIODEFINES_H #define MUS_MIDI 1 #define MUS_MP3 2 @@ -44,4 +44,4 @@ #define AUDIOTYPE_LEGACY_MUSIC 2 #define AUDIOTYPE_LEGACY_SOUND 3 -#endif // __AC_AUDIODEFINES_H +#endif diff --git a/engines/ags/engine/media/audio/audiointernaldefs.h b/engines/ags/engine/media/audio/audiointernaldefs.h index 3dce5d80cae8..94fb568bc1e9 100644 --- a/engines/ags/engine/media/audio/audiointernaldefs.h +++ b/engines/ags/engine/media/audio/audiointernaldefs.h @@ -20,10 +20,10 @@ * */ -#ifndef __AC_SOUNDINTERNALDEFS_H -#define __AC_SOUNDINTERNALDEFS_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_SOUNDINTERNALDEFS_H +#define AGS_ENGINE_MEDIA_AUDIO_SOUNDINTERNALDEFS_H //#define MP3CHUNKSIZE 100000 #define MP3CHUNKSIZE 32768 -#endif // __AC_SOUNDINTERNALDEFS_H +#endif diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index 8c20a135aeac..bb7e2741746a 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYDUMBMOD_H -#define __AC_MYDUMBMOD_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H #include "aldumb.h" #include "media/audio/soundclip.h" @@ -74,4 +74,4 @@ struct MYMOD : public SOUNDCLIP int get_real_mod_pos(); }; -#endif // __AC_MYDUMBMOD_H +#endif diff --git a/engines/ags/engine/media/audio/clip_myjgmod.h b/engines/ags/engine/media/audio/clip_myjgmod.h index 9ddb82bbf214..82d7ff3e038d 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.h +++ b/engines/ags/engine/media/audio/clip_myjgmod.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYJGMOD_H -#define __AC_MYJGMOD_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYJGMOD_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYJGMOD_H #include "jgmod.h" #include "media/audio/soundclip.h" @@ -54,4 +54,4 @@ struct MYMOD:public SOUNDCLIP MYMOD(); }; -#endif // __AC_MYJGMOD_H +#endif diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index 0eccf714a85f..b7970f60efd5 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYMIDI_H -#define __AC_MYMIDI_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMIDI_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMIDI_H #include "media/audio/soundclip.h" @@ -60,4 +60,4 @@ struct MYMIDI:public SOUNDCLIP void adjust_volume() override; }; -#endif // __AC_MYMIDI_H +#endif diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index cf5ee292fdba..c7cde052f122 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYMP3_H -#define __AC_MYMP3_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H #include "almp3.h" #include "media/audio/soundclip.h" @@ -55,4 +55,4 @@ struct MYMP3:public SOUNDCLIP void adjust_stream(); }; -#endif // __AC_MYMP3_H +#endif diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h index 26625f5c5272..06793a8e3182 100644 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYOGG_H -#define __AC_MYOGG_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H #include "alogg.h" #include "media/audio/soundclip.h" @@ -65,4 +65,4 @@ struct MYOGG:public SOUNDCLIP void adjust_stream(); }; -#endif // __AC_MYOGG_H +#endif diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index a5b803135349..0c992cd0ac8e 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYSTATICMP3_H -#define __AC_MYSTATICMP3_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H #include "almp3.h" #include "media/audio/soundclip.h" @@ -62,4 +62,4 @@ struct MYSTATICMP3:public SOUNDCLIP void adjust_stream(); }; -#endif // __AC_MYSTATICMP3_H +#endif diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h index 4e2f3a1de2a3..e40bc2b792f5 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYSTATICOGG_H -#define __AC_MYSTATICOGG_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H #include "alogg.h" #include "media/audio/soundclip.h" @@ -68,4 +68,4 @@ struct MYSTATICOGG:public SOUNDCLIP void adjust_stream(); }; -#endif // __AC_MYSTATICOGG_H +#endif diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h index 094f36eedbdc..d80947bf5371 100644 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MYWAVE_H -#define __AC_MYWAVE_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H +#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H #include "media/audio/soundclip.h" @@ -55,4 +55,4 @@ struct MYWAVE:public SOUNDCLIP void adjust_volume() override; }; -#endif // __AC_MYWAVE_H +#endif diff --git a/engines/ags/engine/media/audio/queuedaudioitem.h b/engines/ags/engine/media/audio/queuedaudioitem.h index d5024de57cf0..7b548da50b55 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.h +++ b/engines/ags/engine/media/audio/queuedaudioitem.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_QUEUEDAUDIOITEM_H -#define __AC_QUEUEDAUDIOITEM_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_QUEUEDAUDIOITEM_H +#define AGS_ENGINE_MEDIA_AUDIO_QUEUEDAUDIOITEM_H struct SOUNDCLIP; @@ -38,4 +38,4 @@ struct QueuedAudioItem { void WriteToFile(Common::Stream *out) const; }; -#endif // __AC_QUEUEDAUDIOITEM_H +#endif diff --git a/engines/ags/engine/media/audio/sound.h b/engines/ags/engine/media/audio/sound.h index 67c9438e1afd..0d51ffbeda99 100644 --- a/engines/ags/engine/media/audio/sound.h +++ b/engines/ags/engine/media/audio/sound.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AC_SOUND_H -#define __AC_SOUND_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_SOUND_H +#define AGS_ENGINE_MEDIA_AUDIO_SOUND_H #include "ac/asset_helper.h" #include "media/audio/soundclip.h" @@ -42,4 +42,4 @@ SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet); extern int use_extra_sound_offset; -#endif // __AC_SOUND_H +#endif diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h index 21bb6b6b67f4..1943462cc2b2 100644 --- a/engines/ags/engine/media/audio/soundcache.h +++ b/engines/ags/engine/media/audio/soundcache.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_SOUNDCACHE_H -#define __AC_SOUNDCACHE_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_SOUNDCACHE_H +#define AGS_ENGINE_MEDIA_AUDIO_SOUNDCACHE_H #include "ac/asset_helper.h" @@ -53,4 +53,4 @@ void sound_cache_free(char* buffer, bool is_wave); char* get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size); -#endif // __AC_SOUNDCACHE_H +#endif diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index 5a0d6e9a6049..e2f2300fda68 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AC_SOUNDCLIP_H -#define __AC_SOUNDCLIP_H +#ifndef AGS_ENGINE_MEDIA_AUDIO_SOUNDCLIP_H +#define AGS_ENGINE_MEDIA_AUDIO_SOUNDCLIP_H #include "util/mutex.h" @@ -177,4 +177,4 @@ struct SOUNDCLIP } }; -#endif // __AC_SOUNDCLIP_H +#endif diff --git a/engines/ags/engine/media/video/VMR9Graph.h b/engines/ags/engine/media/video/VMR9Graph.h index 3f424dd556c5..2b6b52011f4a 100644 --- a/engines/ags/engine/media/video/VMR9Graph.h +++ b/engines/ags/engine/media/video/VMR9Graph.h @@ -31,7 +31,7 @@ #if _MSC_VER > 1000 #pragma once -#endif // _MSC_VER > 1000 +#endif #include #include @@ -157,4 +157,4 @@ class CVMR9Graph IDirect3DSurface9* m_pD3DSurface; }; -#endif // !defined(AFX_VMR9GRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_) +#endif diff --git a/engines/ags/engine/media/video/video.h b/engines/ags/engine/media/video/video.h index b627fe13ba06..fd330820550d 100644 --- a/engines/ags/engine/media/video/video.h +++ b/engines/ags/engine/media/video/video.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_MEDIA__VIDEO_H -#define __AGS_EE_MEDIA__VIDEO_H +#ifndef AGS_ENGINE_MEDIA_VIDEO_VIDEO_H +#define AGS_ENGINE_MEDIA_VIDEO_VIDEO_H void play_theora_video(const char *name, int skip, int flags); void play_flc_file(int numb,int playflags); @@ -29,4 +29,4 @@ void play_flc_file(int numb,int playflags); // Update video playback if the display mode has changed void video_on_gfxmode_changed(); -#endif // __AGS_EE_MEDIA__VIDEO_H +#endif diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 5ce00e0e9062..c8b6975c6aac 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_PLATFORM__AGSPLATFORMDRIVER_H -#define __AGS_EE_PLATFORM__AGSPLATFORMDRIVER_H +#ifndef AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H +#define AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H #include #include @@ -177,4 +177,4 @@ int cd_player_control(int cmdd, int datt); // instance by calling AGSPlatformDriver::GetDriver()? extern AGSPlatformDriver *platform; -#endif // __AGS_EE_PLATFORM__AGSPLATFORMDRIVER_H +#endif diff --git a/engines/ags/engine/platform/util/pe.h b/engines/ags/engine/platform/util/pe.h index 060968f7765e..871079f4d36e 100644 --- a/engines/ags/engine/platform/util/pe.h +++ b/engines/ags/engine/platform/util/pe.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_PLATFORM_UTIL_PE_H -#define __AGS_EE_PLATFORM_UTIL_PE_H +#ifndef AGS_ENGINE_PLATFORM_UTIL_PE_H +#define AGS_ENGINE_PLATFORM_UTIL_PE_H #ifdef __cplusplus extern "C" { @@ -39,4 +39,4 @@ int getVersionInformation(char* filename, version_info_t* version_info); } #endif -#endif // __AGS_EE_PLATFORM_UTIL_PE_H +#endif diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp new file mode 100644 index 000000000000..d540ddb7c774 --- /dev/null +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp @@ -0,0 +1,108 @@ +/* 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 "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS + +#include "platform/windows/debug/namedpipesagsdebugger.h" + +#include // sprintf + +void NamedPipesAGSDebugger::SendAcknowledgement() +{ + DWORD bytesWritten; + WriteFile(_hPipeSending, "MSGACK", 6, &bytesWritten, NULL); +} + + +NamedPipesAGSDebugger::NamedPipesAGSDebugger(const char *instanceToken) +{ + _hPipeSending = NULL; + _hPipeReading = NULL; + _instanceToken = instanceToken; +} + +bool NamedPipesAGSDebugger::Initialize() +{ + // can't use a single duplex pipe as it was deadlocking + char pipeNameBuffer[MAX_PATH]; + sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerGameToEd%s", _instanceToken); + _hPipeSending = CreateFile(pipeNameBuffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, NULL); + + sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerEdToGame%s", _instanceToken); + _hPipeReading = CreateFile(pipeNameBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING,0, NULL); + + if ((_hPipeReading == INVALID_HANDLE_VALUE) || + (_hPipeSending == INVALID_HANDLE_VALUE)) + return false; + + return true; +} + +void NamedPipesAGSDebugger::Shutdown() +{ + if (_hPipeReading != NULL) + { + CloseHandle(_hPipeReading); + CloseHandle(_hPipeSending); + _hPipeReading = NULL; + } +} + +bool NamedPipesAGSDebugger::SendMessageToEditor(const char *message) +{ + DWORD bytesWritten; + return (WriteFile(_hPipeSending, message, strlen(message), &bytesWritten, NULL ) != 0); +} + +bool NamedPipesAGSDebugger::IsMessageAvailable() +{ + DWORD bytesAvailable = 0; + PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL); + + return (bytesAvailable > 0); +} + +char* NamedPipesAGSDebugger::GetNextMessage() +{ + DWORD bytesAvailable = 0; + PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL); + + if (bytesAvailable > 0) + { + char* buffer = (char*)malloc(bytesAvailable + 1); + DWORD bytesRead = 0; + ReadFile(_hPipeReading, buffer, bytesAvailable, &bytesRead, NULL); + buffer[bytesRead] = 0; + + SendAcknowledgement(); + return buffer; + } + else + { + return NULL; + } + +} + +#endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h new file mode 100644 index 000000000000..104e31804f33 --- /dev/null +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h @@ -0,0 +1,48 @@ +/* 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 AGS_ENGINE_DEBUGGING_NAMEDPIPESAGSDEBUGGER_H +#define AGS_ENGINE_DEBUGGING_NAMEDPIPESAGSDEBUGGER_H + +#include +#include +#include "debug/agseditordebugger.h" + +struct NamedPipesAGSDebugger : IAGSEditorDebugger +{ +private: + HANDLE _hPipeSending; + HANDLE _hPipeReading; + const char *_instanceToken; + + void SendAcknowledgement(); +public: + + NamedPipesAGSDebugger(const char *instanceToken); + virtual bool Initialize() override; + virtual void Shutdown() override; + virtual bool SendMessageToEditor(const char *message) override; + virtual bool IsMessageAvailable() override; + virtual char* GetNextMessage() override; +}; + +#endif diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index cd04214f6871..f809f43a3859 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_GFX__ALI3DD3D_H -#define __AGS_EE_GFX__ALI3DD3D_H +#ifndef AGS_ENGINE_PLATFORM_WINDOWS_ALI3DD3D_H +#define AGS_ENGINE_PLATFORM_WINDOWS_ALI3DD3D_H #include "core/platform.h" @@ -343,4 +343,4 @@ class D3DGraphicsFactory : public GfxDriverFactoryBase #include "game/game_init.h" @@ -54,4 +54,4 @@ bool pl_any_want_hook(int event); void pl_set_file_handle(long data, AGS::Common::Stream *stream); void pl_clear_file_handle(); -#endif // __AGS_EE_PLUGIN__PLUGINENGINE_H +#endif diff --git a/engines/ags/engine/plugin/pluginobjectreader.h b/engines/ags/engine/plugin/pluginobjectreader.h index 00cb03c5697b..a768ad00dcb0 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.h +++ b/engines/ags/engine/plugin/pluginobjectreader.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H -#define __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H +#ifndef AGS_ENGINE_PLUGIN_PLUGINOBJECTREADER_H +#define AGS_ENGINE_PLUGIN_PLUGINOBJECTREADER_H class IAGSManagedObjectReader; @@ -30,4 +30,4 @@ struct PluginObjectReader { const char *type; }; -#endif // __AGS_EE_PLUGIN__PLUGINOBJECTREADER_H +#endif diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h index f01ac4a9752b..725f3681e64c 100644 --- a/engines/ags/engine/script/cc_instance.h +++ b/engines/ags/engine/script/cc_instance.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __CC_INSTANCE_H -#define __CC_INSTANCE_H +#ifndef AGS_ENGINE_SCRIPT_CCINSTANCE_H +#define AGS_ENGINE_SCRIPT_CCINSTANCE_H #include #include @@ -228,4 +228,4 @@ struct ccInstance void PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries); }; -#endif // __CC_INSTANCE_H +#endif diff --git a/engines/ags/engine/script/executingscript.h b/engines/ags/engine/script/executingscript.h index ffe68fcc37f9..1d09f6781b51 100644 --- a/engines/ags/engine/script/executingscript.h +++ b/engines/ags/engine/script/executingscript.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H -#define __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H +#ifndef AGS_ENGINE_SCRIPT_EXECUTINGSCRIPT_H +#define AGS_ENGINE_SCRIPT_EXECUTINGSCRIPT_H #include "script/cc_instance.h" @@ -76,4 +76,4 @@ struct ExecutingScript { ExecutingScript(); }; -#endif // __AGS_EE_SCRIPT__EXECUTINGSCRIPT_H +#endif diff --git a/engines/ags/engine/script/exports.h b/engines/ags/engine/script/exports.h index 0829c9557e75..81459c6fdcff 100644 --- a/engines/ags/engine/script/exports.h +++ b/engines/ags/engine/script/exports.h @@ -26,9 +26,9 @@ // //============================================================================= -#ifndef __AGS_EE_SCRIPT__EXPORTS_H -#define __AGS_EE_SCRIPT__EXPORTS_H +#ifndef AGS_ENGINE_SCRIPT_EXPORTS_H +#define AGS_ENGINE_SCRIPT_EXPORTS_H void setup_script_exports(ScriptAPIVersion base_api, ScriptAPIVersion compat_api); -#endif // __AGS_EE_SCRIPT__EXPORTS_H +#endif diff --git a/engines/ags/engine/script/nonblockingscriptfunction.h b/engines/ags/engine/script/nonblockingscriptfunction.h index d924296809d2..61b6af800168 100644 --- a/engines/ags/engine/script/nonblockingscriptfunction.h +++ b/engines/ags/engine/script/nonblockingscriptfunction.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H -#define __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H +#ifndef AGS_ENGINE_SCRIPT_NONBLOCKINGSCRIPTFUNCTION_H +#define AGS_ENGINE_SCRIPT_NONBLOCKINGSCRIPTFUNCTION_H #include "ac/runtime_defines.h" #include "script/runtimescriptvalue.h" @@ -50,4 +50,4 @@ struct NonBlockingScriptFunction } }; -#endif // __AGS_EE_SCRIPT__NONBLOCKINGSCRIPTFUNCTION_H +#endif diff --git a/engines/ags/engine/script/runtimescriptvalue.h b/engines/ags/engine/script/runtimescriptvalue.h index 85b1b716a699..7397a8346ce7 100644 --- a/engines/ags/engine/script/runtimescriptvalue.h +++ b/engines/ags/engine/script/runtimescriptvalue.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H -#define __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H +#ifndef AGS_ENGINE_SCRIPT_RUNTIMESCRIPTVALUE_H +#define AGS_ENGINE_SCRIPT_RUNTIMESCRIPTVALUE_H #include "script/script_api.h" #include "util/memory.h" @@ -393,4 +393,4 @@ struct RuntimeScriptValue intptr_t GetDirectPtr() const; }; -#endif // __AGS_EE_SCRIPT__RUNTIMESCRIPTVALUE_H +#endif diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h index 7404f776ac32..68ac9d598b30 100644 --- a/engines/ags/engine/script/script.h +++ b/engines/ags/engine/script/script.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_SCRIPT__SCRIPT_H -#define __AGS_EE_SCRIPT__SCRIPT_H +#ifndef AGS_ENGINE_SCRIPT_SCRIPT_H +#define AGS_ENGINE_SCRIPT_SCRIPT_H #include @@ -121,4 +121,4 @@ extern std::vector characterScriptObjNames; extern AGS::Common::String objectScriptObjNames[MAX_ROOM_OBJECTS]; extern std::vector guiScriptObjNames; -#endif // __AGS_EE_SCRIPT__SCRIPT_H +#endif diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h index 601ace14f75f..e333c7dc86f0 100644 --- a/engines/ags/engine/script/script_api.h +++ b/engines/ags/engine/script/script_api.h @@ -27,8 +27,8 @@ // //============================================================================= -#ifndef __AGS_EE_SCRIPT__SCRIPTAPI_H -#define __AGS_EE_SCRIPT__SCRIPTAPI_H +#ifndef AGS_ENGINE_SCRIPT_SCRIPTAPI_H +#define AGS_ENGINE_SCRIPT_SCRIPTAPI_H #include #include "core/types.h" @@ -558,4 +558,4 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f RET_CLASS* ret_obj = METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) -#endif // __AGS_EE_SCRIPT__SCRIPTAPI_H +#endif diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h index af636ab774e6..a98f075f5f19 100644 --- a/engines/ags/engine/script/script_runtime.h +++ b/engines/ags/engine/script/script_runtime.h @@ -34,8 +34,8 @@ // //============================================================================= -#ifndef __CS_RUNTIME_H -#define __CS_RUNTIME_H +#ifndef AGS_ENGINE_SCRIPT_SCRIPT_RUNTIME_H +#define AGS_ENGINE_SCRIPT_SCRIPT_RUNTIME_H #include "script/cc_script.h" // ccScript #include "script/cc_instance.h" // ccInstance @@ -74,7 +74,6 @@ extern void *ccGetSymbolAddressForPlugin(const String &name); // DEBUG HOOK typedef void (*new_line_hook_type) (ccInstance *, int); extern void ccSetDebugHook(new_line_hook_type jibble); -#endif // Set the number of while loop iterations that aborts the script extern void ccSetScriptAliveTimer (int); @@ -83,3 +82,5 @@ extern void ccNotifyScriptStillAlive (); // for calling exported plugin functions old-style extern int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms); extern void nullfree(void *data); // in script/script_runtime + +#endif diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index 90dc7ea968b5..99392bdadda5 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -20,8 +20,8 @@ * */ -#ifndef __CC_SYSTEMIMPORTS_H -#define __CC_SYSTEMIMPORTS_H +#ifndef AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H +#define AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H #include #include "script/cc_instance.h" // ccInstance @@ -68,4 +68,4 @@ extern SystemImports simp; // perform old style unsafe function calls extern SystemImports simp_for_plugin; -#endif // __CC_SYSTEMIMPORTS_H +#endif diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h index 7e4f7ac70729..c5c6976977db 100644 --- a/engines/ags/engine/util/library.h +++ b/engines/ags/engine/util/library.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__LIBRARY_H -#define __AGS_EE_UTIL__LIBRARY_H +#ifndef AGS_ENGINE_UTIL_LIBRARY_H +#define AGS_ENGINE_UTIL_LIBRARY_H #include "core/platform.h" #include "util/string.h" @@ -31,7 +31,6 @@ namespace AGS namespace Engine { - class BaseLibrary { public: @@ -66,5 +65,4 @@ class BaseLibrary #endif - -#endif // __AGS_EE_UTIL__MUTEX_H +#endif diff --git a/engines/ags/engine/util/library_dummy.h b/engines/ags/engine/util/library_dummy.h index dd22849d5b41..189f5c6110d8 100644 --- a/engines/ags/engine/util/library_dummy.h +++ b/engines/ags/engine/util/library_dummy.h @@ -20,9 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__LIBRARY_DUMMY_H -#define __AGS_EE_UTIL__LIBRARY_DUMMY_H - +#ifndef AGS_ENGINE_UTIL_LIBRARY_DUMMY_H +#define AGS_ENGINE_UTIL_LIBRARY_DUMMY_H namespace AGS { @@ -70,6 +69,4 @@ typedef DummyLibrary Library; } // namespace Engine } // namespace AGS - - -#endif // __AGS_EE_UTIL__LIBRARY_DUMMY_H +#endif diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index 1b738d230f03..4cf166ed1816 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__LIBRARY_POSIX_H -#define __AGS_EE_UTIL__LIBRARY_POSIX_H +#ifndef AGS_ENGINE_UTIL_LIBRARY_POSIX_H +#define AGS_ENGINE_UTIL_LIBRARY_POSIX_H #include #include "core/platform.h" @@ -156,6 +156,4 @@ typedef PosixLibrary Library; } // namespace Engine } // namespace AGS - - -#endif // __AGS_EE_UTIL__LIBRARY_POSIX_H +#endif diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h index 0ab345d4afda..845f7b35f77a 100644 --- a/engines/ags/engine/util/library_psp.h +++ b/engines/ags/engine/util/library_psp.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__LIBRARY_PSP_H -#define __AGS_EE_UTIL__LIBRARY_PSP_H +#ifndef AGS_ENGINE_UTIL_LIBRARY_PSP_H +#define AGS_ENGINE_UTIL_LIBRARY_PSP_H #include #include "util/string.h" @@ -155,11 +155,7 @@ class PSPLibrary : BaseLibrary typedef PSPLibrary Library; - - } // namespace Engine } // namespace AGS - - -#endif // __AGS_EE_UTIL__LIBRARY_PSP_H +#endif diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h index 7b811689fec7..27e804aafa55 100644 --- a/engines/ags/engine/util/library_windows.h +++ b/engines/ags/engine/util/library_windows.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__LIBRARY_WINDOWS_H -#define __AGS_EE_UTIL__LIBRARY_WINDOWS_H +#ifndef AGS_ENGINE_UTIL_LIBRARY_WINDOWS_H +#define AGS_ENGINE_UTIL_LIBRARY_WINDOWS_H #include "debug/out.h" #include "platform/windows/winapi_exclusive.h" @@ -118,6 +118,4 @@ typedef WindowsLibrary Library; } // namespace Engine } // namespace AGS - - -#endif // __AGS_EE_UTIL__LIBRARY_WINDOWS_H +#endif diff --git a/engines/ags/engine/util/mutex.h b/engines/ags/engine/util/mutex.h index b559680af4e5..7919a1c44269 100644 --- a/engines/ags/engine/util/mutex.h +++ b/engines/ags/engine/util/mutex.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__MUTEX_H -#define __AGS_EE_UTIL__MUTEX_H +#ifndef AGS_ENGINE_UTIL_MUTEX_H +#define AGS_ENGINE_UTIL_MUTEX_H namespace AGS { @@ -55,4 +55,4 @@ class BaseMutex #include "mutex_std.h" #endif -#endif // __AGS_EE_UTIL__MUTEX_H +#endif diff --git a/engines/ags/engine/util/mutex_base.h b/engines/ags/engine/util/mutex_base.h index 9329f1c2a9f7..e4d63f48e5ad 100644 --- a/engines/ags/engine/util/mutex_base.h +++ b/engines/ags/engine/util/mutex_base.h @@ -20,9 +20,8 @@ * */ -#ifndef __AGS_EE_PLATFORM__MUTEX_BASE_H -#define __AGS_EE_PLATFORM__MUTEX_BASE_H - +#ifndef AGS_ENGINE_UTIL_MUTEX_BASE_H +#define AGS_ENGINE_UTIL_MUTEX_BASE_H namespace AGS { @@ -43,4 +42,4 @@ class BaseMutex } // namespace Common } // namespace AGS -#endif // __AGS_EE_PLATFORM__MUTEX_BASE_H +#endif diff --git a/engines/ags/engine/util/mutex_lock.h b/engines/ags/engine/util/mutex_lock.h index c9561d95c95d..a6d5873991b8 100644 --- a/engines/ags/engine/util/mutex_lock.h +++ b/engines/ags/engine/util/mutex_lock.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__MUTEX_LOCK_H -#define __AGS_EE_UTIL__MUTEX_LOCK_H +#ifndef AGS_ENGINE_UTIL_MUTEX_LOCK_H +#define AGS_ENGINE_UTIL_MUTEX_LOCK_H #include "util/mutex.h" @@ -71,4 +71,4 @@ class MutexLock } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__MUTEX_LOCK_H +#endif diff --git a/engines/ags/engine/util/mutex_psp.h b/engines/ags/engine/util/mutex_psp.h index 81920a28afac..8e40697e8be7 100644 --- a/engines/ags/engine/util/mutex_psp.h +++ b/engines/ags/engine/util/mutex_psp.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__PSP_MUTEX_H -#define __AGS_EE_UTIL__PSP_MUTEX_H +#ifndef AGS_ENGINE_UTIL_PSP_MUTEX_H +#define AGS_ENGINE_UTIL_PSP_MUTEX_H #include #include @@ -67,4 +67,4 @@ typedef PSPMutex Mutex; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__PSP_MUTEX_H +#endif diff --git a/engines/ags/engine/util/mutex_pthread.h b/engines/ags/engine/util/mutex_pthread.h index 940531b19e03..9716e3f7fdbe 100644 --- a/engines/ags/engine/util/mutex_pthread.h +++ b/engines/ags/engine/util/mutex_pthread.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__MUTEX_PTHREAD_H -#define __AGS_EE_UTIL__MUTEX_PTHREAD_H +#ifndef AGS_ENGINE_UTIL_MUTEX_PTHREAD_H +#define AGS_ENGINE_UTIL_MUTEX_PTHREAD_H #include @@ -64,4 +64,4 @@ typedef PThreadMutex Mutex; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__MUTEX_PTHREAD_H +#endif diff --git a/engines/ags/engine/util/mutex_std.h b/engines/ags/engine/util/mutex_std.h index 137c1321089a..28ad2f44ff5c 100644 --- a/engines/ags/engine/util/mutex_std.h +++ b/engines/ags/engine/util/mutex_std.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__MUTEX_STD_H -#define __AGS_EE_UTIL__MUTEX_STD_H +#ifndef AGS_ENGINE_UTIL_MUTEX_STD_H +#define AGS_ENGINE_UTIL_MUTEX_STD_H #include @@ -51,4 +51,4 @@ typedef StdMutex Mutex; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__MUTEX_STD_H +#endif diff --git a/engines/ags/engine/util/mutex_wii.h b/engines/ags/engine/util/mutex_wii.h index 93ae9f3b74a3..fbc635993dcb 100644 --- a/engines/ags/engine/util/mutex_wii.h +++ b/engines/ags/engine/util/mutex_wii.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__WII_MUTEX_H -#define __AGS_EE_UTIL__WII_MUTEX_H +#ifndef AGS_ENGINE_UTIL_WII_MUTEX_H +#define AGS_ENGINE_UTIL_WII_MUTEX_H #include @@ -65,4 +65,4 @@ typedef WiiMutex Mutex; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__WII_MUTEX_H +#endif diff --git a/engines/ags/engine/util/mutex_windows.h b/engines/ags/engine/util/mutex_windows.h index 0e3c4c0ba545..4f4748451cac 100644 --- a/engines/ags/engine/util/mutex_windows.h +++ b/engines/ags/engine/util/mutex_windows.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__WINDOWS_MUTEX_H -#define __AGS_EE_UTIL__WINDOWS_MUTEX_H +#ifndef AGS_ENGINE_UTIL_MUTEXT_WINDOWS_H +#define AGS_ENGINE_UTIL_MUTEXT_WINDOWS_H namespace AGS { @@ -71,4 +71,4 @@ typedef WindowsMutex Mutex; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__WINDOWS_MUTEX_H +#endif diff --git a/engines/ags/engine/util/scaling.h b/engines/ags/engine/util/scaling.h index 8ccf81e9bc14..d8c2b1e6cd81 100644 --- a/engines/ags/engine/util/scaling.h +++ b/engines/ags/engine/util/scaling.h @@ -29,8 +29,8 @@ // //============================================================================= -#ifndef __AGS_EE_UTIL__SCALING_H -#define __AGS_EE_UTIL__SCALING_H +#ifndef AGS_ENGINE_UTIL_SCALING_H +#define AGS_ENGINE_UTIL_SCALING_H #include "core/types.h" #include "util/geometry.h" @@ -181,4 +181,4 @@ struct PlaneScaling } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__SCALING_H +#endif diff --git a/engines/ags/engine/util/thread.h b/engines/ags/engine/util/thread.h index 8a64b3caa5ee..00625915a660 100644 --- a/engines/ags/engine/util/thread.h +++ b/engines/ags/engine/util/thread.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__THREAD_H -#define __AGS_EE_UTIL__THREAD_H +#ifndef AGS_ENGINE_UTIL_THREAD_H +#define AGS_ENGINE_UTIL_THREAD_H namespace AGS { @@ -61,4 +61,4 @@ class BaseThread #endif -#endif // __AGS_EE_UTIL__THREAD_H +#endif diff --git a/engines/ags/engine/util/thread_psp.h b/engines/ags/engine/util/thread_psp.h index 1439f6a76823..10d7d059ed5e 100644 --- a/engines/ags/engine/util/thread_psp.h +++ b/engines/ags/engine/util/thread_psp.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_UTIL__PSP_THREAD_H -#define __AGS_EE_UTIL__PSP_THREAD_H +#ifndef AGS_ENGINE_UTIL_PSP_THREAD_H +#define AGS_ENGINE_UTIL_PSP_THREAD_H #include #include @@ -120,4 +120,4 @@ typedef PSPThread Thread; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_UTIL__PSP_THREAD_H +#endif diff --git a/engines/ags/engine/util/thread_pthread.h b/engines/ags/engine/util/thread_pthread.h index ebfad040b9d4..5a8ecc6a8708 100644 --- a/engines/ags/engine/util/thread_pthread.h +++ b/engines/ags/engine/util/thread_pthread.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_PLATFORM__THREAD_PTHREAD_H -#define __AGS_EE_PLATFORM__THREAD_PTHREAD_H +#ifndef AGS_ENGINE_UTIL_THREAD_PTHREAD_H +#define AGS_ENGINE_UTIL_THREAD_PTHREAD_H #include @@ -119,4 +119,4 @@ typedef PThreadThread Thread; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_PLATFORM__THREAD_PTHREAD_H +#endif diff --git a/engines/ags/engine/util/thread_std.h b/engines/ags/engine/util/thread_std.h index bb56882d0a1a..8bb4501ef32c 100644 --- a/engines/ags/engine/util/thread_std.h +++ b/engines/ags/engine/util/thread_std.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_PLATFORM__THREAD_STD_H -#define __AGS_EE_PLATFORM__THREAD_STD_H +#ifndef AGS_ENGINE_UTIL_THREAD_STD_H +#define AGS_ENGINE_UTIL_THREAD_STD_H #include #include @@ -102,4 +102,4 @@ typedef StdThread Thread; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_PLATFORM__THREAD_STD_H +#endif diff --git a/engines/ags/engine/util/thread_wii.h b/engines/ags/engine/util/thread_wii.h index f4baec16aecc..134ded3f9f6b 100644 --- a/engines/ags/engine/util/thread_wii.h +++ b/engines/ags/engine/util/thread_wii.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_PLATFORM__THREAD_WII_H -#define __AGS_EE_PLATFORM__THREAD_WII_H +#ifndef AGS_ENGINE_UTIL_THREAD_WII_H +#define AGS_ENGINE_UTIL_THREAD_WII_H #include @@ -119,4 +119,4 @@ typedef WiiThread Thread; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_PLATFORM__THREAD_WII_H +#endif diff --git a/engines/ags/engine/util/thread_windows.h b/engines/ags/engine/util/thread_windows.h index d8a09cf1be98..a27c4018ad44 100644 --- a/engines/ags/engine/util/thread_windows.h +++ b/engines/ags/engine/util/thread_windows.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_EE_PLATFORM__THREAD_WINDOWS_H -#define __AGS_EE_PLATFORM__THREAD_WINDOWS_H +#ifndef AGS_ENGINE_UTIL_THREAD_WINDOWS_H +#define AGS_ENGINE_UTIL_THREAD_WINDOWS_H namespace AGS { @@ -120,4 +120,4 @@ typedef WindowsThread Thread; } // namespace Engine } // namespace AGS -#endif // __AGS_EE_PLATFORM__THREAD_WINDOWS_H +#endif diff --git a/engines/ags/shared/ac/audiocliptype.h b/engines/ags/shared/ac/audiocliptype.h index 80628d3f05b8..c7997705fb2b 100644 --- a/engines/ags/shared/ac/audiocliptype.h +++ b/engines/ags/shared/ac/audiocliptype.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_AUDIOCLIPTYPE_H -#define __AC_AUDIOCLIPTYPE_H +#ifndef AGS_SHARED_AC_AUDIOCLIPTYPE_H +#define AGS_SHARED_AC_AUDIOCLIPTYPE_H // Forward declaration namespace AGS { namespace Common { class Stream; } } @@ -41,4 +41,4 @@ struct AudioClipType { void WriteToSavegame(Common::Stream *out) const; }; -#endif // __AC_AUDIOCLIPTYPE_H +#endif diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h index adafa53d82c8..614179ec662c 100644 --- a/engines/ags/shared/ac/characterinfo.h +++ b/engines/ags/shared/ac/characterinfo.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_CHARACTERINFO_H -#define __AC_CHARACTERINFO_H +#ifndef AGS_SHARED_AC_CHARACTERINFO_H +#define AGS_SHARED_AC_CHARACTERINFO_H #include "ac/common_defines.h" // constants @@ -149,4 +149,4 @@ struct OldCharacterInfo { #define COPY_CHAR_VAR(name) ci->name = oci->name void ConvertOldCharacterToNew (OldCharacterInfo *oci, CharacterInfo *ci); -#endif // __AC_CHARACTERINFO_H +#endif diff --git a/engines/ags/shared/ac/common.h b/engines/ags/shared/ac/common.h index 54b7e87edef3..2d857485f6ac 100644 --- a/engines/ags/shared/ac/common.h +++ b/engines/ags/shared/ac/common.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_COMMON_H -#define __AC_COMMON_H +#ifndef AGS_SHARED_AC_COMMON_H +#define AGS_SHARED_AC_COMMON_H // These are the project-dependent functions, they are defined both in Engine.App and AGS.Native. void quit(const char *); @@ -32,4 +32,4 @@ int get_our_eip(); extern const char *game_file_sig; -#endif // __AC_COMMON_H +#endif diff --git a/engines/ags/shared/ac/common_defines.h b/engines/ags/shared/ac/common_defines.h index 9cf5bfa55d04..c7b658005eb5 100644 --- a/engines/ags/shared/ac/common_defines.h +++ b/engines/ags/shared/ac/common_defines.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_DEFINES_H -#define __AC_DEFINES_H +#ifndef AGS_SHARED_AC_DEFINES_H +#define AGS_SHARED_AC_DEFINES_H #include "core/platform.h" @@ -128,4 +128,4 @@ #define OBJF_LEGACY_LOCKED 0x40 // object position is locked in the editor (OBSOLETE since 3.5.0) #define OBJF_HASLIGHT 0x80 // the tint_light is valid and treated as brightness -#endif // __AC_DEFINES_H +#endif diff --git a/engines/ags/shared/ac/dialogtopic.h b/engines/ags/shared/ac/dialogtopic.h index e26b7284b9fc..431123b062e7 100644 --- a/engines/ags/shared/ac/dialogtopic.h +++ b/engines/ags/shared/ac/dialogtopic.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_AC__DIALOGTOPIC_H -#define __AGS_CN_AC__DIALOGTOPIC_H +#ifndef AGS_SHARED_AC_DIALOGTOPIC_H +#define AGS_SHARED_AC_DIALOGTOPIC_H namespace AGS { namespace Common { class Stream; } } using namespace AGS; // FIXME later @@ -70,4 +70,4 @@ struct DialogTopic { }; -#endif // __AGS_CN_AC__DIALOGTOPIC_H +#endif diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index a9165dadbb15..adad724dcdfd 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H -#define __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H +#ifndef AGS_SHARED_AC_DYNOBJ_SCRIPTAUDIOCLIP_H +#define AGS_SHARED_AC_DYNOBJ_SCRIPTAUDIOCLIP_H #include "util/string.h" @@ -56,4 +56,4 @@ struct ScriptAudioClip { void ReadFromFile(Common::Stream *in); }; -#endif // __AGS_CN_DYNOBJ__SCRIPTAUDIOCLIP_H +#endif diff --git a/engines/ags/shared/ac/game_version.h b/engines/ags/shared/ac/game_version.h index 745f181e8cf0..7706953f8583 100644 --- a/engines/ags/shared/ac/game_version.h +++ b/engines/ags/shared/ac/game_version.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_AC__GAMEVERSION_H -#define __AGS_CN_AC__GAMEVERSION_H +#ifndef AGS_SHARED_AC_GAMEVERSION_H +#define AGS_SHARED_AC_GAMEVERSION_H /* @@ -153,4 +153,4 @@ enum GameDataVersion extern GameDataVersion loaded_game_file_version; -#endif // __AGS_CN_AC__GAMEVERSION_H +#endif diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index b7f97cf632b8..dce49ef7d8da 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_AC__GAMESETUPSTRUCT_H -#define __AGS_CN_AC__GAMESETUPSTRUCT_H +#ifndef AGS_SHARED_AC_GAMESETUPSTRUCT_H +#define AGS_SHARED_AC_GAMESETUPSTRUCT_H #include #include "ac/audiocliptype.h" @@ -167,4 +167,4 @@ void ConvertOldGameStruct (OldGameSetupStruct *ogss, GameSetupStruct *gss); // Finds an audio clip using legacy convention index ScriptAudioClip* GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num); -#endif // __AGS_CN_AC__GAMESETUPSTRUCT_H +#endif diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h index bb3fdaffa87f..1dd2c6fc2a0b 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.h +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_AC__GAMESETUPSTRUCTBASE_H -#define __AGS_CN_AC__GAMESETUPSTRUCTBASE_H +#ifndef AGS_SHARED_AC_GAMESETUPSTRUCTBASE_H +#define AGS_SHARED_AC_GAMESETUPSTRUCTBASE_H #include "ac/game_version.h" #include "ac/gamestructdefines.h" @@ -224,4 +224,4 @@ struct GameSetupStructBase { int _screenUpscaleMult; }; -#endif // __AGS_CN_AC__GAMESETUPSTRUCTBASE_H +#endif diff --git a/engines/ags/shared/ac/gamestructdefines.h b/engines/ags/shared/ac/gamestructdefines.h index 4458a7de4970..d079c08d0b8b 100644 --- a/engines/ags/shared/ac/gamestructdefines.h +++ b/engines/ags/shared/ac/gamestructdefines.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_AC__GAMESTRUCTDEFINES_H -#define __AGS_CN_AC__GAMESTRUCTDEFINES_H +#ifndef AGS_SHARED_AC_GAMESTRUCTDEFINES_H +#define AGS_SHARED_AC_GAMESTRUCTDEFINES_H #include "util/geometry.h" #include "core/types.h" @@ -258,4 +258,4 @@ struct FontInfo FontInfo(); }; -#endif // __AGS_CN_AC__GAMESTRUCTDEFINES_H +#endif diff --git a/engines/ags/shared/ac/interfacebutton.h b/engines/ags/shared/ac/interfacebutton.h index 1f0caa63c2fa..b5990dda812a 100644 --- a/engines/ags/shared/ac/interfacebutton.h +++ b/engines/ags/shared/ac/interfacebutton.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_INTERFACEBUTTON_H -#define __AC_INTERFACEBUTTON_H +#ifndef AGS_SHARED_AC_INTERFACEBUTTON_H +#define AGS_SHARED_AC_INTERFACEBUTTON_H #define MAXBUTTON 20 #define IBFLG_ENABLED 1 @@ -34,4 +34,4 @@ struct InterfaceButton { void set(int xx, int yy, int picc, int overpicc, int actionn); }; -#endif // __AC_INTERFACEBUTTON_H +#endif diff --git a/engines/ags/shared/ac/interfaceelement.h b/engines/ags/shared/ac/interfaceelement.h index 0a899d0bcc36..4ecd3d5116bd 100644 --- a/engines/ags/shared/ac/interfaceelement.h +++ b/engines/ags/shared/ac/interfaceelement.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_INTERFACEELEMENT_H -#define __AC_INTERFACEELEMENT_H +#ifndef AGS_SHARED_AC_INTERFACEELEMENT_H +#define AGS_SHARED_AC_INTERFACEELEMENT_H #include "ac/interfacebutton.h" // InterfaceButton @@ -56,4 +56,4 @@ button[0].set(0,13,3,-1,0); } };*/ -#endif // __AC_INTERFACEELEMENT_H +#endif diff --git a/engines/ags/shared/ac/inventoryiteminfo.h b/engines/ags/shared/ac/inventoryiteminfo.h index 79d7e8360d19..1506622a5215 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.h +++ b/engines/ags/shared/ac/inventoryiteminfo.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_INVENTORYITEMINFO_H -#define __AC_INVENTORYITEMINFO_H +#ifndef AGS_SHARED_AC_INVENTORYITEMINFO_H +#define AGS_SHARED_AC_INVENTORYITEMINFO_H namespace AGS { namespace Common { class Stream; } } using namespace AGS; // FIXME later @@ -40,4 +40,4 @@ struct InventoryItemInfo { void WriteToSavegame(Common::Stream *out) const; }; -#endif // __AC_INVENTORYITEMINFO_H +#endif diff --git a/engines/ags/shared/ac/mousecursor.h b/engines/ags/shared/ac/mousecursor.h index fc7294fe7f0b..732b6b49fca0 100644 --- a/engines/ags/shared/ac/mousecursor.h +++ b/engines/ags/shared/ac/mousecursor.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_MOUSECURSOR_H -#define __AC_MOUSECURSOR_H +#ifndef AGS_SHARED_AC_MOUSECURSOR_H +#define AGS_SHARED_AC_MOUSECURSOR_H namespace AGS { namespace Common { class Stream; } } using namespace AGS; // FIXME later @@ -45,4 +45,4 @@ struct MouseCursor { void WriteToSavegame(Common::Stream *out) const; }; -#endif // __AC_MOUSECURSOR_H +#endif diff --git a/engines/ags/shared/ac/oldgamesetupstruct.h b/engines/ags/shared/ac/oldgamesetupstruct.h index fa24eb727f95..b0cd0f23d95f 100644 --- a/engines/ags/shared/ac/oldgamesetupstruct.h +++ b/engines/ags/shared/ac/oldgamesetupstruct.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_AC__OLDGAMESETUPSTRUCT_H -#define __AGS_CN_AC__OLDGAMESETUPSTRUCT_H +#ifndef AGS_SHARED_AC_OLDGAMESETUPSTRUCT_H +#define AGS_SHARED_AC_OLDGAMESETUPSTRUCT_H #include "ac/characterinfo.h" // OldCharacterInfo, CharacterInfo #ifdef UNUSED_CODE @@ -80,4 +80,4 @@ struct OldGameSetupStruct : public OriGameSetupStruct2 { unsigned char spriteflags[LEGACY_MAX_SPRITES_V25]; }; -#endif // __AGS_CN_AC__OLDGAMESETUPSTRUCT_H +#endif diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index 8d547ae80fe7..c1bdfe1803e6 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -42,8 +42,8 @@ // //============================================================================= -#ifndef __SPRCACHE_H -#define __SPRCACHE_H +#ifndef AGS_SHARED_AC_SPRITECACHE_H +#define AGS_SHARED_AC_SPRITECACHE_H #include #include @@ -247,4 +247,4 @@ class SpriteCache extern SpriteCache spriteset; -#endif // __SPRCACHE_H +#endif diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index 65fb8bf89a93..6a257e14f4ed 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_VIEW_H -#define __AC_VIEW_H +#ifndef AGS_SHARED_AC_VIEW_H +#define AGS_SHARED_AC_VIEW_H #include @@ -85,4 +85,4 @@ struct ViewStruct272 { void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *newv); -#endif // __AC_VIEW_H +#endif diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h index 667b987145a4..dd499f7b69d8 100644 --- a/engines/ags/shared/ac/wordsdictionary.h +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_WORDSDICTIONARY_H -#define __AC_WORDSDICTIONARY_H +#ifndef AGS_SHARED_AC_WORDSDICTIONARY_H +#define AGS_SHARED_AC_WORDSDICTIONARY_H #include "core/types.h" @@ -60,4 +60,4 @@ extern void encrypt_text(char *toenc); extern void write_string_encrypt(Common::Stream *out, const char *s); extern void write_dictionary (WordsDictionary *dict, Common::Stream *out); -#endif // __AC_WORDSDICTIONARY_H +#endif diff --git a/engines/ags/shared/api/stream_api.h b/engines/ags/shared/api/stream_api.h index 09db657444bb..283a44012829 100644 --- a/engines/ags/shared/api/stream_api.h +++ b/engines/ags/shared/api/stream_api.h @@ -30,8 +30,8 @@ // //============================================================================= -#ifndef __AGS_CN_API__IAGSSTREAM_H -#define __AGS_CN_API__IAGSSTREAM_H +#ifndef AGS_SHARED_API_IAGSSTREAM_H +#define AGS_SHARED_API_IAGSSTREAM_H // TODO: it would probably be better to not include core definition headers // in API class headers, but make separate core headers specifically for @@ -98,4 +98,4 @@ class IAGSStream } // namespace Common } // namespace AGS -#endif // __AGS_CN_API__IAGSSTREAM_H +#endif diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index 07505adeec77..14f906f5be8b 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_CORE__ASSET_H -#define __AGS_CN_CORE__ASSET_H +#ifndef AGS_SHARED_CORE_ASSET_H +#define AGS_SHARED_CORE_ASSET_H #include #include "util/string.h" @@ -67,4 +67,4 @@ struct AssetLibInfo } // namespace Common } // namespace AGS -#endif // __AGS_CN_CORE__ASSET_H +#endif diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h index b1e4f5e0b00e..f12fccba13fb 100644 --- a/engines/ags/shared/core/assetmanager.h +++ b/engines/ags/shared/core/assetmanager.h @@ -41,8 +41,8 @@ // //============================================================================= -#ifndef __AGS_CN_CORE__ASSETMANAGER_H -#define __AGS_CN_CORE__ASSETMANAGER_H +#ifndef AGS_SHARED_CORE_ASSETMANAGER_H +#define AGS_SHARED_CORE_ASSETMANAGER_H #include "util/file.h" // TODO: extract filestream mode constants or introduce generic ones @@ -162,4 +162,4 @@ String GetAssetErrorText(AssetError err); } // namespace Common } // namespace AGS -#endif // __AGS_CN_CORE__ASSETMANAGER_H +#endif diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h index 45a3dc9bdf10..81495f30b933 100644 --- a/engines/ags/shared/core/def_version.h +++ b/engines/ags/shared/core/def_version.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_CORE__DEFVERSION_H -#define __AGS_CN_CORE__DEFVERSION_H +#ifndef AGS_SHARED_CORE_DEFVERSION_H +#define AGS_SHARED_CORE_DEFVERSION_H #define ACI_VERSION_STR "3.5.1.0" #if defined (RC_INVOKED) // for MSVC resource compiler @@ -36,4 +36,4 @@ #define ACI_COPYRIGHT_YEARS "2011-2020" -#endif // __AGS_CN_CORE__DEFVERSION_H +#endif diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h index f1494d09399c..85f640973e35 100644 --- a/engines/ags/shared/core/platform.h +++ b/engines/ags/shared/core/platform.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_PLATFORM_H -#define __AC_PLATFORM_H +#ifndef AGS_SHARED_CORE_PLATFORM_H +#define AGS_SHARED_CORE_PLATFORM_H // platform definitions. Not intended for replacing types or checking for libraries. @@ -124,4 +124,4 @@ #define AGS_PLATFORM_DEBUG (0) #endif -#endif // __AC_PLATFORM_H +#endif diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index 03da2bbb7498..d476de63e6e5 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_CORE__TYPES_H -#define __AGS_CN_CORE__TYPES_H +#ifndef AGS_SHARED_CORE_TYPES_H +#define AGS_SHARED_CORE_TYPES_H #include #include @@ -69,4 +69,4 @@ enum kUnit = 1 << kShift }; -#endif // __AGS_CN_CORE__TYPES_H +#endif diff --git a/engines/ags/shared/debugging/assert.h b/engines/ags/shared/debugging/assert.h index fd02a7f0bc73..cb355fa6df78 100644 --- a/engines/ags/shared/debugging/assert.h +++ b/engines/ags/shared/debugging/assert.h @@ -26,9 +26,9 @@ // //============================================================================= -#ifndef __AGS_CN_DEBUG__ASSERT_H -#define __AGS_CN_DEBUG__ASSERT_H +#ifndef AGS_SHARED_DEBUGGING_ASSERT_H +#define AGS_SHARED_DEBUGGING_ASSERT_H #include -#endif // __AGS_CN_DEBUG__ASSERT_H +#endif diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index fa100f746a63..d001012d5a5a 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -44,8 +44,8 @@ // //============================================================================= -#ifndef __AGS_CN_DEBUG__DEBUGMANAGER_H -#define __AGS_CN_DEBUG__DEBUGMANAGER_H +#ifndef AGS_SHARED_DEBUGGING_DEBUGMANAGER_H +#define AGS_SHARED_DEBUGGING_DEBUGMANAGER_H #include #include @@ -170,4 +170,4 @@ extern DebugManager DbgMgr; } // namespace Common } // namespace AGS -#endif // __AGS_CN_DEBUG__DEBUGMANAGER_H +#endif diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h index d77d4ba68d0d..7e18324357bd 100644 --- a/engines/ags/shared/debugging/out.h +++ b/engines/ags/shared/debugging/out.h @@ -74,8 +74,8 @@ // //============================================================================= -#ifndef __AGS_CN_DEBUG__OUT_H -#define __AGS_CN_DEBUG__OUT_H +#ifndef AGS_SHARED_DEBUGGING_OUT_H +#define AGS_SHARED_DEBUGGING_OUT_H #include "util/string.h" @@ -162,4 +162,4 @@ namespace Debug } // namespace Common } // namespace AGS -#endif // __AGS_CN_DEBUG__OUT_H +#endif diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h index 35eadc595d70..397e4cbfd787 100644 --- a/engines/ags/shared/debugging/outputhandler.h +++ b/engines/ags/shared/debugging/outputhandler.h @@ -27,8 +27,8 @@ // //============================================================================= -#ifndef __AGS_CN_DEBUG__OUTPUTHANDLER_H -#define __AGS_CN_DEBUG__OUTPUTHANDLER_H +#ifndef AGS_SHARED_DEBUGGING_OUTPUTHANDLER_H +#define AGS_SHARED_DEBUGGING_OUTPUTHANDLER_H #include "debug/out.h" #include "util/string.h" @@ -67,4 +67,4 @@ class IOutputHandler } // namespace Common } // namespace AGS -#endif // __AGS_CN_DEBUG__OUTPUTHANDLER_H +#endif diff --git a/engines/ags/shared/font/agsfontrenderer.h b/engines/ags/shared/font/agsfontrenderer.h index f738a11effa7..4d25170eec76 100644 --- a/engines/ags/shared/font/agsfontrenderer.h +++ b/engines/ags/shared/font/agsfontrenderer.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_AGSFONTRENDERER_H -#define __AC_AGSFONTRENDERER_H +#ifndef AGS_SHARED_FONT_AGSFONTRENDERER_H +#define AGS_SHARED_FONT_AGSFONTRENDERER_H struct BITMAP; @@ -64,4 +64,4 @@ class IAGSFontRenderer2 ~IAGSFontRenderer2() = default; }; -#endif // __AC_AGSFONTRENDERER_H +#endif diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index 8502109b87c1..7c71b232f83b 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_FONT_H -#define __AC_FONT_H +#ifndef AGS_SHARED_FONT_FONTS_H +#define AGS_SHARED_FONT_FONTS_H #include #include "core/types.h" @@ -117,4 +117,4 @@ size_t split_lines(const char *texx, SplitLines &lines, int width, int fontNumbe namespace AGS { namespace Common { extern SplitLines Lines; } } -#endif // __AC_FONT_H +#endif diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 4a7cf6722bed..1fbb0883458b 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_TTFFONTRENDERER_H -#define __AC_TTFFONTRENDERER_H +#ifndef AGS_SHARED_FONT_TTFFONTRENDERER_H +#define AGS_SHARED_FONT_TTFFONTRENDERER_H #include #include "font/agsfontrenderer.h" @@ -53,4 +53,4 @@ class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { std::map _fontData; }; -#endif // __AC_TTFFONTRENDERER_H +#endif diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index dd83c60b4736..1f85d65d9f27 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -43,8 +43,8 @@ // //============================================================================= -#ifndef __AGS_CN_FONT__WFNFONT_H -#define __AGS_CN_FONT__WFNFONT_H +#ifndef AGS_SHARED_FONT_WFNFONT_H +#define AGS_SHARED_FONT_WFNFONT_H #include #include "core/types.h" @@ -109,4 +109,4 @@ class WFNFont static const WFNChar _emptyChar; // a dummy character to substitute bad symbols }; -#endif // __AGS_CN_FONT__WFNFONT_H +#endif diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index a7cb943d1ee1..4a164bac9274 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_WFNFONTRENDERER_H -#define __AC_WFNFONTRENDERER_H +#ifndef AGS_SHARED_FONT_WFNFONTRENDERER_H +#define AGS_SHARED_FONT_WFNFONTRENDERER_H #include #include "font/agsfontrenderer.h" @@ -51,4 +51,4 @@ class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { std::map _fontData; }; -#endif // __AC_WFNFONTRENDERER_H +#endif diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index e875cd9416e9..325cc21ac919 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -33,8 +33,8 @@ // //============================================================================= -#ifndef __AGS_CN_GAME__CUSTOMPROPERTIES_H -#define __AGS_CN_GAME__CUSTOMPROPERTIES_H +#ifndef AGS_SHARED_GAME_CUSTOMPROPERTIES_H +#define AGS_SHARED_GAME_CUSTOMPROPERTIES_H #include #include "util/string.h" @@ -110,4 +110,4 @@ namespace Properties } // namespace Common } // namespace AGS -#endif // __AGS_CN_GAME__CUSTOMPROPERTIES_H +#endif diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index aae290ec8ebe..a82b6b7ff37b 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -46,8 +46,8 @@ // //============================================================================= -#ifndef __AGS_CN_GAME__INTEREACTIONS_H -#define __AGS_CN_GAME__INTEREACTIONS_H +#ifndef AGS_SHARED_GAME_INTEREACTIONS_H +#define AGS_SHARED_GAME_INTEREACTIONS_H #include #include "util/string_types.h" @@ -220,4 +220,4 @@ typedef std::shared_ptr PInteractionScripts; extern AGS::Common::InteractionVariable globalvars[MAX_GLOBAL_VARIABLES]; extern int numGlobalVars; -#endif // __AGS_CN_GAME__INTEREACTIONS_H +#endif diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 48d08ba1ec07..2ed4f483d4c5 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -28,8 +28,8 @@ // //============================================================================= -#ifndef __AGS_CN_GAME__MAINGAMEFILE_H -#define __AGS_CN_GAME__MAINGAMEFILE_H +#ifndef AGS_SHARED_GAME_MAINGAMEFILE_H +#define AGS_SHARED_GAME_MAINGAMEFILE_H #include #include @@ -154,4 +154,4 @@ void FixupSaveDirectory(GameSetupStruct &game); } // namespace Common } // namespace AGS -#endif // __AGS_CN_GAME__MAINGAMEFILE_H +#endif diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index 4d1a461d8a86..ec068cc8bfd3 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_GAME__PLUGININFO_H -#define __AGS_CN_GAME__PLUGININFO_H +#ifndef AGS_SHARED_GAME_PLUGININFO_H +#define AGS_SHARED_GAME_PLUGININFO_H #include #include "util/string.h" @@ -54,4 +54,4 @@ struct PluginInfo } // namespace Common } // namespace AGS -#endif // __AGS_CN_GAME__PLUGININFO_H +#endif diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index bf7244fac824..727a97c47625 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -28,8 +28,8 @@ // //============================================================================= -#ifndef __AGS_CN_GAME_ROOMFILE_H -#define __AGS_CN_GAME_ROOMFILE_H +#ifndef AGS_SHARED_GAME_ROOMFILE_H +#define AGS_SHARED_GAME_ROOMFILE_H #include #include @@ -99,4 +99,4 @@ HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersio } // namespace Common } // namespace AGS -#endif // __AGS_CN_GAME_ROOMFILE_H +#endif diff --git a/engines/ags/shared/game/room_version.h b/engines/ags/shared/game/room_version.h index 47507757f12e..f5a14998e228 100644 --- a/engines/ags/shared/game/room_version.h +++ b/engines/ags/shared/game/room_version.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_AC__ROOMVERSION_H -#define __AGS_CN_AC__ROOMVERSION_H +#ifndef AGS_SHARED_GAME_ROOMVERSION_H +#define AGS_SHARED_GAME_ROOMVERSION_H /* room file versions history 8: final v1.14 release @@ -93,4 +93,4 @@ enum RoomFileVersion kRoomVersion_Current = kRoomVersion_3508 }; -#endif // __AGS_CN_AC__ROOMVERSION_H +#endif diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index a6895058eb1d..722c60ce5c02 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -45,8 +45,8 @@ // //============================================================================= -#ifndef __AGS_CN_GAME__ROOMINFO_H -#define __AGS_CN_GAME__ROOMINFO_H +#ifndef AGS_SHARED_GAME_ROOMINFO_H +#define AGS_SHARED_GAME_ROOMINFO_H #include #include "ac/common_defines.h" @@ -394,4 +394,4 @@ PBitmap FixBitmap(PBitmap bmp, int dst_width, int dst_height); } // namespace Common } // namespace AGS -#endif // __AGS_CN_GAME__ROOMINFO_H +#endif diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index c7f437daa668..94c22a4b887c 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -29,8 +29,8 @@ // //============================================================================= -#ifndef __AGS_CN_GFX__ALLEGROBITMAP_H -#define __AGS_CN_GFX__ALLEGROBITMAP_H +#ifndef AGS_SHARED_GFX_ALLEGROBITMAP_H +#define AGS_SHARED_GFX_ALLEGROBITMAP_H #include #include "core/types.h" @@ -257,4 +257,4 @@ namespace BitmapHelper } // namespace Common } // namespace AGS -#endif // __AGS_CN_GFX__ALLEGROBITMAP_H +#endif diff --git a/engines/ags/shared/gfx/bitmap.h b/engines/ags/shared/gfx/bitmap.h index 6e58b95b729b..7d0a7e99a2eb 100644 --- a/engines/ags/shared/gfx/bitmap.h +++ b/engines/ags/shared/gfx/bitmap.h @@ -25,8 +25,9 @@ // Base bitmap header // //============================================================================= -#ifndef __AGS_CN_GFX__BITMAP_H -#define __AGS_CN_GFX__BITMAP_H + +#ifndef AGS_SHARED_GFX_BITMAP_H +#define AGS_SHARED_GFX_BITMAP_H #include "util/geometry.h" @@ -94,4 +95,4 @@ namespace BitmapHelper } // namespace Common } // namespace AGS -#endif // __AGS_CN_GFX__BITMAP_H +#endif diff --git a/engines/ags/shared/gfx/gfx_def.h b/engines/ags/shared/gfx/gfx_def.h index 99254cc8b354..af0582ae1d55 100644 --- a/engines/ags/shared/gfx/gfx_def.h +++ b/engines/ags/shared/gfx/gfx_def.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_GFX__GFXDEF_H -#define __AGS_CN_GFX__GFXDEF_H +#ifndef AGS_SHARED_GFX_GFXDEF_H +#define AGS_SHARED_GFX_GFXDEF_H namespace AGS { @@ -125,4 +125,4 @@ namespace GfxDef } // namespace Common } // namespace AGS -#endif // __AGS_CN_GFX__GFXDEF_H +#endif diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index b32efe8ac865..8637c05aab4b 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUIBUTTON_H -#define __AC_GUIBUTTON_H +#ifndef AGS_SHARED_GUI_GUIBUTTON_H +#define AGS_SHARED_GUI_GUIBUTTON_H #include #include "gui/guiobject.h" @@ -141,4 +141,4 @@ extern int numguibuts; int UpdateAnimatingButton(int bu); void StopButtonAnimation(int idxn); -#endif // __AC_GUIBUTTON_H +#endif diff --git a/engines/ags/shared/gui/guidefines.h b/engines/ags/shared/gui/guidefines.h index 3d43b88b708f..d9c27e42bb79 100644 --- a/engines/ags/shared/gui/guidefines.h +++ b/engines/ags/shared/gui/guidefines.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUIDEFINES_H -#define __AC_GUIDEFINES_H +#ifndef AGS_SHARED_GUI_GUIDEFINES_H +#define AGS_SHARED_GUI_GUIDEFINES_H #define GUIMAGIC 0xcafebeef #define MAX_GUIOBJ_EVENTS 10 @@ -190,4 +190,4 @@ enum GuiSvgVersion extern int guis_need_update; -#endif // __AC_GUIDEFINES_H +#endif diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index ee3959300e8b..0acab662d132 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUIINV_H -#define __AC_GUIINV_H +#ifndef AGS_SHARED_GUI_GUIINV_H +#define AGS_SHARED_GUI_GUIINV_H #include #include "gui/guiobject.h" @@ -75,4 +75,4 @@ class GUIInvWindow : public GUIObject extern std::vector guiinv; extern int numguiinv; -#endif // __AC_GUIINV_H +#endif diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index f9f5a70f0289..86ea4b9e3791 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUILABEL_H -#define __AC_GUILABEL_H +#ifndef AGS_SHARED_GUI_GUILABEL_H +#define AGS_SHARED_GUI_GUILABEL_H #include #include "gui/guiobject.h" @@ -72,4 +72,4 @@ class GUILabel:public GUIObject extern std::vector guilabels; extern int numguilabels; -#endif // __AC_GUILABEL_H +#endif diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index ce68c495a2c0..fcee121ce694 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUILISTBOX_H -#define __AC_GUILISTBOX_H +#ifndef AGS_SHARED_GUI_GUILISTBOX_H +#define AGS_SHARED_GUI_GUILISTBOX_H #include #include "gui/guiobject.h" @@ -103,4 +103,4 @@ class GUIListBox : public GUIObject extern std::vector guilist; extern int numguilist; -#endif // __AC_GUILISTBOX_H +#endif diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index 8166edc8760b..5ec98205dad0 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUIMAIN_H -#define __AC_GUIMAIN_H +#ifndef AGS_SHARED_GUI_GUIMAIN_H +#define AGS_SHARED_GUI_GUIMAIN_H #include #include "ac/common_defines.h" // TODO: split out gui drawing helpers @@ -246,4 +246,4 @@ extern int get_eip_guiobj(); extern bool outlineGuiObjects; -#endif // __AC_GUIMAIN_H +#endif diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h index 0d85a68f8212..2768dd9a6662 100644 --- a/engines/ags/shared/gui/guiobject.h +++ b/engines/ags/shared/gui/guiobject.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUIOBJECT_H -#define __AC_GUIOBJECT_H +#ifndef AGS_SHARED_GUI_GUIOBJECT_H +#define AGS_SHARED_GUI_GUIOBJECT_H #include "core/types.h" #include "gfx/bitmap.h" @@ -131,4 +131,4 @@ extern int all_buttons_disabled; // Tells if the given control is considered enabled, taking global flag into account inline bool IsGUIEnabled(AGS::Common::GUIObject *g) { return !all_buttons_disabled && g->IsEnabled(); } -#endif // __AC_GUIOBJECT_H +#endif diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index 93b124130271..c5dd69c6b0c4 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUISLIDER_H -#define __AC_GUISLIDER_H +#ifndef AGS_SHARED_GUI_GUISLIDER_H +#define AGS_SHARED_GUI_GUISLIDER_H #include #include "gui/guiobject.h" @@ -76,4 +76,4 @@ class GUISlider : public GUIObject extern std::vector guislider; extern int numguislider; -#endif // __AC_GUISLIDER_H +#endif diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index 8c37567dd3f8..0617e8c35853 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_GUITEXTBOX_H -#define __AC_GUITEXTBOX_H +#ifndef AGS_SHARED_GUI_GUITEXTBOX_H +#define AGS_SHARED_GUI_GUITEXTBOX_H #include #include "gui/guiobject.h" @@ -70,4 +70,4 @@ class GUITextBox : public GUIObject extern std::vector guitext; extern int numguitext; -#endif // __AC_GUITEXTBOX_H +#endif diff --git a/engines/ags/shared/script/cc_error.h b/engines/ags/shared/script/cc_error.h index 7f9c49ae4b0a..c3d9591b1eb5 100644 --- a/engines/ags/shared/script/cc_error.h +++ b/engines/ags/shared/script/cc_error.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __CC_ERROR_H -#define __CC_ERROR_H +#ifndef AGS_SHARED_SCRIPT_ERROR_H +#define AGS_SHARED_SCRIPT_ERROR_H #include "util/string.h" @@ -41,4 +41,4 @@ extern AGS::Common::String ccErrorCallStack; // callstack where error happened extern bool ccErrorIsUserError; extern const char *ccCurScriptName; // name of currently compiling script -#endif // __CC_ERROR_H +#endif diff --git a/engines/ags/shared/script/cc_options.h b/engines/ags/shared/script/cc_options.h index beeef080701e..e2ccbb6b7ca2 100644 --- a/engines/ags/shared/script/cc_options.h +++ b/engines/ags/shared/script/cc_options.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __CC_OPTIONS_H -#define __CC_OPTIONS_H +#ifndef AGS_SHARED_SCRIPT_CC_OPTIONS_H +#define AGS_SHARED_SCRIPT_CC_OPTIONS_H #define SCOPT_EXPORTALL 1 // export all functions automatically #define SCOPT_SHOWWARNINGS 2 // printf warnings to console diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index c8a69186d59b..07f8d86de0cd 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __CC_SCRIPT_H -#define __CC_SCRIPT_H +#ifndef AGS_SHARED_SCRIPT_CC_SCRIPT_H +#define AGS_SHARED_SCRIPT_CC_SCRIPT_H #include #include "core/types.h" @@ -82,4 +82,4 @@ struct ccScript typedef std::shared_ptr PScript; -#endif // __CC_SCRIPT_H +#endif diff --git a/engines/ags/shared/script/script_common.h b/engines/ags/shared/script/script_common.h index cd6a0ce2ed36..42fbf6991e92 100644 --- a/engines/ags/shared/script/script_common.h +++ b/engines/ags/shared/script/script_common.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __CS_COMMON_H -#define __CS_COMMON_H +#ifndef AGS_SHARED_SCRIPT_SCRIPT_COMMON_H +#define AGS_SHARED_SCRIPT_SCRIPT_COMMON_H #define SCOM_VERSION 90 #define SCOM_VERSIONSTR "0.90" @@ -138,4 +138,4 @@ extern int currentline; extern const char scfilesig[5]; #define ENDFILESIG 0xbeefcafe -#endif // __CS_COMMON_H +#endif diff --git a/engines/ags/shared/util/alignedstream.h b/engines/ags/shared/util/alignedstream.h index 6b1a4576c880..fd158b4937a2 100644 --- a/engines/ags/shared/util/alignedstream.h +++ b/engines/ags/shared/util/alignedstream.h @@ -42,8 +42,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__ALIGNEDSTREAM_H -#define __AGS_CN_UTIL__ALIGNEDSTREAM_H +#ifndef AGS_SHARED_UTIL_ALIGNEDSTREAM_H +#define AGS_SHARED_UTIL_ALIGNEDSTREAM_H #include "util/proxystream.h" @@ -114,4 +114,4 @@ class AlignedStream : public ProxyStream } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__ALIGNEDSTREAM_H +#endif diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h index 6081aef91704..4b80fe66a7a0 100644 --- a/engines/ags/shared/util/bbop.h +++ b/engines/ags/shared/util/bbop.h @@ -25,8 +25,9 @@ // Various utility bit and byte operations // //============================================================================= -#ifndef __AGS_CN_UTIL__BBOP_H -#define __AGS_CN_UTIL__BBOP_H + +#ifndef AGS_SHARED_UTIL_BBOP_H +#define AGS_SHARED_UTIL_BBOP_H #include "core/platform.h" #include "core/types.h" @@ -165,4 +166,4 @@ namespace BBOp = BitByteOperations; } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__BBOP_H +#endif diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h index 3652c3fe0de1..efb2cdc78505 100644 --- a/engines/ags/shared/util/bufferedstream.h +++ b/engines/ags/shared/util/bufferedstream.h @@ -20,13 +20,8 @@ * */ -//============================================================================= -// -// -// -//============================================================================= -#ifndef __AGS_CN_UTIL__BUFFEREDSTREAM_H -#define __AGS_CN_UTIL__BUFFEREDSTREAM_H +#ifndef AGS_SHARED_UTIL_BUFFEREDSTREAM_H +#define AGS_SHARED_UTIL_BUFFEREDSTREAM_H #include #include "util/filestream.h" @@ -76,4 +71,4 @@ class BufferedStream : public FileStream } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__BUFFEREDSTREAM_H +#endif diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h index eb8e6c7d9346..199020deab8a 100644 --- a/engines/ags/shared/util/compress.h +++ b/engines/ags/shared/util/compress.h @@ -20,8 +20,8 @@ * */ -#ifndef __AC_COMPRESS_H -#define __AC_COMPRESS_H +#ifndef AGS_SHARED_UTIL_COMPRESS_H +#define AGS_SHARED_UTIL_COMPRESS_H #include "util/wgt2allg.h" // color (allegro RGB) @@ -45,4 +45,4 @@ void load_lzw(Common::Stream *in, Common::Bitmap **bmm, int dst_bpp, color *pall void savecompressed_allegro(Common::Stream *out, const Common::Bitmap *bmpp, const color *pall); void loadcompressed_allegro(Common::Stream *in, Common::Bitmap **bimpp, color *pall); -#endif // __AC_COMPRESS_H +#endif diff --git a/engines/ags/shared/util/datastream.h b/engines/ags/shared/util/datastream.h index c3b530bba029..6bbc92ff3f6c 100644 --- a/engines/ags/shared/util/datastream.h +++ b/engines/ags/shared/util/datastream.h @@ -28,8 +28,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__DATASTREAM_H -#define __AGS_CN_UTIL__DATASTREAM_H +#ifndef AGS_SHARED_UTIL_DATASTREAM_H +#define AGS_SHARED_UTIL_DATASTREAM_H #include "util/bbop.h" #include "util/stream.h" @@ -140,4 +140,4 @@ class DataStream : public Stream } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__DATASTREAM_H +#endif diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h index 881c8aa59dbb..85164e9bf106 100644 --- a/engines/ags/shared/util/directory.h +++ b/engines/ags/shared/util/directory.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__DIRECTORY_H -#define __AGS_CN_UTIL__DIRECTORY_H +#ifndef AGS_SHARED_UTIL_DIRECTORY_H +#define AGS_SHARED_UTIL_DIRECTORY_H #include "core/platform.h" #include "util/string.h" @@ -53,4 +53,4 @@ namespace Directory } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__DIRECTORY_H +#endif diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h index 599ab1aeb205..7024c37005d2 100644 --- a/engines/ags/shared/util/error.h +++ b/engines/ags/shared/util/error.h @@ -27,8 +27,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__ERROR_H -#define __AGS_CN_UTIL__ERROR_H +#ifndef AGS_SHARED_UTIL_ERROR_H +#define AGS_SHARED_UTIL_ERROR_H #include #include "util/string.h" @@ -142,4 +142,4 @@ class TypedCodeError : public Error } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__ERROR_H +#endif diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h index 8a513eeafd06..5b1d830ab345 100644 --- a/engines/ags/shared/util/file.h +++ b/engines/ags/shared/util/file.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__FILE_H -#define __AGS_CN_UTIL__FILE_H +#ifndef AGS_SHARED_UTIL_FILE_H +#define AGS_SHARED_UTIL_FILE_H #include "core/platform.h" #include "util/string.h" @@ -94,4 +94,4 @@ namespace File } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__FILE_H +#endif diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index 55dba895db01..4397b0dd28e6 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_UTIL__FILESTREAM_H -#define __AGS_CN_UTIL__FILESTREAM_H +#ifndef AGS_SHARED_UTIL_FILESTREAM_H +#define AGS_SHARED_UTIL_FILESTREAM_H #include @@ -79,4 +79,4 @@ class FileStream : public DataStream } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__FILESTREAM_H +#endif diff --git a/engines/ags/shared/util/geometry.h b/engines/ags/shared/util/geometry.h index acfc8536cd9b..c0ebbaa9b526 100644 --- a/engines/ags/shared/util/geometry.h +++ b/engines/ags/shared/util/geometry.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__GEOMETRY_H -#define __AGS_CN_UTIL__GEOMETRY_H +#ifndef AGS_SHARED_UTIL_GEOMETRY_H +#define AGS_SHARED_UTIL_GEOMETRY_H #include "util/math.h" @@ -413,4 +413,4 @@ Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &place //} // namespace Common //} // namespace AGS -#endif // __AGS_CN_UTIL__GEOMETRY_H +#endif diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h index 7ca76ca51425..9f3d7b3aa502 100644 --- a/engines/ags/shared/util/ini_util.h +++ b/engines/ags/shared/util/ini_util.h @@ -27,8 +27,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__INIUTIL_H -#define __AGS_CN_UTIL__INIUTIL_H +#ifndef AGS_SHARED_UTIL_INIUTIL_H +#define AGS_SHARED_UTIL_INIUTIL_H #include #include "util/string.h" @@ -74,4 +74,4 @@ namespace IniUtil } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__INIUTIL_H +#endif diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h index b77bf5ed05f9..b69b89582ae8 100644 --- a/engines/ags/shared/util/inifile.h +++ b/engines/ags/shared/util/inifile.h @@ -30,8 +30,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__INIFILE_H -#define __AGS_CN_UTIL__INIFILE_H +#ifndef AGS_SHARED_UTIL_INIFILE_H +#define AGS_SHARED_UTIL_INIFILE_H #include #include "util/string.h" @@ -142,4 +142,4 @@ class IniFile } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__INIFILE_H +#endif diff --git a/engines/ags/shared/util/lzw.h b/engines/ags/shared/util/lzw.h index 46af7bbcc2ab..f4a7b459151f 100644 --- a/engines/ags/shared/util/lzw.h +++ b/engines/ags/shared/util/lzw.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_UTIL__LZW_H -#define __AGS_CN_UTIL__LZW_H +#ifndef AGS_SHARED_UTIL_LZW_H +#define AGS_SHARED_UTIL_LZW_H namespace AGS { namespace Common { class Stream; } } using namespace AGS; // FIXME later @@ -31,4 +31,4 @@ unsigned char *lzwexpand_to_mem(Common::Stream *in); extern long outbytes, maxsize, putbytes; -#endif // __AGS_CN_UTIL__LZW_H +#endif diff --git a/engines/ags/shared/util/math.h b/engines/ags/shared/util/math.h index 85be2a33c847..02da48ff1ea0 100644 --- a/engines/ags/shared/util/math.h +++ b/engines/ags/shared/util/math.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__MATH_H -#define __AGS_CN_UTIL__MATH_H +#ifndef AGS_SHARED_UTIL_MATH_H +#define AGS_SHARED_UTIL_MATH_H #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -98,4 +98,4 @@ namespace Math } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__MATH_H +#endif diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h index f84666b090b2..0b4761d24607 100644 --- a/engines/ags/shared/util/memory.h +++ b/engines/ags/shared/util/memory.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__MEMORY_H -#define __AGS_CN_UTIL__MEMORY_H +#ifndef AGS_SHARED_UTIL_MEMORY_H +#define AGS_SHARED_UTIL_MEMORY_H #include #include "util/bbop.h" @@ -253,4 +253,4 @@ namespace Memory } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__MEMORY_H +#endif diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h index cd97e50379c6..bac661c35d77 100644 --- a/engines/ags/shared/util/misc.h +++ b/engines/ags/shared/util/misc.h @@ -49,8 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __MISC_H -#define __MISC_H +#ifndef AGS_SHARED_UTIL_MISC_H +#define AGS_SHARED_UTIL_MISC_H #include "util/file.h" // TODO: extract filestream mode constants diff --git a/engines/ags/shared/util/multifilelib.h b/engines/ags/shared/util/multifilelib.h index 5f73e386d4f7..c7a0eea819c6 100644 --- a/engines/ags/shared/util/multifilelib.h +++ b/engines/ags/shared/util/multifilelib.h @@ -31,8 +31,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__MULTIFILELIB_H -#define __AGS_CN_UTIL__MULTIFILELIB_H +#ifndef AGS_SHARED_UTIL_MULTIFILELIB_H +#define AGS_SHARED_UTIL_MULTIFILELIB_H #include "core/asset.h" #include "util/stream.h" @@ -80,4 +80,4 @@ namespace MFLUtil } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__MULTIFILELIB_H +#endif diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h index 9083f5c88634..87d1e0596ab9 100644 --- a/engines/ags/shared/util/path.h +++ b/engines/ags/shared/util/path.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__PATH_H -#define __AGS_CN_UTIL__PATH_H +#ifndef AGS_SHARED_UTIL_PATH_H +#define AGS_SHARED_UTIL_PATH_H #include "util/string.h" @@ -90,4 +90,4 @@ namespace Path } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__PATH_H +#endif diff --git a/engines/ags/shared/util/proxystream.h b/engines/ags/shared/util/proxystream.h index 7587e779f74f..cc45cde33a0e 100644 --- a/engines/ags/shared/util/proxystream.h +++ b/engines/ags/shared/util/proxystream.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_UTIL__PROXYSTREAM_H -#define __AGS_CN_UTIL__PROXYSTREAM_H +#ifndef AGS_SHARED_UTIL_PROXYSTREAM_H +#define AGS_SHARED_UTIL_PROXYSTREAM_H #include "util/stream.h" @@ -89,4 +89,4 @@ class ProxyStream : public Stream } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__PROXYSTREAM_H +#endif diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h index 726b809fac7c..e57dbbba66aa 100644 --- a/engines/ags/shared/util/stdio_compat.h +++ b/engines/ags/shared/util/stdio_compat.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_UTIL__STDIOCOMPAT_H -#define __AGS_CN_UTIL__STDIOCOMPAT_H +#ifndef AGS_SHARED_UTIL_STDIOCOMPAT_H +#define AGS_SHARED_UTIL_STDIOCOMPAT_H #include #include @@ -44,4 +44,4 @@ file_off_t ags_file_size(const char *path); } #endif -#endif // __AGS_CN_UTIL__STDIOCOMPAT_H +#endif diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index 80c25a1df7a6..e70f9bbfa897 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -32,8 +32,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__STREAM_H -#define __AGS_CN_UTIL__STREAM_H +#ifndef AGS_SHARED_UTIL_STREAM_H +#define AGS_SHARED_UTIL_STREAM_H #include "api/stream_api.h" @@ -92,4 +92,4 @@ class Stream : public IAGSStream } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__STREAM_H +#endif diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index 94a84ab180ab..9bc56a504536 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -43,8 +43,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__STRING_H -#define __AGS_CN_UTIL__STRING_H +#ifndef AGS_SHARED_UTIL_STRING_H +#define AGS_SHARED_UTIL_STRING_H #include #include @@ -386,4 +386,4 @@ class String } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__STRING_H +#endif diff --git a/engines/ags/shared/util/string_compat.h b/engines/ags/shared/util/string_compat.h index 48a06f4312a5..631c6c22a0f9 100644 --- a/engines/ags/shared/util/string_compat.h +++ b/engines/ags/shared/util/string_compat.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_UTIL__STRINGCOMPAT_H -#define __AGS_CN_UTIL__STRINGCOMPAT_H +#ifndef AGS_SHARED_UTIL_STRINGCOMPAT_H +#define AGS_SHARED_UTIL_STRINGCOMPAT_H #include "core/types.h" @@ -39,4 +39,4 @@ char *ags_strdup(const char *s); } #endif -#endif // __AGS_CN_UTIL__STRINGCOMPAT_H +#endif diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index 7359913190dc..62c81dd15706 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_UTIL__STRINGTYPES_H -#define __AGS_CN_UTIL__STRINGTYPES_H +#ifndef AGS_SHARED_UTIL_STRINGTYPES_H +#define AGS_SHARED_UTIL_STRINGTYPES_H #include #include @@ -120,4 +120,4 @@ typedef std::unordered_map StringIMa } // namespace Common } // namespace AGS -#endif //__AGS_CN_UTIL__STRINGTYPES_H +#endif diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h index 95028808c774..440d3521612c 100644 --- a/engines/ags/shared/util/string_utils.h +++ b/engines/ags/shared/util/string_utils.h @@ -20,8 +20,8 @@ * */ -#ifndef __AGS_CN_UTIL__STRINGUTILS_H -#define __AGS_CN_UTIL__STRINGUTILS_H +#ifndef AGS_SHARED_UTIL_STRING_UTILS_H +#define AGS_SHARED_UTIL_STRING_UTILS_H #include "util/string.h" @@ -78,4 +78,4 @@ namespace StrUtil } // namespace AGS -#endif // __AGS_CN_UTIL__STRINGUTILS_H +#endif diff --git a/engines/ags/shared/util/textreader.h b/engines/ags/shared/util/textreader.h index f8fb7b23903e..d5fc20c02619 100644 --- a/engines/ags/shared/util/textreader.h +++ b/engines/ags/shared/util/textreader.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__TEXTREADER_H -#define __AGS_CN_UTIL__TEXTREADER_H +#ifndef AGS_SHARED_UTIL_TEXTREADER_H +#define AGS_SHARED_UTIL_TEXTREADER_H #include "util/string.h" @@ -56,4 +56,4 @@ class TextReader } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__TEXTSTREAM_H +#endif diff --git a/engines/ags/shared/util/textstreamreader.h b/engines/ags/shared/util/textstreamreader.h index 8301f5236b8c..74859a913b7d 100644 --- a/engines/ags/shared/util/textstreamreader.h +++ b/engines/ags/shared/util/textstreamreader.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__TEXTSTREAMREADER_H -#define __AGS_CN_UTIL__TEXTSTREAMREADER_H +#ifndef AGS_SHARED_UTIL_TEXTSTREAMREADER_H +#define AGS_SHARED_UTIL_TEXTSTREAMREADER_H #include "util/textreader.h" @@ -68,4 +68,4 @@ class TextStreamReader : public TextReader } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__TEXTSTREAM_H +#endif diff --git a/engines/ags/shared/util/textstreamwriter.h b/engines/ags/shared/util/textstreamwriter.h index 72f0fdad1aea..58ce4634b883 100644 --- a/engines/ags/shared/util/textstreamwriter.h +++ b/engines/ags/shared/util/textstreamwriter.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__TEXTSTREAMWRITER_H -#define __AGS_CN_UTIL__TEXTSTREAMWRITER_H +#ifndef AGS_SHARED_UTIL_TEXTSTREAMWRITER_H +#define AGS_SHARED_UTIL_TEXTSTREAMWRITER_H #include "util/textwriter.h" @@ -69,4 +69,4 @@ class TextStreamWriter : public TextWriter } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__TEXTSTREAMWRITER_H +#endif diff --git a/engines/ags/shared/util/textwriter.h b/engines/ags/shared/util/textwriter.h index ce07cb6b91b0..9f99a8f08e81 100644 --- a/engines/ags/shared/util/textwriter.h +++ b/engines/ags/shared/util/textwriter.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_UTIL__TEXTWRITER_H -#define __AGS_CN_UTIL__TEXTWRITER_H +#ifndef AGS_SHARED_UTIL_TEXTWRITER_H +#define AGS_SHARED_UTIL_TEXTWRITER_H #include "util/string.h" @@ -57,4 +57,4 @@ class TextWriter } // namespace Common } // namespace AGS -#endif // __AGS_CN_UTIL__TEXTWRITER_H +#endif diff --git a/engines/ags/shared/util/version.h b/engines/ags/shared/util/version.h index c74ccdd29114..09cd6c362457 100644 --- a/engines/ags/shared/util/version.h +++ b/engines/ags/shared/util/version.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef __AGS_CN_MAIN__VERSION_H -#define __AGS_CN_MAIN__VERSION_H +#ifndef AGS_SHARED_UTIL_VERSION_H +#define AGS_SHARED_UTIL_VERSION_H #include "util/string.h" @@ -115,4 +115,4 @@ struct Version } // namespace Common } // namespace AGS -#endif // __AGS_CN_MAIN__VERSION_H +#endif diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index 82e954bdcbc8..ef8a87f62768 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -32,8 +32,8 @@ #define _WGT45_ -#ifndef __WGT4_H -#define __WGT4_H +#ifndef AGS_SHARED_UTIL_WGT4_H +#define AGS_SHARED_UTIL_WGT4_H #include "allegro.h" @@ -85,5 +85,4 @@ extern "C" // archive attributes to search for - al_findfirst breaks with 0 #define FA_SEARCH -1 - -#endif // __WGT4_H +#endif From 49b1418cdbc0b5f44f4a6070fd7bf07e7359294c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 Nov 2020 22:24:21 -0800 Subject: [PATCH 006/215] COMMON: Added WeakPtr class, refactored SharedPtr --- common/ptr.h | 313 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 221 insertions(+), 92 deletions(-) diff --git a/common/ptr.h b/common/ptr.h index 802e84d6d04f..80173268da61 100644 --- a/common/ptr.h +++ b/common/ptr.h @@ -38,16 +38,16 @@ namespace Common { * @{ */ -class SharedPtrDeletionInternal { +class BasePtrDeletionInternal { public: - virtual ~SharedPtrDeletionInternal() {} + virtual ~BasePtrDeletionInternal() {} }; template -class SharedPtrDeletionImpl : public SharedPtrDeletionInternal { +class BasePtrDeletionImpl : public BasePtrDeletionInternal { public: - SharedPtrDeletionImpl(T *ptr) : _ptr(ptr) {} - ~SharedPtrDeletionImpl() { + BasePtrDeletionImpl(T *ptr) : _ptr(ptr) {} + ~BasePtrDeletionImpl() { STATIC_ASSERT(sizeof(T) > 0, SharedPtr_cannot_delete_incomplete_type); delete _ptr; } @@ -56,15 +56,180 @@ class SharedPtrDeletionImpl : public SharedPtrDeletionInternal { }; template -class SharedPtrDeletionDeleterImpl : public SharedPtrDeletionInternal { +class BasePtrDeletionDeleterImpl : public BasePtrDeletionInternal { public: - SharedPtrDeletionDeleterImpl(T *ptr, DL d) : _ptr(ptr), _deleter(d) {} - ~SharedPtrDeletionDeleterImpl() { _deleter(_ptr); } + BasePtrDeletionDeleterImpl(T *ptr, DL d) : _ptr(ptr), _deleter(d) {} + ~BasePtrDeletionDeleterImpl() { _deleter(_ptr); } private: T *_ptr; DL _deleter; }; +/** + * A base class for both SharedPtr and WeakPtr. + * + * This base class encapsulates the logic for the reference counter + * used by both. + */ +template +class BasePtr : public SafeBool > { +#if !defined(__GNUC__) || GCC_ATLEAST(3, 0) + template friend class BasePtr; +#endif +public: + typedef int RefValue; + typedef T ValueType; + typedef T *PointerType; + typedef T &ReferenceType; + + BasePtr() : _refCount(nullptr), _deletion(nullptr), _pointer(nullptr) { + } + + explicit BasePtr(nullptr_t) : _refCount(nullptr), _deletion(nullptr), _pointer(nullptr) { + } + + template + explicit BasePtr(T2 *p) : _refCount(new RefValue(1)), _deletion(new BasePtrDeletionImpl(p)), _pointer(p) { + } + + template + BasePtr(T2 *p, DL d) : _refCount(new RefValue(1)), _deletion(new BasePtrDeletionDeleterImpl(p, d)), _pointer(p) { + } + + BasePtr(const BasePtr &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { + if (_refCount) + ++(*_refCount); + } + template + BasePtr(const BasePtr &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { + if (_refCount) ++(*_refCount); + } + + ~BasePtr() { + decRef(); + } + + /** + * Implicit conversion operator to bool for convenience, to make + * checks like "if (sharedPtr) ..." possible. + */ + bool operator_bool() const { + return _pointer != nullptr; + } + + /** + * Returns the number of references to the assigned pointer. + * This should just be used for debugging purposes. + */ + RefValue refCount() const { + return _refCount ? *_refCount : 0; + } + + /** + * Returns whether the referenced object isn't valid + */ + bool expired() const { + return !_refCount; + } + + /** + * Checks if the object is the only object refering + * to the assigned pointer. This should just be used for + * debugging purposes. + */ + bool unique() const { + return refCount() == 1; + } + + BasePtr &operator=(const BasePtr &r) { + reset(r); + return *this; + } + + template + BasePtr &operator=(const BasePtr &r) { + reset(r); + return *this; + } + + /** + * Resets the object to a NULL pointer. + */ + void reset() { + decRef(); + _deletion = nullptr; + _refCount = nullptr; + _pointer = nullptr; + } + + /** + * Resets the object to the specified pointer + */ + void reset(const BasePtr &r) { + if (r._refCount) + ++(*r._refCount); + decRef(); + + _refCount = r._refCount; + _deletion = r._deletion; + _pointer = r._pointer; + } + + /** + * Resets the object to the specified pointer + */ + template + void reset(const BasePtr &r) { + if (r._refCount) + ++(*r._refCount); + decRef(); + + _refCount = r._refCount; + _deletion = r._deletion; + _pointer = r._pointer; + } + + /** + * Resets the object to the specified pointer + */ + void reset(T *ptr) { + reset(BasePtr(ptr)); + } + +protected: + RefValue *_refCount; + BasePtrDeletionInternal *_deletion; + PointerType _pointer; +protected: + /** + * Decrements the reference count to the stored pointer, and deletes it if + * there are no longer any references to it + */ + void decRef() { + if (_refCount) { + --(*_refCount); + if (!*_refCount) { + delete _refCount; + delete _deletion; + _deletion = nullptr; + _refCount = nullptr; + _pointer = nullptr; + } + } + } + + /** + * Increments the reference count to the stored pointer + */ + void incRef() { + if (_refCount) + ++*_refCount; + } +}; + +template +class WeakPtr; + /** * A simple shared pointer implementation modelled after boost. * @@ -84,7 +249,7 @@ class SharedPtrDeletionDeleterImpl : public SharedPtrDeletionInternal { * as for a normal pointer. If you need to access the plain pointer value * itself later on use the get method. The class also supplies a operator * ->, which does the same as the -> operator on a normal pointer. - * + * * Be sure you are using new to initialize the pointer you want to manage. * If you do not use new for allocating, you have to supply a deleter as * second parameter when creating a SharedPtr object. The deleter has to @@ -107,57 +272,37 @@ class SharedPtrDeletionDeleterImpl : public SharedPtrDeletionInternal { * a plain pointer is only possible via SharedPtr::get. */ template -class SharedPtr : public SafeBool > { -#if !defined(__GNUC__) || GCC_ATLEAST(3, 0) - template friend class SharedPtr; -#endif +class SharedPtr : public BasePtr { public: - typedef int RefValue; - typedef T ValueType; - typedef T *PointerType; - typedef T &ReferenceType; + using ReferenceType = typename BasePtr::ReferenceType; + using PointerType = typename BasePtr::PointerType; - SharedPtr() : _refCount(nullptr), _deletion(nullptr), _pointer(nullptr) {} - - template - explicit SharedPtr(T2 *p) : _refCount(new RefValue(1)), _deletion(new SharedPtrDeletionImpl(p)), _pointer(p) {} + SharedPtr() : BasePtr() { + } - template - SharedPtr(T2 *p, DL d) : _refCount(new RefValue(1)), _deletion(new SharedPtrDeletionDeleterImpl(p, d)), _pointer(p) {} + SharedPtr(nullptr_t) : BasePtr() { + } - SharedPtr(const SharedPtr &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { if (_refCount) ++(*_refCount); } template - SharedPtr(const SharedPtr &r) : _refCount(r._refCount), _deletion(r._deletion), _pointer(r._pointer) { if (_refCount) ++(*_refCount); } - - ~SharedPtr() { decRef(); } + explicit SharedPtr(T2 *p) : BasePtr(p) { + } - SharedPtr &operator=(const SharedPtr &r) { - if (r._refCount) - ++(*r._refCount); - decRef(); + template + SharedPtr(T2 *p, DL d) : BasePtr(p, d) { + } - _refCount = r._refCount; - _deletion = r._deletion; - _pointer = r._pointer; + SharedPtr(const SharedPtr &r) : BasePtr(r) { + } - return *this; + SharedPtr(const WeakPtr &r) : BasePtr(r) { } template - SharedPtr &operator=(const SharedPtr &r) { - if (r._refCount) - ++(*r._refCount); - decRef(); - - _refCount = r._refCount; - _deletion = r._deletion; - _pointer = r._pointer; - - return *this; + SharedPtr(const SharedPtr &r) : BasePtr(r) { } - ReferenceType operator*() const { assert(_pointer); return *_pointer; } - PointerType operator->() const { assert(_pointer); return _pointer; } + T &operator*() const { assert(this->_pointer); return *this->_pointer; } + T *operator->() const { assert(this->_pointer); return this->_pointer; } /** * Returns the plain pointer value. Be sure you know what you @@ -165,65 +310,49 @@ class SharedPtr : public SafeBool > { * * @return the pointer the SharedPtr object manages */ - PointerType get() const { return _pointer; } + PointerType get() const { return this->_pointer; } - /** - * Implicit conversion operator to bool for convenience, to make - * checks like "if (sharedPtr) ..." possible. - */ - bool operator_bool() const { return _pointer != nullptr; } + template + bool operator==(const SharedPtr &r) const { + return this->_pointer == r.get(); + } - /** - * Checks if the SharedPtr object is the only object refering - * to the assigned pointer. This should just be used for - * debugging purposes. - */ - bool unique() const { return refCount() == 1; } + template + bool operator!=(const SharedPtr &r) const { + return this->_pointer != r.get(); + } +}; - /** - * Resets the SharedPtr object to a NULL pointer. - */ - void reset() { - decRef(); - _deletion = nullptr; - _refCount = nullptr; - _pointer = nullptr; +/** + * Implements a smart pointer that holds a non-owning ("weak") refrence to + * a pointer. It needs to be converted to a SharedPtr to access it. + */ +template +class WeakPtr : public BasePtr { +public: + WeakPtr() : BasePtr() { + } + + WeakPtr(nullptr_t) : BasePtr() { } template - bool operator==(const SharedPtr &r) const { - return _pointer == r.get(); + explicit WeakPtr(T2 *p) : BasePtr(p) { + } + + WeakPtr(const BasePtr &r) : BasePtr(r) { } template - bool operator!=(const SharedPtr &r) const { - return _pointer != r.get(); + WeakPtr(const BasePtr &r) : BasePtr(r) { } /** - * Returns the number of references to the assigned pointer. - * This should just be used for debugging purposes. + * Creates a SharedPtr that manages the referenced object */ - RefValue refCount() const { return _refCount ? *_refCount : 0; } -#if !defined(__GNUC__) || GCC_ATLEAST(3, 0) -private: -#endif - void decRef() { - if (_refCount) { - --(*_refCount); - if (!*_refCount) { - delete _refCount; - delete _deletion; - _deletion = nullptr; - _refCount = nullptr; - _pointer = nullptr; - } - } + SharedPtr lock() const { + return SharedPtr(*this); } - - RefValue *_refCount; - SharedPtrDeletionInternal *_deletion; - PointerType _pointer; }; template From c59ad882fc9a0c2488b6548fd8101004c414764d Mon Sep 17 00:00:00 2001 From: dreammaster Date: Sat, 21 Nov 2020 19:31:48 +0000 Subject: [PATCH 007/215] AGS: Run astyle formatting --- engines/ags/ags.cpp | 2 +- engines/ags/detection.cpp | 2 +- engines/ags/engine/ac/asset_helper.h | 19 +- engines/ags/engine/ac/audiochannel.cpp | 399 +- engines/ags/engine/ac/audiochannel.h | 2 +- engines/ags/engine/ac/audioclip.cpp | 143 +- engines/ags/engine/ac/audioclip.h | 6 +- engines/ags/engine/ac/button.cpp | 570 +- engines/ags/engine/ac/button.h | 40 +- engines/ags/engine/ac/cdaudio.cpp | 29 +- engines/ags/engine/ac/cdaudio.h | 2 +- engines/ags/engine/ac/character.cpp | 5323 ++++++++--------- engines/ags/engine/ac/character.h | 50 +- engines/ags/engine/ac/charactercache.h | 20 +- engines/ags/engine/ac/characterextras.cpp | 66 +- engines/ags/engine/ac/characterextras.h | 48 +- .../ags/engine/ac/characterinfo_engine.cpp | 799 ++- engines/ags/engine/ac/datetime.cpp | 115 +- engines/ags/engine/ac/datetime.h | 4 +- engines/ags/engine/ac/dialog.cpp | 2108 ++++--- engines/ags/engine/ac/dialog.h | 2 +- .../ags/engine/ac/dialogoptionsrendering.cpp | 340 +- .../ags/engine/ac/dialogoptionsrendering.h | 4 +- engines/ags/engine/ac/display.cpp | 1320 ++-- engines/ags/engine/ac/display.h | 18 +- engines/ags/engine/ac/draw.cpp | 4122 ++++++------- engines/ags/engine/ac/draw.h | 34 +- engines/ags/engine/ac/draw_software.cpp | 673 +-- engines/ags/engine/ac/drawingsurface.cpp | 985 ++- engines/ags/engine/ac/drawingsurface.h | 40 +- engines/ags/engine/ac/dynamicsprite.cpp | 854 ++- engines/ags/engine/ac/dynamicsprite.h | 48 +- .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 107 +- .../engine/ac/dynobj/cc_agsdynamicobject.h | 58 +- .../ags/engine/ac/dynobj/cc_audiochannel.cpp | 16 +- .../ags/engine/ac/dynobj/cc_audiochannel.h | 6 +- engines/ags/engine/ac/dynobj/cc_audioclip.cpp | 16 +- engines/ags/engine/ac/dynobj/cc_audioclip.h | 6 +- engines/ags/engine/ac/dynobj/cc_character.cpp | 41 +- engines/ags/engine/ac/dynobj/cc_character.h | 14 +- engines/ags/engine/ac/dynobj/cc_dialog.cpp | 16 +- engines/ags/engine/ac/dynobj/cc_dialog.h | 12 +- .../ags/engine/ac/dynobj/cc_dynamicarray.cpp | 180 +- .../ags/engine/ac/dynobj/cc_dynamicarray.h | 52 +- .../ags/engine/ac/dynobj/cc_dynamicobject.cpp | 109 +- .../ags/engine/ac/dynobj/cc_dynamicobject.h | 94 +- .../cc_dynamicobject_addr_and_manager.h | 2 +- engines/ags/engine/ac/dynobj/cc_gui.cpp | 16 +- engines/ags/engine/ac/dynobj/cc_gui.h | 12 +- engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 20 +- engines/ags/engine/ac/dynobj/cc_guiobject.h | 12 +- engines/ags/engine/ac/dynobj/cc_hotspot.cpp | 16 +- engines/ags/engine/ac/dynobj/cc_hotspot.h | 12 +- engines/ags/engine/ac/dynobj/cc_inventory.cpp | 16 +- engines/ags/engine/ac/dynobj/cc_inventory.h | 12 +- engines/ags/engine/ac/dynobj/cc_object.cpp | 16 +- engines/ags/engine/ac/dynobj/cc_object.h | 12 +- engines/ags/engine/ac/dynobj/cc_region.cpp | 16 +- engines/ags/engine/ac/dynobj/cc_region.h | 12 +- .../ags/engine/ac/dynobj/cc_serializer.cpp | 160 +- engines/ags/engine/ac/dynobj/cc_serializer.h | 2 +- .../engine/ac/dynobj/managedobjectpool.cpp | 518 +- .../ags/engine/ac/dynobj/managedobjectpool.h | 98 +- .../ags/engine/ac/dynobj/scriptaudiochannel.h | 7 +- engines/ags/engine/ac/dynobj/scriptcamera.cpp | 60 +- engines/ags/engine/ac/dynobj/scriptcamera.h | 35 +- .../ags/engine/ac/dynobj/scriptdatetime.cpp | 50 +- engines/ags/engine/ac/dynobj/scriptdatetime.h | 16 +- engines/ags/engine/ac/dynobj/scriptdialog.h | 4 +- .../dynobj/scriptdialogoptionsrendering.cpp | 42 +- .../ac/dynobj/scriptdialogoptionsrendering.h | 36 +- engines/ags/engine/ac/dynobj/scriptdict.cpp | 51 +- engines/ags/engine/ac/dynobj/scriptdict.h | 257 +- .../engine/ac/dynobj/scriptdrawingsurface.cpp | 144 +- .../engine/ac/dynobj/scriptdrawingsurface.h | 60 +- .../engine/ac/dynobj/scriptdynamicsprite.cpp | 30 +- .../engine/ac/dynobj/scriptdynamicsprite.h | 14 +- engines/ags/engine/ac/dynobj/scriptfile.cpp | 81 +- engines/ags/engine/ac/dynobj/scriptfile.h | 42 +- engines/ags/engine/ac/dynobj/scriptgui.h | 4 +- engines/ags/engine/ac/dynobj/scripthotspot.h | 4 +- engines/ags/engine/ac/dynobj/scriptinvitem.h | 4 +- engines/ags/engine/ac/dynobj/scriptmouse.h | 2 +- engines/ags/engine/ac/dynobj/scriptobject.h | 6 +- .../ags/engine/ac/dynobj/scriptoverlay.cpp | 85 +- engines/ags/engine/ac/dynobj/scriptoverlay.h | 20 +- engines/ags/engine/ac/dynobj/scriptregion.h | 4 +- engines/ags/engine/ac/dynobj/scriptset.cpp | 51 +- engines/ags/engine/ac/dynobj/scriptset.h | 178 +- engines/ags/engine/ac/dynobj/scriptstring.cpp | 54 +- engines/ags/engine/ac/dynobj/scriptstring.h | 16 +- engines/ags/engine/ac/dynobj/scriptsystem.h | 16 +- .../ags/engine/ac/dynobj/scriptuserobject.cpp | 143 +- .../ags/engine/ac/dynobj/scriptuserobject.h | 74 +- .../ags/engine/ac/dynobj/scriptviewframe.cpp | 40 +- .../ags/engine/ac/dynobj/scriptviewframe.h | 14 +- .../ags/engine/ac/dynobj/scriptviewport.cpp | 60 +- engines/ags/engine/ac/dynobj/scriptviewport.h | 31 +- engines/ags/engine/ac/event.cpp | 615 +- engines/ags/engine/ac/event.h | 26 +- engines/ags/engine/ac/file.cpp | 1113 ++-- engines/ags/engine/ac/file.h | 41 +- engines/ags/engine/ac/game.cpp | 3722 ++++++------ engines/ags/engine/ac/game.h | 50 +- engines/ags/engine/ac/gamesetup.cpp | 51 +- engines/ags/engine/ac/gamesetup.h | 76 +- engines/ags/engine/ac/gamestate.cpp | 1645 +++-- engines/ags/engine/ac/gamestate.h | 646 +- engines/ags/engine/ac/global_api.cpp | 2650 ++++---- engines/ags/engine/ac/global_audio.cpp | 1009 ++-- engines/ags/engine/ac/global_audio.h | 24 +- engines/ags/engine/ac/global_button.cpp | 107 +- engines/ags/engine/ac/global_button.h | 4 +- engines/ags/engine/ac/global_character.cpp | 618 +- engines/ags/engine/ac/global_character.h | 60 +- engines/ags/engine/ac/global_datetime.cpp | 28 +- engines/ags/engine/ac/global_datetime.h | 2 +- engines/ags/engine/ac/global_debug.cpp | 237 +- engines/ags/engine/ac/global_debug.h | 2 +- engines/ags/engine/ac/global_dialog.cpp | 107 +- engines/ags/engine/ac/global_dialog.h | 2 +- engines/ags/engine/ac/global_display.cpp | 253 +- engines/ags/engine/ac/global_display.h | 12 +- .../ags/engine/ac/global_drawingsurface.cpp | 423 +- engines/ags/engine/ac/global_drawingsurface.h | 16 +- .../ags/engine/ac/global_dynamicsprite.cpp | 29 +- engines/ags/engine/ac/global_file.cpp | 247 +- engines/ags/engine/ac/global_file.h | 18 +- engines/ags/engine/ac/global_game.cpp | 1669 +++--- engines/ags/engine/ac/global_game.h | 50 +- engines/ags/engine/ac/global_gui.cpp | 286 +- engines/ags/engine/ac/global_gui.h | 18 +- engines/ags/engine/ac/global_hotspot.cpp | 164 +- engines/ags/engine/ac/global_hotspot.h | 12 +- .../ags/engine/ac/global_inventoryitem.cpp | 152 +- engines/ags/engine/ac/global_inventoryitem.h | 12 +- engines/ags/engine/ac/global_invwindow.cpp | 26 +- engines/ags/engine/ac/global_invwindow.h | 2 +- engines/ags/engine/ac/global_label.cpp | 48 +- engines/ags/engine/ac/global_label.h | 6 +- engines/ags/engine/ac/global_listbox.cpp | 52 +- engines/ags/engine/ac/global_listbox.h | 20 +- engines/ags/engine/ac/global_mouse.cpp | 8 +- engines/ags/engine/ac/global_mouse.h | 4 +- engines/ags/engine/ac/global_object.cpp | 760 ++- engines/ags/engine/ac/global_object.h | 46 +- engines/ags/engine/ac/global_overlay.cpp | 69 +- engines/ags/engine/ac/global_overlay.h | 2 +- engines/ags/engine/ac/global_palette.cpp | 51 +- engines/ags/engine/ac/global_palette.h | 4 +- engines/ags/engine/ac/global_parser.cpp | 12 +- engines/ags/engine/ac/global_parser.h | 2 +- engines/ags/engine/ac/global_plugin.h | 2 +- engines/ags/engine/ac/global_record.cpp | 4 +- engines/ags/engine/ac/global_record.h | 2 +- engines/ags/engine/ac/global_region.cpp | 207 +- engines/ags/engine/ac/global_region.h | 4 +- engines/ags/engine/ac/global_room.cpp | 273 +- engines/ags/engine/ac/global_room.h | 10 +- engines/ags/engine/ac/global_screen.cpp | 196 +- engines/ags/engine/ac/global_screen.h | 2 +- engines/ags/engine/ac/global_slider.cpp | 24 +- engines/ags/engine/ac/global_slider.h | 4 +- engines/ags/engine/ac/global_string.cpp | 58 +- engines/ags/engine/ac/global_string.h | 12 +- engines/ags/engine/ac/global_textbox.cpp | 44 +- engines/ags/engine/ac/global_textbox.h | 6 +- engines/ags/engine/ac/global_timer.cpp | 22 +- engines/ags/engine/ac/global_timer.h | 2 +- engines/ags/engine/ac/global_translation.cpp | 74 +- engines/ags/engine/ac/global_translation.h | 6 +- engines/ags/engine/ac/global_video.cpp | 73 +- engines/ags/engine/ac/global_video.h | 2 +- engines/ags/engine/ac/global_viewframe.cpp | 37 +- engines/ags/engine/ac/global_viewframe.h | 2 +- engines/ags/engine/ac/global_viewport.cpp | 16 +- engines/ags/engine/ac/global_viewport.h | 6 +- engines/ags/engine/ac/global_walkablearea.cpp | 87 +- engines/ags/engine/ac/global_walkablearea.h | 2 +- engines/ags/engine/ac/global_walkbehind.cpp | 20 +- engines/ags/engine/ac/global_walkbehind.h | 2 +- engines/ags/engine/ac/gui.cpp | 1319 ++-- engines/ags/engine/ac/gui.h | 72 +- engines/ags/engine/ac/guicontrol.cpp | 485 +- engines/ags/engine/ac/guicontrol.h | 54 +- engines/ags/engine/ac/guiinv.cpp | 93 +- engines/ags/engine/ac/hotspot.cpp | 241 +- engines/ags/engine/ac/hotspot.h | 12 +- engines/ags/engine/ac/interfacebutton.cpp | 12 +- engines/ags/engine/ac/interfaceelement.cpp | 11 +- engines/ags/engine/ac/inventoryitem.cpp | 235 +- engines/ags/engine/ac/inventoryitem.h | 4 +- engines/ags/engine/ac/invwindow.cpp | 933 ++- engines/ags/engine/ac/invwindow.h | 6 +- engines/ags/engine/ac/keycode.cpp | 478 +- engines/ags/engine/ac/keycode.h | 263 +- engines/ags/engine/ac/label.cpp | 154 +- engines/ags/engine/ac/label.h | 14 +- engines/ags/engine/ac/lipsync.h | 8 +- engines/ags/engine/ac/listbox.cpp | 743 ++- engines/ags/engine/ac/listbox.h | 52 +- engines/ags/engine/ac/math.cpp | 338 +- engines/ags/engine/ac/math.h | 6 +- engines/ags/engine/ac/mouse.cpp | 837 ++- engines/ags/engine/ac/mouse.h | 12 +- engines/ags/engine/ac/movelist.cpp | 103 +- engines/ags/engine/ac/movelist.h | 28 +- engines/ags/engine/ac/object.cpp | 1140 ++-- engines/ags/engine/ac/object.h | 18 +- engines/ags/engine/ac/objectcache.h | 12 +- engines/ags/engine/ac/overlay.cpp | 457 +- engines/ags/engine/ac/overlay.h | 14 +- engines/ags/engine/ac/parser.cpp | 508 +- engines/ags/engine/ac/parser.h | 10 +- engines/ags/engine/ac/path_helper.h | 16 +- engines/ags/engine/ac/properties.cpp | 111 +- engines/ags/engine/ac/properties.h | 4 +- engines/ags/engine/ac/region.cpp | 244 +- engines/ags/engine/ac/region.h | 2 +- engines/ags/engine/ac/richgamemedia.cpp | 50 +- engines/ags/engine/ac/richgamemedia.h | 35 +- engines/ags/engine/ac/room.cpp | 1840 +++--- engines/ags/engine/ac/room.h | 16 +- engines/ags/engine/ac/roomobject.cpp | 207 +- engines/ags/engine/ac/roomobject.h | 58 +- engines/ags/engine/ac/roomstatus.cpp | 336 +- engines/ags/engine/ac/roomstatus.h | 66 +- engines/ags/engine/ac/route_finder.cpp | 202 +- engines/ags/engine/ac/route_finder.h | 8 +- engines/ags/engine/ac/route_finder_impl.cpp | 322 +- engines/ags/engine/ac/route_finder_impl.h | 8 +- .../engine/ac/route_finder_impl_legacy.cpp | 1466 +++-- .../ags/engine/ac/route_finder_impl_legacy.h | 8 +- engines/ags/engine/ac/runtime_defines.h | 11 +- engines/ags/engine/ac/screen.cpp | 243 +- engines/ags/engine/ac/screen.h | 16 +- engines/ags/engine/ac/screenoverlay.cpp | 71 +- engines/ags/engine/ac/screenoverlay.h | 35 +- engines/ags/engine/ac/scriptcontainers.cpp | 397 +- engines/ags/engine/ac/slider.cpp | 215 +- engines/ags/engine/ac/slider.h | 24 +- engines/ags/engine/ac/speech.cpp | 272 +- engines/ags/engine/ac/speech.h | 23 +- engines/ags/engine/ac/sprite.cpp | 257 +- engines/ags/engine/ac/sprite.h | 4 +- engines/ags/engine/ac/spritecache_engine.cpp | 17 +- engines/ags/engine/ac/spritelistentry.h | 19 +- .../ags/engine/ac/statobj/agsstaticobject.cpp | 79 +- .../ags/engine/ac/statobj/agsstaticobject.h | 28 +- engines/ags/engine/ac/statobj/staticarray.cpp | 269 +- engines/ags/engine/ac/statobj/staticarray.h | 58 +- engines/ags/engine/ac/statobj/staticobject.h | 26 +- engines/ags/engine/ac/string.cpp | 599 +- engines/ags/engine/ac/string.h | 26 +- engines/ags/engine/ac/sys_events.cpp | 346 +- engines/ags/engine/ac/sys_events.h | 12 +- engines/ags/engine/ac/system.cpp | 441 +- engines/ags/engine/ac/system.h | 2 +- engines/ags/engine/ac/textbox.cpp | 152 +- engines/ags/engine/ac/textbox.h | 14 +- engines/ags/engine/ac/timer.cpp | 126 +- engines/ags/engine/ac/timer.h | 8 +- engines/ags/engine/ac/topbarsettings.h | 20 +- engines/ags/engine/ac/translation.cpp | 247 +- engines/ags/engine/ac/translation.h | 4 +- engines/ags/engine/ac/tree_map.cpp | 121 +- engines/ags/engine/ac/tree_map.h | 16 +- engines/ags/engine/ac/viewframe.cpp | 301 +- engines/ags/engine/ac/viewframe.h | 12 +- engines/ags/engine/ac/viewport_script.cpp | 770 +-- engines/ags/engine/ac/walkablearea.cpp | 335 +- engines/ags/engine/ac/walkablearea.h | 6 +- engines/ags/engine/ac/walkbehind.cpp | 190 +- engines/ags/engine/ac/walkbehind.h | 11 +- .../ags/engine/debugging/agseditordebugger.h | 17 +- .../engine/debugging/consoleoutputtarget.cpp | 24 +- .../engine/debugging/consoleoutputtarget.h | 15 +- engines/ags/engine/debugging/debug.cpp | 811 ++- engines/ags/engine/debugging/debug_log.h | 2 +- engines/ags/engine/debugging/debugger.h | 9 +- .../ags/engine/debugging/dummyagsdebugger.h | 21 +- .../engine/debugging/filebasedagsdebugger.cpp | 74 +- .../engine/debugging/filebasedagsdebugger.h | 15 +- engines/ags/engine/debugging/logfile.cpp | 92 +- engines/ags/engine/debugging/logfile.h | 56 +- .../ags/engine/debugging/messagebuffer.cpp | 61 +- engines/ags/engine/debugging/messagebuffer.h | 31 +- engines/ags/engine/device/mousew32.cpp | 467 +- engines/ags/engine/device/mousew32.h | 70 +- engines/ags/engine/font/fonts_engine.cpp | 10 +- engines/ags/engine/game/game_init.cpp | 633 +- engines/ags/engine/game/game_init.h | 25 +- engines/ags/engine/game/savegame.cpp | 1265 ++-- engines/ags/engine/game/savegame.h | 166 +- .../ags/engine/game/savegame_components.cpp | 2239 ++++--- engines/ags/engine/game/savegame_components.h | 41 +- engines/ags/engine/game/savegame_internal.h | 179 +- engines/ags/engine/game/viewport.cpp | 317 +- engines/ags/engine/game/viewport.h | 270 +- engines/ags/engine/gfx/ali3dexception.h | 26 +- engines/ags/engine/gfx/ali3dogl.cpp | 3224 +++++----- engines/ags/engine/gfx/ali3dogl.h | 551 +- engines/ags/engine/gfx/ali3dsw.cpp | 1365 ++--- engines/ags/engine/gfx/ali3dsw.h | 382 +- engines/ags/engine/gfx/blender.cpp | 353 +- engines/ags/engine/gfx/color_engine.cpp | 54 +- engines/ags/engine/gfx/ddb.h | 27 +- engines/ags/engine/gfx/gfx_util.cpp | 247 +- engines/ags/engine/gfx/gfx_util.h | 35 +- engines/ags/engine/gfx/gfxdefines.h | 83 +- engines/ags/engine/gfx/gfxdriverbase.cpp | 726 +-- engines/ags/engine/gfx/gfxdriverbase.h | 368 +- engines/ags/engine/gfx/gfxdriverfactory.cpp | 34 +- engines/ags/engine/gfx/gfxdriverfactory.h | 45 +- engines/ags/engine/gfx/gfxdriverfactorybase.h | 119 +- engines/ags/engine/gfx/gfxfilter.h | 54 +- engines/ags/engine/gfx/gfxfilter_aad3d.cpp | 28 +- engines/ags/engine/gfx/gfxfilter_aad3d.h | 22 +- engines/ags/engine/gfx/gfxfilter_aaogl.cpp | 26 +- engines/ags/engine/gfx/gfxfilter_aaogl.h | 22 +- engines/ags/engine/gfx/gfxfilter_allegro.cpp | 225 +- engines/ags/engine/gfx/gfxfilter_allegro.h | 56 +- engines/ags/engine/gfx/gfxfilter_d3d.cpp | 28 +- engines/ags/engine/gfx/gfxfilter_d3d.h | 22 +- engines/ags/engine/gfx/gfxfilter_hqx.cpp | 87 +- engines/ags/engine/gfx/gfxfilter_hqx.h | 34 +- engines/ags/engine/gfx/gfxfilter_ogl.cpp | 26 +- engines/ags/engine/gfx/gfxfilter_ogl.h | 22 +- engines/ags/engine/gfx/gfxfilter_scaling.cpp | 34 +- engines/ags/engine/gfx/gfxfilter_scaling.h | 21 +- engines/ags/engine/gfx/gfxmodelist.h | 15 +- engines/ags/engine/gfx/graphicsdriver.h | 257 +- engines/ags/engine/gfx/hq2x3x.h | 10 +- engines/ags/engine/gui/animatingguibutton.cpp | 42 +- engines/ags/engine/gui/animatingguibutton.h | 20 +- engines/ags/engine/gui/cscidialog.cpp | 411 +- engines/ags/engine/gui/cscidialog.h | 4 +- engines/ags/engine/gui/gui_engine.cpp | 138 +- engines/ags/engine/gui/guidialog.cpp | 843 ++- engines/ags/engine/gui/guidialog.h | 8 +- engines/ags/engine/gui/guidialogdefines.h | 37 +- .../ags/engine/gui/guidialoginternaldefs.h | 2 +- engines/ags/engine/gui/mylabel.cpp | 46 +- engines/ags/engine/gui/mylabel.h | 13 +- engines/ags/engine/gui/mylistbox.cpp | 317 +- engines/ags/engine/gui/mylistbox.h | 21 +- engines/ags/engine/gui/mypushbutton.cpp | 111 +- engines/ags/engine/gui/mypushbutton.h | 13 +- engines/ags/engine/gui/mytextbox.cpp | 94 +- engines/ags/engine/gui/mytextbox.h | 13 +- engines/ags/engine/gui/newcontrol.cpp | 74 +- engines/ags/engine/gui/newcontrol.h | 27 +- engines/ags/engine/main/config.cpp | 1033 ++-- engines/ags/engine/main/config.h | 4 +- engines/ags/engine/main/engine.cpp | 2488 ++++---- engines/ags/engine/main/engine.h | 18 +- engines/ags/engine/main/engine_setup.cpp | 473 +- engines/ags/engine/main/game_file.cpp | 156 +- engines/ags/engine/main/game_run.cpp | 1625 +++-- engines/ags/engine/main/game_run.h | 6 +- engines/ags/engine/main/game_start.cpp | 152 +- engines/ags/engine/main/graphics_mode.cpp | 1021 ++-- engines/ags/engine/main/graphics_mode.h | 117 +- engines/ags/engine/main/main.cpp | 568 +- engines/ags/engine/main/quit.cpp | 330 +- engines/ags/engine/main/quit.h | 37 +- engines/ags/engine/main/update.cpp | 743 ++- engines/ags/engine/main/update.h | 4 +- .../ags/engine/media/audio/ambientsound.cpp | 38 +- engines/ags/engine/media/audio/ambientsound.h | 22 +- engines/ags/engine/media/audio/audio.cpp | 1806 +++--- engines/ags/engine/media/audio/audio.h | 60 +- .../ags/engine/media/audio/clip_mydumbmod.cpp | 198 +- .../ags/engine/media/audio/clip_mydumbmod.h | 53 +- .../ags/engine/media/audio/clip_myjgmod.cpp | 71 +- engines/ags/engine/media/audio/clip_myjgmod.h | 27 +- .../ags/engine/media/audio/clip_mymidi.cpp | 117 +- engines/ags/engine/media/audio/clip_mymidi.h | 35 +- engines/ags/engine/media/audio/clip_mymp3.cpp | 209 +- engines/ags/engine/media/audio/clip_mymp3.h | 41 +- engines/ags/engine/media/audio/clip_myogg.cpp | 277 +- engines/ags/engine/media/audio/clip_myogg.h | 45 +- .../engine/media/audio/clip_mystaticmp3.cpp | 175 +- .../ags/engine/media/audio/clip_mystaticmp3.h | 35 +- .../engine/media/audio/clip_mystaticogg.cpp | 256 +- .../ags/engine/media/audio/clip_mystaticogg.h | 47 +- .../ags/engine/media/audio/clip_mywave.cpp | 130 +- engines/ags/engine/media/audio/clip_mywave.h | 31 +- .../engine/media/audio/queuedaudioitem.cpp | 22 +- .../ags/engine/media/audio/queuedaudioitem.h | 18 +- engines/ags/engine/media/audio/sound.cpp | 432 +- engines/ags/engine/media/audio/soundcache.cpp | 314 +- engines/ags/engine/media/audio/soundcache.h | 23 +- engines/ags/engine/media/audio/soundclip.cpp | 90 +- engines/ags/engine/media/audio/soundclip.h | 244 +- engines/ags/engine/media/video/VMR9Graph.h | 79 +- engines/ags/engine/media/video/video.cpp | 583 +- engines/ags/engine/media/video/video.h | 2 +- .../ags/engine/platform/android/acpland.cpp | 1081 ++-- .../platform/base/agsplatformdriver.cpp | 246 +- .../engine/platform/base/agsplatformdriver.h | 262 +- engines/ags/engine/platform/ios/acplios.cpp | 725 ++- engines/ags/engine/platform/linux/acpllnx.cpp | 239 +- engines/ags/engine/platform/osx/acplmac.cpp | 122 +- engines/ags/engine/platform/util/pe.h | 8 +- .../ags/engine/platform/windows/acplwin.cpp | 1685 +++--- .../debugging/namedpipesagsdebugger.cpp | 103 +- .../windows/debugging/namedpipesagsdebugger.h | 23 +- .../engine/platform/windows/gfx/ali3dd3d.cpp | 3636 ++++++----- .../engine/platform/windows/gfx/ali3dd3d.h | 515 +- .../platform/windows/media/video/acwavi.cpp | 598 +- .../platform/windows/media/video/acwavi3d.cpp | 731 ++- .../ags/engine/platform/windows/minidump.cpp | 117 +- .../platform/windows/setup/winsetup.cpp | 1959 +++--- .../engine/platform/windows/setup/winsetup.h | 6 +- .../platform/windows/win_ex_handling.cpp | 63 +- engines/ags/engine/plugin/agsplugin.cpp | 1496 +++-- engines/ags/engine/plugin/agsplugin.h | 722 +-- engines/ags/engine/plugin/global_plugin.cpp | 399 +- engines/ags/engine/plugin/plugin_builtin.h | 12 +- engines/ags/engine/plugin/plugin_engine.h | 10 +- .../ags/engine/plugin/pluginobjectreader.h | 4 +- engines/ags/engine/resource/resource.h | 2 +- engines/ags/engine/script/cc_instance.cpp | 3342 +++++------ engines/ags/engine/script/cc_instance.h | 284 +- engines/ags/engine/script/executingscript.cpp | 103 +- engines/ags/engine/script/executingscript.h | 68 +- engines/ags/engine/script/exports.cpp | 75 +- .../engine/script/nonblockingscriptfunction.h | 36 +- .../ags/engine/script/runtimescriptvalue.cpp | 451 +- .../ags/engine/script/runtimescriptvalue.h | 641 +- engines/ags/engine/script/script.cpp | 1424 +++-- engines/ags/engine/script/script.h | 22 +- engines/ags/engine/script/script_api.cpp | 383 +- engines/ags/engine/script/script_api.h | 534 +- engines/ags/engine/script/script_engine.cpp | 29 +- engines/ags/engine/script/script_runtime.cpp | 373 +- engines/ags/engine/script/script_runtime.h | 6 +- engines/ags/engine/script/systemimports.cpp | 179 +- engines/ags/engine/script/systemimports.h | 43 +- engines/ags/engine/util/library.h | 21 +- engines/ags/engine/util/library_dummy.h | 47 +- engines/ags/engine/util/library_posix.h | 174 +- engines/ags/engine/util/library_psp.h | 199 +- engines/ags/engine/util/library_windows.h | 114 +- engines/ags/engine/util/mutex.h | 23 +- engines/ags/engine/util/mutex_base.h | 17 +- engines/ags/engine/util/mutex_lock.h | 26 +- engines/ags/engine/util/mutex_psp.h | 39 +- engines/ags/engine/util/mutex_pthread.h | 39 +- engines/ags/engine/util/mutex_std.h | 39 +- engines/ags/engine/util/mutex_wii.h | 39 +- engines/ags/engine/util/mutex_windows.h | 47 +- engines/ags/engine/util/scaling.h | 246 +- engines/ags/engine/util/thread.h | 38 +- engines/ags/engine/util/thread_psp.h | 140 +- engines/ags/engine/util/thread_pthread.h | 134 +- engines/ags/engine/util/thread_std.h | 127 +- engines/ags/engine/util/thread_wii.h | 134 +- engines/ags/engine/util/thread_windows.h | 140 +- engines/ags/shared/ac/audiocliptype.cpp | 40 +- engines/ags/shared/ac/audiocliptype.h | 24 +- engines/ags/shared/ac/characterinfo.cpp | 256 +- engines/ags/shared/ac/characterinfo.h | 144 +- engines/ags/shared/ac/common.cpp | 13 +- engines/ags/shared/ac/dialogtopic.cpp | 33 +- engines/ags/shared/ac/dialogtopic.h | 28 +- .../ags/shared/ac/dynobj/scriptaudioclip.cpp | 23 +- .../ags/shared/ac/dynobj/scriptaudioclip.h | 40 +- engines/ags/shared/ac/game_version.h | 65 +- engines/ags/shared/ac/gamesetupstruct.cpp | 729 ++- engines/ags/shared/ac/gamesetupstruct.h | 236 +- engines/ags/shared/ac/gamesetupstructbase.cpp | 414 +- engines/ags/shared/ac/gamesetupstructbase.h | 386 +- engines/ags/shared/ac/gamestructdefines.h | 184 +- engines/ags/shared/ac/interfacebutton.h | 10 +- engines/ags/shared/ac/interfaceelement.h | 24 +- engines/ags/shared/ac/inventoryiteminfo.cpp | 52 +- engines/ags/shared/ac/inventoryiteminfo.h | 24 +- engines/ags/shared/ac/mousecursor.cpp | 65 +- engines/ags/shared/ac/mousecursor.h | 26 +- engines/ags/shared/ac/oldgamesetupstruct.h | 72 +- engines/ags/shared/ac/spritecache.cpp | 1589 +++-- engines/ags/shared/ac/spritecache.h | 318 +- engines/ags/shared/ac/view.cpp | 284 +- engines/ags/shared/ac/view.h | 78 +- engines/ags/shared/ac/wordsdictionary.cpp | 207 +- engines/ags/shared/ac/wordsdictionary.h | 32 +- engines/ags/shared/api/stream_api.h | 86 +- engines/ags/shared/core/asset.cpp | 24 +- engines/ags/shared/core/asset.h | 36 +- engines/ags/shared/core/assetmanager.cpp | 631 +- engines/ags/shared/core/assetmanager.h | 174 +- engines/ags/shared/core/platform.h | 146 +- engines/ags/shared/core/types.h | 23 +- engines/ags/shared/debugging/debugmanager.cpp | 315 +- engines/ags/shared/debugging/debugmanager.h | 170 +- engines/ags/shared/debugging/out.h | 124 +- engines/ags/shared/debugging/outputhandler.h | 44 +- engines/ags/shared/font/agsfontrenderer.h | 45 +- engines/ags/shared/font/fonts.cpp | 553 +- engines/ags/shared/font/fonts.h | 57 +- engines/ags/shared/font/ttffontrenderer.cpp | 146 +- engines/ags/shared/font/ttffontrenderer.h | 37 +- engines/ags/shared/font/wfnfont.cpp | 298 +- engines/ags/shared/font/wfnfont.h | 87 +- engines/ags/shared/font/wfnfontrenderer.cpp | 229 +- engines/ags/shared/font/wfnfontrenderer.h | 31 +- engines/ags/shared/game/customproperties.cpp | 171 +- engines/ags/shared/game/customproperties.h | 69 +- engines/ags/shared/game/interactions.cpp | 615 +- engines/ags/shared/game/interactions.h | 179 +- engines/ags/shared/game/main_game_file.cpp | 1342 ++--- engines/ags/shared/game/main_game_file.h | 137 +- engines/ags/shared/game/plugininfo.h | 25 +- engines/ags/shared/game/room_file.cpp | 1623 +++-- engines/ags/shared/game/room_file.h | 52 +- .../ags/shared/game/room_file_deprecated.cpp | 148 +- engines/ags/shared/game/room_version.h | 67 +- engines/ags/shared/game/roomstruct.cpp | 453 +- engines/ags/shared/game/roomstruct.h | 465 +- engines/ags/shared/gfx/allegrobitmap.cpp | 421 +- engines/ags/shared/gfx/allegrobitmap.h | 356 +- engines/ags/shared/gfx/bitmap.cpp | 200 +- engines/ags/shared/gfx/bitmap.h | 61 +- engines/ags/shared/gfx/gfx_def.h | 142 +- engines/ags/shared/gui/guibutton.cpp | 598 +- engines/ags/shared/gui/guibutton.h | 171 +- engines/ags/shared/gui/guidefines.h | 191 +- engines/ags/shared/gui/guiinv.cpp | 177 +- engines/ags/shared/gui/guiinv.h | 57 +- engines/ags/shared/gui/guilabel.cpp | 153 +- engines/ags/shared/gui/guilabel.h | 47 +- engines/ags/shared/gui/guilistbox.cpp | 663 +- engines/ags/shared/gui/guilistbox.h | 115 +- engines/ags/shared/gui/guimain.cpp | 1559 +++-- engines/ags/shared/gui/guimain.h | 287 +- engines/ags/shared/gui/guiobject.cpp | 300 +- engines/ags/shared/gui/guiobject.h | 150 +- engines/ags/shared/gui/guislider.cpp | 407 +- engines/ags/shared/gui/guislider.h | 59 +- engines/ags/shared/gui/guitextbox.cpp | 183 +- engines/ags/shared/gui/guitextbox.h | 49 +- engines/ags/shared/script/cc_error.cpp | 47 +- engines/ags/shared/script/cc_options.cpp | 20 +- engines/ags/shared/script/cc_script.cpp | 656 +- engines/ags/shared/script/cc_script.h | 79 +- engines/ags/shared/util/alignedstream.cpp | 547 +- engines/ags/shared/util/alignedstream.h | 104 +- engines/ags/shared/util/bbop.h | 149 +- engines/ags/shared/util/bufferedstream.cpp | 160 +- engines/ags/shared/util/bufferedstream.h | 49 +- engines/ags/shared/util/compress.cpp | 693 ++- engines/ags/shared/util/compress.h | 9 +- engines/ags/shared/util/datastream.cpp | 228 +- engines/ags/shared/util/datastream.h | 179 +- engines/ags/shared/util/directory.cpp | 76 +- engines/ags/shared/util/directory.h | 27 +- engines/ags/shared/util/error.h | 146 +- engines/ags/shared/util/file.cpp | 234 +- engines/ags/shared/util/file.h | 86 +- engines/ags/shared/util/filestream.cpp | 218 +- engines/ags/shared/util/filestream.h | 69 +- engines/ags/shared/util/geometry.cpp | 155 +- engines/ags/shared/util/geometry.h | 443 +- engines/ags/shared/util/ini_util.cpp | 289 +- engines/ags/shared/util/ini_util.h | 55 +- engines/ags/shared/util/inifile.cpp | 407 +- engines/ags/shared/util/inifile.h | 214 +- engines/ags/shared/util/lzw.cpp | 412 +- engines/ags/shared/util/lzw.h | 6 +- engines/ags/shared/util/math.h | 91 +- engines/ags/shared/util/memory.h | 396 +- engines/ags/shared/util/misc.cpp | 243 +- engines/ags/shared/util/misc.h | 16 +- engines/ags/shared/util/multifilelib.h | 55 +- engines/ags/shared/util/mutifilelib.cpp | 755 ++- engines/ags/shared/util/path.cpp | 368 +- engines/ags/shared/util/path.h | 93 +- engines/ags/shared/util/proxystream.cpp | 170 +- engines/ags/shared/util/proxystream.h | 88 +- engines/ags/shared/util/stdio_compat.h | 4 +- engines/ags/shared/util/stream.cpp | 26 +- engines/ags/shared/util/stream.h | 79 +- engines/ags/shared/util/string.cpp | 1754 +++--- engines/ags/shared/util/string.h | 621 +- engines/ags/shared/util/string_types.h | 77 +- engines/ags/shared/util/string_utils.cpp | 210 +- engines/ags/shared/util/string_utils.h | 74 +- engines/ags/shared/util/textreader.h | 33 +- engines/ags/shared/util/textstreamreader.cpp | 198 +- engines/ags/shared/util/textstreamreader.h | 43 +- engines/ags/shared/util/textstreamwriter.cpp | 117 +- engines/ags/shared/util/textstreamwriter.h | 45 +- engines/ags/shared/util/textwriter.h | 35 +- engines/ags/shared/util/version.cpp | 190 +- engines/ags/shared/util/version.h | 136 +- engines/ags/shared/util/wgt2allg.cpp | 355 +- engines/ags/shared/util/wgt2allg.h | 32 +- engines/ags/std/list.h | 2 +- engines/ags/std/map.h | 4 +- engines/ags/std/set.h | 16 +- engines/ags/std/vector.h | 2 +- engines/ags/stubs/allegro/base.h | 4 +- engines/ags/stubs/allegro/color.h | 4 +- engines/ags/stubs/allegro/digi.h | 8 +- engines/ags/stubs/allegro/fixed.cpp | 86 +- engines/ags/stubs/allegro/gfx.h | 6 +- engines/ags/stubs/allegro/midi.h | 10 +- 609 files changed, 70557 insertions(+), 78159 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 133e2ec91513..ce3961461ca2 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -35,7 +35,7 @@ AGSEngine *g_vm; /*------------------------------------------------------------------*/ AGSEngine::AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc) : Engine(syst), - _gameDescription(gameDesc), _randomSource("AGS") { + _gameDescription(gameDesc), _randomSource("AGS") { g_vm = this; DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); diff --git a/engines/ags/detection.cpp b/engines/ags/detection.cpp index 898cc29fb7c3..7956183a508c 100644 --- a/engines/ags/detection.cpp +++ b/engines/ags/detection.cpp @@ -25,7 +25,7 @@ #include "ags/detection_tables.h" AGSMetaEngineDetection::AGSMetaEngineDetection() : AdvancedMetaEngineDetection(AGS::GAME_DESCRIPTIONS, - sizeof(AGS::AGSGameDescription), AGS::AGS_GAMES) { + sizeof(AGS::AGSGameDescription), AGS::AGS_GAMES) { static const char *const DIRECTORY_GLOBS[2] = { "usecode", 0 }; _maxScanDepth = 2; _directoryGlobs = DIRECTORY_GLOBS; diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index bfe4130c314b..4efd81efb07c 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -33,7 +33,11 @@ #include #include "util/string.h" -namespace AGS { namespace Common {class Stream;}} +namespace AGS { +namespace Common { +class Stream; +} +} using AGS::Common::Stream; using AGS::Common::String; @@ -45,8 +49,8 @@ String get_known_assetlib(const String &filename); Stream *find_open_asset(const String &filename); extern "C" { - struct PACKFILE; // Allegro 4's own stream type - struct DUMBFILE; // DUMB stream type + struct PACKFILE; // Allegro 4's own stream type + struct DUMBFILE; // DUMB stream type } // AssetPath combines asset library and item names @@ -62,11 +66,10 @@ AssetPath get_voice_over_assetpath(const String &filename); // Custom AGS PACKFILE user object // TODO: it is preferrable to let our Stream define custom readable window instead, // keeping this as simple as possible for now (we may require a stream classes overhaul). -struct AGS_PACKFILE_OBJ -{ - std::unique_ptr stream; - size_t asset_size = 0u; - size_t remains = 0u; +struct AGS_PACKFILE_OBJ { + std::unique_ptr stream; + size_t asset_size = 0u; + size_t remains = 0u; }; // Creates PACKFILE stream from AGS asset. // This function is supposed to be used only when you have to create Allegro diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp index 3f1190b01785..e3898f35a616 100644 --- a/engines/ags/engine/ac/audiochannel.cpp +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -35,194 +35,163 @@ extern GameState play; extern RoomStruct thisroom; extern CCAudioClip ccDynamicAudioClip; -int AudioChannel_GetID(ScriptAudioChannel *channel) -{ - return channel->id; +int AudioChannel_GetID(ScriptAudioChannel *channel) { + return channel->id; } -int AudioChannel_GetIsPlaying(ScriptAudioChannel *channel) -{ - if (play.fast_forward) - { - return 0; - } +int AudioChannel_GetIsPlaying(ScriptAudioChannel *channel) { + if (play.fast_forward) { + return 0; + } - return channel_is_playing(channel->id) ? 1 : 0; + return channel_is_playing(channel->id) ? 1 : 0; } -int AudioChannel_GetPanning(ScriptAudioChannel *channel) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +int AudioChannel_GetPanning(ScriptAudioChannel *channel) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - return ch->panningAsPercentage; - } - return 0; + if (ch) { + return ch->panningAsPercentage; + } + return 0; } -void AudioChannel_SetPanning(ScriptAudioChannel *channel, int newPanning) -{ - if ((newPanning < -100) || (newPanning > 100)) - quitprintf("!AudioChannel.Panning: panning value must be between -100 and 100 (passed=%d)", newPanning); +void AudioChannel_SetPanning(ScriptAudioChannel *channel, int newPanning) { + if ((newPanning < -100) || (newPanning > 100)) + quitprintf("!AudioChannel.Panning: panning value must be between -100 and 100 (passed=%d)", newPanning); - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - ch->set_panning(((newPanning + 100) * 255) / 200); - ch->panningAsPercentage = newPanning; - } + if (ch) { + ch->set_panning(((newPanning + 100) * 255) / 200); + ch->panningAsPercentage = newPanning; + } } -ScriptAudioClip* AudioChannel_GetPlayingClip(ScriptAudioChannel *channel) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +ScriptAudioClip *AudioChannel_GetPlayingClip(ScriptAudioChannel *channel) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - return (ScriptAudioClip*)ch->sourceClip; - } - return nullptr; + if (ch) { + return (ScriptAudioClip *)ch->sourceClip; + } + return nullptr; } -int AudioChannel_GetPosition(ScriptAudioChannel *channel) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +int AudioChannel_GetPosition(ScriptAudioChannel *channel) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - if (play.fast_forward) - return 999999999; + if (ch) { + if (play.fast_forward) + return 999999999; - return ch->get_pos(); - } - return 0; + return ch->get_pos(); + } + return 0; } -int AudioChannel_GetPositionMs(ScriptAudioChannel *channel) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +int AudioChannel_GetPositionMs(ScriptAudioChannel *channel) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - if (play.fast_forward) - return 999999999; + if (ch) { + if (play.fast_forward) + return 999999999; - return ch->get_pos_ms(); - } - return 0; + return ch->get_pos_ms(); + } + return 0; } -int AudioChannel_GetLengthMs(ScriptAudioChannel *channel) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +int AudioChannel_GetLengthMs(ScriptAudioChannel *channel) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - return ch->get_length_ms(); - } - return 0; + if (ch) { + return ch->get_length_ms(); + } + return 0; } -int AudioChannel_GetVolume(ScriptAudioChannel *channel) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +int AudioChannel_GetVolume(ScriptAudioChannel *channel) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - return ch->get_volume(); - } - return 0; + if (ch) { + return ch->get_volume(); + } + return 0; } -int AudioChannel_SetVolume(ScriptAudioChannel *channel, int newVolume) -{ - if ((newVolume < 0) || (newVolume > 100)) - quitprintf("!AudioChannel.Volume: new value out of range (supplied: %d, range: 0..100)", newVolume); +int AudioChannel_SetVolume(ScriptAudioChannel *channel, int newVolume) { + if ((newVolume < 0) || (newVolume > 100)) + quitprintf("!AudioChannel.Volume: new value out of range (supplied: %d, range: 0..100)", newVolume); - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - ch->set_volume_percent(newVolume); - } - return 0; + if (ch) { + ch->set_volume_percent(newVolume); + } + return 0; } -int AudioChannel_GetSpeed(ScriptAudioChannel *channel) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +int AudioChannel_GetSpeed(ScriptAudioChannel *channel) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - return ch->get_speed(); - } - return 0; + if (ch) { + return ch->get_speed(); + } + return 0; } -void AudioChannel_SetSpeed(ScriptAudioChannel *channel, int new_speed) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); +void AudioChannel_SetSpeed(ScriptAudioChannel *channel, int new_speed) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - ch->set_speed(new_speed); - } + if (ch) { + ch->set_speed(new_speed); + } } -void AudioChannel_Stop(ScriptAudioChannel *channel) -{ - if (channel->id == SCHAN_SPEECH && play.IsNonBlockingVoiceSpeech()) - stop_voice_nonblocking(); - else - stop_or_fade_out_channel(channel->id, -1, nullptr); +void AudioChannel_Stop(ScriptAudioChannel *channel) { + if (channel->id == SCHAN_SPEECH && play.IsNonBlockingVoiceSpeech()) + stop_voice_nonblocking(); + else + stop_or_fade_out_channel(channel->id, -1, nullptr); } -void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition) -{ - if (newPosition < 0) - quitprintf("!AudioChannel.Seek: invalid seek position %d", newPosition); +void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition) { + if (newPosition < 0) + quitprintf("!AudioChannel.Seek: invalid seek position %d", newPosition); - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); - if (ch) - { - ch->seek(newPosition); - } + if (ch) { + ch->seek(newPosition); + } } -void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos) -{ - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(channel->id); - - if (ch) - { - int maxDist = ((xPos > thisroom.Width / 2) ? xPos : (thisroom.Width - xPos)) - AMBIENCE_FULL_DIST; - ch->xSource = (xPos > 0) ? xPos : -1; - ch->ySource = yPos; - ch->maximumPossibleDistanceAway = maxDist; - if (xPos > 0) - { - update_directional_sound_vol(); - } - else - { - ch->apply_directional_modifier(0); - } - } +void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos) { + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(channel->id); + + if (ch) { + int maxDist = ((xPos > thisroom.Width / 2) ? xPos : (thisroom.Width - xPos)) - AMBIENCE_FULL_DIST; + ch->xSource = (xPos > 0) ? xPos : -1; + ch->ySource = yPos; + ch->maximumPossibleDistanceAway = maxDist; + if (xPos > 0) { + update_directional_sound_vol(); + } else { + ch->apply_directional_modifier(0); + } + } } //============================================================================= @@ -236,126 +205,110 @@ void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPo #include "script/script_runtime.h" // int | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetID); +RuntimeScriptValue Sc_AudioChannel_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetID); } // int | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetIsPlaying(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetIsPlaying); +RuntimeScriptValue Sc_AudioChannel_GetIsPlaying(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetIsPlaying); } // int | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetPanning(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPanning); +RuntimeScriptValue Sc_AudioChannel_GetPanning(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPanning); } // void | ScriptAudioChannel *channel, int newPanning -RuntimeScriptValue Sc_AudioChannel_SetPanning(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_SetPanning); +RuntimeScriptValue Sc_AudioChannel_SetPanning(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_SetPanning); } // ScriptAudioClip* | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetPlayingClip(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptAudioChannel, ScriptAudioClip, ccDynamicAudioClip, AudioChannel_GetPlayingClip); +RuntimeScriptValue Sc_AudioChannel_GetPlayingClip(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptAudioChannel, ScriptAudioClip, ccDynamicAudioClip, AudioChannel_GetPlayingClip); } // int | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPosition); +RuntimeScriptValue Sc_AudioChannel_GetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPosition); } // int | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetPositionMs(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPositionMs); +RuntimeScriptValue Sc_AudioChannel_GetPositionMs(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetPositionMs); } // int | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetLengthMs(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetLengthMs); +RuntimeScriptValue Sc_AudioChannel_GetLengthMs(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetLengthMs); } // int | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_GetVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetVolume); +RuntimeScriptValue Sc_AudioChannel_GetVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetVolume); } // int | ScriptAudioChannel *channel, int newVolume -RuntimeScriptValue Sc_AudioChannel_SetVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(ScriptAudioChannel, AudioChannel_SetVolume); +RuntimeScriptValue Sc_AudioChannel_SetVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(ScriptAudioChannel, AudioChannel_SetVolume); } // void | ScriptAudioChannel *channel -RuntimeScriptValue Sc_AudioChannel_Stop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptAudioChannel, AudioChannel_Stop); +RuntimeScriptValue Sc_AudioChannel_Stop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptAudioChannel, AudioChannel_Stop); } // void | ScriptAudioChannel *channel, int newPosition -RuntimeScriptValue Sc_AudioChannel_Seek(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_Seek); +RuntimeScriptValue Sc_AudioChannel_Seek(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_Seek); } // void | ScriptAudioChannel *channel, int xPos, int yPos -RuntimeScriptValue Sc_AudioChannel_SetRoomLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptAudioChannel, AudioChannel_SetRoomLocation); +RuntimeScriptValue Sc_AudioChannel_SetRoomLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptAudioChannel, AudioChannel_SetRoomLocation); } -RuntimeScriptValue Sc_AudioChannel_GetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetSpeed); +RuntimeScriptValue Sc_AudioChannel_GetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetSpeed); } -RuntimeScriptValue Sc_AudioChannel_SetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_SetSpeed); +RuntimeScriptValue Sc_AudioChannel_SetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptAudioChannel, AudioChannel_SetSpeed); } -void RegisterAudioChannelAPI() -{ - ccAddExternalObjectFunction("AudioChannel::Seek^1", Sc_AudioChannel_Seek); - ccAddExternalObjectFunction("AudioChannel::SetRoomLocation^2", Sc_AudioChannel_SetRoomLocation); - ccAddExternalObjectFunction("AudioChannel::Stop^0", Sc_AudioChannel_Stop); - ccAddExternalObjectFunction("AudioChannel::get_ID", Sc_AudioChannel_GetID); - ccAddExternalObjectFunction("AudioChannel::get_IsPlaying", Sc_AudioChannel_GetIsPlaying); - ccAddExternalObjectFunction("AudioChannel::get_LengthMs", Sc_AudioChannel_GetLengthMs); - ccAddExternalObjectFunction("AudioChannel::get_Panning", Sc_AudioChannel_GetPanning); - ccAddExternalObjectFunction("AudioChannel::set_Panning", Sc_AudioChannel_SetPanning); - ccAddExternalObjectFunction("AudioChannel::get_PlayingClip", Sc_AudioChannel_GetPlayingClip); - ccAddExternalObjectFunction("AudioChannel::get_Position", Sc_AudioChannel_GetPosition); - ccAddExternalObjectFunction("AudioChannel::get_PositionMs", Sc_AudioChannel_GetPositionMs); - ccAddExternalObjectFunction("AudioChannel::get_Volume", Sc_AudioChannel_GetVolume); - ccAddExternalObjectFunction("AudioChannel::set_Volume", Sc_AudioChannel_SetVolume); - ccAddExternalObjectFunction("AudioChannel::get_Speed", Sc_AudioChannel_GetSpeed); - ccAddExternalObjectFunction("AudioChannel::set_Speed", Sc_AudioChannel_SetSpeed); - // For compatibility with Ahmet Kamil's (aka Gord10) custom engine - ccAddExternalObjectFunction("AudioChannel::SetSpeed^1", Sc_AudioChannel_SetSpeed); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("AudioChannel::Seek^1", (void*)AudioChannel_Seek); - ccAddExternalFunctionForPlugin("AudioChannel::SetRoomLocation^2", (void*)AudioChannel_SetRoomLocation); - ccAddExternalFunctionForPlugin("AudioChannel::Stop^0", (void*)AudioChannel_Stop); - ccAddExternalFunctionForPlugin("AudioChannel::get_ID", (void*)AudioChannel_GetID); - ccAddExternalFunctionForPlugin("AudioChannel::get_IsPlaying", (void*)AudioChannel_GetIsPlaying); - ccAddExternalFunctionForPlugin("AudioChannel::get_LengthMs", (void*)AudioChannel_GetLengthMs); - ccAddExternalFunctionForPlugin("AudioChannel::get_Panning", (void*)AudioChannel_GetPanning); - ccAddExternalFunctionForPlugin("AudioChannel::set_Panning", (void*)AudioChannel_SetPanning); - ccAddExternalFunctionForPlugin("AudioChannel::get_PlayingClip", (void*)AudioChannel_GetPlayingClip); - ccAddExternalFunctionForPlugin("AudioChannel::get_Position", (void*)AudioChannel_GetPosition); - ccAddExternalFunctionForPlugin("AudioChannel::get_PositionMs", (void*)AudioChannel_GetPositionMs); - ccAddExternalFunctionForPlugin("AudioChannel::get_Volume", (void*)AudioChannel_GetVolume); - ccAddExternalFunctionForPlugin("AudioChannel::set_Volume", (void*)AudioChannel_SetVolume); +void RegisterAudioChannelAPI() { + ccAddExternalObjectFunction("AudioChannel::Seek^1", Sc_AudioChannel_Seek); + ccAddExternalObjectFunction("AudioChannel::SetRoomLocation^2", Sc_AudioChannel_SetRoomLocation); + ccAddExternalObjectFunction("AudioChannel::Stop^0", Sc_AudioChannel_Stop); + ccAddExternalObjectFunction("AudioChannel::get_ID", Sc_AudioChannel_GetID); + ccAddExternalObjectFunction("AudioChannel::get_IsPlaying", Sc_AudioChannel_GetIsPlaying); + ccAddExternalObjectFunction("AudioChannel::get_LengthMs", Sc_AudioChannel_GetLengthMs); + ccAddExternalObjectFunction("AudioChannel::get_Panning", Sc_AudioChannel_GetPanning); + ccAddExternalObjectFunction("AudioChannel::set_Panning", Sc_AudioChannel_SetPanning); + ccAddExternalObjectFunction("AudioChannel::get_PlayingClip", Sc_AudioChannel_GetPlayingClip); + ccAddExternalObjectFunction("AudioChannel::get_Position", Sc_AudioChannel_GetPosition); + ccAddExternalObjectFunction("AudioChannel::get_PositionMs", Sc_AudioChannel_GetPositionMs); + ccAddExternalObjectFunction("AudioChannel::get_Volume", Sc_AudioChannel_GetVolume); + ccAddExternalObjectFunction("AudioChannel::set_Volume", Sc_AudioChannel_SetVolume); + ccAddExternalObjectFunction("AudioChannel::get_Speed", Sc_AudioChannel_GetSpeed); + ccAddExternalObjectFunction("AudioChannel::set_Speed", Sc_AudioChannel_SetSpeed); + // For compatibility with Ahmet Kamil's (aka Gord10) custom engine + ccAddExternalObjectFunction("AudioChannel::SetSpeed^1", Sc_AudioChannel_SetSpeed); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("AudioChannel::Seek^1", (void *)AudioChannel_Seek); + ccAddExternalFunctionForPlugin("AudioChannel::SetRoomLocation^2", (void *)AudioChannel_SetRoomLocation); + ccAddExternalFunctionForPlugin("AudioChannel::Stop^0", (void *)AudioChannel_Stop); + ccAddExternalFunctionForPlugin("AudioChannel::get_ID", (void *)AudioChannel_GetID); + ccAddExternalFunctionForPlugin("AudioChannel::get_IsPlaying", (void *)AudioChannel_GetIsPlaying); + ccAddExternalFunctionForPlugin("AudioChannel::get_LengthMs", (void *)AudioChannel_GetLengthMs); + ccAddExternalFunctionForPlugin("AudioChannel::get_Panning", (void *)AudioChannel_GetPanning); + ccAddExternalFunctionForPlugin("AudioChannel::set_Panning", (void *)AudioChannel_SetPanning); + ccAddExternalFunctionForPlugin("AudioChannel::get_PlayingClip", (void *)AudioChannel_GetPlayingClip); + ccAddExternalFunctionForPlugin("AudioChannel::get_Position", (void *)AudioChannel_GetPosition); + ccAddExternalFunctionForPlugin("AudioChannel::get_PositionMs", (void *)AudioChannel_GetPositionMs); + ccAddExternalFunctionForPlugin("AudioChannel::get_Volume", (void *)AudioChannel_GetVolume); + ccAddExternalFunctionForPlugin("AudioChannel::set_Volume", (void *)AudioChannel_SetVolume); } diff --git a/engines/ags/engine/ac/audiochannel.h b/engines/ags/engine/ac/audiochannel.h index e3f4a82853d8..d130cb8a13fd 100644 --- a/engines/ags/engine/ac/audiochannel.h +++ b/engines/ags/engine/ac/audiochannel.h @@ -30,7 +30,7 @@ int AudioChannel_GetID(ScriptAudioChannel *channel); int AudioChannel_GetIsPlaying(ScriptAudioChannel *channel); int AudioChannel_GetPanning(ScriptAudioChannel *channel); void AudioChannel_SetPanning(ScriptAudioChannel *channel, int newPanning); -ScriptAudioClip* AudioChannel_GetPlayingClip(ScriptAudioChannel *channel); +ScriptAudioClip *AudioChannel_GetPlayingClip(ScriptAudioChannel *channel); int AudioChannel_GetPosition(ScriptAudioChannel *channel); int AudioChannel_GetPositionMs(ScriptAudioChannel *channel); int AudioChannel_GetLengthMs(ScriptAudioChannel *channel); diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp index 2a02f1fd95f4..2653c3aa26f2 100644 --- a/engines/ags/engine/ac/audioclip.cpp +++ b/engines/ags/engine/ac/audioclip.cpp @@ -32,54 +32,44 @@ extern GameSetupStruct game; extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; extern CCAudioChannel ccDynamicAudio; -int AudioClip_GetID(ScriptAudioClip *clip) -{ - return clip->id; +int AudioClip_GetID(ScriptAudioClip *clip) { + return clip->id; } -int AudioClip_GetFileType(ScriptAudioClip *clip) -{ - return clip->fileType; +int AudioClip_GetFileType(ScriptAudioClip *clip) { + return clip->fileType; } -int AudioClip_GetType(ScriptAudioClip *clip) -{ - return clip->type; +int AudioClip_GetType(ScriptAudioClip *clip) { + return clip->type; } -int AudioClip_GetIsAvailable(ScriptAudioClip *clip) -{ - return DoesAssetExistInLib(get_audio_clip_assetpath(clip->bundlingType, clip->fileName)) ? 1 : 0; +int AudioClip_GetIsAvailable(ScriptAudioClip *clip) { + return DoesAssetExistInLib(get_audio_clip_assetpath(clip->bundlingType, clip->fileName)) ? 1 : 0; } -void AudioClip_Stop(ScriptAudioClip *clip) -{ - AudioChannelsLock lock; - for (int i = 0; i < MAX_SOUND_CHANNELS; i++) - { - auto* ch = lock.GetChannelIfPlaying(i); - if ((ch != nullptr) && (ch->sourceClip == clip)) - { - AudioChannel_Stop(&scrAudioChannel[i]); - } - } +void AudioClip_Stop(ScriptAudioClip *clip) { + AudioChannelsLock lock; + for (int i = 0; i < MAX_SOUND_CHANNELS; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if ((ch != nullptr) && (ch->sourceClip == clip)) { + AudioChannel_Stop(&scrAudioChannel[i]); + } + } } -ScriptAudioChannel* AudioClip_Play(ScriptAudioClip *clip, int priority, int repeat) -{ - ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, 0, false); - return sc_ch; +ScriptAudioChannel *AudioClip_Play(ScriptAudioClip *clip, int priority, int repeat) { + ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, 0, false); + return sc_ch; } -ScriptAudioChannel* AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat) -{ - ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, position, false); - return sc_ch; +ScriptAudioChannel *AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat) { + ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, position, false); + return sc_ch; } -ScriptAudioChannel* AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat) -{ - ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, 0, true); - return sc_ch; +ScriptAudioChannel *AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat) { + ScriptAudioChannel *sc_ch = play_audio_clip(clip, priority, repeat, 0, true); + return sc_ch; } //============================================================================= @@ -92,71 +82,62 @@ ScriptAudioChannel* AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, in #include "script/script_api.h" #include "script/script_runtime.h" -RuntimeScriptValue Sc_AudioClip_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetID); +RuntimeScriptValue Sc_AudioClip_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetID); } // int | ScriptAudioClip *clip -RuntimeScriptValue Sc_AudioClip_GetFileType(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetFileType); +RuntimeScriptValue Sc_AudioClip_GetFileType(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetFileType); } // int | ScriptAudioClip *clip -RuntimeScriptValue Sc_AudioClip_GetType(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetType); +RuntimeScriptValue Sc_AudioClip_GetType(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetType); } // int | ScriptAudioClip *clip -RuntimeScriptValue Sc_AudioClip_GetIsAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetIsAvailable); +RuntimeScriptValue Sc_AudioClip_GetIsAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetIsAvailable); } // void | ScriptAudioClip *clip -RuntimeScriptValue Sc_AudioClip_Stop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptAudioClip, AudioClip_Stop); +RuntimeScriptValue Sc_AudioClip_Stop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptAudioClip, AudioClip_Stop); } // ScriptAudioChannel* | ScriptAudioClip *clip, int priority, int repeat -RuntimeScriptValue Sc_AudioClip_Play(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_Play); +RuntimeScriptValue Sc_AudioClip_Play(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_Play); } // ScriptAudioChannel* | ScriptAudioClip *clip, int position, int priority, int repeat -RuntimeScriptValue Sc_AudioClip_PlayFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT3(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayFrom); +RuntimeScriptValue Sc_AudioClip_PlayFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT3(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayFrom); } // ScriptAudioChannel* | ScriptAudioClip *clip, int priority, int repeat -RuntimeScriptValue Sc_AudioClip_PlayQueued(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayQueued); -} - -void RegisterAudioClipAPI() -{ - ccAddExternalObjectFunction("AudioClip::Play^2", Sc_AudioClip_Play); - ccAddExternalObjectFunction("AudioClip::PlayFrom^3", Sc_AudioClip_PlayFrom); - ccAddExternalObjectFunction("AudioClip::PlayQueued^2", Sc_AudioClip_PlayQueued); - ccAddExternalObjectFunction("AudioClip::Stop^0", Sc_AudioClip_Stop); - ccAddExternalObjectFunction("AudioClip::get_ID", Sc_AudioClip_GetID); - ccAddExternalObjectFunction("AudioClip::get_FileType", Sc_AudioClip_GetFileType); - ccAddExternalObjectFunction("AudioClip::get_IsAvailable", Sc_AudioClip_GetIsAvailable); - ccAddExternalObjectFunction("AudioClip::get_Type", Sc_AudioClip_GetType); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("AudioClip::Play^2", (void*)AudioClip_Play); - ccAddExternalFunctionForPlugin("AudioClip::PlayFrom^3", (void*)AudioClip_PlayFrom); - ccAddExternalFunctionForPlugin("AudioClip::PlayQueued^2", (void*)AudioClip_PlayQueued); - ccAddExternalFunctionForPlugin("AudioClip::Stop^0", (void*)AudioClip_Stop); - ccAddExternalFunctionForPlugin("AudioClip::get_FileType", (void*)AudioClip_GetFileType); - ccAddExternalFunctionForPlugin("AudioClip::get_IsAvailable", (void*)AudioClip_GetIsAvailable); - ccAddExternalFunctionForPlugin("AudioClip::get_Type", (void*)AudioClip_GetType); +RuntimeScriptValue Sc_AudioClip_PlayQueued(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayQueued); +} + +void RegisterAudioClipAPI() { + ccAddExternalObjectFunction("AudioClip::Play^2", Sc_AudioClip_Play); + ccAddExternalObjectFunction("AudioClip::PlayFrom^3", Sc_AudioClip_PlayFrom); + ccAddExternalObjectFunction("AudioClip::PlayQueued^2", Sc_AudioClip_PlayQueued); + ccAddExternalObjectFunction("AudioClip::Stop^0", Sc_AudioClip_Stop); + ccAddExternalObjectFunction("AudioClip::get_ID", Sc_AudioClip_GetID); + ccAddExternalObjectFunction("AudioClip::get_FileType", Sc_AudioClip_GetFileType); + ccAddExternalObjectFunction("AudioClip::get_IsAvailable", Sc_AudioClip_GetIsAvailable); + ccAddExternalObjectFunction("AudioClip::get_Type", Sc_AudioClip_GetType); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("AudioClip::Play^2", (void *)AudioClip_Play); + ccAddExternalFunctionForPlugin("AudioClip::PlayFrom^3", (void *)AudioClip_PlayFrom); + ccAddExternalFunctionForPlugin("AudioClip::PlayQueued^2", (void *)AudioClip_PlayQueued); + ccAddExternalFunctionForPlugin("AudioClip::Stop^0", (void *)AudioClip_Stop); + ccAddExternalFunctionForPlugin("AudioClip::get_FileType", (void *)AudioClip_GetFileType); + ccAddExternalFunctionForPlugin("AudioClip::get_IsAvailable", (void *)AudioClip_GetIsAvailable); + ccAddExternalFunctionForPlugin("AudioClip::get_Type", (void *)AudioClip_GetType); } diff --git a/engines/ags/engine/ac/audioclip.h b/engines/ags/engine/ac/audioclip.h index 7c66b2e0577b..8cd7514045e6 100644 --- a/engines/ags/engine/ac/audioclip.h +++ b/engines/ags/engine/ac/audioclip.h @@ -30,8 +30,8 @@ int AudioClip_GetFileType(ScriptAudioClip *clip); int AudioClip_GetType(ScriptAudioClip *clip); int AudioClip_GetIsAvailable(ScriptAudioClip *clip); void AudioClip_Stop(ScriptAudioClip *clip); -ScriptAudioChannel* AudioClip_Play(ScriptAudioClip *clip, int priority, int repeat); -ScriptAudioChannel* AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat); -ScriptAudioChannel* AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat); +ScriptAudioChannel *AudioClip_Play(ScriptAudioClip *clip, int priority, int repeat); +ScriptAudioChannel *AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat); +ScriptAudioChannel *AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat); #endif diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp index f235292a3a53..bf61dd5834e3 100644 --- a/engines/ags/engine/ac/button.cpp +++ b/engines/ags/engine/ac/button.cpp @@ -35,7 +35,7 @@ using namespace AGS::Common; extern GameSetupStruct game; -extern ViewStruct*views; +extern ViewStruct *views; // *** BUTTON FUNCTIONS @@ -43,152 +43,150 @@ AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; int numAnimButs; void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat) { - int guin = butt->ParentId; - int objn = butt->Id; + int guin = butt->ParentId; + int objn = butt->Id; - if ((view < 1) || (view > game.numviews)) - quit("!AnimateButton: invalid view specified"); - view--; + if ((view < 1) || (view > game.numviews)) + quit("!AnimateButton: invalid view specified"); + view--; - if ((loop < 0) || (loop >= views[view].numLoops)) - quit("!AnimateButton: invalid loop specified for view"); + if ((loop < 0) || (loop >= views[view].numLoops)) + quit("!AnimateButton: invalid loop specified for view"); - // if it's already animating, stop it - FindAndRemoveButtonAnimation(guin, objn); + // if it's already animating, stop it + FindAndRemoveButtonAnimation(guin, objn); - if (numAnimButs >= MAX_ANIMATING_BUTTONS) - quit("!AnimateButton: too many animating GUI buttons at once"); + if (numAnimButs >= MAX_ANIMATING_BUTTONS) + quit("!AnimateButton: too many animating GUI buttons at once"); - int buttonId = guis[guin].GetControlID(objn); + int buttonId = guis[guin].GetControlID(objn); - guibuts[buttonId].PushedImage = 0; - guibuts[buttonId].MouseOverImage = 0; + guibuts[buttonId].PushedImage = 0; + guibuts[buttonId].MouseOverImage = 0; - animbuts[numAnimButs].ongui = guin; - animbuts[numAnimButs].onguibut = objn; - animbuts[numAnimButs].buttonid = buttonId; - animbuts[numAnimButs].view = view; - animbuts[numAnimButs].loop = loop; - animbuts[numAnimButs].speed = speed; - animbuts[numAnimButs].repeat = repeat; - animbuts[numAnimButs].frame = -1; - animbuts[numAnimButs].wait = 0; - numAnimButs++; - // launch into the first frame - if (UpdateAnimatingButton(numAnimButs - 1)) - { - debug_script_warn("AnimateButton: no frames to animate"); - StopButtonAnimation(numAnimButs - 1); - } + animbuts[numAnimButs].ongui = guin; + animbuts[numAnimButs].onguibut = objn; + animbuts[numAnimButs].buttonid = buttonId; + animbuts[numAnimButs].view = view; + animbuts[numAnimButs].loop = loop; + animbuts[numAnimButs].speed = speed; + animbuts[numAnimButs].repeat = repeat; + animbuts[numAnimButs].frame = -1; + animbuts[numAnimButs].wait = 0; + numAnimButs++; + // launch into the first frame + if (UpdateAnimatingButton(numAnimButs - 1)) { + debug_script_warn("AnimateButton: no frames to animate"); + StopButtonAnimation(numAnimButs - 1); + } } -const char* Button_GetText_New(GUIButton *butt) { - return CreateNewScriptString(butt->GetText()); +const char *Button_GetText_New(GUIButton *butt) { + return CreateNewScriptString(butt->GetText()); } void Button_GetText(GUIButton *butt, char *buffer) { - strcpy(buffer, butt->GetText()); + strcpy(buffer, butt->GetText()); } void Button_SetText(GUIButton *butt, const char *newtx) { - newtx = get_translation(newtx); + newtx = get_translation(newtx); - if (strcmp(butt->GetText(), newtx)) { - guis_need_update = 1; - butt->SetText(newtx); - } + if (strcmp(butt->GetText(), newtx)) { + guis_need_update = 1; + butt->SetText(newtx); + } } void Button_SetFont(GUIButton *butt, int newFont) { - if ((newFont < 0) || (newFont >= game.numfonts)) - quit("!Button.Font: invalid font number."); + if ((newFont < 0) || (newFont >= game.numfonts)) + quit("!Button.Font: invalid font number."); - if (butt->Font != newFont) { - butt->Font = newFont; - guis_need_update = 1; - } + if (butt->Font != newFont) { + butt->Font = newFont; + guis_need_update = 1; + } } int Button_GetFont(GUIButton *butt) { - return butt->Font; + return butt->Font; } int Button_GetClipImage(GUIButton *butt) { - return butt->IsClippingImage() ? 1 : 0; + return butt->IsClippingImage() ? 1 : 0; } void Button_SetClipImage(GUIButton *butt, int newval) { - if (butt->IsClippingImage() != (newval != 0)) - { - butt->SetClipImage(newval != 0); - guis_need_update = 1; - } + if (butt->IsClippingImage() != (newval != 0)) { + butt->SetClipImage(newval != 0); + guis_need_update = 1; + } } int Button_GetGraphic(GUIButton *butt) { - // return currently displayed pic - if (butt->CurrentImage < 0) - return butt->Image; - return butt->CurrentImage; + // return currently displayed pic + if (butt->CurrentImage < 0) + return butt->Image; + return butt->CurrentImage; } int Button_GetMouseOverGraphic(GUIButton *butt) { - return butt->MouseOverImage; + return butt->MouseOverImage; } void Button_SetMouseOverGraphic(GUIButton *guil, int slotn) { - debug_script_log("GUI %d Button %d mouseover set to slot %d", guil->ParentId, guil->Id, slotn); + debug_script_log("GUI %d Button %d mouseover set to slot %d", guil->ParentId, guil->Id, slotn); - if ((guil->IsMouseOver != 0) && (guil->IsPushed == 0)) - guil->CurrentImage = slotn; - guil->MouseOverImage = slotn; + if ((guil->IsMouseOver != 0) && (guil->IsPushed == 0)) + guil->CurrentImage = slotn; + guil->MouseOverImage = slotn; - guis_need_update = 1; - FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); + guis_need_update = 1; + FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); } int Button_GetNormalGraphic(GUIButton *butt) { - return butt->Image; + return butt->Image; } void Button_SetNormalGraphic(GUIButton *guil, int slotn) { - debug_script_log("GUI %d Button %d normal set to slot %d", guil->ParentId, guil->Id, slotn); - // normal pic - update if mouse is not over, or if there's no MouseOverImage - if (((guil->IsMouseOver == 0) || (guil->MouseOverImage < 1)) && (guil->IsPushed == 0)) - guil->CurrentImage = slotn; - guil->Image = slotn; - // update the clickable area to the same size as the graphic - guil->Width = game.SpriteInfos[slotn].Width; - guil->Height = game.SpriteInfos[slotn].Height; + debug_script_log("GUI %d Button %d normal set to slot %d", guil->ParentId, guil->Id, slotn); + // normal pic - update if mouse is not over, or if there's no MouseOverImage + if (((guil->IsMouseOver == 0) || (guil->MouseOverImage < 1)) && (guil->IsPushed == 0)) + guil->CurrentImage = slotn; + guil->Image = slotn; + // update the clickable area to the same size as the graphic + guil->Width = game.SpriteInfos[slotn].Width; + guil->Height = game.SpriteInfos[slotn].Height; - guis_need_update = 1; - FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); + guis_need_update = 1; + FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); } int Button_GetPushedGraphic(GUIButton *butt) { - return butt->PushedImage; + return butt->PushedImage; } void Button_SetPushedGraphic(GUIButton *guil, int slotn) { - debug_script_log("GUI %d Button %d pushed set to slot %d", guil->ParentId, guil->Id, slotn); + debug_script_log("GUI %d Button %d pushed set to slot %d", guil->ParentId, guil->Id, slotn); - if (guil->IsPushed) - guil->CurrentImage = slotn; - guil->PushedImage = slotn; + if (guil->IsPushed) + guil->CurrentImage = slotn; + guil->PushedImage = slotn; - guis_need_update = 1; - FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); + guis_need_update = 1; + FindAndRemoveButtonAnimation(guil->ParentId, guil->Id); } int Button_GetTextColor(GUIButton *butt) { - return butt->TextColor; + return butt->TextColor; } void Button_SetTextColor(GUIButton *butt, int newcol) { - if (butt->TextColor != newcol) { - butt->TextColor = newcol; - guis_need_update = 1; - } + if (butt->TextColor != newcol) { + butt->TextColor = newcol; + guis_need_update = 1; + } } extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; @@ -198,114 +196,101 @@ extern int numAnimButs; // returns 1 if animation finished int UpdateAnimatingButton(int bu) { - if (animbuts[bu].wait > 0) { - animbuts[bu].wait--; - return 0; - } - ViewStruct *tview = &views[animbuts[bu].view]; - - animbuts[bu].frame++; - - if (animbuts[bu].frame >= tview->loops[animbuts[bu].loop].numFrames) - { - if (tview->loops[animbuts[bu].loop].RunNextLoop()) { - // go to next loop - animbuts[bu].loop++; - animbuts[bu].frame = 0; - } - else if (animbuts[bu].repeat) { - animbuts[bu].frame = 0; - // multi-loop anim, go back - while ((animbuts[bu].loop > 0) && - (tview->loops[animbuts[bu].loop - 1].RunNextLoop())) - animbuts[bu].loop--; - } - else - return 1; - } - - CheckViewFrame(animbuts[bu].view, animbuts[bu].loop, animbuts[bu].frame); - - // update the button's image - guibuts[animbuts[bu].buttonid].Image = tview->loops[animbuts[bu].loop].frames[animbuts[bu].frame].pic; - guibuts[animbuts[bu].buttonid].CurrentImage = guibuts[animbuts[bu].buttonid].Image; - guibuts[animbuts[bu].buttonid].PushedImage = 0; - guibuts[animbuts[bu].buttonid].MouseOverImage = 0; - guis_need_update = 1; - - animbuts[bu].wait = animbuts[bu].speed + tview->loops[animbuts[bu].loop].frames[animbuts[bu].frame].speed; - return 0; + if (animbuts[bu].wait > 0) { + animbuts[bu].wait--; + return 0; + } + ViewStruct *tview = &views[animbuts[bu].view]; + + animbuts[bu].frame++; + + if (animbuts[bu].frame >= tview->loops[animbuts[bu].loop].numFrames) { + if (tview->loops[animbuts[bu].loop].RunNextLoop()) { + // go to next loop + animbuts[bu].loop++; + animbuts[bu].frame = 0; + } else if (animbuts[bu].repeat) { + animbuts[bu].frame = 0; + // multi-loop anim, go back + while ((animbuts[bu].loop > 0) && + (tview->loops[animbuts[bu].loop - 1].RunNextLoop())) + animbuts[bu].loop--; + } else + return 1; + } + + CheckViewFrame(animbuts[bu].view, animbuts[bu].loop, animbuts[bu].frame); + + // update the button's image + guibuts[animbuts[bu].buttonid].Image = tview->loops[animbuts[bu].loop].frames[animbuts[bu].frame].pic; + guibuts[animbuts[bu].buttonid].CurrentImage = guibuts[animbuts[bu].buttonid].Image; + guibuts[animbuts[bu].buttonid].PushedImage = 0; + guibuts[animbuts[bu].buttonid].MouseOverImage = 0; + guis_need_update = 1; + + animbuts[bu].wait = animbuts[bu].speed + tview->loops[animbuts[bu].loop].frames[animbuts[bu].frame].speed; + return 0; } void StopButtonAnimation(int idxn) { - numAnimButs--; - for (int aa = idxn; aa < numAnimButs; aa++) { - animbuts[aa] = animbuts[aa + 1]; - } + numAnimButs--; + for (int aa = idxn; aa < numAnimButs; aa++) { + animbuts[aa] = animbuts[aa + 1]; + } } // Returns the index of the AnimatingGUIButton object corresponding to the // given button ID; returns -1 if no such animation exists -int FindAnimatedButton(int guin, int objn) -{ - for (int i = 0; i < numAnimButs; ++i) - { - if (animbuts[i].ongui == guin && animbuts[i].onguibut == objn) - return i; - } - return -1; -} - -void FindAndRemoveButtonAnimation(int guin, int objn) -{ - int idx = FindAnimatedButton(guin, objn); - if (idx >= 0) - StopButtonAnimation(idx); +int FindAnimatedButton(int guin, int objn) { + for (int i = 0; i < numAnimButs; ++i) { + if (animbuts[i].ongui == guin && animbuts[i].onguibut == objn) + return i; + } + return -1; +} + +void FindAndRemoveButtonAnimation(int guin, int objn) { + int idx = FindAnimatedButton(guin, objn); + if (idx >= 0) + StopButtonAnimation(idx); } // ** end animating buttons code -void Button_Click(GUIButton *butt, int mbut) -{ - process_interface_click(butt->ParentId, butt->Id, mbut); +void Button_Click(GUIButton *butt, int mbut) { + process_interface_click(butt->ParentId, butt->Id, mbut); } -bool Button_IsAnimating(GUIButton *butt) -{ - return FindAnimatedButton(butt->ParentId, butt->Id) >= 0; +bool Button_IsAnimating(GUIButton *butt) { + return FindAnimatedButton(butt->ParentId, butt->Id) >= 0; } // NOTE: in correspondance to similar functions for Character & Object, // GetView returns (view index + 1), while GetLoop and GetFrame return // zero-based index and 0 in case of no animation. -int Button_GetAnimView(GUIButton *butt) -{ - int idx = FindAnimatedButton(butt->ParentId, butt->Id); - return idx >= 0 ? animbuts[idx].view + 1 : 0; +int Button_GetAnimView(GUIButton *butt) { + int idx = FindAnimatedButton(butt->ParentId, butt->Id); + return idx >= 0 ? animbuts[idx].view + 1 : 0; } -int Button_GetAnimLoop(GUIButton *butt) -{ - int idx = FindAnimatedButton(butt->ParentId, butt->Id); - return idx >= 0 ? animbuts[idx].loop : 0; +int Button_GetAnimLoop(GUIButton *butt) { + int idx = FindAnimatedButton(butt->ParentId, butt->Id); + return idx >= 0 ? animbuts[idx].loop : 0; } -int Button_GetAnimFrame(GUIButton *butt) -{ - int idx = FindAnimatedButton(butt->ParentId, butt->Id); - return idx >= 0 ? animbuts[idx].frame : 0; +int Button_GetAnimFrame(GUIButton *butt) { + int idx = FindAnimatedButton(butt->ParentId, butt->Id); + return idx >= 0 ? animbuts[idx].frame : 0; } -int Button_GetTextAlignment(GUIButton *butt) -{ - return butt->TextAlignment; +int Button_GetTextAlignment(GUIButton *butt) { + return butt->TextAlignment; } -void Button_SetTextAlignment(GUIButton *butt, int align) -{ - if (butt->TextAlignment != align) { - butt->TextAlignment = (FrameAlignment)align; - guis_need_update = 1; - } +void Button_SetTextAlignment(GUIButton *butt, int align) { + if (butt->TextAlignment != align) { + butt->TextAlignment = (FrameAlignment)align; + guis_need_update = 1; + } } //============================================================================= @@ -322,188 +307,163 @@ void Button_SetTextAlignment(GUIButton *butt, int align) extern ScriptString myScriptStringImpl; // void | GUIButton *butt, int view, int loop, int speed, int repeat -RuntimeScriptValue Sc_Button_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(GUIButton, Button_Animate); +RuntimeScriptValue Sc_Button_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(GUIButton, Button_Animate); } // const char* | GUIButton *butt -RuntimeScriptValue Sc_Button_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIButton, const char, myScriptStringImpl, Button_GetText_New); +RuntimeScriptValue Sc_Button_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIButton, const char, myScriptStringImpl, Button_GetText_New); } // void | GUIButton *butt, char *buffer -RuntimeScriptValue Sc_Button_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUIButton, Button_GetText, char); +RuntimeScriptValue Sc_Button_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUIButton, Button_GetText, char); } // void | GUIButton *butt, const char *newtx -RuntimeScriptValue Sc_Button_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUIButton, Button_SetText, const char); +RuntimeScriptValue Sc_Button_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUIButton, Button_SetText, const char); } // void | GUIButton *butt, int newFont -RuntimeScriptValue Sc_Button_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_SetFont); +RuntimeScriptValue Sc_Button_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_SetFont); } // int | GUIButton *butt -RuntimeScriptValue Sc_Button_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetFont); +RuntimeScriptValue Sc_Button_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetFont); } // int | GUIButton *butt -RuntimeScriptValue Sc_Button_GetClipImage(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetClipImage); +RuntimeScriptValue Sc_Button_GetClipImage(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetClipImage); } // void | GUIButton *butt, int newval -RuntimeScriptValue Sc_Button_SetClipImage(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_SetClipImage); +RuntimeScriptValue Sc_Button_SetClipImage(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_SetClipImage); } // int | GUIButton *butt -RuntimeScriptValue Sc_Button_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetGraphic); +RuntimeScriptValue Sc_Button_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetGraphic); } // int | GUIButton *butt -RuntimeScriptValue Sc_Button_GetMouseOverGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetMouseOverGraphic); +RuntimeScriptValue Sc_Button_GetMouseOverGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetMouseOverGraphic); } // void | GUIButton *guil, int slotn -RuntimeScriptValue Sc_Button_SetMouseOverGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_SetMouseOverGraphic); +RuntimeScriptValue Sc_Button_SetMouseOverGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_SetMouseOverGraphic); } // int | GUIButton *butt -RuntimeScriptValue Sc_Button_GetNormalGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetNormalGraphic); +RuntimeScriptValue Sc_Button_GetNormalGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetNormalGraphic); } // void | GUIButton *guil, int slotn -RuntimeScriptValue Sc_Button_SetNormalGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_SetNormalGraphic); +RuntimeScriptValue Sc_Button_SetNormalGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_SetNormalGraphic); } // int | GUIButton *butt -RuntimeScriptValue Sc_Button_GetPushedGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetPushedGraphic); +RuntimeScriptValue Sc_Button_GetPushedGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetPushedGraphic); } // void | GUIButton *guil, int slotn -RuntimeScriptValue Sc_Button_SetPushedGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_SetPushedGraphic); +RuntimeScriptValue Sc_Button_SetPushedGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_SetPushedGraphic); } // int | GUIButton *butt -RuntimeScriptValue Sc_Button_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetTextColor); +RuntimeScriptValue Sc_Button_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetTextColor); } // void | GUIButton *butt, int newcol -RuntimeScriptValue Sc_Button_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_SetTextColor); -} - -RuntimeScriptValue Sc_Button_Click(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_Click); -} - -RuntimeScriptValue Sc_Button_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(GUIButton, Button_IsAnimating); -} - -RuntimeScriptValue Sc_Button_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetTextAlignment); -} - -RuntimeScriptValue Sc_Button_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIButton, Button_SetTextAlignment); -} - -RuntimeScriptValue Sc_Button_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetAnimFrame); -} - -RuntimeScriptValue Sc_Button_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetAnimLoop); -} - -RuntimeScriptValue Sc_Button_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIButton, Button_GetAnimView); -} - -void RegisterButtonAPI() -{ - ccAddExternalObjectFunction("Button::Animate^4", Sc_Button_Animate); - ccAddExternalObjectFunction("Button::Click^1", Sc_Button_Click); - ccAddExternalObjectFunction("Button::GetText^1", Sc_Button_GetText); - ccAddExternalObjectFunction("Button::SetText^1", Sc_Button_SetText); - ccAddExternalObjectFunction("Button::get_TextAlignment", Sc_Button_GetTextAlignment); - ccAddExternalObjectFunction("Button::set_TextAlignment", Sc_Button_SetTextAlignment); - ccAddExternalObjectFunction("Button::get_Animating", Sc_Button_GetAnimating); - ccAddExternalObjectFunction("Button::get_ClipImage", Sc_Button_GetClipImage); - ccAddExternalObjectFunction("Button::set_ClipImage", Sc_Button_SetClipImage); - ccAddExternalObjectFunction("Button::get_Font", Sc_Button_GetFont); - ccAddExternalObjectFunction("Button::set_Font", Sc_Button_SetFont); - ccAddExternalObjectFunction("Button::get_Frame", Sc_Button_GetFrame); - ccAddExternalObjectFunction("Button::get_Graphic", Sc_Button_GetGraphic); - ccAddExternalObjectFunction("Button::get_Loop", Sc_Button_GetLoop); - ccAddExternalObjectFunction("Button::get_MouseOverGraphic", Sc_Button_GetMouseOverGraphic); - ccAddExternalObjectFunction("Button::set_MouseOverGraphic", Sc_Button_SetMouseOverGraphic); - ccAddExternalObjectFunction("Button::get_NormalGraphic", Sc_Button_GetNormalGraphic); - ccAddExternalObjectFunction("Button::set_NormalGraphic", Sc_Button_SetNormalGraphic); - ccAddExternalObjectFunction("Button::get_PushedGraphic", Sc_Button_GetPushedGraphic); - ccAddExternalObjectFunction("Button::set_PushedGraphic", Sc_Button_SetPushedGraphic); - ccAddExternalObjectFunction("Button::get_Text", Sc_Button_GetText_New); - ccAddExternalObjectFunction("Button::set_Text", Sc_Button_SetText); - ccAddExternalObjectFunction("Button::get_TextColor", Sc_Button_GetTextColor); - ccAddExternalObjectFunction("Button::set_TextColor", Sc_Button_SetTextColor); - ccAddExternalObjectFunction("Button::get_View", Sc_Button_GetView); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Button::Animate^4", (void*)Button_Animate); - ccAddExternalFunctionForPlugin("Button::GetText^1", (void*)Button_GetText); - ccAddExternalFunctionForPlugin("Button::SetText^1", (void*)Button_SetText); - ccAddExternalFunctionForPlugin("Button::get_ClipImage", (void*)Button_GetClipImage); - ccAddExternalFunctionForPlugin("Button::set_ClipImage", (void*)Button_SetClipImage); - ccAddExternalFunctionForPlugin("Button::get_Font", (void*)Button_GetFont); - ccAddExternalFunctionForPlugin("Button::set_Font", (void*)Button_SetFont); - ccAddExternalFunctionForPlugin("Button::get_Graphic", (void*)Button_GetGraphic); - ccAddExternalFunctionForPlugin("Button::get_MouseOverGraphic", (void*)Button_GetMouseOverGraphic); - ccAddExternalFunctionForPlugin("Button::set_MouseOverGraphic", (void*)Button_SetMouseOverGraphic); - ccAddExternalFunctionForPlugin("Button::get_NormalGraphic", (void*)Button_GetNormalGraphic); - ccAddExternalFunctionForPlugin("Button::set_NormalGraphic", (void*)Button_SetNormalGraphic); - ccAddExternalFunctionForPlugin("Button::get_PushedGraphic", (void*)Button_GetPushedGraphic); - ccAddExternalFunctionForPlugin("Button::set_PushedGraphic", (void*)Button_SetPushedGraphic); - ccAddExternalFunctionForPlugin("Button::get_Text", (void*)Button_GetText_New); - ccAddExternalFunctionForPlugin("Button::set_Text", (void*)Button_SetText); - ccAddExternalFunctionForPlugin("Button::get_TextColor", (void*)Button_GetTextColor); - ccAddExternalFunctionForPlugin("Button::set_TextColor", (void*)Button_SetTextColor); +RuntimeScriptValue Sc_Button_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_SetTextColor); +} + +RuntimeScriptValue Sc_Button_Click(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_Click); +} + +RuntimeScriptValue Sc_Button_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(GUIButton, Button_IsAnimating); +} + +RuntimeScriptValue Sc_Button_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetTextAlignment); +} + +RuntimeScriptValue Sc_Button_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIButton, Button_SetTextAlignment); +} + +RuntimeScriptValue Sc_Button_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetAnimFrame); +} + +RuntimeScriptValue Sc_Button_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetAnimLoop); +} + +RuntimeScriptValue Sc_Button_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIButton, Button_GetAnimView); +} + +void RegisterButtonAPI() { + ccAddExternalObjectFunction("Button::Animate^4", Sc_Button_Animate); + ccAddExternalObjectFunction("Button::Click^1", Sc_Button_Click); + ccAddExternalObjectFunction("Button::GetText^1", Sc_Button_GetText); + ccAddExternalObjectFunction("Button::SetText^1", Sc_Button_SetText); + ccAddExternalObjectFunction("Button::get_TextAlignment", Sc_Button_GetTextAlignment); + ccAddExternalObjectFunction("Button::set_TextAlignment", Sc_Button_SetTextAlignment); + ccAddExternalObjectFunction("Button::get_Animating", Sc_Button_GetAnimating); + ccAddExternalObjectFunction("Button::get_ClipImage", Sc_Button_GetClipImage); + ccAddExternalObjectFunction("Button::set_ClipImage", Sc_Button_SetClipImage); + ccAddExternalObjectFunction("Button::get_Font", Sc_Button_GetFont); + ccAddExternalObjectFunction("Button::set_Font", Sc_Button_SetFont); + ccAddExternalObjectFunction("Button::get_Frame", Sc_Button_GetFrame); + ccAddExternalObjectFunction("Button::get_Graphic", Sc_Button_GetGraphic); + ccAddExternalObjectFunction("Button::get_Loop", Sc_Button_GetLoop); + ccAddExternalObjectFunction("Button::get_MouseOverGraphic", Sc_Button_GetMouseOverGraphic); + ccAddExternalObjectFunction("Button::set_MouseOverGraphic", Sc_Button_SetMouseOverGraphic); + ccAddExternalObjectFunction("Button::get_NormalGraphic", Sc_Button_GetNormalGraphic); + ccAddExternalObjectFunction("Button::set_NormalGraphic", Sc_Button_SetNormalGraphic); + ccAddExternalObjectFunction("Button::get_PushedGraphic", Sc_Button_GetPushedGraphic); + ccAddExternalObjectFunction("Button::set_PushedGraphic", Sc_Button_SetPushedGraphic); + ccAddExternalObjectFunction("Button::get_Text", Sc_Button_GetText_New); + ccAddExternalObjectFunction("Button::set_Text", Sc_Button_SetText); + ccAddExternalObjectFunction("Button::get_TextColor", Sc_Button_GetTextColor); + ccAddExternalObjectFunction("Button::set_TextColor", Sc_Button_SetTextColor); + ccAddExternalObjectFunction("Button::get_View", Sc_Button_GetView); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Button::Animate^4", (void *)Button_Animate); + ccAddExternalFunctionForPlugin("Button::GetText^1", (void *)Button_GetText); + ccAddExternalFunctionForPlugin("Button::SetText^1", (void *)Button_SetText); + ccAddExternalFunctionForPlugin("Button::get_ClipImage", (void *)Button_GetClipImage); + ccAddExternalFunctionForPlugin("Button::set_ClipImage", (void *)Button_SetClipImage); + ccAddExternalFunctionForPlugin("Button::get_Font", (void *)Button_GetFont); + ccAddExternalFunctionForPlugin("Button::set_Font", (void *)Button_SetFont); + ccAddExternalFunctionForPlugin("Button::get_Graphic", (void *)Button_GetGraphic); + ccAddExternalFunctionForPlugin("Button::get_MouseOverGraphic", (void *)Button_GetMouseOverGraphic); + ccAddExternalFunctionForPlugin("Button::set_MouseOverGraphic", (void *)Button_SetMouseOverGraphic); + ccAddExternalFunctionForPlugin("Button::get_NormalGraphic", (void *)Button_GetNormalGraphic); + ccAddExternalFunctionForPlugin("Button::set_NormalGraphic", (void *)Button_SetNormalGraphic); + ccAddExternalFunctionForPlugin("Button::get_PushedGraphic", (void *)Button_GetPushedGraphic); + ccAddExternalFunctionForPlugin("Button::set_PushedGraphic", (void *)Button_SetPushedGraphic); + ccAddExternalFunctionForPlugin("Button::get_Text", (void *)Button_GetText_New); + ccAddExternalFunctionForPlugin("Button::set_Text", (void *)Button_SetText); + ccAddExternalFunctionForPlugin("Button::get_TextColor", (void *)Button_GetTextColor); + ccAddExternalFunctionForPlugin("Button::set_TextColor", (void *)Button_SetTextColor); } diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h index 47022d8ce1de..7f872fcd19ed 100644 --- a/engines/ags/engine/ac/button.h +++ b/engines/ags/engine/ac/button.h @@ -27,26 +27,26 @@ using AGS::Common::GUIButton; -void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat); -const char* Button_GetText_New(GUIButton *butt); -void Button_GetText(GUIButton *butt, char *buffer); -void Button_SetText(GUIButton *butt, const char *newtx); -void Button_SetFont(GUIButton *butt, int newFont); -int Button_GetFont(GUIButton *butt); -int Button_GetClipImage(GUIButton *butt); -void Button_SetClipImage(GUIButton *butt, int newval); -int Button_GetGraphic(GUIButton *butt); -int Button_GetMouseOverGraphic(GUIButton *butt); -void Button_SetMouseOverGraphic(GUIButton *guil, int slotn); -int Button_GetNormalGraphic(GUIButton *butt); -void Button_SetNormalGraphic(GUIButton *guil, int slotn); -int Button_GetPushedGraphic(GUIButton *butt); -void Button_SetPushedGraphic(GUIButton *guil, int slotn); -int Button_GetTextColor(GUIButton *butt); -void Button_SetTextColor(GUIButton *butt, int newcol); +void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat); +const char *Button_GetText_New(GUIButton *butt); +void Button_GetText(GUIButton *butt, char *buffer); +void Button_SetText(GUIButton *butt, const char *newtx); +void Button_SetFont(GUIButton *butt, int newFont); +int Button_GetFont(GUIButton *butt); +int Button_GetClipImage(GUIButton *butt); +void Button_SetClipImage(GUIButton *butt, int newval); +int Button_GetGraphic(GUIButton *butt); +int Button_GetMouseOverGraphic(GUIButton *butt); +void Button_SetMouseOverGraphic(GUIButton *guil, int slotn); +int Button_GetNormalGraphic(GUIButton *butt); +void Button_SetNormalGraphic(GUIButton *guil, int slotn); +int Button_GetPushedGraphic(GUIButton *butt); +void Button_SetPushedGraphic(GUIButton *guil, int slotn); +int Button_GetTextColor(GUIButton *butt); +void Button_SetTextColor(GUIButton *butt, int newcol); -int UpdateAnimatingButton(int bu); -void StopButtonAnimation(int idxn); -void FindAndRemoveButtonAnimation(int guin, int objn); +int UpdateAnimatingButton(int bu); +void StopButtonAnimation(int idxn); +void FindAndRemoveButtonAnimation(int guin, int objn); #endif diff --git a/engines/ags/engine/ac/cdaudio.cpp b/engines/ags/engine/ac/cdaudio.cpp index b8f3a1e5acc4..99294b49a2bf 100644 --- a/engines/ags/engine/ac/cdaudio.cpp +++ b/engines/ags/engine/ac/cdaudio.cpp @@ -23,25 +23,22 @@ #include "ac/cdaudio.h" #include "platform/base/agsplatformdriver.h" -int use_cdplayer=0; +int use_cdplayer = 0; bool triedToUseCdAudioCommand = false; -int need_to_stop_cd=0; +int need_to_stop_cd = 0; -int init_cd_player() -{ - use_cdplayer=0; - return platform->InitializeCDPlayer(); +int init_cd_player() { + use_cdplayer = 0; + return platform->InitializeCDPlayer(); } -int cd_manager(int cmdd,int datt) -{ - if (!triedToUseCdAudioCommand) - { - triedToUseCdAudioCommand = true; - init_cd_player(); - } - if (cmdd==0) return use_cdplayer; - if (use_cdplayer==0) return 0; // ignore other commands +int cd_manager(int cmdd, int datt) { + if (!triedToUseCdAudioCommand) { + triedToUseCdAudioCommand = true; + init_cd_player(); + } + if (cmdd == 0) return use_cdplayer; + if (use_cdplayer == 0) return 0; // ignore other commands - return platform->CDPlayerCommand(cmdd, datt); + return platform->CDPlayerCommand(cmdd, datt); } diff --git a/engines/ags/engine/ac/cdaudio.h b/engines/ags/engine/ac/cdaudio.h index 62852277ee22..d3598a390434 100644 --- a/engines/ags/engine/ac/cdaudio.h +++ b/engines/ags/engine/ac/cdaudio.h @@ -31,6 +31,6 @@ #define CDS_DRIVEEMPTY 0x0800 // no CD in drive int init_cd_player() ; -int cd_manager(int cmdd,int datt) ; +int cd_manager(int cmdd, int datt) ; #endif diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index 533810146964..347eb922d278 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -74,11 +74,11 @@ using namespace AGS::Common; extern GameSetupStruct game; -extern int displayed_room,starting_room; +extern int displayed_room, starting_room; extern RoomStruct thisroom; extern MoveList *mls; -extern ViewStruct*views; -extern RoomObject*objs; +extern ViewStruct *views; +extern RoomObject *objs; extern ScriptInvItem scrInv[MAX_INV]; extern SpriteCache spriteset; extern Bitmap *walkable_areas_temp; @@ -95,13 +95,13 @@ extern CCInventory ccDynamicInv; CharacterExtras *charextra; -CharacterInfo*playerchar; +CharacterInfo *playerchar; int32_t _sc_PlayerCharPtr = 0; int char_lowest_yp; // Sierra-style speech settings -int face_talking=-1,facetalkview=0,facetalkwait=0,facetalkframe=0; -int facetalkloop=0, facetalkrepeat = 0, facetalkAllowBlink = 1; +int face_talking = -1, facetalkview = 0, facetalkwait = 0, facetalkframe = 0; +int facetalkloop = 0, facetalkrepeat = 0, facetalkAllowBlink = 1; int facetalkBlinkLoop = 0; CharacterInfo *facetalkchar = nullptr; // Do override default portrait position during QFG4-style speech overlay update @@ -118,973 +118,921 @@ int numLipLines = 0, curLipLine = -1, curLipLinePhoneme = 0; // **** CHARACTER: FUNCTIONS **** void Character_AddInventory(CharacterInfo *chaa, ScriptInvItem *invi, int addIndex) { - int ee; - - if (invi == nullptr) - quit("!AddInventoryToCharacter: invalid invnetory number"); - - int inum = invi->id; - - if (chaa->inv[inum] >= 32000) - quit("!AddInventory: cannot carry more than 32000 of one inventory item"); - - chaa->inv[inum]++; - - int charid = chaa->index_id; - - if (game.options[OPT_DUPLICATEINV] == 0) { - // Ensure it is only in the list once - for (ee = 0; ee < charextra[charid].invorder_count; ee++) { - if (charextra[charid].invorder[ee] == inum) { - // They already have the item, so don't add it to the list - if (chaa == playerchar) - run_on_event (GE_ADD_INV, RuntimeScriptValue().SetInt32(inum)); - return; - } - } - } - if (charextra[charid].invorder_count >= MAX_INVORDER) - quit("!Too many inventory items added, max 500 display at one time"); - - if ((addIndex == SCR_NO_VALUE) || - (addIndex >= charextra[charid].invorder_count) || - (addIndex < 0)) { - // add new item at end of list - charextra[charid].invorder[charextra[charid].invorder_count] = inum; - } - else { - // insert new item at index - for (ee = charextra[charid].invorder_count - 1; ee >= addIndex; ee--) - charextra[charid].invorder[ee + 1] = charextra[charid].invorder[ee]; - - charextra[charid].invorder[addIndex] = inum; - } - charextra[charid].invorder_count++; - guis_need_update = 1; - if (chaa == playerchar) - run_on_event (GE_ADD_INV, RuntimeScriptValue().SetInt32(inum)); + int ee; + + if (invi == nullptr) + quit("!AddInventoryToCharacter: invalid invnetory number"); + + int inum = invi->id; + + if (chaa->inv[inum] >= 32000) + quit("!AddInventory: cannot carry more than 32000 of one inventory item"); + + chaa->inv[inum]++; + + int charid = chaa->index_id; + + if (game.options[OPT_DUPLICATEINV] == 0) { + // Ensure it is only in the list once + for (ee = 0; ee < charextra[charid].invorder_count; ee++) { + if (charextra[charid].invorder[ee] == inum) { + // They already have the item, so don't add it to the list + if (chaa == playerchar) + run_on_event(GE_ADD_INV, RuntimeScriptValue().SetInt32(inum)); + return; + } + } + } + if (charextra[charid].invorder_count >= MAX_INVORDER) + quit("!Too many inventory items added, max 500 display at one time"); + + if ((addIndex == SCR_NO_VALUE) || + (addIndex >= charextra[charid].invorder_count) || + (addIndex < 0)) { + // add new item at end of list + charextra[charid].invorder[charextra[charid].invorder_count] = inum; + } else { + // insert new item at index + for (ee = charextra[charid].invorder_count - 1; ee >= addIndex; ee--) + charextra[charid].invorder[ee + 1] = charextra[charid].invorder[ee]; + + charextra[charid].invorder[addIndex] = inum; + } + charextra[charid].invorder_count++; + guis_need_update = 1; + if (chaa == playerchar) + run_on_event(GE_ADD_INV, RuntimeScriptValue().SetInt32(inum)); } void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) { - if (chaa->room != displayed_room) - quit("!MoveCharacterPath: specified character not in current room"); + if (chaa->room != displayed_room) + quit("!MoveCharacterPath: specified character not in current room"); - // not already walking, so just do a normal move - if (chaa->walking <= 0) { - Character_Walk(chaa, x, y, IN_BACKGROUND, ANYWHERE); - return; - } + // not already walking, so just do a normal move + if (chaa->walking <= 0) { + Character_Walk(chaa, x, y, IN_BACKGROUND, ANYWHERE); + return; + } - MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; - if (cmls->numstage >= MAXNEEDSTAGES) - { - debug_script_warn("Character_AddWaypoint: move is too complex, cannot add any further paths"); - return; - } + MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; + if (cmls->numstage >= MAXNEEDSTAGES) { + debug_script_warn("Character_AddWaypoint: move is too complex, cannot add any further paths"); + return; + } - cmls->pos[cmls->numstage] = (x << 16) + y; - // They're already walking there anyway - if (cmls->pos[cmls->numstage] == cmls->pos[cmls->numstage - 1]) - return; + cmls->pos[cmls->numstage] = (x << 16) + y; + // They're already walking there anyway + if (cmls->pos[cmls->numstage] == cmls->pos[cmls->numstage - 1]) + return; - calculate_move_stage (cmls, cmls->numstage-1); - cmls->numstage ++; + calculate_move_stage(cmls, cmls->numstage - 1); + cmls->numstage ++; } void Character_AnimateFrom(CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction, int sframe) { - if (direction == FORWARDS) - direction = 0; - else if (direction == BACKWARDS) - direction = 1; - else - quit("!Character.Animate: Invalid DIRECTION parameter"); + if (direction == FORWARDS) + direction = 0; + else if (direction == BACKWARDS) + direction = 1; + else + quit("!Character.Animate: Invalid DIRECTION parameter"); - animate_character(chaa, loop, delay, repeat, 0, direction, sframe); + animate_character(chaa, loop, delay, repeat, 0, direction, sframe); - if ((blocking == BLOCKING) || (blocking == 1)) - GameLoopUntilValueIsZero(&chaa->animating); - else if ((blocking != IN_BACKGROUND) && (blocking != 0)) - quit("!Character.Animate: Invalid BLOCKING parameter"); + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilValueIsZero(&chaa->animating); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("!Character.Animate: Invalid BLOCKING parameter"); } void Character_Animate(CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction) { - Character_AnimateFrom(chaa, loop, delay, repeat, blocking, direction, 0); + Character_AnimateFrom(chaa, loop, delay, repeat, blocking, direction, 0); } -void Character_ChangeRoomAutoPosition(CharacterInfo *chaa, int room, int newPos) -{ - if (chaa->index_id != game.playercharacter) - { - quit("!Character.ChangeRoomAutoPosition can only be used with the player character."); - } - - new_room_pos = newPos; - - if (new_room_pos == 0) { - // auto place on other side of screen - if (chaa->x <= thisroom.Edges.Left + 10) - new_room_pos = 2000; - else if (chaa->x >= thisroom.Edges.Right - 10) - new_room_pos = 1000; - else if (chaa->y <= thisroom.Edges.Top + 10) - new_room_pos = 3000; - else if (chaa->y >= thisroom.Edges.Bottom - 10) - new_room_pos = 4000; - - if (new_room_pos < 3000) - new_room_pos += chaa->y; - else - new_room_pos += chaa->x; - } - NewRoom(room); +void Character_ChangeRoomAutoPosition(CharacterInfo *chaa, int room, int newPos) { + if (chaa->index_id != game.playercharacter) { + quit("!Character.ChangeRoomAutoPosition can only be used with the player character."); + } + + new_room_pos = newPos; + + if (new_room_pos == 0) { + // auto place on other side of screen + if (chaa->x <= thisroom.Edges.Left + 10) + new_room_pos = 2000; + else if (chaa->x >= thisroom.Edges.Right - 10) + new_room_pos = 1000; + else if (chaa->y <= thisroom.Edges.Top + 10) + new_room_pos = 3000; + else if (chaa->y >= thisroom.Edges.Bottom - 10) + new_room_pos = 4000; + + if (new_room_pos < 3000) + new_room_pos += chaa->y; + else + new_room_pos += chaa->x; + } + NewRoom(room); } void Character_ChangeRoom(CharacterInfo *chaa, int room, int x, int y) { - Character_ChangeRoomSetLoop(chaa, room, x, y, SCR_NO_VALUE); + Character_ChangeRoomSetLoop(chaa, room, x, y, SCR_NO_VALUE); } void Character_ChangeRoomSetLoop(CharacterInfo *chaa, int room, int x, int y, int direction) { - if (chaa->index_id != game.playercharacter) { - // NewRoomNPC - if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) { - chaa->x = x; - chaa->y = y; - if (direction != SCR_NO_VALUE && direction>=0) chaa->loop = direction; - } - chaa->prevroom = chaa->room; - chaa->room = room; + if (chaa->index_id != game.playercharacter) { + // NewRoomNPC + if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) { + chaa->x = x; + chaa->y = y; + if (direction != SCR_NO_VALUE && direction >= 0) chaa->loop = direction; + } + chaa->prevroom = chaa->room; + chaa->room = room; debug_script_log("%s moved to room %d, location %d,%d, loop %d", - chaa->scrname, room, chaa->x, chaa->y, chaa->loop); - - return; - } - - if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) { - new_room_pos = 0; - - if (loaded_game_file_version <= kGameVersion_272) - { - // Set position immediately on 2.x. - chaa->x = x; - chaa->y = y; - } - else - { - // don't check X or Y bounds, so that they can do a - // walk-in animation if they want - new_room_x = x; - new_room_y = y; + chaa->scrname, room, chaa->x, chaa->y, chaa->loop); + + return; + } + + if ((x != SCR_NO_VALUE) && (y != SCR_NO_VALUE)) { + new_room_pos = 0; + + if (loaded_game_file_version <= kGameVersion_272) { + // Set position immediately on 2.x. + chaa->x = x; + chaa->y = y; + } else { + // don't check X or Y bounds, so that they can do a + // walk-in animation if they want + new_room_x = x; + new_room_y = y; if (direction != SCR_NO_VALUE) new_room_loop = direction; - } - } + } + } - NewRoom(room); + NewRoom(room); } void Character_ChangeView(CharacterInfo *chap, int vii) { - vii--; - - if ((vii < 0) || (vii >= game.numviews)) - quit("!ChangeCharacterView: invalid view number specified"); - - // if animating, but not idle view, give warning message - if ((chap->flags & CHF_FIXVIEW) && (chap->idleleft >= 0)) - debug_script_warn("Warning: ChangeCharacterView was used while the view was fixed - call ReleaseCharView first"); - - // if the idle animation is playing we should release the view - if ( chap->idleleft < 0) { - Character_UnlockView(chap); - chap->idleleft = chap->idletime; - } - - debug_script_log("%s: Change view to %d", chap->scrname, vii+1); - chap->defview = vii; - chap->view = vii; - chap->animating = 0; - chap->frame = 0; - chap->wait = 0; - chap->walkwait = 0; - charextra[chap->index_id].animwait = 0; - FindReasonableLoopForCharacter(chap); -} - -enum DirectionalLoop -{ - kDirLoop_Down = 0, - kDirLoop_Left = 1, - kDirLoop_Right = 2, - kDirLoop_Up = 3, - kDirLoop_DownRight = 4, - kDirLoop_UpRight = 5, - kDirLoop_DownLeft = 6, - kDirLoop_UpLeft = 7, - - kDirLoop_Default = kDirLoop_Down, - kDirLoop_LastOrthogonal = kDirLoop_Up, - kDirLoop_Last = kDirLoop_UpLeft, + vii--; + + if ((vii < 0) || (vii >= game.numviews)) + quit("!ChangeCharacterView: invalid view number specified"); + + // if animating, but not idle view, give warning message + if ((chap->flags & CHF_FIXVIEW) && (chap->idleleft >= 0)) + debug_script_warn("Warning: ChangeCharacterView was used while the view was fixed - call ReleaseCharView first"); + + // if the idle animation is playing we should release the view + if (chap->idleleft < 0) { + Character_UnlockView(chap); + chap->idleleft = chap->idletime; + } + + debug_script_log("%s: Change view to %d", chap->scrname, vii + 1); + chap->defview = vii; + chap->view = vii; + chap->animating = 0; + chap->frame = 0; + chap->wait = 0; + chap->walkwait = 0; + charextra[chap->index_id].animwait = 0; + FindReasonableLoopForCharacter(chap); +} + +enum DirectionalLoop { + kDirLoop_Down = 0, + kDirLoop_Left = 1, + kDirLoop_Right = 2, + kDirLoop_Up = 3, + kDirLoop_DownRight = 4, + kDirLoop_UpRight = 5, + kDirLoop_DownLeft = 6, + kDirLoop_UpLeft = 7, + + kDirLoop_Default = kDirLoop_Down, + kDirLoop_LastOrthogonal = kDirLoop_Up, + kDirLoop_Last = kDirLoop_UpLeft, }; // Internal direction-facing functions -DirectionalLoop GetDirectionalLoop(CharacterInfo *chinfo, int x_diff, int y_diff) -{ - DirectionalLoop next_loop = kDirLoop_Left; // NOTE: default loop was Left for some reason - - const ViewStruct &chview = views[chinfo->view]; - const bool new_version = loaded_game_file_version > kGameVersion_272; - const bool has_down_loop = ((chview.numLoops > kDirLoop_Down) && (chview.loops[kDirLoop_Down].numFrames > 0)); - const bool has_up_loop = ((chview.numLoops > kDirLoop_Up) && (chview.loops[kDirLoop_Up].numFrames > 0)); - // NOTE: 3.+ games required left & right loops to be present at all times - const bool has_left_loop = new_version || - ((chview.numLoops > kDirLoop_Left) && (chview.loops[kDirLoop_Left].numFrames > 0)); - const bool has_right_loop = new_version || - ((chview.numLoops > kDirLoop_Right) && (chview.loops[kDirLoop_Right].numFrames > 0)); - const bool has_diagonal_loops = useDiagonal(chinfo) == 0; // NOTE: useDiagonal returns 0 for "true" - - const bool want_horizontal = (abs(y_diff) < abs(x_diff)) || - (new_version && (!has_down_loop || !has_up_loop) )|| - // NOTE: <= 2.72 games switch to horizontal loops only if both vertical ones are missing - (!new_version && (!has_down_loop && !has_up_loop)); - if (want_horizontal) - { - const bool want_diagonal = has_diagonal_loops && (abs(y_diff) > abs(x_diff) / 2); - if (!has_left_loop && !has_right_loop) - { - next_loop = kDirLoop_Down; - } - else if (has_right_loop && (x_diff > 0)) - { - next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpRight : kDirLoop_DownRight) : - kDirLoop_Right; - } - else if (has_left_loop && (x_diff <= 0)) - { - next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpLeft : kDirLoop_DownLeft) : - kDirLoop_Left; - } - } - else - { - const bool want_diagonal = has_diagonal_loops && (abs(x_diff) > abs(y_diff) / 2); - if (y_diff > 0 || !has_up_loop) - { - next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_DownLeft : kDirLoop_DownRight) : - kDirLoop_Down; - } - else - { - next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_UpLeft : kDirLoop_UpRight) : - kDirLoop_Up; - } - } - return next_loop; -} - -void FaceDirectionalLoop(CharacterInfo *char1, int direction, int blockingStyle) -{ - // Change facing only if the desired direction is different - if (direction != char1->loop) - { - if ((game.options[OPT_TURNTOFACELOC] != 0) && - (in_enters_screen == 0)) - { - const int no_diagonal = useDiagonal (char1); - const int highestLoopForTurning = no_diagonal != 1 ? kDirLoop_Last : kDirLoop_LastOrthogonal; - if ((char1->loop <= highestLoopForTurning)) - { - // Turn to face new direction - Character_StopMoving(char1); - if (char1->on == 1) - { - // only do the turning if the character is not hidden - // (otherwise GameLoopUntilNotMoving will never return) - start_character_turning (char1, direction, no_diagonal); - - if ((blockingStyle == BLOCKING) || (blockingStyle == 1)) - GameLoopUntilNotMoving(&char1->walking); - } - else - char1->loop = direction; - } - else - char1->loop = direction; - } - else - char1->loop = direction; - } - - char1->frame = 0; -} - -void FaceLocationXY(CharacterInfo *char1, int xx, int yy, int blockingStyle) -{ - debug_script_log("%s: Face location %d,%d", char1->scrname, xx, yy); - - const int diffrx = xx - char1->x; - const int diffry = yy - char1->y; - - if ((diffrx == 0) && (diffry == 0)) { - // FaceLocation called on their current position - do nothing - return; - } - - FaceDirectionalLoop(char1, GetDirectionalLoop(char1, diffrx, diffry), blockingStyle); +DirectionalLoop GetDirectionalLoop(CharacterInfo *chinfo, int x_diff, int y_diff) { + DirectionalLoop next_loop = kDirLoop_Left; // NOTE: default loop was Left for some reason + + const ViewStruct &chview = views[chinfo->view]; + const bool new_version = loaded_game_file_version > kGameVersion_272; + const bool has_down_loop = ((chview.numLoops > kDirLoop_Down) && (chview.loops[kDirLoop_Down].numFrames > 0)); + const bool has_up_loop = ((chview.numLoops > kDirLoop_Up) && (chview.loops[kDirLoop_Up].numFrames > 0)); + // NOTE: 3.+ games required left & right loops to be present at all times + const bool has_left_loop = new_version || + ((chview.numLoops > kDirLoop_Left) && (chview.loops[kDirLoop_Left].numFrames > 0)); + const bool has_right_loop = new_version || + ((chview.numLoops > kDirLoop_Right) && (chview.loops[kDirLoop_Right].numFrames > 0)); + const bool has_diagonal_loops = useDiagonal(chinfo) == 0; // NOTE: useDiagonal returns 0 for "true" + + const bool want_horizontal = (abs(y_diff) < abs(x_diff)) || + (new_version && (!has_down_loop || !has_up_loop)) || + // NOTE: <= 2.72 games switch to horizontal loops only if both vertical ones are missing + (!new_version && (!has_down_loop && !has_up_loop)); + if (want_horizontal) { + const bool want_diagonal = has_diagonal_loops && (abs(y_diff) > abs(x_diff) / 2); + if (!has_left_loop && !has_right_loop) { + next_loop = kDirLoop_Down; + } else if (has_right_loop && (x_diff > 0)) { + next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpRight : kDirLoop_DownRight) : + kDirLoop_Right; + } else if (has_left_loop && (x_diff <= 0)) { + next_loop = want_diagonal ? (y_diff < 0 ? kDirLoop_UpLeft : kDirLoop_DownLeft) : + kDirLoop_Left; + } + } else { + const bool want_diagonal = has_diagonal_loops && (abs(x_diff) > abs(y_diff) / 2); + if (y_diff > 0 || !has_up_loop) { + next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_DownLeft : kDirLoop_DownRight) : + kDirLoop_Down; + } else { + next_loop = want_diagonal ? (x_diff < 0 ? kDirLoop_UpLeft : kDirLoop_UpRight) : + kDirLoop_Up; + } + } + return next_loop; +} + +void FaceDirectionalLoop(CharacterInfo *char1, int direction, int blockingStyle) { + // Change facing only if the desired direction is different + if (direction != char1->loop) { + if ((game.options[OPT_TURNTOFACELOC] != 0) && + (in_enters_screen == 0)) { + const int no_diagonal = useDiagonal(char1); + const int highestLoopForTurning = no_diagonal != 1 ? kDirLoop_Last : kDirLoop_LastOrthogonal; + if ((char1->loop <= highestLoopForTurning)) { + // Turn to face new direction + Character_StopMoving(char1); + if (char1->on == 1) { + // only do the turning if the character is not hidden + // (otherwise GameLoopUntilNotMoving will never return) + start_character_turning(char1, direction, no_diagonal); + + if ((blockingStyle == BLOCKING) || (blockingStyle == 1)) + GameLoopUntilNotMoving(&char1->walking); + } else + char1->loop = direction; + } else + char1->loop = direction; + } else + char1->loop = direction; + } + + char1->frame = 0; +} + +void FaceLocationXY(CharacterInfo *char1, int xx, int yy, int blockingStyle) { + debug_script_log("%s: Face location %d,%d", char1->scrname, xx, yy); + + const int diffrx = xx - char1->x; + const int diffry = yy - char1->y; + + if ((diffrx == 0) && (diffry == 0)) { + // FaceLocation called on their current position - do nothing + return; + } + + FaceDirectionalLoop(char1, GetDirectionalLoop(char1, diffrx, diffry), blockingStyle); } // External direction-facing functions with validation -void Character_FaceDirection(CharacterInfo *char1, int direction, int blockingStyle) -{ - if (char1 == nullptr) - quit("!FaceDirection: invalid character specified"); +void Character_FaceDirection(CharacterInfo *char1, int direction, int blockingStyle) { + if (char1 == nullptr) + quit("!FaceDirection: invalid character specified"); - if (direction != SCR_NO_VALUE) - { - if (direction < 0 || direction > kDirLoop_Last) - quit("!FaceDirection: invalid direction specified"); + if (direction != SCR_NO_VALUE) { + if (direction < 0 || direction > kDirLoop_Last) + quit("!FaceDirection: invalid direction specified"); - FaceDirectionalLoop(char1, direction, blockingStyle); - } + FaceDirectionalLoop(char1, direction, blockingStyle); + } } -void Character_FaceLocation(CharacterInfo *char1, int xx, int yy, int blockingStyle) -{ - if (char1 == nullptr) - quit("!FaceLocation: invalid character specified"); +void Character_FaceLocation(CharacterInfo *char1, int xx, int yy, int blockingStyle) { + if (char1 == nullptr) + quit("!FaceLocation: invalid character specified"); - FaceLocationXY(char1, xx, yy, blockingStyle); + FaceLocationXY(char1, xx, yy, blockingStyle); } void Character_FaceObject(CharacterInfo *char1, ScriptObject *obj, int blockingStyle) { - if (obj == nullptr) - quit("!FaceObject: invalid object specified"); + if (obj == nullptr) + quit("!FaceObject: invalid object specified"); - FaceLocationXY(char1, objs[obj->id].x, objs[obj->id].y, blockingStyle); + FaceLocationXY(char1, objs[obj->id].x, objs[obj->id].y, blockingStyle); } void Character_FaceCharacter(CharacterInfo *char1, CharacterInfo *char2, int blockingStyle) { - if (char2 == nullptr) - quit("!FaceCharacter: invalid character specified"); + if (char2 == nullptr) + quit("!FaceCharacter: invalid character specified"); - if (char1->room != char2->room) - quit("!FaceCharacter: characters are in different rooms"); + if (char1->room != char2->room) + quit("!FaceCharacter: characters are in different rooms"); - FaceLocationXY(char1, char2->x, char2->y, blockingStyle); + FaceLocationXY(char1, char2->x, char2->y, blockingStyle); } void Character_FollowCharacter(CharacterInfo *chaa, CharacterInfo *tofollow, int distaway, int eagerness) { - if ((eagerness < 0) || (eagerness > 250)) - quit("!FollowCharacterEx: invalid eagerness: must be 0-250"); + if ((eagerness < 0) || (eagerness > 250)) + quit("!FollowCharacterEx: invalid eagerness: must be 0-250"); - if ((chaa->index_id == game.playercharacter) && (tofollow != nullptr) && - (tofollow->room != chaa->room)) - quit("!FollowCharacterEx: you cannot tell the player character to follow a character in another room"); + if ((chaa->index_id == game.playercharacter) && (tofollow != nullptr) && + (tofollow->room != chaa->room)) + quit("!FollowCharacterEx: you cannot tell the player character to follow a character in another room"); - if (tofollow != nullptr) { - debug_script_log("%s: Start following %s (dist %d, eager %d)", chaa->scrname, tofollow->scrname, distaway, eagerness); - } - else { - debug_script_log("%s: Stop following other character", chaa->scrname); - } + if (tofollow != nullptr) { + debug_script_log("%s: Start following %s (dist %d, eager %d)", chaa->scrname, tofollow->scrname, distaway, eagerness); + } else { + debug_script_log("%s: Stop following other character", chaa->scrname); + } - if ((chaa->following >= 0) && - (chaa->followinfo == FOLLOW_ALWAYSONTOP)) { - // if this character was following always-on-top, its baseline will - // have been changed, so release it. - chaa->baseline = -1; - } + if ((chaa->following >= 0) && + (chaa->followinfo == FOLLOW_ALWAYSONTOP)) { + // if this character was following always-on-top, its baseline will + // have been changed, so release it. + chaa->baseline = -1; + } - if (tofollow == nullptr) - chaa->following = -1; - else - chaa->following = tofollow->index_id; + if (tofollow == nullptr) + chaa->following = -1; + else + chaa->following = tofollow->index_id; - chaa->followinfo=(distaway << 8) | eagerness; + chaa->followinfo = (distaway << 8) | eagerness; - chaa->flags &= ~CHF_BEHINDSHEPHERD; + chaa->flags &= ~CHF_BEHINDSHEPHERD; - // special case for Always On Other Character - if (distaway == FOLLOW_ALWAYSONTOP) { - chaa->followinfo = FOLLOW_ALWAYSONTOP; - if (eagerness == 1) - chaa->flags |= CHF_BEHINDSHEPHERD; - } + // special case for Always On Other Character + if (distaway == FOLLOW_ALWAYSONTOP) { + chaa->followinfo = FOLLOW_ALWAYSONTOP; + if (eagerness == 1) + chaa->flags |= CHF_BEHINDSHEPHERD; + } - if (chaa->animating & CHANIM_REPEAT) - debug_script_warn("Warning: FollowCharacter called but the sheep is currently animating looped. It may never start to follow."); + if (chaa->animating & CHANIM_REPEAT) + debug_script_warn("Warning: FollowCharacter called but the sheep is currently animating looped. It may never start to follow."); } int Character_IsCollidingWithChar(CharacterInfo *char1, CharacterInfo *char2) { - if (char2 == nullptr) - quit("!AreCharactersColliding: invalid char2"); + if (char2 == nullptr) + quit("!AreCharactersColliding: invalid char2"); - if (char1->room != char2->room) return 0; // not colliding + if (char1->room != char2->room) return 0; // not colliding - if ((char1->y > char2->y - 5) && (char1->y < char2->y + 5)) ; - else return 0; + if ((char1->y > char2->y - 5) && (char1->y < char2->y + 5)) ; + else return 0; - int w1 = game_to_data_coord(GetCharacterWidth(char1->index_id)); - int w2 = game_to_data_coord(GetCharacterWidth(char2->index_id)); + int w1 = game_to_data_coord(GetCharacterWidth(char1->index_id)); + int w2 = game_to_data_coord(GetCharacterWidth(char2->index_id)); - int xps1=char1->x - w1/2; - int xps2=char2->x - w2/2; + int xps1 = char1->x - w1 / 2; + int xps2 = char2->x - w2 / 2; - if ((xps1 >= xps2 - w1) & (xps1 <= xps2 + w2)) return 1; - return 0; + if ((xps1 >= xps2 - w1) & (xps1 <= xps2 + w2)) return 1; + return 0; } int Character_IsCollidingWithObject(CharacterInfo *chin, ScriptObject *objid) { - if (objid == nullptr) - quit("!AreCharObjColliding: invalid object number"); - - if (chin->room != displayed_room) - return 0; - if (objs[objid->id].on != 1) - return 0; - - Bitmap *checkblk = GetObjectImage(objid->id, nullptr); - int objWidth = checkblk->GetWidth(); - int objHeight = checkblk->GetHeight(); - int o1x = objs[objid->id].x; - int o1y = objs[objid->id].y - game_to_data_coord(objHeight); - - Bitmap *charpic = GetCharacterImage(chin->index_id, nullptr); - - int charWidth = charpic->GetWidth(); - int charHeight = charpic->GetHeight(); - int o2x = chin->x - game_to_data_coord(charWidth) / 2; - int o2y = chin->get_effective_y() - 5; // only check feet - - if ((o2x >= o1x - game_to_data_coord(charWidth)) && - (o2x <= o1x + game_to_data_coord(objWidth)) && - (o2y >= o1y - 8) && - (o2y <= o1y + game_to_data_coord(objHeight))) { - // the character's feet are on the object - if (game.options[OPT_PIXPERFECT] == 0) - return 1; - // check if they're on a transparent bit of the object - int stxp = data_to_game_coord(o2x - o1x); - int styp = data_to_game_coord(o2y - o1y); - int maskcol = checkblk->GetMaskColor (); - int maskcolc = charpic->GetMaskColor (); - int thispix, thispixc; - // check each pixel of the object along the char's feet - for (int i = 0; i < charWidth; i += get_fixed_pixel_size(1)) { - for (int j = 0; j < get_fixed_pixel_size(6); j += get_fixed_pixel_size(1)) { - thispix = my_getpixel(checkblk, i + stxp, j + styp); - thispixc = my_getpixel(charpic, i, j + (charHeight - get_fixed_pixel_size(5))); - - if ((thispix != -1) && (thispix != maskcol) && - (thispixc != -1) && (thispixc != maskcolc)) - return 1; - } - } - - } - return 0; + if (objid == nullptr) + quit("!AreCharObjColliding: invalid object number"); + + if (chin->room != displayed_room) + return 0; + if (objs[objid->id].on != 1) + return 0; + + Bitmap *checkblk = GetObjectImage(objid->id, nullptr); + int objWidth = checkblk->GetWidth(); + int objHeight = checkblk->GetHeight(); + int o1x = objs[objid->id].x; + int o1y = objs[objid->id].y - game_to_data_coord(objHeight); + + Bitmap *charpic = GetCharacterImage(chin->index_id, nullptr); + + int charWidth = charpic->GetWidth(); + int charHeight = charpic->GetHeight(); + int o2x = chin->x - game_to_data_coord(charWidth) / 2; + int o2y = chin->get_effective_y() - 5; // only check feet + + if ((o2x >= o1x - game_to_data_coord(charWidth)) && + (o2x <= o1x + game_to_data_coord(objWidth)) && + (o2y >= o1y - 8) && + (o2y <= o1y + game_to_data_coord(objHeight))) { + // the character's feet are on the object + if (game.options[OPT_PIXPERFECT] == 0) + return 1; + // check if they're on a transparent bit of the object + int stxp = data_to_game_coord(o2x - o1x); + int styp = data_to_game_coord(o2y - o1y); + int maskcol = checkblk->GetMaskColor(); + int maskcolc = charpic->GetMaskColor(); + int thispix, thispixc; + // check each pixel of the object along the char's feet + for (int i = 0; i < charWidth; i += get_fixed_pixel_size(1)) { + for (int j = 0; j < get_fixed_pixel_size(6); j += get_fixed_pixel_size(1)) { + thispix = my_getpixel(checkblk, i + stxp, j + styp); + thispixc = my_getpixel(charpic, i, j + (charHeight - get_fixed_pixel_size(5))); + + if ((thispix != -1) && (thispix != maskcol) && + (thispixc != -1) && (thispixc != maskcolc)) + return 1; + } + } + + } + return 0; } bool Character_IsInteractionAvailable(CharacterInfo *cchar, int mood) { - play.check_interaction_only = 1; - RunCharacterInteraction(cchar->index_id, mood); - int ciwas = play.check_interaction_only; - play.check_interaction_only = 0; - return (ciwas == 2); + play.check_interaction_only = 1; + RunCharacterInteraction(cchar->index_id, mood); + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + return (ciwas == 2); } void Character_LockView(CharacterInfo *chap, int vii) { - Character_LockViewEx(chap, vii, STOP_MOVING); + Character_LockViewEx(chap, vii, STOP_MOVING); } void Character_LockViewEx(CharacterInfo *chap, int vii, int stopMoving) { - if ((vii < 1) || (vii > game.numviews)) { - quitprintf("!SetCharacterView: invalid view number (You said %d, max is %d)", vii, game.numviews); - } - vii--; - - debug_script_log("%s: View locked to %d", chap->scrname, vii+1); - if (chap->idleleft < 0) { - Character_UnlockView(chap); - chap->idleleft = chap->idletime; - } - if (stopMoving != KEEP_MOVING) - { - Character_StopMoving(chap); - } - chap->view=vii; - chap->animating=0; - FindReasonableLoopForCharacter(chap); - chap->frame=0; - chap->wait=0; - chap->flags|=CHF_FIXVIEW; - chap->pic_xoffs = 0; - chap->pic_yoffs = 0; + if ((vii < 1) || (vii > game.numviews)) { + quitprintf("!SetCharacterView: invalid view number (You said %d, max is %d)", vii, game.numviews); + } + vii--; + + debug_script_log("%s: View locked to %d", chap->scrname, vii + 1); + if (chap->idleleft < 0) { + Character_UnlockView(chap); + chap->idleleft = chap->idletime; + } + if (stopMoving != KEEP_MOVING) { + Character_StopMoving(chap); + } + chap->view = vii; + chap->animating = 0; + FindReasonableLoopForCharacter(chap); + chap->frame = 0; + chap->wait = 0; + chap->flags |= CHF_FIXVIEW; + chap->pic_xoffs = 0; + chap->pic_yoffs = 0; } void Character_LockViewAligned_Old(CharacterInfo *chap, int vii, int loop, int align) { - Character_LockViewAlignedEx(chap, vii, loop, ConvertLegacyScriptAlignment((LegacyScriptAlignment)align), STOP_MOVING); + Character_LockViewAlignedEx(chap, vii, loop, ConvertLegacyScriptAlignment((LegacyScriptAlignment)align), STOP_MOVING); } void Character_LockViewAlignedEx_Old(CharacterInfo *chap, int vii, int loop, int align, int stopMoving) { - Character_LockViewAlignedEx(chap, vii, loop, ConvertLegacyScriptAlignment((LegacyScriptAlignment)align), stopMoving); + Character_LockViewAlignedEx(chap, vii, loop, ConvertLegacyScriptAlignment((LegacyScriptAlignment)align), stopMoving); } void Character_LockViewAligned(CharacterInfo *chap, int vii, int loop, int align) { - Character_LockViewAlignedEx(chap, vii, loop, align, STOP_MOVING); + Character_LockViewAlignedEx(chap, vii, loop, align, STOP_MOVING); } void Character_LockViewAlignedEx(CharacterInfo *chap, int vii, int loop, int align, int stopMoving) { - if (chap->view < 0) - quit("!SetCharacterLoop: character has invalid old view number"); + if (chap->view < 0) + quit("!SetCharacterLoop: character has invalid old view number"); - int sppic = views[chap->view].loops[chap->loop].frames[chap->frame].pic; - int leftSide = data_to_game_coord(chap->x) - game.SpriteInfos[sppic].Width / 2; + int sppic = views[chap->view].loops[chap->loop].frames[chap->frame].pic; + int leftSide = data_to_game_coord(chap->x) - game.SpriteInfos[sppic].Width / 2; - Character_LockViewEx(chap, vii, stopMoving); + Character_LockViewEx(chap, vii, stopMoving); - if ((loop < 0) || (loop >= views[chap->view].numLoops)) - quit("!SetCharacterViewEx: invalid loop specified"); + if ((loop < 0) || (loop >= views[chap->view].numLoops)) + quit("!SetCharacterViewEx: invalid loop specified"); - chap->loop = loop; - chap->frame = 0; - int newpic = views[chap->view].loops[chap->loop].frames[chap->frame].pic; - int newLeft = data_to_game_coord(chap->x) - game.SpriteInfos[newpic].Width / 2; - int xdiff = 0; + chap->loop = loop; + chap->frame = 0; + int newpic = views[chap->view].loops[chap->loop].frames[chap->frame].pic; + int newLeft = data_to_game_coord(chap->x) - game.SpriteInfos[newpic].Width / 2; + int xdiff = 0; - if (align & kMAlignLeft) - xdiff = leftSide - newLeft; - else if (align & kMAlignHCenter) - xdiff = 0; - else if (align & kMAlignRight) - xdiff = (leftSide + game.SpriteInfos[sppic].Width) - (newLeft + game.SpriteInfos[newpic].Width); - else - quit("!SetCharacterViewEx: invalid alignment type specified"); + if (align & kMAlignLeft) + xdiff = leftSide - newLeft; + else if (align & kMAlignHCenter) + xdiff = 0; + else if (align & kMAlignRight) + xdiff = (leftSide + game.SpriteInfos[sppic].Width) - (newLeft + game.SpriteInfos[newpic].Width); + else + quit("!SetCharacterViewEx: invalid alignment type specified"); - chap->pic_xoffs = xdiff; - chap->pic_yoffs = 0; + chap->pic_xoffs = xdiff; + chap->pic_yoffs = 0; } void Character_LockViewFrame(CharacterInfo *chaa, int view, int loop, int frame) { - Character_LockViewFrameEx(chaa, view, loop, frame, STOP_MOVING); + Character_LockViewFrameEx(chaa, view, loop, frame, STOP_MOVING); } void Character_LockViewFrameEx(CharacterInfo *chaa, int view, int loop, int frame, int stopMoving) { - Character_LockViewEx(chaa, view, stopMoving); + Character_LockViewEx(chaa, view, stopMoving); - view--; - if ((loop < 0) || (loop >= views[view].numLoops)) - quit("!SetCharacterFrame: invalid loop specified"); - if ((frame < 0) || (frame >= views[view].loops[loop].numFrames)) - quit("!SetCharacterFrame: invalid frame specified"); + view--; + if ((loop < 0) || (loop >= views[view].numLoops)) + quit("!SetCharacterFrame: invalid loop specified"); + if ((frame < 0) || (frame >= views[view].loops[loop].numFrames)) + quit("!SetCharacterFrame: invalid frame specified"); - chaa->loop = loop; - chaa->frame = frame; + chaa->loop = loop; + chaa->frame = frame; } void Character_LockViewOffset(CharacterInfo *chap, int vii, int xoffs, int yoffs) { - Character_LockViewOffsetEx(chap, vii, xoffs, yoffs, STOP_MOVING); + Character_LockViewOffsetEx(chap, vii, xoffs, yoffs, STOP_MOVING); } void Character_LockViewOffsetEx(CharacterInfo *chap, int vii, int xoffs, int yoffs, int stopMoving) { - Character_LockViewEx(chap, vii, stopMoving); + Character_LockViewEx(chap, vii, stopMoving); - // This function takes offsets in real game coordinates as opposed to script coordinates - defgame_to_finalgame_coords(xoffs, yoffs); - chap->pic_xoffs = xoffs; - chap->pic_yoffs = yoffs; + // This function takes offsets in real game coordinates as opposed to script coordinates + defgame_to_finalgame_coords(xoffs, yoffs); + chap->pic_xoffs = xoffs; + chap->pic_yoffs = yoffs; } void Character_LoseInventory(CharacterInfo *chap, ScriptInvItem *invi) { - if (invi == nullptr) - quit("!LoseInventoryFromCharacter: invalid invnetory number"); + if (invi == nullptr) + quit("!LoseInventoryFromCharacter: invalid invnetory number"); - int inum = invi->id; + int inum = invi->id; - if (chap->inv[inum] > 0) - chap->inv[inum]--; + if (chap->inv[inum] > 0) + chap->inv[inum]--; - if ((chap->activeinv == inum) & (chap->inv[inum] < 1)) { - chap->activeinv = -1; - if ((chap == playerchar) && (GetCursorMode() == MODE_USE)) - set_cursor_mode(0); - } + if ((chap->activeinv == inum) & (chap->inv[inum] < 1)) { + chap->activeinv = -1; + if ((chap == playerchar) && (GetCursorMode() == MODE_USE)) + set_cursor_mode(0); + } - int charid = chap->index_id; + int charid = chap->index_id; - if ((chap->inv[inum] == 0) || (game.options[OPT_DUPLICATEINV] > 0)) { - int xx,tt; - for (xx = 0; xx < charextra[charid].invorder_count; xx++) { - if (charextra[charid].invorder[xx] == inum) { - charextra[charid].invorder_count--; - for (tt = xx; tt < charextra[charid].invorder_count; tt++) - charextra[charid].invorder[tt] = charextra[charid].invorder[tt+1]; - break; - } - } - } - guis_need_update = 1; + if ((chap->inv[inum] == 0) || (game.options[OPT_DUPLICATEINV] > 0)) { + int xx, tt; + for (xx = 0; xx < charextra[charid].invorder_count; xx++) { + if (charextra[charid].invorder[xx] == inum) { + charextra[charid].invorder_count--; + for (tt = xx; tt < charextra[charid].invorder_count; tt++) + charextra[charid].invorder[tt] = charextra[charid].invorder[tt + 1]; + break; + } + } + } + guis_need_update = 1; - if (chap == playerchar) - run_on_event (GE_LOSE_INV, RuntimeScriptValue().SetInt32(inum)); + if (chap == playerchar) + run_on_event(GE_LOSE_INV, RuntimeScriptValue().SetInt32(inum)); } -void Character_PlaceOnWalkableArea(CharacterInfo *chap) -{ - if (displayed_room < 0) - quit("!Character.PlaceOnWalkableArea: no room is currently loaded"); +void Character_PlaceOnWalkableArea(CharacterInfo *chap) { + if (displayed_room < 0) + quit("!Character.PlaceOnWalkableArea: no room is currently loaded"); - find_nearest_walkable_area(&chap->x, &chap->y); + find_nearest_walkable_area(&chap->x, &chap->y); } void Character_RemoveTint(CharacterInfo *chaa) { - if (chaa->flags & (CHF_HASTINT | CHF_HASLIGHT)) { - debug_script_log("Un-tint %s", chaa->scrname); - chaa->flags &= ~(CHF_HASTINT | CHF_HASLIGHT); - } - else { - debug_script_warn("Character.RemoveTint called but character was not tinted"); - } + if (chaa->flags & (CHF_HASTINT | CHF_HASLIGHT)) { + debug_script_log("Un-tint %s", chaa->scrname); + chaa->flags &= ~(CHF_HASTINT | CHF_HASLIGHT); + } else { + debug_script_warn("Character.RemoveTint called but character was not tinted"); + } } -int Character_GetHasExplicitTint_Old(CharacterInfo *ch) -{ - return ch->has_explicit_tint() || ch->has_explicit_light(); +int Character_GetHasExplicitTint_Old(CharacterInfo *ch) { + return ch->has_explicit_tint() || ch->has_explicit_light(); } -int Character_GetHasExplicitTint(CharacterInfo *ch) -{ - return ch->has_explicit_tint(); +int Character_GetHasExplicitTint(CharacterInfo *ch) { + return ch->has_explicit_tint(); } void Character_Say(CharacterInfo *chaa, const char *text) { - _DisplaySpeechCore(chaa->index_id, text); + _DisplaySpeechCore(chaa->index_id, text); } void Character_SayAt(CharacterInfo *chaa, int x, int y, int width, const char *texx) { - DisplaySpeechAt(x, y, width, chaa->index_id, (char*)texx); + DisplaySpeechAt(x, y, width, chaa->index_id, (char *)texx); } -ScriptOverlay* Character_SayBackground(CharacterInfo *chaa, const char *texx) { +ScriptOverlay *Character_SayBackground(CharacterInfo *chaa, const char *texx) { - int ovltype = DisplaySpeechBackground(chaa->index_id, (char*)texx); - int ovri = find_overlay_of_type(ovltype); - if (ovri<0) - quit("!SayBackground internal error: no overlay"); + int ovltype = DisplaySpeechBackground(chaa->index_id, (char *)texx); + int ovri = find_overlay_of_type(ovltype); + if (ovri < 0) + quit("!SayBackground internal error: no overlay"); - // Convert the overlay ID to an Overlay object - ScriptOverlay *scOver = new ScriptOverlay(); - scOver->overlayId = ovltype; - scOver->borderHeight = 0; - scOver->borderWidth = 0; - scOver->isBackgroundSpeech = 1; - int handl = ccRegisterManagedObject(scOver, scOver); - screenover[ovri].associatedOverlayHandle = handl; + // Convert the overlay ID to an Overlay object + ScriptOverlay *scOver = new ScriptOverlay(); + scOver->overlayId = ovltype; + scOver->borderHeight = 0; + scOver->borderWidth = 0; + scOver->isBackgroundSpeech = 1; + int handl = ccRegisterManagedObject(scOver, scOver); + screenover[ovri].associatedOverlayHandle = handl; - return scOver; + return scOver; } void Character_SetAsPlayer(CharacterInfo *chaa) { - // Set to same character, so ignore. - // But only on versions > 2.61. The relevant entry in the 2.62 changelog is: - // - Fixed SetPlayerCharacter to do nothing at all if you pass the current - // player character to it (previously it was resetting the inventory layout) - if ((loaded_game_file_version > kGameVersion_261) && (game.playercharacter == chaa->index_id)) - return; + // Set to same character, so ignore. + // But only on versions > 2.61. The relevant entry in the 2.62 changelog is: + // - Fixed SetPlayerCharacter to do nothing at all if you pass the current + // player character to it (previously it was resetting the inventory layout) + if ((loaded_game_file_version > kGameVersion_261) && (game.playercharacter == chaa->index_id)) + return; - setup_player_character(chaa->index_id); + setup_player_character(chaa->index_id); - //update_invorder(); + //update_invorder(); - debug_script_log("%s is new player character", playerchar->scrname); + debug_script_log("%s is new player character", playerchar->scrname); - // Within game_start, return now - if (displayed_room < 0) - return; + // Within game_start, return now + if (displayed_room < 0) + return; - // Ignore invalid room numbers for the character and just place him in - // the current room for 2.x. Following script calls to NewRoom() will - // make sure this still works as intended. - if ((loaded_game_file_version <= kGameVersion_272) && (playerchar->room < 0)) - playerchar->room = displayed_room; + // Ignore invalid room numbers for the character and just place him in + // the current room for 2.x. Following script calls to NewRoom() will + // make sure this still works as intended. + if ((loaded_game_file_version <= kGameVersion_272) && (playerchar->room < 0)) + playerchar->room = displayed_room; - if (displayed_room != playerchar->room) - NewRoom(playerchar->room); - else // make sure it doesn't run the region interactions - play.player_on_region = GetRegionIDAtRoom(playerchar->x, playerchar->y); + if (displayed_room != playerchar->room) + NewRoom(playerchar->room); + else // make sure it doesn't run the region interactions + play.player_on_region = GetRegionIDAtRoom(playerchar->x, playerchar->y); - if ((playerchar->activeinv >= 0) && (playerchar->inv[playerchar->activeinv] < 1)) - playerchar->activeinv = -1; + if ((playerchar->activeinv >= 0) && (playerchar->inv[playerchar->activeinv] < 1)) + playerchar->activeinv = -1; - // They had inv selected, so change the cursor - if (cur_mode == MODE_USE) { - if (playerchar->activeinv < 0) - SetNextCursor (); - else - SetActiveInventory (playerchar->activeinv); - } + // They had inv selected, so change the cursor + if (cur_mode == MODE_USE) { + if (playerchar->activeinv < 0) + SetNextCursor(); + else + SetActiveInventory(playerchar->activeinv); + } } void Character_SetIdleView(CharacterInfo *chaa, int iview, int itime) { - if (iview == 1) - quit("!SetCharacterIdle: view 1 cannot be used as an idle view, sorry."); - - // if an idle anim is currently playing, release it - if (chaa->idleleft < 0) - Character_UnlockView(chaa); - - chaa->idleview = iview - 1; - // make sure they don't appear idle while idle anim is disabled - if (iview < 1) - itime = 10; - chaa->idletime = itime; - chaa->idleleft = itime; - - // if not currently animating, reset the wait counter - if ((chaa->animating == 0) && (chaa->walking == 0)) - chaa->wait = 0; - - if (iview >= 1) { - debug_script_log("Set %s idle view to %d (time %d)", chaa->scrname, iview, itime); - } - else { - debug_script_log("%s idle view disabled", chaa->scrname); - } - if (chaa->flags & CHF_FIXVIEW) { - debug_script_warn("SetCharacterIdle called while character view locked with SetCharacterView; idle ignored"); - debug_script_log("View locked, idle will not kick in until Released"); - } - // if they switch to a swimming animation, kick it off immediately - if (itime == 0) - charextra[chaa->index_id].process_idle_this_time = 1; - -} - -bool Character_GetHasExplicitLight(CharacterInfo *ch) -{ - return ch->has_explicit_light(); + if (iview == 1) + quit("!SetCharacterIdle: view 1 cannot be used as an idle view, sorry."); + + // if an idle anim is currently playing, release it + if (chaa->idleleft < 0) + Character_UnlockView(chaa); + + chaa->idleview = iview - 1; + // make sure they don't appear idle while idle anim is disabled + if (iview < 1) + itime = 10; + chaa->idletime = itime; + chaa->idleleft = itime; + + // if not currently animating, reset the wait counter + if ((chaa->animating == 0) && (chaa->walking == 0)) + chaa->wait = 0; + + if (iview >= 1) { + debug_script_log("Set %s idle view to %d (time %d)", chaa->scrname, iview, itime); + } else { + debug_script_log("%s idle view disabled", chaa->scrname); + } + if (chaa->flags & CHF_FIXVIEW) { + debug_script_warn("SetCharacterIdle called while character view locked with SetCharacterView; idle ignored"); + debug_script_log("View locked, idle will not kick in until Released"); + } + // if they switch to a swimming animation, kick it off immediately + if (itime == 0) + charextra[chaa->index_id].process_idle_this_time = 1; + } -int Character_GetLightLevel(CharacterInfo *ch) -{ - return ch->has_explicit_light() ? charextra[ch->index_id].tint_light : 0; +bool Character_GetHasExplicitLight(CharacterInfo *ch) { + return ch->has_explicit_light(); } -void Character_SetLightLevel(CharacterInfo *chaa, int light_level) -{ - light_level = Math::Clamp(light_level, -100, 100); - - charextra[chaa->index_id].tint_light = light_level; - chaa->flags &= ~CHF_HASTINT; - chaa->flags |= CHF_HASLIGHT; +int Character_GetLightLevel(CharacterInfo *ch) { + return ch->has_explicit_light() ? charextra[ch->index_id].tint_light : 0; } -int Character_GetTintRed(CharacterInfo *ch) -{ - return ch->has_explicit_tint() ? charextra[ch->index_id].tint_r : 0; +void Character_SetLightLevel(CharacterInfo *chaa, int light_level) { + light_level = Math::Clamp(light_level, -100, 100); + + charextra[chaa->index_id].tint_light = light_level; + chaa->flags &= ~CHF_HASTINT; + chaa->flags |= CHF_HASLIGHT; } -int Character_GetTintGreen(CharacterInfo *ch) -{ - return ch->has_explicit_tint() ? charextra[ch->index_id].tint_g : 0; +int Character_GetTintRed(CharacterInfo *ch) { + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_r : 0; } -int Character_GetTintBlue(CharacterInfo *ch) -{ - return ch->has_explicit_tint() ? charextra[ch->index_id].tint_b : 0; +int Character_GetTintGreen(CharacterInfo *ch) { + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_g : 0; } -int Character_GetTintSaturation(CharacterInfo *ch) -{ - return ch->has_explicit_tint() ? charextra[ch->index_id].tint_level : 0; +int Character_GetTintBlue(CharacterInfo *ch) { + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_b : 0; } -int Character_GetTintLuminance(CharacterInfo *ch) -{ - return ch->has_explicit_tint() ? ((charextra[ch->index_id].tint_light * 10) / 25) : 0; +int Character_GetTintSaturation(CharacterInfo *ch) { + return ch->has_explicit_tint() ? charextra[ch->index_id].tint_level : 0; +} + +int Character_GetTintLuminance(CharacterInfo *ch) { + return ch->has_explicit_tint() ? ((charextra[ch->index_id].tint_light * 10) / 25) : 0; } void Character_SetOption(CharacterInfo *chaa, int flag, int yesorno) { - if ((yesorno < 0) || (yesorno > 1)) - quit("!SetCharacterProperty: last parameter must be 0 or 1"); + if ((yesorno < 0) || (yesorno > 1)) + quit("!SetCharacterProperty: last parameter must be 0 or 1"); - if (flag & CHF_MANUALSCALING) { - // backwards compatibility fix - Character_SetIgnoreScaling(chaa, yesorno); - } - else { - chaa->flags &= ~flag; - if (yesorno) - chaa->flags |= flag; - } + if (flag & CHF_MANUALSCALING) { + // backwards compatibility fix + Character_SetIgnoreScaling(chaa, yesorno); + } else { + chaa->flags &= ~flag; + if (yesorno) + chaa->flags |= flag; + } } void Character_SetSpeed(CharacterInfo *chaa, int xspeed, int yspeed) { - if ((xspeed == 0) || (xspeed > 50) || (yspeed == 0) || (yspeed > 50)) - quit("!SetCharacterSpeedEx: invalid speed value"); - if (chaa->walking) - { - debug_script_warn("Character_SetSpeed: cannot change speed while walking"); - return; - } + if ((xspeed == 0) || (xspeed > 50) || (yspeed == 0) || (yspeed > 50)) + quit("!SetCharacterSpeedEx: invalid speed value"); + if (chaa->walking) { + debug_script_warn("Character_SetSpeed: cannot change speed while walking"); + return; + } - chaa->walkspeed = xspeed; + chaa->walkspeed = xspeed; - if (yspeed == xspeed) - chaa->walkspeed_y = UNIFORM_WALK_SPEED; - else - chaa->walkspeed_y = yspeed; + if (yspeed == xspeed) + chaa->walkspeed_y = UNIFORM_WALK_SPEED; + else + chaa->walkspeed_y = yspeed; } void Character_StopMoving(CharacterInfo *charp) { - int chaa = charp->index_id; - if (chaa == play.skip_until_char_stops) - EndSkippingUntilCharStops(); - - if (charextra[chaa].xwas != INVALID_X) { - charp->x = charextra[chaa].xwas; - charp->y = charextra[chaa].ywas; - charextra[chaa].xwas = INVALID_X; - } - if ((charp->walking > 0) && (charp->walking < TURNING_AROUND)) { - // if it's not a MoveCharDirect, make sure they end up on a walkable area - if ((mls[charp->walking].direct == 0) && (charp->room == displayed_room)) - Character_PlaceOnWalkableArea(charp); - - debug_script_log("%s: stop moving", charp->scrname); - - charp->idleleft = charp->idletime; - // restart the idle animation straight away - charextra[chaa].process_idle_this_time = 1; - } - if (charp->walking) { - // If the character is currently moving, stop them and reset their frame - charp->walking = 0; - if ((charp->flags & CHF_MOVENOTWALK) == 0) - charp->frame = 0; - } + int chaa = charp->index_id; + if (chaa == play.skip_until_char_stops) + EndSkippingUntilCharStops(); + + if (charextra[chaa].xwas != INVALID_X) { + charp->x = charextra[chaa].xwas; + charp->y = charextra[chaa].ywas; + charextra[chaa].xwas = INVALID_X; + } + if ((charp->walking > 0) && (charp->walking < TURNING_AROUND)) { + // if it's not a MoveCharDirect, make sure they end up on a walkable area + if ((mls[charp->walking].direct == 0) && (charp->room == displayed_room)) + Character_PlaceOnWalkableArea(charp); + + debug_script_log("%s: stop moving", charp->scrname); + + charp->idleleft = charp->idletime; + // restart the idle animation straight away + charextra[chaa].process_idle_this_time = 1; + } + if (charp->walking) { + // If the character is currently moving, stop them and reset their frame + charp->walking = 0; + if ((charp->flags & CHF_MOVENOTWALK) == 0) + charp->frame = 0; + } } void Character_Tint(CharacterInfo *chaa, int red, int green, int blue, int opacity, int luminance) { - if ((red < 0) || (green < 0) || (blue < 0) || - (red > 255) || (green > 255) || (blue > 255) || - (opacity < 0) || (opacity > 100) || - (luminance < 0) || (luminance > 100)) - quit("!Character.Tint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) + quit("!Character.Tint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); - debug_script_log("Set %s tint RGB(%d,%d,%d) %d%%", chaa->scrname, red, green, blue, opacity); + debug_script_log("Set %s tint RGB(%d,%d,%d) %d%%", chaa->scrname, red, green, blue, opacity); - charextra[chaa->index_id].tint_r = red; - charextra[chaa->index_id].tint_g = green; - charextra[chaa->index_id].tint_b = blue; - charextra[chaa->index_id].tint_level = opacity; - charextra[chaa->index_id].tint_light = (luminance * 25) / 10; - chaa->flags &= ~CHF_HASLIGHT; - chaa->flags |= CHF_HASTINT; + charextra[chaa->index_id].tint_r = red; + charextra[chaa->index_id].tint_g = green; + charextra[chaa->index_id].tint_b = blue; + charextra[chaa->index_id].tint_level = opacity; + charextra[chaa->index_id].tint_light = (luminance * 25) / 10; + chaa->flags &= ~CHF_HASLIGHT; + chaa->flags |= CHF_HASTINT; } void Character_Think(CharacterInfo *chaa, const char *text) { - _DisplayThoughtCore(chaa->index_id, text); + _DisplayThoughtCore(chaa->index_id, text); } void Character_UnlockView(CharacterInfo *chaa) { - Character_UnlockViewEx(chaa, STOP_MOVING); + Character_UnlockViewEx(chaa, STOP_MOVING); } void Character_UnlockViewEx(CharacterInfo *chaa, int stopMoving) { - if (chaa->flags & CHF_FIXVIEW) { - debug_script_log("%s: Released view back to default", chaa->scrname); - } - chaa->flags &= ~CHF_FIXVIEW; - chaa->view = chaa->defview; - chaa->frame = 0; - if (stopMoving != KEEP_MOVING) - { - Character_StopMoving(chaa); - } - if (chaa->view >= 0) { - int maxloop = views[chaa->view].numLoops; - if (((chaa->flags & CHF_NODIAGONAL)!=0) && (maxloop > 4)) - maxloop = 4; - FindReasonableLoopForCharacter(chaa); - } - chaa->animating = 0; - chaa->idleleft = chaa->idletime; - chaa->pic_xoffs = 0; - chaa->pic_yoffs = 0; - // restart the idle animation straight away - charextra[chaa->index_id].process_idle_this_time = 1; - -} - - -void Character_Walk(CharacterInfo *chaa, int x, int y, int blocking, int direct) -{ - walk_or_move_character(chaa, x, y, blocking, direct, true); + if (chaa->flags & CHF_FIXVIEW) { + debug_script_log("%s: Released view back to default", chaa->scrname); + } + chaa->flags &= ~CHF_FIXVIEW; + chaa->view = chaa->defview; + chaa->frame = 0; + if (stopMoving != KEEP_MOVING) { + Character_StopMoving(chaa); + } + if (chaa->view >= 0) { + int maxloop = views[chaa->view].numLoops; + if (((chaa->flags & CHF_NODIAGONAL) != 0) && (maxloop > 4)) + maxloop = 4; + FindReasonableLoopForCharacter(chaa); + } + chaa->animating = 0; + chaa->idleleft = chaa->idletime; + chaa->pic_xoffs = 0; + chaa->pic_yoffs = 0; + // restart the idle animation straight away + charextra[chaa->index_id].process_idle_this_time = 1; + } -void Character_Move(CharacterInfo *chaa, int x, int y, int blocking, int direct) -{ - walk_or_move_character(chaa, x, y, blocking, direct, false); + +void Character_Walk(CharacterInfo *chaa, int x, int y, int blocking, int direct) { + walk_or_move_character(chaa, x, y, blocking, direct, true); +} + +void Character_Move(CharacterInfo *chaa, int x, int y, int blocking, int direct) { + walk_or_move_character(chaa, x, y, blocking, direct, false); } void Character_WalkStraight(CharacterInfo *chaa, int xx, int yy, int blocking) { - if (chaa->room != displayed_room) - quit("!MoveCharacterStraight: specified character not in current room"); + if (chaa->room != displayed_room) + quit("!MoveCharacterStraight: specified character not in current room"); - Character_StopMoving(chaa); - int movetox = xx, movetoy = yy; + Character_StopMoving(chaa); + int movetox = xx, movetoy = yy; - set_wallscreen(prepare_walkable_areas(chaa->index_id)); + set_wallscreen(prepare_walkable_areas(chaa->index_id)); - int fromXLowres = room_to_mask_coord(chaa->x); - int fromYLowres = room_to_mask_coord(chaa->y); - int toXLowres = room_to_mask_coord(xx); - int toYLowres = room_to_mask_coord(yy); + int fromXLowres = room_to_mask_coord(chaa->x); + int fromYLowres = room_to_mask_coord(chaa->y); + int toXLowres = room_to_mask_coord(xx); + int toYLowres = room_to_mask_coord(yy); - if (!can_see_from(fromXLowres, fromYLowres, toXLowres, toYLowres)) { - int lastcx, lastcy; - get_lastcpos(lastcx, lastcy); - movetox = mask_to_room_coord(lastcx); - movetoy = mask_to_room_coord(lastcy); - } + if (!can_see_from(fromXLowres, fromYLowres, toXLowres, toYLowres)) { + int lastcx, lastcy; + get_lastcpos(lastcx, lastcy); + movetox = mask_to_room_coord(lastcx); + movetoy = mask_to_room_coord(lastcy); + } - walk_character(chaa->index_id, movetox, movetoy, 1, true); + walk_character(chaa->index_id, movetox, movetoy, 1, true); - if ((blocking == BLOCKING) || (blocking == 1)) - GameLoopUntilNotMoving(&chaa->walking); - else if ((blocking != IN_BACKGROUND) && (blocking != 0)) - quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND"); + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilNotMoving(&chaa->walking); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND"); } void Character_RunInteraction(CharacterInfo *chaa, int mood) { - RunCharacterInteraction(chaa->index_id, mood); + RunCharacterInteraction(chaa->index_id, mood); } @@ -1093,578 +1041,562 @@ void Character_RunInteraction(CharacterInfo *chaa, int mood) { int Character_GetProperty(CharacterInfo *chaa, const char *property) { - return get_int_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property); + return get_int_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property); } void Character_GetPropertyText(CharacterInfo *chaa, const char *property, char *bufer) { - get_text_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property, bufer); + get_text_property(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property, bufer); } -const char* Character_GetTextProperty(CharacterInfo *chaa, const char *property) { - return get_text_property_dynamic_string(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property); +const char *Character_GetTextProperty(CharacterInfo *chaa, const char *property) { + return get_text_property_dynamic_string(game.charProps[chaa->index_id], play.charProps[chaa->index_id], property); } -bool Character_SetProperty(CharacterInfo *chaa, const char *property, int value) -{ - return set_int_property(play.charProps[chaa->index_id], property, value); +bool Character_SetProperty(CharacterInfo *chaa, const char *property, int value) { + return set_int_property(play.charProps[chaa->index_id], property, value); } -bool Character_SetTextProperty(CharacterInfo *chaa, const char *property, const char *value) -{ - return set_text_property(play.charProps[chaa->index_id], property, value); +bool Character_SetTextProperty(CharacterInfo *chaa, const char *property, const char *value) { + return set_text_property(play.charProps[chaa->index_id], property, value); } -ScriptInvItem* Character_GetActiveInventory(CharacterInfo *chaa) { +ScriptInvItem *Character_GetActiveInventory(CharacterInfo *chaa) { - if (chaa->activeinv <= 0) - return nullptr; + if (chaa->activeinv <= 0) + return nullptr; - return &scrInv[chaa->activeinv]; + return &scrInv[chaa->activeinv]; } -void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem* iit) { - guis_need_update = 1; +void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem *iit) { + guis_need_update = 1; - if (iit == nullptr) { - chaa->activeinv = -1; + if (iit == nullptr) { + chaa->activeinv = -1; - if (chaa->index_id == game.playercharacter) { + if (chaa->index_id == game.playercharacter) { - if (GetCursorMode()==MODE_USE) - set_cursor_mode(0); - } - return; - } + if (GetCursorMode() == MODE_USE) + set_cursor_mode(0); + } + return; + } - if (chaa->inv[iit->id] < 1) - { - debug_script_warn("SetActiveInventory: character doesn't have any of that inventory"); - return; - } + if (chaa->inv[iit->id] < 1) { + debug_script_warn("SetActiveInventory: character doesn't have any of that inventory"); + return; + } - chaa->activeinv = iit->id; + chaa->activeinv = iit->id; - if (chaa->index_id == game.playercharacter) { - // if it's the player character, update mouse cursor - update_inv_cursor(iit->id); - set_cursor_mode(MODE_USE); - } + if (chaa->index_id == game.playercharacter) { + // if it's the player character, update mouse cursor + update_inv_cursor(iit->id); + set_cursor_mode(MODE_USE); + } } int Character_GetAnimating(CharacterInfo *chaa) { - if (chaa->animating) - return 1; - return 0; + if (chaa->animating) + return 1; + return 0; } int Character_GetAnimationSpeed(CharacterInfo *chaa) { - return chaa->animspeed; + return chaa->animspeed; } void Character_SetAnimationSpeed(CharacterInfo *chaa, int newval) { - chaa->animspeed = newval; + chaa->animspeed = newval; } int Character_GetBaseline(CharacterInfo *chaa) { - if (chaa->baseline < 1) - return 0; + if (chaa->baseline < 1) + return 0; - return chaa->baseline; + return chaa->baseline; } void Character_SetBaseline(CharacterInfo *chaa, int basel) { - chaa->baseline = basel; + chaa->baseline = basel; } int Character_GetBlinkInterval(CharacterInfo *chaa) { - return chaa->blinkinterval; + return chaa->blinkinterval; } void Character_SetBlinkInterval(CharacterInfo *chaa, int interval) { - if (interval < 0) - quit("!SetCharacterBlinkView: invalid blink interval"); + if (interval < 0) + quit("!SetCharacterBlinkView: invalid blink interval"); - chaa->blinkinterval = interval; + chaa->blinkinterval = interval; - if (chaa->blinktimer > 0) - chaa->blinktimer = chaa->blinkinterval; + if (chaa->blinktimer > 0) + chaa->blinktimer = chaa->blinkinterval; } int Character_GetBlinkView(CharacterInfo *chaa) { - return chaa->blinkview + 1; + return chaa->blinkview + 1; } void Character_SetBlinkView(CharacterInfo *chaa, int vii) { - if (((vii < 2) || (vii > game.numviews)) && (vii != -1)) - quit("!SetCharacterBlinkView: invalid view number"); + if (((vii < 2) || (vii > game.numviews)) && (vii != -1)) + quit("!SetCharacterBlinkView: invalid view number"); - chaa->blinkview = vii - 1; + chaa->blinkview = vii - 1; } int Character_GetBlinkWhileThinking(CharacterInfo *chaa) { - if (chaa->flags & CHF_NOBLINKANDTHINK) - return 0; - return 1; + if (chaa->flags & CHF_NOBLINKANDTHINK) + return 0; + return 1; } void Character_SetBlinkWhileThinking(CharacterInfo *chaa, int yesOrNo) { - chaa->flags &= ~CHF_NOBLINKANDTHINK; - if (yesOrNo == 0) - chaa->flags |= CHF_NOBLINKANDTHINK; + chaa->flags &= ~CHF_NOBLINKANDTHINK; + if (yesOrNo == 0) + chaa->flags |= CHF_NOBLINKANDTHINK; } int Character_GetBlockingHeight(CharacterInfo *chaa) { - return chaa->blocking_height; + return chaa->blocking_height; } void Character_SetBlockingHeight(CharacterInfo *chaa, int hit) { - chaa->blocking_height = hit; + chaa->blocking_height = hit; } int Character_GetBlockingWidth(CharacterInfo *chaa) { - return chaa->blocking_width; + return chaa->blocking_width; } void Character_SetBlockingWidth(CharacterInfo *chaa, int wid) { - chaa->blocking_width = wid; + chaa->blocking_width = wid; } int Character_GetDiagonalWalking(CharacterInfo *chaa) { - if (chaa->flags & CHF_NODIAGONAL) - return 0; - return 1; + if (chaa->flags & CHF_NODIAGONAL) + return 0; + return 1; } void Character_SetDiagonalWalking(CharacterInfo *chaa, int yesorno) { - chaa->flags &= ~CHF_NODIAGONAL; - if (!yesorno) - chaa->flags |= CHF_NODIAGONAL; + chaa->flags &= ~CHF_NODIAGONAL; + if (!yesorno) + chaa->flags |= CHF_NODIAGONAL; } int Character_GetClickable(CharacterInfo *chaa) { - if (chaa->flags & CHF_NOINTERACT) - return 0; - return 1; + if (chaa->flags & CHF_NOINTERACT) + return 0; + return 1; } void Character_SetClickable(CharacterInfo *chaa, int clik) { - chaa->flags &= ~CHF_NOINTERACT; - // if they don't want it clickable, set the relevant bit - if (clik == 0) - chaa->flags |= CHF_NOINTERACT; + chaa->flags &= ~CHF_NOINTERACT; + // if they don't want it clickable, set the relevant bit + if (clik == 0) + chaa->flags |= CHF_NOINTERACT; } int Character_GetID(CharacterInfo *chaa) { - return chaa->index_id; + return chaa->index_id; } int Character_GetFrame(CharacterInfo *chaa) { - return chaa->frame; + return chaa->frame; } void Character_SetFrame(CharacterInfo *chaa, int newval) { - chaa->frame = newval; + chaa->frame = newval; } int Character_GetIdleView(CharacterInfo *chaa) { - if (chaa->idleview < 1) - return -1; + if (chaa->idleview < 1) + return -1; - return chaa->idleview + 1; + return chaa->idleview + 1; } int Character_GetIInventoryQuantity(CharacterInfo *chaa, int index) { - if ((index < 1) || (index >= game.numinvitems)) - quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index); + if ((index < 1) || (index >= game.numinvitems)) + quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index); - return chaa->inv[index]; + return chaa->inv[index]; } -int Character_HasInventory(CharacterInfo *chaa, ScriptInvItem *invi) -{ - if (invi == nullptr) - quit("!Character.HasInventory: NULL inventory item supplied"); +int Character_HasInventory(CharacterInfo *chaa, ScriptInvItem *invi) { + if (invi == nullptr) + quit("!Character.HasInventory: NULL inventory item supplied"); - return (chaa->inv[invi->id] > 0) ? 1 : 0; + return (chaa->inv[invi->id] > 0) ? 1 : 0; } void Character_SetIInventoryQuantity(CharacterInfo *chaa, int index, int quant) { - if ((index < 1) || (index >= game.numinvitems)) - quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index); + if ((index < 1) || (index >= game.numinvitems)) + quitprintf("!Character.InventoryQuantity: invalid inventory index %d", index); - if ((quant < 0) || (quant > 32000)) - quitprintf("!Character.InventoryQuantity: invalid quantity %d", quant); + if ((quant < 0) || (quant > 32000)) + quitprintf("!Character.InventoryQuantity: invalid quantity %d", quant); - chaa->inv[index] = quant; + chaa->inv[index] = quant; } int Character_GetIgnoreLighting(CharacterInfo *chaa) { - if (chaa->flags & CHF_NOLIGHTING) - return 1; - return 0; + if (chaa->flags & CHF_NOLIGHTING) + return 1; + return 0; } void Character_SetIgnoreLighting(CharacterInfo *chaa, int yesorno) { - chaa->flags &= ~CHF_NOLIGHTING; - if (yesorno) - chaa->flags |= CHF_NOLIGHTING; + chaa->flags &= ~CHF_NOLIGHTING; + if (yesorno) + chaa->flags |= CHF_NOLIGHTING; } int Character_GetIgnoreScaling(CharacterInfo *chaa) { - if (chaa->flags & CHF_MANUALSCALING) - return 1; - return 0; + if (chaa->flags & CHF_MANUALSCALING) + return 1; + return 0; } void Character_SetIgnoreScaling(CharacterInfo *chaa, int yesorno) { - if (yesorno) { - // when setting IgnoreScaling to 1, should reset zoom level - // like it used to in pre-2.71 - charextra[chaa->index_id].zoom = 100; - } - Character_SetManualScaling(chaa, yesorno); + if (yesorno) { + // when setting IgnoreScaling to 1, should reset zoom level + // like it used to in pre-2.71 + charextra[chaa->index_id].zoom = 100; + } + Character_SetManualScaling(chaa, yesorno); } void Character_SetManualScaling(CharacterInfo *chaa, int yesorno) { - chaa->flags &= ~CHF_MANUALSCALING; - if (yesorno) - chaa->flags |= CHF_MANUALSCALING; + chaa->flags &= ~CHF_MANUALSCALING; + if (yesorno) + chaa->flags |= CHF_MANUALSCALING; } int Character_GetIgnoreWalkbehinds(CharacterInfo *chaa) { - if (chaa->flags & CHF_NOWALKBEHINDS) - return 1; - return 0; + if (chaa->flags & CHF_NOWALKBEHINDS) + return 1; + return 0; } void Character_SetIgnoreWalkbehinds(CharacterInfo *chaa, int yesorno) { - if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v350) - debug_script_warn("IgnoreWalkbehinds is not recommended for use, consider other solutions"); - chaa->flags &= ~CHF_NOWALKBEHINDS; - if (yesorno) - chaa->flags |= CHF_NOWALKBEHINDS; + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v350) + debug_script_warn("IgnoreWalkbehinds is not recommended for use, consider other solutions"); + chaa->flags &= ~CHF_NOWALKBEHINDS; + if (yesorno) + chaa->flags |= CHF_NOWALKBEHINDS; } int Character_GetMovementLinkedToAnimation(CharacterInfo *chaa) { - if (chaa->flags & CHF_ANTIGLIDE) - return 1; - return 0; + if (chaa->flags & CHF_ANTIGLIDE) + return 1; + return 0; } void Character_SetMovementLinkedToAnimation(CharacterInfo *chaa, int yesorno) { - chaa->flags &= ~CHF_ANTIGLIDE; - if (yesorno) - chaa->flags |= CHF_ANTIGLIDE; + chaa->flags &= ~CHF_ANTIGLIDE; + if (yesorno) + chaa->flags |= CHF_ANTIGLIDE; } int Character_GetLoop(CharacterInfo *chaa) { - return chaa->loop; + return chaa->loop; } void Character_SetLoop(CharacterInfo *chaa, int newval) { - if ((newval < 0) || (newval >= views[chaa->view].numLoops)) - quit("!Character.Loop: invalid loop number for this view"); + if ((newval < 0) || (newval >= views[chaa->view].numLoops)) + quit("!Character.Loop: invalid loop number for this view"); - chaa->loop = newval; + chaa->loop = newval; - if (chaa->frame >= views[chaa->view].loops[chaa->loop].numFrames) - chaa->frame = 0; + if (chaa->frame >= views[chaa->view].loops[chaa->loop].numFrames) + chaa->frame = 0; } int Character_GetMoving(CharacterInfo *chaa) { - if (chaa->walking) - return 1; - return 0; + if (chaa->walking) + return 1; + return 0; } int Character_GetDestinationX(CharacterInfo *chaa) { - if (chaa->walking) { - MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; - return cmls->pos[cmls->numstage - 1] >> 16; - } - else - return chaa->x; + if (chaa->walking) { + MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; + return cmls->pos[cmls->numstage - 1] >> 16; + } else + return chaa->x; } int Character_GetDestinationY(CharacterInfo *chaa) { - if (chaa->walking) { - MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; - return cmls->pos[cmls->numstage - 1] & 0xFFFF; - } - else - return chaa->y; + if (chaa->walking) { + MoveList *cmls = &mls[chaa->walking % TURNING_AROUND]; + return cmls->pos[cmls->numstage - 1] & 0xFFFF; + } else + return chaa->y; } -const char* Character_GetName(CharacterInfo *chaa) { - return CreateNewScriptString(chaa->name); +const char *Character_GetName(CharacterInfo *chaa) { + return CreateNewScriptString(chaa->name); } void Character_SetName(CharacterInfo *chaa, const char *newName) { - strncpy(chaa->name, newName, 40); - chaa->name[39] = 0; + strncpy(chaa->name, newName, 40); + chaa->name[39] = 0; } int Character_GetNormalView(CharacterInfo *chaa) { - return chaa->defview + 1; + return chaa->defview + 1; } int Character_GetPreviousRoom(CharacterInfo *chaa) { - return chaa->prevroom; + return chaa->prevroom; } int Character_GetRoom(CharacterInfo *chaa) { - return chaa->room; + return chaa->room; } int Character_GetScaleMoveSpeed(CharacterInfo *chaa) { - if (chaa->flags & CHF_SCALEMOVESPEED) - return 1; - return 0; + if (chaa->flags & CHF_SCALEMOVESPEED) + return 1; + return 0; } void Character_SetScaleMoveSpeed(CharacterInfo *chaa, int yesorno) { - if ((yesorno < 0) || (yesorno > 1)) - quit("Character.ScaleMoveSpeed: value must be true or false (1 or 0)"); + if ((yesorno < 0) || (yesorno > 1)) + quit("Character.ScaleMoveSpeed: value must be true or false (1 or 0)"); - chaa->flags &= ~CHF_SCALEMOVESPEED; - if (yesorno) - chaa->flags |= CHF_SCALEMOVESPEED; + chaa->flags &= ~CHF_SCALEMOVESPEED; + if (yesorno) + chaa->flags |= CHF_SCALEMOVESPEED; } int Character_GetScaleVolume(CharacterInfo *chaa) { - if (chaa->flags & CHF_SCALEVOLUME) - return 1; - return 0; + if (chaa->flags & CHF_SCALEVOLUME) + return 1; + return 0; } void Character_SetScaleVolume(CharacterInfo *chaa, int yesorno) { - if ((yesorno < 0) || (yesorno > 1)) - quit("Character.ScaleVolume: value must be true or false (1 or 0)"); + if ((yesorno < 0) || (yesorno > 1)) + quit("Character.ScaleVolume: value must be true or false (1 or 0)"); - chaa->flags &= ~CHF_SCALEVOLUME; - if (yesorno) - chaa->flags |= CHF_SCALEVOLUME; + chaa->flags &= ~CHF_SCALEVOLUME; + if (yesorno) + chaa->flags |= CHF_SCALEVOLUME; } int Character_GetScaling(CharacterInfo *chaa) { - return charextra[chaa->index_id].zoom; + return charextra[chaa->index_id].zoom; } void Character_SetScaling(CharacterInfo *chaa, int zoomlevel) { - if ((chaa->flags & CHF_MANUALSCALING) == 0) - { - debug_script_warn("Character.Scaling: cannot set property unless ManualScaling is enabled"); - return; - } - if ((zoomlevel < 5) || (zoomlevel > 200)) - quit("!Character.Scaling: scaling level must be between 5 and 200%"); + if ((chaa->flags & CHF_MANUALSCALING) == 0) { + debug_script_warn("Character.Scaling: cannot set property unless ManualScaling is enabled"); + return; + } + if ((zoomlevel < 5) || (zoomlevel > 200)) + quit("!Character.Scaling: scaling level must be between 5 and 200%"); - charextra[chaa->index_id].zoom = zoomlevel; + charextra[chaa->index_id].zoom = zoomlevel; } int Character_GetSolid(CharacterInfo *chaa) { - if (chaa->flags & CHF_NOBLOCKING) - return 0; - return 1; + if (chaa->flags & CHF_NOBLOCKING) + return 0; + return 1; } void Character_SetSolid(CharacterInfo *chaa, int yesorno) { - chaa->flags &= ~CHF_NOBLOCKING; - if (!yesorno) - chaa->flags |= CHF_NOBLOCKING; + chaa->flags &= ~CHF_NOBLOCKING; + if (!yesorno) + chaa->flags |= CHF_NOBLOCKING; } int Character_GetSpeaking(CharacterInfo *chaa) { - if (get_character_currently_talking() == chaa->index_id) - return 1; + if (get_character_currently_talking() == chaa->index_id) + return 1; - return 0; + return 0; } int Character_GetSpeechColor(CharacterInfo *chaa) { - return chaa->talkcolor; + return chaa->talkcolor; } void Character_SetSpeechColor(CharacterInfo *chaa, int ncol) { - chaa->talkcolor = ncol; + chaa->talkcolor = ncol; } -void Character_SetSpeechAnimationDelay(CharacterInfo *chaa, int newDelay) -{ - if (game.options[OPT_GLOBALTALKANIMSPD] != 0) - { - debug_script_warn("Character.SpeechAnimationDelay cannot be set when global speech animation speed is enabled"); - return; - } +void Character_SetSpeechAnimationDelay(CharacterInfo *chaa, int newDelay) { + if (game.options[OPT_GLOBALTALKANIMSPD] != 0) { + debug_script_warn("Character.SpeechAnimationDelay cannot be set when global speech animation speed is enabled"); + return; + } - chaa->speech_anim_speed = newDelay; + chaa->speech_anim_speed = newDelay; } int Character_GetSpeechView(CharacterInfo *chaa) { - return chaa->talkview + 1; + return chaa->talkview + 1; } void Character_SetSpeechView(CharacterInfo *chaa, int vii) { - if (vii == -1) { - chaa->talkview = -1; - return; - } + if (vii == -1) { + chaa->talkview = -1; + return; + } - if ((vii < 1) || (vii > game.numviews)) - quit("!SetCharacterSpeechView: invalid view number"); + if ((vii < 1) || (vii > game.numviews)) + quit("!SetCharacterSpeechView: invalid view number"); - chaa->talkview = vii - 1; + chaa->talkview = vii - 1; } -bool Character_GetThinking(CharacterInfo *chaa) -{ - return char_thinking == chaa->index_id; +bool Character_GetThinking(CharacterInfo *chaa) { + return char_thinking == chaa->index_id; } -int Character_GetThinkingFrame(CharacterInfo *chaa) -{ - if (char_thinking == chaa->index_id) - return chaa->thinkview > 0 ? chaa->frame : -1; +int Character_GetThinkingFrame(CharacterInfo *chaa) { + if (char_thinking == chaa->index_id) + return chaa->thinkview > 0 ? chaa->frame : -1; - debug_script_warn("Character.ThinkingFrame: character is not currently thinking"); - return -1; + debug_script_warn("Character.ThinkingFrame: character is not currently thinking"); + return -1; } int Character_GetThinkView(CharacterInfo *chaa) { - return chaa->thinkview + 1; + return chaa->thinkview + 1; } void Character_SetThinkView(CharacterInfo *chaa, int vii) { - if (((vii < 2) || (vii > game.numviews)) && (vii != -1)) - quit("!SetCharacterThinkView: invalid view number"); + if (((vii < 2) || (vii > game.numviews)) && (vii != -1)) + quit("!SetCharacterThinkView: invalid view number"); - chaa->thinkview = vii - 1; + chaa->thinkview = vii - 1; } int Character_GetTransparency(CharacterInfo *chaa) { - return GfxDef::LegacyTrans255ToTrans100(chaa->transparency); + return GfxDef::LegacyTrans255ToTrans100(chaa->transparency); } void Character_SetTransparency(CharacterInfo *chaa, int trans) { - if ((trans < 0) || (trans > 100)) - quit("!SetCharTransparent: transparency value must be between 0 and 100"); + if ((trans < 0) || (trans > 100)) + quit("!SetCharTransparent: transparency value must be between 0 and 100"); - chaa->transparency = GfxDef::Trans100ToLegacyTrans255(trans); + chaa->transparency = GfxDef::Trans100ToLegacyTrans255(trans); } int Character_GetTurnBeforeWalking(CharacterInfo *chaa) { - if (chaa->flags & CHF_NOTURNING) - return 0; - return 1; + if (chaa->flags & CHF_NOTURNING) + return 0; + return 1; } void Character_SetTurnBeforeWalking(CharacterInfo *chaa, int yesorno) { - chaa->flags &= ~CHF_NOTURNING; - if (!yesorno) - chaa->flags |= CHF_NOTURNING; + chaa->flags &= ~CHF_NOTURNING; + if (!yesorno) + chaa->flags |= CHF_NOTURNING; } int Character_GetView(CharacterInfo *chaa) { - return chaa->view + 1; + return chaa->view + 1; } int Character_GetWalkSpeedX(CharacterInfo *chaa) { - return chaa->walkspeed; + return chaa->walkspeed; } int Character_GetWalkSpeedY(CharacterInfo *chaa) { - if (chaa->walkspeed_y != UNIFORM_WALK_SPEED) - return chaa->walkspeed_y; + if (chaa->walkspeed_y != UNIFORM_WALK_SPEED) + return chaa->walkspeed_y; - return chaa->walkspeed; + return chaa->walkspeed; } int Character_GetX(CharacterInfo *chaa) { - return chaa->x; + return chaa->x; } void Character_SetX(CharacterInfo *chaa, int newval) { - chaa->x = newval; + chaa->x = newval; } int Character_GetY(CharacterInfo *chaa) { - return chaa->y; + return chaa->y; } void Character_SetY(CharacterInfo *chaa, int newval) { - chaa->y = newval; + chaa->y = newval; } int Character_GetZ(CharacterInfo *chaa) { - return chaa->z; + return chaa->z; } void Character_SetZ(CharacterInfo *chaa, int newval) { - chaa->z = newval; + chaa->z = newval; } extern int char_speaking; int Character_GetSpeakingFrame(CharacterInfo *chaa) { - if ((face_talking >= 0) && (facetalkrepeat)) - { - if (facetalkchar->index_id == chaa->index_id) - { - return facetalkframe; - } - } - else if (char_speaking >= 0) - { - if (char_speaking == chaa->index_id) - { - return chaa->frame; - } - } - - debug_script_warn("Character.SpeakingFrame: character is not currently speaking"); - return -1; + if ((face_talking >= 0) && (facetalkrepeat)) { + if (facetalkchar->index_id == chaa->index_id) { + return facetalkframe; + } + } else if (char_speaking >= 0) { + if (char_speaking == chaa->index_id) { + return chaa->frame; + } + } + + debug_script_warn("Character.SpeakingFrame: character is not currently speaking"); + return -1; } //============================================================================= @@ -1672,1285 +1604,1240 @@ int Character_GetSpeakingFrame(CharacterInfo *chaa) { // order of loops to turn character in circle from down to down int turnlooporder[8] = {0, 6, 1, 7, 3, 5, 2, 4}; -void walk_character(int chac,int tox,int toy,int ignwal, bool autoWalkAnims) { - CharacterInfo*chin=&game.chars[chac]; - if (chin->room!=displayed_room) - quit("!MoveCharacter: character not in current room"); - - chin->flags &= ~CHF_MOVENOTWALK; - - int toxPassedIn = tox, toyPassedIn = toy; - int charX = room_to_mask_coord(chin->x); - int charY = room_to_mask_coord(chin->y); - tox = room_to_mask_coord(tox); - toy = room_to_mask_coord(toy); - - if ((tox == charX) && (toy == charY)) { - StopMoving(chac); - debug_script_log("%s already at destination, not moving", chin->scrname); - return; - } - - if ((chin->animating) && (autoWalkAnims)) - chin->animating = 0; - - if (chin->idleleft < 0) { - ReleaseCharacterView(chac); - chin->idleleft=chin->idletime; - } - // stop them to make sure they're on a walkable area - // but save their frame first so that if they're already - // moving it looks smoother - int oldframe = chin->frame; - int waitWas = 0, animWaitWas = 0; - // if they are currently walking, save the current Wait - if (chin->walking) - { - waitWas = chin->walkwait; - animWaitWas = charextra[chac].animwait; - } - - StopMoving (chac); - chin->frame = oldframe; - // use toxPassedIn cached variable so the hi-res co-ordinates - // are still displayed as such - debug_script_log("%s: Start move to %d,%d", chin->scrname, toxPassedIn, toyPassedIn); - - int move_speed_x = chin->walkspeed; - int move_speed_y = chin->walkspeed; - - if (chin->walkspeed_y != UNIFORM_WALK_SPEED) - move_speed_y = chin->walkspeed_y; - - if ((move_speed_x == 0) && (move_speed_y == 0)) { - debug_script_warn("Warning: MoveCharacter called for '%s' with walk speed 0", chin->name); - } - - set_route_move_speed(move_speed_x, move_speed_y); - set_color_depth(8); - int mslot=find_route(charX, charY, tox, toy, prepare_walkable_areas(chac), chac+CHMLSOFFS, 1, ignwal); - set_color_depth(game.GetColorDepth()); - if (mslot>0) { - chin->walking = mslot; - mls[mslot].direct = ignwal; - convert_move_path_to_room_resolution(&mls[mslot]); - - // cancel any pending waits on current animations - // or if they were already moving, keep the current wait - - // this prevents a glitch if MoveCharacter is called when they - // are already moving - if (autoWalkAnims) - { - chin->walkwait = waitWas; - charextra[chac].animwait = animWaitWas; - - if (mls[mslot].pos[0] != mls[mslot].pos[1]) { - fix_player_sprite(&mls[mslot],chin); - } - } - else - chin->flags |= CHF_MOVENOTWALK; - } - else if (autoWalkAnims) // pathfinder couldn't get a route, stand them still - chin->frame = 0; -} - -int find_looporder_index (int curloop) { - int rr; - for (rr = 0; rr < 8; rr++) { - if (turnlooporder[rr] == curloop) - return rr; - } - return 0; +void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims) { + CharacterInfo *chin = &game.chars[chac]; + if (chin->room != displayed_room) + quit("!MoveCharacter: character not in current room"); + + chin->flags &= ~CHF_MOVENOTWALK; + + int toxPassedIn = tox, toyPassedIn = toy; + int charX = room_to_mask_coord(chin->x); + int charY = room_to_mask_coord(chin->y); + tox = room_to_mask_coord(tox); + toy = room_to_mask_coord(toy); + + if ((tox == charX) && (toy == charY)) { + StopMoving(chac); + debug_script_log("%s already at destination, not moving", chin->scrname); + return; + } + + if ((chin->animating) && (autoWalkAnims)) + chin->animating = 0; + + if (chin->idleleft < 0) { + ReleaseCharacterView(chac); + chin->idleleft = chin->idletime; + } + // stop them to make sure they're on a walkable area + // but save their frame first so that if they're already + // moving it looks smoother + int oldframe = chin->frame; + int waitWas = 0, animWaitWas = 0; + // if they are currently walking, save the current Wait + if (chin->walking) { + waitWas = chin->walkwait; + animWaitWas = charextra[chac].animwait; + } + + StopMoving(chac); + chin->frame = oldframe; + // use toxPassedIn cached variable so the hi-res co-ordinates + // are still displayed as such + debug_script_log("%s: Start move to %d,%d", chin->scrname, toxPassedIn, toyPassedIn); + + int move_speed_x = chin->walkspeed; + int move_speed_y = chin->walkspeed; + + if (chin->walkspeed_y != UNIFORM_WALK_SPEED) + move_speed_y = chin->walkspeed_y; + + if ((move_speed_x == 0) && (move_speed_y == 0)) { + debug_script_warn("Warning: MoveCharacter called for '%s' with walk speed 0", chin->name); + } + + set_route_move_speed(move_speed_x, move_speed_y); + set_color_depth(8); + int mslot = find_route(charX, charY, tox, toy, prepare_walkable_areas(chac), chac + CHMLSOFFS, 1, ignwal); + set_color_depth(game.GetColorDepth()); + if (mslot > 0) { + chin->walking = mslot; + mls[mslot].direct = ignwal; + convert_move_path_to_room_resolution(&mls[mslot]); + + // cancel any pending waits on current animations + // or if they were already moving, keep the current wait - + // this prevents a glitch if MoveCharacter is called when they + // are already moving + if (autoWalkAnims) { + chin->walkwait = waitWas; + charextra[chac].animwait = animWaitWas; + + if (mls[mslot].pos[0] != mls[mslot].pos[1]) { + fix_player_sprite(&mls[mslot], chin); + } + } else + chin->flags |= CHF_MOVENOTWALK; + } else if (autoWalkAnims) // pathfinder couldn't get a route, stand them still + chin->frame = 0; +} + +int find_looporder_index(int curloop) { + int rr; + for (rr = 0; rr < 8; rr++) { + if (turnlooporder[rr] == curloop) + return rr; + } + return 0; } // returns 0 to use diagonal, 1 to not -int useDiagonal (CharacterInfo *char1) { - if ((views[char1->view].numLoops < 8) || ((char1->flags & CHF_NODIAGONAL)!=0)) - return 1; - // If they have just provided standing frames for loops 4-7, to - // provide smoother turning - if (views[char1->view].loops[4].numFrames < 2) - return 2; - return 0; +int useDiagonal(CharacterInfo *char1) { + if ((views[char1->view].numLoops < 8) || ((char1->flags & CHF_NODIAGONAL) != 0)) + return 1; + // If they have just provided standing frames for loops 4-7, to + // provide smoother turning + if (views[char1->view].loops[4].numFrames < 2) + return 2; + return 0; } // returns 1 normally, or 0 if they only have horizontal animations int hasUpDownLoops(CharacterInfo *char1) { - // if no loops in the Down animation - // or no loops in the Up animation - if ((views[char1->view].loops[0].numFrames < 1) || - (views[char1->view].numLoops < 4) || - (views[char1->view].loops[3].numFrames < 1)) - { - return 0; - } - - return 1; -} - -void start_character_turning (CharacterInfo *chinf, int useloop, int no_diagonal) { - // work out how far round they have to turn - int fromidx = find_looporder_index (chinf->loop); - int toidx = find_looporder_index (useloop); - //Display("Curloop: %d, needloop: %d",chinf->loop, useloop); - int ii, go_anticlock = 0; - // work out whether anticlockwise is quicker or not - if ((toidx > fromidx) && ((toidx - fromidx) > 4)) - go_anticlock = 1; - if ((toidx < fromidx) && ((fromidx - toidx) < 4)) - go_anticlock = 1; - // strip any current turning_around stages - chinf->walking = chinf->walking % TURNING_AROUND; - if (go_anticlock) - chinf->walking += TURNING_BACKWARDS; - else - go_anticlock = -1; - - // Allow the diagonal frames just for turning - if (no_diagonal == 2) - no_diagonal = 0; - - for (ii = fromidx; ii != toidx; ii -= go_anticlock) { - if (ii < 0) - ii = 7; - if (ii >= 8) - ii = 0; - if (ii == toidx) - break; - if ((turnlooporder[ii] >= 4) && (no_diagonal > 0)) - continue; - if (views[chinf->view].loops[turnlooporder[ii]].numFrames < 1) - continue; - if (turnlooporder[ii] < views[chinf->view].numLoops) - chinf->walking += TURNING_AROUND; - } - -} - -void fix_player_sprite(MoveList*cmls,CharacterInfo*chinf) { - const fixed xpmove = cmls->xpermove[cmls->onstage]; - const fixed ypmove = cmls->ypermove[cmls->onstage]; - - // if not moving, do nothing - if ((xpmove == 0) && (ypmove == 0)) - return; - - const int useloop = GetDirectionalLoop(chinf, xpmove, ypmove); - - if ((game.options[OPT_ROTATECHARS] == 0) || ((chinf->flags & CHF_NOTURNING) != 0)) { - chinf->loop = useloop; - return; - } - if ((chinf->loop > kDirLoop_LastOrthogonal) && ((chinf->flags & CHF_NODIAGONAL)!=0)) { - // They've just been playing an animation with an extended loop number, - // so don't try and rotate using it - chinf->loop = useloop; - return; - } - if ((chinf->loop >= views[chinf->view].numLoops) || - (views[chinf->view].loops[chinf->loop].numFrames < 1) || - (hasUpDownLoops(chinf) == 0)) { - // Character is not currently on a valid loop, so don't try to rotate - // eg. left/right only view, but current loop 0 - chinf->loop = useloop; - return; - } - const int no_diagonal = useDiagonal (chinf); - start_character_turning (chinf, useloop, no_diagonal); + // if no loops in the Down animation + // or no loops in the Up animation + if ((views[char1->view].loops[0].numFrames < 1) || + (views[char1->view].numLoops < 4) || + (views[char1->view].loops[3].numFrames < 1)) { + return 0; + } + + return 1; +} + +void start_character_turning(CharacterInfo *chinf, int useloop, int no_diagonal) { + // work out how far round they have to turn + int fromidx = find_looporder_index(chinf->loop); + int toidx = find_looporder_index(useloop); + //Display("Curloop: %d, needloop: %d",chinf->loop, useloop); + int ii, go_anticlock = 0; + // work out whether anticlockwise is quicker or not + if ((toidx > fromidx) && ((toidx - fromidx) > 4)) + go_anticlock = 1; + if ((toidx < fromidx) && ((fromidx - toidx) < 4)) + go_anticlock = 1; + // strip any current turning_around stages + chinf->walking = chinf->walking % TURNING_AROUND; + if (go_anticlock) + chinf->walking += TURNING_BACKWARDS; + else + go_anticlock = -1; + + // Allow the diagonal frames just for turning + if (no_diagonal == 2) + no_diagonal = 0; + + for (ii = fromidx; ii != toidx; ii -= go_anticlock) { + if (ii < 0) + ii = 7; + if (ii >= 8) + ii = 0; + if (ii == toidx) + break; + if ((turnlooporder[ii] >= 4) && (no_diagonal > 0)) + continue; + if (views[chinf->view].loops[turnlooporder[ii]].numFrames < 1) + continue; + if (turnlooporder[ii] < views[chinf->view].numLoops) + chinf->walking += TURNING_AROUND; + } + +} + +void fix_player_sprite(MoveList *cmls, CharacterInfo *chinf) { + const fixed xpmove = cmls->xpermove[cmls->onstage]; + const fixed ypmove = cmls->ypermove[cmls->onstage]; + + // if not moving, do nothing + if ((xpmove == 0) && (ypmove == 0)) + return; + + const int useloop = GetDirectionalLoop(chinf, xpmove, ypmove); + + if ((game.options[OPT_ROTATECHARS] == 0) || ((chinf->flags & CHF_NOTURNING) != 0)) { + chinf->loop = useloop; + return; + } + if ((chinf->loop > kDirLoop_LastOrthogonal) && ((chinf->flags & CHF_NODIAGONAL) != 0)) { + // They've just been playing an animation with an extended loop number, + // so don't try and rotate using it + chinf->loop = useloop; + return; + } + if ((chinf->loop >= views[chinf->view].numLoops) || + (views[chinf->view].loops[chinf->loop].numFrames < 1) || + (hasUpDownLoops(chinf) == 0)) { + // Character is not currently on a valid loop, so don't try to rotate + // eg. left/right only view, but current loop 0 + chinf->loop = useloop; + return; + } + const int no_diagonal = useDiagonal(chinf); + start_character_turning(chinf, useloop, no_diagonal); } // Check whether two characters have walked into each other int has_hit_another_character(int sourceChar) { - // if the character who's moving doesn't Bitmap *, don't bother checking - if (game.chars[sourceChar].flags & CHF_NOBLOCKING) - return -1; + // if the character who's moving doesn't Bitmap *, don't bother checking + if (game.chars[sourceChar].flags & CHF_NOBLOCKING) + return -1; - for (int ww = 0; ww < game.numcharacters; ww++) { - if (game.chars[ww].on != 1) continue; - if (game.chars[ww].room != displayed_room) continue; - if (ww == sourceChar) continue; - if (game.chars[ww].flags & CHF_NOBLOCKING) continue; + for (int ww = 0; ww < game.numcharacters; ww++) { + if (game.chars[ww].on != 1) continue; + if (game.chars[ww].room != displayed_room) continue; + if (ww == sourceChar) continue; + if (game.chars[ww].flags & CHF_NOBLOCKING) continue; - if (is_char_on_another (sourceChar, ww, nullptr, nullptr)) { - // we are now overlapping character 'ww' - if ((game.chars[ww].walking) && - ((game.chars[ww].flags & CHF_AWAITINGMOVE) == 0)) - return ww; - } + if (is_char_on_another(sourceChar, ww, nullptr, nullptr)) { + // we are now overlapping character 'ww' + if ((game.chars[ww].walking) && + ((game.chars[ww].flags & CHF_AWAITINGMOVE) == 0)) + return ww; + } - } - return -1; + } + return -1; } // Does the next move from the character's movelist. // Returns 1 if they are now waiting for another char to move, // otherwise returns 0 -int doNextCharMoveStep (CharacterInfo *chi, int &char_index, CharacterExtras *chex) { - int ntf=0, xwas = chi->x, ywas = chi->y; - - if (do_movelist_move(&chi->walking,&chi->x,&chi->y) == 2) - { - if ((chi->flags & CHF_MOVENOTWALK) == 0) - fix_player_sprite(&mls[chi->walking], chi); - } - - ntf = has_hit_another_character(char_index); - if (ntf >= 0) { - chi->walkwait = 30; - if (game.chars[ntf].walkspeed < 5) - chi->walkwait += (5 - game.chars[ntf].walkspeed) * 5; - // we are now waiting for the other char to move, so - // make sure he doesn't stop for us too - - chi->flags |= CHF_AWAITINGMOVE; - - if ((chi->flags & CHF_MOVENOTWALK) == 0) - { - chi->frame = 0; - chex->animwait = chi->walkwait; - } - - if ((chi->walking < 1) || (chi->walking >= TURNING_AROUND)) ; - else if (mls[chi->walking].onpart > 0) { - mls[chi->walking].onpart --; - chi->x = xwas; - chi->y = ywas; - } - debug_script_log("%s: Bumped into %s, waiting for them to move", chi->scrname, game.chars[ntf].scrname); - return 1; - } - return 0; -} - -int find_nearest_walkable_area_within(int *xx, int *yy, int range, int step) -{ - int ex, ey, nearest = 99999, thisis, nearx = 0, neary = 0; - int startx = 0, starty = 14; - int roomWidthLowRes = room_to_mask_coord(thisroom.Width); - int roomHeightLowRes = room_to_mask_coord(thisroom.Height); - int xwidth = roomWidthLowRes, yheight = roomHeightLowRes; - - int xLowRes = room_to_mask_coord(xx[0]); - int yLowRes = room_to_mask_coord(yy[0]); - int rightEdge = room_to_mask_coord(thisroom.Edges.Right); - int leftEdge = room_to_mask_coord(thisroom.Edges.Left); - int topEdge = room_to_mask_coord(thisroom.Edges.Top); - int bottomEdge = room_to_mask_coord(thisroom.Edges.Bottom); - - // tweak because people forget to move the edges sometimes - // if the player is already over the edge, ignore it - if (xLowRes >= rightEdge) rightEdge = roomWidthLowRes; - if (xLowRes <= leftEdge) leftEdge = 0; - if (yLowRes >= bottomEdge) bottomEdge = roomHeightLowRes; - if (yLowRes <= topEdge) topEdge = 0; - - if (range > 0) - { - startx = xLowRes - range; - starty = yLowRes - range; - xwidth = startx + range * 2; - yheight = starty + range * 2; - if (startx < 0) startx = 0; - if (starty < 10) starty = 10; - if (xwidth > roomWidthLowRes) xwidth = roomWidthLowRes; - if (yheight > roomHeightLowRes) yheight = roomHeightLowRes; - } - - for (ex = startx; ex < xwidth; ex += step) { - for (ey = starty; ey < yheight; ey += step) { - // non-walkalbe, so don't go here - if (thisroom.WalkAreaMask->GetPixel(ex,ey) == 0) continue; - // off a screen edge, don't move them there - if ((ex <= leftEdge) || (ex >= rightEdge) || - (ey <= topEdge) || (ey >= bottomEdge)) - continue; - // otherwise, calculate distance from target - thisis=(int) ::sqrt((double)((ex - xLowRes) * (ex - xLowRes) + (ey - yLowRes) * (ey - yLowRes))); - if (thisisGetPixel(room_to_mask_coord(xx[0]), room_to_mask_coord(yy[0])); - // only fix this code if the game was built with 2.61 or above - if (pixValue == 0 || (loaded_game_file_version >= kGameVersion_261 && pixValue < 1)) - { - // First, check every 2 pixels within immediate area - if (!find_nearest_walkable_area_within(xx, yy, 20, 2)) - { - // If not, check whole screen at 5 pixel intervals - find_nearest_walkable_area_within(xx, yy, -1, 5); - } - } +int doNextCharMoveStep(CharacterInfo *chi, int &char_index, CharacterExtras *chex) { + int ntf = 0, xwas = chi->x, ywas = chi->y; + + if (do_movelist_move(&chi->walking, &chi->x, &chi->y) == 2) { + if ((chi->flags & CHF_MOVENOTWALK) == 0) + fix_player_sprite(&mls[chi->walking], chi); + } + + ntf = has_hit_another_character(char_index); + if (ntf >= 0) { + chi->walkwait = 30; + if (game.chars[ntf].walkspeed < 5) + chi->walkwait += (5 - game.chars[ntf].walkspeed) * 5; + // we are now waiting for the other char to move, so + // make sure he doesn't stop for us too + + chi->flags |= CHF_AWAITINGMOVE; + + if ((chi->flags & CHF_MOVENOTWALK) == 0) { + chi->frame = 0; + chex->animwait = chi->walkwait; + } + + if ((chi->walking < 1) || (chi->walking >= TURNING_AROUND)) ; + else if (mls[chi->walking].onpart > 0) { + mls[chi->walking].onpart --; + chi->x = xwas; + chi->y = ywas; + } + debug_script_log("%s: Bumped into %s, waiting for them to move", chi->scrname, game.chars[ntf].scrname); + return 1; + } + return 0; +} + +int find_nearest_walkable_area_within(int *xx, int *yy, int range, int step) { + int ex, ey, nearest = 99999, thisis, nearx = 0, neary = 0; + int startx = 0, starty = 14; + int roomWidthLowRes = room_to_mask_coord(thisroom.Width); + int roomHeightLowRes = room_to_mask_coord(thisroom.Height); + int xwidth = roomWidthLowRes, yheight = roomHeightLowRes; + + int xLowRes = room_to_mask_coord(xx[0]); + int yLowRes = room_to_mask_coord(yy[0]); + int rightEdge = room_to_mask_coord(thisroom.Edges.Right); + int leftEdge = room_to_mask_coord(thisroom.Edges.Left); + int topEdge = room_to_mask_coord(thisroom.Edges.Top); + int bottomEdge = room_to_mask_coord(thisroom.Edges.Bottom); + + // tweak because people forget to move the edges sometimes + // if the player is already over the edge, ignore it + if (xLowRes >= rightEdge) rightEdge = roomWidthLowRes; + if (xLowRes <= leftEdge) leftEdge = 0; + if (yLowRes >= bottomEdge) bottomEdge = roomHeightLowRes; + if (yLowRes <= topEdge) topEdge = 0; + + if (range > 0) { + startx = xLowRes - range; + starty = yLowRes - range; + xwidth = startx + range * 2; + yheight = starty + range * 2; + if (startx < 0) startx = 0; + if (starty < 10) starty = 10; + if (xwidth > roomWidthLowRes) xwidth = roomWidthLowRes; + if (yheight > roomHeightLowRes) yheight = roomHeightLowRes; + } + + for (ex = startx; ex < xwidth; ex += step) { + for (ey = starty; ey < yheight; ey += step) { + // non-walkalbe, so don't go here + if (thisroom.WalkAreaMask->GetPixel(ex, ey) == 0) continue; + // off a screen edge, don't move them there + if ((ex <= leftEdge) || (ex >= rightEdge) || + (ey <= topEdge) || (ey >= bottomEdge)) + continue; + // otherwise, calculate distance from target + thisis = (int) ::sqrt((double)((ex - xLowRes) * (ex - xLowRes) + (ey - yLowRes) * (ey - yLowRes))); + if (thisis < nearest) { + nearest = thisis; + nearx = ex; + neary = ey; + } + } + } + if (nearest < 90000) { + xx[0] = mask_to_room_coord(nearx); + yy[0] = mask_to_room_coord(neary); + return 1; + } + + return 0; +} + +void find_nearest_walkable_area(int *xx, int *yy) { + + int pixValue = thisroom.WalkAreaMask->GetPixel(room_to_mask_coord(xx[0]), room_to_mask_coord(yy[0])); + // only fix this code if the game was built with 2.61 or above + if (pixValue == 0 || (loaded_game_file_version >= kGameVersion_261 && pixValue < 1)) { + // First, check every 2 pixels within immediate area + if (!find_nearest_walkable_area_within(xx, yy, 20, 2)) { + // If not, check whole screen at 5 pixel intervals + find_nearest_walkable_area_within(xx, yy, -1, 5); + } + } } void FindReasonableLoopForCharacter(CharacterInfo *chap) { - if (chap->loop >= views[chap->view].numLoops) - chap->loop=kDirLoop_Default; - if (views[chap->view].numLoops < 1) - quitprintf("!View %d does not have any loops", chap->view + 1); + if (chap->loop >= views[chap->view].numLoops) + chap->loop = kDirLoop_Default; + if (views[chap->view].numLoops < 1) + quitprintf("!View %d does not have any loops", chap->view + 1); - // if the current loop has no frames, find one that does - if (views[chap->view].loops[chap->loop].numFrames < 1) - { - for (int i = 0; i < views[chap->view].numLoops; i++) - { - if (views[chap->view].loops[i].numFrames > 0) { - chap->loop = i; - break; - } - } - } + // if the current loop has no frames, find one that does + if (views[chap->view].loops[chap->loop].numFrames < 1) { + for (int i = 0; i < views[chap->view].numLoops; i++) { + if (views[chap->view].loops[i].numFrames > 0) { + chap->loop = i; + break; + } + } + } } -void walk_or_move_character(CharacterInfo *chaa, int x, int y, int blocking, int direct, bool isWalk) -{ - if (chaa->on != 1) - { - debug_script_warn("MoveCharacterBlocking: character is turned off and cannot be moved"); - return; - } +void walk_or_move_character(CharacterInfo *chaa, int x, int y, int blocking, int direct, bool isWalk) { + if (chaa->on != 1) { + debug_script_warn("MoveCharacterBlocking: character is turned off and cannot be moved"); + return; + } - if ((direct == ANYWHERE) || (direct == 1)) - walk_character(chaa->index_id, x, y, 1, isWalk); - else if ((direct == WALKABLE_AREAS) || (direct == 0)) - walk_character(chaa->index_id, x, y, 0, isWalk); - else - quit("!Character.Walk: Direct must be ANYWHERE or WALKABLE_AREAS"); + if ((direct == ANYWHERE) || (direct == 1)) + walk_character(chaa->index_id, x, y, 1, isWalk); + else if ((direct == WALKABLE_AREAS) || (direct == 0)) + walk_character(chaa->index_id, x, y, 0, isWalk); + else + quit("!Character.Walk: Direct must be ANYWHERE or WALKABLE_AREAS"); - if ((blocking == BLOCKING) || (blocking == 1)) - GameLoopUntilNotMoving(&chaa->walking); - else if ((blocking != IN_BACKGROUND) && (blocking != 0)) - quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND"); + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilNotMoving(&chaa->walking); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("!Character.Walk: Blocking must be BLOCKING or IN_BACKGRUOND"); } int is_valid_character(int newchar) { - if ((newchar < 0) || (newchar >= game.numcharacters)) return 0; - return 1; -} - -int wantMoveNow (CharacterInfo *chi, CharacterExtras *chex) { - // check most likely case first - if ((chex->zoom == 100) || ((chi->flags & CHF_SCALEMOVESPEED) == 0)) - return 1; - - // the % checks don't work when the counter is negative, so once - // it wraps round, correct it - while (chi->walkwaitcounter < 0) { - chi->walkwaitcounter += 12000; - } - - // scaling 170-200%, move 175% speed - if (chex->zoom >= 170) { - if ((chi->walkwaitcounter % 4) >= 1) - return 2; - else - return 1; - } - // scaling 140-170%, move 150% speed - else if (chex->zoom >= 140) { - if ((chi->walkwaitcounter % 2) == 1) - return 2; - else - return 1; - } - // scaling 115-140%, move 125% speed - else if (chex->zoom >= 115) { - if ((chi->walkwaitcounter % 4) >= 3) - return 2; - else - return 1; - } - // scaling 80-120%, normal speed - else if (chex->zoom >= 80) - return 1; - // scaling 60-80%, move 75% speed - if (chex->zoom >= 60) { - if ((chi->walkwaitcounter % 4) >= 1) - return -1; - else if (chex->xwas != INVALID_X) { - // move the second half of the movement to make it smoother - chi->x = chex->xwas; - chi->y = chex->ywas; - chex->xwas = INVALID_X; - } - } - // scaling 30-60%, move 50% speed - else if (chex->zoom >= 30) { - if ((chi->walkwaitcounter % 2) == 1) - return -1; - else if (chex->xwas != INVALID_X) { - // move the second half of the movement to make it smoother - chi->x = chex->xwas; - chi->y = chex->ywas; - chex->xwas = INVALID_X; - } - } - // scaling 0-30%, move 25% speed - else { - if ((chi->walkwaitcounter % 4) >= 3) - return -1; - if (((chi->walkwaitcounter % 4) == 1) && (chex->xwas != INVALID_X)) { - // move the second half of the movement to make it smoother - chi->x = chex->xwas; - chi->y = chex->ywas; - chex->xwas = INVALID_X; - } - - } - - return 0; + if ((newchar < 0) || (newchar >= game.numcharacters)) return 0; + return 1; +} + +int wantMoveNow(CharacterInfo *chi, CharacterExtras *chex) { + // check most likely case first + if ((chex->zoom == 100) || ((chi->flags & CHF_SCALEMOVESPEED) == 0)) + return 1; + + // the % checks don't work when the counter is negative, so once + // it wraps round, correct it + while (chi->walkwaitcounter < 0) { + chi->walkwaitcounter += 12000; + } + + // scaling 170-200%, move 175% speed + if (chex->zoom >= 170) { + if ((chi->walkwaitcounter % 4) >= 1) + return 2; + else + return 1; + } + // scaling 140-170%, move 150% speed + else if (chex->zoom >= 140) { + if ((chi->walkwaitcounter % 2) == 1) + return 2; + else + return 1; + } + // scaling 115-140%, move 125% speed + else if (chex->zoom >= 115) { + if ((chi->walkwaitcounter % 4) >= 3) + return 2; + else + return 1; + } + // scaling 80-120%, normal speed + else if (chex->zoom >= 80) + return 1; + // scaling 60-80%, move 75% speed + if (chex->zoom >= 60) { + if ((chi->walkwaitcounter % 4) >= 1) + return -1; + else if (chex->xwas != INVALID_X) { + // move the second half of the movement to make it smoother + chi->x = chex->xwas; + chi->y = chex->ywas; + chex->xwas = INVALID_X; + } + } + // scaling 30-60%, move 50% speed + else if (chex->zoom >= 30) { + if ((chi->walkwaitcounter % 2) == 1) + return -1; + else if (chex->xwas != INVALID_X) { + // move the second half of the movement to make it smoother + chi->x = chex->xwas; + chi->y = chex->ywas; + chex->xwas = INVALID_X; + } + } + // scaling 0-30%, move 25% speed + else { + if ((chi->walkwaitcounter % 4) >= 3) + return -1; + if (((chi->walkwaitcounter % 4) == 1) && (chex->xwas != INVALID_X)) { + // move the second half of the movement to make it smoother + chi->x = chex->xwas; + chi->y = chex->ywas; + chex->xwas = INVALID_X; + } + + } + + return 0; } void setup_player_character(int charid) { - game.playercharacter = charid; - playerchar = &game.chars[charid]; - _sc_PlayerCharPtr = ccGetObjectHandleFromAddress((char*)playerchar); - if (loaded_game_file_version < kGameVersion_270) { - ccAddExternalDynamicObject("player", playerchar, &ccDynamicCharacter); - } -} - -void animate_character(CharacterInfo *chap, int loopn,int sppd,int rept, int noidleoverride, int direction, int sframe) { - - if ((chap->view < 0) || (chap->view > game.numviews)) { - quitprintf("!AnimateCharacter: you need to set the view number first\n" - "(trying to animate '%s' using loop %d. View is currently %d).",chap->name,loopn,chap->view+1); - } - debug_script_log("%s: Start anim view %d loop %d, spd %d, repeat %d, frame: %d", chap->scrname, chap->view+1, loopn, sppd, rept, sframe); - if ((chap->idleleft < 0) && (noidleoverride == 0)) { - // if idle view in progress for the character (and this is not the - // "start idle animation" animate_character call), stop the idle anim - Character_UnlockView(chap); - chap->idleleft=chap->idletime; - } - if ((loopn < 0) || (loopn >= views[chap->view].numLoops)) - quit("!AnimateCharacter: invalid loop number specified"); - if ((sframe < 0) || (sframe >= views[chap->view].loops[loopn].numFrames)) - quit("!AnimateCharacter: invalid starting frame number specified"); - Character_StopMoving(chap); - chap->animating=1; - if (rept) chap->animating |= CHANIM_REPEAT; - if (direction) chap->animating |= CHANIM_BACKWARDS; - - chap->animating|=((sppd << 8) & 0xff00); - chap->loop=loopn; - // reverse animation starts at the *previous frame* - if (direction) { - sframe--; - if (sframe < 0) - sframe = views[chap->view].loops[loopn].numFrames - (-sframe); - } - chap->frame = sframe; - - chap->wait = sppd + views[chap->view].loops[loopn].frames[chap->frame].speed; - CheckViewFrameForCharacter(chap); + game.playercharacter = charid; + playerchar = &game.chars[charid]; + _sc_PlayerCharPtr = ccGetObjectHandleFromAddress((char *)playerchar); + if (loaded_game_file_version < kGameVersion_270) { + ccAddExternalDynamicObject("player", playerchar, &ccDynamicCharacter); + } +} + +void animate_character(CharacterInfo *chap, int loopn, int sppd, int rept, int noidleoverride, int direction, int sframe) { + + if ((chap->view < 0) || (chap->view > game.numviews)) { + quitprintf("!AnimateCharacter: you need to set the view number first\n" + "(trying to animate '%s' using loop %d. View is currently %d).", chap->name, loopn, chap->view + 1); + } + debug_script_log("%s: Start anim view %d loop %d, spd %d, repeat %d, frame: %d", chap->scrname, chap->view + 1, loopn, sppd, rept, sframe); + if ((chap->idleleft < 0) && (noidleoverride == 0)) { + // if idle view in progress for the character (and this is not the + // "start idle animation" animate_character call), stop the idle anim + Character_UnlockView(chap); + chap->idleleft = chap->idletime; + } + if ((loopn < 0) || (loopn >= views[chap->view].numLoops)) + quit("!AnimateCharacter: invalid loop number specified"); + if ((sframe < 0) || (sframe >= views[chap->view].loops[loopn].numFrames)) + quit("!AnimateCharacter: invalid starting frame number specified"); + Character_StopMoving(chap); + chap->animating = 1; + if (rept) chap->animating |= CHANIM_REPEAT; + if (direction) chap->animating |= CHANIM_BACKWARDS; + + chap->animating |= ((sppd << 8) & 0xff00); + chap->loop = loopn; + // reverse animation starts at the *previous frame* + if (direction) { + sframe--; + if (sframe < 0) + sframe = views[chap->view].loops[loopn].numFrames - (-sframe); + } + chap->frame = sframe; + + chap->wait = sppd + views[chap->view].loops[loopn].frames[chap->frame].speed; + CheckViewFrameForCharacter(chap); } void CheckViewFrameForCharacter(CharacterInfo *chi) { - int soundVolume = SCR_NO_VALUE; + int soundVolume = SCR_NO_VALUE; - if (chi->flags & CHF_SCALEVOLUME) { - // adjust the sound volume using the character's zoom level - int zoom_level = charextra[chi->index_id].zoom; - if (zoom_level == 0) - zoom_level = 100; + if (chi->flags & CHF_SCALEVOLUME) { + // adjust the sound volume using the character's zoom level + int zoom_level = charextra[chi->index_id].zoom; + if (zoom_level == 0) + zoom_level = 100; - soundVolume = zoom_level; + soundVolume = zoom_level; - if (soundVolume < 0) - soundVolume = 0; - if (soundVolume > 100) - soundVolume = 100; - } + if (soundVolume < 0) + soundVolume = 0; + if (soundVolume > 100) + soundVolume = 100; + } - CheckViewFrame(chi->view, chi->loop, chi->frame, soundVolume); + CheckViewFrame(chi->view, chi->loop, chi->frame, soundVolume); } -Bitmap *GetCharacterImage(int charid, int *isFlipped) -{ - if (!gfxDriver->HasAcceleratedTransform()) - { - if (actsps[charid + MAX_ROOM_OBJECTS] != nullptr) - { - // the actsps image is pre-flipped, so no longer register the image as such - if (isFlipped) - *isFlipped = 0; - return actsps[charid + MAX_ROOM_OBJECTS]; - } - } - CharacterInfo*chin=&game.chars[charid]; - int sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic; - return spriteset[sppic]; +Bitmap *GetCharacterImage(int charid, int *isFlipped) { + if (!gfxDriver->HasAcceleratedTransform()) { + if (actsps[charid + MAX_ROOM_OBJECTS] != nullptr) { + // the actsps image is pre-flipped, so no longer register the image as such + if (isFlipped) + *isFlipped = 0; + return actsps[charid + MAX_ROOM_OBJECTS]; + } + } + CharacterInfo *chin = &game.chars[charid]; + int sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic; + return spriteset[sppic]; } CharacterInfo *GetCharacterAtScreen(int xx, int yy) { - int hsnum = GetCharIDAtScreen(xx, yy); - if (hsnum < 0) - return nullptr; - return &game.chars[hsnum]; + int hsnum = GetCharIDAtScreen(xx, yy); + if (hsnum < 0) + return nullptr; + return &game.chars[hsnum]; } -CharacterInfo *GetCharacterAtRoom(int x, int y) -{ - int hsnum = is_pos_on_character(x, y); - if (hsnum < 0) - return nullptr; - return &game.chars[hsnum]; +CharacterInfo *GetCharacterAtRoom(int x, int y) { + int hsnum = is_pos_on_character(x, y); + if (hsnum < 0) + return nullptr; + return &game.chars[hsnum]; } extern int char_lowest_yp, obj_lowest_yp; -int is_pos_on_character(int xx,int yy) { - int cc,sppic,lowestyp=0,lowestwas=-1; - for (cc=0;ccview < 0) || - (chin->loop >= views[chin->view].numLoops) || - (chin->frame >= views[chin->view].loops[chin->loop].numFrames)) - { - continue; - } - - sppic=views[chin->view].loops[chin->loop].frames[chin->frame].pic; - int usewid = charextra[cc].width; - int usehit = charextra[cc].height; - if (usewid==0) usewid=game.SpriteInfos[sppic].Width; - if (usehit==0) usehit= game.SpriteInfos[sppic].Height; - int xxx = chin->x - game_to_data_coord(usewid) / 2; - int yyy = chin->get_effective_y() - game_to_data_coord(usehit); - - int mirrored = views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE; - Bitmap *theImage = GetCharacterImage(cc, &mirrored); - - if (is_pos_in_sprite(xx,yy,xxx,yyy, theImage, - game_to_data_coord(usewid), - game_to_data_coord(usehit), mirrored) == FALSE) - continue; - - int use_base = chin->get_baseline(); - if (use_base < lowestyp) continue; - lowestyp=use_base; - lowestwas=cc; - } - char_lowest_yp = lowestyp; - return lowestwas; +int is_pos_on_character(int xx, int yy) { + int cc, sppic, lowestyp = 0, lowestwas = -1; + for (cc = 0; cc < game.numcharacters; cc++) { + if (game.chars[cc].room != displayed_room) continue; + if (game.chars[cc].on == 0) continue; + if (game.chars[cc].flags & CHF_NOINTERACT) continue; + if (game.chars[cc].view < 0) continue; + CharacterInfo *chin = &game.chars[cc]; + + if ((chin->view < 0) || + (chin->loop >= views[chin->view].numLoops) || + (chin->frame >= views[chin->view].loops[chin->loop].numFrames)) { + continue; + } + + sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic; + int usewid = charextra[cc].width; + int usehit = charextra[cc].height; + if (usewid == 0) usewid = game.SpriteInfos[sppic].Width; + if (usehit == 0) usehit = game.SpriteInfos[sppic].Height; + int xxx = chin->x - game_to_data_coord(usewid) / 2; + int yyy = chin->get_effective_y() - game_to_data_coord(usehit); + + int mirrored = views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE; + Bitmap *theImage = GetCharacterImage(cc, &mirrored); + + if (is_pos_in_sprite(xx, yy, xxx, yyy, theImage, + game_to_data_coord(usewid), + game_to_data_coord(usehit), mirrored) == FALSE) + continue; + + int use_base = chin->get_baseline(); + if (use_base < lowestyp) continue; + lowestyp = use_base; + lowestwas = cc; + } + char_lowest_yp = lowestyp; + return lowestwas; } void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2) { - CharacterInfo *char1 = &game.chars[charid]; - int cwidth, fromx; - - if (char1->blocking_width < 1) - cwidth = game_to_data_coord(GetCharacterWidth(charid)) - 4; - else - cwidth = char1->blocking_width; - - fromx = char1->x - cwidth/2; - if (fromx < 0) { - cwidth += fromx; - fromx = 0; - } - if (fromx + cwidth >= mask_to_room_coord(walkable_areas_temp->GetWidth())) - cwidth = mask_to_room_coord(walkable_areas_temp->GetWidth()) - fromx; - - if (x1) - *x1 = fromx; - if (width) - *width = cwidth; - if (y1) - *y1 = char1->get_blocking_top(); - if (y2) - *y2 = char1->get_blocking_bottom(); + CharacterInfo *char1 = &game.chars[charid]; + int cwidth, fromx; + + if (char1->blocking_width < 1) + cwidth = game_to_data_coord(GetCharacterWidth(charid)) - 4; + else + cwidth = char1->blocking_width; + + fromx = char1->x - cwidth / 2; + if (fromx < 0) { + cwidth += fromx; + fromx = 0; + } + if (fromx + cwidth >= mask_to_room_coord(walkable_areas_temp->GetWidth())) + cwidth = mask_to_room_coord(walkable_areas_temp->GetWidth()) - fromx; + + if (x1) + *x1 = fromx; + if (width) + *width = cwidth; + if (y1) + *y1 = char1->get_blocking_top(); + if (y2) + *y2 = char1->get_blocking_bottom(); } // Check whether the source char has walked onto character ww -int is_char_on_another (int sourceChar, int ww, int*fromxptr, int*cwidptr) { +int is_char_on_another(int sourceChar, int ww, int *fromxptr, int *cwidptr) { - int fromx, cwidth; - int y1, y2; - get_char_blocking_rect(ww, &fromx, &y1, &cwidth, &y2); + int fromx, cwidth; + int y1, y2; + get_char_blocking_rect(ww, &fromx, &y1, &cwidth, &y2); - if (fromxptr) - fromxptr[0] = fromx; - if (cwidptr) - cwidptr[0] = cwidth; + if (fromxptr) + fromxptr[0] = fromx; + if (cwidptr) + cwidptr[0] = cwidth; - // if the character trying to move is already on top of - // this char somehow, allow them through - if ((sourceChar >= 0) && - // x/width are left and width co-ords, so they need >= and < - (game.chars[sourceChar].x >= fromx) && - (game.chars[sourceChar].x < fromx + cwidth) && - // y1/y2 are the top/bottom co-ords, so they need >= / <= - (game.chars[sourceChar].y >= y1 ) && - (game.chars[sourceChar].y <= y2 )) - return 1; + // if the character trying to move is already on top of + // this char somehow, allow them through + if ((sourceChar >= 0) && + // x/width are left and width co-ords, so they need >= and < + (game.chars[sourceChar].x >= fromx) && + (game.chars[sourceChar].x < fromx + cwidth) && + // y1/y2 are the top/bottom co-ords, so they need >= / <= + (game.chars[sourceChar].y >= y1) && + (game.chars[sourceChar].y <= y2)) + return 1; - return 0; + return 0; } int my_getpixel(Bitmap *blk, int x, int y) { - if ((x < 0) || (y < 0) || (x >= blk->GetWidth()) || (y >= blk->GetHeight())) - return -1; + if ((x < 0) || (y < 0) || (x >= blk->GetWidth()) || (y >= blk->GetHeight())) + return -1; - // strip the alpha channel + // strip the alpha channel // TODO: is there a way to do this vtable thing with Bitmap? - BITMAP *al_bmp = (BITMAP*)blk->GetAllegroBitmap(); - return al_bmp->vtable->getpixel(al_bmp, x, y) & 0x00ffffff; + BITMAP *al_bmp = (BITMAP *)blk->GetAllegroBitmap(); + return al_bmp->vtable->getpixel(al_bmp, x, y) & 0x00ffffff; } -int check_click_on_character(int xx,int yy,int mood) { - int lowestwas=is_pos_on_character(xx,yy); - if (lowestwas>=0) { - RunCharacterInteraction (lowestwas, mood); - return 1; - } - return 0; +int check_click_on_character(int xx, int yy, int mood) { + int lowestwas = is_pos_on_character(xx, yy); + if (lowestwas >= 0) { + RunCharacterInteraction(lowestwas, mood); + return 1; + } + return 0; } void _DisplaySpeechCore(int chid, const char *displbuf) { - if (displbuf[0] == 0) { - // no text, just update the current character who's speaking - // this allows the portrait side to be switched with an empty - // speech line - play.swap_portrait_lastchar = chid; - return; - } + if (displbuf[0] == 0) { + // no text, just update the current character who's speaking + // this allows the portrait side to be switched with an empty + // speech line + play.swap_portrait_lastchar = chid; + return; + } - // adjust timing of text (so that DisplaySpeech("%s", str) pauses - // for the length of the string not 2 frames) - int len = (int)strlen(displbuf); - if (len > source_text_length + 3) - source_text_length = len; + // adjust timing of text (so that DisplaySpeech("%s", str) pauses + // for the length of the string not 2 frames) + int len = (int)strlen(displbuf); + if (len > source_text_length + 3) + source_text_length = len; - DisplaySpeech(displbuf, chid); + DisplaySpeech(displbuf, chid); } void _DisplayThoughtCore(int chid, const char *displbuf) { - // adjust timing of text (so that DisplayThought("%s", str) pauses - // for the length of the string not 2 frames) - int len = (int)strlen(displbuf); - if (len > source_text_length + 3) - source_text_length = len; - - int xpp = -1, ypp = -1, width = -1; - - if ((game.options[OPT_SPEECHTYPE] == 0) || (game.chars[chid].thinkview <= 0)) { - // lucasarts-style, so we want a speech bubble actually above - // their head (or if they have no think anim in Sierra-style) - width = data_to_game_coord(play.speech_bubble_width); - xpp = play.RoomToScreenX(data_to_game_coord(game.chars[chid].x)) - width / 2; - if (xpp < 0) - xpp = 0; - // -1 will automatically put it above the char's head - ypp = -1; - } - - _displayspeech ((char*)displbuf, chid, xpp, ypp, width, 1); -} - -void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int isThought) { - if (!is_valid_character(aschar)) - quit("!DisplaySpeech: invalid character"); - - CharacterInfo *speakingChar = &game.chars[aschar]; - if ((speakingChar->view < 0) || (speakingChar->view >= game.numviews)) - quit("!DisplaySpeech: character has invalid view"); - - if (is_text_overlay > 0) - { - debug_script_warn("DisplaySpeech: speech was already displayed (nested DisplaySpeech, perhaps room script and global script conflict?)"); - return; - } - - EndSkippingUntilCharStops(); - - said_speech_line = 1; - - if (play.bgspeech_stay_on_display == 0) { - // remove any background speech - for (size_t i = 0; i < screenover.size();) { - if (screenover[i].timeout > 0) - remove_screen_overlay(screenover[i].type); - else - i++; - } - } - said_text = 1; - - // the strings are pre-translated - //texx = get_translation(texx); - our_eip=150; - - int isPause = 1; - // if the message is all .'s, don't display anything - for (int aa = 0; texx[aa] != 0; aa++) { - if (texx[aa] != '.') { - isPause = 0; - break; - } - } - - play.messagetime = GetTextDisplayTime(texx); - play.speech_in_post_state = false; - - if (isPause) { - postpone_scheduled_music_update_by(std::chrono::milliseconds(play.messagetime * 1000 / frames_per_second)); - GameLoopUntilValueIsNegative(&play.messagetime); - return; - } - - int textcol = speakingChar->talkcolor; - - // if it's 0, it won't be recognised as speech - if (textcol == 0) - textcol = 16; - - Rect ui_view = play.GetUIViewport(); - int allowShrink = 0; - int bwidth = widd; - if (bwidth < 0) - bwidth = ui_view.GetWidth()/2 + ui_view.GetWidth()/4; - - our_eip=151; - - int useview = speakingChar->talkview; - if (isThought) { - useview = speakingChar->thinkview; - // view 0 is not valid for think views - if (useview == 0) - useview = -1; - // speech bubble can shrink to fit - allowShrink = 1; - if (speakingChar->room != displayed_room) { - // not in room, centre it - xx = -1; - yy = -1; - } - } - - if (useview >= game.numviews) - quitprintf("!Character.Say: attempted to use view %d for animation, but it does not exist", useview + 1); - - int tdxp = xx,tdyp = yy; - int oldview=-1, oldloop = -1; - int ovr_type = 0; - - text_lips_offset = 0; - text_lips_text = texx; - - Bitmap *closeupface=nullptr; - // TODO: we always call _display_at later which may also start voice-over; - // find out if this may be refactored and voice started only in one place. - try_auto_play_speech(texx, texx, aschar, true); - - if (game.options[OPT_SPEECHTYPE] == 3) - remove_screen_overlay(OVER_COMPLETE); - our_eip=1500; - - if (game.options[OPT_SPEECHTYPE] == 0) - allowShrink = 1; - - if (speakingChar->idleleft < 0) { - // if idle anim in progress for the character, stop it - ReleaseCharacterView(aschar); - // speakingChar->idleleft = speakingChar->idletime; - } - - bool overlayPositionFixed = false; - int charFrameWas = 0; - int viewWasLocked = 0; - if (speakingChar->flags & CHF_FIXVIEW) - viewWasLocked = 1; - - /*if ((speakingChar->room == displayed_room) || - ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) ) {*/ - - if (speakingChar->room == displayed_room) { - // If the character is in this room, go for it - otherwise - // run the "else" clause which does text in the middle of - // the screen. - our_eip=1501; - - if (speakingChar->walking) - StopMoving(aschar); - - // save the frame we need to go back to - // if they were moving, this will be 0 (because we just called - // StopMoving); otherwise, it might be a specific animation - // frame which we should return to - if (viewWasLocked) - charFrameWas = speakingChar->frame; - - // if the current loop doesn't exist in talking view, use loop 0 - if (speakingChar->loop >= views[speakingChar->view].numLoops) - speakingChar->loop = 0; - - if ((speakingChar->view < 0) || - (speakingChar->loop >= views[speakingChar->view].numLoops) || - (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1)) - { - quitprintf("Unable to display speech because the character %s has an invalid view frame (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame); - } - - our_eip=1504; - - // Calculate speech position based on character's position on screen - auto view = FindNearestViewport(aschar); - if (tdxp < 0) - tdxp = view->RoomToScreen(data_to_game_coord(speakingChar->x), 0).first.X; - if (tdxp < 2) - tdxp = 2; - tdxp = -tdxp; // tell it to centre it ([ikm] not sure what's going on here... wrong comment?) - - if (tdyp < 0) - { - int sppic = views[speakingChar->view].loops[speakingChar->loop].frames[0].pic; - int height = (charextra[aschar].height < 1) ? game.SpriteInfos[sppic].Height : height = charextra[aschar].height; - tdyp = view->RoomToScreen(0, data_to_game_coord(game.chars[aschar].get_effective_y()) - height).first.Y - - get_fixed_pixel_size(5); - if (isThought) // if it's a thought, lift it a bit further up - tdyp -= get_fixed_pixel_size(10); - } - if (tdyp < 5) - tdyp = 5; - - our_eip=152; - - if ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) { - // Sierra-style close-up portrait - - if (play.swap_portrait_lastchar != aschar) { - // if the portraits are set to Alternate, OR they are - // set to Left but swap_portrait has been set to 1 (the old - // method for enabling it), then swap them round - if ((game.options[OPT_PORTRAITSIDE] == PORTRAIT_ALTERNATE) || - ((game.options[OPT_PORTRAITSIDE] == 0) && - (play.swap_portrait_side > 0))) { - - if (play.swap_portrait_side == 2) - play.swap_portrait_side = 1; - else - play.swap_portrait_side = 2; - } - - if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION) { - // Portrait side based on character X-positions - if (play.swap_portrait_lastchar < 0) { - // No previous character been spoken to - // therefore, assume it's the player - if(game.playercharacter != aschar && game.chars[game.playercharacter].room == speakingChar->room && game.chars[game.playercharacter].on == 1) - play.swap_portrait_lastchar = game.playercharacter; - else - // The player's not here. Find another character in this room - // that it could be - for (int ce = 0; ce < game.numcharacters; ce++) { - if ((game.chars[ce].room == speakingChar->room) && - (game.chars[ce].on == 1) && - (ce != aschar)) { - play.swap_portrait_lastchar = ce; - break; - } - } - } - - if (play.swap_portrait_lastchar >= 0) { - // if this character is right of the one before, put the - // portrait on the right - if (speakingChar->x > game.chars[play.swap_portrait_lastchar].x) - play.swap_portrait_side = -1; - else - play.swap_portrait_side = 0; - } - } - play.swap_portrait_lastlastchar = play.swap_portrait_lastchar; - play.swap_portrait_lastchar = aschar; - } - else - // If the portrait side is based on the character's X position and the same character is - // speaking, compare against the previous *previous* character to see where the speech should be - if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION && play.swap_portrait_lastlastchar >= 0) { - if (speakingChar->x > game.chars[play.swap_portrait_lastlastchar].x) - play.swap_portrait_side = -1; - else - play.swap_portrait_side = 0; - } - - // Determine whether to display the portrait on the left or right - int portrait_on_right = 0; - - if (game.options[OPT_SPEECHTYPE] == 3) - { } // always on left with QFG-style speech - else if ((play.swap_portrait_side == 1) || - (play.swap_portrait_side == -1) || - (game.options[OPT_PORTRAITSIDE] == PORTRAIT_RIGHT)) - portrait_on_right = 1; - - - int bigx=0,bigy=0,kk; - ViewStruct*viptr=&views[useview]; - for (kk = 0; kk < viptr->loops[0].numFrames; kk++) - { - int tw = game.SpriteInfos[viptr->loops[0].frames[kk].pic].Width; - if (tw > bigx) bigx=tw; - tw = game.SpriteInfos[viptr->loops[0].frames[kk].pic].Height; - if (tw > bigy) bigy=tw; - } - - // if they accidentally used a large full-screen image as the sierra-style - // talk view, correct it - if ((game.options[OPT_SPEECHTYPE] != 3) && (bigx > ui_view.GetWidth() - get_fixed_pixel_size(50))) - bigx = ui_view.GetWidth() - get_fixed_pixel_size(50); - - if (widd > 0) - bwidth = widd - bigx; - - our_eip=153; - int ovr_yp = get_fixed_pixel_size(20); - int view_frame_x = 0; - int view_frame_y = 0; - facetalk_qfg4_override_placement_x = false; - facetalk_qfg4_override_placement_y = false; - - if (game.options[OPT_SPEECHTYPE] == 3) { - // QFG4-style whole screen picture - closeupface = BitmapHelper::CreateBitmap(ui_view.GetWidth(), ui_view.GetHeight(), spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth()); - closeupface->Clear(0); - if (xx < 0 && play.speech_portrait_placement) - { - facetalk_qfg4_override_placement_x = true; - view_frame_x = play.speech_portrait_x; - } - if (yy < 0 && play.speech_portrait_placement) - { - facetalk_qfg4_override_placement_y = true; - view_frame_y = play.speech_portrait_y; - } - else - { - view_frame_y = ui_view.GetHeight()/2 - game.SpriteInfos[viptr->loops[0].frames[0].pic].Height/2; - } - bigx = ui_view.GetWidth()/2 - get_fixed_pixel_size(20); - ovr_type = OVER_COMPLETE; - ovr_yp = 0; - tdyp = -1; // center vertically - } - else { - // KQ6-style close-up face picture - if (yy < 0 && play.speech_portrait_placement) - { - ovr_yp = play.speech_portrait_y; - } - else if (yy < 0) - ovr_yp = adjust_y_for_guis (ovr_yp); - else - ovr_yp = yy; - - closeupface = BitmapHelper::CreateTransparentBitmap(bigx+1,bigy+1,spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth()); - ovr_type = OVER_PICTURE; - - if (yy < 0) - tdyp = ovr_yp + get_textwindow_top_border_height(play.speech_textwindow_gui); - } - const ViewFrame *vf = &viptr->loops[0].frames[0]; - const bool closeupface_has_alpha = (game.SpriteInfos[vf->pic].Flags & SPF_ALPHACHANNEL) != 0; - DrawViewFrame(closeupface, vf, view_frame_x, view_frame_y); - - int overlay_x = get_fixed_pixel_size(10); - if (xx < 0) { - tdxp = bigx + get_textwindow_border_width(play.speech_textwindow_gui) / 2; - if (play.speech_portrait_placement) - { - overlay_x = play.speech_portrait_x; - tdxp += overlay_x + get_fixed_pixel_size(6); - } - else - { - tdxp += get_fixed_pixel_size(16); - } - - int maxWidth = (ui_view.GetWidth() - tdxp) - get_fixed_pixel_size(5) - - get_textwindow_border_width (play.speech_textwindow_gui) / 2; - - if (bwidth > maxWidth) - bwidth = maxWidth; - } - else { - tdxp = xx + bigx + get_fixed_pixel_size(8); - overlay_x = xx; - } - - // allow the text box to be shrunk to fit the text - allowShrink = 1; - - // if the portrait's on the right, swap it round - if (portrait_on_right) { - if ((xx < 0) || (widd < 0)) { - tdxp = get_fixed_pixel_size(9); - if (play.speech_portrait_placement) - { - overlay_x = (ui_view.GetWidth() - bigx) - play.speech_portrait_x; - int maxWidth = overlay_x - tdxp - get_fixed_pixel_size(9) - - get_textwindow_border_width (play.speech_textwindow_gui) / 2; - if (bwidth > maxWidth) - bwidth = maxWidth; - } - else - { - overlay_x = (ui_view.GetWidth() - bigx) - get_fixed_pixel_size(5); - } - } - else { - overlay_x = (xx + widd - bigx) - get_fixed_pixel_size(5); - tdxp = xx; - } - tdxp += get_textwindow_border_width(play.speech_textwindow_gui) / 2; - allowShrink = 2; - } - if (game.options[OPT_SPEECHTYPE] == 3) - overlay_x = 0; - face_talking=add_screen_overlay(overlay_x,ovr_yp,ovr_type,closeupface, closeupface_has_alpha); - facetalkframe = 0; - facetalkwait = viptr->loops[0].frames[0].speed + GetCharacterSpeechAnimationDelay(speakingChar); - facetalkloop = 0; - facetalkview = useview; - facetalkrepeat = (isThought) ? 0 : 1; - facetalkBlinkLoop = 0; - facetalkAllowBlink = 1; - if ((isThought) && (speakingChar->flags & CHF_NOBLINKANDTHINK)) - facetalkAllowBlink = 0; - facetalkchar = &game.chars[aschar]; - if (facetalkchar->blinktimer < 0) - facetalkchar->blinktimer = facetalkchar->blinkinterval; - textcol=-textcol; - overlayPositionFixed = true; - } - else if (useview >= 0) { - // Lucasarts-style speech - our_eip=154; - - oldview = speakingChar->view; - oldloop = speakingChar->loop; - speakingChar->animating = 1 | (GetCharacterSpeechAnimationDelay(speakingChar) << 8); - // only repeat if speech, not thought - if (!isThought) - speakingChar->animating |= CHANIM_REPEAT; - - speakingChar->view = useview; - speakingChar->frame=0; - speakingChar->flags|=CHF_FIXVIEW; - - if (speakingChar->loop >= views[speakingChar->view].numLoops) - { - // current character loop is outside the normal talking directions - speakingChar->loop = 0; - } - - facetalkBlinkLoop = speakingChar->loop; - - if (speakingChar->on && // don't bother checking if character is not visible (also fixes 'Trilby's Notes' legacy game) - ((speakingChar->loop >= views[speakingChar->view].numLoops) || - (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1))) - { - quitprintf("!Unable to display speech because the character %s has an invalid speech view (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame); - } - - // set up the speed of the first frame - speakingChar->wait = GetCharacterSpeechAnimationDelay(speakingChar) + - views[speakingChar->view].loops[speakingChar->loop].frames[0].speed; - - if (widd < 0) { - bwidth = ui_view.GetWidth()/2 + ui_view.GetWidth()/6; - // If they are close to the screen edge, make the text narrower - int relx = play.RoomToScreenX(data_to_game_coord(speakingChar->x)); - if ((relx < ui_view.GetWidth() / 4) || (relx > ui_view.GetWidth() - (ui_view.GetWidth() / 4))) - bwidth -= ui_view.GetWidth() / 5; - } - /* this causes the text to bob up and down as they talk - tdxp = OVR_AUTOPLACE; - tdyp = aschar;*/ - if (!isThought) // set up the lip sync if not thinking - char_speaking = aschar; - - } - } - else - allowShrink = 1; - - // it wants the centred position, so make it so - if ((xx >= 0) && (tdxp < 0)) - tdxp -= widd / 2; - - // if they used DisplaySpeechAt, then use the supplied width - if ((widd > 0) && (isThought == 0)) - allowShrink = 0; - - if (isThought) - char_thinking = aschar; - - our_eip=155; - _display_at(tdxp, tdyp, bwidth, texx, DISPLAYTEXT_SPEECH, textcol, isThought, allowShrink, overlayPositionFixed); - our_eip=156; - if ((play.in_conversation > 0) && (game.options[OPT_SPEECHTYPE] == 3)) - closeupface = nullptr; - if (closeupface!=nullptr) - remove_screen_overlay(ovr_type); - mark_screen_dirty(); - face_talking = -1; - facetalkchar = nullptr; - our_eip=157; - if (oldview>=0) { - speakingChar->flags &= ~CHF_FIXVIEW; - if (viewWasLocked) - speakingChar->flags |= CHF_FIXVIEW; - speakingChar->view=oldview; - - // Don't reset the loop in 2.x games - if (loaded_game_file_version > kGameVersion_272) - speakingChar->loop = oldloop; - - speakingChar->animating=0; - speakingChar->frame = charFrameWas; - speakingChar->wait=0; - speakingChar->idleleft = speakingChar->idletime; - // restart the idle animation straight away - charextra[aschar].process_idle_this_time = 1; - } - char_speaking = -1; - char_thinking = -1; - if (play.IsBlockingVoiceSpeech()) - stop_voice_speech(); + // adjust timing of text (so that DisplayThought("%s", str) pauses + // for the length of the string not 2 frames) + int len = (int)strlen(displbuf); + if (len > source_text_length + 3) + source_text_length = len; + + int xpp = -1, ypp = -1, width = -1; + + if ((game.options[OPT_SPEECHTYPE] == 0) || (game.chars[chid].thinkview <= 0)) { + // lucasarts-style, so we want a speech bubble actually above + // their head (or if they have no think anim in Sierra-style) + width = data_to_game_coord(play.speech_bubble_width); + xpp = play.RoomToScreenX(data_to_game_coord(game.chars[chid].x)) - width / 2; + if (xpp < 0) + xpp = 0; + // -1 will automatically put it above the char's head + ypp = -1; + } + + _displayspeech((char *)displbuf, chid, xpp, ypp, width, 1); +} + +void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int isThought) { + if (!is_valid_character(aschar)) + quit("!DisplaySpeech: invalid character"); + + CharacterInfo *speakingChar = &game.chars[aschar]; + if ((speakingChar->view < 0) || (speakingChar->view >= game.numviews)) + quit("!DisplaySpeech: character has invalid view"); + + if (is_text_overlay > 0) { + debug_script_warn("DisplaySpeech: speech was already displayed (nested DisplaySpeech, perhaps room script and global script conflict?)"); + return; + } + + EndSkippingUntilCharStops(); + + said_speech_line = 1; + + if (play.bgspeech_stay_on_display == 0) { + // remove any background speech + for (size_t i = 0; i < screenover.size();) { + if (screenover[i].timeout > 0) + remove_screen_overlay(screenover[i].type); + else + i++; + } + } + said_text = 1; + + // the strings are pre-translated + //texx = get_translation(texx); + our_eip = 150; + + int isPause = 1; + // if the message is all .'s, don't display anything + for (int aa = 0; texx[aa] != 0; aa++) { + if (texx[aa] != '.') { + isPause = 0; + break; + } + } + + play.messagetime = GetTextDisplayTime(texx); + play.speech_in_post_state = false; + + if (isPause) { + postpone_scheduled_music_update_by(std::chrono::milliseconds(play.messagetime * 1000 / frames_per_second)); + GameLoopUntilValueIsNegative(&play.messagetime); + return; + } + + int textcol = speakingChar->talkcolor; + + // if it's 0, it won't be recognised as speech + if (textcol == 0) + textcol = 16; + + Rect ui_view = play.GetUIViewport(); + int allowShrink = 0; + int bwidth = widd; + if (bwidth < 0) + bwidth = ui_view.GetWidth() / 2 + ui_view.GetWidth() / 4; + + our_eip = 151; + + int useview = speakingChar->talkview; + if (isThought) { + useview = speakingChar->thinkview; + // view 0 is not valid for think views + if (useview == 0) + useview = -1; + // speech bubble can shrink to fit + allowShrink = 1; + if (speakingChar->room != displayed_room) { + // not in room, centre it + xx = -1; + yy = -1; + } + } + + if (useview >= game.numviews) + quitprintf("!Character.Say: attempted to use view %d for animation, but it does not exist", useview + 1); + + int tdxp = xx, tdyp = yy; + int oldview = -1, oldloop = -1; + int ovr_type = 0; + + text_lips_offset = 0; + text_lips_text = texx; + + Bitmap *closeupface = nullptr; + // TODO: we always call _display_at later which may also start voice-over; + // find out if this may be refactored and voice started only in one place. + try_auto_play_speech(texx, texx, aschar, true); + + if (game.options[OPT_SPEECHTYPE] == 3) + remove_screen_overlay(OVER_COMPLETE); + our_eip = 1500; + + if (game.options[OPT_SPEECHTYPE] == 0) + allowShrink = 1; + + if (speakingChar->idleleft < 0) { + // if idle anim in progress for the character, stop it + ReleaseCharacterView(aschar); + // speakingChar->idleleft = speakingChar->idletime; + } + + bool overlayPositionFixed = false; + int charFrameWas = 0; + int viewWasLocked = 0; + if (speakingChar->flags & CHF_FIXVIEW) + viewWasLocked = 1; + + /*if ((speakingChar->room == displayed_room) || + ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) ) {*/ + + if (speakingChar->room == displayed_room) { + // If the character is in this room, go for it - otherwise + // run the "else" clause which does text in the middle of + // the screen. + our_eip = 1501; + + if (speakingChar->walking) + StopMoving(aschar); + + // save the frame we need to go back to + // if they were moving, this will be 0 (because we just called + // StopMoving); otherwise, it might be a specific animation + // frame which we should return to + if (viewWasLocked) + charFrameWas = speakingChar->frame; + + // if the current loop doesn't exist in talking view, use loop 0 + if (speakingChar->loop >= views[speakingChar->view].numLoops) + speakingChar->loop = 0; + + if ((speakingChar->view < 0) || + (speakingChar->loop >= views[speakingChar->view].numLoops) || + (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1)) { + quitprintf("Unable to display speech because the character %s has an invalid view frame (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame); + } + + our_eip = 1504; + + // Calculate speech position based on character's position on screen + auto view = FindNearestViewport(aschar); + if (tdxp < 0) + tdxp = view->RoomToScreen(data_to_game_coord(speakingChar->x), 0).first.X; + if (tdxp < 2) + tdxp = 2; + tdxp = -tdxp; // tell it to centre it ([ikm] not sure what's going on here... wrong comment?) + + if (tdyp < 0) { + int sppic = views[speakingChar->view].loops[speakingChar->loop].frames[0].pic; + int height = (charextra[aschar].height < 1) ? game.SpriteInfos[sppic].Height : height = charextra[aschar].height; + tdyp = view->RoomToScreen(0, data_to_game_coord(game.chars[aschar].get_effective_y()) - height).first.Y + - get_fixed_pixel_size(5); + if (isThought) // if it's a thought, lift it a bit further up + tdyp -= get_fixed_pixel_size(10); + } + if (tdyp < 5) + tdyp = 5; + + our_eip = 152; + + if ((useview >= 0) && (game.options[OPT_SPEECHTYPE] > 0)) { + // Sierra-style close-up portrait + + if (play.swap_portrait_lastchar != aschar) { + // if the portraits are set to Alternate, OR they are + // set to Left but swap_portrait has been set to 1 (the old + // method for enabling it), then swap them round + if ((game.options[OPT_PORTRAITSIDE] == PORTRAIT_ALTERNATE) || + ((game.options[OPT_PORTRAITSIDE] == 0) && + (play.swap_portrait_side > 0))) { + + if (play.swap_portrait_side == 2) + play.swap_portrait_side = 1; + else + play.swap_portrait_side = 2; + } + + if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION) { + // Portrait side based on character X-positions + if (play.swap_portrait_lastchar < 0) { + // No previous character been spoken to + // therefore, assume it's the player + if (game.playercharacter != aschar && game.chars[game.playercharacter].room == speakingChar->room && game.chars[game.playercharacter].on == 1) + play.swap_portrait_lastchar = game.playercharacter; + else + // The player's not here. Find another character in this room + // that it could be + for (int ce = 0; ce < game.numcharacters; ce++) { + if ((game.chars[ce].room == speakingChar->room) && + (game.chars[ce].on == 1) && + (ce != aschar)) { + play.swap_portrait_lastchar = ce; + break; + } + } + } + + if (play.swap_portrait_lastchar >= 0) { + // if this character is right of the one before, put the + // portrait on the right + if (speakingChar->x > game.chars[play.swap_portrait_lastchar].x) + play.swap_portrait_side = -1; + else + play.swap_portrait_side = 0; + } + } + play.swap_portrait_lastlastchar = play.swap_portrait_lastchar; + play.swap_portrait_lastchar = aschar; + } else + // If the portrait side is based on the character's X position and the same character is + // speaking, compare against the previous *previous* character to see where the speech should be + if (game.options[OPT_PORTRAITSIDE] == PORTRAIT_XPOSITION && play.swap_portrait_lastlastchar >= 0) { + if (speakingChar->x > game.chars[play.swap_portrait_lastlastchar].x) + play.swap_portrait_side = -1; + else + play.swap_portrait_side = 0; + } + + // Determine whether to display the portrait on the left or right + int portrait_on_right = 0; + + if (game.options[OPT_SPEECHTYPE] == 3) { + } // always on left with QFG-style speech + else if ((play.swap_portrait_side == 1) || + (play.swap_portrait_side == -1) || + (game.options[OPT_PORTRAITSIDE] == PORTRAIT_RIGHT)) + portrait_on_right = 1; + + + int bigx = 0, bigy = 0, kk; + ViewStruct *viptr = &views[useview]; + for (kk = 0; kk < viptr->loops[0].numFrames; kk++) { + int tw = game.SpriteInfos[viptr->loops[0].frames[kk].pic].Width; + if (tw > bigx) bigx = tw; + tw = game.SpriteInfos[viptr->loops[0].frames[kk].pic].Height; + if (tw > bigy) bigy = tw; + } + + // if they accidentally used a large full-screen image as the sierra-style + // talk view, correct it + if ((game.options[OPT_SPEECHTYPE] != 3) && (bigx > ui_view.GetWidth() - get_fixed_pixel_size(50))) + bigx = ui_view.GetWidth() - get_fixed_pixel_size(50); + + if (widd > 0) + bwidth = widd - bigx; + + our_eip = 153; + int ovr_yp = get_fixed_pixel_size(20); + int view_frame_x = 0; + int view_frame_y = 0; + facetalk_qfg4_override_placement_x = false; + facetalk_qfg4_override_placement_y = false; + + if (game.options[OPT_SPEECHTYPE] == 3) { + // QFG4-style whole screen picture + closeupface = BitmapHelper::CreateBitmap(ui_view.GetWidth(), ui_view.GetHeight(), spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth()); + closeupface->Clear(0); + if (xx < 0 && play.speech_portrait_placement) { + facetalk_qfg4_override_placement_x = true; + view_frame_x = play.speech_portrait_x; + } + if (yy < 0 && play.speech_portrait_placement) { + facetalk_qfg4_override_placement_y = true; + view_frame_y = play.speech_portrait_y; + } else { + view_frame_y = ui_view.GetHeight() / 2 - game.SpriteInfos[viptr->loops[0].frames[0].pic].Height / 2; + } + bigx = ui_view.GetWidth() / 2 - get_fixed_pixel_size(20); + ovr_type = OVER_COMPLETE; + ovr_yp = 0; + tdyp = -1; // center vertically + } else { + // KQ6-style close-up face picture + if (yy < 0 && play.speech_portrait_placement) { + ovr_yp = play.speech_portrait_y; + } else if (yy < 0) + ovr_yp = adjust_y_for_guis(ovr_yp); + else + ovr_yp = yy; + + closeupface = BitmapHelper::CreateTransparentBitmap(bigx + 1, bigy + 1, spriteset[viptr->loops[0].frames[0].pic]->GetColorDepth()); + ovr_type = OVER_PICTURE; + + if (yy < 0) + tdyp = ovr_yp + get_textwindow_top_border_height(play.speech_textwindow_gui); + } + const ViewFrame *vf = &viptr->loops[0].frames[0]; + const bool closeupface_has_alpha = (game.SpriteInfos[vf->pic].Flags & SPF_ALPHACHANNEL) != 0; + DrawViewFrame(closeupface, vf, view_frame_x, view_frame_y); + + int overlay_x = get_fixed_pixel_size(10); + if (xx < 0) { + tdxp = bigx + get_textwindow_border_width(play.speech_textwindow_gui) / 2; + if (play.speech_portrait_placement) { + overlay_x = play.speech_portrait_x; + tdxp += overlay_x + get_fixed_pixel_size(6); + } else { + tdxp += get_fixed_pixel_size(16); + } + + int maxWidth = (ui_view.GetWidth() - tdxp) - get_fixed_pixel_size(5) - + get_textwindow_border_width(play.speech_textwindow_gui) / 2; + + if (bwidth > maxWidth) + bwidth = maxWidth; + } else { + tdxp = xx + bigx + get_fixed_pixel_size(8); + overlay_x = xx; + } + + // allow the text box to be shrunk to fit the text + allowShrink = 1; + + // if the portrait's on the right, swap it round + if (portrait_on_right) { + if ((xx < 0) || (widd < 0)) { + tdxp = get_fixed_pixel_size(9); + if (play.speech_portrait_placement) { + overlay_x = (ui_view.GetWidth() - bigx) - play.speech_portrait_x; + int maxWidth = overlay_x - tdxp - get_fixed_pixel_size(9) - + get_textwindow_border_width(play.speech_textwindow_gui) / 2; + if (bwidth > maxWidth) + bwidth = maxWidth; + } else { + overlay_x = (ui_view.GetWidth() - bigx) - get_fixed_pixel_size(5); + } + } else { + overlay_x = (xx + widd - bigx) - get_fixed_pixel_size(5); + tdxp = xx; + } + tdxp += get_textwindow_border_width(play.speech_textwindow_gui) / 2; + allowShrink = 2; + } + if (game.options[OPT_SPEECHTYPE] == 3) + overlay_x = 0; + face_talking = add_screen_overlay(overlay_x, ovr_yp, ovr_type, closeupface, closeupface_has_alpha); + facetalkframe = 0; + facetalkwait = viptr->loops[0].frames[0].speed + GetCharacterSpeechAnimationDelay(speakingChar); + facetalkloop = 0; + facetalkview = useview; + facetalkrepeat = (isThought) ? 0 : 1; + facetalkBlinkLoop = 0; + facetalkAllowBlink = 1; + if ((isThought) && (speakingChar->flags & CHF_NOBLINKANDTHINK)) + facetalkAllowBlink = 0; + facetalkchar = &game.chars[aschar]; + if (facetalkchar->blinktimer < 0) + facetalkchar->blinktimer = facetalkchar->blinkinterval; + textcol = -textcol; + overlayPositionFixed = true; + } else if (useview >= 0) { + // Lucasarts-style speech + our_eip = 154; + + oldview = speakingChar->view; + oldloop = speakingChar->loop; + speakingChar->animating = 1 | (GetCharacterSpeechAnimationDelay(speakingChar) << 8); + // only repeat if speech, not thought + if (!isThought) + speakingChar->animating |= CHANIM_REPEAT; + + speakingChar->view = useview; + speakingChar->frame = 0; + speakingChar->flags |= CHF_FIXVIEW; + + if (speakingChar->loop >= views[speakingChar->view].numLoops) { + // current character loop is outside the normal talking directions + speakingChar->loop = 0; + } + + facetalkBlinkLoop = speakingChar->loop; + + if (speakingChar->on && // don't bother checking if character is not visible (also fixes 'Trilby's Notes' legacy game) + ((speakingChar->loop >= views[speakingChar->view].numLoops) || + (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1))) { + quitprintf("!Unable to display speech because the character %s has an invalid speech view (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame); + } + + // set up the speed of the first frame + speakingChar->wait = GetCharacterSpeechAnimationDelay(speakingChar) + + views[speakingChar->view].loops[speakingChar->loop].frames[0].speed; + + if (widd < 0) { + bwidth = ui_view.GetWidth() / 2 + ui_view.GetWidth() / 6; + // If they are close to the screen edge, make the text narrower + int relx = play.RoomToScreenX(data_to_game_coord(speakingChar->x)); + if ((relx < ui_view.GetWidth() / 4) || (relx > ui_view.GetWidth() - (ui_view.GetWidth() / 4))) + bwidth -= ui_view.GetWidth() / 5; + } + /* this causes the text to bob up and down as they talk + tdxp = OVR_AUTOPLACE; + tdyp = aschar;*/ + if (!isThought) // set up the lip sync if not thinking + char_speaking = aschar; + + } + } else + allowShrink = 1; + + // it wants the centred position, so make it so + if ((xx >= 0) && (tdxp < 0)) + tdxp -= widd / 2; + + // if they used DisplaySpeechAt, then use the supplied width + if ((widd > 0) && (isThought == 0)) + allowShrink = 0; + + if (isThought) + char_thinking = aschar; + + our_eip = 155; + _display_at(tdxp, tdyp, bwidth, texx, DISPLAYTEXT_SPEECH, textcol, isThought, allowShrink, overlayPositionFixed); + our_eip = 156; + if ((play.in_conversation > 0) && (game.options[OPT_SPEECHTYPE] == 3)) + closeupface = nullptr; + if (closeupface != nullptr) + remove_screen_overlay(ovr_type); + mark_screen_dirty(); + face_talking = -1; + facetalkchar = nullptr; + our_eip = 157; + if (oldview >= 0) { + speakingChar->flags &= ~CHF_FIXVIEW; + if (viewWasLocked) + speakingChar->flags |= CHF_FIXVIEW; + speakingChar->view = oldview; + + // Don't reset the loop in 2.x games + if (loaded_game_file_version > kGameVersion_272) + speakingChar->loop = oldloop; + + speakingChar->animating = 0; + speakingChar->frame = charFrameWas; + speakingChar->wait = 0; + speakingChar->idleleft = speakingChar->idletime; + // restart the idle animation straight away + charextra[aschar].process_idle_this_time = 1; + } + char_speaking = -1; + char_thinking = -1; + if (play.IsBlockingVoiceSpeech()) + stop_voice_speech(); } int get_character_currently_talking() { - if ((face_talking >= 0) && (facetalkrepeat)) - return facetalkchar->index_id; - else if (char_speaking >= 0) - return char_speaking; + if ((face_talking >= 0) && (facetalkrepeat)) + return facetalkchar->index_id; + else if (char_speaking >= 0) + return char_speaking; - return -1; + return -1; } -void DisplaySpeech(const char*texx, int aschar) { - _displayspeech (texx, aschar, -1, -1, -1, 0); +void DisplaySpeech(const char *texx, int aschar) { + _displayspeech(texx, aschar, -1, -1, -1, 0); } // Calculate which frame of the loop to use for this character of // speech -int GetLipSyncFrame (const char *curtex, int *stroffs) { - /*char *frameletters[MAXLIPSYNCFRAMES] = - {"./,/ ", "A", "O", "F/V", "D/N/G/L/R", "B/P/M", - "Y/H/K/Q/C", "I/T/E/X/th", "U/W", "S/Z/J/ch", NULL, - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};*/ - - int bestfit_len = 0, bestfit = game.default_lipsync_frame; - for (int aa = 0; aa < MAXLIPSYNCFRAMES; aa++) { - char *tptr = game.lipSyncFrameLetters[aa]; - while (tptr[0] != 0) { - int lenthisbit = strlen(tptr); - if (strchr(tptr, '/')) - lenthisbit = strchr(tptr, '/') - tptr; - - if ((ags_strnicmp (curtex, tptr, lenthisbit) == 0) && (lenthisbit > bestfit_len)) { - bestfit = aa; - bestfit_len = lenthisbit; - } - tptr += lenthisbit; - while (tptr[0] == '/') - tptr++; - } - } - // If it's an unknown character, use the default frame - if (bestfit_len == 0) - bestfit_len = 1; - *stroffs += bestfit_len; - return bestfit; +int GetLipSyncFrame(const char *curtex, int *stroffs) { + /*char *frameletters[MAXLIPSYNCFRAMES] = + {"./,/ ", "A", "O", "F/V", "D/N/G/L/R", "B/P/M", + "Y/H/K/Q/C", "I/T/E/X/th", "U/W", "S/Z/J/ch", NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};*/ + + int bestfit_len = 0, bestfit = game.default_lipsync_frame; + for (int aa = 0; aa < MAXLIPSYNCFRAMES; aa++) { + char *tptr = game.lipSyncFrameLetters[aa]; + while (tptr[0] != 0) { + int lenthisbit = strlen(tptr); + if (strchr(tptr, '/')) + lenthisbit = strchr(tptr, '/') - tptr; + + if ((ags_strnicmp(curtex, tptr, lenthisbit) == 0) && (lenthisbit > bestfit_len)) { + bestfit = aa; + bestfit_len = lenthisbit; + } + tptr += lenthisbit; + while (tptr[0] == '/') + tptr++; + } + } + // If it's an unknown character, use the default frame + if (bestfit_len == 0) + bestfit_len = 1; + *stroffs += bestfit_len; + return bestfit; } int update_lip_sync(int talkview, int talkloop, int *talkframeptr) { - int talkframe = talkframeptr[0]; - int talkwait = 0; - - // lip-sync speech - const char *nowsaying = &text_lips_text[text_lips_offset]; - // if it's an apostraphe, skip it (we'll, I'll, etc) - if (nowsaying[0] == '\'') { - text_lips_offset++; - nowsaying++; - } - - if (text_lips_offset >= (int)strlen(text_lips_text)) - talkframe = 0; - else { - talkframe = GetLipSyncFrame (nowsaying, &text_lips_offset); - if (talkframe >= views[talkview].loops[talkloop].numFrames) - talkframe = 0; - } - - talkwait = loops_per_character + views[talkview].loops[talkloop].frames[talkframe].speed; - - talkframeptr[0] = talkframe; - return talkwait; -} - -Rect GetCharacterRoomBBox(int charid, bool use_frame_0) -{ - int width, height; - const CharacterExtras& chex = charextra[charid]; - const CharacterInfo& chin = game.chars[charid]; - int frame = use_frame_0 ? 0 : chin.frame; - int pic = views[chin.view].loops[chin.loop].frames[frame].pic; - scale_sprite_size(pic, chex.zoom, &width, &height); - return RectWH(chin.x - width / 2, chin.y - height, width, height); -} - -PViewport FindNearestViewport(int charid) -{ - Rect bbox = GetCharacterRoomBBox(charid, true); - float min_dist = -1.f; - PViewport nearest_view; - for (int i = 0; i < play.GetRoomViewportCount(); ++i) - { - auto view = play.GetRoomViewport(i); - if (!view->IsVisible()) - continue; - auto cam = view->GetCamera(); - if (!cam) - continue; - Rect camr = cam->GetRect(); - float dist = DistanceBetween(bbox, camr); - if (dist == 0.f) - return view; - if (min_dist < 0.f || dist < min_dist) - { - min_dist = dist; - nearest_view = view; - } - } - return nearest_view ? nearest_view : play.GetRoomViewport(0); + int talkframe = talkframeptr[0]; + int talkwait = 0; + + // lip-sync speech + const char *nowsaying = &text_lips_text[text_lips_offset]; + // if it's an apostraphe, skip it (we'll, I'll, etc) + if (nowsaying[0] == '\'') { + text_lips_offset++; + nowsaying++; + } + + if (text_lips_offset >= (int)strlen(text_lips_text)) + talkframe = 0; + else { + talkframe = GetLipSyncFrame(nowsaying, &text_lips_offset); + if (talkframe >= views[talkview].loops[talkloop].numFrames) + talkframe = 0; + } + + talkwait = loops_per_character + views[talkview].loops[talkloop].frames[talkframe].speed; + + talkframeptr[0] = talkframe; + return talkwait; +} + +Rect GetCharacterRoomBBox(int charid, bool use_frame_0) { + int width, height; + const CharacterExtras &chex = charextra[charid]; + const CharacterInfo &chin = game.chars[charid]; + int frame = use_frame_0 ? 0 : chin.frame; + int pic = views[chin.view].loops[chin.loop].frames[frame].pic; + scale_sprite_size(pic, chex.zoom, &width, &height); + return RectWH(chin.x - width / 2, chin.y - height, width, height); +} + +PViewport FindNearestViewport(int charid) { + Rect bbox = GetCharacterRoomBBox(charid, true); + float min_dist = -1.f; + PViewport nearest_view; + for (int i = 0; i < play.GetRoomViewportCount(); ++i) { + auto view = play.GetRoomViewport(i); + if (!view->IsVisible()) + continue; + auto cam = view->GetCamera(); + if (!cam) + continue; + Rect camr = cam->GetRect(); + float dist = DistanceBetween(bbox, camr); + if (dist == 0.f) + return view; + if (min_dist < 0.f || dist < min_dist) { + min_dist = dist; + nearest_view = view; + } + } + return nearest_view ? nearest_view : play.GetRoomViewport(0); } //============================================================================= @@ -2967,290 +2854,240 @@ PViewport FindNearestViewport(int charid) extern ScriptString myScriptStringImpl; // void | CharacterInfo *chaa, ScriptInvItem *invi, int addIndex -RuntimeScriptValue Sc_Character_AddInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_AddInventory, ScriptInvItem); +RuntimeScriptValue Sc_Character_AddInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_AddInventory, ScriptInvItem); } // void | CharacterInfo *chaa, int x, int y -RuntimeScriptValue Sc_Character_AddWaypoint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(CharacterInfo, Character_AddWaypoint); +RuntimeScriptValue Sc_Character_AddWaypoint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_AddWaypoint); } // void | CharacterInfo *chaa, int loop, int delay, int repeat, int blocking, int direction -RuntimeScriptValue Sc_Character_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Animate); +RuntimeScriptValue Sc_Character_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Animate); } -RuntimeScriptValue Sc_Character_AnimateFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT6(CharacterInfo, Character_AnimateFrom); +RuntimeScriptValue Sc_Character_AnimateFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT6(CharacterInfo, Character_AnimateFrom); } // void | CharacterInfo *chaa, int room, int x, int y -RuntimeScriptValue Sc_Character_ChangeRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(CharacterInfo, Character_ChangeRoom); +RuntimeScriptValue Sc_Character_ChangeRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_ChangeRoom); } -RuntimeScriptValue Sc_Character_ChangeRoomSetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(CharacterInfo, Character_ChangeRoomSetLoop); +RuntimeScriptValue Sc_Character_ChangeRoomSetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_ChangeRoomSetLoop); } // void | CharacterInfo *chaa, int room, int newPos -RuntimeScriptValue Sc_Character_ChangeRoomAutoPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(CharacterInfo, Character_ChangeRoomAutoPosition); +RuntimeScriptValue Sc_Character_ChangeRoomAutoPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_ChangeRoomAutoPosition); } // void | CharacterInfo *chap, int vii -RuntimeScriptValue Sc_Character_ChangeView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_ChangeView); +RuntimeScriptValue Sc_Character_ChangeView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_ChangeView); } // void | CharacterInfo *char1, CharacterInfo *char2, int blockingStyle -RuntimeScriptValue Sc_Character_FaceCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceCharacter, CharacterInfo); +RuntimeScriptValue Sc_Character_FaceCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceCharacter, CharacterInfo); } // void | CharacterInfo *char1, int direction, int blockingStyle -RuntimeScriptValue Sc_Character_FaceDirection(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(CharacterInfo, Character_FaceDirection); +RuntimeScriptValue Sc_Character_FaceDirection(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_FaceDirection); } // void | CharacterInfo *char1, int xx, int yy, int blockingStyle -RuntimeScriptValue Sc_Character_FaceLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(CharacterInfo, Character_FaceLocation); +RuntimeScriptValue Sc_Character_FaceLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_FaceLocation); } // void | CharacterInfo *char1, ScriptObject *obj, int blockingStyle -RuntimeScriptValue Sc_Character_FaceObject(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceObject, ScriptObject); +RuntimeScriptValue Sc_Character_FaceObject(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ_PINT(CharacterInfo, Character_FaceObject, ScriptObject); } // void | CharacterInfo *chaa, CharacterInfo *tofollow, int distaway, int eagerness -RuntimeScriptValue Sc_Character_FollowCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ_PINT2(CharacterInfo, Character_FollowCharacter, CharacterInfo); +RuntimeScriptValue Sc_Character_FollowCharacter(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ_PINT2(CharacterInfo, Character_FollowCharacter, CharacterInfo); } // int (CharacterInfo *chaa, const char *property) -RuntimeScriptValue Sc_Character_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(CharacterInfo, Character_GetProperty, const char); +RuntimeScriptValue Sc_Character_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(CharacterInfo, Character_GetProperty, const char); } // void (CharacterInfo *chaa, const char *property, char *bufer) -RuntimeScriptValue Sc_Character_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ2(CharacterInfo, Character_GetPropertyText, const char, char); +RuntimeScriptValue Sc_Character_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ2(CharacterInfo, Character_GetPropertyText, const char, char); } // const char* (CharacterInfo *chaa, const char *property) -RuntimeScriptValue Sc_Character_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_POBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetTextProperty, const char); +RuntimeScriptValue Sc_Character_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_POBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetTextProperty, const char); } -RuntimeScriptValue Sc_Character_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ_PINT(CharacterInfo, Character_SetProperty, const char); +RuntimeScriptValue Sc_Character_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ_PINT(CharacterInfo, Character_SetProperty, const char); } -RuntimeScriptValue Sc_Character_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ2(CharacterInfo, Character_SetTextProperty, const char, const char); +RuntimeScriptValue Sc_Character_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ2(CharacterInfo, Character_SetTextProperty, const char, const char); } // int (CharacterInfo *chaa, ScriptInvItem *invi) -RuntimeScriptValue Sc_Character_HasInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(CharacterInfo, Character_HasInventory, ScriptInvItem); +RuntimeScriptValue Sc_Character_HasInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(CharacterInfo, Character_HasInventory, ScriptInvItem); } // int (CharacterInfo *char1, CharacterInfo *char2) -RuntimeScriptValue Sc_Character_IsCollidingWithChar(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithChar, CharacterInfo); +RuntimeScriptValue Sc_Character_IsCollidingWithChar(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithChar, CharacterInfo); } // int (CharacterInfo *chin, ScriptObject *objid) -RuntimeScriptValue Sc_Character_IsCollidingWithObject(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithObject, ScriptObject); +RuntimeScriptValue Sc_Character_IsCollidingWithObject(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(CharacterInfo, Character_IsCollidingWithObject, ScriptObject); } -RuntimeScriptValue Sc_Character_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_PINT(CharacterInfo, Character_IsInteractionAvailable); +RuntimeScriptValue Sc_Character_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_PINT(CharacterInfo, Character_IsInteractionAvailable); } // void (CharacterInfo *chap, int vii) -RuntimeScriptValue Sc_Character_LockView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_LockView); +RuntimeScriptValue Sc_Character_LockView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_LockView); } // void (CharacterInfo *chap, int vii, int stopMoving) -RuntimeScriptValue Sc_Character_LockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(CharacterInfo, Character_LockViewEx); +RuntimeScriptValue Sc_Character_LockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_LockViewEx); } // void (CharacterInfo *chap, int vii, int loop, int align) -RuntimeScriptValue Sc_Character_LockViewAligned_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewAligned_Old); +RuntimeScriptValue Sc_Character_LockViewAligned_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewAligned_Old); } // void (CharacterInfo *chap, int vii, int loop, int align, int stopMoving) -RuntimeScriptValue Sc_Character_LockViewAlignedEx_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewAlignedEx_Old); +RuntimeScriptValue Sc_Character_LockViewAlignedEx_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewAlignedEx_Old); } -RuntimeScriptValue Sc_Character_LockViewAligned(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewAligned); +RuntimeScriptValue Sc_Character_LockViewAligned(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewAligned); } -RuntimeScriptValue Sc_Character_LockViewAlignedEx(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewAlignedEx); +RuntimeScriptValue Sc_Character_LockViewAlignedEx(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewAlignedEx); } // void (CharacterInfo *chaa, int view, int loop, int frame) -RuntimeScriptValue Sc_Character_LockViewFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewFrame); +RuntimeScriptValue Sc_Character_LockViewFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewFrame); } // void (CharacterInfo *chaa, int view, int loop, int frame, int stopMoving) -RuntimeScriptValue Sc_Character_LockViewFrameEx(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewFrameEx); +RuntimeScriptValue Sc_Character_LockViewFrameEx(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewFrameEx); } // void (CharacterInfo *chap, int vii, int xoffs, int yoffs) -RuntimeScriptValue Sc_Character_LockViewOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewOffset); +RuntimeScriptValue Sc_Character_LockViewOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_LockViewOffset); } // void (CharacterInfo *chap, int vii, int xoffs, int yoffs, int stopMoving) -RuntimeScriptValue Sc_Character_LockViewOffsetEx(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewOffsetEx); +RuntimeScriptValue Sc_Character_LockViewOffsetEx(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_LockViewOffsetEx); } // void (CharacterInfo *chap, ScriptInvItem *invi) -RuntimeScriptValue Sc_Character_LoseInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(CharacterInfo, Character_LoseInventory, ScriptInvItem); +RuntimeScriptValue Sc_Character_LoseInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(CharacterInfo, Character_LoseInventory, ScriptInvItem); } -// void (CharacterInfo *chaa, int x, int y, int blocking, int direct) -RuntimeScriptValue Sc_Character_Move(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Move); +// void (CharacterInfo *chaa, int x, int y, int blocking, int direct) +RuntimeScriptValue Sc_Character_Move(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Move); } -// void (CharacterInfo *chap) -RuntimeScriptValue Sc_Character_PlaceOnWalkableArea(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(CharacterInfo, Character_PlaceOnWalkableArea); +// void (CharacterInfo *chap) +RuntimeScriptValue Sc_Character_PlaceOnWalkableArea(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(CharacterInfo, Character_PlaceOnWalkableArea); } // void (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_RemoveTint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(CharacterInfo, Character_RemoveTint); +RuntimeScriptValue Sc_Character_RemoveTint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(CharacterInfo, Character_RemoveTint); } // void (CharacterInfo *chaa, int mood) -RuntimeScriptValue Sc_Character_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_RunInteraction); +RuntimeScriptValue Sc_Character_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_RunInteraction); } // void (CharacterInfo *chaa, const char *texx, ...) -RuntimeScriptValue Sc_Character_Say(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_SCRIPT_SPRINTF(Character_Say, 1); - Character_Say((CharacterInfo*)self, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_Character_Say(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_SCRIPT_SPRINTF(Character_Say, 1); + Character_Say((CharacterInfo *)self, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (CharacterInfo *chaa, int x, int y, int width, const char *texx) -RuntimeScriptValue Sc_Character_SayAt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3_POBJ(CharacterInfo, Character_SayAt, const char); +RuntimeScriptValue Sc_Character_SayAt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3_POBJ(CharacterInfo, Character_SayAt, const char); } // ScriptOverlay* (CharacterInfo *chaa, const char *texx) -RuntimeScriptValue Sc_Character_SayBackground(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJAUTO_POBJ(CharacterInfo, ScriptOverlay, Character_SayBackground, const char); +RuntimeScriptValue Sc_Character_SayBackground(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJAUTO_POBJ(CharacterInfo, ScriptOverlay, Character_SayBackground, const char); } // void (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_SetAsPlayer(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(CharacterInfo, Character_SetAsPlayer); +RuntimeScriptValue Sc_Character_SetAsPlayer(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(CharacterInfo, Character_SetAsPlayer); } // void (CharacterInfo *chaa, int iview, int itime) -RuntimeScriptValue Sc_Character_SetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIdleView); +RuntimeScriptValue Sc_Character_SetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIdleView); } -RuntimeScriptValue Sc_Character_HasExplicitLight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(CharacterInfo, Character_GetHasExplicitLight); +RuntimeScriptValue Sc_Character_HasExplicitLight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(CharacterInfo, Character_GetHasExplicitLight); } -RuntimeScriptValue Sc_Character_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetLightLevel); +RuntimeScriptValue Sc_Character_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetLightLevel); } -RuntimeScriptValue Sc_Character_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLightLevel); +RuntimeScriptValue Sc_Character_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLightLevel); } -RuntimeScriptValue Sc_Character_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetTintBlue); +RuntimeScriptValue Sc_Character_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetTintBlue); } -RuntimeScriptValue Sc_Character_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetTintGreen); +RuntimeScriptValue Sc_Character_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetTintGreen); } -RuntimeScriptValue Sc_Character_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetTintRed); +RuntimeScriptValue Sc_Character_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetTintRed); } -RuntimeScriptValue Sc_Character_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetTintSaturation); +RuntimeScriptValue Sc_Character_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetTintSaturation); } -RuntimeScriptValue Sc_Character_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetTintLuminance); +RuntimeScriptValue Sc_Character_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetTintLuminance); } /* @@ -3260,546 +3097,455 @@ RuntimeScriptValue Sc_Character_SetOption(void *self, const RuntimeScriptValue * */ // void (CharacterInfo *chaa, int xspeed, int yspeed) -RuntimeScriptValue Sc_Character_SetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetSpeed); +RuntimeScriptValue Sc_Character_SetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetSpeed); } // void (CharacterInfo *charp) -RuntimeScriptValue Sc_Character_StopMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(CharacterInfo, Character_StopMoving); +RuntimeScriptValue Sc_Character_StopMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(CharacterInfo, Character_StopMoving); } // void (CharacterInfo *chaa, const char *texx, ...) -RuntimeScriptValue Sc_Character_Think(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_SCRIPT_SPRINTF(Character_Think, 1); - Character_Think((CharacterInfo*)self, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_Character_Think(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_SCRIPT_SPRINTF(Character_Think, 1); + Character_Think((CharacterInfo *)self, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } //void (CharacterInfo *chaa, int red, int green, int blue, int opacity, int luminance) -RuntimeScriptValue Sc_Character_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Tint); +RuntimeScriptValue Sc_Character_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(CharacterInfo, Character_Tint); } // void (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_UnlockView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(CharacterInfo, Character_UnlockView); +RuntimeScriptValue Sc_Character_UnlockView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(CharacterInfo, Character_UnlockView); } // void (CharacterInfo *chaa, int stopMoving) -RuntimeScriptValue Sc_Character_UnlockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_UnlockViewEx); +RuntimeScriptValue Sc_Character_UnlockViewEx(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_UnlockViewEx); } // void (CharacterInfo *chaa, int x, int y, int blocking, int direct) -RuntimeScriptValue Sc_Character_Walk(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Walk); +RuntimeScriptValue Sc_Character_Walk(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(CharacterInfo, Character_Walk); } // void (CharacterInfo *chaa, int xx, int yy, int blocking) -RuntimeScriptValue Sc_Character_WalkStraight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(CharacterInfo, Character_WalkStraight); +RuntimeScriptValue Sc_Character_WalkStraight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(CharacterInfo, Character_WalkStraight); } -RuntimeScriptValue Sc_GetCharacterAtRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtRoom); +RuntimeScriptValue Sc_GetCharacterAtRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtRoom); } // CharacterInfo *(int xx, int yy) -RuntimeScriptValue Sc_GetCharacterAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtScreen); +RuntimeScriptValue Sc_GetCharacterAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtScreen); } // ScriptInvItem* (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(CharacterInfo, ScriptInvItem, ccDynamicInv, Character_GetActiveInventory); +RuntimeScriptValue Sc_Character_GetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(CharacterInfo, ScriptInvItem, ccDynamicInv, Character_GetActiveInventory); } // void (CharacterInfo *chaa, ScriptInvItem* iit) -RuntimeScriptValue Sc_Character_SetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetActiveInventory, ScriptInvItem); +RuntimeScriptValue Sc_Character_SetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetActiveInventory, ScriptInvItem); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetAnimating); +RuntimeScriptValue Sc_Character_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetAnimating); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetAnimationSpeed); +RuntimeScriptValue Sc_Character_GetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetAnimationSpeed); } // void (CharacterInfo *chaa, int newval) -RuntimeScriptValue Sc_Character_SetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetAnimationSpeed); +RuntimeScriptValue Sc_Character_SetAnimationSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetAnimationSpeed); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetBaseline); +RuntimeScriptValue Sc_Character_GetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetBaseline); } // void (CharacterInfo *chaa, int basel) -RuntimeScriptValue Sc_Character_SetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBaseline); +RuntimeScriptValue Sc_Character_SetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBaseline); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetBlinkInterval); +RuntimeScriptValue Sc_Character_GetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetBlinkInterval); } // void (CharacterInfo *chaa, int interval) -RuntimeScriptValue Sc_Character_SetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkInterval); +RuntimeScriptValue Sc_Character_SetBlinkInterval(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkInterval); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetBlinkView); +RuntimeScriptValue Sc_Character_GetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetBlinkView); } // void (CharacterInfo *chaa, int vii) -RuntimeScriptValue Sc_Character_SetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkView); +RuntimeScriptValue Sc_Character_SetBlinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkView); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetBlinkWhileThinking); +RuntimeScriptValue Sc_Character_GetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetBlinkWhileThinking); } // void (CharacterInfo *chaa, int yesOrNo) -RuntimeScriptValue Sc_Character_SetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkWhileThinking); +RuntimeScriptValue Sc_Character_SetBlinkWhileThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlinkWhileThinking); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetBlockingHeight); +RuntimeScriptValue Sc_Character_GetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetBlockingHeight); } // void (CharacterInfo *chaa, int hit) -RuntimeScriptValue Sc_Character_SetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingHeight); +RuntimeScriptValue Sc_Character_SetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingHeight); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetBlockingWidth); +RuntimeScriptValue Sc_Character_GetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetBlockingWidth); } // void (CharacterInfo *chaa, int wid) -RuntimeScriptValue Sc_Character_SetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingWidth); +RuntimeScriptValue Sc_Character_SetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetBlockingWidth); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetClickable); +RuntimeScriptValue Sc_Character_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetClickable); } // void (CharacterInfo *chaa, int clik) -RuntimeScriptValue Sc_Character_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetClickable); +RuntimeScriptValue Sc_Character_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetClickable); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetDiagonalWalking); +RuntimeScriptValue Sc_Character_GetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetDiagonalWalking); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetDiagonalWalking); +RuntimeScriptValue Sc_Character_SetDiagonalWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetDiagonalWalking); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetFrame); +RuntimeScriptValue Sc_Character_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetFrame); } // void (CharacterInfo *chaa, int newval) -RuntimeScriptValue Sc_Character_SetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetFrame); +RuntimeScriptValue Sc_Character_SetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetFrame); } -RuntimeScriptValue Sc_Character_GetHasExplicitTint_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetHasExplicitTint_Old); +RuntimeScriptValue Sc_Character_GetHasExplicitTint_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetHasExplicitTint_Old); } -RuntimeScriptValue Sc_Character_GetHasExplicitTint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetHasExplicitTint); +RuntimeScriptValue Sc_Character_GetHasExplicitTint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetHasExplicitTint); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetID); +RuntimeScriptValue Sc_Character_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetID); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetIdleView); +RuntimeScriptValue Sc_Character_GetIdleView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetIdleView); } // int (CharacterInfo *chaa, int index) -RuntimeScriptValue Sc_Character_GetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(CharacterInfo, Character_GetIInventoryQuantity); +RuntimeScriptValue Sc_Character_GetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(CharacterInfo, Character_GetIInventoryQuantity); } // void (CharacterInfo *chaa, int index, int quant) -RuntimeScriptValue Sc_Character_SetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIInventoryQuantity); +RuntimeScriptValue Sc_Character_SetIInventoryQuantity(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(CharacterInfo, Character_SetIInventoryQuantity); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreLighting); +RuntimeScriptValue Sc_Character_GetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreLighting); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreLighting); +RuntimeScriptValue Sc_Character_SetIgnoreLighting(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreLighting); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreScaling); +RuntimeScriptValue Sc_Character_GetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreScaling); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreScaling); +RuntimeScriptValue Sc_Character_SetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreScaling); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreWalkbehinds); +RuntimeScriptValue Sc_Character_GetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetIgnoreWalkbehinds); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreWalkbehinds); +RuntimeScriptValue Sc_Character_SetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetIgnoreWalkbehinds); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetLoop); +RuntimeScriptValue Sc_Character_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetLoop); } // void (CharacterInfo *chaa, int newval) -RuntimeScriptValue Sc_Character_SetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLoop); +RuntimeScriptValue Sc_Character_SetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetLoop); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetManualScaling); +RuntimeScriptValue Sc_Character_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetManualScaling); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetMovementLinkedToAnimation); +RuntimeScriptValue Sc_Character_GetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetMovementLinkedToAnimation); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetMovementLinkedToAnimation); +RuntimeScriptValue Sc_Character_SetMovementLinkedToAnimation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetMovementLinkedToAnimation); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetMoving); +RuntimeScriptValue Sc_Character_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetMoving); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetDestinationX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetDestinationX); +RuntimeScriptValue Sc_Character_GetDestinationX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetDestinationX); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetDestinationY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetDestinationY); +RuntimeScriptValue Sc_Character_GetDestinationY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetDestinationY); } // const char* (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetName); +RuntimeScriptValue Sc_Character_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetName); } // void (CharacterInfo *chaa, const char *newName) -RuntimeScriptValue Sc_Character_SetName(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetName, const char); +RuntimeScriptValue Sc_Character_SetName(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(CharacterInfo, Character_SetName, const char); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetNormalView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetNormalView); +RuntimeScriptValue Sc_Character_GetNormalView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetNormalView); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetPreviousRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetPreviousRoom); +RuntimeScriptValue Sc_Character_GetPreviousRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetPreviousRoom); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetRoom); +RuntimeScriptValue Sc_Character_GetRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetRoom); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetScaleMoveSpeed); +RuntimeScriptValue Sc_Character_GetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetScaleMoveSpeed); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleMoveSpeed); +RuntimeScriptValue Sc_Character_SetScaleMoveSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleMoveSpeed); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetScaleVolume); +RuntimeScriptValue Sc_Character_GetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetScaleVolume); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleVolume); +RuntimeScriptValue Sc_Character_SetScaleVolume(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaleVolume); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetScaling); +RuntimeScriptValue Sc_Character_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetScaling); } // void (CharacterInfo *chaa, int zoomlevel) -RuntimeScriptValue Sc_Character_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaling); +RuntimeScriptValue Sc_Character_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetScaling); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetSolid); +RuntimeScriptValue Sc_Character_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetSolid); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSolid); +RuntimeScriptValue Sc_Character_SetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSolid); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetSpeaking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetSpeaking); +RuntimeScriptValue Sc_Character_GetSpeaking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetSpeaking); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetSpeakingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetSpeakingFrame); +RuntimeScriptValue Sc_Character_GetSpeakingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetSpeakingFrame); } // int (CharacterInfo *cha) -RuntimeScriptValue Sc_GetCharacterSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, GetCharacterSpeechAnimationDelay); +RuntimeScriptValue Sc_GetCharacterSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, GetCharacterSpeechAnimationDelay); } // void (CharacterInfo *chaa, int newDelay) -RuntimeScriptValue Sc_Character_SetSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechAnimationDelay); +RuntimeScriptValue Sc_Character_SetSpeechAnimationDelay(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechAnimationDelay); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetSpeechColor); +RuntimeScriptValue Sc_Character_GetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetSpeechColor); } // void (CharacterInfo *chaa, int ncol) -RuntimeScriptValue Sc_Character_SetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechColor); +RuntimeScriptValue Sc_Character_SetSpeechColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechColor); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetSpeechView); +RuntimeScriptValue Sc_Character_GetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetSpeechView); } // void (CharacterInfo *chaa, int vii) -RuntimeScriptValue Sc_Character_SetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechView); +RuntimeScriptValue Sc_Character_SetSpeechView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetSpeechView); } -RuntimeScriptValue Sc_Character_GetThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(CharacterInfo, Character_GetThinking); +RuntimeScriptValue Sc_Character_GetThinking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(CharacterInfo, Character_GetThinking); } -RuntimeScriptValue Sc_Character_GetThinkingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetThinkingFrame); +RuntimeScriptValue Sc_Character_GetThinkingFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetThinkingFrame); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetThinkView); +RuntimeScriptValue Sc_Character_GetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetThinkView); } // void (CharacterInfo *chaa, int vii) -RuntimeScriptValue Sc_Character_SetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetThinkView); +RuntimeScriptValue Sc_Character_SetThinkView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetThinkView); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetTransparency); +RuntimeScriptValue Sc_Character_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetTransparency); } // void (CharacterInfo *chaa, int trans) -RuntimeScriptValue Sc_Character_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTransparency); +RuntimeScriptValue Sc_Character_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTransparency); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetTurnBeforeWalking); +RuntimeScriptValue Sc_Character_GetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetTurnBeforeWalking); } // void (CharacterInfo *chaa, int yesorno) -RuntimeScriptValue Sc_Character_SetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTurnBeforeWalking); +RuntimeScriptValue Sc_Character_SetTurnBeforeWalking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetTurnBeforeWalking); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetView); +RuntimeScriptValue Sc_Character_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetView); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetWalkSpeedX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedX); +RuntimeScriptValue Sc_Character_GetWalkSpeedX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedX); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetWalkSpeedY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedY); +RuntimeScriptValue Sc_Character_GetWalkSpeedY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetWalkSpeedY); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetX); +RuntimeScriptValue Sc_Character_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetX); } // void (CharacterInfo *chaa, int newval) -RuntimeScriptValue Sc_Character_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetX); +RuntimeScriptValue Sc_Character_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetX); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetY); +RuntimeScriptValue Sc_Character_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetY); } // void (CharacterInfo *chaa, int newval) -RuntimeScriptValue Sc_Character_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetY); +RuntimeScriptValue Sc_Character_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetY); } // int (CharacterInfo *chaa) -RuntimeScriptValue Sc_Character_GetZ(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(CharacterInfo, Character_GetZ); +RuntimeScriptValue Sc_Character_GetZ(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(CharacterInfo, Character_GetZ); } // void (CharacterInfo *chaa, int newval) -RuntimeScriptValue Sc_Character_SetZ(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetZ); +RuntimeScriptValue Sc_Character_SetZ(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(CharacterInfo, Character_SetZ); } //============================================================================= @@ -3809,27 +3555,24 @@ RuntimeScriptValue Sc_Character_SetZ(void *self, const RuntimeScriptValue *param //============================================================================= // void (CharacterInfo *chaa, const char *texx, ...) -void ScPl_Character_Say(CharacterInfo *chaa, const char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - Character_Say(chaa, scsf_buffer); +void ScPl_Character_Say(CharacterInfo *chaa, const char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + Character_Say(chaa, scsf_buffer); } // void (CharacterInfo *chaa, const char *texx, ...) -void ScPl_Character_Think(CharacterInfo *chaa, const char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - Character_Think(chaa, scsf_buffer); +void ScPl_Character_Think(CharacterInfo *chaa, const char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + Character_Think(chaa, scsf_buffer); } -void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) -{ - ccAddExternalObjectFunction("Character::AddInventory^2", Sc_Character_AddInventory); +void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) { + ccAddExternalObjectFunction("Character::AddInventory^2", Sc_Character_AddInventory); ccAddExternalObjectFunction("Character::AddWaypoint^2", Sc_Character_AddWaypoint); ccAddExternalObjectFunction("Character::Animate^5", Sc_Character_Animate); - ccAddExternalObjectFunction("Character::Animate^6", Sc_Character_AnimateFrom); + ccAddExternalObjectFunction("Character::Animate^6", Sc_Character_AnimateFrom); ccAddExternalObjectFunction("Character::ChangeRoom^3", Sc_Character_ChangeRoom); - ccAddExternalObjectFunction("Character::ChangeRoom^4", Sc_Character_ChangeRoomSetLoop); + ccAddExternalObjectFunction("Character::ChangeRoom^4", Sc_Character_ChangeRoomSetLoop); ccAddExternalObjectFunction("Character::ChangeRoomAutoPosition^2", Sc_Character_ChangeRoomAutoPosition); ccAddExternalObjectFunction("Character::ChangeView^1", Sc_Character_ChangeView); ccAddExternalObjectFunction("Character::FaceCharacter^2", Sc_Character_FaceCharacter); @@ -3840,24 +3583,21 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalObjectFunction("Character::GetProperty^1", Sc_Character_GetProperty); ccAddExternalObjectFunction("Character::GetPropertyText^2", Sc_Character_GetPropertyText); ccAddExternalObjectFunction("Character::GetTextProperty^1", Sc_Character_GetTextProperty); - ccAddExternalObjectFunction("Character::SetProperty^2", Sc_Character_SetProperty); - ccAddExternalObjectFunction("Character::SetTextProperty^2", Sc_Character_SetTextProperty); + ccAddExternalObjectFunction("Character::SetProperty^2", Sc_Character_SetProperty); + ccAddExternalObjectFunction("Character::SetTextProperty^2", Sc_Character_SetTextProperty); ccAddExternalObjectFunction("Character::HasInventory^1", Sc_Character_HasInventory); ccAddExternalObjectFunction("Character::IsCollidingWithChar^1", Sc_Character_IsCollidingWithChar); ccAddExternalObjectFunction("Character::IsCollidingWithObject^1", Sc_Character_IsCollidingWithObject); - ccAddExternalObjectFunction("Character::IsInteractionAvailable^1", Sc_Character_IsInteractionAvailable); + ccAddExternalObjectFunction("Character::IsInteractionAvailable^1", Sc_Character_IsInteractionAvailable); ccAddExternalObjectFunction("Character::LockView^1", Sc_Character_LockView); ccAddExternalObjectFunction("Character::LockView^2", Sc_Character_LockViewEx); - if (base_api < kScriptAPI_v350) - { - ccAddExternalObjectFunction("Character::LockViewAligned^3", Sc_Character_LockViewAligned_Old); - ccAddExternalObjectFunction("Character::LockViewAligned^4", Sc_Character_LockViewAlignedEx_Old); - } - else - { - ccAddExternalObjectFunction("Character::LockViewAligned^3", Sc_Character_LockViewAligned); - ccAddExternalObjectFunction("Character::LockViewAligned^4", Sc_Character_LockViewAlignedEx); - } + if (base_api < kScriptAPI_v350) { + ccAddExternalObjectFunction("Character::LockViewAligned^3", Sc_Character_LockViewAligned_Old); + ccAddExternalObjectFunction("Character::LockViewAligned^4", Sc_Character_LockViewAlignedEx_Old); + } else { + ccAddExternalObjectFunction("Character::LockViewAligned^3", Sc_Character_LockViewAligned); + ccAddExternalObjectFunction("Character::LockViewAligned^4", Sc_Character_LockViewAlignedEx); + } ccAddExternalObjectFunction("Character::LockViewFrame^3", Sc_Character_LockViewFrame); ccAddExternalObjectFunction("Character::LockViewFrame^4", Sc_Character_LockViewFrameEx); ccAddExternalObjectFunction("Character::LockViewOffset^3", Sc_Character_LockViewOffset); @@ -3872,7 +3612,7 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalObjectFunction("Character::SayBackground^1", Sc_Character_SayBackground); ccAddExternalObjectFunction("Character::SetAsPlayer^0", Sc_Character_SetAsPlayer); ccAddExternalObjectFunction("Character::SetIdleView^2", Sc_Character_SetIdleView); - ccAddExternalObjectFunction("Character::SetLightLevel^1", Sc_Character_SetLightLevel); + ccAddExternalObjectFunction("Character::SetLightLevel^1", Sc_Character_SetLightLevel); //ccAddExternalObjectFunction("Character::SetOption^2", Sc_Character_SetOption); ccAddExternalObjectFunction("Character::SetWalkSpeed^2", Sc_Character_SetSpeed); ccAddExternalObjectFunction("Character::StopMoving^0", Sc_Character_StopMoving); @@ -3883,7 +3623,7 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalObjectFunction("Character::Walk^4", Sc_Character_Walk); ccAddExternalObjectFunction("Character::WalkStraight^3", Sc_Character_WalkStraight); - ccAddExternalStaticFunction("Character::GetAtRoomXY^2", Sc_GetCharacterAtRoom); + ccAddExternalStaticFunction("Character::GetAtRoomXY^2", Sc_GetCharacterAtRoom); ccAddExternalStaticFunction("Character::GetAtScreenXY^2", Sc_GetCharacterAtScreen); ccAddExternalObjectFunction("Character::get_ActiveInventory", Sc_Character_GetActiveInventory); @@ -3911,10 +3651,10 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalObjectFunction("Character::set_DiagonalLoops", Sc_Character_SetDiagonalWalking); ccAddExternalObjectFunction("Character::get_Frame", Sc_Character_GetFrame); ccAddExternalObjectFunction("Character::set_Frame", Sc_Character_SetFrame); - if (base_api < kScriptAPI_v341) - ccAddExternalObjectFunction("Character::get_HasExplicitTint", Sc_Character_GetHasExplicitTint_Old); - else - ccAddExternalObjectFunction("Character::get_HasExplicitTint", Sc_Character_GetHasExplicitTint); + if (base_api < kScriptAPI_v341) + ccAddExternalObjectFunction("Character::get_HasExplicitTint", Sc_Character_GetHasExplicitTint_Old); + else + ccAddExternalObjectFunction("Character::get_HasExplicitTint", Sc_Character_GetHasExplicitTint); ccAddExternalObjectFunction("Character::get_ID", Sc_Character_GetID); ccAddExternalObjectFunction("Character::get_IdleView", Sc_Character_GetIdleView); ccAddExternalObjectFunction("Character::geti_InventoryQuantity", Sc_Character_GetIInventoryQuantity); @@ -3929,8 +3669,8 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalObjectFunction("Character::set_Loop", Sc_Character_SetLoop); ccAddExternalObjectFunction("Character::get_ManualScaling", Sc_Character_GetIgnoreScaling); ccAddExternalObjectFunction("Character::set_ManualScaling", Sc_Character_SetManualScaling); - ccAddExternalObjectFunction("Character::get_MovementLinkedToAnimation",Sc_Character_GetMovementLinkedToAnimation); - ccAddExternalObjectFunction("Character::set_MovementLinkedToAnimation",Sc_Character_SetMovementLinkedToAnimation); + ccAddExternalObjectFunction("Character::get_MovementLinkedToAnimation", Sc_Character_GetMovementLinkedToAnimation); + ccAddExternalObjectFunction("Character::set_MovementLinkedToAnimation", Sc_Character_SetMovementLinkedToAnimation); ccAddExternalObjectFunction("Character::get_Moving", Sc_Character_GetMoving); ccAddExternalObjectFunction("Character::get_Name", Sc_Character_GetName); ccAddExternalObjectFunction("Character::set_Name", Sc_Character_SetName); @@ -3953,8 +3693,8 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalObjectFunction("Character::set_SpeechColor", Sc_Character_SetSpeechColor); ccAddExternalObjectFunction("Character::get_SpeechView", Sc_Character_GetSpeechView); ccAddExternalObjectFunction("Character::set_SpeechView", Sc_Character_SetSpeechView); - ccAddExternalObjectFunction("Character::get_Thinking", Sc_Character_GetThinking); - ccAddExternalObjectFunction("Character::get_ThinkingFrame", Sc_Character_GetThinkingFrame); + ccAddExternalObjectFunction("Character::get_Thinking", Sc_Character_GetThinking); + ccAddExternalObjectFunction("Character::get_ThinkingFrame", Sc_Character_GetThinkingFrame); ccAddExternalObjectFunction("Character::get_ThinkView", Sc_Character_GetThinkView); ccAddExternalObjectFunction("Character::set_ThinkView", Sc_Character_SetThinkView); ccAddExternalObjectFunction("Character::get_Transparency", Sc_Character_GetTransparency); @@ -3977,156 +3717,153 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalObjectFunction("Character::get_z", Sc_Character_GetZ); ccAddExternalObjectFunction("Character::set_z", Sc_Character_SetZ); - ccAddExternalObjectFunction("Character::get_HasExplicitLight", Sc_Character_HasExplicitLight); - ccAddExternalObjectFunction("Character::get_LightLevel", Sc_Character_GetLightLevel); - ccAddExternalObjectFunction("Character::get_TintBlue", Sc_Character_GetTintBlue); - ccAddExternalObjectFunction("Character::get_TintGreen", Sc_Character_GetTintGreen); - ccAddExternalObjectFunction("Character::get_TintRed", Sc_Character_GetTintRed); - ccAddExternalObjectFunction("Character::get_TintSaturation", Sc_Character_GetTintSaturation); - ccAddExternalObjectFunction("Character::get_TintLuminance", Sc_Character_GetTintLuminance); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Character::AddInventory^2", (void*)Character_AddInventory); - ccAddExternalFunctionForPlugin("Character::AddWaypoint^2", (void*)Character_AddWaypoint); - ccAddExternalFunctionForPlugin("Character::Animate^5", (void*)Character_Animate); - ccAddExternalFunctionForPlugin("Character::ChangeRoom^3", (void*)Character_ChangeRoom); - ccAddExternalFunctionForPlugin("Character::ChangeRoomAutoPosition^2", (void*)Character_ChangeRoomAutoPosition); - ccAddExternalFunctionForPlugin("Character::ChangeView^1", (void*)Character_ChangeView); - ccAddExternalFunctionForPlugin("Character::FaceCharacter^2", (void*)Character_FaceCharacter); - ccAddExternalFunctionForPlugin("Character::FaceDirection^2", (void*)Character_FaceDirection); - ccAddExternalFunctionForPlugin("Character::FaceLocation^3", (void*)Character_FaceLocation); - ccAddExternalFunctionForPlugin("Character::FaceObject^2", (void*)Character_FaceObject); - ccAddExternalFunctionForPlugin("Character::FollowCharacter^3", (void*)Character_FollowCharacter); - ccAddExternalFunctionForPlugin("Character::GetProperty^1", (void*)Character_GetProperty); - ccAddExternalFunctionForPlugin("Character::GetPropertyText^2", (void*)Character_GetPropertyText); - ccAddExternalFunctionForPlugin("Character::GetTextProperty^1", (void*)Character_GetTextProperty); - ccAddExternalFunctionForPlugin("Character::HasInventory^1", (void*)Character_HasInventory); - ccAddExternalFunctionForPlugin("Character::IsCollidingWithChar^1", (void*)Character_IsCollidingWithChar); - ccAddExternalFunctionForPlugin("Character::IsCollidingWithObject^1", (void*)Character_IsCollidingWithObject); - ccAddExternalFunctionForPlugin("Character::LockView^1", (void*)Character_LockView); - ccAddExternalFunctionForPlugin("Character::LockView^2", (void*)Character_LockViewEx); - if (base_api < kScriptAPI_v341) - { - ccAddExternalFunctionForPlugin("Character::LockViewAligned^3", (void*)Character_LockViewAligned_Old); - ccAddExternalFunctionForPlugin("Character::LockViewAligned^4", (void*)Character_LockViewAlignedEx_Old); - } - else - { - ccAddExternalFunctionForPlugin("Character::LockViewAligned^3", (void*)Character_LockViewAligned); - ccAddExternalFunctionForPlugin("Character::LockViewAligned^4", (void*)Character_LockViewAlignedEx); - } - ccAddExternalFunctionForPlugin("Character::LockViewFrame^3", (void*)Character_LockViewFrame); - ccAddExternalFunctionForPlugin("Character::LockViewFrame^4", (void*)Character_LockViewFrameEx); - ccAddExternalFunctionForPlugin("Character::LockViewOffset^3", (void*)Character_LockViewOffset); - ccAddExternalFunctionForPlugin("Character::LockViewOffset^4", (void*)Character_LockViewOffset); - ccAddExternalFunctionForPlugin("Character::LoseInventory^1", (void*)Character_LoseInventory); - ccAddExternalFunctionForPlugin("Character::Move^4", (void*)Character_Move); - ccAddExternalFunctionForPlugin("Character::PlaceOnWalkableArea^0", (void*)Character_PlaceOnWalkableArea); - ccAddExternalFunctionForPlugin("Character::RemoveTint^0", (void*)Character_RemoveTint); - ccAddExternalFunctionForPlugin("Character::RunInteraction^1", (void*)Character_RunInteraction); - ccAddExternalFunctionForPlugin("Character::Say^101", (void*)ScPl_Character_Say); - ccAddExternalFunctionForPlugin("Character::SayAt^4", (void*)Character_SayAt); - ccAddExternalFunctionForPlugin("Character::SayBackground^1", (void*)Character_SayBackground); - ccAddExternalFunctionForPlugin("Character::SetAsPlayer^0", (void*)Character_SetAsPlayer); - ccAddExternalFunctionForPlugin("Character::SetIdleView^2", (void*)Character_SetIdleView); - //ccAddExternalFunctionForPlugin("Character::SetOption^2", (void*)Character_SetOption); - ccAddExternalFunctionForPlugin("Character::SetWalkSpeed^2", (void*)Character_SetSpeed); - ccAddExternalFunctionForPlugin("Character::StopMoving^0", (void*)Character_StopMoving); - ccAddExternalFunctionForPlugin("Character::Think^101", (void*)ScPl_Character_Think); - ccAddExternalFunctionForPlugin("Character::Tint^5", (void*)Character_Tint); - ccAddExternalFunctionForPlugin("Character::UnlockView^0", (void*)Character_UnlockView); - ccAddExternalFunctionForPlugin("Character::UnlockView^1", (void*)Character_UnlockViewEx); - ccAddExternalFunctionForPlugin("Character::Walk^4", (void*)Character_Walk); - ccAddExternalFunctionForPlugin("Character::WalkStraight^3", (void*)Character_WalkStraight); - ccAddExternalFunctionForPlugin("Character::GetAtRoomXY^2", (void*)GetCharacterAtRoom); - ccAddExternalFunctionForPlugin("Character::GetAtScreenXY^2", (void*)GetCharacterAtScreen); - ccAddExternalFunctionForPlugin("Character::get_ActiveInventory", (void*)Character_GetActiveInventory); - ccAddExternalFunctionForPlugin("Character::set_ActiveInventory", (void*)Character_SetActiveInventory); - ccAddExternalFunctionForPlugin("Character::get_Animating", (void*)Character_GetAnimating); - ccAddExternalFunctionForPlugin("Character::get_AnimationSpeed", (void*)Character_GetAnimationSpeed); - ccAddExternalFunctionForPlugin("Character::set_AnimationSpeed", (void*)Character_SetAnimationSpeed); - ccAddExternalFunctionForPlugin("Character::get_Baseline", (void*)Character_GetBaseline); - ccAddExternalFunctionForPlugin("Character::set_Baseline", (void*)Character_SetBaseline); - ccAddExternalFunctionForPlugin("Character::get_BlinkInterval", (void*)Character_GetBlinkInterval); - ccAddExternalFunctionForPlugin("Character::set_BlinkInterval", (void*)Character_SetBlinkInterval); - ccAddExternalFunctionForPlugin("Character::get_BlinkView", (void*)Character_GetBlinkView); - ccAddExternalFunctionForPlugin("Character::set_BlinkView", (void*)Character_SetBlinkView); - ccAddExternalFunctionForPlugin("Character::get_BlinkWhileThinking", (void*)Character_GetBlinkWhileThinking); - ccAddExternalFunctionForPlugin("Character::set_BlinkWhileThinking", (void*)Character_SetBlinkWhileThinking); - ccAddExternalFunctionForPlugin("Character::get_BlockingHeight", (void*)Character_GetBlockingHeight); - ccAddExternalFunctionForPlugin("Character::set_BlockingHeight", (void*)Character_SetBlockingHeight); - ccAddExternalFunctionForPlugin("Character::get_BlockingWidth", (void*)Character_GetBlockingWidth); - ccAddExternalFunctionForPlugin("Character::set_BlockingWidth", (void*)Character_SetBlockingWidth); - ccAddExternalFunctionForPlugin("Character::get_Clickable", (void*)Character_GetClickable); - ccAddExternalFunctionForPlugin("Character::set_Clickable", (void*)Character_SetClickable); - ccAddExternalFunctionForPlugin("Character::get_DestinationX", (void*)Character_GetDestinationX); - ccAddExternalFunctionForPlugin("Character::get_DestinationY", (void*)Character_GetDestinationY); - ccAddExternalFunctionForPlugin("Character::get_DiagonalLoops", (void*)Character_GetDiagonalWalking); - ccAddExternalFunctionForPlugin("Character::set_DiagonalLoops", (void*)Character_SetDiagonalWalking); - ccAddExternalFunctionForPlugin("Character::get_Frame", (void*)Character_GetFrame); - ccAddExternalFunctionForPlugin("Character::set_Frame", (void*)Character_SetFrame); - if (base_api < kScriptAPI_v341) - ccAddExternalFunctionForPlugin("Character::get_HasExplicitTint", (void*)Character_GetHasExplicitTint_Old); - else - ccAddExternalFunctionForPlugin("Character::get_HasExplicitTint", (void*)Character_GetHasExplicitTint); - ccAddExternalFunctionForPlugin("Character::get_ID", (void*)Character_GetID); - ccAddExternalFunctionForPlugin("Character::get_IdleView", (void*)Character_GetIdleView); - ccAddExternalFunctionForPlugin("Character::geti_InventoryQuantity", (void*)Character_GetIInventoryQuantity); - ccAddExternalFunctionForPlugin("Character::seti_InventoryQuantity", (void*)Character_SetIInventoryQuantity); - ccAddExternalFunctionForPlugin("Character::get_IgnoreLighting", (void*)Character_GetIgnoreLighting); - ccAddExternalFunctionForPlugin("Character::set_IgnoreLighting", (void*)Character_SetIgnoreLighting); - ccAddExternalFunctionForPlugin("Character::get_IgnoreScaling", (void*)Character_GetIgnoreScaling); - ccAddExternalFunctionForPlugin("Character::set_IgnoreScaling", (void*)Character_SetIgnoreScaling); - ccAddExternalFunctionForPlugin("Character::get_IgnoreWalkbehinds", (void*)Character_GetIgnoreWalkbehinds); - ccAddExternalFunctionForPlugin("Character::set_IgnoreWalkbehinds", (void*)Character_SetIgnoreWalkbehinds); - ccAddExternalFunctionForPlugin("Character::get_Loop", (void*)Character_GetLoop); - ccAddExternalFunctionForPlugin("Character::set_Loop", (void*)Character_SetLoop); - ccAddExternalFunctionForPlugin("Character::get_ManualScaling", (void*)Character_GetIgnoreScaling); - ccAddExternalFunctionForPlugin("Character::set_ManualScaling", (void*)Character_SetManualScaling); - ccAddExternalFunctionForPlugin("Character::get_MovementLinkedToAnimation",(void*)Character_GetMovementLinkedToAnimation); - ccAddExternalFunctionForPlugin("Character::set_MovementLinkedToAnimation",(void*)Character_SetMovementLinkedToAnimation); - ccAddExternalFunctionForPlugin("Character::get_Moving", (void*)Character_GetMoving); - ccAddExternalFunctionForPlugin("Character::get_Name", (void*)Character_GetName); - ccAddExternalFunctionForPlugin("Character::set_Name", (void*)Character_SetName); - ccAddExternalFunctionForPlugin("Character::get_NormalView", (void*)Character_GetNormalView); - ccAddExternalFunctionForPlugin("Character::get_PreviousRoom", (void*)Character_GetPreviousRoom); - ccAddExternalFunctionForPlugin("Character::get_Room", (void*)Character_GetRoom); - ccAddExternalFunctionForPlugin("Character::get_ScaleMoveSpeed", (void*)Character_GetScaleMoveSpeed); - ccAddExternalFunctionForPlugin("Character::set_ScaleMoveSpeed", (void*)Character_SetScaleMoveSpeed); - ccAddExternalFunctionForPlugin("Character::get_ScaleVolume", (void*)Character_GetScaleVolume); - ccAddExternalFunctionForPlugin("Character::set_ScaleVolume", (void*)Character_SetScaleVolume); - ccAddExternalFunctionForPlugin("Character::get_Scaling", (void*)Character_GetScaling); - ccAddExternalFunctionForPlugin("Character::set_Scaling", (void*)Character_SetScaling); - ccAddExternalFunctionForPlugin("Character::get_Solid", (void*)Character_GetSolid); - ccAddExternalFunctionForPlugin("Character::set_Solid", (void*)Character_SetSolid); - ccAddExternalFunctionForPlugin("Character::get_Speaking", (void*)Character_GetSpeaking); - ccAddExternalFunctionForPlugin("Character::get_SpeakingFrame", (void*)Character_GetSpeakingFrame); - ccAddExternalFunctionForPlugin("Character::get_SpeechAnimationDelay", (void*)GetCharacterSpeechAnimationDelay); - ccAddExternalFunctionForPlugin("Character::set_SpeechAnimationDelay", (void*)Character_SetSpeechAnimationDelay); - ccAddExternalFunctionForPlugin("Character::get_SpeechColor", (void*)Character_GetSpeechColor); - ccAddExternalFunctionForPlugin("Character::set_SpeechColor", (void*)Character_SetSpeechColor); - ccAddExternalFunctionForPlugin("Character::get_SpeechView", (void*)Character_GetSpeechView); - ccAddExternalFunctionForPlugin("Character::set_SpeechView", (void*)Character_SetSpeechView); - ccAddExternalFunctionForPlugin("Character::get_ThinkView", (void*)Character_GetThinkView); - ccAddExternalFunctionForPlugin("Character::set_ThinkView", (void*)Character_SetThinkView); - ccAddExternalFunctionForPlugin("Character::get_Transparency", (void*)Character_GetTransparency); - ccAddExternalFunctionForPlugin("Character::set_Transparency", (void*)Character_SetTransparency); - ccAddExternalFunctionForPlugin("Character::get_TurnBeforeWalking", (void*)Character_GetTurnBeforeWalking); - ccAddExternalFunctionForPlugin("Character::set_TurnBeforeWalking", (void*)Character_SetTurnBeforeWalking); - ccAddExternalFunctionForPlugin("Character::get_View", (void*)Character_GetView); - ccAddExternalFunctionForPlugin("Character::get_WalkSpeedX", (void*)Character_GetWalkSpeedX); - ccAddExternalFunctionForPlugin("Character::get_WalkSpeedY", (void*)Character_GetWalkSpeedY); - ccAddExternalFunctionForPlugin("Character::get_X", (void*)Character_GetX); - ccAddExternalFunctionForPlugin("Character::set_X", (void*)Character_SetX); - ccAddExternalFunctionForPlugin("Character::get_x", (void*)Character_GetX); - ccAddExternalFunctionForPlugin("Character::set_x", (void*)Character_SetX); - ccAddExternalFunctionForPlugin("Character::get_Y", (void*)Character_GetY); - ccAddExternalFunctionForPlugin("Character::set_Y", (void*)Character_SetY); - ccAddExternalFunctionForPlugin("Character::get_y", (void*)Character_GetY); - ccAddExternalFunctionForPlugin("Character::set_y", (void*)Character_SetY); - ccAddExternalFunctionForPlugin("Character::get_Z", (void*)Character_GetZ); - ccAddExternalFunctionForPlugin("Character::set_Z", (void*)Character_SetZ); - ccAddExternalFunctionForPlugin("Character::get_z", (void*)Character_GetZ); - ccAddExternalFunctionForPlugin("Character::set_z", (void*)Character_SetZ); + ccAddExternalObjectFunction("Character::get_HasExplicitLight", Sc_Character_HasExplicitLight); + ccAddExternalObjectFunction("Character::get_LightLevel", Sc_Character_GetLightLevel); + ccAddExternalObjectFunction("Character::get_TintBlue", Sc_Character_GetTintBlue); + ccAddExternalObjectFunction("Character::get_TintGreen", Sc_Character_GetTintGreen); + ccAddExternalObjectFunction("Character::get_TintRed", Sc_Character_GetTintRed); + ccAddExternalObjectFunction("Character::get_TintSaturation", Sc_Character_GetTintSaturation); + ccAddExternalObjectFunction("Character::get_TintLuminance", Sc_Character_GetTintLuminance); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Character::AddInventory^2", (void *)Character_AddInventory); + ccAddExternalFunctionForPlugin("Character::AddWaypoint^2", (void *)Character_AddWaypoint); + ccAddExternalFunctionForPlugin("Character::Animate^5", (void *)Character_Animate); + ccAddExternalFunctionForPlugin("Character::ChangeRoom^3", (void *)Character_ChangeRoom); + ccAddExternalFunctionForPlugin("Character::ChangeRoomAutoPosition^2", (void *)Character_ChangeRoomAutoPosition); + ccAddExternalFunctionForPlugin("Character::ChangeView^1", (void *)Character_ChangeView); + ccAddExternalFunctionForPlugin("Character::FaceCharacter^2", (void *)Character_FaceCharacter); + ccAddExternalFunctionForPlugin("Character::FaceDirection^2", (void *)Character_FaceDirection); + ccAddExternalFunctionForPlugin("Character::FaceLocation^3", (void *)Character_FaceLocation); + ccAddExternalFunctionForPlugin("Character::FaceObject^2", (void *)Character_FaceObject); + ccAddExternalFunctionForPlugin("Character::FollowCharacter^3", (void *)Character_FollowCharacter); + ccAddExternalFunctionForPlugin("Character::GetProperty^1", (void *)Character_GetProperty); + ccAddExternalFunctionForPlugin("Character::GetPropertyText^2", (void *)Character_GetPropertyText); + ccAddExternalFunctionForPlugin("Character::GetTextProperty^1", (void *)Character_GetTextProperty); + ccAddExternalFunctionForPlugin("Character::HasInventory^1", (void *)Character_HasInventory); + ccAddExternalFunctionForPlugin("Character::IsCollidingWithChar^1", (void *)Character_IsCollidingWithChar); + ccAddExternalFunctionForPlugin("Character::IsCollidingWithObject^1", (void *)Character_IsCollidingWithObject); + ccAddExternalFunctionForPlugin("Character::LockView^1", (void *)Character_LockView); + ccAddExternalFunctionForPlugin("Character::LockView^2", (void *)Character_LockViewEx); + if (base_api < kScriptAPI_v341) { + ccAddExternalFunctionForPlugin("Character::LockViewAligned^3", (void *)Character_LockViewAligned_Old); + ccAddExternalFunctionForPlugin("Character::LockViewAligned^4", (void *)Character_LockViewAlignedEx_Old); + } else { + ccAddExternalFunctionForPlugin("Character::LockViewAligned^3", (void *)Character_LockViewAligned); + ccAddExternalFunctionForPlugin("Character::LockViewAligned^4", (void *)Character_LockViewAlignedEx); + } + ccAddExternalFunctionForPlugin("Character::LockViewFrame^3", (void *)Character_LockViewFrame); + ccAddExternalFunctionForPlugin("Character::LockViewFrame^4", (void *)Character_LockViewFrameEx); + ccAddExternalFunctionForPlugin("Character::LockViewOffset^3", (void *)Character_LockViewOffset); + ccAddExternalFunctionForPlugin("Character::LockViewOffset^4", (void *)Character_LockViewOffset); + ccAddExternalFunctionForPlugin("Character::LoseInventory^1", (void *)Character_LoseInventory); + ccAddExternalFunctionForPlugin("Character::Move^4", (void *)Character_Move); + ccAddExternalFunctionForPlugin("Character::PlaceOnWalkableArea^0", (void *)Character_PlaceOnWalkableArea); + ccAddExternalFunctionForPlugin("Character::RemoveTint^0", (void *)Character_RemoveTint); + ccAddExternalFunctionForPlugin("Character::RunInteraction^1", (void *)Character_RunInteraction); + ccAddExternalFunctionForPlugin("Character::Say^101", (void *)ScPl_Character_Say); + ccAddExternalFunctionForPlugin("Character::SayAt^4", (void *)Character_SayAt); + ccAddExternalFunctionForPlugin("Character::SayBackground^1", (void *)Character_SayBackground); + ccAddExternalFunctionForPlugin("Character::SetAsPlayer^0", (void *)Character_SetAsPlayer); + ccAddExternalFunctionForPlugin("Character::SetIdleView^2", (void *)Character_SetIdleView); + //ccAddExternalFunctionForPlugin("Character::SetOption^2", (void*)Character_SetOption); + ccAddExternalFunctionForPlugin("Character::SetWalkSpeed^2", (void *)Character_SetSpeed); + ccAddExternalFunctionForPlugin("Character::StopMoving^0", (void *)Character_StopMoving); + ccAddExternalFunctionForPlugin("Character::Think^101", (void *)ScPl_Character_Think); + ccAddExternalFunctionForPlugin("Character::Tint^5", (void *)Character_Tint); + ccAddExternalFunctionForPlugin("Character::UnlockView^0", (void *)Character_UnlockView); + ccAddExternalFunctionForPlugin("Character::UnlockView^1", (void *)Character_UnlockViewEx); + ccAddExternalFunctionForPlugin("Character::Walk^4", (void *)Character_Walk); + ccAddExternalFunctionForPlugin("Character::WalkStraight^3", (void *)Character_WalkStraight); + ccAddExternalFunctionForPlugin("Character::GetAtRoomXY^2", (void *)GetCharacterAtRoom); + ccAddExternalFunctionForPlugin("Character::GetAtScreenXY^2", (void *)GetCharacterAtScreen); + ccAddExternalFunctionForPlugin("Character::get_ActiveInventory", (void *)Character_GetActiveInventory); + ccAddExternalFunctionForPlugin("Character::set_ActiveInventory", (void *)Character_SetActiveInventory); + ccAddExternalFunctionForPlugin("Character::get_Animating", (void *)Character_GetAnimating); + ccAddExternalFunctionForPlugin("Character::get_AnimationSpeed", (void *)Character_GetAnimationSpeed); + ccAddExternalFunctionForPlugin("Character::set_AnimationSpeed", (void *)Character_SetAnimationSpeed); + ccAddExternalFunctionForPlugin("Character::get_Baseline", (void *)Character_GetBaseline); + ccAddExternalFunctionForPlugin("Character::set_Baseline", (void *)Character_SetBaseline); + ccAddExternalFunctionForPlugin("Character::get_BlinkInterval", (void *)Character_GetBlinkInterval); + ccAddExternalFunctionForPlugin("Character::set_BlinkInterval", (void *)Character_SetBlinkInterval); + ccAddExternalFunctionForPlugin("Character::get_BlinkView", (void *)Character_GetBlinkView); + ccAddExternalFunctionForPlugin("Character::set_BlinkView", (void *)Character_SetBlinkView); + ccAddExternalFunctionForPlugin("Character::get_BlinkWhileThinking", (void *)Character_GetBlinkWhileThinking); + ccAddExternalFunctionForPlugin("Character::set_BlinkWhileThinking", (void *)Character_SetBlinkWhileThinking); + ccAddExternalFunctionForPlugin("Character::get_BlockingHeight", (void *)Character_GetBlockingHeight); + ccAddExternalFunctionForPlugin("Character::set_BlockingHeight", (void *)Character_SetBlockingHeight); + ccAddExternalFunctionForPlugin("Character::get_BlockingWidth", (void *)Character_GetBlockingWidth); + ccAddExternalFunctionForPlugin("Character::set_BlockingWidth", (void *)Character_SetBlockingWidth); + ccAddExternalFunctionForPlugin("Character::get_Clickable", (void *)Character_GetClickable); + ccAddExternalFunctionForPlugin("Character::set_Clickable", (void *)Character_SetClickable); + ccAddExternalFunctionForPlugin("Character::get_DestinationX", (void *)Character_GetDestinationX); + ccAddExternalFunctionForPlugin("Character::get_DestinationY", (void *)Character_GetDestinationY); + ccAddExternalFunctionForPlugin("Character::get_DiagonalLoops", (void *)Character_GetDiagonalWalking); + ccAddExternalFunctionForPlugin("Character::set_DiagonalLoops", (void *)Character_SetDiagonalWalking); + ccAddExternalFunctionForPlugin("Character::get_Frame", (void *)Character_GetFrame); + ccAddExternalFunctionForPlugin("Character::set_Frame", (void *)Character_SetFrame); + if (base_api < kScriptAPI_v341) + ccAddExternalFunctionForPlugin("Character::get_HasExplicitTint", (void *)Character_GetHasExplicitTint_Old); + else + ccAddExternalFunctionForPlugin("Character::get_HasExplicitTint", (void *)Character_GetHasExplicitTint); + ccAddExternalFunctionForPlugin("Character::get_ID", (void *)Character_GetID); + ccAddExternalFunctionForPlugin("Character::get_IdleView", (void *)Character_GetIdleView); + ccAddExternalFunctionForPlugin("Character::geti_InventoryQuantity", (void *)Character_GetIInventoryQuantity); + ccAddExternalFunctionForPlugin("Character::seti_InventoryQuantity", (void *)Character_SetIInventoryQuantity); + ccAddExternalFunctionForPlugin("Character::get_IgnoreLighting", (void *)Character_GetIgnoreLighting); + ccAddExternalFunctionForPlugin("Character::set_IgnoreLighting", (void *)Character_SetIgnoreLighting); + ccAddExternalFunctionForPlugin("Character::get_IgnoreScaling", (void *)Character_GetIgnoreScaling); + ccAddExternalFunctionForPlugin("Character::set_IgnoreScaling", (void *)Character_SetIgnoreScaling); + ccAddExternalFunctionForPlugin("Character::get_IgnoreWalkbehinds", (void *)Character_GetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Character::set_IgnoreWalkbehinds", (void *)Character_SetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Character::get_Loop", (void *)Character_GetLoop); + ccAddExternalFunctionForPlugin("Character::set_Loop", (void *)Character_SetLoop); + ccAddExternalFunctionForPlugin("Character::get_ManualScaling", (void *)Character_GetIgnoreScaling); + ccAddExternalFunctionForPlugin("Character::set_ManualScaling", (void *)Character_SetManualScaling); + ccAddExternalFunctionForPlugin("Character::get_MovementLinkedToAnimation", (void *)Character_GetMovementLinkedToAnimation); + ccAddExternalFunctionForPlugin("Character::set_MovementLinkedToAnimation", (void *)Character_SetMovementLinkedToAnimation); + ccAddExternalFunctionForPlugin("Character::get_Moving", (void *)Character_GetMoving); + ccAddExternalFunctionForPlugin("Character::get_Name", (void *)Character_GetName); + ccAddExternalFunctionForPlugin("Character::set_Name", (void *)Character_SetName); + ccAddExternalFunctionForPlugin("Character::get_NormalView", (void *)Character_GetNormalView); + ccAddExternalFunctionForPlugin("Character::get_PreviousRoom", (void *)Character_GetPreviousRoom); + ccAddExternalFunctionForPlugin("Character::get_Room", (void *)Character_GetRoom); + ccAddExternalFunctionForPlugin("Character::get_ScaleMoveSpeed", (void *)Character_GetScaleMoveSpeed); + ccAddExternalFunctionForPlugin("Character::set_ScaleMoveSpeed", (void *)Character_SetScaleMoveSpeed); + ccAddExternalFunctionForPlugin("Character::get_ScaleVolume", (void *)Character_GetScaleVolume); + ccAddExternalFunctionForPlugin("Character::set_ScaleVolume", (void *)Character_SetScaleVolume); + ccAddExternalFunctionForPlugin("Character::get_Scaling", (void *)Character_GetScaling); + ccAddExternalFunctionForPlugin("Character::set_Scaling", (void *)Character_SetScaling); + ccAddExternalFunctionForPlugin("Character::get_Solid", (void *)Character_GetSolid); + ccAddExternalFunctionForPlugin("Character::set_Solid", (void *)Character_SetSolid); + ccAddExternalFunctionForPlugin("Character::get_Speaking", (void *)Character_GetSpeaking); + ccAddExternalFunctionForPlugin("Character::get_SpeakingFrame", (void *)Character_GetSpeakingFrame); + ccAddExternalFunctionForPlugin("Character::get_SpeechAnimationDelay", (void *)GetCharacterSpeechAnimationDelay); + ccAddExternalFunctionForPlugin("Character::set_SpeechAnimationDelay", (void *)Character_SetSpeechAnimationDelay); + ccAddExternalFunctionForPlugin("Character::get_SpeechColor", (void *)Character_GetSpeechColor); + ccAddExternalFunctionForPlugin("Character::set_SpeechColor", (void *)Character_SetSpeechColor); + ccAddExternalFunctionForPlugin("Character::get_SpeechView", (void *)Character_GetSpeechView); + ccAddExternalFunctionForPlugin("Character::set_SpeechView", (void *)Character_SetSpeechView); + ccAddExternalFunctionForPlugin("Character::get_ThinkView", (void *)Character_GetThinkView); + ccAddExternalFunctionForPlugin("Character::set_ThinkView", (void *)Character_SetThinkView); + ccAddExternalFunctionForPlugin("Character::get_Transparency", (void *)Character_GetTransparency); + ccAddExternalFunctionForPlugin("Character::set_Transparency", (void *)Character_SetTransparency); + ccAddExternalFunctionForPlugin("Character::get_TurnBeforeWalking", (void *)Character_GetTurnBeforeWalking); + ccAddExternalFunctionForPlugin("Character::set_TurnBeforeWalking", (void *)Character_SetTurnBeforeWalking); + ccAddExternalFunctionForPlugin("Character::get_View", (void *)Character_GetView); + ccAddExternalFunctionForPlugin("Character::get_WalkSpeedX", (void *)Character_GetWalkSpeedX); + ccAddExternalFunctionForPlugin("Character::get_WalkSpeedY", (void *)Character_GetWalkSpeedY); + ccAddExternalFunctionForPlugin("Character::get_X", (void *)Character_GetX); + ccAddExternalFunctionForPlugin("Character::set_X", (void *)Character_SetX); + ccAddExternalFunctionForPlugin("Character::get_x", (void *)Character_GetX); + ccAddExternalFunctionForPlugin("Character::set_x", (void *)Character_SetX); + ccAddExternalFunctionForPlugin("Character::get_Y", (void *)Character_GetY); + ccAddExternalFunctionForPlugin("Character::set_Y", (void *)Character_SetY); + ccAddExternalFunctionForPlugin("Character::get_y", (void *)Character_GetY); + ccAddExternalFunctionForPlugin("Character::set_y", (void *)Character_SetY); + ccAddExternalFunctionForPlugin("Character::get_Z", (void *)Character_GetZ); + ccAddExternalFunctionForPlugin("Character::set_Z", (void *)Character_SetZ); + ccAddExternalFunctionForPlugin("Character::get_z", (void *)Character_GetZ); + ccAddExternalFunctionForPlugin("Character::set_z", (void *)Character_SetZ); } diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h index 948465e55468..28a127ad6757 100644 --- a/engines/ags/engine/ac/character.h +++ b/engines/ags/engine/ac/character.h @@ -62,7 +62,7 @@ void Character_RemoveTint(CharacterInfo *chaa); int Character_GetHasExplicitTint(CharacterInfo *chaa); void Character_Say(CharacterInfo *chaa, const char *text); void Character_SayAt(CharacterInfo *chaa, int x, int y, int width, const char *texx); -ScriptOverlay* Character_SayBackground(CharacterInfo *chaa, const char *texx); +ScriptOverlay *Character_SayBackground(CharacterInfo *chaa, const char *texx); void Character_SetAsPlayer(CharacterInfo *chaa); void Character_SetIdleView(CharacterInfo *chaa, int iview, int itime); void Character_SetOption(CharacterInfo *chaa, int flag, int yesorno); @@ -82,10 +82,10 @@ void Character_RunInteraction(CharacterInfo *chaa, int mood); int Character_GetProperty(CharacterInfo *chaa, const char *property); void Character_GetPropertyText(CharacterInfo *chaa, const char *property, char *bufer); -const char* Character_GetTextProperty(CharacterInfo *chaa, const char *property); +const char *Character_GetTextProperty(CharacterInfo *chaa, const char *property); -ScriptInvItem* Character_GetActiveInventory(CharacterInfo *chaa); -void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem* iit); +ScriptInvItem *Character_GetActiveInventory(CharacterInfo *chaa); +void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem *iit); int Character_GetAnimating(CharacterInfo *chaa); int Character_GetAnimationSpeed(CharacterInfo *chaa); void Character_SetAnimationSpeed(CharacterInfo *chaa, int newval); @@ -124,7 +124,7 @@ void Character_SetMovementLinkedToAnimation(CharacterInfo *chaa, int yesorno) int Character_GetLoop(CharacterInfo *chaa); void Character_SetLoop(CharacterInfo *chaa, int newval); int Character_GetMoving(CharacterInfo *chaa); -const char* Character_GetName(CharacterInfo *chaa); +const char *Character_GetName(CharacterInfo *chaa); void Character_SetName(CharacterInfo *chaa, const char *newName); int Character_GetNormalView(CharacterInfo *chaa); int Character_GetPreviousRoom(CharacterInfo *chaa); @@ -163,46 +163,50 @@ int Character_GetSpeakingFrame(CharacterInfo *chaa); //============================================================================= struct MoveList; -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later -void animate_character(CharacterInfo *chap, int loopn,int sppd,int rept, int noidleoverride = 0, int direction = 0, int sframe = 0); -void walk_character(int chac,int tox,int toy,int ignwal, bool autoWalkAnims); -int find_looporder_index (int curloop); +void animate_character(CharacterInfo *chap, int loopn, int sppd, int rept, int noidleoverride = 0, int direction = 0, int sframe = 0); +void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims); +int find_looporder_index(int curloop); // returns 0 to use diagonal, 1 to not -int useDiagonal (CharacterInfo *char1); +int useDiagonal(CharacterInfo *char1); // returns 1 normally, or 0 if they only have horizontal animations int hasUpDownLoops(CharacterInfo *char1); -void start_character_turning (CharacterInfo *chinf, int useloop, int no_diagonal); -void fix_player_sprite(MoveList*cmls,CharacterInfo*chinf); +void start_character_turning(CharacterInfo *chinf, int useloop, int no_diagonal); +void fix_player_sprite(MoveList *cmls, CharacterInfo *chinf); // Check whether two characters have walked into each other int has_hit_another_character(int sourceChar); -int doNextCharMoveStep (CharacterInfo *chi, int &char_index, CharacterExtras *chex); +int doNextCharMoveStep(CharacterInfo *chi, int &char_index, CharacterExtras *chex); int find_nearest_walkable_area_within(int *xx, int *yy, int range, int step); -void find_nearest_walkable_area (int *xx, int *yy); -void walk_character(int chac,int tox,int toy,int ignwal, bool autoWalkAnims); +void find_nearest_walkable_area(int *xx, int *yy); +void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims); void FindReasonableLoopForCharacter(CharacterInfo *chap); void walk_or_move_character(CharacterInfo *chaa, int x, int y, int blocking, int direct, bool isWalk); int is_valid_character(int newchar); -int wantMoveNow (CharacterInfo *chi, CharacterExtras *chex); +int wantMoveNow(CharacterInfo *chi, CharacterExtras *chex); void setup_player_character(int charid); void CheckViewFrameForCharacter(CharacterInfo *chi); Common::Bitmap *GetCharacterImage(int charid, int *isFlipped); CharacterInfo *GetCharacterAtScreen(int xx, int yy); // Get character ID at the given room coordinates -int is_pos_on_character(int xx,int yy); +int is_pos_on_character(int xx, int yy); void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2); // Check whether the source char has walked onto character ww -int is_char_on_another (int sourceChar, int ww, int*fromxptr, int*cwidptr); +int is_char_on_another(int sourceChar, int ww, int *fromxptr, int *cwidptr); int my_getpixel(Common::Bitmap *blk, int x, int y); // X and Y co-ordinates must be in 320x200 format -int check_click_on_character(int xx,int yy,int mood); -int is_pos_on_character(int xx,int yy); +int check_click_on_character(int xx, int yy, int mood); +int is_pos_on_character(int xx, int yy); void _DisplaySpeechCore(int chid, const char *displbuf); void _DisplayThoughtCore(int chid, const char *displbuf); -void _displayspeech(const char*texx, int aschar, int xx, int yy, int widd, int isThought); +void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int isThought); int get_character_currently_talking(); -void DisplaySpeech(const char*texx, int aschar); +void DisplaySpeech(const char *texx, int aschar); int update_lip_sync(int talkview, int talkloop, int *talkframeptr); // Calculates character's bounding box in room coordinates (takes only in-room transform into account) @@ -213,7 +217,7 @@ Rect GetCharacterRoomBBox(int charid, bool use_frame_0 = false); // or the one that is least far away from its camera; calculated as a perpendicular distance between two AABBs. PViewport FindNearestViewport(int charid); -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern CharacterExtras *charextra; extern MoveList *mls; extern int32_t _sc_PlayerCharPtr; diff --git a/engines/ags/engine/ac/charactercache.h b/engines/ags/engine/ac/charactercache.h index 2ba84e66ed51..9032c8302459 100644 --- a/engines/ags/engine/ac/charactercache.h +++ b/engines/ags/engine/ac/charactercache.h @@ -23,18 +23,22 @@ #ifndef AGS_ENGINE_AC_CHARACTERCACHE_H #define AGS_ENGINE_AC_CHARACTERCACHE_H -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later // stores cached info about the character struct CharacterCache { - Common::Bitmap *image; - int sppic; - int scaling; - int inUse; - short tintredwas, tintgrnwas, tintbluwas, tintamntwas; - short lightlevwas, tintlightwas; - // no mirroredWas is required, since the code inverts the sprite number + Common::Bitmap *image; + int sppic; + int scaling; + int inUse; + short tintredwas, tintgrnwas, tintbluwas, tintamntwas; + short lightlevwas, tintlightwas; + // no mirroredWas is required, since the code inverts the sprite number }; #endif diff --git a/engines/ags/engine/ac/characterextras.cpp b/engines/ags/engine/ac/characterextras.cpp index 211534e07563..c76d794c2661 100644 --- a/engines/ags/engine/ac/characterextras.cpp +++ b/engines/ags/engine/ac/characterextras.cpp @@ -25,40 +25,38 @@ using AGS::Common::Stream; -void CharacterExtras::ReadFromFile(Stream *in) -{ - in->ReadArrayOfInt16(invorder, MAX_INVORDER); - invorder_count = in->ReadInt16(); - width = in->ReadInt16(); - height = in->ReadInt16(); - zoom = in->ReadInt16(); - xwas = in->ReadInt16(); - ywas = in->ReadInt16(); - tint_r = in->ReadInt16(); - tint_g = in->ReadInt16(); - tint_b = in->ReadInt16(); - tint_level = in->ReadInt16(); - tint_light = in->ReadInt16(); - process_idle_this_time = in->ReadInt8(); - slow_move_counter = in->ReadInt8(); - animwait = in->ReadInt16(); +void CharacterExtras::ReadFromFile(Stream *in) { + in->ReadArrayOfInt16(invorder, MAX_INVORDER); + invorder_count = in->ReadInt16(); + width = in->ReadInt16(); + height = in->ReadInt16(); + zoom = in->ReadInt16(); + xwas = in->ReadInt16(); + ywas = in->ReadInt16(); + tint_r = in->ReadInt16(); + tint_g = in->ReadInt16(); + tint_b = in->ReadInt16(); + tint_level = in->ReadInt16(); + tint_light = in->ReadInt16(); + process_idle_this_time = in->ReadInt8(); + slow_move_counter = in->ReadInt8(); + animwait = in->ReadInt16(); } -void CharacterExtras::WriteToFile(Stream *out) -{ - out->WriteArrayOfInt16(invorder, MAX_INVORDER); - out->WriteInt16(invorder_count); - out->WriteInt16(width); - out->WriteInt16(height); - out->WriteInt16(zoom); - out->WriteInt16(xwas); - out->WriteInt16(ywas); - out->WriteInt16(tint_r); - out->WriteInt16(tint_g); - out->WriteInt16(tint_b); - out->WriteInt16(tint_level); - out->WriteInt16(tint_light); - out->WriteInt8(process_idle_this_time); - out->WriteInt8(slow_move_counter); - out->WriteInt16(animwait); +void CharacterExtras::WriteToFile(Stream *out) { + out->WriteArrayOfInt16(invorder, MAX_INVORDER); + out->WriteInt16(invorder_count); + out->WriteInt16(width); + out->WriteInt16(height); + out->WriteInt16(zoom); + out->WriteInt16(xwas); + out->WriteInt16(ywas); + out->WriteInt16(tint_r); + out->WriteInt16(tint_g); + out->WriteInt16(tint_b); + out->WriteInt16(tint_level); + out->WriteInt16(tint_light); + out->WriteInt8(process_idle_this_time); + out->WriteInt8(slow_move_counter); + out->WriteInt16(animwait); } diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h index d5d86dcfe457..526e69037478 100644 --- a/engines/ags/engine/ac/characterextras.h +++ b/engines/ags/engine/ac/characterextras.h @@ -26,32 +26,36 @@ #include "ac/runtime_defines.h" // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later struct CharacterExtras { - // UGLY UGLY UGLY!! The CharacterInfo struct size is fixed because it's - // used in the scripts, therefore overflowing stuff has to go here - short invorder[MAX_INVORDER]; - short invorder_count; - // TODO: implement full AABB and keep updated, so that engine could rely on these cached values all time; - // TODO: consider having both fixed AABB and volatile one that changes with animation frame (unless you change how anims work) - short width; - short height; - short zoom; - short xwas; - short ywas; - short tint_r; - short tint_g; - short tint_b; - short tint_level; - short tint_light; - char process_idle_this_time; - char slow_move_counter; - short animwait; + // UGLY UGLY UGLY!! The CharacterInfo struct size is fixed because it's + // used in the scripts, therefore overflowing stuff has to go here + short invorder[MAX_INVORDER]; + short invorder_count; + // TODO: implement full AABB and keep updated, so that engine could rely on these cached values all time; + // TODO: consider having both fixed AABB and volatile one that changes with animation frame (unless you change how anims work) + short width; + short height; + short zoom; + short xwas; + short ywas; + short tint_r; + short tint_g; + short tint_b; + short tint_level; + short tint_light; + char process_idle_this_time; + char slow_move_counter; + short animwait; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); }; #endif diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp index 819b92fc11a8..44ff6b96969d 100644 --- a/engines/ags/engine/ac/characterinfo_engine.cpp +++ b/engines/ags/engine/ac/characterinfo_engine.cpp @@ -31,13 +31,13 @@ #include "ac/viewframe.h" #include "debug/debug_log.h" #include "game/roomstruct.h" -#include "main/maindefines_ex.h" // RETURN_CONTINUE +#include "main/maindefines_ex.h" // RETURN_CONTINUE #include "main/update.h" #include "media/audio/audio_system.h" using namespace AGS::Common; -extern ViewStruct*views; +extern ViewStruct *views; extern GameSetupStruct game; extern int displayed_room; extern GameState play; @@ -48,45 +48,44 @@ extern unsigned int loopcounter; #define Random __Rand int CharacterInfo::get_effective_y() { - return y - z; + return y - z; } int CharacterInfo::get_baseline() { - if (baseline < 1) - return y; - return baseline; + if (baseline < 1) + return y; + return baseline; } int CharacterInfo::get_blocking_top() { - if (blocking_height > 0) - return y - blocking_height / 2; - return y - 2; + if (blocking_height > 0) + return y - blocking_height / 2; + return y - 2; } int CharacterInfo::get_blocking_bottom() { - // the blocking_bottom should be 1 less than the top + height - // since the code does <= checks on it rather than < checks - if (blocking_height > 0) - return (y + (blocking_height + 1) / 2) - 1; - return y + 3; + // the blocking_bottom should be 1 less than the top + height + // since the code does <= checks on it rather than < checks + if (blocking_height > 0) + return (y + (blocking_height + 1) / 2) - 1; + return y + 3; } -void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, int &numSheep, int *followingAsSheep) -{ +void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, int &numSheep, int *followingAsSheep) { int res; if (on != 1) return; - + // walking res = update_character_walking(chex); // [IKM] Yes, it should return! upon getting RETURN_CONTINUE here if (res == RETURN_CONTINUE) { // [IKM] now, this is one of those places... - return; // must be careful not to screw things up + return; // must be careful not to screw things up } - - // Make sure it doesn't flash up a blue cup - if (view < 0) ; - else if (loop >= views[view].numLoops) - loop = 0; - int doing_nothing = 1; + // Make sure it doesn't flash up a blue cup + if (view < 0) ; + else if (loop >= views[view].numLoops) + loop = 0; + + int doing_nothing = 1; update_character_moving(char_index, chex, doing_nothing); @@ -95,422 +94,394 @@ void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, in res = update_character_animating(char_index, doing_nothing); // [IKM] Yes, it should return! upon getting RETURN_CONTINUE here if (res == RETURN_CONTINUE) { // [IKM] now, this is one of those places... - return; // must be careful not to screw things up + return; // must be careful not to screw things up } update_character_follower(char_index, numSheep, followingAsSheep, doing_nothing); update_character_idle(chex, doing_nothing); - chex->process_idle_this_time = 0; + chex->process_idle_this_time = 0; } -void CharacterInfo::UpdateFollowingExactlyCharacter() -{ +void CharacterInfo::UpdateFollowingExactlyCharacter() { x = game.chars[following].x; - y = game.chars[following].y; - z = game.chars[following].z; - room = game.chars[following].room; - prevroom = game.chars[following].prevroom; + y = game.chars[following].y; + z = game.chars[following].z; + room = game.chars[following].room; + prevroom = game.chars[following].prevroom; - int usebase = game.chars[following].get_baseline(); + int usebase = game.chars[following].get_baseline(); - if (flags & CHF_BEHINDSHEPHERD) - baseline = usebase - 1; - else - baseline = usebase + 1; + if (flags & CHF_BEHINDSHEPHERD) + baseline = usebase - 1; + else + baseline = usebase + 1; } -int CharacterInfo::update_character_walking(CharacterExtras *chex) -{ - if (walking >= TURNING_AROUND) { - // Currently rotating to correct direction - if (walkwait > 0) walkwait--; - else { - // Work out which direction is next - int wantloop = find_looporder_index(loop) + 1; - // going anti-clockwise, take one before instead - if (walking >= TURNING_BACKWARDS) - wantloop -= 2; - while (1) { - if (wantloop >= 8) - wantloop = 0; - if (wantloop < 0) - wantloop = 7; - if ((turnlooporder[wantloop] >= views[view].numLoops) || - (views[view].loops[turnlooporder[wantloop]].numFrames < 1) || - ((turnlooporder[wantloop] >= 4) && ((flags & CHF_NODIAGONAL)!=0))) { - if (walking >= TURNING_BACKWARDS) - wantloop--; - else - wantloop++; - } - else break; - } - loop = turnlooporder[wantloop]; - walking -= TURNING_AROUND; - // if still turning, wait for next frame - if (walking % TURNING_BACKWARDS >= TURNING_AROUND) - walkwait = animspeed; - else - walking = walking % TURNING_BACKWARDS; - chex->animwait = 0; - } - return RETURN_CONTINUE; - //continue; - } +int CharacterInfo::update_character_walking(CharacterExtras *chex) { + if (walking >= TURNING_AROUND) { + // Currently rotating to correct direction + if (walkwait > 0) walkwait--; + else { + // Work out which direction is next + int wantloop = find_looporder_index(loop) + 1; + // going anti-clockwise, take one before instead + if (walking >= TURNING_BACKWARDS) + wantloop -= 2; + while (1) { + if (wantloop >= 8) + wantloop = 0; + if (wantloop < 0) + wantloop = 7; + if ((turnlooporder[wantloop] >= views[view].numLoops) || + (views[view].loops[turnlooporder[wantloop]].numFrames < 1) || + ((turnlooporder[wantloop] >= 4) && ((flags & CHF_NODIAGONAL) != 0))) { + if (walking >= TURNING_BACKWARDS) + wantloop--; + else + wantloop++; + } else break; + } + loop = turnlooporder[wantloop]; + walking -= TURNING_AROUND; + // if still turning, wait for next frame + if (walking % TURNING_BACKWARDS >= TURNING_AROUND) + walkwait = animspeed; + else + walking = walking % TURNING_BACKWARDS; + chex->animwait = 0; + } + return RETURN_CONTINUE; + //continue; + } return 0; } -void CharacterInfo::update_character_moving(int &char_index, CharacterExtras *chex, int &doing_nothing) -{ - if ((walking > 0) && (room == displayed_room)) - { - if (walkwait > 0) walkwait--; - else - { - flags &= ~CHF_AWAITINGMOVE; - - // Move the character - int numSteps = wantMoveNow(this, chex); - - if ((numSteps) && (chex->xwas != INVALID_X)) { - // if the zoom level changed mid-move, the walkcounter - // might not have come round properly - so sort it out - x = chex->xwas; - y = chex->ywas; - chex->xwas = INVALID_X; - } - - int oldxp = x, oldyp = y; - - for (int ff = 0; ff < abs(numSteps); ff++) { - if (doNextCharMoveStep (this, char_index, chex)) - break; - if ((walking == 0) || (walking >= TURNING_AROUND)) - break; - } - - if (numSteps < 0) { - // very small scaling, intersperse the movement - // to stop it being jumpy - chex->xwas = x; - chex->ywas = y; - x = ((x) - oldxp) / 2 + oldxp; - y = ((y) - oldyp) / 2 + oldyp; - } - else if (numSteps > 0) - chex->xwas = INVALID_X; - - if ((flags & CHF_ANTIGLIDE) == 0) - walkwaitcounter++; - } - - if (loop >= views[view].numLoops) - quitprintf("Unable to render character %d (%s) because loop %d does not exist in view %d", index_id, name, loop, view + 1); - - // check don't overflow loop - int framesInLoop = views[view].loops[loop].numFrames; - if (frame > framesInLoop) - { - frame = 1; - - if (framesInLoop < 2) - frame = 0; - - if (framesInLoop < 1) - quitprintf("Unable to render character %d (%s) because there are no frames in loop %d", index_id, name, loop); - } - - if (walking<1) { - chex->process_idle_this_time = 1; - doing_nothing=1; - walkwait=0; - chex->animwait = 0; - // use standing pic - Character_StopMoving(this); - frame = 0; - CheckViewFrameForCharacter(this); - } - else if (chex->animwait > 0) chex->animwait--; - else { - if (flags & CHF_ANTIGLIDE) - walkwaitcounter++; - - if ((flags & CHF_MOVENOTWALK) == 0) - { - frame++; - if (frame >= views[view].loops[loop].numFrames) - { - // end of loop, so loop back round skipping the standing frame - frame = 1; - - if (views[view].loops[loop].numFrames < 2) - frame = 0; - } - - chex->animwait = views[view].loops[loop].frames[frame].speed + animspeed; - - if (flags & CHF_ANTIGLIDE) - walkwait = chex->animwait; - else - walkwait = 0; - - CheckViewFrameForCharacter(this); - } - } - doing_nothing = 0; - } +void CharacterInfo::update_character_moving(int &char_index, CharacterExtras *chex, int &doing_nothing) { + if ((walking > 0) && (room == displayed_room)) { + if (walkwait > 0) walkwait--; + else { + flags &= ~CHF_AWAITINGMOVE; + + // Move the character + int numSteps = wantMoveNow(this, chex); + + if ((numSteps) && (chex->xwas != INVALID_X)) { + // if the zoom level changed mid-move, the walkcounter + // might not have come round properly - so sort it out + x = chex->xwas; + y = chex->ywas; + chex->xwas = INVALID_X; + } + + int oldxp = x, oldyp = y; + + for (int ff = 0; ff < abs(numSteps); ff++) { + if (doNextCharMoveStep(this, char_index, chex)) + break; + if ((walking == 0) || (walking >= TURNING_AROUND)) + break; + } + + if (numSteps < 0) { + // very small scaling, intersperse the movement + // to stop it being jumpy + chex->xwas = x; + chex->ywas = y; + x = ((x) - oldxp) / 2 + oldxp; + y = ((y) - oldyp) / 2 + oldyp; + } else if (numSteps > 0) + chex->xwas = INVALID_X; + + if ((flags & CHF_ANTIGLIDE) == 0) + walkwaitcounter++; + } + + if (loop >= views[view].numLoops) + quitprintf("Unable to render character %d (%s) because loop %d does not exist in view %d", index_id, name, loop, view + 1); + + // check don't overflow loop + int framesInLoop = views[view].loops[loop].numFrames; + if (frame > framesInLoop) { + frame = 1; + + if (framesInLoop < 2) + frame = 0; + + if (framesInLoop < 1) + quitprintf("Unable to render character %d (%s) because there are no frames in loop %d", index_id, name, loop); + } + + if (walking < 1) { + chex->process_idle_this_time = 1; + doing_nothing = 1; + walkwait = 0; + chex->animwait = 0; + // use standing pic + Character_StopMoving(this); + frame = 0; + CheckViewFrameForCharacter(this); + } else if (chex->animwait > 0) chex->animwait--; + else { + if (flags & CHF_ANTIGLIDE) + walkwaitcounter++; + + if ((flags & CHF_MOVENOTWALK) == 0) { + frame++; + if (frame >= views[view].loops[loop].numFrames) { + // end of loop, so loop back round skipping the standing frame + frame = 1; + + if (views[view].loops[loop].numFrames < 2) + frame = 0; + } + + chex->animwait = views[view].loops[loop].frames[frame].speed + animspeed; + + if (flags & CHF_ANTIGLIDE) + walkwait = chex->animwait; + else + walkwait = 0; + + CheckViewFrameForCharacter(this); + } + } + doing_nothing = 0; + } } -int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) -{ +int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) { // not moving, but animating - // idleleft is <0 while idle view is playing (.animating is 0) - if (((animating != 0) || (idleleft < 0)) && - ((walking == 0) || ((flags & CHF_MOVENOTWALK) != 0)) && - (room == displayed_room)) - { - doing_nothing = 0; - // idle anim doesn't count as doing something - if (idleleft < 0) - doing_nothing = 1; - - if (wait>0) wait--; - else if ((char_speaking == aa) && (game.options[OPT_LIPSYNCTEXT] != 0)) { - // currently talking with lip-sync speech - int fraa = frame; - wait = update_lip_sync (view, loop, &fraa) - 1; - // closed mouth at end of sentence - // NOTE: standard lip-sync is synchronized with text timer, not voice file - if (play.speech_in_post_state || - ((play.messagetime >= 0) && (play.messagetime < play.close_mouth_speech_time))) - frame = 0; - - if (frame != fraa) { - frame = fraa; - CheckViewFrameForCharacter(this); - } - - //continue; - return RETURN_CONTINUE; - } - else { - int oldframe = frame; - if (animating & CHANIM_BACKWARDS) { - frame--; - if (frame < 0) { - // if the previous loop is a Run Next Loop one, go back to it - if ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) { - - loop --; - frame = views[view].loops[loop].numFrames - 1; - } - else if (animating & CHANIM_REPEAT) { - - frame = views[view].loops[loop].numFrames - 1; - - while (views[view].loops[loop].RunNextLoop()) { - loop++; - frame = views[view].loops[loop].numFrames - 1; - } - } - else { - frame++; - animating = 0; - } - } - } - else - frame++; - - if ((aa == char_speaking) && - (play.speech_in_post_state || - ((!play.speech_has_voice) && - (play.close_mouth_speech_time > 0) && - (play.messagetime < play.close_mouth_speech_time)))) { - // finished talking - stop animation - animating = 0; - frame = 0; - } - - if (frame >= views[view].loops[loop].numFrames) { - - if (views[view].loops[loop].RunNextLoop()) - { - if (loop+1 >= views[view].numLoops) - quit("!Animating character tried to overrun last loop in view"); - loop++; - frame=0; - } - else if ((animating & CHANIM_REPEAT)==0) { - animating=0; - frame--; - // end of idle anim - if (idleleft < 0) { - // constant anim, reset (need this cos animating==0) - if (idletime == 0) - frame = 0; - // one-off anim, stop - else { - ReleaseCharacterView(aa); - idleleft=idletime; - } - } - } - else { - frame=0; - // if it's a multi-loop animation, go back to start - if (play.no_multiloop_repeat == 0) { - while ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) - loop--; - } - } - } - wait = views[view].loops[loop].frames[frame].speed; - // idle anim doesn't have speed stored cos animating==0 - if (idleleft < 0) - wait += animspeed+5; - else - wait += (animating >> 8) & 0x00ff; - - if (frame != oldframe) - CheckViewFrameForCharacter(this); - } - } + // idleleft is <0 while idle view is playing (.animating is 0) + if (((animating != 0) || (idleleft < 0)) && + ((walking == 0) || ((flags & CHF_MOVENOTWALK) != 0)) && + (room == displayed_room)) { + doing_nothing = 0; + // idle anim doesn't count as doing something + if (idleleft < 0) + doing_nothing = 1; + + if (wait > 0) wait--; + else if ((char_speaking == aa) && (game.options[OPT_LIPSYNCTEXT] != 0)) { + // currently talking with lip-sync speech + int fraa = frame; + wait = update_lip_sync(view, loop, &fraa) - 1; + // closed mouth at end of sentence + // NOTE: standard lip-sync is synchronized with text timer, not voice file + if (play.speech_in_post_state || + ((play.messagetime >= 0) && (play.messagetime < play.close_mouth_speech_time))) + frame = 0; + + if (frame != fraa) { + frame = fraa; + CheckViewFrameForCharacter(this); + } + + //continue; + return RETURN_CONTINUE; + } else { + int oldframe = frame; + if (animating & CHANIM_BACKWARDS) { + frame--; + if (frame < 0) { + // if the previous loop is a Run Next Loop one, go back to it + if ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) { + + loop --; + frame = views[view].loops[loop].numFrames - 1; + } else if (animating & CHANIM_REPEAT) { + + frame = views[view].loops[loop].numFrames - 1; + + while (views[view].loops[loop].RunNextLoop()) { + loop++; + frame = views[view].loops[loop].numFrames - 1; + } + } else { + frame++; + animating = 0; + } + } + } else + frame++; + + if ((aa == char_speaking) && + (play.speech_in_post_state || + ((!play.speech_has_voice) && + (play.close_mouth_speech_time > 0) && + (play.messagetime < play.close_mouth_speech_time)))) { + // finished talking - stop animation + animating = 0; + frame = 0; + } + + if (frame >= views[view].loops[loop].numFrames) { + + if (views[view].loops[loop].RunNextLoop()) { + if (loop + 1 >= views[view].numLoops) + quit("!Animating character tried to overrun last loop in view"); + loop++; + frame = 0; + } else if ((animating & CHANIM_REPEAT) == 0) { + animating = 0; + frame--; + // end of idle anim + if (idleleft < 0) { + // constant anim, reset (need this cos animating==0) + if (idletime == 0) + frame = 0; + // one-off anim, stop + else { + ReleaseCharacterView(aa); + idleleft = idletime; + } + } + } else { + frame = 0; + // if it's a multi-loop animation, go back to start + if (play.no_multiloop_repeat == 0) { + while ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) + loop--; + } + } + } + wait = views[view].loops[loop].frames[frame].speed; + // idle anim doesn't have speed stored cos animating==0 + if (idleleft < 0) + wait += animspeed + 5; + else + wait += (animating >> 8) & 0x00ff; + + if (frame != oldframe) + CheckViewFrameForCharacter(this); + } + } return 0; } -void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *followingAsSheep, int &doing_nothing) -{ +void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *followingAsSheep, int &doing_nothing) { if ((following >= 0) && (followinfo == FOLLOW_ALWAYSONTOP)) { - // an always-on-top follow - if (numSheep >= MAX_SHEEP) - quit("too many sheep"); - followingAsSheep[numSheep] = aa; - numSheep++; - } - // not moving, but should be following another character - else if ((following >= 0) && (doing_nothing == 1)) { - short distaway=(followinfo >> 8) & 0x00ff; - // no character in this room - if ((game.chars[following].on == 0) || (on == 0)) ; - else if (room < 0) { - room ++; - if (room == 0) { - // appear in the new room - room = game.chars[following].room; - x = play.entered_at_x; - y = play.entered_at_y; - } - } - // wait a bit, so we're not constantly walking - else if (Random(100) < (followinfo & 0x00ff)) ; - // the followed character has changed room - else if ((room != game.chars[following].room) - && (game.chars[following].on == 0)) - ; // do nothing if the player isn't visible - else if (room != game.chars[following].room) { - prevroom = room; - room = game.chars[following].room; - - if (room == displayed_room) { - // only move to the room-entered position if coming into - // the current room - if (play.entered_at_x > (thisroom.Width - 8)) { - x = thisroom.Width+8; - y = play.entered_at_y; - } - else if (play.entered_at_x < 8) { - x = -8; - y = play.entered_at_y; - } - else if (play.entered_at_y > (thisroom.Height - 8)) { - y = thisroom.Height+8; - x = play.entered_at_x; - } - else if (play.entered_at_y < thisroom.Edges.Top+8) { - y = thisroom.Edges.Top+1; - x = play.entered_at_x; - } - else { - // not at one of the edges - // delay for a few seconds to let the player move - room = -play.follow_change_room_timer; - } - if (room >= 0) { - walk_character(aa,play.entered_at_x,play.entered_at_y,1, true); - doing_nothing = 0; - } - } - } - else if (room != displayed_room) { - // if the characetr is following another character and - // neither is in the current room, don't try to move - } - else if ((abs(game.chars[following].x - x) > distaway+30) | - (abs(game.chars[following].y - y) > distaway+30) | - ((followinfo & 0x00ff) == 0)) { - // in same room - int goxoffs=(Random(50)-25); - // make sure he's not standing on top of the other man - if (goxoffs < 0) goxoffs-=distaway; - else goxoffs+=distaway; - walk_character(aa,game.chars[following].x + goxoffs, - game.chars[following].y + (Random(50)-25),0, true); - doing_nothing = 0; - } - } + // an always-on-top follow + if (numSheep >= MAX_SHEEP) + quit("too many sheep"); + followingAsSheep[numSheep] = aa; + numSheep++; + } + // not moving, but should be following another character + else if ((following >= 0) && (doing_nothing == 1)) { + short distaway = (followinfo >> 8) & 0x00ff; + // no character in this room + if ((game.chars[following].on == 0) || (on == 0)) ; + else if (room < 0) { + room ++; + if (room == 0) { + // appear in the new room + room = game.chars[following].room; + x = play.entered_at_x; + y = play.entered_at_y; + } + } + // wait a bit, so we're not constantly walking + else if (Random(100) < (followinfo & 0x00ff)) ; + // the followed character has changed room + else if ((room != game.chars[following].room) + && (game.chars[following].on == 0)) + ; // do nothing if the player isn't visible + else if (room != game.chars[following].room) { + prevroom = room; + room = game.chars[following].room; + + if (room == displayed_room) { + // only move to the room-entered position if coming into + // the current room + if (play.entered_at_x > (thisroom.Width - 8)) { + x = thisroom.Width + 8; + y = play.entered_at_y; + } else if (play.entered_at_x < 8) { + x = -8; + y = play.entered_at_y; + } else if (play.entered_at_y > (thisroom.Height - 8)) { + y = thisroom.Height + 8; + x = play.entered_at_x; + } else if (play.entered_at_y < thisroom.Edges.Top + 8) { + y = thisroom.Edges.Top + 1; + x = play.entered_at_x; + } else { + // not at one of the edges + // delay for a few seconds to let the player move + room = -play.follow_change_room_timer; + } + if (room >= 0) { + walk_character(aa, play.entered_at_x, play.entered_at_y, 1, true); + doing_nothing = 0; + } + } + } else if (room != displayed_room) { + // if the characetr is following another character and + // neither is in the current room, don't try to move + } else if ((abs(game.chars[following].x - x) > distaway + 30) | + (abs(game.chars[following].y - y) > distaway + 30) | + ((followinfo & 0x00ff) == 0)) { + // in same room + int goxoffs = (Random(50) - 25); + // make sure he's not standing on top of the other man + if (goxoffs < 0) goxoffs -= distaway; + else goxoffs += distaway; + walk_character(aa, game.chars[following].x + goxoffs, + game.chars[following].y + (Random(50) - 25), 0, true); + doing_nothing = 0; + } + } } -void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_nothing) -{ +void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_nothing) { // no idle animation, so skip this bit - if (idleview < 1) ; - // currently playing idle anim - else if (idleleft < 0) ; - // not in the current room - else if (room != displayed_room) ; - // they are moving or animating (or the view is locked), so - // reset idle timeout - else if ((doing_nothing == 0) || ((flags & CHF_FIXVIEW) != 0)) - idleleft = idletime; - // count idle time - else if ((loopcounter%40==0) || (chex->process_idle_this_time == 1)) { - idleleft--; - if (idleleft == -1) { - int useloop=loop; - debug_script_log("%s: Now idle (view %d)", scrname, idleview+1); - Character_LockView(this, idleview+1); - // SetCharView resets it to 0 - idleleft = -2; - int maxLoops = views[idleview].numLoops; - // if the char is set to "no diagonal loops", don't try - // to use diagonal idle loops either - if ((maxLoops > 4) && (useDiagonal(this))) - maxLoops = 4; - // If it's not a "swimming"-type idleanim, choose a random loop - // if there arent enough loops to do the current one. - if ((idletime > 0) && (useloop >= maxLoops)) { - do { - useloop = rand() % maxLoops; - // don't select a loop which is a continuation of a previous one - } while ((useloop > 0) && (views[idleview].loops[useloop-1].RunNextLoop())); - } - // Normal idle anim - just reset to loop 0 if not enough to - // use the current one - else if (useloop >= maxLoops) - useloop = 0; - - animate_character(this,useloop, - animspeed+5,(idletime == 0) ? 1 : 0, 1); - - // don't set Animating while the idle anim plays - animating = 0; - } - } // end do idle animation + if (idleview < 1) ; + // currently playing idle anim + else if (idleleft < 0) ; + // not in the current room + else if (room != displayed_room) ; + // they are moving or animating (or the view is locked), so + // reset idle timeout + else if ((doing_nothing == 0) || ((flags & CHF_FIXVIEW) != 0)) + idleleft = idletime; + // count idle time + else if ((loopcounter % 40 == 0) || (chex->process_idle_this_time == 1)) { + idleleft--; + if (idleleft == -1) { + int useloop = loop; + debug_script_log("%s: Now idle (view %d)", scrname, idleview + 1); + Character_LockView(this, idleview + 1); + // SetCharView resets it to 0 + idleleft = -2; + int maxLoops = views[idleview].numLoops; + // if the char is set to "no diagonal loops", don't try + // to use diagonal idle loops either + if ((maxLoops > 4) && (useDiagonal(this))) + maxLoops = 4; + // If it's not a "swimming"-type idleanim, choose a random loop + // if there arent enough loops to do the current one. + if ((idletime > 0) && (useloop >= maxLoops)) { + do { + useloop = rand() % maxLoops; + // don't select a loop which is a continuation of a previous one + } while ((useloop > 0) && (views[idleview].loops[useloop - 1].RunNextLoop())); + } + // Normal idle anim - just reset to loop 0 if not enough to + // use the current one + else if (useloop >= maxLoops) + useloop = 0; + + animate_character(this, useloop, + animspeed + 5, (idletime == 0) ? 1 : 0, 1); + + // don't set Animating while the idle anim plays + animating = 0; + } + } // end do idle animation } diff --git a/engines/ags/engine/ac/datetime.cpp b/engines/ags/engine/ac/datetime.cpp index e11d967b747e..a4874cb45d24 100644 --- a/engines/ags/engine/ac/datetime.cpp +++ b/engines/ags/engine/ac/datetime.cpp @@ -25,46 +25,46 @@ #include "platform/base/agsplatformdriver.h" #include "script/runtimescriptvalue.h" -ScriptDateTime* DateTime_Now_Core() { - ScriptDateTime *sdt = new ScriptDateTime(); +ScriptDateTime *DateTime_Now_Core() { + ScriptDateTime *sdt = new ScriptDateTime(); - platform->GetSystemTime(sdt); + platform->GetSystemTime(sdt); - return sdt; + return sdt; } -ScriptDateTime* DateTime_Now() { - ScriptDateTime *sdt = DateTime_Now_Core(); - ccRegisterManagedObject(sdt, sdt); - return sdt; +ScriptDateTime *DateTime_Now() { + ScriptDateTime *sdt = DateTime_Now_Core(); + ccRegisterManagedObject(sdt, sdt); + return sdt; } int DateTime_GetYear(ScriptDateTime *sdt) { - return sdt->year; + return sdt->year; } int DateTime_GetMonth(ScriptDateTime *sdt) { - return sdt->month; + return sdt->month; } int DateTime_GetDayOfMonth(ScriptDateTime *sdt) { - return sdt->day; + return sdt->day; } int DateTime_GetHour(ScriptDateTime *sdt) { - return sdt->hour; + return sdt->hour; } int DateTime_GetMinute(ScriptDateTime *sdt) { - return sdt->minute; + return sdt->minute; } int DateTime_GetSecond(ScriptDateTime *sdt) { - return sdt->second; + return sdt->second; } int DateTime_GetRawTime(ScriptDateTime *sdt) { - return sdt->rawUnixTime; + return sdt->rawUnixTime; } //============================================================================= @@ -78,72 +78,63 @@ int DateTime_GetRawTime(ScriptDateTime *sdt) { #include "script/script_runtime.h" // ScriptDateTime* () -RuntimeScriptValue Sc_DateTime_Now(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO(ScriptDateTime, DateTime_Now); +RuntimeScriptValue Sc_DateTime_Now(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO(ScriptDateTime, DateTime_Now); } // int (ScriptDateTime *sdt) -RuntimeScriptValue Sc_DateTime_GetYear(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDateTime, DateTime_GetYear); +RuntimeScriptValue Sc_DateTime_GetYear(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDateTime, DateTime_GetYear); } // int (ScriptDateTime *sdt) -RuntimeScriptValue Sc_DateTime_GetMonth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDateTime, DateTime_GetMonth); +RuntimeScriptValue Sc_DateTime_GetMonth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDateTime, DateTime_GetMonth); } // int (ScriptDateTime *sdt) -RuntimeScriptValue Sc_DateTime_GetDayOfMonth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDateTime, DateTime_GetDayOfMonth); +RuntimeScriptValue Sc_DateTime_GetDayOfMonth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDateTime, DateTime_GetDayOfMonth); } // int (ScriptDateTime *sdt) -RuntimeScriptValue Sc_DateTime_GetHour(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDateTime, DateTime_GetHour); +RuntimeScriptValue Sc_DateTime_GetHour(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDateTime, DateTime_GetHour); } // int (ScriptDateTime *sdt) -RuntimeScriptValue Sc_DateTime_GetMinute(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDateTime, DateTime_GetMinute); +RuntimeScriptValue Sc_DateTime_GetMinute(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDateTime, DateTime_GetMinute); } // int (ScriptDateTime *sdt) -RuntimeScriptValue Sc_DateTime_GetSecond(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDateTime, DateTime_GetSecond); +RuntimeScriptValue Sc_DateTime_GetSecond(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDateTime, DateTime_GetSecond); } // int (ScriptDateTime *sdt) -RuntimeScriptValue Sc_DateTime_GetRawTime(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDateTime, DateTime_GetRawTime); -} - -void RegisterDateTimeAPI() -{ - ccAddExternalStaticFunction("DateTime::get_Now", Sc_DateTime_Now); - ccAddExternalObjectFunction("DateTime::get_DayOfMonth", Sc_DateTime_GetDayOfMonth); - ccAddExternalObjectFunction("DateTime::get_Hour", Sc_DateTime_GetHour); - ccAddExternalObjectFunction("DateTime::get_Minute", Sc_DateTime_GetMinute); - ccAddExternalObjectFunction("DateTime::get_Month", Sc_DateTime_GetMonth); - ccAddExternalObjectFunction("DateTime::get_RawTime", Sc_DateTime_GetRawTime); - ccAddExternalObjectFunction("DateTime::get_Second", Sc_DateTime_GetSecond); - ccAddExternalObjectFunction("DateTime::get_Year", Sc_DateTime_GetYear); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("DateTime::get_Now", (void*)DateTime_Now); - ccAddExternalFunctionForPlugin("DateTime::get_DayOfMonth", (void*)DateTime_GetDayOfMonth); - ccAddExternalFunctionForPlugin("DateTime::get_Hour", (void*)DateTime_GetHour); - ccAddExternalFunctionForPlugin("DateTime::get_Minute", (void*)DateTime_GetMinute); - ccAddExternalFunctionForPlugin("DateTime::get_Month", (void*)DateTime_GetMonth); - ccAddExternalFunctionForPlugin("DateTime::get_RawTime", (void*)DateTime_GetRawTime); - ccAddExternalFunctionForPlugin("DateTime::get_Second", (void*)DateTime_GetSecond); - ccAddExternalFunctionForPlugin("DateTime::get_Year", (void*)DateTime_GetYear); +RuntimeScriptValue Sc_DateTime_GetRawTime(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDateTime, DateTime_GetRawTime); +} + +void RegisterDateTimeAPI() { + ccAddExternalStaticFunction("DateTime::get_Now", Sc_DateTime_Now); + ccAddExternalObjectFunction("DateTime::get_DayOfMonth", Sc_DateTime_GetDayOfMonth); + ccAddExternalObjectFunction("DateTime::get_Hour", Sc_DateTime_GetHour); + ccAddExternalObjectFunction("DateTime::get_Minute", Sc_DateTime_GetMinute); + ccAddExternalObjectFunction("DateTime::get_Month", Sc_DateTime_GetMonth); + ccAddExternalObjectFunction("DateTime::get_RawTime", Sc_DateTime_GetRawTime); + ccAddExternalObjectFunction("DateTime::get_Second", Sc_DateTime_GetSecond); + ccAddExternalObjectFunction("DateTime::get_Year", Sc_DateTime_GetYear); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DateTime::get_Now", (void *)DateTime_Now); + ccAddExternalFunctionForPlugin("DateTime::get_DayOfMonth", (void *)DateTime_GetDayOfMonth); + ccAddExternalFunctionForPlugin("DateTime::get_Hour", (void *)DateTime_GetHour); + ccAddExternalFunctionForPlugin("DateTime::get_Minute", (void *)DateTime_GetMinute); + ccAddExternalFunctionForPlugin("DateTime::get_Month", (void *)DateTime_GetMonth); + ccAddExternalFunctionForPlugin("DateTime::get_RawTime", (void *)DateTime_GetRawTime); + ccAddExternalFunctionForPlugin("DateTime::get_Second", (void *)DateTime_GetSecond); + ccAddExternalFunctionForPlugin("DateTime::get_Year", (void *)DateTime_GetYear); } diff --git a/engines/ags/engine/ac/datetime.h b/engines/ags/engine/ac/datetime.h index 612870825fab..96b922a306da 100644 --- a/engines/ags/engine/ac/datetime.h +++ b/engines/ags/engine/ac/datetime.h @@ -25,8 +25,8 @@ #include "ac/dynobj/scriptdatetime.h" -ScriptDateTime* DateTime_Now_Core(); -ScriptDateTime* DateTime_Now(); +ScriptDateTime *DateTime_Now_Core(); +ScriptDateTime *DateTime_Now(); int DateTime_GetYear(ScriptDateTime *sdt); int DateTime_GetMonth(ScriptDateTime *sdt); int DateTime_GetDayOfMonth(ScriptDateTime *sdt); diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 4cf2f530bf0d..5b2a85f67534 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -66,15 +66,15 @@ extern GameSetupStruct game; extern GameState play; extern ccInstance *dialogScriptsInst; extern int in_new_room; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern SpriteCache spriteset; extern AGSPlatformDriver *platform; -extern int cur_mode,cur_cursor; +extern int cur_mode, cur_cursor; extern IGraphicsDriver *gfxDriver; DialogTopic *dialog; ScriptDialogOptionsRendering ccDialogOptionsRendering; -ScriptDrawingSurface* dialogOptionsRenderingSurface; +ScriptDrawingSurface *dialogOptionsRenderingSurface; int said_speech_line; // used while in dialog to track whether screen needs updating @@ -89,85 +89,74 @@ int longestline = 0; void Dialog_Start(ScriptDialog *sd) { - RunDialog(sd->id); + RunDialog(sd->id); } #define CHOSE_TEXTPARSER -3053 #define SAYCHOSEN_USEFLAG 1 #define SAYCHOSEN_YES 2 -#define SAYCHOSEN_NO 3 - -int Dialog_DisplayOptions(ScriptDialog *sd, int sayChosenOption) -{ - if ((sayChosenOption < 1) || (sayChosenOption > 3)) - quit("!Dialog.DisplayOptions: invalid parameter passed"); - - int chose = show_dialog_options(sd->id, sayChosenOption, (game.options[OPT_RUNGAMEDLGOPTS] != 0)); - if (chose != CHOSE_TEXTPARSER) - { - chose++; - } - return chose; +#define SAYCHOSEN_NO 3 + +int Dialog_DisplayOptions(ScriptDialog *sd, int sayChosenOption) { + if ((sayChosenOption < 1) || (sayChosenOption > 3)) + quit("!Dialog.DisplayOptions: invalid parameter passed"); + + int chose = show_dialog_options(sd->id, sayChosenOption, (game.options[OPT_RUNGAMEDLGOPTS] != 0)); + if (chose != CHOSE_TEXTPARSER) { + chose++; + } + return chose; } void Dialog_SetOptionState(ScriptDialog *sd, int option, int newState) { - SetDialogOption(sd->id, option, newState); + SetDialogOption(sd->id, option, newState); } int Dialog_GetOptionState(ScriptDialog *sd, int option) { - return GetDialogOption(sd->id, option); + return GetDialogOption(sd->id, option); } -int Dialog_HasOptionBeenChosen(ScriptDialog *sd, int option) -{ - if ((option < 1) || (option > dialog[sd->id].numoptions)) - quit("!Dialog.HasOptionBeenChosen: Invalid option number specified"); - option--; +int Dialog_HasOptionBeenChosen(ScriptDialog *sd, int option) { + if ((option < 1) || (option > dialog[sd->id].numoptions)) + quit("!Dialog.HasOptionBeenChosen: Invalid option number specified"); + option--; - if (dialog[sd->id].optionflags[option] & DFLG_HASBEENCHOSEN) - return 1; - return 0; + if (dialog[sd->id].optionflags[option] & DFLG_HASBEENCHOSEN) + return 1; + return 0; } -void Dialog_SetHasOptionBeenChosen(ScriptDialog *sd, int option, bool chosen) -{ - if (option < 1 || option > dialog[sd->id].numoptions) - { - quit("!Dialog.HasOptionBeenChosen: Invalid option number specified"); - } - option--; - if (chosen) - { - dialog[sd->id].optionflags[option] |= DFLG_HASBEENCHOSEN; - } - else - { - dialog[sd->id].optionflags[option] &= ~DFLG_HASBEENCHOSEN; - } +void Dialog_SetHasOptionBeenChosen(ScriptDialog *sd, int option, bool chosen) { + if (option < 1 || option > dialog[sd->id].numoptions) { + quit("!Dialog.HasOptionBeenChosen: Invalid option number specified"); + } + option--; + if (chosen) { + dialog[sd->id].optionflags[option] |= DFLG_HASBEENCHOSEN; + } else { + dialog[sd->id].optionflags[option] &= ~DFLG_HASBEENCHOSEN; + } } -int Dialog_GetOptionCount(ScriptDialog *sd) -{ - return dialog[sd->id].numoptions; +int Dialog_GetOptionCount(ScriptDialog *sd) { + return dialog[sd->id].numoptions; } -int Dialog_GetShowTextParser(ScriptDialog *sd) -{ - return (dialog[sd->id].topicFlags & DTFLG_SHOWPARSER) ? 1 : 0; +int Dialog_GetShowTextParser(ScriptDialog *sd) { + return (dialog[sd->id].topicFlags & DTFLG_SHOWPARSER) ? 1 : 0; } -const char* Dialog_GetOptionText(ScriptDialog *sd, int option) -{ - if ((option < 1) || (option > dialog[sd->id].numoptions)) - quit("!Dialog.GetOptionText: Invalid option number specified"); +const char *Dialog_GetOptionText(ScriptDialog *sd, int option) { + if ((option < 1) || (option > dialog[sd->id].numoptions)) + quit("!Dialog.GetOptionText: Invalid option number specified"); - option--; + option--; - return CreateNewScriptString(get_translation(dialog[sd->id].optionnames[option])); + return CreateNewScriptString(get_translation(dialog[sd->id].optionnames[option])); } int Dialog_GetID(ScriptDialog *sd) { - return sd->id; + return sd->id; } //============================================================================= @@ -177,1056 +166,974 @@ int Dialog_GetID(ScriptDialog *sd) { #define RUN_DIALOG_GOTO_PREVIOUS -4 // dialog manager stuff -void get_dialog_script_parameters(unsigned char* &script, unsigned short* param1, unsigned short* param2) -{ - script++; - *param1 = *script; - script++; - *param1 += *script * 256; - script++; - - if (param2) - { - *param2 = *script; - script++; - *param2 += *script * 256; - script++; - } +void get_dialog_script_parameters(unsigned char *&script, unsigned short *param1, unsigned short *param2) { + script++; + *param1 = *script; + script++; + *param1 += *script * 256; + script++; + + if (param2) { + *param2 = *script; + script++; + *param2 += *script * 256; + script++; + } } -int run_dialog_script(DialogTopic*dtpp, int dialogID, int offse, int optionIndex) { - said_speech_line = 0; - int result = RUN_DIALOG_STAY; - - if (dialogScriptsInst) - { - char funcName[100]; - sprintf(funcName, "_run_dialog%d", dialogID); - RunTextScriptIParam(dialogScriptsInst, funcName, RuntimeScriptValue().SetInt32(optionIndex)); - result = dialogScriptsInst->returnValue; - } - else - { - // old dialog format - if (offse == -1) - return result; - - unsigned char* script = old_dialog_scripts[dialogID].get() + offse; - - unsigned short param1 = 0; - unsigned short param2 = 0; - bool script_running = true; - - while (script_running) - { - switch (*script) - { - case DCMD_SAY: - get_dialog_script_parameters(script, ¶m1, ¶m2); - - if (param1 == DCHAR_PLAYER) - param1 = game.playercharacter; - - if (param1 == DCHAR_NARRATOR) - Display(get_translation(old_speech_lines[param2])); - else - DisplaySpeech(get_translation(old_speech_lines[param2]), param1); - - said_speech_line = 1; - break; - - case DCMD_OPTOFF: - get_dialog_script_parameters(script, ¶m1, nullptr); - SetDialogOption(dialogID, param1 + 1, 0, true); - break; - - case DCMD_OPTON: - get_dialog_script_parameters(script, ¶m1, nullptr); - SetDialogOption(dialogID, param1 + 1, DFLG_ON, true); - break; - - case DCMD_RETURN: - script_running = false; - break; - - case DCMD_STOPDIALOG: - result = RUN_DIALOG_STOP_DIALOG; - script_running = false; - break; - - case DCMD_OPTOFFFOREVER: - get_dialog_script_parameters(script, ¶m1, nullptr); - SetDialogOption(dialogID, param1 + 1, DFLG_OFFPERM, true); - break; - - case DCMD_RUNTEXTSCRIPT: - get_dialog_script_parameters(script, ¶m1, nullptr); - result = run_dialog_request(param1); - script_running = (result == RUN_DIALOG_STAY); - break; - - case DCMD_GOTODIALOG: - get_dialog_script_parameters(script, ¶m1, nullptr); - result = param1; - script_running = false; - break; - - case DCMD_PLAYSOUND: - get_dialog_script_parameters(script, ¶m1, nullptr); - play_sound(param1); - break; - - case DCMD_ADDINV: - get_dialog_script_parameters(script, ¶m1, nullptr); - add_inventory(param1); - break; - - case DCMD_SETSPCHVIEW: - get_dialog_script_parameters(script, ¶m1, ¶m2); - SetCharacterSpeechView(param1, param2); - break; - - case DCMD_NEWROOM: - get_dialog_script_parameters(script, ¶m1, nullptr); - NewRoom(param1); - in_new_room = 1; - result = RUN_DIALOG_STOP_DIALOG; - script_running = false; - break; - - case DCMD_SETGLOBALINT: - get_dialog_script_parameters(script, ¶m1, ¶m2); - SetGlobalInt(param1, param2); - break; - - case DCMD_GIVESCORE: - get_dialog_script_parameters(script, ¶m1, nullptr); - GiveScore(param1); - break; - - case DCMD_GOTOPREVIOUS: - result = RUN_DIALOG_GOTO_PREVIOUS; - script_running = false; - break; - - case DCMD_LOSEINV: - get_dialog_script_parameters(script, ¶m1, nullptr); - lose_inventory(param1); - break; - - case DCMD_ENDSCRIPT: - result = RUN_DIALOG_STOP_DIALOG; - script_running = false; - break; - } - } - } - - if (in_new_room > 0) - return RUN_DIALOG_STOP_DIALOG; - - if (said_speech_line > 0) { - // the line below fixes the problem with the close-up face remaining on the - // screen after they finish talking; however, it makes the dialog options - // area flicker when going between topics. - DisableInterface(); - UpdateGameOnce(); // redraw the screen to make sure it looks right - EnableInterface(); - // if we're not about to abort the dialog, switch back to arrow - if (result != RUN_DIALOG_STOP_DIALOG) - set_mouse_cursor(CURS_ARROW); - } - - return result; +int run_dialog_script(DialogTopic *dtpp, int dialogID, int offse, int optionIndex) { + said_speech_line = 0; + int result = RUN_DIALOG_STAY; + + if (dialogScriptsInst) { + char funcName[100]; + sprintf(funcName, "_run_dialog%d", dialogID); + RunTextScriptIParam(dialogScriptsInst, funcName, RuntimeScriptValue().SetInt32(optionIndex)); + result = dialogScriptsInst->returnValue; + } else { + // old dialog format + if (offse == -1) + return result; + + unsigned char *script = old_dialog_scripts[dialogID].get() + offse; + + unsigned short param1 = 0; + unsigned short param2 = 0; + bool script_running = true; + + while (script_running) { + switch (*script) { + case DCMD_SAY: + get_dialog_script_parameters(script, ¶m1, ¶m2); + + if (param1 == DCHAR_PLAYER) + param1 = game.playercharacter; + + if (param1 == DCHAR_NARRATOR) + Display(get_translation(old_speech_lines[param2])); + else + DisplaySpeech(get_translation(old_speech_lines[param2]), param1); + + said_speech_line = 1; + break; + + case DCMD_OPTOFF: + get_dialog_script_parameters(script, ¶m1, nullptr); + SetDialogOption(dialogID, param1 + 1, 0, true); + break; + + case DCMD_OPTON: + get_dialog_script_parameters(script, ¶m1, nullptr); + SetDialogOption(dialogID, param1 + 1, DFLG_ON, true); + break; + + case DCMD_RETURN: + script_running = false; + break; + + case DCMD_STOPDIALOG: + result = RUN_DIALOG_STOP_DIALOG; + script_running = false; + break; + + case DCMD_OPTOFFFOREVER: + get_dialog_script_parameters(script, ¶m1, nullptr); + SetDialogOption(dialogID, param1 + 1, DFLG_OFFPERM, true); + break; + + case DCMD_RUNTEXTSCRIPT: + get_dialog_script_parameters(script, ¶m1, nullptr); + result = run_dialog_request(param1); + script_running = (result == RUN_DIALOG_STAY); + break; + + case DCMD_GOTODIALOG: + get_dialog_script_parameters(script, ¶m1, nullptr); + result = param1; + script_running = false; + break; + + case DCMD_PLAYSOUND: + get_dialog_script_parameters(script, ¶m1, nullptr); + play_sound(param1); + break; + + case DCMD_ADDINV: + get_dialog_script_parameters(script, ¶m1, nullptr); + add_inventory(param1); + break; + + case DCMD_SETSPCHVIEW: + get_dialog_script_parameters(script, ¶m1, ¶m2); + SetCharacterSpeechView(param1, param2); + break; + + case DCMD_NEWROOM: + get_dialog_script_parameters(script, ¶m1, nullptr); + NewRoom(param1); + in_new_room = 1; + result = RUN_DIALOG_STOP_DIALOG; + script_running = false; + break; + + case DCMD_SETGLOBALINT: + get_dialog_script_parameters(script, ¶m1, ¶m2); + SetGlobalInt(param1, param2); + break; + + case DCMD_GIVESCORE: + get_dialog_script_parameters(script, ¶m1, nullptr); + GiveScore(param1); + break; + + case DCMD_GOTOPREVIOUS: + result = RUN_DIALOG_GOTO_PREVIOUS; + script_running = false; + break; + + case DCMD_LOSEINV: + get_dialog_script_parameters(script, ¶m1, nullptr); + lose_inventory(param1); + break; + + case DCMD_ENDSCRIPT: + result = RUN_DIALOG_STOP_DIALOG; + script_running = false; + break; + } + } + } + + if (in_new_room > 0) + return RUN_DIALOG_STOP_DIALOG; + + if (said_speech_line > 0) { + // the line below fixes the problem with the close-up face remaining on the + // screen after they finish talking; however, it makes the dialog options + // area flicker when going between topics. + DisableInterface(); + UpdateGameOnce(); // redraw the screen to make sure it looks right + EnableInterface(); + // if we're not about to abort the dialog, switch back to arrow + if (result != RUN_DIALOG_STOP_DIALOG) + set_mouse_cursor(CURS_ARROW); + } + + return result; } int write_dialog_options(Bitmap *ds, bool ds_has_alpha, int dlgxp, int curyp, int numdisp, int mouseison, int areawid, - int bullet_wid, int usingfont, DialogTopic*dtop, char*disporder, short*dispyp, - int linespacing, int utextcol, int padding) { - int ww; - - color_t text_color; - for (ww=0;wwoptionflags[disporder[ww]] & DFLG_HASBEENCHOSEN) && - (play.read_dialog_option_colour >= 0)) { - // 'read' colour - text_color = ds->GetCompatibleColor(play.read_dialog_option_colour); - } - else { - // 'unread' colour - text_color = ds->GetCompatibleColor(playerchar->talkcolor); - } - - if (mouseison==ww) { - if (text_color == ds->GetCompatibleColor(utextcol)) - text_color = ds->GetCompatibleColor(13); // the normal colour is the same as highlight col - else text_color = ds->GetCompatibleColor(utextcol); - } - - break_up_text_into_lines(get_translation(dtop->optionnames[disporder[ww]]), Lines, areawid-(2*padding+2+bullet_wid), usingfont); - dispyp[ww]=curyp; - if (game.dialog_bullet > 0) - { - draw_gui_sprite_v330(ds, game.dialog_bullet, dlgxp, curyp, ds_has_alpha); - } - if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering) { - char tempbfr[20]; - int actualpicwid = 0; - if (game.dialog_bullet > 0) - actualpicwid = game.SpriteInfos[game.dialog_bullet].Width+3; - - sprintf (tempbfr, "%d.", ww + 1); - wouttext_outline (ds, dlgxp + actualpicwid, curyp, usingfont, text_color, tempbfr); - } - for (size_t cc=0;ccoptionflags[disporder[ww]] & DFLG_HASBEENCHOSEN) && + (play.read_dialog_option_colour >= 0)) { + // 'read' colour + text_color = ds->GetCompatibleColor(play.read_dialog_option_colour); + } else { + // 'unread' colour + text_color = ds->GetCompatibleColor(playerchar->talkcolor); + } + + if (mouseison == ww) { + if (text_color == ds->GetCompatibleColor(utextcol)) + text_color = ds->GetCompatibleColor(13); // the normal colour is the same as highlight col + else text_color = ds->GetCompatibleColor(utextcol); + } + + break_up_text_into_lines(get_translation(dtop->optionnames[disporder[ww]]), Lines, areawid - (2 * padding + 2 + bullet_wid), usingfont); + dispyp[ww] = curyp; + if (game.dialog_bullet > 0) { + draw_gui_sprite_v330(ds, game.dialog_bullet, dlgxp, curyp, ds_has_alpha); + } + if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering) { + char tempbfr[20]; + int actualpicwid = 0; + if (game.dialog_bullet > 0) + actualpicwid = game.SpriteInfos[game.dialog_bullet].Width + 3; + + sprintf(tempbfr, "%d.", ww + 1); + wouttext_outline(ds, dlgxp + actualpicwid, curyp, usingfont, text_color, tempbfr); + } + for (size_t cc = 0; cc < Lines.Count(); cc++) { + wouttext_outline(ds, dlgxp + ((cc == 0) ? 0 : 9) + bullet_wid, curyp, usingfont, text_color, Lines[cc]); + curyp += linespacing; + } + if (ww < numdisp - 1) + curyp += data_to_game_coord(game.options[OPT_DIALOGGAP]); + } + return curyp; } #define GET_OPTIONS_HEIGHT {\ - needheight = 0;\ - for (int i = 0; i < numdisp; ++i) {\ - break_up_text_into_lines(get_translation(dtop->optionnames[disporder[i]]), Lines, areawid-(2*padding+2+bullet_wid), usingfont);\ - needheight += getheightoflines(usingfont, Lines.Count()) + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ - }\ - if (parserInput) needheight += parserInput->Height + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ - } + needheight = 0;\ + for (int i = 0; i < numdisp; ++i) {\ + break_up_text_into_lines(get_translation(dtop->optionnames[disporder[i]]), Lines, areawid-(2*padding+2+bullet_wid), usingfont);\ + needheight += getheightoflines(usingfont, Lines.Count()) + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ + }\ + if (parserInput) needheight += parserInput->Height + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ + } void draw_gui_for_dialog_options(Bitmap *ds, GUIMain *guib, int dlgxp, int dlgyp) { - if (guib->BgColor != 0) { - color_t draw_color = ds->GetCompatibleColor(guib->BgColor); - ds->FillRect(Rect(dlgxp, dlgyp, dlgxp + guib->Width, dlgyp + guib->Height), draw_color); - } - if (guib->BgImage > 0) - GfxUtil::DrawSpriteWithTransparency(ds, spriteset[guib->BgImage], dlgxp, dlgyp); + if (guib->BgColor != 0) { + color_t draw_color = ds->GetCompatibleColor(guib->BgColor); + ds->FillRect(Rect(dlgxp, dlgyp, dlgxp + guib->Width, dlgyp + guib->Height), draw_color); + } + if (guib->BgImage > 0) + GfxUtil::DrawSpriteWithTransparency(ds, spriteset[guib->BgImage], dlgxp, dlgyp); } -bool get_custom_dialog_options_dimensions(int dlgnum) -{ - ccDialogOptionsRendering.Reset(); - ccDialogOptionsRendering.dialogID = dlgnum; +bool get_custom_dialog_options_dimensions(int dlgnum) { + ccDialogOptionsRendering.Reset(); + ccDialogOptionsRendering.dialogID = dlgnum; - getDialogOptionsDimensionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - run_function_on_non_blocking_thread(&getDialogOptionsDimensionsFunc); + getDialogOptionsDimensionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&getDialogOptionsDimensionsFunc); - if ((ccDialogOptionsRendering.width > 0) && - (ccDialogOptionsRendering.height > 0)) - { - return true; - } - return false; + if ((ccDialogOptionsRendering.width > 0) && + (ccDialogOptionsRendering.height > 0)) { + return true; + } + return false; } #define MAX_TOPIC_HISTORY 50 #define DLG_OPTION_PARSER 99 -struct DialogOptions -{ - int dlgnum; - bool runGameLoopsInBackground; - - int dlgxp; - int dlgyp; - int dialog_abs_x; // absolute dialog position on screen - int padding; - int usingfont; - int lineheight; - int linespacing; - int curswas; - int bullet_wid; - int needheight; - IDriverDependantBitmap *ddb; - Bitmap *subBitmap; - GUITextBox *parserInput; - DialogTopic*dtop; - - char disporder[MAXTOPICOPTIONS]; - short dispyp[MAXTOPICOPTIONS]; - - int numdisp; - int chose; - - Bitmap *tempScrn; - int parserActivated; - - int curyp; - bool wantRefresh; - bool usingCustomRendering; - int orixp; - int oriyp; - int areawid; - int is_textwindow; - int dirtyx; - int dirtyy; - int dirtywidth; - int dirtyheight; - - int mouseison; - int mousewason; - - int forecol; - - void Prepare(int _dlgnum, bool _runGameLoopsInBackground); - void Show(); - void Redraw(); - bool Run(); - void Close(); +struct DialogOptions { + int dlgnum; + bool runGameLoopsInBackground; + + int dlgxp; + int dlgyp; + int dialog_abs_x; // absolute dialog position on screen + int padding; + int usingfont; + int lineheight; + int linespacing; + int curswas; + int bullet_wid; + int needheight; + IDriverDependantBitmap *ddb; + Bitmap *subBitmap; + GUITextBox *parserInput; + DialogTopic *dtop; + + char disporder[MAXTOPICOPTIONS]; + short dispyp[MAXTOPICOPTIONS]; + + int numdisp; + int chose; + + Bitmap *tempScrn; + int parserActivated; + + int curyp; + bool wantRefresh; + bool usingCustomRendering; + int orixp; + int oriyp; + int areawid; + int is_textwindow; + int dirtyx; + int dirtyy; + int dirtywidth; + int dirtyheight; + + int mouseison; + int mousewason; + + int forecol; + + void Prepare(int _dlgnum, bool _runGameLoopsInBackground); + void Show(); + void Redraw(); + bool Run(); + void Close(); }; -void DialogOptions::Prepare(int _dlgnum, bool _runGameLoopsInBackground) -{ - dlgnum = _dlgnum; - runGameLoopsInBackground = _runGameLoopsInBackground; +void DialogOptions::Prepare(int _dlgnum, bool _runGameLoopsInBackground) { + dlgnum = _dlgnum; + runGameLoopsInBackground = _runGameLoopsInBackground; - dlgyp = get_fixed_pixel_size(160); - usingfont=FONT_NORMAL; - lineheight = getfontheight_outlined(usingfont); - linespacing = getfontspacing_outlined(usingfont); - curswas=cur_cursor; - bullet_wid = 0; - ddb = nullptr; - subBitmap = nullptr; - parserInput = nullptr; - dtop = nullptr; + dlgyp = get_fixed_pixel_size(160); + usingfont = FONT_NORMAL; + lineheight = getfontheight_outlined(usingfont); + linespacing = getfontspacing_outlined(usingfont); + curswas = cur_cursor; + bullet_wid = 0; + ddb = nullptr; + subBitmap = nullptr; + parserInput = nullptr; + dtop = nullptr; - if ((dlgnum < 0) || (dlgnum >= game.numdialog)) - quit("!RunDialog: invalid dialog number specified"); + if ((dlgnum < 0) || (dlgnum >= game.numdialog)) + quit("!RunDialog: invalid dialog number specified"); - can_run_delayed_command(); + can_run_delayed_command(); - play.in_conversation ++; + play.in_conversation ++; - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - if (game.dialog_bullet > 0) - bullet_wid = game.SpriteInfos[game.dialog_bullet].Width+3; + if (game.dialog_bullet > 0) + bullet_wid = game.SpriteInfos[game.dialog_bullet].Width + 3; - // numbered options, leave space for the numbers - if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering) - bullet_wid += wgettextwidth_compensate("9. ", usingfont); + // numbered options, leave space for the numbers + if (game.options[OPT_DIALOGNUMBERED] == kDlgOptNumbering) + bullet_wid += wgettextwidth_compensate("9. ", usingfont); - said_text = 0; + said_text = 0; - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - const Rect &ui_view = play.GetUIViewport(); - tempScrn = BitmapHelper::CreateBitmap(ui_view.GetWidth(), ui_view.GetHeight(), game.GetColorDepth()); + const Rect &ui_view = play.GetUIViewport(); + tempScrn = BitmapHelper::CreateBitmap(ui_view.GetWidth(), ui_view.GetHeight(), game.GetColorDepth()); - set_mouse_cursor(CURS_ARROW); + set_mouse_cursor(CURS_ARROW); - dtop=&dialog[dlgnum]; + dtop = &dialog[dlgnum]; - chose=-1; - numdisp=0; + chose = -1; + numdisp = 0; - parserActivated = 0; - if ((dtop->topicFlags & DTFLG_SHOWPARSER) && (play.disable_dialog_parser == 0)) { - parserInput = new GUITextBox(); - parserInput->Height = lineheight + get_fixed_pixel_size(4); - parserInput->SetShowBorder(true); - parserInput->Font = usingfont; - } + parserActivated = 0; + if ((dtop->topicFlags & DTFLG_SHOWPARSER) && (play.disable_dialog_parser == 0)) { + parserInput = new GUITextBox(); + parserInput->Height = lineheight + get_fixed_pixel_size(4); + parserInput->SetShowBorder(true); + parserInput->Font = usingfont; + } - numdisp=0; - for (int i = 0; i < dtop->numoptions; ++i) { - if ((dtop->optionflags[i] & DFLG_ON)==0) continue; - ensure_text_valid_for_font(dtop->optionnames[i], usingfont); - disporder[numdisp]=i; - numdisp++; - } + numdisp = 0; + for (int i = 0; i < dtop->numoptions; ++i) { + if ((dtop->optionflags[i] & DFLG_ON) == 0) continue; + ensure_text_valid_for_font(dtop->optionnames[i], usingfont); + disporder[numdisp] = i; + numdisp++; + } } -void DialogOptions::Show() -{ - if (numdisp<1) quit("!DoDialog: all options have been turned off"); - // Don't display the options if there is only one and the parser - // is not enabled. - if (!((numdisp > 1) || (parserInput != nullptr) || (play.show_single_dialog_option))) - { - chose = disporder[0]; // only one choice, so select it - return; - } - - is_textwindow = 0; - forecol = play.dialog_options_highlight_color; - - mouseison=-1; - mousewason=-10; - const Rect &ui_view = play.GetUIViewport(); - dirtyx = 0; - dirtyy = 0; - dirtywidth = ui_view.GetWidth(); - dirtyheight = ui_view.GetHeight(); - usingCustomRendering = false; - - - dlgxp = 1; - if (get_custom_dialog_options_dimensions(dlgnum)) - { - usingCustomRendering = true; - dirtyx = data_to_game_coord(ccDialogOptionsRendering.x); - dirtyy = data_to_game_coord(ccDialogOptionsRendering.y); - dirtywidth = data_to_game_coord(ccDialogOptionsRendering.width); - dirtyheight = data_to_game_coord(ccDialogOptionsRendering.height); - dialog_abs_x = dirtyx; - } - else if (game.options[OPT_DIALOGIFACE] > 0) - { - GUIMain*guib=&guis[game.options[OPT_DIALOGIFACE]]; - if (guib->IsTextWindow()) { - // text-window, so do the QFG4-style speech options - is_textwindow = 1; - forecol = guib->FgColor; - } - else { - dlgxp = guib->X; - dlgyp = guib->Y; - - dirtyx = dlgxp; - dirtyy = dlgyp; - dirtywidth = guib->Width; - dirtyheight = guib->Height; - dialog_abs_x = guib->X; - - areawid=guib->Width - 5; - padding = TEXTWINDOW_PADDING_DEFAULT; - - GET_OPTIONS_HEIGHT - - if (game.options[OPT_DIALOGUPWARDS]) { - // They want the options upwards from the bottom - dlgyp = (guib->Y + guib->Height) - needheight; - } - - } - } - else { - //dlgyp=(play.viewport.GetHeight()-numdisp*txthit)-1; - const Rect &ui_view = play.GetUIViewport(); - areawid= ui_view.GetWidth()-5; - padding = TEXTWINDOW_PADDING_DEFAULT; - GET_OPTIONS_HEIGHT - dlgyp = ui_view.GetHeight() - needheight; - - dirtyx = 0; - dirtyy = dlgyp - 1; - dirtywidth = ui_view.GetWidth(); - dirtyheight = ui_view.GetHeight() - dirtyy; - dialog_abs_x = 0; - } - if (!is_textwindow) - areawid -= data_to_game_coord(play.dialog_options_x) * 2; - - orixp = dlgxp; - oriyp = dlgyp; - wantRefresh = false; - mouseison=-10; - - update_polled_stuff_if_runtime(); - if (!play.mouse_cursor_hidden) - ags_domouse(DOMOUSE_ENABLE); - update_polled_stuff_if_runtime(); - - Redraw(); - while(Run()); - - if (!play.mouse_cursor_hidden) - ags_domouse(DOMOUSE_DISABLE); +void DialogOptions::Show() { + if (numdisp < 1) quit("!DoDialog: all options have been turned off"); + // Don't display the options if there is only one and the parser + // is not enabled. + if (!((numdisp > 1) || (parserInput != nullptr) || (play.show_single_dialog_option))) { + chose = disporder[0]; // only one choice, so select it + return; + } + + is_textwindow = 0; + forecol = play.dialog_options_highlight_color; + + mouseison = -1; + mousewason = -10; + const Rect &ui_view = play.GetUIViewport(); + dirtyx = 0; + dirtyy = 0; + dirtywidth = ui_view.GetWidth(); + dirtyheight = ui_view.GetHeight(); + usingCustomRendering = false; + + + dlgxp = 1; + if (get_custom_dialog_options_dimensions(dlgnum)) { + usingCustomRendering = true; + dirtyx = data_to_game_coord(ccDialogOptionsRendering.x); + dirtyy = data_to_game_coord(ccDialogOptionsRendering.y); + dirtywidth = data_to_game_coord(ccDialogOptionsRendering.width); + dirtyheight = data_to_game_coord(ccDialogOptionsRendering.height); + dialog_abs_x = dirtyx; + } else if (game.options[OPT_DIALOGIFACE] > 0) { + GUIMain *guib = &guis[game.options[OPT_DIALOGIFACE]]; + if (guib->IsTextWindow()) { + // text-window, so do the QFG4-style speech options + is_textwindow = 1; + forecol = guib->FgColor; + } else { + dlgxp = guib->X; + dlgyp = guib->Y; + + dirtyx = dlgxp; + dirtyy = dlgyp; + dirtywidth = guib->Width; + dirtyheight = guib->Height; + dialog_abs_x = guib->X; + + areawid = guib->Width - 5; + padding = TEXTWINDOW_PADDING_DEFAULT; + + GET_OPTIONS_HEIGHT + + if (game.options[OPT_DIALOGUPWARDS]) { + // They want the options upwards from the bottom + dlgyp = (guib->Y + guib->Height) - needheight; + } + + } + } else { + //dlgyp=(play.viewport.GetHeight()-numdisp*txthit)-1; + const Rect &ui_view = play.GetUIViewport(); + areawid = ui_view.GetWidth() - 5; + padding = TEXTWINDOW_PADDING_DEFAULT; + GET_OPTIONS_HEIGHT + dlgyp = ui_view.GetHeight() - needheight; + + dirtyx = 0; + dirtyy = dlgyp - 1; + dirtywidth = ui_view.GetWidth(); + dirtyheight = ui_view.GetHeight() - dirtyy; + dialog_abs_x = 0; + } + if (!is_textwindow) + areawid -= data_to_game_coord(play.dialog_options_x) * 2; + + orixp = dlgxp; + oriyp = dlgyp; + wantRefresh = false; + mouseison = -10; + + update_polled_stuff_if_runtime(); + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_ENABLE); + update_polled_stuff_if_runtime(); + + Redraw(); + while (Run()); + + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_DISABLE); } -void DialogOptions::Redraw() -{ - wantRefresh = true; - - if (usingCustomRendering) - { - tempScrn = recycle_bitmap(tempScrn, game.GetColorDepth(), - data_to_game_coord(ccDialogOptionsRendering.width), - data_to_game_coord(ccDialogOptionsRendering.height)); - } - - tempScrn->ClearTransparent(); - Bitmap *ds = tempScrn; - - dlgxp = orixp; - dlgyp = oriyp; - const Rect &ui_view = play.GetUIViewport(); - - bool options_surface_has_alpha = false; - - if (usingCustomRendering) - { - ccDialogOptionsRendering.surfaceToRenderTo = dialogOptionsRenderingSurface; - ccDialogOptionsRendering.surfaceAccessed = false; - dialogOptionsRenderingSurface->linkedBitmapOnly = tempScrn; - dialogOptionsRenderingSurface->hasAlphaChannel = ccDialogOptionsRendering.hasAlphaChannel; - options_surface_has_alpha = dialogOptionsRenderingSurface->hasAlphaChannel != 0; - - renderDialogOptionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - run_function_on_non_blocking_thread(&renderDialogOptionsFunc); - - if (!ccDialogOptionsRendering.surfaceAccessed) - debug_script_warn("dialog_options_get_dimensions was implemented, but no dialog_options_render function drew anything to the surface"); - - if (parserInput) - { - parserInput->X = data_to_game_coord(ccDialogOptionsRendering.parserTextboxX); - curyp = data_to_game_coord(ccDialogOptionsRendering.parserTextboxY); - areawid = data_to_game_coord(ccDialogOptionsRendering.parserTextboxWidth); - if (areawid == 0) - areawid = tempScrn->GetWidth(); - } - ccDialogOptionsRendering.needRepaint = false; - } - else if (is_textwindow) { - // text window behind the options - areawid = data_to_game_coord(play.max_dialogoption_width); - int biggest = 0; - padding = guis[game.options[OPT_DIALOGIFACE]].Padding; - for (int i = 0; i < numdisp; ++i) { - break_up_text_into_lines(get_translation(dtop->optionnames[disporder[i]]), Lines, areawid-((2*padding+2)+bullet_wid), usingfont); - if (longestline > biggest) - biggest = longestline; - } - if (biggest < areawid - ((2*padding+6)+bullet_wid)) - areawid = biggest + ((2*padding+6)+bullet_wid); - - if (areawid < data_to_game_coord(play.min_dialogoption_width)) { - areawid = data_to_game_coord(play.min_dialogoption_width); - if (play.min_dialogoption_width > play.max_dialogoption_width) - quit("!game.min_dialogoption_width is larger than game.max_dialogoption_width"); - } - - GET_OPTIONS_HEIGHT - - int savedwid = areawid; - int txoffs=0,tyoffs=0,yspos = ui_view.GetHeight()/2-(2*padding+needheight)/2; - int xspos = ui_view.GetWidth()/2 - areawid/2; - // shift window to the right if QG4-style full-screen pic - if ((game.options[OPT_SPEECHTYPE] == 3) && (said_text > 0)) - xspos = (ui_view.GetWidth() - areawid) - get_fixed_pixel_size(10); - - // needs to draw the right text window, not the default - Bitmap *text_window_ds = nullptr; - draw_text_window(&text_window_ds, false, &txoffs,&tyoffs,&xspos,&yspos,&areawid,nullptr,needheight, game.options[OPT_DIALOGIFACE]); - options_surface_has_alpha = guis[game.options[OPT_DIALOGIFACE]].HasAlphaChannel(); - // since draw_text_window incrases the width, restore it - areawid = savedwid; - - dirtyx = xspos; - dirtyy = yspos; - dirtywidth = text_window_ds->GetWidth(); - dirtyheight = text_window_ds->GetHeight(); - dialog_abs_x = txoffs + xspos; - - GfxUtil::DrawSpriteWithTransparency(ds, text_window_ds, xspos, yspos); - // TODO: here we rely on draw_text_window always assigning new bitmap to text_window_ds; - // should make this more explicit - delete text_window_ds; - - // Ignore the dialog_options_x/y offsets when using a text window - txoffs += xspos; - tyoffs += yspos; - dlgyp = tyoffs; - curyp = write_dialog_options(ds, options_surface_has_alpha, txoffs,tyoffs,numdisp,mouseison,areawid,bullet_wid,usingfont,dtop,disporder,dispyp,linespacing,forecol,padding); - if (parserInput) - parserInput->X = txoffs; - } - else { - - if (wantRefresh) { - // redraw the black background so that anti-alias - // fonts don't re-alias themselves - if (game.options[OPT_DIALOGIFACE] == 0) { - color_t draw_color = ds->GetCompatibleColor(16); - ds->FillRect(Rect(0,dlgyp-1, ui_view.GetWidth()-1, ui_view.GetHeight()-1), draw_color); - } - else { - GUIMain* guib = &guis[game.options[OPT_DIALOGIFACE]]; - if (!guib->IsTextWindow()) - draw_gui_for_dialog_options(ds, guib, dlgxp, dlgyp); - } - } - - dirtyx = 0; - dirtywidth = ui_view.GetWidth(); - - if (game.options[OPT_DIALOGIFACE] > 0) - { - // the whole GUI area should be marked dirty in order - // to ensure it gets drawn - GUIMain* guib = &guis[game.options[OPT_DIALOGIFACE]]; - dirtyheight = guib->Height; - dirtyy = dlgyp; - options_surface_has_alpha = guib->HasAlphaChannel(); - } - else - { - dirtyy = dlgyp - 1; - dirtyheight = needheight + 1; - options_surface_has_alpha = false; - } - - dlgxp += data_to_game_coord(play.dialog_options_x); - dlgyp += data_to_game_coord(play.dialog_options_y); - - // if they use a negative dialog_options_y, make sure the - // area gets marked as dirty - if (dlgyp < dirtyy) - dirtyy = dlgyp; - - //curyp = dlgyp + 1; - curyp = dlgyp; - curyp = write_dialog_options(ds, options_surface_has_alpha, dlgxp,curyp,numdisp,mouseison,areawid,bullet_wid,usingfont,dtop,disporder,dispyp,linespacing,forecol,padding); - - /*if (curyp > play.viewport.GetHeight()) { - dlgyp = play.viewport.GetHeight() - (curyp - dlgyp); - ds->FillRect(Rect(0,dlgyp-1,play.viewport.GetWidth()-1,play.viewport.GetHeight()-1); - goto redraw_options; - }*/ - if (parserInput) - parserInput->X = dlgxp; - } - - if (parserInput) { - // Set up the text box, if present - parserInput->Y = curyp + data_to_game_coord(game.options[OPT_DIALOGGAP]); - parserInput->Width = areawid - get_fixed_pixel_size(10); - parserInput->TextColor = playerchar->talkcolor; - if (mouseison == DLG_OPTION_PARSER) - parserInput->TextColor = forecol; - - if (game.dialog_bullet) // the parser X will get moved in a second - { - draw_gui_sprite_v330(ds, game.dialog_bullet, parserInput->X, parserInput->Y, options_surface_has_alpha); - } - - parserInput->Width -= bullet_wid; - parserInput->X += bullet_wid; - - parserInput->Draw(ds); - parserInput->IsActivated = false; - } - - wantRefresh = false; - - update_polled_stuff_if_runtime(); - - subBitmap = recycle_bitmap(subBitmap, tempScrn->GetColorDepth(), dirtywidth, dirtyheight); - subBitmap = ReplaceBitmapWithSupportedFormat(subBitmap); - - update_polled_stuff_if_runtime(); - - if (usingCustomRendering) - { - subBitmap->Blit(tempScrn, 0, 0, 0, 0, tempScrn->GetWidth(), tempScrn->GetHeight()); - invalidate_rect(dirtyx, dirtyy, dirtyx + subBitmap->GetWidth(), dirtyy + subBitmap->GetHeight(), false); - } - else - { - subBitmap->Blit(tempScrn, dirtyx, dirtyy, 0, 0, dirtywidth, dirtyheight); - } - - if ((ddb != nullptr) && - ((ddb->GetWidth() != dirtywidth) || - (ddb->GetHeight() != dirtyheight))) - { - gfxDriver->DestroyDDB(ddb); - ddb = nullptr; - } - - if (ddb == nullptr) - ddb = gfxDriver->CreateDDBFromBitmap(subBitmap, options_surface_has_alpha, false); - else - gfxDriver->UpdateDDBFromBitmap(ddb, subBitmap, options_surface_has_alpha); - - if (runGameLoopsInBackground) - { - render_graphics(ddb, dirtyx, dirtyy); - } +void DialogOptions::Redraw() { + wantRefresh = true; + + if (usingCustomRendering) { + tempScrn = recycle_bitmap(tempScrn, game.GetColorDepth(), + data_to_game_coord(ccDialogOptionsRendering.width), + data_to_game_coord(ccDialogOptionsRendering.height)); + } + + tempScrn->ClearTransparent(); + Bitmap *ds = tempScrn; + + dlgxp = orixp; + dlgyp = oriyp; + const Rect &ui_view = play.GetUIViewport(); + + bool options_surface_has_alpha = false; + + if (usingCustomRendering) { + ccDialogOptionsRendering.surfaceToRenderTo = dialogOptionsRenderingSurface; + ccDialogOptionsRendering.surfaceAccessed = false; + dialogOptionsRenderingSurface->linkedBitmapOnly = tempScrn; + dialogOptionsRenderingSurface->hasAlphaChannel = ccDialogOptionsRendering.hasAlphaChannel; + options_surface_has_alpha = dialogOptionsRenderingSurface->hasAlphaChannel != 0; + + renderDialogOptionsFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&renderDialogOptionsFunc); + + if (!ccDialogOptionsRendering.surfaceAccessed) + debug_script_warn("dialog_options_get_dimensions was implemented, but no dialog_options_render function drew anything to the surface"); + + if (parserInput) { + parserInput->X = data_to_game_coord(ccDialogOptionsRendering.parserTextboxX); + curyp = data_to_game_coord(ccDialogOptionsRendering.parserTextboxY); + areawid = data_to_game_coord(ccDialogOptionsRendering.parserTextboxWidth); + if (areawid == 0) + areawid = tempScrn->GetWidth(); + } + ccDialogOptionsRendering.needRepaint = false; + } else if (is_textwindow) { + // text window behind the options + areawid = data_to_game_coord(play.max_dialogoption_width); + int biggest = 0; + padding = guis[game.options[OPT_DIALOGIFACE]].Padding; + for (int i = 0; i < numdisp; ++i) { + break_up_text_into_lines(get_translation(dtop->optionnames[disporder[i]]), Lines, areawid - ((2 * padding + 2) + bullet_wid), usingfont); + if (longestline > biggest) + biggest = longestline; + } + if (biggest < areawid - ((2 * padding + 6) + bullet_wid)) + areawid = biggest + ((2 * padding + 6) + bullet_wid); + + if (areawid < data_to_game_coord(play.min_dialogoption_width)) { + areawid = data_to_game_coord(play.min_dialogoption_width); + if (play.min_dialogoption_width > play.max_dialogoption_width) + quit("!game.min_dialogoption_width is larger than game.max_dialogoption_width"); + } + + GET_OPTIONS_HEIGHT + + int savedwid = areawid; + int txoffs = 0, tyoffs = 0, yspos = ui_view.GetHeight() / 2 - (2 * padding + needheight) / 2; + int xspos = ui_view.GetWidth() / 2 - areawid / 2; + // shift window to the right if QG4-style full-screen pic + if ((game.options[OPT_SPEECHTYPE] == 3) && (said_text > 0)) + xspos = (ui_view.GetWidth() - areawid) - get_fixed_pixel_size(10); + + // needs to draw the right text window, not the default + Bitmap *text_window_ds = nullptr; + draw_text_window(&text_window_ds, false, &txoffs, &tyoffs, &xspos, &yspos, &areawid, nullptr, needheight, game.options[OPT_DIALOGIFACE]); + options_surface_has_alpha = guis[game.options[OPT_DIALOGIFACE]].HasAlphaChannel(); + // since draw_text_window incrases the width, restore it + areawid = savedwid; + + dirtyx = xspos; + dirtyy = yspos; + dirtywidth = text_window_ds->GetWidth(); + dirtyheight = text_window_ds->GetHeight(); + dialog_abs_x = txoffs + xspos; + + GfxUtil::DrawSpriteWithTransparency(ds, text_window_ds, xspos, yspos); + // TODO: here we rely on draw_text_window always assigning new bitmap to text_window_ds; + // should make this more explicit + delete text_window_ds; + + // Ignore the dialog_options_x/y offsets when using a text window + txoffs += xspos; + tyoffs += yspos; + dlgyp = tyoffs; + curyp = write_dialog_options(ds, options_surface_has_alpha, txoffs, tyoffs, numdisp, mouseison, areawid, bullet_wid, usingfont, dtop, disporder, dispyp, linespacing, forecol, padding); + if (parserInput) + parserInput->X = txoffs; + } else { + + if (wantRefresh) { + // redraw the black background so that anti-alias + // fonts don't re-alias themselves + if (game.options[OPT_DIALOGIFACE] == 0) { + color_t draw_color = ds->GetCompatibleColor(16); + ds->FillRect(Rect(0, dlgyp - 1, ui_view.GetWidth() - 1, ui_view.GetHeight() - 1), draw_color); + } else { + GUIMain *guib = &guis[game.options[OPT_DIALOGIFACE]]; + if (!guib->IsTextWindow()) + draw_gui_for_dialog_options(ds, guib, dlgxp, dlgyp); + } + } + + dirtyx = 0; + dirtywidth = ui_view.GetWidth(); + + if (game.options[OPT_DIALOGIFACE] > 0) { + // the whole GUI area should be marked dirty in order + // to ensure it gets drawn + GUIMain *guib = &guis[game.options[OPT_DIALOGIFACE]]; + dirtyheight = guib->Height; + dirtyy = dlgyp; + options_surface_has_alpha = guib->HasAlphaChannel(); + } else { + dirtyy = dlgyp - 1; + dirtyheight = needheight + 1; + options_surface_has_alpha = false; + } + + dlgxp += data_to_game_coord(play.dialog_options_x); + dlgyp += data_to_game_coord(play.dialog_options_y); + + // if they use a negative dialog_options_y, make sure the + // area gets marked as dirty + if (dlgyp < dirtyy) + dirtyy = dlgyp; + + //curyp = dlgyp + 1; + curyp = dlgyp; + curyp = write_dialog_options(ds, options_surface_has_alpha, dlgxp, curyp, numdisp, mouseison, areawid, bullet_wid, usingfont, dtop, disporder, dispyp, linespacing, forecol, padding); + + /*if (curyp > play.viewport.GetHeight()) { + dlgyp = play.viewport.GetHeight() - (curyp - dlgyp); + ds->FillRect(Rect(0,dlgyp-1,play.viewport.GetWidth()-1,play.viewport.GetHeight()-1); + goto redraw_options; + }*/ + if (parserInput) + parserInput->X = dlgxp; + } + + if (parserInput) { + // Set up the text box, if present + parserInput->Y = curyp + data_to_game_coord(game.options[OPT_DIALOGGAP]); + parserInput->Width = areawid - get_fixed_pixel_size(10); + parserInput->TextColor = playerchar->talkcolor; + if (mouseison == DLG_OPTION_PARSER) + parserInput->TextColor = forecol; + + if (game.dialog_bullet) { // the parser X will get moved in a second + draw_gui_sprite_v330(ds, game.dialog_bullet, parserInput->X, parserInput->Y, options_surface_has_alpha); + } + + parserInput->Width -= bullet_wid; + parserInput->X += bullet_wid; + + parserInput->Draw(ds); + parserInput->IsActivated = false; + } + + wantRefresh = false; + + update_polled_stuff_if_runtime(); + + subBitmap = recycle_bitmap(subBitmap, tempScrn->GetColorDepth(), dirtywidth, dirtyheight); + subBitmap = ReplaceBitmapWithSupportedFormat(subBitmap); + + update_polled_stuff_if_runtime(); + + if (usingCustomRendering) { + subBitmap->Blit(tempScrn, 0, 0, 0, 0, tempScrn->GetWidth(), tempScrn->GetHeight()); + invalidate_rect(dirtyx, dirtyy, dirtyx + subBitmap->GetWidth(), dirtyy + subBitmap->GetHeight(), false); + } else { + subBitmap->Blit(tempScrn, dirtyx, dirtyy, 0, 0, dirtywidth, dirtyheight); + } + + if ((ddb != nullptr) && + ((ddb->GetWidth() != dirtywidth) || + (ddb->GetHeight() != dirtyheight))) { + gfxDriver->DestroyDDB(ddb); + ddb = nullptr; + } + + if (ddb == nullptr) + ddb = gfxDriver->CreateDDBFromBitmap(subBitmap, options_surface_has_alpha, false); + else + gfxDriver->UpdateDDBFromBitmap(ddb, subBitmap, options_surface_has_alpha); + + if (runGameLoopsInBackground) { + render_graphics(ddb, dirtyx, dirtyy); + } } -bool DialogOptions::Run() -{ - const bool new_custom_render = usingCustomRendering && game.options[OPT_DIALOGOPTIONSAPI] >= 0; - - if (runGameLoopsInBackground) - { - play.disabled_user_interface++; - UpdateGameOnce(false, ddb, dirtyx, dirtyy); - play.disabled_user_interface--; - } - else - { - update_audio_system_on_game_loop(); - render_graphics(ddb, dirtyx, dirtyy); - } - - if (new_custom_render) - { - runDialogOptionRepExecFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - run_function_on_non_blocking_thread(&runDialogOptionRepExecFunc); - } - - int gkey; - if (run_service_key_controls(gkey) && !play.IsIgnoringInput()) { - if (parserInput) { - wantRefresh = true; - // type into the parser - if ((gkey == 361) || ((gkey == ' ') && (strlen(parserInput->Text) == 0))) { - // write previous contents into textbox (F3 or Space when box is empty) - for (unsigned int i = strlen(parserInput->Text); i < strlen(play.lastParserEntry); i++) { - parserInput->OnKeyPress(play.lastParserEntry[i]); - } - //ags_domouse(DOMOUSE_DISABLE); - Redraw(); - return true; // continue running loop - } - else if ((gkey >= 32) || (gkey == 13) || (gkey == 8)) { - parserInput->OnKeyPress(gkey); - if (!parserInput->IsActivated) { - //ags_domouse(DOMOUSE_DISABLE); - Redraw(); - return true; // continue running loop - } - } - } - else if (new_custom_render) - { - runDialogOptionKeyPressHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - runDialogOptionKeyPressHandlerFunc.params[1].SetInt32(GetKeyForKeyPressCb(gkey)); - run_function_on_non_blocking_thread(&runDialogOptionKeyPressHandlerFunc); - } - // Allow selection of options by keyboard shortcuts - else if (game.options[OPT_DIALOGNUMBERED] >= kDlgOptKeysOnly && - gkey >= '1' && gkey <= '9') - { - gkey -= '1'; - if (gkey < numdisp) { - chose = disporder[gkey]; - return false; // end dialog options running loop - } - } - } - mousewason=mouseison; - mouseison=-1; - if (new_custom_render); // do not automatically detect option under mouse - else if (usingCustomRendering) - { - if ((mousex >= dirtyx) && (mousey >= dirtyy) && - (mousex < dirtyx + tempScrn->GetWidth()) && - (mousey < dirtyy + tempScrn->GetHeight())) - { - getDialogOptionUnderCursorFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - run_function_on_non_blocking_thread(&getDialogOptionUnderCursorFunc); - - if (!getDialogOptionUnderCursorFunc.atLeastOneImplementationExists) - quit("!The script function dialog_options_get_active is not implemented. It must be present to use a custom dialogue system."); - - mouseison = ccDialogOptionsRendering.activeOptionID; - } - else - { - ccDialogOptionsRendering.activeOptionID = -1; - } - } - else if (mousex >= dialog_abs_x && mousex < (dialog_abs_x + areawid) && - mousey >= dlgyp && mousey < curyp) - { - mouseison=numdisp-1; - for (int i = 0; i < numdisp; ++i) { - if (mousey < dispyp[i]) { mouseison=i-1; break; } - } - if ((mouseison<0) | (mouseison>=numdisp)) mouseison=-1; - } - - if (parserInput != nullptr) { - int relativeMousey = mousey; - if (usingCustomRendering) - relativeMousey -= dirtyy; - - if ((relativeMousey > parserInput->Y) && - (relativeMousey < parserInput->Y + parserInput->Height)) - mouseison = DLG_OPTION_PARSER; - - if (parserInput->IsActivated) - parserActivated = 1; - } - - int mouseButtonPressed = NONE; - int mouseWheelTurn = 0; - if (run_service_mb_controls(mouseButtonPressed, mouseWheelTurn) && mouseButtonPressed >= 0 && - !play.IsIgnoringInput()) - { - if (mouseison < 0 && !new_custom_render) - { - if (usingCustomRendering) - { - runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1); - run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); - - if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists) - { - Redraw(); - return true; // continue running loop - } - } - return true; // continue running loop - } - if (mouseison == DLG_OPTION_PARSER) { - // they clicked the text box - parserActivated = 1; - } - else if (new_custom_render) - { - runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1); - run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); - } - else if (usingCustomRendering) - { - chose = mouseison; - return false; // end dialog options running loop - } - else { - chose=disporder[mouseison]; - return false; // end dialog options running loop - } - } - - if (usingCustomRendering) - { - if (mouseWheelTurn != 0) - { - runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - runDialogOptionMouseClickHandlerFunc.params[1].SetInt32((mouseWheelTurn < 0) ? 9 : 8); - run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); - - if (!new_custom_render) - { - if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists) - Redraw(); - return true; // continue running loop - } - } - } - - if (parserActivated) { - // They have selected a custom parser-based option - if (!parserInput->Text.IsEmpty() != 0) { - chose = DLG_OPTION_PARSER; - return false; // end dialog options running loop - } - else { - parserActivated = 0; - parserInput->IsActivated = 0; - } - } - if (mousewason != mouseison) { - //ags_domouse(DOMOUSE_DISABLE); - Redraw(); - return true; // continue running loop - } - if (new_custom_render) - { - if (ccDialogOptionsRendering.chosenOptionID >= 0) - { - chose = ccDialogOptionsRendering.chosenOptionID; - ccDialogOptionsRendering.chosenOptionID = -1; - return false; // end dialog options running loop - } - if (ccDialogOptionsRendering.needRepaint) - { - Redraw(); - return true; // continue running loop - } - } - - update_polled_stuff_if_runtime(); - - if (play.fast_forward == 0) - { - WaitForNextFrame(); - } - - return true; // continue running loop +bool DialogOptions::Run() { + const bool new_custom_render = usingCustomRendering && game.options[OPT_DIALOGOPTIONSAPI] >= 0; + + if (runGameLoopsInBackground) { + play.disabled_user_interface++; + UpdateGameOnce(false, ddb, dirtyx, dirtyy); + play.disabled_user_interface--; + } else { + update_audio_system_on_game_loop(); + render_graphics(ddb, dirtyx, dirtyy); + } + + if (new_custom_render) { + runDialogOptionRepExecFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&runDialogOptionRepExecFunc); + } + + int gkey; + if (run_service_key_controls(gkey) && !play.IsIgnoringInput()) { + if (parserInput) { + wantRefresh = true; + // type into the parser + if ((gkey == 361) || ((gkey == ' ') && (strlen(parserInput->Text) == 0))) { + // write previous contents into textbox (F3 or Space when box is empty) + for (unsigned int i = strlen(parserInput->Text); i < strlen(play.lastParserEntry); i++) { + parserInput->OnKeyPress(play.lastParserEntry[i]); + } + //ags_domouse(DOMOUSE_DISABLE); + Redraw(); + return true; // continue running loop + } else if ((gkey >= 32) || (gkey == 13) || (gkey == 8)) { + parserInput->OnKeyPress(gkey); + if (!parserInput->IsActivated) { + //ags_domouse(DOMOUSE_DISABLE); + Redraw(); + return true; // continue running loop + } + } + } else if (new_custom_render) { + runDialogOptionKeyPressHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionKeyPressHandlerFunc.params[1].SetInt32(GetKeyForKeyPressCb(gkey)); + run_function_on_non_blocking_thread(&runDialogOptionKeyPressHandlerFunc); + } + // Allow selection of options by keyboard shortcuts + else if (game.options[OPT_DIALOGNUMBERED] >= kDlgOptKeysOnly && + gkey >= '1' && gkey <= '9') { + gkey -= '1'; + if (gkey < numdisp) { + chose = disporder[gkey]; + return false; // end dialog options running loop + } + } + } + mousewason = mouseison; + mouseison = -1; + if (new_custom_render); // do not automatically detect option under mouse + else if (usingCustomRendering) { + if ((mousex >= dirtyx) && (mousey >= dirtyy) && + (mousex < dirtyx + tempScrn->GetWidth()) && + (mousey < dirtyy + tempScrn->GetHeight())) { + getDialogOptionUnderCursorFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + run_function_on_non_blocking_thread(&getDialogOptionUnderCursorFunc); + + if (!getDialogOptionUnderCursorFunc.atLeastOneImplementationExists) + quit("!The script function dialog_options_get_active is not implemented. It must be present to use a custom dialogue system."); + + mouseison = ccDialogOptionsRendering.activeOptionID; + } else { + ccDialogOptionsRendering.activeOptionID = -1; + } + } else if (mousex >= dialog_abs_x && mousex < (dialog_abs_x + areawid) && + mousey >= dlgyp && mousey < curyp) { + mouseison = numdisp - 1; + for (int i = 0; i < numdisp; ++i) { + if (mousey < dispyp[i]) { + mouseison = i - 1; + break; + } + } + if ((mouseison < 0) | (mouseison >= numdisp)) mouseison = -1; + } + + if (parserInput != nullptr) { + int relativeMousey = mousey; + if (usingCustomRendering) + relativeMousey -= dirtyy; + + if ((relativeMousey > parserInput->Y) && + (relativeMousey < parserInput->Y + parserInput->Height)) + mouseison = DLG_OPTION_PARSER; + + if (parserInput->IsActivated) + parserActivated = 1; + } + + int mouseButtonPressed = NONE; + int mouseWheelTurn = 0; + if (run_service_mb_controls(mouseButtonPressed, mouseWheelTurn) && mouseButtonPressed >= 0 && + !play.IsIgnoringInput()) { + if (mouseison < 0 && !new_custom_render) { + if (usingCustomRendering) { + runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1); + run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); + + if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists) { + Redraw(); + return true; // continue running loop + } + } + return true; // continue running loop + } + if (mouseison == DLG_OPTION_PARSER) { + // they clicked the text box + parserActivated = 1; + } else if (new_custom_render) { + runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionMouseClickHandlerFunc.params[1].SetInt32(mouseButtonPressed + 1); + run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); + } else if (usingCustomRendering) { + chose = mouseison; + return false; // end dialog options running loop + } else { + chose = disporder[mouseison]; + return false; // end dialog options running loop + } + } + + if (usingCustomRendering) { + if (mouseWheelTurn != 0) { + runDialogOptionMouseClickHandlerFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + runDialogOptionMouseClickHandlerFunc.params[1].SetInt32((mouseWheelTurn < 0) ? 9 : 8); + run_function_on_non_blocking_thread(&runDialogOptionMouseClickHandlerFunc); + + if (!new_custom_render) { + if (runDialogOptionMouseClickHandlerFunc.atLeastOneImplementationExists) + Redraw(); + return true; // continue running loop + } + } + } + + if (parserActivated) { + // They have selected a custom parser-based option + if (!parserInput->Text.IsEmpty() != 0) { + chose = DLG_OPTION_PARSER; + return false; // end dialog options running loop + } else { + parserActivated = 0; + parserInput->IsActivated = 0; + } + } + if (mousewason != mouseison) { + //ags_domouse(DOMOUSE_DISABLE); + Redraw(); + return true; // continue running loop + } + if (new_custom_render) { + if (ccDialogOptionsRendering.chosenOptionID >= 0) { + chose = ccDialogOptionsRendering.chosenOptionID; + ccDialogOptionsRendering.chosenOptionID = -1; + return false; // end dialog options running loop + } + if (ccDialogOptionsRendering.needRepaint) { + Redraw(); + return true; // continue running loop + } + } + + update_polled_stuff_if_runtime(); + + if (play.fast_forward == 0) { + WaitForNextFrame(); + } + + return true; // continue running loop } -void DialogOptions::Close() -{ - ags_clear_input_buffer(); - invalidate_screen(); - - if (parserActivated) - { - strcpy (play.lastParserEntry, parserInput->Text); - ParseText (parserInput->Text); - chose = CHOSE_TEXTPARSER; - } - - if (parserInput) { - delete parserInput; - parserInput = nullptr; - } - - if (ddb != nullptr) - gfxDriver->DestroyDDB(ddb); - delete subBitmap; - - set_mouse_cursor(curswas); - // In case it's the QFG4 style dialog, remove the black screen - play.in_conversation--; - remove_screen_overlay(OVER_COMPLETE); - - delete tempScrn; +void DialogOptions::Close() { + ags_clear_input_buffer(); + invalidate_screen(); + + if (parserActivated) { + strcpy(play.lastParserEntry, parserInput->Text); + ParseText(parserInput->Text); + chose = CHOSE_TEXTPARSER; + } + + if (parserInput) { + delete parserInput; + parserInput = nullptr; + } + + if (ddb != nullptr) + gfxDriver->DestroyDDB(ddb); + delete subBitmap; + + set_mouse_cursor(curswas); + // In case it's the QFG4 style dialog, remove the black screen + play.in_conversation--; + remove_screen_overlay(OVER_COMPLETE); + + delete tempScrn; } DialogOptions DlgOpt; -int show_dialog_options(int _dlgnum, int sayChosenOption, bool _runGameLoopsInBackground) -{ - DlgOpt.Prepare(_dlgnum, _runGameLoopsInBackground); - DlgOpt.Show(); - DlgOpt.Close(); - - int dialog_choice = DlgOpt.chose; - if (dialog_choice != CHOSE_TEXTPARSER) - { - DialogTopic *dialog_topic = DlgOpt.dtop; - int &option_flags = dialog_topic->optionflags[dialog_choice]; - const char *option_name = DlgOpt.dtop->optionnames[dialog_choice]; - - option_flags |= DFLG_HASBEENCHOSEN; - bool sayTheOption = false; - if (sayChosenOption == SAYCHOSEN_YES) - { - sayTheOption = true; - } - else if (sayChosenOption == SAYCHOSEN_USEFLAG) - { - sayTheOption = ((option_flags & DFLG_NOREPEAT) == 0); - } - - if (sayTheOption) - DisplaySpeech(get_translation(option_name), game.playercharacter); - } - - return dialog_choice; +int show_dialog_options(int _dlgnum, int sayChosenOption, bool _runGameLoopsInBackground) { + DlgOpt.Prepare(_dlgnum, _runGameLoopsInBackground); + DlgOpt.Show(); + DlgOpt.Close(); + + int dialog_choice = DlgOpt.chose; + if (dialog_choice != CHOSE_TEXTPARSER) { + DialogTopic *dialog_topic = DlgOpt.dtop; + int &option_flags = dialog_topic->optionflags[dialog_choice]; + const char *option_name = DlgOpt.dtop->optionnames[dialog_choice]; + + option_flags |= DFLG_HASBEENCHOSEN; + bool sayTheOption = false; + if (sayChosenOption == SAYCHOSEN_YES) { + sayTheOption = true; + } else if (sayChosenOption == SAYCHOSEN_USEFLAG) { + sayTheOption = ((option_flags & DFLG_NOREPEAT) == 0); + } + + if (sayTheOption) + DisplaySpeech(get_translation(option_name), game.playercharacter); + } + + return dialog_choice; } -void do_conversation(int dlgnum) -{ - EndSkippingUntilCharStops(); - - // AGS 2.x always makes the mouse cursor visible when displaying a dialog. - if (loaded_game_file_version <= kGameVersion_272) - play.mouse_cursor_hidden = 0; - - int dlgnum_was = dlgnum; - int previousTopics[MAX_TOPIC_HISTORY]; - int numPrevTopics = 0; - DialogTopic *dtop = &dialog[dlgnum]; - - // run the startup script - int tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0); - if ((tocar == RUN_DIALOG_STOP_DIALOG) || - (tocar == RUN_DIALOG_GOTO_PREVIOUS)) - { - // 'stop' or 'goto-previous' from first startup script - remove_screen_overlay(OVER_COMPLETE); - play.in_conversation--; - return; - } - else if (tocar >= 0) - dlgnum = tocar; - - while (dlgnum >= 0) - { - if (dlgnum >= game.numdialog) - quit("!RunDialog: invalid dialog number specified"); - - dtop = &dialog[dlgnum]; - - if (dlgnum != dlgnum_was) - { - // dialog topic changed, so play the startup - // script for the new topic - tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0); - dlgnum_was = dlgnum; - if (tocar == RUN_DIALOG_GOTO_PREVIOUS) { - if (numPrevTopics < 1) { - // goto-previous on first topic -- end dialog - tocar = RUN_DIALOG_STOP_DIALOG; - } - else { - tocar = previousTopics[numPrevTopics - 1]; - numPrevTopics--; - } - } - if (tocar == RUN_DIALOG_STOP_DIALOG) - break; - else if (tocar >= 0) { - // save the old topic number in the history - if (numPrevTopics < MAX_TOPIC_HISTORY) { - previousTopics[numPrevTopics] = dlgnum; - numPrevTopics++; - } - dlgnum = tocar; - continue; - } - } - - int chose = show_dialog_options(dlgnum, SAYCHOSEN_USEFLAG, (game.options[OPT_RUNGAMEDLGOPTS] != 0)); - - if (chose == CHOSE_TEXTPARSER) - { - said_speech_line = 0; - - tocar = run_dialog_request(dlgnum); - - if (said_speech_line > 0) { - // fix the problem with the close-up face remaining on screen - DisableInterface(); - UpdateGameOnce(); // redraw the screen to make sure it looks right - EnableInterface(); - set_mouse_cursor(CURS_ARROW); - } - } - else - { - tocar = run_dialog_script(dtop, dlgnum, dtop->entrypoints[chose], chose + 1); - } - - if (tocar == RUN_DIALOG_GOTO_PREVIOUS) { - if (numPrevTopics < 1) { - tocar = RUN_DIALOG_STOP_DIALOG; - } - else { - tocar = previousTopics[numPrevTopics - 1]; - numPrevTopics--; - } - } - if (tocar == RUN_DIALOG_STOP_DIALOG) break; - else if (tocar >= 0) { - // save the old topic number in the history - if (numPrevTopics < MAX_TOPIC_HISTORY) { - previousTopics[numPrevTopics] = dlgnum; - numPrevTopics++; - } - dlgnum = tocar; - } - - } +void do_conversation(int dlgnum) { + EndSkippingUntilCharStops(); + + // AGS 2.x always makes the mouse cursor visible when displaying a dialog. + if (loaded_game_file_version <= kGameVersion_272) + play.mouse_cursor_hidden = 0; + + int dlgnum_was = dlgnum; + int previousTopics[MAX_TOPIC_HISTORY]; + int numPrevTopics = 0; + DialogTopic *dtop = &dialog[dlgnum]; + + // run the startup script + int tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0); + if ((tocar == RUN_DIALOG_STOP_DIALOG) || + (tocar == RUN_DIALOG_GOTO_PREVIOUS)) { + // 'stop' or 'goto-previous' from first startup script + remove_screen_overlay(OVER_COMPLETE); + play.in_conversation--; + return; + } else if (tocar >= 0) + dlgnum = tocar; + + while (dlgnum >= 0) { + if (dlgnum >= game.numdialog) + quit("!RunDialog: invalid dialog number specified"); + + dtop = &dialog[dlgnum]; + + if (dlgnum != dlgnum_was) { + // dialog topic changed, so play the startup + // script for the new topic + tocar = run_dialog_script(dtop, dlgnum, dtop->startupentrypoint, 0); + dlgnum_was = dlgnum; + if (tocar == RUN_DIALOG_GOTO_PREVIOUS) { + if (numPrevTopics < 1) { + // goto-previous on first topic -- end dialog + tocar = RUN_DIALOG_STOP_DIALOG; + } else { + tocar = previousTopics[numPrevTopics - 1]; + numPrevTopics--; + } + } + if (tocar == RUN_DIALOG_STOP_DIALOG) + break; + else if (tocar >= 0) { + // save the old topic number in the history + if (numPrevTopics < MAX_TOPIC_HISTORY) { + previousTopics[numPrevTopics] = dlgnum; + numPrevTopics++; + } + dlgnum = tocar; + continue; + } + } + + int chose = show_dialog_options(dlgnum, SAYCHOSEN_USEFLAG, (game.options[OPT_RUNGAMEDLGOPTS] != 0)); + + if (chose == CHOSE_TEXTPARSER) { + said_speech_line = 0; + + tocar = run_dialog_request(dlgnum); + + if (said_speech_line > 0) { + // fix the problem with the close-up face remaining on screen + DisableInterface(); + UpdateGameOnce(); // redraw the screen to make sure it looks right + EnableInterface(); + set_mouse_cursor(CURS_ARROW); + } + } else { + tocar = run_dialog_script(dtop, dlgnum, dtop->entrypoints[chose], chose + 1); + } + + if (tocar == RUN_DIALOG_GOTO_PREVIOUS) { + if (numPrevTopics < 1) { + tocar = RUN_DIALOG_STOP_DIALOG; + } else { + tocar = previousTopics[numPrevTopics - 1]; + numPrevTopics--; + } + } + if (tocar == RUN_DIALOG_STOP_DIALOG) break; + else if (tocar >= 0) { + // save the old topic number in the history + if (numPrevTopics < MAX_TOPIC_HISTORY) { + previousTopics[numPrevTopics] = dlgnum; + numPrevTopics++; + } + dlgnum = tocar; + } + + } } @@ -1247,86 +1154,75 @@ void do_conversation(int dlgnum) extern ScriptString myScriptStringImpl; // int (ScriptDialog *sd) -RuntimeScriptValue Sc_Dialog_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialog, Dialog_GetID); +RuntimeScriptValue Sc_Dialog_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialog, Dialog_GetID); } // int (ScriptDialog *sd) -RuntimeScriptValue Sc_Dialog_GetOptionCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialog, Dialog_GetOptionCount); +RuntimeScriptValue Sc_Dialog_GetOptionCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialog, Dialog_GetOptionCount); } // int (ScriptDialog *sd) -RuntimeScriptValue Sc_Dialog_GetShowTextParser(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialog, Dialog_GetShowTextParser); +RuntimeScriptValue Sc_Dialog_GetShowTextParser(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialog, Dialog_GetShowTextParser); } // int (ScriptDialog *sd, int sayChosenOption) -RuntimeScriptValue Sc_Dialog_DisplayOptions(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(ScriptDialog, Dialog_DisplayOptions); +RuntimeScriptValue Sc_Dialog_DisplayOptions(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(ScriptDialog, Dialog_DisplayOptions); } // int (ScriptDialog *sd, int option) -RuntimeScriptValue Sc_Dialog_GetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(ScriptDialog, Dialog_GetOptionState); +RuntimeScriptValue Sc_Dialog_GetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(ScriptDialog, Dialog_GetOptionState); } // const char* (ScriptDialog *sd, int option) -RuntimeScriptValue Sc_Dialog_GetOptionText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT(ScriptDialog, const char, myScriptStringImpl, Dialog_GetOptionText); +RuntimeScriptValue Sc_Dialog_GetOptionText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT(ScriptDialog, const char, myScriptStringImpl, Dialog_GetOptionText); } // int (ScriptDialog *sd, int option) -RuntimeScriptValue Sc_Dialog_HasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(ScriptDialog, Dialog_HasOptionBeenChosen); +RuntimeScriptValue Sc_Dialog_HasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(ScriptDialog, Dialog_HasOptionBeenChosen); } -RuntimeScriptValue Sc_Dialog_SetHasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT_PBOOL(ScriptDialog, Dialog_SetHasOptionBeenChosen); +RuntimeScriptValue Sc_Dialog_SetHasOptionBeenChosen(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT_PBOOL(ScriptDialog, Dialog_SetHasOptionBeenChosen); } // void (ScriptDialog *sd, int option, int newState) -RuntimeScriptValue Sc_Dialog_SetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptDialog, Dialog_SetOptionState); +RuntimeScriptValue Sc_Dialog_SetOptionState(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptDialog, Dialog_SetOptionState); } // void (ScriptDialog *sd) -RuntimeScriptValue Sc_Dialog_Start(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptDialog, Dialog_Start); +RuntimeScriptValue Sc_Dialog_Start(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptDialog, Dialog_Start); } -void RegisterDialogAPI() -{ - ccAddExternalObjectFunction("Dialog::get_ID", Sc_Dialog_GetID); - ccAddExternalObjectFunction("Dialog::get_OptionCount", Sc_Dialog_GetOptionCount); - ccAddExternalObjectFunction("Dialog::get_ShowTextParser", Sc_Dialog_GetShowTextParser); - ccAddExternalObjectFunction("Dialog::DisplayOptions^1", Sc_Dialog_DisplayOptions); - ccAddExternalObjectFunction("Dialog::GetOptionState^1", Sc_Dialog_GetOptionState); - ccAddExternalObjectFunction("Dialog::GetOptionText^1", Sc_Dialog_GetOptionText); - ccAddExternalObjectFunction("Dialog::HasOptionBeenChosen^1", Sc_Dialog_HasOptionBeenChosen); - ccAddExternalObjectFunction("Dialog::SetHasOptionBeenChosen^2", Sc_Dialog_SetHasOptionBeenChosen); - ccAddExternalObjectFunction("Dialog::SetOptionState^2", Sc_Dialog_SetOptionState); - ccAddExternalObjectFunction("Dialog::Start^0", Sc_Dialog_Start); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Dialog::get_ID", (void*)Dialog_GetID); - ccAddExternalFunctionForPlugin("Dialog::get_OptionCount", (void*)Dialog_GetOptionCount); - ccAddExternalFunctionForPlugin("Dialog::get_ShowTextParser", (void*)Dialog_GetShowTextParser); - ccAddExternalFunctionForPlugin("Dialog::DisplayOptions^1", (void*)Dialog_DisplayOptions); - ccAddExternalFunctionForPlugin("Dialog::GetOptionState^1", (void*)Dialog_GetOptionState); - ccAddExternalFunctionForPlugin("Dialog::GetOptionText^1", (void*)Dialog_GetOptionText); - ccAddExternalFunctionForPlugin("Dialog::HasOptionBeenChosen^1", (void*)Dialog_HasOptionBeenChosen); - ccAddExternalFunctionForPlugin("Dialog::SetOptionState^2", (void*)Dialog_SetOptionState); - ccAddExternalFunctionForPlugin("Dialog::Start^0", (void*)Dialog_Start); +void RegisterDialogAPI() { + ccAddExternalObjectFunction("Dialog::get_ID", Sc_Dialog_GetID); + ccAddExternalObjectFunction("Dialog::get_OptionCount", Sc_Dialog_GetOptionCount); + ccAddExternalObjectFunction("Dialog::get_ShowTextParser", Sc_Dialog_GetShowTextParser); + ccAddExternalObjectFunction("Dialog::DisplayOptions^1", Sc_Dialog_DisplayOptions); + ccAddExternalObjectFunction("Dialog::GetOptionState^1", Sc_Dialog_GetOptionState); + ccAddExternalObjectFunction("Dialog::GetOptionText^1", Sc_Dialog_GetOptionText); + ccAddExternalObjectFunction("Dialog::HasOptionBeenChosen^1", Sc_Dialog_HasOptionBeenChosen); + ccAddExternalObjectFunction("Dialog::SetHasOptionBeenChosen^2", Sc_Dialog_SetHasOptionBeenChosen); + ccAddExternalObjectFunction("Dialog::SetOptionState^2", Sc_Dialog_SetOptionState); + ccAddExternalObjectFunction("Dialog::Start^0", Sc_Dialog_Start); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Dialog::get_ID", (void *)Dialog_GetID); + ccAddExternalFunctionForPlugin("Dialog::get_OptionCount", (void *)Dialog_GetOptionCount); + ccAddExternalFunctionForPlugin("Dialog::get_ShowTextParser", (void *)Dialog_GetShowTextParser); + ccAddExternalFunctionForPlugin("Dialog::DisplayOptions^1", (void *)Dialog_DisplayOptions); + ccAddExternalFunctionForPlugin("Dialog::GetOptionState^1", (void *)Dialog_GetOptionState); + ccAddExternalFunctionForPlugin("Dialog::GetOptionText^1", (void *)Dialog_GetOptionText); + ccAddExternalFunctionForPlugin("Dialog::HasOptionBeenChosen^1", (void *)Dialog_HasOptionBeenChosen); + ccAddExternalFunctionForPlugin("Dialog::SetOptionState^2", (void *)Dialog_SetOptionState); + ccAddExternalFunctionForPlugin("Dialog::Start^0", (void *)Dialog_Start); } diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h index 076c8d05c1c6..717ac31a2cdc 100644 --- a/engines/ags/engine/ac/dialog.h +++ b/engines/ags/engine/ac/dialog.h @@ -29,7 +29,7 @@ int Dialog_GetID(ScriptDialog *sd); int Dialog_GetOptionCount(ScriptDialog *sd); int Dialog_GetShowTextParser(ScriptDialog *sd); -const char* Dialog_GetOptionText(ScriptDialog *sd, int option); +const char *Dialog_GetOptionText(ScriptDialog *sd, int option); int Dialog_DisplayOptions(ScriptDialog *sd, int sayChosenOption); int Dialog_GetOptionState(ScriptDialog *sd, int option); int Dialog_HasOptionBeenChosen(ScriptDialog *sd, int option); diff --git a/engines/ags/engine/ac/dialogoptionsrendering.cpp b/engines/ags/engine/ac/dialogoptionsrendering.cpp index 686de549b0d9..499ed2104f32 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dialogoptionsrendering.cpp @@ -33,124 +33,101 @@ extern CCDialog ccDynamicDialog; // ** SCRIPT DIALOGOPTIONSRENDERING OBJECT -void DialogOptionsRendering_Update(ScriptDialogOptionsRendering *dlgOptRender) -{ - dlgOptRender->needRepaint = true; +void DialogOptionsRendering_Update(ScriptDialogOptionsRendering *dlgOptRender) { + dlgOptRender->needRepaint = true; } -bool DialogOptionsRendering_RunActiveOption(ScriptDialogOptionsRendering *dlgOptRender) -{ - dlgOptRender->chosenOptionID = dlgOptRender->activeOptionID; - return dlgOptRender->chosenOptionID >= 0; +bool DialogOptionsRendering_RunActiveOption(ScriptDialogOptionsRendering *dlgOptRender) { + dlgOptRender->chosenOptionID = dlgOptRender->activeOptionID; + return dlgOptRender->chosenOptionID >= 0; } -int DialogOptionsRendering_GetX(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->x; +int DialogOptionsRendering_GetX(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->x; } -void DialogOptionsRendering_SetX(ScriptDialogOptionsRendering *dlgOptRender, int newX) -{ - dlgOptRender->x = newX; +void DialogOptionsRendering_SetX(ScriptDialogOptionsRendering *dlgOptRender, int newX) { + dlgOptRender->x = newX; } -int DialogOptionsRendering_GetY(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->y; +int DialogOptionsRendering_GetY(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->y; } -void DialogOptionsRendering_SetY(ScriptDialogOptionsRendering *dlgOptRender, int newY) -{ - dlgOptRender->y = newY; +void DialogOptionsRendering_SetY(ScriptDialogOptionsRendering *dlgOptRender, int newY) { + dlgOptRender->y = newY; } -int DialogOptionsRendering_GetWidth(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->width; +int DialogOptionsRendering_GetWidth(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->width; } -void DialogOptionsRendering_SetWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth) -{ - dlgOptRender->width = newWidth; +void DialogOptionsRendering_SetWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth) { + dlgOptRender->width = newWidth; } -int DialogOptionsRendering_GetHeight(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->height; +int DialogOptionsRendering_GetHeight(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->height; } -void DialogOptionsRendering_SetHeight(ScriptDialogOptionsRendering *dlgOptRender, int newHeight) -{ - dlgOptRender->height = newHeight; +void DialogOptionsRendering_SetHeight(ScriptDialogOptionsRendering *dlgOptRender, int newHeight) { + dlgOptRender->height = newHeight; } -int DialogOptionsRendering_GetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->hasAlphaChannel; +int DialogOptionsRendering_GetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->hasAlphaChannel; } -void DialogOptionsRendering_SetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender, bool hasAlphaChannel) -{ - dlgOptRender->hasAlphaChannel = hasAlphaChannel; +void DialogOptionsRendering_SetHasAlphaChannel(ScriptDialogOptionsRendering *dlgOptRender, bool hasAlphaChannel) { + dlgOptRender->hasAlphaChannel = hasAlphaChannel; } -int DialogOptionsRendering_GetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->parserTextboxX; +int DialogOptionsRendering_GetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->parserTextboxX; } -void DialogOptionsRendering_SetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender, int newX) -{ - dlgOptRender->parserTextboxX = newX; +void DialogOptionsRendering_SetParserTextboxX(ScriptDialogOptionsRendering *dlgOptRender, int newX) { + dlgOptRender->parserTextboxX = newX; } -int DialogOptionsRendering_GetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->parserTextboxY; +int DialogOptionsRendering_GetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->parserTextboxY; } -void DialogOptionsRendering_SetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender, int newY) -{ - dlgOptRender->parserTextboxY = newY; +void DialogOptionsRendering_SetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender, int newY) { + dlgOptRender->parserTextboxY = newY; } -int DialogOptionsRendering_GetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->parserTextboxWidth; +int DialogOptionsRendering_GetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->parserTextboxWidth; } -void DialogOptionsRendering_SetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth) -{ - dlgOptRender->parserTextboxWidth = newWidth; +void DialogOptionsRendering_SetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth) { + dlgOptRender->parserTextboxWidth = newWidth; } -ScriptDialog* DialogOptionsRendering_GetDialogToRender(ScriptDialogOptionsRendering *dlgOptRender) -{ - return &scrDialog[dlgOptRender->dialogID]; +ScriptDialog *DialogOptionsRendering_GetDialogToRender(ScriptDialogOptionsRendering *dlgOptRender) { + return &scrDialog[dlgOptRender->dialogID]; } -ScriptDrawingSurface* DialogOptionsRendering_GetSurface(ScriptDialogOptionsRendering *dlgOptRender) -{ - dlgOptRender->surfaceAccessed = true; - return dlgOptRender->surfaceToRenderTo; +ScriptDrawingSurface *DialogOptionsRendering_GetSurface(ScriptDialogOptionsRendering *dlgOptRender) { + dlgOptRender->surfaceAccessed = true; + return dlgOptRender->surfaceToRenderTo; } -int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender) -{ - return dlgOptRender->activeOptionID + 1; +int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender) { + return dlgOptRender->activeOptionID + 1; } -void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID) -{ - int optionCount = dialog[scrDialog[dlgOptRender->dialogID].id].numoptions; - if ((activeOptionID < 0) || (activeOptionID > optionCount)) - quitprintf("DialogOptionsRenderingInfo.ActiveOptionID: invalid ID specified for this dialog (specified %d, valid range: 1..%d)", activeOptionID, optionCount); +void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID) { + int optionCount = dialog[scrDialog[dlgOptRender->dialogID].id].numoptions; + if ((activeOptionID < 0) || (activeOptionID > optionCount)) + quitprintf("DialogOptionsRenderingInfo.ActiveOptionID: invalid ID specified for this dialog (specified %d, valid range: 1..%d)", activeOptionID, optionCount); - if (dlgOptRender->activeOptionID != activeOptionID - 1) - { - dlgOptRender->activeOptionID = activeOptionID - 1; - dlgOptRender->needRepaint = true; - } + if (dlgOptRender->activeOptionID != activeOptionID - 1) { + dlgOptRender->activeOptionID = activeOptionID - 1; + dlgOptRender->needRepaint = true; + } } //============================================================================= @@ -163,178 +140,155 @@ void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgO #include "script/script_api.h" #include "script/script_runtime.h" -RuntimeScriptValue Sc_DialogOptionsRendering_Update(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptDialogOptionsRendering, DialogOptionsRendering_Update); +RuntimeScriptValue Sc_DialogOptionsRendering_Update(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptDialogOptionsRendering, DialogOptionsRendering_Update); } -RuntimeScriptValue Sc_DialogOptionsRendering_RunActiveOption(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(ScriptDialogOptionsRendering, DialogOptionsRendering_RunActiveOption); +RuntimeScriptValue Sc_DialogOptionsRendering_RunActiveOption(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(ScriptDialogOptionsRendering, DialogOptionsRendering_RunActiveOption); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetActiveOptionID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetActiveOptionID); +RuntimeScriptValue Sc_DialogOptionsRendering_GetActiveOptionID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetActiveOptionID); } // void (ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID) -RuntimeScriptValue Sc_DialogOptionsRendering_SetActiveOptionID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetActiveOptionID); +RuntimeScriptValue Sc_DialogOptionsRendering_SetActiveOptionID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetActiveOptionID); } // ScriptDialog* (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetDialogToRender(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptDialogOptionsRendering, ScriptDialog, ccDynamicDialog, DialogOptionsRendering_GetDialogToRender); +RuntimeScriptValue Sc_DialogOptionsRendering_GetDialogToRender(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptDialogOptionsRendering, ScriptDialog, ccDynamicDialog, DialogOptionsRendering_GetDialogToRender); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetHeight); +RuntimeScriptValue Sc_DialogOptionsRendering_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetHeight); } // void (ScriptDialogOptionsRendering *dlgOptRender, int newHeight) -RuntimeScriptValue Sc_DialogOptionsRendering_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetHeight); +RuntimeScriptValue Sc_DialogOptionsRendering_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetHeight); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxX); +RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxX); } // void (ScriptDialogOptionsRendering *dlgOptRender, int newX) -RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxX); +RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxX); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxY); +RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxY); } // void (ScriptDialogOptionsRendering *dlgOptRender, int newY) -RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxY); +RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxY); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxWidth); +RuntimeScriptValue Sc_DialogOptionsRendering_GetParserTextboxWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetParserTextboxWidth); } // void (ScriptDialogOptionsRendering *dlgOptRender, int newWidth) -RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxWidth); +RuntimeScriptValue Sc_DialogOptionsRendering_SetParserTextboxWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetParserTextboxWidth); } // ScriptDrawingSurface* (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJAUTO(ScriptDialogOptionsRendering, ScriptDrawingSurface, DialogOptionsRendering_GetSurface); +RuntimeScriptValue Sc_DialogOptionsRendering_GetSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJAUTO(ScriptDialogOptionsRendering, ScriptDrawingSurface, DialogOptionsRendering_GetSurface); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetWidth); +RuntimeScriptValue Sc_DialogOptionsRendering_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetWidth); } // void (ScriptDialogOptionsRendering *dlgOptRender, int newWidth) -RuntimeScriptValue Sc_DialogOptionsRendering_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetWidth); +RuntimeScriptValue Sc_DialogOptionsRendering_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetWidth); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetX); +RuntimeScriptValue Sc_DialogOptionsRendering_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetX); } // void (ScriptDialogOptionsRendering *dlgOptRender, int newX) -RuntimeScriptValue Sc_DialogOptionsRendering_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetX); +RuntimeScriptValue Sc_DialogOptionsRendering_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetX); } // int (ScriptDialogOptionsRendering *dlgOptRender) -RuntimeScriptValue Sc_DialogOptionsRendering_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetY); +RuntimeScriptValue Sc_DialogOptionsRendering_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetY); } // void (ScriptDialogOptionsRendering *dlgOptRender, int newY) -RuntimeScriptValue Sc_DialogOptionsRendering_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetY); -} - -RuntimeScriptValue Sc_DialogOptionsRendering_GetHasAlphaChannel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetHasAlphaChannel); -} - -RuntimeScriptValue Sc_DialogOptionsRendering_SetHasAlphaChannel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PBOOL(ScriptDialogOptionsRendering, DialogOptionsRendering_SetHasAlphaChannel); -} - - -void RegisterDialogOptionsRenderingAPI() -{ - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::Update^0", Sc_DialogOptionsRendering_Update); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::RunActiveOption^0", Sc_DialogOptionsRendering_RunActiveOption); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ActiveOptionID", Sc_DialogOptionsRendering_GetActiveOptionID); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ActiveOptionID", Sc_DialogOptionsRendering_SetActiveOptionID); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_DialogToRender", Sc_DialogOptionsRendering_GetDialogToRender); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Height", Sc_DialogOptionsRendering_GetHeight); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Height", Sc_DialogOptionsRendering_SetHeight); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxX", Sc_DialogOptionsRendering_GetParserTextboxX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxX", Sc_DialogOptionsRendering_SetParserTextboxX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxY", Sc_DialogOptionsRendering_GetParserTextboxY); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxY", Sc_DialogOptionsRendering_SetParserTextboxY); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxWidth", Sc_DialogOptionsRendering_GetParserTextboxWidth); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxWidth", Sc_DialogOptionsRendering_SetParserTextboxWidth); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Surface", Sc_DialogOptionsRendering_GetSurface); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Width", Sc_DialogOptionsRendering_GetWidth); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Width", Sc_DialogOptionsRendering_SetWidth); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_X", Sc_DialogOptionsRendering_GetX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_X", Sc_DialogOptionsRendering_SetX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Y", Sc_DialogOptionsRendering_GetY); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Y", Sc_DialogOptionsRendering_SetY); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_HasAlphaChannel", Sc_DialogOptionsRendering_GetHasAlphaChannel); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_HasAlphaChannel", Sc_DialogOptionsRendering_SetHasAlphaChannel); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ActiveOptionID", (void*)DialogOptionsRendering_GetActiveOptionID); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ActiveOptionID", (void*)DialogOptionsRendering_SetActiveOptionID); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_DialogToRender", (void*)DialogOptionsRendering_GetDialogToRender); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Height", (void*)DialogOptionsRendering_GetHeight); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Height", (void*)DialogOptionsRendering_SetHeight); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxX", (void*)DialogOptionsRendering_GetParserTextboxX); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxX", (void*)DialogOptionsRendering_SetParserTextboxX); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxY", (void*)DialogOptionsRendering_GetParserTextboxY); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxY", (void*)DialogOptionsRendering_SetParserTextboxY); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxWidth", (void*)DialogOptionsRendering_GetParserTextboxWidth); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxWidth", (void*)DialogOptionsRendering_SetParserTextboxWidth); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Surface", (void*)DialogOptionsRendering_GetSurface); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Width", (void*)DialogOptionsRendering_GetWidth); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Width", (void*)DialogOptionsRendering_SetWidth); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_X", (void*)DialogOptionsRendering_GetX); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_X", (void*)DialogOptionsRendering_SetX); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Y", (void*)DialogOptionsRendering_GetY); - ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Y", (void*)DialogOptionsRendering_SetY); +RuntimeScriptValue Sc_DialogOptionsRendering_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDialogOptionsRendering, DialogOptionsRendering_SetY); +} + +RuntimeScriptValue Sc_DialogOptionsRendering_GetHasAlphaChannel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDialogOptionsRendering, DialogOptionsRendering_GetHasAlphaChannel); +} + +RuntimeScriptValue Sc_DialogOptionsRendering_SetHasAlphaChannel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PBOOL(ScriptDialogOptionsRendering, DialogOptionsRendering_SetHasAlphaChannel); +} + + +void RegisterDialogOptionsRenderingAPI() { + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::Update^0", Sc_DialogOptionsRendering_Update); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::RunActiveOption^0", Sc_DialogOptionsRendering_RunActiveOption); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ActiveOptionID", Sc_DialogOptionsRendering_GetActiveOptionID); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ActiveOptionID", Sc_DialogOptionsRendering_SetActiveOptionID); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_DialogToRender", Sc_DialogOptionsRendering_GetDialogToRender); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Height", Sc_DialogOptionsRendering_GetHeight); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Height", Sc_DialogOptionsRendering_SetHeight); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxX", Sc_DialogOptionsRendering_GetParserTextboxX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxX", Sc_DialogOptionsRendering_SetParserTextboxX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxY", Sc_DialogOptionsRendering_GetParserTextboxY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxY", Sc_DialogOptionsRendering_SetParserTextboxY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxWidth", Sc_DialogOptionsRendering_GetParserTextboxWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxWidth", Sc_DialogOptionsRendering_SetParserTextboxWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Surface", Sc_DialogOptionsRendering_GetSurface); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Width", Sc_DialogOptionsRendering_GetWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Width", Sc_DialogOptionsRendering_SetWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_X", Sc_DialogOptionsRendering_GetX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_X", Sc_DialogOptionsRendering_SetX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Y", Sc_DialogOptionsRendering_GetY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Y", Sc_DialogOptionsRendering_SetY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_HasAlphaChannel", Sc_DialogOptionsRendering_GetHasAlphaChannel); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_HasAlphaChannel", Sc_DialogOptionsRendering_SetHasAlphaChannel); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ActiveOptionID", (void *)DialogOptionsRendering_GetActiveOptionID); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ActiveOptionID", (void *)DialogOptionsRendering_SetActiveOptionID); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_DialogToRender", (void *)DialogOptionsRendering_GetDialogToRender); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Height", (void *)DialogOptionsRendering_GetHeight); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Height", (void *)DialogOptionsRendering_SetHeight); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxX", (void *)DialogOptionsRendering_GetParserTextboxX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxX", (void *)DialogOptionsRendering_SetParserTextboxX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxY", (void *)DialogOptionsRendering_GetParserTextboxY); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxY", (void *)DialogOptionsRendering_SetParserTextboxY); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_ParserTextBoxWidth", (void *)DialogOptionsRendering_GetParserTextboxWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_ParserTextBoxWidth", (void *)DialogOptionsRendering_SetParserTextboxWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Surface", (void *)DialogOptionsRendering_GetSurface); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Width", (void *)DialogOptionsRendering_GetWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Width", (void *)DialogOptionsRendering_SetWidth); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_X", (void *)DialogOptionsRendering_GetX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_X", (void *)DialogOptionsRendering_SetX); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Y", (void *)DialogOptionsRendering_GetY); + ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Y", (void *)DialogOptionsRendering_SetY); } diff --git a/engines/ags/engine/ac/dialogoptionsrendering.h b/engines/ags/engine/ac/dialogoptionsrendering.h index a4d0aab4b22b..d1e741c20150 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.h +++ b/engines/ags/engine/ac/dialogoptionsrendering.h @@ -42,8 +42,8 @@ int DialogOptionsRendering_GetParserTextboxY(ScriptDialogOptionsRendering *dlgO void DialogOptionsRendering_SetParserTextboxY(ScriptDialogOptionsRendering *dlgOptRender, int newY); int DialogOptionsRendering_GetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender); void DialogOptionsRendering_SetParserTextboxWidth(ScriptDialogOptionsRendering *dlgOptRender, int newWidth); -ScriptDialog* DialogOptionsRendering_GetDialogToRender(ScriptDialogOptionsRendering *dlgOptRender); -ScriptDrawingSurface* DialogOptionsRendering_GetSurface(ScriptDialogOptionsRendering *dlgOptRender); +ScriptDialog *DialogOptionsRendering_GetDialogToRender(ScriptDialogOptionsRendering *dlgOptRender); +ScriptDrawingSurface *DialogOptionsRendering_GetSurface(ScriptDialogOptionsRendering *dlgOptRender); int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender); void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID); diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp index dbf7b27ad5e6..ddb918fae745 100644 --- a/engines/ags/engine/ac/display.cpp +++ b/engines/ags/engine/ac/display.cpp @@ -65,776 +65,730 @@ extern AGSPlatformDriver *platform; extern int loops_per_character; extern SpriteCache spriteset; -int display_message_aschar=0; +int display_message_aschar = 0; TopBarSettings topBar; -struct DisplayVars -{ - int lineheight; // font's height of single line - int linespacing; // font's line spacing - int fulltxtheight; // total height of all the text +struct DisplayVars { + int lineheight; // font's height of single line + int linespacing; // font's line spacing + int fulltxtheight; // total height of all the text } disp; // Pass yy = -1 to find Y co-ord automatically // allowShrink = 0 for none, 1 for leftwards, 2 for rightwards // pass blocking=2 to create permanent overlay -int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int usingfont, int asspch, int isThought, int allowShrink, bool overlayPositionFixed) -{ - const bool use_speech_textwindow = (asspch < 0) && (game.options[OPT_SPEECHTYPE] >= 2); - const bool use_thought_gui = (isThought) && (game.options[OPT_THOUGHTGUI] > 0); - - bool alphaChannel = false; - char todis[STD_BUFFER_SIZE]; - snprintf(todis, STD_BUFFER_SIZE - 1, "%s", text); - int usingGui = -1; - if (use_speech_textwindow) - usingGui = play.speech_textwindow_gui; - else if (use_thought_gui) - usingGui = game.options[OPT_THOUGHTGUI]; - - int padding = get_textwindow_padding(usingGui); - int paddingScaled = get_fixed_pixel_size(padding); - int paddingDoubledScaled = get_fixed_pixel_size(padding * 2); // Just in case screen size does is not neatly divisible by 320x200 - - ensure_text_valid_for_font(todis, usingfont); - break_up_text_into_lines(todis, Lines, wii-2*padding, usingfont); - disp.lineheight = getfontheight_outlined(usingfont); - disp.linespacing= getfontspacing_outlined(usingfont); - disp.fulltxtheight = getheightoflines(usingfont, Lines.Count()); - - // AGS 2.x: If the screen is faded out, fade in again when displaying a message box. - if (!asspch && (loaded_game_file_version <= kGameVersion_272)) - play.screen_is_faded_out = 0; - - // if it's a normal message box and the game was being skipped, - // ensure that the screen is up to date before the message box - // is drawn on top of it - // TODO: is this really necessary anymore? - if ((play.skip_until_char_stops >= 0) && (disp_type == DISPLAYTEXT_MESSAGEBOX)) - render_graphics(); - - EndSkippingUntilCharStops(); - - if (topBar.wantIt) { - // ensure that the window is wide enough to display - // any top bar text - int topBarWid = wgettextwidth_compensate(topBar.text, topBar.font); - topBarWid += data_to_game_coord(play.top_bar_borderwidth + 2) * 2; - if (longestline < topBarWid) - longestline = topBarWid; - // the top bar should behave like DisplaySpeech wrt blocking - disp_type = DISPLAYTEXT_SPEECH; - } - - if (asspch > 0) { - // update the all_buttons_disabled variable in advance - // of the adjust_x/y_for_guis calls - play.disabled_user_interface++; - update_gui_disabled_status(); - play.disabled_user_interface--; - } - - const Rect &ui_view = play.GetUIViewport(); - if (xx == OVR_AUTOPLACE) ; - // centre text in middle of screen - else if (yy<0) yy= ui_view.GetHeight()/2-disp.fulltxtheight/2-padding; - // speech, so it wants to be above the character's head - else if (asspch > 0) { - yy-=disp.fulltxtheight; - if (yy < 5) yy=5; - yy = adjust_y_for_guis (yy); - } - - if (longestline < wii - paddingDoubledScaled) { - // shrink the width of the dialog box to fit the text - int oldWid = wii; - //if ((asspch >= 0) || (allowShrink > 0)) - // If it's not speech, or a shrink is allowed, then shrink it - if ((asspch == 0) || (allowShrink > 0)) - wii = longestline + paddingDoubledScaled; - - // shift the dialog box right to align it, if necessary - if ((allowShrink == 2) && (xx >= 0)) - xx += (oldWid - wii); - } - - if (xx<-1) { - xx=(-xx)-wii/2; - if (xx < 0) - xx = 0; - - xx = adjust_x_for_guis (xx, yy); - - if (xx + wii >= ui_view.GetWidth()) - xx = (ui_view.GetWidth() - wii) - 5; - } - else if (xx<0) xx= ui_view.GetWidth()/2-wii/2; - - int extraHeight = paddingDoubledScaled; - color_t text_color = MakeColor(15); - if (disp_type < DISPLAYTEXT_NORMALOVERLAY) - remove_screen_overlay(OVER_TEXTMSG); // remove any previous blocking texts - - Bitmap *text_window_ds = BitmapHelper::CreateTransparentBitmap((wii > 0) ? wii : 2, disp.fulltxtheight + extraHeight, game.GetColorDepth()); - - // inform draw_text_window to free the old bitmap - const bool wantFreeScreenop = true; - - // - // Creating displayed graphic - // - // may later change if usingGUI, needed to avoid changing original coordinates - int adjustedXX = xx; - int adjustedYY = yy; - - if ((strlen (todis) < 1) || (strcmp (todis, " ") == 0) || (wii == 0)) ; - // if it's an empty speech line, don't draw anything - else if (asspch) { //text_color = ds->GetCompatibleColor(12); - int ttxleft = 0, ttxtop = paddingScaled, oriwid = wii - padding * 2; - int drawBackground = 0; - - if (use_speech_textwindow) { - drawBackground = 1; - } - else if (use_thought_gui) { - // make it treat it as drawing inside a window now - if (asspch > 0) - asspch = -asspch; - drawBackground = 1; - } - - if (drawBackground) - { - draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &ttxleft, &ttxtop, &adjustedXX, &adjustedYY, &wii, &text_color, 0, usingGui); - if (usingGui > 0) - { - alphaChannel = guis[usingGui].HasAlphaChannel(); - } - } - else if ((ShouldAntiAliasText()) && (game.GetColorDepth() >= 24)) - alphaChannel = true; - - for (size_t ee=0;ee= 0) && - ((game.options[OPT_SPEECHTYPE] >= 2) || (isThought))) - text_color = text_window_ds->GetCompatibleColor(guis[usingGui].FgColor); - else - text_color = text_window_ds->GetCompatibleColor(-asspch); - - wouttext_aligned(text_window_ds, ttxleft, ttyp, oriwid, usingfont, text_color, Lines[ee], play.text_align); - } - else { - text_color = text_window_ds->GetCompatibleColor(asspch); - wouttext_aligned(text_window_ds, ttxleft, ttyp, wii, usingfont, text_color, Lines[ee], play.speech_text_align); - } - } - } - else { - int xoffs,yoffs, oriwid = wii - padding * 2; - draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &xoffs,&yoffs,&xx,&yy,&wii,&text_color); - - if (game.options[OPT_TWCUSTOM] > 0) - { - alphaChannel = guis[game.options[OPT_TWCUSTOM]].HasAlphaChannel(); - } - - adjust_y_coordinate_for_text(&yoffs, usingfont); - - for (size_t ee=0;ee= OVER_CUSTOM) ovrtype = disp_type; - - int nse = add_screen_overlay(xx, yy, ovrtype, text_window_ds, adjustedXX - xx, adjustedYY - yy, alphaChannel); - // we should not delete text_window_ds here, because it is now owned by Overlay - - if (disp_type >= DISPLAYTEXT_NORMALOVERLAY) { - return screenover[nse].type; - } - - // - // Wait for the blocking text to timeout or until skipped by another command - // - if (disp_type == DISPLAYTEXT_MESSAGEBOX) { - // If fast-forwarding, then skip immediately - if (play.fast_forward) { - remove_screen_overlay(OVER_TEXTMSG); - play.messagetime=-1; - return 0; - } - - if (!play.mouse_cursor_hidden) - ags_domouse(DOMOUSE_ENABLE); - int countdown = GetTextDisplayTime (todis); - int skip_setting = user_to_internal_skip_speech((SkipSpeechStyle)play.skip_display); - // Loop until skipped - while (true) { - update_audio_system_on_game_loop(); - render_graphics(); - int mbut, mwheelz; - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) { - check_skip_cutscene_mclick(mbut); - if (play.fast_forward) - break; - if (skip_setting & SKIP_MOUSECLICK && !play.IsIgnoringInput()) - break; - } - int kp; - if (run_service_key_controls(kp)) { - check_skip_cutscene_keypress (kp); - if (play.fast_forward) - break; - if ((skip_setting & SKIP_KEYPRESS) && !play.IsIgnoringInput()) - break; - } - - update_polled_stuff_if_runtime(); - - if (play.fast_forward == 0) - { - WaitForNextFrame(); - } - - countdown--; - - // Special behavior when coupled with a voice-over - if (play.speech_has_voice) { - // extend life of text if the voice hasn't finished yet - if (channel_is_playing(SCHAN_SPEECH) && (play.fast_forward == 0)) { - if (countdown <= 1) - countdown = 1; - } - else // if the voice has finished, remove the speech - countdown = 0; - } - // Test for the timed auto-skip - if ((countdown < 1) && (skip_setting & SKIP_AUTOTIMER)) - { - play.SetIgnoreInput(play.ignore_user_input_after_text_timeout_ms); - break; - } - // if skipping cutscene, don't get stuck on No Auto Remove text boxes - if ((countdown < 1) && (play.fast_forward)) - break; - } - if (!play.mouse_cursor_hidden) - ags_domouse(DOMOUSE_DISABLE); - remove_screen_overlay(OVER_TEXTMSG); - invalidate_screen(); - } - else { - // if the speech does not time out, but we are skipping a cutscene, - // allow it to time out - if ((play.messagetime < 0) && (play.fast_forward)) - play.messagetime = 2; - - if (!overlayPositionFixed) - { - screenover[nse].positionRelativeToScreen = false; - VpPoint vpt = play.GetRoomViewport(0)->ScreenToRoom(screenover[nse].x, screenover[nse].y, false); - screenover[nse].x = vpt.first.X; - screenover[nse].y = vpt.first.Y; - } - - GameLoopUntilNoOverlay(); - } - - play.messagetime=-1; - return 0; +int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int usingfont, int asspch, int isThought, int allowShrink, bool overlayPositionFixed) { + const bool use_speech_textwindow = (asspch < 0) && (game.options[OPT_SPEECHTYPE] >= 2); + const bool use_thought_gui = (isThought) && (game.options[OPT_THOUGHTGUI] > 0); + + bool alphaChannel = false; + char todis[STD_BUFFER_SIZE]; + snprintf(todis, STD_BUFFER_SIZE - 1, "%s", text); + int usingGui = -1; + if (use_speech_textwindow) + usingGui = play.speech_textwindow_gui; + else if (use_thought_gui) + usingGui = game.options[OPT_THOUGHTGUI]; + + int padding = get_textwindow_padding(usingGui); + int paddingScaled = get_fixed_pixel_size(padding); + int paddingDoubledScaled = get_fixed_pixel_size(padding * 2); // Just in case screen size does is not neatly divisible by 320x200 + + ensure_text_valid_for_font(todis, usingfont); + break_up_text_into_lines(todis, Lines, wii - 2 * padding, usingfont); + disp.lineheight = getfontheight_outlined(usingfont); + disp.linespacing = getfontspacing_outlined(usingfont); + disp.fulltxtheight = getheightoflines(usingfont, Lines.Count()); + + // AGS 2.x: If the screen is faded out, fade in again when displaying a message box. + if (!asspch && (loaded_game_file_version <= kGameVersion_272)) + play.screen_is_faded_out = 0; + + // if it's a normal message box and the game was being skipped, + // ensure that the screen is up to date before the message box + // is drawn on top of it + // TODO: is this really necessary anymore? + if ((play.skip_until_char_stops >= 0) && (disp_type == DISPLAYTEXT_MESSAGEBOX)) + render_graphics(); + + EndSkippingUntilCharStops(); + + if (topBar.wantIt) { + // ensure that the window is wide enough to display + // any top bar text + int topBarWid = wgettextwidth_compensate(topBar.text, topBar.font); + topBarWid += data_to_game_coord(play.top_bar_borderwidth + 2) * 2; + if (longestline < topBarWid) + longestline = topBarWid; + // the top bar should behave like DisplaySpeech wrt blocking + disp_type = DISPLAYTEXT_SPEECH; + } + + if (asspch > 0) { + // update the all_buttons_disabled variable in advance + // of the adjust_x/y_for_guis calls + play.disabled_user_interface++; + update_gui_disabled_status(); + play.disabled_user_interface--; + } + + const Rect &ui_view = play.GetUIViewport(); + if (xx == OVR_AUTOPLACE) ; + // centre text in middle of screen + else if (yy < 0) yy = ui_view.GetHeight() / 2 - disp.fulltxtheight / 2 - padding; + // speech, so it wants to be above the character's head + else if (asspch > 0) { + yy -= disp.fulltxtheight; + if (yy < 5) yy = 5; + yy = adjust_y_for_guis(yy); + } + + if (longestline < wii - paddingDoubledScaled) { + // shrink the width of the dialog box to fit the text + int oldWid = wii; + //if ((asspch >= 0) || (allowShrink > 0)) + // If it's not speech, or a shrink is allowed, then shrink it + if ((asspch == 0) || (allowShrink > 0)) + wii = longestline + paddingDoubledScaled; + + // shift the dialog box right to align it, if necessary + if ((allowShrink == 2) && (xx >= 0)) + xx += (oldWid - wii); + } + + if (xx < -1) { + xx = (-xx) - wii / 2; + if (xx < 0) + xx = 0; + + xx = adjust_x_for_guis(xx, yy); + + if (xx + wii >= ui_view.GetWidth()) + xx = (ui_view.GetWidth() - wii) - 5; + } else if (xx < 0) xx = ui_view.GetWidth() / 2 - wii / 2; + + int extraHeight = paddingDoubledScaled; + color_t text_color = MakeColor(15); + if (disp_type < DISPLAYTEXT_NORMALOVERLAY) + remove_screen_overlay(OVER_TEXTMSG); // remove any previous blocking texts + + Bitmap *text_window_ds = BitmapHelper::CreateTransparentBitmap((wii > 0) ? wii : 2, disp.fulltxtheight + extraHeight, game.GetColorDepth()); + + // inform draw_text_window to free the old bitmap + const bool wantFreeScreenop = true; + + // + // Creating displayed graphic + // + // may later change if usingGUI, needed to avoid changing original coordinates + int adjustedXX = xx; + int adjustedYY = yy; + + if ((strlen(todis) < 1) || (strcmp(todis, " ") == 0) || (wii == 0)) ; + // if it's an empty speech line, don't draw anything + else if (asspch) { //text_color = ds->GetCompatibleColor(12); + int ttxleft = 0, ttxtop = paddingScaled, oriwid = wii - padding * 2; + int drawBackground = 0; + + if (use_speech_textwindow) { + drawBackground = 1; + } else if (use_thought_gui) { + // make it treat it as drawing inside a window now + if (asspch > 0) + asspch = -asspch; + drawBackground = 1; + } + + if (drawBackground) { + draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &ttxleft, &ttxtop, &adjustedXX, &adjustedYY, &wii, &text_color, 0, usingGui); + if (usingGui > 0) { + alphaChannel = guis[usingGui].HasAlphaChannel(); + } + } else if ((ShouldAntiAliasText()) && (game.GetColorDepth() >= 24)) + alphaChannel = true; + + for (size_t ee = 0; ee < Lines.Count(); ee++) { + //int ttxp=wii/2 - wgettextwidth_compensate(lines[ee], usingfont)/2; + int ttyp = ttxtop + ee * disp.linespacing; + // asspch < 0 means that it's inside a text box so don't + // centre the text + if (asspch < 0) { + if ((usingGui >= 0) && + ((game.options[OPT_SPEECHTYPE] >= 2) || (isThought))) + text_color = text_window_ds->GetCompatibleColor(guis[usingGui].FgColor); + else + text_color = text_window_ds->GetCompatibleColor(-asspch); + + wouttext_aligned(text_window_ds, ttxleft, ttyp, oriwid, usingfont, text_color, Lines[ee], play.text_align); + } else { + text_color = text_window_ds->GetCompatibleColor(asspch); + wouttext_aligned(text_window_ds, ttxleft, ttyp, wii, usingfont, text_color, Lines[ee], play.speech_text_align); + } + } + } else { + int xoffs, yoffs, oriwid = wii - padding * 2; + draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &xoffs, &yoffs, &xx, &yy, &wii, &text_color); + + if (game.options[OPT_TWCUSTOM] > 0) { + alphaChannel = guis[game.options[OPT_TWCUSTOM]].HasAlphaChannel(); + } + + adjust_y_coordinate_for_text(&yoffs, usingfont); + + for (size_t ee = 0; ee < Lines.Count(); ee++) + wouttext_aligned(text_window_ds, xoffs, yoffs + ee * disp.linespacing, oriwid, usingfont, text_color, Lines[ee], play.text_align); + } + + int ovrtype = OVER_TEXTMSG; + if (disp_type == DISPLAYTEXT_NORMALOVERLAY) ovrtype = OVER_CUSTOM; + else if (disp_type >= OVER_CUSTOM) ovrtype = disp_type; + + int nse = add_screen_overlay(xx, yy, ovrtype, text_window_ds, adjustedXX - xx, adjustedYY - yy, alphaChannel); + // we should not delete text_window_ds here, because it is now owned by Overlay + + if (disp_type >= DISPLAYTEXT_NORMALOVERLAY) { + return screenover[nse].type; + } + + // + // Wait for the blocking text to timeout or until skipped by another command + // + if (disp_type == DISPLAYTEXT_MESSAGEBOX) { + // If fast-forwarding, then skip immediately + if (play.fast_forward) { + remove_screen_overlay(OVER_TEXTMSG); + play.messagetime = -1; + return 0; + } + + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_ENABLE); + int countdown = GetTextDisplayTime(todis); + int skip_setting = user_to_internal_skip_speech((SkipSpeechStyle)play.skip_display); + // Loop until skipped + while (true) { + update_audio_system_on_game_loop(); + render_graphics(); + int mbut, mwheelz; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) { + check_skip_cutscene_mclick(mbut); + if (play.fast_forward) + break; + if (skip_setting & SKIP_MOUSECLICK && !play.IsIgnoringInput()) + break; + } + int kp; + if (run_service_key_controls(kp)) { + check_skip_cutscene_keypress(kp); + if (play.fast_forward) + break; + if ((skip_setting & SKIP_KEYPRESS) && !play.IsIgnoringInput()) + break; + } + + update_polled_stuff_if_runtime(); + + if (play.fast_forward == 0) { + WaitForNextFrame(); + } + + countdown--; + + // Special behavior when coupled with a voice-over + if (play.speech_has_voice) { + // extend life of text if the voice hasn't finished yet + if (channel_is_playing(SCHAN_SPEECH) && (play.fast_forward == 0)) { + if (countdown <= 1) + countdown = 1; + } else // if the voice has finished, remove the speech + countdown = 0; + } + // Test for the timed auto-skip + if ((countdown < 1) && (skip_setting & SKIP_AUTOTIMER)) { + play.SetIgnoreInput(play.ignore_user_input_after_text_timeout_ms); + break; + } + // if skipping cutscene, don't get stuck on No Auto Remove text boxes + if ((countdown < 1) && (play.fast_forward)) + break; + } + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_DISABLE); + remove_screen_overlay(OVER_TEXTMSG); + invalidate_screen(); + } else { + // if the speech does not time out, but we are skipping a cutscene, + // allow it to time out + if ((play.messagetime < 0) && (play.fast_forward)) + play.messagetime = 2; + + if (!overlayPositionFixed) { + screenover[nse].positionRelativeToScreen = false; + VpPoint vpt = play.GetRoomViewport(0)->ScreenToRoom(screenover[nse].x, screenover[nse].y, false); + screenover[nse].x = vpt.first.X; + screenover[nse].y = vpt.first.Y; + } + + GameLoopUntilNoOverlay(); + } + + play.messagetime = -1; + return 0; } void _display_at(int xx, int yy, int wii, const char *text, int disp_type, int asspch, int isThought, int allowShrink, bool overlayPositionFixed) { - int usingfont=FONT_NORMAL; - if (asspch) usingfont=FONT_SPEECH; - // TODO: _display_at may be called from _displayspeech, which can start - // and finalize voice speech on its own. Find out if we really need to - // keep track of this and not just stop voice regardless. - bool need_stop_speech = false; - - EndSkippingUntilCharStops(); - - if (try_auto_play_speech(text, text, play.narrator_speech, true)) - {// TODO: is there any need for this flag? - need_stop_speech = true; - } - _display_main(xx, yy, wii, text, disp_type, usingfont, asspch, isThought, allowShrink, overlayPositionFixed); - - if (need_stop_speech) - stop_voice_speech(); + int usingfont = FONT_NORMAL; + if (asspch) usingfont = FONT_SPEECH; + // TODO: _display_at may be called from _displayspeech, which can start + // and finalize voice speech on its own. Find out if we really need to + // keep track of this and not just stop voice regardless. + bool need_stop_speech = false; + + EndSkippingUntilCharStops(); + + if (try_auto_play_speech(text, text, play.narrator_speech, true)) { + // TODO: is there any need for this flag? + need_stop_speech = true; + } + _display_main(xx, yy, wii, text, disp_type, usingfont, asspch, isThought, allowShrink, overlayPositionFixed); + + if (need_stop_speech) + stop_voice_speech(); } -bool try_auto_play_speech(const char *text, const char *&replace_text, int charid, bool blocking) -{ - const char *src = text; - if (src[0] != '&') - return false; - - int sndid = atoi(&src[1]); - while ((src[0] != ' ') & (src[0] != 0)) src++; - if (src[0] == ' ') src++; - if (sndid <= 0) - quit("DisplaySpeech: auto-voice symbol '&' not followed by valid integer"); - - replace_text = src; // skip voice tag - if (play_voice_speech(charid, sndid)) - { - // if Voice Only, then blank out the text - if (play.want_speech == 2) - replace_text = " "; - return true; - } - return false; +bool try_auto_play_speech(const char *text, const char *&replace_text, int charid, bool blocking) { + const char *src = text; + if (src[0] != '&') + return false; + + int sndid = atoi(&src[1]); + while ((src[0] != ' ') & (src[0] != 0)) src++; + if (src[0] == ' ') src++; + if (sndid <= 0) + quit("DisplaySpeech: auto-voice symbol '&' not followed by valid integer"); + + replace_text = src; // skip voice tag + if (play_voice_speech(charid, sndid)) { + // if Voice Only, then blank out the text + if (play.want_speech == 2) + replace_text = " "; + return true; + } + return false; } // TODO: refactor this global variable out; currently it is set at the every get_translation call. // Be careful: a number of Say/Display functions expect it to be set beforehand. int source_text_length = -1; -int GetTextDisplayLength(const char *text) -{ - int len = (int)strlen(text); - if ((text[0] == '&') && (play.unfactor_speech_from_textlength != 0)) - { - // if there's an "&12 text" type line, remove "&12 " from the source length - size_t j = 0; - while ((text[j] != ' ') && (text[j] != 0)) - j++; - j++; - len -= j; - } - return len; +int GetTextDisplayLength(const char *text) { + int len = (int)strlen(text); + if ((text[0] == '&') && (play.unfactor_speech_from_textlength != 0)) { + // if there's an "&12 text" type line, remove "&12 " from the source length + size_t j = 0; + while ((text[j] != ' ') && (text[j] != 0)) + j++; + j++; + len -= j; + } + return len; } int GetTextDisplayTime(const char *text, int canberel) { - int uselen = 0; - auto fpstimer = ::lround(get_current_fps()); - - // if it's background speech, make it stay relative to game speed - if ((canberel == 1) && (play.bgspeech_game_speed == 1)) - fpstimer = 40; - - if (source_text_length >= 0) { - // sync to length of original text, to make sure any animations - // and music sync up correctly - uselen = source_text_length; - source_text_length = -1; - } - else { - uselen = GetTextDisplayLength(text); - } - - if (uselen <= 0) - return 0; - - if (play.text_speed + play.text_speed_modifier <= 0) - quit("!Text speed is zero; unable to display text. Check your game.text_speed settings."); - - // Store how many game loops per character of text - // This is calculated using a hard-coded 15 for the text speed, - // so that it's always the same no matter how fast the user - // can read. - loops_per_character = (((uselen/play.lipsync_speed)+1) * fpstimer) / uselen; - - int textDisplayTimeInMS = ((uselen / (play.text_speed + play.text_speed_modifier)) + 1) * 1000; - if (textDisplayTimeInMS < play.text_min_display_time_ms) - textDisplayTimeInMS = play.text_min_display_time_ms; - - return (textDisplayTimeInMS * fpstimer) / 1000; + int uselen = 0; + auto fpstimer = ::lround(get_current_fps()); + + // if it's background speech, make it stay relative to game speed + if ((canberel == 1) && (play.bgspeech_game_speed == 1)) + fpstimer = 40; + + if (source_text_length >= 0) { + // sync to length of original text, to make sure any animations + // and music sync up correctly + uselen = source_text_length; + source_text_length = -1; + } else { + uselen = GetTextDisplayLength(text); + } + + if (uselen <= 0) + return 0; + + if (play.text_speed + play.text_speed_modifier <= 0) + quit("!Text speed is zero; unable to display text. Check your game.text_speed settings."); + + // Store how many game loops per character of text + // This is calculated using a hard-coded 15 for the text speed, + // so that it's always the same no matter how fast the user + // can read. + loops_per_character = (((uselen / play.lipsync_speed) + 1) * fpstimer) / uselen; + + int textDisplayTimeInMS = ((uselen / (play.text_speed + play.text_speed_modifier)) + 1) * 1000; + if (textDisplayTimeInMS < play.text_min_display_time_ms) + textDisplayTimeInMS = play.text_min_display_time_ms; + + return (textDisplayTimeInMS * fpstimer) / 1000; } bool ShouldAntiAliasText() { - return (game.options[OPT_ANTIALIASFONTS] != 0); + return (game.options[OPT_ANTIALIASFONTS] != 0); } #if defined (AGS_FONTOUTLINE_MOREOPAQUE) // TODO: was suggested by fernewelten, but it's unclear whether is necessary // Make semi-transparent bits much more opaque -void wouttextxy_AutoOutline_Semitransparent2Opaque(Bitmap *map) -{ - if (map->GetColorDepth() < 32) - return; // such maps don't feature partial transparency - size_t const width = map->GetWidth(); - size_t const height = map->GetHeight(); - - for (size_t y = 0; y < height; y++) - { - int32 *sc_line = reinterpret_cast(map->GetScanLineForWriting(y)); - for (size_t x = 0; x < width; x++) - { - int32 &px = sc_line[x]; - int const transparency = geta(px); - if (0 < transparency && transparency < 255) - px = makeacol32( - getr32(px), - getg32(px), - getb32(px), - std::min(85 + transparency * 2, 255)); - } - } +void wouttextxy_AutoOutline_Semitransparent2Opaque(Bitmap *map) { + if (map->GetColorDepth() < 32) + return; // such maps don't feature partial transparency + size_t const width = map->GetWidth(); + size_t const height = map->GetHeight(); + + for (size_t y = 0; y < height; y++) { + int32 *sc_line = reinterpret_cast(map->GetScanLineForWriting(y)); + for (size_t x = 0; x < width; x++) { + int32 &px = sc_line[x]; + int const transparency = geta(px); + if (0 < transparency && transparency < 255) + px = makeacol32( + getr32(px), + getg32(px), + getb32(px), + std::min(85 + transparency * 2, 255)); + } + } } #endif // Draw outline that is calculated from the text font, not derived from an outline font -void wouttextxy_AutoOutline(Bitmap *ds, size_t font, int32_t color, const char *texx, int &xxp, int &yyp) -{ - int const thickness = game.fonts.at(font).AutoOutlineThickness; - auto const style = game.fonts.at(font).AutoOutlineStyle; - if (thickness <= 0) - return; - - // 16-bit games should use 32-bit stencils to keep anti-aliasing working - int const ds_cd = ds->GetColorDepth(); - bool const antialias = ds_cd >= 16 && game.options[OPT_ANTIALIASFONTS] != 0 && !is_bitmap_font(font); - int const stencil_cd = antialias ? 32 : ds_cd; - if (antialias) // This is to make sure TTFs render proper alpha channel in 16-bit games too - color |= makeacol32(0, 0, 0, 0xff); - - size_t const t_width = wgettextwidth(texx, font); - size_t const t_height = wgettextheight(texx, font); - if (t_width == 0 || t_height == 0) - return; - Bitmap texx_stencil, outline_stencil; - texx_stencil.CreateTransparent(t_width, t_height, stencil_cd); - outline_stencil.CreateTransparent(t_width, t_height + 2 * thickness, stencil_cd); - if (outline_stencil.IsNull() || texx_stencil.IsNull()) - return; - wouttextxy(&texx_stencil, 0, 0, font, color, texx); +void wouttextxy_AutoOutline(Bitmap *ds, size_t font, int32_t color, const char *texx, int &xxp, int &yyp) { + int const thickness = game.fonts.at(font).AutoOutlineThickness; + auto const style = game.fonts.at(font).AutoOutlineStyle; + if (thickness <= 0) + return; + + // 16-bit games should use 32-bit stencils to keep anti-aliasing working + int const ds_cd = ds->GetColorDepth(); + bool const antialias = ds_cd >= 16 && game.options[OPT_ANTIALIASFONTS] != 0 && !is_bitmap_font(font); + int const stencil_cd = antialias ? 32 : ds_cd; + if (antialias) // This is to make sure TTFs render proper alpha channel in 16-bit games too + color |= makeacol32(0, 0, 0, 0xff); + + size_t const t_width = wgettextwidth(texx, font); + size_t const t_height = wgettextheight(texx, font); + if (t_width == 0 || t_height == 0) + return; + Bitmap texx_stencil, outline_stencil; + texx_stencil.CreateTransparent(t_width, t_height, stencil_cd); + outline_stencil.CreateTransparent(t_width, t_height + 2 * thickness, stencil_cd); + if (outline_stencil.IsNull() || texx_stencil.IsNull()) + return; + wouttextxy(&texx_stencil, 0, 0, font, color, texx); #if defined (AGS_FONTOUTLINE_MOREOPAQUE) - wouttextxy_AutoOutline_Semitransparent2Opaque(texx_stencil); + wouttextxy_AutoOutline_Semitransparent2Opaque(texx_stencil); #endif - void(Bitmap::*pfn_drawstencil)(Bitmap *src, int dst_x, int dst_y); - if (antialias) - { // NOTE: we must set out blender AFTER wouttextxy, or it will be overidden - set_argb2any_blender(); - pfn_drawstencil = &Bitmap::TransBlendBlt; - } - else - { - pfn_drawstencil = &Bitmap::MaskedBlit; - } - - // move start of text so that the outline doesn't drop off the bitmap - xxp += thickness; - int const outline_y = yyp; - yyp += thickness; - - int largest_y_diff_reached_so_far = -1; - for (int x_diff = thickness; x_diff >= 0; x_diff--) - { - // Integer arithmetics: In the following, we use terms k*(k + 1) to account for rounding. - // (k + 0.5)^2 == k*k + 2*k*0.5 + 0.5^2 == k*k + k + 0.25 ==approx. k*(k + 1) - int y_term_limit = thickness * (thickness + 1); - if (FontInfo::kRounded == style) - y_term_limit -= x_diff * x_diff; - - // extend the outline stencil to the top and bottom - for (int y_diff = largest_y_diff_reached_so_far + 1; - y_diff <= thickness && y_diff * y_diff <= y_term_limit; - y_diff++) - { - (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness - y_diff); - if (y_diff > 0) - (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness + y_diff); - largest_y_diff_reached_so_far = y_diff; - } - - // stamp the outline stencil to the left and right of the text - (ds->*pfn_drawstencil)(&outline_stencil, xxp - x_diff, outline_y); - if (x_diff > 0) - (ds->*pfn_drawstencil)(&outline_stencil, xxp + x_diff, outline_y); - } + void(Bitmap::*pfn_drawstencil)(Bitmap * src, int dst_x, int dst_y); + if (antialias) { + // NOTE: we must set out blender AFTER wouttextxy, or it will be overidden + set_argb2any_blender(); + pfn_drawstencil = &Bitmap::TransBlendBlt; + } else { + pfn_drawstencil = &Bitmap::MaskedBlit; + } + + // move start of text so that the outline doesn't drop off the bitmap + xxp += thickness; + int const outline_y = yyp; + yyp += thickness; + + int largest_y_diff_reached_so_far = -1; + for (int x_diff = thickness; x_diff >= 0; x_diff--) { + // Integer arithmetics: In the following, we use terms k*(k + 1) to account for rounding. + // (k + 0.5)^2 == k*k + 2*k*0.5 + 0.5^2 == k*k + k + 0.25 ==approx. k*(k + 1) + int y_term_limit = thickness * (thickness + 1); + if (FontInfo::kRounded == style) + y_term_limit -= x_diff * x_diff; + + // extend the outline stencil to the top and bottom + for (int y_diff = largest_y_diff_reached_so_far + 1; + y_diff <= thickness && y_diff * y_diff <= y_term_limit; + y_diff++) { + (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness - y_diff); + if (y_diff > 0) + (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness + y_diff); + largest_y_diff_reached_so_far = y_diff; + } + + // stamp the outline stencil to the left and right of the text + (ds->*pfn_drawstencil)(&outline_stencil, xxp - x_diff, outline_y); + if (x_diff > 0) + (ds->*pfn_drawstencil)(&outline_stencil, xxp + x_diff, outline_y); + } } -// Draw an outline if requested, then draw the text on top -void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int font, color_t text_color, const char *texx) -{ - size_t const text_font = static_cast(font); - // Draw outline (a backdrop) if requested - color_t const outline_color = ds->GetCompatibleColor(play.speech_text_shadow); - int const outline_font = get_font_outline(font); - if (outline_font >= 0) - wouttextxy(ds, xxp, yyp, static_cast(outline_font), outline_color, texx); - else if (outline_font == FONT_OUTLINE_AUTO) - wouttextxy_AutoOutline(ds, text_font, outline_color, texx, xxp, yyp); - else - ; // no outline - - // Draw text on top - wouttextxy(ds, xxp, yyp, text_font, text_color, texx); +// Draw an outline if requested, then draw the text on top +void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int font, color_t text_color, const char *texx) { + size_t const text_font = static_cast(font); + // Draw outline (a backdrop) if requested + color_t const outline_color = ds->GetCompatibleColor(play.speech_text_shadow); + int const outline_font = get_font_outline(font); + if (outline_font >= 0) + wouttextxy(ds, xxp, yyp, static_cast(outline_font), outline_color, texx); + else if (outline_font == FONT_OUTLINE_AUTO) + wouttextxy_AutoOutline(ds, text_font, outline_color, texx, xxp, yyp); + else + ; // no outline + + // Draw text on top + wouttextxy(ds, xxp, yyp, text_font, text_color, texx); } void wouttext_aligned(Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align) { - if (align & kMAlignHCenter) - usexp = usexp + (oriwid / 2) - (wgettextwidth_compensate(text, usingfont) / 2); - else if (align & kMAlignRight) - usexp = usexp + (oriwid - wgettextwidth_compensate(text, usingfont)); + if (align & kMAlignHCenter) + usexp = usexp + (oriwid / 2) - (wgettextwidth_compensate(text, usingfont) / 2); + else if (align & kMAlignRight) + usexp = usexp + (oriwid - wgettextwidth_compensate(text, usingfont)); - wouttext_outline(ds, usexp, yy, usingfont, text_color, (char *)text); + wouttext_outline(ds, usexp, yy, usingfont, text_color, (char *)text); } // Get outline's thickness addition to the font's width or height -int get_outline_padding(int font) -{ - if (get_font_outline(font) == FONT_OUTLINE_AUTO) { - return get_font_outline_thickness(font) * 2; - } - return 0; +int get_outline_padding(int font) { + if (get_font_outline(font) == FONT_OUTLINE_AUTO) { + return get_font_outline_thickness(font) * 2; + } + return 0; } -int getfontheight_outlined(int font) -{ - return getfontheight(font) + get_outline_padding(font); +int getfontheight_outlined(int font) { + return getfontheight(font) + get_outline_padding(font); } -int getfontspacing_outlined(int font) -{ - return use_default_linespacing(font) ? - getfontheight_outlined(font) : - getfontlinespacing(font); +int getfontspacing_outlined(int font) { + return use_default_linespacing(font) ? + getfontheight_outlined(font) : + getfontlinespacing(font); } -int getfontlinegap(int font) -{ - return getfontspacing_outlined(font) - getfontheight_outlined(font); +int getfontlinegap(int font) { + return getfontspacing_outlined(font) - getfontheight_outlined(font); } -int getheightoflines(int font, int numlines) -{ - return getfontspacing_outlined(font) * (numlines - 1) + getfontheight_outlined(font); +int getheightoflines(int font, int numlines) { + return getfontspacing_outlined(font) * (numlines - 1) + getfontheight_outlined(font); } -int wgettextwidth_compensate(const char *tex, int font) -{ - return wgettextwidth(tex, font) + get_outline_padding(font); +int wgettextwidth_compensate(const char *tex, int font) { + return wgettextwidth(tex, font) + get_outline_padding(font); } void do_corner(Bitmap *ds, int sprn, int x, int y, int offx, int offy) { - if (sprn<0) return; - if (spriteset[sprn] == nullptr) - { - sprn = 0; - } - - x = x + offx * game.SpriteInfos[sprn].Width; - y = y + offy * game.SpriteInfos[sprn].Height; - draw_gui_sprite_v330(ds, sprn, x, y); + if (sprn < 0) return; + if (spriteset[sprn] == nullptr) { + sprn = 0; + } + + x = x + offx * game.SpriteInfos[sprn].Width; + y = y + offy * game.SpriteInfos[sprn].Height; + draw_gui_sprite_v330(ds, sprn, x, y); } -int get_but_pic(GUIMain*guo,int indx) -{ - int butid = guo->GetControlID(indx); - return butid >= 0 ? guibuts[butid].Image : 0; +int get_but_pic(GUIMain *guo, int indx) { + int butid = guo->GetControlID(indx); + return butid >= 0 ? guibuts[butid].Image : 0; } -void draw_button_background(Bitmap *ds, int xx1,int yy1,int xx2,int yy2,GUIMain*iep) { - color_t draw_color; - if (iep==nullptr) { // standard window - draw_color = ds->GetCompatibleColor(15); - ds->FillRect(Rect(xx1,yy1,xx2,yy2), draw_color); - draw_color = ds->GetCompatibleColor(16); - ds->DrawRect(Rect(xx1,yy1,xx2,yy2), draw_color); - /* draw_color = ds->GetCompatibleColor(opts.tws.backcol); ds->FillRect(Rect(xx1,yy1,xx2,yy2); - draw_color = ds->GetCompatibleColor(opts.tws.ds->GetTextColor()); ds->DrawRect(Rect(xx1+1,yy1+1,xx2-1,yy2-1);*/ - } - else { - if (loaded_game_file_version < kGameVersion_262) // < 2.62 - { - // Color 0 wrongly shows as transparent instead of black - // From the changelog of 2.62: - // - Fixed text windows getting a black background if colour 0 was - // specified, rather than being transparent. - if (iep->BgColor == 0) - iep->BgColor = 16; - } - - if (iep->BgColor >= 0) draw_color = ds->GetCompatibleColor(iep->BgColor); - else draw_color = ds->GetCompatibleColor(0); // black backrgnd behind picture - - if (iep->BgColor > 0) - ds->FillRect(Rect(xx1,yy1,xx2,yy2), draw_color); - - int leftRightWidth = game.SpriteInfos[get_but_pic(iep,4)].Width; - int topBottomHeight = game.SpriteInfos[get_but_pic(iep,6)].Height; - if (iep->BgImage>0) { - if ((loaded_game_file_version <= kGameVersion_272) // 2.xx - && (spriteset[iep->BgImage]->GetWidth() == 1) - && (spriteset[iep->BgImage]->GetHeight() == 1) - && (*((unsigned int*)spriteset[iep->BgImage]->GetData()) == 0x00FF00FF)) - { - // Don't draw fully transparent dummy GUI backgrounds - } - else - { - // offset the background image and clip it so that it is drawn - // such that the border graphics can have a transparent outside - // edge - int bgoffsx = xx1 - leftRightWidth / 2; - int bgoffsy = yy1 - topBottomHeight / 2; - ds->SetClip(Rect(bgoffsx, bgoffsy, xx2 + leftRightWidth / 2, yy2 + topBottomHeight / 2)); - int bgfinishx = xx2; - int bgfinishy = yy2; - int bgoffsyStart = bgoffsy; - while (bgoffsx <= bgfinishx) - { - bgoffsy = bgoffsyStart; - while (bgoffsy <= bgfinishy) - { - draw_gui_sprite_v330(ds, iep->BgImage, bgoffsx, bgoffsy); - bgoffsy += game.SpriteInfos[iep->BgImage].Height; - } - bgoffsx += game.SpriteInfos[iep->BgImage].Width; - } - // return to normal clipping rectangle - ds->SetClip(Rect(0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1)); - } - } - int uu; - for (uu=yy1;uu <= yy2;uu+= game.SpriteInfos[get_but_pic(iep,4)].Height) { - do_corner(ds, get_but_pic(iep,4),xx1,uu,-1,0); // left side - do_corner(ds, get_but_pic(iep,5),xx2+1,uu,0,0); // right side - } - for (uu=xx1;uu <= xx2;uu+=game.SpriteInfos[get_but_pic(iep,6)].Width) { - do_corner(ds, get_but_pic(iep,6),uu,yy1,0,-1); // top side - do_corner(ds, get_but_pic(iep,7),uu,yy2+1,0,0); // bottom side - } - do_corner(ds, get_but_pic(iep,0),xx1,yy1,-1,-1); // top left - do_corner(ds, get_but_pic(iep,1),xx1,yy2+1,-1,0); // bottom left - do_corner(ds, get_but_pic(iep,2),xx2+1,yy1,0,-1); // top right - do_corner(ds, get_but_pic(iep,3),xx2+1,yy2+1,0,0); // bottom right - } +void draw_button_background(Bitmap *ds, int xx1, int yy1, int xx2, int yy2, GUIMain *iep) { + color_t draw_color; + if (iep == nullptr) { // standard window + draw_color = ds->GetCompatibleColor(15); + ds->FillRect(Rect(xx1, yy1, xx2, yy2), draw_color); + draw_color = ds->GetCompatibleColor(16); + ds->DrawRect(Rect(xx1, yy1, xx2, yy2), draw_color); + /* draw_color = ds->GetCompatibleColor(opts.tws.backcol); ds->FillRect(Rect(xx1,yy1,xx2,yy2); + draw_color = ds->GetCompatibleColor(opts.tws.ds->GetTextColor()); ds->DrawRect(Rect(xx1+1,yy1+1,xx2-1,yy2-1);*/ + } else { + if (loaded_game_file_version < kGameVersion_262) { // < 2.62 + // Color 0 wrongly shows as transparent instead of black + // From the changelog of 2.62: + // - Fixed text windows getting a black background if colour 0 was + // specified, rather than being transparent. + if (iep->BgColor == 0) + iep->BgColor = 16; + } + + if (iep->BgColor >= 0) draw_color = ds->GetCompatibleColor(iep->BgColor); + else draw_color = ds->GetCompatibleColor(0); // black backrgnd behind picture + + if (iep->BgColor > 0) + ds->FillRect(Rect(xx1, yy1, xx2, yy2), draw_color); + + int leftRightWidth = game.SpriteInfos[get_but_pic(iep, 4)].Width; + int topBottomHeight = game.SpriteInfos[get_but_pic(iep, 6)].Height; + if (iep->BgImage > 0) { + if ((loaded_game_file_version <= kGameVersion_272) // 2.xx + && (spriteset[iep->BgImage]->GetWidth() == 1) + && (spriteset[iep->BgImage]->GetHeight() == 1) + && (*((unsigned int *)spriteset[iep->BgImage]->GetData()) == 0x00FF00FF)) { + // Don't draw fully transparent dummy GUI backgrounds + } else { + // offset the background image and clip it so that it is drawn + // such that the border graphics can have a transparent outside + // edge + int bgoffsx = xx1 - leftRightWidth / 2; + int bgoffsy = yy1 - topBottomHeight / 2; + ds->SetClip(Rect(bgoffsx, bgoffsy, xx2 + leftRightWidth / 2, yy2 + topBottomHeight / 2)); + int bgfinishx = xx2; + int bgfinishy = yy2; + int bgoffsyStart = bgoffsy; + while (bgoffsx <= bgfinishx) { + bgoffsy = bgoffsyStart; + while (bgoffsy <= bgfinishy) { + draw_gui_sprite_v330(ds, iep->BgImage, bgoffsx, bgoffsy); + bgoffsy += game.SpriteInfos[iep->BgImage].Height; + } + bgoffsx += game.SpriteInfos[iep->BgImage].Width; + } + // return to normal clipping rectangle + ds->SetClip(Rect(0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1)); + } + } + int uu; + for (uu = yy1; uu <= yy2; uu += game.SpriteInfos[get_but_pic(iep, 4)].Height) { + do_corner(ds, get_but_pic(iep, 4), xx1, uu, -1, 0); // left side + do_corner(ds, get_but_pic(iep, 5), xx2 + 1, uu, 0, 0); // right side + } + for (uu = xx1; uu <= xx2; uu += game.SpriteInfos[get_but_pic(iep, 6)].Width) { + do_corner(ds, get_but_pic(iep, 6), uu, yy1, 0, -1); // top side + do_corner(ds, get_but_pic(iep, 7), uu, yy2 + 1, 0, 0); // bottom side + } + do_corner(ds, get_but_pic(iep, 0), xx1, yy1, -1, -1); // top left + do_corner(ds, get_but_pic(iep, 1), xx1, yy2 + 1, -1, 0); // bottom left + do_corner(ds, get_but_pic(iep, 2), xx2 + 1, yy1, 0, -1); // top right + do_corner(ds, get_but_pic(iep, 3), xx2 + 1, yy2 + 1, 0, 0); // bottom right + } } // Calculate the width that the left and right border of the textwindow // GUI take up -int get_textwindow_border_width (int twgui) { - if (twgui < 0) - return 0; +int get_textwindow_border_width(int twgui) { + if (twgui < 0) + return 0; - if (!guis[twgui].IsTextWindow()) - quit("!GUI set as text window but is not actually a text window GUI"); + if (!guis[twgui].IsTextWindow()) + quit("!GUI set as text window but is not actually a text window GUI"); - int borwid = game.SpriteInfos[get_but_pic(&guis[twgui], 4)].Width + - game.SpriteInfos[get_but_pic(&guis[twgui], 5)].Width; + int borwid = game.SpriteInfos[get_but_pic(&guis[twgui], 4)].Width + + game.SpriteInfos[get_but_pic(&guis[twgui], 5)].Width; - return borwid; + return borwid; } // get the hegiht of the text window's top border -int get_textwindow_top_border_height (int twgui) { - if (twgui < 0) - return 0; +int get_textwindow_top_border_height(int twgui) { + if (twgui < 0) + return 0; - if (!guis[twgui].IsTextWindow()) - quit("!GUI set as text window but is not actually a text window GUI"); + if (!guis[twgui].IsTextWindow()) + quit("!GUI set as text window but is not actually a text window GUI"); - return game.SpriteInfos[get_but_pic(&guis[twgui], 6)].Height; + return game.SpriteInfos[get_but_pic(&guis[twgui], 6)].Height; } // Get the padding for a text window // -1 for the game's custom text window int get_textwindow_padding(int ifnum) { - int result; + int result; - if (ifnum < 0) - ifnum = game.options[OPT_TWCUSTOM]; - if (ifnum > 0 && ifnum < game.numgui) - result = guis[ifnum].Padding; - else - result = TEXTWINDOW_PADDING_DEFAULT; + if (ifnum < 0) + ifnum = game.options[OPT_TWCUSTOM]; + if (ifnum > 0 && ifnum < game.numgui) + result = guis[ifnum].Padding; + else + result = TEXTWINDOW_PADDING_DEFAULT; - return result; + return result; } void draw_text_window(Bitmap **text_window_ds, bool should_free_ds, - int*xins,int*yins,int*xx,int*yy,int*wii, color_t *set_text_color, int ovrheight, int ifnum) { - - Bitmap *ds = *text_window_ds; - if (ifnum < 0) - ifnum = game.options[OPT_TWCUSTOM]; - - if (ifnum <= 0) { - if (ovrheight) - quit("!Cannot use QFG4 style options without custom text window"); - draw_button_background(ds, 0,0,ds->GetWidth() - 1,ds->GetHeight() - 1,nullptr); - if (set_text_color) - *set_text_color = ds->GetCompatibleColor(16); - xins[0]=3; - yins[0]=3; - } - else { - if (ifnum >= game.numgui) - quitprintf("!Invalid GUI %d specified as text window (total GUIs: %d)", ifnum, game.numgui); - if (!guis[ifnum].IsTextWindow()) - quit("!GUI set as text window but is not actually a text window GUI"); - - int tbnum = get_but_pic(&guis[ifnum], 0); - - wii[0] += get_textwindow_border_width (ifnum); - xx[0]-=game.SpriteInfos[tbnum].Width; - yy[0]-=game.SpriteInfos[tbnum].Height; - if (ovrheight == 0) - ovrheight = disp.fulltxtheight; - - if (should_free_ds) - delete *text_window_ds; - int padding = get_textwindow_padding(ifnum); - *text_window_ds = BitmapHelper::CreateTransparentBitmap(wii[0],ovrheight+(padding*2)+ game.SpriteInfos[tbnum].Height*2,game.GetColorDepth()); - ds = *text_window_ds; - int xoffs=game.SpriteInfos[tbnum].Width,yoffs= game.SpriteInfos[tbnum].Height; - draw_button_background(ds, xoffs,yoffs,(ds->GetWidth() - xoffs) - 1,(ds->GetHeight() - yoffs) - 1,&guis[ifnum]); - if (set_text_color) - *set_text_color = ds->GetCompatibleColor(guis[ifnum].FgColor); - xins[0]=xoffs+padding; - yins[0]=yoffs+padding; - } + int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum) { + + Bitmap *ds = *text_window_ds; + if (ifnum < 0) + ifnum = game.options[OPT_TWCUSTOM]; + + if (ifnum <= 0) { + if (ovrheight) + quit("!Cannot use QFG4 style options without custom text window"); + draw_button_background(ds, 0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1, nullptr); + if (set_text_color) + *set_text_color = ds->GetCompatibleColor(16); + xins[0] = 3; + yins[0] = 3; + } else { + if (ifnum >= game.numgui) + quitprintf("!Invalid GUI %d specified as text window (total GUIs: %d)", ifnum, game.numgui); + if (!guis[ifnum].IsTextWindow()) + quit("!GUI set as text window but is not actually a text window GUI"); + + int tbnum = get_but_pic(&guis[ifnum], 0); + + wii[0] += get_textwindow_border_width(ifnum); + xx[0] -= game.SpriteInfos[tbnum].Width; + yy[0] -= game.SpriteInfos[tbnum].Height; + if (ovrheight == 0) + ovrheight = disp.fulltxtheight; + + if (should_free_ds) + delete *text_window_ds; + int padding = get_textwindow_padding(ifnum); + *text_window_ds = BitmapHelper::CreateTransparentBitmap(wii[0], ovrheight + (padding * 2) + game.SpriteInfos[tbnum].Height * 2, game.GetColorDepth()); + ds = *text_window_ds; + int xoffs = game.SpriteInfos[tbnum].Width, yoffs = game.SpriteInfos[tbnum].Height; + draw_button_background(ds, xoffs, yoffs, (ds->GetWidth() - xoffs) - 1, (ds->GetHeight() - yoffs) - 1, &guis[ifnum]); + if (set_text_color) + *set_text_color = ds->GetCompatibleColor(guis[ifnum].FgColor); + xins[0] = xoffs + padding; + yins[0] = yoffs + padding; + } } void draw_text_window_and_bar(Bitmap **text_window_ds, bool should_free_ds, - int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight, int ifnum) { - - draw_text_window(text_window_ds, should_free_ds, xins, yins, xx, yy, wii, set_text_color, ovrheight, ifnum); - - if ((topBar.wantIt) && (text_window_ds && *text_window_ds)) { - // top bar on the dialog window with character's name - // create an enlarged window, then free the old one - Bitmap *ds = *text_window_ds; - Bitmap *newScreenop = BitmapHelper::CreateBitmap(ds->GetWidth(), ds->GetHeight() + topBar.height, game.GetColorDepth()); - newScreenop->Blit(ds, 0, 0, 0, topBar.height, ds->GetWidth(), ds->GetHeight()); - delete *text_window_ds; - *text_window_ds = newScreenop; - ds = *text_window_ds; - - // draw the top bar - color_t draw_color = ds->GetCompatibleColor(play.top_bar_backcolor); - ds->FillRect(Rect(0, 0, ds->GetWidth() - 1, topBar.height - 1), draw_color); - if (play.top_bar_backcolor != play.top_bar_bordercolor) { - // draw the border - draw_color = ds->GetCompatibleColor(play.top_bar_bordercolor); - for (int j = 0; j < data_to_game_coord(play.top_bar_borderwidth); j++) - ds->DrawRect(Rect(j, j, ds->GetWidth() - (j + 1), topBar.height - (j + 1)), draw_color); - } - - // draw the text - int textx = (ds->GetWidth() / 2) - wgettextwidth_compensate(topBar.text, topBar.font) / 2; - color_t text_color = ds->GetCompatibleColor(play.top_bar_textcolor); - wouttext_outline(ds, textx, play.top_bar_borderwidth + get_fixed_pixel_size(1), topBar.font, text_color, topBar.text); - - // don't draw it next time - topBar.wantIt = 0; - // adjust the text Y position - yins[0] += topBar.height; - } - else if (topBar.wantIt) - topBar.wantIt = 0; + int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum) { + + draw_text_window(text_window_ds, should_free_ds, xins, yins, xx, yy, wii, set_text_color, ovrheight, ifnum); + + if ((topBar.wantIt) && (text_window_ds && *text_window_ds)) { + // top bar on the dialog window with character's name + // create an enlarged window, then free the old one + Bitmap *ds = *text_window_ds; + Bitmap *newScreenop = BitmapHelper::CreateBitmap(ds->GetWidth(), ds->GetHeight() + topBar.height, game.GetColorDepth()); + newScreenop->Blit(ds, 0, 0, 0, topBar.height, ds->GetWidth(), ds->GetHeight()); + delete *text_window_ds; + *text_window_ds = newScreenop; + ds = *text_window_ds; + + // draw the top bar + color_t draw_color = ds->GetCompatibleColor(play.top_bar_backcolor); + ds->FillRect(Rect(0, 0, ds->GetWidth() - 1, topBar.height - 1), draw_color); + if (play.top_bar_backcolor != play.top_bar_bordercolor) { + // draw the border + draw_color = ds->GetCompatibleColor(play.top_bar_bordercolor); + for (int j = 0; j < data_to_game_coord(play.top_bar_borderwidth); j++) + ds->DrawRect(Rect(j, j, ds->GetWidth() - (j + 1), topBar.height - (j + 1)), draw_color); + } + + // draw the text + int textx = (ds->GetWidth() / 2) - wgettextwidth_compensate(topBar.text, topBar.font) / 2; + color_t text_color = ds->GetCompatibleColor(play.top_bar_textcolor); + wouttext_outline(ds, textx, play.top_bar_borderwidth + get_fixed_pixel_size(1), topBar.font, text_color, topBar.text); + + // don't draw it next time + topBar.wantIt = 0; + // adjust the text Y position + yins[0] += topBar.height; + } else if (topBar.wantIt) + topBar.wantIt = 0; } diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h index 72bd83c57134..6ea4cd5e6713 100644 --- a/engines/ags/engine/ac/display.h +++ b/engines/ags/engine/ac/display.h @@ -45,9 +45,9 @@ bool ShouldAntiAliasText(); int GetTextDisplayLength(const char *text); // Calculates number of game loops for displaying a text on screen int GetTextDisplayTime(const char *text, int canberel = 0); -// Draw an outline if requested, then draw the text on top +// Draw an outline if requested, then draw the text on top void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); -void wouttext_aligned (Common::Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align); +void wouttext_aligned(Common::Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align); // TODO: GUI classes located in Common library do not make use of outlining, // need to find a way to make all code use same functions. // Get the maximal height of the given font, with corresponding outlining @@ -60,23 +60,23 @@ int getfontlinegap(int font); int getheightoflines(int font, int numlines); // Get the maximal width of the given font, with corresponding outlining int wgettextwidth_compensate(const char *tex, int font); -void do_corner(Common::Bitmap *ds, int sprn,int xx1,int yy1,int typx,int typy); +void do_corner(Common::Bitmap *ds, int sprn, int xx1, int yy1, int typx, int typy); // Returns the image of a button control on the GUI under given child index -int get_but_pic(GUIMain*guo,int indx); -void draw_button_background(Common::Bitmap *ds, int xx1,int yy1,int xx2,int yy2,GUIMain*iep); +int get_but_pic(GUIMain *guo, int indx); +void draw_button_background(Common::Bitmap *ds, int xx1, int yy1, int xx2, int yy2, GUIMain *iep); // Calculate the width that the left and right border of the textwindow // GUI take up -int get_textwindow_border_width (int twgui); +int get_textwindow_border_width(int twgui); // get the hegiht of the text window's top border -int get_textwindow_top_border_height (int twgui); +int get_textwindow_top_border_height(int twgui); // draw_text_window: draws the normal or custom text window // create a new bitmap the size of the window before calling, and // point text_window_ds to it // returns text start x & y pos in parameters // Warning!: draw_text_window() and draw_text_window_and_bar() can create new text_window_ds -void draw_text_window(Common::Bitmap **text_window_ds, bool should_free_ds, int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight, int ifnum); +void draw_text_window(Common::Bitmap **text_window_ds, bool should_free_ds, int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum); void draw_text_window_and_bar(Common::Bitmap **text_window_ds, bool should_free_ds, - int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight=0, int ifnum=-1); + int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight = 0, int ifnum = -1); int get_textwindow_padding(int ifnum); // The efficient length of the last source text prepared for display diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index 96b420cf5ac2..e5e80f3ac595 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -103,23 +103,23 @@ extern int walkBehindsCachedForBgNum; extern WalkBehindMethodEnum walkBehindMethod; extern int walk_behind_baselines_changed; extern SpriteCache spriteset; -extern RoomStatus*croom; +extern RoomStatus *croom; extern int our_eip; extern int in_new_room; -extern RoomObject*objs; -extern ViewStruct*views; +extern RoomObject *objs; +extern ViewStruct *views; extern CharacterCache *charcache; extern ObjectCache objcache[MAX_ROOM_OBJECTS]; extern int displayed_room; extern CharacterExtras *charextra; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern int eip_guinum; extern int is_complete_overlay; -extern int cur_mode,cur_cursor; -extern int mouse_frame,mouse_delay; -extern int lastmx,lastmy; +extern int cur_mode, cur_cursor; +extern int mouse_frame, mouse_delay; +extern int lastmx, lastmy; extern IDriverDependantBitmap *mouseCursor; -extern int hotx,hoty; +extern int hotx, hoty; extern int bg_just_changed; color palette[256]; @@ -135,28 +135,27 @@ IDriverDependantBitmap *debugConsole = nullptr; // of the latest version of the sprite int actSpsCount = 0; Bitmap **actsps; -IDriverDependantBitmap* *actspsbmp; +IDriverDependantBitmap * *actspsbmp; // temporary cache of walk-behind for this actsps image Bitmap **actspswb; -IDriverDependantBitmap* *actspswbbmp; -CachedActSpsData* actspswbcache; +IDriverDependantBitmap * *actspswbbmp; +CachedActSpsData *actspswbcache; bool current_background_is_dirty = false; // Room background sprite -IDriverDependantBitmap* roomBackgroundBmp = nullptr; +IDriverDependantBitmap *roomBackgroundBmp = nullptr; // Buffer and info flags for viewport/camera pairs rendering in software mode -struct RoomCameraDrawData -{ - // Intermediate bitmap for the software drawing method. - // We use this bitmap in case room camera has scaling enabled, we draw dirty room rects on it, - // and then pass to software renderer which draws sprite on top and then either blits or stretch-blits - // to the virtual screen. - // For more details see comment in ALSoftwareGraphicsDriver::RenderToBackBuffer(). - PBitmap Buffer; // this is the actual bitmap - PBitmap Frame; // this is either same bitmap reference or sub-bitmap of virtual screen - bool IsOffscreen; // whether room viewport was offscreen (cannot use sub-bitmap) - bool IsOverlap; // whether room viewport overlaps any others (marking dirty rects is complicated) +struct RoomCameraDrawData { + // Intermediate bitmap for the software drawing method. + // We use this bitmap in case room camera has scaling enabled, we draw dirty room rects on it, + // and then pass to software renderer which draws sprite on top and then either blits or stretch-blits + // to the virtual screen. + // For more details see comment in ALSoftwareGraphicsDriver::RenderToBackBuffer(). + PBitmap Buffer; // this is the actual bitmap + PBitmap Frame; // this is either same bitmap reference or sub-bitmap of virtual screen + bool IsOffscreen; // whether room viewport was offscreen (cannot use sub-bitmap) + bool IsOverlap; // whether room viewport overlaps any others (marking dirty rects is complicated) }; std::vector CameraDrawData; @@ -177,16 +176,15 @@ Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; SpriteListEntry::SpriteListEntry() - : bmp(nullptr) - , pic(nullptr) - , baseline(0), x(0), y(0) - , transparent(0) - , takesPriorityIfEqual(false), hasAlphaChannel(false) -{ + : bmp(nullptr) + , pic(nullptr) + , baseline(0), x(0), y(0) + , transparent(0) + , takesPriorityIfEqual(false), hasAlphaChannel(false) { } void setpal() { - set_palette_range(palette, 0, 255, 0); + set_palette_range(palette, 0, 255, 0); } int _places_r = 3, _places_g = 2, _places_b = 3; @@ -194,52 +192,50 @@ int _places_r = 3, _places_g = 2, _places_b = 3; // convert RGB to BGR for strange graphics cards Bitmap *convert_16_to_16bgr(Bitmap *tempbl) { - int x,y; - unsigned short c,r,ds,b; + int x, y; + unsigned short c, r, ds, b; - for (y=0; y < tempbl->GetHeight(); y++) { - unsigned short*p16 = (unsigned short *)tempbl->GetScanLine(y); + for (y = 0; y < tempbl->GetHeight(); y++) { + unsigned short *p16 = (unsigned short *)tempbl->GetScanLine(y); - for (x=0; x < tempbl->GetWidth(); x++) { - c = p16[x]; - if (c != MASK_COLOR_16) { - b = _rgb_scale_5[c & 0x1F]; - ds = _rgb_scale_6[(c >> 5) & 0x3F]; - r = _rgb_scale_5[(c >> 11) & 0x1F]; - // allegro assumes 5-6-5 for 16-bit - p16[x] = (((r >> _places_r) << _rgb_r_shift_16) | - ((ds >> _places_g) << _rgb_g_shift_16) | - ((b >> _places_b) << _rgb_b_shift_16)); + for (x = 0; x < tempbl->GetWidth(); x++) { + c = p16[x]; + if (c != MASK_COLOR_16) { + b = _rgb_scale_5[c & 0x1F]; + ds = _rgb_scale_6[(c >> 5) & 0x3F]; + r = _rgb_scale_5[(c >> 11) & 0x1F]; + // allegro assumes 5-6-5 for 16-bit + p16[x] = (((r >> _places_r) << _rgb_r_shift_16) | + ((ds >> _places_g) << _rgb_g_shift_16) | + ((b >> _places_b) << _rgb_b_shift_16)); - } - } - } + } + } + } - return tempbl; + return tempbl; } // PSP: convert 32 bit RGB to BGR. Bitmap *convert_32_to_32bgr(Bitmap *tempbl) { - int i = 0; - int j = 0; - unsigned char* current; - while (i < tempbl->GetHeight()) - { - current = tempbl->GetScanLineForWriting(i); - while (j < tempbl->GetWidth()) - { - current[0] ^= current[2]; - current[2] ^= current[0]; - current[0] ^= current[2]; - current += 4; - j++; - } - i++; - j = 0; - } - - return tempbl; + int i = 0; + int j = 0; + unsigned char *current; + while (i < tempbl->GetHeight()) { + current = tempbl->GetScanLineForWriting(i); + while (j < tempbl->GetWidth()) { + current[0] ^= current[2]; + current[2] ^= current[0]; + current[0] ^= current[2]; + current += 4; + j++; + } + i++; + j = 0; + } + + return tempbl; } // NOTE: Some of these conversions are required even when using @@ -255,895 +251,782 @@ Bitmap *convert_32_to_32bgr(Bitmap *tempbl) { // TODO: make gfxDriver->GetCompatibleBitmapFormat describe all necessary // conversions, so that we did not have to guess. // -Bitmap *AdjustBitmapForUseWithDisplayMode(Bitmap* bitmap, bool has_alpha) -{ - const int bmp_col_depth = bitmap->GetColorDepth(); - const int sys_col_depth = System_GetColorDepth(); - const int game_col_depth = game.GetColorDepth(); - Bitmap *new_bitmap = bitmap; - - // - // The only special case when bitmap needs to be prepared for graphics driver - // - // In 32-bit display mode, 32-bit bitmaps may require component conversion - // to match graphics driver expectation about pixel format. - // TODO: make GetCompatibleBitmapFormat tell this somehow +Bitmap *AdjustBitmapForUseWithDisplayMode(Bitmap *bitmap, bool has_alpha) { + const int bmp_col_depth = bitmap->GetColorDepth(); + const int sys_col_depth = System_GetColorDepth(); + const int game_col_depth = game.GetColorDepth(); + Bitmap *new_bitmap = bitmap; + + // + // The only special case when bitmap needs to be prepared for graphics driver + // + // In 32-bit display mode, 32-bit bitmaps may require component conversion + // to match graphics driver expectation about pixel format. + // TODO: make GetCompatibleBitmapFormat tell this somehow #if defined (AGS_INVERTED_COLOR_ORDER) - if (sys_col_depth > 16 && bmp_col_depth == 32) - { - // Convert RGB to BGR. - new_bitmap = convert_32_to_32bgr(bitmap); - } + if (sys_col_depth > 16 && bmp_col_depth == 32) { + // Convert RGB to BGR. + new_bitmap = convert_32_to_32bgr(bitmap); + } #endif - // - // The rest is about bringing bitmaps to the native game's format - // (has no dependency on display mode). - // - // In 32-bit game 32-bit bitmaps should have transparent pixels marked - // (this adjustment is probably needed for DrawingSurface ops) - if (game_col_depth == 32 && bmp_col_depth == 32) - { - if (has_alpha) - set_rgb_mask_using_alpha_channel(new_bitmap); - } - // In 32-bit game hicolor bitmaps must be converted to the true color - else if (game_col_depth == 32 && (bmp_col_depth > 8 && bmp_col_depth <= 16)) - { - new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); - } - // In non-32-bit game truecolor bitmaps must be downgraded - else if (game_col_depth <= 16 && bmp_col_depth > 16) - { - if (has_alpha) // if has valid alpha channel, convert it to regular transparency mask - new_bitmap = remove_alpha_channel(bitmap); - else // else simply convert bitmap - new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); - } - // Special case when we must convert 16-bit RGB to BGR - else if (convert_16bit_bgr == 1 && bmp_col_depth == 16) - { - new_bitmap = convert_16_to_16bgr(bitmap); - } - return new_bitmap; -} - -Bitmap *ReplaceBitmapWithSupportedFormat(Bitmap *bitmap) -{ - Bitmap *new_bitmap = GfxUtil::ConvertBitmap(bitmap, gfxDriver->GetCompatibleBitmapFormat(bitmap->GetColorDepth())); - if (new_bitmap != bitmap) - delete bitmap; - return new_bitmap; -} - -Bitmap *PrepareSpriteForUse(Bitmap* bitmap, bool has_alpha) -{ - bool must_switch_palette = bitmap->GetColorDepth() == 8 && game.GetColorDepth() > 8; - if (must_switch_palette) - select_palette(palette); - - Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap, has_alpha); - if (new_bitmap != bitmap) - delete bitmap; - new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); - - if (must_switch_palette) - unselect_palette(); - return new_bitmap; -} - -PBitmap PrepareSpriteForUse(PBitmap bitmap, bool has_alpha) -{ - bool must_switch_palette = bitmap->GetColorDepth() == 8 && System_GetColorDepth() > 8; - if (must_switch_palette) - select_palette(palette); - - Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap.get(), has_alpha); - new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); - - if (must_switch_palette) - unselect_palette(); - return new_bitmap == bitmap.get() ? bitmap : PBitmap(new_bitmap); // if bitmap is same, don't create new smart ptr! -} - -Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res) -{ - Bitmap *dst = new Bitmap(width, height, game.GetColorDepth()); - GraphicResolution want_fmt; - // If the size and color depth are supported we may copy right into our bitmap - if (gfxDriver->GetCopyOfScreenIntoBitmap(dst, at_native_res, &want_fmt)) - return dst; - // Otherwise we might need to copy between few bitmaps... - Bitmap *buf_screenfmt = new Bitmap(want_fmt.Width, want_fmt.Height, want_fmt.ColorDepth); - gfxDriver->GetCopyOfScreenIntoBitmap(buf_screenfmt, at_native_res); - // If at least size matches then we may blit - if (dst->GetSize() == buf_screenfmt->GetSize()) - { - dst->Blit(buf_screenfmt); - } - // Otherwise we need to go through another bitmap of the matching format - else - { - Bitmap *buf_dstfmt = new Bitmap(buf_screenfmt->GetWidth(), buf_screenfmt->GetHeight(), dst->GetColorDepth()); - buf_dstfmt->Blit(buf_screenfmt); - dst->StretchBlt(buf_dstfmt, RectWH(dst->GetSize())); - delete buf_dstfmt; - } - delete buf_screenfmt; - return dst; + // + // The rest is about bringing bitmaps to the native game's format + // (has no dependency on display mode). + // + // In 32-bit game 32-bit bitmaps should have transparent pixels marked + // (this adjustment is probably needed for DrawingSurface ops) + if (game_col_depth == 32 && bmp_col_depth == 32) { + if (has_alpha) + set_rgb_mask_using_alpha_channel(new_bitmap); + } + // In 32-bit game hicolor bitmaps must be converted to the true color + else if (game_col_depth == 32 && (bmp_col_depth > 8 && bmp_col_depth <= 16)) { + new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); + } + // In non-32-bit game truecolor bitmaps must be downgraded + else if (game_col_depth <= 16 && bmp_col_depth > 16) { + if (has_alpha) // if has valid alpha channel, convert it to regular transparency mask + new_bitmap = remove_alpha_channel(bitmap); + else // else simply convert bitmap + new_bitmap = BitmapHelper::CreateBitmapCopy(bitmap, game_col_depth); + } + // Special case when we must convert 16-bit RGB to BGR + else if (convert_16bit_bgr == 1 && bmp_col_depth == 16) { + new_bitmap = convert_16_to_16bgr(bitmap); + } + return new_bitmap; +} + +Bitmap *ReplaceBitmapWithSupportedFormat(Bitmap *bitmap) { + Bitmap *new_bitmap = GfxUtil::ConvertBitmap(bitmap, gfxDriver->GetCompatibleBitmapFormat(bitmap->GetColorDepth())); + if (new_bitmap != bitmap) + delete bitmap; + return new_bitmap; +} + +Bitmap *PrepareSpriteForUse(Bitmap *bitmap, bool has_alpha) { + bool must_switch_palette = bitmap->GetColorDepth() == 8 && game.GetColorDepth() > 8; + if (must_switch_palette) + select_palette(palette); + + Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap, has_alpha); + if (new_bitmap != bitmap) + delete bitmap; + new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); + + if (must_switch_palette) + unselect_palette(); + return new_bitmap; +} + +PBitmap PrepareSpriteForUse(PBitmap bitmap, bool has_alpha) { + bool must_switch_palette = bitmap->GetColorDepth() == 8 && System_GetColorDepth() > 8; + if (must_switch_palette) + select_palette(palette); + + Bitmap *new_bitmap = AdjustBitmapForUseWithDisplayMode(bitmap.get(), has_alpha); + new_bitmap = ReplaceBitmapWithSupportedFormat(new_bitmap); + + if (must_switch_palette) + unselect_palette(); + return new_bitmap == bitmap.get() ? bitmap : PBitmap(new_bitmap); // if bitmap is same, don't create new smart ptr! +} + +Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res) { + Bitmap *dst = new Bitmap(width, height, game.GetColorDepth()); + GraphicResolution want_fmt; + // If the size and color depth are supported we may copy right into our bitmap + if (gfxDriver->GetCopyOfScreenIntoBitmap(dst, at_native_res, &want_fmt)) + return dst; + // Otherwise we might need to copy between few bitmaps... + Bitmap *buf_screenfmt = new Bitmap(want_fmt.Width, want_fmt.Height, want_fmt.ColorDepth); + gfxDriver->GetCopyOfScreenIntoBitmap(buf_screenfmt, at_native_res); + // If at least size matches then we may blit + if (dst->GetSize() == buf_screenfmt->GetSize()) { + dst->Blit(buf_screenfmt); + } + // Otherwise we need to go through another bitmap of the matching format + else { + Bitmap *buf_dstfmt = new Bitmap(buf_screenfmt->GetWidth(), buf_screenfmt->GetHeight(), dst->GetColorDepth()); + buf_dstfmt->Blit(buf_screenfmt); + dst->StretchBlt(buf_dstfmt, RectWH(dst->GetSize())); + delete buf_dstfmt; + } + delete buf_screenfmt; + return dst; } // Begin resolution system functions -// Multiplies up the number of pixels depending on the current +// Multiplies up the number of pixels depending on the current // resolution, to give a relatively fixed size at any game res -AGS_INLINE int get_fixed_pixel_size(int pixels) -{ - return pixels * game.GetRelativeUIMult(); +AGS_INLINE int get_fixed_pixel_size(int pixels) { + return pixels * game.GetRelativeUIMult(); } -AGS_INLINE int data_to_game_coord(int coord) -{ - return coord * game.GetDataUpscaleMult(); +AGS_INLINE int data_to_game_coord(int coord) { + return coord * game.GetDataUpscaleMult(); } -AGS_INLINE void data_to_game_coords(int *x, int *y) -{ - const int mul = game.GetDataUpscaleMult(); - x[0] *= mul; - y[0] *= mul; +AGS_INLINE void data_to_game_coords(int *x, int *y) { + const int mul = game.GetDataUpscaleMult(); + x[0] *= mul; + y[0] *= mul; } -AGS_INLINE void data_to_game_round_up(int *x, int *y) -{ - const int mul = game.GetDataUpscaleMult(); - x[0] = x[0] * mul + (mul - 1); - y[0] = y[0] * mul + (mul - 1); +AGS_INLINE void data_to_game_round_up(int *x, int *y) { + const int mul = game.GetDataUpscaleMult(); + x[0] = x[0] * mul + (mul - 1); + y[0] = y[0] * mul + (mul - 1); } -AGS_INLINE int game_to_data_coord(int coord) -{ - return coord / game.GetDataUpscaleMult(); +AGS_INLINE int game_to_data_coord(int coord) { + return coord / game.GetDataUpscaleMult(); } -AGS_INLINE void game_to_data_coords(int &x, int &y) -{ - const int mul = game.GetDataUpscaleMult(); - x /= mul; - y /= mul; +AGS_INLINE void game_to_data_coords(int &x, int &y) { + const int mul = game.GetDataUpscaleMult(); + x /= mul; + y /= mul; } -AGS_INLINE int game_to_data_round_up(int coord) -{ - const int mul = game.GetDataUpscaleMult(); - return (coord / mul) + (mul - 1); +AGS_INLINE int game_to_data_round_up(int coord) { + const int mul = game.GetDataUpscaleMult(); + return (coord / mul) + (mul - 1); } -AGS_INLINE void ctx_data_to_game_coord(int &x, int &y, bool hires_ctx) -{ - if (hires_ctx && !game.IsLegacyHiRes()) - { - x /= HIRES_COORD_MULTIPLIER; - y /= HIRES_COORD_MULTIPLIER; - } - else if (!hires_ctx && game.IsLegacyHiRes()) - { - x *= HIRES_COORD_MULTIPLIER; - y *= HIRES_COORD_MULTIPLIER; - } +AGS_INLINE void ctx_data_to_game_coord(int &x, int &y, bool hires_ctx) { + if (hires_ctx && !game.IsLegacyHiRes()) { + x /= HIRES_COORD_MULTIPLIER; + y /= HIRES_COORD_MULTIPLIER; + } else if (!hires_ctx && game.IsLegacyHiRes()) { + x *= HIRES_COORD_MULTIPLIER; + y *= HIRES_COORD_MULTIPLIER; + } } -AGS_INLINE void ctx_data_to_game_size(int &w, int &h, bool hires_ctx) -{ - if (hires_ctx && !game.IsLegacyHiRes()) - { - w = Math::Max(1, (w / HIRES_COORD_MULTIPLIER)); - h = Math::Max(1, (h / HIRES_COORD_MULTIPLIER)); - } - else if (!hires_ctx && game.IsLegacyHiRes()) - { - w *= HIRES_COORD_MULTIPLIER; - h *= HIRES_COORD_MULTIPLIER; - } +AGS_INLINE void ctx_data_to_game_size(int &w, int &h, bool hires_ctx) { + if (hires_ctx && !game.IsLegacyHiRes()) { + w = Math::Max(1, (w / HIRES_COORD_MULTIPLIER)); + h = Math::Max(1, (h / HIRES_COORD_MULTIPLIER)); + } else if (!hires_ctx && game.IsLegacyHiRes()) { + w *= HIRES_COORD_MULTIPLIER; + h *= HIRES_COORD_MULTIPLIER; + } } -AGS_INLINE int ctx_data_to_game_size(int size, bool hires_ctx) -{ - if (hires_ctx && !game.IsLegacyHiRes()) - return Math::Max(1, (size / HIRES_COORD_MULTIPLIER)); - if (!hires_ctx && game.IsLegacyHiRes()) - return size * HIRES_COORD_MULTIPLIER; - return size; +AGS_INLINE int ctx_data_to_game_size(int size, bool hires_ctx) { + if (hires_ctx && !game.IsLegacyHiRes()) + return Math::Max(1, (size / HIRES_COORD_MULTIPLIER)); + if (!hires_ctx && game.IsLegacyHiRes()) + return size * HIRES_COORD_MULTIPLIER; + return size; } -AGS_INLINE int game_to_ctx_data_size(int size, bool hires_ctx) -{ - if (hires_ctx && !game.IsLegacyHiRes()) - return size * HIRES_COORD_MULTIPLIER; - else if (!hires_ctx && game.IsLegacyHiRes()) - return Math::Max(1, (size / HIRES_COORD_MULTIPLIER)); - return size; +AGS_INLINE int game_to_ctx_data_size(int size, bool hires_ctx) { + if (hires_ctx && !game.IsLegacyHiRes()) + return size * HIRES_COORD_MULTIPLIER; + else if (!hires_ctx && game.IsLegacyHiRes()) + return Math::Max(1, (size / HIRES_COORD_MULTIPLIER)); + return size; } -AGS_INLINE void defgame_to_finalgame_coords(int &x, int &y) -{ // Note we support only upscale now - x *= game.GetScreenUpscaleMult(); - y *= game.GetScreenUpscaleMult(); +AGS_INLINE void defgame_to_finalgame_coords(int &x, int &y) { + // Note we support only upscale now + x *= game.GetScreenUpscaleMult(); + y *= game.GetScreenUpscaleMult(); } // End resolution system functions // Create blank (black) images used to repaint borders around game frame -void create_blank_image(int coldepth) -{ - // this is the first time that we try to use the graphics driver, - // so it's the most likey place for a crash - try - { - Bitmap *blank = BitmapHelper::CreateBitmap(16, 16, coldepth); - blank = ReplaceBitmapWithSupportedFormat(blank); - blank->Clear(); - blankImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); - blankSidebarImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); - delete blank; - } - catch (Ali3DException gfxException) - { - quit((char*)gfxException._message); - } -} - -void destroy_blank_image() -{ - if (blankImage) - gfxDriver->DestroyDDB(blankImage); - if (blankSidebarImage) - gfxDriver->DestroyDDB(blankSidebarImage); - blankImage = nullptr; - blankSidebarImage = nullptr; -} - -int MakeColor(int color_index) -{ - color_t real_color = 0; - __my_setcolor(&real_color, color_index, game.GetColorDepth()); - return real_color; -} - -void init_draw_method() -{ - if (gfxDriver->HasAcceleratedTransform()) - { - walkBehindMethod = DrawAsSeparateSprite; - create_blank_image(game.GetColorDepth()); - } - else - { - walkBehindMethod = DrawOverCharSprite; - } - - on_mainviewport_changed(); - init_room_drawdata(); - if (gfxDriver->UsesMemoryBackBuffer()) - gfxDriver->GetMemoryBackBuffer()->Clear(); -} - -void dispose_draw_method() -{ - dispose_room_drawdata(); - dispose_invalid_regions(false); - destroy_blank_image(); -} - -void dispose_room_drawdata() -{ - CameraDrawData.clear(); - dispose_invalid_regions(true); -} - -void on_mainviewport_changed() -{ - if (!gfxDriver->RequiresFullRedrawEachFrame()) - { - init_invalid_regions(-1, play.GetMainViewport().GetSize(), RectWH(play.GetMainViewport().GetSize())); - if (game.GetGameRes().ExceedsByAny(play.GetMainViewport().GetSize())) - clear_letterbox_borders(); - } +void create_blank_image(int coldepth) { + // this is the first time that we try to use the graphics driver, + // so it's the most likey place for a crash + try { + Bitmap *blank = BitmapHelper::CreateBitmap(16, 16, coldepth); + blank = ReplaceBitmapWithSupportedFormat(blank); + blank->Clear(); + blankImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); + blankSidebarImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); + delete blank; + } catch (Ali3DException gfxException) { + quit((char *)gfxException._message); + } +} + +void destroy_blank_image() { + if (blankImage) + gfxDriver->DestroyDDB(blankImage); + if (blankSidebarImage) + gfxDriver->DestroyDDB(blankSidebarImage); + blankImage = nullptr; + blankSidebarImage = nullptr; +} + +int MakeColor(int color_index) { + color_t real_color = 0; + __my_setcolor(&real_color, color_index, game.GetColorDepth()); + return real_color; +} + +void init_draw_method() { + if (gfxDriver->HasAcceleratedTransform()) { + walkBehindMethod = DrawAsSeparateSprite; + create_blank_image(game.GetColorDepth()); + } else { + walkBehindMethod = DrawOverCharSprite; + } + + on_mainviewport_changed(); + init_room_drawdata(); + if (gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->GetMemoryBackBuffer()->Clear(); +} + +void dispose_draw_method() { + dispose_room_drawdata(); + dispose_invalid_regions(false); + destroy_blank_image(); +} + +void dispose_room_drawdata() { + CameraDrawData.clear(); + dispose_invalid_regions(true); +} + +void on_mainviewport_changed() { + if (!gfxDriver->RequiresFullRedrawEachFrame()) { + init_invalid_regions(-1, play.GetMainViewport().GetSize(), RectWH(play.GetMainViewport().GetSize())); + if (game.GetGameRes().ExceedsByAny(play.GetMainViewport().GetSize())) + clear_letterbox_borders(); + } } // Allocates a bitmap for rendering camera/viewport pair (software render mode) -void prepare_roomview_frame(Viewport *view) -{ - const int view_index = view->GetID(); - const Size view_sz = view->GetRect().GetSize(); - const Size cam_sz = view->GetCamera()->GetRect().GetSize(); - RoomCameraDrawData &draw_dat = CameraDrawData[view_index]; - // We use intermediate bitmap to render camera/viewport pair in software mode under these conditions: - // * camera size and viewport size are different (this may be suboptimal to paint dirty rects stretched, - // and also Allegro backend cannot stretch background of different colour depth). - // * viewport is located outside of the virtual screen (even if partially): subbitmaps cannot contain - // regions outside of master bitmap, and we must not clamp surface size to virtual screen because - // plugins may want to also use viewport bitmap, therefore it should retain full size. - if (cam_sz == view_sz && !draw_dat.IsOffscreen) - { // note we keep the buffer allocated in case it will become useful later - draw_dat.Frame.reset(); - } - else - { - PBitmap &camera_frame = draw_dat.Frame; - PBitmap &camera_buffer = draw_dat.Buffer; - if (!camera_buffer || camera_buffer->GetWidth() < cam_sz.Width || camera_buffer->GetHeight() < cam_sz.Height) - { - // Allocate new buffer bitmap with an extra size in case they will want to zoom out - int room_width = data_to_game_coord(thisroom.Width); - int room_height = data_to_game_coord(thisroom.Height); - Size alloc_sz = Size::Clamp(cam_sz * 2, Size(1, 1), Size(room_width, room_height)); - camera_buffer.reset(new Bitmap(alloc_sz.Width, alloc_sz.Height, gfxDriver->GetMemoryBackBuffer()->GetColorDepth())); - } - - if (!camera_frame || camera_frame->GetSize() != cam_sz) - { - camera_frame.reset(BitmapHelper::CreateSubBitmap(camera_buffer.get(), RectWH(cam_sz))); - } - } +void prepare_roomview_frame(Viewport *view) { + const int view_index = view->GetID(); + const Size view_sz = view->GetRect().GetSize(); + const Size cam_sz = view->GetCamera()->GetRect().GetSize(); + RoomCameraDrawData &draw_dat = CameraDrawData[view_index]; + // We use intermediate bitmap to render camera/viewport pair in software mode under these conditions: + // * camera size and viewport size are different (this may be suboptimal to paint dirty rects stretched, + // and also Allegro backend cannot stretch background of different colour depth). + // * viewport is located outside of the virtual screen (even if partially): subbitmaps cannot contain + // regions outside of master bitmap, and we must not clamp surface size to virtual screen because + // plugins may want to also use viewport bitmap, therefore it should retain full size. + if (cam_sz == view_sz && !draw_dat.IsOffscreen) { + // note we keep the buffer allocated in case it will become useful later + draw_dat.Frame.reset(); + } else { + PBitmap &camera_frame = draw_dat.Frame; + PBitmap &camera_buffer = draw_dat.Buffer; + if (!camera_buffer || camera_buffer->GetWidth() < cam_sz.Width || camera_buffer->GetHeight() < cam_sz.Height) { + // Allocate new buffer bitmap with an extra size in case they will want to zoom out + int room_width = data_to_game_coord(thisroom.Width); + int room_height = data_to_game_coord(thisroom.Height); + Size alloc_sz = Size::Clamp(cam_sz * 2, Size(1, 1), Size(room_width, room_height)); + camera_buffer.reset(new Bitmap(alloc_sz.Width, alloc_sz.Height, gfxDriver->GetMemoryBackBuffer()->GetColorDepth())); + } + + if (!camera_frame || camera_frame->GetSize() != cam_sz) { + camera_frame.reset(BitmapHelper::CreateSubBitmap(camera_buffer.get(), RectWH(cam_sz))); + } + } } // Syncs room viewport and camera in case either size has changed -void sync_roomview(Viewport *view) -{ - if (view->GetCamera() == nullptr) - return; - init_invalid_regions(view->GetID(), view->GetCamera()->GetRect().GetSize(), play.GetRoomViewportAbs(view->GetID())); - prepare_roomview_frame(view); -} - -void init_room_drawdata() -{ - if (gfxDriver->RequiresFullRedrawEachFrame()) - return; - // Make sure all frame buffers are created for software drawing - int view_count = play.GetRoomViewportCount(); - CameraDrawData.resize(view_count); - for (int i = 0; i < play.GetRoomViewportCount(); ++i) - sync_roomview(play.GetRoomViewport(i).get()); -} - -void on_roomviewport_created(int index) -{ - if (!gfxDriver || gfxDriver->RequiresFullRedrawEachFrame()) - return; - if ((size_t)index < CameraDrawData.size()) - return; - CameraDrawData.resize(index + 1); -} - -void on_roomviewport_deleted(int index) -{ - if (gfxDriver->RequiresFullRedrawEachFrame()) - return; - CameraDrawData.erase(CameraDrawData.begin() + index); - delete_invalid_regions(index); -} - -void on_roomviewport_changed(Viewport *view) -{ - if (gfxDriver->RequiresFullRedrawEachFrame()) - return; - if (!view->IsVisible() || view->GetCamera() == nullptr) - return; - const bool off = !IsRectInsideRect(RectWH(gfxDriver->GetMemoryBackBuffer()->GetSize()), view->GetRect()); - const bool off_changed = off != CameraDrawData[view->GetID()].IsOffscreen; - CameraDrawData[view->GetID()].IsOffscreen = off; - if (view->HasChangedSize()) - sync_roomview(view); - else if (off_changed) - prepare_roomview_frame(view); - // TODO: don't have to do this all the time, perhaps do "dirty rect" method - // and only clear previous viewport location? - invalidate_screen(); - gfxDriver->GetMemoryBackBuffer()->Clear(); -} - -void detect_roomviewport_overlaps(size_t z_index) -{ - if (gfxDriver->RequiresFullRedrawEachFrame()) - return; - // Find out if we overlap or are overlapped by anything; - const auto &viewports = play.GetRoomViewportsZOrdered(); - for (; z_index < viewports.size(); ++z_index) - { - auto this_view = viewports[z_index]; - const int this_id = this_view->GetID(); - bool is_overlap = false; - if (!this_view->IsVisible()) continue; - for (size_t z_index2 = 0; z_index2 < z_index; ++z_index) - { - if (!viewports[z_index2]->IsVisible()) continue; - if (AreRectsIntersecting(this_view->GetRect(), viewports[z_index2]->GetRect())) - { - is_overlap = true; - break; - } - } - if (CameraDrawData[this_id].IsOverlap != is_overlap) - { - CameraDrawData[this_id].IsOverlap = is_overlap; - prepare_roomview_frame(this_view.get()); - } - } -} - -void on_roomcamera_changed(Camera *cam) -{ - if (gfxDriver->RequiresFullRedrawEachFrame()) - return; - if (cam->HasChangedSize()) - { - auto viewrefs = cam->GetLinkedViewports(); - for (auto vr : viewrefs) - { - PViewport vp = vr.lock(); - if (vp) - sync_roomview(vp.get()); - } - } - // TODO: only invalidate what this particular camera sees - invalidate_screen(); -} - -void mark_screen_dirty() -{ - screen_is_dirty = true; -} - -bool is_screen_dirty() -{ - return screen_is_dirty; -} - -void invalidate_screen() -{ - invalidate_all_rects(); -} - -void invalidate_camera_frame(int index) -{ - invalidate_all_camera_rects(index); -} - -void invalidate_rect(int x1, int y1, int x2, int y2, bool in_room) -{ - //if (!in_room) - invalidate_rect_ds(x1, y1, x2, y2, in_room); -} - -void invalidate_sprite(int x1, int y1, IDriverDependantBitmap *pic, bool in_room) -{ - //if (!in_room) - invalidate_rect_ds(x1, y1, x1 + pic->GetWidth(), y1 + pic->GetHeight(), in_room); -} - -void mark_current_background_dirty() -{ - current_background_is_dirty = true; -} - - -void draw_and_invalidate_text(Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text) -{ - wouttext_outline(ds, x1, y1, font, text_color, (char*)text); - invalidate_rect(x1, y1, x1 + wgettextwidth_compensate(text, font), y1 + getfontheight_outlined(font) + get_fixed_pixel_size(1), false); +void sync_roomview(Viewport *view) { + if (view->GetCamera() == nullptr) + return; + init_invalid_regions(view->GetID(), view->GetCamera()->GetRect().GetSize(), play.GetRoomViewportAbs(view->GetID())); + prepare_roomview_frame(view); +} + +void init_room_drawdata() { + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + // Make sure all frame buffers are created for software drawing + int view_count = play.GetRoomViewportCount(); + CameraDrawData.resize(view_count); + for (int i = 0; i < play.GetRoomViewportCount(); ++i) + sync_roomview(play.GetRoomViewport(i).get()); +} + +void on_roomviewport_created(int index) { + if (!gfxDriver || gfxDriver->RequiresFullRedrawEachFrame()) + return; + if ((size_t)index < CameraDrawData.size()) + return; + CameraDrawData.resize(index + 1); +} + +void on_roomviewport_deleted(int index) { + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + CameraDrawData.erase(CameraDrawData.begin() + index); + delete_invalid_regions(index); +} + +void on_roomviewport_changed(Viewport *view) { + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + if (!view->IsVisible() || view->GetCamera() == nullptr) + return; + const bool off = !IsRectInsideRect(RectWH(gfxDriver->GetMemoryBackBuffer()->GetSize()), view->GetRect()); + const bool off_changed = off != CameraDrawData[view->GetID()].IsOffscreen; + CameraDrawData[view->GetID()].IsOffscreen = off; + if (view->HasChangedSize()) + sync_roomview(view); + else if (off_changed) + prepare_roomview_frame(view); + // TODO: don't have to do this all the time, perhaps do "dirty rect" method + // and only clear previous viewport location? + invalidate_screen(); + gfxDriver->GetMemoryBackBuffer()->Clear(); +} + +void detect_roomviewport_overlaps(size_t z_index) { + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + // Find out if we overlap or are overlapped by anything; + const auto &viewports = play.GetRoomViewportsZOrdered(); + for (; z_index < viewports.size(); ++z_index) { + auto this_view = viewports[z_index]; + const int this_id = this_view->GetID(); + bool is_overlap = false; + if (!this_view->IsVisible()) continue; + for (size_t z_index2 = 0; z_index2 < z_index; ++z_index) { + if (!viewports[z_index2]->IsVisible()) continue; + if (AreRectsIntersecting(this_view->GetRect(), viewports[z_index2]->GetRect())) { + is_overlap = true; + break; + } + } + if (CameraDrawData[this_id].IsOverlap != is_overlap) { + CameraDrawData[this_id].IsOverlap = is_overlap; + prepare_roomview_frame(this_view.get()); + } + } +} + +void on_roomcamera_changed(Camera *cam) { + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + if (cam->HasChangedSize()) { + auto viewrefs = cam->GetLinkedViewports(); + for (auto vr : viewrefs) { + PViewport vp = vr.lock(); + if (vp) + sync_roomview(vp.get()); + } + } + // TODO: only invalidate what this particular camera sees + invalidate_screen(); +} + +void mark_screen_dirty() { + screen_is_dirty = true; +} + +bool is_screen_dirty() { + return screen_is_dirty; +} + +void invalidate_screen() { + invalidate_all_rects(); +} + +void invalidate_camera_frame(int index) { + invalidate_all_camera_rects(index); +} + +void invalidate_rect(int x1, int y1, int x2, int y2, bool in_room) { + //if (!in_room) + invalidate_rect_ds(x1, y1, x2, y2, in_room); +} + +void invalidate_sprite(int x1, int y1, IDriverDependantBitmap *pic, bool in_room) { + //if (!in_room) + invalidate_rect_ds(x1, y1, x1 + pic->GetWidth(), y1 + pic->GetHeight(), in_room); +} + +void mark_current_background_dirty() { + current_background_is_dirty = true; +} + + +void draw_and_invalidate_text(Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text) { + wouttext_outline(ds, x1, y1, font, text_color, (char *)text); + invalidate_rect(x1, y1, x1 + wgettextwidth_compensate(text, font), y1 + getfontheight_outlined(font) + get_fixed_pixel_size(1), false); } // Renders black borders for the legacy boxed game mode, // where whole game screen changes size between large and small rooms -void render_black_borders() -{ - if (gfxDriver->UsesMemoryBackBuffer()) - return; - { - gfxDriver->BeginSpriteBatch(RectWH(game.GetGameRes()), SpriteTransform()); - const Rect &viewport = play.GetMainViewport(); - if (viewport.Top > 0) - { - // letterbox borders - blankImage->SetStretch(game.GetGameRes().Width, viewport.Top, false); - gfxDriver->DrawSprite(0, 0, blankImage); - gfxDriver->DrawSprite(0, viewport.Bottom + 1, blankImage); - } - if (viewport.Left > 0) - { - // sidebar borders for widescreen - blankSidebarImage->SetStretch(viewport.Left, viewport.GetHeight(), false); - gfxDriver->DrawSprite(0, 0, blankSidebarImage); - gfxDriver->DrawSprite(viewport.Right + 1, 0, blankSidebarImage); - } - } -} - - -void render_to_screen() -{ - // Stage: final plugin callback (still drawn on game screen - if (pl_any_want_hook(AGSE_FINALSCREENDRAW)) - { - gfxDriver->BeginSpriteBatch(play.GetMainViewport(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); - gfxDriver->DrawSprite(AGSE_FINALSCREENDRAW, 0, nullptr); - } - // Stage: engine overlay - construct_engine_overlay(); - - // only vsync in full screen mode, it makes things worse in a window - gfxDriver->EnableVsyncBeforeRender((scsystem.vsync > 0) && (!scsystem.windowed)); - - bool succeeded = false; - while (!succeeded) - { - try - { - // For software renderer, need to blacken upper part of the game frame when shaking screen moves image down - const Rect &viewport = play.GetMainViewport(); - if (play.shake_screen_yoff > 0 && !gfxDriver->RequiresFullRedrawEachFrame()) - gfxDriver->ClearRectangle(viewport.Left, viewport.Top, viewport.GetWidth() - 1, play.shake_screen_yoff, nullptr); - gfxDriver->Render(0, play.shake_screen_yoff, (GlobalFlipType)play.screen_flipped); +void render_black_borders() { + if (gfxDriver->UsesMemoryBackBuffer()) + return; + { + gfxDriver->BeginSpriteBatch(RectWH(game.GetGameRes()), SpriteTransform()); + const Rect &viewport = play.GetMainViewport(); + if (viewport.Top > 0) { + // letterbox borders + blankImage->SetStretch(game.GetGameRes().Width, viewport.Top, false); + gfxDriver->DrawSprite(0, 0, blankImage); + gfxDriver->DrawSprite(0, viewport.Bottom + 1, blankImage); + } + if (viewport.Left > 0) { + // sidebar borders for widescreen + blankSidebarImage->SetStretch(viewport.Left, viewport.GetHeight(), false); + gfxDriver->DrawSprite(0, 0, blankSidebarImage); + gfxDriver->DrawSprite(viewport.Right + 1, 0, blankSidebarImage); + } + } +} + + +void render_to_screen() { + // Stage: final plugin callback (still drawn on game screen + if (pl_any_want_hook(AGSE_FINALSCREENDRAW)) { + gfxDriver->BeginSpriteBatch(play.GetMainViewport(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + gfxDriver->DrawSprite(AGSE_FINALSCREENDRAW, 0, nullptr); + } + // Stage: engine overlay + construct_engine_overlay(); + + // only vsync in full screen mode, it makes things worse in a window + gfxDriver->EnableVsyncBeforeRender((scsystem.vsync > 0) && (!scsystem.windowed)); + + bool succeeded = false; + while (!succeeded) { + try { + // For software renderer, need to blacken upper part of the game frame when shaking screen moves image down + const Rect &viewport = play.GetMainViewport(); + if (play.shake_screen_yoff > 0 && !gfxDriver->RequiresFullRedrawEachFrame()) + gfxDriver->ClearRectangle(viewport.Left, viewport.Top, viewport.GetWidth() - 1, play.shake_screen_yoff, nullptr); + gfxDriver->Render(0, play.shake_screen_yoff, (GlobalFlipType)play.screen_flipped); #if AGS_PLATFORM_OS_ANDROID - if (game.color_depth == 1) - android_render(); + if (game.color_depth == 1) + android_render(); #elif AGS_PLATFORM_OS_IOS - if (game.color_depth == 1) - ios_render(); + if (game.color_depth == 1) + ios_render(); #endif - succeeded = true; - } - catch (Ali3DFullscreenLostException) - { - platform->Delay(500); - } - } + succeeded = true; + } catch (Ali3DFullscreenLostException) { + platform->Delay(500); + } + } } // Blanks out borders around main viewport in case it became smaller (e.g. after loading another room) -void clear_letterbox_borders() -{ - const Rect &viewport = play.GetMainViewport(); - gfxDriver->ClearRectangle(0, 0, game.GetGameRes().Width - 1, viewport.Top - 1, nullptr); - gfxDriver->ClearRectangle(0, viewport.Bottom + 1, game.GetGameRes().Width - 1, game.GetGameRes().Height - 1, nullptr); +void clear_letterbox_borders() { + const Rect &viewport = play.GetMainViewport(); + gfxDriver->ClearRectangle(0, 0, game.GetGameRes().Width - 1, viewport.Top - 1, nullptr); + gfxDriver->ClearRectangle(0, viewport.Bottom + 1, game.GetGameRes().Width - 1, game.GetGameRes().Height - 1, nullptr); } -void draw_game_screen_callback() -{ - construct_game_scene(true); - construct_game_screen_overlay(false); +void draw_game_screen_callback() { + construct_game_scene(true); + construct_game_screen_overlay(false); } -void putpixel_compensate (Bitmap *ds, int xx,int yy, int col) { - if ((ds->GetColorDepth() == 32) && (col != 0)) { - // ensure the alpha channel is preserved if it has one - int alphaval = geta32(ds->GetPixel(xx, yy)); - col = makeacol32(getr32(col), getg32(col), getb32(col), alphaval); - } - ds->FillRect(Rect(xx, yy, xx + get_fixed_pixel_size(1) - 1, yy + get_fixed_pixel_size(1) - 1), col); +void putpixel_compensate(Bitmap *ds, int xx, int yy, int col) { + if ((ds->GetColorDepth() == 32) && (col != 0)) { + // ensure the alpha channel is preserved if it has one + int alphaval = geta32(ds->GetPixel(xx, yy)); + col = makeacol32(getr32(col), getg32(col), getb32(col), alphaval); + } + ds->FillRect(Rect(xx, yy, xx + get_fixed_pixel_size(1) - 1, yy + get_fixed_pixel_size(1) - 1), col); } void draw_sprite_support_alpha(Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Bitmap *image, bool src_has_alpha, - BlendMode blend_mode, int alpha) -{ - if (alpha <= 0) - return; - - if (game.options[OPT_SPRITEALPHA] == kSpriteAlphaRender_Proper) - { - GfxUtil::DrawSpriteBlend(ds, Point(xpos, ypos), image, blend_mode, ds_has_alpha, src_has_alpha, alpha); - } - // Backwards-compatible drawing - else if (src_has_alpha && alpha == 0xFF) - { - set_alpha_blender(); - ds->TransBlendBlt(image, xpos, ypos); - } - else - { - GfxUtil::DrawSpriteWithTransparency(ds, image, xpos, ypos, alpha); - } + BlendMode blend_mode, int alpha) { + if (alpha <= 0) + return; + + if (game.options[OPT_SPRITEALPHA] == kSpriteAlphaRender_Proper) { + GfxUtil::DrawSpriteBlend(ds, Point(xpos, ypos), image, blend_mode, ds_has_alpha, src_has_alpha, alpha); + } + // Backwards-compatible drawing + else if (src_has_alpha && alpha == 0xFF) { + set_alpha_blender(); + ds->TransBlendBlt(image, xpos, ypos); + } else { + GfxUtil::DrawSpriteWithTransparency(ds, image, xpos, ypos, alpha); + } } void draw_sprite_slot_support_alpha(Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot, - BlendMode blend_mode, int alpha) -{ - draw_sprite_support_alpha(ds, ds_has_alpha, xpos, ypos, spriteset[src_slot], (game.SpriteInfos[src_slot].Flags & SPF_ALPHACHANNEL) != 0, - blend_mode, alpha); + BlendMode blend_mode, int alpha) { + draw_sprite_support_alpha(ds, ds_has_alpha, xpos, ypos, spriteset[src_slot], (game.SpriteInfos[src_slot].Flags & SPF_ALPHACHANNEL) != 0, + blend_mode, alpha); } -IDriverDependantBitmap* recycle_ddb_bitmap(IDriverDependantBitmap *bimp, Bitmap *source, bool hasAlpha, bool opaque) { - if (bimp != nullptr) { - // same colour depth, width and height -> reuse - if (((bimp->GetColorDepth() + 1) / 8 == source->GetBPP()) && - (bimp->GetWidth() == source->GetWidth()) && (bimp->GetHeight() == source->GetHeight())) - { - gfxDriver->UpdateDDBFromBitmap(bimp, source, hasAlpha); - return bimp; - } +IDriverDependantBitmap *recycle_ddb_bitmap(IDriverDependantBitmap *bimp, Bitmap *source, bool hasAlpha, bool opaque) { + if (bimp != nullptr) { + // same colour depth, width and height -> reuse + if (((bimp->GetColorDepth() + 1) / 8 == source->GetBPP()) && + (bimp->GetWidth() == source->GetWidth()) && (bimp->GetHeight() == source->GetHeight())) { + gfxDriver->UpdateDDBFromBitmap(bimp, source, hasAlpha); + return bimp; + } - gfxDriver->DestroyDDB(bimp); - } - bimp = gfxDriver->CreateDDBFromBitmap(source, hasAlpha, opaque); - return bimp; + gfxDriver->DestroyDDB(bimp); + } + bimp = gfxDriver->CreateDDBFromBitmap(source, hasAlpha, opaque); + return bimp; } -void invalidate_cached_walkbehinds() -{ - memset(&actspswbcache[0], 0, sizeof(CachedActSpsData) * actSpsCount); +void invalidate_cached_walkbehinds() { + memset(&actspswbcache[0], 0, sizeof(CachedActSpsData) * actSpsCount); } // sort_out_walk_behinds: modifies the supplied sprite by overwriting parts // of it with transparent pixels where there are walk-behind areas // Returns whether any pixels were updated -int sort_out_walk_behinds(Bitmap *sprit,int xx,int yy,int basel, Bitmap *copyPixelsFrom = nullptr, Bitmap *checkPixelsFrom = nullptr, int zoom=100) { - if (noWalkBehindsAtAll) - return 0; - - if ((!thisroom.WalkBehindMask->IsMemoryBitmap()) || - (!sprit->IsMemoryBitmap())) - quit("!sort_out_walk_behinds: wb bitmap not linear"); - - int rr,tmm, toheight;//,tcol; - // precalculate this to try and shave some time off - int maskcol = sprit->GetMaskColor(); - int spcoldep = sprit->GetColorDepth(); - int screenhit = thisroom.WalkBehindMask->GetHeight(); - short *shptr, *shptr2; - int *loptr, *loptr2; - int pixelsChanged = 0; - int ee = 0; - if (xx < 0) - ee = 0 - xx; - - if ((checkPixelsFrom != nullptr) && (checkPixelsFrom->GetColorDepth() != spcoldep)) - quit("sprite colour depth does not match background colour depth"); - - for ( ; ee < sprit->GetWidth(); ee++) { - if (ee + xx >= thisroom.WalkBehindMask->GetWidth()) - break; - - if ((!walkBehindExists[ee+xx]) || - (walkBehindEndY[ee+xx] <= yy) || - (walkBehindStartY[ee+xx] > yy+sprit->GetHeight())) - continue; - - toheight = sprit->GetHeight(); - - if (walkBehindStartY[ee+xx] < yy) - rr = 0; - else - rr = (walkBehindStartY[ee+xx] - yy); - - // Since we will use _getpixel, ensure we only check within the screen - if (rr + yy < 0) - rr = 0 - yy; - if (toheight + yy > screenhit) - toheight = screenhit - yy; - if (toheight + yy > walkBehindEndY[ee+xx]) - toheight = walkBehindEndY[ee+xx] - yy; - if (rr < 0) - rr = 0; - - for ( ; rr < toheight;rr++) { - - // we're ok with _getpixel because we've checked the screen edges - //tmm = _getpixel(thisroom.WalkBehindMask,ee+xx,rr+yy); - // actually, _getpixel is well inefficient, do it ourselves - // since we know it's 8-bit bitmap - tmm = thisroom.WalkBehindMask->GetScanLine(rr+yy)[ee+xx]; - if (tmm<1) continue; - if (croom->walkbehind_base[tmm] <= basel) continue; - - if (copyPixelsFrom != nullptr) - { - if (spcoldep <= 8) - { - if (checkPixelsFrom->GetScanLine((rr * 100) / zoom)[(ee * 100) / zoom] != maskcol) { - sprit->GetScanLineForWriting(rr)[ee] = copyPixelsFrom->GetScanLine(rr + yy)[ee + xx]; - pixelsChanged = 1; - } - } - else if (spcoldep <= 16) { - shptr = (short*)&sprit->GetScanLine(rr)[0]; - shptr2 = (short*)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; - if (shptr2[(ee * 100) / zoom] != maskcol) { - shptr[ee] = ((short*)(©PixelsFrom->GetScanLine(rr + yy)[0]))[ee + xx]; - pixelsChanged = 1; - } - } - else if (spcoldep == 24) { - char *chptr = (char*)&sprit->GetScanLine(rr)[0]; - char *chptr2 = (char*)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; - if (memcmp(&chptr2[((ee * 100) / zoom) * 3], &maskcol, 3) != 0) { - memcpy(&chptr[ee * 3], ©PixelsFrom->GetScanLine(rr + yy)[(ee + xx) * 3], 3); - pixelsChanged = 1; - } - } - else if (spcoldep <= 32) { - loptr = (int*)&sprit->GetScanLine(rr)[0]; - loptr2 = (int*)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; - if (loptr2[(ee * 100) / zoom] != maskcol) { - loptr[ee] = ((int*)(©PixelsFrom->GetScanLine(rr + yy)[0]))[ee + xx]; - pixelsChanged = 1; - } - } - } - else - { - pixelsChanged = 1; - if (spcoldep <= 8) - sprit->GetScanLineForWriting(rr)[ee] = maskcol; - else if (spcoldep <= 16) { - shptr = (short*)&sprit->GetScanLine(rr)[0]; - shptr[ee] = maskcol; - } - else if (spcoldep == 24) { - char *chptr = (char*)&sprit->GetScanLine(rr)[0]; - memcpy(&chptr[ee * 3], &maskcol, 3); - } - else if (spcoldep <= 32) { - loptr = (int*)&sprit->GetScanLine(rr)[0]; - loptr[ee] = maskcol; - } - else - quit("!Sprite colour depth >32 ??"); - } - } - } - return pixelsChanged; -} - -void sort_out_char_sprite_walk_behind(int actspsIndex, int xx, int yy, int basel, int zoom, int width, int height) -{ - if (noWalkBehindsAtAll) - return; - - if ((!actspswbcache[actspsIndex].valid) || - (actspswbcache[actspsIndex].xWas != xx) || - (actspswbcache[actspsIndex].yWas != yy) || - (actspswbcache[actspsIndex].baselineWas != basel)) - { - actspswb[actspsIndex] = recycle_bitmap(actspswb[actspsIndex], thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth(), width, height, true); - Bitmap *wbSprite = actspswb[actspsIndex]; - - actspswbcache[actspsIndex].isWalkBehindHere = sort_out_walk_behinds(wbSprite, xx, yy, basel, thisroom.BgFrames[play.bg_frame].Graphic.get(), actsps[actspsIndex], zoom); - actspswbcache[actspsIndex].xWas = xx; - actspswbcache[actspsIndex].yWas = yy; - actspswbcache[actspsIndex].baselineWas = basel; - actspswbcache[actspsIndex].valid = 1; - - if (actspswbcache[actspsIndex].isWalkBehindHere) - { - actspswbbmp[actspsIndex] = recycle_ddb_bitmap(actspswbbmp[actspsIndex], actspswb[actspsIndex], false); - } - } - - if (actspswbcache[actspsIndex].isWalkBehindHere) - { - add_to_sprite_list(actspswbbmp[actspsIndex], xx, yy, basel, 0, -1, true); - } +int sort_out_walk_behinds(Bitmap *sprit, int xx, int yy, int basel, Bitmap *copyPixelsFrom = nullptr, Bitmap *checkPixelsFrom = nullptr, int zoom = 100) { + if (noWalkBehindsAtAll) + return 0; + + if ((!thisroom.WalkBehindMask->IsMemoryBitmap()) || + (!sprit->IsMemoryBitmap())) + quit("!sort_out_walk_behinds: wb bitmap not linear"); + + int rr, tmm, toheight; //,tcol; + // precalculate this to try and shave some time off + int maskcol = sprit->GetMaskColor(); + int spcoldep = sprit->GetColorDepth(); + int screenhit = thisroom.WalkBehindMask->GetHeight(); + short *shptr, *shptr2; + int *loptr, *loptr2; + int pixelsChanged = 0; + int ee = 0; + if (xx < 0) + ee = 0 - xx; + + if ((checkPixelsFrom != nullptr) && (checkPixelsFrom->GetColorDepth() != spcoldep)) + quit("sprite colour depth does not match background colour depth"); + + for (; ee < sprit->GetWidth(); ee++) { + if (ee + xx >= thisroom.WalkBehindMask->GetWidth()) + break; + + if ((!walkBehindExists[ee + xx]) || + (walkBehindEndY[ee + xx] <= yy) || + (walkBehindStartY[ee + xx] > yy + sprit->GetHeight())) + continue; + + toheight = sprit->GetHeight(); + + if (walkBehindStartY[ee + xx] < yy) + rr = 0; + else + rr = (walkBehindStartY[ee + xx] - yy); + + // Since we will use _getpixel, ensure we only check within the screen + if (rr + yy < 0) + rr = 0 - yy; + if (toheight + yy > screenhit) + toheight = screenhit - yy; + if (toheight + yy > walkBehindEndY[ee + xx]) + toheight = walkBehindEndY[ee + xx] - yy; + if (rr < 0) + rr = 0; + + for (; rr < toheight; rr++) { + + // we're ok with _getpixel because we've checked the screen edges + //tmm = _getpixel(thisroom.WalkBehindMask,ee+xx,rr+yy); + // actually, _getpixel is well inefficient, do it ourselves + // since we know it's 8-bit bitmap + tmm = thisroom.WalkBehindMask->GetScanLine(rr + yy)[ee + xx]; + if (tmm < 1) continue; + if (croom->walkbehind_base[tmm] <= basel) continue; + + if (copyPixelsFrom != nullptr) { + if (spcoldep <= 8) { + if (checkPixelsFrom->GetScanLine((rr * 100) / zoom)[(ee * 100) / zoom] != maskcol) { + sprit->GetScanLineForWriting(rr)[ee] = copyPixelsFrom->GetScanLine(rr + yy)[ee + xx]; + pixelsChanged = 1; + } + } else if (spcoldep <= 16) { + shptr = (short *)&sprit->GetScanLine(rr)[0]; + shptr2 = (short *)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; + if (shptr2[(ee * 100) / zoom] != maskcol) { + shptr[ee] = ((short *)(©PixelsFrom->GetScanLine(rr + yy)[0]))[ee + xx]; + pixelsChanged = 1; + } + } else if (spcoldep == 24) { + char *chptr = (char *)&sprit->GetScanLine(rr)[0]; + char *chptr2 = (char *)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; + if (memcmp(&chptr2[((ee * 100) / zoom) * 3], &maskcol, 3) != 0) { + memcpy(&chptr[ee * 3], ©PixelsFrom->GetScanLine(rr + yy)[(ee + xx) * 3], 3); + pixelsChanged = 1; + } + } else if (spcoldep <= 32) { + loptr = (int *)&sprit->GetScanLine(rr)[0]; + loptr2 = (int *)&checkPixelsFrom->GetScanLine((rr * 100) / zoom)[0]; + if (loptr2[(ee * 100) / zoom] != maskcol) { + loptr[ee] = ((int *)(©PixelsFrom->GetScanLine(rr + yy)[0]))[ee + xx]; + pixelsChanged = 1; + } + } + } else { + pixelsChanged = 1; + if (spcoldep <= 8) + sprit->GetScanLineForWriting(rr)[ee] = maskcol; + else if (spcoldep <= 16) { + shptr = (short *)&sprit->GetScanLine(rr)[0]; + shptr[ee] = maskcol; + } else if (spcoldep == 24) { + char *chptr = (char *)&sprit->GetScanLine(rr)[0]; + memcpy(&chptr[ee * 3], &maskcol, 3); + } else if (spcoldep <= 32) { + loptr = (int *)&sprit->GetScanLine(rr)[0]; + loptr[ee] = maskcol; + } else + quit("!Sprite colour depth >32 ??"); + } + } + } + return pixelsChanged; +} + +void sort_out_char_sprite_walk_behind(int actspsIndex, int xx, int yy, int basel, int zoom, int width, int height) { + if (noWalkBehindsAtAll) + return; + + if ((!actspswbcache[actspsIndex].valid) || + (actspswbcache[actspsIndex].xWas != xx) || + (actspswbcache[actspsIndex].yWas != yy) || + (actspswbcache[actspsIndex].baselineWas != basel)) { + actspswb[actspsIndex] = recycle_bitmap(actspswb[actspsIndex], thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth(), width, height, true); + Bitmap *wbSprite = actspswb[actspsIndex]; + + actspswbcache[actspsIndex].isWalkBehindHere = sort_out_walk_behinds(wbSprite, xx, yy, basel, thisroom.BgFrames[play.bg_frame].Graphic.get(), actsps[actspsIndex], zoom); + actspswbcache[actspsIndex].xWas = xx; + actspswbcache[actspsIndex].yWas = yy; + actspswbcache[actspsIndex].baselineWas = basel; + actspswbcache[actspsIndex].valid = 1; + + if (actspswbcache[actspsIndex].isWalkBehindHere) { + actspswbbmp[actspsIndex] = recycle_ddb_bitmap(actspswbbmp[actspsIndex], actspswb[actspsIndex], false); + } + } + + if (actspswbcache[actspsIndex].isWalkBehindHere) { + add_to_sprite_list(actspswbbmp[actspsIndex], xx, yy, basel, 0, -1, true); + } } void clear_draw_list() { - thingsToDrawList.clear(); + thingsToDrawList.clear(); } -void add_thing_to_draw(IDriverDependantBitmap* bmp, int x, int y, int trans, bool alphaChannel) { - SpriteListEntry sprite; - sprite.pic = nullptr; - sprite.bmp = bmp; - sprite.x = x; - sprite.y = y; - sprite.transparent = trans; - sprite.hasAlphaChannel = alphaChannel; - thingsToDrawList.push_back(sprite); +void add_thing_to_draw(IDriverDependantBitmap *bmp, int x, int y, int trans, bool alphaChannel) { + SpriteListEntry sprite; + sprite.pic = nullptr; + sprite.bmp = bmp; + sprite.x = x; + sprite.y = y; + sprite.transparent = trans; + sprite.hasAlphaChannel = alphaChannel; + thingsToDrawList.push_back(sprite); } -// the sprite list is an intermediate list used to order +// the sprite list is an intermediate list used to order // objects and characters by their baselines before everything // is added to the Thing To Draw List void clear_sprite_list() { - sprlist.clear(); -} -void add_to_sprite_list(IDriverDependantBitmap* spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind) { - - if (spp == nullptr) - quit("add_to_sprite_list: attempted to draw NULL sprite"); - // completely invisible, so don't draw it at all - if (trans == 255) - return; - - SpriteListEntry sprite; - if ((sprNum >= 0) && ((game.SpriteInfos[sprNum].Flags & SPF_ALPHACHANNEL) != 0)) - sprite.hasAlphaChannel = true; - else - sprite.hasAlphaChannel = false; - - sprite.bmp = spp; - sprite.baseline = baseline; - sprite.x=xx; - sprite.y=yy; - sprite.transparent=trans; - - if (walkBehindMethod == DrawAsSeparateSprite) - sprite.takesPriorityIfEqual = !isWalkBehind; - else - sprite.takesPriorityIfEqual = isWalkBehind; - - sprlist.push_back(sprite); -} - -void repair_alpha_channel(Bitmap *dest, Bitmap *bgpic) -{ - // Repair the alpha channel, because sprites may have been drawn - // over it by the buttons, etc - int theWid = (dest->GetWidth() < bgpic->GetWidth()) ? dest->GetWidth() : bgpic->GetWidth(); - int theHit = (dest->GetHeight() < bgpic->GetHeight()) ? dest->GetHeight() : bgpic->GetHeight(); - for (int y = 0; y < theHit; y++) - { - unsigned int *destination = ((unsigned int*)dest->GetScanLineForWriting(y)); - unsigned int *source = ((unsigned int*)bgpic->GetScanLineForWriting(y)); - for (int x = 0; x < theWid; x++) - { - destination[x] |= (source[x] & 0xff000000); - } - } + sprlist.clear(); +} +void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind) { + + if (spp == nullptr) + quit("add_to_sprite_list: attempted to draw NULL sprite"); + // completely invisible, so don't draw it at all + if (trans == 255) + return; + + SpriteListEntry sprite; + if ((sprNum >= 0) && ((game.SpriteInfos[sprNum].Flags & SPF_ALPHACHANNEL) != 0)) + sprite.hasAlphaChannel = true; + else + sprite.hasAlphaChannel = false; + + sprite.bmp = spp; + sprite.baseline = baseline; + sprite.x = xx; + sprite.y = yy; + sprite.transparent = trans; + + if (walkBehindMethod == DrawAsSeparateSprite) + sprite.takesPriorityIfEqual = !isWalkBehind; + else + sprite.takesPriorityIfEqual = isWalkBehind; + + sprlist.push_back(sprite); +} + +void repair_alpha_channel(Bitmap *dest, Bitmap *bgpic) { + // Repair the alpha channel, because sprites may have been drawn + // over it by the buttons, etc + int theWid = (dest->GetWidth() < bgpic->GetWidth()) ? dest->GetWidth() : bgpic->GetWidth(); + int theHit = (dest->GetHeight() < bgpic->GetHeight()) ? dest->GetHeight() : bgpic->GetHeight(); + for (int y = 0; y < theHit; y++) { + unsigned int *destination = ((unsigned int *)dest->GetScanLineForWriting(y)); + unsigned int *source = ((unsigned int *)bgpic->GetScanLineForWriting(y)); + for (int x = 0; x < theWid; x++) { + destination[x] |= (source[x] & 0xff000000); + } + } } // used by GUI renderer to draw images -void draw_gui_sprite(Bitmap *ds, int pic, int x, int y, bool use_alpha, BlendMode blend_mode) -{ - Bitmap *sprite = spriteset[pic]; - const bool ds_has_alpha = ds->GetColorDepth() == 32; - const bool src_has_alpha = (game.SpriteInfos[pic].Flags & SPF_ALPHACHANNEL) != 0; - - if (use_alpha && game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Proper) - { - GfxUtil::DrawSpriteBlend(ds, Point(x, y), sprite, blend_mode, ds_has_alpha, src_has_alpha); - } - // Backwards-compatible drawing - else if (use_alpha && ds_has_alpha && game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_AdditiveAlpha) - { - if (src_has_alpha) - set_additive_alpha_blender(); - else - set_opaque_alpha_blender(); - ds->TransBlendBlt(sprite, x, y); - } - else - { - GfxUtil::DrawSpriteWithTransparency(ds, sprite, x, y); - } -} - -void draw_gui_sprite_v330(Bitmap *ds, int pic, int x, int y, bool use_alpha, BlendMode blend_mode) -{ - draw_gui_sprite(ds, pic, x, y, use_alpha && (loaded_game_file_version >= kGameVersion_330), blend_mode); +void draw_gui_sprite(Bitmap *ds, int pic, int x, int y, bool use_alpha, BlendMode blend_mode) { + Bitmap *sprite = spriteset[pic]; + const bool ds_has_alpha = ds->GetColorDepth() == 32; + const bool src_has_alpha = (game.SpriteInfos[pic].Flags & SPF_ALPHACHANNEL) != 0; + + if (use_alpha && game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Proper) { + GfxUtil::DrawSpriteBlend(ds, Point(x, y), sprite, blend_mode, ds_has_alpha, src_has_alpha); + } + // Backwards-compatible drawing + else if (use_alpha && ds_has_alpha && game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_AdditiveAlpha) { + if (src_has_alpha) + set_additive_alpha_blender(); + else + set_opaque_alpha_blender(); + ds->TransBlendBlt(sprite, x, y); + } else { + GfxUtil::DrawSpriteWithTransparency(ds, sprite, x, y); + } +} + +void draw_gui_sprite_v330(Bitmap *ds, int pic, int x, int y, bool use_alpha, BlendMode blend_mode) { + draw_gui_sprite(ds, pic, x, y, use_alpha && (loaded_game_file_version >= kGameVersion_330), blend_mode); } // function to sort the sprites into baseline order -bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2) -{ - if (e1.baseline == e2.baseline) - { - if (e1.takesPriorityIfEqual) - return false; - if (e2.takesPriorityIfEqual) - return true; - } - return e1.baseline < e2.baseline; +bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2) { + if (e1.baseline == e2.baseline) { + if (e1.takesPriorityIfEqual) + return false; + if (e2.takesPriorityIfEqual) + return true; + } + return e1.baseline < e2.baseline; } @@ -1151,46 +1034,41 @@ bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2) void draw_sprite_list() { - if (walkBehindMethod == DrawAsSeparateSprite) - { - for (int ee = 1; ee < MAX_WALK_BEHINDS; ee++) - { - if (walkBehindBitmap[ee] != nullptr) - { - add_to_sprite_list(walkBehindBitmap[ee], walkBehindLeft[ee], walkBehindTop[ee], - croom->walkbehind_base[ee], 0, -1, true); - } - } - } + if (walkBehindMethod == DrawAsSeparateSprite) { + for (int ee = 1; ee < MAX_WALK_BEHINDS; ee++) { + if (walkBehindBitmap[ee] != nullptr) { + add_to_sprite_list(walkBehindBitmap[ee], walkBehindLeft[ee], walkBehindTop[ee], + croom->walkbehind_base[ee], 0, -1, true); + } + } + } - std::sort(sprlist.begin(), sprlist.end(), spritelistentry_less); + std::sort(sprlist.begin(), sprlist.end(), spritelistentry_less); - if(pl_any_want_hook(AGSE_PRESCREENDRAW)) - add_thing_to_draw(nullptr, AGSE_PRESCREENDRAW, 0, TRANS_RUN_PLUGIN, false); + if (pl_any_want_hook(AGSE_PRESCREENDRAW)) + add_thing_to_draw(nullptr, AGSE_PRESCREENDRAW, 0, TRANS_RUN_PLUGIN, false); - // copy the sorted sprites into the Things To Draw list - thingsToDrawList.insert(thingsToDrawList.end(), sprlist.begin(), sprlist.end()); + // copy the sorted sprites into the Things To Draw list + thingsToDrawList.insert(thingsToDrawList.end(), sprlist.begin(), sprlist.end()); } // Avoid freeing and reallocating the memory if possible Bitmap *recycle_bitmap(Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent) { - if (bimp != nullptr) { - // same colour depth, width and height -> reuse - if ((bimp->GetColorDepth() == coldep) && (bimp->GetWidth() == wid) - && (bimp->GetHeight() == hit)) - { - if (make_transparent) - { - bimp->ClearTransparent(); - } - return bimp; - } - - delete bimp; - } - bimp = make_transparent ? BitmapHelper::CreateTransparentBitmap(wid, hit,coldep) : - BitmapHelper::CreateBitmap(wid, hit,coldep); - return bimp; + if (bimp != nullptr) { + // same colour depth, width and height -> reuse + if ((bimp->GetColorDepth() == coldep) && (bimp->GetWidth() == wid) + && (bimp->GetHeight() == hit)) { + if (make_transparent) { + bimp->ClearTransparent(); + } + return bimp; + } + + delete bimp; + } + bimp = make_transparent ? BitmapHelper::CreateTransparentBitmap(wid, hit, coldep) : + BitmapHelper::CreateBitmap(wid, hit, coldep); + return bimp; } @@ -1203,83 +1081,78 @@ void get_local_tint(int xpp, int ypp, int nolight, int *tint_b, int *tint_lit, int *light_lev) { - int tint_level = 0, light_level = 0; - int tint_amount = 0; - int tint_red = 0; - int tint_green = 0; - int tint_blue = 0; - int tint_light = 255; - - if (nolight == 0) { - - int onRegion = 0; - - if ((play.ground_level_areas_disabled & GLED_EFFECTS) == 0) { - // check if the player is on a region, to find its - // light/tint level - onRegion = GetRegionIDAtRoom(xpp, ypp); - if (onRegion == 0) { - // when walking, he might just be off a walkable area - onRegion = GetRegionIDAtRoom(xpp - 3, ypp); - if (onRegion == 0) - onRegion = GetRegionIDAtRoom(xpp + 3, ypp); - if (onRegion == 0) - onRegion = GetRegionIDAtRoom(xpp, ypp - 3); - if (onRegion == 0) - onRegion = GetRegionIDAtRoom(xpp, ypp + 3); - } - } - - if ((onRegion > 0) && (onRegion < MAX_ROOM_REGIONS)) { - light_level = thisroom.Regions[onRegion].Light; - tint_level = thisroom.Regions[onRegion].Tint; - } - else if (onRegion <= 0) { - light_level = thisroom.Regions[0].Light; - tint_level = thisroom.Regions[0].Tint; - } - - int tint_sat = (tint_level >> 24) & 0xFF; - if ((game.color_depth == 1) || ((tint_level & 0x00ffffff) == 0) || - (tint_sat == 0)) - tint_level = 0; - - if (tint_level) { - tint_red = (unsigned char)(tint_level & 0x000ff); - tint_green = (unsigned char)((tint_level >> 8) & 0x000ff); - tint_blue = (unsigned char)((tint_level >> 16) & 0x000ff); - tint_amount = tint_sat; - tint_light = light_level; - } - - if (play.rtint_enabled) - { - if (play.rtint_level > 0) - { - // override with room tint - tint_red = play.rtint_red; - tint_green = play.rtint_green; - tint_blue = play.rtint_blue; - tint_amount = play.rtint_level; - tint_light = play.rtint_light; - } - else - { - // override with room light level - tint_amount = 0; - light_level = play.rtint_light; - } - } - } - - // copy to output parameters - *tint_amnt = tint_amount; - *tint_r = tint_red; - *tint_g = tint_green; - *tint_b = tint_blue; - *tint_lit = tint_light; - if (light_lev) - *light_lev = light_level; + int tint_level = 0, light_level = 0; + int tint_amount = 0; + int tint_red = 0; + int tint_green = 0; + int tint_blue = 0; + int tint_light = 255; + + if (nolight == 0) { + + int onRegion = 0; + + if ((play.ground_level_areas_disabled & GLED_EFFECTS) == 0) { + // check if the player is on a region, to find its + // light/tint level + onRegion = GetRegionIDAtRoom(xpp, ypp); + if (onRegion == 0) { + // when walking, he might just be off a walkable area + onRegion = GetRegionIDAtRoom(xpp - 3, ypp); + if (onRegion == 0) + onRegion = GetRegionIDAtRoom(xpp + 3, ypp); + if (onRegion == 0) + onRegion = GetRegionIDAtRoom(xpp, ypp - 3); + if (onRegion == 0) + onRegion = GetRegionIDAtRoom(xpp, ypp + 3); + } + } + + if ((onRegion > 0) && (onRegion < MAX_ROOM_REGIONS)) { + light_level = thisroom.Regions[onRegion].Light; + tint_level = thisroom.Regions[onRegion].Tint; + } else if (onRegion <= 0) { + light_level = thisroom.Regions[0].Light; + tint_level = thisroom.Regions[0].Tint; + } + + int tint_sat = (tint_level >> 24) & 0xFF; + if ((game.color_depth == 1) || ((tint_level & 0x00ffffff) == 0) || + (tint_sat == 0)) + tint_level = 0; + + if (tint_level) { + tint_red = (unsigned char)(tint_level & 0x000ff); + tint_green = (unsigned char)((tint_level >> 8) & 0x000ff); + tint_blue = (unsigned char)((tint_level >> 16) & 0x000ff); + tint_amount = tint_sat; + tint_light = light_level; + } + + if (play.rtint_enabled) { + if (play.rtint_level > 0) { + // override with room tint + tint_red = play.rtint_red; + tint_green = play.rtint_green; + tint_blue = play.rtint_blue; + tint_amount = play.rtint_level; + tint_light = play.rtint_light; + } else { + // override with room light level + tint_amount = 0; + light_level = play.rtint_light; + } + } + } + + // copy to output parameters + *tint_amnt = tint_amount; + *tint_r = tint_red; + *tint_g = tint_green; + *tint_b = tint_blue; + *tint_lit = tint_light; + if (light_lev) + *light_lev = light_level; } @@ -1292,65 +1165,62 @@ void apply_tint_or_light(int actspsindex, int light_level, int tint_blue, int tint_light, int coldept, Bitmap *blitFrom) { - // In a 256-colour game, we cannot do tinting or lightening - // (but we can do darkening, if light_level < 0) - if (game.color_depth == 1) { - if ((light_level > 0) || (tint_amount != 0)) - return; - } - - // we can only do tint/light if the colour depths match - if (game.GetColorDepth() == actsps[actspsindex]->GetColorDepth()) { - Bitmap *oldwas; - // if the caller supplied a source bitmap, ->Blit from it - // (used as a speed optimisation where possible) - if (blitFrom) - oldwas = blitFrom; - // otherwise, make a new target bmp - else { - oldwas = actsps[actspsindex]; - actsps[actspsindex] = BitmapHelper::CreateBitmap(oldwas->GetWidth(), oldwas->GetHeight(), coldept); - } - Bitmap *active_spr = actsps[actspsindex]; - - if (tint_amount) { - // It is an RGB tint - tint_image (active_spr, oldwas, tint_red, tint_green, tint_blue, tint_amount, tint_light); - } - else { - // the RGB values passed to set_trans_blender decide whether it will darken - // or lighten sprites ( <128=darken, >128=lighten). The parameter passed - // to LitBlendBlt defines how much it will be darkened/lightened by. - - int lit_amnt; - active_spr->FillTransparent(); - // It's a light level, not a tint - if (game.color_depth == 1) { - // 256-col - lit_amnt = (250 - ((-light_level) * 5)/2); - } - else { - // hi-color - if (light_level < 0) - set_my_trans_blender(8,8,8,0); - else - set_my_trans_blender(248,248,248,0); - lit_amnt = abs(light_level) * 2; - } - - active_spr->LitBlendBlt(oldwas, 0, 0, lit_amnt); - } - - if (oldwas != blitFrom) - delete oldwas; - - } - else if (blitFrom) { - // sprite colour depth != game colour depth, so don't try and tint - // but we do need to do something, so copy the source - Bitmap *active_spr = actsps[actspsindex]; - active_spr->Blit(blitFrom, 0, 0, 0, 0, active_spr->GetWidth(), active_spr->GetHeight()); - } +// In a 256-colour game, we cannot do tinting or lightening +// (but we can do darkening, if light_level < 0) + if (game.color_depth == 1) { + if ((light_level > 0) || (tint_amount != 0)) + return; + } + +// we can only do tint/light if the colour depths match + if (game.GetColorDepth() == actsps[actspsindex]->GetColorDepth()) { + Bitmap *oldwas; + // if the caller supplied a source bitmap, ->Blit from it + // (used as a speed optimisation where possible) + if (blitFrom) + oldwas = blitFrom; + // otherwise, make a new target bmp + else { + oldwas = actsps[actspsindex]; + actsps[actspsindex] = BitmapHelper::CreateBitmap(oldwas->GetWidth(), oldwas->GetHeight(), coldept); + } + Bitmap *active_spr = actsps[actspsindex]; + + if (tint_amount) { + // It is an RGB tint + tint_image(active_spr, oldwas, tint_red, tint_green, tint_blue, tint_amount, tint_light); + } else { + // the RGB values passed to set_trans_blender decide whether it will darken + // or lighten sprites ( <128=darken, >128=lighten). The parameter passed + // to LitBlendBlt defines how much it will be darkened/lightened by. + + int lit_amnt; + active_spr->FillTransparent(); + // It's a light level, not a tint + if (game.color_depth == 1) { + // 256-col + lit_amnt = (250 - ((-light_level) * 5) / 2); + } else { + // hi-color + if (light_level < 0) + set_my_trans_blender(8, 8, 8, 0); + else + set_my_trans_blender(248, 248, 248, 0); + lit_amnt = abs(light_level) * 2; + } + + active_spr->LitBlendBlt(oldwas, 0, 0, lit_amnt); + } + + if (oldwas != blitFrom) + delete oldwas; + + } else if (blitFrom) { + // sprite colour depth != game colour depth, so don't try and tint + // but we do need to do something, so copy the source + Bitmap *active_spr = actsps[actspsindex]; + active_spr->Blit(blitFrom, 0, 0, 0, 0, active_spr->GetWidth(), active_spr->GetHeight()); + } } @@ -1362,76 +1232,74 @@ int scale_and_flip_sprite(int useindx, int coldept, int zoom_level, int sppic, int newwidth, int newheight, int isMirrored) { - int actsps_used = 1; - - // create and blank out the new sprite - actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, newwidth, newheight, true); - Bitmap *active_spr = actsps[useindx]; - - if (zoom_level != 100) { - // Scaled character - - our_eip = 334; - - // Ensure that anti-aliasing routines have a palette to - // use for mapping while faded out - if (in_new_room) - select_palette (palette); - - - if (isMirrored) { - Bitmap *tempspr = BitmapHelper::CreateBitmap(newwidth, newheight,coldept); - tempspr->Fill (actsps[useindx]->GetMaskColor()); - if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) - tempspr->AAStretchBlt (spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); - else - tempspr->StretchBlt (spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); - active_spr->FlipBlt(tempspr, 0, 0, Common::kBitmap_HFlip); - delete tempspr; - } - else if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) - active_spr->AAStretchBlt(spriteset[sppic],RectWH(0,0,newwidth,newheight), Common::kBitmap_Transparency); - else - active_spr->StretchBlt(spriteset[sppic],RectWH(0,0,newwidth,newheight), Common::kBitmap_Transparency); - - /* AASTR2 version of code (doesn't work properly, gives black borders) - if (IS_ANTIALIAS_SPRITES) { - int aa_mode = AA_MASKED; - if (game.spriteflags[sppic] & SPF_ALPHACHANNEL) - aa_mode |= AA_ALPHA | AA_RAW_ALPHA; - if (isMirrored) - aa_mode |= AA_HFLIP; - - aa_set_mode(aa_mode); - ->AAStretchBlt(actsps[useindx],spriteset[sppic],0,0,newwidth,newheight); - } - else if (isMirrored) { - Bitmap *tempspr = BitmapHelper::CreateBitmap_ (coldept, newwidth, newheight); - ->Clear (tempspr, ->GetMaskColor(actsps[useindx])); - ->StretchBlt (tempspr, spriteset[sppic], 0, 0, newwidth, newheight); - ->FlipBlt(Common::kBitmap_HFlip, (actsps[useindx], tempspr, 0, 0); - wfreeblock (tempspr); - } - else - ->StretchBlt(actsps[useindx],spriteset[sppic],0,0,newwidth,newheight); - */ - if (in_new_room) - unselect_palette(); - - } - else { - // Not a scaled character, draw at normal size - - our_eip = 339; - - if (isMirrored) - active_spr->FlipBlt(spriteset[sppic], 0, 0, Common::kBitmap_HFlip); - else - actsps_used = 0; - //->Blit (spriteset[sppic], actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); - } - - return actsps_used; + int actsps_used = 1; + + // create and blank out the new sprite + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, newwidth, newheight, true); + Bitmap *active_spr = actsps[useindx]; + + if (zoom_level != 100) { + // Scaled character + + our_eip = 334; + + // Ensure that anti-aliasing routines have a palette to + // use for mapping while faded out + if (in_new_room) + select_palette(palette); + + + if (isMirrored) { + Bitmap *tempspr = BitmapHelper::CreateBitmap(newwidth, newheight, coldept); + tempspr->Fill(actsps[useindx]->GetMaskColor()); + if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) + tempspr->AAStretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + else + tempspr->StretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + active_spr->FlipBlt(tempspr, 0, 0, Common::kBitmap_HFlip); + delete tempspr; + } else if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) + active_spr->AAStretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + else + active_spr->StretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + + /* AASTR2 version of code (doesn't work properly, gives black borders) + if (IS_ANTIALIAS_SPRITES) { + int aa_mode = AA_MASKED; + if (game.spriteflags[sppic] & SPF_ALPHACHANNEL) + aa_mode |= AA_ALPHA | AA_RAW_ALPHA; + if (isMirrored) + aa_mode |= AA_HFLIP; + + aa_set_mode(aa_mode); + ->AAStretchBlt(actsps[useindx],spriteset[sppic],0,0,newwidth,newheight); + } + else if (isMirrored) { + Bitmap *tempspr = BitmapHelper::CreateBitmap_ (coldept, newwidth, newheight); + ->Clear (tempspr, ->GetMaskColor(actsps[useindx])); + ->StretchBlt (tempspr, spriteset[sppic], 0, 0, newwidth, newheight); + ->FlipBlt(Common::kBitmap_HFlip, (actsps[useindx], tempspr, 0, 0); + wfreeblock (tempspr); + } + else + ->StretchBlt(actsps[useindx],spriteset[sppic],0,0,newwidth,newheight); + */ + if (in_new_room) + unselect_palette(); + + } else { + // Not a scaled character, draw at normal size + + our_eip = 339; + + if (isMirrored) + active_spr->FlipBlt(spriteset[sppic], 0, 0, Common::kBitmap_HFlip); + else + actsps_used = 0; + //->Blit (spriteset[sppic], actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + } + + return actsps_used; } @@ -1440,182 +1308,168 @@ int scale_and_flip_sprite(int useindx, int coldept, int zoom_level, // returns 1 if nothing at all has changed and actsps is still // intact from last time; 0 otherwise int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysUseSoftware) { - int useindx = aa; - bool hardwareAccelerated = !alwaysUseSoftware && gfxDriver->HasAcceleratedTransform(); - - if (spriteset[objs[aa].num] == nullptr) - quitprintf("There was an error drawing object %d. Its current sprite, %d, is invalid.", aa, objs[aa].num); - - int coldept = spriteset[objs[aa].num]->GetColorDepth(); - int sprwidth = game.SpriteInfos[objs[aa].num].Width; - int sprheight = game.SpriteInfos[objs[aa].num].Height; - - int tint_red, tint_green, tint_blue; - int tint_level, tint_light, light_level; - int zoom_level = 100; - - // calculate the zoom level - if ((objs[aa].flags & OBJF_USEROOMSCALING) == 0) - { - zoom_level = objs[aa].zoom; - } - else - { - int onarea = get_walkable_area_at_location(objs[aa].x, objs[aa].y); - if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) { - // just off the edge of an area -- use the scaling we had - // while on the area - zoom_level = objs[aa].zoom; - } - else - zoom_level = get_area_scaling(onarea, objs[aa].x, objs[aa].y); - } - if (zoom_level != 100) - scale_sprite_size(objs[aa].num, zoom_level, &sprwidth, &sprheight); - objs[aa].zoom = zoom_level; - - // save width/height into parameters if requested - if (drawnWidth) - *drawnWidth = sprwidth; - if (drawnHeight) - *drawnHeight = sprheight; - - objs[aa].last_width = sprwidth; - objs[aa].last_height = sprheight; - - tint_red = tint_green = tint_blue = tint_level = tint_light = light_level = 0; - - if (objs[aa].flags & OBJF_HASTINT) { - // object specific tint, use it - tint_red = objs[aa].tint_r; - tint_green = objs[aa].tint_g; - tint_blue = objs[aa].tint_b; - tint_level = objs[aa].tint_level; - tint_light = objs[aa].tint_light; - light_level = 0; - } - else if (objs[aa].flags & OBJF_HASLIGHT) - { - light_level = objs[aa].tint_light; - } - else { - // get the ambient or region tint - int ignoreRegionTints = 1; - if (objs[aa].flags & OBJF_USEREGIONTINTS) - ignoreRegionTints = 0; - - get_local_tint(objs[aa].x, objs[aa].y, ignoreRegionTints, - &tint_level, &tint_red, &tint_green, &tint_blue, - &tint_light, &light_level); - } - - // check whether the image should be flipped - int isMirrored = 0; - if ( (objs[aa].view >= 0) && - (views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].pic == objs[aa].num) && - ((views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE) != 0)) { - isMirrored = 1; - } - - if ((hardwareAccelerated) && - (walkBehindMethod != DrawOverCharSprite) && - (objcache[aa].image != nullptr) && - (objcache[aa].sppic == objs[aa].num) && - (actsps[useindx] != nullptr)) - { - // HW acceleration - objcache[aa].tintamntwas = tint_level; - objcache[aa].tintredwas = tint_red; - objcache[aa].tintgrnwas = tint_green; - objcache[aa].tintbluwas = tint_blue; - objcache[aa].tintlightwas = tint_light; - objcache[aa].lightlevwas = light_level; - objcache[aa].zoomWas = zoom_level; - objcache[aa].mirroredWas = isMirrored; - - return 1; - } - - if ((!hardwareAccelerated) && (gfxDriver->HasAcceleratedTransform())) - { - // They want to draw it in software mode with the D3D driver, - // so force a redraw - objcache[aa].sppic = -389538; - } - - // If we have the image cached, use it - if ((objcache[aa].image != nullptr) && - (objcache[aa].sppic == objs[aa].num) && - (objcache[aa].tintamntwas == tint_level) && - (objcache[aa].tintlightwas == tint_light) && - (objcache[aa].tintredwas == tint_red) && - (objcache[aa].tintgrnwas == tint_green) && - (objcache[aa].tintbluwas == tint_blue) && - (objcache[aa].lightlevwas == light_level) && - (objcache[aa].zoomWas == zoom_level) && - (objcache[aa].mirroredWas == isMirrored)) { - // the image is the same, we can use it cached! - if ((walkBehindMethod != DrawOverCharSprite) && - (actsps[useindx] != nullptr)) - return 1; - // Check if the X & Y co-ords are the same, too -- if so, there - // is scope for further optimisations - if ((objcache[aa].xwas == objs[aa].x) && - (objcache[aa].ywas == objs[aa].y) && - (actsps[useindx] != nullptr) && - (walk_behind_baselines_changed == 0)) - return 1; - actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, sprwidth, sprheight); - actsps[useindx]->Blit(objcache[aa].image, 0, 0, 0, 0, objcache[aa].image->GetWidth(), objcache[aa].image->GetHeight()); - return 0; - } - - // Not cached, so draw the image - - int actspsUsed = 0; - if (!hardwareAccelerated) - { - // draw the base sprite, scaled and flipped as appropriate - actspsUsed = scale_and_flip_sprite(useindx, coldept, zoom_level, - objs[aa].num, sprwidth, sprheight, isMirrored); - } - else - { - // ensure actsps exists - actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, game.SpriteInfos[objs[aa].num].Width, game.SpriteInfos[objs[aa].num].Height); - } - - // direct read from source bitmap, where possible - Bitmap *comeFrom = nullptr; - if (!actspsUsed) - comeFrom = spriteset[objs[aa].num]; - - // apply tints or lightenings where appropriate, else just copy - // the source bitmap - if (!hardwareAccelerated && ((tint_level > 0) || (light_level != 0))) - { - apply_tint_or_light(useindx, light_level, tint_level, tint_red, - tint_green, tint_blue, tint_light, coldept, - comeFrom); - } - else if (!actspsUsed) { - actsps[useindx]->Blit(spriteset[objs[aa].num],0,0,0,0,game.SpriteInfos[objs[aa].num].Width, game.SpriteInfos[objs[aa].num].Height); - } - - // Re-use the bitmap if it's the same size - objcache[aa].image = recycle_bitmap(objcache[aa].image, coldept, sprwidth, sprheight); - // Create the cached image and store it - objcache[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, sprwidth, sprheight); - objcache[aa].sppic = objs[aa].num; - objcache[aa].tintamntwas = tint_level; - objcache[aa].tintredwas = tint_red; - objcache[aa].tintgrnwas = tint_green; - objcache[aa].tintbluwas = tint_blue; - objcache[aa].tintlightwas = tint_light; - objcache[aa].lightlevwas = light_level; - objcache[aa].zoomWas = zoom_level; - objcache[aa].mirroredWas = isMirrored; - return 0; + int useindx = aa; + bool hardwareAccelerated = !alwaysUseSoftware && gfxDriver->HasAcceleratedTransform(); + + if (spriteset[objs[aa].num] == nullptr) + quitprintf("There was an error drawing object %d. Its current sprite, %d, is invalid.", aa, objs[aa].num); + + int coldept = spriteset[objs[aa].num]->GetColorDepth(); + int sprwidth = game.SpriteInfos[objs[aa].num].Width; + int sprheight = game.SpriteInfos[objs[aa].num].Height; + + int tint_red, tint_green, tint_blue; + int tint_level, tint_light, light_level; + int zoom_level = 100; + + // calculate the zoom level + if ((objs[aa].flags & OBJF_USEROOMSCALING) == 0) { + zoom_level = objs[aa].zoom; + } else { + int onarea = get_walkable_area_at_location(objs[aa].x, objs[aa].y); + if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) { + // just off the edge of an area -- use the scaling we had + // while on the area + zoom_level = objs[aa].zoom; + } else + zoom_level = get_area_scaling(onarea, objs[aa].x, objs[aa].y); + } + if (zoom_level != 100) + scale_sprite_size(objs[aa].num, zoom_level, &sprwidth, &sprheight); + objs[aa].zoom = zoom_level; + + // save width/height into parameters if requested + if (drawnWidth) + *drawnWidth = sprwidth; + if (drawnHeight) + *drawnHeight = sprheight; + + objs[aa].last_width = sprwidth; + objs[aa].last_height = sprheight; + + tint_red = tint_green = tint_blue = tint_level = tint_light = light_level = 0; + + if (objs[aa].flags & OBJF_HASTINT) { + // object specific tint, use it + tint_red = objs[aa].tint_r; + tint_green = objs[aa].tint_g; + tint_blue = objs[aa].tint_b; + tint_level = objs[aa].tint_level; + tint_light = objs[aa].tint_light; + light_level = 0; + } else if (objs[aa].flags & OBJF_HASLIGHT) { + light_level = objs[aa].tint_light; + } else { + // get the ambient or region tint + int ignoreRegionTints = 1; + if (objs[aa].flags & OBJF_USEREGIONTINTS) + ignoreRegionTints = 0; + + get_local_tint(objs[aa].x, objs[aa].y, ignoreRegionTints, + &tint_level, &tint_red, &tint_green, &tint_blue, + &tint_light, &light_level); + } + + // check whether the image should be flipped + int isMirrored = 0; + if ((objs[aa].view >= 0) && + (views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].pic == objs[aa].num) && + ((views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE) != 0)) { + isMirrored = 1; + } + + if ((hardwareAccelerated) && + (walkBehindMethod != DrawOverCharSprite) && + (objcache[aa].image != nullptr) && + (objcache[aa].sppic == objs[aa].num) && + (actsps[useindx] != nullptr)) { + // HW acceleration + objcache[aa].tintamntwas = tint_level; + objcache[aa].tintredwas = tint_red; + objcache[aa].tintgrnwas = tint_green; + objcache[aa].tintbluwas = tint_blue; + objcache[aa].tintlightwas = tint_light; + objcache[aa].lightlevwas = light_level; + objcache[aa].zoomWas = zoom_level; + objcache[aa].mirroredWas = isMirrored; + + return 1; + } + + if ((!hardwareAccelerated) && (gfxDriver->HasAcceleratedTransform())) { + // They want to draw it in software mode with the D3D driver, + // so force a redraw + objcache[aa].sppic = -389538; + } + + // If we have the image cached, use it + if ((objcache[aa].image != nullptr) && + (objcache[aa].sppic == objs[aa].num) && + (objcache[aa].tintamntwas == tint_level) && + (objcache[aa].tintlightwas == tint_light) && + (objcache[aa].tintredwas == tint_red) && + (objcache[aa].tintgrnwas == tint_green) && + (objcache[aa].tintbluwas == tint_blue) && + (objcache[aa].lightlevwas == light_level) && + (objcache[aa].zoomWas == zoom_level) && + (objcache[aa].mirroredWas == isMirrored)) { + // the image is the same, we can use it cached! + if ((walkBehindMethod != DrawOverCharSprite) && + (actsps[useindx] != nullptr)) + return 1; + // Check if the X & Y co-ords are the same, too -- if so, there + // is scope for further optimisations + if ((objcache[aa].xwas == objs[aa].x) && + (objcache[aa].ywas == objs[aa].y) && + (actsps[useindx] != nullptr) && + (walk_behind_baselines_changed == 0)) + return 1; + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, sprwidth, sprheight); + actsps[useindx]->Blit(objcache[aa].image, 0, 0, 0, 0, objcache[aa].image->GetWidth(), objcache[aa].image->GetHeight()); + return 0; + } + + // Not cached, so draw the image + + int actspsUsed = 0; + if (!hardwareAccelerated) { + // draw the base sprite, scaled and flipped as appropriate + actspsUsed = scale_and_flip_sprite(useindx, coldept, zoom_level, + objs[aa].num, sprwidth, sprheight, isMirrored); + } else { + // ensure actsps exists + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, game.SpriteInfos[objs[aa].num].Width, game.SpriteInfos[objs[aa].num].Height); + } + + // direct read from source bitmap, where possible + Bitmap *comeFrom = nullptr; + if (!actspsUsed) + comeFrom = spriteset[objs[aa].num]; + + // apply tints or lightenings where appropriate, else just copy + // the source bitmap + if (!hardwareAccelerated && ((tint_level > 0) || (light_level != 0))) { + apply_tint_or_light(useindx, light_level, tint_level, tint_red, + tint_green, tint_blue, tint_light, coldept, + comeFrom); + } else if (!actspsUsed) { + actsps[useindx]->Blit(spriteset[objs[aa].num], 0, 0, 0, 0, game.SpriteInfos[objs[aa].num].Width, game.SpriteInfos[objs[aa].num].Height); + } + + // Re-use the bitmap if it's the same size + objcache[aa].image = recycle_bitmap(objcache[aa].image, coldept, sprwidth, sprheight); + // Create the cached image and store it + objcache[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, sprwidth, sprheight); + objcache[aa].sppic = objs[aa].num; + objcache[aa].tintamntwas = tint_level; + objcache[aa].tintredwas = tint_red; + objcache[aa].tintgrnwas = tint_green; + objcache[aa].tintbluwas = tint_blue; + objcache[aa].tintlightwas = tint_light; + objcache[aa].lightlevwas = light_level; + objcache[aa].zoomWas = zoom_level; + objcache[aa].mirroredWas = isMirrored; + return 0; } @@ -1624,440 +1478,395 @@ int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysU // This is only called from draw_screen_background, but it's seperated // to help with profiling the program void prepare_objects_for_drawing() { - our_eip=32; - - for (int aa=0; aanumobj; aa++) { - if (objs[aa].on != 1) continue; - // offscreen, don't draw - if ((objs[aa].x >= thisroom.Width) || (objs[aa].y < 1)) - continue; - - const int useindx = aa; - int tehHeight; - int actspsIntact = construct_object_gfx(aa, nullptr, &tehHeight, false); - - // update the cache for next time - objcache[aa].xwas = objs[aa].x; - objcache[aa].ywas = objs[aa].y; - int atxp = data_to_game_coord(objs[aa].x); - int atyp = data_to_game_coord(objs[aa].y) - tehHeight; - - int usebasel = objs[aa].get_baseline(); - - if (objs[aa].flags & OBJF_NOWALKBEHINDS) { - // ignore walk-behinds, do nothing - if (walkBehindMethod == DrawAsSeparateSprite) - { - usebasel += thisroom.Height; - } - } - else if (walkBehindMethod == DrawAsSeparateCharSprite) - { - sort_out_char_sprite_walk_behind(useindx, atxp, atyp, usebasel, objs[aa].zoom, objs[aa].last_width, objs[aa].last_height); - } - else if ((!actspsIntact) && (walkBehindMethod == DrawOverCharSprite)) - { - sort_out_walk_behinds(actsps[useindx], atxp, atyp, usebasel); - } - - if ((!actspsIntact) || (actspsbmp[useindx] == nullptr)) - { - bool hasAlpha = (game.SpriteInfos[objs[aa].num].Flags & SPF_ALPHACHANNEL) != 0; - - if (actspsbmp[useindx] != nullptr) - gfxDriver->DestroyDDB(actspsbmp[useindx]); - actspsbmp[useindx] = gfxDriver->CreateDDBFromBitmap(actsps[useindx], hasAlpha); - } - - if (gfxDriver->HasAcceleratedTransform()) - { - actspsbmp[useindx]->SetFlippedLeftRight(objcache[aa].mirroredWas != 0); - actspsbmp[useindx]->SetStretch(objs[aa].last_width, objs[aa].last_height); - actspsbmp[useindx]->SetTint(objcache[aa].tintredwas, objcache[aa].tintgrnwas, objcache[aa].tintbluwas, (objcache[aa].tintamntwas * 256) / 100); - - if (objcache[aa].tintamntwas > 0) - { - if (objcache[aa].tintlightwas == 0) // luminance of 0 -- pass 1 to enable - actspsbmp[useindx]->SetLightLevel(1); - else if (objcache[aa].tintlightwas < 250) - actspsbmp[useindx]->SetLightLevel(objcache[aa].tintlightwas); - else - actspsbmp[useindx]->SetLightLevel(0); - } - else if (objcache[aa].lightlevwas != 0) - actspsbmp[useindx]->SetLightLevel((objcache[aa].lightlevwas * 25) / 10 + 256); - else - actspsbmp[useindx]->SetLightLevel(0); - } - - add_to_sprite_list(actspsbmp[useindx], atxp, atyp, usebasel, objs[aa].transparent,objs[aa].num); - } + our_eip = 32; + + for (int aa = 0; aa < croom->numobj; aa++) { + if (objs[aa].on != 1) continue; + // offscreen, don't draw + if ((objs[aa].x >= thisroom.Width) || (objs[aa].y < 1)) + continue; + + const int useindx = aa; + int tehHeight; + int actspsIntact = construct_object_gfx(aa, nullptr, &tehHeight, false); + + // update the cache for next time + objcache[aa].xwas = objs[aa].x; + objcache[aa].ywas = objs[aa].y; + int atxp = data_to_game_coord(objs[aa].x); + int atyp = data_to_game_coord(objs[aa].y) - tehHeight; + + int usebasel = objs[aa].get_baseline(); + + if (objs[aa].flags & OBJF_NOWALKBEHINDS) { + // ignore walk-behinds, do nothing + if (walkBehindMethod == DrawAsSeparateSprite) { + usebasel += thisroom.Height; + } + } else if (walkBehindMethod == DrawAsSeparateCharSprite) { + sort_out_char_sprite_walk_behind(useindx, atxp, atyp, usebasel, objs[aa].zoom, objs[aa].last_width, objs[aa].last_height); + } else if ((!actspsIntact) && (walkBehindMethod == DrawOverCharSprite)) { + sort_out_walk_behinds(actsps[useindx], atxp, atyp, usebasel); + } + + if ((!actspsIntact) || (actspsbmp[useindx] == nullptr)) { + bool hasAlpha = (game.SpriteInfos[objs[aa].num].Flags & SPF_ALPHACHANNEL) != 0; + + if (actspsbmp[useindx] != nullptr) + gfxDriver->DestroyDDB(actspsbmp[useindx]); + actspsbmp[useindx] = gfxDriver->CreateDDBFromBitmap(actsps[useindx], hasAlpha); + } + + if (gfxDriver->HasAcceleratedTransform()) { + actspsbmp[useindx]->SetFlippedLeftRight(objcache[aa].mirroredWas != 0); + actspsbmp[useindx]->SetStretch(objs[aa].last_width, objs[aa].last_height); + actspsbmp[useindx]->SetTint(objcache[aa].tintredwas, objcache[aa].tintgrnwas, objcache[aa].tintbluwas, (objcache[aa].tintamntwas * 256) / 100); + + if (objcache[aa].tintamntwas > 0) { + if (objcache[aa].tintlightwas == 0) // luminance of 0 -- pass 1 to enable + actspsbmp[useindx]->SetLightLevel(1); + else if (objcache[aa].tintlightwas < 250) + actspsbmp[useindx]->SetLightLevel(objcache[aa].tintlightwas); + else + actspsbmp[useindx]->SetLightLevel(0); + } else if (objcache[aa].lightlevwas != 0) + actspsbmp[useindx]->SetLightLevel((objcache[aa].lightlevwas * 25) / 10 + 256); + else + actspsbmp[useindx]->SetLightLevel(0); + } + + add_to_sprite_list(actspsbmp[useindx], atxp, atyp, usebasel, objs[aa].transparent, objs[aa].num); + } } // Draws srcimg onto destimg, tinting to the specified level // Totally overwrites the contents of the destination image -void tint_image (Bitmap *ds, Bitmap *srcimg, int red, int grn, int blu, int light_level, int luminance) { - - if ((srcimg->GetColorDepth() != ds->GetColorDepth()) || - (srcimg->GetColorDepth() <= 8)) { - debug_script_warn("Image tint failed - images must both be hi-color"); - // the caller expects something to have been copied - ds->Blit(srcimg, 0, 0, 0, 0, srcimg->GetWidth(), srcimg->GetHeight()); - return; - } - - // For performance reasons, we have a seperate blender for - // when light is being adjusted and when it is not. - // If luminance >= 250, then normal brightness, otherwise darken - if (luminance >= 250) - set_blender_mode (_myblender_color15, _myblender_color16, _myblender_color32, red, grn, blu, 0); - else - set_blender_mode (_myblender_color15_light, _myblender_color16_light, _myblender_color32_light, red, grn, blu, 0); - - if (light_level >= 100) { - // fully colourised - ds->FillTransparent(); - ds->LitBlendBlt(srcimg, 0, 0, luminance); - } - else { - // light_level is between -100 and 100 normally; 0-100 in - // this case when it's a RGB tint - light_level = (light_level * 25) / 10; - - // Copy the image to the new bitmap - ds->Blit(srcimg, 0, 0, 0, 0, srcimg->GetWidth(), srcimg->GetHeight()); - // Render the colourised image to a temporary bitmap, - // then transparently draw it over the original image - Bitmap *finaltarget = BitmapHelper::CreateTransparentBitmap(srcimg->GetWidth(), srcimg->GetHeight(), srcimg->GetColorDepth()); - finaltarget->LitBlendBlt(srcimg, 0, 0, luminance); - - // customized trans blender to preserve alpha channel - set_my_trans_blender (0, 0, 0, light_level); - ds->TransBlendBlt (finaltarget, 0, 0); - delete finaltarget; - } +void tint_image(Bitmap *ds, Bitmap *srcimg, int red, int grn, int blu, int light_level, int luminance) { + + if ((srcimg->GetColorDepth() != ds->GetColorDepth()) || + (srcimg->GetColorDepth() <= 8)) { + debug_script_warn("Image tint failed - images must both be hi-color"); + // the caller expects something to have been copied + ds->Blit(srcimg, 0, 0, 0, 0, srcimg->GetWidth(), srcimg->GetHeight()); + return; + } + + // For performance reasons, we have a seperate blender for + // when light is being adjusted and when it is not. + // If luminance >= 250, then normal brightness, otherwise darken + if (luminance >= 250) + set_blender_mode(_myblender_color15, _myblender_color16, _myblender_color32, red, grn, blu, 0); + else + set_blender_mode(_myblender_color15_light, _myblender_color16_light, _myblender_color32_light, red, grn, blu, 0); + + if (light_level >= 100) { + // fully colourised + ds->FillTransparent(); + ds->LitBlendBlt(srcimg, 0, 0, luminance); + } else { + // light_level is between -100 and 100 normally; 0-100 in + // this case when it's a RGB tint + light_level = (light_level * 25) / 10; + + // Copy the image to the new bitmap + ds->Blit(srcimg, 0, 0, 0, 0, srcimg->GetWidth(), srcimg->GetHeight()); + // Render the colourised image to a temporary bitmap, + // then transparently draw it over the original image + Bitmap *finaltarget = BitmapHelper::CreateTransparentBitmap(srcimg->GetWidth(), srcimg->GetHeight(), srcimg->GetColorDepth()); + finaltarget->LitBlendBlt(srcimg, 0, 0, luminance); + + // customized trans blender to preserve alpha channel + set_my_trans_blender(0, 0, 0, light_level); + ds->TransBlendBlt(finaltarget, 0, 0); + delete finaltarget; + } } void prepare_characters_for_drawing() { - int zoom_level,newwidth,newheight,onarea,sppic; - int light_level,coldept; - int tint_red, tint_green, tint_blue, tint_amount, tint_light = 255; - - our_eip=33; - - // draw characters - for (int aa=0; aa < game.numcharacters; aa++) { - if (game.chars[aa].on==0) continue; - if (game.chars[aa].room!=displayed_room) continue; - eip_guinum = aa; - const int useindx = aa + MAX_ROOM_OBJECTS; - - CharacterInfo*chin=&game.chars[aa]; - our_eip = 330; - // if it's on but set to view -1, they're being silly - if (chin->view < 0) { - quitprintf("!The character '%s' was turned on in the current room (room %d) but has not been assigned a view number.", - chin->name, displayed_room); - } - - if (chin->frame >= views[chin->view].loops[chin->loop].numFrames) - chin->frame = 0; - - if ((chin->loop >= views[chin->view].numLoops) || - (views[chin->view].loops[chin->loop].numFrames < 1)) { - quitprintf("!The character '%s' could not be displayed because there were no frames in loop %d of view %d.", - chin->name, chin->loop, chin->view + 1); - } - - sppic=views[chin->view].loops[chin->loop].frames[chin->frame].pic; - if (sppic < 0) - sppic = 0; // in case it's screwed up somehow - our_eip = 331; - // sort out the stretching if required - onarea = get_walkable_area_at_character (aa); - our_eip = 332; - - // calculate the zoom level - if (chin->flags & CHF_MANUALSCALING) // character ignores scaling - zoom_level = charextra[aa].zoom; - else if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) { - zoom_level = charextra[aa].zoom; - // NOTE: room objects don't have this fix - if (zoom_level == 0) - zoom_level = 100; - } - else - zoom_level = get_area_scaling (onarea, chin->x, chin->y); - - charextra[aa].zoom = zoom_level; - - tint_red = tint_green = tint_blue = tint_amount = tint_light = light_level = 0; - - if (chin->flags & CHF_HASTINT) { - // object specific tint, use it - tint_red = charextra[aa].tint_r; - tint_green = charextra[aa].tint_g; - tint_blue = charextra[aa].tint_b; - tint_amount = charextra[aa].tint_level; - tint_light = charextra[aa].tint_light; - light_level = 0; - } - else if (chin->flags & CHF_HASLIGHT) - { - light_level = charextra[aa].tint_light; - } - else { - get_local_tint(chin->x, chin->y, chin->flags & CHF_NOLIGHTING, - &tint_amount, &tint_red, &tint_green, &tint_blue, - &tint_light, &light_level); - } - - our_eip = 3330; - int isMirrored = 0, specialpic = sppic; - bool usingCachedImage = false; - - coldept = spriteset[sppic]->GetColorDepth(); - - // adjust the sppic if mirrored, so it doesn't accidentally - // cache the mirrored frame as the real one - if (views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE) { - isMirrored = 1; - specialpic = -sppic; - } - - our_eip = 3331; - - // if the character was the same sprite and scaling last time, - // just use the cached image - if ((charcache[aa].inUse) && - (charcache[aa].sppic == specialpic) && - (charcache[aa].scaling == zoom_level) && - (charcache[aa].tintredwas == tint_red) && - (charcache[aa].tintgrnwas == tint_green) && - (charcache[aa].tintbluwas == tint_blue) && - (charcache[aa].tintamntwas == tint_amount) && - (charcache[aa].tintlightwas == tint_light) && - (charcache[aa].lightlevwas == light_level)) - { - if (walkBehindMethod == DrawOverCharSprite) - { - actsps[useindx] = recycle_bitmap(actsps[useindx], charcache[aa].image->GetColorDepth(), charcache[aa].image->GetWidth(), charcache[aa].image->GetHeight()); - actsps[useindx]->Blit (charcache[aa].image, 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); - } - else - { - usingCachedImage = true; - } - } - else if ((charcache[aa].inUse) && - (charcache[aa].sppic == specialpic) && - (gfxDriver->HasAcceleratedTransform())) - { - usingCachedImage = true; - } - else if (charcache[aa].inUse) { - //destroy_bitmap (charcache[aa].image); - charcache[aa].inUse = 0; - } - - our_eip = 3332; - - if (zoom_level != 100) { - // it needs to be stretched, so calculate the new dimensions - - scale_sprite_size(sppic, zoom_level, &newwidth, &newheight); - charextra[aa].width=newwidth; - charextra[aa].height=newheight; - } - else { - // draw at original size, so just use the sprite width and height - // TODO: store width and height always, that's much simplier to use for reference! - charextra[aa].width=0; - charextra[aa].height=0; - newwidth = game.SpriteInfos[sppic].Width; - newheight = game.SpriteInfos[sppic].Height; - } - - our_eip = 3336; - - // Calculate the X & Y co-ordinates of where the sprite will be - const int atxp =(data_to_game_coord(chin->x)) - newwidth/2; - const int atyp =(data_to_game_coord(chin->y) - newheight) - // adjust the Y positioning for the character's Z co-ord - - data_to_game_coord(chin->z); - - charcache[aa].scaling = zoom_level; - charcache[aa].sppic = specialpic; - charcache[aa].tintredwas = tint_red; - charcache[aa].tintgrnwas = tint_green; - charcache[aa].tintbluwas = tint_blue; - charcache[aa].tintamntwas = tint_amount; - charcache[aa].tintlightwas = tint_light; - charcache[aa].lightlevwas = light_level; - - // If cache needs to be re-drawn - if (!charcache[aa].inUse) { - - // create the base sprite in actsps[useindx], which will - // be scaled and/or flipped, as appropriate - int actspsUsed = 0; - if (!gfxDriver->HasAcceleratedTransform()) - { - actspsUsed = scale_and_flip_sprite( - useindx, coldept, zoom_level, sppic, - newwidth, newheight, isMirrored); - } - else - { - // ensure actsps exists - actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, game.SpriteInfos[sppic].Width, game.SpriteInfos[sppic].Height); - } - - our_eip = 335; - - if (((light_level != 0) || (tint_amount != 0)) && - (!gfxDriver->HasAcceleratedTransform())) { - // apply the lightening or tinting - Bitmap *comeFrom = nullptr; - // if possible, direct read from the source image - if (!actspsUsed) - comeFrom = spriteset[sppic]; - - apply_tint_or_light(useindx, light_level, tint_amount, tint_red, - tint_green, tint_blue, tint_light, coldept, - comeFrom); - } - else if (!actspsUsed) { - // no scaling, flipping or tinting was done, so just blit it normally - actsps[useindx]->Blit (spriteset[sppic], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); - } - - // update the character cache with the new image - charcache[aa].inUse = 1; - //charcache[aa].image = BitmapHelper::CreateBitmap_ (coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); - charcache[aa].image = recycle_bitmap(charcache[aa].image, coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); - charcache[aa].image->Blit (actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); - - } // end if !cache.inUse - - int usebasel = chin->get_baseline(); - - our_eip = 336; - - const int bgX = atxp + chin->pic_xoffs; - const int bgY = atyp + chin->pic_yoffs; - - if (chin->flags & CHF_NOWALKBEHINDS) { - // ignore walk-behinds, do nothing - if (walkBehindMethod == DrawAsSeparateSprite) - { - usebasel += thisroom.Height; - } - } - else if (walkBehindMethod == DrawAsSeparateCharSprite) - { - sort_out_char_sprite_walk_behind(useindx, bgX, bgY, usebasel, charextra[aa].zoom, newwidth, newheight); - } - else if (walkBehindMethod == DrawOverCharSprite) - { - sort_out_walk_behinds(actsps[useindx], bgX, bgY, usebasel); - } - - if ((!usingCachedImage) || (actspsbmp[useindx] == nullptr)) - { - bool hasAlpha = (game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) != 0; - - actspsbmp[useindx] = recycle_ddb_bitmap(actspsbmp[useindx], actsps[useindx], hasAlpha); - } - - if (gfxDriver->HasAcceleratedTransform()) - { - actspsbmp[useindx]->SetStretch(newwidth, newheight); - actspsbmp[useindx]->SetFlippedLeftRight(isMirrored != 0); - actspsbmp[useindx]->SetTint(tint_red, tint_green, tint_blue, (tint_amount * 256) / 100); - - if (tint_amount != 0) - { - if (tint_light == 0) // tint with 0 luminance, pass as 1 instead - actspsbmp[useindx]->SetLightLevel(1); - else if (tint_light < 250) - actspsbmp[useindx]->SetLightLevel(tint_light); - else - actspsbmp[useindx]->SetLightLevel(0); - } - else if (light_level != 0) - actspsbmp[useindx]->SetLightLevel((light_level * 25) / 10 + 256); - else - actspsbmp[useindx]->SetLightLevel(0); - - } - - our_eip = 337; - - chin->actx = atxp; - chin->acty = atyp; - - add_to_sprite_list(actspsbmp[useindx], bgX, bgY, usebasel, chin->transparency, sppic); - } + int zoom_level, newwidth, newheight, onarea, sppic; + int light_level, coldept; + int tint_red, tint_green, tint_blue, tint_amount, tint_light = 255; + + our_eip = 33; + + // draw characters + for (int aa = 0; aa < game.numcharacters; aa++) { + if (game.chars[aa].on == 0) continue; + if (game.chars[aa].room != displayed_room) continue; + eip_guinum = aa; + const int useindx = aa + MAX_ROOM_OBJECTS; + + CharacterInfo *chin = &game.chars[aa]; + our_eip = 330; + // if it's on but set to view -1, they're being silly + if (chin->view < 0) { + quitprintf("!The character '%s' was turned on in the current room (room %d) but has not been assigned a view number.", + chin->name, displayed_room); + } + + if (chin->frame >= views[chin->view].loops[chin->loop].numFrames) + chin->frame = 0; + + if ((chin->loop >= views[chin->view].numLoops) || + (views[chin->view].loops[chin->loop].numFrames < 1)) { + quitprintf("!The character '%s' could not be displayed because there were no frames in loop %d of view %d.", + chin->name, chin->loop, chin->view + 1); + } + + sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic; + if (sppic < 0) + sppic = 0; // in case it's screwed up somehow + our_eip = 331; + // sort out the stretching if required + onarea = get_walkable_area_at_character(aa); + our_eip = 332; + + // calculate the zoom level + if (chin->flags & CHF_MANUALSCALING) // character ignores scaling + zoom_level = charextra[aa].zoom; + else if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) { + zoom_level = charextra[aa].zoom; + // NOTE: room objects don't have this fix + if (zoom_level == 0) + zoom_level = 100; + } else + zoom_level = get_area_scaling(onarea, chin->x, chin->y); + + charextra[aa].zoom = zoom_level; + + tint_red = tint_green = tint_blue = tint_amount = tint_light = light_level = 0; + + if (chin->flags & CHF_HASTINT) { + // object specific tint, use it + tint_red = charextra[aa].tint_r; + tint_green = charextra[aa].tint_g; + tint_blue = charextra[aa].tint_b; + tint_amount = charextra[aa].tint_level; + tint_light = charextra[aa].tint_light; + light_level = 0; + } else if (chin->flags & CHF_HASLIGHT) { + light_level = charextra[aa].tint_light; + } else { + get_local_tint(chin->x, chin->y, chin->flags & CHF_NOLIGHTING, + &tint_amount, &tint_red, &tint_green, &tint_blue, + &tint_light, &light_level); + } + + our_eip = 3330; + int isMirrored = 0, specialpic = sppic; + bool usingCachedImage = false; + + coldept = spriteset[sppic]->GetColorDepth(); + + // adjust the sppic if mirrored, so it doesn't accidentally + // cache the mirrored frame as the real one + if (views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE) { + isMirrored = 1; + specialpic = -sppic; + } + + our_eip = 3331; + + // if the character was the same sprite and scaling last time, + // just use the cached image + if ((charcache[aa].inUse) && + (charcache[aa].sppic == specialpic) && + (charcache[aa].scaling == zoom_level) && + (charcache[aa].tintredwas == tint_red) && + (charcache[aa].tintgrnwas == tint_green) && + (charcache[aa].tintbluwas == tint_blue) && + (charcache[aa].tintamntwas == tint_amount) && + (charcache[aa].tintlightwas == tint_light) && + (charcache[aa].lightlevwas == light_level)) { + if (walkBehindMethod == DrawOverCharSprite) { + actsps[useindx] = recycle_bitmap(actsps[useindx], charcache[aa].image->GetColorDepth(), charcache[aa].image->GetWidth(), charcache[aa].image->GetHeight()); + actsps[useindx]->Blit(charcache[aa].image, 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + } else { + usingCachedImage = true; + } + } else if ((charcache[aa].inUse) && + (charcache[aa].sppic == specialpic) && + (gfxDriver->HasAcceleratedTransform())) { + usingCachedImage = true; + } else if (charcache[aa].inUse) { + //destroy_bitmap (charcache[aa].image); + charcache[aa].inUse = 0; + } + + our_eip = 3332; + + if (zoom_level != 100) { + // it needs to be stretched, so calculate the new dimensions + + scale_sprite_size(sppic, zoom_level, &newwidth, &newheight); + charextra[aa].width = newwidth; + charextra[aa].height = newheight; + } else { + // draw at original size, so just use the sprite width and height + // TODO: store width and height always, that's much simplier to use for reference! + charextra[aa].width = 0; + charextra[aa].height = 0; + newwidth = game.SpriteInfos[sppic].Width; + newheight = game.SpriteInfos[sppic].Height; + } + + our_eip = 3336; + + // Calculate the X & Y co-ordinates of where the sprite will be + const int atxp = (data_to_game_coord(chin->x)) - newwidth / 2; + const int atyp = (data_to_game_coord(chin->y) - newheight) + // adjust the Y positioning for the character's Z co-ord + - data_to_game_coord(chin->z); + + charcache[aa].scaling = zoom_level; + charcache[aa].sppic = specialpic; + charcache[aa].tintredwas = tint_red; + charcache[aa].tintgrnwas = tint_green; + charcache[aa].tintbluwas = tint_blue; + charcache[aa].tintamntwas = tint_amount; + charcache[aa].tintlightwas = tint_light; + charcache[aa].lightlevwas = light_level; + + // If cache needs to be re-drawn + if (!charcache[aa].inUse) { + + // create the base sprite in actsps[useindx], which will + // be scaled and/or flipped, as appropriate + int actspsUsed = 0; + if (!gfxDriver->HasAcceleratedTransform()) { + actspsUsed = scale_and_flip_sprite( + useindx, coldept, zoom_level, sppic, + newwidth, newheight, isMirrored); + } else { + // ensure actsps exists + actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, game.SpriteInfos[sppic].Width, game.SpriteInfos[sppic].Height); + } + + our_eip = 335; + + if (((light_level != 0) || (tint_amount != 0)) && + (!gfxDriver->HasAcceleratedTransform())) { + // apply the lightening or tinting + Bitmap *comeFrom = nullptr; + // if possible, direct read from the source image + if (!actspsUsed) + comeFrom = spriteset[sppic]; + + apply_tint_or_light(useindx, light_level, tint_amount, tint_red, + tint_green, tint_blue, tint_light, coldept, + comeFrom); + } else if (!actspsUsed) { + // no scaling, flipping or tinting was done, so just blit it normally + actsps[useindx]->Blit(spriteset[sppic], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + } + + // update the character cache with the new image + charcache[aa].inUse = 1; + //charcache[aa].image = BitmapHelper::CreateBitmap_ (coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + charcache[aa].image = recycle_bitmap(charcache[aa].image, coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + charcache[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); + + } // end if !cache.inUse + + int usebasel = chin->get_baseline(); + + our_eip = 336; + + const int bgX = atxp + chin->pic_xoffs; + const int bgY = atyp + chin->pic_yoffs; + + if (chin->flags & CHF_NOWALKBEHINDS) { + // ignore walk-behinds, do nothing + if (walkBehindMethod == DrawAsSeparateSprite) { + usebasel += thisroom.Height; + } + } else if (walkBehindMethod == DrawAsSeparateCharSprite) { + sort_out_char_sprite_walk_behind(useindx, bgX, bgY, usebasel, charextra[aa].zoom, newwidth, newheight); + } else if (walkBehindMethod == DrawOverCharSprite) { + sort_out_walk_behinds(actsps[useindx], bgX, bgY, usebasel); + } + + if ((!usingCachedImage) || (actspsbmp[useindx] == nullptr)) { + bool hasAlpha = (game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) != 0; + + actspsbmp[useindx] = recycle_ddb_bitmap(actspsbmp[useindx], actsps[useindx], hasAlpha); + } + + if (gfxDriver->HasAcceleratedTransform()) { + actspsbmp[useindx]->SetStretch(newwidth, newheight); + actspsbmp[useindx]->SetFlippedLeftRight(isMirrored != 0); + actspsbmp[useindx]->SetTint(tint_red, tint_green, tint_blue, (tint_amount * 256) / 100); + + if (tint_amount != 0) { + if (tint_light == 0) // tint with 0 luminance, pass as 1 instead + actspsbmp[useindx]->SetLightLevel(1); + else if (tint_light < 250) + actspsbmp[useindx]->SetLightLevel(tint_light); + else + actspsbmp[useindx]->SetLightLevel(0); + } else if (light_level != 0) + actspsbmp[useindx]->SetLightLevel((light_level * 25) / 10 + 256); + else + actspsbmp[useindx]->SetLightLevel(0); + + } + + our_eip = 337; + + chin->actx = atxp; + chin->acty = atyp; + + add_to_sprite_list(actspsbmp[useindx], bgX, bgY, usebasel, chin->transparency, sppic); + } } // Compiles a list of room sprites (characters, objects, background) -void prepare_room_sprites() -{ - // Background sprite is required for the non-software renderers always, - // and for software renderer in case there are overlapping viewports. - // Note that software DDB is just a tiny wrapper around bitmap, so overhead is negligible. - if (roomBackgroundBmp == nullptr) - { - update_polled_stuff_if_runtime(); - roomBackgroundBmp = gfxDriver->CreateDDBFromBitmap(thisroom.BgFrames[play.bg_frame].Graphic.get(), false, true); - } - else if (current_background_is_dirty) - { - update_polled_stuff_if_runtime(); - gfxDriver->UpdateDDBFromBitmap(roomBackgroundBmp, thisroom.BgFrames[play.bg_frame].Graphic.get(), false); - } - if (gfxDriver->RequiresFullRedrawEachFrame()) - { - if (current_background_is_dirty || walkBehindsCachedForBgNum != play.bg_frame) - { - if (walkBehindMethod == DrawAsSeparateSprite) - { - update_walk_behind_images(); - } - } - add_thing_to_draw(roomBackgroundBmp, 0, 0, 0, false); - } - current_background_is_dirty = false; // Note this is only place where this flag is checked - - clear_sprite_list(); - - if ((debug_flags & DBG_NOOBJECTS) == 0) - { - prepare_objects_for_drawing(); - prepare_characters_for_drawing(); - - if ((debug_flags & DBG_NODRAWSPRITES) == 0) - { - our_eip = 34; - draw_sprite_list(); - } - } - our_eip = 36; +void prepare_room_sprites() { + // Background sprite is required for the non-software renderers always, + // and for software renderer in case there are overlapping viewports. + // Note that software DDB is just a tiny wrapper around bitmap, so overhead is negligible. + if (roomBackgroundBmp == nullptr) { + update_polled_stuff_if_runtime(); + roomBackgroundBmp = gfxDriver->CreateDDBFromBitmap(thisroom.BgFrames[play.bg_frame].Graphic.get(), false, true); + } else if (current_background_is_dirty) { + update_polled_stuff_if_runtime(); + gfxDriver->UpdateDDBFromBitmap(roomBackgroundBmp, thisroom.BgFrames[play.bg_frame].Graphic.get(), false); + } + if (gfxDriver->RequiresFullRedrawEachFrame()) { + if (current_background_is_dirty || walkBehindsCachedForBgNum != play.bg_frame) { + if (walkBehindMethod == DrawAsSeparateSprite) { + update_walk_behind_images(); + } + } + add_thing_to_draw(roomBackgroundBmp, 0, 0, 0, false); + } + current_background_is_dirty = false; // Note this is only place where this flag is checked + + clear_sprite_list(); + + if ((debug_flags & DBG_NOOBJECTS) == 0) { + prepare_objects_for_drawing(); + prepare_characters_for_drawing(); + + if ((debug_flags & DBG_NODRAWSPRITES) == 0) { + our_eip = 34; + draw_sprite_list(); + } + } + our_eip = 36; } // Draws the black surface behind (or rather between) the room viewports -void draw_preroom_background() -{ - if (gfxDriver->RequiresFullRedrawEachFrame()) - return; - update_black_invreg_and_reset(gfxDriver->GetMemoryBackBuffer()); +void draw_preroom_background() { + if (gfxDriver->RequiresFullRedrawEachFrame()) + return; + update_black_invreg_and_reset(gfxDriver->GetMemoryBackBuffer()); } // Draws the room background on the given surface. @@ -2067,505 +1876,460 @@ void draw_preroom_background() // ds and roomcam_surface may be the same bitmap. // no_transform flag tells to copy dirty regions on roomcam_surface without any coordinate conversion // whatsoever. -PBitmap draw_room_background(Viewport *view, const SpriteTransform &room_trans) -{ - our_eip = 31; - - // For the sake of software renderer, if there is any kind of camera transform required - // except screen offset, we tell it to draw on separate bitmap first with zero transformation. - // There are few reasons for this, primary is that Allegro does not support StretchBlt - // between different colour depths (i.e. it won't correctly stretch blit 16-bit rooms to - // 32-bit virtual screen). - // Also see comment to ALSoftwareGraphicsDriver::RenderToBackBuffer(). - const int view_index = view->GetID(); - Bitmap *ds = gfxDriver->GetMemoryBackBuffer(); - // If separate bitmap was prepared for this view/camera pair then use it, draw untransformed - // and blit transformed whole surface later. - const bool draw_to_camsurf = CameraDrawData[view_index].Frame != nullptr; - Bitmap *roomcam_surface = draw_to_camsurf ? CameraDrawData[view_index].Frame.get() : ds; - { - // For software renderer: copy dirty rects onto the virtual screen. - // TODO: that would be SUPER NICE to reorganize the code and move this operation into SoftwareGraphicDriver somehow. - // Because basically we duplicate sprite batch transform here. - - auto camera = view->GetCamera(); - set_invalidrects_cameraoffs(view_index, camera->GetRect().Left, camera->GetRect().Top); - - // TODO: (by CJ) - // the following line takes up to 50% of the game CPU time at - // high resolutions and colour depths - if we can optimise it - // somehow, significant performance gains to be had - update_room_invreg_and_reset(view_index, roomcam_surface, thisroom.BgFrames[play.bg_frame].Graphic.get(), draw_to_camsurf); - } - - return CameraDrawData[view_index].Frame; -} - - -void draw_fps(const Rect &viewport) -{ - // TODO: make allocated "fps struct" instead of using static vars!! - static IDriverDependantBitmap* ddb = nullptr; - static Bitmap *fpsDisplay = nullptr; - const int font = FONT_NORMAL; - if (fpsDisplay == nullptr) - { - fpsDisplay = BitmapHelper::CreateBitmap(viewport.GetWidth(), (getfontheight_outlined(font) + get_fixed_pixel_size(5)), game.GetColorDepth()); - fpsDisplay = ReplaceBitmapWithSupportedFormat(fpsDisplay); - } - fpsDisplay->ClearTransparent(); - - color_t text_color = fpsDisplay->GetCompatibleColor(14); - - char base_buffer[20]; - if (!isTimerFpsMaxed()) { - sprintf(base_buffer, "%d", frames_per_second); - } else { - sprintf(base_buffer, "unlimited"); - } - - char fps_buffer[60]; - // Don't display fps if we don't have enough information (because loop count was just reset) - if (!std::isnan(fps)) { - snprintf(fps_buffer, sizeof(fps_buffer), "FPS: %2.1f / %s", fps, base_buffer); - } else { - snprintf(fps_buffer, sizeof(fps_buffer), "FPS: --.- / %s", base_buffer); - } - wouttext_outline(fpsDisplay, 1, 1, font, text_color, fps_buffer); - - char loop_buffer[60]; - sprintf(loop_buffer, "Loop %u", loopcounter); - wouttext_outline(fpsDisplay, viewport.GetWidth() / 2, 1, font, text_color, loop_buffer); - - if (ddb) - gfxDriver->UpdateDDBFromBitmap(ddb, fpsDisplay, false); - else - ddb = gfxDriver->CreateDDBFromBitmap(fpsDisplay, false); - int yp = viewport.GetHeight() - fpsDisplay->GetHeight(); - gfxDriver->DrawSprite(1, yp, ddb); - invalidate_sprite(1, yp, ddb, false); +PBitmap draw_room_background(Viewport *view, const SpriteTransform &room_trans) { + our_eip = 31; + + // For the sake of software renderer, if there is any kind of camera transform required + // except screen offset, we tell it to draw on separate bitmap first with zero transformation. + // There are few reasons for this, primary is that Allegro does not support StretchBlt + // between different colour depths (i.e. it won't correctly stretch blit 16-bit rooms to + // 32-bit virtual screen). + // Also see comment to ALSoftwareGraphicsDriver::RenderToBackBuffer(). + const int view_index = view->GetID(); + Bitmap *ds = gfxDriver->GetMemoryBackBuffer(); + // If separate bitmap was prepared for this view/camera pair then use it, draw untransformed + // and blit transformed whole surface later. + const bool draw_to_camsurf = CameraDrawData[view_index].Frame != nullptr; + Bitmap *roomcam_surface = draw_to_camsurf ? CameraDrawData[view_index].Frame.get() : ds; + { + // For software renderer: copy dirty rects onto the virtual screen. + // TODO: that would be SUPER NICE to reorganize the code and move this operation into SoftwareGraphicDriver somehow. + // Because basically we duplicate sprite batch transform here. + + auto camera = view->GetCamera(); + set_invalidrects_cameraoffs(view_index, camera->GetRect().Left, camera->GetRect().Top); + + // TODO: (by CJ) + // the following line takes up to 50% of the game CPU time at + // high resolutions and colour depths - if we can optimise it + // somehow, significant performance gains to be had + update_room_invreg_and_reset(view_index, roomcam_surface, thisroom.BgFrames[play.bg_frame].Graphic.get(), draw_to_camsurf); + } + + return CameraDrawData[view_index].Frame; +} + + +void draw_fps(const Rect &viewport) { + // TODO: make allocated "fps struct" instead of using static vars!! + static IDriverDependantBitmap *ddb = nullptr; + static Bitmap *fpsDisplay = nullptr; + const int font = FONT_NORMAL; + if (fpsDisplay == nullptr) { + fpsDisplay = BitmapHelper::CreateBitmap(viewport.GetWidth(), (getfontheight_outlined(font) + get_fixed_pixel_size(5)), game.GetColorDepth()); + fpsDisplay = ReplaceBitmapWithSupportedFormat(fpsDisplay); + } + fpsDisplay->ClearTransparent(); + + color_t text_color = fpsDisplay->GetCompatibleColor(14); + + char base_buffer[20]; + if (!isTimerFpsMaxed()) { + sprintf(base_buffer, "%d", frames_per_second); + } else { + sprintf(base_buffer, "unlimited"); + } + + char fps_buffer[60]; + // Don't display fps if we don't have enough information (because loop count was just reset) + if (!std::isnan(fps)) { + snprintf(fps_buffer, sizeof(fps_buffer), "FPS: %2.1f / %s", fps, base_buffer); + } else { + snprintf(fps_buffer, sizeof(fps_buffer), "FPS: --.- / %s", base_buffer); + } + wouttext_outline(fpsDisplay, 1, 1, font, text_color, fps_buffer); + + char loop_buffer[60]; + sprintf(loop_buffer, "Loop %u", loopcounter); + wouttext_outline(fpsDisplay, viewport.GetWidth() / 2, 1, font, text_color, loop_buffer); + + if (ddb) + gfxDriver->UpdateDDBFromBitmap(ddb, fpsDisplay, false); + else + ddb = gfxDriver->CreateDDBFromBitmap(fpsDisplay, false); + int yp = viewport.GetHeight() - fpsDisplay->GetHeight(); + gfxDriver->DrawSprite(1, yp, ddb); + invalidate_sprite(1, yp, ddb, false); } // Draw GUI and overlays of all kinds, anything outside the room space -void draw_gui_and_overlays() -{ - if(pl_any_want_hook(AGSE_PREGUIDRAW)) - add_thing_to_draw(nullptr, AGSE_PREGUIDRAW, 0, TRANS_RUN_PLUGIN, false); - - // draw overlays, except text boxes and portraits - for (const auto &over : screenover) { - // complete overlay draw in non-transparent mode - if (over.type == OVER_COMPLETE) - add_thing_to_draw(over.bmp, over.x, over.y, TRANS_OPAQUE, false); - else if (over.type != OVER_TEXTMSG && over.type != OVER_PICTURE) { - int tdxp, tdyp; - get_overlay_position(over, &tdxp, &tdyp); - add_thing_to_draw(over.bmp, tdxp, tdyp, 0, over.hasAlphaChannel); - } - } - - // Draw GUIs - they should always be on top of overlays like - // speech background text - our_eip=35; - if (((debug_flags & DBG_NOIFACE)==0) && (displayed_room >= 0)) { - int aa; - - if (playerchar->activeinv >= MAX_INV) { - quit("!The player.activeinv variable has been corrupted, probably as a result\n" - "of an incorrect assignment in the game script."); - } - if (playerchar->activeinv < 1) gui_inv_pic=-1; - else gui_inv_pic=game.invinfo[playerchar->activeinv].pic; - our_eip = 37; - if (guis_need_update) { - guis_need_update = 0; - for (aa=0;aaClearTransparent(); - our_eip = 372; - guis[aa].DrawAt(guibg[aa], 0,0); - our_eip = 373; - - bool isAlpha = false; - if (guis[aa].HasAlphaChannel()) - { - isAlpha = true; - - if ((game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Legacy) && (guis[aa].BgImage > 0)) - { - // old-style (pre-3.0.2) GUI alpha rendering - repair_alpha_channel(guibg[aa], spriteset[guis[aa].BgImage]); - } - } - - if (guibgbmp[aa] != nullptr) - { - gfxDriver->UpdateDDBFromBitmap(guibgbmp[aa], guibg[aa], isAlpha); - } - else - { - guibgbmp[aa] = gfxDriver->CreateDDBFromBitmap(guibg[aa], isAlpha); - } - our_eip = 374; - } - } - our_eip = 38; - // Draw the GUIs - for (int gg = 0; gg < game.numgui; gg++) { - aa = play.gui_draw_order[gg]; - if (!guis[aa].IsDisplayed()) continue; - - // Don't draw GUI if "GUIs Turn Off When Disabled" - if ((game.options[OPT_DISABLEOFF] == 3) && - (all_buttons_disabled > 0) && - (guis[aa].PopupStyle != kGUIPopupNoAutoRemove)) - continue; - - add_thing_to_draw(guibgbmp[aa], guis[aa].X, guis[aa].Y, guis[aa].Transparency, guis[aa].HasAlphaChannel()); - - // only poll if the interface is enabled (mouseovers should not - // work while in Wait state) - if (IsInterfaceEnabled()) - guis[aa].Poll(); - } - } - - // draw speech and portraits (so that they appear over GUIs) - for (const auto &over : screenover) - { - if (over.type == OVER_TEXTMSG || over.type == OVER_PICTURE) - { - int tdxp, tdyp; - get_overlay_position(over, &tdxp, &tdyp); - add_thing_to_draw(over.bmp, tdxp, tdyp, 0, false); - } - } - - our_eip = 1099; +void draw_gui_and_overlays() { + if (pl_any_want_hook(AGSE_PREGUIDRAW)) + add_thing_to_draw(nullptr, AGSE_PREGUIDRAW, 0, TRANS_RUN_PLUGIN, false); + + // draw overlays, except text boxes and portraits + for (const auto &over : screenover) { + // complete overlay draw in non-transparent mode + if (over.type == OVER_COMPLETE) + add_thing_to_draw(over.bmp, over.x, over.y, TRANS_OPAQUE, false); + else if (over.type != OVER_TEXTMSG && over.type != OVER_PICTURE) { + int tdxp, tdyp; + get_overlay_position(over, &tdxp, &tdyp); + add_thing_to_draw(over.bmp, tdxp, tdyp, 0, over.hasAlphaChannel); + } + } + + // Draw GUIs - they should always be on top of overlays like + // speech background text + our_eip = 35; + if (((debug_flags & DBG_NOIFACE) == 0) && (displayed_room >= 0)) { + int aa; + + if (playerchar->activeinv >= MAX_INV) { + quit("!The player.activeinv variable has been corrupted, probably as a result\n" + "of an incorrect assignment in the game script."); + } + if (playerchar->activeinv < 1) gui_inv_pic = -1; + else gui_inv_pic = game.invinfo[playerchar->activeinv].pic; + our_eip = 37; + if (guis_need_update) { + guis_need_update = 0; + for (aa = 0; aa < game.numgui; aa++) { + if (!guis[aa].IsDisplayed()) continue; + + if (guibg[aa] == nullptr) + recreate_guibg_image(&guis[aa]); + + eip_guinum = aa; + our_eip = 370; + guibg[aa]->ClearTransparent(); + our_eip = 372; + guis[aa].DrawAt(guibg[aa], 0, 0); + our_eip = 373; + + bool isAlpha = false; + if (guis[aa].HasAlphaChannel()) { + isAlpha = true; + + if ((game.options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Legacy) && (guis[aa].BgImage > 0)) { + // old-style (pre-3.0.2) GUI alpha rendering + repair_alpha_channel(guibg[aa], spriteset[guis[aa].BgImage]); + } + } + + if (guibgbmp[aa] != nullptr) { + gfxDriver->UpdateDDBFromBitmap(guibgbmp[aa], guibg[aa], isAlpha); + } else { + guibgbmp[aa] = gfxDriver->CreateDDBFromBitmap(guibg[aa], isAlpha); + } + our_eip = 374; + } + } + our_eip = 38; + // Draw the GUIs + for (int gg = 0; gg < game.numgui; gg++) { + aa = play.gui_draw_order[gg]; + if (!guis[aa].IsDisplayed()) continue; + + // Don't draw GUI if "GUIs Turn Off When Disabled" + if ((game.options[OPT_DISABLEOFF] == 3) && + (all_buttons_disabled > 0) && + (guis[aa].PopupStyle != kGUIPopupNoAutoRemove)) + continue; + + add_thing_to_draw(guibgbmp[aa], guis[aa].X, guis[aa].Y, guis[aa].Transparency, guis[aa].HasAlphaChannel()); + + // only poll if the interface is enabled (mouseovers should not + // work while in Wait state) + if (IsInterfaceEnabled()) + guis[aa].Poll(); + } + } + + // draw speech and portraits (so that they appear over GUIs) + for (const auto &over : screenover) { + if (over.type == OVER_TEXTMSG || over.type == OVER_PICTURE) { + int tdxp, tdyp; + get_overlay_position(over, &tdxp, &tdyp); + add_thing_to_draw(over.bmp, tdxp, tdyp, 0, false); + } + } + + our_eip = 1099; } // Push the gathered list of sprites into the active graphic renderer -void put_sprite_list_on_screen(bool in_room) -{ - // *** Draw the Things To Draw List *** - - SpriteListEntry *thisThing; - - for (size_t i = 0; i < thingsToDrawList.size(); ++i) - { - thisThing = &thingsToDrawList[i]; - - if (thisThing->bmp != nullptr) { - // mark the image's region as dirty - invalidate_sprite(thisThing->x, thisThing->y, thisThing->bmp, in_room); - } - else if ((thisThing->transparent != TRANS_RUN_PLUGIN) && - (thisThing->bmp == nullptr)) - { - quit("Null pointer added to draw list"); - } - - if (thisThing->bmp != nullptr) - { - if (thisThing->transparent <= 255) - { - thisThing->bmp->SetTransparency(thisThing->transparent); - } - - gfxDriver->DrawSprite(thisThing->x, thisThing->y, thisThing->bmp); - } - else if (thisThing->transparent == TRANS_RUN_PLUGIN) - { - // meta entry to run the plugin hook - gfxDriver->DrawSprite(thisThing->x, thisThing->y, nullptr); - } - else - quit("Unknown entry in draw list"); - } - - our_eip = 1100; -} - -bool GfxDriverNullSpriteCallback(int x, int y) -{ - if (displayed_room < 0) - { - // if no room loaded, various stuff won't be initialized yet - return 1; - } - return (pl_run_plugin_hooks(x, y) != 0); -} - -void GfxDriverOnInitCallback(void *data) -{ - pl_run_plugin_init_gfx_hooks(gfxDriver->GetDriverID(), data); +void put_sprite_list_on_screen(bool in_room) { + // *** Draw the Things To Draw List *** + + SpriteListEntry *thisThing; + + for (size_t i = 0; i < thingsToDrawList.size(); ++i) { + thisThing = &thingsToDrawList[i]; + + if (thisThing->bmp != nullptr) { + // mark the image's region as dirty + invalidate_sprite(thisThing->x, thisThing->y, thisThing->bmp, in_room); + } else if ((thisThing->transparent != TRANS_RUN_PLUGIN) && + (thisThing->bmp == nullptr)) { + quit("Null pointer added to draw list"); + } + + if (thisThing->bmp != nullptr) { + if (thisThing->transparent <= 255) { + thisThing->bmp->SetTransparency(thisThing->transparent); + } + + gfxDriver->DrawSprite(thisThing->x, thisThing->y, thisThing->bmp); + } else if (thisThing->transparent == TRANS_RUN_PLUGIN) { + // meta entry to run the plugin hook + gfxDriver->DrawSprite(thisThing->x, thisThing->y, nullptr); + } else + quit("Unknown entry in draw list"); + } + + our_eip = 1100; +} + +bool GfxDriverNullSpriteCallback(int x, int y) { + if (displayed_room < 0) { + // if no room loaded, various stuff won't be initialized yet + return 1; + } + return (pl_run_plugin_hooks(x, y) != 0); +} + +void GfxDriverOnInitCallback(void *data) { + pl_run_plugin_init_gfx_hooks(gfxDriver->GetDriverID(), data); } // Schedule room rendering: background, objects, characters -static void construct_room_view() -{ - draw_preroom_background(); - prepare_room_sprites(); - // reset the Baselines Changed flag now that we've drawn stuff - walk_behind_baselines_changed = 0; - - for (const auto &viewport : play.GetRoomViewportsZOrdered()) - { - if (!viewport->IsVisible()) - continue; - auto camera = viewport->GetCamera(); - if (!camera) - continue; - const Rect &view_rc = play.GetRoomViewportAbs(viewport->GetID()); - const Rect &cam_rc = camera->GetRect(); - SpriteTransform room_trans(-cam_rc.Left, -cam_rc.Top, - (float)view_rc.GetWidth() / (float)cam_rc.GetWidth(), - (float)view_rc.GetHeight() / (float)cam_rc.GetHeight(), - 0.f); - if (gfxDriver->RequiresFullRedrawEachFrame()) - { // we draw everything as a sprite stack - gfxDriver->BeginSpriteBatch(view_rc, room_trans, Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); - } - else - { - if (CameraDrawData[viewport->GetID()].Frame == nullptr && CameraDrawData[viewport->GetID()].IsOverlap) - { // room background is prepended to the sprite stack - // TODO: here's why we have blit whole piece of background now: - // if we draw directly to the virtual screen overlapping another - // viewport, then we'd have to also mark and repaint every our - // region located directly over their dirty regions. That would - // require to update regions up the stack, converting their - // coordinates (cam1 -> screen -> cam2). - // It's not clear whether this is worth the effort, but if it is, - // then we'd need to optimise view/cam data first. - gfxDriver->BeginSpriteBatch(view_rc, room_trans); - gfxDriver->DrawSprite(0, 0, roomBackgroundBmp); - } - else - { // room background is drawn by dirty rects system - PBitmap bg_surface = draw_room_background(viewport.get(), room_trans); - gfxDriver->BeginSpriteBatch(view_rc, room_trans, Point(), kFlip_None, bg_surface); - } - } - put_sprite_list_on_screen(true); - } - - clear_draw_list(); +static void construct_room_view() { + draw_preroom_background(); + prepare_room_sprites(); + // reset the Baselines Changed flag now that we've drawn stuff + walk_behind_baselines_changed = 0; + + for (const auto &viewport : play.GetRoomViewportsZOrdered()) { + if (!viewport->IsVisible()) + continue; + auto camera = viewport->GetCamera(); + if (!camera) + continue; + const Rect &view_rc = play.GetRoomViewportAbs(viewport->GetID()); + const Rect &cam_rc = camera->GetRect(); + SpriteTransform room_trans(-cam_rc.Left, -cam_rc.Top, + (float)view_rc.GetWidth() / (float)cam_rc.GetWidth(), + (float)view_rc.GetHeight() / (float)cam_rc.GetHeight(), + 0.f); + if (gfxDriver->RequiresFullRedrawEachFrame()) { + // we draw everything as a sprite stack + gfxDriver->BeginSpriteBatch(view_rc, room_trans, Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + } else { + if (CameraDrawData[viewport->GetID()].Frame == nullptr && CameraDrawData[viewport->GetID()].IsOverlap) { + // room background is prepended to the sprite stack + // TODO: here's why we have blit whole piece of background now: + // if we draw directly to the virtual screen overlapping another + // viewport, then we'd have to also mark and repaint every our + // region located directly over their dirty regions. That would + // require to update regions up the stack, converting their + // coordinates (cam1 -> screen -> cam2). + // It's not clear whether this is worth the effort, but if it is, + // then we'd need to optimise view/cam data first. + gfxDriver->BeginSpriteBatch(view_rc, room_trans); + gfxDriver->DrawSprite(0, 0, roomBackgroundBmp); + } else { + // room background is drawn by dirty rects system + PBitmap bg_surface = draw_room_background(viewport.get(), room_trans); + gfxDriver->BeginSpriteBatch(view_rc, room_trans, Point(), kFlip_None, bg_surface); + } + } + put_sprite_list_on_screen(true); + } + + clear_draw_list(); } // Schedule ui rendering -static void construct_ui_view() -{ - gfxDriver->BeginSpriteBatch(play.GetUIViewportAbs(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); - draw_gui_and_overlays(); - put_sprite_list_on_screen(false); - clear_draw_list(); -} - -void construct_game_scene(bool full_redraw) -{ - gfxDriver->ClearDrawLists(); - - if (play.fast_forward) - return; - - our_eip=3; - - // React to changes to viewports and cameras (possibly from script) just before the render - play.UpdateViewports(); - - gfxDriver->UseSmoothScaling(IS_ANTIALIAS_SPRITES); - gfxDriver->RenderSpritesAtScreenResolution(usetup.RenderAtScreenRes, usetup.Supersampling); - - pl_run_plugin_hooks(AGSE_PRERENDER, 0); - - // Possible reasons to invalidate whole screen for the software renderer - if (full_redraw || play.screen_tint > 0 || play.shakesc_length > 0) - invalidate_screen(); - - // TODO: move to game update! don't call update during rendering pass! - // IMPORTANT: keep the order same because sometimes script may depend on it - if (displayed_room >= 0) - play.UpdateRoomCameras(); - - // Stage: room viewports - if (play.screen_is_faded_out == 0 && is_complete_overlay == 0) - { - if (displayed_room >= 0) - { - construct_room_view(); - update_polled_mp3(); - } - else if (!gfxDriver->RequiresFullRedrawEachFrame()) - { - // black it out so we don't get cursor trails - // TODO: this is possible to do with dirty rects system now too (it can paint black rects outside of room viewport) - gfxDriver->GetMemoryBackBuffer()->Fill(0); - } - } - - our_eip=4; - - // Stage: UI overlay - if (play.screen_is_faded_out == 0) - { - construct_ui_view(); - } -} - -void construct_game_screen_overlay(bool draw_mouse) -{ - gfxDriver->BeginSpriteBatch(play.GetMainViewport(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); - if (pl_any_want_hook(AGSE_POSTSCREENDRAW)) - gfxDriver->DrawSprite(AGSE_POSTSCREENDRAW, 0, nullptr); - - // TODO: find out if it's okay to move cursor animation and state update - // to the update loop instead of doing it in the drawing routine - // update animating mouse cursor - if (game.mcurs[cur_cursor].view >= 0) { - ags_domouse(DOMOUSE_NOCURSOR); - // only on mousemove, and it's not moving - if (((game.mcurs[cur_cursor].flags & MCF_ANIMMOVE) != 0) && - (mousex == lastmx) && (mousey == lastmy)); - // only on hotspot, and it's not on one - else if (((game.mcurs[cur_cursor].flags & MCF_HOTSPOT) != 0) && - (GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey)) == 0)) - set_new_cursor_graphic(game.mcurs[cur_cursor].pic); - else if (mouse_delay>0) mouse_delay--; - else { - int viewnum = game.mcurs[cur_cursor].view; - int loopnum = 0; - if (loopnum >= views[viewnum].numLoops) - quitprintf("An animating mouse cursor is using view %d which has no loops", viewnum + 1); - if (views[viewnum].loops[loopnum].numFrames < 1) - quitprintf("An animating mouse cursor is using view %d which has no frames in loop %d", viewnum + 1, loopnum); - - mouse_frame++; - if (mouse_frame >= views[viewnum].loops[loopnum].numFrames) - mouse_frame = 0; - set_new_cursor_graphic(views[viewnum].loops[loopnum].frames[mouse_frame].pic); - mouse_delay = views[viewnum].loops[loopnum].frames[mouse_frame].speed + 5; - CheckViewFrame(viewnum, loopnum, mouse_frame); - } - lastmx = mousex; lastmy = mousey; - } - - ags_domouse(DOMOUSE_NOCURSOR); - - // Stage: mouse cursor - if (draw_mouse && !play.mouse_cursor_hidden && play.screen_is_faded_out == 0) - { - gfxDriver->DrawSprite(mousex - hotx, mousey - hoty, mouseCursor); - invalidate_sprite(mousex - hotx, mousey - hoty, mouseCursor, false); - } - - if (play.screen_is_faded_out == 0) - { - // Stage: screen fx - if (play.screen_tint >= 1) - gfxDriver->SetScreenTint(play.screen_tint & 0xff, (play.screen_tint >> 8) & 0xff, (play.screen_tint >> 16) & 0xff); - // Stage: legacy letterbox mode borders - render_black_borders(); - } - - if (play.screen_is_faded_out != 0 && gfxDriver->RequiresFullRedrawEachFrame()) - { - const Rect &main_viewport = play.GetMainViewport(); - gfxDriver->BeginSpriteBatch(main_viewport, SpriteTransform()); - gfxDriver->SetScreenFade(play.fade_to_red, play.fade_to_green, play.fade_to_blue); - } -} - -void construct_engine_overlay() -{ - const Rect &viewport = RectWH(game.GetGameRes()); - gfxDriver->BeginSpriteBatch(viewport, SpriteTransform()); - - // draw the debug console, if appropriate - if ((play.debug_mode > 0) && (display_console != 0)) - { - const int font = FONT_NORMAL; - int ypp = 1; - int txtspacing = getfontspacing_outlined(font); - int barheight = getheightoflines(font, DEBUG_CONSOLE_NUMLINES - 1) + 4; - - if (debugConsoleBuffer == nullptr) - { - debugConsoleBuffer = BitmapHelper::CreateBitmap(viewport.GetWidth(), barheight, game.GetColorDepth()); - debugConsoleBuffer = ReplaceBitmapWithSupportedFormat(debugConsoleBuffer); - } - - color_t draw_color = debugConsoleBuffer->GetCompatibleColor(15); - debugConsoleBuffer->FillRect(Rect(0, 0, viewport.GetWidth() - 1, barheight), draw_color); - color_t text_color = debugConsoleBuffer->GetCompatibleColor(16); - for (int jj = first_debug_line; jj != last_debug_line; jj = (jj + 1) % DEBUG_CONSOLE_NUMLINES) { - wouttextxy(debugConsoleBuffer, 1, ypp, font, text_color, debug_line[jj]); - ypp += txtspacing; - } - - if (debugConsole == nullptr) - debugConsole = gfxDriver->CreateDDBFromBitmap(debugConsoleBuffer, false, true); - else - gfxDriver->UpdateDDBFromBitmap(debugConsole, debugConsoleBuffer, false); - - gfxDriver->DrawSprite(0, 0, debugConsole); - invalidate_sprite(0, 0, debugConsole, false); - } - - if (display_fps != kFPS_Hide) - draw_fps(viewport); -} - -static void update_shakescreen() -{ - // TODO: unify blocking and non-blocking shake update - play.shake_screen_yoff = 0; - if (play.shakesc_length > 0) - { - if ((loopcounter % play.shakesc_delay) < (play.shakesc_delay / 2)) - play.shake_screen_yoff = play.shakesc_amount; - } -} - -// Draw everything -void render_graphics(IDriverDependantBitmap *extraBitmap, int extraX, int extraY) -{ - // Don't render if skipping cutscene - if (play.fast_forward) - return; - // Don't render if we've just entered new room and are before fade-in - // TODO: find out why this is not skipped for 8-bit games - if ((in_new_room > 0) & (game.color_depth > 1)) - return; - - // TODO: find out if it's okay to move shake to update function - update_shakescreen(); - - construct_game_scene(false); - our_eip=5; - // NOTE: extraBitmap will always be drawn with the UI render stage - if (extraBitmap != nullptr) - { - invalidate_sprite(extraX, extraY, extraBitmap, false); - gfxDriver->DrawSprite(extraX, extraY, extraBitmap); - } - construct_game_screen_overlay(true); - render_to_screen(); - - if (!play.screen_is_faded_out) { - // always update the palette, regardless of whether the plugin - // vetos the screen update - if (bg_just_changed) { - setpal(); - bg_just_changed = 0; - } - } - - screen_is_dirty = false; +static void construct_ui_view() { + gfxDriver->BeginSpriteBatch(play.GetUIViewportAbs(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + draw_gui_and_overlays(); + put_sprite_list_on_screen(false); + clear_draw_list(); +} + +void construct_game_scene(bool full_redraw) { + gfxDriver->ClearDrawLists(); + + if (play.fast_forward) + return; + + our_eip = 3; + + // React to changes to viewports and cameras (possibly from script) just before the render + play.UpdateViewports(); + + gfxDriver->UseSmoothScaling(IS_ANTIALIAS_SPRITES); + gfxDriver->RenderSpritesAtScreenResolution(usetup.RenderAtScreenRes, usetup.Supersampling); + + pl_run_plugin_hooks(AGSE_PRERENDER, 0); + + // Possible reasons to invalidate whole screen for the software renderer + if (full_redraw || play.screen_tint > 0 || play.shakesc_length > 0) + invalidate_screen(); + + // TODO: move to game update! don't call update during rendering pass! + // IMPORTANT: keep the order same because sometimes script may depend on it + if (displayed_room >= 0) + play.UpdateRoomCameras(); + + // Stage: room viewports + if (play.screen_is_faded_out == 0 && is_complete_overlay == 0) { + if (displayed_room >= 0) { + construct_room_view(); + update_polled_mp3(); + } else if (!gfxDriver->RequiresFullRedrawEachFrame()) { + // black it out so we don't get cursor trails + // TODO: this is possible to do with dirty rects system now too (it can paint black rects outside of room viewport) + gfxDriver->GetMemoryBackBuffer()->Fill(0); + } + } + + our_eip = 4; + + // Stage: UI overlay + if (play.screen_is_faded_out == 0) { + construct_ui_view(); + } +} + +void construct_game_screen_overlay(bool draw_mouse) { + gfxDriver->BeginSpriteBatch(play.GetMainViewport(), SpriteTransform(), Point(0, play.shake_screen_yoff), (GlobalFlipType)play.screen_flipped); + if (pl_any_want_hook(AGSE_POSTSCREENDRAW)) + gfxDriver->DrawSprite(AGSE_POSTSCREENDRAW, 0, nullptr); + + // TODO: find out if it's okay to move cursor animation and state update + // to the update loop instead of doing it in the drawing routine + // update animating mouse cursor + if (game.mcurs[cur_cursor].view >= 0) { + ags_domouse(DOMOUSE_NOCURSOR); + // only on mousemove, and it's not moving + if (((game.mcurs[cur_cursor].flags & MCF_ANIMMOVE) != 0) && + (mousex == lastmx) && (mousey == lastmy)); + // only on hotspot, and it's not on one + else if (((game.mcurs[cur_cursor].flags & MCF_HOTSPOT) != 0) && + (GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey)) == 0)) + set_new_cursor_graphic(game.mcurs[cur_cursor].pic); + else if (mouse_delay > 0) mouse_delay--; + else { + int viewnum = game.mcurs[cur_cursor].view; + int loopnum = 0; + if (loopnum >= views[viewnum].numLoops) + quitprintf("An animating mouse cursor is using view %d which has no loops", viewnum + 1); + if (views[viewnum].loops[loopnum].numFrames < 1) + quitprintf("An animating mouse cursor is using view %d which has no frames in loop %d", viewnum + 1, loopnum); + + mouse_frame++; + if (mouse_frame >= views[viewnum].loops[loopnum].numFrames) + mouse_frame = 0; + set_new_cursor_graphic(views[viewnum].loops[loopnum].frames[mouse_frame].pic); + mouse_delay = views[viewnum].loops[loopnum].frames[mouse_frame].speed + 5; + CheckViewFrame(viewnum, loopnum, mouse_frame); + } + lastmx = mousex; + lastmy = mousey; + } + + ags_domouse(DOMOUSE_NOCURSOR); + + // Stage: mouse cursor + if (draw_mouse && !play.mouse_cursor_hidden && play.screen_is_faded_out == 0) { + gfxDriver->DrawSprite(mousex - hotx, mousey - hoty, mouseCursor); + invalidate_sprite(mousex - hotx, mousey - hoty, mouseCursor, false); + } + + if (play.screen_is_faded_out == 0) { + // Stage: screen fx + if (play.screen_tint >= 1) + gfxDriver->SetScreenTint(play.screen_tint & 0xff, (play.screen_tint >> 8) & 0xff, (play.screen_tint >> 16) & 0xff); + // Stage: legacy letterbox mode borders + render_black_borders(); + } + + if (play.screen_is_faded_out != 0 && gfxDriver->RequiresFullRedrawEachFrame()) { + const Rect &main_viewport = play.GetMainViewport(); + gfxDriver->BeginSpriteBatch(main_viewport, SpriteTransform()); + gfxDriver->SetScreenFade(play.fade_to_red, play.fade_to_green, play.fade_to_blue); + } +} + +void construct_engine_overlay() { + const Rect &viewport = RectWH(game.GetGameRes()); + gfxDriver->BeginSpriteBatch(viewport, SpriteTransform()); + + // draw the debug console, if appropriate + if ((play.debug_mode > 0) && (display_console != 0)) { + const int font = FONT_NORMAL; + int ypp = 1; + int txtspacing = getfontspacing_outlined(font); + int barheight = getheightoflines(font, DEBUG_CONSOLE_NUMLINES - 1) + 4; + + if (debugConsoleBuffer == nullptr) { + debugConsoleBuffer = BitmapHelper::CreateBitmap(viewport.GetWidth(), barheight, game.GetColorDepth()); + debugConsoleBuffer = ReplaceBitmapWithSupportedFormat(debugConsoleBuffer); + } + + color_t draw_color = debugConsoleBuffer->GetCompatibleColor(15); + debugConsoleBuffer->FillRect(Rect(0, 0, viewport.GetWidth() - 1, barheight), draw_color); + color_t text_color = debugConsoleBuffer->GetCompatibleColor(16); + for (int jj = first_debug_line; jj != last_debug_line; jj = (jj + 1) % DEBUG_CONSOLE_NUMLINES) { + wouttextxy(debugConsoleBuffer, 1, ypp, font, text_color, debug_line[jj]); + ypp += txtspacing; + } + + if (debugConsole == nullptr) + debugConsole = gfxDriver->CreateDDBFromBitmap(debugConsoleBuffer, false, true); + else + gfxDriver->UpdateDDBFromBitmap(debugConsole, debugConsoleBuffer, false); + + gfxDriver->DrawSprite(0, 0, debugConsole); + invalidate_sprite(0, 0, debugConsole, false); + } + + if (display_fps != kFPS_Hide) + draw_fps(viewport); +} + +static void update_shakescreen() { + // TODO: unify blocking and non-blocking shake update + play.shake_screen_yoff = 0; + if (play.shakesc_length > 0) { + if ((loopcounter % play.shakesc_delay) < (play.shakesc_delay / 2)) + play.shake_screen_yoff = play.shakesc_amount; + } +} + +// Draw everything +void render_graphics(IDriverDependantBitmap *extraBitmap, int extraX, int extraY) { + // Don't render if skipping cutscene + if (play.fast_forward) + return; + // Don't render if we've just entered new room and are before fade-in + // TODO: find out why this is not skipped for 8-bit games + if ((in_new_room > 0) & (game.color_depth > 1)) + return; + + // TODO: find out if it's okay to move shake to update function + update_shakescreen(); + + construct_game_scene(false); + our_eip = 5; + // NOTE: extraBitmap will always be drawn with the UI render stage + if (extraBitmap != nullptr) { + invalidate_sprite(extraX, extraY, extraBitmap, false); + gfxDriver->DrawSprite(extraX, extraY, extraBitmap); + } + construct_game_screen_overlay(true); + render_to_screen(); + + if (!play.screen_is_faded_out) { + // always update the palette, regardless of whether the plugin + // vetos the screen update + if (bg_just_changed) { + setpal(); + bg_just_changed = 0; + } + } + + screen_is_dirty = false; } diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index 63bcb7432a6f..922b557e1b86 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -29,14 +29,14 @@ #include "gfx/gfx_def.h" #include "util/wgt2allg.h" -namespace AGS -{ - namespace Common - { - class Bitmap; - typedef std::shared_ptr PBitmap; - } - namespace Engine { class IDriverDependantBitmap; } +namespace AGS { +namespace Common { +class Bitmap; +typedef std::shared_ptr PBitmap; +} +namespace Engine { +class IDriverDependantBitmap; +} } using namespace AGS; // FIXME later @@ -54,10 +54,10 @@ using namespace AGS; // FIXME later struct CachedActSpsData { - int xWas, yWas; - int baselineWas; - int isWalkBehindHere; - int valid; + int xWas, yWas; + int baselineWas; + int isWalkBehindHere; + int valid; }; // Converts AGS color index to the actual bitmap color using game's color depth @@ -103,8 +103,8 @@ void mark_current_background_dirty(); void invalidate_cached_walkbehinds(); // Avoid freeing and reallocating the memory if possible Common::Bitmap *recycle_bitmap(Common::Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent = false); -Engine::IDriverDependantBitmap* recycle_ddb_bitmap(Engine::IDriverDependantBitmap *bimp, Common::Bitmap *source, bool hasAlpha = false, bool opaque = false); -// Draw everything +Engine::IDriverDependantBitmap *recycle_ddb_bitmap(Engine::IDriverDependantBitmap *bimp, Common::Bitmap *source, bool hasAlpha = false, bool opaque = false); +// Draw everything void render_graphics(Engine::IDriverDependantBitmap *extraBitmap = nullptr, int extraX = 0, int extraY = 0); // Construct game scene, scheduling drawing list for the renderer void construct_game_scene(bool full_redraw = false); @@ -112,8 +112,8 @@ void construct_game_scene(bool full_redraw = false); void construct_game_screen_overlay(bool draw_mouse = true); // Construct engine overlay with debugging tools (fps, console) void construct_engine_overlay(); -void add_to_sprite_list(Engine::IDriverDependantBitmap* spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind = false); -void tint_image (Common::Bitmap *g, Common::Bitmap *source, int red, int grn, int blu, int light_level, int luminance=255); +void add_to_sprite_list(Engine::IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind = false); +void tint_image(Common::Bitmap *g, Common::Bitmap *source, int red, int grn, int blu, int light_level, int luminance = 255); void draw_sprite_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Common::Bitmap *image, bool src_has_alpha, Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); void draw_sprite_slot_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot, @@ -126,7 +126,7 @@ void render_to_screen(); void draw_game_screen_callback(); void GfxDriverOnInitCallback(void *data); bool GfxDriverNullSpriteCallback(int x, int y); -void putpixel_compensate (Common::Bitmap *g, int xx,int yy, int col); +void putpixel_compensate(Common::Bitmap *g, int xx, int yy, int col); // create the actsps[aa] image with the object drawn correctly // returns 1 if nothing at all has changed and actsps is still // intact from last time; 0 otherwise diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index 014713495a21..fb62af5e06af 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -63,118 +63,105 @@ using namespace AGS::Engine; // Dirty rects store coordinate values in the coordinate system of a camera surface, // where coords always span from 0,0 to surface width,height. // Converting from room to dirty rects would require subtracting room camera offsets. -struct IRSpan -{ - int x1, x2; - int mergeSpan(int tx1, int tx2); +struct IRSpan { + int x1, x2; + int mergeSpan(int tx1, int tx2); - IRSpan(); + IRSpan(); }; -struct IRRow -{ - IRSpan span[MAX_SPANS_PER_ROW]; - int numSpans; +struct IRRow { + IRSpan span[MAX_SPANS_PER_ROW]; + int numSpans; - IRRow(); + IRRow(); }; -struct DirtyRects -{ - // Size of the surface managed by this dirty rects object - Size SurfaceSize; - // Where the surface is rendered on screen - Rect Viewport; - // Room -> screen coordinate transformation - PlaneScaling Room2Screen; - // Screen -> dirty surface rect - // The dirty rects are saved in coordinates limited to (0,0)->(camera size) rather than room or screen coords - PlaneScaling Screen2DirtySurf; - - std::vector DirtyRows; - Rect DirtyRegions[MAXDIRTYREGIONS]; - size_t NumDirtyRegions; - - DirtyRects(); - bool IsInit() const; - // Initialize dirty rects for the given surface size - void Init(const Size &surf_size, const Rect &viewport); - void SetSurfaceOffsets(int x, int y); - // Delete dirty rects - void Destroy(); - // Mark all surface as tidy - void Reset(); +struct DirtyRects { + // Size of the surface managed by this dirty rects object + Size SurfaceSize; + // Where the surface is rendered on screen + Rect Viewport; + // Room -> screen coordinate transformation + PlaneScaling Room2Screen; + // Screen -> dirty surface rect + // The dirty rects are saved in coordinates limited to (0,0)->(camera size) rather than room or screen coords + PlaneScaling Screen2DirtySurf; + + std::vector DirtyRows; + Rect DirtyRegions[MAXDIRTYREGIONS]; + size_t NumDirtyRegions; + + DirtyRects(); + bool IsInit() const; + // Initialize dirty rects for the given surface size + void Init(const Size &surf_size, const Rect &viewport); + void SetSurfaceOffsets(int x, int y); + // Delete dirty rects + void Destroy(); + // Mark all surface as tidy + void Reset(); }; IRSpan::IRSpan() - : x1(0), x2(0) -{ + : x1(0), x2(0) { } IRRow::IRRow() - : numSpans(0) -{ + : numSpans(0) { } -int IRSpan::mergeSpan(int tx1, int tx2) -{ - if ((tx1 > x2) || (tx2 < x1)) - return 0; - // overlapping, increase the span - if (tx1 < x1) - x1 = tx1; - if (tx2 > x2) - x2 = tx2; - return 1; +int IRSpan::mergeSpan(int tx1, int tx2) { + if ((tx1 > x2) || (tx2 < x1)) + return 0; + // overlapping, increase the span + if (tx1 < x1) + x1 = tx1; + if (tx2 > x2) + x2 = tx2; + return 1; } DirtyRects::DirtyRects() - : NumDirtyRegions(0) -{ + : NumDirtyRegions(0) { } -bool DirtyRects::IsInit() const -{ - return DirtyRows.size() > 0; +bool DirtyRects::IsInit() const { + return DirtyRows.size() > 0; } -void DirtyRects::Init(const Size &surf_size, const Rect &viewport) -{ - int height = surf_size.Height; - if (SurfaceSize != surf_size) - { - Destroy(); - SurfaceSize = surf_size; - DirtyRows.resize(height); - - NumDirtyRegions = WHOLESCREENDIRTY; - for (int i = 0; i < height; ++i) - DirtyRows[i].numSpans = 0; - } - - Viewport = viewport; - Room2Screen.Init(surf_size, viewport); - Screen2DirtySurf.Init(viewport, RectWH(0, 0, surf_size.Width, surf_size.Height)); +void DirtyRects::Init(const Size &surf_size, const Rect &viewport) { + int height = surf_size.Height; + if (SurfaceSize != surf_size) { + Destroy(); + SurfaceSize = surf_size; + DirtyRows.resize(height); + + NumDirtyRegions = WHOLESCREENDIRTY; + for (int i = 0; i < height; ++i) + DirtyRows[i].numSpans = 0; + } + + Viewport = viewport; + Room2Screen.Init(surf_size, viewport); + Screen2DirtySurf.Init(viewport, RectWH(0, 0, surf_size.Width, surf_size.Height)); } -void DirtyRects::SetSurfaceOffsets(int x, int y) -{ - Room2Screen.SetSrcOffsets(x, y); +void DirtyRects::SetSurfaceOffsets(int x, int y) { + Room2Screen.SetSrcOffsets(x, y); } -void DirtyRects::Destroy() -{ - DirtyRows.clear(); - NumDirtyRegions = 0; +void DirtyRects::Destroy() { + DirtyRows.clear(); + NumDirtyRegions = 0; } -void DirtyRects::Reset() -{ - NumDirtyRegions = 0; +void DirtyRects::Reset() { + NumDirtyRegions = 0; - for (size_t i = 0; i < DirtyRows.size(); ++i) - DirtyRows[i].numSpans = 0; + for (size_t i = 0; i < DirtyRows.size(); ++i) + DirtyRows[i].numSpans = 0; } // Dirty rects for the main viewport background (black screen); @@ -188,198 +175,174 @@ std::vector RoomCamRects; std::vector> RoomCamPositions; -void dispose_invalid_regions(bool /* room_only */) -{ - RoomCamRects.clear(); - RoomCamPositions.clear(); +void dispose_invalid_regions(bool /* room_only */) { + RoomCamRects.clear(); + RoomCamPositions.clear(); } -void init_invalid_regions(int view_index, const Size &surf_size, const Rect &viewport) -{ - if (view_index < 0) - { - BlackRects.Init(surf_size, viewport); - } - else - { - if (RoomCamRects.size() <= (size_t)view_index) - { - RoomCamRects.resize(view_index + 1); - RoomCamPositions.resize(view_index + 1); - } - RoomCamRects[view_index].Init(surf_size, viewport); - RoomCamPositions[view_index] = std::make_pair(-1000, -1000); - } +void init_invalid_regions(int view_index, const Size &surf_size, const Rect &viewport) { + if (view_index < 0) { + BlackRects.Init(surf_size, viewport); + } else { + if (RoomCamRects.size() <= (size_t)view_index) { + RoomCamRects.resize(view_index + 1); + RoomCamPositions.resize(view_index + 1); + } + RoomCamRects[view_index].Init(surf_size, viewport); + RoomCamPositions[view_index] = std::make_pair(-1000, -1000); + } } -void delete_invalid_regions(int view_index) -{ - if (view_index >= 0) - { - RoomCamRects.erase(RoomCamRects.begin() + view_index); - RoomCamPositions.erase(RoomCamPositions.begin() + view_index); - } +void delete_invalid_regions(int view_index) { + if (view_index >= 0) { + RoomCamRects.erase(RoomCamRects.begin() + view_index); + RoomCamPositions.erase(RoomCamPositions.begin() + view_index); + } } -void set_invalidrects_cameraoffs(int view_index, int x, int y) -{ - if (view_index < 0) - { - BlackRects.SetSurfaceOffsets(x, y); - return; - } - else - { - RoomCamRects[view_index].SetSurfaceOffsets(x, y); - } - - int &posxwas = RoomCamPositions[view_index].first; - int &posywas = RoomCamPositions[view_index].second; - if ((x != posxwas) || (y != posywas)) - { - invalidate_all_camera_rects(view_index); - posxwas = x; - posywas = y; - } +void set_invalidrects_cameraoffs(int view_index, int x, int y) { + if (view_index < 0) { + BlackRects.SetSurfaceOffsets(x, y); + return; + } else { + RoomCamRects[view_index].SetSurfaceOffsets(x, y); + } + + int &posxwas = RoomCamPositions[view_index].first; + int &posywas = RoomCamPositions[view_index].second; + if ((x != posxwas) || (y != posywas)) { + invalidate_all_camera_rects(view_index); + posxwas = x; + posywas = y; + } } -void invalidate_all_rects() -{ - for (auto &rects : RoomCamRects) - { - if (!IsRectInsideRect(rects.Viewport, BlackRects.Viewport)) - BlackRects.NumDirtyRegions = WHOLESCREENDIRTY; - rects.NumDirtyRegions = WHOLESCREENDIRTY; - } +void invalidate_all_rects() { + for (auto &rects : RoomCamRects) { + if (!IsRectInsideRect(rects.Viewport, BlackRects.Viewport)) + BlackRects.NumDirtyRegions = WHOLESCREENDIRTY; + rects.NumDirtyRegions = WHOLESCREENDIRTY; + } } -void invalidate_all_camera_rects(int view_index) -{ - if (view_index < 0) - return; - RoomCamRects[view_index].NumDirtyRegions = WHOLESCREENDIRTY; +void invalidate_all_camera_rects(int view_index) { + if (view_index < 0) + return; + RoomCamRects[view_index].NumDirtyRegions = WHOLESCREENDIRTY; } -void invalidate_rect_on_surf(int x1, int y1, int x2, int y2, DirtyRects &rects) -{ - if (rects.DirtyRows.size() == 0) - return; - if (rects.NumDirtyRegions >= MAXDIRTYREGIONS) { - // too many invalid rectangles, just mark the whole thing dirty - rects.NumDirtyRegions = WHOLESCREENDIRTY; - return; - } - - int a; - - const Size &surfsz = rects.SurfaceSize; - if (x1 >= surfsz.Width) x1 = surfsz.Width - 1; - if (y1 >= surfsz.Height) y1 = surfsz.Height - 1; - if (x2 >= surfsz.Width) x2 = surfsz.Width - 1; - if (y2 >= surfsz.Height) y2 = surfsz.Height - 1; - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 < 0) x2 = 0; - if (y2 < 0) y2 = 0; - rects.NumDirtyRegions++; - - // ** Span code - std::vector &dirtyRow = rects.DirtyRows; - int s, foundOne; - // add this rect to the list for this row - for (a = y1; a <= y2; a++) { - foundOne = 0; - for (s = 0; s < dirtyRow[a].numSpans; s++) { - if (dirtyRow[a].span[s].mergeSpan(x1, x2)) { - foundOne = 1; - break; - } - } - if (foundOne) { - // we were merged into a span, so we're ok - int t; - // check whether now two of the spans overlap each other - // in which case merge them - for (s = 0; s < dirtyRow[a].numSpans; s++) { - for (t = s + 1; t < dirtyRow[a].numSpans; t++) { - if (dirtyRow[a].span[s].mergeSpan(dirtyRow[a].span[t].x1, dirtyRow[a].span[t].x2)) { - dirtyRow[a].numSpans--; - for (int u = t; u < dirtyRow[a].numSpans; u++) - dirtyRow[a].span[u] = dirtyRow[a].span[u + 1]; - break; - } - } - } - } - else if (dirtyRow[a].numSpans < MAX_SPANS_PER_ROW) { - dirtyRow[a].span[dirtyRow[a].numSpans].x1 = x1; - dirtyRow[a].span[dirtyRow[a].numSpans].x2 = x2; - dirtyRow[a].numSpans++; - } - else { - // didn't fit in an existing span, and there are none spare - int nearestDist = 99999, nearestWas = -1, extendLeft; - int tleft, tright; - // find the nearest span, and enlarge that to include this rect - for (s = 0; s < dirtyRow[a].numSpans; s++) { - tleft = dirtyRow[a].span[s].x1 - x2; - if ((tleft > 0) && (tleft < nearestDist)) { - nearestDist = tleft; - nearestWas = s; - extendLeft = 1; - } - tright = x1 - dirtyRow[a].span[s].x2; - if ((tright > 0) && (tright < nearestDist)) { - nearestDist = tright; - nearestWas = s; - extendLeft = 0; - } - } - if (extendLeft) - dirtyRow[a].span[nearestWas].x1 = x1; - else - dirtyRow[a].span[nearestWas].x2 = x2; - } - } - // ** End span code - //} +void invalidate_rect_on_surf(int x1, int y1, int x2, int y2, DirtyRects &rects) { + if (rects.DirtyRows.size() == 0) + return; + if (rects.NumDirtyRegions >= MAXDIRTYREGIONS) { + // too many invalid rectangles, just mark the whole thing dirty + rects.NumDirtyRegions = WHOLESCREENDIRTY; + return; + } + + int a; + + const Size &surfsz = rects.SurfaceSize; + if (x1 >= surfsz.Width) x1 = surfsz.Width - 1; + if (y1 >= surfsz.Height) y1 = surfsz.Height - 1; + if (x2 >= surfsz.Width) x2 = surfsz.Width - 1; + if (y2 >= surfsz.Height) y2 = surfsz.Height - 1; + if (x1 < 0) x1 = 0; + if (y1 < 0) y1 = 0; + if (x2 < 0) x2 = 0; + if (y2 < 0) y2 = 0; + rects.NumDirtyRegions++; + + // ** Span code + std::vector &dirtyRow = rects.DirtyRows; + int s, foundOne; + // add this rect to the list for this row + for (a = y1; a <= y2; a++) { + foundOne = 0; + for (s = 0; s < dirtyRow[a].numSpans; s++) { + if (dirtyRow[a].span[s].mergeSpan(x1, x2)) { + foundOne = 1; + break; + } + } + if (foundOne) { + // we were merged into a span, so we're ok + int t; + // check whether now two of the spans overlap each other + // in which case merge them + for (s = 0; s < dirtyRow[a].numSpans; s++) { + for (t = s + 1; t < dirtyRow[a].numSpans; t++) { + if (dirtyRow[a].span[s].mergeSpan(dirtyRow[a].span[t].x1, dirtyRow[a].span[t].x2)) { + dirtyRow[a].numSpans--; + for (int u = t; u < dirtyRow[a].numSpans; u++) + dirtyRow[a].span[u] = dirtyRow[a].span[u + 1]; + break; + } + } + } + } else if (dirtyRow[a].numSpans < MAX_SPANS_PER_ROW) { + dirtyRow[a].span[dirtyRow[a].numSpans].x1 = x1; + dirtyRow[a].span[dirtyRow[a].numSpans].x2 = x2; + dirtyRow[a].numSpans++; + } else { + // didn't fit in an existing span, and there are none spare + int nearestDist = 99999, nearestWas = -1, extendLeft; + int tleft, tright; + // find the nearest span, and enlarge that to include this rect + for (s = 0; s < dirtyRow[a].numSpans; s++) { + tleft = dirtyRow[a].span[s].x1 - x2; + if ((tleft > 0) && (tleft < nearestDist)) { + nearestDist = tleft; + nearestWas = s; + extendLeft = 1; + } + tright = x1 - dirtyRow[a].span[s].x2; + if ((tright > 0) && (tright < nearestDist)) { + nearestDist = tright; + nearestWas = s; + extendLeft = 0; + } + } + if (extendLeft) + dirtyRow[a].span[nearestWas].x1 = x1; + else + dirtyRow[a].span[nearestWas].x2 = x2; + } + } + // ** End span code + //} } -void invalidate_rect_ds(DirtyRects &rects, int x1, int y1, int x2, int y2, bool in_room) -{ - if (!in_room) - { - // TODO: for most opimisation (esp. with multiple viewports) should perhaps - // split/cut parts of the original rectangle which overlap room viewport(s). - Rect r(x1, y1, x2, y2); - // If overlay is NOT completely over the room, then invalidate black rect - if (!IsRectInsideRect(rects.Viewport, r)) - invalidate_rect_on_surf(x1, y1, x2, y2, BlackRects); - // If overlay is NOT intersecting room viewport at all, then stop - if (!AreRectsIntersecting(rects.Viewport, r)) - return; - - // Transform from screen to room coordinates through the known viewport - x1 = rects.Screen2DirtySurf.X.ScalePt(x1); - x2 = rects.Screen2DirtySurf.X.ScalePt(x2); - y1 = rects.Screen2DirtySurf.Y.ScalePt(y1); - y2 = rects.Screen2DirtySurf.Y.ScalePt(y2); - } - else - { - x1 -= rects.Room2Screen.X.GetSrcOffset(); - y1 -= rects.Room2Screen.Y.GetSrcOffset(); - x2 -= rects.Room2Screen.X.GetSrcOffset(); - y2 -= rects.Room2Screen.Y.GetSrcOffset(); - } - - invalidate_rect_on_surf(x1, y1, x2, y2, rects); +void invalidate_rect_ds(DirtyRects &rects, int x1, int y1, int x2, int y2, bool in_room) { + if (!in_room) { + // TODO: for most opimisation (esp. with multiple viewports) should perhaps + // split/cut parts of the original rectangle which overlap room viewport(s). + Rect r(x1, y1, x2, y2); + // If overlay is NOT completely over the room, then invalidate black rect + if (!IsRectInsideRect(rects.Viewport, r)) + invalidate_rect_on_surf(x1, y1, x2, y2, BlackRects); + // If overlay is NOT intersecting room viewport at all, then stop + if (!AreRectsIntersecting(rects.Viewport, r)) + return; + + // Transform from screen to room coordinates through the known viewport + x1 = rects.Screen2DirtySurf.X.ScalePt(x1); + x2 = rects.Screen2DirtySurf.X.ScalePt(x2); + y1 = rects.Screen2DirtySurf.Y.ScalePt(y1); + y2 = rects.Screen2DirtySurf.Y.ScalePt(y2); + } else { + x1 -= rects.Room2Screen.X.GetSrcOffset(); + y1 -= rects.Room2Screen.Y.GetSrcOffset(); + x2 -= rects.Room2Screen.X.GetSrcOffset(); + y2 -= rects.Room2Screen.Y.GetSrcOffset(); + } + + invalidate_rect_on_surf(x1, y1, x2, y2, rects); } -void invalidate_rect_ds(int x1, int y1, int x2, int y2, bool in_room) -{ - for (auto &rects : RoomCamRects) - invalidate_rect_ds(rects, x1, y1, x2, y2, in_room); +void invalidate_rect_ds(int x1, int y1, int x2, int y2, bool in_room) { + for (auto &rects : RoomCamRects) + invalidate_rect_ds(rects, x1, y1, x2, y2, in_room); } // Note that this function is denied to perform any kind of scaling or other transformation @@ -387,115 +350,97 @@ void invalidate_rect_ds(int x1, int y1, int x2, int y2, bool in_room) // while room background was 16-bit and Allegro lib does not support stretching between colour depths. // The no_transform flag here means essentially "no offset", and indicates that the function // must blit src on ds at 0;0. Otherwise, actual Viewport offset is used. -void update_invalid_region(Bitmap *ds, Bitmap *src, const DirtyRects &rects, bool no_transform) -{ - if (rects.NumDirtyRegions == 0) - return; - - if (!no_transform) - ds->SetClip(rects.Viewport); - - const int src_x = rects.Room2Screen.X.GetSrcOffset(); - const int src_y = rects.Room2Screen.Y.GetSrcOffset(); - const int dst_x = no_transform ? 0 : rects.Viewport.Left; - const int dst_y = no_transform ? 0 : rects.Viewport.Top; - - if (rects.NumDirtyRegions == WHOLESCREENDIRTY) - { - ds->Blit(src, src_x, src_y, dst_x, dst_y, rects.SurfaceSize.Width, rects.SurfaceSize.Height); - } - else - { - const std::vector &dirtyRow = rects.DirtyRows; - const int surf_height = rects.SurfaceSize.Height; - // TODO: is this IsMemoryBitmap check is still relevant? - // If bitmaps properties match and no transform required other than linear offset - if ((src->GetColorDepth() == ds->GetColorDepth()) && (ds->IsMemoryBitmap())) - { - const int bypp = src->GetBPP(); - // do the fast memory copy - for (int i = 0; i < surf_height; i++) - { - const uint8_t *src_scanline = src->GetScanLine(i + src_y); - uint8_t *dst_scanline = ds->GetScanLineForWriting(i + dst_y); - const IRRow &dirty_row = dirtyRow[i]; - for (int k = 0; k < dirty_row.numSpans; k++) - { - int tx1 = dirty_row.span[k].x1; - int tx2 = dirty_row.span[k].x2; - memcpy(&dst_scanline[(tx1 + dst_x) * bypp], &src_scanline[(tx1 + src_x) * bypp], ((tx2 - tx1) + 1) * bypp); - } - } - } - // If has to use Blit, but still must draw with no transform but offset - else - { - // do fast copy without transform - for (int i = 0, rowsInOne = 1; i < surf_height; i += rowsInOne, rowsInOne = 1) - { - // if there are rows with identical masks, do them all in one go - // TODO: what is this for? may this be done at the invalidate_rect merge step? - while ((i + rowsInOne < surf_height) && (memcmp(&dirtyRow[i], &dirtyRow[i + rowsInOne], sizeof(IRRow)) == 0)) - rowsInOne++; - - const IRRow &dirty_row = dirtyRow[i]; - for (int k = 0; k < dirty_row.numSpans; k++) - { - int tx1 = dirty_row.span[k].x1; - int tx2 = dirty_row.span[k].x2; - ds->Blit(src, tx1 + src_x, i + src_y, tx1 + dst_x, i + dst_y, (tx2 - tx1) + 1, rowsInOne); - } - } - } - } +void update_invalid_region(Bitmap *ds, Bitmap *src, const DirtyRects &rects, bool no_transform) { + if (rects.NumDirtyRegions == 0) + return; + + if (!no_transform) + ds->SetClip(rects.Viewport); + + const int src_x = rects.Room2Screen.X.GetSrcOffset(); + const int src_y = rects.Room2Screen.Y.GetSrcOffset(); + const int dst_x = no_transform ? 0 : rects.Viewport.Left; + const int dst_y = no_transform ? 0 : rects.Viewport.Top; + + if (rects.NumDirtyRegions == WHOLESCREENDIRTY) { + ds->Blit(src, src_x, src_y, dst_x, dst_y, rects.SurfaceSize.Width, rects.SurfaceSize.Height); + } else { + const std::vector &dirtyRow = rects.DirtyRows; + const int surf_height = rects.SurfaceSize.Height; + // TODO: is this IsMemoryBitmap check is still relevant? + // If bitmaps properties match and no transform required other than linear offset + if ((src->GetColorDepth() == ds->GetColorDepth()) && (ds->IsMemoryBitmap())) { + const int bypp = src->GetBPP(); + // do the fast memory copy + for (int i = 0; i < surf_height; i++) { + const uint8_t *src_scanline = src->GetScanLine(i + src_y); + uint8_t *dst_scanline = ds->GetScanLineForWriting(i + dst_y); + const IRRow &dirty_row = dirtyRow[i]; + for (int k = 0; k < dirty_row.numSpans; k++) { + int tx1 = dirty_row.span[k].x1; + int tx2 = dirty_row.span[k].x2; + memcpy(&dst_scanline[(tx1 + dst_x) * bypp], &src_scanline[(tx1 + src_x) * bypp], ((tx2 - tx1) + 1) * bypp); + } + } + } + // If has to use Blit, but still must draw with no transform but offset + else { + // do fast copy without transform + for (int i = 0, rowsInOne = 1; i < surf_height; i += rowsInOne, rowsInOne = 1) { + // if there are rows with identical masks, do them all in one go + // TODO: what is this for? may this be done at the invalidate_rect merge step? + while ((i + rowsInOne < surf_height) && (memcmp(&dirtyRow[i], &dirtyRow[i + rowsInOne], sizeof(IRRow)) == 0)) + rowsInOne++; + + const IRRow &dirty_row = dirtyRow[i]; + for (int k = 0; k < dirty_row.numSpans; k++) { + int tx1 = dirty_row.span[k].x1; + int tx2 = dirty_row.span[k].x2; + ds->Blit(src, tx1 + src_x, i + src_y, tx1 + dst_x, i + dst_y, (tx2 - tx1) + 1, rowsInOne); + } + } + } + } } -void update_invalid_region(Bitmap *ds, color_t fill_color, const DirtyRects &rects) -{ - ds->SetClip(rects.Viewport); - - if (rects.NumDirtyRegions == WHOLESCREENDIRTY) - { - ds->FillRect(rects.Viewport, fill_color); - } - else - { - const std::vector &dirtyRow = rects.DirtyRows; - const int surf_height = rects.SurfaceSize.Height; - { - const PlaneScaling &tf = rects.Room2Screen; - for (int i = 0, rowsInOne = 1; i < surf_height; i += rowsInOne, rowsInOne = 1) - { - // if there are rows with identical masks, do them all in one go - // TODO: what is this for? may this be done at the invalidate_rect merge step? - while ((i + rowsInOne < surf_height) && (memcmp(&dirtyRow[i], &dirtyRow[i + rowsInOne], sizeof(IRRow)) == 0)) - rowsInOne++; - - const IRRow &dirty_row = dirtyRow[i]; - for (int k = 0; k < dirty_row.numSpans; k++) - { - Rect src_r(dirty_row.span[k].x1, i, dirty_row.span[k].x2, i + rowsInOne - 1); - Rect dst_r = tf.ScaleRange(src_r); - ds->FillRect(dst_r, fill_color); - } - } - } - } +void update_invalid_region(Bitmap *ds, color_t fill_color, const DirtyRects &rects) { + ds->SetClip(rects.Viewport); + + if (rects.NumDirtyRegions == WHOLESCREENDIRTY) { + ds->FillRect(rects.Viewport, fill_color); + } else { + const std::vector &dirtyRow = rects.DirtyRows; + const int surf_height = rects.SurfaceSize.Height; + { + const PlaneScaling &tf = rects.Room2Screen; + for (int i = 0, rowsInOne = 1; i < surf_height; i += rowsInOne, rowsInOne = 1) { + // if there are rows with identical masks, do them all in one go + // TODO: what is this for? may this be done at the invalidate_rect merge step? + while ((i + rowsInOne < surf_height) && (memcmp(&dirtyRow[i], &dirtyRow[i + rowsInOne], sizeof(IRRow)) == 0)) + rowsInOne++; + + const IRRow &dirty_row = dirtyRow[i]; + for (int k = 0; k < dirty_row.numSpans; k++) { + Rect src_r(dirty_row.span[k].x1, i, dirty_row.span[k].x2, i + rowsInOne - 1); + Rect dst_r = tf.ScaleRange(src_r); + ds->FillRect(dst_r, fill_color); + } + } + } + } } -void update_black_invreg_and_reset(Bitmap *ds) -{ - if (!BlackRects.IsInit()) - return; - update_invalid_region(ds, (color_t)0, BlackRects); - BlackRects.Reset(); +void update_black_invreg_and_reset(Bitmap *ds) { + if (!BlackRects.IsInit()) + return; + update_invalid_region(ds, (color_t)0, BlackRects); + BlackRects.Reset(); } -void update_room_invreg_and_reset(int view_index, Bitmap *ds, Bitmap *src, bool no_transform) -{ - if (view_index < 0 || RoomCamRects.size() == 0) - return; - - update_invalid_region(ds, src, RoomCamRects[view_index], no_transform); - RoomCamRects[view_index].Reset(); +void update_room_invreg_and_reset(int view_index, Bitmap *ds, Bitmap *src, bool no_transform) { + if (view_index < 0 || RoomCamRects.size() == 0) + return; + + update_invalid_region(ds, src, RoomCamRects[view_index], no_transform); + RoomCamRects[view_index].Reset(); } diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp index 3e8fc26de12f..329e31297460 100644 --- a/engines/ags/engine/ac/drawingsurface.cpp +++ b/engines/ags/engine/ac/drawingsurface.cpp @@ -47,8 +47,8 @@ using namespace AGS::Engine; extern GameSetupStruct game; extern GameState play; -extern RoomStatus*croom; -extern RoomObject*objs; +extern RoomStatus *croom; +extern RoomObject *objs; extern CharacterCache *charcache; extern ObjectCache objcache[MAX_ROOM_OBJECTS]; extern SpriteCache spriteset; @@ -56,427 +56,387 @@ extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; // ** SCRIPT DRAWINGSURFACE OBJECT -void DrawingSurface_Release(ScriptDrawingSurface* sds) -{ - if (sds->roomBackgroundNumber >= 0) - { - if (sds->modified) - { - if (sds->roomBackgroundNumber == play.bg_frame) - { - invalidate_screen(); - mark_current_background_dirty(); - } - play.raw_modified[sds->roomBackgroundNumber] = 1; - } - - sds->roomBackgroundNumber = -1; - } - if (sds->roomMaskType > kRoomAreaNone) - { - if (sds->roomMaskType == kRoomAreaWalkBehind) - { - recache_walk_behinds(); - } - sds->roomMaskType = kRoomAreaNone; - } - if (sds->dynamicSpriteNumber >= 0) - { - if (sds->modified) - { - int tt; - // force a refresh of any cached object or character images - if (croom != nullptr) - { - for (tt = 0; tt < croom->numobj; tt++) - { - if (objs[tt].num == sds->dynamicSpriteNumber) - objcache[tt].sppic = -31999; - } - } - for (tt = 0; tt < game.numcharacters; tt++) - { - if (charcache[tt].sppic == sds->dynamicSpriteNumber) - charcache[tt].sppic = -31999; - } - for (tt = 0; tt < game.numgui; tt++) - { - if ((guis[tt].BgImage == sds->dynamicSpriteNumber) && - (guis[tt].IsDisplayed())) - { - guis_need_update = 1; - break; - } - } - } - - sds->dynamicSpriteNumber = -1; - } - if (sds->dynamicSurfaceNumber >= 0) - { - delete dynamicallyCreatedSurfaces[sds->dynamicSurfaceNumber]; - dynamicallyCreatedSurfaces[sds->dynamicSurfaceNumber] = nullptr; - sds->dynamicSurfaceNumber = -1; - } - sds->modified = 0; -} - -void ScriptDrawingSurface::PointToGameResolution(int *xcoord, int *ycoord) -{ - ctx_data_to_game_coord(*xcoord, *ycoord, highResCoordinates != 0); -} - -void ScriptDrawingSurface::SizeToGameResolution(int *width, int *height) -{ - ctx_data_to_game_size(*width, *height, highResCoordinates != 0); -} - -void ScriptDrawingSurface::SizeToGameResolution(int *valueToAdjust) -{ - *valueToAdjust = ctx_data_to_game_size(*valueToAdjust, highResCoordinates != 0); +void DrawingSurface_Release(ScriptDrawingSurface *sds) { + if (sds->roomBackgroundNumber >= 0) { + if (sds->modified) { + if (sds->roomBackgroundNumber == play.bg_frame) { + invalidate_screen(); + mark_current_background_dirty(); + } + play.raw_modified[sds->roomBackgroundNumber] = 1; + } + + sds->roomBackgroundNumber = -1; + } + if (sds->roomMaskType > kRoomAreaNone) { + if (sds->roomMaskType == kRoomAreaWalkBehind) { + recache_walk_behinds(); + } + sds->roomMaskType = kRoomAreaNone; + } + if (sds->dynamicSpriteNumber >= 0) { + if (sds->modified) { + int tt; + // force a refresh of any cached object or character images + if (croom != nullptr) { + for (tt = 0; tt < croom->numobj; tt++) { + if (objs[tt].num == sds->dynamicSpriteNumber) + objcache[tt].sppic = -31999; + } + } + for (tt = 0; tt < game.numcharacters; tt++) { + if (charcache[tt].sppic == sds->dynamicSpriteNumber) + charcache[tt].sppic = -31999; + } + for (tt = 0; tt < game.numgui; tt++) { + if ((guis[tt].BgImage == sds->dynamicSpriteNumber) && + (guis[tt].IsDisplayed())) { + guis_need_update = 1; + break; + } + } + } + + sds->dynamicSpriteNumber = -1; + } + if (sds->dynamicSurfaceNumber >= 0) { + delete dynamicallyCreatedSurfaces[sds->dynamicSurfaceNumber]; + dynamicallyCreatedSurfaces[sds->dynamicSurfaceNumber] = nullptr; + sds->dynamicSurfaceNumber = -1; + } + sds->modified = 0; +} + +void ScriptDrawingSurface::PointToGameResolution(int *xcoord, int *ycoord) { + ctx_data_to_game_coord(*xcoord, *ycoord, highResCoordinates != 0); +} + +void ScriptDrawingSurface::SizeToGameResolution(int *width, int *height) { + ctx_data_to_game_size(*width, *height, highResCoordinates != 0); +} + +void ScriptDrawingSurface::SizeToGameResolution(int *valueToAdjust) { + *valueToAdjust = ctx_data_to_game_size(*valueToAdjust, highResCoordinates != 0); } // convert actual co-ordinate back to what the script is expecting -void ScriptDrawingSurface::SizeToDataResolution(int *valueToAdjust) -{ - *valueToAdjust = game_to_ctx_data_size(*valueToAdjust, highResCoordinates != 0); -} - -ScriptDrawingSurface* DrawingSurface_CreateCopy(ScriptDrawingSurface *sds) -{ - Bitmap *sourceBitmap = sds->GetBitmapSurface(); - - for (int i = 0; i < MAX_DYNAMIC_SURFACES; i++) - { - if (dynamicallyCreatedSurfaces[i] == nullptr) - { - dynamicallyCreatedSurfaces[i] = BitmapHelper::CreateBitmapCopy(sourceBitmap); - ScriptDrawingSurface *newSurface = new ScriptDrawingSurface(); - newSurface->dynamicSurfaceNumber = i; - newSurface->hasAlphaChannel = sds->hasAlphaChannel; - ccRegisterManagedObject(newSurface, newSurface); - return newSurface; - } - } - - quit("!DrawingSurface.CreateCopy: too many copied surfaces created"); - return nullptr; -} - -void DrawingSurface_DrawImageImpl(ScriptDrawingSurface* sds, Bitmap* src, int dst_x, int dst_y, int trans, int dst_width, int dst_height, - int src_x, int src_y, int src_width, int src_height, int sprite_id, bool src_has_alpha) -{ - Bitmap *ds = sds->GetBitmapSurface(); - if (src == ds) - quit("!DrawingSurface.DrawImage: cannot draw onto itself"); - if ((trans < 0) || (trans > 100)) - quit("!DrawingSurface.DrawImage: invalid transparency setting"); - - if (trans == 100) - return; // fully transparent - if (dst_width < 1 || dst_height < 1 || src_width < 1 || src_height < 1) - return; // invalid src or dest rectangles - - // Setup uninitialized arguments; convert coordinates for legacy script mode - if (dst_width == SCR_NO_VALUE) { dst_width = src->GetWidth(); } - else { sds->SizeToGameResolution(&dst_width); } - if (dst_height == SCR_NO_VALUE) { dst_height = src->GetHeight(); } - else { sds->SizeToGameResolution(&dst_height); } - - if (src_x == SCR_NO_VALUE) { src_x = 0; } - if (src_y == SCR_NO_VALUE) { src_y = 0; } - sds->PointToGameResolution(&src_x, &src_y); - if (src_width == SCR_NO_VALUE) { src_width = src->GetWidth(); } - else { sds->SizeToGameResolution(&src_width); } - if (src_height == SCR_NO_VALUE) { src_height = src->GetHeight(); } - else { sds->SizeToGameResolution(&src_height); } - - if (dst_x >= ds->GetWidth() || dst_x + dst_width <= 0 || dst_y >= ds->GetHeight() || dst_y + dst_height <= 0 || - src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0) - return; // source or destination rects lie completely off surface - // Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that) - Math::ClampLength(src_x, src_width, 0, src->GetWidth()); - Math::ClampLength(src_y, src_height, 0, src->GetHeight()); - - // TODO: possibly optimize by not making a stretched intermediate bitmap - // if simplier blit/draw_sprite could be called (no translucency with alpha channel). - bool needToFreeBitmap = false; - if (dst_width != src->GetWidth() || dst_height != src->GetHeight() || - src_width != src->GetWidth() || src_height != src->GetHeight()) - { - // Resize and/or partial copy specified - Bitmap *newPic = BitmapHelper::CreateBitmap(dst_width, dst_height, src->GetColorDepth()); - newPic->StretchBlt(src, - RectWH(src_x, src_y, src_width, src_height), - RectWH(0, 0, dst_width, dst_height)); - - src = newPic; - needToFreeBitmap = true; - update_polled_stuff_if_runtime(); - } - - ds = sds->StartDrawing(); - sds->PointToGameResolution(&dst_x, &dst_y); - - if (src->GetColorDepth() != ds->GetColorDepth()) { - if (sprite_id >= 0) - debug_script_warn("DrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", sprite_id, src->GetColorDepth(), ds->GetColorDepth()); - else - debug_script_warn("DrawImage: Source image colour depth %d-bit not same as background depth %d-bit", src->GetColorDepth(), ds->GetColorDepth()); - } - - draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, src_has_alpha, - kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans)); - - sds->FinishedDrawing(); - - if (needToFreeBitmap) - delete src; -} - -void DrawingSurface_DrawImageEx(ScriptDrawingSurface* sds, int dst_x, int dst_y, int slot, int trans, int dst_width, int dst_height, - int src_x, int src_y, int src_width, int src_height) -{ - if ((slot < 0) || (spriteset[slot] == nullptr)) - quit("!DrawingSurface.DrawImage: invalid sprite slot number specified"); - DrawingSurface_DrawImageImpl(sds, spriteset[slot], dst_x, dst_y, trans, dst_width, dst_height, - src_x, src_y, src_width, src_height, slot, (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); -} - -void DrawingSurface_DrawImage(ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height) -{ - DrawingSurface_DrawImageEx(sds, xx, yy, slot, trans, width, height, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE); -} - -void DrawingSurface_DrawSurfaceEx(ScriptDrawingSurface* target, ScriptDrawingSurface* source, int trans, +void ScriptDrawingSurface::SizeToDataResolution(int *valueToAdjust) { + *valueToAdjust = game_to_ctx_data_size(*valueToAdjust, highResCoordinates != 0); +} + +ScriptDrawingSurface *DrawingSurface_CreateCopy(ScriptDrawingSurface *sds) { + Bitmap *sourceBitmap = sds->GetBitmapSurface(); + + for (int i = 0; i < MAX_DYNAMIC_SURFACES; i++) { + if (dynamicallyCreatedSurfaces[i] == nullptr) { + dynamicallyCreatedSurfaces[i] = BitmapHelper::CreateBitmapCopy(sourceBitmap); + ScriptDrawingSurface *newSurface = new ScriptDrawingSurface(); + newSurface->dynamicSurfaceNumber = i; + newSurface->hasAlphaChannel = sds->hasAlphaChannel; + ccRegisterManagedObject(newSurface, newSurface); + return newSurface; + } + } + + quit("!DrawingSurface.CreateCopy: too many copied surfaces created"); + return nullptr; +} + +void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src, int dst_x, int dst_y, int trans, int dst_width, int dst_height, + int src_x, int src_y, int src_width, int src_height, int sprite_id, bool src_has_alpha) { + Bitmap *ds = sds->GetBitmapSurface(); + if (src == ds) + quit("!DrawingSurface.DrawImage: cannot draw onto itself"); + if ((trans < 0) || (trans > 100)) + quit("!DrawingSurface.DrawImage: invalid transparency setting"); + + if (trans == 100) + return; // fully transparent + if (dst_width < 1 || dst_height < 1 || src_width < 1 || src_height < 1) + return; // invalid src or dest rectangles + + // Setup uninitialized arguments; convert coordinates for legacy script mode + if (dst_width == SCR_NO_VALUE) { + dst_width = src->GetWidth(); + } else { + sds->SizeToGameResolution(&dst_width); + } + if (dst_height == SCR_NO_VALUE) { + dst_height = src->GetHeight(); + } else { + sds->SizeToGameResolution(&dst_height); + } + + if (src_x == SCR_NO_VALUE) { + src_x = 0; + } + if (src_y == SCR_NO_VALUE) { + src_y = 0; + } + sds->PointToGameResolution(&src_x, &src_y); + if (src_width == SCR_NO_VALUE) { + src_width = src->GetWidth(); + } else { + sds->SizeToGameResolution(&src_width); + } + if (src_height == SCR_NO_VALUE) { + src_height = src->GetHeight(); + } else { + sds->SizeToGameResolution(&src_height); + } + + if (dst_x >= ds->GetWidth() || dst_x + dst_width <= 0 || dst_y >= ds->GetHeight() || dst_y + dst_height <= 0 || + src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0) + return; // source or destination rects lie completely off surface + // Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that) + Math::ClampLength(src_x, src_width, 0, src->GetWidth()); + Math::ClampLength(src_y, src_height, 0, src->GetHeight()); + + // TODO: possibly optimize by not making a stretched intermediate bitmap + // if simplier blit/draw_sprite could be called (no translucency with alpha channel). + bool needToFreeBitmap = false; + if (dst_width != src->GetWidth() || dst_height != src->GetHeight() || + src_width != src->GetWidth() || src_height != src->GetHeight()) { + // Resize and/or partial copy specified + Bitmap *newPic = BitmapHelper::CreateBitmap(dst_width, dst_height, src->GetColorDepth()); + newPic->StretchBlt(src, + RectWH(src_x, src_y, src_width, src_height), + RectWH(0, 0, dst_width, dst_height)); + + src = newPic; + needToFreeBitmap = true; + update_polled_stuff_if_runtime(); + } + + ds = sds->StartDrawing(); + sds->PointToGameResolution(&dst_x, &dst_y); + + if (src->GetColorDepth() != ds->GetColorDepth()) { + if (sprite_id >= 0) + debug_script_warn("DrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", sprite_id, src->GetColorDepth(), ds->GetColorDepth()); + else + debug_script_warn("DrawImage: Source image colour depth %d-bit not same as background depth %d-bit", src->GetColorDepth(), ds->GetColorDepth()); + } + + draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, src_has_alpha, + kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans)); + + sds->FinishedDrawing(); + + if (needToFreeBitmap) + delete src; +} + +void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds, int dst_x, int dst_y, int slot, int trans, int dst_width, int dst_height, + int src_x, int src_y, int src_width, int src_height) { + if ((slot < 0) || (spriteset[slot] == nullptr)) + quit("!DrawingSurface.DrawImage: invalid sprite slot number specified"); + DrawingSurface_DrawImageImpl(sds, spriteset[slot], dst_x, dst_y, trans, dst_width, dst_height, + src_x, src_y, src_width, src_height, slot, (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); +} + +void DrawingSurface_DrawImage(ScriptDrawingSurface *sds, int xx, int yy, int slot, int trans, int width, int height) { + DrawingSurface_DrawImageEx(sds, xx, yy, slot, trans, width, height, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE); +} + +void DrawingSurface_DrawSurfaceEx(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans, int dst_x, int dst_y, int dst_width, int dst_height, - int src_x, int src_y, int src_width, int src_height) -{ - DrawingSurface_DrawImageImpl(target, source->GetBitmapSurface(), dst_x, dst_y, trans, dst_width, dst_height, - src_x, src_y, src_width, src_height, -1, source->hasAlphaChannel); -} + int src_x, int src_y, int src_width, int src_height) { + DrawingSurface_DrawImageImpl(target, source->GetBitmapSurface(), dst_x, dst_y, trans, dst_width, dst_height, + src_x, src_y, src_width, src_height, -1, source->hasAlphaChannel); +} + +void DrawingSurface_DrawSurface(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans) { + DrawingSurface_DrawSurfaceEx(target, source, trans, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE); +} + +void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour) { + sds->currentColourScript = newColour; + // StartDrawing to set up ds to set the colour at the appropriate + // depth for the background + Bitmap *ds = sds->StartDrawing(); + if (newColour == SCR_COLOR_TRANSPARENT) { + sds->currentColour = ds->GetMaskColor(); + } else { + sds->currentColour = ds->GetCompatibleColor(newColour); + } + sds->FinishedDrawingReadOnly(); +} + +int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds) { + return sds->currentColourScript; +} + +void DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface *sds, int highRes) { + if (game.AllowRelativeRes()) + sds->highResCoordinates = (highRes) ? 1 : 0; +} + +int DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface *sds) { + return sds->highResCoordinates; +} + +int DrawingSurface_GetHeight(ScriptDrawingSurface *sds) { + Bitmap *ds = sds->GetBitmapSurface(); + int height = ds->GetHeight(); + sds->SizeToGameResolution(&height); + return height; +} + +int DrawingSurface_GetWidth(ScriptDrawingSurface *sds) { + Bitmap *ds = sds->GetBitmapSurface(); + int width = ds->GetWidth(); + sds->SizeToGameResolution(&width); + return width; +} + +void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour) { + Bitmap *ds = sds->StartDrawing(); + int allegroColor; + if ((colour == -SCR_NO_VALUE) || (colour == SCR_COLOR_TRANSPARENT)) { + allegroColor = ds->GetMaskColor(); + } else { + allegroColor = ds->GetCompatibleColor(colour); + } + ds->Fill(allegroColor); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius) { + sds->PointToGameResolution(&x, &y); + sds->SizeToGameResolution(&radius); + + Bitmap *ds = sds->StartDrawing(); + ds->FillCircle(Circle(x, y, radius), sds->currentColour); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2) { + sds->PointToGameResolution(&x1, &y1); + sds->PointToGameResolution(&x2, &y2); + + Bitmap *ds = sds->StartDrawing(); + ds->FillRect(Rect(x1, y1, x2, y2), sds->currentColour); + sds->FinishedDrawing(); +} + +void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3) { + sds->PointToGameResolution(&x1, &y1); + sds->PointToGameResolution(&x2, &y2); + sds->PointToGameResolution(&x3, &y3); -void DrawingSurface_DrawSurface(ScriptDrawingSurface* target, ScriptDrawingSurface* source, int trans) -{ - DrawingSurface_DrawSurfaceEx(target, source, trans, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE, 0, 0, SCR_NO_VALUE, SCR_NO_VALUE); + Bitmap *ds = sds->StartDrawing(); + ds->DrawTriangle(Triangle(x1, y1, x2, y2, x3, y3), sds->currentColour); + sds->FinishedDrawing(); } -void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour) -{ - sds->currentColourScript = newColour; - // StartDrawing to set up ds to set the colour at the appropriate - // depth for the background - Bitmap *ds = sds->StartDrawing(); - if (newColour == SCR_COLOR_TRANSPARENT) - { - sds->currentColour = ds->GetMaskColor(); - } - else - { - sds->currentColour = ds->GetCompatibleColor(newColour); - } - sds->FinishedDrawingReadOnly(); -} - -int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds) -{ - return sds->currentColourScript; -} - -void DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface *sds, int highRes) -{ - if (game.AllowRelativeRes()) - sds->highResCoordinates = (highRes) ? 1 : 0; -} - -int DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface *sds) -{ - return sds->highResCoordinates; -} - -int DrawingSurface_GetHeight(ScriptDrawingSurface *sds) -{ - Bitmap *ds = sds->GetBitmapSurface(); - int height = ds->GetHeight(); - sds->SizeToGameResolution(&height); - return height; -} - -int DrawingSurface_GetWidth(ScriptDrawingSurface *sds) -{ - Bitmap *ds = sds->GetBitmapSurface(); - int width = ds->GetWidth(); - sds->SizeToGameResolution(&width); - return width; -} - -void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour) -{ - Bitmap *ds = sds->StartDrawing(); - int allegroColor; - if ((colour == -SCR_NO_VALUE) || (colour == SCR_COLOR_TRANSPARENT)) - { - allegroColor = ds->GetMaskColor(); - } - else - { - allegroColor = ds->GetCompatibleColor(colour); - } - ds->Fill(allegroColor); - sds->FinishedDrawing(); -} - -void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius) -{ - sds->PointToGameResolution(&x, &y); - sds->SizeToGameResolution(&radius); - - Bitmap *ds = sds->StartDrawing(); - ds->FillCircle(Circle(x, y, radius), sds->currentColour); - sds->FinishedDrawing(); -} - -void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2) -{ - sds->PointToGameResolution(&x1, &y1); - sds->PointToGameResolution(&x2, &y2); - - Bitmap *ds = sds->StartDrawing(); - ds->FillRect(Rect(x1,y1,x2,y2), sds->currentColour); - sds->FinishedDrawing(); -} - -void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3) -{ - sds->PointToGameResolution(&x1, &y1); - sds->PointToGameResolution(&x2, &y2); - sds->PointToGameResolution(&x3, &y3); - - Bitmap *ds = sds->StartDrawing(); - ds->DrawTriangle(Triangle(x1,y1,x2,y2,x3,y3), sds->currentColour); - sds->FinishedDrawing(); -} - -void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char* text) -{ - sds->PointToGameResolution(&xx, &yy); - Bitmap *ds = sds->StartDrawing(); - // don't use wtextcolor because it will do a 16->32 conversion - color_t text_color = sds->currentColour; - if ((ds->GetColorDepth() <= 8) && (play.raw_color > 255)) { - text_color = ds->GetCompatibleColor(1); - debug_script_warn ("RawPrint: Attempted to use hi-color on 256-col background"); - } - wouttext_outline(ds, xx, yy, font, text_color, text); - sds->FinishedDrawing(); +void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char *text) { + sds->PointToGameResolution(&xx, &yy); + Bitmap *ds = sds->StartDrawing(); + // don't use wtextcolor because it will do a 16->32 conversion + color_t text_color = sds->currentColour; + if ((ds->GetColorDepth() <= 8) && (play.raw_color > 255)) { + text_color = ds->GetCompatibleColor(1); + debug_script_warn("RawPrint: Attempted to use hi-color on 256-col background"); + } + wouttext_outline(ds, xx, yy, font, text_color, text); + sds->FinishedDrawing(); } void DrawingSurface_DrawStringWrapped_Old(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) { - DrawingSurface_DrawStringWrapped(sds, xx, yy, wid, font, ConvertLegacyScriptAlignment((LegacyScriptAlignment)alignment), msg); + DrawingSurface_DrawStringWrapped(sds, xx, yy, wid, font, ConvertLegacyScriptAlignment((LegacyScriptAlignment)alignment), msg); } void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) { - int linespacing = getfontspacing_outlined(font); - sds->PointToGameResolution(&xx, &yy); - sds->SizeToGameResolution(&wid); + int linespacing = getfontspacing_outlined(font); + sds->PointToGameResolution(&xx, &yy); + sds->SizeToGameResolution(&wid); - if (break_up_text_into_lines(msg, Lines, wid, font) == 0) - return; + if (break_up_text_into_lines(msg, Lines, wid, font) == 0) + return; - Bitmap *ds = sds->StartDrawing(); - color_t text_color = sds->currentColour; + Bitmap *ds = sds->StartDrawing(); + color_t text_color = sds->currentColour; - for (size_t i = 0; i < Lines.Count(); i++) - { - int drawAtX = xx; + for (size_t i = 0; i < Lines.Count(); i++) { + int drawAtX = xx; - if (alignment & kMAlignHCenter) - { - drawAtX = xx + ((wid / 2) - wgettextwidth(Lines[i], font) / 2); - } - else if (alignment & kMAlignRight) - { - drawAtX = (xx + wid) - wgettextwidth(Lines[i], font); - } + if (alignment & kMAlignHCenter) { + drawAtX = xx + ((wid / 2) - wgettextwidth(Lines[i], font) / 2); + } else if (alignment & kMAlignRight) { + drawAtX = (xx + wid) - wgettextwidth(Lines[i], font); + } - wouttext_outline(ds, drawAtX, yy + linespacing*i, font, text_color, Lines[i]); - } + wouttext_outline(ds, drawAtX, yy + linespacing * i, font, text_color, Lines[i]); + } - sds->FinishedDrawing(); + sds->FinishedDrawing(); } -void DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm) -{ - char displbuf[3000]; - get_message_text(msgm, displbuf); - // it's probably too late but check anyway - if (strlen(displbuf) > 2899) - quit("!RawPrintMessageWrapped: message too long"); +void DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm) { + char displbuf[3000]; + get_message_text(msgm, displbuf); + // it's probably too late but check anyway + if (strlen(displbuf) > 2899) + quit("!RawPrintMessageWrapped: message too long"); - DrawingSurface_DrawStringWrapped_Old(sds, xx, yy, wid, font, kLegacyScAlignLeft, displbuf); + DrawingSurface_DrawStringWrapped_Old(sds, xx, yy, wid, font, kLegacyScAlignLeft, displbuf); } void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness) { - sds->PointToGameResolution(&fromx, &fromy); - sds->PointToGameResolution(&tox, &toy); - sds->SizeToGameResolution(&thickness); - int ii,jj,xx,yy; - Bitmap *ds = sds->StartDrawing(); - // draw several lines to simulate the thickness - color_t draw_color = sds->currentColour; - for (ii = 0; ii < thickness; ii++) - { - xx = (ii - (thickness / 2)); - for (jj = 0; jj < thickness; jj++) - { - yy = (jj - (thickness / 2)); - ds->DrawLine (Line(fromx + xx, fromy + yy, tox + xx, toy + yy), draw_color); - } - } - sds->FinishedDrawing(); + sds->PointToGameResolution(&fromx, &fromy); + sds->PointToGameResolution(&tox, &toy); + sds->SizeToGameResolution(&thickness); + int ii, jj, xx, yy; + Bitmap *ds = sds->StartDrawing(); + // draw several lines to simulate the thickness + color_t draw_color = sds->currentColour; + for (ii = 0; ii < thickness; ii++) { + xx = (ii - (thickness / 2)); + for (jj = 0; jj < thickness; jj++) { + yy = (jj - (thickness / 2)); + ds->DrawLine(Line(fromx + xx, fromy + yy, tox + xx, toy + yy), draw_color); + } + } + sds->FinishedDrawing(); } void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y) { - sds->PointToGameResolution(&x, &y); - int thickness = 1; - sds->SizeToGameResolution(&thickness); - int ii,jj; - Bitmap *ds = sds->StartDrawing(); - // draw several pixels to simulate the thickness - color_t draw_color = sds->currentColour; - for (ii = 0; ii < thickness; ii++) - { - for (jj = 0; jj < thickness; jj++) - { - ds->PutPixel(x + ii, y + jj, draw_color); - } - } - sds->FinishedDrawing(); + sds->PointToGameResolution(&x, &y); + int thickness = 1; + sds->SizeToGameResolution(&thickness); + int ii, jj; + Bitmap *ds = sds->StartDrawing(); + // draw several pixels to simulate the thickness + color_t draw_color = sds->currentColour; + for (ii = 0; ii < thickness; ii++) { + for (jj = 0; jj < thickness; jj++) { + ds->PutPixel(x + ii, y + jj, draw_color); + } + } + sds->FinishedDrawing(); } int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) { - sds->PointToGameResolution(&x, &y); - Bitmap *ds = sds->StartDrawing(); - unsigned int rawPixel = ds->GetPixel(x, y); - unsigned int maskColor = ds->GetMaskColor(); - int colDepth = ds->GetColorDepth(); + sds->PointToGameResolution(&x, &y); + Bitmap *ds = sds->StartDrawing(); + unsigned int rawPixel = ds->GetPixel(x, y); + unsigned int maskColor = ds->GetMaskColor(); + int colDepth = ds->GetColorDepth(); - if (rawPixel == maskColor) - { - rawPixel = SCR_COLOR_TRANSPARENT; - } - else if (colDepth > 8) - { - int r = getr_depth(colDepth, rawPixel); - int ds = getg_depth(colDepth, rawPixel); - int b = getb_depth(colDepth, rawPixel); + if (rawPixel == maskColor) { + rawPixel = SCR_COLOR_TRANSPARENT; + } else if (colDepth > 8) { + int r = getr_depth(colDepth, rawPixel); + int ds = getg_depth(colDepth, rawPixel); + int b = getb_depth(colDepth, rawPixel); - rawPixel = Game_GetColorFromRGB(r, ds, b); - } + rawPixel = Game_GetColorFromRGB(r, ds, b); + } - sds->FinishedDrawingReadOnly(); + sds->FinishedDrawingReadOnly(); - return rawPixel; + return rawPixel; } //============================================================================= @@ -490,147 +450,124 @@ int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) { #include "script/script_runtime.h" // void (ScriptDrawingSurface *sds, int colour) -RuntimeScriptValue Sc_DrawingSurface_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_Clear); +RuntimeScriptValue Sc_DrawingSurface_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_Clear); } // ScriptDrawingSurface* (ScriptDrawingSurface *sds) -RuntimeScriptValue Sc_DrawingSurface_CreateCopy(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJAUTO(ScriptDrawingSurface, ScriptDrawingSurface, DrawingSurface_CreateCopy); +RuntimeScriptValue Sc_DrawingSurface_CreateCopy(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJAUTO(ScriptDrawingSurface, ScriptDrawingSurface, DrawingSurface_CreateCopy); } // void (ScriptDrawingSurface *sds, int x, int y, int radius) -RuntimeScriptValue Sc_DrawingSurface_DrawCircle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(ScriptDrawingSurface, DrawingSurface_DrawCircle); +RuntimeScriptValue Sc_DrawingSurface_DrawCircle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(ScriptDrawingSurface, DrawingSurface_DrawCircle); } // void (ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height) -RuntimeScriptValue Sc_DrawingSurface_DrawImage_6(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawImage); +RuntimeScriptValue Sc_DrawingSurface_DrawImage_6(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawImage); } -RuntimeScriptValue Sc_DrawingSurface_DrawImage(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_OBJ_PARAM_COUNT(METHOD, 10); - DrawingSurface_DrawImageEx((ScriptDrawingSurface*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, - params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_DrawingSurface_DrawImage(void *self, const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_OBJ_PARAM_COUNT(METHOD, 10); + DrawingSurface_DrawImageEx((ScriptDrawingSurface *)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, + params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); + return RuntimeScriptValue((int32_t)0); } // void (ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness) -RuntimeScriptValue Sc_DrawingSurface_DrawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawLine); +RuntimeScriptValue Sc_DrawingSurface_DrawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawLine); } // void (ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm) -RuntimeScriptValue Sc_DrawingSurface_DrawMessageWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawMessageWrapped); +RuntimeScriptValue Sc_DrawingSurface_DrawMessageWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(ScriptDrawingSurface, DrawingSurface_DrawMessageWrapped); } // void (ScriptDrawingSurface *sds, int x, int y) -RuntimeScriptValue Sc_DrawingSurface_DrawPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptDrawingSurface, DrawingSurface_DrawPixel); +RuntimeScriptValue Sc_DrawingSurface_DrawPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptDrawingSurface, DrawingSurface_DrawPixel); } // void (ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2) -RuntimeScriptValue Sc_DrawingSurface_DrawRectangle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(ScriptDrawingSurface, DrawingSurface_DrawRectangle); +RuntimeScriptValue Sc_DrawingSurface_DrawRectangle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(ScriptDrawingSurface, DrawingSurface_DrawRectangle); } // void (ScriptDrawingSurface *sds, int xx, int yy, int font, const char* texx, ...) -RuntimeScriptValue Sc_DrawingSurface_DrawString(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_SCRIPT_SPRINTF(DrawingSurface_DrawString, 4); - DrawingSurface_DrawString((ScriptDrawingSurface*)self, params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_DrawingSurface_DrawString(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_SCRIPT_SPRINTF(DrawingSurface_DrawString, 4); + DrawingSurface_DrawString((ScriptDrawingSurface *)self, params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg) -RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped_Old, const char); +RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped_Old(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped_Old, const char); } -RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped, const char); +RuntimeScriptValue Sc_DrawingSurface_DrawStringWrapped(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5_POBJ(ScriptDrawingSurface, DrawingSurface_DrawStringWrapped, const char); } // void (ScriptDrawingSurface* target, ScriptDrawingSurface* source, int translev) -RuntimeScriptValue Sc_DrawingSurface_DrawSurface_2(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ_PINT(ScriptDrawingSurface, DrawingSurface_DrawSurface, ScriptDrawingSurface); +RuntimeScriptValue Sc_DrawingSurface_DrawSurface_2(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ_PINT(ScriptDrawingSurface, DrawingSurface_DrawSurface, ScriptDrawingSurface); } -RuntimeScriptValue Sc_DrawingSurface_DrawSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_OBJ_PARAM_COUNT(METHOD, 10); - DrawingSurface_DrawSurfaceEx((ScriptDrawingSurface*)self, (ScriptDrawingSurface*)params[0].Ptr, - params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, - params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_DrawingSurface_DrawSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_OBJ_PARAM_COUNT(METHOD, 10); + DrawingSurface_DrawSurfaceEx((ScriptDrawingSurface *)self, (ScriptDrawingSurface *)params[0].Ptr, + params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, + params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); + return RuntimeScriptValue((int32_t)0); } // void (ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3) -RuntimeScriptValue Sc_DrawingSurface_DrawTriangle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawTriangle); +RuntimeScriptValue Sc_DrawingSurface_DrawTriangle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT6(ScriptDrawingSurface, DrawingSurface_DrawTriangle); } // int (ScriptDrawingSurface *sds, int x, int y) -RuntimeScriptValue Sc_DrawingSurface_GetPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT2(ScriptDrawingSurface, DrawingSurface_GetPixel); +RuntimeScriptValue Sc_DrawingSurface_GetPixel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT2(ScriptDrawingSurface, DrawingSurface_GetPixel); } // void (ScriptDrawingSurface* sds) -RuntimeScriptValue Sc_DrawingSurface_Release(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptDrawingSurface, DrawingSurface_Release); +RuntimeScriptValue Sc_DrawingSurface_Release(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptDrawingSurface, DrawingSurface_Release); } // int (ScriptDrawingSurface *sds) -RuntimeScriptValue Sc_DrawingSurface_GetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetDrawingColor); +RuntimeScriptValue Sc_DrawingSurface_GetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetDrawingColor); } // void (ScriptDrawingSurface *sds, int newColour) -RuntimeScriptValue Sc_DrawingSurface_SetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetDrawingColor); +RuntimeScriptValue Sc_DrawingSurface_SetDrawingColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetDrawingColor); } // int (ScriptDrawingSurface *sds) -RuntimeScriptValue Sc_DrawingSurface_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetHeight); +RuntimeScriptValue Sc_DrawingSurface_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetHeight); } // int (ScriptDrawingSurface *sds) -RuntimeScriptValue Sc_DrawingSurface_GetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetUseHighResCoordinates); +RuntimeScriptValue Sc_DrawingSurface_GetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetUseHighResCoordinates); } // void (ScriptDrawingSurface *sds, int highRes) -RuntimeScriptValue Sc_DrawingSurface_SetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetUseHighResCoordinates); +RuntimeScriptValue Sc_DrawingSurface_SetUseHighResCoordinates(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_SetUseHighResCoordinates); } // int (ScriptDrawingSurface *sds) -RuntimeScriptValue Sc_DrawingSurface_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetWidth); +RuntimeScriptValue Sc_DrawingSurface_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDrawingSurface, DrawingSurface_GetWidth); } //============================================================================= @@ -640,63 +577,61 @@ RuntimeScriptValue Sc_DrawingSurface_GetWidth(void *self, const RuntimeScriptVal //============================================================================= // void (ScriptDrawingSurface *sds, int xx, int yy, int font, const char* texx, ...) -void ScPl_DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char* texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - DrawingSurface_DrawString(sds, xx, yy, font, scsf_buffer); -} - -void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) -{ - ccAddExternalObjectFunction("DrawingSurface::Clear^1", Sc_DrawingSurface_Clear); - ccAddExternalObjectFunction("DrawingSurface::CreateCopy^0", Sc_DrawingSurface_CreateCopy); - ccAddExternalObjectFunction("DrawingSurface::DrawCircle^3", Sc_DrawingSurface_DrawCircle); - ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage_6); - ccAddExternalObjectFunction("DrawingSurface::DrawImage^10", Sc_DrawingSurface_DrawImage); - ccAddExternalObjectFunction("DrawingSurface::DrawLine^5", Sc_DrawingSurface_DrawLine); - ccAddExternalObjectFunction("DrawingSurface::DrawMessageWrapped^5", Sc_DrawingSurface_DrawMessageWrapped); - ccAddExternalObjectFunction("DrawingSurface::DrawPixel^2", Sc_DrawingSurface_DrawPixel); - ccAddExternalObjectFunction("DrawingSurface::DrawRectangle^4", Sc_DrawingSurface_DrawRectangle); - ccAddExternalObjectFunction("DrawingSurface::DrawString^104", Sc_DrawingSurface_DrawString); - if (base_api < kScriptAPI_v350) - ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped_Old); - else - ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped); - ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface_2); - ccAddExternalObjectFunction("DrawingSurface::DrawSurface^10", Sc_DrawingSurface_DrawSurface); - ccAddExternalObjectFunction("DrawingSurface::DrawTriangle^6", Sc_DrawingSurface_DrawTriangle); - ccAddExternalObjectFunction("DrawingSurface::GetPixel^2", Sc_DrawingSurface_GetPixel); - ccAddExternalObjectFunction("DrawingSurface::Release^0", Sc_DrawingSurface_Release); - ccAddExternalObjectFunction("DrawingSurface::get_DrawingColor", Sc_DrawingSurface_GetDrawingColor); - ccAddExternalObjectFunction("DrawingSurface::set_DrawingColor", Sc_DrawingSurface_SetDrawingColor); - ccAddExternalObjectFunction("DrawingSurface::get_Height", Sc_DrawingSurface_GetHeight); - ccAddExternalObjectFunction("DrawingSurface::get_UseHighResCoordinates", Sc_DrawingSurface_GetUseHighResCoordinates); - ccAddExternalObjectFunction("DrawingSurface::set_UseHighResCoordinates", Sc_DrawingSurface_SetUseHighResCoordinates); - ccAddExternalObjectFunction("DrawingSurface::get_Width", Sc_DrawingSurface_GetWidth); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("DrawingSurface::Clear^1", (void*)DrawingSurface_Clear); - ccAddExternalFunctionForPlugin("DrawingSurface::CreateCopy^0", (void*)DrawingSurface_CreateCopy); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawCircle^3", (void*)DrawingSurface_DrawCircle); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawImage^6", (void*)DrawingSurface_DrawImage); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawLine^5", (void*)DrawingSurface_DrawLine); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawMessageWrapped^5", (void*)DrawingSurface_DrawMessageWrapped); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawPixel^2", (void*)DrawingSurface_DrawPixel); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawRectangle^4", (void*)DrawingSurface_DrawRectangle); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawString^104", (void*)ScPl_DrawingSurface_DrawString); - if (base_api < kScriptAPI_v350) - ccAddExternalFunctionForPlugin("DrawingSurface::DrawStringWrapped^6", (void*)DrawingSurface_DrawStringWrapped_Old); - else - ccAddExternalFunctionForPlugin("DrawingSurface::DrawStringWrapped^6", (void*)DrawingSurface_DrawStringWrapped); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawSurface^2", (void*)DrawingSurface_DrawSurface); - ccAddExternalFunctionForPlugin("DrawingSurface::DrawTriangle^6", (void*)DrawingSurface_DrawTriangle); - ccAddExternalFunctionForPlugin("DrawingSurface::GetPixel^2", (void*)DrawingSurface_GetPixel); - ccAddExternalFunctionForPlugin("DrawingSurface::Release^0", (void*)DrawingSurface_Release); - ccAddExternalFunctionForPlugin("DrawingSurface::get_DrawingColor", (void*)DrawingSurface_GetDrawingColor); - ccAddExternalFunctionForPlugin("DrawingSurface::set_DrawingColor", (void*)DrawingSurface_SetDrawingColor); - ccAddExternalFunctionForPlugin("DrawingSurface::get_Height", (void*)DrawingSurface_GetHeight); - ccAddExternalFunctionForPlugin("DrawingSurface::get_UseHighResCoordinates", (void*)DrawingSurface_GetUseHighResCoordinates); - ccAddExternalFunctionForPlugin("DrawingSurface::set_UseHighResCoordinates", (void*)DrawingSurface_SetUseHighResCoordinates); - ccAddExternalFunctionForPlugin("DrawingSurface::get_Width", (void*)DrawingSurface_GetWidth); +void ScPl_DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + DrawingSurface_DrawString(sds, xx, yy, font, scsf_buffer); +} + +void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) { + ccAddExternalObjectFunction("DrawingSurface::Clear^1", Sc_DrawingSurface_Clear); + ccAddExternalObjectFunction("DrawingSurface::CreateCopy^0", Sc_DrawingSurface_CreateCopy); + ccAddExternalObjectFunction("DrawingSurface::DrawCircle^3", Sc_DrawingSurface_DrawCircle); + ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage_6); + ccAddExternalObjectFunction("DrawingSurface::DrawImage^10", Sc_DrawingSurface_DrawImage); + ccAddExternalObjectFunction("DrawingSurface::DrawLine^5", Sc_DrawingSurface_DrawLine); + ccAddExternalObjectFunction("DrawingSurface::DrawMessageWrapped^5", Sc_DrawingSurface_DrawMessageWrapped); + ccAddExternalObjectFunction("DrawingSurface::DrawPixel^2", Sc_DrawingSurface_DrawPixel); + ccAddExternalObjectFunction("DrawingSurface::DrawRectangle^4", Sc_DrawingSurface_DrawRectangle); + ccAddExternalObjectFunction("DrawingSurface::DrawString^104", Sc_DrawingSurface_DrawString); + if (base_api < kScriptAPI_v350) + ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped_Old); + else + ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped); + ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface_2); + ccAddExternalObjectFunction("DrawingSurface::DrawSurface^10", Sc_DrawingSurface_DrawSurface); + ccAddExternalObjectFunction("DrawingSurface::DrawTriangle^6", Sc_DrawingSurface_DrawTriangle); + ccAddExternalObjectFunction("DrawingSurface::GetPixel^2", Sc_DrawingSurface_GetPixel); + ccAddExternalObjectFunction("DrawingSurface::Release^0", Sc_DrawingSurface_Release); + ccAddExternalObjectFunction("DrawingSurface::get_DrawingColor", Sc_DrawingSurface_GetDrawingColor); + ccAddExternalObjectFunction("DrawingSurface::set_DrawingColor", Sc_DrawingSurface_SetDrawingColor); + ccAddExternalObjectFunction("DrawingSurface::get_Height", Sc_DrawingSurface_GetHeight); + ccAddExternalObjectFunction("DrawingSurface::get_UseHighResCoordinates", Sc_DrawingSurface_GetUseHighResCoordinates); + ccAddExternalObjectFunction("DrawingSurface::set_UseHighResCoordinates", Sc_DrawingSurface_SetUseHighResCoordinates); + ccAddExternalObjectFunction("DrawingSurface::get_Width", Sc_DrawingSurface_GetWidth); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DrawingSurface::Clear^1", (void *)DrawingSurface_Clear); + ccAddExternalFunctionForPlugin("DrawingSurface::CreateCopy^0", (void *)DrawingSurface_CreateCopy); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawCircle^3", (void *)DrawingSurface_DrawCircle); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawImage^6", (void *)DrawingSurface_DrawImage); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawLine^5", (void *)DrawingSurface_DrawLine); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawMessageWrapped^5", (void *)DrawingSurface_DrawMessageWrapped); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawPixel^2", (void *)DrawingSurface_DrawPixel); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawRectangle^4", (void *)DrawingSurface_DrawRectangle); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawString^104", (void *)ScPl_DrawingSurface_DrawString); + if (base_api < kScriptAPI_v350) + ccAddExternalFunctionForPlugin("DrawingSurface::DrawStringWrapped^6", (void *)DrawingSurface_DrawStringWrapped_Old); + else + ccAddExternalFunctionForPlugin("DrawingSurface::DrawStringWrapped^6", (void *)DrawingSurface_DrawStringWrapped); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawSurface^2", (void *)DrawingSurface_DrawSurface); + ccAddExternalFunctionForPlugin("DrawingSurface::DrawTriangle^6", (void *)DrawingSurface_DrawTriangle); + ccAddExternalFunctionForPlugin("DrawingSurface::GetPixel^2", (void *)DrawingSurface_GetPixel); + ccAddExternalFunctionForPlugin("DrawingSurface::Release^0", (void *)DrawingSurface_Release); + ccAddExternalFunctionForPlugin("DrawingSurface::get_DrawingColor", (void *)DrawingSurface_GetDrawingColor); + ccAddExternalFunctionForPlugin("DrawingSurface::set_DrawingColor", (void *)DrawingSurface_SetDrawingColor); + ccAddExternalFunctionForPlugin("DrawingSurface::get_Height", (void *)DrawingSurface_GetHeight); + ccAddExternalFunctionForPlugin("DrawingSurface::get_UseHighResCoordinates", (void *)DrawingSurface_GetUseHighResCoordinates); + ccAddExternalFunctionForPlugin("DrawingSurface::set_UseHighResCoordinates", (void *)DrawingSurface_SetUseHighResCoordinates); + ccAddExternalFunctionForPlugin("DrawingSurface::get_Width", (void *)DrawingSurface_GetWidth); } diff --git a/engines/ags/engine/ac/drawingsurface.h b/engines/ags/engine/ac/drawingsurface.h index 20737be5a4aa..5878f2a83775 100644 --- a/engines/ags/engine/ac/drawingsurface.h +++ b/engines/ags/engine/ac/drawingsurface.h @@ -25,26 +25,26 @@ #include "ac/dynobj/scriptdrawingsurface.h" -void DrawingSurface_Release(ScriptDrawingSurface* sds); +void DrawingSurface_Release(ScriptDrawingSurface *sds); // convert actual co-ordinate back to what the script is expecting -ScriptDrawingSurface* DrawingSurface_CreateCopy(ScriptDrawingSurface *sds); -void DrawingSurface_DrawSurface(ScriptDrawingSurface* target, ScriptDrawingSurface* source, int translev); -void DrawingSurface_DrawImage_FullSrc(ScriptDrawingSurface* sds, int xx, int yy, int slot, int trans, int width, int height); -void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour); -int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds); -void DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface *sds, int highRes); -int DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface *sds); -int DrawingSurface_GetHeight(ScriptDrawingSurface *sds); -int DrawingSurface_GetWidth(ScriptDrawingSurface *sds); -void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour); -void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius); -void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2); -void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3); -void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char* text); -void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg); -void DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm); -void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness); -void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y); -int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y); +ScriptDrawingSurface *DrawingSurface_CreateCopy(ScriptDrawingSurface *sds); +void DrawingSurface_DrawSurface(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int translev); +void DrawingSurface_DrawImage_FullSrc(ScriptDrawingSurface *sds, int xx, int yy, int slot, int trans, int width, int height); +void DrawingSurface_SetDrawingColor(ScriptDrawingSurface *sds, int newColour); +int DrawingSurface_GetDrawingColor(ScriptDrawingSurface *sds); +void DrawingSurface_SetUseHighResCoordinates(ScriptDrawingSurface *sds, int highRes); +int DrawingSurface_GetUseHighResCoordinates(ScriptDrawingSurface *sds); +int DrawingSurface_GetHeight(ScriptDrawingSurface *sds); +int DrawingSurface_GetWidth(ScriptDrawingSurface *sds); +void DrawingSurface_Clear(ScriptDrawingSurface *sds, int colour); +void DrawingSurface_DrawCircle(ScriptDrawingSurface *sds, int x, int y, int radius); +void DrawingSurface_DrawRectangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2); +void DrawingSurface_DrawTriangle(ScriptDrawingSurface *sds, int x1, int y1, int x2, int y2, int x3, int y3); +void DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, int font, const char *text); +void DrawingSurface_DrawStringWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int alignment, const char *msg); +void DrawingSurface_DrawMessageWrapped(ScriptDrawingSurface *sds, int xx, int yy, int wid, int font, int msgm); +void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, int tox, int toy, int thickness); +void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y); +int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y); #endif diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp index 18e5b2c264bb..a6143bf6ae1c 100644 --- a/engines/ags/engine/ac/dynamicsprite.cpp +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -47,8 +47,8 @@ using namespace Engine; extern GameSetupStruct game; extern SpriteCache spriteset; extern RoomStruct thisroom; -extern RoomObject*objs; -extern RoomStatus*croom; +extern RoomObject *objs; +extern RoomStatus *croom; extern CharacterCache *charcache; extern ObjectCache objcache[MAX_ROOM_OBJECTS]; @@ -60,457 +60,440 @@ char check_dynamic_sprites_at_exit = 1; // ** SCRIPT DYNAMIC SPRITE void DynamicSprite_Delete(ScriptDynamicSprite *sds) { - if (sds->slot) { - free_dynamic_sprite(sds->slot); - sds->slot = 0; - } + if (sds->slot) { + free_dynamic_sprite(sds->slot); + sds->slot = 0; + } } -ScriptDrawingSurface* DynamicSprite_GetDrawingSurface(ScriptDynamicSprite *dss) -{ - ScriptDrawingSurface *surface = new ScriptDrawingSurface(); - surface->dynamicSpriteNumber = dss->slot; +ScriptDrawingSurface *DynamicSprite_GetDrawingSurface(ScriptDynamicSprite *dss) { + ScriptDrawingSurface *surface = new ScriptDrawingSurface(); + surface->dynamicSpriteNumber = dss->slot; - if ((game.SpriteInfos[dss->slot].Flags & SPF_ALPHACHANNEL) != 0) - surface->hasAlphaChannel = true; + if ((game.SpriteInfos[dss->slot].Flags & SPF_ALPHACHANNEL) != 0) + surface->hasAlphaChannel = true; - ccRegisterManagedObject(surface, surface); - return surface; + ccRegisterManagedObject(surface, surface); + return surface; } int DynamicSprite_GetGraphic(ScriptDynamicSprite *sds) { - if (sds->slot == 0) - quit("!DynamicSprite.Graphic: Cannot get graphic, sprite has been deleted"); - return sds->slot; + if (sds->slot == 0) + quit("!DynamicSprite.Graphic: Cannot get graphic, sprite has been deleted"); + return sds->slot; } int DynamicSprite_GetWidth(ScriptDynamicSprite *sds) { - return game_to_data_coord(game.SpriteInfos[sds->slot].Width); + return game_to_data_coord(game.SpriteInfos[sds->slot].Width); } int DynamicSprite_GetHeight(ScriptDynamicSprite *sds) { - return game_to_data_coord(game.SpriteInfos[sds->slot].Height); + return game_to_data_coord(game.SpriteInfos[sds->slot].Height); } int DynamicSprite_GetColorDepth(ScriptDynamicSprite *sds) { - int depth = spriteset[sds->slot]->GetColorDepth(); - if (depth == 15) - depth = 16; - if (depth == 24) - depth = 32; - return depth; + int depth = spriteset[sds->slot]->GetColorDepth(); + if (depth == 15) + depth = 16; + if (depth == 24) + depth = 32; + return depth; } void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height) { - if ((width < 1) || (height < 1)) - quit("!DynamicSprite.Resize: width and height must be greater than zero"); - if (sds->slot == 0) - quit("!DynamicSprite.Resize: sprite has been deleted"); + if ((width < 1) || (height < 1)) + quit("!DynamicSprite.Resize: width and height must be greater than zero"); + if (sds->slot == 0) + quit("!DynamicSprite.Resize: sprite has been deleted"); - data_to_game_coords(&width, &height); + data_to_game_coords(&width, &height); - if (width * height >= 25000000) - quitprintf("!DynamicSprite.Resize: new size is too large: %d x %d", width, height); + if (width * height >= 25000000) + quitprintf("!DynamicSprite.Resize: new size is too large: %d x %d", width, height); - // resize the sprite to the requested size - Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); - newPic->StretchBlt(spriteset[sds->slot], - RectWH(0, 0, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height), - RectWH(0, 0, width, height)); + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + newPic->StretchBlt(spriteset[sds->slot], + RectWH(0, 0, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height), + RectWH(0, 0, width, height)); - delete spriteset[sds->slot]; + delete spriteset[sds->slot]; - // replace the bitmap in the sprite set - add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); } void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction) { - if ((direction < 1) || (direction > 3)) - quit("!DynamicSprite.Flip: invalid direction"); - if (sds->slot == 0) - quit("!DynamicSprite.Flip: sprite has been deleted"); + if ((direction < 1) || (direction > 3)) + quit("!DynamicSprite.Flip: invalid direction"); + if (sds->slot == 0) + quit("!DynamicSprite.Flip: sprite has been deleted"); - // resize the sprite to the requested size - Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height, spriteset[sds->slot]->GetColorDepth()); + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height, spriteset[sds->slot]->GetColorDepth()); - if (direction == 1) - newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HFlip); - else if (direction == 2) - newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_VFlip); - else if (direction == 3) - newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HVFlip); + if (direction == 1) + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HFlip); + else if (direction == 2) + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_VFlip); + else if (direction == 3) + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HVFlip); - delete spriteset[sds->slot]; + delete spriteset[sds->slot]; - // replace the bitmap in the sprite set - add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); } void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSprite) { - if (sds->slot == 0) - quit("!DynamicSprite.CopyTransparencyMask: sprite has been deleted"); + if (sds->slot == 0) + quit("!DynamicSprite.CopyTransparencyMask: sprite has been deleted"); - if ((game.SpriteInfos[sds->slot].Width != game.SpriteInfos[sourceSprite].Width) || - (game.SpriteInfos[sds->slot].Height != game.SpriteInfos[sourceSprite].Height)) - { - quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same size"); - } + if ((game.SpriteInfos[sds->slot].Width != game.SpriteInfos[sourceSprite].Width) || + (game.SpriteInfos[sds->slot].Height != game.SpriteInfos[sourceSprite].Height)) { + quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same size"); + } - Bitmap *target = spriteset[sds->slot]; - Bitmap *source = spriteset[sourceSprite]; + Bitmap *target = spriteset[sds->slot]; + Bitmap *source = spriteset[sourceSprite]; - if (target->GetColorDepth() != source->GetColorDepth()) - { - quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same colour depth"); - } + if (target->GetColorDepth() != source->GetColorDepth()) { + quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same colour depth"); + } - // set the target's alpha channel depending on the source - bool dst_has_alpha = (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0; - bool src_has_alpha = (game.SpriteInfos[sourceSprite].Flags & SPF_ALPHACHANNEL) != 0; - game.SpriteInfos[sds->slot].Flags &= ~SPF_ALPHACHANNEL; - if (src_has_alpha) - { - game.SpriteInfos[sds->slot].Flags |= SPF_ALPHACHANNEL; - } + // set the target's alpha channel depending on the source + bool dst_has_alpha = (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0; + bool src_has_alpha = (game.SpriteInfos[sourceSprite].Flags & SPF_ALPHACHANNEL) != 0; + game.SpriteInfos[sds->slot].Flags &= ~SPF_ALPHACHANNEL; + if (src_has_alpha) { + game.SpriteInfos[sds->slot].Flags |= SPF_ALPHACHANNEL; + } - BitmapHelper::CopyTransparency(target, source, dst_has_alpha, src_has_alpha); + BitmapHelper::CopyTransparency(target, source, dst_has_alpha, src_has_alpha); } -void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y) -{ - if (sds->slot == 0) - quit("!DynamicSprite.ChangeCanvasSize: sprite has been deleted"); - if ((width < 1) || (height < 1)) - quit("!DynamicSprite.ChangeCanvasSize: new size is too small"); +void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y) { + if (sds->slot == 0) + quit("!DynamicSprite.ChangeCanvasSize: sprite has been deleted"); + if ((width < 1) || (height < 1)) + quit("!DynamicSprite.ChangeCanvasSize: new size is too small"); - data_to_game_coords(&x, &y); - data_to_game_coords(&width, &height); + data_to_game_coords(&x, &y); + data_to_game_coords(&width, &height); - Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); - // blit it into the enlarged image - newPic->Blit(spriteset[sds->slot], 0, 0, x, y, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height); + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + // blit it into the enlarged image + newPic->Blit(spriteset[sds->slot], 0, 0, x, y, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height); - delete spriteset[sds->slot]; + delete spriteset[sds->slot]; - // replace the bitmap in the sprite set - add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); } void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int height) { - if ((width < 1) || (height < 1)) - quit("!DynamicSprite.Crop: co-ordinates do not make sense"); - if (sds->slot == 0) - quit("!DynamicSprite.Crop: sprite has been deleted"); + if ((width < 1) || (height < 1)) + quit("!DynamicSprite.Crop: co-ordinates do not make sense"); + if (sds->slot == 0) + quit("!DynamicSprite.Crop: sprite has been deleted"); - data_to_game_coords(&x1, &y1); - data_to_game_coords(&width, &height); + data_to_game_coords(&x1, &y1); + data_to_game_coords(&width, &height); - if ((width > game.SpriteInfos[sds->slot].Width) || (height > game.SpriteInfos[sds->slot].Height)) - quit("!DynamicSprite.Crop: requested to crop an area larger than the source"); + if ((width > game.SpriteInfos[sds->slot].Width) || (height > game.SpriteInfos[sds->slot].Height)) + quit("!DynamicSprite.Crop: requested to crop an area larger than the source"); - Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); - // blit it cropped - newPic->Blit(spriteset[sds->slot], x1, y1, 0, 0, newPic->GetWidth(), newPic->GetHeight()); + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + // blit it cropped + newPic->Blit(spriteset[sds->slot], x1, y1, 0, 0, newPic->GetWidth(), newPic->GetHeight()); - delete spriteset[sds->slot]; + delete spriteset[sds->slot]; - // replace the bitmap in the sprite set - add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); } void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int height) { - if ((angle < 1) || (angle > 359)) - quit("!DynamicSprite.Rotate: invalid angle (must be 1-359)"); - if (sds->slot == 0) - quit("!DynamicSprite.Rotate: sprite has been deleted"); + if ((angle < 1) || (angle > 359)) + quit("!DynamicSprite.Rotate: invalid angle (must be 1-359)"); + if (sds->slot == 0) + quit("!DynamicSprite.Rotate: sprite has been deleted"); - if ((width == SCR_NO_VALUE) || (height == SCR_NO_VALUE)) { - // calculate the new image size automatically - // 1 degree = 181 degrees in terms of x/y size, so % 180 - int useAngle = angle % 180; - // and 0..90 is the same as 180..90 - if (useAngle > 90) - useAngle = 180 - useAngle; - // useAngle is now between 0 and 90 (otherwise the sin/cos stuff doesn't work) - double angleInRadians = (double)useAngle * (M_PI / 180.0); - double sinVal = sin(angleInRadians); - double cosVal = cos(angleInRadians); + if ((width == SCR_NO_VALUE) || (height == SCR_NO_VALUE)) { + // calculate the new image size automatically + // 1 degree = 181 degrees in terms of x/y size, so % 180 + int useAngle = angle % 180; + // and 0..90 is the same as 180..90 + if (useAngle > 90) + useAngle = 180 - useAngle; + // useAngle is now between 0 and 90 (otherwise the sin/cos stuff doesn't work) + double angleInRadians = (double)useAngle * (M_PI / 180.0); + double sinVal = sin(angleInRadians); + double cosVal = cos(angleInRadians); - width = (cosVal * (double)game.SpriteInfos[sds->slot].Width + sinVal * (double)game.SpriteInfos[sds->slot].Height); - height = (sinVal * (double)game.SpriteInfos[sds->slot].Width + cosVal * (double)game.SpriteInfos[sds->slot].Height); - } - else { - data_to_game_coords(&width, &height); - } + width = (cosVal * (double)game.SpriteInfos[sds->slot].Width + sinVal * (double)game.SpriteInfos[sds->slot].Height); + height = (sinVal * (double)game.SpriteInfos[sds->slot].Width + cosVal * (double)game.SpriteInfos[sds->slot].Height); + } else { + data_to_game_coords(&width, &height); + } - // convert to allegro angle - angle = (angle * 256) / 360; + // convert to allegro angle + angle = (angle * 256) / 360; - // resize the sprite to the requested size - Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); - // rotate the sprite about its centre - // (+ width%2 fixes one pixel offset problem) - newPic->RotateBlt(spriteset[sds->slot], width / 2 + width % 2, height / 2, - game.SpriteInfos[sds->slot].Width / 2, game.SpriteInfos[sds->slot].Height / 2, itofix(angle)); + // rotate the sprite about its centre + // (+ width%2 fixes one pixel offset problem) + newPic->RotateBlt(spriteset[sds->slot], width / 2 + width % 2, height / 2, + game.SpriteInfos[sds->slot].Width / 2, game.SpriteInfos[sds->slot].Height / 2, itofix(angle)); - delete spriteset[sds->slot]; + delete spriteset[sds->slot]; - // replace the bitmap in the sprite set - add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); } -void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance) -{ - Bitmap *source = spriteset[sds->slot]; - Bitmap *newPic = BitmapHelper::CreateBitmap(source->GetWidth(), source->GetHeight(), source->GetColorDepth()); +void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance) { + Bitmap *source = spriteset[sds->slot]; + Bitmap *newPic = BitmapHelper::CreateBitmap(source->GetWidth(), source->GetHeight(), source->GetColorDepth()); - tint_image(newPic, source, red, green, blue, saturation, (luminance * 25) / 10); + tint_image(newPic, source, red, green, blue, saturation, (luminance * 25) / 10); - delete source; - // replace the bitmap in the sprite set - add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); + delete source; + // replace the bitmap in the sprite set + add_dynamic_sprite(sds->slot, newPic, (game.SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0); } -int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char* namm) -{ - if (sds->slot == 0) - quit("!DynamicSprite.SaveToFile: sprite has been deleted"); +int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char *namm) { + if (sds->slot == 0) + quit("!DynamicSprite.SaveToFile: sprite has been deleted"); - auto filename = String(namm); - if (filename.FindChar('.') == -1) - filename.Append(".bmp"); + auto filename = String(namm); + if (filename.FindChar('.') == -1) + filename.Append(".bmp"); - ResolvedPath rp; - if (!ResolveWritePathAndCreateDirs(filename, rp)) - return 0; - return spriteset[sds->slot]->SaveToFile(rp.FullPath, palette) ? 1 : 0; + ResolvedPath rp; + if (!ResolveWritePathAndCreateDirs(filename, rp)) + return 0; + return spriteset[sds->slot]->SaveToFile(rp.FullPath, palette) ? 1 : 0; } -ScriptDynamicSprite* DynamicSprite_CreateFromSaveGame(int sgslot, int width, int height) { - int slotnum = LoadSaveSlotScreenshot(sgslot, width, height); - if (slotnum) { - ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(slotnum); - return new_spr; - } - return nullptr; +ScriptDynamicSprite *DynamicSprite_CreateFromSaveGame(int sgslot, int width, int height) { + int slotnum = LoadSaveSlotScreenshot(sgslot, width, height); + if (slotnum) { + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(slotnum); + return new_spr; + } + return nullptr; } -ScriptDynamicSprite* DynamicSprite_CreateFromFile(const char *filename) { - int slotnum = LoadImageFile(filename); - if (slotnum) { - ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(slotnum); - return new_spr; - } - return nullptr; +ScriptDynamicSprite *DynamicSprite_CreateFromFile(const char *filename) { + int slotnum = LoadImageFile(filename); + if (slotnum) { + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(slotnum); + return new_spr; + } + return nullptr; } -ScriptDynamicSprite* DynamicSprite_CreateFromScreenShot(int width, int height) { +ScriptDynamicSprite *DynamicSprite_CreateFromScreenShot(int width, int height) { - // TODO: refactor and merge with create_savegame_screenshot() + // TODO: refactor and merge with create_savegame_screenshot() - int gotSlot = spriteset.GetFreeIndex(); - if (gotSlot <= 0) - return nullptr; + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; - const Rect &viewport = play.GetMainViewport(); - if (width <= 0) - width = viewport.GetWidth(); - else - width = data_to_game_coord(width); + const Rect &viewport = play.GetMainViewport(); + if (width <= 0) + width = viewport.GetWidth(); + else + width = data_to_game_coord(width); - if (height <= 0) - height = viewport.GetHeight(); - else - height = data_to_game_coord(height); + if (height <= 0) + height = viewport.GetHeight(); + else + height = data_to_game_coord(height); - Bitmap *newPic = CopyScreenIntoBitmap(width, height); + Bitmap *newPic = CopyScreenIntoBitmap(width, height); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - // replace the bitmap in the sprite set - add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic)); - ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); - return new_spr; + // replace the bitmap in the sprite set + add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic)); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; } -ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite(int slot, int preserveAlphaChannel) { +ScriptDynamicSprite *DynamicSprite_CreateFromExistingSprite(int slot, int preserveAlphaChannel) { - int gotSlot = spriteset.GetFreeIndex(); - if (gotSlot <= 0) - return nullptr; + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; - if (!spriteset.DoesSpriteExist(slot)) - quitprintf("DynamicSprite.CreateFromExistingSprite: sprite %d does not exist", slot); + if (!spriteset.DoesSpriteExist(slot)) + quitprintf("DynamicSprite.CreateFromExistingSprite: sprite %d does not exist", slot); - // create a new sprite as a copy of the existing one - Bitmap *newPic = BitmapHelper::CreateBitmapCopy(spriteset[slot]); - if (newPic == nullptr) - return nullptr; + // create a new sprite as a copy of the existing one + Bitmap *newPic = BitmapHelper::CreateBitmapCopy(spriteset[slot]); + if (newPic == nullptr) + return nullptr; - bool hasAlpha = (preserveAlphaChannel) && ((game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); + bool hasAlpha = (preserveAlphaChannel) && ((game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); - // replace the bitmap in the sprite set - add_dynamic_sprite(gotSlot, newPic, hasAlpha); - ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); - return new_spr; + // replace the bitmap in the sprite set + add_dynamic_sprite(gotSlot, newPic, hasAlpha); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; } -ScriptDynamicSprite* DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface *sds, int x, int y, int width, int height) -{ - int gotSlot = spriteset.GetFreeIndex(); - if (gotSlot <= 0) - return nullptr; +ScriptDynamicSprite *DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface *sds, int x, int y, int width, int height) { + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; - // use DrawingSurface resolution - sds->PointToGameResolution(&x, &y); - sds->SizeToGameResolution(&width, &height); + // use DrawingSurface resolution + sds->PointToGameResolution(&x, &y); + sds->SizeToGameResolution(&width, &height); - Bitmap *ds = sds->StartDrawing(); + Bitmap *ds = sds->StartDrawing(); - if ((x < 0) || (y < 0) || (x + width > ds->GetWidth()) || (y + height > ds->GetHeight())) - quit("!DynamicSprite.CreateFromDrawingSurface: requested area is outside the surface"); + if ((x < 0) || (y < 0) || (x + width > ds->GetWidth()) || (y + height > ds->GetHeight())) + quit("!DynamicSprite.CreateFromDrawingSurface: requested area is outside the surface"); - int colDepth = ds->GetColorDepth(); + int colDepth = ds->GetColorDepth(); - Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, colDepth); - if (newPic == nullptr) - return nullptr; + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, colDepth); + if (newPic == nullptr) + return nullptr; - newPic->Blit(ds, x, y, 0, 0, width, height); + newPic->Blit(ds, x, y, 0, 0, width, height); - sds->FinishedDrawingReadOnly(); + sds->FinishedDrawingReadOnly(); - add_dynamic_sprite(gotSlot, newPic, (sds->hasAlphaChannel != 0)); - ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); - return new_spr; + add_dynamic_sprite(gotSlot, newPic, (sds->hasAlphaChannel != 0)); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; } -ScriptDynamicSprite* DynamicSprite_Create(int width, int height, int alphaChannel) -{ - data_to_game_coords(&width, &height); +ScriptDynamicSprite *DynamicSprite_Create(int width, int height, int alphaChannel) { + data_to_game_coords(&width, &height); - int gotSlot = spriteset.GetFreeIndex(); - if (gotSlot <= 0) - return nullptr; + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; - Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, game.GetColorDepth()); - if (newPic == nullptr) - return nullptr; + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, game.GetColorDepth()); + if (newPic == nullptr) + return nullptr; - if ((alphaChannel) && (game.GetColorDepth() < 32)) - alphaChannel = false; + if ((alphaChannel) && (game.GetColorDepth() < 32)) + alphaChannel = false; - add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic), alphaChannel != 0); - ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); - return new_spr; + add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(newPic), alphaChannel != 0); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; } -ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite_Old(int slot) -{ - return DynamicSprite_CreateFromExistingSprite(slot, 0); +ScriptDynamicSprite *DynamicSprite_CreateFromExistingSprite_Old(int slot) { + return DynamicSprite_CreateFromExistingSprite(slot, 0); } -ScriptDynamicSprite* DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height) { +ScriptDynamicSprite *DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height) { - if (frame == SCR_NO_VALUE) { - frame = play.bg_frame; - } - else if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount)) - quit("!DynamicSprite.CreateFromBackground: invalid frame specified"); + if (frame == SCR_NO_VALUE) { + frame = play.bg_frame; + } else if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount)) + quit("!DynamicSprite.CreateFromBackground: invalid frame specified"); - if (x1 == SCR_NO_VALUE) { - x1 = 0; - y1 = 0; - width = play.room_width; - height = play.room_height; - } - else if ((x1 < 0) || (y1 < 0) || (width < 1) || (height < 1) || - (x1 + width > play.room_width) || (y1 + height > play.room_height)) - quit("!DynamicSprite.CreateFromBackground: invalid co-ordinates specified"); + if (x1 == SCR_NO_VALUE) { + x1 = 0; + y1 = 0; + width = play.room_width; + height = play.room_height; + } else if ((x1 < 0) || (y1 < 0) || (width < 1) || (height < 1) || + (x1 + width > play.room_width) || (y1 + height > play.room_height)) + quit("!DynamicSprite.CreateFromBackground: invalid co-ordinates specified"); - data_to_game_coords(&x1, &y1); - data_to_game_coords(&width, &height); + data_to_game_coords(&x1, &y1); + data_to_game_coords(&width, &height); - int gotSlot = spriteset.GetFreeIndex(); - if (gotSlot <= 0) - return nullptr; + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return nullptr; - // create a new sprite as a copy of the existing one - Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, thisroom.BgFrames[frame].Graphic->GetColorDepth()); - if (newPic == nullptr) - return nullptr; + // create a new sprite as a copy of the existing one + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, thisroom.BgFrames[frame].Graphic->GetColorDepth()); + if (newPic == nullptr) + return nullptr; - newPic->Blit(thisroom.BgFrames[frame].Graphic.get(), x1, y1, 0, 0, width, height); + newPic->Blit(thisroom.BgFrames[frame].Graphic.get(), x1, y1, 0, 0, width, height); - // replace the bitmap in the sprite set - add_dynamic_sprite(gotSlot, newPic); - ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); - return new_spr; + // replace the bitmap in the sprite set + add_dynamic_sprite(gotSlot, newPic); + ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); + return new_spr; } //============================================================================= void add_dynamic_sprite(int gotSlot, Bitmap *redin, bool hasAlpha) { - spriteset.SetSprite(gotSlot, redin); - - game.SpriteInfos[gotSlot].Flags = SPF_DYNAMICALLOC; - - if (redin->GetColorDepth() > 8) - game.SpriteInfos[gotSlot].Flags |= SPF_HICOLOR; - if (redin->GetColorDepth() > 16) - game.SpriteInfos[gotSlot].Flags |= SPF_TRUECOLOR; - if (hasAlpha) - game.SpriteInfos[gotSlot].Flags |= SPF_ALPHACHANNEL; - - game.SpriteInfos[gotSlot].Width = redin->GetWidth(); - game.SpriteInfos[gotSlot].Height = redin->GetHeight(); -} - -void free_dynamic_sprite (int gotSlot) { - int tt; - - if ((gotSlot < 0) || (gotSlot >= spriteset.GetSpriteSlotCount())) - quit("!FreeDynamicSprite: invalid slot number"); - - if ((game.SpriteInfos[gotSlot].Flags & SPF_DYNAMICALLOC) == 0) - quitprintf("!DeleteSprite: Attempted to free static sprite %d that was not loaded by the script", gotSlot); - - spriteset.RemoveSprite(gotSlot, true); - - game.SpriteInfos[gotSlot].Flags = 0; - game.SpriteInfos[gotSlot].Width = 0; - game.SpriteInfos[gotSlot].Height = 0; - - // ensure it isn't still on any GUI buttons - for (tt = 0; tt < numguibuts; tt++) { - if (guibuts[tt].IsDeleted()) - continue; - if (guibuts[tt].Image == gotSlot) - guibuts[tt].Image = 0; - if (guibuts[tt].CurrentImage == gotSlot) - guibuts[tt].CurrentImage = 0; - if (guibuts[tt].MouseOverImage == gotSlot) - guibuts[tt].MouseOverImage = 0; - if (guibuts[tt].PushedImage == gotSlot) - guibuts[tt].PushedImage = 0; - } - - // force refresh of any object caches using the sprite - if (croom != nullptr) - { - for (tt = 0; tt < croom->numobj; tt++) - { - if (objs[tt].num == gotSlot) - { - objs[tt].num = 0; - objcache[tt].sppic = -1; - } - else if (objcache[tt].sppic == gotSlot) - objcache[tt].sppic = -1; - } - } + spriteset.SetSprite(gotSlot, redin); + + game.SpriteInfos[gotSlot].Flags = SPF_DYNAMICALLOC; + + if (redin->GetColorDepth() > 8) + game.SpriteInfos[gotSlot].Flags |= SPF_HICOLOR; + if (redin->GetColorDepth() > 16) + game.SpriteInfos[gotSlot].Flags |= SPF_TRUECOLOR; + if (hasAlpha) + game.SpriteInfos[gotSlot].Flags |= SPF_ALPHACHANNEL; + + game.SpriteInfos[gotSlot].Width = redin->GetWidth(); + game.SpriteInfos[gotSlot].Height = redin->GetHeight(); +} + +void free_dynamic_sprite(int gotSlot) { + int tt; + + if ((gotSlot < 0) || (gotSlot >= spriteset.GetSpriteSlotCount())) + quit("!FreeDynamicSprite: invalid slot number"); + + if ((game.SpriteInfos[gotSlot].Flags & SPF_DYNAMICALLOC) == 0) + quitprintf("!DeleteSprite: Attempted to free static sprite %d that was not loaded by the script", gotSlot); + + spriteset.RemoveSprite(gotSlot, true); + + game.SpriteInfos[gotSlot].Flags = 0; + game.SpriteInfos[gotSlot].Width = 0; + game.SpriteInfos[gotSlot].Height = 0; + + // ensure it isn't still on any GUI buttons + for (tt = 0; tt < numguibuts; tt++) { + if (guibuts[tt].IsDeleted()) + continue; + if (guibuts[tt].Image == gotSlot) + guibuts[tt].Image = 0; + if (guibuts[tt].CurrentImage == gotSlot) + guibuts[tt].CurrentImage = 0; + if (guibuts[tt].MouseOverImage == gotSlot) + guibuts[tt].MouseOverImage = 0; + if (guibuts[tt].PushedImage == gotSlot) + guibuts[tt].PushedImage = 0; + } + + // force refresh of any object caches using the sprite + if (croom != nullptr) { + for (tt = 0; tt < croom->numobj; tt++) { + if (objs[tt].num == gotSlot) { + objs[tt].num = 0; + objcache[tt].sppic = -1; + } else if (objcache[tt].sppic == gotSlot) + objcache[tt].sppic = -1; + } + } } //============================================================================= @@ -524,185 +507,162 @@ void free_dynamic_sprite (int gotSlot) { #include "script/script_runtime.h" // void (ScriptDynamicSprite *sds, int width, int height, int x, int y) -RuntimeScriptValue Sc_DynamicSprite_ChangeCanvasSize(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(ScriptDynamicSprite, DynamicSprite_ChangeCanvasSize); +RuntimeScriptValue Sc_DynamicSprite_ChangeCanvasSize(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(ScriptDynamicSprite, DynamicSprite_ChangeCanvasSize); } // void (ScriptDynamicSprite *sds, int sourceSprite) -RuntimeScriptValue Sc_DynamicSprite_CopyTransparencyMask(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDynamicSprite, DynamicSprite_CopyTransparencyMask); +RuntimeScriptValue Sc_DynamicSprite_CopyTransparencyMask(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDynamicSprite, DynamicSprite_CopyTransparencyMask); } // void (ScriptDynamicSprite *sds, int x1, int y1, int width, int height) -RuntimeScriptValue Sc_DynamicSprite_Crop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(ScriptDynamicSprite, DynamicSprite_Crop); +RuntimeScriptValue Sc_DynamicSprite_Crop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(ScriptDynamicSprite, DynamicSprite_Crop); } // void (ScriptDynamicSprite *sds) -RuntimeScriptValue Sc_DynamicSprite_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptDynamicSprite, DynamicSprite_Delete); +RuntimeScriptValue Sc_DynamicSprite_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptDynamicSprite, DynamicSprite_Delete); } // void (ScriptDynamicSprite *sds, int direction) -RuntimeScriptValue Sc_DynamicSprite_Flip(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptDynamicSprite, DynamicSprite_Flip); +RuntimeScriptValue Sc_DynamicSprite_Flip(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptDynamicSprite, DynamicSprite_Flip); } // ScriptDrawingSurface* (ScriptDynamicSprite *dss) -RuntimeScriptValue Sc_DynamicSprite_GetDrawingSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJAUTO(ScriptDynamicSprite, ScriptDrawingSurface, DynamicSprite_GetDrawingSurface); +RuntimeScriptValue Sc_DynamicSprite_GetDrawingSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJAUTO(ScriptDynamicSprite, ScriptDrawingSurface, DynamicSprite_GetDrawingSurface); } // void (ScriptDynamicSprite *sds, int width, int height) -RuntimeScriptValue Sc_DynamicSprite_Resize(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptDynamicSprite, DynamicSprite_Resize); +RuntimeScriptValue Sc_DynamicSprite_Resize(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptDynamicSprite, DynamicSprite_Resize); } // void (ScriptDynamicSprite *sds, int angle, int width, int height) -RuntimeScriptValue Sc_DynamicSprite_Rotate(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(ScriptDynamicSprite, DynamicSprite_Rotate); +RuntimeScriptValue Sc_DynamicSprite_Rotate(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(ScriptDynamicSprite, DynamicSprite_Rotate); } // int (ScriptDynamicSprite *sds, const char* namm) -RuntimeScriptValue Sc_DynamicSprite_SaveToFile(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(ScriptDynamicSprite, DynamicSprite_SaveToFile, const char); +RuntimeScriptValue Sc_DynamicSprite_SaveToFile(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(ScriptDynamicSprite, DynamicSprite_SaveToFile, const char); } // void (ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance) -RuntimeScriptValue Sc_DynamicSprite_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(ScriptDynamicSprite, DynamicSprite_Tint); +RuntimeScriptValue Sc_DynamicSprite_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(ScriptDynamicSprite, DynamicSprite_Tint); } // int (ScriptDynamicSprite *sds) -RuntimeScriptValue Sc_DynamicSprite_GetColorDepth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetColorDepth); +RuntimeScriptValue Sc_DynamicSprite_GetColorDepth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetColorDepth); } // int (ScriptDynamicSprite *sds) -RuntimeScriptValue Sc_DynamicSprite_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetGraphic); +RuntimeScriptValue Sc_DynamicSprite_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetGraphic); } // int (ScriptDynamicSprite *sds) -RuntimeScriptValue Sc_DynamicSprite_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetHeight); +RuntimeScriptValue Sc_DynamicSprite_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetHeight); } // int (ScriptDynamicSprite *sds) -RuntimeScriptValue Sc_DynamicSprite_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetWidth); +RuntimeScriptValue Sc_DynamicSprite_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDynamicSprite, DynamicSprite_GetWidth); } // ScriptDynamicSprite* (int width, int height, int alphaChannel) -RuntimeScriptValue Sc_DynamicSprite_Create(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT3(ScriptDynamicSprite, DynamicSprite_Create); +RuntimeScriptValue Sc_DynamicSprite_Create(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT3(ScriptDynamicSprite, DynamicSprite_Create); } // ScriptDynamicSprite* (int frame, int x1, int y1, int width, int height) -RuntimeScriptValue Sc_DynamicSprite_CreateFromBackground(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT5(ScriptDynamicSprite, DynamicSprite_CreateFromBackground); +RuntimeScriptValue Sc_DynamicSprite_CreateFromBackground(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT5(ScriptDynamicSprite, DynamicSprite_CreateFromBackground); } // ScriptDynamicSprite* (ScriptDrawingSurface *sds, int x, int y, int width, int height) -RuntimeScriptValue Sc_DynamicSprite_CreateFromDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_POBJ_PINT4(ScriptDynamicSprite, DynamicSprite_CreateFromDrawingSurface, ScriptDrawingSurface); +RuntimeScriptValue Sc_DynamicSprite_CreateFromDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_POBJ_PINT4(ScriptDynamicSprite, DynamicSprite_CreateFromDrawingSurface, ScriptDrawingSurface); } // ScriptDynamicSprite* (int slot) -RuntimeScriptValue Sc_DynamicSprite_CreateFromExistingSprite_Old(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT(ScriptDynamicSprite, DynamicSprite_CreateFromExistingSprite_Old); +RuntimeScriptValue Sc_DynamicSprite_CreateFromExistingSprite_Old(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT(ScriptDynamicSprite, DynamicSprite_CreateFromExistingSprite_Old); } // ScriptDynamicSprite* (int slot, int preserveAlphaChannel) -RuntimeScriptValue Sc_DynamicSprite_CreateFromExistingSprite(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT2(ScriptDynamicSprite, DynamicSprite_CreateFromExistingSprite); +RuntimeScriptValue Sc_DynamicSprite_CreateFromExistingSprite(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT2(ScriptDynamicSprite, DynamicSprite_CreateFromExistingSprite); } // ScriptDynamicSprite* (const char *filename) -RuntimeScriptValue Sc_DynamicSprite_CreateFromFile(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_POBJ(ScriptDynamicSprite, DynamicSprite_CreateFromFile, const char); +RuntimeScriptValue Sc_DynamicSprite_CreateFromFile(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_POBJ(ScriptDynamicSprite, DynamicSprite_CreateFromFile, const char); } // ScriptDynamicSprite* (int sgslot, int width, int height) -RuntimeScriptValue Sc_DynamicSprite_CreateFromSaveGame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT3(ScriptDynamicSprite, DynamicSprite_CreateFromSaveGame); +RuntimeScriptValue Sc_DynamicSprite_CreateFromSaveGame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT3(ScriptDynamicSprite, DynamicSprite_CreateFromSaveGame); } // ScriptDynamicSprite* (int width, int height) -RuntimeScriptValue Sc_DynamicSprite_CreateFromScreenShot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT2(ScriptDynamicSprite, DynamicSprite_CreateFromScreenShot); -} - - -void RegisterDynamicSpriteAPI() -{ - ccAddExternalObjectFunction("DynamicSprite::ChangeCanvasSize^4", Sc_DynamicSprite_ChangeCanvasSize); - ccAddExternalObjectFunction("DynamicSprite::CopyTransparencyMask^1", Sc_DynamicSprite_CopyTransparencyMask); - ccAddExternalObjectFunction("DynamicSprite::Crop^4", Sc_DynamicSprite_Crop); - ccAddExternalObjectFunction("DynamicSprite::Delete", Sc_DynamicSprite_Delete); - ccAddExternalObjectFunction("DynamicSprite::Flip^1", Sc_DynamicSprite_Flip); - ccAddExternalObjectFunction("DynamicSprite::GetDrawingSurface^0", Sc_DynamicSprite_GetDrawingSurface); - ccAddExternalObjectFunction("DynamicSprite::Resize^2", Sc_DynamicSprite_Resize); - ccAddExternalObjectFunction("DynamicSprite::Rotate^3", Sc_DynamicSprite_Rotate); - ccAddExternalObjectFunction("DynamicSprite::SaveToFile^1", Sc_DynamicSprite_SaveToFile); - ccAddExternalObjectFunction("DynamicSprite::Tint^5", Sc_DynamicSprite_Tint); - ccAddExternalObjectFunction("DynamicSprite::get_ColorDepth", Sc_DynamicSprite_GetColorDepth); - ccAddExternalObjectFunction("DynamicSprite::get_Graphic", Sc_DynamicSprite_GetGraphic); - ccAddExternalObjectFunction("DynamicSprite::get_Height", Sc_DynamicSprite_GetHeight); - ccAddExternalObjectFunction("DynamicSprite::get_Width", Sc_DynamicSprite_GetWidth); - ccAddExternalStaticFunction("DynamicSprite::Create^3", Sc_DynamicSprite_Create); - ccAddExternalStaticFunction("DynamicSprite::CreateFromBackground", Sc_DynamicSprite_CreateFromBackground); - ccAddExternalStaticFunction("DynamicSprite::CreateFromDrawingSurface^5", Sc_DynamicSprite_CreateFromDrawingSurface); - ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^1", Sc_DynamicSprite_CreateFromExistingSprite_Old); - ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^2", Sc_DynamicSprite_CreateFromExistingSprite); - ccAddExternalStaticFunction("DynamicSprite::CreateFromFile", Sc_DynamicSprite_CreateFromFile); - ccAddExternalStaticFunction("DynamicSprite::CreateFromSaveGame", Sc_DynamicSprite_CreateFromSaveGame); - ccAddExternalStaticFunction("DynamicSprite::CreateFromScreenShot", Sc_DynamicSprite_CreateFromScreenShot); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("DynamicSprite::ChangeCanvasSize^4", (void*)DynamicSprite_ChangeCanvasSize); - ccAddExternalFunctionForPlugin("DynamicSprite::CopyTransparencyMask^1", (void*)DynamicSprite_CopyTransparencyMask); - ccAddExternalFunctionForPlugin("DynamicSprite::Crop^4", (void*)DynamicSprite_Crop); - ccAddExternalFunctionForPlugin("DynamicSprite::Delete", (void*)DynamicSprite_Delete); - ccAddExternalFunctionForPlugin("DynamicSprite::Flip^1", (void*)DynamicSprite_Flip); - ccAddExternalFunctionForPlugin("DynamicSprite::GetDrawingSurface^0", (void*)DynamicSprite_GetDrawingSurface); - ccAddExternalFunctionForPlugin("DynamicSprite::Resize^2", (void*)DynamicSprite_Resize); - ccAddExternalFunctionForPlugin("DynamicSprite::Rotate^3", (void*)DynamicSprite_Rotate); - ccAddExternalFunctionForPlugin("DynamicSprite::SaveToFile^1", (void*)DynamicSprite_SaveToFile); - ccAddExternalFunctionForPlugin("DynamicSprite::Tint^5", (void*)DynamicSprite_Tint); - ccAddExternalFunctionForPlugin("DynamicSprite::get_ColorDepth", (void*)DynamicSprite_GetColorDepth); - ccAddExternalFunctionForPlugin("DynamicSprite::get_Graphic", (void*)DynamicSprite_GetGraphic); - ccAddExternalFunctionForPlugin("DynamicSprite::get_Height", (void*)DynamicSprite_GetHeight); - ccAddExternalFunctionForPlugin("DynamicSprite::get_Width", (void*)DynamicSprite_GetWidth); - ccAddExternalFunctionForPlugin("DynamicSprite::Create^3", (void*)DynamicSprite_Create); - ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromBackground", (void*)DynamicSprite_CreateFromBackground); - ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromDrawingSurface^5", (void*)DynamicSprite_CreateFromDrawingSurface); - ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromExistingSprite^1", (void*)DynamicSprite_CreateFromExistingSprite_Old); - ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromExistingSprite^2", (void*)DynamicSprite_CreateFromExistingSprite); - ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromFile", (void*)DynamicSprite_CreateFromFile); - ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromSaveGame", (void*)DynamicSprite_CreateFromSaveGame); - ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromScreenShot", (void*)DynamicSprite_CreateFromScreenShot); +RuntimeScriptValue Sc_DynamicSprite_CreateFromScreenShot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT2(ScriptDynamicSprite, DynamicSprite_CreateFromScreenShot); +} + + +void RegisterDynamicSpriteAPI() { + ccAddExternalObjectFunction("DynamicSprite::ChangeCanvasSize^4", Sc_DynamicSprite_ChangeCanvasSize); + ccAddExternalObjectFunction("DynamicSprite::CopyTransparencyMask^1", Sc_DynamicSprite_CopyTransparencyMask); + ccAddExternalObjectFunction("DynamicSprite::Crop^4", Sc_DynamicSprite_Crop); + ccAddExternalObjectFunction("DynamicSprite::Delete", Sc_DynamicSprite_Delete); + ccAddExternalObjectFunction("DynamicSprite::Flip^1", Sc_DynamicSprite_Flip); + ccAddExternalObjectFunction("DynamicSprite::GetDrawingSurface^0", Sc_DynamicSprite_GetDrawingSurface); + ccAddExternalObjectFunction("DynamicSprite::Resize^2", Sc_DynamicSprite_Resize); + ccAddExternalObjectFunction("DynamicSprite::Rotate^3", Sc_DynamicSprite_Rotate); + ccAddExternalObjectFunction("DynamicSprite::SaveToFile^1", Sc_DynamicSprite_SaveToFile); + ccAddExternalObjectFunction("DynamicSprite::Tint^5", Sc_DynamicSprite_Tint); + ccAddExternalObjectFunction("DynamicSprite::get_ColorDepth", Sc_DynamicSprite_GetColorDepth); + ccAddExternalObjectFunction("DynamicSprite::get_Graphic", Sc_DynamicSprite_GetGraphic); + ccAddExternalObjectFunction("DynamicSprite::get_Height", Sc_DynamicSprite_GetHeight); + ccAddExternalObjectFunction("DynamicSprite::get_Width", Sc_DynamicSprite_GetWidth); + ccAddExternalStaticFunction("DynamicSprite::Create^3", Sc_DynamicSprite_Create); + ccAddExternalStaticFunction("DynamicSprite::CreateFromBackground", Sc_DynamicSprite_CreateFromBackground); + ccAddExternalStaticFunction("DynamicSprite::CreateFromDrawingSurface^5", Sc_DynamicSprite_CreateFromDrawingSurface); + ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^1", Sc_DynamicSprite_CreateFromExistingSprite_Old); + ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^2", Sc_DynamicSprite_CreateFromExistingSprite); + ccAddExternalStaticFunction("DynamicSprite::CreateFromFile", Sc_DynamicSprite_CreateFromFile); + ccAddExternalStaticFunction("DynamicSprite::CreateFromSaveGame", Sc_DynamicSprite_CreateFromSaveGame); + ccAddExternalStaticFunction("DynamicSprite::CreateFromScreenShot", Sc_DynamicSprite_CreateFromScreenShot); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("DynamicSprite::ChangeCanvasSize^4", (void *)DynamicSprite_ChangeCanvasSize); + ccAddExternalFunctionForPlugin("DynamicSprite::CopyTransparencyMask^1", (void *)DynamicSprite_CopyTransparencyMask); + ccAddExternalFunctionForPlugin("DynamicSprite::Crop^4", (void *)DynamicSprite_Crop); + ccAddExternalFunctionForPlugin("DynamicSprite::Delete", (void *)DynamicSprite_Delete); + ccAddExternalFunctionForPlugin("DynamicSprite::Flip^1", (void *)DynamicSprite_Flip); + ccAddExternalFunctionForPlugin("DynamicSprite::GetDrawingSurface^0", (void *)DynamicSprite_GetDrawingSurface); + ccAddExternalFunctionForPlugin("DynamicSprite::Resize^2", (void *)DynamicSprite_Resize); + ccAddExternalFunctionForPlugin("DynamicSprite::Rotate^3", (void *)DynamicSprite_Rotate); + ccAddExternalFunctionForPlugin("DynamicSprite::SaveToFile^1", (void *)DynamicSprite_SaveToFile); + ccAddExternalFunctionForPlugin("DynamicSprite::Tint^5", (void *)DynamicSprite_Tint); + ccAddExternalFunctionForPlugin("DynamicSprite::get_ColorDepth", (void *)DynamicSprite_GetColorDepth); + ccAddExternalFunctionForPlugin("DynamicSprite::get_Graphic", (void *)DynamicSprite_GetGraphic); + ccAddExternalFunctionForPlugin("DynamicSprite::get_Height", (void *)DynamicSprite_GetHeight); + ccAddExternalFunctionForPlugin("DynamicSprite::get_Width", (void *)DynamicSprite_GetWidth); + ccAddExternalFunctionForPlugin("DynamicSprite::Create^3", (void *)DynamicSprite_Create); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromBackground", (void *)DynamicSprite_CreateFromBackground); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromDrawingSurface^5", (void *)DynamicSprite_CreateFromDrawingSurface); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromExistingSprite^1", (void *)DynamicSprite_CreateFromExistingSprite_Old); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromExistingSprite^2", (void *)DynamicSprite_CreateFromExistingSprite); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromFile", (void *)DynamicSprite_CreateFromFile); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromSaveGame", (void *)DynamicSprite_CreateFromSaveGame); + ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromScreenShot", (void *)DynamicSprite_CreateFromScreenShot); } diff --git a/engines/ags/engine/ac/dynamicsprite.h b/engines/ags/engine/ac/dynamicsprite.h index f6d7674780f2..14610057a883 100644 --- a/engines/ags/engine/ac/dynamicsprite.h +++ b/engines/ags/engine/ac/dynamicsprite.h @@ -26,31 +26,31 @@ #include "ac/dynobj/scriptdynamicsprite.h" #include "ac/dynobj/scriptdrawingsurface.h" -void DynamicSprite_Delete(ScriptDynamicSprite *sds); -ScriptDrawingSurface* DynamicSprite_GetDrawingSurface(ScriptDynamicSprite *dss); -int DynamicSprite_GetGraphic(ScriptDynamicSprite *sds); -int DynamicSprite_GetWidth(ScriptDynamicSprite *sds); -int DynamicSprite_GetHeight(ScriptDynamicSprite *sds); -int DynamicSprite_GetColorDepth(ScriptDynamicSprite *sds); -void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height); -void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction); -void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSprite); -void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y); -void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int height); -void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int height); -void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance); -int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char* namm); -ScriptDynamicSprite* DynamicSprite_CreateFromSaveGame(int sgslot, int width, int height); -ScriptDynamicSprite* DynamicSprite_CreateFromFile(const char *filename); -ScriptDynamicSprite* DynamicSprite_CreateFromScreenShot(int width, int height); -ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite(int slot, int preserveAlphaChannel); -ScriptDynamicSprite* DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface *sds, int x, int y, int width, int height); -ScriptDynamicSprite* DynamicSprite_Create(int width, int height, int alphaChannel); -ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite_Old(int slot); -ScriptDynamicSprite* DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height); +void DynamicSprite_Delete(ScriptDynamicSprite *sds); +ScriptDrawingSurface *DynamicSprite_GetDrawingSurface(ScriptDynamicSprite *dss); +int DynamicSprite_GetGraphic(ScriptDynamicSprite *sds); +int DynamicSprite_GetWidth(ScriptDynamicSprite *sds); +int DynamicSprite_GetHeight(ScriptDynamicSprite *sds); +int DynamicSprite_GetColorDepth(ScriptDynamicSprite *sds); +void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height); +void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction); +void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSprite); +void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y); +void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int height); +void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int height); +void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance); +int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char *namm); +ScriptDynamicSprite *DynamicSprite_CreateFromSaveGame(int sgslot, int width, int height); +ScriptDynamicSprite *DynamicSprite_CreateFromFile(const char *filename); +ScriptDynamicSprite *DynamicSprite_CreateFromScreenShot(int width, int height); +ScriptDynamicSprite *DynamicSprite_CreateFromExistingSprite(int slot, int preserveAlphaChannel); +ScriptDynamicSprite *DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface *sds, int x, int y, int width, int height); +ScriptDynamicSprite *DynamicSprite_Create(int width, int height, int alphaChannel); +ScriptDynamicSprite *DynamicSprite_CreateFromExistingSprite_Old(int slot); +ScriptDynamicSprite *DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height); -void add_dynamic_sprite(int gotSlot, Common::Bitmap *redin, bool hasAlpha = false); -void free_dynamic_sprite (int gotSlot); +void add_dynamic_sprite(int gotSlot, Common::Bitmap *redin, bool hasAlpha = false); +void free_dynamic_sprite(int gotSlot); #endif diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp index ef775fcb987d..ea692ed53178 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -31,108 +31,97 @@ using namespace AGS::Common; // *** The script serialization routines for built-in types int AGSCCDynamicObject::Dispose(const char *address, bool force) { - // cannot be removed from memory - return 0; + // cannot be removed from memory + return 0; } void AGSCCDynamicObject::StartSerialize(char *sbuffer) { - bytesSoFar = 0; - serbuffer = sbuffer; + bytesSoFar = 0; + serbuffer = sbuffer; } void AGSCCDynamicObject::SerializeInt(int val) { - char *chptr = &serbuffer[bytesSoFar]; - int *iptr = (int*)chptr; - *iptr = BBOp::Int32FromLE(val); - bytesSoFar += 4; + char *chptr = &serbuffer[bytesSoFar]; + int *iptr = (int *)chptr; + *iptr = BBOp::Int32FromLE(val); + bytesSoFar += 4; } void AGSCCDynamicObject::SerializeFloat(float val) { - char *chptr = &serbuffer[bytesSoFar]; - float *fptr = (float*)chptr; - *fptr = BBOp::FloatFromLE(val); - bytesSoFar += 4; + char *chptr = &serbuffer[bytesSoFar]; + float *fptr = (float *)chptr; + *fptr = BBOp::FloatFromLE(val); + bytesSoFar += 4; } int AGSCCDynamicObject::EndSerialize() { - return bytesSoFar; + return bytesSoFar; } void AGSCCDynamicObject::StartUnserialize(const char *sbuffer, int pTotalBytes) { - bytesSoFar = 0; - totalBytes = pTotalBytes; - serbuffer = (char*)sbuffer; + bytesSoFar = 0; + totalBytes = pTotalBytes; + serbuffer = (char *)sbuffer; } int AGSCCDynamicObject::UnserializeInt() { - if (bytesSoFar >= totalBytes) - quit("Unserialise: internal error: read past EOF"); + if (bytesSoFar >= totalBytes) + quit("Unserialise: internal error: read past EOF"); - char *chptr = &serbuffer[bytesSoFar]; - bytesSoFar += 4; - return BBOp::Int32FromLE(*((int*)chptr)); + char *chptr = &serbuffer[bytesSoFar]; + bytesSoFar += 4; + return BBOp::Int32FromLE(*((int *)chptr)); } float AGSCCDynamicObject::UnserializeFloat() { - if (bytesSoFar >= totalBytes) - quit("Unserialise: internal error: read past EOF"); + if (bytesSoFar >= totalBytes) + quit("Unserialise: internal error: read past EOF"); - char *chptr = &serbuffer[bytesSoFar]; - bytesSoFar += 4; - return BBOp::FloatFromLE(*((float*)chptr)); + char *chptr = &serbuffer[bytesSoFar]; + bytesSoFar += 4; + return BBOp::FloatFromLE(*((float *)chptr)); } -const char* AGSCCDynamicObject::GetFieldPtr(const char *address, intptr_t offset) -{ - return address + offset; +const char *AGSCCDynamicObject::GetFieldPtr(const char *address, intptr_t offset) { + return address + offset; } -void AGSCCDynamicObject::Read(const char *address, intptr_t offset, void *dest, int size) -{ - memcpy(dest, address + offset, size); +void AGSCCDynamicObject::Read(const char *address, intptr_t offset, void *dest, int size) { + memcpy(dest, address + offset, size); } -uint8_t AGSCCDynamicObject::ReadInt8(const char *address, intptr_t offset) -{ - return *(uint8_t*)(address + offset); +uint8_t AGSCCDynamicObject::ReadInt8(const char *address, intptr_t offset) { + return *(uint8_t *)(address + offset); } -int16_t AGSCCDynamicObject::ReadInt16(const char *address, intptr_t offset) -{ - return *(int16_t*)(address + offset); +int16_t AGSCCDynamicObject::ReadInt16(const char *address, intptr_t offset) { + return *(int16_t *)(address + offset); } -int32_t AGSCCDynamicObject::ReadInt32(const char *address, intptr_t offset) -{ - return *(int32_t*)(address + offset); +int32_t AGSCCDynamicObject::ReadInt32(const char *address, intptr_t offset) { + return *(int32_t *)(address + offset); } -float AGSCCDynamicObject::ReadFloat(const char *address, intptr_t offset) -{ - return *(float*)(address + offset); +float AGSCCDynamicObject::ReadFloat(const char *address, intptr_t offset) { + return *(float *)(address + offset); } -void AGSCCDynamicObject::Write(const char *address, intptr_t offset, void *src, int size) -{ - memcpy((void*)(address + offset), src, size); +void AGSCCDynamicObject::Write(const char *address, intptr_t offset, void *src, int size) { + memcpy((void *)(address + offset), src, size); } -void AGSCCDynamicObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) -{ - *(uint8_t*)(address + offset) = val; +void AGSCCDynamicObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) { + *(uint8_t *)(address + offset) = val; } -void AGSCCDynamicObject::WriteInt16(const char *address, intptr_t offset, int16_t val) -{ - *(int16_t*)(address + offset) = val; +void AGSCCDynamicObject::WriteInt16(const char *address, intptr_t offset, int16_t val) { + *(int16_t *)(address + offset) = val; } -void AGSCCDynamicObject::WriteInt32(const char *address, intptr_t offset, int32_t val) -{ - *(int32_t*)(address + offset) = val; +void AGSCCDynamicObject::WriteInt32(const char *address, intptr_t offset, int32_t val) { + *(int32_t *)(address + offset) = val; } -void AGSCCDynamicObject::WriteFloat(const char *address, intptr_t offset, float val) -{ - *(float*)(address + offset) = val; +void AGSCCDynamicObject::WriteFloat(const char *address, intptr_t offset, float val) { + *(float *)(address + offset) = val; } diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h index 30f83e8a5a42..c14103702614 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h @@ -27,41 +27,41 @@ struct AGSCCDynamicObject : ICCDynamicObject { protected: - virtual ~AGSCCDynamicObject() = default; + virtual ~AGSCCDynamicObject() = default; public: - // default implementation - int Dispose(const char *address, bool force) override; + // default implementation + int Dispose(const char *address, bool force) override; - // TODO: pass savegame format version - virtual void Unserialize(int index, const char *serializedData, int dataSize) = 0; + // TODO: pass savegame format version + virtual void Unserialize(int index, const char *serializedData, int dataSize) = 0; - // Legacy support for reading and writing object values by their relative offset - const char* GetFieldPtr(const char *address, intptr_t offset) override; - void Read(const char *address, intptr_t offset, void *dest, int size) override; - uint8_t ReadInt8(const char *address, intptr_t offset) override; - int16_t ReadInt16(const char *address, intptr_t offset) override; - int32_t ReadInt32(const char *address, intptr_t offset) override; - float ReadFloat(const char *address, intptr_t offset) override; - void Write(const char *address, intptr_t offset, void *src, int size) override; - void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; - void WriteInt16(const char *address, intptr_t offset, int16_t val) override; - void WriteInt32(const char *address, intptr_t offset, int32_t val) override; - void WriteFloat(const char *address, intptr_t offset, float val) override; + // Legacy support for reading and writing object values by their relative offset + const char *GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; protected: - // Savegame serialization - // TODO: reimplement with the proper memory stream?! - int bytesSoFar; - int totalBytes; - char *serbuffer; + // Savegame serialization + // TODO: reimplement with the proper memory stream?! + int bytesSoFar; + int totalBytes; + char *serbuffer; - void StartSerialize(char *sbuffer); - void SerializeInt(int val); - void SerializeFloat(float val); - int EndSerialize(); - void StartUnserialize(const char *sbuffer, int pTotalBytes); - int UnserializeInt(); - float UnserializeFloat(); + void StartSerialize(char *sbuffer); + void SerializeInt(int val); + void SerializeFloat(float val); + int EndSerialize(); + void StartUnserialize(const char *sbuffer, int pTotalBytes); + int UnserializeInt(); + float UnserializeFloat(); }; diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp index e93da266f5e9..b8463f2f3348 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp @@ -27,18 +27,18 @@ extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; const char *CCAudioChannel::GetType() { - return "AudioChannel"; + return "AudioChannel"; } int CCAudioChannel::Serialize(const char *address, char *buffer, int bufsize) { - ScriptAudioChannel *ach = (ScriptAudioChannel*)address; - StartSerialize(buffer); - SerializeInt(ach->id); - return EndSerialize(); + ScriptAudioChannel *ach = (ScriptAudioChannel *)address; + StartSerialize(buffer); + SerializeInt(ach->id); + return EndSerialize(); } void CCAudioChannel::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int id = UnserializeInt(); - ccRegisterUnserializedObject(index, &scrAudioChannel[id], this); + StartUnserialize(serializedData, dataSize); + int id = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrAudioChannel[id], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.h b/engines/ags/engine/ac/dynobj/cc_audiochannel.h index 8f5b2a05d8ec..e36ff25f36df 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.h +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.h @@ -26,9 +26,9 @@ #include "ac/dynobj/cc_agsdynamicobject.h" struct CCAudioChannel final : AGSCCDynamicObject { - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; #endif diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp index 90607a3c5cbc..06a70867d3f5 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp @@ -27,18 +27,18 @@ extern GameSetupStruct game; const char *CCAudioClip::GetType() { - return "AudioClip"; + return "AudioClip"; } int CCAudioClip::Serialize(const char *address, char *buffer, int bufsize) { - ScriptAudioClip *ach = (ScriptAudioClip*)address; - StartSerialize(buffer); - SerializeInt(ach->id); - return EndSerialize(); + ScriptAudioClip *ach = (ScriptAudioClip *)address; + StartSerialize(buffer); + SerializeInt(ach->id); + return EndSerialize(); } void CCAudioClip::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int id = UnserializeInt(); - ccRegisterUnserializedObject(index, &game.audioClips[id], this); + StartUnserialize(serializedData, dataSize); + int id = UnserializeInt(); + ccRegisterUnserializedObject(index, &game.audioClips[id], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.h b/engines/ags/engine/ac/dynobj/cc_audioclip.h index 5d715bbe9b7e..3b3f7645315b 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.h +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.h @@ -26,9 +26,9 @@ #include "ac/dynobj/cc_agsdynamicobject.h" struct CCAudioClip final : AGSCCDynamicObject { - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; #endif diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index f54087b0f209..07658e367d77 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -30,37 +30,34 @@ extern GameSetupStruct game; // return the type name of the object const char *CCCharacter::GetType() { - return "Character"; + return "Character"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCCharacter::Serialize(const char *address, char *buffer, int bufsize) { - CharacterInfo *chaa = (CharacterInfo*)address; - StartSerialize(buffer); - SerializeInt(chaa->index_id); - return EndSerialize(); + CharacterInfo *chaa = (CharacterInfo *)address; + StartSerialize(buffer); + SerializeInt(chaa->index_id); + return EndSerialize(); } void CCCharacter::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int num = UnserializeInt(); - ccRegisterUnserializedObject(index, &game.chars[num], this); + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &game.chars[num], this); } -void CCCharacter::WriteInt16(const char *address, intptr_t offset, int16_t val) -{ - *(int16_t*)(address + offset) = val; +void CCCharacter::WriteInt16(const char *address, intptr_t offset, int16_t val) { + *(int16_t *)(address + offset) = val; - // Detect when a game directly modifies the inventory, which causes the displayed - // and actual inventory to diverge since 2.70. Force an update of the displayed - // inventory for older games that reply on the previous behaviour. - if (loaded_game_file_version < kGameVersion_270) - { - const int invoffset = 112; - if (offset >= invoffset && offset < (invoffset + MAX_INV * sizeof(short))) - { - update_invorder(); - } - } + // Detect when a game directly modifies the inventory, which causes the displayed + // and actual inventory to diverge since 2.70. Force an update of the displayed + // inventory for older games that reply on the previous behaviour. + if (loaded_game_file_version < kGameVersion_270) { + const int invoffset = 112; + if (offset >= invoffset && offset < (invoffset + MAX_INV * sizeof(short))) { + update_invorder(); + } + } } diff --git a/engines/ags/engine/ac/dynobj/cc_character.h b/engines/ags/engine/ac/dynobj/cc_character.h index e9d461e4165c..e608c281e071 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.h +++ b/engines/ags/engine/ac/dynobj/cc_character.h @@ -27,16 +27,16 @@ struct CCCharacter final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; - void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; }; #endif diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp index 1b9cdfc0be68..47bcefca7693 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp @@ -27,20 +27,20 @@ // return the type name of the object const char *CCDialog::GetType() { - return "Dialog"; + return "Dialog"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCDialog::Serialize(const char *address, char *buffer, int bufsize) { - ScriptDialog *shh = (ScriptDialog*)address; - StartSerialize(buffer); - SerializeInt(shh->id); - return EndSerialize(); + ScriptDialog *shh = (ScriptDialog *)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); } void CCDialog::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int num = UnserializeInt(); - ccRegisterUnserializedObject(index, &scrDialog[num], this); + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrDialog[num], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.h b/engines/ags/engine/ac/dynobj/cc_dialog.h index 6146522622fe..0ed6030ff7fd 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.h +++ b/engines/ags/engine/ac/dynobj/cc_dialog.h @@ -27,14 +27,14 @@ struct CCDialog final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp index 9bf273b14b47..0a66cccc5047 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp @@ -25,145 +25,125 @@ // return the type name of the object const char *CCDynamicArray::GetType() { - return CC_DYNAMIC_ARRAY_TYPE_NAME; + return CC_DYNAMIC_ARRAY_TYPE_NAME; } int CCDynamicArray::Dispose(const char *address, bool force) { - address -= 8; - - // If it's an array of managed objects, release their ref counts; - // except if this array is forcefully removed from the managed pool, - // in which case just ignore these. - if (!force) - { - int *elementCount = (int*)address; - if (elementCount[0] & ARRAY_MANAGED_TYPE_FLAG) - { - elementCount[0] &= ~ARRAY_MANAGED_TYPE_FLAG; - for (int i = 0; i < elementCount[0]; i++) - { - if (elementCount[2 + i] != 0) - { - ccReleaseObjectReference(elementCount[2 + i]); - } - } - } - } - - delete address; - return 1; + address -= 8; + + // If it's an array of managed objects, release their ref counts; + // except if this array is forcefully removed from the managed pool, + // in which case just ignore these. + if (!force) { + int *elementCount = (int *)address; + if (elementCount[0] & ARRAY_MANAGED_TYPE_FLAG) { + elementCount[0] &= ~ARRAY_MANAGED_TYPE_FLAG; + for (int i = 0; i < elementCount[0]; i++) { + if (elementCount[2 + i] != 0) { + ccReleaseObjectReference(elementCount[2 + i]); + } + } + } + } + + delete address; + return 1; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCDynamicArray::Serialize(const char *address, char *buffer, int bufsize) { - int *sizeInBytes = &((int*)address)[-1]; - int sizeToWrite = *sizeInBytes + 8; - if (sizeToWrite > bufsize) - { - // buffer not big enough, ask for a bigger one - return -sizeToWrite; - } - memcpy(buffer, address - 8, sizeToWrite); - return sizeToWrite; + int *sizeInBytes = &((int *)address)[-1]; + int sizeToWrite = *sizeInBytes + 8; + if (sizeToWrite > bufsize) { + // buffer not big enough, ask for a bigger one + return -sizeToWrite; + } + memcpy(buffer, address - 8, sizeToWrite); + return sizeToWrite; } void CCDynamicArray::Unserialize(int index, const char *serializedData, int dataSize) { - char *newArray = new char[dataSize]; - memcpy(newArray, serializedData, dataSize); - ccRegisterUnserializedObject(index, &newArray[8], this); + char *newArray = new char[dataSize]; + memcpy(newArray, serializedData, dataSize); + ccRegisterUnserializedObject(index, &newArray[8], this); } -DynObjectRef CCDynamicArray::Create(int numElements, int elementSize, bool isManagedType) -{ - char *newArray = new char[numElements * elementSize + 8]; - memset(newArray, 0, numElements * elementSize + 8); - int *sizePtr = (int*)newArray; - sizePtr[0] = numElements; - sizePtr[1] = numElements * elementSize; - if (isManagedType) - sizePtr[0] |= ARRAY_MANAGED_TYPE_FLAG; - void *obj_ptr = &newArray[8]; - int32_t handle = ccRegisterManagedObject(obj_ptr, this); - if (handle == 0) - { - delete[] newArray; - return DynObjectRef(0, nullptr); - } - return DynObjectRef(handle, obj_ptr); +DynObjectRef CCDynamicArray::Create(int numElements, int elementSize, bool isManagedType) { + char *newArray = new char[numElements * elementSize + 8]; + memset(newArray, 0, numElements * elementSize + 8); + int *sizePtr = (int *)newArray; + sizePtr[0] = numElements; + sizePtr[1] = numElements * elementSize; + if (isManagedType) + sizePtr[0] |= ARRAY_MANAGED_TYPE_FLAG; + void *obj_ptr = &newArray[8]; + int32_t handle = ccRegisterManagedObject(obj_ptr, this); + if (handle == 0) { + delete[] newArray; + return DynObjectRef(0, nullptr); + } + return DynObjectRef(handle, obj_ptr); } -const char* CCDynamicArray::GetFieldPtr(const char *address, intptr_t offset) -{ - return address + offset; +const char *CCDynamicArray::GetFieldPtr(const char *address, intptr_t offset) { + return address + offset; } -void CCDynamicArray::Read(const char *address, intptr_t offset, void *dest, int size) -{ - memcpy(dest, address + offset, size); +void CCDynamicArray::Read(const char *address, intptr_t offset, void *dest, int size) { + memcpy(dest, address + offset, size); } -uint8_t CCDynamicArray::ReadInt8(const char *address, intptr_t offset) -{ - return *(uint8_t*)(address + offset); +uint8_t CCDynamicArray::ReadInt8(const char *address, intptr_t offset) { + return *(uint8_t *)(address + offset); } -int16_t CCDynamicArray::ReadInt16(const char *address, intptr_t offset) -{ - return *(int16_t*)(address + offset); +int16_t CCDynamicArray::ReadInt16(const char *address, intptr_t offset) { + return *(int16_t *)(address + offset); } -int32_t CCDynamicArray::ReadInt32(const char *address, intptr_t offset) -{ - return *(int32_t*)(address + offset); +int32_t CCDynamicArray::ReadInt32(const char *address, intptr_t offset) { + return *(int32_t *)(address + offset); } -float CCDynamicArray::ReadFloat(const char *address, intptr_t offset) -{ - return *(float*)(address + offset); +float CCDynamicArray::ReadFloat(const char *address, intptr_t offset) { + return *(float *)(address + offset); } -void CCDynamicArray::Write(const char *address, intptr_t offset, void *src, int size) -{ - memcpy((void*)(address + offset), src, size); +void CCDynamicArray::Write(const char *address, intptr_t offset, void *src, int size) { + memcpy((void *)(address + offset), src, size); } -void CCDynamicArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) -{ - *(uint8_t*)(address + offset) = val; +void CCDynamicArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) { + *(uint8_t *)(address + offset) = val; } -void CCDynamicArray::WriteInt16(const char *address, intptr_t offset, int16_t val) -{ - *(int16_t*)(address + offset) = val; +void CCDynamicArray::WriteInt16(const char *address, intptr_t offset, int16_t val) { + *(int16_t *)(address + offset) = val; } -void CCDynamicArray::WriteInt32(const char *address, intptr_t offset, int32_t val) -{ - *(int32_t*)(address + offset) = val; +void CCDynamicArray::WriteInt32(const char *address, intptr_t offset, int32_t val) { + *(int32_t *)(address + offset) = val; } -void CCDynamicArray::WriteFloat(const char *address, intptr_t offset, float val) -{ - *(float*)(address + offset) = val; +void CCDynamicArray::WriteFloat(const char *address, intptr_t offset, float val) { + *(float *)(address + offset) = val; } CCDynamicArray globalDynamicArray; -DynObjectRef DynamicArrayHelpers::CreateStringArray(const std::vector items) -{ - // NOTE: we need element size of "handle" for array of managed pointers - DynObjectRef arr = globalDynamicArray.Create(items.size(), sizeof(int32_t), true); - if (!arr.second) - return arr; - // Create script strings and put handles into array - int32_t *slots = static_cast(arr.second); - for (auto s : items) - { - DynObjectRef str = stringClassImpl->CreateString(s); - *(slots++) = str.first; - } - return arr; +DynObjectRef DynamicArrayHelpers::CreateStringArray(const std::vector items) { + // NOTE: we need element size of "handle" for array of managed pointers + DynObjectRef arr = globalDynamicArray.Create(items.size(), sizeof(int32_t), true); + if (!arr.second) + return arr; + // Create script strings and put handles into array + int32_t *slots = static_cast(arr.second); + for (auto s : items) { + DynObjectRef str = stringClassImpl->CreateString(s); + *(slots++) = str.first; + } + return arr; } diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index 8ee984eb39d7..f5febb7e03ec 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -29,39 +29,37 @@ #define CC_DYNAMIC_ARRAY_TYPE_NAME "CCDynamicArray" #define ARRAY_MANAGED_TYPE_FLAG 0x80000000 -struct CCDynamicArray final : ICCDynamicObject -{ - // return the type name of the object - const char *GetType() override; - int Dispose(const char *address, bool force) override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; - virtual void Unserialize(int index, const char *serializedData, int dataSize); - // Create managed array object and return a pointer to the beginning of a buffer - DynObjectRef Create(int numElements, int elementSize, bool isManagedType); +struct CCDynamicArray final : ICCDynamicObject { + // return the type name of the object + const char *GetType() override; + int Dispose(const char *address, bool force) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + virtual void Unserialize(int index, const char *serializedData, int dataSize); + // Create managed array object and return a pointer to the beginning of a buffer + DynObjectRef Create(int numElements, int elementSize, bool isManagedType); - // Legacy support for reading and writing object values by their relative offset - const char* GetFieldPtr(const char *address, intptr_t offset) override; - void Read(const char *address, intptr_t offset, void *dest, int size) override; - uint8_t ReadInt8(const char *address, intptr_t offset) override; - int16_t ReadInt16(const char *address, intptr_t offset) override; - int32_t ReadInt32(const char *address, intptr_t offset) override; - float ReadFloat(const char *address, intptr_t offset) override; - void Write(const char *address, intptr_t offset, void *src, int size) override; - void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; - void WriteInt16(const char *address, intptr_t offset, int16_t val) override; - void WriteInt32(const char *address, intptr_t offset, int32_t val) override; - void WriteFloat(const char *address, intptr_t offset, float val) override; + // Legacy support for reading and writing object values by their relative offset + const char *GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; }; extern CCDynamicArray globalDynamicArray; // Helper functions for setting up dynamic arrays. -namespace DynamicArrayHelpers -{ - // Create array of managed strings - DynObjectRef CreateStringArray(const std::vector); +namespace DynamicArrayHelpers { +// Create array of managed strings +DynObjectRef CreateStringArray(const std::vector); }; #endif diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp index 0bc70e3aee75..09fb15af7c7d 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp @@ -51,111 +51,110 @@ ICCStringClass *stringClassImpl = nullptr; // set the class that will be used for dynamic strings void ccSetStringClassImpl(ICCStringClass *theClass) { - stringClassImpl = theClass; + stringClassImpl = theClass; } // register a memory handle for the object and allow script // pointers to point to it int32_t ccRegisterManagedObject(const void *object, ICCDynamicObject *callback, bool plugin_object) { - int32_t handl = pool.AddObject((const char*)object, callback, plugin_object); + int32_t handl = pool.AddObject((const char *)object, callback, plugin_object); - ManagedObjectLog("Register managed object type '%s' handle=%d addr=%08X", - ((callback == NULL) ? "(unknown)" : callback->GetType()), handl, object); + ManagedObjectLog("Register managed object type '%s' handle=%d addr=%08X", + ((callback == NULL) ? "(unknown)" : callback->GetType()), handl, object); - return handl; + return handl; } // register a de-serialized object int32_t ccRegisterUnserializedObject(int index, const void *object, ICCDynamicObject *callback, bool plugin_object) { - return pool.AddUnserializedObject((const char*)object, callback, plugin_object, index); + return pool.AddUnserializedObject((const char *)object, callback, plugin_object, index); } // unregister a particular object int ccUnRegisterManagedObject(const void *object) { - return pool.RemoveObject((const char*)object); + return pool.RemoveObject((const char *)object); } // remove all registered objects void ccUnregisterAllObjects() { - pool.reset(); + pool.reset(); } // serialize all objects to disk void ccSerializeAllObjects(Stream *out) { - pool.WriteToDisk(out); + pool.WriteToDisk(out); } // un-serialise all objects (will remove all currently registered ones) int ccUnserializeAllObjects(Stream *in, ICCObjectReader *callback) { - return pool.ReadFromDisk(in, callback); + return pool.ReadFromDisk(in, callback); } // dispose the object if RefCount==0 void ccAttemptDisposeObject(int32_t handle) { - pool.CheckDispose(handle); + pool.CheckDispose(handle); } // translate between object handles and memory addresses int32_t ccGetObjectHandleFromAddress(const char *address) { - // set to null - if (address == nullptr) - return 0; + // set to null + if (address == nullptr) + return 0; - int32_t handl = pool.AddressToHandle(address); + int32_t handl = pool.AddressToHandle(address); - ManagedObjectLog("Line %d WritePtr: %08X to %d", currentline, address, handl); + ManagedObjectLog("Line %d WritePtr: %08X to %d", currentline, address, handl); - if (handl == 0) { - cc_error("Pointer cast failure: the object being pointed to is not in the managed object pool"); - return -1; - } - return handl; + if (handl == 0) { + cc_error("Pointer cast failure: the object being pointed to is not in the managed object pool"); + return -1; + } + return handl; } const char *ccGetObjectAddressFromHandle(int32_t handle) { - if (handle == 0) { - return nullptr; - } - const char *addr = pool.HandleToAddress(handle); - - ManagedObjectLog("Line %d ReadPtr: %d to %08X", currentline, handle, addr); - - if (addr == nullptr) { - cc_error("Error retrieving pointer: invalid handle %d", handle); - return nullptr; - } - return addr; + if (handle == 0) { + return nullptr; + } + const char *addr = pool.HandleToAddress(handle); + + ManagedObjectLog("Line %d ReadPtr: %d to %08X", currentline, handle, addr); + + if (addr == nullptr) { + cc_error("Error retrieving pointer: invalid handle %d", handle); + return nullptr; + } + return addr; } -ScriptValueType ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager) -{ - if (handle == 0) { - object = nullptr; - manager = nullptr; - return kScValUndefined; - } - ScriptValueType obj_type = pool.HandleToAddressAndManager(handle, object, manager); - if (obj_type == kScValUndefined) { - cc_error("Error retrieving pointer: invalid handle %d", handle); - } - return obj_type; +ScriptValueType ccGetObjectAddressAndManagerFromHandle(int32_t handle, void *&object, ICCDynamicObject *&manager) { + if (handle == 0) { + object = nullptr; + manager = nullptr; + return kScValUndefined; + } + ScriptValueType obj_type = pool.HandleToAddressAndManager(handle, object, manager); + if (obj_type == kScValUndefined) { + cc_error("Error retrieving pointer: invalid handle %d", handle); + } + return obj_type; } int ccAddObjectReference(int32_t handle) { - if (handle == 0) - return 0; + if (handle == 0) + return 0; - return pool.AddRef(handle); + return pool.AddRef(handle); } int ccReleaseObjectReference(int32_t handle) { - if (handle == 0) - return 0; + if (handle == 0) + return 0; - if (pool.HandleToAddress(handle) == nullptr) { - cc_error("Error releasing pointer: invalid handle %d", handle); - return -1; - } + if (pool.HandleToAddress(handle) == nullptr) { + cc_error("Error releasing pointer: invalid handle %d", handle); + return -1; + } - return pool.SubRef(handle); + return pool.SubRef(handle); } diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index ada26fd3ffc4..39f7a2ffcf6c 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -33,67 +33,71 @@ #include "core/types.h" // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later // A pair of managed handle and abstract object pointer -typedef std::pair DynObjectRef; +typedef std::pair DynObjectRef; // OBJECT-BASED SCRIPTING RUNTIME FUNCTIONS // interface struct ICCDynamicObject { - // when a ref count reaches 0, this is called with the address - // of the object. Return 1 to remove the object from memory, 0 to - // leave it - // The "force" flag tells system to detach the object, breaking any links and references - // to other managed objects or game resources (instead of disposing these too). - // TODO: it might be better to rewrite the managed pool and remove this flag at all, - // because it makes the use of this interface prone to mistakes. - virtual int Dispose(const char *address, bool force = false) = 0; - // return the type name of the object - virtual const char *GetType() = 0; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - // TODO: pass savegame format version - virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; + // when a ref count reaches 0, this is called with the address + // of the object. Return 1 to remove the object from memory, 0 to + // leave it + // The "force" flag tells system to detach the object, breaking any links and references + // to other managed objects or game resources (instead of disposing these too). + // TODO: it might be better to rewrite the managed pool and remove this flag at all, + // because it makes the use of this interface prone to mistakes. + virtual int Dispose(const char *address, bool force = false) = 0; + // return the type name of the object + virtual const char *GetType() = 0; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + // TODO: pass savegame format version + virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; - // Legacy support for reading and writing object values by their relative offset. - // WARNING: following were never a part of plugin API, therefore these methods - // should **never** be called for kScValPluginObject script objects! - // - // RE: GetFieldPtr() - // According to AGS script specification, when the old-string pointer or char array is passed - // as an argument, the byte-code does not include any specific command for the member variable - // retrieval and instructs to pass an address of the object itself with certain offset. - // This results in functions like StrCopy writing directly over object address. - // There may be other implementations, but the big question is: how to detect when this is - // necessary, because byte-code does not contain any distinct operation for this case. - // The worst thing here is that with the current byte-code structure we can never tell whether - // offset 0 means getting pointer to whole object or a pointer to its first field. - virtual const char* GetFieldPtr(const char *address, intptr_t offset) = 0; - virtual void Read(const char *address, intptr_t offset, void *dest, int size) = 0; - virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; - virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; - virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; - virtual float ReadFloat(const char *address, intptr_t offset) = 0; - virtual void Write(const char *address, intptr_t offset, void *src, int size) = 0; - virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; - virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; - virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; - virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; + // Legacy support for reading and writing object values by their relative offset. + // WARNING: following were never a part of plugin API, therefore these methods + // should **never** be called for kScValPluginObject script objects! + // + // RE: GetFieldPtr() + // According to AGS script specification, when the old-string pointer or char array is passed + // as an argument, the byte-code does not include any specific command for the member variable + // retrieval and instructs to pass an address of the object itself with certain offset. + // This results in functions like StrCopy writing directly over object address. + // There may be other implementations, but the big question is: how to detect when this is + // necessary, because byte-code does not contain any distinct operation for this case. + // The worst thing here is that with the current byte-code structure we can never tell whether + // offset 0 means getting pointer to whole object or a pointer to its first field. + virtual const char *GetFieldPtr(const char *address, intptr_t offset) = 0; + virtual void Read(const char *address, intptr_t offset, void *dest, int size) = 0; + virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; + virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; + virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; + virtual float ReadFloat(const char *address, intptr_t offset) = 0; + virtual void Write(const char *address, intptr_t offset, void *src, int size) = 0; + virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; + virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; + virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; + virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; protected: - ICCDynamicObject() = default; - ~ICCDynamicObject() = default; + ICCDynamicObject() = default; + ~ICCDynamicObject() = default; }; struct ICCObjectReader { - // TODO: pass savegame format version - virtual void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) = 0; + // TODO: pass savegame format version + virtual void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) = 0; }; struct ICCStringClass { - virtual DynObjectRef CreateString(const char *fromText) = 0; + virtual DynObjectRef CreateString(const char *fromText) = 0; }; // set the class that will be used for dynamic strings diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h index 99d55e5f0e1a..d3a9e5963a28 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h @@ -27,7 +27,7 @@ #include "ac/dynobj/cc_dynamicobject.h" extern ScriptValueType ccGetObjectAddressAndManagerFromHandle( - int32_t handle, void *&object, ICCDynamicObject *&manager); + int32_t handle, void *&object, ICCDynamicObject *&manager); #endif diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp index e453edd45b24..300883cff82a 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.cpp +++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp @@ -27,20 +27,20 @@ extern ScriptGUI *scrGui; // return the type name of the object const char *CCGUI::GetType() { - return "GUI"; + return "GUI"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCGUI::Serialize(const char *address, char *buffer, int bufsize) { - ScriptGUI *shh = (ScriptGUI*)address; - StartSerialize(buffer); - SerializeInt(shh->id); - return EndSerialize(); + ScriptGUI *shh = (ScriptGUI *)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); } void CCGUI::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int num = UnserializeInt(); - ccRegisterUnserializedObject(index, &scrGui[num], this); + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrGui[num], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_gui.h b/engines/ags/engine/ac/dynobj/cc_gui.h index 8d1b60838714..7a24b76e2304 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.h +++ b/engines/ags/engine/ac/dynobj/cc_gui.h @@ -27,14 +27,14 @@ struct CCGUI final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; #endif diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp index 5983f6561bfc..df0e23233d7b 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -29,22 +29,22 @@ using AGS::Common::GUIObject; // return the type name of the object const char *CCGUIObject::GetType() { - return "GUIObject"; + return "GUIObject"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCGUIObject::Serialize(const char *address, char *buffer, int bufsize) { - GUIObject *guio = (GUIObject*)address; - StartSerialize(buffer); - SerializeInt(guio->ParentId); - SerializeInt(guio->Id); - return EndSerialize(); + GUIObject *guio = (GUIObject *)address; + StartSerialize(buffer); + SerializeInt(guio->ParentId); + SerializeInt(guio->Id); + return EndSerialize(); } void CCGUIObject::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int guinum = UnserializeInt(); - int objnum = UnserializeInt(); - ccRegisterUnserializedObject(index, guis[guinum].GetControl(objnum), this); + StartUnserialize(serializedData, dataSize); + int guinum = UnserializeInt(); + int objnum = UnserializeInt(); + ccRegisterUnserializedObject(index, guis[guinum].GetControl(objnum), this); } diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.h b/engines/ags/engine/ac/dynobj/cc_guiobject.h index bb457bed10c0..d07e6bd645ce 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.h +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.h @@ -27,14 +27,14 @@ struct CCGUIObject final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp index 073cd657142a..310a1ad06d51 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp @@ -29,20 +29,20 @@ extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; // return the type name of the object const char *CCHotspot::GetType() { - return "Hotspot"; + return "Hotspot"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCHotspot::Serialize(const char *address, char *buffer, int bufsize) { - ScriptHotspot *shh = (ScriptHotspot*)address; - StartSerialize(buffer); - SerializeInt(shh->id); - return EndSerialize(); + ScriptHotspot *shh = (ScriptHotspot *)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); } void CCHotspot::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int num = UnserializeInt(); - ccRegisterUnserializedObject(index, &scrHotspot[num], this); + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrHotspot[num], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.h b/engines/ags/engine/ac/dynobj/cc_hotspot.h index e5ca7a7756a6..0efb6ed4bd2a 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.h +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.h @@ -27,14 +27,14 @@ struct CCHotspot final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp index 9333b5d96cf5..1e3045348bfa 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.cpp +++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp @@ -28,20 +28,20 @@ extern ScriptInvItem scrInv[MAX_INV]; // return the type name of the object const char *CCInventory::GetType() { - return "Inventory"; + return "Inventory"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCInventory::Serialize(const char *address, char *buffer, int bufsize) { - ScriptInvItem *shh = (ScriptInvItem*)address; - StartSerialize(buffer); - SerializeInt(shh->id); - return EndSerialize(); + ScriptInvItem *shh = (ScriptInvItem *)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); } void CCInventory::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int num = UnserializeInt(); - ccRegisterUnserializedObject(index, &scrInv[num], this); + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrInv[num], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.h b/engines/ags/engine/ac/dynobj/cc_inventory.h index 4b793b339426..450305d69dcd 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.h +++ b/engines/ags/engine/ac/dynobj/cc_inventory.h @@ -27,14 +27,14 @@ struct CCInventory final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp index 355456e78cf3..1f695146f39d 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.cpp +++ b/engines/ags/engine/ac/dynobj/cc_object.cpp @@ -29,20 +29,20 @@ extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; // return the type name of the object const char *CCObject::GetType() { - return "Object"; + return "Object"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCObject::Serialize(const char *address, char *buffer, int bufsize) { - ScriptObject *shh = (ScriptObject*)address; - StartSerialize(buffer); - SerializeInt(shh->id); - return EndSerialize(); + ScriptObject *shh = (ScriptObject *)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); } void CCObject::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int num = UnserializeInt(); - ccRegisterUnserializedObject(index, &scrObj[num], this); + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrObj[num], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_object.h b/engines/ags/engine/ac/dynobj/cc_object.h index 88533aaebe99..d1da2d7a2b6f 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.h +++ b/engines/ags/engine/ac/dynobj/cc_object.h @@ -27,14 +27,14 @@ struct CCObject final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp index 31130c9b5e59..a1de49619b2e 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.cpp +++ b/engines/ags/engine/ac/dynobj/cc_region.cpp @@ -29,20 +29,20 @@ extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; // return the type name of the object const char *CCRegion::GetType() { - return "Region"; + return "Region"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCRegion::Serialize(const char *address, char *buffer, int bufsize) { - ScriptRegion *shh = (ScriptRegion*)address; - StartSerialize(buffer); - SerializeInt(shh->id); - return EndSerialize(); + ScriptRegion *shh = (ScriptRegion *)address; + StartSerialize(buffer); + SerializeInt(shh->id); + return EndSerialize(); } void CCRegion::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int num = UnserializeInt(); - ccRegisterUnserializedObject(index, &scrRegion[num], this); + StartUnserialize(serializedData, dataSize); + int num = UnserializeInt(); + ccRegisterUnserializedObject(index, &scrRegion[num], this); } diff --git a/engines/ags/engine/ac/dynobj/cc_region.h b/engines/ags/engine/ac/dynobj/cc_region.h index c16136d599a3..7b52c7ae775c 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.h +++ b/engines/ags/engine/ac/dynobj/cc_region.h @@ -27,14 +27,14 @@ struct CCRegion final : AGSCCDynamicObject { - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; }; diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp index f183747b983a..90ae3bad28db 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.cpp +++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp @@ -42,7 +42,7 @@ extern CCInventory ccDynamicInv; extern CCGUI ccDynamicGUI; extern CCObject ccDynamicObject; extern CCDialog ccDynamicDialog; -extern ScriptDrawingSurface* dialogOptionsRenderingSurface; +extern ScriptDrawingSurface *dialogOptionsRenderingSurface; extern ScriptDialogOptionsRendering ccDialogOptionsRendering; extern PluginObjectReader pluginReaders[MAX_PLUGIN_OBJECT_READERS]; extern int numPluginReaders; @@ -52,100 +52,72 @@ extern int numPluginReaders; void AGSDeSerializer::Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) { - if (strcmp(objectType, "GUIObject") == 0) { - ccDynamicGUIObject.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Character") == 0) { - ccDynamicCharacter.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Hotspot") == 0) { - ccDynamicHotspot.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Region") == 0) { - ccDynamicRegion.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Inventory") == 0) { - ccDynamicInv.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Dialog") == 0) { - ccDynamicDialog.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "GUI") == 0) { - ccDynamicGUI.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Object") == 0) { - ccDynamicObject.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "String") == 0) { - ScriptString *scf = new ScriptString(); - scf->Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "File") == 0) { - // files cannot be restored properly -- so just recreate - // the object; attempting any operations on it will fail - sc_File *scf = new sc_File(); - ccRegisterUnserializedObject(index, scf, scf); - } - else if (strcmp(objectType, "Overlay") == 0) { - ScriptOverlay *scf = new ScriptOverlay(); - scf->Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "DateTime") == 0) { - ScriptDateTime *scf = new ScriptDateTime(); - scf->Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "ViewFrame") == 0) { - ScriptViewFrame *scf = new ScriptViewFrame(); - scf->Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "DynamicSprite") == 0) { - ScriptDynamicSprite *scf = new ScriptDynamicSprite(); - scf->Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "DrawingSurface") == 0) { - ScriptDrawingSurface *sds = new ScriptDrawingSurface(); - sds->Unserialize(index, serializedData, dataSize); + if (strcmp(objectType, "GUIObject") == 0) { + ccDynamicGUIObject.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Character") == 0) { + ccDynamicCharacter.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Hotspot") == 0) { + ccDynamicHotspot.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Region") == 0) { + ccDynamicRegion.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Inventory") == 0) { + ccDynamicInv.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Dialog") == 0) { + ccDynamicDialog.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "GUI") == 0) { + ccDynamicGUI.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Object") == 0) { + ccDynamicObject.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "String") == 0) { + ScriptString *scf = new ScriptString(); + scf->Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "File") == 0) { + // files cannot be restored properly -- so just recreate + // the object; attempting any operations on it will fail + sc_File *scf = new sc_File(); + ccRegisterUnserializedObject(index, scf, scf); + } else if (strcmp(objectType, "Overlay") == 0) { + ScriptOverlay *scf = new ScriptOverlay(); + scf->Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "DateTime") == 0) { + ScriptDateTime *scf = new ScriptDateTime(); + scf->Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "ViewFrame") == 0) { + ScriptViewFrame *scf = new ScriptViewFrame(); + scf->Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "DynamicSprite") == 0) { + ScriptDynamicSprite *scf = new ScriptDynamicSprite(); + scf->Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "DrawingSurface") == 0) { + ScriptDrawingSurface *sds = new ScriptDrawingSurface(); + sds->Unserialize(index, serializedData, dataSize); - if (sds->isLinkedBitmapOnly) - { - dialogOptionsRenderingSurface = sds; - } - } - else if (strcmp(objectType, "DialogOptionsRendering") == 0) - { - ccDialogOptionsRendering.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "StringDictionary") == 0) - { - Dict_Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "StringSet") == 0) - { - Set_Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Viewport2") == 0) - { - Viewport_Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "Camera2") == 0) - { - Camera_Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "UserObject") == 0) { - ScriptUserObject *suo = new ScriptUserObject(); - suo->Unserialize(index, serializedData, dataSize); - } - else if (!unserialize_audio_script_object(index, objectType, serializedData, dataSize)) - { - // check if the type is read by a plugin - for (int ii = 0; ii < numPluginReaders; ii++) { - if (strcmp(objectType, pluginReaders[ii].type) == 0) { - pluginReaders[ii].reader->Unserialize(index, serializedData, dataSize); - return; - } - } - quitprintf("Unserialise: unknown object type: '%s'", objectType); - } + if (sds->isLinkedBitmapOnly) { + dialogOptionsRenderingSurface = sds; + } + } else if (strcmp(objectType, "DialogOptionsRendering") == 0) { + ccDialogOptionsRendering.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "StringDictionary") == 0) { + Dict_Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "StringSet") == 0) { + Set_Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Viewport2") == 0) { + Viewport_Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "Camera2") == 0) { + Camera_Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "UserObject") == 0) { + ScriptUserObject *suo = new ScriptUserObject(); + suo->Unserialize(index, serializedData, dataSize); + } else if (!unserialize_audio_script_object(index, objectType, serializedData, dataSize)) { + // check if the type is read by a plugin + for (int ii = 0; ii < numPluginReaders; ii++) { + if (strcmp(objectType, pluginReaders[ii].type) == 0) { + pluginReaders[ii].reader->Unserialize(index, serializedData, dataSize); + return; + } + } + quitprintf("Unserialise: unknown object type: '%s'", objectType); + } } AGSDeSerializer ccUnserializer; diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h index 655138738b55..0253eb94f31d 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.h +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -27,7 +27,7 @@ struct AGSDeSerializer : ICCObjectReader { - void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) override; }; extern AGSDeSerializer ccUnserializer; diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index 2d430147437a..a5ab383717f0 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -38,294 +38,342 @@ const auto GARBAGE_COLLECTION_INTERVAL = 1024; const auto RESERVED_SIZE = 2048; int ManagedObjectPool::Remove(ManagedObject &o, bool force) { - if (!o.isUsed()) { return 1; } // already removed + if (!o.isUsed()) { + return 1; // already removed + } - bool canBeRemovedFromPool = o.callback->Dispose(o.addr, force) != 0; - if (!(canBeRemovedFromPool || force)) { return 0; } + bool canBeRemovedFromPool = o.callback->Dispose(o.addr, force) != 0; + if (!(canBeRemovedFromPool || force)) { + return 0; + } - auto handle = o.handle; - available_ids.push(o.handle); + auto handle = o.handle; + available_ids.push(o.handle); - handleByAddress.erase(o.addr); - o = ManagedObject(); + handleByAddress.erase(o.addr); + o = ManagedObject(); - ManagedObjectLog("Line %d Disposed managed object handle=%d", currentline, handle); + ManagedObjectLog("Line %d Disposed managed object handle=%d", currentline, handle); - return 1; + return 1; } int32_t ManagedObjectPool::AddRef(int32_t handle) { - if (handle < 0 || (size_t)handle >= objects.size()) { return 0; } - auto & o = objects[handle]; - if (!o.isUsed()) { return 0; } - - o.refCount += 1; - ManagedObjectLog("Line %d AddRef: handle=%d new refcount=%d", currentline, o.handle, o.refCount); - return o.refCount; + if (handle < 0 || (size_t)handle >= objects.size()) { + return 0; + } + auto &o = objects[handle]; + if (!o.isUsed()) { + return 0; + } + + o.refCount += 1; + ManagedObjectLog("Line %d AddRef: handle=%d new refcount=%d", currentline, o.handle, o.refCount); + return o.refCount; } int ManagedObjectPool::CheckDispose(int32_t handle) { - if (handle < 0 || (size_t)handle >= objects.size()) { return 1; } - auto & o = objects[handle]; - if (!o.isUsed()) { return 1; } - if (o.refCount >= 1) { return 0; } - return Remove(o); + if (handle < 0 || (size_t)handle >= objects.size()) { + return 1; + } + auto &o = objects[handle]; + if (!o.isUsed()) { + return 1; + } + if (o.refCount >= 1) { + return 0; + } + return Remove(o); } int32_t ManagedObjectPool::SubRef(int32_t handle) { - if (handle < 0 || (size_t)handle >= objects.size()) { return 0; } - auto & o = objects[handle]; - if (!o.isUsed()) { return 0; } - - o.refCount--; - auto newRefCount = o.refCount; - auto canBeDisposed = (o.addr != disableDisposeForObject); - if (canBeDisposed) { - CheckDispose(handle); - } - // object could be removed at this point, don't use any values. - ManagedObjectLog("Line %d SubRef: handle=%d new refcount=%d canBeDisposed=%d", currentline, handle, newRefCount, canBeDisposed); - return newRefCount; + if (handle < 0 || (size_t)handle >= objects.size()) { + return 0; + } + auto &o = objects[handle]; + if (!o.isUsed()) { + return 0; + } + + o.refCount--; + auto newRefCount = o.refCount; + auto canBeDisposed = (o.addr != disableDisposeForObject); + if (canBeDisposed) { + CheckDispose(handle); + } + // object could be removed at this point, don't use any values. + ManagedObjectLog("Line %d SubRef: handle=%d new refcount=%d canBeDisposed=%d", currentline, handle, newRefCount, canBeDisposed); + return newRefCount; } int32_t ManagedObjectPool::AddressToHandle(const char *addr) { - if (addr == nullptr) { return 0; } - auto it = handleByAddress.find(addr); - if (it == handleByAddress.end()) { return 0; } - return it->second; + if (addr == nullptr) { + return 0; + } + auto it = handleByAddress.find(addr); + if (it == handleByAddress.end()) { + return 0; + } + return it->second; } // this function is called often (whenever a pointer is used) -const char* ManagedObjectPool::HandleToAddress(int32_t handle) { - if (handle < 0 || (size_t)handle >= objects.size()) { return nullptr; } - auto & o = objects[handle]; - if (!o.isUsed()) { return nullptr; } - return o.addr; +const char *ManagedObjectPool::HandleToAddress(int32_t handle) { + if (handle < 0 || (size_t)handle >= objects.size()) { + return nullptr; + } + auto &o = objects[handle]; + if (!o.isUsed()) { + return nullptr; + } + return o.addr; } // this function is called often (whenever a pointer is used) ScriptValueType ManagedObjectPool::HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager) { - if (handle < 0 || (size_t)handle >= objects.size()) { return kScValUndefined; } - auto & o = objects[handle]; - if (!o.isUsed()) { return kScValUndefined; } - - object = (void *)o.addr; // WARNING: This strips the const from the char* pointer. - manager = o.callback; - return o.obj_type; + if (handle < 0 || (size_t)handle >= objects.size()) { + return kScValUndefined; + } + auto &o = objects[handle]; + if (!o.isUsed()) { + return kScValUndefined; + } + + object = (void *)o.addr; // WARNING: This strips the const from the char* pointer. + manager = o.callback; + return o.obj_type; } int ManagedObjectPool::RemoveObject(const char *address) { - if (address == nullptr) { return 0; } - auto it = handleByAddress.find(address); - if (it == handleByAddress.end()) { return 0; } - - auto & o = objects[it->second]; - return Remove(o, true); + if (address == nullptr) { + return 0; + } + auto it = handleByAddress.find(address); + if (it == handleByAddress.end()) { + return 0; + } + + auto &o = objects[it->second]; + return Remove(o, true); } -void ManagedObjectPool::RunGarbageCollectionIfAppropriate() -{ - if (objectCreationCounter <= GARBAGE_COLLECTION_INTERVAL) { return; } - RunGarbageCollection(); - objectCreationCounter = 0; +void ManagedObjectPool::RunGarbageCollectionIfAppropriate() { + if (objectCreationCounter <= GARBAGE_COLLECTION_INTERVAL) { + return; + } + RunGarbageCollection(); + objectCreationCounter = 0; } -void ManagedObjectPool::RunGarbageCollection() -{ - for (int i = 1; i < nextHandle; i++) { - auto & o = objects[i]; - if (!o.isUsed()) { continue; } - if (o.refCount < 1) { - Remove(o); - } - } - ManagedObjectLog("Ran garbage collection"); +void ManagedObjectPool::RunGarbageCollection() { + for (int i = 1; i < nextHandle; i++) { + auto &o = objects[i]; + if (!o.isUsed()) { + continue; + } + if (o.refCount < 1) { + Remove(o); + } + } + ManagedObjectLog("Ran garbage collection"); } -int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object) -{ - int32_t handle; - - if (!available_ids.empty()) { - handle = available_ids.front(); - available_ids.pop(); - } else { - handle = nextHandle++; - if ((size_t)handle >= objects.size()) { - objects.resize(handle + 1024, ManagedObject()); - } - } - - auto & o = objects[handle]; - if (o.isUsed()) { cc_error("used: %d", handle); return 0; } - - o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); - - handleByAddress.insert({address, o.handle}); - objectCreationCounter++; - ManagedObjectLog("Allocated managed object handle=%d, type=%s", handle, callback->GetType()); - return o.handle; +int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object) { + int32_t handle; + + if (!available_ids.empty()) { + handle = available_ids.front(); + available_ids.pop(); + } else { + handle = nextHandle++; + if ((size_t)handle >= objects.size()) { + objects.resize(handle + 1024, ManagedObject()); + } + } + + auto &o = objects[handle]; + if (o.isUsed()) { + cc_error("used: %d", handle); + return 0; + } + + o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); + + handleByAddress.insert({address, o.handle}); + objectCreationCounter++; + ManagedObjectLog("Allocated managed object handle=%d, type=%s", handle, callback->GetType()); + return o.handle; } -int ManagedObjectPool::AddUnserializedObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int handle) -{ - if (handle < 0) { cc_error("Attempt to assign invalid handle: %d", handle); return 0; } - if ((size_t)handle >= objects.size()) { - objects.resize(handle + 1024, ManagedObject()); - } +int ManagedObjectPool::AddUnserializedObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int handle) { + if (handle < 0) { + cc_error("Attempt to assign invalid handle: %d", handle); + return 0; + } + if ((size_t)handle >= objects.size()) { + objects.resize(handle + 1024, ManagedObject()); + } - auto & o = objects[handle]; - if (o.isUsed()) { cc_error("bad save. used: %d", o.handle); return 0; } + auto &o = objects[handle]; + if (o.isUsed()) { + cc_error("bad save. used: %d", o.handle); + return 0; + } - o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); + o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); - handleByAddress.insert({address, o.handle}); - ManagedObjectLog("Allocated unserialized managed object handle=%d, type=%s", o.handle, callback->GetType()); - return o.handle; + handleByAddress.insert({address, o.handle}); + ManagedObjectLog("Allocated unserialized managed object handle=%d, type=%s", o.handle, callback->GetType()); + return o.handle; } void ManagedObjectPool::WriteToDisk(Stream *out) { - // use this opportunity to clean up any non-referenced pointers - RunGarbageCollection(); - - std::vector serializeBuffer; - serializeBuffer.resize(SERIALIZE_BUFFER_SIZE); - - out->WriteInt32(OBJECT_CACHE_MAGIC_NUMBER); - out->WriteInt32(2); // version - - int size = 0; - for (int i = 1; i < nextHandle; i++) { - auto const & o = objects[i]; - if (o.isUsed()) { - size += 1; - } - } - out->WriteInt32(size); - - for (int i = 1; i < nextHandle; i++) { - auto const & o = objects[i]; - if (!o.isUsed()) { continue; } - - // handle - out->WriteInt32(o.handle); - // write the type of the object - StrUtil::WriteCStr((char*)o.callback->GetType(), out); - // now write the object data - int bytesWritten = o.callback->Serialize(o.addr, &serializeBuffer.front(), serializeBuffer.size()); - if ((bytesWritten < 0) && ((size_t)(-bytesWritten) > serializeBuffer.size())) - { - // buffer not big enough, re-allocate with requested size - serializeBuffer.resize(-bytesWritten); - bytesWritten = o.callback->Serialize(o.addr, &serializeBuffer.front(), serializeBuffer.size()); - } - assert(bytesWritten >= 0); - out->WriteInt32(bytesWritten); - out->Write(&serializeBuffer.front(), bytesWritten); - out->WriteInt32(o.refCount); - - ManagedObjectLog("Wrote handle = %d", o.handle); - } + // use this opportunity to clean up any non-referenced pointers + RunGarbageCollection(); + + std::vector serializeBuffer; + serializeBuffer.resize(SERIALIZE_BUFFER_SIZE); + + out->WriteInt32(OBJECT_CACHE_MAGIC_NUMBER); + out->WriteInt32(2); // version + + int size = 0; + for (int i = 1; i < nextHandle; i++) { + auto const &o = objects[i]; + if (o.isUsed()) { + size += 1; + } + } + out->WriteInt32(size); + + for (int i = 1; i < nextHandle; i++) { + auto const &o = objects[i]; + if (!o.isUsed()) { + continue; + } + + // handle + out->WriteInt32(o.handle); + // write the type of the object + StrUtil::WriteCStr((char *)o.callback->GetType(), out); + // now write the object data + int bytesWritten = o.callback->Serialize(o.addr, &serializeBuffer.front(), serializeBuffer.size()); + if ((bytesWritten < 0) && ((size_t)(-bytesWritten) > serializeBuffer.size())) { + // buffer not big enough, re-allocate with requested size + serializeBuffer.resize(-bytesWritten); + bytesWritten = o.callback->Serialize(o.addr, &serializeBuffer.front(), serializeBuffer.size()); + } + assert(bytesWritten >= 0); + out->WriteInt32(bytesWritten); + out->Write(&serializeBuffer.front(), bytesWritten); + out->WriteInt32(o.refCount); + + ManagedObjectLog("Wrote handle = %d", o.handle); + } } int ManagedObjectPool::ReadFromDisk(Stream *in, ICCObjectReader *reader) { - if (in->ReadInt32() != OBJECT_CACHE_MAGIC_NUMBER) { - cc_error("Data was not written by ccSeralize"); - return -1; - } - - char typeNameBuffer[200]; - std::vector serializeBuffer; - serializeBuffer.resize(SERIALIZE_BUFFER_SIZE); - - auto version = in->ReadInt32(); - - switch (version) { - case 1: - { - // IMPORTANT: numObjs is "nextHandleId", which is why we iterate from 1 to numObjs-1 - int numObjs = in->ReadInt32(); - for (int i = 1; i < numObjs; i++) { - StrUtil::ReadCStr(typeNameBuffer, in, sizeof(typeNameBuffer)); - if (typeNameBuffer[0] != 0) { - size_t numBytes = in->ReadInt32(); - if (numBytes > serializeBuffer.size()) { - serializeBuffer.resize(numBytes); - } - in->Read(&serializeBuffer.front(), numBytes); - if (strcmp(typeNameBuffer, CC_DYNAMIC_ARRAY_TYPE_NAME) == 0) { - globalDynamicArray.Unserialize(i, &serializeBuffer.front(), numBytes); - } else { - reader->Unserialize(i, typeNameBuffer, &serializeBuffer.front(), numBytes); - } - objects[i].refCount = in->ReadInt32(); - ManagedObjectLog("Read handle = %d", objects[i].handle); - } - } - } - break; - case 2: - { - // This is actually number of objects written. - int objectsSize = in->ReadInt32(); - for (int i = 0; i < objectsSize; i++) { - auto handle = in->ReadInt32(); - assert (handle >= 1); - StrUtil::ReadCStr(typeNameBuffer, in, sizeof(typeNameBuffer)); - assert (typeNameBuffer[0] != 0); - size_t numBytes = in->ReadInt32(); - if (numBytes > serializeBuffer.size()) { - serializeBuffer.resize(numBytes); - } - in->Read(&serializeBuffer.front(), numBytes); - if (strcmp(typeNameBuffer, CC_DYNAMIC_ARRAY_TYPE_NAME) == 0) { - globalDynamicArray.Unserialize(handle, &serializeBuffer.front(), numBytes); - } else { - reader->Unserialize(handle, typeNameBuffer, &serializeBuffer.front(), numBytes); - } - objects[handle].refCount = in->ReadInt32(); - ManagedObjectLog("Read handle = %d", objects[i].handle); - } - } - break; - default: - cc_error("Invalid data version: %d", version); - return -1; - } - - // re-adjust next handles. (in case saved in random order) - while (!available_ids.empty()) { available_ids.pop(); } - nextHandle = 1; - - for (const auto &o : objects) { - if (o.isUsed()) { - nextHandle = o.handle + 1; - } - } - for (int i = 1; i < nextHandle; i++) { - if (!objects[i].isUsed()) { - available_ids.push(i); - } - } - - return 0; + if (in->ReadInt32() != OBJECT_CACHE_MAGIC_NUMBER) { + cc_error("Data was not written by ccSeralize"); + return -1; + } + + char typeNameBuffer[200]; + std::vector serializeBuffer; + serializeBuffer.resize(SERIALIZE_BUFFER_SIZE); + + auto version = in->ReadInt32(); + + switch (version) { + case 1: { + // IMPORTANT: numObjs is "nextHandleId", which is why we iterate from 1 to numObjs-1 + int numObjs = in->ReadInt32(); + for (int i = 1; i < numObjs; i++) { + StrUtil::ReadCStr(typeNameBuffer, in, sizeof(typeNameBuffer)); + if (typeNameBuffer[0] != 0) { + size_t numBytes = in->ReadInt32(); + if (numBytes > serializeBuffer.size()) { + serializeBuffer.resize(numBytes); + } + in->Read(&serializeBuffer.front(), numBytes); + if (strcmp(typeNameBuffer, CC_DYNAMIC_ARRAY_TYPE_NAME) == 0) { + globalDynamicArray.Unserialize(i, &serializeBuffer.front(), numBytes); + } else { + reader->Unserialize(i, typeNameBuffer, &serializeBuffer.front(), numBytes); + } + objects[i].refCount = in->ReadInt32(); + ManagedObjectLog("Read handle = %d", objects[i].handle); + } + } + } + break; + case 2: { + // This is actually number of objects written. + int objectsSize = in->ReadInt32(); + for (int i = 0; i < objectsSize; i++) { + auto handle = in->ReadInt32(); + assert(handle >= 1); + StrUtil::ReadCStr(typeNameBuffer, in, sizeof(typeNameBuffer)); + assert(typeNameBuffer[0] != 0); + size_t numBytes = in->ReadInt32(); + if (numBytes > serializeBuffer.size()) { + serializeBuffer.resize(numBytes); + } + in->Read(&serializeBuffer.front(), numBytes); + if (strcmp(typeNameBuffer, CC_DYNAMIC_ARRAY_TYPE_NAME) == 0) { + globalDynamicArray.Unserialize(handle, &serializeBuffer.front(), numBytes); + } else { + reader->Unserialize(handle, typeNameBuffer, &serializeBuffer.front(), numBytes); + } + objects[handle].refCount = in->ReadInt32(); + ManagedObjectLog("Read handle = %d", objects[i].handle); + } + } + break; + default: + cc_error("Invalid data version: %d", version); + return -1; + } + + // re-adjust next handles. (in case saved in random order) + while (!available_ids.empty()) { + available_ids.pop(); + } + nextHandle = 1; + + for (const auto &o : objects) { + if (o.isUsed()) { + nextHandle = o.handle + 1; + } + } + for (int i = 1; i < nextHandle; i++) { + if (!objects[i].isUsed()) { + available_ids.push(i); + } + } + + return 0; } // de-allocate all objects void ManagedObjectPool::reset() { - for (int i = 1; i < nextHandle; i++) { - auto & o = objects[i]; - if (!o.isUsed()) { continue; } - Remove(o, true); - } - while (!available_ids.empty()) { available_ids.pop(); } - nextHandle = 1; + for (int i = 1; i < nextHandle; i++) { + auto &o = objects[i]; + if (!o.isUsed()) { + continue; + } + Remove(o, true); + } + while (!available_ids.empty()) { + available_ids.pop(); + } + nextHandle = 1; } ManagedObjectPool::ManagedObjectPool() : objectCreationCounter(0), nextHandle(1), available_ids(), objects(RESERVED_SIZE, ManagedObject()), handleByAddress() { - handleByAddress.reserve(RESERVED_SIZE); + handleByAddress.reserve(RESERVED_SIZE); } ManagedObjectPool pool; diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index b08284222520..93cd695b1f18 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -30,59 +30,65 @@ #include "script/runtimescriptvalue.h" #include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject -namespace AGS { namespace Common { class Stream; }} +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later struct ManagedObjectPool final { private: - // TODO: find out if we can make handle size_t - struct ManagedObject { - ScriptValueType obj_type; - int32_t handle; - // TODO: this makes no sense having this as "const char*", - // void* will be proper (and in all related functions) - const char *addr; - ICCDynamicObject *callback; - int refCount; - - bool isUsed() const { return obj_type != kScValUndefined; } - - ManagedObject() - : obj_type(kScValUndefined), handle(0), addr(nullptr), callback(nullptr), refCount(0) {} - ManagedObject(ScriptValueType obj_type, int32_t handle, const char *addr, ICCDynamicObject * callback) - : obj_type(obj_type), handle(handle), addr(addr), callback(callback), refCount(0) {} - }; - - int objectCreationCounter; // used to do garbage collection every so often - - int32_t nextHandle {}; // TODO: manage nextHandle's going over INT32_MAX ! - std::queue available_ids; - std::vector objects; - std::unordered_map handleByAddress; - - void Init(int32_t theHandle, const char *theAddress, ICCDynamicObject *theCallback, ScriptValueType objType); - int Remove(ManagedObject &o, bool force = false); - - void RunGarbageCollection(); + // TODO: find out if we can make handle size_t + struct ManagedObject { + ScriptValueType obj_type; + int32_t handle; + // TODO: this makes no sense having this as "const char*", + // void* will be proper (and in all related functions) + const char *addr; + ICCDynamicObject *callback; + int refCount; + + bool isUsed() const { + return obj_type != kScValUndefined; + } + + ManagedObject() + : obj_type(kScValUndefined), handle(0), addr(nullptr), callback(nullptr), refCount(0) {} + ManagedObject(ScriptValueType obj_type, int32_t handle, const char *addr, ICCDynamicObject *callback) + : obj_type(obj_type), handle(handle), addr(addr), callback(callback), refCount(0) {} + }; + + int objectCreationCounter; // used to do garbage collection every so often + + int32_t nextHandle {}; // TODO: manage nextHandle's going over INT32_MAX ! + std::queue available_ids; + std::vector objects; + std::unordered_map handleByAddress; + + void Init(int32_t theHandle, const char *theAddress, ICCDynamicObject *theCallback, ScriptValueType objType); + int Remove(ManagedObject &o, bool force = false); + + void RunGarbageCollection(); public: - int32_t AddRef(int32_t handle); - int CheckDispose(int32_t handle); - int32_t SubRef(int32_t handle); - int32_t AddressToHandle(const char *addr); - const char* HandleToAddress(int32_t handle); - ScriptValueType HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager); - int RemoveObject(const char *address); - void RunGarbageCollectionIfAppropriate(); - int AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object); - int AddUnserializedObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int handle); - void WriteToDisk(Common::Stream *out); - int ReadFromDisk(Common::Stream *in, ICCObjectReader *reader); - void reset(); - ManagedObjectPool(); - - const char* disableDisposeForObject {nullptr}; + int32_t AddRef(int32_t handle); + int CheckDispose(int32_t handle); + int32_t SubRef(int32_t handle); + int32_t AddressToHandle(const char *addr); + const char *HandleToAddress(int32_t handle); + ScriptValueType HandleToAddressAndManager(int32_t handle, void *&object, ICCDynamicObject *&manager); + int RemoveObject(const char *address); + void RunGarbageCollectionIfAppropriate(); + int AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object); + int AddUnserializedObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int handle); + void WriteToDisk(Common::Stream *out); + int ReadFromDisk(Common::Stream *in, ICCObjectReader *reader); + void reset(); + ManagedObjectPool(); + + const char *disableDisposeForObject {nullptr}; }; extern ManagedObjectPool pool; diff --git a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h index 8b762f7ec34c..2358526b2a98 100644 --- a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h +++ b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h @@ -23,10 +23,9 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTAUDIOCHANNEL_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTAUDIOCHANNEL_H -struct ScriptAudioChannel -{ - int id; - int reserved; +struct ScriptAudioChannel { + int id; + int reserved; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp index a4f44f881b49..138464e29cf9 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.cpp +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -28,45 +28,39 @@ using namespace AGS::Common; ScriptCamera::ScriptCamera(int id) : _id(id) {} -const char *ScriptCamera::GetType() -{ - return "Camera2"; +const char *ScriptCamera::GetType() { + return "Camera2"; } -int ScriptCamera::Dispose(const char *address, bool force) -{ - // Note that ScriptCamera is a reference to actual Camera object, - // and this deletes the reference, while camera may remain in GameState. - delete this; - return 1; +int ScriptCamera::Dispose(const char *address, bool force) { + // Note that ScriptCamera is a reference to actual Camera object, + // and this deletes the reference, while camera may remain in GameState. + delete this; + return 1; } -int ScriptCamera::Serialize(const char *address, char *buffer, int bufsize) -{ - StartSerialize(buffer); - SerializeInt(_id); - return EndSerialize(); +int ScriptCamera::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + SerializeInt(_id); + return EndSerialize(); } -void ScriptCamera::Unserialize(int index, const char *serializedData, int dataSize) -{ - StartUnserialize(serializedData, dataSize); - _id = UnserializeInt(); - ccRegisterUnserializedObject(index, this, this); +void ScriptCamera::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + _id = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); } -ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dataSize) -{ - // The way it works now, we must not create a new script object, - // but acquire one from the GameState, which keeps the first reference. - // This is essential because GameState should be able to invalidate any - // script references when Camera gets removed. - const int id = BBOp::Int32FromLE(*((int*)serializedData)); - if (id >= 0) - { - auto scam = play.RegisterRoomCamera(id, handle); - if (scam) - return scam; - } - return new ScriptCamera(-1); // make invalid reference +ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dataSize) { + // The way it works now, we must not create a new script object, + // but acquire one from the GameState, which keeps the first reference. + // This is essential because GameState should be able to invalidate any + // script references when Camera gets removed. + const int id = BBOp::Int32FromLE(*((int *)serializedData)); + if (id >= 0) { + auto scam = play.RegisterRoomCamera(id, handle); + if (scam) + return scam; + } + return new ScriptCamera(-1); // make invalid reference } diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.h b/engines/ags/engine/ac/dynobj/scriptcamera.h index 16708a1e8366..c958a78c36a3 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.h +++ b/engines/ags/engine/ac/dynobj/scriptcamera.h @@ -26,24 +26,29 @@ #include "ac/dynobj/cc_agsdynamicobject.h" // ScriptCamera keeps a reference to actual room Camera in script. -struct ScriptCamera final : AGSCCDynamicObject -{ +struct ScriptCamera final : AGSCCDynamicObject { public: - ScriptCamera(int id); - - // Get camera index; negative means the camera was deleted - int GetID() const { return _id; } - void SetID(int id) { _id = id; } - // Reset camera index to indicate that this reference is no longer valid - void Invalidate() { _id = -1; } - - const char *GetType() override; - int Dispose(const char *address, bool force) override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + ScriptCamera(int id); + + // Get camera index; negative means the camera was deleted + int GetID() const { + return _id; + } + void SetID(int id) { + _id = id; + } + // Reset camera index to indicate that this reference is no longer valid + void Invalidate() { + _id = -1; + } + + const char *GetType() override; + int Dispose(const char *address, bool force) override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; private: - int _id = -1; // index of camera in the game state array + int _id = -1; // index of camera in the game state array }; // Unserialize camera from the memory stream diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp index 45836d06e483..19c0abcd9165 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp @@ -23,41 +23,41 @@ #include "ac/dynobj/scriptdatetime.h" int ScriptDateTime::Dispose(const char *address, bool force) { - // always dispose a DateTime - delete this; - return 1; + // always dispose a DateTime + delete this; + return 1; } const char *ScriptDateTime::GetType() { - return "DateTime"; + return "DateTime"; } int ScriptDateTime::Serialize(const char *address, char *buffer, int bufsize) { - StartSerialize(buffer); - SerializeInt(year); - SerializeInt(month); - SerializeInt(day); - SerializeInt(hour); - SerializeInt(minute); - SerializeInt(second); - SerializeInt(rawUnixTime); - return EndSerialize(); + StartSerialize(buffer); + SerializeInt(year); + SerializeInt(month); + SerializeInt(day); + SerializeInt(hour); + SerializeInt(minute); + SerializeInt(second); + SerializeInt(rawUnixTime); + return EndSerialize(); } void ScriptDateTime::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - year = UnserializeInt(); - month = UnserializeInt(); - day = UnserializeInt(); - hour = UnserializeInt(); - minute = UnserializeInt(); - second = UnserializeInt(); - rawUnixTime = UnserializeInt(); - ccRegisterUnserializedObject(index, this, this); + StartUnserialize(serializedData, dataSize); + year = UnserializeInt(); + month = UnserializeInt(); + day = UnserializeInt(); + hour = UnserializeInt(); + minute = UnserializeInt(); + second = UnserializeInt(); + rawUnixTime = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); } ScriptDateTime::ScriptDateTime() { - year = month = day = 0; - hour = minute = second = 0; - rawUnixTime = 0; + year = month = day = 0; + hour = minute = second = 0; + rawUnixTime = 0; } diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.h b/engines/ags/engine/ac/dynobj/scriptdatetime.h index e65661a3198b..79c755149bf9 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.h +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.h @@ -26,16 +26,16 @@ #include "ac/dynobj/cc_agsdynamicobject.h" struct ScriptDateTime final : AGSCCDynamicObject { - int year, month, day; - int hour, minute, second; - int rawUnixTime; + int year, month, day; + int hour, minute, second; + int rawUnixTime; - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; - ScriptDateTime(); + ScriptDateTime(); }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdialog.h b/engines/ags/engine/ac/dynobj/scriptdialog.h index 9668fa4d62ef..b1bdefd72788 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialog.h +++ b/engines/ags/engine/ac/dynobj/scriptdialog.h @@ -24,8 +24,8 @@ #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOG_H struct ScriptDialog { - int id; - int reserved; + int id; + int reserved; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp index d844282b7806..7414e3a81c3e 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp @@ -24,38 +24,36 @@ // return the type name of the object const char *ScriptDialogOptionsRendering::GetType() { - return "DialogOptionsRendering"; + return "DialogOptionsRendering"; } // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int ScriptDialogOptionsRendering::Serialize(const char *address, char *buffer, int bufsize) { - return 0; + return 0; } void ScriptDialogOptionsRendering::Unserialize(int index, const char *serializedData, int dataSize) { - ccRegisterUnserializedObject(index, this, this); + ccRegisterUnserializedObject(index, this, this); } -void ScriptDialogOptionsRendering::Reset() -{ - x = 0; - y = 0; - width = 0; - height = 0; - hasAlphaChannel = false; - parserTextboxX = 0; - parserTextboxY = 0; - parserTextboxWidth = 0; - dialogID = 0; - surfaceToRenderTo = nullptr; - surfaceAccessed = false; - activeOptionID = -1; - chosenOptionID = -1; - needRepaint = false; +void ScriptDialogOptionsRendering::Reset() { + x = 0; + y = 0; + width = 0; + height = 0; + hasAlphaChannel = false; + parserTextboxX = 0; + parserTextboxY = 0; + parserTextboxWidth = 0; + dialogID = 0; + surfaceToRenderTo = nullptr; + surfaceAccessed = false; + activeOptionID = -1; + chosenOptionID = -1; + needRepaint = false; } -ScriptDialogOptionsRendering::ScriptDialogOptionsRendering() -{ - Reset(); +ScriptDialogOptionsRendering::ScriptDialogOptionsRendering() { + Reset(); } diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h index bc09dd8d8c89..88277931ff96 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h @@ -26,29 +26,29 @@ #include "ac/dynobj/scriptdrawingsurface.h" struct ScriptDialogOptionsRendering final : AGSCCDynamicObject { - int x, y, width, height; - bool hasAlphaChannel; - int parserTextboxX, parserTextboxY; - int parserTextboxWidth; - int dialogID; - int activeOptionID; - int chosenOptionID; - ScriptDrawingSurface *surfaceToRenderTo; - bool surfaceAccessed; - bool needRepaint; + int x, y, width, height; + bool hasAlphaChannel; + int parserTextboxX, parserTextboxY; + int parserTextboxWidth; + int dialogID; + int activeOptionID; + int chosenOptionID; + ScriptDrawingSurface *surfaceToRenderTo; + bool surfaceAccessed; + bool needRepaint; - // return the type name of the object - const char *GetType() override; + // return the type name of the object + const char *GetType() override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; - void Reset(); + void Reset(); - ScriptDialogOptionsRendering(); + ScriptDialogOptionsRendering(); }; diff --git a/engines/ags/engine/ac/dynobj/scriptdict.cpp b/engines/ags/engine/ac/dynobj/scriptdict.cpp index 4bec65ce42a8..8dbb901265e6 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdict.cpp @@ -22,38 +22,33 @@ #include "ac/dynobj/scriptdict.h" -int ScriptDictBase::Dispose(const char *address, bool force) -{ - Clear(); - delete this; - return 1; +int ScriptDictBase::Dispose(const char *address, bool force) { + Clear(); + delete this; + return 1; } -const char *ScriptDictBase::GetType() -{ - return "StringDictionary"; +const char *ScriptDictBase::GetType() { + return "StringDictionary"; } -int ScriptDictBase::Serialize(const char *address, char *buffer, int bufsize) -{ - size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; - if (bufsize < 0 || total_sz >(size_t)bufsize) - { - // buffer not big enough, ask for a bigger one - return -((int)total_sz); - } - StartSerialize(buffer); - SerializeInt(IsSorted()); - SerializeInt(IsCaseSensitive()); - SerializeContainer(); - return EndSerialize(); +int ScriptDictBase::Serialize(const char *address, char *buffer, int bufsize) { + size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; + if (bufsize < 0 || total_sz > (size_t)bufsize) { + // buffer not big enough, ask for a bigger one + return -((int)total_sz); + } + StartSerialize(buffer); + SerializeInt(IsSorted()); + SerializeInt(IsCaseSensitive()); + SerializeContainer(); + return EndSerialize(); } -void ScriptDictBase::Unserialize(int index, const char *serializedData, int dataSize) -{ - // NOTE: we expect sorted/case flags are read by external reader; - // this is awkward, but I did not find better design solution atm - StartUnserialize(serializedData, dataSize); - UnserializeContainer(serializedData); - ccRegisterUnserializedObject(index, this, this); +void ScriptDictBase::Unserialize(int index, const char *serializedData, int dataSize) { + // NOTE: we expect sorted/case flags are read by external reader; + // this is awkward, but I did not find better design solution atm + StartUnserialize(serializedData, dataSize); + UnserializeContainer(serializedData); + ccRegisterUnserializedObject(index, this, this); } diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index da8062ed08a2..3dc6b863266b 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -45,148 +45,139 @@ using namespace AGS::Common; -class ScriptDictBase : public AGSCCDynamicObject -{ +class ScriptDictBase : public AGSCCDynamicObject { public: - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; - - virtual bool IsCaseSensitive() const = 0; - virtual bool IsSorted() const = 0; - - virtual void Clear() = 0; - virtual bool Contains(const char *key) = 0; - virtual const char *Get(const char *key) = 0; - virtual bool Remove(const char *key) = 0; - virtual bool Set(const char *key, const char *value) = 0; - virtual int GetItemCount() = 0; - virtual void GetKeys(std::vector &buf) const = 0; - virtual void GetValues(std::vector &buf) const = 0; + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + + virtual bool IsCaseSensitive() const = 0; + virtual bool IsSorted() const = 0; + + virtual void Clear() = 0; + virtual bool Contains(const char *key) = 0; + virtual const char *Get(const char *key) = 0; + virtual bool Remove(const char *key) = 0; + virtual bool Set(const char *key, const char *value) = 0; + virtual int GetItemCount() = 0; + virtual void GetKeys(std::vector &buf) const = 0; + virtual void GetValues(std::vector &buf) const = 0; private: - virtual size_t CalcSerializeSize() = 0; - virtual void SerializeContainer() = 0; - virtual void UnserializeContainer(const char *serializedData) = 0; + virtual size_t CalcSerializeSize() = 0; + virtual void SerializeContainer() = 0; + virtual void UnserializeContainer(const char *serializedData) = 0; }; template -class ScriptDictImpl final : public ScriptDictBase -{ +class ScriptDictImpl final : public ScriptDictBase { public: - typedef typename TDict::const_iterator ConstIterator; - - ScriptDictImpl() = default; - - bool IsCaseSensitive() const override { return is_casesensitive; } - bool IsSorted() const override { return is_sorted; } - - void Clear() override - { - for (auto it = _dic.begin(); it != _dic.end(); ++it) - DeleteItem(it); - _dic.clear(); - } - bool Contains(const char *key) override { return _dic.count(String::Wrapper(key)) != 0; } - const char *Get(const char *key) override - { - auto it = _dic.find(String::Wrapper(key)); - if (it == _dic.end()) return nullptr; - return it->second.GetNullableCStr(); - } - bool Remove(const char *key) override - { - auto it = _dic.find(String::Wrapper(key)); - if (it == _dic.end()) return false; - DeleteItem(it); - _dic.erase(it); - return true; - } - bool Set(const char *key, const char *value) override - { - if (!key) return false; - size_t key_len = strlen(key); - size_t value_len = value ? strlen(value) : 0; - return TryAddItem(key, key_len, value, value_len); - } - int GetItemCount() override { return _dic.size(); } - void GetKeys(std::vector &buf) const override - { - for (auto it = _dic.begin(); it != _dic.end(); ++it) - buf.push_back(it->first.GetCStr()); // keys cannot be null - } - void GetValues(std::vector &buf) const override - { - for (auto it = _dic.begin(); it != _dic.end(); ++it) - buf.push_back(it->second.GetNullableCStr()); // values may be null - } + typedef typename TDict::const_iterator ConstIterator; + + ScriptDictImpl() = default; + + bool IsCaseSensitive() const override { + return is_casesensitive; + } + bool IsSorted() const override { + return is_sorted; + } + + void Clear() override { + for (auto it = _dic.begin(); it != _dic.end(); ++it) + DeleteItem(it); + _dic.clear(); + } + bool Contains(const char *key) override { + return _dic.count(String::Wrapper(key)) != 0; + } + const char *Get(const char *key) override { + auto it = _dic.find(String::Wrapper(key)); + if (it == _dic.end()) return nullptr; + return it->second.GetNullableCStr(); + } + bool Remove(const char *key) override { + auto it = _dic.find(String::Wrapper(key)); + if (it == _dic.end()) return false; + DeleteItem(it); + _dic.erase(it); + return true; + } + bool Set(const char *key, const char *value) override { + if (!key) return false; + size_t key_len = strlen(key); + size_t value_len = value ? strlen(value) : 0; + return TryAddItem(key, key_len, value, value_len); + } + int GetItemCount() override { + return _dic.size(); + } + void GetKeys(std::vector &buf) const override { + for (auto it = _dic.begin(); it != _dic.end(); ++it) + buf.push_back(it->first.GetCStr()); // keys cannot be null + } + void GetValues(std::vector &buf) const override { + for (auto it = _dic.begin(); it != _dic.end(); ++it) + buf.push_back(it->second.GetNullableCStr()); // values may be null + } private: - bool TryAddItem(const char *key, size_t key_len, const char *value, size_t value_len) - { - String elem_key(key, key_len); - String elem_value; - if (value) - elem_value.SetString(value, value_len); - _dic[elem_key] = elem_value; - return true; - } - void DeleteItem(ConstIterator it) { /* do nothing */ } - - size_t CalcSerializeSize() override - { - size_t total_sz = sizeof(int32_t); - for (auto it = _dic.begin(); it != _dic.end(); ++it) - { - total_sz += sizeof(int32_t) + it->first.GetLength(); - total_sz += sizeof(int32_t) + it->second.GetLength(); - } - return total_sz; - } - - void SerializeContainer() override - { - SerializeInt((int)_dic.size()); - for (auto it = _dic.begin(); it != _dic.end(); ++it) - { - SerializeInt((int)it->first.GetLength()); - memcpy(&serbuffer[bytesSoFar], it->first.GetCStr(), it->first.GetLength()); - bytesSoFar += it->first.GetLength(); - if (it->second.GetNullableCStr()) // values may be null - { - SerializeInt((int)it->second.GetLength()); - memcpy(&serbuffer[bytesSoFar], it->second.GetCStr(), it->second.GetLength()); - bytesSoFar += it->second.GetLength(); - } - else - { - SerializeInt(-1); - } - } - } - - void UnserializeContainer(const char *serializedData) override - { - size_t item_count = (size_t)UnserializeInt(); - for (size_t i = 0; i < item_count; ++i) - { - size_t key_len = UnserializeInt(); - int key_pos = bytesSoFar; bytesSoFar += key_len; - size_t value_len = UnserializeInt(); - if (value_len == (size_t)-1) - { - TryAddItem(&serializedData[key_pos], key_len, nullptr, 0); - } - else - { - int value_pos = bytesSoFar; bytesSoFar += value_len; - TryAddItem(&serializedData[key_pos], key_len, &serializedData[value_pos], value_len); - } - } - } - - TDict _dic; + bool TryAddItem(const char *key, size_t key_len, const char *value, size_t value_len) { + String elem_key(key, key_len); + String elem_value; + if (value) + elem_value.SetString(value, value_len); + _dic[elem_key] = elem_value; + return true; + } + void DeleteItem(ConstIterator it) { + /* do nothing */ + } + + size_t CalcSerializeSize() override { + size_t total_sz = sizeof(int32_t); + for (auto it = _dic.begin(); it != _dic.end(); ++it) { + total_sz += sizeof(int32_t) + it->first.GetLength(); + total_sz += sizeof(int32_t) + it->second.GetLength(); + } + return total_sz; + } + + void SerializeContainer() override { + SerializeInt((int)_dic.size()); + for (auto it = _dic.begin(); it != _dic.end(); ++it) { + SerializeInt((int)it->first.GetLength()); + memcpy(&serbuffer[bytesSoFar], it->first.GetCStr(), it->first.GetLength()); + bytesSoFar += it->first.GetLength(); + if (it->second.GetNullableCStr()) { // values may be null + SerializeInt((int)it->second.GetLength()); + memcpy(&serbuffer[bytesSoFar], it->second.GetCStr(), it->second.GetLength()); + bytesSoFar += it->second.GetLength(); + } else { + SerializeInt(-1); + } + } + } + + void UnserializeContainer(const char *serializedData) override { + size_t item_count = (size_t)UnserializeInt(); + for (size_t i = 0; i < item_count; ++i) { + size_t key_len = UnserializeInt(); + int key_pos = bytesSoFar; + bytesSoFar += key_len; + size_t value_len = UnserializeInt(); + if (value_len == (size_t) - 1) { + TryAddItem(&serializedData[key_pos], key_len, nullptr, 0); + } else { + int value_pos = bytesSoFar; + bytesSoFar += value_len; + TryAddItem(&serializedData[key_pos], key_len, &serializedData[value_pos], value_len); + } + } + } + + TDict _dic; }; typedef ScriptDictImpl< std::map, true, true > ScriptDict; diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp index 14e66298f42c..08e1bbc591b6 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -38,100 +38,94 @@ extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES]; extern GameState play; extern GameSetupStruct game; -Bitmap* ScriptDrawingSurface::GetBitmapSurface() -{ - // TODO: consider creating weak_ptr here, and store one in the DrawingSurface! - if (roomBackgroundNumber >= 0) - return thisroom.BgFrames[roomBackgroundNumber].Graphic.get(); - else if (dynamicSpriteNumber >= 0) - return spriteset[dynamicSpriteNumber]; - else if (dynamicSurfaceNumber >= 0) - return dynamicallyCreatedSurfaces[dynamicSurfaceNumber]; - else if (linkedBitmapOnly != nullptr) - return linkedBitmapOnly; - else if (roomMaskType > kRoomAreaNone) - return thisroom.GetMask(roomMaskType); - quit("!DrawingSurface: attempted to use surface after Release was called"); - return nullptr; +Bitmap *ScriptDrawingSurface::GetBitmapSurface() { + // TODO: consider creating weak_ptr here, and store one in the DrawingSurface! + if (roomBackgroundNumber >= 0) + return thisroom.BgFrames[roomBackgroundNumber].Graphic.get(); + else if (dynamicSpriteNumber >= 0) + return spriteset[dynamicSpriteNumber]; + else if (dynamicSurfaceNumber >= 0) + return dynamicallyCreatedSurfaces[dynamicSurfaceNumber]; + else if (linkedBitmapOnly != nullptr) + return linkedBitmapOnly; + else if (roomMaskType > kRoomAreaNone) + return thisroom.GetMask(roomMaskType); + quit("!DrawingSurface: attempted to use surface after Release was called"); + return nullptr; } -Bitmap *ScriptDrawingSurface::StartDrawing() -{ - //abufBackup = abuf; - return this->GetBitmapSurface(); +Bitmap *ScriptDrawingSurface::StartDrawing() { + //abufBackup = abuf; + return this->GetBitmapSurface(); } -void ScriptDrawingSurface::FinishedDrawingReadOnly() -{ - //abuf = abufBackup; +void ScriptDrawingSurface::FinishedDrawingReadOnly() { + //abuf = abufBackup; } -void ScriptDrawingSurface::FinishedDrawing() -{ - FinishedDrawingReadOnly(); - modified = 1; +void ScriptDrawingSurface::FinishedDrawing() { + FinishedDrawingReadOnly(); + modified = 1; } int ScriptDrawingSurface::Dispose(const char *address, bool force) { - // dispose the drawing surface - DrawingSurface_Release(this); - delete this; - return 1; + // dispose the drawing surface + DrawingSurface_Release(this); + delete this; + return 1; } const char *ScriptDrawingSurface::GetType() { - return "DrawingSurface"; + return "DrawingSurface"; } int ScriptDrawingSurface::Serialize(const char *address, char *buffer, int bufsize) { - StartSerialize(buffer); - SerializeInt(roomBackgroundNumber & 0xFFFF | (roomMaskType << 16)); - SerializeInt(dynamicSpriteNumber); - SerializeInt(dynamicSurfaceNumber); - SerializeInt(currentColour); - SerializeInt(currentColourScript); - SerializeInt(highResCoordinates); - SerializeInt(modified); - SerializeInt(hasAlphaChannel); - SerializeInt(isLinkedBitmapOnly ? 1 : 0); - return EndSerialize(); + StartSerialize(buffer); + SerializeInt(roomBackgroundNumber & 0xFFFF | (roomMaskType << 16)); + SerializeInt(dynamicSpriteNumber); + SerializeInt(dynamicSurfaceNumber); + SerializeInt(currentColour); + SerializeInt(currentColourScript); + SerializeInt(highResCoordinates); + SerializeInt(modified); + SerializeInt(hasAlphaChannel); + SerializeInt(isLinkedBitmapOnly ? 1 : 0); + return EndSerialize(); } void ScriptDrawingSurface::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int room_ds = UnserializeInt(); - roomBackgroundNumber = static_cast(room_ds & 0xFFFF); - roomMaskType = (RoomAreaMask)(room_ds >> 16); - dynamicSpriteNumber = UnserializeInt(); - dynamicSurfaceNumber = UnserializeInt(); - currentColour = UnserializeInt(); - currentColourScript = UnserializeInt(); - highResCoordinates = UnserializeInt(); - modified = UnserializeInt(); - hasAlphaChannel = UnserializeInt(); - isLinkedBitmapOnly = (UnserializeInt() != 0); - ccRegisterUnserializedObject(index, this, this); + StartUnserialize(serializedData, dataSize); + int room_ds = UnserializeInt(); + roomBackgroundNumber = static_cast(room_ds & 0xFFFF); + roomMaskType = (RoomAreaMask)(room_ds >> 16); + dynamicSpriteNumber = UnserializeInt(); + dynamicSurfaceNumber = UnserializeInt(); + currentColour = UnserializeInt(); + currentColourScript = UnserializeInt(); + highResCoordinates = UnserializeInt(); + modified = UnserializeInt(); + hasAlphaChannel = UnserializeInt(); + isLinkedBitmapOnly = (UnserializeInt() != 0); + ccRegisterUnserializedObject(index, this, this); } -ScriptDrawingSurface::ScriptDrawingSurface() -{ - roomBackgroundNumber = -1; - roomMaskType = kRoomAreaNone; - dynamicSpriteNumber = -1; - dynamicSurfaceNumber = -1; - isLinkedBitmapOnly = false; - linkedBitmapOnly = nullptr; - currentColour = play.raw_color; - currentColourScript = 0; - modified = 0; - hasAlphaChannel = 0; - highResCoordinates = 0; - // NOTE: Normally in contemporary games coordinates ratio will always be 1:1. - // But we still support legacy drawing, so have to set this up even for modern games, - // otherwise we'd have to complicate conversion conditions further. - if (game.IsLegacyHiRes() && game.IsDataInNativeCoordinates()) - { - highResCoordinates = 1; - } +ScriptDrawingSurface::ScriptDrawingSurface() { + roomBackgroundNumber = -1; + roomMaskType = kRoomAreaNone; + dynamicSpriteNumber = -1; + dynamicSurfaceNumber = -1; + isLinkedBitmapOnly = false; + linkedBitmapOnly = nullptr; + currentColour = play.raw_color; + currentColourScript = 0; + modified = 0; + hasAlphaChannel = 0; + highResCoordinates = 0; + // NOTE: Normally in contemporary games coordinates ratio will always be 1:1. + // But we still support legacy drawing, so have to set this up even for modern games, + // otherwise we'd have to complicate conversion conditions further. + if (game.IsLegacyHiRes() && game.IsDataInNativeCoordinates()) { + highResCoordinates = 1; + } } diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h index b3f4a190e429..5a60c3853f73 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h @@ -26,38 +26,42 @@ #include "ac/dynobj/cc_agsdynamicobject.h" #include "game/roomstruct.h" -namespace AGS { namespace Common { class Bitmap; }} +namespace AGS { +namespace Common { +class Bitmap; +} +} struct ScriptDrawingSurface final : AGSCCDynamicObject { - // These numbers and types are used to determine the source of this drawing surface; - // only one of them can be valid for this surface. - int roomBackgroundNumber; - RoomAreaMask roomMaskType; - int dynamicSpriteNumber; - int dynamicSurfaceNumber; - bool isLinkedBitmapOnly; - Common::Bitmap *linkedBitmapOnly; - int currentColour; - int currentColourScript; - int highResCoordinates; - int modified; - int hasAlphaChannel; - //Common::Bitmap* abufBackup; + // These numbers and types are used to determine the source of this drawing surface; + // only one of them can be valid for this surface. + int roomBackgroundNumber; + RoomAreaMask roomMaskType; + int dynamicSpriteNumber; + int dynamicSurfaceNumber; + bool isLinkedBitmapOnly; + Common::Bitmap *linkedBitmapOnly; + int currentColour; + int currentColourScript; + int highResCoordinates; + int modified; + int hasAlphaChannel; + //Common::Bitmap* abufBackup; - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; - Common::Bitmap* GetBitmapSurface(); - Common::Bitmap *StartDrawing(); - void PointToGameResolution(int *xcoord, int *ycoord); - void SizeToGameResolution(int *width, int *height); - void SizeToGameResolution(int *adjustValue); - void SizeToDataResolution(int *adjustValue); - void FinishedDrawing(); - void FinishedDrawingReadOnly(); + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + Common::Bitmap *GetBitmapSurface(); + Common::Bitmap *StartDrawing(); + void PointToGameResolution(int *xcoord, int *ycoord); + void SizeToGameResolution(int *width, int *height); + void SizeToGameResolution(int *adjustValue); + void SizeToDataResolution(int *adjustValue); + void FinishedDrawing(); + void FinishedDrawingReadOnly(); - ScriptDrawingSurface(); + ScriptDrawingSurface(); }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp index 0063e7ae87a2..817d77b6fe1e 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp @@ -24,35 +24,35 @@ #include "ac/dynamicsprite.h" int ScriptDynamicSprite::Dispose(const char *address, bool force) { - // always dispose - if ((slot) && (!force)) - free_dynamic_sprite(slot); + // always dispose + if ((slot) && (!force)) + free_dynamic_sprite(slot); - delete this; - return 1; + delete this; + return 1; } const char *ScriptDynamicSprite::GetType() { - return "DynamicSprite"; + return "DynamicSprite"; } int ScriptDynamicSprite::Serialize(const char *address, char *buffer, int bufsize) { - StartSerialize(buffer); - SerializeInt(slot); - return EndSerialize(); + StartSerialize(buffer); + SerializeInt(slot); + return EndSerialize(); } void ScriptDynamicSprite::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - slot = UnserializeInt(); - ccRegisterUnserializedObject(index, this, this); + StartUnserialize(serializedData, dataSize); + slot = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); } ScriptDynamicSprite::ScriptDynamicSprite(int theSlot) { - slot = theSlot; - ccRegisterManagedObject(this, this); + slot = theSlot; + ccRegisterManagedObject(this, this); } ScriptDynamicSprite::ScriptDynamicSprite() { - slot = 0; + slot = 0; } diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h index 0104d759b168..a5ed2909d793 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h @@ -26,15 +26,15 @@ #include "ac/dynobj/cc_agsdynamicobject.h" struct ScriptDynamicSprite final : AGSCCDynamicObject { - int slot; + int slot; - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; - ScriptDynamicSprite(int slot); - ScriptDynamicSprite(); + ScriptDynamicSprite(int slot); + ScriptDynamicSprite(); }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptfile.cpp b/engines/ags/engine/ac/dynobj/scriptfile.cpp index 9341c5d00442..122ab0a8cfb2 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.cpp +++ b/engines/ags/engine/ac/dynobj/scriptfile.cpp @@ -24,90 +24,79 @@ #include "ac/global_file.h" // CHECKME: actually NULLs here will be equal to kFile_Open & kFile_Read -const Common::FileOpenMode sc_File::fopenModes[] = - {Common::kFile_Open/*CHECKME, was undefined*/, Common::kFile_Open, Common::kFile_CreateAlways, Common::kFile_Create}; -const Common::FileWorkMode sc_File::fworkModes[] = - {Common::kFile_Read/*CHECKME, was undefined*/, Common::kFile_Read, Common::kFile_Write, Common::kFile_Write}; +const Common::FileOpenMode sc_File::fopenModes[] = +{Common::kFile_Open/*CHECKME, was undefined*/, Common::kFile_Open, Common::kFile_CreateAlways, Common::kFile_Create}; +const Common::FileWorkMode sc_File::fworkModes[] = +{Common::kFile_Read/*CHECKME, was undefined*/, Common::kFile_Read, Common::kFile_Write, Common::kFile_Write}; int sc_File::Dispose(const char *address, bool force) { - Close(); - delete this; - return 1; + Close(); + delete this; + return 1; } const char *sc_File::GetType() { - return "File"; + return "File"; } int sc_File::Serialize(const char *address, char *buffer, int bufsize) { - // we cannot serialize an open file, so it will get closed - return 0; + // we cannot serialize an open file, so it will get closed + return 0; } int sc_File::OpenFile(const char *filename, int mode) { - handle = FileOpen(filename, fopenModes[mode], fworkModes[mode]); - if (handle <= 0) - return 0; - return 1; + handle = FileOpen(filename, fopenModes[mode], fworkModes[mode]); + if (handle <= 0) + return 0; + return 1; } void sc_File::Close() { - if (handle > 0) { - FileClose(handle); - handle = 0; - } + if (handle > 0) { + FileClose(handle); + handle = 0; + } } sc_File::sc_File() { - handle = 0; + handle = 0; } -const char* sc_File::GetFieldPtr(const char *address, intptr_t offset) -{ - return address; +const char *sc_File::GetFieldPtr(const char *address, intptr_t offset) { + return address; } -void sc_File::Read(const char *address, intptr_t offset, void *dest, int size) -{ +void sc_File::Read(const char *address, intptr_t offset, void *dest, int size) { } -uint8_t sc_File::ReadInt8(const char *address, intptr_t offset) -{ - return 0; +uint8_t sc_File::ReadInt8(const char *address, intptr_t offset) { + return 0; } -int16_t sc_File::ReadInt16(const char *address, intptr_t offset) -{ - return 0; +int16_t sc_File::ReadInt16(const char *address, intptr_t offset) { + return 0; } -int32_t sc_File::ReadInt32(const char *address, intptr_t offset) -{ - return 0; +int32_t sc_File::ReadInt32(const char *address, intptr_t offset) { + return 0; } -float sc_File::ReadFloat(const char *address, intptr_t offset) -{ - return 0.0; +float sc_File::ReadFloat(const char *address, intptr_t offset) { + return 0.0; } -void sc_File::Write(const char *address, intptr_t offset, void *src, int size) -{ +void sc_File::Write(const char *address, intptr_t offset, void *src, int size) { } -void sc_File::WriteInt8(const char *address, intptr_t offset, uint8_t val) -{ +void sc_File::WriteInt8(const char *address, intptr_t offset, uint8_t val) { } -void sc_File::WriteInt16(const char *address, intptr_t offset, int16_t val) -{ +void sc_File::WriteInt16(const char *address, intptr_t offset, int16_t val) { } -void sc_File::WriteInt32(const char *address, intptr_t offset, int32_t val) -{ +void sc_File::WriteInt32(const char *address, intptr_t offset, int32_t val) { } -void sc_File::WriteFloat(const char *address, intptr_t offset, float val) -{ +void sc_File::WriteFloat(const char *address, intptr_t offset, float val) { } diff --git a/engines/ags/engine/ac/dynobj/scriptfile.h b/engines/ags/engine/ac/dynobj/scriptfile.h index 3a1571fb617f..4aa2e8ccf7d8 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.h +++ b/engines/ags/engine/ac/dynobj/scriptfile.h @@ -33,34 +33,34 @@ using namespace AGS; // FIXME later #define scFileAppend 3 struct sc_File final : ICCDynamicObject { - int32_t handle; + int32_t handle; - static const Common::FileOpenMode fopenModes[]; - static const Common::FileWorkMode fworkModes[]; + static const Common::FileOpenMode fopenModes[]; + static const Common::FileWorkMode fworkModes[]; - int Dispose(const char *address, bool force) override; + int Dispose(const char *address, bool force) override; - const char *GetType() override; + const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; + int Serialize(const char *address, char *buffer, int bufsize) override; - int OpenFile(const char *filename, int mode); - void Close(); + int OpenFile(const char *filename, int mode); + void Close(); - sc_File(); + sc_File(); - // Legacy support for reading and writing object values by their relative offset - const char* GetFieldPtr(const char *address, intptr_t offset) override; - void Read(const char *address, intptr_t offset, void *dest, int size) override; - uint8_t ReadInt8(const char *address, intptr_t offset) override; - int16_t ReadInt16(const char *address, intptr_t offset) override; - int32_t ReadInt32(const char *address, intptr_t offset) override; - float ReadFloat(const char *address, intptr_t offset) override; - void Write(const char *address, intptr_t offset, void *src, int size) override; - void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; - void WriteInt16(const char *address, intptr_t offset, int16_t val) override; - void WriteInt32(const char *address, intptr_t offset, int32_t val) override; - void WriteFloat(const char *address, intptr_t offset, float val) override; + // Legacy support for reading and writing object values by their relative offset + const char *GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptgui.h b/engines/ags/engine/ac/dynobj/scriptgui.h index 690a803ef278..3b6326078dd7 100644 --- a/engines/ags/engine/ac/dynobj/scriptgui.h +++ b/engines/ags/engine/ac/dynobj/scriptgui.h @@ -25,8 +25,8 @@ // 64 bit: This struct must be 8 byte long struct ScriptGUI { - int id; - int __padding; + int id; + int __padding; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scripthotspot.h b/engines/ags/engine/ac/dynobj/scripthotspot.h index dd93e1aa7052..6b692c3c7ce3 100644 --- a/engines/ags/engine/ac/dynobj/scripthotspot.h +++ b/engines/ags/engine/ac/dynobj/scripthotspot.h @@ -24,8 +24,8 @@ #define AGS_ENGINE_AC_DYNOBJ_SCRIPTHOTSPOT_H struct ScriptHotspot { - int id; - int reserved; + int id; + int reserved; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptinvitem.h b/engines/ags/engine/ac/dynobj/scriptinvitem.h index b6da8b17ab75..2c4b74607392 100644 --- a/engines/ags/engine/ac/dynobj/scriptinvitem.h +++ b/engines/ags/engine/ac/dynobj/scriptinvitem.h @@ -24,8 +24,8 @@ #define AGS_ENGINE_AC_DYNOBJ_SCRIPTINVITEM_H struct ScriptInvItem { - int id; - int reserved; + int id; + int reserved; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptmouse.h b/engines/ags/engine/ac/dynobj/scriptmouse.h index c2cc4f75d930..d1a8f566858e 100644 --- a/engines/ags/engine/ac/dynobj/scriptmouse.h +++ b/engines/ags/engine/ac/dynobj/scriptmouse.h @@ -25,7 +25,7 @@ // The text script's "mouse" struct struct ScriptMouse { - int x,y; + int x, y; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptobject.h b/engines/ags/engine/ac/dynobj/scriptobject.h index 154393ce1e19..b2c06e051cb5 100644 --- a/engines/ags/engine/ac/dynobj/scriptobject.h +++ b/engines/ags/engine/ac/dynobj/scriptobject.h @@ -27,9 +27,9 @@ // 64 bit: Struct size must be 8 byte for scripts to work struct ScriptObject { - int id; - //RoomObject *obj; - int __padding; + int id; + //RoomObject *obj; + int __padding; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp index f165a0bbcc08..ba8954b9482b 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp @@ -26,66 +26,61 @@ #include "ac/runtime_defines.h" #include "ac/screenoverlay.h" -int ScriptOverlay::Dispose(const char *address, bool force) -{ - // since the managed object is being deleted, remove the - // reference so it doesn't try and dispose something else - // with that handle later - int overlayIndex = find_overlay_of_type(overlayId); - if (overlayIndex >= 0) - { - screenover[overlayIndex].associatedOverlayHandle = 0; - } +int ScriptOverlay::Dispose(const char *address, bool force) { + // since the managed object is being deleted, remove the + // reference so it doesn't try and dispose something else + // with that handle later + int overlayIndex = find_overlay_of_type(overlayId); + if (overlayIndex >= 0) { + screenover[overlayIndex].associatedOverlayHandle = 0; + } - // if this is being removed voluntarily (ie. pointer out of - // scope) then remove the associateed overlay - // Otherwise, it's a Restre Game or something so don't - if ((!force) && (!isBackgroundSpeech) && (Overlay_GetValid(this))) - { - Remove(); - } + // if this is being removed voluntarily (ie. pointer out of + // scope) then remove the associateed overlay + // Otherwise, it's a Restre Game or something so don't + if ((!force) && (!isBackgroundSpeech) && (Overlay_GetValid(this))) { + Remove(); + } - delete this; - return 1; + delete this; + return 1; } const char *ScriptOverlay::GetType() { - return "Overlay"; + return "Overlay"; } int ScriptOverlay::Serialize(const char *address, char *buffer, int bufsize) { - StartSerialize(buffer); - SerializeInt(overlayId); - SerializeInt(borderWidth); - SerializeInt(borderHeight); - SerializeInt(isBackgroundSpeech); - return EndSerialize(); + StartSerialize(buffer); + SerializeInt(overlayId); + SerializeInt(borderWidth); + SerializeInt(borderHeight); + SerializeInt(isBackgroundSpeech); + return EndSerialize(); } void ScriptOverlay::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - overlayId = UnserializeInt(); - borderWidth = UnserializeInt(); - borderHeight = UnserializeInt(); - isBackgroundSpeech = UnserializeInt(); - ccRegisterUnserializedObject(index, this, this); + StartUnserialize(serializedData, dataSize); + overlayId = UnserializeInt(); + borderWidth = UnserializeInt(); + borderHeight = UnserializeInt(); + isBackgroundSpeech = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); } -void ScriptOverlay::Remove() -{ - int overlayIndex = find_overlay_of_type(overlayId); - if (overlayIndex < 0) - { - quit("ScriptOverlay::Remove: overlay is not there!"); - } - remove_screen_overlay_index(overlayIndex); - overlayId = -1; +void ScriptOverlay::Remove() { + int overlayIndex = find_overlay_of_type(overlayId); + if (overlayIndex < 0) { + quit("ScriptOverlay::Remove: overlay is not there!"); + } + remove_screen_overlay_index(overlayIndex); + overlayId = -1; } ScriptOverlay::ScriptOverlay() { - overlayId = -1; - borderWidth = 0; - borderHeight = 0; - isBackgroundSpeech = 0; + overlayId = -1; + borderWidth = 0; + borderHeight = 0; + isBackgroundSpeech = 0; } diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.h b/engines/ags/engine/ac/dynobj/scriptoverlay.h index 76785cd922af..b407f40191fb 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.h +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.h @@ -26,17 +26,17 @@ #include "ac/dynobj/cc_agsdynamicobject.h" struct ScriptOverlay final : AGSCCDynamicObject { - int overlayId; - int borderWidth; - int borderHeight; - int isBackgroundSpeech; + int overlayId; + int borderWidth; + int borderHeight; + int isBackgroundSpeech; - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; - void Remove(); - ScriptOverlay(); + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; + void Remove(); + ScriptOverlay(); }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptregion.h b/engines/ags/engine/ac/dynobj/scriptregion.h index 86deb65f0b1d..bc5244128224 100644 --- a/engines/ags/engine/ac/dynobj/scriptregion.h +++ b/engines/ags/engine/ac/dynobj/scriptregion.h @@ -24,8 +24,8 @@ #define AGS_ENGINE_AC_DYNOBJ_SCRIPTREGION_H struct ScriptRegion { - int id; - int reserved; + int id; + int reserved; }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptset.cpp b/engines/ags/engine/ac/dynobj/scriptset.cpp index a17a48c1ffae..db1e733f5085 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.cpp +++ b/engines/ags/engine/ac/dynobj/scriptset.cpp @@ -22,38 +22,33 @@ #include "ac/dynobj/scriptset.h" -int ScriptSetBase::Dispose(const char *address, bool force) -{ - Clear(); - delete this; - return 1; +int ScriptSetBase::Dispose(const char *address, bool force) { + Clear(); + delete this; + return 1; } -const char *ScriptSetBase::GetType() -{ - return "StringSet"; +const char *ScriptSetBase::GetType() { + return "StringSet"; } -int ScriptSetBase::Serialize(const char *address, char *buffer, int bufsize) -{ - size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; - if (bufsize < 0 || total_sz > (size_t)bufsize) - { - // buffer not big enough, ask for a bigger one - return -((int)total_sz); - } - StartSerialize(buffer); - SerializeInt(IsSorted()); - SerializeInt(IsCaseSensitive()); - SerializeContainer(); - return EndSerialize(); +int ScriptSetBase::Serialize(const char *address, char *buffer, int bufsize) { + size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; + if (bufsize < 0 || total_sz > (size_t)bufsize) { + // buffer not big enough, ask for a bigger one + return -((int)total_sz); + } + StartSerialize(buffer); + SerializeInt(IsSorted()); + SerializeInt(IsCaseSensitive()); + SerializeContainer(); + return EndSerialize(); } -void ScriptSetBase::Unserialize(int index, const char *serializedData, int dataSize) -{ - // NOTE: we expect sorted/case flags are read by external reader; - // this is awkward, but I did not find better design solution atm - StartUnserialize(serializedData, dataSize); - UnserializeContainer(serializedData); - ccRegisterUnserializedObject(index, this, this); +void ScriptSetBase::Unserialize(int index, const char *serializedData, int dataSize) { + // NOTE: we expect sorted/case flags are read by external reader; + // this is awkward, but I did not find better design solution atm + StartUnserialize(serializedData, dataSize); + UnserializeContainer(serializedData); + ccRegisterUnserializedObject(index, this, this); } diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index 3f71b19b8f03..165425b10479 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -44,107 +44,105 @@ using namespace AGS::Common; -class ScriptSetBase : public AGSCCDynamicObject -{ +class ScriptSetBase : public AGSCCDynamicObject { public: - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; - virtual bool IsCaseSensitive() const = 0; - virtual bool IsSorted() const = 0; + virtual bool IsCaseSensitive() const = 0; + virtual bool IsSorted() const = 0; - virtual bool Add(const char *item) = 0; - virtual void Clear() = 0; - virtual bool Contains(const char *item) const = 0; - virtual bool Remove(const char *item) = 0; - virtual int GetItemCount() const = 0; - virtual void GetItems(std::vector &buf) const = 0; + virtual bool Add(const char *item) = 0; + virtual void Clear() = 0; + virtual bool Contains(const char *item) const = 0; + virtual bool Remove(const char *item) = 0; + virtual int GetItemCount() const = 0; + virtual void GetItems(std::vector &buf) const = 0; private: - virtual size_t CalcSerializeSize() = 0; - virtual void SerializeContainer() = 0; - virtual void UnserializeContainer(const char *serializedData) = 0; + virtual size_t CalcSerializeSize() = 0; + virtual void SerializeContainer() = 0; + virtual void UnserializeContainer(const char *serializedData) = 0; }; template -class ScriptSetImpl final : public ScriptSetBase -{ +class ScriptSetImpl final : public ScriptSetBase { public: - typedef typename TSet::const_iterator ConstIterator; - - ScriptSetImpl() = default; - - bool IsCaseSensitive() const override { return is_casesensitive; } - bool IsSorted() const override { return is_sorted; } - - bool Add(const char *item) override - { - if (!item) return false; - size_t len = strlen(item); - return TryAddItem(item, len); - } - void Clear() override - { - for (auto it = _set.begin(); it != _set.end(); ++it) - DeleteItem(it); - _set.clear(); - } - bool Contains(const char *item) const override { return _set.count(String::Wrapper(item)) != 0; } - bool Remove(const char *item) override - { - auto it = _set.find(String::Wrapper(item)); - if (it == _set.end()) return false; - DeleteItem(it); - _set.erase(it); - return true; - } - int GetItemCount() const override { return _set.size(); } - void GetItems(std::vector &buf) const override - { - for (auto it = _set.begin(); it != _set.end(); ++it) - buf.push_back(it->GetCStr()); - } + typedef typename TSet::const_iterator ConstIterator; + + ScriptSetImpl() = default; + + bool IsCaseSensitive() const override { + return is_casesensitive; + } + bool IsSorted() const override { + return is_sorted; + } + + bool Add(const char *item) override { + if (!item) return false; + size_t len = strlen(item); + return TryAddItem(item, len); + } + void Clear() override { + for (auto it = _set.begin(); it != _set.end(); ++it) + DeleteItem(it); + _set.clear(); + } + bool Contains(const char *item) const override { + return _set.count(String::Wrapper(item)) != 0; + } + bool Remove(const char *item) override { + auto it = _set.find(String::Wrapper(item)); + if (it == _set.end()) return false; + DeleteItem(it); + _set.erase(it); + return true; + } + int GetItemCount() const override { + return _set.size(); + } + void GetItems(std::vector &buf) const override { + for (auto it = _set.begin(); it != _set.end(); ++it) + buf.push_back(it->GetCStr()); + } private: - bool TryAddItem(const char *item, size_t len) - { - return _set.insert(String(item, len)).second; - } - void DeleteItem(ConstIterator it) { /* do nothing */ } - - size_t CalcSerializeSize() override - { - size_t total_sz = sizeof(int32_t); - for (auto it = _set.begin(); it != _set.end(); ++it) - total_sz += sizeof(int32_t) + it->GetLength(); - return total_sz; - } - - void SerializeContainer() override - { - SerializeInt((int)_set.size()); - for (auto it = _set.begin(); it != _set.end(); ++it) - { - SerializeInt((int)it->GetLength()); - memcpy(&serbuffer[bytesSoFar], it->GetCStr(), it->GetLength()); - bytesSoFar += it->GetLength(); - } - } - - void UnserializeContainer(const char *serializedData) override - { - size_t item_count = (size_t)UnserializeInt(); - for (size_t i = 0; i < item_count; ++i) - { - size_t len = UnserializeInt(); - TryAddItem(&serializedData[bytesSoFar], len); - bytesSoFar += len; - } - } - - TSet _set; + bool TryAddItem(const char *item, size_t len) { + return _set.insert(String(item, len)).second; + } + void DeleteItem(ConstIterator it) { + /* do nothing */ + } + + size_t CalcSerializeSize() override { + size_t total_sz = sizeof(int32_t); + for (auto it = _set.begin(); it != _set.end(); ++it) + total_sz += sizeof(int32_t) + it->GetLength(); + return total_sz; + } + + void SerializeContainer() override { + SerializeInt((int)_set.size()); + for (auto it = _set.begin(); it != _set.end(); ++it) { + SerializeInt((int)it->GetLength()); + memcpy(&serbuffer[bytesSoFar], it->GetCStr(), it->GetLength()); + bytesSoFar += it->GetLength(); + } + } + + void UnserializeContainer(const char *serializedData) override { + size_t item_count = (size_t)UnserializeInt(); + for (size_t i = 0; i < item_count; ++i) { + size_t len = UnserializeInt(); + TryAddItem(&serializedData[bytesSoFar], len); + bytesSoFar += len; + } + } + + TSet _set; }; typedef ScriptSetImpl< std::set, true, true > ScriptSet; diff --git a/engines/ags/engine/ac/dynobj/scriptstring.cpp b/engines/ags/engine/ac/dynobj/scriptstring.cpp index be95335bd8f8..637de80e35c8 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.cpp +++ b/engines/ags/engine/ac/dynobj/scriptstring.cpp @@ -26,49 +26,49 @@ #include DynObjectRef ScriptString::CreateString(const char *fromText) { - return CreateNewScriptStringObj(fromText); + return CreateNewScriptStringObj(fromText); } int ScriptString::Dispose(const char *address, bool force) { - // always dispose - if (text) { - free(text); - text = nullptr; - } - delete this; - return 1; + // always dispose + if (text) { + free(text); + text = nullptr; + } + delete this; + return 1; } const char *ScriptString::GetType() { - return "String"; + return "String"; } int ScriptString::Serialize(const char *address, char *buffer, int bufsize) { - StartSerialize(buffer); - - auto toSerialize = text ? text : ""; - - auto len = strlen(toSerialize); - SerializeInt(len); - strcpy(&serbuffer[bytesSoFar], toSerialize); - bytesSoFar += len + 1; - - return EndSerialize(); + StartSerialize(buffer); + + auto toSerialize = text ? text : ""; + + auto len = strlen(toSerialize); + SerializeInt(len); + strcpy(&serbuffer[bytesSoFar], toSerialize); + bytesSoFar += len + 1; + + return EndSerialize(); } void ScriptString::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - int textsize = UnserializeInt(); - text = (char*)malloc(textsize + 1); - strcpy(text, &serializedData[bytesSoFar]); - ccRegisterUnserializedObject(index, text, this); + StartUnserialize(serializedData, dataSize); + int textsize = UnserializeInt(); + text = (char *)malloc(textsize + 1); + strcpy(text, &serializedData[bytesSoFar]); + ccRegisterUnserializedObject(index, text, this); } ScriptString::ScriptString() { - text = nullptr; + text = nullptr; } ScriptString::ScriptString(const char *fromText) { - text = (char*)malloc(strlen(fromText) + 1); - strcpy(text, fromText); + text = (char *)malloc(strlen(fromText) + 1); + strcpy(text, fromText); } diff --git a/engines/ags/engine/ac/dynobj/scriptstring.h b/engines/ags/engine/ac/dynobj/scriptstring.h index b59595b0943d..289b1e6d5c87 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.h +++ b/engines/ags/engine/ac/dynobj/scriptstring.h @@ -26,17 +26,17 @@ #include "ac/dynobj/cc_agsdynamicobject.h" struct ScriptString final : AGSCCDynamicObject, ICCStringClass { - char *text; + char *text; - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; - DynObjectRef CreateString(const char *fromText) override; + DynObjectRef CreateString(const char *fromText) override; - ScriptString(); - ScriptString(const char *fromText); + ScriptString(); + ScriptString(const char *fromText); }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptsystem.h b/engines/ags/engine/ac/dynobj/scriptsystem.h index 4b5d19a8fdb0..4d40079dd88b 100644 --- a/engines/ags/engine/ac/dynobj/scriptsystem.h +++ b/engines/ags/engine/ac/dynobj/scriptsystem.h @@ -25,14 +25,14 @@ // The text script's "system" struct struct ScriptSystem { - int width,height; - int coldepth; - int os; - int windowed; - int vsync; - int viewport_width, viewport_height; - char aci_version[10]; // FIXME this when possible, version format is different now - int reserved[5]; // so that future scripts don't overwrite data + int width, height; + int coldepth; + int os; + int windowed; + int vsync; + int viewport_width, viewport_height; + char aci_version[10]; // FIXME this when possible, version format is different now + int reserved[5]; // so that future scripts don't overwrite data }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp index b3cdb00bcf63..b519bb17f850 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp @@ -24,129 +24,108 @@ #include "scriptuserobject.h" // return the type name of the object -const char *ScriptUserObject::GetType() -{ - return "UserObject"; +const char *ScriptUserObject::GetType() { + return "UserObject"; } ScriptUserObject::ScriptUserObject() - : _size(0) - , _data(nullptr) -{ + : _size(0) + , _data(nullptr) { } -ScriptUserObject::~ScriptUserObject() -{ - delete [] _data; +ScriptUserObject::~ScriptUserObject() { + delete [] _data; } -/* static */ ScriptUserObject *ScriptUserObject::CreateManaged(size_t size) -{ - ScriptUserObject *suo = new ScriptUserObject(); - suo->Create(nullptr, size); - ccRegisterManagedObject(suo, suo); - return suo; +/* static */ ScriptUserObject *ScriptUserObject::CreateManaged(size_t size) { + ScriptUserObject *suo = new ScriptUserObject(); + suo->Create(nullptr, size); + ccRegisterManagedObject(suo, suo); + return suo; } -void ScriptUserObject::Create(const char *data, size_t size) -{ - delete [] _data; - _data = nullptr; +void ScriptUserObject::Create(const char *data, size_t size) { + delete [] _data; + _data = nullptr; - _size = size; - if (_size > 0) - { - _data = new char[size]; - if (data) - memcpy(_data, data, _size); - else - memset(_data, 0, _size); - } + _size = size; + if (_size > 0) { + _data = new char[size]; + if (data) + memcpy(_data, data, _size); + else + memset(_data, 0, _size); + } } -int ScriptUserObject::Dispose(const char *address, bool force) -{ - delete this; - return 1; +int ScriptUserObject::Dispose(const char *address, bool force) { + delete this; + return 1; } -int ScriptUserObject::Serialize(const char *address, char *buffer, int bufsize) -{ - if (_size > bufsize) - // buffer not big enough, ask for a bigger one - return -_size; +int ScriptUserObject::Serialize(const char *address, char *buffer, int bufsize) { + if (_size > bufsize) + // buffer not big enough, ask for a bigger one + return -_size; - memcpy(buffer, _data, _size); - return _size; + memcpy(buffer, _data, _size); + return _size; } -void ScriptUserObject::Unserialize(int index, const char *serializedData, int dataSize) -{ - Create(serializedData, dataSize); - ccRegisterUnserializedObject(index, this, this); +void ScriptUserObject::Unserialize(int index, const char *serializedData, int dataSize) { + Create(serializedData, dataSize); + ccRegisterUnserializedObject(index, this, this); } -const char* ScriptUserObject::GetFieldPtr(const char *address, intptr_t offset) -{ - return _data + offset; +const char *ScriptUserObject::GetFieldPtr(const char *address, intptr_t offset) { + return _data + offset; } -void ScriptUserObject::Read(const char *address, intptr_t offset, void *dest, int size) -{ - memcpy(dest, _data + offset, size); +void ScriptUserObject::Read(const char *address, intptr_t offset, void *dest, int size) { + memcpy(dest, _data + offset, size); } -uint8_t ScriptUserObject::ReadInt8(const char *address, intptr_t offset) -{ - return *(uint8_t*)(_data + offset); +uint8_t ScriptUserObject::ReadInt8(const char *address, intptr_t offset) { + return *(uint8_t *)(_data + offset); } -int16_t ScriptUserObject::ReadInt16(const char *address, intptr_t offset) -{ - return *(int16_t*)(_data + offset); +int16_t ScriptUserObject::ReadInt16(const char *address, intptr_t offset) { + return *(int16_t *)(_data + offset); } -int32_t ScriptUserObject::ReadInt32(const char *address, intptr_t offset) -{ - return *(int32_t*)(_data + offset); +int32_t ScriptUserObject::ReadInt32(const char *address, intptr_t offset) { + return *(int32_t *)(_data + offset); } -float ScriptUserObject::ReadFloat(const char *address, intptr_t offset) -{ - return *(float*)(_data + offset); +float ScriptUserObject::ReadFloat(const char *address, intptr_t offset) { + return *(float *)(_data + offset); } -void ScriptUserObject::Write(const char *address, intptr_t offset, void *src, int size) -{ - memcpy((void*)(_data + offset), src, size); +void ScriptUserObject::Write(const char *address, intptr_t offset, void *src, int size) { + memcpy((void *)(_data + offset), src, size); } -void ScriptUserObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) -{ - *(uint8_t*)(_data + offset) = val; +void ScriptUserObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) { + *(uint8_t *)(_data + offset) = val; } -void ScriptUserObject::WriteInt16(const char *address, intptr_t offset, int16_t val) -{ - *(int16_t*)(_data + offset) = val; +void ScriptUserObject::WriteInt16(const char *address, intptr_t offset, int16_t val) { + *(int16_t *)(_data + offset) = val; } -void ScriptUserObject::WriteInt32(const char *address, intptr_t offset, int32_t val) -{ - *(int32_t*)(_data + offset) = val; +void ScriptUserObject::WriteInt32(const char *address, intptr_t offset, int32_t val) { + *(int32_t *)(_data + offset) = val; } -void ScriptUserObject::WriteFloat(const char *address, intptr_t offset, float val) -{ - *(float*)(_data + offset) = val; +void ScriptUserObject::WriteFloat(const char *address, intptr_t offset, float val) { + *(float *)(_data + offset) = val; } // Allocates managed struct containing two ints: X and Y -ScriptUserObject *ScriptStructHelpers::CreatePoint(int x, int y) -{ - ScriptUserObject *suo = ScriptUserObject::CreateManaged(sizeof(int32_t) * 2); - suo->WriteInt32((const char*)suo, 0, x); - suo->WriteInt32((const char*)suo, sizeof(int32_t), y); - return suo; +ScriptUserObject *ScriptStructHelpers::CreatePoint(int x, int y) { + ScriptUserObject *suo = ScriptUserObject::CreateManaged(sizeof(int32_t) * 2); + suo->WriteInt32((const char *)suo, 0, x); + suo->WriteInt32((const char *)suo, sizeof(int32_t), y); + return suo; } diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h index f89ac7fe762b..0e3f0f6b45d0 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.h +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -31,56 +31,54 @@ #include "ac/dynobj/cc_agsdynamicobject.h" -struct ScriptUserObject final : ICCDynamicObject -{ +struct ScriptUserObject final : ICCDynamicObject { public: - ScriptUserObject(); - + ScriptUserObject(); + protected: - virtual ~ScriptUserObject(); + virtual ~ScriptUserObject(); public: - static ScriptUserObject *CreateManaged(size_t size); - void Create(const char *data, size_t size); + static ScriptUserObject *CreateManaged(size_t size); + void Create(const char *data, size_t size); - // return the type name of the object - const char *GetType() override; - int Dispose(const char *address, bool force) override; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - int Serialize(const char *address, char *buffer, int bufsize) override; - virtual void Unserialize(int index, const char *serializedData, int dataSize); + // return the type name of the object + const char *GetType() override; + int Dispose(const char *address, bool force) override; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + int Serialize(const char *address, char *buffer, int bufsize) override; + virtual void Unserialize(int index, const char *serializedData, int dataSize); - // Support for reading and writing object values by their relative offset - const char* GetFieldPtr(const char *address, intptr_t offset) override; - void Read(const char *address, intptr_t offset, void *dest, int size) override; - uint8_t ReadInt8(const char *address, intptr_t offset) override; - int16_t ReadInt16(const char *address, intptr_t offset) override; - int32_t ReadInt32(const char *address, intptr_t offset) override; - float ReadFloat(const char *address, intptr_t offset) override; - void Write(const char *address, intptr_t offset, void *src, int size) override; - void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; - void WriteInt16(const char *address, intptr_t offset, int16_t val) override; - void WriteInt32(const char *address, intptr_t offset, int32_t val) override; - void WriteFloat(const char *address, intptr_t offset, float val) override; + // Support for reading and writing object values by their relative offset + const char *GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; private: - // NOTE: we use signed int for Size at the moment, because the managed - // object interface's Serialize() function requires the object to return - // negative value of size in case the provided buffer was not large - // enough. Since this interface is also a part of Plugin API, we would - // need more significant change to program before we could use different - // approach. - int32_t _size; - char *_data; + // NOTE: we use signed int for Size at the moment, because the managed + // object interface's Serialize() function requires the object to return + // negative value of size in case the provided buffer was not large + // enough. Since this interface is also a part of Plugin API, we would + // need more significant change to program before we could use different + // approach. + int32_t _size; + char *_data; }; // Helper functions for setting up custom managed structs based on ScriptUserObject. -namespace ScriptStructHelpers -{ - // Creates a managed Point object, represented as a pair of X and Y coordinates. - ScriptUserObject *CreatePoint(int x, int y); +namespace ScriptStructHelpers { +// Creates a managed Point object, represented as a pair of X and Y coordinates. +ScriptUserObject *CreatePoint(int x, int y); }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp index 955af85f631e..d3f6ccd31746 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp @@ -23,39 +23,39 @@ #include "ac/dynobj/scriptviewframe.h" int ScriptViewFrame::Dispose(const char *address, bool force) { - // always dispose a ViewFrame - delete this; - return 1; + // always dispose a ViewFrame + delete this; + return 1; } const char *ScriptViewFrame::GetType() { - return "ViewFrame"; + return "ViewFrame"; } int ScriptViewFrame::Serialize(const char *address, char *buffer, int bufsize) { - StartSerialize(buffer); - SerializeInt(view); - SerializeInt(loop); - SerializeInt(frame); - return EndSerialize(); + StartSerialize(buffer); + SerializeInt(view); + SerializeInt(loop); + SerializeInt(frame); + return EndSerialize(); } void ScriptViewFrame::Unserialize(int index, const char *serializedData, int dataSize) { - StartUnserialize(serializedData, dataSize); - view = UnserializeInt(); - loop = UnserializeInt(); - frame = UnserializeInt(); - ccRegisterUnserializedObject(index, this, this); + StartUnserialize(serializedData, dataSize); + view = UnserializeInt(); + loop = UnserializeInt(); + frame = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); } ScriptViewFrame::ScriptViewFrame(int p_view, int p_loop, int p_frame) { - view = p_view; - loop = p_loop; - frame = p_frame; + view = p_view; + loop = p_loop; + frame = p_frame; } ScriptViewFrame::ScriptViewFrame() { - view = -1; - loop = -1; - frame = -1; + view = -1; + loop = -1; + frame = -1; } diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.h b/engines/ags/engine/ac/dynobj/scriptviewframe.h index b625328b0223..7b0dc386196e 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.h +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.h @@ -26,15 +26,15 @@ #include "ac/dynobj/cc_agsdynamicobject.h" struct ScriptViewFrame final : AGSCCDynamicObject { - int view, loop, frame; + int view, loop, frame; - int Dispose(const char *address, bool force) override; - const char *GetType() override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + int Dispose(const char *address, bool force) override; + const char *GetType() override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; - ScriptViewFrame(int p_view, int p_loop, int p_frame); - ScriptViewFrame(); + ScriptViewFrame(int p_view, int p_loop, int p_frame); + ScriptViewFrame(); }; #endif diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp index f2563a566299..54bb03e849b4 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -28,45 +28,39 @@ using namespace AGS::Common; ScriptViewport::ScriptViewport(int id) : _id(id) {} -const char *ScriptViewport::GetType() -{ - return "Viewport2"; +const char *ScriptViewport::GetType() { + return "Viewport2"; } -int ScriptViewport::Dispose(const char *address, bool force) -{ - // Note that ScriptViewport is a reference to actual Viewport object, - // and this deletes the reference, while viewport may remain in GameState. - delete this; - return 1; +int ScriptViewport::Dispose(const char *address, bool force) { + // Note that ScriptViewport is a reference to actual Viewport object, + // and this deletes the reference, while viewport may remain in GameState. + delete this; + return 1; } -int ScriptViewport::Serialize(const char *address, char *buffer, int bufsize) -{ - StartSerialize(buffer); - SerializeInt(_id); - return EndSerialize(); +int ScriptViewport::Serialize(const char *address, char *buffer, int bufsize) { + StartSerialize(buffer); + SerializeInt(_id); + return EndSerialize(); } -void ScriptViewport::Unserialize(int index, const char *serializedData, int dataSize) -{ - StartUnserialize(serializedData, dataSize); - _id = UnserializeInt(); - ccRegisterUnserializedObject(index, this, this); +void ScriptViewport::Unserialize(int index, const char *serializedData, int dataSize) { + StartUnserialize(serializedData, dataSize); + _id = UnserializeInt(); + ccRegisterUnserializedObject(index, this, this); } -ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int dataSize) -{ - // The way it works now, we must not create a new script object, - // but acquire one from the GameState, which keeps the first reference. - // This is essential because GameState should be able to invalidate any - // script references when Viewport gets removed. - const int id = BBOp::Int32FromLE(*((int*)serializedData)); - if (id >= 0) - { - auto scview = play.RegisterRoomViewport(id, handle); - if (scview) - return scview; - } - return new ScriptViewport(-1); // make invalid reference +ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int dataSize) { + // The way it works now, we must not create a new script object, + // but acquire one from the GameState, which keeps the first reference. + // This is essential because GameState should be able to invalidate any + // script references when Viewport gets removed. + const int id = BBOp::Int32FromLE(*((int *)serializedData)); + if (id >= 0) { + auto scview = play.RegisterRoomViewport(id, handle); + if (scview) + return scview; + } + return new ScriptViewport(-1); // make invalid reference } diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.h b/engines/ags/engine/ac/dynobj/scriptviewport.h index 26ca3cde8c3c..a199e6ff388d 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.h +++ b/engines/ags/engine/ac/dynobj/scriptviewport.h @@ -26,23 +26,28 @@ #include "ac/dynobj/cc_agsdynamicobject.h" // ScriptViewport keeps a reference to actual room Viewport in script. -struct ScriptViewport final : AGSCCDynamicObject -{ +struct ScriptViewport final : AGSCCDynamicObject { public: - ScriptViewport(int id); - // Get viewport index; negative means the viewport was deleted - int GetID() const { return _id; } - void SetID(int id) { _id = id; } - // Reset viewport index to indicate that this reference is no longer valid - void Invalidate() { _id = -1; } + ScriptViewport(int id); + // Get viewport index; negative means the viewport was deleted + int GetID() const { + return _id; + } + void SetID(int id) { + _id = id; + } + // Reset viewport index to indicate that this reference is no longer valid + void Invalidate() { + _id = -1; + } - const char *GetType() override; - int Dispose(const char *address, bool force) override; - int Serialize(const char *address, char *buffer, int bufsize) override; - void Unserialize(int index, const char *serializedData, int dataSize) override; + const char *GetType() override; + int Dispose(const char *address, bool force) override; + int Serialize(const char *address, char *buffer, int bufsize) override; + void Unserialize(int index, const char *serializedData, int dataSize) override; private: - int _id = -1; // index of viewport in the game state array + int _id = -1; // index of viewport in the game state array }; // Unserialize viewport from the memory stream diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp index c2960351c434..e977adde5495 100644 --- a/engines/ags/engine/ac/event.cpp +++ b/engines/ags/engine/ac/event.cpp @@ -47,7 +47,7 @@ using namespace AGS::Engine; extern GameSetupStruct game; extern RoomStruct thisroom; -extern RoomStatus*croom; +extern RoomStatus *croom; extern int displayed_room; extern GameState play; extern color palette[256]; @@ -55,380 +55,349 @@ extern IGraphicsDriver *gfxDriver; extern AGSPlatformDriver *platform; extern color old_palette[256]; -int in_enters_screen=0,done_es_error = 0; +int in_enters_screen = 0, done_es_error = 0; int in_leaves_screen = -1; -EventHappened event[MAXEVENTS+1]; -int numevents=0; +EventHappened event[MAXEVENTS + 1]; +int numevents = 0; -const char*evblockbasename; +const char *evblockbasename; int evblocknum; -int inside_processevent=0; +int inside_processevent = 0; int eventClaimed = EVENT_NONE; -const char*tsnames[4]={nullptr, REP_EXEC_NAME, "on_key_press","on_mouse_click"}; +const char *tsnames[4] = {nullptr, REP_EXEC_NAME, "on_key_press", "on_mouse_click"}; int run_claimable_event(const char *tsname, bool includeRoom, int numParams, const RuntimeScriptValue *params, bool *eventWasClaimed) { - *eventWasClaimed = true; - // Run the room script function, and if it is not claimed, - // then run the main one - // We need to remember the eventClaimed variable's state, in case - // this is a nested event - int eventClaimedOldValue = eventClaimed; - eventClaimed = EVENT_INPROGRESS; - int toret; - - if (includeRoom && roominst) { - toret = RunScriptFunctionIfExists(roominst, tsname, numParams, params); - - if (eventClaimed == EVENT_CLAIMED) { - eventClaimed = eventClaimedOldValue; - return toret; - } - } - - // run script modules - for (int kk = 0; kk < numScriptModules; kk++) { - toret = RunScriptFunctionIfExists(moduleInst[kk], tsname, numParams, params); - - if (eventClaimed == EVENT_CLAIMED) { - eventClaimed = eventClaimedOldValue; - return toret; - } - } - - eventClaimed = eventClaimedOldValue; - *eventWasClaimed = false; - return 0; + *eventWasClaimed = true; + // Run the room script function, and if it is not claimed, + // then run the main one + // We need to remember the eventClaimed variable's state, in case + // this is a nested event + int eventClaimedOldValue = eventClaimed; + eventClaimed = EVENT_INPROGRESS; + int toret; + + if (includeRoom && roominst) { + toret = RunScriptFunctionIfExists(roominst, tsname, numParams, params); + + if (eventClaimed == EVENT_CLAIMED) { + eventClaimed = eventClaimedOldValue; + return toret; + } + } + + // run script modules + for (int kk = 0; kk < numScriptModules; kk++) { + toret = RunScriptFunctionIfExists(moduleInst[kk], tsname, numParams, params); + + if (eventClaimed == EVENT_CLAIMED) { + eventClaimed = eventClaimedOldValue; + return toret; + } + } + + eventClaimed = eventClaimedOldValue; + *eventWasClaimed = false; + return 0; } // runs the global script on_event function -void run_on_event (int evtype, RuntimeScriptValue &wparam) -{ - QueueScriptFunction(kScInstGame, "on_event", 2, RuntimeScriptValue().SetInt32(evtype), wparam); +void run_on_event(int evtype, RuntimeScriptValue &wparam) { + QueueScriptFunction(kScInstGame, "on_event", 2, RuntimeScriptValue().SetInt32(evtype), wparam); } void run_room_event(int id) { - evblockbasename="room"; - - if (thisroom.EventHandlers != nullptr) - { - run_interaction_script(thisroom.EventHandlers.get(), id); - } - else - { - run_interaction_event (&croom->intrRoom, id); - } + evblockbasename = "room"; + + if (thisroom.EventHandlers != nullptr) { + run_interaction_script(thisroom.EventHandlers.get(), id); + } else { + run_interaction_event(&croom->intrRoom, id); + } } void run_event_block_inv(int invNum, int event) { - evblockbasename="inventory%d"; - if (loaded_game_file_version > kGameVersion_272) - { - run_interaction_script(game.invScripts[invNum].get(), event); - } - else - { - run_interaction_event(game.intrInv[invNum].get(), event); - } + evblockbasename = "inventory%d"; + if (loaded_game_file_version > kGameVersion_272) { + run_interaction_script(game.invScripts[invNum].get(), event); + } else { + run_interaction_event(game.intrInv[invNum].get(), event); + } } // event list functions -void setevent(int evtyp,int ev1,int ev2,int ev3) { - event[numevents].type=evtyp; - event[numevents].data1=ev1; - event[numevents].data2=ev2; - event[numevents].data3=ev3; - event[numevents].player=game.playercharacter; - numevents++; - if (numevents>=MAXEVENTS) quit("too many events posted"); +void setevent(int evtyp, int ev1, int ev2, int ev3) { + event[numevents].type = evtyp; + event[numevents].data1 = ev1; + event[numevents].data2 = ev2; + event[numevents].data3 = ev3; + event[numevents].player = game.playercharacter; + numevents++; + if (numevents >= MAXEVENTS) quit("too many events posted"); } // TODO: this is kind of a hack, which forces event to be processed even if // it was fired from insides of other event processing. // The proper solution would be to do the event processing overhaul in AGS. -void force_event(int evtyp,int ev1,int ev2,int ev3) -{ - if (inside_processevent) - runevent_now(evtyp, ev1, ev2, ev3); - else - setevent(evtyp, ev1, ev2, ev3); +void force_event(int evtyp, int ev1, int ev2, int ev3) { + if (inside_processevent) + runevent_now(evtyp, ev1, ev2, ev3); + else + setevent(evtyp, ev1, ev2, ev3); } -void process_event(EventHappened*evp) { - RuntimeScriptValue rval_null; - if (evp->type==EV_TEXTSCRIPT) { - ccError=0; - if (evp->data2 > -1000) { - QueueScriptFunction(kScInstGame, tsnames[evp->data1], 1, RuntimeScriptValue().SetInt32(evp->data2)); - } - else { - QueueScriptFunction(kScInstGame, tsnames[evp->data1]); - } - } - else if (evp->type==EV_NEWROOM) { - NewRoom(evp->data1); - } - else if (evp->type==EV_RUNEVBLOCK) { - Interaction*evpt=nullptr; - PInteractionScripts scriptPtr = nullptr; - const char *oldbasename = evblockbasename; - int oldblocknum = evblocknum; - - if (evp->data1==EVB_HOTSPOT) { - - if (thisroom.Hotspots[evp->data2].EventHandlers != nullptr) - scriptPtr = thisroom.Hotspots[evp->data2].EventHandlers; - else - evpt=&croom->intrHotspot[evp->data2]; - - evblockbasename="hotspot%d"; - evblocknum=evp->data2; - //Debug::Printf("Running hotspot interaction for hotspot %d, event %d", evp->data2, evp->data3); - } - else if (evp->data1==EVB_ROOM) { - - if (thisroom.EventHandlers != nullptr) - scriptPtr = thisroom.EventHandlers; - else - evpt=&croom->intrRoom; - - evblockbasename="room"; - if (evp->data3 == 5) { - in_enters_screen ++; - run_on_event (GE_ENTER_ROOM, RuntimeScriptValue().SetInt32(displayed_room)); - - } - //Debug::Printf("Running room interaction, event %d", evp->data3); - } - - if (scriptPtr != nullptr) - { - run_interaction_script(scriptPtr.get(), evp->data3); - } - else if (evpt != nullptr) - { - run_interaction_event(evpt,evp->data3); - } - else - quit("process_event: RunEvBlock: unknown evb type"); - - evblockbasename = oldbasename; - evblocknum = oldblocknum; - - if ((evp->data3 == 5) && (evp->data1 == EVB_ROOM)) - in_enters_screen --; - } - else if (evp->type==EV_FADEIN) { - // if they change the transition type before the fadein, make - // sure the screen doesn't freeze up - play.screen_is_faded_out = 0; - - // determine the transition style - int theTransition = play.fade_effect; - - if (play.next_screen_transition >= 0) { - // a one-off transition was selected, so use it - theTransition = play.next_screen_transition; - play.next_screen_transition = -1; - } - - if (pl_run_plugin_hooks(AGSE_TRANSITIONIN, 0)) - return; - - if (play.fast_forward) - return; - - const bool ignore_transition = (play.screen_tint > 0); - if (((theTransition == FADE_CROSSFADE) || (theTransition == FADE_DISSOLVE)) && - (saved_viewport_bitmap == nullptr) && !ignore_transition) - { - // transition type was not crossfade/dissolve when the screen faded out, - // but it is now when the screen fades in (Eg. a save game was restored - // with a different setting). Therefore just fade normally. - my_fade_out(5); - theTransition = FADE_NORMAL; - } +void process_event(EventHappened *evp) { + RuntimeScriptValue rval_null; + if (evp->type == EV_TEXTSCRIPT) { + ccError = 0; + if (evp->data2 > -1000) { + QueueScriptFunction(kScInstGame, tsnames[evp->data1], 1, RuntimeScriptValue().SetInt32(evp->data2)); + } else { + QueueScriptFunction(kScInstGame, tsnames[evp->data1]); + } + } else if (evp->type == EV_NEWROOM) { + NewRoom(evp->data1); + } else if (evp->type == EV_RUNEVBLOCK) { + Interaction *evpt = nullptr; + PInteractionScripts scriptPtr = nullptr; + const char *oldbasename = evblockbasename; + int oldblocknum = evblocknum; + + if (evp->data1 == EVB_HOTSPOT) { + + if (thisroom.Hotspots[evp->data2].EventHandlers != nullptr) + scriptPtr = thisroom.Hotspots[evp->data2].EventHandlers; + else + evpt = &croom->intrHotspot[evp->data2]; + + evblockbasename = "hotspot%d"; + evblocknum = evp->data2; + //Debug::Printf("Running hotspot interaction for hotspot %d, event %d", evp->data2, evp->data3); + } else if (evp->data1 == EVB_ROOM) { + + if (thisroom.EventHandlers != nullptr) + scriptPtr = thisroom.EventHandlers; + else + evpt = &croom->intrRoom; + + evblockbasename = "room"; + if (evp->data3 == 5) { + in_enters_screen ++; + run_on_event(GE_ENTER_ROOM, RuntimeScriptValue().SetInt32(displayed_room)); + + } + //Debug::Printf("Running room interaction, event %d", evp->data3); + } + + if (scriptPtr != nullptr) { + run_interaction_script(scriptPtr.get(), evp->data3); + } else if (evpt != nullptr) { + run_interaction_event(evpt, evp->data3); + } else + quit("process_event: RunEvBlock: unknown evb type"); + + evblockbasename = oldbasename; + evblocknum = oldblocknum; + + if ((evp->data3 == 5) && (evp->data1 == EVB_ROOM)) + in_enters_screen --; + } else if (evp->type == EV_FADEIN) { + // if they change the transition type before the fadein, make + // sure the screen doesn't freeze up + play.screen_is_faded_out = 0; + + // determine the transition style + int theTransition = play.fade_effect; + + if (play.next_screen_transition >= 0) { + // a one-off transition was selected, so use it + theTransition = play.next_screen_transition; + play.next_screen_transition = -1; + } + + if (pl_run_plugin_hooks(AGSE_TRANSITIONIN, 0)) + return; + + if (play.fast_forward) + return; + + const bool ignore_transition = (play.screen_tint > 0); + if (((theTransition == FADE_CROSSFADE) || (theTransition == FADE_DISSOLVE)) && + (saved_viewport_bitmap == nullptr) && !ignore_transition) { + // transition type was not crossfade/dissolve when the screen faded out, + // but it is now when the screen fades in (Eg. a save game was restored + // with a different setting). Therefore just fade normally. + my_fade_out(5); + theTransition = FADE_NORMAL; + } // TODO: use normal coordinates instead of "native_size" and multiply_up_*? - const Size &data_res = game.GetDataRes(); - const Rect &viewport = play.GetMainViewport(); - - if ((theTransition == FADE_INSTANT) || ignore_transition) - set_palette_range(palette, 0, 255, 0); - else if (theTransition == FADE_NORMAL) - { - my_fade_in(palette,5); - } - else if (theTransition == FADE_BOXOUT) - { - if (!gfxDriver->UsesMemoryBackBuffer()) - { - gfxDriver->BoxOutEffect(false, get_fixed_pixel_size(16), 1000 / GetGameSpeed()); - } - else - { - // First of all we render the game once again and save backbuffer from further editing. - // We put temporary bitmap as a new backbuffer for the transition period, and - // will be drawing saved image of the game over to that backbuffer, simulating "box-out". - set_palette_range(palette, 0, 255, 0); - construct_game_scene(true); - construct_game_screen_overlay(false); - gfxDriver->RenderToBackBuffer(); - Bitmap *saved_backbuf = gfxDriver->GetMemoryBackBuffer(); - Bitmap *temp_scr = new Bitmap(saved_backbuf->GetWidth(), saved_backbuf->GetHeight(), saved_backbuf->GetColorDepth()); - gfxDriver->SetMemoryBackBuffer(temp_scr); - temp_scr->Clear(); - render_to_screen(); - - const int speed = get_fixed_pixel_size(16); - const int yspeed = viewport.GetHeight() / (viewport.GetWidth() / speed); - int boxwid = speed, boxhit = yspeed; - while (boxwid < temp_scr->GetWidth()) - { - boxwid += speed; - boxhit += yspeed; - boxwid = Math::Clamp(boxwid, 0, viewport.GetWidth()); - boxhit = Math::Clamp(boxhit, 0, viewport.GetHeight()); - int lxp = viewport.GetWidth() / 2 - boxwid / 2; - int lyp = viewport.GetHeight() / 2 - boxhit / 2; - gfxDriver->Vsync(); - temp_scr->Blit(saved_backbuf, lxp, lyp, lxp, lyp, - boxwid, boxhit); - render_to_screen(); - update_polled_mp3(); - WaitForNextFrame(); - } - gfxDriver->SetMemoryBackBuffer(saved_backbuf); - } - play.screen_is_faded_out = 0; - } - else if (theTransition == FADE_CROSSFADE) - { - if (game.color_depth == 1) - quit("!Cannot use crossfade screen transition in 256-colour games"); - - IDriverDependantBitmap *ddb = prepare_screen_for_transition_in(); - - int transparency = 254; - - while (transparency > 0) { - // do the crossfade - ddb->SetTransparency(transparency); - invalidate_screen(); - construct_game_scene(true); - construct_game_screen_overlay(false); - - if (transparency > 16) - { - // on last frame of fade (where transparency < 16), don't - // draw the old screen on top - gfxDriver->DrawSprite(0, 0, ddb); - } - render_to_screen(); - update_polled_stuff_if_runtime(); - WaitForNextFrame(); - transparency -= 16; - } - saved_viewport_bitmap->Release(); - - delete saved_viewport_bitmap; - saved_viewport_bitmap = nullptr; - set_palette_range(palette, 0, 255, 0); - gfxDriver->DestroyDDB(ddb); - } - else if (theTransition == FADE_DISSOLVE) { - int pattern[16]={0,4,14,9,5,11,2,8,10,3,12,7,15,6,13,1}; - int aa,bb,cc; - color interpal[256]; - - IDriverDependantBitmap *ddb = prepare_screen_for_transition_in(); - for (aa=0;aa<16;aa++) { - // merge the palette while dithering - if (game.color_depth == 1) - { - fade_interpolate(old_palette,palette,interpal,aa*4,0,255); - set_palette_range(interpal, 0, 255, 0); - } - // do the dissolving - int maskCol = saved_viewport_bitmap->GetMaskColor(); - for (bb=0;bbPutPixel(bb+pattern[aa]/4, cc+pattern[aa]%4, maskCol); - } - } - gfxDriver->UpdateDDBFromBitmap(ddb, saved_viewport_bitmap, false); - construct_game_scene(true); - construct_game_screen_overlay(false); - gfxDriver->DrawSprite(0, 0, ddb); - render_to_screen(); - update_polled_stuff_if_runtime(); - WaitForNextFrame(); - } - - delete saved_viewport_bitmap; - saved_viewport_bitmap = nullptr; - set_palette_range(palette, 0, 255, 0); - gfxDriver->DestroyDDB(ddb); - } - - } - else if (evp->type==EV_IFACECLICK) - process_interface_click(evp->data1, evp->data2, evp->data3); - else quit("process_event: unknown event to process"); + const Size &data_res = game.GetDataRes(); + const Rect &viewport = play.GetMainViewport(); + + if ((theTransition == FADE_INSTANT) || ignore_transition) + set_palette_range(palette, 0, 255, 0); + else if (theTransition == FADE_NORMAL) { + my_fade_in(palette, 5); + } else if (theTransition == FADE_BOXOUT) { + if (!gfxDriver->UsesMemoryBackBuffer()) { + gfxDriver->BoxOutEffect(false, get_fixed_pixel_size(16), 1000 / GetGameSpeed()); + } else { + // First of all we render the game once again and save backbuffer from further editing. + // We put temporary bitmap as a new backbuffer for the transition period, and + // will be drawing saved image of the game over to that backbuffer, simulating "box-out". + set_palette_range(palette, 0, 255, 0); + construct_game_scene(true); + construct_game_screen_overlay(false); + gfxDriver->RenderToBackBuffer(); + Bitmap *saved_backbuf = gfxDriver->GetMemoryBackBuffer(); + Bitmap *temp_scr = new Bitmap(saved_backbuf->GetWidth(), saved_backbuf->GetHeight(), saved_backbuf->GetColorDepth()); + gfxDriver->SetMemoryBackBuffer(temp_scr); + temp_scr->Clear(); + render_to_screen(); + + const int speed = get_fixed_pixel_size(16); + const int yspeed = viewport.GetHeight() / (viewport.GetWidth() / speed); + int boxwid = speed, boxhit = yspeed; + while (boxwid < temp_scr->GetWidth()) { + boxwid += speed; + boxhit += yspeed; + boxwid = Math::Clamp(boxwid, 0, viewport.GetWidth()); + boxhit = Math::Clamp(boxhit, 0, viewport.GetHeight()); + int lxp = viewport.GetWidth() / 2 - boxwid / 2; + int lyp = viewport.GetHeight() / 2 - boxhit / 2; + gfxDriver->Vsync(); + temp_scr->Blit(saved_backbuf, lxp, lyp, lxp, lyp, + boxwid, boxhit); + render_to_screen(); + update_polled_mp3(); + WaitForNextFrame(); + } + gfxDriver->SetMemoryBackBuffer(saved_backbuf); + } + play.screen_is_faded_out = 0; + } else if (theTransition == FADE_CROSSFADE) { + if (game.color_depth == 1) + quit("!Cannot use crossfade screen transition in 256-colour games"); + + IDriverDependantBitmap *ddb = prepare_screen_for_transition_in(); + + int transparency = 254; + + while (transparency > 0) { + // do the crossfade + ddb->SetTransparency(transparency); + invalidate_screen(); + construct_game_scene(true); + construct_game_screen_overlay(false); + + if (transparency > 16) { + // on last frame of fade (where transparency < 16), don't + // draw the old screen on top + gfxDriver->DrawSprite(0, 0, ddb); + } + render_to_screen(); + update_polled_stuff_if_runtime(); + WaitForNextFrame(); + transparency -= 16; + } + saved_viewport_bitmap->Release(); + + delete saved_viewport_bitmap; + saved_viewport_bitmap = nullptr; + set_palette_range(palette, 0, 255, 0); + gfxDriver->DestroyDDB(ddb); + } else if (theTransition == FADE_DISSOLVE) { + int pattern[16] = {0, 4, 14, 9, 5, 11, 2, 8, 10, 3, 12, 7, 15, 6, 13, 1}; + int aa, bb, cc; + color interpal[256]; + + IDriverDependantBitmap *ddb = prepare_screen_for_transition_in(); + for (aa = 0; aa < 16; aa++) { + // merge the palette while dithering + if (game.color_depth == 1) { + fade_interpolate(old_palette, palette, interpal, aa * 4, 0, 255); + set_palette_range(interpal, 0, 255, 0); + } + // do the dissolving + int maskCol = saved_viewport_bitmap->GetMaskColor(); + for (bb = 0; bb < viewport.GetWidth(); bb += 4) { + for (cc = 0; cc < viewport.GetHeight(); cc += 4) { + saved_viewport_bitmap->PutPixel(bb + pattern[aa] / 4, cc + pattern[aa] % 4, maskCol); + } + } + gfxDriver->UpdateDDBFromBitmap(ddb, saved_viewport_bitmap, false); + construct_game_scene(true); + construct_game_screen_overlay(false); + gfxDriver->DrawSprite(0, 0, ddb); + render_to_screen(); + update_polled_stuff_if_runtime(); + WaitForNextFrame(); + } + + delete saved_viewport_bitmap; + saved_viewport_bitmap = nullptr; + set_palette_range(palette, 0, 255, 0); + gfxDriver->DestroyDDB(ddb); + } + + } else if (evp->type == EV_IFACECLICK) + process_interface_click(evp->data1, evp->data2, evp->data3); + else quit("process_event: unknown event to process"); } -void runevent_now (int evtyp, int ev1, int ev2, int ev3) { - EventHappened evh; - evh.type = evtyp; - evh.data1 = ev1; - evh.data2 = ev2; - evh.data3 = ev3; - evh.player = game.playercharacter; - process_event(&evh); +void runevent_now(int evtyp, int ev1, int ev2, int ev3) { + EventHappened evh; + evh.type = evtyp; + evh.data1 = ev1; + evh.data2 = ev2; + evh.data3 = ev3; + evh.player = game.playercharacter; + process_event(&evh); } -void processallevents(int numev,EventHappened*evlist) { - int dd; +void processallevents(int numev, EventHappened *evlist) { + int dd; - if (inside_processevent) - return; + if (inside_processevent) + return; - // make a copy of the events - if processing an event includes - // a blocking function it will continue to the next game loop - // and wipe out the event pointer we were passed - EventHappened copyOfList[MAXEVENTS]; - memcpy(©OfList[0], &evlist[0], sizeof(EventHappened) * numev); + // make a copy of the events - if processing an event includes + // a blocking function it will continue to the next game loop + // and wipe out the event pointer we were passed + EventHappened copyOfList[MAXEVENTS]; + memcpy(©OfList[0], &evlist[0], sizeof(EventHappened) * numev); - int room_was = play.room_changes; + int room_was = play.room_changes; - inside_processevent++; + inside_processevent++; - for (dd=0;dd scFileAppend)) - quit("!OpenFile: invalid file mode"); + if ((mode < scFileRead) || (mode > scFileAppend)) + quit("!OpenFile: invalid file mode"); - sc_File *scf = new sc_File(); - if (scf->OpenFile(fnmm, mode) == 0) { - delete scf; - return nullptr; - } - ccRegisterManagedObject(scf, scf); - return scf; + sc_File *scf = new sc_File(); + if (scf->OpenFile(fnmm, mode) == 0) { + delete scf; + return nullptr; + } + ccRegisterManagedObject(scf, scf); + return scf; } void File_Close(sc_File *fil) { - fil->Close(); + fil->Close(); } void File_WriteString(sc_File *fil, const char *towrite) { - FileWrite(fil->handle, towrite); + FileWrite(fil->handle, towrite); } void File_WriteInt(sc_File *fil, int towrite) { - FileWriteInt(fil->handle, towrite); + FileWriteInt(fil->handle, towrite); } void File_WriteRawChar(sc_File *fil, int towrite) { - FileWriteRawChar(fil->handle, towrite); + FileWriteRawChar(fil->handle, towrite); } void File_WriteRawLine(sc_File *fil, const char *towrite) { - FileWriteRawLine(fil->handle, towrite); -} - -void File_ReadRawLine(sc_File *fil, char* buffer) { - Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.ReadRawLine"); - check_strlen(buffer); - int i = 0; - while (i < MAXSTRLEN - 1) { - buffer[i] = in->ReadInt8(); - if (buffer[i] == 13) { - // CR -- skip LF and abort - in->ReadInt8(); - break; - } - if (buffer[i] == 10) // LF only -- abort - break; - if (in->EOS()) // EOF -- abort - break; - i++; - } - buffer[i] = 0; -} - -const char* File_ReadRawLineBack(sc_File *fil) { - char readbuffer[MAX_MAXSTRLEN + 1]; - File_ReadRawLine(fil, readbuffer); - return CreateNewScriptString(readbuffer); + FileWriteRawLine(fil->handle, towrite); +} + +void File_ReadRawLine(sc_File *fil, char *buffer) { + Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.ReadRawLine"); + check_strlen(buffer); + int i = 0; + while (i < MAXSTRLEN - 1) { + buffer[i] = in->ReadInt8(); + if (buffer[i] == 13) { + // CR -- skip LF and abort + in->ReadInt8(); + break; + } + if (buffer[i] == 10) // LF only -- abort + break; + if (in->EOS()) // EOF -- abort + break; + i++; + } + buffer[i] = 0; +} + +const char *File_ReadRawLineBack(sc_File *fil) { + char readbuffer[MAX_MAXSTRLEN + 1]; + File_ReadRawLine(fil, readbuffer); + return CreateNewScriptString(readbuffer); } void File_ReadString(sc_File *fil, char *toread) { - FileRead(fil->handle, toread); + FileRead(fil->handle, toread); } -const char* File_ReadStringBack(sc_File *fil) { - Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.ReadStringBack"); - if (in->EOS()) { - return CreateNewScriptString(""); - } +const char *File_ReadStringBack(sc_File *fil) { + Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.ReadStringBack"); + if (in->EOS()) { + return CreateNewScriptString(""); + } - int lle = in->ReadInt32(); - if ((lle >= 20000) || (lle < 1)) - quit("!File.ReadStringBack: file was not written by WriteString"); + int lle = in->ReadInt32(); + if ((lle >= 20000) || (lle < 1)) + quit("!File.ReadStringBack: file was not written by WriteString"); - char *retVal = (char*)malloc(lle); - in->Read(retVal, lle); + char *retVal = (char *)malloc(lle); + in->Read(retVal, lle); - return CreateNewScriptString(retVal, false); + return CreateNewScriptString(retVal, false); } int File_ReadInt(sc_File *fil) { - return FileReadInt(fil->handle); + return FileReadInt(fil->handle); } int File_ReadRawChar(sc_File *fil) { - return FileReadRawChar(fil->handle); + return FileReadRawChar(fil->handle); } int File_ReadRawInt(sc_File *fil) { - return FileReadRawInt(fil->handle); + return FileReadRawInt(fil->handle); } -int File_Seek(sc_File *fil, int offset, int origin) -{ - Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.Seek"); - if (!in->Seek(offset, (StreamSeek)origin)) { return -1; } - return in->GetPosition(); +int File_Seek(sc_File *fil, int offset, int origin) { + Stream *in = get_valid_file_stream_from_handle(fil->handle, "File.Seek"); + if (!in->Seek(offset, (StreamSeek)origin)) { + return -1; + } + return in->GetPosition(); } int File_GetEOF(sc_File *fil) { - if (fil->handle <= 0) - return 1; - return FileIsEOF(fil->handle); + if (fil->handle <= 0) + return 1; + return FileIsEOF(fil->handle); } int File_GetError(sc_File *fil) { - if (fil->handle <= 0) - return 1; - return FileIsError(fil->handle); + if (fil->handle <= 0) + return 1; + return FileIsError(fil->handle); } -int File_GetPosition(sc_File *fil) -{ - if (fil->handle <= 0) - return -1; - Stream *stream = get_valid_file_stream_from_handle(fil->handle, "File.Position"); - // TODO: a problem is that AGS script does not support unsigned or long int - return (int)stream->GetPosition(); +int File_GetPosition(sc_File *fil) { + if (fil->handle <= 0) + return -1; + Stream *stream = get_valid_file_stream_from_handle(fil->handle, "File.Position"); + // TODO: a problem is that AGS script does not support unsigned or long int + return (int)stream->GetPosition(); } //============================================================================= @@ -215,461 +215,394 @@ const String UserSavedgamesRootToken = "$MYDOCS$"; const String GameSavedgamesDirToken = "$SAVEGAMEDIR$"; const String GameDataDirToken = "$APPDATADIR$"; -void FixupFilename(char *filename) -{ - const char *illegal = platform->GetIllegalFileChars(); - for (char *name_ptr = filename; *name_ptr; ++name_ptr) - { - if (*name_ptr < ' ') - { - *name_ptr = '_'; - } - else - { - for (const char *ch_ptr = illegal; *ch_ptr; ++ch_ptr) - if (*name_ptr == *ch_ptr) - *name_ptr = '_'; - } - } +void FixupFilename(char *filename) { + const char *illegal = platform->GetIllegalFileChars(); + for (char *name_ptr = filename; *name_ptr; ++name_ptr) { + if (*name_ptr < ' ') { + *name_ptr = '_'; + } else { + for (const char *ch_ptr = illegal; *ch_ptr; ++ch_ptr) + if (*name_ptr == *ch_ptr) + *name_ptr = '_'; + } + } } // Tests if there is a special path token in the beginning of the given path; // if there is and there is no slash between token and the rest of the string, // then assigns new string that has such slash. // Returns TRUE if the new string was created, and FALSE if the path was good. -bool FixSlashAfterToken(const String &path, const String &token, String &new_path) -{ - if (path.CompareLeft(token) == 0 && path.GetLength() > token.GetLength() && - path[token.GetLength()] != '/') - { - new_path = String::FromFormat("%s/%s", token.GetCStr(), path.Mid(token.GetLength()).GetCStr()); - return true; - } - return false; -} - -String FixSlashAfterToken(const String &path) -{ - String fixed_path = path; - Path::FixupPath(fixed_path); - if (FixSlashAfterToken(fixed_path, GameInstallRootToken, fixed_path) || - FixSlashAfterToken(fixed_path, UserSavedgamesRootToken, fixed_path) || - FixSlashAfterToken(fixed_path, GameSavedgamesDirToken, fixed_path) || - FixSlashAfterToken(fixed_path, GameDataDirToken, fixed_path)) - return fixed_path; - return path; -} - -String MakeSpecialSubDir(const String &sp_dir) -{ - if (is_relative_filename(sp_dir)) - return sp_dir; - String full_path = sp_dir; - if (full_path.GetLast() != '/' && full_path.GetLast() != '\\') - full_path.AppendChar('/'); - full_path.Append(game.saveGameFolderName); - Directory::CreateDirectory(full_path); - return full_path; -} - -String MakeAppDataPath() -{ - String app_data_path = usetup.shared_data_dir; - if (app_data_path.IsEmpty()) - app_data_path = MakeSpecialSubDir(PathOrCurDir(platform->GetAllUsersDataDirectory())); - Directory::CreateDirectory(app_data_path); - app_data_path.AppendChar('/'); - return app_data_path; -} - -bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath &rp) -{ - rp = ResolvedPath(); - - bool is_absolute = !is_relative_filename(orig_sc_path); - if (is_absolute && !read_only) - { - debug_script_warn("Attempt to access file '%s' denied (cannot write to absolute path)", orig_sc_path.GetCStr()); - return false; - } - - if (is_absolute) - { - rp.FullPath = orig_sc_path; - return true; - } - - String sc_path = FixSlashAfterToken(orig_sc_path); - String parent_dir; - String child_path; - String alt_path; - if (sc_path.CompareLeft(GameInstallRootToken, GameInstallRootToken.GetLength()) == 0) - { - if (!read_only) - { - debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory)", - sc_path.GetCStr()); - return false; - } - parent_dir = get_install_dir(); - parent_dir.AppendChar('/'); - child_path = sc_path.Mid(GameInstallRootToken.GetLength()); - } - else if (sc_path.CompareLeft(GameSavedgamesDirToken, GameSavedgamesDirToken.GetLength()) == 0) - { - parent_dir = get_save_game_directory(); - child_path = sc_path.Mid(GameSavedgamesDirToken.GetLength()); - } - else if (sc_path.CompareLeft(GameDataDirToken, GameDataDirToken.GetLength()) == 0) - { - parent_dir = MakeAppDataPath(); - child_path = sc_path.Mid(GameDataDirToken.GetLength()); - } - else - { - child_path = sc_path; - - // For games which were made without having safe paths in mind, - // provide two paths: a path to the local directory and a path to - // AppData directory. - // This is done in case game writes a file by local path, and would - // like to read it back later. Since AppData path has higher priority, - // game will first check the AppData location and find a previously - // written file. - // If no file was written yet, but game is trying to read a pre-created - // file in the installation directory, then such file will be found - // following the 'alt_path'. - parent_dir = MakeAppDataPath(); - // Set alternate non-remapped "unsafe" path for read-only operations - if (read_only) - alt_path = String::FromFormat("%s/%s", get_install_dir().GetCStr(), sc_path.GetCStr()); - - // For games made in the safe-path-aware versions of AGS, report a warning - // if the unsafe path is used for write operation - if (!read_only && game.options[OPT_SAFEFILEPATHS]) - { - debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory);\nPath will be remapped to the app data directory: '%s'", - sc_path.GetCStr(), parent_dir.GetCStr()); - } - } - - if (child_path[0u] == '\\' || child_path[0u] == '/') - child_path.ClipLeft(1); - - String full_path = String::FromFormat("%s%s", parent_dir.GetCStr(), child_path.GetCStr()); - // don't allow write operations for relative paths outside game dir - if (!read_only) - { - if (!Path::IsSameOrSubDir(parent_dir, full_path)) - { - debug_script_warn("Attempt to access file '%s' denied (outside of game directory)", sc_path.GetCStr()); - return false; - } - } - rp.BaseDir = parent_dir; - rp.FullPath = full_path; - rp.AltPath = alt_path; - return true; -} - -bool ResolveWritePathAndCreateDirs(const String &sc_path, ResolvedPath &rp) -{ - if (!ResolveScriptPath(sc_path, false, rp)) - return false; - if (!Directory::CreateAllDirectories(rp.BaseDir, Path::GetDirectoryPath(rp.FullPath))) - { - debug_script_warn("ResolveScriptPath: failed to create all subdirectories: %s", rp.FullPath.GetCStr()); - return false; - } - return true; -} - -Stream *LocateAsset(const AssetPath &path, size_t &asset_size) -{ - String assetlib = path.first; - String assetname = path.second; - bool needsetback = false; - // Change to the different library, if required - // TODO: teaching AssetManager to register multiple libraries simultaneously - // will let us skip this step, and also make this operation much faster. - if (!assetlib.IsEmpty() && assetlib.CompareNoCase(ResPaths.GamePak.Name) != 0) - { - AssetManager::SetDataFile(get_known_assetlib(assetlib)); - needsetback = true; - } - Stream *asset_stream = AssetManager::OpenAsset(assetname); - asset_size = AssetManager::GetLastAssetSize(); - if (needsetback) - AssetManager::SetDataFile(ResPaths.GamePak.Path); - return asset_stream; +bool FixSlashAfterToken(const String &path, const String &token, String &new_path) { + if (path.CompareLeft(token) == 0 && path.GetLength() > token.GetLength() && + path[token.GetLength()] != '/') { + new_path = String::FromFormat("%s/%s", token.GetCStr(), path.Mid(token.GetLength()).GetCStr()); + return true; + } + return false; +} + +String FixSlashAfterToken(const String &path) { + String fixed_path = path; + Path::FixupPath(fixed_path); + if (FixSlashAfterToken(fixed_path, GameInstallRootToken, fixed_path) || + FixSlashAfterToken(fixed_path, UserSavedgamesRootToken, fixed_path) || + FixSlashAfterToken(fixed_path, GameSavedgamesDirToken, fixed_path) || + FixSlashAfterToken(fixed_path, GameDataDirToken, fixed_path)) + return fixed_path; + return path; +} + +String MakeSpecialSubDir(const String &sp_dir) { + if (is_relative_filename(sp_dir)) + return sp_dir; + String full_path = sp_dir; + if (full_path.GetLast() != '/' && full_path.GetLast() != '\\') + full_path.AppendChar('/'); + full_path.Append(game.saveGameFolderName); + Directory::CreateDirectory(full_path); + return full_path; +} + +String MakeAppDataPath() { + String app_data_path = usetup.shared_data_dir; + if (app_data_path.IsEmpty()) + app_data_path = MakeSpecialSubDir(PathOrCurDir(platform->GetAllUsersDataDirectory())); + Directory::CreateDirectory(app_data_path); + app_data_path.AppendChar('/'); + return app_data_path; +} + +bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath &rp) { + rp = ResolvedPath(); + + bool is_absolute = !is_relative_filename(orig_sc_path); + if (is_absolute && !read_only) { + debug_script_warn("Attempt to access file '%s' denied (cannot write to absolute path)", orig_sc_path.GetCStr()); + return false; + } + + if (is_absolute) { + rp.FullPath = orig_sc_path; + return true; + } + + String sc_path = FixSlashAfterToken(orig_sc_path); + String parent_dir; + String child_path; + String alt_path; + if (sc_path.CompareLeft(GameInstallRootToken, GameInstallRootToken.GetLength()) == 0) { + if (!read_only) { + debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory)", + sc_path.GetCStr()); + return false; + } + parent_dir = get_install_dir(); + parent_dir.AppendChar('/'); + child_path = sc_path.Mid(GameInstallRootToken.GetLength()); + } else if (sc_path.CompareLeft(GameSavedgamesDirToken, GameSavedgamesDirToken.GetLength()) == 0) { + parent_dir = get_save_game_directory(); + child_path = sc_path.Mid(GameSavedgamesDirToken.GetLength()); + } else if (sc_path.CompareLeft(GameDataDirToken, GameDataDirToken.GetLength()) == 0) { + parent_dir = MakeAppDataPath(); + child_path = sc_path.Mid(GameDataDirToken.GetLength()); + } else { + child_path = sc_path; + + // For games which were made without having safe paths in mind, + // provide two paths: a path to the local directory and a path to + // AppData directory. + // This is done in case game writes a file by local path, and would + // like to read it back later. Since AppData path has higher priority, + // game will first check the AppData location and find a previously + // written file. + // If no file was written yet, but game is trying to read a pre-created + // file in the installation directory, then such file will be found + // following the 'alt_path'. + parent_dir = MakeAppDataPath(); + // Set alternate non-remapped "unsafe" path for read-only operations + if (read_only) + alt_path = String::FromFormat("%s/%s", get_install_dir().GetCStr(), sc_path.GetCStr()); + + // For games made in the safe-path-aware versions of AGS, report a warning + // if the unsafe path is used for write operation + if (!read_only && game.options[OPT_SAFEFILEPATHS]) { + debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory);\nPath will be remapped to the app data directory: '%s'", + sc_path.GetCStr(), parent_dir.GetCStr()); + } + } + + if (child_path[0u] == '\\' || child_path[0u] == '/') + child_path.ClipLeft(1); + + String full_path = String::FromFormat("%s%s", parent_dir.GetCStr(), child_path.GetCStr()); + // don't allow write operations for relative paths outside game dir + if (!read_only) { + if (!Path::IsSameOrSubDir(parent_dir, full_path)) { + debug_script_warn("Attempt to access file '%s' denied (outside of game directory)", sc_path.GetCStr()); + return false; + } + } + rp.BaseDir = parent_dir; + rp.FullPath = full_path; + rp.AltPath = alt_path; + return true; +} + +bool ResolveWritePathAndCreateDirs(const String &sc_path, ResolvedPath &rp) { + if (!ResolveScriptPath(sc_path, false, rp)) + return false; + if (!Directory::CreateAllDirectories(rp.BaseDir, Path::GetDirectoryPath(rp.FullPath))) { + debug_script_warn("ResolveScriptPath: failed to create all subdirectories: %s", rp.FullPath.GetCStr()); + return false; + } + return true; +} + +Stream *LocateAsset(const AssetPath &path, size_t &asset_size) { + String assetlib = path.first; + String assetname = path.second; + bool needsetback = false; + // Change to the different library, if required + // TODO: teaching AssetManager to register multiple libraries simultaneously + // will let us skip this step, and also make this operation much faster. + if (!assetlib.IsEmpty() && assetlib.CompareNoCase(ResPaths.GamePak.Name) != 0) { + AssetManager::SetDataFile(get_known_assetlib(assetlib)); + needsetback = true; + } + Stream *asset_stream = AssetManager::OpenAsset(assetname); + asset_size = AssetManager::GetLastAssetSize(); + if (needsetback) + AssetManager::SetDataFile(ResPaths.GamePak.Path); + return asset_stream; } // // AGS custom PACKFILE callbacks, that use our own Stream object // -static int ags_pf_fclose(void *userdata) -{ - delete (AGS_PACKFILE_OBJ*)userdata; - return 0; +static int ags_pf_fclose(void *userdata) { + delete(AGS_PACKFILE_OBJ *)userdata; + return 0; } -static int ags_pf_getc(void *userdata) -{ - AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)userdata; - if (obj->remains > 0) - { - obj->remains--; - return obj->stream->ReadByte(); - } - return -1; +static int ags_pf_getc(void *userdata) { + AGS_PACKFILE_OBJ *obj = (AGS_PACKFILE_OBJ *)userdata; + if (obj->remains > 0) { + obj->remains--; + return obj->stream->ReadByte(); + } + return -1; } -static int ags_pf_ungetc(int c, void *userdata) -{ - return -1; // we do not want to support this +static int ags_pf_ungetc(int c, void *userdata) { + return -1; // we do not want to support this } -static long ags_pf_fread(void *p, long n, void *userdata) -{ - AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)userdata; - if (obj->remains > 0) - { - size_t read = Math::Min(obj->remains, (size_t)n); - obj->remains -= read; - return obj->stream->Read(p, read); - } - return -1; +static long ags_pf_fread(void *p, long n, void *userdata) { + AGS_PACKFILE_OBJ *obj = (AGS_PACKFILE_OBJ *)userdata; + if (obj->remains > 0) { + size_t read = Math::Min(obj->remains, (size_t)n); + obj->remains -= read; + return obj->stream->Read(p, read); + } + return -1; } -static int ags_pf_putc(int c, void *userdata) -{ - return -1; // don't support write +static int ags_pf_putc(int c, void *userdata) { + return -1; // don't support write } -static long ags_pf_fwrite(AL_CONST void *p, long n, void *userdata) -{ - return -1; // don't support write +static long ags_pf_fwrite(AL_CONST void *p, long n, void *userdata) { + return -1; // don't support write } -static int ags_pf_fseek(void *userdata, int offset) -{ - return -1; // don't support seek +static int ags_pf_fseek(void *userdata, int offset) { + return -1; // don't support seek } -static int ags_pf_feof(void *userdata) -{ - return ((AGS_PACKFILE_OBJ*)userdata)->remains == 0; +static int ags_pf_feof(void *userdata) { + return ((AGS_PACKFILE_OBJ *)userdata)->remains == 0; } -static int ags_pf_ferror(void *userdata) -{ - return ((AGS_PACKFILE_OBJ*)userdata)->stream->HasErrors() ? 1 : 0; +static int ags_pf_ferror(void *userdata) { + return ((AGS_PACKFILE_OBJ *)userdata)->stream->HasErrors() ? 1 : 0; } // Custom PACKFILE callback table static PACKFILE_VTABLE ags_packfile_vtable = { - ags_pf_fclose, - ags_pf_getc, - ags_pf_ungetc, - ags_pf_fread, - ags_pf_putc, - ags_pf_fwrite, - ags_pf_fseek, - ags_pf_feof, - ags_pf_ferror + ags_pf_fclose, + ags_pf_getc, + ags_pf_ungetc, + ags_pf_fread, + ags_pf_putc, + ags_pf_fwrite, + ags_pf_fseek, + ags_pf_feof, + ags_pf_ferror }; // -PACKFILE *PackfileFromAsset(const AssetPath &path, size_t &asset_size) -{ - Stream *asset_stream = LocateAsset(path, asset_size); - if (asset_stream && asset_size > 0) - { - AGS_PACKFILE_OBJ* obj = new AGS_PACKFILE_OBJ; - obj->stream.reset(asset_stream); - obj->asset_size = asset_size; - obj->remains = asset_size; - return pack_fopen_vtable(&ags_packfile_vtable, obj); - } - return nullptr; -} - -DUMBFILE *DUMBfileFromAsset(const AssetPath &path, size_t &asset_size) -{ - PACKFILE *pf = PackfileFromAsset(path, asset_size); - if (pf) - return dumbfile_open_packfile(pf); - return nullptr; -} - -bool DoesAssetExistInLib(const AssetPath &assetname) -{ - bool needsetback = false; - // Change to the different library, if required - // TODO: teaching AssetManager to register multiple libraries simultaneously - // will let us skip this step, and also make this operation much faster. - if (!assetname.first.IsEmpty() && assetname.first.CompareNoCase(ResPaths.GamePak.Name) != 0) - { - AssetManager::SetDataFile(get_known_assetlib(assetname.first)); - needsetback = true; - } - bool res = AssetManager::DoesAssetExist(assetname.second); - if (needsetback) - AssetManager::SetDataFile(ResPaths.GamePak.Path); - return res; -} - -void set_install_dir(const String &path, const String &audio_path, const String &voice_path) -{ - if (path.IsEmpty()) - installDirectory = "."; - else - installDirectory = Path::MakePathNoSlash(path); - if (audio_path.IsEmpty()) - installAudioDirectory = "."; - else - installAudioDirectory = Path::MakePathNoSlash(audio_path); - if (voice_path.IsEmpty()) - installVoiceDirectory = "."; - else - installVoiceDirectory = Path::MakePathNoSlash(voice_path); -} - -String get_install_dir() -{ - return installDirectory; -} - -String get_audio_install_dir() -{ - return installAudioDirectory; -} - -String get_voice_install_dir() -{ - return installVoiceDirectory; -} - -void get_install_dir_path(char* buffer, const char *fileName) -{ - sprintf(buffer, "%s/%s", installDirectory.GetCStr(), fileName); -} - -String find_assetlib(const String &filename) -{ - String libname = cbuf_to_string_and_free( ci_find_file(ResPaths.DataDir, filename) ); - if (AssetManager::IsDataFile(libname)) - return libname; - if (Path::ComparePaths(ResPaths.DataDir, installDirectory) != 0) - { - // Hack for running in Debugger - libname = cbuf_to_string_and_free( ci_find_file(installDirectory, filename) ); - if (AssetManager::IsDataFile(libname)) - return libname; - } - return ""; +PACKFILE *PackfileFromAsset(const AssetPath &path, size_t &asset_size) { + Stream *asset_stream = LocateAsset(path, asset_size); + if (asset_stream && asset_size > 0) { + AGS_PACKFILE_OBJ *obj = new AGS_PACKFILE_OBJ; + obj->stream.reset(asset_stream); + obj->asset_size = asset_size; + obj->remains = asset_size; + return pack_fopen_vtable(&ags_packfile_vtable, obj); + } + return nullptr; +} + +DUMBFILE *DUMBfileFromAsset(const AssetPath &path, size_t &asset_size) { + PACKFILE *pf = PackfileFromAsset(path, asset_size); + if (pf) + return dumbfile_open_packfile(pf); + return nullptr; +} + +bool DoesAssetExistInLib(const AssetPath &assetname) { + bool needsetback = false; + // Change to the different library, if required + // TODO: teaching AssetManager to register multiple libraries simultaneously + // will let us skip this step, and also make this operation much faster. + if (!assetname.first.IsEmpty() && assetname.first.CompareNoCase(ResPaths.GamePak.Name) != 0) { + AssetManager::SetDataFile(get_known_assetlib(assetname.first)); + needsetback = true; + } + bool res = AssetManager::DoesAssetExist(assetname.second); + if (needsetback) + AssetManager::SetDataFile(ResPaths.GamePak.Path); + return res; +} + +void set_install_dir(const String &path, const String &audio_path, const String &voice_path) { + if (path.IsEmpty()) + installDirectory = "."; + else + installDirectory = Path::MakePathNoSlash(path); + if (audio_path.IsEmpty()) + installAudioDirectory = "."; + else + installAudioDirectory = Path::MakePathNoSlash(audio_path); + if (voice_path.IsEmpty()) + installVoiceDirectory = "."; + else + installVoiceDirectory = Path::MakePathNoSlash(voice_path); +} + +String get_install_dir() { + return installDirectory; +} + +String get_audio_install_dir() { + return installAudioDirectory; +} + +String get_voice_install_dir() { + return installVoiceDirectory; +} + +void get_install_dir_path(char *buffer, const char *fileName) { + sprintf(buffer, "%s/%s", installDirectory.GetCStr(), fileName); +} + +String find_assetlib(const String &filename) { + String libname = cbuf_to_string_and_free(ci_find_file(ResPaths.DataDir, filename)); + if (AssetManager::IsDataFile(libname)) + return libname; + if (Path::ComparePaths(ResPaths.DataDir, installDirectory) != 0) { + // Hack for running in Debugger + libname = cbuf_to_string_and_free(ci_find_file(installDirectory, filename)); + if (AssetManager::IsDataFile(libname)) + return libname; + } + return ""; } // Looks up for known valid asset library and returns path, or empty string if failed -String get_known_assetlib(const String &filename) -{ - // TODO: write now there's only 3 regular PAKs, so we may do this quick - // string comparison, but if we support more maybe we could use a table. - if (filename.CompareNoCase(ResPaths.GamePak.Name) == 0) - return ResPaths.GamePak.Path; - if (filename.CompareNoCase(ResPaths.AudioPak.Name) == 0) - return ResPaths.AudioPak.Path; - if (filename.CompareNoCase(ResPaths.SpeechPak.Name) == 0) - return ResPaths.SpeechPak.Path; - return String(); -} - -Stream *find_open_asset(const String &filename) -{ - Stream *asset_s = Common::AssetManager::OpenAsset(filename); - if (!asset_s && Path::ComparePaths(ResPaths.DataDir, installDirectory) != 0) - { - // Just in case they're running in Debug, try standalone file in compiled folder - asset_s = ci_fopen(String::FromFormat("%s/%s", installDirectory.GetCStr(), filename.GetCStr())); - } - return asset_s; -} - -AssetPath get_audio_clip_assetpath(int bundling_type, const String &filename) -{ - // Special case is explicitly defined audio directory, which should be - // tried first regardless of bundling type. - if (Path::ComparePaths(ResPaths.DataDir, installAudioDirectory) != 0) - { - String filepath = String::FromFormat("%s/%s", installAudioDirectory.GetCStr(), filename.GetCStr()); - if (Path::IsFile(filepath)) - return AssetPath("", filepath); - } - - if (bundling_type == AUCL_BUNDLE_EXE) - return AssetPath(ResPaths.GamePak.Name, filename); - else if (bundling_type == AUCL_BUNDLE_VOX) - return AssetPath(game.GetAudioVOXName(), filename); - return AssetPath(); -} - -AssetPath get_voice_over_assetpath(const String &filename) -{ - // Special case is explicitly defined voice-over directory, which should be - // tried first. - if (Path::ComparePaths(ResPaths.DataDir, installVoiceDirectory) != 0) - { - String filepath = String::FromFormat("%s/%s", installVoiceDirectory.GetCStr(), filename.GetCStr()); - if (Path::IsFile(filepath)) - return AssetPath("", filepath); - } - return AssetPath(ResPaths.SpeechPak.Name, filename); +String get_known_assetlib(const String &filename) { + // TODO: write now there's only 3 regular PAKs, so we may do this quick + // string comparison, but if we support more maybe we could use a table. + if (filename.CompareNoCase(ResPaths.GamePak.Name) == 0) + return ResPaths.GamePak.Path; + if (filename.CompareNoCase(ResPaths.AudioPak.Name) == 0) + return ResPaths.AudioPak.Path; + if (filename.CompareNoCase(ResPaths.SpeechPak.Name) == 0) + return ResPaths.SpeechPak.Path; + return String(); +} + +Stream *find_open_asset(const String &filename) { + Stream *asset_s = Common::AssetManager::OpenAsset(filename); + if (!asset_s && Path::ComparePaths(ResPaths.DataDir, installDirectory) != 0) { + // Just in case they're running in Debug, try standalone file in compiled folder + asset_s = ci_fopen(String::FromFormat("%s/%s", installDirectory.GetCStr(), filename.GetCStr())); + } + return asset_s; +} + +AssetPath get_audio_clip_assetpath(int bundling_type, const String &filename) { + // Special case is explicitly defined audio directory, which should be + // tried first regardless of bundling type. + if (Path::ComparePaths(ResPaths.DataDir, installAudioDirectory) != 0) { + String filepath = String::FromFormat("%s/%s", installAudioDirectory.GetCStr(), filename.GetCStr()); + if (Path::IsFile(filepath)) + return AssetPath("", filepath); + } + + if (bundling_type == AUCL_BUNDLE_EXE) + return AssetPath(ResPaths.GamePak.Name, filename); + else if (bundling_type == AUCL_BUNDLE_VOX) + return AssetPath(game.GetAudioVOXName(), filename); + return AssetPath(); +} + +AssetPath get_voice_over_assetpath(const String &filename) { + // Special case is explicitly defined voice-over directory, which should be + // tried first. + if (Path::ComparePaths(ResPaths.DataDir, installVoiceDirectory) != 0) { + String filepath = String::FromFormat("%s/%s", installVoiceDirectory.GetCStr(), filename.GetCStr()); + if (Path::IsFile(filepath)) + return AssetPath("", filepath); + } + return AssetPath(ResPaths.SpeechPak.Name, filename); } ScriptFileHandle valid_handles[MAX_OPEN_SCRIPT_FILES + 1]; // [IKM] NOTE: this is not precisely the number of files opened at this moment, // but rather maximal number of handles that were used simultaneously during game run int num_open_script_files = 0; -ScriptFileHandle *check_valid_file_handle_ptr(Stream *stream_ptr, const char *operation_name) -{ - if (stream_ptr) - { - for (int i = 0; i < num_open_script_files; ++i) - { - if (stream_ptr == valid_handles[i].stream) - { - return &valid_handles[i]; - } - } - } - - String exmsg = String::FromFormat("!%s: invalid file handle; file not previously opened or has been closed", operation_name); - quit(exmsg); - return nullptr; -} - -ScriptFileHandle *check_valid_file_handle_int32(int32_t handle, const char *operation_name) -{ - if (handle > 0) - { - for (int i = 0; i < num_open_script_files; ++i) - { - if (handle == valid_handles[i].handle) - { - return &valid_handles[i]; - } - } - } - - String exmsg = String::FromFormat("!%s: invalid file handle; file not previously opened or has been closed", operation_name); - quit(exmsg); - return nullptr; -} - -Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_name) -{ - ScriptFileHandle *sc_handle = check_valid_file_handle_int32(handle, operation_name); - return sc_handle ? sc_handle->stream : nullptr; +ScriptFileHandle *check_valid_file_handle_ptr(Stream *stream_ptr, const char *operation_name) { + if (stream_ptr) { + for (int i = 0; i < num_open_script_files; ++i) { + if (stream_ptr == valid_handles[i].stream) { + return &valid_handles[i]; + } + } + } + + String exmsg = String::FromFormat("!%s: invalid file handle; file not previously opened or has been closed", operation_name); + quit(exmsg); + return nullptr; +} + +ScriptFileHandle *check_valid_file_handle_int32(int32_t handle, const char *operation_name) { + if (handle > 0) { + for (int i = 0; i < num_open_script_files; ++i) { + if (handle == valid_handles[i].handle) { + return &valid_handles[i]; + } + } + } + + String exmsg = String::FromFormat("!%s: invalid file handle; file not previously opened or has been closed", operation_name); + quit(exmsg); + return nullptr; +} + +Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_name) { + ScriptFileHandle *sc_handle = check_valid_file_handle_int32(handle, operation_name); + return sc_handle ? sc_handle->stream : nullptr; } //============================================================================= @@ -686,157 +619,137 @@ Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_ extern ScriptString myScriptStringImpl; // int (const char *fnmm) -RuntimeScriptValue Sc_File_Delete(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(File_Delete, const char); +RuntimeScriptValue Sc_File_Delete(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(File_Delete, const char); } // int (const char *fnmm) -RuntimeScriptValue Sc_File_Exists(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(File_Exists, const char); +RuntimeScriptValue Sc_File_Exists(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(File_Exists, const char); } // void *(const char *fnmm, int mode) -RuntimeScriptValue Sc_sc_OpenFile(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_POBJ_PINT(sc_File, sc_OpenFile, const char); +RuntimeScriptValue Sc_sc_OpenFile(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_POBJ_PINT(sc_File, sc_OpenFile, const char); } // void (sc_File *fil) -RuntimeScriptValue Sc_File_Close(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(sc_File, File_Close); +RuntimeScriptValue Sc_File_Close(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(sc_File, File_Close); } // int (sc_File *fil) -RuntimeScriptValue Sc_File_ReadInt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(sc_File, File_ReadInt); +RuntimeScriptValue Sc_File_ReadInt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(sc_File, File_ReadInt); } // int (sc_File *fil) -RuntimeScriptValue Sc_File_ReadRawChar(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(sc_File, File_ReadRawChar); +RuntimeScriptValue Sc_File_ReadRawChar(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(sc_File, File_ReadRawChar); } // int (sc_File *fil) -RuntimeScriptValue Sc_File_ReadRawInt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(sc_File, File_ReadRawInt); +RuntimeScriptValue Sc_File_ReadRawInt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(sc_File, File_ReadRawInt); } // void (sc_File *fil, char* buffer) -RuntimeScriptValue Sc_File_ReadRawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(sc_File, File_ReadRawLine, char); +RuntimeScriptValue Sc_File_ReadRawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(sc_File, File_ReadRawLine, char); } // const char* (sc_File *fil) -RuntimeScriptValue Sc_File_ReadRawLineBack(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadRawLineBack); +RuntimeScriptValue Sc_File_ReadRawLineBack(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadRawLineBack); } // void (sc_File *fil, char *toread) -RuntimeScriptValue Sc_File_ReadString(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(sc_File, File_ReadString, char); +RuntimeScriptValue Sc_File_ReadString(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(sc_File, File_ReadString, char); } // const char* (sc_File *fil) -RuntimeScriptValue Sc_File_ReadStringBack(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadStringBack); +RuntimeScriptValue Sc_File_ReadStringBack(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadStringBack); } // void (sc_File *fil, int towrite) -RuntimeScriptValue Sc_File_WriteInt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(sc_File, File_WriteInt); +RuntimeScriptValue Sc_File_WriteInt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(sc_File, File_WriteInt); } // void (sc_File *fil, int towrite) -RuntimeScriptValue Sc_File_WriteRawChar(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(sc_File, File_WriteRawChar); +RuntimeScriptValue Sc_File_WriteRawChar(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(sc_File, File_WriteRawChar); } // void (sc_File *fil, const char *towrite) -RuntimeScriptValue Sc_File_WriteRawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(sc_File, File_WriteRawLine, const char); +RuntimeScriptValue Sc_File_WriteRawLine(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(sc_File, File_WriteRawLine, const char); } // void (sc_File *fil, const char *towrite) -RuntimeScriptValue Sc_File_WriteString(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(sc_File, File_WriteString, const char); +RuntimeScriptValue Sc_File_WriteString(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(sc_File, File_WriteString, const char); } -RuntimeScriptValue Sc_File_Seek(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT2(sc_File, File_Seek); +RuntimeScriptValue Sc_File_Seek(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT2(sc_File, File_Seek); } // int (sc_File *fil) -RuntimeScriptValue Sc_File_GetEOF(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(sc_File, File_GetEOF); +RuntimeScriptValue Sc_File_GetEOF(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(sc_File, File_GetEOF); } // int (sc_File *fil) -RuntimeScriptValue Sc_File_GetError(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(sc_File, File_GetError); -} - -RuntimeScriptValue Sc_File_GetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(sc_File, File_GetPosition); -} - - -void RegisterFileAPI() -{ - ccAddExternalStaticFunction("File::Delete^1", Sc_File_Delete); - ccAddExternalStaticFunction("File::Exists^1", Sc_File_Exists); - ccAddExternalStaticFunction("File::Open^2", Sc_sc_OpenFile); - ccAddExternalObjectFunction("File::Close^0", Sc_File_Close); - ccAddExternalObjectFunction("File::ReadInt^0", Sc_File_ReadInt); - ccAddExternalObjectFunction("File::ReadRawChar^0", Sc_File_ReadRawChar); - ccAddExternalObjectFunction("File::ReadRawInt^0", Sc_File_ReadRawInt); - ccAddExternalObjectFunction("File::ReadRawLine^1", Sc_File_ReadRawLine); - ccAddExternalObjectFunction("File::ReadRawLineBack^0", Sc_File_ReadRawLineBack); - ccAddExternalObjectFunction("File::ReadString^1", Sc_File_ReadString); - ccAddExternalObjectFunction("File::ReadStringBack^0", Sc_File_ReadStringBack); - ccAddExternalObjectFunction("File::WriteInt^1", Sc_File_WriteInt); - ccAddExternalObjectFunction("File::WriteRawChar^1", Sc_File_WriteRawChar); - ccAddExternalObjectFunction("File::WriteRawLine^1", Sc_File_WriteRawLine); - ccAddExternalObjectFunction("File::WriteString^1", Sc_File_WriteString); - ccAddExternalObjectFunction("File::Seek^2", Sc_File_Seek); - ccAddExternalObjectFunction("File::get_EOF", Sc_File_GetEOF); - ccAddExternalObjectFunction("File::get_Error", Sc_File_GetError); - ccAddExternalObjectFunction("File::get_Position", Sc_File_GetPosition); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("File::Delete^1", (void*)File_Delete); - ccAddExternalFunctionForPlugin("File::Exists^1", (void*)File_Exists); - ccAddExternalFunctionForPlugin("File::Open^2", (void*)sc_OpenFile); - ccAddExternalFunctionForPlugin("File::Close^0", (void*)File_Close); - ccAddExternalFunctionForPlugin("File::ReadInt^0", (void*)File_ReadInt); - ccAddExternalFunctionForPlugin("File::ReadRawChar^0", (void*)File_ReadRawChar); - ccAddExternalFunctionForPlugin("File::ReadRawInt^0", (void*)File_ReadRawInt); - ccAddExternalFunctionForPlugin("File::ReadRawLine^1", (void*)File_ReadRawLine); - ccAddExternalFunctionForPlugin("File::ReadRawLineBack^0", (void*)File_ReadRawLineBack); - ccAddExternalFunctionForPlugin("File::ReadString^1", (void*)File_ReadString); - ccAddExternalFunctionForPlugin("File::ReadStringBack^0", (void*)File_ReadStringBack); - ccAddExternalFunctionForPlugin("File::WriteInt^1", (void*)File_WriteInt); - ccAddExternalFunctionForPlugin("File::WriteRawChar^1", (void*)File_WriteRawChar); - ccAddExternalFunctionForPlugin("File::WriteRawLine^1", (void*)File_WriteRawLine); - ccAddExternalFunctionForPlugin("File::WriteString^1", (void*)File_WriteString); - ccAddExternalFunctionForPlugin("File::get_EOF", (void*)File_GetEOF); - ccAddExternalFunctionForPlugin("File::get_Error", (void*)File_GetError); +RuntimeScriptValue Sc_File_GetError(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(sc_File, File_GetError); +} + +RuntimeScriptValue Sc_File_GetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(sc_File, File_GetPosition); +} + + +void RegisterFileAPI() { + ccAddExternalStaticFunction("File::Delete^1", Sc_File_Delete); + ccAddExternalStaticFunction("File::Exists^1", Sc_File_Exists); + ccAddExternalStaticFunction("File::Open^2", Sc_sc_OpenFile); + ccAddExternalObjectFunction("File::Close^0", Sc_File_Close); + ccAddExternalObjectFunction("File::ReadInt^0", Sc_File_ReadInt); + ccAddExternalObjectFunction("File::ReadRawChar^0", Sc_File_ReadRawChar); + ccAddExternalObjectFunction("File::ReadRawInt^0", Sc_File_ReadRawInt); + ccAddExternalObjectFunction("File::ReadRawLine^1", Sc_File_ReadRawLine); + ccAddExternalObjectFunction("File::ReadRawLineBack^0", Sc_File_ReadRawLineBack); + ccAddExternalObjectFunction("File::ReadString^1", Sc_File_ReadString); + ccAddExternalObjectFunction("File::ReadStringBack^0", Sc_File_ReadStringBack); + ccAddExternalObjectFunction("File::WriteInt^1", Sc_File_WriteInt); + ccAddExternalObjectFunction("File::WriteRawChar^1", Sc_File_WriteRawChar); + ccAddExternalObjectFunction("File::WriteRawLine^1", Sc_File_WriteRawLine); + ccAddExternalObjectFunction("File::WriteString^1", Sc_File_WriteString); + ccAddExternalObjectFunction("File::Seek^2", Sc_File_Seek); + ccAddExternalObjectFunction("File::get_EOF", Sc_File_GetEOF); + ccAddExternalObjectFunction("File::get_Error", Sc_File_GetError); + ccAddExternalObjectFunction("File::get_Position", Sc_File_GetPosition); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("File::Delete^1", (void *)File_Delete); + ccAddExternalFunctionForPlugin("File::Exists^1", (void *)File_Exists); + ccAddExternalFunctionForPlugin("File::Open^2", (void *)sc_OpenFile); + ccAddExternalFunctionForPlugin("File::Close^0", (void *)File_Close); + ccAddExternalFunctionForPlugin("File::ReadInt^0", (void *)File_ReadInt); + ccAddExternalFunctionForPlugin("File::ReadRawChar^0", (void *)File_ReadRawChar); + ccAddExternalFunctionForPlugin("File::ReadRawInt^0", (void *)File_ReadRawInt); + ccAddExternalFunctionForPlugin("File::ReadRawLine^1", (void *)File_ReadRawLine); + ccAddExternalFunctionForPlugin("File::ReadRawLineBack^0", (void *)File_ReadRawLineBack); + ccAddExternalFunctionForPlugin("File::ReadString^1", (void *)File_ReadString); + ccAddExternalFunctionForPlugin("File::ReadStringBack^0", (void *)File_ReadStringBack); + ccAddExternalFunctionForPlugin("File::WriteInt^1", (void *)File_WriteInt); + ccAddExternalFunctionForPlugin("File::WriteRawChar^1", (void *)File_WriteRawChar); + ccAddExternalFunctionForPlugin("File::WriteRawLine^1", (void *)File_WriteRawLine); + ccAddExternalFunctionForPlugin("File::WriteString^1", (void *)File_WriteString); + ccAddExternalFunctionForPlugin("File::get_EOF", (void *)File_GetEOF); + ccAddExternalFunctionForPlugin("File::get_Error", (void *)File_GetError); } diff --git a/engines/ags/engine/ac/file.h b/engines/ags/engine/ac/file.h index dd00616365e9..2ea04e003852 100644 --- a/engines/ags/engine/ac/file.h +++ b/engines/ags/engine/ac/file.h @@ -33,30 +33,29 @@ #include "ac/runtime_defines.h" using AGS::Common::Stream; -int File_Exists(const char *fnmm); -int File_Delete(const char *fnmm); -void *sc_OpenFile(const char *fnmm, int mode); -void File_Close(sc_File *fil); -void File_WriteString(sc_File *fil, const char *towrite); -void File_WriteInt(sc_File *fil, int towrite); -void File_WriteRawChar(sc_File *fil, int towrite); -void File_WriteRawLine(sc_File *fil, const char *towrite); -void File_ReadRawLine(sc_File *fil, char* buffer); -const char* File_ReadRawLineBack(sc_File *fil); -void File_ReadString(sc_File *fil, char *toread); -const char* File_ReadStringBack(sc_File *fil); -int File_ReadInt(sc_File *fil); -int File_ReadRawChar(sc_File *fil); -int File_ReadRawInt(sc_File *fil); +int File_Exists(const char *fnmm); +int File_Delete(const char *fnmm); +void *sc_OpenFile(const char *fnmm, int mode); +void File_Close(sc_File *fil); +void File_WriteString(sc_File *fil, const char *towrite); +void File_WriteInt(sc_File *fil, int towrite); +void File_WriteRawChar(sc_File *fil, int towrite); +void File_WriteRawLine(sc_File *fil, const char *towrite); +void File_ReadRawLine(sc_File *fil, char *buffer); +const char *File_ReadRawLineBack(sc_File *fil); +void File_ReadString(sc_File *fil, char *toread); +const char *File_ReadStringBack(sc_File *fil); +int File_ReadInt(sc_File *fil); +int File_ReadRawChar(sc_File *fil); +int File_ReadRawInt(sc_File *fil); int File_Seek(sc_File *fil, int offset, int origin); -int File_GetEOF(sc_File *fil); -int File_GetError(sc_File *fil); +int File_GetEOF(sc_File *fil); +int File_GetError(sc_File *fil); int File_GetPosition(sc_File *fil); -struct ScriptFileHandle -{ - Stream *stream; - int32_t handle; +struct ScriptFileHandle { + Stream *stream; + int32_t handle; }; extern ScriptFileHandle valid_handles[MAX_OPEN_SCRIPT_FILES + 1]; extern int num_open_script_files; diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 220349f2c0bc..5fc5e57d00c2 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -102,7 +102,7 @@ using namespace AGS::Common; using namespace AGS::Engine; extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; -extern int cur_mode,cur_cursor; +extern int cur_mode, cur_cursor; extern SpeechLipSyncLine *splipsync; extern int numLipLines, curLipLine, curLipLinePhoneme; @@ -111,12 +111,12 @@ extern DialogTopic *dialog; extern int ifacepopped; // currently displayed pop-up GUI (-1 if none) extern int mouse_on_iface; // mouse cursor is over this interface -extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; +extern int mouse_ifacebut_xoffs, mouse_ifacebut_yoffs; extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; extern int numAnimButs; -extern int is_complete_overlay,is_text_overlay; +extern int is_complete_overlay, is_text_overlay; #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID extern int psp_gfx_renderer; @@ -126,11 +126,11 @@ extern int obj_lowest_yp, char_lowest_yp; extern int actSpsCount; extern Bitmap **actsps; -extern IDriverDependantBitmap* *actspsbmp; +extern IDriverDependantBitmap * *actspsbmp; // temporary cache of walk-behind for this actsps image extern Bitmap **actspswb; -extern IDriverDependantBitmap* *actspswbbmp; -extern CachedActSpsData* actspswbcache; +extern IDriverDependantBitmap * *actspswbbmp; +extern CachedActSpsData *actspswbcache; extern Bitmap **guibg; extern IDriverDependantBitmap **guibgbmp; extern char transFileName[MAX_PATH]; @@ -145,24 +145,24 @@ GameState play; GameSetup usetup; GameSetupStruct game; RoomStatus troom; // used for non-saveable rooms, eg. intro -RoomObject*objs; -RoomStatus*croom=nullptr; +RoomObject *objs; +RoomStatus *croom = nullptr; RoomStruct thisroom; volatile int switching_away_from_game = 0; volatile bool switched_away = false; volatile char want_exit = 0, abort_engine = 0; GameDataVersion loaded_game_file_version = kGameVersion_Undefined; -int frames_per_second=40; -int displayed_room=-10,starting_room = -1; -int in_new_room=0, new_room_was = 0; // 1 in new room, 2 first time in new room, 3 loading saved game -int new_room_pos=0; +int frames_per_second = 40; +int displayed_room = -10, starting_room = -1; +int in_new_room = 0, new_room_was = 0; // 1 in new room, 2 first time in new room, 3 loading saved game +int new_room_pos = 0; int new_room_x = SCR_NO_VALUE, new_room_y = SCR_NO_VALUE; int new_room_loop = SCR_NO_VALUE; // initially size 1, this will be increased by the initFile function SpriteCache spriteset(game.SpriteInfos); -int proper_exit=0,our_eip=0; +int proper_exit = 0, our_eip = 0; std::vector guis; @@ -189,7 +189,7 @@ ScriptRegion scrRegion[MAX_ROOM_REGIONS]; ScriptInvItem scrInv[MAX_INV]; ScriptDialog *scrDialog; -ViewStruct*views=nullptr; +ViewStruct *views = nullptr; CharacterCache *charcache = nullptr; ObjectCache objcache[MAX_ROOM_OBJECTS]; @@ -202,10 +202,10 @@ String saveGameDirectory = "./"; // Custom save game parent directory String saveGameParent; -const char* sgnametemplate = "agssave.%03d"; +const char *sgnametemplate = "agssave.%03d"; String saveGameSuffix; -int game_paused=0; +int game_paused = 0; char pexbuf[STD_BUFFER_SIZE]; unsigned int load_new_game = 0; @@ -218,123 +218,106 @@ int getloctype_index = 0, getloctype_throughgui = 0; // Audio //============================================================================= -void Game_StopAudio(int audioType) -{ - if (((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) && (audioType != SCR_NO_VALUE)) - quitprintf("!Game.StopAudio: invalid audio type %d", audioType); - int aa; - - for (aa = 0; aa < MAX_SOUND_CHANNELS; aa++) - { - if (audioType == SCR_NO_VALUE) - { - stop_or_fade_out_channel(aa); - } - else - { - ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); - if ((clip != nullptr) && (clip->type == audioType)) - stop_or_fade_out_channel(aa); - } - } - - remove_clips_of_type_from_queue(audioType); -} - -int Game_IsAudioPlaying(int audioType) -{ - if (((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) && (audioType != SCR_NO_VALUE)) - quitprintf("!Game.IsAudioPlaying: invalid audio type %d", audioType); - - if (play.fast_forward) - return 0; - - for (int aa = 0; aa < MAX_SOUND_CHANNELS; aa++) - { - ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); - if (clip != nullptr) - { - if ((clip->type == audioType) || (audioType == SCR_NO_VALUE)) - { - return 1; - } - } - } - return 0; -} - -void Game_SetAudioTypeSpeechVolumeDrop(int audioType, int volumeDrop) -{ - if ((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) - quitprintf("!Game.SetAudioTypeVolume: invalid audio type: %d", audioType); - - Debug::Printf("Game.SetAudioTypeSpeechVolumeDrop: type: %d, drop: %d", audioType, volumeDrop); - game.audioClipTypes[audioType].volume_reduction_while_speech_playing = volumeDrop; - update_volume_drop_if_voiceover(); -} - -void Game_SetAudioTypeVolume(int audioType, int volume, int changeType) -{ - if ((volume < 0) || (volume > 100)) - quitprintf("!Game.SetAudioTypeVolume: volume %d is not between 0..100", volume); - if ((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) - quitprintf("!Game.SetAudioTypeVolume: invalid audio type: %d", audioType); - - Debug::Printf("Game.SetAudioTypeVolume: type: %d, volume: %d, change: %d", audioType, volume, changeType); - if ((changeType == VOL_CHANGEEXISTING) || - (changeType == VOL_BOTH)) - { - AudioChannelsLock lock; - for (int aa = 0; aa < MAX_SOUND_CHANNELS; aa++) - { - ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); - if ((clip != nullptr) && (clip->type == audioType)) - { - auto* ch = lock.GetChannel(aa); - if (ch) - ch->set_volume_percent(volume); - } - } - } - - if ((changeType == VOL_SETFUTUREDEFAULT) || - (changeType == VOL_BOTH)) - { - play.default_audio_type_volumes[audioType] = volume; - - // update queued clip volumes - update_queued_clips_volume(audioType, volume); - } +void Game_StopAudio(int audioType) { + if (((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) && (audioType != SCR_NO_VALUE)) + quitprintf("!Game.StopAudio: invalid audio type %d", audioType); + int aa; + + for (aa = 0; aa < MAX_SOUND_CHANNELS; aa++) { + if (audioType == SCR_NO_VALUE) { + stop_or_fade_out_channel(aa); + } else { + ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); + if ((clip != nullptr) && (clip->type == audioType)) + stop_or_fade_out_channel(aa); + } + } + + remove_clips_of_type_from_queue(audioType); +} + +int Game_IsAudioPlaying(int audioType) { + if (((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) && (audioType != SCR_NO_VALUE)) + quitprintf("!Game.IsAudioPlaying: invalid audio type %d", audioType); + + if (play.fast_forward) + return 0; + + for (int aa = 0; aa < MAX_SOUND_CHANNELS; aa++) { + ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); + if (clip != nullptr) { + if ((clip->type == audioType) || (audioType == SCR_NO_VALUE)) { + return 1; + } + } + } + return 0; +} + +void Game_SetAudioTypeSpeechVolumeDrop(int audioType, int volumeDrop) { + if ((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) + quitprintf("!Game.SetAudioTypeVolume: invalid audio type: %d", audioType); + + Debug::Printf("Game.SetAudioTypeSpeechVolumeDrop: type: %d, drop: %d", audioType, volumeDrop); + game.audioClipTypes[audioType].volume_reduction_while_speech_playing = volumeDrop; + update_volume_drop_if_voiceover(); +} + +void Game_SetAudioTypeVolume(int audioType, int volume, int changeType) { + if ((volume < 0) || (volume > 100)) + quitprintf("!Game.SetAudioTypeVolume: volume %d is not between 0..100", volume); + if ((audioType < 0) || ((size_t)audioType >= game.audioClipTypes.size())) + quitprintf("!Game.SetAudioTypeVolume: invalid audio type: %d", audioType); + + Debug::Printf("Game.SetAudioTypeVolume: type: %d, volume: %d, change: %d", audioType, volume, changeType); + if ((changeType == VOL_CHANGEEXISTING) || + (changeType == VOL_BOTH)) { + AudioChannelsLock lock; + for (int aa = 0; aa < MAX_SOUND_CHANNELS; aa++) { + ScriptAudioClip *clip = AudioChannel_GetPlayingClip(&scrAudioChannel[aa]); + if ((clip != nullptr) && (clip->type == audioType)) { + auto *ch = lock.GetChannel(aa); + if (ch) + ch->set_volume_percent(volume); + } + } + } + + if ((changeType == VOL_SETFUTUREDEFAULT) || + (changeType == VOL_BOTH)) { + play.default_audio_type_volumes[audioType] = volume; + + // update queued clip volumes + update_queued_clips_volume(audioType, volume); + } } int Game_GetMODPattern() { - if (current_music_type != MUS_MOD) - return -1; - AudioChannelsLock lock; - auto* music_ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); - return music_ch ? music_ch->get_pos() : -1; + if (current_music_type != MUS_MOD) + return -1; + AudioChannelsLock lock; + auto *music_ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + return music_ch ? music_ch->get_pos() : -1; } //============================================================================= // --- //============================================================================= -int Game_GetDialogCount() -{ - return game.numdialog; +int Game_GetDialogCount() { + return game.numdialog; } -void set_debug_mode(bool on) -{ - play.debug_mode = on ? 1 : 0; - debug_set_console(on); +void set_debug_mode(bool on) { + play.debug_mode = on ? 1 : 0; + debug_set_console(on); } void set_game_speed(int new_fps) { - frames_per_second = new_fps; - if (!isTimerFpsMaxed()) // if in maxed mode, don't update timer for now - setTimerFps(new_fps); + frames_per_second = new_fps; + if (!isTimerFpsMaxed()) // if in maxed mode, don't update timer for now + setTimerFps(new_fps); } extern int cbuttfont; @@ -342,341 +325,306 @@ extern int acdialog_font; int oldmouse; void setup_for_dialog() { - cbuttfont = play.normal_font; - acdialog_font = play.normal_font; - if (!play.mouse_cursor_hidden) - ags_domouse(DOMOUSE_ENABLE); - oldmouse=cur_cursor; set_mouse_cursor(CURS_ARROW); + cbuttfont = play.normal_font; + acdialog_font = play.normal_font; + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_ENABLE); + oldmouse = cur_cursor; + set_mouse_cursor(CURS_ARROW); } void restore_after_dialog() { - set_mouse_cursor(oldmouse); - if (!play.mouse_cursor_hidden) - ags_domouse(DOMOUSE_DISABLE); - invalidate_screen(); + set_mouse_cursor(oldmouse); + if (!play.mouse_cursor_hidden) + ags_domouse(DOMOUSE_DISABLE); + invalidate_screen(); } -String get_save_game_directory() -{ - return saveGameDirectory; +String get_save_game_directory() { + return saveGameDirectory; } -String get_save_game_suffix() -{ - return saveGameSuffix; +String get_save_game_suffix() { + return saveGameSuffix; } -void set_save_game_suffix(const String &suffix) -{ - saveGameSuffix = suffix; +void set_save_game_suffix(const String &suffix) { + saveGameSuffix = suffix; } String get_save_game_path(int slotNum) { - String filename; - filename.Format(sgnametemplate, slotNum); - String path = saveGameDirectory; - path.Append(filename); - path.Append(saveGameSuffix); - return path; + String filename; + filename.Format(sgnametemplate, slotNum); + String path = saveGameDirectory; + path.Append(filename); + path.Append(saveGameSuffix); + return path; } // Convert a path possibly containing path tags into acceptable save path -bool MakeSaveGameDir(const String &newFolder, ResolvedPath &rp) -{ - rp = ResolvedPath(); - // don't allow absolute paths - if (!is_relative_filename(newFolder)) - return false; - - String base_dir; - String newSaveGameDir = FixSlashAfterToken(newFolder); - - if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) - { - if (saveGameParent.IsEmpty()) - { - base_dir = PathOrCurDir(platform->GetUserSavedgamesDirectory()); - newSaveGameDir.ReplaceMid(0, UserSavedgamesRootToken.GetLength(), base_dir); - } - else - { - // If there is a custom save parent directory, then replace - // not only root token, but also first subdirectory - newSaveGameDir.ClipSection('/', 0, 1); - if (!newSaveGameDir.IsEmpty()) - newSaveGameDir.PrependChar('/'); - newSaveGameDir.Prepend(saveGameParent); - base_dir = saveGameParent; - } - } - else - { - // Convert the path relative to installation folder into path relative to the - // safe save path with default name - if (saveGameParent.IsEmpty()) - { - base_dir = PathOrCurDir(platform->GetUserSavedgamesDirectory()); - newSaveGameDir.Format("%s/%s/%s", base_dir.GetCStr(), game.saveGameFolderName, newFolder.GetCStr()); - } - else - { - base_dir = saveGameParent; - newSaveGameDir.Format("%s/%s", saveGameParent.GetCStr(), newFolder.GetCStr()); - } - // For games made in the safe-path-aware versions of AGS, report a warning - if (game.options[OPT_SAFEFILEPATHS]) - { - debug_script_warn("Attempt to explicitly set savegame location relative to the game installation directory ('%s') denied;\nPath will be remapped to the user documents directory: '%s'", - newFolder.GetCStr(), newSaveGameDir.GetCStr()); - } - } - rp.BaseDir = Path::MakeTrailingSlash(base_dir); - rp.FullPath = Path::MakeTrailingSlash(newSaveGameDir); - return true; -} - -bool SetCustomSaveParent(const String &path) -{ - if (SetSaveGameDirectoryPath(path, true)) - { - saveGameParent = path; - return true; - } - return false; -} - -bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path) -{ - if (!newFolder || newFolder[0] == 0) - newFolder = "."; - String newSaveGameDir; - if (explicit_path) - { - newSaveGameDir = Path::MakeTrailingSlash(newFolder); - if (!Directory::CreateDirectory(newSaveGameDir)) - return false; - } - else - { - ResolvedPath rp; - if (!MakeSaveGameDir(newFolder, rp)) - return false; - if (!Directory::CreateAllDirectories(rp.BaseDir, rp.FullPath)) - { - debug_script_warn("SetSaveGameDirectory: failed to create all subdirectories: %s", rp.FullPath.GetCStr()); - return false; - } - newSaveGameDir = rp.FullPath; - } - - String newFolderTempFile = String::FromFormat("%s""agstmp.tmp", newSaveGameDir.GetCStr()); - if (!Common::File::TestCreateFile(newFolderTempFile)) - return false; - - // copy the Restart Game file, if applicable - String restartGamePath = String::FromFormat("%s""agssave.%d%s", saveGameDirectory.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); - Stream *restartGameFile = Common::File::OpenFileRead(restartGamePath); - if (restartGameFile != nullptr) - { - long fileSize = restartGameFile->GetLength(); - char *mbuffer = (char*)malloc(fileSize); - restartGameFile->Read(mbuffer, fileSize); - delete restartGameFile; - - restartGamePath.Format("%s""agssave.%d%s", newSaveGameDir.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); - restartGameFile = Common::File::CreateFile(restartGamePath); - restartGameFile->Write(mbuffer, fileSize); - delete restartGameFile; - free(mbuffer); - } - - saveGameDirectory = newSaveGameDir; - return true; -} - -int Game_SetSaveGameDirectory(const char *newFolder) -{ - return SetSaveGameDirectoryPath(newFolder, false) ? 1 : 0; -} - -const char* Game_GetSaveSlotDescription(int slnum) { - String description; - if (read_savedgame_description(get_save_game_path(slnum), description)) - { - return CreateNewScriptString(description); - } - return nullptr; +bool MakeSaveGameDir(const String &newFolder, ResolvedPath &rp) { + rp = ResolvedPath(); + // don't allow absolute paths + if (!is_relative_filename(newFolder)) + return false; + + String base_dir; + String newSaveGameDir = FixSlashAfterToken(newFolder); + + if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) { + if (saveGameParent.IsEmpty()) { + base_dir = PathOrCurDir(platform->GetUserSavedgamesDirectory()); + newSaveGameDir.ReplaceMid(0, UserSavedgamesRootToken.GetLength(), base_dir); + } else { + // If there is a custom save parent directory, then replace + // not only root token, but also first subdirectory + newSaveGameDir.ClipSection('/', 0, 1); + if (!newSaveGameDir.IsEmpty()) + newSaveGameDir.PrependChar('/'); + newSaveGameDir.Prepend(saveGameParent); + base_dir = saveGameParent; + } + } else { + // Convert the path relative to installation folder into path relative to the + // safe save path with default name + if (saveGameParent.IsEmpty()) { + base_dir = PathOrCurDir(platform->GetUserSavedgamesDirectory()); + newSaveGameDir.Format("%s/%s/%s", base_dir.GetCStr(), game.saveGameFolderName, newFolder.GetCStr()); + } else { + base_dir = saveGameParent; + newSaveGameDir.Format("%s/%s", saveGameParent.GetCStr(), newFolder.GetCStr()); + } + // For games made in the safe-path-aware versions of AGS, report a warning + if (game.options[OPT_SAFEFILEPATHS]) { + debug_script_warn("Attempt to explicitly set savegame location relative to the game installation directory ('%s') denied;\nPath will be remapped to the user documents directory: '%s'", + newFolder.GetCStr(), newSaveGameDir.GetCStr()); + } + } + rp.BaseDir = Path::MakeTrailingSlash(base_dir); + rp.FullPath = Path::MakeTrailingSlash(newSaveGameDir); + return true; +} + +bool SetCustomSaveParent(const String &path) { + if (SetSaveGameDirectoryPath(path, true)) { + saveGameParent = path; + return true; + } + return false; +} + +bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path) { + if (!newFolder || newFolder[0] == 0) + newFolder = "."; + String newSaveGameDir; + if (explicit_path) { + newSaveGameDir = Path::MakeTrailingSlash(newFolder); + if (!Directory::CreateDirectory(newSaveGameDir)) + return false; + } else { + ResolvedPath rp; + if (!MakeSaveGameDir(newFolder, rp)) + return false; + if (!Directory::CreateAllDirectories(rp.BaseDir, rp.FullPath)) { + debug_script_warn("SetSaveGameDirectory: failed to create all subdirectories: %s", rp.FullPath.GetCStr()); + return false; + } + newSaveGameDir = rp.FullPath; + } + + String newFolderTempFile = String::FromFormat("%s""agstmp.tmp", newSaveGameDir.GetCStr()); + if (!Common::File::TestCreateFile(newFolderTempFile)) + return false; + + // copy the Restart Game file, if applicable + String restartGamePath = String::FromFormat("%s""agssave.%d%s", saveGameDirectory.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); + Stream *restartGameFile = Common::File::OpenFileRead(restartGamePath); + if (restartGameFile != nullptr) { + long fileSize = restartGameFile->GetLength(); + char *mbuffer = (char *)malloc(fileSize); + restartGameFile->Read(mbuffer, fileSize); + delete restartGameFile; + + restartGamePath.Format("%s""agssave.%d%s", newSaveGameDir.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); + restartGameFile = Common::File::CreateFile(restartGamePath); + restartGameFile->Write(mbuffer, fileSize); + delete restartGameFile; + free(mbuffer); + } + + saveGameDirectory = newSaveGameDir; + return true; +} + +int Game_SetSaveGameDirectory(const char *newFolder) { + return SetSaveGameDirectoryPath(newFolder, false) ? 1 : 0; +} + +const char *Game_GetSaveSlotDescription(int slnum) { + String description; + if (read_savedgame_description(get_save_game_path(slnum), description)) { + return CreateNewScriptString(description); + } + return nullptr; } void restore_game_dialog() { - can_run_delayed_command(); - if (thisroom.Options.SaveLoadDisabled == 1) { - DisplayMessage (983); - return; - } - if (inside_script) { - curscript->queue_action(ePSARestoreGameDialog, 0, "RestoreGameDialog"); - return; - } - setup_for_dialog(); - int toload=loadgamedialog(); - restore_after_dialog(); - if (toload>=0) { - try_restore_save(toload); - } + can_run_delayed_command(); + if (thisroom.Options.SaveLoadDisabled == 1) { + DisplayMessage(983); + return; + } + if (inside_script) { + curscript->queue_action(ePSARestoreGameDialog, 0, "RestoreGameDialog"); + return; + } + setup_for_dialog(); + int toload = loadgamedialog(); + restore_after_dialog(); + if (toload >= 0) { + try_restore_save(toload); + } } void save_game_dialog() { - if (thisroom.Options.SaveLoadDisabled == 1) { - DisplayMessage (983); - return; - } - if (inside_script) { - curscript->queue_action(ePSASaveGameDialog, 0, "SaveGameDialog"); - return; - } - setup_for_dialog(); - int toload=savegamedialog(); - restore_after_dialog(); - if (toload>=0) - save_game(toload, get_gui_dialog_buffer()); + if (thisroom.Options.SaveLoadDisabled == 1) { + DisplayMessage(983); + return; + } + if (inside_script) { + curscript->queue_action(ePSASaveGameDialog, 0, "SaveGameDialog"); + return; + } + setup_for_dialog(); + int toload = savegamedialog(); + restore_after_dialog(); + if (toload >= 0) + save_game(toload, get_gui_dialog_buffer()); } -void free_do_once_tokens() -{ - play.do_once_tokens.resize(0); +void free_do_once_tokens() { + play.do_once_tokens.resize(0); } // Free all the memory associated with the game // TODO: call this when exiting the game (currently only called in RunAGSGame) -void unload_game_file() -{ - close_translation(); - - play.FreeViewportsAndCameras(); - - characterScriptObjNames.clear(); - free(charextra); - free(mls); - free(actsps); - free(actspsbmp); - free(actspswb); - free(actspswbbmp); - free(actspswbcache); - - if ((gameinst != nullptr) && (gameinst->pc != 0)) - { - quit("Error: unload_game called while script still running"); - } - else - { - delete gameinstFork; - delete gameinst; - gameinstFork = nullptr; - gameinst = nullptr; - } - - gamescript.reset(); - - if ((dialogScriptsInst != nullptr) && (dialogScriptsInst->pc != 0)) - { - quit("Error: unload_game called while dialog script still running"); - } - else if (dialogScriptsInst != nullptr) - { - delete dialogScriptsInst; - dialogScriptsInst = nullptr; - } - - dialogScriptsScript.reset(); - - for (int i = 0; i < numScriptModules; ++i) - { - delete moduleInstFork[i]; - delete moduleInst[i]; - scriptModules[i].reset(); - } - moduleInstFork.resize(0); - moduleInst.resize(0); - scriptModules.resize(0); - repExecAlways.moduleHasFunction.resize(0); - lateRepExecAlways.moduleHasFunction.resize(0); - getDialogOptionsDimensionsFunc.moduleHasFunction.resize(0); - renderDialogOptionsFunc.moduleHasFunction.resize(0); - getDialogOptionUnderCursorFunc.moduleHasFunction.resize(0); - runDialogOptionMouseClickHandlerFunc.moduleHasFunction.resize(0); - runDialogOptionKeyPressHandlerFunc.moduleHasFunction.resize(0); - runDialogOptionRepExecFunc.moduleHasFunction.resize(0); - numScriptModules = 0; - - free(views); - views = nullptr; - - free(charcache); - charcache = nullptr; - - if (splipsync != nullptr) - { - for (int i = 0; i < numLipLines; ++i) - { - free(splipsync[i].endtimeoffs); - free(splipsync[i].frame); - } - free(splipsync); - splipsync = nullptr; - numLipLines = 0; - curLipLine = -1; - } - - for (int i = 0; i < game.numdialog; ++i) - { - if (dialog[i].optionscripts != nullptr) - free(dialog[i].optionscripts); - dialog[i].optionscripts = nullptr; - } - free(dialog); - dialog = nullptr; - delete[] scrDialog; - scrDialog = nullptr; - - for (int i = 0; i < game.numgui; ++i) { - free(guibg[i]); - guibg[i] = nullptr; - } - - guiScriptObjNames.clear(); - free(guibg); - guis.clear(); - free(scrGui); - - pl_stop_plugins(); - ccRemoveAllSymbols(); - ccUnregisterAllObjects(); - - free_all_fonts(); - - free_do_once_tokens(); - free(play.gui_draw_order); - - resetRoomStatuses(); - - // free game struct last because it contains object counts - game.Free(); -} - - - +void unload_game_file() { + close_translation(); + + play.FreeViewportsAndCameras(); + + characterScriptObjNames.clear(); + free(charextra); + free(mls); + free(actsps); + free(actspsbmp); + free(actspswb); + free(actspswbbmp); + free(actspswbcache); + + if ((gameinst != nullptr) && (gameinst->pc != 0)) { + quit("Error: unload_game called while script still running"); + } else { + delete gameinstFork; + delete gameinst; + gameinstFork = nullptr; + gameinst = nullptr; + } + gamescript.reset(); + if ((dialogScriptsInst != nullptr) && (dialogScriptsInst->pc != 0)) { + quit("Error: unload_game called while dialog script still running"); + } else if (dialogScriptsInst != nullptr) { + delete dialogScriptsInst; + dialogScriptsInst = nullptr; + } -const char* Game_GetGlobalStrings(int index) { - if ((index < 0) || (index >= MAXGLOBALSTRINGS)) - quit("!Game.GlobalStrings: invalid index"); + dialogScriptsScript.reset(); - return CreateNewScriptString(play.globalstrings[index]); + for (int i = 0; i < numScriptModules; ++i) { + delete moduleInstFork[i]; + delete moduleInst[i]; + scriptModules[i].reset(); + } + moduleInstFork.resize(0); + moduleInst.resize(0); + scriptModules.resize(0); + repExecAlways.moduleHasFunction.resize(0); + lateRepExecAlways.moduleHasFunction.resize(0); + getDialogOptionsDimensionsFunc.moduleHasFunction.resize(0); + renderDialogOptionsFunc.moduleHasFunction.resize(0); + getDialogOptionUnderCursorFunc.moduleHasFunction.resize(0); + runDialogOptionMouseClickHandlerFunc.moduleHasFunction.resize(0); + runDialogOptionKeyPressHandlerFunc.moduleHasFunction.resize(0); + runDialogOptionRepExecFunc.moduleHasFunction.resize(0); + numScriptModules = 0; + + free(views); + views = nullptr; + + free(charcache); + charcache = nullptr; + + if (splipsync != nullptr) { + for (int i = 0; i < numLipLines; ++i) { + free(splipsync[i].endtimeoffs); + free(splipsync[i].frame); + } + free(splipsync); + splipsync = nullptr; + numLipLines = 0; + curLipLine = -1; + } + + for (int i = 0; i < game.numdialog; ++i) { + if (dialog[i].optionscripts != nullptr) + free(dialog[i].optionscripts); + dialog[i].optionscripts = nullptr; + } + free(dialog); + dialog = nullptr; + delete[] scrDialog; + scrDialog = nullptr; + + for (int i = 0; i < game.numgui; ++i) { + free(guibg[i]); + guibg[i] = nullptr; + } + + guiScriptObjNames.clear(); + free(guibg); + guis.clear(); + free(scrGui); + + pl_stop_plugins(); + ccRemoveAllSymbols(); + ccUnregisterAllObjects(); + + free_all_fonts(); + + free_do_once_tokens(); + free(play.gui_draw_order); + + resetRoomStatuses(); + + // free game struct last because it contains object counts + game.Free(); +} + + + + + + +const char *Game_GetGlobalStrings(int index) { + if ((index < 0) || (index >= MAXGLOBALSTRINGS)) + quit("!Game.GlobalStrings: invalid index"); + + return CreateNewScriptString(play.globalstrings[index]); } @@ -687,276 +635,251 @@ char gamefilenamebuf[200]; // ** GetGameParameter replacement functions int Game_GetInventoryItemCount() { - // because of the dummy item 0, this is always one higher than it should be - return game.numinvitems - 1; + // because of the dummy item 0, this is always one higher than it should be + return game.numinvitems - 1; } int Game_GetFontCount() { - return game.numfonts; + return game.numfonts; } int Game_GetMouseCursorCount() { - return game.numcursors; + return game.numcursors; } int Game_GetCharacterCount() { - return game.numcharacters; + return game.numcharacters; } int Game_GetGUICount() { - return game.numgui; + return game.numgui; } int Game_GetViewCount() { - return game.numviews; + return game.numviews; } -int Game_GetUseNativeCoordinates() -{ - return game.IsDataInNativeCoordinates() ? 1 : 0; +int Game_GetUseNativeCoordinates() { + return game.IsDataInNativeCoordinates() ? 1 : 0; } int Game_GetSpriteWidth(int spriteNum) { - if (spriteNum < 0) - return 0; + if (spriteNum < 0) + return 0; - if (!spriteset.DoesSpriteExist(spriteNum)) - return 0; + if (!spriteset.DoesSpriteExist(spriteNum)) + return 0; - return game_to_data_coord(game.SpriteInfos[spriteNum].Width); + return game_to_data_coord(game.SpriteInfos[spriteNum].Width); } int Game_GetSpriteHeight(int spriteNum) { - if (spriteNum < 0) - return 0; + if (spriteNum < 0) + return 0; - if (!spriteset.DoesSpriteExist(spriteNum)) - return 0; + if (!spriteset.DoesSpriteExist(spriteNum)) + return 0; - return game_to_data_coord(game.SpriteInfos[spriteNum].Height); + return game_to_data_coord(game.SpriteInfos[spriteNum].Height); } int Game_GetLoopCountForView(int viewNumber) { - if ((viewNumber < 1) || (viewNumber > game.numviews)) - quit("!GetGameParameter: invalid view specified"); + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); - return views[viewNumber - 1].numLoops; + return views[viewNumber - 1].numLoops; } int Game_GetRunNextSettingForLoop(int viewNumber, int loopNumber) { - if ((viewNumber < 1) || (viewNumber > game.numviews)) - quit("!GetGameParameter: invalid view specified"); - if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) - quit("!GetGameParameter: invalid loop specified"); + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); + if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) + quit("!GetGameParameter: invalid loop specified"); - return (views[viewNumber - 1].loops[loopNumber].RunNextLoop()) ? 1 : 0; + return (views[viewNumber - 1].loops[loopNumber].RunNextLoop()) ? 1 : 0; } int Game_GetFrameCountForLoop(int viewNumber, int loopNumber) { - if ((viewNumber < 1) || (viewNumber > game.numviews)) - quit("!GetGameParameter: invalid view specified"); - if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) - quit("!GetGameParameter: invalid loop specified"); + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); + if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) + quit("!GetGameParameter: invalid loop specified"); - return views[viewNumber - 1].loops[loopNumber].numFrames; + return views[viewNumber - 1].loops[loopNumber].numFrames; } -ScriptViewFrame* Game_GetViewFrame(int viewNumber, int loopNumber, int frame) { - if ((viewNumber < 1) || (viewNumber > game.numviews)) - quit("!GetGameParameter: invalid view specified"); - if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) - quit("!GetGameParameter: invalid loop specified"); - if ((frame < 0) || (frame >= views[viewNumber - 1].loops[loopNumber].numFrames)) - quit("!GetGameParameter: invalid frame specified"); +ScriptViewFrame *Game_GetViewFrame(int viewNumber, int loopNumber, int frame) { + if ((viewNumber < 1) || (viewNumber > game.numviews)) + quit("!GetGameParameter: invalid view specified"); + if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops)) + quit("!GetGameParameter: invalid loop specified"); + if ((frame < 0) || (frame >= views[viewNumber - 1].loops[loopNumber].numFrames)) + quit("!GetGameParameter: invalid frame specified"); - ScriptViewFrame *sdt = new ScriptViewFrame(viewNumber - 1, loopNumber, frame); - ccRegisterManagedObject(sdt, sdt); - return sdt; + ScriptViewFrame *sdt = new ScriptViewFrame(viewNumber - 1, loopNumber, frame); + ccRegisterManagedObject(sdt, sdt); + return sdt; } -int Game_DoOnceOnly(const char *token) -{ - for (int i = 0; i < (int)play.do_once_tokens.size(); i++) - { - if (play.do_once_tokens[i] == token) - { - return 0; - } - } - play.do_once_tokens.push_back(token); - return 1; +int Game_DoOnceOnly(const char *token) { + for (int i = 0; i < (int)play.do_once_tokens.size(); i++) { + if (play.do_once_tokens[i] == token) { + return 0; + } + } + play.do_once_tokens.push_back(token); + return 1; } -int Game_GetTextReadingSpeed() -{ - return play.text_speed; +int Game_GetTextReadingSpeed() { + return play.text_speed; } -void Game_SetTextReadingSpeed(int newTextSpeed) -{ - if (newTextSpeed < 1) - quitprintf("!Game.TextReadingSpeed: %d is an invalid speed", newTextSpeed); +void Game_SetTextReadingSpeed(int newTextSpeed) { + if (newTextSpeed < 1) + quitprintf("!Game.TextReadingSpeed: %d is an invalid speed", newTextSpeed); - play.text_speed = newTextSpeed; + play.text_speed = newTextSpeed; } -int Game_GetMinimumTextDisplayTimeMs() -{ - return play.text_min_display_time_ms; +int Game_GetMinimumTextDisplayTimeMs() { + return play.text_min_display_time_ms; } -void Game_SetMinimumTextDisplayTimeMs(int newTextMinTime) -{ - play.text_min_display_time_ms = newTextMinTime; +void Game_SetMinimumTextDisplayTimeMs(int newTextMinTime) { + play.text_min_display_time_ms = newTextMinTime; } -int Game_GetIgnoreUserInputAfterTextTimeoutMs() -{ - return play.ignore_user_input_after_text_timeout_ms; +int Game_GetIgnoreUserInputAfterTextTimeoutMs() { + return play.ignore_user_input_after_text_timeout_ms; } -void Game_SetIgnoreUserInputAfterTextTimeoutMs(int newValueMs) -{ - play.ignore_user_input_after_text_timeout_ms = newValueMs; +void Game_SetIgnoreUserInputAfterTextTimeoutMs(int newValueMs) { + play.ignore_user_input_after_text_timeout_ms = newValueMs; } const char *Game_GetFileName() { - return CreateNewScriptString(ResPaths.GamePak.Name); + return CreateNewScriptString(ResPaths.GamePak.Name); } const char *Game_GetName() { - return CreateNewScriptString(play.game_name); + return CreateNewScriptString(play.game_name); } void Game_SetName(const char *newName) { - strncpy(play.game_name, newName, 99); - play.game_name[99] = 0; - set_window_title(play.game_name); + strncpy(play.game_name, newName, 99); + play.game_name[99] = 0; + set_window_title(play.game_name); } -int Game_GetSkippingCutscene() -{ - if (play.fast_forward) - { - return 1; - } - return 0; +int Game_GetSkippingCutscene() { + if (play.fast_forward) { + return 1; + } + return 0; } -int Game_GetInSkippableCutscene() -{ - if (play.in_cutscene) - { - return 1; - } - return 0; +int Game_GetInSkippableCutscene() { + if (play.in_cutscene) { + return 1; + } + return 0; } int Game_GetColorFromRGB(int red, int grn, int blu) { - if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) || - (blu < 0) || (blu > 255)) - quit("!GetColorFromRGB: colour values must be 0-255"); + if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) || + (blu < 0) || (blu > 255)) + quit("!GetColorFromRGB: colour values must be 0-255"); - if (game.color_depth == 1) - { - return makecol8(red, grn, blu); - } + if (game.color_depth == 1) { + return makecol8(red, grn, blu); + } - int agscolor = ((blu >> 3) & 0x1f); - agscolor += ((grn >> 2) & 0x3f) << 5; - agscolor += ((red >> 3) & 0x1f) << 11; - return agscolor; + int agscolor = ((blu >> 3) & 0x1f); + agscolor += ((grn >> 2) & 0x3f) << 5; + agscolor += ((red >> 3) & 0x1f) << 11; + return agscolor; } -const char* Game_InputBox(const char *msg) { - char buffer[STD_BUFFER_SIZE]; - sc_inputbox(msg, buffer); - return CreateNewScriptString(buffer); +const char *Game_InputBox(const char *msg) { + char buffer[STD_BUFFER_SIZE]; + sc_inputbox(msg, buffer); + return CreateNewScriptString(buffer); } -const char* Game_GetLocationName(int x, int y) { - char buffer[STD_BUFFER_SIZE]; - GetLocationName(x, y, buffer); - return CreateNewScriptString(buffer); +const char *Game_GetLocationName(int x, int y) { + char buffer[STD_BUFFER_SIZE]; + GetLocationName(x, y, buffer); + return CreateNewScriptString(buffer); } -const char* Game_GetGlobalMessages(int index) { - if ((index < 500) || (index >= MAXGLOBALMES + 500)) { - return nullptr; - } - char buffer[STD_BUFFER_SIZE]; - buffer[0] = 0; - replace_tokens(get_translation(get_global_message(index)), buffer, STD_BUFFER_SIZE); - return CreateNewScriptString(buffer); +const char *Game_GetGlobalMessages(int index) { + if ((index < 500) || (index >= MAXGLOBALMES + 500)) { + return nullptr; + } + char buffer[STD_BUFFER_SIZE]; + buffer[0] = 0; + replace_tokens(get_translation(get_global_message(index)), buffer, STD_BUFFER_SIZE); + return CreateNewScriptString(buffer); } int Game_GetSpeechFont() { - return play.speech_font; + return play.speech_font; } int Game_GetNormalFont() { - return play.normal_font; + return play.normal_font; } -const char* Game_GetTranslationFilename() { - char buffer[STD_BUFFER_SIZE]; - GetTranslationName(buffer); - return CreateNewScriptString(buffer); +const char *Game_GetTranslationFilename() { + char buffer[STD_BUFFER_SIZE]; + GetTranslationName(buffer); + return CreateNewScriptString(buffer); } -int Game_ChangeTranslation(const char *newFilename) -{ - if ((newFilename == nullptr) || (newFilename[0] == 0)) - { - close_translation(); - strcpy(transFileName, ""); - usetup.translation = ""; - return 1; - } +int Game_ChangeTranslation(const char *newFilename) { + if ((newFilename == nullptr) || (newFilename[0] == 0)) { + close_translation(); + strcpy(transFileName, ""); + usetup.translation = ""; + return 1; + } - String oldTransFileName; - oldTransFileName = transFileName; + String oldTransFileName; + oldTransFileName = transFileName; - if (init_translation(newFilename, oldTransFileName.LeftSection('.'), false)) - { - usetup.translation = newFilename; - return 1; - } - else - { - strcpy(transFileName, oldTransFileName); - return 0; - } + if (init_translation(newFilename, oldTransFileName.LeftSection('.'), false)) { + usetup.translation = newFilename; + return 1; + } else { + strcpy(transFileName, oldTransFileName); + return 0; + } } -ScriptAudioClip *Game_GetAudioClip(int index) -{ - if (index < 0 || (size_t)index >= game.audioClips.size()) - return nullptr; - return &game.audioClips[index]; +ScriptAudioClip *Game_GetAudioClip(int index) { + if (index < 0 || (size_t)index >= game.audioClips.size()) + return nullptr; + return &game.audioClips[index]; } -ScriptCamera* Game_GetCamera() -{ - return play.GetScriptCamera(0); +ScriptCamera *Game_GetCamera() { + return play.GetScriptCamera(0); } -int Game_GetCameraCount() -{ - return play.GetRoomCameraCount(); +int Game_GetCameraCount() { + return play.GetRoomCameraCount(); } -ScriptCamera* Game_GetAnyCamera(int index) -{ - return play.GetScriptCamera(index); +ScriptCamera *Game_GetAnyCamera(int index) { + return play.GetScriptCamera(index); } -void Game_SimulateKeyPress(int key) -{ - int platformKey = GetKeyForKeyPressCb(key); - platformKey = PlatformKeyFromAgsKey(platformKey); - if (platformKey >= 0) { - simulate_keypress(platformKey); - } +void Game_SimulateKeyPress(int key) { + int platformKey = GetKeyForKeyPressCb(key); + platformKey = PlatformKeyFromAgsKey(platformKey); + if (platformKey >= 0) { + simulate_keypress(platformKey); + } } //============================================================================= @@ -966,1145 +889,1044 @@ void Game_SimulateKeyPress(int key) void serialize_bitmap(const Common::Bitmap *thispic, Stream *out) { - if (thispic != nullptr) { - out->WriteInt32(thispic->GetWidth()); - out->WriteInt32(thispic->GetHeight()); - out->WriteInt32(thispic->GetColorDepth()); - for (int cc=0;ccGetHeight();cc++) - { - switch (thispic->GetColorDepth()) - { - case 8: - // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8; - // therefore 15-bit bitmaps are saved only partially? is this a bug? or? - case 15: - out->WriteArray(&thispic->GetScanLine(cc)[0], thispic->GetWidth(), 1); - break; - case 16: - out->WriteArrayOfInt16((const int16_t*)&thispic->GetScanLine(cc)[0], thispic->GetWidth()); - break; - case 32: - out->WriteArrayOfInt32((const int32_t*)&thispic->GetScanLine(cc)[0], thispic->GetWidth()); - break; - } - } - } + if (thispic != nullptr) { + out->WriteInt32(thispic->GetWidth()); + out->WriteInt32(thispic->GetHeight()); + out->WriteInt32(thispic->GetColorDepth()); + for (int cc = 0; cc < thispic->GetHeight(); cc++) { + switch (thispic->GetColorDepth()) { + case 8: + // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8; + // therefore 15-bit bitmaps are saved only partially? is this a bug? or? + case 15: + out->WriteArray(&thispic->GetScanLine(cc)[0], thispic->GetWidth(), 1); + break; + case 16: + out->WriteArrayOfInt16((const int16_t *)&thispic->GetScanLine(cc)[0], thispic->GetWidth()); + break; + case 32: + out->WriteArrayOfInt32((const int32_t *)&thispic->GetScanLine(cc)[0], thispic->GetWidth()); + break; + } + } + } } // On Windows we could just use IIDFromString but this is platform-independant -void convert_guid_from_text_to_binary(const char *guidText, unsigned char *buffer) -{ - guidText++; // skip { - for (int bytesDone = 0; bytesDone < 16; bytesDone++) - { - if (*guidText == '-') - guidText++; - - char tempString[3]; - tempString[0] = guidText[0]; - tempString[1] = guidText[1]; - tempString[2] = 0; - int thisByte = 0; - sscanf(tempString, "%X", &thisByte); - - buffer[bytesDone] = thisByte; - guidText += 2; - } - - // Swap bytes to give correct GUID order - unsigned char temp; - temp = buffer[0]; buffer[0] = buffer[3]; buffer[3] = temp; - temp = buffer[1]; buffer[1] = buffer[2]; buffer[2] = temp; - temp = buffer[4]; buffer[4] = buffer[5]; buffer[5] = temp; - temp = buffer[6]; buffer[6] = buffer[7]; buffer[7] = temp; +void convert_guid_from_text_to_binary(const char *guidText, unsigned char *buffer) { + guidText++; // skip { + for (int bytesDone = 0; bytesDone < 16; bytesDone++) { + if (*guidText == '-') + guidText++; + + char tempString[3]; + tempString[0] = guidText[0]; + tempString[1] = guidText[1]; + tempString[2] = 0; + int thisByte = 0; + sscanf(tempString, "%X", &thisByte); + + buffer[bytesDone] = thisByte; + guidText += 2; + } + + // Swap bytes to give correct GUID order + unsigned char temp; + temp = buffer[0]; + buffer[0] = buffer[3]; + buffer[3] = temp; + temp = buffer[1]; + buffer[1] = buffer[2]; + buffer[2] = temp; + temp = buffer[4]; + buffer[4] = buffer[5]; + buffer[5] = temp; + temp = buffer[6]; + buffer[6] = buffer[7]; + buffer[7] = temp; } Bitmap *read_serialized_bitmap(Stream *in) { - Bitmap *thispic; - int picwid = in->ReadInt32(); - int pichit = in->ReadInt32(); - int piccoldep = in->ReadInt32(); - thispic = BitmapHelper::CreateBitmap(picwid,pichit,piccoldep); - if (thispic == nullptr) - return nullptr; - for (int vv=0; vv < pichit; vv++) - { - switch (piccoldep) - { - case 8: - // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8 - case 15: - in->ReadArray(thispic->GetScanLineForWriting(vv), picwid, 1); - break; - case 16: - in->ReadArrayOfInt16((int16_t*)thispic->GetScanLineForWriting(vv), picwid); - break; - case 32: - in->ReadArrayOfInt32((int32_t*)thispic->GetScanLineForWriting(vv), picwid); - break; - } - } - - return thispic; -} - -void skip_serialized_bitmap(Stream *in) -{ - int picwid = in->ReadInt32(); - int pichit = in->ReadInt32(); - int piccoldep = in->ReadInt32(); - // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8 - int bpp = piccoldep / 8; - in->Seek(picwid * pichit * bpp); -} - -long write_screen_shot_for_vista(Stream *out, Bitmap *screenshot) -{ - long fileSize = 0; - String tempFileName = String::FromFormat("%s""_tmpscht.bmp", saveGameDirectory.GetCStr()); - - screenshot->SaveToFile(tempFileName, palette); - - update_polled_stuff_if_runtime(); - - if (exists(tempFileName)) - { - fileSize = file_size_ex(tempFileName); - char *buffer = (char*)malloc(fileSize); - - Stream *temp_in = Common::File::OpenFileRead(tempFileName); - temp_in->Read(buffer, fileSize); - delete temp_in; - ::remove(tempFileName); - - out->Write(buffer, fileSize); - free(buffer); - } - return fileSize; -} - -void WriteGameSetupStructBase_Aligned(Stream *out) -{ - AlignedStream align_s(out, Common::kAligned_Write); - game.GameSetupStructBase::WriteToFile(&align_s); + Bitmap *thispic; + int picwid = in->ReadInt32(); + int pichit = in->ReadInt32(); + int piccoldep = in->ReadInt32(); + thispic = BitmapHelper::CreateBitmap(picwid, pichit, piccoldep); + if (thispic == nullptr) + return nullptr; + for (int vv = 0; vv < pichit; vv++) { + switch (piccoldep) { + case 8: + // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8 + case 15: + in->ReadArray(thispic->GetScanLineForWriting(vv), picwid, 1); + break; + case 16: + in->ReadArrayOfInt16((int16_t *)thispic->GetScanLineForWriting(vv), picwid); + break; + case 32: + in->ReadArrayOfInt32((int32_t *)thispic->GetScanLineForWriting(vv), picwid); + break; + } + } + + return thispic; +} + +void skip_serialized_bitmap(Stream *in) { + int picwid = in->ReadInt32(); + int pichit = in->ReadInt32(); + int piccoldep = in->ReadInt32(); + // CHECKME: originally, AGS does not use real BPP here, but simply divides color depth by 8 + int bpp = piccoldep / 8; + in->Seek(picwid * pichit * bpp); +} + +long write_screen_shot_for_vista(Stream *out, Bitmap *screenshot) { + long fileSize = 0; + String tempFileName = String::FromFormat("%s""_tmpscht.bmp", saveGameDirectory.GetCStr()); + + screenshot->SaveToFile(tempFileName, palette); + + update_polled_stuff_if_runtime(); + + if (exists(tempFileName)) { + fileSize = file_size_ex(tempFileName); + char *buffer = (char *)malloc(fileSize); + + Stream *temp_in = Common::File::OpenFileRead(tempFileName); + temp_in->Read(buffer, fileSize); + delete temp_in; + ::remove(tempFileName); + + out->Write(buffer, fileSize); + free(buffer); + } + return fileSize; +} + +void WriteGameSetupStructBase_Aligned(Stream *out) { + AlignedStream align_s(out, Common::kAligned_Write); + game.GameSetupStructBase::WriteToFile(&align_s); } #define MAGICNUMBER 0xbeefcafe -void create_savegame_screenshot(Bitmap *&screenShot) -{ - if (game.options[OPT_SAVESCREENSHOT]) { - int usewid = data_to_game_coord(play.screenshot_width); - int usehit = data_to_game_coord(play.screenshot_height); - const Rect &viewport = play.GetMainViewport(); - if (usewid > viewport.GetWidth()) - usewid = viewport.GetWidth(); - if (usehit > viewport.GetHeight()) - usehit = viewport.GetHeight(); - - if ((play.screenshot_width < 16) || (play.screenshot_height < 16)) - quit("!Invalid game.screenshot_width/height, must be from 16x16 to screen res"); - - screenShot = CopyScreenIntoBitmap(usewid, usehit); - } -} - -void save_game(int slotn, const char*descript) { - - // dont allow save in rep_exec_always, because we dont save - // the state of blocked scripts - can_run_delayed_command(); - - if (inside_script) { - strcpy(curscript->postScriptSaveSlotDescription[curscript->queue_action(ePSASaveGame, slotn, "SaveGameSlot")], descript); - return; - } - - if (platform->GetDiskFreeSpaceMB() < 2) { - Display("ERROR: There is not enough disk space free to save the game. Clear some disk space and try again."); - return; - } - - VALIDATE_STRING(descript); - String nametouse; - nametouse = get_save_game_path(slotn); - - Bitmap *screenShot = nullptr; - - // Screenshot - create_savegame_screenshot(screenShot); - - Common::PStream out = StartSavegame(nametouse, descript, screenShot); - if (out == nullptr) - quit("save_game: unable to open savegame file for writing"); - - update_polled_stuff_if_runtime(); - - // Actual dynamic game data is saved here - SaveGameState(out); - - if (screenShot != nullptr) - { - int screenShotOffset = out->GetPosition() - sizeof(RICH_GAME_MEDIA_HEADER); - int screenShotSize = write_screen_shot_for_vista(out.get(), screenShot); - - update_polled_stuff_if_runtime(); - - out.reset(Common::File::OpenFile(nametouse, Common::kFile_Open, Common::kFile_ReadWrite)); - out->Seek(12, kSeekBegin); - out->WriteInt32(screenShotOffset); - out->Seek(4); - out->WriteInt32(screenShotSize); - } - - if (screenShot != nullptr) - delete screenShot; -} - -HSaveError restore_game_head_dynamic_values(Stream *in, RestoredData &r_data) -{ - r_data.FPS = in->ReadInt32(); - r_data.CursorMode = in->ReadInt32(); - r_data.CursorID = in->ReadInt32(); - SavegameComponents::ReadLegacyCameraState(in, r_data); - set_loop_counter(in->ReadInt32()); - return HSaveError::None(); -} - -void restore_game_spriteset(Stream *in) -{ - // ensure the sprite set is at least as large as it was - // when the game was saved - spriteset.EnlargeTo(in->ReadInt32() - 1); // they saved top_index + 1 - // get serialized dynamic sprites - int sprnum = in->ReadInt32(); - while (sprnum) { - unsigned char spriteflag = in->ReadByte(); - add_dynamic_sprite(sprnum, read_serialized_bitmap(in)); - game.SpriteInfos[sprnum].Flags = spriteflag; - sprnum = in->ReadInt32(); - } -} - -HSaveError restore_game_scripts(Stream *in, const PreservedParams &pp, RestoredData &r_data) -{ - // read the global script data segment - int gdatasize = in->ReadInt32(); - if (pp.GlScDataSize != gdatasize) - { - return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching size of global script data."); - } - r_data.GlobalScript.Len = gdatasize; - r_data.GlobalScript.Data.reset(new char[gdatasize]); - in->Read(r_data.GlobalScript.Data.get(), gdatasize); - - if (in->ReadInt32() != numScriptModules) - { - return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of script modules."); - } - r_data.ScriptModules.resize(numScriptModules); - for (int i = 0; i < numScriptModules; ++i) - { - size_t module_size = in->ReadInt32(); - if (pp.ScMdDataSize[i] != module_size) - { - return new SavegameError(kSvgErr_GameContentAssertion, String::FromFormat("Mismatching size of script module data, module %d.", i)); - } - r_data.ScriptModules[i].Len = module_size; - r_data.ScriptModules[i].Data.reset(new char[module_size]); - in->Read(r_data.ScriptModules[i].Data.get(), module_size); - } - return HSaveError::None(); -} - -void ReadRoomStatus_Aligned(RoomStatus *roomstat, Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - roomstat->ReadFromFile_v321(&align_s); -} - -void restore_game_room_state(Stream *in) -{ - int vv; - - displayed_room = in->ReadInt32(); - - // read the room state for all the rooms the player has been in - RoomStatus* roomstat; - int beenhere; - for (vv=0;vvReadByte(); - if (beenhere) - { - roomstat = getRoomStatus(vv); - roomstat->beenhere = beenhere; - - if (roomstat->beenhere) - { - ReadRoomStatus_Aligned(roomstat, in); - if (roomstat->tsdatasize > 0) - { - roomstat->tsdata=(char*)malloc(roomstat->tsdatasize + 8); // JJS: Why allocate 8 additional bytes? - in->Read(&roomstat->tsdata[0], roomstat->tsdatasize); - } - } - } - } -} - -void ReadGameState_Aligned(Stream *in, RestoredData &r_data) -{ - AlignedStream align_s(in, Common::kAligned_Read); - play.ReadFromSavegame(&align_s, kGSSvgVersion_OldFormat, r_data); -} - -void restore_game_play_ex_data(Stream *in) -{ - char rbuffer[200]; - for (size_t i = 0; i < play.do_once_tokens.size(); ++i) - { - StrUtil::ReadCStr(rbuffer, in, sizeof(rbuffer)); - play.do_once_tokens[i] = rbuffer; - } - - in->ReadArrayOfInt32(&play.gui_draw_order[0], game.numgui); -} - -void restore_game_play(Stream *in, RestoredData &r_data) -{ - int screenfadedout_was = play.screen_is_faded_out; - int roomchanges_was = play.room_changes; - // make sure the pointer is preserved - int *gui_draw_order_was = play.gui_draw_order; - - ReadGameState_Aligned(in, r_data); - r_data.Cameras[0].Flags = r_data.Camera0_Flags; - - play.screen_is_faded_out = screenfadedout_was; - play.room_changes = roomchanges_was; - play.gui_draw_order = gui_draw_order_was; - - restore_game_play_ex_data(in); -} - -void ReadMoveList_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int i = 0; i < game.numcharacters + MAX_ROOM_OBJECTS + 1; ++i) - { - mls[i].ReadFromFile_Legacy(&align_s); - - align_s.Reset(); - } -} - -void ReadGameSetupStructBase_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - game.GameSetupStructBase::ReadFromFile(&align_s); -} - -void ReadCharacterExtras_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int i = 0; i < game.numcharacters; ++i) - { - charextra[i].ReadFromFile(&align_s); - align_s.Reset(); - } -} - -void restore_game_palette(Stream *in) -{ - in->ReadArray(&palette[0],sizeof(color),256); -} - -void restore_game_dialogs(Stream *in) -{ - for (int vv=0;vvReadArrayOfInt32(&dialog[vv].optionflags[0],MAXTOPICOPTIONS); -} - -void restore_game_more_dynamic_values(Stream *in) -{ - mouse_on_iface=in->ReadInt32(); - in->ReadInt32(); // mouse_on_iface_button - in->ReadInt32(); // mouse_pushed_iface - ifacepopped = in->ReadInt32(); - game_paused=in->ReadInt32(); -} - -void ReadAnimatedButtons_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int i = 0; i < numAnimButs; ++i) - { - animbuts[i].ReadFromFile(&align_s); - align_s.Reset(); - } -} - -HSaveError restore_game_gui(Stream *in, int numGuisWas) -{ - HError err = GUI::ReadGUI(guis, in, true); - if (!err) - return new SavegameError(kSvgErr_GameObjectInitFailed, err); - game.numgui = guis.size(); - - if (numGuisWas != game.numgui) - { - return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of GUI."); - } - - numAnimButs = in->ReadInt32(); - ReadAnimatedButtons_Aligned(in); - return HSaveError::None(); -} - -HSaveError restore_game_audiocliptypes(Stream *in) -{ - if (in->ReadInt32() != game.audioClipTypes.size()) - { - return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clip Types."); - } - - for (size_t i = 0; i < game.audioClipTypes.size(); ++i) - { - game.audioClipTypes[i].ReadFromFile(in); - } - return HSaveError::None(); -} - -void restore_game_thisroom(Stream *in, RestoredData &r_data) -{ - in->ReadArrayOfInt16(r_data.RoomLightLevels, MAX_ROOM_REGIONS); - in->ReadArrayOfInt32(r_data.RoomTintLevels, MAX_ROOM_REGIONS); - in->ReadArrayOfInt16(r_data.RoomZoomLevels1, MAX_WALK_AREAS + 1); - in->ReadArrayOfInt16(r_data.RoomZoomLevels2, MAX_WALK_AREAS + 1); -} - -void restore_game_ambientsounds(Stream *in, RestoredData &r_data) -{ - for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) - { - ambient[i].ReadFromFile(in); - } - - for (int bb = 1; bb < MAX_SOUND_CHANNELS; bb++) { - if (ambient[bb].channel == 0) - r_data.DoAmbient[bb] = 0; - else { - r_data.DoAmbient[bb] = ambient[bb].num; - ambient[bb].channel = 0; - } - } -} - -void ReadOverlays_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (auto &over : screenover) - { - over.ReadFromFile(&align_s, 0); - align_s.Reset(); - } -} - -void restore_game_overlays(Stream *in) -{ - screenover.resize(in->ReadInt32()); - ReadOverlays_Aligned(in); - for (auto &over : screenover) { - if (over.hasSerializedBitmap) - over.pic = read_serialized_bitmap(in); - } -} - -void restore_game_dynamic_surfaces(Stream *in, RestoredData &r_data) -{ - // load into a temp array since ccUnserialiseObjects will destroy - // it otherwise - r_data.DynamicSurfaces.resize(MAX_DYNAMIC_SURFACES); - for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) - { - if (in->ReadInt8() == 0) - { - r_data.DynamicSurfaces[i] = nullptr; - } - else - { - r_data.DynamicSurfaces[i] = read_serialized_bitmap(in); - } - } -} - -void restore_game_displayed_room_status(Stream *in, RestoredData &r_data) -{ - int bb; - for (bb = 0; bb < MAX_ROOM_BGFRAMES; bb++) - r_data.RoomBkgScene[bb].reset(); - - if (displayed_room >= 0) { - - for (bb = 0; bb < MAX_ROOM_BGFRAMES; bb++) { - r_data.RoomBkgScene[bb] = nullptr; - if (play.raw_modified[bb]) { - r_data.RoomBkgScene[bb].reset(read_serialized_bitmap(in)); - } - } - bb = in->ReadInt32(); - - if (bb) - raw_saved_screen = read_serialized_bitmap(in); - - // get the current troom, in case they save in room 600 or whatever - ReadRoomStatus_Aligned(&troom, in); - - if (troom.tsdatasize > 0) { - troom.tsdata=(char*)malloc(troom.tsdatasize+5); - in->Read(&troom.tsdata[0],troom.tsdatasize); - } - else - troom.tsdata = nullptr; - } -} - -HSaveError restore_game_globalvars(Stream *in) -{ - if (in->ReadInt32() != numGlobalVars) - { - return new SavegameError(kSvgErr_GameContentAssertion, "Restore game error: mismatching number of Global Variables."); - } - - for (int i = 0; i < numGlobalVars; ++i) - { - globalvars[i].Read(in); - } - return HSaveError::None(); -} - -HSaveError restore_game_views(Stream *in) -{ - if (in->ReadInt32() != game.numviews) - { - return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Views."); - } - - for (int bb = 0; bb < game.numviews; bb++) { - for (int cc = 0; cc < views[bb].numLoops; cc++) { - for (int dd = 0; dd < views[bb].loops[cc].numFrames; dd++) - { - views[bb].loops[cc].frames[dd].sound = in->ReadInt32(); - views[bb].loops[cc].frames[dd].pic = in->ReadInt32(); - } - } - } - return HSaveError::None(); -} - -HSaveError restore_game_audioclips_and_crossfade(Stream *in, RestoredData &r_data) -{ - if (in->ReadInt32() != game.audioClips.size()) - { - return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clips."); - } - - for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) - { - RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; - chan_info.Pos = 0; - chan_info.ClipID = in->ReadInt32(); - if (chan_info.ClipID >= 0) - { - if ((size_t)chan_info.ClipID >= game.audioClips.size()) - { - return new SavegameError(kSvgErr_GameObjectInitFailed, "Invalid audio clip index."); - } - - chan_info.Pos = in->ReadInt32(); - if (chan_info.Pos < 0) - chan_info.Pos = 0; - chan_info.Priority = in->ReadInt32(); - chan_info.Repeat = in->ReadInt32(); - chan_info.Vol = in->ReadInt32(); - chan_info.Pan = in->ReadInt32(); - chan_info.VolAsPercent = in->ReadInt32(); - chan_info.PanAsPercent = in->ReadInt32(); - chan_info.Speed = 1000; - if (loaded_game_file_version >= kGameVersion_340_2) - chan_info.Speed = in->ReadInt32(); - } - } - crossFading = in->ReadInt32(); - crossFadeVolumePerStep = in->ReadInt32(); - crossFadeStep = in->ReadInt32(); - crossFadeVolumeAtStart = in->ReadInt32(); - return HSaveError::None(); -} - -HSaveError restore_game_data(Stream *in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) -{ - int vv; - - HSaveError err = restore_game_head_dynamic_values(in, r_data); - if (!err) - return err; - restore_game_spriteset(in); - - update_polled_stuff_if_runtime(); - - err = restore_game_scripts(in, pp, r_data); - if (!err) - return err; - restore_game_room_state(in); - restore_game_play(in, r_data); - ReadMoveList_Aligned(in); - - // save pointer members before reading - char* gswas=game.globalscript; - ccScript* compsc=game.compiled_script; - CharacterInfo* chwas=game.chars; - WordsDictionary *olddict = game.dict; - char* mesbk[MAXGLOBALMES]; - int numchwas = game.numcharacters; - for (vv=0;vvReadInt32() != MAGICNUMBER+1) - { - return new SavegameError(kSvgErr_InconsistentFormat, "MAGICNUMBER not found before Audio Clips."); - } - - err = restore_game_audioclips_and_crossfade(in, r_data); - if (!err) - return err; - - auto pluginFileHandle = AGSE_RESTOREGAME; - pl_set_file_handle(pluginFileHandle, in); - pl_run_plugin_hooks(AGSE_RESTOREGAME, pluginFileHandle); - pl_clear_file_handle(); - if (in->ReadInt32() != (unsigned)MAGICNUMBER) - return new SavegameError(kSvgErr_InconsistentPlugin); - - // save the new room music vol for later use - r_data.RoomVolume = (RoomVolumeMod)in->ReadInt32(); - - if (ccUnserializeAllObjects(in, &ccUnserializer)) - { - return new SavegameError(kSvgErr_GameObjectInitFailed, - String::FromFormat("Managed pool deserialization failed: %s.", ccErrorString.GetCStr())); - } - - // preserve legacy music type setting - current_music_type = in->ReadInt32(); - - return HSaveError::None(); +void create_savegame_screenshot(Bitmap *&screenShot) { + if (game.options[OPT_SAVESCREENSHOT]) { + int usewid = data_to_game_coord(play.screenshot_width); + int usehit = data_to_game_coord(play.screenshot_height); + const Rect &viewport = play.GetMainViewport(); + if (usewid > viewport.GetWidth()) + usewid = viewport.GetWidth(); + if (usehit > viewport.GetHeight()) + usehit = viewport.GetHeight(); + + if ((play.screenshot_width < 16) || (play.screenshot_height < 16)) + quit("!Invalid game.screenshot_width/height, must be from 16x16 to screen res"); + + screenShot = CopyScreenIntoBitmap(usewid, usehit); + } +} + +void save_game(int slotn, const char *descript) { + + // dont allow save in rep_exec_always, because we dont save + // the state of blocked scripts + can_run_delayed_command(); + + if (inside_script) { + strcpy(curscript->postScriptSaveSlotDescription[curscript->queue_action(ePSASaveGame, slotn, "SaveGameSlot")], descript); + return; + } + + if (platform->GetDiskFreeSpaceMB() < 2) { + Display("ERROR: There is not enough disk space free to save the game. Clear some disk space and try again."); + return; + } + + VALIDATE_STRING(descript); + String nametouse; + nametouse = get_save_game_path(slotn); + + Bitmap *screenShot = nullptr; + + // Screenshot + create_savegame_screenshot(screenShot); + + Common::PStream out = StartSavegame(nametouse, descript, screenShot); + if (out == nullptr) + quit("save_game: unable to open savegame file for writing"); + + update_polled_stuff_if_runtime(); + + // Actual dynamic game data is saved here + SaveGameState(out); + + if (screenShot != nullptr) { + int screenShotOffset = out->GetPosition() - sizeof(RICH_GAME_MEDIA_HEADER); + int screenShotSize = write_screen_shot_for_vista(out.get(), screenShot); + + update_polled_stuff_if_runtime(); + + out.reset(Common::File::OpenFile(nametouse, Common::kFile_Open, Common::kFile_ReadWrite)); + out->Seek(12, kSeekBegin); + out->WriteInt32(screenShotOffset); + out->Seek(4); + out->WriteInt32(screenShotSize); + } + + if (screenShot != nullptr) + delete screenShot; +} + +HSaveError restore_game_head_dynamic_values(Stream *in, RestoredData &r_data) { + r_data.FPS = in->ReadInt32(); + r_data.CursorMode = in->ReadInt32(); + r_data.CursorID = in->ReadInt32(); + SavegameComponents::ReadLegacyCameraState(in, r_data); + set_loop_counter(in->ReadInt32()); + return HSaveError::None(); +} + +void restore_game_spriteset(Stream *in) { + // ensure the sprite set is at least as large as it was + // when the game was saved + spriteset.EnlargeTo(in->ReadInt32() - 1); // they saved top_index + 1 + // get serialized dynamic sprites + int sprnum = in->ReadInt32(); + while (sprnum) { + unsigned char spriteflag = in->ReadByte(); + add_dynamic_sprite(sprnum, read_serialized_bitmap(in)); + game.SpriteInfos[sprnum].Flags = spriteflag; + sprnum = in->ReadInt32(); + } +} + +HSaveError restore_game_scripts(Stream *in, const PreservedParams &pp, RestoredData &r_data) { + // read the global script data segment + int gdatasize = in->ReadInt32(); + if (pp.GlScDataSize != gdatasize) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching size of global script data."); + } + r_data.GlobalScript.Len = gdatasize; + r_data.GlobalScript.Data.reset(new char[gdatasize]); + in->Read(r_data.GlobalScript.Data.get(), gdatasize); + + if (in->ReadInt32() != numScriptModules) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of script modules."); + } + r_data.ScriptModules.resize(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) { + size_t module_size = in->ReadInt32(); + if (pp.ScMdDataSize[i] != module_size) { + return new SavegameError(kSvgErr_GameContentAssertion, String::FromFormat("Mismatching size of script module data, module %d.", i)); + } + r_data.ScriptModules[i].Len = module_size; + r_data.ScriptModules[i].Data.reset(new char[module_size]); + in->Read(r_data.ScriptModules[i].Data.get(), module_size); + } + return HSaveError::None(); +} + +void ReadRoomStatus_Aligned(RoomStatus *roomstat, Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + roomstat->ReadFromFile_v321(&align_s); +} + +void restore_game_room_state(Stream *in) { + int vv; + + displayed_room = in->ReadInt32(); + + // read the room state for all the rooms the player has been in + RoomStatus *roomstat; + int beenhere; + for (vv = 0; vv < MAX_ROOMS; vv++) { + beenhere = in->ReadByte(); + if (beenhere) { + roomstat = getRoomStatus(vv); + roomstat->beenhere = beenhere; + + if (roomstat->beenhere) { + ReadRoomStatus_Aligned(roomstat, in); + if (roomstat->tsdatasize > 0) { + roomstat->tsdata = (char *)malloc(roomstat->tsdatasize + 8); // JJS: Why allocate 8 additional bytes? + in->Read(&roomstat->tsdata[0], roomstat->tsdatasize); + } + } + } + } +} + +void ReadGameState_Aligned(Stream *in, RestoredData &r_data) { + AlignedStream align_s(in, Common::kAligned_Read); + play.ReadFromSavegame(&align_s, kGSSvgVersion_OldFormat, r_data); +} + +void restore_game_play_ex_data(Stream *in) { + char rbuffer[200]; + for (size_t i = 0; i < play.do_once_tokens.size(); ++i) { + StrUtil::ReadCStr(rbuffer, in, sizeof(rbuffer)); + play.do_once_tokens[i] = rbuffer; + } + + in->ReadArrayOfInt32(&play.gui_draw_order[0], game.numgui); +} + +void restore_game_play(Stream *in, RestoredData &r_data) { + int screenfadedout_was = play.screen_is_faded_out; + int roomchanges_was = play.room_changes; + // make sure the pointer is preserved + int *gui_draw_order_was = play.gui_draw_order; + + ReadGameState_Aligned(in, r_data); + r_data.Cameras[0].Flags = r_data.Camera0_Flags; + + play.screen_is_faded_out = screenfadedout_was; + play.room_changes = roomchanges_was; + play.gui_draw_order = gui_draw_order_was; + + restore_game_play_ex_data(in); +} + +void ReadMoveList_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < game.numcharacters + MAX_ROOM_OBJECTS + 1; ++i) { + mls[i].ReadFromFile_Legacy(&align_s); + + align_s.Reset(); + } +} + +void ReadGameSetupStructBase_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + game.GameSetupStructBase::ReadFromFile(&align_s); +} + +void ReadCharacterExtras_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < game.numcharacters; ++i) { + charextra[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void restore_game_palette(Stream *in) { + in->ReadArray(&palette[0], sizeof(color), 256); +} + +void restore_game_dialogs(Stream *in) { + for (int vv = 0; vv < game.numdialog; vv++) + in->ReadArrayOfInt32(&dialog[vv].optionflags[0], MAXTOPICOPTIONS); +} + +void restore_game_more_dynamic_values(Stream *in) { + mouse_on_iface = in->ReadInt32(); + in->ReadInt32(); // mouse_on_iface_button + in->ReadInt32(); // mouse_pushed_iface + ifacepopped = in->ReadInt32(); + game_paused = in->ReadInt32(); +} + +void ReadAnimatedButtons_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < numAnimButs; ++i) { + animbuts[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +HSaveError restore_game_gui(Stream *in, int numGuisWas) { + HError err = GUI::ReadGUI(guis, in, true); + if (!err) + return new SavegameError(kSvgErr_GameObjectInitFailed, err); + game.numgui = guis.size(); + + if (numGuisWas != game.numgui) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of GUI."); + } + + numAnimButs = in->ReadInt32(); + ReadAnimatedButtons_Aligned(in); + return HSaveError::None(); +} + +HSaveError restore_game_audiocliptypes(Stream *in) { + if (in->ReadInt32() != game.audioClipTypes.size()) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clip Types."); + } + + for (size_t i = 0; i < game.audioClipTypes.size(); ++i) { + game.audioClipTypes[i].ReadFromFile(in); + } + return HSaveError::None(); +} + +void restore_game_thisroom(Stream *in, RestoredData &r_data) { + in->ReadArrayOfInt16(r_data.RoomLightLevels, MAX_ROOM_REGIONS); + in->ReadArrayOfInt32(r_data.RoomTintLevels, MAX_ROOM_REGIONS); + in->ReadArrayOfInt16(r_data.RoomZoomLevels1, MAX_WALK_AREAS + 1); + in->ReadArrayOfInt16(r_data.RoomZoomLevels2, MAX_WALK_AREAS + 1); +} + +void restore_game_ambientsounds(Stream *in, RestoredData &r_data) { + for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) { + ambient[i].ReadFromFile(in); + } + + for (int bb = 1; bb < MAX_SOUND_CHANNELS; bb++) { + if (ambient[bb].channel == 0) + r_data.DoAmbient[bb] = 0; + else { + r_data.DoAmbient[bb] = ambient[bb].num; + ambient[bb].channel = 0; + } + } +} + +void ReadOverlays_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (auto &over : screenover) { + over.ReadFromFile(&align_s, 0); + align_s.Reset(); + } +} + +void restore_game_overlays(Stream *in) { + screenover.resize(in->ReadInt32()); + ReadOverlays_Aligned(in); + for (auto &over : screenover) { + if (over.hasSerializedBitmap) + over.pic = read_serialized_bitmap(in); + } +} + +void restore_game_dynamic_surfaces(Stream *in, RestoredData &r_data) { + // load into a temp array since ccUnserialiseObjects will destroy + // it otherwise + r_data.DynamicSurfaces.resize(MAX_DYNAMIC_SURFACES); + for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) { + if (in->ReadInt8() == 0) { + r_data.DynamicSurfaces[i] = nullptr; + } else { + r_data.DynamicSurfaces[i] = read_serialized_bitmap(in); + } + } +} + +void restore_game_displayed_room_status(Stream *in, RestoredData &r_data) { + int bb; + for (bb = 0; bb < MAX_ROOM_BGFRAMES; bb++) + r_data.RoomBkgScene[bb].reset(); + + if (displayed_room >= 0) { + + for (bb = 0; bb < MAX_ROOM_BGFRAMES; bb++) { + r_data.RoomBkgScene[bb] = nullptr; + if (play.raw_modified[bb]) { + r_data.RoomBkgScene[bb].reset(read_serialized_bitmap(in)); + } + } + bb = in->ReadInt32(); + + if (bb) + raw_saved_screen = read_serialized_bitmap(in); + + // get the current troom, in case they save in room 600 or whatever + ReadRoomStatus_Aligned(&troom, in); + + if (troom.tsdatasize > 0) { + troom.tsdata = (char *)malloc(troom.tsdatasize + 5); + in->Read(&troom.tsdata[0], troom.tsdatasize); + } else + troom.tsdata = nullptr; + } +} + +HSaveError restore_game_globalvars(Stream *in) { + if (in->ReadInt32() != numGlobalVars) { + return new SavegameError(kSvgErr_GameContentAssertion, "Restore game error: mismatching number of Global Variables."); + } + + for (int i = 0; i < numGlobalVars; ++i) { + globalvars[i].Read(in); + } + return HSaveError::None(); +} + +HSaveError restore_game_views(Stream *in) { + if (in->ReadInt32() != game.numviews) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Views."); + } + + for (int bb = 0; bb < game.numviews; bb++) { + for (int cc = 0; cc < views[bb].numLoops; cc++) { + for (int dd = 0; dd < views[bb].loops[cc].numFrames; dd++) { + views[bb].loops[cc].frames[dd].sound = in->ReadInt32(); + views[bb].loops[cc].frames[dd].pic = in->ReadInt32(); + } + } + } + return HSaveError::None(); +} + +HSaveError restore_game_audioclips_and_crossfade(Stream *in, RestoredData &r_data) { + if (in->ReadInt32() != game.audioClips.size()) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clips."); + } + + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { + RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; + chan_info.Pos = 0; + chan_info.ClipID = in->ReadInt32(); + if (chan_info.ClipID >= 0) { + if ((size_t)chan_info.ClipID >= game.audioClips.size()) { + return new SavegameError(kSvgErr_GameObjectInitFailed, "Invalid audio clip index."); + } + + chan_info.Pos = in->ReadInt32(); + if (chan_info.Pos < 0) + chan_info.Pos = 0; + chan_info.Priority = in->ReadInt32(); + chan_info.Repeat = in->ReadInt32(); + chan_info.Vol = in->ReadInt32(); + chan_info.Pan = in->ReadInt32(); + chan_info.VolAsPercent = in->ReadInt32(); + chan_info.PanAsPercent = in->ReadInt32(); + chan_info.Speed = 1000; + if (loaded_game_file_version >= kGameVersion_340_2) + chan_info.Speed = in->ReadInt32(); + } + } + crossFading = in->ReadInt32(); + crossFadeVolumePerStep = in->ReadInt32(); + crossFadeStep = in->ReadInt32(); + crossFadeVolumeAtStart = in->ReadInt32(); + return HSaveError::None(); +} + +HSaveError restore_game_data(Stream *in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) { + int vv; + + HSaveError err = restore_game_head_dynamic_values(in, r_data); + if (!err) + return err; + restore_game_spriteset(in); + + update_polled_stuff_if_runtime(); + + err = restore_game_scripts(in, pp, r_data); + if (!err) + return err; + restore_game_room_state(in); + restore_game_play(in, r_data); + ReadMoveList_Aligned(in); + + // save pointer members before reading + char *gswas = game.globalscript; + ccScript *compsc = game.compiled_script; + CharacterInfo *chwas = game.chars; + WordsDictionary *olddict = game.dict; + char *mesbk[MAXGLOBALMES]; + int numchwas = game.numcharacters; + for (vv = 0; vv < MAXGLOBALMES; vv++) mesbk[vv] = game.messages[vv]; + int numdiwas = game.numdialog; + int numinvwas = game.numinvitems; + int numviewswas = game.numviews; + int numGuisWas = game.numgui; + + ReadGameSetupStructBase_Aligned(in); + + // Delete unneeded data + // TODO: reorganize this (may be solved by optimizing safe format too) + delete [] game.load_messages; + game.load_messages = nullptr; + + if (game.numdialog != numdiwas) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Dialogs."); + } + if (numchwas != game.numcharacters) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Characters."); + } + if (numinvwas != game.numinvitems) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Inventory Items."); + } + if (game.numviews != numviewswas) { + return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Views."); + } + + game.ReadFromSaveGame_v321(in, gswas, compsc, chwas, olddict, mesbk); + + // Modified custom properties are read separately to keep existing save format + play.ReadCustomProperties_v340(in); + + ReadCharacterExtras_Aligned(in); + restore_game_palette(in); + restore_game_dialogs(in); + restore_game_more_dynamic_values(in); + err = restore_game_gui(in, numGuisWas); + if (!err) + return err; + err = restore_game_audiocliptypes(in); + if (!err) + return err; + restore_game_thisroom(in, r_data); + restore_game_ambientsounds(in, r_data); + restore_game_overlays(in); + + update_polled_stuff_if_runtime(); + + restore_game_dynamic_surfaces(in, r_data); + + update_polled_stuff_if_runtime(); + + restore_game_displayed_room_status(in, r_data); + err = restore_game_globalvars(in); + if (!err) + return err; + err = restore_game_views(in); + if (!err) + return err; + + if (in->ReadInt32() != MAGICNUMBER + 1) { + return new SavegameError(kSvgErr_InconsistentFormat, "MAGICNUMBER not found before Audio Clips."); + } + + err = restore_game_audioclips_and_crossfade(in, r_data); + if (!err) + return err; + + auto pluginFileHandle = AGSE_RESTOREGAME; + pl_set_file_handle(pluginFileHandle, in); + pl_run_plugin_hooks(AGSE_RESTOREGAME, pluginFileHandle); + pl_clear_file_handle(); + if (in->ReadInt32() != (unsigned)MAGICNUMBER) + return new SavegameError(kSvgErr_InconsistentPlugin); + + // save the new room music vol for later use + r_data.RoomVolume = (RoomVolumeMod)in->ReadInt32(); + + if (ccUnserializeAllObjects(in, &ccUnserializer)) { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Managed pool deserialization failed: %s.", ccErrorString.GetCStr())); + } + + // preserve legacy music type setting + current_music_type = in->ReadInt32(); + + return HSaveError::None(); } int gameHasBeenRestored = 0; int oldeip; -bool read_savedgame_description(const String &savedgame, String &description) -{ - SavegameDescription desc; - if (OpenSavegame(savedgame, desc, kSvgDesc_UserText)) - { - description = desc.UserText; - return true; - } - return false; -} - -bool read_savedgame_screenshot(const String &savedgame, int &want_shot) -{ - want_shot = 0; - - SavegameDescription desc; - HSaveError err = OpenSavegame(savedgame, desc, kSvgDesc_UserImage); - if (!err) - return false; - - if (desc.UserImage.get()) - { - int slot = spriteset.GetFreeIndex(); - if (slot > 0) - { - // add it into the sprite set - add_dynamic_sprite(slot, ReplaceBitmapWithSupportedFormat(desc.UserImage.release())); - want_shot = slot; - } - } - return true; -} - -HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten) -{ - data_overwritten = false; - gameHasBeenRestored++; - - oldeip = our_eip; - our_eip = 2050; - - HSaveError err; - SavegameSource src; - SavegameDescription desc; - err = OpenSavegame(path, src, desc, kSvgDesc_EnvInfo); - - // saved in incompatible enviroment - if (!err) - return err; - // CHECKME: is this color depth test still essential? if yes, is there possible workaround? - else if (desc.ColorDepth != game.GetColorDepth()) - return new SavegameError(kSvgErr_DifferentColorDepth, String::FromFormat("Running: %d-bit, saved in: %d-bit.", game.GetColorDepth(), desc.ColorDepth)); - - // saved with different game file - if (Path::ComparePaths(desc.MainDataFilename, ResPaths.GamePak.Name)) - { - // [IKM] 2012-11-26: this is a workaround, indeed. - // Try to find wanted game's executable; if it does not exist, - // continue loading savedgame in current game, and pray for the best - get_install_dir_path(gamefilenamebuf, desc.MainDataFilename); - if (Common::File::TestReadFile(gamefilenamebuf)) - { - RunAGSGame (desc.MainDataFilename, 0, 0); - load_new_game_restore = slotNumber; - return HSaveError::None(); - } - Common::Debug::Printf(kDbgMsg_Warn, "WARNING: the saved game '%s' references game file '%s', but it cannot be found in the current directory. Trying to restore in the running game instead.", - path.GetCStr(), desc.MainDataFilename.GetCStr()); - } - - // do the actual restore - err = RestoreGameState(src.InputStream, src.Version); - data_overwritten = true; - if (!err) - return err; - src.InputStream.reset(); - our_eip = oldeip; - - // ensure keyboard buffer is clean - ags_clear_input_buffer(); - // call "After Restore" event callback - run_on_event(GE_RESTORE_GAME, RuntimeScriptValue().SetInt32(slotNumber)); - return HSaveError::None(); -} - -bool try_restore_save(int slot) -{ - return try_restore_save(get_save_game_path(slot), slot); -} - -bool try_restore_save(const Common::String &path, int slot) -{ - bool data_overwritten; - HSaveError err = load_game(path, slot, data_overwritten); - if (!err) - { - String error = String::FromFormat("Unable to restore the saved game.\n%s", - err->FullMessage().GetCStr()); - // currently AGS cannot properly revert to stable state if some of the - // game data was released or overwritten by the data from save file, - // this is why we tell engine to shutdown if that happened. - if (data_overwritten) - quitprintf(error); - else - Display(error); - return false; - } - return true; -} - -bool is_in_cutscene() -{ - return play.in_cutscene > 0; -} - -CutsceneSkipStyle get_cutscene_skipstyle() -{ - return static_cast(play.in_cutscene); -} - -void start_skipping_cutscene () { - play.fast_forward = 1; - // if a drop-down icon bar is up, remove it as it will pause the game - if (ifacepopped>=0) - remove_popup_interface(ifacepopped); - - // if a text message is currently displayed, remove it - if (is_text_overlay > 0) - remove_screen_overlay(OVER_TEXTMSG); - -} - -bool check_skip_cutscene_keypress (int kgn) { - - CutsceneSkipStyle skip = get_cutscene_skipstyle(); - if (skip == eSkipSceneAnyKey || skip == eSkipSceneKeyMouse || - (kgn == 27 && (skip == eSkipSceneEscOnly || skip == eSkipSceneEscOrRMB))) - { - start_skipping_cutscene(); - return true; - } - return false; -} - -bool check_skip_cutscene_mclick(int mbut) -{ - CutsceneSkipStyle skip = get_cutscene_skipstyle(); - if (skip == eSkipSceneMouse || skip == eSkipSceneKeyMouse || - (mbut == RIGHT && skip == eSkipSceneEscOrRMB)) - { - start_skipping_cutscene(); - return true; - } - return false; +bool read_savedgame_description(const String &savedgame, String &description) { + SavegameDescription desc; + if (OpenSavegame(savedgame, desc, kSvgDesc_UserText)) { + description = desc.UserText; + return true; + } + return false; +} + +bool read_savedgame_screenshot(const String &savedgame, int &want_shot) { + want_shot = 0; + + SavegameDescription desc; + HSaveError err = OpenSavegame(savedgame, desc, kSvgDesc_UserImage); + if (!err) + return false; + + if (desc.UserImage.get()) { + int slot = spriteset.GetFreeIndex(); + if (slot > 0) { + // add it into the sprite set + add_dynamic_sprite(slot, ReplaceBitmapWithSupportedFormat(desc.UserImage.release())); + want_shot = slot; + } + } + return true; +} + +HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten) { + data_overwritten = false; + gameHasBeenRestored++; + + oldeip = our_eip; + our_eip = 2050; + + HSaveError err; + SavegameSource src; + SavegameDescription desc; + err = OpenSavegame(path, src, desc, kSvgDesc_EnvInfo); + + // saved in incompatible enviroment + if (!err) + return err; + // CHECKME: is this color depth test still essential? if yes, is there possible workaround? + else if (desc.ColorDepth != game.GetColorDepth()) + return new SavegameError(kSvgErr_DifferentColorDepth, String::FromFormat("Running: %d-bit, saved in: %d-bit.", game.GetColorDepth(), desc.ColorDepth)); + + // saved with different game file + if (Path::ComparePaths(desc.MainDataFilename, ResPaths.GamePak.Name)) { + // [IKM] 2012-11-26: this is a workaround, indeed. + // Try to find wanted game's executable; if it does not exist, + // continue loading savedgame in current game, and pray for the best + get_install_dir_path(gamefilenamebuf, desc.MainDataFilename); + if (Common::File::TestReadFile(gamefilenamebuf)) { + RunAGSGame(desc.MainDataFilename, 0, 0); + load_new_game_restore = slotNumber; + return HSaveError::None(); + } + Common::Debug::Printf(kDbgMsg_Warn, "WARNING: the saved game '%s' references game file '%s', but it cannot be found in the current directory. Trying to restore in the running game instead.", + path.GetCStr(), desc.MainDataFilename.GetCStr()); + } + + // do the actual restore + err = RestoreGameState(src.InputStream, src.Version); + data_overwritten = true; + if (!err) + return err; + src.InputStream.reset(); + our_eip = oldeip; + + // ensure keyboard buffer is clean + ags_clear_input_buffer(); + // call "After Restore" event callback + run_on_event(GE_RESTORE_GAME, RuntimeScriptValue().SetInt32(slotNumber)); + return HSaveError::None(); +} + +bool try_restore_save(int slot) { + return try_restore_save(get_save_game_path(slot), slot); +} + +bool try_restore_save(const Common::String &path, int slot) { + bool data_overwritten; + HSaveError err = load_game(path, slot, data_overwritten); + if (!err) { + String error = String::FromFormat("Unable to restore the saved game.\n%s", + err->FullMessage().GetCStr()); + // currently AGS cannot properly revert to stable state if some of the + // game data was released or overwritten by the data from save file, + // this is why we tell engine to shutdown if that happened. + if (data_overwritten) + quitprintf(error); + else + Display(error); + return false; + } + return true; +} + +bool is_in_cutscene() { + return play.in_cutscene > 0; +} + +CutsceneSkipStyle get_cutscene_skipstyle() { + return static_cast(play.in_cutscene); +} + +void start_skipping_cutscene() { + play.fast_forward = 1; + // if a drop-down icon bar is up, remove it as it will pause the game + if (ifacepopped >= 0) + remove_popup_interface(ifacepopped); + + // if a text message is currently displayed, remove it + if (is_text_overlay > 0) + remove_screen_overlay(OVER_TEXTMSG); + +} + +bool check_skip_cutscene_keypress(int kgn) { + + CutsceneSkipStyle skip = get_cutscene_skipstyle(); + if (skip == eSkipSceneAnyKey || skip == eSkipSceneKeyMouse || + (kgn == 27 && (skip == eSkipSceneEscOnly || skip == eSkipSceneEscOrRMB))) { + start_skipping_cutscene(); + return true; + } + return false; +} + +bool check_skip_cutscene_mclick(int mbut) { + CutsceneSkipStyle skip = get_cutscene_skipstyle(); + if (skip == eSkipSceneMouse || skip == eSkipSceneKeyMouse || + (mbut == RIGHT && skip == eSkipSceneEscOrRMB)) { + start_skipping_cutscene(); + return true; + } + return false; } // Helper functions used by StartCutscene/EndCutscene, but also // by SkipUntilCharacterStops void initialize_skippable_cutscene() { - play.end_cutscene_music = -1; + play.end_cutscene_music = -1; } void stop_fast_forwarding() { - // when the skipping of a cutscene comes to an end, update things - play.fast_forward = 0; - setpal(); - if (play.end_cutscene_music >= 0) - newmusic(play.end_cutscene_music); + // when the skipping of a cutscene comes to an end, update things + play.fast_forward = 0; + setpal(); + if (play.end_cutscene_music >= 0) + newmusic(play.end_cutscene_music); - { - AudioChannelsLock lock; + { + AudioChannelsLock lock; - // Restore actual volume of sounds - for (int aa = 0; aa <= MAX_SOUND_CHANNELS; aa++) - { - auto* ch = lock.GetChannelIfPlaying(aa); - if (ch) - { - ch->set_mute(false); - } - } - } // -- AudioChannelsLock + // Restore actual volume of sounds + for (int aa = 0; aa <= MAX_SOUND_CHANNELS; aa++) { + auto *ch = lock.GetChannelIfPlaying(aa); + if (ch) { + ch->set_mute(false); + } + } + } // -- AudioChannelsLock - update_music_volume(); + update_music_volume(); } // allowHotspot0 defines whether Hotspot 0 returns LOCTYPE_HOTSPOT // or whether it returns 0 -int __GetLocationType(int xxx,int yyy, int allowHotspot0) { - getloctype_index = 0; - // If it's not in ProcessClick, then return 0 when over a GUI - if ((GetGUIAt(xxx, yyy) >= 0) && (getloctype_throughgui == 0)) - return 0; - - getloctype_throughgui = 0; - - const int scrx = xxx; - const int scry = yyy; - VpPoint vpt = play.ScreenToRoomDivDown(xxx, yyy); - if (vpt.second < 0) - return 0; - xxx = vpt.first.X; - yyy = vpt.first.Y; - if ((xxx>=thisroom.Width) | (xxx<0) | (yyy<0) | (yyy>=thisroom.Height)) - return 0; - - // check characters, objects and walkbehinds, work out which is - // foremost visible to the player - int charat = is_pos_on_character(xxx,yyy); - int hsat = get_hotspot_at(xxx,yyy); - int objat = GetObjectIDAtScreen(scrx, scry); - - data_to_game_coords(&xxx, &yyy); - - int wbat = thisroom.WalkBehindMask->GetPixel(xxx, yyy); - - if (wbat <= 0) wbat = 0; - else wbat = croom->walkbehind_base[wbat]; - - int winner = 0; - // if it's an Ignore Walkbehinds object, then ignore the walkbehind - if ((objat >= 0) && ((objs[objat].flags & OBJF_NOWALKBEHINDS) != 0)) - wbat = 0; - if ((charat >= 0) && ((game.chars[charat].flags & CHF_NOWALKBEHINDS) != 0)) - wbat = 0; - - if ((charat >= 0) && (objat >= 0)) { - if ((wbat > obj_lowest_yp) && (wbat > char_lowest_yp)) - winner = LOCTYPE_HOTSPOT; - else if (obj_lowest_yp > char_lowest_yp) - winner = LOCTYPE_OBJ; - else - winner = LOCTYPE_CHAR; - } - else if (charat >= 0) { - if (wbat > char_lowest_yp) - winner = LOCTYPE_HOTSPOT; - else - winner = LOCTYPE_CHAR; - } - else if (objat >= 0) { - if (wbat > obj_lowest_yp) - winner = LOCTYPE_HOTSPOT; - else - winner = LOCTYPE_OBJ; - } - - if (winner == 0) { - if (hsat >= 0) - winner = LOCTYPE_HOTSPOT; - } - - if ((winner == LOCTYPE_HOTSPOT) && (!allowHotspot0) && (hsat == 0)) - winner = 0; - - if (winner == LOCTYPE_HOTSPOT) - getloctype_index = hsat; - else if (winner == LOCTYPE_CHAR) - getloctype_index = charat; - else if (winner == LOCTYPE_OBJ) - getloctype_index = objat; - - return winner; +int __GetLocationType(int xxx, int yyy, int allowHotspot0) { + getloctype_index = 0; + // If it's not in ProcessClick, then return 0 when over a GUI + if ((GetGUIAt(xxx, yyy) >= 0) && (getloctype_throughgui == 0)) + return 0; + + getloctype_throughgui = 0; + + const int scrx = xxx; + const int scry = yyy; + VpPoint vpt = play.ScreenToRoomDivDown(xxx, yyy); + if (vpt.second < 0) + return 0; + xxx = vpt.first.X; + yyy = vpt.first.Y; + if ((xxx >= thisroom.Width) | (xxx < 0) | (yyy < 0) | (yyy >= thisroom.Height)) + return 0; + + // check characters, objects and walkbehinds, work out which is + // foremost visible to the player + int charat = is_pos_on_character(xxx, yyy); + int hsat = get_hotspot_at(xxx, yyy); + int objat = GetObjectIDAtScreen(scrx, scry); + + data_to_game_coords(&xxx, &yyy); + + int wbat = thisroom.WalkBehindMask->GetPixel(xxx, yyy); + + if (wbat <= 0) wbat = 0; + else wbat = croom->walkbehind_base[wbat]; + + int winner = 0; + // if it's an Ignore Walkbehinds object, then ignore the walkbehind + if ((objat >= 0) && ((objs[objat].flags & OBJF_NOWALKBEHINDS) != 0)) + wbat = 0; + if ((charat >= 0) && ((game.chars[charat].flags & CHF_NOWALKBEHINDS) != 0)) + wbat = 0; + + if ((charat >= 0) && (objat >= 0)) { + if ((wbat > obj_lowest_yp) && (wbat > char_lowest_yp)) + winner = LOCTYPE_HOTSPOT; + else if (obj_lowest_yp > char_lowest_yp) + winner = LOCTYPE_OBJ; + else + winner = LOCTYPE_CHAR; + } else if (charat >= 0) { + if (wbat > char_lowest_yp) + winner = LOCTYPE_HOTSPOT; + else + winner = LOCTYPE_CHAR; + } else if (objat >= 0) { + if (wbat > obj_lowest_yp) + winner = LOCTYPE_HOTSPOT; + else + winner = LOCTYPE_OBJ; + } + + if (winner == 0) { + if (hsat >= 0) + winner = LOCTYPE_HOTSPOT; + } + + if ((winner == LOCTYPE_HOTSPOT) && (!allowHotspot0) && (hsat == 0)) + winner = 0; + + if (winner == LOCTYPE_HOTSPOT) + getloctype_index = hsat; + else if (winner == LOCTYPE_CHAR) + getloctype_index = charat; + else if (winner == LOCTYPE_OBJ) + getloctype_index = objat; + + return winner; } // Called whenever game looses input focus -void display_switch_out() -{ - switched_away = true; - ags_clear_input_buffer(); - // Always unlock mouse when switching out from the game - Mouse::UnlockFromWindow(); - platform->DisplaySwitchOut(); - platform->ExitFullscreenMode(); +void display_switch_out() { + switched_away = true; + ags_clear_input_buffer(); + // Always unlock mouse when switching out from the game + Mouse::UnlockFromWindow(); + platform->DisplaySwitchOut(); + platform->ExitFullscreenMode(); } -void display_switch_out_suspend() -{ - // this is only called if in SWITCH_PAUSE mode - //debug_script_warn("display_switch_out"); - display_switch_out(); +void display_switch_out_suspend() { + // this is only called if in SWITCH_PAUSE mode + //debug_script_warn("display_switch_out"); + display_switch_out(); - switching_away_from_game++; + switching_away_from_game++; - platform->PauseApplication(); + platform->PauseApplication(); - // allow background running temporarily to halt the sound - if (set_display_switch_mode(SWITCH_BACKGROUND) == -1) - set_display_switch_mode(SWITCH_BACKAMNESIA); + // allow background running temporarily to halt the sound + if (set_display_switch_mode(SWITCH_BACKGROUND) == -1) + set_display_switch_mode(SWITCH_BACKAMNESIA); - { - // stop the sound stuttering - AudioChannelsLock lock; - for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { - auto* ch = lock.GetChannelIfPlaying(i); - if (ch) { - ch->pause(); - } - } - } // -- AudioChannelsLock + { + // stop the sound stuttering + AudioChannelsLock lock; + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if (ch) { + ch->pause(); + } + } + } // -- AudioChannelsLock - platform->Delay(1000); + platform->Delay(1000); - // restore the callbacks - SetMultitasking(0); + // restore the callbacks + SetMultitasking(0); - switching_away_from_game--; + switching_away_from_game--; } // Called whenever game gets input focus -void display_switch_in() -{ - switched_away = false; - if (gfxDriver) - { - DisplayMode mode = gfxDriver->GetDisplayMode(); - if (!mode.Windowed) - platform->EnterFullscreenMode(mode); - } - platform->DisplaySwitchIn(); - ags_clear_input_buffer(); - // If auto lock option is set, lock mouse to the game window - if (usetup.mouse_auto_lock && scsystem.windowed) - Mouse::TryLockToWindow(); -} - -void display_switch_in_resume() -{ - display_switch_in(); - - { - AudioChannelsLock lock; - for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { - auto* ch = lock.GetChannelIfPlaying(i); - if (ch) { - ch->resume(); - } - } - } // -- AudioChannelsLock - - // clear the screen if necessary - if (gfxDriver && gfxDriver->UsesMemoryBackBuffer()) - gfxDriver->ClearRectangle(0, 0, game.GetGameRes().Width - 1, game.GetGameRes().Height - 1, nullptr); - - platform->ResumeApplication(); -} - -void replace_tokens(const char*srcmes,char*destm, int maxlen) { - int indxdest=0,indxsrc=0; - const char*srcp; - char *destp; - while (srcmes[indxsrc]!=0) { - srcp=&srcmes[indxsrc]; - destp=&destm[indxdest]; - if ((strncmp(srcp,"@IN",3)==0) | (strncmp(srcp,"@GI",3)==0)) { - int tokentype=0; - if (srcp[1]=='I') tokentype=1; - else tokentype=2; - int inx=atoi(&srcp[3]); - srcp++; - indxsrc+=2; - while (srcp[0]!='@') { - if (srcp[0]==0) quit("!Display: special token not terminated"); - srcp++; - indxsrc++; - } - char tval[10]; - if (tokentype==1) { - if ((inx<1) | (inx>=game.numinvitems)) - quit("!Display: invalid inv item specified in @IN@"); - snprintf(tval,sizeof(tval),"%d",playerchar->inv[inx]); - } - else { - if ((inx<0) | (inx>=MAXGSVALUES)) - quit("!Display: invalid global int index speicifed in @GI@"); - snprintf(tval,sizeof(tval),"%d",GetGlobalInt(inx)); - } - strcpy(destp,tval); - indxdest+=strlen(tval); - } - else { - destp[0]=srcp[0]; - indxdest++; - indxsrc++; - } - if (indxdest >= maxlen - 3) - break; - } - destm[indxdest]=0; -} - -const char *get_global_message (int msnum) { - if (game.messages[msnum-500] == nullptr) - return ""; - return get_translation(game.messages[msnum-500]); -} - -void get_message_text (int msnum, char *buffer, char giveErr) { - int maxlen = 9999; - if (!giveErr) - maxlen = MAX_MAXSTRLEN; - - if (msnum>=500) { - - if ((msnum >= MAXGLOBALMES + 500) || (game.messages[msnum-500]==nullptr)) { - if (giveErr) - quit("!DisplayGlobalMessage: message does not exist"); - buffer[0] = 0; - return; - } - buffer[0] = 0; - replace_tokens(get_translation(game.messages[msnum-500]), buffer, maxlen); - return; - } - else if (msnum < 0 || (size_t)msnum >= thisroom.MessageCount) { - if (giveErr) - quit("!DisplayMessage: Invalid message number to display"); - buffer[0] = 0; - return; - } - - buffer[0]=0; - replace_tokens(get_translation(thisroom.Messages[msnum]), buffer, maxlen); -} - -bool unserialize_audio_script_object(int index, const char *objectType, const char *serializedData, int dataSize) -{ - if (strcmp(objectType, "AudioChannel") == 0) - { - ccDynamicAudio.Unserialize(index, serializedData, dataSize); - } - else if (strcmp(objectType, "AudioClip") == 0) - { - ccDynamicAudioClip.Unserialize(index, serializedData, dataSize); - } - else - { - return false; - } - return true; +void display_switch_in() { + switched_away = false; + if (gfxDriver) { + DisplayMode mode = gfxDriver->GetDisplayMode(); + if (!mode.Windowed) + platform->EnterFullscreenMode(mode); + } + platform->DisplaySwitchIn(); + ags_clear_input_buffer(); + // If auto lock option is set, lock mouse to the game window + if (usetup.mouse_auto_lock && scsystem.windowed) + Mouse::TryLockToWindow(); +} + +void display_switch_in_resume() { + display_switch_in(); + + { + AudioChannelsLock lock; + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if (ch) { + ch->resume(); + } + } + } // -- AudioChannelsLock + + // clear the screen if necessary + if (gfxDriver && gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->ClearRectangle(0, 0, game.GetGameRes().Width - 1, game.GetGameRes().Height - 1, nullptr); + + platform->ResumeApplication(); +} + +void replace_tokens(const char *srcmes, char *destm, int maxlen) { + int indxdest = 0, indxsrc = 0; + const char *srcp; + char *destp; + while (srcmes[indxsrc] != 0) { + srcp = &srcmes[indxsrc]; + destp = &destm[indxdest]; + if ((strncmp(srcp, "@IN", 3) == 0) | (strncmp(srcp, "@GI", 3) == 0)) { + int tokentype = 0; + if (srcp[1] == 'I') tokentype = 1; + else tokentype = 2; + int inx = atoi(&srcp[3]); + srcp++; + indxsrc += 2; + while (srcp[0] != '@') { + if (srcp[0] == 0) quit("!Display: special token not terminated"); + srcp++; + indxsrc++; + } + char tval[10]; + if (tokentype == 1) { + if ((inx < 1) | (inx >= game.numinvitems)) + quit("!Display: invalid inv item specified in @IN@"); + snprintf(tval, sizeof(tval), "%d", playerchar->inv[inx]); + } else { + if ((inx < 0) | (inx >= MAXGSVALUES)) + quit("!Display: invalid global int index speicifed in @GI@"); + snprintf(tval, sizeof(tval), "%d", GetGlobalInt(inx)); + } + strcpy(destp, tval); + indxdest += strlen(tval); + } else { + destp[0] = srcp[0]; + indxdest++; + indxsrc++; + } + if (indxdest >= maxlen - 3) + break; + } + destm[indxdest] = 0; +} + +const char *get_global_message(int msnum) { + if (game.messages[msnum - 500] == nullptr) + return ""; + return get_translation(game.messages[msnum - 500]); +} + +void get_message_text(int msnum, char *buffer, char giveErr) { + int maxlen = 9999; + if (!giveErr) + maxlen = MAX_MAXSTRLEN; + + if (msnum >= 500) { + + if ((msnum >= MAXGLOBALMES + 500) || (game.messages[msnum - 500] == nullptr)) { + if (giveErr) + quit("!DisplayGlobalMessage: message does not exist"); + buffer[0] = 0; + return; + } + buffer[0] = 0; + replace_tokens(get_translation(game.messages[msnum - 500]), buffer, maxlen); + return; + } else if (msnum < 0 || (size_t)msnum >= thisroom.MessageCount) { + if (giveErr) + quit("!DisplayMessage: Invalid message number to display"); + buffer[0] = 0; + return; + } + + buffer[0] = 0; + replace_tokens(get_translation(thisroom.Messages[msnum]), buffer, maxlen); +} + +bool unserialize_audio_script_object(int index, const char *objectType, const char *serializedData, int dataSize) { + if (strcmp(objectType, "AudioChannel") == 0) { + ccDynamicAudio.Unserialize(index, serializedData, dataSize); + } else if (strcmp(objectType, "AudioClip") == 0) { + ccDynamicAudioClip.Unserialize(index, serializedData, dataSize); + } else { + return false; + } + return true; } //============================================================================= @@ -2118,436 +1940,380 @@ bool unserialize_audio_script_object(int index, const char *objectType, const ch #include "script/script_runtime.h" // int (int audioType); -RuntimeScriptValue Sc_Game_IsAudioPlaying(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(Game_IsAudioPlaying); +RuntimeScriptValue Sc_Game_IsAudioPlaying(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(Game_IsAudioPlaying); } // void (int audioType, int volumeDrop) -RuntimeScriptValue Sc_Game_SetAudioTypeSpeechVolumeDrop(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(Game_SetAudioTypeSpeechVolumeDrop); +RuntimeScriptValue Sc_Game_SetAudioTypeSpeechVolumeDrop(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(Game_SetAudioTypeSpeechVolumeDrop); } // void (int audioType, int volume, int changeType) -RuntimeScriptValue Sc_Game_SetAudioTypeVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(Game_SetAudioTypeVolume); +RuntimeScriptValue Sc_Game_SetAudioTypeVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(Game_SetAudioTypeVolume); } // void (int audioType) -RuntimeScriptValue Sc_Game_StopAudio(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(Game_StopAudio); +RuntimeScriptValue Sc_Game_StopAudio(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(Game_StopAudio); } // int (const char *newFilename) -RuntimeScriptValue Sc_Game_ChangeTranslation(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(Game_ChangeTranslation, const char); +RuntimeScriptValue Sc_Game_ChangeTranslation(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(Game_ChangeTranslation, const char); } // int (const char *token) -RuntimeScriptValue Sc_Game_DoOnceOnly(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(Game_DoOnceOnly, const char); +RuntimeScriptValue Sc_Game_DoOnceOnly(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(Game_DoOnceOnly, const char); } // int (int red, int grn, int blu) -RuntimeScriptValue Sc_Game_GetColorFromRGB(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT3(Game_GetColorFromRGB); +RuntimeScriptValue Sc_Game_GetColorFromRGB(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT3(Game_GetColorFromRGB); } // int (int viewNumber, int loopNumber) -RuntimeScriptValue Sc_Game_GetFrameCountForLoop(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(Game_GetFrameCountForLoop); +RuntimeScriptValue Sc_Game_GetFrameCountForLoop(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(Game_GetFrameCountForLoop); } // const char* (int x, int y) -RuntimeScriptValue Sc_Game_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(const char, myScriptStringImpl, Game_GetLocationName); +RuntimeScriptValue Sc_Game_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(const char, myScriptStringImpl, Game_GetLocationName); } // int (int viewNumber) -RuntimeScriptValue Sc_Game_GetLoopCountForView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(Game_GetLoopCountForView); +RuntimeScriptValue Sc_Game_GetLoopCountForView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(Game_GetLoopCountForView); } // int () -RuntimeScriptValue Sc_Game_GetMODPattern(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetMODPattern); +RuntimeScriptValue Sc_Game_GetMODPattern(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetMODPattern); } // int (int viewNumber, int loopNumber) -RuntimeScriptValue Sc_Game_GetRunNextSettingForLoop(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(Game_GetRunNextSettingForLoop); +RuntimeScriptValue Sc_Game_GetRunNextSettingForLoop(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(Game_GetRunNextSettingForLoop); } // const char* (int slnum) -RuntimeScriptValue Sc_Game_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetSaveSlotDescription); +RuntimeScriptValue Sc_Game_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetSaveSlotDescription); } // ScriptViewFrame* (int viewNumber, int loopNumber, int frame) -RuntimeScriptValue Sc_Game_GetViewFrame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT3(ScriptViewFrame, Game_GetViewFrame); +RuntimeScriptValue Sc_Game_GetViewFrame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT3(ScriptViewFrame, Game_GetViewFrame); } // const char* (const char *msg) -RuntimeScriptValue Sc_Game_InputBox(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Game_InputBox, const char); +RuntimeScriptValue Sc_Game_InputBox(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Game_InputBox, const char); } // int (const char *newFolder) -RuntimeScriptValue Sc_Game_SetSaveGameDirectory(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(Game_SetSaveGameDirectory, const char); +RuntimeScriptValue Sc_Game_SetSaveGameDirectory(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(Game_SetSaveGameDirectory, const char); } // void (int evenAmbient); -RuntimeScriptValue Sc_StopAllSounds(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(StopAllSounds); +RuntimeScriptValue Sc_StopAllSounds(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(StopAllSounds); } // int () -RuntimeScriptValue Sc_Game_GetCharacterCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetCharacterCount); +RuntimeScriptValue Sc_Game_GetCharacterCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetCharacterCount); } // int () -RuntimeScriptValue Sc_Game_GetDialogCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetDialogCount); +RuntimeScriptValue Sc_Game_GetDialogCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetDialogCount); } // const char *() -RuntimeScriptValue Sc_Game_GetFileName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetFileName); +RuntimeScriptValue Sc_Game_GetFileName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetFileName); } // int () -RuntimeScriptValue Sc_Game_GetFontCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetFontCount); +RuntimeScriptValue Sc_Game_GetFontCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetFontCount); } // const char* (int index) -RuntimeScriptValue Sc_Game_GetGlobalMessages(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalMessages); +RuntimeScriptValue Sc_Game_GetGlobalMessages(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalMessages); } // const char* (int index) -RuntimeScriptValue Sc_Game_GetGlobalStrings(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalStrings); +RuntimeScriptValue Sc_Game_GetGlobalStrings(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalStrings); } // void (int index, char *newval); -RuntimeScriptValue Sc_SetGlobalString(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(SetGlobalString, const char); +RuntimeScriptValue Sc_SetGlobalString(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(SetGlobalString, const char); } // int () -RuntimeScriptValue Sc_Game_GetGUICount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetGUICount); +RuntimeScriptValue Sc_Game_GetGUICount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetGUICount); } // int () -RuntimeScriptValue Sc_Game_GetIgnoreUserInputAfterTextTimeoutMs(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetIgnoreUserInputAfterTextTimeoutMs); +RuntimeScriptValue Sc_Game_GetIgnoreUserInputAfterTextTimeoutMs(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetIgnoreUserInputAfterTextTimeoutMs); } // void (int newValueMs) -RuntimeScriptValue Sc_Game_SetIgnoreUserInputAfterTextTimeoutMs(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(Game_SetIgnoreUserInputAfterTextTimeoutMs); +RuntimeScriptValue Sc_Game_SetIgnoreUserInputAfterTextTimeoutMs(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(Game_SetIgnoreUserInputAfterTextTimeoutMs); } // int () -RuntimeScriptValue Sc_Game_GetInSkippableCutscene(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetInSkippableCutscene); +RuntimeScriptValue Sc_Game_GetInSkippableCutscene(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetInSkippableCutscene); } // int () -RuntimeScriptValue Sc_Game_GetInventoryItemCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetInventoryItemCount); +RuntimeScriptValue Sc_Game_GetInventoryItemCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetInventoryItemCount); } // int () -RuntimeScriptValue Sc_Game_GetMinimumTextDisplayTimeMs(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetMinimumTextDisplayTimeMs); +RuntimeScriptValue Sc_Game_GetMinimumTextDisplayTimeMs(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetMinimumTextDisplayTimeMs); } // void (int newTextMinTime) -RuntimeScriptValue Sc_Game_SetMinimumTextDisplayTimeMs(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(Game_SetMinimumTextDisplayTimeMs); +RuntimeScriptValue Sc_Game_SetMinimumTextDisplayTimeMs(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(Game_SetMinimumTextDisplayTimeMs); } // int () -RuntimeScriptValue Sc_Game_GetMouseCursorCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetMouseCursorCount); +RuntimeScriptValue Sc_Game_GetMouseCursorCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetMouseCursorCount); } // const char *() -RuntimeScriptValue Sc_Game_GetName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetName); +RuntimeScriptValue Sc_Game_GetName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetName); } // void (const char *newName) -RuntimeScriptValue Sc_Game_SetName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_POBJ(Game_SetName, const char); +RuntimeScriptValue Sc_Game_SetName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_POBJ(Game_SetName, const char); } // int () -RuntimeScriptValue Sc_Game_GetNormalFont(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetNormalFont); +RuntimeScriptValue Sc_Game_GetNormalFont(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetNormalFont); } // void (int fontnum); -RuntimeScriptValue Sc_SetNormalFont(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetNormalFont); +RuntimeScriptValue Sc_SetNormalFont(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetNormalFont); } // int () -RuntimeScriptValue Sc_Game_GetSkippingCutscene(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetSkippingCutscene); +RuntimeScriptValue Sc_Game_GetSkippingCutscene(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetSkippingCutscene); } // int () -RuntimeScriptValue Sc_Game_GetSpeechFont(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetSpeechFont); +RuntimeScriptValue Sc_Game_GetSpeechFont(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetSpeechFont); } // void (int fontnum); -RuntimeScriptValue Sc_SetSpeechFont(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetSpeechFont); +RuntimeScriptValue Sc_SetSpeechFont(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetSpeechFont); } // int (int spriteNum) -RuntimeScriptValue Sc_Game_GetSpriteWidth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(Game_GetSpriteWidth); +RuntimeScriptValue Sc_Game_GetSpriteWidth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(Game_GetSpriteWidth); } // int (int spriteNum) -RuntimeScriptValue Sc_Game_GetSpriteHeight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(Game_GetSpriteHeight); +RuntimeScriptValue Sc_Game_GetSpriteHeight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(Game_GetSpriteHeight); } // int () -RuntimeScriptValue Sc_Game_GetTextReadingSpeed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetTextReadingSpeed); +RuntimeScriptValue Sc_Game_GetTextReadingSpeed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetTextReadingSpeed); } // void (int newTextSpeed) -RuntimeScriptValue Sc_Game_SetTextReadingSpeed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(Game_SetTextReadingSpeed); +RuntimeScriptValue Sc_Game_SetTextReadingSpeed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(Game_SetTextReadingSpeed); } // const char* () -RuntimeScriptValue Sc_Game_GetTranslationFilename(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetTranslationFilename); +RuntimeScriptValue Sc_Game_GetTranslationFilename(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetTranslationFilename); } // int () -RuntimeScriptValue Sc_Game_GetUseNativeCoordinates(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetUseNativeCoordinates); +RuntimeScriptValue Sc_Game_GetUseNativeCoordinates(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetUseNativeCoordinates); } // int () -RuntimeScriptValue Sc_Game_GetViewCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetViewCount); -} - -RuntimeScriptValue Sc_Game_GetAudioClipCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(game.audioClips.size()); -} - -RuntimeScriptValue Sc_Game_GetAudioClip(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT(ScriptAudioClip, ccDynamicAudioClip, Game_GetAudioClip); -} - -RuntimeScriptValue Sc_Game_IsPluginLoaded(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_BOOL_OBJ(pl_is_plugin_loaded, const char); -} - -RuntimeScriptValue Sc_Game_PlayVoiceClip(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_POBJ_PINT_PBOOL(ScriptAudioChannel, ccDynamicAudio, PlayVoiceClip, CharacterInfo); -} - -RuntimeScriptValue Sc_Game_GetCamera(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO(ScriptCamera, Game_GetCamera); -} - -RuntimeScriptValue Sc_Game_GetCameraCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Game_GetCameraCount); -} - -RuntimeScriptValue Sc_Game_GetAnyCamera(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT(ScriptCamera, Game_GetAnyCamera); -} - -RuntimeScriptValue Sc_Game_SimulateKeyPress(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(Game_SimulateKeyPress); -} - -void RegisterGameAPI() -{ - ccAddExternalStaticFunction("Game::IsAudioPlaying^1", Sc_Game_IsAudioPlaying); - ccAddExternalStaticFunction("Game::SetAudioTypeSpeechVolumeDrop^2", Sc_Game_SetAudioTypeSpeechVolumeDrop); - ccAddExternalStaticFunction("Game::SetAudioTypeVolume^3", Sc_Game_SetAudioTypeVolume); - ccAddExternalStaticFunction("Game::StopAudio^1", Sc_Game_StopAudio); - ccAddExternalStaticFunction("Game::ChangeTranslation^1", Sc_Game_ChangeTranslation); - ccAddExternalStaticFunction("Game::DoOnceOnly^1", Sc_Game_DoOnceOnly); - ccAddExternalStaticFunction("Game::GetColorFromRGB^3", Sc_Game_GetColorFromRGB); - ccAddExternalStaticFunction("Game::GetFrameCountForLoop^2", Sc_Game_GetFrameCountForLoop); - ccAddExternalStaticFunction("Game::GetLocationName^2", Sc_Game_GetLocationName); - ccAddExternalStaticFunction("Game::GetLoopCountForView^1", Sc_Game_GetLoopCountForView); - ccAddExternalStaticFunction("Game::GetMODPattern^0", Sc_Game_GetMODPattern); - ccAddExternalStaticFunction("Game::GetRunNextSettingForLoop^2", Sc_Game_GetRunNextSettingForLoop); - ccAddExternalStaticFunction("Game::GetSaveSlotDescription^1", Sc_Game_GetSaveSlotDescription); - ccAddExternalStaticFunction("Game::GetViewFrame^3", Sc_Game_GetViewFrame); - ccAddExternalStaticFunction("Game::InputBox^1", Sc_Game_InputBox); - ccAddExternalStaticFunction("Game::SetSaveGameDirectory^1", Sc_Game_SetSaveGameDirectory); - ccAddExternalStaticFunction("Game::StopSound^1", Sc_StopAllSounds); - ccAddExternalStaticFunction("Game::get_CharacterCount", Sc_Game_GetCharacterCount); - ccAddExternalStaticFunction("Game::get_DialogCount", Sc_Game_GetDialogCount); - ccAddExternalStaticFunction("Game::get_FileName", Sc_Game_GetFileName); - ccAddExternalStaticFunction("Game::get_FontCount", Sc_Game_GetFontCount); - ccAddExternalStaticFunction("Game::geti_GlobalMessages", Sc_Game_GetGlobalMessages); - ccAddExternalStaticFunction("Game::geti_GlobalStrings", Sc_Game_GetGlobalStrings); - ccAddExternalStaticFunction("Game::seti_GlobalStrings", Sc_SetGlobalString); - ccAddExternalStaticFunction("Game::get_GUICount", Sc_Game_GetGUICount); - ccAddExternalStaticFunction("Game::get_IgnoreUserInputAfterTextTimeoutMs", Sc_Game_GetIgnoreUserInputAfterTextTimeoutMs); - ccAddExternalStaticFunction("Game::set_IgnoreUserInputAfterTextTimeoutMs", Sc_Game_SetIgnoreUserInputAfterTextTimeoutMs); - ccAddExternalStaticFunction("Game::get_InSkippableCutscene", Sc_Game_GetInSkippableCutscene); - ccAddExternalStaticFunction("Game::get_InventoryItemCount", Sc_Game_GetInventoryItemCount); - ccAddExternalStaticFunction("Game::get_MinimumTextDisplayTimeMs", Sc_Game_GetMinimumTextDisplayTimeMs); - ccAddExternalStaticFunction("Game::set_MinimumTextDisplayTimeMs", Sc_Game_SetMinimumTextDisplayTimeMs); - ccAddExternalStaticFunction("Game::get_MouseCursorCount", Sc_Game_GetMouseCursorCount); - ccAddExternalStaticFunction("Game::get_Name", Sc_Game_GetName); - ccAddExternalStaticFunction("Game::set_Name", Sc_Game_SetName); - ccAddExternalStaticFunction("Game::get_NormalFont", Sc_Game_GetNormalFont); - ccAddExternalStaticFunction("Game::set_NormalFont", Sc_SetNormalFont); - ccAddExternalStaticFunction("Game::get_SkippingCutscene", Sc_Game_GetSkippingCutscene); - ccAddExternalStaticFunction("Game::get_SpeechFont", Sc_Game_GetSpeechFont); - ccAddExternalStaticFunction("Game::set_SpeechFont", Sc_SetSpeechFont); - ccAddExternalStaticFunction("Game::geti_SpriteWidth", Sc_Game_GetSpriteWidth); - ccAddExternalStaticFunction("Game::geti_SpriteHeight", Sc_Game_GetSpriteHeight); - ccAddExternalStaticFunction("Game::get_TextReadingSpeed", Sc_Game_GetTextReadingSpeed); - ccAddExternalStaticFunction("Game::set_TextReadingSpeed", Sc_Game_SetTextReadingSpeed); - ccAddExternalStaticFunction("Game::get_TranslationFilename", Sc_Game_GetTranslationFilename); - ccAddExternalStaticFunction("Game::get_UseNativeCoordinates", Sc_Game_GetUseNativeCoordinates); - ccAddExternalStaticFunction("Game::get_ViewCount", Sc_Game_GetViewCount); - ccAddExternalStaticFunction("Game::get_AudioClipCount", Sc_Game_GetAudioClipCount); - ccAddExternalStaticFunction("Game::geti_AudioClips", Sc_Game_GetAudioClip); - ccAddExternalStaticFunction("Game::IsPluginLoaded", Sc_Game_IsPluginLoaded); - ccAddExternalStaticFunction("Game::PlayVoiceClip", Sc_Game_PlayVoiceClip); - ccAddExternalStaticFunction("Game::SimulateKeyPress", Sc_Game_SimulateKeyPress); - - ccAddExternalStaticFunction("Game::get_Camera", Sc_Game_GetCamera); - ccAddExternalStaticFunction("Game::get_CameraCount", Sc_Game_GetCameraCount); - ccAddExternalStaticFunction("Game::geti_Cameras", Sc_Game_GetAnyCamera); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Game::IsAudioPlaying^1", (void*)Game_IsAudioPlaying); - ccAddExternalFunctionForPlugin("Game::SetAudioTypeSpeechVolumeDrop^2", (void*)Game_SetAudioTypeSpeechVolumeDrop); - ccAddExternalFunctionForPlugin("Game::SetAudioTypeVolume^3", (void*)Game_SetAudioTypeVolume); - ccAddExternalFunctionForPlugin("Game::StopAudio^1", (void*)Game_StopAudio); - ccAddExternalFunctionForPlugin("Game::ChangeTranslation^1", (void*)Game_ChangeTranslation); - ccAddExternalFunctionForPlugin("Game::DoOnceOnly^1", (void*)Game_DoOnceOnly); - ccAddExternalFunctionForPlugin("Game::GetColorFromRGB^3", (void*)Game_GetColorFromRGB); - ccAddExternalFunctionForPlugin("Game::GetFrameCountForLoop^2", (void*)Game_GetFrameCountForLoop); - ccAddExternalFunctionForPlugin("Game::GetLocationName^2", (void*)Game_GetLocationName); - ccAddExternalFunctionForPlugin("Game::GetLoopCountForView^1", (void*)Game_GetLoopCountForView); - ccAddExternalFunctionForPlugin("Game::GetMODPattern^0", (void*)Game_GetMODPattern); - ccAddExternalFunctionForPlugin("Game::GetRunNextSettingForLoop^2", (void*)Game_GetRunNextSettingForLoop); - ccAddExternalFunctionForPlugin("Game::GetSaveSlotDescription^1", (void*)Game_GetSaveSlotDescription); - ccAddExternalFunctionForPlugin("Game::GetViewFrame^3", (void*)Game_GetViewFrame); - ccAddExternalFunctionForPlugin("Game::InputBox^1", (void*)Game_InputBox); - ccAddExternalFunctionForPlugin("Game::SetSaveGameDirectory^1", (void*)Game_SetSaveGameDirectory); - ccAddExternalFunctionForPlugin("Game::StopSound^1", (void*)StopAllSounds); - ccAddExternalFunctionForPlugin("Game::get_CharacterCount", (void*)Game_GetCharacterCount); - ccAddExternalFunctionForPlugin("Game::get_DialogCount", (void*)Game_GetDialogCount); - ccAddExternalFunctionForPlugin("Game::get_FileName", (void*)Game_GetFileName); - ccAddExternalFunctionForPlugin("Game::get_FontCount", (void*)Game_GetFontCount); - ccAddExternalFunctionForPlugin("Game::geti_GlobalMessages", (void*)Game_GetGlobalMessages); - ccAddExternalFunctionForPlugin("Game::geti_GlobalStrings", (void*)Game_GetGlobalStrings); - ccAddExternalFunctionForPlugin("Game::seti_GlobalStrings", (void*)SetGlobalString); - ccAddExternalFunctionForPlugin("Game::get_GUICount", (void*)Game_GetGUICount); - ccAddExternalFunctionForPlugin("Game::get_IgnoreUserInputAfterTextTimeoutMs", (void*)Game_GetIgnoreUserInputAfterTextTimeoutMs); - ccAddExternalFunctionForPlugin("Game::set_IgnoreUserInputAfterTextTimeoutMs", (void*)Game_SetIgnoreUserInputAfterTextTimeoutMs); - ccAddExternalFunctionForPlugin("Game::get_InSkippableCutscene", (void*)Game_GetInSkippableCutscene); - ccAddExternalFunctionForPlugin("Game::get_InventoryItemCount", (void*)Game_GetInventoryItemCount); - ccAddExternalFunctionForPlugin("Game::get_MinimumTextDisplayTimeMs", (void*)Game_GetMinimumTextDisplayTimeMs); - ccAddExternalFunctionForPlugin("Game::set_MinimumTextDisplayTimeMs", (void*)Game_SetMinimumTextDisplayTimeMs); - ccAddExternalFunctionForPlugin("Game::get_MouseCursorCount", (void*)Game_GetMouseCursorCount); - ccAddExternalFunctionForPlugin("Game::get_Name", (void*)Game_GetName); - ccAddExternalFunctionForPlugin("Game::set_Name", (void*)Game_SetName); - ccAddExternalFunctionForPlugin("Game::get_NormalFont", (void*)Game_GetNormalFont); - ccAddExternalFunctionForPlugin("Game::set_NormalFont", (void*)SetNormalFont); - ccAddExternalFunctionForPlugin("Game::get_SkippingCutscene", (void*)Game_GetSkippingCutscene); - ccAddExternalFunctionForPlugin("Game::get_SpeechFont", (void*)Game_GetSpeechFont); - ccAddExternalFunctionForPlugin("Game::set_SpeechFont", (void*)SetSpeechFont); - ccAddExternalFunctionForPlugin("Game::geti_SpriteWidth", (void*)Game_GetSpriteWidth); - ccAddExternalFunctionForPlugin("Game::geti_SpriteHeight", (void*)Game_GetSpriteHeight); - ccAddExternalFunctionForPlugin("Game::get_TextReadingSpeed", (void*)Game_GetTextReadingSpeed); - ccAddExternalFunctionForPlugin("Game::set_TextReadingSpeed", (void*)Game_SetTextReadingSpeed); - ccAddExternalFunctionForPlugin("Game::get_TranslationFilename", (void*)Game_GetTranslationFilename); - ccAddExternalFunctionForPlugin("Game::get_UseNativeCoordinates", (void*)Game_GetUseNativeCoordinates); - ccAddExternalFunctionForPlugin("Game::get_ViewCount", (void*)Game_GetViewCount); - ccAddExternalFunctionForPlugin("Game::PlayVoiceClip", (void*)PlayVoiceClip); -} - -void RegisterStaticObjects() -{ - ccAddExternalStaticObject("game",&play, &GameStaticManager); - ccAddExternalStaticObject("gs_globals",&play.globalvars[0], &GlobalStaticManager); - ccAddExternalStaticObject("mouse",&scmouse, &GlobalStaticManager); - ccAddExternalStaticObject("palette",&palette[0], &GlobalStaticManager); - ccAddExternalStaticObject("system",&scsystem, &GlobalStaticManager); - ccAddExternalStaticObject("savegameindex",&play.filenumbers[0], &GlobalStaticManager); +RuntimeScriptValue Sc_Game_GetViewCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetViewCount); +} + +RuntimeScriptValue Sc_Game_GetAudioClipCount(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(game.audioClips.size()); +} + +RuntimeScriptValue Sc_Game_GetAudioClip(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT(ScriptAudioClip, ccDynamicAudioClip, Game_GetAudioClip); +} + +RuntimeScriptValue Sc_Game_IsPluginLoaded(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_BOOL_OBJ(pl_is_plugin_loaded, const char); +} + +RuntimeScriptValue Sc_Game_PlayVoiceClip(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_POBJ_PINT_PBOOL(ScriptAudioChannel, ccDynamicAudio, PlayVoiceClip, CharacterInfo); +} + +RuntimeScriptValue Sc_Game_GetCamera(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO(ScriptCamera, Game_GetCamera); +} + +RuntimeScriptValue Sc_Game_GetCameraCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Game_GetCameraCount); +} + +RuntimeScriptValue Sc_Game_GetAnyCamera(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT(ScriptCamera, Game_GetAnyCamera); +} + +RuntimeScriptValue Sc_Game_SimulateKeyPress(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(Game_SimulateKeyPress); +} + +void RegisterGameAPI() { + ccAddExternalStaticFunction("Game::IsAudioPlaying^1", Sc_Game_IsAudioPlaying); + ccAddExternalStaticFunction("Game::SetAudioTypeSpeechVolumeDrop^2", Sc_Game_SetAudioTypeSpeechVolumeDrop); + ccAddExternalStaticFunction("Game::SetAudioTypeVolume^3", Sc_Game_SetAudioTypeVolume); + ccAddExternalStaticFunction("Game::StopAudio^1", Sc_Game_StopAudio); + ccAddExternalStaticFunction("Game::ChangeTranslation^1", Sc_Game_ChangeTranslation); + ccAddExternalStaticFunction("Game::DoOnceOnly^1", Sc_Game_DoOnceOnly); + ccAddExternalStaticFunction("Game::GetColorFromRGB^3", Sc_Game_GetColorFromRGB); + ccAddExternalStaticFunction("Game::GetFrameCountForLoop^2", Sc_Game_GetFrameCountForLoop); + ccAddExternalStaticFunction("Game::GetLocationName^2", Sc_Game_GetLocationName); + ccAddExternalStaticFunction("Game::GetLoopCountForView^1", Sc_Game_GetLoopCountForView); + ccAddExternalStaticFunction("Game::GetMODPattern^0", Sc_Game_GetMODPattern); + ccAddExternalStaticFunction("Game::GetRunNextSettingForLoop^2", Sc_Game_GetRunNextSettingForLoop); + ccAddExternalStaticFunction("Game::GetSaveSlotDescription^1", Sc_Game_GetSaveSlotDescription); + ccAddExternalStaticFunction("Game::GetViewFrame^3", Sc_Game_GetViewFrame); + ccAddExternalStaticFunction("Game::InputBox^1", Sc_Game_InputBox); + ccAddExternalStaticFunction("Game::SetSaveGameDirectory^1", Sc_Game_SetSaveGameDirectory); + ccAddExternalStaticFunction("Game::StopSound^1", Sc_StopAllSounds); + ccAddExternalStaticFunction("Game::get_CharacterCount", Sc_Game_GetCharacterCount); + ccAddExternalStaticFunction("Game::get_DialogCount", Sc_Game_GetDialogCount); + ccAddExternalStaticFunction("Game::get_FileName", Sc_Game_GetFileName); + ccAddExternalStaticFunction("Game::get_FontCount", Sc_Game_GetFontCount); + ccAddExternalStaticFunction("Game::geti_GlobalMessages", Sc_Game_GetGlobalMessages); + ccAddExternalStaticFunction("Game::geti_GlobalStrings", Sc_Game_GetGlobalStrings); + ccAddExternalStaticFunction("Game::seti_GlobalStrings", Sc_SetGlobalString); + ccAddExternalStaticFunction("Game::get_GUICount", Sc_Game_GetGUICount); + ccAddExternalStaticFunction("Game::get_IgnoreUserInputAfterTextTimeoutMs", Sc_Game_GetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalStaticFunction("Game::set_IgnoreUserInputAfterTextTimeoutMs", Sc_Game_SetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalStaticFunction("Game::get_InSkippableCutscene", Sc_Game_GetInSkippableCutscene); + ccAddExternalStaticFunction("Game::get_InventoryItemCount", Sc_Game_GetInventoryItemCount); + ccAddExternalStaticFunction("Game::get_MinimumTextDisplayTimeMs", Sc_Game_GetMinimumTextDisplayTimeMs); + ccAddExternalStaticFunction("Game::set_MinimumTextDisplayTimeMs", Sc_Game_SetMinimumTextDisplayTimeMs); + ccAddExternalStaticFunction("Game::get_MouseCursorCount", Sc_Game_GetMouseCursorCount); + ccAddExternalStaticFunction("Game::get_Name", Sc_Game_GetName); + ccAddExternalStaticFunction("Game::set_Name", Sc_Game_SetName); + ccAddExternalStaticFunction("Game::get_NormalFont", Sc_Game_GetNormalFont); + ccAddExternalStaticFunction("Game::set_NormalFont", Sc_SetNormalFont); + ccAddExternalStaticFunction("Game::get_SkippingCutscene", Sc_Game_GetSkippingCutscene); + ccAddExternalStaticFunction("Game::get_SpeechFont", Sc_Game_GetSpeechFont); + ccAddExternalStaticFunction("Game::set_SpeechFont", Sc_SetSpeechFont); + ccAddExternalStaticFunction("Game::geti_SpriteWidth", Sc_Game_GetSpriteWidth); + ccAddExternalStaticFunction("Game::geti_SpriteHeight", Sc_Game_GetSpriteHeight); + ccAddExternalStaticFunction("Game::get_TextReadingSpeed", Sc_Game_GetTextReadingSpeed); + ccAddExternalStaticFunction("Game::set_TextReadingSpeed", Sc_Game_SetTextReadingSpeed); + ccAddExternalStaticFunction("Game::get_TranslationFilename", Sc_Game_GetTranslationFilename); + ccAddExternalStaticFunction("Game::get_UseNativeCoordinates", Sc_Game_GetUseNativeCoordinates); + ccAddExternalStaticFunction("Game::get_ViewCount", Sc_Game_GetViewCount); + ccAddExternalStaticFunction("Game::get_AudioClipCount", Sc_Game_GetAudioClipCount); + ccAddExternalStaticFunction("Game::geti_AudioClips", Sc_Game_GetAudioClip); + ccAddExternalStaticFunction("Game::IsPluginLoaded", Sc_Game_IsPluginLoaded); + ccAddExternalStaticFunction("Game::PlayVoiceClip", Sc_Game_PlayVoiceClip); + ccAddExternalStaticFunction("Game::SimulateKeyPress", Sc_Game_SimulateKeyPress); + + ccAddExternalStaticFunction("Game::get_Camera", Sc_Game_GetCamera); + ccAddExternalStaticFunction("Game::get_CameraCount", Sc_Game_GetCameraCount); + ccAddExternalStaticFunction("Game::geti_Cameras", Sc_Game_GetAnyCamera); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Game::IsAudioPlaying^1", (void *)Game_IsAudioPlaying); + ccAddExternalFunctionForPlugin("Game::SetAudioTypeSpeechVolumeDrop^2", (void *)Game_SetAudioTypeSpeechVolumeDrop); + ccAddExternalFunctionForPlugin("Game::SetAudioTypeVolume^3", (void *)Game_SetAudioTypeVolume); + ccAddExternalFunctionForPlugin("Game::StopAudio^1", (void *)Game_StopAudio); + ccAddExternalFunctionForPlugin("Game::ChangeTranslation^1", (void *)Game_ChangeTranslation); + ccAddExternalFunctionForPlugin("Game::DoOnceOnly^1", (void *)Game_DoOnceOnly); + ccAddExternalFunctionForPlugin("Game::GetColorFromRGB^3", (void *)Game_GetColorFromRGB); + ccAddExternalFunctionForPlugin("Game::GetFrameCountForLoop^2", (void *)Game_GetFrameCountForLoop); + ccAddExternalFunctionForPlugin("Game::GetLocationName^2", (void *)Game_GetLocationName); + ccAddExternalFunctionForPlugin("Game::GetLoopCountForView^1", (void *)Game_GetLoopCountForView); + ccAddExternalFunctionForPlugin("Game::GetMODPattern^0", (void *)Game_GetMODPattern); + ccAddExternalFunctionForPlugin("Game::GetRunNextSettingForLoop^2", (void *)Game_GetRunNextSettingForLoop); + ccAddExternalFunctionForPlugin("Game::GetSaveSlotDescription^1", (void *)Game_GetSaveSlotDescription); + ccAddExternalFunctionForPlugin("Game::GetViewFrame^3", (void *)Game_GetViewFrame); + ccAddExternalFunctionForPlugin("Game::InputBox^1", (void *)Game_InputBox); + ccAddExternalFunctionForPlugin("Game::SetSaveGameDirectory^1", (void *)Game_SetSaveGameDirectory); + ccAddExternalFunctionForPlugin("Game::StopSound^1", (void *)StopAllSounds); + ccAddExternalFunctionForPlugin("Game::get_CharacterCount", (void *)Game_GetCharacterCount); + ccAddExternalFunctionForPlugin("Game::get_DialogCount", (void *)Game_GetDialogCount); + ccAddExternalFunctionForPlugin("Game::get_FileName", (void *)Game_GetFileName); + ccAddExternalFunctionForPlugin("Game::get_FontCount", (void *)Game_GetFontCount); + ccAddExternalFunctionForPlugin("Game::geti_GlobalMessages", (void *)Game_GetGlobalMessages); + ccAddExternalFunctionForPlugin("Game::geti_GlobalStrings", (void *)Game_GetGlobalStrings); + ccAddExternalFunctionForPlugin("Game::seti_GlobalStrings", (void *)SetGlobalString); + ccAddExternalFunctionForPlugin("Game::get_GUICount", (void *)Game_GetGUICount); + ccAddExternalFunctionForPlugin("Game::get_IgnoreUserInputAfterTextTimeoutMs", (void *)Game_GetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalFunctionForPlugin("Game::set_IgnoreUserInputAfterTextTimeoutMs", (void *)Game_SetIgnoreUserInputAfterTextTimeoutMs); + ccAddExternalFunctionForPlugin("Game::get_InSkippableCutscene", (void *)Game_GetInSkippableCutscene); + ccAddExternalFunctionForPlugin("Game::get_InventoryItemCount", (void *)Game_GetInventoryItemCount); + ccAddExternalFunctionForPlugin("Game::get_MinimumTextDisplayTimeMs", (void *)Game_GetMinimumTextDisplayTimeMs); + ccAddExternalFunctionForPlugin("Game::set_MinimumTextDisplayTimeMs", (void *)Game_SetMinimumTextDisplayTimeMs); + ccAddExternalFunctionForPlugin("Game::get_MouseCursorCount", (void *)Game_GetMouseCursorCount); + ccAddExternalFunctionForPlugin("Game::get_Name", (void *)Game_GetName); + ccAddExternalFunctionForPlugin("Game::set_Name", (void *)Game_SetName); + ccAddExternalFunctionForPlugin("Game::get_NormalFont", (void *)Game_GetNormalFont); + ccAddExternalFunctionForPlugin("Game::set_NormalFont", (void *)SetNormalFont); + ccAddExternalFunctionForPlugin("Game::get_SkippingCutscene", (void *)Game_GetSkippingCutscene); + ccAddExternalFunctionForPlugin("Game::get_SpeechFont", (void *)Game_GetSpeechFont); + ccAddExternalFunctionForPlugin("Game::set_SpeechFont", (void *)SetSpeechFont); + ccAddExternalFunctionForPlugin("Game::geti_SpriteWidth", (void *)Game_GetSpriteWidth); + ccAddExternalFunctionForPlugin("Game::geti_SpriteHeight", (void *)Game_GetSpriteHeight); + ccAddExternalFunctionForPlugin("Game::get_TextReadingSpeed", (void *)Game_GetTextReadingSpeed); + ccAddExternalFunctionForPlugin("Game::set_TextReadingSpeed", (void *)Game_SetTextReadingSpeed); + ccAddExternalFunctionForPlugin("Game::get_TranslationFilename", (void *)Game_GetTranslationFilename); + ccAddExternalFunctionForPlugin("Game::get_UseNativeCoordinates", (void *)Game_GetUseNativeCoordinates); + ccAddExternalFunctionForPlugin("Game::get_ViewCount", (void *)Game_GetViewCount); + ccAddExternalFunctionForPlugin("Game::PlayVoiceClip", (void *)PlayVoiceClip); +} + +void RegisterStaticObjects() { + ccAddExternalStaticObject("game", &play, &GameStaticManager); + ccAddExternalStaticObject("gs_globals", &play.globalvars[0], &GlobalStaticManager); + ccAddExternalStaticObject("mouse", &scmouse, &GlobalStaticManager); + ccAddExternalStaticObject("palette", &palette[0], &GlobalStaticManager); + ccAddExternalStaticObject("system", &scsystem, &GlobalStaticManager); + ccAddExternalStaticObject("savegameindex", &play.filenumbers[0], &GlobalStaticManager); } diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h index a3e9b4cbee73..5466ead57ac0 100644 --- a/engines/ags/engine/ac/game.h +++ b/engines/ags/engine/ac/game.h @@ -34,7 +34,12 @@ #include "util/string.h" // Forward declaration -namespace AGS { namespace Common { class Bitmap; class Stream; } } +namespace AGS { +namespace Common { +class Bitmap; +class Stream; +} +} using namespace AGS; // FIXME later #define RAGMODE_PRESERVEGLOBALINT 1 @@ -55,15 +60,14 @@ using namespace AGS; // FIXME later #define GP_NUMINVITEMS 12 #define GP_ISFRAMEFLIPPED 13 -enum CutsceneSkipStyle -{ - kSkipSceneUndefined = 0, - eSkipSceneEscOnly = 1, - eSkipSceneAnyKey = 2, - eSkipSceneMouse = 3, - eSkipSceneKeyMouse = 4, - eSkipSceneEscOrRMB = 5, - eSkipSceneScriptOnly = 6 +enum CutsceneSkipStyle { + kSkipSceneUndefined = 0, + eSkipSceneEscOnly = 1, + eSkipSceneAnyKey = 2, + eSkipSceneMouse = 3, + eSkipSceneKeyMouse = 4, + eSkipSceneEscOrRMB = 5, + eSkipSceneScriptOnly = 6 }; //============================================================================= @@ -92,9 +96,9 @@ bool SetCustomSaveParent(const Common::String &path); // as a relative to system's user saves directory bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path = false); int Game_SetSaveGameDirectory(const char *newFolder); -const char* Game_GetSaveSlotDescription(int slnum); +const char *Game_GetSaveSlotDescription(int slnum); -const char* Game_GetGlobalStrings(int index); +const char *Game_GetGlobalStrings(int index); int Game_GetInventoryItemCount(); int Game_GetFontCount(); @@ -108,7 +112,7 @@ int Game_GetSpriteHeight(int spriteNum); int Game_GetLoopCountForView(int viewNumber); int Game_GetRunNextSettingForLoop(int viewNumber, int loopNumber); int Game_GetFrameCountForLoop(int viewNumber, int loopNumber); -ScriptViewFrame* Game_GetViewFrame(int viewNumber, int loopNumber, int frame); +ScriptViewFrame *Game_GetViewFrame(int viewNumber, int loopNumber, int frame); int Game_DoOnceOnly(const char *token); int Game_GetTextReadingSpeed(); @@ -125,15 +129,15 @@ int Game_GetSkippingCutscene(); int Game_GetInSkippableCutscene(); int Game_GetColorFromRGB(int red, int grn, int blu); -const char* Game_InputBox(const char *msg); -const char* Game_GetLocationName(int x, int y); +const char *Game_InputBox(const char *msg); +const char *Game_GetLocationName(int x, int y); -const char* Game_GetGlobalMessages(int index); +const char *Game_GetGlobalMessages(int index); int Game_GetSpeechFont(); int Game_GetNormalFont(); -const char* Game_GetTranslationFilename(); +const char *Game_GetTranslationFilename(); int Game_ChangeTranslation(const char *newFilename); //============================================================================= @@ -151,7 +155,7 @@ void save_game_dialog(); void free_do_once_tokens(); // Free all the memory associated with the game void unload_game_file(); -void save_game(int slotn, const char*descript); +void save_game(int slotn, const char *descript); bool read_savedgame_description(const Common::String &savedgame, Common::String &description); bool read_savedgame_screenshot(const Common::String &savedgame, int &want_shot); // Tries to restore saved game and displays an error on failure; if the error occured @@ -167,13 +171,13 @@ long write_screen_shot_for_vista(Common::Stream *out, Common::Bitmap *screenshot bool is_in_cutscene(); CutsceneSkipStyle get_cutscene_skipstyle(); -void start_skipping_cutscene (); +void start_skipping_cutscene(); bool check_skip_cutscene_keypress(int kgn); bool check_skip_cutscene_mclick(int mbut); void initialize_skippable_cutscene(); void stop_fast_forwarding(); -int __GetLocationType(int xxx,int yyy, int allowHotspot0); +int __GetLocationType(int xxx, int yyy, int allowHotspot0); // Called whenever game looses input focus void display_switch_out(); @@ -184,9 +188,9 @@ void display_switch_out_suspend(); // Called when the game gets input focus and should resume void display_switch_in_resume(); -void replace_tokens(const char*srcmes,char*destm, int maxlen = 99999); -const char *get_global_message (int msnum); -void get_message_text (int msnum, char *buffer, char giveErr = 1); +void replace_tokens(const char *srcmes, char *destm, int maxlen = 99999); +const char *get_global_message(int msnum); +void get_message_text(int msnum, char *buffer, char giveErr = 1); bool unserialize_audio_script_object(int index, const char *objectType, const char *serializedData, int dataSize); diff --git a/engines/ags/engine/ac/gamesetup.cpp b/engines/ags/engine/ac/gamesetup.cpp index 6dc749f38135..d33d4739e38f 100644 --- a/engines/ags/engine/ac/gamesetup.cpp +++ b/engines/ags/engine/ac/gamesetup.cpp @@ -23,31 +23,30 @@ #include "util/wgt2allg.h" // DIGI_AUTODETECT & MIDI_AUTODETECT #include "ac/gamesetup.h" -GameSetup::GameSetup() -{ - digicard=DIGI_AUTODETECT; - midicard=MIDI_AUTODETECT; - mod_player=1; - no_speech_pack = false; - textheight = 0; - enable_antialiasing = false; - disable_exception_handling = false; - mouse_auto_lock = false; - override_script_os = -1; - override_multitasking = -1; - override_upscale = false; - mouse_speed = 1.f; - mouse_ctrl_when = kMouseCtrl_Fullscreen; - mouse_ctrl_enabled = true; - mouse_speed_def = kMouseSpeed_CurrentDisplay; - RenderAtScreenRes = false; - Supersampling = 1; +GameSetup::GameSetup() { + digicard = DIGI_AUTODETECT; + midicard = MIDI_AUTODETECT; + mod_player = 1; + no_speech_pack = false; + textheight = 0; + enable_antialiasing = false; + disable_exception_handling = false; + mouse_auto_lock = false; + override_script_os = -1; + override_multitasking = -1; + override_upscale = false; + mouse_speed = 1.f; + mouse_ctrl_when = kMouseCtrl_Fullscreen; + mouse_ctrl_enabled = true; + mouse_speed_def = kMouseSpeed_CurrentDisplay; + RenderAtScreenRes = false; + Supersampling = 1; - Screen.DisplayMode.ScreenSize.MatchDeviceRatio = true; - Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_MaxDisplay; - Screen.DisplayMode.RefreshRate = 0; - Screen.DisplayMode.VSync = false; - Screen.DisplayMode.Windowed = false; - Screen.FsGameFrame = GameFrameSetup(kFrame_MaxProportional); - Screen.WinGameFrame = GameFrameSetup(kFrame_MaxRound); + Screen.DisplayMode.ScreenSize.MatchDeviceRatio = true; + Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_MaxDisplay; + Screen.DisplayMode.RefreshRate = 0; + Screen.DisplayMode.VSync = false; + Screen.DisplayMode.Windowed = false; + Screen.FsGameFrame = GameFrameSetup(kFrame_MaxProportional); + Screen.WinGameFrame = GameFrameSetup(kFrame_MaxRound); } diff --git a/engines/ags/engine/ac/gamesetup.h b/engines/ags/engine/ac/gamesetup.h index 9f204c624d2a..9bb46ca09912 100644 --- a/engines/ags/engine/ac/gamesetup.h +++ b/engines/ags/engine/ac/gamesetup.h @@ -28,20 +28,18 @@ // Mouse control activation type -enum MouseControlWhen -{ - kMouseCtrl_Never, // never control mouse (track system mouse position) - kMouseCtrl_Fullscreen, // control mouse in fullscreen only - kMouseCtrl_Always, // always control mouse (fullscreen and windowed) - kNumMouseCtrlOptions +enum MouseControlWhen { + kMouseCtrl_Never, // never control mouse (track system mouse position) + kMouseCtrl_Fullscreen, // control mouse in fullscreen only + kMouseCtrl_Always, // always control mouse (fullscreen and windowed) + kNumMouseCtrlOptions }; // Mouse speed definition, specifies how the speed setting is applied to the mouse movement -enum MouseSpeedDef -{ - kMouseSpeed_Absolute, // apply speed multiplier directly - kMouseSpeed_CurrentDisplay, // keep speed/resolution relation based on current system display mode - kNumMouseSpeedDefs +enum MouseSpeedDef { + kMouseSpeed_Absolute, // apply speed multiplier directly + kMouseSpeed_CurrentDisplay, // keep speed/resolution relation based on current system display mode + kNumMouseSpeedDefs }; using AGS::Common::String; @@ -54,36 +52,36 @@ using AGS::Common::String; // that engine may use a "config" object or combo of objects to store // current user config, which may also be changed from script, and saved. struct GameSetup { - int digicard; - int midicard; - int mod_player; - int textheight; // text height used on the certain built-in GUI // TODO: move out to game class? - bool no_speech_pack; - bool enable_antialiasing; - bool disable_exception_handling; - String data_files_dir; - String main_data_filename; - String main_data_filepath; - String install_dir; // optional custom install dir path - String install_audio_dir; // optional custom install audio dir path - String install_voice_dir; // optional custom install voice-over dir path - String user_data_dir; // directory to write savedgames and user files to - String shared_data_dir; // directory to write shared game files to - String translation; - bool mouse_auto_lock; - int override_script_os; - char override_multitasking; - bool override_upscale; - float mouse_speed; - MouseControlWhen mouse_ctrl_when; - bool mouse_ctrl_enabled; - MouseSpeedDef mouse_speed_def; - bool RenderAtScreenRes; // render sprites at screen resolution, as opposed to native one - int Supersampling; + int digicard; + int midicard; + int mod_player; + int textheight; // text height used on the certain built-in GUI // TODO: move out to game class? + bool no_speech_pack; + bool enable_antialiasing; + bool disable_exception_handling; + String data_files_dir; + String main_data_filename; + String main_data_filepath; + String install_dir; // optional custom install dir path + String install_audio_dir; // optional custom install audio dir path + String install_voice_dir; // optional custom install voice-over dir path + String user_data_dir; // directory to write savedgames and user files to + String shared_data_dir; // directory to write shared game files to + String translation; + bool mouse_auto_lock; + int override_script_os; + char override_multitasking; + bool override_upscale; + float mouse_speed; + MouseControlWhen mouse_ctrl_when; + bool mouse_ctrl_enabled; + MouseSpeedDef mouse_speed_def; + bool RenderAtScreenRes; // render sprites at screen resolution, as opposed to native one + int Supersampling; - ScreenSetup Screen; + ScreenSetup Screen; - GameSetup(); + GameSetup(); }; // TODO: setup object is used for two purposes: temporarily storing config diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index 0366ec5e686e..2837ec920227 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -47,898 +47,807 @@ extern RoomStruct thisroom; extern CharacterInfo *playerchar; extern ScriptSystem scsystem; -GameState::GameState() -{ - _isAutoRoomViewport = true; - _mainViewportHasChanged = false; +GameState::GameState() { + _isAutoRoomViewport = true; + _mainViewportHasChanged = false; } -void GameState::Free() -{ - raw_drawing_surface.reset(); - FreeProperties(); +void GameState::Free() { + raw_drawing_surface.reset(); + FreeProperties(); } -bool GameState::IsAutoRoomViewport() const -{ - return _isAutoRoomViewport; -} - -void GameState::SetAutoRoomViewport(bool on) -{ - _isAutoRoomViewport = on; -} +bool GameState::IsAutoRoomViewport() const { + return _isAutoRoomViewport; +} + +void GameState::SetAutoRoomViewport(bool on) { + _isAutoRoomViewport = on; +} + +void GameState::SetMainViewport(const Rect &viewport) { + _mainViewport.SetRect(viewport); + Mouse::SetGraphicArea(); + scsystem.viewport_width = game_to_data_coord(_mainViewport.GetRect().GetWidth()); + scsystem.viewport_height = game_to_data_coord(_mainViewport.GetRect().GetHeight()); + _mainViewportHasChanged = true; +} + +const Rect &GameState::GetMainViewport() const { + return _mainViewport.GetRect(); +} + +const Rect &GameState::GetUIViewport() const { + return _uiViewport.GetRect(); +} -void GameState::SetMainViewport(const Rect &viewport) -{ - _mainViewport.SetRect(viewport); - Mouse::SetGraphicArea(); - scsystem.viewport_width = game_to_data_coord(_mainViewport.GetRect().GetWidth()); - scsystem.viewport_height = game_to_data_coord(_mainViewport.GetRect().GetHeight()); - _mainViewportHasChanged = true; +PViewport GameState::GetRoomViewport(int index) const { + return _roomViewports[index]; } -const Rect &GameState::GetMainViewport() const -{ - return _mainViewport.GetRect(); +const std::vector &GameState::GetRoomViewportsZOrdered() const { + return _roomViewportsSorted; } -const Rect &GameState::GetUIViewport() const -{ - return _uiViewport.GetRect(); +PViewport GameState::GetRoomViewportAt(int x, int y) const { + // We iterate backwards, because in AGS low z-order means bottom + for (auto it = _roomViewportsSorted.rbegin(); it != _roomViewportsSorted.rend(); ++it) + if ((*it)->IsVisible() && (*it)->GetRect().IsInside(x, y)) + return *it; + return nullptr; } -PViewport GameState::GetRoomViewport(int index) const -{ - return _roomViewports[index]; +Rect GameState::GetUIViewportAbs() const { + return Rect::MoveBy(_uiViewport.GetRect(), _mainViewport.GetRect().Left, _mainViewport.GetRect().Top); } -const std::vector &GameState::GetRoomViewportsZOrdered() const -{ - return _roomViewportsSorted; -} - -PViewport GameState::GetRoomViewportAt(int x, int y) const -{ - // We iterate backwards, because in AGS low z-order means bottom - for (auto it = _roomViewportsSorted.rbegin(); it != _roomViewportsSorted.rend(); ++it) - if ((*it)->IsVisible() && (*it)->GetRect().IsInside(x, y)) - return *it; - return nullptr; -} - -Rect GameState::GetUIViewportAbs() const -{ - return Rect::MoveBy(_uiViewport.GetRect(), _mainViewport.GetRect().Left, _mainViewport.GetRect().Top); -} - -Rect GameState::GetRoomViewportAbs(int index) const -{ - return Rect::MoveBy(_roomViewports[index]->GetRect(), _mainViewport.GetRect().Left, _mainViewport.GetRect().Top); +Rect GameState::GetRoomViewportAbs(int index) const { + return Rect::MoveBy(_roomViewports[index]->GetRect(), _mainViewport.GetRect().Left, _mainViewport.GetRect().Top); } -void GameState::SetUIViewport(const Rect &viewport) -{ - _uiViewport.SetRect(viewport); +void GameState::SetUIViewport(const Rect &viewport) { + _uiViewport.SetRect(viewport); } -static bool ViewportZOrder(const PViewport e1, const PViewport e2) -{ - return e1->GetZOrder() < e2->GetZOrder(); +static bool ViewportZOrder(const PViewport e1, const PViewport e2) { + return e1->GetZOrder() < e2->GetZOrder(); } - -void GameState::UpdateViewports() -{ - if (_mainViewportHasChanged) - { - on_mainviewport_changed(); - _mainViewportHasChanged = false; - } - if (_roomViewportZOrderChanged) - { - auto old_sort = _roomViewportsSorted; - _roomViewportsSorted = _roomViewports; - std::sort(_roomViewportsSorted.begin(), _roomViewportsSorted.end(), ViewportZOrder); - for (size_t i = 0; i < _roomViewportsSorted.size(); ++i) - { - if (i >= old_sort.size() || _roomViewportsSorted[i] != old_sort[i]) - _roomViewportsSorted[i]->SetChangedVisible(); - } - _roomViewportZOrderChanged = false; - } - size_t vp_changed = -1; - for (size_t i = _roomViewportsSorted.size(); i-- > 0;) - { - auto vp = _roomViewportsSorted[i]; - if (vp->HasChangedSize() || vp->HasChangedPosition() || vp->HasChangedVisible()) - { - vp_changed = i; - on_roomviewport_changed(vp.get()); - vp->ClearChangedFlags(); - } - } - if (vp_changed != -1) - detect_roomviewport_overlaps(vp_changed); - for (auto cam : _roomCameras) - { - if (cam->HasChangedSize() || cam->HasChangedPosition()) - { - on_roomcamera_changed(cam.get()); - cam->ClearChangedFlags(); - } - } -} - -void GameState::InvalidateViewportZOrder() -{ - _roomViewportZOrderChanged = true; -} - -PCamera GameState::GetRoomCamera(int index) const -{ - return _roomCameras[index]; -} - -void GameState::UpdateRoomCameras() -{ - for (size_t i = 0; i < _roomCameras.size(); ++i) - UpdateRoomCamera(i); -} - -void GameState::UpdateRoomCamera(int index) -{ - auto cam = _roomCameras[index]; - const Rect &rc = cam->GetRect(); - const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); - if ((real_room_sz.Width > rc.GetWidth()) || (real_room_sz.Height > rc.GetHeight())) - { - // TODO: split out into Camera Behavior - if (!cam->IsLocked()) - { - int x = data_to_game_coord(playerchar->x) - rc.GetWidth() / 2; - int y = data_to_game_coord(playerchar->y) - rc.GetHeight() / 2; - cam->SetAt(x, y); - } - } - else - { - cam->SetAt(0, 0); - } -} - -Point GameState::RoomToScreen(int roomx, int roomy) -{ - return _roomViewports[0]->RoomToScreen(roomx, roomy, false).first; -} - -int GameState::RoomToScreenX(int roomx) -{ - return _roomViewports[0]->RoomToScreen(roomx, 0, false).first.X; -} - -int GameState::RoomToScreenY(int roomy) -{ - return _roomViewports[0]->RoomToScreen(0, roomy, false).first.Y; -} - -VpPoint GameState::ScreenToRoomImpl(int scrx, int scry, int view_index, bool clip_viewport, bool convert_cam_to_data) -{ - PViewport view; - if (view_index < 0) - { - view = GetRoomViewportAt(scrx, scry); - if (!view) - return std::make_pair(Point(), -1); - } - else - { - view = _roomViewports[view_index]; - } - return view->ScreenToRoom(scrx, scry, clip_viewport, convert_cam_to_data); -} - -VpPoint GameState::ScreenToRoom(int scrx, int scry) -{ - if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v3507) - return ScreenToRoomImpl(scrx, scry, -1, true, false); - return ScreenToRoomImpl(scrx, scry, 0, false, false); -} - -VpPoint GameState::ScreenToRoomDivDown(int scrx, int scry) -{ - if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v3507) - return ScreenToRoomImpl(scrx, scry, -1, true, true); - return ScreenToRoomImpl(scrx, scry, 0, false, true); -} - -void GameState::CreatePrimaryViewportAndCamera() -{ - if (_roomViewports.size() == 0) - { - play.CreateRoomViewport(); - play.RegisterRoomViewport(0); - } - if (_roomCameras.size() == 0) - { - play.CreateRoomCamera(); - play.RegisterRoomCamera(0); - } - _roomViewports[0]->LinkCamera(_roomCameras[0]); - _roomCameras[0]->LinkToViewport(_roomViewports[0]); -} - -PViewport GameState::CreateRoomViewport() -{ - int index = (int)_roomViewports.size(); - PViewport viewport(new Viewport()); - viewport->SetID(index); - viewport->SetRect(_mainViewport.GetRect()); - ScriptViewport *scv = new ScriptViewport(index); - _roomViewports.push_back(viewport); - _scViewportRefs.push_back(std::make_pair(scv, 0)); - _roomViewportsSorted.push_back(viewport); - _roomViewportZOrderChanged = true; - on_roomviewport_created(index); - return viewport; -} - -ScriptViewport *GameState::RegisterRoomViewport(int index, int32_t handle) -{ - if (index < 0 || (size_t)index >= _roomViewports.size()) - return nullptr; - auto &scobj = _scViewportRefs[index]; - if (handle == 0) - { - handle = ccRegisterManagedObject(scobj.first, scobj.first); - ccAddObjectReference(handle); // one reference for the GameState - } - else - { - ccRegisterUnserializedObject(handle, scobj.first, scobj.first); - } - scobj.second = handle; - return scobj.first; -} - -void GameState::DeleteRoomViewport(int index) -{ - // NOTE: viewport 0 can not be deleted - if (index <= 0 || (size_t)index >= _roomViewports.size()) - return; - auto scobj = _scViewportRefs[index]; - scobj.first->Invalidate(); - ccReleaseObjectReference(scobj.second); - auto cam = _roomViewports[index]->GetCamera(); - if (cam) - cam->UnlinkFromViewport(index); - _roomViewports.erase(_roomViewports.begin() + index); - _scViewportRefs.erase(_scViewportRefs.begin() + index); - for (size_t i = index; i < _roomViewports.size(); ++i) - { - _roomViewports[i]->SetID(i); - _scViewportRefs[i].first->SetID(i); - } - for (size_t i = 0; i < _roomViewportsSorted.size(); ++i) - { - if (_roomViewportsSorted[i]->GetID() == index) - { - _roomViewportsSorted.erase(_roomViewportsSorted.begin() + i); - break; - } - } - on_roomviewport_deleted(index); -} - -int GameState::GetRoomViewportCount() const -{ - return (int)_roomViewports.size(); -} - -PCamera GameState::CreateRoomCamera() -{ - int index = (int)_roomCameras.size(); - PCamera camera(new Camera()); - camera->SetID(index); - camera->SetAt(0, 0); - camera->SetSize(_mainViewport.GetRect().GetSize()); - ScriptCamera *scam = new ScriptCamera(index); - _scCameraRefs.push_back(std::make_pair(scam, 0)); - _roomCameras.push_back(camera); - return camera; -} - -ScriptCamera *GameState::RegisterRoomCamera(int index, int32_t handle) -{ - if (index < 0 || (size_t)index >= _roomCameras.size()) - return nullptr; - auto &scobj = _scCameraRefs[index]; - if (handle == 0) - { - handle = ccRegisterManagedObject(scobj.first, scobj.first); - ccAddObjectReference(handle); // one reference for the GameState - } - else - { - ccRegisterUnserializedObject(handle, scobj.first, scobj.first); - } - scobj.second = handle; - return scobj.first; -} - -void GameState::DeleteRoomCamera(int index) -{ - // NOTE: camera 0 can not be deleted - if (index <= 0 || (size_t)index >= _roomCameras.size()) - return; - auto scobj = _scCameraRefs[index]; - scobj.first->Invalidate(); - ccReleaseObjectReference(scobj.second); - for (auto& viewref : _roomCameras[index]->GetLinkedViewports()) - { - auto view = viewref.lock(); - if (view) - view->LinkCamera(nullptr); - } - _roomCameras.erase(_roomCameras.begin() + index); - _scCameraRefs.erase(_scCameraRefs.begin() + index); - for (size_t i = index; i < _roomCameras.size(); ++i) - { - _roomCameras[i]->SetID(i); - _scCameraRefs[i].first->SetID(i); - } -} - -int GameState::GetRoomCameraCount() const -{ - return (int)_roomCameras.size(); -} - -ScriptViewport *GameState::GetScriptViewport(int index) -{ - if (index < 0 || (size_t)index >= _roomViewports.size()) - return NULL; - return _scViewportRefs[index].first; -} - -ScriptCamera *GameState::GetScriptCamera(int index) -{ - if (index < 0 || (size_t)index >= _roomCameras.size()) - return NULL; - return _scCameraRefs[index].first; -} - -bool GameState::IsIgnoringInput() const -{ - return AGS_Clock::now() < _ignoreUserInputUntilTime; -} - -void GameState::SetIgnoreInput(int timeout_ms) -{ - if (AGS_Clock::now() + std::chrono::milliseconds(timeout_ms) > _ignoreUserInputUntilTime) - _ignoreUserInputUntilTime = AGS_Clock::now() + std::chrono::milliseconds(timeout_ms); -} - -void GameState::ClearIgnoreInput() -{ - _ignoreUserInputUntilTime = AGS_Clock::now(); -} - -bool GameState::IsBlockingVoiceSpeech() const -{ - return speech_has_voice && speech_voice_blocking; -} - -bool GameState::IsNonBlockingVoiceSpeech() const -{ - return speech_has_voice && !speech_voice_blocking; -} - -bool GameState::ShouldPlayVoiceSpeech() const -{ - return !play.fast_forward && - (play.want_speech >= 1) && (!ResPaths.SpeechPak.Name.IsEmpty()); -} - -void GameState::ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, RestoredData &r_data) -{ - const bool old_save = svg_ver < kGSSvgVersion_Initial; - score = in->ReadInt32(); - usedmode = in->ReadInt32(); - disabled_user_interface = in->ReadInt32(); - gscript_timer = in->ReadInt32(); - debug_mode = in->ReadInt32(); - in->ReadArrayOfInt32(globalvars, MAXGLOBALVARS); - messagetime = in->ReadInt32(); - usedinv = in->ReadInt32(); - inv_top = in->ReadInt32(); - inv_numdisp = in->ReadInt32(); - obsolete_inv_numorder = in->ReadInt32(); - inv_numinline = in->ReadInt32(); - text_speed = in->ReadInt32(); - sierra_inv_color = in->ReadInt32(); - talkanim_speed = in->ReadInt32(); - inv_item_wid = in->ReadInt32(); - inv_item_hit = in->ReadInt32(); - speech_text_shadow = in->ReadInt32(); - swap_portrait_side = in->ReadInt32(); - speech_textwindow_gui = in->ReadInt32(); - follow_change_room_timer = in->ReadInt32(); - totalscore = in->ReadInt32(); - skip_display = in->ReadInt32(); - no_multiloop_repeat = in->ReadInt32(); - roomscript_finished = in->ReadInt32(); - used_inv_on = in->ReadInt32(); - no_textbg_when_voice = in->ReadInt32(); - max_dialogoption_width = in->ReadInt32(); - no_hicolor_fadein = in->ReadInt32(); - bgspeech_game_speed = in->ReadInt32(); - bgspeech_stay_on_display = in->ReadInt32(); - unfactor_speech_from_textlength = in->ReadInt32(); - mp3_loop_before_end = in->ReadInt32(); - speech_music_drop = in->ReadInt32(); - in_cutscene = in->ReadInt32(); - fast_forward = in->ReadInt32(); - room_width = in->ReadInt32(); - room_height = in->ReadInt32(); - game_speed_modifier = in->ReadInt32(); - score_sound = in->ReadInt32(); - takeover_data = in->ReadInt32(); - replay_hotkey_unused = in->ReadInt32(); - dialog_options_x = in->ReadInt32(); - dialog_options_y = in->ReadInt32(); - narrator_speech = in->ReadInt32(); - ambient_sounds_persist = in->ReadInt32(); - lipsync_speed = in->ReadInt32(); - close_mouth_speech_time = in->ReadInt32(); - disable_antialiasing = in->ReadInt32(); - text_speed_modifier = in->ReadInt32(); - if (svg_ver < kGSSvgVersion_350) - text_align = ConvertLegacyScriptAlignment((LegacyScriptAlignment)in->ReadInt32()); - else - text_align = (HorAlignment)in->ReadInt32(); - speech_bubble_width = in->ReadInt32(); - min_dialogoption_width = in->ReadInt32(); - disable_dialog_parser = in->ReadInt32(); - anim_background_speed = in->ReadInt32(); // the setting for this room - top_bar_backcolor= in->ReadInt32(); - top_bar_textcolor = in->ReadInt32(); - top_bar_bordercolor = in->ReadInt32(); - top_bar_borderwidth = in->ReadInt32(); - top_bar_ypos = in->ReadInt32(); - screenshot_width = in->ReadInt32(); - screenshot_height = in->ReadInt32(); - top_bar_font = in->ReadInt32(); - if (svg_ver < kGSSvgVersion_350) - speech_text_align = ConvertLegacyScriptAlignment((LegacyScriptAlignment)in->ReadInt32()); - else - speech_text_align = (HorAlignment)in->ReadInt32(); - auto_use_walkto_points = in->ReadInt32(); - inventory_greys_out = in->ReadInt32(); - skip_speech_specific_key = in->ReadInt32(); - abort_key = in->ReadInt32(); - fade_to_red = in->ReadInt32(); - fade_to_green = in->ReadInt32(); - fade_to_blue = in->ReadInt32(); - show_single_dialog_option = in->ReadInt32(); - keep_screen_during_instant_transition = in->ReadInt32(); - read_dialog_option_colour = in->ReadInt32(); - stop_dialog_at_end = in->ReadInt32(); - speech_portrait_placement = in->ReadInt32(); - speech_portrait_x = in->ReadInt32(); - speech_portrait_y = in->ReadInt32(); - speech_display_post_time_ms = in->ReadInt32(); - dialog_options_highlight_color = in->ReadInt32(); - if (old_save) - in->ReadArrayOfInt32(reserved, GAME_STATE_RESERVED_INTS); - // ** up to here is referenced in the script "game." object - if (old_save) - { - in->ReadInt32(); // recording - in->ReadInt32(); // playback - in->ReadInt16(); // gamestep - } - randseed = in->ReadInt32(); // random seed - player_on_region = in->ReadInt32(); // player's current region - if (old_save) - in->ReadInt32(); // screen_is_faded_out - check_interaction_only = in->ReadInt32(); - bg_frame = in->ReadInt32(); - bg_anim_delay = in->ReadInt32(); // for animating backgrounds - music_vol_was = in->ReadInt32(); // before the volume drop - wait_counter = in->ReadInt16(); - mboundx1 = in->ReadInt16(); - mboundx2 = in->ReadInt16(); - mboundy1 = in->ReadInt16(); - mboundy2 = in->ReadInt16(); - fade_effect = in->ReadInt32(); - bg_frame_locked = in->ReadInt32(); - in->ReadArrayOfInt32(globalscriptvars, MAXGSVALUES); - cur_music_number = in->ReadInt32(); - music_repeat = in->ReadInt32(); - music_master_volume = in->ReadInt32(); - digital_master_volume = in->ReadInt32(); - in->Read(walkable_areas_on, MAX_WALK_AREAS+1); - screen_flipped = in->ReadInt16(); - if (svg_ver < kGSSvgVersion_3510) - { - short offsets_locked = in->ReadInt16(); - if (offsets_locked != 0) - r_data.Camera0_Flags = kSvgCamPosLocked; - } - entered_at_x = in->ReadInt32(); - entered_at_y = in->ReadInt32(); - entered_edge = in->ReadInt32(); - want_speech = in->ReadInt32(); - cant_skip_speech = in->ReadInt32(); - in->ReadArrayOfInt32(script_timers, MAX_TIMERS); - sound_volume = in->ReadInt32(); - speech_volume = in->ReadInt32(); - normal_font = in->ReadInt32(); - speech_font = in->ReadInt32(); - key_skip_wait = in->ReadInt8(); - swap_portrait_lastchar = in->ReadInt32(); - separate_music_lib = in->ReadInt32(); - in_conversation = in->ReadInt32(); - screen_tint = in->ReadInt32(); - num_parsed_words = in->ReadInt32(); - in->ReadArrayOfInt16( parsed_words, MAX_PARSED_WORDS); - in->Read( bad_parsed_word, 100); - raw_color = in->ReadInt32(); - if (old_save) - in->ReadArrayOfInt32(raw_modified, MAX_ROOM_BGFRAMES); - in->ReadArrayOfInt16( filenumbers, MAXSAVEGAMES); - if (old_save) - in->ReadInt32(); // room_changes - mouse_cursor_hidden = in->ReadInt32(); - silent_midi = in->ReadInt32(); - silent_midi_channel = in->ReadInt32(); - current_music_repeating = in->ReadInt32(); - shakesc_delay = in->ReadInt32(); - shakesc_amount = in->ReadInt32(); - shakesc_length = in->ReadInt32(); - rtint_red = in->ReadInt32(); - rtint_green = in->ReadInt32(); - rtint_blue = in->ReadInt32(); - rtint_level = in->ReadInt32(); - rtint_light = in->ReadInt32(); - if (!old_save || loaded_game_file_version >= kGameVersion_340_4) - rtint_enabled = in->ReadBool(); - else - rtint_enabled = rtint_level > 0; - end_cutscene_music = in->ReadInt32(); - skip_until_char_stops = in->ReadInt32(); - get_loc_name_last_time = in->ReadInt32(); - get_loc_name_save_cursor = in->ReadInt32(); - restore_cursor_mode_to = in->ReadInt32(); - restore_cursor_image_to = in->ReadInt32(); - music_queue_size = in->ReadInt16(); - in->ReadArrayOfInt16( music_queue, MAX_QUEUED_MUSIC); - new_music_queue_size = in->ReadInt16(); - if (!old_save) - { - for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) - { - new_music_queue[i].ReadFromFile(in); - } - } - - crossfading_out_channel = in->ReadInt16(); - crossfade_step = in->ReadInt16(); - crossfade_out_volume_per_step = in->ReadInt16(); - crossfade_initial_volume_out = in->ReadInt16(); - crossfading_in_channel = in->ReadInt16(); - crossfade_in_volume_per_step = in->ReadInt16(); - crossfade_final_volume_in = in->ReadInt16(); - - if (old_save) - ReadQueuedAudioItems_Aligned(in); - - in->Read(takeover_from, 50); - in->Read(playmp3file_name, PLAYMP3FILE_MAX_FILENAME_LEN); - in->Read(globalstrings, MAXGLOBALSTRINGS * MAX_MAXSTRLEN); - in->Read(lastParserEntry, MAX_MAXSTRLEN); - in->Read(game_name, 100); - ground_level_areas_disabled = in->ReadInt32(); - next_screen_transition = in->ReadInt32(); - in->ReadInt32(); // gamma_adjustment -- do not apply gamma level from savegame - temporarily_turned_off_character = in->ReadInt16(); - inv_backwards_compatibility = in->ReadInt16(); - if (old_save) - { - in->ReadInt32(); // gui_draw_order - in->ReadInt32(); // do_once_tokens; - } - int num_do_once_tokens = in->ReadInt32(); - do_once_tokens.resize(num_do_once_tokens); - if (!old_save) - { - for (int i = 0; i < num_do_once_tokens; ++i) - { - StrUtil::ReadString(do_once_tokens[i], in); - } - } - text_min_display_time_ms = in->ReadInt32(); - ignore_user_input_after_text_timeout_ms = in->ReadInt32(); - if (svg_ver < kGSSvgVersion_3509) - in->ReadInt32(); // ignore_user_input_until_time -- do not apply from savegame - if (old_save) - in->ReadArrayOfInt32(default_audio_type_volumes, MAX_AUDIO_TYPES); - if (svg_ver >= kGSSvgVersion_3509) - { - int voice_speech_flags = in->ReadInt32(); - speech_has_voice = voice_speech_flags != 0; - speech_voice_blocking = (voice_speech_flags & 0x02) != 0; - } -} - -void GameState::WriteForSavegame(Common::Stream *out) const -{ - // NOTE: following parameters are never saved: - // recording, playback, gamestep, screen_is_faded_out, room_changes - out->WriteInt32(score); - out->WriteInt32(usedmode); - out->WriteInt32(disabled_user_interface); - out->WriteInt32(gscript_timer); - out->WriteInt32(debug_mode); - out->WriteArrayOfInt32(globalvars, MAXGLOBALVARS); - out->WriteInt32(messagetime); - out->WriteInt32(usedinv); - out->WriteInt32(inv_top); - out->WriteInt32(inv_numdisp); - out->WriteInt32(obsolete_inv_numorder); - out->WriteInt32(inv_numinline); - out->WriteInt32(text_speed); - out->WriteInt32(sierra_inv_color); - out->WriteInt32(talkanim_speed); - out->WriteInt32(inv_item_wid); - out->WriteInt32(inv_item_hit); - out->WriteInt32(speech_text_shadow); - out->WriteInt32(swap_portrait_side); - out->WriteInt32(speech_textwindow_gui); - out->WriteInt32(follow_change_room_timer); - out->WriteInt32(totalscore); - out->WriteInt32(skip_display); - out->WriteInt32(no_multiloop_repeat); - out->WriteInt32(roomscript_finished); - out->WriteInt32(used_inv_on); - out->WriteInt32(no_textbg_when_voice); - out->WriteInt32(max_dialogoption_width); - out->WriteInt32(no_hicolor_fadein); - out->WriteInt32(bgspeech_game_speed); - out->WriteInt32(bgspeech_stay_on_display); - out->WriteInt32(unfactor_speech_from_textlength); - out->WriteInt32(mp3_loop_before_end); - out->WriteInt32(speech_music_drop); - out->WriteInt32(in_cutscene); - out->WriteInt32(fast_forward); - out->WriteInt32(room_width); - out->WriteInt32(room_height); - out->WriteInt32(game_speed_modifier); - out->WriteInt32(score_sound); - out->WriteInt32(takeover_data); - out->WriteInt32(replay_hotkey_unused); // StartRecording: not supported - out->WriteInt32(dialog_options_x); - out->WriteInt32(dialog_options_y); - out->WriteInt32(narrator_speech); - out->WriteInt32(ambient_sounds_persist); - out->WriteInt32(lipsync_speed); - out->WriteInt32(close_mouth_speech_time); - out->WriteInt32(disable_antialiasing); - out->WriteInt32(text_speed_modifier); - out->WriteInt32(text_align); - out->WriteInt32(speech_bubble_width); - out->WriteInt32(min_dialogoption_width); - out->WriteInt32(disable_dialog_parser); - out->WriteInt32(anim_background_speed); // the setting for this room - out->WriteInt32(top_bar_backcolor); - out->WriteInt32(top_bar_textcolor); - out->WriteInt32(top_bar_bordercolor); - out->WriteInt32(top_bar_borderwidth); - out->WriteInt32(top_bar_ypos); - out->WriteInt32(screenshot_width); - out->WriteInt32(screenshot_height); - out->WriteInt32(top_bar_font); - out->WriteInt32(speech_text_align); - out->WriteInt32(auto_use_walkto_points); - out->WriteInt32(inventory_greys_out); - out->WriteInt32(skip_speech_specific_key); - out->WriteInt32(abort_key); - out->WriteInt32(fade_to_red); - out->WriteInt32(fade_to_green); - out->WriteInt32(fade_to_blue); - out->WriteInt32(show_single_dialog_option); - out->WriteInt32(keep_screen_during_instant_transition); - out->WriteInt32(read_dialog_option_colour); - out->WriteInt32(stop_dialog_at_end); - out->WriteInt32(speech_portrait_placement); - out->WriteInt32(speech_portrait_x); - out->WriteInt32(speech_portrait_y); - out->WriteInt32(speech_display_post_time_ms); - out->WriteInt32(dialog_options_highlight_color); - // ** up to here is referenced in the script "game." object - out->WriteInt32(randseed); // random seed - out->WriteInt32( player_on_region); // player's current region - out->WriteInt32( check_interaction_only); - out->WriteInt32( bg_frame); - out->WriteInt32( bg_anim_delay); // for animating backgrounds - out->WriteInt32( music_vol_was); // before the volume drop - out->WriteInt16(wait_counter); - out->WriteInt16(mboundx1); - out->WriteInt16(mboundx2); - out->WriteInt16(mboundy1); - out->WriteInt16(mboundy2); - out->WriteInt32( fade_effect); - out->WriteInt32( bg_frame_locked); - out->WriteArrayOfInt32(globalscriptvars, MAXGSVALUES); - out->WriteInt32( cur_music_number); - out->WriteInt32( music_repeat); - out->WriteInt32( music_master_volume); - out->WriteInt32( digital_master_volume); - out->Write(walkable_areas_on, MAX_WALK_AREAS+1); - out->WriteInt16( screen_flipped); - out->WriteInt32( entered_at_x); - out->WriteInt32( entered_at_y); - out->WriteInt32( entered_edge); - out->WriteInt32( want_speech); - out->WriteInt32( cant_skip_speech); - out->WriteArrayOfInt32(script_timers, MAX_TIMERS); - out->WriteInt32( sound_volume); - out->WriteInt32( speech_volume); - out->WriteInt32( normal_font); - out->WriteInt32( speech_font); - out->WriteInt8( key_skip_wait); - out->WriteInt32( swap_portrait_lastchar); - out->WriteInt32( separate_music_lib); - out->WriteInt32( in_conversation); - out->WriteInt32( screen_tint); - out->WriteInt32( num_parsed_words); - out->WriteArrayOfInt16( parsed_words, MAX_PARSED_WORDS); - out->Write( bad_parsed_word, 100); - out->WriteInt32( raw_color); - out->WriteArrayOfInt16( filenumbers, MAXSAVEGAMES); - out->WriteInt32( mouse_cursor_hidden); - out->WriteInt32( silent_midi); - out->WriteInt32( silent_midi_channel); - out->WriteInt32( current_music_repeating); - out->WriteInt32( shakesc_delay); - out->WriteInt32( shakesc_amount); - out->WriteInt32( shakesc_length); - out->WriteInt32( rtint_red); - out->WriteInt32( rtint_green); - out->WriteInt32( rtint_blue); - out->WriteInt32( rtint_level); - out->WriteInt32( rtint_light); - out->WriteBool(rtint_enabled); - out->WriteInt32( end_cutscene_music); - out->WriteInt32( skip_until_char_stops); - out->WriteInt32( get_loc_name_last_time); - out->WriteInt32( get_loc_name_save_cursor); - out->WriteInt32( restore_cursor_mode_to); - out->WriteInt32( restore_cursor_image_to); - out->WriteInt16( music_queue_size); - out->WriteArrayOfInt16( music_queue, MAX_QUEUED_MUSIC); - out->WriteInt16(new_music_queue_size); - for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) - { - new_music_queue[i].WriteToFile(out); - } - - out->WriteInt16( crossfading_out_channel); - out->WriteInt16( crossfade_step); - out->WriteInt16( crossfade_out_volume_per_step); - out->WriteInt16( crossfade_initial_volume_out); - out->WriteInt16( crossfading_in_channel); - out->WriteInt16( crossfade_in_volume_per_step); - out->WriteInt16( crossfade_final_volume_in); - - out->Write(takeover_from, 50); - out->Write(playmp3file_name, PLAYMP3FILE_MAX_FILENAME_LEN); - out->Write(globalstrings, MAXGLOBALSTRINGS * MAX_MAXSTRLEN); - out->Write(lastParserEntry, MAX_MAXSTRLEN); - out->Write(game_name, 100); - out->WriteInt32( ground_level_areas_disabled); - out->WriteInt32( next_screen_transition); - out->WriteInt32( gamma_adjustment); - out->WriteInt16(temporarily_turned_off_character); - out->WriteInt16(inv_backwards_compatibility); - out->WriteInt32(do_once_tokens.size()); - for (int i = 0; i < (int)do_once_tokens.size(); ++i) - { - StrUtil::WriteString(do_once_tokens[i], out); - } - out->WriteInt32( text_min_display_time_ms); - out->WriteInt32( ignore_user_input_after_text_timeout_ms); - - int voice_speech_flags = speech_has_voice ? 0x01 : 0; - if (speech_voice_blocking) - voice_speech_flags |= 0x02; - out->WriteInt32(voice_speech_flags); -} - -void GameState::ReadQueuedAudioItems_Aligned(Common::Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) - { - new_music_queue[i].ReadFromFile(&align_s); - align_s.Reset(); - } -} - -void GameState::FreeProperties() -{ - for (auto &p : charProps) - p.clear(); - for (auto &p : invProps) - p.clear(); -} - -void GameState::FreeViewportsAndCameras() -{ - _roomViewports.clear(); - _roomViewportsSorted.clear(); - for (auto &scobj : _scViewportRefs) - { - scobj.first->Invalidate(); - ccReleaseObjectReference(scobj.second); - } - _scViewportRefs.clear(); - _roomCameras.clear(); - for (auto &scobj : _scCameraRefs) - { - scobj.first->Invalidate(); - ccReleaseObjectReference(scobj.second); - } - _scCameraRefs.clear(); -} - -void GameState::ReadCustomProperties_v340(Common::Stream *in) -{ - if (loaded_game_file_version >= kGameVersion_340_4) - { - // After runtime property values were read we also copy missing default, - // because we do not keep defaults in the saved game, and also in case - // this save is made by an older game version which had different - // properties. - for (int i = 0; i < game.numcharacters; ++i) - Properties::ReadValues(charProps[i], in); - for (int i = 0; i < game.numinvitems; ++i) - Properties::ReadValues(invProps[i], in); - } -} - -void GameState::WriteCustomProperties_v340(Common::Stream *out) const -{ - if (loaded_game_file_version >= kGameVersion_340_4) - { - // We temporarily remove properties that kept default values - // just for the saving data time to avoid getting lots of - // redundant data into saved games - for (int i = 0; i < game.numcharacters; ++i) - Properties::WriteValues(charProps[i], out); - for (int i = 0; i < game.numinvitems; ++i) - Properties::WriteValues(invProps[i], out); - } + +void GameState::UpdateViewports() { + if (_mainViewportHasChanged) { + on_mainviewport_changed(); + _mainViewportHasChanged = false; + } + if (_roomViewportZOrderChanged) { + auto old_sort = _roomViewportsSorted; + _roomViewportsSorted = _roomViewports; + std::sort(_roomViewportsSorted.begin(), _roomViewportsSorted.end(), ViewportZOrder); + for (size_t i = 0; i < _roomViewportsSorted.size(); ++i) { + if (i >= old_sort.size() || _roomViewportsSorted[i] != old_sort[i]) + _roomViewportsSorted[i]->SetChangedVisible(); + } + _roomViewportZOrderChanged = false; + } + size_t vp_changed = -1; + for (size_t i = _roomViewportsSorted.size(); i-- > 0;) { + auto vp = _roomViewportsSorted[i]; + if (vp->HasChangedSize() || vp->HasChangedPosition() || vp->HasChangedVisible()) { + vp_changed = i; + on_roomviewport_changed(vp.get()); + vp->ClearChangedFlags(); + } + } + if (vp_changed != -1) + detect_roomviewport_overlaps(vp_changed); + for (auto cam : _roomCameras) { + if (cam->HasChangedSize() || cam->HasChangedPosition()) { + on_roomcamera_changed(cam.get()); + cam->ClearChangedFlags(); + } + } +} + +void GameState::InvalidateViewportZOrder() { + _roomViewportZOrderChanged = true; +} + +PCamera GameState::GetRoomCamera(int index) const { + return _roomCameras[index]; +} + +void GameState::UpdateRoomCameras() { + for (size_t i = 0; i < _roomCameras.size(); ++i) + UpdateRoomCamera(i); +} + +void GameState::UpdateRoomCamera(int index) { + auto cam = _roomCameras[index]; + const Rect &rc = cam->GetRect(); + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + if ((real_room_sz.Width > rc.GetWidth()) || (real_room_sz.Height > rc.GetHeight())) { + // TODO: split out into Camera Behavior + if (!cam->IsLocked()) { + int x = data_to_game_coord(playerchar->x) - rc.GetWidth() / 2; + int y = data_to_game_coord(playerchar->y) - rc.GetHeight() / 2; + cam->SetAt(x, y); + } + } else { + cam->SetAt(0, 0); + } +} + +Point GameState::RoomToScreen(int roomx, int roomy) { + return _roomViewports[0]->RoomToScreen(roomx, roomy, false).first; +} + +int GameState::RoomToScreenX(int roomx) { + return _roomViewports[0]->RoomToScreen(roomx, 0, false).first.X; +} + +int GameState::RoomToScreenY(int roomy) { + return _roomViewports[0]->RoomToScreen(0, roomy, false).first.Y; +} + +VpPoint GameState::ScreenToRoomImpl(int scrx, int scry, int view_index, bool clip_viewport, bool convert_cam_to_data) { + PViewport view; + if (view_index < 0) { + view = GetRoomViewportAt(scrx, scry); + if (!view) + return std::make_pair(Point(), -1); + } else { + view = _roomViewports[view_index]; + } + return view->ScreenToRoom(scrx, scry, clip_viewport, convert_cam_to_data); +} + +VpPoint GameState::ScreenToRoom(int scrx, int scry) { + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v3507) + return ScreenToRoomImpl(scrx, scry, -1, true, false); + return ScreenToRoomImpl(scrx, scry, 0, false, false); +} + +VpPoint GameState::ScreenToRoomDivDown(int scrx, int scry) { + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v3507) + return ScreenToRoomImpl(scrx, scry, -1, true, true); + return ScreenToRoomImpl(scrx, scry, 0, false, true); +} + +void GameState::CreatePrimaryViewportAndCamera() { + if (_roomViewports.size() == 0) { + play.CreateRoomViewport(); + play.RegisterRoomViewport(0); + } + if (_roomCameras.size() == 0) { + play.CreateRoomCamera(); + play.RegisterRoomCamera(0); + } + _roomViewports[0]->LinkCamera(_roomCameras[0]); + _roomCameras[0]->LinkToViewport(_roomViewports[0]); +} + +PViewport GameState::CreateRoomViewport() { + int index = (int)_roomViewports.size(); + PViewport viewport(new Viewport()); + viewport->SetID(index); + viewport->SetRect(_mainViewport.GetRect()); + ScriptViewport *scv = new ScriptViewport(index); + _roomViewports.push_back(viewport); + _scViewportRefs.push_back(std::make_pair(scv, 0)); + _roomViewportsSorted.push_back(viewport); + _roomViewportZOrderChanged = true; + on_roomviewport_created(index); + return viewport; +} + +ScriptViewport *GameState::RegisterRoomViewport(int index, int32_t handle) { + if (index < 0 || (size_t)index >= _roomViewports.size()) + return nullptr; + auto &scobj = _scViewportRefs[index]; + if (handle == 0) { + handle = ccRegisterManagedObject(scobj.first, scobj.first); + ccAddObjectReference(handle); // one reference for the GameState + } else { + ccRegisterUnserializedObject(handle, scobj.first, scobj.first); + } + scobj.second = handle; + return scobj.first; +} + +void GameState::DeleteRoomViewport(int index) { + // NOTE: viewport 0 can not be deleted + if (index <= 0 || (size_t)index >= _roomViewports.size()) + return; + auto scobj = _scViewportRefs[index]; + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + auto cam = _roomViewports[index]->GetCamera(); + if (cam) + cam->UnlinkFromViewport(index); + _roomViewports.erase(_roomViewports.begin() + index); + _scViewportRefs.erase(_scViewportRefs.begin() + index); + for (size_t i = index; i < _roomViewports.size(); ++i) { + _roomViewports[i]->SetID(i); + _scViewportRefs[i].first->SetID(i); + } + for (size_t i = 0; i < _roomViewportsSorted.size(); ++i) { + if (_roomViewportsSorted[i]->GetID() == index) { + _roomViewportsSorted.erase(_roomViewportsSorted.begin() + i); + break; + } + } + on_roomviewport_deleted(index); +} + +int GameState::GetRoomViewportCount() const { + return (int)_roomViewports.size(); +} + +PCamera GameState::CreateRoomCamera() { + int index = (int)_roomCameras.size(); + PCamera camera(new Camera()); + camera->SetID(index); + camera->SetAt(0, 0); + camera->SetSize(_mainViewport.GetRect().GetSize()); + ScriptCamera *scam = new ScriptCamera(index); + _scCameraRefs.push_back(std::make_pair(scam, 0)); + _roomCameras.push_back(camera); + return camera; +} + +ScriptCamera *GameState::RegisterRoomCamera(int index, int32_t handle) { + if (index < 0 || (size_t)index >= _roomCameras.size()) + return nullptr; + auto &scobj = _scCameraRefs[index]; + if (handle == 0) { + handle = ccRegisterManagedObject(scobj.first, scobj.first); + ccAddObjectReference(handle); // one reference for the GameState + } else { + ccRegisterUnserializedObject(handle, scobj.first, scobj.first); + } + scobj.second = handle; + return scobj.first; +} + +void GameState::DeleteRoomCamera(int index) { + // NOTE: camera 0 can not be deleted + if (index <= 0 || (size_t)index >= _roomCameras.size()) + return; + auto scobj = _scCameraRefs[index]; + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + for (auto &viewref : _roomCameras[index]->GetLinkedViewports()) { + auto view = viewref.lock(); + if (view) + view->LinkCamera(nullptr); + } + _roomCameras.erase(_roomCameras.begin() + index); + _scCameraRefs.erase(_scCameraRefs.begin() + index); + for (size_t i = index; i < _roomCameras.size(); ++i) { + _roomCameras[i]->SetID(i); + _scCameraRefs[i].first->SetID(i); + } +} + +int GameState::GetRoomCameraCount() const { + return (int)_roomCameras.size(); +} + +ScriptViewport *GameState::GetScriptViewport(int index) { + if (index < 0 || (size_t)index >= _roomViewports.size()) + return NULL; + return _scViewportRefs[index].first; +} + +ScriptCamera *GameState::GetScriptCamera(int index) { + if (index < 0 || (size_t)index >= _roomCameras.size()) + return NULL; + return _scCameraRefs[index].first; +} + +bool GameState::IsIgnoringInput() const { + return AGS_Clock::now() < _ignoreUserInputUntilTime; +} + +void GameState::SetIgnoreInput(int timeout_ms) { + if (AGS_Clock::now() + std::chrono::milliseconds(timeout_ms) > _ignoreUserInputUntilTime) + _ignoreUserInputUntilTime = AGS_Clock::now() + std::chrono::milliseconds(timeout_ms); +} + +void GameState::ClearIgnoreInput() { + _ignoreUserInputUntilTime = AGS_Clock::now(); +} + +bool GameState::IsBlockingVoiceSpeech() const { + return speech_has_voice && speech_voice_blocking; +} + +bool GameState::IsNonBlockingVoiceSpeech() const { + return speech_has_voice && !speech_voice_blocking; +} + +bool GameState::ShouldPlayVoiceSpeech() const { + return !play.fast_forward && + (play.want_speech >= 1) && (!ResPaths.SpeechPak.Name.IsEmpty()); +} + +void GameState::ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, RestoredData &r_data) { + const bool old_save = svg_ver < kGSSvgVersion_Initial; + score = in->ReadInt32(); + usedmode = in->ReadInt32(); + disabled_user_interface = in->ReadInt32(); + gscript_timer = in->ReadInt32(); + debug_mode = in->ReadInt32(); + in->ReadArrayOfInt32(globalvars, MAXGLOBALVARS); + messagetime = in->ReadInt32(); + usedinv = in->ReadInt32(); + inv_top = in->ReadInt32(); + inv_numdisp = in->ReadInt32(); + obsolete_inv_numorder = in->ReadInt32(); + inv_numinline = in->ReadInt32(); + text_speed = in->ReadInt32(); + sierra_inv_color = in->ReadInt32(); + talkanim_speed = in->ReadInt32(); + inv_item_wid = in->ReadInt32(); + inv_item_hit = in->ReadInt32(); + speech_text_shadow = in->ReadInt32(); + swap_portrait_side = in->ReadInt32(); + speech_textwindow_gui = in->ReadInt32(); + follow_change_room_timer = in->ReadInt32(); + totalscore = in->ReadInt32(); + skip_display = in->ReadInt32(); + no_multiloop_repeat = in->ReadInt32(); + roomscript_finished = in->ReadInt32(); + used_inv_on = in->ReadInt32(); + no_textbg_when_voice = in->ReadInt32(); + max_dialogoption_width = in->ReadInt32(); + no_hicolor_fadein = in->ReadInt32(); + bgspeech_game_speed = in->ReadInt32(); + bgspeech_stay_on_display = in->ReadInt32(); + unfactor_speech_from_textlength = in->ReadInt32(); + mp3_loop_before_end = in->ReadInt32(); + speech_music_drop = in->ReadInt32(); + in_cutscene = in->ReadInt32(); + fast_forward = in->ReadInt32(); + room_width = in->ReadInt32(); + room_height = in->ReadInt32(); + game_speed_modifier = in->ReadInt32(); + score_sound = in->ReadInt32(); + takeover_data = in->ReadInt32(); + replay_hotkey_unused = in->ReadInt32(); + dialog_options_x = in->ReadInt32(); + dialog_options_y = in->ReadInt32(); + narrator_speech = in->ReadInt32(); + ambient_sounds_persist = in->ReadInt32(); + lipsync_speed = in->ReadInt32(); + close_mouth_speech_time = in->ReadInt32(); + disable_antialiasing = in->ReadInt32(); + text_speed_modifier = in->ReadInt32(); + if (svg_ver < kGSSvgVersion_350) + text_align = ConvertLegacyScriptAlignment((LegacyScriptAlignment)in->ReadInt32()); + else + text_align = (HorAlignment)in->ReadInt32(); + speech_bubble_width = in->ReadInt32(); + min_dialogoption_width = in->ReadInt32(); + disable_dialog_parser = in->ReadInt32(); + anim_background_speed = in->ReadInt32(); // the setting for this room + top_bar_backcolor = in->ReadInt32(); + top_bar_textcolor = in->ReadInt32(); + top_bar_bordercolor = in->ReadInt32(); + top_bar_borderwidth = in->ReadInt32(); + top_bar_ypos = in->ReadInt32(); + screenshot_width = in->ReadInt32(); + screenshot_height = in->ReadInt32(); + top_bar_font = in->ReadInt32(); + if (svg_ver < kGSSvgVersion_350) + speech_text_align = ConvertLegacyScriptAlignment((LegacyScriptAlignment)in->ReadInt32()); + else + speech_text_align = (HorAlignment)in->ReadInt32(); + auto_use_walkto_points = in->ReadInt32(); + inventory_greys_out = in->ReadInt32(); + skip_speech_specific_key = in->ReadInt32(); + abort_key = in->ReadInt32(); + fade_to_red = in->ReadInt32(); + fade_to_green = in->ReadInt32(); + fade_to_blue = in->ReadInt32(); + show_single_dialog_option = in->ReadInt32(); + keep_screen_during_instant_transition = in->ReadInt32(); + read_dialog_option_colour = in->ReadInt32(); + stop_dialog_at_end = in->ReadInt32(); + speech_portrait_placement = in->ReadInt32(); + speech_portrait_x = in->ReadInt32(); + speech_portrait_y = in->ReadInt32(); + speech_display_post_time_ms = in->ReadInt32(); + dialog_options_highlight_color = in->ReadInt32(); + if (old_save) + in->ReadArrayOfInt32(reserved, GAME_STATE_RESERVED_INTS); + // ** up to here is referenced in the script "game." object + if (old_save) { + in->ReadInt32(); // recording + in->ReadInt32(); // playback + in->ReadInt16(); // gamestep + } + randseed = in->ReadInt32(); // random seed + player_on_region = in->ReadInt32(); // player's current region + if (old_save) + in->ReadInt32(); // screen_is_faded_out + check_interaction_only = in->ReadInt32(); + bg_frame = in->ReadInt32(); + bg_anim_delay = in->ReadInt32(); // for animating backgrounds + music_vol_was = in->ReadInt32(); // before the volume drop + wait_counter = in->ReadInt16(); + mboundx1 = in->ReadInt16(); + mboundx2 = in->ReadInt16(); + mboundy1 = in->ReadInt16(); + mboundy2 = in->ReadInt16(); + fade_effect = in->ReadInt32(); + bg_frame_locked = in->ReadInt32(); + in->ReadArrayOfInt32(globalscriptvars, MAXGSVALUES); + cur_music_number = in->ReadInt32(); + music_repeat = in->ReadInt32(); + music_master_volume = in->ReadInt32(); + digital_master_volume = in->ReadInt32(); + in->Read(walkable_areas_on, MAX_WALK_AREAS + 1); + screen_flipped = in->ReadInt16(); + if (svg_ver < kGSSvgVersion_3510) { + short offsets_locked = in->ReadInt16(); + if (offsets_locked != 0) + r_data.Camera0_Flags = kSvgCamPosLocked; + } + entered_at_x = in->ReadInt32(); + entered_at_y = in->ReadInt32(); + entered_edge = in->ReadInt32(); + want_speech = in->ReadInt32(); + cant_skip_speech = in->ReadInt32(); + in->ReadArrayOfInt32(script_timers, MAX_TIMERS); + sound_volume = in->ReadInt32(); + speech_volume = in->ReadInt32(); + normal_font = in->ReadInt32(); + speech_font = in->ReadInt32(); + key_skip_wait = in->ReadInt8(); + swap_portrait_lastchar = in->ReadInt32(); + separate_music_lib = in->ReadInt32(); + in_conversation = in->ReadInt32(); + screen_tint = in->ReadInt32(); + num_parsed_words = in->ReadInt32(); + in->ReadArrayOfInt16(parsed_words, MAX_PARSED_WORDS); + in->Read(bad_parsed_word, 100); + raw_color = in->ReadInt32(); + if (old_save) + in->ReadArrayOfInt32(raw_modified, MAX_ROOM_BGFRAMES); + in->ReadArrayOfInt16(filenumbers, MAXSAVEGAMES); + if (old_save) + in->ReadInt32(); // room_changes + mouse_cursor_hidden = in->ReadInt32(); + silent_midi = in->ReadInt32(); + silent_midi_channel = in->ReadInt32(); + current_music_repeating = in->ReadInt32(); + shakesc_delay = in->ReadInt32(); + shakesc_amount = in->ReadInt32(); + shakesc_length = in->ReadInt32(); + rtint_red = in->ReadInt32(); + rtint_green = in->ReadInt32(); + rtint_blue = in->ReadInt32(); + rtint_level = in->ReadInt32(); + rtint_light = in->ReadInt32(); + if (!old_save || loaded_game_file_version >= kGameVersion_340_4) + rtint_enabled = in->ReadBool(); + else + rtint_enabled = rtint_level > 0; + end_cutscene_music = in->ReadInt32(); + skip_until_char_stops = in->ReadInt32(); + get_loc_name_last_time = in->ReadInt32(); + get_loc_name_save_cursor = in->ReadInt32(); + restore_cursor_mode_to = in->ReadInt32(); + restore_cursor_image_to = in->ReadInt32(); + music_queue_size = in->ReadInt16(); + in->ReadArrayOfInt16(music_queue, MAX_QUEUED_MUSIC); + new_music_queue_size = in->ReadInt16(); + if (!old_save) { + for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) { + new_music_queue[i].ReadFromFile(in); + } + } + + crossfading_out_channel = in->ReadInt16(); + crossfade_step = in->ReadInt16(); + crossfade_out_volume_per_step = in->ReadInt16(); + crossfade_initial_volume_out = in->ReadInt16(); + crossfading_in_channel = in->ReadInt16(); + crossfade_in_volume_per_step = in->ReadInt16(); + crossfade_final_volume_in = in->ReadInt16(); + + if (old_save) + ReadQueuedAudioItems_Aligned(in); + + in->Read(takeover_from, 50); + in->Read(playmp3file_name, PLAYMP3FILE_MAX_FILENAME_LEN); + in->Read(globalstrings, MAXGLOBALSTRINGS * MAX_MAXSTRLEN); + in->Read(lastParserEntry, MAX_MAXSTRLEN); + in->Read(game_name, 100); + ground_level_areas_disabled = in->ReadInt32(); + next_screen_transition = in->ReadInt32(); + in->ReadInt32(); // gamma_adjustment -- do not apply gamma level from savegame + temporarily_turned_off_character = in->ReadInt16(); + inv_backwards_compatibility = in->ReadInt16(); + if (old_save) { + in->ReadInt32(); // gui_draw_order + in->ReadInt32(); // do_once_tokens; + } + int num_do_once_tokens = in->ReadInt32(); + do_once_tokens.resize(num_do_once_tokens); + if (!old_save) { + for (int i = 0; i < num_do_once_tokens; ++i) { + StrUtil::ReadString(do_once_tokens[i], in); + } + } + text_min_display_time_ms = in->ReadInt32(); + ignore_user_input_after_text_timeout_ms = in->ReadInt32(); + if (svg_ver < kGSSvgVersion_3509) + in->ReadInt32(); // ignore_user_input_until_time -- do not apply from savegame + if (old_save) + in->ReadArrayOfInt32(default_audio_type_volumes, MAX_AUDIO_TYPES); + if (svg_ver >= kGSSvgVersion_3509) { + int voice_speech_flags = in->ReadInt32(); + speech_has_voice = voice_speech_flags != 0; + speech_voice_blocking = (voice_speech_flags & 0x02) != 0; + } +} + +void GameState::WriteForSavegame(Common::Stream *out) const { + // NOTE: following parameters are never saved: + // recording, playback, gamestep, screen_is_faded_out, room_changes + out->WriteInt32(score); + out->WriteInt32(usedmode); + out->WriteInt32(disabled_user_interface); + out->WriteInt32(gscript_timer); + out->WriteInt32(debug_mode); + out->WriteArrayOfInt32(globalvars, MAXGLOBALVARS); + out->WriteInt32(messagetime); + out->WriteInt32(usedinv); + out->WriteInt32(inv_top); + out->WriteInt32(inv_numdisp); + out->WriteInt32(obsolete_inv_numorder); + out->WriteInt32(inv_numinline); + out->WriteInt32(text_speed); + out->WriteInt32(sierra_inv_color); + out->WriteInt32(talkanim_speed); + out->WriteInt32(inv_item_wid); + out->WriteInt32(inv_item_hit); + out->WriteInt32(speech_text_shadow); + out->WriteInt32(swap_portrait_side); + out->WriteInt32(speech_textwindow_gui); + out->WriteInt32(follow_change_room_timer); + out->WriteInt32(totalscore); + out->WriteInt32(skip_display); + out->WriteInt32(no_multiloop_repeat); + out->WriteInt32(roomscript_finished); + out->WriteInt32(used_inv_on); + out->WriteInt32(no_textbg_when_voice); + out->WriteInt32(max_dialogoption_width); + out->WriteInt32(no_hicolor_fadein); + out->WriteInt32(bgspeech_game_speed); + out->WriteInt32(bgspeech_stay_on_display); + out->WriteInt32(unfactor_speech_from_textlength); + out->WriteInt32(mp3_loop_before_end); + out->WriteInt32(speech_music_drop); + out->WriteInt32(in_cutscene); + out->WriteInt32(fast_forward); + out->WriteInt32(room_width); + out->WriteInt32(room_height); + out->WriteInt32(game_speed_modifier); + out->WriteInt32(score_sound); + out->WriteInt32(takeover_data); + out->WriteInt32(replay_hotkey_unused); // StartRecording: not supported + out->WriteInt32(dialog_options_x); + out->WriteInt32(dialog_options_y); + out->WriteInt32(narrator_speech); + out->WriteInt32(ambient_sounds_persist); + out->WriteInt32(lipsync_speed); + out->WriteInt32(close_mouth_speech_time); + out->WriteInt32(disable_antialiasing); + out->WriteInt32(text_speed_modifier); + out->WriteInt32(text_align); + out->WriteInt32(speech_bubble_width); + out->WriteInt32(min_dialogoption_width); + out->WriteInt32(disable_dialog_parser); + out->WriteInt32(anim_background_speed); // the setting for this room + out->WriteInt32(top_bar_backcolor); + out->WriteInt32(top_bar_textcolor); + out->WriteInt32(top_bar_bordercolor); + out->WriteInt32(top_bar_borderwidth); + out->WriteInt32(top_bar_ypos); + out->WriteInt32(screenshot_width); + out->WriteInt32(screenshot_height); + out->WriteInt32(top_bar_font); + out->WriteInt32(speech_text_align); + out->WriteInt32(auto_use_walkto_points); + out->WriteInt32(inventory_greys_out); + out->WriteInt32(skip_speech_specific_key); + out->WriteInt32(abort_key); + out->WriteInt32(fade_to_red); + out->WriteInt32(fade_to_green); + out->WriteInt32(fade_to_blue); + out->WriteInt32(show_single_dialog_option); + out->WriteInt32(keep_screen_during_instant_transition); + out->WriteInt32(read_dialog_option_colour); + out->WriteInt32(stop_dialog_at_end); + out->WriteInt32(speech_portrait_placement); + out->WriteInt32(speech_portrait_x); + out->WriteInt32(speech_portrait_y); + out->WriteInt32(speech_display_post_time_ms); + out->WriteInt32(dialog_options_highlight_color); + // ** up to here is referenced in the script "game." object + out->WriteInt32(randseed); // random seed + out->WriteInt32(player_on_region); // player's current region + out->WriteInt32(check_interaction_only); + out->WriteInt32(bg_frame); + out->WriteInt32(bg_anim_delay); // for animating backgrounds + out->WriteInt32(music_vol_was); // before the volume drop + out->WriteInt16(wait_counter); + out->WriteInt16(mboundx1); + out->WriteInt16(mboundx2); + out->WriteInt16(mboundy1); + out->WriteInt16(mboundy2); + out->WriteInt32(fade_effect); + out->WriteInt32(bg_frame_locked); + out->WriteArrayOfInt32(globalscriptvars, MAXGSVALUES); + out->WriteInt32(cur_music_number); + out->WriteInt32(music_repeat); + out->WriteInt32(music_master_volume); + out->WriteInt32(digital_master_volume); + out->Write(walkable_areas_on, MAX_WALK_AREAS + 1); + out->WriteInt16(screen_flipped); + out->WriteInt32(entered_at_x); + out->WriteInt32(entered_at_y); + out->WriteInt32(entered_edge); + out->WriteInt32(want_speech); + out->WriteInt32(cant_skip_speech); + out->WriteArrayOfInt32(script_timers, MAX_TIMERS); + out->WriteInt32(sound_volume); + out->WriteInt32(speech_volume); + out->WriteInt32(normal_font); + out->WriteInt32(speech_font); + out->WriteInt8(key_skip_wait); + out->WriteInt32(swap_portrait_lastchar); + out->WriteInt32(separate_music_lib); + out->WriteInt32(in_conversation); + out->WriteInt32(screen_tint); + out->WriteInt32(num_parsed_words); + out->WriteArrayOfInt16(parsed_words, MAX_PARSED_WORDS); + out->Write(bad_parsed_word, 100); + out->WriteInt32(raw_color); + out->WriteArrayOfInt16(filenumbers, MAXSAVEGAMES); + out->WriteInt32(mouse_cursor_hidden); + out->WriteInt32(silent_midi); + out->WriteInt32(silent_midi_channel); + out->WriteInt32(current_music_repeating); + out->WriteInt32(shakesc_delay); + out->WriteInt32(shakesc_amount); + out->WriteInt32(shakesc_length); + out->WriteInt32(rtint_red); + out->WriteInt32(rtint_green); + out->WriteInt32(rtint_blue); + out->WriteInt32(rtint_level); + out->WriteInt32(rtint_light); + out->WriteBool(rtint_enabled); + out->WriteInt32(end_cutscene_music); + out->WriteInt32(skip_until_char_stops); + out->WriteInt32(get_loc_name_last_time); + out->WriteInt32(get_loc_name_save_cursor); + out->WriteInt32(restore_cursor_mode_to); + out->WriteInt32(restore_cursor_image_to); + out->WriteInt16(music_queue_size); + out->WriteArrayOfInt16(music_queue, MAX_QUEUED_MUSIC); + out->WriteInt16(new_music_queue_size); + for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) { + new_music_queue[i].WriteToFile(out); + } + + out->WriteInt16(crossfading_out_channel); + out->WriteInt16(crossfade_step); + out->WriteInt16(crossfade_out_volume_per_step); + out->WriteInt16(crossfade_initial_volume_out); + out->WriteInt16(crossfading_in_channel); + out->WriteInt16(crossfade_in_volume_per_step); + out->WriteInt16(crossfade_final_volume_in); + + out->Write(takeover_from, 50); + out->Write(playmp3file_name, PLAYMP3FILE_MAX_FILENAME_LEN); + out->Write(globalstrings, MAXGLOBALSTRINGS * MAX_MAXSTRLEN); + out->Write(lastParserEntry, MAX_MAXSTRLEN); + out->Write(game_name, 100); + out->WriteInt32(ground_level_areas_disabled); + out->WriteInt32(next_screen_transition); + out->WriteInt32(gamma_adjustment); + out->WriteInt16(temporarily_turned_off_character); + out->WriteInt16(inv_backwards_compatibility); + out->WriteInt32(do_once_tokens.size()); + for (int i = 0; i < (int)do_once_tokens.size(); ++i) { + StrUtil::WriteString(do_once_tokens[i], out); + } + out->WriteInt32(text_min_display_time_ms); + out->WriteInt32(ignore_user_input_after_text_timeout_ms); + + int voice_speech_flags = speech_has_voice ? 0x01 : 0; + if (speech_voice_blocking) + voice_speech_flags |= 0x02; + out->WriteInt32(voice_speech_flags); +} + +void GameState::ReadQueuedAudioItems_Aligned(Common::Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) { + new_music_queue[i].ReadFromFile(&align_s); + align_s.Reset(); + } +} + +void GameState::FreeProperties() { + for (auto &p : charProps) + p.clear(); + for (auto &p : invProps) + p.clear(); +} + +void GameState::FreeViewportsAndCameras() { + _roomViewports.clear(); + _roomViewportsSorted.clear(); + for (auto &scobj : _scViewportRefs) { + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + } + _scViewportRefs.clear(); + _roomCameras.clear(); + for (auto &scobj : _scCameraRefs) { + scobj.first->Invalidate(); + ccReleaseObjectReference(scobj.second); + } + _scCameraRefs.clear(); +} + +void GameState::ReadCustomProperties_v340(Common::Stream *in) { + if (loaded_game_file_version >= kGameVersion_340_4) { + // After runtime property values were read we also copy missing default, + // because we do not keep defaults in the saved game, and also in case + // this save is made by an older game version which had different + // properties. + for (int i = 0; i < game.numcharacters; ++i) + Properties::ReadValues(charProps[i], in); + for (int i = 0; i < game.numinvitems; ++i) + Properties::ReadValues(invProps[i], in); + } +} + +void GameState::WriteCustomProperties_v340(Common::Stream *out) const { + if (loaded_game_file_version >= kGameVersion_340_4) { + // We temporarily remove properties that kept default values + // just for the saving data time to avoid getting lots of + // redundant data into saved games + for (int i = 0; i < game.numcharacters; ++i) + Properties::WriteValues(charProps[i], out); + for (int i = 0; i < game.numinvitems; ++i) + Properties::WriteValues(invProps[i], out); + } } // Converts legacy alignment type used in script API -HorAlignment ConvertLegacyScriptAlignment(LegacyScriptAlignment align) -{ - switch (align) - { - case kLegacyScAlignLeft: return kHAlignLeft; - case kLegacyScAlignCentre: return kHAlignCenter; - case kLegacyScAlignRight: return kHAlignRight; - } - return kHAlignNone; +HorAlignment ConvertLegacyScriptAlignment(LegacyScriptAlignment align) { + switch (align) { + case kLegacyScAlignLeft: + return kHAlignLeft; + case kLegacyScAlignCentre: + return kHAlignCenter; + case kLegacyScAlignRight: + return kHAlignRight; + } + return kHAlignNone; } // Reads legacy alignment type from the value set in script depending on the // current Script API level. This is made to make it possible to change // Alignment constants in the Script API and still support old version. -HorAlignment ReadScriptAlignment(int32_t align) -{ - return game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v350 ? - ConvertLegacyScriptAlignment((LegacyScriptAlignment)align) : - (HorAlignment)align; +HorAlignment ReadScriptAlignment(int32_t align) { + return game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v350 ? + ConvertLegacyScriptAlignment((LegacyScriptAlignment)align) : + (HorAlignment)align; } diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h index 24d6b64ff887..a594e5391ac5 100644 --- a/engines/ags/engine/ac/gamestate.h +++ b/engines/ags/engine/ac/gamestate.h @@ -37,14 +37,15 @@ #include "ac/timer.h" // Forward declaration -namespace AGS -{ - namespace Common - { - class Bitmap; class Stream; - typedef std::shared_ptr PBitmap; - } - namespace Engine { struct RestoredData; } +namespace AGS { +namespace Common { +class Bitmap; +class Stream; +typedef std::shared_ptr PBitmap; +} +namespace Engine { +struct RestoredData; +} } using namespace AGS; // FIXME later struct ScriptViewport; @@ -53,342 +54,341 @@ struct ScriptCamera; #define GAME_STATE_RESERVED_INTS 5 // Savegame data format -enum GameStateSvgVersion -{ - kGSSvgVersion_OldFormat = -1, // TODO: remove after old save support is dropped - kGSSvgVersion_Initial = 0, - kGSSvgVersion_350 = 1, - kGSSvgVersion_3509 = 2, - kGSSvgVersion_3510 = 3, +enum GameStateSvgVersion { + kGSSvgVersion_OldFormat = -1, // TODO: remove after old save support is dropped + kGSSvgVersion_Initial = 0, + kGSSvgVersion_350 = 1, + kGSSvgVersion_3509 = 2, + kGSSvgVersion_3510 = 3, }; // Adding to this might need to modify AGSDEFNS.SH and AGSPLUGIN.H struct GameState { - int score; // player's current score - int usedmode; // set by ProcessClick to last cursor mode used - int disabled_user_interface; // >0 while in cutscene/etc - int gscript_timer; // obsolete - int debug_mode; // whether we're in debug mode - int globalvars[MAXGLOBALVARS]; // obsolete - int messagetime; // time left for auto-remove messages - int usedinv; // inventory item last used - int inv_top,inv_numdisp,obsolete_inv_numorder,inv_numinline; - int text_speed; // how quickly text is removed - int sierra_inv_color; // background used to paint defualt inv window - int talkanim_speed; // animation speed of talking anims - int inv_item_wid,inv_item_hit; // set by SetInvDimensions - int speech_text_shadow; // colour of outline fonts (default black) - int swap_portrait_side; // sierra-style speech swap sides - int speech_textwindow_gui; // textwindow used for sierra-style speech - int follow_change_room_timer; // delay before moving following characters into new room - int totalscore; // maximum possible score - int skip_display; // how the user can skip normal Display windows - int no_multiloop_repeat; // for backwards compatibility - int roomscript_finished; // on_call finished in room - int used_inv_on; // inv item they clicked on - int no_textbg_when_voice; // no textwindow bgrnd when voice speech is used - int max_dialogoption_width; // max width of dialog options text window - int no_hicolor_fadein; // fade out but instant in for hi-color - int bgspeech_game_speed; // is background speech relative to game speed - int bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used - int unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay - int mp3_loop_before_end; // (UNUSED!) loop this time before end of track (ms) - int speech_music_drop; // how much to drop music volume by when speech is played - int in_cutscene; // we are between a StartCutscene and EndCutscene - int fast_forward; // player has elected to skip cutscene - int room_width; // width of current room - int room_height; // height of current room - // ** up to here is referenced in the plugin interface - int game_speed_modifier; - int score_sound; - int takeover_data; // value passed to RunAGSGame in previous game - int replay_hotkey_unused; // (UNUSED!) StartRecording: not supported - int dialog_options_x; - int dialog_options_y; - int narrator_speech; - int ambient_sounds_persist; - int lipsync_speed; - int close_mouth_speech_time; // stop speech animation at (messagetime - close_mouth_speech_time) - // (this is designed to work in text-only mode) - int disable_antialiasing; - int text_speed_modifier; - HorAlignment text_align; - int speech_bubble_width; - int min_dialogoption_width; - int disable_dialog_parser; - int anim_background_speed; // the setting for this room - int top_bar_backcolor; - int top_bar_textcolor; - int top_bar_bordercolor; - int top_bar_borderwidth; - int top_bar_ypos; - int screenshot_width; - int screenshot_height; - int top_bar_font; - HorAlignment speech_text_align; - int auto_use_walkto_points; - int inventory_greys_out; - int skip_speech_specific_key; - int abort_key; - int fade_to_red; - int fade_to_green; - int fade_to_blue; - int show_single_dialog_option; - int keep_screen_during_instant_transition; - int read_dialog_option_colour; - int stop_dialog_at_end; - int speech_portrait_placement; // speech portrait placement mode (automatic/custom) - int speech_portrait_x; // a speech portrait x offset from corresponding screen side - int speech_portrait_y; // a speech portrait y offset - int speech_display_post_time_ms; // keep speech text/portrait on screen after text/voice has finished playing; - // no speech animation is supposed to be played at this time - int dialog_options_highlight_color; // The colour used for highlighted (hovered over) text in dialog options - int reserved[GAME_STATE_RESERVED_INTS]; // make sure if a future version adds a var, it doesn't mess anything up - // ** up to here is referenced in the script "game." object - long randseed; // random seed - int player_on_region; // player's current region - int screen_is_faded_out; // the screen is currently black - int check_interaction_only; - int bg_frame,bg_anim_delay; // for animating backgrounds - int music_vol_was; // before the volume drop - short wait_counter; - char wait_skipped_by; // tells how last wait was skipped [not serialized] - int wait_skipped_by_data; // extended data telling how last wait was skipped [not serialized] - short mboundx1,mboundx2,mboundy1,mboundy2; - int fade_effect; - int bg_frame_locked; - int globalscriptvars[MAXGSVALUES]; - int cur_music_number,music_repeat; - int music_master_volume; - int digital_master_volume; - char walkable_areas_on[MAX_WALK_AREAS+1]; - short screen_flipped; - int entered_at_x,entered_at_y, entered_edge; - int want_speech; - int cant_skip_speech; - int script_timers[MAX_TIMERS]; - int sound_volume,speech_volume; - int normal_font, speech_font; - char key_skip_wait; - int swap_portrait_lastchar; - int swap_portrait_lastlastchar; - int separate_music_lib; - int in_conversation; - int screen_tint; - int num_parsed_words; - short parsed_words[MAX_PARSED_WORDS]; - char bad_parsed_word[100]; - int raw_color; - int raw_modified[MAX_ROOM_BGFRAMES]; - Common::PBitmap raw_drawing_surface; - short filenumbers[MAXSAVEGAMES]; - int room_changes; - int mouse_cursor_hidden; - int silent_midi; - int silent_midi_channel; - int current_music_repeating; // remember what the loop flag was when this music started - unsigned long shakesc_delay; // unsigned long to match loopcounter - int shakesc_amount, shakesc_length; - int rtint_red, rtint_green, rtint_blue, rtint_level, rtint_light; - bool rtint_enabled; - int end_cutscene_music; - int skip_until_char_stops; - int get_loc_name_last_time; - int get_loc_name_save_cursor; - int restore_cursor_mode_to; - int restore_cursor_image_to; - short music_queue_size; - short music_queue[MAX_QUEUED_MUSIC]; - short new_music_queue_size; - short crossfading_out_channel; - short crossfade_step; - short crossfade_out_volume_per_step; - short crossfade_initial_volume_out; - short crossfading_in_channel; - short crossfade_in_volume_per_step; - short crossfade_final_volume_in; - QueuedAudioItem new_music_queue[MAX_QUEUED_MUSIC]; - char takeover_from[50]; - char playmp3file_name[PLAYMP3FILE_MAX_FILENAME_LEN]; - char globalstrings[MAXGLOBALSTRINGS][MAX_MAXSTRLEN]; - char lastParserEntry[MAX_MAXSTRLEN]; - char game_name[100]; - int ground_level_areas_disabled; - int next_screen_transition; - int gamma_adjustment; - short temporarily_turned_off_character; // Hide Player Charactr ticked - short inv_backwards_compatibility; - int *gui_draw_order; - std::vector do_once_tokens; - int text_min_display_time_ms; - int ignore_user_input_after_text_timeout_ms; - int default_audio_type_volumes[MAX_AUDIO_TYPES]; + int score; // player's current score + int usedmode; // set by ProcessClick to last cursor mode used + int disabled_user_interface; // >0 while in cutscene/etc + int gscript_timer; // obsolete + int debug_mode; // whether we're in debug mode + int globalvars[MAXGLOBALVARS]; // obsolete + int messagetime; // time left for auto-remove messages + int usedinv; // inventory item last used + int inv_top, inv_numdisp, obsolete_inv_numorder, inv_numinline; + int text_speed; // how quickly text is removed + int sierra_inv_color; // background used to paint defualt inv window + int talkanim_speed; // animation speed of talking anims + int inv_item_wid, inv_item_hit; // set by SetInvDimensions + int speech_text_shadow; // colour of outline fonts (default black) + int swap_portrait_side; // sierra-style speech swap sides + int speech_textwindow_gui; // textwindow used for sierra-style speech + int follow_change_room_timer; // delay before moving following characters into new room + int totalscore; // maximum possible score + int skip_display; // how the user can skip normal Display windows + int no_multiloop_repeat; // for backwards compatibility + int roomscript_finished; // on_call finished in room + int used_inv_on; // inv item they clicked on + int no_textbg_when_voice; // no textwindow bgrnd when voice speech is used + int max_dialogoption_width; // max width of dialog options text window + int no_hicolor_fadein; // fade out but instant in for hi-color + int bgspeech_game_speed; // is background speech relative to game speed + int bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used + int unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay + int mp3_loop_before_end; // (UNUSED!) loop this time before end of track (ms) + int speech_music_drop; // how much to drop music volume by when speech is played + int in_cutscene; // we are between a StartCutscene and EndCutscene + int fast_forward; // player has elected to skip cutscene + int room_width; // width of current room + int room_height; // height of current room + // ** up to here is referenced in the plugin interface + int game_speed_modifier; + int score_sound; + int takeover_data; // value passed to RunAGSGame in previous game + int replay_hotkey_unused; // (UNUSED!) StartRecording: not supported + int dialog_options_x; + int dialog_options_y; + int narrator_speech; + int ambient_sounds_persist; + int lipsync_speed; + int close_mouth_speech_time; // stop speech animation at (messagetime - close_mouth_speech_time) + // (this is designed to work in text-only mode) + int disable_antialiasing; + int text_speed_modifier; + HorAlignment text_align; + int speech_bubble_width; + int min_dialogoption_width; + int disable_dialog_parser; + int anim_background_speed; // the setting for this room + int top_bar_backcolor; + int top_bar_textcolor; + int top_bar_bordercolor; + int top_bar_borderwidth; + int top_bar_ypos; + int screenshot_width; + int screenshot_height; + int top_bar_font; + HorAlignment speech_text_align; + int auto_use_walkto_points; + int inventory_greys_out; + int skip_speech_specific_key; + int abort_key; + int fade_to_red; + int fade_to_green; + int fade_to_blue; + int show_single_dialog_option; + int keep_screen_during_instant_transition; + int read_dialog_option_colour; + int stop_dialog_at_end; + int speech_portrait_placement; // speech portrait placement mode (automatic/custom) + int speech_portrait_x; // a speech portrait x offset from corresponding screen side + int speech_portrait_y; // a speech portrait y offset + int speech_display_post_time_ms; // keep speech text/portrait on screen after text/voice has finished playing; + // no speech animation is supposed to be played at this time + int dialog_options_highlight_color; // The colour used for highlighted (hovered over) text in dialog options + int reserved[GAME_STATE_RESERVED_INTS]; // make sure if a future version adds a var, it doesn't mess anything up + // ** up to here is referenced in the script "game." object + long randseed; // random seed + int player_on_region; // player's current region + int screen_is_faded_out; // the screen is currently black + int check_interaction_only; + int bg_frame, bg_anim_delay; // for animating backgrounds + int music_vol_was; // before the volume drop + short wait_counter; + char wait_skipped_by; // tells how last wait was skipped [not serialized] + int wait_skipped_by_data; // extended data telling how last wait was skipped [not serialized] + short mboundx1, mboundx2, mboundy1, mboundy2; + int fade_effect; + int bg_frame_locked; + int globalscriptvars[MAXGSVALUES]; + int cur_music_number, music_repeat; + int music_master_volume; + int digital_master_volume; + char walkable_areas_on[MAX_WALK_AREAS + 1]; + short screen_flipped; + int entered_at_x, entered_at_y, entered_edge; + int want_speech; + int cant_skip_speech; + int script_timers[MAX_TIMERS]; + int sound_volume, speech_volume; + int normal_font, speech_font; + char key_skip_wait; + int swap_portrait_lastchar; + int swap_portrait_lastlastchar; + int separate_music_lib; + int in_conversation; + int screen_tint; + int num_parsed_words; + short parsed_words[MAX_PARSED_WORDS]; + char bad_parsed_word[100]; + int raw_color; + int raw_modified[MAX_ROOM_BGFRAMES]; + Common::PBitmap raw_drawing_surface; + short filenumbers[MAXSAVEGAMES]; + int room_changes; + int mouse_cursor_hidden; + int silent_midi; + int silent_midi_channel; + int current_music_repeating; // remember what the loop flag was when this music started + unsigned long shakesc_delay; // unsigned long to match loopcounter + int shakesc_amount, shakesc_length; + int rtint_red, rtint_green, rtint_blue, rtint_level, rtint_light; + bool rtint_enabled; + int end_cutscene_music; + int skip_until_char_stops; + int get_loc_name_last_time; + int get_loc_name_save_cursor; + int restore_cursor_mode_to; + int restore_cursor_image_to; + short music_queue_size; + short music_queue[MAX_QUEUED_MUSIC]; + short new_music_queue_size; + short crossfading_out_channel; + short crossfade_step; + short crossfade_out_volume_per_step; + short crossfade_initial_volume_out; + short crossfading_in_channel; + short crossfade_in_volume_per_step; + short crossfade_final_volume_in; + QueuedAudioItem new_music_queue[MAX_QUEUED_MUSIC]; + char takeover_from[50]; + char playmp3file_name[PLAYMP3FILE_MAX_FILENAME_LEN]; + char globalstrings[MAXGLOBALSTRINGS][MAX_MAXSTRLEN]; + char lastParserEntry[MAX_MAXSTRLEN]; + char game_name[100]; + int ground_level_areas_disabled; + int next_screen_transition; + int gamma_adjustment; + short temporarily_turned_off_character; // Hide Player Charactr ticked + short inv_backwards_compatibility; + int *gui_draw_order; + std::vector do_once_tokens; + int text_min_display_time_ms; + int ignore_user_input_after_text_timeout_ms; + int default_audio_type_volumes[MAX_AUDIO_TYPES]; - // Dynamic custom property values for characters and items - std::vector charProps; - AGS::Common::StringIMap invProps[MAX_INV]; + // Dynamic custom property values for characters and items + std::vector charProps; + AGS::Common::StringIMap invProps[MAX_INV]; - // Dynamic speech state - // - // Tells whether there is a voice-over played during current speech - bool speech_has_voice; - // Tells whether the voice was played in blocking mode; - // atm blocking speech handles itself, and we only need to finalize - // non-blocking voice speech during game update; speech refactor would be - // required to get rid of this rule. - bool speech_voice_blocking; - // Tells whether character speech stays on screen not animated for additional time - bool speech_in_post_state; + // Dynamic speech state + // + // Tells whether there is a voice-over played during current speech + bool speech_has_voice; + // Tells whether the voice was played in blocking mode; + // atm blocking speech handles itself, and we only need to finalize + // non-blocking voice speech during game update; speech refactor would be + // required to get rid of this rule. + bool speech_voice_blocking; + // Tells whether character speech stays on screen not animated for additional time + bool speech_in_post_state; - int shake_screen_yoff; // y offset of the shaking screen + int shake_screen_yoff; // y offset of the shaking screen - GameState(); - // Free game resources - void Free(); + GameState(); + // Free game resources + void Free(); - // - // Viewport and camera control. - // Viewports are positioned in game screen coordinates, related to the "game size", - // while cameras are positioned in room coordinates. - // - // Tells if the room viewport should be adjusted automatically each time a new room is loaded - bool IsAutoRoomViewport() const; - // Returns main viewport position on screen, this is the overall game view - const Rect &GetMainViewport() const; - // Returns UI viewport position on screen, this is the GUI layer - const Rect &GetUIViewport() const; - // Returns Room viewport object by it's main index - PViewport GetRoomViewport(int index) const; - // Returns Room viewport object by index in z-order - const std::vector &GetRoomViewportsZOrdered() const; - // Finds room viewport at the given screen coordinates; returns nullptr if non found - PViewport GetRoomViewportAt(int x, int y) const; - // Returns UI viewport position in absolute coordinates (with main viewport offset) - Rect GetUIViewportAbs() const; - // Returns Room viewport position in absolute coordinates (with main viewport offset) - Rect GetRoomViewportAbs(int index) const; - // Sets if the room viewport should be adjusted automatically each time a new room is loaded - void SetAutoRoomViewport(bool on); - // Main viewport defines the location of all things drawn and interactable on the game screen. - // Other viewports are defined relative to the main viewports. - void SetMainViewport(const Rect &viewport); - // UI viewport is a formal dummy viewport for GUI and Overlays (like speech). - void SetUIViewport(const Rect &viewport); - // Applies all the pending changes to viewports and cameras; - // NOTE: this function may be slow, thus recommended to be called only once - // and during the main game update. - void UpdateViewports(); - // Notifies game state that viewports need z-order resorting upon next update. - void InvalidateViewportZOrder(); - // Returns room camera object chosen by index - PCamera GetRoomCamera(int index) const; - // Runs cameras behaviors - void UpdateRoomCameras(); - // Converts room coordinates to the game screen coordinates through the room viewport - // This group of functions always tries to pass a point through the **primary** room viewport - // TODO: also support using arbitrary viewport (for multiple viewports). - Point RoomToScreen(int roomx, int roomy); - int RoomToScreenX(int roomx); - int RoomToScreenY(int roomy); - // Converts game screen coordinates to the room coordinates through the room viewport - // This pair of functions tries to find if there is any viewport at the given coords and results - // in failure if there is none. - // TODO: find out if possible to refactor and get rid of "variadic" variants; - // usually this depends on how the arguments are created (whether they are in "variadic" or true coords) - VpPoint ScreenToRoom(int scrx, int scry); - VpPoint ScreenToRoomDivDown(int scrx, int scry); // native "variadic" coords variant + // + // Viewport and camera control. + // Viewports are positioned in game screen coordinates, related to the "game size", + // while cameras are positioned in room coordinates. + // + // Tells if the room viewport should be adjusted automatically each time a new room is loaded + bool IsAutoRoomViewport() const; + // Returns main viewport position on screen, this is the overall game view + const Rect &GetMainViewport() const; + // Returns UI viewport position on screen, this is the GUI layer + const Rect &GetUIViewport() const; + // Returns Room viewport object by it's main index + PViewport GetRoomViewport(int index) const; + // Returns Room viewport object by index in z-order + const std::vector &GetRoomViewportsZOrdered() const; + // Finds room viewport at the given screen coordinates; returns nullptr if non found + PViewport GetRoomViewportAt(int x, int y) const; + // Returns UI viewport position in absolute coordinates (with main viewport offset) + Rect GetUIViewportAbs() const; + // Returns Room viewport position in absolute coordinates (with main viewport offset) + Rect GetRoomViewportAbs(int index) const; + // Sets if the room viewport should be adjusted automatically each time a new room is loaded + void SetAutoRoomViewport(bool on); + // Main viewport defines the location of all things drawn and interactable on the game screen. + // Other viewports are defined relative to the main viewports. + void SetMainViewport(const Rect &viewport); + // UI viewport is a formal dummy viewport for GUI and Overlays (like speech). + void SetUIViewport(const Rect &viewport); + // Applies all the pending changes to viewports and cameras; + // NOTE: this function may be slow, thus recommended to be called only once + // and during the main game update. + void UpdateViewports(); + // Notifies game state that viewports need z-order resorting upon next update. + void InvalidateViewportZOrder(); + // Returns room camera object chosen by index + PCamera GetRoomCamera(int index) const; + // Runs cameras behaviors + void UpdateRoomCameras(); + // Converts room coordinates to the game screen coordinates through the room viewport + // This group of functions always tries to pass a point through the **primary** room viewport + // TODO: also support using arbitrary viewport (for multiple viewports). + Point RoomToScreen(int roomx, int roomy); + int RoomToScreenX(int roomx); + int RoomToScreenY(int roomy); + // Converts game screen coordinates to the room coordinates through the room viewport + // This pair of functions tries to find if there is any viewport at the given coords and results + // in failure if there is none. + // TODO: find out if possible to refactor and get rid of "variadic" variants; + // usually this depends on how the arguments are created (whether they are in "variadic" or true coords) + VpPoint ScreenToRoom(int scrx, int scry); + VpPoint ScreenToRoomDivDown(int scrx, int scry); // native "variadic" coords variant - // Makes sure primary viewport and camera are created and linked together - void CreatePrimaryViewportAndCamera(); - // Creates new room viewport - PViewport CreateRoomViewport(); - // Register camera in the managed system; optionally links to existing handle - ScriptViewport *RegisterRoomViewport(int index, int32_t handle = 0); - // Deletes existing room viewport - void DeleteRoomViewport(int index); - // Get number of room viewports - int GetRoomViewportCount() const; - // Creates new room camera - PCamera CreateRoomCamera(); - // Register camera in the managed system; optionally links to existing handle - ScriptCamera *RegisterRoomCamera(int index, int32_t handle = 0); - // Deletes existing room camera - void DeleteRoomCamera(int index); - // Get number of room cameras - int GetRoomCameraCount() const; - // Gets script viewport reference; does NOT increment refcount - // because script interpreter does this when acquiring managed pointer. - ScriptViewport *GetScriptViewport(int index); - // Gets script camera reference; does NOT increment refcount - // because script interpreter does this when acquiring managed pointer. - ScriptCamera *GetScriptCamera(int index); + // Makes sure primary viewport and camera are created and linked together + void CreatePrimaryViewportAndCamera(); + // Creates new room viewport + PViewport CreateRoomViewport(); + // Register camera in the managed system; optionally links to existing handle + ScriptViewport *RegisterRoomViewport(int index, int32_t handle = 0); + // Deletes existing room viewport + void DeleteRoomViewport(int index); + // Get number of room viewports + int GetRoomViewportCount() const; + // Creates new room camera + PCamera CreateRoomCamera(); + // Register camera in the managed system; optionally links to existing handle + ScriptCamera *RegisterRoomCamera(int index, int32_t handle = 0); + // Deletes existing room camera + void DeleteRoomCamera(int index); + // Get number of room cameras + int GetRoomCameraCount() const; + // Gets script viewport reference; does NOT increment refcount + // because script interpreter does this when acquiring managed pointer. + ScriptViewport *GetScriptViewport(int index); + // Gets script camera reference; does NOT increment refcount + // because script interpreter does this when acquiring managed pointer. + ScriptCamera *GetScriptCamera(int index); - // - // User input management - // - // Tells if game should ignore user input right now. Note that some of the parent states - // may not ignore it at the same time, such as cutscene state, which may still be skipped - // with a key press or a mouse button. - bool IsIgnoringInput() const; - // Sets ignore input state, for the given time; if there's one already, chooses max timeout - void SetIgnoreInput(int timeout_ms); - // Clears ignore input state - void ClearIgnoreInput(); + // + // User input management + // + // Tells if game should ignore user input right now. Note that some of the parent states + // may not ignore it at the same time, such as cutscene state, which may still be skipped + // with a key press or a mouse button. + bool IsIgnoringInput() const; + // Sets ignore input state, for the given time; if there's one already, chooses max timeout + void SetIgnoreInput(int timeout_ms); + // Clears ignore input state + void ClearIgnoreInput(); - // - // Voice speech management - // - // Tells if there's a blocking voice speech playing right now - bool IsBlockingVoiceSpeech() const; - // Tells whether we have to finalize voice speech when stopping or reusing the channel - bool IsNonBlockingVoiceSpeech() const; - // Speech helpers - bool ShouldPlayVoiceSpeech() const; + // + // Voice speech management + // + // Tells if there's a blocking voice speech playing right now + bool IsBlockingVoiceSpeech() const; + // Tells whether we have to finalize voice speech when stopping or reusing the channel + bool IsNonBlockingVoiceSpeech() const; + // Speech helpers + bool ShouldPlayVoiceSpeech() const; - // - // Serialization - // - void ReadQueuedAudioItems_Aligned(Common::Stream *in); - void ReadCustomProperties_v340(Common::Stream *in); - void WriteCustomProperties_v340(Common::Stream *out) const; - void ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, AGS::Engine::RestoredData &r_data); - void WriteForSavegame(Common::Stream *out) const; - void FreeProperties(); - void FreeViewportsAndCameras(); + // + // Serialization + // + void ReadQueuedAudioItems_Aligned(Common::Stream *in); + void ReadCustomProperties_v340(Common::Stream *in); + void WriteCustomProperties_v340(Common::Stream *out) const; + void ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, AGS::Engine::RestoredData &r_data); + void WriteForSavegame(Common::Stream *out) const; + void FreeProperties(); + void FreeViewportsAndCameras(); private: - VpPoint ScreenToRoomImpl(int scrx, int scry, int view_index, bool clip_viewport, bool convert_cam_to_data); - void UpdateRoomCamera(int index); + VpPoint ScreenToRoomImpl(int scrx, int scry, int view_index, bool clip_viewport, bool convert_cam_to_data); + void UpdateRoomCamera(int index); - // Defines if the room viewport should be adjusted to the room size automatically. - bool _isAutoRoomViewport; - // Main viewport defines the rectangle of the drawn and interactable area - // in the most basic case it will be equal to the game size. - Viewport _mainViewport; - // UI viewport defines the render and interaction rectangle of game's UI. - Viewport _uiViewport; - // Room viewports define place on screen where the room camera's - // contents are drawn. - std::vector _roomViewports; - // Vector of viewports sorted in z-order. - std::vector _roomViewportsSorted; - // Cameras defines the position of a "looking eye" inside the room. - std::vector _roomCameras; - // Script viewports and cameras are references to real data export to - // user script. They became invalidated as the actual object gets - // destroyed, but are kept in memory to prevent script errors. - std::vector> _scViewportRefs; - std::vector> _scCameraRefs; + // Defines if the room viewport should be adjusted to the room size automatically. + bool _isAutoRoomViewport; + // Main viewport defines the rectangle of the drawn and interactable area + // in the most basic case it will be equal to the game size. + Viewport _mainViewport; + // UI viewport defines the render and interaction rectangle of game's UI. + Viewport _uiViewport; + // Room viewports define place on screen where the room camera's + // contents are drawn. + std::vector _roomViewports; + // Vector of viewports sorted in z-order. + std::vector _roomViewportsSorted; + // Cameras defines the position of a "looking eye" inside the room. + std::vector _roomCameras; + // Script viewports and cameras are references to real data export to + // user script. They became invalidated as the actual object gets + // destroyed, but are kept in memory to prevent script errors. + std::vector> _scViewportRefs; + std::vector> _scCameraRefs; - // Tells that the main viewport's position has changed since last game update - bool _mainViewportHasChanged; - // Tells that room viewports need z-order resort - bool _roomViewportZOrderChanged; + // Tells that the main viewport's position has changed since last game update + bool _mainViewportHasChanged; + // Tells that room viewports need z-order resort + bool _roomViewportZOrderChanged; - AGS_Clock::time_point _ignoreUserInputUntilTime; + AGS_Clock::time_point _ignoreUserInputUntilTime; }; // Converts legacy alignment type used in script API diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp index ce838680e899..1f6a96790c3b 100644 --- a/engines/ags/engine/ac/global_api.cpp +++ b/engines/ags/engine/ac/global_api.cpp @@ -84,101 +84,85 @@ extern ScriptString myScriptStringImpl; // void (char*texx, ...) -RuntimeScriptValue Sc_sc_AbortGame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(_sc_AbortGame, 1); - _sc_AbortGame(scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_sc_AbortGame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(_sc_AbortGame, 1); + _sc_AbortGame(scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (int inum) -RuntimeScriptValue Sc_add_inventory(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(add_inventory); +RuntimeScriptValue Sc_add_inventory(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(add_inventory); } // void (int charid, int inum) -RuntimeScriptValue Sc_AddInventoryToCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(AddInventoryToCharacter); +RuntimeScriptValue Sc_AddInventoryToCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(AddInventoryToCharacter); } // void (int guin, int objn, int view, int loop, int speed, int repeat) -RuntimeScriptValue Sc_AnimateButton(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT6(AnimateButton); +RuntimeScriptValue Sc_AnimateButton(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT6(AnimateButton); } // void (int chh, int loopn, int sppd, int rept) -RuntimeScriptValue Sc_scAnimateCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(scAnimateCharacter); +RuntimeScriptValue Sc_scAnimateCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(scAnimateCharacter); } // void (int chh, int loopn, int sppd, int rept, int direction, int blocking) -RuntimeScriptValue Sc_AnimateCharacterEx(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT6(AnimateCharacterEx); +RuntimeScriptValue Sc_AnimateCharacterEx(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT6(AnimateCharacterEx); } // void (int obn,int loopn,int spdd,int rept) -RuntimeScriptValue Sc_AnimateObject(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(AnimateObject); +RuntimeScriptValue Sc_AnimateObject(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(AnimateObject); } // void (int obn,int loopn,int spdd,int rept, int direction, int blocking) -RuntimeScriptValue Sc_AnimateObjectEx(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT6(AnimateObjectEx); +RuntimeScriptValue Sc_AnimateObjectEx(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT6(AnimateObjectEx); } // int (int cchar1,int cchar2) -RuntimeScriptValue Sc_AreCharactersColliding(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(AreCharactersColliding); +RuntimeScriptValue Sc_AreCharactersColliding(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(AreCharactersColliding); } // int (int charid,int objid) -RuntimeScriptValue Sc_AreCharObjColliding(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(AreCharObjColliding); +RuntimeScriptValue Sc_AreCharObjColliding(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(AreCharObjColliding); } // int (int obj1,int obj2) -RuntimeScriptValue Sc_AreObjectsColliding(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(AreObjectsColliding); +RuntimeScriptValue Sc_AreObjectsColliding(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(AreObjectsColliding); } // int (int thing1, int thing2) -RuntimeScriptValue Sc_AreThingsOverlapping(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(AreThingsOverlapping); +RuntimeScriptValue Sc_AreThingsOverlapping(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(AreThingsOverlapping); } // void (int value) -RuntimeScriptValue Sc_CallRoomScript(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(CallRoomScript); +RuntimeScriptValue Sc_CallRoomScript(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(CallRoomScript); } // int (int cmdd,int datt) -RuntimeScriptValue Sc_cd_manager(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(cd_manager); +RuntimeScriptValue Sc_cd_manager(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(cd_manager); } // void (int ifn) -RuntimeScriptValue Sc_CentreGUI(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(CentreGUI); +RuntimeScriptValue Sc_CentreGUI(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(CentreGUI); } // void (int chaa,int vii) -RuntimeScriptValue Sc_ChangeCharacterView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(ChangeCharacterView); +RuntimeScriptValue Sc_ChangeCharacterView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(ChangeCharacterView); } extern RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *params, int32_t param_count); @@ -186,1619 +170,1355 @@ extern RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *param extern RuntimeScriptValue Sc_ChangeCursorHotspot(const RuntimeScriptValue *params, int32_t param_count); // void () -RuntimeScriptValue Sc_ClaimEvent(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(ClaimEvent); +RuntimeScriptValue Sc_ClaimEvent(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(ClaimEvent); } // int (int xx,int yy,int slott,int trans) -RuntimeScriptValue Sc_CreateGraphicOverlay(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT4(CreateGraphicOverlay); +RuntimeScriptValue Sc_CreateGraphicOverlay(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT4(CreateGraphicOverlay); } // int (int xx,int yy,int wii,int fontid,int clr,char*texx, ...) -RuntimeScriptValue Sc_CreateTextOverlay(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(CreateTextOverlay, 6); - return RuntimeScriptValue().SetInt32( - CreateTextOverlay(params[0].IValue, params[1].IValue, params[2].IValue, - params[3].IValue, params[4].IValue, scsf_buffer, DISPLAYTEXT_NORMALOVERLAY)); +RuntimeScriptValue Sc_CreateTextOverlay(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(CreateTextOverlay, 6); + return RuntimeScriptValue().SetInt32( + CreateTextOverlay(params[0].IValue, params[1].IValue, params[2].IValue, + params[3].IValue, params[4].IValue, scsf_buffer, DISPLAYTEXT_NORMALOVERLAY)); } // void (int strt,int eend) -RuntimeScriptValue Sc_CyclePalette(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(CyclePalette); +RuntimeScriptValue Sc_CyclePalette(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(CyclePalette); } // void (int cmdd,int dataa) -RuntimeScriptValue Sc_script_debug(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(script_debug); +RuntimeScriptValue Sc_script_debug(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(script_debug); } // void (int slnum) -RuntimeScriptValue Sc_DeleteSaveSlot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(DeleteSaveSlot); +RuntimeScriptValue Sc_DeleteSaveSlot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(DeleteSaveSlot); } // void (int gotSlot) -RuntimeScriptValue Sc_free_dynamic_sprite(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(free_dynamic_sprite); +RuntimeScriptValue Sc_free_dynamic_sprite(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(free_dynamic_sprite); } extern RuntimeScriptValue Sc_disable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count); // void (int alsoEffects) -RuntimeScriptValue Sc_DisableGroundLevelAreas(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(DisableGroundLevelAreas); +RuntimeScriptValue Sc_DisableGroundLevelAreas(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(DisableGroundLevelAreas); } // void (int hsnum) -RuntimeScriptValue Sc_DisableHotspot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(DisableHotspot); +RuntimeScriptValue Sc_DisableHotspot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(DisableHotspot); } // void () -RuntimeScriptValue Sc_DisableInterface(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(DisableInterface); +RuntimeScriptValue Sc_DisableInterface(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(DisableInterface); } // void (int hsnum) -RuntimeScriptValue Sc_DisableRegion(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(DisableRegion); +RuntimeScriptValue Sc_DisableRegion(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(DisableRegion); } // void (char*texx, ...) -RuntimeScriptValue Sc_Display(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(Display, 1); - DisplaySimple(scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_Display(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(Display, 1); + DisplaySimple(scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (int xxp,int yyp,int widd,char*texx, ...) -RuntimeScriptValue Sc_DisplayAt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(DisplayAt, 4); - DisplayAt(params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_DisplayAt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(DisplayAt, 4); + DisplayAt(params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (int ypos, char *texx) -RuntimeScriptValue Sc_DisplayAtY(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(DisplayAtY, const char); +RuntimeScriptValue Sc_DisplayAtY(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(DisplayAtY, const char); } // void (int msnum) -RuntimeScriptValue Sc_DisplayMessage(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(DisplayMessage); +RuntimeScriptValue Sc_DisplayMessage(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(DisplayMessage); } // void (int msnum, int ypos) -RuntimeScriptValue Sc_DisplayMessageAtY(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(DisplayMessageAtY); +RuntimeScriptValue Sc_DisplayMessageAtY(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(DisplayMessageAtY); } // void (int ypos, int ttexcol, int backcol, char *title, int msgnum) -RuntimeScriptValue Sc_DisplayMessageBar(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3_POBJ_PINT(DisplayMessageBar, const char); +RuntimeScriptValue Sc_DisplayMessageBar(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3_POBJ_PINT(DisplayMessageBar, const char); } // void (int chid,char*texx, ...) -RuntimeScriptValue Sc_sc_displayspeech(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(DisplayAt, 2); - __sc_displayspeech(params[0].IValue, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_sc_displayspeech(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(DisplayAt, 2); + __sc_displayspeech(params[0].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (int xx, int yy, int wii, int aschar, char*spch) -RuntimeScriptValue Sc_DisplaySpeechAt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4_POBJ(DisplaySpeechAt, const char); +RuntimeScriptValue Sc_DisplaySpeechAt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4_POBJ(DisplaySpeechAt, const char); } // int (int charid,char*speel) -RuntimeScriptValue Sc_DisplaySpeechBackground(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT_POBJ(DisplaySpeechBackground, const char); +RuntimeScriptValue Sc_DisplaySpeechBackground(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT_POBJ(DisplaySpeechBackground, const char); } // void (int chid, const char*texx, ...) -RuntimeScriptValue Sc_DisplayThought(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(DisplayThought, 2); - DisplayThought(params[0].IValue, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_DisplayThought(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(DisplayThought, 2); + DisplayThought(params[0].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (int ypos, int ttexcol, int backcol, char *title, char*texx, ...) -RuntimeScriptValue Sc_DisplayTopBar(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(DisplayTopBar, 5); - DisplayTopBar(params[0].IValue, params[1].IValue, params[2].IValue, params[3].Ptr, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_DisplayTopBar(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(DisplayTopBar, 5); + DisplayTopBar(params[0].IValue, params[1].IValue, params[2].IValue, params[3].Ptr, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } extern RuntimeScriptValue Sc_enable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count); // void () -RuntimeScriptValue Sc_EnableGroundLevelAreas(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(EnableGroundLevelAreas); +RuntimeScriptValue Sc_EnableGroundLevelAreas(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(EnableGroundLevelAreas); } // void (int hsnum) -RuntimeScriptValue Sc_EnableHotspot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(EnableHotspot); +RuntimeScriptValue Sc_EnableHotspot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(EnableHotspot); } // void () -RuntimeScriptValue Sc_EnableInterface(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(EnableInterface); +RuntimeScriptValue Sc_EnableInterface(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(EnableInterface); } // void (int hsnum) -RuntimeScriptValue Sc_EnableRegion(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(EnableRegion); +RuntimeScriptValue Sc_EnableRegion(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(EnableRegion); } // int () -RuntimeScriptValue Sc_EndCutscene(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(EndCutscene); +RuntimeScriptValue Sc_EndCutscene(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(EndCutscene); } // void (int cha,int toface) -RuntimeScriptValue Sc_FaceCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(FaceCharacter); +RuntimeScriptValue Sc_FaceCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(FaceCharacter); } // void (int cha, int xx, int yy) -RuntimeScriptValue Sc_FaceLocation(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(FaceLocation); +RuntimeScriptValue Sc_FaceLocation(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(FaceLocation); } // void (int sppd) -RuntimeScriptValue Sc_FadeIn(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(FadeIn); +RuntimeScriptValue Sc_FadeIn(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(FadeIn); } // void (int spdd) -RuntimeScriptValue Sc_my_fade_out(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(my_fade_out); +RuntimeScriptValue Sc_my_fade_out(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(my_fade_out); } // void (int handle) -RuntimeScriptValue Sc_FileClose(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(FileClose); +RuntimeScriptValue Sc_FileClose(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(FileClose); } // int (int handle) -RuntimeScriptValue Sc_FileIsEOF(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(FileIsEOF); +RuntimeScriptValue Sc_FileIsEOF(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(FileIsEOF); } // int (int handle) -RuntimeScriptValue Sc_FileIsError(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(FileIsError); +RuntimeScriptValue Sc_FileIsError(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(FileIsError); } // int (const char*fnmm, const char* cmode) -RuntimeScriptValue Sc_FileOpenCMode(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ2(FileOpenCMode, const char, const char); +RuntimeScriptValue Sc_FileOpenCMode(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ2(FileOpenCMode, const char, const char); } // void (int handle,char*toread) -RuntimeScriptValue Sc_FileRead(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(FileRead, char); +RuntimeScriptValue Sc_FileRead(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(FileRead, char); } // int (int handle) -RuntimeScriptValue Sc_FileReadInt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(FileReadInt); +RuntimeScriptValue Sc_FileReadInt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(FileReadInt); } // char (int handle) -RuntimeScriptValue Sc_FileReadRawChar(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(FileReadRawChar); +RuntimeScriptValue Sc_FileReadRawChar(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(FileReadRawChar); } // int (int handle) -RuntimeScriptValue Sc_FileReadRawInt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(FileReadRawInt); +RuntimeScriptValue Sc_FileReadRawInt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(FileReadRawInt); } // void (int handle, const char *towrite) -RuntimeScriptValue Sc_FileWrite(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(FileWrite, const char); +RuntimeScriptValue Sc_FileWrite(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(FileWrite, const char); } // void (int handle,int into) -RuntimeScriptValue Sc_FileWriteInt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(FileWriteInt); +RuntimeScriptValue Sc_FileWriteInt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(FileWriteInt); } // void (int handle, int chartoWrite) -RuntimeScriptValue Sc_FileWriteRawChar(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(FileWriteRawChar); +RuntimeScriptValue Sc_FileWriteRawChar(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(FileWriteRawChar); } // void (int handle, const char*towrite) -RuntimeScriptValue Sc_FileWriteRawLine(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(FileWriteRawLine, const char); +RuntimeScriptValue Sc_FileWriteRawLine(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(FileWriteRawLine, const char); } // int (const char* GUIName) -RuntimeScriptValue Sc_FindGUIID(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(FindGUIID, const char); +RuntimeScriptValue Sc_FindGUIID(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(FindGUIID, const char); } // void (int amount) -RuntimeScriptValue Sc_FlipScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(FlipScreen); +RuntimeScriptValue Sc_FlipScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(FlipScreen); } // int (SCRIPT_FLOAT(value), int roundDirection) -RuntimeScriptValue Sc_FloatToInt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PFLOAT_PINT(FloatToInt); +RuntimeScriptValue Sc_FloatToInt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PFLOAT_PINT(FloatToInt); } // void (int who, int tofollow) -RuntimeScriptValue Sc_FollowCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(FollowCharacter); +RuntimeScriptValue Sc_FollowCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(FollowCharacter); } // void (int who, int tofollow, int distaway, int eagerness) -RuntimeScriptValue Sc_FollowCharacterEx(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(FollowCharacterEx); +RuntimeScriptValue Sc_FollowCharacterEx(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(FollowCharacterEx); } // int () -RuntimeScriptValue Sc_GetBackgroundFrame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetBackgroundFrame); +RuntimeScriptValue Sc_GetBackgroundFrame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetBackgroundFrame); } // int (int guin, int objn, int ptype) -RuntimeScriptValue Sc_GetButtonPic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT3(GetButtonPic); +RuntimeScriptValue Sc_GetButtonPic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT3(GetButtonPic); } // int (int xx, int yy) -RuntimeScriptValue Sc_GetCharIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetCharIDAtScreen); +RuntimeScriptValue Sc_GetCharIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetCharIDAtScreen); } // int (int cha, const char *property) -RuntimeScriptValue Sc_GetCharacterProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT_POBJ(GetCharacterProperty, const char); +RuntimeScriptValue Sc_GetCharacterProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT_POBJ(GetCharacterProperty, const char); } // void (int item, const char *property, char *bufer) -RuntimeScriptValue Sc_GetCharacterPropertyText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ2(GetCharacterPropertyText, const char, char); +RuntimeScriptValue Sc_GetCharacterPropertyText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ2(GetCharacterPropertyText, const char, char); } // int () -RuntimeScriptValue Sc_GetCurrentMusic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetCurrentMusic); +RuntimeScriptValue Sc_GetCurrentMusic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetCurrentMusic); } extern RuntimeScriptValue Sc_GetCursorMode(const RuntimeScriptValue *params, int32_t param_count); // int (int dlg, int opt) -RuntimeScriptValue Sc_GetDialogOption(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetDialogOption); +RuntimeScriptValue Sc_GetDialogOption(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetDialogOption); } // int (int opt) -RuntimeScriptValue Sc_GetGameOption(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetGameOption); +RuntimeScriptValue Sc_GetGameOption(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetGameOption); } // int (int parm, int data1, int data2, int data3) -RuntimeScriptValue Sc_GetGameParameter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT4(GetGameParameter); +RuntimeScriptValue Sc_GetGameParameter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT4(GetGameParameter); } // int () -RuntimeScriptValue Sc_GetGameSpeed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetGameSpeed); +RuntimeScriptValue Sc_GetGameSpeed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetGameSpeed); } // int (int index) -RuntimeScriptValue Sc_GetGlobalInt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetGlobalInt); +RuntimeScriptValue Sc_GetGlobalInt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetGlobalInt); } // void (int index, char *strval) -RuntimeScriptValue Sc_GetGlobalString(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(GetGlobalString, char); +RuntimeScriptValue Sc_GetGlobalString(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(GetGlobalString, char); } // int (const char *varName) -RuntimeScriptValue Sc_GetGraphicalVariable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(GetGraphicalVariable, const char); +RuntimeScriptValue Sc_GetGraphicalVariable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(GetGraphicalVariable, const char); } // int (int xx,int yy) -RuntimeScriptValue Sc_GetGUIAt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetGUIAt); +RuntimeScriptValue Sc_GetGUIAt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetGUIAt); } // int (int xx, int yy) -RuntimeScriptValue Sc_GetGUIObjectAt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetGUIObjectAt); +RuntimeScriptValue Sc_GetGUIObjectAt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetGUIObjectAt); } // int (int xxx,int yyy) -RuntimeScriptValue Sc_GetHotspotIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetHotspotIDAtScreen); +RuntimeScriptValue Sc_GetHotspotIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetHotspotIDAtScreen); } // void (int hotspot, char *buffer) -RuntimeScriptValue Sc_GetHotspotName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(GetHotspotName, char); +RuntimeScriptValue Sc_GetHotspotName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(GetHotspotName, char); } // int (int hotspot) -RuntimeScriptValue Sc_GetHotspotPointX(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetHotspotPointX); +RuntimeScriptValue Sc_GetHotspotPointX(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetHotspotPointX); } // int (int hotspot) -RuntimeScriptValue Sc_GetHotspotPointY(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetHotspotPointY); +RuntimeScriptValue Sc_GetHotspotPointY(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetHotspotPointY); } // int (int hss, const char *property) -RuntimeScriptValue Sc_GetHotspotProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT_POBJ(GetHotspotProperty, const char); +RuntimeScriptValue Sc_GetHotspotProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT_POBJ(GetHotspotProperty, const char); } // void (int item, const char *property, char *bufer) -RuntimeScriptValue Sc_GetHotspotPropertyText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ2(GetHotspotPropertyText, const char, char); +RuntimeScriptValue Sc_GetHotspotPropertyText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ2(GetHotspotPropertyText, const char, char); } // int (int xxx, int yyy) -RuntimeScriptValue Sc_GetInvAt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetInvAt); +RuntimeScriptValue Sc_GetInvAt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetInvAt); } // int (int indx) -RuntimeScriptValue Sc_GetInvGraphic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetInvGraphic); +RuntimeScriptValue Sc_GetInvGraphic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetInvGraphic); } // void (int indx,char*buff) -RuntimeScriptValue Sc_GetInvName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(GetInvName, char); +RuntimeScriptValue Sc_GetInvName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(GetInvName, char); } // int (int item, const char *property) -RuntimeScriptValue Sc_GetInvProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT_POBJ(GetInvProperty, const char); +RuntimeScriptValue Sc_GetInvProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT_POBJ(GetInvProperty, const char); } // void (int item, const char *property, char *bufer) -RuntimeScriptValue Sc_GetInvPropertyText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ2(GetInvPropertyText, const char, char); +RuntimeScriptValue Sc_GetInvPropertyText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ2(GetInvPropertyText, const char, char); } // void (int xxx,int yyy,char*tempo) -RuntimeScriptValue Sc_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2_POBJ(GetLocationName, char); +RuntimeScriptValue Sc_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2_POBJ(GetLocationName, char); } // int (int xxx,int yyy) -RuntimeScriptValue Sc_GetLocationType(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetLocationType); +RuntimeScriptValue Sc_GetLocationType(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetLocationType); } // void (int msg, char *buffer) -RuntimeScriptValue Sc_GetMessageText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(GetMessageText, char); +RuntimeScriptValue Sc_GetMessageText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(GetMessageText, char); } // int () -RuntimeScriptValue Sc_GetMIDIPosition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetMIDIPosition); +RuntimeScriptValue Sc_GetMIDIPosition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetMIDIPosition); } // int () -RuntimeScriptValue Sc_GetMP3PosMillis(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetMP3PosMillis); +RuntimeScriptValue Sc_GetMP3PosMillis(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetMP3PosMillis); } // int (int xx,int yy) -RuntimeScriptValue Sc_GetObjectIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetObjectIDAtScreen); +RuntimeScriptValue Sc_GetObjectIDAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetObjectIDAtScreen); } // int (int obn) -RuntimeScriptValue Sc_GetObjectBaseline(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetObjectBaseline); +RuntimeScriptValue Sc_GetObjectBaseline(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetObjectBaseline); } // int (int obn) -RuntimeScriptValue Sc_GetObjectGraphic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetObjectGraphic); +RuntimeScriptValue Sc_GetObjectGraphic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetObjectGraphic); } // void (int obj, char *buffer) -RuntimeScriptValue Sc_GetObjectName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(GetObjectName, char); +RuntimeScriptValue Sc_GetObjectName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(GetObjectName, char); } // int (int hss, const char *property) -RuntimeScriptValue Sc_GetObjectProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT_POBJ(GetObjectProperty, const char); +RuntimeScriptValue Sc_GetObjectProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT_POBJ(GetObjectProperty, const char); } // void (int item, const char *property, char *bufer) -RuntimeScriptValue Sc_GetObjectPropertyText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ2(GetObjectPropertyText, const char, char); +RuntimeScriptValue Sc_GetObjectPropertyText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ2(GetObjectPropertyText, const char, char); } // int (int objj) -RuntimeScriptValue Sc_GetObjectX(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetObjectX); +RuntimeScriptValue Sc_GetObjectX(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetObjectX); } // int (int objj) -RuntimeScriptValue Sc_GetObjectY(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetObjectY); +RuntimeScriptValue Sc_GetObjectY(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetObjectY); } // int () -RuntimeScriptValue Sc_GetPlayerCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetPlayerCharacter); +RuntimeScriptValue Sc_GetPlayerCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetPlayerCharacter); } // int () -RuntimeScriptValue Sc_GetRawTime(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetRawTime); +RuntimeScriptValue Sc_GetRawTime(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetRawTime); } // int (int xxx, int yyy) -RuntimeScriptValue Sc_GetRegionIDAtRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetRegionIDAtRoom); +RuntimeScriptValue Sc_GetRegionIDAtRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetRegionIDAtRoom); } // void (const char *property, char *bufer) -RuntimeScriptValue Sc_GetRoomPropertyText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_POBJ2(GetRoomPropertyText, const char, char); +RuntimeScriptValue Sc_GetRoomPropertyText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_POBJ2(GetRoomPropertyText, const char, char); } // int (int slnum,char*desbuf) -RuntimeScriptValue Sc_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT_POBJ(GetSaveSlotDescription, char); +RuntimeScriptValue Sc_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT_POBJ(GetSaveSlotDescription, char); } // int (int x, int y) -RuntimeScriptValue Sc_GetScalingAt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetScalingAt); +RuntimeScriptValue Sc_GetScalingAt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetScalingAt); } // int (int guin,int objn) -RuntimeScriptValue Sc_GetSliderValue(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetSliderValue); +RuntimeScriptValue Sc_GetSliderValue(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetSliderValue); } // void (int guin, int objn, char*txbuf) -RuntimeScriptValue Sc_GetTextBoxText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2_POBJ(GetTextBoxText, char); +RuntimeScriptValue Sc_GetTextBoxText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2_POBJ(GetTextBoxText, char); } // int (char *text, int fontnum, int width) -RuntimeScriptValue Sc_GetTextHeight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ_PINT2(GetTextHeight, const char); +RuntimeScriptValue Sc_GetTextHeight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ_PINT2(GetTextHeight, const char); } // int (char *text, int fontnum) -RuntimeScriptValue Sc_GetTextWidth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ_PINT(GetTextWidth, const char); +RuntimeScriptValue Sc_GetTextWidth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ_PINT(GetTextWidth, const char); } -RuntimeScriptValue Sc_GetFontHeight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetFontHeight); +RuntimeScriptValue Sc_GetFontHeight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetFontHeight); } -RuntimeScriptValue Sc_GetFontLineSpacing(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(GetFontLineSpacing); +RuntimeScriptValue Sc_GetFontLineSpacing(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(GetFontLineSpacing); } // int (int whatti) -RuntimeScriptValue Sc_sc_GetTime(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(sc_GetTime); +RuntimeScriptValue Sc_sc_GetTime(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(sc_GetTime); } // char * (const char *text) -RuntimeScriptValue Sc_get_translation(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_POBJ(char, myScriptStringImpl, get_translation, const char); +RuntimeScriptValue Sc_get_translation(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_POBJ(char, myScriptStringImpl, get_translation, const char); } // int (char* buffer) -RuntimeScriptValue Sc_GetTranslationName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(GetTranslationName, char); +RuntimeScriptValue Sc_GetTranslationName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(GetTranslationName, char); } // int () -RuntimeScriptValue Sc_GetViewportX(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetViewportX); +RuntimeScriptValue Sc_GetViewportX(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetViewportX); } // int () -RuntimeScriptValue Sc_GetViewportY(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetViewportY); +RuntimeScriptValue Sc_GetViewportY(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetViewportY); } -RuntimeScriptValue Sc_GetWalkableAreaAtRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetWalkableAreaAtRoom); +RuntimeScriptValue Sc_GetWalkableAreaAtRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetWalkableAreaAtRoom); } // int (int xxx,int yyy) -RuntimeScriptValue Sc_GetWalkableAreaAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(GetWalkableAreaAtScreen); +RuntimeScriptValue Sc_GetWalkableAreaAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(GetWalkableAreaAtScreen); } -RuntimeScriptValue Sc_GetDrawingSurfaceForWalkableArea(const RuntimeScriptValue *params, int32_t param_count) -{ - ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkable); - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +RuntimeScriptValue Sc_GetDrawingSurfaceForWalkableArea(const RuntimeScriptValue *params, int32_t param_count) { + ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkable); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); } -RuntimeScriptValue Sc_GetDrawingSurfaceForWalkbehind(const RuntimeScriptValue *params, int32_t param_count) -{ - ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkBehind); - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +RuntimeScriptValue Sc_GetDrawingSurfaceForWalkbehind(const RuntimeScriptValue *params, int32_t param_count) { + ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaWalkBehind); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); } -// void (int amnt) -RuntimeScriptValue Sc_GiveScore(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(GiveScore); +// void (int amnt) +RuntimeScriptValue Sc_GiveScore(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(GiveScore); } // int (int roomnum) -RuntimeScriptValue Sc_HasPlayerBeenInRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(HasPlayerBeenInRoom); +RuntimeScriptValue Sc_HasPlayerBeenInRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(HasPlayerBeenInRoom); } -// void () -RuntimeScriptValue Sc_HideMouseCursor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(HideMouseCursor); +// void () +RuntimeScriptValue Sc_HideMouseCursor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(HideMouseCursor); } // void (const char*msg,char*bufr) -RuntimeScriptValue Sc_sc_inputbox(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_POBJ2(sc_inputbox, const char, char); +RuntimeScriptValue Sc_sc_inputbox(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_POBJ2(sc_inputbox, const char, char); } // void (int ifn) -RuntimeScriptValue Sc_InterfaceOff(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(InterfaceOff); +RuntimeScriptValue Sc_InterfaceOff(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(InterfaceOff); } // void (int ifn) -RuntimeScriptValue Sc_InterfaceOn(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(InterfaceOn); +RuntimeScriptValue Sc_InterfaceOn(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(InterfaceOn); } -// FLOAT_RETURN_TYPE (int value) -RuntimeScriptValue Sc_IntToFloat(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PINT(IntToFloat); +// FLOAT_RETURN_TYPE (int value) +RuntimeScriptValue Sc_IntToFloat(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PINT(IntToFloat); } // void () -RuntimeScriptValue Sc_sc_invscreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(sc_invscreen); +RuntimeScriptValue Sc_sc_invscreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(sc_invscreen); } extern RuntimeScriptValue Sc_IsButtonDown(const RuntimeScriptValue *params, int32_t param_count); // int (int chan) -RuntimeScriptValue Sc_IsChannelPlaying(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsChannelPlaying); +RuntimeScriptValue Sc_IsChannelPlaying(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsChannelPlaying); } // int () -RuntimeScriptValue Sc_IsGamePaused(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(IsGamePaused); +RuntimeScriptValue Sc_IsGamePaused(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(IsGamePaused); } // int (int guinum) -RuntimeScriptValue Sc_IsGUIOn(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsGUIOn); +RuntimeScriptValue Sc_IsGUIOn(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsGUIOn); } // int (int xx,int yy,int mood) -RuntimeScriptValue Sc_IsInteractionAvailable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT3(IsInteractionAvailable); +RuntimeScriptValue Sc_IsInteractionAvailable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT3(IsInteractionAvailable); } // int (int item, int mood) -RuntimeScriptValue Sc_IsInventoryInteractionAvailable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(IsInventoryInteractionAvailable); +RuntimeScriptValue Sc_IsInventoryInteractionAvailable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(IsInventoryInteractionAvailable); } // int () -RuntimeScriptValue Sc_IsInterfaceEnabled(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(IsInterfaceEnabled); +RuntimeScriptValue Sc_IsInterfaceEnabled(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(IsInterfaceEnabled); } // int (int keycode) -RuntimeScriptValue Sc_IsKeyPressed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsKeyPressed); +RuntimeScriptValue Sc_IsKeyPressed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsKeyPressed); } // int () -RuntimeScriptValue Sc_IsMusicPlaying(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(IsMusicPlaying); +RuntimeScriptValue Sc_IsMusicPlaying(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(IsMusicPlaying); } // int () -RuntimeScriptValue Sc_IsMusicVoxAvailable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(IsMusicVoxAvailable); +RuntimeScriptValue Sc_IsMusicVoxAvailable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(IsMusicVoxAvailable); } // int (int objj) -RuntimeScriptValue Sc_IsObjectAnimating(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsObjectAnimating); +RuntimeScriptValue Sc_IsObjectAnimating(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsObjectAnimating); } // int (int objj) -RuntimeScriptValue Sc_IsObjectMoving(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsObjectMoving); +RuntimeScriptValue Sc_IsObjectMoving(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsObjectMoving); } // int (int objj) -RuntimeScriptValue Sc_IsObjectOn(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsObjectOn); +RuntimeScriptValue Sc_IsObjectOn(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsObjectOn); } // int (int ovrid) -RuntimeScriptValue Sc_IsOverlayValid(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsOverlayValid); +RuntimeScriptValue Sc_IsOverlayValid(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsOverlayValid); } // int () -RuntimeScriptValue Sc_IsSoundPlaying(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(IsSoundPlaying); +RuntimeScriptValue Sc_IsSoundPlaying(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(IsSoundPlaying); } // int (int tnum) -RuntimeScriptValue Sc_IsTimerExpired(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsTimerExpired); +RuntimeScriptValue Sc_IsTimerExpired(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsTimerExpired); } // int () -RuntimeScriptValue Sc_IsTranslationAvailable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(IsTranslationAvailable); +RuntimeScriptValue Sc_IsTranslationAvailable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(IsTranslationAvailable); } // int () -RuntimeScriptValue Sc_IsVoxAvailable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(IsVoxAvailable); +RuntimeScriptValue Sc_IsVoxAvailable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(IsVoxAvailable); } // void (int guin, int objn, const char*newitem) -RuntimeScriptValue Sc_ListBoxAdd(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2_POBJ(ListBoxAdd, const char); +RuntimeScriptValue Sc_ListBoxAdd(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2_POBJ(ListBoxAdd, const char); } // void (int guin, int objn) -RuntimeScriptValue Sc_ListBoxClear(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(ListBoxClear); +RuntimeScriptValue Sc_ListBoxClear(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(ListBoxClear); } // void (int guin, int objn, const char*filemask) -RuntimeScriptValue Sc_ListBoxDirList(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2_POBJ(ListBoxDirList, const char); +RuntimeScriptValue Sc_ListBoxDirList(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2_POBJ(ListBoxDirList, const char); } // char* (int guin, int objn, int item, char*buffer) -RuntimeScriptValue Sc_ListBoxGetItemText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT3_POBJ(char, myScriptStringImpl, ListBoxGetItemText, char); +RuntimeScriptValue Sc_ListBoxGetItemText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT3_POBJ(char, myScriptStringImpl, ListBoxGetItemText, char); } // int (int guin, int objn) -RuntimeScriptValue Sc_ListBoxGetNumItems(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(ListBoxGetNumItems); +RuntimeScriptValue Sc_ListBoxGetNumItems(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(ListBoxGetNumItems); } // int (int guin, int objn) -RuntimeScriptValue Sc_ListBoxGetSelected(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(ListBoxGetSelected); +RuntimeScriptValue Sc_ListBoxGetSelected(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(ListBoxGetSelected); } // void (int guin, int objn, int itemIndex) -RuntimeScriptValue Sc_ListBoxRemove(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(ListBoxRemove); +RuntimeScriptValue Sc_ListBoxRemove(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(ListBoxRemove); } // int (int guin, int objn) -RuntimeScriptValue Sc_ListBoxSaveGameList(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(ListBoxSaveGameList); +RuntimeScriptValue Sc_ListBoxSaveGameList(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(ListBoxSaveGameList); } // void (int guin, int objn, int newsel) -RuntimeScriptValue Sc_ListBoxSetSelected(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(ListBoxSetSelected); +RuntimeScriptValue Sc_ListBoxSetSelected(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(ListBoxSetSelected); } // void (int guin, int objn, int item) -RuntimeScriptValue Sc_ListBoxSetTopItem(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(ListBoxSetTopItem); +RuntimeScriptValue Sc_ListBoxSetTopItem(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(ListBoxSetTopItem); } // int (const char *filename) -RuntimeScriptValue Sc_LoadImageFile(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(LoadImageFile, const char); +RuntimeScriptValue Sc_LoadImageFile(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(LoadImageFile, const char); } // int (int slnum, int width, int height) -RuntimeScriptValue Sc_LoadSaveSlotScreenshot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT3(LoadSaveSlotScreenshot); +RuntimeScriptValue Sc_LoadSaveSlotScreenshot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT3(LoadSaveSlotScreenshot); } // void (int inum) -RuntimeScriptValue Sc_lose_inventory(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(lose_inventory); +RuntimeScriptValue Sc_lose_inventory(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(lose_inventory); } // void (int charid, int inum) -RuntimeScriptValue Sc_LoseInventoryFromCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(LoseInventoryFromCharacter); +RuntimeScriptValue Sc_LoseInventoryFromCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(LoseInventoryFromCharacter); } // void (int obn) -RuntimeScriptValue Sc_MergeObject(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(MergeObject); +RuntimeScriptValue Sc_MergeObject(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(MergeObject); } // void (int cc,int xx,int yy) -RuntimeScriptValue Sc_MoveCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(MoveCharacter); +RuntimeScriptValue Sc_MoveCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(MoveCharacter); } // void (int chaa,int xx,int yy,int direct) -RuntimeScriptValue Sc_MoveCharacterBlocking(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(MoveCharacterBlocking); +RuntimeScriptValue Sc_MoveCharacterBlocking(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(MoveCharacterBlocking); } // void (int cc,int xx, int yy) -RuntimeScriptValue Sc_MoveCharacterDirect(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(MoveCharacterDirect); +RuntimeScriptValue Sc_MoveCharacterDirect(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(MoveCharacterDirect); } // void (int chac, int tox, int toy) -RuntimeScriptValue Sc_MoveCharacterPath(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(MoveCharacterPath); +RuntimeScriptValue Sc_MoveCharacterPath(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(MoveCharacterPath); } // void (int cc,int xx, int yy) -RuntimeScriptValue Sc_MoveCharacterStraight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(MoveCharacterStraight); +RuntimeScriptValue Sc_MoveCharacterStraight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(MoveCharacterStraight); } // void (int chaa,int hotsp) -RuntimeScriptValue Sc_MoveCharacterToHotspot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(MoveCharacterToHotspot); +RuntimeScriptValue Sc_MoveCharacterToHotspot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(MoveCharacterToHotspot); } // void (int chaa,int obbj) -RuntimeScriptValue Sc_MoveCharacterToObject(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(MoveCharacterToObject); +RuntimeScriptValue Sc_MoveCharacterToObject(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(MoveCharacterToObject); } // void (int objj,int xx,int yy,int spp) -RuntimeScriptValue Sc_MoveObject(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(MoveObject); +RuntimeScriptValue Sc_MoveObject(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(MoveObject); } // void (int objj,int xx,int yy,int spp) -RuntimeScriptValue Sc_MoveObjectDirect(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(MoveObjectDirect); +RuntimeScriptValue Sc_MoveObjectDirect(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(MoveObjectDirect); } // void (int ovrid, int newx,int newy) -RuntimeScriptValue Sc_MoveOverlay(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(MoveOverlay); +RuntimeScriptValue Sc_MoveOverlay(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(MoveOverlay); } // void (int charid) -RuntimeScriptValue Sc_MoveToWalkableArea(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(MoveToWalkableArea); +RuntimeScriptValue Sc_MoveToWalkableArea(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(MoveToWalkableArea); } // void (int nrnum) -RuntimeScriptValue Sc_NewRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(NewRoom); +RuntimeScriptValue Sc_NewRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(NewRoom); } // void (int nrnum,int newx,int newy) -RuntimeScriptValue Sc_NewRoomEx(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(NewRoomEx); +RuntimeScriptValue Sc_NewRoomEx(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(NewRoomEx); } // void (int charid, int nrnum, int newx, int newy) -RuntimeScriptValue Sc_NewRoomNPC(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(NewRoomNPC); +RuntimeScriptValue Sc_NewRoomNPC(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(NewRoomNPC); } // void (int obn) -RuntimeScriptValue Sc_ObjectOff(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(ObjectOff); +RuntimeScriptValue Sc_ObjectOff(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(ObjectOff); } // void (int obn) -RuntimeScriptValue Sc_ObjectOn(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(ObjectOn); +RuntimeScriptValue Sc_ObjectOn(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(ObjectOn); } extern RuntimeScriptValue Sc_ParseText(const RuntimeScriptValue *params, int32_t param_count); // void () -RuntimeScriptValue Sc_PauseGame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(PauseGame); +RuntimeScriptValue Sc_PauseGame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(PauseGame); } // void (int channel, int sndnum, int vol, int x, int y) -RuntimeScriptValue Sc_PlayAmbientSound(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT5(PlayAmbientSound); +RuntimeScriptValue Sc_PlayAmbientSound(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT5(PlayAmbientSound); } // void (int numb,int playflags) -RuntimeScriptValue Sc_play_flc_file(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(play_flc_file); +RuntimeScriptValue Sc_play_flc_file(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(play_flc_file); } // void (char *filename) -RuntimeScriptValue Sc_PlayMP3File(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_POBJ(PlayMP3File, const char); +RuntimeScriptValue Sc_PlayMP3File(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_POBJ(PlayMP3File, const char); } // void (int newmus) -RuntimeScriptValue Sc_PlayMusicResetQueue(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(PlayMusicResetQueue); +RuntimeScriptValue Sc_PlayMusicResetQueue(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(PlayMusicResetQueue); } // int (int musnum) -RuntimeScriptValue Sc_PlayMusicQueued(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(PlayMusicQueued); +RuntimeScriptValue Sc_PlayMusicQueued(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(PlayMusicQueued); } // void (int mnum) -RuntimeScriptValue Sc_PlaySilentMIDI(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(PlaySilentMIDI); +RuntimeScriptValue Sc_PlaySilentMIDI(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(PlaySilentMIDI); } // int (int val1) -RuntimeScriptValue Sc_play_sound(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(play_sound); +RuntimeScriptValue Sc_play_sound(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(play_sound); } // int (int val1, int channel) -RuntimeScriptValue Sc_PlaySoundEx(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(PlaySoundEx); +RuntimeScriptValue Sc_PlaySoundEx(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(PlaySoundEx); } // void (const char* name, int skip, int flags) -RuntimeScriptValue Sc_scrPlayVideo(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_POBJ_PINT2(scrPlayVideo, const char); +RuntimeScriptValue Sc_scrPlayVideo(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_POBJ_PINT2(scrPlayVideo, const char); } // void (int dialog) -RuntimeScriptValue Sc_QuitGame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(QuitGame); +RuntimeScriptValue Sc_QuitGame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(QuitGame); } // int (int upto) -RuntimeScriptValue Sc_Rand(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(__Rand); +RuntimeScriptValue Sc_Rand(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(__Rand); } // void (int clr) -RuntimeScriptValue Sc_RawClear(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RawClear); +RuntimeScriptValue Sc_RawClear(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RawClear); } // void (int xx, int yy, int rad) -RuntimeScriptValue Sc_RawDrawCircle(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(RawDrawCircle); +RuntimeScriptValue Sc_RawDrawCircle(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(RawDrawCircle); } // void (int frame, int translev) -RuntimeScriptValue Sc_RawDrawFrameTransparent(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(RawDrawFrameTransparent); +RuntimeScriptValue Sc_RawDrawFrameTransparent(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(RawDrawFrameTransparent); } // void (int xx, int yy, int slot) -RuntimeScriptValue Sc_RawDrawImage(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(RawDrawImage); +RuntimeScriptValue Sc_RawDrawImage(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(RawDrawImage); } // void (int xx, int yy, int slot) -RuntimeScriptValue Sc_RawDrawImageOffset(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(RawDrawImageOffset); +RuntimeScriptValue Sc_RawDrawImageOffset(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(RawDrawImageOffset); } // void (int xx, int yy, int gotSlot, int width, int height) -RuntimeScriptValue Sc_RawDrawImageResized(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT5(RawDrawImageResized); +RuntimeScriptValue Sc_RawDrawImageResized(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT5(RawDrawImageResized); } // void (int xx, int yy, int slot, int trans) -RuntimeScriptValue Sc_RawDrawImageTransparent(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(RawDrawImageTransparent); +RuntimeScriptValue Sc_RawDrawImageTransparent(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(RawDrawImageTransparent); } // void (int fromx, int fromy, int tox, int toy) -RuntimeScriptValue Sc_RawDrawLine(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(RawDrawLine); +RuntimeScriptValue Sc_RawDrawLine(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(RawDrawLine); } // void (int x1, int y1, int x2, int y2) -RuntimeScriptValue Sc_RawDrawRectangle(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(RawDrawRectangle); +RuntimeScriptValue Sc_RawDrawRectangle(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(RawDrawRectangle); } // void (int x1, int y1, int x2, int y2, int x3, int y3) -RuntimeScriptValue Sc_RawDrawTriangle(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT6(RawDrawTriangle); +RuntimeScriptValue Sc_RawDrawTriangle(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT6(RawDrawTriangle); } // void (int xx, int yy, char*texx, ...) -RuntimeScriptValue Sc_RawPrint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(RawPrint, 3); - RawPrint(params[0].IValue, params[1].IValue, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_RawPrint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(RawPrint, 3); + RawPrint(params[0].IValue, params[1].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (int xx, int yy, int wid, int font, int msgm) -RuntimeScriptValue Sc_RawPrintMessageWrapped(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT5(RawPrintMessageWrapped); +RuntimeScriptValue Sc_RawPrintMessageWrapped(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT5(RawPrintMessageWrapped); } // void () -RuntimeScriptValue Sc_RawRestoreScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(RawRestoreScreen); +RuntimeScriptValue Sc_RawRestoreScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(RawRestoreScreen); } // void (int red, int green, int blue, int opacity) -RuntimeScriptValue Sc_RawRestoreScreenTinted(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(RawRestoreScreenTinted); +RuntimeScriptValue Sc_RawRestoreScreenTinted(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(RawRestoreScreenTinted); } // void () -RuntimeScriptValue Sc_RawSaveScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(RawSaveScreen); +RuntimeScriptValue Sc_RawSaveScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(RawSaveScreen); } // void (int clr) -RuntimeScriptValue Sc_RawSetColor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RawSetColor); +RuntimeScriptValue Sc_RawSetColor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RawSetColor); } // void (int red, int grn, int blu) -RuntimeScriptValue Sc_RawSetColorRGB(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(RawSetColorRGB); +RuntimeScriptValue Sc_RawSetColorRGB(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(RawSetColorRGB); } extern RuntimeScriptValue Sc_RefreshMouse(const RuntimeScriptValue *params, int32_t param_count); // void (int chat) -RuntimeScriptValue Sc_ReleaseCharacterView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(ReleaseCharacterView); +RuntimeScriptValue Sc_ReleaseCharacterView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(ReleaseCharacterView); } // void () -RuntimeScriptValue Sc_ReleaseViewport(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(ReleaseViewport); +RuntimeScriptValue Sc_ReleaseViewport(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(ReleaseViewport); } // void (int obj) -RuntimeScriptValue Sc_RemoveObjectTint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RemoveObjectTint); +RuntimeScriptValue Sc_RemoveObjectTint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RemoveObjectTint); } // void (int ovrid) -RuntimeScriptValue Sc_RemoveOverlay(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RemoveOverlay); +RuntimeScriptValue Sc_RemoveOverlay(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RemoveOverlay); } // void (int areanum) -RuntimeScriptValue Sc_RemoveWalkableArea(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RemoveWalkableArea); +RuntimeScriptValue Sc_RemoveWalkableArea(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RemoveWalkableArea); } // void (int nrnum) -RuntimeScriptValue Sc_ResetRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(ResetRoom); +RuntimeScriptValue Sc_ResetRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(ResetRoom); } // void () -RuntimeScriptValue Sc_restart_game(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(restart_game); +RuntimeScriptValue Sc_restart_game(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(restart_game); } // void () -RuntimeScriptValue Sc_restore_game_dialog(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(restore_game_dialog); +RuntimeScriptValue Sc_restore_game_dialog(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(restore_game_dialog); } // void (int slnum) -RuntimeScriptValue Sc_RestoreGameSlot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RestoreGameSlot); +RuntimeScriptValue Sc_RestoreGameSlot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RestoreGameSlot); } // void (int areanum) -RuntimeScriptValue Sc_RestoreWalkableArea(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RestoreWalkableArea); +RuntimeScriptValue Sc_RestoreWalkableArea(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RestoreWalkableArea); } // int (char *newgame, unsigned int mode, int data) -RuntimeScriptValue Sc_RunAGSGame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ_PINT2(RunAGSGame, const char); +RuntimeScriptValue Sc_RunAGSGame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ_PINT2(RunAGSGame, const char); } // void (int cc, int mood) -RuntimeScriptValue Sc_RunCharacterInteraction(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(RunCharacterInteraction); +RuntimeScriptValue Sc_RunCharacterInteraction(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(RunCharacterInteraction); } // void (int tum) -RuntimeScriptValue Sc_RunDialog(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(RunDialog); +RuntimeScriptValue Sc_RunDialog(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(RunDialog); } // void (int hotspothere, int mood) -RuntimeScriptValue Sc_RunHotspotInteraction(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(RunHotspotInteraction); +RuntimeScriptValue Sc_RunHotspotInteraction(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(RunHotspotInteraction); } // void (int iit, int modd) -RuntimeScriptValue Sc_RunInventoryInteraction(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(RunInventoryInteraction); +RuntimeScriptValue Sc_RunInventoryInteraction(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(RunInventoryInteraction); } // void (int aa, int mood) -RuntimeScriptValue Sc_RunObjectInteraction(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(RunObjectInteraction); +RuntimeScriptValue Sc_RunObjectInteraction(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(RunObjectInteraction); } // void (int regnum, int mood) -RuntimeScriptValue Sc_RunRegionInteraction(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(RunRegionInteraction); +RuntimeScriptValue Sc_RunRegionInteraction(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(RunRegionInteraction); } extern RuntimeScriptValue Sc_Said(const RuntimeScriptValue *params, int32_t param_count); // int (char*buffer) -RuntimeScriptValue Sc_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(SaidUnknownWord, char); +RuntimeScriptValue Sc_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(SaidUnknownWord, char); } extern RuntimeScriptValue Sc_SaveCursorForLocationChange(const RuntimeScriptValue *params, int32_t param_count); // void () -RuntimeScriptValue Sc_save_game_dialog(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(save_game_dialog); +RuntimeScriptValue Sc_save_game_dialog(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(save_game_dialog); } // void (int slotn, const char*descript) -RuntimeScriptValue Sc_save_game(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(save_game, const char); +RuntimeScriptValue Sc_save_game(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(save_game, const char); } // int (char*namm) -RuntimeScriptValue Sc_SaveScreenShot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(SaveScreenShot, const char); +RuntimeScriptValue Sc_SaveScreenShot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(SaveScreenShot, const char); } // void (int position) -RuntimeScriptValue Sc_SeekMIDIPosition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SeekMIDIPosition); +RuntimeScriptValue Sc_SeekMIDIPosition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SeekMIDIPosition); } // void (int patnum) -RuntimeScriptValue Sc_SeekMODPattern(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SeekMODPattern); +RuntimeScriptValue Sc_SeekMODPattern(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SeekMODPattern); } // void (int posn) -RuntimeScriptValue Sc_SeekMP3PosMillis(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SeekMP3PosMillis); +RuntimeScriptValue Sc_SeekMP3PosMillis(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SeekMP3PosMillis); } // void (int iit) -RuntimeScriptValue Sc_SetActiveInventory(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetActiveInventory); +RuntimeScriptValue Sc_SetActiveInventory(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetActiveInventory); } // void (int red, int green, int blue, int opacity, int luminance) -RuntimeScriptValue Sc_SetAmbientTint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT5(SetAmbientTint); +RuntimeScriptValue Sc_SetAmbientTint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT5(SetAmbientTint); } -RuntimeScriptValue Sc_SetAmbientLightLevel(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetAmbientLightLevel); +RuntimeScriptValue Sc_SetAmbientLightLevel(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetAmbientLightLevel); } // void (int area, int brightness) -RuntimeScriptValue Sc_SetAreaLightLevel(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetAreaLightLevel); +RuntimeScriptValue Sc_SetAreaLightLevel(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetAreaLightLevel); } // void (int area, int min, int max) -RuntimeScriptValue Sc_SetAreaScaling(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetAreaScaling); +RuntimeScriptValue Sc_SetAreaScaling(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetAreaScaling); } // void (int frnum) -RuntimeScriptValue Sc_SetBackgroundFrame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetBackgroundFrame); +RuntimeScriptValue Sc_SetBackgroundFrame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetBackgroundFrame); } // void (int guin,int objn,int ptype,int slotn) -RuntimeScriptValue Sc_SetButtonPic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetButtonPic); +RuntimeScriptValue Sc_SetButtonPic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetButtonPic); } // void (int guin,int objn,char*newtx) -RuntimeScriptValue Sc_SetButtonText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2_POBJ(SetButtonText, const char); +RuntimeScriptValue Sc_SetButtonText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2_POBJ(SetButtonText, const char); } // void (int chan, int newvol) -RuntimeScriptValue Sc_SetChannelVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetChannelVolume); +RuntimeScriptValue Sc_SetChannelVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetChannelVolume); } // void (int obn, int basel) -RuntimeScriptValue Sc_SetCharacterBaseline(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterBaseline); +RuntimeScriptValue Sc_SetCharacterBaseline(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterBaseline); } // void (int cha, int clik) -RuntimeScriptValue Sc_SetCharacterClickable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterClickable); +RuntimeScriptValue Sc_SetCharacterClickable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterClickable); } // void (int chaa, int view, int loop, int frame) -RuntimeScriptValue Sc_SetCharacterFrame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetCharacterFrame); +RuntimeScriptValue Sc_SetCharacterFrame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetCharacterFrame); } // void (int who, int iview, int itime) -RuntimeScriptValue Sc_SetCharacterIdle(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetCharacterIdle); +RuntimeScriptValue Sc_SetCharacterIdle(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetCharacterIdle); } // void (int who, int yesorno) -RuntimeScriptValue Sc_SetCharacterIgnoreLight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterIgnoreLight); +RuntimeScriptValue Sc_SetCharacterIgnoreLight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterIgnoreLight); } // void (int cha, int clik) -RuntimeScriptValue Sc_SetCharacterIgnoreWalkbehinds(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterIgnoreWalkbehinds); +RuntimeScriptValue Sc_SetCharacterIgnoreWalkbehinds(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterIgnoreWalkbehinds); } // void (int who, int flag, int yesorno) -RuntimeScriptValue Sc_SetCharacterProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetCharacterProperty); +RuntimeScriptValue Sc_SetCharacterProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetCharacterProperty); } // void (int chaa, int vii, int intrv) -RuntimeScriptValue Sc_SetCharacterBlinkView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetCharacterBlinkView); +RuntimeScriptValue Sc_SetCharacterBlinkView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetCharacterBlinkView); } // void (int chaa, int vii) -RuntimeScriptValue Sc_SetCharacterSpeechView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterSpeechView); +RuntimeScriptValue Sc_SetCharacterSpeechView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterSpeechView); } // void (int chaa,int nspeed) -RuntimeScriptValue Sc_SetCharacterSpeed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterSpeed); +RuntimeScriptValue Sc_SetCharacterSpeed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterSpeed); } // void (int chaa, int xspeed, int yspeed) -RuntimeScriptValue Sc_SetCharacterSpeedEx(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetCharacterSpeedEx); +RuntimeScriptValue Sc_SetCharacterSpeedEx(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetCharacterSpeedEx); } // void (int obn,int trans) -RuntimeScriptValue Sc_SetCharacterTransparency(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterTransparency); +RuntimeScriptValue Sc_SetCharacterTransparency(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterTransparency); } // void (int chaa,int vii) -RuntimeScriptValue Sc_SetCharacterView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetCharacterView); +RuntimeScriptValue Sc_SetCharacterView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetCharacterView); } // void (int chaa, int vii, int loop, int align) -RuntimeScriptValue Sc_SetCharacterViewEx(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetCharacterViewEx); +RuntimeScriptValue Sc_SetCharacterViewEx(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetCharacterViewEx); } // void (int chaa, int vii, int xoffs, int yoffs) -RuntimeScriptValue Sc_SetCharacterViewOffset(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetCharacterViewOffset); +RuntimeScriptValue Sc_SetCharacterViewOffset(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetCharacterViewOffset); } extern RuntimeScriptValue Sc_set_cursor_mode(const RuntimeScriptValue *params, int32_t param_count); extern RuntimeScriptValue Sc_set_default_cursor(const RuntimeScriptValue *params, int32_t param_count); // void (int dlg,int opt,int onoroff) -RuntimeScriptValue Sc_SetDialogOption(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetDialogOption); +RuntimeScriptValue Sc_SetDialogOption(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetDialogOption); } // void (int newvol) -RuntimeScriptValue Sc_SetDigitalMasterVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetDigitalMasterVolume); +RuntimeScriptValue Sc_SetDigitalMasterVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetDigitalMasterVolume); } // void (int red, int green, int blue) -RuntimeScriptValue Sc_SetFadeColor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetFadeColor); +RuntimeScriptValue Sc_SetFadeColor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetFadeColor); } // void (int vii, int loop, int frame, int sound) -RuntimeScriptValue Sc_SetFrameSound(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetFrameSound); +RuntimeScriptValue Sc_SetFrameSound(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetFrameSound); } // int (int opt, int setting) -RuntimeScriptValue Sc_SetGameOption(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT2(SetGameOption); +RuntimeScriptValue Sc_SetGameOption(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT2(SetGameOption); } // void (int newspd) -RuntimeScriptValue Sc_SetGameSpeed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetGameSpeed); +RuntimeScriptValue Sc_SetGameSpeed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetGameSpeed); } // void (int index,int valu) -RuntimeScriptValue Sc_SetGlobalInt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetGlobalInt); +RuntimeScriptValue Sc_SetGlobalInt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetGlobalInt); } extern RuntimeScriptValue Sc_SetGlobalString(const RuntimeScriptValue *params, int32_t param_count); // void (const char *varName, int p_value) -RuntimeScriptValue Sc_SetGraphicalVariable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_POBJ_PINT(SetGraphicalVariable, const char); +RuntimeScriptValue Sc_SetGraphicalVariable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_POBJ_PINT(SetGraphicalVariable, const char); } // void (int guin, int slotn) -RuntimeScriptValue Sc_SetGUIBackgroundPic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetGUIBackgroundPic); +RuntimeScriptValue Sc_SetGUIBackgroundPic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetGUIBackgroundPic); } // void (int guin, int clickable) -RuntimeScriptValue Sc_SetGUIClickable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetGUIClickable); +RuntimeScriptValue Sc_SetGUIClickable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetGUIClickable); } // void (int guin, int objn, int enabled) -RuntimeScriptValue Sc_SetGUIObjectEnabled(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetGUIObjectEnabled); +RuntimeScriptValue Sc_SetGUIObjectEnabled(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetGUIObjectEnabled); } // void (int guin, int objn, int xx, int yy) -RuntimeScriptValue Sc_SetGUIObjectPosition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetGUIObjectPosition); +RuntimeScriptValue Sc_SetGUIObjectPosition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetGUIObjectPosition); } // void (int ifn, int objn, int newwid, int newhit) -RuntimeScriptValue Sc_SetGUIObjectSize(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetGUIObjectSize); +RuntimeScriptValue Sc_SetGUIObjectSize(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetGUIObjectSize); } // void (int ifn,int xx,int yy) -RuntimeScriptValue Sc_SetGUIPosition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetGUIPosition); +RuntimeScriptValue Sc_SetGUIPosition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetGUIPosition); } // void (int ifn, int widd, int hitt) -RuntimeScriptValue Sc_SetGUISize(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetGUISize); +RuntimeScriptValue Sc_SetGUISize(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetGUISize); } // void (int ifn, int trans) -RuntimeScriptValue Sc_SetGUITransparency(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetGUITransparency); +RuntimeScriptValue Sc_SetGUITransparency(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetGUITransparency); } // void (int guin, int z) -RuntimeScriptValue Sc_SetGUIZOrder(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetGUIZOrder); +RuntimeScriptValue Sc_SetGUIZOrder(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetGUIZOrder); } // void (int invi, const char *newName) -RuntimeScriptValue Sc_SetInvItemName(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT_POBJ(SetInvItemName, const char); +RuntimeScriptValue Sc_SetInvItemName(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT_POBJ(SetInvItemName, const char); } // void (int invi, int piccy) -RuntimeScriptValue Sc_set_inv_item_pic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(set_inv_item_pic); +RuntimeScriptValue Sc_set_inv_item_pic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(set_inv_item_pic); } // void (int ww,int hh) -RuntimeScriptValue Sc_SetInvDimensions(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetInvDimensions); +RuntimeScriptValue Sc_SetInvDimensions(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetInvDimensions); } // void (int guin,int objn, int colr) -RuntimeScriptValue Sc_SetLabelColor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetLabelColor); +RuntimeScriptValue Sc_SetLabelColor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetLabelColor); } // void (int guin,int objn, int fontnum) -RuntimeScriptValue Sc_SetLabelFont(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetLabelFont); +RuntimeScriptValue Sc_SetLabelFont(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetLabelFont); } // void (int guin,int objn,char*newtx) -RuntimeScriptValue Sc_SetLabelText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2_POBJ(SetLabelText, const char); +RuntimeScriptValue Sc_SetLabelText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2_POBJ(SetLabelText, const char); } extern RuntimeScriptValue Sc_SetMouseBounds(const RuntimeScriptValue *params, int32_t param_count); @@ -1806,427 +1526,360 @@ extern RuntimeScriptValue Sc_set_mouse_cursor(const RuntimeScriptValue *params, extern RuntimeScriptValue Sc_SetMousePosition(const RuntimeScriptValue *params, int32_t param_count); // void (int mode) -RuntimeScriptValue Sc_SetMultitasking(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetMultitasking); +RuntimeScriptValue Sc_SetMultitasking(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetMultitasking); } // void (int newvol) -RuntimeScriptValue Sc_SetMusicMasterVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetMusicMasterVolume); +RuntimeScriptValue Sc_SetMusicMasterVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetMusicMasterVolume); } // void (int loopflag) -RuntimeScriptValue Sc_SetMusicRepeat(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetMusicRepeat); +RuntimeScriptValue Sc_SetMusicRepeat(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetMusicRepeat); } // void (int newvol) -RuntimeScriptValue Sc_SetMusicVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetMusicVolume); +RuntimeScriptValue Sc_SetMusicVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetMusicVolume); } extern RuntimeScriptValue Sc_SetNextCursor(const RuntimeScriptValue *params, int32_t param_count); // void (int newtrans) -RuntimeScriptValue Sc_SetNextScreenTransition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetNextScreenTransition); +RuntimeScriptValue Sc_SetNextScreenTransition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetNextScreenTransition); } extern RuntimeScriptValue Sc_SetNormalFont(const RuntimeScriptValue *params, int32_t param_count); // void (int obn, int basel) -RuntimeScriptValue Sc_SetObjectBaseline(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetObjectBaseline); +RuntimeScriptValue Sc_SetObjectBaseline(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetObjectBaseline); } // void (int cha, int clik) -RuntimeScriptValue Sc_SetObjectClickable(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetObjectClickable); +RuntimeScriptValue Sc_SetObjectClickable(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetObjectClickable); } // void (int obn,int viw,int lop,int fra) -RuntimeScriptValue Sc_SetObjectFrame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetObjectFrame); +RuntimeScriptValue Sc_SetObjectFrame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetObjectFrame); } -// void (int obn,int slott) -RuntimeScriptValue Sc_SetObjectGraphic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetObjectGraphic); +// void (int obn,int slott) +RuntimeScriptValue Sc_SetObjectGraphic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetObjectGraphic); } // void (int cha, int clik) -RuntimeScriptValue Sc_SetObjectIgnoreWalkbehinds(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetObjectIgnoreWalkbehinds); +RuntimeScriptValue Sc_SetObjectIgnoreWalkbehinds(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetObjectIgnoreWalkbehinds); } // void (int objj, int tox, int toy) -RuntimeScriptValue Sc_SetObjectPosition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetObjectPosition); +RuntimeScriptValue Sc_SetObjectPosition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetObjectPosition); } // void (int obj, int red, int green, int blue, int opacity, int luminance) -RuntimeScriptValue Sc_SetObjectTint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT6(SetObjectTint); +RuntimeScriptValue Sc_SetObjectTint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT6(SetObjectTint); } // void (int obn,int trans) -RuntimeScriptValue Sc_SetObjectTransparency(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetObjectTransparency); +RuntimeScriptValue Sc_SetObjectTransparency(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetObjectTransparency); } // void (int obn,int vii) -RuntimeScriptValue Sc_SetObjectView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetObjectView); +RuntimeScriptValue Sc_SetObjectView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetObjectView); } // void (int inndx,int rr,int gg,int bb) -RuntimeScriptValue Sc_SetPalRGB(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetPalRGB); +RuntimeScriptValue Sc_SetPalRGB(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetPalRGB); } // void (int newchar) -RuntimeScriptValue Sc_SetPlayerCharacter(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetPlayerCharacter); +RuntimeScriptValue Sc_SetPlayerCharacter(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetPlayerCharacter); } // void (int area, int red, int green, int blue, int amount) -RuntimeScriptValue Sc_SetRegionTint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT5(SetRegionTint); +RuntimeScriptValue Sc_SetRegionTint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT5(SetRegionTint); } // void () -RuntimeScriptValue Sc_SetRestartPoint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(SetRestartPoint); +RuntimeScriptValue Sc_SetRestartPoint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(SetRestartPoint); } // void (int newtrans) -RuntimeScriptValue Sc_SetScreenTransition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetScreenTransition); +RuntimeScriptValue Sc_SetScreenTransition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetScreenTransition); } // void (int newval) -RuntimeScriptValue Sc_SetSkipSpeech(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_PARAM_COUNT(SetSkipSpeech, 1); - SetSkipSpeech((SkipSpeechStyle)params[0].IValue); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_SetSkipSpeech(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_PARAM_COUNT(SetSkipSpeech, 1); + SetSkipSpeech((SkipSpeechStyle)params[0].IValue); + return RuntimeScriptValue((int32_t)0); } // void (int guin,int objn, int valn) -RuntimeScriptValue Sc_SetSliderValue(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetSliderValue); +RuntimeScriptValue Sc_SetSliderValue(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetSliderValue); } // void (int newvol) -RuntimeScriptValue Sc_SetSoundVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetSoundVolume); +RuntimeScriptValue Sc_SetSoundVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetSoundVolume); } extern RuntimeScriptValue Sc_SetSpeechFont(const RuntimeScriptValue *params, int32_t param_count); // void (int newstyle) -RuntimeScriptValue Sc_SetSpeechStyle(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetSpeechStyle); +RuntimeScriptValue Sc_SetSpeechStyle(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetSpeechStyle); } // void (int newvol) -RuntimeScriptValue Sc_SetSpeechVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetSpeechVolume); +RuntimeScriptValue Sc_SetSpeechVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetSpeechVolume); } // void (int chaa,int ncol) -RuntimeScriptValue Sc_SetTalkingColor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetTalkingColor); +RuntimeScriptValue Sc_SetTalkingColor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetTalkingColor); } // void (int guin,int objn, int fontnum) -RuntimeScriptValue Sc_SetTextBoxFont(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(SetTextBoxFont); +RuntimeScriptValue Sc_SetTextBoxFont(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(SetTextBoxFont); } // void (int guin, int objn, char*txbuf) -RuntimeScriptValue Sc_SetTextBoxText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2_POBJ(SetTextBoxText, const char); +RuntimeScriptValue Sc_SetTextBoxText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2_POBJ(SetTextBoxText, const char); } // void (int ovrid,int xx,int yy,int wii,int fontid,int clr,char*texx,...) -RuntimeScriptValue Sc_SetTextOverlay(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(SetTextOverlay, 7); - SetTextOverlay(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, - params[4].IValue, params[5].IValue, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_SetTextOverlay(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(SetTextOverlay, 7); + SetTextOverlay(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, + params[4].IValue, params[5].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (int guinum) -RuntimeScriptValue Sc_SetTextWindowGUI(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetTextWindowGUI); +RuntimeScriptValue Sc_SetTextWindowGUI(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetTextWindowGUI); } // void (int tnum,int timeout) -RuntimeScriptValue Sc_script_SetTimer(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(script_SetTimer); +RuntimeScriptValue Sc_script_SetTimer(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(script_SetTimer); } // void (int offsx,int offsy) -RuntimeScriptValue Sc_SetViewport(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetViewport); +RuntimeScriptValue Sc_SetViewport(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetViewport); } // void (int newmod) -RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SetVoiceMode); +RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SetVoiceMode); } // void (int wa,int bl) -RuntimeScriptValue Sc_SetWalkBehindBase(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetWalkBehindBase); +RuntimeScriptValue Sc_SetWalkBehindBase(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetWalkBehindBase); } // void (int severe) -RuntimeScriptValue Sc_ShakeScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(ShakeScreen); +RuntimeScriptValue Sc_ShakeScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(ShakeScreen); } // void (int delay, int amount, int length) -RuntimeScriptValue Sc_ShakeScreenBackground(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(ShakeScreenBackground); +RuntimeScriptValue Sc_ShakeScreenBackground(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(ShakeScreenBackground); } // void () -RuntimeScriptValue Sc_ShowMouseCursor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(ShowMouseCursor); +RuntimeScriptValue Sc_ShowMouseCursor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(ShowMouseCursor); } -RuntimeScriptValue Sc_SkipCutscene(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(SkipCutscene); +RuntimeScriptValue Sc_SkipCutscene(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(SkipCutscene); } // void (int cc) -RuntimeScriptValue Sc_SkipUntilCharacterStops(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(SkipUntilCharacterStops); +RuntimeScriptValue Sc_SkipUntilCharacterStops(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(SkipUntilCharacterStops); } // void (int skipwith) -RuntimeScriptValue Sc_StartCutscene(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(StartCutscene); +RuntimeScriptValue Sc_StartCutscene(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(StartCutscene); } // void (int keyToStop) -RuntimeScriptValue Sc_scStartRecording(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(scStartRecording); +RuntimeScriptValue Sc_scStartRecording(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(scStartRecording); } // void (int channel) -RuntimeScriptValue Sc_StopAmbientSound(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(StopAmbientSound); +RuntimeScriptValue Sc_StopAmbientSound(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(StopAmbientSound); } -// void (int chid) -RuntimeScriptValue Sc_stop_and_destroy_channel(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(stop_and_destroy_channel); +// void (int chid) +RuntimeScriptValue Sc_stop_and_destroy_channel(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(stop_and_destroy_channel); } // void () -RuntimeScriptValue Sc_StopDialog(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(StopDialog); +RuntimeScriptValue Sc_StopDialog(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(StopDialog); } // void (int chaa) -RuntimeScriptValue Sc_StopMoving(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(StopMoving); +RuntimeScriptValue Sc_StopMoving(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(StopMoving); } // void () -RuntimeScriptValue Sc_scr_StopMusic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(scr_StopMusic); +RuntimeScriptValue Sc_scr_StopMusic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(scr_StopMusic); } // void (int objj) -RuntimeScriptValue Sc_StopObjectMoving(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(StopObjectMoving); +RuntimeScriptValue Sc_StopObjectMoving(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(StopObjectMoving); } // void (char*s1,char*s2) -RuntimeScriptValue Sc_sc_strcat(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_PARAM_COUNT(_sc_strcat, 2); - _sc_strcat((char*)params[0].Ptr, (const char*)params[1].Ptr); - // NOTE: tests with old (<= 2.60) AGS show that StrCat returned the second string - // (could be result of UB, but we are doing this for more accurate emulation) - return params[1]; +RuntimeScriptValue Sc_sc_strcat(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_PARAM_COUNT(_sc_strcat, 2); + _sc_strcat((char *)params[0].Ptr, (const char *)params[1].Ptr); + // NOTE: tests with old (<= 2.60) AGS show that StrCat returned the second string + // (could be result of UB, but we are doing this for more accurate emulation) + return params[1]; } -RuntimeScriptValue Sc_stricmp(const RuntimeScriptValue *params, int32_t param_count) -{ - // Calling C stdlib function ags_stricmp - API_SCALL_INT_POBJ2(ags_stricmp, const char, const char); +RuntimeScriptValue Sc_stricmp(const RuntimeScriptValue *params, int32_t param_count) { + // Calling C stdlib function ags_stricmp + API_SCALL_INT_POBJ2(ags_stricmp, const char, const char); } -RuntimeScriptValue Sc_strcmp(const RuntimeScriptValue *params, int32_t param_count) -{ - // Calling C stdlib function strcmp - API_SCALL_INT_POBJ2(strcmp, const char, const char); +RuntimeScriptValue Sc_strcmp(const RuntimeScriptValue *params, int32_t param_count) { + // Calling C stdlib function strcmp + API_SCALL_INT_POBJ2(strcmp, const char, const char); } // int (const char *s1, const char *s2) -RuntimeScriptValue Sc_StrContains(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ2(StrContains, const char, const char); +RuntimeScriptValue Sc_StrContains(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ2(StrContains, const char, const char); } // void (char*s1, const char*s2); -RuntimeScriptValue Sc_sc_strcpy(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_PARAM_COUNT(_sc_strcpy, 2); - _sc_strcpy((char*)params[0].Ptr, (const char*)params[1].Ptr); - return params[0]; +RuntimeScriptValue Sc_sc_strcpy(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_PARAM_COUNT(_sc_strcpy, 2); + _sc_strcpy((char *)params[0].Ptr, (const char *)params[1].Ptr); + return params[0]; } // void (char*destt, const char*texx, ...); -RuntimeScriptValue Sc_sc_sprintf(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(_sc_sprintf, 2); - _sc_strcpy(params[0].Ptr, scsf_buffer); - return params[0]; +RuntimeScriptValue Sc_sc_sprintf(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(_sc_sprintf, 2); + _sc_strcpy(params[0].Ptr, scsf_buffer); + return params[0]; } // int (char *strin, int posn) -RuntimeScriptValue Sc_StrGetCharAt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ_PINT(StrGetCharAt, const char); +RuntimeScriptValue Sc_StrGetCharAt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ_PINT(StrGetCharAt, const char); } // int (const char*stino) -RuntimeScriptValue Sc_StringToInt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(StringToInt, const char); +RuntimeScriptValue Sc_StringToInt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(StringToInt, const char); } -RuntimeScriptValue Sc_strlen(const RuntimeScriptValue *params, int32_t param_count) -{ - // Calling C stdlib function strlen - API_SCALL_INT_POBJ(strlen, const char); +RuntimeScriptValue Sc_strlen(const RuntimeScriptValue *params, int32_t param_count) { + // Calling C stdlib function strlen + API_SCALL_INT_POBJ(strlen, const char); } // void (char *strin, int posn, int nchar) -RuntimeScriptValue Sc_StrSetCharAt(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_PARAM_COUNT(StrSetCharAt, 3); - StrSetCharAt((char*)params[0].Ptr, params[1].IValue, params[2].IValue); - return params[0]; +RuntimeScriptValue Sc_StrSetCharAt(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_PARAM_COUNT(StrSetCharAt, 3); + StrSetCharAt((char *)params[0].Ptr, params[1].IValue, params[2].IValue); + return params[0]; } // void (char *desbuf) -RuntimeScriptValue Sc_sc_strlower(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_PARAM_COUNT(_sc_strlower, 1); - _sc_strlower((char*)params[0].Ptr); - return params[0]; +RuntimeScriptValue Sc_sc_strlower(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_PARAM_COUNT(_sc_strlower, 1); + _sc_strlower((char *)params[0].Ptr); + return params[0]; } // void (char *desbuf) -RuntimeScriptValue Sc_sc_strupper(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_PARAM_COUNT(_sc_strupper, 1); - _sc_strupper((char*)params[0].Ptr); - return params[0]; +RuntimeScriptValue Sc_sc_strupper(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_PARAM_COUNT(_sc_strupper, 1); + _sc_strupper((char *)params[0].Ptr); + return params[0]; } // void (int red, int grn, int blu) -RuntimeScriptValue Sc_TintScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(TintScreen); +RuntimeScriptValue Sc_TintScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(TintScreen); } // void () -RuntimeScriptValue Sc_UnPauseGame(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(UnPauseGame); +RuntimeScriptValue Sc_UnPauseGame(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(UnPauseGame); } // void () -RuntimeScriptValue Sc_update_invorder(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(update_invorder); +RuntimeScriptValue Sc_update_invorder(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(update_invorder); } // void () -RuntimeScriptValue Sc_UpdatePalette(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(UpdatePalette); +RuntimeScriptValue Sc_UpdatePalette(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(UpdatePalette); } // void (int nloops) -RuntimeScriptValue Sc_scrWait(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(scrWait); +RuntimeScriptValue Sc_scrWait(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(scrWait); } // int (int nloops) -RuntimeScriptValue Sc_WaitKey(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(WaitKey); +RuntimeScriptValue Sc_WaitKey(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(WaitKey); } -RuntimeScriptValue Sc_WaitMouse(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(WaitMouse); +RuntimeScriptValue Sc_WaitMouse(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(WaitMouse); } // int (int nloops) -RuntimeScriptValue Sc_WaitMouseKey(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(WaitMouseKey); +RuntimeScriptValue Sc_WaitMouseKey(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(WaitMouseKey); } -RuntimeScriptValue Sc_SkipWait(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(SkipWait); +RuntimeScriptValue Sc_SkipWait(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(SkipWait); } //============================================================================= @@ -2236,79 +1889,68 @@ RuntimeScriptValue Sc_SkipWait(const RuntimeScriptValue *params, int32_t param_c //============================================================================= // void (char*texx, ...) -void ScPl_sc_AbortGame(const char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - _sc_AbortGame(scsf_buffer); +void ScPl_sc_AbortGame(const char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + _sc_AbortGame(scsf_buffer); } // int (int xx,int yy,int wii,int fontid,int clr,char*texx, ...) -int ScPl_CreateTextOverlay(int xx, int yy, int wii, int fontid, int clr, char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - return CreateTextOverlay(xx, yy, wii, fontid, clr, scsf_buffer, DISPLAYTEXT_NORMALOVERLAY); +int ScPl_CreateTextOverlay(int xx, int yy, int wii, int fontid, int clr, char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + return CreateTextOverlay(xx, yy, wii, fontid, clr, scsf_buffer, DISPLAYTEXT_NORMALOVERLAY); } // void (char*texx, ...) -void ScPl_Display(char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - DisplaySimple(scsf_buffer); +void ScPl_Display(char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplaySimple(scsf_buffer); } // void (int xxp,int yyp,int widd,char*texx, ...) -void ScPl_DisplayAt(int xxp, int yyp, int widd, char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - DisplayAt(xxp, yyp, widd, scsf_buffer); +void ScPl_DisplayAt(int xxp, int yyp, int widd, char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplayAt(xxp, yyp, widd, scsf_buffer); } // void (int chid,char*texx, ...) -void ScPl_sc_displayspeech(int chid, char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - __sc_displayspeech(chid, scsf_buffer); +void ScPl_sc_displayspeech(int chid, char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + __sc_displayspeech(chid, scsf_buffer); } // void (int chid, const char*texx, ...) -void ScPl_DisplayThought(int chid, const char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - DisplayThought(chid, scsf_buffer); +void ScPl_DisplayThought(int chid, const char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplayThought(chid, scsf_buffer); } // void (int ypos, int ttexcol, int backcol, char *title, char*texx, ...) -void ScPl_DisplayTopBar(int ypos, int ttexcol, int backcol, char *title, char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - DisplayTopBar(ypos, ttexcol, backcol, title, scsf_buffer); +void ScPl_DisplayTopBar(int ypos, int ttexcol, int backcol, char *title, char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + DisplayTopBar(ypos, ttexcol, backcol, title, scsf_buffer); } // void (int xx, int yy, char*texx, ...) -void ScPl_RawPrint(int xx, int yy, char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - RawPrint(xx, yy, scsf_buffer); +void ScPl_RawPrint(int xx, int yy, char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + RawPrint(xx, yy, scsf_buffer); } // void (int ovrid,int xx,int yy,int wii,int fontid,int clr,char*texx,...) -void ScPl_SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int clr, char*texx,...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - SetTextOverlay(ovrid, xx, yy, wii, fontid, clr, scsf_buffer); +void ScPl_SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int clr, char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + SetTextOverlay(ovrid, xx, yy, wii, fontid, clr, scsf_buffer); } // void (char*destt, const char*texx, ...); -void ScPl_sc_sprintf(char *destt, const char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - _sc_strcpy(destt, scsf_buffer); +void ScPl_sc_sprintf(char *destt, const char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + _sc_strcpy(destt, scsf_buffer); } -void RegisterGlobalAPI() -{ - ccAddExternalStaticFunction("AbortGame", Sc_sc_AbortGame); +void RegisterGlobalAPI() { + ccAddExternalStaticFunction("AbortGame", Sc_sc_AbortGame); ccAddExternalStaticFunction("AddInventory", Sc_add_inventory); ccAddExternalStaticFunction("AddInventoryToCharacter", Sc_AddInventoryToCharacter); ccAddExternalStaticFunction("AnimateButton", Sc_AnimateButton); @@ -2362,7 +2004,7 @@ void RegisterGlobalAPI() ccAddExternalStaticFunction("FileClose", Sc_FileClose); ccAddExternalStaticFunction("FileIsEOF", Sc_FileIsEOF); ccAddExternalStaticFunction("FileIsError", Sc_FileIsError); - // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen + // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen ccAddExternalStaticFunction("FileOpen", Sc_FileOpenCMode); ccAddExternalStaticFunction("FileRead", Sc_FileRead); ccAddExternalStaticFunction("FileReadInt", Sc_FileReadInt); @@ -2437,11 +2079,11 @@ void RegisterGlobalAPI() ccAddExternalStaticFunction("GetTranslationName", Sc_GetTranslationName); ccAddExternalStaticFunction("GetViewportX", Sc_GetViewportX); ccAddExternalStaticFunction("GetViewportY", Sc_GetViewportY); - ccAddExternalStaticFunction("GetWalkableAreaAtRoom", Sc_GetWalkableAreaAtRoom); + ccAddExternalStaticFunction("GetWalkableAreaAtRoom", Sc_GetWalkableAreaAtRoom); ccAddExternalStaticFunction("GetWalkableAreaAt", Sc_GetWalkableAreaAtScreen); - ccAddExternalStaticFunction("GetWalkableAreaAtScreen", Sc_GetWalkableAreaAtScreen); - ccAddExternalStaticFunction("GetDrawingSurfaceForWalkableArea", Sc_GetDrawingSurfaceForWalkableArea); - ccAddExternalStaticFunction("GetDrawingSurfaceForWalkbehind", Sc_GetDrawingSurfaceForWalkbehind); + ccAddExternalStaticFunction("GetWalkableAreaAtScreen", Sc_GetWalkableAreaAtScreen); + ccAddExternalStaticFunction("GetDrawingSurfaceForWalkableArea", Sc_GetDrawingSurfaceForWalkableArea); + ccAddExternalStaticFunction("GetDrawingSurfaceForWalkbehind", Sc_GetDrawingSurfaceForWalkbehind); ccAddExternalStaticFunction("GiveScore", Sc_GiveScore); ccAddExternalStaticFunction("HasPlayerBeenInRoom", Sc_HasPlayerBeenInRoom); ccAddExternalStaticFunction("HideMouseCursor", Sc_HideMouseCursor); @@ -2558,7 +2200,7 @@ void RegisterGlobalAPI() ccAddExternalStaticFunction("SeekMP3PosMillis", Sc_SeekMP3PosMillis); ccAddExternalStaticFunction("SetActiveInventory", Sc_SetActiveInventory); ccAddExternalStaticFunction("SetAmbientTint", Sc_SetAmbientTint); - ccAddExternalStaticFunction("SetAmbientLightLevel", Sc_SetAmbientLightLevel); + ccAddExternalStaticFunction("SetAmbientLightLevel", Sc_SetAmbientLightLevel); ccAddExternalStaticFunction("SetAreaLightLevel", Sc_SetAreaLightLevel); ccAddExternalStaticFunction("SetAreaScaling", Sc_SetAreaScaling); ccAddExternalStaticFunction("SetBackgroundFrame", Sc_SetBackgroundFrame); @@ -2649,7 +2291,7 @@ void RegisterGlobalAPI() ccAddExternalStaticFunction("ShakeScreen", Sc_ShakeScreen); ccAddExternalStaticFunction("ShakeScreenBackground", Sc_ShakeScreenBackground); ccAddExternalStaticFunction("ShowMouseCursor", Sc_ShowMouseCursor); - ccAddExternalStaticFunction("SkipCutscene", Sc_SkipCutscene); + ccAddExternalStaticFunction("SkipCutscene", Sc_SkipCutscene); ccAddExternalStaticFunction("SkipUntilCharacterStops", Sc_SkipUntilCharacterStops); ccAddExternalStaticFunction("StartCutscene", Sc_StartCutscene); ccAddExternalStaticFunction("StartRecording", Sc_scStartRecording); @@ -2681,371 +2323,371 @@ void RegisterGlobalAPI() ccAddExternalStaticFunction("WaitMouseKey", Sc_WaitMouseKey); ccAddExternalStaticFunction("SkipWait", Sc_SkipWait); - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("AbortGame", (void*)ScPl_sc_AbortGame); - ccAddExternalFunctionForPlugin("AddInventory", (void*)add_inventory); - ccAddExternalFunctionForPlugin("AddInventoryToCharacter", (void*)AddInventoryToCharacter); - ccAddExternalFunctionForPlugin("AnimateButton", (void*)AnimateButton); - ccAddExternalFunctionForPlugin("AnimateCharacter", (void*)scAnimateCharacter); - ccAddExternalFunctionForPlugin("AnimateCharacterEx", (void*)AnimateCharacterEx); - ccAddExternalFunctionForPlugin("AnimateObject", (void*)AnimateObject); - ccAddExternalFunctionForPlugin("AnimateObjectEx", (void*)AnimateObjectEx); - ccAddExternalFunctionForPlugin("AreCharactersColliding", (void*)AreCharactersColliding); - ccAddExternalFunctionForPlugin("AreCharObjColliding", (void*)AreCharObjColliding); - ccAddExternalFunctionForPlugin("AreObjectsColliding", (void*)AreObjectsColliding); - ccAddExternalFunctionForPlugin("AreThingsOverlapping", (void*)AreThingsOverlapping); - ccAddExternalFunctionForPlugin("CallRoomScript", (void*)CallRoomScript); - ccAddExternalFunctionForPlugin("CDAudio", (void*)cd_manager); - ccAddExternalFunctionForPlugin("CentreGUI", (void*)CentreGUI); - ccAddExternalFunctionForPlugin("ChangeCharacterView", (void*)ChangeCharacterView); - ccAddExternalFunctionForPlugin("ChangeCursorGraphic", (void*)ChangeCursorGraphic); - ccAddExternalFunctionForPlugin("ChangeCursorHotspot", (void*)ChangeCursorHotspot); - ccAddExternalFunctionForPlugin("ClaimEvent", (void*)ClaimEvent); - ccAddExternalFunctionForPlugin("CreateGraphicOverlay", (void*)CreateGraphicOverlay); - ccAddExternalFunctionForPlugin("CreateTextOverlay", (void*)ScPl_CreateTextOverlay); - ccAddExternalFunctionForPlugin("CyclePalette", (void*)CyclePalette); - ccAddExternalFunctionForPlugin("Debug", (void*)script_debug); - ccAddExternalFunctionForPlugin("DeleteSaveSlot", (void*)DeleteSaveSlot); - ccAddExternalFunctionForPlugin("DeleteSprite", (void*)free_dynamic_sprite); - ccAddExternalFunctionForPlugin("DisableCursorMode", (void*)disable_cursor_mode); - ccAddExternalFunctionForPlugin("DisableGroundLevelAreas", (void*)DisableGroundLevelAreas); - ccAddExternalFunctionForPlugin("DisableHotspot", (void*)DisableHotspot); - ccAddExternalFunctionForPlugin("DisableInterface", (void*)DisableInterface); - ccAddExternalFunctionForPlugin("DisableRegion", (void*)DisableRegion); - ccAddExternalFunctionForPlugin("Display", (void*)ScPl_Display); - ccAddExternalFunctionForPlugin("DisplayAt", (void*)ScPl_DisplayAt); - ccAddExternalFunctionForPlugin("DisplayAtY", (void*)DisplayAtY); - ccAddExternalFunctionForPlugin("DisplayMessage", (void*)DisplayMessage); - ccAddExternalFunctionForPlugin("DisplayMessageAtY", (void*)DisplayMessageAtY); - ccAddExternalFunctionForPlugin("DisplayMessageBar", (void*)DisplayMessageBar); - ccAddExternalFunctionForPlugin("DisplaySpeech", (void*)ScPl_sc_displayspeech); - ccAddExternalFunctionForPlugin("DisplaySpeechAt", (void*)DisplaySpeechAt); - ccAddExternalFunctionForPlugin("DisplaySpeechBackground", (void*)DisplaySpeechBackground); - ccAddExternalFunctionForPlugin("DisplayThought", (void*)ScPl_DisplayThought); - ccAddExternalFunctionForPlugin("DisplayTopBar", (void*)ScPl_DisplayTopBar); - ccAddExternalFunctionForPlugin("EnableCursorMode", (void*)enable_cursor_mode); - ccAddExternalFunctionForPlugin("EnableGroundLevelAreas", (void*)EnableGroundLevelAreas); - ccAddExternalFunctionForPlugin("EnableHotspot", (void*)EnableHotspot); - ccAddExternalFunctionForPlugin("EnableInterface", (void*)EnableInterface); - ccAddExternalFunctionForPlugin("EnableRegion", (void*)EnableRegion); - ccAddExternalFunctionForPlugin("EndCutscene", (void*)EndCutscene); - ccAddExternalFunctionForPlugin("FaceCharacter", (void*)FaceCharacter); - ccAddExternalFunctionForPlugin("FaceLocation", (void*)FaceLocation); - ccAddExternalFunctionForPlugin("FadeIn", (void*)FadeIn); - ccAddExternalFunctionForPlugin("FadeOut", (void*)my_fade_out); - ccAddExternalFunctionForPlugin("FileClose", (void*)FileClose); - ccAddExternalFunctionForPlugin("FileIsEOF", (void*)FileIsEOF); - ccAddExternalFunctionForPlugin("FileIsError", (void*)FileIsError); - // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen - ccAddExternalFunctionForPlugin("FileOpen", (void*)FileOpenCMode); - ccAddExternalFunctionForPlugin("FileRead", (void*)FileRead); - ccAddExternalFunctionForPlugin("FileReadInt", (void*)FileReadInt); - ccAddExternalFunctionForPlugin("FileReadRawChar", (void*)FileReadRawChar); - ccAddExternalFunctionForPlugin("FileReadRawInt", (void*)FileReadRawInt); - ccAddExternalFunctionForPlugin("FileWrite", (void*)FileWrite); - ccAddExternalFunctionForPlugin("FileWriteInt", (void*)FileWriteInt); - ccAddExternalFunctionForPlugin("FileWriteRawChar", (void*)FileWriteRawChar); - ccAddExternalFunctionForPlugin("FileWriteRawLine", (void*)FileWriteRawLine); - ccAddExternalFunctionForPlugin("FindGUIID", (void*)FindGUIID); - ccAddExternalFunctionForPlugin("FlipScreen", (void*)FlipScreen); - ccAddExternalFunctionForPlugin("FloatToInt", (void*)FloatToInt); - ccAddExternalFunctionForPlugin("FollowCharacter", (void*)FollowCharacter); - ccAddExternalFunctionForPlugin("FollowCharacterEx", (void*)FollowCharacterEx); - ccAddExternalFunctionForPlugin("GetBackgroundFrame", (void*)GetBackgroundFrame); - ccAddExternalFunctionForPlugin("GetButtonPic", (void*)GetButtonPic); - ccAddExternalFunctionForPlugin("GetCharacterAt", (void*)GetCharIDAtScreen); - ccAddExternalFunctionForPlugin("GetCharacterProperty", (void*)GetCharacterProperty); - ccAddExternalFunctionForPlugin("GetCharacterPropertyText", (void*)GetCharacterPropertyText); - ccAddExternalFunctionForPlugin("GetCurrentMusic", (void*)GetCurrentMusic); - ccAddExternalFunctionForPlugin("GetCursorMode", (void*)GetCursorMode); - ccAddExternalFunctionForPlugin("GetDialogOption", (void*)GetDialogOption); - ccAddExternalFunctionForPlugin("GetGameOption", (void*)GetGameOption); - ccAddExternalFunctionForPlugin("GetGameParameter", (void*)GetGameParameter); - ccAddExternalFunctionForPlugin("GetGameSpeed", (void*)GetGameSpeed); - ccAddExternalFunctionForPlugin("GetGlobalInt", (void*)GetGlobalInt); - ccAddExternalFunctionForPlugin("GetGlobalString", (void*)GetGlobalString); - ccAddExternalFunctionForPlugin("GetGraphicalVariable", (void*)GetGraphicalVariable); - ccAddExternalFunctionForPlugin("GetGUIAt", (void*)GetGUIAt); - ccAddExternalFunctionForPlugin("GetGUIObjectAt", (void*)GetGUIObjectAt); - ccAddExternalFunctionForPlugin("GetHotspotAt", (void*)GetHotspotIDAtScreen); - ccAddExternalFunctionForPlugin("GetHotspotName", (void*)GetHotspotName); - ccAddExternalFunctionForPlugin("GetHotspotPointX", (void*)GetHotspotPointX); - ccAddExternalFunctionForPlugin("GetHotspotPointY", (void*)GetHotspotPointY); - ccAddExternalFunctionForPlugin("GetHotspotProperty", (void*)GetHotspotProperty); - ccAddExternalFunctionForPlugin("GetHotspotPropertyText", (void*)GetHotspotPropertyText); - ccAddExternalFunctionForPlugin("GetInvAt", (void*)GetInvAt); - ccAddExternalFunctionForPlugin("GetInvGraphic", (void*)GetInvGraphic); - ccAddExternalFunctionForPlugin("GetInvName", (void*)GetInvName); - ccAddExternalFunctionForPlugin("GetInvProperty", (void*)GetInvProperty); - ccAddExternalFunctionForPlugin("GetInvPropertyText", (void*)GetInvPropertyText); - //ccAddExternalFunctionForPlugin("GetLanguageString", (void*)GetLanguageString); - ccAddExternalFunctionForPlugin("GetLocationName", (void*)GetLocationName); - ccAddExternalFunctionForPlugin("GetLocationType", (void*)GetLocationType); - ccAddExternalFunctionForPlugin("GetMessageText", (void*)GetMessageText); - ccAddExternalFunctionForPlugin("GetMIDIPosition", (void*)GetMIDIPosition); - ccAddExternalFunctionForPlugin("GetMP3PosMillis", (void*)GetMP3PosMillis); - ccAddExternalFunctionForPlugin("GetObjectAt", (void*)GetObjectIDAtScreen); - ccAddExternalFunctionForPlugin("GetObjectBaseline", (void*)GetObjectBaseline); - ccAddExternalFunctionForPlugin("GetObjectGraphic", (void*)GetObjectGraphic); - ccAddExternalFunctionForPlugin("GetObjectName", (void*)GetObjectName); - ccAddExternalFunctionForPlugin("GetObjectProperty", (void*)GetObjectProperty); - ccAddExternalFunctionForPlugin("GetObjectPropertyText", (void*)GetObjectPropertyText); - ccAddExternalFunctionForPlugin("GetObjectX", (void*)GetObjectX); - ccAddExternalFunctionForPlugin("GetObjectY", (void*)GetObjectY); - // ccAddExternalFunctionForPlugin("GetPalette", (void*)scGetPal); - ccAddExternalFunctionForPlugin("GetPlayerCharacter", (void*)GetPlayerCharacter); - ccAddExternalFunctionForPlugin("GetRawTime", (void*)GetRawTime); - ccAddExternalFunctionForPlugin("GetRegionAt", (void*)GetRegionIDAtRoom); - ccAddExternalFunctionForPlugin("GetRoomProperty", (void*)Room_GetProperty); - ccAddExternalFunctionForPlugin("GetRoomPropertyText", (void*)GetRoomPropertyText); - ccAddExternalFunctionForPlugin("GetSaveSlotDescription", (void*)GetSaveSlotDescription); - ccAddExternalFunctionForPlugin("GetScalingAt", (void*)GetScalingAt); - ccAddExternalFunctionForPlugin("GetSliderValue", (void*)GetSliderValue); - ccAddExternalFunctionForPlugin("GetTextBoxText", (void*)GetTextBoxText); - ccAddExternalFunctionForPlugin("GetTextHeight", (void*)GetTextHeight); - ccAddExternalFunctionForPlugin("GetTextWidth", (void*)GetTextWidth); - ccAddExternalFunctionForPlugin("GetTime", (void*)sc_GetTime); - ccAddExternalFunctionForPlugin("GetTranslation", (void*)get_translation); - ccAddExternalFunctionForPlugin("GetTranslationName", (void*)GetTranslationName); - ccAddExternalFunctionForPlugin("GetViewportX", (void*)GetViewportX); - ccAddExternalFunctionForPlugin("GetViewportY", (void*)GetViewportY); - ccAddExternalFunctionForPlugin("GetWalkableAreaAtRoom", (void*)GetWalkableAreaAtRoom); - ccAddExternalFunctionForPlugin("GetWalkableAreaAt", (void*)GetWalkableAreaAtScreen); - ccAddExternalFunctionForPlugin("GetWalkableAreaAtScreen", (void*)GetWalkableAreaAtScreen); - ccAddExternalFunctionForPlugin("GiveScore", (void*)GiveScore); - ccAddExternalFunctionForPlugin("HasPlayerBeenInRoom", (void*)HasPlayerBeenInRoom); - ccAddExternalFunctionForPlugin("HideMouseCursor", (void*)HideMouseCursor); - ccAddExternalFunctionForPlugin("InputBox", (void*)sc_inputbox); - ccAddExternalFunctionForPlugin("InterfaceOff", (void*)InterfaceOff); - ccAddExternalFunctionForPlugin("InterfaceOn", (void*)InterfaceOn); - ccAddExternalFunctionForPlugin("IntToFloat", (void*)IntToFloat); - ccAddExternalFunctionForPlugin("InventoryScreen", (void*)sc_invscreen); - ccAddExternalFunctionForPlugin("IsButtonDown", (void*)IsButtonDown); - ccAddExternalFunctionForPlugin("IsChannelPlaying", (void*)IsChannelPlaying); - ccAddExternalFunctionForPlugin("IsGamePaused", (void*)IsGamePaused); - ccAddExternalFunctionForPlugin("IsGUIOn", (void*)IsGUIOn); - ccAddExternalFunctionForPlugin("IsInteractionAvailable", (void*)IsInteractionAvailable); - ccAddExternalFunctionForPlugin("IsInventoryInteractionAvailable", (void*)IsInventoryInteractionAvailable); - ccAddExternalFunctionForPlugin("IsInterfaceEnabled", (void*)IsInterfaceEnabled); - ccAddExternalFunctionForPlugin("IsKeyPressed", (void*)IsKeyPressed); - ccAddExternalFunctionForPlugin("IsMusicPlaying", (void*)IsMusicPlaying); - ccAddExternalFunctionForPlugin("IsMusicVoxAvailable", (void*)IsMusicVoxAvailable); - ccAddExternalFunctionForPlugin("IsObjectAnimating", (void*)IsObjectAnimating); - ccAddExternalFunctionForPlugin("IsObjectMoving", (void*)IsObjectMoving); - ccAddExternalFunctionForPlugin("IsObjectOn", (void*)IsObjectOn); - ccAddExternalFunctionForPlugin("IsOverlayValid", (void*)IsOverlayValid); - ccAddExternalFunctionForPlugin("IsSoundPlaying", (void*)IsSoundPlaying); - ccAddExternalFunctionForPlugin("IsTimerExpired", (void*)IsTimerExpired); - ccAddExternalFunctionForPlugin("IsTranslationAvailable", (void*)IsTranslationAvailable); - ccAddExternalFunctionForPlugin("IsVoxAvailable", (void*)IsVoxAvailable); - ccAddExternalFunctionForPlugin("ListBoxAdd", (void*)ListBoxAdd); - ccAddExternalFunctionForPlugin("ListBoxClear", (void*)ListBoxClear); - ccAddExternalFunctionForPlugin("ListBoxDirList", (void*)ListBoxDirList); - ccAddExternalFunctionForPlugin("ListBoxGetItemText", (void*)ListBoxGetItemText); - ccAddExternalFunctionForPlugin("ListBoxGetNumItems", (void*)ListBoxGetNumItems); - ccAddExternalFunctionForPlugin("ListBoxGetSelected", (void*)ListBoxGetSelected); - ccAddExternalFunctionForPlugin("ListBoxRemove", (void*)ListBoxRemove); - ccAddExternalFunctionForPlugin("ListBoxSaveGameList", (void*)ListBoxSaveGameList); - ccAddExternalFunctionForPlugin("ListBoxSetSelected", (void*)ListBoxSetSelected); - ccAddExternalFunctionForPlugin("ListBoxSetTopItem", (void*)ListBoxSetTopItem); - ccAddExternalFunctionForPlugin("LoadImageFile", (void*)LoadImageFile); - ccAddExternalFunctionForPlugin("LoadSaveSlotScreenshot", (void*)LoadSaveSlotScreenshot); - ccAddExternalFunctionForPlugin("LoseInventory", (void*)lose_inventory); - ccAddExternalFunctionForPlugin("LoseInventoryFromCharacter", (void*)LoseInventoryFromCharacter); - ccAddExternalFunctionForPlugin("MergeObject", (void*)MergeObject); - ccAddExternalFunctionForPlugin("MoveCharacter", (void*)MoveCharacter); - ccAddExternalFunctionForPlugin("MoveCharacterBlocking", (void*)MoveCharacterBlocking); - ccAddExternalFunctionForPlugin("MoveCharacterDirect", (void*)MoveCharacterDirect); - ccAddExternalFunctionForPlugin("MoveCharacterPath", (void*)MoveCharacterPath); - ccAddExternalFunctionForPlugin("MoveCharacterStraight", (void*)MoveCharacterStraight); - ccAddExternalFunctionForPlugin("MoveCharacterToHotspot", (void*)MoveCharacterToHotspot); - ccAddExternalFunctionForPlugin("MoveCharacterToObject", (void*)MoveCharacterToObject); - ccAddExternalFunctionForPlugin("MoveObject", (void*)MoveObject); - ccAddExternalFunctionForPlugin("MoveObjectDirect", (void*)MoveObjectDirect); - ccAddExternalFunctionForPlugin("MoveOverlay", (void*)MoveOverlay); - ccAddExternalFunctionForPlugin("MoveToWalkableArea", (void*)MoveToWalkableArea); - ccAddExternalFunctionForPlugin("NewRoom", (void*)NewRoom); - ccAddExternalFunctionForPlugin("NewRoomEx", (void*)NewRoomEx); - ccAddExternalFunctionForPlugin("NewRoomNPC", (void*)NewRoomNPC); - ccAddExternalFunctionForPlugin("ObjectOff", (void*)ObjectOff); - ccAddExternalFunctionForPlugin("ObjectOn", (void*)ObjectOn); - ccAddExternalFunctionForPlugin("ParseText", (void*)ParseText); - ccAddExternalFunctionForPlugin("PauseGame", (void*)PauseGame); - ccAddExternalFunctionForPlugin("PlayAmbientSound", (void*)PlayAmbientSound); - ccAddExternalFunctionForPlugin("PlayFlic", (void*)play_flc_file); - ccAddExternalFunctionForPlugin("PlayMP3File", (void*)PlayMP3File); - ccAddExternalFunctionForPlugin("PlayMusic", (void*)PlayMusicResetQueue); - ccAddExternalFunctionForPlugin("PlayMusicQueued", (void*)PlayMusicQueued); - ccAddExternalFunctionForPlugin("PlaySilentMIDI", (void*)PlaySilentMIDI); - ccAddExternalFunctionForPlugin("PlaySound", (void*)play_sound); - ccAddExternalFunctionForPlugin("PlaySoundEx", (void*)PlaySoundEx); - ccAddExternalFunctionForPlugin("PlayVideo", (void*)scrPlayVideo); - ccAddExternalFunctionForPlugin("ProcessClick", (void*)RoomProcessClick); - ccAddExternalFunctionForPlugin("QuitGame", (void*)QuitGame); - ccAddExternalFunctionForPlugin("Random", (void*)__Rand); - ccAddExternalFunctionForPlugin("RawClearScreen", (void*)RawClear); - ccAddExternalFunctionForPlugin("RawDrawCircle", (void*)RawDrawCircle); - ccAddExternalFunctionForPlugin("RawDrawFrameTransparent", (void*)RawDrawFrameTransparent); - ccAddExternalFunctionForPlugin("RawDrawImage", (void*)RawDrawImage); - ccAddExternalFunctionForPlugin("RawDrawImageOffset", (void*)RawDrawImageOffset); - ccAddExternalFunctionForPlugin("RawDrawImageResized", (void*)RawDrawImageResized); - ccAddExternalFunctionForPlugin("RawDrawImageTransparent", (void*)RawDrawImageTransparent); - ccAddExternalFunctionForPlugin("RawDrawLine", (void*)RawDrawLine); - ccAddExternalFunctionForPlugin("RawDrawRectangle", (void*)RawDrawRectangle); - ccAddExternalFunctionForPlugin("RawDrawTriangle", (void*)RawDrawTriangle); - ccAddExternalFunctionForPlugin("RawPrint", (void*)ScPl_RawPrint); - ccAddExternalFunctionForPlugin("RawPrintMessageWrapped", (void*)RawPrintMessageWrapped); - ccAddExternalFunctionForPlugin("RawRestoreScreen", (void*)RawRestoreScreen); - ccAddExternalFunctionForPlugin("RawRestoreScreenTinted", (void*)RawRestoreScreenTinted); - ccAddExternalFunctionForPlugin("RawSaveScreen", (void*)RawSaveScreen); - ccAddExternalFunctionForPlugin("RawSetColor", (void*)RawSetColor); - ccAddExternalFunctionForPlugin("RawSetColorRGB", (void*)RawSetColorRGB); - ccAddExternalFunctionForPlugin("RefreshMouse", (void*)RefreshMouse); - ccAddExternalFunctionForPlugin("ReleaseCharacterView", (void*)ReleaseCharacterView); - ccAddExternalFunctionForPlugin("ReleaseViewport", (void*)ReleaseViewport); - ccAddExternalFunctionForPlugin("RemoveObjectTint", (void*)RemoveObjectTint); - ccAddExternalFunctionForPlugin("RemoveOverlay", (void*)RemoveOverlay); - ccAddExternalFunctionForPlugin("RemoveWalkableArea", (void*)RemoveWalkableArea); - ccAddExternalFunctionForPlugin("ResetRoom", (void*)ResetRoom); - ccAddExternalFunctionForPlugin("RestartGame", (void*)restart_game); - ccAddExternalFunctionForPlugin("RestoreGameDialog", (void*)restore_game_dialog); - ccAddExternalFunctionForPlugin("RestoreGameSlot", (void*)RestoreGameSlot); - ccAddExternalFunctionForPlugin("RestoreWalkableArea", (void*)RestoreWalkableArea); - ccAddExternalFunctionForPlugin("RunAGSGame", (void*)RunAGSGame); - ccAddExternalFunctionForPlugin("RunCharacterInteraction", (void*)RunCharacterInteraction); - ccAddExternalFunctionForPlugin("RunDialog", (void*)RunDialog); - ccAddExternalFunctionForPlugin("RunHotspotInteraction", (void*)RunHotspotInteraction); - ccAddExternalFunctionForPlugin("RunInventoryInteraction", (void*)RunInventoryInteraction); - ccAddExternalFunctionForPlugin("RunObjectInteraction", (void*)RunObjectInteraction); - ccAddExternalFunctionForPlugin("RunRegionInteraction", (void*)RunRegionInteraction); - ccAddExternalFunctionForPlugin("Said", (void*)Said); - ccAddExternalFunctionForPlugin("SaidUnknownWord", (void*)SaidUnknownWord); - ccAddExternalFunctionForPlugin("SaveCursorForLocationChange", (void*)SaveCursorForLocationChange); - ccAddExternalFunctionForPlugin("SaveGameDialog", (void*)save_game_dialog); - ccAddExternalFunctionForPlugin("SaveGameSlot", (void*)save_game); - ccAddExternalFunctionForPlugin("SaveScreenShot", (void*)SaveScreenShot); - ccAddExternalFunctionForPlugin("SeekMIDIPosition", (void*)SeekMIDIPosition); - ccAddExternalFunctionForPlugin("SeekMODPattern", (void*)SeekMODPattern); - ccAddExternalFunctionForPlugin("SeekMP3PosMillis", (void*)SeekMP3PosMillis); - ccAddExternalFunctionForPlugin("SetActiveInventory", (void*)SetActiveInventory); - ccAddExternalFunctionForPlugin("SetAmbientTint", (void*)SetAmbientTint); - ccAddExternalFunctionForPlugin("SetAreaLightLevel", (void*)SetAreaLightLevel); - ccAddExternalFunctionForPlugin("SetAreaScaling", (void*)SetAreaScaling); - ccAddExternalFunctionForPlugin("SetBackgroundFrame", (void*)SetBackgroundFrame); - ccAddExternalFunctionForPlugin("SetButtonPic", (void*)SetButtonPic); - ccAddExternalFunctionForPlugin("SetButtonText", (void*)SetButtonText); - ccAddExternalFunctionForPlugin("SetChannelVolume", (void*)SetChannelVolume); - ccAddExternalFunctionForPlugin("SetCharacterBaseline", (void*)SetCharacterBaseline); - ccAddExternalFunctionForPlugin("SetCharacterClickable", (void*)SetCharacterClickable); - ccAddExternalFunctionForPlugin("SetCharacterFrame", (void*)SetCharacterFrame); - ccAddExternalFunctionForPlugin("SetCharacterIdle", (void*)SetCharacterIdle); - ccAddExternalFunctionForPlugin("SetCharacterIgnoreLight", (void*)SetCharacterIgnoreLight); - ccAddExternalFunctionForPlugin("SetCharacterIgnoreWalkbehinds", (void*)SetCharacterIgnoreWalkbehinds); - ccAddExternalFunctionForPlugin("SetCharacterProperty", (void*)SetCharacterProperty); - ccAddExternalFunctionForPlugin("SetCharacterBlinkView", (void*)SetCharacterBlinkView); - ccAddExternalFunctionForPlugin("SetCharacterSpeechView", (void*)SetCharacterSpeechView); - ccAddExternalFunctionForPlugin("SetCharacterSpeed", (void*)SetCharacterSpeed); - ccAddExternalFunctionForPlugin("SetCharacterSpeedEx", (void*)SetCharacterSpeedEx); - ccAddExternalFunctionForPlugin("SetCharacterTransparency", (void*)SetCharacterTransparency); - ccAddExternalFunctionForPlugin("SetCharacterView", (void*)SetCharacterView); - ccAddExternalFunctionForPlugin("SetCharacterViewEx", (void*)SetCharacterViewEx); - ccAddExternalFunctionForPlugin("SetCharacterViewOffset", (void*)SetCharacterViewOffset); - ccAddExternalFunctionForPlugin("SetCursorMode", (void*)set_cursor_mode); - ccAddExternalFunctionForPlugin("SetDefaultCursor", (void*)set_default_cursor); - ccAddExternalFunctionForPlugin("SetDialogOption", (void*)SetDialogOption); - ccAddExternalFunctionForPlugin("SetDigitalMasterVolume", (void*)SetDigitalMasterVolume); - ccAddExternalFunctionForPlugin("SetFadeColor", (void*)SetFadeColor); - ccAddExternalFunctionForPlugin("SetFrameSound", (void*)SetFrameSound); - ccAddExternalFunctionForPlugin("SetGameOption", (void*)SetGameOption); - ccAddExternalFunctionForPlugin("SetGameSpeed", (void*)SetGameSpeed); - ccAddExternalFunctionForPlugin("SetGlobalInt", (void*)SetGlobalInt); - ccAddExternalFunctionForPlugin("SetGlobalString", (void*)SetGlobalString); - ccAddExternalFunctionForPlugin("SetGraphicalVariable", (void*)SetGraphicalVariable); - ccAddExternalFunctionForPlugin("SetGUIBackgroundPic", (void*)SetGUIBackgroundPic); - ccAddExternalFunctionForPlugin("SetGUIClickable", (void*)SetGUIClickable); - ccAddExternalFunctionForPlugin("SetGUIObjectEnabled", (void*)SetGUIObjectEnabled); - ccAddExternalFunctionForPlugin("SetGUIObjectPosition", (void*)SetGUIObjectPosition); - ccAddExternalFunctionForPlugin("SetGUIObjectSize", (void*)SetGUIObjectSize); - ccAddExternalFunctionForPlugin("SetGUIPosition", (void*)SetGUIPosition); - ccAddExternalFunctionForPlugin("SetGUISize", (void*)SetGUISize); - ccAddExternalFunctionForPlugin("SetGUITransparency", (void*)SetGUITransparency); - ccAddExternalFunctionForPlugin("SetGUIZOrder", (void*)SetGUIZOrder); - ccAddExternalFunctionForPlugin("SetInvItemName", (void*)SetInvItemName); - ccAddExternalFunctionForPlugin("SetInvItemPic", (void*)set_inv_item_pic); - ccAddExternalFunctionForPlugin("SetInvDimensions", (void*)SetInvDimensions); - ccAddExternalFunctionForPlugin("SetLabelColor", (void*)SetLabelColor); - ccAddExternalFunctionForPlugin("SetLabelFont", (void*)SetLabelFont); - ccAddExternalFunctionForPlugin("SetLabelText", (void*)SetLabelText); - ccAddExternalFunctionForPlugin("SetMouseBounds", (void*)SetMouseBounds); - ccAddExternalFunctionForPlugin("SetMouseCursor", (void*)set_mouse_cursor); - ccAddExternalFunctionForPlugin("SetMousePosition", (void*)SetMousePosition); - ccAddExternalFunctionForPlugin("SetMultitaskingMode", (void*)SetMultitasking); - ccAddExternalFunctionForPlugin("SetMusicMasterVolume", (void*)SetMusicMasterVolume); - ccAddExternalFunctionForPlugin("SetMusicRepeat", (void*)SetMusicRepeat); - ccAddExternalFunctionForPlugin("SetMusicVolume", (void*)SetMusicVolume); - ccAddExternalFunctionForPlugin("SetNextCursorMode", (void*)SetNextCursor); - ccAddExternalFunctionForPlugin("SetNextScreenTransition", (void*)SetNextScreenTransition); - ccAddExternalFunctionForPlugin("SetNormalFont", (void*)SetNormalFont); - ccAddExternalFunctionForPlugin("SetObjectBaseline", (void*)SetObjectBaseline); - ccAddExternalFunctionForPlugin("SetObjectClickable", (void*)SetObjectClickable); - ccAddExternalFunctionForPlugin("SetObjectFrame", (void*)SetObjectFrame); - ccAddExternalFunctionForPlugin("SetObjectGraphic", (void*)SetObjectGraphic); - ccAddExternalFunctionForPlugin("SetObjectIgnoreWalkbehinds", (void*)SetObjectIgnoreWalkbehinds); - ccAddExternalFunctionForPlugin("SetObjectPosition", (void*)SetObjectPosition); - ccAddExternalFunctionForPlugin("SetObjectTint", (void*)SetObjectTint); - ccAddExternalFunctionForPlugin("SetObjectTransparency", (void*)SetObjectTransparency); - ccAddExternalFunctionForPlugin("SetObjectView", (void*)SetObjectView); - // ccAddExternalFunctionForPlugin("SetPalette", (void*)scSetPal); - ccAddExternalFunctionForPlugin("SetPalRGB", (void*)SetPalRGB); - ccAddExternalFunctionForPlugin("SetPlayerCharacter", (void*)SetPlayerCharacter); - ccAddExternalFunctionForPlugin("SetRegionTint", (void*)SetRegionTint); - ccAddExternalFunctionForPlugin("SetRestartPoint", (void*)SetRestartPoint); - ccAddExternalFunctionForPlugin("SetScreenTransition", (void*)SetScreenTransition); - ccAddExternalFunctionForPlugin("SetSkipSpeech", (void*)SetSkipSpeech); - ccAddExternalFunctionForPlugin("SetSliderValue", (void*)SetSliderValue); - ccAddExternalFunctionForPlugin("SetSoundVolume", (void*)SetSoundVolume); - ccAddExternalFunctionForPlugin("SetSpeechFont", (void*)SetSpeechFont); - ccAddExternalFunctionForPlugin("SetSpeechStyle", (void*)SetSpeechStyle); - ccAddExternalFunctionForPlugin("SetSpeechVolume", (void*)SetSpeechVolume); - ccAddExternalFunctionForPlugin("SetTalkingColor", (void*)SetTalkingColor); - ccAddExternalFunctionForPlugin("SetTextBoxFont", (void*)SetTextBoxFont); - ccAddExternalFunctionForPlugin("SetTextBoxText", (void*)SetTextBoxText); - ccAddExternalFunctionForPlugin("SetTextOverlay", (void*)ScPl_SetTextOverlay); - ccAddExternalFunctionForPlugin("SetTextWindowGUI", (void*)SetTextWindowGUI); - ccAddExternalFunctionForPlugin("SetTimer", (void*)script_SetTimer); - ccAddExternalFunctionForPlugin("SetViewport", (void*)SetViewport); - ccAddExternalFunctionForPlugin("SetVoiceMode", (void*)SetVoiceMode); - ccAddExternalFunctionForPlugin("SetWalkBehindBase", (void*)SetWalkBehindBase); - ccAddExternalFunctionForPlugin("ShakeScreen", (void*)ShakeScreen); - ccAddExternalFunctionForPlugin("ShakeScreenBackground", (void*)ShakeScreenBackground); - ccAddExternalFunctionForPlugin("ShowMouseCursor", (void*)ShowMouseCursor); - ccAddExternalFunctionForPlugin("SkipUntilCharacterStops", (void*)SkipUntilCharacterStops); - ccAddExternalFunctionForPlugin("StartCutscene", (void*)StartCutscene); - ccAddExternalFunctionForPlugin("StartRecording", (void*)scStartRecording); - ccAddExternalFunctionForPlugin("StopAmbientSound", (void*)StopAmbientSound); - ccAddExternalFunctionForPlugin("StopChannel", (void*)stop_and_destroy_channel); - ccAddExternalFunctionForPlugin("StopDialog", (void*)StopDialog); - ccAddExternalFunctionForPlugin("StopMoving", (void*)StopMoving); - ccAddExternalFunctionForPlugin("StopMusic", (void*)scr_StopMusic); - ccAddExternalFunctionForPlugin("StopObjectMoving", (void*)StopObjectMoving); - ccAddExternalFunctionForPlugin("StrCat", (void*)_sc_strcat); - ccAddExternalFunctionForPlugin("StrCaseComp", (void*)ags_stricmp); - ccAddExternalFunctionForPlugin("StrComp", (void*)strcmp); - ccAddExternalFunctionForPlugin("StrContains", (void*)StrContains); - ccAddExternalFunctionForPlugin("StrCopy", (void*)_sc_strcpy); - ccAddExternalFunctionForPlugin("StrFormat", (void*)ScPl_sc_sprintf); - ccAddExternalFunctionForPlugin("StrGetCharAt", (void*)StrGetCharAt); - ccAddExternalFunctionForPlugin("StringToInt", (void*)StringToInt); - ccAddExternalFunctionForPlugin("StrLen", (void*)strlen); - ccAddExternalFunctionForPlugin("StrSetCharAt", (void*)StrSetCharAt); - ccAddExternalFunctionForPlugin("StrToLowerCase", (void*)_sc_strlower); - ccAddExternalFunctionForPlugin("StrToUpperCase", (void*)_sc_strupper); - ccAddExternalFunctionForPlugin("TintScreen", (void*)TintScreen); - ccAddExternalFunctionForPlugin("UnPauseGame", (void*)UnPauseGame); - ccAddExternalFunctionForPlugin("UpdateInventory", (void*)update_invorder); - ccAddExternalFunctionForPlugin("UpdatePalette", (void*)UpdatePalette); - ccAddExternalFunctionForPlugin("Wait", (void*)scrWait); - ccAddExternalFunctionForPlugin("WaitKey", (void*)WaitKey); - ccAddExternalFunctionForPlugin("WaitMouseKey", (void*)WaitMouseKey); + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("AbortGame", (void *)ScPl_sc_AbortGame); + ccAddExternalFunctionForPlugin("AddInventory", (void *)add_inventory); + ccAddExternalFunctionForPlugin("AddInventoryToCharacter", (void *)AddInventoryToCharacter); + ccAddExternalFunctionForPlugin("AnimateButton", (void *)AnimateButton); + ccAddExternalFunctionForPlugin("AnimateCharacter", (void *)scAnimateCharacter); + ccAddExternalFunctionForPlugin("AnimateCharacterEx", (void *)AnimateCharacterEx); + ccAddExternalFunctionForPlugin("AnimateObject", (void *)AnimateObject); + ccAddExternalFunctionForPlugin("AnimateObjectEx", (void *)AnimateObjectEx); + ccAddExternalFunctionForPlugin("AreCharactersColliding", (void *)AreCharactersColliding); + ccAddExternalFunctionForPlugin("AreCharObjColliding", (void *)AreCharObjColliding); + ccAddExternalFunctionForPlugin("AreObjectsColliding", (void *)AreObjectsColliding); + ccAddExternalFunctionForPlugin("AreThingsOverlapping", (void *)AreThingsOverlapping); + ccAddExternalFunctionForPlugin("CallRoomScript", (void *)CallRoomScript); + ccAddExternalFunctionForPlugin("CDAudio", (void *)cd_manager); + ccAddExternalFunctionForPlugin("CentreGUI", (void *)CentreGUI); + ccAddExternalFunctionForPlugin("ChangeCharacterView", (void *)ChangeCharacterView); + ccAddExternalFunctionForPlugin("ChangeCursorGraphic", (void *)ChangeCursorGraphic); + ccAddExternalFunctionForPlugin("ChangeCursorHotspot", (void *)ChangeCursorHotspot); + ccAddExternalFunctionForPlugin("ClaimEvent", (void *)ClaimEvent); + ccAddExternalFunctionForPlugin("CreateGraphicOverlay", (void *)CreateGraphicOverlay); + ccAddExternalFunctionForPlugin("CreateTextOverlay", (void *)ScPl_CreateTextOverlay); + ccAddExternalFunctionForPlugin("CyclePalette", (void *)CyclePalette); + ccAddExternalFunctionForPlugin("Debug", (void *)script_debug); + ccAddExternalFunctionForPlugin("DeleteSaveSlot", (void *)DeleteSaveSlot); + ccAddExternalFunctionForPlugin("DeleteSprite", (void *)free_dynamic_sprite); + ccAddExternalFunctionForPlugin("DisableCursorMode", (void *)disable_cursor_mode); + ccAddExternalFunctionForPlugin("DisableGroundLevelAreas", (void *)DisableGroundLevelAreas); + ccAddExternalFunctionForPlugin("DisableHotspot", (void *)DisableHotspot); + ccAddExternalFunctionForPlugin("DisableInterface", (void *)DisableInterface); + ccAddExternalFunctionForPlugin("DisableRegion", (void *)DisableRegion); + ccAddExternalFunctionForPlugin("Display", (void *)ScPl_Display); + ccAddExternalFunctionForPlugin("DisplayAt", (void *)ScPl_DisplayAt); + ccAddExternalFunctionForPlugin("DisplayAtY", (void *)DisplayAtY); + ccAddExternalFunctionForPlugin("DisplayMessage", (void *)DisplayMessage); + ccAddExternalFunctionForPlugin("DisplayMessageAtY", (void *)DisplayMessageAtY); + ccAddExternalFunctionForPlugin("DisplayMessageBar", (void *)DisplayMessageBar); + ccAddExternalFunctionForPlugin("DisplaySpeech", (void *)ScPl_sc_displayspeech); + ccAddExternalFunctionForPlugin("DisplaySpeechAt", (void *)DisplaySpeechAt); + ccAddExternalFunctionForPlugin("DisplaySpeechBackground", (void *)DisplaySpeechBackground); + ccAddExternalFunctionForPlugin("DisplayThought", (void *)ScPl_DisplayThought); + ccAddExternalFunctionForPlugin("DisplayTopBar", (void *)ScPl_DisplayTopBar); + ccAddExternalFunctionForPlugin("EnableCursorMode", (void *)enable_cursor_mode); + ccAddExternalFunctionForPlugin("EnableGroundLevelAreas", (void *)EnableGroundLevelAreas); + ccAddExternalFunctionForPlugin("EnableHotspot", (void *)EnableHotspot); + ccAddExternalFunctionForPlugin("EnableInterface", (void *)EnableInterface); + ccAddExternalFunctionForPlugin("EnableRegion", (void *)EnableRegion); + ccAddExternalFunctionForPlugin("EndCutscene", (void *)EndCutscene); + ccAddExternalFunctionForPlugin("FaceCharacter", (void *)FaceCharacter); + ccAddExternalFunctionForPlugin("FaceLocation", (void *)FaceLocation); + ccAddExternalFunctionForPlugin("FadeIn", (void *)FadeIn); + ccAddExternalFunctionForPlugin("FadeOut", (void *)my_fade_out); + ccAddExternalFunctionForPlugin("FileClose", (void *)FileClose); + ccAddExternalFunctionForPlugin("FileIsEOF", (void *)FileIsEOF); + ccAddExternalFunctionForPlugin("FileIsError", (void *)FileIsError); + // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen + ccAddExternalFunctionForPlugin("FileOpen", (void *)FileOpenCMode); + ccAddExternalFunctionForPlugin("FileRead", (void *)FileRead); + ccAddExternalFunctionForPlugin("FileReadInt", (void *)FileReadInt); + ccAddExternalFunctionForPlugin("FileReadRawChar", (void *)FileReadRawChar); + ccAddExternalFunctionForPlugin("FileReadRawInt", (void *)FileReadRawInt); + ccAddExternalFunctionForPlugin("FileWrite", (void *)FileWrite); + ccAddExternalFunctionForPlugin("FileWriteInt", (void *)FileWriteInt); + ccAddExternalFunctionForPlugin("FileWriteRawChar", (void *)FileWriteRawChar); + ccAddExternalFunctionForPlugin("FileWriteRawLine", (void *)FileWriteRawLine); + ccAddExternalFunctionForPlugin("FindGUIID", (void *)FindGUIID); + ccAddExternalFunctionForPlugin("FlipScreen", (void *)FlipScreen); + ccAddExternalFunctionForPlugin("FloatToInt", (void *)FloatToInt); + ccAddExternalFunctionForPlugin("FollowCharacter", (void *)FollowCharacter); + ccAddExternalFunctionForPlugin("FollowCharacterEx", (void *)FollowCharacterEx); + ccAddExternalFunctionForPlugin("GetBackgroundFrame", (void *)GetBackgroundFrame); + ccAddExternalFunctionForPlugin("GetButtonPic", (void *)GetButtonPic); + ccAddExternalFunctionForPlugin("GetCharacterAt", (void *)GetCharIDAtScreen); + ccAddExternalFunctionForPlugin("GetCharacterProperty", (void *)GetCharacterProperty); + ccAddExternalFunctionForPlugin("GetCharacterPropertyText", (void *)GetCharacterPropertyText); + ccAddExternalFunctionForPlugin("GetCurrentMusic", (void *)GetCurrentMusic); + ccAddExternalFunctionForPlugin("GetCursorMode", (void *)GetCursorMode); + ccAddExternalFunctionForPlugin("GetDialogOption", (void *)GetDialogOption); + ccAddExternalFunctionForPlugin("GetGameOption", (void *)GetGameOption); + ccAddExternalFunctionForPlugin("GetGameParameter", (void *)GetGameParameter); + ccAddExternalFunctionForPlugin("GetGameSpeed", (void *)GetGameSpeed); + ccAddExternalFunctionForPlugin("GetGlobalInt", (void *)GetGlobalInt); + ccAddExternalFunctionForPlugin("GetGlobalString", (void *)GetGlobalString); + ccAddExternalFunctionForPlugin("GetGraphicalVariable", (void *)GetGraphicalVariable); + ccAddExternalFunctionForPlugin("GetGUIAt", (void *)GetGUIAt); + ccAddExternalFunctionForPlugin("GetGUIObjectAt", (void *)GetGUIObjectAt); + ccAddExternalFunctionForPlugin("GetHotspotAt", (void *)GetHotspotIDAtScreen); + ccAddExternalFunctionForPlugin("GetHotspotName", (void *)GetHotspotName); + ccAddExternalFunctionForPlugin("GetHotspotPointX", (void *)GetHotspotPointX); + ccAddExternalFunctionForPlugin("GetHotspotPointY", (void *)GetHotspotPointY); + ccAddExternalFunctionForPlugin("GetHotspotProperty", (void *)GetHotspotProperty); + ccAddExternalFunctionForPlugin("GetHotspotPropertyText", (void *)GetHotspotPropertyText); + ccAddExternalFunctionForPlugin("GetInvAt", (void *)GetInvAt); + ccAddExternalFunctionForPlugin("GetInvGraphic", (void *)GetInvGraphic); + ccAddExternalFunctionForPlugin("GetInvName", (void *)GetInvName); + ccAddExternalFunctionForPlugin("GetInvProperty", (void *)GetInvProperty); + ccAddExternalFunctionForPlugin("GetInvPropertyText", (void *)GetInvPropertyText); + //ccAddExternalFunctionForPlugin("GetLanguageString", (void*)GetLanguageString); + ccAddExternalFunctionForPlugin("GetLocationName", (void *)GetLocationName); + ccAddExternalFunctionForPlugin("GetLocationType", (void *)GetLocationType); + ccAddExternalFunctionForPlugin("GetMessageText", (void *)GetMessageText); + ccAddExternalFunctionForPlugin("GetMIDIPosition", (void *)GetMIDIPosition); + ccAddExternalFunctionForPlugin("GetMP3PosMillis", (void *)GetMP3PosMillis); + ccAddExternalFunctionForPlugin("GetObjectAt", (void *)GetObjectIDAtScreen); + ccAddExternalFunctionForPlugin("GetObjectBaseline", (void *)GetObjectBaseline); + ccAddExternalFunctionForPlugin("GetObjectGraphic", (void *)GetObjectGraphic); + ccAddExternalFunctionForPlugin("GetObjectName", (void *)GetObjectName); + ccAddExternalFunctionForPlugin("GetObjectProperty", (void *)GetObjectProperty); + ccAddExternalFunctionForPlugin("GetObjectPropertyText", (void *)GetObjectPropertyText); + ccAddExternalFunctionForPlugin("GetObjectX", (void *)GetObjectX); + ccAddExternalFunctionForPlugin("GetObjectY", (void *)GetObjectY); + // ccAddExternalFunctionForPlugin("GetPalette", (void*)scGetPal); + ccAddExternalFunctionForPlugin("GetPlayerCharacter", (void *)GetPlayerCharacter); + ccAddExternalFunctionForPlugin("GetRawTime", (void *)GetRawTime); + ccAddExternalFunctionForPlugin("GetRegionAt", (void *)GetRegionIDAtRoom); + ccAddExternalFunctionForPlugin("GetRoomProperty", (void *)Room_GetProperty); + ccAddExternalFunctionForPlugin("GetRoomPropertyText", (void *)GetRoomPropertyText); + ccAddExternalFunctionForPlugin("GetSaveSlotDescription", (void *)GetSaveSlotDescription); + ccAddExternalFunctionForPlugin("GetScalingAt", (void *)GetScalingAt); + ccAddExternalFunctionForPlugin("GetSliderValue", (void *)GetSliderValue); + ccAddExternalFunctionForPlugin("GetTextBoxText", (void *)GetTextBoxText); + ccAddExternalFunctionForPlugin("GetTextHeight", (void *)GetTextHeight); + ccAddExternalFunctionForPlugin("GetTextWidth", (void *)GetTextWidth); + ccAddExternalFunctionForPlugin("GetTime", (void *)sc_GetTime); + ccAddExternalFunctionForPlugin("GetTranslation", (void *)get_translation); + ccAddExternalFunctionForPlugin("GetTranslationName", (void *)GetTranslationName); + ccAddExternalFunctionForPlugin("GetViewportX", (void *)GetViewportX); + ccAddExternalFunctionForPlugin("GetViewportY", (void *)GetViewportY); + ccAddExternalFunctionForPlugin("GetWalkableAreaAtRoom", (void *)GetWalkableAreaAtRoom); + ccAddExternalFunctionForPlugin("GetWalkableAreaAt", (void *)GetWalkableAreaAtScreen); + ccAddExternalFunctionForPlugin("GetWalkableAreaAtScreen", (void *)GetWalkableAreaAtScreen); + ccAddExternalFunctionForPlugin("GiveScore", (void *)GiveScore); + ccAddExternalFunctionForPlugin("HasPlayerBeenInRoom", (void *)HasPlayerBeenInRoom); + ccAddExternalFunctionForPlugin("HideMouseCursor", (void *)HideMouseCursor); + ccAddExternalFunctionForPlugin("InputBox", (void *)sc_inputbox); + ccAddExternalFunctionForPlugin("InterfaceOff", (void *)InterfaceOff); + ccAddExternalFunctionForPlugin("InterfaceOn", (void *)InterfaceOn); + ccAddExternalFunctionForPlugin("IntToFloat", (void *)IntToFloat); + ccAddExternalFunctionForPlugin("InventoryScreen", (void *)sc_invscreen); + ccAddExternalFunctionForPlugin("IsButtonDown", (void *)IsButtonDown); + ccAddExternalFunctionForPlugin("IsChannelPlaying", (void *)IsChannelPlaying); + ccAddExternalFunctionForPlugin("IsGamePaused", (void *)IsGamePaused); + ccAddExternalFunctionForPlugin("IsGUIOn", (void *)IsGUIOn); + ccAddExternalFunctionForPlugin("IsInteractionAvailable", (void *)IsInteractionAvailable); + ccAddExternalFunctionForPlugin("IsInventoryInteractionAvailable", (void *)IsInventoryInteractionAvailable); + ccAddExternalFunctionForPlugin("IsInterfaceEnabled", (void *)IsInterfaceEnabled); + ccAddExternalFunctionForPlugin("IsKeyPressed", (void *)IsKeyPressed); + ccAddExternalFunctionForPlugin("IsMusicPlaying", (void *)IsMusicPlaying); + ccAddExternalFunctionForPlugin("IsMusicVoxAvailable", (void *)IsMusicVoxAvailable); + ccAddExternalFunctionForPlugin("IsObjectAnimating", (void *)IsObjectAnimating); + ccAddExternalFunctionForPlugin("IsObjectMoving", (void *)IsObjectMoving); + ccAddExternalFunctionForPlugin("IsObjectOn", (void *)IsObjectOn); + ccAddExternalFunctionForPlugin("IsOverlayValid", (void *)IsOverlayValid); + ccAddExternalFunctionForPlugin("IsSoundPlaying", (void *)IsSoundPlaying); + ccAddExternalFunctionForPlugin("IsTimerExpired", (void *)IsTimerExpired); + ccAddExternalFunctionForPlugin("IsTranslationAvailable", (void *)IsTranslationAvailable); + ccAddExternalFunctionForPlugin("IsVoxAvailable", (void *)IsVoxAvailable); + ccAddExternalFunctionForPlugin("ListBoxAdd", (void *)ListBoxAdd); + ccAddExternalFunctionForPlugin("ListBoxClear", (void *)ListBoxClear); + ccAddExternalFunctionForPlugin("ListBoxDirList", (void *)ListBoxDirList); + ccAddExternalFunctionForPlugin("ListBoxGetItemText", (void *)ListBoxGetItemText); + ccAddExternalFunctionForPlugin("ListBoxGetNumItems", (void *)ListBoxGetNumItems); + ccAddExternalFunctionForPlugin("ListBoxGetSelected", (void *)ListBoxGetSelected); + ccAddExternalFunctionForPlugin("ListBoxRemove", (void *)ListBoxRemove); + ccAddExternalFunctionForPlugin("ListBoxSaveGameList", (void *)ListBoxSaveGameList); + ccAddExternalFunctionForPlugin("ListBoxSetSelected", (void *)ListBoxSetSelected); + ccAddExternalFunctionForPlugin("ListBoxSetTopItem", (void *)ListBoxSetTopItem); + ccAddExternalFunctionForPlugin("LoadImageFile", (void *)LoadImageFile); + ccAddExternalFunctionForPlugin("LoadSaveSlotScreenshot", (void *)LoadSaveSlotScreenshot); + ccAddExternalFunctionForPlugin("LoseInventory", (void *)lose_inventory); + ccAddExternalFunctionForPlugin("LoseInventoryFromCharacter", (void *)LoseInventoryFromCharacter); + ccAddExternalFunctionForPlugin("MergeObject", (void *)MergeObject); + ccAddExternalFunctionForPlugin("MoveCharacter", (void *)MoveCharacter); + ccAddExternalFunctionForPlugin("MoveCharacterBlocking", (void *)MoveCharacterBlocking); + ccAddExternalFunctionForPlugin("MoveCharacterDirect", (void *)MoveCharacterDirect); + ccAddExternalFunctionForPlugin("MoveCharacterPath", (void *)MoveCharacterPath); + ccAddExternalFunctionForPlugin("MoveCharacterStraight", (void *)MoveCharacterStraight); + ccAddExternalFunctionForPlugin("MoveCharacterToHotspot", (void *)MoveCharacterToHotspot); + ccAddExternalFunctionForPlugin("MoveCharacterToObject", (void *)MoveCharacterToObject); + ccAddExternalFunctionForPlugin("MoveObject", (void *)MoveObject); + ccAddExternalFunctionForPlugin("MoveObjectDirect", (void *)MoveObjectDirect); + ccAddExternalFunctionForPlugin("MoveOverlay", (void *)MoveOverlay); + ccAddExternalFunctionForPlugin("MoveToWalkableArea", (void *)MoveToWalkableArea); + ccAddExternalFunctionForPlugin("NewRoom", (void *)NewRoom); + ccAddExternalFunctionForPlugin("NewRoomEx", (void *)NewRoomEx); + ccAddExternalFunctionForPlugin("NewRoomNPC", (void *)NewRoomNPC); + ccAddExternalFunctionForPlugin("ObjectOff", (void *)ObjectOff); + ccAddExternalFunctionForPlugin("ObjectOn", (void *)ObjectOn); + ccAddExternalFunctionForPlugin("ParseText", (void *)ParseText); + ccAddExternalFunctionForPlugin("PauseGame", (void *)PauseGame); + ccAddExternalFunctionForPlugin("PlayAmbientSound", (void *)PlayAmbientSound); + ccAddExternalFunctionForPlugin("PlayFlic", (void *)play_flc_file); + ccAddExternalFunctionForPlugin("PlayMP3File", (void *)PlayMP3File); + ccAddExternalFunctionForPlugin("PlayMusic", (void *)PlayMusicResetQueue); + ccAddExternalFunctionForPlugin("PlayMusicQueued", (void *)PlayMusicQueued); + ccAddExternalFunctionForPlugin("PlaySilentMIDI", (void *)PlaySilentMIDI); + ccAddExternalFunctionForPlugin("PlaySound", (void *)play_sound); + ccAddExternalFunctionForPlugin("PlaySoundEx", (void *)PlaySoundEx); + ccAddExternalFunctionForPlugin("PlayVideo", (void *)scrPlayVideo); + ccAddExternalFunctionForPlugin("ProcessClick", (void *)RoomProcessClick); + ccAddExternalFunctionForPlugin("QuitGame", (void *)QuitGame); + ccAddExternalFunctionForPlugin("Random", (void *)__Rand); + ccAddExternalFunctionForPlugin("RawClearScreen", (void *)RawClear); + ccAddExternalFunctionForPlugin("RawDrawCircle", (void *)RawDrawCircle); + ccAddExternalFunctionForPlugin("RawDrawFrameTransparent", (void *)RawDrawFrameTransparent); + ccAddExternalFunctionForPlugin("RawDrawImage", (void *)RawDrawImage); + ccAddExternalFunctionForPlugin("RawDrawImageOffset", (void *)RawDrawImageOffset); + ccAddExternalFunctionForPlugin("RawDrawImageResized", (void *)RawDrawImageResized); + ccAddExternalFunctionForPlugin("RawDrawImageTransparent", (void *)RawDrawImageTransparent); + ccAddExternalFunctionForPlugin("RawDrawLine", (void *)RawDrawLine); + ccAddExternalFunctionForPlugin("RawDrawRectangle", (void *)RawDrawRectangle); + ccAddExternalFunctionForPlugin("RawDrawTriangle", (void *)RawDrawTriangle); + ccAddExternalFunctionForPlugin("RawPrint", (void *)ScPl_RawPrint); + ccAddExternalFunctionForPlugin("RawPrintMessageWrapped", (void *)RawPrintMessageWrapped); + ccAddExternalFunctionForPlugin("RawRestoreScreen", (void *)RawRestoreScreen); + ccAddExternalFunctionForPlugin("RawRestoreScreenTinted", (void *)RawRestoreScreenTinted); + ccAddExternalFunctionForPlugin("RawSaveScreen", (void *)RawSaveScreen); + ccAddExternalFunctionForPlugin("RawSetColor", (void *)RawSetColor); + ccAddExternalFunctionForPlugin("RawSetColorRGB", (void *)RawSetColorRGB); + ccAddExternalFunctionForPlugin("RefreshMouse", (void *)RefreshMouse); + ccAddExternalFunctionForPlugin("ReleaseCharacterView", (void *)ReleaseCharacterView); + ccAddExternalFunctionForPlugin("ReleaseViewport", (void *)ReleaseViewport); + ccAddExternalFunctionForPlugin("RemoveObjectTint", (void *)RemoveObjectTint); + ccAddExternalFunctionForPlugin("RemoveOverlay", (void *)RemoveOverlay); + ccAddExternalFunctionForPlugin("RemoveWalkableArea", (void *)RemoveWalkableArea); + ccAddExternalFunctionForPlugin("ResetRoom", (void *)ResetRoom); + ccAddExternalFunctionForPlugin("RestartGame", (void *)restart_game); + ccAddExternalFunctionForPlugin("RestoreGameDialog", (void *)restore_game_dialog); + ccAddExternalFunctionForPlugin("RestoreGameSlot", (void *)RestoreGameSlot); + ccAddExternalFunctionForPlugin("RestoreWalkableArea", (void *)RestoreWalkableArea); + ccAddExternalFunctionForPlugin("RunAGSGame", (void *)RunAGSGame); + ccAddExternalFunctionForPlugin("RunCharacterInteraction", (void *)RunCharacterInteraction); + ccAddExternalFunctionForPlugin("RunDialog", (void *)RunDialog); + ccAddExternalFunctionForPlugin("RunHotspotInteraction", (void *)RunHotspotInteraction); + ccAddExternalFunctionForPlugin("RunInventoryInteraction", (void *)RunInventoryInteraction); + ccAddExternalFunctionForPlugin("RunObjectInteraction", (void *)RunObjectInteraction); + ccAddExternalFunctionForPlugin("RunRegionInteraction", (void *)RunRegionInteraction); + ccAddExternalFunctionForPlugin("Said", (void *)Said); + ccAddExternalFunctionForPlugin("SaidUnknownWord", (void *)SaidUnknownWord); + ccAddExternalFunctionForPlugin("SaveCursorForLocationChange", (void *)SaveCursorForLocationChange); + ccAddExternalFunctionForPlugin("SaveGameDialog", (void *)save_game_dialog); + ccAddExternalFunctionForPlugin("SaveGameSlot", (void *)save_game); + ccAddExternalFunctionForPlugin("SaveScreenShot", (void *)SaveScreenShot); + ccAddExternalFunctionForPlugin("SeekMIDIPosition", (void *)SeekMIDIPosition); + ccAddExternalFunctionForPlugin("SeekMODPattern", (void *)SeekMODPattern); + ccAddExternalFunctionForPlugin("SeekMP3PosMillis", (void *)SeekMP3PosMillis); + ccAddExternalFunctionForPlugin("SetActiveInventory", (void *)SetActiveInventory); + ccAddExternalFunctionForPlugin("SetAmbientTint", (void *)SetAmbientTint); + ccAddExternalFunctionForPlugin("SetAreaLightLevel", (void *)SetAreaLightLevel); + ccAddExternalFunctionForPlugin("SetAreaScaling", (void *)SetAreaScaling); + ccAddExternalFunctionForPlugin("SetBackgroundFrame", (void *)SetBackgroundFrame); + ccAddExternalFunctionForPlugin("SetButtonPic", (void *)SetButtonPic); + ccAddExternalFunctionForPlugin("SetButtonText", (void *)SetButtonText); + ccAddExternalFunctionForPlugin("SetChannelVolume", (void *)SetChannelVolume); + ccAddExternalFunctionForPlugin("SetCharacterBaseline", (void *)SetCharacterBaseline); + ccAddExternalFunctionForPlugin("SetCharacterClickable", (void *)SetCharacterClickable); + ccAddExternalFunctionForPlugin("SetCharacterFrame", (void *)SetCharacterFrame); + ccAddExternalFunctionForPlugin("SetCharacterIdle", (void *)SetCharacterIdle); + ccAddExternalFunctionForPlugin("SetCharacterIgnoreLight", (void *)SetCharacterIgnoreLight); + ccAddExternalFunctionForPlugin("SetCharacterIgnoreWalkbehinds", (void *)SetCharacterIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("SetCharacterProperty", (void *)SetCharacterProperty); + ccAddExternalFunctionForPlugin("SetCharacterBlinkView", (void *)SetCharacterBlinkView); + ccAddExternalFunctionForPlugin("SetCharacterSpeechView", (void *)SetCharacterSpeechView); + ccAddExternalFunctionForPlugin("SetCharacterSpeed", (void *)SetCharacterSpeed); + ccAddExternalFunctionForPlugin("SetCharacterSpeedEx", (void *)SetCharacterSpeedEx); + ccAddExternalFunctionForPlugin("SetCharacterTransparency", (void *)SetCharacterTransparency); + ccAddExternalFunctionForPlugin("SetCharacterView", (void *)SetCharacterView); + ccAddExternalFunctionForPlugin("SetCharacterViewEx", (void *)SetCharacterViewEx); + ccAddExternalFunctionForPlugin("SetCharacterViewOffset", (void *)SetCharacterViewOffset); + ccAddExternalFunctionForPlugin("SetCursorMode", (void *)set_cursor_mode); + ccAddExternalFunctionForPlugin("SetDefaultCursor", (void *)set_default_cursor); + ccAddExternalFunctionForPlugin("SetDialogOption", (void *)SetDialogOption); + ccAddExternalFunctionForPlugin("SetDigitalMasterVolume", (void *)SetDigitalMasterVolume); + ccAddExternalFunctionForPlugin("SetFadeColor", (void *)SetFadeColor); + ccAddExternalFunctionForPlugin("SetFrameSound", (void *)SetFrameSound); + ccAddExternalFunctionForPlugin("SetGameOption", (void *)SetGameOption); + ccAddExternalFunctionForPlugin("SetGameSpeed", (void *)SetGameSpeed); + ccAddExternalFunctionForPlugin("SetGlobalInt", (void *)SetGlobalInt); + ccAddExternalFunctionForPlugin("SetGlobalString", (void *)SetGlobalString); + ccAddExternalFunctionForPlugin("SetGraphicalVariable", (void *)SetGraphicalVariable); + ccAddExternalFunctionForPlugin("SetGUIBackgroundPic", (void *)SetGUIBackgroundPic); + ccAddExternalFunctionForPlugin("SetGUIClickable", (void *)SetGUIClickable); + ccAddExternalFunctionForPlugin("SetGUIObjectEnabled", (void *)SetGUIObjectEnabled); + ccAddExternalFunctionForPlugin("SetGUIObjectPosition", (void *)SetGUIObjectPosition); + ccAddExternalFunctionForPlugin("SetGUIObjectSize", (void *)SetGUIObjectSize); + ccAddExternalFunctionForPlugin("SetGUIPosition", (void *)SetGUIPosition); + ccAddExternalFunctionForPlugin("SetGUISize", (void *)SetGUISize); + ccAddExternalFunctionForPlugin("SetGUITransparency", (void *)SetGUITransparency); + ccAddExternalFunctionForPlugin("SetGUIZOrder", (void *)SetGUIZOrder); + ccAddExternalFunctionForPlugin("SetInvItemName", (void *)SetInvItemName); + ccAddExternalFunctionForPlugin("SetInvItemPic", (void *)set_inv_item_pic); + ccAddExternalFunctionForPlugin("SetInvDimensions", (void *)SetInvDimensions); + ccAddExternalFunctionForPlugin("SetLabelColor", (void *)SetLabelColor); + ccAddExternalFunctionForPlugin("SetLabelFont", (void *)SetLabelFont); + ccAddExternalFunctionForPlugin("SetLabelText", (void *)SetLabelText); + ccAddExternalFunctionForPlugin("SetMouseBounds", (void *)SetMouseBounds); + ccAddExternalFunctionForPlugin("SetMouseCursor", (void *)set_mouse_cursor); + ccAddExternalFunctionForPlugin("SetMousePosition", (void *)SetMousePosition); + ccAddExternalFunctionForPlugin("SetMultitaskingMode", (void *)SetMultitasking); + ccAddExternalFunctionForPlugin("SetMusicMasterVolume", (void *)SetMusicMasterVolume); + ccAddExternalFunctionForPlugin("SetMusicRepeat", (void *)SetMusicRepeat); + ccAddExternalFunctionForPlugin("SetMusicVolume", (void *)SetMusicVolume); + ccAddExternalFunctionForPlugin("SetNextCursorMode", (void *)SetNextCursor); + ccAddExternalFunctionForPlugin("SetNextScreenTransition", (void *)SetNextScreenTransition); + ccAddExternalFunctionForPlugin("SetNormalFont", (void *)SetNormalFont); + ccAddExternalFunctionForPlugin("SetObjectBaseline", (void *)SetObjectBaseline); + ccAddExternalFunctionForPlugin("SetObjectClickable", (void *)SetObjectClickable); + ccAddExternalFunctionForPlugin("SetObjectFrame", (void *)SetObjectFrame); + ccAddExternalFunctionForPlugin("SetObjectGraphic", (void *)SetObjectGraphic); + ccAddExternalFunctionForPlugin("SetObjectIgnoreWalkbehinds", (void *)SetObjectIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("SetObjectPosition", (void *)SetObjectPosition); + ccAddExternalFunctionForPlugin("SetObjectTint", (void *)SetObjectTint); + ccAddExternalFunctionForPlugin("SetObjectTransparency", (void *)SetObjectTransparency); + ccAddExternalFunctionForPlugin("SetObjectView", (void *)SetObjectView); + // ccAddExternalFunctionForPlugin("SetPalette", (void*)scSetPal); + ccAddExternalFunctionForPlugin("SetPalRGB", (void *)SetPalRGB); + ccAddExternalFunctionForPlugin("SetPlayerCharacter", (void *)SetPlayerCharacter); + ccAddExternalFunctionForPlugin("SetRegionTint", (void *)SetRegionTint); + ccAddExternalFunctionForPlugin("SetRestartPoint", (void *)SetRestartPoint); + ccAddExternalFunctionForPlugin("SetScreenTransition", (void *)SetScreenTransition); + ccAddExternalFunctionForPlugin("SetSkipSpeech", (void *)SetSkipSpeech); + ccAddExternalFunctionForPlugin("SetSliderValue", (void *)SetSliderValue); + ccAddExternalFunctionForPlugin("SetSoundVolume", (void *)SetSoundVolume); + ccAddExternalFunctionForPlugin("SetSpeechFont", (void *)SetSpeechFont); + ccAddExternalFunctionForPlugin("SetSpeechStyle", (void *)SetSpeechStyle); + ccAddExternalFunctionForPlugin("SetSpeechVolume", (void *)SetSpeechVolume); + ccAddExternalFunctionForPlugin("SetTalkingColor", (void *)SetTalkingColor); + ccAddExternalFunctionForPlugin("SetTextBoxFont", (void *)SetTextBoxFont); + ccAddExternalFunctionForPlugin("SetTextBoxText", (void *)SetTextBoxText); + ccAddExternalFunctionForPlugin("SetTextOverlay", (void *)ScPl_SetTextOverlay); + ccAddExternalFunctionForPlugin("SetTextWindowGUI", (void *)SetTextWindowGUI); + ccAddExternalFunctionForPlugin("SetTimer", (void *)script_SetTimer); + ccAddExternalFunctionForPlugin("SetViewport", (void *)SetViewport); + ccAddExternalFunctionForPlugin("SetVoiceMode", (void *)SetVoiceMode); + ccAddExternalFunctionForPlugin("SetWalkBehindBase", (void *)SetWalkBehindBase); + ccAddExternalFunctionForPlugin("ShakeScreen", (void *)ShakeScreen); + ccAddExternalFunctionForPlugin("ShakeScreenBackground", (void *)ShakeScreenBackground); + ccAddExternalFunctionForPlugin("ShowMouseCursor", (void *)ShowMouseCursor); + ccAddExternalFunctionForPlugin("SkipUntilCharacterStops", (void *)SkipUntilCharacterStops); + ccAddExternalFunctionForPlugin("StartCutscene", (void *)StartCutscene); + ccAddExternalFunctionForPlugin("StartRecording", (void *)scStartRecording); + ccAddExternalFunctionForPlugin("StopAmbientSound", (void *)StopAmbientSound); + ccAddExternalFunctionForPlugin("StopChannel", (void *)stop_and_destroy_channel); + ccAddExternalFunctionForPlugin("StopDialog", (void *)StopDialog); + ccAddExternalFunctionForPlugin("StopMoving", (void *)StopMoving); + ccAddExternalFunctionForPlugin("StopMusic", (void *)scr_StopMusic); + ccAddExternalFunctionForPlugin("StopObjectMoving", (void *)StopObjectMoving); + ccAddExternalFunctionForPlugin("StrCat", (void *)_sc_strcat); + ccAddExternalFunctionForPlugin("StrCaseComp", (void *)ags_stricmp); + ccAddExternalFunctionForPlugin("StrComp", (void *)strcmp); + ccAddExternalFunctionForPlugin("StrContains", (void *)StrContains); + ccAddExternalFunctionForPlugin("StrCopy", (void *)_sc_strcpy); + ccAddExternalFunctionForPlugin("StrFormat", (void *)ScPl_sc_sprintf); + ccAddExternalFunctionForPlugin("StrGetCharAt", (void *)StrGetCharAt); + ccAddExternalFunctionForPlugin("StringToInt", (void *)StringToInt); + ccAddExternalFunctionForPlugin("StrLen", (void *)strlen); + ccAddExternalFunctionForPlugin("StrSetCharAt", (void *)StrSetCharAt); + ccAddExternalFunctionForPlugin("StrToLowerCase", (void *)_sc_strlower); + ccAddExternalFunctionForPlugin("StrToUpperCase", (void *)_sc_strupper); + ccAddExternalFunctionForPlugin("TintScreen", (void *)TintScreen); + ccAddExternalFunctionForPlugin("UnPauseGame", (void *)UnPauseGame); + ccAddExternalFunctionForPlugin("UpdateInventory", (void *)update_invorder); + ccAddExternalFunctionForPlugin("UpdatePalette", (void *)UpdatePalette); + ccAddExternalFunctionForPlugin("Wait", (void *)scrWait); + ccAddExternalFunctionForPlugin("WaitKey", (void *)WaitKey); + ccAddExternalFunctionForPlugin("WaitMouseKey", (void *)WaitMouseKey); } diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp index 85899b47c311..b9154a968615 100644 --- a/engines/ags/engine/ac/global_audio.cpp +++ b/engines/ags/engine/ac/global_audio.cpp @@ -45,644 +45,625 @@ extern RoomStruct thisroom; extern SpeechLipSyncLine *splipsync; extern int numLipLines, curLipLine, curLipLinePhoneme; -void StopAmbientSound (int channel) { - if ((channel < 0) || (channel >= MAX_SOUND_CHANNELS)) - quit("!StopAmbientSound: invalid channel"); - - if (ambient[channel].channel == 0) - return; - - stop_and_destroy_channel(channel); - ambient[channel].channel = 0; -} - -void PlayAmbientSound (int channel, int sndnum, int vol, int x, int y) { - // the channel parameter is to allow multiple ambient sounds in future - if ((channel < 1) || (channel == SCHAN_SPEECH) || (channel >= MAX_SOUND_CHANNELS)) - quit("!PlayAmbientSound: invalid channel number"); - if ((vol < 1) || (vol > 255)) - quit("!PlayAmbientSound: volume must be 1 to 255"); - - ScriptAudioClip *aclip = GetAudioClipForOldStyleNumber(game, false, sndnum); - if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) - return; - - // only play the sound if it's not already playing - if ((ambient[channel].channel < 1) || (!channel_is_playing(ambient[channel].channel)) || - (ambient[channel].num != sndnum)) { - - StopAmbientSound(channel); - // in case a normal non-ambient sound was playing, stop it too - stop_and_destroy_channel(channel); - - SOUNDCLIP *asound = aclip ? load_sound_and_play(aclip, true) : nullptr; - if (asound == nullptr) { - debug_script_warn ("Cannot load ambient sound %d", sndnum); - debug_script_log("FAILED to load ambient sound %d", sndnum); - return; - } - - debug_script_log("Playing ambient sound %d on channel %d", sndnum, channel); - ambient[channel].channel = channel; - asound->priority = 15; // ambient sound higher priority than normal sfx - set_clip_to_channel(channel, asound); - } - // calculate the maximum distance away the player can be, using X - // only (since X centred is still more-or-less total Y) - ambient[channel].maxdist = ((x > thisroom.Width / 2) ? x : (thisroom.Width - x)) - AMBIENCE_FULL_DIST; - ambient[channel].num = sndnum; - ambient[channel].x = x; - ambient[channel].y = y; - ambient[channel].vol = vol; - update_ambient_sound_vol(); +void StopAmbientSound(int channel) { + if ((channel < 0) || (channel >= MAX_SOUND_CHANNELS)) + quit("!StopAmbientSound: invalid channel"); + + if (ambient[channel].channel == 0) + return; + + stop_and_destroy_channel(channel); + ambient[channel].channel = 0; +} + +void PlayAmbientSound(int channel, int sndnum, int vol, int x, int y) { + // the channel parameter is to allow multiple ambient sounds in future + if ((channel < 1) || (channel == SCHAN_SPEECH) || (channel >= MAX_SOUND_CHANNELS)) + quit("!PlayAmbientSound: invalid channel number"); + if ((vol < 1) || (vol > 255)) + quit("!PlayAmbientSound: volume must be 1 to 255"); + + ScriptAudioClip *aclip = GetAudioClipForOldStyleNumber(game, false, sndnum); + if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) + return; + + // only play the sound if it's not already playing + if ((ambient[channel].channel < 1) || (!channel_is_playing(ambient[channel].channel)) || + (ambient[channel].num != sndnum)) { + + StopAmbientSound(channel); + // in case a normal non-ambient sound was playing, stop it too + stop_and_destroy_channel(channel); + + SOUNDCLIP *asound = aclip ? load_sound_and_play(aclip, true) : nullptr; + if (asound == nullptr) { + debug_script_warn("Cannot load ambient sound %d", sndnum); + debug_script_log("FAILED to load ambient sound %d", sndnum); + return; + } + + debug_script_log("Playing ambient sound %d on channel %d", sndnum, channel); + ambient[channel].channel = channel; + asound->priority = 15; // ambient sound higher priority than normal sfx + set_clip_to_channel(channel, asound); + } + // calculate the maximum distance away the player can be, using X + // only (since X centred is still more-or-less total Y) + ambient[channel].maxdist = ((x > thisroom.Width / 2) ? x : (thisroom.Width - x)) - AMBIENCE_FULL_DIST; + ambient[channel].num = sndnum; + ambient[channel].x = x; + ambient[channel].y = y; + ambient[channel].vol = vol; + update_ambient_sound_vol(); } int IsChannelPlaying(int chan) { - if (play.fast_forward) - return 0; + if (play.fast_forward) + return 0; - if ((chan < 0) || (chan >= MAX_SOUND_CHANNELS)) - quit("!IsChannelPlaying: invalid sound channel"); + if ((chan < 0) || (chan >= MAX_SOUND_CHANNELS)) + quit("!IsChannelPlaying: invalid sound channel"); - if (channel_is_playing(chan)) - return 1; + if (channel_is_playing(chan)) + return 1; - return 0; + return 0; } int IsSoundPlaying() { - if (play.fast_forward) - return 0; + if (play.fast_forward) + return 0; - // find if there's a sound playing - AudioChannelsLock lock; - for (int i = SCHAN_NORMAL; i < MAX_SOUND_CHANNELS; i++) { - if (lock.GetChannelIfPlaying(i)) - return 1; - } + // find if there's a sound playing + AudioChannelsLock lock; + for (int i = SCHAN_NORMAL; i < MAX_SOUND_CHANNELS; i++) { + if (lock.GetChannelIfPlaying(i)) + return 1; + } - return 0; + return 0; } // returns -1 on failure, channel number on success int PlaySoundEx(int val1, int channel) { - if (debug_flags & DBG_NOSFX) - return -1; + if (debug_flags & DBG_NOSFX) + return -1; - ScriptAudioClip *aclip = GetAudioClipForOldStyleNumber(game, false, val1); - if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) - return -1; // if sound is off, ignore it + ScriptAudioClip *aclip = GetAudioClipForOldStyleNumber(game, false, val1); + if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) + return -1; // if sound is off, ignore it - if ((channel < SCHAN_NORMAL) || (channel >= MAX_SOUND_CHANNELS)) - quit("!PlaySoundEx: invalid channel specified, must be 3-7"); + if ((channel < SCHAN_NORMAL) || (channel >= MAX_SOUND_CHANNELS)) + quit("!PlaySoundEx: invalid channel specified, must be 3-7"); - // if an ambient sound is playing on this channel, abort it - StopAmbientSound(channel); + // if an ambient sound is playing on this channel, abort it + StopAmbientSound(channel); - if (val1 < 0) { - stop_and_destroy_channel (channel); - return -1; - } - // if skipping a cutscene, don't try and play the sound - if (play.fast_forward) - return -1; + if (val1 < 0) { + stop_and_destroy_channel(channel); + return -1; + } + // if skipping a cutscene, don't try and play the sound + if (play.fast_forward) + return -1; - // free the old sound - stop_and_destroy_channel (channel); - debug_script_log("Playing sound %d on channel %d", val1, channel); + // free the old sound + stop_and_destroy_channel(channel); + debug_script_log("Playing sound %d on channel %d", val1, channel); - SOUNDCLIP *soundfx = aclip ? load_sound_and_play(aclip, false) : nullptr; - if (soundfx == nullptr) { - debug_script_warn("Sound sample load failure: cannot load sound %d", val1); - debug_script_log("FAILED to load sound %d", val1); - return -1; - } + SOUNDCLIP *soundfx = aclip ? load_sound_and_play(aclip, false) : nullptr; + if (soundfx == nullptr) { + debug_script_warn("Sound sample load failure: cannot load sound %d", val1); + debug_script_log("FAILED to load sound %d", val1); + return -1; + } - soundfx->priority = 10; - soundfx->set_volume (play.sound_volume); - set_clip_to_channel(channel,soundfx); - return channel; + soundfx->priority = 10; + soundfx->set_volume(play.sound_volume); + set_clip_to_channel(channel, soundfx); + return channel; } void StopAllSounds(int evenAmbient) { - // backwards-compatible hack -- stop Type 3 (default Sound Type) - Game_StopAudio(3); + // backwards-compatible hack -- stop Type 3 (default Sound Type) + Game_StopAudio(3); - if (evenAmbient) - Game_StopAudio(1); + if (evenAmbient) + Game_StopAudio(1); } void PlayMusicResetQueue(int newmus) { - play.music_queue_size = 0; - newmusic(newmus); + play.music_queue_size = 0; + newmusic(newmus); } -void SeekMIDIPosition (int position) { - if (play.silent_midi == 0 && current_music_type != MUS_MIDI) - return; +void SeekMIDIPosition(int position) { + if (play.silent_midi == 0 && current_music_type != MUS_MIDI) + return; - AudioChannelsLock lock; - auto *ch = lock.GetChannel(SCHAN_MUSIC); - ch->seek(position); - debug_script_log("Seek MIDI position to %d", position); + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_MUSIC); + ch->seek(position); + debug_script_log("Seek MIDI position to %d", position); } -int GetMIDIPosition () { - if (play.fast_forward) - return 99999; - if (play.silent_midi == 0 && current_music_type != MUS_MIDI) - return -1; // returns -1 on failure according to old manuals - - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); - if (ch) { - return ch->get_pos(); - } +int GetMIDIPosition() { + if (play.fast_forward) + return 99999; + if (play.silent_midi == 0 && current_music_type != MUS_MIDI) + return -1; // returns -1 on failure according to old manuals - return -1; + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + if (ch) { + return ch->get_pos(); + } + + return -1; } int IsMusicPlaying() { - // in case they have a "while (IsMusicPlaying())" loop - if ((play.fast_forward) && (play.skip_until_char_stops < 0)) - return 0; + // in case they have a "while (IsMusicPlaying())" loop + if ((play.fast_forward) && (play.skip_until_char_stops < 0)) + return 0; - // This only returns positive if there was a music started by old audio API - if (current_music_type == 0) - return 0; + // This only returns positive if there was a music started by old audio API + if (current_music_type == 0) + return 0; - AudioChannelsLock lock; - auto *ch = lock.GetChannel(SCHAN_MUSIC); - if (ch == nullptr) - { // This was probably a hacky fix in case it was not reset by game update; TODO: find out if needed - current_music_type = 0; - return 0; - } + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_MUSIC); + if (ch == nullptr) { + // This was probably a hacky fix in case it was not reset by game update; TODO: find out if needed + current_music_type = 0; + return 0; + } - bool result = (ch->is_playing()) || (crossFading > 0 && (lock.GetChannelIfPlaying(crossFading) != nullptr)); - return result ? 1 : 0; + bool result = (ch->is_playing()) || (crossFading > 0 && (lock.GetChannelIfPlaying(crossFading) != nullptr)); + return result ? 1 : 0; } int PlayMusicQueued(int musnum) { - // Just get the queue size - if (musnum < 0) - return play.music_queue_size; + // Just get the queue size + if (musnum < 0) + return play.music_queue_size; - if ((IsMusicPlaying() == 0) && (play.music_queue_size == 0)) { - newmusic(musnum); - return 0; - } + if ((IsMusicPlaying() == 0) && (play.music_queue_size == 0)) { + newmusic(musnum); + return 0; + } - if (play.music_queue_size >= MAX_QUEUED_MUSIC) { - debug_script_log("Too many queued music, cannot add %d", musnum); - return 0; - } + if (play.music_queue_size >= MAX_QUEUED_MUSIC) { + debug_script_log("Too many queued music, cannot add %d", musnum); + return 0; + } - if ((play.music_queue_size > 0) && - (play.music_queue[play.music_queue_size - 1] >= QUEUED_MUSIC_REPEAT)) { - debug_script_warn("PlayMusicQueued: cannot queue music after a repeating tune has been queued"); - return 0; - } + if ((play.music_queue_size > 0) && + (play.music_queue[play.music_queue_size - 1] >= QUEUED_MUSIC_REPEAT)) { + debug_script_warn("PlayMusicQueued: cannot queue music after a repeating tune has been queued"); + return 0; + } - if (play.music_repeat) { - debug_script_log("Queuing music %d to loop", musnum); - musnum += QUEUED_MUSIC_REPEAT; - } - else { - debug_script_log("Queuing music %d", musnum); - } + if (play.music_repeat) { + debug_script_log("Queuing music %d to loop", musnum); + musnum += QUEUED_MUSIC_REPEAT; + } else { + debug_script_log("Queuing music %d", musnum); + } - play.music_queue[play.music_queue_size] = musnum; - play.music_queue_size++; + play.music_queue[play.music_queue_size] = musnum; + play.music_queue_size++; - if (play.music_queue_size == 1) { + if (play.music_queue_size == 1) { - clear_music_cache(); + clear_music_cache(); - cachedQueuedMusic = load_music_from_disk(musnum, (play.music_repeat > 0)); - } + cachedQueuedMusic = load_music_from_disk(musnum, (play.music_repeat > 0)); + } - return play.music_queue_size; + return play.music_queue_size; } void scr_StopMusic() { - play.music_queue_size = 0; - stopmusic(); + play.music_queue_size = 0; + stopmusic(); } void SeekMODPattern(int patnum) { - if (current_music_type != MUS_MOD) - return; + if (current_music_type != MUS_MOD) + return; - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); - if (ch) { - ch->seek (patnum); - debug_script_log("Seek MOD/XM to pattern %d", patnum); - } + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + if (ch) { + ch->seek(patnum); + debug_script_log("Seek MOD/XM to pattern %d", patnum); + } } -void SeekMP3PosMillis (int posn) { - if (current_music_type != MUS_MP3 && current_music_type != MUS_OGG) - return; +void SeekMP3PosMillis(int posn) { + if (current_music_type != MUS_MP3 && current_music_type != MUS_OGG) + return; - AudioChannelsLock lock; - auto *mus_ch = lock.GetChannel(SCHAN_MUSIC); - auto *cf_ch = (crossFading > 0) ? lock.GetChannel(crossFading) : nullptr; - if (cf_ch) - cf_ch->seek(posn); - else if (mus_ch) - mus_ch->seek(posn); + AudioChannelsLock lock; + auto *mus_ch = lock.GetChannel(SCHAN_MUSIC); + auto *cf_ch = (crossFading > 0) ? lock.GetChannel(crossFading) : nullptr; + if (cf_ch) + cf_ch->seek(posn); + else if (mus_ch) + mus_ch->seek(posn); } -int GetMP3PosMillis () { - // in case they have "while (GetMP3PosMillis() < 5000) " - if (play.fast_forward) - return 999999; - if (current_music_type != MUS_MP3 && current_music_type != MUS_OGG) - return 0; // returns 0 on failure according to old manuals +int GetMP3PosMillis() { + // in case they have "while (GetMP3PosMillis() < 5000) " + if (play.fast_forward) + return 999999; + if (current_music_type != MUS_MP3 && current_music_type != MUS_OGG) + return 0; // returns 0 on failure according to old manuals - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); - if (ch) { - int result = ch->get_pos_ms(); - if (result >= 0) - return result; + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(SCHAN_MUSIC); + if (ch) { + int result = ch->get_pos_ms(); + if (result >= 0) + return result; - return ch->get_pos (); - } + return ch->get_pos(); + } - return 0; + return 0; } void SetMusicVolume(int newvol) { - if ((newvol < kRoomVolumeMin) || (newvol > kRoomVolumeMax)) - quitprintf("!SetMusicVolume: invalid volume number. Must be from %d to %d.", kRoomVolumeMin, kRoomVolumeMax); - thisroom.Options.MusicVolume=(RoomVolumeMod)newvol; - update_music_volume(); + if ((newvol < kRoomVolumeMin) || (newvol > kRoomVolumeMax)) + quitprintf("!SetMusicVolume: invalid volume number. Must be from %d to %d.", kRoomVolumeMin, kRoomVolumeMax); + thisroom.Options.MusicVolume = (RoomVolumeMod)newvol; + update_music_volume(); } void SetMusicMasterVolume(int newvol) { - const int min_volume = loaded_game_file_version < kGameVersion_330 ? 0 : - -LegacyMusicMasterVolumeAdjustment - (kRoomVolumeMax * LegacyRoomVolumeFactor); - if ((newvol < min_volume) | (newvol>100)) - quitprintf("!SetMusicMasterVolume: invalid volume - must be from %d to %d", min_volume, 100); - play.music_master_volume=newvol+LegacyMusicMasterVolumeAdjustment; - update_music_volume(); + const int min_volume = loaded_game_file_version < kGameVersion_330 ? 0 : + -LegacyMusicMasterVolumeAdjustment - (kRoomVolumeMax * LegacyRoomVolumeFactor); + if ((newvol < min_volume) | (newvol > 100)) + quitprintf("!SetMusicMasterVolume: invalid volume - must be from %d to %d", min_volume, 100); + play.music_master_volume = newvol + LegacyMusicMasterVolumeAdjustment; + update_music_volume(); } void SetSoundVolume(int newvol) { - if ((newvol<0) | (newvol>255)) - quit("!SetSoundVolume: invalid volume - must be from 0-255"); - play.sound_volume = newvol; - Game_SetAudioTypeVolume(AUDIOTYPE_LEGACY_AMBIENT_SOUND, (newvol * 100) / 255, VOL_BOTH); - Game_SetAudioTypeVolume(AUDIOTYPE_LEGACY_SOUND, (newvol * 100) / 255, VOL_BOTH); - update_ambient_sound_vol (); + if ((newvol < 0) | (newvol > 255)) + quit("!SetSoundVolume: invalid volume - must be from 0-255"); + play.sound_volume = newvol; + Game_SetAudioTypeVolume(AUDIOTYPE_LEGACY_AMBIENT_SOUND, (newvol * 100) / 255, VOL_BOTH); + Game_SetAudioTypeVolume(AUDIOTYPE_LEGACY_SOUND, (newvol * 100) / 255, VOL_BOTH); + update_ambient_sound_vol(); } void SetChannelVolume(int chan, int newvol) { - if ((newvol<0) || (newvol>255)) - quit("!SetChannelVolume: invalid volume - must be from 0-255"); - if ((chan < 0) || (chan >= MAX_SOUND_CHANNELS)) - quit("!SetChannelVolume: invalid channel id"); + if ((newvol < 0) || (newvol > 255)) + quit("!SetChannelVolume: invalid volume - must be from 0-255"); + if ((chan < 0) || (chan >= MAX_SOUND_CHANNELS)) + quit("!SetChannelVolume: invalid channel id"); - AudioChannelsLock lock; - auto* ch = lock.GetChannelIfPlaying(chan); + AudioChannelsLock lock; + auto *ch = lock.GetChannelIfPlaying(chan); - if (ch) { - if (chan == ambient[chan].channel) { - ambient[chan].vol = newvol; - update_ambient_sound_vol(); - } - else - ch->set_volume (newvol); - } + if (ch) { + if (chan == ambient[chan].channel) { + ambient[chan].vol = newvol; + update_ambient_sound_vol(); + } else + ch->set_volume(newvol); + } } -void SetDigitalMasterVolume (int newvol) { - if ((newvol<0) | (newvol>100)) - quit("!SetDigitalMasterVolume: invalid volume - must be from 0-100"); - play.digital_master_volume = newvol; - set_volume ((newvol * 255) / 100, -1); +void SetDigitalMasterVolume(int newvol) { + if ((newvol < 0) | (newvol > 100)) + quit("!SetDigitalMasterVolume: invalid volume - must be from 0-100"); + play.digital_master_volume = newvol; + set_volume((newvol * 255) / 100, -1); } int GetCurrentMusic() { - return play.cur_music_number; + return play.cur_music_number; } void SetMusicRepeat(int loopflag) { - play.music_repeat=loopflag; -} - -void PlayMP3File (const char *filename) { - if (strlen(filename) >= PLAYMP3FILE_MAX_FILENAME_LEN) - quit("!PlayMP3File: filename too long"); - - debug_script_log("PlayMP3File %s", filename); - - AssetPath asset_name("", filename); - - int useChan = prepare_for_new_music (); - bool doLoop = (play.music_repeat > 0); - - SOUNDCLIP *clip = nullptr; - - if (!clip) { - clip = my_load_static_ogg(asset_name, 150, doLoop); - if (clip) { - if (clip->play()) { - set_clip_to_channel(useChan, clip); - current_music_type = MUS_OGG; - play.cur_music_number = 1000; - // save the filename (if it's not what we were supplied with) - if (filename != &play.playmp3file_name[0]) - strcpy (play.playmp3file_name, filename); - } else { - clip->destroy(); - delete clip; - clip = nullptr; - } - } - } - - if (!clip) - { - clip = my_load_static_mp3(asset_name, 150, doLoop); - if (clip) { - if (clip->play()) { - set_clip_to_channel(useChan, clip); - current_music_type = MUS_MP3; - play.cur_music_number = 1000; - // save the filename (if it's not what we were supplied with) - if (filename != &play.playmp3file_name[0]) - strcpy(play.playmp3file_name, filename); - } else { - clip->destroy(); - delete clip; - clip = nullptr; - } - } - } - - if (!clip) { - set_clip_to_channel(useChan, nullptr); - debug_script_warn ("PlayMP3File: file '%s' not found or cannot play", filename); - } - - post_new_music_check(useChan); - - update_music_volume(); -} - -void PlaySilentMIDI (int mnum) { - if (current_music_type == MUS_MIDI) - quit("!PlaySilentMIDI: proper midi music is in progress"); - - set_volume (-1, 0); - play.silent_midi = mnum; - play.silent_midi_channel = SCHAN_SPEECH; - stop_and_destroy_channel(play.silent_midi_channel); - // No idea why it uses speech voice channel, but since it does (and until this is changed) - // we have to correctly reset speech voice in case there was a nonblocking speech - if (play.IsNonBlockingVoiceSpeech()) - stop_voice_nonblocking(); - - SOUNDCLIP *clip = load_sound_clip_from_old_style_number(true, mnum, false); - if (clip == nullptr) - { - quitprintf("!PlaySilentMIDI: failed to load aMusic%d", mnum); - } - AudioChannelsLock lock; - lock.SetChannel(play.silent_midi_channel, clip); - if (!clip->play()) { - clip->destroy(); - delete clip; - clip = nullptr; - quitprintf("!PlaySilentMIDI: failed to play aMusic%d", mnum); - } - clip->set_volume_percent(0); + play.music_repeat = loopflag; +} + +void PlayMP3File(const char *filename) { + if (strlen(filename) >= PLAYMP3FILE_MAX_FILENAME_LEN) + quit("!PlayMP3File: filename too long"); + + debug_script_log("PlayMP3File %s", filename); + + AssetPath asset_name("", filename); + + int useChan = prepare_for_new_music(); + bool doLoop = (play.music_repeat > 0); + + SOUNDCLIP *clip = nullptr; + + if (!clip) { + clip = my_load_static_ogg(asset_name, 150, doLoop); + if (clip) { + if (clip->play()) { + set_clip_to_channel(useChan, clip); + current_music_type = MUS_OGG; + play.cur_music_number = 1000; + // save the filename (if it's not what we were supplied with) + if (filename != &play.playmp3file_name[0]) + strcpy(play.playmp3file_name, filename); + } else { + clip->destroy(); + delete clip; + clip = nullptr; + } + } + } + + if (!clip) { + clip = my_load_static_mp3(asset_name, 150, doLoop); + if (clip) { + if (clip->play()) { + set_clip_to_channel(useChan, clip); + current_music_type = MUS_MP3; + play.cur_music_number = 1000; + // save the filename (if it's not what we were supplied with) + if (filename != &play.playmp3file_name[0]) + strcpy(play.playmp3file_name, filename); + } else { + clip->destroy(); + delete clip; + clip = nullptr; + } + } + } + + if (!clip) { + set_clip_to_channel(useChan, nullptr); + debug_script_warn("PlayMP3File: file '%s' not found or cannot play", filename); + } + + post_new_music_check(useChan); + + update_music_volume(); +} + +void PlaySilentMIDI(int mnum) { + if (current_music_type == MUS_MIDI) + quit("!PlaySilentMIDI: proper midi music is in progress"); + + set_volume(-1, 0); + play.silent_midi = mnum; + play.silent_midi_channel = SCHAN_SPEECH; + stop_and_destroy_channel(play.silent_midi_channel); + // No idea why it uses speech voice channel, but since it does (and until this is changed) + // we have to correctly reset speech voice in case there was a nonblocking speech + if (play.IsNonBlockingVoiceSpeech()) + stop_voice_nonblocking(); + + SOUNDCLIP *clip = load_sound_clip_from_old_style_number(true, mnum, false); + if (clip == nullptr) { + quitprintf("!PlaySilentMIDI: failed to load aMusic%d", mnum); + } + AudioChannelsLock lock; + lock.SetChannel(play.silent_midi_channel, clip); + if (!clip->play()) { + clip->destroy(); + delete clip; + clip = nullptr; + quitprintf("!PlaySilentMIDI: failed to play aMusic%d", mnum); + } + clip->set_volume_percent(0); } void SetSpeechVolume(int newvol) { - if ((newvol<0) | (newvol>255)) - quit("!SetSpeechVolume: invalid volume - must be from 0-255"); + if ((newvol < 0) | (newvol > 255)) + quit("!SetSpeechVolume: invalid volume - must be from 0-255"); - AudioChannelsLock lock; - auto* ch = lock.GetChannel(SCHAN_SPEECH); - if (ch) - ch->set_volume (newvol); - play.speech_volume = newvol; + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_SPEECH); + if (ch) + ch->set_volume(newvol); + play.speech_volume = newvol; } // 0 = text only // 1 = voice & text // 2 = voice only -void SetVoiceMode (int newmod) { - if ((newmod < 0) | (newmod > 2)) - quit("!SetVoiceMode: invalid mode number (must be 0,1,2)"); - // If speech is turned off, store the mode anyway in case the - // user adds the VOX file later - if (play.want_speech < 0) - play.want_speech = (-newmod) - 1; - else - play.want_speech = newmod; +void SetVoiceMode(int newmod) { + if ((newmod < 0) | (newmod > 2)) + quit("!SetVoiceMode: invalid mode number (must be 0,1,2)"); + // If speech is turned off, store the mode anyway in case the + // user adds the VOX file later + if (play.want_speech < 0) + play.want_speech = (-newmod) - 1; + else + play.want_speech = newmod; } -int GetVoiceMode() -{ - return play.want_speech >= 0 ? play.want_speech : -(play.want_speech + 1); +int GetVoiceMode() { + return play.want_speech >= 0 ? play.want_speech : -(play.want_speech + 1); } int IsVoxAvailable() { - if (play.want_speech < 0) - return 0; - return 1; + if (play.want_speech < 0) + return 0; + return 1; } -int IsMusicVoxAvailable () { - return play.separate_music_lib; +int IsMusicVoxAvailable() { + return play.separate_music_lib; } extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; -ScriptAudioChannel *PlayVoiceClip(CharacterInfo *ch, int sndid, bool as_speech) -{ - if (!play_voice_nonblocking(ch->index_id, sndid, as_speech)) - return NULL; - return &scrAudioChannel[SCHAN_SPEECH]; +ScriptAudioChannel *PlayVoiceClip(CharacterInfo *ch, int sndid, bool as_speech) { + if (!play_voice_nonblocking(ch->index_id, sndid, as_speech)) + return NULL; + return &scrAudioChannel[SCHAN_SPEECH]; } // Construct an asset name for the voice-over clip for the given character and cue id -String get_cue_filename(int charid, int sndid) -{ - String script_name; - if (charid >= 0) - { - // append the first 4 characters of the script name to the filename - if (game.chars[charid].scrname[0] == 'c') - script_name.SetString(&game.chars[charid].scrname[1], 4); - else - script_name.SetString(game.chars[charid].scrname, 4); - } - else - { - script_name = "NARR"; - } - return String::FromFormat("%s%d", script_name.GetCStr(), sndid); +String get_cue_filename(int charid, int sndid) { + String script_name; + if (charid >= 0) { + // append the first 4 characters of the script name to the filename + if (game.chars[charid].scrname[0] == 'c') + script_name.SetString(&game.chars[charid].scrname[1], 4); + else + script_name.SetString(game.chars[charid].scrname, 4); + } else { + script_name = "NARR"; + } + return String::FromFormat("%s%d", script_name.GetCStr(), sndid); } // Play voice-over clip on the common channel; // voice_name should be bare clip name without extension -static bool play_voice_clip_on_channel(const String &voice_name) -{ - stop_and_destroy_channel(SCHAN_SPEECH); - - String asset_name = voice_name; - asset_name.Append(".wav"); - SOUNDCLIP *speechmp3 = my_load_wave(get_voice_over_assetpath(asset_name), play.speech_volume, 0); - - if (speechmp3 == nullptr) { - asset_name.ReplaceMid(asset_name.GetLength() - 3, 3, "ogg"); - speechmp3 = my_load_ogg(get_voice_over_assetpath(asset_name), play.speech_volume); - } - - if (speechmp3 == nullptr) { - asset_name.ReplaceMid(asset_name.GetLength() - 3, 3, "mp3"); - speechmp3 = my_load_mp3(get_voice_over_assetpath(asset_name), play.speech_volume); - } - - if (speechmp3 != nullptr) { - if (!speechmp3->play()) { - // not assigned to a channel, so clean up manually. - speechmp3->destroy(); - delete speechmp3; - speechmp3 = nullptr; - } - } - - if (speechmp3 == nullptr) { - debug_script_warn("Speech load failure: '%s'", voice_name.GetCStr()); - return false; - } - - set_clip_to_channel(SCHAN_SPEECH,speechmp3); - return true; +static bool play_voice_clip_on_channel(const String &voice_name) { + stop_and_destroy_channel(SCHAN_SPEECH); + + String asset_name = voice_name; + asset_name.Append(".wav"); + SOUNDCLIP *speechmp3 = my_load_wave(get_voice_over_assetpath(asset_name), play.speech_volume, 0); + + if (speechmp3 == nullptr) { + asset_name.ReplaceMid(asset_name.GetLength() - 3, 3, "ogg"); + speechmp3 = my_load_ogg(get_voice_over_assetpath(asset_name), play.speech_volume); + } + + if (speechmp3 == nullptr) { + asset_name.ReplaceMid(asset_name.GetLength() - 3, 3, "mp3"); + speechmp3 = my_load_mp3(get_voice_over_assetpath(asset_name), play.speech_volume); + } + + if (speechmp3 != nullptr) { + if (!speechmp3->play()) { + // not assigned to a channel, so clean up manually. + speechmp3->destroy(); + delete speechmp3; + speechmp3 = nullptr; + } + } + + if (speechmp3 == nullptr) { + debug_script_warn("Speech load failure: '%s'", voice_name.GetCStr()); + return false; + } + + set_clip_to_channel(SCHAN_SPEECH, speechmp3); + return true; } // Play voice-over clip and adjust audio volumes; // voice_name should be bare clip name without extension -static bool play_voice_clip_impl(const String &voice_name, bool as_speech, bool is_blocking) -{ - if (!play_voice_clip_on_channel(voice_name)) - return false; - if (!as_speech) - return true; - - play.speech_has_voice = true; - play.speech_voice_blocking = is_blocking; - - cancel_scheduled_music_update(); - play.music_vol_was = play.music_master_volume; - // Negative value means set exactly; positive means drop that amount - if (play.speech_music_drop < 0) - play.music_master_volume = -play.speech_music_drop; - else - play.music_master_volume -= play.speech_music_drop; - apply_volume_drop_modifier(true); - update_music_volume(); - update_ambient_sound_vol(); - return true; +static bool play_voice_clip_impl(const String &voice_name, bool as_speech, bool is_blocking) { + if (!play_voice_clip_on_channel(voice_name)) + return false; + if (!as_speech) + return true; + + play.speech_has_voice = true; + play.speech_voice_blocking = is_blocking; + + cancel_scheduled_music_update(); + play.music_vol_was = play.music_master_volume; + // Negative value means set exactly; positive means drop that amount + if (play.speech_music_drop < 0) + play.music_master_volume = -play.speech_music_drop; + else + play.music_master_volume -= play.speech_music_drop; + apply_volume_drop_modifier(true); + update_music_volume(); + update_ambient_sound_vol(); + return true; } // Stop voice-over clip and schedule audio volume reset -static void stop_voice_clip_impl() -{ - play.music_master_volume = play.music_vol_was; - // update the music in a bit (fixes two speeches follow each other - // and music going up-then-down) - schedule_music_update_at(AGS_Clock::now() + std::chrono::milliseconds(500)); - stop_and_destroy_channel(SCHAN_SPEECH); -} - -bool play_voice_speech(int charid, int sndid) -{ - // don't play speech if we're skipping a cutscene - if (!play.ShouldPlayVoiceSpeech()) - return false; - - String voice_file = get_cue_filename(charid, sndid); - if (!play_voice_clip_impl(voice_file, true, true)) - return false; - - int ii; // Compare the base file name to the .pam file name - curLipLine = -1; // See if we have voice lip sync for this line - curLipLinePhoneme = -1; - for (ii = 0; ii < numLipLines; ii++) { - if (ags_stricmp(splipsync[ii].filename, voice_file) == 0) { - curLipLine = ii; - break; - } - } - // if the lip-sync is being used for voice sync, disable - // the text-related lipsync - if (numLipLines > 0) - game.options[OPT_LIPSYNCTEXT] = 0; - - // change Sierra w/bgrnd to Sierra without background when voice - // is available (for Tierra) - if ((game.options[OPT_SPEECHTYPE] == 2) && (play.no_textbg_when_voice > 0)) { - game.options[OPT_SPEECHTYPE] = 1; - play.no_textbg_when_voice = 2; - } - return true; -} - -bool play_voice_nonblocking(int charid, int sndid, bool as_speech) -{ - // don't play voice if we're skipping a cutscene - if (!play.ShouldPlayVoiceSpeech()) - return false; - // don't play voice if there's a blocking speech with voice-over already - if (play.IsBlockingVoiceSpeech()) - return false; - - String voice_file = get_cue_filename(charid, sndid); - return play_voice_clip_impl(voice_file, as_speech, false); -} - -void stop_voice_speech() -{ - if (!play.speech_has_voice) - return; - - stop_voice_clip_impl(); - - // Reset lipsync - curLipLine = -1; - // Set back to Sierra w/bgrnd - if (play.no_textbg_when_voice == 2) - { - play.no_textbg_when_voice = 1; - game.options[OPT_SPEECHTYPE] = 2; - } - play.speech_has_voice = false; - play.speech_voice_blocking = false; -} - -void stop_voice_nonblocking() -{ - if (!play.speech_has_voice) - return; - stop_voice_clip_impl(); - // Only reset speech flags if we are truly playing a non-blocking voice; - // otherwise we might be inside blocking speech function and should let - // it keep these flags to be able to finalize properly. - // This is an imperfection of current speech implementation. - if (!play.speech_voice_blocking) - { - play.speech_has_voice = false; - play.speech_voice_blocking = false; - } +static void stop_voice_clip_impl() { + play.music_master_volume = play.music_vol_was; + // update the music in a bit (fixes two speeches follow each other + // and music going up-then-down) + schedule_music_update_at(AGS_Clock::now() + std::chrono::milliseconds(500)); + stop_and_destroy_channel(SCHAN_SPEECH); +} + +bool play_voice_speech(int charid, int sndid) { + // don't play speech if we're skipping a cutscene + if (!play.ShouldPlayVoiceSpeech()) + return false; + + String voice_file = get_cue_filename(charid, sndid); + if (!play_voice_clip_impl(voice_file, true, true)) + return false; + + int ii; // Compare the base file name to the .pam file name + curLipLine = -1; // See if we have voice lip sync for this line + curLipLinePhoneme = -1; + for (ii = 0; ii < numLipLines; ii++) { + if (ags_stricmp(splipsync[ii].filename, voice_file) == 0) { + curLipLine = ii; + break; + } + } + // if the lip-sync is being used for voice sync, disable + // the text-related lipsync + if (numLipLines > 0) + game.options[OPT_LIPSYNCTEXT] = 0; + + // change Sierra w/bgrnd to Sierra without background when voice + // is available (for Tierra) + if ((game.options[OPT_SPEECHTYPE] == 2) && (play.no_textbg_when_voice > 0)) { + game.options[OPT_SPEECHTYPE] = 1; + play.no_textbg_when_voice = 2; + } + return true; +} + +bool play_voice_nonblocking(int charid, int sndid, bool as_speech) { + // don't play voice if we're skipping a cutscene + if (!play.ShouldPlayVoiceSpeech()) + return false; + // don't play voice if there's a blocking speech with voice-over already + if (play.IsBlockingVoiceSpeech()) + return false; + + String voice_file = get_cue_filename(charid, sndid); + return play_voice_clip_impl(voice_file, as_speech, false); +} + +void stop_voice_speech() { + if (!play.speech_has_voice) + return; + + stop_voice_clip_impl(); + + // Reset lipsync + curLipLine = -1; + // Set back to Sierra w/bgrnd + if (play.no_textbg_when_voice == 2) { + play.no_textbg_when_voice = 1; + game.options[OPT_SPEECHTYPE] = 2; + } + play.speech_has_voice = false; + play.speech_voice_blocking = false; +} + +void stop_voice_nonblocking() { + if (!play.speech_has_voice) + return; + stop_voice_clip_impl(); + // Only reset speech flags if we are truly playing a non-blocking voice; + // otherwise we might be inside blocking speech function and should let + // it keep these flags to be able to finalize properly. + // This is an imperfection of current speech implementation. + if (!play.speech_voice_blocking) { + play.speech_has_voice = false; + play.speech_voice_blocking = false; + } } diff --git a/engines/ags/engine/ac/global_audio.h b/engines/ags/engine/ac/global_audio.h index 0f6a7f61bddc..d30be09dbecd 100644 --- a/engines/ags/engine/ac/global_audio.h +++ b/engines/ags/engine/ac/global_audio.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBALAUDIO_H #define AGS_ENGINE_AC_GLOBALAUDIO_H -void StopAmbientSound (int channel); -void PlayAmbientSound (int channel, int sndnum, int vol, int x, int y); +void StopAmbientSound(int channel); +void PlayAmbientSound(int channel, int sndnum, int vol, int x, int y); int IsChannelPlaying(int chan); int IsSoundPlaying(); // returns -1 on failure, channel number on success @@ -32,29 +32,29 @@ int PlaySoundEx(int val1, int channel); void StopAllSounds(int evenAmbient); void PlayMusicResetQueue(int newmus); -void SeekMIDIPosition (int position); -int GetMIDIPosition (); +void SeekMIDIPosition(int position); +int GetMIDIPosition(); int IsMusicPlaying(); int PlayMusicQueued(int musnum); void scr_StopMusic(); void SeekMODPattern(int patnum); -void SeekMP3PosMillis (int posn); -int GetMP3PosMillis (); +void SeekMP3PosMillis(int posn); +int GetMP3PosMillis(); void SetMusicVolume(int newvol); void SetMusicMasterVolume(int newvol); void SetSoundVolume(int newvol); void SetChannelVolume(int chan, int newvol); -void SetDigitalMasterVolume (int newvol); +void SetDigitalMasterVolume(int newvol); int GetCurrentMusic(); void SetMusicRepeat(int loopflag); -void PlayMP3File (const char *filename); -void PlaySilentMIDI (int mnum); +void PlayMP3File(const char *filename); +void PlaySilentMIDI(int mnum); void SetSpeechVolume(int newvol); -void SetVoiceMode (int newmod); -int GetVoiceMode (); +void SetVoiceMode(int newmod); +int GetVoiceMode(); int IsVoxAvailable(); -int IsMusicVoxAvailable (); +int IsMusicVoxAvailable(); struct CharacterInfo; struct ScriptAudioChannel; diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp index e122ad6201ee..26a46dad6257 100644 --- a/engines/ags/engine/ac/global_button.cpp +++ b/engines/ags/engine/ac/global_button.cpp @@ -32,76 +32,71 @@ using namespace AGS::Common; extern GameSetupStruct game; -void SetButtonText(int guin,int objn, const char*newtx) { - VALIDATE_STRING(newtx); - if ((guin<0) | (guin>=game.numgui)) - quit("!SetButtonText: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) - quit("!SetButtonText: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUIButton) - quit("!SetButtonText: specified control is not a button"); +void SetButtonText(int guin, int objn, const char *newtx) { + VALIDATE_STRING(newtx); + if ((guin < 0) | (guin >= game.numgui)) + quit("!SetButtonText: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) + quit("!SetButtonText: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUIButton) + quit("!SetButtonText: specified control is not a button"); - GUIButton*guil=(GUIButton*)guis[guin].GetControl(objn); - Button_SetText(guil, newtx); + GUIButton *guil = (GUIButton *)guis[guin].GetControl(objn); + Button_SetText(guil, newtx); } void AnimateButton(int guin, int objn, int view, int loop, int speed, int repeat) { - if ((guin<0) | (guin>=game.numgui)) quit("!AnimateButton: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!AnimateButton: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUIButton) - quit("!AnimateButton: specified control is not a button"); + if ((guin < 0) | (guin >= game.numgui)) quit("!AnimateButton: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!AnimateButton: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUIButton) + quit("!AnimateButton: specified control is not a button"); - Button_Animate((GUIButton*)guis[guin].GetControl(objn), view, loop, speed, repeat); + Button_Animate((GUIButton *)guis[guin].GetControl(objn), view, loop, speed, repeat); } int GetButtonPic(int guin, int objn, int ptype) { - if ((guin<0) | (guin>=game.numgui)) quit("!GetButtonPic: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!GetButtonPic: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUIButton) - quit("!GetButtonPic: specified control is not a button"); - if ((ptype < 0) | (ptype > 3)) quit("!GetButtonPic: invalid pic type"); + if ((guin < 0) | (guin >= game.numgui)) quit("!GetButtonPic: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!GetButtonPic: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUIButton) + quit("!GetButtonPic: specified control is not a button"); + if ((ptype < 0) | (ptype > 3)) quit("!GetButtonPic: invalid pic type"); - GUIButton*guil=(GUIButton*)guis[guin].GetControl(objn); + GUIButton *guil = (GUIButton *)guis[guin].GetControl(objn); - if (ptype == 0) { - // currently displayed pic - if (guil->CurrentImage < 0) - return guil->Image; - return guil->CurrentImage; - } - else if (ptype==1) { - // nomal pic - return guil->Image; - } - else if (ptype==2) { - // mouseover pic - return guil->MouseOverImage; - } - else { // pushed pic - return guil->PushedImage; - } + if (ptype == 0) { + // currently displayed pic + if (guil->CurrentImage < 0) + return guil->Image; + return guil->CurrentImage; + } else if (ptype == 1) { + // nomal pic + return guil->Image; + } else if (ptype == 2) { + // mouseover pic + return guil->MouseOverImage; + } else { // pushed pic + return guil->PushedImage; + } - quit("internal error in getbuttonpic"); + quit("internal error in getbuttonpic"); } -void SetButtonPic(int guin,int objn,int ptype,int slotn) { - if ((guin<0) | (guin>=game.numgui)) quit("!SetButtonPic: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetButtonPic: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUIButton) - quit("!SetButtonPic: specified control is not a button"); - if ((ptype<1) | (ptype>3)) quit("!SetButtonPic: invalid pic type"); +void SetButtonPic(int guin, int objn, int ptype, int slotn) { + if ((guin < 0) | (guin >= game.numgui)) quit("!SetButtonPic: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetButtonPic: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUIButton) + quit("!SetButtonPic: specified control is not a button"); + if ((ptype < 1) | (ptype > 3)) quit("!SetButtonPic: invalid pic type"); - GUIButton*guil=(GUIButton*)guis[guin].GetControl(objn); - if (ptype==1) { - Button_SetNormalGraphic(guil, slotn); - } - else if (ptype==2) { - // mouseover pic - Button_SetMouseOverGraphic(guil, slotn); - } - else { // pushed pic - Button_SetPushedGraphic(guil, slotn); - } + GUIButton *guil = (GUIButton *)guis[guin].GetControl(objn); + if (ptype == 1) { + Button_SetNormalGraphic(guil, slotn); + } else if (ptype == 2) { + // mouseover pic + Button_SetMouseOverGraphic(guil, slotn); + } else { // pushed pic + Button_SetPushedGraphic(guil, slotn); + } } diff --git a/engines/ags/engine/ac/global_button.h b/engines/ags/engine/ac/global_button.h index 518e73c63f4e..ee7fb5dbb4e3 100644 --- a/engines/ags/engine/ac/global_button.h +++ b/engines/ags/engine/ac/global_button.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_AC_GLOBALBUTTON_H #define AGS_ENGINE_AC_GLOBALBUTTON_H -void SetButtonText(int guin,int objn, const char*newtx); +void SetButtonText(int guin, int objn, const char *newtx); void AnimateButton(int guin, int objn, int view, int loop, int speed, int repeat); int GetButtonPic(int guin, int objn, int ptype); -void SetButtonPic(int guin,int objn,int ptype,int slotn); +void SetButtonPic(int guin, int objn, int ptype, int slotn); #endif diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp index 6788617f2bd0..874aa92d24cd 100644 --- a/engines/ags/engine/ac/global_character.cpp +++ b/engines/ags/engine/ac/global_character.cpp @@ -51,8 +51,8 @@ using namespace AGS::Common; extern GameSetupStruct game; -extern ViewStruct*views; -extern RoomObject*objs; +extern ViewStruct *views; +extern RoomObject *objs; extern RoomStruct thisroom; extern GameState play; extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; @@ -60,517 +60,505 @@ extern ScriptInvItem scrInv[MAX_INV]; // defined in character unit extern CharacterExtras *charextra; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern int32_t _sc_PlayerCharPtr; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; void StopMoving(int chaa) { - Character_StopMoving(&game.chars[chaa]); + Character_StopMoving(&game.chars[chaa]); } void ReleaseCharacterView(int chat) { - if (!is_valid_character(chat)) - quit("!ReleaseCahracterView: invalid character supplied"); + if (!is_valid_character(chat)) + quit("!ReleaseCahracterView: invalid character supplied"); - Character_UnlockView(&game.chars[chat]); + Character_UnlockView(&game.chars[chat]); } void MoveToWalkableArea(int charid) { - if (!is_valid_character(charid)) - quit("!MoveToWalkableArea: invalid character specified"); + if (!is_valid_character(charid)) + quit("!MoveToWalkableArea: invalid character specified"); - Character_PlaceOnWalkableArea(&game.chars[charid]); + Character_PlaceOnWalkableArea(&game.chars[charid]); } void FaceLocation(int cha, int xx, int yy) { - if (!is_valid_character(cha)) - quit("!FaceLocation: Invalid character specified"); + if (!is_valid_character(cha)) + quit("!FaceLocation: Invalid character specified"); - Character_FaceLocation(&game.chars[cha], xx, yy, BLOCKING); + Character_FaceLocation(&game.chars[cha], xx, yy, BLOCKING); } -void FaceCharacter(int cha,int toface) { - if (!is_valid_character(cha)) - quit("!FaceCharacter: Invalid character specified"); - if (!is_valid_character(toface)) - quit("!FaceCharacter: invalid character specified"); +void FaceCharacter(int cha, int toface) { + if (!is_valid_character(cha)) + quit("!FaceCharacter: Invalid character specified"); + if (!is_valid_character(toface)) + quit("!FaceCharacter: invalid character specified"); - Character_FaceCharacter(&game.chars[cha], &game.chars[toface], BLOCKING); + Character_FaceCharacter(&game.chars[cha], &game.chars[toface], BLOCKING); } void SetCharacterIdle(int who, int iview, int itime) { - if (!is_valid_character(who)) - quit("!SetCharacterIdle: Invalid character specified"); + if (!is_valid_character(who)) + quit("!SetCharacterIdle: Invalid character specified"); - Character_SetIdleView(&game.chars[who], iview, itime); + Character_SetIdleView(&game.chars[who], iview, itime); } int GetCharacterWidth(int ww) { - CharacterInfo *char1 = &game.chars[ww]; + CharacterInfo *char1 = &game.chars[ww]; - if (charextra[ww].width < 1) - { - if ((char1->view < 0) || - (char1->loop >= views[char1->view].numLoops) || - (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) - { - debug_script_warn("GetCharacterWidth: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); - return data_to_game_coord(4); - } + if (charextra[ww].width < 1) { + if ((char1->view < 0) || + (char1->loop >= views[char1->view].numLoops) || + (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) { + debug_script_warn("GetCharacterWidth: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); + return data_to_game_coord(4); + } - return game.SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Width; - } - else - return charextra[ww].width; + return game.SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Width; + } else + return charextra[ww].width; } int GetCharacterHeight(int charid) { - CharacterInfo *char1 = &game.chars[charid]; + CharacterInfo *char1 = &game.chars[charid]; - if (charextra[charid].height < 1) - { - if ((char1->view < 0) || - (char1->loop >= views[char1->view].numLoops) || - (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) - { - debug_script_warn("GetCharacterHeight: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); - return data_to_game_coord(2); - } + if (charextra[charid].height < 1) { + if ((char1->view < 0) || + (char1->loop >= views[char1->view].numLoops) || + (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) { + debug_script_warn("GetCharacterHeight: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); + return data_to_game_coord(2); + } - return game.SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Height; - } - else - return charextra[charid].height; + return game.SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Height; + } else + return charextra[charid].height; } -void SetCharacterBaseline (int obn, int basel) { - if (!is_valid_character(obn)) quit("!SetCharacterBaseline: invalid object number specified"); +void SetCharacterBaseline(int obn, int basel) { + if (!is_valid_character(obn)) quit("!SetCharacterBaseline: invalid object number specified"); - Character_SetBaseline(&game.chars[obn], basel); + Character_SetBaseline(&game.chars[obn], basel); } // pass trans=0 for fully solid, trans=100 for fully transparent -void SetCharacterTransparency(int obn,int trans) { - if (!is_valid_character(obn)) - quit("!SetCharTransparent: invalid character number specified"); +void SetCharacterTransparency(int obn, int trans) { + if (!is_valid_character(obn)) + quit("!SetCharTransparent: invalid character number specified"); - Character_SetTransparency(&game.chars[obn], trans); + Character_SetTransparency(&game.chars[obn], trans); } -void scAnimateCharacter (int chh, int loopn, int sppd, int rept) { - if (!is_valid_character(chh)) - quit("AnimateCharacter: invalid character"); +void scAnimateCharacter(int chh, int loopn, int sppd, int rept) { + if (!is_valid_character(chh)) + quit("AnimateCharacter: invalid character"); - animate_character(&game.chars[chh], loopn, sppd, rept); + animate_character(&game.chars[chh], loopn, sppd, rept); } void AnimateCharacterEx(int chh, int loopn, int sppd, int rept, int direction, int blocking) { - if ((direction < 0) || (direction > 1)) - quit("!AnimateCharacterEx: invalid direction"); - if (!is_valid_character(chh)) - quit("AnimateCharacter: invalid character"); + if ((direction < 0) || (direction > 1)) + quit("!AnimateCharacterEx: invalid direction"); + if (!is_valid_character(chh)) + quit("AnimateCharacter: invalid character"); - if (direction) - direction = BACKWARDS; - else - direction = FORWARDS; + if (direction) + direction = BACKWARDS; + else + direction = FORWARDS; - if (blocking) - blocking = BLOCKING; - else - blocking = IN_BACKGROUND; + if (blocking) + blocking = BLOCKING; + else + blocking = IN_BACKGROUND; - Character_Animate(&game.chars[chh], loopn, sppd, rept, blocking, direction); + Character_Animate(&game.chars[chh], loopn, sppd, rept, blocking, direction); } void SetPlayerCharacter(int newchar) { - if (!is_valid_character(newchar)) - quit("!SetPlayerCharacter: Invalid character specified"); + if (!is_valid_character(newchar)) + quit("!SetPlayerCharacter: Invalid character specified"); - Character_SetAsPlayer(&game.chars[newchar]); + Character_SetAsPlayer(&game.chars[newchar]); } void FollowCharacterEx(int who, int tofollow, int distaway, int eagerness) { - if (!is_valid_character(who)) - quit("!FollowCharacter: Invalid character specified"); - CharacterInfo *chtofollow = nullptr; - if (tofollow != -1) - { - if (!is_valid_character(tofollow)) - quit("!FollowCharacterEx: invalid character to follow"); - else - chtofollow = &game.chars[tofollow]; - } + if (!is_valid_character(who)) + quit("!FollowCharacter: Invalid character specified"); + CharacterInfo *chtofollow = nullptr; + if (tofollow != -1) { + if (!is_valid_character(tofollow)) + quit("!FollowCharacterEx: invalid character to follow"); + else + chtofollow = &game.chars[tofollow]; + } - Character_FollowCharacter(&game.chars[who], chtofollow, distaway, eagerness); + Character_FollowCharacter(&game.chars[who], chtofollow, distaway, eagerness); } void FollowCharacter(int who, int tofollow) { - FollowCharacterEx(who,tofollow,10,97); + FollowCharacterEx(who, tofollow, 10, 97); } -void SetCharacterIgnoreLight (int who, int yesorno) { - if (!is_valid_character(who)) - quit("!SetCharacterIgnoreLight: Invalid character specified"); +void SetCharacterIgnoreLight(int who, int yesorno) { + if (!is_valid_character(who)) + quit("!SetCharacterIgnoreLight: Invalid character specified"); - Character_SetIgnoreLighting(&game.chars[who], yesorno); + Character_SetIgnoreLighting(&game.chars[who], yesorno); } -void MoveCharacter(int cc,int xx,int yy) { - walk_character(cc,xx,yy,0, true); +void MoveCharacter(int cc, int xx, int yy) { + walk_character(cc, xx, yy, 0, true); } -void MoveCharacterDirect(int cc,int xx, int yy) { - walk_character(cc,xx,yy,1, true); +void MoveCharacterDirect(int cc, int xx, int yy) { + walk_character(cc, xx, yy, 1, true); } -void MoveCharacterStraight(int cc,int xx, int yy) { - if (!is_valid_character(cc)) - quit("!MoveCharacterStraight: invalid character specified"); +void MoveCharacterStraight(int cc, int xx, int yy) { + if (!is_valid_character(cc)) + quit("!MoveCharacterStraight: invalid character specified"); - Character_WalkStraight(&game.chars[cc], xx, yy, IN_BACKGROUND); + Character_WalkStraight(&game.chars[cc], xx, yy, IN_BACKGROUND); } // Append to character path -void MoveCharacterPath (int chac, int tox, int toy) { - if (!is_valid_character(chac)) - quit("!MoveCharacterPath: invalid character specified"); +void MoveCharacterPath(int chac, int tox, int toy) { + if (!is_valid_character(chac)) + quit("!MoveCharacterPath: invalid character specified"); - Character_AddWaypoint(&game.chars[chac], tox, toy); + Character_AddWaypoint(&game.chars[chac], tox, toy); } int GetPlayerCharacter() { - return game.playercharacter; + return game.playercharacter; } void SetCharacterSpeedEx(int chaa, int xspeed, int yspeed) { - if (!is_valid_character(chaa)) - quit("!SetCharacterSpeedEx: invalid character"); + if (!is_valid_character(chaa)) + quit("!SetCharacterSpeedEx: invalid character"); - Character_SetSpeed(&game.chars[chaa], xspeed, yspeed); + Character_SetSpeed(&game.chars[chaa], xspeed, yspeed); } -void SetCharacterSpeed(int chaa,int nspeed) { - SetCharacterSpeedEx(chaa, nspeed, nspeed); +void SetCharacterSpeed(int chaa, int nspeed) { + SetCharacterSpeedEx(chaa, nspeed, nspeed); } -void SetTalkingColor(int chaa,int ncol) { - if (!is_valid_character(chaa)) quit("!SetTalkingColor: invalid character"); +void SetTalkingColor(int chaa, int ncol) { + if (!is_valid_character(chaa)) quit("!SetTalkingColor: invalid character"); - Character_SetSpeechColor(&game.chars[chaa], ncol); + Character_SetSpeechColor(&game.chars[chaa], ncol); } -void SetCharacterSpeechView (int chaa, int vii) { - if (!is_valid_character(chaa)) - quit("!SetCharacterSpeechView: invalid character specified"); +void SetCharacterSpeechView(int chaa, int vii) { + if (!is_valid_character(chaa)) + quit("!SetCharacterSpeechView: invalid character specified"); - Character_SetSpeechView(&game.chars[chaa], vii); + Character_SetSpeechView(&game.chars[chaa], vii); } -void SetCharacterBlinkView (int chaa, int vii, int intrv) { - if (!is_valid_character(chaa)) - quit("!SetCharacterBlinkView: invalid character specified"); +void SetCharacterBlinkView(int chaa, int vii, int intrv) { + if (!is_valid_character(chaa)) + quit("!SetCharacterBlinkView: invalid character specified"); - Character_SetBlinkView(&game.chars[chaa], vii); - Character_SetBlinkInterval(&game.chars[chaa], intrv); + Character_SetBlinkView(&game.chars[chaa], vii); + Character_SetBlinkInterval(&game.chars[chaa], intrv); } -void SetCharacterView(int chaa,int vii) { - if (!is_valid_character(chaa)) - quit("!SetCharacterView: invalid character specified"); +void SetCharacterView(int chaa, int vii) { + if (!is_valid_character(chaa)) + quit("!SetCharacterView: invalid character specified"); - Character_LockView(&game.chars[chaa], vii); + Character_LockView(&game.chars[chaa], vii); } void SetCharacterFrame(int chaa, int view, int loop, int frame) { - Character_LockViewFrame(&game.chars[chaa], view, loop, frame); + Character_LockViewFrame(&game.chars[chaa], view, loop, frame); } // similar to SetCharView, but aligns the frame to make it line up -void SetCharacterViewEx (int chaa, int vii, int loop, int align) { +void SetCharacterViewEx(int chaa, int vii, int loop, int align) { - Character_LockViewAligned(&game.chars[chaa], vii, loop, align); + Character_LockViewAligned(&game.chars[chaa], vii, loop, align); } -void SetCharacterViewOffset (int chaa, int vii, int xoffs, int yoffs) { +void SetCharacterViewOffset(int chaa, int vii, int xoffs, int yoffs) { - Character_LockViewOffset(&game.chars[chaa], vii, xoffs, yoffs); + Character_LockViewOffset(&game.chars[chaa], vii, xoffs, yoffs); } -void ChangeCharacterView(int chaa,int vii) { - if (!is_valid_character(chaa)) - quit("!ChangeCharacterView: invalid character specified"); +void ChangeCharacterView(int chaa, int vii) { + if (!is_valid_character(chaa)) + quit("!ChangeCharacterView: invalid character specified"); - Character_ChangeView(&game.chars[chaa], vii); + Character_ChangeView(&game.chars[chaa], vii); } -void SetCharacterClickable (int cha, int clik) { - if (!is_valid_character(cha)) - quit("!SetCharacterClickable: Invalid character specified"); - // make the character clicklabe (reset "No interaction" bit) - game.chars[cha].flags&=~CHF_NOINTERACT; - // if they don't want it clickable, set the relevant bit - if (clik == 0) - game.chars[cha].flags|=CHF_NOINTERACT; +void SetCharacterClickable(int cha, int clik) { + if (!is_valid_character(cha)) + quit("!SetCharacterClickable: Invalid character specified"); + // make the character clicklabe (reset "No interaction" bit) + game.chars[cha].flags &= ~CHF_NOINTERACT; + // if they don't want it clickable, set the relevant bit + if (clik == 0) + game.chars[cha].flags |= CHF_NOINTERACT; } -void SetCharacterIgnoreWalkbehinds (int cha, int clik) { - if (!is_valid_character(cha)) - quit("!SetCharacterIgnoreWalkbehinds: Invalid character specified"); +void SetCharacterIgnoreWalkbehinds(int cha, int clik) { + if (!is_valid_character(cha)) + quit("!SetCharacterIgnoreWalkbehinds: Invalid character specified"); - Character_SetIgnoreWalkbehinds(&game.chars[cha], clik); + Character_SetIgnoreWalkbehinds(&game.chars[cha], clik); } -void MoveCharacterToObject(int chaa,int obbj) { - // invalid object, do nothing - // this allows MoveCharacterToObject(EGO, GetObjectAt(...)); - if (!is_valid_object(obbj)) - return; +void MoveCharacterToObject(int chaa, int obbj) { + // invalid object, do nothing + // this allows MoveCharacterToObject(EGO, GetObjectAt(...)); + if (!is_valid_object(obbj)) + return; - walk_character(chaa,objs[obbj].x+5,objs[obbj].y+6,0, true); + walk_character(chaa, objs[obbj].x + 5, objs[obbj].y + 6, 0, true); - GameLoopUntilNotMoving(&game.chars[chaa].walking); + GameLoopUntilNotMoving(&game.chars[chaa].walking); } -void MoveCharacterToHotspot(int chaa,int hotsp) { - if ((hotsp<0) || (hotsp>=MAX_ROOM_HOTSPOTS)) - quit("!MovecharacterToHotspot: invalid hotspot"); - if (thisroom.Hotspots[hotsp].WalkTo.X<1) return; - walk_character(chaa,thisroom.Hotspots[hotsp].WalkTo.X,thisroom.Hotspots[hotsp].WalkTo.Y,0, true); +void MoveCharacterToHotspot(int chaa, int hotsp) { + if ((hotsp < 0) || (hotsp >= MAX_ROOM_HOTSPOTS)) + quit("!MovecharacterToHotspot: invalid hotspot"); + if (thisroom.Hotspots[hotsp].WalkTo.X < 1) return; + walk_character(chaa, thisroom.Hotspots[hotsp].WalkTo.X, thisroom.Hotspots[hotsp].WalkTo.Y, 0, true); - GameLoopUntilNotMoving(&game.chars[chaa].walking); + GameLoopUntilNotMoving(&game.chars[chaa].walking); } -void MoveCharacterBlocking(int chaa,int xx,int yy,int direct) { - if (!is_valid_character (chaa)) - quit("!MoveCharacterBlocking: invalid character"); +void MoveCharacterBlocking(int chaa, int xx, int yy, int direct) { + if (!is_valid_character(chaa)) + quit("!MoveCharacterBlocking: invalid character"); - // check if they try to move the player when Hide Player Char is - // ticked -- otherwise this will hang the game - if (game.chars[chaa].on != 1) - { - debug_script_warn("MoveCharacterBlocking: character is turned off (is Hide Player Character selected?) and cannot be moved"); - return; - } + // check if they try to move the player when Hide Player Char is + // ticked -- otherwise this will hang the game + if (game.chars[chaa].on != 1) { + debug_script_warn("MoveCharacterBlocking: character is turned off (is Hide Player Character selected?) and cannot be moved"); + return; + } - if (direct) - MoveCharacterDirect(chaa,xx,yy); - else - MoveCharacter(chaa,xx,yy); + if (direct) + MoveCharacterDirect(chaa, xx, yy); + else + MoveCharacter(chaa, xx, yy); - GameLoopUntilNotMoving(&game.chars[chaa].walking); + GameLoopUntilNotMoving(&game.chars[chaa].walking); } -int GetCharacterSpeechAnimationDelay(CharacterInfo *cha) -{ - if ((loaded_game_file_version < kGameVersion_312) && (game.options[OPT_SPEECHTYPE] != 0)) - { +int GetCharacterSpeechAnimationDelay(CharacterInfo *cha) { + if ((loaded_game_file_version < kGameVersion_312) && (game.options[OPT_SPEECHTYPE] != 0)) { // legacy versions of AGS assigned a fixed delay to Sierra-style speech only return 5; } if (game.options[OPT_GLOBALTALKANIMSPD] != 0) return play.talkanim_speed; - else - return cha->speech_anim_speed; -} - -void RunCharacterInteraction (int cc, int mood) { - if (!is_valid_character(cc)) - quit("!RunCharacterInteraction: invalid character"); - - int passon=-1,cdata=-1; - if (mood==MODE_LOOK) passon=0; - else if (mood==MODE_HAND) passon=1; - else if (mood==MODE_TALK) passon=2; - else if (mood==MODE_USE) { passon=3; - cdata=playerchar->activeinv; - play.usedinv=cdata; - } - else if (mood==MODE_PICKUP) passon = 5; - else if (mood==MODE_CUSTOM1) passon = 6; - else if (mood==MODE_CUSTOM2) passon = 7; - - evblockbasename="character%d"; evblocknum=cc; - if (loaded_game_file_version > kGameVersion_272) - { - if (passon>=0) - run_interaction_script(game.charScripts[cc].get(), passon, 4, (passon == 3)); - run_interaction_script(game.charScripts[cc].get(), 4); // any click on char - } - else - { - if (passon>=0) - run_interaction_event(game.intrChar[cc].get(),passon, 4, (passon == 3)); - run_interaction_event(game.intrChar[cc].get(),4); // any click on char - } + else + return cha->speech_anim_speed; +} + +void RunCharacterInteraction(int cc, int mood) { + if (!is_valid_character(cc)) + quit("!RunCharacterInteraction: invalid character"); + + int passon = -1, cdata = -1; + if (mood == MODE_LOOK) passon = 0; + else if (mood == MODE_HAND) passon = 1; + else if (mood == MODE_TALK) passon = 2; + else if (mood == MODE_USE) { + passon = 3; + cdata = playerchar->activeinv; + play.usedinv = cdata; + } else if (mood == MODE_PICKUP) passon = 5; + else if (mood == MODE_CUSTOM1) passon = 6; + else if (mood == MODE_CUSTOM2) passon = 7; + + evblockbasename = "character%d"; + evblocknum = cc; + if (loaded_game_file_version > kGameVersion_272) { + if (passon >= 0) + run_interaction_script(game.charScripts[cc].get(), passon, 4, (passon == 3)); + run_interaction_script(game.charScripts[cc].get(), 4); // any click on char + } else { + if (passon >= 0) + run_interaction_event(game.intrChar[cc].get(), passon, 4, (passon == 3)); + run_interaction_event(game.intrChar[cc].get(), 4); // any click on char + } } -int AreCharObjColliding(int charid,int objid) { - if (!is_valid_character(charid)) - quit("!AreCharObjColliding: invalid character"); - if (!is_valid_object(objid)) - quit("!AreCharObjColliding: invalid object number"); +int AreCharObjColliding(int charid, int objid) { + if (!is_valid_character(charid)) + quit("!AreCharObjColliding: invalid character"); + if (!is_valid_object(objid)) + quit("!AreCharObjColliding: invalid object number"); - return Character_IsCollidingWithObject(&game.chars[charid], &scrObj[objid]); + return Character_IsCollidingWithObject(&game.chars[charid], &scrObj[objid]); } -int AreCharactersColliding(int cchar1,int cchar2) { - if (!is_valid_character(cchar1)) - quit("!AreCharactersColliding: invalid char1"); - if (!is_valid_character(cchar2)) - quit("!AreCharactersColliding: invalid char2"); +int AreCharactersColliding(int cchar1, int cchar2) { + if (!is_valid_character(cchar1)) + quit("!AreCharactersColliding: invalid char1"); + if (!is_valid_character(cchar2)) + quit("!AreCharactersColliding: invalid char2"); - return Character_IsCollidingWithChar(&game.chars[cchar1], &game.chars[cchar2]); + return Character_IsCollidingWithChar(&game.chars[cchar1], &game.chars[cchar2]); } -int GetCharacterProperty (int cha, const char *property) { - if (!is_valid_character(cha)) - quit("!GetCharacterProperty: invalid character"); - return get_int_property (game.charProps[cha], play.charProps[cha], property); +int GetCharacterProperty(int cha, const char *property) { + if (!is_valid_character(cha)) + quit("!GetCharacterProperty: invalid character"); + return get_int_property(game.charProps[cha], play.charProps[cha], property); } -void SetCharacterProperty (int who, int flag, int yesorno) { - if (!is_valid_character(who)) - quit("!SetCharacterProperty: Invalid character specified"); +void SetCharacterProperty(int who, int flag, int yesorno) { + if (!is_valid_character(who)) + quit("!SetCharacterProperty: Invalid character specified"); - Character_SetOption(&game.chars[who], flag, yesorno); + Character_SetOption(&game.chars[who], flag, yesorno); } -void GetCharacterPropertyText (int item, const char *property, char *bufer) { - get_text_property (game.charProps[item], play.charProps[item], property, bufer); +void GetCharacterPropertyText(int item, const char *property, char *bufer) { + get_text_property(game.charProps[item], play.charProps[item], property, bufer); } int GetCharIDAtScreen(int xx, int yy) { - VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); - if (vpt.second < 0) - return -1; - return is_pos_on_character(vpt.first.X, vpt.first.Y); + VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); + if (vpt.second < 0) + return -1; + return is_pos_on_character(vpt.first.X, vpt.first.Y); } void SetActiveInventory(int iit) { - ScriptInvItem *tosend = nullptr; - if ((iit > 0) && (iit < game.numinvitems)) - tosend = &scrInv[iit]; - else if (iit != -1) - quitprintf("!SetActiveInventory: invalid inventory number %d", iit); + ScriptInvItem *tosend = nullptr; + if ((iit > 0) && (iit < game.numinvitems)) + tosend = &scrInv[iit]; + else if (iit != -1) + quitprintf("!SetActiveInventory: invalid inventory number %d", iit); - Character_SetActiveInventory(playerchar, tosend); + Character_SetActiveInventory(playerchar, tosend); } void update_invorder() { - for (int cc = 0; cc < game.numcharacters; cc++) { - charextra[cc].invorder_count = 0; - int ff, howmany; - // Iterate through all inv items, adding them once (or multiple - // times if requested) to the list. - for (ff=0;ff < game.numinvitems;ff++) { - howmany = game.chars[cc].inv[ff]; - if ((game.options[OPT_DUPLICATEINV] == 0) && (howmany > 1)) - howmany = 1; - - for (int ts = 0; ts < howmany; ts++) { - if (charextra[cc].invorder_count >= MAX_INVORDER) - quit("!Too many inventory items to display: 500 max"); - - charextra[cc].invorder[charextra[cc].invorder_count] = ff; - charextra[cc].invorder_count++; - } - } - } - // backwards compatibility - play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; - - guis_need_update = 1; + for (int cc = 0; cc < game.numcharacters; cc++) { + charextra[cc].invorder_count = 0; + int ff, howmany; + // Iterate through all inv items, adding them once (or multiple + // times if requested) to the list. + for (ff = 0; ff < game.numinvitems; ff++) { + howmany = game.chars[cc].inv[ff]; + if ((game.options[OPT_DUPLICATEINV] == 0) && (howmany > 1)) + howmany = 1; + + for (int ts = 0; ts < howmany; ts++) { + if (charextra[cc].invorder_count >= MAX_INVORDER) + quit("!Too many inventory items to display: 500 max"); + + charextra[cc].invorder[charextra[cc].invorder_count] = ff; + charextra[cc].invorder_count++; + } + } + } + // backwards compatibility + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; + + guis_need_update = 1; } void add_inventory(int inum) { - if ((inum < 0) || (inum >= MAX_INV)) - quit("!AddInventory: invalid inventory number"); + if ((inum < 0) || (inum >= MAX_INV)) + quit("!AddInventory: invalid inventory number"); - Character_AddInventory(playerchar, &scrInv[inum], SCR_NO_VALUE); + Character_AddInventory(playerchar, &scrInv[inum], SCR_NO_VALUE); - play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; } void lose_inventory(int inum) { - if ((inum < 0) || (inum >= MAX_INV)) - quit("!LoseInventory: invalid inventory number"); + if ((inum < 0) || (inum >= MAX_INV)) + quit("!LoseInventory: invalid inventory number"); - Character_LoseInventory(playerchar, &scrInv[inum]); + Character_LoseInventory(playerchar, &scrInv[inum]); - play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; } void AddInventoryToCharacter(int charid, int inum) { - if (!is_valid_character(charid)) - quit("!AddInventoryToCharacter: invalid character specified"); - if ((inum < 1) || (inum >= game.numinvitems)) - quit("!AddInventory: invalid inv item specified"); + if (!is_valid_character(charid)) + quit("!AddInventoryToCharacter: invalid character specified"); + if ((inum < 1) || (inum >= game.numinvitems)) + quit("!AddInventory: invalid inv item specified"); - Character_AddInventory(&game.chars[charid], &scrInv[inum], SCR_NO_VALUE); + Character_AddInventory(&game.chars[charid], &scrInv[inum], SCR_NO_VALUE); } void LoseInventoryFromCharacter(int charid, int inum) { - if (!is_valid_character(charid)) - quit("!LoseInventoryFromCharacter: invalid character specified"); - if ((inum < 1) || (inum >= game.numinvitems)) - quit("!AddInventory: invalid inv item specified"); + if (!is_valid_character(charid)) + quit("!LoseInventoryFromCharacter: invalid character specified"); + if ((inum < 1) || (inum >= game.numinvitems)) + quit("!AddInventory: invalid inv item specified"); - Character_LoseInventory(&game.chars[charid], &scrInv[inum]); + Character_LoseInventory(&game.chars[charid], &scrInv[inum]); } void DisplayThought(int chid, const char *text) { - if ((chid < 0) || (chid >= game.numcharacters)) - quit("!DisplayThought: invalid character specified"); + if ((chid < 0) || (chid >= game.numcharacters)) + quit("!DisplayThought: invalid character specified"); - _DisplayThoughtCore(chid, text); + _DisplayThoughtCore(chid, text); } void __sc_displayspeech(int chid, const char *text) { - if ((chid<0) || (chid>=game.numcharacters)) - quit("!DisplaySpeech: invalid character specified"); + if ((chid < 0) || (chid >= game.numcharacters)) + quit("!DisplaySpeech: invalid character specified"); - _DisplaySpeechCore(chid, text); + _DisplaySpeechCore(chid, text); } // **** THIS IS UNDOCUMENTED BECAUSE IT DOESN'T WORK PROPERLY // **** AT 640x400 AND DOESN'T USE THE RIGHT SPEECH STYLE -void DisplaySpeechAt (int xx, int yy, int wii, int aschar, const char*spch) { - data_to_game_coords(&xx, &yy); - wii = data_to_game_coord(wii); - _displayspeech (get_translation(spch), aschar, xx, yy, wii, 0); -} - -int DisplaySpeechBackground(int charid, const char*speel) { - // remove any previous background speech for this character - for (size_t i = 0; i < screenover.size();) { - if (screenover[i].bgSpeechForChar == charid) - remove_screen_overlay_index(i); - else - i++; - } - - int ovrl=CreateTextOverlay(OVR_AUTOPLACE,charid,play.GetUIViewport().GetWidth()/2,FONT_SPEECH, - -game.chars[charid].talkcolor, get_translation(speel), DISPLAYTEXT_NORMALOVERLAY); - - int scid = find_overlay_of_type(ovrl); - screenover[scid].bgSpeechForChar = charid; - screenover[scid].timeout = GetTextDisplayTime(speel, 1); - return ovrl; +void DisplaySpeechAt(int xx, int yy, int wii, int aschar, const char *spch) { + data_to_game_coords(&xx, &yy); + wii = data_to_game_coord(wii); + _displayspeech(get_translation(spch), aschar, xx, yy, wii, 0); +} + +int DisplaySpeechBackground(int charid, const char *speel) { + // remove any previous background speech for this character + for (size_t i = 0; i < screenover.size();) { + if (screenover[i].bgSpeechForChar == charid) + remove_screen_overlay_index(i); + else + i++; + } + + int ovrl = CreateTextOverlay(OVR_AUTOPLACE, charid, play.GetUIViewport().GetWidth() / 2, FONT_SPEECH, + -game.chars[charid].talkcolor, get_translation(speel), DISPLAYTEXT_NORMALOVERLAY); + + int scid = find_overlay_of_type(ovrl); + screenover[scid].bgSpeechForChar = charid; + screenover[scid].timeout = GetTextDisplayTime(speel, 1); + return ovrl; } diff --git a/engines/ags/engine/ac/global_character.h b/engines/ags/engine/ac/global_character.h index e9d19b4c21a0..213df919d261 100644 --- a/engines/ags/engine/ac/global_character.h +++ b/engines/ags/engine/ac/global_character.h @@ -29,50 +29,50 @@ void StopMoving(int chaa); void ReleaseCharacterView(int chat); void MoveToWalkableArea(int charid); void FaceLocation(int cha, int xx, int yy); -void FaceCharacter(int cha,int toface); +void FaceCharacter(int cha, int toface); void SetCharacterIdle(int who, int iview, int itime); int GetCharacterWidth(int ww); int GetCharacterHeight(int charid); -void SetCharacterBaseline (int obn, int basel); +void SetCharacterBaseline(int obn, int basel); // pass trans=0 for fully solid, trans=100 for fully transparent -void SetCharacterTransparency(int obn,int trans); -void scAnimateCharacter (int chh, int loopn, int sppd, int rept); +void SetCharacterTransparency(int obn, int trans); +void scAnimateCharacter(int chh, int loopn, int sppd, int rept); void AnimateCharacterEx(int chh, int loopn, int sppd, int rept, int direction, int blocking); void SetPlayerCharacter(int newchar); void FollowCharacterEx(int who, int tofollow, int distaway, int eagerness); void FollowCharacter(int who, int tofollow); -void SetCharacterIgnoreLight (int who, int yesorno); -void MoveCharacter(int cc,int xx,int yy); -void MoveCharacterDirect(int cc,int xx, int yy); -void MoveCharacterStraight(int cc,int xx, int yy); +void SetCharacterIgnoreLight(int who, int yesorno); +void MoveCharacter(int cc, int xx, int yy); +void MoveCharacterDirect(int cc, int xx, int yy); +void MoveCharacterStraight(int cc, int xx, int yy); // Append to character path -void MoveCharacterPath (int chac, int tox, int toy); +void MoveCharacterPath(int chac, int tox, int toy); void SetCharacterSpeedEx(int chaa, int xspeed, int yspeed); -void SetCharacterSpeed(int chaa,int nspeed); -void SetTalkingColor(int chaa,int ncol); -void SetCharacterSpeechView (int chaa, int vii); -void SetCharacterBlinkView (int chaa, int vii, int intrv); -void SetCharacterView(int chaa,int vii); +void SetCharacterSpeed(int chaa, int nspeed); +void SetTalkingColor(int chaa, int ncol); +void SetCharacterSpeechView(int chaa, int vii); +void SetCharacterBlinkView(int chaa, int vii, int intrv); +void SetCharacterView(int chaa, int vii); void SetCharacterFrame(int chaa, int view, int loop, int frame); // similar to SetCharView, but aligns the frame to make it line up -void SetCharacterViewEx (int chaa, int vii, int loop, int align); -void SetCharacterViewOffset (int chaa, int vii, int xoffs, int yoffs); -void ChangeCharacterView(int chaa,int vii); -void SetCharacterClickable (int cha, int clik); -void SetCharacterIgnoreWalkbehinds (int cha, int clik); -void MoveCharacterToObject(int chaa,int obbj); -void MoveCharacterToHotspot(int chaa,int hotsp); -void MoveCharacterBlocking(int chaa,int xx,int yy,int direct); +void SetCharacterViewEx(int chaa, int vii, int loop, int align); +void SetCharacterViewOffset(int chaa, int vii, int xoffs, int yoffs); +void ChangeCharacterView(int chaa, int vii); +void SetCharacterClickable(int cha, int clik); +void SetCharacterIgnoreWalkbehinds(int cha, int clik); +void MoveCharacterToObject(int chaa, int obbj); +void MoveCharacterToHotspot(int chaa, int hotsp); +void MoveCharacterBlocking(int chaa, int xx, int yy, int direct); -void RunCharacterInteraction (int cc, int mood); -int AreCharObjColliding(int charid,int objid); -int AreCharactersColliding(int cchar1,int cchar2); +void RunCharacterInteraction(int cc, int mood); +int AreCharObjColliding(int charid, int objid); +int AreCharactersColliding(int cchar1, int cchar2); -int GetCharacterProperty (int cha, const char *property); -void SetCharacterProperty (int who, int flag, int yesorno); +int GetCharacterProperty(int cha, const char *property); +void SetCharacterProperty(int who, int flag, int yesorno); int GetPlayerCharacter(); -void GetCharacterPropertyText (int item, const char *property, char *bufer); +void GetCharacterPropertyText(int item, const char *property, char *bufer); int GetCharacterSpeechAnimationDelay(CharacterInfo *cha); int GetCharIDAtScreen(int xx, int yy); @@ -86,7 +86,7 @@ void lose_inventory(int inum); void DisplayThought(int chid, const char *text); void __sc_displayspeech(int chid, const char *text); -void DisplaySpeechAt (int xx, int yy, int wii, int aschar, const char*spch); -int DisplaySpeechBackground(int charid, const char*speel); +void DisplaySpeechAt(int xx, int yy, int wii, int aschar, const char *spch); +int DisplaySpeechBackground(int charid, const char *speel); #endif diff --git a/engines/ags/engine/ac/global_datetime.cpp b/engines/ags/engine/ac/global_datetime.cpp index 700005ceb23c..619e678a4751 100644 --- a/engines/ags/engine/ac/global_datetime.cpp +++ b/engines/ags/engine/ac/global_datetime.cpp @@ -26,23 +26,23 @@ #include "ac/common.h" int sc_GetTime(int whatti) { - ScriptDateTime *sdt = DateTime_Now_Core(); - int returnVal = 0; + ScriptDateTime *sdt = DateTime_Now_Core(); + int returnVal = 0; - if (whatti == 1) returnVal = sdt->hour; - else if (whatti == 2) returnVal = sdt->minute; - else if (whatti == 3) returnVal = sdt->second; - else if (whatti == 4) returnVal = sdt->day; - else if (whatti == 5) returnVal = sdt->month; - else if (whatti == 6) returnVal = sdt->year; - else quit("!GetTime: invalid parameter passed"); + if (whatti == 1) returnVal = sdt->hour; + else if (whatti == 2) returnVal = sdt->minute; + else if (whatti == 3) returnVal = sdt->second; + else if (whatti == 4) returnVal = sdt->day; + else if (whatti == 5) returnVal = sdt->month; + else if (whatti == 6) returnVal = sdt->year; + else quit("!GetTime: invalid parameter passed"); - delete sdt; + delete sdt; - return returnVal; + return returnVal; } -int GetRawTime () { - // TODO: we might need to modify script API to support larger time type - return static_cast(time(nullptr)); +int GetRawTime() { + // TODO: we might need to modify script API to support larger time type + return static_cast(time(nullptr)); } diff --git a/engines/ags/engine/ac/global_datetime.h b/engines/ags/engine/ac/global_datetime.h index 55fd3abe6349..89970236619e 100644 --- a/engines/ags/engine/ac/global_datetime.h +++ b/engines/ags/engine/ac/global_datetime.h @@ -24,6 +24,6 @@ #define AGS_ENGINE_AC_GLOBALDATETIME_H int sc_GetTime(int whatti) ; -int GetRawTime (); +int GetRawTime(); #endif diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp index 41f9ac5d231e..4131c1834f29 100644 --- a/engines/ags/engine/ac/global_debug.cpp +++ b/engines/ags/engine/ac/global_debug.cpp @@ -54,7 +54,7 @@ extern GameSetupStruct game; extern GameSetup usetup; extern GameState play; extern RoomStruct thisroom; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern int convert_16bit_bgr; extern IGraphicsDriver *gfxDriver; @@ -64,135 +64,124 @@ extern int displayed_room, starting_room; extern MoveList *mls; extern char transFileName[MAX_PATH]; -String GetRuntimeInfo() -{ - DisplayMode mode = gfxDriver->GetDisplayMode(); - Rect render_frame = gfxDriver->GetRenderDestination(); - PGfxFilter filter = gfxDriver->GetGraphicsFilter(); - String runtimeInfo = String::FromFormat( - "Adventure Game Studio run-time engine[ACI version %s" - "[Game resolution %d x %d (%d-bit)" - "[Running %d x %d at %d-bit%s%s[GFX: %s; %s[Draw frame %d x %d[" - "Sprite cache size: %d KB (limit %d KB; %d locked)", - EngineVersion.LongString.GetCStr(), game.GetGameRes().Width, game.GetGameRes().Height, game.GetColorDepth(), - mode.Width, mode.Height, mode.ColorDepth, (convert_16bit_bgr) ? " BGR" : "", - mode.Windowed ? " W" : "", - gfxDriver->GetDriverName(), filter->GetInfo().Name.GetCStr(), - render_frame.GetWidth(), render_frame.GetHeight(), - spriteset.GetCacheSize() / 1024, spriteset.GetMaxCacheSize() / 1024, spriteset.GetLockedSize() / 1024); - if (play.separate_music_lib) - runtimeInfo.Append("[AUDIO.VOX enabled"); - if (play.want_speech >= 1) - runtimeInfo.Append("[SPEECH.VOX enabled"); - if (transtree != nullptr) { - runtimeInfo.Append("[Using translation "); - runtimeInfo.Append(transFileName); - } - if (usetup.mod_player == 0) - runtimeInfo.Append("[(mod/xm player discarded)"); +String GetRuntimeInfo() { + DisplayMode mode = gfxDriver->GetDisplayMode(); + Rect render_frame = gfxDriver->GetRenderDestination(); + PGfxFilter filter = gfxDriver->GetGraphicsFilter(); + String runtimeInfo = String::FromFormat( + "Adventure Game Studio run-time engine[ACI version %s" + "[Game resolution %d x %d (%d-bit)" + "[Running %d x %d at %d-bit%s%s[GFX: %s; %s[Draw frame %d x %d[" + "Sprite cache size: %d KB (limit %d KB; %d locked)", + EngineVersion.LongString.GetCStr(), game.GetGameRes().Width, game.GetGameRes().Height, game.GetColorDepth(), + mode.Width, mode.Height, mode.ColorDepth, (convert_16bit_bgr) ? " BGR" : "", + mode.Windowed ? " W" : "", + gfxDriver->GetDriverName(), filter->GetInfo().Name.GetCStr(), + render_frame.GetWidth(), render_frame.GetHeight(), + spriteset.GetCacheSize() / 1024, spriteset.GetMaxCacheSize() / 1024, spriteset.GetLockedSize() / 1024); + if (play.separate_music_lib) + runtimeInfo.Append("[AUDIO.VOX enabled"); + if (play.want_speech >= 1) + runtimeInfo.Append("[SPEECH.VOX enabled"); + if (transtree != nullptr) { + runtimeInfo.Append("[Using translation "); + runtimeInfo.Append(transFileName); + } + if (usetup.mod_player == 0) + runtimeInfo.Append("[(mod/xm player discarded)"); - return runtimeInfo; + return runtimeInfo; } -void script_debug(int cmdd,int dataa) { - if (play.debug_mode==0) return; - int rr; - if (cmdd==0) { - for (rr=1;rrinv[rr]=1; - update_invorder(); - // Display("invorder decided there are %d items[display %d",play.inv_numorder,play.inv_numdisp); - } - else if (cmdd==1) { - String toDisplay = GetRuntimeInfo(); - Display(toDisplay.GetCStr()); - // Display("shftR: %d shftG: %d shftB: %d", _rgb_r_shift_16, _rgb_g_shift_16, _rgb_b_shift_16); - // Display("Remaining memory: %d kb",_go32_dpmi_remaining_virtual_memory()/1024); - //Display("Play char bcd: %d",->GetColorDepth(spriteset[views[playerchar->view].frames[playerchar->loop][playerchar->frame].pic])); - } - else if (cmdd==2) - { // show walkable areas from here - // TODO: support multiple viewports?! - const int viewport_index = 0; - const int camera_index = 0; - Bitmap *tempw=BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(),thisroom.WalkAreaMask->GetHeight()); - tempw->Blit(prepare_walkable_areas(-1),0,0,0,0,tempw->GetWidth(),tempw->GetHeight()); - const Rect &viewport = play.GetRoomViewport(viewport_index)->GetRect(); - const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); - Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); - Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); - view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); +void script_debug(int cmdd, int dataa) { + if (play.debug_mode == 0) return; + int rr; + if (cmdd == 0) { + for (rr = 1; rr < game.numinvitems; rr++) + playerchar->inv[rr] = 1; + update_invorder(); + // Display("invorder decided there are %d items[display %d",play.inv_numorder,play.inv_numdisp); + } else if (cmdd == 1) { + String toDisplay = GetRuntimeInfo(); + Display(toDisplay.GetCStr()); + // Display("shftR: %d shftG: %d shftB: %d", _rgb_r_shift_16, _rgb_g_shift_16, _rgb_b_shift_16); + // Display("Remaining memory: %d kb",_go32_dpmi_remaining_virtual_memory()/1024); + //Display("Play char bcd: %d",->GetColorDepth(spriteset[views[playerchar->view].frames[playerchar->loop][playerchar->frame].pic])); + } else if (cmdd == 2) { + // show walkable areas from here + // TODO: support multiple viewports?! + const int viewport_index = 0; + const int camera_index = 0; + Bitmap *tempw = BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight()); + tempw->Blit(prepare_walkable_areas(-1), 0, 0, 0, 0, tempw->GetWidth(), tempw->GetHeight()); + const Rect &viewport = play.GetRoomViewport(viewport_index)->GetRect(); + const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); + Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); + Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); + view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); - IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); - render_graphics(ddb, viewport.Left, viewport.Top); + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); + render_graphics(ddb, viewport.Left, viewport.Top); - delete tempw; - delete view_bmp; - gfxDriver->DestroyDDB(ddb); - ags_wait_until_keypress(); - invalidate_screen(); - } - else if (cmdd==3) - { - int goToRoom = -1; - if (game.roomCount == 0) - { - char inroomtex[80]; - sprintf(inroomtex, "!Enter new room: (in room %d)", displayed_room); - setup_for_dialog(); - goToRoom = enternumberwindow(inroomtex); - restore_after_dialog(); - } - else - { - setup_for_dialog(); - goToRoom = roomSelectorWindow(displayed_room, game.roomCount, game.roomNumbers, game.roomNames); - restore_after_dialog(); - } - if (goToRoom >= 0) - NewRoom(goToRoom); - } - else if (cmdd == 4) { - if (display_fps != kFPS_Forced) - display_fps = (FPSDisplayMode)dataa; - } - else if (cmdd == 5) { - if (dataa == 0) dataa = game.playercharacter; - if (game.chars[dataa].walking < 1) { - Display("Not currently moving."); - return; - } - Bitmap *tempw=BitmapHelper::CreateTransparentBitmap(thisroom.WalkAreaMask->GetWidth(),thisroom.WalkAreaMask->GetHeight()); - int mlsnum = game.chars[dataa].walking; - if (game.chars[dataa].walking >= TURNING_AROUND) - mlsnum %= TURNING_AROUND; - MoveList*cmls = &mls[mlsnum]; - for (int i = 0; i < cmls->numstage-1; i++) { - short srcx=short((cmls->pos[i] >> 16) & 0x00ffff); - short srcy=short(cmls->pos[i] & 0x00ffff); - short targetx=short((cmls->pos[i+1] >> 16) & 0x00ffff); - short targety=short(cmls->pos[i+1] & 0x00ffff); - tempw->DrawLine(Line(srcx, srcy, targetx, targety), MakeColor(i+1)); - } + delete tempw; + delete view_bmp; + gfxDriver->DestroyDDB(ddb); + ags_wait_until_keypress(); + invalidate_screen(); + } else if (cmdd == 3) { + int goToRoom = -1; + if (game.roomCount == 0) { + char inroomtex[80]; + sprintf(inroomtex, "!Enter new room: (in room %d)", displayed_room); + setup_for_dialog(); + goToRoom = enternumberwindow(inroomtex); + restore_after_dialog(); + } else { + setup_for_dialog(); + goToRoom = roomSelectorWindow(displayed_room, game.roomCount, game.roomNumbers, game.roomNames); + restore_after_dialog(); + } + if (goToRoom >= 0) + NewRoom(goToRoom); + } else if (cmdd == 4) { + if (display_fps != kFPS_Forced) + display_fps = (FPSDisplayMode)dataa; + } else if (cmdd == 5) { + if (dataa == 0) dataa = game.playercharacter; + if (game.chars[dataa].walking < 1) { + Display("Not currently moving."); + return; + } + Bitmap *tempw = BitmapHelper::CreateTransparentBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight()); + int mlsnum = game.chars[dataa].walking; + if (game.chars[dataa].walking >= TURNING_AROUND) + mlsnum %= TURNING_AROUND; + MoveList *cmls = &mls[mlsnum]; + for (int i = 0; i < cmls->numstage - 1; i++) { + short srcx = short((cmls->pos[i] >> 16) & 0x00ffff); + short srcy = short(cmls->pos[i] & 0x00ffff); + short targetx = short((cmls->pos[i + 1] >> 16) & 0x00ffff); + short targety = short(cmls->pos[i + 1] & 0x00ffff); + tempw->DrawLine(Line(srcx, srcy, targetx, targety), MakeColor(i + 1)); + } - // TODO: support multiple viewports?! - const int viewport_index = 0; - const int camera_index = 0; - const Rect &viewport = play.GetRoomViewport(viewport_index)->GetRect(); - const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); - Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); - Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); - view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); + // TODO: support multiple viewports?! + const int viewport_index = 0; + const int camera_index = 0; + const Rect &viewport = play.GetRoomViewport(viewport_index)->GetRect(); + const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); + Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); + Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); + view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); - IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); - render_graphics(ddb, viewport.Left, viewport.Top); + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); + render_graphics(ddb, viewport.Left, viewport.Top); - delete tempw; - delete view_bmp; - gfxDriver->DestroyDDB(ddb); - ags_wait_until_keypress(); - } - else if (cmdd == 99) - ccSetOption(SCOPT_DEBUGRUN, dataa); - else quit("!Debug: unknown command code"); + delete tempw; + delete view_bmp; + gfxDriver->DestroyDDB(ddb); + ags_wait_until_keypress(); + } else if (cmdd == 99) + ccSetOption(SCOPT_DEBUGRUN, dataa); + else quit("!Debug: unknown command code"); } diff --git a/engines/ags/engine/ac/global_debug.h b/engines/ags/engine/ac/global_debug.h index 2f4e4445156d..6019593cbd3d 100644 --- a/engines/ags/engine/ac/global_debug.h +++ b/engines/ags/engine/ac/global_debug.h @@ -27,6 +27,6 @@ #include "util/string.h" AGS::Common::String GetRuntimeInfo(); -void script_debug(int cmdd,int dataa); +void script_debug(int cmdd, int dataa); #endif diff --git a/engines/ags/engine/ac/global_dialog.cpp b/engines/ags/engine/ac/global_dialog.cpp index 5115355e9db5..0acc1f5feee8 100644 --- a/engines/ags/engine/ac/global_dialog.cpp +++ b/engines/ags/engine/ac/global_dialog.cpp @@ -39,73 +39,70 @@ extern DialogTopic *dialog; ScriptPosition last_in_dialog_request_script_pos; void RunDialog(int tum) { - if ((tum<0) | (tum>=game.numdialog)) - quit("!RunDialog: invalid topic number specified"); + if ((tum < 0) | (tum >= game.numdialog)) + quit("!RunDialog: invalid topic number specified"); - can_run_delayed_command(); + can_run_delayed_command(); - if (play.stop_dialog_at_end != DIALOG_NONE) { - if (play.stop_dialog_at_end == DIALOG_RUNNING) - play.stop_dialog_at_end = DIALOG_NEWTOPIC + tum; - else - quitprintf("!RunDialog: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", - last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); - return; - } + if (play.stop_dialog_at_end != DIALOG_NONE) { + if (play.stop_dialog_at_end == DIALOG_RUNNING) + play.stop_dialog_at_end = DIALOG_NEWTOPIC + tum; + else + quitprintf("!RunDialog: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", + last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); + return; + } - get_script_position(last_in_dialog_request_script_pos); + get_script_position(last_in_dialog_request_script_pos); - if (inside_script) - curscript->queue_action(ePSARunDialog, tum, "RunDialog"); - else - do_conversation(tum); + if (inside_script) + curscript->queue_action(ePSARunDialog, tum, "RunDialog"); + else + do_conversation(tum); } void StopDialog() { - if (play.stop_dialog_at_end == DIALOG_NONE) { - debug_script_warn("StopDialog called, but was not in a dialog"); - debug_script_log("StopDialog called but no dialog"); - return; - } - get_script_position(last_in_dialog_request_script_pos); - play.stop_dialog_at_end = DIALOG_STOP; + if (play.stop_dialog_at_end == DIALOG_NONE) { + debug_script_warn("StopDialog called, but was not in a dialog"); + debug_script_log("StopDialog called but no dialog"); + return; + } + get_script_position(last_in_dialog_request_script_pos); + play.stop_dialog_at_end = DIALOG_STOP; } -void SetDialogOption(int dlg, int opt, int onoroff, bool dlg_script) -{ - if ((dlg<0) | (dlg>=game.numdialog)) - quit("!SetDialogOption: Invalid topic number specified"); - if ((opt<1) | (opt>dialog[dlg].numoptions)) - { - // Pre-3.1.1 games had "dialog scripts" that were written in different language and - // parsed differently; its "option-on/off" commands were more permissive. - if (dlg_script) - { - Debug::Printf(kDbgGroup_Game, kDbgMsg_Error, "SetDialogOption: Invalid option number specified (%d : %d)", dlg, opt); - return; - } - quit("!SetDialogOption: Invalid option number specified"); - } - opt--; +void SetDialogOption(int dlg, int opt, int onoroff, bool dlg_script) { + if ((dlg < 0) | (dlg >= game.numdialog)) + quit("!SetDialogOption: Invalid topic number specified"); + if ((opt < 1) | (opt > dialog[dlg].numoptions)) { + // Pre-3.1.1 games had "dialog scripts" that were written in different language and + // parsed differently; its "option-on/off" commands were more permissive. + if (dlg_script) { + Debug::Printf(kDbgGroup_Game, kDbgMsg_Error, "SetDialogOption: Invalid option number specified (%d : %d)", dlg, opt); + return; + } + quit("!SetDialogOption: Invalid option number specified"); + } + opt--; - dialog[dlg].optionflags[opt]&=~DFLG_ON; - if ((onoroff==1) & ((dialog[dlg].optionflags[opt] & DFLG_OFFPERM)==0)) - dialog[dlg].optionflags[opt]|=DFLG_ON; - else if (onoroff==2) - dialog[dlg].optionflags[opt]|=DFLG_OFFPERM; + dialog[dlg].optionflags[opt] &= ~DFLG_ON; + if ((onoroff == 1) & ((dialog[dlg].optionflags[opt] & DFLG_OFFPERM) == 0)) + dialog[dlg].optionflags[opt] |= DFLG_ON; + else if (onoroff == 2) + dialog[dlg].optionflags[opt] |= DFLG_OFFPERM; } -int GetDialogOption (int dlg, int opt) { - if ((dlg<0) | (dlg>=game.numdialog)) - quit("!GetDialogOption: Invalid topic number specified"); - if ((opt<1) | (opt>dialog[dlg].numoptions)) - quit("!GetDialogOption: Invalid option number specified"); - opt--; +int GetDialogOption(int dlg, int opt) { + if ((dlg < 0) | (dlg >= game.numdialog)) + quit("!GetDialogOption: Invalid topic number specified"); + if ((opt < 1) | (opt > dialog[dlg].numoptions)) + quit("!GetDialogOption: Invalid option number specified"); + opt--; - if (dialog[dlg].optionflags[opt] & DFLG_OFFPERM) - return 2; - if (dialog[dlg].optionflags[opt] & DFLG_ON) - return 1; - return 0; + if (dialog[dlg].optionflags[opt] & DFLG_OFFPERM) + return 2; + if (dialog[dlg].optionflags[opt] & DFLG_ON) + return 1; + return 0; } diff --git a/engines/ags/engine/ac/global_dialog.h b/engines/ags/engine/ac/global_dialog.h index faf0539b838f..b9733d41019d 100644 --- a/engines/ags/engine/ac/global_dialog.h +++ b/engines/ags/engine/ac/global_dialog.h @@ -24,7 +24,7 @@ #define AGS_ENGINE_AC_GLOBALDIALOG_H void RunDialog(int tum); -int GetDialogOption (int dlg, int opt); +int GetDialogOption(int dlg, int opt); void SetDialogOption(int dlg, int opt, int onoroff, bool dlg_script = false); void StopDialog(); diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp index 06398c1ef8c0..08b821051a61 100644 --- a/engines/ags/engine/ac/global_display.cpp +++ b/engines/ags/engine/ac/global_display.cpp @@ -49,160 +49,155 @@ extern RoomStruct thisroom; extern int display_message_aschar; extern GameSetupStruct game; -void Display(const char*texx, ...) { - char displbuf[STD_BUFFER_SIZE]; - va_list ap; - va_start(ap,texx); - vsprintf(displbuf, get_translation(texx), ap); - va_end(ap); - DisplayAtY (-1, displbuf); +void Display(const char *texx, ...) { + char displbuf[STD_BUFFER_SIZE]; + va_list ap; + va_start(ap, texx); + vsprintf(displbuf, get_translation(texx), ap); + va_end(ap); + DisplayAtY(-1, displbuf); } -void DisplaySimple(const char *text) -{ - DisplayAtY (-1, text); +void DisplaySimple(const char *text) { + DisplayAtY(-1, text); } -void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const char *text) -{ - // FIXME: refactor source_text_length and get rid of this ugly hack! - const int real_text_sourcelen = source_text_length; - snprintf(topBar.text, sizeof(topBar.text), "%s", get_translation(title)); - source_text_length = real_text_sourcelen; - - if (ypos > 0) - play.top_bar_ypos = ypos; - if (ttexcol > 0) - play.top_bar_textcolor = ttexcol; - if (backcol > 0) - play.top_bar_backcolor = backcol; - - topBar.wantIt = 1; - topBar.font = FONT_NORMAL; - topBar.height = getfontheight_outlined(topBar.font); - topBar.height += data_to_game_coord(play.top_bar_borderwidth) * 2 + get_fixed_pixel_size(1); - - // they want to customize the font - if (play.top_bar_font >= 0) - topBar.font = play.top_bar_font; - - // DisplaySpeech normally sets this up, but since we're not going via it... - if (play.cant_skip_speech & SKIP_AUTOTIMER) - play.messagetime = GetTextDisplayTime(text); - - DisplayAtY(play.top_bar_ypos, text); +void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const char *text) { + // FIXME: refactor source_text_length and get rid of this ugly hack! + const int real_text_sourcelen = source_text_length; + snprintf(topBar.text, sizeof(topBar.text), "%s", get_translation(title)); + source_text_length = real_text_sourcelen; + + if (ypos > 0) + play.top_bar_ypos = ypos; + if (ttexcol > 0) + play.top_bar_textcolor = ttexcol; + if (backcol > 0) + play.top_bar_backcolor = backcol; + + topBar.wantIt = 1; + topBar.font = FONT_NORMAL; + topBar.height = getfontheight_outlined(topBar.font); + topBar.height += data_to_game_coord(play.top_bar_borderwidth) * 2 + get_fixed_pixel_size(1); + + // they want to customize the font + if (play.top_bar_font >= 0) + topBar.font = play.top_bar_font; + + // DisplaySpeech normally sets this up, but since we're not going via it... + if (play.cant_skip_speech & SKIP_AUTOTIMER) + play.messagetime = GetTextDisplayTime(text); + + DisplayAtY(play.top_bar_ypos, text); } // Display a room/global message in the bar void DisplayMessageBar(int ypos, int ttexcol, int backcol, const char *title, int msgnum) { - char msgbufr[3001]; - get_message_text(msgnum, msgbufr); - DisplayTopBar(ypos, ttexcol, backcol, title, msgbufr); + char msgbufr[3001]; + get_message_text(msgnum, msgbufr); + DisplayTopBar(ypos, ttexcol, backcol, title, msgbufr); } void DisplayMessageAtY(int msnum, int ypos) { - char msgbufr[3001]; - if (msnum>=500) { - get_message_text (msnum, msgbufr); - if (display_message_aschar > 0) - DisplaySpeech(msgbufr, display_message_aschar); - else - DisplayAtY(ypos, msgbufr); - display_message_aschar=0; - return; - } - - if (display_message_aschar > 0) { - display_message_aschar=0; - quit("!DisplayMessage: data column specified a character for local\n" - "message; use the message editor to select the character for room\n" - "messages.\n"); - } - - int repeatloop=1; - while (repeatloop) { - get_message_text (msnum, msgbufr); - - if (thisroom.MessageInfos[msnum].DisplayAs > 0) { - DisplaySpeech(msgbufr, thisroom.MessageInfos[msnum].DisplayAs - 1); - } - else { - // time out automatically if they have set that - int oldGameSkipDisp = play.skip_display; - if (thisroom.MessageInfos[msnum].Flags & MSG_TIMELIMIT) - play.skip_display = 0; - - DisplayAtY(ypos, msgbufr); - - play.skip_display = oldGameSkipDisp; - } - if (thisroom.MessageInfos[msnum].Flags & MSG_DISPLAYNEXT) { - msnum++; - repeatloop=1; - } - else - repeatloop=0; - } + char msgbufr[3001]; + if (msnum >= 500) { + get_message_text(msnum, msgbufr); + if (display_message_aschar > 0) + DisplaySpeech(msgbufr, display_message_aschar); + else + DisplayAtY(ypos, msgbufr); + display_message_aschar = 0; + return; + } + + if (display_message_aschar > 0) { + display_message_aschar = 0; + quit("!DisplayMessage: data column specified a character for local\n" + "message; use the message editor to select the character for room\n" + "messages.\n"); + } + + int repeatloop = 1; + while (repeatloop) { + get_message_text(msnum, msgbufr); + + if (thisroom.MessageInfos[msnum].DisplayAs > 0) { + DisplaySpeech(msgbufr, thisroom.MessageInfos[msnum].DisplayAs - 1); + } else { + // time out automatically if they have set that + int oldGameSkipDisp = play.skip_display; + if (thisroom.MessageInfos[msnum].Flags & MSG_TIMELIMIT) + play.skip_display = 0; + + DisplayAtY(ypos, msgbufr); + + play.skip_display = oldGameSkipDisp; + } + if (thisroom.MessageInfos[msnum].Flags & MSG_DISPLAYNEXT) { + msnum++; + repeatloop = 1; + } else + repeatloop = 0; + } } void DisplayMessage(int msnum) { - DisplayMessageAtY (msnum, -1); + DisplayMessageAtY(msnum, -1); } -void DisplayAt(int xxp,int yyp,int widd, const char* text) { - data_to_game_coords(&xxp, &yyp); - widd = data_to_game_coord(widd); +void DisplayAt(int xxp, int yyp, int widd, const char *text) { + data_to_game_coords(&xxp, &yyp); + widd = data_to_game_coord(widd); - if (widd<1) widd=play.GetUIViewport().GetWidth()/2; - if (xxp<0) xxp=play.GetUIViewport().GetWidth()/2-widd/2; - _display_at(xxp, yyp, widd, text, DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); + if (widd < 1) widd = play.GetUIViewport().GetWidth() / 2; + if (xxp < 0) xxp = play.GetUIViewport().GetWidth() / 2 - widd / 2; + _display_at(xxp, yyp, widd, text, DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); } -void DisplayAtY (int ypos, const char *texx) { - const Rect &ui_view = play.GetUIViewport(); - if ((ypos < -1) || (ypos >= ui_view.GetHeight())) - quitprintf("!DisplayAtY: invalid Y co-ordinate supplied (used: %d; valid: 0..%d)", ypos, ui_view.GetHeight()); - - // Display("") ... a bit of a stupid thing to do, so ignore it - if (texx[0] == 0) - return; - - if (ypos > 0) - ypos = data_to_game_coord(ypos); - - if (game.options[OPT_ALWAYSSPCH]) - DisplaySpeechAt(-1, (ypos > 0) ? game_to_data_coord(ypos) : ypos, -1, game.playercharacter, texx); - else { - // Normal "Display" in text box - - if (is_screen_dirty()) { - // erase any previous DisplaySpeech - play.disabled_user_interface ++; - UpdateGameOnce(); - play.disabled_user_interface --; - } - - _display_at(-1, ypos, ui_view.GetWidth() / 2 + ui_view.GetWidth() / 4, - get_translation(texx), DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); - } +void DisplayAtY(int ypos, const char *texx) { + const Rect &ui_view = play.GetUIViewport(); + if ((ypos < -1) || (ypos >= ui_view.GetHeight())) + quitprintf("!DisplayAtY: invalid Y co-ordinate supplied (used: %d; valid: 0..%d)", ypos, ui_view.GetHeight()); + + // Display("") ... a bit of a stupid thing to do, so ignore it + if (texx[0] == 0) + return; + + if (ypos > 0) + ypos = data_to_game_coord(ypos); + + if (game.options[OPT_ALWAYSSPCH]) + DisplaySpeechAt(-1, (ypos > 0) ? game_to_data_coord(ypos) : ypos, -1, game.playercharacter, texx); + else { + // Normal "Display" in text box + + if (is_screen_dirty()) { + // erase any previous DisplaySpeech + play.disabled_user_interface ++; + UpdateGameOnce(); + play.disabled_user_interface --; + } + + _display_at(-1, ypos, ui_view.GetWidth() / 2 + ui_view.GetWidth() / 4, + get_translation(texx), DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); + } } -void SetSpeechStyle (int newstyle) { - if ((newstyle < 0) || (newstyle > 3)) - quit("!SetSpeechStyle: must use a SPEECH_* constant as parameter"); - game.options[OPT_SPEECHTYPE] = newstyle; +void SetSpeechStyle(int newstyle) { + if ((newstyle < 0) || (newstyle > 3)) + quit("!SetSpeechStyle: must use a SPEECH_* constant as parameter"); + game.options[OPT_SPEECHTYPE] = newstyle; } -void SetSkipSpeech (SkipSpeechStyle newval) { - if ((newval < kSkipSpeechFirst) || (newval > kSkipSpeechLast)) - quit("!SetSkipSpeech: invalid skip mode specified"); +void SetSkipSpeech(SkipSpeechStyle newval) { + if ((newval < kSkipSpeechFirst) || (newval > kSkipSpeechLast)) + quit("!SetSkipSpeech: invalid skip mode specified"); - debug_script_log("SkipSpeech style set to %d", newval); - play.cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)newval); + debug_script_log("SkipSpeech style set to %d", newval); + play.cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)newval); } -SkipSpeechStyle GetSkipSpeech() -{ - return internal_skip_speech_to_user(play.cant_skip_speech); +SkipSpeechStyle GetSkipSpeech() { + return internal_skip_speech_to_user(play.cant_skip_speech); } diff --git a/engines/ags/engine/ac/global_display.h b/engines/ags/engine/ac/global_display.h index f71803675ca0..8f6f1397ac2c 100644 --- a/engines/ags/engine/ac/global_display.h +++ b/engines/ags/engine/ac/global_display.h @@ -25,18 +25,18 @@ #include "ac/speech.h" -void Display(const char*texx, ...); // applies translation -void DisplaySimple(const char* text); // does not apply translation -void DisplayAt(int xxp,int yyp,int widd, const char*text); -void DisplayAtY (int ypos, const char *texx); +void Display(const char *texx, ...); // applies translation +void DisplaySimple(const char *text); // does not apply translation +void DisplayAt(int xxp, int yyp, int widd, const char *text); +void DisplayAtY(int ypos, const char *texx); void DisplayMessage(int msnum); void DisplayMessageAtY(int msnum, int ypos); void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const char *text); // Display a room/global message in the bar void DisplayMessageBar(int ypos, int ttexcol, int backcol, const char *title, int msgnum); -void SetSpeechStyle (int newstyle); -void SetSkipSpeech (SkipSpeechStyle newval); +void SetSpeechStyle(int newstyle); +void SetSkipSpeech(SkipSpeechStyle newval); SkipSpeechStyle GetSkipSpeech(); #endif diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp index 2c5dea5b3d03..5fe00fdacdc3 100644 --- a/engines/ags/engine/ac/global_drawingsurface.cpp +++ b/engines/ags/engine/ac/global_drawingsurface.cpp @@ -52,258 +52,255 @@ extern GameSetupStruct game; #define RAW_SURFACE() (play.raw_drawing_surface.get()) // RawSaveScreen: copy the current screen to a backup bitmap -void RawSaveScreen () { - if (raw_saved_screen != nullptr) - delete raw_saved_screen; - PBitmap source = thisroom.BgFrames[play.bg_frame].Graphic; - raw_saved_screen = BitmapHelper::CreateBitmapCopy(source.get()); +void RawSaveScreen() { + if (raw_saved_screen != nullptr) + delete raw_saved_screen; + PBitmap source = thisroom.BgFrames[play.bg_frame].Graphic; + raw_saved_screen = BitmapHelper::CreateBitmapCopy(source.get()); } // RawRestoreScreen: copy backup bitmap back to screen; we // deliberately don't free the Bitmap *cos they can multiple restore // and it gets freed on room exit anyway void RawRestoreScreen() { - if (raw_saved_screen == nullptr) { - debug_script_warn("RawRestoreScreen: unable to restore, since the screen hasn't been saved previously."); - return; - } - PBitmap deston = thisroom.BgFrames[play.bg_frame].Graphic; - deston->Blit(raw_saved_screen, 0, 0, 0, 0, deston->GetWidth(), deston->GetHeight()); - invalidate_screen(); - mark_current_background_dirty(); + if (raw_saved_screen == nullptr) { + debug_script_warn("RawRestoreScreen: unable to restore, since the screen hasn't been saved previously."); + return; + } + PBitmap deston = thisroom.BgFrames[play.bg_frame].Graphic; + deston->Blit(raw_saved_screen, 0, 0, 0, 0, deston->GetWidth(), deston->GetHeight()); + invalidate_screen(); + mark_current_background_dirty(); } // Restores the backup bitmap, but tints it to the specified level void RawRestoreScreenTinted(int red, int green, int blue, int opacity) { - if (raw_saved_screen == nullptr) { - debug_script_warn("RawRestoreScreenTinted: unable to restore, since the screen hasn't been saved previously."); - return; - } - if ((red < 0) || (green < 0) || (blue < 0) || - (red > 255) || (green > 255) || (blue > 255) || - (opacity < 1) || (opacity > 100)) - quit("!RawRestoreScreenTinted: invalid parameter. R,G,B must be 0-255, opacity 1-100"); - - debug_script_log("RawRestoreTinted RGB(%d,%d,%d) %d%%", red, green, blue, opacity); - - PBitmap deston = thisroom.BgFrames[play.bg_frame].Graphic; - tint_image(deston.get(), raw_saved_screen, red, green, blue, opacity); - invalidate_screen(); - mark_current_background_dirty(); + if (raw_saved_screen == nullptr) { + debug_script_warn("RawRestoreScreenTinted: unable to restore, since the screen hasn't been saved previously."); + return; + } + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 1) || (opacity > 100)) + quit("!RawRestoreScreenTinted: invalid parameter. R,G,B must be 0-255, opacity 1-100"); + + debug_script_log("RawRestoreTinted RGB(%d,%d,%d) %d%%", red, green, blue, opacity); + + PBitmap deston = thisroom.BgFrames[play.bg_frame].Graphic; + tint_image(deston.get(), raw_saved_screen, red, green, blue, opacity); + invalidate_screen(); + mark_current_background_dirty(); } -void RawDrawFrameTransparent (int frame, int translev) { - if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount) || - (translev < 0) || (translev > 99)) - quit("!RawDrawFrameTransparent: invalid parameter (transparency must be 0-99, frame a valid BG frame)"); - - PBitmap bg = thisroom.BgFrames[frame].Graphic; - if (bg->GetColorDepth() <= 8) - quit("!RawDrawFrameTransparent: 256-colour backgrounds not supported"); - - if (frame == play.bg_frame) - quit("!RawDrawFrameTransparent: cannot draw current background onto itself"); - - RAW_START(); - if (translev == 0) - { - // just draw it over the top, no transparency - RAW_SURFACE()->Blit(bg.get(), 0, 0, 0, 0, bg->GetWidth(), bg->GetHeight()); - } - else - { - // Draw it transparently - GfxUtil::DrawSpriteWithTransparency (RAW_SURFACE(), bg.get(), 0, 0, - GfxDef::Trans100ToAlpha255(translev)); - } - invalidate_screen(); - mark_current_background_dirty(); - RAW_END(); +void RawDrawFrameTransparent(int frame, int translev) { + if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount) || + (translev < 0) || (translev > 99)) + quit("!RawDrawFrameTransparent: invalid parameter (transparency must be 0-99, frame a valid BG frame)"); + + PBitmap bg = thisroom.BgFrames[frame].Graphic; + if (bg->GetColorDepth() <= 8) + quit("!RawDrawFrameTransparent: 256-colour backgrounds not supported"); + + if (frame == play.bg_frame) + quit("!RawDrawFrameTransparent: cannot draw current background onto itself"); + + RAW_START(); + if (translev == 0) { + // just draw it over the top, no transparency + RAW_SURFACE()->Blit(bg.get(), 0, 0, 0, 0, bg->GetWidth(), bg->GetHeight()); + } else { + // Draw it transparently + GfxUtil::DrawSpriteWithTransparency(RAW_SURFACE(), bg.get(), 0, 0, + GfxDef::Trans100ToAlpha255(translev)); + } + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); } -void RawClear (int clr) { - RAW_START(); - clr = RAW_SURFACE()->GetCompatibleColor(clr); - RAW_SURFACE()->Clear (clr); - invalidate_screen(); - mark_current_background_dirty(); +void RawClear(int clr) { + RAW_START(); + clr = RAW_SURFACE()->GetCompatibleColor(clr); + RAW_SURFACE()->Clear(clr); + invalidate_screen(); + mark_current_background_dirty(); } -void RawSetColor (int clr) { - // set the colour at the appropriate depth for the background - play.raw_color = MakeColor(clr); +void RawSetColor(int clr) { + // set the colour at the appropriate depth for the background + play.raw_color = MakeColor(clr); } void RawSetColorRGB(int red, int grn, int blu) { - if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) || - (blu < 0) || (blu > 255)) - quit("!RawSetColorRGB: colour values must be 0-255"); + if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) || + (blu < 0) || (blu > 255)) + quit("!RawSetColorRGB: colour values must be 0-255"); - play.raw_color = makecol_depth(thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth(), red, grn, blu); + play.raw_color = makecol_depth(thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth(), red, grn, blu); } -void RawPrint (int xx, int yy, const char *text) { - RAW_START(); - // don't use wtextcolor because it will do a 16->32 conversion - color_t text_color = play.raw_color; - if ((RAW_SURFACE()->GetColorDepth() <= 8) && (play.raw_color > 255)) { - text_color = RAW_SURFACE()->GetCompatibleColor(1); - debug_script_warn ("RawPrint: Attempted to use hi-color on 256-col background"); - } - data_to_game_coords(&xx, &yy); - wouttext_outline(RAW_SURFACE(), xx, yy, play.normal_font, text_color, text); - // we must invalidate the entire screen because these are room - // co-ordinates, not screen co-ords which it works with - invalidate_screen(); - mark_current_background_dirty(); - RAW_END(); +void RawPrint(int xx, int yy, const char *text) { + RAW_START(); + // don't use wtextcolor because it will do a 16->32 conversion + color_t text_color = play.raw_color; + if ((RAW_SURFACE()->GetColorDepth() <= 8) && (play.raw_color > 255)) { + text_color = RAW_SURFACE()->GetCompatibleColor(1); + debug_script_warn("RawPrint: Attempted to use hi-color on 256-col background"); + } + data_to_game_coords(&xx, &yy); + wouttext_outline(RAW_SURFACE(), xx, yy, play.normal_font, text_color, text); + // we must invalidate the entire screen because these are room + // co-ordinates, not screen co-ords which it works with + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); } -void RawPrintMessageWrapped (int xx, int yy, int wid, int font, int msgm) { - char displbuf[3000]; - int linespacing = getfontspacing_outlined(font); - data_to_game_coords(&xx, &yy); - wid = data_to_game_coord(wid); - - get_message_text (msgm, displbuf); - // it's probably too late but check anyway - if (strlen(displbuf) > 2899) - quit("!RawPrintMessageWrapped: message too long"); - if (break_up_text_into_lines(displbuf, Lines, wid, font) == 0) - return; - - RAW_START(); - color_t text_color = play.raw_color; - for (size_t i = 0; i < Lines.Count(); i++) - wouttext_outline(RAW_SURFACE(), xx, yy + linespacing*i, font, text_color, Lines[i]); - invalidate_screen(); - mark_current_background_dirty(); - RAW_END(); +void RawPrintMessageWrapped(int xx, int yy, int wid, int font, int msgm) { + char displbuf[3000]; + int linespacing = getfontspacing_outlined(font); + data_to_game_coords(&xx, &yy); + wid = data_to_game_coord(wid); + + get_message_text(msgm, displbuf); + // it's probably too late but check anyway + if (strlen(displbuf) > 2899) + quit("!RawPrintMessageWrapped: message too long"); + if (break_up_text_into_lines(displbuf, Lines, wid, font) == 0) + return; + + RAW_START(); + color_t text_color = play.raw_color; + for (size_t i = 0; i < Lines.Count(); i++) + wouttext_outline(RAW_SURFACE(), xx, yy + linespacing * i, font, text_color, Lines[i]); + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); } void RawDrawImageCore(int xx, int yy, int slot, int alpha) { - if ((slot < 0) || (spriteset[slot] == nullptr)) - quit("!RawDrawImage: invalid sprite slot number specified"); - RAW_START(); - - if (spriteset[slot]->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) { - debug_script_warn("RawDrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", slot, spriteset[slot]->GetColorDepth(), RAW_SURFACE()->GetColorDepth()); - } - - draw_sprite_slot_support_alpha(RAW_SURFACE(), false, xx, yy, slot, kBlendMode_Alpha, alpha); - invalidate_screen(); - mark_current_background_dirty(); - RAW_END(); + if ((slot < 0) || (spriteset[slot] == nullptr)) + quit("!RawDrawImage: invalid sprite slot number specified"); + RAW_START(); + + if (spriteset[slot]->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) { + debug_script_warn("RawDrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", slot, spriteset[slot]->GetColorDepth(), RAW_SURFACE()->GetColorDepth()); + } + + draw_sprite_slot_support_alpha(RAW_SURFACE(), false, xx, yy, slot, kBlendMode_Alpha, alpha); + invalidate_screen(); + mark_current_background_dirty(); + RAW_END(); } void RawDrawImage(int xx, int yy, int slot) { - data_to_game_coords(&xx, &yy); - RawDrawImageCore(xx, yy, slot); + data_to_game_coords(&xx, &yy); + RawDrawImageCore(xx, yy, slot); } void RawDrawImageTrans(int xx, int yy, int slot, int alpha) { - data_to_game_coords(&xx, &yy); - RawDrawImageCore(xx, yy, slot, alpha); + data_to_game_coords(&xx, &yy); + RawDrawImageCore(xx, yy, slot, alpha); } void RawDrawImageOffset(int xx, int yy, int slot) { - // This function takes coordinates in real game coordinates as opposed to script coordinates - defgame_to_finalgame_coords(xx, yy); - RawDrawImageCore(xx, yy, slot); + // This function takes coordinates in real game coordinates as opposed to script coordinates + defgame_to_finalgame_coords(xx, yy); + RawDrawImageCore(xx, yy, slot); } void RawDrawImageTransparent(int xx, int yy, int slot, int legacy_transparency) { - if ((legacy_transparency < 0) || (legacy_transparency > 100)) - quit("!RawDrawImageTransparent: invalid transparency setting"); - - // WARNING: the previous versions of AGS actually had a bug: - // although manual stated that RawDrawImageTransparent takes % of transparency - // as an argument, that value was used improperly when setting up an Allegro's - // trans_blender, which caused it to act about as % of opacity instead, but - // with a twist. - // - // It was converted to 255-ranged "transparency" parameter: - // int transparency = (trans * 255) / 100; - // - // Note by CJ: - // Transparency is a bit counter-intuitive - // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible - // - // In order to support this backward-compatible behavior, we convert the - // opacity into proper alpha this way: - // 0 => alpha 255 - // 100 => alpha 0 - // 1 - 99 => alpha 1 - 244 - // - RawDrawImageTrans(xx, yy, slot, GfxDef::LegacyTrans100ToAlpha255(legacy_transparency)); - - update_polled_stuff_if_runtime(); // this operation can be slow so stop music skipping + if ((legacy_transparency < 0) || (legacy_transparency > 100)) + quit("!RawDrawImageTransparent: invalid transparency setting"); + + // WARNING: the previous versions of AGS actually had a bug: + // although manual stated that RawDrawImageTransparent takes % of transparency + // as an argument, that value was used improperly when setting up an Allegro's + // trans_blender, which caused it to act about as % of opacity instead, but + // with a twist. + // + // It was converted to 255-ranged "transparency" parameter: + // int transparency = (trans * 255) / 100; + // + // Note by CJ: + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + // + // In order to support this backward-compatible behavior, we convert the + // opacity into proper alpha this way: + // 0 => alpha 255 + // 100 => alpha 0 + // 1 - 99 => alpha 1 - 244 + // + RawDrawImageTrans(xx, yy, slot, GfxDef::LegacyTrans100ToAlpha255(legacy_transparency)); + + update_polled_stuff_if_runtime(); // this operation can be slow so stop music skipping } void RawDrawImageResized(int xx, int yy, int gotSlot, int width, int height) { - if ((gotSlot < 0) || (spriteset[gotSlot] == nullptr)) - quit("!RawDrawImageResized: invalid sprite slot number specified"); - // very small, don't draw it - if ((width < 1) || (height < 1)) - return; - - data_to_game_coords(&xx, &yy); - data_to_game_coords(&width, &height); - - // resize the sprite to the requested size - Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); - newPic->StretchBlt(spriteset[gotSlot], - RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), - RectWH(0, 0, width, height)); - - RAW_START(); - if (newPic->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) - quit("!RawDrawImageResized: image colour depth mismatch: the background image must have the same colour depth as the sprite being drawn"); - - GfxUtil::DrawSpriteWithTransparency(RAW_SURFACE(), newPic, xx, yy); - delete newPic; - invalidate_screen(); - mark_current_background_dirty(); - update_polled_stuff_if_runtime(); // this operation can be slow so stop music skipping - RAW_END(); + if ((gotSlot < 0) || (spriteset[gotSlot] == nullptr)) + quit("!RawDrawImageResized: invalid sprite slot number specified"); + // very small, don't draw it + if ((width < 1) || (height < 1)) + return; + + data_to_game_coords(&xx, &yy); + data_to_game_coords(&width, &height); + + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); + newPic->StretchBlt(spriteset[gotSlot], + RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), + RectWH(0, 0, width, height)); + + RAW_START(); + if (newPic->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) + quit("!RawDrawImageResized: image colour depth mismatch: the background image must have the same colour depth as the sprite being drawn"); + + GfxUtil::DrawSpriteWithTransparency(RAW_SURFACE(), newPic, xx, yy); + delete newPic; + invalidate_screen(); + mark_current_background_dirty(); + update_polled_stuff_if_runtime(); // this operation can be slow so stop music skipping + RAW_END(); } -void RawDrawLine (int fromx, int fromy, int tox, int toy) { - data_to_game_coords(&fromx, &fromy); - data_to_game_coords(&tox, &toy); - - play.raw_modified[play.bg_frame] = 1; - int ii,jj; - // draw a line thick enough to look the same at all resolutions - PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; - color_t draw_color = play.raw_color; - for (ii = 0; ii < get_fixed_pixel_size(1); ii++) { - for (jj = 0; jj < get_fixed_pixel_size(1); jj++) - bg->DrawLine (Line(fromx+ii, fromy+jj, tox+ii, toy+jj), draw_color); - } - invalidate_screen(); - mark_current_background_dirty(); +void RawDrawLine(int fromx, int fromy, int tox, int toy) { + data_to_game_coords(&fromx, &fromy); + data_to_game_coords(&tox, &toy); + + play.raw_modified[play.bg_frame] = 1; + int ii, jj; + // draw a line thick enough to look the same at all resolutions + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + color_t draw_color = play.raw_color; + for (ii = 0; ii < get_fixed_pixel_size(1); ii++) { + for (jj = 0; jj < get_fixed_pixel_size(1); jj++) + bg->DrawLine(Line(fromx + ii, fromy + jj, tox + ii, toy + jj), draw_color); + } + invalidate_screen(); + mark_current_background_dirty(); } -void RawDrawCircle (int xx, int yy, int rad) { - data_to_game_coords(&xx, &yy); - rad = data_to_game_coord(rad); - - play.raw_modified[play.bg_frame] = 1; - PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; - bg->FillCircle(Circle (xx, yy, rad), play.raw_color); - invalidate_screen(); - mark_current_background_dirty(); +void RawDrawCircle(int xx, int yy, int rad) { + data_to_game_coords(&xx, &yy); + rad = data_to_game_coord(rad); + + play.raw_modified[play.bg_frame] = 1; + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + bg->FillCircle(Circle(xx, yy, rad), play.raw_color); + invalidate_screen(); + mark_current_background_dirty(); } void RawDrawRectangle(int x1, int y1, int x2, int y2) { - play.raw_modified[play.bg_frame] = 1; - data_to_game_coords(&x1, &y1); - data_to_game_round_up(&x2, &y2); - - PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; - bg->FillRect(Rect(x1,y1,x2,y2), play.raw_color); - invalidate_screen(); - mark_current_background_dirty(); + play.raw_modified[play.bg_frame] = 1; + data_to_game_coords(&x1, &y1); + data_to_game_round_up(&x2, &y2); + + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + bg->FillRect(Rect(x1, y1, x2, y2), play.raw_color); + invalidate_screen(); + mark_current_background_dirty(); } void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) { - play.raw_modified[play.bg_frame] = 1; - data_to_game_coords(&x1, &y1); - data_to_game_coords(&x2, &y2); - data_to_game_coords(&x3, &y3); - - PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; - bg->DrawTriangle(Triangle (x1,y1,x2,y2,x3,y3), play.raw_color); - invalidate_screen(); - mark_current_background_dirty(); + play.raw_modified[play.bg_frame] = 1; + data_to_game_coords(&x1, &y1); + data_to_game_coords(&x2, &y2); + data_to_game_coords(&x3, &y3); + + PBitmap bg = thisroom.BgFrames[play.bg_frame].Graphic; + bg->DrawTriangle(Triangle(x1, y1, x2, y2, x3, y3), play.raw_color); + invalidate_screen(); + mark_current_background_dirty(); } diff --git a/engines/ags/engine/ac/global_drawingsurface.h b/engines/ags/engine/ac/global_drawingsurface.h index a65fe88a793e..e9b2626e86a3 100644 --- a/engines/ags/engine/ac/global_drawingsurface.h +++ b/engines/ags/engine/ac/global_drawingsurface.h @@ -23,26 +23,26 @@ #ifndef AGS_ENGINE_AC_GLOBALDRAWINGSURFACE_H #define AGS_ENGINE_AC_GLOBALDRAWINGSURFACE_H -void RawSaveScreen (); +void RawSaveScreen(); // RawRestoreScreen: copy backup bitmap back to screen; we // deliberately don't free the Common::Bitmap *cos they can multiple restore // and it gets freed on room exit anyway void RawRestoreScreen(); // Restores the backup bitmap, but tints it to the specified level void RawRestoreScreenTinted(int red, int green, int blue, int opacity); -void RawDrawFrameTransparent (int frame, int translev); -void RawClear (int clr); -void RawSetColor (int clr); +void RawDrawFrameTransparent(int frame, int translev); +void RawClear(int clr); +void RawSetColor(int clr); void RawSetColorRGB(int red, int grn, int blu); -void RawPrint (int xx, int yy, const char *text); -void RawPrintMessageWrapped (int xx, int yy, int wid, int font, int msgm); +void RawPrint(int xx, int yy, const char *text); +void RawPrintMessageWrapped(int xx, int yy, int wid, int font, int msgm); void RawDrawImageCore(int xx, int yy, int slot, int alpha = 0xFF); void RawDrawImage(int xx, int yy, int slot); void RawDrawImageOffset(int xx, int yy, int slot); void RawDrawImageTransparent(int xx, int yy, int slot, int opacity); void RawDrawImageResized(int xx, int yy, int gotSlot, int width, int height); -void RawDrawLine (int fromx, int fromy, int tox, int toy); -void RawDrawCircle (int xx, int yy, int rad); +void RawDrawLine(int fromx, int fromy, int tox, int toy); +void RawDrawCircle(int xx, int yy, int rad); void RawDrawRectangle(int x1, int y1, int x2, int y2); void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3); diff --git a/engines/ags/engine/ac/global_dynamicsprite.cpp b/engines/ags/engine/ac/global_dynamicsprite.cpp index 00898e7cfc13..4ecd20bf5d04 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.cpp +++ b/engines/ags/engine/ac/global_dynamicsprite.cpp @@ -36,23 +36,22 @@ using namespace AGS::Engine; extern SpriteCache spriteset; extern IGraphicsDriver *gfxDriver; -int LoadImageFile(const char *filename) -{ - ResolvedPath rp; - if (!ResolveScriptPath(filename, true, rp)) - return 0; +int LoadImageFile(const char *filename) { + ResolvedPath rp; + if (!ResolveScriptPath(filename, true, rp)) + return 0; - Bitmap *loadedFile = BitmapHelper::LoadFromFile(rp.FullPath); - if (!loadedFile && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) - loadedFile = BitmapHelper::LoadFromFile(rp.AltPath); - if (!loadedFile) - return 0; + Bitmap *loadedFile = BitmapHelper::LoadFromFile(rp.FullPath); + if (!loadedFile && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) + loadedFile = BitmapHelper::LoadFromFile(rp.AltPath); + if (!loadedFile) + return 0; - int gotSlot = spriteset.GetFreeIndex(); - if (gotSlot <= 0) - return 0; + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return 0; - add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(loadedFile)); + add_dynamic_sprite(gotSlot, ReplaceBitmapWithSupportedFormat(loadedFile)); - return gotSlot; + return gotSlot; } diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index d2fb8775b4b7..47670c712a6e 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -34,152 +34,143 @@ using namespace AGS::Common; -int32_t FileOpenCMode(const char*fnmm, const char* cmode) -{ - Common::FileOpenMode open_mode; - Common::FileWorkMode work_mode; - // NOTE: here we ignore the text-mode flag. AGS 2.62 did not let - // game devs to open files in text mode. The file reading and - // writing logic in AGS makes extra control characters added for - // security reasons, and FileWriteRawLine adds CR/LF to the end - // of string on its own. - if (!Common::File::GetFileModesFromCMode(cmode, open_mode, work_mode)) - { - return 0; - } - return FileOpen(fnmm, open_mode, work_mode); +int32_t FileOpenCMode(const char *fnmm, const char *cmode) { + Common::FileOpenMode open_mode; + Common::FileWorkMode work_mode; + // NOTE: here we ignore the text-mode flag. AGS 2.62 did not let + // game devs to open files in text mode. The file reading and + // writing logic in AGS makes extra control characters added for + // security reasons, and FileWriteRawLine adds CR/LF to the end + // of string on its own. + if (!Common::File::GetFileModesFromCMode(cmode, open_mode, work_mode)) { + return 0; + } + return FileOpen(fnmm, open_mode, work_mode); } // Find a free file slot to use -int32_t FindFreeFileSlot() -{ - int useindx = 0; - for (; useindx < num_open_script_files; useindx++) - { - if (valid_handles[useindx].stream == nullptr) - break; - } - - if (useindx >= num_open_script_files && - num_open_script_files >= MAX_OPEN_SCRIPT_FILES) - { - quit("!FileOpen: tried to open more than 10 files simultaneously - close some first"); - return -1; - } - return useindx; +int32_t FindFreeFileSlot() { + int useindx = 0; + for (; useindx < num_open_script_files; useindx++) { + if (valid_handles[useindx].stream == nullptr) + break; + } + + if (useindx >= num_open_script_files && + num_open_script_files >= MAX_OPEN_SCRIPT_FILES) { + quit("!FileOpen: tried to open more than 10 files simultaneously - close some first"); + return -1; + } + return useindx; } -int32_t FileOpen(const char*fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode) -{ - int32_t useindx = FindFreeFileSlot(); - if (useindx < 0) - return 0; - - ResolvedPath rp; - if (open_mode == kFile_Open && work_mode == kFile_Read) - { - if (!ResolveScriptPath(fnmm, true, rp)) - return 0; - } - else - { - if (!ResolveWritePathAndCreateDirs(fnmm, rp)) - return 0; - } - - Stream *s = File::OpenFile(rp.FullPath, open_mode, work_mode); - if (!s && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) - s = File::OpenFile(rp.AltPath, open_mode, work_mode); - - valid_handles[useindx].stream = s; - if (valid_handles[useindx].stream == nullptr) - return 0; - valid_handles[useindx].handle = useindx + 1; // make handle indexes 1-based - - if (useindx >= num_open_script_files) - num_open_script_files++; - return valid_handles[useindx].handle; +int32_t FileOpen(const char *fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode) { + int32_t useindx = FindFreeFileSlot(); + if (useindx < 0) + return 0; + + ResolvedPath rp; + if (open_mode == kFile_Open && work_mode == kFile_Read) { + if (!ResolveScriptPath(fnmm, true, rp)) + return 0; + } else { + if (!ResolveWritePathAndCreateDirs(fnmm, rp)) + return 0; + } + + Stream *s = File::OpenFile(rp.FullPath, open_mode, work_mode); + if (!s && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) + s = File::OpenFile(rp.AltPath, open_mode, work_mode); + + valid_handles[useindx].stream = s; + if (valid_handles[useindx].stream == nullptr) + return 0; + valid_handles[useindx].handle = useindx + 1; // make handle indexes 1-based + + if (useindx >= num_open_script_files) + num_open_script_files++; + return valid_handles[useindx].handle; } void FileClose(int32_t handle) { - ScriptFileHandle *sc_handle = check_valid_file_handle_int32(handle,"FileClose"); - delete sc_handle->stream; - sc_handle->stream = nullptr; - sc_handle->handle = 0; - } + ScriptFileHandle *sc_handle = check_valid_file_handle_int32(handle, "FileClose"); + delete sc_handle->stream; + sc_handle->stream = nullptr; + sc_handle->handle = 0; +} void FileWrite(int32_t handle, const char *towrite) { - Stream *out = get_valid_file_stream_from_handle(handle,"FileWrite"); - out->WriteInt32(strlen(towrite)+1); - out->Write(towrite,strlen(towrite)+1); - } -void FileWriteRawLine(int32_t handle, const char*towrite) { - Stream *out = get_valid_file_stream_from_handle(handle,"FileWriteRawLine"); - out->Write(towrite,strlen(towrite)); - out->WriteInt8 (13); - out->WriteInt8 (10); - } -void FileRead(int32_t handle,char*toread) { - VALIDATE_STRING(toread); - Stream *in = get_valid_file_stream_from_handle(handle,"FileRead"); - if (in->EOS()) { - toread[0] = 0; - return; - } - int lle=in->ReadInt32(); - if ((lle>=200) | (lle<1)) quit("!FileRead: file was not written by FileWrite"); - in->Read(toread,lle); - } -int FileIsEOF (int32_t handle) { - Stream *stream = get_valid_file_stream_from_handle(handle,"FileIsEOF"); - if (stream->EOS()) - return 1; - - // TODO: stream errors - if (stream->HasErrors()) - return 1; - - if (stream->GetPosition () >= stream->GetLength()) - return 1; - return 0; + Stream *out = get_valid_file_stream_from_handle(handle, "FileWrite"); + out->WriteInt32(strlen(towrite) + 1); + out->Write(towrite, strlen(towrite) + 1); +} +void FileWriteRawLine(int32_t handle, const char *towrite) { + Stream *out = get_valid_file_stream_from_handle(handle, "FileWriteRawLine"); + out->Write(towrite, strlen(towrite)); + out->WriteInt8(13); + out->WriteInt8(10); +} +void FileRead(int32_t handle, char *toread) { + VALIDATE_STRING(toread); + Stream *in = get_valid_file_stream_from_handle(handle, "FileRead"); + if (in->EOS()) { + toread[0] = 0; + return; + } + int lle = in->ReadInt32(); + if ((lle >= 200) | (lle < 1)) quit("!FileRead: file was not written by FileWrite"); + in->Read(toread, lle); +} +int FileIsEOF(int32_t handle) { + Stream *stream = get_valid_file_stream_from_handle(handle, "FileIsEOF"); + if (stream->EOS()) + return 1; + + // TODO: stream errors + if (stream->HasErrors()) + return 1; + + if (stream->GetPosition() >= stream->GetLength()) + return 1; + return 0; } int FileIsError(int32_t handle) { - Stream *stream = get_valid_file_stream_from_handle(handle,"FileIsError"); + Stream *stream = get_valid_file_stream_from_handle(handle, "FileIsError"); - // TODO: stream errors - if (stream->HasErrors()) - return 1; + // TODO: stream errors + if (stream->HasErrors()) + return 1; - return 0; + return 0; +} +void FileWriteInt(int32_t handle, int into) { + Stream *out = get_valid_file_stream_from_handle(handle, "FileWriteInt"); + out->WriteInt8('I'); + out->WriteInt32(into); } -void FileWriteInt(int32_t handle,int into) { - Stream *out = get_valid_file_stream_from_handle(handle,"FileWriteInt"); - out->WriteInt8('I'); - out->WriteInt32(into); - } int FileReadInt(int32_t handle) { - Stream *in = get_valid_file_stream_from_handle(handle,"FileReadInt"); - if (in->EOS()) - return -1; - if (in->ReadInt8()!='I') - quit("!FileReadInt: File read back in wrong order"); - return in->ReadInt32(); - } + Stream *in = get_valid_file_stream_from_handle(handle, "FileReadInt"); + if (in->EOS()) + return -1; + if (in->ReadInt8() != 'I') + quit("!FileReadInt: File read back in wrong order"); + return in->ReadInt32(); +} char FileReadRawChar(int32_t handle) { - Stream *in = get_valid_file_stream_from_handle(handle,"FileReadRawChar"); - if (in->EOS()) - return -1; - return in->ReadInt8(); - } + Stream *in = get_valid_file_stream_from_handle(handle, "FileReadRawChar"); + if (in->EOS()) + return -1; + return in->ReadInt8(); +} int FileReadRawInt(int32_t handle) { - Stream *in = get_valid_file_stream_from_handle(handle,"FileReadRawInt"); - if (in->EOS()) - return -1; - return in->ReadInt32(); + Stream *in = get_valid_file_stream_from_handle(handle, "FileReadRawInt"); + if (in->EOS()) + return -1; + return in->ReadInt32(); } void FileWriteRawChar(int32_t handle, int chartoWrite) { - Stream *out = get_valid_file_stream_from_handle(handle,"FileWriteRawChar"); - if ((chartoWrite < 0) || (chartoWrite > 255)) - quit("!FileWriteRawChar: can only write values 0-255"); + Stream *out = get_valid_file_stream_from_handle(handle, "FileWriteRawChar"); + if ((chartoWrite < 0) || (chartoWrite > 255)) + quit("!FileWriteRawChar: can only write values 0-255"); - out->WriteInt8(chartoWrite); + out->WriteInt8(chartoWrite); } diff --git a/engines/ags/engine/ac/global_file.h b/engines/ags/engine/ac/global_file.h index 7f5b59ee5dbe..3e58cfdc1035 100644 --- a/engines/ags/engine/ac/global_file.h +++ b/engines/ags/engine/ac/global_file.h @@ -25,19 +25,23 @@ #include "util/file.h" -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later -int32_t FileOpen(const char*fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); +int32_t FileOpen(const char *fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen -int32_t FileOpenCMode(const char*fnmm, const char* cmode); +int32_t FileOpenCMode(const char *fnmm, const char *cmode); void FileClose(int32_t handle); void FileWrite(int32_t handle, const char *towrite); -void FileWriteRawLine(int32_t handle, const char*towrite); -void FileRead(int32_t handle,char*toread); -int FileIsEOF (int32_t handle); +void FileWriteRawLine(int32_t handle, const char *towrite); +void FileRead(int32_t handle, char *toread); +int FileIsEOF(int32_t handle); int FileIsError(int32_t handle); -void FileWriteInt(int32_t handle,int into); +void FileWriteInt(int32_t handle, int into); int FileReadInt(int32_t handle); char FileReadRawChar(int32_t handle); int FileReadRawInt(int32_t handle); diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 1939308192c4..afeea81d3ba0 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -74,7 +74,7 @@ using namespace AGS::Common; #define ALLEGRO_KEYBOARD_HANDLER extern GameState play; -extern ExecutingScript*curscript; +extern ExecutingScript *curscript; extern int displayed_room; extern int game_paused; extern SpriteCache spriteset; @@ -83,8 +83,8 @@ extern GameSetup usetup; extern unsigned int load_new_game; extern int load_new_game_restore; extern GameSetupStruct game; -extern ViewStruct*views; -extern RoomStatus*croom; +extern ViewStruct *views; +extern RoomStatus *croom; extern int gui_disabled_style; extern RoomStruct thisroom; extern int getloctype_index; @@ -95,869 +95,1050 @@ extern color palette[256]; extern int psp_gfx_renderer; #endif -void GiveScore(int amnt) -{ - guis_need_update = 1; - play.score += amnt; +void GiveScore(int amnt) { + guis_need_update = 1; + play.score += amnt; - if ((amnt > 0) && (play.score_sound >= 0)) - play_audio_clip_by_index(play.score_sound); + if ((amnt > 0) && (play.score_sound >= 0)) + play_audio_clip_by_index(play.score_sound); - run_on_event (GE_GOT_SCORE, RuntimeScriptValue().SetInt32(amnt)); + run_on_event(GE_GOT_SCORE, RuntimeScriptValue().SetInt32(amnt)); } void restart_game() { - can_run_delayed_command(); - if (inside_script) { - curscript->queue_action(ePSARestartGame, 0, "RestartGame"); - return; - } - try_restore_save(RESTART_POINT_SAVE_GAME_NUMBER); + can_run_delayed_command(); + if (inside_script) { + curscript->queue_action(ePSARestartGame, 0, "RestartGame"); + return; + } + try_restore_save(RESTART_POINT_SAVE_GAME_NUMBER); } void RestoreGameSlot(int slnum) { - if (displayed_room < 0) - quit("!RestoreGameSlot: a game cannot be restored from within game_start"); - - can_run_delayed_command(); - if (inside_script) { - curscript->queue_action(ePSARestoreGame, slnum, "RestoreGameSlot"); - return; - } - try_restore_save(slnum); -} - -void DeleteSaveSlot (int slnum) { - String nametouse; - nametouse = get_save_game_path(slnum); - ::remove (nametouse); - if ((slnum >= 1) && (slnum <= MAXSAVEGAMES)) { - String thisname; - for (int i = MAXSAVEGAMES; i > slnum; i--) { - thisname = get_save_game_path(i); - if (Common::File::TestReadFile(thisname)) { - // Rename the highest save game to fill in the gap - rename (thisname, nametouse); - break; - } - } - - } + if (displayed_room < 0) + quit("!RestoreGameSlot: a game cannot be restored from within game_start"); + + can_run_delayed_command(); + if (inside_script) { + curscript->queue_action(ePSARestoreGame, slnum, "RestoreGameSlot"); + return; + } + try_restore_save(slnum); +} + +void DeleteSaveSlot(int slnum) { + String nametouse; + nametouse = get_save_game_path(slnum); + ::remove(nametouse); + if ((slnum >= 1) && (slnum <= MAXSAVEGAMES)) { + String thisname; + for (int i = MAXSAVEGAMES; i > slnum; i--) { + thisname = get_save_game_path(i); + if (Common::File::TestReadFile(thisname)) { + // Rename the highest save game to fill in the gap + rename(thisname, nametouse); + break; + } + } + + } } void PauseGame() { - game_paused++; - debug_script_log("Game paused"); + game_paused++; + debug_script_log("Game paused"); } void UnPauseGame() { - if (game_paused > 0) - game_paused--; - debug_script_log("Game UnPaused, pause level now %d", game_paused); + if (game_paused > 0) + game_paused--; + debug_script_log("Game UnPaused, pause level now %d", game_paused); } int IsGamePaused() { - if (game_paused>0) return 1; - return 0; + if (game_paused > 0) return 1; + return 0; } -int GetSaveSlotDescription(int slnum,char*desbuf) { - VALIDATE_STRING(desbuf); - String description; - if (read_savedgame_description(get_save_game_path(slnum), description)) - { - strcpy(desbuf, description); - return 1; - } - sprintf(desbuf,"INVALID SLOT %d", slnum); - return 0; +int GetSaveSlotDescription(int slnum, char *desbuf) { + VALIDATE_STRING(desbuf); + String description; + if (read_savedgame_description(get_save_game_path(slnum), description)) { + strcpy(desbuf, description); + return 1; + } + sprintf(desbuf, "INVALID SLOT %d", slnum); + return 0; } int LoadSaveSlotScreenshot(int slnum, int width, int height) { - int gotSlot; - data_to_game_coords(&width, &height); + int gotSlot; + data_to_game_coords(&width, &height); - if (!read_savedgame_screenshot(get_save_game_path(slnum), gotSlot)) - return 0; + if (!read_savedgame_screenshot(get_save_game_path(slnum), gotSlot)) + return 0; - if (gotSlot == 0) - return 0; + if (gotSlot == 0) + return 0; - if ((game.SpriteInfos[gotSlot].Width == width) && (game.SpriteInfos[gotSlot].Height == height)) - return gotSlot; + if ((game.SpriteInfos[gotSlot].Width == width) && (game.SpriteInfos[gotSlot].Height == height)) + return gotSlot; - // resize the sprite to the requested size - Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); - newPic->StretchBlt(spriteset[gotSlot], - RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), - RectWH(0, 0, width, height)); + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); + newPic->StretchBlt(spriteset[gotSlot], + RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), + RectWH(0, 0, width, height)); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - // replace the bitmap in the sprite set - free_dynamic_sprite(gotSlot); - add_dynamic_sprite(gotSlot, newPic); + // replace the bitmap in the sprite set + free_dynamic_sprite(gotSlot); + add_dynamic_sprite(gotSlot, newPic); - return gotSlot; + return gotSlot; } -void SetGlobalInt(int index,int valu) { - if ((index<0) | (index>=MAXGSVALUES)) - quit("!SetGlobalInt: invalid index"); +void SetGlobalInt(int index, int valu) { + if ((index < 0) | (index >= MAXGSVALUES)) + quit("!SetGlobalInt: invalid index"); - if (play.globalscriptvars[index] != valu) { - debug_script_log("GlobalInt %d set to %d", index, valu); - } + if (play.globalscriptvars[index] != valu) { + debug_script_log("GlobalInt %d set to %d", index, valu); + } - play.globalscriptvars[index]=valu; + play.globalscriptvars[index] = valu; } int GetGlobalInt(int index) { - if ((index<0) | (index>=MAXGSVALUES)) - quit("!GetGlobalInt: invalid index"); - return play.globalscriptvars[index]; + if ((index < 0) | (index >= MAXGSVALUES)) + quit("!GetGlobalInt: invalid index"); + return play.globalscriptvars[index]; } -void SetGlobalString (int index, const char *newval) { - if ((index<0) | (index >= MAXGLOBALSTRINGS)) - quit("!SetGlobalString: invalid index"); - debug_script_log("GlobalString %d set to '%s'", index, newval); - strncpy(play.globalstrings[index], newval, MAX_MAXSTRLEN); - // truncate it to 200 chars, to be sure - play.globalstrings[index][MAX_MAXSTRLEN - 1] = 0; +void SetGlobalString(int index, const char *newval) { + if ((index < 0) | (index >= MAXGLOBALSTRINGS)) + quit("!SetGlobalString: invalid index"); + debug_script_log("GlobalString %d set to '%s'", index, newval); + strncpy(play.globalstrings[index], newval, MAX_MAXSTRLEN); + // truncate it to 200 chars, to be sure + play.globalstrings[index][MAX_MAXSTRLEN - 1] = 0; } -void GetGlobalString (int index, char *strval) { - if ((index<0) | (index >= MAXGLOBALSTRINGS)) - quit("!GetGlobalString: invalid index"); - strcpy (strval, play.globalstrings[index]); +void GetGlobalString(int index, char *strval) { + if ((index < 0) | (index >= MAXGLOBALSTRINGS)) + quit("!GetGlobalString: invalid index"); + strcpy(strval, play.globalstrings[index]); } // TODO: refactor this method, and use same shared procedure at both normal stop/startup and in RunAGSGame -int RunAGSGame (const char *newgame, unsigned int mode, int data) { - - can_run_delayed_command(); - - int AllowedModes = RAGMODE_PRESERVEGLOBALINT | RAGMODE_LOADNOW; - - if ((mode & (~AllowedModes)) != 0) - quit("!RunAGSGame: mode value unknown"); - - if (editor_debugging_enabled) - { - quit("!RunAGSGame cannot be used while running the game from within the AGS Editor. You must build the game EXE and run it from there to use this function."); - } - - if ((mode & RAGMODE_LOADNOW) == 0) { - // need to copy, since the script gets destroyed - get_install_dir_path(gamefilenamebuf, newgame); - ResPaths.GamePak.Path = gamefilenamebuf; - ResPaths.GamePak.Name = get_filename(gamefilenamebuf); - play.takeover_data = data; - load_new_game_restore = -1; - - if (inside_script) { - curscript->queue_action(ePSARunAGSGame, mode | RAGMODE_LOADNOW, "RunAGSGame"); - ccInstance::GetCurrentInstance()->Abort(); - } - else - load_new_game = mode | RAGMODE_LOADNOW; - - return 0; - } - - int ee; - - unload_old_room(); - displayed_room = -10; - - save_config_file(); // save current user config in case engine fails to run new game - unload_game_file(); - - // Adjust config (NOTE: normally, RunAGSGame would need a redesign to allow separate config etc per each game) - usetup.translation = ""; // reset to default, prevent from trying translation file of game A in game B - - if (Common::AssetManager::SetDataFile(ResPaths.GamePak.Path) != Common::kAssetNoError) - quitprintf("!RunAGSGame: unable to load new game file '%s'", ResPaths.GamePak.Path.GetCStr()); - - show_preload(); - - HError err = load_game_file(); - if (!err) - quitprintf("!RunAGSGame: error loading new game file:\n%s", err->FullMessage().GetCStr()); - - spriteset.Reset(); - err = spriteset.InitFile(SpriteCache::DefaultSpriteFileName, SpriteCache::DefaultSpriteIndexName); - if (!err) - quitprintf("!RunAGSGame: error loading new sprites:\n%s", err->FullMessage().GetCStr()); - - if ((mode & RAGMODE_PRESERVEGLOBALINT) == 0) { - // reset GlobalInts - for (ee = 0; ee < MAXGSVALUES; ee++) - play.globalscriptvars[ee] = 0; - } - - engine_init_game_settings(); - play.screen_is_faded_out = 1; - - if (load_new_game_restore >= 0) { - try_restore_save(load_new_game_restore); - load_new_game_restore = -1; - } - else - start_game(); - - return 0; -} - -int GetGameParameter (int parm, int data1, int data2, int data3) { - switch (parm) { - case GP_SPRITEWIDTH: - return Game_GetSpriteWidth(data1); - case GP_SPRITEHEIGHT: - return Game_GetSpriteHeight(data1); - case GP_NUMLOOPS: - return Game_GetLoopCountForView(data1); - case GP_NUMFRAMES: - return Game_GetFrameCountForLoop(data1, data2); - case GP_FRAMESPEED: - case GP_FRAMEIMAGE: - case GP_FRAMESOUND: - case GP_ISFRAMEFLIPPED: - { - if ((data1 < 1) || (data1 > game.numviews)) { - quitprintf("!GetGameParameter: invalid view specified (v: %d, l: %d, f: %d)", data1, data2, data3); - } - if ((data2 < 0) || (data2 >= views[data1 - 1].numLoops)) { - quitprintf("!GetGameParameter: invalid loop specified (v: %d, l: %d, f: %d)", data1, data2, data3); - } - if ((data3 < 0) || (data3 >= views[data1 - 1].loops[data2].numFrames)) { - quitprintf("!GetGameParameter: invalid frame specified (v: %d, l: %d, f: %d)", data1, data2, data3); - } - - ViewFrame *pvf = &views[data1 - 1].loops[data2].frames[data3]; - - if (parm == GP_FRAMESPEED) - return pvf->speed; - else if (parm == GP_FRAMEIMAGE) - return pvf->pic; - else if (parm == GP_FRAMESOUND) - return get_old_style_number_for_sound(pvf->sound); - else if (parm == GP_ISFRAMEFLIPPED) - return (pvf->flags & VFLG_FLIPSPRITE) ? 1 : 0; - else - quit("GetGameParameter internal error"); - } - case GP_ISRUNNEXTLOOP: - return Game_GetRunNextSettingForLoop(data1, data2); - case GP_NUMGUIS: - return game.numgui; - case GP_NUMOBJECTS: - return croom->numobj; - case GP_NUMCHARACTERS: - return game.numcharacters; - case GP_NUMINVITEMS: - return game.numinvitems; - default: - quit("!GetGameParameter: unknown parameter specified"); - } - return 0; +int RunAGSGame(const char *newgame, unsigned int mode, int data) { + + can_run_delayed_command(); + + int AllowedModes = RAGMODE_PRESERVEGLOBALINT | RAGMODE_LOADNOW; + + if ((mode & (~AllowedModes)) != 0) + quit("!RunAGSGame: mode value unknown"); + + if (editor_debugging_enabled) { + quit("!RunAGSGame cannot be used while running the game from within the AGS Editor. You must build the game EXE and run it from there to use this function."); + } + + if ((mode & RAGMODE_LOADNOW) == 0) { + // need to copy, since the script gets destroyed + get_install_dir_path(gamefilenamebuf, newgame); + ResPaths.GamePak.Path = gamefilenamebuf; + ResPaths.GamePak.Name = get_filename(gamefilenamebuf); + play.takeover_data = data; + load_new_game_restore = -1; + + if (inside_script) { + curscript->queue_action(ePSARunAGSGame, mode | RAGMODE_LOADNOW, "RunAGSGame"); + ccInstance::GetCurrentInstance()->Abort(); + } else + load_new_game = mode | RAGMODE_LOADNOW; + + return 0; + } + + int ee; + + unload_old_room(); + displayed_room = -10; + + save_config_file(); // save current user config in case engine fails to run new game + unload_game_file(); + + // Adjust config (NOTE: normally, RunAGSGame would need a redesign to allow separate config etc per each game) + usetup.translation = ""; // reset to default, prevent from trying translation file of game A in game B + + if (Common::AssetManager::SetDataFile(ResPaths.GamePak.Path) != Common::kAssetNoError) + quitprintf("!RunAGSGame: unable to load new game file '%s'", ResPaths.GamePak.Path.GetCStr()); + + show_preload(); + + HError err = load_game_file(); + if (!err) + quitprintf("!RunAGSGame: error loading new game file:\n%s", err->FullMessage().GetCStr()); + + spriteset.Reset(); + err = spriteset.InitFile(SpriteCache::DefaultSpriteFileName, SpriteCache::DefaultSpriteIndexName); + if (!err) + quitprintf("!RunAGSGame: error loading new sprites:\n%s", err->FullMessage().GetCStr()); + + if ((mode & RAGMODE_PRESERVEGLOBALINT) == 0) { + // reset GlobalInts + for (ee = 0; ee < MAXGSVALUES; ee++) + play.globalscriptvars[ee] = 0; + } + + engine_init_game_settings(); + play.screen_is_faded_out = 1; + + if (load_new_game_restore >= 0) { + try_restore_save(load_new_game_restore); + load_new_game_restore = -1; + } else + start_game(); + + return 0; +} + +int GetGameParameter(int parm, int data1, int data2, int data3) { + switch (parm) { + case GP_SPRITEWIDTH: + return Game_GetSpriteWidth(data1); + case GP_SPRITEHEIGHT: + return Game_GetSpriteHeight(data1); + case GP_NUMLOOPS: + return Game_GetLoopCountForView(data1); + case GP_NUMFRAMES: + return Game_GetFrameCountForLoop(data1, data2); + case GP_FRAMESPEED: + case GP_FRAMEIMAGE: + case GP_FRAMESOUND: + case GP_ISFRAMEFLIPPED: { + if ((data1 < 1) || (data1 > game.numviews)) { + quitprintf("!GetGameParameter: invalid view specified (v: %d, l: %d, f: %d)", data1, data2, data3); + } + if ((data2 < 0) || (data2 >= views[data1 - 1].numLoops)) { + quitprintf("!GetGameParameter: invalid loop specified (v: %d, l: %d, f: %d)", data1, data2, data3); + } + if ((data3 < 0) || (data3 >= views[data1 - 1].loops[data2].numFrames)) { + quitprintf("!GetGameParameter: invalid frame specified (v: %d, l: %d, f: %d)", data1, data2, data3); + } + + ViewFrame *pvf = &views[data1 - 1].loops[data2].frames[data3]; + + if (parm == GP_FRAMESPEED) + return pvf->speed; + else if (parm == GP_FRAMEIMAGE) + return pvf->pic; + else if (parm == GP_FRAMESOUND) + return get_old_style_number_for_sound(pvf->sound); + else if (parm == GP_ISFRAMEFLIPPED) + return (pvf->flags & VFLG_FLIPSPRITE) ? 1 : 0; + else + quit("GetGameParameter internal error"); + } + case GP_ISRUNNEXTLOOP: + return Game_GetRunNextSettingForLoop(data1, data2); + case GP_NUMGUIS: + return game.numgui; + case GP_NUMOBJECTS: + return croom->numobj; + case GP_NUMCHARACTERS: + return game.numcharacters; + case GP_NUMINVITEMS: + return game.numinvitems; + default: + quit("!GetGameParameter: unknown parameter specified"); + } + return 0; } void QuitGame(int dialog) { - if (dialog) { - int rcode; - setup_for_dialog(); - rcode=quitdialog(); - restore_after_dialog(); - if (rcode==0) return; - } - quit("|You have exited."); + if (dialog) { + int rcode; + setup_for_dialog(); + rcode = quitdialog(); + restore_after_dialog(); + if (rcode == 0) return; + } + quit("|You have exited."); } void SetRestartPoint() { - save_game(RESTART_POINT_SAVE_GAME_NUMBER, "Restart Game Auto-Save"); + save_game(RESTART_POINT_SAVE_GAME_NUMBER, "Restart Game Auto-Save"); } void SetGameSpeed(int newspd) { - newspd += play.game_speed_modifier; - if (newspd>1000) newspd=1000; - if (newspd<10) newspd=10; - set_game_speed(newspd); - debug_script_log("Game speed set to %d", newspd); + newspd += play.game_speed_modifier; + if (newspd > 1000) newspd = 1000; + if (newspd < 10) newspd = 10; + set_game_speed(newspd); + debug_script_log("Game speed set to %d", newspd); } int GetGameSpeed() { - return ::lround(get_current_fps()) - play.game_speed_modifier; + return ::lround(get_current_fps()) - play.game_speed_modifier; } -int SetGameOption (int opt, int setting) { - if (((opt < 1) || (opt > OPT_HIGHESTOPTION)) && (opt != OPT_LIPSYNCTEXT)) - quit("!SetGameOption: invalid option specified"); - - if (opt == OPT_ANTIGLIDE) - { - for (int i = 0; i < game.numcharacters; i++) - { - if (setting) - game.chars[i].flags |= CHF_ANTIGLIDE; - else - game.chars[i].flags &= ~CHF_ANTIGLIDE; - } - } - - if ((opt == OPT_CROSSFADEMUSIC) && (game.audioClipTypes.size() > AUDIOTYPE_LEGACY_MUSIC)) - { - // legacy compatibility -- changing crossfade speed here also - // updates the new audio clip type style - game.audioClipTypes[AUDIOTYPE_LEGACY_MUSIC].crossfadeSpeed = setting; - } - - int oldval = game.options[opt]; - game.options[opt] = setting; - - if (opt == OPT_DUPLICATEINV) - update_invorder(); - else if (opt == OPT_DISABLEOFF) - gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); - else if (opt == OPT_PORTRAITSIDE) { - if (setting == 0) // set back to Left - play.swap_portrait_side = 0; - } - - return oldval; +int SetGameOption(int opt, int setting) { + if (((opt < 1) || (opt > OPT_HIGHESTOPTION)) && (opt != OPT_LIPSYNCTEXT)) + quit("!SetGameOption: invalid option specified"); + + if (opt == OPT_ANTIGLIDE) { + for (int i = 0; i < game.numcharacters; i++) { + if (setting) + game.chars[i].flags |= CHF_ANTIGLIDE; + else + game.chars[i].flags &= ~CHF_ANTIGLIDE; + } + } + + if ((opt == OPT_CROSSFADEMUSIC) && (game.audioClipTypes.size() > AUDIOTYPE_LEGACY_MUSIC)) { + // legacy compatibility -- changing crossfade speed here also + // updates the new audio clip type style + game.audioClipTypes[AUDIOTYPE_LEGACY_MUSIC].crossfadeSpeed = setting; + } + + int oldval = game.options[opt]; + game.options[opt] = setting; + + if (opt == OPT_DUPLICATEINV) + update_invorder(); + else if (opt == OPT_DISABLEOFF) + gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); + else if (opt == OPT_PORTRAITSIDE) { + if (setting == 0) // set back to Left + play.swap_portrait_side = 0; + } + + return oldval; } -int GetGameOption (int opt) { - if (((opt < 1) || (opt > OPT_HIGHESTOPTION)) && (opt != OPT_LIPSYNCTEXT)) - quit("!GetGameOption: invalid option specified"); +int GetGameOption(int opt) { + if (((opt < 1) || (opt > OPT_HIGHESTOPTION)) && (opt != OPT_LIPSYNCTEXT)) + quit("!GetGameOption: invalid option specified"); - return game.options[opt]; + return game.options[opt]; } void SkipUntilCharacterStops(int cc) { - if (!is_valid_character(cc)) - quit("!SkipUntilCharacterStops: invalid character specified"); - if (game.chars[cc].room!=displayed_room) - quit("!SkipUntilCharacterStops: specified character not in current room"); + if (!is_valid_character(cc)) + quit("!SkipUntilCharacterStops: invalid character specified"); + if (game.chars[cc].room != displayed_room) + quit("!SkipUntilCharacterStops: specified character not in current room"); - // if they are not currently moving, do nothing - if (!game.chars[cc].walking) - return; + // if they are not currently moving, do nothing + if (!game.chars[cc].walking) + return; - if (is_in_cutscene()) - quit("!SkipUntilCharacterStops: cannot be used within a cutscene"); + if (is_in_cutscene()) + quit("!SkipUntilCharacterStops: cannot be used within a cutscene"); - initialize_skippable_cutscene(); - play.fast_forward = 2; - play.skip_until_char_stops = cc; + initialize_skippable_cutscene(); + play.fast_forward = 2; + play.skip_until_char_stops = cc; } void EndSkippingUntilCharStops() { - // not currently skipping, so ignore - if (play.skip_until_char_stops < 0) - return; + // not currently skipping, so ignore + if (play.skip_until_char_stops < 0) + return; - stop_fast_forwarding(); - play.skip_until_char_stops = -1; + stop_fast_forwarding(); + play.skip_until_char_stops = -1; } -void StartCutscene (int skipwith) { - static ScriptPosition last_cutscene_script_pos; +void StartCutscene(int skipwith) { + static ScriptPosition last_cutscene_script_pos; - if (is_in_cutscene()) { - quitprintf("!StartCutscene: already in a cutscene; previous started in \"%s\", line %d", - last_cutscene_script_pos.Section.GetCStr(), last_cutscene_script_pos.Line); - } + if (is_in_cutscene()) { + quitprintf("!StartCutscene: already in a cutscene; previous started in \"%s\", line %d", + last_cutscene_script_pos.Section.GetCStr(), last_cutscene_script_pos.Line); + } - if ((skipwith < 1) || (skipwith > 6)) - quit("!StartCutscene: invalid argument, must be 1 to 5."); + if ((skipwith < 1) || (skipwith > 6)) + quit("!StartCutscene: invalid argument, must be 1 to 5."); - get_script_position(last_cutscene_script_pos); + get_script_position(last_cutscene_script_pos); - // make sure they can't be skipping and cutsceneing at the same time - EndSkippingUntilCharStops(); + // make sure they can't be skipping and cutsceneing at the same time + EndSkippingUntilCharStops(); - play.in_cutscene = skipwith; - initialize_skippable_cutscene(); + play.in_cutscene = skipwith; + initialize_skippable_cutscene(); } -void SkipCutscene() -{ - if (is_in_cutscene()) - start_skipping_cutscene(); +void SkipCutscene() { + if (is_in_cutscene()) + start_skipping_cutscene(); } -int EndCutscene () { - if (!is_in_cutscene()) - quit("!EndCutscene: not in a cutscene"); +int EndCutscene() { + if (!is_in_cutscene()) + quit("!EndCutscene: not in a cutscene"); - int retval = play.fast_forward; - play.in_cutscene = 0; - // Stop it fast-forwarding - stop_fast_forwarding(); + int retval = play.fast_forward; + play.in_cutscene = 0; + // Stop it fast-forwarding + stop_fast_forwarding(); - // make sure that the screen redraws - invalidate_screen(); + // make sure that the screen redraws + invalidate_screen(); - // Return whether the player skipped it - return retval; + // Return whether the player skipped it + return retval; } -void sc_inputbox(const char*msg,char*bufr) { - VALIDATE_STRING(bufr); - setup_for_dialog(); - enterstringwindow(get_translation(msg),bufr); - restore_after_dialog(); +void sc_inputbox(const char *msg, char *bufr) { + VALIDATE_STRING(bufr); + setup_for_dialog(); + enterstringwindow(get_translation(msg), bufr); + restore_after_dialog(); } // GetLocationType exported function - just call through // to the main function with default 0 -int GetLocationType(int xxx,int yyy) { - return __GetLocationType(xxx, yyy, 0); +int GetLocationType(int xxx, int yyy) { + return __GetLocationType(xxx, yyy, 0); } void SaveCursorForLocationChange() { - // update the current location name - char tempo[100]; - GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); - - if (play.get_loc_name_save_cursor != play.get_loc_name_last_time) { - play.get_loc_name_save_cursor = play.get_loc_name_last_time; - play.restore_cursor_mode_to = GetCursorMode(); - play.restore_cursor_image_to = GetMouseCursor(); - debug_script_log("Saving mouse: mode %d cursor %d", play.restore_cursor_mode_to, play.restore_cursor_image_to); - } -} - -void GetLocationName(int xxx,int yyy,char*tempo) { - if (displayed_room < 0) - quit("!GetLocationName: no room has been loaded"); - - VALIDATE_STRING(tempo); - - tempo[0] = 0; - - if (GetGUIAt(xxx, yyy) >= 0) { - int mover = GetInvAt (xxx, yyy); - if (mover > 0) { - if (play.get_loc_name_last_time != 1000 + mover) - guis_need_update = 1; - play.get_loc_name_last_time = 1000 + mover; - strcpy(tempo,get_translation(game.invinfo[mover].name)); - } - else if ((play.get_loc_name_last_time > 1000) && (play.get_loc_name_last_time < 1000 + MAX_INV)) { - // no longer selecting an item - guis_need_update = 1; - play.get_loc_name_last_time = -1; - } - return; - } - - int loctype = GetLocationType(xxx, yyy); // GetLocationType takes screen coords - VpPoint vpt = play.ScreenToRoomDivDown(xxx, yyy); - if (vpt.second < 0) - return; - xxx = vpt.first.X; - yyy = vpt.first.Y; - if ((xxx>=thisroom.Width) | (xxx<0) | (yyy<0) | (yyy>=thisroom.Height)) - return; - - int onhs,aa; - if (loctype == 0) { - if (play.get_loc_name_last_time != 0) { - play.get_loc_name_last_time = 0; - guis_need_update = 1; - } - return; - } - - // on character - if (loctype == LOCTYPE_CHAR) { - onhs = getloctype_index; - strcpy(tempo,get_translation(game.chars[onhs].name)); - if (play.get_loc_name_last_time != 2000+onhs) - guis_need_update = 1; - play.get_loc_name_last_time = 2000+onhs; - return; - } - // on object - if (loctype == LOCTYPE_OBJ) { - aa = getloctype_index; - strcpy(tempo,get_translation(thisroom.Objects[aa].Name)); - // Compatibility: < 3.1.1 games returned space for nameless object - // (presumably was a bug, but fixing it affected certain games behavior) - if (loaded_game_file_version < kGameVersion_311 && tempo[0] == 0) { - tempo[0] = ' '; - tempo[1] = 0; - } - if (play.get_loc_name_last_time != 3000+aa) - guis_need_update = 1; - play.get_loc_name_last_time = 3000+aa; - return; - } - onhs = getloctype_index; - if (onhs>0) strcpy(tempo,get_translation(thisroom.Hotspots[onhs].Name)); - if (play.get_loc_name_last_time != onhs) - guis_need_update = 1; - play.get_loc_name_last_time = onhs; -} - -int IsKeyPressed (int keycode) { + // update the current location name + char tempo[100]; + GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + + if (play.get_loc_name_save_cursor != play.get_loc_name_last_time) { + play.get_loc_name_save_cursor = play.get_loc_name_last_time; + play.restore_cursor_mode_to = GetCursorMode(); + play.restore_cursor_image_to = GetMouseCursor(); + debug_script_log("Saving mouse: mode %d cursor %d", play.restore_cursor_mode_to, play.restore_cursor_image_to); + } +} + +void GetLocationName(int xxx, int yyy, char *tempo) { + if (displayed_room < 0) + quit("!GetLocationName: no room has been loaded"); + + VALIDATE_STRING(tempo); + + tempo[0] = 0; + + if (GetGUIAt(xxx, yyy) >= 0) { + int mover = GetInvAt(xxx, yyy); + if (mover > 0) { + if (play.get_loc_name_last_time != 1000 + mover) + guis_need_update = 1; + play.get_loc_name_last_time = 1000 + mover; + strcpy(tempo, get_translation(game.invinfo[mover].name)); + } else if ((play.get_loc_name_last_time > 1000) && (play.get_loc_name_last_time < 1000 + MAX_INV)) { + // no longer selecting an item + guis_need_update = 1; + play.get_loc_name_last_time = -1; + } + return; + } + + int loctype = GetLocationType(xxx, yyy); // GetLocationType takes screen coords + VpPoint vpt = play.ScreenToRoomDivDown(xxx, yyy); + if (vpt.second < 0) + return; + xxx = vpt.first.X; + yyy = vpt.first.Y; + if ((xxx >= thisroom.Width) | (xxx < 0) | (yyy < 0) | (yyy >= thisroom.Height)) + return; + + int onhs, aa; + if (loctype == 0) { + if (play.get_loc_name_last_time != 0) { + play.get_loc_name_last_time = 0; + guis_need_update = 1; + } + return; + } + + // on character + if (loctype == LOCTYPE_CHAR) { + onhs = getloctype_index; + strcpy(tempo, get_translation(game.chars[onhs].name)); + if (play.get_loc_name_last_time != 2000 + onhs) + guis_need_update = 1; + play.get_loc_name_last_time = 2000 + onhs; + return; + } + // on object + if (loctype == LOCTYPE_OBJ) { + aa = getloctype_index; + strcpy(tempo, get_translation(thisroom.Objects[aa].Name)); + // Compatibility: < 3.1.1 games returned space for nameless object + // (presumably was a bug, but fixing it affected certain games behavior) + if (loaded_game_file_version < kGameVersion_311 && tempo[0] == 0) { + tempo[0] = ' '; + tempo[1] = 0; + } + if (play.get_loc_name_last_time != 3000 + aa) + guis_need_update = 1; + play.get_loc_name_last_time = 3000 + aa; + return; + } + onhs = getloctype_index; + if (onhs > 0) strcpy(tempo, get_translation(thisroom.Hotspots[onhs].Name)); + if (play.get_loc_name_last_time != onhs) + guis_need_update = 1; + play.get_loc_name_last_time = onhs; +} + +int IsKeyPressed(int keycode) { #ifdef ALLEGRO_KEYBOARD_HANDLER - if (keyboard_needs_poll()) - poll_keyboard(); - - switch(keycode) { - case eAGSKeyCodeBackspace: return ags_iskeypressed(__allegro_KEY_BACKSPACE); break; - case eAGSKeyCodeTab: return ags_iskeypressed(__allegro_KEY_TAB); break; - case eAGSKeyCodeReturn: return ags_iskeypressed(__allegro_KEY_ENTER) || ags_iskeypressed(__allegro_KEY_ENTER_PAD); break; - case eAGSKeyCodeEscape: return ags_iskeypressed(__allegro_KEY_ESC); break; - case eAGSKeyCodeSpace: return ags_iskeypressed(__allegro_KEY_SPACE); break; - case eAGSKeyCodeSingleQuote: return ags_iskeypressed(__allegro_KEY_QUOTE); break; - case eAGSKeyCodeComma: return ags_iskeypressed(__allegro_KEY_COMMA); break; - case eAGSKeyCodePeriod: return ags_iskeypressed(__allegro_KEY_STOP); break; - case eAGSKeyCodeForwardSlash: return ags_iskeypressed(__allegro_KEY_SLASH) || ags_iskeypressed(__allegro_KEY_SLASH_PAD); break; - case eAGSKeyCodeBackSlash: return ags_iskeypressed(__allegro_KEY_BACKSLASH) || ags_iskeypressed(__allegro_KEY_BACKSLASH2); break; - case eAGSKeyCodeSemiColon: return ags_iskeypressed(__allegro_KEY_SEMICOLON); break; - case eAGSKeyCodeEquals: return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_EQUALS_PAD); break; - case eAGSKeyCodeOpenBracket: return ags_iskeypressed(__allegro_KEY_OPENBRACE); break; - case eAGSKeyCodeCloseBracket: return ags_iskeypressed(__allegro_KEY_CLOSEBRACE); break; - // NOTE: we're treating EQUALS like PLUS, even though it is only available shifted. - case eAGSKeyCodePlus: return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_PLUS_PAD); break; - case eAGSKeyCodeHyphen: return ags_iskeypressed(__allegro_KEY_MINUS) || ags_iskeypressed(__allegro_KEY_MINUS_PAD); break; - - // non-shifted versions of keys - case eAGSKeyCodeColon: return ags_iskeypressed(__allegro_KEY_COLON) || ags_iskeypressed(__allegro_KEY_COLON2); break; - case eAGSKeyCodeAsterisk: return ags_iskeypressed(__allegro_KEY_ASTERISK); break; - case eAGSKeyCodeAt: return ags_iskeypressed(__allegro_KEY_AT); break; - - case eAGSKeyCode0: return ags_iskeypressed(__allegro_KEY_0); break; - case eAGSKeyCode1: return ags_iskeypressed(__allegro_KEY_1); break; - case eAGSKeyCode2: return ags_iskeypressed(__allegro_KEY_2); break; - case eAGSKeyCode3: return ags_iskeypressed(__allegro_KEY_3); break; - case eAGSKeyCode4: return ags_iskeypressed(__allegro_KEY_4); break; - case eAGSKeyCode5: return ags_iskeypressed(__allegro_KEY_5); break; - case eAGSKeyCode6: return ags_iskeypressed(__allegro_KEY_6); break; - case eAGSKeyCode7: return ags_iskeypressed(__allegro_KEY_7); break; - case eAGSKeyCode8: return ags_iskeypressed(__allegro_KEY_8); break; - case eAGSKeyCode9: return ags_iskeypressed(__allegro_KEY_9); break; - - case eAGSKeyCodeA: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('A')); break; - case eAGSKeyCodeB: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('B')); break; - case eAGSKeyCodeC: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('C')); break; - case eAGSKeyCodeD: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('D')); break; - case eAGSKeyCodeE: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('E')); break; - case eAGSKeyCodeF: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('F')); break; - case eAGSKeyCodeG: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('G')); break; - case eAGSKeyCodeH: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('H')); break; - case eAGSKeyCodeI: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('I')); break; - case eAGSKeyCodeJ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('J')); break; - case eAGSKeyCodeK: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('K')); break; - case eAGSKeyCodeL: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('L')); break; - case eAGSKeyCodeM: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('M')); break; - case eAGSKeyCodeN: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('N')); break; - case eAGSKeyCodeO: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('O')); break; - case eAGSKeyCodeP: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('P')); break; - case eAGSKeyCodeQ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Q')); break; - case eAGSKeyCodeR: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('R')); break; - case eAGSKeyCodeS: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('S')); break; - case eAGSKeyCodeT: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('T')); break; - case eAGSKeyCodeU: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('U')); break; - case eAGSKeyCodeV: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('V')); break; - case eAGSKeyCodeW: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('W')); break; - case eAGSKeyCodeX: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('X')); break; - case eAGSKeyCodeY: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Y')); break; - case eAGSKeyCodeZ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Z')); break; - - case eAGSKeyCodeF1: return ags_iskeypressed(__allegro_KEY_F1); break; - case eAGSKeyCodeF2: return ags_iskeypressed(__allegro_KEY_F2); break; - case eAGSKeyCodeF3: return ags_iskeypressed(__allegro_KEY_F3); break; - case eAGSKeyCodeF4: return ags_iskeypressed(__allegro_KEY_F4); break; - case eAGSKeyCodeF5: return ags_iskeypressed(__allegro_KEY_F5); break; - case eAGSKeyCodeF6: return ags_iskeypressed(__allegro_KEY_F6); break; - case eAGSKeyCodeF7: return ags_iskeypressed(__allegro_KEY_F7); break; - case eAGSKeyCodeF8: return ags_iskeypressed(__allegro_KEY_F8); break; - case eAGSKeyCodeF9: return ags_iskeypressed(__allegro_KEY_F9); break; - case eAGSKeyCodeF10: return ags_iskeypressed(__allegro_KEY_F10); break; - case eAGSKeyCodeF11: return ags_iskeypressed(__allegro_KEY_F11); break; - case eAGSKeyCodeF12: return ags_iskeypressed(__allegro_KEY_F12); break; - - case eAGSKeyCodeHome: return ags_iskeypressed(__allegro_KEY_HOME) || ags_iskeypressed(__allegro_KEY_7_PAD); break; - case eAGSKeyCodeUpArrow: return ags_iskeypressed(__allegro_KEY_UP) || ags_iskeypressed(__allegro_KEY_8_PAD); break; - case eAGSKeyCodePageUp: return ags_iskeypressed(__allegro_KEY_PGUP) || ags_iskeypressed(__allegro_KEY_9_PAD); break; - case eAGSKeyCodeLeftArrow: return ags_iskeypressed(__allegro_KEY_LEFT) || ags_iskeypressed(__allegro_KEY_4_PAD); break; - case eAGSKeyCodeNumPad5: return ags_iskeypressed(__allegro_KEY_5_PAD); break; - case eAGSKeyCodeRightArrow: return ags_iskeypressed(__allegro_KEY_RIGHT) || ags_iskeypressed(__allegro_KEY_6_PAD); break; - case eAGSKeyCodeEnd: return ags_iskeypressed(__allegro_KEY_END) || ags_iskeypressed(__allegro_KEY_1_PAD); break; - case eAGSKeyCodeDownArrow: return ags_iskeypressed(__allegro_KEY_DOWN) || ags_iskeypressed(__allegro_KEY_2_PAD); break; - case eAGSKeyCodePageDown: return ags_iskeypressed(__allegro_KEY_PGDN) || ags_iskeypressed(__allegro_KEY_3_PAD); break; - case eAGSKeyCodeInsert: return ags_iskeypressed(__allegro_KEY_INSERT) || ags_iskeypressed(__allegro_KEY_0_PAD); break; - case eAGSKeyCodeDelete: return ags_iskeypressed(__allegro_KEY_DEL) || ags_iskeypressed(__allegro_KEY_DEL_PAD); break; - - // These keys are not defined in the eAGSKey enum but are in the manual - // https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html - - case 403: return ags_iskeypressed(__allegro_KEY_LSHIFT); break; - case 404: return ags_iskeypressed(__allegro_KEY_RSHIFT); break; - case 405: return ags_iskeypressed(__allegro_KEY_LCONTROL); break; - case 406: return ags_iskeypressed(__allegro_KEY_RCONTROL); break; - case 407: return ags_iskeypressed(__allegro_KEY_ALT); break; - - // (noted here for interest) - // The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes. - // These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints. - - case 392: return ags_iskeypressed(__allegro_KEY_PRTSCR); break; - case 393: return ags_iskeypressed(__allegro_KEY_PAUSE); break; - case 394: return ags_iskeypressed(__allegro_KEY_ABNT_C1); break; // The ABNT_C1 (Brazilian) key - case 395: return ags_iskeypressed(__allegro_KEY_YEN); break; - case 396: return ags_iskeypressed(__allegro_KEY_KANA); break; - case 397: return ags_iskeypressed(__allegro_KEY_CONVERT); break; - case 398: return ags_iskeypressed(__allegro_KEY_NOCONVERT); break; - case 400: return ags_iskeypressed(__allegro_KEY_CIRCUMFLEX); break; - case 402: return ags_iskeypressed(__allegro_KEY_KANJI); break; - case 420: return ags_iskeypressed(__allegro_KEY_ALTGR); break; - case 421: return ags_iskeypressed(__allegro_KEY_LWIN); break; - case 422: return ags_iskeypressed(__allegro_KEY_RWIN); break; - case 423: return ags_iskeypressed(__allegro_KEY_MENU); break; - case 424: return ags_iskeypressed(__allegro_KEY_SCRLOCK); break; - case 425: return ags_iskeypressed(__allegro_KEY_NUMLOCK); break; - case 426: return ags_iskeypressed(__allegro_KEY_CAPSLOCK); break; - - // Allegro4 keys that were never supported: - // __allegro_KEY_COMMAND - // __allegro_KEY_TILDE - // __allegro_KEY_BACKQUOTE - - default: - // Remaining Allegro4 keycodes are offset by AGS_EXT_KEY_SHIFT - if (keycode >= AGS_EXT_KEY_SHIFT) { - if (ags_iskeypressed(keycode - AGS_EXT_KEY_SHIFT)) { return 1; } - } - debug_script_log("IsKeyPressed: unsupported keycode %d", keycode); - return 0; - } + if (keyboard_needs_poll()) + poll_keyboard(); + + switch (keycode) { + case eAGSKeyCodeBackspace: + return ags_iskeypressed(__allegro_KEY_BACKSPACE); + break; + case eAGSKeyCodeTab: + return ags_iskeypressed(__allegro_KEY_TAB); + break; + case eAGSKeyCodeReturn: + return ags_iskeypressed(__allegro_KEY_ENTER) || ags_iskeypressed(__allegro_KEY_ENTER_PAD); + break; + case eAGSKeyCodeEscape: + return ags_iskeypressed(__allegro_KEY_ESC); + break; + case eAGSKeyCodeSpace: + return ags_iskeypressed(__allegro_KEY_SPACE); + break; + case eAGSKeyCodeSingleQuote: + return ags_iskeypressed(__allegro_KEY_QUOTE); + break; + case eAGSKeyCodeComma: + return ags_iskeypressed(__allegro_KEY_COMMA); + break; + case eAGSKeyCodePeriod: + return ags_iskeypressed(__allegro_KEY_STOP); + break; + case eAGSKeyCodeForwardSlash: + return ags_iskeypressed(__allegro_KEY_SLASH) || ags_iskeypressed(__allegro_KEY_SLASH_PAD); + break; + case eAGSKeyCodeBackSlash: + return ags_iskeypressed(__allegro_KEY_BACKSLASH) || ags_iskeypressed(__allegro_KEY_BACKSLASH2); + break; + case eAGSKeyCodeSemiColon: + return ags_iskeypressed(__allegro_KEY_SEMICOLON); + break; + case eAGSKeyCodeEquals: + return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_EQUALS_PAD); + break; + case eAGSKeyCodeOpenBracket: + return ags_iskeypressed(__allegro_KEY_OPENBRACE); + break; + case eAGSKeyCodeCloseBracket: + return ags_iskeypressed(__allegro_KEY_CLOSEBRACE); + break; + // NOTE: we're treating EQUALS like PLUS, even though it is only available shifted. + case eAGSKeyCodePlus: + return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_PLUS_PAD); + break; + case eAGSKeyCodeHyphen: + return ags_iskeypressed(__allegro_KEY_MINUS) || ags_iskeypressed(__allegro_KEY_MINUS_PAD); + break; + + // non-shifted versions of keys + case eAGSKeyCodeColon: + return ags_iskeypressed(__allegro_KEY_COLON) || ags_iskeypressed(__allegro_KEY_COLON2); + break; + case eAGSKeyCodeAsterisk: + return ags_iskeypressed(__allegro_KEY_ASTERISK); + break; + case eAGSKeyCodeAt: + return ags_iskeypressed(__allegro_KEY_AT); + break; + + case eAGSKeyCode0: + return ags_iskeypressed(__allegro_KEY_0); + break; + case eAGSKeyCode1: + return ags_iskeypressed(__allegro_KEY_1); + break; + case eAGSKeyCode2: + return ags_iskeypressed(__allegro_KEY_2); + break; + case eAGSKeyCode3: + return ags_iskeypressed(__allegro_KEY_3); + break; + case eAGSKeyCode4: + return ags_iskeypressed(__allegro_KEY_4); + break; + case eAGSKeyCode5: + return ags_iskeypressed(__allegro_KEY_5); + break; + case eAGSKeyCode6: + return ags_iskeypressed(__allegro_KEY_6); + break; + case eAGSKeyCode7: + return ags_iskeypressed(__allegro_KEY_7); + break; + case eAGSKeyCode8: + return ags_iskeypressed(__allegro_KEY_8); + break; + case eAGSKeyCode9: + return ags_iskeypressed(__allegro_KEY_9); + break; + + case eAGSKeyCodeA: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('A')); + break; + case eAGSKeyCodeB: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('B')); + break; + case eAGSKeyCodeC: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('C')); + break; + case eAGSKeyCodeD: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('D')); + break; + case eAGSKeyCodeE: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('E')); + break; + case eAGSKeyCodeF: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('F')); + break; + case eAGSKeyCodeG: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('G')); + break; + case eAGSKeyCodeH: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('H')); + break; + case eAGSKeyCodeI: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('I')); + break; + case eAGSKeyCodeJ: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('J')); + break; + case eAGSKeyCodeK: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('K')); + break; + case eAGSKeyCodeL: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('L')); + break; + case eAGSKeyCodeM: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('M')); + break; + case eAGSKeyCodeN: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('N')); + break; + case eAGSKeyCodeO: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('O')); + break; + case eAGSKeyCodeP: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('P')); + break; + case eAGSKeyCodeQ: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Q')); + break; + case eAGSKeyCodeR: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('R')); + break; + case eAGSKeyCodeS: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('S')); + break; + case eAGSKeyCodeT: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('T')); + break; + case eAGSKeyCodeU: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('U')); + break; + case eAGSKeyCodeV: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('V')); + break; + case eAGSKeyCodeW: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('W')); + break; + case eAGSKeyCodeX: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('X')); + break; + case eAGSKeyCodeY: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Y')); + break; + case eAGSKeyCodeZ: + return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Z')); + break; + + case eAGSKeyCodeF1: + return ags_iskeypressed(__allegro_KEY_F1); + break; + case eAGSKeyCodeF2: + return ags_iskeypressed(__allegro_KEY_F2); + break; + case eAGSKeyCodeF3: + return ags_iskeypressed(__allegro_KEY_F3); + break; + case eAGSKeyCodeF4: + return ags_iskeypressed(__allegro_KEY_F4); + break; + case eAGSKeyCodeF5: + return ags_iskeypressed(__allegro_KEY_F5); + break; + case eAGSKeyCodeF6: + return ags_iskeypressed(__allegro_KEY_F6); + break; + case eAGSKeyCodeF7: + return ags_iskeypressed(__allegro_KEY_F7); + break; + case eAGSKeyCodeF8: + return ags_iskeypressed(__allegro_KEY_F8); + break; + case eAGSKeyCodeF9: + return ags_iskeypressed(__allegro_KEY_F9); + break; + case eAGSKeyCodeF10: + return ags_iskeypressed(__allegro_KEY_F10); + break; + case eAGSKeyCodeF11: + return ags_iskeypressed(__allegro_KEY_F11); + break; + case eAGSKeyCodeF12: + return ags_iskeypressed(__allegro_KEY_F12); + break; + + case eAGSKeyCodeHome: + return ags_iskeypressed(__allegro_KEY_HOME) || ags_iskeypressed(__allegro_KEY_7_PAD); + break; + case eAGSKeyCodeUpArrow: + return ags_iskeypressed(__allegro_KEY_UP) || ags_iskeypressed(__allegro_KEY_8_PAD); + break; + case eAGSKeyCodePageUp: + return ags_iskeypressed(__allegro_KEY_PGUP) || ags_iskeypressed(__allegro_KEY_9_PAD); + break; + case eAGSKeyCodeLeftArrow: + return ags_iskeypressed(__allegro_KEY_LEFT) || ags_iskeypressed(__allegro_KEY_4_PAD); + break; + case eAGSKeyCodeNumPad5: + return ags_iskeypressed(__allegro_KEY_5_PAD); + break; + case eAGSKeyCodeRightArrow: + return ags_iskeypressed(__allegro_KEY_RIGHT) || ags_iskeypressed(__allegro_KEY_6_PAD); + break; + case eAGSKeyCodeEnd: + return ags_iskeypressed(__allegro_KEY_END) || ags_iskeypressed(__allegro_KEY_1_PAD); + break; + case eAGSKeyCodeDownArrow: + return ags_iskeypressed(__allegro_KEY_DOWN) || ags_iskeypressed(__allegro_KEY_2_PAD); + break; + case eAGSKeyCodePageDown: + return ags_iskeypressed(__allegro_KEY_PGDN) || ags_iskeypressed(__allegro_KEY_3_PAD); + break; + case eAGSKeyCodeInsert: + return ags_iskeypressed(__allegro_KEY_INSERT) || ags_iskeypressed(__allegro_KEY_0_PAD); + break; + case eAGSKeyCodeDelete: + return ags_iskeypressed(__allegro_KEY_DEL) || ags_iskeypressed(__allegro_KEY_DEL_PAD); + break; + + // These keys are not defined in the eAGSKey enum but are in the manual + // https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html + + case 403: + return ags_iskeypressed(__allegro_KEY_LSHIFT); + break; + case 404: + return ags_iskeypressed(__allegro_KEY_RSHIFT); + break; + case 405: + return ags_iskeypressed(__allegro_KEY_LCONTROL); + break; + case 406: + return ags_iskeypressed(__allegro_KEY_RCONTROL); + break; + case 407: + return ags_iskeypressed(__allegro_KEY_ALT); + break; + + // (noted here for interest) + // The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes. + // These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints. + + case 392: + return ags_iskeypressed(__allegro_KEY_PRTSCR); + break; + case 393: + return ags_iskeypressed(__allegro_KEY_PAUSE); + break; + case 394: + return ags_iskeypressed(__allegro_KEY_ABNT_C1); + break; // The ABNT_C1 (Brazilian) key + case 395: + return ags_iskeypressed(__allegro_KEY_YEN); + break; + case 396: + return ags_iskeypressed(__allegro_KEY_KANA); + break; + case 397: + return ags_iskeypressed(__allegro_KEY_CONVERT); + break; + case 398: + return ags_iskeypressed(__allegro_KEY_NOCONVERT); + break; + case 400: + return ags_iskeypressed(__allegro_KEY_CIRCUMFLEX); + break; + case 402: + return ags_iskeypressed(__allegro_KEY_KANJI); + break; + case 420: + return ags_iskeypressed(__allegro_KEY_ALTGR); + break; + case 421: + return ags_iskeypressed(__allegro_KEY_LWIN); + break; + case 422: + return ags_iskeypressed(__allegro_KEY_RWIN); + break; + case 423: + return ags_iskeypressed(__allegro_KEY_MENU); + break; + case 424: + return ags_iskeypressed(__allegro_KEY_SCRLOCK); + break; + case 425: + return ags_iskeypressed(__allegro_KEY_NUMLOCK); + break; + case 426: + return ags_iskeypressed(__allegro_KEY_CAPSLOCK); + break; + + // Allegro4 keys that were never supported: + // __allegro_KEY_COMMAND + // __allegro_KEY_TILDE + // __allegro_KEY_BACKQUOTE + + default: + // Remaining Allegro4 keycodes are offset by AGS_EXT_KEY_SHIFT + if (keycode >= AGS_EXT_KEY_SHIFT) { + if (ags_iskeypressed(keycode - AGS_EXT_KEY_SHIFT)) { + return 1; + } + } + debug_script_log("IsKeyPressed: unsupported keycode %d", keycode); + return 0; + } #else - // old allegro version - quit("allegro keyboard handler not in use??"); + // old allegro version + quit("allegro keyboard handler not in use??"); #endif } -int SaveScreenShot(const char*namm) { - String fileName; - String svg_dir = get_save_game_directory(); - - if (strchr(namm,'.') == nullptr) - fileName.Format("%s%s.bmp", svg_dir.GetCStr(), namm); - else - fileName.Format("%s%s", svg_dir.GetCStr(), namm); - - Bitmap *buffer = CopyScreenIntoBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight()); - if (!buffer->SaveToFile(fileName, palette) != 0) - { - delete buffer; - return 0; - } - delete buffer; - return 1; // successful -} - -void SetMultitasking (int mode) { - if ((mode < 0) | (mode > 1)) - quit("!SetMultitasking: invalid mode parameter"); - - if (usetup.override_multitasking >= 0) - { - mode = usetup.override_multitasking; - } - - // Don't allow background running if full screen - if ((mode == 1) && (!scsystem.windowed)) - mode = 0; - - if (mode == 0) { - if (set_display_switch_mode(SWITCH_PAUSE) == -1) - set_display_switch_mode(SWITCH_AMNESIA); - // install callbacks to stop the sound when switching away - set_display_switch_callback(SWITCH_IN, display_switch_in_resume); - set_display_switch_callback(SWITCH_OUT, display_switch_out_suspend); - } - else { - if (set_display_switch_mode (SWITCH_BACKGROUND) == -1) - set_display_switch_mode(SWITCH_BACKAMNESIA); - set_display_switch_callback(SWITCH_IN, display_switch_in); - set_display_switch_callback(SWITCH_OUT, display_switch_out); - } +int SaveScreenShot(const char *namm) { + String fileName; + String svg_dir = get_save_game_directory(); + + if (strchr(namm, '.') == nullptr) + fileName.Format("%s%s.bmp", svg_dir.GetCStr(), namm); + else + fileName.Format("%s%s", svg_dir.GetCStr(), namm); + + Bitmap *buffer = CopyScreenIntoBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight()); + if (!buffer->SaveToFile(fileName, palette) != 0) { + delete buffer; + return 0; + } + delete buffer; + return 1; // successful +} + +void SetMultitasking(int mode) { + if ((mode < 0) | (mode > 1)) + quit("!SetMultitasking: invalid mode parameter"); + + if (usetup.override_multitasking >= 0) { + mode = usetup.override_multitasking; + } + + // Don't allow background running if full screen + if ((mode == 1) && (!scsystem.windowed)) + mode = 0; + + if (mode == 0) { + if (set_display_switch_mode(SWITCH_PAUSE) == -1) + set_display_switch_mode(SWITCH_AMNESIA); + // install callbacks to stop the sound when switching away + set_display_switch_callback(SWITCH_IN, display_switch_in_resume); + set_display_switch_callback(SWITCH_OUT, display_switch_out_suspend); + } else { + if (set_display_switch_mode(SWITCH_BACKGROUND) == -1) + set_display_switch_mode(SWITCH_BACKAMNESIA); + set_display_switch_callback(SWITCH_IN, display_switch_in); + set_display_switch_callback(SWITCH_OUT, display_switch_out); + } } extern int getloctype_throughgui, getloctype_index; -void RoomProcessClick(int xx,int yy,int mood) { - getloctype_throughgui = 1; - int loctype = GetLocationType (xx, yy); - VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); - if (vpt.second < 0) - return; - xx = vpt.first.X; - yy = vpt.first.Y; - - if ((mood==MODE_WALK) && (game.options[OPT_NOWALKMODE]==0)) { - int hsnum=get_hotspot_at(xx,yy); - if (hsnum<1) ; - else if (thisroom.Hotspots[hsnum].WalkTo.X<1) ; - else if (play.auto_use_walkto_points == 0) ; - else { - xx=thisroom.Hotspots[hsnum].WalkTo.X; - yy=thisroom.Hotspots[hsnum].WalkTo.Y; - debug_script_log("Move to walk-to point hotspot %d", hsnum); - } - walk_character(game.playercharacter,xx,yy,0, true); - return; - } - play.usedmode=mood; - - if (loctype == 0) { - // click on nothing -> hotspot 0 - getloctype_index = 0; - loctype = LOCTYPE_HOTSPOT; - } - - if (loctype == LOCTYPE_CHAR) { - if (check_click_on_character(xx,yy,mood)) return; - } - else if (loctype == LOCTYPE_OBJ) { - if (check_click_on_object(xx,yy,mood)) return; - } - else if (loctype == LOCTYPE_HOTSPOT) - RunHotspotInteraction (getloctype_index, mood); -} - -int IsInteractionAvailable (int xx,int yy,int mood) { - getloctype_throughgui = 1; - int loctype = GetLocationType (xx, yy); - VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); - if (vpt.second < 0) - return 0; - xx = vpt.first.X; - yy = vpt.first.Y; - - // You can always walk places - if ((mood==MODE_WALK) && (game.options[OPT_NOWALKMODE]==0)) - return 1; - - play.check_interaction_only = 1; - - if (loctype == 0) { - // click on nothing -> hotspot 0 - getloctype_index = 0; - loctype = LOCTYPE_HOTSPOT; - } - - if (loctype == LOCTYPE_CHAR) { - check_click_on_character(xx,yy,mood); - } - else if (loctype == LOCTYPE_OBJ) { - check_click_on_object(xx,yy,mood); - } - else if (loctype == LOCTYPE_HOTSPOT) - RunHotspotInteraction (getloctype_index, mood); - - int ciwas = play.check_interaction_only; - play.check_interaction_only = 0; - - if (ciwas == 2) - return 1; - - return 0; -} - -void GetMessageText (int msg, char *buffer) { - VALIDATE_STRING(buffer); - get_message_text (msg, buffer, 0); -} - -void SetSpeechFont (int fontnum) { - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!SetSpeechFont: invalid font number."); - play.speech_font = fontnum; -} - -void SetNormalFont (int fontnum) { - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!SetNormalFont: invalid font number."); - play.normal_font = fontnum; -} - -void _sc_AbortGame(const char* text) { - char displbuf[STD_BUFFER_SIZE] = "!?"; - snprintf(&displbuf[2], STD_BUFFER_SIZE - 3, "%s", text); - quit(displbuf); -} - -int GetGraphicalVariable (const char *varName) { - InteractionVariable *theVar = FindGraphicalVariable(varName); - if (theVar == nullptr) { - quitprintf("!GetGraphicalVariable: interaction variable '%s' not found", varName); - return 0; - } - return theVar->Value; -} - -void SetGraphicalVariable (const char *varName, int p_value) { - InteractionVariable *theVar = FindGraphicalVariable(varName); - if (theVar == nullptr) { - quitprintf("!SetGraphicalVariable: interaction variable '%s' not found", varName); - } - else - theVar->Value = p_value; -} - -int WaitImpl(int skip_type, int nloops) -{ - play.wait_counter = nloops; - play.wait_skipped_by = SKIP_AUTOTIMER; // we set timer flag by default to simplify that case - play.wait_skipped_by_data = 0; - play.key_skip_wait = skip_type; - - GameLoopUntilValueIsZero(&play.wait_counter); +void RoomProcessClick(int xx, int yy, int mood) { + getloctype_throughgui = 1; + int loctype = GetLocationType(xx, yy); + VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); + if (vpt.second < 0) + return; + xx = vpt.first.X; + yy = vpt.first.Y; + + if ((mood == MODE_WALK) && (game.options[OPT_NOWALKMODE] == 0)) { + int hsnum = get_hotspot_at(xx, yy); + if (hsnum < 1) ; + else if (thisroom.Hotspots[hsnum].WalkTo.X < 1) ; + else if (play.auto_use_walkto_points == 0) ; + else { + xx = thisroom.Hotspots[hsnum].WalkTo.X; + yy = thisroom.Hotspots[hsnum].WalkTo.Y; + debug_script_log("Move to walk-to point hotspot %d", hsnum); + } + walk_character(game.playercharacter, xx, yy, 0, true); + return; + } + play.usedmode = mood; + + if (loctype == 0) { + // click on nothing -> hotspot 0 + getloctype_index = 0; + loctype = LOCTYPE_HOTSPOT; + } + + if (loctype == LOCTYPE_CHAR) { + if (check_click_on_character(xx, yy, mood)) return; + } else if (loctype == LOCTYPE_OBJ) { + if (check_click_on_object(xx, yy, mood)) return; + } else if (loctype == LOCTYPE_HOTSPOT) + RunHotspotInteraction(getloctype_index, mood); +} + +int IsInteractionAvailable(int xx, int yy, int mood) { + getloctype_throughgui = 1; + int loctype = GetLocationType(xx, yy); + VpPoint vpt = play.ScreenToRoomDivDown(xx, yy); + if (vpt.second < 0) + return 0; + xx = vpt.first.X; + yy = vpt.first.Y; + + // You can always walk places + if ((mood == MODE_WALK) && (game.options[OPT_NOWALKMODE] == 0)) + return 1; + + play.check_interaction_only = 1; + + if (loctype == 0) { + // click on nothing -> hotspot 0 + getloctype_index = 0; + loctype = LOCTYPE_HOTSPOT; + } + + if (loctype == LOCTYPE_CHAR) { + check_click_on_character(xx, yy, mood); + } else if (loctype == LOCTYPE_OBJ) { + check_click_on_object(xx, yy, mood); + } else if (loctype == LOCTYPE_HOTSPOT) + RunHotspotInteraction(getloctype_index, mood); + + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + + if (ciwas == 2) + return 1; + + return 0; +} + +void GetMessageText(int msg, char *buffer) { + VALIDATE_STRING(buffer); + get_message_text(msg, buffer, 0); +} + +void SetSpeechFont(int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetSpeechFont: invalid font number."); + play.speech_font = fontnum; +} + +void SetNormalFont(int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetNormalFont: invalid font number."); + play.normal_font = fontnum; +} + +void _sc_AbortGame(const char *text) { + char displbuf[STD_BUFFER_SIZE] = "!?"; + snprintf(&displbuf[2], STD_BUFFER_SIZE - 3, "%s", text); + quit(displbuf); +} + +int GetGraphicalVariable(const char *varName) { + InteractionVariable *theVar = FindGraphicalVariable(varName); + if (theVar == nullptr) { + quitprintf("!GetGraphicalVariable: interaction variable '%s' not found", varName); + return 0; + } + return theVar->Value; +} + +void SetGraphicalVariable(const char *varName, int p_value) { + InteractionVariable *theVar = FindGraphicalVariable(varName); + if (theVar == nullptr) { + quitprintf("!SetGraphicalVariable: interaction variable '%s' not found", varName); + } else + theVar->Value = p_value; +} - if (game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v351) - { - // < 3.5.1 return 1 is skipped by user input, otherwise 0 - return (play.wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK) != 0) ? 1 : 0; - } - // >= 3.5.1 return positive keycode, negative mouse button code, or 0 as time-out - switch (play.wait_skipped_by) - { - case SKIP_KEYPRESS: return play.wait_skipped_by_data; - case SKIP_MOUSECLICK: return -(play.wait_skipped_by_data + 1); // convert to 1-based code and negate - default: return 0; - } +int WaitImpl(int skip_type, int nloops) { + play.wait_counter = nloops; + play.wait_skipped_by = SKIP_AUTOTIMER; // we set timer flag by default to simplify that case + play.wait_skipped_by_data = 0; + play.key_skip_wait = skip_type; + + GameLoopUntilValueIsZero(&play.wait_counter); + + if (game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v351) { + // < 3.5.1 return 1 is skipped by user input, otherwise 0 + return (play.wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK) != 0) ? 1 : 0; + } + // >= 3.5.1 return positive keycode, negative mouse button code, or 0 as time-out + switch (play.wait_skipped_by) { + case SKIP_KEYPRESS: + return play.wait_skipped_by_data; + case SKIP_MOUSECLICK: + return -(play.wait_skipped_by_data + 1); // convert to 1-based code and negate + default: + return 0; + } } void scrWait(int nloops) { - WaitImpl(SKIP_AUTOTIMER, nloops); + WaitImpl(SKIP_AUTOTIMER, nloops); } int WaitKey(int nloops) { - return WaitImpl(SKIP_KEYPRESS | SKIP_AUTOTIMER, nloops); + return WaitImpl(SKIP_KEYPRESS | SKIP_AUTOTIMER, nloops); } int WaitMouse(int nloops) { - return WaitImpl(SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops); + return WaitImpl(SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops); } int WaitMouseKey(int nloops) { - return WaitImpl(SKIP_KEYPRESS | SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops); + return WaitImpl(SKIP_KEYPRESS | SKIP_MOUSECLICK | SKIP_AUTOTIMER, nloops); } void SkipWait() { - play.wait_counter = 0; + play.wait_counter = 0; } diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h index a7a4418c99dd..d777fafef306 100644 --- a/engines/ags/engine/ac/global_game.h +++ b/engines/ags/engine/ac/global_game.h @@ -29,24 +29,24 @@ using namespace AGS; // FIXME later void GiveScore(int amnt); void restart_game(); void RestoreGameSlot(int slnum); -void DeleteSaveSlot (int slnum); -int GetSaveSlotDescription(int slnum,char*desbuf); +void DeleteSaveSlot(int slnum); +int GetSaveSlotDescription(int slnum, char *desbuf); int LoadSaveSlotScreenshot(int slnum, int width, int height); void PauseGame(); void UnPauseGame(); int IsGamePaused(); -void SetGlobalInt(int index,int valu); +void SetGlobalInt(int index, int valu); int GetGlobalInt(int index); -void SetGlobalString (int index, const char *newval); -void GetGlobalString (int index, char *strval); -int RunAGSGame (const char *newgame, unsigned int mode, int data); -int GetGameParameter (int parm, int data1, int data2, int data3); +void SetGlobalString(int index, const char *newval); +void GetGlobalString(int index, char *strval); +int RunAGSGame(const char *newgame, unsigned int mode, int data); +int GetGameParameter(int parm, int data1, int data2, int data3); void QuitGame(int dialog); void SetRestartPoint(); void SetGameSpeed(int newspd); int GetGameSpeed(); -int SetGameOption (int opt, int setting); -int GetGameOption (int opt); +int SetGameOption(int opt, int setting); +int GetGameOption(int opt); void SkipUntilCharacterStops(int cc); void EndSkippingUntilCharStops(); @@ -56,34 +56,34 @@ void EndSkippingUntilCharStops(); // 3 = mouse button // 4 = mouse button or any key // 5 = right click or ESC only -void StartCutscene (int skipwith); -int EndCutscene (); +void StartCutscene(int skipwith); +int EndCutscene(); // Tell the game to skip current cutscene void SkipCutscene(); -void sc_inputbox(const char*msg,char*bufr); +void sc_inputbox(const char *msg, char *bufr); -int GetLocationType(int xxx,int yyy); +int GetLocationType(int xxx, int yyy); void SaveCursorForLocationChange(); -void GetLocationName(int xxx,int yyy,char*tempo); +void GetLocationName(int xxx, int yyy, char *tempo); -int IsKeyPressed (int keycode); +int IsKeyPressed(int keycode); -int SaveScreenShot(const char*namm); -void SetMultitasking (int mode); +int SaveScreenShot(const char *namm); +void SetMultitasking(int mode); -void RoomProcessClick(int xx,int yy,int mood); -int IsInteractionAvailable (int xx,int yy,int mood); +void RoomProcessClick(int xx, int yy, int mood); +int IsInteractionAvailable(int xx, int yy, int mood); -void GetMessageText (int msg, char *buffer); +void GetMessageText(int msg, char *buffer); -void SetSpeechFont (int fontnum); -void SetNormalFont (int fontnum); +void SetSpeechFont(int fontnum); +void SetNormalFont(int fontnum); -void _sc_AbortGame(const char* text); +void _sc_AbortGame(const char *text); -int GetGraphicalVariable (const char *varName); -void SetGraphicalVariable (const char *varName, int p_value); +int GetGraphicalVariable(const char *varName); +void SetGraphicalVariable(const char *varName, int p_value); void scrWait(int nloops); int WaitKey(int nloops); int WaitMouse(int nloops); diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp index ba3134ab590e..63b659d0ecbb 100644 --- a/engines/ags/engine/ac/global_gui.cpp +++ b/engines/ags/engine/ac/global_gui.cpp @@ -41,224 +41,222 @@ using namespace AGS::Common; extern GameSetupStruct game; extern ScriptGUI *scrGui; -int IsGUIOn (int guinum) { - if ((guinum < 0) || (guinum >= game.numgui)) - quit("!IsGUIOn: invalid GUI number specified"); - return (guis[guinum].IsDisplayed()) ? 1 : 0; +int IsGUIOn(int guinum) { + if ((guinum < 0) || (guinum >= game.numgui)) + quit("!IsGUIOn: invalid GUI number specified"); + return (guis[guinum].IsDisplayed()) ? 1 : 0; } // This is an internal script function, and is undocumented. // It is used by the editor's automatic macro generation. -int FindGUIID (const char* GUIName) { - for (int ii = 0; ii < game.numgui; ii++) { - if (guis[ii].Name.IsEmpty()) - continue; - if (strcmp(guis[ii].Name, GUIName) == 0) - return ii; - if ((guis[ii].Name[0u] == 'g') && (ags_stricmp(guis[ii].Name.GetCStr() + 1, GUIName) == 0)) - return ii; - } - quit("FindGUIID: No matching GUI found: GUI may have been deleted"); - return -1; +int FindGUIID(const char *GUIName) { + for (int ii = 0; ii < game.numgui; ii++) { + if (guis[ii].Name.IsEmpty()) + continue; + if (strcmp(guis[ii].Name, GUIName) == 0) + return ii; + if ((guis[ii].Name[0u] == 'g') && (ags_stricmp(guis[ii].Name.GetCStr() + 1, GUIName) == 0)) + return ii; + } + quit("FindGUIID: No matching GUI found: GUI may have been deleted"); + return -1; } void InterfaceOn(int ifn) { - if ((ifn<0) | (ifn>=game.numgui)) - quit("!GUIOn: invalid GUI specified"); - - EndSkippingUntilCharStops(); - - if (guis[ifn].IsVisible()) { - debug_script_log("GUIOn(%d) ignored (already on)", ifn); - return; - } - guis_need_update = 1; - guis[ifn].SetVisible(true); - debug_script_log("GUI %d turned on", ifn); - // modal interface - if (guis[ifn].PopupStyle==kGUIPopupModal) PauseGame(); - // clear the cached mouse position - guis[ifn].OnControlPositionChanged(); - guis[ifn].Poll(); + if ((ifn < 0) | (ifn >= game.numgui)) + quit("!GUIOn: invalid GUI specified"); + + EndSkippingUntilCharStops(); + + if (guis[ifn].IsVisible()) { + debug_script_log("GUIOn(%d) ignored (already on)", ifn); + return; + } + guis_need_update = 1; + guis[ifn].SetVisible(true); + debug_script_log("GUI %d turned on", ifn); + // modal interface + if (guis[ifn].PopupStyle == kGUIPopupModal) PauseGame(); + // clear the cached mouse position + guis[ifn].OnControlPositionChanged(); + guis[ifn].Poll(); } void InterfaceOff(int ifn) { - if ((ifn<0) | (ifn>=game.numgui)) quit("!GUIOff: invalid GUI specified"); - if (!guis[ifn].IsVisible()) { - debug_script_log("GUIOff(%d) ignored (already off)", ifn); - return; - } - debug_script_log("GUI %d turned off", ifn); - guis[ifn].SetVisible(false); - if (guis[ifn].MouseOverCtrl>=0) { - // Make sure that the overpic is turned off when the GUI goes off - guis[ifn].GetControl(guis[ifn].MouseOverCtrl)->OnMouseLeave(); - guis[ifn].MouseOverCtrl = -1; - } - guis[ifn].OnControlPositionChanged(); - guis_need_update = 1; - // modal interface - if (guis[ifn].PopupStyle==kGUIPopupModal) UnPauseGame(); + if ((ifn < 0) | (ifn >= game.numgui)) quit("!GUIOff: invalid GUI specified"); + if (!guis[ifn].IsVisible()) { + debug_script_log("GUIOff(%d) ignored (already off)", ifn); + return; + } + debug_script_log("GUI %d turned off", ifn); + guis[ifn].SetVisible(false); + if (guis[ifn].MouseOverCtrl >= 0) { + // Make sure that the overpic is turned off when the GUI goes off + guis[ifn].GetControl(guis[ifn].MouseOverCtrl)->OnMouseLeave(); + guis[ifn].MouseOverCtrl = -1; + } + guis[ifn].OnControlPositionChanged(); + guis_need_update = 1; + // modal interface + if (guis[ifn].PopupStyle == kGUIPopupModal) UnPauseGame(); } void SetGUIObjectEnabled(int guin, int objn, int enabled) { - if ((guin<0) || (guin>=game.numgui)) - quit("!SetGUIObjectEnabled: invalid GUI number"); - if ((objn<0) || (objn>=guis[guin].GetControlCount())) - quit("!SetGUIObjectEnabled: invalid object number"); + if ((guin < 0) || (guin >= game.numgui)) + quit("!SetGUIObjectEnabled: invalid GUI number"); + if ((objn < 0) || (objn >= guis[guin].GetControlCount())) + quit("!SetGUIObjectEnabled: invalid object number"); - GUIControl_SetEnabled(guis[guin].GetControl(objn), enabled); + GUIControl_SetEnabled(guis[guin].GetControl(objn), enabled); } void SetGUIObjectPosition(int guin, int objn, int xx, int yy) { - if ((guin<0) || (guin>=game.numgui)) - quit("!SetGUIObjectPosition: invalid GUI number"); - if ((objn<0) || (objn>=guis[guin].GetControlCount())) - quit("!SetGUIObjectPosition: invalid object number"); + if ((guin < 0) || (guin >= game.numgui)) + quit("!SetGUIObjectPosition: invalid GUI number"); + if ((objn < 0) || (objn >= guis[guin].GetControlCount())) + quit("!SetGUIObjectPosition: invalid object number"); - GUIControl_SetPosition(guis[guin].GetControl(objn), xx, yy); + GUIControl_SetPosition(guis[guin].GetControl(objn), xx, yy); } -void SetGUIPosition(int ifn,int xx,int yy) { - if ((ifn<0) || (ifn>=game.numgui)) - quit("!SetGUIPosition: invalid GUI number"); - - GUI_SetPosition(&scrGui[ifn], xx, yy); +void SetGUIPosition(int ifn, int xx, int yy) { + if ((ifn < 0) || (ifn >= game.numgui)) + quit("!SetGUIPosition: invalid GUI number"); + + GUI_SetPosition(&scrGui[ifn], xx, yy); } void SetGUIObjectSize(int ifn, int objn, int newwid, int newhit) { - if ((ifn<0) || (ifn>=game.numgui)) - quit("!SetGUIObjectSize: invalid GUI number"); + if ((ifn < 0) || (ifn >= game.numgui)) + quit("!SetGUIObjectSize: invalid GUI number"); - if ((objn<0) || (objn >= guis[ifn].GetControlCount())) - quit("!SetGUIObjectSize: invalid object number"); + if ((objn < 0) || (objn >= guis[ifn].GetControlCount())) + quit("!SetGUIObjectSize: invalid object number"); - GUIControl_SetSize(guis[ifn].GetControl(objn), newwid, newhit); + GUIControl_SetSize(guis[ifn].GetControl(objn), newwid, newhit); } -void SetGUISize (int ifn, int widd, int hitt) { - if ((ifn<0) || (ifn>=game.numgui)) - quit("!SetGUISize: invalid GUI number"); +void SetGUISize(int ifn, int widd, int hitt) { + if ((ifn < 0) || (ifn >= game.numgui)) + quit("!SetGUISize: invalid GUI number"); - GUI_SetSize(&scrGui[ifn], widd, hitt); + GUI_SetSize(&scrGui[ifn], widd, hitt); } void SetGUIZOrder(int guin, int z) { - if ((guin<0) || (guin>=game.numgui)) - quit("!SetGUIZOrder: invalid GUI number"); + if ((guin < 0) || (guin >= game.numgui)) + quit("!SetGUIZOrder: invalid GUI number"); - GUI_SetZOrder(&scrGui[guin], z); + GUI_SetZOrder(&scrGui[guin], z); } void SetGUIClickable(int guin, int clickable) { - if ((guin<0) || (guin>=game.numgui)) - quit("!SetGUIClickable: invalid GUI number"); + if ((guin < 0) || (guin >= game.numgui)) + quit("!SetGUIClickable: invalid GUI number"); - GUI_SetClickable(&scrGui[guin], clickable); + GUI_SetClickable(&scrGui[guin], clickable); } // pass trans=0 for fully solid, trans=100 for fully transparent void SetGUITransparency(int ifn, int trans) { - if ((ifn < 0) | (ifn >= game.numgui)) - quit("!SetGUITransparency: invalid GUI number"); + if ((ifn < 0) | (ifn >= game.numgui)) + quit("!SetGUITransparency: invalid GUI number"); - GUI_SetTransparency(&scrGui[ifn], trans); + GUI_SetTransparency(&scrGui[ifn], trans); } -void CentreGUI (int ifn) { - if ((ifn<0) | (ifn>=game.numgui)) - quit("!CentreGUI: invalid GUI number"); +void CentreGUI(int ifn) { + if ((ifn < 0) | (ifn >= game.numgui)) + quit("!CentreGUI: invalid GUI number"); - GUI_Centre(&scrGui[ifn]); + GUI_Centre(&scrGui[ifn]); } int GetTextWidth(const char *text, int fontnum) { - VALIDATE_STRING(text); - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!GetTextWidth: invalid font number."); + VALIDATE_STRING(text); + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetTextWidth: invalid font number."); - return game_to_data_coord(wgettextwidth_compensate(text, fontnum)); + return game_to_data_coord(wgettextwidth_compensate(text, fontnum)); } int GetTextHeight(const char *text, int fontnum, int width) { - VALIDATE_STRING(text); - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!GetTextHeight: invalid font number."); + VALIDATE_STRING(text); + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetTextHeight: invalid font number."); - if (break_up_text_into_lines(text, Lines, data_to_game_coord(width), fontnum) == 0) - return 0; - return game_to_data_coord(getheightoflines(fontnum, Lines.Count())); + if (break_up_text_into_lines(text, Lines, data_to_game_coord(width), fontnum) == 0) + return 0; + return game_to_data_coord(getheightoflines(fontnum, Lines.Count())); } -int GetFontHeight(int fontnum) -{ - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!GetFontHeight: invalid font number."); - return game_to_data_coord(getfontheight_outlined(fontnum)); +int GetFontHeight(int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetFontHeight: invalid font number."); + return game_to_data_coord(getfontheight_outlined(fontnum)); } -int GetFontLineSpacing(int fontnum) -{ - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!GetFontLineSpacing: invalid font number."); - return game_to_data_coord(getfontspacing_outlined(fontnum)); +int GetFontLineSpacing(int fontnum) { + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!GetFontLineSpacing: invalid font number."); + return game_to_data_coord(getfontspacing_outlined(fontnum)); } -void SetGUIBackgroundPic (int guin, int slotn) { - if ((guin<0) | (guin>=game.numgui)) - quit("!SetGUIBackgroundPic: invalid GUI number"); +void SetGUIBackgroundPic(int guin, int slotn) { + if ((guin < 0) | (guin >= game.numgui)) + quit("!SetGUIBackgroundPic: invalid GUI number"); - GUI_SetBackgroundGraphic(&scrGui[guin], slotn); + GUI_SetBackgroundGraphic(&scrGui[guin], slotn); } void DisableInterface() { - play.disabled_user_interface++; - guis_need_update = 1; - set_mouse_cursor(CURS_WAIT); - } + play.disabled_user_interface++; + guis_need_update = 1; + set_mouse_cursor(CURS_WAIT); +} void EnableInterface() { - guis_need_update = 1; - play.disabled_user_interface--; - if (play.disabled_user_interface<1) { - play.disabled_user_interface=0; - set_default_cursor(); - } - } + guis_need_update = 1; + play.disabled_user_interface--; + if (play.disabled_user_interface < 1) { + play.disabled_user_interface = 0; + set_default_cursor(); + } +} // Returns 1 if user interface is enabled, 0 if disabled int IsInterfaceEnabled() { - return (play.disabled_user_interface > 0) ? 0 : 1; + return (play.disabled_user_interface > 0) ? 0 : 1; } -int GetGUIObjectAt (int xx, int yy) { - GUIObject *toret = GetGUIControlAtLocation(xx, yy); - if (toret == nullptr) - return -1; +int GetGUIObjectAt(int xx, int yy) { + GUIObject *toret = GetGUIControlAtLocation(xx, yy); + if (toret == nullptr) + return -1; - return toret->Id; + return toret->Id; } -int GetGUIAt (int xx,int yy) { - data_to_game_coords(&xx, &yy); +int GetGUIAt(int xx, int yy) { + data_to_game_coords(&xx, &yy); - int aa, ll; - for (ll = game.numgui - 1; ll >= 0; ll--) { - aa = play.gui_draw_order[ll]; - if (guis[aa].IsInteractableAt(xx, yy)) - return aa; - } - return -1; + int aa, ll; + for (ll = game.numgui - 1; ll >= 0; ll--) { + aa = play.gui_draw_order[ll]; + if (guis[aa].IsInteractableAt(xx, yy)) + return aa; + } + return -1; } -void SetTextWindowGUI (int guinum) { - if ((guinum < -1) | (guinum >= game.numgui)) - quit("!SetTextWindowGUI: invalid GUI number"); +void SetTextWindowGUI(int guinum) { + if ((guinum < -1) | (guinum >= game.numgui)) + quit("!SetTextWindowGUI: invalid GUI number"); - if (guinum < 0) ; // disable it - else if (!guis[guinum].IsTextWindow()) - quit("!SetTextWindowGUI: specified GUI is not a text window"); + if (guinum < 0) ; // disable it + else if (!guis[guinum].IsTextWindow()) + quit("!SetTextWindowGUI: specified GUI is not a text window"); - if (play.speech_textwindow_gui == game.options[OPT_TWCUSTOM]) - play.speech_textwindow_gui = guinum; - game.options[OPT_TWCUSTOM] = guinum; + if (play.speech_textwindow_gui == game.options[OPT_TWCUSTOM]) + play.speech_textwindow_gui = guinum; + game.options[OPT_TWCUSTOM] = guinum; } diff --git a/engines/ags/engine/ac/global_gui.h b/engines/ags/engine/ac/global_gui.h index 680021442a25..3539a5cf1df4 100644 --- a/engines/ags/engine/ac/global_gui.h +++ b/engines/ags/engine/ac/global_gui.h @@ -24,21 +24,21 @@ #define AGS_ENGINE_AC_GLOBAL_GUI_H // IsGUIOn tells whether GUI is actually displayed on screen right now -int IsGUIOn (int guinum); +int IsGUIOn(int guinum); // This is an internal script function, and is undocumented. // It is used by the editor's automatic macro generation. // TODO: find out how relevant this comment is? -int FindGUIID (const char* GUIName); +int FindGUIID(const char *GUIName); // Sets GUI visible property on void InterfaceOn(int ifn); // Sets GUI visible property off void InterfaceOff(int ifn); -void CentreGUI (int ifn); +void CentreGUI(int ifn); int GetTextWidth(const char *text, int fontnum); int GetTextHeight(const char *text, int fontnum, int width); int GetFontHeight(int fontnum); int GetFontLineSpacing(int fontnum); -void SetGUIBackgroundPic (int guin, int slotn); +void SetGUIBackgroundPic(int guin, int slotn); void DisableInterface(); void EnableInterface(); // Returns 1 if user interface is enabled, 0 if disabled @@ -47,13 +47,13 @@ int IsInterfaceEnabled(); void SetGUITransparency(int ifn, int trans); void SetGUIClickable(int guin, int clickable); void SetGUIZOrder(int guin, int z); -void SetGUISize (int ifn, int widd, int hitt); -void SetGUIPosition(int ifn,int xx,int yy); +void SetGUISize(int ifn, int widd, int hitt); +void SetGUIPosition(int ifn, int xx, int yy); void SetGUIObjectSize(int ifn, int objn, int newwid, int newhit); void SetGUIObjectEnabled(int guin, int objn, int enabled); void SetGUIObjectPosition(int guin, int objn, int xx, int yy); -int GetGUIObjectAt (int xx, int yy); -int GetGUIAt (int xx,int yy); -void SetTextWindowGUI (int guinum); +int GetGUIObjectAt(int xx, int yy); +int GetGUIAt(int xx, int yy); +void SetTextWindowGUI(int guinum); #endif diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp index 55da38845490..c24917104f1f 100644 --- a/engines/ags/engine/ac/global_hotspot.cpp +++ b/engines/ags/engine/ac/global_hotspot.cpp @@ -40,116 +40,112 @@ using namespace AGS::Common; extern RoomStruct thisroom; -extern RoomStatus*croom; -extern CharacterInfo*playerchar; +extern RoomStatus *croom; +extern CharacterInfo *playerchar; extern GameSetupStruct game; void DisableHotspot(int hsnum) { - if ((hsnum<1) | (hsnum>=MAX_ROOM_HOTSPOTS)) - quit("!DisableHotspot: invalid hotspot specified"); - croom->hotspot_enabled[hsnum]=0; - debug_script_log("Hotspot %d disabled", hsnum); + if ((hsnum < 1) | (hsnum >= MAX_ROOM_HOTSPOTS)) + quit("!DisableHotspot: invalid hotspot specified"); + croom->hotspot_enabled[hsnum] = 0; + debug_script_log("Hotspot %d disabled", hsnum); } void EnableHotspot(int hsnum) { - if ((hsnum<1) | (hsnum>=MAX_ROOM_HOTSPOTS)) - quit("!EnableHotspot: invalid hotspot specified"); - croom->hotspot_enabled[hsnum]=1; - debug_script_log("Hotspot %d re-enabled", hsnum); + if ((hsnum < 1) | (hsnum >= MAX_ROOM_HOTSPOTS)) + quit("!EnableHotspot: invalid hotspot specified"); + croom->hotspot_enabled[hsnum] = 1; + debug_script_log("Hotspot %d re-enabled", hsnum); } -int GetHotspotPointX (int hotspot) { - if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) - quit("!GetHotspotPointX: invalid hotspot"); +int GetHotspotPointX(int hotspot) { + if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) + quit("!GetHotspotPointX: invalid hotspot"); - if (thisroom.Hotspots[hotspot].WalkTo.X < 1) - return -1; + if (thisroom.Hotspots[hotspot].WalkTo.X < 1) + return -1; - return thisroom.Hotspots[hotspot].WalkTo.X; + return thisroom.Hotspots[hotspot].WalkTo.X; } -int GetHotspotPointY (int hotspot) { - if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) - quit("!GetHotspotPointY: invalid hotspot"); +int GetHotspotPointY(int hotspot) { + if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) + quit("!GetHotspotPointY: invalid hotspot"); - if (thisroom.Hotspots[hotspot].WalkTo.X < 1) // TODO: there was "x" here, why? - return -1; + if (thisroom.Hotspots[hotspot].WalkTo.X < 1) // TODO: there was "x" here, why? + return -1; - return thisroom.Hotspots[hotspot].WalkTo.Y; + return thisroom.Hotspots[hotspot].WalkTo.Y; } int GetHotspotIDAtScreen(int scrx, int scry) { - VpPoint vpt = play.ScreenToRoomDivDown(scrx, scry); - if (vpt.second < 0) return 0; - return get_hotspot_at(vpt.first.X, vpt.first.Y); + VpPoint vpt = play.ScreenToRoomDivDown(scrx, scry); + if (vpt.second < 0) return 0; + return get_hotspot_at(vpt.first.X, vpt.first.Y); } void GetHotspotName(int hotspot, char *buffer) { - VALIDATE_STRING(buffer); - if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) - quit("!GetHotspotName: invalid hotspot number"); + VALIDATE_STRING(buffer); + if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS)) + quit("!GetHotspotName: invalid hotspot number"); - strcpy(buffer, get_translation(thisroom.Hotspots[hotspot].Name)); + strcpy(buffer, get_translation(thisroom.Hotspots[hotspot].Name)); } -void RunHotspotInteraction (int hotspothere, int mood) { - - int passon=-1,cdata=-1; - if (mood==MODE_TALK) passon=4; - else if (mood==MODE_WALK) passon=0; - else if (mood==MODE_LOOK) passon=1; - else if (mood==MODE_HAND) passon=2; - else if (mood==MODE_PICKUP) passon=7; - else if (mood==MODE_CUSTOM1) passon = 8; - else if (mood==MODE_CUSTOM2) passon = 9; - else if (mood==MODE_USE) { passon=3; - cdata=playerchar->activeinv; - play.usedinv=cdata; - } - - if ((game.options[OPT_WALKONLOOK]==0) & (mood==MODE_LOOK)) ; - else if (play.auto_use_walkto_points == 0) ; - else if ((mood!=MODE_WALK) && (play.check_interaction_only == 0)) - MoveCharacterToHotspot(game.playercharacter,hotspothere); - - // can't use the setevent functions because this ProcessClick is only - // executed once in a eventlist - const char *oldbasename = evblockbasename; - int oldblocknum = evblocknum; - - evblockbasename="hotspot%d"; - evblocknum=hotspothere; - - if (thisroom.Hotspots[hotspothere].EventHandlers != nullptr) - { - if (passon>=0) - run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), passon, 5, (passon == 3)); - run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), 5); // any click on hotspot - } - else - { - if (passon>=0) { - if (run_interaction_event(&croom->intrHotspot[hotspothere],passon, 5, (passon == 3))) { - evblockbasename = oldbasename; - evblocknum = oldblocknum; - return; - } - } - // run the 'any click on hs' event - run_interaction_event(&croom->intrHotspot[hotspothere],5); - } - - evblockbasename = oldbasename; - evblocknum = oldblocknum; +void RunHotspotInteraction(int hotspothere, int mood) { + + int passon = -1, cdata = -1; + if (mood == MODE_TALK) passon = 4; + else if (mood == MODE_WALK) passon = 0; + else if (mood == MODE_LOOK) passon = 1; + else if (mood == MODE_HAND) passon = 2; + else if (mood == MODE_PICKUP) passon = 7; + else if (mood == MODE_CUSTOM1) passon = 8; + else if (mood == MODE_CUSTOM2) passon = 9; + else if (mood == MODE_USE) { + passon = 3; + cdata = playerchar->activeinv; + play.usedinv = cdata; + } + + if ((game.options[OPT_WALKONLOOK] == 0) & (mood == MODE_LOOK)) ; + else if (play.auto_use_walkto_points == 0) ; + else if ((mood != MODE_WALK) && (play.check_interaction_only == 0)) + MoveCharacterToHotspot(game.playercharacter, hotspothere); + + // can't use the setevent functions because this ProcessClick is only + // executed once in a eventlist + const char *oldbasename = evblockbasename; + int oldblocknum = evblocknum; + + evblockbasename = "hotspot%d"; + evblocknum = hotspothere; + + if (thisroom.Hotspots[hotspothere].EventHandlers != nullptr) { + if (passon >= 0) + run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), passon, 5, (passon == 3)); + run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), 5); // any click on hotspot + } else { + if (passon >= 0) { + if (run_interaction_event(&croom->intrHotspot[hotspothere], passon, 5, (passon == 3))) { + evblockbasename = oldbasename; + evblocknum = oldblocknum; + return; + } + } + // run the 'any click on hs' event + run_interaction_event(&croom->intrHotspot[hotspothere], 5); + } + + evblockbasename = oldbasename; + evblocknum = oldblocknum; } -int GetHotspotProperty (int hss, const char *property) -{ - return get_int_property(thisroom.Hotspots[hss].Properties, croom->hsProps[hss], property); +int GetHotspotProperty(int hss, const char *property) { + return get_int_property(thisroom.Hotspots[hss].Properties, croom->hsProps[hss], property); } -void GetHotspotPropertyText (int item, const char *property, char *bufer) -{ - get_text_property(thisroom.Hotspots[item].Properties, croom->hsProps[item], property, bufer); +void GetHotspotPropertyText(int item, const char *property, char *bufer) { + get_text_property(thisroom.Hotspots[item].Properties, croom->hsProps[item], property, bufer); } diff --git a/engines/ags/engine/ac/global_hotspot.h b/engines/ags/engine/ac/global_hotspot.h index 339322b9c317..36eb1846709d 100644 --- a/engines/ags/engine/ac/global_hotspot.h +++ b/engines/ags/engine/ac/global_hotspot.h @@ -25,16 +25,16 @@ void DisableHotspot(int hsnum); void EnableHotspot(int hsnum); -int GetHotspotPointX (int hotspot); -int GetHotspotPointY (int hotspot); +int GetHotspotPointX(int hotspot); +int GetHotspotPointY(int hotspot); // Gets hotspot ID at the given screen coordinates; // if hotspot is disabled or non-existing, returns 0 (no area) -int GetHotspotIDAtScreen(int xxx,int yyy); +int GetHotspotIDAtScreen(int xxx, int yyy); void GetHotspotName(int hotspot, char *buffer); -void RunHotspotInteraction (int hotspothere, int mood); +void RunHotspotInteraction(int hotspothere, int mood); -int GetHotspotProperty (int hss, const char *property); -void GetHotspotPropertyText (int item, const char *property, char *bufer); +int GetHotspotProperty(int hss, const char *property); +void GetHotspotPropertyText(int item, const char *property, char *bufer); #endif diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp index 680b6afd4704..117a52492aec 100644 --- a/engines/ags/engine/ac/global_inventoryitem.cpp +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -39,114 +39,112 @@ using namespace AGS::Common; extern GameSetupStruct game; extern GameState play; extern int mousex, mousey; -extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; -extern const char*evblockbasename; +extern int mouse_ifacebut_xoffs, mouse_ifacebut_yoffs; +extern const char *evblockbasename; extern int evblocknum; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; void set_inv_item_pic(int invi, int piccy) { - if ((invi < 1) || (invi > game.numinvitems)) - quit("!SetInvItemPic: invalid inventory item specified"); + if ((invi < 1) || (invi > game.numinvitems)) + quit("!SetInvItemPic: invalid inventory item specified"); - if (game.invinfo[invi].pic == piccy) - return; + if (game.invinfo[invi].pic == piccy) + return; - if (game.invinfo[invi].pic == game.invinfo[invi].cursorPic) - { - // Backwards compatibility -- there didn't used to be a cursorPic, - // so if they're the same update both. - set_inv_item_cursorpic(invi, piccy); - } + if (game.invinfo[invi].pic == game.invinfo[invi].cursorPic) { + // Backwards compatibility -- there didn't used to be a cursorPic, + // so if they're the same update both. + set_inv_item_cursorpic(invi, piccy); + } - game.invinfo[invi].pic = piccy; - guis_need_update = 1; + game.invinfo[invi].pic = piccy; + guis_need_update = 1; } void SetInvItemName(int invi, const char *newName) { - if ((invi < 1) || (invi > game.numinvitems)) - quit("!SetInvName: invalid inventory item specified"); + if ((invi < 1) || (invi > game.numinvitems)) + quit("!SetInvName: invalid inventory item specified"); - // set the new name, making sure it doesn't overflow the buffer - strncpy(game.invinfo[invi].name, newName, 25); - game.invinfo[invi].name[24] = 0; + // set the new name, making sure it doesn't overflow the buffer + strncpy(game.invinfo[invi].name, newName, 25); + game.invinfo[invi].name[24] = 0; - // might need to redraw the GUI if it has the inv item name on it - guis_need_update = 1; + // might need to redraw the GUI if it has the inv item name on it + guis_need_update = 1; } -int GetInvAt (int xxx, int yyy) { - int ongui = GetGUIAt (xxx, yyy); - if (ongui >= 0) { - int mxwas = mousex, mywas = mousey; - mousex = data_to_game_coord(xxx) - guis[ongui].X; - mousey = data_to_game_coord(yyy) - guis[ongui].Y; - int onobj = guis[ongui].FindControlUnderMouse(); - GUIObject *guio = guis[ongui].GetControl(onobj); - if (guio) { - mouse_ifacebut_xoffs = mousex-(guio->X); - mouse_ifacebut_yoffs = mousey-(guio->Y); - } - mousex = mxwas; - mousey = mywas; - if (guio && (guis[ongui].GetControlType(onobj) == kGUIInvWindow)) - return offset_over_inv((GUIInvWindow*)guio); - } - return -1; +int GetInvAt(int xxx, int yyy) { + int ongui = GetGUIAt(xxx, yyy); + if (ongui >= 0) { + int mxwas = mousex, mywas = mousey; + mousex = data_to_game_coord(xxx) - guis[ongui].X; + mousey = data_to_game_coord(yyy) - guis[ongui].Y; + int onobj = guis[ongui].FindControlUnderMouse(); + GUIObject *guio = guis[ongui].GetControl(onobj); + if (guio) { + mouse_ifacebut_xoffs = mousex - (guio->X); + mouse_ifacebut_yoffs = mousey - (guio->Y); + } + mousex = mxwas; + mousey = mywas; + if (guio && (guis[ongui].GetControlType(onobj) == kGUIInvWindow)) + return offset_over_inv((GUIInvWindow *)guio); + } + return -1; } -void GetInvName(int indx,char*buff) { - VALIDATE_STRING(buff); - if ((indx<0) | (indx>=game.numinvitems)) quit("!GetInvName: invalid inventory item specified"); - strcpy(buff,get_translation(game.invinfo[indx].name)); +void GetInvName(int indx, char *buff) { + VALIDATE_STRING(buff); + if ((indx < 0) | (indx >= game.numinvitems)) quit("!GetInvName: invalid inventory item specified"); + strcpy(buff, get_translation(game.invinfo[indx].name)); } int GetInvGraphic(int indx) { - if ((indx<0) | (indx>=game.numinvitems)) quit("!GetInvGraphic: invalid inventory item specified"); + if ((indx < 0) | (indx >= game.numinvitems)) quit("!GetInvGraphic: invalid inventory item specified"); - return game.invinfo[indx].pic; + return game.invinfo[indx].pic; } -void RunInventoryInteraction (int iit, int modd) { - if ((iit < 0) || (iit >= game.numinvitems)) - quit("!RunInventoryInteraction: invalid inventory number"); - - evblocknum = iit; - if (modd == MODE_LOOK) - run_event_block_inv(iit, 0); - else if (modd == MODE_HAND) - run_event_block_inv(iit, 1); - else if (modd == MODE_USE) { - play.usedinv = playerchar->activeinv; - run_event_block_inv(iit, 3); - } - else if (modd == MODE_TALK) - run_event_block_inv(iit, 2); - else // other click on invnetory - run_event_block_inv(iit, 4); +void RunInventoryInteraction(int iit, int modd) { + if ((iit < 0) || (iit >= game.numinvitems)) + quit("!RunInventoryInteraction: invalid inventory number"); + + evblocknum = iit; + if (modd == MODE_LOOK) + run_event_block_inv(iit, 0); + else if (modd == MODE_HAND) + run_event_block_inv(iit, 1); + else if (modd == MODE_USE) { + play.usedinv = playerchar->activeinv; + run_event_block_inv(iit, 3); + } else if (modd == MODE_TALK) + run_event_block_inv(iit, 2); + else // other click on invnetory + run_event_block_inv(iit, 4); } -int IsInventoryInteractionAvailable (int item, int mood) { - if ((item < 0) || (item >= MAX_INV)) - quit("!IsInventoryInteractionAvailable: invalid inventory number"); +int IsInventoryInteractionAvailable(int item, int mood) { + if ((item < 0) || (item >= MAX_INV)) + quit("!IsInventoryInteractionAvailable: invalid inventory number"); - play.check_interaction_only = 1; + play.check_interaction_only = 1; - RunInventoryInteraction(item, mood); + RunInventoryInteraction(item, mood); - int ciwas = play.check_interaction_only; - play.check_interaction_only = 0; + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; - if (ciwas == 2) - return 1; + if (ciwas == 2) + return 1; - return 0; + return 0; } -int GetInvProperty (int item, const char *property) { - return get_int_property (game.invProps[item], play.invProps[item], property); +int GetInvProperty(int item, const char *property) { + return get_int_property(game.invProps[item], play.invProps[item], property); } -void GetInvPropertyText (int item, const char *property, char *bufer) { - get_text_property (game.invProps[item], play.invProps[item], property, bufer); +void GetInvPropertyText(int item, const char *property, char *bufer) { + get_text_property(game.invProps[item], play.invProps[item], property, bufer); } diff --git a/engines/ags/engine/ac/global_inventoryitem.h b/engines/ags/engine/ac/global_inventoryitem.h index 56dad5c651c1..332a59cf06ff 100644 --- a/engines/ags/engine/ac/global_inventoryitem.h +++ b/engines/ags/engine/ac/global_inventoryitem.h @@ -25,12 +25,12 @@ void set_inv_item_pic(int invi, int piccy); void SetInvItemName(int invi, const char *newName); -int GetInvAt (int xxx, int yyy); -void GetInvName(int indx,char*buff); +int GetInvAt(int xxx, int yyy); +void GetInvName(int indx, char *buff); int GetInvGraphic(int indx); -void RunInventoryInteraction (int iit, int modd); -int IsInventoryInteractionAvailable (int item, int mood); -int GetInvProperty (int item, const char *property); -void GetInvPropertyText (int item, const char *property, char *bufer); +void RunInventoryInteraction(int iit, int modd); +int IsInventoryInteractionAvailable(int item, int mood); +int GetInvProperty(int item, const char *property); +void GetInvPropertyText(int item, const char *property, char *bufer); #endif diff --git a/engines/ags/engine/ac/global_invwindow.cpp b/engines/ags/engine/ac/global_invwindow.cpp index d09043e99adf..4433a1b347ff 100644 --- a/engines/ags/engine/ac/global_invwindow.cpp +++ b/engines/ags/engine/ac/global_invwindow.cpp @@ -27,22 +27,22 @@ #include "gui/guiinv.h" #include "script/executingscript.h" -extern ExecutingScript*curscript; +extern ExecutingScript *curscript; extern GameState play; void sc_invscreen() { - curscript->queue_action(ePSAInvScreen, 0, "InventoryScreen"); + curscript->queue_action(ePSAInvScreen, 0, "InventoryScreen"); } -void SetInvDimensions(int ww,int hh) { - play.inv_item_wid = ww; - play.inv_item_hit = hh; - play.inv_numdisp = 0; - // backwards compatibility - for (int i = 0; i < numguiinv; i++) { - guiinv[i].ItemWidth = ww; - guiinv[i].ItemHeight = hh; - guiinv[i].OnResized(); - } - guis_need_update = 1; +void SetInvDimensions(int ww, int hh) { + play.inv_item_wid = ww; + play.inv_item_hit = hh; + play.inv_numdisp = 0; + // backwards compatibility + for (int i = 0; i < numguiinv; i++) { + guiinv[i].ItemWidth = ww; + guiinv[i].ItemHeight = hh; + guiinv[i].OnResized(); + } + guis_need_update = 1; } diff --git a/engines/ags/engine/ac/global_invwindow.h b/engines/ags/engine/ac/global_invwindow.h index fa2e5b6752dc..7e952fd0e605 100644 --- a/engines/ags/engine/ac/global_invwindow.h +++ b/engines/ags/engine/ac/global_invwindow.h @@ -24,6 +24,6 @@ #define AGS_ENGINE_AC_GLOBAL_INVWINDOW_H void sc_invscreen(); -void SetInvDimensions(int ww,int hh); +void SetInvDimensions(int ww, int hh); #endif diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp index a7e4cad662a0..2943089f9c48 100644 --- a/engines/ags/engine/ac/global_label.cpp +++ b/engines/ags/engine/ac/global_label.cpp @@ -31,36 +31,36 @@ using namespace AGS::Common; extern GameSetupStruct game; -void SetLabelColor(int guin,int objn, int colr) { - if ((guin<0) | (guin>=game.numgui)) - quit("!SetLabelColor: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) - quit("!SetLabelColor: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUILabel) - quit("!SetLabelColor: specified control is not a label"); +void SetLabelColor(int guin, int objn, int colr) { + if ((guin < 0) | (guin >= game.numgui)) + quit("!SetLabelColor: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) + quit("!SetLabelColor: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUILabel) + quit("!SetLabelColor: specified control is not a label"); - GUILabel*guil=(GUILabel*)guis[guin].GetControl(objn); - Label_SetColor(guil, colr); + GUILabel *guil = (GUILabel *)guis[guin].GetControl(objn); + Label_SetColor(guil, colr); } -void SetLabelText(int guin,int objn, const char*newtx) { - VALIDATE_STRING(newtx); - if ((guin<0) | (guin>=game.numgui)) quit("!SetLabelText: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetLabelTexT: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUILabel) - quit("!SetLabelText: specified control is not a label"); +void SetLabelText(int guin, int objn, const char *newtx) { + VALIDATE_STRING(newtx); + if ((guin < 0) | (guin >= game.numgui)) quit("!SetLabelText: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetLabelTexT: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUILabel) + quit("!SetLabelText: specified control is not a label"); - GUILabel*guil=(GUILabel*)guis[guin].GetControl(objn); - Label_SetText(guil, newtx); + GUILabel *guil = (GUILabel *)guis[guin].GetControl(objn); + Label_SetText(guil, newtx); } -void SetLabelFont(int guin,int objn, int fontnum) { +void SetLabelFont(int guin, int objn, int fontnum) { - if ((guin<0) | (guin>=game.numgui)) quit("!SetLabelFont: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetLabelFont: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUILabel) - quit("!SetLabelFont: specified control is not a label"); + if ((guin < 0) | (guin >= game.numgui)) quit("!SetLabelFont: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetLabelFont: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUILabel) + quit("!SetLabelFont: specified control is not a label"); - GUILabel*guil=(GUILabel*)guis[guin].GetControl(objn); - Label_SetFont(guil, fontnum); + GUILabel *guil = (GUILabel *)guis[guin].GetControl(objn); + Label_SetFont(guil, fontnum); } diff --git a/engines/ags/engine/ac/global_label.h b/engines/ags/engine/ac/global_label.h index f3553a53938e..5c75f8b08fba 100644 --- a/engines/ags/engine/ac/global_label.h +++ b/engines/ags/engine/ac/global_label.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_LABEL_H #define AGS_ENGINE_AC_GLOBAL_LABEL_H -void SetLabelColor(int guin,int objn, int colr); -void SetLabelText(int guin,int objn, const char*newtx); -void SetLabelFont(int guin,int objn, int fontnum); +void SetLabelColor(int guin, int objn, int colr); +void SetLabelText(int guin, int objn, const char *newtx); +void SetLabelFont(int guin, int objn, int fontnum); #endif diff --git a/engines/ags/engine/ac/global_listbox.cpp b/engines/ags/engine/ac/global_listbox.cpp index f5d93df57fae..99c3938dd2ce 100644 --- a/engines/ags/engine/ac/global_listbox.cpp +++ b/engines/ags/engine/ac/global_listbox.cpp @@ -26,45 +26,45 @@ #include "ac/string.h" void ListBoxClear(int guin, int objn) { - GUIListBox*guisl=is_valid_listbox(guin,objn); - ListBox_Clear(guisl); + GUIListBox *guisl = is_valid_listbox(guin, objn); + ListBox_Clear(guisl); } -void ListBoxAdd(int guin, int objn, const char*newitem) { - GUIListBox*guisl=is_valid_listbox(guin,objn); - ListBox_AddItem(guisl, newitem); +void ListBoxAdd(int guin, int objn, const char *newitem) { + GUIListBox *guisl = is_valid_listbox(guin, objn); + ListBox_AddItem(guisl, newitem); } void ListBoxRemove(int guin, int objn, int itemIndex) { - GUIListBox*guisl = is_valid_listbox(guin,objn); - ListBox_RemoveItem(guisl, itemIndex); + GUIListBox *guisl = is_valid_listbox(guin, objn); + ListBox_RemoveItem(guisl, itemIndex); } int ListBoxGetSelected(int guin, int objn) { - GUIListBox*guisl=is_valid_listbox(guin,objn); - return ListBox_GetSelectedIndex(guisl); + GUIListBox *guisl = is_valid_listbox(guin, objn); + return ListBox_GetSelectedIndex(guisl); } int ListBoxGetNumItems(int guin, int objn) { - GUIListBox*guisl=is_valid_listbox(guin,objn); - return ListBox_GetItemCount(guisl); + GUIListBox *guisl = is_valid_listbox(guin, objn); + return ListBox_GetItemCount(guisl); } -char* ListBoxGetItemText(int guin, int objn, int item, char*buffer) { - VALIDATE_STRING(buffer); - GUIListBox*guisl=is_valid_listbox(guin,objn); - return ListBox_GetItemText(guisl, item, buffer); +char *ListBoxGetItemText(int guin, int objn, int item, char *buffer) { + VALIDATE_STRING(buffer); + GUIListBox *guisl = is_valid_listbox(guin, objn); + return ListBox_GetItemText(guisl, item, buffer); } void ListBoxSetSelected(int guin, int objn, int newsel) { - GUIListBox*guisl=is_valid_listbox(guin,objn); - ListBox_SetSelectedIndex(guisl, newsel); + GUIListBox *guisl = is_valid_listbox(guin, objn); + ListBox_SetSelectedIndex(guisl, newsel); } -void ListBoxSetTopItem (int guin, int objn, int item) { - GUIListBox*guisl = is_valid_listbox(guin,objn); - ListBox_SetTopItem(guisl, item); +void ListBoxSetTopItem(int guin, int objn, int item) { + GUIListBox *guisl = is_valid_listbox(guin, objn); + ListBox_SetTopItem(guisl, item); } -int ListBoxSaveGameList (int guin, int objn) { - GUIListBox*guisl=is_valid_listbox(guin,objn); - return ListBox_FillSaveGameList(guisl); +int ListBoxSaveGameList(int guin, int objn) { + GUIListBox *guisl = is_valid_listbox(guin, objn); + return ListBox_FillSaveGameList(guisl); } -void ListBoxDirList (int guin, int objn, const char*filemask) { - GUIListBox *guisl = is_valid_listbox(guin,objn); - ListBox_FillDirList(guisl, filemask); +void ListBoxDirList(int guin, int objn, const char *filemask) { + GUIListBox *guisl = is_valid_listbox(guin, objn); + ListBox_FillDirList(guisl, filemask); } diff --git a/engines/ags/engine/ac/global_listbox.h b/engines/ags/engine/ac/global_listbox.h index df48eadd77ad..2d781cb425ce 100644 --- a/engines/ags/engine/ac/global_listbox.h +++ b/engines/ags/engine/ac/global_listbox.h @@ -23,15 +23,15 @@ #ifndef AGS_ENGINE_AC_GLOBAL_LISTBOX_H #define AGS_ENGINE_AC_GLOBAL_LISTBOX_H -void ListBoxClear(int guin, int objn); -void ListBoxAdd(int guin, int objn, const char*newitem); -void ListBoxRemove(int guin, int objn, int itemIndex); -int ListBoxGetSelected(int guin, int objn); -int ListBoxGetNumItems(int guin, int objn); -char* ListBoxGetItemText(int guin, int objn, int item, char*buffer); -void ListBoxSetSelected(int guin, int objn, int newsel); -void ListBoxSetTopItem (int guin, int objn, int item); -int ListBoxSaveGameList (int guin, int objn); -void ListBoxDirList (int guin, int objn, const char*filemask); +void ListBoxClear(int guin, int objn); +void ListBoxAdd(int guin, int objn, const char *newitem); +void ListBoxRemove(int guin, int objn, int itemIndex); +int ListBoxGetSelected(int guin, int objn); +int ListBoxGetNumItems(int guin, int objn); +char *ListBoxGetItemText(int guin, int objn, int item, char *buffer); +void ListBoxSetSelected(int guin, int objn, int newsel); +void ListBoxSetTopItem(int guin, int objn, int item); +int ListBoxSaveGameList(int guin, int objn); +void ListBoxDirList(int guin, int objn, const char *filemask); #endif diff --git a/engines/ags/engine/ac/global_mouse.cpp b/engines/ags/engine/ac/global_mouse.cpp index a17871e8289f..af7534661004 100644 --- a/engines/ags/engine/ac/global_mouse.cpp +++ b/engines/ags/engine/ac/global_mouse.cpp @@ -25,10 +25,10 @@ extern GameState play; -void HideMouseCursor () { - play.mouse_cursor_hidden = 1; +void HideMouseCursor() { + play.mouse_cursor_hidden = 1; } -void ShowMouseCursor () { - play.mouse_cursor_hidden = 0; +void ShowMouseCursor() { + play.mouse_cursor_hidden = 0; } diff --git a/engines/ags/engine/ac/global_mouse.h b/engines/ags/engine/ac/global_mouse.h index dacbf5e8ee6a..ecf01627430d 100644 --- a/engines/ags/engine/ac/global_mouse.h +++ b/engines/ags/engine/ac/global_mouse.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBAL_MOUSE_H #define AGS_ENGINE_AC_GLOBAL_MOUSE_H -void HideMouseCursor (); -void ShowMouseCursor (); +void HideMouseCursor(); +void ShowMouseCursor(); #endif diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp index 1132b8184a23..ec7c793e31ca 100644 --- a/engines/ags/engine/ac/global_object.cpp +++ b/engines/ags/engine/ac/global_object.cpp @@ -49,483 +49,469 @@ using namespace AGS::Common; #define OVERLAPPING_OBJECT 1000 -extern RoomStatus*croom; -extern RoomObject*objs; -extern ViewStruct*views; +extern RoomStatus *croom; +extern RoomObject *objs; +extern ViewStruct *views; extern GameSetupStruct game; extern ObjectCache objcache[MAX_ROOM_OBJECTS]; extern RoomStruct thisroom; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern int displayed_room; extern SpriteCache spriteset; extern int actSpsCount; extern Bitmap **actsps; -extern IDriverDependantBitmap* *actspsbmp; +extern IDriverDependantBitmap * *actspsbmp; extern IGraphicsDriver *gfxDriver; // Used for deciding whether a char or obj was closer int obj_lowest_yp; -int GetObjectIDAtScreen(int scrx, int scry) -{ - // translate screen co-ordinates to room co-ordinates - VpPoint vpt = play.ScreenToRoomDivDown(scrx, scry); - if (vpt.second < 0) - return -1; - return GetObjectIDAtRoom(vpt.first.X, vpt.first.Y); -} - -int GetObjectIDAtRoom(int roomx, int roomy) -{ - int aa,bestshotyp=-1,bestshotwas=-1; - // Iterate through all objects in the room - for (aa=0;aanumobj;aa++) { - if (objs[aa].on != 1) continue; - if (objs[aa].flags & OBJF_NOINTERACT) - continue; - int xxx=objs[aa].x,yyy=objs[aa].y; - int isflipped = 0; - int spWidth = game_to_data_coord(objs[aa].get_width()); - int spHeight = game_to_data_coord(objs[aa].get_height()); - if (objs[aa].view >= 0) - isflipped = views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE; - - Bitmap *theImage = GetObjectImage(aa, &isflipped); - - if (is_pos_in_sprite(roomx, roomy, xxx, yyy - spHeight, theImage, - spWidth, spHeight, isflipped) == FALSE) - continue; - - int usebasel = objs[aa].get_baseline(); - if (usebasel < bestshotyp) continue; - - bestshotwas = aa; - bestshotyp = usebasel; - } - obj_lowest_yp = bestshotyp; - return bestshotwas; +int GetObjectIDAtScreen(int scrx, int scry) { + // translate screen co-ordinates to room co-ordinates + VpPoint vpt = play.ScreenToRoomDivDown(scrx, scry); + if (vpt.second < 0) + return -1; + return GetObjectIDAtRoom(vpt.first.X, vpt.first.Y); +} + +int GetObjectIDAtRoom(int roomx, int roomy) { + int aa, bestshotyp = -1, bestshotwas = -1; + // Iterate through all objects in the room + for (aa = 0; aa < croom->numobj; aa++) { + if (objs[aa].on != 1) continue; + if (objs[aa].flags & OBJF_NOINTERACT) + continue; + int xxx = objs[aa].x, yyy = objs[aa].y; + int isflipped = 0; + int spWidth = game_to_data_coord(objs[aa].get_width()); + int spHeight = game_to_data_coord(objs[aa].get_height()); + if (objs[aa].view >= 0) + isflipped = views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE; + + Bitmap *theImage = GetObjectImage(aa, &isflipped); + + if (is_pos_in_sprite(roomx, roomy, xxx, yyy - spHeight, theImage, + spWidth, spHeight, isflipped) == FALSE) + continue; + + int usebasel = objs[aa].get_baseline(); + if (usebasel < bestshotyp) continue; + + bestshotwas = aa; + bestshotyp = usebasel; + } + obj_lowest_yp = bestshotyp; + return bestshotwas; } void SetObjectTint(int obj, int red, int green, int blue, int opacity, int luminance) { - if ((red < 0) || (green < 0) || (blue < 0) || - (red > 255) || (green > 255) || (blue > 255) || - (opacity < 0) || (opacity > 100) || - (luminance < 0) || (luminance > 100)) - quit("!SetObjectTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) + quit("!SetObjectTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); - if (!is_valid_object(obj)) - quit("!SetObjectTint: invalid object number specified"); + if (!is_valid_object(obj)) + quit("!SetObjectTint: invalid object number specified"); - debug_script_log("Set object %d tint RGB(%d,%d,%d) %d%%", obj, red, green, blue, opacity); + debug_script_log("Set object %d tint RGB(%d,%d,%d) %d%%", obj, red, green, blue, opacity); - objs[obj].tint_r = red; - objs[obj].tint_g = green; - objs[obj].tint_b = blue; - objs[obj].tint_level = opacity; - objs[obj].tint_light = (luminance * 25) / 10; - objs[obj].flags &= ~OBJF_HASLIGHT; - objs[obj].flags |= OBJF_HASTINT; + objs[obj].tint_r = red; + objs[obj].tint_g = green; + objs[obj].tint_b = blue; + objs[obj].tint_level = opacity; + objs[obj].tint_light = (luminance * 25) / 10; + objs[obj].flags &= ~OBJF_HASLIGHT; + objs[obj].flags |= OBJF_HASTINT; } void RemoveObjectTint(int obj) { - if (!is_valid_object(obj)) - quit("!RemoveObjectTint: invalid object"); - - if (objs[obj].flags & (OBJF_HASTINT | OBJF_HASLIGHT)) { - debug_script_log("Un-tint object %d", obj); - objs[obj].flags &= ~(OBJF_HASTINT | OBJF_HASLIGHT); - } - else { - debug_script_warn("RemoveObjectTint called but object was not tinted"); - } -} - -void SetObjectView(int obn,int vii) { - if (!is_valid_object(obn)) quit("!SetObjectView: invalid object number specified"); - debug_script_log("Object %d set to view %d", obn, vii); - if ((vii < 1) || (vii > game.numviews)) { - quitprintf("!SetObjectView: invalid view number (You said %d, max is %d)", vii, game.numviews); - } - vii--; - - objs[obn].view=vii; - objs[obn].frame=0; - if (objs[obn].loop >= views[vii].numLoops) - objs[obn].loop=0; - objs[obn].cycling=0; - objs[obn].num = views[vii].loops[0].frames[0].pic; -} - -void SetObjectFrame(int obn,int viw,int lop,int fra) { - if (!is_valid_object(obn)) quit("!SetObjectFrame: invalid object number specified"); - viw--; - if (viw < 0 || viw >= game.numviews) quitprintf("!SetObjectFrame: invalid view number used (%d, range is 0 - %d)", viw, game.numviews - 1); - if (lop < 0 || lop >= views[viw].numLoops) quitprintf("!SetObjectFrame: invalid loop number used (%d, range is 0 - %d)", lop, views[viw].numLoops - 1); - // AGS < 3.5.1 let user to pass literally any positive invalid frame value by silently reassigning it to zero... - if (loaded_game_file_version < kGameVersion_351) - { - if (fra >= views[viw].loops[lop].numFrames) - { - debug_script_warn("SetObjectFrame: frame index out of range (%d, must be 0 - %d), set to 0", fra, views[viw].loops[lop].numFrames - 1); - fra = 0; - } - } - if (fra < 0 || fra >= views[viw].loops[lop].numFrames) quitprintf("!SetObjectFrame: invalid frame number used (%d, range is 0 - %d)", fra, views[viw].loops[lop].numFrames - 1); - // AGS >= 3.2.0 do not let assign an empty loop - // NOTE: pre-3.2.0 games are converting views from ViewStruct272 struct, always has at least 1 frame - if (loaded_game_file_version >= kGameVersion_320) - { - if (views[viw].loops[lop].numFrames == 0) - quit("!SetObjectFrame: specified loop has no frames"); - } - objs[obn].view = viw; - objs[obn].loop = lop; - objs[obn].frame = fra; - objs[obn].cycling=0; - objs[obn].num = views[viw].loops[lop].frames[fra].pic; - CheckViewFrame(viw, objs[obn].loop, objs[obn].frame); + if (!is_valid_object(obj)) + quit("!RemoveObjectTint: invalid object"); + + if (objs[obj].flags & (OBJF_HASTINT | OBJF_HASLIGHT)) { + debug_script_log("Un-tint object %d", obj); + objs[obj].flags &= ~(OBJF_HASTINT | OBJF_HASLIGHT); + } else { + debug_script_warn("RemoveObjectTint called but object was not tinted"); + } +} + +void SetObjectView(int obn, int vii) { + if (!is_valid_object(obn)) quit("!SetObjectView: invalid object number specified"); + debug_script_log("Object %d set to view %d", obn, vii); + if ((vii < 1) || (vii > game.numviews)) { + quitprintf("!SetObjectView: invalid view number (You said %d, max is %d)", vii, game.numviews); + } + vii--; + + objs[obn].view = vii; + objs[obn].frame = 0; + if (objs[obn].loop >= views[vii].numLoops) + objs[obn].loop = 0; + objs[obn].cycling = 0; + objs[obn].num = views[vii].loops[0].frames[0].pic; +} + +void SetObjectFrame(int obn, int viw, int lop, int fra) { + if (!is_valid_object(obn)) quit("!SetObjectFrame: invalid object number specified"); + viw--; + if (viw < 0 || viw >= game.numviews) quitprintf("!SetObjectFrame: invalid view number used (%d, range is 0 - %d)", viw, game.numviews - 1); + if (lop < 0 || lop >= views[viw].numLoops) quitprintf("!SetObjectFrame: invalid loop number used (%d, range is 0 - %d)", lop, views[viw].numLoops - 1); + // AGS < 3.5.1 let user to pass literally any positive invalid frame value by silently reassigning it to zero... + if (loaded_game_file_version < kGameVersion_351) { + if (fra >= views[viw].loops[lop].numFrames) { + debug_script_warn("SetObjectFrame: frame index out of range (%d, must be 0 - %d), set to 0", fra, views[viw].loops[lop].numFrames - 1); + fra = 0; + } + } + if (fra < 0 || fra >= views[viw].loops[lop].numFrames) quitprintf("!SetObjectFrame: invalid frame number used (%d, range is 0 - %d)", fra, views[viw].loops[lop].numFrames - 1); + // AGS >= 3.2.0 do not let assign an empty loop + // NOTE: pre-3.2.0 games are converting views from ViewStruct272 struct, always has at least 1 frame + if (loaded_game_file_version >= kGameVersion_320) { + if (views[viw].loops[lop].numFrames == 0) + quit("!SetObjectFrame: specified loop has no frames"); + } + objs[obn].view = viw; + objs[obn].loop = lop; + objs[obn].frame = fra; + objs[obn].cycling = 0; + objs[obn].num = views[viw].loops[lop].frames[fra].pic; + CheckViewFrame(viw, objs[obn].loop, objs[obn].frame); } // pass trans=0 for fully solid, trans=100 for fully transparent -void SetObjectTransparency(int obn,int trans) { - if (!is_valid_object(obn)) quit("!SetObjectTransparent: invalid object number specified"); - if ((trans < 0) || (trans > 100)) quit("!SetObjectTransparent: transparency value must be between 0 and 100"); +void SetObjectTransparency(int obn, int trans) { + if (!is_valid_object(obn)) quit("!SetObjectTransparent: invalid object number specified"); + if ((trans < 0) || (trans > 100)) quit("!SetObjectTransparent: transparency value must be between 0 and 100"); - objs[obn].transparent = GfxDef::Trans100ToLegacyTrans255(trans); + objs[obn].transparent = GfxDef::Trans100ToLegacyTrans255(trans); } -void SetObjectBaseline (int obn, int basel) { - if (!is_valid_object(obn)) quit("!SetObjectBaseline: invalid object number specified"); - // baseline has changed, invalidate the cache - if (objs[obn].baseline != basel) { - objcache[obn].ywas = -9999; - objs[obn].baseline = basel; - } +void SetObjectBaseline(int obn, int basel) { + if (!is_valid_object(obn)) quit("!SetObjectBaseline: invalid object number specified"); + // baseline has changed, invalidate the cache + if (objs[obn].baseline != basel) { + objcache[obn].ywas = -9999; + objs[obn].baseline = basel; + } } int GetObjectBaseline(int obn) { - if (!is_valid_object(obn)) quit("!GetObjectBaseline: invalid object number specified"); + if (!is_valid_object(obn)) quit("!GetObjectBaseline: invalid object number specified"); - if (objs[obn].baseline < 1) - return 0; + if (objs[obn].baseline < 1) + return 0; - return objs[obn].baseline; + return objs[obn].baseline; } void AnimateObjectImpl(int obn, int loopn, int spdd, int rept, int direction, int blocking, int sframe) { - if (obn>=MANOBJNUM) { - scAnimateCharacter(obn - 100,loopn,spdd,rept); - return; - } - if (!is_valid_object(obn)) - quit("!AnimateObject: invalid object number specified"); - if (objs[obn].view < 0) - quit("!AnimateObject: object has not been assigned a view"); - if (loopn < 0 || loopn >= views[objs[obn].view].numLoops) - quit("!AnimateObject: invalid loop number specified"); - if (sframe < 0 || sframe >= views[objs[obn].view].loops[loopn].numFrames) - quit("!AnimateObject: invalid starting frame number specified"); - if ((direction < 0) || (direction > 1)) - quit("!AnimateObjectEx: invalid direction"); - if ((rept < 0) || (rept > 2)) - quit("!AnimateObjectEx: invalid repeat value"); - if (views[objs[obn].view].loops[loopn].numFrames < 1) - quit("!AnimateObject: no frames in the specified view loop"); - - debug_script_log("Obj %d start anim view %d loop %d, speed %d, repeat %d, frame %d", obn, objs[obn].view+1, loopn, spdd, rept, sframe); - - objs[obn].cycling = rept+1 + (direction * 10); - objs[obn].loop=loopn; - // reverse animation starts at the *previous frame* - if (direction) { - sframe--; - if (sframe < 0) - sframe = views[objs[obn].view].loops[loopn].numFrames - (-sframe); - } - objs[obn].frame = sframe; - - objs[obn].overall_speed=spdd; - objs[obn].wait = spdd+views[objs[obn].view].loops[loopn].frames[objs[obn].frame].speed; - objs[obn].num = views[objs[obn].view].loops[loopn].frames[objs[obn].frame].pic; - CheckViewFrame (objs[obn].view, loopn, objs[obn].frame); - - if (blocking) - GameLoopUntilValueIsZero(&objs[obn].cycling); + if (obn >= MANOBJNUM) { + scAnimateCharacter(obn - 100, loopn, spdd, rept); + return; + } + if (!is_valid_object(obn)) + quit("!AnimateObject: invalid object number specified"); + if (objs[obn].view < 0) + quit("!AnimateObject: object has not been assigned a view"); + if (loopn < 0 || loopn >= views[objs[obn].view].numLoops) + quit("!AnimateObject: invalid loop number specified"); + if (sframe < 0 || sframe >= views[objs[obn].view].loops[loopn].numFrames) + quit("!AnimateObject: invalid starting frame number specified"); + if ((direction < 0) || (direction > 1)) + quit("!AnimateObjectEx: invalid direction"); + if ((rept < 0) || (rept > 2)) + quit("!AnimateObjectEx: invalid repeat value"); + if (views[objs[obn].view].loops[loopn].numFrames < 1) + quit("!AnimateObject: no frames in the specified view loop"); + + debug_script_log("Obj %d start anim view %d loop %d, speed %d, repeat %d, frame %d", obn, objs[obn].view + 1, loopn, spdd, rept, sframe); + + objs[obn].cycling = rept + 1 + (direction * 10); + objs[obn].loop = loopn; + // reverse animation starts at the *previous frame* + if (direction) { + sframe--; + if (sframe < 0) + sframe = views[objs[obn].view].loops[loopn].numFrames - (-sframe); + } + objs[obn].frame = sframe; + + objs[obn].overall_speed = spdd; + objs[obn].wait = spdd + views[objs[obn].view].loops[loopn].frames[objs[obn].frame].speed; + objs[obn].num = views[objs[obn].view].loops[loopn].frames[objs[obn].frame].pic; + CheckViewFrame(objs[obn].view, loopn, objs[obn].frame); + + if (blocking) + GameLoopUntilValueIsZero(&objs[obn].cycling); } void AnimateObjectEx(int obn, int loopn, int spdd, int rept, int direction, int blocking) { - AnimateObjectImpl(obn, loopn, spdd, rept, direction, blocking, 0); + AnimateObjectImpl(obn, loopn, spdd, rept, direction, blocking, 0); } -void AnimateObject(int obn,int loopn,int spdd,int rept) { - AnimateObjectImpl(obn, loopn, spdd, rept, 0, 0, 0); +void AnimateObject(int obn, int loopn, int spdd, int rept) { + AnimateObjectImpl(obn, loopn, spdd, rept, 0, 0, 0); } void MergeObject(int obn) { - if (!is_valid_object(obn)) quit("!MergeObject: invalid object specified"); - int theHeight; + if (!is_valid_object(obn)) quit("!MergeObject: invalid object specified"); + int theHeight; - construct_object_gfx(obn, nullptr, &theHeight, true); + construct_object_gfx(obn, nullptr, &theHeight, true); - //Bitmap *oldabuf = graphics->bmp; - //abuf = thisroom.BgFrames.Graphic[play.bg_frame]; - PBitmap bg_frame = thisroom.BgFrames[play.bg_frame].Graphic; - if (bg_frame->GetColorDepth() != actsps[obn]->GetColorDepth()) - quit("!MergeObject: unable to merge object due to color depth differences"); + //Bitmap *oldabuf = graphics->bmp; + //abuf = thisroom.BgFrames.Graphic[play.bg_frame]; + PBitmap bg_frame = thisroom.BgFrames[play.bg_frame].Graphic; + if (bg_frame->GetColorDepth() != actsps[obn]->GetColorDepth()) + quit("!MergeObject: unable to merge object due to color depth differences"); - int xpos = data_to_game_coord(objs[obn].x); - int ypos = (data_to_game_coord(objs[obn].y) - theHeight); + int xpos = data_to_game_coord(objs[obn].x); + int ypos = (data_to_game_coord(objs[obn].y) - theHeight); - draw_sprite_support_alpha(bg_frame.get(), false, xpos, ypos, actsps[obn], (game.SpriteInfos[objs[obn].num].Flags & SPF_ALPHACHANNEL) != 0); - invalidate_screen(); - mark_current_background_dirty(); + draw_sprite_support_alpha(bg_frame.get(), false, xpos, ypos, actsps[obn], (game.SpriteInfos[objs[obn].num].Flags & SPF_ALPHACHANNEL) != 0); + invalidate_screen(); + mark_current_background_dirty(); - //abuf = oldabuf; - // mark the sprite as merged - objs[obn].on = 2; - debug_script_log("Object %d merged into background", obn); + //abuf = oldabuf; + // mark the sprite as merged + objs[obn].on = 2; + debug_script_log("Object %d merged into background", obn); } void StopObjectMoving(int objj) { - if (!is_valid_object(objj)) - quit("!StopObjectMoving: invalid object number"); - objs[objj].moving = 0; + if (!is_valid_object(objj)) + quit("!StopObjectMoving: invalid object number"); + objs[objj].moving = 0; - debug_script_log("Object %d stop moving", objj); + debug_script_log("Object %d stop moving", objj); } void ObjectOff(int obn) { - if (!is_valid_object(obn)) quit("!ObjectOff: invalid object specified"); - // don't change it if on == 2 (merged) - if (objs[obn].on == 1) { - objs[obn].on = 0; - debug_script_log("Object %d turned off", obn); - StopObjectMoving(obn); - } + if (!is_valid_object(obn)) quit("!ObjectOff: invalid object specified"); + // don't change it if on == 2 (merged) + if (objs[obn].on == 1) { + objs[obn].on = 0; + debug_script_log("Object %d turned off", obn); + StopObjectMoving(obn); + } } void ObjectOn(int obn) { - if (!is_valid_object(obn)) quit("!ObjectOn: invalid object specified"); - if (objs[obn].on == 0) { - objs[obn].on = 1; - debug_script_log("Object %d turned on", obn); - } + if (!is_valid_object(obn)) quit("!ObjectOn: invalid object specified"); + if (objs[obn].on == 0) { + objs[obn].on = 1; + debug_script_log("Object %d turned on", obn); + } } -int IsObjectOn (int objj) { - if (!is_valid_object(objj)) quit("!IsObjectOn: invalid object number"); +int IsObjectOn(int objj) { + if (!is_valid_object(objj)) quit("!IsObjectOn: invalid object number"); - // ==1 is on, ==2 is merged into background - if (objs[objj].on == 1) - return 1; + // ==1 is on, ==2 is merged into background + if (objs[objj].on == 1) + return 1; - return 0; + return 0; } -void SetObjectGraphic(int obn,int slott) { - if (!is_valid_object(obn)) quit("!SetObjectGraphic: invalid object specified"); +void SetObjectGraphic(int obn, int slott) { + if (!is_valid_object(obn)) quit("!SetObjectGraphic: invalid object specified"); - if (objs[obn].num != slott) { - objs[obn].num = slott; - debug_script_log("Object %d graphic changed to slot %d", obn, slott); - } - objs[obn].cycling=0; - objs[obn].frame = 0; - objs[obn].loop = 0; - objs[obn].view = -1; + if (objs[obn].num != slott) { + objs[obn].num = slott; + debug_script_log("Object %d graphic changed to slot %d", obn, slott); + } + objs[obn].cycling = 0; + objs[obn].frame = 0; + objs[obn].loop = 0; + objs[obn].view = -1; } int GetObjectGraphic(int obn) { - if (!is_valid_object(obn)) quit("!GetObjectGraphic: invalid object specified"); - return objs[obn].num; + if (!is_valid_object(obn)) quit("!GetObjectGraphic: invalid object specified"); + return objs[obn].num; } -int GetObjectY (int objj) { - if (!is_valid_object(objj)) quit("!GetObjectY: invalid object number"); - return objs[objj].y; +int GetObjectY(int objj) { + if (!is_valid_object(objj)) quit("!GetObjectY: invalid object number"); + return objs[objj].y; } int IsObjectAnimating(int objj) { - if (!is_valid_object(objj)) quit("!IsObjectAnimating: invalid object number"); - return (objs[objj].cycling != 0) ? 1 : 0; + if (!is_valid_object(objj)) quit("!IsObjectAnimating: invalid object number"); + return (objs[objj].cycling != 0) ? 1 : 0; } int IsObjectMoving(int objj) { - if (!is_valid_object(objj)) quit("!IsObjectMoving: invalid object number"); - return (objs[objj].moving > 0) ? 1 : 0; + if (!is_valid_object(objj)) quit("!IsObjectMoving: invalid object number"); + return (objs[objj].moving > 0) ? 1 : 0; } void SetObjectPosition(int objj, int tox, int toy) { - if (!is_valid_object(objj)) - quit("!SetObjectPosition: invalid object number"); + if (!is_valid_object(objj)) + quit("!SetObjectPosition: invalid object number"); - if (objs[objj].moving > 0) - { - debug_script_warn("Object.SetPosition: cannot set position while object is moving"); - return; - } + if (objs[objj].moving > 0) { + debug_script_warn("Object.SetPosition: cannot set position while object is moving"); + return; + } - objs[objj].x = tox; - objs[objj].y = toy; + objs[objj].x = tox; + objs[objj].y = toy; } void GetObjectName(int obj, char *buffer) { - VALIDATE_STRING(buffer); - if (!is_valid_object(obj)) - quit("!GetObjectName: invalid object number"); - - strcpy(buffer, get_translation(thisroom.Objects[obj].Name)); -} - -void MoveObject(int objj,int xx,int yy,int spp) { - move_object(objj,xx,yy,spp,0); -} -void MoveObjectDirect(int objj,int xx,int yy,int spp) { - move_object(objj,xx,yy,spp,1); -} - -void SetObjectClickable (int cha, int clik) { - if (!is_valid_object(cha)) - quit("!SetObjectClickable: Invalid object specified"); - objs[cha].flags&=~OBJF_NOINTERACT; - if (clik == 0) - objs[cha].flags|=OBJF_NOINTERACT; -} - -void SetObjectIgnoreWalkbehinds (int cha, int clik) { - if (!is_valid_object(cha)) - quit("!SetObjectIgnoreWalkbehinds: Invalid object specified"); - if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v350) - debug_script_warn("IgnoreWalkbehinds is not recommended for use, consider other solutions"); - objs[cha].flags&=~OBJF_NOWALKBEHINDS; - if (clik) - objs[cha].flags|=OBJF_NOWALKBEHINDS; - // clear the cache - objcache[cha].ywas = -9999; -} - -void RunObjectInteraction (int aa, int mood) { - if (!is_valid_object(aa)) - quit("!RunObjectInteraction: invalid object number for current room"); - int passon=-1,cdata=-1; - if (mood==MODE_LOOK) passon=0; - else if (mood==MODE_HAND) passon=1; - else if (mood==MODE_TALK) passon=2; - else if (mood==MODE_PICKUP) passon=5; - else if (mood==MODE_CUSTOM1) passon = 6; - else if (mood==MODE_CUSTOM2) passon = 7; - else if (mood==MODE_USE) { passon=3; - cdata=playerchar->activeinv; - play.usedinv=cdata; } - evblockbasename="object%d"; evblocknum=aa; - - if (thisroom.Objects[aa].EventHandlers != nullptr) - { - if (passon>=0) - { - if (run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), passon, 4, (passon == 3))) - return; - } - run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), 4); // any click on obj - } - else - { - if (passon>=0) { - if (run_interaction_event(&croom->intrObject[aa],passon, 4, (passon == 3))) - return; - } - run_interaction_event(&croom->intrObject[aa],4); // any click on obj - } -} - -int AreObjectsColliding(int obj1,int obj2) { - if ((!is_valid_object(obj1)) | (!is_valid_object(obj2))) - quit("!AreObjectsColliding: invalid object specified"); - - return (AreThingsOverlapping(obj1 + OVERLAPPING_OBJECT, obj2 + OVERLAPPING_OBJECT)) ? 1 : 0; + VALIDATE_STRING(buffer); + if (!is_valid_object(obj)) + quit("!GetObjectName: invalid object number"); + + strcpy(buffer, get_translation(thisroom.Objects[obj].Name)); +} + +void MoveObject(int objj, int xx, int yy, int spp) { + move_object(objj, xx, yy, spp, 0); +} +void MoveObjectDirect(int objj, int xx, int yy, int spp) { + move_object(objj, xx, yy, spp, 1); +} + +void SetObjectClickable(int cha, int clik) { + if (!is_valid_object(cha)) + quit("!SetObjectClickable: Invalid object specified"); + objs[cha].flags &= ~OBJF_NOINTERACT; + if (clik == 0) + objs[cha].flags |= OBJF_NOINTERACT; +} + +void SetObjectIgnoreWalkbehinds(int cha, int clik) { + if (!is_valid_object(cha)) + quit("!SetObjectIgnoreWalkbehinds: Invalid object specified"); + if (game.options[OPT_BASESCRIPTAPI] >= kScriptAPI_v350) + debug_script_warn("IgnoreWalkbehinds is not recommended for use, consider other solutions"); + objs[cha].flags &= ~OBJF_NOWALKBEHINDS; + if (clik) + objs[cha].flags |= OBJF_NOWALKBEHINDS; + // clear the cache + objcache[cha].ywas = -9999; +} + +void RunObjectInteraction(int aa, int mood) { + if (!is_valid_object(aa)) + quit("!RunObjectInteraction: invalid object number for current room"); + int passon = -1, cdata = -1; + if (mood == MODE_LOOK) passon = 0; + else if (mood == MODE_HAND) passon = 1; + else if (mood == MODE_TALK) passon = 2; + else if (mood == MODE_PICKUP) passon = 5; + else if (mood == MODE_CUSTOM1) passon = 6; + else if (mood == MODE_CUSTOM2) passon = 7; + else if (mood == MODE_USE) { + passon = 3; + cdata = playerchar->activeinv; + play.usedinv = cdata; + } + evblockbasename = "object%d"; + evblocknum = aa; + + if (thisroom.Objects[aa].EventHandlers != nullptr) { + if (passon >= 0) { + if (run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), passon, 4, (passon == 3))) + return; + } + run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), 4); // any click on obj + } else { + if (passon >= 0) { + if (run_interaction_event(&croom->intrObject[aa], passon, 4, (passon == 3))) + return; + } + run_interaction_event(&croom->intrObject[aa], 4); // any click on obj + } +} + +int AreObjectsColliding(int obj1, int obj2) { + if ((!is_valid_object(obj1)) | (!is_valid_object(obj2))) + quit("!AreObjectsColliding: invalid object specified"); + + return (AreThingsOverlapping(obj1 + OVERLAPPING_OBJECT, obj2 + OVERLAPPING_OBJECT)) ? 1 : 0; } int GetThingRect(int thing, _Rect *rect) { - if (is_valid_character(thing)) { - if (game.chars[thing].room != displayed_room) - return 0; - - int charwid = game_to_data_coord(GetCharacterWidth(thing)); - rect->x1 = game.chars[thing].x - (charwid / 2); - rect->x2 = rect->x1 + charwid; - rect->y1 = game.chars[thing].get_effective_y() - game_to_data_coord(GetCharacterHeight(thing)); - rect->y2 = game.chars[thing].get_effective_y(); - } - else if (is_valid_object(thing - OVERLAPPING_OBJECT)) { - int objid = thing - OVERLAPPING_OBJECT; - if (objs[objid].on != 1) - return 0; - rect->x1 = objs[objid].x; - rect->x2 = objs[objid].x + game_to_data_coord(objs[objid].get_width()); - rect->y1 = objs[objid].y - game_to_data_coord(objs[objid].get_height()); - rect->y2 = objs[objid].y; - } - else - quit("!AreThingsOverlapping: invalid parameter"); - - return 1; + if (is_valid_character(thing)) { + if (game.chars[thing].room != displayed_room) + return 0; + + int charwid = game_to_data_coord(GetCharacterWidth(thing)); + rect->x1 = game.chars[thing].x - (charwid / 2); + rect->x2 = rect->x1 + charwid; + rect->y1 = game.chars[thing].get_effective_y() - game_to_data_coord(GetCharacterHeight(thing)); + rect->y2 = game.chars[thing].get_effective_y(); + } else if (is_valid_object(thing - OVERLAPPING_OBJECT)) { + int objid = thing - OVERLAPPING_OBJECT; + if (objs[objid].on != 1) + return 0; + rect->x1 = objs[objid].x; + rect->x2 = objs[objid].x + game_to_data_coord(objs[objid].get_width()); + rect->y1 = objs[objid].y - game_to_data_coord(objs[objid].get_height()); + rect->y2 = objs[objid].y; + } else + quit("!AreThingsOverlapping: invalid parameter"); + + return 1; } int AreThingsOverlapping(int thing1, int thing2) { - _Rect r1, r2; - // get the bounding rectangles, and return 0 if the object/char - // is currently turned off - if (GetThingRect(thing1, &r1) == 0) - return 0; - if (GetThingRect(thing2, &r2) == 0) - return 0; - - if ((r1.x2 > r2.x1) && (r1.x1 < r2.x2) && - (r1.y2 > r2.y1) && (r1.y1 < r2.y2)) { - // determine how far apart they are - // take the smaller of the X distances as the overlapping amount - int xdist = abs(r1.x2 - r2.x1); - if (abs(r1.x1 - r2.x2) < xdist) - xdist = abs(r1.x1 - r2.x2); - // take the smaller of the Y distances - int ydist = abs(r1.y2 - r2.y1); - if (abs(r1.y1 - r2.y2) < ydist) - ydist = abs(r1.y1 - r2.y2); - // the overlapping amount is the smaller of the X and Y ovrlap - if (xdist < ydist) - return xdist; - else - return ydist; - // return 1; - } - return 0; -} - -int GetObjectProperty (int hss, const char *property) -{ - if (!is_valid_object(hss)) - quit("!GetObjectProperty: invalid object"); - return get_int_property(thisroom.Objects[hss].Properties, croom->objProps[hss], property); -} - -void GetObjectPropertyText (int item, const char *property, char *bufer) -{ - get_text_property(thisroom.Objects[item].Properties, croom->objProps[item], property, bufer); -} - -Bitmap *GetObjectImage(int obj, int *isFlipped) -{ - if (!gfxDriver->HasAcceleratedTransform()) - { - if (actsps[obj] != nullptr) { - // the actsps image is pre-flipped, so no longer register the image as such - if (isFlipped) - *isFlipped = 0; - - return actsps[obj]; - } - } - return spriteset[objs[obj].num]; + _Rect r1, r2; + // get the bounding rectangles, and return 0 if the object/char + // is currently turned off + if (GetThingRect(thing1, &r1) == 0) + return 0; + if (GetThingRect(thing2, &r2) == 0) + return 0; + + if ((r1.x2 > r2.x1) && (r1.x1 < r2.x2) && + (r1.y2 > r2.y1) && (r1.y1 < r2.y2)) { + // determine how far apart they are + // take the smaller of the X distances as the overlapping amount + int xdist = abs(r1.x2 - r2.x1); + if (abs(r1.x1 - r2.x2) < xdist) + xdist = abs(r1.x1 - r2.x2); + // take the smaller of the Y distances + int ydist = abs(r1.y2 - r2.y1); + if (abs(r1.y1 - r2.y2) < ydist) + ydist = abs(r1.y1 - r2.y2); + // the overlapping amount is the smaller of the X and Y ovrlap + if (xdist < ydist) + return xdist; + else + return ydist; + // return 1; + } + return 0; +} + +int GetObjectProperty(int hss, const char *property) { + if (!is_valid_object(hss)) + quit("!GetObjectProperty: invalid object"); + return get_int_property(thisroom.Objects[hss].Properties, croom->objProps[hss], property); +} + +void GetObjectPropertyText(int item, const char *property, char *bufer) { + get_text_property(thisroom.Objects[item].Properties, croom->objProps[item], property, bufer); +} + +Bitmap *GetObjectImage(int obj, int *isFlipped) { + if (!gfxDriver->HasAcceleratedTransform()) { + if (actsps[obj] != nullptr) { + // the actsps image is pre-flipped, so no longer register the image as such + if (isFlipped) + *isFlipped = 0; + + return actsps[obj]; + } + } + return spriteset[objs[obj].num]; } diff --git a/engines/ags/engine/ac/global_object.h b/engines/ags/engine/ac/global_object.h index 65b364fd29ee..9e0e94778505 100644 --- a/engines/ags/engine/ac/global_object.h +++ b/engines/ags/engine/ac/global_object.h @@ -23,53 +23,57 @@ #ifndef AGS_ENGINE_AC_GLOBAL_OBJECT_H #define AGS_ENGINE_AC_GLOBAL_OBJECT_H -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later // TODO: merge with other Rect declared in bitmap unit struct _Rect { - int x1,y1,x2,y2; + int x1, y1, x2, y2; }; // Get object at the given screen coordinates -int GetObjectIDAtScreen(int xx,int yy); +int GetObjectIDAtScreen(int xx, int yy); // Get object at the given room coordinates int GetObjectIDAtRoom(int roomx, int roomy); void SetObjectTint(int obj, int red, int green, int blue, int opacity, int luminance); void RemoveObjectTint(int obj); -void SetObjectView(int obn,int vii); -void SetObjectFrame(int obn,int viw,int lop,int fra); +void SetObjectView(int obn, int vii); +void SetObjectFrame(int obn, int viw, int lop, int fra); // pass trans=0 for fully solid, trans=100 for fully transparent -void SetObjectTransparency(int obn,int trans); -void SetObjectBaseline (int obn, int basel); +void SetObjectTransparency(int obn, int trans); +void SetObjectBaseline(int obn, int basel); int GetObjectBaseline(int obn); -void AnimateObjectEx(int obn,int loopn,int spdd,int rept, int direction, int blocking); -void AnimateObject(int obn,int loopn,int spdd,int rept); +void AnimateObjectEx(int obn, int loopn, int spdd, int rept, int direction, int blocking); +void AnimateObject(int obn, int loopn, int spdd, int rept); void AnimateObjectImpl(int obn, int loopn, int spdd, int rept, int direction, int blocking, int sframe); void MergeObject(int obn); void StopObjectMoving(int objj); void ObjectOff(int obn); void ObjectOn(int obn); -int IsObjectOn (int objj); -void SetObjectGraphic(int obn,int slott); +int IsObjectOn(int objj); +void SetObjectGraphic(int obn, int slott); int GetObjectGraphic(int obn); -int GetObjectX (int objj); -int GetObjectY (int objj); +int GetObjectX(int objj); +int GetObjectY(int objj); int IsObjectAnimating(int objj); int IsObjectMoving(int objj); void SetObjectPosition(int objj, int tox, int toy); void GetObjectName(int obj, char *buffer); -void MoveObject(int objj,int xx,int yy,int spp); -void MoveObjectDirect(int objj,int xx,int yy,int spp); -void SetObjectClickable (int cha, int clik); -void SetObjectIgnoreWalkbehinds (int cha, int clik); -void RunObjectInteraction (int aa, int mood); -int AreObjectsColliding(int obj1,int obj2); +void MoveObject(int objj, int xx, int yy, int spp); +void MoveObjectDirect(int objj, int xx, int yy, int spp); +void SetObjectClickable(int cha, int clik); +void SetObjectIgnoreWalkbehinds(int cha, int clik); +void RunObjectInteraction(int aa, int mood); +int AreObjectsColliding(int obj1, int obj2); int GetThingRect(int thing, _Rect *rect); int AreThingsOverlapping(int thing1, int thing2); -int GetObjectProperty (int hss, const char *property); -void GetObjectPropertyText (int item, const char *property, char *bufer); +int GetObjectProperty(int hss, const char *property); +void GetObjectPropertyText(int item, const char *property, char *bufer); Common::Bitmap *GetObjectImage(int obj, int *isFlipped); diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp index 99f67a9fc543..bd10c5e7d400 100644 --- a/engines/ags/engine/ac/global_overlay.cpp +++ b/engines/ags/engine/ac/global_overlay.cpp @@ -44,59 +44,58 @@ extern GameSetupStruct game; void RemoveOverlay(int ovrid) { - if (find_overlay_of_type(ovrid) < 0) quit("!RemoveOverlay: invalid overlay id passed"); - remove_screen_overlay(ovrid); + if (find_overlay_of_type(ovrid) < 0) quit("!RemoveOverlay: invalid overlay id passed"); + remove_screen_overlay(ovrid); } -int CreateGraphicOverlay(int xx,int yy,int slott,int trans) { - data_to_game_coords(&xx, &yy); +int CreateGraphicOverlay(int xx, int yy, int slott, int trans) { + data_to_game_coords(&xx, &yy); - Bitmap *screeno=BitmapHelper::CreateTransparentBitmap(game.SpriteInfos[slott].Width, game.SpriteInfos[slott].Height, game.GetColorDepth()); - wputblock(screeno, 0,0,spriteset[slott],trans); - bool hasAlpha = (game.SpriteInfos[slott].Flags & SPF_ALPHACHANNEL) != 0; - int nse = add_screen_overlay(xx, yy, OVER_CUSTOM, screeno, hasAlpha); - return screenover[nse].type; + Bitmap *screeno = BitmapHelper::CreateTransparentBitmap(game.SpriteInfos[slott].Width, game.SpriteInfos[slott].Height, game.GetColorDepth()); + wputblock(screeno, 0, 0, spriteset[slott], trans); + bool hasAlpha = (game.SpriteInfos[slott].Flags & SPF_ALPHACHANNEL) != 0; + int nse = add_screen_overlay(xx, yy, OVER_CUSTOM, screeno, hasAlpha); + return screenover[nse].type; } int CreateTextOverlayCore(int xx, int yy, int wii, int fontid, int text_color, const char *text, int disp_type, int allowShrink) { - if (wii<8) wii=play.GetUIViewport().GetWidth()/2; - if (xx<0) xx=play.GetUIViewport().GetWidth()/2-wii/2; - if (text_color ==0) text_color =16; - return _display_main(xx,yy,wii, text, disp_type, fontid, -text_color, 0, allowShrink, false); + if (wii < 8) wii = play.GetUIViewport().GetWidth() / 2; + if (xx < 0) xx = play.GetUIViewport().GetWidth() / 2 - wii / 2; + if (text_color == 0) text_color = 16; + return _display_main(xx, yy, wii, text, disp_type, fontid, -text_color, 0, allowShrink, false); } -int CreateTextOverlay(int xx, int yy, int wii, int fontid, int text_color, const char* text, int disp_type) { - int allowShrink = 0; +int CreateTextOverlay(int xx, int yy, int wii, int fontid, int text_color, const char *text, int disp_type) { + int allowShrink = 0; - if (xx != OVR_AUTOPLACE) { - data_to_game_coords(&xx,&yy); - wii = data_to_game_coord(wii); - } - else // allow DisplaySpeechBackground to be shrunk - allowShrink = 1; + if (xx != OVR_AUTOPLACE) { + data_to_game_coords(&xx, &yy); + wii = data_to_game_coord(wii); + } else // allow DisplaySpeechBackground to be shrunk + allowShrink = 1; - return CreateTextOverlayCore(xx, yy, wii, fontid, text_color, text, disp_type, allowShrink); + return CreateTextOverlayCore(xx, yy, wii, fontid, text_color, text, disp_type, allowShrink); } void SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int text_color, const char *text) { - RemoveOverlay(ovrid); - const int disp_type = ovrid; - if (CreateTextOverlay(xx, yy, wii, fontid, text_color, text, disp_type) !=ovrid) - quit("SetTextOverlay internal error: inconsistent type ids"); + RemoveOverlay(ovrid); + const int disp_type = ovrid; + if (CreateTextOverlay(xx, yy, wii, fontid, text_color, text, disp_type) != ovrid) + quit("SetTextOverlay internal error: inconsistent type ids"); } -void MoveOverlay(int ovrid, int newx,int newy) { - data_to_game_coords(&newx, &newy); +void MoveOverlay(int ovrid, int newx, int newy) { + data_to_game_coords(&newx, &newy); - int ovri=find_overlay_of_type(ovrid); - if (ovri<0) quit("!MoveOverlay: invalid overlay ID specified"); - screenover[ovri].x=newx; - screenover[ovri].y=newy; + int ovri = find_overlay_of_type(ovrid); + if (ovri < 0) quit("!MoveOverlay: invalid overlay ID specified"); + screenover[ovri].x = newx; + screenover[ovri].y = newy; } int IsOverlayValid(int ovrid) { - if (find_overlay_of_type(ovrid) < 0) - return 0; + if (find_overlay_of_type(ovrid) < 0) + return 0; - return 1; + return 1; } diff --git a/engines/ags/engine/ac/global_overlay.h b/engines/ags/engine/ac/global_overlay.h index 3cb71b53f65c..5b2e9c8439c2 100644 --- a/engines/ags/engine/ac/global_overlay.h +++ b/engines/ags/engine/ac/global_overlay.h @@ -26,7 +26,7 @@ void RemoveOverlay(int ovrid); int CreateGraphicOverlay(int xx, int yy, int slott, int trans); int CreateTextOverlayCore(int xx, int yy, int wii, int fontid, int text_color, const char *text, int disp_type, int allowShrink); -int CreateTextOverlay(int xx, int yy, int wii, int fontid, int clr, const char* text, int disp_type); +int CreateTextOverlay(int xx, int yy, int wii, int fontid, int clr, const char *text, int disp_type); void SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int text_color, const char *text); void MoveOverlay(int ovrid, int newx, int newy); int IsOverlayValid(int ovrid); diff --git a/engines/ags/engine/ac/global_palette.cpp b/engines/ags/engine/ac/global_palette.cpp index 0fb925f0506a..25daf644a979 100644 --- a/engines/ags/engine/ac/global_palette.cpp +++ b/engines/ags/engine/ac/global_palette.cpp @@ -31,33 +31,32 @@ extern GameState play; extern color palette[256]; -void CyclePalette(int strt,int eend) { - // hi-color game must invalidate screen since the palette changes - // the effect of the drawing operations - if (game.color_depth > 1) - invalidate_screen(); +void CyclePalette(int strt, int eend) { + // hi-color game must invalidate screen since the palette changes + // the effect of the drawing operations + if (game.color_depth > 1) + invalidate_screen(); - if ((strt < 0) || (strt > 255) || (eend < 0) || (eend > 255)) - quit("!CyclePalette: start and end must be 0-255"); + if ((strt < 0) || (strt > 255) || (eend < 0) || (eend > 255)) + quit("!CyclePalette: start and end must be 0-255"); - if (eend > strt) { - // forwards - wcolrotate(strt, eend, 0, palette); - set_palette_range(palette, strt, eend, 0); - } - else { - // backwards - wcolrotate(eend, strt, 1, palette); - set_palette_range(palette, eend, strt, 0); - } + if (eend > strt) { + // forwards + wcolrotate(strt, eend, 0, palette); + set_palette_range(palette, strt, eend, 0); + } else { + // backwards + wcolrotate(eend, strt, 1, palette); + set_palette_range(palette, eend, strt, 0); + } } -void SetPalRGB(int inndx,int rr,int gg,int bb) { - if (game.color_depth > 1) - invalidate_screen(); +void SetPalRGB(int inndx, int rr, int gg, int bb) { + if (game.color_depth > 1) + invalidate_screen(); - wsetrgb(inndx,rr,gg,bb,palette); - set_palette_range(palette, inndx, inndx, 0); + wsetrgb(inndx, rr, gg, bb, palette); + set_palette_range(palette, inndx, inndx, 0); } /*void scSetPal(color*pptr) { wsetpalette(0,255,pptr); @@ -67,9 +66,9 @@ get_palette(pptr); }*/ void UpdatePalette() { - if (game.color_depth > 1) - invalidate_screen(); + if (game.color_depth > 1) + invalidate_screen(); - if (!play.fast_forward) - setpal(); + if (!play.fast_forward) + setpal(); } diff --git a/engines/ags/engine/ac/global_palette.h b/engines/ags/engine/ac/global_palette.h index 9005c166191f..13ff58ab570d 100644 --- a/engines/ags/engine/ac/global_palette.h +++ b/engines/ags/engine/ac/global_palette.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_PALETTE_H #define AGS_ENGINE_AC_GLOBAL_PALETTE_H -void CyclePalette(int strt,int eend); -void SetPalRGB(int inndx,int rr,int gg,int bb); +void CyclePalette(int strt, int eend); +void SetPalRGB(int inndx, int rr, int gg, int bb); void UpdatePalette(); #endif diff --git a/engines/ags/engine/ac/global_parser.cpp b/engines/ags/engine/ac/global_parser.cpp index a51a151e20df..54bcb0852df2 100644 --- a/engines/ags/engine/ac/global_parser.cpp +++ b/engines/ags/engine/ac/global_parser.cpp @@ -28,10 +28,10 @@ extern GameState play; -int SaidUnknownWord (char*buffer) { - VALIDATE_STRING(buffer); - strcpy (buffer, play.bad_parsed_word); - if (play.bad_parsed_word[0] == 0) - return 0; - return 1; +int SaidUnknownWord(char *buffer) { + VALIDATE_STRING(buffer); + strcpy(buffer, play.bad_parsed_word); + if (play.bad_parsed_word[0] == 0) + return 0; + return 1; } diff --git a/engines/ags/engine/ac/global_parser.h b/engines/ags/engine/ac/global_parser.h index 92772678093d..b3e99bd5e4f9 100644 --- a/engines/ags/engine/ac/global_parser.h +++ b/engines/ags/engine/ac/global_parser.h @@ -23,6 +23,6 @@ #ifndef AGS_ENGINE_AC_GLOBAL_PARSER_H #define AGS_ENGINE_AC_GLOBAL_PARSER_H -int SaidUnknownWord (char*buffer); +int SaidUnknownWord(char *buffer); #endif diff --git a/engines/ags/engine/ac/global_plugin.h b/engines/ags/engine/ac/global_plugin.h index 7d14d7f8ad99..193c1dc99d45 100644 --- a/engines/ags/engine/ac/global_plugin.h +++ b/engines/ags/engine/ac/global_plugin.h @@ -24,6 +24,6 @@ #define AGS_ENGINE_AC_GLOBAL_PLUGIN_H void PluginSimulateMouseClick(int pluginButtonID); -bool RegisterPluginStubs(const char* name); +bool RegisterPluginStubs(const char *name); #endif diff --git a/engines/ags/engine/ac/global_record.cpp b/engines/ags/engine/ac/global_record.cpp index 5b799f5290c0..ef251f9ebf62 100644 --- a/engines/ags/engine/ac/global_record.cpp +++ b/engines/ags/engine/ac/global_record.cpp @@ -23,6 +23,6 @@ #include "ac/global_record.h" #include "ac/common.h" -void scStartRecording (int keyToStop) { - quit("!StartRecording: not supported"); +void scStartRecording(int keyToStop) { + quit("!StartRecording: not supported"); } diff --git a/engines/ags/engine/ac/global_record.h b/engines/ags/engine/ac/global_record.h index 1a924b37018d..b459b0c15e22 100644 --- a/engines/ags/engine/ac/global_record.h +++ b/engines/ags/engine/ac/global_record.h @@ -23,6 +23,6 @@ #ifndef AGS_ENGINE_AC_GLOBAL_RECORD_H #define AGS_ENGINE_AC_GLOBAL_RECORD_H -void scStartRecording (int keyToStop); +void scStartRecording(int keyToStop); #endif diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp index 1ee83973fe8e..46c79ade0036 100644 --- a/engines/ags/engine/ac/global_region.cpp +++ b/engines/ags/engine/ac/global_region.cpp @@ -35,138 +35,133 @@ using namespace AGS::Common; extern RoomStruct thisroom; -extern RoomStatus*croom; -extern const char*evblockbasename; +extern RoomStatus *croom; +extern const char *evblockbasename; extern int evblocknum; int GetRegionIDAtRoom(int xxx, int yyy) { - // if the co-ordinates are off the edge of the screen, - // correct them to be just within - // this fixes walk-off-screen problems - xxx = room_to_mask_coord(xxx); - yyy = room_to_mask_coord(yyy); - - if (loaded_game_file_version >= kGameVersion_262) // Version 2.6.2+ - { - if (xxx >= thisroom.RegionMask->GetWidth()) - xxx = thisroom.RegionMask->GetWidth() - 1; - if (yyy >= thisroom.RegionMask->GetHeight()) - yyy = thisroom.RegionMask->GetHeight() - 1; - if (xxx < 0) - xxx = 0; - if (yyy < 0) - yyy = 0; - } - - int hsthere = thisroom.RegionMask->GetPixel (xxx, yyy); - if (hsthere <= 0 || hsthere >= MAX_ROOM_REGIONS) return 0; - if (croom->region_enabled[hsthere] == 0) return 0; - return hsthere; + // if the co-ordinates are off the edge of the screen, + // correct them to be just within + // this fixes walk-off-screen problems + xxx = room_to_mask_coord(xxx); + yyy = room_to_mask_coord(yyy); + + if (loaded_game_file_version >= kGameVersion_262) { // Version 2.6.2+ + if (xxx >= thisroom.RegionMask->GetWidth()) + xxx = thisroom.RegionMask->GetWidth() - 1; + if (yyy >= thisroom.RegionMask->GetHeight()) + yyy = thisroom.RegionMask->GetHeight() - 1; + if (xxx < 0) + xxx = 0; + if (yyy < 0) + yyy = 0; + } + + int hsthere = thisroom.RegionMask->GetPixel(xxx, yyy); + if (hsthere <= 0 || hsthere >= MAX_ROOM_REGIONS) return 0; + if (croom->region_enabled[hsthere] == 0) return 0; + return hsthere; } void SetAreaLightLevel(int area, int brightness) { - if ((area < 0) || (area > MAX_ROOM_REGIONS)) - quit("!SetAreaLightLevel: invalid region"); - if (brightness < -100) brightness = -100; - if (brightness > 100) brightness = 100; - thisroom.Regions[area].Light = brightness; - // disable RGB tint for this area - thisroom.Regions[area].Tint = 0; - debug_script_log("Region %d light level set to %d", area, brightness); + if ((area < 0) || (area > MAX_ROOM_REGIONS)) + quit("!SetAreaLightLevel: invalid region"); + if (brightness < -100) brightness = -100; + if (brightness > 100) brightness = 100; + thisroom.Regions[area].Light = brightness; + // disable RGB tint for this area + thisroom.Regions[area].Tint = 0; + debug_script_log("Region %d light level set to %d", area, brightness); } -void SetRegionTint (int area, int red, int green, int blue, int amount, int luminance) -{ - if ((area < 0) || (area > MAX_ROOM_REGIONS)) - quit("!SetRegionTint: invalid region"); - - if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || - (blue < 0) || (blue > 255)) { - quit("!SetRegionTint: RGB values must be 0-255"); - } - - // originally the value was passed as 0 - // TODO: find out which versions had this; fixup only for past versions in the future! - if (amount == 0) - amount = 100; - - if ((amount < 1) || (amount > 100)) - quit("!SetRegionTint: amount must be 1-100"); - if ((luminance < 0) || (luminance > 100)) - quit("!SetRegionTint: luminance must be 0-100"); - - debug_script_log("Region %d tint set to %d,%d,%d", area, red, green, blue); - - /*red -= 100; - green -= 100; - blue -= 100;*/ - - thisroom.Regions[area].Tint = (red & 0xFF) | - ((green & 0xFF) << 8) | - ((blue & 0XFF) << 16) | - ((amount & 0xFF) << 24); - thisroom.Regions[area].Light = (luminance * 25) / 10; +void SetRegionTint(int area, int red, int green, int blue, int amount, int luminance) { + if ((area < 0) || (area > MAX_ROOM_REGIONS)) + quit("!SetRegionTint: invalid region"); + + if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || + (blue < 0) || (blue > 255)) { + quit("!SetRegionTint: RGB values must be 0-255"); + } + + // originally the value was passed as 0 + // TODO: find out which versions had this; fixup only for past versions in the future! + if (amount == 0) + amount = 100; + + if ((amount < 1) || (amount > 100)) + quit("!SetRegionTint: amount must be 1-100"); + if ((luminance < 0) || (luminance > 100)) + quit("!SetRegionTint: luminance must be 0-100"); + + debug_script_log("Region %d tint set to %d,%d,%d", area, red, green, blue); + + /*red -= 100; + green -= 100; + blue -= 100;*/ + + thisroom.Regions[area].Tint = (red & 0xFF) | + ((green & 0xFF) << 8) | + ((blue & 0XFF) << 16) | + ((amount & 0xFF) << 24); + thisroom.Regions[area].Light = (luminance * 25) / 10; } void DisableRegion(int hsnum) { - if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS)) - quit("!DisableRegion: invalid region specified"); + if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS)) + quit("!DisableRegion: invalid region specified"); - croom->region_enabled[hsnum] = 0; - debug_script_log("Region %d disabled", hsnum); + croom->region_enabled[hsnum] = 0; + debug_script_log("Region %d disabled", hsnum); } void EnableRegion(int hsnum) { - if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS)) - quit("!EnableRegion: invalid region specified"); + if ((hsnum < 0) || (hsnum >= MAX_ROOM_REGIONS)) + quit("!EnableRegion: invalid region specified"); - croom->region_enabled[hsnum] = 1; - debug_script_log("Region %d enabled", hsnum); + croom->region_enabled[hsnum] = 1; + debug_script_log("Region %d enabled", hsnum); } void DisableGroundLevelAreas(int alsoEffects) { - if ((alsoEffects < 0) || (alsoEffects > 1)) - quit("!DisableGroundLevelAreas: invalid parameter: must be 0 or 1"); + if ((alsoEffects < 0) || (alsoEffects > 1)) + quit("!DisableGroundLevelAreas: invalid parameter: must be 0 or 1"); - play.ground_level_areas_disabled = GLED_INTERACTION; + play.ground_level_areas_disabled = GLED_INTERACTION; - if (alsoEffects) - play.ground_level_areas_disabled |= GLED_EFFECTS; + if (alsoEffects) + play.ground_level_areas_disabled |= GLED_EFFECTS; - debug_script_log("Ground-level areas disabled"); + debug_script_log("Ground-level areas disabled"); } void EnableGroundLevelAreas() { - play.ground_level_areas_disabled = 0; + play.ground_level_areas_disabled = 0; - debug_script_log("Ground-level areas re-enabled"); + debug_script_log("Ground-level areas re-enabled"); } -void RunRegionInteraction (int regnum, int mood) { - if ((regnum < 0) || (regnum >= MAX_ROOM_REGIONS)) - quit("!RunRegionInteraction: invalid region speicfied"); - if ((mood < 0) || (mood > 2)) - quit("!RunRegionInteraction: invalid event specified"); - - // We need a backup, because region interactions can run - // while another interaction (eg. hotspot) is in a Wait - // command, and leaving our basename would call the wrong - // script later on - const char *oldbasename = evblockbasename; - int oldblocknum = evblocknum; - - evblockbasename = "region%d"; - evblocknum = regnum; - - if (thisroom.Regions[regnum].EventHandlers != nullptr) - { - run_interaction_script(thisroom.Regions[regnum].EventHandlers.get(), mood); - } - else - { - run_interaction_event(&croom->intrRegion[regnum], mood); - } - - evblockbasename = oldbasename; - evblocknum = oldblocknum; +void RunRegionInteraction(int regnum, int mood) { + if ((regnum < 0) || (regnum >= MAX_ROOM_REGIONS)) + quit("!RunRegionInteraction: invalid region speicfied"); + if ((mood < 0) || (mood > 2)) + quit("!RunRegionInteraction: invalid event specified"); + + // We need a backup, because region interactions can run + // while another interaction (eg. hotspot) is in a Wait + // command, and leaving our basename would call the wrong + // script later on + const char *oldbasename = evblockbasename; + int oldblocknum = evblocknum; + + evblockbasename = "region%d"; + evblocknum = regnum; + + if (thisroom.Regions[regnum].EventHandlers != nullptr) { + run_interaction_script(thisroom.Regions[regnum].EventHandlers.get(), mood); + } else { + run_interaction_event(&croom->intrRegion[regnum], mood); + } + + evblockbasename = oldbasename; + evblocknum = oldblocknum; } diff --git a/engines/ags/engine/ac/global_region.h b/engines/ags/engine/ac/global_region.h index 0c69239d8531..205a45f90cd2 100644 --- a/engines/ags/engine/ac/global_region.h +++ b/engines/ags/engine/ac/global_region.h @@ -27,11 +27,11 @@ // if region is disabled or non-existing, returns 0 (no area) int GetRegionIDAtRoom(int xxx, int yyy); void SetAreaLightLevel(int area, int brightness); -void SetRegionTint (int area, int red, int green, int blue, int amount, int luminance = 100); +void SetRegionTint(int area, int red, int green, int blue, int amount, int luminance = 100); void DisableRegion(int hsnum); void EnableRegion(int hsnum); void DisableGroundLevelAreas(int alsoEffects); void EnableGroundLevelAreas(); -void RunRegionInteraction (int regnum, int mood); +void RunRegionInteraction(int regnum, int mood); #endif diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp index e3f35b833a74..e07db97dfe2b 100644 --- a/engines/ags/engine/ac/global_room.cpp +++ b/engines/ags/engine/ac/global_room.cpp @@ -44,7 +44,7 @@ using namespace Common; extern GameState play; extern GameSetupStruct game; extern RoomStatus *croom; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern int displayed_room; extern int in_enters_screen; extern int in_leaves_screen; @@ -53,179 +53,170 @@ extern MoveList *mls; extern int gs_to_newroom; extern RoomStruct thisroom; -void SetAmbientTint (int red, int green, int blue, int opacity, int luminance) { - if ((red < 0) || (green < 0) || (blue < 0) || - (red > 255) || (green > 255) || (blue > 255) || - (opacity < 0) || (opacity > 100) || - (luminance < 0) || (luminance > 100)) - quit("!SetTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); - - debug_script_log("Set ambient tint RGB(%d,%d,%d) %d%%", red, green, blue, opacity); - - play.rtint_enabled = opacity > 0; - play.rtint_red = red; - play.rtint_green = green; - play.rtint_blue = blue; - play.rtint_level = opacity; - play.rtint_light = (luminance * 25) / 10; +void SetAmbientTint(int red, int green, int blue, int opacity, int luminance) { + if ((red < 0) || (green < 0) || (blue < 0) || + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) + quit("!SetTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); + + debug_script_log("Set ambient tint RGB(%d,%d,%d) %d%%", red, green, blue, opacity); + + play.rtint_enabled = opacity > 0; + play.rtint_red = red; + play.rtint_green = green; + play.rtint_blue = blue; + play.rtint_level = opacity; + play.rtint_light = (luminance * 25) / 10; } -void SetAmbientLightLevel(int light_level) -{ - light_level = Math::Clamp(light_level, -100, 100); +void SetAmbientLightLevel(int light_level) { + light_level = Math::Clamp(light_level, -100, 100); - play.rtint_enabled = light_level != 0; - play.rtint_level = 0; - play.rtint_light = light_level; + play.rtint_enabled = light_level != 0; + play.rtint_level = 0; + play.rtint_light = light_level; } extern ScriptPosition last_in_dialog_request_script_pos; void NewRoom(int nrnum) { - if (nrnum < 0) - quitprintf("!NewRoom: room change requested to invalid room number %d.", nrnum); - - if (displayed_room < 0) { - // called from game_start; change the room where the game will start - playerchar->room = nrnum; - return; - } - - - debug_script_log("Room change requested to room %d", nrnum); - EndSkippingUntilCharStops(); - - can_run_delayed_command(); - - if (play.stop_dialog_at_end != DIALOG_NONE) { - if (play.stop_dialog_at_end == DIALOG_RUNNING) - play.stop_dialog_at_end = DIALOG_NEWROOM + nrnum; - else { - quitprintf("!NewRoom: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", - last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); - } - return; - } - - get_script_position(last_in_dialog_request_script_pos); - - if (in_leaves_screen >= 0) { - // NewRoom called from the Player Leaves Screen event -- just - // change which room it will go to - in_leaves_screen = nrnum; - } - else if (in_enters_screen) { - setevent(EV_NEWROOM,nrnum); - return; - } - else if (in_inv_screen) { - inv_screen_newroom = nrnum; - return; - } - else if ((inside_script==0) & (in_graph_script==0)) { - new_room(nrnum,playerchar); - return; - } - else if (inside_script) { - curscript->queue_action(ePSANewRoom, nrnum, "NewRoom"); - // we might be within a MoveCharacterBlocking -- the room - // change should abort it - if ((playerchar->walking > 0) && (playerchar->walking < TURNING_AROUND)) { - // nasty hack - make sure it doesn't move the character - // to a walkable area - mls[playerchar->walking].direct = 1; - StopMoving(game.playercharacter); - } - } - else if (in_graph_script) - gs_to_newroom = nrnum; + if (nrnum < 0) + quitprintf("!NewRoom: room change requested to invalid room number %d.", nrnum); + + if (displayed_room < 0) { + // called from game_start; change the room where the game will start + playerchar->room = nrnum; + return; + } + + + debug_script_log("Room change requested to room %d", nrnum); + EndSkippingUntilCharStops(); + + can_run_delayed_command(); + + if (play.stop_dialog_at_end != DIALOG_NONE) { + if (play.stop_dialog_at_end == DIALOG_RUNNING) + play.stop_dialog_at_end = DIALOG_NEWROOM + nrnum; + else { + quitprintf("!NewRoom: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", + last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); + } + return; + } + + get_script_position(last_in_dialog_request_script_pos); + + if (in_leaves_screen >= 0) { + // NewRoom called from the Player Leaves Screen event -- just + // change which room it will go to + in_leaves_screen = nrnum; + } else if (in_enters_screen) { + setevent(EV_NEWROOM, nrnum); + return; + } else if (in_inv_screen) { + inv_screen_newroom = nrnum; + return; + } else if ((inside_script == 0) & (in_graph_script == 0)) { + new_room(nrnum, playerchar); + return; + } else if (inside_script) { + curscript->queue_action(ePSANewRoom, nrnum, "NewRoom"); + // we might be within a MoveCharacterBlocking -- the room + // change should abort it + if ((playerchar->walking > 0) && (playerchar->walking < TURNING_AROUND)) { + // nasty hack - make sure it doesn't move the character + // to a walkable area + mls[playerchar->walking].direct = 1; + StopMoving(game.playercharacter); + } + } else if (in_graph_script) + gs_to_newroom = nrnum; } -void NewRoomEx(int nrnum,int newx,int newy) { - Character_ChangeRoom(playerchar, nrnum, newx, newy); +void NewRoomEx(int nrnum, int newx, int newy) { + Character_ChangeRoom(playerchar, nrnum, newx, newy); } void NewRoomNPC(int charid, int nrnum, int newx, int newy) { - if (!is_valid_character(charid)) - quit("!NewRoomNPC: invalid character"); - if (charid == game.playercharacter) - quit("!NewRoomNPC: use NewRoomEx with the player character"); + if (!is_valid_character(charid)) + quit("!NewRoomNPC: invalid character"); + if (charid == game.playercharacter) + quit("!NewRoomNPC: use NewRoomEx with the player character"); - Character_ChangeRoom(&game.chars[charid], nrnum, newx, newy); + Character_ChangeRoom(&game.chars[charid], nrnum, newx, newy); } void ResetRoom(int nrnum) { - if (nrnum == displayed_room) - quit("!ResetRoom: cannot reset current room"); - if ((nrnum<0) | (nrnum>=MAX_ROOMS)) - quit("!ResetRoom: invalid room number"); - - if (isRoomStatusValid(nrnum)) - { - RoomStatus* roomstat = getRoomStatus(nrnum); - roomstat->FreeScriptData(); - roomstat->FreeProperties(); - roomstat->beenhere = 0; - } - - debug_script_log("Room %d reset to original state", nrnum); + if (nrnum == displayed_room) + quit("!ResetRoom: cannot reset current room"); + if ((nrnum < 0) | (nrnum >= MAX_ROOMS)) + quit("!ResetRoom: invalid room number"); + + if (isRoomStatusValid(nrnum)) { + RoomStatus *roomstat = getRoomStatus(nrnum); + roomstat->FreeScriptData(); + roomstat->FreeProperties(); + roomstat->beenhere = 0; + } + + debug_script_log("Room %d reset to original state", nrnum); } int HasPlayerBeenInRoom(int roomnum) { - if ((roomnum < 0) || (roomnum >= MAX_ROOMS)) - return 0; - if (isRoomStatusValid(roomnum)) - return getRoomStatus(roomnum)->beenhere; - else - return 0; + if ((roomnum < 0) || (roomnum >= MAX_ROOMS)) + return 0; + if (isRoomStatusValid(roomnum)) + return getRoomStatus(roomnum)->beenhere; + else + return 0; } -void CallRoomScript (int value) { - can_run_delayed_command(); +void CallRoomScript(int value) { + can_run_delayed_command(); - if (!inside_script) - quit("!CallRoomScript: not inside a script???"); + if (!inside_script) + quit("!CallRoomScript: not inside a script???"); - play.roomscript_finished = 0; - RuntimeScriptValue rval_null; - curscript->run_another("on_call", kScInstRoom, 1, RuntimeScriptValue().SetInt32(value), rval_null); + play.roomscript_finished = 0; + RuntimeScriptValue rval_null; + curscript->run_another("on_call", kScInstRoom, 1, RuntimeScriptValue().SetInt32(value), rval_null); } -int HasBeenToRoom (int roomnum) { - if ((roomnum < 0) || (roomnum >= MAX_ROOMS)) - quit("!HasBeenToRoom: invalid room number specified"); +int HasBeenToRoom(int roomnum) { + if ((roomnum < 0) || (roomnum >= MAX_ROOMS)) + quit("!HasBeenToRoom: invalid room number specified"); - if (isRoomStatusValid(roomnum)) - return getRoomStatus(roomnum)->beenhere; - else - return 0; + if (isRoomStatusValid(roomnum)) + return getRoomStatus(roomnum)->beenhere; + else + return 0; } -void GetRoomPropertyText (const char *property, char *bufer) -{ - get_text_property(thisroom.Properties, croom->roomProps, property, bufer); +void GetRoomPropertyText(const char *property, char *bufer) { + get_text_property(thisroom.Properties, croom->roomProps, property, bufer); } void SetBackgroundFrame(int frnum) { - if ((frnum < -1) || (frnum != -1 && (size_t)frnum >= thisroom.BgFrameCount)) - quit("!SetBackgrondFrame: invalid frame number specified"); - if (frnum<0) { - play.bg_frame_locked=0; - return; - } - - play.bg_frame_locked = 1; - - if (frnum == play.bg_frame) - { - // already on this frame, do nothing - return; - } - - play.bg_frame = frnum; - on_background_frame_change (); + if ((frnum < -1) || (frnum != -1 && (size_t)frnum >= thisroom.BgFrameCount)) + quit("!SetBackgrondFrame: invalid frame number specified"); + if (frnum < 0) { + play.bg_frame_locked = 0; + return; + } + + play.bg_frame_locked = 1; + + if (frnum == play.bg_frame) { + // already on this frame, do nothing + return; + } + + play.bg_frame = frnum; + on_background_frame_change(); } int GetBackgroundFrame() { - return play.bg_frame; + return play.bg_frame; } diff --git a/engines/ags/engine/ac/global_room.h b/engines/ags/engine/ac/global_room.h index e469d7a34ff5..7bf95ed306fe 100644 --- a/engines/ags/engine/ac/global_room.h +++ b/engines/ags/engine/ac/global_room.h @@ -23,16 +23,16 @@ #ifndef AGS_ENGINE_AC_GLOBAL_ROOM_H #define AGS_ENGINE_AC_GLOBAL_ROOM_H -void SetAmbientTint (int red, int green, int blue, int opacity, int luminance); +void SetAmbientTint(int red, int green, int blue, int opacity, int luminance); void SetAmbientLightLevel(int light_level); void NewRoom(int nrnum); -void NewRoomEx(int nrnum,int newx,int newy); +void NewRoomEx(int nrnum, int newx, int newy); void NewRoomNPC(int charid, int nrnum, int newx, int newy); void ResetRoom(int nrnum); int HasPlayerBeenInRoom(int roomnum); -void CallRoomScript (int value); -int HasBeenToRoom (int roomnum); -void GetRoomPropertyText (const char *property, char *bufer); +void CallRoomScript(int value); +int HasBeenToRoom(int roomnum); +void GetRoomPropertyText(const char *property, char *bufer); void SetBackgroundFrame(int frnum); int GetBackgroundFrame() ; diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp index 7b6846ee7e19..5e77dbb647d6 100644 --- a/engines/ags/engine/ac/global_screen.cpp +++ b/engines/ags/engine/ac/global_screen.cpp @@ -48,141 +48,135 @@ extern color palette[256]; extern unsigned int loopcounter; void FlipScreen(int amount) { - if ((amount<0) | (amount>3)) quit("!FlipScreen: invalid argument (0-3)"); - play.screen_flipped=amount; + if ((amount < 0) | (amount > 3)) quit("!FlipScreen: invalid argument (0-3)"); + play.screen_flipped = amount; } void ShakeScreen(int severe) { - EndSkippingUntilCharStops(); - - if (play.fast_forward) - return; - - severe = data_to_game_coord(severe); - - // TODO: support shaking room viewport separately - // TODO: rely on game speed setting? and/or provide frequency and duration args - // TODO: unify blocking and non-blocking shake update - - play.shakesc_length = 10; - play.shakesc_delay = 2; - play.shakesc_amount = severe; - play.mouse_cursor_hidden++; - - if (gfxDriver->RequiresFullRedrawEachFrame()) - { - for (int hh = 0; hh < 40; hh++) - { - loopcounter++; - platform->Delay(50); - - render_graphics(); - - update_polled_stuff_if_runtime(); - } - } - else - { - // Optimized variant for software render: create game scene once and shake it - construct_game_scene(); - gfxDriver->RenderToBackBuffer(); - for (int hh = 0; hh < 40; hh++) - { - platform->Delay(50); - const int yoff = hh % 2 == 0 ? 0 : severe; - play.shake_screen_yoff = yoff; - render_to_screen(); - update_polled_stuff_if_runtime(); - } - clear_letterbox_borders(); - render_to_screen(); - } - - play.mouse_cursor_hidden--; - play.shakesc_length = 0; - play.shakesc_delay = 0; - play.shakesc_amount = 0; + EndSkippingUntilCharStops(); + + if (play.fast_forward) + return; + + severe = data_to_game_coord(severe); + + // TODO: support shaking room viewport separately + // TODO: rely on game speed setting? and/or provide frequency and duration args + // TODO: unify blocking and non-blocking shake update + + play.shakesc_length = 10; + play.shakesc_delay = 2; + play.shakesc_amount = severe; + play.mouse_cursor_hidden++; + + if (gfxDriver->RequiresFullRedrawEachFrame()) { + for (int hh = 0; hh < 40; hh++) { + loopcounter++; + platform->Delay(50); + + render_graphics(); + + update_polled_stuff_if_runtime(); + } + } else { + // Optimized variant for software render: create game scene once and shake it + construct_game_scene(); + gfxDriver->RenderToBackBuffer(); + for (int hh = 0; hh < 40; hh++) { + platform->Delay(50); + const int yoff = hh % 2 == 0 ? 0 : severe; + play.shake_screen_yoff = yoff; + render_to_screen(); + update_polled_stuff_if_runtime(); + } + clear_letterbox_borders(); + render_to_screen(); + } + + play.mouse_cursor_hidden--; + play.shakesc_length = 0; + play.shakesc_delay = 0; + play.shakesc_amount = 0; } -void ShakeScreenBackground (int delay, int amount, int length) { - if (delay < 2) - quit("!ShakeScreenBackground: invalid delay parameter"); +void ShakeScreenBackground(int delay, int amount, int length) { + if (delay < 2) + quit("!ShakeScreenBackground: invalid delay parameter"); - amount = data_to_game_coord(amount); + amount = data_to_game_coord(amount); - if (amount < play.shakesc_amount) - { - // from a bigger to smaller shake, clear up the borders - clear_letterbox_borders(); - } + if (amount < play.shakesc_amount) { + // from a bigger to smaller shake, clear up the borders + clear_letterbox_borders(); + } - play.shakesc_amount = amount; - play.shakesc_delay = delay; - play.shakesc_length = length; + play.shakesc_amount = amount; + play.shakesc_delay = delay; + play.shakesc_length = length; } void TintScreen(int red, int grn, int blu) { - if ((red < 0) || (grn < 0) || (blu < 0) || (red > 100) || (grn > 100) || (blu > 100)) - quit("!TintScreen: RGB values must be 0-100"); - - invalidate_screen(); - - if ((red == 0) && (grn == 0) && (blu == 0)) { - play.screen_tint = -1; - return; - } - red = (red * 25) / 10; - grn = (grn * 25) / 10; - blu = (blu * 25) / 10; - play.screen_tint = red + (grn << 8) + (blu << 16); + if ((red < 0) || (grn < 0) || (blu < 0) || (red > 100) || (grn > 100) || (blu > 100)) + quit("!TintScreen: RGB values must be 0-100"); + + invalidate_screen(); + + if ((red == 0) && (grn == 0) && (blu == 0)) { + play.screen_tint = -1; + return; + } + red = (red * 25) / 10; + grn = (grn * 25) / 10; + blu = (blu * 25) / 10; + play.screen_tint = red + (grn << 8) + (blu << 16); } void my_fade_out(int spdd) { - EndSkippingUntilCharStops(); + EndSkippingUntilCharStops(); - if (play.fast_forward) - return; + if (play.fast_forward) + return; - if (play.screen_is_faded_out == 0) - gfxDriver->FadeOut(spdd, play.fade_to_red, play.fade_to_green, play.fade_to_blue); + if (play.screen_is_faded_out == 0) + gfxDriver->FadeOut(spdd, play.fade_to_red, play.fade_to_green, play.fade_to_blue); - if (game.color_depth > 1) - play.screen_is_faded_out = 1; + if (game.color_depth > 1) + play.screen_is_faded_out = 1; } void SetScreenTransition(int newtrans) { - if ((newtrans < 0) || (newtrans > FADE_LAST)) - quit("!SetScreenTransition: invalid transition type"); + if ((newtrans < 0) || (newtrans > FADE_LAST)) + quit("!SetScreenTransition: invalid transition type"); - play.fade_effect = newtrans; + play.fade_effect = newtrans; - debug_script_log("Screen transition changed"); + debug_script_log("Screen transition changed"); } void SetNextScreenTransition(int newtrans) { - if ((newtrans < 0) || (newtrans > FADE_LAST)) - quit("!SetNextScreenTransition: invalid transition type"); + if ((newtrans < 0) || (newtrans > FADE_LAST)) + quit("!SetNextScreenTransition: invalid transition type"); - play.next_screen_transition = newtrans; + play.next_screen_transition = newtrans; - debug_script_log("SetNextScreenTransition engaged"); + debug_script_log("SetNextScreenTransition engaged"); } void SetFadeColor(int red, int green, int blue) { - if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || - (blue < 0) || (blue > 255)) - quit("!SetFadeColor: Red, Green and Blue must be 0-255"); + if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || + (blue < 0) || (blue > 255)) + quit("!SetFadeColor: Red, Green and Blue must be 0-255"); - play.fade_to_red = red; - play.fade_to_green = green; - play.fade_to_blue = blue; + play.fade_to_red = red; + play.fade_to_green = green; + play.fade_to_blue = blue; } void FadeIn(int sppd) { - EndSkippingUntilCharStops(); + EndSkippingUntilCharStops(); - if (play.fast_forward) - return; + if (play.fast_forward) + return; - my_fade_in(palette,sppd); + my_fade_in(palette, sppd); } diff --git a/engines/ags/engine/ac/global_screen.h b/engines/ags/engine/ac/global_screen.h index ea6d5f1be606..1807e115f157 100644 --- a/engines/ags/engine/ac/global_screen.h +++ b/engines/ags/engine/ac/global_screen.h @@ -25,7 +25,7 @@ void FlipScreen(int amount); void ShakeScreen(int severe); -void ShakeScreenBackground (int delay, int amount, int length); +void ShakeScreenBackground(int delay, int amount, int length); void TintScreen(int red, int grn, int blu); void my_fade_out(int spdd); void SetScreenTransition(int newtrans); diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp index d8847ec22b3a..290b864e512f 100644 --- a/engines/ags/engine/ac/global_slider.cpp +++ b/engines/ags/engine/ac/global_slider.cpp @@ -31,20 +31,20 @@ using namespace AGS::Common; extern GameSetupStruct game; -void SetSliderValue(int guin,int objn, int valn) { - if ((guin<0) | (guin>=game.numgui)) quit("!SetSliderValue: invalid GUI number"); - if (guis[guin].GetControlType(objn)!=kGUISlider) - quit("!SetSliderValue: specified control is not a slider"); +void SetSliderValue(int guin, int objn, int valn) { + if ((guin < 0) | (guin >= game.numgui)) quit("!SetSliderValue: invalid GUI number"); + if (guis[guin].GetControlType(objn) != kGUISlider) + quit("!SetSliderValue: specified control is not a slider"); - GUISlider*guisl=(GUISlider*)guis[guin].GetControl(objn); - Slider_SetValue(guisl, valn); + GUISlider *guisl = (GUISlider *)guis[guin].GetControl(objn); + Slider_SetValue(guisl, valn); } -int GetSliderValue(int guin,int objn) { - if ((guin<0) | (guin>=game.numgui)) quit("!GetSliderValue: invalid GUI number"); - if (guis[guin].GetControlType(objn)!=kGUISlider) - quit("!GetSliderValue: specified control is not a slider"); +int GetSliderValue(int guin, int objn) { + if ((guin < 0) | (guin >= game.numgui)) quit("!GetSliderValue: invalid GUI number"); + if (guis[guin].GetControlType(objn) != kGUISlider) + quit("!GetSliderValue: specified control is not a slider"); - GUISlider*guisl=(GUISlider*)guis[guin].GetControl(objn); - return Slider_GetValue(guisl); + GUISlider *guisl = (GUISlider *)guis[guin].GetControl(objn); + return Slider_GetValue(guisl); } diff --git a/engines/ags/engine/ac/global_slider.h b/engines/ags/engine/ac/global_slider.h index a904619574f4..bef7247ac0b0 100644 --- a/engines/ags/engine/ac/global_slider.h +++ b/engines/ags/engine/ac/global_slider.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBAL_SLIDER_H #define AGS_ENGINE_AC_GLOBAL_SLIDER_H -void SetSliderValue(int guin,int objn, int valn); -int GetSliderValue(int guin,int objn); +void SetSliderValue(int guin, int objn, int valn); +int GetSliderValue(int guin, int objn); #endif diff --git a/engines/ags/engine/ac/global_string.cpp b/engines/ags/engine/ac/global_string.cpp index 598e9ec767a5..751932012936 100644 --- a/engines/ags/engine/ac/global_string.cpp +++ b/engines/ags/engine/ac/global_string.cpp @@ -30,40 +30,40 @@ extern int MAXSTRLEN; -int StrGetCharAt (const char *strin, int posn) { - if ((posn < 0) || (posn >= (int)strlen(strin))) - return 0; - return strin[posn]; +int StrGetCharAt(const char *strin, int posn) { + if ((posn < 0) || (posn >= (int)strlen(strin))) + return 0; + return strin[posn]; } -void StrSetCharAt (char *strin, int posn, int nchar) { - if ((posn < 0) || (posn > (int)strlen(strin)) || (posn >= MAX_MAXSTRLEN)) - quit("!StrSetCharAt: tried to write past end of string"); +void StrSetCharAt(char *strin, int posn, int nchar) { + if ((posn < 0) || (posn > (int)strlen(strin)) || (posn >= MAX_MAXSTRLEN)) + quit("!StrSetCharAt: tried to write past end of string"); - if (posn == (int)strlen(strin)) - strin[posn+1] = 0; - strin[posn] = nchar; + if (posn == (int)strlen(strin)) + strin[posn + 1] = 0; + strin[posn] = nchar; } -void _sc_strcat(char*s1, const char*s2) { - // make sure they don't try to append a char to the string - VALIDATE_STRING (s2); - check_strlen(s1); - int mosttocopy=(MAXSTRLEN-strlen(s1))-1; - // int numbf=game.iface[4].numbuttons; - my_strncpy(&s1[strlen(s1)], s2, mosttocopy); +void _sc_strcat(char *s1, const char *s2) { + // make sure they don't try to append a char to the string + VALIDATE_STRING(s2); + check_strlen(s1); + int mosttocopy = (MAXSTRLEN - strlen(s1)) - 1; + // int numbf=game.iface[4].numbuttons; + my_strncpy(&s1[strlen(s1)], s2, mosttocopy); } -void _sc_strlower (char *desbuf) { - VALIDATE_STRING(desbuf); - check_strlen (desbuf); - ags_strlwr (desbuf); +void _sc_strlower(char *desbuf) { + VALIDATE_STRING(desbuf); + check_strlen(desbuf); + ags_strlwr(desbuf); } -void _sc_strupper (char *desbuf) { - VALIDATE_STRING(desbuf); - check_strlen (desbuf); - ags_strupr (desbuf); +void _sc_strupper(char *desbuf) { + VALIDATE_STRING(desbuf); + check_strlen(desbuf); + ags_strupr(desbuf); } /*int _sc_strcmp (char *s1, char *s2) { @@ -74,8 +74,8 @@ int _sc_stricmp (char *s1, char *s2) { return ags_stricmp (get_translation (s1), get_translation(s2)); }*/ -void _sc_strcpy(char*destt, const char *text) { - VALIDATE_STRING(destt); - check_strlen(destt); - my_strncpy(destt, text, MAXSTRLEN - 1); +void _sc_strcpy(char *destt, const char *text) { + VALIDATE_STRING(destt); + check_strlen(destt); + my_strncpy(destt, text, MAXSTRLEN - 1); } diff --git a/engines/ags/engine/ac/global_string.h b/engines/ags/engine/ac/global_string.h index a78b30b552ef..88ce8319f0c5 100644 --- a/engines/ags/engine/ac/global_string.h +++ b/engines/ags/engine/ac/global_string.h @@ -23,11 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBAL_STRING_H #define AGS_ENGINE_AC_GLOBAL_STRING_H -int StrGetCharAt (const char *strin, int posn); -void StrSetCharAt (char *strin, int posn, int nchar); -void _sc_strcat(char*s1, const char*s2); -void _sc_strlower (char *desbuf); -void _sc_strupper (char *desbuf); -void _sc_strcpy(char*destt, const char*text); +int StrGetCharAt(const char *strin, int posn); +void StrSetCharAt(char *strin, int posn, int nchar); +void _sc_strcat(char *s1, const char *s2); +void _sc_strlower(char *desbuf); +void _sc_strupper(char *desbuf); +void _sc_strcpy(char *destt, const char *text); #endif diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp index ddd6f1fe1295..fec358f98b99 100644 --- a/engines/ags/engine/ac/global_textbox.cpp +++ b/engines/ags/engine/ac/global_textbox.cpp @@ -32,34 +32,34 @@ using namespace AGS::Common; extern GameSetupStruct game; -void SetTextBoxFont(int guin,int objn, int fontnum) { +void SetTextBoxFont(int guin, int objn, int fontnum) { - if ((guin<0) | (guin>=game.numgui)) quit("!SetTextBoxFont: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetTextBoxFont: invalid object number"); - if (guis[guin].GetControlType(objn) != kGUITextBox) - quit("!SetTextBoxFont: specified control is not a text box"); + if ((guin < 0) | (guin >= game.numgui)) quit("!SetTextBoxFont: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetTextBoxFont: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUITextBox) + quit("!SetTextBoxFont: specified control is not a text box"); - GUITextBox *guit = (GUITextBox*)guis[guin].GetControl(objn); - TextBox_SetFont(guit, fontnum); + GUITextBox *guit = (GUITextBox *)guis[guin].GetControl(objn); + TextBox_SetFont(guit, fontnum); } -void GetTextBoxText(int guin, int objn, char*txbuf) { - VALIDATE_STRING(txbuf); - if ((guin<0) | (guin>=game.numgui)) quit("!GetTextBoxText: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!GetTextBoxText: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUITextBox) - quit("!GetTextBoxText: specified control is not a text box"); +void GetTextBoxText(int guin, int objn, char *txbuf) { + VALIDATE_STRING(txbuf); + if ((guin < 0) | (guin >= game.numgui)) quit("!GetTextBoxText: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!GetTextBoxText: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUITextBox) + quit("!GetTextBoxText: specified control is not a text box"); - GUITextBox*guisl=(GUITextBox*)guis[guin].GetControl(objn); - TextBox_GetText(guisl, txbuf); + GUITextBox *guisl = (GUITextBox *)guis[guin].GetControl(objn); + TextBox_GetText(guisl, txbuf); } -void SetTextBoxText(int guin, int objn, const char* txbuf) { - if ((guin<0) | (guin>=game.numgui)) quit("!SetTextBoxText: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!SetTextBoxText: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUITextBox) - quit("!SetTextBoxText: specified control is not a text box"); +void SetTextBoxText(int guin, int objn, const char *txbuf) { + if ((guin < 0) | (guin >= game.numgui)) quit("!SetTextBoxText: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetTextBoxText: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUITextBox) + quit("!SetTextBoxText: specified control is not a text box"); - GUITextBox*guisl=(GUITextBox*)guis[guin].GetControl(objn); - TextBox_SetText(guisl, txbuf); + GUITextBox *guisl = (GUITextBox *)guis[guin].GetControl(objn); + TextBox_SetText(guisl, txbuf); } diff --git a/engines/ags/engine/ac/global_textbox.h b/engines/ags/engine/ac/global_textbox.h index d42f1ddd3b24..bd95b85c4eff 100644 --- a/engines/ags/engine/ac/global_textbox.h +++ b/engines/ags/engine/ac/global_textbox.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_TEXTBOX_H #define AGS_ENGINE_AC_GLOBAL_TEXTBOX_H -void SetTextBoxFont(int guin,int objn, int fontnum); -void GetTextBoxText(int guin, int objn, char*txbuf); -void SetTextBoxText(int guin, int objn, const char*txbuf); +void SetTextBoxFont(int guin, int objn, int fontnum); +void GetTextBoxText(int guin, int objn, char *txbuf); +void SetTextBoxText(int guin, int objn, const char *txbuf); #endif diff --git a/engines/ags/engine/ac/global_timer.cpp b/engines/ags/engine/ac/global_timer.cpp index 86c080a10ff1..cc4373bcc550 100644 --- a/engines/ags/engine/ac/global_timer.cpp +++ b/engines/ags/engine/ac/global_timer.cpp @@ -28,18 +28,18 @@ extern GameState play; -void script_SetTimer(int tnum,int timeout) { - if ((tnum < 1) || (tnum >= MAX_TIMERS)) - quit("!StartTimer: invalid timer number"); - play.script_timers[tnum] = timeout; +void script_SetTimer(int tnum, int timeout) { + if ((tnum < 1) || (tnum >= MAX_TIMERS)) + quit("!StartTimer: invalid timer number"); + play.script_timers[tnum] = timeout; } int IsTimerExpired(int tnum) { - if ((tnum < 1) || (tnum >= MAX_TIMERS)) - quit("!IsTimerExpired: invalid timer number"); - if (play.script_timers[tnum] == 1) { - play.script_timers[tnum] = 0; - return 1; - } - return 0; + if ((tnum < 1) || (tnum >= MAX_TIMERS)) + quit("!IsTimerExpired: invalid timer number"); + if (play.script_timers[tnum] == 1) { + play.script_timers[tnum] = 0; + return 1; + } + return 0; } diff --git a/engines/ags/engine/ac/global_timer.h b/engines/ags/engine/ac/global_timer.h index b387bd8955dc..17b0b78a0486 100644 --- a/engines/ags/engine/ac/global_timer.h +++ b/engines/ags/engine/ac/global_timer.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBAL_TIMER_H #define AGS_ENGINE_AC_GLOBAL_TIMER_H -void script_SetTimer(int tnum,int timeout); +void script_SetTimer(int tnum, int timeout); int IsTimerExpired(int tnum); #endif diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index fb86e11e68e6..5e6230810be3 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -40,54 +40,52 @@ extern AGSPlatformDriver *platform; extern TreeMap *transtree; extern char transFileName[MAX_PATH]; -const char *get_translation (const char *text) { - if (text == nullptr) - quit("!Null string supplied to CheckForTranslations"); +const char *get_translation(const char *text) { + if (text == nullptr) + quit("!Null string supplied to CheckForTranslations"); - source_text_length = GetTextDisplayLength(text); + source_text_length = GetTextDisplayLength(text); #if AGS_PLATFORM_64BIT - // check if a plugin wants to translate it - if so, return that - // TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems - char *plResult = Int32ToPtr(pl_run_plugin_hooks(AGSE_TRANSLATETEXT, PtrToInt32(text))); - if (plResult) { - return plResult; - } + // check if a plugin wants to translate it - if so, return that + // TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems + char *plResult = Int32ToPtr(pl_run_plugin_hooks(AGSE_TRANSLATETEXT, PtrToInt32(text))); + if (plResult) { + return plResult; + } #endif - if (transtree != nullptr) { - // translate the text using the translation file - char * transl = transtree->findValue (text); - if (transl != nullptr) - return transl; - } - // return the original text - return text; + if (transtree != nullptr) { + // translate the text using the translation file + char *transl = transtree->findValue(text); + if (transl != nullptr) + return transl; + } + // return the original text + return text; } -int IsTranslationAvailable () { - if (transtree != nullptr) - return 1; - return 0; +int IsTranslationAvailable() { + if (transtree != nullptr) + return 1; + return 0; } -int GetTranslationName (char* buffer) { - VALIDATE_STRING (buffer); - const char *copyFrom = transFileName; +int GetTranslationName(char *buffer) { + VALIDATE_STRING(buffer); + const char *copyFrom = transFileName; - while (strchr(copyFrom, '\\') != nullptr) - { - copyFrom = strchr(copyFrom, '\\') + 1; - } - while (strchr(copyFrom, '/') != nullptr) - { - copyFrom = strchr(copyFrom, '/') + 1; - } + while (strchr(copyFrom, '\\') != nullptr) { + copyFrom = strchr(copyFrom, '\\') + 1; + } + while (strchr(copyFrom, '/') != nullptr) { + copyFrom = strchr(copyFrom, '/') + 1; + } - strcpy (buffer, copyFrom); - // remove the ".tra" from the end of the filename - if (strstr (buffer, ".tra") != nullptr) - strstr (buffer, ".tra")[0] = 0; + strcpy(buffer, copyFrom); + // remove the ".tra" from the end of the filename + if (strstr(buffer, ".tra") != nullptr) + strstr(buffer, ".tra")[0] = 0; - return IsTranslationAvailable(); + return IsTranslationAvailable(); } diff --git a/engines/ags/engine/ac/global_translation.h b/engines/ags/engine/ac/global_translation.h index ab462602cd79..4c2d7a54eb49 100644 --- a/engines/ags/engine/ac/global_translation.h +++ b/engines/ags/engine/ac/global_translation.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_TRANSLATION_H #define AGS_ENGINE_AC_GLOBAL_TRANSLATION_H -const char *get_translation (const char *text); -int IsTranslationAvailable (); -int GetTranslationName (char* buffer); +const char *get_translation(const char *text); +int IsTranslationAvailable(); +int GetTranslationName(char *buffer); #endif diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp index 89da7e59ff31..20582e0dcdb7 100644 --- a/engines/ags/engine/ac/global_video.cpp +++ b/engines/ags/engine/ac/global_video.cpp @@ -34,56 +34,51 @@ #include "util/string_compat.h" -void scrPlayVideo(const char* name, int skip, int flags) { - EndSkippingUntilCharStops(); +void scrPlayVideo(const char *name, int skip, int flags) { + EndSkippingUntilCharStops(); - if (play.fast_forward) - return; - if (debug_flags & DBG_NOVIDEO) - return; + if (play.fast_forward) + return; + if (debug_flags & DBG_NOVIDEO) + return; - if ((flags < 10) && (usetup.digicard == DIGI_NONE)) { - // if game audio is disabled in Setup, then don't - // play any sound on the video either - flags += 10; - } + if ((flags < 10) && (usetup.digicard == DIGI_NONE)) { + // if game audio is disabled in Setup, then don't + // play any sound on the video either + flags += 10; + } - pause_sound_if_necessary_and_play_video(name, skip, flags); + pause_sound_if_necessary_and_play_video(name, skip, flags); } #ifndef AGS_NO_VIDEO_PLAYER -void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags) -{ - int musplaying = play.cur_music_number, i; - int ambientWas[MAX_SOUND_CHANNELS]; - for (i = 1; i < MAX_SOUND_CHANNELS; i++) - ambientWas[i] = ambient[i].channel; +void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags) { + int musplaying = play.cur_music_number, i; + int ambientWas[MAX_SOUND_CHANNELS]; + for (i = 1; i < MAX_SOUND_CHANNELS; i++) + ambientWas[i] = ambient[i].channel; - if ((strlen(name) > 3) && (ags_stricmp(&name[strlen(name) - 3], "ogv") == 0)) - { - play_theora_video(name, skip, flags); - } - else - { - char videoFilePath[MAX_PATH]; - get_install_dir_path(videoFilePath, name); + if ((strlen(name) > 3) && (ags_stricmp(&name[strlen(name) - 3], "ogv") == 0)) { + play_theora_video(name, skip, flags); + } else { + char videoFilePath[MAX_PATH]; + get_install_dir_path(videoFilePath, name); - platform->PlayVideo(videoFilePath, skip, flags); - } + platform->PlayVideo(videoFilePath, skip, flags); + } - if (flags < 10) - { - update_music_volume(); - // restart the music - if (musplaying >= 0) - newmusic (musplaying); - for (i = 1; i < MAX_SOUND_CHANNELS; i++) { - if (ambientWas[i] > 0) - PlayAmbientSound(ambientWas[i], ambient[i].num, ambient[i].vol, ambient[i].x, ambient[i].y); - } - } + if (flags < 10) { + update_music_volume(); + // restart the music + if (musplaying >= 0) + newmusic(musplaying); + for (i = 1; i < MAX_SOUND_CHANNELS; i++) { + if (ambientWas[i] > 0) + PlayAmbientSound(ambientWas[i], ambient[i].num, ambient[i].vol, ambient[i].x, ambient[i].y); + } + } } #else diff --git a/engines/ags/engine/ac/global_video.h b/engines/ags/engine/ac/global_video.h index ac381da671e8..3996ccad9ba8 100644 --- a/engines/ags/engine/ac/global_video.h +++ b/engines/ags/engine/ac/global_video.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBAL_VIDEO_H #define AGS_ENGINE_AC_GLOBAL_VIDEO_H -void scrPlayVideo(const char* name, int skip, int flags); +void scrPlayVideo(const char *name, int skip, int flags); void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags); #endif diff --git a/engines/ags/engine/ac/global_viewframe.cpp b/engines/ags/engine/ac/global_viewframe.cpp index 08a4486b0efb..ad5f8da4144a 100644 --- a/engines/ags/engine/ac/global_viewframe.cpp +++ b/engines/ags/engine/ac/global_viewframe.cpp @@ -28,30 +28,27 @@ #include "media/audio/audio_system.h" extern GameSetupStruct game; -extern ViewStruct*views; +extern ViewStruct *views; -void SetFrameSound (int vii, int loop, int frame, int sound) { - if ((vii < 1) || (vii > game.numviews)) - quit("!SetFrameSound: invalid view number"); - vii--; +void SetFrameSound(int vii, int loop, int frame, int sound) { + if ((vii < 1) || (vii > game.numviews)) + quit("!SetFrameSound: invalid view number"); + vii--; - if (loop >= views[vii].numLoops) - quit("!SetFrameSound: invalid loop number"); + if (loop >= views[vii].numLoops) + quit("!SetFrameSound: invalid loop number"); - if (frame >= views[vii].loops[loop].numFrames) - quit("!SetFrameSound: invalid frame number"); + if (frame >= views[vii].loops[loop].numFrames) + quit("!SetFrameSound: invalid frame number"); - if (sound < 1) - { - views[vii].loops[loop].frames[frame].sound = -1; - } - else - { - ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, sound); - if (clip == nullptr) - quitprintf("!SetFrameSound: audio clip aSound%d not found", sound); + if (sound < 1) { + views[vii].loops[loop].frames[frame].sound = -1; + } else { + ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(game, false, sound); + if (clip == nullptr) + quitprintf("!SetFrameSound: audio clip aSound%d not found", sound); - views[vii].loops[loop].frames[frame].sound = clip->id + (game.IsLegacyAudioSystem() ? 0x10000000 : 0); - } + views[vii].loops[loop].frames[frame].sound = clip->id + (game.IsLegacyAudioSystem() ? 0x10000000 : 0); + } } diff --git a/engines/ags/engine/ac/global_viewframe.h b/engines/ags/engine/ac/global_viewframe.h index ca0100e8eae7..f06119ba9e3c 100644 --- a/engines/ags/engine/ac/global_viewframe.h +++ b/engines/ags/engine/ac/global_viewframe.h @@ -23,6 +23,6 @@ #ifndef AGS_ENGINE_AC_GLOBAL_VIEWFRAME_H #define AGS_ENGINE_AC_GLOBAL_VIEWFRAME_H -void SetFrameSound (int vii, int loop, int frame, int sound); +void SetFrameSound(int vii, int loop, int frame, int sound); #endif diff --git a/engines/ags/engine/ac/global_viewport.cpp b/engines/ags/engine/ac/global_viewport.cpp index 88397ecd205e..cd64d8117cac 100644 --- a/engines/ags/engine/ac/global_viewport.cpp +++ b/engines/ags/engine/ac/global_viewport.cpp @@ -25,16 +25,16 @@ #include "debug/debug_log.h" void SetViewport(int offsx, int offsy) { - offsx = data_to_game_coord(offsx); - offsy = data_to_game_coord(offsy); - play.GetRoomCamera(0)->LockAt(offsx, offsy); + offsx = data_to_game_coord(offsx); + offsy = data_to_game_coord(offsy); + play.GetRoomCamera(0)->LockAt(offsx, offsy); } void ReleaseViewport() { - play.GetRoomCamera(0)->Release(); + play.GetRoomCamera(0)->Release(); } -int GetViewportX () { - return game_to_data_coord(play.GetRoomCamera(0)->GetRect().Left); +int GetViewportX() { + return game_to_data_coord(play.GetRoomCamera(0)->GetRect().Left); } -int GetViewportY () { - return game_to_data_coord(play.GetRoomCamera(0)->GetRect().Top); +int GetViewportY() { + return game_to_data_coord(play.GetRoomCamera(0)->GetRect().Top); } diff --git a/engines/ags/engine/ac/global_viewport.h b/engines/ags/engine/ac/global_viewport.h index 4e68532410dd..f8bf12179b6e 100644 --- a/engines/ags/engine/ac/global_viewport.h +++ b/engines/ags/engine/ac/global_viewport.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_AC_GLOBAL_VIEWPORT_H #define AGS_ENGINE_AC_GLOBAL_VIEWPORT_H -void SetViewport(int offsx,int offsy); +void SetViewport(int offsx, int offsy); void ReleaseViewport(); -int GetViewportX (); -int GetViewportY (); +int GetViewportX(); +int GetViewportY(); #endif diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp index 584b6a702fb5..7dc5c7ec2afa 100644 --- a/engines/ags/engine/ac/global_walkablearea.cpp +++ b/engines/ags/engine/ac/global_walkablearea.cpp @@ -33,66 +33,65 @@ using namespace AGS::Common; extern RoomStruct thisroom; -int GetScalingAt (int x, int y) { - int onarea = get_walkable_area_pixel(x, y); - if (onarea < 0) - return 100; +int GetScalingAt(int x, int y) { + int onarea = get_walkable_area_pixel(x, y); + if (onarea < 0) + return 100; - return get_area_scaling (onarea, x, y); + return get_area_scaling(onarea, x, y); } void SetAreaScaling(int area, int min, int max) { - if ((area < 0) || (area > MAX_WALK_AREAS)) - quit("!SetAreaScaling: invalid walkalbe area"); - - if (min > max) - quit("!SetAreaScaling: min > max"); - - if ((min < 5) || (max < 5) || (min > 200) || (max > 200)) - quit("!SetAreaScaling: min and max must be in range 5-200"); - - // the values are stored differently - min -= 100; - max -= 100; - - if (min == max) { - thisroom.WalkAreas[area].ScalingFar = min; - thisroom.WalkAreas[area].ScalingNear = NOT_VECTOR_SCALED; - } - else { - thisroom.WalkAreas[area].ScalingFar = min; - thisroom.WalkAreas[area].ScalingNear = max; - } + if ((area < 0) || (area > MAX_WALK_AREAS)) + quit("!SetAreaScaling: invalid walkalbe area"); + + if (min > max) + quit("!SetAreaScaling: min > max"); + + if ((min < 5) || (max < 5) || (min > 200) || (max > 200)) + quit("!SetAreaScaling: min and max must be in range 5-200"); + + // the values are stored differently + min -= 100; + max -= 100; + + if (min == max) { + thisroom.WalkAreas[area].ScalingFar = min; + thisroom.WalkAreas[area].ScalingNear = NOT_VECTOR_SCALED; + } else { + thisroom.WalkAreas[area].ScalingFar = min; + thisroom.WalkAreas[area].ScalingNear = max; + } } void RemoveWalkableArea(int areanum) { - if ((areanum<1) | (areanum>15)) - quit("!RemoveWalkableArea: invalid area number specified (1-15)."); - play.walkable_areas_on[areanum]=0; - redo_walkable_areas(); - debug_script_log("Walkable area %d removed", areanum); + if ((areanum < 1) | (areanum > 15)) + quit("!RemoveWalkableArea: invalid area number specified (1-15)."); + play.walkable_areas_on[areanum] = 0; + redo_walkable_areas(); + debug_script_log("Walkable area %d removed", areanum); } void RestoreWalkableArea(int areanum) { - if ((areanum<1) | (areanum>15)) - quit("!RestoreWalkableArea: invalid area number specified (1-15)."); - play.walkable_areas_on[areanum]=1; - redo_walkable_areas(); - debug_script_log("Walkable area %d restored", areanum); + if ((areanum < 1) | (areanum > 15)) + quit("!RestoreWalkableArea: invalid area number specified (1-15)."); + play.walkable_areas_on[areanum] = 1; + redo_walkable_areas(); + debug_script_log("Walkable area %d restored", areanum); } int GetWalkableAreaAtScreen(int x, int y) { - VpPoint vpt = play.ScreenToRoomDivDown(x, y); - if (vpt.second < 0) - return 0; - return GetWalkableAreaAtRoom(vpt.first.X, vpt.first.Y); + VpPoint vpt = play.ScreenToRoomDivDown(x, y); + if (vpt.second < 0) + return 0; + return GetWalkableAreaAtRoom(vpt.first.X, vpt.first.Y); } int GetWalkableAreaAtRoom(int x, int y) { - int area = get_walkable_area_pixel(x, y); - // IMPORTANT: disabled walkable areas are actually erased completely from the mask; - // see: RemoveWalkableArea() and RestoreWalkableArea(). - return area >= 0 && area < (MAX_WALK_AREAS + 1) ? area : 0; + int area = get_walkable_area_pixel(x, y); + // IMPORTANT: disabled walkable areas are actually erased completely from the mask; + // see: RemoveWalkableArea() and RestoreWalkableArea(). + return area >= 0 && area < (MAX_WALK_AREAS + 1) ? area : 0; } //============================================================================= diff --git a/engines/ags/engine/ac/global_walkablearea.h b/engines/ags/engine/ac/global_walkablearea.h index 7ab0e1188114..837f677fccc8 100644 --- a/engines/ags/engine/ac/global_walkablearea.h +++ b/engines/ags/engine/ac/global_walkablearea.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBAL_WALKABLEAREA_H #define AGS_ENGINE_AC_GLOBAL_WALKABLEAREA_H -int GetScalingAt (int x, int y); +int GetScalingAt(int x, int y); void SetAreaScaling(int area, int min, int max); void RemoveWalkableArea(int areanum); void RestoreWalkableArea(int areanum); diff --git a/engines/ags/engine/ac/global_walkbehind.cpp b/engines/ags/engine/ac/global_walkbehind.cpp index 3a14fde331a8..e48d80bd0485 100644 --- a/engines/ags/engine/ac/global_walkbehind.cpp +++ b/engines/ags/engine/ac/global_walkbehind.cpp @@ -28,17 +28,17 @@ #include "ac/walkbehind.h" #include "debug/debug_log.h" -extern RoomStatus*croom; +extern RoomStatus *croom; extern int walk_behind_baselines_changed; -void SetWalkBehindBase(int wa,int bl) { - if ((wa < 1) || (wa >= MAX_WALK_BEHINDS)) - quit("!SetWalkBehindBase: invalid walk-behind area specified"); +void SetWalkBehindBase(int wa, int bl) { + if ((wa < 1) || (wa >= MAX_WALK_BEHINDS)) + quit("!SetWalkBehindBase: invalid walk-behind area specified"); - if (bl != croom->walkbehind_base[wa]) { - walk_behind_baselines_changed = 1; - invalidate_cached_walkbehinds(); - croom->walkbehind_base[wa] = bl; - debug_script_log("Walk-behind %d baseline changed to %d", wa, bl); - } + if (bl != croom->walkbehind_base[wa]) { + walk_behind_baselines_changed = 1; + invalidate_cached_walkbehinds(); + croom->walkbehind_base[wa] = bl; + debug_script_log("Walk-behind %d baseline changed to %d", wa, bl); + } } diff --git a/engines/ags/engine/ac/global_walkbehind.h b/engines/ags/engine/ac/global_walkbehind.h index 0e9b1efabedf..0243a3a1ee36 100644 --- a/engines/ags/engine/ac/global_walkbehind.h +++ b/engines/ags/engine/ac/global_walkbehind.h @@ -23,6 +23,6 @@ #ifndef AGS_ENGINE_AC_GLOBAL_WALKBEHIND_H #define AGS_ENGINE_AC_GLOBAL_WALKBEHIND_H -void SetWalkBehindBase(int wa,int bl); +void SetWalkBehindBase(int wa, int bl); #endif diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp index deb12cf0ed1e..479060c578c7 100644 --- a/engines/ags/engine/ac/gui.cpp +++ b/engines/ags/engine/ac/gui.cpp @@ -62,7 +62,7 @@ using namespace AGS::Engine; extern GameSetup usetup; extern RoomStruct thisroom; -extern int cur_mode,cur_cursor; +extern int cur_mode, cur_cursor; extern ccInstance *gameinst; extern ScriptGUI *scrGui; extern GameSetupStruct game; @@ -75,636 +75,607 @@ extern CCGUI ccDynamicGUI; extern CCGUIObject ccDynamicGUIObject; -int ifacepopped=-1; // currently displayed pop-up GUI (-1 if none) -int mouse_on_iface=-1; // mouse cursor is over this interface -int mouse_ifacebut_xoffs=-1,mouse_ifacebut_yoffs=-1; +int ifacepopped = -1; // currently displayed pop-up GUI (-1 if none) +int mouse_on_iface = -1; // mouse cursor is over this interface +int mouse_ifacebut_xoffs = -1, mouse_ifacebut_yoffs = -1; int eip_guinum, eip_guiobj; -ScriptGUI* GUI_AsTextWindow(ScriptGUI *tehgui) -{ // Internally both GUI and TextWindow are implemented by same class - return guis[tehgui->id].IsTextWindow() ? &scrGui[tehgui->id] : nullptr; +ScriptGUI *GUI_AsTextWindow(ScriptGUI *tehgui) { + // Internally both GUI and TextWindow are implemented by same class + return guis[tehgui->id].IsTextWindow() ? &scrGui[tehgui->id] : nullptr; } -int GUI_GetPopupStyle(ScriptGUI *tehgui) -{ - return guis[tehgui->id].PopupStyle; +int GUI_GetPopupStyle(ScriptGUI *tehgui) { + return guis[tehgui->id].PopupStyle; } void GUI_SetVisible(ScriptGUI *tehgui, int isvisible) { - if (isvisible) - InterfaceOn(tehgui->id); - else - InterfaceOff(tehgui->id); + if (isvisible) + InterfaceOn(tehgui->id); + else + InterfaceOff(tehgui->id); } int GUI_GetVisible(ScriptGUI *tehgui) { - // GUI_GetVisible is slightly different from IsGUIOn, because - // with a mouse ypos gui it returns 1 if the GUI is enabled, - // whereas IsGUIOn actually checks if it is displayed - return guis[tehgui->id].IsVisible() ? 1 : 0; + // GUI_GetVisible is slightly different from IsGUIOn, because + // with a mouse ypos gui it returns 1 if the GUI is enabled, + // whereas IsGUIOn actually checks if it is displayed + return guis[tehgui->id].IsVisible() ? 1 : 0; } int GUI_GetX(ScriptGUI *tehgui) { - return game_to_data_coord(guis[tehgui->id].X); + return game_to_data_coord(guis[tehgui->id].X); } void GUI_SetX(ScriptGUI *tehgui, int xx) { - guis[tehgui->id].X = data_to_game_coord(xx); + guis[tehgui->id].X = data_to_game_coord(xx); } int GUI_GetY(ScriptGUI *tehgui) { - return game_to_data_coord(guis[tehgui->id].Y); + return game_to_data_coord(guis[tehgui->id].Y); } void GUI_SetY(ScriptGUI *tehgui, int yy) { - guis[tehgui->id].Y = data_to_game_coord(yy); + guis[tehgui->id].Y = data_to_game_coord(yy); } void GUI_SetPosition(ScriptGUI *tehgui, int xx, int yy) { - GUI_SetX(tehgui, xx); - GUI_SetY(tehgui, yy); + GUI_SetX(tehgui, xx); + GUI_SetY(tehgui, yy); } void GUI_SetSize(ScriptGUI *sgui, int widd, int hitt) { - if ((widd < 1) || (hitt < 1)) - quitprintf("!SetGUISize: invalid dimensions (tried to set to %d x %d)", widd, hitt); + if ((widd < 1) || (hitt < 1)) + quitprintf("!SetGUISize: invalid dimensions (tried to set to %d x %d)", widd, hitt); - GUIMain *tehgui = &guis[sgui->id]; - data_to_game_coords(&widd, &hitt); + GUIMain *tehgui = &guis[sgui->id]; + data_to_game_coords(&widd, &hitt); - if ((tehgui->Width == widd) && (tehgui->Height == hitt)) - return; - - tehgui->Width = widd; - tehgui->Height = hitt; - - recreate_guibg_image(tehgui); + if ((tehgui->Width == widd) && (tehgui->Height == hitt)) + return; - guis_need_update = 1; + tehgui->Width = widd; + tehgui->Height = hitt; + + recreate_guibg_image(tehgui); + + guis_need_update = 1; } int GUI_GetWidth(ScriptGUI *sgui) { - return game_to_data_coord(guis[sgui->id].Width); + return game_to_data_coord(guis[sgui->id].Width); } int GUI_GetHeight(ScriptGUI *sgui) { - return game_to_data_coord(guis[sgui->id].Height); + return game_to_data_coord(guis[sgui->id].Height); } void GUI_SetWidth(ScriptGUI *sgui, int newwid) { - GUI_SetSize(sgui, newwid, GUI_GetHeight(sgui)); + GUI_SetSize(sgui, newwid, GUI_GetHeight(sgui)); } void GUI_SetHeight(ScriptGUI *sgui, int newhit) { - GUI_SetSize(sgui, GUI_GetWidth(sgui), newhit); + GUI_SetSize(sgui, GUI_GetWidth(sgui), newhit); } void GUI_SetZOrder(ScriptGUI *tehgui, int z) { - guis[tehgui->id].ZOrder = z; - update_gui_zorder(); + guis[tehgui->id].ZOrder = z; + update_gui_zorder(); } int GUI_GetZOrder(ScriptGUI *tehgui) { - return guis[tehgui->id].ZOrder; + return guis[tehgui->id].ZOrder; } void GUI_SetClickable(ScriptGUI *tehgui, int clickable) { - guis[tehgui->id].SetClickable(clickable != 0); + guis[tehgui->id].SetClickable(clickable != 0); } int GUI_GetClickable(ScriptGUI *tehgui) { - return guis[tehgui->id].IsClickable() ? 1 : 0; + return guis[tehgui->id].IsClickable() ? 1 : 0; } int GUI_GetID(ScriptGUI *tehgui) { - return tehgui->id; + return tehgui->id; } -GUIObject* GUI_GetiControls(ScriptGUI *tehgui, int idx) { - if ((idx < 0) || (idx >= guis[tehgui->id].GetControlCount())) - return nullptr; - return guis[tehgui->id].GetControl(idx); +GUIObject *GUI_GetiControls(ScriptGUI *tehgui, int idx) { + if ((idx < 0) || (idx >= guis[tehgui->id].GetControlCount())) + return nullptr; + return guis[tehgui->id].GetControl(idx); } int GUI_GetControlCount(ScriptGUI *tehgui) { - return guis[tehgui->id].GetControlCount(); + return guis[tehgui->id].GetControlCount(); } -int GUI_GetPopupYPos(ScriptGUI *tehgui) -{ - return guis[tehgui->id].PopupAtMouseY; +int GUI_GetPopupYPos(ScriptGUI *tehgui) { + return guis[tehgui->id].PopupAtMouseY; } -void GUI_SetPopupYPos(ScriptGUI *tehgui, int newpos) -{ - if (!guis[tehgui->id].IsTextWindow()) - guis[tehgui->id].PopupAtMouseY = newpos; +void GUI_SetPopupYPos(ScriptGUI *tehgui, int newpos) { + if (!guis[tehgui->id].IsTextWindow()) + guis[tehgui->id].PopupAtMouseY = newpos; } void GUI_SetTransparency(ScriptGUI *tehgui, int trans) { - if ((trans < 0) | (trans > 100)) - quit("!SetGUITransparency: transparency value must be between 0 and 100"); + if ((trans < 0) | (trans > 100)) + quit("!SetGUITransparency: transparency value must be between 0 and 100"); - guis[tehgui->id].SetTransparencyAsPercentage(trans); + guis[tehgui->id].SetTransparencyAsPercentage(trans); } int GUI_GetTransparency(ScriptGUI *tehgui) { - if (guis[tehgui->id].Transparency == 0) - return 0; - if (guis[tehgui->id].Transparency == 255) - return 100; + if (guis[tehgui->id].Transparency == 0) + return 0; + if (guis[tehgui->id].Transparency == 255) + return 100; - return 100 - ((guis[tehgui->id].Transparency * 10) / 25); + return 100 - ((guis[tehgui->id].Transparency * 10) / 25); } void GUI_Centre(ScriptGUI *sgui) { - GUIMain *tehgui = &guis[sgui->id]; - tehgui->X = play.GetUIViewport().GetWidth() / 2 - tehgui->Width / 2; - tehgui->Y = play.GetUIViewport().GetHeight() / 2 - tehgui->Height / 2; + GUIMain *tehgui = &guis[sgui->id]; + tehgui->X = play.GetUIViewport().GetWidth() / 2 - tehgui->Width / 2; + tehgui->Y = play.GetUIViewport().GetHeight() / 2 - tehgui->Height / 2; } void GUI_SetBackgroundGraphic(ScriptGUI *tehgui, int slotn) { - if (guis[tehgui->id].BgImage != slotn) { - guis[tehgui->id].BgImage = slotn; - guis_need_update = 1; - } + if (guis[tehgui->id].BgImage != slotn) { + guis[tehgui->id].BgImage = slotn; + guis_need_update = 1; + } } int GUI_GetBackgroundGraphic(ScriptGUI *tehgui) { - if (guis[tehgui->id].BgImage < 1) - return 0; - return guis[tehgui->id].BgImage; + if (guis[tehgui->id].BgImage < 1) + return 0; + return guis[tehgui->id].BgImage; } -void GUI_SetBackgroundColor(ScriptGUI *tehgui, int newcol) -{ - if (guis[tehgui->id].BgColor != newcol) - { - guis[tehgui->id].BgColor = newcol; - guis_need_update = 1; - } +void GUI_SetBackgroundColor(ScriptGUI *tehgui, int newcol) { + if (guis[tehgui->id].BgColor != newcol) { + guis[tehgui->id].BgColor = newcol; + guis_need_update = 1; + } } -int GUI_GetBackgroundColor(ScriptGUI *tehgui) -{ - return guis[tehgui->id].BgColor; +int GUI_GetBackgroundColor(ScriptGUI *tehgui) { + return guis[tehgui->id].BgColor; } -void GUI_SetBorderColor(ScriptGUI *tehgui, int newcol) -{ - if (guis[tehgui->id].IsTextWindow()) - return; - if (guis[tehgui->id].FgColor != newcol) - { - guis[tehgui->id].FgColor = newcol; - guis_need_update = 1; - } +void GUI_SetBorderColor(ScriptGUI *tehgui, int newcol) { + if (guis[tehgui->id].IsTextWindow()) + return; + if (guis[tehgui->id].FgColor != newcol) { + guis[tehgui->id].FgColor = newcol; + guis_need_update = 1; + } } -int GUI_GetBorderColor(ScriptGUI *tehgui) -{ - if (guis[tehgui->id].IsTextWindow()) - return 0; - return guis[tehgui->id].FgColor; +int GUI_GetBorderColor(ScriptGUI *tehgui) { + if (guis[tehgui->id].IsTextWindow()) + return 0; + return guis[tehgui->id].FgColor; } -void GUI_SetTextColor(ScriptGUI *tehgui, int newcol) -{ - if (!guis[tehgui->id].IsTextWindow()) - return; - if (guis[tehgui->id].FgColor != newcol) - { - guis[tehgui->id].FgColor = newcol; - guis_need_update = 1; - } +void GUI_SetTextColor(ScriptGUI *tehgui, int newcol) { + if (!guis[tehgui->id].IsTextWindow()) + return; + if (guis[tehgui->id].FgColor != newcol) { + guis[tehgui->id].FgColor = newcol; + guis_need_update = 1; + } } -int GUI_GetTextColor(ScriptGUI *tehgui) -{ - if (!guis[tehgui->id].IsTextWindow()) - return 0; - return guis[tehgui->id].FgColor; +int GUI_GetTextColor(ScriptGUI *tehgui) { + if (!guis[tehgui->id].IsTextWindow()) + return 0; + return guis[tehgui->id].FgColor; } -int GUI_GetTextPadding(ScriptGUI *tehgui) -{ - return guis[tehgui->id].Padding; +int GUI_GetTextPadding(ScriptGUI *tehgui) { + return guis[tehgui->id].Padding; } -void GUI_SetTextPadding(ScriptGUI *tehgui, int newpos) -{ - if (guis[tehgui->id].IsTextWindow()) - guis[tehgui->id].Padding = newpos; +void GUI_SetTextPadding(ScriptGUI *tehgui, int newpos) { + if (guis[tehgui->id].IsTextWindow()) + guis[tehgui->id].Padding = newpos; } ScriptGUI *GetGUIAtLocation(int xx, int yy) { - int guiid = GetGUIAt(xx, yy); - if (guiid < 0) - return nullptr; - return &scrGui[guiid]; -} - -void GUI_Click(ScriptGUI *scgui, int mbut) -{ - process_interface_click(scgui->id, -1, mbut); -} - -void GUI_ProcessClick(int x, int y, int mbut) -{ - int guiid = gui_get_interactable(x, y); - if (guiid >= 0) - { - const int real_mousex = mousex; - const int real_mousey = mousey; - mousex = x; - mousey = y; - guis[guiid].Poll(); - gui_on_mouse_down(guiid, mbut); - gui_on_mouse_up(guiid, mbut); - mousex = real_mousex; - mousey = real_mousey; - } + int guiid = GetGUIAt(xx, yy); + if (guiid < 0) + return nullptr; + return &scrGui[guiid]; +} + +void GUI_Click(ScriptGUI *scgui, int mbut) { + process_interface_click(scgui->id, -1, mbut); +} + +void GUI_ProcessClick(int x, int y, int mbut) { + int guiid = gui_get_interactable(x, y); + if (guiid >= 0) { + const int real_mousex = mousex; + const int real_mousey = mousey; + mousex = x; + mousey = y; + guis[guiid].Poll(); + gui_on_mouse_down(guiid, mbut); + gui_on_mouse_up(guiid, mbut); + mousex = real_mousex; + mousey = real_mousey; + } } //============================================================================= void remove_popup_interface(int ifacenum) { - if (ifacepopped != ifacenum) return; - ifacepopped=-1; UnPauseGame(); - guis[ifacenum].SetConceal(true); - if (mousey<=guis[ifacenum].PopupAtMouseY) - Mouse::SetPosition(Point(mousex, guis[ifacenum].PopupAtMouseY+2)); - if ((!IsInterfaceEnabled()) && (cur_cursor == cur_mode)) - // Only change the mouse cursor if it hasn't been specifically changed first - set_mouse_cursor(CURS_WAIT); - else if (IsInterfaceEnabled()) - set_default_cursor(); - - if (ifacenum==mouse_on_iface) mouse_on_iface=-1; - guis_need_update = 1; + if (ifacepopped != ifacenum) return; + ifacepopped = -1; + UnPauseGame(); + guis[ifacenum].SetConceal(true); + if (mousey <= guis[ifacenum].PopupAtMouseY) + Mouse::SetPosition(Point(mousex, guis[ifacenum].PopupAtMouseY + 2)); + if ((!IsInterfaceEnabled()) && (cur_cursor == cur_mode)) + // Only change the mouse cursor if it hasn't been specifically changed first + set_mouse_cursor(CURS_WAIT); + else if (IsInterfaceEnabled()) + set_default_cursor(); + + if (ifacenum == mouse_on_iface) mouse_on_iface = -1; + guis_need_update = 1; } void process_interface_click(int ifce, int btn, int mbut) { - if (btn < 0) { - // click on GUI background - QueueScriptFunction(kScInstGame, guis[ifce].OnClickHandler, 2, - RuntimeScriptValue().SetDynamicObject(&scrGui[ifce], &ccDynamicGUI), - RuntimeScriptValue().SetInt32(mbut)); - return; - } - - int btype = guis[ifce].GetControlType(btn); - int rtype=kGUIAction_None,rdata; - if (btype==kGUIButton) { - GUIButton*gbuto=(GUIButton*)guis[ifce].GetControl(btn); - rtype=gbuto->ClickAction[kMouseLeft]; - rdata=gbuto->ClickData[kMouseLeft]; - } - else if ((btype==kGUISlider) || (btype == kGUITextBox) || (btype == kGUIListBox)) - rtype = kGUIAction_RunScript; - else quit("unknown GUI object triggered process_interface"); - - if (rtype==kGUIAction_None) ; - else if (rtype==kGUIAction_SetMode) - set_cursor_mode(rdata); - else if (rtype==kGUIAction_RunScript) { - GUIObject *theObj = guis[ifce].GetControl(btn); - // if the object has a special handler script then run it; - // otherwise, run interface_click - if ((theObj->GetEventCount() > 0) && - (!theObj->EventHandlers[0].IsEmpty()) && - (!gameinst->GetSymbolAddress(theObj->EventHandlers[0]).IsNull())) { - // control-specific event handler - if (strchr(theObj->GetEventArgs(0), ',') != nullptr) - QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 2, - RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject), - RuntimeScriptValue().SetInt32(mbut)); - else - QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 1, - RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject)); - } - else - QueueScriptFunction(kScInstGame, "interface_click", 2, - RuntimeScriptValue().SetInt32(ifce), - RuntimeScriptValue().SetInt32(btn)); - } + if (btn < 0) { + // click on GUI background + QueueScriptFunction(kScInstGame, guis[ifce].OnClickHandler, 2, + RuntimeScriptValue().SetDynamicObject(&scrGui[ifce], &ccDynamicGUI), + RuntimeScriptValue().SetInt32(mbut)); + return; + } + + int btype = guis[ifce].GetControlType(btn); + int rtype = kGUIAction_None, rdata; + if (btype == kGUIButton) { + GUIButton *gbuto = (GUIButton *)guis[ifce].GetControl(btn); + rtype = gbuto->ClickAction[kMouseLeft]; + rdata = gbuto->ClickData[kMouseLeft]; + } else if ((btype == kGUISlider) || (btype == kGUITextBox) || (btype == kGUIListBox)) + rtype = kGUIAction_RunScript; + else quit("unknown GUI object triggered process_interface"); + + if (rtype == kGUIAction_None) ; + else if (rtype == kGUIAction_SetMode) + set_cursor_mode(rdata); + else if (rtype == kGUIAction_RunScript) { + GUIObject *theObj = guis[ifce].GetControl(btn); + // if the object has a special handler script then run it; + // otherwise, run interface_click + if ((theObj->GetEventCount() > 0) && + (!theObj->EventHandlers[0].IsEmpty()) && + (!gameinst->GetSymbolAddress(theObj->EventHandlers[0]).IsNull())) { + // control-specific event handler + if (strchr(theObj->GetEventArgs(0), ',') != nullptr) + QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 2, + RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject), + RuntimeScriptValue().SetInt32(mbut)); + else + QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 1, + RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject)); + } else + QueueScriptFunction(kScInstGame, "interface_click", 2, + RuntimeScriptValue().SetInt32(ifce), + RuntimeScriptValue().SetInt32(btn)); + } } void replace_macro_tokens(const char *text, String &fixed_text) { - const char*curptr=&text[0]; - char tmpm[3]; - const char*endat = curptr + strlen(text); - fixed_text.Empty(); - char tempo[STD_BUFFER_SIZE]; - - while (1) { - if (curptr[0]==0) break; - if (curptr>=endat) break; - if (curptr[0]=='@') { - const char *curptrWasAt = curptr; - char macroname[21]; int idd=0; curptr++; - for (idd=0;idd<20;idd++) { - if (curptr[0]=='@') { - macroname[idd]=0; - curptr++; - break; - } - // unterminated macro (eg. "@SCORETEXT"), so abort - if (curptr[0] == 0) - break; - macroname[idd]=curptr[0]; - curptr++; - } - macroname[idd]=0; - tempo[0]=0; - if (ags_stricmp(macroname,"score")==0) - sprintf(tempo,"%d",play.score); - else if (ags_stricmp(macroname,"totalscore")==0) - sprintf(tempo,"%d",MAXSCORE); - else if (ags_stricmp(macroname,"scoretext")==0) - sprintf(tempo,"%d of %d",play.score,MAXSCORE); - else if (ags_stricmp(macroname,"gamename")==0) - strcpy(tempo, play.game_name); - else if (ags_stricmp(macroname,"overhotspot")==0) { - // While game is in Wait mode, no overhotspot text - if (!IsInterfaceEnabled()) - tempo[0] = 0; - else - GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); - } - else { // not a macro, there's just a @ in the message - curptr = curptrWasAt + 1; - strcpy(tempo, "@"); - } - - fixed_text.Append(tempo); - } - else { - tmpm[0]=curptr[0]; tmpm[1]=0; - fixed_text.Append(tmpm); - curptr++; - } - } + const char *curptr = &text[0]; + char tmpm[3]; + const char *endat = curptr + strlen(text); + fixed_text.Empty(); + char tempo[STD_BUFFER_SIZE]; + + while (1) { + if (curptr[0] == 0) break; + if (curptr >= endat) break; + if (curptr[0] == '@') { + const char *curptrWasAt = curptr; + char macroname[21]; + int idd = 0; + curptr++; + for (idd = 0; idd < 20; idd++) { + if (curptr[0] == '@') { + macroname[idd] = 0; + curptr++; + break; + } + // unterminated macro (eg. "@SCORETEXT"), so abort + if (curptr[0] == 0) + break; + macroname[idd] = curptr[0]; + curptr++; + } + macroname[idd] = 0; + tempo[0] = 0; + if (ags_stricmp(macroname, "score") == 0) + sprintf(tempo, "%d", play.score); + else if (ags_stricmp(macroname, "totalscore") == 0) + sprintf(tempo, "%d", MAXSCORE); + else if (ags_stricmp(macroname, "scoretext") == 0) + sprintf(tempo, "%d of %d", play.score, MAXSCORE); + else if (ags_stricmp(macroname, "gamename") == 0) + strcpy(tempo, play.game_name); + else if (ags_stricmp(macroname, "overhotspot") == 0) { + // While game is in Wait mode, no overhotspot text + if (!IsInterfaceEnabled()) + tempo[0] = 0; + else + GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + } else { // not a macro, there's just a @ in the message + curptr = curptrWasAt + 1; + strcpy(tempo, "@"); + } + + fixed_text.Append(tempo); + } else { + tmpm[0] = curptr[0]; + tmpm[1] = 0; + fixed_text.Append(tmpm); + curptr++; + } + } } void update_gui_zorder() { - int numdone = 0, b; - - // for each GUI - for (int a = 0; a < game.numgui; a++) { - // find the right place in the draw order array - int insertAt = numdone; - for (b = 0; b < numdone; b++) { - if (guis[a].ZOrder < guis[play.gui_draw_order[b]].ZOrder) { - insertAt = b; - break; - } - } - // insert the new item - for (b = numdone - 1; b >= insertAt; b--) - play.gui_draw_order[b + 1] = play.gui_draw_order[b]; - play.gui_draw_order[insertAt] = a; - numdone++; - } - -} - - -void export_gui_controls(int ee) -{ - for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) - { - GUIObject *guio = guis[ee].GetControl(ff); - if (!guio->Name.IsEmpty()) - ccAddExternalDynamicObject(guio->Name, guio, &ccDynamicGUIObject); - ccRegisterManagedObject(guio, &ccDynamicGUIObject); - } -} - -void unexport_gui_controls(int ee) -{ - for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) - { - GUIObject *guio = guis[ee].GetControl(ff); - if (!guio->Name.IsEmpty()) - ccRemoveExternalSymbol(guio->Name); - if (!ccUnRegisterManagedObject(guio)) - quit("unable to unregister guicontrol object"); - } + int numdone = 0, b; + + // for each GUI + for (int a = 0; a < game.numgui; a++) { + // find the right place in the draw order array + int insertAt = numdone; + for (b = 0; b < numdone; b++) { + if (guis[a].ZOrder < guis[play.gui_draw_order[b]].ZOrder) { + insertAt = b; + break; + } + } + // insert the new item + for (b = numdone - 1; b >= insertAt; b--) + play.gui_draw_order[b + 1] = play.gui_draw_order[b]; + play.gui_draw_order[insertAt] = a; + numdone++; + } + +} + + +void export_gui_controls(int ee) { + for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) { + GUIObject *guio = guis[ee].GetControl(ff); + if (!guio->Name.IsEmpty()) + ccAddExternalDynamicObject(guio->Name, guio, &ccDynamicGUIObject); + ccRegisterManagedObject(guio, &ccDynamicGUIObject); + } +} + +void unexport_gui_controls(int ee) { + for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) { + GUIObject *guio = guis[ee].GetControl(ff); + if (!guio->Name.IsEmpty()) + ccRemoveExternalSymbol(guio->Name); + if (!ccUnRegisterManagedObject(guio)) + quit("unable to unregister guicontrol object"); + } } int convert_gui_disabled_style(int oldStyle) { - int toret = GUIDIS_GREYOUT; + int toret = GUIDIS_GREYOUT; - // if GUIs Turn Off is selected, don't grey out buttons for - // any Persistent GUIs which remain - // set to 0x80 so that it is still non-zero, but has no effect - if (oldStyle == 3) - toret = GUIDIS_GUIOFF; - // GUIs Go Black - else if (oldStyle == 1) - toret = GUIDIS_BLACKOUT; - // GUIs unchanged - else if (oldStyle == 2) - toret = GUIDIS_UNCHANGED; + // if GUIs Turn Off is selected, don't grey out buttons for + // any Persistent GUIs which remain + // set to 0x80 so that it is still non-zero, but has no effect + if (oldStyle == 3) + toret = GUIDIS_GUIOFF; + // GUIs Go Black + else if (oldStyle == 1) + toret = GUIDIS_BLACKOUT; + // GUIs unchanged + else if (oldStyle == 2) + toret = GUIDIS_UNCHANGED; - return toret; + return toret; } void update_gui_disabled_status() { - // update GUI display status (perhaps we've gone into - // an interface disabled state) - int all_buttons_was = all_buttons_disabled; - all_buttons_disabled = 0; - - if (!IsInterfaceEnabled()) { - all_buttons_disabled = gui_disabled_style; - } - - if (all_buttons_was != all_buttons_disabled) { - // GUIs might have been removed/added - for (int aa = 0; aa < game.numgui; aa++) { - guis[aa].OnControlPositionChanged(); - } - guis_need_update = 1; - invalidate_screen(); - } -} - - -int adjust_x_for_guis (int xx, int yy) { - if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) - return xx; - // If it's covered by a GUI, move it right a bit - for (int aa=0;aa < game.numgui; aa++) { - if (!guis[aa].IsDisplayed()) - continue; - if ((guis[aa].X > xx) || (guis[aa].Y > yy) || (guis[aa].Y + guis[aa].Height < yy)) - continue; - // totally transparent GUI, ignore - if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1)) - continue; - - // try to deal with full-width GUIs across the top - if (guis[aa].X + guis[aa].Width >= get_fixed_pixel_size(280)) - continue; - - if (xx < guis[aa].X + guis[aa].Width) - xx = guis[aa].X + guis[aa].Width + 2; - } - return xx; -} - -int adjust_y_for_guis ( int yy) { - if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) - return yy; - // If it's covered by a GUI, move it down a bit - for (int aa=0;aa < game.numgui; aa++) { - if (!guis[aa].IsDisplayed()) - continue; - if (guis[aa].Y > yy) - continue; - // totally transparent GUI, ignore - if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1)) - continue; - - // try to deal with full-height GUIs down the left or right - if (guis[aa].Height > get_fixed_pixel_size(50)) - continue; - - if (yy < guis[aa].Y + guis[aa].Height) - yy = guis[aa].Y + guis[aa].Height + 2; - } - return yy; -} - -void recreate_guibg_image(GUIMain *tehgui) -{ - int ifn = tehgui->ID; - delete guibg[ifn]; - guibg[ifn] = BitmapHelper::CreateBitmap(tehgui->Width, tehgui->Height, game.GetColorDepth()); - if (guibg[ifn] == nullptr) - quit("SetGUISize: internal error: unable to reallocate gui cache"); - guibg[ifn] = ReplaceBitmapWithSupportedFormat(guibg[ifn]); - - if (guibgbmp[ifn] != nullptr) - { - gfxDriver->DestroyDDB(guibgbmp[ifn]); - guibgbmp[ifn] = nullptr; - } + // update GUI display status (perhaps we've gone into + // an interface disabled state) + int all_buttons_was = all_buttons_disabled; + all_buttons_disabled = 0; + + if (!IsInterfaceEnabled()) { + all_buttons_disabled = gui_disabled_style; + } + + if (all_buttons_was != all_buttons_disabled) { + // GUIs might have been removed/added + for (int aa = 0; aa < game.numgui; aa++) { + guis[aa].OnControlPositionChanged(); + } + guis_need_update = 1; + invalidate_screen(); + } +} + + +int adjust_x_for_guis(int xx, int yy) { + if ((game.options[OPT_DISABLEOFF] == 3) && (all_buttons_disabled > 0)) + return xx; + // If it's covered by a GUI, move it right a bit + for (int aa = 0; aa < game.numgui; aa++) { + if (!guis[aa].IsDisplayed()) + continue; + if ((guis[aa].X > xx) || (guis[aa].Y > yy) || (guis[aa].Y + guis[aa].Height < yy)) + continue; + // totally transparent GUI, ignore + if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1)) + continue; + + // try to deal with full-width GUIs across the top + if (guis[aa].X + guis[aa].Width >= get_fixed_pixel_size(280)) + continue; + + if (xx < guis[aa].X + guis[aa].Width) + xx = guis[aa].X + guis[aa].Width + 2; + } + return xx; +} + +int adjust_y_for_guis(int yy) { + if ((game.options[OPT_DISABLEOFF] == 3) && (all_buttons_disabled > 0)) + return yy; + // If it's covered by a GUI, move it down a bit + for (int aa = 0; aa < game.numgui; aa++) { + if (!guis[aa].IsDisplayed()) + continue; + if (guis[aa].Y > yy) + continue; + // totally transparent GUI, ignore + if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1)) + continue; + + // try to deal with full-height GUIs down the left or right + if (guis[aa].Height > get_fixed_pixel_size(50)) + continue; + + if (yy < guis[aa].Y + guis[aa].Height) + yy = guis[aa].Y + guis[aa].Height + 2; + } + return yy; +} + +void recreate_guibg_image(GUIMain *tehgui) { + int ifn = tehgui->ID; + delete guibg[ifn]; + guibg[ifn] = BitmapHelper::CreateBitmap(tehgui->Width, tehgui->Height, game.GetColorDepth()); + if (guibg[ifn] == nullptr) + quit("SetGUISize: internal error: unable to reallocate gui cache"); + guibg[ifn] = ReplaceBitmapWithSupportedFormat(guibg[ifn]); + + if (guibgbmp[ifn] != nullptr) { + gfxDriver->DestroyDDB(guibgbmp[ifn]); + guibgbmp[ifn] = nullptr; + } } extern int is_complete_overlay; -int gui_get_interactable(int x,int y) -{ - if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) - return -1; - return GetGUIAt(x, y); -} - -int gui_on_mouse_move() -{ - int mouse_over_gui = -1; - // If all GUIs are off, skip the loop - if ((game.options[OPT_DISABLEOFF]==3) && (all_buttons_disabled > 0)) ; - else { - // Scan for mouse-y-pos GUIs, and pop one up if appropriate - // Also work out the mouse-over GUI while we're at it - int ll; - for (ll = 0; ll < game.numgui;ll++) { - const int guin = play.gui_draw_order[ll]; - if (guis[guin].IsInteractableAt(mousex, mousey)) mouse_over_gui=guin; - - if (guis[guin].PopupStyle!=kGUIPopupMouseY) continue; - if (is_complete_overlay>0) break; // interfaces disabled - // if (play.disabled_user_interface>0) break; - if (ifacepopped==guin) continue; - if (!guis[guin].IsVisible()) continue; - // Don't allow it to be popped up while skipping cutscene - if (play.fast_forward) continue; - - if (mousey < guis[guin].PopupAtMouseY) { - set_mouse_cursor(CURS_ARROW); - guis[guin].SetConceal(false); guis_need_update = 1; - ifacepopped=guin; PauseGame(); - break; - } - } - } - return mouse_over_gui; -} - -void gui_on_mouse_hold(const int wasongui, const int wasbutdown) -{ - for (int i=0;iIsActivated) continue; - if (guis[wasongui].GetControlType(i)!=kGUISlider) continue; - // GUI Slider repeatedly activates while being dragged - guio->IsActivated = false; - force_event(EV_IFACECLICK, wasongui, i, wasbutdown); - break; - } -} - -void gui_on_mouse_up(const int wasongui, const int wasbutdown) -{ - guis[wasongui].OnMouseButtonUp(); - - for (int i=0;iIsActivated) continue; - guio->IsActivated = false; - if (!IsInterfaceEnabled()) break; - - int cttype=guis[wasongui].GetControlType(i); - if ((cttype == kGUIButton) || (cttype == kGUISlider) || (cttype == kGUIListBox)) { - force_event(EV_IFACECLICK, wasongui, i, wasbutdown); - } - else if (cttype == kGUIInvWindow) { - mouse_ifacebut_xoffs=mousex-(guio->X)-guis[wasongui].X; - mouse_ifacebut_yoffs=mousey-(guio->Y)-guis[wasongui].Y; - int iit=offset_over_inv((GUIInvWindow*)guio); - if (iit>=0) { - evblocknum=iit; - play.used_inv_on = iit; - if (game.options[OPT_HANDLEINVCLICKS]) { - // Let the script handle the click - // LEFTINV is 5, RIGHTINV is 6 - force_event(EV_TEXTSCRIPT,TS_MCLICK, wasbutdown + 4); - } - else if (wasbutdown==2) // right-click is always Look - run_event_block_inv(iit, 0); - else if (cur_mode == MODE_HAND) - SetActiveInventory(iit); - else - RunInventoryInteraction (iit, cur_mode); - evblocknum=-1; - } - } - else quit("clicked on unknown control type"); - if (guis[wasongui].PopupStyle==kGUIPopupMouseY) - remove_popup_interface(wasongui); - break; - } - - run_on_event(GE_GUI_MOUSEUP, RuntimeScriptValue().SetInt32(wasongui)); -} - -void gui_on_mouse_down(const int guin, const int mbut) -{ - debug_script_log("Mouse click over GUI %d", guin); - guis[guin].OnMouseButtonDown(); - // run GUI click handler if not on any control - if ((guis[guin].MouseDownCtrl < 0) && (!guis[guin].OnClickHandler.IsEmpty())) - force_event(EV_IFACECLICK, guin, -1, mbut); - - run_on_event(GE_GUI_MOUSEDOWN, RuntimeScriptValue().SetInt32(guin)); +int gui_get_interactable(int x, int y) { + if ((game.options[OPT_DISABLEOFF] == 3) && (all_buttons_disabled > 0)) + return -1; + return GetGUIAt(x, y); +} + +int gui_on_mouse_move() { + int mouse_over_gui = -1; + // If all GUIs are off, skip the loop + if ((game.options[OPT_DISABLEOFF] == 3) && (all_buttons_disabled > 0)) ; + else { + // Scan for mouse-y-pos GUIs, and pop one up if appropriate + // Also work out the mouse-over GUI while we're at it + int ll; + for (ll = 0; ll < game.numgui; ll++) { + const int guin = play.gui_draw_order[ll]; + if (guis[guin].IsInteractableAt(mousex, mousey)) mouse_over_gui = guin; + + if (guis[guin].PopupStyle != kGUIPopupMouseY) continue; + if (is_complete_overlay > 0) break; // interfaces disabled + // if (play.disabled_user_interface>0) break; + if (ifacepopped == guin) continue; + if (!guis[guin].IsVisible()) continue; + // Don't allow it to be popped up while skipping cutscene + if (play.fast_forward) continue; + + if (mousey < guis[guin].PopupAtMouseY) { + set_mouse_cursor(CURS_ARROW); + guis[guin].SetConceal(false); + guis_need_update = 1; + ifacepopped = guin; + PauseGame(); + break; + } + } + } + return mouse_over_gui; +} + +void gui_on_mouse_hold(const int wasongui, const int wasbutdown) { + for (int i = 0; i < guis[wasongui].GetControlCount(); i++) { + GUIObject *guio = guis[wasongui].GetControl(i); + if (!guio->IsActivated) continue; + if (guis[wasongui].GetControlType(i) != kGUISlider) continue; + // GUI Slider repeatedly activates while being dragged + guio->IsActivated = false; + force_event(EV_IFACECLICK, wasongui, i, wasbutdown); + break; + } +} + +void gui_on_mouse_up(const int wasongui, const int wasbutdown) { + guis[wasongui].OnMouseButtonUp(); + + for (int i = 0; i < guis[wasongui].GetControlCount(); i++) { + GUIObject *guio = guis[wasongui].GetControl(i); + if (!guio->IsActivated) continue; + guio->IsActivated = false; + if (!IsInterfaceEnabled()) break; + + int cttype = guis[wasongui].GetControlType(i); + if ((cttype == kGUIButton) || (cttype == kGUISlider) || (cttype == kGUIListBox)) { + force_event(EV_IFACECLICK, wasongui, i, wasbutdown); + } else if (cttype == kGUIInvWindow) { + mouse_ifacebut_xoffs = mousex - (guio->X) - guis[wasongui].X; + mouse_ifacebut_yoffs = mousey - (guio->Y) - guis[wasongui].Y; + int iit = offset_over_inv((GUIInvWindow *)guio); + if (iit >= 0) { + evblocknum = iit; + play.used_inv_on = iit; + if (game.options[OPT_HANDLEINVCLICKS]) { + // Let the script handle the click + // LEFTINV is 5, RIGHTINV is 6 + force_event(EV_TEXTSCRIPT, TS_MCLICK, wasbutdown + 4); + } else if (wasbutdown == 2) // right-click is always Look + run_event_block_inv(iit, 0); + else if (cur_mode == MODE_HAND) + SetActiveInventory(iit); + else + RunInventoryInteraction(iit, cur_mode); + evblocknum = -1; + } + } else quit("clicked on unknown control type"); + if (guis[wasongui].PopupStyle == kGUIPopupMouseY) + remove_popup_interface(wasongui); + break; + } + + run_on_event(GE_GUI_MOUSEUP, RuntimeScriptValue().SetInt32(wasongui)); +} + +void gui_on_mouse_down(const int guin, const int mbut) { + debug_script_log("Mouse click over GUI %d", guin); + guis[guin].OnMouseButtonDown(); + // run GUI click handler if not on any control + if ((guis[guin].MouseDownCtrl < 0) && (!guis[guin].OnClickHandler.IsEmpty())) + force_event(EV_IFACECLICK, guin, -1, mbut); + + run_on_event(GE_GUI_MOUSEDOWN, RuntimeScriptValue().SetInt32(guin)); } //============================================================================= @@ -718,292 +689,252 @@ void gui_on_mouse_down(const int guin, const int mbut) #include "script/script_runtime.h" // void GUI_Centre(ScriptGUI *sgui) -RuntimeScriptValue Sc_GUI_Centre(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptGUI, GUI_Centre); +RuntimeScriptValue Sc_GUI_Centre(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptGUI, GUI_Centre); } // ScriptGUI *(int xx, int yy) -RuntimeScriptValue Sc_GetGUIAtLocation(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptGUI, ccDynamicGUI, GetGUIAtLocation); +RuntimeScriptValue Sc_GetGUIAtLocation(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptGUI, ccDynamicGUI, GetGUIAtLocation); } // void (ScriptGUI *tehgui, int xx, int yy) -RuntimeScriptValue Sc_GUI_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptGUI, GUI_SetPosition); +RuntimeScriptValue Sc_GUI_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptGUI, GUI_SetPosition); } // void (ScriptGUI *sgui, int widd, int hitt) -RuntimeScriptValue Sc_GUI_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptGUI, GUI_SetSize); +RuntimeScriptValue Sc_GUI_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptGUI, GUI_SetSize); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetBackgroundGraphic); +RuntimeScriptValue Sc_GUI_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetBackgroundGraphic); } // void (ScriptGUI *tehgui, int slotn) -RuntimeScriptValue Sc_GUI_SetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBackgroundGraphic); +RuntimeScriptValue Sc_GUI_SetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBackgroundGraphic); } -RuntimeScriptValue Sc_GUI_GetBackgroundColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetBackgroundColor); +RuntimeScriptValue Sc_GUI_GetBackgroundColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetBackgroundColor); } -RuntimeScriptValue Sc_GUI_SetBackgroundColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBackgroundColor); +RuntimeScriptValue Sc_GUI_SetBackgroundColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBackgroundColor); } -RuntimeScriptValue Sc_GUI_GetBorderColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetBorderColor); +RuntimeScriptValue Sc_GUI_GetBorderColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetBorderColor); } -RuntimeScriptValue Sc_GUI_SetBorderColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBorderColor); +RuntimeScriptValue Sc_GUI_SetBorderColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetBorderColor); } -RuntimeScriptValue Sc_GUI_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetTextColor); +RuntimeScriptValue Sc_GUI_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetTextColor); } -RuntimeScriptValue Sc_GUI_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTextColor); +RuntimeScriptValue Sc_GUI_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTextColor); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetClickable); +RuntimeScriptValue Sc_GUI_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetClickable); } // void (ScriptGUI *tehgui, int clickable) -RuntimeScriptValue Sc_GUI_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetClickable); +RuntimeScriptValue Sc_GUI_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetClickable); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetControlCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetControlCount); +RuntimeScriptValue Sc_GUI_GetControlCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetControlCount); } // GUIObject* (ScriptGUI *tehgui, int idx) -RuntimeScriptValue Sc_GUI_GetiControls(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT(ScriptGUI, GUIObject, ccDynamicGUIObject, GUI_GetiControls); +RuntimeScriptValue Sc_GUI_GetiControls(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT(ScriptGUI, GUIObject, ccDynamicGUIObject, GUI_GetiControls); } // int (ScriptGUI *sgui) -RuntimeScriptValue Sc_GUI_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetHeight); +RuntimeScriptValue Sc_GUI_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetHeight); } // void (ScriptGUI *sgui, int newhit) -RuntimeScriptValue Sc_GUI_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetHeight); +RuntimeScriptValue Sc_GUI_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetHeight); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetID); +RuntimeScriptValue Sc_GUI_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetID); } -RuntimeScriptValue Sc_GUI_GetPopupYPos(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetPopupYPos); +RuntimeScriptValue Sc_GUI_GetPopupYPos(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetPopupYPos); } -RuntimeScriptValue Sc_GUI_SetPopupYPos(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetPopupYPos); +RuntimeScriptValue Sc_GUI_SetPopupYPos(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetPopupYPos); } -RuntimeScriptValue Sc_GUI_GetTextPadding(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetTextPadding); +RuntimeScriptValue Sc_GUI_GetTextPadding(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetTextPadding); } -RuntimeScriptValue Sc_GUI_SetTextPadding(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTextPadding); +RuntimeScriptValue Sc_GUI_SetTextPadding(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTextPadding); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetTransparency); +RuntimeScriptValue Sc_GUI_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetTransparency); } // void (ScriptGUI *tehgui, int trans) -RuntimeScriptValue Sc_GUI_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTransparency); +RuntimeScriptValue Sc_GUI_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetTransparency); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetVisible); +RuntimeScriptValue Sc_GUI_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetVisible); } // void (ScriptGUI *tehgui, int isvisible) -RuntimeScriptValue Sc_GUI_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetVisible); +RuntimeScriptValue Sc_GUI_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetVisible); } // int (ScriptGUI *sgui) -RuntimeScriptValue Sc_GUI_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetWidth); +RuntimeScriptValue Sc_GUI_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetWidth); } // void (ScriptGUI *sgui, int newwid) -RuntimeScriptValue Sc_GUI_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetWidth); +RuntimeScriptValue Sc_GUI_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetWidth); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetX); +RuntimeScriptValue Sc_GUI_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetX); } // void (ScriptGUI *tehgui, int xx) -RuntimeScriptValue Sc_GUI_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetX); +RuntimeScriptValue Sc_GUI_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetX); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetY); +RuntimeScriptValue Sc_GUI_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetY); } // void (ScriptGUI *tehgui, int yy) -RuntimeScriptValue Sc_GUI_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetY); +RuntimeScriptValue Sc_GUI_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetY); } // int (ScriptGUI *tehgui) -RuntimeScriptValue Sc_GUI_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetZOrder); +RuntimeScriptValue Sc_GUI_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetZOrder); } // void (ScriptGUI *tehgui, int z) -RuntimeScriptValue Sc_GUI_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetZOrder); -} - -RuntimeScriptValue Sc_GUI_AsTextWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptGUI, ScriptGUI, ccDynamicGUI, GUI_AsTextWindow); -} - -RuntimeScriptValue Sc_GUI_GetPopupStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptGUI, GUI_GetPopupStyle); -} - -RuntimeScriptValue Sc_GUI_Click(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptGUI, GUI_Click); -} - -RuntimeScriptValue Sc_GUI_ProcessClick(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(GUI_ProcessClick); -} - -void RegisterGUIAPI() -{ - ccAddExternalObjectFunction("GUI::Centre^0", Sc_GUI_Centre); - ccAddExternalObjectFunction("GUI::Click^1", Sc_GUI_Click); - ccAddExternalStaticFunction("GUI::GetAtScreenXY^2", Sc_GetGUIAtLocation); - ccAddExternalStaticFunction("GUI::ProcessClick^3", Sc_GUI_ProcessClick); - ccAddExternalObjectFunction("GUI::SetPosition^2", Sc_GUI_SetPosition); - ccAddExternalObjectFunction("GUI::SetSize^2", Sc_GUI_SetSize); - ccAddExternalObjectFunction("GUI::get_BackgroundGraphic", Sc_GUI_GetBackgroundGraphic); - ccAddExternalObjectFunction("GUI::set_BackgroundGraphic", Sc_GUI_SetBackgroundGraphic); - ccAddExternalObjectFunction("GUI::get_BackgroundColor", Sc_GUI_GetBackgroundColor); - ccAddExternalObjectFunction("GUI::set_BackgroundColor", Sc_GUI_SetBackgroundColor); - ccAddExternalObjectFunction("GUI::get_BorderColor", Sc_GUI_GetBorderColor); - ccAddExternalObjectFunction("GUI::set_BorderColor", Sc_GUI_SetBorderColor); - ccAddExternalObjectFunction("GUI::get_Clickable", Sc_GUI_GetClickable); - ccAddExternalObjectFunction("GUI::set_Clickable", Sc_GUI_SetClickable); - ccAddExternalObjectFunction("GUI::get_ControlCount", Sc_GUI_GetControlCount); - ccAddExternalObjectFunction("GUI::geti_Controls", Sc_GUI_GetiControls); - ccAddExternalObjectFunction("GUI::get_Height", Sc_GUI_GetHeight); - ccAddExternalObjectFunction("GUI::set_Height", Sc_GUI_SetHeight); - ccAddExternalObjectFunction("GUI::get_ID", Sc_GUI_GetID); - ccAddExternalObjectFunction("GUI::get_AsTextWindow", Sc_GUI_AsTextWindow); - ccAddExternalObjectFunction("GUI::get_PopupStyle", Sc_GUI_GetPopupStyle); - ccAddExternalObjectFunction("GUI::get_PopupYPos", Sc_GUI_GetPopupYPos); - ccAddExternalObjectFunction("GUI::set_PopupYPos", Sc_GUI_SetPopupYPos); - ccAddExternalObjectFunction("TextWindowGUI::get_TextColor", Sc_GUI_GetTextColor); - ccAddExternalObjectFunction("TextWindowGUI::set_TextColor", Sc_GUI_SetTextColor); - ccAddExternalObjectFunction("TextWindowGUI::get_TextPadding", Sc_GUI_GetTextPadding); - ccAddExternalObjectFunction("TextWindowGUI::set_TextPadding", Sc_GUI_SetTextPadding); - ccAddExternalObjectFunction("GUI::get_Transparency", Sc_GUI_GetTransparency); - ccAddExternalObjectFunction("GUI::set_Transparency", Sc_GUI_SetTransparency); - ccAddExternalObjectFunction("GUI::get_Visible", Sc_GUI_GetVisible); - ccAddExternalObjectFunction("GUI::set_Visible", Sc_GUI_SetVisible); - ccAddExternalObjectFunction("GUI::get_Width", Sc_GUI_GetWidth); - ccAddExternalObjectFunction("GUI::set_Width", Sc_GUI_SetWidth); - ccAddExternalObjectFunction("GUI::get_X", Sc_GUI_GetX); - ccAddExternalObjectFunction("GUI::set_X", Sc_GUI_SetX); - ccAddExternalObjectFunction("GUI::get_Y", Sc_GUI_GetY); - ccAddExternalObjectFunction("GUI::set_Y", Sc_GUI_SetY); - ccAddExternalObjectFunction("GUI::get_ZOrder", Sc_GUI_GetZOrder); - ccAddExternalObjectFunction("GUI::set_ZOrder", Sc_GUI_SetZOrder); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("GUI::Centre^0", (void*)GUI_Centre); - ccAddExternalFunctionForPlugin("GUI::GetAtScreenXY^2", (void*)GetGUIAtLocation); - ccAddExternalFunctionForPlugin("GUI::SetPosition^2", (void*)GUI_SetPosition); - ccAddExternalFunctionForPlugin("GUI::SetSize^2", (void*)GUI_SetSize); - ccAddExternalFunctionForPlugin("GUI::get_BackgroundGraphic", (void*)GUI_GetBackgroundGraphic); - ccAddExternalFunctionForPlugin("GUI::set_BackgroundGraphic", (void*)GUI_SetBackgroundGraphic); - ccAddExternalFunctionForPlugin("GUI::get_Clickable", (void*)GUI_GetClickable); - ccAddExternalFunctionForPlugin("GUI::set_Clickable", (void*)GUI_SetClickable); - ccAddExternalFunctionForPlugin("GUI::get_ControlCount", (void*)GUI_GetControlCount); - ccAddExternalFunctionForPlugin("GUI::geti_Controls", (void*)GUI_GetiControls); - ccAddExternalFunctionForPlugin("GUI::get_Height", (void*)GUI_GetHeight); - ccAddExternalFunctionForPlugin("GUI::set_Height", (void*)GUI_SetHeight); - ccAddExternalFunctionForPlugin("GUI::get_ID", (void*)GUI_GetID); - ccAddExternalFunctionForPlugin("GUI::get_Transparency", (void*)GUI_GetTransparency); - ccAddExternalFunctionForPlugin("GUI::set_Transparency", (void*)GUI_SetTransparency); - ccAddExternalFunctionForPlugin("GUI::get_Visible", (void*)GUI_GetVisible); - ccAddExternalFunctionForPlugin("GUI::set_Visible", (void*)GUI_SetVisible); - ccAddExternalFunctionForPlugin("GUI::get_Width", (void*)GUI_GetWidth); - ccAddExternalFunctionForPlugin("GUI::set_Width", (void*)GUI_SetWidth); - ccAddExternalFunctionForPlugin("GUI::get_X", (void*)GUI_GetX); - ccAddExternalFunctionForPlugin("GUI::set_X", (void*)GUI_SetX); - ccAddExternalFunctionForPlugin("GUI::get_Y", (void*)GUI_GetY); - ccAddExternalFunctionForPlugin("GUI::set_Y", (void*)GUI_SetY); - ccAddExternalFunctionForPlugin("GUI::get_ZOrder", (void*)GUI_GetZOrder); - ccAddExternalFunctionForPlugin("GUI::set_ZOrder", (void*)GUI_SetZOrder); +RuntimeScriptValue Sc_GUI_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_SetZOrder); +} + +RuntimeScriptValue Sc_GUI_AsTextWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptGUI, ScriptGUI, ccDynamicGUI, GUI_AsTextWindow); +} + +RuntimeScriptValue Sc_GUI_GetPopupStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptGUI, GUI_GetPopupStyle); +} + +RuntimeScriptValue Sc_GUI_Click(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptGUI, GUI_Click); +} + +RuntimeScriptValue Sc_GUI_ProcessClick(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(GUI_ProcessClick); +} + +void RegisterGUIAPI() { + ccAddExternalObjectFunction("GUI::Centre^0", Sc_GUI_Centre); + ccAddExternalObjectFunction("GUI::Click^1", Sc_GUI_Click); + ccAddExternalStaticFunction("GUI::GetAtScreenXY^2", Sc_GetGUIAtLocation); + ccAddExternalStaticFunction("GUI::ProcessClick^3", Sc_GUI_ProcessClick); + ccAddExternalObjectFunction("GUI::SetPosition^2", Sc_GUI_SetPosition); + ccAddExternalObjectFunction("GUI::SetSize^2", Sc_GUI_SetSize); + ccAddExternalObjectFunction("GUI::get_BackgroundGraphic", Sc_GUI_GetBackgroundGraphic); + ccAddExternalObjectFunction("GUI::set_BackgroundGraphic", Sc_GUI_SetBackgroundGraphic); + ccAddExternalObjectFunction("GUI::get_BackgroundColor", Sc_GUI_GetBackgroundColor); + ccAddExternalObjectFunction("GUI::set_BackgroundColor", Sc_GUI_SetBackgroundColor); + ccAddExternalObjectFunction("GUI::get_BorderColor", Sc_GUI_GetBorderColor); + ccAddExternalObjectFunction("GUI::set_BorderColor", Sc_GUI_SetBorderColor); + ccAddExternalObjectFunction("GUI::get_Clickable", Sc_GUI_GetClickable); + ccAddExternalObjectFunction("GUI::set_Clickable", Sc_GUI_SetClickable); + ccAddExternalObjectFunction("GUI::get_ControlCount", Sc_GUI_GetControlCount); + ccAddExternalObjectFunction("GUI::geti_Controls", Sc_GUI_GetiControls); + ccAddExternalObjectFunction("GUI::get_Height", Sc_GUI_GetHeight); + ccAddExternalObjectFunction("GUI::set_Height", Sc_GUI_SetHeight); + ccAddExternalObjectFunction("GUI::get_ID", Sc_GUI_GetID); + ccAddExternalObjectFunction("GUI::get_AsTextWindow", Sc_GUI_AsTextWindow); + ccAddExternalObjectFunction("GUI::get_PopupStyle", Sc_GUI_GetPopupStyle); + ccAddExternalObjectFunction("GUI::get_PopupYPos", Sc_GUI_GetPopupYPos); + ccAddExternalObjectFunction("GUI::set_PopupYPos", Sc_GUI_SetPopupYPos); + ccAddExternalObjectFunction("TextWindowGUI::get_TextColor", Sc_GUI_GetTextColor); + ccAddExternalObjectFunction("TextWindowGUI::set_TextColor", Sc_GUI_SetTextColor); + ccAddExternalObjectFunction("TextWindowGUI::get_TextPadding", Sc_GUI_GetTextPadding); + ccAddExternalObjectFunction("TextWindowGUI::set_TextPadding", Sc_GUI_SetTextPadding); + ccAddExternalObjectFunction("GUI::get_Transparency", Sc_GUI_GetTransparency); + ccAddExternalObjectFunction("GUI::set_Transparency", Sc_GUI_SetTransparency); + ccAddExternalObjectFunction("GUI::get_Visible", Sc_GUI_GetVisible); + ccAddExternalObjectFunction("GUI::set_Visible", Sc_GUI_SetVisible); + ccAddExternalObjectFunction("GUI::get_Width", Sc_GUI_GetWidth); + ccAddExternalObjectFunction("GUI::set_Width", Sc_GUI_SetWidth); + ccAddExternalObjectFunction("GUI::get_X", Sc_GUI_GetX); + ccAddExternalObjectFunction("GUI::set_X", Sc_GUI_SetX); + ccAddExternalObjectFunction("GUI::get_Y", Sc_GUI_GetY); + ccAddExternalObjectFunction("GUI::set_Y", Sc_GUI_SetY); + ccAddExternalObjectFunction("GUI::get_ZOrder", Sc_GUI_GetZOrder); + ccAddExternalObjectFunction("GUI::set_ZOrder", Sc_GUI_SetZOrder); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("GUI::Centre^0", (void *)GUI_Centre); + ccAddExternalFunctionForPlugin("GUI::GetAtScreenXY^2", (void *)GetGUIAtLocation); + ccAddExternalFunctionForPlugin("GUI::SetPosition^2", (void *)GUI_SetPosition); + ccAddExternalFunctionForPlugin("GUI::SetSize^2", (void *)GUI_SetSize); + ccAddExternalFunctionForPlugin("GUI::get_BackgroundGraphic", (void *)GUI_GetBackgroundGraphic); + ccAddExternalFunctionForPlugin("GUI::set_BackgroundGraphic", (void *)GUI_SetBackgroundGraphic); + ccAddExternalFunctionForPlugin("GUI::get_Clickable", (void *)GUI_GetClickable); + ccAddExternalFunctionForPlugin("GUI::set_Clickable", (void *)GUI_SetClickable); + ccAddExternalFunctionForPlugin("GUI::get_ControlCount", (void *)GUI_GetControlCount); + ccAddExternalFunctionForPlugin("GUI::geti_Controls", (void *)GUI_GetiControls); + ccAddExternalFunctionForPlugin("GUI::get_Height", (void *)GUI_GetHeight); + ccAddExternalFunctionForPlugin("GUI::set_Height", (void *)GUI_SetHeight); + ccAddExternalFunctionForPlugin("GUI::get_ID", (void *)GUI_GetID); + ccAddExternalFunctionForPlugin("GUI::get_Transparency", (void *)GUI_GetTransparency); + ccAddExternalFunctionForPlugin("GUI::set_Transparency", (void *)GUI_SetTransparency); + ccAddExternalFunctionForPlugin("GUI::get_Visible", (void *)GUI_GetVisible); + ccAddExternalFunctionForPlugin("GUI::set_Visible", (void *)GUI_SetVisible); + ccAddExternalFunctionForPlugin("GUI::get_Width", (void *)GUI_GetWidth); + ccAddExternalFunctionForPlugin("GUI::set_Width", (void *)GUI_SetWidth); + ccAddExternalFunctionForPlugin("GUI::get_X", (void *)GUI_GetX); + ccAddExternalFunctionForPlugin("GUI::set_X", (void *)GUI_SetX); + ccAddExternalFunctionForPlugin("GUI::get_Y", (void *)GUI_GetY); + ccAddExternalFunctionForPlugin("GUI::set_Y", (void *)GUI_SetY); + ccAddExternalFunctionForPlugin("GUI::get_ZOrder", (void *)GUI_GetZOrder); + ccAddExternalFunctionForPlugin("GUI::set_ZOrder", (void *)GUI_SetZOrder); } diff --git a/engines/ags/engine/ac/gui.h b/engines/ags/engine/ac/gui.h index a80f8843578a..9a2eb055cc39 100644 --- a/engines/ags/engine/ac/gui.h +++ b/engines/ags/engine/ac/gui.h @@ -31,32 +31,32 @@ using AGS::Common::GUIObject; ScriptGUI *GUI_AsTextWindow(ScriptGUI *tehgui); int GUI_GetPopupStyle(ScriptGUI *tehgui); -void GUI_SetVisible(ScriptGUI *tehgui, int isvisible); -int GUI_GetVisible(ScriptGUI *tehgui); -int GUI_GetX(ScriptGUI *tehgui); -void GUI_SetX(ScriptGUI *tehgui, int xx); -int GUI_GetY(ScriptGUI *tehgui); -void GUI_SetY(ScriptGUI *tehgui, int yy); -void GUI_SetPosition(ScriptGUI *tehgui, int xx, int yy); -void GUI_SetSize(ScriptGUI *sgui, int widd, int hitt); -int GUI_GetWidth(ScriptGUI *sgui); -int GUI_GetHeight(ScriptGUI *sgui); -void GUI_SetWidth(ScriptGUI *sgui, int newwid); -void GUI_SetHeight(ScriptGUI *sgui, int newhit); -void GUI_SetZOrder(ScriptGUI *tehgui, int z); -int GUI_GetZOrder(ScriptGUI *tehgui); -void GUI_SetClickable(ScriptGUI *tehgui, int clickable); -int GUI_GetClickable(ScriptGUI *tehgui); -int GUI_GetID(ScriptGUI *tehgui); -GUIObject* GUI_GetiControls(ScriptGUI *tehgui, int idx); -int GUI_GetControlCount(ScriptGUI *tehgui); +void GUI_SetVisible(ScriptGUI *tehgui, int isvisible); +int GUI_GetVisible(ScriptGUI *tehgui); +int GUI_GetX(ScriptGUI *tehgui); +void GUI_SetX(ScriptGUI *tehgui, int xx); +int GUI_GetY(ScriptGUI *tehgui); +void GUI_SetY(ScriptGUI *tehgui, int yy); +void GUI_SetPosition(ScriptGUI *tehgui, int xx, int yy); +void GUI_SetSize(ScriptGUI *sgui, int widd, int hitt); +int GUI_GetWidth(ScriptGUI *sgui); +int GUI_GetHeight(ScriptGUI *sgui); +void GUI_SetWidth(ScriptGUI *sgui, int newwid); +void GUI_SetHeight(ScriptGUI *sgui, int newhit); +void GUI_SetZOrder(ScriptGUI *tehgui, int z); +int GUI_GetZOrder(ScriptGUI *tehgui); +void GUI_SetClickable(ScriptGUI *tehgui, int clickable); +int GUI_GetClickable(ScriptGUI *tehgui); +int GUI_GetID(ScriptGUI *tehgui); +GUIObject *GUI_GetiControls(ScriptGUI *tehgui, int idx); +int GUI_GetControlCount(ScriptGUI *tehgui); void GUI_SetPopupYPos(ScriptGUI *tehgui, int newpos); int GUI_GetPopupYPos(ScriptGUI *tehgui); -void GUI_SetTransparency(ScriptGUI *tehgui, int trans); -int GUI_GetTransparency(ScriptGUI *tehgui); -void GUI_Centre(ScriptGUI *sgui); -void GUI_SetBackgroundGraphic(ScriptGUI *tehgui, int slotn); -int GUI_GetBackgroundGraphic(ScriptGUI *tehgui); +void GUI_SetTransparency(ScriptGUI *tehgui, int trans); +int GUI_GetTransparency(ScriptGUI *tehgui); +void GUI_Centre(ScriptGUI *sgui); +void GUI_SetBackgroundGraphic(ScriptGUI *tehgui, int slotn); +int GUI_GetBackgroundGraphic(ScriptGUI *tehgui); void GUI_SetBackgroundColor(ScriptGUI *tehgui, int newcol); int GUI_GetBackgroundColor(ScriptGUI *tehgui); void GUI_SetBorderColor(ScriptGUI *tehgui, int newcol); @@ -67,19 +67,19 @@ void GUI_SetTextPadding(ScriptGUI *tehgui, int newpos); int GUI_GetTextPadding(ScriptGUI *tehgui); ScriptGUI *GetGUIAtLocation(int xx, int yy); -void remove_popup_interface(int ifacenum); -void process_interface_click(int ifce, int btn, int mbut); -void replace_macro_tokens(const char *text, AGS::Common::String &fixed_text); -void update_gui_zorder(); -void export_gui_controls(int ee); -void unexport_gui_controls(int ee); -int convert_gui_disabled_style(int oldStyle); -void update_gui_disabled_status(); -int adjust_x_for_guis (int xx, int yy); -int adjust_y_for_guis ( int yy); -void recreate_guibg_image(GUIMain *tehgui); +void remove_popup_interface(int ifacenum); +void process_interface_click(int ifce, int btn, int mbut); +void replace_macro_tokens(const char *text, AGS::Common::String &fixed_text); +void update_gui_zorder(); +void export_gui_controls(int ee); +void unexport_gui_controls(int ee); +int convert_gui_disabled_style(int oldStyle); +void update_gui_disabled_status(); +int adjust_x_for_guis(int xx, int yy); +int adjust_y_for_guis(int yy); +void recreate_guibg_image(GUIMain *tehgui); -int gui_get_interactable(int x,int y); +int gui_get_interactable(int x, int y); int gui_on_mouse_move(); void gui_on_mouse_hold(const int wasongui, const int wasbutdown); void gui_on_mouse_up(const int wasongui, const int wasbutdown); diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp index 2587cac7ebaa..cc182c4db89e 100644 --- a/engines/ags/engine/ac/guicontrol.cpp +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -37,201 +37,196 @@ using namespace AGS::Common; -extern ScriptGUI*scrGui; +extern ScriptGUI *scrGui; extern CCGUI ccDynamicGUI; extern CCGUIObject ccDynamicGUIObject; GUIObject *GetGUIControlAtLocation(int xx, int yy) { - int guinum = GetGUIAt(xx, yy); - if (guinum == -1) - return nullptr; + int guinum = GetGUIAt(xx, yy); + if (guinum == -1) + return nullptr; - data_to_game_coords(&xx, &yy); + data_to_game_coords(&xx, &yy); - int oldmousex = mousex, oldmousey = mousey; - mousex = xx - guis[guinum].X; - mousey = yy - guis[guinum].Y; - int toret = guis[guinum].FindControlUnderMouse(0, false); - mousex = oldmousex; - mousey = oldmousey; - if (toret < 0) - return nullptr; + int oldmousex = mousex, oldmousey = mousey; + mousex = xx - guis[guinum].X; + mousey = yy - guis[guinum].Y; + int toret = guis[guinum].FindControlUnderMouse(0, false); + mousex = oldmousex; + mousey = oldmousey; + if (toret < 0) + return nullptr; - return guis[guinum].GetControl(toret); + return guis[guinum].GetControl(toret); } int GUIControl_GetVisible(GUIObject *guio) { - return guio->IsVisible(); + return guio->IsVisible(); } -void GUIControl_SetVisible(GUIObject *guio, int visible) -{ - const bool on = visible != 0; - if (on != guio->IsVisible()) - { - guio->SetVisible(on); - guis[guio->ParentId].OnControlPositionChanged(); - guis_need_update = 1; - } +void GUIControl_SetVisible(GUIObject *guio, int visible) { + const bool on = visible != 0; + if (on != guio->IsVisible()) { + guio->SetVisible(on); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; + } } int GUIControl_GetClickable(GUIObject *guio) { - if (guio->IsClickable()) - return 1; - return 0; + if (guio->IsClickable()) + return 1; + return 0; } void GUIControl_SetClickable(GUIObject *guio, int enabled) { - if (enabled) - guio->SetClickable(true); - else - guio->SetClickable(false); + if (enabled) + guio->SetClickable(true); + else + guio->SetClickable(false); - guis[guio->ParentId].OnControlPositionChanged(); - guis_need_update = 1; + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; } int GUIControl_GetEnabled(GUIObject *guio) { - return guio->IsEnabled() ? 1 : 0; + return guio->IsEnabled() ? 1 : 0; } void GUIControl_SetEnabled(GUIObject *guio, int enabled) { - const bool on = enabled != 0; - if (on != guio->IsEnabled()) - { - guio->SetEnabled(on); - guis[guio->ParentId].OnControlPositionChanged(); - guis_need_update = 1; - } + const bool on = enabled != 0; + if (on != guio->IsEnabled()) { + guio->SetEnabled(on); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; + } } int GUIControl_GetID(GUIObject *guio) { - return guio->Id; + return guio->Id; } -ScriptGUI* GUIControl_GetOwningGUI(GUIObject *guio) { - return &scrGui[guio->ParentId]; +ScriptGUI *GUIControl_GetOwningGUI(GUIObject *guio) { + return &scrGui[guio->ParentId]; } -GUIButton* GUIControl_GetAsButton(GUIObject *guio) { - if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIButton) - return nullptr; +GUIButton *GUIControl_GetAsButton(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIButton) + return nullptr; - return (GUIButton*)guio; + return (GUIButton *)guio; } -GUIInvWindow* GUIControl_GetAsInvWindow(GUIObject *guio) { - if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIInvWindow) - return nullptr; +GUIInvWindow *GUIControl_GetAsInvWindow(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIInvWindow) + return nullptr; - return (GUIInvWindow*)guio; + return (GUIInvWindow *)guio; } -GUILabel* GUIControl_GetAsLabel(GUIObject *guio) { - if (guis[guio->ParentId].GetControlType(guio->Id) != kGUILabel) - return nullptr; +GUILabel *GUIControl_GetAsLabel(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUILabel) + return nullptr; - return (GUILabel*)guio; + return (GUILabel *)guio; } -GUIListBox* GUIControl_GetAsListBox(GUIObject *guio) { - if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIListBox) - return nullptr; +GUIListBox *GUIControl_GetAsListBox(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIListBox) + return nullptr; - return (GUIListBox*)guio; + return (GUIListBox *)guio; } -GUISlider* GUIControl_GetAsSlider(GUIObject *guio) { - if (guis[guio->ParentId].GetControlType(guio->Id) != kGUISlider) - return nullptr; +GUISlider *GUIControl_GetAsSlider(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUISlider) + return nullptr; - return (GUISlider*)guio; + return (GUISlider *)guio; } -GUITextBox* GUIControl_GetAsTextBox(GUIObject *guio) { - if (guis[guio->ParentId].GetControlType(guio->Id) != kGUITextBox) - return nullptr; +GUITextBox *GUIControl_GetAsTextBox(GUIObject *guio) { + if (guis[guio->ParentId].GetControlType(guio->Id) != kGUITextBox) + return nullptr; - return (GUITextBox*)guio; + return (GUITextBox *)guio; } int GUIControl_GetX(GUIObject *guio) { - return game_to_data_coord(guio->X); + return game_to_data_coord(guio->X); } void GUIControl_SetX(GUIObject *guio, int xx) { - guio->X = data_to_game_coord(xx); - guis[guio->ParentId].OnControlPositionChanged(); - guis_need_update = 1; + guio->X = data_to_game_coord(xx); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; } int GUIControl_GetY(GUIObject *guio) { - return game_to_data_coord(guio->Y); + return game_to_data_coord(guio->Y); } void GUIControl_SetY(GUIObject *guio, int yy) { - guio->Y = data_to_game_coord(yy); - guis[guio->ParentId].OnControlPositionChanged(); - guis_need_update = 1; + guio->Y = data_to_game_coord(yy); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; } -int GUIControl_GetZOrder(GUIObject *guio) -{ - return guio->ZOrder; +int GUIControl_GetZOrder(GUIObject *guio) { + return guio->ZOrder; } -void GUIControl_SetZOrder(GUIObject *guio, int zorder) -{ - if (guis[guio->ParentId].SetControlZOrder(guio->Id, zorder)) - guis_need_update = 1; +void GUIControl_SetZOrder(GUIObject *guio, int zorder) { + if (guis[guio->ParentId].SetControlZOrder(guio->Id, zorder)) + guis_need_update = 1; } void GUIControl_SetPosition(GUIObject *guio, int xx, int yy) { - GUIControl_SetX(guio, xx); - GUIControl_SetY(guio, yy); + GUIControl_SetX(guio, xx); + GUIControl_SetY(guio, yy); } int GUIControl_GetWidth(GUIObject *guio) { - return game_to_data_coord(guio->Width); + return game_to_data_coord(guio->Width); } void GUIControl_SetWidth(GUIObject *guio, int newwid) { - guio->Width = data_to_game_coord(newwid); - guio->OnResized(); - guis[guio->ParentId].OnControlPositionChanged(); - guis_need_update = 1; + guio->Width = data_to_game_coord(newwid); + guio->OnResized(); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; } int GUIControl_GetHeight(GUIObject *guio) { - return game_to_data_coord(guio->Height); + return game_to_data_coord(guio->Height); } void GUIControl_SetHeight(GUIObject *guio, int newhit) { - guio->Height = data_to_game_coord(newhit); - guio->OnResized(); - guis[guio->ParentId].OnControlPositionChanged(); - guis_need_update = 1; + guio->Height = data_to_game_coord(newhit); + guio->OnResized(); + guis[guio->ParentId].OnControlPositionChanged(); + guis_need_update = 1; } void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit) { - if ((newwid < 2) || (newhit < 2)) - quit("!SetGUIObjectSize: new size is too small (must be at least 2x2)"); + if ((newwid < 2) || (newhit < 2)) + quit("!SetGUIObjectSize: new size is too small (must be at least 2x2)"); - debug_script_log("SetGUIObject %d,%d size %d,%d", guio->ParentId, guio->Id, newwid, newhit); - GUIControl_SetWidth(guio, newwid); - GUIControl_SetHeight(guio, newhit); + debug_script_log("SetGUIObject %d,%d size %d,%d", guio->ParentId, guio->Id, newwid, newhit); + GUIControl_SetWidth(guio, newwid); + GUIControl_SetHeight(guio, newhit); } void GUIControl_SendToBack(GUIObject *guio) { - if (guis[guio->ParentId].SendControlToBack(guio->Id)) - guis_need_update = 1; + if (guis[guio->ParentId].SendControlToBack(guio->Id)) + guis_need_update = 1; } void GUIControl_BringToFront(GUIObject *guio) { - if (guis[guio->ParentId].BringControlToFront(guio->Id)) - guis_need_update = 1; + if (guis[guio->ParentId].BringControlToFront(guio->Id)) + guis_need_update = 1; } //============================================================================= @@ -245,238 +240,208 @@ void GUIControl_BringToFront(GUIObject *guio) { #include "script/script_runtime.h" // void (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_BringToFront(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(GUIObject, GUIControl_BringToFront); +RuntimeScriptValue Sc_GUIControl_BringToFront(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(GUIObject, GUIControl_BringToFront); } // GUIObject *(int xx, int yy) -RuntimeScriptValue Sc_GetGUIControlAtLocation(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(GUIObject, ccDynamicGUIObject, GetGUIControlAtLocation); +RuntimeScriptValue Sc_GetGUIControlAtLocation(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(GUIObject, ccDynamicGUIObject, GetGUIControlAtLocation); } // void (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_SendToBack(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(GUIObject, GUIControl_SendToBack); +RuntimeScriptValue Sc_GUIControl_SendToBack(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(GUIObject, GUIControl_SendToBack); } // void (GUIObject *guio, int xx, int yy) -RuntimeScriptValue Sc_GUIControl_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(GUIObject, GUIControl_SetPosition); +RuntimeScriptValue Sc_GUIControl_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(GUIObject, GUIControl_SetPosition); } // void (GUIObject *guio, int newwid, int newhit) -RuntimeScriptValue Sc_GUIControl_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(GUIObject, GUIControl_SetSize); +RuntimeScriptValue Sc_GUIControl_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(GUIObject, GUIControl_SetSize); } // GUIButton* (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetAsButton(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIObject, GUIButton, ccDynamicGUI, GUIControl_GetAsButton); +RuntimeScriptValue Sc_GUIControl_GetAsButton(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIObject, GUIButton, ccDynamicGUI, GUIControl_GetAsButton); } // GUIInvWindow* (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetAsInvWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIObject, GUIInvWindow, ccDynamicGUI, GUIControl_GetAsInvWindow); +RuntimeScriptValue Sc_GUIControl_GetAsInvWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIObject, GUIInvWindow, ccDynamicGUI, GUIControl_GetAsInvWindow); } // GUILabel* (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetAsLabel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIObject, GUILabel, ccDynamicGUI, GUIControl_GetAsLabel); +RuntimeScriptValue Sc_GUIControl_GetAsLabel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIObject, GUILabel, ccDynamicGUI, GUIControl_GetAsLabel); } // GUIListBox* (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetAsListBox(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIObject, GUIListBox, ccDynamicGUI, GUIControl_GetAsListBox); +RuntimeScriptValue Sc_GUIControl_GetAsListBox(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIObject, GUIListBox, ccDynamicGUI, GUIControl_GetAsListBox); } // GUISlider* (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetAsSlider(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIObject, GUISlider, ccDynamicGUI, GUIControl_GetAsSlider); +RuntimeScriptValue Sc_GUIControl_GetAsSlider(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIObject, GUISlider, ccDynamicGUI, GUIControl_GetAsSlider); } // GUITextBox* (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetAsTextBox(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIObject, GUITextBox, ccDynamicGUI, GUIControl_GetAsTextBox); +RuntimeScriptValue Sc_GUIControl_GetAsTextBox(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIObject, GUITextBox, ccDynamicGUI, GUIControl_GetAsTextBox); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetClickable); +RuntimeScriptValue Sc_GUIControl_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetClickable); } // void (GUIObject *guio, int enabled) -RuntimeScriptValue Sc_GUIControl_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetClickable); +RuntimeScriptValue Sc_GUIControl_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetClickable); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetEnabled); +RuntimeScriptValue Sc_GUIControl_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetEnabled); } // void (GUIObject *guio, int enabled) -RuntimeScriptValue Sc_GUIControl_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetEnabled); +RuntimeScriptValue Sc_GUIControl_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetEnabled); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetHeight); +RuntimeScriptValue Sc_GUIControl_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetHeight); } // void (GUIObject *guio, int newhit) -RuntimeScriptValue Sc_GUIControl_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetHeight); +RuntimeScriptValue Sc_GUIControl_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetHeight); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetID); +RuntimeScriptValue Sc_GUIControl_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetID); } // ScriptGUI* (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetOwningGUI(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIObject, ScriptGUI, ccDynamicGUI, GUIControl_GetOwningGUI); +RuntimeScriptValue Sc_GUIControl_GetOwningGUI(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIObject, ScriptGUI, ccDynamicGUI, GUIControl_GetOwningGUI); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetVisible); +RuntimeScriptValue Sc_GUIControl_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetVisible); } // void (GUIObject *guio, int visible) -RuntimeScriptValue Sc_GUIControl_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetVisible); +RuntimeScriptValue Sc_GUIControl_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetVisible); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetWidth); +RuntimeScriptValue Sc_GUIControl_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetWidth); } // void (GUIObject *guio, int newwid) -RuntimeScriptValue Sc_GUIControl_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetWidth); +RuntimeScriptValue Sc_GUIControl_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetWidth); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetX); +RuntimeScriptValue Sc_GUIControl_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetX); } // void (GUIObject *guio, int xx) -RuntimeScriptValue Sc_GUIControl_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetX); +RuntimeScriptValue Sc_GUIControl_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetX); } // int (GUIObject *guio) -RuntimeScriptValue Sc_GUIControl_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetY); +RuntimeScriptValue Sc_GUIControl_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetY); } // void (GUIObject *guio, int yy) -RuntimeScriptValue Sc_GUIControl_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetY); -} - -RuntimeScriptValue Sc_GUIControl_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIObject, GUIControl_GetZOrder); -} - -RuntimeScriptValue Sc_GUIControl_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetZOrder); -} - - - -void RegisterGUIControlAPI() -{ - ccAddExternalObjectFunction("GUIControl::BringToFront^0", Sc_GUIControl_BringToFront); - ccAddExternalStaticFunction("GUIControl::GetAtScreenXY^2", Sc_GetGUIControlAtLocation); - ccAddExternalObjectFunction("GUIControl::SendToBack^0", Sc_GUIControl_SendToBack); - ccAddExternalObjectFunction("GUIControl::SetPosition^2", Sc_GUIControl_SetPosition); - ccAddExternalObjectFunction("GUIControl::SetSize^2", Sc_GUIControl_SetSize); - ccAddExternalObjectFunction("GUIControl::get_AsButton", Sc_GUIControl_GetAsButton); - ccAddExternalObjectFunction("GUIControl::get_AsInvWindow", Sc_GUIControl_GetAsInvWindow); - ccAddExternalObjectFunction("GUIControl::get_AsLabel", Sc_GUIControl_GetAsLabel); - ccAddExternalObjectFunction("GUIControl::get_AsListBox", Sc_GUIControl_GetAsListBox); - ccAddExternalObjectFunction("GUIControl::get_AsSlider", Sc_GUIControl_GetAsSlider); - ccAddExternalObjectFunction("GUIControl::get_AsTextBox", Sc_GUIControl_GetAsTextBox); - ccAddExternalObjectFunction("GUIControl::get_Clickable", Sc_GUIControl_GetClickable); - ccAddExternalObjectFunction("GUIControl::set_Clickable", Sc_GUIControl_SetClickable); - ccAddExternalObjectFunction("GUIControl::get_Enabled", Sc_GUIControl_GetEnabled); - ccAddExternalObjectFunction("GUIControl::set_Enabled", Sc_GUIControl_SetEnabled); - ccAddExternalObjectFunction("GUIControl::get_Height", Sc_GUIControl_GetHeight); - ccAddExternalObjectFunction("GUIControl::set_Height", Sc_GUIControl_SetHeight); - ccAddExternalObjectFunction("GUIControl::get_ID", Sc_GUIControl_GetID); - ccAddExternalObjectFunction("GUIControl::get_OwningGUI", Sc_GUIControl_GetOwningGUI); - ccAddExternalObjectFunction("GUIControl::get_Visible", Sc_GUIControl_GetVisible); - ccAddExternalObjectFunction("GUIControl::set_Visible", Sc_GUIControl_SetVisible); - ccAddExternalObjectFunction("GUIControl::get_Width", Sc_GUIControl_GetWidth); - ccAddExternalObjectFunction("GUIControl::set_Width", Sc_GUIControl_SetWidth); - ccAddExternalObjectFunction("GUIControl::get_X", Sc_GUIControl_GetX); - ccAddExternalObjectFunction("GUIControl::set_X", Sc_GUIControl_SetX); - ccAddExternalObjectFunction("GUIControl::get_Y", Sc_GUIControl_GetY); - ccAddExternalObjectFunction("GUIControl::set_Y", Sc_GUIControl_SetY); - ccAddExternalObjectFunction("GUIControl::get_ZOrder", Sc_GUIControl_GetZOrder); - ccAddExternalObjectFunction("GUIControl::set_ZOrder", Sc_GUIControl_SetZOrder); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("GUIControl::BringToFront^0", (void*)GUIControl_BringToFront); - ccAddExternalFunctionForPlugin("GUIControl::GetAtScreenXY^2", (void*)GetGUIControlAtLocation); - ccAddExternalFunctionForPlugin("GUIControl::SendToBack^0", (void*)GUIControl_SendToBack); - ccAddExternalFunctionForPlugin("GUIControl::SetPosition^2", (void*)GUIControl_SetPosition); - ccAddExternalFunctionForPlugin("GUIControl::SetSize^2", (void*)GUIControl_SetSize); - ccAddExternalFunctionForPlugin("GUIControl::get_AsButton", (void*)GUIControl_GetAsButton); - ccAddExternalFunctionForPlugin("GUIControl::get_AsInvWindow", (void*)GUIControl_GetAsInvWindow); - ccAddExternalFunctionForPlugin("GUIControl::get_AsLabel", (void*)GUIControl_GetAsLabel); - ccAddExternalFunctionForPlugin("GUIControl::get_AsListBox", (void*)GUIControl_GetAsListBox); - ccAddExternalFunctionForPlugin("GUIControl::get_AsSlider", (void*)GUIControl_GetAsSlider); - ccAddExternalFunctionForPlugin("GUIControl::get_AsTextBox", (void*)GUIControl_GetAsTextBox); - ccAddExternalFunctionForPlugin("GUIControl::get_Clickable", (void*)GUIControl_GetClickable); - ccAddExternalFunctionForPlugin("GUIControl::set_Clickable", (void*)GUIControl_SetClickable); - ccAddExternalFunctionForPlugin("GUIControl::get_Enabled", (void*)GUIControl_GetEnabled); - ccAddExternalFunctionForPlugin("GUIControl::set_Enabled", (void*)GUIControl_SetEnabled); - ccAddExternalFunctionForPlugin("GUIControl::get_Height", (void*)GUIControl_GetHeight); - ccAddExternalFunctionForPlugin("GUIControl::set_Height", (void*)GUIControl_SetHeight); - ccAddExternalFunctionForPlugin("GUIControl::get_ID", (void*)GUIControl_GetID); - ccAddExternalFunctionForPlugin("GUIControl::get_OwningGUI", (void*)GUIControl_GetOwningGUI); - ccAddExternalFunctionForPlugin("GUIControl::get_Visible", (void*)GUIControl_GetVisible); - ccAddExternalFunctionForPlugin("GUIControl::set_Visible", (void*)GUIControl_SetVisible); - ccAddExternalFunctionForPlugin("GUIControl::get_Width", (void*)GUIControl_GetWidth); - ccAddExternalFunctionForPlugin("GUIControl::set_Width", (void*)GUIControl_SetWidth); - ccAddExternalFunctionForPlugin("GUIControl::get_X", (void*)GUIControl_GetX); - ccAddExternalFunctionForPlugin("GUIControl::set_X", (void*)GUIControl_SetX); - ccAddExternalFunctionForPlugin("GUIControl::get_Y", (void*)GUIControl_GetY); - ccAddExternalFunctionForPlugin("GUIControl::set_Y", (void*)GUIControl_SetY); +RuntimeScriptValue Sc_GUIControl_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetY); +} + +RuntimeScriptValue Sc_GUIControl_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIObject, GUIControl_GetZOrder); +} + +RuntimeScriptValue Sc_GUIControl_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIObject, GUIControl_SetZOrder); +} + + + +void RegisterGUIControlAPI() { + ccAddExternalObjectFunction("GUIControl::BringToFront^0", Sc_GUIControl_BringToFront); + ccAddExternalStaticFunction("GUIControl::GetAtScreenXY^2", Sc_GetGUIControlAtLocation); + ccAddExternalObjectFunction("GUIControl::SendToBack^0", Sc_GUIControl_SendToBack); + ccAddExternalObjectFunction("GUIControl::SetPosition^2", Sc_GUIControl_SetPosition); + ccAddExternalObjectFunction("GUIControl::SetSize^2", Sc_GUIControl_SetSize); + ccAddExternalObjectFunction("GUIControl::get_AsButton", Sc_GUIControl_GetAsButton); + ccAddExternalObjectFunction("GUIControl::get_AsInvWindow", Sc_GUIControl_GetAsInvWindow); + ccAddExternalObjectFunction("GUIControl::get_AsLabel", Sc_GUIControl_GetAsLabel); + ccAddExternalObjectFunction("GUIControl::get_AsListBox", Sc_GUIControl_GetAsListBox); + ccAddExternalObjectFunction("GUIControl::get_AsSlider", Sc_GUIControl_GetAsSlider); + ccAddExternalObjectFunction("GUIControl::get_AsTextBox", Sc_GUIControl_GetAsTextBox); + ccAddExternalObjectFunction("GUIControl::get_Clickable", Sc_GUIControl_GetClickable); + ccAddExternalObjectFunction("GUIControl::set_Clickable", Sc_GUIControl_SetClickable); + ccAddExternalObjectFunction("GUIControl::get_Enabled", Sc_GUIControl_GetEnabled); + ccAddExternalObjectFunction("GUIControl::set_Enabled", Sc_GUIControl_SetEnabled); + ccAddExternalObjectFunction("GUIControl::get_Height", Sc_GUIControl_GetHeight); + ccAddExternalObjectFunction("GUIControl::set_Height", Sc_GUIControl_SetHeight); + ccAddExternalObjectFunction("GUIControl::get_ID", Sc_GUIControl_GetID); + ccAddExternalObjectFunction("GUIControl::get_OwningGUI", Sc_GUIControl_GetOwningGUI); + ccAddExternalObjectFunction("GUIControl::get_Visible", Sc_GUIControl_GetVisible); + ccAddExternalObjectFunction("GUIControl::set_Visible", Sc_GUIControl_SetVisible); + ccAddExternalObjectFunction("GUIControl::get_Width", Sc_GUIControl_GetWidth); + ccAddExternalObjectFunction("GUIControl::set_Width", Sc_GUIControl_SetWidth); + ccAddExternalObjectFunction("GUIControl::get_X", Sc_GUIControl_GetX); + ccAddExternalObjectFunction("GUIControl::set_X", Sc_GUIControl_SetX); + ccAddExternalObjectFunction("GUIControl::get_Y", Sc_GUIControl_GetY); + ccAddExternalObjectFunction("GUIControl::set_Y", Sc_GUIControl_SetY); + ccAddExternalObjectFunction("GUIControl::get_ZOrder", Sc_GUIControl_GetZOrder); + ccAddExternalObjectFunction("GUIControl::set_ZOrder", Sc_GUIControl_SetZOrder); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("GUIControl::BringToFront^0", (void *)GUIControl_BringToFront); + ccAddExternalFunctionForPlugin("GUIControl::GetAtScreenXY^2", (void *)GetGUIControlAtLocation); + ccAddExternalFunctionForPlugin("GUIControl::SendToBack^0", (void *)GUIControl_SendToBack); + ccAddExternalFunctionForPlugin("GUIControl::SetPosition^2", (void *)GUIControl_SetPosition); + ccAddExternalFunctionForPlugin("GUIControl::SetSize^2", (void *)GUIControl_SetSize); + ccAddExternalFunctionForPlugin("GUIControl::get_AsButton", (void *)GUIControl_GetAsButton); + ccAddExternalFunctionForPlugin("GUIControl::get_AsInvWindow", (void *)GUIControl_GetAsInvWindow); + ccAddExternalFunctionForPlugin("GUIControl::get_AsLabel", (void *)GUIControl_GetAsLabel); + ccAddExternalFunctionForPlugin("GUIControl::get_AsListBox", (void *)GUIControl_GetAsListBox); + ccAddExternalFunctionForPlugin("GUIControl::get_AsSlider", (void *)GUIControl_GetAsSlider); + ccAddExternalFunctionForPlugin("GUIControl::get_AsTextBox", (void *)GUIControl_GetAsTextBox); + ccAddExternalFunctionForPlugin("GUIControl::get_Clickable", (void *)GUIControl_GetClickable); + ccAddExternalFunctionForPlugin("GUIControl::set_Clickable", (void *)GUIControl_SetClickable); + ccAddExternalFunctionForPlugin("GUIControl::get_Enabled", (void *)GUIControl_GetEnabled); + ccAddExternalFunctionForPlugin("GUIControl::set_Enabled", (void *)GUIControl_SetEnabled); + ccAddExternalFunctionForPlugin("GUIControl::get_Height", (void *)GUIControl_GetHeight); + ccAddExternalFunctionForPlugin("GUIControl::set_Height", (void *)GUIControl_SetHeight); + ccAddExternalFunctionForPlugin("GUIControl::get_ID", (void *)GUIControl_GetID); + ccAddExternalFunctionForPlugin("GUIControl::get_OwningGUI", (void *)GUIControl_GetOwningGUI); + ccAddExternalFunctionForPlugin("GUIControl::get_Visible", (void *)GUIControl_GetVisible); + ccAddExternalFunctionForPlugin("GUIControl::set_Visible", (void *)GUIControl_SetVisible); + ccAddExternalFunctionForPlugin("GUIControl::get_Width", (void *)GUIControl_GetWidth); + ccAddExternalFunctionForPlugin("GUIControl::set_Width", (void *)GUIControl_SetWidth); + ccAddExternalFunctionForPlugin("GUIControl::get_X", (void *)GUIControl_GetX); + ccAddExternalFunctionForPlugin("GUIControl::set_X", (void *)GUIControl_SetX); + ccAddExternalFunctionForPlugin("GUIControl::get_Y", (void *)GUIControl_GetY); + ccAddExternalFunctionForPlugin("GUIControl::set_Y", (void *)GUIControl_SetY); } diff --git a/engines/ags/engine/ac/guicontrol.h b/engines/ags/engine/ac/guicontrol.h index fd2d0c2452e0..b0527ebfb5cf 100644 --- a/engines/ags/engine/ac/guicontrol.h +++ b/engines/ags/engine/ac/guicontrol.h @@ -40,34 +40,34 @@ using AGS::Common::GUIListBox; using AGS::Common::GUISlider; using AGS::Common::GUITextBox; -GUIObject *GetGUIControlAtLocation(int xx, int yy); -int GUIControl_GetVisible(GUIObject *guio); -void GUIControl_SetVisible(GUIObject *guio, int visible); -int GUIControl_GetClickable(GUIObject *guio); -void GUIControl_SetClickable(GUIObject *guio, int enabled); -int GUIControl_GetEnabled(GUIObject *guio); -void GUIControl_SetEnabled(GUIObject *guio, int enabled); -int GUIControl_GetID(GUIObject *guio); -ScriptGUI* GUIControl_GetOwningGUI(GUIObject *guio); -GUIButton* GUIControl_GetAsButton(GUIObject *guio); -GUIInvWindow* GUIControl_GetAsInvWindow(GUIObject *guio); -GUILabel* GUIControl_GetAsLabel(GUIObject *guio); -GUIListBox* GUIControl_GetAsListBox(GUIObject *guio); -GUISlider* GUIControl_GetAsSlider(GUIObject *guio); -GUITextBox* GUIControl_GetAsTextBox(GUIObject *guio); -int GUIControl_GetX(GUIObject *guio); -void GUIControl_SetX(GUIObject *guio, int xx); -int GUIControl_GetY(GUIObject *guio); -void GUIControl_SetY(GUIObject *guio, int yy); +GUIObject *GetGUIControlAtLocation(int xx, int yy); +int GUIControl_GetVisible(GUIObject *guio); +void GUIControl_SetVisible(GUIObject *guio, int visible); +int GUIControl_GetClickable(GUIObject *guio); +void GUIControl_SetClickable(GUIObject *guio, int enabled); +int GUIControl_GetEnabled(GUIObject *guio); +void GUIControl_SetEnabled(GUIObject *guio, int enabled); +int GUIControl_GetID(GUIObject *guio); +ScriptGUI *GUIControl_GetOwningGUI(GUIObject *guio); +GUIButton *GUIControl_GetAsButton(GUIObject *guio); +GUIInvWindow *GUIControl_GetAsInvWindow(GUIObject *guio); +GUILabel *GUIControl_GetAsLabel(GUIObject *guio); +GUIListBox *GUIControl_GetAsListBox(GUIObject *guio); +GUISlider *GUIControl_GetAsSlider(GUIObject *guio); +GUITextBox *GUIControl_GetAsTextBox(GUIObject *guio); +int GUIControl_GetX(GUIObject *guio); +void GUIControl_SetX(GUIObject *guio, int xx); +int GUIControl_GetY(GUIObject *guio); +void GUIControl_SetY(GUIObject *guio, int yy); int GUIControl_GetZOrder(GUIObject *guio); void GUIControl_SetZOrder(GUIObject *guio, int zorder); -void GUIControl_SetPosition(GUIObject *guio, int xx, int yy); -int GUIControl_GetWidth(GUIObject *guio); -void GUIControl_SetWidth(GUIObject *guio, int newwid); -int GUIControl_GetHeight(GUIObject *guio); -void GUIControl_SetHeight(GUIObject *guio, int newhit); -void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit); -void GUIControl_SendToBack(GUIObject *guio); -void GUIControl_BringToFront(GUIObject *guio); +void GUIControl_SetPosition(GUIObject *guio, int xx, int yy); +int GUIControl_GetWidth(GUIObject *guio); +void GUIControl_SetWidth(GUIObject *guio, int newwid); +int GUIControl_GetHeight(GUIObject *guio); +void GUIControl_SetHeight(GUIObject *guio, int newhit); +void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit); +void GUIControl_SendToBack(GUIObject *guio); +void GUIControl_BringToFront(GUIObject *guio); #endif diff --git a/engines/ags/engine/ac/guiinv.cpp b/engines/ags/engine/ac/guiinv.cpp index cb56307b1d80..7bda0b6a5acd 100644 --- a/engines/ags/engine/ac/guiinv.cpp +++ b/engines/ags/engine/ac/guiinv.cpp @@ -37,65 +37,58 @@ extern CharacterExtras *charextra; extern SpriteCache spriteset; -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -int GUIInvWindow::GetCharacterId() const -{ - if (CharId < 0) - return game.playercharacter; +int GUIInvWindow::GetCharacterId() const { + if (CharId < 0) + return game.playercharacter; - return CharId; + return CharId; } -void GUIInvWindow::Draw(Bitmap *ds) -{ - const bool enabled = IsGUIEnabled(this); - if (!enabled && (gui_disabled_style == GUIDIS_BLACKOUT)) - return; +void GUIInvWindow::Draw(Bitmap *ds) { + const bool enabled = IsGUIEnabled(this); + if (!enabled && (gui_disabled_style == GUIDIS_BLACKOUT)) + return; - // backwards compatibility - play.inv_numinline = ColCount; - play.inv_numdisp = RowCount * ColCount; - play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; - // if the user changes top_inv_item, switch into backwards - // compatibiltiy mode - if (play.inv_top) - play.inv_backwards_compatibility = 1; - if (play.inv_backwards_compatibility) - TopItem = play.inv_top; + // backwards compatibility + play.inv_numinline = ColCount; + play.inv_numdisp = RowCount * ColCount; + play.obsolete_inv_numorder = charextra[game.playercharacter].invorder_count; + // if the user changes top_inv_item, switch into backwards + // compatibiltiy mode + if (play.inv_top) + play.inv_backwards_compatibility = 1; + if (play.inv_backwards_compatibility) + TopItem = play.inv_top; - // draw the items - const int leftmost_x = X; - int at_x = X; - int at_y = Y; - int lastItem = TopItem + (ColCount * RowCount); - if (lastItem > charextra[GetCharacterId()].invorder_count) - lastItem = charextra[GetCharacterId()].invorder_count; + // draw the items + const int leftmost_x = X; + int at_x = X; + int at_y = Y; + int lastItem = TopItem + (ColCount * RowCount); + if (lastItem > charextra[GetCharacterId()].invorder_count) + lastItem = charextra[GetCharacterId()].invorder_count; - for (int item = TopItem; item < lastItem; ++item) - { - // draw inv graphic - draw_gui_sprite(ds, game.invinfo[charextra[GetCharacterId()].invorder[item]].pic, at_x, at_y, true); - at_x += data_to_game_coord(ItemWidth); + for (int item = TopItem; item < lastItem; ++item) { + // draw inv graphic + draw_gui_sprite(ds, game.invinfo[charextra[GetCharacterId()].invorder[item]].pic, at_x, at_y, true); + at_x += data_to_game_coord(ItemWidth); - // go to next row when appropriate - if ((item - TopItem) % ColCount == (ColCount - 1)) - { - at_x = leftmost_x; - at_y += data_to_game_coord(ItemHeight); - } - } + // go to next row when appropriate + if ((item - TopItem) % ColCount == (ColCount - 1)) { + at_x = leftmost_x; + at_y += data_to_game_coord(ItemHeight); + } + } - if (!enabled && - gui_disabled_style == GUIDIS_GREYOUT && - play.inventory_greys_out == 1) - { - // darken the inventory when disabled - GUI::DrawDisabledEffect(ds, RectWH(X, Y, Width, Height)); - } + if (!enabled && + gui_disabled_style == GUIDIS_GREYOUT && + play.inventory_greys_out == 1) { + // darken the inventory when disabled + GUI::DrawDisabledEffect(ds, RectWH(X, Y, Width, Height)); + } } } // namespace Common diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp index a013cbffa8c1..01c4d74bcc66 100644 --- a/engines/ags/engine/ac/hotspot.cpp +++ b/engines/ags/engine/ac/hotspot.cpp @@ -36,93 +36,88 @@ using namespace AGS::Common; extern RoomStruct thisroom; -extern RoomStatus*croom; +extern RoomStatus *croom; extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; extern CCHotspot ccDynamicHotspot; void Hotspot_SetEnabled(ScriptHotspot *hss, int newval) { - if (newval) - EnableHotspot(hss->id); - else - DisableHotspot(hss->id); + if (newval) + EnableHotspot(hss->id); + else + DisableHotspot(hss->id); } int Hotspot_GetEnabled(ScriptHotspot *hss) { - return croom->hotspot_enabled[hss->id]; + return croom->hotspot_enabled[hss->id]; } int Hotspot_GetID(ScriptHotspot *hss) { - return hss->id; + return hss->id; } int Hotspot_GetWalkToX(ScriptHotspot *hss) { - return GetHotspotPointX(hss->id); + return GetHotspotPointX(hss->id); } int Hotspot_GetWalkToY(ScriptHotspot *hss) { - return GetHotspotPointY(hss->id); + return GetHotspotPointY(hss->id); } ScriptHotspot *GetHotspotAtScreen(int xx, int yy) { - return &scrHotspot[GetHotspotIDAtScreen(xx, yy)]; + return &scrHotspot[GetHotspotIDAtScreen(xx, yy)]; } ScriptHotspot *GetHotspotAtRoom(int x, int y) { - return &scrHotspot[get_hotspot_at(x, y)]; + return &scrHotspot[get_hotspot_at(x, y)]; } void Hotspot_GetName(ScriptHotspot *hss, char *buffer) { - GetHotspotName(hss->id, buffer); + GetHotspotName(hss->id, buffer); } -const char* Hotspot_GetName_New(ScriptHotspot *hss) { - return CreateNewScriptString(get_translation(thisroom.Hotspots[hss->id].Name)); +const char *Hotspot_GetName_New(ScriptHotspot *hss) { + return CreateNewScriptString(get_translation(thisroom.Hotspots[hss->id].Name)); } bool Hotspot_IsInteractionAvailable(ScriptHotspot *hhot, int mood) { - play.check_interaction_only = 1; - RunHotspotInteraction(hhot->id, mood); - int ciwas = play.check_interaction_only; - play.check_interaction_only = 0; - return (ciwas == 2); + play.check_interaction_only = 1; + RunHotspotInteraction(hhot->id, mood); + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + return (ciwas == 2); } -void Hotspot_RunInteraction (ScriptHotspot *hss, int mood) { - RunHotspotInteraction(hss->id, mood); +void Hotspot_RunInteraction(ScriptHotspot *hss, int mood) { + RunHotspotInteraction(hss->id, mood); } -int Hotspot_GetProperty (ScriptHotspot *hss, const char *property) -{ - return get_int_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property); +int Hotspot_GetProperty(ScriptHotspot *hss, const char *property) { + return get_int_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property); } -void Hotspot_GetPropertyText (ScriptHotspot *hss, const char *property, char *bufer) -{ - get_text_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property, bufer); +void Hotspot_GetPropertyText(ScriptHotspot *hss, const char *property, char *bufer) { + get_text_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property, bufer); } -const char* Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property) -{ - return get_text_property_dynamic_string(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property); +const char *Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property) { + return get_text_property_dynamic_string(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property); } -bool Hotspot_SetProperty(ScriptHotspot *hss, const char *property, int value) -{ - return set_int_property(croom->hsProps[hss->id], property, value); +bool Hotspot_SetProperty(ScriptHotspot *hss, const char *property, int value) { + return set_int_property(croom->hsProps[hss->id], property, value); } -bool Hotspot_SetTextProperty(ScriptHotspot *hss, const char *property, const char *value) -{ - return set_text_property(croom->hsProps[hss->id], property, value); +bool Hotspot_SetTextProperty(ScriptHotspot *hss, const char *property, const char *value) { + return set_text_property(croom->hsProps[hss->id], property, value); } -int get_hotspot_at(int xpp,int ypp) { - int onhs=thisroom.HotspotMask->GetPixel(room_to_mask_coord(xpp), room_to_mask_coord(ypp)); - if (onhs <= 0 || onhs >= MAX_ROOM_HOTSPOTS) return 0; - if (croom->hotspot_enabled[onhs]==0) return 0; - return onhs; +int get_hotspot_at(int xpp, int ypp) { + int onhs = thisroom.HotspotMask->GetPixel(room_to_mask_coord(xpp), room_to_mask_coord(ypp)); + if (onhs <= 0 || onhs >= MAX_ROOM_HOTSPOTS) return 0; + if (croom->hotspot_enabled[onhs] == 0) return 0; + return onhs; } //============================================================================= @@ -138,139 +133,121 @@ int get_hotspot_at(int xpp,int ypp) { extern ScriptString myScriptStringImpl; -RuntimeScriptValue Sc_GetHotspotAtRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtRoom); +RuntimeScriptValue Sc_GetHotspotAtRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtRoom); } // ScriptHotspot *(int xx, int yy) -RuntimeScriptValue Sc_GetHotspotAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtScreen); +RuntimeScriptValue Sc_GetHotspotAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtScreen); } -RuntimeScriptValue Sc_Hotspot_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) -{ - ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaHotspot); - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +RuntimeScriptValue Sc_Hotspot_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) { + ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaHotspot); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); } // void (ScriptHotspot *hss, char *buffer) -RuntimeScriptValue Sc_Hotspot_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(ScriptHotspot, Hotspot_GetName, char); +RuntimeScriptValue Sc_Hotspot_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(ScriptHotspot, Hotspot_GetName, char); } // int (ScriptHotspot *hss, const char *property) -RuntimeScriptValue Sc_Hotspot_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(ScriptHotspot, Hotspot_GetProperty, const char); +RuntimeScriptValue Sc_Hotspot_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(ScriptHotspot, Hotspot_GetProperty, const char); } // void (ScriptHotspot *hss, const char *property, char *bufer) -RuntimeScriptValue Sc_Hotspot_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ2(ScriptHotspot, Hotspot_GetPropertyText, const char, char); +RuntimeScriptValue Sc_Hotspot_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ2(ScriptHotspot, Hotspot_GetPropertyText, const char, char); } // const char* (ScriptHotspot *hss, const char *property) -RuntimeScriptValue Sc_Hotspot_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_POBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetTextProperty, const char); +RuntimeScriptValue Sc_Hotspot_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_POBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetTextProperty, const char); } -RuntimeScriptValue Sc_Hotspot_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ_PINT(ScriptHotspot, Hotspot_SetProperty, const char); +RuntimeScriptValue Sc_Hotspot_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ_PINT(ScriptHotspot, Hotspot_SetProperty, const char); } -RuntimeScriptValue Sc_Hotspot_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ2(ScriptHotspot, Hotspot_SetTextProperty, const char, const char); +RuntimeScriptValue Sc_Hotspot_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ2(ScriptHotspot, Hotspot_SetTextProperty, const char, const char); } -RuntimeScriptValue Sc_Hotspot_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_PINT(ScriptHotspot, Hotspot_IsInteractionAvailable); +RuntimeScriptValue Sc_Hotspot_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_PINT(ScriptHotspot, Hotspot_IsInteractionAvailable); } // void (ScriptHotspot *hss, int mood) -RuntimeScriptValue Sc_Hotspot_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptHotspot, Hotspot_RunInteraction); +RuntimeScriptValue Sc_Hotspot_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptHotspot, Hotspot_RunInteraction); } // int (ScriptHotspot *hss) -RuntimeScriptValue Sc_Hotspot_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptHotspot, Hotspot_GetEnabled); +RuntimeScriptValue Sc_Hotspot_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetEnabled); } // void (ScriptHotspot *hss, int newval) -RuntimeScriptValue Sc_Hotspot_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptHotspot, Hotspot_SetEnabled); +RuntimeScriptValue Sc_Hotspot_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptHotspot, Hotspot_SetEnabled); } // int (ScriptHotspot *hss) -RuntimeScriptValue Sc_Hotspot_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptHotspot, Hotspot_GetID); +RuntimeScriptValue Sc_Hotspot_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetID); } // const char* (ScriptHotspot *hss) -RuntimeScriptValue Sc_Hotspot_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetName_New); +RuntimeScriptValue Sc_Hotspot_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetName_New); } // int (ScriptHotspot *hss) -RuntimeScriptValue Sc_Hotspot_GetWalkToX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptHotspot, Hotspot_GetWalkToX); +RuntimeScriptValue Sc_Hotspot_GetWalkToX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetWalkToX); } // int (ScriptHotspot *hss) -RuntimeScriptValue Sc_Hotspot_GetWalkToY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptHotspot, Hotspot_GetWalkToY); -} - - - -void RegisterHotspotAPI() -{ - ccAddExternalStaticFunction("Hotspot::GetAtRoomXY^2", Sc_GetHotspotAtRoom); - ccAddExternalStaticFunction("Hotspot::GetAtScreenXY^2", Sc_GetHotspotAtScreen); - ccAddExternalStaticFunction("Hotspot::GetDrawingSurface", Sc_Hotspot_GetDrawingSurface); - ccAddExternalObjectFunction("Hotspot::GetName^1", Sc_Hotspot_GetName); - ccAddExternalObjectFunction("Hotspot::GetProperty^1", Sc_Hotspot_GetProperty); - ccAddExternalObjectFunction("Hotspot::GetPropertyText^2", Sc_Hotspot_GetPropertyText); - ccAddExternalObjectFunction("Hotspot::GetTextProperty^1", Sc_Hotspot_GetTextProperty); - ccAddExternalObjectFunction("Hotspot::SetProperty^2", Sc_Hotspot_SetProperty); - ccAddExternalObjectFunction("Hotspot::SetTextProperty^2", Sc_Hotspot_SetTextProperty); - ccAddExternalObjectFunction("Hotspot::IsInteractionAvailable^1", Sc_Hotspot_IsInteractionAvailable); - ccAddExternalObjectFunction("Hotspot::RunInteraction^1", Sc_Hotspot_RunInteraction); - ccAddExternalObjectFunction("Hotspot::get_Enabled", Sc_Hotspot_GetEnabled); - ccAddExternalObjectFunction("Hotspot::set_Enabled", Sc_Hotspot_SetEnabled); - ccAddExternalObjectFunction("Hotspot::get_ID", Sc_Hotspot_GetID); - ccAddExternalObjectFunction("Hotspot::get_Name", Sc_Hotspot_GetName_New); - ccAddExternalObjectFunction("Hotspot::get_WalkToX", Sc_Hotspot_GetWalkToX); - ccAddExternalObjectFunction("Hotspot::get_WalkToY", Sc_Hotspot_GetWalkToY); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Hotspot::GetAtRoomXY^2", (void*)GetHotspotAtRoom); - ccAddExternalFunctionForPlugin("Hotspot::GetAtScreenXY^2", (void*)GetHotspotAtScreen); - ccAddExternalFunctionForPlugin("Hotspot::GetName^1", (void*)Hotspot_GetName); - ccAddExternalFunctionForPlugin("Hotspot::GetProperty^1", (void*)Hotspot_GetProperty); - ccAddExternalFunctionForPlugin("Hotspot::GetPropertyText^2", (void*)Hotspot_GetPropertyText); - ccAddExternalFunctionForPlugin("Hotspot::GetTextProperty^1", (void*)Hotspot_GetTextProperty); - ccAddExternalFunctionForPlugin("Hotspot::RunInteraction^1", (void*)Hotspot_RunInteraction); - ccAddExternalFunctionForPlugin("Hotspot::get_Enabled", (void*)Hotspot_GetEnabled); - ccAddExternalFunctionForPlugin("Hotspot::set_Enabled", (void*)Hotspot_SetEnabled); - ccAddExternalFunctionForPlugin("Hotspot::get_ID", (void*)Hotspot_GetID); - ccAddExternalFunctionForPlugin("Hotspot::get_Name", (void*)Hotspot_GetName_New); - ccAddExternalFunctionForPlugin("Hotspot::get_WalkToX", (void*)Hotspot_GetWalkToX); - ccAddExternalFunctionForPlugin("Hotspot::get_WalkToY", (void*)Hotspot_GetWalkToY); +RuntimeScriptValue Sc_Hotspot_GetWalkToY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptHotspot, Hotspot_GetWalkToY); +} + + + +void RegisterHotspotAPI() { + ccAddExternalStaticFunction("Hotspot::GetAtRoomXY^2", Sc_GetHotspotAtRoom); + ccAddExternalStaticFunction("Hotspot::GetAtScreenXY^2", Sc_GetHotspotAtScreen); + ccAddExternalStaticFunction("Hotspot::GetDrawingSurface", Sc_Hotspot_GetDrawingSurface); + ccAddExternalObjectFunction("Hotspot::GetName^1", Sc_Hotspot_GetName); + ccAddExternalObjectFunction("Hotspot::GetProperty^1", Sc_Hotspot_GetProperty); + ccAddExternalObjectFunction("Hotspot::GetPropertyText^2", Sc_Hotspot_GetPropertyText); + ccAddExternalObjectFunction("Hotspot::GetTextProperty^1", Sc_Hotspot_GetTextProperty); + ccAddExternalObjectFunction("Hotspot::SetProperty^2", Sc_Hotspot_SetProperty); + ccAddExternalObjectFunction("Hotspot::SetTextProperty^2", Sc_Hotspot_SetTextProperty); + ccAddExternalObjectFunction("Hotspot::IsInteractionAvailable^1", Sc_Hotspot_IsInteractionAvailable); + ccAddExternalObjectFunction("Hotspot::RunInteraction^1", Sc_Hotspot_RunInteraction); + ccAddExternalObjectFunction("Hotspot::get_Enabled", Sc_Hotspot_GetEnabled); + ccAddExternalObjectFunction("Hotspot::set_Enabled", Sc_Hotspot_SetEnabled); + ccAddExternalObjectFunction("Hotspot::get_ID", Sc_Hotspot_GetID); + ccAddExternalObjectFunction("Hotspot::get_Name", Sc_Hotspot_GetName_New); + ccAddExternalObjectFunction("Hotspot::get_WalkToX", Sc_Hotspot_GetWalkToX); + ccAddExternalObjectFunction("Hotspot::get_WalkToY", Sc_Hotspot_GetWalkToY); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Hotspot::GetAtRoomXY^2", (void *)GetHotspotAtRoom); + ccAddExternalFunctionForPlugin("Hotspot::GetAtScreenXY^2", (void *)GetHotspotAtScreen); + ccAddExternalFunctionForPlugin("Hotspot::GetName^1", (void *)Hotspot_GetName); + ccAddExternalFunctionForPlugin("Hotspot::GetProperty^1", (void *)Hotspot_GetProperty); + ccAddExternalFunctionForPlugin("Hotspot::GetPropertyText^2", (void *)Hotspot_GetPropertyText); + ccAddExternalFunctionForPlugin("Hotspot::GetTextProperty^1", (void *)Hotspot_GetTextProperty); + ccAddExternalFunctionForPlugin("Hotspot::RunInteraction^1", (void *)Hotspot_RunInteraction); + ccAddExternalFunctionForPlugin("Hotspot::get_Enabled", (void *)Hotspot_GetEnabled); + ccAddExternalFunctionForPlugin("Hotspot::set_Enabled", (void *)Hotspot_SetEnabled); + ccAddExternalFunctionForPlugin("Hotspot::get_ID", (void *)Hotspot_GetID); + ccAddExternalFunctionForPlugin("Hotspot::get_Name", (void *)Hotspot_GetName_New); + ccAddExternalFunctionForPlugin("Hotspot::get_WalkToX", (void *)Hotspot_GetWalkToX); + ccAddExternalFunctionForPlugin("Hotspot::get_WalkToY", (void *)Hotspot_GetWalkToY); } diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h index e1c7804b27ff..226ab4ef6d78 100644 --- a/engines/ags/engine/ac/hotspot.h +++ b/engines/ags/engine/ac/hotspot.h @@ -32,16 +32,16 @@ ScriptHotspot *GetHotspotAtScreen(int xx, int yy); int Hotspot_GetWalkToX(ScriptHotspot *hss);; int Hotspot_GetWalkToY(ScriptHotspot *hss); void Hotspot_GetName(ScriptHotspot *hss, char *buffer); -const char* Hotspot_GetName_New(ScriptHotspot *hss); +const char *Hotspot_GetName_New(ScriptHotspot *hss); bool Hotspot_IsInteractionAvailable(ScriptHotspot *hhot, int mood); -void Hotspot_RunInteraction (ScriptHotspot *hss, int mood); +void Hotspot_RunInteraction(ScriptHotspot *hss, int mood); -int Hotspot_GetProperty (ScriptHotspot *hss, const char *property); -void Hotspot_GetPropertyText (ScriptHotspot *hss, const char *property, char *bufer); -const char* Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property); +int Hotspot_GetProperty(ScriptHotspot *hss, const char *property); +void Hotspot_GetPropertyText(ScriptHotspot *hss, const char *property, char *bufer); +const char *Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property); // Gets hotspot ID at the given room coordinates; // if hotspot is disabled or non-existing, returns 0 (no area) -int get_hotspot_at(int xpp,int ypp); +int get_hotspot_at(int xpp, int ypp); #endif diff --git a/engines/ags/engine/ac/interfacebutton.cpp b/engines/ags/engine/ac/interfacebutton.cpp index 080f85296a5e..d10d90c8d44f 100644 --- a/engines/ags/engine/ac/interfacebutton.cpp +++ b/engines/ags/engine/ac/interfacebutton.cpp @@ -23,7 +23,13 @@ #include "ac/interfacebutton.h" void InterfaceButton::set(int xx, int yy, int picc, int overpicc, int actionn) { - x = xx; y = yy; pic = picc; overpic = overpicc; leftclick = actionn; pushpic = 0; - rightclick = 0; flags = IBFLG_ENABLED; - reserved_for_future = 0; + x = xx; + y = yy; + pic = picc; + overpic = overpicc; + leftclick = actionn; + pushpic = 0; + rightclick = 0; + flags = IBFLG_ENABLED; + reserved_for_future = 0; } diff --git a/engines/ags/engine/ac/interfaceelement.cpp b/engines/ags/engine/ac/interfaceelement.cpp index 229b9e05d71e..154ce79e57a1 100644 --- a/engines/ags/engine/ac/interfaceelement.cpp +++ b/engines/ags/engine/ac/interfaceelement.cpp @@ -24,6 +24,13 @@ #include "ac/interfaceelement.h" InterfaceElement::InterfaceElement() { - vtextxp = 0; vtextyp = 1; strcpy(vtext,"@SCORETEXT@$r@GAMENAME@"); - numbuttons = 0; bgcol = 8; fgcol = 15; bordercol = 0; on = 1; flags = 0; + vtextxp = 0; + vtextyp = 1; + strcpy(vtext, "@SCORETEXT@$r@GAMENAME@"); + numbuttons = 0; + bgcol = 8; + fgcol = 15; + bordercol = 0; + on = 1; + flags = 0; } diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp index 9eb8ff499d9d..a32161f16b48 100644 --- a/engines/ags/engine/ac/inventoryitem.cpp +++ b/engines/ags/engine/ac/inventoryitem.cpp @@ -37,92 +37,86 @@ extern GameSetupStruct game; extern ScriptInvItem scrInv[MAX_INV]; extern int cur_cursor; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern CCInventory ccDynamicInv; -void InventoryItem_SetCursorGraphic(ScriptInvItem *iitem, int newSprite) -{ - set_inv_item_cursorpic(iitem->id, newSprite); +void InventoryItem_SetCursorGraphic(ScriptInvItem *iitem, int newSprite) { + set_inv_item_cursorpic(iitem->id, newSprite); } -int InventoryItem_GetCursorGraphic(ScriptInvItem *iitem) -{ - return game.invinfo[iitem->id].cursorPic; +int InventoryItem_GetCursorGraphic(ScriptInvItem *iitem) { + return game.invinfo[iitem->id].cursorPic; } void InventoryItem_SetGraphic(ScriptInvItem *iitem, int piccy) { - set_inv_item_pic(iitem->id, piccy); + set_inv_item_pic(iitem->id, piccy); } void InventoryItem_SetName(ScriptInvItem *scii, const char *newname) { - SetInvItemName(scii->id, newname); + SetInvItemName(scii->id, newname); } int InventoryItem_GetID(ScriptInvItem *scii) { - return scii->id; + return scii->id; } ScriptInvItem *GetInvAtLocation(int xx, int yy) { - int hsnum = GetInvAt(xx, yy); - if (hsnum <= 0) - return nullptr; - return &scrInv[hsnum]; + int hsnum = GetInvAt(xx, yy); + if (hsnum <= 0) + return nullptr; + return &scrInv[hsnum]; } void InventoryItem_GetName(ScriptInvItem *iitem, char *buff) { - GetInvName(iitem->id, buff); + GetInvName(iitem->id, buff); } -const char* InventoryItem_GetName_New(ScriptInvItem *invitem) { - return CreateNewScriptString(get_translation(game.invinfo[invitem->id].name)); +const char *InventoryItem_GetName_New(ScriptInvItem *invitem) { + return CreateNewScriptString(get_translation(game.invinfo[invitem->id].name)); } int InventoryItem_GetGraphic(ScriptInvItem *iitem) { - return game.invinfo[iitem->id].pic; + return game.invinfo[iitem->id].pic; } void InventoryItem_RunInteraction(ScriptInvItem *iitem, int mood) { - RunInventoryInteraction(iitem->id, mood); + RunInventoryInteraction(iitem->id, mood); } int InventoryItem_CheckInteractionAvailable(ScriptInvItem *iitem, int mood) { - return IsInventoryInteractionAvailable(iitem->id, mood); + return IsInventoryInteractionAvailable(iitem->id, mood); } int InventoryItem_GetProperty(ScriptInvItem *scii, const char *property) { - return get_int_property (game.invProps[scii->id], play.invProps[scii->id], property); + return get_int_property(game.invProps[scii->id], play.invProps[scii->id], property); } void InventoryItem_GetPropertyText(ScriptInvItem *scii, const char *property, char *bufer) { - get_text_property(game.invProps[scii->id], play.invProps[scii->id], property, bufer); + get_text_property(game.invProps[scii->id], play.invProps[scii->id], property, bufer); } -const char* InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *property) { - return get_text_property_dynamic_string(game.invProps[scii->id], play.invProps[scii->id], property); +const char *InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *property) { + return get_text_property_dynamic_string(game.invProps[scii->id], play.invProps[scii->id], property); } -bool InventoryItem_SetProperty(ScriptInvItem *scii, const char *property, int value) -{ - return set_int_property(play.invProps[scii->id], property, value); +bool InventoryItem_SetProperty(ScriptInvItem *scii, const char *property, int value) { + return set_int_property(play.invProps[scii->id], property, value); } -bool InventoryItem_SetTextProperty(ScriptInvItem *scii, const char *property, const char *value) -{ - return set_text_property(play.invProps[scii->id], property, value); +bool InventoryItem_SetTextProperty(ScriptInvItem *scii, const char *property, const char *value) { + return set_text_property(play.invProps[scii->id], property, value); } //============================================================================= -void set_inv_item_cursorpic(int invItemId, int piccy) -{ - game.invinfo[invItemId].cursorPic = piccy; +void set_inv_item_cursorpic(int invItemId, int piccy) { + game.invinfo[invItemId].cursorPic = piccy; - if ((cur_cursor == MODE_USE) && (playerchar->activeinv == invItemId)) - { - update_inv_cursor(invItemId); - set_mouse_cursor(cur_cursor); - } + if ((cur_cursor == MODE_USE) && (playerchar->activeinv == invItemId)) { + update_inv_cursor(invItemId); + set_mouse_cursor(cur_cursor); + } } //============================================================================= @@ -139,136 +133,119 @@ void set_inv_item_cursorpic(int invItemId, int piccy) extern ScriptString myScriptStringImpl; // ScriptInvItem *(int xx, int yy) -RuntimeScriptValue Sc_GetInvAtLocation(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptInvItem, ccDynamicInv, GetInvAtLocation); +RuntimeScriptValue Sc_GetInvAtLocation(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptInvItem, ccDynamicInv, GetInvAtLocation); } // int (ScriptInvItem *iitem, int mood) -RuntimeScriptValue Sc_InventoryItem_CheckInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(ScriptInvItem, InventoryItem_CheckInteractionAvailable); +RuntimeScriptValue Sc_InventoryItem_CheckInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(ScriptInvItem, InventoryItem_CheckInteractionAvailable); } // void (ScriptInvItem *iitem, char *buff) -RuntimeScriptValue Sc_InventoryItem_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(ScriptInvItem, InventoryItem_GetName, char); +RuntimeScriptValue Sc_InventoryItem_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(ScriptInvItem, InventoryItem_GetName, char); } // int (ScriptInvItem *scii, const char *property) -RuntimeScriptValue Sc_InventoryItem_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(ScriptInvItem, InventoryItem_GetProperty, const char); +RuntimeScriptValue Sc_InventoryItem_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(ScriptInvItem, InventoryItem_GetProperty, const char); } // void (ScriptInvItem *scii, const char *property, char *bufer) -RuntimeScriptValue Sc_InventoryItem_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ2(ScriptInvItem, InventoryItem_GetPropertyText, const char, char); +RuntimeScriptValue Sc_InventoryItem_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ2(ScriptInvItem, InventoryItem_GetPropertyText, const char, char); } // const char* (ScriptInvItem *scii, const char *property) -RuntimeScriptValue Sc_InventoryItem_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_POBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetTextProperty, const char); +RuntimeScriptValue Sc_InventoryItem_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_POBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetTextProperty, const char); } -RuntimeScriptValue Sc_InventoryItem_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ_PINT(ScriptInvItem, InventoryItem_SetProperty, const char); +RuntimeScriptValue Sc_InventoryItem_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ_PINT(ScriptInvItem, InventoryItem_SetProperty, const char); } -RuntimeScriptValue Sc_InventoryItem_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ2(ScriptInvItem, InventoryItem_SetTextProperty, const char, const char); +RuntimeScriptValue Sc_InventoryItem_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ2(ScriptInvItem, InventoryItem_SetTextProperty, const char, const char); } // void (ScriptInvItem *iitem, int mood) -RuntimeScriptValue Sc_InventoryItem_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_RunInteraction); +RuntimeScriptValue Sc_InventoryItem_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_RunInteraction); } // void (ScriptInvItem *scii, const char *newname) -RuntimeScriptValue Sc_InventoryItem_SetName(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(ScriptInvItem, InventoryItem_SetName, const char); +RuntimeScriptValue Sc_InventoryItem_SetName(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(ScriptInvItem, InventoryItem_SetName, const char); } -// int (ScriptInvItem *iitem) -RuntimeScriptValue Sc_InventoryItem_GetCursorGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetCursorGraphic); +// int (ScriptInvItem *iitem) +RuntimeScriptValue Sc_InventoryItem_GetCursorGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetCursorGraphic); } -// void (ScriptInvItem *iitem, int newSprite) -RuntimeScriptValue Sc_InventoryItem_SetCursorGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_SetCursorGraphic); +// void (ScriptInvItem *iitem, int newSprite) +RuntimeScriptValue Sc_InventoryItem_SetCursorGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_SetCursorGraphic); } // int (ScriptInvItem *iitem) -RuntimeScriptValue Sc_InventoryItem_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetGraphic); +RuntimeScriptValue Sc_InventoryItem_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetGraphic); } // void (ScriptInvItem *iitem, int piccy) -RuntimeScriptValue Sc_InventoryItem_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_SetGraphic); +RuntimeScriptValue Sc_InventoryItem_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptInvItem, InventoryItem_SetGraphic); } // int (ScriptInvItem *scii) -RuntimeScriptValue Sc_InventoryItem_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetID); +RuntimeScriptValue Sc_InventoryItem_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptInvItem, InventoryItem_GetID); } // const char* (ScriptInvItem *invitem) -RuntimeScriptValue Sc_InventoryItem_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetName_New); -} - - - -void RegisterInventoryItemAPI() -{ - ccAddExternalStaticFunction("InventoryItem::GetAtScreenXY^2", Sc_GetInvAtLocation); - ccAddExternalObjectFunction("InventoryItem::IsInteractionAvailable^1", Sc_InventoryItem_CheckInteractionAvailable); - ccAddExternalObjectFunction("InventoryItem::GetName^1", Sc_InventoryItem_GetName); - ccAddExternalObjectFunction("InventoryItem::GetProperty^1", Sc_InventoryItem_GetProperty); - ccAddExternalObjectFunction("InventoryItem::GetPropertyText^2", Sc_InventoryItem_GetPropertyText); - ccAddExternalObjectFunction("InventoryItem::GetTextProperty^1", Sc_InventoryItem_GetTextProperty); - ccAddExternalObjectFunction("InventoryItem::SetProperty^2", Sc_InventoryItem_SetProperty); - ccAddExternalObjectFunction("InventoryItem::SetTextProperty^2", Sc_InventoryItem_SetTextProperty); - ccAddExternalObjectFunction("InventoryItem::RunInteraction^1", Sc_InventoryItem_RunInteraction); - ccAddExternalObjectFunction("InventoryItem::SetName^1", Sc_InventoryItem_SetName); - ccAddExternalObjectFunction("InventoryItem::get_CursorGraphic", Sc_InventoryItem_GetCursorGraphic); - ccAddExternalObjectFunction("InventoryItem::set_CursorGraphic", Sc_InventoryItem_SetCursorGraphic); - ccAddExternalObjectFunction("InventoryItem::get_Graphic", Sc_InventoryItem_GetGraphic); - ccAddExternalObjectFunction("InventoryItem::set_Graphic", Sc_InventoryItem_SetGraphic); - ccAddExternalObjectFunction("InventoryItem::get_ID", Sc_InventoryItem_GetID); - ccAddExternalObjectFunction("InventoryItem::get_Name", Sc_InventoryItem_GetName_New); - ccAddExternalObjectFunction("InventoryItem::set_Name", Sc_InventoryItem_SetName); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("InventoryItem::GetAtScreenXY^2", (void*)GetInvAtLocation); - ccAddExternalFunctionForPlugin("InventoryItem::IsInteractionAvailable^1", (void*)InventoryItem_CheckInteractionAvailable); - ccAddExternalFunctionForPlugin("InventoryItem::GetName^1", (void*)InventoryItem_GetName); - ccAddExternalFunctionForPlugin("InventoryItem::GetProperty^1", (void*)InventoryItem_GetProperty); - ccAddExternalFunctionForPlugin("InventoryItem::GetPropertyText^2", (void*)InventoryItem_GetPropertyText); - ccAddExternalFunctionForPlugin("InventoryItem::GetTextProperty^1", (void*)InventoryItem_GetTextProperty); - ccAddExternalFunctionForPlugin("InventoryItem::RunInteraction^1", (void*)InventoryItem_RunInteraction); - ccAddExternalFunctionForPlugin("InventoryItem::SetName^1", (void*)InventoryItem_SetName); - ccAddExternalFunctionForPlugin("InventoryItem::get_CursorGraphic", (void*)InventoryItem_GetCursorGraphic); - ccAddExternalFunctionForPlugin("InventoryItem::set_CursorGraphic", (void*)InventoryItem_SetCursorGraphic); - ccAddExternalFunctionForPlugin("InventoryItem::get_Graphic", (void*)InventoryItem_GetGraphic); - ccAddExternalFunctionForPlugin("InventoryItem::set_Graphic", (void*)InventoryItem_SetGraphic); - ccAddExternalFunctionForPlugin("InventoryItem::get_ID", (void*)InventoryItem_GetID); - ccAddExternalFunctionForPlugin("InventoryItem::get_Name", (void*)InventoryItem_GetName_New); - ccAddExternalFunctionForPlugin("InventoryItem::set_Name", (void*)InventoryItem_SetName); +RuntimeScriptValue Sc_InventoryItem_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetName_New); +} + + + +void RegisterInventoryItemAPI() { + ccAddExternalStaticFunction("InventoryItem::GetAtScreenXY^2", Sc_GetInvAtLocation); + ccAddExternalObjectFunction("InventoryItem::IsInteractionAvailable^1", Sc_InventoryItem_CheckInteractionAvailable); + ccAddExternalObjectFunction("InventoryItem::GetName^1", Sc_InventoryItem_GetName); + ccAddExternalObjectFunction("InventoryItem::GetProperty^1", Sc_InventoryItem_GetProperty); + ccAddExternalObjectFunction("InventoryItem::GetPropertyText^2", Sc_InventoryItem_GetPropertyText); + ccAddExternalObjectFunction("InventoryItem::GetTextProperty^1", Sc_InventoryItem_GetTextProperty); + ccAddExternalObjectFunction("InventoryItem::SetProperty^2", Sc_InventoryItem_SetProperty); + ccAddExternalObjectFunction("InventoryItem::SetTextProperty^2", Sc_InventoryItem_SetTextProperty); + ccAddExternalObjectFunction("InventoryItem::RunInteraction^1", Sc_InventoryItem_RunInteraction); + ccAddExternalObjectFunction("InventoryItem::SetName^1", Sc_InventoryItem_SetName); + ccAddExternalObjectFunction("InventoryItem::get_CursorGraphic", Sc_InventoryItem_GetCursorGraphic); + ccAddExternalObjectFunction("InventoryItem::set_CursorGraphic", Sc_InventoryItem_SetCursorGraphic); + ccAddExternalObjectFunction("InventoryItem::get_Graphic", Sc_InventoryItem_GetGraphic); + ccAddExternalObjectFunction("InventoryItem::set_Graphic", Sc_InventoryItem_SetGraphic); + ccAddExternalObjectFunction("InventoryItem::get_ID", Sc_InventoryItem_GetID); + ccAddExternalObjectFunction("InventoryItem::get_Name", Sc_InventoryItem_GetName_New); + ccAddExternalObjectFunction("InventoryItem::set_Name", Sc_InventoryItem_SetName); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("InventoryItem::GetAtScreenXY^2", (void *)GetInvAtLocation); + ccAddExternalFunctionForPlugin("InventoryItem::IsInteractionAvailable^1", (void *)InventoryItem_CheckInteractionAvailable); + ccAddExternalFunctionForPlugin("InventoryItem::GetName^1", (void *)InventoryItem_GetName); + ccAddExternalFunctionForPlugin("InventoryItem::GetProperty^1", (void *)InventoryItem_GetProperty); + ccAddExternalFunctionForPlugin("InventoryItem::GetPropertyText^2", (void *)InventoryItem_GetPropertyText); + ccAddExternalFunctionForPlugin("InventoryItem::GetTextProperty^1", (void *)InventoryItem_GetTextProperty); + ccAddExternalFunctionForPlugin("InventoryItem::RunInteraction^1", (void *)InventoryItem_RunInteraction); + ccAddExternalFunctionForPlugin("InventoryItem::SetName^1", (void *)InventoryItem_SetName); + ccAddExternalFunctionForPlugin("InventoryItem::get_CursorGraphic", (void *)InventoryItem_GetCursorGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::set_CursorGraphic", (void *)InventoryItem_SetCursorGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::get_Graphic", (void *)InventoryItem_GetGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::set_Graphic", (void *)InventoryItem_SetGraphic); + ccAddExternalFunctionForPlugin("InventoryItem::get_ID", (void *)InventoryItem_GetID); + ccAddExternalFunctionForPlugin("InventoryItem::get_Name", (void *)InventoryItem_GetName_New); + ccAddExternalFunctionForPlugin("InventoryItem::set_Name", (void *)InventoryItem_SetName); } diff --git a/engines/ags/engine/ac/inventoryitem.h b/engines/ags/engine/ac/inventoryitem.h index 1fedcabd5a05..6159b1e9ddea 100644 --- a/engines/ags/engine/ac/inventoryitem.h +++ b/engines/ags/engine/ac/inventoryitem.h @@ -32,13 +32,13 @@ void InventoryItem_SetName(ScriptInvItem *scii, const char *newname); int InventoryItem_GetID(ScriptInvItem *scii); ScriptInvItem *GetInvAtLocation(int xx, int yy); void InventoryItem_GetName(ScriptInvItem *iitem, char *buff); -const char* InventoryItem_GetName_New(ScriptInvItem *invitem); +const char *InventoryItem_GetName_New(ScriptInvItem *invitem); int InventoryItem_GetGraphic(ScriptInvItem *iitem); void InventoryItem_RunInteraction(ScriptInvItem *iitem, int mood); int InventoryItem_CheckInteractionAvailable(ScriptInvItem *iitem, int mood); int InventoryItem_GetProperty(ScriptInvItem *scii, const char *property); void InventoryItem_GetPropertyText(ScriptInvItem *scii, const char *property, char *bufer); -const char* InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *property); +const char *InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *property); void set_inv_item_cursorpic(int invItemId, int piccy); diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp index cb124cf406f5..eafc35680f48 100644 --- a/engines/ags/engine/ac/invwindow.cpp +++ b/engines/ags/engine/ac/invwindow.cpp @@ -51,11 +51,11 @@ extern GameSetupStruct game; extern GameState play; extern CharacterExtras *charextra; extern ScriptInvItem scrInv[MAX_INV]; -extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; +extern int mouse_ifacebut_xoffs, mouse_ifacebut_yoffs; extern SpriteCache spriteset; -extern int mousex,mousey; +extern int mousex, mousey; extern int evblocknum; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern AGSPlatformDriver *platform; extern CCCharacter ccDynamicCharacter; extern CCInventory ccDynamicInv; @@ -65,106 +65,106 @@ int in_inv_screen = 0, inv_screen_newroom = -1; // *** INV WINDOW FUNCTIONS void InvWindow_SetCharacterToUse(GUIInvWindow *guii, CharacterInfo *chaa) { - if (chaa == nullptr) - guii->CharId = -1; - else - guii->CharId = chaa->index_id; - // reset to top of list - guii->TopItem = 0; + if (chaa == nullptr) + guii->CharId = -1; + else + guii->CharId = chaa->index_id; + // reset to top of list + guii->TopItem = 0; - guis_need_update = 1; + guis_need_update = 1; } -CharacterInfo* InvWindow_GetCharacterToUse(GUIInvWindow *guii) { - if (guii->CharId < 0) - return nullptr; +CharacterInfo *InvWindow_GetCharacterToUse(GUIInvWindow *guii) { + if (guii->CharId < 0) + return nullptr; - return &game.chars[guii->CharId]; + return &game.chars[guii->CharId]; } void InvWindow_SetItemWidth(GUIInvWindow *guii, int newwidth) { - guii->ItemWidth = newwidth; - guii->OnResized(); + guii->ItemWidth = newwidth; + guii->OnResized(); } int InvWindow_GetItemWidth(GUIInvWindow *guii) { - return guii->ItemWidth; + return guii->ItemWidth; } void InvWindow_SetItemHeight(GUIInvWindow *guii, int newhit) { - guii->ItemHeight = newhit; - guii->OnResized(); + guii->ItemHeight = newhit; + guii->OnResized(); } int InvWindow_GetItemHeight(GUIInvWindow *guii) { - return guii->ItemHeight; + return guii->ItemHeight; } void InvWindow_SetTopItem(GUIInvWindow *guii, int topitem) { - if (guii->TopItem != topitem) { - guii->TopItem = topitem; - guis_need_update = 1; - } + if (guii->TopItem != topitem) { + guii->TopItem = topitem; + guis_need_update = 1; + } } int InvWindow_GetTopItem(GUIInvWindow *guii) { - return guii->TopItem; + return guii->TopItem; } int InvWindow_GetItemsPerRow(GUIInvWindow *guii) { - return guii->ColCount; + return guii->ColCount; } int InvWindow_GetItemCount(GUIInvWindow *guii) { - return charextra[guii->GetCharacterId()].invorder_count; + return charextra[guii->GetCharacterId()].invorder_count; } int InvWindow_GetRowCount(GUIInvWindow *guii) { - return guii->RowCount; + return guii->RowCount; } void InvWindow_ScrollDown(GUIInvWindow *guii) { - if ((charextra[guii->GetCharacterId()].invorder_count) > - (guii->TopItem + (guii->ColCount * guii->RowCount))) { - guii->TopItem += guii->ColCount; - guis_need_update = 1; - } + if ((charextra[guii->GetCharacterId()].invorder_count) > + (guii->TopItem + (guii->ColCount * guii->RowCount))) { + guii->TopItem += guii->ColCount; + guis_need_update = 1; + } } void InvWindow_ScrollUp(GUIInvWindow *guii) { - if (guii->TopItem > 0) { - guii->TopItem -= guii->ColCount; - if (guii->TopItem < 0) - guii->TopItem = 0; + if (guii->TopItem > 0) { + guii->TopItem -= guii->ColCount; + if (guii->TopItem < 0) + guii->TopItem = 0; - guis_need_update = 1; - } + guis_need_update = 1; + } } -ScriptInvItem* InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index) { - if ((index < 0) || (index >= charextra[guii->GetCharacterId()].invorder_count)) - return nullptr; - return &scrInv[charextra[guii->GetCharacterId()].invorder[index]]; +ScriptInvItem *InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index) { + if ((index < 0) || (index >= charextra[guii->GetCharacterId()].invorder_count)) + return nullptr; + return &scrInv[charextra[guii->GetCharacterId()].invorder[index]]; } //============================================================================= int offset_over_inv(GUIInvWindow *inv) { - if (inv->ItemWidth <= 0 || inv->ItemHeight <= 0) - return -1; - int mover = mouse_ifacebut_xoffs / data_to_game_coord(inv->ItemWidth); - // if it's off the edge of the visible items, ignore - if (mover >= inv->ColCount) - return -1; - mover += (mouse_ifacebut_yoffs / data_to_game_coord(inv->ItemHeight)) * inv->ColCount; - if (mover >= inv->ColCount * inv->RowCount) - return -1; + if (inv->ItemWidth <= 0 || inv->ItemHeight <= 0) + return -1; + int mover = mouse_ifacebut_xoffs / data_to_game_coord(inv->ItemWidth); + // if it's off the edge of the visible items, ignore + if (mover >= inv->ColCount) + return -1; + mover += (mouse_ifacebut_yoffs / data_to_game_coord(inv->ItemHeight)) * inv->ColCount; + if (mover >= inv->ColCount * inv->RowCount) + return -1; - mover += inv->TopItem; - if ((mover < 0) || (mover >= charextra[inv->GetCharacterId()].invorder_count)) - return -1; + mover += inv->TopItem; + if ((mover < 0) || (mover >= charextra[inv->GetCharacterId()].invorder_count)) + return -1; - return charextra[inv->GetCharacterId()].invorder[mover]; + return charextra[inv->GetCharacterId()].invorder[mover]; } // @@ -175,363 +175,347 @@ int offset_over_inv(GUIInvWindow *inv) { #define ICONSPERLINE 4 struct DisplayInvItem { - int num; - int sprnum; + int num; + int sprnum; }; -struct InventoryScreen -{ - static const int ARROWBUTTONWID = 11; - - int BUTTONAREAHEIGHT; - int cmode; - int toret; - int top_item; - int num_visible_items; - int MAX_ITEMAREA_HEIGHT; - int wasonitem; - int bartop; - int barxp; - int numitems; - int widest; - int highest; - int windowwid; - int windowhit; - int windowxp; - int windowyp; - int buttonyp; - DisplayInvItem dii[MAX_INV]; - int btn_look_sprite; - int btn_select_sprite; - int btn_ok_sprite; - - int break_code; - - void Prepare(); - int Redraw(); - void Draw(Bitmap *ds); - void RedrawOverItem(Bitmap *ds, int isonitem); - bool Run(); - void Close(); +struct InventoryScreen { + static const int ARROWBUTTONWID = 11; + + int BUTTONAREAHEIGHT; + int cmode; + int toret; + int top_item; + int num_visible_items; + int MAX_ITEMAREA_HEIGHT; + int wasonitem; + int bartop; + int barxp; + int numitems; + int widest; + int highest; + int windowwid; + int windowhit; + int windowxp; + int windowyp; + int buttonyp; + DisplayInvItem dii[MAX_INV]; + int btn_look_sprite; + int btn_select_sprite; + int btn_ok_sprite; + + int break_code; + + void Prepare(); + int Redraw(); + void Draw(Bitmap *ds); + void RedrawOverItem(Bitmap *ds, int isonitem); + bool Run(); + void Close(); }; InventoryScreen InvScr; -void InventoryScreen::Prepare() -{ - BUTTONAREAHEIGHT = get_fixed_pixel_size(30); - cmode=CURS_ARROW; - toret = -1; - top_item = 0; - num_visible_items = 0; - MAX_ITEMAREA_HEIGHT = ((play.GetUIViewport().GetHeight() - BUTTONAREAHEIGHT) - get_fixed_pixel_size(20)); - in_inv_screen++; - inv_screen_newroom = -1; - - // Sprites 2041, 2042 and 2043 were hardcoded in the older versions of - // the engine to be used in the built-in inventory window. - // If they did not exist engine first fell back to sprites 0, 1, 2 instead. - // Fun fact: this fallback does not seem to be intentional, and was a - // coincidental result of SpriteCache incorrectly remembering "last seeked - // sprite" as 2041/2042/2043 while in fact stream was after sprite 0. - if (spriteset[2041] == nullptr || spriteset[2042] == nullptr || spriteset[2043] == nullptr) - debug_script_warn("InventoryScreen: one or more of the inventory screen graphics (sprites 2041, 2042, 2043) does not exist, fallback to sprites 0, 1, 2 instead"); - btn_look_sprite = spriteset[2041] != nullptr ? 2041 : 0; - btn_select_sprite = spriteset[2042] != nullptr ? 2042 : (spriteset[1] != nullptr ? 1 : 0); - btn_ok_sprite = spriteset[2043] != nullptr ? 2043 : (spriteset[2] != nullptr ? 2 : 0); - - break_code = 0; -} - -int InventoryScreen::Redraw() -{ - numitems=0; - widest=0; - highest=0; - if (charextra[game.playercharacter].invorder_count < 0) - update_invorder(); - if (charextra[game.playercharacter].invorder_count == 0) { - DisplayMessage(996); - in_inv_screen--; - return -1; - } - - if (inv_screen_newroom >= 0) { - in_inv_screen--; - NewRoom(inv_screen_newroom); - return -1; - } - - for (int i = 0; i < charextra[game.playercharacter].invorder_count; ++i) { - if (game.invinfo[charextra[game.playercharacter].invorder[i]].name[0]!=0) { - dii[numitems].num = charextra[game.playercharacter].invorder[i]; - dii[numitems].sprnum = game.invinfo[charextra[game.playercharacter].invorder[i]].pic; - int snn=dii[numitems].sprnum; - if (game.SpriteInfos[snn].Width > widest) widest=game.SpriteInfos[snn].Width; - if (game.SpriteInfos[snn].Height > highest) highest= game.SpriteInfos[snn].Height; - numitems++; - } - } - if (numitems != charextra[game.playercharacter].invorder_count) - quit("inconsistent inventory calculations"); - - widest += get_fixed_pixel_size(4); - highest += get_fixed_pixel_size(4); - num_visible_items = (MAX_ITEMAREA_HEIGHT / highest) * ICONSPERLINE; - - windowhit = highest * (numitems/ICONSPERLINE) + get_fixed_pixel_size(4); - if ((numitems%ICONSPERLINE) !=0) windowhit+=highest; - if (windowhit > MAX_ITEMAREA_HEIGHT) { - windowhit = (MAX_ITEMAREA_HEIGHT / highest) * highest + get_fixed_pixel_size(4); - } - windowhit += BUTTONAREAHEIGHT; - - windowwid = widest*ICONSPERLINE + get_fixed_pixel_size(4); - if (windowwid < get_fixed_pixel_size(105)) windowwid = get_fixed_pixel_size(105); - windowxp=play.GetUIViewport().GetWidth()/2-windowwid/2; - windowyp=play.GetUIViewport().GetHeight()/2-windowhit/2; - buttonyp = windowhit - BUTTONAREAHEIGHT; - bartop = get_fixed_pixel_size(2); - barxp = get_fixed_pixel_size(2); - - Bitmap *ds = prepare_gui_screen(windowxp, windowyp, windowwid, windowhit, true); - Draw(ds); - //ags_domouse(DOMOUSE_ENABLE); - set_mouse_cursor(cmode); - wasonitem = -1; - return 0; -} - -void InventoryScreen::Draw(Bitmap *ds) -{ - color_t draw_color = ds->GetCompatibleColor(play.sierra_inv_color); - ds->FillRect(Rect(0,0,windowwid,windowhit), draw_color); - draw_color = ds->GetCompatibleColor(0); - ds->FillRect(Rect(barxp,bartop, windowwid - get_fixed_pixel_size(2),buttonyp-1), draw_color); - for (int i = top_item; i < numitems; ++i) { - if (i >= top_item + num_visible_items) - break; - Bitmap *spof=spriteset[dii[i].sprnum]; - wputblock(ds, barxp+1+((i-top_item)%4)*widest+widest/2-spof->GetWidth()/2, - bartop+1+((i-top_item)/4)*highest+highest/2-spof->GetHeight()/2,spof,1); - } +void InventoryScreen::Prepare() { + BUTTONAREAHEIGHT = get_fixed_pixel_size(30); + cmode = CURS_ARROW; + toret = -1; + top_item = 0; + num_visible_items = 0; + MAX_ITEMAREA_HEIGHT = ((play.GetUIViewport().GetHeight() - BUTTONAREAHEIGHT) - get_fixed_pixel_size(20)); + in_inv_screen++; + inv_screen_newroom = -1; + + // Sprites 2041, 2042 and 2043 were hardcoded in the older versions of + // the engine to be used in the built-in inventory window. + // If they did not exist engine first fell back to sprites 0, 1, 2 instead. + // Fun fact: this fallback does not seem to be intentional, and was a + // coincidental result of SpriteCache incorrectly remembering "last seeked + // sprite" as 2041/2042/2043 while in fact stream was after sprite 0. + if (spriteset[2041] == nullptr || spriteset[2042] == nullptr || spriteset[2043] == nullptr) + debug_script_warn("InventoryScreen: one or more of the inventory screen graphics (sprites 2041, 2042, 2043) does not exist, fallback to sprites 0, 1, 2 instead"); + btn_look_sprite = spriteset[2041] != nullptr ? 2041 : 0; + btn_select_sprite = spriteset[2042] != nullptr ? 2042 : (spriteset[1] != nullptr ? 1 : 0); + btn_ok_sprite = spriteset[2043] != nullptr ? 2043 : (spriteset[2] != nullptr ? 2 : 0); + + break_code = 0; +} + +int InventoryScreen::Redraw() { + numitems = 0; + widest = 0; + highest = 0; + if (charextra[game.playercharacter].invorder_count < 0) + update_invorder(); + if (charextra[game.playercharacter].invorder_count == 0) { + DisplayMessage(996); + in_inv_screen--; + return -1; + } + + if (inv_screen_newroom >= 0) { + in_inv_screen--; + NewRoom(inv_screen_newroom); + return -1; + } + + for (int i = 0; i < charextra[game.playercharacter].invorder_count; ++i) { + if (game.invinfo[charextra[game.playercharacter].invorder[i]].name[0] != 0) { + dii[numitems].num = charextra[game.playercharacter].invorder[i]; + dii[numitems].sprnum = game.invinfo[charextra[game.playercharacter].invorder[i]].pic; + int snn = dii[numitems].sprnum; + if (game.SpriteInfos[snn].Width > widest) widest = game.SpriteInfos[snn].Width; + if (game.SpriteInfos[snn].Height > highest) highest = game.SpriteInfos[snn].Height; + numitems++; + } + } + if (numitems != charextra[game.playercharacter].invorder_count) + quit("inconsistent inventory calculations"); + + widest += get_fixed_pixel_size(4); + highest += get_fixed_pixel_size(4); + num_visible_items = (MAX_ITEMAREA_HEIGHT / highest) * ICONSPERLINE; + + windowhit = highest * (numitems / ICONSPERLINE) + get_fixed_pixel_size(4); + if ((numitems % ICONSPERLINE) != 0) windowhit += highest; + if (windowhit > MAX_ITEMAREA_HEIGHT) { + windowhit = (MAX_ITEMAREA_HEIGHT / highest) * highest + get_fixed_pixel_size(4); + } + windowhit += BUTTONAREAHEIGHT; + + windowwid = widest * ICONSPERLINE + get_fixed_pixel_size(4); + if (windowwid < get_fixed_pixel_size(105)) windowwid = get_fixed_pixel_size(105); + windowxp = play.GetUIViewport().GetWidth() / 2 - windowwid / 2; + windowyp = play.GetUIViewport().GetHeight() / 2 - windowhit / 2; + buttonyp = windowhit - BUTTONAREAHEIGHT; + bartop = get_fixed_pixel_size(2); + barxp = get_fixed_pixel_size(2); + + Bitmap *ds = prepare_gui_screen(windowxp, windowyp, windowwid, windowhit, true); + Draw(ds); + //ags_domouse(DOMOUSE_ENABLE); + set_mouse_cursor(cmode); + wasonitem = -1; + return 0; +} + +void InventoryScreen::Draw(Bitmap *ds) { + color_t draw_color = ds->GetCompatibleColor(play.sierra_inv_color); + ds->FillRect(Rect(0, 0, windowwid, windowhit), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->FillRect(Rect(barxp, bartop, windowwid - get_fixed_pixel_size(2), buttonyp - 1), draw_color); + for (int i = top_item; i < numitems; ++i) { + if (i >= top_item + num_visible_items) + break; + Bitmap *spof = spriteset[dii[i].sprnum]; + wputblock(ds, barxp + 1 + ((i - top_item) % 4)*widest + widest / 2 - spof->GetWidth() / 2, + bartop + 1 + ((i - top_item) / 4)*highest + highest / 2 - spof->GetHeight() / 2, spof, 1); + } #define BUTTONWID Math::Max(1, game.SpriteInfos[btn_select_sprite].Width) - // Draw select, look and OK buttons - wputblock(ds, 2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_look_sprite], 1); - wputblock(ds, 3+BUTTONWID, buttonyp + get_fixed_pixel_size(2), spriteset[btn_select_sprite], 1); - wputblock(ds, 4+BUTTONWID*2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_ok_sprite], 1); - - // Draw Up and Down buttons if required - Bitmap *arrowblock = BitmapHelper::CreateTransparentBitmap (ARROWBUTTONWID, ARROWBUTTONWID); - draw_color = arrowblock->GetCompatibleColor(0); - if (play.sierra_inv_color == 0) - draw_color = ds->GetCompatibleColor(14); - - arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, ARROWBUTTONWID-2, 9), draw_color); - arrowblock->DrawLine(Line(ARROWBUTTONWID/2, 2, 2, 9), draw_color); - arrowblock->DrawLine(Line(2, 9, ARROWBUTTONWID-2, 9), draw_color); - arrowblock->FloodFill(ARROWBUTTONWID/2, 4, draw_color); - - if (top_item > 0) - wputblock(ds, windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(2), arrowblock, 1); - if (top_item + num_visible_items < numitems) - arrowblock->FlipBlt(arrowblock, windowwid-ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID, Common::kBitmap_VFlip); - delete arrowblock; -} - -void InventoryScreen::RedrawOverItem(Bitmap *ds, int isonitem) -{ - int rectxp=barxp+1+(wasonitem%4)*widest; - int rectyp=bartop+1+((wasonitem - top_item)/4)*highest; - if (wasonitem>=0) - { - color_t draw_color = ds->GetCompatibleColor(0); - ds->DrawRect(Rect(rectxp,rectyp,rectxp+widest-1,rectyp+highest-1), draw_color); - } - if (isonitem>=0) - { - color_t draw_color = ds->GetCompatibleColor(14);//opts.invrectcol); - rectxp=barxp+1+(isonitem%4)*widest; - rectyp=bartop+1+((isonitem - top_item)/4)*highest; - ds->DrawRect(Rect(rectxp,rectyp,rectxp+widest-1,rectyp+highest-1), draw_color); - } -} - -bool InventoryScreen::Run() -{ - int kgn; - if (run_service_key_controls(kgn) && !play.IsIgnoringInput()) - { - return false; // end inventory screen loop - } - - update_audio_system_on_game_loop(); - refresh_gui_screen(); - - // NOTE: this is because old code was working with full game screen - const int mousex = ::mousex - windowxp; - const int mousey = ::mousey - windowyp; - - int isonitem=((mousey-bartop)/highest)*ICONSPERLINE+(mousex-barxp)/widest; - if (mousey<=bartop) isonitem=-1; - else if (isonitem >= 0) isonitem += top_item; - if ((isonitem<0) | (isonitem>=numitems) | (isonitem >= top_item + num_visible_items)) - isonitem=-1; - - int mclick, mwheelz; - if (!run_service_mb_controls(mclick, mwheelz) || play.IsIgnoringInput()) { - mclick = NONE; - } - - if (mclick == LEFT) { - if ((mousey<0) | (mousey>windowhit) | (mousex<0) | (mousex>windowwid)) - return true; // continue inventory screen loop - if (mouseyactiveinv; - playerchar->activeinv = toret; - - //ags_domouse(DOMOUSE_DISABLE); - run_event_block_inv(dii[clickedon].num, 3); - - // if the script didn't change it, then put it back - if (playerchar->activeinv == toret) - playerchar->activeinv = activeinvwas; - - // in case the script did anything to the screen, redraw it - UpdateGameOnce(); - - // They used the active item and lost it - if (playerchar->inv[toret] < 1) { - cmode = CURS_ARROW; - set_mouse_cursor(cmode); - toret = -1; - } - - break_code = Redraw(); - return break_code == 0; - } - toret=dii[clickedon].num; - // int plusng=play.using; play.using=toret; - update_inv_cursor(toret); - set_mouse_cursor(MODE_USE); - cmode=MODE_USE; - // play.using=plusng; - // break; - return true; // continue inventory screen loop - } - else { - if (mousex >= windowwid-ARROWBUTTONWID) { - if (mousey < buttonyp + get_fixed_pixel_size(2) + ARROWBUTTONWID) { - if (top_item > 0) { - top_item -= ICONSPERLINE; - //ags_domouse(DOMOUSE_DISABLE); - - break_code = Redraw(); - return break_code == 0; - } - } - else if ((mousey < buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID*2) && (top_item + num_visible_items < numitems)) { - top_item += ICONSPERLINE; - //ags_domouse(DOMOUSE_DISABLE); - - break_code = Redraw(); - return break_code == 0; - } - return true; // continue inventory screen loop - } - - int buton=mousex-2; - if (buton<0) return true; // continue inventory screen loop - buton/=BUTTONWID; - if (buton>=3) return true; // continue inventory screen loop - if (buton==0) { toret=-1; cmode=MODE_LOOK; } - else if (buton==1) { cmode=CURS_ARROW; toret=-1; } - else - { - return false; // end inventory screen loop - } - set_mouse_cursor(cmode); - } - } - else if (mclick == RIGHT) { - if (cmode == CURS_ARROW) - cmode = MODE_LOOK; - else - cmode = CURS_ARROW; - toret = -1; - set_mouse_cursor(cmode); - } - else if (isonitem!=wasonitem) - { - //ags_domouse(DOMOUSE_DISABLE); - RedrawOverItem(get_gui_screen(), isonitem); - //ags_domouse(DOMOUSE_ENABLE); - } - wasonitem=isonitem; - - update_polled_stuff_if_runtime(); - - WaitForNextFrame(); - - return true; // continue inventory screen loop -} - -void InventoryScreen::Close() -{ - clear_gui_screen(); - set_default_cursor(); - invalidate_screen(); - in_inv_screen--; -} - -int __actual_invscreen() -{ - InvScr.Prepare(); - InvScr.break_code = InvScr.Redraw(); - if (InvScr.break_code != 0) - { - return InvScr.break_code; - } - - while (InvScr.Run()); - - if (InvScr.break_code != 0) - { - return InvScr.break_code; - } - - ags_clear_input_buffer(); - - InvScr.Close(); - return InvScr.toret; + // Draw select, look and OK buttons + wputblock(ds, 2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_look_sprite], 1); + wputblock(ds, 3 + BUTTONWID, buttonyp + get_fixed_pixel_size(2), spriteset[btn_select_sprite], 1); + wputblock(ds, 4 + BUTTONWID * 2, buttonyp + get_fixed_pixel_size(2), spriteset[btn_ok_sprite], 1); + + // Draw Up and Down buttons if required + Bitmap *arrowblock = BitmapHelper::CreateTransparentBitmap(ARROWBUTTONWID, ARROWBUTTONWID); + draw_color = arrowblock->GetCompatibleColor(0); + if (play.sierra_inv_color == 0) + draw_color = ds->GetCompatibleColor(14); + + arrowblock->DrawLine(Line(ARROWBUTTONWID / 2, 2, ARROWBUTTONWID - 2, 9), draw_color); + arrowblock->DrawLine(Line(ARROWBUTTONWID / 2, 2, 2, 9), draw_color); + arrowblock->DrawLine(Line(2, 9, ARROWBUTTONWID - 2, 9), draw_color); + arrowblock->FloodFill(ARROWBUTTONWID / 2, 4, draw_color); + + if (top_item > 0) + wputblock(ds, windowwid - ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(2), arrowblock, 1); + if (top_item + num_visible_items < numitems) + arrowblock->FlipBlt(arrowblock, windowwid - ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID, Common::kBitmap_VFlip); + delete arrowblock; +} + +void InventoryScreen::RedrawOverItem(Bitmap *ds, int isonitem) { + int rectxp = barxp + 1 + (wasonitem % 4) * widest; + int rectyp = bartop + 1 + ((wasonitem - top_item) / 4) * highest; + if (wasonitem >= 0) { + color_t draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(rectxp, rectyp, rectxp + widest - 1, rectyp + highest - 1), draw_color); + } + if (isonitem >= 0) { + color_t draw_color = ds->GetCompatibleColor(14);//opts.invrectcol); + rectxp = barxp + 1 + (isonitem % 4) * widest; + rectyp = bartop + 1 + ((isonitem - top_item) / 4) * highest; + ds->DrawRect(Rect(rectxp, rectyp, rectxp + widest - 1, rectyp + highest - 1), draw_color); + } +} + +bool InventoryScreen::Run() { + int kgn; + if (run_service_key_controls(kgn) && !play.IsIgnoringInput()) { + return false; // end inventory screen loop + } + + update_audio_system_on_game_loop(); + refresh_gui_screen(); + + // NOTE: this is because old code was working with full game screen + const int mousex = ::mousex - windowxp; + const int mousey = ::mousey - windowyp; + + int isonitem = ((mousey - bartop) / highest) * ICONSPERLINE + (mousex - barxp) / widest; + if (mousey <= bartop) isonitem = -1; + else if (isonitem >= 0) isonitem += top_item; + if ((isonitem < 0) | (isonitem >= numitems) | (isonitem >= top_item + num_visible_items)) + isonitem = -1; + + int mclick, mwheelz; + if (!run_service_mb_controls(mclick, mwheelz) || play.IsIgnoringInput()) { + mclick = NONE; + } + + if (mclick == LEFT) { + if ((mousey < 0) | (mousey > windowhit) | (mousex < 0) | (mousex > windowwid)) + return true; // continue inventory screen loop + if (mousey < buttonyp) { + int clickedon = isonitem; + if (clickedon < 0) return true; // continue inventory screen loop + evblocknum = dii[clickedon].num; + play.used_inv_on = dii[clickedon].num; + + if (cmode == MODE_LOOK) { + //ags_domouse(DOMOUSE_DISABLE); + run_event_block_inv(dii[clickedon].num, 0); + // in case the script did anything to the screen, redraw it + UpdateGameOnce(); + + break_code = Redraw(); + return break_code == 0; + } else if (cmode == MODE_USE) { + // use objects on each other + play.usedinv = toret; + + // set the activeinv so the script can check it + int activeinvwas = playerchar->activeinv; + playerchar->activeinv = toret; + + //ags_domouse(DOMOUSE_DISABLE); + run_event_block_inv(dii[clickedon].num, 3); + + // if the script didn't change it, then put it back + if (playerchar->activeinv == toret) + playerchar->activeinv = activeinvwas; + + // in case the script did anything to the screen, redraw it + UpdateGameOnce(); + + // They used the active item and lost it + if (playerchar->inv[toret] < 1) { + cmode = CURS_ARROW; + set_mouse_cursor(cmode); + toret = -1; + } + + break_code = Redraw(); + return break_code == 0; + } + toret = dii[clickedon].num; + // int plusng=play.using; play.using=toret; + update_inv_cursor(toret); + set_mouse_cursor(MODE_USE); + cmode = MODE_USE; + // play.using=plusng; + // break; + return true; // continue inventory screen loop + } else { + if (mousex >= windowwid - ARROWBUTTONWID) { + if (mousey < buttonyp + get_fixed_pixel_size(2) + ARROWBUTTONWID) { + if (top_item > 0) { + top_item -= ICONSPERLINE; + //ags_domouse(DOMOUSE_DISABLE); + + break_code = Redraw(); + return break_code == 0; + } + } else if ((mousey < buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID * 2) && (top_item + num_visible_items < numitems)) { + top_item += ICONSPERLINE; + //ags_domouse(DOMOUSE_DISABLE); + + break_code = Redraw(); + return break_code == 0; + } + return true; // continue inventory screen loop + } + + int buton = mousex - 2; + if (buton < 0) return true; // continue inventory screen loop + buton /= BUTTONWID; + if (buton >= 3) return true; // continue inventory screen loop + if (buton == 0) { + toret = -1; + cmode = MODE_LOOK; + } else if (buton == 1) { + cmode = CURS_ARROW; + toret = -1; + } else { + return false; // end inventory screen loop + } + set_mouse_cursor(cmode); + } + } else if (mclick == RIGHT) { + if (cmode == CURS_ARROW) + cmode = MODE_LOOK; + else + cmode = CURS_ARROW; + toret = -1; + set_mouse_cursor(cmode); + } else if (isonitem != wasonitem) { + //ags_domouse(DOMOUSE_DISABLE); + RedrawOverItem(get_gui_screen(), isonitem); + //ags_domouse(DOMOUSE_ENABLE); + } + wasonitem = isonitem; + + update_polled_stuff_if_runtime(); + + WaitForNextFrame(); + + return true; // continue inventory screen loop +} + +void InventoryScreen::Close() { + clear_gui_screen(); + set_default_cursor(); + invalidate_screen(); + in_inv_screen--; +} + +int __actual_invscreen() { + InvScr.Prepare(); + InvScr.break_code = InvScr.Redraw(); + if (InvScr.break_code != 0) { + return InvScr.break_code; + } + + while (InvScr.Run()); + + if (InvScr.break_code != 0) { + return InvScr.break_code; + } + + ags_clear_input_buffer(); + + InvScr.Close(); + return InvScr.toret; } int invscreen() { - int selt=__actual_invscreen(); - if (selt<0) return -1; - playerchar->activeinv=selt; - guis_need_update = 1; - set_cursor_mode(MODE_USE); - return selt; + int selt = __actual_invscreen(); + if (selt < 0) return -1; + playerchar->activeinv = selt; + guis_need_update = 1; + set_cursor_mode(MODE_USE); + return selt; } //============================================================================= @@ -545,122 +529,107 @@ int invscreen() { #include "script/script_runtime.h" // void (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(GUIInvWindow, InvWindow_ScrollDown); +RuntimeScriptValue Sc_InvWindow_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(GUIInvWindow, InvWindow_ScrollDown); } // void (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_ScrollUp(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(GUIInvWindow, InvWindow_ScrollUp); +RuntimeScriptValue Sc_InvWindow_ScrollUp(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(GUIInvWindow, InvWindow_ScrollUp); } // CharacterInfo* (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_GetCharacterToUse(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUIInvWindow, CharacterInfo, ccDynamicCharacter, InvWindow_GetCharacterToUse); +RuntimeScriptValue Sc_InvWindow_GetCharacterToUse(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUIInvWindow, CharacterInfo, ccDynamicCharacter, InvWindow_GetCharacterToUse); } // void (GUIInvWindow *guii, CharacterInfo *chaa) -RuntimeScriptValue Sc_InvWindow_SetCharacterToUse(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUIInvWindow, InvWindow_SetCharacterToUse, CharacterInfo); +RuntimeScriptValue Sc_InvWindow_SetCharacterToUse(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUIInvWindow, InvWindow_SetCharacterToUse, CharacterInfo); } // ScriptInvItem* (GUIInvWindow *guii, int index) -RuntimeScriptValue Sc_InvWindow_GetItemAtIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT(GUIInvWindow, ScriptInvItem, ccDynamicInv, InvWindow_GetItemAtIndex); +RuntimeScriptValue Sc_InvWindow_GetItemAtIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT(GUIInvWindow, ScriptInvItem, ccDynamicInv, InvWindow_GetItemAtIndex); } // int (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemCount); +RuntimeScriptValue Sc_InvWindow_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemCount); } // int (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_GetItemHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemHeight); +RuntimeScriptValue Sc_InvWindow_GetItemHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemHeight); } // void (GUIInvWindow *guii, int newhit) -RuntimeScriptValue Sc_InvWindow_SetItemHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetItemHeight); +RuntimeScriptValue Sc_InvWindow_SetItemHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetItemHeight); } // int (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_GetItemWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemWidth); +RuntimeScriptValue Sc_InvWindow_GetItemWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemWidth); } // void (GUIInvWindow *guii, int newwidth) -RuntimeScriptValue Sc_InvWindow_SetItemWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetItemWidth); +RuntimeScriptValue Sc_InvWindow_SetItemWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetItemWidth); } // int (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_GetItemsPerRow(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemsPerRow); +RuntimeScriptValue Sc_InvWindow_GetItemsPerRow(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetItemsPerRow); } // int (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_GetRowCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIInvWindow, InvWindow_GetRowCount); +RuntimeScriptValue Sc_InvWindow_GetRowCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetRowCount); } // int (GUIInvWindow *guii) -RuntimeScriptValue Sc_InvWindow_GetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIInvWindow, InvWindow_GetTopItem); +RuntimeScriptValue Sc_InvWindow_GetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIInvWindow, InvWindow_GetTopItem); } // void (GUIInvWindow *guii, int topitem) -RuntimeScriptValue Sc_InvWindow_SetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetTopItem); -} - - - -void RegisterInventoryWindowAPI() -{ - ccAddExternalObjectFunction("InvWindow::ScrollDown^0", Sc_InvWindow_ScrollDown); - ccAddExternalObjectFunction("InvWindow::ScrollUp^0", Sc_InvWindow_ScrollUp); - ccAddExternalObjectFunction("InvWindow::get_CharacterToUse", Sc_InvWindow_GetCharacterToUse); - ccAddExternalObjectFunction("InvWindow::set_CharacterToUse", Sc_InvWindow_SetCharacterToUse); - ccAddExternalObjectFunction("InvWindow::geti_ItemAtIndex", Sc_InvWindow_GetItemAtIndex); - ccAddExternalObjectFunction("InvWindow::get_ItemCount", Sc_InvWindow_GetItemCount); - ccAddExternalObjectFunction("InvWindow::get_ItemHeight", Sc_InvWindow_GetItemHeight); - ccAddExternalObjectFunction("InvWindow::set_ItemHeight", Sc_InvWindow_SetItemHeight); - ccAddExternalObjectFunction("InvWindow::get_ItemWidth", Sc_InvWindow_GetItemWidth); - ccAddExternalObjectFunction("InvWindow::set_ItemWidth", Sc_InvWindow_SetItemWidth); - ccAddExternalObjectFunction("InvWindow::get_ItemsPerRow", Sc_InvWindow_GetItemsPerRow); - ccAddExternalObjectFunction("InvWindow::get_RowCount", Sc_InvWindow_GetRowCount); - ccAddExternalObjectFunction("InvWindow::get_TopItem", Sc_InvWindow_GetTopItem); - ccAddExternalObjectFunction("InvWindow::set_TopItem", Sc_InvWindow_SetTopItem); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("InvWindow::ScrollDown^0", (void*)InvWindow_ScrollDown); - ccAddExternalFunctionForPlugin("InvWindow::ScrollUp^0", (void*)InvWindow_ScrollUp); - ccAddExternalFunctionForPlugin("InvWindow::get_CharacterToUse", (void*)InvWindow_GetCharacterToUse); - ccAddExternalFunctionForPlugin("InvWindow::set_CharacterToUse", (void*)InvWindow_SetCharacterToUse); - ccAddExternalFunctionForPlugin("InvWindow::geti_ItemAtIndex", (void*)InvWindow_GetItemAtIndex); - ccAddExternalFunctionForPlugin("InvWindow::get_ItemCount", (void*)InvWindow_GetItemCount); - ccAddExternalFunctionForPlugin("InvWindow::get_ItemHeight", (void*)InvWindow_GetItemHeight); - ccAddExternalFunctionForPlugin("InvWindow::set_ItemHeight", (void*)InvWindow_SetItemHeight); - ccAddExternalFunctionForPlugin("InvWindow::get_ItemWidth", (void*)InvWindow_GetItemWidth); - ccAddExternalFunctionForPlugin("InvWindow::set_ItemWidth", (void*)InvWindow_SetItemWidth); - ccAddExternalFunctionForPlugin("InvWindow::get_ItemsPerRow", (void*)InvWindow_GetItemsPerRow); - ccAddExternalFunctionForPlugin("InvWindow::get_RowCount", (void*)InvWindow_GetRowCount); - ccAddExternalFunctionForPlugin("InvWindow::get_TopItem", (void*)InvWindow_GetTopItem); - ccAddExternalFunctionForPlugin("InvWindow::set_TopItem", (void*)InvWindow_SetTopItem); +RuntimeScriptValue Sc_InvWindow_SetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIInvWindow, InvWindow_SetTopItem); +} + + + +void RegisterInventoryWindowAPI() { + ccAddExternalObjectFunction("InvWindow::ScrollDown^0", Sc_InvWindow_ScrollDown); + ccAddExternalObjectFunction("InvWindow::ScrollUp^0", Sc_InvWindow_ScrollUp); + ccAddExternalObjectFunction("InvWindow::get_CharacterToUse", Sc_InvWindow_GetCharacterToUse); + ccAddExternalObjectFunction("InvWindow::set_CharacterToUse", Sc_InvWindow_SetCharacterToUse); + ccAddExternalObjectFunction("InvWindow::geti_ItemAtIndex", Sc_InvWindow_GetItemAtIndex); + ccAddExternalObjectFunction("InvWindow::get_ItemCount", Sc_InvWindow_GetItemCount); + ccAddExternalObjectFunction("InvWindow::get_ItemHeight", Sc_InvWindow_GetItemHeight); + ccAddExternalObjectFunction("InvWindow::set_ItemHeight", Sc_InvWindow_SetItemHeight); + ccAddExternalObjectFunction("InvWindow::get_ItemWidth", Sc_InvWindow_GetItemWidth); + ccAddExternalObjectFunction("InvWindow::set_ItemWidth", Sc_InvWindow_SetItemWidth); + ccAddExternalObjectFunction("InvWindow::get_ItemsPerRow", Sc_InvWindow_GetItemsPerRow); + ccAddExternalObjectFunction("InvWindow::get_RowCount", Sc_InvWindow_GetRowCount); + ccAddExternalObjectFunction("InvWindow::get_TopItem", Sc_InvWindow_GetTopItem); + ccAddExternalObjectFunction("InvWindow::set_TopItem", Sc_InvWindow_SetTopItem); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("InvWindow::ScrollDown^0", (void *)InvWindow_ScrollDown); + ccAddExternalFunctionForPlugin("InvWindow::ScrollUp^0", (void *)InvWindow_ScrollUp); + ccAddExternalFunctionForPlugin("InvWindow::get_CharacterToUse", (void *)InvWindow_GetCharacterToUse); + ccAddExternalFunctionForPlugin("InvWindow::set_CharacterToUse", (void *)InvWindow_SetCharacterToUse); + ccAddExternalFunctionForPlugin("InvWindow::geti_ItemAtIndex", (void *)InvWindow_GetItemAtIndex); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemCount", (void *)InvWindow_GetItemCount); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemHeight", (void *)InvWindow_GetItemHeight); + ccAddExternalFunctionForPlugin("InvWindow::set_ItemHeight", (void *)InvWindow_SetItemHeight); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemWidth", (void *)InvWindow_GetItemWidth); + ccAddExternalFunctionForPlugin("InvWindow::set_ItemWidth", (void *)InvWindow_SetItemWidth); + ccAddExternalFunctionForPlugin("InvWindow::get_ItemsPerRow", (void *)InvWindow_GetItemsPerRow); + ccAddExternalFunctionForPlugin("InvWindow::get_RowCount", (void *)InvWindow_GetRowCount); + ccAddExternalFunctionForPlugin("InvWindow::get_TopItem", (void *)InvWindow_GetTopItem); + ccAddExternalFunctionForPlugin("InvWindow::set_TopItem", (void *)InvWindow_SetTopItem); } diff --git a/engines/ags/engine/ac/invwindow.h b/engines/ags/engine/ac/invwindow.h index fe1e9a8105c2..4e46eec4720d 100644 --- a/engines/ags/engine/ac/invwindow.h +++ b/engines/ags/engine/ac/invwindow.h @@ -30,7 +30,7 @@ using AGS::Common::GUIInvWindow; void InvWindow_SetCharacterToUse(GUIInvWindow *guii, CharacterInfo *chaa); -CharacterInfo* InvWindow_GetCharacterToUse(GUIInvWindow *guii); +CharacterInfo *InvWindow_GetCharacterToUse(GUIInvWindow *guii); void InvWindow_SetItemWidth(GUIInvWindow *guii, int newwidth); int InvWindow_GetItemWidth(GUIInvWindow *guii); void InvWindow_SetItemHeight(GUIInvWindow *guii, int newhit); @@ -42,11 +42,11 @@ int InvWindow_GetItemCount(GUIInvWindow *guii); int InvWindow_GetRowCount(GUIInvWindow *guii); void InvWindow_ScrollDown(GUIInvWindow *guii); void InvWindow_ScrollUp(GUIInvWindow *guii); -ScriptInvItem* InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index); +ScriptInvItem *InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index); //============================================================================= -int offset_over_inv(GUIInvWindow *inv); +int offset_over_inv(GUIInvWindow *inv); // NOTE: This function is valid for AGS 2.72 and lower int invscreen(); diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp index c4442eb5a8e9..e16de8b958fa 100644 --- a/engines/ags/engine/ac/keycode.cpp +++ b/engines/ags/engine/ac/keycode.cpp @@ -24,140 +24,364 @@ #include -int GetKeyForKeyPressCb(int keycode) -{ - // lower case 'a'..'z' do not exist as keycodes, only ascii. 'A'..'Z' do though! - return (keycode >= 'a' && keycode <= 'z') ? keycode - 32 : keycode; +int GetKeyForKeyPressCb(int keycode) { + // lower case 'a'..'z' do not exist as keycodes, only ascii. 'A'..'Z' do though! + return (keycode >= 'a' && keycode <= 'z') ? keycode - 32 : keycode; } -int PlatformKeyFromAgsKey(int key) -{ - int platformKey = -1; +int PlatformKeyFromAgsKey(int key) { + int platformKey = -1; - switch (key) { - // ctrl-[A-Z] keys are numbered 1-26 for A-Z - case eAGSKeyCodeCtrlA: platformKey = 1; break; - case eAGSKeyCodeCtrlB: platformKey = 2; break; - case eAGSKeyCodeCtrlC: platformKey = 3; break; - case eAGSKeyCodeCtrlD: platformKey = 4; break; - case eAGSKeyCodeCtrlE: platformKey = 5; break; - case eAGSKeyCodeCtrlF: platformKey = 6; break; - case eAGSKeyCodeCtrlG: platformKey = 7; break; - // case eAGSKeyCodeCtrlH: // overlap with backspace - // case eAGSKeyCodeCtrlI: // overlap with tab - case eAGSKeyCodeCtrlJ: platformKey = 10; break; - case eAGSKeyCodeCtrlK: platformKey = 11; break; - case eAGSKeyCodeCtrlL: platformKey = 12; break; - // case eAGSKeyCodeCtrlM: // overlap with return - case eAGSKeyCodeCtrlN: platformKey = 14; break; - case eAGSKeyCodeCtrlO: platformKey = 15; break; - case eAGSKeyCodeCtrlP: platformKey = 16; break; - case eAGSKeyCodeCtrlQ: platformKey = 17; break; - case eAGSKeyCodeCtrlR: platformKey = 18; break; - case eAGSKeyCodeCtrlS: platformKey = 19; break; - case eAGSKeyCodeCtrlT: platformKey = 20; break; - case eAGSKeyCodeCtrlU: platformKey = 21; break; - case eAGSKeyCodeCtrlV: platformKey = 22; break; - case eAGSKeyCodeCtrlW: platformKey = 23; break; - case eAGSKeyCodeCtrlX: platformKey = 24; break; - case eAGSKeyCodeCtrlY: platformKey = 25; break; - case eAGSKeyCodeCtrlZ: platformKey = 26; break; + switch (key) { + // ctrl-[A-Z] keys are numbered 1-26 for A-Z + case eAGSKeyCodeCtrlA: + platformKey = 1; + break; + case eAGSKeyCodeCtrlB: + platformKey = 2; + break; + case eAGSKeyCodeCtrlC: + platformKey = 3; + break; + case eAGSKeyCodeCtrlD: + platformKey = 4; + break; + case eAGSKeyCodeCtrlE: + platformKey = 5; + break; + case eAGSKeyCodeCtrlF: + platformKey = 6; + break; + case eAGSKeyCodeCtrlG: + platformKey = 7; + break; + // case eAGSKeyCodeCtrlH: // overlap with backspace + // case eAGSKeyCodeCtrlI: // overlap with tab + case eAGSKeyCodeCtrlJ: + platformKey = 10; + break; + case eAGSKeyCodeCtrlK: + platformKey = 11; + break; + case eAGSKeyCodeCtrlL: + platformKey = 12; + break; + // case eAGSKeyCodeCtrlM: // overlap with return + case eAGSKeyCodeCtrlN: + platformKey = 14; + break; + case eAGSKeyCodeCtrlO: + platformKey = 15; + break; + case eAGSKeyCodeCtrlP: + platformKey = 16; + break; + case eAGSKeyCodeCtrlQ: + platformKey = 17; + break; + case eAGSKeyCodeCtrlR: + platformKey = 18; + break; + case eAGSKeyCodeCtrlS: + platformKey = 19; + break; + case eAGSKeyCodeCtrlT: + platformKey = 20; + break; + case eAGSKeyCodeCtrlU: + platformKey = 21; + break; + case eAGSKeyCodeCtrlV: + platformKey = 22; + break; + case eAGSKeyCodeCtrlW: + platformKey = 23; + break; + case eAGSKeyCodeCtrlX: + platformKey = 24; + break; + case eAGSKeyCodeCtrlY: + platformKey = 25; + break; + case eAGSKeyCodeCtrlZ: + platformKey = 26; + break; - case eAGSKeyCodeBackspace: platformKey = (__allegro_KEY_BACKSPACE << 8) | 8; break; - case eAGSKeyCodeTab: platformKey = (__allegro_KEY_TAB << 8) | 9; break; - case eAGSKeyCodeReturn: platformKey = (__allegro_KEY_ENTER << 8) | 13; break; - case eAGSKeyCodeEscape: platformKey = (__allegro_KEY_ESC << 8) | 27; break; - case eAGSKeyCodeSpace: platformKey = (__allegro_KEY_SPACE << 8) | ' '; break; - case eAGSKeyCodeExclamationMark: platformKey = '!'; break; - case eAGSKeyCodeDoubleQuote: platformKey = '"'; break; - case eAGSKeyCodeHash: platformKey = '#'; break; - case eAGSKeyCodeDollar: platformKey = '$'; break; - case eAGSKeyCodePercent: platformKey = '%'; break; - case eAGSKeyCodeAmpersand: platformKey = '&'; break; - case eAGSKeyCodeSingleQuote: platformKey = '\''; break; - case eAGSKeyCodeOpenParenthesis: platformKey = '('; break; - case eAGSKeyCodeCloseParenthesis: platformKey = ')'; break; - case eAGSKeyCodeAsterisk: platformKey = '*'; break; - case eAGSKeyCodePlus: platformKey = '+'; break; - case eAGSKeyCodeComma: platformKey = ','; break; - case eAGSKeyCodeHyphen: platformKey = '-'; break; - case eAGSKeyCodePeriod: platformKey = '.'; break; - case eAGSKeyCodeForwardSlash: platformKey = '/'; break; - case eAGSKeyCodeColon: platformKey = ':'; break; - case eAGSKeyCodeSemiColon: platformKey = ';'; break; - case eAGSKeyCodeLessThan: platformKey = '<'; break; - case eAGSKeyCodeEquals: platformKey = '='; break; - case eAGSKeyCodeGreaterThan: platformKey = '>'; break; - case eAGSKeyCodeQuestionMark: platformKey = '?'; break; - case eAGSKeyCodeAt: platformKey = '@'; break; - case eAGSKeyCodeOpenBracket: platformKey = '['; break; - case eAGSKeyCodeBackSlash: platformKey = '\\'; break; - case eAGSKeyCodeCloseBracket: platformKey = ']'; break; - case eAGSKeyCodeUnderscore: platformKey = '_'; break; + case eAGSKeyCodeBackspace: + platformKey = (__allegro_KEY_BACKSPACE << 8) | 8; + break; + case eAGSKeyCodeTab: + platformKey = (__allegro_KEY_TAB << 8) | 9; + break; + case eAGSKeyCodeReturn: + platformKey = (__allegro_KEY_ENTER << 8) | 13; + break; + case eAGSKeyCodeEscape: + platformKey = (__allegro_KEY_ESC << 8) | 27; + break; + case eAGSKeyCodeSpace: + platformKey = (__allegro_KEY_SPACE << 8) | ' '; + break; + case eAGSKeyCodeExclamationMark: + platformKey = '!'; + break; + case eAGSKeyCodeDoubleQuote: + platformKey = '"'; + break; + case eAGSKeyCodeHash: + platformKey = '#'; + break; + case eAGSKeyCodeDollar: + platformKey = '$'; + break; + case eAGSKeyCodePercent: + platformKey = '%'; + break; + case eAGSKeyCodeAmpersand: + platformKey = '&'; + break; + case eAGSKeyCodeSingleQuote: + platformKey = '\''; + break; + case eAGSKeyCodeOpenParenthesis: + platformKey = '('; + break; + case eAGSKeyCodeCloseParenthesis: + platformKey = ')'; + break; + case eAGSKeyCodeAsterisk: + platformKey = '*'; + break; + case eAGSKeyCodePlus: + platformKey = '+'; + break; + case eAGSKeyCodeComma: + platformKey = ','; + break; + case eAGSKeyCodeHyphen: + platformKey = '-'; + break; + case eAGSKeyCodePeriod: + platformKey = '.'; + break; + case eAGSKeyCodeForwardSlash: + platformKey = '/'; + break; + case eAGSKeyCodeColon: + platformKey = ':'; + break; + case eAGSKeyCodeSemiColon: + platformKey = ';'; + break; + case eAGSKeyCodeLessThan: + platformKey = '<'; + break; + case eAGSKeyCodeEquals: + platformKey = '='; + break; + case eAGSKeyCodeGreaterThan: + platformKey = '>'; + break; + case eAGSKeyCodeQuestionMark: + platformKey = '?'; + break; + case eAGSKeyCodeAt: + platformKey = '@'; + break; + case eAGSKeyCodeOpenBracket: + platformKey = '['; + break; + case eAGSKeyCodeBackSlash: + platformKey = '\\'; + break; + case eAGSKeyCodeCloseBracket: + platformKey = ']'; + break; + case eAGSKeyCodeUnderscore: + platformKey = '_'; + break; - case eAGSKeyCode0: platformKey = (__allegro_KEY_0 << 8) | '0'; break; - case eAGSKeyCode1: platformKey = (__allegro_KEY_1 << 8) | '1'; break; - case eAGSKeyCode2: platformKey = (__allegro_KEY_2 << 8) | '2'; break; - case eAGSKeyCode3: platformKey = (__allegro_KEY_3 << 8) | '3'; break; - case eAGSKeyCode4: platformKey = (__allegro_KEY_4 << 8) | '4'; break; - case eAGSKeyCode5: platformKey = (__allegro_KEY_5 << 8) | '5'; break; - case eAGSKeyCode6: platformKey = (__allegro_KEY_6 << 8) | '6'; break; - case eAGSKeyCode7: platformKey = (__allegro_KEY_7 << 8) | '7'; break; - case eAGSKeyCode8: platformKey = (__allegro_KEY_8 << 8) | '8'; break; - case eAGSKeyCode9: platformKey = (__allegro_KEY_9 << 8) | '9'; break; + case eAGSKeyCode0: + platformKey = (__allegro_KEY_0 << 8) | '0'; + break; + case eAGSKeyCode1: + platformKey = (__allegro_KEY_1 << 8) | '1'; + break; + case eAGSKeyCode2: + platformKey = (__allegro_KEY_2 << 8) | '2'; + break; + case eAGSKeyCode3: + platformKey = (__allegro_KEY_3 << 8) | '3'; + break; + case eAGSKeyCode4: + platformKey = (__allegro_KEY_4 << 8) | '4'; + break; + case eAGSKeyCode5: + platformKey = (__allegro_KEY_5 << 8) | '5'; + break; + case eAGSKeyCode6: + platformKey = (__allegro_KEY_6 << 8) | '6'; + break; + case eAGSKeyCode7: + platformKey = (__allegro_KEY_7 << 8) | '7'; + break; + case eAGSKeyCode8: + platformKey = (__allegro_KEY_8 << 8) | '8'; + break; + case eAGSKeyCode9: + platformKey = (__allegro_KEY_9 << 8) | '9'; + break; - case eAGSKeyCodeA: platformKey = (__allegro_KEY_A << 8) | 'a'; break; - case eAGSKeyCodeB: platformKey = (__allegro_KEY_B << 8) | 'b'; break; - case eAGSKeyCodeC: platformKey = (__allegro_KEY_C << 8) | 'c'; break; - case eAGSKeyCodeD: platformKey = (__allegro_KEY_D << 8) | 'd'; break; - case eAGSKeyCodeE: platformKey = (__allegro_KEY_E << 8) | 'e'; break; - case eAGSKeyCodeF: platformKey = (__allegro_KEY_F << 8) | 'f'; break; - case eAGSKeyCodeG: platformKey = (__allegro_KEY_G << 8) | 'g'; break; - case eAGSKeyCodeH: platformKey = (__allegro_KEY_H << 8) | 'h'; break; - case eAGSKeyCodeI: platformKey = (__allegro_KEY_I << 8) | 'i'; break; - case eAGSKeyCodeJ: platformKey = (__allegro_KEY_J << 8) | 'j'; break; - case eAGSKeyCodeK: platformKey = (__allegro_KEY_K << 8) | 'k'; break; - case eAGSKeyCodeL: platformKey = (__allegro_KEY_L << 8) | 'l'; break; - case eAGSKeyCodeM: platformKey = (__allegro_KEY_M << 8) | 'm'; break; - case eAGSKeyCodeN: platformKey = (__allegro_KEY_N << 8) | 'n'; break; - case eAGSKeyCodeO: platformKey = (__allegro_KEY_O << 8) | 'o'; break; - case eAGSKeyCodeP: platformKey = (__allegro_KEY_P << 8) | 'p'; break; - case eAGSKeyCodeQ: platformKey = (__allegro_KEY_Q << 8) | 'q'; break; - case eAGSKeyCodeR: platformKey = (__allegro_KEY_R << 8) | 'r'; break; - case eAGSKeyCodeS: platformKey = (__allegro_KEY_S << 8) | 's'; break; - case eAGSKeyCodeT: platformKey = (__allegro_KEY_T << 8) | 't'; break; - case eAGSKeyCodeU: platformKey = (__allegro_KEY_U << 8) | 'u'; break; - case eAGSKeyCodeV: platformKey = (__allegro_KEY_V << 8) | 'v'; break; - case eAGSKeyCodeW: platformKey = (__allegro_KEY_W << 8) | 'w'; break; - case eAGSKeyCodeX: platformKey = (__allegro_KEY_X << 8) | 'x'; break; - case eAGSKeyCodeY: platformKey = (__allegro_KEY_Y << 8) | 'y'; break; - case eAGSKeyCodeZ: platformKey = (__allegro_KEY_Z << 8) | 'z'; break; + case eAGSKeyCodeA: + platformKey = (__allegro_KEY_A << 8) | 'a'; + break; + case eAGSKeyCodeB: + platformKey = (__allegro_KEY_B << 8) | 'b'; + break; + case eAGSKeyCodeC: + platformKey = (__allegro_KEY_C << 8) | 'c'; + break; + case eAGSKeyCodeD: + platformKey = (__allegro_KEY_D << 8) | 'd'; + break; + case eAGSKeyCodeE: + platformKey = (__allegro_KEY_E << 8) | 'e'; + break; + case eAGSKeyCodeF: + platformKey = (__allegro_KEY_F << 8) | 'f'; + break; + case eAGSKeyCodeG: + platformKey = (__allegro_KEY_G << 8) | 'g'; + break; + case eAGSKeyCodeH: + platformKey = (__allegro_KEY_H << 8) | 'h'; + break; + case eAGSKeyCodeI: + platformKey = (__allegro_KEY_I << 8) | 'i'; + break; + case eAGSKeyCodeJ: + platformKey = (__allegro_KEY_J << 8) | 'j'; + break; + case eAGSKeyCodeK: + platformKey = (__allegro_KEY_K << 8) | 'k'; + break; + case eAGSKeyCodeL: + platformKey = (__allegro_KEY_L << 8) | 'l'; + break; + case eAGSKeyCodeM: + platformKey = (__allegro_KEY_M << 8) | 'm'; + break; + case eAGSKeyCodeN: + platformKey = (__allegro_KEY_N << 8) | 'n'; + break; + case eAGSKeyCodeO: + platformKey = (__allegro_KEY_O << 8) | 'o'; + break; + case eAGSKeyCodeP: + platformKey = (__allegro_KEY_P << 8) | 'p'; + break; + case eAGSKeyCodeQ: + platformKey = (__allegro_KEY_Q << 8) | 'q'; + break; + case eAGSKeyCodeR: + platformKey = (__allegro_KEY_R << 8) | 'r'; + break; + case eAGSKeyCodeS: + platformKey = (__allegro_KEY_S << 8) | 's'; + break; + case eAGSKeyCodeT: + platformKey = (__allegro_KEY_T << 8) | 't'; + break; + case eAGSKeyCodeU: + platformKey = (__allegro_KEY_U << 8) | 'u'; + break; + case eAGSKeyCodeV: + platformKey = (__allegro_KEY_V << 8) | 'v'; + break; + case eAGSKeyCodeW: + platformKey = (__allegro_KEY_W << 8) | 'w'; + break; + case eAGSKeyCodeX: + platformKey = (__allegro_KEY_X << 8) | 'x'; + break; + case eAGSKeyCodeY: + platformKey = (__allegro_KEY_Y << 8) | 'y'; + break; + case eAGSKeyCodeZ: + platformKey = (__allegro_KEY_Z << 8) | 'z'; + break; - case eAGSKeyCodeF1: platformKey = __allegro_KEY_F1 << 8; break; - case eAGSKeyCodeF2: platformKey = __allegro_KEY_F2 << 8; break; - case eAGSKeyCodeF3: platformKey = __allegro_KEY_F3 << 8; break; - case eAGSKeyCodeF4: platformKey = __allegro_KEY_F4 << 8; break; - case eAGSKeyCodeF5: platformKey = __allegro_KEY_F5 << 8; break; - case eAGSKeyCodeF6: platformKey = __allegro_KEY_F6 << 8; break; - case eAGSKeyCodeF7: platformKey = __allegro_KEY_F7 << 8; break; - case eAGSKeyCodeF8: platformKey = __allegro_KEY_F8 << 8; break; - case eAGSKeyCodeF9: platformKey = __allegro_KEY_F9 << 8; break; - case eAGSKeyCodeF10: platformKey = __allegro_KEY_F10 << 8; break; - case eAGSKeyCodeF11: platformKey = __allegro_KEY_F11 << 8; break; - case eAGSKeyCodeF12: platformKey = __allegro_KEY_F12 << 8; break; + case eAGSKeyCodeF1: + platformKey = __allegro_KEY_F1 << 8; + break; + case eAGSKeyCodeF2: + platformKey = __allegro_KEY_F2 << 8; + break; + case eAGSKeyCodeF3: + platformKey = __allegro_KEY_F3 << 8; + break; + case eAGSKeyCodeF4: + platformKey = __allegro_KEY_F4 << 8; + break; + case eAGSKeyCodeF5: + platformKey = __allegro_KEY_F5 << 8; + break; + case eAGSKeyCodeF6: + platformKey = __allegro_KEY_F6 << 8; + break; + case eAGSKeyCodeF7: + platformKey = __allegro_KEY_F7 << 8; + break; + case eAGSKeyCodeF8: + platformKey = __allegro_KEY_F8 << 8; + break; + case eAGSKeyCodeF9: + platformKey = __allegro_KEY_F9 << 8; + break; + case eAGSKeyCodeF10: + platformKey = __allegro_KEY_F10 << 8; + break; + case eAGSKeyCodeF11: + platformKey = __allegro_KEY_F11 << 8; + break; + case eAGSKeyCodeF12: + platformKey = __allegro_KEY_F12 << 8; + break; - case eAGSKeyCodeHome: platformKey = __allegro_KEY_HOME << 8; break; - case eAGSKeyCodeUpArrow: platformKey = __allegro_KEY_UP << 8; break; - case eAGSKeyCodePageUp: platformKey = __allegro_KEY_PGUP << 8; break; - case eAGSKeyCodeLeftArrow: platformKey = __allegro_KEY_LEFT << 8; break; - case eAGSKeyCodeNumPad5: platformKey = __allegro_KEY_5_PAD << 8; break; - case eAGSKeyCodeRightArrow: platformKey = __allegro_KEY_RIGHT << 8; break; - case eAGSKeyCodeEnd: platformKey = __allegro_KEY_END << 8; break; - case eAGSKeyCodeDownArrow: platformKey = __allegro_KEY_DOWN << 8; break; - case eAGSKeyCodePageDown: platformKey = __allegro_KEY_PGDN << 8; break; - case eAGSKeyCodeInsert: platformKey = __allegro_KEY_INSERT << 8; break; - case eAGSKeyCodeDelete: platformKey = __allegro_KEY_DEL << 8; break; - } + case eAGSKeyCodeHome: + platformKey = __allegro_KEY_HOME << 8; + break; + case eAGSKeyCodeUpArrow: + platformKey = __allegro_KEY_UP << 8; + break; + case eAGSKeyCodePageUp: + platformKey = __allegro_KEY_PGUP << 8; + break; + case eAGSKeyCodeLeftArrow: + platformKey = __allegro_KEY_LEFT << 8; + break; + case eAGSKeyCodeNumPad5: + platformKey = __allegro_KEY_5_PAD << 8; + break; + case eAGSKeyCodeRightArrow: + platformKey = __allegro_KEY_RIGHT << 8; + break; + case eAGSKeyCodeEnd: + platformKey = __allegro_KEY_END << 8; + break; + case eAGSKeyCodeDownArrow: + platformKey = __allegro_KEY_DOWN << 8; + break; + case eAGSKeyCodePageDown: + platformKey = __allegro_KEY_PGDN << 8; + break; + case eAGSKeyCodeInsert: + platformKey = __allegro_KEY_INSERT << 8; + break; + case eAGSKeyCodeDelete: + platformKey = __allegro_KEY_DEL << 8; + break; + } - return platformKey; + return platformKey; } diff --git a/engines/ags/engine/ac/keycode.h b/engines/ags/engine/ac/keycode.h index 292274b60e7d..63c944bad889 100644 --- a/engines/ags/engine/ac/keycode.h +++ b/engines/ags/engine/ac/keycode.h @@ -31,138 +31,137 @@ #define AGS_EXT_KEY_SHIFT 300 // These are based on values in agsdefn.sh -enum eAGSKeyCode -{ - eAGSKeyCodeNone = 0, - - eAGSKeyCodeCtrlA = 1, - eAGSKeyCodeCtrlB = 2, - eAGSKeyCodeCtrlC = 3, - eAGSKeyCodeCtrlD = 4, - eAGSKeyCodeCtrlE = 5, - eAGSKeyCodeCtrlF = 6, - eAGSKeyCodeCtrlG = 7, - eAGSKeyCodeCtrlH = 8, - eAGSKeyCodeCtrlI = 9, - eAGSKeyCodeCtrlJ = 10, - eAGSKeyCodeCtrlK = 11, - eAGSKeyCodeCtrlL = 12, - eAGSKeyCodeCtrlM = 13, - eAGSKeyCodeCtrlN = 14, - eAGSKeyCodeCtrlO = 15, - eAGSKeyCodeCtrlP = 16, - eAGSKeyCodeCtrlQ = 17, - eAGSKeyCodeCtrlR = 18, - eAGSKeyCodeCtrlS = 19, - eAGSKeyCodeCtrlT = 20, - eAGSKeyCodeCtrlU = 21, - eAGSKeyCodeCtrlV = 22, - eAGSKeyCodeCtrlW = 23, - eAGSKeyCodeCtrlX = 24, - eAGSKeyCodeCtrlY = 25, - eAGSKeyCodeCtrlZ = 26, - - eAGSKeyCodeBackspace = 8, - eAGSKeyCodeTab = 9, - eAGSKeyCodeReturn = 13, - eAGSKeyCodeEscape = 27, - eAGSKeyCodeSpace = 32, - eAGSKeyCodeExclamationMark = 33, - eAGSKeyCodeDoubleQuote = 34, - eAGSKeyCodeHash = 35, - eAGSKeyCodeDollar = 36, - eAGSKeyCodePercent = 37, - eAGSKeyCodeAmpersand = 38, - eAGSKeyCodeSingleQuote = 39, - eAGSKeyCodeOpenParenthesis = 40, - eAGSKeyCodeCloseParenthesis = 41, - eAGSKeyCodeAsterisk = 42, - eAGSKeyCodePlus = 43, - eAGSKeyCodeComma = 44, - eAGSKeyCodeHyphen = 45, - eAGSKeyCodePeriod = 46, - eAGSKeyCodeForwardSlash = 47, - eAGSKeyCodeColon = 58, - eAGSKeyCodeSemiColon = 59, - eAGSKeyCodeLessThan = 60, - eAGSKeyCodeEquals = 61, - eAGSKeyCodeGreaterThan = 62, - eAGSKeyCodeQuestionMark = 63, - eAGSKeyCodeAt = 64, - eAGSKeyCodeOpenBracket = 91, - eAGSKeyCodeBackSlash = 92, - eAGSKeyCodeCloseBracket = 93, - eAGSKeyCodeUnderscore = 95, - - eAGSKeyCode0 = 48, - eAGSKeyCode1 = 49, - eAGSKeyCode2 = 50, - eAGSKeyCode3 = 51, - eAGSKeyCode4 = 52, - eAGSKeyCode5 = 53, - eAGSKeyCode6 = 54, - eAGSKeyCode7 = 55, - eAGSKeyCode8 = 56, - eAGSKeyCode9 = 57, - - eAGSKeyCodeA = 65, - eAGSKeyCodeB = 66, - eAGSKeyCodeC = 67, - eAGSKeyCodeD = 68, - eAGSKeyCodeE = 69, - eAGSKeyCodeF = 70, - eAGSKeyCodeG = 71, - eAGSKeyCodeH = 72, - eAGSKeyCodeI = 73, - eAGSKeyCodeJ = 74, - eAGSKeyCodeK = 75, - eAGSKeyCodeL = 76, - eAGSKeyCodeM = 77, - eAGSKeyCodeN = 78, - eAGSKeyCodeO = 79, - eAGSKeyCodeP = 80, - eAGSKeyCodeQ = 81, - eAGSKeyCodeR = 82, - eAGSKeyCodeS = 83, - eAGSKeyCodeT = 84, - eAGSKeyCodeU = 85, - eAGSKeyCodeV = 86, - eAGSKeyCodeW = 87, - eAGSKeyCodeX = 88, - eAGSKeyCodeY = 89, - eAGSKeyCodeZ = 90, - - eAGSKeyCodeF1 = AGS_EXT_KEY_SHIFT + 59, - eAGSKeyCodeF2 = AGS_EXT_KEY_SHIFT + 60, - eAGSKeyCodeF3 = AGS_EXT_KEY_SHIFT + 61, - eAGSKeyCodeF4 = AGS_EXT_KEY_SHIFT + 62, - eAGSKeyCodeF5 = AGS_EXT_KEY_SHIFT + 63, - eAGSKeyCodeF6 = AGS_EXT_KEY_SHIFT + 64, - eAGSKeyCodeF7 = AGS_EXT_KEY_SHIFT + 65, - eAGSKeyCodeF8 = AGS_EXT_KEY_SHIFT + 66, - eAGSKeyCodeF9 = AGS_EXT_KEY_SHIFT + 67, - eAGSKeyCodeF10 = AGS_EXT_KEY_SHIFT + 68, - eAGSKeyCodeF11 = AGS_EXT_KEY_SHIFT + 133, - eAGSKeyCodeF12 = AGS_EXT_KEY_SHIFT + 134, - - eAGSKeyCodeHome = AGS_EXT_KEY_SHIFT + 71, - eAGSKeyCodeUpArrow = AGS_EXT_KEY_SHIFT + 72, - eAGSKeyCodePageUp = AGS_EXT_KEY_SHIFT + 73, - eAGSKeyCodeLeftArrow = AGS_EXT_KEY_SHIFT + 75, - eAGSKeyCodeNumPad5 = AGS_EXT_KEY_SHIFT + 76, - eAGSKeyCodeRightArrow = AGS_EXT_KEY_SHIFT + 77, - eAGSKeyCodeEnd = AGS_EXT_KEY_SHIFT + 79, - eAGSKeyCodeDownArrow = AGS_EXT_KEY_SHIFT + 80, - eAGSKeyCodePageDown = AGS_EXT_KEY_SHIFT + 81, - eAGSKeyCodeInsert = AGS_EXT_KEY_SHIFT + 82, - eAGSKeyCodeDelete = AGS_EXT_KEY_SHIFT + 83, - - eAGSKeyCodeAltTab = AGS_EXT_KEY_SHIFT + 99, - - // These are only used by debugging and abort keys. - // They're based on allegro4 codes so I won't expand here. - eAGSKeyCodeAltV = 322, - eAGSKeyCodeAltX = 324 +enum eAGSKeyCode { + eAGSKeyCodeNone = 0, + + eAGSKeyCodeCtrlA = 1, + eAGSKeyCodeCtrlB = 2, + eAGSKeyCodeCtrlC = 3, + eAGSKeyCodeCtrlD = 4, + eAGSKeyCodeCtrlE = 5, + eAGSKeyCodeCtrlF = 6, + eAGSKeyCodeCtrlG = 7, + eAGSKeyCodeCtrlH = 8, + eAGSKeyCodeCtrlI = 9, + eAGSKeyCodeCtrlJ = 10, + eAGSKeyCodeCtrlK = 11, + eAGSKeyCodeCtrlL = 12, + eAGSKeyCodeCtrlM = 13, + eAGSKeyCodeCtrlN = 14, + eAGSKeyCodeCtrlO = 15, + eAGSKeyCodeCtrlP = 16, + eAGSKeyCodeCtrlQ = 17, + eAGSKeyCodeCtrlR = 18, + eAGSKeyCodeCtrlS = 19, + eAGSKeyCodeCtrlT = 20, + eAGSKeyCodeCtrlU = 21, + eAGSKeyCodeCtrlV = 22, + eAGSKeyCodeCtrlW = 23, + eAGSKeyCodeCtrlX = 24, + eAGSKeyCodeCtrlY = 25, + eAGSKeyCodeCtrlZ = 26, + + eAGSKeyCodeBackspace = 8, + eAGSKeyCodeTab = 9, + eAGSKeyCodeReturn = 13, + eAGSKeyCodeEscape = 27, + eAGSKeyCodeSpace = 32, + eAGSKeyCodeExclamationMark = 33, + eAGSKeyCodeDoubleQuote = 34, + eAGSKeyCodeHash = 35, + eAGSKeyCodeDollar = 36, + eAGSKeyCodePercent = 37, + eAGSKeyCodeAmpersand = 38, + eAGSKeyCodeSingleQuote = 39, + eAGSKeyCodeOpenParenthesis = 40, + eAGSKeyCodeCloseParenthesis = 41, + eAGSKeyCodeAsterisk = 42, + eAGSKeyCodePlus = 43, + eAGSKeyCodeComma = 44, + eAGSKeyCodeHyphen = 45, + eAGSKeyCodePeriod = 46, + eAGSKeyCodeForwardSlash = 47, + eAGSKeyCodeColon = 58, + eAGSKeyCodeSemiColon = 59, + eAGSKeyCodeLessThan = 60, + eAGSKeyCodeEquals = 61, + eAGSKeyCodeGreaterThan = 62, + eAGSKeyCodeQuestionMark = 63, + eAGSKeyCodeAt = 64, + eAGSKeyCodeOpenBracket = 91, + eAGSKeyCodeBackSlash = 92, + eAGSKeyCodeCloseBracket = 93, + eAGSKeyCodeUnderscore = 95, + + eAGSKeyCode0 = 48, + eAGSKeyCode1 = 49, + eAGSKeyCode2 = 50, + eAGSKeyCode3 = 51, + eAGSKeyCode4 = 52, + eAGSKeyCode5 = 53, + eAGSKeyCode6 = 54, + eAGSKeyCode7 = 55, + eAGSKeyCode8 = 56, + eAGSKeyCode9 = 57, + + eAGSKeyCodeA = 65, + eAGSKeyCodeB = 66, + eAGSKeyCodeC = 67, + eAGSKeyCodeD = 68, + eAGSKeyCodeE = 69, + eAGSKeyCodeF = 70, + eAGSKeyCodeG = 71, + eAGSKeyCodeH = 72, + eAGSKeyCodeI = 73, + eAGSKeyCodeJ = 74, + eAGSKeyCodeK = 75, + eAGSKeyCodeL = 76, + eAGSKeyCodeM = 77, + eAGSKeyCodeN = 78, + eAGSKeyCodeO = 79, + eAGSKeyCodeP = 80, + eAGSKeyCodeQ = 81, + eAGSKeyCodeR = 82, + eAGSKeyCodeS = 83, + eAGSKeyCodeT = 84, + eAGSKeyCodeU = 85, + eAGSKeyCodeV = 86, + eAGSKeyCodeW = 87, + eAGSKeyCodeX = 88, + eAGSKeyCodeY = 89, + eAGSKeyCodeZ = 90, + + eAGSKeyCodeF1 = AGS_EXT_KEY_SHIFT + 59, + eAGSKeyCodeF2 = AGS_EXT_KEY_SHIFT + 60, + eAGSKeyCodeF3 = AGS_EXT_KEY_SHIFT + 61, + eAGSKeyCodeF4 = AGS_EXT_KEY_SHIFT + 62, + eAGSKeyCodeF5 = AGS_EXT_KEY_SHIFT + 63, + eAGSKeyCodeF6 = AGS_EXT_KEY_SHIFT + 64, + eAGSKeyCodeF7 = AGS_EXT_KEY_SHIFT + 65, + eAGSKeyCodeF8 = AGS_EXT_KEY_SHIFT + 66, + eAGSKeyCodeF9 = AGS_EXT_KEY_SHIFT + 67, + eAGSKeyCodeF10 = AGS_EXT_KEY_SHIFT + 68, + eAGSKeyCodeF11 = AGS_EXT_KEY_SHIFT + 133, + eAGSKeyCodeF12 = AGS_EXT_KEY_SHIFT + 134, + + eAGSKeyCodeHome = AGS_EXT_KEY_SHIFT + 71, + eAGSKeyCodeUpArrow = AGS_EXT_KEY_SHIFT + 72, + eAGSKeyCodePageUp = AGS_EXT_KEY_SHIFT + 73, + eAGSKeyCodeLeftArrow = AGS_EXT_KEY_SHIFT + 75, + eAGSKeyCodeNumPad5 = AGS_EXT_KEY_SHIFT + 76, + eAGSKeyCodeRightArrow = AGS_EXT_KEY_SHIFT + 77, + eAGSKeyCodeEnd = AGS_EXT_KEY_SHIFT + 79, + eAGSKeyCodeDownArrow = AGS_EXT_KEY_SHIFT + 80, + eAGSKeyCodePageDown = AGS_EXT_KEY_SHIFT + 81, + eAGSKeyCodeInsert = AGS_EXT_KEY_SHIFT + 82, + eAGSKeyCodeDelete = AGS_EXT_KEY_SHIFT + 83, + + eAGSKeyCodeAltTab = AGS_EXT_KEY_SHIFT + 99, + + // These are only used by debugging and abort keys. + // They're based on allegro4 codes so I won't expand here. + eAGSKeyCodeAltV = 322, + eAGSKeyCodeAltX = 324 }; #define AGS_KEYCODE_INSERT (eAGSKeyCodeInsert) diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp index d16026956c5f..077a81b34aa6 100644 --- a/engines/ags/engine/ac/label.cpp +++ b/engines/ags/engine/ac/label.cpp @@ -31,59 +31,57 @@ extern GameSetupStruct game; // ** LABEL FUNCTIONS -const char* Label_GetText_New(GUILabel *labl) { - return CreateNewScriptString(labl->GetText()); +const char *Label_GetText_New(GUILabel *labl) { + return CreateNewScriptString(labl->GetText()); } void Label_GetText(GUILabel *labl, char *buffer) { - strcpy(buffer, labl->GetText()); + strcpy(buffer, labl->GetText()); } void Label_SetText(GUILabel *labl, const char *newtx) { - newtx = get_translation(newtx); + newtx = get_translation(newtx); - if (strcmp(labl->GetText(), newtx)) { - guis_need_update = 1; - labl->SetText(newtx); - } + if (strcmp(labl->GetText(), newtx)) { + guis_need_update = 1; + labl->SetText(newtx); + } } -int Label_GetTextAlignment(GUILabel *labl) -{ - return labl->TextAlignment; +int Label_GetTextAlignment(GUILabel *labl) { + return labl->TextAlignment; } -void Label_SetTextAlignment(GUILabel *labl, int align) -{ - if (labl->TextAlignment != align) { - labl->TextAlignment = (HorAlignment)align; - guis_need_update = 1; - } +void Label_SetTextAlignment(GUILabel *labl, int align) { + if (labl->TextAlignment != align) { + labl->TextAlignment = (HorAlignment)align; + guis_need_update = 1; + } } int Label_GetColor(GUILabel *labl) { - return labl->TextColor; + return labl->TextColor; } void Label_SetColor(GUILabel *labl, int colr) { - if (labl->TextColor != colr) { - labl->TextColor = colr; - guis_need_update = 1; - } + if (labl->TextColor != colr) { + labl->TextColor = colr; + guis_need_update = 1; + } } int Label_GetFont(GUILabel *labl) { - return labl->Font; + return labl->Font; } void Label_SetFont(GUILabel *guil, int fontnum) { - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!SetLabelFont: invalid font number."); + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetLabelFont: invalid font number."); - if (fontnum != guil->Font) { - guil->Font = fontnum; - guis_need_update = 1; - } + if (fontnum != guil->Font) { + guil->Font = fontnum; + guis_need_update = 1; + } } //============================================================================= @@ -100,81 +98,71 @@ void Label_SetFont(GUILabel *guil, int fontnum) { extern ScriptString myScriptStringImpl; // void (GUILabel *labl, char *buffer) -RuntimeScriptValue Sc_Label_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUILabel, Label_GetText, char); +RuntimeScriptValue Sc_Label_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUILabel, Label_GetText, char); } // void (GUILabel *labl, const char *newtx) -RuntimeScriptValue Sc_Label_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUILabel, Label_SetText, const char); +RuntimeScriptValue Sc_Label_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUILabel, Label_SetText, const char); } -RuntimeScriptValue Sc_Label_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUILabel, Label_GetTextAlignment); +RuntimeScriptValue Sc_Label_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUILabel, Label_GetTextAlignment); } -RuntimeScriptValue Sc_Label_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUILabel, Label_SetTextAlignment); +RuntimeScriptValue Sc_Label_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUILabel, Label_SetTextAlignment); } // int (GUILabel *labl) -RuntimeScriptValue Sc_Label_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUILabel, Label_GetFont); +RuntimeScriptValue Sc_Label_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUILabel, Label_GetFont); } // void (GUILabel *guil, int fontnum) -RuntimeScriptValue Sc_Label_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUILabel, Label_SetFont); +RuntimeScriptValue Sc_Label_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUILabel, Label_SetFont); } // const char* (GUILabel *labl) -RuntimeScriptValue Sc_Label_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUILabel, const char, myScriptStringImpl, Label_GetText_New); +RuntimeScriptValue Sc_Label_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUILabel, const char, myScriptStringImpl, Label_GetText_New); } // int (GUILabel *labl) -RuntimeScriptValue Sc_Label_GetColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUILabel, Label_GetColor); +RuntimeScriptValue Sc_Label_GetColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUILabel, Label_GetColor); } // void (GUILabel *labl, int colr) -RuntimeScriptValue Sc_Label_SetColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUILabel, Label_SetColor); -} - - - -void RegisterLabelAPI() -{ - ccAddExternalObjectFunction("Label::GetText^1", Sc_Label_GetText); - ccAddExternalObjectFunction("Label::SetText^1", Sc_Label_SetText); - ccAddExternalObjectFunction("Label::get_TextAlignment", Sc_Label_GetTextAlignment); - ccAddExternalObjectFunction("Label::set_TextAlignment", Sc_Label_SetTextAlignment); - ccAddExternalObjectFunction("Label::get_Font", Sc_Label_GetFont); - ccAddExternalObjectFunction("Label::set_Font", Sc_Label_SetFont); - ccAddExternalObjectFunction("Label::get_Text", Sc_Label_GetText_New); - ccAddExternalObjectFunction("Label::set_Text", Sc_Label_SetText); - ccAddExternalObjectFunction("Label::get_TextColor", Sc_Label_GetColor); - ccAddExternalObjectFunction("Label::set_TextColor", Sc_Label_SetColor); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Label::GetText^1", (void*)Label_GetText); - ccAddExternalFunctionForPlugin("Label::SetText^1", (void*)Label_SetText); - ccAddExternalFunctionForPlugin("Label::get_Font", (void*)Label_GetFont); - ccAddExternalFunctionForPlugin("Label::set_Font", (void*)Label_SetFont); - ccAddExternalFunctionForPlugin("Label::get_Text", (void*)Label_GetText_New); - ccAddExternalFunctionForPlugin("Label::set_Text", (void*)Label_SetText); - ccAddExternalFunctionForPlugin("Label::get_TextColor", (void*)Label_GetColor); - ccAddExternalFunctionForPlugin("Label::set_TextColor", (void*)Label_SetColor); +RuntimeScriptValue Sc_Label_SetColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUILabel, Label_SetColor); +} + + + +void RegisterLabelAPI() { + ccAddExternalObjectFunction("Label::GetText^1", Sc_Label_GetText); + ccAddExternalObjectFunction("Label::SetText^1", Sc_Label_SetText); + ccAddExternalObjectFunction("Label::get_TextAlignment", Sc_Label_GetTextAlignment); + ccAddExternalObjectFunction("Label::set_TextAlignment", Sc_Label_SetTextAlignment); + ccAddExternalObjectFunction("Label::get_Font", Sc_Label_GetFont); + ccAddExternalObjectFunction("Label::set_Font", Sc_Label_SetFont); + ccAddExternalObjectFunction("Label::get_Text", Sc_Label_GetText_New); + ccAddExternalObjectFunction("Label::set_Text", Sc_Label_SetText); + ccAddExternalObjectFunction("Label::get_TextColor", Sc_Label_GetColor); + ccAddExternalObjectFunction("Label::set_TextColor", Sc_Label_SetColor); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Label::GetText^1", (void *)Label_GetText); + ccAddExternalFunctionForPlugin("Label::SetText^1", (void *)Label_SetText); + ccAddExternalFunctionForPlugin("Label::get_Font", (void *)Label_GetFont); + ccAddExternalFunctionForPlugin("Label::set_Font", (void *)Label_SetFont); + ccAddExternalFunctionForPlugin("Label::get_Text", (void *)Label_GetText_New); + ccAddExternalFunctionForPlugin("Label::set_Text", (void *)Label_SetText); + ccAddExternalFunctionForPlugin("Label::get_TextColor", (void *)Label_GetColor); + ccAddExternalFunctionForPlugin("Label::set_TextColor", (void *)Label_SetColor); } diff --git a/engines/ags/engine/ac/label.h b/engines/ags/engine/ac/label.h index 8aa5976cd5cc..687c77c0f886 100644 --- a/engines/ags/engine/ac/label.h +++ b/engines/ags/engine/ac/label.h @@ -27,12 +27,12 @@ using AGS::Common::GUILabel; -const char* Label_GetText_New(GUILabel *labl); -void Label_GetText(GUILabel *labl, char *buffer); -void Label_SetText(GUILabel *labl, const char *newtx); -int Label_GetColor(GUILabel *labl); -void Label_SetColor(GUILabel *labl, int colr); -int Label_GetFont(GUILabel *labl); -void Label_SetFont(GUILabel *guil, int fontnum); +const char *Label_GetText_New(GUILabel *labl); +void Label_GetText(GUILabel *labl, char *buffer); +void Label_SetText(GUILabel *labl, const char *newtx); +int Label_GetColor(GUILabel *labl); +void Label_SetColor(GUILabel *labl, int colr); +int Label_GetFont(GUILabel *labl); +void Label_SetFont(GUILabel *guil, int fontnum); #endif diff --git a/engines/ags/engine/ac/lipsync.h b/engines/ags/engine/ac/lipsync.h index 694d02489f7b..6508c6813f6d 100644 --- a/engines/ags/engine/ac/lipsync.h +++ b/engines/ags/engine/ac/lipsync.h @@ -24,10 +24,10 @@ #define AGS_ENGINE_AC_LIPSYNC_H struct SpeechLipSyncLine { - char filename[14]; - int *endtimeoffs; - short*frame; - short numPhonemes; + char filename[14]; + int *endtimeoffs; + short *frame; + short numPhonemes; }; #endif diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index 142b75e2aa19..ca42a539fb8e 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -40,343 +40,340 @@ extern GameSetupStruct game; // *** LIST BOX FUNCTIONS int ListBox_AddItem(GUIListBox *lbb, const char *text) { - if (lbb->AddItem(text) < 0) - return 0; + if (lbb->AddItem(text) < 0) + return 0; - guis_need_update = 1; - return 1; + guis_need_update = 1; + return 1; } int ListBox_InsertItemAt(GUIListBox *lbb, int index, const char *text) { - if (lbb->InsertItem(index, text) < 0) - return 0; + if (lbb->InsertItem(index, text) < 0) + return 0; - guis_need_update = 1; - return 1; + guis_need_update = 1; + return 1; } void ListBox_Clear(GUIListBox *listbox) { - listbox->Clear(); - guis_need_update = 1; + listbox->Clear(); + guis_need_update = 1; } -void FillDirList(std::set &files, const String &path) -{ - al_ffblk dfb; - int dun = al_findfirst(path, &dfb, FA_SEARCH); - while (!dun) { - files.insert(dfb.name); - dun = al_findnext(&dfb); - } - al_findclose(&dfb); +void FillDirList(std::set &files, const String &path) { + al_ffblk dfb; + int dun = al_findfirst(path, &dfb, FA_SEARCH); + while (!dun) { + files.insert(dfb.name); + dun = al_findnext(&dfb); + } + al_findclose(&dfb); } void ListBox_FillDirList(GUIListBox *listbox, const char *filemask) { - listbox->Clear(); - guis_need_update = 1; + listbox->Clear(); + guis_need_update = 1; - ResolvedPath rp; - if (!ResolveScriptPath(filemask, true, rp)) - return; + ResolvedPath rp; + if (!ResolveScriptPath(filemask, true, rp)) + return; - std::set files; - FillDirList(files, rp.FullPath); - if (!rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) - FillDirList(files, rp.AltPath); + std::set files; + FillDirList(files, rp.FullPath); + if (!rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) + FillDirList(files, rp.AltPath); - for (std::set::const_iterator it = files.begin(); it != files.end(); ++it) - { - listbox->AddItem(*it); - } + for (std::set::const_iterator it = files.begin(); it != files.end(); ++it) { + listbox->AddItem(*it); + } } int ListBox_GetSaveGameSlots(GUIListBox *listbox, int index) { - if ((index < 0) || (index >= listbox->ItemCount)) - quit("!ListBox.SaveGameSlot: index out of range"); + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBox.SaveGameSlot: index out of range"); - return listbox->SavedGameIndex[index]; + return listbox->SavedGameIndex[index]; } int ListBox_FillSaveGameList(GUIListBox *listbox) { - listbox->Clear(); - - int numsaves=0; - int bufix=0; - al_ffblk ffb; - long filedates[MAXSAVEGAMES]; - char buff[200]; - - String svg_dir = get_save_game_directory(); - String searchPath = String::FromFormat("%s""agssave.*", svg_dir.GetCStr()); - - int don = al_findfirst(searchPath, &ffb, FA_SEARCH); - while (!don) { - bufix=0; - if (numsaves >= MAXSAVEGAMES) - break; - // only list games .000 to .099 (to allow higher slots for other perposes) - if (strstr(ffb.name,".0")==nullptr) { - don = al_findnext(&ffb); - continue; - } - const char *numberExtension = strstr(ffb.name, ".0") + 1; - int saveGameSlot = atoi(numberExtension); - GetSaveSlotDescription(saveGameSlot, buff); - listbox->AddItem(buff); - listbox->SavedGameIndex[numsaves] = saveGameSlot; - filedates[numsaves]=(long int)ffb.time; - numsaves++; - don = al_findnext(&ffb); - } - al_findclose(&ffb); - - int nn; - for (nn=0;nnItems[kk]; - listbox->Items[kk] = listbox->Items[kk+1]; - listbox->Items[kk+1] = tempptr; - int numtem = listbox->SavedGameIndex[kk]; - listbox->SavedGameIndex[kk] = listbox->SavedGameIndex[kk+1]; - listbox->SavedGameIndex[kk+1] = numtem; - long numted=filedates[kk]; filedates[kk]=filedates[kk+1]; - filedates[kk+1]=numted; - } - } - } - - // update the global savegameindex[] array for backward compatibilty - for (nn = 0; nn < numsaves; nn++) { - play.filenumbers[nn] = listbox->SavedGameIndex[nn]; - } - - guis_need_update = 1; - listbox->SetSvgIndex(true); - - if (numsaves >= MAXSAVEGAMES) - return 1; - return 0; + listbox->Clear(); + + int numsaves = 0; + int bufix = 0; + al_ffblk ffb; + long filedates[MAXSAVEGAMES]; + char buff[200]; + + String svg_dir = get_save_game_directory(); + String searchPath = String::FromFormat("%s""agssave.*", svg_dir.GetCStr()); + + int don = al_findfirst(searchPath, &ffb, FA_SEARCH); + while (!don) { + bufix = 0; + if (numsaves >= MAXSAVEGAMES) + break; + // only list games .000 to .099 (to allow higher slots for other perposes) + if (strstr(ffb.name, ".0") == nullptr) { + don = al_findnext(&ffb); + continue; + } + const char *numberExtension = strstr(ffb.name, ".0") + 1; + int saveGameSlot = atoi(numberExtension); + GetSaveSlotDescription(saveGameSlot, buff); + listbox->AddItem(buff); + listbox->SavedGameIndex[numsaves] = saveGameSlot; + filedates[numsaves] = (long int)ffb.time; + numsaves++; + don = al_findnext(&ffb); + } + al_findclose(&ffb); + + int nn; + for (nn = 0; nn < numsaves - 1; nn++) { + for (int kk = 0; kk < numsaves - 1; kk++) { // Date order the games + + if (filedates[kk] < filedates[kk + 1]) { // swap them round + String tempptr = listbox->Items[kk]; + listbox->Items[kk] = listbox->Items[kk + 1]; + listbox->Items[kk + 1] = tempptr; + int numtem = listbox->SavedGameIndex[kk]; + listbox->SavedGameIndex[kk] = listbox->SavedGameIndex[kk + 1]; + listbox->SavedGameIndex[kk + 1] = numtem; + long numted = filedates[kk]; + filedates[kk] = filedates[kk + 1]; + filedates[kk + 1] = numted; + } + } + } + + // update the global savegameindex[] array for backward compatibilty + for (nn = 0; nn < numsaves; nn++) { + play.filenumbers[nn] = listbox->SavedGameIndex[nn]; + } + + guis_need_update = 1; + listbox->SetSvgIndex(true); + + if (numsaves >= MAXSAVEGAMES) + return 1; + return 0; } int ListBox_GetItemAtLocation(GUIListBox *listbox, int x, int y) { - if (!guis[listbox->ParentId].IsDisplayed()) - return -1; + if (!guis[listbox->ParentId].IsDisplayed()) + return -1; - data_to_game_coords(&x, &y); - x = (x - listbox->X) - guis[listbox->ParentId].X; - y = (y - listbox->Y) - guis[listbox->ParentId].Y; + data_to_game_coords(&x, &y); + x = (x - listbox->X) - guis[listbox->ParentId].X; + y = (y - listbox->Y) - guis[listbox->ParentId].Y; - if ((x < 0) || (y < 0) || (x >= listbox->Width) || (y >= listbox->Height)) - return -1; - - return listbox->GetItemAt(x, y); + if ((x < 0) || (y < 0) || (x >= listbox->Width) || (y >= listbox->Height)) + return -1; + + return listbox->GetItemAt(x, y); } char *ListBox_GetItemText(GUIListBox *listbox, int index, char *buffer) { - if ((index < 0) || (index >= listbox->ItemCount)) - quit("!ListBoxGetItemText: invalid item specified"); - strncpy(buffer, listbox->Items[index],198); - buffer[199] = 0; - return buffer; + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBoxGetItemText: invalid item specified"); + strncpy(buffer, listbox->Items[index], 198); + buffer[199] = 0; + return buffer; } -const char* ListBox_GetItems(GUIListBox *listbox, int index) { - if ((index < 0) || (index >= listbox->ItemCount)) - quit("!ListBox.Items: invalid index specified"); +const char *ListBox_GetItems(GUIListBox *listbox, int index) { + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBox.Items: invalid index specified"); - return CreateNewScriptString(listbox->Items[index]); + return CreateNewScriptString(listbox->Items[index]); } void ListBox_SetItemText(GUIListBox *listbox, int index, const char *newtext) { - if ((index < 0) || (index >= listbox->ItemCount)) - quit("!ListBoxSetItemText: invalid item specified"); + if ((index < 0) || (index >= listbox->ItemCount)) + quit("!ListBoxSetItemText: invalid item specified"); - if (strcmp(listbox->Items[index], newtext)) { - listbox->SetItemText(index, newtext); - guis_need_update = 1; - } + if (strcmp(listbox->Items[index], newtext)) { + listbox->SetItemText(index, newtext); + guis_need_update = 1; + } } void ListBox_RemoveItem(GUIListBox *listbox, int itemIndex) { - - if ((itemIndex < 0) || (itemIndex >= listbox->ItemCount)) - quit("!ListBoxRemove: invalid listindex specified"); - listbox->RemoveItem(itemIndex); - guis_need_update = 1; + if ((itemIndex < 0) || (itemIndex >= listbox->ItemCount)) + quit("!ListBoxRemove: invalid listindex specified"); + + listbox->RemoveItem(itemIndex); + guis_need_update = 1; } int ListBox_GetItemCount(GUIListBox *listbox) { - return listbox->ItemCount; + return listbox->ItemCount; } int ListBox_GetFont(GUIListBox *listbox) { - return listbox->Font; + return listbox->Font; } void ListBox_SetFont(GUIListBox *listbox, int newfont) { - if ((newfont < 0) || (newfont >= game.numfonts)) - quit("!ListBox.Font: invalid font number."); + if ((newfont < 0) || (newfont >= game.numfonts)) + quit("!ListBox.Font: invalid font number."); - if (newfont != listbox->Font) { - listbox->SetFont(newfont); - guis_need_update = 1; - } + if (newfont != listbox->Font) { + listbox->SetFont(newfont); + guis_need_update = 1; + } } bool ListBox_GetShowBorder(GUIListBox *listbox) { - return listbox->IsBorderShown(); + return listbox->IsBorderShown(); } void ListBox_SetShowBorder(GUIListBox *listbox, bool newValue) { - if (listbox->IsBorderShown() != newValue) - { - listbox->SetShowBorder(newValue); - guis_need_update = 1; - } + if (listbox->IsBorderShown() != newValue) { + listbox->SetShowBorder(newValue); + guis_need_update = 1; + } } bool ListBox_GetShowScrollArrows(GUIListBox *listbox) { - return listbox->AreArrowsShown(); + return listbox->AreArrowsShown(); } void ListBox_SetShowScrollArrows(GUIListBox *listbox, bool newValue) { - if (listbox->AreArrowsShown() != newValue) - { - listbox->SetShowArrows(newValue); - guis_need_update = 1; - } + if (listbox->AreArrowsShown() != newValue) { + listbox->SetShowArrows(newValue); + guis_need_update = 1; + } } int ListBox_GetHideBorder(GUIListBox *listbox) { - return !ListBox_GetShowBorder(listbox); + return !ListBox_GetShowBorder(listbox); } void ListBox_SetHideBorder(GUIListBox *listbox, int newValue) { - ListBox_SetShowBorder(listbox, !newValue); + ListBox_SetShowBorder(listbox, !newValue); } int ListBox_GetHideScrollArrows(GUIListBox *listbox) { - return !ListBox_GetShowScrollArrows(listbox); + return !ListBox_GetShowScrollArrows(listbox); } void ListBox_SetHideScrollArrows(GUIListBox *listbox, int newValue) { - ListBox_SetShowScrollArrows(listbox, !newValue); + ListBox_SetShowScrollArrows(listbox, !newValue); } int ListBox_GetSelectedBackColor(GUIListBox *listbox) { - return listbox->SelectedBgColor; + return listbox->SelectedBgColor; } void ListBox_SetSelectedBackColor(GUIListBox *listbox, int colr) { - if (listbox->SelectedBgColor != colr) { - listbox->SelectedBgColor = colr; - guis_need_update = 1; - } + if (listbox->SelectedBgColor != colr) { + listbox->SelectedBgColor = colr; + guis_need_update = 1; + } } int ListBox_GetSelectedTextColor(GUIListBox *listbox) { - return listbox->SelectedTextColor; + return listbox->SelectedTextColor; } void ListBox_SetSelectedTextColor(GUIListBox *listbox, int colr) { - if (listbox->SelectedTextColor != colr) { - listbox->SelectedTextColor = colr; - guis_need_update = 1; - } + if (listbox->SelectedTextColor != colr) { + listbox->SelectedTextColor = colr; + guis_need_update = 1; + } } int ListBox_GetTextAlignment(GUIListBox *listbox) { - return listbox->TextAlignment; + return listbox->TextAlignment; } void ListBox_SetTextAlignment(GUIListBox *listbox, int align) { - if (listbox->TextAlignment != align) { - listbox->TextAlignment = (HorAlignment)align; - guis_need_update = 1; - } + if (listbox->TextAlignment != align) { + listbox->TextAlignment = (HorAlignment)align; + guis_need_update = 1; + } } int ListBox_GetTextColor(GUIListBox *listbox) { - return listbox->TextColor; + return listbox->TextColor; } void ListBox_SetTextColor(GUIListBox *listbox, int colr) { - if (listbox->TextColor != colr) { - listbox->TextColor = colr; - guis_need_update = 1; - } + if (listbox->TextColor != colr) { + listbox->TextColor = colr; + guis_need_update = 1; + } } int ListBox_GetSelectedIndex(GUIListBox *listbox) { - if ((listbox->SelectedItem < 0) || (listbox->SelectedItem >= listbox->ItemCount)) - return -1; - return listbox->SelectedItem; + if ((listbox->SelectedItem < 0) || (listbox->SelectedItem >= listbox->ItemCount)) + return -1; + return listbox->SelectedItem; } void ListBox_SetSelectedIndex(GUIListBox *guisl, int newsel) { - if (newsel >= guisl->ItemCount) - newsel = -1; + if (newsel >= guisl->ItemCount) + newsel = -1; - if (guisl->SelectedItem != newsel) { - guisl->SelectedItem = newsel; - if (newsel >= 0) { - if (newsel < guisl->TopItem) - guisl->TopItem = newsel; - if (newsel >= guisl->TopItem + guisl->VisibleItemCount) - guisl->TopItem = (newsel - guisl->VisibleItemCount) + 1; - } - guis_need_update = 1; - } + if (guisl->SelectedItem != newsel) { + guisl->SelectedItem = newsel; + if (newsel >= 0) { + if (newsel < guisl->TopItem) + guisl->TopItem = newsel; + if (newsel >= guisl->TopItem + guisl->VisibleItemCount) + guisl->TopItem = (newsel - guisl->VisibleItemCount) + 1; + } + guis_need_update = 1; + } } int ListBox_GetTopItem(GUIListBox *listbox) { - return listbox->TopItem; + return listbox->TopItem; } void ListBox_SetTopItem(GUIListBox *guisl, int item) { - if ((guisl->ItemCount == 0) && (item == 0)) - ; // allow resetting an empty box to the top - else if ((item >= guisl->ItemCount) || (item < 0)) - quit("!ListBoxSetTopItem: tried to set top to beyond top or bottom of list"); + if ((guisl->ItemCount == 0) && (item == 0)) + ; // allow resetting an empty box to the top + else if ((item >= guisl->ItemCount) || (item < 0)) + quit("!ListBoxSetTopItem: tried to set top to beyond top or bottom of list"); - guisl->TopItem = item; - guis_need_update = 1; + guisl->TopItem = item; + guis_need_update = 1; } int ListBox_GetRowCount(GUIListBox *listbox) { - return listbox->VisibleItemCount; + return listbox->VisibleItemCount; } void ListBox_ScrollDown(GUIListBox *listbox) { - if (listbox->TopItem + listbox->VisibleItemCount < listbox->ItemCount) { - listbox->TopItem++; - guis_need_update = 1; - } + if (listbox->TopItem + listbox->VisibleItemCount < listbox->ItemCount) { + listbox->TopItem++; + guis_need_update = 1; + } } void ListBox_ScrollUp(GUIListBox *listbox) { - if (listbox->TopItem > 0) { - listbox->TopItem--; - guis_need_update = 1; - } + if (listbox->TopItem > 0) { + listbox->TopItem--; + guis_need_update = 1; + } } -GUIListBox* is_valid_listbox (int guin, int objn) { - if ((guin<0) | (guin>=game.numgui)) quit("!ListBox: invalid GUI number"); - if ((objn<0) | (objn>=guis[guin].GetControlCount())) quit("!ListBox: invalid object number"); - if (guis[guin].GetControlType(objn)!=kGUIListBox) - quit("!ListBox: specified control is not a list box"); - guis_need_update = 1; - return (GUIListBox*)guis[guin].GetControl(objn); +GUIListBox *is_valid_listbox(int guin, int objn) { + if ((guin < 0) | (guin >= game.numgui)) quit("!ListBox: invalid GUI number"); + if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!ListBox: invalid object number"); + if (guis[guin].GetControlType(objn) != kGUIListBox) + quit("!ListBox: specified control is not a list box"); + guis_need_update = 1; + return (GUIListBox *)guis[guin].GetControl(objn); } //============================================================================= @@ -393,290 +390,252 @@ GUIListBox* is_valid_listbox (int guin, int objn) { extern ScriptString myScriptStringImpl; // int (GUIListBox *lbb, const char *text) -RuntimeScriptValue Sc_ListBox_AddItem(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(GUIListBox, ListBox_AddItem, const char); +RuntimeScriptValue Sc_ListBox_AddItem(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(GUIListBox, ListBox_AddItem, const char); } // void (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(GUIListBox, ListBox_Clear); +RuntimeScriptValue Sc_ListBox_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(GUIListBox, ListBox_Clear); } // void (GUIListBox *listbox, const char *filemask) -RuntimeScriptValue Sc_ListBox_FillDirList(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUIListBox, ListBox_FillDirList, const char); +RuntimeScriptValue Sc_ListBox_FillDirList(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUIListBox, ListBox_FillDirList, const char); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_FillSaveGameList(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_FillSaveGameList); +RuntimeScriptValue Sc_ListBox_FillSaveGameList(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_FillSaveGameList); } // int (GUIListBox *listbox, int x, int y) -RuntimeScriptValue Sc_ListBox_GetItemAtLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT2(GUIListBox, ListBox_GetItemAtLocation); +RuntimeScriptValue Sc_ListBox_GetItemAtLocation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT2(GUIListBox, ListBox_GetItemAtLocation); } // char *(GUIListBox *listbox, int index, char *buffer) -RuntimeScriptValue Sc_ListBox_GetItemText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT_POBJ(GUIListBox, char, myScriptStringImpl, ListBox_GetItemText, char); +RuntimeScriptValue Sc_ListBox_GetItemText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT_POBJ(GUIListBox, char, myScriptStringImpl, ListBox_GetItemText, char); } // int (GUIListBox *lbb, int index, const char *text) -RuntimeScriptValue Sc_ListBox_InsertItemAt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT_POBJ(GUIListBox, ListBox_InsertItemAt, const char); +RuntimeScriptValue Sc_ListBox_InsertItemAt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT_POBJ(GUIListBox, ListBox_InsertItemAt, const char); } // void (GUIListBox *listbox, int itemIndex) -RuntimeScriptValue Sc_ListBox_RemoveItem(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_RemoveItem); +RuntimeScriptValue Sc_ListBox_RemoveItem(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_RemoveItem); } // void (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(GUIListBox, ListBox_ScrollDown); +RuntimeScriptValue Sc_ListBox_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(GUIListBox, ListBox_ScrollDown); } // void (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_ScrollUp(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(GUIListBox, ListBox_ScrollUp); +RuntimeScriptValue Sc_ListBox_ScrollUp(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(GUIListBox, ListBox_ScrollUp); } // void (GUIListBox *listbox, int index, const char *newtext) -RuntimeScriptValue Sc_ListBox_SetItemText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT_POBJ(GUIListBox, ListBox_SetItemText, const char); +RuntimeScriptValue Sc_ListBox_SetItemText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT_POBJ(GUIListBox, ListBox_SetItemText, const char); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetFont); +RuntimeScriptValue Sc_ListBox_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetFont); } // void (GUIListBox *listbox, int newfont) -RuntimeScriptValue Sc_ListBox_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetFont); +RuntimeScriptValue Sc_ListBox_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetFont); } -RuntimeScriptValue Sc_ListBox_GetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(GUIListBox, ListBox_GetShowBorder); +RuntimeScriptValue Sc_ListBox_GetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(GUIListBox, ListBox_GetShowBorder); } -RuntimeScriptValue Sc_ListBox_SetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PBOOL(GUIListBox, ListBox_SetShowBorder); +RuntimeScriptValue Sc_ListBox_SetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PBOOL(GUIListBox, ListBox_SetShowBorder); } -RuntimeScriptValue Sc_ListBox_GetShowScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(GUIListBox, ListBox_GetShowScrollArrows); +RuntimeScriptValue Sc_ListBox_GetShowScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(GUIListBox, ListBox_GetShowScrollArrows); } -RuntimeScriptValue Sc_ListBox_SetShowScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PBOOL(GUIListBox, ListBox_SetShowScrollArrows); +RuntimeScriptValue Sc_ListBox_SetShowScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PBOOL(GUIListBox, ListBox_SetShowScrollArrows); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_GetHideBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetHideBorder); +RuntimeScriptValue Sc_ListBox_GetHideBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetHideBorder); } // void (GUIListBox *listbox, int newValue) -RuntimeScriptValue Sc_ListBox_SetHideBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetHideBorder); +RuntimeScriptValue Sc_ListBox_SetHideBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetHideBorder); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_GetHideScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetHideScrollArrows); +RuntimeScriptValue Sc_ListBox_GetHideScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetHideScrollArrows); } // void (GUIListBox *listbox, int newValue) -RuntimeScriptValue Sc_ListBox_SetHideScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetHideScrollArrows); +RuntimeScriptValue Sc_ListBox_SetHideScrollArrows(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetHideScrollArrows); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetItemCount); +RuntimeScriptValue Sc_ListBox_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetItemCount); } // const char* (GUIListBox *listbox, int index) -RuntimeScriptValue Sc_ListBox_GetItems(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT(GUIListBox, const char, myScriptStringImpl, ListBox_GetItems); +RuntimeScriptValue Sc_ListBox_GetItems(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT(GUIListBox, const char, myScriptStringImpl, ListBox_GetItems); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_GetRowCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetRowCount); +RuntimeScriptValue Sc_ListBox_GetRowCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetRowCount); } // int (GUIListBox *listbox, int index) -RuntimeScriptValue Sc_ListBox_GetSaveGameSlots(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(GUIListBox, ListBox_GetSaveGameSlots); +RuntimeScriptValue Sc_ListBox_GetSaveGameSlots(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(GUIListBox, ListBox_GetSaveGameSlots); } -RuntimeScriptValue Sc_ListBox_GetSelectedBackColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedBackColor); +RuntimeScriptValue Sc_ListBox_GetSelectedBackColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedBackColor); } // void (GUIListBox *guisl, int newsel) -RuntimeScriptValue Sc_ListBox_SetSelectedBackColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedBackColor); +RuntimeScriptValue Sc_ListBox_SetSelectedBackColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedBackColor); } -RuntimeScriptValue Sc_ListBox_GetSelectedTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedTextColor); +RuntimeScriptValue Sc_ListBox_GetSelectedTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedTextColor); } // void (GUIListBox *guisl, int newsel) -RuntimeScriptValue Sc_ListBox_SetSelectedTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedTextColor); +RuntimeScriptValue Sc_ListBox_SetSelectedTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedTextColor); } -RuntimeScriptValue Sc_ListBox_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetTextAlignment); +RuntimeScriptValue Sc_ListBox_GetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetTextAlignment); } // void (GUIListBox *guisl, int newsel) -RuntimeScriptValue Sc_ListBox_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTextAlignment); +RuntimeScriptValue Sc_ListBox_SetTextAlignment(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTextAlignment); } -RuntimeScriptValue Sc_ListBox_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetTextColor); +RuntimeScriptValue Sc_ListBox_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetTextColor); } // void (GUIListBox *guisl, int newsel) -RuntimeScriptValue Sc_ListBox_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTextColor); +RuntimeScriptValue Sc_ListBox_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTextColor); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_GetSelectedIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedIndex); +RuntimeScriptValue Sc_ListBox_GetSelectedIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetSelectedIndex); } // void (GUIListBox *guisl, int newsel) -RuntimeScriptValue Sc_ListBox_SetSelectedIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedIndex); +RuntimeScriptValue Sc_ListBox_SetSelectedIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetSelectedIndex); } // int (GUIListBox *listbox) -RuntimeScriptValue Sc_ListBox_GetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUIListBox, ListBox_GetTopItem); +RuntimeScriptValue Sc_ListBox_GetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUIListBox, ListBox_GetTopItem); } // void (GUIListBox *guisl, int item) -RuntimeScriptValue Sc_ListBox_SetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTopItem); -} - - - -void RegisterListBoxAPI() -{ - ccAddExternalObjectFunction("ListBox::AddItem^1", Sc_ListBox_AddItem); - ccAddExternalObjectFunction("ListBox::Clear^0", Sc_ListBox_Clear); - ccAddExternalObjectFunction("ListBox::FillDirList^1", Sc_ListBox_FillDirList); - ccAddExternalObjectFunction("ListBox::FillSaveGameList^0", Sc_ListBox_FillSaveGameList); - ccAddExternalObjectFunction("ListBox::GetItemAtLocation^2", Sc_ListBox_GetItemAtLocation); - ccAddExternalObjectFunction("ListBox::GetItemText^2", Sc_ListBox_GetItemText); - ccAddExternalObjectFunction("ListBox::InsertItemAt^2", Sc_ListBox_InsertItemAt); - ccAddExternalObjectFunction("ListBox::RemoveItem^1", Sc_ListBox_RemoveItem); - ccAddExternalObjectFunction("ListBox::ScrollDown^0", Sc_ListBox_ScrollDown); - ccAddExternalObjectFunction("ListBox::ScrollUp^0", Sc_ListBox_ScrollUp); - ccAddExternalObjectFunction("ListBox::SetItemText^2", Sc_ListBox_SetItemText); - ccAddExternalObjectFunction("ListBox::get_Font", Sc_ListBox_GetFont); - ccAddExternalObjectFunction("ListBox::set_Font", Sc_ListBox_SetFont); - ccAddExternalObjectFunction("ListBox::get_ShowBorder", Sc_ListBox_GetShowBorder); - ccAddExternalObjectFunction("ListBox::set_ShowBorder", Sc_ListBox_SetShowBorder); - ccAddExternalObjectFunction("ListBox::get_ShowScrollArrows", Sc_ListBox_GetShowScrollArrows); - ccAddExternalObjectFunction("ListBox::set_ShowScrollArrows", Sc_ListBox_SetShowScrollArrows); - // old "inverted" properties - ccAddExternalObjectFunction("ListBox::get_HideBorder", Sc_ListBox_GetHideBorder); - ccAddExternalObjectFunction("ListBox::set_HideBorder", Sc_ListBox_SetHideBorder); - ccAddExternalObjectFunction("ListBox::get_HideScrollArrows", Sc_ListBox_GetHideScrollArrows); - ccAddExternalObjectFunction("ListBox::set_HideScrollArrows", Sc_ListBox_SetHideScrollArrows); - // - ccAddExternalObjectFunction("ListBox::get_ItemCount", Sc_ListBox_GetItemCount); - ccAddExternalObjectFunction("ListBox::geti_Items", Sc_ListBox_GetItems); - ccAddExternalObjectFunction("ListBox::seti_Items", Sc_ListBox_SetItemText); - ccAddExternalObjectFunction("ListBox::get_RowCount", Sc_ListBox_GetRowCount); - ccAddExternalObjectFunction("ListBox::geti_SaveGameSlots", Sc_ListBox_GetSaveGameSlots); - ccAddExternalObjectFunction("ListBox::get_SelectedBackColor", Sc_ListBox_GetSelectedBackColor); - ccAddExternalObjectFunction("ListBox::set_SelectedBackColor", Sc_ListBox_SetSelectedBackColor); - ccAddExternalObjectFunction("ListBox::get_SelectedIndex", Sc_ListBox_GetSelectedIndex); - ccAddExternalObjectFunction("ListBox::set_SelectedIndex", Sc_ListBox_SetSelectedIndex); - ccAddExternalObjectFunction("ListBox::get_SelectedTextColor", Sc_ListBox_GetSelectedTextColor); - ccAddExternalObjectFunction("ListBox::set_SelectedTextColor", Sc_ListBox_SetSelectedTextColor); - ccAddExternalObjectFunction("ListBox::get_TextAlignment", Sc_ListBox_GetTextAlignment); - ccAddExternalObjectFunction("ListBox::set_TextAlignment", Sc_ListBox_SetTextAlignment); - ccAddExternalObjectFunction("ListBox::get_TextColor", Sc_ListBox_GetTextColor); - ccAddExternalObjectFunction("ListBox::set_TextColor", Sc_ListBox_SetTextColor); - ccAddExternalObjectFunction("ListBox::get_TopItem", Sc_ListBox_GetTopItem); - ccAddExternalObjectFunction("ListBox::set_TopItem", Sc_ListBox_SetTopItem); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("ListBox::AddItem^1", (void*)ListBox_AddItem); - ccAddExternalFunctionForPlugin("ListBox::Clear^0", (void*)ListBox_Clear); - ccAddExternalFunctionForPlugin("ListBox::FillDirList^1", (void*)ListBox_FillDirList); - ccAddExternalFunctionForPlugin("ListBox::FillSaveGameList^0", (void*)ListBox_FillSaveGameList); - ccAddExternalFunctionForPlugin("ListBox::GetItemAtLocation^2", (void*)ListBox_GetItemAtLocation); - ccAddExternalFunctionForPlugin("ListBox::GetItemText^2", (void*)ListBox_GetItemText); - ccAddExternalFunctionForPlugin("ListBox::InsertItemAt^2", (void*)ListBox_InsertItemAt); - ccAddExternalFunctionForPlugin("ListBox::RemoveItem^1", (void*)ListBox_RemoveItem); - ccAddExternalFunctionForPlugin("ListBox::ScrollDown^0", (void*)ListBox_ScrollDown); - ccAddExternalFunctionForPlugin("ListBox::ScrollUp^0", (void*)ListBox_ScrollUp); - ccAddExternalFunctionForPlugin("ListBox::SetItemText^2", (void*)ListBox_SetItemText); - ccAddExternalFunctionForPlugin("ListBox::get_Font", (void*)ListBox_GetFont); - ccAddExternalFunctionForPlugin("ListBox::set_Font", (void*)ListBox_SetFont); - ccAddExternalFunctionForPlugin("ListBox::get_HideBorder", (void*)ListBox_GetHideBorder); - ccAddExternalFunctionForPlugin("ListBox::set_HideBorder", (void*)ListBox_SetHideBorder); - ccAddExternalFunctionForPlugin("ListBox::get_HideScrollArrows", (void*)ListBox_GetHideScrollArrows); - ccAddExternalFunctionForPlugin("ListBox::set_HideScrollArrows", (void*)ListBox_SetHideScrollArrows); - ccAddExternalFunctionForPlugin("ListBox::get_ItemCount", (void*)ListBox_GetItemCount); - ccAddExternalFunctionForPlugin("ListBox::geti_Items", (void*)ListBox_GetItems); - ccAddExternalFunctionForPlugin("ListBox::seti_Items", (void*)ListBox_SetItemText); - ccAddExternalFunctionForPlugin("ListBox::get_RowCount", (void*)ListBox_GetRowCount); - ccAddExternalFunctionForPlugin("ListBox::geti_SaveGameSlots", (void*)ListBox_GetSaveGameSlots); - ccAddExternalFunctionForPlugin("ListBox::get_SelectedIndex", (void*)ListBox_GetSelectedIndex); - ccAddExternalFunctionForPlugin("ListBox::set_SelectedIndex", (void*)ListBox_SetSelectedIndex); - ccAddExternalFunctionForPlugin("ListBox::get_TopItem", (void*)ListBox_GetTopItem); - ccAddExternalFunctionForPlugin("ListBox::set_TopItem", (void*)ListBox_SetTopItem); +RuntimeScriptValue Sc_ListBox_SetTopItem(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUIListBox, ListBox_SetTopItem); +} + + + +void RegisterListBoxAPI() { + ccAddExternalObjectFunction("ListBox::AddItem^1", Sc_ListBox_AddItem); + ccAddExternalObjectFunction("ListBox::Clear^0", Sc_ListBox_Clear); + ccAddExternalObjectFunction("ListBox::FillDirList^1", Sc_ListBox_FillDirList); + ccAddExternalObjectFunction("ListBox::FillSaveGameList^0", Sc_ListBox_FillSaveGameList); + ccAddExternalObjectFunction("ListBox::GetItemAtLocation^2", Sc_ListBox_GetItemAtLocation); + ccAddExternalObjectFunction("ListBox::GetItemText^2", Sc_ListBox_GetItemText); + ccAddExternalObjectFunction("ListBox::InsertItemAt^2", Sc_ListBox_InsertItemAt); + ccAddExternalObjectFunction("ListBox::RemoveItem^1", Sc_ListBox_RemoveItem); + ccAddExternalObjectFunction("ListBox::ScrollDown^0", Sc_ListBox_ScrollDown); + ccAddExternalObjectFunction("ListBox::ScrollUp^0", Sc_ListBox_ScrollUp); + ccAddExternalObjectFunction("ListBox::SetItemText^2", Sc_ListBox_SetItemText); + ccAddExternalObjectFunction("ListBox::get_Font", Sc_ListBox_GetFont); + ccAddExternalObjectFunction("ListBox::set_Font", Sc_ListBox_SetFont); + ccAddExternalObjectFunction("ListBox::get_ShowBorder", Sc_ListBox_GetShowBorder); + ccAddExternalObjectFunction("ListBox::set_ShowBorder", Sc_ListBox_SetShowBorder); + ccAddExternalObjectFunction("ListBox::get_ShowScrollArrows", Sc_ListBox_GetShowScrollArrows); + ccAddExternalObjectFunction("ListBox::set_ShowScrollArrows", Sc_ListBox_SetShowScrollArrows); + // old "inverted" properties + ccAddExternalObjectFunction("ListBox::get_HideBorder", Sc_ListBox_GetHideBorder); + ccAddExternalObjectFunction("ListBox::set_HideBorder", Sc_ListBox_SetHideBorder); + ccAddExternalObjectFunction("ListBox::get_HideScrollArrows", Sc_ListBox_GetHideScrollArrows); + ccAddExternalObjectFunction("ListBox::set_HideScrollArrows", Sc_ListBox_SetHideScrollArrows); + // + ccAddExternalObjectFunction("ListBox::get_ItemCount", Sc_ListBox_GetItemCount); + ccAddExternalObjectFunction("ListBox::geti_Items", Sc_ListBox_GetItems); + ccAddExternalObjectFunction("ListBox::seti_Items", Sc_ListBox_SetItemText); + ccAddExternalObjectFunction("ListBox::get_RowCount", Sc_ListBox_GetRowCount); + ccAddExternalObjectFunction("ListBox::geti_SaveGameSlots", Sc_ListBox_GetSaveGameSlots); + ccAddExternalObjectFunction("ListBox::get_SelectedBackColor", Sc_ListBox_GetSelectedBackColor); + ccAddExternalObjectFunction("ListBox::set_SelectedBackColor", Sc_ListBox_SetSelectedBackColor); + ccAddExternalObjectFunction("ListBox::get_SelectedIndex", Sc_ListBox_GetSelectedIndex); + ccAddExternalObjectFunction("ListBox::set_SelectedIndex", Sc_ListBox_SetSelectedIndex); + ccAddExternalObjectFunction("ListBox::get_SelectedTextColor", Sc_ListBox_GetSelectedTextColor); + ccAddExternalObjectFunction("ListBox::set_SelectedTextColor", Sc_ListBox_SetSelectedTextColor); + ccAddExternalObjectFunction("ListBox::get_TextAlignment", Sc_ListBox_GetTextAlignment); + ccAddExternalObjectFunction("ListBox::set_TextAlignment", Sc_ListBox_SetTextAlignment); + ccAddExternalObjectFunction("ListBox::get_TextColor", Sc_ListBox_GetTextColor); + ccAddExternalObjectFunction("ListBox::set_TextColor", Sc_ListBox_SetTextColor); + ccAddExternalObjectFunction("ListBox::get_TopItem", Sc_ListBox_GetTopItem); + ccAddExternalObjectFunction("ListBox::set_TopItem", Sc_ListBox_SetTopItem); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("ListBox::AddItem^1", (void *)ListBox_AddItem); + ccAddExternalFunctionForPlugin("ListBox::Clear^0", (void *)ListBox_Clear); + ccAddExternalFunctionForPlugin("ListBox::FillDirList^1", (void *)ListBox_FillDirList); + ccAddExternalFunctionForPlugin("ListBox::FillSaveGameList^0", (void *)ListBox_FillSaveGameList); + ccAddExternalFunctionForPlugin("ListBox::GetItemAtLocation^2", (void *)ListBox_GetItemAtLocation); + ccAddExternalFunctionForPlugin("ListBox::GetItemText^2", (void *)ListBox_GetItemText); + ccAddExternalFunctionForPlugin("ListBox::InsertItemAt^2", (void *)ListBox_InsertItemAt); + ccAddExternalFunctionForPlugin("ListBox::RemoveItem^1", (void *)ListBox_RemoveItem); + ccAddExternalFunctionForPlugin("ListBox::ScrollDown^0", (void *)ListBox_ScrollDown); + ccAddExternalFunctionForPlugin("ListBox::ScrollUp^0", (void *)ListBox_ScrollUp); + ccAddExternalFunctionForPlugin("ListBox::SetItemText^2", (void *)ListBox_SetItemText); + ccAddExternalFunctionForPlugin("ListBox::get_Font", (void *)ListBox_GetFont); + ccAddExternalFunctionForPlugin("ListBox::set_Font", (void *)ListBox_SetFont); + ccAddExternalFunctionForPlugin("ListBox::get_HideBorder", (void *)ListBox_GetHideBorder); + ccAddExternalFunctionForPlugin("ListBox::set_HideBorder", (void *)ListBox_SetHideBorder); + ccAddExternalFunctionForPlugin("ListBox::get_HideScrollArrows", (void *)ListBox_GetHideScrollArrows); + ccAddExternalFunctionForPlugin("ListBox::set_HideScrollArrows", (void *)ListBox_SetHideScrollArrows); + ccAddExternalFunctionForPlugin("ListBox::get_ItemCount", (void *)ListBox_GetItemCount); + ccAddExternalFunctionForPlugin("ListBox::geti_Items", (void *)ListBox_GetItems); + ccAddExternalFunctionForPlugin("ListBox::seti_Items", (void *)ListBox_SetItemText); + ccAddExternalFunctionForPlugin("ListBox::get_RowCount", (void *)ListBox_GetRowCount); + ccAddExternalFunctionForPlugin("ListBox::geti_SaveGameSlots", (void *)ListBox_GetSaveGameSlots); + ccAddExternalFunctionForPlugin("ListBox::get_SelectedIndex", (void *)ListBox_GetSelectedIndex); + ccAddExternalFunctionForPlugin("ListBox::set_SelectedIndex", (void *)ListBox_SetSelectedIndex); + ccAddExternalFunctionForPlugin("ListBox::get_TopItem", (void *)ListBox_GetTopItem); + ccAddExternalFunctionForPlugin("ListBox::set_TopItem", (void *)ListBox_SetTopItem); } diff --git a/engines/ags/engine/ac/listbox.h b/engines/ags/engine/ac/listbox.h index 2b0c07af264f..c0243a22776a 100644 --- a/engines/ags/engine/ac/listbox.h +++ b/engines/ags/engine/ac/listbox.h @@ -27,32 +27,32 @@ using AGS::Common::GUIListBox; -int ListBox_AddItem(GUIListBox *lbb, const char *text); -int ListBox_InsertItemAt(GUIListBox *lbb, int index, const char *text); -void ListBox_Clear(GUIListBox *listbox); -void ListBox_FillDirList(GUIListBox *listbox, const char *filemask); -int ListBox_GetSaveGameSlots(GUIListBox *listbox, int index); -int ListBox_FillSaveGameList(GUIListBox *listbox); -int ListBox_GetItemAtLocation(GUIListBox *listbox, int x, int y); -char *ListBox_GetItemText(GUIListBox *listbox, int index, char *buffer); -const char* ListBox_GetItems(GUIListBox *listbox, int index); -void ListBox_SetItemText(GUIListBox *listbox, int index, const char *newtext); -void ListBox_RemoveItem(GUIListBox *listbox, int itemIndex); -int ListBox_GetItemCount(GUIListBox *listbox); -int ListBox_GetFont(GUIListBox *listbox); -void ListBox_SetFont(GUIListBox *listbox, int newfont); -int ListBox_GetHideBorder(GUIListBox *listbox); -void ListBox_SetHideBorder(GUIListBox *listbox, int newValue); -int ListBox_GetHideScrollArrows(GUIListBox *listbox); -void ListBox_SetHideScrollArrows(GUIListBox *listbox, int newValue); -int ListBox_GetSelectedIndex(GUIListBox *listbox); -void ListBox_SetSelectedIndex(GUIListBox *guisl, int newsel); -int ListBox_GetTopItem(GUIListBox *listbox); -void ListBox_SetTopItem(GUIListBox *guisl, int item); -int ListBox_GetRowCount(GUIListBox *listbox); -void ListBox_ScrollDown(GUIListBox *listbox); -void ListBox_ScrollUp(GUIListBox *listbox); +int ListBox_AddItem(GUIListBox *lbb, const char *text); +int ListBox_InsertItemAt(GUIListBox *lbb, int index, const char *text); +void ListBox_Clear(GUIListBox *listbox); +void ListBox_FillDirList(GUIListBox *listbox, const char *filemask); +int ListBox_GetSaveGameSlots(GUIListBox *listbox, int index); +int ListBox_FillSaveGameList(GUIListBox *listbox); +int ListBox_GetItemAtLocation(GUIListBox *listbox, int x, int y); +char *ListBox_GetItemText(GUIListBox *listbox, int index, char *buffer); +const char *ListBox_GetItems(GUIListBox *listbox, int index); +void ListBox_SetItemText(GUIListBox *listbox, int index, const char *newtext); +void ListBox_RemoveItem(GUIListBox *listbox, int itemIndex); +int ListBox_GetItemCount(GUIListBox *listbox); +int ListBox_GetFont(GUIListBox *listbox); +void ListBox_SetFont(GUIListBox *listbox, int newfont); +int ListBox_GetHideBorder(GUIListBox *listbox); +void ListBox_SetHideBorder(GUIListBox *listbox, int newValue); +int ListBox_GetHideScrollArrows(GUIListBox *listbox); +void ListBox_SetHideScrollArrows(GUIListBox *listbox, int newValue); +int ListBox_GetSelectedIndex(GUIListBox *listbox); +void ListBox_SetSelectedIndex(GUIListBox *guisl, int newsel); +int ListBox_GetTopItem(GUIListBox *listbox); +void ListBox_SetTopItem(GUIListBox *guisl, int item); +int ListBox_GetRowCount(GUIListBox *listbox); +void ListBox_ScrollDown(GUIListBox *listbox); +void ListBox_ScrollUp(GUIListBox *listbox); -GUIListBox* is_valid_listbox (int guin, int objn); +GUIListBox *is_valid_listbox(int guin, int objn); #endif diff --git a/engines/ags/engine/ac/math.cpp b/engines/ags/engine/ac/math.cpp index 48e27b7edcec..228558fc5261 100644 --- a/engines/ags/engine/ac/math.cpp +++ b/engines/ags/engine/ac/math.cpp @@ -25,141 +25,118 @@ #include "ac/common.h" // quit #include "util/math.h" -int FloatToInt(float value, int roundDirection) -{ - if (value >= 0.0) { - if (roundDirection == eRoundDown) - return static_cast(value); - else if (roundDirection == eRoundNearest) - return static_cast(value + 0.5); - else if (roundDirection == eRoundUp) - return static_cast(value + 0.999999); - else - quit("!FloatToInt: invalid round direction"); - } - else { - // negative number - if (roundDirection == eRoundUp) - return static_cast(value); // this just truncates - else if (roundDirection == eRoundNearest) - return static_cast(value - 0.5); - else if (roundDirection == eRoundDown) - return static_cast(value - 0.999999); - else - quit("!FloatToInt: invalid round direction"); - } - return 0; +int FloatToInt(float value, int roundDirection) { + if (value >= 0.0) { + if (roundDirection == eRoundDown) + return static_cast(value); + else if (roundDirection == eRoundNearest) + return static_cast(value + 0.5); + else if (roundDirection == eRoundUp) + return static_cast(value + 0.999999); + else + quit("!FloatToInt: invalid round direction"); + } else { + // negative number + if (roundDirection == eRoundUp) + return static_cast(value); // this just truncates + else if (roundDirection == eRoundNearest) + return static_cast(value - 0.5); + else if (roundDirection == eRoundDown) + return static_cast(value - 0.999999); + else + quit("!FloatToInt: invalid round direction"); + } + return 0; } -float IntToFloat(int value) -{ - return static_cast(value); +float IntToFloat(int value) { + return static_cast(value); } -float StringToFloat(const char *theString) -{ - return static_cast(atof(theString)); +float StringToFloat(const char *theString) { + return static_cast(atof(theString)); } -float Math_Cos(float value) -{ - return cos(value); +float Math_Cos(float value) { + return cos(value); } -float Math_Sin(float value) -{ - return sin(value); +float Math_Sin(float value) { + return sin(value); } -float Math_Tan(float value) -{ - return tan(value); +float Math_Tan(float value) { + return tan(value); } -float Math_ArcCos(float value) -{ - return acos(value); +float Math_ArcCos(float value) { + return acos(value); } -float Math_ArcSin(float value) -{ - return asin(value); +float Math_ArcSin(float value) { + return asin(value); } -float Math_ArcTan(float value) -{ - return atan(value); +float Math_ArcTan(float value) { + return atan(value); } -float Math_ArcTan2(float yval, float xval) -{ - return atan2(yval, xval); +float Math_ArcTan2(float yval, float xval) { + return atan2(yval, xval); } -float Math_Log(float value) -{ - return log(value); +float Math_Log(float value) { + return log(value); } -float Math_Log10(float value) -{ - return ::log10(value); +float Math_Log10(float value) { + return ::log10(value); } -float Math_Exp(float value) -{ - return exp(value); +float Math_Exp(float value) { + return exp(value); } -float Math_Cosh(float value) -{ - return cosh(value); +float Math_Cosh(float value) { + return cosh(value); } -float Math_Sinh(float value) -{ - return sinh(value); +float Math_Sinh(float value) { + return sinh(value); } -float Math_Tanh(float value) -{ - return tanh(value); +float Math_Tanh(float value) { + return tanh(value); } -float Math_RaiseToPower(float base, float exp) -{ - return ::pow(base, exp); +float Math_RaiseToPower(float base, float exp) { + return ::pow(base, exp); } -float Math_DegreesToRadians(float value) -{ - return static_cast(value * (M_PI / 180.0)); +float Math_DegreesToRadians(float value) { + return static_cast(value * (M_PI / 180.0)); } -float Math_RadiansToDegrees(float value) -{ - return static_cast(value * (180.0 / M_PI)); +float Math_RadiansToDegrees(float value) { + return static_cast(value * (180.0 / M_PI)); } -float Math_GetPi() -{ - return static_cast(M_PI); +float Math_GetPi() { + return static_cast(M_PI); } -float Math_Sqrt(float value) -{ - if (value < 0.0) - quit("!Sqrt: cannot perform square root of negative number"); +float Math_Sqrt(float value) { + if (value < 0.0) + quit("!Sqrt: cannot perform square root of negative number"); - return ::sqrt(value); + return ::sqrt(value); } -int __Rand(int upto) -{ - upto++; - if (upto < 1) - quit("!Random: invalid parameter passed -- must be at least 0."); - return rand()%upto; +int __Rand(int upto) { + upto++; + if (upto < 1) + quit("!Random: invalid parameter passed -- must be at least 0."); + return rand() % upto; } @@ -174,153 +151,134 @@ int __Rand(int upto) #include "script/script_runtime.h" // float (float value) -RuntimeScriptValue Sc_Math_ArcCos(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_ArcCos); +RuntimeScriptValue Sc_Math_ArcCos(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_ArcCos); } // float (float value) -RuntimeScriptValue Sc_Math_ArcSin(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_ArcSin); +RuntimeScriptValue Sc_Math_ArcSin(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_ArcSin); } // float (float value) -RuntimeScriptValue Sc_Math_ArcTan(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_ArcTan); +RuntimeScriptValue Sc_Math_ArcTan(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_ArcTan); } // float (SCRIPT_FLOAT(yval), SCRIPT_FLOAT(xval)) -RuntimeScriptValue Sc_Math_ArcTan2(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT2(Math_ArcTan2); +RuntimeScriptValue Sc_Math_ArcTan2(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT2(Math_ArcTan2); } // float (float value) -RuntimeScriptValue Sc_Math_Cos(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Cos); +RuntimeScriptValue Sc_Math_Cos(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Cos); } // float (float value) -RuntimeScriptValue Sc_Math_Cosh(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Cosh); +RuntimeScriptValue Sc_Math_Cosh(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Cosh); } // float (float value) -RuntimeScriptValue Sc_Math_DegreesToRadians(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_DegreesToRadians); +RuntimeScriptValue Sc_Math_DegreesToRadians(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_DegreesToRadians); } // float (float value) -RuntimeScriptValue Sc_Math_Exp(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Exp); +RuntimeScriptValue Sc_Math_Exp(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Exp); } // float (float value) -RuntimeScriptValue Sc_Math_Log(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Log); +RuntimeScriptValue Sc_Math_Log(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Log); } // float (float value) -RuntimeScriptValue Sc_Math_Log10(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Log10); +RuntimeScriptValue Sc_Math_Log10(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Log10); } // float (float value) -RuntimeScriptValue Sc_Math_RadiansToDegrees(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_RadiansToDegrees); +RuntimeScriptValue Sc_Math_RadiansToDegrees(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_RadiansToDegrees); } // float (SCRIPT_FLOAT(base), SCRIPT_FLOAT(exp)) -RuntimeScriptValue Sc_Math_RaiseToPower(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT2(Math_RaiseToPower); +RuntimeScriptValue Sc_Math_RaiseToPower(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT2(Math_RaiseToPower); } // float (float value) -RuntimeScriptValue Sc_Math_Sin(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Sin); +RuntimeScriptValue Sc_Math_Sin(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Sin); } // float (float value) -RuntimeScriptValue Sc_Math_Sinh(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Sinh); +RuntimeScriptValue Sc_Math_Sinh(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Sinh); } // float (float value) -RuntimeScriptValue Sc_Math_Sqrt(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Sqrt); +RuntimeScriptValue Sc_Math_Sqrt(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Sqrt); } // float (float value) -RuntimeScriptValue Sc_Math_Tan(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Tan); +RuntimeScriptValue Sc_Math_Tan(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Tan); } // float (float value) -RuntimeScriptValue Sc_Math_Tanh(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT_PFLOAT(Math_Tanh); +RuntimeScriptValue Sc_Math_Tanh(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT_PFLOAT(Math_Tanh); } // float () -RuntimeScriptValue Sc_Math_GetPi(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT(Math_GetPi); -} - - -void RegisterMathAPI() -{ - ccAddExternalStaticFunction("Maths::ArcCos^1", Sc_Math_ArcCos); - ccAddExternalStaticFunction("Maths::ArcSin^1", Sc_Math_ArcSin); - ccAddExternalStaticFunction("Maths::ArcTan^1", Sc_Math_ArcTan); - ccAddExternalStaticFunction("Maths::ArcTan2^2", Sc_Math_ArcTan2); - ccAddExternalStaticFunction("Maths::Cos^1", Sc_Math_Cos); - ccAddExternalStaticFunction("Maths::Cosh^1", Sc_Math_Cosh); - ccAddExternalStaticFunction("Maths::DegreesToRadians^1", Sc_Math_DegreesToRadians); - ccAddExternalStaticFunction("Maths::Exp^1", Sc_Math_Exp); - ccAddExternalStaticFunction("Maths::Log^1", Sc_Math_Log); - ccAddExternalStaticFunction("Maths::Log10^1", Sc_Math_Log10); - ccAddExternalStaticFunction("Maths::RadiansToDegrees^1", Sc_Math_RadiansToDegrees); - ccAddExternalStaticFunction("Maths::RaiseToPower^2", Sc_Math_RaiseToPower); - ccAddExternalStaticFunction("Maths::Sin^1", Sc_Math_Sin); - ccAddExternalStaticFunction("Maths::Sinh^1", Sc_Math_Sinh); - ccAddExternalStaticFunction("Maths::Sqrt^1", Sc_Math_Sqrt); - ccAddExternalStaticFunction("Maths::Tan^1", Sc_Math_Tan); - ccAddExternalStaticFunction("Maths::Tanh^1", Sc_Math_Tanh); - ccAddExternalStaticFunction("Maths::get_Pi", Sc_Math_GetPi); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Maths::ArcCos^1", (void*)Math_ArcCos); - ccAddExternalFunctionForPlugin("Maths::ArcSin^1", (void*)Math_ArcSin); - ccAddExternalFunctionForPlugin("Maths::ArcTan^1", (void*)Math_ArcTan); - ccAddExternalFunctionForPlugin("Maths::ArcTan2^2", (void*)Math_ArcTan2); - ccAddExternalFunctionForPlugin("Maths::Cos^1", (void*)Math_Cos); - ccAddExternalFunctionForPlugin("Maths::Cosh^1", (void*)Math_Cosh); - ccAddExternalFunctionForPlugin("Maths::DegreesToRadians^1", (void*)Math_DegreesToRadians); - ccAddExternalFunctionForPlugin("Maths::Exp^1", (void*)Math_Exp); - ccAddExternalFunctionForPlugin("Maths::Log^1", (void*)Math_Log); - ccAddExternalFunctionForPlugin("Maths::Log10^1", (void*)Math_Log10); - ccAddExternalFunctionForPlugin("Maths::RadiansToDegrees^1", (void*)Math_RadiansToDegrees); - ccAddExternalFunctionForPlugin("Maths::RaiseToPower^2", (void*)Math_RaiseToPower); - ccAddExternalFunctionForPlugin("Maths::Sin^1", (void*)Math_Sin); - ccAddExternalFunctionForPlugin("Maths::Sinh^1", (void*)Math_Sinh); - ccAddExternalFunctionForPlugin("Maths::Sqrt^1", (void*)Math_Sqrt); - ccAddExternalFunctionForPlugin("Maths::Tan^1", (void*)Math_Tan); - ccAddExternalFunctionForPlugin("Maths::Tanh^1", (void*)Math_Tanh); - ccAddExternalFunctionForPlugin("Maths::get_Pi", (void*)Math_GetPi); +RuntimeScriptValue Sc_Math_GetPi(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT(Math_GetPi); +} + + +void RegisterMathAPI() { + ccAddExternalStaticFunction("Maths::ArcCos^1", Sc_Math_ArcCos); + ccAddExternalStaticFunction("Maths::ArcSin^1", Sc_Math_ArcSin); + ccAddExternalStaticFunction("Maths::ArcTan^1", Sc_Math_ArcTan); + ccAddExternalStaticFunction("Maths::ArcTan2^2", Sc_Math_ArcTan2); + ccAddExternalStaticFunction("Maths::Cos^1", Sc_Math_Cos); + ccAddExternalStaticFunction("Maths::Cosh^1", Sc_Math_Cosh); + ccAddExternalStaticFunction("Maths::DegreesToRadians^1", Sc_Math_DegreesToRadians); + ccAddExternalStaticFunction("Maths::Exp^1", Sc_Math_Exp); + ccAddExternalStaticFunction("Maths::Log^1", Sc_Math_Log); + ccAddExternalStaticFunction("Maths::Log10^1", Sc_Math_Log10); + ccAddExternalStaticFunction("Maths::RadiansToDegrees^1", Sc_Math_RadiansToDegrees); + ccAddExternalStaticFunction("Maths::RaiseToPower^2", Sc_Math_RaiseToPower); + ccAddExternalStaticFunction("Maths::Sin^1", Sc_Math_Sin); + ccAddExternalStaticFunction("Maths::Sinh^1", Sc_Math_Sinh); + ccAddExternalStaticFunction("Maths::Sqrt^1", Sc_Math_Sqrt); + ccAddExternalStaticFunction("Maths::Tan^1", Sc_Math_Tan); + ccAddExternalStaticFunction("Maths::Tanh^1", Sc_Math_Tanh); + ccAddExternalStaticFunction("Maths::get_Pi", Sc_Math_GetPi); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Maths::ArcCos^1", (void *)Math_ArcCos); + ccAddExternalFunctionForPlugin("Maths::ArcSin^1", (void *)Math_ArcSin); + ccAddExternalFunctionForPlugin("Maths::ArcTan^1", (void *)Math_ArcTan); + ccAddExternalFunctionForPlugin("Maths::ArcTan2^2", (void *)Math_ArcTan2); + ccAddExternalFunctionForPlugin("Maths::Cos^1", (void *)Math_Cos); + ccAddExternalFunctionForPlugin("Maths::Cosh^1", (void *)Math_Cosh); + ccAddExternalFunctionForPlugin("Maths::DegreesToRadians^1", (void *)Math_DegreesToRadians); + ccAddExternalFunctionForPlugin("Maths::Exp^1", (void *)Math_Exp); + ccAddExternalFunctionForPlugin("Maths::Log^1", (void *)Math_Log); + ccAddExternalFunctionForPlugin("Maths::Log10^1", (void *)Math_Log10); + ccAddExternalFunctionForPlugin("Maths::RadiansToDegrees^1", (void *)Math_RadiansToDegrees); + ccAddExternalFunctionForPlugin("Maths::RaiseToPower^2", (void *)Math_RaiseToPower); + ccAddExternalFunctionForPlugin("Maths::Sin^1", (void *)Math_Sin); + ccAddExternalFunctionForPlugin("Maths::Sinh^1", (void *)Math_Sinh); + ccAddExternalFunctionForPlugin("Maths::Sqrt^1", (void *)Math_Sqrt); + ccAddExternalFunctionForPlugin("Maths::Tan^1", (void *)Math_Tan); + ccAddExternalFunctionForPlugin("Maths::Tanh^1", (void *)Math_Tanh); + ccAddExternalFunctionForPlugin("Maths::get_Pi", (void *)Math_GetPi); } diff --git a/engines/ags/engine/ac/math.h b/engines/ags/engine/ac/math.h index 8dd7d8f55e7c..bd3d3f7f1e1a 100644 --- a/engines/ags/engine/ac/math.h +++ b/engines/ags/engine/ac/math.h @@ -26,9 +26,9 @@ #include "core/types.h" enum RoundDirections { - eRoundDown = 0, - eRoundNearest = 1, - eRoundUp = 2 + eRoundDown = 0, + eRoundNearest = 1, + eRoundUp = 2 }; diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp index 1c6e8e1a9725..067571982566 100644 --- a/engines/ags/engine/ac/mouse.cpp +++ b/engines/ags/engine/ac/mouse.cpp @@ -50,16 +50,16 @@ extern GameState play; extern ScriptSystem scsystem; extern Bitmap *mousecurs[MAXCURSORS]; extern SpriteCache spriteset; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern IGraphicsDriver *gfxDriver; extern void ags_domouse(int str); extern int misbuttondown(int buno); ScriptMouse scmouse; -int cur_mode,cur_cursor; -int mouse_frame=0,mouse_delay=0; -int lastmx=-1,lastmy=-1; +int cur_mode, cur_cursor; +int mouse_frame = 0, mouse_delay = 0; +int lastmx = -1, lastmy = -1; char alpha_blend_cursor = 0; Bitmap *dotted_mouse_cursor = nullptr; IDriverDependantBitmap *mouseCursor = nullptr; @@ -68,395 +68,382 @@ Bitmap *blank_mouse_cursor = nullptr; // The Mouse:: functions are static so the script doesn't pass // in an object parameter void Mouse_SetVisible(int isOn) { - if (isOn) - ShowMouseCursor(); - else - HideMouseCursor(); + if (isOn) + ShowMouseCursor(); + else + HideMouseCursor(); } int Mouse_GetVisible() { - if (play.mouse_cursor_hidden) - return 0; - return 1; -} - -void SetMouseBounds(int x1, int y1, int x2, int y2) -{ - int xmax = game_to_data_coord(play.GetMainViewport().GetWidth()) - 1; - int ymax = game_to_data_coord(play.GetMainViewport().GetHeight()) - 1; - if ((x1 == 0) && (y1 == 0) && (x2 == 0) && (y2 == 0)) - { - x2 = xmax; - y2 = ymax; - } - else - { - if (x1 < 0 || x1 > xmax || x2 < 0 || x2 > xmax || x1 > x2 || y1 < 0 || y1 > ymax || y2 < 0 || y2 > ymax || y1 > y2) - debug_script_warn("SetMouseBounds: arguments are out of range and will be corrected: (%d,%d)-(%d,%d), range is (%d,%d)-(%d,%d)", - x1, y1, x2, y2, 0, 0, xmax, ymax); - x1 = Math::Clamp(x1, 0, xmax); - x2 = Math::Clamp(x2, x1, xmax); - y1 = Math::Clamp(y1, 0, ymax); - y2 = Math::Clamp(y2, y1, ymax); - } - - debug_script_log("Mouse bounds constrained to (%d,%d)-(%d,%d)", x1, y1, x2, y2); - data_to_game_coords(&x1, &y1); - data_to_game_round_up(&x2, &y2); - - play.mboundx1 = x1; - play.mboundx2 = x2; - play.mboundy1 = y1; - play.mboundy2 = y2; - Mouse::SetMoveLimit(Rect(x1, y1, x2, y2)); + if (play.mouse_cursor_hidden) + return 0; + return 1; +} + +void SetMouseBounds(int x1, int y1, int x2, int y2) { + int xmax = game_to_data_coord(play.GetMainViewport().GetWidth()) - 1; + int ymax = game_to_data_coord(play.GetMainViewport().GetHeight()) - 1; + if ((x1 == 0) && (y1 == 0) && (x2 == 0) && (y2 == 0)) { + x2 = xmax; + y2 = ymax; + } else { + if (x1 < 0 || x1 > xmax || x2 < 0 || x2 > xmax || x1 > x2 || y1 < 0 || y1 > ymax || y2 < 0 || y2 > ymax || y1 > y2) + debug_script_warn("SetMouseBounds: arguments are out of range and will be corrected: (%d,%d)-(%d,%d), range is (%d,%d)-(%d,%d)", + x1, y1, x2, y2, 0, 0, xmax, ymax); + x1 = Math::Clamp(x1, 0, xmax); + x2 = Math::Clamp(x2, x1, xmax); + y1 = Math::Clamp(y1, 0, ymax); + y2 = Math::Clamp(y2, y1, ymax); + } + + debug_script_log("Mouse bounds constrained to (%d,%d)-(%d,%d)", x1, y1, x2, y2); + data_to_game_coords(&x1, &y1); + data_to_game_round_up(&x2, &y2); + + play.mboundx1 = x1; + play.mboundx2 = x2; + play.mboundy1 = y1; + play.mboundy2 = y2; + Mouse::SetMoveLimit(Rect(x1, y1, x2, y2)); } // mouse cursor functions: // set_mouse_cursor: changes visual appearance to specified cursor void set_mouse_cursor(int newcurs) { - const int hotspotx = game.mcurs[newcurs].hotx, hotspoty = game.mcurs[newcurs].hoty; - msethotspot(hotspotx, hotspoty); - - // if it's same cursor and there's animation in progress, then don't assign a new pic just yet - if (newcurs == cur_cursor && game.mcurs[newcurs].view >= 0 && - (mouse_frame > 0 || mouse_delay > 0)) - { - return; - } - - // reset animation timing only if it's another cursor - if (newcurs != cur_cursor) - { - cur_cursor = newcurs; - mouse_frame = 0; - mouse_delay = 0; - } - - // Assign new pic - set_new_cursor_graphic(game.mcurs[newcurs].pic); - delete dotted_mouse_cursor; - dotted_mouse_cursor = nullptr; - - // If it's inventory cursor, draw hotspot crosshair sprite upon it - if ((newcurs == MODE_USE) && (game.mcurs[newcurs].pic > 0) && - ((game.hotdot > 0) || (game.invhotdotsprite > 0)) ) { - // If necessary, create a copy of the cursor and put the hotspot - // dot onto it - dotted_mouse_cursor = BitmapHelper::CreateBitmapCopy(mousecurs[0]); - - if (game.invhotdotsprite > 0) { - draw_sprite_slot_support_alpha(dotted_mouse_cursor, - (game.SpriteInfos[game.mcurs[newcurs].pic].Flags & SPF_ALPHACHANNEL) != 0, - hotspotx - game.SpriteInfos[game.invhotdotsprite].Width / 2, - hotspoty - game.SpriteInfos[game.invhotdotsprite].Height / 2, - game.invhotdotsprite); - } - else { - putpixel_compensate (dotted_mouse_cursor, hotspotx, hotspoty, MakeColor(game.hotdot)); - - if (game.hotdotouter > 0) { - int outercol = MakeColor(game.hotdotouter); - - putpixel_compensate (dotted_mouse_cursor, hotspotx + get_fixed_pixel_size(1), hotspoty, outercol); - putpixel_compensate (dotted_mouse_cursor, hotspotx, hotspoty + get_fixed_pixel_size(1), outercol); - putpixel_compensate (dotted_mouse_cursor, hotspotx - get_fixed_pixel_size(1), hotspoty, outercol); - putpixel_compensate (dotted_mouse_cursor, hotspotx, hotspoty - get_fixed_pixel_size(1), outercol); - } - } - mousecurs[0] = dotted_mouse_cursor; - update_cached_mouse_cursor(); - } + const int hotspotx = game.mcurs[newcurs].hotx, hotspoty = game.mcurs[newcurs].hoty; + msethotspot(hotspotx, hotspoty); + + // if it's same cursor and there's animation in progress, then don't assign a new pic just yet + if (newcurs == cur_cursor && game.mcurs[newcurs].view >= 0 && + (mouse_frame > 0 || mouse_delay > 0)) { + return; + } + + // reset animation timing only if it's another cursor + if (newcurs != cur_cursor) { + cur_cursor = newcurs; + mouse_frame = 0; + mouse_delay = 0; + } + + // Assign new pic + set_new_cursor_graphic(game.mcurs[newcurs].pic); + delete dotted_mouse_cursor; + dotted_mouse_cursor = nullptr; + + // If it's inventory cursor, draw hotspot crosshair sprite upon it + if ((newcurs == MODE_USE) && (game.mcurs[newcurs].pic > 0) && + ((game.hotdot > 0) || (game.invhotdotsprite > 0))) { + // If necessary, create a copy of the cursor and put the hotspot + // dot onto it + dotted_mouse_cursor = BitmapHelper::CreateBitmapCopy(mousecurs[0]); + + if (game.invhotdotsprite > 0) { + draw_sprite_slot_support_alpha(dotted_mouse_cursor, + (game.SpriteInfos[game.mcurs[newcurs].pic].Flags & SPF_ALPHACHANNEL) != 0, + hotspotx - game.SpriteInfos[game.invhotdotsprite].Width / 2, + hotspoty - game.SpriteInfos[game.invhotdotsprite].Height / 2, + game.invhotdotsprite); + } else { + putpixel_compensate(dotted_mouse_cursor, hotspotx, hotspoty, MakeColor(game.hotdot)); + + if (game.hotdotouter > 0) { + int outercol = MakeColor(game.hotdotouter); + + putpixel_compensate(dotted_mouse_cursor, hotspotx + get_fixed_pixel_size(1), hotspoty, outercol); + putpixel_compensate(dotted_mouse_cursor, hotspotx, hotspoty + get_fixed_pixel_size(1), outercol); + putpixel_compensate(dotted_mouse_cursor, hotspotx - get_fixed_pixel_size(1), hotspoty, outercol); + putpixel_compensate(dotted_mouse_cursor, hotspotx, hotspoty - get_fixed_pixel_size(1), outercol); + } + } + mousecurs[0] = dotted_mouse_cursor; + update_cached_mouse_cursor(); + } } // set_default_cursor: resets visual appearance to current mode (walk, look, etc) void set_default_cursor() { - set_mouse_cursor(cur_mode); + set_mouse_cursor(cur_mode); } // permanently change cursor graphic -void ChangeCursorGraphic (int curs, int newslot) { - if ((curs < 0) || (curs >= game.numcursors)) - quit("!ChangeCursorGraphic: invalid mouse cursor"); +void ChangeCursorGraphic(int curs, int newslot) { + if ((curs < 0) || (curs >= game.numcursors)) + quit("!ChangeCursorGraphic: invalid mouse cursor"); - if ((curs == MODE_USE) && (game.options[OPT_FIXEDINVCURSOR] == 0)) - debug_script_warn("Mouse.ChangeModeGraphic should not be used on the Inventory cursor when the cursor is linked to the active inventory item"); + if ((curs == MODE_USE) && (game.options[OPT_FIXEDINVCURSOR] == 0)) + debug_script_warn("Mouse.ChangeModeGraphic should not be used on the Inventory cursor when the cursor is linked to the active inventory item"); - game.mcurs[curs].pic = newslot; - spriteset.Precache(newslot); - if (curs == cur_mode) - set_mouse_cursor (curs); + game.mcurs[curs].pic = newslot; + spriteset.Precache(newslot); + if (curs == cur_mode) + set_mouse_cursor(curs); } int Mouse_GetModeGraphic(int curs) { - if ((curs < 0) || (curs >= game.numcursors)) - quit("!Mouse.GetModeGraphic: invalid mouse cursor"); + if ((curs < 0) || (curs >= game.numcursors)) + quit("!Mouse.GetModeGraphic: invalid mouse cursor"); - return game.mcurs[curs].pic; + return game.mcurs[curs].pic; } -void ChangeCursorHotspot (int curs, int x, int y) { - if ((curs < 0) || (curs >= game.numcursors)) - quit("!ChangeCursorHotspot: invalid mouse cursor"); - game.mcurs[curs].hotx = data_to_game_coord(x); - game.mcurs[curs].hoty = data_to_game_coord(y); - if (curs == cur_cursor) - set_mouse_cursor (cur_cursor); +void ChangeCursorHotspot(int curs, int x, int y) { + if ((curs < 0) || (curs >= game.numcursors)) + quit("!ChangeCursorHotspot: invalid mouse cursor"); + game.mcurs[curs].hotx = data_to_game_coord(x); + game.mcurs[curs].hoty = data_to_game_coord(y); + if (curs == cur_cursor) + set_mouse_cursor(cur_cursor); } void Mouse_ChangeModeView(int curs, int newview) { - if ((curs < 0) || (curs >= game.numcursors)) - quit("!Mouse.ChangeModeView: invalid mouse cursor"); + if ((curs < 0) || (curs >= game.numcursors)) + quit("!Mouse.ChangeModeView: invalid mouse cursor"); - newview--; + newview--; - game.mcurs[curs].view = newview; + game.mcurs[curs].view = newview; - if (newview >= 0) - { - precache_view(newview); - } + if (newview >= 0) { + precache_view(newview); + } - if (curs == cur_cursor) - mouse_delay = 0; // force update + if (curs == cur_cursor) + mouse_delay = 0; // force update } -void SetNextCursor () { - set_cursor_mode (find_next_enabled_cursor(cur_mode + 1)); +void SetNextCursor() { + set_cursor_mode(find_next_enabled_cursor(cur_mode + 1)); } void SetPreviousCursor() { - set_cursor_mode(find_previous_enabled_cursor(cur_mode - 1)); + set_cursor_mode(find_previous_enabled_cursor(cur_mode - 1)); } // set_cursor_mode: changes mode and appearance void set_cursor_mode(int newmode) { - if ((newmode < 0) || (newmode >= game.numcursors)) - quit("!SetCursorMode: invalid cursor mode specified"); - - guis_need_update = 1; - if (game.mcurs[newmode].flags & MCF_DISABLED) { - find_next_enabled_cursor(newmode); - return; } - if (newmode == MODE_USE) { - if (playerchar->activeinv == -1) { - find_next_enabled_cursor(0); - return; - } - update_inv_cursor(playerchar->activeinv); - } - cur_mode=newmode; - set_default_cursor(); - - debug_script_log("Cursor mode set to %d", newmode); + if ((newmode < 0) || (newmode >= game.numcursors)) + quit("!SetCursorMode: invalid cursor mode specified"); + + guis_need_update = 1; + if (game.mcurs[newmode].flags & MCF_DISABLED) { + find_next_enabled_cursor(newmode); + return; + } + if (newmode == MODE_USE) { + if (playerchar->activeinv == -1) { + find_next_enabled_cursor(0); + return; + } + update_inv_cursor(playerchar->activeinv); + } + cur_mode = newmode; + set_default_cursor(); + + debug_script_log("Cursor mode set to %d", newmode); } void enable_cursor_mode(int modd) { - game.mcurs[modd].flags&=~MCF_DISABLED; - // now search the interfaces for related buttons to re-enable - int uu,ww; - - for (uu=0;uuClickAction[kMouseLeft]!=kGUIAction_SetMode) continue; - if (gbpt->ClickData[kMouseLeft]!=modd) continue; - gbpt->SetEnabled(true); - } - } - guis_need_update = 1; + game.mcurs[modd].flags &= ~MCF_DISABLED; + // now search the interfaces for related buttons to re-enable + int uu, ww; + + for (uu = 0; uu < game.numgui; uu++) { + for (ww = 0; ww < guis[uu].GetControlCount(); ww++) { + if (guis[uu].GetControlType(ww) != kGUIButton) continue; + GUIButton *gbpt = (GUIButton *)guis[uu].GetControl(ww); + if (gbpt->ClickAction[kMouseLeft] != kGUIAction_SetMode) continue; + if (gbpt->ClickData[kMouseLeft] != modd) continue; + gbpt->SetEnabled(true); + } + } + guis_need_update = 1; } void disable_cursor_mode(int modd) { - game.mcurs[modd].flags|=MCF_DISABLED; - // now search the interfaces for related buttons to kill - int uu,ww; - - for (uu=0;uuClickAction[kMouseLeft]!=kGUIAction_SetMode) continue; - if (gbpt->ClickData[kMouseLeft]!=modd) continue; - gbpt->SetEnabled(false); - } - } - if (cur_mode==modd) find_next_enabled_cursor(modd); - guis_need_update = 1; + game.mcurs[modd].flags |= MCF_DISABLED; + // now search the interfaces for related buttons to kill + int uu, ww; + + for (uu = 0; uu < game.numgui; uu++) { + for (ww = 0; ww < guis[uu].GetControlCount(); ww++) { + if (guis[uu].GetControlType(ww) != kGUIButton) continue; + GUIButton *gbpt = (GUIButton *)guis[uu].GetControl(ww); + if (gbpt->ClickAction[kMouseLeft] != kGUIAction_SetMode) continue; + if (gbpt->ClickData[kMouseLeft] != modd) continue; + gbpt->SetEnabled(false); + } + } + if (cur_mode == modd) find_next_enabled_cursor(modd); + guis_need_update = 1; } void RefreshMouse() { - ags_domouse(DOMOUSE_NOCURSOR); - scmouse.x = game_to_data_coord(mousex); - scmouse.y = game_to_data_coord(mousey); + ags_domouse(DOMOUSE_NOCURSOR); + scmouse.x = game_to_data_coord(mousex); + scmouse.y = game_to_data_coord(mousey); } -void SetMousePosition (int newx, int newy) { - const Rect &viewport = play.GetMainViewport(); +void SetMousePosition(int newx, int newy) { + const Rect &viewport = play.GetMainViewport(); - if (newx < 0) - newx = 0; - if (newy < 0) - newy = 0; - if (newx >= viewport.GetWidth()) - newx = viewport.GetWidth() - 1; - if (newy >= viewport.GetHeight()) - newy = viewport.GetHeight() - 1; + if (newx < 0) + newx = 0; + if (newy < 0) + newy = 0; + if (newx >= viewport.GetWidth()) + newx = viewport.GetWidth() - 1; + if (newy >= viewport.GetHeight()) + newy = viewport.GetHeight() - 1; - data_to_game_coords(&newx, &newy); - Mouse::SetPosition(Point(newx, newy)); - RefreshMouse(); + data_to_game_coords(&newx, &newy); + Mouse::SetPosition(Point(newx, newy)); + RefreshMouse(); } int GetCursorMode() { - return cur_mode; + return cur_mode; } int IsButtonDown(int which) { - if ((which < 1) || (which > 3)) - quit("!IsButtonDown: only works with eMouseLeft, eMouseRight, eMouseMiddle"); - if (misbuttondown(which-1)) - return 1; - return 0; + if ((which < 1) || (which > 3)) + quit("!IsButtonDown: only works with eMouseLeft, eMouseRight, eMouseMiddle"); + if (misbuttondown(which - 1)) + return 1; + return 0; } int IsModeEnabled(int which) { - return (which < 0) || (which >= game.numcursors) ? 0 : - which == MODE_USE ? playerchar->activeinv > 0 : - (game.mcurs[which].flags & MCF_DISABLED) == 0; -} - -void Mouse_EnableControl(bool on) -{ - usetup.mouse_ctrl_enabled = on; // remember setting in config - - bool is_windowed = scsystem.windowed != 0; - // Whether mouse movement should be controlled by the engine - this is - // determined based on related config option. - bool should_control_mouse = usetup.mouse_ctrl_when == kMouseCtrl_Always || - (usetup.mouse_ctrl_when == kMouseCtrl_Fullscreen && !is_windowed); - // Whether mouse movement control is supported by the engine - this is - // determined on per platform basis. Some builds may not have such - // capability, e.g. because of how backend library implements mouse utils. - bool can_control_mouse = platform->IsMouseControlSupported(is_windowed); - // The resulting choice is made based on two aforementioned factors. - on &= should_control_mouse && can_control_mouse; - if (on) - Mouse::EnableControl(!is_windowed); - else - Mouse::DisableControl(); + return (which < 0) || (which >= game.numcursors) ? 0 : + which == MODE_USE ? playerchar->activeinv > 0 : + (game.mcurs[which].flags & MCF_DISABLED) == 0; +} + +void Mouse_EnableControl(bool on) { + usetup.mouse_ctrl_enabled = on; // remember setting in config + + bool is_windowed = scsystem.windowed != 0; + // Whether mouse movement should be controlled by the engine - this is + // determined based on related config option. + bool should_control_mouse = usetup.mouse_ctrl_when == kMouseCtrl_Always || + (usetup.mouse_ctrl_when == kMouseCtrl_Fullscreen && !is_windowed); + // Whether mouse movement control is supported by the engine - this is + // determined on per platform basis. Some builds may not have such + // capability, e.g. because of how backend library implements mouse utils. + bool can_control_mouse = platform->IsMouseControlSupported(is_windowed); + // The resulting choice is made based on two aforementioned factors. + on &= should_control_mouse && can_control_mouse; + if (on) + Mouse::EnableControl(!is_windowed); + else + Mouse::DisableControl(); } //============================================================================= int GetMouseCursor() { - return cur_cursor; + return cur_cursor; } void update_script_mouse_coords() { - scmouse.x = game_to_data_coord(mousex); - scmouse.y = game_to_data_coord(mousey); + scmouse.x = game_to_data_coord(mousex); + scmouse.y = game_to_data_coord(mousey); } void update_inv_cursor(int invnum) { - if ((game.options[OPT_FIXEDINVCURSOR]==0) && (invnum > 0)) { - int cursorSprite = game.invinfo[invnum].cursorPic; + if ((game.options[OPT_FIXEDINVCURSOR] == 0) && (invnum > 0)) { + int cursorSprite = game.invinfo[invnum].cursorPic; - // Fall back to the inventory pic if no cursor pic is defined. - if (cursorSprite == 0) - cursorSprite = game.invinfo[invnum].pic; + // Fall back to the inventory pic if no cursor pic is defined. + if (cursorSprite == 0) + cursorSprite = game.invinfo[invnum].pic; - game.mcurs[MODE_USE].pic = cursorSprite; - // all cursor images must be pre-cached - spriteset.Precache(cursorSprite); + game.mcurs[MODE_USE].pic = cursorSprite; + // all cursor images must be pre-cached + spriteset.Precache(cursorSprite); - if ((game.invinfo[invnum].hotx > 0) || (game.invinfo[invnum].hoty > 0)) { - // if the hotspot was set (unfortunately 0,0 isn't a valid co-ord) - game.mcurs[MODE_USE].hotx=game.invinfo[invnum].hotx; - game.mcurs[MODE_USE].hoty=game.invinfo[invnum].hoty; - } - else { - game.mcurs[MODE_USE].hotx = game.SpriteInfos[cursorSprite].Width / 2; - game.mcurs[MODE_USE].hoty = game.SpriteInfos[cursorSprite].Height / 2; - } - } + if ((game.invinfo[invnum].hotx > 0) || (game.invinfo[invnum].hoty > 0)) { + // if the hotspot was set (unfortunately 0,0 isn't a valid co-ord) + game.mcurs[MODE_USE].hotx = game.invinfo[invnum].hotx; + game.mcurs[MODE_USE].hoty = game.invinfo[invnum].hoty; + } else { + game.mcurs[MODE_USE].hotx = game.SpriteInfos[cursorSprite].Width / 2; + game.mcurs[MODE_USE].hoty = game.SpriteInfos[cursorSprite].Height / 2; + } + } } -void update_cached_mouse_cursor() -{ - if (mouseCursor != nullptr) - gfxDriver->DestroyDDB(mouseCursor); - mouseCursor = gfxDriver->CreateDDBFromBitmap(mousecurs[0], alpha_blend_cursor != 0); +void update_cached_mouse_cursor() { + if (mouseCursor != nullptr) + gfxDriver->DestroyDDB(mouseCursor); + mouseCursor = gfxDriver->CreateDDBFromBitmap(mousecurs[0], alpha_blend_cursor != 0); } -void set_new_cursor_graphic (int spriteslot) { - mousecurs[0] = spriteset[spriteslot]; +void set_new_cursor_graphic(int spriteslot) { + mousecurs[0] = spriteset[spriteslot]; - // It looks like spriteslot 0 can be used in games with version 2.72 and lower. - // The NULL check should ensure that the sprite is valid anyway. - if (((spriteslot < 1) && (loaded_game_file_version > kGameVersion_272)) || (mousecurs[0] == nullptr)) - { - if (blank_mouse_cursor == nullptr) - { - blank_mouse_cursor = BitmapHelper::CreateTransparentBitmap(1, 1, game.GetColorDepth()); - } - mousecurs[0] = blank_mouse_cursor; - } + // It looks like spriteslot 0 can be used in games with version 2.72 and lower. + // The NULL check should ensure that the sprite is valid anyway. + if (((spriteslot < 1) && (loaded_game_file_version > kGameVersion_272)) || (mousecurs[0] == nullptr)) { + if (blank_mouse_cursor == nullptr) { + blank_mouse_cursor = BitmapHelper::CreateTransparentBitmap(1, 1, game.GetColorDepth()); + } + mousecurs[0] = blank_mouse_cursor; + } - if (game.SpriteInfos[spriteslot].Flags & SPF_ALPHACHANNEL) - alpha_blend_cursor = 1; - else - alpha_blend_cursor = 0; + if (game.SpriteInfos[spriteslot].Flags & SPF_ALPHACHANNEL) + alpha_blend_cursor = 1; + else + alpha_blend_cursor = 0; - update_cached_mouse_cursor(); + update_cached_mouse_cursor(); } bool is_standard_cursor_enabled(int curs) { - if ((game.mcurs[curs].flags & MCF_DISABLED) == 0) { - // inventory cursor, and they have an active item - if (curs == MODE_USE) - { - if (playerchar->activeinv > 0) - return true; - } - // standard cursor that's not disabled, go with it - else if (game.mcurs[curs].flags & MCF_STANDARD) - return true; - } - return false; + if ((game.mcurs[curs].flags & MCF_DISABLED) == 0) { + // inventory cursor, and they have an active item + if (curs == MODE_USE) { + if (playerchar->activeinv > 0) + return true; + } + // standard cursor that's not disabled, go with it + else if (game.mcurs[curs].flags & MCF_STANDARD) + return true; + } + return false; } int find_next_enabled_cursor(int startwith) { - if (startwith >= game.numcursors) - startwith = 0; - int testing=startwith; - do { - if (is_standard_cursor_enabled(testing)) break; - testing++; - if (testing >= game.numcursors) testing=0; - } while (testing!=startwith); + if (startwith >= game.numcursors) + startwith = 0; + int testing = startwith; + do { + if (is_standard_cursor_enabled(testing)) break; + testing++; + if (testing >= game.numcursors) testing = 0; + } while (testing != startwith); - if (testing!=startwith) - set_cursor_mode(testing); + if (testing != startwith) + set_cursor_mode(testing); - return testing; + return testing; } int find_previous_enabled_cursor(int startwith) { - if (startwith < 0) - startwith = game.numcursors - 1; - int testing = startwith; - do { - if (is_standard_cursor_enabled(testing)) break; - testing--; - if (testing < 0) testing = game.numcursors - 1; - } while (testing != startwith); - - if (testing != startwith) - set_cursor_mode(testing); + if (startwith < 0) + startwith = game.numcursors - 1; + int testing = startwith; + do { + if (is_standard_cursor_enabled(testing)) break; + testing--; + if (testing < 0) testing = game.numcursors - 1; + } while (testing != startwith); - return testing; + if (testing != startwith) + set_cursor_mode(testing); + + return testing; } @@ -472,201 +459,175 @@ int find_previous_enabled_cursor(int startwith) { #include "ac/global_game.h" // void (int curs, int newslot) -RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(ChangeCursorGraphic); +RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(ChangeCursorGraphic); } // void (int curs, int x, int y) -RuntimeScriptValue Sc_ChangeCursorHotspot(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(ChangeCursorHotspot); +RuntimeScriptValue Sc_ChangeCursorHotspot(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(ChangeCursorHotspot); } // void (int curs, int newview) -RuntimeScriptValue Sc_Mouse_ChangeModeView(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(Mouse_ChangeModeView); +RuntimeScriptValue Sc_Mouse_ChangeModeView(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(Mouse_ChangeModeView); } // void (int modd) -RuntimeScriptValue Sc_disable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(disable_cursor_mode); +RuntimeScriptValue Sc_disable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(disable_cursor_mode); } // void (int modd) -RuntimeScriptValue Sc_enable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(enable_cursor_mode); +RuntimeScriptValue Sc_enable_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(enable_cursor_mode); } // int (int curs) -RuntimeScriptValue Sc_Mouse_GetModeGraphic(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(Mouse_GetModeGraphic); +RuntimeScriptValue Sc_Mouse_GetModeGraphic(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(Mouse_GetModeGraphic); } // int (int which) -RuntimeScriptValue Sc_IsButtonDown(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsButtonDown); +RuntimeScriptValue Sc_IsButtonDown(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsButtonDown); } // int (int which) -RuntimeScriptValue Sc_IsModeEnabled(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_PINT(IsModeEnabled); +RuntimeScriptValue Sc_IsModeEnabled(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_PINT(IsModeEnabled); } // void (); -RuntimeScriptValue Sc_SaveCursorForLocationChange(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(SaveCursorForLocationChange); +RuntimeScriptValue Sc_SaveCursorForLocationChange(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(SaveCursorForLocationChange); } // void () -RuntimeScriptValue Sc_SetNextCursor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(SetNextCursor); +RuntimeScriptValue Sc_SetNextCursor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(SetNextCursor); } // void () -RuntimeScriptValue Sc_SetPreviousCursor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(SetPreviousCursor); +RuntimeScriptValue Sc_SetPreviousCursor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(SetPreviousCursor); } // void (int x1, int y1, int x2, int y2) -RuntimeScriptValue Sc_SetMouseBounds(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT4(SetMouseBounds); +RuntimeScriptValue Sc_SetMouseBounds(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT4(SetMouseBounds); } // void (int newx, int newy) -RuntimeScriptValue Sc_SetMousePosition(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT2(SetMousePosition); +RuntimeScriptValue Sc_SetMousePosition(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT2(SetMousePosition); } // void () -RuntimeScriptValue Sc_RefreshMouse(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(RefreshMouse); +RuntimeScriptValue Sc_RefreshMouse(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(RefreshMouse); } // void () -RuntimeScriptValue Sc_set_default_cursor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID(set_default_cursor); +RuntimeScriptValue Sc_set_default_cursor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID(set_default_cursor); } // void (int newcurs) -RuntimeScriptValue Sc_set_mouse_cursor(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(set_mouse_cursor); +RuntimeScriptValue Sc_set_mouse_cursor(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(set_mouse_cursor); } // int () -RuntimeScriptValue Sc_GetCursorMode(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetCursorMode); +RuntimeScriptValue Sc_GetCursorMode(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetCursorMode); } // void (int newmode) -RuntimeScriptValue Sc_set_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(set_cursor_mode); +RuntimeScriptValue Sc_set_cursor_mode(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(set_cursor_mode); } // int () -RuntimeScriptValue Sc_Mouse_GetVisible(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Mouse_GetVisible); +RuntimeScriptValue Sc_Mouse_GetVisible(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Mouse_GetVisible); } // void (int isOn) -RuntimeScriptValue Sc_Mouse_SetVisible(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(Mouse_SetVisible); -} - -RuntimeScriptValue Sc_Mouse_Click(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(PluginSimulateMouseClick); -} - -RuntimeScriptValue Sc_Mouse_GetControlEnabled(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_BOOL(Mouse::IsControlEnabled); -} - -RuntimeScriptValue Sc_Mouse_SetControlEnabled(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PBOOL(Mouse_EnableControl); -} - - -RuntimeScriptValue Sc_Mouse_GetSpeed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_FLOAT(Mouse::GetSpeed); -} - -RuntimeScriptValue Sc_Mouse_SetSpeed(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_VARIABLE_VALUE("Mouse::Speed"); - Mouse::SetSpeed(params[0].FValue); - return RuntimeScriptValue(); -} - -void RegisterMouseAPI() -{ - ccAddExternalStaticFunction("Mouse::ChangeModeGraphic^2", Sc_ChangeCursorGraphic); - ccAddExternalStaticFunction("Mouse::ChangeModeHotspot^3", Sc_ChangeCursorHotspot); - ccAddExternalStaticFunction("Mouse::ChangeModeView^2", Sc_Mouse_ChangeModeView); - ccAddExternalStaticFunction("Mouse::Click^1", Sc_Mouse_Click); - ccAddExternalStaticFunction("Mouse::DisableMode^1", Sc_disable_cursor_mode); - ccAddExternalStaticFunction("Mouse::EnableMode^1", Sc_enable_cursor_mode); - ccAddExternalStaticFunction("Mouse::GetModeGraphic^1", Sc_Mouse_GetModeGraphic); - ccAddExternalStaticFunction("Mouse::IsButtonDown^1", Sc_IsButtonDown); - ccAddExternalStaticFunction("Mouse::IsModeEnabled^1", Sc_IsModeEnabled); - ccAddExternalStaticFunction("Mouse::SaveCursorUntilItLeaves^0", Sc_SaveCursorForLocationChange); - ccAddExternalStaticFunction("Mouse::SelectNextMode^0", Sc_SetNextCursor); - ccAddExternalStaticFunction("Mouse::SelectPreviousMode^0", Sc_SetPreviousCursor); - ccAddExternalStaticFunction("Mouse::SetBounds^4", Sc_SetMouseBounds); - ccAddExternalStaticFunction("Mouse::SetPosition^2", Sc_SetMousePosition); - ccAddExternalStaticFunction("Mouse::Update^0", Sc_RefreshMouse); - ccAddExternalStaticFunction("Mouse::UseDefaultGraphic^0", Sc_set_default_cursor); - ccAddExternalStaticFunction("Mouse::UseModeGraphic^1", Sc_set_mouse_cursor); - ccAddExternalStaticFunction("Mouse::get_ControlEnabled", Sc_Mouse_GetControlEnabled); - ccAddExternalStaticFunction("Mouse::set_ControlEnabled", Sc_Mouse_SetControlEnabled); - ccAddExternalStaticFunction("Mouse::get_Mode", Sc_GetCursorMode); - ccAddExternalStaticFunction("Mouse::set_Mode", Sc_set_cursor_mode); - ccAddExternalStaticFunction("Mouse::get_Speed", Sc_Mouse_GetSpeed); - ccAddExternalStaticFunction("Mouse::set_Speed", Sc_Mouse_SetSpeed); - ccAddExternalStaticFunction("Mouse::get_Visible", Sc_Mouse_GetVisible); - ccAddExternalStaticFunction("Mouse::set_Visible", Sc_Mouse_SetVisible); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Mouse::ChangeModeGraphic^2", (void*)ChangeCursorGraphic); - ccAddExternalFunctionForPlugin("Mouse::ChangeModeHotspot^3", (void*)ChangeCursorHotspot); - ccAddExternalFunctionForPlugin("Mouse::ChangeModeView^2", (void*)Mouse_ChangeModeView); - ccAddExternalFunctionForPlugin("Mouse::DisableMode^1", (void*)disable_cursor_mode); - ccAddExternalFunctionForPlugin("Mouse::EnableMode^1", (void*)enable_cursor_mode); - ccAddExternalFunctionForPlugin("Mouse::GetModeGraphic^1", (void*)Mouse_GetModeGraphic); - ccAddExternalFunctionForPlugin("Mouse::IsButtonDown^1", (void*)IsButtonDown); - ccAddExternalFunctionForPlugin("Mouse::IsModeEnabled^1", (void*)IsModeEnabled); - ccAddExternalFunctionForPlugin("Mouse::SaveCursorUntilItLeaves^0", (void*)SaveCursorForLocationChange); - ccAddExternalFunctionForPlugin("Mouse::SelectNextMode^0", (void*)SetNextCursor); - ccAddExternalFunctionForPlugin("Mouse::SelectPreviousMode^0", (void*)SetPreviousCursor); - ccAddExternalFunctionForPlugin("Mouse::SetBounds^4", (void*)SetMouseBounds); - ccAddExternalFunctionForPlugin("Mouse::SetPosition^2", (void*)SetMousePosition); - ccAddExternalFunctionForPlugin("Mouse::Update^0", (void*)RefreshMouse); - ccAddExternalFunctionForPlugin("Mouse::UseDefaultGraphic^0", (void*)set_default_cursor); - ccAddExternalFunctionForPlugin("Mouse::UseModeGraphic^1", (void*)set_mouse_cursor); - ccAddExternalFunctionForPlugin("Mouse::get_Mode", (void*)GetCursorMode); - ccAddExternalFunctionForPlugin("Mouse::set_Mode", (void*)set_cursor_mode); - ccAddExternalFunctionForPlugin("Mouse::get_Visible", (void*)Mouse_GetVisible); - ccAddExternalFunctionForPlugin("Mouse::set_Visible", (void*)Mouse_SetVisible); +RuntimeScriptValue Sc_Mouse_SetVisible(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(Mouse_SetVisible); +} + +RuntimeScriptValue Sc_Mouse_Click(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(PluginSimulateMouseClick); +} + +RuntimeScriptValue Sc_Mouse_GetControlEnabled(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_BOOL(Mouse::IsControlEnabled); +} + +RuntimeScriptValue Sc_Mouse_SetControlEnabled(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PBOOL(Mouse_EnableControl); +} + + +RuntimeScriptValue Sc_Mouse_GetSpeed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_FLOAT(Mouse::GetSpeed); +} + +RuntimeScriptValue Sc_Mouse_SetSpeed(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_VARIABLE_VALUE("Mouse::Speed"); + Mouse::SetSpeed(params[0].FValue); + return RuntimeScriptValue(); +} + +void RegisterMouseAPI() { + ccAddExternalStaticFunction("Mouse::ChangeModeGraphic^2", Sc_ChangeCursorGraphic); + ccAddExternalStaticFunction("Mouse::ChangeModeHotspot^3", Sc_ChangeCursorHotspot); + ccAddExternalStaticFunction("Mouse::ChangeModeView^2", Sc_Mouse_ChangeModeView); + ccAddExternalStaticFunction("Mouse::Click^1", Sc_Mouse_Click); + ccAddExternalStaticFunction("Mouse::DisableMode^1", Sc_disable_cursor_mode); + ccAddExternalStaticFunction("Mouse::EnableMode^1", Sc_enable_cursor_mode); + ccAddExternalStaticFunction("Mouse::GetModeGraphic^1", Sc_Mouse_GetModeGraphic); + ccAddExternalStaticFunction("Mouse::IsButtonDown^1", Sc_IsButtonDown); + ccAddExternalStaticFunction("Mouse::IsModeEnabled^1", Sc_IsModeEnabled); + ccAddExternalStaticFunction("Mouse::SaveCursorUntilItLeaves^0", Sc_SaveCursorForLocationChange); + ccAddExternalStaticFunction("Mouse::SelectNextMode^0", Sc_SetNextCursor); + ccAddExternalStaticFunction("Mouse::SelectPreviousMode^0", Sc_SetPreviousCursor); + ccAddExternalStaticFunction("Mouse::SetBounds^4", Sc_SetMouseBounds); + ccAddExternalStaticFunction("Mouse::SetPosition^2", Sc_SetMousePosition); + ccAddExternalStaticFunction("Mouse::Update^0", Sc_RefreshMouse); + ccAddExternalStaticFunction("Mouse::UseDefaultGraphic^0", Sc_set_default_cursor); + ccAddExternalStaticFunction("Mouse::UseModeGraphic^1", Sc_set_mouse_cursor); + ccAddExternalStaticFunction("Mouse::get_ControlEnabled", Sc_Mouse_GetControlEnabled); + ccAddExternalStaticFunction("Mouse::set_ControlEnabled", Sc_Mouse_SetControlEnabled); + ccAddExternalStaticFunction("Mouse::get_Mode", Sc_GetCursorMode); + ccAddExternalStaticFunction("Mouse::set_Mode", Sc_set_cursor_mode); + ccAddExternalStaticFunction("Mouse::get_Speed", Sc_Mouse_GetSpeed); + ccAddExternalStaticFunction("Mouse::set_Speed", Sc_Mouse_SetSpeed); + ccAddExternalStaticFunction("Mouse::get_Visible", Sc_Mouse_GetVisible); + ccAddExternalStaticFunction("Mouse::set_Visible", Sc_Mouse_SetVisible); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Mouse::ChangeModeGraphic^2", (void *)ChangeCursorGraphic); + ccAddExternalFunctionForPlugin("Mouse::ChangeModeHotspot^3", (void *)ChangeCursorHotspot); + ccAddExternalFunctionForPlugin("Mouse::ChangeModeView^2", (void *)Mouse_ChangeModeView); + ccAddExternalFunctionForPlugin("Mouse::DisableMode^1", (void *)disable_cursor_mode); + ccAddExternalFunctionForPlugin("Mouse::EnableMode^1", (void *)enable_cursor_mode); + ccAddExternalFunctionForPlugin("Mouse::GetModeGraphic^1", (void *)Mouse_GetModeGraphic); + ccAddExternalFunctionForPlugin("Mouse::IsButtonDown^1", (void *)IsButtonDown); + ccAddExternalFunctionForPlugin("Mouse::IsModeEnabled^1", (void *)IsModeEnabled); + ccAddExternalFunctionForPlugin("Mouse::SaveCursorUntilItLeaves^0", (void *)SaveCursorForLocationChange); + ccAddExternalFunctionForPlugin("Mouse::SelectNextMode^0", (void *)SetNextCursor); + ccAddExternalFunctionForPlugin("Mouse::SelectPreviousMode^0", (void *)SetPreviousCursor); + ccAddExternalFunctionForPlugin("Mouse::SetBounds^4", (void *)SetMouseBounds); + ccAddExternalFunctionForPlugin("Mouse::SetPosition^2", (void *)SetMousePosition); + ccAddExternalFunctionForPlugin("Mouse::Update^0", (void *)RefreshMouse); + ccAddExternalFunctionForPlugin("Mouse::UseDefaultGraphic^0", (void *)set_default_cursor); + ccAddExternalFunctionForPlugin("Mouse::UseModeGraphic^1", (void *)set_mouse_cursor); + ccAddExternalFunctionForPlugin("Mouse::get_Mode", (void *)GetCursorMode); + ccAddExternalFunctionForPlugin("Mouse::set_Mode", (void *)set_cursor_mode); + ccAddExternalFunctionForPlugin("Mouse::get_Visible", (void *)Mouse_GetVisible); + ccAddExternalFunctionForPlugin("Mouse::set_Visible", (void *)Mouse_SetVisible); } diff --git a/engines/ags/engine/ac/mouse.h b/engines/ags/engine/ac/mouse.h index a38abde70682..02893e2619e0 100644 --- a/engines/ags/engine/ac/mouse.h +++ b/engines/ags/engine/ac/mouse.h @@ -41,14 +41,14 @@ int Mouse_GetModeGraphic(int curs); void Mouse_ChangeModeView(int curs, int newview); // The Mouse:: functions are static so the script doesn't pass // in an object parameter -void SetMousePosition (int newx, int newy); +void SetMousePosition(int newx, int newy); int GetCursorMode(); -void SetNextCursor (); +void SetNextCursor(); // permanently change cursor graphic -void ChangeCursorGraphic (int curs, int newslot); -void ChangeCursorHotspot (int curs, int x, int y); +void ChangeCursorGraphic(int curs, int newslot); +void ChangeCursorHotspot(int curs, int x, int y); int IsButtonDown(int which); -void SetMouseBounds (int x1, int y1, int x2, int y2); +void SetMouseBounds(int x1, int y1, int x2, int y2); void RefreshMouse(); // mouse cursor functions: // set_mouse_cursor: changes visual appearance to specified cursor @@ -69,7 +69,7 @@ int GetMouseCursor(); void update_script_mouse_coords(); void update_inv_cursor(int invnum); void update_cached_mouse_cursor(); -void set_new_cursor_graphic (int spriteslot); +void set_new_cursor_graphic(int spriteslot); int find_next_enabled_cursor(int startwith); int find_previous_enabled_cursor(int startwith); diff --git a/engines/ags/engine/ac/movelist.cpp b/engines/ags/engine/ac/movelist.cpp index 4020726e5463..8f8d034d7a5a 100644 --- a/engines/ags/engine/ac/movelist.cpp +++ b/engines/ags/engine/ac/movelist.cpp @@ -27,66 +27,61 @@ using namespace AGS::Common; using namespace AGS::Engine; -void MoveList::ReadFromFile_Legacy(Stream *in) -{ - in->ReadArrayOfInt32(pos, MAXNEEDSTAGES_LEGACY); - numstage = in->ReadInt32(); - in->ReadArrayOfInt32(xpermove, MAXNEEDSTAGES_LEGACY); - in->ReadArrayOfInt32(ypermove, MAXNEEDSTAGES_LEGACY); - fromx = in->ReadInt32(); - fromy = in->ReadInt32(); - onstage = in->ReadInt32(); - onpart = in->ReadInt32(); - lastx = in->ReadInt32(); - lasty = in->ReadInt32(); - doneflag = in->ReadInt8(); - direct = in->ReadInt8(); +void MoveList::ReadFromFile_Legacy(Stream *in) { + in->ReadArrayOfInt32(pos, MAXNEEDSTAGES_LEGACY); + numstage = in->ReadInt32(); + in->ReadArrayOfInt32(xpermove, MAXNEEDSTAGES_LEGACY); + in->ReadArrayOfInt32(ypermove, MAXNEEDSTAGES_LEGACY); + fromx = in->ReadInt32(); + fromy = in->ReadInt32(); + onstage = in->ReadInt32(); + onpart = in->ReadInt32(); + lastx = in->ReadInt32(); + lasty = in->ReadInt32(); + doneflag = in->ReadInt8(); + direct = in->ReadInt8(); } -HSaveError MoveList::ReadFromFile(Stream *in, int32_t cmp_ver) -{ - if (cmp_ver < 1) - { - ReadFromFile_Legacy(in); - return HSaveError::None(); - } +HSaveError MoveList::ReadFromFile(Stream *in, int32_t cmp_ver) { + if (cmp_ver < 1) { + ReadFromFile_Legacy(in); + return HSaveError::None(); + } - numstage = in->ReadInt32(); - // TODO: reimplement MoveList stages as vector to avoid these limits - if (numstage > MAXNEEDSTAGES) - { - return new SavegameError(kSvgErr_IncompatibleEngine, - String::FromFormat("Incompatible number of movelist steps (count: %d, max : %d).", numstage, MAXNEEDSTAGES)); - } + numstage = in->ReadInt32(); + // TODO: reimplement MoveList stages as vector to avoid these limits + if (numstage > MAXNEEDSTAGES) { + return new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Incompatible number of movelist steps (count: %d, max : %d).", numstage, MAXNEEDSTAGES)); + } - fromx = in->ReadInt32(); - fromy = in->ReadInt32(); - onstage = in->ReadInt32(); - onpart = in->ReadInt32(); - lastx = in->ReadInt32(); - lasty = in->ReadInt32(); - doneflag = in->ReadInt8(); - direct = in->ReadInt8(); + fromx = in->ReadInt32(); + fromy = in->ReadInt32(); + onstage = in->ReadInt32(); + onpart = in->ReadInt32(); + lastx = in->ReadInt32(); + lasty = in->ReadInt32(); + doneflag = in->ReadInt8(); + direct = in->ReadInt8(); - in->ReadArrayOfInt32(pos, numstage); - in->ReadArrayOfInt32(xpermove, numstage); - in->ReadArrayOfInt32(ypermove, numstage); - return HSaveError::None(); + in->ReadArrayOfInt32(pos, numstage); + in->ReadArrayOfInt32(xpermove, numstage); + in->ReadArrayOfInt32(ypermove, numstage); + return HSaveError::None(); } -void MoveList::WriteToFile(Stream *out) -{ - out->WriteInt32(numstage); - out->WriteInt32(fromx); - out->WriteInt32(fromy); - out->WriteInt32(onstage); - out->WriteInt32(onpart); - out->WriteInt32(lastx); - out->WriteInt32(lasty); - out->WriteInt8(doneflag); - out->WriteInt8(direct); +void MoveList::WriteToFile(Stream *out) { + out->WriteInt32(numstage); + out->WriteInt32(fromx); + out->WriteInt32(fromy); + out->WriteInt32(onstage); + out->WriteInt32(onpart); + out->WriteInt32(lastx); + out->WriteInt32(lasty); + out->WriteInt8(doneflag); + out->WriteInt8(direct); - out->WriteArrayOfInt32(pos, numstage); - out->WriteArrayOfInt32(xpermove, numstage); - out->WriteArrayOfInt32(ypermove, numstage); + out->WriteArrayOfInt32(pos, numstage); + out->WriteArrayOfInt32(xpermove, numstage); + out->WriteArrayOfInt32(ypermove, numstage); } diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h index ce47eb45cbc4..8bde626f1838 100644 --- a/engines/ags/engine/ac/movelist.h +++ b/engines/ags/engine/ac/movelist.h @@ -27,25 +27,29 @@ #include "game/savegame.h" // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define MAXNEEDSTAGES 256 #define MAXNEEDSTAGES_LEGACY 40 struct MoveList { - int pos[MAXNEEDSTAGES]; - int numstage; - fixed xpermove[MAXNEEDSTAGES], ypermove[MAXNEEDSTAGES]; - int fromx, fromy; - int onstage, onpart; - int lastx, lasty; - char doneflag; - char direct; // MoveCharDirect was used or not + int pos[MAXNEEDSTAGES]; + int numstage; + fixed xpermove[MAXNEEDSTAGES], ypermove[MAXNEEDSTAGES]; + int fromx, fromy; + int onstage, onpart; + int lastx, lasty; + char doneflag; + char direct; // MoveCharDirect was used or not - void ReadFromFile_Legacy(Common::Stream *in); - AGS::Engine::HSaveError ReadFromFile(Common::Stream *in, int32_t cmp_ver); - void WriteToFile(Common::Stream *out); + void ReadFromFile_Legacy(Common::Stream *in); + AGS::Engine::HSaveError ReadFromFile(Common::Stream *in, int32_t cmp_ver); + void WriteToFile(Common::Stream *out); }; #endif diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp index 289d06090011..6cedba484f89 100644 --- a/engines/ags/engine/ac/object.cpp +++ b/engines/ags/engine/ac/object.cpp @@ -50,9 +50,9 @@ using namespace AGS::Common; extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; -extern RoomStatus*croom; -extern RoomObject*objs; -extern ViewStruct*views; +extern RoomStatus *croom; +extern RoomObject *objs; +extern ViewStruct *views; extern RoomStruct thisroom; extern ObjectCache objcache[MAX_ROOM_OBJECTS]; extern MoveList *mls; @@ -63,510 +63,491 @@ extern CCObject ccDynamicObject; int Object_IsCollidingWithObject(ScriptObject *objj, ScriptObject *obj2) { - return AreObjectsColliding(objj->id, obj2->id); + return AreObjectsColliding(objj->id, obj2->id); } ScriptObject *GetObjectAtScreen(int xx, int yy) { - int hsnum = GetObjectIDAtScreen(xx, yy); - if (hsnum < 0) - return nullptr; - return &scrObj[hsnum]; + int hsnum = GetObjectIDAtScreen(xx, yy); + if (hsnum < 0) + return nullptr; + return &scrObj[hsnum]; } -ScriptObject *GetObjectAtRoom(int x, int y) -{ - int hsnum = GetObjectIDAtRoom(x, y); - if (hsnum < 0) - return nullptr; - return &scrObj[hsnum]; +ScriptObject *GetObjectAtRoom(int x, int y) { + int hsnum = GetObjectIDAtRoom(x, y); + if (hsnum < 0) + return nullptr; + return &scrObj[hsnum]; } AGS_INLINE int is_valid_object(int obtest) { - if ((obtest < 0) || (obtest >= croom->numobj)) return 0; - return 1; + if ((obtest < 0) || (obtest >= croom->numobj)) return 0; + return 1; } void Object_Tint(ScriptObject *objj, int red, int green, int blue, int saturation, int luminance) { - SetObjectTint(objj->id, red, green, blue, saturation, luminance); + SetObjectTint(objj->id, red, green, blue, saturation, luminance); } void Object_RemoveTint(ScriptObject *objj) { - RemoveObjectTint(objj->id); + RemoveObjectTint(objj->id); } void Object_SetView(ScriptObject *objj, int view, int loop, int frame) { - if (game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v351) - { // Previous version of SetView had negative loop and frame mean "use latest values" - auto &obj = objs[objj->id]; - if (loop < 0) loop = obj.loop; - if (frame < 0) frame = obj.frame; - const int vidx = view - 1; - if (vidx < 0 || vidx >= game.numviews) quit("!Object_SetView: invalid view number used"); - loop = Math::Clamp(loop, 0, (int)views[vidx].numLoops - 1); - frame = Math::Clamp(frame, 0, (int)views[vidx].loops[loop].numFrames - 1); - } - SetObjectFrame(objj->id, view, loop, frame); + if (game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v351) { + // Previous version of SetView had negative loop and frame mean "use latest values" + auto &obj = objs[objj->id]; + if (loop < 0) loop = obj.loop; + if (frame < 0) frame = obj.frame; + const int vidx = view - 1; + if (vidx < 0 || vidx >= game.numviews) quit("!Object_SetView: invalid view number used"); + loop = Math::Clamp(loop, 0, (int)views[vidx].numLoops - 1); + frame = Math::Clamp(frame, 0, (int)views[vidx].loops[loop].numFrames - 1); + } + SetObjectFrame(objj->id, view, loop, frame); } void Object_SetTransparency(ScriptObject *objj, int trans) { - SetObjectTransparency(objj->id, trans); + SetObjectTransparency(objj->id, trans); } int Object_GetTransparency(ScriptObject *objj) { - if (!is_valid_object(objj->id)) - quit("!Object.Transparent: invalid object number specified"); + if (!is_valid_object(objj->id)) + quit("!Object.Transparent: invalid object number specified"); - return GfxDef::LegacyTrans255ToTrans100(objs[objj->id].transparent); + return GfxDef::LegacyTrans255ToTrans100(objs[objj->id].transparent); } void Object_SetBaseline(ScriptObject *objj, int basel) { - SetObjectBaseline(objj->id, basel); + SetObjectBaseline(objj->id, basel); } int Object_GetBaseline(ScriptObject *objj) { - return GetObjectBaseline(objj->id); + return GetObjectBaseline(objj->id); } void Object_AnimateFrom(ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction, int sframe) { - if (direction == FORWARDS) - direction = 0; - else if (direction == BACKWARDS) - direction = 1; - else - quit("!Object.Animate: Invalid DIRECTION parameter"); + if (direction == FORWARDS) + direction = 0; + else if (direction == BACKWARDS) + direction = 1; + else + quit("!Object.Animate: Invalid DIRECTION parameter"); - if ((blocking == BLOCKING) || (blocking == 1)) - blocking = 1; - else if ((blocking == IN_BACKGROUND) || (blocking == 0)) - blocking = 0; - else - quit("!Object.Animate: Invalid BLOCKING parameter"); + if ((blocking == BLOCKING) || (blocking == 1)) + blocking = 1; + else if ((blocking == IN_BACKGROUND) || (blocking == 0)) + blocking = 0; + else + quit("!Object.Animate: Invalid BLOCKING parameter"); - AnimateObjectImpl(objj->id, loop, delay, repeat, direction, blocking, sframe); + AnimateObjectImpl(objj->id, loop, delay, repeat, direction, blocking, sframe); } void Object_Animate(ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction) { - Object_AnimateFrom(objj, loop, delay, repeat, blocking, direction, 0); + Object_AnimateFrom(objj, loop, delay, repeat, blocking, direction, 0); } void Object_StopAnimating(ScriptObject *objj) { - if (!is_valid_object(objj->id)) - quit("!Object.StopAnimating: invalid object number"); + if (!is_valid_object(objj->id)) + quit("!Object.StopAnimating: invalid object number"); - if (objs[objj->id].cycling) { - objs[objj->id].cycling = 0; - objs[objj->id].wait = 0; - } + if (objs[objj->id].cycling) { + objs[objj->id].cycling = 0; + objs[objj->id].wait = 0; + } } void Object_MergeIntoBackground(ScriptObject *objj) { - MergeObject(objj->id); + MergeObject(objj->id); } void Object_StopMoving(ScriptObject *objj) { - StopObjectMoving(objj->id); + StopObjectMoving(objj->id); } void Object_SetVisible(ScriptObject *objj, int onoroff) { - if (onoroff) - ObjectOn(objj->id); - else - ObjectOff(objj->id); + if (onoroff) + ObjectOn(objj->id); + else + ObjectOff(objj->id); } int Object_GetView(ScriptObject *objj) { - if (objs[objj->id].view < 0) - return 0; - return objs[objj->id].view + 1; + if (objs[objj->id].view < 0) + return 0; + return objs[objj->id].view + 1; } int Object_GetLoop(ScriptObject *objj) { - if (objs[objj->id].view < 0) - return 0; - return objs[objj->id].loop; + if (objs[objj->id].view < 0) + return 0; + return objs[objj->id].loop; } int Object_GetFrame(ScriptObject *objj) { - if (objs[objj->id].view < 0) - return 0; - return objs[objj->id].frame; + if (objs[objj->id].view < 0) + return 0; + return objs[objj->id].frame; } int Object_GetVisible(ScriptObject *objj) { - return IsObjectOn(objj->id); + return IsObjectOn(objj->id); } void Object_SetGraphic(ScriptObject *objj, int slott) { - SetObjectGraphic(objj->id, slott); + SetObjectGraphic(objj->id, slott); } int Object_GetGraphic(ScriptObject *objj) { - return GetObjectGraphic(objj->id); + return GetObjectGraphic(objj->id); } -int GetObjectX (int objj) { - if (!is_valid_object(objj)) quit("!GetObjectX: invalid object number"); - return objs[objj].x; +int GetObjectX(int objj) { + if (!is_valid_object(objj)) quit("!GetObjectX: invalid object number"); + return objs[objj].x; } int Object_GetX(ScriptObject *objj) { - return GetObjectX(objj->id); + return GetObjectX(objj->id); } int Object_GetY(ScriptObject *objj) { - return GetObjectY(objj->id); + return GetObjectY(objj->id); } int Object_GetAnimating(ScriptObject *objj) { - return IsObjectAnimating(objj->id); + return IsObjectAnimating(objj->id); } int Object_GetMoving(ScriptObject *objj) { - return IsObjectMoving(objj->id); + return IsObjectMoving(objj->id); } -bool Object_HasExplicitLight(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_light(); +bool Object_HasExplicitLight(ScriptObject *obj) { + return objs[obj->id].has_explicit_light(); } -bool Object_HasExplicitTint(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_tint(); +bool Object_HasExplicitTint(ScriptObject *obj) { + return objs[obj->id].has_explicit_tint(); } -int Object_GetLightLevel(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_light() ? objs[obj->id].tint_light : 0; +int Object_GetLightLevel(ScriptObject *obj) { + return objs[obj->id].has_explicit_light() ? objs[obj->id].tint_light : 0; } -void Object_SetLightLevel(ScriptObject *objj, int light_level) -{ - int obj = objj->id; - if (!is_valid_object(obj)) - quit("!SetObjectTint: invalid object number specified"); +void Object_SetLightLevel(ScriptObject *objj, int light_level) { + int obj = objj->id; + if (!is_valid_object(obj)) + quit("!SetObjectTint: invalid object number specified"); - objs[obj].tint_light = light_level; - objs[obj].flags &= ~OBJF_HASTINT; - objs[obj].flags |= OBJF_HASLIGHT; + objs[obj].tint_light = light_level; + objs[obj].flags &= ~OBJF_HASTINT; + objs[obj].flags |= OBJF_HASLIGHT; } -int Object_GetTintRed(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_r : 0; +int Object_GetTintRed(ScriptObject *obj) { + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_r : 0; } -int Object_GetTintGreen(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_g : 0; +int Object_GetTintGreen(ScriptObject *obj) { + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_g : 0; } -int Object_GetTintBlue(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_b : 0; +int Object_GetTintBlue(ScriptObject *obj) { + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_b : 0; } -int Object_GetTintSaturation(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_level : 0; +int Object_GetTintSaturation(ScriptObject *obj) { + return objs[obj->id].has_explicit_tint() ? objs[obj->id].tint_level : 0; } -int Object_GetTintLuminance(ScriptObject *obj) -{ - return objs[obj->id].has_explicit_tint() ? ((objs[obj->id].tint_light * 10) / 25) : 0; +int Object_GetTintLuminance(ScriptObject *obj) { + return objs[obj->id].has_explicit_tint() ? ((objs[obj->id].tint_light * 10) / 25) : 0; } void Object_SetPosition(ScriptObject *objj, int xx, int yy) { - SetObjectPosition(objj->id, xx, yy); + SetObjectPosition(objj->id, xx, yy); } void Object_SetX(ScriptObject *objj, int xx) { - SetObjectPosition(objj->id, xx, objs[objj->id].y); + SetObjectPosition(objj->id, xx, objs[objj->id].y); } void Object_SetY(ScriptObject *objj, int yy) { - SetObjectPosition(objj->id, objs[objj->id].x, yy); + SetObjectPosition(objj->id, objs[objj->id].x, yy); } void Object_GetName(ScriptObject *objj, char *buffer) { - GetObjectName(objj->id, buffer); + GetObjectName(objj->id, buffer); } -const char* Object_GetName_New(ScriptObject *objj) { - if (!is_valid_object(objj->id)) - quit("!Object.Name: invalid object number"); +const char *Object_GetName_New(ScriptObject *objj) { + if (!is_valid_object(objj->id)) + quit("!Object.Name: invalid object number"); - return CreateNewScriptString(get_translation(thisroom.Objects[objj->id].Name)); + return CreateNewScriptString(get_translation(thisroom.Objects[objj->id].Name)); } bool Object_IsInteractionAvailable(ScriptObject *oobj, int mood) { - play.check_interaction_only = 1; - RunObjectInteraction(oobj->id, mood); - int ciwas = play.check_interaction_only; - play.check_interaction_only = 0; - return (ciwas == 2); + play.check_interaction_only = 1; + RunObjectInteraction(oobj->id, mood); + int ciwas = play.check_interaction_only; + play.check_interaction_only = 0; + return (ciwas == 2); } void Object_Move(ScriptObject *objj, int x, int y, int speed, int blocking, int direct) { - if ((direct == ANYWHERE) || (direct == 1)) - direct = 1; - else if ((direct == WALKABLE_AREAS) || (direct == 0)) - direct = 0; - else - quit("Object.Move: invalid DIRECT parameter"); + if ((direct == ANYWHERE) || (direct == 1)) + direct = 1; + else if ((direct == WALKABLE_AREAS) || (direct == 0)) + direct = 0; + else + quit("Object.Move: invalid DIRECT parameter"); - move_object(objj->id, x, y, speed, direct); + move_object(objj->id, x, y, speed, direct); - if ((blocking == BLOCKING) || (blocking == 1)) - GameLoopUntilValueIsZero(&objs[objj->id].moving); - else if ((blocking != IN_BACKGROUND) && (blocking != 0)) - quit("Object.Move: invalid BLOCKING paramter"); + if ((blocking == BLOCKING) || (blocking == 1)) + GameLoopUntilValueIsZero(&objs[objj->id].moving); + else if ((blocking != IN_BACKGROUND) && (blocking != 0)) + quit("Object.Move: invalid BLOCKING paramter"); } void Object_SetClickable(ScriptObject *objj, int clik) { - SetObjectClickable(objj->id, clik); + SetObjectClickable(objj->id, clik); } int Object_GetClickable(ScriptObject *objj) { - if (!is_valid_object(objj->id)) - quit("!Object.Clickable: Invalid object specified"); + if (!is_valid_object(objj->id)) + quit("!Object.Clickable: Invalid object specified"); - if (objs[objj->id].flags & OBJF_NOINTERACT) - return 0; - return 1; + if (objs[objj->id].flags & OBJF_NOINTERACT) + return 0; + return 1; } -void Object_SetManualScaling(ScriptObject *objj, bool on) -{ - if (on) objs[objj->id].flags &= ~OBJF_USEROOMSCALING; - else objs[objj->id].flags |= OBJF_USEROOMSCALING; - // clear the cache - objcache[objj->id].ywas = -9999; +void Object_SetManualScaling(ScriptObject *objj, bool on) { + if (on) objs[objj->id].flags &= ~OBJF_USEROOMSCALING; + else objs[objj->id].flags |= OBJF_USEROOMSCALING; + // clear the cache + objcache[objj->id].ywas = -9999; } void Object_SetIgnoreScaling(ScriptObject *objj, int newval) { - if (!is_valid_object(objj->id)) - quit("!Object.IgnoreScaling: Invalid object specified"); - if (newval) - objs[objj->id].zoom = 100; // compatibility, for before manual scaling existed - Object_SetManualScaling(objj, newval != 0); + if (!is_valid_object(objj->id)) + quit("!Object.IgnoreScaling: Invalid object specified"); + if (newval) + objs[objj->id].zoom = 100; // compatibility, for before manual scaling existed + Object_SetManualScaling(objj, newval != 0); } int Object_GetIgnoreScaling(ScriptObject *objj) { - if (!is_valid_object(objj->id)) - quit("!Object.IgnoreScaling: Invalid object specified"); + if (!is_valid_object(objj->id)) + quit("!Object.IgnoreScaling: Invalid object specified"); - if (objs[objj->id].flags & OBJF_USEROOMSCALING) - return 0; - return 1; + if (objs[objj->id].flags & OBJF_USEROOMSCALING) + return 0; + return 1; } int Object_GetScaling(ScriptObject *objj) { - return objs[objj->id].zoom; + return objs[objj->id].zoom; } void Object_SetScaling(ScriptObject *objj, int zoomlevel) { - if ((objs[objj->id].flags & OBJF_USEROOMSCALING) != 0) - { - debug_script_warn("Object.Scaling: cannot set property unless ManualScaling is enabled"); - return; - } - int zoom_fixed = Math::Clamp(zoomlevel, 1, (int)(INT16_MAX)); // RoomObject.zoom is int16 - if (zoomlevel != zoom_fixed) - debug_script_warn("Object.Scaling: scaling level must be between 1 and %d%%", (int)(INT16_MAX)); - objs[objj->id].zoom = zoom_fixed; + if ((objs[objj->id].flags & OBJF_USEROOMSCALING) != 0) { + debug_script_warn("Object.Scaling: cannot set property unless ManualScaling is enabled"); + return; + } + int zoom_fixed = Math::Clamp(zoomlevel, 1, (int)(INT16_MAX)); // RoomObject.zoom is int16 + if (zoomlevel != zoom_fixed) + debug_script_warn("Object.Scaling: scaling level must be between 1 and %d%%", (int)(INT16_MAX)); + objs[objj->id].zoom = zoom_fixed; } void Object_SetSolid(ScriptObject *objj, int solid) { - objs[objj->id].flags &= ~OBJF_SOLID; - if (solid) - objs[objj->id].flags |= OBJF_SOLID; + objs[objj->id].flags &= ~OBJF_SOLID; + if (solid) + objs[objj->id].flags |= OBJF_SOLID; } int Object_GetSolid(ScriptObject *objj) { - if (objs[objj->id].flags & OBJF_SOLID) - return 1; - return 0; + if (objs[objj->id].flags & OBJF_SOLID) + return 1; + return 0; } void Object_SetBlockingWidth(ScriptObject *objj, int bwid) { - objs[objj->id].blocking_width = bwid; + objs[objj->id].blocking_width = bwid; } int Object_GetBlockingWidth(ScriptObject *objj) { - return objs[objj->id].blocking_width; + return objs[objj->id].blocking_width; } void Object_SetBlockingHeight(ScriptObject *objj, int bhit) { - objs[objj->id].blocking_height = bhit; + objs[objj->id].blocking_height = bhit; } int Object_GetBlockingHeight(ScriptObject *objj) { - return objs[objj->id].blocking_height; + return objs[objj->id].blocking_height; } int Object_GetID(ScriptObject *objj) { - return objj->id; + return objj->id; } void Object_SetIgnoreWalkbehinds(ScriptObject *chaa, int clik) { - SetObjectIgnoreWalkbehinds(chaa->id, clik); + SetObjectIgnoreWalkbehinds(chaa->id, clik); } int Object_GetIgnoreWalkbehinds(ScriptObject *chaa) { - if (!is_valid_object(chaa->id)) - quit("!Object.IgnoreWalkbehinds: Invalid object specified"); + if (!is_valid_object(chaa->id)) + quit("!Object.IgnoreWalkbehinds: Invalid object specified"); - if (objs[chaa->id].flags & OBJF_NOWALKBEHINDS) - return 1; - return 0; + if (objs[chaa->id].flags & OBJF_NOWALKBEHINDS) + return 1; + return 0; } -void move_object(int objj,int tox,int toy,int spee,int ignwal) { +void move_object(int objj, int tox, int toy, int spee, int ignwal) { - if (!is_valid_object(objj)) - quit("!MoveObject: invalid object number"); + if (!is_valid_object(objj)) + quit("!MoveObject: invalid object number"); - // AGS <= 2.61 uses MoveObject with spp=-1 internally instead of SetObjectPosition - if ((loaded_game_file_version <= kGameVersion_261) && (spee == -1)) - { - objs[objj].x = tox; - objs[objj].y = toy; - return; - } + // AGS <= 2.61 uses MoveObject with spp=-1 internally instead of SetObjectPosition + if ((loaded_game_file_version <= kGameVersion_261) && (spee == -1)) { + objs[objj].x = tox; + objs[objj].y = toy; + return; + } - debug_script_log("Object %d start move to %d,%d", objj, tox, toy); + debug_script_log("Object %d start move to %d,%d", objj, tox, toy); - int objX = room_to_mask_coord(objs[objj].x); - int objY = room_to_mask_coord(objs[objj].y); - tox = room_to_mask_coord(tox); - toy = room_to_mask_coord(toy); + int objX = room_to_mask_coord(objs[objj].x); + int objY = room_to_mask_coord(objs[objj].y); + tox = room_to_mask_coord(tox); + toy = room_to_mask_coord(toy); - set_route_move_speed(spee, spee); - set_color_depth(8); - int mslot=find_route(objX, objY, tox, toy, prepare_walkable_areas(-1), objj+1, 1, ignwal); - set_color_depth(game.GetColorDepth()); - if (mslot>0) { - objs[objj].moving = mslot; - mls[mslot].direct = ignwal; - convert_move_path_to_room_resolution(&mls[mslot]); - } + set_route_move_speed(spee, spee); + set_color_depth(8); + int mslot = find_route(objX, objY, tox, toy, prepare_walkable_areas(-1), objj + 1, 1, ignwal); + set_color_depth(game.GetColorDepth()); + if (mslot > 0) { + objs[objj].moving = mslot; + mls[mslot].direct = ignwal; + convert_move_path_to_room_resolution(&mls[mslot]); + } } void Object_RunInteraction(ScriptObject *objj, int mode) { - RunObjectInteraction(objj->id, mode); + RunObjectInteraction(objj->id, mode); } -int Object_GetProperty (ScriptObject *objj, const char *property) { - return GetObjectProperty(objj->id, property); +int Object_GetProperty(ScriptObject *objj, const char *property) { + return GetObjectProperty(objj->id, property); } void Object_GetPropertyText(ScriptObject *objj, const char *property, char *bufer) { - GetObjectPropertyText(objj->id, property, bufer); + GetObjectPropertyText(objj->id, property, bufer); } -const char* Object_GetTextProperty(ScriptObject *objj, const char *property) -{ - return get_text_property_dynamic_string(thisroom.Objects[objj->id].Properties, croom->objProps[objj->id], property); +const char *Object_GetTextProperty(ScriptObject *objj, const char *property) { + return get_text_property_dynamic_string(thisroom.Objects[objj->id].Properties, croom->objProps[objj->id], property); } -bool Object_SetProperty(ScriptObject *objj, const char *property, int value) -{ - return set_int_property(croom->objProps[objj->id], property, value); +bool Object_SetProperty(ScriptObject *objj, const char *property, int value) { + return set_int_property(croom->objProps[objj->id], property, value); } -bool Object_SetTextProperty(ScriptObject *objj, const char *property, const char *value) -{ - return set_text_property(croom->objProps[objj->id], property, value); +bool Object_SetTextProperty(ScriptObject *objj, const char *property, const char *value) { + return set_text_property(croom->objProps[objj->id], property, value); } void get_object_blocking_rect(int objid, int *x1, int *y1, int *width, int *y2) { - RoomObject *tehobj = &objs[objid]; - int cwidth, fromx; - - if (tehobj->blocking_width < 1) - cwidth = game_to_data_coord(tehobj->last_width) - 4; - else - cwidth = tehobj->blocking_width; - - fromx = tehobj->x + (game_to_data_coord(tehobj->last_width) / 2) - cwidth / 2; - if (fromx < 0) { - cwidth += fromx; - fromx = 0; - } - if (fromx + cwidth >= mask_to_room_coord(walkable_areas_temp->GetWidth())) - cwidth = mask_to_room_coord(walkable_areas_temp->GetWidth()) - fromx; - - if (x1) - *x1 = fromx; - if (width) - *width = cwidth; - if (y1) { - if (tehobj->blocking_height > 0) - *y1 = tehobj->y - tehobj->blocking_height / 2; - else - *y1 = tehobj->y - 2; - } - if (y2) { - if (tehobj->blocking_height > 0) - *y2 = tehobj->y + tehobj->blocking_height / 2; - else - *y2 = tehobj->y + 3; - } -} - -int isposinbox(int mmx,int mmy,int lf,int tp,int rt,int bt) { - if ((mmx>=lf) & (mmx<=rt) & (mmy>=tp) & (mmy<=bt)) return TRUE; - else return FALSE; + RoomObject *tehobj = &objs[objid]; + int cwidth, fromx; + + if (tehobj->blocking_width < 1) + cwidth = game_to_data_coord(tehobj->last_width) - 4; + else + cwidth = tehobj->blocking_width; + + fromx = tehobj->x + (game_to_data_coord(tehobj->last_width) / 2) - cwidth / 2; + if (fromx < 0) { + cwidth += fromx; + fromx = 0; + } + if (fromx + cwidth >= mask_to_room_coord(walkable_areas_temp->GetWidth())) + cwidth = mask_to_room_coord(walkable_areas_temp->GetWidth()) - fromx; + + if (x1) + *x1 = fromx; + if (width) + *width = cwidth; + if (y1) { + if (tehobj->blocking_height > 0) + *y1 = tehobj->y - tehobj->blocking_height / 2; + else + *y1 = tehobj->y - 2; + } + if (y2) { + if (tehobj->blocking_height > 0) + *y2 = tehobj->y + tehobj->blocking_height / 2; + else + *y2 = tehobj->y + 3; + } +} + +int isposinbox(int mmx, int mmy, int lf, int tp, int rt, int bt) { + if ((mmx >= lf) & (mmx <= rt) & (mmy >= tp) & (mmy <= bt)) return TRUE; + else return FALSE; } // xx,yy is the position in room co-ordinates that we are checking // arx,ary is the sprite x/y co-ordinates -int is_pos_in_sprite(int xx,int yy,int arx,int ary, Bitmap *sprit, int spww,int sphh, int flipped) { - if (spww==0) spww = game_to_data_coord(sprit->GetWidth()) - 1; - if (sphh==0) sphh = game_to_data_coord(sprit->GetHeight()) - 1; +int is_pos_in_sprite(int xx, int yy, int arx, int ary, Bitmap *sprit, int spww, int sphh, int flipped) { + if (spww == 0) spww = game_to_data_coord(sprit->GetWidth()) - 1; + if (sphh == 0) sphh = game_to_data_coord(sprit->GetHeight()) - 1; - if (isposinbox(xx,yy,arx,ary,arx+spww,ary+sphh)==FALSE) - return FALSE; + if (isposinbox(xx, yy, arx, ary, arx + spww, ary + sphh) == FALSE) + return FALSE; - if (game.options[OPT_PIXPERFECT]) - { - // if it's transparent, or off the edge of the sprite, ignore - int xpos = data_to_game_coord(xx - arx); - int ypos = data_to_game_coord(yy - ary); + if (game.options[OPT_PIXPERFECT]) { + // if it's transparent, or off the edge of the sprite, ignore + int xpos = data_to_game_coord(xx - arx); + int ypos = data_to_game_coord(yy - ary); - if (gfxDriver->HasAcceleratedTransform()) - { - // hardware acceleration, so the sprite in memory will not have - // been stretched, it will be original size. Thus, adjust our - // calculations to compensate - data_to_game_coords(&spww, &sphh); + if (gfxDriver->HasAcceleratedTransform()) { + // hardware acceleration, so the sprite in memory will not have + // been stretched, it will be original size. Thus, adjust our + // calculations to compensate + data_to_game_coords(&spww, &sphh); - if (spww != sprit->GetWidth()) - xpos = (xpos * sprit->GetWidth()) / spww; - if (sphh != sprit->GetHeight()) - ypos = (ypos * sprit->GetHeight()) / sphh; - } + if (spww != sprit->GetWidth()) + xpos = (xpos * sprit->GetWidth()) / spww; + if (sphh != sprit->GetHeight()) + ypos = (ypos * sprit->GetHeight()) / sphh; + } - if (flipped) - xpos = (sprit->GetWidth() - 1) - xpos; + if (flipped) + xpos = (sprit->GetWidth() - 1) - xpos; - int gpcol = my_getpixel(sprit, xpos, ypos); + int gpcol = my_getpixel(sprit, xpos, ypos); - if ((gpcol == sprit->GetMaskColor()) || (gpcol == -1)) - return FALSE; - } - return TRUE; + if ((gpcol == sprit->GetMaskColor()) || (gpcol == -1)) + return FALSE; + } + return TRUE; } // X and Y co-ordinates must be in native format (TODO: find out if this comment is still true) -int check_click_on_object(int roomx, int roomy, int mood) -{ - int aa = GetObjectIDAtRoom(roomx, roomy); - if (aa < 0) return 0; - RunObjectInteraction(aa, mood); - return 1; +int check_click_on_object(int roomx, int roomy, int mood) { + int aa = GetObjectIDAtRoom(roomx, roomy); + if (aa < 0) return 0; + RunObjectInteraction(aa, mood); + return 1; } //============================================================================= @@ -583,496 +564,431 @@ int check_click_on_object(int roomx, int roomy, int mood) extern ScriptString myScriptStringImpl; // void (ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction) -RuntimeScriptValue Sc_Object_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(ScriptObject, Object_Animate); +RuntimeScriptValue Sc_Object_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(ScriptObject, Object_Animate); } -RuntimeScriptValue Sc_Object_AnimateFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT6(ScriptObject, Object_AnimateFrom); +RuntimeScriptValue Sc_Object_AnimateFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT6(ScriptObject, Object_AnimateFrom); } // int (ScriptObject *objj, ScriptObject *obj2) -RuntimeScriptValue Sc_Object_IsCollidingWithObject(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(ScriptObject, Object_IsCollidingWithObject, ScriptObject); +RuntimeScriptValue Sc_Object_IsCollidingWithObject(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(ScriptObject, Object_IsCollidingWithObject, ScriptObject); } // void (ScriptObject *objj, char *buffer) -RuntimeScriptValue Sc_Object_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(ScriptObject, Object_GetName, char); +RuntimeScriptValue Sc_Object_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(ScriptObject, Object_GetName, char); } // int (ScriptObject *objj, const char *property) -RuntimeScriptValue Sc_Object_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(ScriptObject, Object_GetProperty, const char); +RuntimeScriptValue Sc_Object_GetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(ScriptObject, Object_GetProperty, const char); } // void (ScriptObject *objj, const char *property, char *bufer) -RuntimeScriptValue Sc_Object_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ2(ScriptObject, Object_GetPropertyText, const char, char); +RuntimeScriptValue Sc_Object_GetPropertyText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ2(ScriptObject, Object_GetPropertyText, const char, char); } //const char* (ScriptObject *objj, const char *property) -RuntimeScriptValue Sc_Object_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_POBJ(ScriptObject, const char, myScriptStringImpl, Object_GetTextProperty, const char); +RuntimeScriptValue Sc_Object_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_POBJ(ScriptObject, const char, myScriptStringImpl, Object_GetTextProperty, const char); } -RuntimeScriptValue Sc_Object_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ_PINT(ScriptObject, Object_SetProperty, const char); +RuntimeScriptValue Sc_Object_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ_PINT(ScriptObject, Object_SetProperty, const char); } -RuntimeScriptValue Sc_Object_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ2(ScriptObject, Object_SetTextProperty, const char, const char); +RuntimeScriptValue Sc_Object_SetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ2(ScriptObject, Object_SetTextProperty, const char, const char); } // void (ScriptObject *objj) -RuntimeScriptValue Sc_Object_MergeIntoBackground(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptObject, Object_MergeIntoBackground); +RuntimeScriptValue Sc_Object_MergeIntoBackground(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptObject, Object_MergeIntoBackground); } -RuntimeScriptValue Sc_Object_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_PINT(ScriptObject, Object_IsInteractionAvailable); +RuntimeScriptValue Sc_Object_IsInteractionAvailable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_PINT(ScriptObject, Object_IsInteractionAvailable); } // void (ScriptObject *objj, int x, int y, int speed, int blocking, int direct) -RuntimeScriptValue Sc_Object_Move(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(ScriptObject, Object_Move); +RuntimeScriptValue Sc_Object_Move(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(ScriptObject, Object_Move); } // void (ScriptObject *objj) -RuntimeScriptValue Sc_Object_RemoveTint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptObject, Object_RemoveTint); +RuntimeScriptValue Sc_Object_RemoveTint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptObject, Object_RemoveTint); } // void (ScriptObject *objj, int mode) -RuntimeScriptValue Sc_Object_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_RunInteraction); +RuntimeScriptValue Sc_Object_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_RunInteraction); } -RuntimeScriptValue Sc_Object_HasExplicitLight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(ScriptObject, Object_HasExplicitLight); +RuntimeScriptValue Sc_Object_HasExplicitLight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(ScriptObject, Object_HasExplicitLight); } -RuntimeScriptValue Sc_Object_HasExplicitTint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(ScriptObject, Object_HasExplicitTint); +RuntimeScriptValue Sc_Object_HasExplicitTint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(ScriptObject, Object_HasExplicitTint); } -RuntimeScriptValue Sc_Object_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetLightLevel); +RuntimeScriptValue Sc_Object_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetLightLevel); } -RuntimeScriptValue Sc_Object_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetLightLevel); +RuntimeScriptValue Sc_Object_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetLightLevel); } -RuntimeScriptValue Sc_Object_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetTintBlue); +RuntimeScriptValue Sc_Object_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetTintBlue); } -RuntimeScriptValue Sc_Object_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetTintGreen); +RuntimeScriptValue Sc_Object_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetTintGreen); } -RuntimeScriptValue Sc_Object_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetTintRed); +RuntimeScriptValue Sc_Object_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetTintRed); } -RuntimeScriptValue Sc_Object_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetTintSaturation); +RuntimeScriptValue Sc_Object_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetTintSaturation); } -RuntimeScriptValue Sc_Object_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetTintLuminance); +RuntimeScriptValue Sc_Object_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetTintLuminance); } // void (ScriptObject *objj, int xx, int yy) -RuntimeScriptValue Sc_Object_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptObject, Object_SetPosition); +RuntimeScriptValue Sc_Object_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptObject, Object_SetPosition); } // void (ScriptObject *objj, int view, int loop, int frame) -RuntimeScriptValue Sc_Object_SetView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT3(ScriptObject, Object_SetView); +RuntimeScriptValue Sc_Object_SetView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT3(ScriptObject, Object_SetView); } // void (ScriptObject *objj) -RuntimeScriptValue Sc_Object_StopAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptObject, Object_StopAnimating); +RuntimeScriptValue Sc_Object_StopAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptObject, Object_StopAnimating); } // void (ScriptObject *objj) -RuntimeScriptValue Sc_Object_StopMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptObject, Object_StopMoving); +RuntimeScriptValue Sc_Object_StopMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptObject, Object_StopMoving); } // void (ScriptObject *objj, int red, int green, int blue, int saturation, int luminance) -RuntimeScriptValue Sc_Object_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(ScriptObject, Object_Tint); +RuntimeScriptValue Sc_Object_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(ScriptObject, Object_Tint); } -RuntimeScriptValue Sc_GetObjectAtRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtRoom); +RuntimeScriptValue Sc_GetObjectAtRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtRoom); } // ScriptObject *(int xx, int yy) -RuntimeScriptValue Sc_GetObjectAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtScreen); +RuntimeScriptValue Sc_GetObjectAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtScreen); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetAnimating); +RuntimeScriptValue Sc_Object_GetAnimating(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetAnimating); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetBaseline); +RuntimeScriptValue Sc_Object_GetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetBaseline); } // void (ScriptObject *objj, int basel) -RuntimeScriptValue Sc_Object_SetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBaseline); +RuntimeScriptValue Sc_Object_SetBaseline(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBaseline); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetBlockingHeight); +RuntimeScriptValue Sc_Object_GetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetBlockingHeight); } // void (ScriptObject *objj, int bhit) -RuntimeScriptValue Sc_Object_SetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBlockingHeight); +RuntimeScriptValue Sc_Object_SetBlockingHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBlockingHeight); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetBlockingWidth); +RuntimeScriptValue Sc_Object_GetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetBlockingWidth); } // void (ScriptObject *objj, int bwid) -RuntimeScriptValue Sc_Object_SetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBlockingWidth); +RuntimeScriptValue Sc_Object_SetBlockingWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetBlockingWidth); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetClickable); +RuntimeScriptValue Sc_Object_GetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetClickable); } // void (ScriptObject *objj, int clik) -RuntimeScriptValue Sc_Object_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetClickable); +RuntimeScriptValue Sc_Object_SetClickable(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetClickable); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetFrame); +RuntimeScriptValue Sc_Object_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetFrame); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetGraphic); +RuntimeScriptValue Sc_Object_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetGraphic); } // void (ScriptObject *objj, int slott) -RuntimeScriptValue Sc_Object_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetGraphic); +RuntimeScriptValue Sc_Object_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetGraphic); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetID); +RuntimeScriptValue Sc_Object_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetID); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetIgnoreScaling); +RuntimeScriptValue Sc_Object_GetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetIgnoreScaling); } // void (ScriptObject *objj, int newval) -RuntimeScriptValue Sc_Object_SetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetIgnoreScaling); +RuntimeScriptValue Sc_Object_SetIgnoreScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetIgnoreScaling); } // int (ScriptObject *chaa) -RuntimeScriptValue Sc_Object_GetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetIgnoreWalkbehinds); +RuntimeScriptValue Sc_Object_GetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetIgnoreWalkbehinds); } // void (ScriptObject *chaa, int clik) -RuntimeScriptValue Sc_Object_SetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetIgnoreWalkbehinds); +RuntimeScriptValue Sc_Object_SetIgnoreWalkbehinds(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetIgnoreWalkbehinds); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetLoop); +RuntimeScriptValue Sc_Object_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetLoop); } -RuntimeScriptValue Sc_Object_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PBOOL(ScriptObject, Object_SetManualScaling); +RuntimeScriptValue Sc_Object_SetManualScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PBOOL(ScriptObject, Object_SetManualScaling); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetMoving); +RuntimeScriptValue Sc_Object_GetMoving(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetMoving); } // const char* (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptObject, const char, myScriptStringImpl, Object_GetName_New); +RuntimeScriptValue Sc_Object_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptObject, const char, myScriptStringImpl, Object_GetName_New); } -RuntimeScriptValue Sc_Object_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetScaling); +RuntimeScriptValue Sc_Object_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetScaling); } -RuntimeScriptValue Sc_Object_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetScaling); +RuntimeScriptValue Sc_Object_SetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetScaling); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetSolid); +RuntimeScriptValue Sc_Object_GetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetSolid); } // void (ScriptObject *objj, int solid) -RuntimeScriptValue Sc_Object_SetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetSolid); +RuntimeScriptValue Sc_Object_SetSolid(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetSolid); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetTransparency); +RuntimeScriptValue Sc_Object_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetTransparency); } // void (ScriptObject *objj, int trans) -RuntimeScriptValue Sc_Object_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetTransparency); +RuntimeScriptValue Sc_Object_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetTransparency); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetView); +RuntimeScriptValue Sc_Object_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetView); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetVisible); +RuntimeScriptValue Sc_Object_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetVisible); } // void (ScriptObject *objj, int onoroff) -RuntimeScriptValue Sc_Object_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetVisible); +RuntimeScriptValue Sc_Object_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetVisible); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetX); +RuntimeScriptValue Sc_Object_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetX); } // void (ScriptObject *objj, int xx) -RuntimeScriptValue Sc_Object_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetX); +RuntimeScriptValue Sc_Object_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetX); } // int (ScriptObject *objj) -RuntimeScriptValue Sc_Object_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptObject, Object_GetY); +RuntimeScriptValue Sc_Object_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptObject, Object_GetY); } // void (ScriptObject *objj, int yy) -RuntimeScriptValue Sc_Object_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptObject, Object_SetY); -} - - - -void RegisterObjectAPI() -{ - ccAddExternalObjectFunction("Object::Animate^5", Sc_Object_Animate); - ccAddExternalObjectFunction("Object::Animate^6", Sc_Object_AnimateFrom); - ccAddExternalObjectFunction("Object::IsCollidingWithObject^1", Sc_Object_IsCollidingWithObject); - ccAddExternalObjectFunction("Object::GetName^1", Sc_Object_GetName); - ccAddExternalObjectFunction("Object::GetProperty^1", Sc_Object_GetProperty); - ccAddExternalObjectFunction("Object::GetPropertyText^2", Sc_Object_GetPropertyText); - ccAddExternalObjectFunction("Object::GetTextProperty^1", Sc_Object_GetTextProperty); - ccAddExternalObjectFunction("Object::SetProperty^2", Sc_Object_SetProperty); - ccAddExternalObjectFunction("Object::SetTextProperty^2", Sc_Object_SetTextProperty); - ccAddExternalObjectFunction("Object::IsInteractionAvailable^1", Sc_Object_IsInteractionAvailable); - ccAddExternalObjectFunction("Object::MergeIntoBackground^0", Sc_Object_MergeIntoBackground); - ccAddExternalObjectFunction("Object::Move^5", Sc_Object_Move); - ccAddExternalObjectFunction("Object::RemoveTint^0", Sc_Object_RemoveTint); - ccAddExternalObjectFunction("Object::RunInteraction^1", Sc_Object_RunInteraction); - ccAddExternalObjectFunction("Object::SetLightLevel^1", Sc_Object_SetLightLevel); - ccAddExternalObjectFunction("Object::SetPosition^2", Sc_Object_SetPosition); - ccAddExternalObjectFunction("Object::SetView^3", Sc_Object_SetView); - ccAddExternalObjectFunction("Object::StopAnimating^0", Sc_Object_StopAnimating); - ccAddExternalObjectFunction("Object::StopMoving^0", Sc_Object_StopMoving); - ccAddExternalObjectFunction("Object::Tint^5", Sc_Object_Tint); - - // static - ccAddExternalStaticFunction("Object::GetAtRoomXY^2", Sc_GetObjectAtRoom); - ccAddExternalStaticFunction("Object::GetAtScreenXY^2", Sc_GetObjectAtScreen); - - ccAddExternalObjectFunction("Object::get_Animating", Sc_Object_GetAnimating); - ccAddExternalObjectFunction("Object::get_Baseline", Sc_Object_GetBaseline); - ccAddExternalObjectFunction("Object::set_Baseline", Sc_Object_SetBaseline); - ccAddExternalObjectFunction("Object::get_BlockingHeight", Sc_Object_GetBlockingHeight); - ccAddExternalObjectFunction("Object::set_BlockingHeight", Sc_Object_SetBlockingHeight); - ccAddExternalObjectFunction("Object::get_BlockingWidth", Sc_Object_GetBlockingWidth); - ccAddExternalObjectFunction("Object::set_BlockingWidth", Sc_Object_SetBlockingWidth); - ccAddExternalObjectFunction("Object::get_Clickable", Sc_Object_GetClickable); - ccAddExternalObjectFunction("Object::set_Clickable", Sc_Object_SetClickable); - ccAddExternalObjectFunction("Object::get_Frame", Sc_Object_GetFrame); - ccAddExternalObjectFunction("Object::get_Graphic", Sc_Object_GetGraphic); - ccAddExternalObjectFunction("Object::set_Graphic", Sc_Object_SetGraphic); - ccAddExternalObjectFunction("Object::get_ID", Sc_Object_GetID); - ccAddExternalObjectFunction("Object::get_IgnoreScaling", Sc_Object_GetIgnoreScaling); - ccAddExternalObjectFunction("Object::set_IgnoreScaling", Sc_Object_SetIgnoreScaling); - ccAddExternalObjectFunction("Object::get_IgnoreWalkbehinds", Sc_Object_GetIgnoreWalkbehinds); - ccAddExternalObjectFunction("Object::set_IgnoreWalkbehinds", Sc_Object_SetIgnoreWalkbehinds); - ccAddExternalObjectFunction("Object::get_Loop", Sc_Object_GetLoop); - ccAddExternalObjectFunction("Object::get_ManualScaling", Sc_Object_GetIgnoreScaling); - ccAddExternalObjectFunction("Object::set_ManualScaling", Sc_Object_SetManualScaling); - ccAddExternalObjectFunction("Object::get_Moving", Sc_Object_GetMoving); - ccAddExternalObjectFunction("Object::get_Name", Sc_Object_GetName_New); - ccAddExternalObjectFunction("Object::get_Scaling", Sc_Object_GetScaling); - ccAddExternalObjectFunction("Object::set_Scaling", Sc_Object_SetScaling); - ccAddExternalObjectFunction("Object::get_Solid", Sc_Object_GetSolid); - ccAddExternalObjectFunction("Object::set_Solid", Sc_Object_SetSolid); - ccAddExternalObjectFunction("Object::get_Transparency", Sc_Object_GetTransparency); - ccAddExternalObjectFunction("Object::set_Transparency", Sc_Object_SetTransparency); - ccAddExternalObjectFunction("Object::get_View", Sc_Object_GetView); - ccAddExternalObjectFunction("Object::get_Visible", Sc_Object_GetVisible); - ccAddExternalObjectFunction("Object::set_Visible", Sc_Object_SetVisible); - ccAddExternalObjectFunction("Object::get_X", Sc_Object_GetX); - ccAddExternalObjectFunction("Object::set_X", Sc_Object_SetX); - ccAddExternalObjectFunction("Object::get_Y", Sc_Object_GetY); - ccAddExternalObjectFunction("Object::set_Y", Sc_Object_SetY); - - ccAddExternalObjectFunction("Object::get_HasExplicitLight", Sc_Object_HasExplicitLight); - ccAddExternalObjectFunction("Object::get_HasExplicitTint", Sc_Object_HasExplicitTint); - ccAddExternalObjectFunction("Object::get_LightLevel", Sc_Object_GetLightLevel); - ccAddExternalObjectFunction("Object::set_LightLevel", Sc_Object_SetLightLevel); - ccAddExternalObjectFunction("Object::get_TintBlue", Sc_Object_GetTintBlue); - ccAddExternalObjectFunction("Object::get_TintGreen", Sc_Object_GetTintGreen); - ccAddExternalObjectFunction("Object::get_TintRed", Sc_Object_GetTintRed); - ccAddExternalObjectFunction("Object::get_TintSaturation", Sc_Object_GetTintSaturation); - ccAddExternalObjectFunction("Object::get_TintLuminance", Sc_Object_GetTintLuminance); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Object::Animate^5", (void*)Object_Animate); - ccAddExternalFunctionForPlugin("Object::IsCollidingWithObject^1", (void*)Object_IsCollidingWithObject); - ccAddExternalFunctionForPlugin("Object::GetName^1", (void*)Object_GetName); - ccAddExternalFunctionForPlugin("Object::GetProperty^1", (void*)Object_GetProperty); - ccAddExternalFunctionForPlugin("Object::GetPropertyText^2", (void*)Object_GetPropertyText); - ccAddExternalFunctionForPlugin("Object::GetTextProperty^1", (void*)Object_GetTextProperty); - ccAddExternalFunctionForPlugin("Object::MergeIntoBackground^0", (void*)Object_MergeIntoBackground); - ccAddExternalFunctionForPlugin("Object::Move^5", (void*)Object_Move); - ccAddExternalFunctionForPlugin("Object::RemoveTint^0", (void*)Object_RemoveTint); - ccAddExternalFunctionForPlugin("Object::RunInteraction^1", (void*)Object_RunInteraction); - ccAddExternalFunctionForPlugin("Object::SetPosition^2", (void*)Object_SetPosition); - ccAddExternalFunctionForPlugin("Object::SetView^3", (void*)Object_SetView); - ccAddExternalFunctionForPlugin("Object::StopAnimating^0", (void*)Object_StopAnimating); - ccAddExternalFunctionForPlugin("Object::StopMoving^0", (void*)Object_StopMoving); - ccAddExternalFunctionForPlugin("Object::Tint^5", (void*)Object_Tint); - ccAddExternalFunctionForPlugin("Object::GetAtRoomXY^2", (void*)GetObjectAtRoom); - ccAddExternalFunctionForPlugin("Object::GetAtScreenXY^2", (void*)GetObjectAtScreen); - ccAddExternalFunctionForPlugin("Object::get_Animating", (void*)Object_GetAnimating); - ccAddExternalFunctionForPlugin("Object::get_Baseline", (void*)Object_GetBaseline); - ccAddExternalFunctionForPlugin("Object::set_Baseline", (void*)Object_SetBaseline); - ccAddExternalFunctionForPlugin("Object::get_BlockingHeight", (void*)Object_GetBlockingHeight); - ccAddExternalFunctionForPlugin("Object::set_BlockingHeight", (void*)Object_SetBlockingHeight); - ccAddExternalFunctionForPlugin("Object::get_BlockingWidth", (void*)Object_GetBlockingWidth); - ccAddExternalFunctionForPlugin("Object::set_BlockingWidth", (void*)Object_SetBlockingWidth); - ccAddExternalFunctionForPlugin("Object::get_Clickable", (void*)Object_GetClickable); - ccAddExternalFunctionForPlugin("Object::set_Clickable", (void*)Object_SetClickable); - ccAddExternalFunctionForPlugin("Object::get_Frame", (void*)Object_GetFrame); - ccAddExternalFunctionForPlugin("Object::get_Graphic", (void*)Object_GetGraphic); - ccAddExternalFunctionForPlugin("Object::set_Graphic", (void*)Object_SetGraphic); - ccAddExternalFunctionForPlugin("Object::get_ID", (void*)Object_GetID); - ccAddExternalFunctionForPlugin("Object::get_IgnoreScaling", (void*)Object_GetIgnoreScaling); - ccAddExternalFunctionForPlugin("Object::set_IgnoreScaling", (void*)Object_SetIgnoreScaling); - ccAddExternalFunctionForPlugin("Object::get_IgnoreWalkbehinds", (void*)Object_GetIgnoreWalkbehinds); - ccAddExternalFunctionForPlugin("Object::set_IgnoreWalkbehinds", (void*)Object_SetIgnoreWalkbehinds); - ccAddExternalFunctionForPlugin("Object::get_Loop", (void*)Object_GetLoop); - ccAddExternalFunctionForPlugin("Object::get_Moving", (void*)Object_GetMoving); - ccAddExternalFunctionForPlugin("Object::get_Name", (void*)Object_GetName_New); - ccAddExternalFunctionForPlugin("Object::get_Solid", (void*)Object_GetSolid); - ccAddExternalFunctionForPlugin("Object::set_Solid", (void*)Object_SetSolid); - ccAddExternalFunctionForPlugin("Object::get_Transparency", (void*)Object_GetTransparency); - ccAddExternalFunctionForPlugin("Object::set_Transparency", (void*)Object_SetTransparency); - ccAddExternalFunctionForPlugin("Object::get_View", (void*)Object_GetView); - ccAddExternalFunctionForPlugin("Object::get_Visible", (void*)Object_GetVisible); - ccAddExternalFunctionForPlugin("Object::set_Visible", (void*)Object_SetVisible); - ccAddExternalFunctionForPlugin("Object::get_X", (void*)Object_GetX); - ccAddExternalFunctionForPlugin("Object::set_X", (void*)Object_SetX); - ccAddExternalFunctionForPlugin("Object::get_Y", (void*)Object_GetY); - ccAddExternalFunctionForPlugin("Object::set_Y", (void*)Object_SetY); +RuntimeScriptValue Sc_Object_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptObject, Object_SetY); +} + + + +void RegisterObjectAPI() { + ccAddExternalObjectFunction("Object::Animate^5", Sc_Object_Animate); + ccAddExternalObjectFunction("Object::Animate^6", Sc_Object_AnimateFrom); + ccAddExternalObjectFunction("Object::IsCollidingWithObject^1", Sc_Object_IsCollidingWithObject); + ccAddExternalObjectFunction("Object::GetName^1", Sc_Object_GetName); + ccAddExternalObjectFunction("Object::GetProperty^1", Sc_Object_GetProperty); + ccAddExternalObjectFunction("Object::GetPropertyText^2", Sc_Object_GetPropertyText); + ccAddExternalObjectFunction("Object::GetTextProperty^1", Sc_Object_GetTextProperty); + ccAddExternalObjectFunction("Object::SetProperty^2", Sc_Object_SetProperty); + ccAddExternalObjectFunction("Object::SetTextProperty^2", Sc_Object_SetTextProperty); + ccAddExternalObjectFunction("Object::IsInteractionAvailable^1", Sc_Object_IsInteractionAvailable); + ccAddExternalObjectFunction("Object::MergeIntoBackground^0", Sc_Object_MergeIntoBackground); + ccAddExternalObjectFunction("Object::Move^5", Sc_Object_Move); + ccAddExternalObjectFunction("Object::RemoveTint^0", Sc_Object_RemoveTint); + ccAddExternalObjectFunction("Object::RunInteraction^1", Sc_Object_RunInteraction); + ccAddExternalObjectFunction("Object::SetLightLevel^1", Sc_Object_SetLightLevel); + ccAddExternalObjectFunction("Object::SetPosition^2", Sc_Object_SetPosition); + ccAddExternalObjectFunction("Object::SetView^3", Sc_Object_SetView); + ccAddExternalObjectFunction("Object::StopAnimating^0", Sc_Object_StopAnimating); + ccAddExternalObjectFunction("Object::StopMoving^0", Sc_Object_StopMoving); + ccAddExternalObjectFunction("Object::Tint^5", Sc_Object_Tint); + + // static + ccAddExternalStaticFunction("Object::GetAtRoomXY^2", Sc_GetObjectAtRoom); + ccAddExternalStaticFunction("Object::GetAtScreenXY^2", Sc_GetObjectAtScreen); + + ccAddExternalObjectFunction("Object::get_Animating", Sc_Object_GetAnimating); + ccAddExternalObjectFunction("Object::get_Baseline", Sc_Object_GetBaseline); + ccAddExternalObjectFunction("Object::set_Baseline", Sc_Object_SetBaseline); + ccAddExternalObjectFunction("Object::get_BlockingHeight", Sc_Object_GetBlockingHeight); + ccAddExternalObjectFunction("Object::set_BlockingHeight", Sc_Object_SetBlockingHeight); + ccAddExternalObjectFunction("Object::get_BlockingWidth", Sc_Object_GetBlockingWidth); + ccAddExternalObjectFunction("Object::set_BlockingWidth", Sc_Object_SetBlockingWidth); + ccAddExternalObjectFunction("Object::get_Clickable", Sc_Object_GetClickable); + ccAddExternalObjectFunction("Object::set_Clickable", Sc_Object_SetClickable); + ccAddExternalObjectFunction("Object::get_Frame", Sc_Object_GetFrame); + ccAddExternalObjectFunction("Object::get_Graphic", Sc_Object_GetGraphic); + ccAddExternalObjectFunction("Object::set_Graphic", Sc_Object_SetGraphic); + ccAddExternalObjectFunction("Object::get_ID", Sc_Object_GetID); + ccAddExternalObjectFunction("Object::get_IgnoreScaling", Sc_Object_GetIgnoreScaling); + ccAddExternalObjectFunction("Object::set_IgnoreScaling", Sc_Object_SetIgnoreScaling); + ccAddExternalObjectFunction("Object::get_IgnoreWalkbehinds", Sc_Object_GetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Object::set_IgnoreWalkbehinds", Sc_Object_SetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Object::get_Loop", Sc_Object_GetLoop); + ccAddExternalObjectFunction("Object::get_ManualScaling", Sc_Object_GetIgnoreScaling); + ccAddExternalObjectFunction("Object::set_ManualScaling", Sc_Object_SetManualScaling); + ccAddExternalObjectFunction("Object::get_Moving", Sc_Object_GetMoving); + ccAddExternalObjectFunction("Object::get_Name", Sc_Object_GetName_New); + ccAddExternalObjectFunction("Object::get_Scaling", Sc_Object_GetScaling); + ccAddExternalObjectFunction("Object::set_Scaling", Sc_Object_SetScaling); + ccAddExternalObjectFunction("Object::get_Solid", Sc_Object_GetSolid); + ccAddExternalObjectFunction("Object::set_Solid", Sc_Object_SetSolid); + ccAddExternalObjectFunction("Object::get_Transparency", Sc_Object_GetTransparency); + ccAddExternalObjectFunction("Object::set_Transparency", Sc_Object_SetTransparency); + ccAddExternalObjectFunction("Object::get_View", Sc_Object_GetView); + ccAddExternalObjectFunction("Object::get_Visible", Sc_Object_GetVisible); + ccAddExternalObjectFunction("Object::set_Visible", Sc_Object_SetVisible); + ccAddExternalObjectFunction("Object::get_X", Sc_Object_GetX); + ccAddExternalObjectFunction("Object::set_X", Sc_Object_SetX); + ccAddExternalObjectFunction("Object::get_Y", Sc_Object_GetY); + ccAddExternalObjectFunction("Object::set_Y", Sc_Object_SetY); + + ccAddExternalObjectFunction("Object::get_HasExplicitLight", Sc_Object_HasExplicitLight); + ccAddExternalObjectFunction("Object::get_HasExplicitTint", Sc_Object_HasExplicitTint); + ccAddExternalObjectFunction("Object::get_LightLevel", Sc_Object_GetLightLevel); + ccAddExternalObjectFunction("Object::set_LightLevel", Sc_Object_SetLightLevel); + ccAddExternalObjectFunction("Object::get_TintBlue", Sc_Object_GetTintBlue); + ccAddExternalObjectFunction("Object::get_TintGreen", Sc_Object_GetTintGreen); + ccAddExternalObjectFunction("Object::get_TintRed", Sc_Object_GetTintRed); + ccAddExternalObjectFunction("Object::get_TintSaturation", Sc_Object_GetTintSaturation); + ccAddExternalObjectFunction("Object::get_TintLuminance", Sc_Object_GetTintLuminance); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Object::Animate^5", (void *)Object_Animate); + ccAddExternalFunctionForPlugin("Object::IsCollidingWithObject^1", (void *)Object_IsCollidingWithObject); + ccAddExternalFunctionForPlugin("Object::GetName^1", (void *)Object_GetName); + ccAddExternalFunctionForPlugin("Object::GetProperty^1", (void *)Object_GetProperty); + ccAddExternalFunctionForPlugin("Object::GetPropertyText^2", (void *)Object_GetPropertyText); + ccAddExternalFunctionForPlugin("Object::GetTextProperty^1", (void *)Object_GetTextProperty); + ccAddExternalFunctionForPlugin("Object::MergeIntoBackground^0", (void *)Object_MergeIntoBackground); + ccAddExternalFunctionForPlugin("Object::Move^5", (void *)Object_Move); + ccAddExternalFunctionForPlugin("Object::RemoveTint^0", (void *)Object_RemoveTint); + ccAddExternalFunctionForPlugin("Object::RunInteraction^1", (void *)Object_RunInteraction); + ccAddExternalFunctionForPlugin("Object::SetPosition^2", (void *)Object_SetPosition); + ccAddExternalFunctionForPlugin("Object::SetView^3", (void *)Object_SetView); + ccAddExternalFunctionForPlugin("Object::StopAnimating^0", (void *)Object_StopAnimating); + ccAddExternalFunctionForPlugin("Object::StopMoving^0", (void *)Object_StopMoving); + ccAddExternalFunctionForPlugin("Object::Tint^5", (void *)Object_Tint); + ccAddExternalFunctionForPlugin("Object::GetAtRoomXY^2", (void *)GetObjectAtRoom); + ccAddExternalFunctionForPlugin("Object::GetAtScreenXY^2", (void *)GetObjectAtScreen); + ccAddExternalFunctionForPlugin("Object::get_Animating", (void *)Object_GetAnimating); + ccAddExternalFunctionForPlugin("Object::get_Baseline", (void *)Object_GetBaseline); + ccAddExternalFunctionForPlugin("Object::set_Baseline", (void *)Object_SetBaseline); + ccAddExternalFunctionForPlugin("Object::get_BlockingHeight", (void *)Object_GetBlockingHeight); + ccAddExternalFunctionForPlugin("Object::set_BlockingHeight", (void *)Object_SetBlockingHeight); + ccAddExternalFunctionForPlugin("Object::get_BlockingWidth", (void *)Object_GetBlockingWidth); + ccAddExternalFunctionForPlugin("Object::set_BlockingWidth", (void *)Object_SetBlockingWidth); + ccAddExternalFunctionForPlugin("Object::get_Clickable", (void *)Object_GetClickable); + ccAddExternalFunctionForPlugin("Object::set_Clickable", (void *)Object_SetClickable); + ccAddExternalFunctionForPlugin("Object::get_Frame", (void *)Object_GetFrame); + ccAddExternalFunctionForPlugin("Object::get_Graphic", (void *)Object_GetGraphic); + ccAddExternalFunctionForPlugin("Object::set_Graphic", (void *)Object_SetGraphic); + ccAddExternalFunctionForPlugin("Object::get_ID", (void *)Object_GetID); + ccAddExternalFunctionForPlugin("Object::get_IgnoreScaling", (void *)Object_GetIgnoreScaling); + ccAddExternalFunctionForPlugin("Object::set_IgnoreScaling", (void *)Object_SetIgnoreScaling); + ccAddExternalFunctionForPlugin("Object::get_IgnoreWalkbehinds", (void *)Object_GetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Object::set_IgnoreWalkbehinds", (void *)Object_SetIgnoreWalkbehinds); + ccAddExternalFunctionForPlugin("Object::get_Loop", (void *)Object_GetLoop); + ccAddExternalFunctionForPlugin("Object::get_Moving", (void *)Object_GetMoving); + ccAddExternalFunctionForPlugin("Object::get_Name", (void *)Object_GetName_New); + ccAddExternalFunctionForPlugin("Object::get_Solid", (void *)Object_GetSolid); + ccAddExternalFunctionForPlugin("Object::set_Solid", (void *)Object_SetSolid); + ccAddExternalFunctionForPlugin("Object::get_Transparency", (void *)Object_GetTransparency); + ccAddExternalFunctionForPlugin("Object::set_Transparency", (void *)Object_SetTransparency); + ccAddExternalFunctionForPlugin("Object::get_View", (void *)Object_GetView); + ccAddExternalFunctionForPlugin("Object::get_Visible", (void *)Object_GetVisible); + ccAddExternalFunctionForPlugin("Object::set_Visible", (void *)Object_SetVisible); + ccAddExternalFunctionForPlugin("Object::get_X", (void *)Object_GetX); + ccAddExternalFunctionForPlugin("Object::set_X", (void *)Object_SetX); + ccAddExternalFunctionForPlugin("Object::get_Y", (void *)Object_GetY); + ccAddExternalFunctionForPlugin("Object::set_Y", (void *)Object_SetY); } diff --git a/engines/ags/engine/ac/object.h b/engines/ags/engine/ac/object.h index 0d7262a78ad9..11f5d31b57bd 100644 --- a/engines/ags/engine/ac/object.h +++ b/engines/ags/engine/ac/object.h @@ -34,7 +34,11 @@ #include "ac/common_defines.h" #include "ac/dynobj/scriptobject.h" -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later extern AGS_INLINE int is_valid_object(int obtest); @@ -66,7 +70,7 @@ void Object_SetPosition(ScriptObject *objj, int xx, int yy); void Object_SetX(ScriptObject *objj, int xx); void Object_SetY(ScriptObject *objj, int yy); void Object_GetName(ScriptObject *objj, char *buffer); -const char* Object_GetName_New(ScriptObject *objj); +const char *Object_GetName_New(ScriptObject *objj); bool Object_IsInteractionAvailable(ScriptObject *oobj, int mood); void Object_Move(ScriptObject *objj, int x, int y, int speed, int blocking, int direct); void Object_SetClickable(ScriptObject *objj, int clik); @@ -84,14 +88,14 @@ void Object_SetIgnoreWalkbehinds(ScriptObject *chaa, int clik); int Object_GetIgnoreWalkbehinds(ScriptObject *chaa); void Object_RunInteraction(ScriptObject *objj, int mode); -int Object_GetProperty (ScriptObject *objj, const char *property); +int Object_GetProperty(ScriptObject *objj, const char *property); void Object_GetPropertyText(ScriptObject *objj, const char *property, char *bufer); -const char* Object_GetTextProperty(ScriptObject *objj, const char *property); +const char *Object_GetTextProperty(ScriptObject *objj, const char *property); -void move_object(int objj,int tox,int toy,int spee,int ignwal); +void move_object(int objj, int tox, int toy, int spee, int ignwal); void get_object_blocking_rect(int objid, int *x1, int *y1, int *width, int *y2); -int isposinbox(int mmx,int mmy,int lf,int tp,int rt,int bt); -int is_pos_in_sprite(int xx,int yy,int arx,int ary, Common::Bitmap *sprit, int spww,int sphh, int flipped = 0); +int isposinbox(int mmx, int mmy, int lf, int tp, int rt, int bt); +int is_pos_in_sprite(int xx, int yy, int arx, int ary, Common::Bitmap *sprit, int spww, int sphh, int flipped = 0); // X and Y co-ordinates must be in native format // X and Y are ROOM coordinates int check_click_on_object(int roomx, int roomy, int mood); diff --git a/engines/ags/engine/ac/objectcache.h b/engines/ags/engine/ac/objectcache.h index 916b47c46216..ba7a323ebea5 100644 --- a/engines/ags/engine/ac/objectcache.h +++ b/engines/ags/engine/ac/objectcache.h @@ -25,12 +25,12 @@ // stores cached object info struct ObjectCache { - Common::Bitmap *image; - int sppic; - short tintredwas, tintgrnwas, tintbluwas, tintamntwas, tintlightwas; - short lightlevwas, mirroredWas, zoomWas; - // The following are used to determine if the character has moved - int xwas, ywas; + Common::Bitmap *image; + int sppic; + short tintredwas, tintgrnwas, tintbluwas, tintamntwas, tintlightwas; + short lightlevwas, mirroredWas, zoomWas; + // The following are used to determine if the character has moved + int xwas, ywas; }; #endif diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp index f74603f0acae..3d1b5bcc26e6 100644 --- a/engines/ags/engine/ac/overlay.cpp +++ b/engines/ags/engine/ac/overlay.cpp @@ -44,248 +44,239 @@ using namespace AGS::Engine; extern GameSetupStruct game; extern int displayed_room; extern int face_talking; -extern ViewStruct*views; +extern ViewStruct *views; extern CharacterExtras *charextra; extern IGraphicsDriver *gfxDriver; std::vector screenover; -int is_complete_overlay=0,is_text_overlay=0; +int is_complete_overlay = 0, is_text_overlay = 0; void Overlay_Remove(ScriptOverlay *sco) { - sco->Remove(); + sco->Remove(); } void Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int text_color, const char *text) { - int ovri=find_overlay_of_type(scover->overlayId); - if (ovri<0) - quit("!Overlay.SetText: invalid overlay ID specified"); - int xx = game_to_data_coord(screenover[ovri].x) - scover->borderWidth; - int yy = game_to_data_coord(screenover[ovri].y) - scover->borderHeight; + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!Overlay.SetText: invalid overlay ID specified"); + int xx = game_to_data_coord(screenover[ovri].x) - scover->borderWidth; + int yy = game_to_data_coord(screenover[ovri].y) - scover->borderHeight; - RemoveOverlay(scover->overlayId); - const int disp_type = scover->overlayId; + RemoveOverlay(scover->overlayId); + const int disp_type = scover->overlayId; - if (CreateTextOverlay(xx, yy, wii, fontid, text_color, get_translation(text), disp_type) != scover->overlayId) - quit("SetTextOverlay internal error: inconsistent type ids"); + if (CreateTextOverlay(xx, yy, wii, fontid, text_color, get_translation(text), disp_type) != scover->overlayId) + quit("SetTextOverlay internal error: inconsistent type ids"); } int Overlay_GetX(ScriptOverlay *scover) { - int ovri = find_overlay_of_type(scover->overlayId); - if (ovri < 0) - quit("!invalid overlay ID specified"); + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); - int tdxp, tdyp; - get_overlay_position(screenover[ovri], &tdxp, &tdyp); + int tdxp, tdyp; + get_overlay_position(screenover[ovri], &tdxp, &tdyp); - return game_to_data_coord(tdxp); + return game_to_data_coord(tdxp); } void Overlay_SetX(ScriptOverlay *scover, int newx) { - int ovri = find_overlay_of_type(scover->overlayId); - if (ovri < 0) - quit("!invalid overlay ID specified"); + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); - screenover[ovri].x = data_to_game_coord(newx); + screenover[ovri].x = data_to_game_coord(newx); } int Overlay_GetY(ScriptOverlay *scover) { - int ovri = find_overlay_of_type(scover->overlayId); - if (ovri < 0) - quit("!invalid overlay ID specified"); + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); - int tdxp, tdyp; - get_overlay_position(screenover[ovri], &tdxp, &tdyp); + int tdxp, tdyp; + get_overlay_position(screenover[ovri], &tdxp, &tdyp); - return game_to_data_coord(tdyp); + return game_to_data_coord(tdyp); } void Overlay_SetY(ScriptOverlay *scover, int newy) { - int ovri = find_overlay_of_type(scover->overlayId); - if (ovri < 0) - quit("!invalid overlay ID specified"); + int ovri = find_overlay_of_type(scover->overlayId); + if (ovri < 0) + quit("!invalid overlay ID specified"); - screenover[ovri].y = data_to_game_coord(newy); + screenover[ovri].y = data_to_game_coord(newy); } int Overlay_GetValid(ScriptOverlay *scover) { - if (scover->overlayId == -1) - return 0; + if (scover->overlayId == -1) + return 0; - if (!IsOverlayValid(scover->overlayId)) { - scover->overlayId = -1; - return 0; - } + if (!IsOverlayValid(scover->overlayId)) { + scover->overlayId = -1; + return 0; + } - return 1; + return 1; } -ScriptOverlay* Overlay_CreateGraphical(int x, int y, int slot, int transparent) { - ScriptOverlay *sco = new ScriptOverlay(); - sco->overlayId = CreateGraphicOverlay(x, y, slot, transparent); - sco->borderHeight = 0; - sco->borderWidth = 0; - sco->isBackgroundSpeech = 0; +ScriptOverlay *Overlay_CreateGraphical(int x, int y, int slot, int transparent) { + ScriptOverlay *sco = new ScriptOverlay(); + sco->overlayId = CreateGraphicOverlay(x, y, slot, transparent); + sco->borderHeight = 0; + sco->borderWidth = 0; + sco->isBackgroundSpeech = 0; - ccRegisterManagedObject(sco, sco); - return sco; + ccRegisterManagedObject(sco, sco); + return sco; } -ScriptOverlay* Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char* text) { - ScriptOverlay *sco = new ScriptOverlay(); +ScriptOverlay *Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char *text) { + ScriptOverlay *sco = new ScriptOverlay(); - data_to_game_coords(&x, &y); - width = data_to_game_coord(width); + data_to_game_coords(&x, &y); + width = data_to_game_coord(width); - sco->overlayId = CreateTextOverlayCore(x, y, width, font, colour, text, DISPLAYTEXT_NORMALOVERLAY, 0); + sco->overlayId = CreateTextOverlayCore(x, y, width, font, colour, text, DISPLAYTEXT_NORMALOVERLAY, 0); - int ovri = find_overlay_of_type(sco->overlayId); - sco->borderWidth = game_to_data_coord(screenover[ovri].x - x); - sco->borderHeight = game_to_data_coord(screenover[ovri].y - y); - sco->isBackgroundSpeech = 0; + int ovri = find_overlay_of_type(sco->overlayId); + sco->borderWidth = game_to_data_coord(screenover[ovri].x - x); + sco->borderHeight = game_to_data_coord(screenover[ovri].y - y); + sco->isBackgroundSpeech = 0; - ccRegisterManagedObject(sco, sco); - return sco; + ccRegisterManagedObject(sco, sco); + return sco; } //============================================================================= -void dispose_overlay(ScreenOverlay &over) -{ - delete over.pic; - over.pic = nullptr; - if (over.bmp != nullptr) - gfxDriver->DestroyDDB(over.bmp); - over.bmp = nullptr; - // if the script didn't actually use the Overlay* return - // value, dispose of the pointer - if (over.associatedOverlayHandle) - ccAttemptDisposeObject(over.associatedOverlayHandle); +void dispose_overlay(ScreenOverlay &over) { + delete over.pic; + over.pic = nullptr; + if (over.bmp != nullptr) + gfxDriver->DestroyDDB(over.bmp); + over.bmp = nullptr; + // if the script didn't actually use the Overlay* return + // value, dispose of the pointer + if (over.associatedOverlayHandle) + ccAttemptDisposeObject(over.associatedOverlayHandle); } -void remove_screen_overlay_index(size_t over_idx) -{ - ScreenOverlay &over = screenover[over_idx]; - dispose_overlay(over); - if (over.type==OVER_COMPLETE) is_complete_overlay--; - if (over.type==OVER_TEXTMSG) is_text_overlay--; - screenover.erase(screenover.begin() + over_idx); - // if an overlay before the sierra-style speech one is removed, - // update the index - if (face_talking >= 0 && (size_t)face_talking > over_idx) - face_talking--; +void remove_screen_overlay_index(size_t over_idx) { + ScreenOverlay &over = screenover[over_idx]; + dispose_overlay(over); + if (over.type == OVER_COMPLETE) is_complete_overlay--; + if (over.type == OVER_TEXTMSG) is_text_overlay--; + screenover.erase(screenover.begin() + over_idx); + // if an overlay before the sierra-style speech one is removed, + // update the index + if (face_talking >= 0 && (size_t)face_talking > over_idx) + face_talking--; } -void remove_screen_overlay(int type) -{ - for (size_t i = 0; i < screenover.size();) - { - if (type < 0 || screenover[i].type == type) - remove_screen_overlay_index(i); - else - i++; - } +void remove_screen_overlay(int type) { + for (size_t i = 0; i < screenover.size();) { + if (type < 0 || screenover[i].type == type) + remove_screen_overlay_index(i); + else + i++; + } } -int find_overlay_of_type(int type) -{ - for (size_t i = 0; i < screenover.size(); ++i) - { - if (screenover[i].type == type) return i; - } - return -1; +int find_overlay_of_type(int type) { + for (size_t i = 0; i < screenover.size(); ++i) { + if (screenover[i].type == type) return i; + } + return -1; } -size_t add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChannel) -{ - return add_screen_overlay(x, y, type, piccy, 0, 0, alphaChannel); +size_t add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChannel) { + return add_screen_overlay(x, y, type, piccy, 0, 0, alphaChannel); } -size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) -{ - if (type==OVER_COMPLETE) is_complete_overlay++; - if (type==OVER_TEXTMSG) is_text_overlay++; - if (type==OVER_CUSTOM) { - // find an unused custom ID; TODO: find a better approach! - for (int id = OVER_CUSTOM + 1; id < screenover.size() + OVER_CUSTOM + 1; ++id) { - if (find_overlay_of_type(id) == -1) { type=id; break; } - } - } - ScreenOverlay over; - over.pic=piccy; - over.bmp = gfxDriver->CreateDDBFromBitmap(piccy, alphaChannel); - over.x=x; - over.y=y; - over._offsetX = pic_offx; - over._offsetY = pic_offy; - over.type=type; - over.timeout=0; - over.bgSpeechForChar = -1; - over.associatedOverlayHandle = 0; - over.hasAlphaChannel = alphaChannel; - over.positionRelativeToScreen = true; - screenover.push_back(over); - return screenover.size() - 1; +size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) { + if (type == OVER_COMPLETE) is_complete_overlay++; + if (type == OVER_TEXTMSG) is_text_overlay++; + if (type == OVER_CUSTOM) { + // find an unused custom ID; TODO: find a better approach! + for (int id = OVER_CUSTOM + 1; id < screenover.size() + OVER_CUSTOM + 1; ++id) { + if (find_overlay_of_type(id) == -1) { + type = id; + break; + } + } + } + ScreenOverlay over; + over.pic = piccy; + over.bmp = gfxDriver->CreateDDBFromBitmap(piccy, alphaChannel); + over.x = x; + over.y = y; + over._offsetX = pic_offx; + over._offsetY = pic_offy; + over.type = type; + over.timeout = 0; + over.bgSpeechForChar = -1; + over.associatedOverlayHandle = 0; + over.hasAlphaChannel = alphaChannel; + over.positionRelativeToScreen = true; + screenover.push_back(over); + return screenover.size() - 1; } void get_overlay_position(const ScreenOverlay &over, int *x, int *y) { - int tdxp, tdyp; - const Rect &ui_view = play.GetUIViewport(); - - if (over.x == OVR_AUTOPLACE) { - // auto place on character - int charid = over.y; - - auto view = FindNearestViewport(charid); - const int charpic = views[game.chars[charid].view].loops[game.chars[charid].loop].frames[0].pic; - const int height = (charextra[charid].height < 1) ? game.SpriteInfos[charpic].Height : charextra[charid].height; - Point screenpt = view->RoomToScreen( - data_to_game_coord(game.chars[charid].x), - data_to_game_coord(game.chars[charid].get_effective_y()) - height).first; - tdxp = screenpt.X - over.pic->GetWidth() / 2; - if (tdxp < 0) tdxp = 0; - tdyp = screenpt.Y - get_fixed_pixel_size(5); - tdyp -= over.pic->GetHeight(); - if (tdyp < 5) tdyp = 5; - - if ((tdxp + over.pic->GetWidth()) >= ui_view.GetWidth()) - tdxp = (ui_view.GetWidth() - over.pic->GetWidth()) - 1; - if (game.chars[charid].room != displayed_room) { - tdxp = ui_view.GetWidth()/2 - over.pic->GetWidth()/2; - tdyp = ui_view.GetHeight()/2 - over.pic->GetHeight()/2; - } - } - else { - // Note: the internal offset is only needed when x,y coordinates are specified - // and only in the case where the overlay is using a GUI. See issue #1098 - tdxp = over.x + over._offsetX; - tdyp = over.y + over._offsetY; - - if (!over.positionRelativeToScreen) - { - Point tdxy = play.RoomToScreen(tdxp, tdyp); - tdxp = tdxy.X; - tdyp = tdxy.Y; - } - } - *x = tdxp; - *y = tdyp; + int tdxp, tdyp; + const Rect &ui_view = play.GetUIViewport(); + + if (over.x == OVR_AUTOPLACE) { + // auto place on character + int charid = over.y; + + auto view = FindNearestViewport(charid); + const int charpic = views[game.chars[charid].view].loops[game.chars[charid].loop].frames[0].pic; + const int height = (charextra[charid].height < 1) ? game.SpriteInfos[charpic].Height : charextra[charid].height; + Point screenpt = view->RoomToScreen( + data_to_game_coord(game.chars[charid].x), + data_to_game_coord(game.chars[charid].get_effective_y()) - height).first; + tdxp = screenpt.X - over.pic->GetWidth() / 2; + if (tdxp < 0) tdxp = 0; + tdyp = screenpt.Y - get_fixed_pixel_size(5); + tdyp -= over.pic->GetHeight(); + if (tdyp < 5) tdyp = 5; + + if ((tdxp + over.pic->GetWidth()) >= ui_view.GetWidth()) + tdxp = (ui_view.GetWidth() - over.pic->GetWidth()) - 1; + if (game.chars[charid].room != displayed_room) { + tdxp = ui_view.GetWidth() / 2 - over.pic->GetWidth() / 2; + tdyp = ui_view.GetHeight() / 2 - over.pic->GetHeight() / 2; + } + } else { + // Note: the internal offset is only needed when x,y coordinates are specified + // and only in the case where the overlay is using a GUI. See issue #1098 + tdxp = over.x + over._offsetX; + tdyp = over.y + over._offsetY; + + if (!over.positionRelativeToScreen) { + Point tdxy = play.RoomToScreen(tdxp, tdyp); + tdxp = tdxy.X; + tdyp = tdxy.Y; + } + } + *x = tdxp; + *y = tdyp; } -void recreate_overlay_ddbs() -{ - for (auto &over : screenover) - { - if (over.bmp) - gfxDriver->DestroyDDB(over.bmp); - if (over.pic) - over.bmp = gfxDriver->CreateDDBFromBitmap(over.pic, false); - else - over.bmp = nullptr; - } +void recreate_overlay_ddbs() { + for (auto &over : screenover) { + if (over.bmp) + gfxDriver->DestroyDDB(over.bmp); + if (over.pic) + over.bmp = gfxDriver->CreateDDBFromBitmap(over.pic, false); + else + over.bmp = nullptr; + } } //============================================================================= @@ -299,62 +290,53 @@ void recreate_overlay_ddbs() #include "script/script_runtime.h" // ScriptOverlay* (int x, int y, int slot, int transparent) -RuntimeScriptValue Sc_Overlay_CreateGraphical(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT4(ScriptOverlay, Overlay_CreateGraphical); +RuntimeScriptValue Sc_Overlay_CreateGraphical(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT4(ScriptOverlay, Overlay_CreateGraphical); } // ScriptOverlay* (int x, int y, int width, int font, int colour, const char* text, ...) -RuntimeScriptValue Sc_Overlay_CreateTextual(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(Overlay_CreateTextual, 6); - ScriptOverlay *overlay = Overlay_CreateTextual(params[0].IValue, params[1].IValue, params[2].IValue, - params[3].IValue, params[4].IValue, scsf_buffer); - return RuntimeScriptValue().SetDynamicObject(overlay, overlay); +RuntimeScriptValue Sc_Overlay_CreateTextual(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(Overlay_CreateTextual, 6); + ScriptOverlay *overlay = Overlay_CreateTextual(params[0].IValue, params[1].IValue, params[2].IValue, + params[3].IValue, params[4].IValue, scsf_buffer); + return RuntimeScriptValue().SetDynamicObject(overlay, overlay); } // void (ScriptOverlay *scover, int wii, int fontid, int clr, char*texx, ...) -RuntimeScriptValue Sc_Overlay_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_SCRIPT_SPRINTF(Overlay_SetText, 4); - Overlay_SetText((ScriptOverlay*)self, params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_Overlay_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_SCRIPT_SPRINTF(Overlay_SetText, 4); + Overlay_SetText((ScriptOverlay *)self, params[0].IValue, params[1].IValue, params[2].IValue, scsf_buffer); + return RuntimeScriptValue((int32_t)0); } // void (ScriptOverlay *sco) -RuntimeScriptValue Sc_Overlay_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptOverlay, Overlay_Remove); +RuntimeScriptValue Sc_Overlay_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptOverlay, Overlay_Remove); } // int (ScriptOverlay *scover) -RuntimeScriptValue Sc_Overlay_GetValid(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptOverlay, Overlay_GetValid); +RuntimeScriptValue Sc_Overlay_GetValid(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptOverlay, Overlay_GetValid); } // int (ScriptOverlay *scover) -RuntimeScriptValue Sc_Overlay_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptOverlay, Overlay_GetX); +RuntimeScriptValue Sc_Overlay_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptOverlay, Overlay_GetX); } // void (ScriptOverlay *scover, int newx) -RuntimeScriptValue Sc_Overlay_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetX); +RuntimeScriptValue Sc_Overlay_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetX); } // int (ScriptOverlay *scover) -RuntimeScriptValue Sc_Overlay_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptOverlay, Overlay_GetY); +RuntimeScriptValue Sc_Overlay_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptOverlay, Overlay_GetY); } // void (ScriptOverlay *scover, int newy) -RuntimeScriptValue Sc_Overlay_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetY); +RuntimeScriptValue Sc_Overlay_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetY); } //============================================================================= @@ -364,41 +346,38 @@ RuntimeScriptValue Sc_Overlay_SetY(void *self, const RuntimeScriptValue *params, //============================================================================= // ScriptOverlay* (int x, int y, int width, int font, int colour, const char* text, ...) -ScriptOverlay* ScPl_Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char *text, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(text); - return Overlay_CreateTextual(x, y, width, font, colour, scsf_buffer); +ScriptOverlay *ScPl_Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char *text, ...) { + API_PLUGIN_SCRIPT_SPRINTF(text); + return Overlay_CreateTextual(x, y, width, font, colour, scsf_buffer); } // void (ScriptOverlay *scover, int wii, int fontid, int clr, char*texx, ...) -void ScPl_Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - Overlay_SetText(scover, wii, fontid, clr, scsf_buffer); +void ScPl_Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + Overlay_SetText(scover, wii, fontid, clr, scsf_buffer); } -void RegisterOverlayAPI() -{ - ccAddExternalStaticFunction("Overlay::CreateGraphical^4", Sc_Overlay_CreateGraphical); - ccAddExternalStaticFunction("Overlay::CreateTextual^106", Sc_Overlay_CreateTextual); - ccAddExternalObjectFunction("Overlay::SetText^104", Sc_Overlay_SetText); - ccAddExternalObjectFunction("Overlay::Remove^0", Sc_Overlay_Remove); - ccAddExternalObjectFunction("Overlay::get_Valid", Sc_Overlay_GetValid); - ccAddExternalObjectFunction("Overlay::get_X", Sc_Overlay_GetX); - ccAddExternalObjectFunction("Overlay::set_X", Sc_Overlay_SetX); - ccAddExternalObjectFunction("Overlay::get_Y", Sc_Overlay_GetY); - ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Overlay::CreateGraphical^4", (void*)Overlay_CreateGraphical); - ccAddExternalFunctionForPlugin("Overlay::CreateTextual^106", (void*)ScPl_Overlay_CreateTextual); - ccAddExternalFunctionForPlugin("Overlay::SetText^104", (void*)ScPl_Overlay_SetText); - ccAddExternalFunctionForPlugin("Overlay::Remove^0", (void*)Overlay_Remove); - ccAddExternalFunctionForPlugin("Overlay::get_Valid", (void*)Overlay_GetValid); - ccAddExternalFunctionForPlugin("Overlay::get_X", (void*)Overlay_GetX); - ccAddExternalFunctionForPlugin("Overlay::set_X", (void*)Overlay_SetX); - ccAddExternalFunctionForPlugin("Overlay::get_Y", (void*)Overlay_GetY); - ccAddExternalFunctionForPlugin("Overlay::set_Y", (void*)Overlay_SetY); +void RegisterOverlayAPI() { + ccAddExternalStaticFunction("Overlay::CreateGraphical^4", Sc_Overlay_CreateGraphical); + ccAddExternalStaticFunction("Overlay::CreateTextual^106", Sc_Overlay_CreateTextual); + ccAddExternalObjectFunction("Overlay::SetText^104", Sc_Overlay_SetText); + ccAddExternalObjectFunction("Overlay::Remove^0", Sc_Overlay_Remove); + ccAddExternalObjectFunction("Overlay::get_Valid", Sc_Overlay_GetValid); + ccAddExternalObjectFunction("Overlay::get_X", Sc_Overlay_GetX); + ccAddExternalObjectFunction("Overlay::set_X", Sc_Overlay_SetX); + ccAddExternalObjectFunction("Overlay::get_Y", Sc_Overlay_GetY); + ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Overlay::CreateGraphical^4", (void *)Overlay_CreateGraphical); + ccAddExternalFunctionForPlugin("Overlay::CreateTextual^106", (void *)ScPl_Overlay_CreateTextual); + ccAddExternalFunctionForPlugin("Overlay::SetText^104", (void *)ScPl_Overlay_SetText); + ccAddExternalFunctionForPlugin("Overlay::Remove^0", (void *)Overlay_Remove); + ccAddExternalFunctionForPlugin("Overlay::get_Valid", (void *)Overlay_GetValid); + ccAddExternalFunctionForPlugin("Overlay::get_X", (void *)Overlay_GetX); + ccAddExternalFunctionForPlugin("Overlay::set_X", (void *)Overlay_SetX); + ccAddExternalFunctionForPlugin("Overlay::get_Y", (void *)Overlay_GetY); + ccAddExternalFunctionForPlugin("Overlay::set_Y", (void *)Overlay_SetY); } diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h index 96f5b388757a..d5628fcc0e91 100644 --- a/engines/ags/engine/ac/overlay.h +++ b/engines/ags/engine/ac/overlay.h @@ -27,24 +27,28 @@ #include "ac/screenoverlay.h" #include "ac/dynobj/scriptoverlay.h" -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later void Overlay_Remove(ScriptOverlay *sco); -void Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, const char*text); +void Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, const char *text); int Overlay_GetX(ScriptOverlay *scover); void Overlay_SetX(ScriptOverlay *scover, int newx); int Overlay_GetY(ScriptOverlay *scover); void Overlay_SetY(ScriptOverlay *scover, int newy); int Overlay_GetValid(ScriptOverlay *scover); -ScriptOverlay* Overlay_CreateGraphical(int x, int y, int slot, int transparent); -ScriptOverlay* Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char* text); +ScriptOverlay *Overlay_CreateGraphical(int x, int y, int slot, int transparent); +ScriptOverlay *Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char *text); int find_overlay_of_type(int type); void remove_screen_overlay(int type); // Calculates overlay position in screen coordinates void get_overlay_position(const ScreenOverlay &over, int *x, int *y); -size_t add_screen_overlay(int x,int y,int type,Common::Bitmap *piccy, bool alphaChannel = false); +size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, bool alphaChannel = false); size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false); void remove_screen_overlay_index(size_t over_idx); void recreate_overlay_ddbs(); diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp index 1f62782c952c..4ec35d8794e3 100644 --- a/engines/ags/engine/ac/parser.cpp +++ b/engines/ags/engine/ac/parser.cpp @@ -37,265 +37,260 @@ using namespace AGS::Common; extern GameSetupStruct game; extern GameState play; -int Parser_FindWordID(const char *wordToFind) -{ - return find_word_in_dictionary(wordToFind); +int Parser_FindWordID(const char *wordToFind) { + return find_word_in_dictionary(wordToFind); } -const char* Parser_SaidUnknownWord() { - if (play.bad_parsed_word[0] == 0) - return nullptr; - return CreateNewScriptString(play.bad_parsed_word); +const char *Parser_SaidUnknownWord() { + if (play.bad_parsed_word[0] == 0) + return nullptr; + return CreateNewScriptString(play.bad_parsed_word); } -void ParseText (const char*text) { - parse_sentence (text, &play.num_parsed_words, play.parsed_words, nullptr, 0); +void ParseText(const char *text) { + parse_sentence(text, &play.num_parsed_words, play.parsed_words, nullptr, 0); } // Said: call with argument for example "get apple"; we then check // word by word if it matches (using dictonary ID equivalence to match // synonyms). Returns 1 if it does, 0 if not. -int Said (const char *checkwords) { - int numword = 0; - short words[MAX_PARSED_WORDS]; - return parse_sentence (checkwords, &numword, &words[0], play.parsed_words, play.num_parsed_words); +int Said(const char *checkwords) { + int numword = 0; + short words[MAX_PARSED_WORDS]; + return parse_sentence(checkwords, &numword, &words[0], play.parsed_words, play.num_parsed_words); } //============================================================================= -int find_word_in_dictionary (const char *lookfor) { - int j; - if (game.dict == nullptr) - return -1; - - for (j = 0; j < game.dict->num_words; j++) { - if (ags_stricmp(lookfor, game.dict->word[j]) == 0) { - return game.dict->wordnum[j]; - } - } - if (lookfor[0] != 0) { - // If the word wasn't found, but it ends in 'S', see if there's - // a non-plural version - const char *ptat = &lookfor[strlen(lookfor)-1]; - char lastletter = *ptat; - if ((lastletter == 's') || (lastletter == 'S') || (lastletter == '\'')) { - String singular = lookfor; - singular.ClipRight(1); - return find_word_in_dictionary(singular); - } - } - return -1; +int find_word_in_dictionary(const char *lookfor) { + int j; + if (game.dict == nullptr) + return -1; + + for (j = 0; j < game.dict->num_words; j++) { + if (ags_stricmp(lookfor, game.dict->word[j]) == 0) { + return game.dict->wordnum[j]; + } + } + if (lookfor[0] != 0) { + // If the word wasn't found, but it ends in 'S', see if there's + // a non-plural version + const char *ptat = &lookfor[strlen(lookfor) - 1]; + char lastletter = *ptat; + if ((lastletter == 's') || (lastletter == 'S') || (lastletter == '\'')) { + String singular = lookfor; + singular.ClipRight(1); + return find_word_in_dictionary(singular); + } + } + return -1; } int is_valid_word_char(char theChar) { - if ((isalnum((unsigned char)theChar)) || (theChar == '\'') || (theChar == '-')) { - return 1; - } - return 0; + if ((isalnum((unsigned char)theChar)) || (theChar == '\'') || (theChar == '-')) { + return 1; + } + return 0; } int FindMatchingMultiWordWord(char *thisword, const char **text) { - // see if there are any multi-word words - // that match -- if so, use them - const char *tempptr = *text; - char tempword[150] = ""; - if (thisword != nullptr) - strcpy(tempword, thisword); - - int bestMatchFound = -1, word; - const char *tempptrAtBestMatch = tempptr; - - do { - // extract and concat the next word - strcat(tempword, " "); - while (tempptr[0] == ' ') tempptr++; - char chbuffer[2]; - while (is_valid_word_char(tempptr[0])) { - sprintf(chbuffer, "%c", tempptr[0]); - strcat(tempword, chbuffer); - tempptr++; - } - // is this it? - word = find_word_in_dictionary(tempword); - // take the longest match we find - if (word >= 0) { - bestMatchFound = word; - tempptrAtBestMatch = tempptr; - } - - } while (tempptr[0] == ' '); - - word = bestMatchFound; - - if (word >= 0) { - // yes, a word like "pick up" was found - *text = tempptrAtBestMatch; - if (thisword != nullptr) - strcpy(thisword, tempword); - } - - return word; + // see if there are any multi-word words + // that match -- if so, use them + const char *tempptr = *text; + char tempword[150] = ""; + if (thisword != nullptr) + strcpy(tempword, thisword); + + int bestMatchFound = -1, word; + const char *tempptrAtBestMatch = tempptr; + + do { + // extract and concat the next word + strcat(tempword, " "); + while (tempptr[0] == ' ') tempptr++; + char chbuffer[2]; + while (is_valid_word_char(tempptr[0])) { + sprintf(chbuffer, "%c", tempptr[0]); + strcat(tempword, chbuffer); + tempptr++; + } + // is this it? + word = find_word_in_dictionary(tempword); + // take the longest match we find + if (word >= 0) { + bestMatchFound = word; + tempptrAtBestMatch = tempptr; + } + + } while (tempptr[0] == ' '); + + word = bestMatchFound; + + if (word >= 0) { + // yes, a word like "pick up" was found + *text = tempptrAtBestMatch; + if (thisword != nullptr) + strcpy(thisword, tempword); + } + + return word; } // parse_sentence: pass compareto as NULL to parse the sentence, or // compareto as non-null to check if it matches the passed sentence -int parse_sentence (const char *src_text, int *numwords, short*wordarray, short*compareto, int comparetonum) { - char thisword[150] = "\0"; - int i = 0, comparing = 0; - char in_optional = 0, do_word_now = 0; - int optional_start = 0; - - numwords[0] = 0; - if (compareto == nullptr) - play.bad_parsed_word[0] = 0; - - String uniform_text = src_text; - uniform_text.MakeLower(); - const char *text = uniform_text.GetCStr(); - while (1) { - if ((compareto != nullptr) && (compareto[comparing] == RESTOFLINE)) - return 1; - - if ((text[0] == ']') && (compareto != nullptr)) { - if (!in_optional) - quitprintf("!Said: unexpected ']'\nText: %s", src_text); - do_word_now = 1; - } - - if (is_valid_word_char(text[0])) { - // Part of a word, add it on - thisword[i] = text[0]; - i++; - } - else if ((text[0] == '[') && (compareto != nullptr)) { - if (in_optional) - quitprintf("!Said: nested optional words\nText: %s", src_text); - - in_optional = 1; - optional_start = comparing; - } - else if ((thisword[0] != 0) || ((text[0] == 0) && (i > 0)) || (do_word_now == 1)) { - // End of word, so process it - thisword[i] = 0; - i = 0; - int word = -1; - - if (text[0] == ' ') { - word = FindMatchingMultiWordWord(thisword, &text); - } - - if (word < 0) { - // just a normal word - word = find_word_in_dictionary(thisword); - } - - // "look rol" - if (word == RESTOFLINE) - return 1; - if (compareto) { - // check string is longer than user input - if (comparing >= comparetonum) { - if (in_optional) { - // eg. "exit [door]" - there's no more user input - // but the optional word is still there - if (do_word_now) { - in_optional = 0; - do_word_now = 0; - } - thisword[0] = 0; - text++; - continue; - } - return 0; - } - if (word <= 0) - quitprintf("!Said: supplied word '%s' is not in dictionary or is an ignored word\nText: %s", thisword, src_text); - if (word == ANYWORD) { } - else if (word != compareto[comparing]) { - // words don't match - if a comma then a list of possibles, - // so allow retry - if (text[0] == ',') - comparing--; - else { - // words don't match - if (in_optional) { - // inside an optional clause, so skip it - while (text[0] != ']') { - if (text[0] == 0) - quitprintf("!Said: unterminated [optional]\nText: %s", src_text); - text++; - } - // -1 because it's about to be ++'d again - comparing = optional_start - 1; - } - // words don't match outside an optional clause, abort - else - return 0; - } - } - else if (text[0] == ',') { - // this alternative matched, but there are more - // so skip the other alternatives - int continueSearching = 1; - while (continueSearching) { - - const char *textStart = &text[1]; - - while ((text[0] == ',') || (isalnum((unsigned char)text[0]) != 0)) - text++; - - continueSearching = 0; - - if (text[0] == ' ') { - strcpy(thisword, textStart); - thisword[text - textStart] = 0; - // forward past any multi-word alternatives - if (FindMatchingMultiWordWord(thisword, &text) >= 0) - continueSearching = 1; - } - } - - if ((text[0] == ']') && (in_optional)) { - // [go,move] we just matched "go", so skip over "move" - in_optional = 0; - text++; - } - - // go back cos it'll be ++'d in a minute - text--; - } - comparing++; - } - else if (word != 0) { - // it's not an ignore word (it's a known word, or an unknown - // word, so save its index) - wordarray[numwords[0]] = word; - numwords[0]++; - if (numwords[0] >= MAX_PARSED_WORDS) - return 0; - // if it's an unknown word, store it for use in messages like - // "you can't use the word 'xxx' in this game" - if ((word < 0) && (play.bad_parsed_word[0] == 0)) - strcpy(play.bad_parsed_word, thisword); - } - - if (do_word_now) { - in_optional = 0; - do_word_now = 0; - } - - thisword[0] = 0; - } - if (text[0] == 0) - break; - text++; - } - // If the user input is longer than the Said string, it's wrong - // eg Said("look door") and they type "look door jibble" - // rol should be used instead to enable this - if (comparing < comparetonum) - return 0; - return 1; +int parse_sentence(const char *src_text, int *numwords, short *wordarray, short *compareto, int comparetonum) { + char thisword[150] = "\0"; + int i = 0, comparing = 0; + char in_optional = 0, do_word_now = 0; + int optional_start = 0; + + numwords[0] = 0; + if (compareto == nullptr) + play.bad_parsed_word[0] = 0; + + String uniform_text = src_text; + uniform_text.MakeLower(); + const char *text = uniform_text.GetCStr(); + while (1) { + if ((compareto != nullptr) && (compareto[comparing] == RESTOFLINE)) + return 1; + + if ((text[0] == ']') && (compareto != nullptr)) { + if (!in_optional) + quitprintf("!Said: unexpected ']'\nText: %s", src_text); + do_word_now = 1; + } + + if (is_valid_word_char(text[0])) { + // Part of a word, add it on + thisword[i] = text[0]; + i++; + } else if ((text[0] == '[') && (compareto != nullptr)) { + if (in_optional) + quitprintf("!Said: nested optional words\nText: %s", src_text); + + in_optional = 1; + optional_start = comparing; + } else if ((thisword[0] != 0) || ((text[0] == 0) && (i > 0)) || (do_word_now == 1)) { + // End of word, so process it + thisword[i] = 0; + i = 0; + int word = -1; + + if (text[0] == ' ') { + word = FindMatchingMultiWordWord(thisword, &text); + } + + if (word < 0) { + // just a normal word + word = find_word_in_dictionary(thisword); + } + + // "look rol" + if (word == RESTOFLINE) + return 1; + if (compareto) { + // check string is longer than user input + if (comparing >= comparetonum) { + if (in_optional) { + // eg. "exit [door]" - there's no more user input + // but the optional word is still there + if (do_word_now) { + in_optional = 0; + do_word_now = 0; + } + thisword[0] = 0; + text++; + continue; + } + return 0; + } + if (word <= 0) + quitprintf("!Said: supplied word '%s' is not in dictionary or is an ignored word\nText: %s", thisword, src_text); + if (word == ANYWORD) { } + else if (word != compareto[comparing]) { + // words don't match - if a comma then a list of possibles, + // so allow retry + if (text[0] == ',') + comparing--; + else { + // words don't match + if (in_optional) { + // inside an optional clause, so skip it + while (text[0] != ']') { + if (text[0] == 0) + quitprintf("!Said: unterminated [optional]\nText: %s", src_text); + text++; + } + // -1 because it's about to be ++'d again + comparing = optional_start - 1; + } + // words don't match outside an optional clause, abort + else + return 0; + } + } else if (text[0] == ',') { + // this alternative matched, but there are more + // so skip the other alternatives + int continueSearching = 1; + while (continueSearching) { + + const char *textStart = &text[1]; + + while ((text[0] == ',') || (isalnum((unsigned char)text[0]) != 0)) + text++; + + continueSearching = 0; + + if (text[0] == ' ') { + strcpy(thisword, textStart); + thisword[text - textStart] = 0; + // forward past any multi-word alternatives + if (FindMatchingMultiWordWord(thisword, &text) >= 0) + continueSearching = 1; + } + } + + if ((text[0] == ']') && (in_optional)) { + // [go,move] we just matched "go", so skip over "move" + in_optional = 0; + text++; + } + + // go back cos it'll be ++'d in a minute + text--; + } + comparing++; + } else if (word != 0) { + // it's not an ignore word (it's a known word, or an unknown + // word, so save its index) + wordarray[numwords[0]] = word; + numwords[0]++; + if (numwords[0] >= MAX_PARSED_WORDS) + return 0; + // if it's an unknown word, store it for use in messages like + // "you can't use the word 'xxx' in this game" + if ((word < 0) && (play.bad_parsed_word[0] == 0)) + strcpy(play.bad_parsed_word, thisword); + } + + if (do_word_now) { + in_optional = 0; + do_word_now = 0; + } + + thisword[0] = 0; + } + if (text[0] == 0) + break; + text++; + } + // If the user input is longer than the Said string, it's wrong + // eg Said("look door") and they type "look door jibble" + // rol should be used instead to enable this + if (comparing < comparetonum) + return 0; + return 1; } //============================================================================= @@ -312,42 +307,37 @@ int parse_sentence (const char *src_text, int *numwords, short*wordarray, short* extern ScriptString myScriptStringImpl; // int (const char *wordToFind) -RuntimeScriptValue Sc_Parser_FindWordID(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(Parser_FindWordID, const char); +RuntimeScriptValue Sc_Parser_FindWordID(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(Parser_FindWordID, const char); } // void (char*text) -RuntimeScriptValue Sc_ParseText(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_POBJ(ParseText, /*const*/ char); +RuntimeScriptValue Sc_ParseText(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_POBJ(ParseText, /*const*/ char); } // const char* () -RuntimeScriptValue Sc_Parser_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ(const char, myScriptStringImpl, Parser_SaidUnknownWord); +RuntimeScriptValue Sc_Parser_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ(const char, myScriptStringImpl, Parser_SaidUnknownWord); } // int (char*checkwords) -RuntimeScriptValue Sc_Said(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(Said, /*const*/ char); +RuntimeScriptValue Sc_Said(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(Said, /*const*/ char); } -void RegisterParserAPI() -{ - ccAddExternalStaticFunction("Parser::FindWordID^1", Sc_Parser_FindWordID); - ccAddExternalStaticFunction("Parser::ParseText^1", Sc_ParseText); - ccAddExternalStaticFunction("Parser::SaidUnknownWord^0",Sc_Parser_SaidUnknownWord); - ccAddExternalStaticFunction("Parser::Said^1", Sc_Said); +void RegisterParserAPI() { + ccAddExternalStaticFunction("Parser::FindWordID^1", Sc_Parser_FindWordID); + ccAddExternalStaticFunction("Parser::ParseText^1", Sc_ParseText); + ccAddExternalStaticFunction("Parser::SaidUnknownWord^0", Sc_Parser_SaidUnknownWord); + ccAddExternalStaticFunction("Parser::Said^1", Sc_Said); - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - ccAddExternalFunctionForPlugin("Parser::FindWordID^1", (void*)Parser_FindWordID); - ccAddExternalFunctionForPlugin("Parser::ParseText^1", (void*)ParseText); - ccAddExternalFunctionForPlugin("Parser::SaidUnknownWord^0",(void*)Parser_SaidUnknownWord); - ccAddExternalFunctionForPlugin("Parser::Said^1", (void*)Said); + ccAddExternalFunctionForPlugin("Parser::FindWordID^1", (void *)Parser_FindWordID); + ccAddExternalFunctionForPlugin("Parser::ParseText^1", (void *)ParseText); + ccAddExternalFunctionForPlugin("Parser::SaidUnknownWord^0", (void *)Parser_SaidUnknownWord); + ccAddExternalFunctionForPlugin("Parser::Said^1", (void *)Said); } diff --git a/engines/ags/engine/ac/parser.h b/engines/ags/engine/ac/parser.h index 6da49934ab60..2f7431ac07f2 100644 --- a/engines/ags/engine/ac/parser.h +++ b/engines/ags/engine/ac/parser.h @@ -24,15 +24,15 @@ #define AGS_ENGINE_AC_PARSER_H int Parser_FindWordID(const char *wordToFind); -const char* Parser_SaidUnknownWord(); -void ParseText (const char*text); -int Said (const char*checkwords); +const char *Parser_SaidUnknownWord(); +void ParseText(const char *text); +int Said(const char *checkwords); //============================================================================= -int find_word_in_dictionary (const char *lookfor); +int find_word_in_dictionary(const char *lookfor); int is_valid_word_char(char theChar); int FindMatchingMultiWordWord(char *thisword, const char **text); -int parse_sentence (const char *src_text, int *numwords, short*wordarray, short*compareto, int comparetonum); +int parse_sentence(const char *src_text, int *numwords, short *wordarray, short *compareto, int comparetonum); #endif diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h index a5cd9d89dacb..3761f15dac54 100644 --- a/engines/ags/engine/ac/path_helper.h +++ b/engines/ags/engine/ac/path_helper.h @@ -38,9 +38,8 @@ extern const String UserSavedgamesRootToken; extern const String GameSavedgamesDirToken; extern const String GameDataDirToken; -inline const char *PathOrCurDir(const char *path) -{ - return path ? path : "."; +inline const char *PathOrCurDir(const char *path) { + return path ? path : "."; } // Subsitutes illegal characters with '_'. This function uses illegal chars array @@ -56,11 +55,10 @@ String FixSlashAfterToken(const String &path); String MakeSpecialSubDir(const String &sp_dir); // ResolvedPath describes an actual location pointed by a user path (e.g. from script) -struct ResolvedPath -{ - String BaseDir; // base directory, one of the special path roots - String FullPath;// full path - String AltPath; // alternative full path, for backwards compatibility +struct ResolvedPath { + String BaseDir; // base directory, one of the special path roots + String FullPath;// full path + String AltPath; // alternative full path, for backwards compatibility }; // Resolves a file path provided by user (e.g. script) into actual file path, // by substituting special keywords with actual platform-specific directory names. @@ -81,6 +79,6 @@ void set_install_dir(const String &path, const String &audio_path, const Stri String get_install_dir(); String get_audio_install_dir(); String get_voice_install_dir(); -void get_install_dir_path(char* buffer, const char *fileName); +void get_install_dir_path(char *buffer, const char *fileName); #endif diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp index 5c773c93bcf7..aae559baac16 100644 --- a/engines/ags/engine/ac/properties.cpp +++ b/engines/ags/engine/ac/properties.cpp @@ -35,81 +35,72 @@ extern ScriptString myScriptStringImpl; // begin custom property functions -bool get_property_desc(PropertyDesc &desc, const char *property, PropertyType want_type) -{ - PropertySchema::const_iterator sch_it = game.propSchema.find(property); - if (sch_it == game.propSchema.end()) - quit("!GetProperty: no such property found in schema. Make sure you are using the property's name, and not its description, when calling this command."); +bool get_property_desc(PropertyDesc &desc, const char *property, PropertyType want_type) { + PropertySchema::const_iterator sch_it = game.propSchema.find(property); + if (sch_it == game.propSchema.end()) + quit("!GetProperty: no such property found in schema. Make sure you are using the property's name, and not its description, when calling this command."); - desc = sch_it->second; - if (want_type == kPropertyString && desc.Type != kPropertyString) - quit("!GetTextProperty: need to use GetProperty for a non-text property"); - else if (want_type != kPropertyString && desc.Type == kPropertyString) - quit("!GetProperty: need to use GetTextProperty for a text property"); - return true; + desc = sch_it->second; + if (want_type == kPropertyString && desc.Type != kPropertyString) + quit("!GetTextProperty: need to use GetProperty for a non-text property"); + else if (want_type != kPropertyString && desc.Type == kPropertyString) + quit("!GetProperty: need to use GetTextProperty for a text property"); + return true; } -String get_property_value(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, const String def_val) -{ - // First check runtime properties, then static properties; - // if no matching entry was found, use default schema value - StringIMap::const_iterator it = rt_prop.find(property); - if (it != rt_prop.end()) - return it->second; - it = st_prop.find(property); - if (it != st_prop.end()) - return it->second; - return def_val; +String get_property_value(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, const String def_val) { + // First check runtime properties, then static properties; + // if no matching entry was found, use default schema value + StringIMap::const_iterator it = rt_prop.find(property); + if (it != rt_prop.end()) + return it->second; + it = st_prop.find(property); + if (it != st_prop.end()) + return it->second; + return def_val; } // Get an integer property -int get_int_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property) -{ - PropertyDesc desc; - if (!get_property_desc(desc, property, kPropertyInteger)) - return 0; - return StrUtil::StringToInt(get_property_value(st_prop, rt_prop, property, desc.DefaultValue)); +int get_int_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property) { + PropertyDesc desc; + if (!get_property_desc(desc, property, kPropertyInteger)) + return 0; + return StrUtil::StringToInt(get_property_value(st_prop, rt_prop, property, desc.DefaultValue)); } // Get a string property -void get_text_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, char *bufer) -{ - PropertyDesc desc; - if (!get_property_desc(desc, property, kPropertyString)) - return; +void get_text_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, char *bufer) { + PropertyDesc desc; + if (!get_property_desc(desc, property, kPropertyString)) + return; - String val = get_property_value(st_prop, rt_prop, property, desc.DefaultValue); - strcpy(bufer, val); + String val = get_property_value(st_prop, rt_prop, property, desc.DefaultValue); + strcpy(bufer, val); } -const char* get_text_property_dynamic_string(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property) -{ - PropertyDesc desc; - if (!get_property_desc(desc, property, kPropertyString)) - return nullptr; +const char *get_text_property_dynamic_string(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property) { + PropertyDesc desc; + if (!get_property_desc(desc, property, kPropertyString)) + return nullptr; - String val = get_property_value(st_prop, rt_prop, property, desc.DefaultValue); - return CreateNewScriptString(val); + String val = get_property_value(st_prop, rt_prop, property, desc.DefaultValue); + return CreateNewScriptString(val); } -bool set_int_property(StringIMap &rt_prop, const char *property, int value) -{ - PropertyDesc desc; - if (get_property_desc(desc, property, kPropertyInteger)) - { - rt_prop[desc.Name] = StrUtil::IntToString(value); - return true; - } - return false; +bool set_int_property(StringIMap &rt_prop, const char *property, int value) { + PropertyDesc desc; + if (get_property_desc(desc, property, kPropertyInteger)) { + rt_prop[desc.Name] = StrUtil::IntToString(value); + return true; + } + return false; } -bool set_text_property(StringIMap &rt_prop, const char *property, const char* value) -{ - PropertyDesc desc; - if (get_property_desc(desc, property, kPropertyString)) - { - rt_prop[desc.Name] = value; - return true; - } - return false; +bool set_text_property(StringIMap &rt_prop, const char *property, const char *value) { + PropertyDesc desc; + if (get_property_desc(desc, property, kPropertyString)) { + rt_prop[desc.Name] = value; + return true; + } + return false; } diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h index f0d233a8c828..44bc30ffb368 100644 --- a/engines/ags/engine/ac/properties.h +++ b/engines/ags/engine/ac/properties.h @@ -34,9 +34,9 @@ using AGS::Common::StringIMap; // returned for the given property. int get_int_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property); void get_text_property(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property, char *bufer); -const char* get_text_property_dynamic_string(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property); +const char *get_text_property_dynamic_string(const StringIMap &st_prop, const StringIMap &rt_prop, const char *property); bool set_int_property(StringIMap &rt_prop, const char *property, int value); -bool set_text_property(StringIMap &rt_prop, const char *property, const char* value); +bool set_text_property(StringIMap &rt_prop, const char *property, const char *value); #endif diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp index 39fd7f233abb..a9755ed88de5 100644 --- a/engines/ags/engine/ac/region.cpp +++ b/engines/ags/engine/ac/region.cpp @@ -36,7 +36,7 @@ using namespace AGS::Common; extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; extern RoomStruct thisroom; -extern RoomStatus*croom; +extern RoomStatus *croom; extern GameSetupStruct game; extern COLOR_MAP maincoltable; extern color palette[256]; @@ -44,94 +44,88 @@ extern CCRegion ccDynamicRegion; ScriptRegion *GetRegionAtRoom(int xx, int yy) { - return &scrRegion[GetRegionIDAtRoom(xx, yy)]; + return &scrRegion[GetRegionIDAtRoom(xx, yy)]; } -ScriptRegion *GetRegionAtScreen(int x, int y) -{ - VpPoint vpt = play.ScreenToRoomDivDown(x, y); - if (vpt.second < 0) - return nullptr; - return GetRegionAtRoom(vpt.first.X, vpt.first.Y); +ScriptRegion *GetRegionAtScreen(int x, int y) { + VpPoint vpt = play.ScreenToRoomDivDown(x, y); + if (vpt.second < 0) + return nullptr; + return GetRegionAtRoom(vpt.first.X, vpt.first.Y); } void Region_SetLightLevel(ScriptRegion *ssr, int brightness) { - SetAreaLightLevel(ssr->id, brightness); + SetAreaLightLevel(ssr->id, brightness); } int Region_GetLightLevel(ScriptRegion *ssr) { - return thisroom.GetRegionLightLevel(ssr->id); + return thisroom.GetRegionLightLevel(ssr->id); } int Region_GetTintEnabled(ScriptRegion *srr) { - if (thisroom.Regions[srr->id].Tint & 0xFF000000) - return 1; - return 0; + if (thisroom.Regions[srr->id].Tint & 0xFF000000) + return 1; + return 0; } int Region_GetTintRed(ScriptRegion *srr) { - return thisroom.Regions[srr->id].Tint & 0x000000ff; + return thisroom.Regions[srr->id].Tint & 0x000000ff; } int Region_GetTintGreen(ScriptRegion *srr) { - return (thisroom.Regions[srr->id].Tint >> 8) & 0x000000ff; + return (thisroom.Regions[srr->id].Tint >> 8) & 0x000000ff; } int Region_GetTintBlue(ScriptRegion *srr) { - return (thisroom.Regions[srr->id].Tint >> 16) & 0x000000ff; + return (thisroom.Regions[srr->id].Tint >> 16) & 0x000000ff; } int Region_GetTintSaturation(ScriptRegion *srr) { - return (thisroom.Regions[srr->id].Tint >> 24) & 0xFF; + return (thisroom.Regions[srr->id].Tint >> 24) & 0xFF; } -int Region_GetTintLuminance(ScriptRegion *srr) -{ - return thisroom.GetRegionTintLuminance(srr->id); +int Region_GetTintLuminance(ScriptRegion *srr) { + return thisroom.GetRegionTintLuminance(srr->id); } -void Region_Tint(ScriptRegion *srr, int red, int green, int blue, int amount, int luminance) -{ - SetRegionTint(srr->id, red, green, blue, amount, luminance); +void Region_Tint(ScriptRegion *srr, int red, int green, int blue, int amount, int luminance) { + SetRegionTint(srr->id, red, green, blue, amount, luminance); } -void Region_TintNoLum(ScriptRegion *srr, int red, int green, int blue, int amount) -{ - SetRegionTint(srr->id, red, green, blue, amount); +void Region_TintNoLum(ScriptRegion *srr, int red, int green, int blue, int amount) { + SetRegionTint(srr->id, red, green, blue, amount); } void Region_SetEnabled(ScriptRegion *ssr, int enable) { - if (enable) - EnableRegion(ssr->id); - else - DisableRegion(ssr->id); + if (enable) + EnableRegion(ssr->id); + else + DisableRegion(ssr->id); } int Region_GetEnabled(ScriptRegion *ssr) { - return croom->region_enabled[ssr->id]; + return croom->region_enabled[ssr->id]; } int Region_GetID(ScriptRegion *ssr) { - return ssr->id; + return ssr->id; } void Region_RunInteraction(ScriptRegion *ssr, int mood) { - RunRegionInteraction(ssr->id, mood); + RunRegionInteraction(ssr->id, mood); } //============================================================================= -void generate_light_table() -{ - if (game.color_depth == 1 && color_map == nullptr) - { - create_light_table(&maincoltable, palette, 0, 0, 0, nullptr); - color_map = &maincoltable; - } +void generate_light_table() { + if (game.color_depth == 1 && color_map == nullptr) { + create_light_table(&maincoltable, palette, 0, 0, 0, nullptr); + color_map = &maincoltable; + } } //============================================================================= @@ -145,140 +139,122 @@ void generate_light_table() #include "script/script_runtime.h" // ScriptRegion *(int xx, int yy) -RuntimeScriptValue Sc_GetRegionAtRoom(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtRoom); +RuntimeScriptValue Sc_GetRegionAtRoom(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtRoom); } -RuntimeScriptValue Sc_GetRegionAtScreen(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtScreen); +RuntimeScriptValue Sc_GetRegionAtScreen(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtScreen); } -RuntimeScriptValue Sc_Region_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) -{ - ScriptDrawingSurface* ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaRegion); - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); +RuntimeScriptValue Sc_Region_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) { + ScriptDrawingSurface *ret_obj = Room_GetDrawingSurfaceForMask(kRoomAreaRegion); + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj); } -RuntimeScriptValue Sc_Region_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT5(ScriptRegion, Region_Tint); +RuntimeScriptValue Sc_Region_Tint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT5(ScriptRegion, Region_Tint); } // void (ScriptRegion *srr, int red, int green, int blue, int amount) -RuntimeScriptValue Sc_Region_TintNoLum(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(ScriptRegion, Region_TintNoLum); +RuntimeScriptValue Sc_Region_TintNoLum(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(ScriptRegion, Region_TintNoLum); } // void (ScriptRegion *ssr, int mood) -RuntimeScriptValue Sc_Region_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptRegion, Region_RunInteraction); +RuntimeScriptValue Sc_Region_RunInteraction(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptRegion, Region_RunInteraction); } // int (ScriptRegion *ssr) -RuntimeScriptValue Sc_Region_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetEnabled); +RuntimeScriptValue Sc_Region_GetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetEnabled); } // void (ScriptRegion *ssr, int enable) -RuntimeScriptValue Sc_Region_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptRegion, Region_SetEnabled); +RuntimeScriptValue Sc_Region_SetEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptRegion, Region_SetEnabled); } // int (ScriptRegion *ssr) -RuntimeScriptValue Sc_Region_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetID); +RuntimeScriptValue Sc_Region_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetID); } // int (ScriptRegion *ssr) -RuntimeScriptValue Sc_Region_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetLightLevel); +RuntimeScriptValue Sc_Region_GetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetLightLevel); } // void (ScriptRegion *ssr, int brightness) -RuntimeScriptValue Sc_Region_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptRegion, Region_SetLightLevel); +RuntimeScriptValue Sc_Region_SetLightLevel(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptRegion, Region_SetLightLevel); } // int (ScriptRegion *srr) -RuntimeScriptValue Sc_Region_GetTintEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetTintEnabled); +RuntimeScriptValue Sc_Region_GetTintEnabled(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetTintEnabled); } // int (ScriptRegion *srr) -RuntimeScriptValue Sc_Region_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetTintBlue); +RuntimeScriptValue Sc_Region_GetTintBlue(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetTintBlue); } // int (ScriptRegion *srr) -RuntimeScriptValue Sc_Region_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetTintGreen); +RuntimeScriptValue Sc_Region_GetTintGreen(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetTintGreen); } // int (ScriptRegion *srr) -RuntimeScriptValue Sc_Region_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetTintRed); +RuntimeScriptValue Sc_Region_GetTintRed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetTintRed); } // int (ScriptRegion *srr) -RuntimeScriptValue Sc_Region_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetTintSaturation); -} - -RuntimeScriptValue Sc_Region_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptRegion, Region_GetTintLuminance); -} - - - -void RegisterRegionAPI() -{ - ccAddExternalStaticFunction("Region::GetAtRoomXY^2", Sc_GetRegionAtRoom); - ccAddExternalStaticFunction("Region::GetAtScreenXY^2", Sc_GetRegionAtScreen); - ccAddExternalStaticFunction("Region::GetDrawingSurface", Sc_Region_GetDrawingSurface); - ccAddExternalObjectFunction("Region::Tint^4", Sc_Region_TintNoLum); - ccAddExternalObjectFunction("Region::Tint^5", Sc_Region_Tint); - ccAddExternalObjectFunction("Region::RunInteraction^1", Sc_Region_RunInteraction); - ccAddExternalObjectFunction("Region::get_Enabled", Sc_Region_GetEnabled); - ccAddExternalObjectFunction("Region::set_Enabled", Sc_Region_SetEnabled); - ccAddExternalObjectFunction("Region::get_ID", Sc_Region_GetID); - ccAddExternalObjectFunction("Region::get_LightLevel", Sc_Region_GetLightLevel); - ccAddExternalObjectFunction("Region::set_LightLevel", Sc_Region_SetLightLevel); - ccAddExternalObjectFunction("Region::get_TintEnabled", Sc_Region_GetTintEnabled); - ccAddExternalObjectFunction("Region::get_TintBlue", Sc_Region_GetTintBlue); - ccAddExternalObjectFunction("Region::get_TintGreen", Sc_Region_GetTintGreen); - ccAddExternalObjectFunction("Region::get_TintRed", Sc_Region_GetTintRed); - ccAddExternalObjectFunction("Region::get_TintSaturation", Sc_Region_GetTintSaturation); - ccAddExternalObjectFunction("Region::get_TintLuminance", Sc_Region_GetTintLuminance); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Region::GetAtRoomXY^2", (void*)GetRegionAtRoom); - ccAddExternalFunctionForPlugin("Region::GetAtScreenXY^2", (void*)GetRegionAtScreen); - ccAddExternalFunctionForPlugin("Region::Tint^4", (void*)Region_TintNoLum); - ccAddExternalFunctionForPlugin("Region::RunInteraction^1", (void*)Region_RunInteraction); - ccAddExternalFunctionForPlugin("Region::get_Enabled", (void*)Region_GetEnabled); - ccAddExternalFunctionForPlugin("Region::set_Enabled", (void*)Region_SetEnabled); - ccAddExternalFunctionForPlugin("Region::get_ID", (void*)Region_GetID); - ccAddExternalFunctionForPlugin("Region::get_LightLevel", (void*)Region_GetLightLevel); - ccAddExternalFunctionForPlugin("Region::set_LightLevel", (void*)Region_SetLightLevel); - ccAddExternalFunctionForPlugin("Region::get_TintEnabled", (void*)Region_GetTintEnabled); - ccAddExternalFunctionForPlugin("Region::get_TintBlue", (void*)Region_GetTintBlue); - ccAddExternalFunctionForPlugin("Region::get_TintGreen", (void*)Region_GetTintGreen); - ccAddExternalFunctionForPlugin("Region::get_TintRed", (void*)Region_GetTintRed); - ccAddExternalFunctionForPlugin("Region::get_TintSaturation", (void*)Region_GetTintSaturation); +RuntimeScriptValue Sc_Region_GetTintSaturation(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetTintSaturation); +} + +RuntimeScriptValue Sc_Region_GetTintLuminance(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptRegion, Region_GetTintLuminance); +} + + + +void RegisterRegionAPI() { + ccAddExternalStaticFunction("Region::GetAtRoomXY^2", Sc_GetRegionAtRoom); + ccAddExternalStaticFunction("Region::GetAtScreenXY^2", Sc_GetRegionAtScreen); + ccAddExternalStaticFunction("Region::GetDrawingSurface", Sc_Region_GetDrawingSurface); + ccAddExternalObjectFunction("Region::Tint^4", Sc_Region_TintNoLum); + ccAddExternalObjectFunction("Region::Tint^5", Sc_Region_Tint); + ccAddExternalObjectFunction("Region::RunInteraction^1", Sc_Region_RunInteraction); + ccAddExternalObjectFunction("Region::get_Enabled", Sc_Region_GetEnabled); + ccAddExternalObjectFunction("Region::set_Enabled", Sc_Region_SetEnabled); + ccAddExternalObjectFunction("Region::get_ID", Sc_Region_GetID); + ccAddExternalObjectFunction("Region::get_LightLevel", Sc_Region_GetLightLevel); + ccAddExternalObjectFunction("Region::set_LightLevel", Sc_Region_SetLightLevel); + ccAddExternalObjectFunction("Region::get_TintEnabled", Sc_Region_GetTintEnabled); + ccAddExternalObjectFunction("Region::get_TintBlue", Sc_Region_GetTintBlue); + ccAddExternalObjectFunction("Region::get_TintGreen", Sc_Region_GetTintGreen); + ccAddExternalObjectFunction("Region::get_TintRed", Sc_Region_GetTintRed); + ccAddExternalObjectFunction("Region::get_TintSaturation", Sc_Region_GetTintSaturation); + ccAddExternalObjectFunction("Region::get_TintLuminance", Sc_Region_GetTintLuminance); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Region::GetAtRoomXY^2", (void *)GetRegionAtRoom); + ccAddExternalFunctionForPlugin("Region::GetAtScreenXY^2", (void *)GetRegionAtScreen); + ccAddExternalFunctionForPlugin("Region::Tint^4", (void *)Region_TintNoLum); + ccAddExternalFunctionForPlugin("Region::RunInteraction^1", (void *)Region_RunInteraction); + ccAddExternalFunctionForPlugin("Region::get_Enabled", (void *)Region_GetEnabled); + ccAddExternalFunctionForPlugin("Region::set_Enabled", (void *)Region_SetEnabled); + ccAddExternalFunctionForPlugin("Region::get_ID", (void *)Region_GetID); + ccAddExternalFunctionForPlugin("Region::get_LightLevel", (void *)Region_GetLightLevel); + ccAddExternalFunctionForPlugin("Region::set_LightLevel", (void *)Region_SetLightLevel); + ccAddExternalFunctionForPlugin("Region::get_TintEnabled", (void *)Region_GetTintEnabled); + ccAddExternalFunctionForPlugin("Region::get_TintBlue", (void *)Region_GetTintBlue); + ccAddExternalFunctionForPlugin("Region::get_TintGreen", (void *)Region_GetTintGreen); + ccAddExternalFunctionForPlugin("Region::get_TintRed", (void *)Region_GetTintRed); + ccAddExternalFunctionForPlugin("Region::get_TintSaturation", (void *)Region_GetTintSaturation); } diff --git a/engines/ags/engine/ac/region.h b/engines/ags/engine/ac/region.h index 9deb80b13369..49a9688ed2ee 100644 --- a/engines/ags/engine/ac/region.h +++ b/engines/ags/engine/ac/region.h @@ -38,7 +38,7 @@ void Region_Tint(ScriptRegion *srr, int red, int green, int blue, int amount, void Region_SetEnabled(ScriptRegion *ssr, int enable); int Region_GetEnabled(ScriptRegion *ssr); int Region_GetID(ScriptRegion *ssr); -void Region_RunInteraction(ScriptRegion *ssr, int mood); +void Region_RunInteraction(ScriptRegion *ssr, int mood); void generate_light_table(); diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp index dd8313ab1d79..7e0888c2c034 100644 --- a/engines/ags/engine/ac/richgamemedia.cpp +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -25,32 +25,30 @@ using AGS::Common::Stream; -void RICH_GAME_MEDIA_HEADER::ReadFromFile(Stream *in) -{ - dwMagicNumber = in->ReadInt32(); - dwHeaderVersion = in->ReadInt32(); - dwHeaderSize = in->ReadInt32(); - dwThumbnailOffsetLowerDword = in->ReadInt32(); - dwThumbnailOffsetHigherDword = in->ReadInt32(); - dwThumbnailSize = in->ReadInt32(); - in->Read(guidGameId, 16); - in->ReadArrayOfInt16((int16_t*)szGameName, RM_MAXLENGTH); - in->ReadArrayOfInt16((int16_t*)szSaveName, RM_MAXLENGTH); - in->ReadArrayOfInt16((int16_t*)szLevelName, RM_MAXLENGTH); - in->ReadArrayOfInt16((int16_t*)szComments, RM_MAXLENGTH); +void RICH_GAME_MEDIA_HEADER::ReadFromFile(Stream *in) { + dwMagicNumber = in->ReadInt32(); + dwHeaderVersion = in->ReadInt32(); + dwHeaderSize = in->ReadInt32(); + dwThumbnailOffsetLowerDword = in->ReadInt32(); + dwThumbnailOffsetHigherDword = in->ReadInt32(); + dwThumbnailSize = in->ReadInt32(); + in->Read(guidGameId, 16); + in->ReadArrayOfInt16((int16_t *)szGameName, RM_MAXLENGTH); + in->ReadArrayOfInt16((int16_t *)szSaveName, RM_MAXLENGTH); + in->ReadArrayOfInt16((int16_t *)szLevelName, RM_MAXLENGTH); + in->ReadArrayOfInt16((int16_t *)szComments, RM_MAXLENGTH); } -void RICH_GAME_MEDIA_HEADER::WriteToFile(Stream *out) -{ - out->WriteInt32(dwMagicNumber); - out->WriteInt32(dwHeaderVersion); - out->WriteInt32(dwHeaderSize); - out->WriteInt32(dwThumbnailOffsetLowerDword); - out->WriteInt32(dwThumbnailOffsetHigherDword); - out->WriteInt32(dwThumbnailSize); - out->Write(guidGameId, 16); - out->WriteArrayOfInt16((int16_t*)szGameName, RM_MAXLENGTH); - out->WriteArrayOfInt16((int16_t*)szSaveName, RM_MAXLENGTH); - out->WriteArrayOfInt16((int16_t*)szLevelName, RM_MAXLENGTH); - out->WriteArrayOfInt16((int16_t*)szComments, RM_MAXLENGTH); +void RICH_GAME_MEDIA_HEADER::WriteToFile(Stream *out) { + out->WriteInt32(dwMagicNumber); + out->WriteInt32(dwHeaderVersion); + out->WriteInt32(dwHeaderSize); + out->WriteInt32(dwThumbnailOffsetLowerDword); + out->WriteInt32(dwThumbnailOffsetHigherDword); + out->WriteInt32(dwThumbnailSize); + out->Write(guidGameId, 16); + out->WriteArrayOfInt16((int16_t *)szGameName, RM_MAXLENGTH); + out->WriteArrayOfInt16((int16_t *)szSaveName, RM_MAXLENGTH); + out->WriteArrayOfInt16((int16_t *)szLevelName, RM_MAXLENGTH); + out->WriteArrayOfInt16((int16_t *)szComments, RM_MAXLENGTH); } diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index 28acaf2cbbed..faeac1760b44 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -29,27 +29,30 @@ #define RM_MAGICNUMBER "RGMH" // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #pragma pack(push) #pragma pack(1) -typedef struct _RICH_GAME_MEDIA_HEADER -{ - int dwMagicNumber; - int dwHeaderVersion; - int dwHeaderSize; - int dwThumbnailOffsetLowerDword; - int dwThumbnailOffsetHigherDword; - int dwThumbnailSize; - unsigned char guidGameId[16]; - unsigned short szGameName[RM_MAXLENGTH]; - unsigned short szSaveName[RM_MAXLENGTH]; - unsigned short szLevelName[RM_MAXLENGTH]; - unsigned short szComments[RM_MAXLENGTH]; +typedef struct _RICH_GAME_MEDIA_HEADER { + int dwMagicNumber; + int dwHeaderVersion; + int dwHeaderSize; + int dwThumbnailOffsetLowerDword; + int dwThumbnailOffsetHigherDword; + int dwThumbnailSize; + unsigned char guidGameId[16]; + unsigned short szGameName[RM_MAXLENGTH]; + unsigned short szSaveName[RM_MAXLENGTH]; + unsigned short szLevelName[RM_MAXLENGTH]; + unsigned short szComments[RM_MAXLENGTH]; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); } RICH_GAME_MEDIA_HEADER; #pragma pack(pop) diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index f62d72e90ce5..e77929b86320 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -83,10 +83,10 @@ using namespace AGS::Engine; extern GameSetup usetup; extern GameSetupStruct game; extern GameState play; -extern RoomStatus*croom; +extern RoomStatus *croom; extern RoomStatus troom; // used for non-saveable rooms, eg. intro extern int displayed_room; -extern RoomObject*objs; +extern RoomObject *objs; extern ccInstance *roominst; extern AGSPlatformDriver *platform; extern int numevents; @@ -101,18 +101,18 @@ extern SpriteCache spriteset; extern int in_new_room, new_room_was; // 1 in new room, 2 first time in new room, 3 loading saved game extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; extern int in_leaves_screen; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern int starting_room; extern unsigned int loopcounter; -extern IDriverDependantBitmap* roomBackgroundBmp; +extern IDriverDependantBitmap *roomBackgroundBmp; extern IGraphicsDriver *gfxDriver; extern Bitmap *raw_saved_screen; extern int actSpsCount; extern Bitmap **actsps; -extern IDriverDependantBitmap* *actspsbmp; +extern IDriverDependantBitmap * *actspsbmp; extern Bitmap **actspswb; -extern IDriverDependantBitmap* *actspswbbmp; -extern CachedActSpsData* actspswbcache; +extern IDriverDependantBitmap * *actspswbbmp; +extern CachedActSpsData *actspswbcache; extern color palette[256]; extern int mouse_z_was; @@ -123,103 +123,96 @@ extern CCHotspot ccDynamicHotspot; extern CCObject ccDynamicObject; RGB_MAP rgb_table; // for 256-col antialiasing -int new_room_flags=0; -int gs_to_newroom=-1; +int new_room_flags = 0; +int gs_to_newroom = -1; -ScriptDrawingSurface* Room_GetDrawingSurfaceForBackground(int backgroundNumber) -{ - if (displayed_room < 0) - quit("!Room.GetDrawingSurfaceForBackground: no room is currently loaded"); +ScriptDrawingSurface *Room_GetDrawingSurfaceForBackground(int backgroundNumber) { + if (displayed_room < 0) + quit("!Room.GetDrawingSurfaceForBackground: no room is currently loaded"); - if (backgroundNumber == SCR_NO_VALUE) - { - backgroundNumber = play.bg_frame; - } + if (backgroundNumber == SCR_NO_VALUE) { + backgroundNumber = play.bg_frame; + } - if ((backgroundNumber < 0) || ((size_t)backgroundNumber >= thisroom.BgFrameCount)) - quit("!Room.GetDrawingSurfaceForBackground: invalid background number specified"); + if ((backgroundNumber < 0) || ((size_t)backgroundNumber >= thisroom.BgFrameCount)) + quit("!Room.GetDrawingSurfaceForBackground: invalid background number specified"); - ScriptDrawingSurface *surface = new ScriptDrawingSurface(); - surface->roomBackgroundNumber = backgroundNumber; - ccRegisterManagedObject(surface, surface); - return surface; + ScriptDrawingSurface *surface = new ScriptDrawingSurface(); + surface->roomBackgroundNumber = backgroundNumber; + ccRegisterManagedObject(surface, surface); + return surface; } -ScriptDrawingSurface* Room_GetDrawingSurfaceForMask(RoomAreaMask mask) -{ - if (displayed_room < 0) - quit("!Room_GetDrawingSurfaceForMask: no room is currently loaded"); - ScriptDrawingSurface *surface = new ScriptDrawingSurface(); - surface->roomMaskType = mask; - ccRegisterManagedObject(surface, surface); - return surface; +ScriptDrawingSurface *Room_GetDrawingSurfaceForMask(RoomAreaMask mask) { + if (displayed_room < 0) + quit("!Room_GetDrawingSurfaceForMask: no room is currently loaded"); + ScriptDrawingSurface *surface = new ScriptDrawingSurface(); + surface->roomMaskType = mask; + ccRegisterManagedObject(surface, surface); + return surface; } int Room_GetObjectCount() { - return croom->numobj; + return croom->numobj; } int Room_GetWidth() { - return thisroom.Width; + return thisroom.Width; } int Room_GetHeight() { - return thisroom.Height; + return thisroom.Height; } int Room_GetColorDepth() { - return thisroom.BgFrames[0].Graphic->GetColorDepth(); + return thisroom.BgFrames[0].Graphic->GetColorDepth(); } int Room_GetLeftEdge() { - return thisroom.Edges.Left; + return thisroom.Edges.Left; } int Room_GetRightEdge() { - return thisroom.Edges.Right; + return thisroom.Edges.Right; } int Room_GetTopEdge() { - return thisroom.Edges.Top; + return thisroom.Edges.Top; } int Room_GetBottomEdge() { - return thisroom.Edges.Bottom; + return thisroom.Edges.Bottom; } int Room_GetMusicOnLoad() { - return thisroom.Options.StartupMusic; + return thisroom.Options.StartupMusic; } -int Room_GetProperty(const char *property) -{ - return get_int_property(thisroom.Properties, croom->roomProps, property); +int Room_GetProperty(const char *property) { + return get_int_property(thisroom.Properties, croom->roomProps, property); } -const char* Room_GetTextProperty(const char *property) -{ - return get_text_property_dynamic_string(thisroom.Properties, croom->roomProps, property); +const char *Room_GetTextProperty(const char *property) { + return get_text_property_dynamic_string(thisroom.Properties, croom->roomProps, property); } -bool Room_SetProperty(const char *property, int value) -{ - return set_int_property(croom->roomProps, property, value); +bool Room_SetProperty(const char *property, int value) { + return set_int_property(croom->roomProps, property, value); } -bool Room_SetTextProperty(const char *property, const char *value) -{ - return set_text_property(croom->roomProps, property, value); +bool Room_SetTextProperty(const char *property, const char *value) { + return set_text_property(croom->roomProps, property, value); } -const char* Room_GetMessages(int index) { - if ((index < 0) || ((size_t)index >= thisroom.MessageCount)) { - return nullptr; - } - char buffer[STD_BUFFER_SIZE]; - buffer[0]=0; - replace_tokens(get_translation(thisroom.Messages[index]), buffer, STD_BUFFER_SIZE); - return CreateNewScriptString(buffer); +const char *Room_GetMessages(int index) { + if ((index < 0) || ((size_t)index >= thisroom.MessageCount)) { + return nullptr; + } + char buffer[STD_BUFFER_SIZE]; + buffer[0] = 0; + replace_tokens(get_translation(thisroom.Messages[index]), buffer, STD_BUFFER_SIZE); + return CreateNewScriptString(buffer); } @@ -228,885 +221,877 @@ const char* Room_GetMessages(int index) { // Makes sure that room background and walk-behind mask are matching room size // in game resolution coordinates; in other words makes graphics appropriate // for display in the game. -void convert_room_background_to_game_res() -{ - if (!game.AllowRelativeRes() || !thisroom.IsRelativeRes()) - return; +void convert_room_background_to_game_res() { + if (!game.AllowRelativeRes() || !thisroom.IsRelativeRes()) + return; - int bkg_width = thisroom.Width; - int bkg_height = thisroom.Height; - data_to_game_coords(&bkg_width, &bkg_height); + int bkg_width = thisroom.Width; + int bkg_height = thisroom.Height; + data_to_game_coords(&bkg_width, &bkg_height); - for (size_t i = 0; i < thisroom.BgFrameCount; ++i) - thisroom.BgFrames[i].Graphic = FixBitmap(thisroom.BgFrames[i].Graphic, bkg_width, bkg_height); + for (size_t i = 0; i < thisroom.BgFrameCount; ++i) + thisroom.BgFrames[i].Graphic = FixBitmap(thisroom.BgFrames[i].Graphic, bkg_width, bkg_height); - // Fix walk-behinds to match room background - // TODO: would not we need to do similar to each mask if they were 1:1 in hires room? - thisroom.WalkBehindMask = FixBitmap(thisroom.WalkBehindMask, bkg_width, bkg_height); + // Fix walk-behinds to match room background + // TODO: would not we need to do similar to each mask if they were 1:1 in hires room? + thisroom.WalkBehindMask = FixBitmap(thisroom.WalkBehindMask, bkg_width, bkg_height); } -void save_room_data_segment () { - croom->FreeScriptData(); - - croom->tsdatasize = roominst->globaldatasize; - if (croom->tsdatasize > 0) { - croom->tsdata=(char*)malloc(croom->tsdatasize+10); - memcpy(croom->tsdata,&roominst->globaldata[0],croom->tsdatasize); - } +void save_room_data_segment() { + croom->FreeScriptData(); + + croom->tsdatasize = roominst->globaldatasize; + if (croom->tsdatasize > 0) { + croom->tsdata = (char *)malloc(croom->tsdatasize + 10); + memcpy(croom->tsdata, &roominst->globaldata[0], croom->tsdatasize); + } } void unload_old_room() { - int ff; - - // if switching games on restore, don't do this - if (displayed_room < 0) - return; - - debug_script_log("Unloading room %d", displayed_room); - - current_fade_out_effect(); - - dispose_room_drawdata(); - - for (ff=0;ffnumobj;ff++) - objs[ff].moving = 0; - - if (!play.ambient_sounds_persist) { - for (ff = 1; ff < MAX_SOUND_CHANNELS; ff++) - StopAmbientSound(ff); - } - - cancel_all_scripts(); - numevents = 0; // cancel any pending room events - - if (roomBackgroundBmp != nullptr) - { - gfxDriver->DestroyDDB(roomBackgroundBmp); - roomBackgroundBmp = nullptr; - } - - if (croom==nullptr) ; - else if (roominst!=nullptr) { - save_room_data_segment(); - delete roominstFork; - delete roominst; - roominstFork = nullptr; - roominst=nullptr; - } - else croom->tsdatasize=0; - memset(&play.walkable_areas_on[0],1,MAX_WALK_AREAS+1); - play.bg_frame=0; - play.bg_frame_locked=0; - remove_screen_overlay(-1); - delete raw_saved_screen; - raw_saved_screen = nullptr; - for (ff = 0; ff < MAX_ROOM_BGFRAMES; ff++) - play.raw_modified[ff] = 0; - for (size_t i = 0; i < thisroom.LocalVariables.size() && i < MAX_GLOBAL_VARIABLES; ++i) - croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value; - - // wipe the character cache when we change rooms - for (ff = 0; ff < game.numcharacters; ff++) { - if (charcache[ff].inUse) { - delete charcache[ff].image; - charcache[ff].image = nullptr; - charcache[ff].inUse = 0; - } - // ensure that any half-moves (eg. with scaled movement) are stopped - charextra[ff].xwas = INVALID_X; - } - - play.swap_portrait_lastchar = -1; - play.swap_portrait_lastlastchar = -1; - - for (ff = 0; ff < croom->numobj; ff++) { - // un-export the object's script object - if (objectScriptObjNames[ff].IsEmpty()) - continue; - - ccRemoveExternalSymbol(objectScriptObjNames[ff]); - } - - for (ff = 0; ff < MAX_ROOM_HOTSPOTS; ff++) { - if (thisroom.Hotspots[ff].ScriptName.IsEmpty()) - continue; - - ccRemoveExternalSymbol(thisroom.Hotspots[ff].ScriptName); - } - - croom_ptr_clear(); - - // clear the object cache - for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) { - delete objcache[ff].image; - objcache[ff].image = nullptr; - } - // clear the actsps buffers to save memory, since the - // objects/characters involved probably aren't on the - // new screen. this also ensures all cached data is flushed - for (ff = 0; ff < MAX_ROOM_OBJECTS + game.numcharacters; ff++) { - delete actsps[ff]; - actsps[ff] = nullptr; - - if (actspsbmp[ff] != nullptr) - gfxDriver->DestroyDDB(actspsbmp[ff]); - actspsbmp[ff] = nullptr; - - delete actspswb[ff]; - actspswb[ff] = nullptr; - - if (actspswbbmp[ff] != nullptr) - gfxDriver->DestroyDDB(actspswbbmp[ff]); - actspswbbmp[ff] = nullptr; - - actspswbcache[ff].valid = 0; - } - - // if Hide Player Character was ticked, restore it to visible - if (play.temporarily_turned_off_character >= 0) { - game.chars[play.temporarily_turned_off_character].on = 1; - play.temporarily_turned_off_character = -1; - } + int ff; + + // if switching games on restore, don't do this + if (displayed_room < 0) + return; + + debug_script_log("Unloading room %d", displayed_room); + + current_fade_out_effect(); + + dispose_room_drawdata(); + + for (ff = 0; ff < croom->numobj; ff++) + objs[ff].moving = 0; + + if (!play.ambient_sounds_persist) { + for (ff = 1; ff < MAX_SOUND_CHANNELS; ff++) + StopAmbientSound(ff); + } + + cancel_all_scripts(); + numevents = 0; // cancel any pending room events + + if (roomBackgroundBmp != nullptr) { + gfxDriver->DestroyDDB(roomBackgroundBmp); + roomBackgroundBmp = nullptr; + } + + if (croom == nullptr) ; + else if (roominst != nullptr) { + save_room_data_segment(); + delete roominstFork; + delete roominst; + roominstFork = nullptr; + roominst = nullptr; + } else croom->tsdatasize = 0; + memset(&play.walkable_areas_on[0], 1, MAX_WALK_AREAS + 1); + play.bg_frame = 0; + play.bg_frame_locked = 0; + remove_screen_overlay(-1); + delete raw_saved_screen; + raw_saved_screen = nullptr; + for (ff = 0; ff < MAX_ROOM_BGFRAMES; ff++) + play.raw_modified[ff] = 0; + for (size_t i = 0; i < thisroom.LocalVariables.size() && i < MAX_GLOBAL_VARIABLES; ++i) + croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value; + + // wipe the character cache when we change rooms + for (ff = 0; ff < game.numcharacters; ff++) { + if (charcache[ff].inUse) { + delete charcache[ff].image; + charcache[ff].image = nullptr; + charcache[ff].inUse = 0; + } + // ensure that any half-moves (eg. with scaled movement) are stopped + charextra[ff].xwas = INVALID_X; + } + + play.swap_portrait_lastchar = -1; + play.swap_portrait_lastlastchar = -1; + + for (ff = 0; ff < croom->numobj; ff++) { + // un-export the object's script object + if (objectScriptObjNames[ff].IsEmpty()) + continue; + + ccRemoveExternalSymbol(objectScriptObjNames[ff]); + } + + for (ff = 0; ff < MAX_ROOM_HOTSPOTS; ff++) { + if (thisroom.Hotspots[ff].ScriptName.IsEmpty()) + continue; + + ccRemoveExternalSymbol(thisroom.Hotspots[ff].ScriptName); + } + + croom_ptr_clear(); + + // clear the object cache + for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) { + delete objcache[ff].image; + objcache[ff].image = nullptr; + } + // clear the actsps buffers to save memory, since the + // objects/characters involved probably aren't on the + // new screen. this also ensures all cached data is flushed + for (ff = 0; ff < MAX_ROOM_OBJECTS + game.numcharacters; ff++) { + delete actsps[ff]; + actsps[ff] = nullptr; + + if (actspsbmp[ff] != nullptr) + gfxDriver->DestroyDDB(actspsbmp[ff]); + actspsbmp[ff] = nullptr; + + delete actspswb[ff]; + actspswb[ff] = nullptr; + + if (actspswbbmp[ff] != nullptr) + gfxDriver->DestroyDDB(actspswbbmp[ff]); + actspswbbmp[ff] = nullptr; + + actspswbcache[ff].valid = 0; + } + + // if Hide Player Character was ticked, restore it to visible + if (play.temporarily_turned_off_character >= 0) { + game.chars[play.temporarily_turned_off_character].on = 1; + play.temporarily_turned_off_character = -1; + } } // Convert all room objects to the data resolution (only if it's different from game resolution). // TODO: merge this into UpdateRoomData? or this is required for engine only? -void convert_room_coordinates_to_data_res(RoomStruct *rstruc) -{ - if (game.GetDataUpscaleMult() == 1) - return; - - const int mul = game.GetDataUpscaleMult(); - for (size_t i = 0; i < rstruc->ObjectCount; ++i) - { - rstruc->Objects[i].X /= mul; - rstruc->Objects[i].Y /= mul; - if (rstruc->Objects[i].Baseline > 0) - { - rstruc->Objects[i].Baseline /= mul; - } - } - - for (size_t i = 0; i < rstruc->HotspotCount; ++i) - { - rstruc->Hotspots[i].WalkTo.X /= mul; - rstruc->Hotspots[i].WalkTo.Y /= mul; - } - - for (size_t i = 0; i < rstruc->WalkBehindCount; ++i) - { - rstruc->WalkBehinds[i].Baseline /= mul; - } - - rstruc->Edges.Left /= mul; - rstruc->Edges.Top /= mul; - rstruc->Edges.Bottom /= mul; - rstruc->Edges.Right /= mul; - rstruc->Width /= mul; - rstruc->Height /= mul; +void convert_room_coordinates_to_data_res(RoomStruct *rstruc) { + if (game.GetDataUpscaleMult() == 1) + return; + + const int mul = game.GetDataUpscaleMult(); + for (size_t i = 0; i < rstruc->ObjectCount; ++i) { + rstruc->Objects[i].X /= mul; + rstruc->Objects[i].Y /= mul; + if (rstruc->Objects[i].Baseline > 0) { + rstruc->Objects[i].Baseline /= mul; + } + } + + for (size_t i = 0; i < rstruc->HotspotCount; ++i) { + rstruc->Hotspots[i].WalkTo.X /= mul; + rstruc->Hotspots[i].WalkTo.Y /= mul; + } + + for (size_t i = 0; i < rstruc->WalkBehindCount; ++i) { + rstruc->WalkBehinds[i].Baseline /= mul; + } + + rstruc->Edges.Left /= mul; + rstruc->Edges.Top /= mul; + rstruc->Edges.Bottom /= mul; + rstruc->Edges.Right /= mul; + rstruc->Width /= mul; + rstruc->Height /= mul; } extern int convert_16bit_bgr; -void update_letterbox_mode() -{ - const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); - const Rect game_frame = RectWH(game.GetGameRes()); - Rect new_main_view = game_frame; - // In the original engine the letterbox feature only allowed viewports of - // either 200 or 240 (400 and 480) pixels, if the room height was equal or greater than 200 (400). - // Also, the UI viewport should be matching room viewport in that case. - // NOTE: if "OPT_LETTERBOX" is false, altsize.Height = size.Height always. - const int viewport_height = - real_room_sz.Height < game.GetLetterboxSize().Height ? real_room_sz.Height : - (real_room_sz.Height >= game.GetLetterboxSize().Height && real_room_sz.Height < game.GetGameRes().Height) ? game.GetLetterboxSize().Height : - game.GetGameRes().Height; - new_main_view.SetHeight(viewport_height); - - play.SetMainViewport(CenterInRect(game_frame, new_main_view)); - play.SetUIViewport(new_main_view); +void update_letterbox_mode() { + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + const Rect game_frame = RectWH(game.GetGameRes()); + Rect new_main_view = game_frame; + // In the original engine the letterbox feature only allowed viewports of + // either 200 or 240 (400 and 480) pixels, if the room height was equal or greater than 200 (400). + // Also, the UI viewport should be matching room viewport in that case. + // NOTE: if "OPT_LETTERBOX" is false, altsize.Height = size.Height always. + const int viewport_height = + real_room_sz.Height < game.GetLetterboxSize().Height ? real_room_sz.Height : + (real_room_sz.Height >= game.GetLetterboxSize().Height && real_room_sz.Height < game.GetGameRes().Height) ? game.GetLetterboxSize().Height : + game.GetGameRes().Height; + new_main_view.SetHeight(viewport_height); + + play.SetMainViewport(CenterInRect(game_frame, new_main_view)); + play.SetUIViewport(new_main_view); } // Automatically reset primary room viewport and camera to match the new room size -static void adjust_viewport_to_room() -{ - const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); - const Rect main_view = play.GetMainViewport(); - Rect new_room_view = RectWH(Size::Clamp(real_room_sz, Size(1, 1), main_view.GetSize())); - - auto view = play.GetRoomViewport(0); - view->SetRect(new_room_view); - auto cam = view->GetCamera(); - if (cam) - { - cam->SetSize(new_room_view.GetSize()); - cam->SetAt(0, 0); - cam->Release(); - } +static void adjust_viewport_to_room() { + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + const Rect main_view = play.GetMainViewport(); + Rect new_room_view = RectWH(Size::Clamp(real_room_sz, Size(1, 1), main_view.GetSize())); + + auto view = play.GetRoomViewport(0); + view->SetRect(new_room_view); + auto cam = view->GetCamera(); + if (cam) { + cam->SetSize(new_room_view.GetSize()); + cam->SetAt(0, 0); + cam->Release(); + } } // Run through all viewports and cameras to make sure they can work in new room's bounds -static void update_all_viewcams_with_newroom() -{ - for (int i = 0; i < play.GetRoomCameraCount(); ++i) - { - auto cam = play.GetRoomCamera(i); - const Rect old_pos = cam->GetRect(); - cam->SetSize(old_pos.GetSize()); - cam->SetAt(old_pos.Left, old_pos.Top); - } +static void update_all_viewcams_with_newroom() { + for (int i = 0; i < play.GetRoomCameraCount(); ++i) { + auto cam = play.GetRoomCamera(i); + const Rect old_pos = cam->GetRect(); + cam->SetSize(old_pos.GetSize()); + cam->SetAt(old_pos.Left, old_pos.Top); + } } // forchar = playerchar on NewRoom, or NULL if restore saved game -void load_new_room(int newnum, CharacterInfo*forchar) { - - debug_script_log("Loading room %d", newnum); - - String room_filename; - int cc; - done_es_error = 0; - play.room_changes ++; - // TODO: find out why do we need to temporarily lower color depth to 8-bit. - // Or do we? There's a serious usability problem in this: if any bitmap is - // created meanwhile it will have this color depth by default, which may - // lead to unexpected errors. - set_color_depth(8); - displayed_room=newnum; - - room_filename.Format("room%d.crm", newnum); - if (newnum == 0) { - // support both room0.crm and intro.crm - // 2.70: Renamed intro.crm to room0.crm, to stop it causing confusion - if ((loaded_game_file_version < kGameVersion_270 && Common::AssetManager::DoesAssetExist("intro.crm")) || - (loaded_game_file_version >= kGameVersion_270 && !Common::AssetManager::DoesAssetExist(room_filename))) - { - room_filename = "intro.crm"; - } - } - - update_polled_stuff_if_runtime(); - - // load the room from disk - our_eip=200; - thisroom.GameID = NO_GAME_ID_IN_ROOM_FILE; - load_room(room_filename, &thisroom, game.IsLegacyHiRes(), game.SpriteInfos); - - if ((thisroom.GameID != NO_GAME_ID_IN_ROOM_FILE) && - (thisroom.GameID != game.uniqueid)) { - quitprintf("!Unable to load '%s'. This room file is assigned to a different game.", room_filename.GetCStr()); - } - - convert_room_coordinates_to_data_res(&thisroom); - - update_polled_stuff_if_runtime(); - our_eip=201; - /* // apparently, doing this stops volume spiking between tracks - if (thisroom.Options.StartupMusic>0) { - stopmusic(); - delay(100); - }*/ - - play.room_width = thisroom.Width; - play.room_height = thisroom.Height; - play.anim_background_speed = thisroom.BgAnimSpeed; - play.bg_anim_delay = play.anim_background_speed; - - // do the palette - for (cc=0;cc<256;cc++) { - if (game.paluses[cc]==PAL_BACKGROUND) - palette[cc]=thisroom.Palette[cc]; - else { - // copy the gamewide colours into the room palette - for (size_t i = 0; i < thisroom.BgFrameCount; ++i) - thisroom.BgFrames[i].Palette[cc] = palette[cc]; - } - } - - for (size_t i = 0; i < thisroom.BgFrameCount; ++i) { - update_polled_stuff_if_runtime(); - thisroom.BgFrames[i].Graphic = PrepareSpriteForUse(thisroom.BgFrames[i].Graphic, false); - } - - update_polled_stuff_if_runtime(); - - our_eip=202; - // Update game viewports - if (game.IsLegacyLetterbox()) - update_letterbox_mode(); - SetMouseBounds(0, 0, 0, 0); - - our_eip=203; - in_new_room=1; - - // walkable_areas_temp is used by the pathfinder to generate a - // copy of the walkable areas - allocate it here to save time later - delete walkable_areas_temp; - walkable_areas_temp = BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight(), 8); - - // Make a backup copy of the walkable areas prior to - // any RemoveWalkableArea commands - delete walkareabackup; - // copy the walls screen - walkareabackup=BitmapHelper::CreateBitmapCopy(thisroom.WalkAreaMask.get()); - - our_eip=204; - update_polled_stuff_if_runtime(); - redo_walkable_areas(); - update_polled_stuff_if_runtime(); - - set_color_depth(game.GetColorDepth()); - convert_room_background_to_game_res(); - recache_walk_behinds(); - update_polled_stuff_if_runtime(); - - our_eip=205; - // setup objects - if (forchar != nullptr) { - // if not restoring a game, always reset this room - troom.beenhere=0; - troom.FreeScriptData(); - troom.FreeProperties(); - memset(&troom.hotspot_enabled[0],1,MAX_ROOM_HOTSPOTS); - memset(&troom.region_enabled[0], 1, MAX_ROOM_REGIONS); - } - if ((newnum>=0) & (newnumbeenhere > 0) { - // if we've been here before, save the Times Run information - // since we will overwrite the actual NewInteraction structs - // (cos they have pointers and this might have been loaded from - // a save game) - if (thisroom.EventHandlers == nullptr) - {// legacy interactions - thisroom.Interaction->CopyTimesRun(croom->intrRoom); - for (cc=0;cc < MAX_ROOM_HOTSPOTS;cc++) - thisroom.Hotspots[cc].Interaction->CopyTimesRun(croom->intrHotspot[cc]); - for (cc=0;cc < MAX_ROOM_OBJECTS;cc++) - thisroom.Objects[cc].Interaction->CopyTimesRun(croom->intrObject[cc]); - for (cc=0;cc < MAX_ROOM_REGIONS;cc++) - thisroom.Regions[cc].Interaction->CopyTimesRun(croom->intrRegion[cc]); - } - } - if (croom->beenhere==0) { - croom->numobj=thisroom.ObjectCount; - croom->tsdatasize=0; - for (cc=0;ccnumobj;cc++) { - croom->obj[cc].x=thisroom.Objects[cc].X; - croom->obj[cc].y=thisroom.Objects[cc].Y; - croom->obj[cc].num=thisroom.Objects[cc].Sprite; - croom->obj[cc].on=thisroom.Objects[cc].IsOn; - croom->obj[cc].view=-1; - croom->obj[cc].loop=0; - croom->obj[cc].frame=0; - croom->obj[cc].wait=0; - croom->obj[cc].transparent=0; - croom->obj[cc].moving=-1; - croom->obj[cc].flags = thisroom.Objects[cc].Flags; - croom->obj[cc].baseline=-1; - croom->obj[cc].zoom = 100; - croom->obj[cc].last_width = 0; - croom->obj[cc].last_height = 0; - croom->obj[cc].blocking_width = 0; - croom->obj[cc].blocking_height = 0; - if (thisroom.Objects[cc].Baseline>=0) - // croom->obj[cc].baseoffs=thisroom.Objects.Baseline[cc]-thisroom.Objects[cc].y; - croom->obj[cc].baseline=thisroom.Objects[cc].Baseline; - } - for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i) - croom->walkbehind_base[i] = thisroom.WalkBehinds[i].Baseline; - for (cc=0;ccflagstates[cc]=0; - - /* // we copy these structs for the Score column to work - croom->misccond=thisroom.misccond; - for (cc=0;cchscond[cc]=thisroom.hscond[cc]; - for (cc=0;ccobjcond[cc]=thisroom.objcond[cc];*/ - - for (cc=0;cc < MAX_ROOM_HOTSPOTS;cc++) { - croom->hotspot_enabled[cc] = 1; - } - for (cc = 0; cc < MAX_ROOM_REGIONS; cc++) { - croom->region_enabled[cc] = 1; - } - - croom->beenhere=1; - in_new_room=2; - } - else { - // We have been here before - for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i) - thisroom.LocalVariables[i].Value = croom->interactionVariableValues[i]; - } - - update_polled_stuff_if_runtime(); - - if (thisroom.EventHandlers == nullptr) - {// legacy interactions - // copy interactions from room file into our temporary struct - croom->intrRoom = *thisroom.Interaction; - for (cc=0;ccintrHotspot[cc] = *thisroom.Hotspots[cc].Interaction; - for (cc=0;ccintrObject[cc] = *thisroom.Objects[cc].Interaction; - for (cc=0;ccintrRegion[cc] = *thisroom.Regions[cc].Interaction; - } - - objs=&croom->obj[0]; - - for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++) { - // 64 bit: Using the id instead - // scrObj[cc].obj = &croom->obj[cc]; - objectScriptObjNames[cc].Free(); - } - - for (cc = 0; cc < croom->numobj; cc++) { - // export the object's script object - if (thisroom.Objects[cc].ScriptName.IsEmpty()) - continue; - objectScriptObjNames[cc] = thisroom.Objects[cc].ScriptName; - ccAddExternalDynamicObject(objectScriptObjNames[cc], &scrObj[cc], &ccDynamicObject); - } - - for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) { - if (thisroom.Hotspots[cc].ScriptName.IsEmpty()) - continue; - - ccAddExternalDynamicObject(thisroom.Hotspots[cc].ScriptName, &scrHotspot[cc], &ccDynamicHotspot); - } - - our_eip=206; - /* THIS IS DONE IN THE EDITOR NOW - thisroom.BgFrames.IsPaletteShared[0] = 1; - for (dd = 1; dd < thisroom.BgFrameCount; dd++) { - if (memcmp (&thisroom.BgFrames.Palette[dd][0], &palette[0], sizeof(color) * 256) == 0) - thisroom.BgFrames.IsPaletteShared[dd] = 1; - else - thisroom.BgFrames.IsPaletteShared[dd] = 0; - } - // only make the first frame shared if the last is - if (thisroom.BgFrames.IsPaletteShared[thisroom.BgFrameCount - 1] == 0) - thisroom.BgFrames.IsPaletteShared[0] = 0;*/ - - update_polled_stuff_if_runtime(); - - our_eip = 210; - if (IS_ANTIALIAS_SPRITES) { - // sometimes the palette has corrupt entries, which crash - // the create_rgb_table call - // so, fix them - for (int ff = 0; ff < 256; ff++) { - if (palette[ff].r > 63) - palette[ff].r = 63; - if (palette[ff].g > 63) - palette[ff].g = 63; - if (palette[ff].b > 63) - palette[ff].b = 63; - } - create_rgb_table (&rgb_table, palette, nullptr); - rgb_map = &rgb_table; - } - our_eip = 211; - if (forchar!=nullptr) { - // if it's not a Restore Game - - // if a following character is still waiting to come into the - // previous room, force it out so that the timer resets - for (int ff = 0; ff < game.numcharacters; ff++) { - if ((game.chars[ff].following >= 0) && (game.chars[ff].room < 0)) { - if ((game.chars[ff].following == game.playercharacter) && - (forchar->prevroom == newnum)) - // the player went back to the previous room, so make sure - // the following character is still there - game.chars[ff].room = newnum; - else - game.chars[ff].room = game.chars[game.chars[ff].following].room; - } - } - - forchar->prevroom=forchar->room; - forchar->room=newnum; - // only stop moving if it's a new room, not a restore game - for (cc=0;cctsdatasize>0) { - if (croom->tsdatasize != roominst->globaldatasize) - quit("room script data segment size has changed"); - memcpy(&roominst->globaldata[0],croom->tsdata,croom->tsdatasize); - } - } - our_eip=207; - play.entered_edge = -1; - - if ((new_room_x != SCR_NO_VALUE) && (forchar != nullptr)) - { - forchar->x = new_room_x; - forchar->y = new_room_y; +void load_new_room(int newnum, CharacterInfo *forchar) { + + debug_script_log("Loading room %d", newnum); + + String room_filename; + int cc; + done_es_error = 0; + play.room_changes ++; + // TODO: find out why do we need to temporarily lower color depth to 8-bit. + // Or do we? There's a serious usability problem in this: if any bitmap is + // created meanwhile it will have this color depth by default, which may + // lead to unexpected errors. + set_color_depth(8); + displayed_room = newnum; + + room_filename.Format("room%d.crm", newnum); + if (newnum == 0) { + // support both room0.crm and intro.crm + // 2.70: Renamed intro.crm to room0.crm, to stop it causing confusion + if ((loaded_game_file_version < kGameVersion_270 && Common::AssetManager::DoesAssetExist("intro.crm")) || + (loaded_game_file_version >= kGameVersion_270 && !Common::AssetManager::DoesAssetExist(room_filename))) { + room_filename = "intro.crm"; + } + } + + update_polled_stuff_if_runtime(); + + // load the room from disk + our_eip = 200; + thisroom.GameID = NO_GAME_ID_IN_ROOM_FILE; + load_room(room_filename, &thisroom, game.IsLegacyHiRes(), game.SpriteInfos); + + if ((thisroom.GameID != NO_GAME_ID_IN_ROOM_FILE) && + (thisroom.GameID != game.uniqueid)) { + quitprintf("!Unable to load '%s'. This room file is assigned to a different game.", room_filename.GetCStr()); + } + + convert_room_coordinates_to_data_res(&thisroom); + + update_polled_stuff_if_runtime(); + our_eip = 201; + /* // apparently, doing this stops volume spiking between tracks + if (thisroom.Options.StartupMusic>0) { + stopmusic(); + delay(100); + }*/ + + play.room_width = thisroom.Width; + play.room_height = thisroom.Height; + play.anim_background_speed = thisroom.BgAnimSpeed; + play.bg_anim_delay = play.anim_background_speed; + + // do the palette + for (cc = 0; cc < 256; cc++) { + if (game.paluses[cc] == PAL_BACKGROUND) + palette[cc] = thisroom.Palette[cc]; + else { + // copy the gamewide colours into the room palette + for (size_t i = 0; i < thisroom.BgFrameCount; ++i) + thisroom.BgFrames[i].Palette[cc] = palette[cc]; + } + } + + for (size_t i = 0; i < thisroom.BgFrameCount; ++i) { + update_polled_stuff_if_runtime(); + thisroom.BgFrames[i].Graphic = PrepareSpriteForUse(thisroom.BgFrames[i].Graphic, false); + } + + update_polled_stuff_if_runtime(); + + our_eip = 202; + // Update game viewports + if (game.IsLegacyLetterbox()) + update_letterbox_mode(); + SetMouseBounds(0, 0, 0, 0); + + our_eip = 203; + in_new_room = 1; + + // walkable_areas_temp is used by the pathfinder to generate a + // copy of the walkable areas - allocate it here to save time later + delete walkable_areas_temp; + walkable_areas_temp = BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight(), 8); + + // Make a backup copy of the walkable areas prior to + // any RemoveWalkableArea commands + delete walkareabackup; + // copy the walls screen + walkareabackup = BitmapHelper::CreateBitmapCopy(thisroom.WalkAreaMask.get()); + + our_eip = 204; + update_polled_stuff_if_runtime(); + redo_walkable_areas(); + update_polled_stuff_if_runtime(); + + set_color_depth(game.GetColorDepth()); + convert_room_background_to_game_res(); + recache_walk_behinds(); + update_polled_stuff_if_runtime(); + + our_eip = 205; + // setup objects + if (forchar != nullptr) { + // if not restoring a game, always reset this room + troom.beenhere = 0; + troom.FreeScriptData(); + troom.FreeProperties(); + memset(&troom.hotspot_enabled[0], 1, MAX_ROOM_HOTSPOTS); + memset(&troom.region_enabled[0], 1, MAX_ROOM_REGIONS); + } + if ((newnum >= 0) & (newnum < MAX_ROOMS)) + croom = getRoomStatus(newnum); + else croom = &troom; + + if (croom->beenhere > 0) { + // if we've been here before, save the Times Run information + // since we will overwrite the actual NewInteraction structs + // (cos they have pointers and this might have been loaded from + // a save game) + if (thisroom.EventHandlers == nullptr) { + // legacy interactions + thisroom.Interaction->CopyTimesRun(croom->intrRoom); + for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) + thisroom.Hotspots[cc].Interaction->CopyTimesRun(croom->intrHotspot[cc]); + for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++) + thisroom.Objects[cc].Interaction->CopyTimesRun(croom->intrObject[cc]); + for (cc = 0; cc < MAX_ROOM_REGIONS; cc++) + thisroom.Regions[cc].Interaction->CopyTimesRun(croom->intrRegion[cc]); + } + } + if (croom->beenhere == 0) { + croom->numobj = thisroom.ObjectCount; + croom->tsdatasize = 0; + for (cc = 0; cc < croom->numobj; cc++) { + croom->obj[cc].x = thisroom.Objects[cc].X; + croom->obj[cc].y = thisroom.Objects[cc].Y; + croom->obj[cc].num = thisroom.Objects[cc].Sprite; + croom->obj[cc].on = thisroom.Objects[cc].IsOn; + croom->obj[cc].view = -1; + croom->obj[cc].loop = 0; + croom->obj[cc].frame = 0; + croom->obj[cc].wait = 0; + croom->obj[cc].transparent = 0; + croom->obj[cc].moving = -1; + croom->obj[cc].flags = thisroom.Objects[cc].Flags; + croom->obj[cc].baseline = -1; + croom->obj[cc].zoom = 100; + croom->obj[cc].last_width = 0; + croom->obj[cc].last_height = 0; + croom->obj[cc].blocking_width = 0; + croom->obj[cc].blocking_height = 0; + if (thisroom.Objects[cc].Baseline >= 0) + // croom->obj[cc].baseoffs=thisroom.Objects.Baseline[cc]-thisroom.Objects[cc].y; + croom->obj[cc].baseline = thisroom.Objects[cc].Baseline; + } + for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i) + croom->walkbehind_base[i] = thisroom.WalkBehinds[i].Baseline; + for (cc = 0; cc < MAX_FLAGS; cc++) croom->flagstates[cc] = 0; + + /* // we copy these structs for the Score column to work + croom->misccond=thisroom.misccond; + for (cc=0;cchscond[cc]=thisroom.hscond[cc]; + for (cc=0;ccobjcond[cc]=thisroom.objcond[cc];*/ + + for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) { + croom->hotspot_enabled[cc] = 1; + } + for (cc = 0; cc < MAX_ROOM_REGIONS; cc++) { + croom->region_enabled[cc] = 1; + } + + croom->beenhere = 1; + in_new_room = 2; + } else { + // We have been here before + for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i) + thisroom.LocalVariables[i].Value = croom->interactionVariableValues[i]; + } + + update_polled_stuff_if_runtime(); + + if (thisroom.EventHandlers == nullptr) { + // legacy interactions + // copy interactions from room file into our temporary struct + croom->intrRoom = *thisroom.Interaction; + for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) + croom->intrHotspot[cc] = *thisroom.Hotspots[cc].Interaction; + for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++) + croom->intrObject[cc] = *thisroom.Objects[cc].Interaction; + for (cc = 0; cc < MAX_ROOM_REGIONS; cc++) + croom->intrRegion[cc] = *thisroom.Regions[cc].Interaction; + } + + objs = &croom->obj[0]; + + for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++) { + // 64 bit: Using the id instead + // scrObj[cc].obj = &croom->obj[cc]; + objectScriptObjNames[cc].Free(); + } + + for (cc = 0; cc < croom->numobj; cc++) { + // export the object's script object + if (thisroom.Objects[cc].ScriptName.IsEmpty()) + continue; + objectScriptObjNames[cc] = thisroom.Objects[cc].ScriptName; + ccAddExternalDynamicObject(objectScriptObjNames[cc], &scrObj[cc], &ccDynamicObject); + } + + for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) { + if (thisroom.Hotspots[cc].ScriptName.IsEmpty()) + continue; + + ccAddExternalDynamicObject(thisroom.Hotspots[cc].ScriptName, &scrHotspot[cc], &ccDynamicHotspot); + } + + our_eip = 206; + /* THIS IS DONE IN THE EDITOR NOW + thisroom.BgFrames.IsPaletteShared[0] = 1; + for (dd = 1; dd < thisroom.BgFrameCount; dd++) { + if (memcmp (&thisroom.BgFrames.Palette[dd][0], &palette[0], sizeof(color) * 256) == 0) + thisroom.BgFrames.IsPaletteShared[dd] = 1; + else + thisroom.BgFrames.IsPaletteShared[dd] = 0; + } + // only make the first frame shared if the last is + if (thisroom.BgFrames.IsPaletteShared[thisroom.BgFrameCount - 1] == 0) + thisroom.BgFrames.IsPaletteShared[0] = 0;*/ + + update_polled_stuff_if_runtime(); + + our_eip = 210; + if (IS_ANTIALIAS_SPRITES) { + // sometimes the palette has corrupt entries, which crash + // the create_rgb_table call + // so, fix them + for (int ff = 0; ff < 256; ff++) { + if (palette[ff].r > 63) + palette[ff].r = 63; + if (palette[ff].g > 63) + palette[ff].g = 63; + if (palette[ff].b > 63) + palette[ff].b = 63; + } + create_rgb_table(&rgb_table, palette, nullptr); + rgb_map = &rgb_table; + } + our_eip = 211; + if (forchar != nullptr) { + // if it's not a Restore Game + + // if a following character is still waiting to come into the + // previous room, force it out so that the timer resets + for (int ff = 0; ff < game.numcharacters; ff++) { + if ((game.chars[ff].following >= 0) && (game.chars[ff].room < 0)) { + if ((game.chars[ff].following == game.playercharacter) && + (forchar->prevroom == newnum)) + // the player went back to the previous room, so make sure + // the following character is still there + game.chars[ff].room = newnum; + else + game.chars[ff].room = game.chars[game.chars[ff].following].room; + } + } + + forchar->prevroom = forchar->room; + forchar->room = newnum; + // only stop moving if it's a new room, not a restore game + for (cc = 0; cc < game.numcharacters; cc++) + StopMoving(cc); + + } + + update_polled_stuff_if_runtime(); + + roominst = nullptr; + if (debug_flags & DBG_NOSCRIPT) ; + else if (thisroom.CompiledScript != nullptr) { + compile_room_script(); + if (croom->tsdatasize > 0) { + if (croom->tsdatasize != roominst->globaldatasize) + quit("room script data segment size has changed"); + memcpy(&roominst->globaldata[0], croom->tsdata, croom->tsdatasize); + } + } + our_eip = 207; + play.entered_edge = -1; + + if ((new_room_x != SCR_NO_VALUE) && (forchar != nullptr)) { + forchar->x = new_room_x; + forchar->y = new_room_y; if (new_room_loop != SCR_NO_VALUE) forchar->loop = new_room_loop; - } - new_room_x = SCR_NO_VALUE; + } + new_room_x = SCR_NO_VALUE; new_room_loop = SCR_NO_VALUE; - if ((new_room_pos>0) & (forchar!=nullptr)) { - if (new_room_pos>=4000) { - play.entered_edge = 3; - forchar->y = thisroom.Edges.Top + get_fixed_pixel_size(1); - forchar->x=new_room_pos%1000; - if (forchar->x==0) forchar->x=thisroom.Width/2; - if (forchar->x <= thisroom.Edges.Left) - forchar->x = thisroom.Edges.Left + 3; - if (forchar->x >= thisroom.Edges.Right) - forchar->x = thisroom.Edges.Right - 3; - forchar->loop=0; - } - else if (new_room_pos>=3000) { - play.entered_edge = 2; - forchar->y = thisroom.Edges.Bottom - get_fixed_pixel_size(1); - forchar->x=new_room_pos%1000; - if (forchar->x==0) forchar->x=thisroom.Width/2; - if (forchar->x <= thisroom.Edges.Left) - forchar->x = thisroom.Edges.Left + 3; - if (forchar->x >= thisroom.Edges.Right) - forchar->x = thisroom.Edges.Right - 3; - forchar->loop=3; - } - else if (new_room_pos>=2000) { - play.entered_edge = 1; - forchar->x = thisroom.Edges.Right - get_fixed_pixel_size(1); - forchar->y=new_room_pos%1000; - if (forchar->y==0) forchar->y=thisroom.Height/2; - if (forchar->y <= thisroom.Edges.Top) - forchar->y = thisroom.Edges.Top + 3; - if (forchar->y >= thisroom.Edges.Bottom) - forchar->y = thisroom.Edges.Bottom - 3; - forchar->loop=1; - } - else if (new_room_pos>=1000) { - play.entered_edge = 0; - forchar->x = thisroom.Edges.Left + get_fixed_pixel_size(1); - forchar->y=new_room_pos%1000; - if (forchar->y==0) forchar->y=thisroom.Height/2; - if (forchar->y <= thisroom.Edges.Top) - forchar->y = thisroom.Edges.Top + 3; - if (forchar->y >= thisroom.Edges.Bottom) - forchar->y = thisroom.Edges.Bottom - 3; - forchar->loop=2; - } - // if starts on un-walkable area - if (get_walkable_area_pixel(forchar->x, forchar->y) == 0) { - if (new_room_pos>=3000) { // bottom or top of screen - int tryleft=forchar->x - 1,tryright=forchar->x + 1; - while (1) { - if (get_walkable_area_pixel(tryleft, forchar->y) > 0) { - forchar->x=tryleft; break; } - if (get_walkable_area_pixel(tryright, forchar->y) > 0) { - forchar->x=tryright; break; } - int nowhere=0; - if (tryleft>thisroom.Edges.Left) { tryleft--; nowhere++; } - if (tryright=1000) { // left or right - int tryleft=forchar->y - 1,tryright=forchar->y + 1; - while (1) { - if (get_walkable_area_pixel(forchar->x, tryleft) > 0) { - forchar->y=tryleft; break; } - if (get_walkable_area_pixel(forchar->x, tryright) > 0) { - forchar->y=tryright; break; } - int nowhere=0; - if (tryleft>thisroom.Edges.Top) { tryleft--; nowhere++; } - if (tryrightx; - play.entered_at_y=forchar->y; - if (forchar->x >= thisroom.Edges.Right) - play.entered_edge = 1; - else if (forchar->x <= thisroom.Edges.Left) - play.entered_edge = 0; - else if (forchar->y >= thisroom.Edges.Bottom) - play.entered_edge = 2; - else if (forchar->y <= thisroom.Edges.Top) - play.entered_edge = 3; - } - if (thisroom.Options.StartupMusic>0) - PlayMusicResetQueue(thisroom.Options.StartupMusic); - - our_eip=208; - if (forchar!=nullptr) { - if (thisroom.Options.PlayerCharOff==0) { forchar->on=1; - enable_cursor_mode(0); } - else { - forchar->on=0; - disable_cursor_mode(0); - // remember which character we turned off, in case they - // use SetPlyaerChracter within this room (so we re-enable - // the correct character when leaving the room) - play.temporarily_turned_off_character = game.playercharacter; - } - if (forchar->flags & CHF_FIXVIEW) ; - else if (thisroom.Options.PlayerView==0) forchar->view=forchar->defview; - else forchar->view=thisroom.Options.PlayerView-1; - forchar->frame=0; // make him standing - } - color_map = nullptr; - - our_eip = 209; - update_polled_stuff_if_runtime(); - generate_light_table(); - update_music_volume(); - - // If we are not restoring a save, update cameras to accomodate for this - // new room; otherwise this is done later when cameras are recreated. - if (forchar != nullptr) - { - if (play.IsAutoRoomViewport()) - adjust_viewport_to_room(); - update_all_viewcams_with_newroom(); - play.UpdateRoomCameras(); // update auto tracking - } - init_room_drawdata(); - - our_eip = 212; - invalidate_screen(); - for (cc=0;ccnumobj;cc++) { - if (objs[cc].on == 2) - MergeObject(cc); - } - new_room_flags=0; - play.gscript_timer=-1; // avoid screw-ups with changing screens - play.player_on_region = 0; - // trash any input which they might have done while it was loading - ags_clear_input_buffer(); - // no fade in, so set the palette immediately in case of 256-col sprites - if (game.color_depth > 1) - setpal(); - - our_eip=220; - update_polled_stuff_if_runtime(); - debug_script_log("Now in room %d", displayed_room); - guis_need_update = 1; - pl_run_plugin_hooks(AGSE_ENTERROOM, displayed_room); - // MoveToWalkableArea(game.playercharacter); - // MSS_CHECK_ALL_BLOCKS; + if ((new_room_pos > 0) & (forchar != nullptr)) { + if (new_room_pos >= 4000) { + play.entered_edge = 3; + forchar->y = thisroom.Edges.Top + get_fixed_pixel_size(1); + forchar->x = new_room_pos % 1000; + if (forchar->x == 0) forchar->x = thisroom.Width / 2; + if (forchar->x <= thisroom.Edges.Left) + forchar->x = thisroom.Edges.Left + 3; + if (forchar->x >= thisroom.Edges.Right) + forchar->x = thisroom.Edges.Right - 3; + forchar->loop = 0; + } else if (new_room_pos >= 3000) { + play.entered_edge = 2; + forchar->y = thisroom.Edges.Bottom - get_fixed_pixel_size(1); + forchar->x = new_room_pos % 1000; + if (forchar->x == 0) forchar->x = thisroom.Width / 2; + if (forchar->x <= thisroom.Edges.Left) + forchar->x = thisroom.Edges.Left + 3; + if (forchar->x >= thisroom.Edges.Right) + forchar->x = thisroom.Edges.Right - 3; + forchar->loop = 3; + } else if (new_room_pos >= 2000) { + play.entered_edge = 1; + forchar->x = thisroom.Edges.Right - get_fixed_pixel_size(1); + forchar->y = new_room_pos % 1000; + if (forchar->y == 0) forchar->y = thisroom.Height / 2; + if (forchar->y <= thisroom.Edges.Top) + forchar->y = thisroom.Edges.Top + 3; + if (forchar->y >= thisroom.Edges.Bottom) + forchar->y = thisroom.Edges.Bottom - 3; + forchar->loop = 1; + } else if (new_room_pos >= 1000) { + play.entered_edge = 0; + forchar->x = thisroom.Edges.Left + get_fixed_pixel_size(1); + forchar->y = new_room_pos % 1000; + if (forchar->y == 0) forchar->y = thisroom.Height / 2; + if (forchar->y <= thisroom.Edges.Top) + forchar->y = thisroom.Edges.Top + 3; + if (forchar->y >= thisroom.Edges.Bottom) + forchar->y = thisroom.Edges.Bottom - 3; + forchar->loop = 2; + } + // if starts on un-walkable area + if (get_walkable_area_pixel(forchar->x, forchar->y) == 0) { + if (new_room_pos >= 3000) { // bottom or top of screen + int tryleft = forchar->x - 1, tryright = forchar->x + 1; + while (1) { + if (get_walkable_area_pixel(tryleft, forchar->y) > 0) { + forchar->x = tryleft; + break; + } + if (get_walkable_area_pixel(tryright, forchar->y) > 0) { + forchar->x = tryright; + break; + } + int nowhere = 0; + if (tryleft > thisroom.Edges.Left) { + tryleft--; + nowhere++; + } + if (tryright < thisroom.Edges.Right) { + tryright++; + nowhere++; + } + if (nowhere == 0) break; // no place to go, so leave him + } + } else if (new_room_pos >= 1000) { // left or right + int tryleft = forchar->y - 1, tryright = forchar->y + 1; + while (1) { + if (get_walkable_area_pixel(forchar->x, tryleft) > 0) { + forchar->y = tryleft; + break; + } + if (get_walkable_area_pixel(forchar->x, tryright) > 0) { + forchar->y = tryright; + break; + } + int nowhere = 0; + if (tryleft > thisroom.Edges.Top) { + tryleft--; + nowhere++; + } + if (tryright < thisroom.Edges.Bottom) { + tryright++; + nowhere++; + } + if (nowhere == 0) break; // no place to go, so leave him + } + } + } + new_room_pos = 0; + } + if (forchar != nullptr) { + play.entered_at_x = forchar->x; + play.entered_at_y = forchar->y; + if (forchar->x >= thisroom.Edges.Right) + play.entered_edge = 1; + else if (forchar->x <= thisroom.Edges.Left) + play.entered_edge = 0; + else if (forchar->y >= thisroom.Edges.Bottom) + play.entered_edge = 2; + else if (forchar->y <= thisroom.Edges.Top) + play.entered_edge = 3; + } + if (thisroom.Options.StartupMusic > 0) + PlayMusicResetQueue(thisroom.Options.StartupMusic); + + our_eip = 208; + if (forchar != nullptr) { + if (thisroom.Options.PlayerCharOff == 0) { + forchar->on = 1; + enable_cursor_mode(0); + } else { + forchar->on = 0; + disable_cursor_mode(0); + // remember which character we turned off, in case they + // use SetPlyaerChracter within this room (so we re-enable + // the correct character when leaving the room) + play.temporarily_turned_off_character = game.playercharacter; + } + if (forchar->flags & CHF_FIXVIEW) ; + else if (thisroom.Options.PlayerView == 0) forchar->view = forchar->defview; + else forchar->view = thisroom.Options.PlayerView - 1; + forchar->frame = 0; // make him standing + } + color_map = nullptr; + + our_eip = 209; + update_polled_stuff_if_runtime(); + generate_light_table(); + update_music_volume(); + + // If we are not restoring a save, update cameras to accomodate for this + // new room; otherwise this is done later when cameras are recreated. + if (forchar != nullptr) { + if (play.IsAutoRoomViewport()) + adjust_viewport_to_room(); + update_all_viewcams_with_newroom(); + play.UpdateRoomCameras(); // update auto tracking + } + init_room_drawdata(); + + our_eip = 212; + invalidate_screen(); + for (cc = 0; cc < croom->numobj; cc++) { + if (objs[cc].on == 2) + MergeObject(cc); + } + new_room_flags = 0; + play.gscript_timer = -1; // avoid screw-ups with changing screens + play.player_on_region = 0; + // trash any input which they might have done while it was loading + ags_clear_input_buffer(); + // no fade in, so set the palette immediately in case of 256-col sprites + if (game.color_depth > 1) + setpal(); + + our_eip = 220; + update_polled_stuff_if_runtime(); + debug_script_log("Now in room %d", displayed_room); + guis_need_update = 1; + pl_run_plugin_hooks(AGSE_ENTERROOM, displayed_room); + // MoveToWalkableArea(game.playercharacter); + // MSS_CHECK_ALL_BLOCKS; } extern int psp_clear_cache_on_room_change; // new_room: changes the current room number, and loads the new room from disk -void new_room(int newnum,CharacterInfo*forchar) { - EndSkippingUntilCharStops(); +void new_room(int newnum, CharacterInfo *forchar) { + EndSkippingUntilCharStops(); - debug_script_log("Room change requested to room %d", newnum); + debug_script_log("Room change requested to room %d", newnum); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - // we are currently running Leaves Screen scripts - in_leaves_screen = newnum; + // we are currently running Leaves Screen scripts + in_leaves_screen = newnum; - // player leaves screen event - run_room_event(8); - // Run the global OnRoomLeave event - run_on_event (GE_LEAVE_ROOM, RuntimeScriptValue().SetInt32(displayed_room)); + // player leaves screen event + run_room_event(8); + // Run the global OnRoomLeave event + run_on_event(GE_LEAVE_ROOM, RuntimeScriptValue().SetInt32(displayed_room)); - pl_run_plugin_hooks(AGSE_LEAVEROOM, displayed_room); + pl_run_plugin_hooks(AGSE_LEAVEROOM, displayed_room); - // update the new room number if it has been altered by OnLeave scripts - newnum = in_leaves_screen; - in_leaves_screen = -1; + // update the new room number if it has been altered by OnLeave scripts + newnum = in_leaves_screen; + in_leaves_screen = -1; - if ((playerchar->following >= 0) && - (game.chars[playerchar->following].room != newnum)) { - // the player character is following another character, - // who is not in the new room. therefore, abort the follow - playerchar->following = -1; - } - update_polled_stuff_if_runtime(); + if ((playerchar->following >= 0) && + (game.chars[playerchar->following].room != newnum)) { + // the player character is following another character, + // who is not in the new room. therefore, abort the follow + playerchar->following = -1; + } + update_polled_stuff_if_runtime(); - // change rooms - unload_old_room(); + // change rooms + unload_old_room(); - if (psp_clear_cache_on_room_change) - { - // Delete all cached sprites - spriteset.DisposeAll(); + if (psp_clear_cache_on_room_change) { + // Delete all cached sprites + spriteset.DisposeAll(); - // Delete all gui background images - for (int i = 0; i < game.numgui; i++) - { - delete guibg[i]; - guibg[i] = nullptr; + // Delete all gui background images + for (int i = 0; i < game.numgui; i++) { + delete guibg[i]; + guibg[i] = nullptr; - if (guibgbmp[i]) - gfxDriver->DestroyDDB(guibgbmp[i]); - guibgbmp[i] = nullptr; - } - guis_need_update = 1; - } + if (guibgbmp[i]) + gfxDriver->DestroyDDB(guibgbmp[i]); + guibgbmp[i] = nullptr; + } + guis_need_update = 1; + } - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - load_new_room(newnum,forchar); + load_new_room(newnum, forchar); } int find_highest_room_entered() { - int qq,fndas=-1; - for (qq=0;qqbeenhere != 0)) - fndas = qq; - } - // This is actually legal - they might start in room 400 and save - //if (fndas<0) quit("find_highest_room: been in no rooms?"); - return fndas; + int qq, fndas = -1; + for (qq = 0; qq < MAX_ROOMS; qq++) { + if (isRoomStatusValid(qq) && (getRoomStatus(qq)->beenhere != 0)) + fndas = qq; + } + // This is actually legal - they might start in room 400 and save + //if (fndas<0) quit("find_highest_room: been in no rooms?"); + return fndas; } void first_room_initialization() { - starting_room = displayed_room; - set_loop_counter(0); - mouse_z_was = mouse_z; + starting_room = displayed_room; + set_loop_counter(0); + mouse_z_was = mouse_z; } void check_new_room() { - // if they're in a new room, run Player Enters Screen and on_event(ENTER_ROOM) - if ((in_new_room>0) & (in_new_room!=3)) { - EventHappened evh; - evh.type = EV_RUNEVBLOCK; - evh.data1 = EVB_ROOM; - evh.data2 = 0; - evh.data3 = 5; - evh.player=game.playercharacter; - // make sure that any script calls don't re-call enters screen - int newroom_was = in_new_room; - in_new_room = 0; - play.disabled_user_interface ++; - process_event(&evh); - play.disabled_user_interface --; - in_new_room = newroom_was; - // setevent(EV_RUNEVBLOCK,EVB_ROOM,0,5); - } + // if they're in a new room, run Player Enters Screen and on_event(ENTER_ROOM) + if ((in_new_room > 0) & (in_new_room != 3)) { + EventHappened evh; + evh.type = EV_RUNEVBLOCK; + evh.data1 = EVB_ROOM; + evh.data2 = 0; + evh.data3 = 5; + evh.player = game.playercharacter; + // make sure that any script calls don't re-call enters screen + int newroom_was = in_new_room; + in_new_room = 0; + play.disabled_user_interface ++; + process_event(&evh); + play.disabled_user_interface --; + in_new_room = newroom_was; + // setevent(EV_RUNEVBLOCK,EVB_ROOM,0,5); + } } void compile_room_script() { - ccError = 0; + ccError = 0; - roominst = ccInstance::CreateFromScript(thisroom.CompiledScript); + roominst = ccInstance::CreateFromScript(thisroom.CompiledScript); - if ((ccError!=0) || (roominst==nullptr)) { - quitprintf("Unable to create local script: %s", ccErrorString.GetCStr()); - } + if ((ccError != 0) || (roominst == nullptr)) { + quitprintf("Unable to create local script: %s", ccErrorString.GetCStr()); + } - roominstFork = roominst->Fork(); - if (roominstFork == nullptr) - quitprintf("Unable to create forked room instance: %s", ccErrorString.GetCStr()); + roominstFork = roominst->Fork(); + if (roominstFork == nullptr) + quitprintf("Unable to create forked room instance: %s", ccErrorString.GetCStr()); - repExecAlways.roomHasFunction = true; - lateRepExecAlways.roomHasFunction = true; - getDialogOptionsDimensionsFunc.roomHasFunction = true; + repExecAlways.roomHasFunction = true; + lateRepExecAlways.roomHasFunction = true; + getDialogOptionsDimensionsFunc.roomHasFunction = true; } int bg_just_changed = 0; -void on_background_frame_change () { +void on_background_frame_change() { - invalidate_screen(); - mark_current_background_dirty(); - invalidate_cached_walkbehinds(); + invalidate_screen(); + mark_current_background_dirty(); + invalidate_cached_walkbehinds(); - // get the new frame's palette - memcpy (palette, thisroom.BgFrames[play.bg_frame].Palette, sizeof(color) * 256); + // get the new frame's palette + memcpy(palette, thisroom.BgFrames[play.bg_frame].Palette, sizeof(color) * 256); - // hi-colour, update the palette. It won't have an immediate effect - // but will be drawn properly when the screen fades in - if (game.color_depth > 1) - setpal(); + // hi-colour, update the palette. It won't have an immediate effect + // but will be drawn properly when the screen fades in + if (game.color_depth > 1) + setpal(); - if (in_enters_screen) - return; + if (in_enters_screen) + return; - // Don't update the palette if it hasn't changed - if (thisroom.BgFrames[play.bg_frame].IsPaletteShared) - return; + // Don't update the palette if it hasn't changed + if (thisroom.BgFrames[play.bg_frame].IsPaletteShared) + return; - // 256-colours, tell it to update the palette (will actually be done as - // close as possible to the screen update to prevent flicker problem) - if (game.color_depth == 1) - bg_just_changed = 1; + // 256-colours, tell it to update the palette (will actually be done as + // close as possible to the screen update to prevent flicker problem) + if (game.color_depth == 1) + bg_just_changed = 1; } -void croom_ptr_clear() -{ - croom = nullptr; - objs = nullptr; +void croom_ptr_clear() { + croom = nullptr; + objs = nullptr; } -AGS_INLINE int room_to_mask_coord(int coord) -{ - return coord * game.GetDataUpscaleMult() / thisroom.MaskResolution; +AGS_INLINE int room_to_mask_coord(int coord) { + return coord * game.GetDataUpscaleMult() / thisroom.MaskResolution; } -AGS_INLINE int mask_to_room_coord(int coord) -{ - return coord * thisroom.MaskResolution / game.GetDataUpscaleMult(); +AGS_INLINE int mask_to_room_coord(int coord) { + return coord * thisroom.MaskResolution / game.GetDataUpscaleMult(); } -void convert_move_path_to_room_resolution(MoveList *ml) -{ - if ((game.options[OPT_WALKSPEEDABSOLUTE] != 0) && game.GetDataUpscaleMult() > 1) - { // Speeds are independent from MaskResolution - for (int i = 0; i < ml->numstage; i++) - { // ...so they are not multiplied by MaskResolution factor when converted to room coords - ml->xpermove[i] = ml->xpermove[i] / game.GetDataUpscaleMult(); - ml->ypermove[i] = ml->ypermove[i] / game.GetDataUpscaleMult(); - } - } - - if (thisroom.MaskResolution == game.GetDataUpscaleMult()) - return; - - ml->fromx = mask_to_room_coord(ml->fromx); - ml->fromy = mask_to_room_coord(ml->fromy); - ml->lastx = mask_to_room_coord(ml->lastx); - ml->lasty = mask_to_room_coord(ml->lasty); - - for (int i = 0; i < ml->numstage; i++) - { - uint16_t lowPart = mask_to_room_coord(ml->pos[i] & 0x0000ffff); - uint16_t highPart = mask_to_room_coord((ml->pos[i] >> 16) & 0x0000ffff); - ml->pos[i] = ((int)highPart << 16) | (lowPart & 0x0000ffff); - } - - if (game.options[OPT_WALKSPEEDABSOLUTE] == 0) - { // Speeds are scaling with MaskResolution - for (int i = 0; i < ml->numstage; i++) - { - ml->xpermove[i] = mask_to_room_coord(ml->xpermove[i]); - ml->ypermove[i] = mask_to_room_coord(ml->ypermove[i]); - } - } +void convert_move_path_to_room_resolution(MoveList *ml) { + if ((game.options[OPT_WALKSPEEDABSOLUTE] != 0) && game.GetDataUpscaleMult() > 1) { + // Speeds are independent from MaskResolution + for (int i = 0; i < ml->numstage; i++) { + // ...so they are not multiplied by MaskResolution factor when converted to room coords + ml->xpermove[i] = ml->xpermove[i] / game.GetDataUpscaleMult(); + ml->ypermove[i] = ml->ypermove[i] / game.GetDataUpscaleMult(); + } + } + + if (thisroom.MaskResolution == game.GetDataUpscaleMult()) + return; + + ml->fromx = mask_to_room_coord(ml->fromx); + ml->fromy = mask_to_room_coord(ml->fromy); + ml->lastx = mask_to_room_coord(ml->lastx); + ml->lasty = mask_to_room_coord(ml->lasty); + + for (int i = 0; i < ml->numstage; i++) { + uint16_t lowPart = mask_to_room_coord(ml->pos[i] & 0x0000ffff); + uint16_t highPart = mask_to_room_coord((ml->pos[i] >> 16) & 0x0000ffff); + ml->pos[i] = ((int)highPart << 16) | (lowPart & 0x0000ffff); + } + + if (game.options[OPT_WALKSPEEDABSOLUTE] == 0) { + // Speeds are scaling with MaskResolution + for (int i = 0; i < ml->numstage; i++) { + ml->xpermove[i] = mask_to_room_coord(ml->xpermove[i]); + ml->ypermove[i] = mask_to_room_coord(ml->ypermove[i]); + } + } } //============================================================================= @@ -1123,134 +1108,117 @@ void convert_move_path_to_room_resolution(MoveList *ml) extern ScriptString myScriptStringImpl; // ScriptDrawingSurface* (int backgroundNumber) -RuntimeScriptValue Sc_Room_GetDrawingSurfaceForBackground(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT(ScriptDrawingSurface, Room_GetDrawingSurfaceForBackground); +RuntimeScriptValue Sc_Room_GetDrawingSurfaceForBackground(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT(ScriptDrawingSurface, Room_GetDrawingSurfaceForBackground); } // int (const char *property) -RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(Room_GetProperty, const char); +RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(Room_GetProperty, const char); } // const char* (const char *property) -RuntimeScriptValue Sc_Room_GetTextProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Room_GetTextProperty, const char); +RuntimeScriptValue Sc_Room_GetTextProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Room_GetTextProperty, const char); } -RuntimeScriptValue Sc_Room_SetProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_BOOL_POBJ_PINT(Room_SetProperty, const char); +RuntimeScriptValue Sc_Room_SetProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_BOOL_POBJ_PINT(Room_SetProperty, const char); } // const char* (const char *property) -RuntimeScriptValue Sc_Room_SetTextProperty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_BOOL_POBJ2(Room_SetTextProperty, const char, const char); +RuntimeScriptValue Sc_Room_SetTextProperty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_BOOL_POBJ2(Room_SetTextProperty, const char, const char); } // int () -RuntimeScriptValue Sc_Room_GetBottomEdge(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetBottomEdge); +RuntimeScriptValue Sc_Room_GetBottomEdge(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetBottomEdge); } // int () -RuntimeScriptValue Sc_Room_GetColorDepth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetColorDepth); +RuntimeScriptValue Sc_Room_GetColorDepth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetColorDepth); } // int () -RuntimeScriptValue Sc_Room_GetHeight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetHeight); +RuntimeScriptValue Sc_Room_GetHeight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetHeight); } // int () -RuntimeScriptValue Sc_Room_GetLeftEdge(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetLeftEdge); +RuntimeScriptValue Sc_Room_GetLeftEdge(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetLeftEdge); } // const char* (int index) -RuntimeScriptValue Sc_Room_GetMessages(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Room_GetMessages); +RuntimeScriptValue Sc_Room_GetMessages(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Room_GetMessages); } // int () -RuntimeScriptValue Sc_Room_GetMusicOnLoad(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetMusicOnLoad); +RuntimeScriptValue Sc_Room_GetMusicOnLoad(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetMusicOnLoad); } // int () -RuntimeScriptValue Sc_Room_GetObjectCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetObjectCount); +RuntimeScriptValue Sc_Room_GetObjectCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetObjectCount); } // int () -RuntimeScriptValue Sc_Room_GetRightEdge(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetRightEdge); +RuntimeScriptValue Sc_Room_GetRightEdge(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetRightEdge); } // int () -RuntimeScriptValue Sc_Room_GetTopEdge(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetTopEdge); +RuntimeScriptValue Sc_Room_GetTopEdge(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetTopEdge); } // int () -RuntimeScriptValue Sc_Room_GetWidth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Room_GetWidth); +RuntimeScriptValue Sc_Room_GetWidth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Room_GetWidth); } // void (int xx,int yy,int mood) -RuntimeScriptValue Sc_RoomProcessClick(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT3(RoomProcessClick); +RuntimeScriptValue Sc_RoomProcessClick(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT3(RoomProcessClick); } -void RegisterRoomAPI() -{ - ccAddExternalStaticFunction("Room::GetDrawingSurfaceForBackground^1", Sc_Room_GetDrawingSurfaceForBackground); - ccAddExternalStaticFunction("Room::GetProperty^1", Sc_Room_GetProperty); - ccAddExternalStaticFunction("Room::GetTextProperty^1", Sc_Room_GetTextProperty); - ccAddExternalStaticFunction("Room::SetProperty^2", Sc_Room_SetProperty); - ccAddExternalStaticFunction("Room::SetTextProperty^2", Sc_Room_SetTextProperty); - ccAddExternalStaticFunction("Room::ProcessClick^3", Sc_RoomProcessClick); - ccAddExternalStaticFunction("ProcessClick", Sc_RoomProcessClick); - ccAddExternalStaticFunction("Room::get_BottomEdge", Sc_Room_GetBottomEdge); - ccAddExternalStaticFunction("Room::get_ColorDepth", Sc_Room_GetColorDepth); - ccAddExternalStaticFunction("Room::get_Height", Sc_Room_GetHeight); - ccAddExternalStaticFunction("Room::get_LeftEdge", Sc_Room_GetLeftEdge); - ccAddExternalStaticFunction("Room::geti_Messages", Sc_Room_GetMessages); - ccAddExternalStaticFunction("Room::get_MusicOnLoad", Sc_Room_GetMusicOnLoad); - ccAddExternalStaticFunction("Room::get_ObjectCount", Sc_Room_GetObjectCount); - ccAddExternalStaticFunction("Room::get_RightEdge", Sc_Room_GetRightEdge); - ccAddExternalStaticFunction("Room::get_TopEdge", Sc_Room_GetTopEdge); - ccAddExternalStaticFunction("Room::get_Width", Sc_Room_GetWidth); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Room::GetDrawingSurfaceForBackground^1", (void*)Room_GetDrawingSurfaceForBackground); - ccAddExternalFunctionForPlugin("Room::GetProperty^1", (void*)Room_GetProperty); - ccAddExternalFunctionForPlugin("Room::GetTextProperty^1", (void*)Room_GetTextProperty); - ccAddExternalFunctionForPlugin("Room::get_BottomEdge", (void*)Room_GetBottomEdge); - ccAddExternalFunctionForPlugin("Room::get_ColorDepth", (void*)Room_GetColorDepth); - ccAddExternalFunctionForPlugin("Room::get_Height", (void*)Room_GetHeight); - ccAddExternalFunctionForPlugin("Room::get_LeftEdge", (void*)Room_GetLeftEdge); - ccAddExternalFunctionForPlugin("Room::geti_Messages", (void*)Room_GetMessages); - ccAddExternalFunctionForPlugin("Room::get_MusicOnLoad", (void*)Room_GetMusicOnLoad); - ccAddExternalFunctionForPlugin("Room::get_ObjectCount", (void*)Room_GetObjectCount); - ccAddExternalFunctionForPlugin("Room::get_RightEdge", (void*)Room_GetRightEdge); - ccAddExternalFunctionForPlugin("Room::get_TopEdge", (void*)Room_GetTopEdge); - ccAddExternalFunctionForPlugin("Room::get_Width", (void*)Room_GetWidth); +void RegisterRoomAPI() { + ccAddExternalStaticFunction("Room::GetDrawingSurfaceForBackground^1", Sc_Room_GetDrawingSurfaceForBackground); + ccAddExternalStaticFunction("Room::GetProperty^1", Sc_Room_GetProperty); + ccAddExternalStaticFunction("Room::GetTextProperty^1", Sc_Room_GetTextProperty); + ccAddExternalStaticFunction("Room::SetProperty^2", Sc_Room_SetProperty); + ccAddExternalStaticFunction("Room::SetTextProperty^2", Sc_Room_SetTextProperty); + ccAddExternalStaticFunction("Room::ProcessClick^3", Sc_RoomProcessClick); + ccAddExternalStaticFunction("ProcessClick", Sc_RoomProcessClick); + ccAddExternalStaticFunction("Room::get_BottomEdge", Sc_Room_GetBottomEdge); + ccAddExternalStaticFunction("Room::get_ColorDepth", Sc_Room_GetColorDepth); + ccAddExternalStaticFunction("Room::get_Height", Sc_Room_GetHeight); + ccAddExternalStaticFunction("Room::get_LeftEdge", Sc_Room_GetLeftEdge); + ccAddExternalStaticFunction("Room::geti_Messages", Sc_Room_GetMessages); + ccAddExternalStaticFunction("Room::get_MusicOnLoad", Sc_Room_GetMusicOnLoad); + ccAddExternalStaticFunction("Room::get_ObjectCount", Sc_Room_GetObjectCount); + ccAddExternalStaticFunction("Room::get_RightEdge", Sc_Room_GetRightEdge); + ccAddExternalStaticFunction("Room::get_TopEdge", Sc_Room_GetTopEdge); + ccAddExternalStaticFunction("Room::get_Width", Sc_Room_GetWidth); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Room::GetDrawingSurfaceForBackground^1", (void *)Room_GetDrawingSurfaceForBackground); + ccAddExternalFunctionForPlugin("Room::GetProperty^1", (void *)Room_GetProperty); + ccAddExternalFunctionForPlugin("Room::GetTextProperty^1", (void *)Room_GetTextProperty); + ccAddExternalFunctionForPlugin("Room::get_BottomEdge", (void *)Room_GetBottomEdge); + ccAddExternalFunctionForPlugin("Room::get_ColorDepth", (void *)Room_GetColorDepth); + ccAddExternalFunctionForPlugin("Room::get_Height", (void *)Room_GetHeight); + ccAddExternalFunctionForPlugin("Room::get_LeftEdge", (void *)Room_GetLeftEdge); + ccAddExternalFunctionForPlugin("Room::geti_Messages", (void *)Room_GetMessages); + ccAddExternalFunctionForPlugin("Room::get_MusicOnLoad", (void *)Room_GetMusicOnLoad); + ccAddExternalFunctionForPlugin("Room::get_ObjectCount", (void *)Room_GetObjectCount); + ccAddExternalFunctionForPlugin("Room::get_RightEdge", (void *)Room_GetRightEdge); + ccAddExternalFunctionForPlugin("Room::get_TopEdge", (void *)Room_GetTopEdge); + ccAddExternalFunctionForPlugin("Room::get_Width", (void *)Room_GetWidth); } diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h index e34e1f9506ba..0c3149e574ac 100644 --- a/engines/ags/engine/ac/room.h +++ b/engines/ags/engine/ac/room.h @@ -28,8 +28,8 @@ #include "script/runtimescriptvalue.h" #include "game/roomstruct.h" -ScriptDrawingSurface* Room_GetDrawingSurfaceForBackground(int backgroundNumber); -ScriptDrawingSurface* Room_GetDrawingSurfaceForMask(RoomAreaMask mask); +ScriptDrawingSurface *Room_GetDrawingSurfaceForBackground(int backgroundNumber); +ScriptDrawingSurface *Room_GetDrawingSurfaceForMask(RoomAreaMask mask); int Room_GetObjectCount(); int Room_GetWidth(); int Room_GetHeight(); @@ -39,22 +39,22 @@ int Room_GetRightEdge(); int Room_GetTopEdge(); int Room_GetBottomEdge(); int Room_GetMusicOnLoad(); -const char* Room_GetTextProperty(const char *property); +const char *Room_GetTextProperty(const char *property); int Room_GetProperty(const char *property); -const char* Room_GetMessages(int index); +const char *Room_GetMessages(int index); RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t param_count); //============================================================================= -void save_room_data_segment (); +void save_room_data_segment(); void unload_old_room(); -void load_new_room(int newnum,CharacterInfo*forchar); -void new_room(int newnum,CharacterInfo*forchar); +void load_new_room(int newnum, CharacterInfo *forchar); +void new_room(int newnum, CharacterInfo *forchar); int find_highest_room_entered(); void first_room_initialization(); void check_new_room(); void compile_room_script(); -void on_background_frame_change (); +void on_background_frame_change(); // Clear the current room pointer if room status is no longer valid void croom_ptr_clear(); diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp index 41f18b7fd7b2..b4a8d4de4f7b 100644 --- a/engines/ags/engine/ac/roomobject.cpp +++ b/engines/ags/engine/ac/roomobject.cpp @@ -32,143 +32,134 @@ using AGS::Common::Stream; -extern ViewStruct*views; +extern ViewStruct *views; extern GameState play; extern GameSetupStruct game; -RoomObject::RoomObject() -{ - x = y = 0; - transparent = 0; - tint_r = tint_g = 0; - tint_b = tint_level = 0; - tint_light = 0; - zoom = 0; - last_width = last_height = 0; - num = 0; - baseline = 0; - view = loop = frame = 0; - wait = moving = 0; - cycling = 0; - overall_speed = 0; - on = 0; - flags = 0; - blocking_width = blocking_height = 0; +RoomObject::RoomObject() { + x = y = 0; + transparent = 0; + tint_r = tint_g = 0; + tint_b = tint_level = 0; + tint_light = 0; + zoom = 0; + last_width = last_height = 0; + num = 0; + baseline = 0; + view = loop = frame = 0; + wait = moving = 0; + cycling = 0; + overall_speed = 0; + on = 0; + flags = 0; + blocking_width = blocking_height = 0; } int RoomObject::get_width() { - if (last_width == 0) - return game.SpriteInfos[num].Width; - return last_width; + if (last_width == 0) + return game.SpriteInfos[num].Width; + return last_width; } int RoomObject::get_height() { - if (last_height == 0) - return game.SpriteInfos[num].Height; - return last_height; + if (last_height == 0) + return game.SpriteInfos[num].Height; + return last_height; } int RoomObject::get_baseline() { - if (baseline < 1) - return y; - return baseline; + if (baseline < 1) + return y; + return baseline; } -void RoomObject::UpdateCyclingView() -{ +void RoomObject::UpdateCyclingView() { if (on != 1) return; - if (moving>0) { - do_movelist_move(&moving,&x,&y); - } - if (cycling==0) return; - if (view<0) return; - if (wait>0) { wait--; return; } + if (moving > 0) { + do_movelist_move(&moving, &x, &y); + } + if (cycling == 0) return; + if (view < 0) return; + if (wait > 0) { + wait--; + return; + } - if (cycling >= ANIM_BACKWARDS) { + if (cycling >= ANIM_BACKWARDS) { - update_cycle_view_backwards(); + update_cycle_view_backwards(); - } - else { // Animate forwards - - update_cycle_view_forwards(); + } else { // Animate forwards - } // end if forwards + update_cycle_view_forwards(); - ViewFrame*vfptr=&views[view].loops[loop].frames[frame]; - num = vfptr->pic; + } // end if forwards - if (cycling == 0) - return; + ViewFrame *vfptr = &views[view].loops[loop].frames[frame]; + num = vfptr->pic; - wait=vfptr->speed+overall_speed; - CheckViewFrame (view, loop, frame); + if (cycling == 0) + return; + + wait = vfptr->speed + overall_speed; + CheckViewFrame(view, loop, frame); } -void RoomObject::update_cycle_view_forwards() -{ +void RoomObject::update_cycle_view_forwards() { frame++; - if (frame >= views[view].loops[loop].numFrames) { - // go to next loop thing - if (views[view].loops[loop].RunNextLoop()) { - if (loop+1 >= views[view].numLoops) - quit("!Last loop in a view requested to move to next loop"); - loop++; - frame=0; - } - else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) { - // leave it on the last frame - cycling=0; - frame--; - } - else { - if (play.no_multiloop_repeat == 0) { - // multi-loop anims, go back to start of it - while ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) - loop --; - } - if (cycling % ANIM_BACKWARDS == ANIM_ONCERESET) - cycling=0; - frame=0; - } - } + if (frame >= views[view].loops[loop].numFrames) { + // go to next loop thing + if (views[view].loops[loop].RunNextLoop()) { + if (loop + 1 >= views[view].numLoops) + quit("!Last loop in a view requested to move to next loop"); + loop++; + frame = 0; + } else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) { + // leave it on the last frame + cycling = 0; + frame--; + } else { + if (play.no_multiloop_repeat == 0) { + // multi-loop anims, go back to start of it + while ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) + loop --; + } + if (cycling % ANIM_BACKWARDS == ANIM_ONCERESET) + cycling = 0; + frame = 0; + } + } } -void RoomObject::update_cycle_view_backwards() -{ +void RoomObject::update_cycle_view_backwards() { // animate backwards - frame--; - if (frame < 0) { - if ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) - { - // If it's a Go-to-next-loop on the previous one, then go back - loop --; - frame = views[view].loops[loop].numFrames - 1; - } - else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) { - // leave it on the first frame - cycling = 0; - frame = 0; - } - else { // repeating animation - frame = views[view].loops[loop].numFrames - 1; - } - } + frame--; + if (frame < 0) { + if ((loop > 0) && + (views[view].loops[loop - 1].RunNextLoop())) { + // If it's a Go-to-next-loop on the previous one, then go back + loop --; + frame = views[view].loops[loop].numFrames - 1; + } else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) { + // leave it on the first frame + cycling = 0; + frame = 0; + } else { // repeating animation + frame = views[view].loops[loop].numFrames - 1; + } + } } -void RoomObject::ReadFromFile(Stream *in) -{ - in->ReadArrayOfInt32(&x, 3); - in->ReadArrayOfInt16(&tint_r, 15); - in->ReadArrayOfInt8((int8_t*)&cycling, 4); - in->ReadArrayOfInt16(&blocking_width, 2); +void RoomObject::ReadFromFile(Stream *in) { + in->ReadArrayOfInt32(&x, 3); + in->ReadArrayOfInt16(&tint_r, 15); + in->ReadArrayOfInt8((int8_t *)&cycling, 4); + in->ReadArrayOfInt16(&blocking_width, 2); } -void RoomObject::WriteToFile(Stream *out) const -{ - out->WriteArrayOfInt32(&x, 3); - out->WriteArrayOfInt16(&tint_r, 15); - out->WriteArrayOfInt8((int8_t*)&cycling, 4); - out->WriteArrayOfInt16(&blocking_width, 2); +void RoomObject::WriteToFile(Stream *out) const { + out->WriteArrayOfInt32(&x, 3); + out->WriteArrayOfInt16(&tint_r, 15); + out->WriteArrayOfInt8((int8_t *)&cycling, 4); + out->WriteArrayOfInt16(&blocking_width, 2); } diff --git a/engines/ags/engine/ac/roomobject.h b/engines/ags/engine/ac/roomobject.h index af648ba35fc1..22dce65a76d8 100644 --- a/engines/ags/engine/ac/roomobject.h +++ b/engines/ags/engine/ac/roomobject.h @@ -25,43 +25,51 @@ #include "ac/common_defines.h" -namespace AGS { namespace Common { class Stream; }} +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later // IMPORTANT: this struct is restricted by plugin API! struct RoomObject { - int x,y; - int transparent; // current transparency setting - short tint_r, tint_g; // specific object tint - short tint_b, tint_level; - short tint_light; - short zoom; // zoom level, either manual or from the current area - short last_width, last_height; // width/height last time drawn - short num; // sprite slot number - short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline - short view,loop,frame; // only used to track animation - 'num' holds the current sprite - short wait,moving; - char cycling; // is it currently animating? - char overall_speed; - char on; - char flags; - short blocking_width, blocking_height; + int x, y; + int transparent; // current transparency setting + short tint_r, tint_g; // specific object tint + short tint_b, tint_level; + short tint_light; + short zoom; // zoom level, either manual or from the current area + short last_width, last_height; // width/height last time drawn + short num; // sprite slot number + short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline + short view, loop, frame; // only used to track animation - 'num' holds the current sprite + short wait, moving; + char cycling; // is it currently animating? + char overall_speed; + char on; + char flags; + short blocking_width, blocking_height; - RoomObject(); + RoomObject(); - int get_width(); - int get_height(); - int get_baseline(); + int get_width(); + int get_height(); + int get_baseline(); - inline bool has_explicit_light() const { return (flags & OBJF_HASLIGHT) != 0; } - inline bool has_explicit_tint() const { return (flags & OBJF_HASTINT) != 0; } + inline bool has_explicit_light() const { + return (flags & OBJF_HASLIGHT) != 0; + } + inline bool has_explicit_tint() const { + return (flags & OBJF_HASTINT) != 0; + } void UpdateCyclingView(); void update_cycle_view_forwards(); void update_cycle_view_backwards(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out) const; + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out) const; }; #endif diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp index 1a37d53110f5..96e036b72f6e 100644 --- a/engines/ags/engine/ac/roomstatus.cpp +++ b/engines/ags/engine/ac/roomstatus.cpp @@ -32,217 +32,183 @@ using namespace AGS::Common; using namespace AGS::Engine; -RoomStatus::RoomStatus() -{ - beenhere = 0; - numobj = 0; - memset(&flagstates, 0, sizeof(flagstates)); - tsdatasize = 0; - tsdata = nullptr; - - memset(&hotspot_enabled, 0, sizeof(hotspot_enabled)); - memset(®ion_enabled, 0, sizeof(region_enabled)); - memset(&walkbehind_base, 0, sizeof(walkbehind_base)); - memset(&interactionVariableValues, 0, sizeof(interactionVariableValues)); +RoomStatus::RoomStatus() { + beenhere = 0; + numobj = 0; + memset(&flagstates, 0, sizeof(flagstates)); + tsdatasize = 0; + tsdata = nullptr; + + memset(&hotspot_enabled, 0, sizeof(hotspot_enabled)); + memset(®ion_enabled, 0, sizeof(region_enabled)); + memset(&walkbehind_base, 0, sizeof(walkbehind_base)); + memset(&interactionVariableValues, 0, sizeof(interactionVariableValues)); } -RoomStatus::~RoomStatus() -{ - if (tsdata) - delete [] tsdata; +RoomStatus::~RoomStatus() { + if (tsdata) + delete [] tsdata; } -void RoomStatus::FreeScriptData() -{ - if (tsdata) - delete [] tsdata; - tsdata = nullptr; - tsdatasize = 0; +void RoomStatus::FreeScriptData() { + if (tsdata) + delete [] tsdata; + tsdata = nullptr; + tsdatasize = 0; } -void RoomStatus::FreeProperties() -{ - roomProps.clear(); - for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) - { - hsProps[i].clear(); - } - for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) - { - objProps[i].clear(); - } +void RoomStatus::FreeProperties() { + roomProps.clear(); + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) { + hsProps[i].clear(); + } + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) { + objProps[i].clear(); + } } -void RoomStatus::ReadFromFile_v321(Stream *in) -{ - beenhere = in->ReadInt32(); - numobj = in->ReadInt32(); - ReadRoomObjects_Aligned(in); - in->ReadArrayOfInt16(flagstates, MAX_FLAGS); - tsdatasize = in->ReadInt32(); - in->ReadInt32(); // tsdata - for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) - { - intrHotspot[i].ReadFromSavedgame_v321(in); - } - for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) - { - intrObject[i].ReadFromSavedgame_v321(in); - } - for (int i = 0; i < MAX_ROOM_REGIONS; ++i) - { - intrRegion[i].ReadFromSavedgame_v321(in); - } - intrRoom.ReadFromSavedgame_v321(in); - in->ReadArrayOfInt8((int8_t*)hotspot_enabled, MAX_ROOM_HOTSPOTS); - in->ReadArrayOfInt8((int8_t*)region_enabled, MAX_ROOM_REGIONS); - in->ReadArrayOfInt16(walkbehind_base, MAX_WALK_BEHINDS); - in->ReadArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); - - if (loaded_game_file_version >= kGameVersion_340_4) - { - Properties::ReadValues(roomProps, in); - for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) - { - Properties::ReadValues(hsProps[i], in); - } - for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) - { - Properties::ReadValues(objProps[i], in); - } - } +void RoomStatus::ReadFromFile_v321(Stream *in) { + beenhere = in->ReadInt32(); + numobj = in->ReadInt32(); + ReadRoomObjects_Aligned(in); + in->ReadArrayOfInt16(flagstates, MAX_FLAGS); + tsdatasize = in->ReadInt32(); + in->ReadInt32(); // tsdata + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) { + intrHotspot[i].ReadFromSavedgame_v321(in); + } + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) { + intrObject[i].ReadFromSavedgame_v321(in); + } + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) { + intrRegion[i].ReadFromSavedgame_v321(in); + } + intrRoom.ReadFromSavedgame_v321(in); + in->ReadArrayOfInt8((int8_t *)hotspot_enabled, MAX_ROOM_HOTSPOTS); + in->ReadArrayOfInt8((int8_t *)region_enabled, MAX_ROOM_REGIONS); + in->ReadArrayOfInt16(walkbehind_base, MAX_WALK_BEHINDS); + in->ReadArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); + + if (loaded_game_file_version >= kGameVersion_340_4) { + Properties::ReadValues(roomProps, in); + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) { + Properties::ReadValues(hsProps[i], in); + } + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) { + Properties::ReadValues(objProps[i], in); + } + } } -void RoomStatus::ReadRoomObjects_Aligned(Common::Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) - { - obj[i].ReadFromFile(&align_s); - align_s.Reset(); - } +void RoomStatus::ReadRoomObjects_Aligned(Common::Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) { + obj[i].ReadFromFile(&align_s); + align_s.Reset(); + } } -void RoomStatus::ReadFromSavegame(Stream *in) -{ - FreeScriptData(); - FreeProperties(); - - beenhere = in->ReadInt8(); - numobj = in->ReadInt32(); - for (int i = 0; i < numobj; ++i) - { - obj[i].ReadFromFile(in); - Properties::ReadValues(objProps[i], in); - if (loaded_game_file_version <= kGameVersion_272) - SavegameComponents::ReadInteraction272(intrObject[i], in); - } - for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) - { - hotspot_enabled[i] = in->ReadInt8(); - Properties::ReadValues(hsProps[i], in); - if (loaded_game_file_version <= kGameVersion_272) - SavegameComponents::ReadInteraction272(intrHotspot[i], in); - } - for (int i = 0; i < MAX_ROOM_REGIONS; ++i) - { - region_enabled[i] = in->ReadInt8(); - if (loaded_game_file_version <= kGameVersion_272) - SavegameComponents::ReadInteraction272(intrRegion[i], in); - } - for (int i = 0; i < MAX_WALK_BEHINDS; ++i) - { - walkbehind_base[i] = in->ReadInt32(); - } - - Properties::ReadValues(roomProps, in); - if (loaded_game_file_version <= kGameVersion_272) - { - SavegameComponents::ReadInteraction272(intrRoom, in); - in->ReadArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); - } - - tsdatasize = in->ReadInt32(); - if (tsdatasize) - { - tsdata = new char[tsdatasize]; - in->Read(tsdata, tsdatasize); - } +void RoomStatus::ReadFromSavegame(Stream *in) { + FreeScriptData(); + FreeProperties(); + + beenhere = in->ReadInt8(); + numobj = in->ReadInt32(); + for (int i = 0; i < numobj; ++i) { + obj[i].ReadFromFile(in); + Properties::ReadValues(objProps[i], in); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::ReadInteraction272(intrObject[i], in); + } + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) { + hotspot_enabled[i] = in->ReadInt8(); + Properties::ReadValues(hsProps[i], in); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::ReadInteraction272(intrHotspot[i], in); + } + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) { + region_enabled[i] = in->ReadInt8(); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::ReadInteraction272(intrRegion[i], in); + } + for (int i = 0; i < MAX_WALK_BEHINDS; ++i) { + walkbehind_base[i] = in->ReadInt32(); + } + + Properties::ReadValues(roomProps, in); + if (loaded_game_file_version <= kGameVersion_272) { + SavegameComponents::ReadInteraction272(intrRoom, in); + in->ReadArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); + } + + tsdatasize = in->ReadInt32(); + if (tsdatasize) { + tsdata = new char[tsdatasize]; + in->Read(tsdata, tsdatasize); + } } -void RoomStatus::WriteToSavegame(Stream *out) const -{ - out->WriteInt8(beenhere); - out->WriteInt32(numobj); - for (int i = 0; i < numobj; ++i) - { - obj[i].WriteToFile(out); - Properties::WriteValues(objProps[i], out); - if (loaded_game_file_version <= kGameVersion_272) - SavegameComponents::WriteInteraction272(intrObject[i], out); - } - for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) - { - out->WriteInt8(hotspot_enabled[i]); - Properties::WriteValues(hsProps[i], out); - if (loaded_game_file_version <= kGameVersion_272) - SavegameComponents::WriteInteraction272(intrHotspot[i], out); - } - for (int i = 0; i < MAX_ROOM_REGIONS; ++i) - { - out->WriteInt8(region_enabled[i]); - if (loaded_game_file_version <= kGameVersion_272) - SavegameComponents::WriteInteraction272(intrRegion[i], out); - } - for (int i = 0; i < MAX_WALK_BEHINDS; ++i) - { - out->WriteInt32(walkbehind_base[i]); - } - - Properties::WriteValues(roomProps, out); - if (loaded_game_file_version <= kGameVersion_272) - { - SavegameComponents::WriteInteraction272(intrRoom, out); - out->WriteArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); - } - - out->WriteInt32(tsdatasize); - if (tsdatasize) - out->Write(tsdata, tsdatasize); +void RoomStatus::WriteToSavegame(Stream *out) const { + out->WriteInt8(beenhere); + out->WriteInt32(numobj); + for (int i = 0; i < numobj; ++i) { + obj[i].WriteToFile(out); + Properties::WriteValues(objProps[i], out); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::WriteInteraction272(intrObject[i], out); + } + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) { + out->WriteInt8(hotspot_enabled[i]); + Properties::WriteValues(hsProps[i], out); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::WriteInteraction272(intrHotspot[i], out); + } + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) { + out->WriteInt8(region_enabled[i]); + if (loaded_game_file_version <= kGameVersion_272) + SavegameComponents::WriteInteraction272(intrRegion[i], out); + } + for (int i = 0; i < MAX_WALK_BEHINDS; ++i) { + out->WriteInt32(walkbehind_base[i]); + } + + Properties::WriteValues(roomProps, out); + if (loaded_game_file_version <= kGameVersion_272) { + SavegameComponents::WriteInteraction272(intrRoom, out); + out->WriteArrayOfInt32(interactionVariableValues, MAX_GLOBAL_VARIABLES); + } + + out->WriteInt32(tsdatasize); + if (tsdatasize) + out->Write(tsdata, tsdatasize); } // JJS: Replacement for the global roomstats array in the original engine. -RoomStatus* room_statuses[MAX_ROOMS]; +RoomStatus *room_statuses[MAX_ROOMS]; // Replaces all accesses to the roomstats array -RoomStatus* getRoomStatus(int room) -{ - if (room_statuses[room] == nullptr) - { - // First access, allocate and initialise the status - room_statuses[room] = new RoomStatus(); - } - return room_statuses[room]; +RoomStatus *getRoomStatus(int room) { + if (room_statuses[room] == nullptr) { + // First access, allocate and initialise the status + room_statuses[room] = new RoomStatus(); + } + return room_statuses[room]; } // Used in places where it is only important to know whether the player // had previously entered the room. In this case it is not necessary // to initialise the status because a player can only have been in // a room if the status is already initialised. -bool isRoomStatusValid(int room) -{ - return (room_statuses[room] != nullptr); +bool isRoomStatusValid(int room) { + return (room_statuses[room] != nullptr); } -void resetRoomStatuses() -{ - for (int i = 0; i < MAX_ROOMS; i++) - { - if (room_statuses[i] != nullptr) - { - delete room_statuses[i]; - room_statuses[i] = nullptr; - } - } +void resetRoomStatuses() { + for (int i = 0; i < MAX_ROOMS; i++) { + if (room_statuses[i] != nullptr) { + delete room_statuses[i]; + room_statuses[i] = nullptr; + } + } } diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h index a57036815199..70e4701865fa 100644 --- a/engines/ags/engine/ac/roomstatus.h +++ b/engines/ags/engine/ac/roomstatus.h @@ -29,52 +29,56 @@ #include "util/string_types.h" // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using AGS::Common::Stream; using AGS::Common::Interaction; // This struct is saved in the save games - it contains everything about // a room that could change struct RoomStatus { - int beenhere; - int numobj; - RoomObject obj[MAX_ROOM_OBJECTS]; - short flagstates[MAX_FLAGS]; - int tsdatasize; - char* tsdata; - Interaction intrHotspot[MAX_ROOM_HOTSPOTS]; - Interaction intrObject [MAX_ROOM_OBJECTS]; - Interaction intrRegion [MAX_ROOM_REGIONS]; - Interaction intrRoom; + int beenhere; + int numobj; + RoomObject obj[MAX_ROOM_OBJECTS]; + short flagstates[MAX_FLAGS]; + int tsdatasize; + char *tsdata; + Interaction intrHotspot[MAX_ROOM_HOTSPOTS]; + Interaction intrObject [MAX_ROOM_OBJECTS]; + Interaction intrRegion [MAX_ROOM_REGIONS]; + Interaction intrRoom; - Common::StringIMap roomProps; - Common::StringIMap hsProps[MAX_ROOM_HOTSPOTS]; - Common::StringIMap objProps[MAX_ROOM_OBJECTS]; - // [IKM] 2012-06-22: not used anywhere + Common::StringIMap roomProps; + Common::StringIMap hsProps[MAX_ROOM_HOTSPOTS]; + Common::StringIMap objProps[MAX_ROOM_OBJECTS]; + // [IKM] 2012-06-22: not used anywhere #ifdef UNUSED_CODE - EventBlock hscond[MAX_ROOM_HOTSPOTS]; - EventBlock objcond[MAX_ROOM_OBJECTS]; - EventBlock misccond; + EventBlock hscond[MAX_ROOM_HOTSPOTS]; + EventBlock objcond[MAX_ROOM_OBJECTS]; + EventBlock misccond; #endif - char hotspot_enabled[MAX_ROOM_HOTSPOTS]; - char region_enabled[MAX_ROOM_REGIONS]; - short walkbehind_base[MAX_WALK_BEHINDS]; - int interactionVariableValues[MAX_GLOBAL_VARIABLES]; + char hotspot_enabled[MAX_ROOM_HOTSPOTS]; + char region_enabled[MAX_ROOM_REGIONS]; + short walkbehind_base[MAX_WALK_BEHINDS]; + int interactionVariableValues[MAX_GLOBAL_VARIABLES]; - RoomStatus(); - ~RoomStatus(); + RoomStatus(); + ~RoomStatus(); - void FreeScriptData(); - void FreeProperties(); + void FreeScriptData(); + void FreeProperties(); - void ReadFromFile_v321(Common::Stream *in); - void ReadRoomObjects_Aligned(Common::Stream *in); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile_v321(Common::Stream *in); + void ReadRoomObjects_Aligned(Common::Stream *in); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; }; // Replaces all accesses to the roomstats array -RoomStatus* getRoomStatus(int room); +RoomStatus *getRoomStatus(int room); // Used in places where it is only important to know whether the player // had previously entered the room. In this case it is not necessary // to initialise the status because a player can only have been in diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index 68ec56d740d9..60be1c042fb3 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -29,142 +29,112 @@ using AGS::Common::Bitmap; -class IRouteFinder -{ - public: - virtual void init_pathfinder() = 0; - virtual void shutdown_pathfinder() = 0; - virtual void set_wallscreen(Bitmap *wallscreen) = 0; - virtual int can_see_from(int x1, int y1, int x2, int y2) = 0; - virtual void get_lastcpos(int &lastcx, int &lastcy) = 0; - virtual void set_route_move_speed(int speed_x, int speed_y) = 0; - virtual int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) = 0; - virtual void calculate_move_stage(MoveList * mlsp, int aaa) = 0; +class IRouteFinder { +public: + virtual void init_pathfinder() = 0; + virtual void shutdown_pathfinder() = 0; + virtual void set_wallscreen(Bitmap *wallscreen) = 0; + virtual int can_see_from(int x1, int y1, int x2, int y2) = 0; + virtual void get_lastcpos(int &lastcx, int &lastcy) = 0; + virtual void set_route_move_speed(int speed_x, int speed_y) = 0; + virtual int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) = 0; + virtual void calculate_move_stage(MoveList *mlsp, int aaa) = 0; }; -class AGSRouteFinder : public IRouteFinder -{ - public: - void init_pathfinder() override - { - AGS::Engine::RouteFinder::init_pathfinder(); - } - void shutdown_pathfinder() override - { - AGS::Engine::RouteFinder::shutdown_pathfinder(); - } - void set_wallscreen(Bitmap *wallscreen) override - { - AGS::Engine::RouteFinder::set_wallscreen(wallscreen); - } - int can_see_from(int x1, int y1, int x2, int y2) override - { - return AGS::Engine::RouteFinder::can_see_from(x1, y1, x2, y2); - } - void get_lastcpos(int &lastcx, int &lastcy) override - { - AGS::Engine::RouteFinder::get_lastcpos(lastcx, lastcy); - } - void set_route_move_speed(int speed_x, int speed_y) override - { - AGS::Engine::RouteFinder::set_route_move_speed(speed_x, speed_y); - } - int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override - { - return AGS::Engine::RouteFinder::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); - } - void calculate_move_stage(MoveList * mlsp, int aaa) override - { - AGS::Engine::RouteFinder::calculate_move_stage(mlsp, aaa); - } +class AGSRouteFinder : public IRouteFinder { +public: + void init_pathfinder() override { + AGS::Engine::RouteFinder::init_pathfinder(); + } + void shutdown_pathfinder() override { + AGS::Engine::RouteFinder::shutdown_pathfinder(); + } + void set_wallscreen(Bitmap *wallscreen) override { + AGS::Engine::RouteFinder::set_wallscreen(wallscreen); + } + int can_see_from(int x1, int y1, int x2, int y2) override { + return AGS::Engine::RouteFinder::can_see_from(x1, y1, x2, y2); + } + void get_lastcpos(int &lastcx, int &lastcy) override { + AGS::Engine::RouteFinder::get_lastcpos(lastcx, lastcy); + } + void set_route_move_speed(int speed_x, int speed_y) override { + AGS::Engine::RouteFinder::set_route_move_speed(speed_x, speed_y); + } + int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override { + return AGS::Engine::RouteFinder::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); + } + void calculate_move_stage(MoveList *mlsp, int aaa) override { + AGS::Engine::RouteFinder::calculate_move_stage(mlsp, aaa); + } }; -class AGSLegacyRouteFinder : public IRouteFinder -{ - public: - void init_pathfinder() override - { - AGS::Engine::RouteFinderLegacy::init_pathfinder(); - } - void shutdown_pathfinder() override - { - AGS::Engine::RouteFinderLegacy::shutdown_pathfinder(); - } - void set_wallscreen(Bitmap *wallscreen) override - { - AGS::Engine::RouteFinderLegacy::set_wallscreen(wallscreen); - } - int can_see_from(int x1, int y1, int x2, int y2) override - { - return AGS::Engine::RouteFinderLegacy::can_see_from(x1, y1, x2, y2); - } - void get_lastcpos(int &lastcx, int &lastcy) override - { - AGS::Engine::RouteFinderLegacy::get_lastcpos(lastcx, lastcy); - } - void set_route_move_speed(int speed_x, int speed_y) override - { - AGS::Engine::RouteFinderLegacy::set_route_move_speed(speed_x, speed_y); - } - int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override - { - return AGS::Engine::RouteFinderLegacy::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); - } - void calculate_move_stage(MoveList * mlsp, int aaa) override - { - AGS::Engine::RouteFinderLegacy::calculate_move_stage(mlsp, aaa); - } +class AGSLegacyRouteFinder : public IRouteFinder { +public: + void init_pathfinder() override { + AGS::Engine::RouteFinderLegacy::init_pathfinder(); + } + void shutdown_pathfinder() override { + AGS::Engine::RouteFinderLegacy::shutdown_pathfinder(); + } + void set_wallscreen(Bitmap *wallscreen) override { + AGS::Engine::RouteFinderLegacy::set_wallscreen(wallscreen); + } + int can_see_from(int x1, int y1, int x2, int y2) override { + return AGS::Engine::RouteFinderLegacy::can_see_from(x1, y1, x2, y2); + } + void get_lastcpos(int &lastcx, int &lastcy) override { + AGS::Engine::RouteFinderLegacy::get_lastcpos(lastcx, lastcy); + } + void set_route_move_speed(int speed_x, int speed_y) override { + AGS::Engine::RouteFinderLegacy::set_route_move_speed(speed_x, speed_y); + } + int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override { + return AGS::Engine::RouteFinderLegacy::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); + } + void calculate_move_stage(MoveList *mlsp, int aaa) override { + AGS::Engine::RouteFinderLegacy::calculate_move_stage(mlsp, aaa); + } }; static IRouteFinder *route_finder_impl = nullptr; -void init_pathfinder(GameDataVersion game_file_version) -{ - if (game_file_version >= kGameVersion_350) - { - AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize path finder library"); - route_finder_impl = new AGSRouteFinder(); - } - else - { - AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize legacy path finder library"); - route_finder_impl = new AGSLegacyRouteFinder(); - } - - route_finder_impl->init_pathfinder(); +void init_pathfinder(GameDataVersion game_file_version) { + if (game_file_version >= kGameVersion_350) { + AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize path finder library"); + route_finder_impl = new AGSRouteFinder(); + } else { + AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize legacy path finder library"); + route_finder_impl = new AGSLegacyRouteFinder(); + } + + route_finder_impl->init_pathfinder(); } -void shutdown_pathfinder() -{ - route_finder_impl->shutdown_pathfinder(); +void shutdown_pathfinder() { + route_finder_impl->shutdown_pathfinder(); } -void set_wallscreen(Bitmap *wallscreen) -{ - route_finder_impl->set_wallscreen(wallscreen); +void set_wallscreen(Bitmap *wallscreen) { + route_finder_impl->set_wallscreen(wallscreen); } -int can_see_from(int x1, int y1, int x2, int y2) -{ - return route_finder_impl->can_see_from(x1, y1, x2, y2); +int can_see_from(int x1, int y1, int x2, int y2) { + return route_finder_impl->can_see_from(x1, y1, x2, y2); } -void get_lastcpos(int &lastcx, int &lastcy) -{ - route_finder_impl->get_lastcpos(lastcx, lastcy); +void get_lastcpos(int &lastcx, int &lastcy) { + route_finder_impl->get_lastcpos(lastcx, lastcy); } -void set_route_move_speed(int speed_x, int speed_y) -{ - route_finder_impl->set_route_move_speed(speed_x, speed_y); +void set_route_move_speed(int speed_x, int speed_y) { + route_finder_impl->set_route_move_speed(speed_x, speed_y); } -int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) -{ - return route_finder_impl->find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); +int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) { + return route_finder_impl->find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls); } -void calculate_move_stage(MoveList * mlsp, int aaa) -{ - route_finder_impl->calculate_move_stage(mlsp, aaa); +void calculate_move_stage(MoveList *mlsp, int aaa) { + route_finder_impl->calculate_move_stage(mlsp, aaa); } diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h index 35dc05fc24a2..17ee1af0abf7 100644 --- a/engines/ags/engine/ac/route_finder.h +++ b/engines/ags/engine/ac/route_finder.h @@ -26,7 +26,11 @@ #include "ac/game_version.h" // Forward declaration -namespace AGS { namespace Common { class Bitmap; }} +namespace AGS { +namespace Common { +class Bitmap; +} +} struct MoveList; void init_pathfinder(GameDataVersion game_file_version); @@ -40,6 +44,6 @@ void get_lastcpos(int &lastcx, int &lastcy); void set_route_move_speed(int speed_x, int speed_y); int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); -void calculate_move_stage(MoveList * mlsp, int aaa); +void calculate_move_stage(MoveList *mlsp, int aaa); #endif diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp index 2fcf218f2b93..24a95870445f 100644 --- a/engines/ags/engine/ac/route_finder_impl.cpp +++ b/engines/ags/engine/ac/route_finder_impl.cpp @@ -59,222 +59,206 @@ static Navigation nav; static Bitmap *wallscreen; static int lastcx, lastcy; -void init_pathfinder() -{ +void init_pathfinder() { } -void shutdown_pathfinder() -{ +void shutdown_pathfinder() { } -void set_wallscreen(Bitmap *wallscreen_) -{ - wallscreen = wallscreen_; +void set_wallscreen(Bitmap *wallscreen_) { + wallscreen = wallscreen_; } -static void sync_nav_wallscreen() -{ - // FIXME: this is dumb, but... - nav.Resize(wallscreen->GetWidth(), wallscreen->GetHeight()); +static void sync_nav_wallscreen() { + // FIXME: this is dumb, but... + nav.Resize(wallscreen->GetWidth(), wallscreen->GetHeight()); - for (int y=0; yGetHeight(); y++) - nav.SetMapRow(y, wallscreen->GetScanLine(y)); + for (int y = 0; y < wallscreen->GetHeight(); y++) + nav.SetMapRow(y, wallscreen->GetScanLine(y)); } -int can_see_from(int x1, int y1, int x2, int y2) -{ - lastcx = x1; - lastcy = y1; +int can_see_from(int x1, int y1, int x2, int y2) { + lastcx = x1; + lastcy = y1; - if ((x1 == x2) && (y1 == y2)) - return 1; + if ((x1 == x2) && (y1 == y2)) + return 1; - sync_nav_wallscreen(); + sync_nav_wallscreen(); - return !nav.TraceLine(x1, y1, x2, y2, lastcx, lastcy); + return !nav.TraceLine(x1, y1, x2, y2, lastcx, lastcy); } -void get_lastcpos(int &lastcx_, int &lastcy_) -{ - lastcx_ = lastcx; - lastcy_ = lastcy; +void get_lastcpos(int &lastcx_, int &lastcy_) { + lastcx_ = lastcx; + lastcy_ = lastcy; } // new routing using JPS -static int find_route_jps(int fromx, int fromy, int destx, int desty) -{ - sync_nav_wallscreen(); +static int find_route_jps(int fromx, int fromy, int destx, int desty) { + sync_nav_wallscreen(); - static std::vector path, cpath; - path.clear(); - cpath.clear(); + static std::vector path, cpath; + path.clear(); + cpath.clear(); - if (nav.NavigateRefined(fromx, fromy, destx, desty, path, cpath) == Navigation::NAV_UNREACHABLE) - return 0; + if (nav.NavigateRefined(fromx, fromy, destx, desty, path, cpath) == Navigation::NAV_UNREACHABLE) + return 0; - num_navpoints = 0; + num_navpoints = 0; - // new behavior: cut path if too complex rather than abort with error message - int count = std::min((int)cpath.size(), MAXNAVPOINTS); + // new behavior: cut path if too complex rather than abort with error message + int count = std::min((int)cpath.size(), MAXNAVPOINTS); - for (int i = 0; ipos[aaa] == mlsp->pos[aaa + 1]) { - mlsp->xpermove[aaa] = 0; - mlsp->ypermove[aaa] = 0; - return; - } - - short ourx = (mlsp->pos[aaa] >> 16) & 0x000ffff; - short oury = (mlsp->pos[aaa] & 0x000ffff); - short destx = ((mlsp->pos[aaa + 1] >> 16) & 0x000ffff); - short desty = (mlsp->pos[aaa + 1] & 0x000ffff); - - // Special case for vertical and horizontal movements - if (ourx == destx) { - mlsp->xpermove[aaa] = 0; - mlsp->ypermove[aaa] = move_speed_y; - if (desty < oury) - mlsp->ypermove[aaa] = -mlsp->ypermove[aaa]; - - return; - } - - if (oury == desty) { - mlsp->xpermove[aaa] = move_speed_x; - mlsp->ypermove[aaa] = 0; - if (destx < ourx) - mlsp->xpermove[aaa] = -mlsp->xpermove[aaa]; - - return; - } - - fixed xdist = itofix(abs(ourx - destx)); - fixed ydist = itofix(abs(oury - desty)); - - fixed useMoveSpeed; - - if (move_speed_x == move_speed_y) { - useMoveSpeed = move_speed_x; - } - else { - // different X and Y move speeds - // the X proportion of the movement is (x / (x + y)) - fixed xproportion = fixdiv(xdist, (xdist + ydist)); - - if (move_speed_x > move_speed_y) { - // speed = y + ((1 - xproportion) * (x - y)) - useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y); - } - else { - // speed = x + (xproportion * (y - x)) - useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x); - } - } - - fixed angl = fixatan(fixdiv(ydist, xdist)); - - // now, since new opp=hyp*sin, work out the Y step size - //fixed newymove = useMoveSpeed * fsin(angl); - fixed newymove = fixmul(useMoveSpeed, fixsin(angl)); - - // since adj=hyp*cos, work out X step size - //fixed newxmove = useMoveSpeed * fcos(angl); - fixed newxmove = fixmul(useMoveSpeed, fixcos(angl)); - - if (destx < ourx) - newxmove = -newxmove; - if (desty < oury) - newymove = -newymove; - - mlsp->xpermove[aaa] = newxmove; - mlsp->ypermove[aaa] = newymove; +void calculate_move_stage(MoveList *mlsp, int aaa) { + // work out the x & y per move. First, opp/adj=tan, so work out the angle + if (mlsp->pos[aaa] == mlsp->pos[aaa + 1]) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = 0; + return; + } + + short ourx = (mlsp->pos[aaa] >> 16) & 0x000ffff; + short oury = (mlsp->pos[aaa] & 0x000ffff); + short destx = ((mlsp->pos[aaa + 1] >> 16) & 0x000ffff); + short desty = (mlsp->pos[aaa + 1] & 0x000ffff); + + // Special case for vertical and horizontal movements + if (ourx == destx) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = move_speed_y; + if (desty < oury) + mlsp->ypermove[aaa] = -mlsp->ypermove[aaa]; + + return; + } + + if (oury == desty) { + mlsp->xpermove[aaa] = move_speed_x; + mlsp->ypermove[aaa] = 0; + if (destx < ourx) + mlsp->xpermove[aaa] = -mlsp->xpermove[aaa]; + + return; + } + + fixed xdist = itofix(abs(ourx - destx)); + fixed ydist = itofix(abs(oury - desty)); + + fixed useMoveSpeed; + + if (move_speed_x == move_speed_y) { + useMoveSpeed = move_speed_x; + } else { + // different X and Y move speeds + // the X proportion of the movement is (x / (x + y)) + fixed xproportion = fixdiv(xdist, (xdist + ydist)); + + if (move_speed_x > move_speed_y) { + // speed = y + ((1 - xproportion) * (x - y)) + useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y); + } else { + // speed = x + (xproportion * (y - x)) + useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x); + } + } + + fixed angl = fixatan(fixdiv(ydist, xdist)); + + // now, since new opp=hyp*sin, work out the Y step size + //fixed newymove = useMoveSpeed * fsin(angl); + fixed newymove = fixmul(useMoveSpeed, fixsin(angl)); + + // since adj=hyp*cos, work out X step size + //fixed newxmove = useMoveSpeed * fcos(angl); + fixed newxmove = fixmul(useMoveSpeed, fixcos(angl)); + + if (destx < ourx) + newxmove = -newxmove; + if (desty < oury) + newymove = -newymove; + + mlsp->xpermove[aaa] = newxmove; + mlsp->ypermove[aaa] = newymove; } -int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) -{ - int i; +int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) { + int i; - wallscreen = onscreen; + wallscreen = onscreen; - num_navpoints = 0; + num_navpoints = 0; - if (ignore_walls || can_see_from(srcx, srcy, xx, yy)) - { - num_navpoints = 2; - navpoints[0] = MAKE_INTCOORD(srcx, srcy); - navpoints[1] = MAKE_INTCOORD(xx, yy); - } else { - if ((nocross == 0) && (wallscreen->GetPixel(xx, yy) == 0)) - return 0; // clicked on a wall + if (ignore_walls || can_see_from(srcx, srcy, xx, yy)) { + num_navpoints = 2; + navpoints[0] = MAKE_INTCOORD(srcx, srcy); + navpoints[1] = MAKE_INTCOORD(xx, yy); + } else { + if ((nocross == 0) && (wallscreen->GetPixel(xx, yy) == 0)) + return 0; // clicked on a wall - find_route_jps(srcx, srcy, xx, yy); - } + find_route_jps(srcx, srcy, xx, yy); + } - if (!num_navpoints) - return 0; + if (!num_navpoints) + return 0; - // FIXME: really necessary? - if (num_navpoints == 1) - navpoints[num_navpoints++] = navpoints[0]; + // FIXME: really necessary? + if (num_navpoints == 1) + navpoints[num_navpoints++] = navpoints[0]; - assert(num_navpoints <= MAXNAVPOINTS); + assert(num_navpoints <= MAXNAVPOINTS); #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stages", srcx,srcy,xx,yy,num_navpoints); + AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stages", srcx, srcy, xx, yy, num_navpoints); #endif - int mlist = movlst; - mls[mlist].numstage = num_navpoints; - memcpy(&mls[mlist].pos[0], &navpoints[0], sizeof(int) * num_navpoints); + int mlist = movlst; + mls[mlist].numstage = num_navpoints; + memcpy(&mls[mlist].pos[0], &navpoints[0], sizeof(int) * num_navpoints); #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stages: %d\n",num_navpoints); + AGS::Common::Debug::Printf("stages: %d\n", num_navpoints); #endif - for (i=0; i=320) | (y>=200) | (x<0) | (y<0)) line_failed=1; - else */ if (getpixel(bmpp, x, y) < 1) - line_failed = 1; - else if (line_failed == 0) { - lastcx = x; - lastcy = y; - } +static void line_callback(BITMAP *bmpp, int x, int y, int d) { + /* if ((x>=320) | (y>=200) | (x<0) | (y<0)) line_failed=1; + else */ if (getpixel(bmpp, x, y) < 1) + line_failed = 1; + else if (line_failed == 0) { + lastcx = x; + lastcy = y; + } } -int can_see_from(int x1, int y1, int x2, int y2) -{ - assert(wallscreen != nullptr); +int can_see_from(int x1, int y1, int x2, int y2) { + assert(wallscreen != nullptr); - line_failed = 0; - lastcx = x1; - lastcy = y1; + line_failed = 0; + lastcx = x1; + lastcy = y1; - if ((x1 == x2) && (y1 == y2)) - return 1; + if ((x1 == x2) && (y1 == y2)) + return 1; - // TODO: need some way to use Bitmap with callback - do_line((BITMAP*)wallscreen->GetAllegroBitmap(), x1, y1, x2, y2, 0, line_callback); - if (line_failed == 0) - return 1; + // TODO: need some way to use Bitmap with callback + do_line((BITMAP *)wallscreen->GetAllegroBitmap(), x1, y1, x2, y2, 0, line_callback); + if (line_failed == 0) + return 1; - return 0; + return 0; } void get_lastcpos(int &lastcx_, int &lastcy_) { - lastcx_ = lastcx; - lastcy_ = lastcy; + lastcx_ = lastcx; + lastcy_ = lastcy; } -int find_nearest_walkable_area(Bitmap *tempw, int fromX, int fromY, int toX, int toY, int destX, int destY, int granularity) -{ - assert(tempw != nullptr); - - int ex, ey, nearest = 99999, thisis, nearx, neary; - if (fromX < 0) fromX = 0; - if (fromY < 0) fromY = 0; - if (toX >= tempw->GetWidth()) toX = tempw->GetWidth() - 1; - if (toY >= tempw->GetHeight()) toY = tempw->GetHeight() - 1; - - for (ex = fromX; ex < toX; ex += granularity) - { - for (ey = fromY; ey < toY; ey += granularity) - { - if (tempw->GetScanLine(ey)[ex] != 232) - continue; - - thisis = (int)::sqrt((double)((ex - destX) * (ex - destX) + (ey - destY) * (ey - destY))); - if (thisis < nearest) - { - nearest = thisis; - nearx = ex; - neary = ey; - } - } - } - - if (nearest < 90000) { - suggestx = nearx; - suggesty = neary; - return 1; - } - - return 0; +int find_nearest_walkable_area(Bitmap *tempw, int fromX, int fromY, int toX, int toY, int destX, int destY, int granularity) { + assert(tempw != nullptr); + + int ex, ey, nearest = 99999, thisis, nearx, neary; + if (fromX < 0) fromX = 0; + if (fromY < 0) fromY = 0; + if (toX >= tempw->GetWidth()) toX = tempw->GetWidth() - 1; + if (toY >= tempw->GetHeight()) toY = tempw->GetHeight() - 1; + + for (ex = fromX; ex < toX; ex += granularity) { + for (ey = fromY; ey < toY; ey += granularity) { + if (tempw->GetScanLine(ey)[ex] != 232) + continue; + + thisis = (int)::sqrt((double)((ex - destX) * (ex - destX) + (ey - destY) * (ey - destY))); + if (thisis < nearest) { + nearest = thisis; + nearx = ex; + neary = ey; + } + } + } + + if (nearest < 90000) { + suggestx = nearx; + suggesty = neary; + return 1; + } + + return 0; } #define MAX_GRANULARITY 3 static int walk_area_granularity[MAX_WALK_AREAS + 1]; -static int is_route_possible(int fromx, int fromy, int tox, int toy, Bitmap *wss) -{ - wallscreen = wss; - suggestx = -1; - - // ensure it's a memory bitmap, so we can use direct access to line[] array - if ((wss == nullptr) || (!wss->IsMemoryBitmap()) || (wss->GetColorDepth() != 8)) - quit("is_route_possible: invalid walkable areas bitmap supplied"); - - if (wallscreen->GetPixel(fromx, fromy) < 1) - return 0; - - Bitmap *tempw = BitmapHelper::CreateBitmapCopy(wallscreen, 8); - - if (tempw == nullptr) - quit("no memory for route calculation"); - if (!tempw->IsMemoryBitmap()) - quit("tempw is not memory bitmap"); - - int dd, ff; - // initialize array for finding widths of walkable areas - int thisar, inarow = 0, lastarea = 0; - int walk_area_times[MAX_WALK_AREAS + 1]; - for (dd = 0; dd <= MAX_WALK_AREAS; dd++) { - walk_area_times[dd] = 0; - walk_area_granularity[dd] = 0; - } - - for (ff = 0; ff < tempw->GetHeight(); ff++) { - const uint8_t *tempw_scanline = tempw->GetScanLine(ff); - for (dd = 0; dd < tempw->GetWidth(); dd++) { - thisar = tempw_scanline[dd]; - // count how high the area is at this point - if ((thisar == lastarea) && (thisar > 0)) - inarow++; - else if (lastarea > MAX_WALK_AREAS) - quit("!Calculate_Route: invalid colours in walkable area mask"); - else if (lastarea != 0) { - walk_area_granularity[lastarea] += inarow; - walk_area_times[lastarea]++; - inarow = 0; - } - lastarea = thisar; - } - } - - for (dd = 0; dd < tempw->GetWidth(); dd++) { - for (ff = 0; ff < tempw->GetHeight(); ff++) { - uint8_t *tempw_scanline = tempw->GetScanLineForWriting(ff); - thisar = tempw_scanline[dd]; - if (thisar > 0) - tempw_scanline[dd] = 1; - // count how high the area is at this point - if ((thisar == lastarea) && (thisar > 0)) - inarow++; - else if (lastarea != 0) { - walk_area_granularity[lastarea] += inarow; - walk_area_times[lastarea]++; - inarow = 0; - } - lastarea = thisar; - } - } - - // find the average "width" of a path in this walkable area - for (dd = 1; dd <= MAX_WALK_AREAS; dd++) { - if (walk_area_times[dd] == 0) { - walk_area_granularity[dd] = MAX_GRANULARITY; - continue; - } - - walk_area_granularity[dd] /= walk_area_times[dd]; - if (walk_area_granularity[dd] <= 4) - walk_area_granularity[dd] = 2; - else if (walk_area_granularity[dd] <= 15) - walk_area_granularity[dd] = 3; - else - walk_area_granularity[dd] = MAX_GRANULARITY; +static int is_route_possible(int fromx, int fromy, int tox, int toy, Bitmap *wss) { + wallscreen = wss; + suggestx = -1; + + // ensure it's a memory bitmap, so we can use direct access to line[] array + if ((wss == nullptr) || (!wss->IsMemoryBitmap()) || (wss->GetColorDepth() != 8)) + quit("is_route_possible: invalid walkable areas bitmap supplied"); + + if (wallscreen->GetPixel(fromx, fromy) < 1) + return 0; + + Bitmap *tempw = BitmapHelper::CreateBitmapCopy(wallscreen, 8); + + if (tempw == nullptr) + quit("no memory for route calculation"); + if (!tempw->IsMemoryBitmap()) + quit("tempw is not memory bitmap"); + + int dd, ff; + // initialize array for finding widths of walkable areas + int thisar, inarow = 0, lastarea = 0; + int walk_area_times[MAX_WALK_AREAS + 1]; + for (dd = 0; dd <= MAX_WALK_AREAS; dd++) { + walk_area_times[dd] = 0; + walk_area_granularity[dd] = 0; + } + + for (ff = 0; ff < tempw->GetHeight(); ff++) { + const uint8_t *tempw_scanline = tempw->GetScanLine(ff); + for (dd = 0; dd < tempw->GetWidth(); dd++) { + thisar = tempw_scanline[dd]; + // count how high the area is at this point + if ((thisar == lastarea) && (thisar > 0)) + inarow++; + else if (lastarea > MAX_WALK_AREAS) + quit("!Calculate_Route: invalid colours in walkable area mask"); + else if (lastarea != 0) { + walk_area_granularity[lastarea] += inarow; + walk_area_times[lastarea]++; + inarow = 0; + } + lastarea = thisar; + } + } + + for (dd = 0; dd < tempw->GetWidth(); dd++) { + for (ff = 0; ff < tempw->GetHeight(); ff++) { + uint8_t *tempw_scanline = tempw->GetScanLineForWriting(ff); + thisar = tempw_scanline[dd]; + if (thisar > 0) + tempw_scanline[dd] = 1; + // count how high the area is at this point + if ((thisar == lastarea) && (thisar > 0)) + inarow++; + else if (lastarea != 0) { + walk_area_granularity[lastarea] += inarow; + walk_area_times[lastarea]++; + inarow = 0; + } + lastarea = thisar; + } + } + + // find the average "width" of a path in this walkable area + for (dd = 1; dd <= MAX_WALK_AREAS; dd++) { + if (walk_area_times[dd] == 0) { + walk_area_granularity[dd] = MAX_GRANULARITY; + continue; + } + + walk_area_granularity[dd] /= walk_area_times[dd]; + if (walk_area_granularity[dd] <= 4) + walk_area_granularity[dd] = 2; + else if (walk_area_granularity[dd] <= 15) + walk_area_granularity[dd] = 3; + else + walk_area_granularity[dd] = MAX_GRANULARITY; #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("area %d: Gran %d", dd, walk_area_granularity[dd]); + AGS::Common::Debug::Printf("area %d: Gran %d", dd, walk_area_granularity[dd]); #endif - } - walk_area_granularity[0] = MAX_GRANULARITY; - - tempw->FloodFill(fromx, fromy, 232); - if (tempw->GetPixel(tox, toy) != 232) - { - // Destination pixel is not walkable - // Try the 100x100 square around the target first at 3-pixel granularity - int tryFirstX = tox - 50, tryToX = tox + 50; - int tryFirstY = toy - 50, tryToY = toy + 50; - - if (!find_nearest_walkable_area(tempw, tryFirstX, tryFirstY, tryToX, tryToY, tox, toy, 3)) - { - // Nothing found, sweep the whole room at 5 pixel granularity - find_nearest_walkable_area(tempw, 0, 0, tempw->GetWidth(), tempw->GetHeight(), tox, toy, 5); - } - - delete tempw; - return 0; - } - delete tempw; - - return 1; + } + walk_area_granularity[0] = MAX_GRANULARITY; + + tempw->FloodFill(fromx, fromy, 232); + if (tempw->GetPixel(tox, toy) != 232) { + // Destination pixel is not walkable + // Try the 100x100 square around the target first at 3-pixel granularity + int tryFirstX = tox - 50, tryToX = tox + 50; + int tryFirstY = toy - 50, tryToY = toy + 50; + + if (!find_nearest_walkable_area(tempw, tryFirstX, tryFirstY, tryToX, tryToY, tox, toy, 3)) { + // Nothing found, sweep the whole room at 5 pixel granularity + find_nearest_walkable_area(tempw, 0, 0, tempw->GetWidth(), tempw->GetHeight(), tox, toy, 5); + } + + delete tempw; + return 0; + } + delete tempw; + + return 1; } static int leftorright = 0; @@ -281,661 +270,640 @@ static const int BEENHERE_SIZE = 2; #define DIR_UP 1 #define DIR_DOWN 3 -static int try_this_square(int srcx, int srcy, int tox, int toy) -{ - assert(pathbackx != nullptr); - assert(pathbacky != nullptr); - assert(beenhere != nullptr); +static int try_this_square(int srcx, int srcy, int tox, int toy) { + assert(pathbackx != nullptr); + assert(pathbacky != nullptr); + assert(beenhere != nullptr); - if (beenhere[srcy][srcx] & 0x80) - return 0; + if (beenhere[srcy][srcx] & 0x80) + return 0; - // nesting of 8040 leads to stack overflow - if (nesting > 7000) - return 0; + // nesting of 8040 leads to stack overflow + if (nesting > 7000) + return 0; - nesting++; - if (can_see_from(srcx, srcy, tox, toy)) { - finalpartx = srcx; - finalparty = srcy; - nesting--; - pathbackstage = 0; - return 2; - } + nesting++; + if (can_see_from(srcx, srcy, tox, toy)) { + finalpartx = srcx; + finalparty = srcy; + nesting--; + pathbackstage = 0; + return 2; + } #ifdef DEBUG_PATHFINDER - // wputblock(lastcx, lastcy, mousecurs[C_CROSS], 1); + // wputblock(lastcx, lastcy, mousecurs[C_CROSS], 1); #endif - int trydir = DIR_UP; - int xdiff = abs(srcx - tox), ydiff = abs(srcy - toy); - if (ydiff > xdiff) { - if (srcy > toy) - trydir = DIR_UP; - else - trydir = DIR_DOWN; - } else if (srcx > tox) - trydir = DIR_LEFT; - else if (srcx < tox) - trydir = DIR_RIGHT; + int trydir = DIR_UP; + int xdiff = abs(srcx - tox), ydiff = abs(srcy - toy); + if (ydiff > xdiff) { + if (srcy > toy) + trydir = DIR_UP; + else + trydir = DIR_DOWN; + } else if (srcx > tox) + trydir = DIR_LEFT; + else if (srcx < tox) + trydir = DIR_RIGHT; - int iterations = 0; + int iterations = 0; try_again: - int nextx = srcx, nexty = srcy; - if (trydir == DIR_LEFT) - nextx--; - else if (trydir == DIR_RIGHT) - nextx++; - else if (trydir == DIR_DOWN) - nexty++; - else if (trydir == DIR_UP) - nexty--; - - iterations++; - if (iterations > 5) { + int nextx = srcx, nexty = srcy; + if (trydir == DIR_LEFT) + nextx--; + else if (trydir == DIR_RIGHT) + nextx++; + else if (trydir == DIR_DOWN) + nexty++; + else if (trydir == DIR_UP) + nexty--; + + iterations++; + if (iterations > 5) { #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("not found: %d,%d beenhere 0x%X\n",srcx,srcy,beenhere[srcy][srcx]); + AGS::Common::Debug::Printf("not found: %d,%d beenhere 0x%X\n", srcx, srcy, beenhere[srcy][srcx]); #endif - nesting--; - return 0; - } - - if (((nextx < 0) | (nextx >= wallscreen->GetWidth()) | (nexty < 0) | (nexty >= wallscreen->GetHeight())) || - (wallscreen->GetPixel(nextx, nexty) == 0) || ((beenhere[srcy][srcx] & (1 << trydir)) != 0)) { - - if (leftorright == 0) { - trydir++; - if (trydir > 3) - trydir = 0; - } else { - trydir--; - if (trydir < 0) - trydir = 3; - } - goto try_again; - } - beenhere[srcy][srcx] |= (1 << trydir); + nesting--; + return 0; + } + + if (((nextx < 0) | (nextx >= wallscreen->GetWidth()) | (nexty < 0) | (nexty >= wallscreen->GetHeight())) || + (wallscreen->GetPixel(nextx, nexty) == 0) || ((beenhere[srcy][srcx] & (1 << trydir)) != 0)) { + + if (leftorright == 0) { + trydir++; + if (trydir > 3) + trydir = 0; + } else { + trydir--; + if (trydir < 0) + trydir = 3; + } + goto try_again; + } + beenhere[srcy][srcx] |= (1 << trydir); // srcx=nextx; srcy=nexty; - beenhere[srcy][srcx] |= 0x80; // being processed - - int retcod = try_this_square(nextx, nexty, tox, toy); - if (retcod == 0) - goto try_again; - - nesting--; - beenhere[srcy][srcx] &= 0x7f; - if (retcod == 2) { - pathbackx[pathbackstage] = srcx; - pathbacky[pathbackstage] = srcy; - pathbackstage++; - if (pathbackstage >= MAXPATHBACK - 1) - return 0; - - return 2; - } - return 1; + beenhere[srcy][srcx] |= 0x80; // being processed + + int retcod = try_this_square(nextx, nexty, tox, toy); + if (retcod == 0) + goto try_again; + + nesting--; + beenhere[srcy][srcx] &= 0x7f; + if (retcod == 2) { + pathbackx[pathbackstage] = srcx; + pathbacky[pathbackstage] = srcy; + pathbackstage++; + if (pathbackstage >= MAXPATHBACK - 1) + return 0; + + return 2; + } + return 1; } #define CHECK_MIN(cellx, celly) { \ - if (beenhere[celly][cellx] == -1) {\ - adjcount = 0; \ - if ((wallscreen->GetScanLine(celly)[cellx] != 0) && (beenhere[j][i]+modifier <= min)) {\ - if (beenhere[j][i]+modifier < min) { \ - min = beenhere[j][i]+modifier; \ - numfound = 0; } \ - if (numfound < 40) { \ - newcell[numfound] = (celly) * wallscreen->GetWidth() + (cellx);\ - cheapest[numfound] = j * wallscreen->GetWidth() + i;\ - numfound++; \ - }\ - } \ - }} + if (beenhere[celly][cellx] == -1) {\ + adjcount = 0; \ + if ((wallscreen->GetScanLine(celly)[cellx] != 0) && (beenhere[j][i]+modifier <= min)) {\ + if (beenhere[j][i]+modifier < min) { \ + min = beenhere[j][i]+modifier; \ + numfound = 0; } \ + if (numfound < 40) { \ + newcell[numfound] = (celly) * wallscreen->GetWidth() + (cellx);\ + cheapest[numfound] = j * wallscreen->GetWidth() + i;\ + numfound++; \ + }\ + } \ + }} #define MAX_TRAIL_LENGTH 5000 // Round down the supplied co-ordinates to the area granularity, // and move a bit if this causes them to become non-walkable -static void round_down_coords(int &tmpx, int &tmpy) -{ - assert(wallscreen != nullptr); +static void round_down_coords(int &tmpx, int &tmpy) { + assert(wallscreen != nullptr); - int startgran = walk_area_granularity[wallscreen->GetPixel(tmpx, tmpy)]; - tmpy = tmpy - tmpy % startgran; + int startgran = walk_area_granularity[wallscreen->GetPixel(tmpx, tmpy)]; + tmpy = tmpy - tmpy % startgran; - if (tmpy < 0) - tmpy = 0; + if (tmpy < 0) + tmpy = 0; - tmpx = tmpx - tmpx % startgran; - if (tmpx < 0) - tmpx = 0; + tmpx = tmpx - tmpx % startgran; + if (tmpx < 0) + tmpx = 0; - if (wallscreen->GetPixel(tmpx, tmpy) == 0) { - tmpx += startgran; - if ((wallscreen->GetPixel(tmpx, tmpy) == 0) && (tmpy < wallscreen->GetHeight() - startgran)) { - tmpy += startgran; + if (wallscreen->GetPixel(tmpx, tmpy) == 0) { + tmpx += startgran; + if ((wallscreen->GetPixel(tmpx, tmpy) == 0) && (tmpy < wallscreen->GetHeight() - startgran)) { + tmpy += startgran; - if (wallscreen->GetPixel(tmpx, tmpy) == 0) - tmpx -= startgran; - } - } + if (wallscreen->GetPixel(tmpx, tmpy) == 0) + tmpx -= startgran; + } + } } -static int find_route_dijkstra(int fromx, int fromy, int destx, int desty) -{ - int i, j; - - assert(wallscreen != nullptr); - assert(pathbackx != nullptr); - assert(pathbacky != nullptr); - assert(beenhere != nullptr); - - // This algorithm doesn't behave differently the second time, so ignore - if (leftorright == 1) - return 0; - - for (i = 0; i < wallscreen->GetHeight(); i++) - memset(&beenhere[i][0], 0xff, wallscreen->GetWidth() * BEENHERE_SIZE); - - round_down_coords(fromx, fromy); - beenhere[fromy][fromx] = 0; - - int temprd = destx, tempry = desty; - round_down_coords(temprd, tempry); - if ((temprd == fromx) && (tempry == fromy)) { - // already at destination - pathbackstage = 0; - return 1; - } - - int allocsize = int (wallscreen->GetWidth()) * int (wallscreen->GetHeight()) * sizeof(int); - int *parent = (int *)malloc(allocsize); - int min = 999999, cheapest[40], newcell[40], replace[40]; - int *visited = (int *)malloc(MAX_TRAIL_LENGTH * sizeof(int)); - int iteration = 1; - visited[0] = fromy * wallscreen->GetWidth() + fromx; - parent[visited[0]] = -1; - - int granularity = 3, newx = -1, newy, foundAnswer = -1, numreplace; - int changeiter, numfound, adjcount; - int destxlow = destx - MAX_GRANULARITY; - int destylow = desty - MAX_GRANULARITY; - int destxhi = destxlow + MAX_GRANULARITY * 2; - int destyhi = destylow + MAX_GRANULARITY * 2; - int modifier = 0; - int totalfound = 0; - int DIRECTION_BONUS = 0; - - update_polled_stuff_if_runtime(); - - while (foundAnswer < 0) { - min = 29999; - changeiter = iteration; - numfound = 0; - numreplace = 0; - - for (int n = 0; n < iteration; n++) { - if (visited[n] == -1) - continue; - - i = visited[n] % wallscreen->GetWidth(); - j = visited[n] / wallscreen->GetWidth(); - granularity = walk_area_granularity[wallscreen->GetScanLine(j)[i]]; - adjcount = 1; - - if (i >= granularity) { - modifier = (destx < i) ? DIRECTION_BONUS : 0; - CHECK_MIN(i - granularity, j) - } - - if (j >= granularity) { - modifier = (desty < j) ? DIRECTION_BONUS : 0; - CHECK_MIN(i, j - granularity) - } - - if (i < wallscreen->GetWidth() - granularity) { - modifier = (destx > i) ? DIRECTION_BONUS : 0; - CHECK_MIN(i + granularity, j) - } - - if (j < wallscreen->GetHeight() - granularity) { - modifier = (desty > j) ? DIRECTION_BONUS : 0; - CHECK_MIN(i, j + granularity) - } - - // If all the adjacent cells have been done, stop checking this one - if (adjcount) { - if (numreplace < 40) { - visited[numreplace] = -1; - replace[numreplace] = n; - numreplace++; - } - } - } - - if (numfound == 0) { - free(visited); - free(parent); - return 0; - } - - totalfound += numfound; - for (int p = 0; p < numfound; p++) { - newx = newcell[p] % wallscreen->GetWidth(); - newy = newcell[p] / wallscreen->GetWidth(); - beenhere[newy][newx] = beenhere[cheapest[p] / wallscreen->GetWidth()][cheapest[p] % wallscreen->GetWidth()] + 1; +static int find_route_dijkstra(int fromx, int fromy, int destx, int desty) { + int i, j; + + assert(wallscreen != nullptr); + assert(pathbackx != nullptr); + assert(pathbacky != nullptr); + assert(beenhere != nullptr); + + // This algorithm doesn't behave differently the second time, so ignore + if (leftorright == 1) + return 0; + + for (i = 0; i < wallscreen->GetHeight(); i++) + memset(&beenhere[i][0], 0xff, wallscreen->GetWidth() * BEENHERE_SIZE); + + round_down_coords(fromx, fromy); + beenhere[fromy][fromx] = 0; + + int temprd = destx, tempry = desty; + round_down_coords(temprd, tempry); + if ((temprd == fromx) && (tempry == fromy)) { + // already at destination + pathbackstage = 0; + return 1; + } + + int allocsize = int (wallscreen->GetWidth()) * int (wallscreen->GetHeight()) * sizeof(int); + int *parent = (int *)malloc(allocsize); + int min = 999999, cheapest[40], newcell[40], replace[40]; + int *visited = (int *)malloc(MAX_TRAIL_LENGTH * sizeof(int)); + int iteration = 1; + visited[0] = fromy * wallscreen->GetWidth() + fromx; + parent[visited[0]] = -1; + + int granularity = 3, newx = -1, newy, foundAnswer = -1, numreplace; + int changeiter, numfound, adjcount; + int destxlow = destx - MAX_GRANULARITY; + int destylow = desty - MAX_GRANULARITY; + int destxhi = destxlow + MAX_GRANULARITY * 2; + int destyhi = destylow + MAX_GRANULARITY * 2; + int modifier = 0; + int totalfound = 0; + int DIRECTION_BONUS = 0; + + update_polled_stuff_if_runtime(); + + while (foundAnswer < 0) { + min = 29999; + changeiter = iteration; + numfound = 0; + numreplace = 0; + + for (int n = 0; n < iteration; n++) { + if (visited[n] == -1) + continue; + + i = visited[n] % wallscreen->GetWidth(); + j = visited[n] / wallscreen->GetWidth(); + granularity = walk_area_granularity[wallscreen->GetScanLine(j)[i]]; + adjcount = 1; + + if (i >= granularity) { + modifier = (destx < i) ? DIRECTION_BONUS : 0; + CHECK_MIN(i - granularity, j) + } + + if (j >= granularity) { + modifier = (desty < j) ? DIRECTION_BONUS : 0; + CHECK_MIN(i, j - granularity) + } + + if (i < wallscreen->GetWidth() - granularity) { + modifier = (destx > i) ? DIRECTION_BONUS : 0; + CHECK_MIN(i + granularity, j) + } + + if (j < wallscreen->GetHeight() - granularity) { + modifier = (desty > j) ? DIRECTION_BONUS : 0; + CHECK_MIN(i, j + granularity) + } + + // If all the adjacent cells have been done, stop checking this one + if (adjcount) { + if (numreplace < 40) { + visited[numreplace] = -1; + replace[numreplace] = n; + numreplace++; + } + } + } + + if (numfound == 0) { + free(visited); + free(parent); + return 0; + } + + totalfound += numfound; + for (int p = 0; p < numfound; p++) { + newx = newcell[p] % wallscreen->GetWidth(); + newy = newcell[p] / wallscreen->GetWidth(); + beenhere[newy][newx] = beenhere[cheapest[p] / wallscreen->GetWidth()][cheapest[p] % wallscreen->GetWidth()] + 1; // int wal = walk_area_granularity[->GetPixel(wallscreen, newx, newy)]; // beenhere[newy - newy%wal][newx - newx%wal] = beenhere[newy][newx]; - parent[newcell[p]] = cheapest[p]; - - // edges of screen pose a problem, so if current and dest are within - // certain distance of the edge, say we've got it - if ((newx >= wallscreen->GetWidth() - MAX_GRANULARITY) && (destx >= wallscreen->GetWidth() - MAX_GRANULARITY)) - newx = destx; - - if ((newy >= wallscreen->GetHeight() - MAX_GRANULARITY) && (desty >= wallscreen->GetHeight() - MAX_GRANULARITY)) - newy = desty; - - // Found the desination, abort loop - if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) - && (newy <= destyhi)) { - foundAnswer = newcell[p]; - break; - } - - if (totalfound >= 1000) { - //Doesn't work cos it can see the destination from the point that's - //not nearest - // every so often, check if we can see the destination - if (can_see_from(newx, newy, destx, desty)) { - DIRECTION_BONUS -= 50; - totalfound = 0; - } - - } - - if (numreplace > 0) { - numreplace--; - changeiter = replace[numreplace]; - } else - changeiter = iteration; - - visited[changeiter] = newcell[p]; - if (changeiter == iteration) - iteration++; - - changeiter = iteration; - if (iteration >= MAX_TRAIL_LENGTH) { - free(visited); - free(parent); - return 0; - } - } - if (totalfound >= 1000) { - update_polled_stuff_if_runtime(); - totalfound = 0; - } - } - free(visited); - - int on; - pathbackstage = 0; - pathbackx[pathbackstage] = destx; - pathbacky[pathbackstage] = desty; - pathbackstage++; - - for (on = parent[foundAnswer];; on = parent[on]) { - if (on == -1) - break; - - newx = on % wallscreen->GetWidth(); - newy = on / wallscreen->GetWidth(); - if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) - && (newy <= destyhi)) - break; - - pathbackx[pathbackstage] = on % wallscreen->GetWidth(); - pathbacky[pathbackstage] = on / wallscreen->GetWidth(); - pathbackstage++; - if (pathbackstage >= MAXPATHBACK) { - free(parent); - return 0; - } - } - free(parent); - return 1; + parent[newcell[p]] = cheapest[p]; + + // edges of screen pose a problem, so if current and dest are within + // certain distance of the edge, say we've got it + if ((newx >= wallscreen->GetWidth() - MAX_GRANULARITY) && (destx >= wallscreen->GetWidth() - MAX_GRANULARITY)) + newx = destx; + + if ((newy >= wallscreen->GetHeight() - MAX_GRANULARITY) && (desty >= wallscreen->GetHeight() - MAX_GRANULARITY)) + newy = desty; + + // Found the desination, abort loop + if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) + && (newy <= destyhi)) { + foundAnswer = newcell[p]; + break; + } + + if (totalfound >= 1000) { + //Doesn't work cos it can see the destination from the point that's + //not nearest + // every so often, check if we can see the destination + if (can_see_from(newx, newy, destx, desty)) { + DIRECTION_BONUS -= 50; + totalfound = 0; + } + + } + + if (numreplace > 0) { + numreplace--; + changeiter = replace[numreplace]; + } else + changeiter = iteration; + + visited[changeiter] = newcell[p]; + if (changeiter == iteration) + iteration++; + + changeiter = iteration; + if (iteration >= MAX_TRAIL_LENGTH) { + free(visited); + free(parent); + return 0; + } + } + if (totalfound >= 1000) { + update_polled_stuff_if_runtime(); + totalfound = 0; + } + } + free(visited); + + int on; + pathbackstage = 0; + pathbackx[pathbackstage] = destx; + pathbacky[pathbackstage] = desty; + pathbackstage++; + + for (on = parent[foundAnswer];; on = parent[on]) { + if (on == -1) + break; + + newx = on % wallscreen->GetWidth(); + newy = on / wallscreen->GetWidth(); + if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) + && (newy <= destyhi)) + break; + + pathbackx[pathbackstage] = on % wallscreen->GetWidth(); + pathbacky[pathbackstage] = on / wallscreen->GetWidth(); + pathbackstage++; + if (pathbackstage >= MAXPATHBACK) { + free(parent); + return 0; + } + } + free(parent); + return 1; } -static int __find_route(int srcx, int srcy, short *tox, short *toy, int noredx) -{ - assert(wallscreen != nullptr); - assert(beenhere != nullptr); - assert(tox != nullptr); - assert(toy != nullptr); +static int __find_route(int srcx, int srcy, short *tox, short *toy, int noredx) { + assert(wallscreen != nullptr); + assert(beenhere != nullptr); + assert(tox != nullptr); + assert(toy != nullptr); - if ((noredx == 0) && (wallscreen->GetPixel(tox[0], toy[0]) == 0)) - return 0; // clicked on a wall + if ((noredx == 0) && (wallscreen->GetPixel(tox[0], toy[0]) == 0)) + return 0; // clicked on a wall - pathbackstage = 0; + pathbackstage = 0; - if (leftorright == 0) { - waspossible = 1; + if (leftorright == 0) { + waspossible = 1; findroutebk: - if ((srcx == tox[0]) && (srcy == toy[0])) { - pathbackstage = 0; - return 1; - } - - if ((waspossible = is_route_possible(srcx, srcy, tox[0], toy[0], wallscreen)) == 0) { - if (suggestx >= 0) { - tox[0] = suggestx; - toy[0] = suggesty; - goto findroutebk; - } - return 0; - } - } - - if (leftorright == 1) { - if (waspossible == 0) - return 0; - } - - // Try the new pathfinding algorithm - if (find_route_dijkstra(srcx, srcy, tox[0], toy[0])) { - return 1; - } - - // if the new pathfinder failed, try the old one - pathbackstage = 0; - memset(&beenhere[0][0], 0, wallscreen->GetWidth() * wallscreen->GetHeight() * BEENHERE_SIZE); - if (try_this_square(srcx, srcy, tox[0], toy[0]) == 0) - return 0; - - return 1; + if ((srcx == tox[0]) && (srcy == toy[0])) { + pathbackstage = 0; + return 1; + } + + if ((waspossible = is_route_possible(srcx, srcy, tox[0], toy[0], wallscreen)) == 0) { + if (suggestx >= 0) { + tox[0] = suggestx; + toy[0] = suggesty; + goto findroutebk; + } + return 0; + } + } + + if (leftorright == 1) { + if (waspossible == 0) + return 0; + } + + // Try the new pathfinding algorithm + if (find_route_dijkstra(srcx, srcy, tox[0], toy[0])) { + return 1; + } + + // if the new pathfinder failed, try the old one + pathbackstage = 0; + memset(&beenhere[0][0], 0, wallscreen->GetWidth() * wallscreen->GetHeight() * BEENHERE_SIZE); + if (try_this_square(srcx, srcy, tox[0], toy[0]) == 0) + return 0; + + return 1; } -void set_route_move_speed(int speed_x, int speed_y) -{ - // negative move speeds like -2 get converted to 1/2 - if (speed_x < 0) { - move_speed_x = itofix(1) / (-speed_x); - } - else { - move_speed_x = itofix(speed_x); - } - - if (speed_y < 0) { - move_speed_y = itofix(1) / (-speed_y); - } - else { - move_speed_y = itofix(speed_y); - } +void set_route_move_speed(int speed_x, int speed_y) { + // negative move speeds like -2 get converted to 1/2 + if (speed_x < 0) { + move_speed_x = itofix(1) / (-speed_x); + } else { + move_speed_x = itofix(speed_x); + } + + if (speed_y < 0) { + move_speed_y = itofix(1) / (-speed_y); + } else { + move_speed_y = itofix(speed_y); + } } // Calculates the X and Y per game loop, for this stage of the // movelist -void calculate_move_stage(MoveList * mlsp, int aaa) -{ - assert(mlsp != nullptr); - - // work out the x & y per move. First, opp/adj=tan, so work out the angle - if (mlsp->pos[aaa] == mlsp->pos[aaa + 1]) { - mlsp->xpermove[aaa] = 0; - mlsp->ypermove[aaa] = 0; - return; - } - - short ourx = (mlsp->pos[aaa] >> 16) & 0x000ffff; - short oury = (mlsp->pos[aaa] & 0x000ffff); - short destx = ((mlsp->pos[aaa + 1] >> 16) & 0x000ffff); - short desty = (mlsp->pos[aaa + 1] & 0x000ffff); - - // Special case for vertical and horizontal movements - if (ourx == destx) { - mlsp->xpermove[aaa] = 0; - mlsp->ypermove[aaa] = move_speed_y; - if (desty < oury) - mlsp->ypermove[aaa] = -mlsp->ypermove[aaa]; - - return; - } - - if (oury == desty) { - mlsp->xpermove[aaa] = move_speed_x; - mlsp->ypermove[aaa] = 0; - if (destx < ourx) - mlsp->xpermove[aaa] = -mlsp->xpermove[aaa]; - - return; - } - - fixed xdist = itofix(abs(ourx - destx)); - fixed ydist = itofix(abs(oury - desty)); - - fixed useMoveSpeed; - - if (move_speed_x == move_speed_y) { - useMoveSpeed = move_speed_x; - } - else { - // different X and Y move speeds - // the X proportion of the movement is (x / (x + y)) - fixed xproportion = fixdiv(xdist, (xdist + ydist)); - - if (move_speed_x > move_speed_y) { - // speed = y + ((1 - xproportion) * (x - y)) - useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y); - } - else { - // speed = x + (xproportion * (y - x)) - useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x); - } - } - - fixed angl = fixatan(fixdiv(ydist, xdist)); - - // now, since new opp=hyp*sin, work out the Y step size - //fixed newymove = useMoveSpeed * fsin(angl); - fixed newymove = fixmul(useMoveSpeed, fixsin(angl)); - - // since adj=hyp*cos, work out X step size - //fixed newxmove = useMoveSpeed * fcos(angl); - fixed newxmove = fixmul(useMoveSpeed, fixcos(angl)); - - if (destx < ourx) - newxmove = -newxmove; - if (desty < oury) - newymove = -newymove; - - mlsp->xpermove[aaa] = newxmove; - mlsp->ypermove[aaa] = newymove; +void calculate_move_stage(MoveList *mlsp, int aaa) { + assert(mlsp != nullptr); + + // work out the x & y per move. First, opp/adj=tan, so work out the angle + if (mlsp->pos[aaa] == mlsp->pos[aaa + 1]) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = 0; + return; + } + + short ourx = (mlsp->pos[aaa] >> 16) & 0x000ffff; + short oury = (mlsp->pos[aaa] & 0x000ffff); + short destx = ((mlsp->pos[aaa + 1] >> 16) & 0x000ffff); + short desty = (mlsp->pos[aaa + 1] & 0x000ffff); + + // Special case for vertical and horizontal movements + if (ourx == destx) { + mlsp->xpermove[aaa] = 0; + mlsp->ypermove[aaa] = move_speed_y; + if (desty < oury) + mlsp->ypermove[aaa] = -mlsp->ypermove[aaa]; + + return; + } + + if (oury == desty) { + mlsp->xpermove[aaa] = move_speed_x; + mlsp->ypermove[aaa] = 0; + if (destx < ourx) + mlsp->xpermove[aaa] = -mlsp->xpermove[aaa]; + + return; + } + + fixed xdist = itofix(abs(ourx - destx)); + fixed ydist = itofix(abs(oury - desty)); + + fixed useMoveSpeed; + + if (move_speed_x == move_speed_y) { + useMoveSpeed = move_speed_x; + } else { + // different X and Y move speeds + // the X proportion of the movement is (x / (x + y)) + fixed xproportion = fixdiv(xdist, (xdist + ydist)); + + if (move_speed_x > move_speed_y) { + // speed = y + ((1 - xproportion) * (x - y)) + useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y); + } else { + // speed = x + (xproportion * (y - x)) + useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x); + } + } + + fixed angl = fixatan(fixdiv(ydist, xdist)); + + // now, since new opp=hyp*sin, work out the Y step size + //fixed newymove = useMoveSpeed * fsin(angl); + fixed newymove = fixmul(useMoveSpeed, fixsin(angl)); + + // since adj=hyp*cos, work out X step size + //fixed newxmove = useMoveSpeed * fcos(angl); + fixed newxmove = fixmul(useMoveSpeed, fixcos(angl)); + + if (destx < ourx) + newxmove = -newxmove; + if (desty < oury) + newymove = -newymove; + + mlsp->xpermove[aaa] = newxmove; + mlsp->ypermove[aaa] = newymove; #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stage %d from %d,%d to %d,%d Xpermove:%X Ypm:%X", aaa, ourx, oury, destx, desty, newxmove, newymove); - // wtextcolor(14); - // wgtprintf((reallyneed[aaa] >> 16) & 0x000ffff, reallyneed[aaa] & 0x000ffff, cbuttfont, "%d", aaa); + AGS::Common::Debug::Printf("stage %d from %d,%d to %d,%d Xpermove:%X Ypm:%X", aaa, ourx, oury, destx, desty, newxmove, newymove); + // wtextcolor(14); + // wgtprintf((reallyneed[aaa] >> 16) & 0x000ffff, reallyneed[aaa] & 0x000ffff, cbuttfont, "%d", aaa); #endif } #define MAKE_INTCOORD(x,y) (((unsigned short)x << 16) | ((unsigned short)y)) -int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) -{ - assert(onscreen != nullptr); - assert(mls != nullptr); - assert(pathbackx != nullptr); - assert(pathbacky != nullptr); +int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) { + assert(onscreen != nullptr); + assert(mls != nullptr); + assert(pathbackx != nullptr); + assert(pathbacky != nullptr); #ifdef DEBUG_PATHFINDER - // __wnormscreen(); + // __wnormscreen(); #endif - wallscreen = onscreen; - leftorright = 0; - int aaa; - - if (wallscreen->GetHeight() > beenhere_array_size) - { - beenhere = (short**)realloc(beenhere, sizeof(short*) * wallscreen->GetHeight()); - beenhere_array_size = wallscreen->GetHeight(); - - if (beenhere == nullptr) - quit("insufficient memory to allocate pathfinder beenhere buffer"); - - for (aaa = 0; aaa < wallscreen->GetHeight(); aaa++) - { - beenhere[aaa] = nullptr; - } - } - - int orisrcx = srcx, orisrcy = srcy; - finalpartx = -1; - - if (ignore_walls) { - pathbackstage = 0; - } - else if (can_see_from(srcx, srcy, xx, yy)) { - pathbackstage = 0; - } - else { - beenhere[0] = (short *)malloc((wallscreen->GetWidth()) * (wallscreen->GetHeight()) * BEENHERE_SIZE); - - for (aaa = 1; aaa < wallscreen->GetHeight(); aaa++) - beenhere[aaa] = beenhere[0] + aaa * (wallscreen->GetWidth()); - - if (__find_route(srcx, srcy, &xx, &yy, nocross) == 0) { - leftorright = 1; - if (__find_route(srcx, srcy, &xx, &yy, nocross) == 0) - pathbackstage = -1; - } - free(beenhere[0]); - - for (aaa = 0; aaa < wallscreen->GetHeight(); aaa++) - { - beenhere[aaa] = nullptr; - } - } - - if (pathbackstage >= 0) { - int nearestpos = 0, nearestindx; - int reallyneed[MAXNEEDSTAGES], numstages = 0; - reallyneed[numstages] = MAKE_INTCOORD(srcx,srcy); - numstages++; - nearestindx = -1; - - int lastpbs = pathbackstage; + wallscreen = onscreen; + leftorright = 0; + int aaa; + + if (wallscreen->GetHeight() > beenhere_array_size) { + beenhere = (short **)realloc(beenhere, sizeof(short *) * wallscreen->GetHeight()); + beenhere_array_size = wallscreen->GetHeight(); + + if (beenhere == nullptr) + quit("insufficient memory to allocate pathfinder beenhere buffer"); + + for (aaa = 0; aaa < wallscreen->GetHeight(); aaa++) { + beenhere[aaa] = nullptr; + } + } + + int orisrcx = srcx, orisrcy = srcy; + finalpartx = -1; + + if (ignore_walls) { + pathbackstage = 0; + } else if (can_see_from(srcx, srcy, xx, yy)) { + pathbackstage = 0; + } else { + beenhere[0] = (short *)malloc((wallscreen->GetWidth()) * (wallscreen->GetHeight()) * BEENHERE_SIZE); + + for (aaa = 1; aaa < wallscreen->GetHeight(); aaa++) + beenhere[aaa] = beenhere[0] + aaa * (wallscreen->GetWidth()); + + if (__find_route(srcx, srcy, &xx, &yy, nocross) == 0) { + leftorright = 1; + if (__find_route(srcx, srcy, &xx, &yy, nocross) == 0) + pathbackstage = -1; + } + free(beenhere[0]); + + for (aaa = 0; aaa < wallscreen->GetHeight(); aaa++) { + beenhere[aaa] = nullptr; + } + } + + if (pathbackstage >= 0) { + int nearestpos = 0, nearestindx; + int reallyneed[MAXNEEDSTAGES], numstages = 0; + reallyneed[numstages] = MAKE_INTCOORD(srcx, srcy); + numstages++; + nearestindx = -1; + + int lastpbs = pathbackstage; stage_again: - nearestpos = 0; - aaa = 1; - // find the furthest point that can be seen from this stage - for (aaa = pathbackstage - 1; aaa >= 0; aaa--) { + nearestpos = 0; + aaa = 1; + // find the furthest point that can be seen from this stage + for (aaa = pathbackstage - 1; aaa >= 0; aaa--) { #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stage %2d: %2d,%2d\n",aaa,pathbackx[aaa],pathbacky[aaa]); + AGS::Common::Debug::Printf("stage %2d: %2d,%2d\n", aaa, pathbackx[aaa], pathbacky[aaa]); #endif - if (can_see_from(srcx, srcy, pathbackx[aaa], pathbacky[aaa])) { - nearestpos = MAKE_INTCOORD(pathbackx[aaa], pathbacky[aaa]); - nearestindx = aaa; - } - } - - if ((nearestpos == 0) && (can_see_from(srcx, srcy, xx, yy) == 0) && - (srcx >= 0) && (srcy >= 0) && (srcx < wallscreen->GetWidth()) && (srcy < wallscreen->GetHeight()) && (pathbackstage > 0)) { - // If we couldn't see anything, we're stuck in a corner so advance - // to the next square anyway (but only if they're on the screen) - nearestindx = pathbackstage - 1; - nearestpos = MAKE_INTCOORD(pathbackx[nearestindx], pathbacky[nearestindx]); - } - - if (nearestpos > 0) { - reallyneed[numstages] = nearestpos; - numstages++; - if (numstages >= MAXNEEDSTAGES - 1) - quit("too many stages for auto-walk"); - srcx = (nearestpos >> 16) & 0x000ffff; - srcy = nearestpos & 0x000ffff; + if (can_see_from(srcx, srcy, pathbackx[aaa], pathbacky[aaa])) { + nearestpos = MAKE_INTCOORD(pathbackx[aaa], pathbacky[aaa]); + nearestindx = aaa; + } + } + + if ((nearestpos == 0) && (can_see_from(srcx, srcy, xx, yy) == 0) && + (srcx >= 0) && (srcy >= 0) && (srcx < wallscreen->GetWidth()) && (srcy < wallscreen->GetHeight()) && (pathbackstage > 0)) { + // If we couldn't see anything, we're stuck in a corner so advance + // to the next square anyway (but only if they're on the screen) + nearestindx = pathbackstage - 1; + nearestpos = MAKE_INTCOORD(pathbackx[nearestindx], pathbacky[nearestindx]); + } + + if (nearestpos > 0) { + reallyneed[numstages] = nearestpos; + numstages++; + if (numstages >= MAXNEEDSTAGES - 1) + quit("too many stages for auto-walk"); + srcx = (nearestpos >> 16) & 0x000ffff; + srcy = nearestpos & 0x000ffff; #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("Added: %d, %d pbs:%d",srcx,srcy,pathbackstage); + AGS::Common::Debug::Printf("Added: %d, %d pbs:%d", srcx, srcy, pathbackstage); #endif - lastpbs = pathbackstage; - pathbackstage = nearestindx; - goto stage_again; - } - - if (finalpartx >= 0) { - reallyneed[numstages] = MAKE_INTCOORD(finalpartx, finalparty); - numstages++; - } - - // Make sure the end co-ord is in there - if (reallyneed[numstages - 1] != MAKE_INTCOORD(xx, yy)) { - reallyneed[numstages] = MAKE_INTCOORD(xx, yy); - numstages++; - } - - if ((numstages == 1) && (xx == orisrcx) && (yy == orisrcy)) { - return 0; - } + lastpbs = pathbackstage; + pathbackstage = nearestindx; + goto stage_again; + } + + if (finalpartx >= 0) { + reallyneed[numstages] = MAKE_INTCOORD(finalpartx, finalparty); + numstages++; + } + + // Make sure the end co-ord is in there + if (reallyneed[numstages - 1] != MAKE_INTCOORD(xx, yy)) { + reallyneed[numstages] = MAKE_INTCOORD(xx, yy); + numstages++; + } + + if ((numstages == 1) && (xx == orisrcx) && (yy == orisrcy)) { + return 0; + } #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stage, %d stages", orisrcx,orisrcy,xx,yy,pathbackstage,numstages); + AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stage, %d stages", orisrcx, orisrcy, xx, yy, pathbackstage, numstages); #endif - int mlist = movlst; - mls[mlist].numstage = numstages; - memcpy(&mls[mlist].pos[0], &reallyneed[0], sizeof(int) * numstages); + int mlist = movlst; + mls[mlist].numstage = numstages; + memcpy(&mls[mlist].pos[0], &reallyneed[0], sizeof(int) * numstages); #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stages: %d\n",numstages); + AGS::Common::Debug::Printf("stages: %d\n", numstages); #endif - for (aaa = 0; aaa < numstages - 1; aaa++) { - calculate_move_stage(&mls[mlist], aaa); - } - - mls[mlist].fromx = orisrcx; - mls[mlist].fromy = orisrcy; - mls[mlist].onstage = 0; - mls[mlist].onpart = 0; - mls[mlist].doneflag = 0; - mls[mlist].lastx = -1; - mls[mlist].lasty = -1; + for (aaa = 0; aaa < numstages - 1; aaa++) { + calculate_move_stage(&mls[mlist], aaa); + } + + mls[mlist].fromx = orisrcx; + mls[mlist].fromy = orisrcy; + mls[mlist].onstage = 0; + mls[mlist].onpart = 0; + mls[mlist].doneflag = 0; + mls[mlist].lastx = -1; + mls[mlist].lasty = -1; #ifdef DEBUG_PATHFINDER - // getch(); + // getch(); #endif - return mlist; - } else { - return 0; - } + return mlist; + } else { + return 0; + } #ifdef DEBUG_PATHFINDER - // __unnormscreen(); + // __unnormscreen(); #endif } -void shutdown_pathfinder() -{ - if (pathbackx != nullptr) - { - free(pathbackx); - } - if (pathbacky != nullptr) - { - free(pathbacky); - } - if (beenhere != nullptr) - { - if (beenhere[0] != nullptr) - { - free(beenhere[0]); - } - free(beenhere); - } - - pathbackx = nullptr; - pathbacky = nullptr; - beenhere = nullptr; - beenhere_array_size = 0; +void shutdown_pathfinder() { + if (pathbackx != nullptr) { + free(pathbackx); + } + if (pathbacky != nullptr) { + free(pathbacky); + } + if (beenhere != nullptr) { + if (beenhere[0] != nullptr) { + free(beenhere[0]); + } + free(beenhere); + } + + pathbackx = nullptr; + pathbacky = nullptr; + beenhere = nullptr; + beenhere_array_size = 0; } diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h index 26e9f69730ec..4da9d5017f06 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.h +++ b/engines/ags/engine/ac/route_finder_impl_legacy.h @@ -24,7 +24,11 @@ #define AGS_ENGINE_AC_ROUTE_FINDER_IMPL_LEGACY // Forward declaration -namespace AGS { namespace Common { class Bitmap; }} +namespace AGS { +namespace Common { +class Bitmap; +} +} struct MoveList; namespace AGS { @@ -42,7 +46,7 @@ void get_lastcpos(int &lastcx, int &lastcy); void set_route_move_speed(int speed_x, int speed_y); int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); -void calculate_move_stage(MoveList * mlsp, int aaa); +void calculate_move_stage(MoveList *mlsp, int aaa); } // namespace RouteFinderLegacy } // namespace Engine diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h index b48320eb30c9..806a2f93d95b 100644 --- a/engines/ags/engine/ac/runtime_defines.h +++ b/engines/ags/engine/ac/runtime_defines.h @@ -47,17 +47,16 @@ #define MAXSAVEGAMES 50 #define MAX_QUEUED_MUSIC 10 #define GLED_INTERACTION 1 -#define GLED_EFFECTS 2 +#define GLED_EFFECTS 2 #define QUEUED_MUSIC_REPEAT 10000 #define PLAYMP3FILE_MAX_FILENAME_LEN 50 #define MAX_AUDIO_TYPES 30 // Legacy (pre 3.5.0) alignment types used in the script API -enum LegacyScriptAlignment -{ - kLegacyScAlignLeft = 1, - kLegacyScAlignCentre = 2, - kLegacyScAlignRight = 3 +enum LegacyScriptAlignment { + kLegacyScAlignLeft = 1, + kLegacyScAlignCentre = 2, + kLegacyScAlignRight = 3 }; const int LegacyMusicMasterVolumeAdjustment = 60; diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index 8ab98f8b8d9e..39faca649664 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -45,76 +45,66 @@ extern IGraphicsDriver *gfxDriver; extern AGSPlatformDriver *platform; void my_fade_in(PALETTE p, int speed) { - if (game.color_depth > 1) { - set_palette (p); + if (game.color_depth > 1) { + set_palette(p); - play.screen_is_faded_out = 0; + play.screen_is_faded_out = 0; - if (play.no_hicolor_fadein) { - return; - } - } + if (play.no_hicolor_fadein) { + return; + } + } - gfxDriver->FadeIn(speed, p, play.fade_to_red, play.fade_to_green, play.fade_to_blue); + gfxDriver->FadeIn(speed, p, play.fade_to_red, play.fade_to_green, play.fade_to_blue); } Bitmap *saved_viewport_bitmap = nullptr; color old_palette[256]; -void current_fade_out_effect () { - if (pl_run_plugin_hooks(AGSE_TRANSITIONOUT, 0)) - return; - - // get the screen transition type - int theTransition = play.fade_effect; - // was a temporary transition selected? if so, use it - if (play.next_screen_transition >= 0) - theTransition = play.next_screen_transition; - const bool ignore_transition = play.screen_tint > 0; - - if ((theTransition == FADE_INSTANT) || ignore_transition) { - if (!play.keep_screen_during_instant_transition) - set_palette_range(black_palette, 0, 255, 0); - } - else if (theTransition == FADE_NORMAL) - { - my_fade_out(5); - } - else if (theTransition == FADE_BOXOUT) - { - gfxDriver->BoxOutEffect(true, get_fixed_pixel_size(16), 1000 / GetGameSpeed()); - play.screen_is_faded_out = 1; - } - else - { - get_palette(old_palette); - const Rect &viewport = play.GetMainViewport(); - saved_viewport_bitmap = CopyScreenIntoBitmap(viewport.GetWidth(), viewport.GetHeight()); - } -} - -IDriverDependantBitmap* prepare_screen_for_transition_in() -{ - if (saved_viewport_bitmap == nullptr) - quit("Crossfade: buffer is null attempting transition"); - - saved_viewport_bitmap = ReplaceBitmapWithSupportedFormat(saved_viewport_bitmap); - const Rect &viewport = play.GetMainViewport(); - if (saved_viewport_bitmap->GetHeight() < viewport.GetHeight()) - { - Bitmap *enlargedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); - enlargedBuffer->Blit(saved_viewport_bitmap, 0, 0, 0, (viewport.GetHeight() - saved_viewport_bitmap->GetHeight()) / 2, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); - delete saved_viewport_bitmap; - saved_viewport_bitmap = enlargedBuffer; - } - else if (saved_viewport_bitmap->GetHeight() > viewport.GetHeight()) - { - Bitmap *clippedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); - clippedBuffer->Blit(saved_viewport_bitmap, 0, (saved_viewport_bitmap->GetHeight() - viewport.GetHeight()) / 2, 0, 0, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); - delete saved_viewport_bitmap; - saved_viewport_bitmap = clippedBuffer; - } - IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(saved_viewport_bitmap, false); - return ddb; +void current_fade_out_effect() { + if (pl_run_plugin_hooks(AGSE_TRANSITIONOUT, 0)) + return; + + // get the screen transition type + int theTransition = play.fade_effect; + // was a temporary transition selected? if so, use it + if (play.next_screen_transition >= 0) + theTransition = play.next_screen_transition; + const bool ignore_transition = play.screen_tint > 0; + + if ((theTransition == FADE_INSTANT) || ignore_transition) { + if (!play.keep_screen_during_instant_transition) + set_palette_range(black_palette, 0, 255, 0); + } else if (theTransition == FADE_NORMAL) { + my_fade_out(5); + } else if (theTransition == FADE_BOXOUT) { + gfxDriver->BoxOutEffect(true, get_fixed_pixel_size(16), 1000 / GetGameSpeed()); + play.screen_is_faded_out = 1; + } else { + get_palette(old_palette); + const Rect &viewport = play.GetMainViewport(); + saved_viewport_bitmap = CopyScreenIntoBitmap(viewport.GetWidth(), viewport.GetHeight()); + } +} + +IDriverDependantBitmap *prepare_screen_for_transition_in() { + if (saved_viewport_bitmap == nullptr) + quit("Crossfade: buffer is null attempting transition"); + + saved_viewport_bitmap = ReplaceBitmapWithSupportedFormat(saved_viewport_bitmap); + const Rect &viewport = play.GetMainViewport(); + if (saved_viewport_bitmap->GetHeight() < viewport.GetHeight()) { + Bitmap *enlargedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); + enlargedBuffer->Blit(saved_viewport_bitmap, 0, 0, 0, (viewport.GetHeight() - saved_viewport_bitmap->GetHeight()) / 2, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); + delete saved_viewport_bitmap; + saved_viewport_bitmap = enlargedBuffer; + } else if (saved_viewport_bitmap->GetHeight() > viewport.GetHeight()) { + Bitmap *clippedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); + clippedBuffer->Blit(saved_viewport_bitmap, 0, (saved_viewport_bitmap->GetHeight() - viewport.GetHeight()) / 2, 0, 0, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); + delete saved_viewport_bitmap; + saved_viewport_bitmap = clippedBuffer; + } + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(saved_viewport_bitmap, false); + return ddb; } //============================================================================= @@ -123,115 +113,96 @@ IDriverDependantBitmap* prepare_screen_for_transition_in() // //============================================================================= -int Screen_GetScreenWidth() -{ - return game.GetGameRes().Width; +int Screen_GetScreenWidth() { + return game.GetGameRes().Width; } -int Screen_GetScreenHeight() -{ - return game.GetGameRes().Height; +int Screen_GetScreenHeight() { + return game.GetGameRes().Height; } -bool Screen_GetAutoSizeViewport() -{ - return play.IsAutoRoomViewport(); +bool Screen_GetAutoSizeViewport() { + return play.IsAutoRoomViewport(); } -void Screen_SetAutoSizeViewport(bool on) -{ - play.SetAutoRoomViewport(on); +void Screen_SetAutoSizeViewport(bool on) { + play.SetAutoRoomViewport(on); } -ScriptViewport* Screen_GetViewport() -{ - return play.GetScriptViewport(0); +ScriptViewport *Screen_GetViewport() { + return play.GetScriptViewport(0); } -int Screen_GetViewportCount() -{ - return play.GetRoomViewportCount(); +int Screen_GetViewportCount() { + return play.GetRoomViewportCount(); } -ScriptViewport* Screen_GetAnyViewport(int index) -{ - return play.GetScriptViewport(index); +ScriptViewport *Screen_GetAnyViewport(int index) { + return play.GetScriptViewport(index); } -ScriptUserObject* Screen_ScreenToRoomPoint(int scrx, int scry) -{ - data_to_game_coords(&scrx, &scry); +ScriptUserObject *Screen_ScreenToRoomPoint(int scrx, int scry) { + data_to_game_coords(&scrx, &scry); - VpPoint vpt = play.ScreenToRoom(scrx, scry); - if (vpt.second < 0) - return nullptr; + VpPoint vpt = play.ScreenToRoom(scrx, scry); + if (vpt.second < 0) + return nullptr; - game_to_data_coords(vpt.first.X, vpt.first.Y); - return ScriptStructHelpers::CreatePoint(vpt.first.X, vpt.first.Y); + game_to_data_coords(vpt.first.X, vpt.first.Y); + return ScriptStructHelpers::CreatePoint(vpt.first.X, vpt.first.Y); } -ScriptUserObject *Screen_RoomToScreenPoint(int roomx, int roomy) -{ - data_to_game_coords(&roomx, &roomy); - Point pt = play.RoomToScreen(roomx, roomy); - game_to_data_coords(pt.X, pt.Y); - return ScriptStructHelpers::CreatePoint(pt.X, pt.Y); +ScriptUserObject *Screen_RoomToScreenPoint(int roomx, int roomy) { + data_to_game_coords(&roomx, &roomy); + Point pt = play.RoomToScreen(roomx, roomy); + game_to_data_coords(pt.X, pt.Y); + return ScriptStructHelpers::CreatePoint(pt.X, pt.Y); } -RuntimeScriptValue Sc_Screen_GetScreenHeight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Screen_GetScreenHeight); +RuntimeScriptValue Sc_Screen_GetScreenHeight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Screen_GetScreenHeight); } -RuntimeScriptValue Sc_Screen_GetScreenWidth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Screen_GetScreenWidth); +RuntimeScriptValue Sc_Screen_GetScreenWidth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Screen_GetScreenWidth); } -RuntimeScriptValue Sc_Screen_GetAutoSizeViewport(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_BOOL(Screen_GetAutoSizeViewport); +RuntimeScriptValue Sc_Screen_GetAutoSizeViewport(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_BOOL(Screen_GetAutoSizeViewport); } -RuntimeScriptValue Sc_Screen_SetAutoSizeViewport(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PBOOL(Screen_SetAutoSizeViewport); +RuntimeScriptValue Sc_Screen_SetAutoSizeViewport(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PBOOL(Screen_SetAutoSizeViewport); } -RuntimeScriptValue Sc_Screen_GetViewport(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO(ScriptViewport, Screen_GetViewport); +RuntimeScriptValue Sc_Screen_GetViewport(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO(ScriptViewport, Screen_GetViewport); } -RuntimeScriptValue Sc_Screen_GetViewportCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(Screen_GetViewportCount); +RuntimeScriptValue Sc_Screen_GetViewportCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(Screen_GetViewportCount); } -RuntimeScriptValue Sc_Screen_GetAnyViewport(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT(ScriptViewport, Screen_GetAnyViewport); +RuntimeScriptValue Sc_Screen_GetAnyViewport(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT(ScriptViewport, Screen_GetAnyViewport); } -RuntimeScriptValue Sc_Screen_ScreenToRoomPoint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT2(ScriptUserObject, Screen_ScreenToRoomPoint); +RuntimeScriptValue Sc_Screen_ScreenToRoomPoint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT2(ScriptUserObject, Screen_ScreenToRoomPoint); } -RuntimeScriptValue Sc_Screen_RoomToScreenPoint(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT2(ScriptUserObject, Screen_RoomToScreenPoint); +RuntimeScriptValue Sc_Screen_RoomToScreenPoint(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT2(ScriptUserObject, Screen_RoomToScreenPoint); } -void RegisterScreenAPI() -{ - ccAddExternalStaticFunction("Screen::get_Height", Sc_Screen_GetScreenHeight); - ccAddExternalStaticFunction("Screen::get_Width", Sc_Screen_GetScreenWidth); - ccAddExternalStaticFunction("Screen::get_AutoSizeViewportOnRoomLoad", Sc_Screen_GetAutoSizeViewport); - ccAddExternalStaticFunction("Screen::set_AutoSizeViewportOnRoomLoad", Sc_Screen_SetAutoSizeViewport); - ccAddExternalStaticFunction("Screen::get_Viewport", Sc_Screen_GetViewport); - ccAddExternalStaticFunction("Screen::get_ViewportCount", Sc_Screen_GetViewportCount); - ccAddExternalStaticFunction("Screen::geti_Viewports", Sc_Screen_GetAnyViewport); - ccAddExternalStaticFunction("Screen::ScreenToRoomPoint", Sc_Screen_ScreenToRoomPoint); - ccAddExternalStaticFunction("Screen::RoomToScreenPoint", Sc_Screen_RoomToScreenPoint); +void RegisterScreenAPI() { + ccAddExternalStaticFunction("Screen::get_Height", Sc_Screen_GetScreenHeight); + ccAddExternalStaticFunction("Screen::get_Width", Sc_Screen_GetScreenWidth); + ccAddExternalStaticFunction("Screen::get_AutoSizeViewportOnRoomLoad", Sc_Screen_GetAutoSizeViewport); + ccAddExternalStaticFunction("Screen::set_AutoSizeViewportOnRoomLoad", Sc_Screen_SetAutoSizeViewport); + ccAddExternalStaticFunction("Screen::get_Viewport", Sc_Screen_GetViewport); + ccAddExternalStaticFunction("Screen::get_ViewportCount", Sc_Screen_GetViewportCount); + ccAddExternalStaticFunction("Screen::geti_Viewports", Sc_Screen_GetAnyViewport); + ccAddExternalStaticFunction("Screen::ScreenToRoomPoint", Sc_Screen_ScreenToRoomPoint); + ccAddExternalStaticFunction("Screen::RoomToScreenPoint", Sc_Screen_RoomToScreenPoint); } diff --git a/engines/ags/engine/ac/screen.h b/engines/ags/engine/ac/screen.h index a89012f50e0f..4c95fb8065f0 100644 --- a/engines/ags/engine/ac/screen.h +++ b/engines/ags/engine/ac/screen.h @@ -23,12 +23,20 @@ #ifndef AGS_ENGINE_AC_SCREEN_H #define AGS_ENGINE_AC_SCREEN_H -namespace AGS { namespace Common { class Bitmap; } } -namespace AGS { namespace Engine { class IDriverDependantBitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} +namespace AGS { +namespace Engine { +class IDriverDependantBitmap; +} +} void my_fade_in(PALETTE p, int speed); -void current_fade_out_effect (); -AGS::Engine::IDriverDependantBitmap* prepare_screen_for_transition_in(); +void current_fade_out_effect(); +AGS::Engine::IDriverDependantBitmap *prepare_screen_for_transition_in(); // Screenshot made in the last room, used during some of the transition effects extern AGS::Common::Bitmap *saved_viewport_bitmap; diff --git a/engines/ags/engine/ac/screenoverlay.cpp b/engines/ags/engine/ac/screenoverlay.cpp index 9fd69b2367d1..c90e3bc77e88 100644 --- a/engines/ags/engine/ac/screenoverlay.cpp +++ b/engines/ags/engine/ac/screenoverlay.cpp @@ -25,43 +25,40 @@ using AGS::Common::Stream; -void ScreenOverlay::ReadFromFile(Stream *in, int32_t cmp_ver) -{ - // Skipping bmp and pic pointer values - // TODO: find out if it's safe to just drop these pointers!! replace with unique_ptr? - bmp = nullptr; - pic = nullptr; - in->ReadInt32(); // bmp - hasSerializedBitmap = in->ReadInt32() != 0; - type = in->ReadInt32(); - x = in->ReadInt32(); - y = in->ReadInt32(); - timeout = in->ReadInt32(); - bgSpeechForChar = in->ReadInt32(); - associatedOverlayHandle = in->ReadInt32(); - hasAlphaChannel = in->ReadBool(); - positionRelativeToScreen = in->ReadBool(); - if (cmp_ver >= 1) - { - _offsetX = in->ReadInt32(); - _offsetY = in->ReadInt32(); - } +void ScreenOverlay::ReadFromFile(Stream *in, int32_t cmp_ver) { + // Skipping bmp and pic pointer values + // TODO: find out if it's safe to just drop these pointers!! replace with unique_ptr? + bmp = nullptr; + pic = nullptr; + in->ReadInt32(); // bmp + hasSerializedBitmap = in->ReadInt32() != 0; + type = in->ReadInt32(); + x = in->ReadInt32(); + y = in->ReadInt32(); + timeout = in->ReadInt32(); + bgSpeechForChar = in->ReadInt32(); + associatedOverlayHandle = in->ReadInt32(); + hasAlphaChannel = in->ReadBool(); + positionRelativeToScreen = in->ReadBool(); + if (cmp_ver >= 1) { + _offsetX = in->ReadInt32(); + _offsetY = in->ReadInt32(); + } } -void ScreenOverlay::WriteToFile(Stream *out) const -{ - // Writing bitmap "pointers" to correspond to full structure writing - out->WriteInt32(0); // bmp - out->WriteInt32(pic ? 1 : 0); // pic - out->WriteInt32(type); - out->WriteInt32(x); - out->WriteInt32(y); - out->WriteInt32(timeout); - out->WriteInt32(bgSpeechForChar); - out->WriteInt32(associatedOverlayHandle); - out->WriteBool(hasAlphaChannel); - out->WriteBool(positionRelativeToScreen); - // since cmp_ver = 1 - out->WriteInt32(_offsetX); - out->WriteInt32(_offsetY); +void ScreenOverlay::WriteToFile(Stream *out) const { + // Writing bitmap "pointers" to correspond to full structure writing + out->WriteInt32(0); // bmp + out->WriteInt32(pic ? 1 : 0); // pic + out->WriteInt32(type); + out->WriteInt32(x); + out->WriteInt32(y); + out->WriteInt32(timeout); + out->WriteInt32(bgSpeechForChar); + out->WriteInt32(associatedOverlayHandle); + out->WriteBool(hasAlphaChannel); + out->WriteBool(positionRelativeToScreen); + // since cmp_ver = 1 + out->WriteInt32(_offsetX); + out->WriteInt32(_offsetY); } diff --git a/engines/ags/engine/ac/screenoverlay.h b/engines/ags/engine/ac/screenoverlay.h index 3f772edb49a8..751077a0a510 100644 --- a/engines/ags/engine/ac/screenoverlay.h +++ b/engines/ags/engine/ac/screenoverlay.h @@ -26,24 +26,33 @@ #include // Forward declaration -namespace AGS { namespace Common { class Bitmap; class Stream; } } -namespace AGS { namespace Engine { class IDriverDependantBitmap; }} +namespace AGS { +namespace Common { +class Bitmap; +class Stream; +} +} +namespace AGS { +namespace Engine { +class IDriverDependantBitmap; +} +} using namespace AGS; // FIXME later struct ScreenOverlay { - Engine::IDriverDependantBitmap *bmp = nullptr; - Common::Bitmap *pic = nullptr; - int type = 0, x = 0, y = 0, timeout = 0; - int bgSpeechForChar = 0; - int associatedOverlayHandle = 0; - bool hasAlphaChannel = false; - bool positionRelativeToScreen = false; - bool hasSerializedBitmap = false; - int _offsetX = 0, _offsetY = 0; + Engine::IDriverDependantBitmap *bmp = nullptr; + Common::Bitmap *pic = nullptr; + int type = 0, x = 0, y = 0, timeout = 0; + int bgSpeechForChar = 0; + int associatedOverlayHandle = 0; + bool hasAlphaChannel = false; + bool positionRelativeToScreen = false; + bool hasSerializedBitmap = false; + int _offsetX = 0, _offsetY = 0; - void ReadFromFile(Common::Stream *in, int32_t cmp_ver); - void WriteToFile(Common::Stream *out) const; + void ReadFromFile(Common::Stream *in, int32_t cmp_ver); + void WriteToFile(Common::Stream *out) const; }; #endif diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index c22f8622f239..6913fa606b09 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -45,160 +45,135 @@ extern ScriptString myScriptStringImpl; // //============================================================================= -ScriptDictBase *Dict_CreateImpl(bool sorted, bool case_sensitive) -{ - ScriptDictBase *dic; - if (sorted) - { - if (case_sensitive) - dic = new ScriptDict(); - else - dic = new ScriptDictCI(); - } - else - { - if (case_sensitive) - dic = new ScriptHashDict(); - else - dic = new ScriptHashDictCI(); - } - return dic; -} - -ScriptDictBase *Dict_Create(bool sorted, bool case_sensitive) -{ - ScriptDictBase *dic = Dict_CreateImpl(sorted, case_sensitive); - ccRegisterManagedObject(dic, dic); - return dic; +ScriptDictBase *Dict_CreateImpl(bool sorted, bool case_sensitive) { + ScriptDictBase *dic; + if (sorted) { + if (case_sensitive) + dic = new ScriptDict(); + else + dic = new ScriptDictCI(); + } else { + if (case_sensitive) + dic = new ScriptHashDict(); + else + dic = new ScriptHashDictCI(); + } + return dic; +} + +ScriptDictBase *Dict_Create(bool sorted, bool case_sensitive) { + ScriptDictBase *dic = Dict_CreateImpl(sorted, case_sensitive); + ccRegisterManagedObject(dic, dic); + return dic; } // TODO: we need memory streams -ScriptDictBase *Dict_Unserialize(int index, const char *serializedData, int dataSize) -{ - if (dataSize < sizeof(int32_t) * 2) - quit("Dict_Unserialize: not enough data."); - const char *ptr = serializedData; - const int sorted = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); - const int cs = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); - ScriptDictBase *dic = Dict_CreateImpl(sorted != 0, cs != 0); - dic->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); - return dic; +ScriptDictBase *Dict_Unserialize(int index, const char *serializedData, int dataSize) { + if (dataSize < sizeof(int32_t) * 2) + quit("Dict_Unserialize: not enough data."); + const char *ptr = serializedData; + const int sorted = BBOp::Int32FromLE(*((int *)ptr)); + ptr += sizeof(int32_t); + const int cs = BBOp::Int32FromLE(*((int *)ptr)); + ptr += sizeof(int32_t); + ScriptDictBase *dic = Dict_CreateImpl(sorted != 0, cs != 0); + dic->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); + return dic; } -void Dict_Clear(ScriptDictBase *dic) -{ - dic->Clear(); +void Dict_Clear(ScriptDictBase *dic) { + dic->Clear(); } -bool Dict_Contains(ScriptDictBase *dic, const char *key) -{ - return dic->Contains(key); +bool Dict_Contains(ScriptDictBase *dic, const char *key) { + return dic->Contains(key); } -const char *Dict_Get(ScriptDictBase *dic, const char *key) -{ - auto *str = dic->Get(key); - return str ? CreateNewScriptString(str) : nullptr; +const char *Dict_Get(ScriptDictBase *dic, const char *key) { + auto *str = dic->Get(key); + return str ? CreateNewScriptString(str) : nullptr; } -bool Dict_Remove(ScriptDictBase *dic, const char *key) -{ - return dic->Remove(key); +bool Dict_Remove(ScriptDictBase *dic, const char *key) { + return dic->Remove(key); } -bool Dict_Set(ScriptDictBase *dic, const char *key, const char *value) -{ - return dic->Set(key, value); +bool Dict_Set(ScriptDictBase *dic, const char *key, const char *value) { + return dic->Set(key, value); } -int Dict_GetCompareStyle(ScriptDictBase *dic) -{ - return dic->IsCaseSensitive() ? 1 : 0; +int Dict_GetCompareStyle(ScriptDictBase *dic) { + return dic->IsCaseSensitive() ? 1 : 0; } -int Dict_GetSortStyle(ScriptDictBase *dic) -{ - return dic->IsSorted() ? 1 : 0; +int Dict_GetSortStyle(ScriptDictBase *dic) { + return dic->IsSorted() ? 1 : 0; } -int Dict_GetItemCount(ScriptDictBase *dic) -{ - return dic->GetItemCount(); +int Dict_GetItemCount(ScriptDictBase *dic) { + return dic->GetItemCount(); } -void *Dict_GetKeysAsArray(ScriptDictBase *dic) -{ - std::vector items; - dic->GetKeys(items); - if (items.size() == 0) - return nullptr; - DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); - return arr.second; +void *Dict_GetKeysAsArray(ScriptDictBase *dic) { + std::vector items; + dic->GetKeys(items); + if (items.size() == 0) + return nullptr; + DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); + return arr.second; } -void *Dict_GetValuesAsArray(ScriptDictBase *dic) -{ - std::vector items; - dic->GetValues(items); - if (items.size() == 0) - return nullptr; - DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); - return arr.second; +void *Dict_GetValuesAsArray(ScriptDictBase *dic) { + std::vector items; + dic->GetValues(items); + if (items.size() == 0) + return nullptr; + DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); + return arr.second; } -RuntimeScriptValue Sc_Dict_Create(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PBOOL2(ScriptDictBase, Dict_Create); +RuntimeScriptValue Sc_Dict_Create(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PBOOL2(ScriptDictBase, Dict_Create); } -RuntimeScriptValue Sc_Dict_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptDictBase, Dict_Clear); +RuntimeScriptValue Sc_Dict_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptDictBase, Dict_Clear); } -RuntimeScriptValue Sc_Dict_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Contains, const char); +RuntimeScriptValue Sc_Dict_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Contains, const char); } -RuntimeScriptValue Sc_Dict_Get(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, myScriptStringImpl, Dict_Get, const char); +RuntimeScriptValue Sc_Dict_Get(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, myScriptStringImpl, Dict_Get, const char); } -RuntimeScriptValue Sc_Dict_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Remove, const char); +RuntimeScriptValue Sc_Dict_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ(ScriptDictBase, Dict_Remove, const char); } -RuntimeScriptValue Sc_Dict_Set(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ2(ScriptDictBase, Dict_Set, const char, const char); +RuntimeScriptValue Sc_Dict_Set(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ2(ScriptDictBase, Dict_Set, const char, const char); } -RuntimeScriptValue Sc_Dict_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDictBase, Dict_GetCompareStyle); +RuntimeScriptValue Sc_Dict_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDictBase, Dict_GetCompareStyle); } -RuntimeScriptValue Sc_Dict_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDictBase, Dict_GetSortStyle); +RuntimeScriptValue Sc_Dict_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDictBase, Dict_GetSortStyle); } -RuntimeScriptValue Sc_Dict_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptDictBase, Dict_GetItemCount); +RuntimeScriptValue Sc_Dict_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptDictBase, Dict_GetItemCount); } -RuntimeScriptValue Sc_Dict_GetKeysAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptDictBase, void, globalDynamicArray, Dict_GetKeysAsArray); +RuntimeScriptValue Sc_Dict_GetKeysAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptDictBase, void, globalDynamicArray, Dict_GetKeysAsArray); } -RuntimeScriptValue Sc_Dict_GetValuesAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptDictBase, void, globalDynamicArray, Dict_GetValuesAsArray); +RuntimeScriptValue Sc_Dict_GetValuesAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptDictBase, void, globalDynamicArray, Dict_GetValuesAsArray); } //============================================================================= @@ -207,159 +182,137 @@ RuntimeScriptValue Sc_Dict_GetValuesAsArray(void *self, const RuntimeScriptValue // //============================================================================= -ScriptSetBase *Set_CreateImpl(bool sorted, bool case_sensitive) -{ - ScriptSetBase *set; - if (sorted) - { - if (case_sensitive) - set = new ScriptSet(); - else - set = new ScriptSetCI(); - } - else - { - if (case_sensitive) - set = new ScriptHashSet(); - else - set = new ScriptHashSetCI(); - } - return set; -} - -ScriptSetBase *Set_Create(bool sorted, bool case_sensitive) -{ - ScriptSetBase *set = Set_CreateImpl(sorted, case_sensitive); - ccRegisterManagedObject(set, set); - return set; +ScriptSetBase *Set_CreateImpl(bool sorted, bool case_sensitive) { + ScriptSetBase *set; + if (sorted) { + if (case_sensitive) + set = new ScriptSet(); + else + set = new ScriptSetCI(); + } else { + if (case_sensitive) + set = new ScriptHashSet(); + else + set = new ScriptHashSetCI(); + } + return set; +} + +ScriptSetBase *Set_Create(bool sorted, bool case_sensitive) { + ScriptSetBase *set = Set_CreateImpl(sorted, case_sensitive); + ccRegisterManagedObject(set, set); + return set; } // TODO: we need memory streams -ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize) -{ - if (dataSize < sizeof(int32_t) * 2) - quit("Set_Unserialize: not enough data."); - const char *ptr = serializedData; - const int sorted = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); - const int cs = BBOp::Int32FromLE(*((int*)ptr)); ptr += sizeof(int32_t); - ScriptSetBase *set = Set_CreateImpl(sorted != 0, cs != 0); - set->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); - return set; +ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize) { + if (dataSize < sizeof(int32_t) * 2) + quit("Set_Unserialize: not enough data."); + const char *ptr = serializedData; + const int sorted = BBOp::Int32FromLE(*((int *)ptr)); + ptr += sizeof(int32_t); + const int cs = BBOp::Int32FromLE(*((int *)ptr)); + ptr += sizeof(int32_t); + ScriptSetBase *set = Set_CreateImpl(sorted != 0, cs != 0); + set->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); + return set; } -bool Set_Add(ScriptSetBase *set, const char *item) -{ - return set->Add(item); +bool Set_Add(ScriptSetBase *set, const char *item) { + return set->Add(item); } -void Set_Clear(ScriptSetBase *set) -{ - set->Clear(); +void Set_Clear(ScriptSetBase *set) { + set->Clear(); } -bool Set_Contains(ScriptSetBase *set, const char *item) -{ - return set->Contains(item); +bool Set_Contains(ScriptSetBase *set, const char *item) { + return set->Contains(item); } -bool Set_Remove(ScriptSetBase *set, const char *item) -{ - return set->Remove(item); +bool Set_Remove(ScriptSetBase *set, const char *item) { + return set->Remove(item); } -int Set_GetCompareStyle(ScriptSetBase *set) -{ - return set->IsCaseSensitive() ? 1 : 0; +int Set_GetCompareStyle(ScriptSetBase *set) { + return set->IsCaseSensitive() ? 1 : 0; } -int Set_GetSortStyle(ScriptSetBase *set) -{ - return set->IsSorted() ? 1 : 0; +int Set_GetSortStyle(ScriptSetBase *set) { + return set->IsSorted() ? 1 : 0; } -int Set_GetItemCount(ScriptSetBase *set) -{ - return set->GetItemCount(); +int Set_GetItemCount(ScriptSetBase *set) { + return set->GetItemCount(); } -void *Set_GetItemsAsArray(ScriptSetBase *set) -{ - std::vector items; - set->GetItems(items); - if (items.size() == 0) - return nullptr; - DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); - return arr.second; +void *Set_GetItemsAsArray(ScriptSetBase *set) { + std::vector items; + set->GetItems(items); + if (items.size() == 0) + return nullptr; + DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); + return arr.second; } -RuntimeScriptValue Sc_Set_Create(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PBOOL2(ScriptSetBase, Set_Create); +RuntimeScriptValue Sc_Set_Create(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PBOOL2(ScriptSetBase, Set_Create); } -RuntimeScriptValue Sc_Set_Add(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Add, const char); +RuntimeScriptValue Sc_Set_Add(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Add, const char); } -RuntimeScriptValue Sc_Set_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptSetBase, Set_Clear); +RuntimeScriptValue Sc_Set_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptSetBase, Set_Clear); } -RuntimeScriptValue Sc_Set_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Contains, const char); +RuntimeScriptValue Sc_Set_Contains(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Contains, const char); } -RuntimeScriptValue Sc_Set_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Remove, const char); +RuntimeScriptValue Sc_Set_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL_POBJ(ScriptSetBase, Set_Remove, const char); } -RuntimeScriptValue Sc_Set_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptSetBase, Set_GetCompareStyle); +RuntimeScriptValue Sc_Set_GetCompareStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptSetBase, Set_GetCompareStyle); } -RuntimeScriptValue Sc_Set_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptSetBase, Set_GetSortStyle); +RuntimeScriptValue Sc_Set_GetSortStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptSetBase, Set_GetSortStyle); } -RuntimeScriptValue Sc_Set_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptSetBase, Set_GetItemCount); +RuntimeScriptValue Sc_Set_GetItemCount(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptSetBase, Set_GetItemCount); } -RuntimeScriptValue Sc_Set_GetItemAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptSetBase, void, globalDynamicArray, Set_GetItemsAsArray); +RuntimeScriptValue Sc_Set_GetItemAsArray(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptSetBase, void, globalDynamicArray, Set_GetItemsAsArray); } -void RegisterContainerAPI() -{ - ccAddExternalStaticFunction("Dictionary::Create", Sc_Dict_Create); - ccAddExternalObjectFunction("Dictionary::Clear", Sc_Dict_Clear); - ccAddExternalObjectFunction("Dictionary::Contains", Sc_Dict_Contains); - ccAddExternalObjectFunction("Dictionary::Get", Sc_Dict_Get); - ccAddExternalObjectFunction("Dictionary::Remove", Sc_Dict_Remove); - ccAddExternalObjectFunction("Dictionary::Set", Sc_Dict_Set); - ccAddExternalObjectFunction("Dictionary::get_CompareStyle", Sc_Dict_GetCompareStyle); - ccAddExternalObjectFunction("Dictionary::get_SortStyle", Sc_Dict_GetSortStyle); - ccAddExternalObjectFunction("Dictionary::get_ItemCount", Sc_Dict_GetItemCount); - ccAddExternalObjectFunction("Dictionary::GetKeysAsArray", Sc_Dict_GetKeysAsArray); - ccAddExternalObjectFunction("Dictionary::GetValuesAsArray", Sc_Dict_GetValuesAsArray); +void RegisterContainerAPI() { + ccAddExternalStaticFunction("Dictionary::Create", Sc_Dict_Create); + ccAddExternalObjectFunction("Dictionary::Clear", Sc_Dict_Clear); + ccAddExternalObjectFunction("Dictionary::Contains", Sc_Dict_Contains); + ccAddExternalObjectFunction("Dictionary::Get", Sc_Dict_Get); + ccAddExternalObjectFunction("Dictionary::Remove", Sc_Dict_Remove); + ccAddExternalObjectFunction("Dictionary::Set", Sc_Dict_Set); + ccAddExternalObjectFunction("Dictionary::get_CompareStyle", Sc_Dict_GetCompareStyle); + ccAddExternalObjectFunction("Dictionary::get_SortStyle", Sc_Dict_GetSortStyle); + ccAddExternalObjectFunction("Dictionary::get_ItemCount", Sc_Dict_GetItemCount); + ccAddExternalObjectFunction("Dictionary::GetKeysAsArray", Sc_Dict_GetKeysAsArray); + ccAddExternalObjectFunction("Dictionary::GetValuesAsArray", Sc_Dict_GetValuesAsArray); - ccAddExternalStaticFunction("Set::Create", Sc_Set_Create); - ccAddExternalObjectFunction("Set::Add", Sc_Set_Add); - ccAddExternalObjectFunction("Set::Clear", Sc_Set_Clear); - ccAddExternalObjectFunction("Set::Contains", Sc_Set_Contains); - ccAddExternalObjectFunction("Set::Remove", Sc_Set_Remove); - ccAddExternalObjectFunction("Set::get_CompareStyle", Sc_Set_GetCompareStyle); - ccAddExternalObjectFunction("Set::get_SortStyle", Sc_Set_GetSortStyle); - ccAddExternalObjectFunction("Set::get_ItemCount", Sc_Set_GetItemCount); - ccAddExternalObjectFunction("Set::GetItemsAsArray", Sc_Set_GetItemAsArray); + ccAddExternalStaticFunction("Set::Create", Sc_Set_Create); + ccAddExternalObjectFunction("Set::Add", Sc_Set_Add); + ccAddExternalObjectFunction("Set::Clear", Sc_Set_Clear); + ccAddExternalObjectFunction("Set::Contains", Sc_Set_Contains); + ccAddExternalObjectFunction("Set::Remove", Sc_Set_Remove); + ccAddExternalObjectFunction("Set::get_CompareStyle", Sc_Set_GetCompareStyle); + ccAddExternalObjectFunction("Set::get_SortStyle", Sc_Set_GetSortStyle); + ccAddExternalObjectFunction("Set::get_ItemCount", Sc_Set_GetItemCount); + ccAddExternalObjectFunction("Set::GetItemsAsArray", Sc_Set_GetItemAsArray); } diff --git a/engines/ags/engine/ac/slider.cpp b/engines/ags/engine/ac/slider.cpp index f1b6b07c4e2b..2cd6b58e4cda 100644 --- a/engines/ags/engine/ac/slider.cpp +++ b/engines/ags/engine/ac/slider.cpp @@ -27,93 +27,87 @@ void Slider_SetMax(GUISlider *guisl, int valn) { - if (valn != guisl->MaxValue) { - guisl->MaxValue = valn; + if (valn != guisl->MaxValue) { + guisl->MaxValue = valn; - if (guisl->Value > guisl->MaxValue) - guisl->Value = guisl->MaxValue; - if (guisl->MinValue > guisl->MaxValue) - quit("!Slider.Max: minimum cannot be greater than maximum"); + if (guisl->Value > guisl->MaxValue) + guisl->Value = guisl->MaxValue; + if (guisl->MinValue > guisl->MaxValue) + quit("!Slider.Max: minimum cannot be greater than maximum"); - guis_need_update = 1; - } + guis_need_update = 1; + } } int Slider_GetMax(GUISlider *guisl) { - return guisl->MaxValue; + return guisl->MaxValue; } void Slider_SetMin(GUISlider *guisl, int valn) { - if (valn != guisl->MinValue) { - guisl->MinValue = valn; + if (valn != guisl->MinValue) { + guisl->MinValue = valn; - if (guisl->Value < guisl->MinValue) - guisl->Value = guisl->MinValue; - if (guisl->MinValue > guisl->MaxValue) - quit("!Slider.Min: minimum cannot be greater than maximum"); + if (guisl->Value < guisl->MinValue) + guisl->Value = guisl->MinValue; + if (guisl->MinValue > guisl->MaxValue) + quit("!Slider.Min: minimum cannot be greater than maximum"); - guis_need_update = 1; - } + guis_need_update = 1; + } } int Slider_GetMin(GUISlider *guisl) { - return guisl->MinValue; + return guisl->MinValue; } void Slider_SetValue(GUISlider *guisl, int valn) { - if (valn > guisl->MaxValue) valn = guisl->MaxValue; - if (valn < guisl->MinValue) valn = guisl->MinValue; + if (valn > guisl->MaxValue) valn = guisl->MaxValue; + if (valn < guisl->MinValue) valn = guisl->MinValue; - if (valn != guisl->Value) { - guisl->Value = valn; - guis_need_update = 1; - } + if (valn != guisl->Value) { + guisl->Value = valn; + guis_need_update = 1; + } } int Slider_GetValue(GUISlider *guisl) { - return guisl->Value; + return guisl->Value; } int Slider_GetBackgroundGraphic(GUISlider *guisl) { - return (guisl->BgImage > 0) ? guisl->BgImage : 0; + return (guisl->BgImage > 0) ? guisl->BgImage : 0; } -void Slider_SetBackgroundGraphic(GUISlider *guisl, int newImage) -{ - if (newImage != guisl->BgImage) - { - guisl->BgImage = newImage; - guis_need_update = 1; - } +void Slider_SetBackgroundGraphic(GUISlider *guisl, int newImage) { + if (newImage != guisl->BgImage) { + guisl->BgImage = newImage; + guis_need_update = 1; + } } int Slider_GetHandleGraphic(GUISlider *guisl) { - return (guisl->HandleImage > 0) ? guisl->HandleImage : 0; + return (guisl->HandleImage > 0) ? guisl->HandleImage : 0; } -void Slider_SetHandleGraphic(GUISlider *guisl, int newImage) -{ - if (newImage != guisl->HandleImage) - { - guisl->HandleImage = newImage; - guis_need_update = 1; - } +void Slider_SetHandleGraphic(GUISlider *guisl, int newImage) { + if (newImage != guisl->HandleImage) { + guisl->HandleImage = newImage; + guis_need_update = 1; + } } int Slider_GetHandleOffset(GUISlider *guisl) { - return guisl->HandleOffset; + return guisl->HandleOffset; } -void Slider_SetHandleOffset(GUISlider *guisl, int newOffset) -{ - if (newOffset != guisl->HandleOffset) - { - guisl->HandleOffset = newOffset; - guis_need_update = 1; - } +void Slider_SetHandleOffset(GUISlider *guisl, int newOffset) { + if (newOffset != guisl->HandleOffset) { + guisl->HandleOffset = newOffset; + guis_need_update = 1; + } } //============================================================================= @@ -127,105 +121,92 @@ void Slider_SetHandleOffset(GUISlider *guisl, int newOffset) #include "script/script_runtime.h" // int (GUISlider *guisl) -RuntimeScriptValue Sc_Slider_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUISlider, Slider_GetBackgroundGraphic); +RuntimeScriptValue Sc_Slider_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUISlider, Slider_GetBackgroundGraphic); } // void (GUISlider *guisl, int newImage) -RuntimeScriptValue Sc_Slider_SetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUISlider, Slider_SetBackgroundGraphic); +RuntimeScriptValue Sc_Slider_SetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetBackgroundGraphic); } // int (GUISlider *guisl) -RuntimeScriptValue Sc_Slider_GetHandleGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUISlider, Slider_GetHandleGraphic); +RuntimeScriptValue Sc_Slider_GetHandleGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUISlider, Slider_GetHandleGraphic); } // void (GUISlider *guisl, int newImage) -RuntimeScriptValue Sc_Slider_SetHandleGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUISlider, Slider_SetHandleGraphic); +RuntimeScriptValue Sc_Slider_SetHandleGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetHandleGraphic); } // int (GUISlider *guisl) -RuntimeScriptValue Sc_Slider_GetHandleOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUISlider, Slider_GetHandleOffset); +RuntimeScriptValue Sc_Slider_GetHandleOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUISlider, Slider_GetHandleOffset); } // void (GUISlider *guisl, int newOffset) -RuntimeScriptValue Sc_Slider_SetHandleOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUISlider, Slider_SetHandleOffset); +RuntimeScriptValue Sc_Slider_SetHandleOffset(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetHandleOffset); } // int (GUISlider *guisl) -RuntimeScriptValue Sc_Slider_GetMax(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUISlider, Slider_GetMax); +RuntimeScriptValue Sc_Slider_GetMax(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUISlider, Slider_GetMax); } // void (GUISlider *guisl, int valn) -RuntimeScriptValue Sc_Slider_SetMax(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUISlider, Slider_SetMax); +RuntimeScriptValue Sc_Slider_SetMax(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetMax); } // int (GUISlider *guisl) -RuntimeScriptValue Sc_Slider_GetMin(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUISlider, Slider_GetMin); +RuntimeScriptValue Sc_Slider_GetMin(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUISlider, Slider_GetMin); } // void (GUISlider *guisl, int valn) -RuntimeScriptValue Sc_Slider_SetMin(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUISlider, Slider_SetMin); +RuntimeScriptValue Sc_Slider_SetMin(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetMin); } // int (GUISlider *guisl) -RuntimeScriptValue Sc_Slider_GetValue(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUISlider, Slider_GetValue); +RuntimeScriptValue Sc_Slider_GetValue(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUISlider, Slider_GetValue); } // void Slider_SetValue(GUISlider *guisl, int valn) -RuntimeScriptValue Sc_Slider_SetValue(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUISlider, Slider_SetValue); -} - - -void RegisterSliderAPI() -{ - ccAddExternalObjectFunction("Slider::get_BackgroundGraphic", Sc_Slider_GetBackgroundGraphic); - ccAddExternalObjectFunction("Slider::set_BackgroundGraphic", Sc_Slider_SetBackgroundGraphic); - ccAddExternalObjectFunction("Slider::get_HandleGraphic", Sc_Slider_GetHandleGraphic); - ccAddExternalObjectFunction("Slider::set_HandleGraphic", Sc_Slider_SetHandleGraphic); - ccAddExternalObjectFunction("Slider::get_HandleOffset", Sc_Slider_GetHandleOffset); - ccAddExternalObjectFunction("Slider::set_HandleOffset", Sc_Slider_SetHandleOffset); - ccAddExternalObjectFunction("Slider::get_Max", Sc_Slider_GetMax); - ccAddExternalObjectFunction("Slider::set_Max", Sc_Slider_SetMax); - ccAddExternalObjectFunction("Slider::get_Min", Sc_Slider_GetMin); - ccAddExternalObjectFunction("Slider::set_Min", Sc_Slider_SetMin); - ccAddExternalObjectFunction("Slider::get_Value", Sc_Slider_GetValue); - ccAddExternalObjectFunction("Slider::set_Value", Sc_Slider_SetValue); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("Slider::get_BackgroundGraphic", (void*)Slider_GetBackgroundGraphic); - ccAddExternalFunctionForPlugin("Slider::set_BackgroundGraphic", (void*)Slider_SetBackgroundGraphic); - ccAddExternalFunctionForPlugin("Slider::get_HandleGraphic", (void*)Slider_GetHandleGraphic); - ccAddExternalFunctionForPlugin("Slider::set_HandleGraphic", (void*)Slider_SetHandleGraphic); - ccAddExternalFunctionForPlugin("Slider::get_HandleOffset", (void*)Slider_GetHandleOffset); - ccAddExternalFunctionForPlugin("Slider::set_HandleOffset", (void*)Slider_SetHandleOffset); - ccAddExternalFunctionForPlugin("Slider::get_Max", (void*)Slider_GetMax); - ccAddExternalFunctionForPlugin("Slider::set_Max", (void*)Slider_SetMax); - ccAddExternalFunctionForPlugin("Slider::get_Min", (void*)Slider_GetMin); - ccAddExternalFunctionForPlugin("Slider::set_Min", (void*)Slider_SetMin); - ccAddExternalFunctionForPlugin("Slider::get_Value", (void*)Slider_GetValue); - ccAddExternalFunctionForPlugin("Slider::set_Value", (void*)Slider_SetValue); +RuntimeScriptValue Sc_Slider_SetValue(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUISlider, Slider_SetValue); +} + + +void RegisterSliderAPI() { + ccAddExternalObjectFunction("Slider::get_BackgroundGraphic", Sc_Slider_GetBackgroundGraphic); + ccAddExternalObjectFunction("Slider::set_BackgroundGraphic", Sc_Slider_SetBackgroundGraphic); + ccAddExternalObjectFunction("Slider::get_HandleGraphic", Sc_Slider_GetHandleGraphic); + ccAddExternalObjectFunction("Slider::set_HandleGraphic", Sc_Slider_SetHandleGraphic); + ccAddExternalObjectFunction("Slider::get_HandleOffset", Sc_Slider_GetHandleOffset); + ccAddExternalObjectFunction("Slider::set_HandleOffset", Sc_Slider_SetHandleOffset); + ccAddExternalObjectFunction("Slider::get_Max", Sc_Slider_GetMax); + ccAddExternalObjectFunction("Slider::set_Max", Sc_Slider_SetMax); + ccAddExternalObjectFunction("Slider::get_Min", Sc_Slider_GetMin); + ccAddExternalObjectFunction("Slider::set_Min", Sc_Slider_SetMin); + ccAddExternalObjectFunction("Slider::get_Value", Sc_Slider_GetValue); + ccAddExternalObjectFunction("Slider::set_Value", Sc_Slider_SetValue); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("Slider::get_BackgroundGraphic", (void *)Slider_GetBackgroundGraphic); + ccAddExternalFunctionForPlugin("Slider::set_BackgroundGraphic", (void *)Slider_SetBackgroundGraphic); + ccAddExternalFunctionForPlugin("Slider::get_HandleGraphic", (void *)Slider_GetHandleGraphic); + ccAddExternalFunctionForPlugin("Slider::set_HandleGraphic", (void *)Slider_SetHandleGraphic); + ccAddExternalFunctionForPlugin("Slider::get_HandleOffset", (void *)Slider_GetHandleOffset); + ccAddExternalFunctionForPlugin("Slider::set_HandleOffset", (void *)Slider_SetHandleOffset); + ccAddExternalFunctionForPlugin("Slider::get_Max", (void *)Slider_GetMax); + ccAddExternalFunctionForPlugin("Slider::set_Max", (void *)Slider_SetMax); + ccAddExternalFunctionForPlugin("Slider::get_Min", (void *)Slider_GetMin); + ccAddExternalFunctionForPlugin("Slider::set_Min", (void *)Slider_SetMin); + ccAddExternalFunctionForPlugin("Slider::get_Value", (void *)Slider_GetValue); + ccAddExternalFunctionForPlugin("Slider::set_Value", (void *)Slider_SetValue); } diff --git a/engines/ags/engine/ac/slider.h b/engines/ags/engine/ac/slider.h index 3ce4329cc24e..8d0b21dff552 100644 --- a/engines/ags/engine/ac/slider.h +++ b/engines/ags/engine/ac/slider.h @@ -27,17 +27,17 @@ using AGS::Common::GUISlider; -void Slider_SetMax(GUISlider *guisl, int valn); -int Slider_GetMax(GUISlider *guisl); -void Slider_SetMin(GUISlider *guisl, int valn); -int Slider_GetMin(GUISlider *guisl); -void Slider_SetValue(GUISlider *guisl, int valn); -int Slider_GetValue(GUISlider *guisl); -int Slider_GetBackgroundGraphic(GUISlider *guisl); -void Slider_SetBackgroundGraphic(GUISlider *guisl, int newImage); -int Slider_GetHandleGraphic(GUISlider *guisl); -void Slider_SetHandleGraphic(GUISlider *guisl, int newImage); -int Slider_GetHandleOffset(GUISlider *guisl); -void Slider_SetHandleOffset(GUISlider *guisl, int newOffset); +void Slider_SetMax(GUISlider *guisl, int valn); +int Slider_GetMax(GUISlider *guisl); +void Slider_SetMin(GUISlider *guisl, int valn); +int Slider_GetMin(GUISlider *guisl); +void Slider_SetValue(GUISlider *guisl, int valn); +int Slider_GetValue(GUISlider *guisl); +int Slider_GetBackgroundGraphic(GUISlider *guisl); +void Slider_SetBackgroundGraphic(GUISlider *guisl, int newImage); +int Slider_GetHandleGraphic(GUISlider *guisl); +void Slider_SetHandleGraphic(GUISlider *guisl, int newImage); +int Slider_GetHandleOffset(GUISlider *guisl); +void Slider_SetHandleOffset(GUISlider *guisl, int newOffset); #endif diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp index ebe0db73be24..32c416a7c6ff 100644 --- a/engines/ags/engine/ac/speech.cpp +++ b/engines/ags/engine/ac/speech.cpp @@ -25,65 +25,49 @@ #include "ac/speech.h" #include "debug/debug_log.h" -int user_to_internal_skip_speech(SkipSpeechStyle userval) -{ - switch (userval) - { - case kSkipSpeechKeyMouseTime: - return SKIP_AUTOTIMER | SKIP_KEYPRESS | SKIP_MOUSECLICK; - case kSkipSpeechKeyTime: - return SKIP_AUTOTIMER | SKIP_KEYPRESS; - case kSkipSpeechTime: - return SKIP_AUTOTIMER; - case kSkipSpeechKeyMouse: - return SKIP_KEYPRESS | SKIP_MOUSECLICK; - case kSkipSpeechMouseTime: - return SKIP_AUTOTIMER | SKIP_MOUSECLICK; - case kSkipSpeechKey: - return SKIP_KEYPRESS; - case kSkipSpeechMouse: - return SKIP_MOUSECLICK; - default: - quit("user_to_internal_skip_speech: unknown userval"); - return 0; - } -} - -SkipSpeechStyle internal_skip_speech_to_user(int internal_val) -{ - if (internal_val & SKIP_AUTOTIMER) - { - internal_val &= ~SKIP_AUTOTIMER; - if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) - { - return kSkipSpeechKeyMouseTime; - } - else if (internal_val == SKIP_KEYPRESS) - { - return kSkipSpeechKeyTime; - } - else if (internal_val == SKIP_MOUSECLICK) - { - return kSkipSpeechMouseTime; - } - return kSkipSpeechTime; - } - else - { - if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) - { - return kSkipSpeechKeyMouse; - } - else if (internal_val == SKIP_KEYPRESS) - { - return kSkipSpeechKey; - } - else if (internal_val == SKIP_MOUSECLICK) - { - return kSkipSpeechMouse; - } - } - return kSkipSpeechUndefined; +int user_to_internal_skip_speech(SkipSpeechStyle userval) { + switch (userval) { + case kSkipSpeechKeyMouseTime: + return SKIP_AUTOTIMER | SKIP_KEYPRESS | SKIP_MOUSECLICK; + case kSkipSpeechKeyTime: + return SKIP_AUTOTIMER | SKIP_KEYPRESS; + case kSkipSpeechTime: + return SKIP_AUTOTIMER; + case kSkipSpeechKeyMouse: + return SKIP_KEYPRESS | SKIP_MOUSECLICK; + case kSkipSpeechMouseTime: + return SKIP_AUTOTIMER | SKIP_MOUSECLICK; + case kSkipSpeechKey: + return SKIP_KEYPRESS; + case kSkipSpeechMouse: + return SKIP_MOUSECLICK; + default: + quit("user_to_internal_skip_speech: unknown userval"); + return 0; + } +} + +SkipSpeechStyle internal_skip_speech_to_user(int internal_val) { + if (internal_val & SKIP_AUTOTIMER) { + internal_val &= ~SKIP_AUTOTIMER; + if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) { + return kSkipSpeechKeyMouseTime; + } else if (internal_val == SKIP_KEYPRESS) { + return kSkipSpeechKeyTime; + } else if (internal_val == SKIP_MOUSECLICK) { + return kSkipSpeechMouseTime; + } + return kSkipSpeechTime; + } else { + if (internal_val == (SKIP_KEYPRESS | SKIP_MOUSECLICK)) { + return kSkipSpeechKeyMouse; + } else if (internal_val == SKIP_KEYPRESS) { + return kSkipSpeechKey; + } else if (internal_val == SKIP_MOUSECLICK) { + return kSkipSpeechMouse; + } + } + return kSkipSpeechUndefined; } //============================================================================= @@ -103,160 +87,136 @@ SkipSpeechStyle internal_skip_speech_to_user(int internal_val) extern GameSetupStruct game; extern GameState play; -RuntimeScriptValue Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(play.close_mouth_speech_time); +RuntimeScriptValue Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(play.close_mouth_speech_time); } -RuntimeScriptValue Sc_Speech_SetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARSET_PINT(play.close_mouth_speech_time); +RuntimeScriptValue Sc_Speech_SetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) { + API_VARSET_PINT(play.close_mouth_speech_time); } -RuntimeScriptValue Sc_Speech_GetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(play.speech_portrait_placement); +RuntimeScriptValue Sc_Speech_GetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(play.speech_portrait_placement); } -RuntimeScriptValue Sc_Speech_SetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARSET_PINT(play.speech_portrait_placement); +RuntimeScriptValue Sc_Speech_SetCustomPortraitPlacement(const RuntimeScriptValue *params, int32_t param_count) { + API_VARSET_PINT(play.speech_portrait_placement); } -RuntimeScriptValue Sc_Speech_GetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(play.speech_display_post_time_ms); +RuntimeScriptValue Sc_Speech_GetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(play.speech_display_post_time_ms); } -RuntimeScriptValue Sc_Speech_SetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARSET_PINT(play.speech_display_post_time_ms); +RuntimeScriptValue Sc_Speech_SetDisplayPostTimeMs(const RuntimeScriptValue *params, int32_t param_count) { + API_VARSET_PINT(play.speech_display_post_time_ms); } -RuntimeScriptValue Sc_Speech_GetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) -{ +RuntimeScriptValue Sc_Speech_GetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) { API_VARGET_INT(play.talkanim_speed); } -RuntimeScriptValue Sc_Speech_SetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) -{ - if (game.options[OPT_GLOBALTALKANIMSPD] == 0) - { - debug_script_warn("Speech.GlobalSpeechAnimationDelay cannot be set when global speech animation speed is not enabled; set Speech.UseGlobalSpeechAnimationDelay first!"); - return RuntimeScriptValue(); - } +RuntimeScriptValue Sc_Speech_SetGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) { + if (game.options[OPT_GLOBALTALKANIMSPD] == 0) { + debug_script_warn("Speech.GlobalSpeechAnimationDelay cannot be set when global speech animation speed is not enabled; set Speech.UseGlobalSpeechAnimationDelay first!"); + return RuntimeScriptValue(); + } API_VARSET_PINT(play.talkanim_speed); } -RuntimeScriptValue Sc_Speech_GetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(play.speech_portrait_x); +RuntimeScriptValue Sc_Speech_GetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(play.speech_portrait_x); } -RuntimeScriptValue Sc_Speech_SetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARSET_PINT(play.speech_portrait_x); +RuntimeScriptValue Sc_Speech_SetPortraitXOffset(const RuntimeScriptValue *params, int32_t param_count) { + API_VARSET_PINT(play.speech_portrait_x); } -RuntimeScriptValue Sc_Speech_GetPortraitY(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(play.speech_portrait_y); +RuntimeScriptValue Sc_Speech_GetPortraitY(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(play.speech_portrait_y); } -RuntimeScriptValue Sc_Speech_SetPortraitY(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARSET_PINT(play.speech_portrait_y); +RuntimeScriptValue Sc_Speech_SetPortraitY(const RuntimeScriptValue *params, int32_t param_count) { + API_VARSET_PINT(play.speech_portrait_y); } -RuntimeScriptValue Sc_Speech_GetStyle(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(game.options[OPT_SPEECHTYPE]); +RuntimeScriptValue Sc_Speech_GetStyle(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(game.options[OPT_SPEECHTYPE]); } extern RuntimeScriptValue Sc_SetSpeechStyle(const RuntimeScriptValue *params, int32_t param_count); -RuntimeScriptValue Sc_Speech_GetSkipKey(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(play.skip_speech_specific_key); +RuntimeScriptValue Sc_Speech_GetSkipKey(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(play.skip_speech_specific_key); } -RuntimeScriptValue Sc_Speech_SetSkipKey(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARSET_PINT(play.skip_speech_specific_key); +RuntimeScriptValue Sc_Speech_SetSkipKey(const RuntimeScriptValue *params, int32_t param_count) { + API_VARSET_PINT(play.skip_speech_specific_key); } -RuntimeScriptValue Sc_Speech_GetSkipStyle(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetSkipSpeech); +RuntimeScriptValue Sc_Speech_GetSkipStyle(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetSkipSpeech); } extern RuntimeScriptValue Sc_SetSkipSpeech(const RuntimeScriptValue *params, int32_t param_count); -RuntimeScriptValue Sc_Speech_GetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) -{ - API_VARGET_INT(play.speech_text_align); +RuntimeScriptValue Sc_Speech_GetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) { + API_VARGET_INT(play.speech_text_align); } -RuntimeScriptValue Sc_Speech_SetTextAlignment_Old(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_VARIABLE_VALUE(play.speech_text_align); - play.speech_text_align = ReadScriptAlignment(params[0].IValue); - return RuntimeScriptValue(); +RuntimeScriptValue Sc_Speech_SetTextAlignment_Old(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_VARIABLE_VALUE(play.speech_text_align); + play.speech_text_align = ReadScriptAlignment(params[0].IValue); + return RuntimeScriptValue(); } -RuntimeScriptValue Sc_Speech_SetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_VARIABLE_VALUE(play.speech_text_align); - play.speech_text_align = (HorAlignment)params[0].IValue; - return RuntimeScriptValue(); +RuntimeScriptValue Sc_Speech_SetTextAlignment(const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_VARIABLE_VALUE(play.speech_text_align); + play.speech_text_align = (HorAlignment)params[0].IValue; + return RuntimeScriptValue(); } -RuntimeScriptValue Sc_Speech_GetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) -{ +RuntimeScriptValue Sc_Speech_GetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) { API_VARGET_INT(game.options[OPT_GLOBALTALKANIMSPD]); } -RuntimeScriptValue Sc_Speech_SetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) -{ +RuntimeScriptValue Sc_Speech_SetUseGlobalSpeechAnimationDelay(const RuntimeScriptValue *params, int32_t param_count) { API_VARSET_PINT(game.options[OPT_GLOBALTALKANIMSPD]); } -RuntimeScriptValue Sc_Speech_GetVoiceMode(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(GetVoiceMode); +RuntimeScriptValue Sc_Speech_GetVoiceMode(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(GetVoiceMode); } extern RuntimeScriptValue Sc_SetVoiceMode(const RuntimeScriptValue *params, int32_t param_count); -void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) -{ - ccAddExternalStaticFunction("Speech::get_AnimationStopTimeMargin", Sc_Speech_GetAnimationStopTimeMargin); - ccAddExternalStaticFunction("Speech::set_AnimationStopTimeMargin", Sc_Speech_SetAnimationStopTimeMargin); - ccAddExternalStaticFunction("Speech::get_CustomPortraitPlacement", Sc_Speech_GetCustomPortraitPlacement); - ccAddExternalStaticFunction("Speech::set_CustomPortraitPlacement", Sc_Speech_SetCustomPortraitPlacement); - ccAddExternalStaticFunction("Speech::get_DisplayPostTimeMs", Sc_Speech_GetDisplayPostTimeMs); - ccAddExternalStaticFunction("Speech::set_DisplayPostTimeMs", Sc_Speech_SetDisplayPostTimeMs); +void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) { + ccAddExternalStaticFunction("Speech::get_AnimationStopTimeMargin", Sc_Speech_GetAnimationStopTimeMargin); + ccAddExternalStaticFunction("Speech::set_AnimationStopTimeMargin", Sc_Speech_SetAnimationStopTimeMargin); + ccAddExternalStaticFunction("Speech::get_CustomPortraitPlacement", Sc_Speech_GetCustomPortraitPlacement); + ccAddExternalStaticFunction("Speech::set_CustomPortraitPlacement", Sc_Speech_SetCustomPortraitPlacement); + ccAddExternalStaticFunction("Speech::get_DisplayPostTimeMs", Sc_Speech_GetDisplayPostTimeMs); + ccAddExternalStaticFunction("Speech::set_DisplayPostTimeMs", Sc_Speech_SetDisplayPostTimeMs); ccAddExternalStaticFunction("Speech::get_GlobalSpeechAnimationDelay", Sc_Speech_GetGlobalSpeechAnimationDelay); ccAddExternalStaticFunction("Speech::set_GlobalSpeechAnimationDelay", Sc_Speech_SetGlobalSpeechAnimationDelay); - ccAddExternalStaticFunction("Speech::get_PortraitXOffset", Sc_Speech_GetPortraitXOffset); - ccAddExternalStaticFunction("Speech::set_PortraitXOffset", Sc_Speech_SetPortraitXOffset); - ccAddExternalStaticFunction("Speech::get_PortraitY", Sc_Speech_GetPortraitY); - ccAddExternalStaticFunction("Speech::set_PortraitY", Sc_Speech_SetPortraitY); - ccAddExternalStaticFunction("Speech::get_SkipKey", Sc_Speech_GetSkipKey); - ccAddExternalStaticFunction("Speech::set_SkipKey", Sc_Speech_SetSkipKey); - ccAddExternalStaticFunction("Speech::get_SkipStyle", Sc_Speech_GetSkipStyle); - ccAddExternalStaticFunction("Speech::set_SkipStyle", Sc_SetSkipSpeech); - ccAddExternalStaticFunction("Speech::get_Style", Sc_Speech_GetStyle); - ccAddExternalStaticFunction("Speech::set_Style", Sc_SetSpeechStyle); - ccAddExternalStaticFunction("Speech::get_TextAlignment", Sc_Speech_GetTextAlignment); - if (base_api < kScriptAPI_v350) - ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment_Old); - else - ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment); + ccAddExternalStaticFunction("Speech::get_PortraitXOffset", Sc_Speech_GetPortraitXOffset); + ccAddExternalStaticFunction("Speech::set_PortraitXOffset", Sc_Speech_SetPortraitXOffset); + ccAddExternalStaticFunction("Speech::get_PortraitY", Sc_Speech_GetPortraitY); + ccAddExternalStaticFunction("Speech::set_PortraitY", Sc_Speech_SetPortraitY); + ccAddExternalStaticFunction("Speech::get_SkipKey", Sc_Speech_GetSkipKey); + ccAddExternalStaticFunction("Speech::set_SkipKey", Sc_Speech_SetSkipKey); + ccAddExternalStaticFunction("Speech::get_SkipStyle", Sc_Speech_GetSkipStyle); + ccAddExternalStaticFunction("Speech::set_SkipStyle", Sc_SetSkipSpeech); + ccAddExternalStaticFunction("Speech::get_Style", Sc_Speech_GetStyle); + ccAddExternalStaticFunction("Speech::set_Style", Sc_SetSpeechStyle); + ccAddExternalStaticFunction("Speech::get_TextAlignment", Sc_Speech_GetTextAlignment); + if (base_api < kScriptAPI_v350) + ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment_Old); + else + ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment); ccAddExternalStaticFunction("Speech::get_UseGlobalSpeechAnimationDelay", Sc_Speech_GetUseGlobalSpeechAnimationDelay); ccAddExternalStaticFunction("Speech::set_UseGlobalSpeechAnimationDelay", Sc_Speech_SetUseGlobalSpeechAnimationDelay); - ccAddExternalStaticFunction("Speech::get_VoiceMode", Sc_Speech_GetVoiceMode); - ccAddExternalStaticFunction("Speech::set_VoiceMode", Sc_SetVoiceMode); + ccAddExternalStaticFunction("Speech::get_VoiceMode", Sc_Speech_GetVoiceMode); + ccAddExternalStaticFunction("Speech::set_VoiceMode", Sc_SetVoiceMode); - /* -- Don't register more unsafe plugin symbols until new plugin interface is designed --*/ + /* -- Don't register more unsafe plugin symbols until new plugin interface is designed --*/ } diff --git a/engines/ags/engine/ac/speech.h b/engines/ags/engine/ac/speech.h index 58179f8327cc..e3eea3c030e3 100644 --- a/engines/ags/engine/ac/speech.h +++ b/engines/ags/engine/ac/speech.h @@ -23,19 +23,18 @@ #ifndef AGS_ENGINE_AC_SPEECH_H #define AGS_ENGINE_AC_SPEECH_H -enum SkipSpeechStyle -{ - kSkipSpeechUndefined = -1, - kSkipSpeechKeyMouseTime = 0, - kSkipSpeechKeyTime = 1, - kSkipSpeechTime = 2, - kSkipSpeechKeyMouse = 3, - kSkipSpeechMouseTime = 4, - kSkipSpeechKey = 5, - kSkipSpeechMouse = 6, +enum SkipSpeechStyle { + kSkipSpeechUndefined = -1, + kSkipSpeechKeyMouseTime = 0, + kSkipSpeechKeyTime = 1, + kSkipSpeechTime = 2, + kSkipSpeechKeyMouse = 3, + kSkipSpeechMouseTime = 4, + kSkipSpeechKey = 5, + kSkipSpeechMouse = 6, - kSkipSpeechFirst = kSkipSpeechKeyMouseTime, - kSkipSpeechLast = kSkipSpeechMouse + kSkipSpeechFirst = kSkipSpeechKeyMouseTime, + kSkipSpeechLast = kSkipSpeechMouse }; int user_to_internal_skip_speech(SkipSpeechStyle userval); diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp index f5b10160041c..c34bc4dfa99a 100644 --- a/engines/ags/engine/ac/sprite.cpp +++ b/engines/ags/engine/ac/sprite.cpp @@ -42,153 +42,142 @@ extern color palette[256]; extern IGraphicsDriver *gfxDriver; extern AGSPlatformDriver *platform; -void get_new_size_for_sprite (int ee, int ww, int hh, int &newwid, int &newhit) -{ - newwid = ww; - newhit = hh; - const SpriteInfo &spinfo = game.SpriteInfos[ee]; - if (!game.AllowRelativeRes() || !spinfo.IsRelativeRes()) - return; - ctx_data_to_game_size(newwid, newhit, spinfo.IsLegacyHiRes()); +void get_new_size_for_sprite(int ee, int ww, int hh, int &newwid, int &newhit) { + newwid = ww; + newhit = hh; + const SpriteInfo &spinfo = game.SpriteInfos[ee]; + if (!game.AllowRelativeRes() || !spinfo.IsRelativeRes()) + return; + ctx_data_to_game_size(newwid, newhit, spinfo.IsLegacyHiRes()); } // set any alpha-transparent pixels in the image to the appropriate // RGB mask value so that the blit calls work correctly -void set_rgb_mask_using_alpha_channel(Bitmap *image) -{ - int x, y; - - for (y=0; y < image->GetHeight(); y++) - { - unsigned int*psrc = (unsigned int *)image->GetScanLine(y); - - for (x=0; x < image->GetWidth(); x++) - { - if ((psrc[x] & 0xff000000) == 0x00000000) - psrc[x] = MASK_COLOR_32; - } - } +void set_rgb_mask_using_alpha_channel(Bitmap *image) { + int x, y; + + for (y = 0; y < image->GetHeight(); y++) { + unsigned int *psrc = (unsigned int *)image->GetScanLine(y); + + for (x = 0; x < image->GetWidth(); x++) { + if ((psrc[x] & 0xff000000) == 0x00000000) + psrc[x] = MASK_COLOR_32; + } + } } // from is a 32-bit RGBA image, to is a 15/16/24-bit destination image -Bitmap *remove_alpha_channel(Bitmap *from) -{ - const int game_cd = game.GetColorDepth(); - Bitmap *to = BitmapHelper::CreateBitmap(from->GetWidth(), from->GetHeight(), game_cd); - const int maskcol = to->GetMaskColor(); - int y,x; - unsigned int c,b,g,r; - - if (game_cd == 24) // 32-to-24 - { - for (y=0; y < from->GetHeight(); y++) { - unsigned int*psrc = (unsigned int *)from->GetScanLine(y); - unsigned char*pdest = (unsigned char*)to->GetScanLine(y); - - for (x=0; x < from->GetWidth(); x++) { - c = psrc[x]; - // less than 50% opaque, remove the pixel - if (((c >> 24) & 0x00ff) < 128) - c = maskcol; - - // copy the RGB values across - memcpy(&pdest[x * 3], &c, 3); - } - } - } - else if (game_cd > 8) // 32 to 15 or 16 - { - for (y=0; y < from->GetHeight(); y++) { - unsigned int*psrc = (unsigned int *)from->GetScanLine(y); - unsigned short*pdest = (unsigned short *)to->GetScanLine(y); - - for (x=0; x < from->GetWidth(); x++) { - c = psrc[x]; - // less than 50% opaque, remove the pixel - if (((c >> 24) & 0x00ff) < 128) - pdest[x] = maskcol; - else { - // otherwise, copy it across - r = (c >> 16) & 0x00ff; - g = (c >> 8) & 0x00ff; - b = c & 0x00ff; - pdest[x] = makecol_depth(game_cd, r, g, b); - } - } - } - } - else // 32 to 8-bit game - { // TODO: consider similar to above approach if this becomes a wanted feature - to->Blit(from); - } - return to; +Bitmap *remove_alpha_channel(Bitmap *from) { + const int game_cd = game.GetColorDepth(); + Bitmap *to = BitmapHelper::CreateBitmap(from->GetWidth(), from->GetHeight(), game_cd); + const int maskcol = to->GetMaskColor(); + int y, x; + unsigned int c, b, g, r; + + if (game_cd == 24) { // 32-to-24 + for (y = 0; y < from->GetHeight(); y++) { + unsigned int *psrc = (unsigned int *)from->GetScanLine(y); + unsigned char *pdest = (unsigned char *)to->GetScanLine(y); + + for (x = 0; x < from->GetWidth(); x++) { + c = psrc[x]; + // less than 50% opaque, remove the pixel + if (((c >> 24) & 0x00ff) < 128) + c = maskcol; + + // copy the RGB values across + memcpy(&pdest[x * 3], &c, 3); + } + } + } else if (game_cd > 8) { // 32 to 15 or 16 + for (y = 0; y < from->GetHeight(); y++) { + unsigned int *psrc = (unsigned int *)from->GetScanLine(y); + unsigned short *pdest = (unsigned short *)to->GetScanLine(y); + + for (x = 0; x < from->GetWidth(); x++) { + c = psrc[x]; + // less than 50% opaque, remove the pixel + if (((c >> 24) & 0x00ff) < 128) + pdest[x] = maskcol; + else { + // otherwise, copy it across + r = (c >> 16) & 0x00ff; + g = (c >> 8) & 0x00ff; + b = c & 0x00ff; + pdest[x] = makecol_depth(game_cd, r, g, b); + } + } + } + } else { // 32 to 8-bit game + // TODO: consider similar to above approach if this becomes a wanted feature + to->Blit(from); + } + return to; } void pre_save_sprite(int ee) { - // not used, we don't save + // not used, we don't save } // these vars are global to help with debugging Bitmap *tmpdbl, *curspr; int newwid, newhit; -void initialize_sprite (int ee) { - - if ((ee < 0) || (ee > spriteset.GetSpriteSlotCount())) - quit("initialize_sprite: invalid sprite number"); - - if ((spriteset[ee] == nullptr) && (ee > 0)) { - // replace empty sprites with blue cups, to avoid crashes - spriteset.RemapSpriteToSprite0(ee); - } - else if (spriteset[ee]==nullptr) { - game.SpriteInfos[ee].Width=0; - game.SpriteInfos[ee].Height=0; - } - else { - // stretch sprites to correct resolution - int oldeip = our_eip; - our_eip = 4300; - - if (game.SpriteInfos[ee].Flags & SPF_HADALPHACHANNEL) { - // we stripped the alpha channel out last time, put - // it back so that we can remove it properly again - game.SpriteInfos[ee].Flags |= SPF_ALPHACHANNEL; - } - - curspr = spriteset[ee]; - get_new_size_for_sprite (ee, curspr->GetWidth(), curspr->GetHeight(), newwid, newhit); - - eip_guinum = ee; - eip_guiobj = newwid; - - if ((newwid != curspr->GetWidth()) || (newhit != curspr->GetHeight())) { - tmpdbl = BitmapHelper::CreateTransparentBitmap(newwid,newhit,curspr->GetColorDepth()); - if (tmpdbl == nullptr) - quit("Not enough memory to load sprite graphics"); - tmpdbl->Acquire (); - curspr->Acquire (); - tmpdbl->StretchBlt(curspr,RectWH(0,0,tmpdbl->GetWidth(),tmpdbl->GetHeight()), Common::kBitmap_Transparency); - curspr->Release (); - tmpdbl->Release (); - delete curspr; - spriteset.SubstituteBitmap(ee, tmpdbl); - } - - game.SpriteInfos[ee].Width=spriteset[ee]->GetWidth(); - game.SpriteInfos[ee].Height=spriteset[ee]->GetHeight(); - - spriteset.SubstituteBitmap(ee, PrepareSpriteForUse(spriteset[ee], (game.SpriteInfos[ee].Flags & SPF_ALPHACHANNEL) != 0)); - - if (game.GetColorDepth() < 32) { - game.SpriteInfos[ee].Flags &= ~SPF_ALPHACHANNEL; - // save the fact that it had one for the next time this - // is re-loaded from disk - game.SpriteInfos[ee].Flags |= SPF_HADALPHACHANNEL; - } - - pl_run_plugin_hooks(AGSE_SPRITELOAD, ee); - update_polled_stuff_if_runtime(); - - our_eip = oldeip; - } +void initialize_sprite(int ee) { + + if ((ee < 0) || (ee > spriteset.GetSpriteSlotCount())) + quit("initialize_sprite: invalid sprite number"); + + if ((spriteset[ee] == nullptr) && (ee > 0)) { + // replace empty sprites with blue cups, to avoid crashes + spriteset.RemapSpriteToSprite0(ee); + } else if (spriteset[ee] == nullptr) { + game.SpriteInfos[ee].Width = 0; + game.SpriteInfos[ee].Height = 0; + } else { + // stretch sprites to correct resolution + int oldeip = our_eip; + our_eip = 4300; + + if (game.SpriteInfos[ee].Flags & SPF_HADALPHACHANNEL) { + // we stripped the alpha channel out last time, put + // it back so that we can remove it properly again + game.SpriteInfos[ee].Flags |= SPF_ALPHACHANNEL; + } + + curspr = spriteset[ee]; + get_new_size_for_sprite(ee, curspr->GetWidth(), curspr->GetHeight(), newwid, newhit); + + eip_guinum = ee; + eip_guiobj = newwid; + + if ((newwid != curspr->GetWidth()) || (newhit != curspr->GetHeight())) { + tmpdbl = BitmapHelper::CreateTransparentBitmap(newwid, newhit, curspr->GetColorDepth()); + if (tmpdbl == nullptr) + quit("Not enough memory to load sprite graphics"); + tmpdbl->Acquire(); + curspr->Acquire(); + tmpdbl->StretchBlt(curspr, RectWH(0, 0, tmpdbl->GetWidth(), tmpdbl->GetHeight()), Common::kBitmap_Transparency); + curspr->Release(); + tmpdbl->Release(); + delete curspr; + spriteset.SubstituteBitmap(ee, tmpdbl); + } + + game.SpriteInfos[ee].Width = spriteset[ee]->GetWidth(); + game.SpriteInfos[ee].Height = spriteset[ee]->GetHeight(); + + spriteset.SubstituteBitmap(ee, PrepareSpriteForUse(spriteset[ee], (game.SpriteInfos[ee].Flags & SPF_ALPHACHANNEL) != 0)); + + if (game.GetColorDepth() < 32) { + game.SpriteInfos[ee].Flags &= ~SPF_ALPHACHANNEL; + // save the fact that it had one for the next time this + // is re-loaded from disk + game.SpriteInfos[ee].Flags |= SPF_HADALPHACHANNEL; + } + + pl_run_plugin_hooks(AGSE_SPRITELOAD, ee); + update_polled_stuff_if_runtime(); + + our_eip = oldeip; + } } diff --git a/engines/ags/engine/ac/sprite.h b/engines/ags/engine/ac/sprite.h index d97d00f74a56..a5d15f35f151 100644 --- a/engines/ags/engine/ac/sprite.h +++ b/engines/ags/engine/ac/sprite.h @@ -23,13 +23,13 @@ #ifndef AGS_ENGINE_AC_SPRITE_H #define AGS_ENGINE_AC_SPRITE_H -void get_new_size_for_sprite (int ee, int ww, int hh, int &newwid, int &newhit); +void get_new_size_for_sprite(int ee, int ww, int hh, int &newwid, int &newhit); // set any alpha-transparent pixels in the image to the appropriate // RGB mask value so that the ->Blit calls work correctly void set_rgb_mask_using_alpha_channel(Common::Bitmap *image); // from is a 32-bit RGBA image, to is a 15/16/24-bit destination image Common::Bitmap *remove_alpha_channel(Common::Bitmap *from); void pre_save_sprite(int ee); -void initialize_sprite (int ee); +void initialize_sprite(int ee); #endif diff --git a/engines/ags/engine/ac/spritecache_engine.cpp b/engines/ags/engine/ac/spritecache_engine.cpp index df0a8dec6e4a..5c6533d5dc55 100644 --- a/engines/ags/engine/ac/spritecache_engine.cpp +++ b/engines/ags/engine/ac/spritecache_engine.cpp @@ -41,13 +41,12 @@ // Engine-specific implementation split out of sprcache.cpp //============================================================================= -void SpriteCache::InitNullSpriteParams(sprkey_t index) -{ - // make it a blue cup, to avoid crashes - _sprInfos[index].Width = _sprInfos[0].Width; - _sprInfos[index].Height = _sprInfos[0].Height; - _spriteData[index].Image = nullptr; - _spriteData[index].Offset = _spriteData[0].Offset; - _spriteData[index].Size = _spriteData[0].Size; - _spriteData[index].Flags = SPRCACHEFLAG_REMAPPED; +void SpriteCache::InitNullSpriteParams(sprkey_t index) { + // make it a blue cup, to avoid crashes + _sprInfos[index].Width = _sprInfos[0].Width; + _sprInfos[index].Height = _sprInfos[0].Height; + _spriteData[index].Image = nullptr; + _spriteData[index].Offset = _spriteData[0].Offset; + _spriteData[index].Size = _spriteData[0].Size; + _spriteData[index].Flags = SPRCACHEFLAG_REMAPPED; } diff --git a/engines/ags/engine/ac/spritelistentry.h b/engines/ags/engine/ac/spritelistentry.h index aa45aad77c6c..735eaf2d10dc 100644 --- a/engines/ags/engine/ac/spritelistentry.h +++ b/engines/ags/engine/ac/spritelistentry.h @@ -25,17 +25,16 @@ #include "gfx/ddb.h" -struct SpriteListEntry -{ - AGS::Engine::IDriverDependantBitmap *bmp; - AGS::Common::Bitmap *pic; - int baseline; - int x,y; - int transparent; - bool takesPriorityIfEqual; - bool hasAlphaChannel; +struct SpriteListEntry { + AGS::Engine::IDriverDependantBitmap *bmp; + AGS::Common::Bitmap *pic; + int baseline; + int x, y; + int transparent; + bool takesPriorityIfEqual; + bool hasAlphaChannel; - SpriteListEntry(); + SpriteListEntry(); }; #endif diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp index 376dd0e4cea4..53233da9f813 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.cpp +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -28,74 +28,59 @@ AGSStaticObject GlobalStaticManager; StaticGame GameStaticManager; -const char* AGSStaticObject::GetFieldPtr(const char *address, intptr_t offset) -{ - return address + offset; +const char *AGSStaticObject::GetFieldPtr(const char *address, intptr_t offset) { + return address + offset; } -void AGSStaticObject::Read(const char *address, intptr_t offset, void *dest, int size) -{ - memcpy(dest, address + offset, size); +void AGSStaticObject::Read(const char *address, intptr_t offset, void *dest, int size) { + memcpy(dest, address + offset, size); } -uint8_t AGSStaticObject::ReadInt8(const char *address, intptr_t offset) -{ - return *(uint8_t*)(address + offset); +uint8_t AGSStaticObject::ReadInt8(const char *address, intptr_t offset) { + return *(uint8_t *)(address + offset); } -int16_t AGSStaticObject::ReadInt16(const char *address, intptr_t offset) -{ - return *(int16_t*)(address + offset); +int16_t AGSStaticObject::ReadInt16(const char *address, intptr_t offset) { + return *(int16_t *)(address + offset); } -int32_t AGSStaticObject::ReadInt32(const char *address, intptr_t offset) -{ - return *(int32_t*)(address + offset); +int32_t AGSStaticObject::ReadInt32(const char *address, intptr_t offset) { + return *(int32_t *)(address + offset); } -float AGSStaticObject::ReadFloat(const char *address, intptr_t offset) -{ - return *(float*)(address + offset); +float AGSStaticObject::ReadFloat(const char *address, intptr_t offset) { + return *(float *)(address + offset); } -void AGSStaticObject::Write(const char *address, intptr_t offset, void *src, int size) -{ - memcpy((void*)(address + offset), src, size); +void AGSStaticObject::Write(const char *address, intptr_t offset, void *src, int size) { + memcpy((void *)(address + offset), src, size); } -void AGSStaticObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) -{ - *(uint8_t*)(address + offset) = val; +void AGSStaticObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) { + *(uint8_t *)(address + offset) = val; } -void AGSStaticObject::WriteInt16(const char *address, intptr_t offset, int16_t val) -{ - *(int16_t*)(address + offset) = val; +void AGSStaticObject::WriteInt16(const char *address, intptr_t offset, int16_t val) { + *(int16_t *)(address + offset) = val; } -void AGSStaticObject::WriteInt32(const char *address, intptr_t offset, int32_t val) -{ - *(int32_t*)(address + offset) = val; +void AGSStaticObject::WriteInt32(const char *address, intptr_t offset, int32_t val) { + *(int32_t *)(address + offset) = val; } -void AGSStaticObject::WriteFloat(const char *address, intptr_t offset, float val) -{ - *(float*)(address + offset) = val; +void AGSStaticObject::WriteFloat(const char *address, intptr_t offset, float val) { + *(float *)(address + offset) = val; } -void StaticGame::WriteInt32(const char *address, intptr_t offset, int32_t val) -{ - if (offset == 4 * sizeof(int32_t)) - { // game.debug_mode - set_debug_mode(val != 0); - } - else if (offset == 99 * sizeof(int32_t) || offset == 112 * sizeof(int32_t)) - { // game.text_align, game.speech_text_align - *(int32_t*)(address + offset) = ReadScriptAlignment(val); - } - else - { - *(int32_t*)(address + offset) = val; - } +void StaticGame::WriteInt32(const char *address, intptr_t offset, int32_t val) { + if (offset == 4 * sizeof(int32_t)) { + // game.debug_mode + set_debug_mode(val != 0); + } else if (offset == 99 * sizeof(int32_t) || offset == 112 * sizeof(int32_t)) { + // game.text_align, game.speech_text_align + *(int32_t *)(address + offset) = ReadScriptAlignment(val); + } else { + *(int32_t *)(address + offset) = val; + } } diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.h b/engines/ags/engine/ac/statobj/agsstaticobject.h index 49e00f0653f7..adcf2411bbf0 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.h +++ b/engines/ags/engine/ac/statobj/agsstaticobject.h @@ -26,25 +26,25 @@ #include "ac/statobj/staticobject.h" struct AGSStaticObject : public ICCStaticObject { - ~AGSStaticObject() override = default; + ~AGSStaticObject() override = default; - // Legacy support for reading and writing object values by their relative offset - const char* GetFieldPtr(const char *address, intptr_t offset) override; - void Read(const char *address, intptr_t offset, void *dest, int size) override; - uint8_t ReadInt8(const char *address, intptr_t offset) override; - int16_t ReadInt16(const char *address, intptr_t offset) override; - int32_t ReadInt32(const char *address, intptr_t offset) override; - float ReadFloat(const char *address, intptr_t offset) override; - void Write(const char *address, intptr_t offset, void *src, int size) override; - void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; - void WriteInt16(const char *address, intptr_t offset, int16_t val) override; - void WriteInt32(const char *address, intptr_t offset, int32_t val) override; - void WriteFloat(const char *address, intptr_t offset, float val) override; + // Legacy support for reading and writing object values by their relative offset + const char *GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; }; // Wrapper around script's "Game" struct, managing access to its variables struct StaticGame : public AGSStaticObject { - void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; }; extern AGSStaticObject GlobalStaticManager; diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp index 774e3bc47185..8b87c74932b2 100644 --- a/engines/ags/engine/ac/statobj/staticarray.cpp +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -24,194 +24,139 @@ #include "ac/statobj/staticarray.h" #include "ac/dynobj/cc_dynamicobject.h" -void StaticArray::Create(int elem_legacy_size, int elem_real_size, int elem_count) -{ - _staticMgr = nullptr; - _dynamicMgr = nullptr; - _elemLegacySize = elem_legacy_size; - _elemRealSize = elem_real_size; - _elemCount = elem_count; +void StaticArray::Create(int elem_legacy_size, int elem_real_size, int elem_count) { + _staticMgr = nullptr; + _dynamicMgr = nullptr; + _elemLegacySize = elem_legacy_size; + _elemRealSize = elem_real_size; + _elemCount = elem_count; } -void StaticArray::Create(ICCStaticObject *stcmgr, int elem_legacy_size, int elem_real_size, int elem_count) -{ - _staticMgr = stcmgr; - _dynamicMgr = nullptr; - _elemLegacySize = elem_legacy_size; - _elemRealSize = elem_real_size; - _elemCount = elem_count; +void StaticArray::Create(ICCStaticObject *stcmgr, int elem_legacy_size, int elem_real_size, int elem_count) { + _staticMgr = stcmgr; + _dynamicMgr = nullptr; + _elemLegacySize = elem_legacy_size; + _elemRealSize = elem_real_size; + _elemCount = elem_count; } -void StaticArray::Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int elem_real_size, int elem_count) -{ - _staticMgr = nullptr; - _dynamicMgr = dynmgr; - _elemLegacySize = elem_legacy_size; - _elemRealSize = elem_real_size; - _elemCount = elem_count; +void StaticArray::Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int elem_real_size, int elem_count) { + _staticMgr = nullptr; + _dynamicMgr = dynmgr; + _elemLegacySize = elem_legacy_size; + _elemRealSize = elem_real_size; + _elemCount = elem_count; } -const char *StaticArray::GetElementPtr(const char *address, intptr_t legacy_offset) -{ - return address + (legacy_offset / _elemLegacySize) * _elemRealSize; +const char *StaticArray::GetElementPtr(const char *address, intptr_t legacy_offset) { + return address + (legacy_offset / _elemLegacySize) * _elemRealSize; } -const char* StaticArray::GetFieldPtr(const char *address, intptr_t offset) -{ - return GetElementPtr(address, offset); +const char *StaticArray::GetFieldPtr(const char *address, intptr_t offset) { + return GetElementPtr(address, offset); } -void StaticArray::Read(const char *address, intptr_t offset, void *dest, int size) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->Read(el_ptr, offset % _elemLegacySize, dest, size); - } - else if (_dynamicMgr) - { - return _dynamicMgr->Read(el_ptr, offset % _elemLegacySize, dest, size); - } - memcpy(dest, el_ptr + offset % _elemLegacySize, size); +void StaticArray::Read(const char *address, intptr_t offset, void *dest, int size) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->Read(el_ptr, offset % _elemLegacySize, dest, size); + } else if (_dynamicMgr) { + return _dynamicMgr->Read(el_ptr, offset % _elemLegacySize, dest, size); + } + memcpy(dest, el_ptr + offset % _elemLegacySize, size); } -uint8_t StaticArray::ReadInt8(const char *address, intptr_t offset) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->ReadInt8(el_ptr, offset % _elemLegacySize); - } - else if (_dynamicMgr) - { - return _dynamicMgr->ReadInt8(el_ptr, offset % _elemLegacySize); - } - return *(uint8_t*)(el_ptr + offset % _elemLegacySize); +uint8_t StaticArray::ReadInt8(const char *address, intptr_t offset) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->ReadInt8(el_ptr, offset % _elemLegacySize); + } else if (_dynamicMgr) { + return _dynamicMgr->ReadInt8(el_ptr, offset % _elemLegacySize); + } + return *(uint8_t *)(el_ptr + offset % _elemLegacySize); } -int16_t StaticArray::ReadInt16(const char *address, intptr_t offset) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->ReadInt16(el_ptr, offset % _elemLegacySize); - } - else if (_dynamicMgr) - { - return _dynamicMgr->ReadInt16(el_ptr, offset % _elemLegacySize); - } - return *(uint16_t*)(el_ptr + offset % _elemLegacySize); +int16_t StaticArray::ReadInt16(const char *address, intptr_t offset) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->ReadInt16(el_ptr, offset % _elemLegacySize); + } else if (_dynamicMgr) { + return _dynamicMgr->ReadInt16(el_ptr, offset % _elemLegacySize); + } + return *(uint16_t *)(el_ptr + offset % _elemLegacySize); } -int32_t StaticArray::ReadInt32(const char *address, intptr_t offset) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->ReadInt32(el_ptr, offset % _elemLegacySize); - } - else if (_dynamicMgr) - { - return _dynamicMgr->ReadInt32(el_ptr, offset % _elemLegacySize); - } - return *(uint32_t*)(el_ptr + offset % _elemLegacySize); +int32_t StaticArray::ReadInt32(const char *address, intptr_t offset) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->ReadInt32(el_ptr, offset % _elemLegacySize); + } else if (_dynamicMgr) { + return _dynamicMgr->ReadInt32(el_ptr, offset % _elemLegacySize); + } + return *(uint32_t *)(el_ptr + offset % _elemLegacySize); } -float StaticArray::ReadFloat(const char *address, intptr_t offset) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->ReadFloat(el_ptr, offset % _elemLegacySize); - } - else if (_dynamicMgr) - { - return _dynamicMgr->ReadFloat(el_ptr, offset % _elemLegacySize); - } - return *(float*)(el_ptr + offset % _elemLegacySize); +float StaticArray::ReadFloat(const char *address, intptr_t offset) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->ReadFloat(el_ptr, offset % _elemLegacySize); + } else if (_dynamicMgr) { + return _dynamicMgr->ReadFloat(el_ptr, offset % _elemLegacySize); + } + return *(float *)(el_ptr + offset % _elemLegacySize); } -void StaticArray::Write(const char *address, intptr_t offset, void *src, int size) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->Write(el_ptr, offset % _elemLegacySize, src, size); - } - else if (_dynamicMgr) - { - return _dynamicMgr->Write(el_ptr, offset % _elemLegacySize, src, size); - } - else - { - memcpy((void*)(el_ptr + offset % _elemLegacySize), src, size); - } +void StaticArray::Write(const char *address, intptr_t offset, void *src, int size) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->Write(el_ptr, offset % _elemLegacySize, src, size); + } else if (_dynamicMgr) { + return _dynamicMgr->Write(el_ptr, offset % _elemLegacySize, src, size); + } else { + memcpy((void *)(el_ptr + offset % _elemLegacySize), src, size); + } } -void StaticArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->WriteInt8(el_ptr, offset % _elemLegacySize, val); - } - else if (_dynamicMgr) - { - return _dynamicMgr->WriteInt8(el_ptr, offset % _elemLegacySize, val); - } - else - { - *(uint8_t*)(el_ptr + offset % _elemLegacySize) = val; - } +void StaticArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->WriteInt8(el_ptr, offset % _elemLegacySize, val); + } else if (_dynamicMgr) { + return _dynamicMgr->WriteInt8(el_ptr, offset % _elemLegacySize, val); + } else { + *(uint8_t *)(el_ptr + offset % _elemLegacySize) = val; + } } -void StaticArray::WriteInt16(const char *address, intptr_t offset, int16_t val) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->WriteInt16(el_ptr, offset % _elemLegacySize, val); - } - else if (_dynamicMgr) - { - return _dynamicMgr->WriteInt16(el_ptr, offset % _elemLegacySize, val); - } - else - { - *(uint16_t*)(el_ptr + offset % _elemLegacySize) = val; - } +void StaticArray::WriteInt16(const char *address, intptr_t offset, int16_t val) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->WriteInt16(el_ptr, offset % _elemLegacySize, val); + } else if (_dynamicMgr) { + return _dynamicMgr->WriteInt16(el_ptr, offset % _elemLegacySize, val); + } else { + *(uint16_t *)(el_ptr + offset % _elemLegacySize) = val; + } } -void StaticArray::WriteInt32(const char *address, intptr_t offset, int32_t val) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->WriteInt32(el_ptr, offset % _elemLegacySize, val); - } - else if (_dynamicMgr) - { - return _dynamicMgr->WriteInt32(el_ptr, offset % _elemLegacySize, val); - } - else - { - *(uint32_t*)(el_ptr + offset % _elemLegacySize) = val; - } +void StaticArray::WriteInt32(const char *address, intptr_t offset, int32_t val) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->WriteInt32(el_ptr, offset % _elemLegacySize, val); + } else if (_dynamicMgr) { + return _dynamicMgr->WriteInt32(el_ptr, offset % _elemLegacySize, val); + } else { + *(uint32_t *)(el_ptr + offset % _elemLegacySize) = val; + } } -void StaticArray::WriteFloat(const char *address, intptr_t offset, float val) -{ - const char *el_ptr = GetElementPtr(address, offset); - if (_staticMgr) - { - return _staticMgr->WriteFloat(el_ptr, offset % _elemLegacySize, val); - } - else if (_dynamicMgr) - { - return _dynamicMgr->WriteFloat(el_ptr, offset % _elemLegacySize, val); - } - else - { - *(float*)(el_ptr + offset % _elemLegacySize) = val; - } +void StaticArray::WriteFloat(const char *address, intptr_t offset, float val) { + const char *el_ptr = GetElementPtr(address, offset); + if (_staticMgr) { + return _staticMgr->WriteFloat(el_ptr, offset % _elemLegacySize, val); + } else if (_dynamicMgr) { + return _dynamicMgr->WriteFloat(el_ptr, offset % _elemLegacySize, val); + } else { + *(float *)(el_ptr + offset % _elemLegacySize) = val; + } } diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h index 950894a72120..729e7f9bcefa 100644 --- a/engines/ags/engine/ac/statobj/staticarray.h +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -29,41 +29,39 @@ struct ICCDynamicObject; struct StaticArray : public ICCStaticObject { public: - ~StaticArray() override = default; + ~StaticArray() override = default; - void Create(int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); - void Create(ICCStaticObject *stcmgr, int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); - void Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); + void Create(int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); + void Create(ICCStaticObject *stcmgr, int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); + void Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int elem_real_size, int elem_count = -1 /*unknown*/); - inline ICCStaticObject *GetStaticManager() const - { - return _staticMgr; - } - inline ICCDynamicObject *GetDynamicManager() const - { - return _dynamicMgr; - } - // Legacy support for reading and writing object values by their relative offset - virtual const char *GetElementPtr(const char *address, intptr_t legacy_offset); + inline ICCStaticObject *GetStaticManager() const { + return _staticMgr; + } + inline ICCDynamicObject *GetDynamicManager() const { + return _dynamicMgr; + } + // Legacy support for reading and writing object values by their relative offset + virtual const char *GetElementPtr(const char *address, intptr_t legacy_offset); - const char* GetFieldPtr(const char *address, intptr_t offset) override; - void Read(const char *address, intptr_t offset, void *dest, int size) override; - uint8_t ReadInt8(const char *address, intptr_t offset) override; - int16_t ReadInt16(const char *address, intptr_t offset) override; - int32_t ReadInt32(const char *address, intptr_t offset) override; - float ReadFloat(const char *address, intptr_t offset) override; - void Write(const char *address, intptr_t offset, void *src, int size) override; - void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; - void WriteInt16(const char *address, intptr_t offset, int16_t val) override; - void WriteInt32(const char *address, intptr_t offset, int32_t val) override; - void WriteFloat(const char *address, intptr_t offset, float val) override; + const char *GetFieldPtr(const char *address, intptr_t offset) override; + void Read(const char *address, intptr_t offset, void *dest, int size) override; + uint8_t ReadInt8(const char *address, intptr_t offset) override; + int16_t ReadInt16(const char *address, intptr_t offset) override; + int32_t ReadInt32(const char *address, intptr_t offset) override; + float ReadFloat(const char *address, intptr_t offset) override; + void Write(const char *address, intptr_t offset, void *src, int size) override; + void WriteInt8(const char *address, intptr_t offset, uint8_t val) override; + void WriteInt16(const char *address, intptr_t offset, int16_t val) override; + void WriteInt32(const char *address, intptr_t offset, int32_t val) override; + void WriteFloat(const char *address, intptr_t offset, float val) override; private: - ICCStaticObject *_staticMgr; - ICCDynamicObject *_dynamicMgr; - int _elemLegacySize; - int _elemRealSize; - int _elemCount; + ICCStaticObject *_staticMgr; + ICCDynamicObject *_dynamicMgr; + int _elemLegacySize; + int _elemRealSize; + int _elemCount; }; #endif diff --git a/engines/ags/engine/ac/statobj/staticobject.h b/engines/ags/engine/ac/statobj/staticobject.h index 3580f0c678cf..4e424a02b0ee 100644 --- a/engines/ags/engine/ac/statobj/staticobject.h +++ b/engines/ags/engine/ac/statobj/staticobject.h @@ -34,20 +34,20 @@ #include "core/types.h" struct ICCStaticObject { - virtual ~ICCStaticObject() = default; + virtual ~ICCStaticObject() = default; - // Legacy support for reading and writing object values by their relative offset - virtual const char* GetFieldPtr(const char *address, intptr_t offset) = 0; - virtual void Read(const char *address, intptr_t offset, void *dest, int size)= 0; - virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; - virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; - virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; - virtual float ReadFloat(const char *address, intptr_t offset) = 0; - virtual void Write(const char *address, intptr_t offset, void *src, int size)= 0; - virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; - virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; - virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; - virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; + // Legacy support for reading and writing object values by their relative offset + virtual const char *GetFieldPtr(const char *address, intptr_t offset) = 0; + virtual void Read(const char *address, intptr_t offset, void *dest, int size) = 0; + virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; + virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; + virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; + virtual float ReadFloat(const char *address, intptr_t offset) = 0; + virtual void Write(const char *address, intptr_t offset, void *src, int size) = 0; + virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; + virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; + virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; + virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; }; #endif diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index 117e619ce379..11b27c34e42a 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -39,257 +39,238 @@ extern GameState play; extern int longestline; extern ScriptString myScriptStringImpl; -int String_IsNullOrEmpty(const char *thisString) -{ - if ((thisString == nullptr) || (thisString[0] == 0)) - return 1; +int String_IsNullOrEmpty(const char *thisString) { + if ((thisString == nullptr) || (thisString[0] == 0)) + return 1; - return 0; + return 0; } -const char* String_Copy(const char *srcString) { - return CreateNewScriptString(srcString); +const char *String_Copy(const char *srcString) { + return CreateNewScriptString(srcString); } -const char* String_Append(const char *thisString, const char *extrabit) { - char *buffer = (char*)malloc(strlen(thisString) + strlen(extrabit) + 1); - strcpy(buffer, thisString); - strcat(buffer, extrabit); - return CreateNewScriptString(buffer, false); +const char *String_Append(const char *thisString, const char *extrabit) { + char *buffer = (char *)malloc(strlen(thisString) + strlen(extrabit) + 1); + strcpy(buffer, thisString); + strcat(buffer, extrabit); + return CreateNewScriptString(buffer, false); } -const char* String_AppendChar(const char *thisString, char extraOne) { - char *buffer = (char*)malloc(strlen(thisString) + 2); - sprintf(buffer, "%s%c", thisString, extraOne); - return CreateNewScriptString(buffer, false); +const char *String_AppendChar(const char *thisString, char extraOne) { + char *buffer = (char *)malloc(strlen(thisString) + 2); + sprintf(buffer, "%s%c", thisString, extraOne); + return CreateNewScriptString(buffer, false); } -const char* String_ReplaceCharAt(const char *thisString, int index, char newChar) { - if ((index < 0) || (index >= (int)strlen(thisString))) - quit("!String.ReplaceCharAt: index outside range of string"); +const char *String_ReplaceCharAt(const char *thisString, int index, char newChar) { + if ((index < 0) || (index >= (int)strlen(thisString))) + quit("!String.ReplaceCharAt: index outside range of string"); - char *buffer = (char*)malloc(strlen(thisString) + 1); - strcpy(buffer, thisString); - buffer[index] = newChar; - return CreateNewScriptString(buffer, false); + char *buffer = (char *)malloc(strlen(thisString) + 1); + strcpy(buffer, thisString); + buffer[index] = newChar; + return CreateNewScriptString(buffer, false); } -const char* String_Truncate(const char *thisString, int length) { - if (length < 0) - quit("!String.Truncate: invalid length"); +const char *String_Truncate(const char *thisString, int length) { + if (length < 0) + quit("!String.Truncate: invalid length"); - if (length >= (int)strlen(thisString)) - { - return thisString; - } + if (length >= (int)strlen(thisString)) { + return thisString; + } - char *buffer = (char*)malloc(length + 1); - strncpy(buffer, thisString, length); - buffer[length] = 0; - return CreateNewScriptString(buffer, false); + char *buffer = (char *)malloc(length + 1); + strncpy(buffer, thisString, length); + buffer[length] = 0; + return CreateNewScriptString(buffer, false); } -const char* String_Substring(const char *thisString, int index, int length) { - if (length < 0) - quit("!String.Substring: invalid length"); - if ((index < 0) || (index > (int)strlen(thisString))) - quit("!String.Substring: invalid index"); +const char *String_Substring(const char *thisString, int index, int length) { + if (length < 0) + quit("!String.Substring: invalid length"); + if ((index < 0) || (index > (int)strlen(thisString))) + quit("!String.Substring: invalid index"); - char *buffer = (char*)malloc(length + 1); - strncpy(buffer, &thisString[index], length); - buffer[length] = 0; - return CreateNewScriptString(buffer, false); + char *buffer = (char *)malloc(length + 1); + strncpy(buffer, &thisString[index], length); + buffer[length] = 0; + return CreateNewScriptString(buffer, false); } int String_CompareTo(const char *thisString, const char *otherString, bool caseSensitive) { - if (caseSensitive) { - return strcmp(thisString, otherString); - } - else { - return ags_stricmp(thisString, otherString); - } + if (caseSensitive) { + return strcmp(thisString, otherString); + } else { + return ags_stricmp(thisString, otherString); + } } int String_StartsWith(const char *thisString, const char *checkForString, bool caseSensitive) { - if (caseSensitive) { - return (strncmp(thisString, checkForString, strlen(checkForString)) == 0) ? 1 : 0; - } - else { - return (ags_strnicmp(thisString, checkForString, strlen(checkForString)) == 0) ? 1 : 0; - } + if (caseSensitive) { + return (strncmp(thisString, checkForString, strlen(checkForString)) == 0) ? 1 : 0; + } else { + return (ags_strnicmp(thisString, checkForString, strlen(checkForString)) == 0) ? 1 : 0; + } } int String_EndsWith(const char *thisString, const char *checkForString, bool caseSensitive) { - int checkAtOffset = strlen(thisString) - strlen(checkForString); - - if (checkAtOffset < 0) - { - return 0; - } - - if (caseSensitive) - { - return (strcmp(&thisString[checkAtOffset], checkForString) == 0) ? 1 : 0; - } - else - { - return (ags_stricmp(&thisString[checkAtOffset], checkForString) == 0) ? 1 : 0; - } -} - -const char* String_Replace(const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive) -{ - char resultBuffer[STD_BUFFER_SIZE] = ""; - int thisStringLen = (int)strlen(thisString); - int outputSize = 0; - for (int i = 0; i < thisStringLen; i++) - { - bool matchHere = false; - if (caseSensitive) - { - matchHere = (strncmp(&thisString[i], lookForText, strlen(lookForText)) == 0); - } - else - { - matchHere = (ags_strnicmp(&thisString[i], lookForText, strlen(lookForText)) == 0); - } - - if (matchHere) - { - strcpy(&resultBuffer[outputSize], replaceWithText); - outputSize += strlen(replaceWithText); - i += strlen(lookForText) - 1; - } - else - { - resultBuffer[outputSize] = thisString[i]; - outputSize++; - } - } - - resultBuffer[outputSize] = 0; - - return CreateNewScriptString(resultBuffer, true); -} - -const char* String_LowerCase(const char *thisString) { - char *buffer = (char*)malloc(strlen(thisString) + 1); - strcpy(buffer, thisString); - ags_strlwr(buffer); - return CreateNewScriptString(buffer, false); -} - -const char* String_UpperCase(const char *thisString) { - char *buffer = (char*)malloc(strlen(thisString) + 1); - strcpy(buffer, thisString); - ags_strupr(buffer); - return CreateNewScriptString(buffer, false); + int checkAtOffset = strlen(thisString) - strlen(checkForString); + + if (checkAtOffset < 0) { + return 0; + } + + if (caseSensitive) { + return (strcmp(&thisString[checkAtOffset], checkForString) == 0) ? 1 : 0; + } else { + return (ags_stricmp(&thisString[checkAtOffset], checkForString) == 0) ? 1 : 0; + } +} + +const char *String_Replace(const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive) { + char resultBuffer[STD_BUFFER_SIZE] = ""; + int thisStringLen = (int)strlen(thisString); + int outputSize = 0; + for (int i = 0; i < thisStringLen; i++) { + bool matchHere = false; + if (caseSensitive) { + matchHere = (strncmp(&thisString[i], lookForText, strlen(lookForText)) == 0); + } else { + matchHere = (ags_strnicmp(&thisString[i], lookForText, strlen(lookForText)) == 0); + } + + if (matchHere) { + strcpy(&resultBuffer[outputSize], replaceWithText); + outputSize += strlen(replaceWithText); + i += strlen(lookForText) - 1; + } else { + resultBuffer[outputSize] = thisString[i]; + outputSize++; + } + } + + resultBuffer[outputSize] = 0; + + return CreateNewScriptString(resultBuffer, true); +} + +const char *String_LowerCase(const char *thisString) { + char *buffer = (char *)malloc(strlen(thisString) + 1); + strcpy(buffer, thisString); + ags_strlwr(buffer); + return CreateNewScriptString(buffer, false); +} + +const char *String_UpperCase(const char *thisString) { + char *buffer = (char *)malloc(strlen(thisString) + 1); + strcpy(buffer, thisString); + ags_strupr(buffer); + return CreateNewScriptString(buffer, false); } int String_GetChars(const char *texx, int index) { - if ((index < 0) || (index >= (int)strlen(texx))) - return 0; - return texx[index]; + if ((index < 0) || (index >= (int)strlen(texx))) + return 0; + return texx[index]; } -int StringToInt(const char*stino) { - return atoi(stino); +int StringToInt(const char *stino) { + return atoi(stino); } -int StrContains (const char *s1, const char *s2) { - VALIDATE_STRING (s1); - VALIDATE_STRING (s2); - char *tempbuf1 = (char*)malloc(strlen(s1) + 1); - char *tempbuf2 = (char*)malloc(strlen(s2) + 1); - strcpy(tempbuf1, s1); - strcpy(tempbuf2, s2); - ags_strlwr(tempbuf1); - ags_strlwr(tempbuf2); +int StrContains(const char *s1, const char *s2) { + VALIDATE_STRING(s1); + VALIDATE_STRING(s2); + char *tempbuf1 = (char *)malloc(strlen(s1) + 1); + char *tempbuf2 = (char *)malloc(strlen(s2) + 1); + strcpy(tempbuf1, s1); + strcpy(tempbuf2, s2); + ags_strlwr(tempbuf1); + ags_strlwr(tempbuf2); - char *offs = strstr (tempbuf1, tempbuf2); - free(tempbuf1); - free(tempbuf2); + char *offs = strstr(tempbuf1, tempbuf2); + free(tempbuf1); + free(tempbuf2); - if (offs == nullptr) - return -1; + if (offs == nullptr) + return -1; - return (offs - tempbuf1); + return (offs - tempbuf1); } //============================================================================= const char *CreateNewScriptString(const char *fromText, bool reAllocate) { - return (const char*)CreateNewScriptStringObj(fromText, reAllocate).second; -} - -DynObjectRef CreateNewScriptStringObj(const char *fromText, bool reAllocate) -{ - ScriptString *str; - if (reAllocate) { - str = new ScriptString(fromText); - } - else { - str = new ScriptString(); - str->text = (char*)fromText; - } - void *obj_ptr = str->text; - int32_t handle = ccRegisterManagedObject(obj_ptr, str); - if (handle == 0) - { - delete str; - return DynObjectRef(0, nullptr); - } - return DynObjectRef(handle, obj_ptr); + return (const char *)CreateNewScriptStringObj(fromText, reAllocate).second; +} + +DynObjectRef CreateNewScriptStringObj(const char *fromText, bool reAllocate) { + ScriptString *str; + if (reAllocate) { + str = new ScriptString(fromText); + } else { + str = new ScriptString(); + str->text = (char *)fromText; + } + void *obj_ptr = str->text; + int32_t handle = ccRegisterManagedObject(obj_ptr, str); + if (handle == 0) { + delete str; + return DynObjectRef(0, nullptr); + } + return DynObjectRef(handle, obj_ptr); } size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, int fonnt, size_t max_lines) { - if (fonnt == -1) - fonnt = play.normal_font; - - // char sofar[100]; - if (todis[0]=='&') { - while ((todis[0]!=' ') & (todis[0]!=0)) todis++; - if (todis[0]==' ') todis++; - } - lines.Reset(); - longestline=0; - - // Don't attempt to display anything if the width is tiny - if (wii < 3) - return 0; - - int line_length; - - split_lines(todis, lines, wii, fonnt, max_lines); - - // Right-to-left just means reverse the text then - // write it as normal - if (game.options[OPT_RIGHTLEFTWRITE]) - for (size_t rr = 0; rr < lines.Count(); rr++) { - lines[rr].Reverse(); - line_length = wgettextwidth_compensate(lines[rr], fonnt); - if (line_length > longestline) - longestline = line_length; - } - else - for (size_t rr = 0; rr < lines.Count(); rr++) { - line_length = wgettextwidth_compensate(lines[rr], fonnt); - if (line_length > longestline) - longestline = line_length; - } - return lines.Count(); + if (fonnt == -1) + fonnt = play.normal_font; + + // char sofar[100]; + if (todis[0] == '&') { + while ((todis[0] != ' ') & (todis[0] != 0)) todis++; + if (todis[0] == ' ') todis++; + } + lines.Reset(); + longestline = 0; + + // Don't attempt to display anything if the width is tiny + if (wii < 3) + return 0; + + int line_length; + + split_lines(todis, lines, wii, fonnt, max_lines); + + // Right-to-left just means reverse the text then + // write it as normal + if (game.options[OPT_RIGHTLEFTWRITE]) + for (size_t rr = 0; rr < lines.Count(); rr++) { + lines[rr].Reverse(); + line_length = wgettextwidth_compensate(lines[rr], fonnt); + if (line_length > longestline) + longestline = line_length; + } + else + for (size_t rr = 0; rr < lines.Count(); rr++) { + line_length = wgettextwidth_compensate(lines[rr], fonnt); + if (line_length > longestline) + longestline = line_length; + } + return lines.Count(); } int MAXSTRLEN = MAX_MAXSTRLEN; -void check_strlen(char*ptt) { - MAXSTRLEN = MAX_MAXSTRLEN; - long charstart = (long)&game.chars[0]; - long charend = charstart + sizeof(CharacterInfo)*game.numcharacters; - if (((long)&ptt[0] >= charstart) && ((long)&ptt[0] <= charend)) - MAXSTRLEN=30; +void check_strlen(char *ptt) { + MAXSTRLEN = MAX_MAXSTRLEN; + long charstart = (long)&game.chars[0]; + long charend = charstart + sizeof(CharacterInfo) * game.numcharacters; + if (((long)&ptt[0] >= charstart) && ((long)&ptt[0] <= charend)) + MAXSTRLEN = 30; } /*void GetLanguageString(int indxx,char*buffr) { @@ -301,14 +282,13 @@ buffr[199]=0; }*/ void my_strncpy(char *dest, const char *src, int len) { - // the normal strncpy pads out the string with zeros up to the - // max length -- we don't want that - if (strlen(src) >= (unsigned)len) { - strncpy(dest, src, len); - dest[len] = 0; - } - else - strcpy(dest, src); + // the normal strncpy pads out the string with zeros up to the + // max length -- we don't want that + if (strlen(src) >= (unsigned)len) { + strncpy(dest, src, len); + dest[len] = 0; + } else + strcpy(dest, src); } //============================================================================= @@ -323,118 +303,99 @@ void my_strncpy(char *dest, const char *src, int len) { #include "ac/math.h" // int (const char *thisString) -RuntimeScriptValue Sc_String_IsNullOrEmpty(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT_POBJ(String_IsNullOrEmpty, const char); +RuntimeScriptValue Sc_String_IsNullOrEmpty(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT_POBJ(String_IsNullOrEmpty, const char); } // const char* (const char *thisString, const char *extrabit) -RuntimeScriptValue Sc_String_Append(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_POBJ(const char, const char, myScriptStringImpl, String_Append, const char); +RuntimeScriptValue Sc_String_Append(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_POBJ(const char, const char, myScriptStringImpl, String_Append, const char); } // const char* (const char *thisString, char extraOne) -RuntimeScriptValue Sc_String_AppendChar(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_AppendChar); +RuntimeScriptValue Sc_String_AppendChar(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_AppendChar); } // int (const char *thisString, const char *otherString, bool caseSensitive) -RuntimeScriptValue Sc_String_CompareTo(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ_PBOOL(const char, String_CompareTo, const char); +RuntimeScriptValue Sc_String_CompareTo(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ_PBOOL(const char, String_CompareTo, const char); } // int (const char *s1, const char *s2) -RuntimeScriptValue Sc_StrContains(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ(const char, StrContains, const char); +RuntimeScriptValue Sc_StrContains(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ(const char, StrContains, const char); } // const char* (const char *srcString) -RuntimeScriptValue Sc_String_Copy(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_Copy); +RuntimeScriptValue Sc_String_Copy(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_Copy); } // int (const char *thisString, const char *checkForString, bool caseSensitive) -RuntimeScriptValue Sc_String_EndsWith(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ_PBOOL(const char, String_EndsWith, const char); +RuntimeScriptValue Sc_String_EndsWith(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ_PBOOL(const char, String_EndsWith, const char); } // const char* (const char *texx, ...) -RuntimeScriptValue Sc_String_Format(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(String_Format, 1); - return RuntimeScriptValue().SetDynamicObject((void*)CreateNewScriptString(scsf_buffer), &myScriptStringImpl); +RuntimeScriptValue Sc_String_Format(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(String_Format, 1); + return RuntimeScriptValue().SetDynamicObject((void *)CreateNewScriptString(scsf_buffer), &myScriptStringImpl); } // const char* (const char *thisString) -RuntimeScriptValue Sc_String_LowerCase(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_LowerCase); +RuntimeScriptValue Sc_String_LowerCase(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_LowerCase); } // const char* (const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive) -RuntimeScriptValue Sc_String_Replace(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_POBJ2_PBOOL(const char, const char, myScriptStringImpl, String_Replace, const char, const char); +RuntimeScriptValue Sc_String_Replace(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_POBJ2_PBOOL(const char, const char, myScriptStringImpl, String_Replace, const char, const char); } // const char* (const char *thisString, int index, char newChar) -RuntimeScriptValue Sc_String_ReplaceCharAt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_ReplaceCharAt); +RuntimeScriptValue Sc_String_ReplaceCharAt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_ReplaceCharAt); } // int (const char *thisString, const char *checkForString, bool caseSensitive) -RuntimeScriptValue Sc_String_StartsWith(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_POBJ_PBOOL(const char, String_StartsWith, const char); +RuntimeScriptValue Sc_String_StartsWith(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_POBJ_PBOOL(const char, String_StartsWith, const char); } // const char* (const char *thisString, int index, int length) -RuntimeScriptValue Sc_String_Substring(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_Substring); +RuntimeScriptValue Sc_String_Substring(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_Substring); } // const char* (const char *thisString, int length) -RuntimeScriptValue Sc_String_Truncate(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_Truncate); +RuntimeScriptValue Sc_String_Truncate(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_Truncate); } // const char* (const char *thisString) -RuntimeScriptValue Sc_String_UpperCase(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_UpperCase); +RuntimeScriptValue Sc_String_UpperCase(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_UpperCase); } // FLOAT_RETURN_TYPE (const char *theString); -RuntimeScriptValue Sc_StringToFloat(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_FLOAT(const char, StringToFloat); +RuntimeScriptValue Sc_StringToFloat(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_FLOAT(const char, StringToFloat); } // int (char*stino) -RuntimeScriptValue Sc_StringToInt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(const char, StringToInt); +RuntimeScriptValue Sc_StringToInt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(const char, StringToInt); } // int (const char *texx, int index) -RuntimeScriptValue Sc_String_GetChars(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT_PINT(const char, String_GetChars); +RuntimeScriptValue Sc_String_GetChars(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT_PINT(const char, String_GetChars); } -RuntimeScriptValue Sc_strlen(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - ASSERT_SELF(strlen); - return RuntimeScriptValue().SetInt32(strlen((const char*)self)); +RuntimeScriptValue Sc_strlen(void *self, const RuntimeScriptValue *params, int32_t param_count) { + ASSERT_SELF(strlen); + return RuntimeScriptValue().SetInt32(strlen((const char *)self)); } //============================================================================= @@ -444,56 +405,54 @@ RuntimeScriptValue Sc_strlen(void *self, const RuntimeScriptValue *params, int32 //============================================================================= // const char* (const char *texx, ...) -const char *ScPl_String_Format(const char *texx, ...) -{ - API_PLUGIN_SCRIPT_SPRINTF(texx); - return CreateNewScriptString(scsf_buffer); -} - - -void RegisterStringAPI() -{ - ccAddExternalStaticFunction("String::IsNullOrEmpty^1", Sc_String_IsNullOrEmpty); - ccAddExternalObjectFunction("String::Append^1", Sc_String_Append); - ccAddExternalObjectFunction("String::AppendChar^1", Sc_String_AppendChar); - ccAddExternalObjectFunction("String::CompareTo^2", Sc_String_CompareTo); - ccAddExternalObjectFunction("String::Contains^1", Sc_StrContains); - ccAddExternalObjectFunction("String::Copy^0", Sc_String_Copy); - ccAddExternalObjectFunction("String::EndsWith^2", Sc_String_EndsWith); - ccAddExternalStaticFunction("String::Format^101", Sc_String_Format); - ccAddExternalObjectFunction("String::IndexOf^1", Sc_StrContains); - ccAddExternalObjectFunction("String::LowerCase^0", Sc_String_LowerCase); - ccAddExternalObjectFunction("String::Replace^3", Sc_String_Replace); - ccAddExternalObjectFunction("String::ReplaceCharAt^2", Sc_String_ReplaceCharAt); - ccAddExternalObjectFunction("String::StartsWith^2", Sc_String_StartsWith); - ccAddExternalObjectFunction("String::Substring^2", Sc_String_Substring); - ccAddExternalObjectFunction("String::Truncate^1", Sc_String_Truncate); - ccAddExternalObjectFunction("String::UpperCase^0", Sc_String_UpperCase); - ccAddExternalObjectFunction("String::get_AsFloat", Sc_StringToFloat); - ccAddExternalObjectFunction("String::get_AsInt", Sc_StringToInt); - ccAddExternalObjectFunction("String::geti_Chars", Sc_String_GetChars); - ccAddExternalObjectFunction("String::get_Length", Sc_strlen); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("String::IsNullOrEmpty^1", (void*)String_IsNullOrEmpty); - ccAddExternalFunctionForPlugin("String::Append^1", (void*)String_Append); - ccAddExternalFunctionForPlugin("String::AppendChar^1", (void*)String_AppendChar); - ccAddExternalFunctionForPlugin("String::CompareTo^2", (void*)String_CompareTo); - ccAddExternalFunctionForPlugin("String::Contains^1", (void*)StrContains); - ccAddExternalFunctionForPlugin("String::Copy^0", (void*)String_Copy); - ccAddExternalFunctionForPlugin("String::EndsWith^2", (void*)String_EndsWith); - ccAddExternalFunctionForPlugin("String::Format^101", (void*)ScPl_String_Format); - ccAddExternalFunctionForPlugin("String::IndexOf^1", (void*)StrContains); - ccAddExternalFunctionForPlugin("String::LowerCase^0", (void*)String_LowerCase); - ccAddExternalFunctionForPlugin("String::Replace^3", (void*)String_Replace); - ccAddExternalFunctionForPlugin("String::ReplaceCharAt^2", (void*)String_ReplaceCharAt); - ccAddExternalFunctionForPlugin("String::StartsWith^2", (void*)String_StartsWith); - ccAddExternalFunctionForPlugin("String::Substring^2", (void*)String_Substring); - ccAddExternalFunctionForPlugin("String::Truncate^1", (void*)String_Truncate); - ccAddExternalFunctionForPlugin("String::UpperCase^0", (void*)String_UpperCase); - ccAddExternalFunctionForPlugin("String::get_AsFloat", (void*)StringToFloat); - ccAddExternalFunctionForPlugin("String::get_AsInt", (void*)StringToInt); - ccAddExternalFunctionForPlugin("String::geti_Chars", (void*)String_GetChars); - ccAddExternalFunctionForPlugin("String::get_Length", (void*)strlen); +const char *ScPl_String_Format(const char *texx, ...) { + API_PLUGIN_SCRIPT_SPRINTF(texx); + return CreateNewScriptString(scsf_buffer); +} + + +void RegisterStringAPI() { + ccAddExternalStaticFunction("String::IsNullOrEmpty^1", Sc_String_IsNullOrEmpty); + ccAddExternalObjectFunction("String::Append^1", Sc_String_Append); + ccAddExternalObjectFunction("String::AppendChar^1", Sc_String_AppendChar); + ccAddExternalObjectFunction("String::CompareTo^2", Sc_String_CompareTo); + ccAddExternalObjectFunction("String::Contains^1", Sc_StrContains); + ccAddExternalObjectFunction("String::Copy^0", Sc_String_Copy); + ccAddExternalObjectFunction("String::EndsWith^2", Sc_String_EndsWith); + ccAddExternalStaticFunction("String::Format^101", Sc_String_Format); + ccAddExternalObjectFunction("String::IndexOf^1", Sc_StrContains); + ccAddExternalObjectFunction("String::LowerCase^0", Sc_String_LowerCase); + ccAddExternalObjectFunction("String::Replace^3", Sc_String_Replace); + ccAddExternalObjectFunction("String::ReplaceCharAt^2", Sc_String_ReplaceCharAt); + ccAddExternalObjectFunction("String::StartsWith^2", Sc_String_StartsWith); + ccAddExternalObjectFunction("String::Substring^2", Sc_String_Substring); + ccAddExternalObjectFunction("String::Truncate^1", Sc_String_Truncate); + ccAddExternalObjectFunction("String::UpperCase^0", Sc_String_UpperCase); + ccAddExternalObjectFunction("String::get_AsFloat", Sc_StringToFloat); + ccAddExternalObjectFunction("String::get_AsInt", Sc_StringToInt); + ccAddExternalObjectFunction("String::geti_Chars", Sc_String_GetChars); + ccAddExternalObjectFunction("String::get_Length", Sc_strlen); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("String::IsNullOrEmpty^1", (void *)String_IsNullOrEmpty); + ccAddExternalFunctionForPlugin("String::Append^1", (void *)String_Append); + ccAddExternalFunctionForPlugin("String::AppendChar^1", (void *)String_AppendChar); + ccAddExternalFunctionForPlugin("String::CompareTo^2", (void *)String_CompareTo); + ccAddExternalFunctionForPlugin("String::Contains^1", (void *)StrContains); + ccAddExternalFunctionForPlugin("String::Copy^0", (void *)String_Copy); + ccAddExternalFunctionForPlugin("String::EndsWith^2", (void *)String_EndsWith); + ccAddExternalFunctionForPlugin("String::Format^101", (void *)ScPl_String_Format); + ccAddExternalFunctionForPlugin("String::IndexOf^1", (void *)StrContains); + ccAddExternalFunctionForPlugin("String::LowerCase^0", (void *)String_LowerCase); + ccAddExternalFunctionForPlugin("String::Replace^3", (void *)String_Replace); + ccAddExternalFunctionForPlugin("String::ReplaceCharAt^2", (void *)String_ReplaceCharAt); + ccAddExternalFunctionForPlugin("String::StartsWith^2", (void *)String_StartsWith); + ccAddExternalFunctionForPlugin("String::Substring^2", (void *)String_Substring); + ccAddExternalFunctionForPlugin("String::Truncate^1", (void *)String_Truncate); + ccAddExternalFunctionForPlugin("String::UpperCase^0", (void *)String_UpperCase); + ccAddExternalFunctionForPlugin("String::get_AsFloat", (void *)StringToFloat); + ccAddExternalFunctionForPlugin("String::get_AsInt", (void *)StringToInt); + ccAddExternalFunctionForPlugin("String::geti_Chars", (void *)String_GetChars); + ccAddExternalFunctionForPlugin("String::get_Length", (void *)strlen); } diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h index 3a2865e637fc..43968ed85491 100644 --- a/engines/ags/engine/ac/string.h +++ b/engines/ags/engine/ac/string.h @@ -30,32 +30,32 @@ #define VALIDATE_STRING(strin) if ((unsigned long)strin <= 4096) quit("!String argument was null: make sure you pass a string, not an int, as a buffer") int String_IsNullOrEmpty(const char *thisString); -const char* String_Copy(const char *srcString); -const char* String_Append(const char *thisString, const char *extrabit); -const char* String_AppendChar(const char *thisString, char extraOne); -const char* String_ReplaceCharAt(const char *thisString, int index, char newChar); -const char* String_Truncate(const char *thisString, int length); -const char* String_Substring(const char *thisString, int index, int length); +const char *String_Copy(const char *srcString); +const char *String_Append(const char *thisString, const char *extrabit); +const char *String_AppendChar(const char *thisString, char extraOne); +const char *String_ReplaceCharAt(const char *thisString, int index, char newChar); +const char *String_Truncate(const char *thisString, int length); +const char *String_Substring(const char *thisString, int index, int length); int String_CompareTo(const char *thisString, const char *otherString, bool caseSensitive); int String_StartsWith(const char *thisString, const char *checkForString, bool caseSensitive); int String_EndsWith(const char *thisString, const char *checkForString, bool caseSensitive); -const char* String_Replace(const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive); -const char* String_LowerCase(const char *thisString); -const char* String_UpperCase(const char *thisString); +const char *String_Replace(const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive); +const char *String_LowerCase(const char *thisString); +const char *String_UpperCase(const char *thisString); int String_GetChars(const char *texx, int index); -int StringToInt(const char*stino); -int StrContains (const char *s1, const char *s2); +int StringToInt(const char *stino); +int StrContains(const char *s1, const char *s2); //============================================================================= -const char* CreateNewScriptString(const char *fromText, bool reAllocate = true); +const char *CreateNewScriptString(const char *fromText, bool reAllocate = true); DynObjectRef CreateNewScriptStringObj(const char *fromText, bool reAllocate = true); class SplitLines; // Break up the text into lines restricted by the given width; // returns number of lines, or 0 if text cannot be split well to fit in this width. // Does additional processing, like removal of voice-over tags and text reversal if right-to-left text display is on. size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, int fonnt, size_t max_lines = -1); -void check_strlen(char*ptt); +void check_strlen(char *ptt); void my_strncpy(char *dest, const char *src, int len); #endif diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index 4293d6163b33..9c0d029b65f3 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -48,167 +48,223 @@ extern int misbuttondown(int buno); int mouse_z_was = 0; -int ags_kbhit () { - return keypressed(); +int ags_kbhit() { + return keypressed(); } -int ags_iskeypressed (int keycode) { - if (keycode >= 0 && keycode < __allegro_KEY_MAX) - { - return key[keycode] != 0; - } - return 0; +int ags_iskeypressed(int keycode) { + if (keycode >= 0 && keycode < __allegro_KEY_MAX) { + return key[keycode] != 0; + } + return 0; } -int ags_misbuttondown (int but) { - return misbuttondown(but); +int ags_misbuttondown(int but) { + return misbuttondown(but); } int ags_mgetbutton() { - int result; - - if (pluginSimulatedClick > NONE) { - result = pluginSimulatedClick; - pluginSimulatedClick = NONE; - } - else { - result = mgetbutton(); - } - return result; + int result; + + if (pluginSimulatedClick > NONE) { + result = pluginSimulatedClick; + pluginSimulatedClick = NONE; + } else { + result = mgetbutton(); + } + return result; } -void ags_domouse (int what) { - // do mouse is "update the mouse x,y and also the cursor position", unless DOMOUSE_NOCURSOR is set. - if (what == DOMOUSE_NOCURSOR) - mgetgraphpos(); - else - domouse(what); +void ags_domouse(int what) { + // do mouse is "update the mouse x,y and also the cursor position", unless DOMOUSE_NOCURSOR is set. + if (what == DOMOUSE_NOCURSOR) + mgetgraphpos(); + else + domouse(what); } -int ags_check_mouse_wheel () { - int result = 0; - if ((mouse_z != mouse_z_was) && (game.options[OPT_MOUSEWHEEL] != 0)) { - if (mouse_z > mouse_z_was) - result = 1; - else - result = -1; - mouse_z_was = mouse_z; - } - return result; +int ags_check_mouse_wheel() { + int result = 0; + if ((mouse_z != mouse_z_was) && (game.options[OPT_MOUSEWHEEL] != 0)) { + if (mouse_z > mouse_z_was) + result = 1; + else + result = -1; + mouse_z_was = mouse_z; + } + return result; } int ags_getch() { - const int read_key_value = readkey(); - int gott = read_key_value; - const int scancode = ((gott >> 8) & 0x00ff); - const int ascii = (gott & 0x00ff); - - bool is_extended = (ascii == EXTENDED_KEY_CODE); - // On macos, the extended keycode is the ascii character '?' or '\0' if alt-key - // so check it's not actually the character '?' - #if AGS_PLATFORM_OS_MACOS && ! AGS_PLATFORM_OS_IOS - is_extended = is_extended || ((ascii == EXTENDED_KEY_CODE_MACOS) && (scancode != __allegro_KEY_SLASH)); - #endif - - /* char message[200]; - sprintf(message, "Scancode: %04X", gott); - Debug::Printf(message);*/ - - /*if ((scancode >= KEY_0_PAD) && (scancode <= KEY_9_PAD)) { - // fix numeric pad keys if numlock is off (allegro 4.2 changed this behaviour) - if ((key_shifts & KB_NUMLOCK_FLAG) == 0) - gott = (gott & 0xff00) | EXTENDED_KEY_CODE; - }*/ - - if (gott == READKEY_CODE_ALT_TAB) - { - // Alt+Tab, it gets stuck down unless we do this - gott = AGS_KEYCODE_ALT_TAB; - } - #if AGS_PLATFORM_OS_MACOS - else if (scancode == __allegro_KEY_BACKSPACE) - { - gott = eAGSKeyCodeBackspace; - } - #endif - else if (is_extended) - { - - // I believe we rely on a lot of keys being converted to ASCII, which is why - // the complete scan code list is not here. - - switch(scancode) - { - case __allegro_KEY_F1 : gott = eAGSKeyCodeF1 ; break; - case __allegro_KEY_F2 : gott = eAGSKeyCodeF2 ; break; - case __allegro_KEY_F3 : gott = eAGSKeyCodeF3 ; break; - case __allegro_KEY_F4 : gott = eAGSKeyCodeF4 ; break; - case __allegro_KEY_F5 : gott = eAGSKeyCodeF5 ; break; - case __allegro_KEY_F6 : gott = eAGSKeyCodeF6 ; break; - case __allegro_KEY_F7 : gott = eAGSKeyCodeF7 ; break; - case __allegro_KEY_F8 : gott = eAGSKeyCodeF8 ; break; - case __allegro_KEY_F9 : gott = eAGSKeyCodeF9 ; break; - case __allegro_KEY_F10 : gott = eAGSKeyCodeF10 ; break; - case __allegro_KEY_F11 : gott = eAGSKeyCodeF11 ; break; - case __allegro_KEY_F12 : gott = eAGSKeyCodeF12 ; break; - - case __allegro_KEY_INSERT : gott = eAGSKeyCodeInsert ; break; - case __allegro_KEY_DEL : gott = eAGSKeyCodeDelete ; break; - case __allegro_KEY_HOME : gott = eAGSKeyCodeHome ; break; - case __allegro_KEY_END : gott = eAGSKeyCodeEnd ; break; - case __allegro_KEY_PGUP : gott = eAGSKeyCodePageUp ; break; - case __allegro_KEY_PGDN : gott = eAGSKeyCodePageDown ; break; - case __allegro_KEY_LEFT : gott = eAGSKeyCodeLeftArrow ; break; - case __allegro_KEY_RIGHT : gott = eAGSKeyCodeRightArrow ; break; - case __allegro_KEY_UP : gott = eAGSKeyCodeUpArrow ; break; - case __allegro_KEY_DOWN : gott = eAGSKeyCodeDownArrow ; break; - - case __allegro_KEY_0_PAD : gott = eAGSKeyCodeInsert ; break; - case __allegro_KEY_1_PAD : gott = eAGSKeyCodeEnd ; break; - case __allegro_KEY_2_PAD : gott = eAGSKeyCodeDownArrow ; break; - case __allegro_KEY_3_PAD : gott = eAGSKeyCodePageDown ; break; - case __allegro_KEY_4_PAD : gott = eAGSKeyCodeLeftArrow ; break; - case __allegro_KEY_5_PAD : gott = eAGSKeyCodeNumPad5 ; break; - case __allegro_KEY_6_PAD : gott = eAGSKeyCodeRightArrow ; break; - case __allegro_KEY_7_PAD : gott = eAGSKeyCodeHome ; break; - case __allegro_KEY_8_PAD : gott = eAGSKeyCodeUpArrow ; break; - case __allegro_KEY_9_PAD : gott = eAGSKeyCodePageUp ; break; - case __allegro_KEY_DEL_PAD : gott = eAGSKeyCodeDelete ; break; - - default: - // no meaningful mappings - // this is how we accidentally got the alt-key mappings - gott = scancode + AGS_EXT_KEY_SHIFT; - } - } - else - { - // this includes ascii characters and ctrl-A-Z - gott = ascii; - } - - // Alt+X, abort (but only once game is loaded) - if ((gott == play.abort_key) && (displayed_room >= 0)) { - check_dynamic_sprites_at_exit = 0; - quit("!|"); - } - - //sprintf(message, "Keypress: %d", gott); - //Debug::Printf(message); - - return gott; + const int read_key_value = readkey(); + int gott = read_key_value; + const int scancode = ((gott >> 8) & 0x00ff); + const int ascii = (gott & 0x00ff); + + bool is_extended = (ascii == EXTENDED_KEY_CODE); + // On macos, the extended keycode is the ascii character '?' or '\0' if alt-key + // so check it's not actually the character '?' +#if AGS_PLATFORM_OS_MACOS && ! AGS_PLATFORM_OS_IOS + is_extended = is_extended || ((ascii == EXTENDED_KEY_CODE_MACOS) && (scancode != __allegro_KEY_SLASH)); +#endif + + /* char message[200]; + sprintf(message, "Scancode: %04X", gott); + Debug::Printf(message);*/ + + /*if ((scancode >= KEY_0_PAD) && (scancode <= KEY_9_PAD)) { + // fix numeric pad keys if numlock is off (allegro 4.2 changed this behaviour) + if ((key_shifts & KB_NUMLOCK_FLAG) == 0) + gott = (gott & 0xff00) | EXTENDED_KEY_CODE; + }*/ + + if (gott == READKEY_CODE_ALT_TAB) { + // Alt+Tab, it gets stuck down unless we do this + gott = AGS_KEYCODE_ALT_TAB; + } +#if AGS_PLATFORM_OS_MACOS + else if (scancode == __allegro_KEY_BACKSPACE) { + gott = eAGSKeyCodeBackspace; + } +#endif + else if (is_extended) { + + // I believe we rely on a lot of keys being converted to ASCII, which is why + // the complete scan code list is not here. + + switch (scancode) { + case __allegro_KEY_F1 : + gott = eAGSKeyCodeF1 ; + break; + case __allegro_KEY_F2 : + gott = eAGSKeyCodeF2 ; + break; + case __allegro_KEY_F3 : + gott = eAGSKeyCodeF3 ; + break; + case __allegro_KEY_F4 : + gott = eAGSKeyCodeF4 ; + break; + case __allegro_KEY_F5 : + gott = eAGSKeyCodeF5 ; + break; + case __allegro_KEY_F6 : + gott = eAGSKeyCodeF6 ; + break; + case __allegro_KEY_F7 : + gott = eAGSKeyCodeF7 ; + break; + case __allegro_KEY_F8 : + gott = eAGSKeyCodeF8 ; + break; + case __allegro_KEY_F9 : + gott = eAGSKeyCodeF9 ; + break; + case __allegro_KEY_F10 : + gott = eAGSKeyCodeF10 ; + break; + case __allegro_KEY_F11 : + gott = eAGSKeyCodeF11 ; + break; + case __allegro_KEY_F12 : + gott = eAGSKeyCodeF12 ; + break; + + case __allegro_KEY_INSERT : + gott = eAGSKeyCodeInsert ; + break; + case __allegro_KEY_DEL : + gott = eAGSKeyCodeDelete ; + break; + case __allegro_KEY_HOME : + gott = eAGSKeyCodeHome ; + break; + case __allegro_KEY_END : + gott = eAGSKeyCodeEnd ; + break; + case __allegro_KEY_PGUP : + gott = eAGSKeyCodePageUp ; + break; + case __allegro_KEY_PGDN : + gott = eAGSKeyCodePageDown ; + break; + case __allegro_KEY_LEFT : + gott = eAGSKeyCodeLeftArrow ; + break; + case __allegro_KEY_RIGHT : + gott = eAGSKeyCodeRightArrow ; + break; + case __allegro_KEY_UP : + gott = eAGSKeyCodeUpArrow ; + break; + case __allegro_KEY_DOWN : + gott = eAGSKeyCodeDownArrow ; + break; + + case __allegro_KEY_0_PAD : + gott = eAGSKeyCodeInsert ; + break; + case __allegro_KEY_1_PAD : + gott = eAGSKeyCodeEnd ; + break; + case __allegro_KEY_2_PAD : + gott = eAGSKeyCodeDownArrow ; + break; + case __allegro_KEY_3_PAD : + gott = eAGSKeyCodePageDown ; + break; + case __allegro_KEY_4_PAD : + gott = eAGSKeyCodeLeftArrow ; + break; + case __allegro_KEY_5_PAD : + gott = eAGSKeyCodeNumPad5 ; + break; + case __allegro_KEY_6_PAD : + gott = eAGSKeyCodeRightArrow ; + break; + case __allegro_KEY_7_PAD : + gott = eAGSKeyCodeHome ; + break; + case __allegro_KEY_8_PAD : + gott = eAGSKeyCodeUpArrow ; + break; + case __allegro_KEY_9_PAD : + gott = eAGSKeyCodePageUp ; + break; + case __allegro_KEY_DEL_PAD : + gott = eAGSKeyCodeDelete ; + break; + + default: + // no meaningful mappings + // this is how we accidentally got the alt-key mappings + gott = scancode + AGS_EXT_KEY_SHIFT; + } + } else { + // this includes ascii characters and ctrl-A-Z + gott = ascii; + } + + // Alt+X, abort (but only once game is loaded) + if ((gott == play.abort_key) && (displayed_room >= 0)) { + check_dynamic_sprites_at_exit = 0; + quit("!|"); + } + + //sprintf(message, "Keypress: %d", gott); + //Debug::Printf(message); + + return gott; } -void ags_clear_input_buffer() -{ - while (ags_kbhit()) ags_getch(); - while (mgetbutton() != NONE); +void ags_clear_input_buffer() { + while (ags_kbhit()) ags_getch(); + while (mgetbutton() != NONE); } -void ags_wait_until_keypress() -{ - while (!ags_kbhit()) { - platform->YieldCPU(); - } - ags_getch(); +void ags_wait_until_keypress() { + while (!ags_kbhit()) { + platform->YieldCPU(); + } + ags_getch(); } diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h index 42e34f9c86be..d2e953193040 100644 --- a/engines/ags/engine/ac/sys_events.h +++ b/engines/ags/engine/ac/sys_events.h @@ -23,14 +23,14 @@ #ifndef AGS_ENGINE_AC_SYS_EVENTS_H #define AGS_ENGINE_AC_SYS_EVENTS_H -int ags_getch (); -int ags_kbhit (); -int ags_iskeypressed (int keycode); +int ags_getch(); +int ags_kbhit(); +int ags_iskeypressed(int keycode); -int ags_misbuttondown (int but); +int ags_misbuttondown(int but); int ags_mgetbutton(); -void ags_domouse (int what); -int ags_check_mouse_wheel (); +void ags_domouse(int what); +int ags_check_mouse_wheel(); // Clears buffered keypresses and mouse clicks, if any void ags_clear_input_buffer(); diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index eb91e8c62998..e4936cb9e39f 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -53,17 +53,16 @@ extern IGraphicsDriver *gfxDriver; extern CCAudioChannel ccDynamicAudio; extern volatile bool switched_away; -bool System_HasInputFocus() -{ - return !switched_away; +bool System_HasInputFocus() { + return !switched_away; } int System_GetColorDepth() { - return scsystem.coldepth; + return scsystem.coldepth; } int System_GetOS() { - return scsystem.os; + return scsystem.os; } // [IKM] 2014-09-21 @@ -72,7 +71,7 @@ int System_GetOS() { // in pixels, but rather game frame size, which could include black borders, // in 'native' (unscaled) pixels. This was due the specifics of how graphics // modes were implemented in previous versions. -// +// // Quote from the old manual: // "Returns the actual screen width that the game is running at. If a graphic // filter is in use, the resolution returned will be that before any @@ -88,151 +87,136 @@ int System_GetOS() { // compatibility. // int System_GetScreenWidth() { - return game.GetGameRes().Width; + return game.GetGameRes().Width; } int System_GetScreenHeight() { - return game.GetGameRes().Height; + return game.GetGameRes().Height; } int System_GetViewportHeight() { - return game_to_data_coord(play.GetMainViewport().GetHeight()); + return game_to_data_coord(play.GetMainViewport().GetHeight()); } int System_GetViewportWidth() { - return game_to_data_coord(play.GetMainViewport().GetWidth()); + return game_to_data_coord(play.GetMainViewport().GetWidth()); } const char *System_GetVersion() { - return CreateNewScriptString(EngineVersion.LongString); + return CreateNewScriptString(EngineVersion.LongString); } -int System_GetHardwareAcceleration() -{ - return gfxDriver->HasAcceleratedTransform() ? 1 : 0; +int System_GetHardwareAcceleration() { + return gfxDriver->HasAcceleratedTransform() ? 1 : 0; } -int System_GetNumLock() -{ - return (key_shifts & KB_NUMLOCK_FLAG) ? 1 : 0; +int System_GetNumLock() { + return (key_shifts & KB_NUMLOCK_FLAG) ? 1 : 0; } -int System_GetCapsLock() -{ - return (key_shifts & KB_CAPSLOCK_FLAG) ? 1 : 0; +int System_GetCapsLock() { + return (key_shifts & KB_CAPSLOCK_FLAG) ? 1 : 0; } -int System_GetScrollLock() -{ - return (key_shifts & KB_SCROLOCK_FLAG) ? 1 : 0; +int System_GetScrollLock() { + return (key_shifts & KB_SCROLOCK_FLAG) ? 1 : 0; } -void System_SetNumLock(int newValue) -{ - // doesn't work ... maybe allegro doesn't implement this on windows - int ledState = key_shifts & (KB_SCROLOCK_FLAG | KB_CAPSLOCK_FLAG); - if (newValue) - { - ledState |= KB_NUMLOCK_FLAG; - } - set_leds(ledState); +void System_SetNumLock(int newValue) { + // doesn't work ... maybe allegro doesn't implement this on windows + int ledState = key_shifts & (KB_SCROLOCK_FLAG | KB_CAPSLOCK_FLAG); + if (newValue) { + ledState |= KB_NUMLOCK_FLAG; + } + set_leds(ledState); } int System_GetVsync() { - return scsystem.vsync; + return scsystem.vsync; } void System_SetVsync(int newValue) { - if(ags_stricmp(gfxDriver->GetDriverID(), "D3D9") != 0) - scsystem.vsync = newValue; + if (ags_stricmp(gfxDriver->GetDriverID(), "D3D9") != 0) + scsystem.vsync = newValue; } int System_GetWindowed() { - return scsystem.windowed; + return scsystem.windowed; } -void System_SetWindowed(int windowed) -{ - if (windowed != scsystem.windowed) - engine_try_switch_windowed_gfxmode(); +void System_SetWindowed(int windowed) { + if (windowed != scsystem.windowed) + engine_try_switch_windowed_gfxmode(); } int System_GetSupportsGammaControl() { - return gfxDriver->SupportsGammaControl(); + return gfxDriver->SupportsGammaControl(); } int System_GetGamma() { - return play.gamma_adjustment; + return play.gamma_adjustment; } void System_SetGamma(int newValue) { - if ((newValue < 0) || (newValue > 200)) - quitprintf("!System.Gamma: value must be between 0-200 (not %d)", newValue); + if ((newValue < 0) || (newValue > 200)) + quitprintf("!System.Gamma: value must be between 0-200 (not %d)", newValue); - if (play.gamma_adjustment != newValue) { - debug_script_log("Gamma control set to %d", newValue); - play.gamma_adjustment = newValue; + if (play.gamma_adjustment != newValue) { + debug_script_log("Gamma control set to %d", newValue); + play.gamma_adjustment = newValue; - if (gfxDriver->SupportsGammaControl()) - gfxDriver->SetGamma(newValue); - } + if (gfxDriver->SupportsGammaControl()) + gfxDriver->SetGamma(newValue); + } } -int System_GetAudioChannelCount() -{ - return MAX_SOUND_CHANNELS; +int System_GetAudioChannelCount() { + return MAX_SOUND_CHANNELS; } -ScriptAudioChannel* System_GetAudioChannels(int index) -{ - if ((index < 0) || (index >= MAX_SOUND_CHANNELS)) - quit("!System.AudioChannels: invalid sound channel index"); +ScriptAudioChannel *System_GetAudioChannels(int index) { + if ((index < 0) || (index >= MAX_SOUND_CHANNELS)) + quit("!System.AudioChannels: invalid sound channel index"); - return &scrAudioChannel[index]; + return &scrAudioChannel[index]; } -int System_GetVolume() -{ - return play.digital_master_volume; +int System_GetVolume() { + return play.digital_master_volume; } -void System_SetVolume(int newvol) -{ - if ((newvol < 0) || (newvol > 100)) - quit("!System.Volume: invalid volume - must be from 0-100"); +void System_SetVolume(int newvol) { + if ((newvol < 0) || (newvol > 100)) + quit("!System.Volume: invalid volume - must be from 0-100"); - if (newvol == play.digital_master_volume) - return; + if (newvol == play.digital_master_volume) + return; - play.digital_master_volume = newvol; - set_volume((newvol * 255) / 100, (newvol * 255) / 100); + play.digital_master_volume = newvol; + set_volume((newvol * 255) / 100, (newvol * 255) / 100); - // allegro's set_volume can lose the volumes of all the channels - // if it was previously set low; so restore them - AudioChannelsLock lock; - for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) - { - auto* ch = lock.GetChannelIfPlaying(i); - if (ch) - ch->adjust_volume(); - } + // allegro's set_volume can lose the volumes of all the channels + // if it was previously set low; so restore them + AudioChannelsLock lock; + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if (ch) + ch->adjust_volume(); + } } -const char* System_GetRuntimeInfo() -{ - String runtimeInfo = GetRuntimeInfo(); +const char *System_GetRuntimeInfo() { + String runtimeInfo = GetRuntimeInfo(); - return CreateNewScriptString(runtimeInfo.GetCStr()); + return CreateNewScriptString(runtimeInfo.GetCStr()); } -int System_GetRenderAtScreenResolution() -{ - return usetup.RenderAtScreenRes; +int System_GetRenderAtScreenResolution() { + return usetup.RenderAtScreenRes; } -void System_SetRenderAtScreenResolution(int enable) -{ - usetup.RenderAtScreenRes = enable != 0; +void System_SetRenderAtScreenResolution(int enable) { + usetup.RenderAtScreenRes = enable != 0; } //============================================================================= @@ -249,227 +233,198 @@ void System_SetRenderAtScreenResolution(int enable) extern ScriptString myScriptStringImpl; // int () -RuntimeScriptValue Sc_System_GetAudioChannelCount(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetAudioChannelCount); +RuntimeScriptValue Sc_System_GetAudioChannelCount(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetAudioChannelCount); } // ScriptAudioChannel* (int index) -RuntimeScriptValue Sc_System_GetAudioChannels(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ_PINT(ScriptAudioChannel, ccDynamicAudio, System_GetAudioChannels); +RuntimeScriptValue Sc_System_GetAudioChannels(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ_PINT(ScriptAudioChannel, ccDynamicAudio, System_GetAudioChannels); } // int () -RuntimeScriptValue Sc_System_GetCapsLock(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetCapsLock); +RuntimeScriptValue Sc_System_GetCapsLock(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetCapsLock); } // int () -RuntimeScriptValue Sc_System_GetColorDepth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetColorDepth); +RuntimeScriptValue Sc_System_GetColorDepth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetColorDepth); } // int () -RuntimeScriptValue Sc_System_GetGamma(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetGamma); +RuntimeScriptValue Sc_System_GetGamma(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetGamma); } // void (int newValue) -RuntimeScriptValue Sc_System_SetGamma(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(System_SetGamma); +RuntimeScriptValue Sc_System_SetGamma(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(System_SetGamma); } -// int () -RuntimeScriptValue Sc_System_GetHardwareAcceleration(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetHardwareAcceleration); +// int () +RuntimeScriptValue Sc_System_GetHardwareAcceleration(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetHardwareAcceleration); } -RuntimeScriptValue Sc_System_GetHasInputFocus(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_BOOL(System_HasInputFocus); +RuntimeScriptValue Sc_System_GetHasInputFocus(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_BOOL(System_HasInputFocus); } // int () -RuntimeScriptValue Sc_System_GetNumLock(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetNumLock); +RuntimeScriptValue Sc_System_GetNumLock(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetNumLock); } // void (int newValue) -RuntimeScriptValue Sc_System_SetNumLock(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(System_SetNumLock); +RuntimeScriptValue Sc_System_SetNumLock(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(System_SetNumLock); } // int () -RuntimeScriptValue Sc_System_GetOS(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetOS); +RuntimeScriptValue Sc_System_GetOS(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetOS); } // int () -RuntimeScriptValue Sc_System_GetScreenHeight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetScreenHeight); +RuntimeScriptValue Sc_System_GetScreenHeight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetScreenHeight); } // int () -RuntimeScriptValue Sc_System_GetScreenWidth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetScreenWidth); +RuntimeScriptValue Sc_System_GetScreenWidth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetScreenWidth); } // int () -RuntimeScriptValue Sc_System_GetScrollLock(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetScrollLock); +RuntimeScriptValue Sc_System_GetScrollLock(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetScrollLock); } // int () -RuntimeScriptValue Sc_System_GetSupportsGammaControl(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetSupportsGammaControl); +RuntimeScriptValue Sc_System_GetSupportsGammaControl(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetSupportsGammaControl); } // const char *() -RuntimeScriptValue Sc_System_GetVersion(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ(const char, myScriptStringImpl, System_GetVersion); +RuntimeScriptValue Sc_System_GetVersion(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ(const char, myScriptStringImpl, System_GetVersion); } // int () -RuntimeScriptValue Sc_System_GetViewportHeight(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetViewportHeight); +RuntimeScriptValue Sc_System_GetViewportHeight(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetViewportHeight); } // int () -RuntimeScriptValue Sc_System_GetViewportWidth(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetViewportWidth); +RuntimeScriptValue Sc_System_GetViewportWidth(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetViewportWidth); } // int () -RuntimeScriptValue Sc_System_GetVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetVolume); +RuntimeScriptValue Sc_System_GetVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetVolume); } // void (int newvol) -RuntimeScriptValue Sc_System_SetVolume(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(System_SetVolume); +RuntimeScriptValue Sc_System_SetVolume(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(System_SetVolume); } // int () -RuntimeScriptValue Sc_System_GetVsync(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetVsync); +RuntimeScriptValue Sc_System_GetVsync(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetVsync); } // void (int newValue) -RuntimeScriptValue Sc_System_SetVsync(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(System_SetVsync); +RuntimeScriptValue Sc_System_SetVsync(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(System_SetVsync); } -RuntimeScriptValue Sc_System_GetWindowed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetWindowed); +RuntimeScriptValue Sc_System_GetWindowed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetWindowed); } -RuntimeScriptValue Sc_System_SetWindowed(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(System_SetWindowed); +RuntimeScriptValue Sc_System_SetWindowed(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(System_SetWindowed); } // const char *() -RuntimeScriptValue Sc_System_GetRuntimeInfo(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJ(const char, myScriptStringImpl, System_GetRuntimeInfo); -} - -RuntimeScriptValue Sc_System_GetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_INT(System_GetRenderAtScreenResolution); -} - -RuntimeScriptValue Sc_System_SetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_VOID_PINT(System_SetRenderAtScreenResolution); -} - -RuntimeScriptValue Sc_System_Log(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_SCRIPT_SPRINTF(Sc_System_Log, 2); - Debug::Printf(kDbgGroup_Script, (MessageType)params[0].IValue, "%s", scsf_buffer); - return RuntimeScriptValue((int32_t)0); -} - - - -void RegisterSystemAPI() -{ - ccAddExternalStaticFunction("System::get_AudioChannelCount", Sc_System_GetAudioChannelCount); - ccAddExternalStaticFunction("System::geti_AudioChannels", Sc_System_GetAudioChannels); - ccAddExternalStaticFunction("System::get_CapsLock", Sc_System_GetCapsLock); - ccAddExternalStaticFunction("System::get_ColorDepth", Sc_System_GetColorDepth); - ccAddExternalStaticFunction("System::get_Gamma", Sc_System_GetGamma); - ccAddExternalStaticFunction("System::set_Gamma", Sc_System_SetGamma); - ccAddExternalStaticFunction("System::get_HardwareAcceleration", Sc_System_GetHardwareAcceleration); - ccAddExternalStaticFunction("System::get_HasInputFocus", Sc_System_GetHasInputFocus); - ccAddExternalStaticFunction("System::get_NumLock", Sc_System_GetNumLock); - ccAddExternalStaticFunction("System::set_NumLock", Sc_System_SetNumLock); - ccAddExternalStaticFunction("System::get_OperatingSystem", Sc_System_GetOS); - ccAddExternalStaticFunction("System::get_RenderAtScreenResolution", Sc_System_GetRenderAtScreenResolution); - ccAddExternalStaticFunction("System::set_RenderAtScreenResolution", Sc_System_SetRenderAtScreenResolution); - ccAddExternalStaticFunction("System::get_RuntimeInfo", Sc_System_GetRuntimeInfo); - ccAddExternalStaticFunction("System::get_ScreenHeight", Sc_System_GetScreenHeight); - ccAddExternalStaticFunction("System::get_ScreenWidth", Sc_System_GetScreenWidth); - ccAddExternalStaticFunction("System::get_ScrollLock", Sc_System_GetScrollLock); - ccAddExternalStaticFunction("System::get_SupportsGammaControl", Sc_System_GetSupportsGammaControl); - ccAddExternalStaticFunction("System::get_Version", Sc_System_GetVersion); - ccAddExternalStaticFunction("SystemInfo::get_Version", Sc_System_GetVersion); - ccAddExternalStaticFunction("System::get_ViewportHeight", Sc_System_GetViewportHeight); - ccAddExternalStaticFunction("System::get_ViewportWidth", Sc_System_GetViewportWidth); - ccAddExternalStaticFunction("System::get_Volume", Sc_System_GetVolume); - ccAddExternalStaticFunction("System::set_Volume", Sc_System_SetVolume); - ccAddExternalStaticFunction("System::get_VSync", Sc_System_GetVsync); - ccAddExternalStaticFunction("System::set_VSync", Sc_System_SetVsync); - ccAddExternalStaticFunction("System::get_Windowed", Sc_System_GetWindowed); - ccAddExternalStaticFunction("System::set_Windowed", Sc_System_SetWindowed); - ccAddExternalStaticFunction("System::Log^102", Sc_System_Log); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("System::get_AudioChannelCount", (void*)System_GetAudioChannelCount); - ccAddExternalFunctionForPlugin("System::geti_AudioChannels", (void*)System_GetAudioChannels); - ccAddExternalFunctionForPlugin("System::get_CapsLock", (void*)System_GetCapsLock); - ccAddExternalFunctionForPlugin("System::get_ColorDepth", (void*)System_GetColorDepth); - ccAddExternalFunctionForPlugin("System::get_Gamma", (void*)System_GetGamma); - ccAddExternalFunctionForPlugin("System::set_Gamma", (void*)System_SetGamma); - ccAddExternalFunctionForPlugin("System::get_HardwareAcceleration", (void*)System_GetHardwareAcceleration); - ccAddExternalFunctionForPlugin("System::get_NumLock", (void*)System_GetNumLock); - ccAddExternalFunctionForPlugin("System::set_NumLock", (void*)System_SetNumLock); - ccAddExternalFunctionForPlugin("System::get_OperatingSystem", (void*)System_GetOS); - ccAddExternalFunctionForPlugin("System::get_RuntimeInfo", (void*)System_GetRuntimeInfo); - ccAddExternalFunctionForPlugin("System::get_ScreenHeight", (void*)System_GetScreenHeight); - ccAddExternalFunctionForPlugin("System::get_ScreenWidth", (void*)System_GetScreenWidth); - ccAddExternalFunctionForPlugin("System::get_ScrollLock", (void*)System_GetScrollLock); - ccAddExternalFunctionForPlugin("System::get_SupportsGammaControl", (void*)System_GetSupportsGammaControl); - ccAddExternalFunctionForPlugin("System::get_Version", (void*)System_GetVersion); - ccAddExternalFunctionForPlugin("SystemInfo::get_Version", (void*)System_GetVersion); - ccAddExternalFunctionForPlugin("System::get_ViewportHeight", (void*)System_GetViewportHeight); - ccAddExternalFunctionForPlugin("System::get_ViewportWidth", (void*)System_GetViewportWidth); - ccAddExternalFunctionForPlugin("System::get_Volume", (void*)System_GetVolume); - ccAddExternalFunctionForPlugin("System::set_Volume", (void*)System_SetVolume); - ccAddExternalFunctionForPlugin("System::get_VSync", (void*)System_GetVsync); - ccAddExternalFunctionForPlugin("System::set_VSync", (void*)System_SetVsync); - ccAddExternalFunctionForPlugin("System::get_Windowed", (void*)System_GetWindowed); +RuntimeScriptValue Sc_System_GetRuntimeInfo(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJ(const char, myScriptStringImpl, System_GetRuntimeInfo); +} + +RuntimeScriptValue Sc_System_GetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_INT(System_GetRenderAtScreenResolution); +} + +RuntimeScriptValue Sc_System_SetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_VOID_PINT(System_SetRenderAtScreenResolution); +} + +RuntimeScriptValue Sc_System_Log(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_SCRIPT_SPRINTF(Sc_System_Log, 2); + Debug::Printf(kDbgGroup_Script, (MessageType)params[0].IValue, "%s", scsf_buffer); + return RuntimeScriptValue((int32_t)0); +} + + + +void RegisterSystemAPI() { + ccAddExternalStaticFunction("System::get_AudioChannelCount", Sc_System_GetAudioChannelCount); + ccAddExternalStaticFunction("System::geti_AudioChannels", Sc_System_GetAudioChannels); + ccAddExternalStaticFunction("System::get_CapsLock", Sc_System_GetCapsLock); + ccAddExternalStaticFunction("System::get_ColorDepth", Sc_System_GetColorDepth); + ccAddExternalStaticFunction("System::get_Gamma", Sc_System_GetGamma); + ccAddExternalStaticFunction("System::set_Gamma", Sc_System_SetGamma); + ccAddExternalStaticFunction("System::get_HardwareAcceleration", Sc_System_GetHardwareAcceleration); + ccAddExternalStaticFunction("System::get_HasInputFocus", Sc_System_GetHasInputFocus); + ccAddExternalStaticFunction("System::get_NumLock", Sc_System_GetNumLock); + ccAddExternalStaticFunction("System::set_NumLock", Sc_System_SetNumLock); + ccAddExternalStaticFunction("System::get_OperatingSystem", Sc_System_GetOS); + ccAddExternalStaticFunction("System::get_RenderAtScreenResolution", Sc_System_GetRenderAtScreenResolution); + ccAddExternalStaticFunction("System::set_RenderAtScreenResolution", Sc_System_SetRenderAtScreenResolution); + ccAddExternalStaticFunction("System::get_RuntimeInfo", Sc_System_GetRuntimeInfo); + ccAddExternalStaticFunction("System::get_ScreenHeight", Sc_System_GetScreenHeight); + ccAddExternalStaticFunction("System::get_ScreenWidth", Sc_System_GetScreenWidth); + ccAddExternalStaticFunction("System::get_ScrollLock", Sc_System_GetScrollLock); + ccAddExternalStaticFunction("System::get_SupportsGammaControl", Sc_System_GetSupportsGammaControl); + ccAddExternalStaticFunction("System::get_Version", Sc_System_GetVersion); + ccAddExternalStaticFunction("SystemInfo::get_Version", Sc_System_GetVersion); + ccAddExternalStaticFunction("System::get_ViewportHeight", Sc_System_GetViewportHeight); + ccAddExternalStaticFunction("System::get_ViewportWidth", Sc_System_GetViewportWidth); + ccAddExternalStaticFunction("System::get_Volume", Sc_System_GetVolume); + ccAddExternalStaticFunction("System::set_Volume", Sc_System_SetVolume); + ccAddExternalStaticFunction("System::get_VSync", Sc_System_GetVsync); + ccAddExternalStaticFunction("System::set_VSync", Sc_System_SetVsync); + ccAddExternalStaticFunction("System::get_Windowed", Sc_System_GetWindowed); + ccAddExternalStaticFunction("System::set_Windowed", Sc_System_SetWindowed); + ccAddExternalStaticFunction("System::Log^102", Sc_System_Log); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("System::get_AudioChannelCount", (void *)System_GetAudioChannelCount); + ccAddExternalFunctionForPlugin("System::geti_AudioChannels", (void *)System_GetAudioChannels); + ccAddExternalFunctionForPlugin("System::get_CapsLock", (void *)System_GetCapsLock); + ccAddExternalFunctionForPlugin("System::get_ColorDepth", (void *)System_GetColorDepth); + ccAddExternalFunctionForPlugin("System::get_Gamma", (void *)System_GetGamma); + ccAddExternalFunctionForPlugin("System::set_Gamma", (void *)System_SetGamma); + ccAddExternalFunctionForPlugin("System::get_HardwareAcceleration", (void *)System_GetHardwareAcceleration); + ccAddExternalFunctionForPlugin("System::get_NumLock", (void *)System_GetNumLock); + ccAddExternalFunctionForPlugin("System::set_NumLock", (void *)System_SetNumLock); + ccAddExternalFunctionForPlugin("System::get_OperatingSystem", (void *)System_GetOS); + ccAddExternalFunctionForPlugin("System::get_RuntimeInfo", (void *)System_GetRuntimeInfo); + ccAddExternalFunctionForPlugin("System::get_ScreenHeight", (void *)System_GetScreenHeight); + ccAddExternalFunctionForPlugin("System::get_ScreenWidth", (void *)System_GetScreenWidth); + ccAddExternalFunctionForPlugin("System::get_ScrollLock", (void *)System_GetScrollLock); + ccAddExternalFunctionForPlugin("System::get_SupportsGammaControl", (void *)System_GetSupportsGammaControl); + ccAddExternalFunctionForPlugin("System::get_Version", (void *)System_GetVersion); + ccAddExternalFunctionForPlugin("SystemInfo::get_Version", (void *)System_GetVersion); + ccAddExternalFunctionForPlugin("System::get_ViewportHeight", (void *)System_GetViewportHeight); + ccAddExternalFunctionForPlugin("System::get_ViewportWidth", (void *)System_GetViewportWidth); + ccAddExternalFunctionForPlugin("System::get_Volume", (void *)System_GetVolume); + ccAddExternalFunctionForPlugin("System::set_Volume", (void *)System_SetVolume); + ccAddExternalFunctionForPlugin("System::get_VSync", (void *)System_GetVsync); + ccAddExternalFunctionForPlugin("System::set_VSync", (void *)System_SetVsync); + ccAddExternalFunctionForPlugin("System::get_Windowed", (void *)System_GetWindowed); } diff --git a/engines/ags/engine/ac/system.h b/engines/ags/engine/ac/system.h index ba372a379745..7ed12cc875c3 100644 --- a/engines/ags/engine/ac/system.h +++ b/engines/ags/engine/ac/system.h @@ -44,7 +44,7 @@ int System_GetSupportsGammaControl(); int System_GetGamma(); void System_SetGamma(int newValue); int System_GetAudioChannelCount(); -ScriptAudioChannel* System_GetAudioChannels(int index); +ScriptAudioChannel *System_GetAudioChannels(int index); int System_GetVolume(); void System_SetVolume(int newvol); const char *System_GetRuntimeInfo(); diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp index 100d936c73b0..4d8bce4677a6 100644 --- a/engines/ags/engine/ac/textbox.cpp +++ b/engines/ags/engine/ac/textbox.cpp @@ -31,59 +31,55 @@ extern GameSetupStruct game; // ** TEXT BOX FUNCTIONS -const char* TextBox_GetText_New(GUITextBox *texbox) { - return CreateNewScriptString(texbox->Text); +const char *TextBox_GetText_New(GUITextBox *texbox) { + return CreateNewScriptString(texbox->Text); } void TextBox_GetText(GUITextBox *texbox, char *buffer) { - strcpy(buffer, texbox->Text); + strcpy(buffer, texbox->Text); } void TextBox_SetText(GUITextBox *texbox, const char *newtex) { - if (strcmp(texbox->Text, newtex)) { - texbox->Text = newtex; - guis_need_update = 1; - } + if (strcmp(texbox->Text, newtex)) { + texbox->Text = newtex; + guis_need_update = 1; + } } int TextBox_GetTextColor(GUITextBox *guit) { - return guit->TextColor; + return guit->TextColor; } -void TextBox_SetTextColor(GUITextBox *guit, int colr) -{ - if (guit->TextColor != colr) - { - guit->TextColor = colr; - guis_need_update = 1; - } +void TextBox_SetTextColor(GUITextBox *guit, int colr) { + if (guit->TextColor != colr) { + guit->TextColor = colr; + guis_need_update = 1; + } } int TextBox_GetFont(GUITextBox *guit) { - return guit->Font; + return guit->Font; } void TextBox_SetFont(GUITextBox *guit, int fontnum) { - if ((fontnum < 0) || (fontnum >= game.numfonts)) - quit("!SetTextBoxFont: invalid font number."); + if ((fontnum < 0) || (fontnum >= game.numfonts)) + quit("!SetTextBoxFont: invalid font number."); - if (guit->Font != fontnum) { - guit->Font = fontnum; - guis_need_update = 1; - } + if (guit->Font != fontnum) { + guit->Font = fontnum; + guis_need_update = 1; + } } bool TextBox_GetShowBorder(GUITextBox *guit) { - return guit->IsBorderShown(); + return guit->IsBorderShown(); } -void TextBox_SetShowBorder(GUITextBox *guit, bool on) -{ - if (guit->IsBorderShown() != on) - { - guit->SetShowBorder(on); - guis_need_update = 1; - } +void TextBox_SetShowBorder(GUITextBox *guit, bool on) { + if (guit->IsBorderShown() != on) { + guit->SetShowBorder(on); + guis_need_update = 1; + } } //============================================================================= @@ -100,80 +96,70 @@ void TextBox_SetShowBorder(GUITextBox *guit, bool on) extern ScriptString myScriptStringImpl; // void (GUITextBox *texbox, char *buffer) -RuntimeScriptValue Sc_TextBox_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUITextBox, TextBox_GetText, char); +RuntimeScriptValue Sc_TextBox_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUITextBox, TextBox_GetText, char); } // void (GUITextBox *texbox, const char *newtex) -RuntimeScriptValue Sc_TextBox_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(GUITextBox, TextBox_SetText, const char); +RuntimeScriptValue Sc_TextBox_SetText(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(GUITextBox, TextBox_SetText, const char); } // int (GUITextBox *guit) -RuntimeScriptValue Sc_TextBox_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUITextBox, TextBox_GetFont); +RuntimeScriptValue Sc_TextBox_GetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUITextBox, TextBox_GetFont); } // void (GUITextBox *guit, int fontnum) -RuntimeScriptValue Sc_TextBox_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUITextBox, TextBox_SetFont); +RuntimeScriptValue Sc_TextBox_SetFont(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUITextBox, TextBox_SetFont); } -RuntimeScriptValue Sc_TextBox_GetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(GUITextBox, TextBox_GetShowBorder); +RuntimeScriptValue Sc_TextBox_GetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(GUITextBox, TextBox_GetShowBorder); } // void (GUITextBox *guit, int fontnum) -RuntimeScriptValue Sc_TextBox_SetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PBOOL(GUITextBox, TextBox_SetShowBorder); +RuntimeScriptValue Sc_TextBox_SetShowBorder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PBOOL(GUITextBox, TextBox_SetShowBorder); } // const char* (GUITextBox *texbox) -RuntimeScriptValue Sc_TextBox_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(GUITextBox, const char *, myScriptStringImpl, TextBox_GetText_New); +RuntimeScriptValue Sc_TextBox_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(GUITextBox, const char *, myScriptStringImpl, TextBox_GetText_New); } // int (GUITextBox *guit) -RuntimeScriptValue Sc_TextBox_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(GUITextBox, TextBox_GetTextColor); +RuntimeScriptValue Sc_TextBox_GetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(GUITextBox, TextBox_GetTextColor); } // void (GUITextBox *guit, int colr) -RuntimeScriptValue Sc_TextBox_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(GUITextBox, TextBox_SetTextColor); -} - - -void RegisterTextBoxAPI() -{ - ccAddExternalObjectFunction("TextBox::GetText^1", Sc_TextBox_GetText); - ccAddExternalObjectFunction("TextBox::SetText^1", Sc_TextBox_SetText); - ccAddExternalObjectFunction("TextBox::get_Font", Sc_TextBox_GetFont); - ccAddExternalObjectFunction("TextBox::set_Font", Sc_TextBox_SetFont); - ccAddExternalObjectFunction("TextBox::get_ShowBorder", Sc_TextBox_GetShowBorder); - ccAddExternalObjectFunction("TextBox::set_ShowBorder", Sc_TextBox_SetShowBorder); - ccAddExternalObjectFunction("TextBox::get_Text", Sc_TextBox_GetText_New); - ccAddExternalObjectFunction("TextBox::set_Text", Sc_TextBox_SetText); - ccAddExternalObjectFunction("TextBox::get_TextColor", Sc_TextBox_GetTextColor); - ccAddExternalObjectFunction("TextBox::set_TextColor", Sc_TextBox_SetTextColor); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("TextBox::GetText^1", (void*)TextBox_GetText); - ccAddExternalFunctionForPlugin("TextBox::SetText^1", (void*)TextBox_SetText); - ccAddExternalFunctionForPlugin("TextBox::get_Font", (void*)TextBox_GetFont); - ccAddExternalFunctionForPlugin("TextBox::set_Font", (void*)TextBox_SetFont); - ccAddExternalFunctionForPlugin("TextBox::get_Text", (void*)TextBox_GetText_New); - ccAddExternalFunctionForPlugin("TextBox::set_Text", (void*)TextBox_SetText); - ccAddExternalFunctionForPlugin("TextBox::get_TextColor", (void*)TextBox_GetTextColor); - ccAddExternalFunctionForPlugin("TextBox::set_TextColor", (void*)TextBox_SetTextColor); +RuntimeScriptValue Sc_TextBox_SetTextColor(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(GUITextBox, TextBox_SetTextColor); +} + + +void RegisterTextBoxAPI() { + ccAddExternalObjectFunction("TextBox::GetText^1", Sc_TextBox_GetText); + ccAddExternalObjectFunction("TextBox::SetText^1", Sc_TextBox_SetText); + ccAddExternalObjectFunction("TextBox::get_Font", Sc_TextBox_GetFont); + ccAddExternalObjectFunction("TextBox::set_Font", Sc_TextBox_SetFont); + ccAddExternalObjectFunction("TextBox::get_ShowBorder", Sc_TextBox_GetShowBorder); + ccAddExternalObjectFunction("TextBox::set_ShowBorder", Sc_TextBox_SetShowBorder); + ccAddExternalObjectFunction("TextBox::get_Text", Sc_TextBox_GetText_New); + ccAddExternalObjectFunction("TextBox::set_Text", Sc_TextBox_SetText); + ccAddExternalObjectFunction("TextBox::get_TextColor", Sc_TextBox_GetTextColor); + ccAddExternalObjectFunction("TextBox::set_TextColor", Sc_TextBox_SetTextColor); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("TextBox::GetText^1", (void *)TextBox_GetText); + ccAddExternalFunctionForPlugin("TextBox::SetText^1", (void *)TextBox_SetText); + ccAddExternalFunctionForPlugin("TextBox::get_Font", (void *)TextBox_GetFont); + ccAddExternalFunctionForPlugin("TextBox::set_Font", (void *)TextBox_SetFont); + ccAddExternalFunctionForPlugin("TextBox::get_Text", (void *)TextBox_GetText_New); + ccAddExternalFunctionForPlugin("TextBox::set_Text", (void *)TextBox_SetText); + ccAddExternalFunctionForPlugin("TextBox::get_TextColor", (void *)TextBox_GetTextColor); + ccAddExternalFunctionForPlugin("TextBox::set_TextColor", (void *)TextBox_SetTextColor); } diff --git a/engines/ags/engine/ac/textbox.h b/engines/ags/engine/ac/textbox.h index 2f671e9988ec..6720f392a77a 100644 --- a/engines/ags/engine/ac/textbox.h +++ b/engines/ags/engine/ac/textbox.h @@ -27,12 +27,12 @@ using AGS::Common::GUITextBox; -const char* TextBox_GetText_New(GUITextBox *texbox); -void TextBox_GetText(GUITextBox *texbox, char *buffer); -void TextBox_SetText(GUITextBox *texbox, const char *newtex); -int TextBox_GetTextColor(GUITextBox *guit); -void TextBox_SetTextColor(GUITextBox *guit, int colr); -int TextBox_GetFont(GUITextBox *guit); -void TextBox_SetFont(GUITextBox *guit, int fontnum); +const char *TextBox_GetText_New(GUITextBox *texbox); +void TextBox_GetText(GUITextBox *texbox, char *buffer); +void TextBox_SetText(GUITextBox *texbox, const char *newtex); +int TextBox_GetTextColor(GUITextBox *guit); +void TextBox_SetTextColor(GUITextBox *guit, int colr); +int TextBox_GetFont(GUITextBox *guit); +void TextBox_SetFont(GUITextBox *guit, int fontnum); #endif diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index 8dc1915437cb..e94e7b3ed776 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -35,7 +35,7 @@ namespace { const auto MAXIMUM_FALL_BEHIND = 3; -auto tick_duration = std::chrono::microseconds(1000000LL/40); +auto tick_duration = std::chrono::microseconds(1000000LL / 40); auto framerate_maxed = false; auto last_tick_time = AGS_Clock::now(); @@ -43,86 +43,80 @@ auto next_frame_timestamp = AGS_Clock::now(); } -std::chrono::microseconds GetFrameDuration() -{ - if (framerate_maxed) { - return std::chrono::microseconds(0); - } - return tick_duration; +std::chrono::microseconds GetFrameDuration() { + if (framerate_maxed) { + return std::chrono::microseconds(0); + } + return tick_duration; } -void setTimerFps(int new_fps) -{ - tick_duration = std::chrono::microseconds(1000000LL/new_fps); - framerate_maxed = new_fps >= 1000; +void setTimerFps(int new_fps) { + tick_duration = std::chrono::microseconds(1000000LL / new_fps); + framerate_maxed = new_fps >= 1000; - last_tick_time = AGS_Clock::now(); - next_frame_timestamp = AGS_Clock::now(); + last_tick_time = AGS_Clock::now(); + next_frame_timestamp = AGS_Clock::now(); } -bool isTimerFpsMaxed() -{ - return framerate_maxed; +bool isTimerFpsMaxed() { + return framerate_maxed; } -void WaitForNextFrame() -{ - auto now = AGS_Clock::now(); - auto frameDuration = GetFrameDuration(); - - // early exit if we're trying to maximise framerate - if (frameDuration <= std::chrono::milliseconds::zero()) { - next_frame_timestamp = now; - return; - } - - // jump ahead if we're lagging - if (next_frame_timestamp < (now - MAXIMUM_FALL_BEHIND*frameDuration)) { - next_frame_timestamp = now; - } - - auto frame_time_remaining = next_frame_timestamp - now; - if (frame_time_remaining > std::chrono::milliseconds::zero()) { - std::this_thread::sleep_for(frame_time_remaining); - } - - next_frame_timestamp += frameDuration; +void WaitForNextFrame() { + auto now = AGS_Clock::now(); + auto frameDuration = GetFrameDuration(); + + // early exit if we're trying to maximise framerate + if (frameDuration <= std::chrono::milliseconds::zero()) { + next_frame_timestamp = now; + return; + } + + // jump ahead if we're lagging + if (next_frame_timestamp < (now - MAXIMUM_FALL_BEHIND * frameDuration)) { + next_frame_timestamp = now; + } + + auto frame_time_remaining = next_frame_timestamp - now; + if (frame_time_remaining > std::chrono::milliseconds::zero()) { + std::this_thread::sleep_for(frame_time_remaining); + } + + next_frame_timestamp += frameDuration; } -bool waitingForNextTick() -{ - auto now = AGS_Clock::now(); +bool waitingForNextTick() { + auto now = AGS_Clock::now(); - if (framerate_maxed) { - last_tick_time = now; - return false; - } + if (framerate_maxed) { + last_tick_time = now; + return false; + } - auto is_lagging = (now - last_tick_time) > (MAXIMUM_FALL_BEHIND*tick_duration); - if (is_lagging) { + auto is_lagging = (now - last_tick_time) > (MAXIMUM_FALL_BEHIND * tick_duration); + if (is_lagging) { #if AGS_PLATFORM_DEBUG && defined (__GNUC__) - auto missed_ticks = ((now - last_tick_time)/tick_duration); - printf("Lagging! Missed %lld ticks!\n", (long long)missed_ticks); - void *array[10]; - auto size = backtrace(array, 10); - backtrace_symbols_fd(array, size, STDOUT_FILENO); - printf("\n"); + auto missed_ticks = ((now - last_tick_time) / tick_duration); + printf("Lagging! Missed %lld ticks!\n", (long long)missed_ticks); + void *array[10]; + auto size = backtrace(array, 10); + backtrace_symbols_fd(array, size, STDOUT_FILENO); + printf("\n"); #endif - last_tick_time = now; - return false; - } + last_tick_time = now; + return false; + } - auto next_tick_time = last_tick_time + tick_duration; - if (next_tick_time <= now) { - last_tick_time = next_tick_time; - return false; - } + auto next_tick_time = last_tick_time + tick_duration; + if (next_tick_time <= now) { + last_tick_time = next_tick_time; + return false; + } - return true; + return true; } -void skipMissedTicks() -{ - last_tick_time = AGS_Clock::now(); - next_frame_timestamp = AGS_Clock::now(); +void skipMissedTicks() { + last_tick_time = AGS_Clock::now(); + next_frame_timestamp = AGS_Clock::now(); } diff --git a/engines/ags/engine/ac/timer.h b/engines/ags/engine/ac/timer.h index f6f1f0947bf7..66363c8d58a4 100644 --- a/engines/ags/engine/ac/timer.h +++ b/engines/ags/engine/ac/timer.h @@ -28,10 +28,10 @@ // use high resolution clock only if we know it is monotonic/steady. // refer to https://stackoverflow.com/a/38253266/84262 -using AGS_Clock = std::conditional< - std::chrono::high_resolution_clock::is_steady, - std::chrono::high_resolution_clock, std::chrono::steady_clock - >::type; +using AGS_Clock = std::conditional < + std::chrono::high_resolution_clock::is_steady, + std::chrono::high_resolution_clock, std::chrono::steady_clock + >::type; extern void WaitForNextFrame(); diff --git a/engines/ags/engine/ac/topbarsettings.h b/engines/ags/engine/ac/topbarsettings.h index 5a23efb1f837..4b8e1a660b38 100644 --- a/engines/ags/engine/ac/topbarsettings.h +++ b/engines/ags/engine/ac/topbarsettings.h @@ -24,17 +24,17 @@ #define AGS_ENGINE_AC_TOPBARSETTINGS_H struct TopBarSettings { - int wantIt; - int height; - int font; - char text[200]; + int wantIt; + int height; + int font; + char text[200]; - TopBarSettings() { - wantIt = 0; - height = 0; - font = 0; - text[0] = 0; - } + TopBarSettings() { + wantIt = 0; + height = 0; + font = 0; + text[0] = 0; + } }; #endif diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp index f7d49331842c..85e64f45abf8 100644 --- a/engines/ags/engine/ac/translation.cpp +++ b/engines/ags/engine/ac/translation.cpp @@ -48,141 +48,126 @@ TreeMap *transtree = nullptr; long lang_offs_start = 0; char transFileName[MAX_PATH] = "\0"; -void close_translation () { - if (transtree != nullptr) { - delete transtree; - transtree = nullptr; - } +void close_translation() { + if (transtree != nullptr) { + delete transtree; + transtree = nullptr; + } } bool parse_translation(Stream *language_file, String &parse_error); -bool init_translation (const String &lang, const String &fallback_lang, bool quit_on_error) { - - if (lang.IsEmpty()) - return false; - sprintf(transFileName, "%s.tra", lang.GetCStr()); - - Stream *language_file = find_open_asset(transFileName); - if (language_file == nullptr) - { - Debug::Printf(kDbgMsg_Error, "Cannot open translation: %s", transFileName); - return false; - } - // in case it's inside a library file, record the offset - lang_offs_start = language_file->GetPosition(); - - char transsig[16] = {0}; - language_file->Read(transsig, 15); - if (strcmp(transsig, "AGSTranslation") != 0) { - Debug::Printf(kDbgMsg_Error, "Translation signature mismatch: %s", transFileName); - delete language_file; - return false; - } - - if (transtree != nullptr) - { - close_translation(); - } - transtree = new TreeMap(); - - String parse_error; - bool result = parse_translation(language_file, parse_error); - delete language_file; - - if (!result) - { - close_translation(); - parse_error.Prepend(String::FromFormat("Failed to read translation file: %s:\n", transFileName)); - if (quit_on_error) - { - parse_error.PrependChar('!'); - quit(parse_error); - } - else - { - Debug::Printf(kDbgMsg_Error, parse_error); - if (!fallback_lang.IsEmpty()) - { - Debug::Printf("Fallback to translation: %s", fallback_lang.GetCStr()); - init_translation(fallback_lang, "", false); - } - return false; - } - } - Debug::Printf("Translation initialized: %s", transFileName); - return true; +bool init_translation(const String &lang, const String &fallback_lang, bool quit_on_error) { + + if (lang.IsEmpty()) + return false; + sprintf(transFileName, "%s.tra", lang.GetCStr()); + + Stream *language_file = find_open_asset(transFileName); + if (language_file == nullptr) { + Debug::Printf(kDbgMsg_Error, "Cannot open translation: %s", transFileName); + return false; + } + // in case it's inside a library file, record the offset + lang_offs_start = language_file->GetPosition(); + + char transsig[16] = {0}; + language_file->Read(transsig, 15); + if (strcmp(transsig, "AGSTranslation") != 0) { + Debug::Printf(kDbgMsg_Error, "Translation signature mismatch: %s", transFileName); + delete language_file; + return false; + } + + if (transtree != nullptr) { + close_translation(); + } + transtree = new TreeMap(); + + String parse_error; + bool result = parse_translation(language_file, parse_error); + delete language_file; + + if (!result) { + close_translation(); + parse_error.Prepend(String::FromFormat("Failed to read translation file: %s:\n", transFileName)); + if (quit_on_error) { + parse_error.PrependChar('!'); + quit(parse_error); + } else { + Debug::Printf(kDbgMsg_Error, parse_error); + if (!fallback_lang.IsEmpty()) { + Debug::Printf("Fallback to translation: %s", fallback_lang.GetCStr()); + init_translation(fallback_lang, "", false); + } + return false; + } + } + Debug::Printf("Translation initialized: %s", transFileName); + return true; } -bool parse_translation(Stream *language_file, String &parse_error) -{ - while (!language_file->EOS()) { - int blockType = language_file->ReadInt32(); - if (blockType == -1) - break; - // MACPORT FIX 9/6/5: remove warning - /* int blockSize = */ language_file->ReadInt32(); - - if (blockType == 1) { - char original[STD_BUFFER_SIZE], translation[STD_BUFFER_SIZE]; - while (1) { - read_string_decrypt (language_file, original, STD_BUFFER_SIZE); - read_string_decrypt (language_file, translation, STD_BUFFER_SIZE); - if ((strlen (original) < 1) && (strlen(translation) < 1)) - break; - if (language_file->EOS()) - { - parse_error = "Translation file is corrupt"; - return false; - } - transtree->addText (original, translation); - } - - } - else if (blockType == 2) { - int uidfrom; - char wasgamename[100]; - uidfrom = language_file->ReadInt32(); - read_string_decrypt (language_file, wasgamename, sizeof(wasgamename)); - if ((uidfrom != game.uniqueid) || (strcmp (wasgamename, game.gamename) != 0)) { - parse_error.Format("The translation file is not compatible with this game. The translation is designed for '%s'.", - wasgamename); - return false; - } - } - else if (blockType == 3) { - // game settings - int temp = language_file->ReadInt32(); - // normal font - if (temp >= 0) - SetNormalFont (temp); - temp = language_file->ReadInt32(); - // speech font - if (temp >= 0) - SetSpeechFont (temp); - temp = language_file->ReadInt32(); - // text direction - if (temp == 1) { - play.text_align = kHAlignLeft; - game.options[OPT_RIGHTLEFTWRITE] = 0; - } - else if (temp == 2) { - play.text_align = kHAlignRight; - game.options[OPT_RIGHTLEFTWRITE] = 1; - } - } - else - { - parse_error.Format("Unknown block type in translation file (%d).", blockType); - return false; - } - } - - if (transtree->text == nullptr) - { - parse_error = "The translation file was empty."; - return false; - } - - return true; +bool parse_translation(Stream *language_file, String &parse_error) { + while (!language_file->EOS()) { + int blockType = language_file->ReadInt32(); + if (blockType == -1) + break; + // MACPORT FIX 9/6/5: remove warning + /* int blockSize = */ language_file->ReadInt32(); + + if (blockType == 1) { + char original[STD_BUFFER_SIZE], translation[STD_BUFFER_SIZE]; + while (1) { + read_string_decrypt(language_file, original, STD_BUFFER_SIZE); + read_string_decrypt(language_file, translation, STD_BUFFER_SIZE); + if ((strlen(original) < 1) && (strlen(translation) < 1)) + break; + if (language_file->EOS()) { + parse_error = "Translation file is corrupt"; + return false; + } + transtree->addText(original, translation); + } + + } else if (blockType == 2) { + int uidfrom; + char wasgamename[100]; + uidfrom = language_file->ReadInt32(); + read_string_decrypt(language_file, wasgamename, sizeof(wasgamename)); + if ((uidfrom != game.uniqueid) || (strcmp(wasgamename, game.gamename) != 0)) { + parse_error.Format("The translation file is not compatible with this game. The translation is designed for '%s'.", + wasgamename); + return false; + } + } else if (blockType == 3) { + // game settings + int temp = language_file->ReadInt32(); + // normal font + if (temp >= 0) + SetNormalFont(temp); + temp = language_file->ReadInt32(); + // speech font + if (temp >= 0) + SetSpeechFont(temp); + temp = language_file->ReadInt32(); + // text direction + if (temp == 1) { + play.text_align = kHAlignLeft; + game.options[OPT_RIGHTLEFTWRITE] = 0; + } else if (temp == 2) { + play.text_align = kHAlignRight; + game.options[OPT_RIGHTLEFTWRITE] = 1; + } + } else { + parse_error.Format("Unknown block type in translation file (%d).", blockType); + return false; + } + } + + if (transtree->text == nullptr) { + parse_error = "The translation file was empty."; + return false; + } + + return true; } diff --git a/engines/ags/engine/ac/translation.h b/engines/ags/engine/ac/translation.h index a7692089c3bd..1ee20f9e377b 100644 --- a/engines/ags/engine/ac/translation.h +++ b/engines/ags/engine/ac/translation.h @@ -27,7 +27,7 @@ using AGS::Common::String; -void close_translation (); -bool init_translation (const String &lang, const String &fallback_lang, bool quit_on_error); +void close_translation(); +bool init_translation(const String &lang, const String &fallback_lang, bool quit_on_error); #endif diff --git a/engines/ags/engine/ac/tree_map.cpp b/engines/ags/engine/ac/tree_map.cpp index b4be592cc831..a25ab6dcc5f2 100644 --- a/engines/ags/engine/ac/tree_map.cpp +++ b/engines/ags/engine/ac/tree_map.cpp @@ -26,81 +26,78 @@ #include "ac/tree_map.h" TreeMap::TreeMap() { - left = nullptr; - right = nullptr; - text = nullptr; - translation = nullptr; + left = nullptr; + right = nullptr; + text = nullptr; + translation = nullptr; } -char* TreeMap::findValue (const char* key) { - if (text == nullptr) - return nullptr; +char *TreeMap::findValue(const char *key) { + if (text == nullptr) + return nullptr; - if (strcmp(key, text) == 0) - return translation; - //debug_script_warn("Compare: '%s' with '%s'", key, text); + if (strcmp(key, text) == 0) + return translation; + //debug_script_warn("Compare: '%s' with '%s'", key, text); - if (strcmp (key, text) < 0) { - if (left == nullptr) - return nullptr; - return left->findValue (key); - } - else { - if (right == nullptr) - return nullptr; - return right->findValue (key); - } + if (strcmp(key, text) < 0) { + if (left == nullptr) + return nullptr; + return left->findValue(key); + } else { + if (right == nullptr) + return nullptr; + return right->findValue(key); + } } -void TreeMap::addText (const char* ntx, char *trans) { - if ((ntx == nullptr) || (ntx[0] == 0) || - ((text != nullptr) && (strcmp(ntx, text) == 0))) - // don't add if it's an empty string or if it's already here - return; +void TreeMap::addText(const char *ntx, char *trans) { + if ((ntx == nullptr) || (ntx[0] == 0) || + ((text != nullptr) && (strcmp(ntx, text) == 0))) + // don't add if it's an empty string or if it's already here + return; - if (text == nullptr) { - text = (char*)malloc(strlen(ntx)+1); - translation = (char*)malloc(strlen(trans)+1); - if (translation == nullptr) - quit("load_translation: out of memory"); - strcpy(text, ntx); - strcpy(translation, trans); - } - else if (strcmp(ntx, text) < 0) { - // Earlier in alphabet, add to left - if (left == nullptr) - left = new TreeMap(); + if (text == nullptr) { + text = (char *)malloc(strlen(ntx) + 1); + translation = (char *)malloc(strlen(trans) + 1); + if (translation == nullptr) + quit("load_translation: out of memory"); + strcpy(text, ntx); + strcpy(translation, trans); + } else if (strcmp(ntx, text) < 0) { + // Earlier in alphabet, add to left + if (left == nullptr) + left = new TreeMap(); - left->addText (ntx, trans); - } - else if (strcmp(ntx, text) > 0) { - // Later in alphabet, add to right - if (right == nullptr) - right = new TreeMap(); + left->addText(ntx, trans); + } else if (strcmp(ntx, text) > 0) { + // Later in alphabet, add to right + if (right == nullptr) + right = new TreeMap(); - right->addText (ntx, trans); - } + right->addText(ntx, trans); + } } void TreeMap::clear() { - if (left) { - left->clear(); - delete left; - } - if (right) { - right->clear(); - delete right; - } - if (text) - free(text); - if (translation) - free(translation); - left = nullptr; - right = nullptr; - text = nullptr; - translation = nullptr; + if (left) { + left->clear(); + delete left; + } + if (right) { + right->clear(); + delete right; + } + if (text) + free(text); + if (translation) + free(translation); + left = nullptr; + right = nullptr; + text = nullptr; + translation = nullptr; } TreeMap::~TreeMap() { - clear(); + clear(); } diff --git a/engines/ags/engine/ac/tree_map.h b/engines/ags/engine/ac/tree_map.h index 6c181f8e2cfb..f00bb11f5a3b 100644 --- a/engines/ags/engine/ac/tree_map.h +++ b/engines/ags/engine/ac/tree_map.h @@ -26,15 +26,15 @@ // Binary tree structure for holding translations, allows fast // access struct TreeMap { - TreeMap *left, *right; - char *text; - char *translation; + TreeMap *left, *right; + char *text; + char *translation; - TreeMap(); - char* findValue (const char* key); - void addText (const char* ntx, char *trans); - void clear(); - ~TreeMap(); + TreeMap(); + char *findValue(const char *key); + void addText(const char *ntx, char *trans); + void clear(); + ~TreeMap(); }; #endif diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp index 2c65e247b74a..81605b5d0200 100644 --- a/engines/ags/engine/ac/viewframe.cpp +++ b/engines/ags/engine/ac/viewframe.cpp @@ -35,158 +35,139 @@ using AGS::Common::Bitmap; using AGS::Common::Graphics; extern GameSetupStruct game; -extern ViewStruct*views; +extern ViewStruct *views; extern SpriteCache spriteset; extern CCAudioClip ccDynamicAudioClip; int ViewFrame_GetFlipped(ScriptViewFrame *svf) { - if (views[svf->view].loops[svf->loop].frames[svf->frame].flags & VFLG_FLIPSPRITE) - return 1; - return 0; + if (views[svf->view].loops[svf->loop].frames[svf->frame].flags & VFLG_FLIPSPRITE) + return 1; + return 0; } int ViewFrame_GetGraphic(ScriptViewFrame *svf) { - return views[svf->view].loops[svf->loop].frames[svf->frame].pic; + return views[svf->view].loops[svf->loop].frames[svf->frame].pic; } void ViewFrame_SetGraphic(ScriptViewFrame *svf, int newPic) { - views[svf->view].loops[svf->loop].frames[svf->frame].pic = newPic; + views[svf->view].loops[svf->loop].frames[svf->frame].pic = newPic; } -ScriptAudioClip* ViewFrame_GetLinkedAudio(ScriptViewFrame *svf) -{ - int soundIndex = views[svf->view].loops[svf->loop].frames[svf->frame].sound; - if (soundIndex < 0) - return nullptr; +ScriptAudioClip *ViewFrame_GetLinkedAudio(ScriptViewFrame *svf) { + int soundIndex = views[svf->view].loops[svf->loop].frames[svf->frame].sound; + if (soundIndex < 0) + return nullptr; - return &game.audioClips[soundIndex]; + return &game.audioClips[soundIndex]; } -void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip* clip) -{ - int newSoundIndex = -1; - if (clip != nullptr) - newSoundIndex = clip->id; +void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip *clip) { + int newSoundIndex = -1; + if (clip != nullptr) + newSoundIndex = clip->id; - views[svf->view].loops[svf->loop].frames[svf->frame].sound = newSoundIndex; + views[svf->view].loops[svf->loop].frames[svf->frame].sound = newSoundIndex; } int ViewFrame_GetSound(ScriptViewFrame *svf) { - // convert audio clip to old-style sound number - return get_old_style_number_for_sound(views[svf->view].loops[svf->loop].frames[svf->frame].sound); + // convert audio clip to old-style sound number + return get_old_style_number_for_sound(views[svf->view].loops[svf->loop].frames[svf->frame].sound); } -void ViewFrame_SetSound(ScriptViewFrame *svf, int newSound) -{ - if (newSound < 1) - { - views[svf->view].loops[svf->loop].frames[svf->frame].sound = -1; - } - else - { - // convert sound number to audio clip - ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, newSound); - if (clip == nullptr) - quitprintf("!SetFrameSound: audio clip aSound%d not found", newSound); - - views[svf->view].loops[svf->loop].frames[svf->frame].sound = clip->id + (game.IsLegacyAudioSystem() ? 0x10000000 : 0); - } +void ViewFrame_SetSound(ScriptViewFrame *svf, int newSound) { + if (newSound < 1) { + views[svf->view].loops[svf->loop].frames[svf->frame].sound = -1; + } else { + // convert sound number to audio clip + ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(game, false, newSound); + if (clip == nullptr) + quitprintf("!SetFrameSound: audio clip aSound%d not found", newSound); + + views[svf->view].loops[svf->loop].frames[svf->frame].sound = clip->id + (game.IsLegacyAudioSystem() ? 0x10000000 : 0); + } } int ViewFrame_GetSpeed(ScriptViewFrame *svf) { - return views[svf->view].loops[svf->loop].frames[svf->frame].speed; + return views[svf->view].loops[svf->loop].frames[svf->frame].speed; } int ViewFrame_GetView(ScriptViewFrame *svf) { - return svf->view + 1; + return svf->view + 1; } int ViewFrame_GetLoop(ScriptViewFrame *svf) { - return svf->loop; + return svf->loop; } int ViewFrame_GetFrame(ScriptViewFrame *svf) { - return svf->frame; + return svf->frame; } //============================================================================= -void precache_view(int view) -{ - if (view < 0) - return; +void precache_view(int view) { + if (view < 0) + return; - for (int i = 0; i < views[view].numLoops; i++) { - for (int j = 0; j < views[view].loops[i].numFrames; j++) - spriteset.Precache(views[view].loops[i].frames[j].pic); - } + for (int i = 0; i < views[view].numLoops; i++) { + for (int j = 0; j < views[view].loops[i].numFrames; j++) + spriteset.Precache(views[view].loops[i].frames[j].pic); + } } // the specified frame has just appeared, see if we need // to play a sound or whatever -void CheckViewFrame (int view, int loop, int frame, int sound_volume) { - ScriptAudioChannel *channel = nullptr; - if (game.IsLegacyAudioSystem()) - { - if (views[view].loops[loop].frames[frame].sound > 0) - { - if (views[view].loops[loop].frames[frame].sound < 0x10000000) - { - ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, views[view].loops[loop].frames[frame].sound); - if (clip) - views[view].loops[loop].frames[frame].sound = clip->id + 0x10000000; - else - { - views[view].loops[loop].frames[frame].sound = 0; - return; - } - } - channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound - 0x10000000); - } - } - else - { - if (views[view].loops[loop].frames[frame].sound >= 0) { - // play this sound (eg. footstep) - channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound); - } - } - if (sound_volume != SCR_NO_VALUE && channel != nullptr) - { - AudioChannelsLock lock; - auto* ch = lock.GetChannel(channel->id); - if (ch) - ch->set_volume_percent(ch->get_volume() * sound_volume / 100); - } - +void CheckViewFrame(int view, int loop, int frame, int sound_volume) { + ScriptAudioChannel *channel = nullptr; + if (game.IsLegacyAudioSystem()) { + if (views[view].loops[loop].frames[frame].sound > 0) { + if (views[view].loops[loop].frames[frame].sound < 0x10000000) { + ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(game, false, views[view].loops[loop].frames[frame].sound); + if (clip) + views[view].loops[loop].frames[frame].sound = clip->id + 0x10000000; + else { + views[view].loops[loop].frames[frame].sound = 0; + return; + } + } + channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound - 0x10000000); + } + } else { + if (views[view].loops[loop].frames[frame].sound >= 0) { + // play this sound (eg. footstep) + channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound); + } + } + if (sound_volume != SCR_NO_VALUE && channel != nullptr) { + AudioChannelsLock lock; + auto *ch = lock.GetChannel(channel->id); + if (ch) + ch->set_volume_percent(ch->get_volume() * sound_volume / 100); + } + } // draws a view frame, flipped if appropriate -void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend) -{ - // NOTE: DrawViewFrame supports alpha blending only since OPT_SPRITEALPHA; - // this is why there's no sense in blending if it's not set (will do no good anyway). - if (alpha_blend && game.options[OPT_SPRITEALPHA] == kSpriteAlphaRender_Proper) - { - Bitmap *vf_bmp = spriteset[vframe->pic]; - Bitmap *src = vf_bmp; - if (vframe->flags & VFLG_FLIPSPRITE) - { - src = new Bitmap(vf_bmp->GetWidth(), vf_bmp->GetHeight(), vf_bmp->GetColorDepth()); - src->FlipBlt(vf_bmp, 0, 0, Common::kBitmap_HFlip); - } - draw_sprite_support_alpha(ds, true, x, y, src, (game.SpriteInfos[vframe->pic].Flags & SPF_ALPHACHANNEL) != 0); - if (src != vf_bmp) - delete src; - } - else - { - if (vframe->flags & VFLG_FLIPSPRITE) - ds->FlipBlt(spriteset[vframe->pic], x, y, Common::kBitmap_HFlip); - else - ds->Blit(spriteset[vframe->pic], x, y, Common::kBitmap_Transparency); - } +void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend) { + // NOTE: DrawViewFrame supports alpha blending only since OPT_SPRITEALPHA; + // this is why there's no sense in blending if it's not set (will do no good anyway). + if (alpha_blend && game.options[OPT_SPRITEALPHA] == kSpriteAlphaRender_Proper) { + Bitmap *vf_bmp = spriteset[vframe->pic]; + Bitmap *src = vf_bmp; + if (vframe->flags & VFLG_FLIPSPRITE) { + src = new Bitmap(vf_bmp->GetWidth(), vf_bmp->GetHeight(), vf_bmp->GetColorDepth()); + src->FlipBlt(vf_bmp, 0, 0, Common::kBitmap_HFlip); + } + draw_sprite_support_alpha(ds, true, x, y, src, (game.SpriteInfos[vframe->pic].Flags & SPF_ALPHACHANNEL) != 0); + if (src != vf_bmp) + delete src; + } else { + if (vframe->flags & VFLG_FLIPSPRITE) + ds->FlipBlt(spriteset[vframe->pic], x, y, Common::kBitmap_HFlip); + else + ds->Blit(spriteset[vframe->pic], x, y, Common::kBitmap_Transparency); + } } //============================================================================= @@ -200,96 +181,84 @@ void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha #include "script/script_runtime.h" // int (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetFlipped(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFlipped); +RuntimeScriptValue Sc_ViewFrame_GetFlipped(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFlipped); } // int (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFrame); +RuntimeScriptValue Sc_ViewFrame_GetFrame(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFrame); } // int (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetGraphic); +RuntimeScriptValue Sc_ViewFrame_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetGraphic); } // void (ScriptViewFrame *svf, int newPic) -RuntimeScriptValue Sc_ViewFrame_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetGraphic); +RuntimeScriptValue Sc_ViewFrame_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetGraphic); } // ScriptAudioClip* (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJ(ScriptViewFrame, ScriptAudioClip, ccDynamicAudioClip, ViewFrame_GetLinkedAudio); +RuntimeScriptValue Sc_ViewFrame_GetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJ(ScriptViewFrame, ScriptAudioClip, ccDynamicAudioClip, ViewFrame_GetLinkedAudio); } // void (ScriptViewFrame *svf, ScriptAudioClip* clip) -RuntimeScriptValue Sc_ViewFrame_SetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(ScriptViewFrame, ViewFrame_SetLinkedAudio, ScriptAudioClip); +RuntimeScriptValue Sc_ViewFrame_SetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(ScriptViewFrame, ViewFrame_SetLinkedAudio, ScriptAudioClip); } // int (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetLoop); +RuntimeScriptValue Sc_ViewFrame_GetLoop(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetLoop); } // int (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSound); +RuntimeScriptValue Sc_ViewFrame_GetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSound); } // void (ScriptViewFrame *svf, int newSound) -RuntimeScriptValue Sc_ViewFrame_SetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetSound); +RuntimeScriptValue Sc_ViewFrame_SetSound(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptViewFrame, ViewFrame_SetSound); } // int (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSpeed); +RuntimeScriptValue Sc_ViewFrame_GetSpeed(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetSpeed); } // int (ScriptViewFrame *svf) -RuntimeScriptValue Sc_ViewFrame_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetView); +RuntimeScriptValue Sc_ViewFrame_GetView(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetView); } -void RegisterViewFrameAPI() -{ - ccAddExternalObjectFunction("ViewFrame::get_Flipped", Sc_ViewFrame_GetFlipped); - ccAddExternalObjectFunction("ViewFrame::get_Frame", Sc_ViewFrame_GetFrame); - ccAddExternalObjectFunction("ViewFrame::get_Graphic", Sc_ViewFrame_GetGraphic); - ccAddExternalObjectFunction("ViewFrame::set_Graphic", Sc_ViewFrame_SetGraphic); - ccAddExternalObjectFunction("ViewFrame::get_LinkedAudio", Sc_ViewFrame_GetLinkedAudio); - ccAddExternalObjectFunction("ViewFrame::set_LinkedAudio", Sc_ViewFrame_SetLinkedAudio); - ccAddExternalObjectFunction("ViewFrame::get_Loop", Sc_ViewFrame_GetLoop); - ccAddExternalObjectFunction("ViewFrame::get_Sound", Sc_ViewFrame_GetSound); - ccAddExternalObjectFunction("ViewFrame::set_Sound", Sc_ViewFrame_SetSound); - ccAddExternalObjectFunction("ViewFrame::get_Speed", Sc_ViewFrame_GetSpeed); - ccAddExternalObjectFunction("ViewFrame::get_View", Sc_ViewFrame_GetView); - - /* ----------------------- Registering unsafe exports for plugins -----------------------*/ - - ccAddExternalFunctionForPlugin("ViewFrame::get_Flipped", (void*)ViewFrame_GetFlipped); - ccAddExternalFunctionForPlugin("ViewFrame::get_Frame", (void*)ViewFrame_GetFrame); - ccAddExternalFunctionForPlugin("ViewFrame::get_Graphic", (void*)ViewFrame_GetGraphic); - ccAddExternalFunctionForPlugin("ViewFrame::set_Graphic", (void*)ViewFrame_SetGraphic); - ccAddExternalFunctionForPlugin("ViewFrame::get_LinkedAudio", (void*)ViewFrame_GetLinkedAudio); - ccAddExternalFunctionForPlugin("ViewFrame::set_LinkedAudio", (void*)ViewFrame_SetLinkedAudio); - ccAddExternalFunctionForPlugin("ViewFrame::get_Loop", (void*)ViewFrame_GetLoop); - ccAddExternalFunctionForPlugin("ViewFrame::get_Sound", (void*)ViewFrame_GetSound); - ccAddExternalFunctionForPlugin("ViewFrame::set_Sound", (void*)ViewFrame_SetSound); - ccAddExternalFunctionForPlugin("ViewFrame::get_Speed", (void*)ViewFrame_GetSpeed); - ccAddExternalFunctionForPlugin("ViewFrame::get_View", (void*)ViewFrame_GetView); +void RegisterViewFrameAPI() { + ccAddExternalObjectFunction("ViewFrame::get_Flipped", Sc_ViewFrame_GetFlipped); + ccAddExternalObjectFunction("ViewFrame::get_Frame", Sc_ViewFrame_GetFrame); + ccAddExternalObjectFunction("ViewFrame::get_Graphic", Sc_ViewFrame_GetGraphic); + ccAddExternalObjectFunction("ViewFrame::set_Graphic", Sc_ViewFrame_SetGraphic); + ccAddExternalObjectFunction("ViewFrame::get_LinkedAudio", Sc_ViewFrame_GetLinkedAudio); + ccAddExternalObjectFunction("ViewFrame::set_LinkedAudio", Sc_ViewFrame_SetLinkedAudio); + ccAddExternalObjectFunction("ViewFrame::get_Loop", Sc_ViewFrame_GetLoop); + ccAddExternalObjectFunction("ViewFrame::get_Sound", Sc_ViewFrame_GetSound); + ccAddExternalObjectFunction("ViewFrame::set_Sound", Sc_ViewFrame_SetSound); + ccAddExternalObjectFunction("ViewFrame::get_Speed", Sc_ViewFrame_GetSpeed); + ccAddExternalObjectFunction("ViewFrame::get_View", Sc_ViewFrame_GetView); + + /* ----------------------- Registering unsafe exports for plugins -----------------------*/ + + ccAddExternalFunctionForPlugin("ViewFrame::get_Flipped", (void *)ViewFrame_GetFlipped); + ccAddExternalFunctionForPlugin("ViewFrame::get_Frame", (void *)ViewFrame_GetFrame); + ccAddExternalFunctionForPlugin("ViewFrame::get_Graphic", (void *)ViewFrame_GetGraphic); + ccAddExternalFunctionForPlugin("ViewFrame::set_Graphic", (void *)ViewFrame_SetGraphic); + ccAddExternalFunctionForPlugin("ViewFrame::get_LinkedAudio", (void *)ViewFrame_GetLinkedAudio); + ccAddExternalFunctionForPlugin("ViewFrame::set_LinkedAudio", (void *)ViewFrame_SetLinkedAudio); + ccAddExternalFunctionForPlugin("ViewFrame::get_Loop", (void *)ViewFrame_GetLoop); + ccAddExternalFunctionForPlugin("ViewFrame::get_Sound", (void *)ViewFrame_GetSound); + ccAddExternalFunctionForPlugin("ViewFrame::set_Sound", (void *)ViewFrame_SetSound); + ccAddExternalFunctionForPlugin("ViewFrame::get_Speed", (void *)ViewFrame_GetSpeed); + ccAddExternalFunctionForPlugin("ViewFrame::get_View", (void *)ViewFrame_GetView); } diff --git a/engines/ags/engine/ac/viewframe.h b/engines/ags/engine/ac/viewframe.h index 6b5e3b838897..171170ab6c62 100644 --- a/engines/ags/engine/ac/viewframe.h +++ b/engines/ags/engine/ac/viewframe.h @@ -29,14 +29,18 @@ #include "ac/dynobj/scriptviewframe.h" #include "gfx/bitmap.h" -namespace AGS { namespace Common { class Graphics; } } +namespace AGS { +namespace Common { +class Graphics; +} +} using namespace AGS; // FIXME later int ViewFrame_GetFlipped(ScriptViewFrame *svf); int ViewFrame_GetGraphic(ScriptViewFrame *svf); void ViewFrame_SetGraphic(ScriptViewFrame *svf, int newPic); -ScriptAudioClip* ViewFrame_GetLinkedAudio(ScriptViewFrame *svf); -void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip* clip); +ScriptAudioClip *ViewFrame_GetLinkedAudio(ScriptViewFrame *svf); +void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip *clip); int ViewFrame_GetSound(ScriptViewFrame *svf); void ViewFrame_SetSound(ScriptViewFrame *svf, int newSound); int ViewFrame_GetSpeed(ScriptViewFrame *svf); @@ -45,7 +49,7 @@ int ViewFrame_GetLoop(ScriptViewFrame *svf); int ViewFrame_GetFrame(ScriptViewFrame *svf); void precache_view(int view); -void CheckViewFrame (int view, int loop, int frame, int sound_volume=SCR_NO_VALUE); +void CheckViewFrame(int view, int loop, int frame, int sound_volume = SCR_NO_VALUE); // draws a view frame, flipped if appropriate void DrawViewFrame(Common::Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend = false); diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp index e144ed440c29..ae83413e887e 100644 --- a/engines/ags/engine/ac/viewport_script.cpp +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -43,177 +43,185 @@ using namespace AGS::Common; // //============================================================================= -ScriptCamera* Camera_Create() -{ - auto cam = play.CreateRoomCamera(); - if (!cam) - return NULL; - return play.RegisterRoomCamera(cam->GetID()); +ScriptCamera *Camera_Create() { + auto cam = play.CreateRoomCamera(); + if (!cam) + return NULL; + return play.RegisterRoomCamera(cam->GetID()); +} + +void Camera_Delete(ScriptCamera *scam) { + play.DeleteRoomCamera(scam->GetID()); +} + +int Camera_GetX(ScriptCamera *scam) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.X: trying to use deleted camera"); + return 0; + } + int x = play.GetRoomCamera(scam->GetID())->GetRect().Left; + return game_to_data_coord(x); +} + +void Camera_SetX(ScriptCamera *scam, int x) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.X: trying to use deleted camera"); + return; + } + x = data_to_game_coord(x); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->LockAt(x, cam->GetRect().Top); +} + +int Camera_GetY(ScriptCamera *scam) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.Y: trying to use deleted camera"); + return 0; + } + int y = play.GetRoomCamera(scam->GetID())->GetRect().Top; + return game_to_data_coord(y); } -void Camera_Delete(ScriptCamera *scam) -{ - play.DeleteRoomCamera(scam->GetID()); +void Camera_SetY(ScriptCamera *scam, int y) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.Y: trying to use deleted camera"); + return; + } + y = data_to_game_coord(y); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->LockAt(cam->GetRect().Left, y); } -int Camera_GetX(ScriptCamera *scam) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.X: trying to use deleted camera"); return 0; } - int x = play.GetRoomCamera(scam->GetID())->GetRect().Left; - return game_to_data_coord(x); +int Camera_GetWidth(ScriptCamera *scam) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.Width: trying to use deleted camera"); + return 0; + } + int width = play.GetRoomCamera(scam->GetID())->GetRect().GetWidth(); + return game_to_data_coord(width); } -void Camera_SetX(ScriptCamera *scam, int x) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.X: trying to use deleted camera"); return; } - x = data_to_game_coord(x); - auto cam = play.GetRoomCamera(scam->GetID()); - cam->LockAt(x, cam->GetRect().Top); +void Camera_SetWidth(ScriptCamera *scam, int width) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.Width: trying to use deleted camera"); + return; + } + width = data_to_game_coord(width); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->SetSize(Size(width, cam->GetRect().GetHeight())); } -int Camera_GetY(ScriptCamera *scam) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.Y: trying to use deleted camera"); return 0; } - int y = play.GetRoomCamera(scam->GetID())->GetRect().Top; - return game_to_data_coord(y); +int Camera_GetHeight(ScriptCamera *scam) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.Height: trying to use deleted camera"); + return 0; + } + int height = play.GetRoomCamera(scam->GetID())->GetRect().GetHeight(); + return game_to_data_coord(height); } -void Camera_SetY(ScriptCamera *scam, int y) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.Y: trying to use deleted camera"); return; } - y = data_to_game_coord(y); - auto cam = play.GetRoomCamera(scam->GetID()); - cam->LockAt(cam->GetRect().Left, y); +void Camera_SetHeight(ScriptCamera *scam, int height) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.Height: trying to use deleted camera"); + return; + } + height = data_to_game_coord(height); + auto cam = play.GetRoomCamera(scam->GetID()); + cam->SetSize(Size(cam->GetRect().GetWidth(), height)); } -int Camera_GetWidth(ScriptCamera *scam) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.Width: trying to use deleted camera"); return 0; } - int width = play.GetRoomCamera(scam->GetID())->GetRect().GetWidth(); - return game_to_data_coord(width); +bool Camera_GetAutoTracking(ScriptCamera *scam) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.AutoTracking: trying to use deleted camera"); + return false; + } + return !play.GetRoomCamera(scam->GetID())->IsLocked(); } -void Camera_SetWidth(ScriptCamera *scam, int width) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.Width: trying to use deleted camera"); return; } - width = data_to_game_coord(width); - auto cam = play.GetRoomCamera(scam->GetID()); - cam->SetSize(Size(width, cam->GetRect().GetHeight())); +void Camera_SetAutoTracking(ScriptCamera *scam, bool on) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.AutoTracking: trying to use deleted camera"); + return; + } + auto cam = play.GetRoomCamera(scam->GetID()); + if (on) + cam->Release(); + else + cam->Lock(); } -int Camera_GetHeight(ScriptCamera *scam) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.Height: trying to use deleted camera"); return 0; } - int height = play.GetRoomCamera(scam->GetID())->GetRect().GetHeight(); - return game_to_data_coord(height); +void Camera_SetAt(ScriptCamera *scam, int x, int y) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.SetAt: trying to use deleted camera"); + return; + } + data_to_game_coords(&x, &y); + play.GetRoomCamera(scam->GetID())->LockAt(x, y); } -void Camera_SetHeight(ScriptCamera *scam, int height) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.Height: trying to use deleted camera"); return; } - height = data_to_game_coord(height); - auto cam = play.GetRoomCamera(scam->GetID()); - cam->SetSize(Size(cam->GetRect().GetWidth(), height)); +void Camera_SetSize(ScriptCamera *scam, int width, int height) { + if (scam->GetID() < 0) { + debug_script_warn("Camera.SetSize: trying to use deleted camera"); + return; + } + data_to_game_coords(&width, &height); + play.GetRoomCamera(scam->GetID())->SetSize(Size(width, height)); } -bool Camera_GetAutoTracking(ScriptCamera *scam) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.AutoTracking: trying to use deleted camera"); return false; } - return !play.GetRoomCamera(scam->GetID())->IsLocked(); +RuntimeScriptValue Sc_Camera_Create(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO(ScriptCamera, Camera_Create); } -void Camera_SetAutoTracking(ScriptCamera *scam, bool on) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.AutoTracking: trying to use deleted camera"); return; } - auto cam = play.GetRoomCamera(scam->GetID()); - if (on) - cam->Release(); - else - cam->Lock(); +RuntimeScriptValue Sc_Camera_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptCamera, Camera_Delete); } -void Camera_SetAt(ScriptCamera *scam, int x, int y) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.SetAt: trying to use deleted camera"); return; } - data_to_game_coords(&x, &y); - play.GetRoomCamera(scam->GetID())->LockAt(x, y); +RuntimeScriptValue Sc_Camera_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptCamera, Camera_GetX); } -void Camera_SetSize(ScriptCamera *scam, int width, int height) -{ - if (scam->GetID() < 0) { debug_script_warn("Camera.SetSize: trying to use deleted camera"); return; } - data_to_game_coords(&width, &height); - play.GetRoomCamera(scam->GetID())->SetSize(Size(width, height)); +RuntimeScriptValue Sc_Camera_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetX); } -RuntimeScriptValue Sc_Camera_Create(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO(ScriptCamera, Camera_Create); +RuntimeScriptValue Sc_Camera_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptCamera, Camera_GetY); } -RuntimeScriptValue Sc_Camera_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptCamera, Camera_Delete); +RuntimeScriptValue Sc_Camera_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetY); } -RuntimeScriptValue Sc_Camera_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptCamera, Camera_GetX); +RuntimeScriptValue Sc_Camera_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptCamera, Camera_GetWidth); } -RuntimeScriptValue Sc_Camera_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetX); +RuntimeScriptValue Sc_Camera_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetWidth); } -RuntimeScriptValue Sc_Camera_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptCamera, Camera_GetY); +RuntimeScriptValue Sc_Camera_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptCamera, Camera_GetHeight); } -RuntimeScriptValue Sc_Camera_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetY); +RuntimeScriptValue Sc_Camera_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetHeight); } -RuntimeScriptValue Sc_Camera_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptCamera, Camera_GetWidth); +RuntimeScriptValue Sc_Camera_GetAutoTracking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(ScriptCamera, Camera_GetAutoTracking); } -RuntimeScriptValue Sc_Camera_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetWidth); +RuntimeScriptValue Sc_Camera_SetAutoTracking(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PBOOL(ScriptCamera, Camera_SetAutoTracking); } -RuntimeScriptValue Sc_Camera_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptCamera, Camera_GetHeight); +RuntimeScriptValue Sc_Camera_SetAt(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptCamera, Camera_SetAt); } -RuntimeScriptValue Sc_Camera_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptCamera, Camera_SetHeight); -} - -RuntimeScriptValue Sc_Camera_GetAutoTracking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(ScriptCamera, Camera_GetAutoTracking); -} - -RuntimeScriptValue Sc_Camera_SetAutoTracking(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PBOOL(ScriptCamera, Camera_SetAutoTracking); -} - -RuntimeScriptValue Sc_Camera_SetAt(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptCamera, Camera_SetAt); -} - -RuntimeScriptValue Sc_Camera_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT2(ScriptCamera, Camera_SetSize); +RuntimeScriptValue Sc_Camera_SetSize(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT2(ScriptCamera, Camera_SetSize); } @@ -223,315 +231,325 @@ RuntimeScriptValue Sc_Camera_SetSize(void *self, const RuntimeScriptValue *param // //============================================================================= -ScriptViewport* Viewport_Create() -{ - auto view = play.CreateRoomViewport(); - if (!view) - return NULL; - return play.RegisterRoomViewport(view->GetID()); -} - -void Viewport_Delete(ScriptViewport *scv) -{ - play.DeleteRoomViewport(scv->GetID()); -} - -int Viewport_GetX(ScriptViewport *scv) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.X: trying to use deleted viewport"); return 0; } - int x = play.GetRoomViewport(scv->GetID())->GetRect().Left; - return game_to_data_coord(x); -} - -void Viewport_SetX(ScriptViewport *scv, int x) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.X: trying to use deleted viewport"); return; } - x = data_to_game_coord(x); - auto view = play.GetRoomViewport(scv->GetID()); - view->SetAt(x, view->GetRect().Top); -} - -int Viewport_GetY(ScriptViewport *scv) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Y: trying to use deleted viewport"); return 0; } - int y = play.GetRoomViewport(scv->GetID())->GetRect().Top; - return game_to_data_coord(y); -} - -void Viewport_SetY(ScriptViewport *scv, int y) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Y: trying to use deleted viewport"); return; } - y = data_to_game_coord(y); - auto view = play.GetRoomViewport(scv->GetID()); - view->SetAt(view->GetRect().Left, y); -} - -int Viewport_GetWidth(ScriptViewport *scv) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Width: trying to use deleted viewport"); return 0; } - int width = play.GetRoomViewport(scv->GetID())->GetRect().GetWidth(); - return game_to_data_coord(width); -} - -void Viewport_SetWidth(ScriptViewport *scv, int width) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Width: trying to use deleted viewport"); return; } - width = data_to_game_coord(width); - auto view = play.GetRoomViewport(scv->GetID()); - view->SetSize(Size(width, view->GetRect().GetHeight())); -} - -int Viewport_GetHeight(ScriptViewport *scv) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Height: trying to use deleted viewport"); return 0; } - int height = play.GetRoomViewport(scv->GetID())->GetRect().GetHeight(); - return game_to_data_coord(height); -} - -void Viewport_SetHeight(ScriptViewport *scv, int height) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Height: trying to use deleted viewport"); return; } - height = data_to_game_coord(height); - auto view = play.GetRoomViewport(scv->GetID()); - view->SetSize(Size(view->GetRect().GetWidth(), height)); -} - -ScriptCamera* Viewport_GetCamera(ScriptViewport *scv) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Camera: trying to use deleted viewport"); return nullptr; } - auto view = play.GetRoomViewport(scv->GetID()); - auto cam = view->GetCamera(); - if (!cam) - return nullptr; - return play.GetScriptCamera(cam->GetID()); -} - -void Viewport_SetCamera(ScriptViewport *scv, ScriptCamera *scam) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Camera: trying to use deleted viewport"); return; } - if (scam != nullptr && scam->GetID() < 0) { debug_script_warn("Viewport.Camera: trying to link deleted camera"); return; } - auto view = play.GetRoomViewport(scv->GetID()); - // unlink previous camera - auto cam = view->GetCamera(); - if (cam) - cam->UnlinkFromViewport(view->GetID()); - // link new one - if (scam != nullptr) - { - cam = play.GetRoomCamera(scam->GetID()); - view->LinkCamera(cam); - cam->LinkToViewport(view); - } - else - { - view->LinkCamera(nullptr); - } -} - -bool Viewport_GetVisible(ScriptViewport *scv) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Visible: trying to use deleted viewport"); return false; } - return play.GetRoomViewport(scv->GetID())->IsVisible(); -} - -void Viewport_SetVisible(ScriptViewport *scv, bool on) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.Visible: trying to use deleted viewport"); return; } - play.GetRoomViewport(scv->GetID())->SetVisible(on); +ScriptViewport *Viewport_Create() { + auto view = play.CreateRoomViewport(); + if (!view) + return NULL; + return play.RegisterRoomViewport(view->GetID()); +} + +void Viewport_Delete(ScriptViewport *scv) { + play.DeleteRoomViewport(scv->GetID()); +} + +int Viewport_GetX(ScriptViewport *scv) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.X: trying to use deleted viewport"); + return 0; + } + int x = play.GetRoomViewport(scv->GetID())->GetRect().Left; + return game_to_data_coord(x); +} + +void Viewport_SetX(ScriptViewport *scv, int x) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.X: trying to use deleted viewport"); + return; + } + x = data_to_game_coord(x); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetAt(x, view->GetRect().Top); +} + +int Viewport_GetY(ScriptViewport *scv) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Y: trying to use deleted viewport"); + return 0; + } + int y = play.GetRoomViewport(scv->GetID())->GetRect().Top; + return game_to_data_coord(y); +} + +void Viewport_SetY(ScriptViewport *scv, int y) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Y: trying to use deleted viewport"); + return; + } + y = data_to_game_coord(y); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetAt(view->GetRect().Left, y); +} + +int Viewport_GetWidth(ScriptViewport *scv) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Width: trying to use deleted viewport"); + return 0; + } + int width = play.GetRoomViewport(scv->GetID())->GetRect().GetWidth(); + return game_to_data_coord(width); +} + +void Viewport_SetWidth(ScriptViewport *scv, int width) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Width: trying to use deleted viewport"); + return; + } + width = data_to_game_coord(width); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetSize(Size(width, view->GetRect().GetHeight())); +} + +int Viewport_GetHeight(ScriptViewport *scv) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Height: trying to use deleted viewport"); + return 0; + } + int height = play.GetRoomViewport(scv->GetID())->GetRect().GetHeight(); + return game_to_data_coord(height); +} + +void Viewport_SetHeight(ScriptViewport *scv, int height) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Height: trying to use deleted viewport"); + return; + } + height = data_to_game_coord(height); + auto view = play.GetRoomViewport(scv->GetID()); + view->SetSize(Size(view->GetRect().GetWidth(), height)); +} + +ScriptCamera *Viewport_GetCamera(ScriptViewport *scv) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Camera: trying to use deleted viewport"); + return nullptr; + } + auto view = play.GetRoomViewport(scv->GetID()); + auto cam = view->GetCamera(); + if (!cam) + return nullptr; + return play.GetScriptCamera(cam->GetID()); +} + +void Viewport_SetCamera(ScriptViewport *scv, ScriptCamera *scam) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Camera: trying to use deleted viewport"); + return; + } + if (scam != nullptr && scam->GetID() < 0) { + debug_script_warn("Viewport.Camera: trying to link deleted camera"); + return; + } + auto view = play.GetRoomViewport(scv->GetID()); + // unlink previous camera + auto cam = view->GetCamera(); + if (cam) + cam->UnlinkFromViewport(view->GetID()); + // link new one + if (scam != nullptr) { + cam = play.GetRoomCamera(scam->GetID()); + view->LinkCamera(cam); + cam->LinkToViewport(view); + } else { + view->LinkCamera(nullptr); + } +} + +bool Viewport_GetVisible(ScriptViewport *scv) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Visible: trying to use deleted viewport"); + return false; + } + return play.GetRoomViewport(scv->GetID())->IsVisible(); +} + +void Viewport_SetVisible(ScriptViewport *scv, bool on) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.Visible: trying to use deleted viewport"); + return; + } + play.GetRoomViewport(scv->GetID())->SetVisible(on); } -int Viewport_GetZOrder(ScriptViewport *scv) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.ZOrder: trying to use deleted viewport"); return 0; } - return play.GetRoomViewport(scv->GetID())->GetZOrder(); +int Viewport_GetZOrder(ScriptViewport *scv) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.ZOrder: trying to use deleted viewport"); + return 0; + } + return play.GetRoomViewport(scv->GetID())->GetZOrder(); } -void Viewport_SetZOrder(ScriptViewport *scv, int zorder) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.ZOrder: trying to use deleted viewport"); return; } - play.GetRoomViewport(scv->GetID())->SetZOrder(zorder); - play.InvalidateViewportZOrder(); +void Viewport_SetZOrder(ScriptViewport *scv, int zorder) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.ZOrder: trying to use deleted viewport"); + return; + } + play.GetRoomViewport(scv->GetID())->SetZOrder(zorder); + play.InvalidateViewportZOrder(); } -ScriptViewport* Viewport_GetAtScreenXY(int x, int y) -{ - data_to_game_coords(&x, &y); - PViewport view = play.GetRoomViewportAt(x, y); - if (!view) - return nullptr; - return play.GetScriptViewport(view->GetID()); +ScriptViewport *Viewport_GetAtScreenXY(int x, int y) { + data_to_game_coords(&x, &y); + PViewport view = play.GetRoomViewportAt(x, y); + if (!view) + return nullptr; + return play.GetScriptViewport(view->GetID()); } -void Viewport_SetPosition(ScriptViewport *scv, int x, int y, int width, int height) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.SetPosition: trying to use deleted viewport"); return; } - data_to_game_coords(&x, &y); - data_to_game_coords(&width, &height); - play.GetRoomViewport(scv->GetID())->SetRect(RectWH(x, y, width, height)); +void Viewport_SetPosition(ScriptViewport *scv, int x, int y, int width, int height) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.SetPosition: trying to use deleted viewport"); + return; + } + data_to_game_coords(&x, &y); + data_to_game_coords(&width, &height); + play.GetRoomViewport(scv->GetID())->SetRect(RectWH(x, y, width, height)); } -ScriptUserObject *Viewport_ScreenToRoomPoint(ScriptViewport *scv, int scrx, int scry, bool clipViewport) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.ScreenToRoomPoint: trying to use deleted viewport"); return nullptr; } - data_to_game_coords(&scrx, &scry); +ScriptUserObject *Viewport_ScreenToRoomPoint(ScriptViewport *scv, int scrx, int scry, bool clipViewport) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.ScreenToRoomPoint: trying to use deleted viewport"); + return nullptr; + } + data_to_game_coords(&scrx, &scry); - VpPoint vpt = play.GetRoomViewport(scv->GetID())->ScreenToRoom(scrx, scry, clipViewport); - if (vpt.second < 0) - return nullptr; + VpPoint vpt = play.GetRoomViewport(scv->GetID())->ScreenToRoom(scrx, scry, clipViewport); + if (vpt.second < 0) + return nullptr; - game_to_data_coords(vpt.first.X, vpt.first.Y); - return ScriptStructHelpers::CreatePoint(vpt.first.X, vpt.first.Y); + game_to_data_coords(vpt.first.X, vpt.first.Y); + return ScriptStructHelpers::CreatePoint(vpt.first.X, vpt.first.Y); } -ScriptUserObject *Viewport_RoomToScreenPoint(ScriptViewport *scv, int roomx, int roomy, bool clipViewport) -{ - if (scv->GetID() < 0) { debug_script_warn("Viewport.RoomToScreenPoint: trying to use deleted viewport"); return nullptr; } - data_to_game_coords(&roomx, &roomy); - Point pt = play.RoomToScreen(roomx, roomy); - if (clipViewport && !play.GetRoomViewport(scv->GetID())->GetRect().IsInside(pt.X, pt.Y)) - return nullptr; +ScriptUserObject *Viewport_RoomToScreenPoint(ScriptViewport *scv, int roomx, int roomy, bool clipViewport) { + if (scv->GetID() < 0) { + debug_script_warn("Viewport.RoomToScreenPoint: trying to use deleted viewport"); + return nullptr; + } + data_to_game_coords(&roomx, &roomy); + Point pt = play.RoomToScreen(roomx, roomy); + if (clipViewport && !play.GetRoomViewport(scv->GetID())->GetRect().IsInside(pt.X, pt.Y)) + return nullptr; - game_to_data_coords(pt.X, pt.Y); - return ScriptStructHelpers::CreatePoint(pt.X, pt.Y); + game_to_data_coords(pt.X, pt.Y); + return ScriptStructHelpers::CreatePoint(pt.X, pt.Y); } -RuntimeScriptValue Sc_Viewport_Create(const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO(ScriptViewport, Viewport_Create); +RuntimeScriptValue Sc_Viewport_Create(const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO(ScriptViewport, Viewport_Create); } -RuntimeScriptValue Sc_Viewport_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID(ScriptViewport, Viewport_Delete); +RuntimeScriptValue Sc_Viewport_Delete(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID(ScriptViewport, Viewport_Delete); } -RuntimeScriptValue Sc_Viewport_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewport, Viewport_GetX); +RuntimeScriptValue Sc_Viewport_GetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewport, Viewport_GetX); } -RuntimeScriptValue Sc_Viewport_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetX); +RuntimeScriptValue Sc_Viewport_SetX(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetX); } -RuntimeScriptValue Sc_Viewport_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewport, Viewport_GetY); +RuntimeScriptValue Sc_Viewport_GetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewport, Viewport_GetY); } -RuntimeScriptValue Sc_Viewport_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetY); +RuntimeScriptValue Sc_Viewport_SetY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetY); } -RuntimeScriptValue Sc_Viewport_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewport, Viewport_GetWidth); +RuntimeScriptValue Sc_Viewport_GetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewport, Viewport_GetWidth); } -RuntimeScriptValue Sc_Viewport_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetWidth); +RuntimeScriptValue Sc_Viewport_SetWidth(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetWidth); } -RuntimeScriptValue Sc_Viewport_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewport, Viewport_GetHeight); +RuntimeScriptValue Sc_Viewport_GetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewport, Viewport_GetHeight); } -RuntimeScriptValue Sc_Viewport_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetHeight); +RuntimeScriptValue Sc_Viewport_SetHeight(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetHeight); } -RuntimeScriptValue Sc_Viewport_GetCamera(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJAUTO(ScriptViewport, ScriptCamera, Viewport_GetCamera); +RuntimeScriptValue Sc_Viewport_GetCamera(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJAUTO(ScriptViewport, ScriptCamera, Viewport_GetCamera); } -RuntimeScriptValue Sc_Viewport_SetCamera(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_POBJ(ScriptViewport, Viewport_SetCamera, ScriptCamera); +RuntimeScriptValue Sc_Viewport_SetCamera(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_POBJ(ScriptViewport, Viewport_SetCamera, ScriptCamera); } -RuntimeScriptValue Sc_Viewport_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_BOOL(ScriptViewport, Viewport_GetVisible); +RuntimeScriptValue Sc_Viewport_GetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_BOOL(ScriptViewport, Viewport_GetVisible); } -RuntimeScriptValue Sc_Viewport_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PBOOL(ScriptViewport, Viewport_SetVisible); +RuntimeScriptValue Sc_Viewport_SetVisible(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PBOOL(ScriptViewport, Viewport_SetVisible); } -RuntimeScriptValue Sc_Viewport_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_INT(ScriptViewport, Viewport_GetZOrder); +RuntimeScriptValue Sc_Viewport_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_INT(ScriptViewport, Viewport_GetZOrder); } -RuntimeScriptValue Sc_Viewport_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetZOrder); +RuntimeScriptValue Sc_Viewport_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT(ScriptViewport, Viewport_SetZOrder); } -RuntimeScriptValue Sc_Viewport_GetAtScreenXY(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_SCALL_OBJAUTO_PINT2(ScriptViewport, Viewport_GetAtScreenXY); +RuntimeScriptValue Sc_Viewport_GetAtScreenXY(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_SCALL_OBJAUTO_PINT2(ScriptViewport, Viewport_GetAtScreenXY); } -RuntimeScriptValue Sc_Viewport_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_VOID_PINT4(ScriptViewport, Viewport_SetPosition); +RuntimeScriptValue Sc_Viewport_SetPosition(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_VOID_PINT4(ScriptViewport, Viewport_SetPosition); } -RuntimeScriptValue Sc_Viewport_ScreenToRoomPoint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJAUTO_PINT2_PBOOL(ScriptViewport, ScriptUserObject, Viewport_ScreenToRoomPoint); +RuntimeScriptValue Sc_Viewport_ScreenToRoomPoint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJAUTO_PINT2_PBOOL(ScriptViewport, ScriptUserObject, Viewport_ScreenToRoomPoint); } -RuntimeScriptValue Sc_Viewport_RoomToScreenPoint(void *self, const RuntimeScriptValue *params, int32_t param_count) -{ - API_OBJCALL_OBJAUTO_PINT2_PBOOL(ScriptViewport, ScriptUserObject, Viewport_RoomToScreenPoint); +RuntimeScriptValue Sc_Viewport_RoomToScreenPoint(void *self, const RuntimeScriptValue *params, int32_t param_count) { + API_OBJCALL_OBJAUTO_PINT2_PBOOL(ScriptViewport, ScriptUserObject, Viewport_RoomToScreenPoint); } -void RegisterViewportAPI() -{ - ccAddExternalStaticFunction("Camera::Create", Sc_Camera_Create); - ccAddExternalObjectFunction("Camera::Delete", Sc_Camera_Delete); - ccAddExternalObjectFunction("Camera::get_X", Sc_Camera_GetX); - ccAddExternalObjectFunction("Camera::set_X", Sc_Camera_SetX); - ccAddExternalObjectFunction("Camera::get_Y", Sc_Camera_GetY); - ccAddExternalObjectFunction("Camera::set_Y", Sc_Camera_SetY); - ccAddExternalObjectFunction("Camera::get_Width", Sc_Camera_GetWidth); - ccAddExternalObjectFunction("Camera::set_Width", Sc_Camera_SetWidth); - ccAddExternalObjectFunction("Camera::get_Height", Sc_Camera_GetHeight); - ccAddExternalObjectFunction("Camera::set_Height", Sc_Camera_SetHeight); - ccAddExternalObjectFunction("Camera::get_AutoTracking", Sc_Camera_GetAutoTracking); - ccAddExternalObjectFunction("Camera::set_AutoTracking", Sc_Camera_SetAutoTracking); - ccAddExternalObjectFunction("Camera::SetAt", Sc_Camera_SetAt); - ccAddExternalObjectFunction("Camera::SetSize", Sc_Camera_SetSize); +void RegisterViewportAPI() { + ccAddExternalStaticFunction("Camera::Create", Sc_Camera_Create); + ccAddExternalObjectFunction("Camera::Delete", Sc_Camera_Delete); + ccAddExternalObjectFunction("Camera::get_X", Sc_Camera_GetX); + ccAddExternalObjectFunction("Camera::set_X", Sc_Camera_SetX); + ccAddExternalObjectFunction("Camera::get_Y", Sc_Camera_GetY); + ccAddExternalObjectFunction("Camera::set_Y", Sc_Camera_SetY); + ccAddExternalObjectFunction("Camera::get_Width", Sc_Camera_GetWidth); + ccAddExternalObjectFunction("Camera::set_Width", Sc_Camera_SetWidth); + ccAddExternalObjectFunction("Camera::get_Height", Sc_Camera_GetHeight); + ccAddExternalObjectFunction("Camera::set_Height", Sc_Camera_SetHeight); + ccAddExternalObjectFunction("Camera::get_AutoTracking", Sc_Camera_GetAutoTracking); + ccAddExternalObjectFunction("Camera::set_AutoTracking", Sc_Camera_SetAutoTracking); + ccAddExternalObjectFunction("Camera::SetAt", Sc_Camera_SetAt); + ccAddExternalObjectFunction("Camera::SetSize", Sc_Camera_SetSize); - ccAddExternalStaticFunction("Viewport::Create", Sc_Viewport_Create); - ccAddExternalObjectFunction("Viewport::Delete", Sc_Viewport_Delete); - ccAddExternalObjectFunction("Viewport::get_X", Sc_Viewport_GetX); - ccAddExternalObjectFunction("Viewport::set_X", Sc_Viewport_SetX); - ccAddExternalObjectFunction("Viewport::get_Y", Sc_Viewport_GetY); - ccAddExternalObjectFunction("Viewport::set_Y", Sc_Viewport_SetY); - ccAddExternalObjectFunction("Viewport::get_Width", Sc_Viewport_GetWidth); - ccAddExternalObjectFunction("Viewport::set_Width", Sc_Viewport_SetWidth); - ccAddExternalObjectFunction("Viewport::get_Height", Sc_Viewport_GetHeight); - ccAddExternalObjectFunction("Viewport::set_Height", Sc_Viewport_SetHeight); - ccAddExternalObjectFunction("Viewport::get_Camera", Sc_Viewport_GetCamera); - ccAddExternalObjectFunction("Viewport::set_Camera", Sc_Viewport_SetCamera); - ccAddExternalObjectFunction("Viewport::get_Visible", Sc_Viewport_GetVisible); - ccAddExternalObjectFunction("Viewport::set_Visible", Sc_Viewport_SetVisible); - ccAddExternalObjectFunction("Viewport::get_ZOrder", Sc_Viewport_GetZOrder); - ccAddExternalObjectFunction("Viewport::set_ZOrder", Sc_Viewport_SetZOrder); - ccAddExternalObjectFunction("Viewport::GetAtScreenXY", Sc_Viewport_GetAtScreenXY); - ccAddExternalObjectFunction("Viewport::SetPosition", Sc_Viewport_SetPosition); - ccAddExternalObjectFunction("Viewport::ScreenToRoomPoint", Sc_Viewport_ScreenToRoomPoint); - ccAddExternalObjectFunction("Viewport::RoomToScreenPoint", Sc_Viewport_RoomToScreenPoint); + ccAddExternalStaticFunction("Viewport::Create", Sc_Viewport_Create); + ccAddExternalObjectFunction("Viewport::Delete", Sc_Viewport_Delete); + ccAddExternalObjectFunction("Viewport::get_X", Sc_Viewport_GetX); + ccAddExternalObjectFunction("Viewport::set_X", Sc_Viewport_SetX); + ccAddExternalObjectFunction("Viewport::get_Y", Sc_Viewport_GetY); + ccAddExternalObjectFunction("Viewport::set_Y", Sc_Viewport_SetY); + ccAddExternalObjectFunction("Viewport::get_Width", Sc_Viewport_GetWidth); + ccAddExternalObjectFunction("Viewport::set_Width", Sc_Viewport_SetWidth); + ccAddExternalObjectFunction("Viewport::get_Height", Sc_Viewport_GetHeight); + ccAddExternalObjectFunction("Viewport::set_Height", Sc_Viewport_SetHeight); + ccAddExternalObjectFunction("Viewport::get_Camera", Sc_Viewport_GetCamera); + ccAddExternalObjectFunction("Viewport::set_Camera", Sc_Viewport_SetCamera); + ccAddExternalObjectFunction("Viewport::get_Visible", Sc_Viewport_GetVisible); + ccAddExternalObjectFunction("Viewport::set_Visible", Sc_Viewport_SetVisible); + ccAddExternalObjectFunction("Viewport::get_ZOrder", Sc_Viewport_GetZOrder); + ccAddExternalObjectFunction("Viewport::set_ZOrder", Sc_Viewport_SetZOrder); + ccAddExternalObjectFunction("Viewport::GetAtScreenXY", Sc_Viewport_GetAtScreenXY); + ccAddExternalObjectFunction("Viewport::SetPosition", Sc_Viewport_SetPosition); + ccAddExternalObjectFunction("Viewport::ScreenToRoomPoint", Sc_Viewport_ScreenToRoomPoint); + ccAddExternalObjectFunction("Viewport::RoomToScreenPoint", Sc_Viewport_RoomToScreenPoint); } diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp index 1666b21b162d..8b16f635b843 100644 --- a/engines/ags/engine/ac/walkablearea.cpp +++ b/engines/ags/engine/ac/walkablearea.cpp @@ -39,208 +39,203 @@ extern RoomStruct thisroom; extern GameState play; extern GameSetupStruct game; extern int displayed_room; -extern RoomStatus*croom; -extern RoomObject*objs; +extern RoomStatus *croom; +extern RoomObject *objs; -Bitmap *walkareabackup=nullptr, *walkable_areas_temp = nullptr; +Bitmap *walkareabackup = nullptr, *walkable_areas_temp = nullptr; void redo_walkable_areas() { - // since this is an 8-bit memory bitmap, we can just use direct - // memory access - if ((!thisroom.WalkAreaMask->IsLinearBitmap()) || (thisroom.WalkAreaMask->GetColorDepth() != 8)) - quit("Walkable areas bitmap not linear"); + // since this is an 8-bit memory bitmap, we can just use direct + // memory access + if ((!thisroom.WalkAreaMask->IsLinearBitmap()) || (thisroom.WalkAreaMask->GetColorDepth() != 8)) + quit("Walkable areas bitmap not linear"); - thisroom.WalkAreaMask->Blit(walkareabackup, 0, 0, 0, 0, thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight()); + thisroom.WalkAreaMask->Blit(walkareabackup, 0, 0, 0, 0, thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight()); - int hh,ww; - for (hh=0;hhGetHeight();hh++) { - uint8_t *walls_scanline = thisroom.WalkAreaMask->GetScanLineForWriting(hh); - for (ww=0;wwGetWidth();ww++) { - // if (play.walkable_areas_on[_getpixel(thisroom.WalkAreaMask,ww,hh)]==0) - if (play.walkable_areas_on[walls_scanline[ww]]==0) - walls_scanline[ww] = 0; - } - } + int hh, ww; + for (hh = 0; hh < walkareabackup->GetHeight(); hh++) { + uint8_t *walls_scanline = thisroom.WalkAreaMask->GetScanLineForWriting(hh); + for (ww = 0; ww < walkareabackup->GetWidth(); ww++) { + // if (play.walkable_areas_on[_getpixel(thisroom.WalkAreaMask,ww,hh)]==0) + if (play.walkable_areas_on[walls_scanline[ww]] == 0) + walls_scanline[ww] = 0; + } + } } -int get_walkable_area_pixel(int x, int y) -{ - return thisroom.WalkAreaMask->GetPixel(room_to_mask_coord(x), room_to_mask_coord(y)); +int get_walkable_area_pixel(int x, int y) { + return thisroom.WalkAreaMask->GetPixel(room_to_mask_coord(x), room_to_mask_coord(y)); } -int get_area_scaling (int onarea, int xx, int yy) { - - int zoom_level = 100; - xx = room_to_mask_coord(xx); - yy = room_to_mask_coord(yy); - - if ((onarea >= 0) && (onarea <= MAX_WALK_AREAS) && - (thisroom.WalkAreas[onarea].ScalingNear != NOT_VECTOR_SCALED)) { - // We have vector scaling! - // In case the character is off the screen, limit the Y co-ordinate - // to within the area range (otherwise we get silly zoom levels - // that cause Out Of Memory crashes) - if (yy > thisroom.WalkAreas[onarea].Bottom) - yy = thisroom.WalkAreas[onarea].Bottom; - if (yy < thisroom.WalkAreas[onarea].Top) - yy = thisroom.WalkAreas[onarea].Top; - // Work it all out without having to use floats - // Percent = ((y - top) * 100) / (areabottom - areatop) - // Zoom level = ((max - min) * Percent) / 100 - if (thisroom.WalkAreas[onarea].Bottom != thisroom.WalkAreas[onarea].Top) - { - int percent = ((yy - thisroom.WalkAreas[onarea].Top) * 100) - / (thisroom.WalkAreas[onarea].Bottom - thisroom.WalkAreas[onarea].Top); - zoom_level = ((thisroom.WalkAreas[onarea].ScalingNear - thisroom.WalkAreas[onarea].ScalingFar) * (percent)) / 100 + thisroom.WalkAreas[onarea].ScalingFar; - } - else - { - // Special case for 1px tall walkable area: take bottom line scaling - zoom_level = thisroom.WalkAreas[onarea].ScalingNear; - } - zoom_level += 100; - } - else if ((onarea >= 0) & (onarea <= MAX_WALK_AREAS)) - zoom_level = thisroom.WalkAreas[onarea].ScalingFar + 100; - - if (zoom_level == 0) - zoom_level = 100; - - return zoom_level; +int get_area_scaling(int onarea, int xx, int yy) { + + int zoom_level = 100; + xx = room_to_mask_coord(xx); + yy = room_to_mask_coord(yy); + + if ((onarea >= 0) && (onarea <= MAX_WALK_AREAS) && + (thisroom.WalkAreas[onarea].ScalingNear != NOT_VECTOR_SCALED)) { + // We have vector scaling! + // In case the character is off the screen, limit the Y co-ordinate + // to within the area range (otherwise we get silly zoom levels + // that cause Out Of Memory crashes) + if (yy > thisroom.WalkAreas[onarea].Bottom) + yy = thisroom.WalkAreas[onarea].Bottom; + if (yy < thisroom.WalkAreas[onarea].Top) + yy = thisroom.WalkAreas[onarea].Top; + // Work it all out without having to use floats + // Percent = ((y - top) * 100) / (areabottom - areatop) + // Zoom level = ((max - min) * Percent) / 100 + if (thisroom.WalkAreas[onarea].Bottom != thisroom.WalkAreas[onarea].Top) { + int percent = ((yy - thisroom.WalkAreas[onarea].Top) * 100) + / (thisroom.WalkAreas[onarea].Bottom - thisroom.WalkAreas[onarea].Top); + zoom_level = ((thisroom.WalkAreas[onarea].ScalingNear - thisroom.WalkAreas[onarea].ScalingFar) * (percent)) / 100 + thisroom.WalkAreas[onarea].ScalingFar; + } else { + // Special case for 1px tall walkable area: take bottom line scaling + zoom_level = thisroom.WalkAreas[onarea].ScalingNear; + } + zoom_level += 100; + } else if ((onarea >= 0) & (onarea <= MAX_WALK_AREAS)) + zoom_level = thisroom.WalkAreas[onarea].ScalingFar + 100; + + if (zoom_level == 0) + zoom_level = 100; + + return zoom_level; } void scale_sprite_size(int sppic, int zoom_level, int *newwidth, int *newheight) { - newwidth[0] = (game.SpriteInfos[sppic].Width * zoom_level) / 100; - newheight[0] = (game.SpriteInfos[sppic].Height * zoom_level) / 100; - if (newwidth[0] < 1) - newwidth[0] = 1; - if (newheight[0] < 1) - newheight[0] = 1; + newwidth[0] = (game.SpriteInfos[sppic].Width * zoom_level) / 100; + newheight[0] = (game.SpriteInfos[sppic].Height * zoom_level) / 100; + if (newwidth[0] < 1) + newwidth[0] = 1; + if (newheight[0] < 1) + newheight[0] = 1; } void remove_walkable_areas_from_temp(int fromx, int cwidth, int starty, int endy) { - fromx = room_to_mask_coord(fromx); - cwidth = room_to_mask_coord(cwidth); - starty = room_to_mask_coord(starty); - endy = room_to_mask_coord(endy); + fromx = room_to_mask_coord(fromx); + cwidth = room_to_mask_coord(cwidth); + starty = room_to_mask_coord(starty); + endy = room_to_mask_coord(endy); - int yyy; - if (endy >= walkable_areas_temp->GetHeight()) - endy = walkable_areas_temp->GetHeight() - 1; - if (starty < 0) - starty = 0; + int yyy; + if (endy >= walkable_areas_temp->GetHeight()) + endy = walkable_areas_temp->GetHeight() - 1; + if (starty < 0) + starty = 0; - for (; cwidth > 0; cwidth --) { - for (yyy = starty; yyy <= endy; yyy++) - walkable_areas_temp->PutPixel (fromx, yyy, 0); - fromx ++; - } + for (; cwidth > 0; cwidth --) { + for (yyy = starty; yyy <= endy; yyy++) + walkable_areas_temp->PutPixel(fromx, yyy, 0); + fromx ++; + } } int is_point_in_rect(int x, int y, int left, int top, int right, int bottom) { - if ((x >= left) && (x < right) && (y >= top ) && (y <= bottom)) - return 1; - return 0; + if ((x >= left) && (x < right) && (y >= top) && (y <= bottom)) + return 1; + return 0; } -Bitmap *prepare_walkable_areas (int sourceChar) { - // copy the walkable areas to the temp bitmap - walkable_areas_temp->Blit(thisroom.WalkAreaMask.get(), 0,0,0,0,thisroom.WalkAreaMask->GetWidth(),thisroom.WalkAreaMask->GetHeight()); - // if the character who's moving doesn't Bitmap *, don't bother checking - if (sourceChar < 0) ; - else if (game.chars[sourceChar].flags & CHF_NOBLOCKING) - return walkable_areas_temp; - - int ww; - // for each character in the current room, make the area under - // them unwalkable - for (ww = 0; ww < game.numcharacters; ww++) { - if (game.chars[ww].on != 1) continue; - if (game.chars[ww].room != displayed_room) continue; - if (ww == sourceChar) continue; - if (game.chars[ww].flags & CHF_NOBLOCKING) continue; - if (room_to_mask_coord(game.chars[ww].y) >= walkable_areas_temp->GetHeight()) continue; - if (room_to_mask_coord(game.chars[ww].x) >= walkable_areas_temp->GetWidth()) continue; - if ((game.chars[ww].y < 0) || (game.chars[ww].x < 0)) continue; - - CharacterInfo *char1 = &game.chars[ww]; - int cwidth, fromx; - - if (is_char_on_another(sourceChar, ww, &fromx, &cwidth)) - continue; - if ((sourceChar >= 0) && (is_char_on_another(ww, sourceChar, nullptr, nullptr))) - continue; - - remove_walkable_areas_from_temp(fromx, cwidth, char1->get_blocking_top(), char1->get_blocking_bottom()); - } - - // check for any blocking objects in the room, and deal with them - // as well - for (ww = 0; ww < croom->numobj; ww++) { - if (objs[ww].on != 1) continue; - if ((objs[ww].flags & OBJF_SOLID) == 0) - continue; - if (room_to_mask_coord(objs[ww].y) >= walkable_areas_temp->GetHeight()) continue; - if (room_to_mask_coord(objs[ww].x) >= walkable_areas_temp->GetWidth()) continue; - if ((objs[ww].y < 0) || (objs[ww].x < 0)) continue; - - int x1, y1, width, y2; - get_object_blocking_rect(ww, &x1, &y1, &width, &y2); - - // if the character is currently standing on the object, ignore - // it so as to allow him to escape - if ((sourceChar >= 0) && - (is_point_in_rect(game.chars[sourceChar].x, game.chars[sourceChar].y, - x1, y1, x1 + width, y2))) - continue; - - remove_walkable_areas_from_temp(x1, width, y1, y2); - } - - return walkable_areas_temp; +Bitmap *prepare_walkable_areas(int sourceChar) { + // copy the walkable areas to the temp bitmap + walkable_areas_temp->Blit(thisroom.WalkAreaMask.get(), 0, 0, 0, 0, thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight()); + // if the character who's moving doesn't Bitmap *, don't bother checking + if (sourceChar < 0) ; + else if (game.chars[sourceChar].flags & CHF_NOBLOCKING) + return walkable_areas_temp; + + int ww; + // for each character in the current room, make the area under + // them unwalkable + for (ww = 0; ww < game.numcharacters; ww++) { + if (game.chars[ww].on != 1) continue; + if (game.chars[ww].room != displayed_room) continue; + if (ww == sourceChar) continue; + if (game.chars[ww].flags & CHF_NOBLOCKING) continue; + if (room_to_mask_coord(game.chars[ww].y) >= walkable_areas_temp->GetHeight()) continue; + if (room_to_mask_coord(game.chars[ww].x) >= walkable_areas_temp->GetWidth()) continue; + if ((game.chars[ww].y < 0) || (game.chars[ww].x < 0)) continue; + + CharacterInfo *char1 = &game.chars[ww]; + int cwidth, fromx; + + if (is_char_on_another(sourceChar, ww, &fromx, &cwidth)) + continue; + if ((sourceChar >= 0) && (is_char_on_another(ww, sourceChar, nullptr, nullptr))) + continue; + + remove_walkable_areas_from_temp(fromx, cwidth, char1->get_blocking_top(), char1->get_blocking_bottom()); + } + + // check for any blocking objects in the room, and deal with them + // as well + for (ww = 0; ww < croom->numobj; ww++) { + if (objs[ww].on != 1) continue; + if ((objs[ww].flags & OBJF_SOLID) == 0) + continue; + if (room_to_mask_coord(objs[ww].y) >= walkable_areas_temp->GetHeight()) continue; + if (room_to_mask_coord(objs[ww].x) >= walkable_areas_temp->GetWidth()) continue; + if ((objs[ww].y < 0) || (objs[ww].x < 0)) continue; + + int x1, y1, width, y2; + get_object_blocking_rect(ww, &x1, &y1, &width, &y2); + + // if the character is currently standing on the object, ignore + // it so as to allow him to escape + if ((sourceChar >= 0) && + (is_point_in_rect(game.chars[sourceChar].x, game.chars[sourceChar].y, + x1, y1, x1 + width, y2))) + continue; + + remove_walkable_areas_from_temp(x1, width, y1, y2); + } + + return walkable_areas_temp; } // return the walkable area at the character's feet, taking into account // that he might just be off the edge of one int get_walkable_area_at_location(int xx, int yy) { - int onarea = get_walkable_area_pixel(xx, yy); - - if (onarea < 0) { - // the character has walked off the edge of the screen, so stop them - // jumping up to full size when leaving - if (xx >= thisroom.Width) - onarea = get_walkable_area_pixel(thisroom.Width-1, yy); - else if (xx < 0) - onarea = get_walkable_area_pixel(0, yy); - else if (yy >= thisroom.Height) - onarea = get_walkable_area_pixel(xx, thisroom.Height - 1); - else if (yy < 0) - onarea = get_walkable_area_pixel(xx, 1); - } - if (onarea==0) { - // the path finder sometimes slightly goes into non-walkable areas; - // so check for scaling in adjacent pixels - const int TRYGAP=2; - onarea = get_walkable_area_pixel(xx + TRYGAP, yy); - if (onarea<=0) - onarea = get_walkable_area_pixel(xx - TRYGAP, yy); - if (onarea<=0) - onarea = get_walkable_area_pixel(xx, yy + TRYGAP); - if (onarea<=0) - onarea = get_walkable_area_pixel(xx, yy - TRYGAP); - if (onarea < 0) - onarea = 0; - } - - return onarea; + int onarea = get_walkable_area_pixel(xx, yy); + + if (onarea < 0) { + // the character has walked off the edge of the screen, so stop them + // jumping up to full size when leaving + if (xx >= thisroom.Width) + onarea = get_walkable_area_pixel(thisroom.Width - 1, yy); + else if (xx < 0) + onarea = get_walkable_area_pixel(0, yy); + else if (yy >= thisroom.Height) + onarea = get_walkable_area_pixel(xx, thisroom.Height - 1); + else if (yy < 0) + onarea = get_walkable_area_pixel(xx, 1); + } + if (onarea == 0) { + // the path finder sometimes slightly goes into non-walkable areas; + // so check for scaling in adjacent pixels + const int TRYGAP = 2; + onarea = get_walkable_area_pixel(xx + TRYGAP, yy); + if (onarea <= 0) + onarea = get_walkable_area_pixel(xx - TRYGAP, yy); + if (onarea <= 0) + onarea = get_walkable_area_pixel(xx, yy + TRYGAP); + if (onarea <= 0) + onarea = get_walkable_area_pixel(xx, yy - TRYGAP); + if (onarea < 0) + onarea = 0; + } + + return onarea; } -int get_walkable_area_at_character (int charnum) { - CharacterInfo *chin = &game.chars[charnum]; - return get_walkable_area_at_location(chin->x, chin->y); +int get_walkable_area_at_character(int charnum) { + CharacterInfo *chin = &game.chars[charnum]; + return get_walkable_area_at_location(chin->x, chin->y); } diff --git a/engines/ags/engine/ac/walkablearea.h b/engines/ags/engine/ac/walkablearea.h index b5694934bb3f..5be0c3902ecb 100644 --- a/engines/ags/engine/ac/walkablearea.h +++ b/engines/ags/engine/ac/walkablearea.h @@ -25,12 +25,12 @@ void redo_walkable_areas(); int get_walkable_area_pixel(int x, int y); -int get_area_scaling (int onarea, int xx, int yy); +int get_area_scaling(int onarea, int xx, int yy); void scale_sprite_size(int sppic, int zoom_level, int *newwidth, int *newheight); void remove_walkable_areas_from_temp(int fromx, int cwidth, int starty, int endy); int is_point_in_rect(int x, int y, int left, int top, int right, int bottom); -Common::Bitmap *prepare_walkable_areas (int sourceChar); +Common::Bitmap *prepare_walkable_areas(int sourceChar); int get_walkable_area_at_location(int xx, int yy); -int get_walkable_area_at_character (int charnum); +int get_walkable_area_at_character(int charnum); #endif diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp index 5a067a586b7b..ab1cc69554b1 100644 --- a/engines/ags/engine/ac/walkbehind.cpp +++ b/engines/ags/engine/ac/walkbehind.cpp @@ -45,107 +45,97 @@ int walkBehindsCachedForBgNum = 0; WalkBehindMethodEnum walkBehindMethod = DrawOverCharSprite; int walk_behind_baselines_changed = 0; -void update_walk_behind_images() -{ - int ee, rr; - int bpp = (thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth() + 7) / 8; - Bitmap *wbbmp; - for (ee = 1; ee < MAX_WALK_BEHINDS; ee++) - { - update_polled_stuff_if_runtime(); - - if (walkBehindRight[ee] > 0) - { - wbbmp = BitmapHelper::CreateTransparentBitmap( - (walkBehindRight[ee] - walkBehindLeft[ee]) + 1, - (walkBehindBottom[ee] - walkBehindTop[ee]) + 1, - thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth()); - int yy, startX = walkBehindLeft[ee], startY = walkBehindTop[ee]; - for (rr = startX; rr <= walkBehindRight[ee]; rr++) - { - for (yy = startY; yy <= walkBehindBottom[ee]; yy++) - { - if (thisroom.WalkBehindMask->GetScanLine(yy)[rr] == ee) - { - for (int ii = 0; ii < bpp; ii++) - wbbmp->GetScanLineForWriting(yy - startY)[(rr - startX) * bpp + ii] = thisroom.BgFrames[play.bg_frame].Graphic->GetScanLine(yy)[rr * bpp + ii]; - } - } - } - - update_polled_stuff_if_runtime(); - - if (walkBehindBitmap[ee] != nullptr) - { - gfxDriver->DestroyDDB(walkBehindBitmap[ee]); - } - walkBehindBitmap[ee] = gfxDriver->CreateDDBFromBitmap(wbbmp, false); - delete wbbmp; - } - } - - walkBehindsCachedForBgNum = play.bg_frame; +void update_walk_behind_images() { + int ee, rr; + int bpp = (thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth() + 7) / 8; + Bitmap *wbbmp; + for (ee = 1; ee < MAX_WALK_BEHINDS; ee++) { + update_polled_stuff_if_runtime(); + + if (walkBehindRight[ee] > 0) { + wbbmp = BitmapHelper::CreateTransparentBitmap( + (walkBehindRight[ee] - walkBehindLeft[ee]) + 1, + (walkBehindBottom[ee] - walkBehindTop[ee]) + 1, + thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth()); + int yy, startX = walkBehindLeft[ee], startY = walkBehindTop[ee]; + for (rr = startX; rr <= walkBehindRight[ee]; rr++) { + for (yy = startY; yy <= walkBehindBottom[ee]; yy++) { + if (thisroom.WalkBehindMask->GetScanLine(yy)[rr] == ee) { + for (int ii = 0; ii < bpp; ii++) + wbbmp->GetScanLineForWriting(yy - startY)[(rr - startX) * bpp + ii] = thisroom.BgFrames[play.bg_frame].Graphic->GetScanLine(yy)[rr * bpp + ii]; + } + } + } + + update_polled_stuff_if_runtime(); + + if (walkBehindBitmap[ee] != nullptr) { + gfxDriver->DestroyDDB(walkBehindBitmap[ee]); + } + walkBehindBitmap[ee] = gfxDriver->CreateDDBFromBitmap(wbbmp, false); + delete wbbmp; + } + } + + walkBehindsCachedForBgNum = play.bg_frame; } -void recache_walk_behinds () { - if (walkBehindExists) { - free (walkBehindExists); - free (walkBehindStartY); - free (walkBehindEndY); - } - - walkBehindExists = (char*)malloc (thisroom.WalkBehindMask->GetWidth()); - walkBehindStartY = (int*)malloc (thisroom.WalkBehindMask->GetWidth() * sizeof(int)); - walkBehindEndY = (int*)malloc (thisroom.WalkBehindMask->GetWidth() * sizeof(int)); - noWalkBehindsAtAll = 1; - - int ee,rr,tmm; - const int NO_WALK_BEHIND = 100000; - for (ee = 0; ee < MAX_WALK_BEHINDS; ee++) - { - walkBehindLeft[ee] = NO_WALK_BEHIND; - walkBehindTop[ee] = NO_WALK_BEHIND; - walkBehindRight[ee] = 0; - walkBehindBottom[ee] = 0; - - if (walkBehindBitmap[ee] != nullptr) - { - gfxDriver->DestroyDDB(walkBehindBitmap[ee]); - walkBehindBitmap[ee] = nullptr; - } - } - - update_polled_stuff_if_runtime(); - - // since this is an 8-bit memory bitmap, we can just use direct - // memory access - if ((!thisroom.WalkBehindMask->IsLinearBitmap()) || (thisroom.WalkBehindMask->GetColorDepth() != 8)) - quit("Walk behinds bitmap not linear"); - - for (ee=0;eeGetWidth();ee++) { - walkBehindExists[ee] = 0; - for (rr=0;rrGetHeight();rr++) { - tmm = thisroom.WalkBehindMask->GetScanLine(rr)[ee]; - //tmm = _getpixel(thisroom.WalkBehindMask,ee,rr); - if ((tmm >= 1) && (tmm < MAX_WALK_BEHINDS)) { - if (!walkBehindExists[ee]) { - walkBehindStartY[ee] = rr; - walkBehindExists[ee] = tmm; - noWalkBehindsAtAll = 0; - } - walkBehindEndY[ee] = rr + 1; // +1 to allow bottom line of screen to work - - if (ee < walkBehindLeft[tmm]) walkBehindLeft[tmm] = ee; - if (rr < walkBehindTop[tmm]) walkBehindTop[tmm] = rr; - if (ee > walkBehindRight[tmm]) walkBehindRight[tmm] = ee; - if (rr > walkBehindBottom[tmm]) walkBehindBottom[tmm] = rr; - } - } - } - - if (walkBehindMethod == DrawAsSeparateSprite) - { - update_walk_behind_images(); - } +void recache_walk_behinds() { + if (walkBehindExists) { + free(walkBehindExists); + free(walkBehindStartY); + free(walkBehindEndY); + } + + walkBehindExists = (char *)malloc(thisroom.WalkBehindMask->GetWidth()); + walkBehindStartY = (int *)malloc(thisroom.WalkBehindMask->GetWidth() * sizeof(int)); + walkBehindEndY = (int *)malloc(thisroom.WalkBehindMask->GetWidth() * sizeof(int)); + noWalkBehindsAtAll = 1; + + int ee, rr, tmm; + const int NO_WALK_BEHIND = 100000; + for (ee = 0; ee < MAX_WALK_BEHINDS; ee++) { + walkBehindLeft[ee] = NO_WALK_BEHIND; + walkBehindTop[ee] = NO_WALK_BEHIND; + walkBehindRight[ee] = 0; + walkBehindBottom[ee] = 0; + + if (walkBehindBitmap[ee] != nullptr) { + gfxDriver->DestroyDDB(walkBehindBitmap[ee]); + walkBehindBitmap[ee] = nullptr; + } + } + + update_polled_stuff_if_runtime(); + + // since this is an 8-bit memory bitmap, we can just use direct + // memory access + if ((!thisroom.WalkBehindMask->IsLinearBitmap()) || (thisroom.WalkBehindMask->GetColorDepth() != 8)) + quit("Walk behinds bitmap not linear"); + + for (ee = 0; ee < thisroom.WalkBehindMask->GetWidth(); ee++) { + walkBehindExists[ee] = 0; + for (rr = 0; rr < thisroom.WalkBehindMask->GetHeight(); rr++) { + tmm = thisroom.WalkBehindMask->GetScanLine(rr)[ee]; + //tmm = _getpixel(thisroom.WalkBehindMask,ee,rr); + if ((tmm >= 1) && (tmm < MAX_WALK_BEHINDS)) { + if (!walkBehindExists[ee]) { + walkBehindStartY[ee] = rr; + walkBehindExists[ee] = tmm; + noWalkBehindsAtAll = 0; + } + walkBehindEndY[ee] = rr + 1; // +1 to allow bottom line of screen to work + + if (ee < walkBehindLeft[tmm]) walkBehindLeft[tmm] = ee; + if (rr < walkBehindTop[tmm]) walkBehindTop[tmm] = rr; + if (ee > walkBehindRight[tmm]) walkBehindRight[tmm] = ee; + if (rr > walkBehindBottom[tmm]) walkBehindBottom[tmm] = rr; + } + } + } + + if (walkBehindMethod == DrawAsSeparateSprite) { + update_walk_behind_images(); + } } diff --git a/engines/ags/engine/ac/walkbehind.h b/engines/ags/engine/ac/walkbehind.h index a2210ede876f..2bb80701a1f0 100644 --- a/engines/ags/engine/ac/walkbehind.h +++ b/engines/ags/engine/ac/walkbehind.h @@ -23,14 +23,13 @@ #ifndef AGS_ENGINE_AC_WALKBEHIND_H #define AGS_ENGINE_AC_WALKBEHIND_H -enum WalkBehindMethodEnum -{ - DrawOverCharSprite, - DrawAsSeparateSprite, - DrawAsSeparateCharSprite +enum WalkBehindMethodEnum { + DrawOverCharSprite, + DrawAsSeparateSprite, + DrawAsSeparateCharSprite }; void update_walk_behind_images(); -void recache_walk_behinds (); +void recache_walk_behinds(); #endif diff --git a/engines/ags/engine/debugging/agseditordebugger.h b/engines/ags/engine/debugging/agseditordebugger.h index fdee2419e96a..8871a2f5dd3e 100644 --- a/engines/ags/engine/debugging/agseditordebugger.h +++ b/engines/ags/engine/debugging/agseditordebugger.h @@ -23,17 +23,16 @@ #ifndef AGS_ENGINE_DEBUGGING_AGSEDITORDEBUGGER_H #define AGS_ENGINE_DEBUGGING_AGSEDITORDEBUGGER_H -struct IAGSEditorDebugger -{ +struct IAGSEditorDebugger { public: - virtual ~IAGSEditorDebugger() = default; + virtual ~IAGSEditorDebugger() = default; - virtual bool Initialize() = 0; - virtual void Shutdown() = 0; - virtual bool SendMessageToEditor(const char *message) = 0; - virtual bool IsMessageAvailable() = 0; - // Message will be allocated on heap with malloc - virtual char* GetNextMessage() = 0; + virtual bool Initialize() = 0; + virtual void Shutdown() = 0; + virtual bool SendMessageToEditor(const char *message) = 0; + virtual bool IsMessageAvailable() = 0; + // Message will be allocated on heap with malloc + virtual char *GetNextMessage() = 0; }; #endif diff --git a/engines/ags/engine/debugging/consoleoutputtarget.cpp b/engines/ags/engine/debugging/consoleoutputtarget.cpp index 9f53eb120843..3e90694f39ef 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.cpp +++ b/engines/ags/engine/debugging/consoleoutputtarget.cpp @@ -24,26 +24,22 @@ #include "consoleoutputtarget.h" #include "debug/debug_log.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -ConsoleOutputTarget::ConsoleOutputTarget() -{ +ConsoleOutputTarget::ConsoleOutputTarget() { } ConsoleOutputTarget::~ConsoleOutputTarget() = default; -void ConsoleOutputTarget::PrintMessage(const DebugMessage &msg) -{ - // limit number of characters for console - // TODO: is there a way to find out how many characters can fit in? - debug_line[last_debug_line] = msg.Text.Left(99); +void ConsoleOutputTarget::PrintMessage(const DebugMessage &msg) { + // limit number of characters for console + // TODO: is there a way to find out how many characters can fit in? + debug_line[last_debug_line] = msg.Text.Left(99); - last_debug_line = (last_debug_line + 1) % DEBUG_CONSOLE_NUMLINES; - if (last_debug_line == first_debug_line) - first_debug_line = (first_debug_line + 1) % DEBUG_CONSOLE_NUMLINES; + last_debug_line = (last_debug_line + 1) % DEBUG_CONSOLE_NUMLINES; + if (last_debug_line == first_debug_line) + first_debug_line = (first_debug_line + 1) % DEBUG_CONSOLE_NUMLINES; } } // namespace Engine diff --git a/engines/ags/engine/debugging/consoleoutputtarget.h b/engines/ags/engine/debugging/consoleoutputtarget.h index d6cab71dcef9..9e12ac973995 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.h +++ b/engines/ags/engine/debugging/consoleoutputtarget.h @@ -32,21 +32,18 @@ #include "debug/outputhandler.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using Common::String; using Common::DebugMessage; -class ConsoleOutputTarget : public AGS::Common::IOutputHandler -{ +class ConsoleOutputTarget : public AGS::Common::IOutputHandler { public: - ConsoleOutputTarget(); - virtual ~ConsoleOutputTarget(); + ConsoleOutputTarget(); + virtual ~ConsoleOutputTarget(); - void PrintMessage(const DebugMessage &msg) override; + void PrintMessage(const DebugMessage &msg) override; }; } // namespace Engine diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index 4c3a99fe85b8..e180cad5c2ae 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -72,21 +72,19 @@ volatile int game_paused_in_debugger = 0; HWND editor_window_handle = 0; -IAGSEditorDebugger *GetEditorDebugger(const char *instanceToken) -{ - return new NamedPipesAGSDebugger(instanceToken); +IAGSEditorDebugger *GetEditorDebugger(const char *instanceToken) { + return new NamedPipesAGSDebugger(instanceToken); } #else // AGS_PLATFORM_OS_WINDOWS -IAGSEditorDebugger *GetEditorDebugger(const char *instanceToken) -{ - return nullptr; +IAGSEditorDebugger *GetEditorDebugger(const char *instanceToken) { + return nullptr; } #endif -int debug_flags=0; +int debug_flags = 0; String debug_line[DEBUG_CONSOLE_NUMLINES]; int first_debug_line = 0, last_debug_line = 0, display_console = 0; @@ -105,474 +103,417 @@ const String OutputGameConsoleID = "console"; -PDebugOutput create_log_output(const String &name, const String &path = "", LogFile::OpenMode open_mode = LogFile::kLogFile_Overwrite) -{ - // Else create new one, if we know this ID - if (name.CompareNoCase(OutputSystemID) == 0) - { - return DbgMgr.RegisterOutput(OutputSystemID, AGSPlatformDriver::GetDriver(), kDbgMsg_None); - } - else if (name.CompareNoCase(OutputFileID) == 0) - { - DebugLogFile.reset(new LogFile()); - String logfile_path = !path.IsEmpty() ? path : String::FromFormat("%s/ags.log", platform->GetAppOutputDirectory()); - if (!DebugLogFile->OpenFile(logfile_path, open_mode)) - return nullptr; - platform->WriteStdOut("Logging to %s", logfile_path.GetCStr()); - auto dbgout = DbgMgr.RegisterOutput(OutputFileID, DebugLogFile.get(), kDbgMsg_None); - return dbgout; - } - else if (name.CompareNoCase(OutputGameConsoleID) == 0) - { - DebugConsole.reset(new ConsoleOutputTarget()); - return DbgMgr.RegisterOutput(OutputGameConsoleID, DebugConsole.get(), kDbgMsg_None); - } - return nullptr; +PDebugOutput create_log_output(const String &name, const String &path = "", LogFile::OpenMode open_mode = LogFile::kLogFile_Overwrite) { + // Else create new one, if we know this ID + if (name.CompareNoCase(OutputSystemID) == 0) { + return DbgMgr.RegisterOutput(OutputSystemID, AGSPlatformDriver::GetDriver(), kDbgMsg_None); + } else if (name.CompareNoCase(OutputFileID) == 0) { + DebugLogFile.reset(new LogFile()); + String logfile_path = !path.IsEmpty() ? path : String::FromFormat("%s/ags.log", platform->GetAppOutputDirectory()); + if (!DebugLogFile->OpenFile(logfile_path, open_mode)) + return nullptr; + platform->WriteStdOut("Logging to %s", logfile_path.GetCStr()); + auto dbgout = DbgMgr.RegisterOutput(OutputFileID, DebugLogFile.get(), kDbgMsg_None); + return dbgout; + } else if (name.CompareNoCase(OutputGameConsoleID) == 0) { + DebugConsole.reset(new ConsoleOutputTarget()); + return DbgMgr.RegisterOutput(OutputGameConsoleID, DebugConsole.get(), kDbgMsg_None); + } + return nullptr; } // Parses a string where each character defines a single log group; returns list of real group names. -std::vector parse_log_multigroup(const String &group_str) -{ - std::vector grplist; - for (size_t i = 0; i < group_str.GetLength(); ++i) - { - switch (group_str[i]) - { - case 'm': grplist.push_back("main"); break; - case 'g': grplist.push_back("game"); break; - case 's': grplist.push_back("script"); break; - case 'c': grplist.push_back("sprcache"); break; - case 'o': grplist.push_back("manobj"); break; - } - } - return grplist; +std::vector parse_log_multigroup(const String &group_str) { + std::vector grplist; + for (size_t i = 0; i < group_str.GetLength(); ++i) { + switch (group_str[i]) { + case 'm': + grplist.push_back("main"); + break; + case 'g': + grplist.push_back("game"); + break; + case 's': + grplist.push_back("script"); + break; + case 'c': + grplist.push_back("sprcache"); + break; + case 'o': + grplist.push_back("manobj"); + break; + } + } + return grplist; } -MessageType get_messagetype_from_string(const String &mt) -{ - int mtype; - if (StrUtil::StringToInt(mt, mtype, 0) == StrUtil::kNoError) - return (MessageType)mtype; - - if (mt.CompareNoCase("alert") == 0) return kDbgMsg_Alert; - else if (mt.CompareNoCase("fatal") == 0) return kDbgMsg_Fatal; - else if (mt.CompareNoCase("error") == 0) return kDbgMsg_Error; - else if (mt.CompareNoCase("warn") == 0) return kDbgMsg_Warn; - else if (mt.CompareNoCase("info") == 0) return kDbgMsg_Info; - else if (mt.CompareNoCase("debug") == 0) return kDbgMsg_Debug; - else if (mt.CompareNoCase("all") == 0) return kDbgMsg_All; - return kDbgMsg_None; +MessageType get_messagetype_from_string(const String &mt) { + int mtype; + if (StrUtil::StringToInt(mt, mtype, 0) == StrUtil::kNoError) + return (MessageType)mtype; + + if (mt.CompareNoCase("alert") == 0) return kDbgMsg_Alert; + else if (mt.CompareNoCase("fatal") == 0) return kDbgMsg_Fatal; + else if (mt.CompareNoCase("error") == 0) return kDbgMsg_Error; + else if (mt.CompareNoCase("warn") == 0) return kDbgMsg_Warn; + else if (mt.CompareNoCase("info") == 0) return kDbgMsg_Info; + else if (mt.CompareNoCase("debug") == 0) return kDbgMsg_Debug; + else if (mt.CompareNoCase("all") == 0) return kDbgMsg_All; + return kDbgMsg_None; } typedef std::pair DbgGroupOption; void apply_log_config(const ConfigTree &cfg, const String &log_id, bool def_enabled, - std::initializer_list def_opts) -{ - String value = INIreadstring(cfg, "log", log_id); - if (value.IsEmpty() && !def_enabled) - return; - - // First test if already registered, if not then try create it - auto dbgout = DbgMgr.GetOutput(log_id); - const bool was_created_earlier = dbgout != nullptr; - if (!dbgout) - { - String path = INIreadstring(cfg, "log", String::FromFormat("%s-path", log_id.GetCStr())); - dbgout = create_log_output(log_id, path); - if (!dbgout) - return; // unknown output type - } - dbgout->ClearGroupFilters(); - - if (value.IsEmpty() || value.CompareNoCase("default") == 0) - { - for (const auto opt : def_opts) - dbgout->SetGroupFilter(opt.first, opt.second); - } - else - { - const auto options = value.Split(','); - for (const auto &opt : options) - { - String groupname = opt.LeftSection(':'); - MessageType msgtype = kDbgMsg_All; - if (opt.GetLength() >= groupname.GetLength() + 1) - { - String msglevel = opt.Mid(groupname.GetLength() + 1); - msglevel.Trim(); - if (msglevel.GetLength() > 0) - msgtype = get_messagetype_from_string(msglevel); - } - groupname.Trim(); - if (groupname.CompareNoCase("all") == 0 || groupname.IsEmpty()) - { - dbgout->SetAllGroupFilters(msgtype); - } - else if (groupname[0u] != '+') - { - dbgout->SetGroupFilter(groupname, msgtype); - } - else - { - const auto groups = parse_log_multigroup(groupname); - for (const auto &g : groups) - dbgout->SetGroupFilter(g, msgtype); - } - } - } - - // Delegate buffered messages to this new output - if (DebugMsgBuff && !was_created_earlier) - DebugMsgBuff->Send(log_id); + std::initializer_list def_opts) { + String value = INIreadstring(cfg, "log", log_id); + if (value.IsEmpty() && !def_enabled) + return; + + // First test if already registered, if not then try create it + auto dbgout = DbgMgr.GetOutput(log_id); + const bool was_created_earlier = dbgout != nullptr; + if (!dbgout) { + String path = INIreadstring(cfg, "log", String::FromFormat("%s-path", log_id.GetCStr())); + dbgout = create_log_output(log_id, path); + if (!dbgout) + return; // unknown output type + } + dbgout->ClearGroupFilters(); + + if (value.IsEmpty() || value.CompareNoCase("default") == 0) { + for (const auto opt : def_opts) + dbgout->SetGroupFilter(opt.first, opt.second); + } else { + const auto options = value.Split(','); + for (const auto &opt : options) { + String groupname = opt.LeftSection(':'); + MessageType msgtype = kDbgMsg_All; + if (opt.GetLength() >= groupname.GetLength() + 1) { + String msglevel = opt.Mid(groupname.GetLength() + 1); + msglevel.Trim(); + if (msglevel.GetLength() > 0) + msgtype = get_messagetype_from_string(msglevel); + } + groupname.Trim(); + if (groupname.CompareNoCase("all") == 0 || groupname.IsEmpty()) { + dbgout->SetAllGroupFilters(msgtype); + } else if (groupname[0u] != '+') { + dbgout->SetGroupFilter(groupname, msgtype); + } else { + const auto groups = parse_log_multigroup(groupname); + for (const auto &g : groups) + dbgout->SetGroupFilter(g, msgtype); + } + } + } + + // Delegate buffered messages to this new output + if (DebugMsgBuff && !was_created_earlier) + DebugMsgBuff->Send(log_id); } -void init_debug(const ConfigTree &cfg, bool stderr_only) -{ - // Register outputs - apply_debug_config(cfg); - platform->SetOutputToErr(stderr_only); +void init_debug(const ConfigTree &cfg, bool stderr_only) { + // Register outputs + apply_debug_config(cfg); + platform->SetOutputToErr(stderr_only); - if (stderr_only) - return; + if (stderr_only) + return; - // Message buffer to save all messages in case we read different log settings from config file - DebugMsgBuff.reset(new MessageBuffer()); - DbgMgr.RegisterOutput(OutputMsgBufID, DebugMsgBuff.get(), kDbgMsg_All); + // Message buffer to save all messages in case we read different log settings from config file + DebugMsgBuff.reset(new MessageBuffer()); + DbgMgr.RegisterOutput(OutputMsgBufID, DebugMsgBuff.get(), kDbgMsg_All); } -void apply_debug_config(const ConfigTree &cfg) -{ - apply_log_config(cfg, OutputSystemID, /* defaults */ true, { DbgGroupOption(kDbgGroup_Main, kDbgMsg_Info) }); - bool legacy_log_enabled = INIreadint(cfg, "misc", "log", 0) != 0; - apply_log_config(cfg, OutputFileID, - /* defaults */ - legacy_log_enabled, - { DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), - DbgGroupOption(kDbgGroup_Game, kDbgMsg_Info), - DbgGroupOption(kDbgGroup_Script, kDbgMsg_All), +void apply_debug_config(const ConfigTree &cfg) { + apply_log_config(cfg, OutputSystemID, /* defaults */ true, { DbgGroupOption(kDbgGroup_Main, kDbgMsg_Info) }); + bool legacy_log_enabled = INIreadint(cfg, "misc", "log", 0) != 0; + apply_log_config(cfg, OutputFileID, + /* defaults */ + legacy_log_enabled, { + DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Game, kDbgMsg_Info), + DbgGroupOption(kDbgGroup_Script, kDbgMsg_All), #ifdef DEBUG_SPRITECACHE - DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_All), + DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_All), #else - DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_Info), + DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_Info), #endif #ifdef DEBUG_MANAGED_OBJECTS - DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_All), + DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_All), #else - DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_Info), + DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_Info), #endif - }); - - // Init game console if the game was compiled in Debug mode - if (game.options[OPT_DEBUGMODE] != 0) - { - apply_log_config(cfg, OutputGameConsoleID, - /* defaults */ - true, - { DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), - DbgGroupOption(kDbgGroup_Game, kDbgMsg_All), - DbgGroupOption(kDbgGroup_Script, kDbgMsg_All) - }); - debug_set_console(true); - } - - // If the game was compiled in Debug mode *and* there's no regular file log, - // then open "warnings.log" for printing script warnings. - if (game.options[OPT_DEBUGMODE] != 0 && !DebugLogFile) - { - auto dbgout = create_log_output(OutputFileID, "warnings.log", LogFile::kLogFile_OverwriteAtFirstMessage); - if (dbgout) - { - dbgout->SetGroupFilter(kDbgGroup_Game, kDbgMsg_Warn); - dbgout->SetGroupFilter(kDbgGroup_Script, kDbgMsg_Warn); - } - } - - // We don't need message buffer beyond this point - DbgMgr.UnregisterOutput(OutputMsgBufID); - DebugMsgBuff.reset(); + }); + + // Init game console if the game was compiled in Debug mode + if (game.options[OPT_DEBUGMODE] != 0) { + apply_log_config(cfg, OutputGameConsoleID, + /* defaults */ + true, { + DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Game, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Script, kDbgMsg_All) + }); + debug_set_console(true); + } + + // If the game was compiled in Debug mode *and* there's no regular file log, + // then open "warnings.log" for printing script warnings. + if (game.options[OPT_DEBUGMODE] != 0 && !DebugLogFile) { + auto dbgout = create_log_output(OutputFileID, "warnings.log", LogFile::kLogFile_OverwriteAtFirstMessage); + if (dbgout) { + dbgout->SetGroupFilter(kDbgGroup_Game, kDbgMsg_Warn); + dbgout->SetGroupFilter(kDbgGroup_Script, kDbgMsg_Warn); + } + } + + // We don't need message buffer beyond this point + DbgMgr.UnregisterOutput(OutputMsgBufID); + DebugMsgBuff.reset(); } -void shutdown_debug() -{ - // Shutdown output subsystem - DbgMgr.UnregisterAll(); +void shutdown_debug() { + // Shutdown output subsystem + DbgMgr.UnregisterAll(); - DebugMsgBuff.reset(); - DebugLogFile.reset(); - DebugConsole.reset(); + DebugMsgBuff.reset(); + DebugLogFile.reset(); + DebugConsole.reset(); } -void debug_set_console(bool enable) -{ - if (DebugConsole) - DbgMgr.GetOutput(OutputGameConsoleID)->SetEnabled(enable); +void debug_set_console(bool enable) { + if (DebugConsole) + DbgMgr.GetOutput(OutputGameConsoleID)->SetEnabled(enable); } // Prepends message text with current room number and running script info, then logs result -void debug_script_print(const String &msg, MessageType mt) -{ - String script_ref; - ccInstance *curinst = ccInstance::GetCurrentInstance(); - if (curinst != nullptr) { - String scriptname; - if (curinst->instanceof == gamescript) - scriptname = "G "; - else if (curinst->instanceof == thisroom.CompiledScript) - scriptname = "R "; - else if (curinst->instanceof == dialogScriptsScript) - scriptname = "D "; - else - scriptname = "? "; - script_ref.Format("[%s%d]", scriptname.GetCStr(), currentline); - } - - Debug::Printf(kDbgGroup_Game, mt, "(room:%d)%s %s", displayed_room, script_ref.GetCStr(), msg.GetCStr()); +void debug_script_print(const String &msg, MessageType mt) { + String script_ref; + ccInstance *curinst = ccInstance::GetCurrentInstance(); + if (curinst != nullptr) { + String scriptname; + if (curinst->instanceof == gamescript) + scriptname = "G "; + else if (curinst->instanceof == thisroom.CompiledScript) + scriptname = "R "; + else if (curinst->instanceof == dialogScriptsScript) + scriptname = "D "; + else + scriptname = "? "; + script_ref.Format("[%s%d]", scriptname.GetCStr(), currentline); + } + + Debug::Printf(kDbgGroup_Game, mt, "(room:%d)%s %s", displayed_room, script_ref.GetCStr(), msg.GetCStr()); } -void debug_script_warn(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); - String full_msg = String::FromFormatV(msg, ap); - va_end(ap); - debug_script_print(full_msg, kDbgMsg_Warn); +void debug_script_warn(const char *msg, ...) { + va_list ap; + va_start(ap, msg); + String full_msg = String::FromFormatV(msg, ap); + va_end(ap); + debug_script_print(full_msg, kDbgMsg_Warn); } -void debug_script_log(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); - String full_msg = String::FromFormatV(msg, ap); - va_end(ap); - debug_script_print(full_msg, kDbgMsg_Debug); +void debug_script_log(const char *msg, ...) { + va_list ap; + va_start(ap, msg); + String full_msg = String::FromFormatV(msg, ap); + va_end(ap); + debug_script_print(full_msg, kDbgMsg_Debug); } -String get_cur_script(int numberOfLinesOfCallStack) -{ - String callstack; - ccInstance *sci = ccInstance::GetCurrentInstance(); - if (sci) - callstack = sci->GetCallStack(numberOfLinesOfCallStack); - if (callstack.IsEmpty()) - callstack = ccErrorCallStack; - return callstack; +String get_cur_script(int numberOfLinesOfCallStack) { + String callstack; + ccInstance *sci = ccInstance::GetCurrentInstance(); + if (sci) + callstack = sci->GetCallStack(numberOfLinesOfCallStack); + if (callstack.IsEmpty()) + callstack = ccErrorCallStack; + return callstack; } -bool get_script_position(ScriptPosition &script_pos) -{ - ccInstance *cur_instance = ccInstance::GetCurrentInstance(); - if (cur_instance) - { - cur_instance->GetScriptPosition(script_pos); - return true; - } - return false; +bool get_script_position(ScriptPosition &script_pos) { + ccInstance *cur_instance = ccInstance::GetCurrentInstance(); + if (cur_instance) { + cur_instance->GetScriptPosition(script_pos); + return true; + } + return false; } -struct Breakpoint -{ - char scriptName[80]; - int lineNumber; +struct Breakpoint { + char scriptName[80]; + int lineNumber; }; std::vector breakpoints; int numBreakpoints = 0; -bool send_message_to_editor(const char *msg, const char *errorMsg) -{ - String callStack = get_cur_script(25); - if (callStack.IsEmpty()) - return false; +bool send_message_to_editor(const char *msg, const char *errorMsg) { + String callStack = get_cur_script(25); + if (callStack.IsEmpty()) + return false; - char messageToSend[STD_BUFFER_SIZE]; - sprintf(messageToSend, "", msg); + char messageToSend[STD_BUFFER_SIZE]; + sprintf(messageToSend, "", msg); #if AGS_PLATFORM_OS_WINDOWS - sprintf(&messageToSend[strlen(messageToSend)], " %d ", (int)win_get_window()); + sprintf(&messageToSend[strlen(messageToSend)], " %d ", (int)win_get_window()); #endif - sprintf(&messageToSend[strlen(messageToSend)], " ", callStack.GetCStr()); - if (errorMsg != nullptr) - { - sprintf(&messageToSend[strlen(messageToSend)], " ", errorMsg); - } - strcat(messageToSend, ""); + sprintf(&messageToSend[strlen(messageToSend)], " ", callStack.GetCStr()); + if (errorMsg != nullptr) { + sprintf(&messageToSend[strlen(messageToSend)], " ", errorMsg); + } + strcat(messageToSend, ""); - editor_debugger->SendMessageToEditor(messageToSend); + editor_debugger->SendMessageToEditor(messageToSend); - return true; + return true; } -bool send_message_to_editor(const char *msg) -{ - return send_message_to_editor(msg, nullptr); +bool send_message_to_editor(const char *msg) { + return send_message_to_editor(msg, nullptr); } -bool init_editor_debugging() -{ +bool init_editor_debugging() { #if AGS_PLATFORM_OS_WINDOWS - editor_debugger = GetEditorDebugger(editor_debugger_instance_token); + editor_debugger = GetEditorDebugger(editor_debugger_instance_token); #else - // Editor isn't ported yet - editor_debugger = nullptr; + // Editor isn't ported yet + editor_debugger = nullptr; #endif - if (editor_debugger == nullptr) - quit("editor_debugger is NULL but debugger enabled"); + if (editor_debugger == nullptr) + quit("editor_debugger is NULL but debugger enabled"); - if (editor_debugger->Initialize()) - { - editor_debugging_initialized = 1; + if (editor_debugger->Initialize()) { + editor_debugging_initialized = 1; - // Wait for the editor to send the initial breakpoints - // and then its READY message - while (check_for_messages_from_editor() != 2) - { - platform->Delay(10); - } + // Wait for the editor to send the initial breakpoints + // and then its READY message + while (check_for_messages_from_editor() != 2) { + platform->Delay(10); + } - send_message_to_editor("START"); - return true; - } + send_message_to_editor("START"); + return true; + } - return false; + return false; } -int check_for_messages_from_editor() -{ - if (editor_debugger->IsMessageAvailable()) - { - char *msg = editor_debugger->GetNextMessage(); - if (msg == nullptr) - { - return 0; - } - - if (strncmp(msg, "IsMessageAvailable()) { + char *msg = editor_debugger->GetNextMessage(); + if (msg == nullptr) { + return 0; + } + + if (strncmp(msg, "Delay(10); - } + want_exit = 0; + // allow the editor to break with the error message + if (editor_window_handle != NULL) + SetForegroundWindow(editor_window_handle); + + if (!send_message_to_editor("ERROR", qmsg)) + return false; + + while ((check_for_messages_from_editor() == 0) && (want_exit == 0)) { + update_polled_mp3(); + platform->Delay(10); + } #endif - return true; + return true; } -void break_into_debugger() -{ +void break_into_debugger() { #if AGS_PLATFORM_OS_WINDOWS - if (editor_window_handle != NULL) - SetForegroundWindow(editor_window_handle); + if (editor_window_handle != NULL) + SetForegroundWindow(editor_window_handle); - send_message_to_editor("BREAK"); - game_paused_in_debugger = 1; + send_message_to_editor("BREAK"); + game_paused_in_debugger = 1; - while (game_paused_in_debugger) - { - update_polled_stuff_if_runtime(); - platform->YieldCPU(); - } + while (game_paused_in_debugger) { + update_polled_stuff_if_runtime(); + platform->YieldCPU(); + } #endif } @@ -581,57 +522,53 @@ int scrDebugWait = 0; extern int pluginsWantingDebugHooks; // allow LShift to single-step, RShift to pause flow -void scriptDebugHook (ccInstance *ccinst, int linenum) { - - if (pluginsWantingDebugHooks > 0) { - // a plugin is handling the debugging - String scname = GetScriptName(ccinst); - pl_run_plugin_debug_hooks(scname, linenum); - return; - } - - // no plugin, use built-in debugger - - if (ccinst == nullptr) - { - // come out of script - return; - } - - if (break_on_next_script_step) - { - break_on_next_script_step = 0; - break_into_debugger(); - return; - } - - const char *scriptName = ccinst->runningInst->instanceof->GetSectionName(ccinst->pc); - - for (int i = 0; i < numBreakpoints; i++) - { - if ((breakpoints[i].lineNumber == linenum) && - (strcmp(breakpoints[i].scriptName, scriptName) == 0)) - { - break_into_debugger(); - break; - } - } +void scriptDebugHook(ccInstance *ccinst, int linenum) { + + if (pluginsWantingDebugHooks > 0) { + // a plugin is handling the debugging + String scname = GetScriptName(ccinst); + pl_run_plugin_debug_hooks(scname, linenum); + return; + } + + // no plugin, use built-in debugger + + if (ccinst == nullptr) { + // come out of script + return; + } + + if (break_on_next_script_step) { + break_on_next_script_step = 0; + break_into_debugger(); + return; + } + + const char *scriptName = ccinst->runningInst->instanceof->GetSectionName(ccinst->pc); + + for (int i = 0; i < numBreakpoints; i++) { + if ((breakpoints[i].lineNumber == linenum) && + (strcmp(breakpoints[i].scriptName, scriptName) == 0)) { + break_into_debugger(); + break; + } + } } int scrlockWasDown = 0; void check_debug_keys() { - if (play.debug_mode) { - // do the run-time script debugging + if (play.debug_mode) { + // do the run-time script debugging - if ((!key[KEY_SCRLOCK]) && (scrlockWasDown)) - scrlockWasDown = 0; - else if ((key[KEY_SCRLOCK]) && (!scrlockWasDown)) { + if ((!key[KEY_SCRLOCK]) && (scrlockWasDown)) + scrlockWasDown = 0; + else if ((key[KEY_SCRLOCK]) && (!scrlockWasDown)) { - break_on_next_script_step = 1; - scrlockWasDown = 1; - } + break_on_next_script_step = 1; + scrlockWasDown = 1; + } - } + } } diff --git a/engines/ags/engine/debugging/debug_log.h b/engines/ags/engine/debugging/debug_log.h index f5b677da8442..f8d07e03830c 100644 --- a/engines/ags/engine/debugging/debug_log.h +++ b/engines/ags/engine/debugging/debug_log.h @@ -45,7 +45,7 @@ void quitprintf(const char *texx, ...); bool init_editor_debugging(); // allow LShift to single-step, RShift to pause flow -void scriptDebugHook (ccInstance *ccinst, int linenum) ; +void scriptDebugHook(ccInstance *ccinst, int linenum) ; extern AGS::Common::String debug_line[DEBUG_CONSOLE_NUMLINES]; extern int first_debug_line, last_debug_line, display_console; diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h index 5f8cb21a0e14..399952677171 100644 --- a/engines/ags/engine/debugging/debugger.h +++ b/engines/ags/engine/debugging/debugger.h @@ -54,11 +54,10 @@ void check_debug_keys(); #define DBG_REGONLY 0x200 #define DBG_NOVIDEO 0x400 -enum FPSDisplayMode -{ - kFPS_Hide = 0, // hid by the script/user command - kFPS_Display = 1, // shown by the script/user command - kFPS_Forced = 2 // forced shown by the engine arg +enum FPSDisplayMode { + kFPS_Hide = 0, // hid by the script/user command + kFPS_Display = 1, // shown by the script/user command + kFPS_Forced = 2 // forced shown by the engine arg }; extern float fps; diff --git a/engines/ags/engine/debugging/dummyagsdebugger.h b/engines/ags/engine/debugging/dummyagsdebugger.h index 140baffc30dc..8ae955bc5b1c 100644 --- a/engines/ags/engine/debugging/dummyagsdebugger.h +++ b/engines/ags/engine/debugging/dummyagsdebugger.h @@ -25,15 +25,22 @@ #include "debug/debugger.h" -struct DummyAGSDebugger : IAGSEditorDebugger -{ +struct DummyAGSDebugger : IAGSEditorDebugger { public: - virtual bool Initialize() override { return false; } - virtual void Shutdown() override { } - virtual bool SendMessageToEditor(const char *message) override { return false; } - virtual bool IsMessageAvailable() override { return false; } - virtual char* GetNextMessage() override { return NULL; } + virtual bool Initialize() override { + return false; + } + virtual void Shutdown() override { } + virtual bool SendMessageToEditor(const char *message) override { + return false; + } + virtual bool IsMessageAvailable() override { + return false; + } + virtual char *GetNextMessage() override { + return NULL; + } }; #endif diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.cpp b/engines/ags/engine/debugging/filebasedagsdebugger.cpp index d00edf7711ae..22d2ce218c38 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.cpp +++ b/engines/ags/engine/debugging/filebasedagsdebugger.cpp @@ -31,55 +31,47 @@ using AGS::Common::Stream; using AGS::Common::TextStreamWriter; -const char* SENT_MESSAGE_FILE_NAME = "dbgrecv.tmp"; +const char *SENT_MESSAGE_FILE_NAME = "dbgrecv.tmp"; -bool FileBasedAGSDebugger::Initialize() -{ - if (exists(SENT_MESSAGE_FILE_NAME)) - { - ::remove(SENT_MESSAGE_FILE_NAME); - } - return true; +bool FileBasedAGSDebugger::Initialize() { + if (exists(SENT_MESSAGE_FILE_NAME)) { + ::remove(SENT_MESSAGE_FILE_NAME); + } + return true; } -void FileBasedAGSDebugger::Shutdown() -{ +void FileBasedAGSDebugger::Shutdown() { } -bool FileBasedAGSDebugger::SendMessageToEditor(const char *message) -{ - while (exists(SENT_MESSAGE_FILE_NAME)) - { - platform->YieldCPU(); - } +bool FileBasedAGSDebugger::SendMessageToEditor(const char *message) { + while (exists(SENT_MESSAGE_FILE_NAME)) { + platform->YieldCPU(); + } - Stream *out = Common::File::CreateFile(SENT_MESSAGE_FILE_NAME); - // CHECKME: originally the file was opened as "wb" for some reason, - // which means the message should be written as a binary array; - // or shouldn't it? - out->Write(message, strlen(message)); - delete out; - return true; + Stream *out = Common::File::CreateFile(SENT_MESSAGE_FILE_NAME); + // CHECKME: originally the file was opened as "wb" for some reason, + // which means the message should be written as a binary array; + // or shouldn't it? + out->Write(message, strlen(message)); + delete out; + return true; } -bool FileBasedAGSDebugger::IsMessageAvailable() -{ - return (exists("dbgsend.tmp") != 0); +bool FileBasedAGSDebugger::IsMessageAvailable() { + return (exists("dbgsend.tmp") != 0); } -char* FileBasedAGSDebugger::GetNextMessage() -{ - Stream *in = Common::File::OpenFileRead("dbgsend.tmp"); - if (in == nullptr) - { - // check again, because the editor might have deleted the file in the meantime - return nullptr; - } - int fileSize = in->GetLength(); - char *msg = (char*)malloc(fileSize + 1); - in->Read(msg, fileSize); - delete in; - ::remove("dbgsend.tmp"); - msg[fileSize] = 0; - return msg; +char *FileBasedAGSDebugger::GetNextMessage() { + Stream *in = Common::File::OpenFileRead("dbgsend.tmp"); + if (in == nullptr) { + // check again, because the editor might have deleted the file in the meantime + return nullptr; + } + int fileSize = in->GetLength(); + char *msg = (char *)malloc(fileSize + 1); + in->Read(msg, fileSize); + delete in; + ::remove("dbgsend.tmp"); + msg[fileSize] = 0; + return msg; } diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.h b/engines/ags/engine/debugging/filebasedagsdebugger.h index 1caeee702e3f..aebfba868fa3 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.h +++ b/engines/ags/engine/debugging/filebasedagsdebugger.h @@ -25,18 +25,17 @@ #include "debug/agseditordebugger.h" -struct FileBasedAGSDebugger : IAGSEditorDebugger -{ +struct FileBasedAGSDebugger : IAGSEditorDebugger { public: - bool Initialize() override; - void Shutdown() override; - bool SendMessageToEditor(const char *message) override; - bool IsMessageAvailable() override; - char* GetNextMessage() override; + bool Initialize() override; + void Shutdown() override; + bool SendMessageToEditor(const char *message) override; + bool IsMessageAvailable() override; + char *GetNextMessage() override; }; -extern const char* SENT_MESSAGE_FILE_NAME; +extern const char *SENT_MESSAGE_FILE_NAME; #endif diff --git a/engines/ags/engine/debugging/logfile.cpp b/engines/ags/engine/debugging/logfile.cpp index dae1d4478cba..444b880bb3c5 100644 --- a/engines/ags/engine/debugging/logfile.cpp +++ b/engines/ags/engine/debugging/logfile.cpp @@ -26,70 +26,58 @@ #include "util/stream.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using namespace Common; LogFile::LogFile() - : _openMode(kLogFile_Overwrite) -{ + : _openMode(kLogFile_Overwrite) { } -void LogFile::PrintMessage(const DebugMessage &msg) -{ - if (!_file.get()) - { - if (_filePath.IsEmpty()) - return; - _file.reset(File::OpenFile(_filePath, _openMode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, - Common::kFile_Write)); - if (!_file) - { - Debug::Printf("Unable to write log to '%s'.", _filePath.GetCStr()); - _filePath = ""; - return; - } - } +void LogFile::PrintMessage(const DebugMessage &msg) { + if (!_file.get()) { + if (_filePath.IsEmpty()) + return; + _file.reset(File::OpenFile(_filePath, _openMode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, + Common::kFile_Write)); + if (!_file) { + Debug::Printf("Unable to write log to '%s'.", _filePath.GetCStr()); + _filePath = ""; + return; + } + } - if (!msg.GroupName.IsEmpty()) - { - _file->Write(msg.GroupName, msg.GroupName.GetLength()); - _file->Write(" : ", 3); - } - _file->Write(msg.Text, msg.Text.GetLength()); - _file->WriteInt8('\n'); - // We should flush after every write to the log; this will make writing - // bit slower, but will increase the chances that all latest output - // will get to the disk in case of program crash. - _file->Flush(); + if (!msg.GroupName.IsEmpty()) { + _file->Write(msg.GroupName, msg.GroupName.GetLength()); + _file->Write(" : ", 3); + } + _file->Write(msg.Text, msg.Text.GetLength()); + _file->WriteInt8('\n'); + // We should flush after every write to the log; this will make writing + // bit slower, but will increase the chances that all latest output + // will get to the disk in case of program crash. + _file->Flush(); } -bool LogFile::OpenFile(const String &file_path, OpenMode open_mode) -{ - CloseFile(); +bool LogFile::OpenFile(const String &file_path, OpenMode open_mode) { + CloseFile(); - _filePath = file_path; - _openMode = open_mode; - if (open_mode == OpenMode::kLogFile_OverwriteAtFirstMessage) - { - return File::TestWriteFile(_filePath); - } - else - { - _file.reset(File::OpenFile(file_path, - open_mode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, - Common::kFile_Write)); - return _file.get() != nullptr; - } + _filePath = file_path; + _openMode = open_mode; + if (open_mode == OpenMode::kLogFile_OverwriteAtFirstMessage) { + return File::TestWriteFile(_filePath); + } else { + _file.reset(File::OpenFile(file_path, + open_mode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, + Common::kFile_Write)); + return _file.get() != nullptr; + } } -void LogFile::CloseFile() -{ - _file.reset(); - _filePath.Empty(); +void LogFile::CloseFile() { + _file.reset(); + _filePath.Empty(); } } // namespace Engine diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h index 4bf8d8a96a0c..c0f9a6824578 100644 --- a/engines/ags/engine/debugging/logfile.h +++ b/engines/ags/engine/debugging/logfile.h @@ -38,49 +38,47 @@ #include #include "debug/outputhandler.h" -namespace AGS -{ +namespace AGS { -namespace Common { class Stream; } +namespace Common { +class Stream; +} -namespace Engine -{ +namespace Engine { using Common::DebugMessage; using Common::Stream; using Common::String; -class LogFile : public AGS::Common::IOutputHandler -{ +class LogFile : public AGS::Common::IOutputHandler { public: - enum OpenMode - { - kLogFile_Overwrite, - kLogFile_OverwriteAtFirstMessage, - kLogFile_Append - }; + enum OpenMode { + kLogFile_Overwrite, + kLogFile_OverwriteAtFirstMessage, + kLogFile_Append + }; public: - LogFile(); + LogFile(); - void PrintMessage(const Common::DebugMessage &msg) override; + void PrintMessage(const Common::DebugMessage &msg) override; - // Open file using given file path, optionally appending if one exists - // - // TODO: filepath parameter here may be actually used as a pattern - // or prefix, while the actual filename could be made by combining - // this prefix with current date, game name, and similar additional - // useful information. Whether this is to be determined here or on - // high-level side remains a question. - // - bool OpenFile(const String &file_path, OpenMode open_mode = kLogFile_Overwrite); - // Close file - void CloseFile(); + // Open file using given file path, optionally appending if one exists + // + // TODO: filepath parameter here may be actually used as a pattern + // or prefix, while the actual filename could be made by combining + // this prefix with current date, game name, and similar additional + // useful information. Whether this is to be determined here or on + // high-level side remains a question. + // + bool OpenFile(const String &file_path, OpenMode open_mode = kLogFile_Overwrite); + // Close file + void CloseFile(); private: - std::unique_ptr _file; - String _filePath; - OpenMode _openMode; + std::unique_ptr _file; + String _filePath; + OpenMode _openMode; }; } // namespace Engine diff --git a/engines/ags/engine/debugging/messagebuffer.cpp b/engines/ags/engine/debugging/messagebuffer.cpp index 0ef84d5806b3..3ae8f427992a 100644 --- a/engines/ags/engine/debugging/messagebuffer.cpp +++ b/engines/ags/engine/debugging/messagebuffer.cpp @@ -23,53 +23,44 @@ #include "debug/debugmanager.h" #include "debug/messagebuffer.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using namespace Common; MessageBuffer::MessageBuffer(size_t buffer_limit) - : _bufferLimit(buffer_limit) - , _msgLost(0) -{ + : _bufferLimit(buffer_limit) + , _msgLost(0) { } -void MessageBuffer::PrintMessage(const DebugMessage &msg) -{ - if (_buffer.size() < _bufferLimit) - _buffer.push_back(msg); - else - _msgLost++; +void MessageBuffer::PrintMessage(const DebugMessage &msg) { + if (_buffer.size() < _bufferLimit) + _buffer.push_back(msg); + else + _msgLost++; } -void MessageBuffer::Clear() -{ - _buffer.clear(); - _msgLost = 0; +void MessageBuffer::Clear() { + _buffer.clear(); + _msgLost = 0; } -void MessageBuffer::Send(const String &out_id) -{ - if (_buffer.empty()) - return; - if (_msgLost > 0) - { - DebugGroup gr = DbgMgr.GetGroup(kDbgGroup_Main); - DbgMgr.SendMessage(out_id, DebugMessage(String::FromFormat("WARNING: output %s lost exceeding buffer: %u debug messages\n", out_id.GetCStr(), (unsigned)_msgLost), - gr.UID.ID, gr.OutputName, kDbgMsg_All)); - } - for (std::vector::const_iterator it = _buffer.begin(); it != _buffer.end(); ++it) - { - DbgMgr.SendMessage(out_id, *it); - } +void MessageBuffer::Send(const String &out_id) { + if (_buffer.empty()) + return; + if (_msgLost > 0) { + DebugGroup gr = DbgMgr.GetGroup(kDbgGroup_Main); + DbgMgr.SendMessage(out_id, DebugMessage(String::FromFormat("WARNING: output %s lost exceeding buffer: %u debug messages\n", out_id.GetCStr(), (unsigned)_msgLost), + gr.UID.ID, gr.OutputName, kDbgMsg_All)); + } + for (std::vector::const_iterator it = _buffer.begin(); it != _buffer.end(); ++it) { + DbgMgr.SendMessage(out_id, *it); + } } -void MessageBuffer::Flush(const String &out_id) -{ - Send(out_id); - Clear(); +void MessageBuffer::Flush(const String &out_id) { + Send(out_id); + Clear(); } } // namespace Engine diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h index e8f986f1118e..1f80ee5494e3 100644 --- a/engines/ags/engine/debugging/messagebuffer.h +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -34,32 +34,29 @@ #include #include "debug/outputhandler.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using Common::String; using Common::DebugMessage; -class MessageBuffer : public AGS::Common::IOutputHandler -{ +class MessageBuffer : public AGS::Common::IOutputHandler { public: - MessageBuffer(size_t buffer_limit = 1024); + MessageBuffer(size_t buffer_limit = 1024); - void PrintMessage(const DebugMessage &msg) override; + void PrintMessage(const DebugMessage &msg) override; - // Clears buffer - void Clear(); - // Sends buffered messages into given output target - void Send(const String &out_id); - // Sends buffered messages into given output target and clears buffer - void Flush(const String &out_id); + // Clears buffer + void Clear(); + // Sends buffered messages into given output target + void Send(const String &out_id); + // Sends buffered messages into given output target and clears buffer + void Flush(const String &out_id); private: - const size_t _bufferLimit; - std::vector _buffer; - size_t _msgLost; + const size_t _bufferLimit; + std::vector _buffer; + size_t _msgLost; }; } // namespace Engine diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index 1a7d1f32f403..66b0b147c373 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -81,317 +81,278 @@ Bitmap *mousecurs[MAXCURSORS]; extern color palette[256]; extern volatile bool switched_away; -namespace Mouse -{ - // Tells whether mouse was locked to the game window - bool LockedToWindow = false; - - // Screen rectangle, in which the mouse movement is controlled by engine - Rect ControlRect; - // Mouse control enabled flag - bool ControlEnabled = false; - // Flag that tells whether the mouse must be forced to stay inside control rect - bool ConfineInCtrlRect = false; - // Mouse speed value provided by user - float SpeedVal = 1.f; - // Mouse speed unit - float SpeedUnit = 1.f; - // Actual speed factor (cached) - float Speed = 1.f; - - - void AdjustPosition(int &x, int &y); +namespace Mouse { +// Tells whether mouse was locked to the game window +bool LockedToWindow = false; + +// Screen rectangle, in which the mouse movement is controlled by engine +Rect ControlRect; +// Mouse control enabled flag +bool ControlEnabled = false; +// Flag that tells whether the mouse must be forced to stay inside control rect +bool ConfineInCtrlRect = false; +// Mouse speed value provided by user +float SpeedVal = 1.f; +// Mouse speed unit +float SpeedUnit = 1.f; +// Actual speed factor (cached) +float Speed = 1.f; + + +void AdjustPosition(int &x, int &y); } -void mgraphconfine(int x1, int y1, int x2, int y2) -{ - Mouse::ControlRect = Rect(x1, y1, x2, y2); - set_mouse_range(Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom); - Debug::Printf("Mouse confined: (%d,%d)-(%d,%d) (%dx%d)", - Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom, - Mouse::ControlRect.GetWidth(), Mouse::ControlRect.GetHeight()); +void mgraphconfine(int x1, int y1, int x2, int y2) { + Mouse::ControlRect = Rect(x1, y1, x2, y2); + set_mouse_range(Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom); + Debug::Printf("Mouse confined: (%d,%d)-(%d,%d) (%dx%d)", + Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom, + Mouse::ControlRect.GetWidth(), Mouse::ControlRect.GetHeight()); } -void mgetgraphpos() -{ - poll_mouse(); - if (disable_mgetgraphpos) - { - // The cursor coordinates are provided from alternate source; - // in this case we completely ignore actual cursor movement. - if (!ignore_bounds && - (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) - { - mousex = Math::Clamp(mousex, boundx1, boundx2); - mousey = Math::Clamp(mousey, boundy1, boundy2); - msetgraphpos(mousex, mousey); - } - return; - } - - if (!switched_away && Mouse::ControlEnabled) - { - // Control mouse movement by querying mouse mickeys (movement deltas) - // and applying them to saved mouse coordinates. - int mickey_x, mickey_y; - get_mouse_mickeys(&mickey_x, &mickey_y); - - // Apply mouse speed - int dx = Mouse::Speed * mickey_x; - int dy = Mouse::Speed * mickey_y; - - // - // Perform actual cursor update - //--------------------------------------------------------------------- - // If the real cursor is inside the control rectangle (read - game window), - // then apply sensitivity factors and adjust real cursor position - if (Mouse::ControlRect.IsInside(real_mouse_x + dx, real_mouse_y + dy)) - { - real_mouse_x += dx; - real_mouse_y += dy; - position_mouse(real_mouse_x, real_mouse_y); - } - // Otherwise, if real cursor was moved outside the control rect, yet we - // are required to confine cursor inside one, then adjust cursor position - // to stay inside the rect's bounds. - else if (Mouse::ConfineInCtrlRect) - { - real_mouse_x = Math::Clamp(real_mouse_x + dx, Mouse::ControlRect.Left, Mouse::ControlRect.Right); - real_mouse_y = Math::Clamp(real_mouse_y + dy, Mouse::ControlRect.Top, Mouse::ControlRect.Bottom); - position_mouse(real_mouse_x, real_mouse_y); - } - // Lastly, if the real cursor is out of the control rect, simply add - // actual movement to keep up with the system cursor coordinates. - else - { - real_mouse_x += mickey_x; - real_mouse_y += mickey_y; - } - - // Do not update the game cursor if the real cursor is beyond the control rect - if (!Mouse::ControlRect.IsInside(real_mouse_x, real_mouse_y)) - return; - } - else - { - // Save real cursor coordinates provided by system - real_mouse_x = mouse_x; - real_mouse_y = mouse_y; - } - - // Set new in-game cursor position - mousex = real_mouse_x; - mousey = real_mouse_y; - - if (!ignore_bounds && - (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) - { - mousex = Math::Clamp(mousex, boundx1, boundx2); - mousey = Math::Clamp(mousey, boundy1, boundy2); - msetgraphpos(mousex, mousey); - } - - // Convert to virtual coordinates - Mouse::AdjustPosition(mousex, mousey); +void mgetgraphpos() { + poll_mouse(); + if (disable_mgetgraphpos) { + // The cursor coordinates are provided from alternate source; + // in this case we completely ignore actual cursor movement. + if (!ignore_bounds && + (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { + mousex = Math::Clamp(mousex, boundx1, boundx2); + mousey = Math::Clamp(mousey, boundy1, boundy2); + msetgraphpos(mousex, mousey); + } + return; + } + + if (!switched_away && Mouse::ControlEnabled) { + // Control mouse movement by querying mouse mickeys (movement deltas) + // and applying them to saved mouse coordinates. + int mickey_x, mickey_y; + get_mouse_mickeys(&mickey_x, &mickey_y); + + // Apply mouse speed + int dx = Mouse::Speed * mickey_x; + int dy = Mouse::Speed * mickey_y; + + // + // Perform actual cursor update + //--------------------------------------------------------------------- + // If the real cursor is inside the control rectangle (read - game window), + // then apply sensitivity factors and adjust real cursor position + if (Mouse::ControlRect.IsInside(real_mouse_x + dx, real_mouse_y + dy)) { + real_mouse_x += dx; + real_mouse_y += dy; + position_mouse(real_mouse_x, real_mouse_y); + } + // Otherwise, if real cursor was moved outside the control rect, yet we + // are required to confine cursor inside one, then adjust cursor position + // to stay inside the rect's bounds. + else if (Mouse::ConfineInCtrlRect) { + real_mouse_x = Math::Clamp(real_mouse_x + dx, Mouse::ControlRect.Left, Mouse::ControlRect.Right); + real_mouse_y = Math::Clamp(real_mouse_y + dy, Mouse::ControlRect.Top, Mouse::ControlRect.Bottom); + position_mouse(real_mouse_x, real_mouse_y); + } + // Lastly, if the real cursor is out of the control rect, simply add + // actual movement to keep up with the system cursor coordinates. + else { + real_mouse_x += mickey_x; + real_mouse_y += mickey_y; + } + + // Do not update the game cursor if the real cursor is beyond the control rect + if (!Mouse::ControlRect.IsInside(real_mouse_x, real_mouse_y)) + return; + } else { + // Save real cursor coordinates provided by system + real_mouse_x = mouse_x; + real_mouse_y = mouse_y; + } + + // Set new in-game cursor position + mousex = real_mouse_x; + mousey = real_mouse_y; + + if (!ignore_bounds && + (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { + mousex = Math::Clamp(mousex, boundx1, boundx2); + mousey = Math::Clamp(mousey, boundy1, boundy2); + msetgraphpos(mousex, mousey); + } + + // Convert to virtual coordinates + Mouse::AdjustPosition(mousex, mousey); } -void msetcursorlimit(int x1, int y1, int x2, int y2) -{ - boundx1 = x1; - boundy1 = y1; - boundx2 = x2; - boundy2 = y2; +void msetcursorlimit(int x1, int y1, int x2, int y2) { + boundx1 = x1; + boundy1 = y1; + boundx2 = x2; + boundy2 = y2; } int hotxwas = 0, hotywas = 0; -void domouse(int str) -{ - /* - TO USE THIS ROUTINE YOU MUST LOAD A MOUSE CURSOR USING mloadcursor. - YOU MUST ALSO REMEMBER TO CALL mfreemem AT THE END OF THE PROGRAM. - */ - int poow = mousecurs[currentcursor]->GetWidth(); - int pooh = mousecurs[currentcursor]->GetHeight(); - int smx = mousex - hotxwas, smy = mousey - hotywas; - const Rect &viewport = play.GetMainViewport(); - - mgetgraphpos(); - mousex -= hotx; - mousey -= hoty; - - if (mousex + poow >= viewport.GetWidth()) - poow = viewport.GetWidth() - mousex; - - if (mousey + pooh >= viewport.GetHeight()) - pooh = viewport.GetHeight() - mousey; - - mousex += hotx; - mousey += hoty; - hotxwas = hotx; - hotywas = hoty; +void domouse(int str) { + /* + TO USE THIS ROUTINE YOU MUST LOAD A MOUSE CURSOR USING mloadcursor. + YOU MUST ALSO REMEMBER TO CALL mfreemem AT THE END OF THE PROGRAM. + */ + int poow = mousecurs[currentcursor]->GetWidth(); + int pooh = mousecurs[currentcursor]->GetHeight(); + int smx = mousex - hotxwas, smy = mousey - hotywas; + const Rect &viewport = play.GetMainViewport(); + + mgetgraphpos(); + mousex -= hotx; + mousey -= hoty; + + if (mousex + poow >= viewport.GetWidth()) + poow = viewport.GetWidth() - mousex; + + if (mousey + pooh >= viewport.GetHeight()) + pooh = viewport.GetHeight() - mousey; + + mousex += hotx; + mousey += hoty; + hotxwas = hotx; + hotywas = hoty; } -int ismouseinbox(int lf, int tp, int rt, int bt) -{ - if ((mousex >= lf) & (mousex <= rt) & (mousey >= tp) & (mousey <= bt)) - return TRUE; - else - return FALSE; +int ismouseinbox(int lf, int tp, int rt, int bt) { + if ((mousex >= lf) & (mousex <= rt) & (mousey >= tp) & (mousey <= bt)) + return TRUE; + else + return FALSE; } -void mfreemem() -{ - for (int re = 0; re < numcurso; re++) { - delete mousecurs[re]; - } +void mfreemem() { + for (int re = 0; re < numcurso; re++) { + delete mousecurs[re]; + } } -void mloadwcursor(char *namm) -{ - color dummypal[256]; - if (wloadsprites(&dummypal[0], namm, mousecurs, 0, MAXCURSORS)) { - //printf("C_Load_wCursor: Error reading mouse cursor file\n"); - exit(1); - } +void mloadwcursor(char *namm) { + color dummypal[256]; + if (wloadsprites(&dummypal[0], namm, mousecurs, 0, MAXCURSORS)) { + //printf("C_Load_wCursor: Error reading mouse cursor file\n"); + exit(1); + } } int butwas = 0; -int mgetbutton() -{ - int toret = NONE; - poll_mouse(); - int butis = mouse_b; - - if ((butis > 0) & (butwas > 0)) - return NONE; // don't allow holding button down - - if (butis & 1) - { - toret = LEFT; +int mgetbutton() { + int toret = NONE; + poll_mouse(); + int butis = mouse_b; + + if ((butis > 0) & (butwas > 0)) + return NONE; // don't allow holding button down + + if (butis & 1) { + toret = LEFT; #if AGS_SIMULATE_RIGHT_CLICK - // j Ctrl-left click should be right-click - if (ags_iskeypressed(__allegro_KEY_LCONTROL) || ags_iskeypressed(__allegro_KEY_RCONTROL)) - { - toret = RIGHT; - } + // j Ctrl-left click should be right-click + if (ags_iskeypressed(__allegro_KEY_LCONTROL) || ags_iskeypressed(__allegro_KEY_RCONTROL)) { + toret = RIGHT; + } #endif - } - else if (butis & 2) - toret = RIGHT; - else if (butis & 4) - toret = MIDDLE; - - butwas = butis; - return toret; + } else if (butis & 2) + toret = RIGHT; + else if (butis & 4) + toret = MIDDLE; + + butwas = butis; + return toret; } const int MB_ARRAY[3] = { 1, 2, 4 }; -int misbuttondown(int buno) -{ - poll_mouse(); - if (mouse_b & MB_ARRAY[buno]) - return TRUE; - return FALSE; +int misbuttondown(int buno) { + poll_mouse(); + if (mouse_b & MB_ARRAY[buno]) + return TRUE; + return FALSE; } -void msetgraphpos(int xa, int ya) -{ - real_mouse_x = xa; - real_mouse_y = ya; - position_mouse(real_mouse_x, real_mouse_y); +void msetgraphpos(int xa, int ya) { + real_mouse_x = xa; + real_mouse_y = ya; + position_mouse(real_mouse_x, real_mouse_y); } -void msethotspot(int xx, int yy) -{ - hotx = xx; // mousex -= hotx; mousey -= hoty; - hoty = yy; // mousex += hotx; mousey += hoty; +void msethotspot(int xx, int yy) { + hotx = xx; // mousex -= hotx; mousey -= hoty; + hoty = yy; // mousex += hotx; mousey += hoty; } -int minstalled() -{ - return install_mouse(); +int minstalled() { + return install_mouse(); } -void Mouse::AdjustPosition(int &x, int &y) -{ - x = GameScaling.X.UnScalePt(x) - play.GetMainViewport().Left; - y = GameScaling.Y.UnScalePt(y) - play.GetMainViewport().Top; +void Mouse::AdjustPosition(int &x, int &y) { + x = GameScaling.X.UnScalePt(x) - play.GetMainViewport().Left; + y = GameScaling.Y.UnScalePt(y) - play.GetMainViewport().Top; } -void Mouse::SetGraphicArea() -{ - Rect dst_r = GameScaling.ScaleRange(play.GetMainViewport()); - mgraphconfine(dst_r.Left, dst_r.Top, dst_r.Right, dst_r.Bottom); +void Mouse::SetGraphicArea() { + Rect dst_r = GameScaling.ScaleRange(play.GetMainViewport()); + mgraphconfine(dst_r.Left, dst_r.Top, dst_r.Right, dst_r.Bottom); } -void Mouse::SetMoveLimit(const Rect &r) -{ - Rect src_r = OffsetRect(r, play.GetMainViewport().GetLT()); - Rect dst_r = GameScaling.ScaleRange(src_r); - msetcursorlimit(dst_r.Left, dst_r.Top, dst_r.Right, dst_r.Bottom); +void Mouse::SetMoveLimit(const Rect &r) { + Rect src_r = OffsetRect(r, play.GetMainViewport().GetLT()); + Rect dst_r = GameScaling.ScaleRange(src_r); + msetcursorlimit(dst_r.Left, dst_r.Top, dst_r.Right, dst_r.Bottom); } -void Mouse::SetPosition(const Point p) -{ - msetgraphpos(GameScaling.X.ScalePt(p.X + play.GetMainViewport().Left), GameScaling.Y.ScalePt(p.Y + play.GetMainViewport().Top)); +void Mouse::SetPosition(const Point p) { + msetgraphpos(GameScaling.X.ScalePt(p.X + play.GetMainViewport().Left), GameScaling.Y.ScalePt(p.Y + play.GetMainViewport().Top)); } -bool Mouse::IsLockedToWindow() -{ - return LockedToWindow; +bool Mouse::IsLockedToWindow() { + return LockedToWindow; } -bool Mouse::TryLockToWindow() -{ - if (!LockedToWindow) - LockedToWindow = platform->LockMouseToWindow(); - return LockedToWindow; +bool Mouse::TryLockToWindow() { + if (!LockedToWindow) + LockedToWindow = platform->LockMouseToWindow(); + return LockedToWindow; } -void Mouse::UnlockFromWindow() -{ - platform->UnlockMouse(); - LockedToWindow = false; +void Mouse::UnlockFromWindow() { + platform->UnlockMouse(); + LockedToWindow = false; } -void Mouse::EnableControl(bool confine) -{ - ControlEnabled = true; - ConfineInCtrlRect = confine; +void Mouse::EnableControl(bool confine) { + ControlEnabled = true; + ConfineInCtrlRect = confine; } -void Mouse::DisableControl() -{ - ControlEnabled = false; - ConfineInCtrlRect = false; +void Mouse::DisableControl() { + ControlEnabled = false; + ConfineInCtrlRect = false; } -bool Mouse::IsControlEnabled() -{ - return ControlEnabled; +bool Mouse::IsControlEnabled() { + return ControlEnabled; } -void Mouse::SetSpeedUnit(float f) -{ - SpeedUnit = f; - Speed = SpeedVal / SpeedUnit; +void Mouse::SetSpeedUnit(float f) { + SpeedUnit = f; + Speed = SpeedVal / SpeedUnit; } -float Mouse::GetSpeedUnit() -{ - return SpeedUnit; +float Mouse::GetSpeedUnit() { + return SpeedUnit; } -void Mouse::SetSpeed(float speed) -{ - SpeedVal = Math::Max(0.f, speed); - Speed = SpeedUnit * SpeedVal; +void Mouse::SetSpeed(float speed) { + SpeedVal = Math::Max(0.f, speed); + Speed = SpeedUnit * SpeedVal; } -float Mouse::GetSpeed() -{ - return SpeedVal; +float Mouse::GetSpeed() { + return SpeedVal; } diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h index 66c5565ef74f..5bd55bdd62e5 100644 --- a/engines/ags/engine/device/mousew32.h +++ b/engines/ags/engine/device/mousew32.h @@ -37,10 +37,14 @@ #include "util/geometry.h" -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later -void msetgraphpos(int,int); +void msetgraphpos(int, int); // Sets the area of the screen within which the mouse can move void mgraphconfine(int x1, int y1, int x2, int y2); void mgetgraphpos(); @@ -54,41 +58,39 @@ void msetgraphpos(int xa, int ya); void msethotspot(int xx, int yy); int minstalled(); -namespace Mouse -{ - // Get if mouse is locked to the game window - bool IsLockedToWindow(); - // Try locking mouse to the game window - bool TryLockToWindow(); - // Unlock mouse from the game window - void UnlockFromWindow(); +namespace Mouse { +// Get if mouse is locked to the game window +bool IsLockedToWindow(); +// Try locking mouse to the game window +bool TryLockToWindow(); +// Unlock mouse from the game window +void UnlockFromWindow(); - // Enable mouse movement control - void EnableControl(bool confine); - // Disable mouse movement control - void DisableControl(); - // Tell if the mouse movement control is enabled - bool IsControlEnabled(); - // Set base speed factor, which would serve as a mouse speed unit - void SetSpeedUnit(float f); - // Get base speed factor - float GetSpeedUnit(); - // Set speed factors - void SetSpeed(float speed); - // Get speed factor - float GetSpeed(); +// Enable mouse movement control +void EnableControl(bool confine); +// Disable mouse movement control +void DisableControl(); +// Tell if the mouse movement control is enabled +bool IsControlEnabled(); +// Set base speed factor, which would serve as a mouse speed unit +void SetSpeedUnit(float f); +// Get base speed factor +float GetSpeedUnit(); +// Set speed factors +void SetSpeed(float speed); +// Get speed factor +float GetSpeed(); } -namespace Mouse -{ - // Updates limits of the area inside which the standard OS cursor is not shown; - // uses game's main viewport (in native coordinates) to calculate real area on screen - void SetGraphicArea(); - // Limits the area where the game cursor can move on virtual screen; - // parameter must be in native game coordinates - void SetMoveLimit(const Rect &r); - // Set actual OS cursor position on screen; parameter must be in native game coordinates - void SetPosition(const Point p); +namespace Mouse { +// Updates limits of the area inside which the standard OS cursor is not shown; +// uses game's main viewport (in native coordinates) to calculate real area on screen +void SetGraphicArea(); +// Limits the area where the game cursor can move on virtual screen; +// parameter must be in native game coordinates +void SetMoveLimit(const Rect &r); +// Set actual OS cursor position on screen; parameter must be in native game coordinates +void SetPosition(const Point p); } diff --git a/engines/ags/engine/font/fonts_engine.cpp b/engines/ags/engine/font/fonts_engine.cpp index 813c4eb073ef..1f773351cac7 100644 --- a/engines/ags/engine/font/fonts_engine.cpp +++ b/engines/ags/engine/font/fonts_engine.cpp @@ -36,12 +36,10 @@ extern GameSetupStruct game; // Engine-specific implementation split out of acfonts.cpp //============================================================================= -void set_our_eip(int eip) -{ - our_eip = eip; +void set_our_eip(int eip) { + our_eip = eip; } -int get_our_eip() -{ - return our_eip; +int get_our_eip() { + return our_eip; } diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp index fec45ef7a58d..f2b37d1ac010 100644 --- a/engines/ags/engine/game/game_init.cpp +++ b/engines/ags/engine/game/game_init.cpp @@ -57,10 +57,10 @@ using namespace Engine; extern GameSetupStruct game; extern int actSpsCount; extern Bitmap **actsps; -extern IDriverDependantBitmap* *actspsbmp; +extern IDriverDependantBitmap * *actspsbmp; extern Bitmap **actspswb; -extern IDriverDependantBitmap* *actspswbbmp; -extern CachedActSpsData* actspswbcache; +extern IDriverDependantBitmap * *actspswbbmp; +extern CachedActSpsData *actspswbcache; extern CharacterCache *charcache; extern CCGUIObject ccDynamicGUIObject; @@ -82,7 +82,7 @@ extern ScriptInvItem scrInv[MAX_INV]; extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; extern ScriptDialogOptionsRendering ccDialogOptionsRendering; -extern ScriptDrawingSurface* dialogOptionsRenderingSurface; +extern ScriptDrawingSurface *dialogOptionsRenderingSurface; extern AGSStaticObject GlobalStaticManager; @@ -111,374 +111,341 @@ StaticArray StaticInventoryArray; StaticArray StaticDialogArray; -namespace AGS -{ -namespace Engine -{ - -String GetGameInitErrorText(GameInitErrorType err) -{ - switch (err) - { - case kGameInitErr_NoError: - return "No error."; - case kGameInitErr_NoFonts: - return "No fonts specified to be used in this game."; - case kGameInitErr_TooManyAudioTypes: - return "Too many audio types for this engine to handle."; - case kGameInitErr_EntityInitFail: - return "Failed to initialize game entities."; - case kGameInitErr_TooManyPlugins: - return "Too many plugins for this engine to handle."; - case kGameInitErr_PluginNameInvalid: - return "Plugin name is invalid."; - case kGameInitErr_ScriptLinkFailed: - return "Script link failed."; - } - return "Unknown error."; +namespace AGS { +namespace Engine { + +String GetGameInitErrorText(GameInitErrorType err) { + switch (err) { + case kGameInitErr_NoError: + return "No error."; + case kGameInitErr_NoFonts: + return "No fonts specified to be used in this game."; + case kGameInitErr_TooManyAudioTypes: + return "Too many audio types for this engine to handle."; + case kGameInitErr_EntityInitFail: + return "Failed to initialize game entities."; + case kGameInitErr_TooManyPlugins: + return "Too many plugins for this engine to handle."; + case kGameInitErr_PluginNameInvalid: + return "Plugin name is invalid."; + case kGameInitErr_ScriptLinkFailed: + return "Script link failed."; + } + return "Unknown error."; } // Initializes audio channels and clips and registers them in the script system -void InitAndRegisterAudioObjects() -{ - for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) - { - scrAudioChannel[i].id = i; - ccRegisterManagedObject(&scrAudioChannel[i], &ccDynamicAudio); - } - - for (size_t i = 0; i < game.audioClips.size(); ++i) - { - // Note that as of 3.5.0 data format the clip IDs are still restricted - // to actual item index in array, so we don't make any difference - // between game versions, for now. - game.audioClips[i].id = i; - ccRegisterManagedObject(&game.audioClips[i], &ccDynamicAudioClip); - ccAddExternalDynamicObject(game.audioClips[i].scriptName, &game.audioClips[i], &ccDynamicAudioClip); - } +void InitAndRegisterAudioObjects() { + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { + scrAudioChannel[i].id = i; + ccRegisterManagedObject(&scrAudioChannel[i], &ccDynamicAudio); + } + + for (size_t i = 0; i < game.audioClips.size(); ++i) { + // Note that as of 3.5.0 data format the clip IDs are still restricted + // to actual item index in array, so we don't make any difference + // between game versions, for now. + game.audioClips[i].id = i; + ccRegisterManagedObject(&game.audioClips[i], &ccDynamicAudioClip); + ccAddExternalDynamicObject(game.audioClips[i].scriptName, &game.audioClips[i], &ccDynamicAudioClip); + } } // Initializes characters and registers them in the script system -void InitAndRegisterCharacters() -{ - characterScriptObjNames.resize(game.numcharacters); - for (int i = 0; i < game.numcharacters; ++i) - { - game.chars[i].walking = 0; - game.chars[i].animating = 0; - game.chars[i].pic_xoffs = 0; - game.chars[i].pic_yoffs = 0; - game.chars[i].blinkinterval = 140; - game.chars[i].blinktimer = game.chars[i].blinkinterval; - game.chars[i].index_id = i; - game.chars[i].blocking_width = 0; - game.chars[i].blocking_height = 0; - game.chars[i].prevroom = -1; - game.chars[i].loop = 0; - game.chars[i].frame = 0; - game.chars[i].walkwait = -1; - ccRegisterManagedObject(&game.chars[i], &ccDynamicCharacter); - - // export the character's script object - characterScriptObjNames[i] = game.chars[i].scrname; - ccAddExternalDynamicObject(characterScriptObjNames[i], &game.chars[i], &ccDynamicCharacter); - } +void InitAndRegisterCharacters() { + characterScriptObjNames.resize(game.numcharacters); + for (int i = 0; i < game.numcharacters; ++i) { + game.chars[i].walking = 0; + game.chars[i].animating = 0; + game.chars[i].pic_xoffs = 0; + game.chars[i].pic_yoffs = 0; + game.chars[i].blinkinterval = 140; + game.chars[i].blinktimer = game.chars[i].blinkinterval; + game.chars[i].index_id = i; + game.chars[i].blocking_width = 0; + game.chars[i].blocking_height = 0; + game.chars[i].prevroom = -1; + game.chars[i].loop = 0; + game.chars[i].frame = 0; + game.chars[i].walkwait = -1; + ccRegisterManagedObject(&game.chars[i], &ccDynamicCharacter); + + // export the character's script object + characterScriptObjNames[i] = game.chars[i].scrname; + ccAddExternalDynamicObject(characterScriptObjNames[i], &game.chars[i], &ccDynamicCharacter); + } } // Initializes dialog and registers them in the script system -void InitAndRegisterDialogs() -{ - scrDialog = new ScriptDialog[game.numdialog]; - for (int i = 0; i < game.numdialog; ++i) - { - scrDialog[i].id = i; - scrDialog[i].reserved = 0; - ccRegisterManagedObject(&scrDialog[i], &ccDynamicDialog); - - if (!game.dialogScriptNames[i].IsEmpty()) - ccAddExternalDynamicObject(game.dialogScriptNames[i], &scrDialog[i], &ccDynamicDialog); - } +void InitAndRegisterDialogs() { + scrDialog = new ScriptDialog[game.numdialog]; + for (int i = 0; i < game.numdialog; ++i) { + scrDialog[i].id = i; + scrDialog[i].reserved = 0; + ccRegisterManagedObject(&scrDialog[i], &ccDynamicDialog); + + if (!game.dialogScriptNames[i].IsEmpty()) + ccAddExternalDynamicObject(game.dialogScriptNames[i], &scrDialog[i], &ccDynamicDialog); + } } // Initializes dialog options rendering objects and registers them in the script system -void InitAndRegisterDialogOptions() -{ - ccRegisterManagedObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); - - dialogOptionsRenderingSurface = new ScriptDrawingSurface(); - dialogOptionsRenderingSurface->isLinkedBitmapOnly = true; - long dorsHandle = ccRegisterManagedObject(dialogOptionsRenderingSurface, dialogOptionsRenderingSurface); - ccAddObjectReference(dorsHandle); +void InitAndRegisterDialogOptions() { + ccRegisterManagedObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); + + dialogOptionsRenderingSurface = new ScriptDrawingSurface(); + dialogOptionsRenderingSurface->isLinkedBitmapOnly = true; + long dorsHandle = ccRegisterManagedObject(dialogOptionsRenderingSurface, dialogOptionsRenderingSurface); + ccAddObjectReference(dorsHandle); } // Initializes gui and registers them in the script system -HError InitAndRegisterGUI() -{ - scrGui = (ScriptGUI*)malloc(sizeof(ScriptGUI) * game.numgui); - for (int i = 0; i < game.numgui; ++i) - { - scrGui[i].id = -1; - } - - guiScriptObjNames.resize(game.numgui); - for (int i = 0; i < game.numgui; ++i) - { - // link controls to their parent guis - HError err = guis[i].RebuildArray(); - if (!err) - return err; - // export all the GUI's controls - export_gui_controls(i); - // copy the script name to its own memory location - // because ccAddExtSymbol only keeps a reference - guiScriptObjNames[i] = guis[i].Name; - scrGui[i].id = i; - ccAddExternalDynamicObject(guiScriptObjNames[i], &scrGui[i], &ccDynamicGUI); - ccRegisterManagedObject(&scrGui[i], &ccDynamicGUI); - } - return HError::None(); +HError InitAndRegisterGUI() { + scrGui = (ScriptGUI *)malloc(sizeof(ScriptGUI) * game.numgui); + for (int i = 0; i < game.numgui; ++i) { + scrGui[i].id = -1; + } + + guiScriptObjNames.resize(game.numgui); + for (int i = 0; i < game.numgui; ++i) { + // link controls to their parent guis + HError err = guis[i].RebuildArray(); + if (!err) + return err; + // export all the GUI's controls + export_gui_controls(i); + // copy the script name to its own memory location + // because ccAddExtSymbol only keeps a reference + guiScriptObjNames[i] = guis[i].Name; + scrGui[i].id = i; + ccAddExternalDynamicObject(guiScriptObjNames[i], &scrGui[i], &ccDynamicGUI); + ccRegisterManagedObject(&scrGui[i], &ccDynamicGUI); + } + return HError::None(); } // Initializes inventory items and registers them in the script system -void InitAndRegisterInvItems() -{ - for (int i = 0; i < MAX_INV; ++i) - { - scrInv[i].id = i; - scrInv[i].reserved = 0; - ccRegisterManagedObject(&scrInv[i], &ccDynamicInv); - - if (!game.invScriptNames[i].IsEmpty()) - ccAddExternalDynamicObject(game.invScriptNames[i], &scrInv[i], &ccDynamicInv); - } +void InitAndRegisterInvItems() { + for (int i = 0; i < MAX_INV; ++i) { + scrInv[i].id = i; + scrInv[i].reserved = 0; + ccRegisterManagedObject(&scrInv[i], &ccDynamicInv); + + if (!game.invScriptNames[i].IsEmpty()) + ccAddExternalDynamicObject(game.invScriptNames[i], &scrInv[i], &ccDynamicInv); + } } // Initializes room hotspots and registers them in the script system -void InitAndRegisterHotspots() -{ - for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) - { - scrHotspot[i].id = i; - scrHotspot[i].reserved = 0; - ccRegisterManagedObject(&scrHotspot[i], &ccDynamicHotspot); - } +void InitAndRegisterHotspots() { + for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) { + scrHotspot[i].id = i; + scrHotspot[i].reserved = 0; + ccRegisterManagedObject(&scrHotspot[i], &ccDynamicHotspot); + } } // Initializes room objects and registers them in the script system -void InitAndRegisterRoomObjects() -{ - for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) - { - ccRegisterManagedObject(&scrObj[i], &ccDynamicObject); - } +void InitAndRegisterRoomObjects() { + for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) { + ccRegisterManagedObject(&scrObj[i], &ccDynamicObject); + } } // Initializes room regions and registers them in the script system -void InitAndRegisterRegions() -{ - for (int i = 0; i < MAX_ROOM_REGIONS; ++i) - { - scrRegion[i].id = i; - scrRegion[i].reserved = 0; - ccRegisterManagedObject(&scrRegion[i], &ccDynamicRegion); - } +void InitAndRegisterRegions() { + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) { + scrRegion[i].id = i; + scrRegion[i].reserved = 0; + ccRegisterManagedObject(&scrRegion[i], &ccDynamicRegion); + } } // Registers static entity arrays in the script system -void RegisterStaticArrays() -{ - StaticCharacterArray.Create(&ccDynamicCharacter, sizeof(CharacterInfo), sizeof(CharacterInfo)); - StaticObjectArray.Create(&ccDynamicObject, sizeof(ScriptObject), sizeof(ScriptObject)); - StaticGUIArray.Create(&ccDynamicGUI, sizeof(ScriptGUI), sizeof(ScriptGUI)); - StaticHotspotArray.Create(&ccDynamicHotspot, sizeof(ScriptHotspot), sizeof(ScriptHotspot)); - StaticRegionArray.Create(&ccDynamicRegion, sizeof(ScriptRegion), sizeof(ScriptRegion)); - StaticInventoryArray.Create(&ccDynamicInv, sizeof(ScriptInvItem), sizeof(ScriptInvItem)); - StaticDialogArray.Create(&ccDynamicDialog, sizeof(ScriptDialog), sizeof(ScriptDialog)); - - ccAddExternalStaticArray("character",&game.chars[0], &StaticCharacterArray); - ccAddExternalStaticArray("object",&scrObj[0], &StaticObjectArray); - ccAddExternalStaticArray("gui",&scrGui[0], &StaticGUIArray); - ccAddExternalStaticArray("hotspot",&scrHotspot[0], &StaticHotspotArray); - ccAddExternalStaticArray("region",&scrRegion[0], &StaticRegionArray); - ccAddExternalStaticArray("inventory",&scrInv[0], &StaticInventoryArray); - ccAddExternalStaticArray("dialog", &scrDialog[0], &StaticDialogArray); +void RegisterStaticArrays() { + StaticCharacterArray.Create(&ccDynamicCharacter, sizeof(CharacterInfo), sizeof(CharacterInfo)); + StaticObjectArray.Create(&ccDynamicObject, sizeof(ScriptObject), sizeof(ScriptObject)); + StaticGUIArray.Create(&ccDynamicGUI, sizeof(ScriptGUI), sizeof(ScriptGUI)); + StaticHotspotArray.Create(&ccDynamicHotspot, sizeof(ScriptHotspot), sizeof(ScriptHotspot)); + StaticRegionArray.Create(&ccDynamicRegion, sizeof(ScriptRegion), sizeof(ScriptRegion)); + StaticInventoryArray.Create(&ccDynamicInv, sizeof(ScriptInvItem), sizeof(ScriptInvItem)); + StaticDialogArray.Create(&ccDynamicDialog, sizeof(ScriptDialog), sizeof(ScriptDialog)); + + ccAddExternalStaticArray("character", &game.chars[0], &StaticCharacterArray); + ccAddExternalStaticArray("object", &scrObj[0], &StaticObjectArray); + ccAddExternalStaticArray("gui", &scrGui[0], &StaticGUIArray); + ccAddExternalStaticArray("hotspot", &scrHotspot[0], &StaticHotspotArray); + ccAddExternalStaticArray("region", &scrRegion[0], &StaticRegionArray); + ccAddExternalStaticArray("inventory", &scrInv[0], &StaticInventoryArray); + ccAddExternalStaticArray("dialog", &scrDialog[0], &StaticDialogArray); } // Initializes various game entities and registers them in the script system -HError InitAndRegisterGameEntities() -{ - InitAndRegisterAudioObjects(); - InitAndRegisterCharacters(); - InitAndRegisterDialogs(); - InitAndRegisterDialogOptions(); - HError err = InitAndRegisterGUI(); - if (!err) - return err; - InitAndRegisterInvItems(); - - InitAndRegisterHotspots(); - InitAndRegisterRegions(); - InitAndRegisterRoomObjects(); - play.CreatePrimaryViewportAndCamera(); - - RegisterStaticArrays(); - - setup_player_character(game.playercharacter); - if (loaded_game_file_version >= kGameVersion_270) - ccAddExternalStaticObject("player", &_sc_PlayerCharPtr, &GlobalStaticManager); - return HError::None(); +HError InitAndRegisterGameEntities() { + InitAndRegisterAudioObjects(); + InitAndRegisterCharacters(); + InitAndRegisterDialogs(); + InitAndRegisterDialogOptions(); + HError err = InitAndRegisterGUI(); + if (!err) + return err; + InitAndRegisterInvItems(); + + InitAndRegisterHotspots(); + InitAndRegisterRegions(); + InitAndRegisterRoomObjects(); + play.CreatePrimaryViewportAndCamera(); + + RegisterStaticArrays(); + + setup_player_character(game.playercharacter); + if (loaded_game_file_version >= kGameVersion_270) + ccAddExternalStaticObject("player", &_sc_PlayerCharPtr, &GlobalStaticManager); + return HError::None(); } -void LoadFonts(GameDataVersion data_ver) -{ - for (int i = 0; i < game.numfonts; ++i) - { - if (!wloadfont_size(i, game.fonts[i])) - quitprintf("Unable to load font %d, no renderer could load a matching file", i); - } +void LoadFonts(GameDataVersion data_ver) { + for (int i = 0; i < game.numfonts; ++i) { + if (!wloadfont_size(i, game.fonts[i])) + quitprintf("Unable to load font %d, no renderer could load a matching file", i); + } } -void AllocScriptModules() -{ - moduleInst.resize(numScriptModules, nullptr); - moduleInstFork.resize(numScriptModules, nullptr); - moduleRepExecAddr.resize(numScriptModules); - repExecAlways.moduleHasFunction.resize(numScriptModules, true); - lateRepExecAlways.moduleHasFunction.resize(numScriptModules, true); - getDialogOptionsDimensionsFunc.moduleHasFunction.resize(numScriptModules, true); - renderDialogOptionsFunc.moduleHasFunction.resize(numScriptModules, true); - getDialogOptionUnderCursorFunc.moduleHasFunction.resize(numScriptModules, true); - runDialogOptionMouseClickHandlerFunc.moduleHasFunction.resize(numScriptModules, true); - runDialogOptionKeyPressHandlerFunc.moduleHasFunction.resize(numScriptModules, true); - runDialogOptionRepExecFunc.moduleHasFunction.resize(numScriptModules, true); - for (int i = 0; i < numScriptModules; ++i) - { - moduleRepExecAddr[i].Invalidate(); - } +void AllocScriptModules() { + moduleInst.resize(numScriptModules, nullptr); + moduleInstFork.resize(numScriptModules, nullptr); + moduleRepExecAddr.resize(numScriptModules); + repExecAlways.moduleHasFunction.resize(numScriptModules, true); + lateRepExecAlways.moduleHasFunction.resize(numScriptModules, true); + getDialogOptionsDimensionsFunc.moduleHasFunction.resize(numScriptModules, true); + renderDialogOptionsFunc.moduleHasFunction.resize(numScriptModules, true); + getDialogOptionUnderCursorFunc.moduleHasFunction.resize(numScriptModules, true); + runDialogOptionMouseClickHandlerFunc.moduleHasFunction.resize(numScriptModules, true); + runDialogOptionKeyPressHandlerFunc.moduleHasFunction.resize(numScriptModules, true); + runDialogOptionRepExecFunc.moduleHasFunction.resize(numScriptModules, true); + for (int i = 0; i < numScriptModules; ++i) { + moduleRepExecAddr[i].Invalidate(); + } } -HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion data_ver) -{ - const ScriptAPIVersion base_api = (ScriptAPIVersion)game.options[OPT_BASESCRIPTAPI]; - const ScriptAPIVersion compat_api = (ScriptAPIVersion)game.options[OPT_SCRIPTCOMPATLEV]; - if (data_ver >= kGameVersion_341) - { - // TODO: find a way to either automate this list of strings or make it more visible (shared & easier to find in engine code) - // TODO: stack-allocated strings, here and in other similar places - const String scapi_names[kScriptAPI_Current + 1] = {"v3.2.1", "v3.3.0", "v3.3.4", "v3.3.5", "v3.4.0", "v3.4.1", "v3.5.0", "v3.5.0.7"}; - Debug::Printf(kDbgMsg_Info, "Requested script API: %s (%d), compat level: %s (%d)", - base_api >= 0 && base_api <= kScriptAPI_Current ? scapi_names[base_api].GetCStr() : "unknown", base_api, - compat_api >= 0 && compat_api <= kScriptAPI_Current ? scapi_names[compat_api].GetCStr() : "unknown", compat_api); - } - // If the game was compiled using unsupported version of the script API, - // we warn about potential incompatibilities but proceed further. - if (game.options[OPT_BASESCRIPTAPI] > kScriptAPI_Current) - platform->DisplayAlert("Warning: this game requests a higher version of AGS script API, it may not run correctly or run at all."); - - // - // 1. Check that the loaded data is valid and compatible with the current - // engine capabilities. - // - if (game.numfonts == 0) - return new GameInitError(kGameInitErr_NoFonts); - if (game.audioClipTypes.size() > MAX_AUDIO_TYPES) - return new GameInitError(kGameInitErr_TooManyAudioTypes, String::FromFormat("Required: %u, max: %d", game.audioClipTypes.size(), MAX_AUDIO_TYPES)); - - // - // 2. Apply overriding config settings - // - // The earlier versions of AGS provided support for "upscaling" low-res - // games (320x200 and 320x240) to hi-res (640x400 and 640x480 - // respectively). The script API has means for detecting if the game is - // running upscaled, and game developer could use this opportunity to setup - // game accordingly (e.g. assign hi-res fonts, etc). - // This feature is officially deprecated since 3.1.0, however the engine - // itself still supports it, technically. - // This overriding option re-enables "upscaling". It works ONLY for low-res - // resolutions, such as 320x200 and 320x240. - if (usetup.override_upscale) - { - if (game.GetResolutionType() == kGameResolution_320x200) - game.SetGameResolution(kGameResolution_640x400); - else if (game.GetResolutionType() == kGameResolution_320x240) - game.SetGameResolution(kGameResolution_640x480); - } - - // - // 3. Allocate and init game objects - // - charextra = (CharacterExtras*)calloc(game.numcharacters, sizeof(CharacterExtras)); - charcache = (CharacterCache*)calloc(1,sizeof(CharacterCache)*game.numcharacters+5); - mls = (MoveList*)calloc(game.numcharacters + MAX_ROOM_OBJECTS + 1, sizeof(MoveList)); - actSpsCount = game.numcharacters + MAX_ROOM_OBJECTS + 2; - actsps = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *)); - actspsbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*)); - actspswb = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *)); - actspswbbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*)); - actspswbcache = (CachedActSpsData*)calloc(actSpsCount, sizeof(CachedActSpsData)); - play.charProps.resize(game.numcharacters); - old_dialog_scripts = ents.OldDialogScripts; - old_speech_lines = ents.OldSpeechLines; - HError err = InitAndRegisterGameEntities(); - if (!err) - return new GameInitError(kGameInitErr_EntityInitFail, err); - LoadFonts(data_ver); - - // - // 4. Initialize certain runtime variables - // - game_paused = 0; // reset the game paused flag - ifacepopped = -1; - - String svg_suffix; - if (game.saveGameFileExtension[0] != 0) - svg_suffix.Format(".%s", game.saveGameFileExtension); - set_save_game_suffix(svg_suffix); - - play.score_sound = game.scoreClipID; - play.fade_effect = game.options[OPT_FADETYPE]; - - // - // 5. Initialize runtime state of certain game objects - // - for (int i = 0; i < numguilabels; ++i) - { - // labels are not clickable by default - guilabels[i].SetClickable(false); - } - play.gui_draw_order = (int*)calloc(game.numgui * sizeof(int), 1); - update_gui_zorder(); - calculate_reserved_channel_count(); - - // - // 6. Register engine API exports - // NOTE: we must do this before plugin start, because some plugins may - // require access to script API at initialization time. - // - ccSetScriptAliveTimer(150000); - ccSetStringClassImpl(&myScriptStringImpl); - setup_script_exports(base_api, compat_api); - - // - // 7. Start up plugins - // - pl_register_plugins(ents.PluginInfos); - pl_startup_plugins(); - - // - // 8. Create script modules - // NOTE: we must do this after plugins, because some plugins may export - // script symbols too. - // - gamescript = ents.GlobalScript; - dialogScriptsScript = ents.DialogScript; - numScriptModules = ents.ScriptModules.size(); - scriptModules = ents.ScriptModules; - AllocScriptModules(); - if (create_global_script()) - return new GameInitError(kGameInitErr_ScriptLinkFailed, ccErrorString); - - return HGameInitError::None(); +HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion data_ver) { + const ScriptAPIVersion base_api = (ScriptAPIVersion)game.options[OPT_BASESCRIPTAPI]; + const ScriptAPIVersion compat_api = (ScriptAPIVersion)game.options[OPT_SCRIPTCOMPATLEV]; + if (data_ver >= kGameVersion_341) { + // TODO: find a way to either automate this list of strings or make it more visible (shared & easier to find in engine code) + // TODO: stack-allocated strings, here and in other similar places + const String scapi_names[kScriptAPI_Current + 1] = {"v3.2.1", "v3.3.0", "v3.3.4", "v3.3.5", "v3.4.0", "v3.4.1", "v3.5.0", "v3.5.0.7"}; + Debug::Printf(kDbgMsg_Info, "Requested script API: %s (%d), compat level: %s (%d)", + base_api >= 0 && base_api <= kScriptAPI_Current ? scapi_names[base_api].GetCStr() : "unknown", base_api, + compat_api >= 0 && compat_api <= kScriptAPI_Current ? scapi_names[compat_api].GetCStr() : "unknown", compat_api); + } + // If the game was compiled using unsupported version of the script API, + // we warn about potential incompatibilities but proceed further. + if (game.options[OPT_BASESCRIPTAPI] > kScriptAPI_Current) + platform->DisplayAlert("Warning: this game requests a higher version of AGS script API, it may not run correctly or run at all."); + + // + // 1. Check that the loaded data is valid and compatible with the current + // engine capabilities. + // + if (game.numfonts == 0) + return new GameInitError(kGameInitErr_NoFonts); + if (game.audioClipTypes.size() > MAX_AUDIO_TYPES) + return new GameInitError(kGameInitErr_TooManyAudioTypes, String::FromFormat("Required: %u, max: %d", game.audioClipTypes.size(), MAX_AUDIO_TYPES)); + + // + // 2. Apply overriding config settings + // + // The earlier versions of AGS provided support for "upscaling" low-res + // games (320x200 and 320x240) to hi-res (640x400 and 640x480 + // respectively). The script API has means for detecting if the game is + // running upscaled, and game developer could use this opportunity to setup + // game accordingly (e.g. assign hi-res fonts, etc). + // This feature is officially deprecated since 3.1.0, however the engine + // itself still supports it, technically. + // This overriding option re-enables "upscaling". It works ONLY for low-res + // resolutions, such as 320x200 and 320x240. + if (usetup.override_upscale) { + if (game.GetResolutionType() == kGameResolution_320x200) + game.SetGameResolution(kGameResolution_640x400); + else if (game.GetResolutionType() == kGameResolution_320x240) + game.SetGameResolution(kGameResolution_640x480); + } + + // + // 3. Allocate and init game objects + // + charextra = (CharacterExtras *)calloc(game.numcharacters, sizeof(CharacterExtras)); + charcache = (CharacterCache *)calloc(1, sizeof(CharacterCache) * game.numcharacters + 5); + mls = (MoveList *)calloc(game.numcharacters + MAX_ROOM_OBJECTS + 1, sizeof(MoveList)); + actSpsCount = game.numcharacters + MAX_ROOM_OBJECTS + 2; + actsps = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *)); + actspsbmp = (IDriverDependantBitmap **)calloc(actSpsCount, sizeof(IDriverDependantBitmap *)); + actspswb = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *)); + actspswbbmp = (IDriverDependantBitmap **)calloc(actSpsCount, sizeof(IDriverDependantBitmap *)); + actspswbcache = (CachedActSpsData *)calloc(actSpsCount, sizeof(CachedActSpsData)); + play.charProps.resize(game.numcharacters); + old_dialog_scripts = ents.OldDialogScripts; + old_speech_lines = ents.OldSpeechLines; + HError err = InitAndRegisterGameEntities(); + if (!err) + return new GameInitError(kGameInitErr_EntityInitFail, err); + LoadFonts(data_ver); + + // + // 4. Initialize certain runtime variables + // + game_paused = 0; // reset the game paused flag + ifacepopped = -1; + + String svg_suffix; + if (game.saveGameFileExtension[0] != 0) + svg_suffix.Format(".%s", game.saveGameFileExtension); + set_save_game_suffix(svg_suffix); + + play.score_sound = game.scoreClipID; + play.fade_effect = game.options[OPT_FADETYPE]; + + // + // 5. Initialize runtime state of certain game objects + // + for (int i = 0; i < numguilabels; ++i) { + // labels are not clickable by default + guilabels[i].SetClickable(false); + } + play.gui_draw_order = (int *)calloc(game.numgui * sizeof(int), 1); + update_gui_zorder(); + calculate_reserved_channel_count(); + + // + // 6. Register engine API exports + // NOTE: we must do this before plugin start, because some plugins may + // require access to script API at initialization time. + // + ccSetScriptAliveTimer(150000); + ccSetStringClassImpl(&myScriptStringImpl); + setup_script_exports(base_api, compat_api); + + // + // 7. Start up plugins + // + pl_register_plugins(ents.PluginInfos); + pl_startup_plugins(); + + // + // 8. Create script modules + // NOTE: we must do this after plugins, because some plugins may export + // script symbols too. + // + gamescript = ents.GlobalScript; + dialogScriptsScript = ents.DialogScript; + numScriptModules = ents.ScriptModules.size(); + scriptModules = ents.ScriptModules; + AllocScriptModules(); + if (create_global_script()) + return new GameInitError(kGameInitErr_ScriptLinkFailed, ccErrorString); + + return HGameInitError::None(); } } // namespace Engine diff --git a/engines/ags/engine/game/game_init.h b/engines/ags/engine/game/game_init.h index 89ce79c917bd..0ce363d62646 100644 --- a/engines/ags/engine/game/game_init.h +++ b/engines/ags/engine/game/game_init.h @@ -33,24 +33,21 @@ #include "game/main_game_file.h" #include "util/string.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using namespace Common; // Error codes for initializing the game -enum GameInitErrorType -{ - kGameInitErr_NoError, - // currently AGS requires at least one font to be present in game - kGameInitErr_NoFonts, - kGameInitErr_TooManyAudioTypes, - kGameInitErr_EntityInitFail, - kGameInitErr_TooManyPlugins, - kGameInitErr_PluginNameInvalid, - kGameInitErr_ScriptLinkFailed +enum GameInitErrorType { + kGameInitErr_NoError, + // currently AGS requires at least one font to be present in game + kGameInitErr_NoFonts, + kGameInitErr_TooManyAudioTypes, + kGameInitErr_EntityInitFail, + kGameInitErr_TooManyPlugins, + kGameInitErr_PluginNameInvalid, + kGameInitErr_ScriptLinkFailed }; String GetGameInitErrorText(GameInitErrorType err); diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index 5cfd5407ba97..fcafebf060df 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -78,728 +78,659 @@ extern RoomStatus troom; extern RoomStatus *croom; -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { const String SavegameSource::LegacySignature = "Adventure Game Studio saved game"; const String SavegameSource::Signature = "Adventure Game Studio saved game v2"; SavegameSource::SavegameSource() - : Version(kSvgVersion_Undefined) -{ + : Version(kSvgVersion_Undefined) { } SavegameDescription::SavegameDescription() - : MainDataVersion(kGameVersion_Undefined) - , ColorDepth(0) -{ + : MainDataVersion(kGameVersion_Undefined) + , ColorDepth(0) { } PreservedParams::PreservedParams() - : SpeechVOX(0) - , MusicVOX(0) - , GlScDataSize(0) -{ + : SpeechVOX(0) + , MusicVOX(0) + , GlScDataSize(0) { } RestoredData::ScriptData::ScriptData() - : Len(0) -{ + : Len(0) { } RestoredData::RestoredData() - : FPS(0) - , RoomVolume(kRoomVolumeNormal) - , CursorID(0) - , CursorMode(0) -{ - memset(RoomLightLevels, 0, sizeof(RoomLightLevels)); - memset(RoomTintLevels, 0, sizeof(RoomTintLevels)); - memset(RoomZoomLevels1, 0, sizeof(RoomZoomLevels1)); - memset(RoomZoomLevels2, 0, sizeof(RoomZoomLevels2)); - memset(DoAmbient, 0, sizeof(DoAmbient)); + : FPS(0) + , RoomVolume(kRoomVolumeNormal) + , CursorID(0) + , CursorMode(0) { + memset(RoomLightLevels, 0, sizeof(RoomLightLevels)); + memset(RoomTintLevels, 0, sizeof(RoomTintLevels)); + memset(RoomZoomLevels1, 0, sizeof(RoomZoomLevels1)); + memset(RoomZoomLevels2, 0, sizeof(RoomZoomLevels2)); + memset(DoAmbient, 0, sizeof(DoAmbient)); } -String GetSavegameErrorText(SavegameErrorType err) -{ - switch (err) - { - case kSvgErr_NoError: - return "No error."; - case kSvgErr_FileOpenFailed: - return "File not found or could not be opened."; - case kSvgErr_SignatureFailed: - return "Not an AGS saved game or unsupported format."; - case kSvgErr_FormatVersionNotSupported: - return "Save format version not supported."; - case kSvgErr_IncompatibleEngine: - return "Save was written by incompatible engine, or file is corrupted."; - case kSvgErr_GameGuidMismatch: - return "Game GUID does not match, saved by a different game."; - case kSvgErr_ComponentListOpeningTagFormat: - return "Failed to parse opening tag of the components list."; - case kSvgErr_ComponentListClosingTagMissing: - return "Closing tag of the components list was not met."; - case kSvgErr_ComponentOpeningTagFormat: - return "Failed to parse opening component tag."; - case kSvgErr_ComponentClosingTagFormat: - return "Failed to parse closing component tag."; - case kSvgErr_ComponentSizeMismatch: - return "Component data size mismatch."; - case kSvgErr_UnsupportedComponent: - return "Unknown and/or unsupported component."; - case kSvgErr_ComponentSerialization: - return "Failed to write the savegame component."; - case kSvgErr_ComponentUnserialization: - return "Failed to restore the savegame component."; - case kSvgErr_InconsistentFormat: - return "Inconsistent format, or file is corrupted."; - case kSvgErr_UnsupportedComponentVersion: - return "Component data version not supported."; - case kSvgErr_GameContentAssertion: - return "Saved content does not match current game."; - case kSvgErr_InconsistentData: - return "Inconsistent save data, or file is corrupted."; - case kSvgErr_InconsistentPlugin: - return "One of the game plugins did not restore its game data correctly."; - case kSvgErr_DifferentColorDepth: - return "Saved with the engine running at a different colour depth."; - case kSvgErr_GameObjectInitFailed: - return "Game object initialization failed after save restoration."; - } - return "Unknown error."; +String GetSavegameErrorText(SavegameErrorType err) { + switch (err) { + case kSvgErr_NoError: + return "No error."; + case kSvgErr_FileOpenFailed: + return "File not found or could not be opened."; + case kSvgErr_SignatureFailed: + return "Not an AGS saved game or unsupported format."; + case kSvgErr_FormatVersionNotSupported: + return "Save format version not supported."; + case kSvgErr_IncompatibleEngine: + return "Save was written by incompatible engine, or file is corrupted."; + case kSvgErr_GameGuidMismatch: + return "Game GUID does not match, saved by a different game."; + case kSvgErr_ComponentListOpeningTagFormat: + return "Failed to parse opening tag of the components list."; + case kSvgErr_ComponentListClosingTagMissing: + return "Closing tag of the components list was not met."; + case kSvgErr_ComponentOpeningTagFormat: + return "Failed to parse opening component tag."; + case kSvgErr_ComponentClosingTagFormat: + return "Failed to parse closing component tag."; + case kSvgErr_ComponentSizeMismatch: + return "Component data size mismatch."; + case kSvgErr_UnsupportedComponent: + return "Unknown and/or unsupported component."; + case kSvgErr_ComponentSerialization: + return "Failed to write the savegame component."; + case kSvgErr_ComponentUnserialization: + return "Failed to restore the savegame component."; + case kSvgErr_InconsistentFormat: + return "Inconsistent format, or file is corrupted."; + case kSvgErr_UnsupportedComponentVersion: + return "Component data version not supported."; + case kSvgErr_GameContentAssertion: + return "Saved content does not match current game."; + case kSvgErr_InconsistentData: + return "Inconsistent save data, or file is corrupted."; + case kSvgErr_InconsistentPlugin: + return "One of the game plugins did not restore its game data correctly."; + case kSvgErr_DifferentColorDepth: + return "Saved with the engine running at a different colour depth."; + case kSvgErr_GameObjectInitFailed: + return "Game object initialization failed after save restoration."; + } + return "Unknown error."; } -Bitmap *RestoreSaveImage(Stream *in) -{ - if (in->ReadInt32()) - return read_serialized_bitmap(in); - return nullptr; +Bitmap *RestoreSaveImage(Stream *in) { + if (in->ReadInt32()) + return read_serialized_bitmap(in); + return nullptr; } -void SkipSaveImage(Stream *in) -{ - if (in->ReadInt32()) - skip_serialized_bitmap(in); +void SkipSaveImage(Stream *in) { + if (in->ReadInt32()) + skip_serialized_bitmap(in); } -HSaveError ReadDescription(Stream *in, SavegameVersion &svg_ver, SavegameDescription &desc, SavegameDescElem elems) -{ - svg_ver = (SavegameVersion)in->ReadInt32(); - if (svg_ver < kSvgVersion_LowestSupported || svg_ver > kSvgVersion_Current) - return new SavegameError(kSvgErr_FormatVersionNotSupported, - String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); - - // Enviroment information - if (elems & kSvgDesc_EnvInfo) - { - desc.EngineName = StrUtil::ReadString(in); - desc.EngineVersion.SetFromString(StrUtil::ReadString(in)); - desc.GameGuid = StrUtil::ReadString(in); - desc.GameTitle = StrUtil::ReadString(in); - desc.MainDataFilename = StrUtil::ReadString(in); - if (svg_ver >= kSvgVersion_Cmp_64bit) - desc.MainDataVersion = (GameDataVersion)in->ReadInt32(); - desc.ColorDepth = in->ReadInt32(); - } - else - { - StrUtil::SkipString(in); - StrUtil::SkipString(in); - StrUtil::SkipString(in); - StrUtil::SkipString(in); - StrUtil::SkipString(in); - if (svg_ver >= kSvgVersion_Cmp_64bit) - in->ReadInt32(); // game data version - in->ReadInt32(); // color depth - } - // User description - if (elems & kSvgDesc_UserText) - desc.UserText = StrUtil::ReadString(in); - else - StrUtil::SkipString(in); - if (elems & kSvgDesc_UserImage) - desc.UserImage.reset(RestoreSaveImage(in)); - else - SkipSaveImage(in); - - return HSaveError::None(); +HSaveError ReadDescription(Stream *in, SavegameVersion &svg_ver, SavegameDescription &desc, SavegameDescElem elems) { + svg_ver = (SavegameVersion)in->ReadInt32(); + if (svg_ver < kSvgVersion_LowestSupported || svg_ver > kSvgVersion_Current) + return new SavegameError(kSvgErr_FormatVersionNotSupported, + String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); + + // Enviroment information + if (elems & kSvgDesc_EnvInfo) { + desc.EngineName = StrUtil::ReadString(in); + desc.EngineVersion.SetFromString(StrUtil::ReadString(in)); + desc.GameGuid = StrUtil::ReadString(in); + desc.GameTitle = StrUtil::ReadString(in); + desc.MainDataFilename = StrUtil::ReadString(in); + if (svg_ver >= kSvgVersion_Cmp_64bit) + desc.MainDataVersion = (GameDataVersion)in->ReadInt32(); + desc.ColorDepth = in->ReadInt32(); + } else { + StrUtil::SkipString(in); + StrUtil::SkipString(in); + StrUtil::SkipString(in); + StrUtil::SkipString(in); + StrUtil::SkipString(in); + if (svg_ver >= kSvgVersion_Cmp_64bit) + in->ReadInt32(); // game data version + in->ReadInt32(); // color depth + } + // User description + if (elems & kSvgDesc_UserText) + desc.UserText = StrUtil::ReadString(in); + else + StrUtil::SkipString(in); + if (elems & kSvgDesc_UserImage) + desc.UserImage.reset(RestoreSaveImage(in)); + else + SkipSaveImage(in); + + return HSaveError::None(); } -HSaveError ReadDescription_v321(Stream *in, SavegameVersion &svg_ver, SavegameDescription &desc, SavegameDescElem elems) -{ - // Legacy savegame header - if (elems & kSvgDesc_UserText) - desc.UserText.Read(in); - else - StrUtil::SkipCStr(in); - svg_ver = (SavegameVersion)in->ReadInt32(); - - // Check saved game format version - if (svg_ver < kSvgVersion_LowestSupported || - svg_ver > kSvgVersion_Current) - { - return new SavegameError(kSvgErr_FormatVersionNotSupported, - String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); - } - - if (elems & kSvgDesc_UserImage) - desc.UserImage.reset(RestoreSaveImage(in)); - else - SkipSaveImage(in); - - String version_str = String::FromStream(in); - Version eng_version(version_str); - if (eng_version > EngineVersion || - eng_version < SavedgameLowestBackwardCompatVersion) - { - // Engine version is either non-forward or non-backward compatible - return new SavegameError(kSvgErr_IncompatibleEngine, - String::FromFormat("Required: %s, supported: %s - %s.", eng_version.LongString.GetCStr(), SavedgameLowestBackwardCompatVersion.LongString.GetCStr(), EngineVersion.LongString.GetCStr())); - } - if (elems & kSvgDesc_EnvInfo) - { - desc.MainDataFilename.Read(in); - in->ReadInt32(); // unscaled game height with borders, now obsolete - desc.ColorDepth = in->ReadInt32(); - } - else - { - StrUtil::SkipCStr(in); - in->ReadInt32(); // unscaled game height with borders, now obsolete - in->ReadInt32(); // color depth - } - - return HSaveError::None(); +HSaveError ReadDescription_v321(Stream *in, SavegameVersion &svg_ver, SavegameDescription &desc, SavegameDescElem elems) { + // Legacy savegame header + if (elems & kSvgDesc_UserText) + desc.UserText.Read(in); + else + StrUtil::SkipCStr(in); + svg_ver = (SavegameVersion)in->ReadInt32(); + + // Check saved game format version + if (svg_ver < kSvgVersion_LowestSupported || + svg_ver > kSvgVersion_Current) { + return new SavegameError(kSvgErr_FormatVersionNotSupported, + String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); + } + + if (elems & kSvgDesc_UserImage) + desc.UserImage.reset(RestoreSaveImage(in)); + else + SkipSaveImage(in); + + String version_str = String::FromStream(in); + Version eng_version(version_str); + if (eng_version > EngineVersion || + eng_version < SavedgameLowestBackwardCompatVersion) { + // Engine version is either non-forward or non-backward compatible + return new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Required: %s, supported: %s - %s.", eng_version.LongString.GetCStr(), SavedgameLowestBackwardCompatVersion.LongString.GetCStr(), EngineVersion.LongString.GetCStr())); + } + if (elems & kSvgDesc_EnvInfo) { + desc.MainDataFilename.Read(in); + in->ReadInt32(); // unscaled game height with borders, now obsolete + desc.ColorDepth = in->ReadInt32(); + } else { + StrUtil::SkipCStr(in); + in->ReadInt32(); // unscaled game height with borders, now obsolete + in->ReadInt32(); // color depth + } + + return HSaveError::None(); } -HSaveError OpenSavegameBase(const String &filename, SavegameSource *src, SavegameDescription *desc, SavegameDescElem elems) -{ - UStream in(File::OpenFileRead(filename)); - if (!in.get()) - return new SavegameError(kSvgErr_FileOpenFailed, String::FromFormat("Requested filename: %s.", filename.GetCStr())); - - // Skip MS Windows Vista rich media header - RICH_GAME_MEDIA_HEADER rich_media_header; - rich_media_header.ReadFromFile(in.get()); - - // Check saved game signature - bool is_new_save = false; - size_t pre_sig_pos = in->GetPosition(); - String svg_sig = String::FromStreamCount(in.get(), SavegameSource::Signature.GetLength()); - if (svg_sig.Compare(SavegameSource::Signature) == 0) - { - is_new_save = true; - } - else - { - in->Seek(pre_sig_pos, kSeekBegin); - svg_sig = String::FromStreamCount(in.get(), SavegameSource::LegacySignature.GetLength()); - if (svg_sig.Compare(SavegameSource::LegacySignature) != 0) - return new SavegameError(kSvgErr_SignatureFailed); - } - - SavegameVersion svg_ver; - SavegameDescription temp_desc; - HSaveError err; - if (is_new_save) - err = ReadDescription(in.get(), svg_ver, temp_desc, desc ? elems : kSvgDesc_None); - else - err = ReadDescription_v321(in.get(), svg_ver, temp_desc, desc ? elems : kSvgDesc_None); - if (!err) - return err; - - if (src) - { - src->Filename = filename; - src->Version = svg_ver; - src->InputStream.reset(in.release()); // give the stream away to the caller - } - if (desc) - { - if (elems & kSvgDesc_EnvInfo) - { - desc->EngineName = temp_desc.EngineName; - desc->EngineVersion = temp_desc.EngineVersion; - desc->GameGuid = temp_desc.GameGuid; - desc->GameTitle = temp_desc.GameTitle; - desc->MainDataFilename = temp_desc.MainDataFilename; - desc->MainDataVersion = temp_desc.MainDataVersion; - desc->ColorDepth = temp_desc.ColorDepth; - } - if (elems & kSvgDesc_UserText) - desc->UserText = temp_desc.UserText; - if (elems & kSvgDesc_UserImage) - desc->UserImage.reset(temp_desc.UserImage.release()); - } - return err; +HSaveError OpenSavegameBase(const String &filename, SavegameSource *src, SavegameDescription *desc, SavegameDescElem elems) { + UStream in(File::OpenFileRead(filename)); + if (!in.get()) + return new SavegameError(kSvgErr_FileOpenFailed, String::FromFormat("Requested filename: %s.", filename.GetCStr())); + + // Skip MS Windows Vista rich media header + RICH_GAME_MEDIA_HEADER rich_media_header; + rich_media_header.ReadFromFile(in.get()); + + // Check saved game signature + bool is_new_save = false; + size_t pre_sig_pos = in->GetPosition(); + String svg_sig = String::FromStreamCount(in.get(), SavegameSource::Signature.GetLength()); + if (svg_sig.Compare(SavegameSource::Signature) == 0) { + is_new_save = true; + } else { + in->Seek(pre_sig_pos, kSeekBegin); + svg_sig = String::FromStreamCount(in.get(), SavegameSource::LegacySignature.GetLength()); + if (svg_sig.Compare(SavegameSource::LegacySignature) != 0) + return new SavegameError(kSvgErr_SignatureFailed); + } + + SavegameVersion svg_ver; + SavegameDescription temp_desc; + HSaveError err; + if (is_new_save) + err = ReadDescription(in.get(), svg_ver, temp_desc, desc ? elems : kSvgDesc_None); + else + err = ReadDescription_v321(in.get(), svg_ver, temp_desc, desc ? elems : kSvgDesc_None); + if (!err) + return err; + + if (src) { + src->Filename = filename; + src->Version = svg_ver; + src->InputStream.reset(in.release()); // give the stream away to the caller + } + if (desc) { + if (elems & kSvgDesc_EnvInfo) { + desc->EngineName = temp_desc.EngineName; + desc->EngineVersion = temp_desc.EngineVersion; + desc->GameGuid = temp_desc.GameGuid; + desc->GameTitle = temp_desc.GameTitle; + desc->MainDataFilename = temp_desc.MainDataFilename; + desc->MainDataVersion = temp_desc.MainDataVersion; + desc->ColorDepth = temp_desc.ColorDepth; + } + if (elems & kSvgDesc_UserText) + desc->UserText = temp_desc.UserText; + if (elems & kSvgDesc_UserImage) + desc->UserImage.reset(temp_desc.UserImage.release()); + } + return err; } -HSaveError OpenSavegame(const String &filename, SavegameSource &src, SavegameDescription &desc, SavegameDescElem elems) -{ - return OpenSavegameBase(filename, &src, &desc, elems); +HSaveError OpenSavegame(const String &filename, SavegameSource &src, SavegameDescription &desc, SavegameDescElem elems) { + return OpenSavegameBase(filename, &src, &desc, elems); } -HSaveError OpenSavegame(const String &filename, SavegameDescription &desc, SavegameDescElem elems) -{ - return OpenSavegameBase(filename, nullptr, &desc, elems); +HSaveError OpenSavegame(const String &filename, SavegameDescription &desc, SavegameDescElem elems) { + return OpenSavegameBase(filename, nullptr, &desc, elems); } // Prepares engine for actual save restore (stops processes, cleans up memory) -void DoBeforeRestore(PreservedParams &pp) -{ - pp.SpeechVOX = play.want_speech; - pp.MusicVOX = play.separate_music_lib; - - unload_old_room(); - delete raw_saved_screen; - raw_saved_screen = nullptr; - remove_screen_overlay(-1); - is_complete_overlay = 0; - is_text_overlay = 0; - - // cleanup dynamic sprites - // NOTE: sprite 0 is a special constant sprite that cannot be dynamic - for (int i = 1; i < spriteset.GetSpriteSlotCount(); ++i) - { - if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) - { - // do this early, so that it changing guibuts doesn't - // affect the restored data - free_dynamic_sprite(i); - } - } - - // cleanup GUI backgrounds - for (int i = 0; i < game.numgui; ++i) - { - delete guibg[i]; - guibg[i] = nullptr; - - if (guibgbmp[i]) - gfxDriver->DestroyDDB(guibgbmp[i]); - guibgbmp[i] = nullptr; - } - - // preserve script data sizes and cleanup scripts - pp.GlScDataSize = gameinst->globaldatasize; - delete gameinstFork; - delete gameinst; - gameinstFork = nullptr; - gameinst = nullptr; - pp.ScMdDataSize.resize(numScriptModules); - for (int i = 0; i < numScriptModules; ++i) - { - pp.ScMdDataSize[i] = moduleInst[i]->globaldatasize; - delete moduleInstFork[i]; - delete moduleInst[i]; - moduleInst[i] = nullptr; - } - - play.FreeProperties(); - play.FreeViewportsAndCameras(); - - delete roominstFork; - delete roominst; - roominstFork = nullptr; - roominst = nullptr; - - delete dialogScriptsInst; - dialogScriptsInst = nullptr; - - resetRoomStatuses(); - troom.FreeScriptData(); - troom.FreeProperties(); - free_do_once_tokens(); - - // unregister gui controls from API exports - // TODO: find out why are we doing this here? is this really necessary? - for (int i = 0; i < game.numgui; ++i) - { - unexport_gui_controls(i); - } - // Clear the managed object pool - ccUnregisterAllObjects(); - - // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size - for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) - { - stop_and_destroy_channel_ex(i, false); - } - - clear_music_cache(); +void DoBeforeRestore(PreservedParams &pp) { + pp.SpeechVOX = play.want_speech; + pp.MusicVOX = play.separate_music_lib; + + unload_old_room(); + delete raw_saved_screen; + raw_saved_screen = nullptr; + remove_screen_overlay(-1); + is_complete_overlay = 0; + is_text_overlay = 0; + + // cleanup dynamic sprites + // NOTE: sprite 0 is a special constant sprite that cannot be dynamic + for (int i = 1; i < spriteset.GetSpriteSlotCount(); ++i) { + if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) { + // do this early, so that it changing guibuts doesn't + // affect the restored data + free_dynamic_sprite(i); + } + } + + // cleanup GUI backgrounds + for (int i = 0; i < game.numgui; ++i) { + delete guibg[i]; + guibg[i] = nullptr; + + if (guibgbmp[i]) + gfxDriver->DestroyDDB(guibgbmp[i]); + guibgbmp[i] = nullptr; + } + + // preserve script data sizes and cleanup scripts + pp.GlScDataSize = gameinst->globaldatasize; + delete gameinstFork; + delete gameinst; + gameinstFork = nullptr; + gameinst = nullptr; + pp.ScMdDataSize.resize(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) { + pp.ScMdDataSize[i] = moduleInst[i]->globaldatasize; + delete moduleInstFork[i]; + delete moduleInst[i]; + moduleInst[i] = nullptr; + } + + play.FreeProperties(); + play.FreeViewportsAndCameras(); + + delete roominstFork; + delete roominst; + roominstFork = nullptr; + roominst = nullptr; + + delete dialogScriptsInst; + dialogScriptsInst = nullptr; + + resetRoomStatuses(); + troom.FreeScriptData(); + troom.FreeProperties(); + free_do_once_tokens(); + + // unregister gui controls from API exports + // TODO: find out why are we doing this here? is this really necessary? + for (int i = 0; i < game.numgui; ++i) { + unexport_gui_controls(i); + } + // Clear the managed object pool + ccUnregisterAllObjects(); + + // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { + stop_and_destroy_channel_ex(i, false); + } + + clear_music_cache(); } -void RestoreViewportsAndCameras(const RestoredData &r_data) -{ - for (size_t i = 0; i < r_data.Cameras.size(); ++i) - { - const auto &cam_dat = r_data.Cameras[i]; - auto cam = play.GetRoomCamera(i); - cam->SetID(cam_dat.ID); - if ((cam_dat.Flags & kSvgCamPosLocked) != 0) - cam->Lock(); - else - cam->Release(); - cam->SetAt(cam_dat.Left, cam_dat.Top); - cam->SetSize(Size(cam_dat.Width, cam_dat.Height)); - } - for (size_t i = 0; i < r_data.Viewports.size(); ++i) - { - const auto &view_dat = r_data.Viewports[i]; - auto view = play.GetRoomViewport(i); - view->SetID(view_dat.ID); - view->SetVisible((view_dat.Flags & kSvgViewportVisible) != 0); - view->SetRect(RectWH(view_dat.Left, view_dat.Top, view_dat.Width, view_dat.Height)); - view->SetZOrder(view_dat.ZOrder); - // Restore camera link - int cam_index = view_dat.CamID; - if (cam_index < 0) continue; - auto cam = play.GetRoomCamera(cam_index); - view->LinkCamera(cam); - cam->LinkToViewport(view); - } - play.InvalidateViewportZOrder(); +void RestoreViewportsAndCameras(const RestoredData &r_data) { + for (size_t i = 0; i < r_data.Cameras.size(); ++i) { + const auto &cam_dat = r_data.Cameras[i]; + auto cam = play.GetRoomCamera(i); + cam->SetID(cam_dat.ID); + if ((cam_dat.Flags & kSvgCamPosLocked) != 0) + cam->Lock(); + else + cam->Release(); + cam->SetAt(cam_dat.Left, cam_dat.Top); + cam->SetSize(Size(cam_dat.Width, cam_dat.Height)); + } + for (size_t i = 0; i < r_data.Viewports.size(); ++i) { + const auto &view_dat = r_data.Viewports[i]; + auto view = play.GetRoomViewport(i); + view->SetID(view_dat.ID); + view->SetVisible((view_dat.Flags & kSvgViewportVisible) != 0); + view->SetRect(RectWH(view_dat.Left, view_dat.Top, view_dat.Width, view_dat.Height)); + view->SetZOrder(view_dat.ZOrder); + // Restore camera link + int cam_index = view_dat.CamID; + if (cam_index < 0) continue; + auto cam = play.GetRoomCamera(cam_index); + view->LinkCamera(cam); + cam->LinkToViewport(view); + } + play.InvalidateViewportZOrder(); } // Final processing after successfully restoring from save -HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) -{ - // Use a yellow dialog highlight for older game versions - // CHECKME: it is dubious that this should be right here - if(loaded_game_file_version < kGameVersion_331) - play.dialog_options_highlight_color = DIALOG_OPTIONS_HIGHLIGHT_COLOR_DEFAULT; - - // Preserve whether the music vox is available - play.separate_music_lib = pp.MusicVOX; - // If they had the vox when they saved it, but they don't now - if ((pp.SpeechVOX < 0) && (play.want_speech >= 0)) - play.want_speech = (-play.want_speech) - 1; - // If they didn't have the vox before, but now they do - else if ((pp.SpeechVOX >= 0) && (play.want_speech < 0)) - play.want_speech = (-play.want_speech) - 1; - - // recache queued clips - for (int i = 0; i < play.new_music_queue_size; ++i) - { - play.new_music_queue[i].cachedClip = nullptr; - } - - // restore these to the ones retrieved from the save game - const size_t dynsurf_num = Math::Min((size_t)MAX_DYNAMIC_SURFACES, r_data.DynamicSurfaces.size()); - for (size_t i = 0; i < dynsurf_num; ++i) - { - dynamicallyCreatedSurfaces[i] = r_data.DynamicSurfaces[i]; - } - - for (int i = 0; i < game.numgui; ++i) - export_gui_controls(i); - update_gui_zorder(); - - if (create_global_script()) - { - return new SavegameError(kSvgErr_GameObjectInitFailed, - String::FromFormat("Unable to recreate global script: %s", ccErrorString.GetCStr())); - } - - // read the global data into the newly created script - if (r_data.GlobalScript.Data.get()) - memcpy(gameinst->globaldata, r_data.GlobalScript.Data.get(), - Math::Min((size_t)gameinst->globaldatasize, r_data.GlobalScript.Len)); - - // restore the script module data - for (int i = 0; i < numScriptModules; ++i) - { - if (r_data.ScriptModules[i].Data.get()) - memcpy(moduleInst[i]->globaldata, r_data.ScriptModules[i].Data.get(), - Math::Min((size_t)moduleInst[i]->globaldatasize, r_data.ScriptModules[i].Len)); - } - - setup_player_character(game.playercharacter); - - // Save some parameters to restore them after room load - int gstimer=play.gscript_timer; - int oldx1 = play.mboundx1, oldx2 = play.mboundx2; - int oldy1 = play.mboundy1, oldy2 = play.mboundy2; - - // disable the queue momentarily - int queuedMusicSize = play.music_queue_size; - play.music_queue_size = 0; - - update_polled_stuff_if_runtime(); - - // load the room the game was saved in - if (displayed_room >= 0) - load_new_room(displayed_room, nullptr); - - update_polled_stuff_if_runtime(); - - play.gscript_timer=gstimer; - // restore the correct room volume (they might have modified - // it with SetMusicVolume) - thisroom.Options.MusicVolume = r_data.RoomVolume; - - Mouse::SetMoveLimit(Rect(oldx1, oldy1, oldx2, oldy2)); - - set_cursor_mode(r_data.CursorMode); - set_mouse_cursor(r_data.CursorID); - if (r_data.CursorMode == MODE_USE) - SetActiveInventory(playerchar->activeinv); - // ensure that the current cursor is locked - spriteset.Precache(game.mcurs[r_data.CursorID].pic); - - set_window_title(play.game_name); - - update_polled_stuff_if_runtime(); - - if (displayed_room >= 0) - { - for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) - { - if (r_data.RoomBkgScene[i]) - { - thisroom.BgFrames[i].Graphic = r_data.RoomBkgScene[i]; - } - } - - in_new_room=3; // don't run "enters screen" events - // now that room has loaded, copy saved light levels in - for (size_t i = 0; i < MAX_ROOM_REGIONS; ++i) - { - thisroom.Regions[i].Light = r_data.RoomLightLevels[i]; - thisroom.Regions[i].Tint = r_data.RoomTintLevels[i]; - } - generate_light_table(); - - for (size_t i = 0; i < MAX_WALK_AREAS + 1; ++i) - { - thisroom.WalkAreas[i].ScalingFar = r_data.RoomZoomLevels1[i]; - thisroom.WalkAreas[i].ScalingNear = r_data.RoomZoomLevels2[i]; - } - - on_background_frame_change(); - } - - gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); - - // restore the queue now that the music is playing - play.music_queue_size = queuedMusicSize; - - if (play.digital_master_volume >= 0) - System_SetVolume(play.digital_master_volume); - - // Run audio clips on channels - // these two crossfading parameters have to be temporarily reset - const int cf_in_chan = play.crossfading_in_channel; - const int cf_out_chan = play.crossfading_out_channel; - play.crossfading_in_channel = 0; - play.crossfading_out_channel = 0; - - { - AudioChannelsLock lock; - // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size - for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) - { - const RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; - if (chan_info.ClipID < 0) - continue; - if ((size_t)chan_info.ClipID >= game.audioClips.size()) - { - return new SavegameError(kSvgErr_GameObjectInitFailed, - String::FromFormat("Invalid audio clip index: %d (clip count: %u).", chan_info.ClipID, game.audioClips.size())); - } - play_audio_clip_on_channel(i, &game.audioClips[chan_info.ClipID], - chan_info.Priority, chan_info.Repeat, chan_info.Pos); - - auto* ch = lock.GetChannel(i); - if (ch != nullptr) - { - ch->set_volume_direct(chan_info.VolAsPercent, chan_info.Vol); - ch->set_speed(chan_info.Speed); - ch->set_panning(chan_info.Pan); - ch->panningAsPercentage = chan_info.PanAsPercent; - ch->xSource = chan_info.XSource; - ch->ySource = chan_info.YSource; - ch->maximumPossibleDistanceAway = chan_info.MaxDist; - } - } - if ((cf_in_chan > 0) && (lock.GetChannel(cf_in_chan) != nullptr)) - play.crossfading_in_channel = cf_in_chan; - if ((cf_out_chan > 0) && (lock.GetChannel(cf_out_chan) != nullptr)) - play.crossfading_out_channel = cf_out_chan; - - // If there were synced audio tracks, the time taken to load in the - // different channels will have thrown them out of sync, so re-time it - // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size - for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) - { - auto* ch = lock.GetChannelIfPlaying(i); - int pos = r_data.AudioChans[i].Pos; - if ((pos > 0) && (ch != nullptr)) - { - ch->seek(pos); - } - } - } // -- AudioChannelsLock - - // TODO: investigate loop range - for (int i = 1; i < MAX_SOUND_CHANNELS; ++i) - { - if (r_data.DoAmbient[i]) - PlayAmbientSound(i, r_data.DoAmbient[i], ambient[i].vol, ambient[i].x, ambient[i].y); - } - update_directional_sound_vol(); - - for (int i = 0; i < game.numgui; ++i) - { - guibg[i] = BitmapHelper::CreateBitmap(guis[i].Width, guis[i].Height, game.GetColorDepth()); - guibg[i] = ReplaceBitmapWithSupportedFormat(guibg[i]); - } - - recreate_overlay_ddbs(); - - guis_need_update = 1; - - RestoreViewportsAndCameras(r_data); - - play.ClearIgnoreInput(); // don't keep ignored input after save restore - update_polled_stuff_if_runtime(); - - pl_run_plugin_hooks(AGSE_POSTRESTOREGAME, 0); - - if (displayed_room < 0) - { - // the restart point, no room was loaded - load_new_room(playerchar->room, playerchar); - playerchar->prevroom = -1; - - first_room_initialization(); - } - - if ((play.music_queue_size > 0) && (cachedQueuedMusic == nullptr)) - { - cachedQueuedMusic = load_music_from_disk(play.music_queue[0], 0); - } - - // Test if the old-style audio had playing music and it was properly loaded - if (current_music_type > 0) - { - AudioChannelsLock lock; - - if ((crossFading > 0 && !lock.GetChannelIfPlaying(crossFading)) || - (crossFading <= 0 && !lock.GetChannelIfPlaying(SCHAN_MUSIC))) - { - current_music_type = 0; // playback failed, reset flag - } - } - - set_game_speed(r_data.FPS); - - return HSaveError::None(); +HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) { + // Use a yellow dialog highlight for older game versions + // CHECKME: it is dubious that this should be right here + if (loaded_game_file_version < kGameVersion_331) + play.dialog_options_highlight_color = DIALOG_OPTIONS_HIGHLIGHT_COLOR_DEFAULT; + + // Preserve whether the music vox is available + play.separate_music_lib = pp.MusicVOX; + // If they had the vox when they saved it, but they don't now + if ((pp.SpeechVOX < 0) && (play.want_speech >= 0)) + play.want_speech = (-play.want_speech) - 1; + // If they didn't have the vox before, but now they do + else if ((pp.SpeechVOX >= 0) && (play.want_speech < 0)) + play.want_speech = (-play.want_speech) - 1; + + // recache queued clips + for (int i = 0; i < play.new_music_queue_size; ++i) { + play.new_music_queue[i].cachedClip = nullptr; + } + + // restore these to the ones retrieved from the save game + const size_t dynsurf_num = Math::Min((size_t)MAX_DYNAMIC_SURFACES, r_data.DynamicSurfaces.size()); + for (size_t i = 0; i < dynsurf_num; ++i) { + dynamicallyCreatedSurfaces[i] = r_data.DynamicSurfaces[i]; + } + + for (int i = 0; i < game.numgui; ++i) + export_gui_controls(i); + update_gui_zorder(); + + if (create_global_script()) { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Unable to recreate global script: %s", ccErrorString.GetCStr())); + } + + // read the global data into the newly created script + if (r_data.GlobalScript.Data.get()) + memcpy(gameinst->globaldata, r_data.GlobalScript.Data.get(), + Math::Min((size_t)gameinst->globaldatasize, r_data.GlobalScript.Len)); + + // restore the script module data + for (int i = 0; i < numScriptModules; ++i) { + if (r_data.ScriptModules[i].Data.get()) + memcpy(moduleInst[i]->globaldata, r_data.ScriptModules[i].Data.get(), + Math::Min((size_t)moduleInst[i]->globaldatasize, r_data.ScriptModules[i].Len)); + } + + setup_player_character(game.playercharacter); + + // Save some parameters to restore them after room load + int gstimer = play.gscript_timer; + int oldx1 = play.mboundx1, oldx2 = play.mboundx2; + int oldy1 = play.mboundy1, oldy2 = play.mboundy2; + + // disable the queue momentarily + int queuedMusicSize = play.music_queue_size; + play.music_queue_size = 0; + + update_polled_stuff_if_runtime(); + + // load the room the game was saved in + if (displayed_room >= 0) + load_new_room(displayed_room, nullptr); + + update_polled_stuff_if_runtime(); + + play.gscript_timer = gstimer; + // restore the correct room volume (they might have modified + // it with SetMusicVolume) + thisroom.Options.MusicVolume = r_data.RoomVolume; + + Mouse::SetMoveLimit(Rect(oldx1, oldy1, oldx2, oldy2)); + + set_cursor_mode(r_data.CursorMode); + set_mouse_cursor(r_data.CursorID); + if (r_data.CursorMode == MODE_USE) + SetActiveInventory(playerchar->activeinv); + // ensure that the current cursor is locked + spriteset.Precache(game.mcurs[r_data.CursorID].pic); + + set_window_title(play.game_name); + + update_polled_stuff_if_runtime(); + + if (displayed_room >= 0) { + for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) { + if (r_data.RoomBkgScene[i]) { + thisroom.BgFrames[i].Graphic = r_data.RoomBkgScene[i]; + } + } + + in_new_room = 3; // don't run "enters screen" events + // now that room has loaded, copy saved light levels in + for (size_t i = 0; i < MAX_ROOM_REGIONS; ++i) { + thisroom.Regions[i].Light = r_data.RoomLightLevels[i]; + thisroom.Regions[i].Tint = r_data.RoomTintLevels[i]; + } + generate_light_table(); + + for (size_t i = 0; i < MAX_WALK_AREAS + 1; ++i) { + thisroom.WalkAreas[i].ScalingFar = r_data.RoomZoomLevels1[i]; + thisroom.WalkAreas[i].ScalingNear = r_data.RoomZoomLevels2[i]; + } + + on_background_frame_change(); + } + + gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); + + // restore the queue now that the music is playing + play.music_queue_size = queuedMusicSize; + + if (play.digital_master_volume >= 0) + System_SetVolume(play.digital_master_volume); + + // Run audio clips on channels + // these two crossfading parameters have to be temporarily reset + const int cf_in_chan = play.crossfading_in_channel; + const int cf_out_chan = play.crossfading_out_channel; + play.crossfading_in_channel = 0; + play.crossfading_out_channel = 0; + + { + AudioChannelsLock lock; + // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { + const RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; + if (chan_info.ClipID < 0) + continue; + if ((size_t)chan_info.ClipID >= game.audioClips.size()) { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Invalid audio clip index: %d (clip count: %u).", chan_info.ClipID, game.audioClips.size())); + } + play_audio_clip_on_channel(i, &game.audioClips[chan_info.ClipID], + chan_info.Priority, chan_info.Repeat, chan_info.Pos); + + auto *ch = lock.GetChannel(i); + if (ch != nullptr) { + ch->set_volume_direct(chan_info.VolAsPercent, chan_info.Vol); + ch->set_speed(chan_info.Speed); + ch->set_panning(chan_info.Pan); + ch->panningAsPercentage = chan_info.PanAsPercent; + ch->xSource = chan_info.XSource; + ch->ySource = chan_info.YSource; + ch->maximumPossibleDistanceAway = chan_info.MaxDist; + } + } + if ((cf_in_chan > 0) && (lock.GetChannel(cf_in_chan) != nullptr)) + play.crossfading_in_channel = cf_in_chan; + if ((cf_out_chan > 0) && (lock.GetChannel(cf_out_chan) != nullptr)) + play.crossfading_out_channel = cf_out_chan; + + // If there were synced audio tracks, the time taken to load in the + // different channels will have thrown them out of sync, so re-time it + // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { + auto *ch = lock.GetChannelIfPlaying(i); + int pos = r_data.AudioChans[i].Pos; + if ((pos > 0) && (ch != nullptr)) { + ch->seek(pos); + } + } + } // -- AudioChannelsLock + + // TODO: investigate loop range + for (int i = 1; i < MAX_SOUND_CHANNELS; ++i) { + if (r_data.DoAmbient[i]) + PlayAmbientSound(i, r_data.DoAmbient[i], ambient[i].vol, ambient[i].x, ambient[i].y); + } + update_directional_sound_vol(); + + for (int i = 0; i < game.numgui; ++i) { + guibg[i] = BitmapHelper::CreateBitmap(guis[i].Width, guis[i].Height, game.GetColorDepth()); + guibg[i] = ReplaceBitmapWithSupportedFormat(guibg[i]); + } + + recreate_overlay_ddbs(); + + guis_need_update = 1; + + RestoreViewportsAndCameras(r_data); + + play.ClearIgnoreInput(); // don't keep ignored input after save restore + update_polled_stuff_if_runtime(); + + pl_run_plugin_hooks(AGSE_POSTRESTOREGAME, 0); + + if (displayed_room < 0) { + // the restart point, no room was loaded + load_new_room(playerchar->room, playerchar); + playerchar->prevroom = -1; + + first_room_initialization(); + } + + if ((play.music_queue_size > 0) && (cachedQueuedMusic == nullptr)) { + cachedQueuedMusic = load_music_from_disk(play.music_queue[0], 0); + } + + // Test if the old-style audio had playing music and it was properly loaded + if (current_music_type > 0) { + AudioChannelsLock lock; + + if ((crossFading > 0 && !lock.GetChannelIfPlaying(crossFading)) || + (crossFading <= 0 && !lock.GetChannelIfPlaying(SCHAN_MUSIC))) { + current_music_type = 0; // playback failed, reset flag + } + } + + set_game_speed(r_data.FPS); + + return HSaveError::None(); } -HSaveError RestoreGameState(PStream in, SavegameVersion svg_version) -{ - PreservedParams pp; - RestoredData r_data; - DoBeforeRestore(pp); - HSaveError err; - if (svg_version >= kSvgVersion_Components) - err = SavegameComponents::ReadAll(in, svg_version, pp, r_data); - else - err = restore_game_data(in.get(), svg_version, pp, r_data); - if (!err) - return err; - return DoAfterRestore(pp, r_data); +HSaveError RestoreGameState(PStream in, SavegameVersion svg_version) { + PreservedParams pp; + RestoredData r_data; + DoBeforeRestore(pp); + HSaveError err; + if (svg_version >= kSvgVersion_Components) + err = SavegameComponents::ReadAll(in, svg_version, pp, r_data); + else + err = restore_game_data(in.get(), svg_version, pp, r_data); + if (!err) + return err; + return DoAfterRestore(pp, r_data); } -void WriteSaveImage(Stream *out, const Bitmap *screenshot) -{ - // store the screenshot at the start to make it easily accesible - out->WriteInt32((screenshot == nullptr) ? 0 : 1); +void WriteSaveImage(Stream *out, const Bitmap *screenshot) { + // store the screenshot at the start to make it easily accesible + out->WriteInt32((screenshot == nullptr) ? 0 : 1); - if (screenshot) - serialize_bitmap(screenshot, out); + if (screenshot) + serialize_bitmap(screenshot, out); } -void WriteDescription(Stream *out, const String &user_text, const Bitmap *user_image) -{ - // Data format version - out->WriteInt32(kSvgVersion_Current); - // Enviroment information - StrUtil::WriteString("Adventure Game Studio run-time engine", out); - StrUtil::WriteString(EngineVersion.LongString, out); - StrUtil::WriteString(game.guid, out); - StrUtil::WriteString(game.gamename, out); - StrUtil::WriteString(ResPaths.GamePak.Name, out); - out->WriteInt32(loaded_game_file_version); - out->WriteInt32(game.GetColorDepth()); - // User description - StrUtil::WriteString(user_text, out); - WriteSaveImage(out, user_image); +void WriteDescription(Stream *out, const String &user_text, const Bitmap *user_image) { + // Data format version + out->WriteInt32(kSvgVersion_Current); + // Enviroment information + StrUtil::WriteString("Adventure Game Studio run-time engine", out); + StrUtil::WriteString(EngineVersion.LongString, out); + StrUtil::WriteString(game.guid, out); + StrUtil::WriteString(game.gamename, out); + StrUtil::WriteString(ResPaths.GamePak.Name, out); + out->WriteInt32(loaded_game_file_version); + out->WriteInt32(game.GetColorDepth()); + // User description + StrUtil::WriteString(user_text, out); + WriteSaveImage(out, user_image); } -PStream StartSavegame(const String &filename, const String &user_text, const Bitmap *user_image) -{ - Stream *out = Common::File::CreateFile(filename); - if (!out) - return PStream(); - - // Initialize and write Vista header - RICH_GAME_MEDIA_HEADER vistaHeader; - memset(&vistaHeader, 0, sizeof(RICH_GAME_MEDIA_HEADER)); - memcpy(&vistaHeader.dwMagicNumber, RM_MAGICNUMBER, sizeof(int)); - vistaHeader.dwHeaderVersion = 1; - vistaHeader.dwHeaderSize = sizeof(RICH_GAME_MEDIA_HEADER); - vistaHeader.dwThumbnailOffsetHigherDword = 0; - vistaHeader.dwThumbnailOffsetLowerDword = 0; - vistaHeader.dwThumbnailSize = 0; - convert_guid_from_text_to_binary(game.guid, &vistaHeader.guidGameId[0]); - uconvert(game.gamename, U_ASCII, (char*)&vistaHeader.szGameName[0], U_UNICODE, RM_MAXLENGTH); - uconvert(user_text, U_ASCII, (char*)&vistaHeader.szSaveName[0], U_UNICODE, RM_MAXLENGTH); - vistaHeader.szLevelName[0] = 0; - vistaHeader.szComments[0] = 0; - // MS Windows Vista rich media header - vistaHeader.WriteToFile(out); - - // Savegame signature - out->Write(SavegameSource::Signature.GetCStr(), SavegameSource::Signature.GetLength()); - - // CHECKME: what is this plugin hook suppose to mean, and if it is called here correctly - pl_run_plugin_hooks(AGSE_PRESAVEGAME, 0); - - // Write descrition block - WriteDescription(out, user_text, user_image); - return PStream(out); +PStream StartSavegame(const String &filename, const String &user_text, const Bitmap *user_image) { + Stream *out = Common::File::CreateFile(filename); + if (!out) + return PStream(); + + // Initialize and write Vista header + RICH_GAME_MEDIA_HEADER vistaHeader; + memset(&vistaHeader, 0, sizeof(RICH_GAME_MEDIA_HEADER)); + memcpy(&vistaHeader.dwMagicNumber, RM_MAGICNUMBER, sizeof(int)); + vistaHeader.dwHeaderVersion = 1; + vistaHeader.dwHeaderSize = sizeof(RICH_GAME_MEDIA_HEADER); + vistaHeader.dwThumbnailOffsetHigherDword = 0; + vistaHeader.dwThumbnailOffsetLowerDword = 0; + vistaHeader.dwThumbnailSize = 0; + convert_guid_from_text_to_binary(game.guid, &vistaHeader.guidGameId[0]); + uconvert(game.gamename, U_ASCII, (char *)&vistaHeader.szGameName[0], U_UNICODE, RM_MAXLENGTH); + uconvert(user_text, U_ASCII, (char *)&vistaHeader.szSaveName[0], U_UNICODE, RM_MAXLENGTH); + vistaHeader.szLevelName[0] = 0; + vistaHeader.szComments[0] = 0; + // MS Windows Vista rich media header + vistaHeader.WriteToFile(out); + + // Savegame signature + out->Write(SavegameSource::Signature.GetCStr(), SavegameSource::Signature.GetLength()); + + // CHECKME: what is this plugin hook suppose to mean, and if it is called here correctly + pl_run_plugin_hooks(AGSE_PRESAVEGAME, 0); + + // Write descrition block + WriteDescription(out, user_text, user_image); + return PStream(out); } -void DoBeforeSave() -{ - if (play.cur_music_number >= 0) - { - if (IsMusicPlaying() == 0) - play.cur_music_number = -1; - } - - if (displayed_room >= 0) - { - // update the current room script's data segment copy - if (roominst) - save_room_data_segment(); - - // Update the saved interaction variable values - for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i) - croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value; - } +void DoBeforeSave() { + if (play.cur_music_number >= 0) { + if (IsMusicPlaying() == 0) + play.cur_music_number = -1; + } + + if (displayed_room >= 0) { + // update the current room script's data segment copy + if (roominst) + save_room_data_segment(); + + // Update the saved interaction variable values + for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i) + croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value; + } } -void SaveGameState(PStream out) -{ - DoBeforeSave(); - SavegameComponents::WriteAllCommon(out); +void SaveGameState(PStream out) { + DoBeforeSave(); + SavegameComponents::WriteAllCommon(out); } } // namespace Engine diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h index d13ddebe8b18..838d2122aa99 100644 --- a/engines/ags/engine/game/savegame.h +++ b/engines/ags/engine/game/savegame.h @@ -29,13 +29,14 @@ #include "util/version.h" -namespace AGS -{ +namespace AGS { -namespace Common { class Bitmap; class Stream; } +namespace Common { +class Bitmap; +class Stream; +} -namespace Engine -{ +namespace Engine { using Common::Bitmap; using Common::ErrorHandle; @@ -52,43 +53,41 @@ typedef std::shared_ptr PStream; // 8 last old style saved game format (of AGS 3.2.1) // 9 first new style (self-descriptive block-based) format version //----------------------------------------------------------------------------- -enum SavegameVersion -{ - kSvgVersion_Undefined = 0, - kSvgVersion_321 = 8, - kSvgVersion_Components= 9, - kSvgVersion_Cmp_64bit = 10, - kSvgVersion_350_final = 11, - kSvgVersion_350_final2= 12, - kSvgVersion_Current = kSvgVersion_350_final2, - kSvgVersion_LowestSupported = kSvgVersion_321 // change if support dropped +enum SavegameVersion { + kSvgVersion_Undefined = 0, + kSvgVersion_321 = 8, + kSvgVersion_Components = 9, + kSvgVersion_Cmp_64bit = 10, + kSvgVersion_350_final = 11, + kSvgVersion_350_final2 = 12, + kSvgVersion_Current = kSvgVersion_350_final2, + kSvgVersion_LowestSupported = kSvgVersion_321 // change if support dropped }; // Error codes for save restoration routine -enum SavegameErrorType -{ - kSvgErr_NoError, - kSvgErr_FileOpenFailed, - kSvgErr_SignatureFailed, - kSvgErr_FormatVersionNotSupported, - kSvgErr_IncompatibleEngine, - kSvgErr_GameGuidMismatch, - kSvgErr_ComponentListOpeningTagFormat, - kSvgErr_ComponentListClosingTagMissing, - kSvgErr_ComponentOpeningTagFormat, - kSvgErr_ComponentClosingTagFormat, - kSvgErr_ComponentSizeMismatch, - kSvgErr_UnsupportedComponent, - kSvgErr_ComponentSerialization, - kSvgErr_ComponentUnserialization, - kSvgErr_InconsistentFormat, - kSvgErr_UnsupportedComponentVersion, - kSvgErr_GameContentAssertion, - kSvgErr_InconsistentData, - kSvgErr_InconsistentPlugin, - kSvgErr_DifferentColorDepth, - kSvgErr_GameObjectInitFailed, - kNumSavegameError +enum SavegameErrorType { + kSvgErr_NoError, + kSvgErr_FileOpenFailed, + kSvgErr_SignatureFailed, + kSvgErr_FormatVersionNotSupported, + kSvgErr_IncompatibleEngine, + kSvgErr_GameGuidMismatch, + kSvgErr_ComponentListOpeningTagFormat, + kSvgErr_ComponentListClosingTagMissing, + kSvgErr_ComponentOpeningTagFormat, + kSvgErr_ComponentClosingTagFormat, + kSvgErr_ComponentSizeMismatch, + kSvgErr_UnsupportedComponent, + kSvgErr_ComponentSerialization, + kSvgErr_ComponentUnserialization, + kSvgErr_InconsistentFormat, + kSvgErr_UnsupportedComponentVersion, + kSvgErr_GameContentAssertion, + kSvgErr_InconsistentData, + kSvgErr_InconsistentPlugin, + kSvgErr_DifferentColorDepth, + kSvgErr_GameObjectInitFailed, + kNumSavegameError }; String GetSavegameErrorText(SavegameErrorType err); @@ -99,60 +98,57 @@ typedef std::unique_ptr UStream; typedef std::unique_ptr UBitmap; // SavegameSource defines a successfully opened savegame stream -struct SavegameSource -{ - // Signature of the current savegame format - static const String Signature; - // Signature of the legacy savegame format - static const String LegacySignature; - - // Name of the savefile - String Filename; - // Savegame format version - SavegameVersion Version; - // A ponter to the opened stream - PStream InputStream; - - SavegameSource(); +struct SavegameSource { + // Signature of the current savegame format + static const String Signature; + // Signature of the legacy savegame format + static const String LegacySignature; + + // Name of the savefile + String Filename; + // Savegame format version + SavegameVersion Version; + // A ponter to the opened stream + PStream InputStream; + + SavegameSource(); }; // Supported elements of savegame description; // these may be used as flags to define valid fields -enum SavegameDescElem -{ - kSvgDesc_None = 0, - kSvgDesc_EnvInfo = 0x0001, - kSvgDesc_UserText = 0x0002, - kSvgDesc_UserImage = 0x0004, - kSvgDesc_All = kSvgDesc_EnvInfo | kSvgDesc_UserText | kSvgDesc_UserImage +enum SavegameDescElem { + kSvgDesc_None = 0, + kSvgDesc_EnvInfo = 0x0001, + kSvgDesc_UserText = 0x0002, + kSvgDesc_UserImage = 0x0004, + kSvgDesc_All = kSvgDesc_EnvInfo | kSvgDesc_UserText | kSvgDesc_UserImage }; // SavegameDescription describes savegame with information about the enviroment // it was created in, and custom data provided by user -struct SavegameDescription -{ - // Name of the engine that saved the game - String EngineName; - // Version of the engine that saved the game - Version EngineVersion; - // Guid of the game which made this save - String GameGuid; - // Title of the game which made this save - String GameTitle; - // Name of the main data file used; this is needed to properly - // load saves made by "minigames" - String MainDataFilename; - // Game's main data version; should be checked early to know - // if the save was made for the supported game format - GameDataVersion MainDataVersion; - // Native color depth of the game; this is required to - // properly restore dynamic graphics from the save - int ColorDepth; - - String UserText; - UBitmap UserImage; - - SavegameDescription(); +struct SavegameDescription { + // Name of the engine that saved the game + String EngineName; + // Version of the engine that saved the game + Version EngineVersion; + // Guid of the game which made this save + String GameGuid; + // Title of the game which made this save + String GameTitle; + // Name of the main data file used; this is needed to properly + // load saves made by "minigames" + String MainDataFilename; + // Game's main data version; should be checked early to know + // if the save was made for the supported game format + GameDataVersion MainDataVersion; + // Native color depth of the game; this is required to + // properly restore dynamic graphics from the save + int ColorDepth; + + String UserText; + UBitmap UserImage; + + SavegameDescription(); }; diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index c95a3e108ec4..8c69ecb3c8b3 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -75,1324 +75,1187 @@ extern Bitmap *raw_saved_screen; extern MoveList *mls; -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -namespace SavegameComponents -{ +namespace SavegameComponents { const String ComponentListTag = "Components"; -void WriteFormatTag(PStream out, const String &tag, bool open = true) -{ - String full_tag = String::FromFormat(open ? "<%s>" : "", tag.GetCStr()); - out->Write(full_tag.GetCStr(), full_tag.GetLength()); +void WriteFormatTag(PStream out, const String &tag, bool open = true) { + String full_tag = String::FromFormat(open ? "<%s>" : "", tag.GetCStr()); + out->Write(full_tag.GetCStr(), full_tag.GetLength()); } -bool ReadFormatTag(PStream in, String &tag, bool open = true) -{ - if (in->ReadByte() != '<') - return false; - if (!open && in->ReadByte() != '/') - return false; - tag.Empty(); - while (!in->EOS()) - { - char c = in->ReadByte(); - if (c == '>') - return true; - tag.AppendChar(c); - } - return false; // reached EOS before closing symbol +bool ReadFormatTag(PStream in, String &tag, bool open = true) { + if (in->ReadByte() != '<') + return false; + if (!open && in->ReadByte() != '/') + return false; + tag.Empty(); + while (!in->EOS()) { + char c = in->ReadByte(); + if (c == '>') + return true; + tag.AppendChar(c); + } + return false; // reached EOS before closing symbol } -bool AssertFormatTag(PStream in, const String &tag, bool open = true) -{ - String read_tag; - if (!ReadFormatTag(in, read_tag, open)) - return false; - return read_tag.Compare(tag) == 0; +bool AssertFormatTag(PStream in, const String &tag, bool open = true) { + String read_tag; + if (!ReadFormatTag(in, read_tag, open)) + return false; + return read_tag.Compare(tag) == 0; } -bool AssertFormatTagStrict(HSaveError &err, PStream in, const String &tag, bool open = true) -{ - - String read_tag; - if (!ReadFormatTag(in, read_tag, open) || read_tag.Compare(tag) != 0) - { - err = new SavegameError(kSvgErr_InconsistentFormat, - String::FromFormat("Mismatching tag: %s.", tag.GetCStr())); - return false; - } - return true; +bool AssertFormatTagStrict(HSaveError &err, PStream in, const String &tag, bool open = true) { + + String read_tag; + if (!ReadFormatTag(in, read_tag, open) || read_tag.Compare(tag) != 0) { + err = new SavegameError(kSvgErr_InconsistentFormat, + String::FromFormat("Mismatching tag: %s.", tag.GetCStr())); + return false; + } + return true; } -inline bool AssertCompatLimit(HSaveError &err, int count, int max_count, const char *content_name) -{ - if (count > max_count) - { - err = new SavegameError(kSvgErr_IncompatibleEngine, - String::FromFormat("Incompatible number of %s (count: %d, max: %d).", - content_name, count, max_count)); - return false; - } - return true; +inline bool AssertCompatLimit(HSaveError &err, int count, int max_count, const char *content_name) { + if (count > max_count) { + err = new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Incompatible number of %s (count: %d, max: %d).", + content_name, count, max_count)); + return false; + } + return true; } -inline bool AssertCompatRange(HSaveError &err, int value, int min_value, int max_value, const char *content_name) -{ - if (value < min_value || value > max_value) - { - err = new SavegameError(kSvgErr_IncompatibleEngine, - String::FromFormat("Restore game error: incompatible %s (id: %d, range: %d - %d).", - content_name, value, min_value, max_value)); - return false; - } - return true; +inline bool AssertCompatRange(HSaveError &err, int value, int min_value, int max_value, const char *content_name) { + if (value < min_value || value > max_value) { + err = new SavegameError(kSvgErr_IncompatibleEngine, + String::FromFormat("Restore game error: incompatible %s (id: %d, range: %d - %d).", + content_name, value, min_value, max_value)); + return false; + } + return true; } -inline bool AssertGameContent(HSaveError &err, int new_val, int original_val, const char *content_name) -{ - if (new_val != original_val) - { - err = new SavegameError(kSvgErr_GameContentAssertion, - String::FromFormat("Mismatching number of %s (game: %d, save: %d).", - content_name, original_val, new_val)); - return false; - } - return true; +inline bool AssertGameContent(HSaveError &err, int new_val, int original_val, const char *content_name) { + if (new_val != original_val) { + err = new SavegameError(kSvgErr_GameContentAssertion, + String::FromFormat("Mismatching number of %s (game: %d, save: %d).", + content_name, original_val, new_val)); + return false; + } + return true; } inline bool AssertGameObjectContent(HSaveError &err, int new_val, int original_val, const char *content_name, - const char *obj_type, int obj_id) -{ - if (new_val != original_val) - { - err = new SavegameError(kSvgErr_GameContentAssertion, - String::FromFormat("Mismatching number of %s, %s #%d (game: %d, save: %d).", - content_name, obj_type, obj_id, original_val, new_val)); - return false; - } - return true; + const char *obj_type, int obj_id) { + if (new_val != original_val) { + err = new SavegameError(kSvgErr_GameContentAssertion, + String::FromFormat("Mismatching number of %s, %s #%d (game: %d, save: %d).", + content_name, obj_type, obj_id, original_val, new_val)); + return false; + } + return true; } inline bool AssertGameObjectContent2(HSaveError &err, int new_val, int original_val, const char *content_name, - const char *obj1_type, int obj1_id, const char *obj2_type, int obj2_id) -{ - if (new_val != original_val) - { - err = new SavegameError(kSvgErr_GameContentAssertion, - String::FromFormat("Mismatching number of %s, %s #%d, %s #%d (game: %d, save: %d).", - content_name, obj1_type, obj1_id, obj2_type, obj2_id, original_val, new_val)); - return false; - } - return true; + const char *obj1_type, int obj1_id, const char *obj2_type, int obj2_id) { + if (new_val != original_val) { + err = new SavegameError(kSvgErr_GameContentAssertion, + String::FromFormat("Mismatching number of %s, %s #%d, %s #%d (game: %d, save: %d).", + content_name, obj1_type, obj1_id, obj2_type, obj2_id, original_val, new_val)); + return false; + } + return true; } -void WriteCameraState(const Camera &cam, Stream *out) -{ - int flags = 0; - if (cam.IsLocked()) flags |= kSvgCamPosLocked; - out->WriteInt32(flags); - const Rect &rc = cam.GetRect(); - out->WriteInt32(rc.Left); - out->WriteInt32(rc.Top); - out->WriteInt32(rc.GetWidth()); - out->WriteInt32(rc.GetHeight()); +void WriteCameraState(const Camera &cam, Stream *out) { + int flags = 0; + if (cam.IsLocked()) flags |= kSvgCamPosLocked; + out->WriteInt32(flags); + const Rect &rc = cam.GetRect(); + out->WriteInt32(rc.Left); + out->WriteInt32(rc.Top); + out->WriteInt32(rc.GetWidth()); + out->WriteInt32(rc.GetHeight()); } -void WriteViewportState(const Viewport &view, Stream *out) -{ - int flags = 0; - if (view.IsVisible()) flags |= kSvgViewportVisible; - out->WriteInt32(flags); - const Rect &rc = view.GetRect(); - out->WriteInt32(rc.Left); - out->WriteInt32(rc.Top); - out->WriteInt32(rc.GetWidth()); - out->WriteInt32(rc.GetHeight()); - out->WriteInt32(view.GetZOrder()); - auto cam = view.GetCamera(); - if (cam) - out->WriteInt32(cam->GetID()); - else - out->WriteInt32(-1); +void WriteViewportState(const Viewport &view, Stream *out) { + int flags = 0; + if (view.IsVisible()) flags |= kSvgViewportVisible; + out->WriteInt32(flags); + const Rect &rc = view.GetRect(); + out->WriteInt32(rc.Left); + out->WriteInt32(rc.Top); + out->WriteInt32(rc.GetWidth()); + out->WriteInt32(rc.GetHeight()); + out->WriteInt32(view.GetZOrder()); + auto cam = view.GetCamera(); + if (cam) + out->WriteInt32(cam->GetID()); + else + out->WriteInt32(-1); } -HSaveError WriteGameState(PStream out) -{ - // Game base - game.WriteForSavegame(out); - // Game palette - // TODO: probably no need to save this for hi/true-res game - out->WriteArray(palette, sizeof(color), 256); - - if (loaded_game_file_version <= kGameVersion_272) - { - // Global variables - out->WriteInt32(numGlobalVars); - for (int i = 0; i < numGlobalVars; ++i) - globalvars[i].Write(out.get()); - } - - // Game state - play.WriteForSavegame(out.get()); - // Other dynamic values - out->WriteInt32(frames_per_second); - out->WriteInt32(loopcounter); - out->WriteInt32(ifacepopped); - out->WriteInt32(game_paused); - // Mouse cursor - out->WriteInt32(cur_mode); - out->WriteInt32(cur_cursor); - out->WriteInt32(mouse_on_iface); - - // Viewports and cameras - int viewcam_flags = 0; - if (play.IsAutoRoomViewport()) - viewcam_flags |= kSvgGameAutoRoomView; - out->WriteInt32(viewcam_flags); - out->WriteInt32(play.GetRoomCameraCount()); - for (int i = 0; i < play.GetRoomCameraCount(); ++i) - WriteCameraState(*play.GetRoomCamera(i), out.get()); - out->WriteInt32(play.GetRoomViewportCount()); - for (int i = 0; i < play.GetRoomViewportCount(); ++i) - WriteViewportState(*play.GetRoomViewport(i), out.get()); - - return HSaveError::None(); +HSaveError WriteGameState(PStream out) { + // Game base + game.WriteForSavegame(out); + // Game palette + // TODO: probably no need to save this for hi/true-res game + out->WriteArray(palette, sizeof(color), 256); + + if (loaded_game_file_version <= kGameVersion_272) { + // Global variables + out->WriteInt32(numGlobalVars); + for (int i = 0; i < numGlobalVars; ++i) + globalvars[i].Write(out.get()); + } + + // Game state + play.WriteForSavegame(out.get()); + // Other dynamic values + out->WriteInt32(frames_per_second); + out->WriteInt32(loopcounter); + out->WriteInt32(ifacepopped); + out->WriteInt32(game_paused); + // Mouse cursor + out->WriteInt32(cur_mode); + out->WriteInt32(cur_cursor); + out->WriteInt32(mouse_on_iface); + + // Viewports and cameras + int viewcam_flags = 0; + if (play.IsAutoRoomViewport()) + viewcam_flags |= kSvgGameAutoRoomView; + out->WriteInt32(viewcam_flags); + out->WriteInt32(play.GetRoomCameraCount()); + for (int i = 0; i < play.GetRoomCameraCount(); ++i) + WriteCameraState(*play.GetRoomCamera(i), out.get()); + out->WriteInt32(play.GetRoomViewportCount()); + for (int i = 0; i < play.GetRoomViewportCount(); ++i) + WriteViewportState(*play.GetRoomViewport(i), out.get()); + + return HSaveError::None(); } -void ReadLegacyCameraState(Stream *in, RestoredData &r_data) -{ - // Precreate viewport and camera and save data in temp structs - int camx = in->ReadInt32(); - int camy = in->ReadInt32(); - play.CreateRoomCamera(); - play.CreateRoomViewport(); - const auto &main_view = play.GetMainViewport(); - RestoredData::CameraData cam_dat; - cam_dat.ID = 0; - cam_dat.Left = camx; - cam_dat.Top = camy; - cam_dat.Width = main_view.GetWidth(); - cam_dat.Height = main_view.GetHeight(); - r_data.Cameras.push_back(cam_dat); - RestoredData::ViewportData view_dat; - view_dat.ID = 0; - view_dat.Width = main_view.GetWidth(); - view_dat.Height = main_view.GetHeight(); - view_dat.Flags = kSvgViewportVisible; - view_dat.CamID = 0; - r_data.Viewports.push_back(view_dat); +void ReadLegacyCameraState(Stream *in, RestoredData &r_data) { + // Precreate viewport and camera and save data in temp structs + int camx = in->ReadInt32(); + int camy = in->ReadInt32(); + play.CreateRoomCamera(); + play.CreateRoomViewport(); + const auto &main_view = play.GetMainViewport(); + RestoredData::CameraData cam_dat; + cam_dat.ID = 0; + cam_dat.Left = camx; + cam_dat.Top = camy; + cam_dat.Width = main_view.GetWidth(); + cam_dat.Height = main_view.GetHeight(); + r_data.Cameras.push_back(cam_dat); + RestoredData::ViewportData view_dat; + view_dat.ID = 0; + view_dat.Width = main_view.GetWidth(); + view_dat.Height = main_view.GetHeight(); + view_dat.Flags = kSvgViewportVisible; + view_dat.CamID = 0; + r_data.Viewports.push_back(view_dat); } -void ReadCameraState(RestoredData &r_data, Stream *in) -{ - RestoredData::CameraData cam; - cam.ID = r_data.Cameras.size(); - cam.Flags = in->ReadInt32(); - cam.Left = in->ReadInt32(); - cam.Top = in->ReadInt32(); - cam.Width = in->ReadInt32(); - cam.Height = in->ReadInt32(); - r_data.Cameras.push_back(cam); +void ReadCameraState(RestoredData &r_data, Stream *in) { + RestoredData::CameraData cam; + cam.ID = r_data.Cameras.size(); + cam.Flags = in->ReadInt32(); + cam.Left = in->ReadInt32(); + cam.Top = in->ReadInt32(); + cam.Width = in->ReadInt32(); + cam.Height = in->ReadInt32(); + r_data.Cameras.push_back(cam); } -void ReadViewportState(RestoredData &r_data, Stream *in) -{ - RestoredData::ViewportData view; - view.ID = r_data.Viewports.size(); - view.Flags = in->ReadInt32(); - view.Left = in->ReadInt32(); - view.Top = in->ReadInt32(); - view.Width = in->ReadInt32(); - view.Height = in->ReadInt32(); - view.ZOrder = in->ReadInt32(); - view.CamID = in->ReadInt32(); - r_data.Viewports.push_back(view); +void ReadViewportState(RestoredData &r_data, Stream *in) { + RestoredData::ViewportData view; + view.ID = r_data.Viewports.size(); + view.Flags = in->ReadInt32(); + view.Left = in->ReadInt32(); + view.Top = in->ReadInt32(); + view.Width = in->ReadInt32(); + view.Height = in->ReadInt32(); + view.ZOrder = in->ReadInt32(); + view.CamID = in->ReadInt32(); + r_data.Viewports.push_back(view); } -HSaveError ReadGameState(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - GameStateSvgVersion svg_ver = (GameStateSvgVersion)cmp_ver; - // Game base - game.ReadFromSavegame(in); - // Game palette - in->ReadArray(palette, sizeof(color), 256); - - if (loaded_game_file_version <= kGameVersion_272) - { - // Legacy interaction global variables - if (!AssertGameContent(err, in->ReadInt32(), numGlobalVars, "Global Variables")) - return err; - for (int i = 0; i < numGlobalVars; ++i) - globalvars[i].Read(in.get()); - } - - // Game state - play.ReadFromSavegame(in.get(), svg_ver, r_data); - - // Other dynamic values - r_data.FPS = in->ReadInt32(); - set_loop_counter(in->ReadInt32()); - ifacepopped = in->ReadInt32(); - game_paused = in->ReadInt32(); - // Mouse cursor state - r_data.CursorMode = in->ReadInt32(); - r_data.CursorID = in->ReadInt32(); - mouse_on_iface = in->ReadInt32(); - - // Viewports and cameras - if (svg_ver < kGSSvgVersion_3510) - { - ReadLegacyCameraState(in.get(), r_data); - r_data.Cameras[0].Flags = r_data.Camera0_Flags; - } - else - { - int viewcam_flags = in->ReadInt32(); - play.SetAutoRoomViewport((viewcam_flags & kSvgGameAutoRoomView) != 0); - // TODO: we create viewport and camera objects here because they are - // required for the managed pool deserialization, but read actual - // data into temp structs because we need to apply it after active - // room is loaded. - // See comments to RestoredData struct for further details. - int cam_count = in->ReadInt32(); - for (int i = 0; i < cam_count; ++i) - { - play.CreateRoomCamera(); - ReadCameraState(r_data, in.get()); - } - int view_count = in->ReadInt32(); - for (int i = 0; i < view_count; ++i) - { - play.CreateRoomViewport(); - ReadViewportState(r_data, in.get()); - } - } - return err; +HSaveError ReadGameState(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + GameStateSvgVersion svg_ver = (GameStateSvgVersion)cmp_ver; + // Game base + game.ReadFromSavegame(in); + // Game palette + in->ReadArray(palette, sizeof(color), 256); + + if (loaded_game_file_version <= kGameVersion_272) { + // Legacy interaction global variables + if (!AssertGameContent(err, in->ReadInt32(), numGlobalVars, "Global Variables")) + return err; + for (int i = 0; i < numGlobalVars; ++i) + globalvars[i].Read(in.get()); + } + + // Game state + play.ReadFromSavegame(in.get(), svg_ver, r_data); + + // Other dynamic values + r_data.FPS = in->ReadInt32(); + set_loop_counter(in->ReadInt32()); + ifacepopped = in->ReadInt32(); + game_paused = in->ReadInt32(); + // Mouse cursor state + r_data.CursorMode = in->ReadInt32(); + r_data.CursorID = in->ReadInt32(); + mouse_on_iface = in->ReadInt32(); + + // Viewports and cameras + if (svg_ver < kGSSvgVersion_3510) { + ReadLegacyCameraState(in.get(), r_data); + r_data.Cameras[0].Flags = r_data.Camera0_Flags; + } else { + int viewcam_flags = in->ReadInt32(); + play.SetAutoRoomViewport((viewcam_flags & kSvgGameAutoRoomView) != 0); + // TODO: we create viewport and camera objects here because they are + // required for the managed pool deserialization, but read actual + // data into temp structs because we need to apply it after active + // room is loaded. + // See comments to RestoredData struct for further details. + int cam_count = in->ReadInt32(); + for (int i = 0; i < cam_count; ++i) { + play.CreateRoomCamera(); + ReadCameraState(r_data, in.get()); + } + int view_count = in->ReadInt32(); + for (int i = 0; i < view_count; ++i) { + play.CreateRoomViewport(); + ReadViewportState(r_data, in.get()); + } + } + return err; } -HSaveError WriteAudio(PStream out) -{ - AudioChannelsLock lock; - - // Game content assertion - out->WriteInt32(game.audioClipTypes.size()); - out->WriteInt32(game.audioClips.size()); // [ivan-mogilko] not necessary, kept only to avoid changing save format - // Audio types - for (size_t i = 0; i < game.audioClipTypes.size(); ++i) - { - game.audioClipTypes[i].WriteToSavegame(out.get()); - out->WriteInt32(play.default_audio_type_volumes[i]); - } - - // Audio clips and crossfade - for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) - { - auto* ch = lock.GetChannelIfPlaying(i); - if ((ch != nullptr) && (ch->sourceClip != nullptr)) - { - out->WriteInt32(((ScriptAudioClip*)ch->sourceClip)->id); - out->WriteInt32(ch->get_pos()); - out->WriteInt32(ch->priority); - out->WriteInt32(ch->repeat ? 1 : 0); - out->WriteInt32(ch->vol); - out->WriteInt32(ch->panning); - out->WriteInt32(ch->volAsPercentage); - out->WriteInt32(ch->panningAsPercentage); - out->WriteInt32(ch->get_speed()); - // since version 1 - out->WriteInt32(ch->xSource); - out->WriteInt32(ch->ySource); - out->WriteInt32(ch->maximumPossibleDistanceAway); - } - else - { - out->WriteInt32(-1); - } - } - out->WriteInt32(crossFading); - out->WriteInt32(crossFadeVolumePerStep); - out->WriteInt32(crossFadeStep); - out->WriteInt32(crossFadeVolumeAtStart); - // CHECKME: why this needs to be saved? - out->WriteInt32(current_music_type); - - // Ambient sound - for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) - ambient[i].WriteToFile(out.get()); - return HSaveError::None(); +HSaveError WriteAudio(PStream out) { + AudioChannelsLock lock; + + // Game content assertion + out->WriteInt32(game.audioClipTypes.size()); + out->WriteInt32(game.audioClips.size()); // [ivan-mogilko] not necessary, kept only to avoid changing save format + // Audio types + for (size_t i = 0; i < game.audioClipTypes.size(); ++i) { + game.audioClipTypes[i].WriteToSavegame(out.get()); + out->WriteInt32(play.default_audio_type_volumes[i]); + } + + // Audio clips and crossfade + for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if ((ch != nullptr) && (ch->sourceClip != nullptr)) { + out->WriteInt32(((ScriptAudioClip *)ch->sourceClip)->id); + out->WriteInt32(ch->get_pos()); + out->WriteInt32(ch->priority); + out->WriteInt32(ch->repeat ? 1 : 0); + out->WriteInt32(ch->vol); + out->WriteInt32(ch->panning); + out->WriteInt32(ch->volAsPercentage); + out->WriteInt32(ch->panningAsPercentage); + out->WriteInt32(ch->get_speed()); + // since version 1 + out->WriteInt32(ch->xSource); + out->WriteInt32(ch->ySource); + out->WriteInt32(ch->maximumPossibleDistanceAway); + } else { + out->WriteInt32(-1); + } + } + out->WriteInt32(crossFading); + out->WriteInt32(crossFadeVolumePerStep); + out->WriteInt32(crossFadeStep); + out->WriteInt32(crossFadeVolumeAtStart); + // CHECKME: why this needs to be saved? + out->WriteInt32(current_music_type); + + // Ambient sound + for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) + ambient[i].WriteToFile(out.get()); + return HSaveError::None(); } -HSaveError ReadAudio(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - // Game content assertion - if (!AssertGameContent(err, in->ReadInt32(), game.audioClipTypes.size(), "Audio Clip Types")) - return err; - in->ReadInt32(); // audio clip count - /* [ivan-mogilko] looks like it's not necessary to assert, as there's no data serialized for clips - if (!AssertGameContent(err, in->ReadInt32(), game.audioClips.size(), "Audio Clips")) - return err;*/ - - // Audio types - for (size_t i = 0; i < game.audioClipTypes.size(); ++i) - { - game.audioClipTypes[i].ReadFromSavegame(in.get()); - play.default_audio_type_volumes[i] = in->ReadInt32(); - } - - // Audio clips and crossfade - for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) - { - RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; - chan_info.Pos = 0; - chan_info.ClipID = in->ReadInt32(); - if (chan_info.ClipID >= 0) - { - chan_info.Pos = in->ReadInt32(); - if (chan_info.Pos < 0) - chan_info.Pos = 0; - chan_info.Priority = in->ReadInt32(); - chan_info.Repeat = in->ReadInt32(); - chan_info.Vol = in->ReadInt32(); - chan_info.Pan = in->ReadInt32(); - chan_info.VolAsPercent = in->ReadInt32(); - chan_info.PanAsPercent = in->ReadInt32(); - chan_info.Speed = 1000; - chan_info.Speed = in->ReadInt32(); - if (cmp_ver >= 1) - { - chan_info.XSource = in->ReadInt32(); - chan_info.YSource = in->ReadInt32(); - chan_info.MaxDist = in->ReadInt32(); - } - } - } - crossFading = in->ReadInt32(); - crossFadeVolumePerStep = in->ReadInt32(); - crossFadeStep = in->ReadInt32(); - crossFadeVolumeAtStart = in->ReadInt32(); - // preserve legacy music type setting - current_music_type = in->ReadInt32(); - - // Ambient sound - for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) - ambient[i].ReadFromFile(in.get()); - for (int i = 1; i < MAX_SOUND_CHANNELS; ++i) - { - if (ambient[i].channel == 0) - { - r_data.DoAmbient[i] = 0; - } - else - { - r_data.DoAmbient[i] = ambient[i].num; - ambient[i].channel = 0; - } - } - return err; +HSaveError ReadAudio(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + // Game content assertion + if (!AssertGameContent(err, in->ReadInt32(), game.audioClipTypes.size(), "Audio Clip Types")) + return err; + in->ReadInt32(); // audio clip count + /* [ivan-mogilko] looks like it's not necessary to assert, as there's no data serialized for clips + if (!AssertGameContent(err, in->ReadInt32(), game.audioClips.size(), "Audio Clips")) + return err;*/ + + // Audio types + for (size_t i = 0; i < game.audioClipTypes.size(); ++i) { + game.audioClipTypes[i].ReadFromSavegame(in.get()); + play.default_audio_type_volumes[i] = in->ReadInt32(); + } + + // Audio clips and crossfade + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { + RestoredData::ChannelInfo &chan_info = r_data.AudioChans[i]; + chan_info.Pos = 0; + chan_info.ClipID = in->ReadInt32(); + if (chan_info.ClipID >= 0) { + chan_info.Pos = in->ReadInt32(); + if (chan_info.Pos < 0) + chan_info.Pos = 0; + chan_info.Priority = in->ReadInt32(); + chan_info.Repeat = in->ReadInt32(); + chan_info.Vol = in->ReadInt32(); + chan_info.Pan = in->ReadInt32(); + chan_info.VolAsPercent = in->ReadInt32(); + chan_info.PanAsPercent = in->ReadInt32(); + chan_info.Speed = 1000; + chan_info.Speed = in->ReadInt32(); + if (cmp_ver >= 1) { + chan_info.XSource = in->ReadInt32(); + chan_info.YSource = in->ReadInt32(); + chan_info.MaxDist = in->ReadInt32(); + } + } + } + crossFading = in->ReadInt32(); + crossFadeVolumePerStep = in->ReadInt32(); + crossFadeStep = in->ReadInt32(); + crossFadeVolumeAtStart = in->ReadInt32(); + // preserve legacy music type setting + current_music_type = in->ReadInt32(); + + // Ambient sound + for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) + ambient[i].ReadFromFile(in.get()); + for (int i = 1; i < MAX_SOUND_CHANNELS; ++i) { + if (ambient[i].channel == 0) { + r_data.DoAmbient[i] = 0; + } else { + r_data.DoAmbient[i] = ambient[i].num; + ambient[i].channel = 0; + } + } + return err; } -void WriteTimesRun272(const Interaction &intr, Stream *out) -{ - for (size_t i = 0; i < intr.Events.size(); ++i) - out->WriteInt32(intr.Events[i].TimesRun); +void WriteTimesRun272(const Interaction &intr, Stream *out) { + for (size_t i = 0; i < intr.Events.size(); ++i) + out->WriteInt32(intr.Events[i].TimesRun); } -void WriteInteraction272(const Interaction &intr, Stream *out) -{ - const size_t evt_count = intr.Events.size(); - out->WriteInt32(evt_count); - for (size_t i = 0; i < evt_count; ++i) - out->WriteInt32(intr.Events[i].Type); - WriteTimesRun272(intr, out); +void WriteInteraction272(const Interaction &intr, Stream *out) { + const size_t evt_count = intr.Events.size(); + out->WriteInt32(evt_count); + for (size_t i = 0; i < evt_count; ++i) + out->WriteInt32(intr.Events[i].Type); + WriteTimesRun272(intr, out); } -void ReadTimesRun272(Interaction &intr, Stream *in) -{ - for (size_t i = 0; i < intr.Events.size(); ++i) - intr.Events[i].TimesRun = in->ReadInt32(); +void ReadTimesRun272(Interaction &intr, Stream *in) { + for (size_t i = 0; i < intr.Events.size(); ++i) + intr.Events[i].TimesRun = in->ReadInt32(); } -HSaveError ReadInteraction272(Interaction &intr, Stream *in) -{ - HSaveError err; - const size_t evt_count = in->ReadInt32(); - if (!AssertCompatLimit(err, evt_count, MAX_NEWINTERACTION_EVENTS, "interactions")) - return err; - intr.Events.resize(evt_count); - for (size_t i = 0; i < evt_count; ++i) - intr.Events[i].Type = in->ReadInt32(); - ReadTimesRun272(intr, in); - return err; +HSaveError ReadInteraction272(Interaction &intr, Stream *in) { + HSaveError err; + const size_t evt_count = in->ReadInt32(); + if (!AssertCompatLimit(err, evt_count, MAX_NEWINTERACTION_EVENTS, "interactions")) + return err; + intr.Events.resize(evt_count); + for (size_t i = 0; i < evt_count; ++i) + intr.Events[i].Type = in->ReadInt32(); + ReadTimesRun272(intr, in); + return err; } -HSaveError WriteCharacters(PStream out) -{ - out->WriteInt32(game.numcharacters); - for (int i = 0; i < game.numcharacters; ++i) - { - game.chars[i].WriteToFile(out.get()); - charextra[i].WriteToFile(out.get()); - Properties::WriteValues(play.charProps[i], out.get()); - if (loaded_game_file_version <= kGameVersion_272) - WriteTimesRun272(*game.intrChar[i], out.get()); - // character movement path cache - mls[CHMLSOFFS + i].WriteToFile(out.get()); - } - return HSaveError::None(); +HSaveError WriteCharacters(PStream out) { + out->WriteInt32(game.numcharacters); + for (int i = 0; i < game.numcharacters; ++i) { + game.chars[i].WriteToFile(out.get()); + charextra[i].WriteToFile(out.get()); + Properties::WriteValues(play.charProps[i], out.get()); + if (loaded_game_file_version <= kGameVersion_272) + WriteTimesRun272(*game.intrChar[i], out.get()); + // character movement path cache + mls[CHMLSOFFS + i].WriteToFile(out.get()); + } + return HSaveError::None(); } -HSaveError ReadCharacters(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - if (!AssertGameContent(err, in->ReadInt32(), game.numcharacters, "Characters")) - return err; - for (int i = 0; i < game.numcharacters; ++i) - { - game.chars[i].ReadFromFile(in.get()); - charextra[i].ReadFromFile(in.get()); - Properties::ReadValues(play.charProps[i], in.get()); - if (loaded_game_file_version <= kGameVersion_272) - ReadTimesRun272(*game.intrChar[i], in.get()); - // character movement path cache - err = mls[CHMLSOFFS + i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0); - if (!err) - return err; - } - return err; +HSaveError ReadCharacters(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numcharacters, "Characters")) + return err; + for (int i = 0; i < game.numcharacters; ++i) { + game.chars[i].ReadFromFile(in.get()); + charextra[i].ReadFromFile(in.get()); + Properties::ReadValues(play.charProps[i], in.get()); + if (loaded_game_file_version <= kGameVersion_272) + ReadTimesRun272(*game.intrChar[i], in.get()); + // character movement path cache + err = mls[CHMLSOFFS + i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0); + if (!err) + return err; + } + return err; } -HSaveError WriteDialogs(PStream out) -{ - out->WriteInt32(game.numdialog); - for (int i = 0; i < game.numdialog; ++i) - { - dialog[i].WriteToSavegame(out.get()); - } - return HSaveError::None(); +HSaveError WriteDialogs(PStream out) { + out->WriteInt32(game.numdialog); + for (int i = 0; i < game.numdialog; ++i) { + dialog[i].WriteToSavegame(out.get()); + } + return HSaveError::None(); } -HSaveError ReadDialogs(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - if (!AssertGameContent(err, in->ReadInt32(), game.numdialog, "Dialogs")) - return err; - for (int i = 0; i < game.numdialog; ++i) - { - dialog[i].ReadFromSavegame(in.get()); - } - return err; +HSaveError ReadDialogs(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numdialog, "Dialogs")) + return err; + for (int i = 0; i < game.numdialog; ++i) { + dialog[i].ReadFromSavegame(in.get()); + } + return err; } -HSaveError WriteGUI(PStream out) -{ - // GUI state - WriteFormatTag(out, "GUIs"); - out->WriteInt32(game.numgui); - for (int i = 0; i < game.numgui; ++i) - guis[i].WriteToSavegame(out.get()); - - WriteFormatTag(out, "GUIButtons"); - out->WriteInt32(numguibuts); - for (int i = 0; i < numguibuts; ++i) - guibuts[i].WriteToSavegame(out.get()); - - WriteFormatTag(out, "GUILabels"); - out->WriteInt32(numguilabels); - for (int i = 0; i < numguilabels; ++i) - guilabels[i].WriteToSavegame(out.get()); - - WriteFormatTag(out, "GUIInvWindows"); - out->WriteInt32(numguiinv); - for (int i = 0; i < numguiinv; ++i) - guiinv[i].WriteToSavegame(out.get()); - - WriteFormatTag(out, "GUISliders"); - out->WriteInt32(numguislider); - for (int i = 0; i < numguislider; ++i) - guislider[i].WriteToSavegame(out.get()); - - WriteFormatTag(out, "GUITextBoxes"); - out->WriteInt32(numguitext); - for (int i = 0; i < numguitext; ++i) - guitext[i].WriteToSavegame(out.get()); - - WriteFormatTag(out, "GUIListBoxes"); - out->WriteInt32(numguilist); - for (int i = 0; i < numguilist; ++i) - guilist[i].WriteToSavegame(out.get()); - - // Animated buttons - WriteFormatTag(out, "AnimatedButtons"); - out->WriteInt32(numAnimButs); - for (int i = 0; i < numAnimButs; ++i) - animbuts[i].WriteToFile(out.get()); - return HSaveError::None(); +HSaveError WriteGUI(PStream out) { + // GUI state + WriteFormatTag(out, "GUIs"); + out->WriteInt32(game.numgui); + for (int i = 0; i < game.numgui; ++i) + guis[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUIButtons"); + out->WriteInt32(numguibuts); + for (int i = 0; i < numguibuts; ++i) + guibuts[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUILabels"); + out->WriteInt32(numguilabels); + for (int i = 0; i < numguilabels; ++i) + guilabels[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUIInvWindows"); + out->WriteInt32(numguiinv); + for (int i = 0; i < numguiinv; ++i) + guiinv[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUISliders"); + out->WriteInt32(numguislider); + for (int i = 0; i < numguislider; ++i) + guislider[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUITextBoxes"); + out->WriteInt32(numguitext); + for (int i = 0; i < numguitext; ++i) + guitext[i].WriteToSavegame(out.get()); + + WriteFormatTag(out, "GUIListBoxes"); + out->WriteInt32(numguilist); + for (int i = 0; i < numguilist; ++i) + guilist[i].WriteToSavegame(out.get()); + + // Animated buttons + WriteFormatTag(out, "AnimatedButtons"); + out->WriteInt32(numAnimButs); + for (int i = 0; i < numAnimButs; ++i) + animbuts[i].WriteToFile(out.get()); + return HSaveError::None(); } -HSaveError ReadGUI(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - const GuiSvgVersion svg_ver = (GuiSvgVersion)cmp_ver; - // GUI state - if (!AssertFormatTagStrict(err, in, "GUIs")) - return err; - if (!AssertGameContent(err, in->ReadInt32(), game.numgui, "GUIs")) - return err; - for (int i = 0; i < game.numgui; ++i) - guis[i].ReadFromSavegame(in.get(), svg_ver); - - if (!AssertFormatTagStrict(err, in, "GUIButtons")) - return err; - if (!AssertGameContent(err, in->ReadInt32(), numguibuts, "GUI Buttons")) - return err; - for (int i = 0; i < numguibuts; ++i) - guibuts[i].ReadFromSavegame(in.get(), svg_ver); - - if (!AssertFormatTagStrict(err, in, "GUILabels")) - return err; - if (!AssertGameContent(err, in->ReadInt32(), numguilabels, "GUI Labels")) - return err; - for (int i = 0; i < numguilabels; ++i) - guilabels[i].ReadFromSavegame(in.get(), svg_ver); - - if (!AssertFormatTagStrict(err, in, "GUIInvWindows")) - return err; - if (!AssertGameContent(err, in->ReadInt32(), numguiinv, "GUI InvWindows")) - return err; - for (int i = 0; i < numguiinv; ++i) - guiinv[i].ReadFromSavegame(in.get(), svg_ver); - - if (!AssertFormatTagStrict(err, in, "GUISliders")) - return err; - if (!AssertGameContent(err, in->ReadInt32(), numguislider, "GUI Sliders")) - return err; - for (int i = 0; i < numguislider; ++i) - guislider[i].ReadFromSavegame(in.get(), svg_ver); - - if (!AssertFormatTagStrict(err, in, "GUITextBoxes")) - return err; - if (!AssertGameContent(err, in->ReadInt32(), numguitext, "GUI TextBoxes")) - return err; - for (int i = 0; i < numguitext; ++i) - guitext[i].ReadFromSavegame(in.get(), svg_ver); - - if (!AssertFormatTagStrict(err, in, "GUIListBoxes")) - return err; - if (!AssertGameContent(err, in->ReadInt32(), numguilist, "GUI ListBoxes")) - return err; - for (int i = 0; i < numguilist; ++i) - guilist[i].ReadFromSavegame(in.get(), svg_ver); - - // Animated buttons - if (!AssertFormatTagStrict(err, in, "AnimatedButtons")) - return err; - int anim_count = in->ReadInt32(); - if (!AssertCompatLimit(err, anim_count, MAX_ANIMATING_BUTTONS, "animated buttons")) - return err; - numAnimButs = anim_count; - for (int i = 0; i < numAnimButs; ++i) - animbuts[i].ReadFromFile(in.get()); - return err; +HSaveError ReadGUI(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + const GuiSvgVersion svg_ver = (GuiSvgVersion)cmp_ver; + // GUI state + if (!AssertFormatTagStrict(err, in, "GUIs")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), game.numgui, "GUIs")) + return err; + for (int i = 0; i < game.numgui; ++i) + guis[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUIButtons")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguibuts, "GUI Buttons")) + return err; + for (int i = 0; i < numguibuts; ++i) + guibuts[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUILabels")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguilabels, "GUI Labels")) + return err; + for (int i = 0; i < numguilabels; ++i) + guilabels[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUIInvWindows")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguiinv, "GUI InvWindows")) + return err; + for (int i = 0; i < numguiinv; ++i) + guiinv[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUISliders")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguislider, "GUI Sliders")) + return err; + for (int i = 0; i < numguislider; ++i) + guislider[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUITextBoxes")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguitext, "GUI TextBoxes")) + return err; + for (int i = 0; i < numguitext; ++i) + guitext[i].ReadFromSavegame(in.get(), svg_ver); + + if (!AssertFormatTagStrict(err, in, "GUIListBoxes")) + return err; + if (!AssertGameContent(err, in->ReadInt32(), numguilist, "GUI ListBoxes")) + return err; + for (int i = 0; i < numguilist; ++i) + guilist[i].ReadFromSavegame(in.get(), svg_ver); + + // Animated buttons + if (!AssertFormatTagStrict(err, in, "AnimatedButtons")) + return err; + int anim_count = in->ReadInt32(); + if (!AssertCompatLimit(err, anim_count, MAX_ANIMATING_BUTTONS, "animated buttons")) + return err; + numAnimButs = anim_count; + for (int i = 0; i < numAnimButs; ++i) + animbuts[i].ReadFromFile(in.get()); + return err; } -HSaveError WriteInventory(PStream out) -{ - out->WriteInt32(game.numinvitems); - for (int i = 0; i < game.numinvitems; ++i) - { - game.invinfo[i].WriteToSavegame(out.get()); - Properties::WriteValues(play.invProps[i], out.get()); - if (loaded_game_file_version <= kGameVersion_272) - WriteTimesRun272(*game.intrInv[i], out.get()); - } - return HSaveError::None(); +HSaveError WriteInventory(PStream out) { + out->WriteInt32(game.numinvitems); + for (int i = 0; i < game.numinvitems; ++i) { + game.invinfo[i].WriteToSavegame(out.get()); + Properties::WriteValues(play.invProps[i], out.get()); + if (loaded_game_file_version <= kGameVersion_272) + WriteTimesRun272(*game.intrInv[i], out.get()); + } + return HSaveError::None(); } -HSaveError ReadInventory(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - if (!AssertGameContent(err, in->ReadInt32(), game.numinvitems, "Inventory Items")) - return err; - for (int i = 0; i < game.numinvitems; ++i) - { - game.invinfo[i].ReadFromSavegame(in.get()); - Properties::ReadValues(play.invProps[i], in.get()); - if (loaded_game_file_version <= kGameVersion_272) - ReadTimesRun272(*game.intrInv[i], in.get()); - } - return err; +HSaveError ReadInventory(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numinvitems, "Inventory Items")) + return err; + for (int i = 0; i < game.numinvitems; ++i) { + game.invinfo[i].ReadFromSavegame(in.get()); + Properties::ReadValues(play.invProps[i], in.get()); + if (loaded_game_file_version <= kGameVersion_272) + ReadTimesRun272(*game.intrInv[i], in.get()); + } + return err; } -HSaveError WriteMouseCursors(PStream out) -{ - out->WriteInt32(game.numcursors); - for (int i = 0; i < game.numcursors; ++i) - { - game.mcurs[i].WriteToSavegame(out.get()); - } - return HSaveError::None(); +HSaveError WriteMouseCursors(PStream out) { + out->WriteInt32(game.numcursors); + for (int i = 0; i < game.numcursors; ++i) { + game.mcurs[i].WriteToSavegame(out.get()); + } + return HSaveError::None(); } -HSaveError ReadMouseCursors(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - if (!AssertGameContent(err, in->ReadInt32(), game.numcursors, "Mouse Cursors")) - return err; - for (int i = 0; i < game.numcursors; ++i) - { - game.mcurs[i].ReadFromSavegame(in.get()); - } - return err; +HSaveError ReadMouseCursors(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numcursors, "Mouse Cursors")) + return err; + for (int i = 0; i < game.numcursors; ++i) { + game.mcurs[i].ReadFromSavegame(in.get()); + } + return err; } -HSaveError WriteViews(PStream out) -{ - out->WriteInt32(game.numviews); - for (int view = 0; view < game.numviews; ++view) - { - out->WriteInt32(views[view].numLoops); - for (int loop = 0; loop < views[view].numLoops; ++loop) - { - out->WriteInt32(views[view].loops[loop].numFrames); - for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) - { - out->WriteInt32(views[view].loops[loop].frames[frame].sound); - out->WriteInt32(views[view].loops[loop].frames[frame].pic); - } - } - } - return HSaveError::None(); +HSaveError WriteViews(PStream out) { + out->WriteInt32(game.numviews); + for (int view = 0; view < game.numviews; ++view) { + out->WriteInt32(views[view].numLoops); + for (int loop = 0; loop < views[view].numLoops; ++loop) { + out->WriteInt32(views[view].loops[loop].numFrames); + for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) { + out->WriteInt32(views[view].loops[loop].frames[frame].sound); + out->WriteInt32(views[view].loops[loop].frames[frame].pic); + } + } + } + return HSaveError::None(); } -HSaveError ReadViews(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - if (!AssertGameContent(err, in->ReadInt32(), game.numviews, "Views")) - return err; - for (int view = 0; view < game.numviews; ++view) - { - if (!AssertGameObjectContent(err, in->ReadInt32(), views[view].numLoops, - "Loops", "View", view)) - return err; - for (int loop = 0; loop < views[view].numLoops; ++loop) - { - if (!AssertGameObjectContent2(err, in->ReadInt32(), views[view].loops[loop].numFrames, - "Frame", "View", view, "Loop", loop)) - return err; - for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) - { - views[view].loops[loop].frames[frame].sound = in->ReadInt32(); - views[view].loops[loop].frames[frame].pic = in->ReadInt32(); - } - } - } - return err; +HSaveError ReadViews(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + if (!AssertGameContent(err, in->ReadInt32(), game.numviews, "Views")) + return err; + for (int view = 0; view < game.numviews; ++view) { + if (!AssertGameObjectContent(err, in->ReadInt32(), views[view].numLoops, + "Loops", "View", view)) + return err; + for (int loop = 0; loop < views[view].numLoops; ++loop) { + if (!AssertGameObjectContent2(err, in->ReadInt32(), views[view].loops[loop].numFrames, + "Frame", "View", view, "Loop", loop)) + return err; + for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) { + views[view].loops[loop].frames[frame].sound = in->ReadInt32(); + views[view].loops[loop].frames[frame].pic = in->ReadInt32(); + } + } + } + return err; } -HSaveError WriteDynamicSprites(PStream out) -{ - const soff_t ref_pos = out->GetPosition(); - out->WriteInt32(0); // number of dynamic sprites - out->WriteInt32(0); // top index - int count = 0; - int top_index = 1; - for (int i = 1; i < spriteset.GetSpriteSlotCount(); ++i) - { - if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) - { - count++; - top_index = i; - out->WriteInt32(i); - out->WriteInt32(game.SpriteInfos[i].Flags); - serialize_bitmap(spriteset[i], out.get()); - } - } - const soff_t end_pos = out->GetPosition(); - out->Seek(ref_pos, kSeekBegin); - out->WriteInt32(count); - out->WriteInt32(top_index); - out->Seek(end_pos, kSeekBegin); - return HSaveError::None(); +HSaveError WriteDynamicSprites(PStream out) { + const soff_t ref_pos = out->GetPosition(); + out->WriteInt32(0); // number of dynamic sprites + out->WriteInt32(0); // top index + int count = 0; + int top_index = 1; + for (int i = 1; i < spriteset.GetSpriteSlotCount(); ++i) { + if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) { + count++; + top_index = i; + out->WriteInt32(i); + out->WriteInt32(game.SpriteInfos[i].Flags); + serialize_bitmap(spriteset[i], out.get()); + } + } + const soff_t end_pos = out->GetPosition(); + out->Seek(ref_pos, kSeekBegin); + out->WriteInt32(count); + out->WriteInt32(top_index); + out->Seek(end_pos, kSeekBegin); + return HSaveError::None(); } -HSaveError ReadDynamicSprites(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - const int spr_count = in->ReadInt32(); - // ensure the sprite set is at least large enough - // to accomodate top dynamic sprite index - const int top_index = in->ReadInt32(); - spriteset.EnlargeTo(top_index); - for (int i = 0; i < spr_count; ++i) - { - int id = in->ReadInt32(); - int flags = in->ReadInt32(); - add_dynamic_sprite(id, read_serialized_bitmap(in.get())); - game.SpriteInfos[id].Flags = flags; - } - return err; +HSaveError ReadDynamicSprites(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + const int spr_count = in->ReadInt32(); + // ensure the sprite set is at least large enough + // to accomodate top dynamic sprite index + const int top_index = in->ReadInt32(); + spriteset.EnlargeTo(top_index); + for (int i = 0; i < spr_count; ++i) { + int id = in->ReadInt32(); + int flags = in->ReadInt32(); + add_dynamic_sprite(id, read_serialized_bitmap(in.get())); + game.SpriteInfos[id].Flags = flags; + } + return err; } -HSaveError WriteOverlays(PStream out) -{ - out->WriteInt32(screenover.size()); - for (const auto &over : screenover) - { - over.WriteToFile(out.get()); - serialize_bitmap(over.pic, out.get()); - } - return HSaveError::None(); +HSaveError WriteOverlays(PStream out) { + out->WriteInt32(screenover.size()); + for (const auto &over : screenover) { + over.WriteToFile(out.get()); + serialize_bitmap(over.pic, out.get()); + } + return HSaveError::None(); } -HSaveError ReadOverlays(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - size_t over_count = in->ReadInt32(); - for (size_t i = 0; i < over_count; ++i) - { - ScreenOverlay over; - over.ReadFromFile(in.get(), cmp_ver); - if (over.hasSerializedBitmap) - over.pic = read_serialized_bitmap(in.get()); - screenover.push_back(over); - } - return err; +HSaveError ReadOverlays(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + size_t over_count = in->ReadInt32(); + for (size_t i = 0; i < over_count; ++i) { + ScreenOverlay over; + over.ReadFromFile(in.get(), cmp_ver); + if (over.hasSerializedBitmap) + over.pic = read_serialized_bitmap(in.get()); + screenover.push_back(over); + } + return err; } -HSaveError WriteDynamicSurfaces(PStream out) -{ - out->WriteInt32(MAX_DYNAMIC_SURFACES); - for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) - { - if (dynamicallyCreatedSurfaces[i] == nullptr) - { - out->WriteInt8(0); - } - else - { - out->WriteInt8(1); - serialize_bitmap(dynamicallyCreatedSurfaces[i], out.get()); - } - } - return HSaveError::None(); +HSaveError WriteDynamicSurfaces(PStream out) { + out->WriteInt32(MAX_DYNAMIC_SURFACES); + for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) { + if (dynamicallyCreatedSurfaces[i] == nullptr) { + out->WriteInt8(0); + } else { + out->WriteInt8(1); + serialize_bitmap(dynamicallyCreatedSurfaces[i], out.get()); + } + } + return HSaveError::None(); } -HSaveError ReadDynamicSurfaces(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - if (!AssertCompatLimit(err, in->ReadInt32(), MAX_DYNAMIC_SURFACES, "Drawing Surfaces")) - return err; - // Load the surfaces into a temporary array since ccUnserialiseObjects will destroy them otherwise - r_data.DynamicSurfaces.resize(MAX_DYNAMIC_SURFACES); - for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) - { - if (in->ReadInt8() == 0) - r_data.DynamicSurfaces[i] = nullptr; - else - r_data.DynamicSurfaces[i] = read_serialized_bitmap(in.get()); - } - return err; +HSaveError ReadDynamicSurfaces(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + if (!AssertCompatLimit(err, in->ReadInt32(), MAX_DYNAMIC_SURFACES, "Drawing Surfaces")) + return err; + // Load the surfaces into a temporary array since ccUnserialiseObjects will destroy them otherwise + r_data.DynamicSurfaces.resize(MAX_DYNAMIC_SURFACES); + for (int i = 0; i < MAX_DYNAMIC_SURFACES; ++i) { + if (in->ReadInt8() == 0) + r_data.DynamicSurfaces[i] = nullptr; + else + r_data.DynamicSurfaces[i] = read_serialized_bitmap(in.get()); + } + return err; } -HSaveError WriteScriptModules(PStream out) -{ - // write the data segment of the global script - int data_len = gameinst->globaldatasize; - out->WriteInt32(data_len); - if (data_len > 0) - out->Write(gameinst->globaldata, data_len); - // write the script modules data segments - out->WriteInt32(numScriptModules); - for (int i = 0; i < numScriptModules; ++i) - { - data_len = moduleInst[i]->globaldatasize; - out->WriteInt32(data_len); - if (data_len > 0) - out->Write(moduleInst[i]->globaldata, data_len); - } - return HSaveError::None(); +HSaveError WriteScriptModules(PStream out) { + // write the data segment of the global script + int data_len = gameinst->globaldatasize; + out->WriteInt32(data_len); + if (data_len > 0) + out->Write(gameinst->globaldata, data_len); + // write the script modules data segments + out->WriteInt32(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) { + data_len = moduleInst[i]->globaldatasize; + out->WriteInt32(data_len); + if (data_len > 0) + out->Write(moduleInst[i]->globaldata, data_len); + } + return HSaveError::None(); } -HSaveError ReadScriptModules(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - // read the global script data segment - int data_len = in->ReadInt32(); - if (!AssertGameContent(err, data_len, pp.GlScDataSize, "global script data")) - return err; - r_data.GlobalScript.Len = data_len; - r_data.GlobalScript.Data.reset(new char[data_len]); - in->Read(r_data.GlobalScript.Data.get(), data_len); - - if (!AssertGameContent(err, in->ReadInt32(), numScriptModules, "Script Modules")) - return err; - r_data.ScriptModules.resize(numScriptModules); - for (int i = 0; i < numScriptModules; ++i) - { - data_len = in->ReadInt32(); - if (!AssertGameObjectContent(err, data_len, pp.ScMdDataSize[i], "script module data", "module", i)) - return err; - r_data.ScriptModules[i].Len = data_len; - r_data.ScriptModules[i].Data.reset(new char[data_len]); - in->Read(r_data.ScriptModules[i].Data.get(), data_len); - } - return err; +HSaveError ReadScriptModules(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + // read the global script data segment + int data_len = in->ReadInt32(); + if (!AssertGameContent(err, data_len, pp.GlScDataSize, "global script data")) + return err; + r_data.GlobalScript.Len = data_len; + r_data.GlobalScript.Data.reset(new char[data_len]); + in->Read(r_data.GlobalScript.Data.get(), data_len); + + if (!AssertGameContent(err, in->ReadInt32(), numScriptModules, "Script Modules")) + return err; + r_data.ScriptModules.resize(numScriptModules); + for (int i = 0; i < numScriptModules; ++i) { + data_len = in->ReadInt32(); + if (!AssertGameObjectContent(err, data_len, pp.ScMdDataSize[i], "script module data", "module", i)) + return err; + r_data.ScriptModules[i].Len = data_len; + r_data.ScriptModules[i].Data.reset(new char[data_len]); + in->Read(r_data.ScriptModules[i].Data.get(), data_len); + } + return err; } -HSaveError WriteRoomStates(PStream out) -{ - // write the room state for all the rooms the player has been in - out->WriteInt32(MAX_ROOMS); - for (int i = 0; i < MAX_ROOMS; ++i) - { - if (isRoomStatusValid(i)) - { - RoomStatus *roomstat = getRoomStatus(i); - if (roomstat->beenhere) - { - out->WriteInt32(i); - WriteFormatTag(out, "RoomState", true); - roomstat->WriteToSavegame(out.get()); - WriteFormatTag(out, "RoomState", false); - } - else - out->WriteInt32(-1); - } - else - out->WriteInt32(-1); - } - return HSaveError::None(); +HSaveError WriteRoomStates(PStream out) { + // write the room state for all the rooms the player has been in + out->WriteInt32(MAX_ROOMS); + for (int i = 0; i < MAX_ROOMS; ++i) { + if (isRoomStatusValid(i)) { + RoomStatus *roomstat = getRoomStatus(i); + if (roomstat->beenhere) { + out->WriteInt32(i); + WriteFormatTag(out, "RoomState", true); + roomstat->WriteToSavegame(out.get()); + WriteFormatTag(out, "RoomState", false); + } else + out->WriteInt32(-1); + } else + out->WriteInt32(-1); + } + return HSaveError::None(); } -HSaveError ReadRoomStates(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - int roomstat_count = in->ReadInt32(); - for (; roomstat_count > 0; --roomstat_count) - { - int id = in->ReadInt32(); - // If id == -1, then the player has not been there yet (or room state was reset) - if (id != -1) - { - if (!AssertCompatRange(err, id, 0, MAX_ROOMS - 1, "room index")) - return err; - if (!AssertFormatTagStrict(err, in, "RoomState", true)) - return err; - RoomStatus *roomstat = getRoomStatus(id); - roomstat->ReadFromSavegame(in.get()); - if (!AssertFormatTagStrict(err, in, "RoomState", false)) - return err; - } - } - return HSaveError::None(); +HSaveError ReadRoomStates(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + int roomstat_count = in->ReadInt32(); + for (; roomstat_count > 0; --roomstat_count) { + int id = in->ReadInt32(); + // If id == -1, then the player has not been there yet (or room state was reset) + if (id != -1) { + if (!AssertCompatRange(err, id, 0, MAX_ROOMS - 1, "room index")) + return err; + if (!AssertFormatTagStrict(err, in, "RoomState", true)) + return err; + RoomStatus *roomstat = getRoomStatus(id); + roomstat->ReadFromSavegame(in.get()); + if (!AssertFormatTagStrict(err, in, "RoomState", false)) + return err; + } + } + return HSaveError::None(); } -HSaveError WriteThisRoom(PStream out) -{ - out->WriteInt32(displayed_room); - if (displayed_room < 0) - return HSaveError::None(); - - // modified room backgrounds - for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) - { - out->WriteBool(play.raw_modified[i] != 0); - if (play.raw_modified[i]) - serialize_bitmap(thisroom.BgFrames[i].Graphic.get(), out.get()); - } - out->WriteBool(raw_saved_screen != nullptr); - if (raw_saved_screen) - serialize_bitmap(raw_saved_screen, out.get()); - - // room region state - for (int i = 0; i < MAX_ROOM_REGIONS; ++i) - { - out->WriteInt32(thisroom.Regions[i].Light); - out->WriteInt32(thisroom.Regions[i].Tint); - } - for (int i = 0; i < MAX_WALK_AREAS + 1; ++i) - { - out->WriteInt32(thisroom.WalkAreas[i].ScalingFar); - out->WriteInt32(thisroom.WalkAreas[i].ScalingNear); - } - - // room object movement paths cache - out->WriteInt32(thisroom.ObjectCount + 1); - for (size_t i = 0; i < thisroom.ObjectCount + 1; ++i) - { - mls[i].WriteToFile(out.get()); - } - - // room music volume - out->WriteInt32(thisroom.Options.MusicVolume); - - // persistent room's indicator - const bool persist = displayed_room < MAX_ROOMS; - out->WriteBool(persist); - // write the current troom state, in case they save in temporary room - if (!persist) - troom.WriteToSavegame(out.get()); - return HSaveError::None(); +HSaveError WriteThisRoom(PStream out) { + out->WriteInt32(displayed_room); + if (displayed_room < 0) + return HSaveError::None(); + + // modified room backgrounds + for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) { + out->WriteBool(play.raw_modified[i] != 0); + if (play.raw_modified[i]) + serialize_bitmap(thisroom.BgFrames[i].Graphic.get(), out.get()); + } + out->WriteBool(raw_saved_screen != nullptr); + if (raw_saved_screen) + serialize_bitmap(raw_saved_screen, out.get()); + + // room region state + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) { + out->WriteInt32(thisroom.Regions[i].Light); + out->WriteInt32(thisroom.Regions[i].Tint); + } + for (int i = 0; i < MAX_WALK_AREAS + 1; ++i) { + out->WriteInt32(thisroom.WalkAreas[i].ScalingFar); + out->WriteInt32(thisroom.WalkAreas[i].ScalingNear); + } + + // room object movement paths cache + out->WriteInt32(thisroom.ObjectCount + 1); + for (size_t i = 0; i < thisroom.ObjectCount + 1; ++i) { + mls[i].WriteToFile(out.get()); + } + + // room music volume + out->WriteInt32(thisroom.Options.MusicVolume); + + // persistent room's indicator + const bool persist = displayed_room < MAX_ROOMS; + out->WriteBool(persist); + // write the current troom state, in case they save in temporary room + if (!persist) + troom.WriteToSavegame(out.get()); + return HSaveError::None(); } -HSaveError ReadThisRoom(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - HSaveError err; - displayed_room = in->ReadInt32(); - if (displayed_room < 0) - return err; - - // modified room backgrounds - for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) - { - play.raw_modified[i] = in->ReadBool(); - if (play.raw_modified[i]) - r_data.RoomBkgScene[i].reset(read_serialized_bitmap(in.get())); - else - r_data.RoomBkgScene[i] = nullptr; - } - if (in->ReadBool()) - raw_saved_screen = read_serialized_bitmap(in.get()); - - // room region state - for (int i = 0; i < MAX_ROOM_REGIONS; ++i) - { - r_data.RoomLightLevels[i] = in->ReadInt32(); - r_data.RoomTintLevels[i] = in->ReadInt32(); - } - for (int i = 0; i < MAX_WALK_AREAS + 1; ++i) - { - r_data.RoomZoomLevels1[i] = in->ReadInt32(); - r_data.RoomZoomLevels2[i] = in->ReadInt32(); - } - - // room object movement paths cache - int objmls_count = in->ReadInt32(); - if (!AssertCompatLimit(err, objmls_count, CHMLSOFFS, "room object move lists")) - return err; - for (int i = 0; i < objmls_count; ++i) - { - err = mls[i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0); - if (!err) - return err; - } - - // save the new room music vol for later use - r_data.RoomVolume = (RoomVolumeMod)in->ReadInt32(); - - // read the current troom state, in case they saved in temporary room - if (!in->ReadBool()) - troom.ReadFromSavegame(in.get()); - - return HSaveError::None(); +HSaveError ReadThisRoom(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + HSaveError err; + displayed_room = in->ReadInt32(); + if (displayed_room < 0) + return err; + + // modified room backgrounds + for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) { + play.raw_modified[i] = in->ReadBool(); + if (play.raw_modified[i]) + r_data.RoomBkgScene[i].reset(read_serialized_bitmap(in.get())); + else + r_data.RoomBkgScene[i] = nullptr; + } + if (in->ReadBool()) + raw_saved_screen = read_serialized_bitmap(in.get()); + + // room region state + for (int i = 0; i < MAX_ROOM_REGIONS; ++i) { + r_data.RoomLightLevels[i] = in->ReadInt32(); + r_data.RoomTintLevels[i] = in->ReadInt32(); + } + for (int i = 0; i < MAX_WALK_AREAS + 1; ++i) { + r_data.RoomZoomLevels1[i] = in->ReadInt32(); + r_data.RoomZoomLevels2[i] = in->ReadInt32(); + } + + // room object movement paths cache + int objmls_count = in->ReadInt32(); + if (!AssertCompatLimit(err, objmls_count, CHMLSOFFS, "room object move lists")) + return err; + for (int i = 0; i < objmls_count; ++i) { + err = mls[i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0); + if (!err) + return err; + } + + // save the new room music vol for later use + r_data.RoomVolume = (RoomVolumeMod)in->ReadInt32(); + + // read the current troom state, in case they saved in temporary room + if (!in->ReadBool()) + troom.ReadFromSavegame(in.get()); + + return HSaveError::None(); } -HSaveError WriteManagedPool(PStream out) -{ - ccSerializeAllObjects(out.get()); - return HSaveError::None(); +HSaveError WriteManagedPool(PStream out) { + ccSerializeAllObjects(out.get()); + return HSaveError::None(); } -HSaveError ReadManagedPool(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - if (ccUnserializeAllObjects(in.get(), &ccUnserializer)) - { - return new SavegameError(kSvgErr_GameObjectInitFailed, - String::FromFormat("Managed pool deserialization failed: %s", ccErrorString.GetCStr())); - } - return HSaveError::None(); +HSaveError ReadManagedPool(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + if (ccUnserializeAllObjects(in.get(), &ccUnserializer)) { + return new SavegameError(kSvgErr_GameObjectInitFailed, + String::FromFormat("Managed pool deserialization failed: %s", ccErrorString.GetCStr())); + } + return HSaveError::None(); } -HSaveError WritePluginData(PStream out) -{ - auto pluginFileHandle = AGSE_SAVEGAME; - pl_set_file_handle(pluginFileHandle, out.get()); - pl_run_plugin_hooks(AGSE_SAVEGAME, pluginFileHandle); - pl_clear_file_handle(); - return HSaveError::None(); +HSaveError WritePluginData(PStream out) { + auto pluginFileHandle = AGSE_SAVEGAME; + pl_set_file_handle(pluginFileHandle, out.get()); + pl_run_plugin_hooks(AGSE_SAVEGAME, pluginFileHandle); + pl_clear_file_handle(); + return HSaveError::None(); } -HSaveError ReadPluginData(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) -{ - auto pluginFileHandle = AGSE_RESTOREGAME; - pl_set_file_handle(pluginFileHandle, in.get()); - pl_run_plugin_hooks(AGSE_RESTOREGAME, pluginFileHandle); - pl_clear_file_handle(); - return HSaveError::None(); +HSaveError ReadPluginData(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { + auto pluginFileHandle = AGSE_RESTOREGAME; + pl_set_file_handle(pluginFileHandle, in.get()); + pl_run_plugin_hooks(AGSE_RESTOREGAME, pluginFileHandle); + pl_clear_file_handle(); + return HSaveError::None(); } // Description of a supported game state serialization component -struct ComponentHandler -{ - String Name; // internal component's ID - int32_t Version; // current version to write and the highest supported version - int32_t LowestVersion; // lowest supported version that the engine can read - HSaveError (*Serialize) (PStream); - HSaveError (*Unserialize)(PStream, int32_t cmp_ver, const PreservedParams&, RestoredData&); +struct ComponentHandler { + String Name; // internal component's ID + int32_t Version; // current version to write and the highest supported version + int32_t LowestVersion; // lowest supported version that the engine can read + HSaveError(*Serialize)(PStream); + HSaveError(*Unserialize)(PStream, int32_t cmp_ver, const PreservedParams &, RestoredData &); }; // Array of supported components -ComponentHandler ComponentHandlers[] = -{ - { - "Game State", - kGSSvgVersion_3510, - kGSSvgVersion_Initial, - WriteGameState, - ReadGameState - }, - { - "Audio", - 1, - 0, - WriteAudio, - ReadAudio - }, - { - "Characters", - 1, - 0, - WriteCharacters, - ReadCharacters - }, - { - "Dialogs", - 0, - 0, - WriteDialogs, - ReadDialogs - }, - { - "GUI", - kGuiSvgVersion_350, - kGuiSvgVersion_Initial, - WriteGUI, - ReadGUI - }, - { - "Inventory Items", - 0, - 0, - WriteInventory, - ReadInventory - }, - { - "Mouse Cursors", - 0, - 0, - WriteMouseCursors, - ReadMouseCursors - }, - { - "Views", - 0, - 0, - WriteViews, - ReadViews - }, - { - "Dynamic Sprites", - 0, - 0, - WriteDynamicSprites, - ReadDynamicSprites - }, - { - "Overlays", - 1, - 0, - WriteOverlays, - ReadOverlays - }, - { - "Drawing Surfaces", - 0, - 0, - WriteDynamicSurfaces, - ReadDynamicSurfaces - }, - { - "Script Modules", - 0, - 0, - WriteScriptModules, - ReadScriptModules - }, - { - "Room States", - 0, - 0, - WriteRoomStates, - ReadRoomStates - }, - { - "Loaded Room State", - 1, - 0, - WriteThisRoom, - ReadThisRoom - }, - { - "Managed Pool", - 1, - 0, - WriteManagedPool, - ReadManagedPool - }, - { - "Plugin Data", - 0, - 0, - WritePluginData, - ReadPluginData - }, - { nullptr, 0, 0, nullptr, nullptr } // end of array +ComponentHandler ComponentHandlers[] = { + { + "Game State", + kGSSvgVersion_3510, + kGSSvgVersion_Initial, + WriteGameState, + ReadGameState + }, + { + "Audio", + 1, + 0, + WriteAudio, + ReadAudio + }, + { + "Characters", + 1, + 0, + WriteCharacters, + ReadCharacters + }, + { + "Dialogs", + 0, + 0, + WriteDialogs, + ReadDialogs + }, + { + "GUI", + kGuiSvgVersion_350, + kGuiSvgVersion_Initial, + WriteGUI, + ReadGUI + }, + { + "Inventory Items", + 0, + 0, + WriteInventory, + ReadInventory + }, + { + "Mouse Cursors", + 0, + 0, + WriteMouseCursors, + ReadMouseCursors + }, + { + "Views", + 0, + 0, + WriteViews, + ReadViews + }, + { + "Dynamic Sprites", + 0, + 0, + WriteDynamicSprites, + ReadDynamicSprites + }, + { + "Overlays", + 1, + 0, + WriteOverlays, + ReadOverlays + }, + { + "Drawing Surfaces", + 0, + 0, + WriteDynamicSurfaces, + ReadDynamicSurfaces + }, + { + "Script Modules", + 0, + 0, + WriteScriptModules, + ReadScriptModules + }, + { + "Room States", + 0, + 0, + WriteRoomStates, + ReadRoomStates + }, + { + "Loaded Room State", + 1, + 0, + WriteThisRoom, + ReadThisRoom + }, + { + "Managed Pool", + 1, + 0, + WriteManagedPool, + ReadManagedPool + }, + { + "Plugin Data", + 0, + 0, + WritePluginData, + ReadPluginData + }, + { nullptr, 0, 0, nullptr, nullptr } // end of array }; typedef std::map HandlersMap; -void GenerateHandlersMap(HandlersMap &map) -{ - map.clear(); - for (int i = 0; !ComponentHandlers[i].Name.IsEmpty(); ++i) - map[ComponentHandlers[i].Name] = ComponentHandlers[i]; +void GenerateHandlersMap(HandlersMap &map) { + map.clear(); + for (int i = 0; !ComponentHandlers[i].Name.IsEmpty(); ++i) + map[ComponentHandlers[i].Name] = ComponentHandlers[i]; } // A helper struct to pass to (de)serialization handlers -struct SvgCmpReadHelper -{ - SavegameVersion Version; // general savegame version - const PreservedParams &PP; // previous game state kept for reference - RestoredData &RData; // temporary storage for loaded data, that - // will be applied after loading is done - // The map of serialization handlers, one per supported component type ID - HandlersMap Handlers; - - SvgCmpReadHelper(SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) - : Version(svg_version) - , PP(pp) - , RData(r_data) - { - } +struct SvgCmpReadHelper { + SavegameVersion Version; // general savegame version + const PreservedParams &PP; // previous game state kept for reference + RestoredData &RData; // temporary storage for loaded data, that + // will be applied after loading is done + // The map of serialization handlers, one per supported component type ID + HandlersMap Handlers; + + SvgCmpReadHelper(SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) + : Version(svg_version) + , PP(pp) + , RData(r_data) { + } }; // The basic information about deserialized component, used for debugging purposes -struct ComponentInfo -{ - String Name; // internal component's ID - int32_t Version; // data format version - soff_t Offset; // offset at which an opening tag is located - soff_t DataOffset; // offset at which component data begins - soff_t DataSize; // expected size of component data - - ComponentInfo() : Version(-1), Offset(0), DataOffset(0), DataSize(0) {} +struct ComponentInfo { + String Name; // internal component's ID + int32_t Version; // data format version + soff_t Offset; // offset at which an opening tag is located + soff_t DataOffset; // offset at which component data begins + soff_t DataSize; // expected size of component data + + ComponentInfo() : Version(-1), Offset(0), DataOffset(0), DataSize(0) {} }; -HSaveError ReadComponent(PStream in, SvgCmpReadHelper &hlp, ComponentInfo &info) -{ - info = ComponentInfo(); // reset in case of early error - info.Offset = in->GetPosition(); - if (!ReadFormatTag(in, info.Name, true)) - return new SavegameError(kSvgErr_ComponentOpeningTagFormat); - info.Version = in->ReadInt32(); - info.DataSize = hlp.Version >= kSvgVersion_Cmp_64bit ? in->ReadInt64() : in->ReadInt32(); - info.DataOffset = in->GetPosition(); - - const ComponentHandler *handler = nullptr; - std::map::const_iterator it_hdr = hlp.Handlers.find(info.Name); - if (it_hdr != hlp.Handlers.end()) - handler = &it_hdr->second; - - if (!handler || !handler->Unserialize) - return new SavegameError(kSvgErr_UnsupportedComponent); - if (info.Version > handler->Version || info.Version < handler->LowestVersion) - return new SavegameError(kSvgErr_UnsupportedComponentVersion, String::FromFormat("Saved version: %d, supported: %d - %d", info.Version, handler->LowestVersion, handler->Version)); - HSaveError err = handler->Unserialize(in, info.Version, hlp.PP, hlp.RData); - if (!err) - return err; - if (in->GetPosition() - info.DataOffset != info.DataSize) - return new SavegameError(kSvgErr_ComponentSizeMismatch, String::FromFormat("Expected: %lld, actual: %lld", info.DataSize, in->GetPosition() - info.DataOffset)); - if (!AssertFormatTag(in, info.Name, false)) - return new SavegameError(kSvgErr_ComponentClosingTagFormat); - return HSaveError::None(); +HSaveError ReadComponent(PStream in, SvgCmpReadHelper &hlp, ComponentInfo &info) { + info = ComponentInfo(); // reset in case of early error + info.Offset = in->GetPosition(); + if (!ReadFormatTag(in, info.Name, true)) + return new SavegameError(kSvgErr_ComponentOpeningTagFormat); + info.Version = in->ReadInt32(); + info.DataSize = hlp.Version >= kSvgVersion_Cmp_64bit ? in->ReadInt64() : in->ReadInt32(); + info.DataOffset = in->GetPosition(); + + const ComponentHandler *handler = nullptr; + std::map::const_iterator it_hdr = hlp.Handlers.find(info.Name); + if (it_hdr != hlp.Handlers.end()) + handler = &it_hdr->second; + + if (!handler || !handler->Unserialize) + return new SavegameError(kSvgErr_UnsupportedComponent); + if (info.Version > handler->Version || info.Version < handler->LowestVersion) + return new SavegameError(kSvgErr_UnsupportedComponentVersion, String::FromFormat("Saved version: %d, supported: %d - %d", info.Version, handler->LowestVersion, handler->Version)); + HSaveError err = handler->Unserialize(in, info.Version, hlp.PP, hlp.RData); + if (!err) + return err; + if (in->GetPosition() - info.DataOffset != info.DataSize) + return new SavegameError(kSvgErr_ComponentSizeMismatch, String::FromFormat("Expected: %lld, actual: %lld", info.DataSize, in->GetPosition() - info.DataOffset)); + if (!AssertFormatTag(in, info.Name, false)) + return new SavegameError(kSvgErr_ComponentClosingTagFormat); + return HSaveError::None(); } -HSaveError ReadAll(PStream in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) -{ - // Prepare a helper struct we will be passing to the block reading proc - SvgCmpReadHelper hlp(svg_version, pp, r_data); - GenerateHandlersMap(hlp.Handlers); - - size_t idx = 0; - if (!AssertFormatTag(in, ComponentListTag, true)) - return new SavegameError(kSvgErr_ComponentListOpeningTagFormat); - do - { - // Look out for the end of the component list: - // this is the only way how this function ends with success - soff_t off = in->GetPosition(); - if (AssertFormatTag(in, ComponentListTag, false)) - return HSaveError::None(); - // If the list's end was not detected, then seek back and continue reading - in->Seek(off, kSeekBegin); - - ComponentInfo info; - HSaveError err = ReadComponent(in, hlp, info); - if (!err) - { - return new SavegameError(kSvgErr_ComponentUnserialization, - String::FromFormat("(#%d) %s, version %i, at offset %u.", - idx, info.Name.IsEmpty() ? "unknown" : info.Name.GetCStr(), info.Version, info.Offset), - err); - } - update_polled_stuff_if_runtime(); - idx++; - } - while (!in->EOS()); - return new SavegameError(kSvgErr_ComponentListClosingTagMissing); +HSaveError ReadAll(PStream in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data) { + // Prepare a helper struct we will be passing to the block reading proc + SvgCmpReadHelper hlp(svg_version, pp, r_data); + GenerateHandlersMap(hlp.Handlers); + + size_t idx = 0; + if (!AssertFormatTag(in, ComponentListTag, true)) + return new SavegameError(kSvgErr_ComponentListOpeningTagFormat); + do { + // Look out for the end of the component list: + // this is the only way how this function ends with success + soff_t off = in->GetPosition(); + if (AssertFormatTag(in, ComponentListTag, false)) + return HSaveError::None(); + // If the list's end was not detected, then seek back and continue reading + in->Seek(off, kSeekBegin); + + ComponentInfo info; + HSaveError err = ReadComponent(in, hlp, info); + if (!err) { + return new SavegameError(kSvgErr_ComponentUnserialization, + String::FromFormat("(#%d) %s, version %i, at offset %u.", + idx, info.Name.IsEmpty() ? "unknown" : info.Name.GetCStr(), info.Version, info.Offset), + err); + } + update_polled_stuff_if_runtime(); + idx++; + } while (!in->EOS()); + return new SavegameError(kSvgErr_ComponentListClosingTagMissing); } -HSaveError WriteComponent(PStream out, ComponentHandler &hdlr) -{ - WriteFormatTag(out, hdlr.Name, true); - out->WriteInt32(hdlr.Version); - soff_t ref_pos = out->GetPosition(); - out->WriteInt64(0); // placeholder for the component size - HSaveError err = hdlr.Serialize(out); - soff_t end_pos = out->GetPosition(); - out->Seek(ref_pos, kSeekBegin); - out->WriteInt64(end_pos - ref_pos - sizeof(int64_t)); // size of serialized component data - out->Seek(end_pos, kSeekBegin); - if (err) - WriteFormatTag(out, hdlr.Name, false); - return err; +HSaveError WriteComponent(PStream out, ComponentHandler &hdlr) { + WriteFormatTag(out, hdlr.Name, true); + out->WriteInt32(hdlr.Version); + soff_t ref_pos = out->GetPosition(); + out->WriteInt64(0); // placeholder for the component size + HSaveError err = hdlr.Serialize(out); + soff_t end_pos = out->GetPosition(); + out->Seek(ref_pos, kSeekBegin); + out->WriteInt64(end_pos - ref_pos - sizeof(int64_t)); // size of serialized component data + out->Seek(end_pos, kSeekBegin); + if (err) + WriteFormatTag(out, hdlr.Name, false); + return err; } -HSaveError WriteAllCommon(PStream out) -{ - WriteFormatTag(out, ComponentListTag, true); - for (int type = 0; !ComponentHandlers[type].Name.IsEmpty(); ++type) - { - HSaveError err = WriteComponent(out, ComponentHandlers[type]); - if (!err) - { - return new SavegameError(kSvgErr_ComponentSerialization, - String::FromFormat("Component: (#%d) %s", type, ComponentHandlers[type].Name.GetCStr()), - err); - } - update_polled_stuff_if_runtime(); - } - WriteFormatTag(out, ComponentListTag, false); - return HSaveError::None(); +HSaveError WriteAllCommon(PStream out) { + WriteFormatTag(out, ComponentListTag, true); + for (int type = 0; !ComponentHandlers[type].Name.IsEmpty(); ++type) { + HSaveError err = WriteComponent(out, ComponentHandlers[type]); + if (!err) { + return new SavegameError(kSvgErr_ComponentSerialization, + String::FromFormat("Component: (#%d) %s", type, ComponentHandlers[type].Name.GetCStr()), + err); + } + update_polled_stuff_if_runtime(); + } + WriteFormatTag(out, ComponentListTag, false); + return HSaveError::None(); } } // namespace SavegameBlocks diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h index 7f99fe7d501d..77355ee30433 100644 --- a/engines/ags/engine/game/savegame_components.h +++ b/engines/ags/engine/game/savegame_components.h @@ -26,13 +26,13 @@ #include "game/savegame.h" #include "util/stream.h" -namespace AGS -{ +namespace AGS { -namespace Common { struct Interaction; } +namespace Common { +struct Interaction; +} -namespace Engine -{ +namespace Engine { using Common::Stream; typedef std::shared_ptr PStream; @@ -40,22 +40,21 @@ typedef std::shared_ptr PStream; struct PreservedParams; struct RestoredData; -namespace SavegameComponents -{ - // Reads all available components from the stream - HSaveError ReadAll(PStream in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data); - // Writes a full list of common components to the stream - HSaveError WriteAllCommon(PStream out); - - // Utility functions for reading and writing legacy interactions, - // or their "times run" counters separately. - void ReadTimesRun272(Interaction &intr, Stream *in); - HSaveError ReadInteraction272(Interaction &intr, Stream *in); - void WriteTimesRun272(const Interaction &intr, Stream *out); - void WriteInteraction272(const Interaction &intr, Stream *out); - - // Precreates primary camera and viewport and reads legacy camera data - void ReadLegacyCameraState(Stream *in, RestoredData &r_data); +namespace SavegameComponents { +// Reads all available components from the stream +HSaveError ReadAll(PStream in, SavegameVersion svg_version, const PreservedParams &pp, RestoredData &r_data); +// Writes a full list of common components to the stream +HSaveError WriteAllCommon(PStream out); + +// Utility functions for reading and writing legacy interactions, +// or their "times run" counters separately. +void ReadTimesRun272(Interaction &intr, Stream *in); +HSaveError ReadInteraction272(Interaction &intr, Stream *in); +void WriteTimesRun272(const Interaction &intr, Stream *out); +void WriteInteraction272(const Interaction &intr, Stream *out); + +// Precreates primary camera and viewport and reads legacy camera data +void ReadLegacyCameraState(Stream *in, RestoredData &r_data); } } // namespace Engine diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index bfbda8f0b46a..9970ecd90433 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -30,10 +30,8 @@ #include "media/audio/audiodefines.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using AGS::Common::Bitmap; @@ -43,107 +41,98 @@ typedef std::shared_ptr PBitmap; // parameters that are saved before the save restoration // and either applied or compared to new values after // loading save data -struct PreservedParams -{ - // Whether speech and audio packages available - int SpeechVOX; - int MusicVOX; - // Script global data sizes - int GlScDataSize; - std::vector ScMdDataSize; - - PreservedParams(); +struct PreservedParams { + // Whether speech and audio packages available + int SpeechVOX; + int MusicVOX; + // Script global data sizes + int GlScDataSize; + std::vector ScMdDataSize; + + PreservedParams(); }; -enum GameViewCamFlags -{ - kSvgGameAutoRoomView = 0x01 +enum GameViewCamFlags { + kSvgGameAutoRoomView = 0x01 }; -enum CameraSaveFlags -{ - kSvgCamPosLocked = 0x01 +enum CameraSaveFlags { + kSvgCamPosLocked = 0x01 }; -enum ViewportSaveFlags -{ - kSvgViewportVisible = 0x01 +enum ViewportSaveFlags { + kSvgViewportVisible = 0x01 }; // RestoredData keeps certain temporary data to help with // the restoration process -struct RestoredData -{ - int FPS; - // Unserialized bitmaps for dynamic surfaces - std::vector DynamicSurfaces; - // Scripts global data - struct ScriptData - { - std::shared_ptr Data; - size_t Len; - - ScriptData(); - }; - ScriptData GlobalScript; - std::vector ScriptModules; - // Room data (has to be be preserved until room is loaded) - PBitmap RoomBkgScene[MAX_ROOM_BGFRAMES]; - short RoomLightLevels[MAX_ROOM_REGIONS]; - int RoomTintLevels[MAX_ROOM_REGIONS]; - short RoomZoomLevels1[MAX_WALK_AREAS + 1]; - short RoomZoomLevels2[MAX_WALK_AREAS + 1]; - RoomVolumeMod RoomVolume; - // Mouse cursor parameters - int CursorID; - int CursorMode; - // General audio - struct ChannelInfo - { - int ClipID = 0; - int Pos = 0; - int Priority = 0; - int Repeat = 0; - int Vol = 0; - int VolAsPercent = 0; - int Pan = 0; - int PanAsPercent = 0; - int Speed = 0; - // since version 1 - int XSource = -1; - int YSource = -1; - int MaxDist = 0; - }; - ChannelInfo AudioChans[MAX_SOUND_CHANNELS + 1]; - // Ambient sounds - int DoAmbient[MAX_SOUND_CHANNELS]; - // Viewport and camera data, has to be preserved and applied only after - // room gets loaded, because we must clamp these to room parameters. - struct ViewportData - { - int ID = -1; - int Flags = 0; - int Left = 0; - int Top = 0; - int Width = 0; - int Height = 0; - int ZOrder = 0; - int CamID = -1; - }; - struct CameraData - { - int ID = -1; - int Flags = 0; - int Left = 0; - int Top = 0; - int Width = 0; - int Height = 0; - }; - std::vector Viewports; - std::vector Cameras; - int32_t Camera0_Flags = 0; // flags for primary camera, when data is read in legacy order - - RestoredData(); +struct RestoredData { + int FPS; + // Unserialized bitmaps for dynamic surfaces + std::vector DynamicSurfaces; + // Scripts global data + struct ScriptData { + std::shared_ptr Data; + size_t Len; + + ScriptData(); + }; + ScriptData GlobalScript; + std::vector ScriptModules; + // Room data (has to be be preserved until room is loaded) + PBitmap RoomBkgScene[MAX_ROOM_BGFRAMES]; + short RoomLightLevels[MAX_ROOM_REGIONS]; + int RoomTintLevels[MAX_ROOM_REGIONS]; + short RoomZoomLevels1[MAX_WALK_AREAS + 1]; + short RoomZoomLevels2[MAX_WALK_AREAS + 1]; + RoomVolumeMod RoomVolume; + // Mouse cursor parameters + int CursorID; + int CursorMode; + // General audio + struct ChannelInfo { + int ClipID = 0; + int Pos = 0; + int Priority = 0; + int Repeat = 0; + int Vol = 0; + int VolAsPercent = 0; + int Pan = 0; + int PanAsPercent = 0; + int Speed = 0; + // since version 1 + int XSource = -1; + int YSource = -1; + int MaxDist = 0; + }; + ChannelInfo AudioChans[MAX_SOUND_CHANNELS + 1]; + // Ambient sounds + int DoAmbient[MAX_SOUND_CHANNELS]; + // Viewport and camera data, has to be preserved and applied only after + // room gets loaded, because we must clamp these to room parameters. + struct ViewportData { + int ID = -1; + int Flags = 0; + int Left = 0; + int Top = 0; + int Width = 0; + int Height = 0; + int ZOrder = 0; + int CamID = -1; + }; + struct CameraData { + int ID = -1; + int Flags = 0; + int Left = 0; + int Top = 0; + int Width = 0; + int Height = 0; + }; + std::vector Viewports; + std::vector Cameras; + int32_t Camera0_Flags = 0; // flags for primary camera, when data is read in legacy order + + RestoredData(); }; } // namespace Engine diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp index 33ef5e6af432..30390da8e79d 100644 --- a/engines/ags/engine/game/viewport.cpp +++ b/engines/ags/engine/game/viewport.cpp @@ -30,204 +30,175 @@ using namespace AGS::Common; extern RoomStruct thisroom; -void Camera::SetID(int id) -{ - _id = id; +void Camera::SetID(int id) { + _id = id; } // Returns Room camera position and size inside the room (in room coordinates) -const Rect &Camera::GetRect() const -{ - return _position; +const Rect &Camera::GetRect() const { + return _position; } // Sets explicit room camera's orthographic size -void Camera::SetSize(const Size cam_size) -{ - // TODO: currently we don't support having camera larger than room background - // (or rather - looking outside of the room background); look into this later - const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); - Size real_size = Size::Clamp(cam_size, Size(1, 1), real_room_sz); - - _position.SetWidth(real_size.Width); - _position.SetHeight(real_size.Height); - for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) - { - auto locked_vp = vp->lock(); - if (locked_vp) - locked_vp->AdjustTransformation(); - } - _hasChangedSize = true; +void Camera::SetSize(const Size cam_size) { + // TODO: currently we don't support having camera larger than room background + // (or rather - looking outside of the room background); look into this later + const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height)); + Size real_size = Size::Clamp(cam_size, Size(1, 1), real_room_sz); + + _position.SetWidth(real_size.Width); + _position.SetHeight(real_size.Height); + for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) { + auto locked_vp = vp->lock(); + if (locked_vp) + locked_vp->AdjustTransformation(); + } + _hasChangedSize = true; } // Puts room camera to the new location in the room -void Camera::SetAt(int x, int y) -{ - int cw = _position.GetWidth(); - int ch = _position.GetHeight(); - int room_width = data_to_game_coord(thisroom.Width); - int room_height = data_to_game_coord(thisroom.Height); - x = Math::Clamp(x, 0, room_width - cw); - y = Math::Clamp(y, 0, room_height - ch); - _position.MoveTo(Point(x, y)); - _hasChangedPosition = true; +void Camera::SetAt(int x, int y) { + int cw = _position.GetWidth(); + int ch = _position.GetHeight(); + int room_width = data_to_game_coord(thisroom.Width); + int room_height = data_to_game_coord(thisroom.Height); + x = Math::Clamp(x, 0, room_width - cw); + y = Math::Clamp(y, 0, room_height - ch); + _position.MoveTo(Point(x, y)); + _hasChangedPosition = true; } // Tells if camera is currently locked at custom position -bool Camera::IsLocked() const -{ - return _locked; +bool Camera::IsLocked() const { + return _locked; } // Locks room camera at its current position -void Camera::Lock() -{ - debug_script_log("Room camera locked"); - _locked = true; +void Camera::Lock() { + debug_script_log("Room camera locked"); + _locked = true; } // Similar to SetAt, but also locks camera preventing it from following player character -void Camera::LockAt(int x, int y) -{ - debug_script_log("Room camera locked to %d,%d", x, y); - SetAt(x, y); - _locked = true; +void Camera::LockAt(int x, int y) { + debug_script_log("Room camera locked to %d,%d", x, y); + SetAt(x, y); + _locked = true; } // Releases camera lock, letting it follow player character -void Camera::Release() -{ - _locked = false; - debug_script_log("Room camera released back to engine control"); +void Camera::Release() { + _locked = false; + debug_script_log("Room camera released back to engine control"); } // Link this camera to a new viewport; this does not unlink any linked ones -void Camera::LinkToViewport(ViewportRef viewport) -{ - auto new_locked = viewport.lock(); - if (!new_locked) - return; - for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) - { - auto old_locked = vp->lock(); - if (old_locked->GetID() == new_locked->GetID()) - return; - } - _viewportRefs.push_back(viewport); +void Camera::LinkToViewport(ViewportRef viewport) { + auto new_locked = viewport.lock(); + if (!new_locked) + return; + for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) { + auto old_locked = vp->lock(); + if (old_locked->GetID() == new_locked->GetID()) + return; + } + _viewportRefs.push_back(viewport); } // Unlinks this camera from a given viewport; does nothing if link did not exist -void Camera::UnlinkFromViewport(int id) -{ - for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) - { - auto locked = vp->lock(); - if (locked && locked->GetID() == id) - { - _viewportRefs.erase(vp); - return; - } - } -} - -const std::vector &Camera::GetLinkedViewports() const -{ - return _viewportRefs; -} - -void Viewport::SetID(int id) -{ - _id = id; -} - -void Viewport::SetRect(const Rect &rc) -{ - // TODO: consider allowing size 0,0, in which case viewport is considered not visible - Size fix_size = rc.GetSize().IsNull() ? Size(1, 1) : rc.GetSize(); - _position = RectWH(rc.Left, rc.Top, fix_size.Width, fix_size.Height); - AdjustTransformation(); - _hasChangedPosition = true; - _hasChangedSize = true; -} - -void Viewport::SetSize(const Size sz) -{ - // TODO: consider allowing size 0,0, in which case viewport is considered not visible - Size fix_size = sz.IsNull() ? Size(1, 1) : sz; - _position = RectWH(_position.Left, _position.Top, fix_size.Width, fix_size.Height); - AdjustTransformation(); - _hasChangedSize = true; -} - -void Viewport::SetAt(int x, int y) -{ - _position.MoveTo(Point(x, y)); - AdjustTransformation(); - _hasChangedPosition = true; -} - -void Viewport::SetVisible(bool on) -{ - _visible = on; - _hasChangedVisible = true; -} - -void Viewport::SetZOrder(int zorder) -{ - _zorder = zorder; - _hasChangedVisible = true; -} - -void Viewport::AdjustTransformation() -{ - auto locked_cam = _camera.lock(); - if (locked_cam) - _transform.Init(locked_cam->GetRect().GetSize(), _position); -} - -PCamera Viewport::GetCamera() const -{ - return _camera.lock(); -} - -void Viewport::LinkCamera(PCamera cam) -{ - _camera = cam; - AdjustTransformation(); -} - -VpPoint Viewport::RoomToScreen(int roomx, int roomy, bool clip) const -{ - auto cam = _camera.lock(); - if (!cam) - return std::make_pair(Point(), -1); - const Rect &camr = cam->GetRect(); - Point screen_pt = _transform.Scale(Point(roomx - camr.Left, roomy - camr.Top)); - if (clip && !_position.IsInside(screen_pt)) - return std::make_pair(Point(), -1); - return std::make_pair(screen_pt, _id); -} - -VpPoint Viewport::ScreenToRoom(int scrx, int scry, bool clip, bool convert_cam_to_data) const -{ - Point screen_pt(scrx, scry); - if (clip && !_position.IsInside(screen_pt)) - return std::make_pair(Point(), -1); - auto cam = _camera.lock(); - if (!cam) - return std::make_pair(Point(), -1); - - const Rect &camr = cam->GetRect(); - Point p = _transform.UnScale(screen_pt); - if (convert_cam_to_data) - { - p.X += game_to_data_coord(camr.Left); - p.Y += game_to_data_coord(camr.Top); - } - else - { - p.X += camr.Left; - p.Y += camr.Top; - } - return std::make_pair(p, _id); +void Camera::UnlinkFromViewport(int id) { + for (auto vp = _viewportRefs.begin(); vp != _viewportRefs.end(); ++vp) { + auto locked = vp->lock(); + if (locked && locked->GetID() == id) { + _viewportRefs.erase(vp); + return; + } + } +} + +const std::vector &Camera::GetLinkedViewports() const { + return _viewportRefs; +} + +void Viewport::SetID(int id) { + _id = id; +} + +void Viewport::SetRect(const Rect &rc) { + // TODO: consider allowing size 0,0, in which case viewport is considered not visible + Size fix_size = rc.GetSize().IsNull() ? Size(1, 1) : rc.GetSize(); + _position = RectWH(rc.Left, rc.Top, fix_size.Width, fix_size.Height); + AdjustTransformation(); + _hasChangedPosition = true; + _hasChangedSize = true; +} + +void Viewport::SetSize(const Size sz) { + // TODO: consider allowing size 0,0, in which case viewport is considered not visible + Size fix_size = sz.IsNull() ? Size(1, 1) : sz; + _position = RectWH(_position.Left, _position.Top, fix_size.Width, fix_size.Height); + AdjustTransformation(); + _hasChangedSize = true; +} + +void Viewport::SetAt(int x, int y) { + _position.MoveTo(Point(x, y)); + AdjustTransformation(); + _hasChangedPosition = true; +} + +void Viewport::SetVisible(bool on) { + _visible = on; + _hasChangedVisible = true; +} + +void Viewport::SetZOrder(int zorder) { + _zorder = zorder; + _hasChangedVisible = true; +} + +void Viewport::AdjustTransformation() { + auto locked_cam = _camera.lock(); + if (locked_cam) + _transform.Init(locked_cam->GetRect().GetSize(), _position); +} + +PCamera Viewport::GetCamera() const { + return _camera.lock(); +} + +void Viewport::LinkCamera(PCamera cam) { + _camera = cam; + AdjustTransformation(); +} + +VpPoint Viewport::RoomToScreen(int roomx, int roomy, bool clip) const { + auto cam = _camera.lock(); + if (!cam) + return std::make_pair(Point(), -1); + const Rect &camr = cam->GetRect(); + Point screen_pt = _transform.Scale(Point(roomx - camr.Left, roomy - camr.Top)); + if (clip && !_position.IsInside(screen_pt)) + return std::make_pair(Point(), -1); + return std::make_pair(screen_pt, _id); +} + +VpPoint Viewport::ScreenToRoom(int scrx, int scry, bool clip, bool convert_cam_to_data) const { + Point screen_pt(scrx, scry); + if (clip && !_position.IsInside(screen_pt)) + return std::make_pair(Point(), -1); + auto cam = _camera.lock(); + if (!cam) + return std::make_pair(Point(), -1); + + const Rect &camr = cam->GetRect(); + Point p = _transform.UnScale(screen_pt); + if (convert_cam_to_data) { + p.X += game_to_data_coord(camr.Left); + p.Y += game_to_data_coord(camr.Top); + } else { + p.X += camr.Left; + p.Y += camr.Top; + } + return std::make_pair(p, _id); } diff --git a/engines/ags/engine/game/viewport.h b/engines/ags/engine/game/viewport.h index f6f820f14dbf..b5b100b5329f 100644 --- a/engines/ags/engine/game/viewport.h +++ b/engines/ags/engine/game/viewport.h @@ -46,9 +46,9 @@ typedef std::weak_ptr ViewportRef; // From https://stackoverflow.com/questions/45507041/how-to-check-if-weak-ptr-is-empty-non-assigned // Tests that weak_ptr is empty (was not initialized with valid reference) template -bool is_uninitialized(std::weak_ptr const& weak) { - using wt = std::weak_ptr; - return !weak.owner_before(wt{}) && !wt{}.owner_before(weak); +bool is_uninitialized(std::weak_ptr const &weak) { + using wt = std::weak_ptr; + return !weak.owner_before(wt{}) &&!wt{} .owner_before(weak); } @@ -59,56 +59,60 @@ bool is_uninitialized(std::weak_ptr const& weak) { // Camera does not move on its own, this is performed by separate behavior // algorithm. But it provides "lock" property that tells if its position is // currently owned by user script. -class Camera -{ +class Camera { public: - // Gets camera ID (serves as an index) - inline int GetID() const { return _id; } - // Sets new camera ID - void SetID(int id); - // Returns Room camera position and size inside the room (in room coordinates) - const Rect &GetRect() const; - // Sets explicit room camera's orthographic size - void SetSize(const Size sz); - // Puts room camera to the new location in the room - void SetAt(int x, int y); - // Tells if camera is currently locked at custom position - bool IsLocked() const; - // Locks room camera at its current position - void Lock(); - // Similar to SetAt, but also locks camera preventing it from following player character - void LockAt(int x, int y); - // Releases camera lock, letting it follow player character - void Release(); - - // Link this camera to a new viewport; this does not unlink any linked ones - void LinkToViewport(ViewportRef viewport); - // Unlinks this camera from a given viewport; does nothing if link did not exist - void UnlinkFromViewport(int id); - // Get the array of linked viewport references - const std::vector &GetLinkedViewports() const; - - // Tell if this camera has changed recently - inline bool HasChangedPosition() const { return _hasChangedPosition; } - inline bool HasChangedSize() const { return _hasChangedSize; } - // Clears the changed flags - void ClearChangedFlags() - { - _hasChangedPosition = false; - _hasChangedSize = false; - } + // Gets camera ID (serves as an index) + inline int GetID() const { + return _id; + } + // Sets new camera ID + void SetID(int id); + // Returns Room camera position and size inside the room (in room coordinates) + const Rect &GetRect() const; + // Sets explicit room camera's orthographic size + void SetSize(const Size sz); + // Puts room camera to the new location in the room + void SetAt(int x, int y); + // Tells if camera is currently locked at custom position + bool IsLocked() const; + // Locks room camera at its current position + void Lock(); + // Similar to SetAt, but also locks camera preventing it from following player character + void LockAt(int x, int y); + // Releases camera lock, letting it follow player character + void Release(); + + // Link this camera to a new viewport; this does not unlink any linked ones + void LinkToViewport(ViewportRef viewport); + // Unlinks this camera from a given viewport; does nothing if link did not exist + void UnlinkFromViewport(int id); + // Get the array of linked viewport references + const std::vector &GetLinkedViewports() const; + + // Tell if this camera has changed recently + inline bool HasChangedPosition() const { + return _hasChangedPosition; + } + inline bool HasChangedSize() const { + return _hasChangedSize; + } + // Clears the changed flags + void ClearChangedFlags() { + _hasChangedPosition = false; + _hasChangedSize = false; + } private: - int _id = -1; - // Actual position and orthographic size - Rect _position; - // Locked or following player automatically - bool _locked = false; - // Linked viewport refs, used to notify viewports of camera changes - std::vector _viewportRefs; - // Flags that tell whether this camera's position on screen has changed recently - bool _hasChangedPosition = false; - bool _hasChangedSize = false; + int _id = -1; + // Actual position and orthographic size + Rect _position; + // Locked or following player automatically + bool _locked = false; + // Linked viewport refs, used to notify viewports of camera changes + std::vector _viewportRefs; + // Flags that tell whether this camera's position on screen has changed recently + bool _hasChangedPosition = false; + bool _hasChangedSize = false; }; @@ -120,84 +124,100 @@ typedef std::pair VpPoint; // Viewport class defines a rectangular area on game screen where the contents // of a Camera are rendered. // Viewport may have one linked camera at a time. -class Viewport -{ +class Viewport { public: - // Gets viewport ID (serves as an index) - inline int GetID() const { return _id; } - // Sets new viewport ID - void SetID(int id); - // Returns viewport's position on screen - inline const Rect &GetRect() const { return _position; } - // Returns viewport's room-to-screen transformation - inline const AGS::Engine::PlaneScaling &GetTransform() const { return _transform; } - // Set viewport's rectangle on screen - void SetRect(const Rect &rc); - // Sets viewport size - void SetSize(const Size sz); - // Sets viewport's position on screen - void SetAt(int x, int y); - - // Tells whether viewport content is rendered on screen - bool IsVisible() const { return _visible; } - // Changes viewport visibility - void SetVisible(bool on); - // Gets the order viewport is displayed on screen - int GetZOrder() const { return _zorder; } - // Sets the viewport's z-order on screen - void SetZOrder(int zorder); - - // Calculates room-to-viewport coordinate conversion. - void AdjustTransformation(); - // Returns linked camera - PCamera GetCamera() const; - // Links new camera to this viewport, overriding existing link; - // pass nullptr to leave viewport without a camera link - void LinkCamera(PCamera cam); - - // TODO: provide a Transform object here that does these conversions instead - // Converts room coordinates to the game screen coordinates through this viewport; - // if clipping is on, the function will fail for room coordinates outside of camera - VpPoint RoomToScreen(int roomx, int roomy, bool clip = false) const; - // Converts game screen coordinates to the room coordinates through this viewport; - // if clipping is on, the function will fail for screen coordinates outside of viewport; - // convert_cam_to_data parameter converts camera "game" coordinates to "data" units (legacy mode) - VpPoint ScreenToRoom(int scrx, int scry, bool clip = false, bool convert_cam_to_data = false) const; - - // Following functions tell if this viewport has changed recently - inline bool HasChangedPosition() const { return _hasChangedPosition; } - inline bool HasChangedSize() const { return _hasChangedSize; } - inline bool HasChangedVisible() const { return _hasChangedVisible; } - inline void SetChangedVisible() { _hasChangedVisible = true; } - // Clears the changed flags - inline void ClearChangedFlags() - { - _hasChangedPosition = false; - _hasChangedSize = false; - _hasChangedVisible = false; - } + // Gets viewport ID (serves as an index) + inline int GetID() const { + return _id; + } + // Sets new viewport ID + void SetID(int id); + // Returns viewport's position on screen + inline const Rect &GetRect() const { + return _position; + } + // Returns viewport's room-to-screen transformation + inline const AGS::Engine::PlaneScaling &GetTransform() const { + return _transform; + } + // Set viewport's rectangle on screen + void SetRect(const Rect &rc); + // Sets viewport size + void SetSize(const Size sz); + // Sets viewport's position on screen + void SetAt(int x, int y); + + // Tells whether viewport content is rendered on screen + bool IsVisible() const { + return _visible; + } + // Changes viewport visibility + void SetVisible(bool on); + // Gets the order viewport is displayed on screen + int GetZOrder() const { + return _zorder; + } + // Sets the viewport's z-order on screen + void SetZOrder(int zorder); + + // Calculates room-to-viewport coordinate conversion. + void AdjustTransformation(); + // Returns linked camera + PCamera GetCamera() const; + // Links new camera to this viewport, overriding existing link; + // pass nullptr to leave viewport without a camera link + void LinkCamera(PCamera cam); + + // TODO: provide a Transform object here that does these conversions instead + // Converts room coordinates to the game screen coordinates through this viewport; + // if clipping is on, the function will fail for room coordinates outside of camera + VpPoint RoomToScreen(int roomx, int roomy, bool clip = false) const; + // Converts game screen coordinates to the room coordinates through this viewport; + // if clipping is on, the function will fail for screen coordinates outside of viewport; + // convert_cam_to_data parameter converts camera "game" coordinates to "data" units (legacy mode) + VpPoint ScreenToRoom(int scrx, int scry, bool clip = false, bool convert_cam_to_data = false) const; + + // Following functions tell if this viewport has changed recently + inline bool HasChangedPosition() const { + return _hasChangedPosition; + } + inline bool HasChangedSize() const { + return _hasChangedSize; + } + inline bool HasChangedVisible() const { + return _hasChangedVisible; + } + inline void SetChangedVisible() { + _hasChangedVisible = true; + } + // Clears the changed flags + inline void ClearChangedFlags() { + _hasChangedPosition = false; + _hasChangedSize = false; + _hasChangedVisible = false; + } private: - // Parameterized implementation of screen-to-room coordinate conversion - VpPoint ScreenToRoomImpl(int scrx, int scry, bool clip, bool convert_cam_to_data); - - int _id = -1; - // Position of the viewport on screen - Rect _position; - // TODO: Camera reference (when supporting multiple cameras) - // Coordinate tranform between camera and viewport - // TODO: need to add rotate conversion to let script API support that; - // (maybe use full 3D matrix for that) - AGS::Engine::PlaneScaling _transform; - // Linked camera reference - CameraRef _camera; - bool _visible = true; - int _zorder = 0; - // Flags that tell whether this viewport's position on screen has changed recently - bool _hasChangedPosition = false; - bool _hasChangedOffscreen = false; - bool _hasChangedSize = false; - bool _hasChangedVisible = false; + // Parameterized implementation of screen-to-room coordinate conversion + VpPoint ScreenToRoomImpl(int scrx, int scry, bool clip, bool convert_cam_to_data); + + int _id = -1; + // Position of the viewport on screen + Rect _position; + // TODO: Camera reference (when supporting multiple cameras) + // Coordinate tranform between camera and viewport + // TODO: need to add rotate conversion to let script API support that; + // (maybe use full 3D matrix for that) + AGS::Engine::PlaneScaling _transform; + // Linked camera reference + CameraRef _camera; + bool _visible = true; + int _zorder = 0; + // Flags that tell whether this viewport's position on screen has changed recently + bool _hasChangedPosition = false; + bool _hasChangedOffscreen = false; + bool _hasChangedSize = false; + bool _hasChangedVisible = false; }; #endif diff --git a/engines/ags/engine/gfx/ali3dexception.h b/engines/ags/engine/gfx/ali3dexception.h index ab5fc9423050..92c40a96e60e 100644 --- a/engines/ags/engine/gfx/ali3dexception.h +++ b/engines/ags/engine/gfx/ali3dexception.h @@ -29,28 +29,22 @@ #ifndef AGS_ENGINE_GFX_ALI3DEXCEPTION_H #define AGS_ENGINE_GFX_ALI3DEXCEPTION_H -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class Ali3DException -{ +class Ali3DException { public: - Ali3DException(const char *message) - { - _message = message; - } + Ali3DException(const char *message) { + _message = message; + } - const char *_message; + const char *_message; }; -class Ali3DFullscreenLostException : public Ali3DException -{ +class Ali3DFullscreenLostException : public Ali3DException { public: - Ali3DFullscreenLostException() : Ali3DException("User has switched away from application") - { - } + Ali3DFullscreenLostException() : Ali3DException("User has switched away from application") { + } }; } // namespace Engine diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 69e36007c086..68102c6b0ba3 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -41,14 +41,14 @@ #define GL_CLAMP GL_CLAMP_TO_EDGE // Defined in Allegro -extern "C" +extern "C" { - void android_swap_buffers(); - void android_create_screen(int width, int height, int color_depth); - void android_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); + void android_swap_buffers(); + void android_create_screen(int width, int height, int color_depth); + void android_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); } -extern "C" void android_debug_printf(char* format, ...); +extern "C" void android_debug_printf(char *format, ...); extern unsigned int android_screen_physical_width; extern unsigned int android_screen_physical_height; @@ -58,7 +58,7 @@ extern int android_screen_initialized; #define device_mouse_setup android_mouse_setup #define device_swap_buffers android_swap_buffers -const char* fbo_extension_string = "GL_OES_framebuffer_object"; +const char *fbo_extension_string = "GL_OES_framebuffer_object"; #define glGenFramebuffersEXT glGenFramebuffersOES #define glDeleteFramebuffersEXT glDeleteFramebuffersOES @@ -77,13 +77,13 @@ const void (*glSwapIntervalEXT)(int) = NULL; #elif AGS_PLATFORM_OS_IOS -extern "C" +extern "C" { - void ios_swap_buffers(); - void ios_select_buffer(); - void ios_create_screen(); - float get_device_scale(); - void ios_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); + void ios_swap_buffers(); + void ios_select_buffer(); + void ios_create_screen(); + float get_device_scale(); + void ios_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); } #define glOrtho glOrthof @@ -97,7 +97,7 @@ extern int ios_screen_initialized; #define device_mouse_setup ios_mouse_setup #define device_swap_buffers ios_swap_buffers -const char* fbo_extension_string = "GL_OES_framebuffer_object"; +const char *fbo_extension_string = "GL_OES_framebuffer_object"; #define glGenFramebuffersEXT glGenFramebuffersOES #define glDeleteFramebuffersEXT glDeleteFramebuffersOES @@ -120,12 +120,9 @@ const void (*glSwapIntervalEXT)(int) = NULL; extern RGB palette[256]; -namespace AGS -{ -namespace Engine -{ -namespace OGL -{ +namespace AGS { +namespace Engine { +namespace OGL { using namespace AGS::Common; @@ -133,618 +130,569 @@ void ogl_dummy_vsync() { } #define GFX_OPENGL AL_ID('O','G','L',' ') -GFX_DRIVER gfx_opengl = -{ - GFX_OPENGL, - empty_string, - empty_string, - "OpenGL", - nullptr, // init - nullptr, // exit - nullptr, // AL_METHOD(int, scroll, (int x, int y)); - ogl_dummy_vsync, // vsync - nullptr, // setpalette - nullptr, // AL_METHOD(int, request_scroll, (int x, int y)); - nullptr, // AL_METHOD(int, poll_scroll, (void)); - nullptr, // AL_METHOD(void, enable_triple_buffer, (void)); - nullptr, //create_video_bitmap - nullptr, //destroy_video_bitmap - nullptr, //show_video_bitmap - nullptr, - nullptr, //gfx_directx_create_system_bitmap, - nullptr, //gfx_directx_destroy_system_bitmap, - nullptr, //gfx_directx_set_mouse_sprite, - nullptr, //gfx_directx_show_mouse, - nullptr, //gfx_directx_hide_mouse, - nullptr, //gfx_directx_move_mouse, - nullptr, // AL_METHOD(void, drawing_mode, (void)); - nullptr, // AL_METHOD(void, save_video_state, (void*)); - nullptr, // AL_METHOD(void, restore_video_state, (void*)); - nullptr, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); - nullptr, // AL_METHOD(int, fetch_mode_list, (void)); - 0, 0, // int w, h; - FALSE, // int linear; - 0, // long bank_size; - 0, // long bank_gran; - 0, // long vid_mem; - 0, // long vid_phys_base; - TRUE // int windowed; +GFX_DRIVER gfx_opengl = { + GFX_OPENGL, + empty_string, + empty_string, + "OpenGL", + nullptr, // init + nullptr, // exit + nullptr, // AL_METHOD(int, scroll, (int x, int y)); + ogl_dummy_vsync, // vsync + nullptr, // setpalette + nullptr, // AL_METHOD(int, request_scroll, (int x, int y)); + nullptr, // AL_METHOD(int, poll_scroll, (void)); + nullptr, // AL_METHOD(void, enable_triple_buffer, (void)); + nullptr, //create_video_bitmap + nullptr, //destroy_video_bitmap + nullptr, //show_video_bitmap + nullptr, + nullptr, //gfx_directx_create_system_bitmap, + nullptr, //gfx_directx_destroy_system_bitmap, + nullptr, //gfx_directx_set_mouse_sprite, + nullptr, //gfx_directx_show_mouse, + nullptr, //gfx_directx_hide_mouse, + nullptr, //gfx_directx_move_mouse, + nullptr, // AL_METHOD(void, drawing_mode, (void)); + nullptr, // AL_METHOD(void, save_video_state, (void*)); + nullptr, // AL_METHOD(void, restore_video_state, (void*)); + nullptr, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); + nullptr, // AL_METHOD(int, fetch_mode_list, (void)); + 0, 0, // int w, h; + FALSE, // int linear; + 0, // long bank_size; + 0, // long bank_gran; + 0, // long vid_mem; + 0, // long vid_phys_base; + TRUE // int windowed; }; -void OGLBitmap::Dispose() -{ - if (_tiles != nullptr) - { - for (int i = 0; i < _numTiles; i++) - glDeleteTextures(1, &(_tiles[i].texture)); +void OGLBitmap::Dispose() { + if (_tiles != nullptr) { + for (int i = 0; i < _numTiles; i++) + glDeleteTextures(1, &(_tiles[i].texture)); - free(_tiles); - _tiles = nullptr; - _numTiles = 0; - } - if (_vertex != nullptr) - { - free(_vertex); - _vertex = nullptr; - } + free(_tiles); + _tiles = nullptr; + _numTiles = 0; + } + if (_vertex != nullptr) { + free(_vertex); + _vertex = nullptr; + } } OGLGraphicsDriver::ShaderProgram::ShaderProgram() : Program(0), SamplerVar(0), ColorVar(0), AuxVar(0) {} -OGLGraphicsDriver::OGLGraphicsDriver() -{ +OGLGraphicsDriver::OGLGraphicsDriver() { #if AGS_PLATFORM_OS_WINDOWS - _hDC = NULL; - _hRC = NULL; - _hWnd = NULL; - _hInstance = NULL; - device_screen_physical_width = 0; - device_screen_physical_height = 0; + _hDC = NULL; + _hRC = NULL; + _hWnd = NULL; + _hInstance = NULL; + device_screen_physical_width = 0; + device_screen_physical_height = 0; #elif AGS_PLATFORM_OS_LINUX - device_screen_physical_width = 0; - device_screen_physical_height = 0; - _glxContext = nullptr; - _have_window = false; + device_screen_physical_width = 0; + device_screen_physical_height = 0; + _glxContext = nullptr; + _have_window = false; #elif AGS_PLATFORM_OS_ANDROID - device_screen_physical_width = android_screen_physical_width; - device_screen_physical_height = android_screen_physical_height; + device_screen_physical_width = android_screen_physical_width; + device_screen_physical_height = android_screen_physical_height; #elif AGS_PLATFORM_OS_IOS - device_screen_physical_width = ios_screen_physical_width; - device_screen_physical_height = ios_screen_physical_height; + device_screen_physical_width = ios_screen_physical_width; + device_screen_physical_height = ios_screen_physical_height; #endif - _firstTimeInit = false; - _backbuffer = 0; - _fbo = 0; - _legacyPixelShader = false; - _can_render_to_texture = false; - _do_render_to_texture = false; - _super_sampling = 1; - SetupDefaultVertices(); + _firstTimeInit = false; + _backbuffer = 0; + _fbo = 0; + _legacyPixelShader = false; + _can_render_to_texture = false; + _do_render_to_texture = false; + _super_sampling = 1; + SetupDefaultVertices(); - // Shifts comply to GL_RGBA - _vmem_r_shift_32 = 0; - _vmem_g_shift_32 = 8; - _vmem_b_shift_32 = 16; - _vmem_a_shift_32 = 24; + // Shifts comply to GL_RGBA + _vmem_r_shift_32 = 0; + _vmem_g_shift_32 = 8; + _vmem_b_shift_32 = 16; + _vmem_a_shift_32 = 24; } -void OGLGraphicsDriver::SetupDefaultVertices() -{ - std::fill(_backbuffer_vertices, _backbuffer_vertices + sizeof(_backbuffer_vertices) / sizeof(GLfloat), 0.0f); - std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); +void OGLGraphicsDriver::SetupDefaultVertices() { + std::fill(_backbuffer_vertices, _backbuffer_vertices + sizeof(_backbuffer_vertices) / sizeof(GLfloat), 0.0f); + std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); - defaultVertices[0].position.x = 0.0f; - defaultVertices[0].position.y = 0.0f; - defaultVertices[0].tu=0.0; - defaultVertices[0].tv=0.0; + defaultVertices[0].position.x = 0.0f; + defaultVertices[0].position.y = 0.0f; + defaultVertices[0].tu = 0.0; + defaultVertices[0].tv = 0.0; - defaultVertices[1].position.x = 1.0f; - defaultVertices[1].position.y = 0.0f; - defaultVertices[1].tu=1.0; - defaultVertices[1].tv=0.0; + defaultVertices[1].position.x = 1.0f; + defaultVertices[1].position.y = 0.0f; + defaultVertices[1].tu = 1.0; + defaultVertices[1].tv = 0.0; - defaultVertices[2].position.x = 0.0f; - defaultVertices[2].position.y = -1.0f; - defaultVertices[2].tu=0.0; - defaultVertices[2].tv=1.0; + defaultVertices[2].position.x = 0.0f; + defaultVertices[2].position.y = -1.0f; + defaultVertices[2].tu = 0.0; + defaultVertices[2].tv = 1.0; - defaultVertices[3].position.x = 1.0f; - defaultVertices[3].position.y = -1.0f; - defaultVertices[3].tu=1.0; - defaultVertices[3].tv=1.0; + defaultVertices[3].position.x = 1.0f; + defaultVertices[3].position.y = -1.0f; + defaultVertices[3].tu = 1.0; + defaultVertices[3].tv = 1.0; } #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX -void OGLGraphicsDriver::CreateDesktopScreen(int width, int height, int depth) -{ - device_screen_physical_width = width; - device_screen_physical_height = height; +void OGLGraphicsDriver::CreateDesktopScreen(int width, int height, int depth) { + device_screen_physical_width = width; + device_screen_physical_height = height; } #elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS -void OGLGraphicsDriver::UpdateDeviceScreen() -{ +void OGLGraphicsDriver::UpdateDeviceScreen() { #if AGS_PLATFORM_OS_ANDROID - device_screen_physical_width = android_screen_physical_width; - device_screen_physical_height = android_screen_physical_height; + device_screen_physical_width = android_screen_physical_width; + device_screen_physical_height = android_screen_physical_height; #elif AGS_PLATFORM_OS_IOS - device_screen_physical_width = ios_screen_physical_width; - device_screen_physical_height = ios_screen_physical_height; + device_screen_physical_width = ios_screen_physical_width; + device_screen_physical_height = ios_screen_physical_height; #endif - Debug::Printf("OGL: notified of device screen updated to %d x %d, resizing viewport", device_screen_physical_width, device_screen_physical_height); - _mode.Width = device_screen_physical_width; - _mode.Height = device_screen_physical_height; - InitGlParams(_mode); - if (_initSurfaceUpdateCallback) - _initSurfaceUpdateCallback(); + Debug::Printf("OGL: notified of device screen updated to %d x %d, resizing viewport", device_screen_physical_width, device_screen_physical_height); + _mode.Width = device_screen_physical_width; + _mode.Height = device_screen_physical_height; + InitGlParams(_mode); + if (_initSurfaceUpdateCallback) + _initSurfaceUpdateCallback(); } #endif -void OGLGraphicsDriver::Vsync() -{ - // do nothing on OpenGL +void OGLGraphicsDriver::Vsync() { + // do nothing on OpenGL } -void OGLGraphicsDriver::RenderSpritesAtScreenResolution(bool enabled, int supersampling) -{ - if (_can_render_to_texture) - { - _do_render_to_texture = !enabled; - _super_sampling = supersampling; - TestSupersampling(); - } +void OGLGraphicsDriver::RenderSpritesAtScreenResolution(bool enabled, int supersampling) { + if (_can_render_to_texture) { + _do_render_to_texture = !enabled; + _super_sampling = supersampling; + TestSupersampling(); + } - if (_do_render_to_texture) - glDisable(GL_SCISSOR_TEST); + if (_do_render_to_texture) + glDisable(GL_SCISSOR_TEST); } -bool OGLGraphicsDriver::IsModeSupported(const DisplayMode &mode) -{ - if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) - { - set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); - return false; - } - return true; +bool OGLGraphicsDriver::IsModeSupported(const DisplayMode &mode) { + if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) { + set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); + return false; + } + return true; } -bool OGLGraphicsDriver::SupportsGammaControl() -{ - return false; +bool OGLGraphicsDriver::SupportsGammaControl() { + return false; } -void OGLGraphicsDriver::SetGamma(int newGamma) -{ +void OGLGraphicsDriver::SetGamma(int newGamma) { } -void OGLGraphicsDriver::SetGraphicsFilter(POGLFilter filter) -{ - _filter = filter; - OnSetFilter(); +void OGLGraphicsDriver::SetGraphicsFilter(POGLFilter filter) { + _filter = filter; + OnSetFilter(); } -void OGLGraphicsDriver::SetTintMethod(TintMethod method) -{ - _legacyPixelShader = (method == TintReColourise); +void OGLGraphicsDriver::SetTintMethod(TintMethod method) { + _legacyPixelShader = (method == TintReColourise); } -void OGLGraphicsDriver::FirstTimeInit() -{ - String ogl_v_str; +void OGLGraphicsDriver::FirstTimeInit() { + String ogl_v_str; #ifdef GLAPI - ogl_v_str.Format("%d.%d", GLVersion.major, GLVersion.minor); + ogl_v_str.Format("%d.%d", GLVersion.major, GLVersion.minor); #else - ogl_v_str = (const char*)glGetString(GL_VERSION); + ogl_v_str = (const char *)glGetString(GL_VERSION); #endif - Debug::Printf(kDbgMsg_Info, "Running OpenGL: %s", ogl_v_str.GetCStr()); + Debug::Printf(kDbgMsg_Info, "Running OpenGL: %s", ogl_v_str.GetCStr()); + + // Initialize default sprite batch, it will be used when no other batch was activated + OGLGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); - // Initialize default sprite batch, it will be used when no other batch was activated - OGLGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); - - TestRenderToTexture(); - CreateShaders(); - _firstTimeInit = true; + TestRenderToTexture(); + CreateShaders(); + _firstTimeInit = true; } #if AGS_PLATFORM_OS_LINUX -Atom get_x_atom (const char *atom_name) -{ - Atom atom = XInternAtom(_xwin.display, atom_name, False); - if (atom == None) - { - Debug::Printf(kDbgMsg_Error, "ERROR: X11 atom \"%s\" not found.\n", atom_name); - } - return atom; +Atom get_x_atom(const char *atom_name) { + Atom atom = XInternAtom(_xwin.display, atom_name, False); + if (atom == None) { + Debug::Printf(kDbgMsg_Error, "ERROR: X11 atom \"%s\" not found.\n", atom_name); + } + return atom; } #endif -bool OGLGraphicsDriver::InitGlScreen(const DisplayMode &mode) -{ +bool OGLGraphicsDriver::InitGlScreen(const DisplayMode &mode) { #if AGS_PLATFORM_OS_ANDROID - android_create_screen(mode.Width, mode.Height, mode.ColorDepth); + android_create_screen(mode.Width, mode.Height, mode.ColorDepth); #elif AGS_PLATFORM_OS_IOS - ios_create_screen(); - ios_select_buffer(); + ios_create_screen(); + ios_select_buffer(); #elif AGS_PLATFORM_OS_WINDOWS - if (mode.Windowed) - { - platform->AdjustWindowStyleForWindowed(); - } - else - { - if (platform->EnterFullscreenMode(mode)) - platform->AdjustWindowStyleForFullscreen(); - } - - // NOTE: adjust_window may leave task bar visible, so we do not use it for fullscreen mode - if (mode.Windowed && adjust_window(mode.Width, mode.Height) != 0) - { - set_allegro_error("Window size not supported"); - return false; - } - - _hWnd = win_get_window(); - if (!(_hDC = GetDC(_hWnd))) - return false; - - // First check if we need to recreate GL context, this will only be - // required if different color depth is requested. - if (_hRC) - { - GLuint pixel_fmt = GetPixelFormat(_hDC); - PIXELFORMATDESCRIPTOR pfd; - DescribePixelFormat(_hDC, pixel_fmt, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - if (pfd.cColorBits != mode.ColorDepth) - { - DeleteGlContext(); - } - } - - if (!_hRC) - { - if (!CreateGlContext(mode)) - return false; - } - - if (!gladLoadWGL(_hDC)) { - Debug::Printf(kDbgMsg_Error, "Failed to load WGL."); - return false; - } - - if (!gladLoadGL()) { - Debug::Printf(kDbgMsg_Error, "Failed to load GL."); - return false; - } - - CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); - win_grab_input(); + if (mode.Windowed) { + platform->AdjustWindowStyleForWindowed(); + } else { + if (platform->EnterFullscreenMode(mode)) + platform->AdjustWindowStyleForFullscreen(); + } + + // NOTE: adjust_window may leave task bar visible, so we do not use it for fullscreen mode + if (mode.Windowed && adjust_window(mode.Width, mode.Height) != 0) { + set_allegro_error("Window size not supported"); + return false; + } + + _hWnd = win_get_window(); + if (!(_hDC = GetDC(_hWnd))) + return false; + + // First check if we need to recreate GL context, this will only be + // required if different color depth is requested. + if (_hRC) { + GLuint pixel_fmt = GetPixelFormat(_hDC); + PIXELFORMATDESCRIPTOR pfd; + DescribePixelFormat(_hDC, pixel_fmt, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + if (pfd.cColorBits != mode.ColorDepth) { + DeleteGlContext(); + } + } + + if (!_hRC) { + if (!CreateGlContext(mode)) + return false; + } + + if (!gladLoadWGL(_hDC)) { + Debug::Printf(kDbgMsg_Error, "Failed to load WGL."); + return false; + } + + if (!gladLoadGL()) { + Debug::Printf(kDbgMsg_Error, "Failed to load GL."); + return false; + } + + CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); + win_grab_input(); #elif AGS_PLATFORM_OS_LINUX - if (!_have_window) - { - // Use Allegro to create our window. We don't care what size Allegro uses - // here, we will set that ourselves below by manipulating members of - // Allegro's_xwin structure. We need to use the Allegro routine here (rather - // than create our own X window) to remain compatible with Allegro's mouse & - // keyboard handling. - // - // Note that although _xwin contains a special "fullscreen" Window member - // (_xwin.fs_window), we do not use it for going fullscreen. Instead we ask - // the window manager to take the "managed" Window (_xwin.wm_window) - // fullscreen for us. All drawing goes to the "real" Window (_xwin.window). - if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 0, 0, 0, 0) != 0) - return false; - _have_window = true; - } - - if (!gladLoadGLX(_xwin.display, DefaultScreen(_xwin.display))) { - Debug::Printf(kDbgMsg_Error, "Failed to load GLX."); - return false; - } - - if (!_glxContext && !CreateGlContext(mode)) - return false; - - if(!gladLoadGL()) { - Debug::Printf(kDbgMsg_Error, "Failed to load GL."); - return false; - } - - { - // Set the size of our "managed" window. - XSizeHints *hints = XAllocSizeHints(); - - if (hints) - { - if (mode.Windowed) - { - // Set a fixed-size window. This is copied from Allegro 4's - // _xwin_private_create_screen(). - hints->flags = PMinSize | PMaxSize | PBaseSize; - hints->min_width = hints->max_width = hints->base_width = mode.Width; - hints->min_height = hints->max_height = hints->base_height = mode.Height; - } - else - { - // Clear any previously set demand for a fixed-size window, otherwise - // the window manager will ignore our request to go full-screen. - hints->flags = 0; - } - - XSetWMNormalHints(_xwin.display, _xwin.wm_window, hints); - } - - XFree(hints); - } - - // Set the window we are actually drawing into to the desired size. - XResizeWindow(_xwin.display, _xwin.window, mode.Width, mode.Height); - - // Make Allegro aware of the new window size, otherwise the mouse cursor - // movement may be erratic. - _xwin.window_width = mode.Width; - _xwin.window_height = mode.Height; - - { - // Ask the window manager to add (or remove) the "fullscreen" property on - // our top-level window. - const Atom wm_state = get_x_atom("_NET_WM_STATE"); - const Atom fullscreen = get_x_atom("_NET_WM_STATE_FULLSCREEN"); - const long remove_property = 0; - const long add_property = 1; - - XEvent xev; - memset(&xev, 0, sizeof(xev)); - xev.type = ClientMessage; - xev.xclient.window = _xwin.wm_window; - xev.xclient.message_type = wm_state; - xev.xclient.format = 32; - xev.xclient.data.l[0] = mode.Windowed ? remove_property : add_property; - xev.xclient.data.l[1] = fullscreen; - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 1; // Message source is a regular application. - Status status = XSendEvent(_xwin.display, DefaultRootWindow(_xwin.display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); - if (status == 0) - { - Debug::Printf(kDbgMsg_Error, "ERROR: Failed to encode window state message.\n"); - } - } - - CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); + if (!_have_window) { + // Use Allegro to create our window. We don't care what size Allegro uses + // here, we will set that ourselves below by manipulating members of + // Allegro's_xwin structure. We need to use the Allegro routine here (rather + // than create our own X window) to remain compatible with Allegro's mouse & + // keyboard handling. + // + // Note that although _xwin contains a special "fullscreen" Window member + // (_xwin.fs_window), we do not use it for going fullscreen. Instead we ask + // the window manager to take the "managed" Window (_xwin.wm_window) + // fullscreen for us. All drawing goes to the "real" Window (_xwin.window). + if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 0, 0, 0, 0) != 0) + return false; + _have_window = true; + } + + if (!gladLoadGLX(_xwin.display, DefaultScreen(_xwin.display))) { + Debug::Printf(kDbgMsg_Error, "Failed to load GLX."); + return false; + } + + if (!_glxContext && !CreateGlContext(mode)) + return false; + + if (!gladLoadGL()) { + Debug::Printf(kDbgMsg_Error, "Failed to load GL."); + return false; + } + + { + // Set the size of our "managed" window. + XSizeHints *hints = XAllocSizeHints(); + + if (hints) { + if (mode.Windowed) { + // Set a fixed-size window. This is copied from Allegro 4's + // _xwin_private_create_screen(). + hints->flags = PMinSize | PMaxSize | PBaseSize; + hints->min_width = hints->max_width = hints->base_width = mode.Width; + hints->min_height = hints->max_height = hints->base_height = mode.Height; + } else { + // Clear any previously set demand for a fixed-size window, otherwise + // the window manager will ignore our request to go full-screen. + hints->flags = 0; + } + + XSetWMNormalHints(_xwin.display, _xwin.wm_window, hints); + } + + XFree(hints); + } + + // Set the window we are actually drawing into to the desired size. + XResizeWindow(_xwin.display, _xwin.window, mode.Width, mode.Height); + + // Make Allegro aware of the new window size, otherwise the mouse cursor + // movement may be erratic. + _xwin.window_width = mode.Width; + _xwin.window_height = mode.Height; + + { + // Ask the window manager to add (or remove) the "fullscreen" property on + // our top-level window. + const Atom wm_state = get_x_atom("_NET_WM_STATE"); + const Atom fullscreen = get_x_atom("_NET_WM_STATE_FULLSCREEN"); + const long remove_property = 0; + const long add_property = 1; + + XEvent xev; + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.xclient.window = _xwin.wm_window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = mode.Windowed ? remove_property : add_property; + xev.xclient.data.l[1] = fullscreen; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 1; // Message source is a regular application. + Status status = XSendEvent(_xwin.display, DefaultRootWindow(_xwin.display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + if (status == 0) { + Debug::Printf(kDbgMsg_Error, "ERROR: Failed to encode window state message.\n"); + } + } + + CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); #endif - gfx_driver = &gfx_opengl; - return true; + gfx_driver = &gfx_opengl; + return true; } -void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) -{ - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glShadeModel(GL_FLAT); +void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glShadeModel(GL_FLAT); - glEnable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, device_screen_physical_width, device_screen_physical_height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, device_screen_physical_width, 0, device_screen_physical_height, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glViewport(0, 0, device_screen_physical_width, device_screen_physical_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, device_screen_physical_width, 0, device_screen_physical_height, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); - auto interval = mode.Vsync ? 1 : 0; - bool vsyncEnabled = false; + auto interval = mode.Vsync ? 1 : 0; + bool vsyncEnabled = false; #if AGS_PLATFORM_OS_WINDOWS - if (GLAD_WGL_EXT_swap_control) { - vsyncEnabled = wglSwapIntervalEXT(interval) != FALSE; - } + if (GLAD_WGL_EXT_swap_control) { + vsyncEnabled = wglSwapIntervalEXT(interval) != FALSE; + } #endif #if AGS_PLATFORM_OS_LINUX - if (GLAD_GLX_EXT_swap_control) { - glXSwapIntervalEXT(_xwin.display, _xwin.window, interval); - // glx requires hooking into XSetErrorHandler to test for BadWindow or BadValue - vsyncEnabled = true; - } else if (GLAD_GLX_MESA_swap_control) { - vsyncEnabled = glXSwapIntervalMESA(interval) == 0; - } else if (GLAD_GLX_SGI_swap_control) { - vsyncEnabled = glXSwapIntervalSGI(interval) == 0; - } + if (GLAD_GLX_EXT_swap_control) { + glXSwapIntervalEXT(_xwin.display, _xwin.window, interval); + // glx requires hooking into XSetErrorHandler to test for BadWindow or BadValue + vsyncEnabled = true; + } else if (GLAD_GLX_MESA_swap_control) { + vsyncEnabled = glXSwapIntervalMESA(interval) == 0; + } else if (GLAD_GLX_SGI_swap_control) { + vsyncEnabled = glXSwapIntervalSGI(interval) == 0; + } #endif - // TODO: find out how to implement SwapInterval on other platforms, and how to check if it's supported + // TODO: find out how to implement SwapInterval on other platforms, and how to check if it's supported - if (mode.Vsync && !vsyncEnabled) { - Debug::Printf(kDbgMsg_Warn, "WARNING: Vertical sync could not be enabled. Setting will be kept at driver default."); - } + if (mode.Vsync && !vsyncEnabled) { + Debug::Printf(kDbgMsg_Warn, "WARNING: Vertical sync could not be enabled. Setting will be kept at driver default."); + } #if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - // Setup library mouse to have 1:1 coordinate transformation. - // NOTE: cannot move this call to general mouse handling mode. Unfortunately, much of the setup and rendering - // is duplicated in the Android/iOS ports' Allegro library patches, and is run when the Software renderer - // is selected in AGS. This ugly situation causes trouble... - float device_scale = 1.0f; - - #if AGS_PLATFORM_OS_IOS - device_scale = get_device_scale(); - #endif - - device_mouse_setup(0, device_screen_physical_width - 1, 0, device_screen_physical_height - 1, device_scale, device_scale); + // Setup library mouse to have 1:1 coordinate transformation. + // NOTE: cannot move this call to general mouse handling mode. Unfortunately, much of the setup and rendering + // is duplicated in the Android/iOS ports' Allegro library patches, and is run when the Software renderer + // is selected in AGS. This ugly situation causes trouble... + float device_scale = 1.0f; + +#if AGS_PLATFORM_OS_IOS + device_scale = get_device_scale(); +#endif + + device_mouse_setup(0, device_screen_physical_width - 1, 0, device_screen_physical_height - 1, device_scale, device_scale); #endif } -bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) -{ +bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) { #if AGS_PLATFORM_OS_WINDOWS - PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, - (BYTE)mode.ColorDepth, - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 0, - 0, - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - _oldPixelFormat = GetPixelFormat(_hDC); - DescribePixelFormat(_hDC, _oldPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &_oldPixelFormatDesc); - - GLuint pixel_fmt; - if (!(pixel_fmt = ChoosePixelFormat(_hDC, &pfd))) - return false; - - if (!SetPixelFormat(_hDC, pixel_fmt, &pfd)) - return false; - - if (!(_hRC = wglCreateContext(_hDC))) - return false; - - if(!wglMakeCurrent(_hDC, _hRC)) - return false; + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + (BYTE)mode.ColorDepth, + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 0, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + _oldPixelFormat = GetPixelFormat(_hDC); + DescribePixelFormat(_hDC, _oldPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &_oldPixelFormatDesc); + + GLuint pixel_fmt; + if (!(pixel_fmt = ChoosePixelFormat(_hDC, &pfd))) + return false; + + if (!SetPixelFormat(_hDC, pixel_fmt, &pfd)) + return false; + + if (!(_hRC = wglCreateContext(_hDC))) + return false; + + if (!wglMakeCurrent(_hDC, _hRC)) + return false; #endif // AGS_PLATFORM_OS_WINDOWS #if AGS_PLATFORM_OS_LINUX - int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; - XVisualInfo *vi = glXChooseVisual(_xwin.display, DefaultScreen(_xwin.display), attrib); - if (!vi) - { - Debug::Printf(kDbgMsg_Error, "ERROR: glXChooseVisual() failed.\n"); - return false; - } - - if (!(_glxContext = glXCreateContext(_xwin.display, vi, None, True))) - { - Debug::Printf(kDbgMsg_Error, "ERROR: glXCreateContext() failed.\n"); - return false; - } - - if (!glXMakeCurrent(_xwin.display, _xwin.window, _glxContext)) - { - Debug::Printf(kDbgMsg_Error, "ERROR: glXMakeCurrent() failed.\n"); - return false; - } + int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; + XVisualInfo *vi = glXChooseVisual(_xwin.display, DefaultScreen(_xwin.display), attrib); + if (!vi) { + Debug::Printf(kDbgMsg_Error, "ERROR: glXChooseVisual() failed.\n"); + return false; + } + + if (!(_glxContext = glXCreateContext(_xwin.display, vi, None, True))) { + Debug::Printf(kDbgMsg_Error, "ERROR: glXCreateContext() failed.\n"); + return false; + } + + if (!glXMakeCurrent(_xwin.display, _xwin.window, _glxContext)) { + Debug::Printf(kDbgMsg_Error, "ERROR: glXMakeCurrent() failed.\n"); + return false; + } #endif - return true; + return true; } -void OGLGraphicsDriver::DeleteGlContext() -{ +void OGLGraphicsDriver::DeleteGlContext() { #if AGS_PLATFORM_OS_WINDOWS - if (_hRC) - { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(_hRC); - _hRC = NULL; - } - - if (_oldPixelFormat > 0) - SetPixelFormat(_hDC, _oldPixelFormat, &_oldPixelFormatDesc); + if (_hRC) { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(_hRC); + _hRC = NULL; + } + + if (_oldPixelFormat > 0) + SetPixelFormat(_hDC, _oldPixelFormat, &_oldPixelFormatDesc); #elif AGS_PLATFORM_OS_LINUX - if (_glxContext) - { - glXMakeCurrent(_xwin.display, None, nullptr); - glXDestroyContext(_xwin.display, _glxContext); - _glxContext = nullptr; - } + if (_glxContext) { + glXMakeCurrent(_xwin.display, None, nullptr); + glXDestroyContext(_xwin.display, _glxContext); + _glxContext = nullptr; + } #endif } -inline bool CanDoFrameBuffer() -{ +inline bool CanDoFrameBuffer() { #ifdef GLAPI - return GLAD_GL_EXT_framebuffer_object != 0; + return GLAD_GL_EXT_framebuffer_object != 0; #else #if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - const char* fbo_extension_string = "GL_OES_framebuffer_object"; + const char *fbo_extension_string = "GL_OES_framebuffer_object"; #else - const char* fbo_extension_string = "GL_EXT_framebuffer_object"; + const char *fbo_extension_string = "GL_EXT_framebuffer_object"; #endif - const char* extensions = (const char*)glGetString(GL_EXTENSIONS); - return extensions && strstr(extensions, fbo_extension_string) != NULL; + const char *extensions = (const char *)glGetString(GL_EXTENSIONS); + return extensions && strstr(extensions, fbo_extension_string) != NULL; #endif } -void OGLGraphicsDriver::TestRenderToTexture() -{ - if (CanDoFrameBuffer()) { - _can_render_to_texture = true; - TestSupersampling(); - } else { - _can_render_to_texture = false; - Debug::Printf(kDbgMsg_Warn, "WARNING: OpenGL extension 'GL_EXT_framebuffer_object' not supported, rendering to texture mode will be disabled."); - } - - if (!_can_render_to_texture) - _do_render_to_texture = false; -} - -void OGLGraphicsDriver::TestSupersampling() -{ - if (!_can_render_to_texture) - return; - // Disable super-sampling if it would cause a too large texture size - if (_super_sampling > 1) - { - int max = 1024; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); - if ((max < _srcRect.GetWidth() * _super_sampling) || (max < _srcRect.GetHeight() * _super_sampling)) - _super_sampling = 1; - } -} - -void OGLGraphicsDriver::CreateShaders() -{ - if (!GLAD_GL_VERSION_2_0) { - Debug::Printf(kDbgMsg_Error, "ERROR: Shaders require a minimum of OpenGL 2.0 support."); - return; - } - CreateTintShader(); - CreateLightShader(); -} - -void OGLGraphicsDriver::CreateTintShader() -{ - const char *fragment_shader_src = - // NOTE: this shader emulates "historical" AGS software tinting; it is not - // necessarily "proper" tinting in modern terms. - // The RGB-HSV-RGB conversion found in the Internet (copyright unknown); - // Color processing is replicated from Direct3D shader by Chris Jones - // (Engine/resource/tintshaderLegacy.fx). - // Uniforms: - // textID - texture index (usually 0), - // tintHSV - tint color in HSV, - // tintAmnTrsLum - tint parameters: amount, translucence (alpha), luminance. - "\ +void OGLGraphicsDriver::TestRenderToTexture() { + if (CanDoFrameBuffer()) { + _can_render_to_texture = true; + TestSupersampling(); + } else { + _can_render_to_texture = false; + Debug::Printf(kDbgMsg_Warn, "WARNING: OpenGL extension 'GL_EXT_framebuffer_object' not supported, rendering to texture mode will be disabled."); + } + + if (!_can_render_to_texture) + _do_render_to_texture = false; +} + +void OGLGraphicsDriver::TestSupersampling() { + if (!_can_render_to_texture) + return; + // Disable super-sampling if it would cause a too large texture size + if (_super_sampling > 1) { + int max = 1024; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); + if ((max < _srcRect.GetWidth() * _super_sampling) || (max < _srcRect.GetHeight() * _super_sampling)) + _super_sampling = 1; + } +} + +void OGLGraphicsDriver::CreateShaders() { + if (!GLAD_GL_VERSION_2_0) { + Debug::Printf(kDbgMsg_Error, "ERROR: Shaders require a minimum of OpenGL 2.0 support."); + return; + } + CreateTintShader(); + CreateLightShader(); +} + +void OGLGraphicsDriver::CreateTintShader() { + const char *fragment_shader_src = + // NOTE: this shader emulates "historical" AGS software tinting; it is not + // necessarily "proper" tinting in modern terms. + // The RGB-HSV-RGB conversion found in the Internet (copyright unknown); + // Color processing is replicated from Direct3D shader by Chris Jones + // (Engine/resource/tintshaderLegacy.fx). + // Uniforms: + // textID - texture index (usually 0), + // tintHSV - tint color in HSV, + // tintAmnTrsLum - tint parameters: amount, translucence (alpha), luminance. + "\ #version 120\n\ uniform sampler2D textID;\n\ uniform vec3 tintHSV;\n\ @@ -785,21 +733,20 @@ void OGLGraphicsDriver::CreateTintShader() gl_FragColor = vec4(new_col, src_col.w * tintAmnTrsLum[1]);\n\ }\n\ "; - CreateShaderProgram(_tintShader, "Tinting", fragment_shader_src, "textID", "tintHSV", "tintAmnTrsLum"); -} - -void OGLGraphicsDriver::CreateLightShader() -{ - const char *fragment_shader_src = - // NOTE: due to how the lighting works in AGS, this is combined MODULATE / ADD shader. - // if the light is < 0, then MODULATE operation is used, otherwise ADD is used. - // NOTE: it's been said that using branching in shaders produces inefficient code. - // If that will ever become a real problem, we can easily split this shader in two. - // Uniforms: - // textID - texture index (usually 0), - // light - light level, - // alpha - color alpha value. - "\ + CreateShaderProgram(_tintShader, "Tinting", fragment_shader_src, "textID", "tintHSV", "tintAmnTrsLum"); +} + +void OGLGraphicsDriver::CreateLightShader() { + const char *fragment_shader_src = + // NOTE: due to how the lighting works in AGS, this is combined MODULATE / ADD shader. + // if the light is < 0, then MODULATE operation is used, otherwise ADD is used. + // NOTE: it's been said that using branching in shaders produces inefficient code. + // If that will ever become a real problem, we can easily split this shader in two. + // Uniforms: + // textID - texture index (usually 0), + // light - light level, + // alpha - color alpha value. + "\ #version 120\n\ uniform sampler2D textID;\n\ uniform float light;\n\ @@ -814,1256 +761,1111 @@ void OGLGraphicsDriver::CreateLightShader() gl_FragColor = vec4(src_col.xyz * abs(light), src_col.w * alpha);\n\ }\n\ "; - CreateShaderProgram(_lightShader, "Lighting", fragment_shader_src, "textID", "light", "alpha"); + CreateShaderProgram(_lightShader, "Lighting", fragment_shader_src, "textID", "light", "alpha"); } void OGLGraphicsDriver::CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, - const char *sampler_var, const char *color_var, const char *aux_var) -{ - GLint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr); - glCompileShader(fragment_shader); - GLint result; - glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &result); - if (result == GL_FALSE) - { - OutputShaderError(fragment_shader, String::FromFormat("%s program's fragment shader", name), true); - glDeleteShader(fragment_shader); - return; - } - - GLuint program = glCreateProgram(); - glAttachShader(program, fragment_shader); - glLinkProgram(program); - glGetProgramiv(program, GL_LINK_STATUS, &result); - if(result == GL_FALSE) - { - OutputShaderError(program, String::FromFormat("%s program", name), false); - glDeleteProgram(program); - glDeleteShader(fragment_shader); - return; - } - glDetachShader(program, fragment_shader); - glDeleteShader(fragment_shader); - - prg.Program = program; - prg.SamplerVar = glGetUniformLocation(program, sampler_var); - prg.ColorVar = glGetUniformLocation(program, color_var); - prg.AuxVar = glGetUniformLocation(program, aux_var); - Debug::Printf("OGL: %s shader program created successfully", name); -} - -void OGLGraphicsDriver::DeleteShaderProgram(ShaderProgram &prg) -{ - if (prg.Program) - glDeleteProgram(prg.Program); - prg.Program = 0; -} - -void OGLGraphicsDriver::OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader) -{ - GLint log_len; - if (is_shader) - glGetShaderiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); - else - glGetProgramiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); - std::vector errorLog(log_len); - if (log_len > 0) - { - if (is_shader) - glGetShaderInfoLog(obj_id, log_len, &log_len, &errorLog[0]); - else - glGetProgramInfoLog(obj_id, log_len, &log_len, &errorLog[0]); - } - - Debug::Printf(kDbgMsg_Error, "ERROR: OpenGL: %s %s:", obj_name.GetCStr(), is_shader ? "failed to compile" : "failed to link"); - if (errorLog.size() > 0) - { - Debug::Printf(kDbgMsg_Error, "----------------------------------------"); - Debug::Printf(kDbgMsg_Error, "%s", &errorLog[0]); - Debug::Printf(kDbgMsg_Error, "----------------------------------------"); - } - else - { - Debug::Printf(kDbgMsg_Error, "Shader info log was empty."); - } -} - -void OGLGraphicsDriver::SetupBackbufferTexture() -{ - // NOTE: ability to render to texture depends on OGL context, which is - // created in SetDisplayMode, therefore creation of textures require - // both native size set and context capabilities test passed. - if (!IsNativeSizeValid() || !_can_render_to_texture) - return; - - DeleteBackbufferTexture(); - - // _backbuffer_texture_coordinates defines translation from wanted texture size to actual supported texture size - _backRenderSize = _srcRect.GetSize() * _super_sampling; - _backTextureSize = _backRenderSize; - AdjustSizeToNearestSupportedByCard(&_backTextureSize.Width, &_backTextureSize.Height); - const float back_ratio_w = (float)_backRenderSize.Width / (float)_backTextureSize.Width; - const float back_ratio_h = (float)_backRenderSize.Height / (float)_backTextureSize.Height; - std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); - _backbuffer_texture_coordinates[2] = _backbuffer_texture_coordinates[6] = back_ratio_w; - _backbuffer_texture_coordinates[5] = _backbuffer_texture_coordinates[7] = back_ratio_h; - - glGenTextures(1, &_backbuffer); - glBindTexture(GL_TEXTURE_2D, _backbuffer); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backTextureSize.Width, _backTextureSize.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glBindTexture(GL_TEXTURE_2D, 0); - - glGenFramebuffersEXT(1, &_fbo); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _backbuffer, 0); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - - // Assign vertices of the backbuffer texture position in the scene - _backbuffer_vertices[0] = _backbuffer_vertices[4] = 0; - _backbuffer_vertices[2] = _backbuffer_vertices[6] = _srcRect.GetWidth(); - _backbuffer_vertices[5] = _backbuffer_vertices[7] = _srcRect.GetHeight(); - _backbuffer_vertices[1] = _backbuffer_vertices[3] = 0; -} - -void OGLGraphicsDriver::DeleteBackbufferTexture() -{ - if (_backbuffer) - glDeleteTextures(1, &_backbuffer); - if (_fbo) - glDeleteFramebuffersEXT(1, &_fbo); - _backbuffer = 0; - _fbo = 0; -} + const char *sampler_var, const char *color_var, const char *aux_var) { + GLint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr); + glCompileShader(fragment_shader); + GLint result; + glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) { + OutputShaderError(fragment_shader, String::FromFormat("%s program's fragment shader", name), true); + glDeleteShader(fragment_shader); + return; + } + + GLuint program = glCreateProgram(); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &result); + if (result == GL_FALSE) { + OutputShaderError(program, String::FromFormat("%s program", name), false); + glDeleteProgram(program); + glDeleteShader(fragment_shader); + return; + } + glDetachShader(program, fragment_shader); + glDeleteShader(fragment_shader); + + prg.Program = program; + prg.SamplerVar = glGetUniformLocation(program, sampler_var); + prg.ColorVar = glGetUniformLocation(program, color_var); + prg.AuxVar = glGetUniformLocation(program, aux_var); + Debug::Printf("OGL: %s shader program created successfully", name); +} + +void OGLGraphicsDriver::DeleteShaderProgram(ShaderProgram &prg) { + if (prg.Program) + glDeleteProgram(prg.Program); + prg.Program = 0; +} + +void OGLGraphicsDriver::OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader) { + GLint log_len; + if (is_shader) + glGetShaderiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); + else + glGetProgramiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); + std::vector errorLog(log_len); + if (log_len > 0) { + if (is_shader) + glGetShaderInfoLog(obj_id, log_len, &log_len, &errorLog[0]); + else + glGetProgramInfoLog(obj_id, log_len, &log_len, &errorLog[0]); + } + + Debug::Printf(kDbgMsg_Error, "ERROR: OpenGL: %s %s:", obj_name.GetCStr(), is_shader ? "failed to compile" : "failed to link"); + if (errorLog.size() > 0) { + Debug::Printf(kDbgMsg_Error, "----------------------------------------"); + Debug::Printf(kDbgMsg_Error, "%s", &errorLog[0]); + Debug::Printf(kDbgMsg_Error, "----------------------------------------"); + } else { + Debug::Printf(kDbgMsg_Error, "Shader info log was empty."); + } +} + +void OGLGraphicsDriver::SetupBackbufferTexture() { + // NOTE: ability to render to texture depends on OGL context, which is + // created in SetDisplayMode, therefore creation of textures require + // both native size set and context capabilities test passed. + if (!IsNativeSizeValid() || !_can_render_to_texture) + return; + + DeleteBackbufferTexture(); + + // _backbuffer_texture_coordinates defines translation from wanted texture size to actual supported texture size + _backRenderSize = _srcRect.GetSize() * _super_sampling; + _backTextureSize = _backRenderSize; + AdjustSizeToNearestSupportedByCard(&_backTextureSize.Width, &_backTextureSize.Height); + const float back_ratio_w = (float)_backRenderSize.Width / (float)_backTextureSize.Width; + const float back_ratio_h = (float)_backRenderSize.Height / (float)_backTextureSize.Height; + std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); + _backbuffer_texture_coordinates[2] = _backbuffer_texture_coordinates[6] = back_ratio_w; + _backbuffer_texture_coordinates[5] = _backbuffer_texture_coordinates[7] = back_ratio_h; + + glGenTextures(1, &_backbuffer); + glBindTexture(GL_TEXTURE_2D, _backbuffer); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backTextureSize.Width, _backTextureSize.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glBindTexture(GL_TEXTURE_2D, 0); + + glGenFramebuffersEXT(1, &_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _backbuffer, 0); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + // Assign vertices of the backbuffer texture position in the scene + _backbuffer_vertices[0] = _backbuffer_vertices[4] = 0; + _backbuffer_vertices[2] = _backbuffer_vertices[6] = _srcRect.GetWidth(); + _backbuffer_vertices[5] = _backbuffer_vertices[7] = _srcRect.GetHeight(); + _backbuffer_vertices[1] = _backbuffer_vertices[3] = 0; +} + +void OGLGraphicsDriver::DeleteBackbufferTexture() { + if (_backbuffer) + glDeleteTextures(1, &_backbuffer); + if (_fbo) + glDeleteFramebuffersEXT(1, &_fbo); + _backbuffer = 0; + _fbo = 0; +} + +void OGLGraphicsDriver::SetupViewport() { + if (!IsModeSet() || !IsRenderFrameValid()) + return; + + // Setup viewport rect and scissor + _viewportRect = ConvertTopDownRect(_dstRect, device_screen_physical_height); + glScissor(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); +} + +Rect OGLGraphicsDriver::ConvertTopDownRect(const Rect &rect, int surface_height) { + return RectWH(rect.Left, surface_height - 1 - rect.Bottom, rect.GetWidth(), rect.GetHeight()); +} + +bool OGLGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) { + ReleaseDisplayMode(); + + if (mode.ColorDepth < 15) { + set_allegro_error("OpenGL driver does not support 256-color display mode"); + return false; + } + + try { + if (!InitGlScreen(mode)) + return false; + if (!_firstTimeInit) + FirstTimeInit(); + InitGlParams(mode); + } catch (Ali3DException exception) { + if (exception._message != get_allegro_error()) + set_allegro_error(exception._message); + return false; + } + + OnInit(loopTimer); -void OGLGraphicsDriver::SetupViewport() -{ - if (!IsModeSet() || !IsRenderFrameValid()) - return; + // On certain platforms OpenGL renderer ignores requested screen sizes + // and uses values imposed by the operating system (device). + DisplayMode final_mode = mode; + final_mode.Width = device_screen_physical_width; + final_mode.Height = device_screen_physical_height; + OnModeSet(final_mode); - // Setup viewport rect and scissor - _viewportRect = ConvertTopDownRect(_dstRect, device_screen_physical_height); - glScissor(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); + // If we already have a native size set, then update virtual screen and setup backbuffer texture immediately + CreateVirtualScreen(); + SetupBackbufferTexture(); + // If we already have a render frame configured, then setup viewport and backbuffer mappings immediately + SetupViewport(); + return true; } -Rect OGLGraphicsDriver::ConvertTopDownRect(const Rect &rect, int surface_height) -{ - return RectWH(rect.Left, surface_height - 1 - rect.Bottom, rect.GetWidth(), rect.GetHeight()); +void OGLGraphicsDriver::CreateVirtualScreen() { + if (!IsModeSet() || !IsNativeSizeValid()) + return; + // create initial stage screen for plugin raw drawing + _stageVirtualScreen = CreateStageScreen(0, _srcRect.GetSize()); + // we must set Allegro's screen pointer to **something** + screen = (BITMAP *)_stageVirtualScreen->GetAllegroBitmap(); } -bool OGLGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) -{ - ReleaseDisplayMode(); - - if (mode.ColorDepth < 15) - { - set_allegro_error("OpenGL driver does not support 256-color display mode"); - return false; - } - - try - { - if (!InitGlScreen(mode)) - return false; - if (!_firstTimeInit) - FirstTimeInit(); - InitGlParams(mode); - } - catch (Ali3DException exception) - { - if (exception._message != get_allegro_error()) - set_allegro_error(exception._message); - return false; - } - - OnInit(loopTimer); - - // On certain platforms OpenGL renderer ignores requested screen sizes - // and uses values imposed by the operating system (device). - DisplayMode final_mode = mode; - final_mode.Width = device_screen_physical_width; - final_mode.Height = device_screen_physical_height; - OnModeSet(final_mode); - - // If we already have a native size set, then update virtual screen and setup backbuffer texture immediately - CreateVirtualScreen(); - SetupBackbufferTexture(); - // If we already have a render frame configured, then setup viewport and backbuffer mappings immediately - SetupViewport(); - return true; -} - -void OGLGraphicsDriver::CreateVirtualScreen() -{ - if (!IsModeSet() || !IsNativeSizeValid()) - return; - // create initial stage screen for plugin raw drawing - _stageVirtualScreen = CreateStageScreen(0, _srcRect.GetSize()); - // we must set Allegro's screen pointer to **something** - screen = (BITMAP*)_stageVirtualScreen->GetAllegroBitmap(); +bool OGLGraphicsDriver::SetNativeSize(const Size &src_size) { + OnSetNativeSize(src_size); + SetupBackbufferTexture(); + // If we already have a gfx mode set, then update virtual screen immediately + CreateVirtualScreen(); + TestSupersampling(); + return !_srcRect.IsEmpty(); } -bool OGLGraphicsDriver::SetNativeSize(const Size &src_size) -{ - OnSetNativeSize(src_size); - SetupBackbufferTexture(); - // If we already have a gfx mode set, then update virtual screen immediately - CreateVirtualScreen(); - TestSupersampling(); - return !_srcRect.IsEmpty(); +bool OGLGraphicsDriver::SetRenderFrame(const Rect &dst_rect) { + if (!IsNativeSizeValid()) + return false; + OnSetRenderFrame(dst_rect); + // Also make sure viewport and backbuffer mappings are updated using new native & destination rectangles + SetupViewport(); + return !_dstRect.IsEmpty(); } -bool OGLGraphicsDriver::SetRenderFrame(const Rect &dst_rect) -{ - if (!IsNativeSizeValid()) - return false; - OnSetRenderFrame(dst_rect); - // Also make sure viewport and backbuffer mappings are updated using new native & destination rectangles - SetupViewport(); - return !_dstRect.IsEmpty(); +int OGLGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const { + // TODO: check for device caps to know which depth is supported? + return 32; } -int OGLGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const -{ - // TODO: check for device caps to know which depth is supported? - return 32; -} - -IGfxModeList *OGLGraphicsDriver::GetSupportedModeList(int color_depth) -{ - std::vector modes; - platform->GetSystemDisplayModes(modes); - return new OGLDisplayModeList(modes); +IGfxModeList *OGLGraphicsDriver::GetSupportedModeList(int color_depth) { + std::vector modes; + platform->GetSystemDisplayModes(modes); + return new OGLDisplayModeList(modes); } -PGfxFilter OGLGraphicsDriver::GetGraphicsFilter() const -{ - return _filter; +PGfxFilter OGLGraphicsDriver::GetGraphicsFilter() const { + return _filter; } -void OGLGraphicsDriver::ReleaseDisplayMode() -{ - if (!IsModeSet()) - return; +void OGLGraphicsDriver::ReleaseDisplayMode() { + if (!IsModeSet()) + return; - OnModeReleased(); - ClearDrawLists(); - ClearDrawBackups(); - DeleteBackbufferTexture(); - DestroyFxPool(); - DestroyAllStageScreens(); + OnModeReleased(); + ClearDrawLists(); + ClearDrawBackups(); + DeleteBackbufferTexture(); + DestroyFxPool(); + DestroyAllStageScreens(); - gfx_driver = nullptr; + gfx_driver = nullptr; - platform->ExitFullscreenMode(); + platform->ExitFullscreenMode(); } -void OGLGraphicsDriver::UnInit() -{ - OnUnInit(); - ReleaseDisplayMode(); +void OGLGraphicsDriver::UnInit() { + OnUnInit(); + ReleaseDisplayMode(); - DeleteGlContext(); + DeleteGlContext(); #if AGS_PLATFORM_OS_WINDOWS - _hWnd = NULL; - _hDC = NULL; + _hWnd = NULL; + _hDC = NULL; #endif - DeleteShaderProgram(_tintShader); - DeleteShaderProgram(_lightShader); + DeleteShaderProgram(_tintShader); + DeleteShaderProgram(_lightShader); } -OGLGraphicsDriver::~OGLGraphicsDriver() -{ - OGLGraphicsDriver::UnInit(); +OGLGraphicsDriver::~OGLGraphicsDriver() { + OGLGraphicsDriver::UnInit(); } -void OGLGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) -{ - // NOTE: this function is practically useless at the moment, because OGL redraws whole game frame each time +void OGLGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) { + // NOTE: this function is practically useless at the moment, because OGL redraws whole game frame each time } -bool OGLGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) -{ - (void)at_native_res; // TODO: support this at some point - - // TODO: following implementation currently only reads GL pixels in 32-bit RGBA. - // this **should** work regardless of actual display mode because OpenGL is - // responsible to convert and fill pixel buffer correctly. - // If you like to support writing directly into 16-bit bitmap, please take - // care of ammending the pixel reading code below. - const int read_in_colordepth = 32; - Size need_size = _do_render_to_texture ? _backRenderSize : _dstRect.GetSize(); - if (destination->GetColorDepth() != read_in_colordepth || destination->GetSize() != need_size) - { - if (want_fmt) - *want_fmt = GraphicResolution(need_size.Width, need_size.Height, read_in_colordepth); - return false; - } - - Rect retr_rect; - if (_do_render_to_texture) - { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); - retr_rect = RectWH(0, 0, _backRenderSize.Width, _backRenderSize.Height); - } - else - { +bool OGLGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) { + (void)at_native_res; // TODO: support this at some point + + // TODO: following implementation currently only reads GL pixels in 32-bit RGBA. + // this **should** work regardless of actual display mode because OpenGL is + // responsible to convert and fill pixel buffer correctly. + // If you like to support writing directly into 16-bit bitmap, please take + // care of ammending the pixel reading code below. + const int read_in_colordepth = 32; + Size need_size = _do_render_to_texture ? _backRenderSize : _dstRect.GetSize(); + if (destination->GetColorDepth() != read_in_colordepth || destination->GetSize() != need_size) { + if (want_fmt) + *want_fmt = GraphicResolution(need_size.Width, need_size.Height, read_in_colordepth); + return false; + } + + Rect retr_rect; + if (_do_render_to_texture) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); + retr_rect = RectWH(0, 0, _backRenderSize.Width, _backRenderSize.Height); + } else { #if AGS_PLATFORM_OS_IOS - ios_select_buffer(); + ios_select_buffer(); #elif AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX - glReadBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); #endif - retr_rect = _dstRect; - } - - int bpp = read_in_colordepth / 8; - int bufferSize = retr_rect.GetWidth() * retr_rect.GetHeight() * bpp; - - unsigned char* buffer = new unsigned char[bufferSize]; - if (buffer) - { - glReadPixels(retr_rect.Left, retr_rect.Top, retr_rect.GetWidth(), retr_rect.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buffer); - - unsigned char* sourcePtr = buffer; - for (int y = destination->GetHeight() - 1; y >= 0; y--) - { - unsigned int * destPtr = reinterpret_cast(&destination->GetScanLineForWriting(y)[0]); - for (int dx = 0, sx = 0; dx < destination->GetWidth(); ++dx, sx = dx * bpp) - { - destPtr[dx] = makeacol32(sourcePtr[sx + 0], sourcePtr[sx + 1], sourcePtr[sx + 2], sourcePtr[sx + 3]); - } - sourcePtr += retr_rect.GetWidth() * bpp; - } - - if (_pollingCallback) - _pollingCallback(); - - delete [] buffer; - } - return true; -} - -void OGLGraphicsDriver::RenderToBackBuffer() -{ - throw Ali3DException("OGL driver does not have a back buffer"); -} - -void OGLGraphicsDriver::Render() -{ - Render(0, 0, kFlip_None); -} - -void OGLGraphicsDriver::Render(int /*xoff*/, int /*yoff*/, GlobalFlipType /*flip*/) -{ - _render(true); -} - -void OGLGraphicsDriver::_reDrawLastFrame() -{ - RestoreDrawLists(); -} - -void OGLGraphicsDriver::_renderSprite(const OGLDrawListEntry *drawListEntry, const GLMATRIX &matGlobal) -{ - OGLBitmap *bmpToDraw = drawListEntry->bitmap; - - if (bmpToDraw->_transparency >= 255) - return; - - const bool do_tint = bmpToDraw->_tintSaturation > 0 && _tintShader.Program > 0; - const bool do_light = bmpToDraw->_tintSaturation == 0 && bmpToDraw->_lightLevel > 0 && _lightShader.Program > 0; - if (do_tint) - { - // Use tinting shader - glUseProgram(_tintShader.Program); - float rgb[3]; - float sat_trs_lum[3]; // saturation / transparency / luminance - if (_legacyPixelShader) - { - rgb_to_hsv(bmpToDraw->_red, bmpToDraw->_green, bmpToDraw->_blue, &rgb[0], &rgb[1], &rgb[2]); - rgb[0] /= 360.0; // In HSV, Hue is 0-360 - } - else - { - rgb[0] = (float)bmpToDraw->_red / 255.0; - rgb[1] = (float)bmpToDraw->_green / 255.0; - rgb[2] = (float)bmpToDraw->_blue / 255.0; - } - - sat_trs_lum[0] = (float)bmpToDraw->_tintSaturation / 255.0; - - if (bmpToDraw->_transparency > 0) - sat_trs_lum[1] = (float)bmpToDraw->_transparency / 255.0; - else - sat_trs_lum[1] = 1.0f; - - if (bmpToDraw->_lightLevel > 0) - sat_trs_lum[2] = (float)bmpToDraw->_lightLevel / 255.0; - else - sat_trs_lum[2] = 1.0f; - - glUniform1i(_tintShader.SamplerVar, 0); - glUniform3f(_tintShader.ColorVar, rgb[0], rgb[1], rgb[2]); - glUniform3f(_tintShader.AuxVar, sat_trs_lum[0], sat_trs_lum[1], sat_trs_lum[2]); - } - else if (do_light) - { - // Use light shader - glUseProgram(_lightShader.Program); - float light_lev = 1.0f; - float alpha = 1.0f; - - // Light level parameter in DDB is weird, it is measured in units of - // 1/255 (although effectively 1/250, see draw.cpp), but contains two - // ranges: 1-255 is darker range and 256-511 is brighter range. - // (light level of 0 means "default color") - if ((bmpToDraw->_lightLevel > 0) && (bmpToDraw->_lightLevel < 256)) - { - // darkening the sprite... this stupid calculation is for - // consistency with the allegro software-mode code that does - // a trans blend with a (8,8,8) sprite - light_lev = -((bmpToDraw->_lightLevel * 192) / 256 + 64) / 255.f; // darker, uses MODULATE op - } - else if (bmpToDraw->_lightLevel > 256) - { - light_lev = ((bmpToDraw->_lightLevel - 256) / 2) / 255.f; // brighter, uses ADD op - } - - if (bmpToDraw->_transparency > 0) - alpha = bmpToDraw->_transparency / 255.f; - - glUniform1i(_lightShader.SamplerVar, 0); - glUniform1f(_lightShader.ColorVar, light_lev); - glUniform1f(_lightShader.AuxVar, alpha); - } - else - { - // Use default processing - if (bmpToDraw->_transparency == 0) - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - else - glColor4f(1.0f, 1.0f, 1.0f, bmpToDraw->_transparency / 255.0f); - } - - float width = bmpToDraw->GetWidthToRender(); - float height = bmpToDraw->GetHeightToRender(); - float xProportion = (float)width / (float)bmpToDraw->_width; - float yProportion = (float)height / (float)bmpToDraw->_height; - int drawAtX = drawListEntry->x; - int drawAtY = drawListEntry->y; - - for (int ti = 0; ti < bmpToDraw->_numTiles; ti++) - { - width = bmpToDraw->_tiles[ti].width * xProportion; - height = bmpToDraw->_tiles[ti].height * yProportion; - float xOffs; - float yOffs = bmpToDraw->_tiles[ti].y * yProportion; - if (bmpToDraw->_flipped) - xOffs = (bmpToDraw->_width - (bmpToDraw->_tiles[ti].x + bmpToDraw->_tiles[ti].width)) * xProportion; - else - xOffs = bmpToDraw->_tiles[ti].x * xProportion; - int thisX = drawAtX + xOffs; - int thisY = drawAtY + yOffs; - thisX = (-(_srcRect.GetWidth() / 2)) + thisX; - thisY = (_srcRect.GetHeight() / 2) - thisY; - - //Setup translation and scaling matrices - float widthToScale = (float)width; - float heightToScale = (float)height; - if (bmpToDraw->_flipped) - { - // The usual transform changes 0..1 into 0..width - // So first negate it (which changes 0..w into -w..0) - widthToScale = -widthToScale; - // and now shift it over to make it 0..w again - thisX += width; - } - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // - // IMPORTANT: in OpenGL order of transformation is REVERSE to the order of commands! - // - // Origin is at the middle of the surface - if (_do_render_to_texture) - glTranslatef(_backRenderSize.Width / 2.0f, _backRenderSize.Height / 2.0f, 0.0f); - else - glTranslatef(_srcRect.GetWidth() / 2.0f, _srcRect.GetHeight() / 2.0f, 0.0f); - - // Global batch transform - glMultMatrixf(matGlobal.m); - // Self sprite transform (first scale, then rotate and then translate, reversed) - glTranslatef((float)thisX, (float)thisY, 0.0f); - glRotatef(0.f, 0.f, 0.f, 1.f); - glScalef(widthToScale, heightToScale, 1.0f); - - glBindTexture(GL_TEXTURE_2D, bmpToDraw->_tiles[ti].texture); - - if ((_smoothScaling) && bmpToDraw->_useResampler && (bmpToDraw->_stretchToHeight > 0) && - ((bmpToDraw->_stretchToHeight != bmpToDraw->_height) || - (bmpToDraw->_stretchToWidth != bmpToDraw->_width))) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - else if (_do_render_to_texture) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - else - { - _filter->SetFilteringForStandardSprite(); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - if (bmpToDraw->_vertex != nullptr) - { - glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].tu)); - glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].position)); - } - else - { - glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].tu); - glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].position); - } - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - } - glUseProgram(0); -} - -void OGLGraphicsDriver::_render(bool clearDrawListAfterwards) -{ + retr_rect = _dstRect; + } + + int bpp = read_in_colordepth / 8; + int bufferSize = retr_rect.GetWidth() * retr_rect.GetHeight() * bpp; + + unsigned char *buffer = new unsigned char[bufferSize]; + if (buffer) { + glReadPixels(retr_rect.Left, retr_rect.Top, retr_rect.GetWidth(), retr_rect.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + unsigned char *sourcePtr = buffer; + for (int y = destination->GetHeight() - 1; y >= 0; y--) { + unsigned int *destPtr = reinterpret_cast(&destination->GetScanLineForWriting(y)[0]); + for (int dx = 0, sx = 0; dx < destination->GetWidth(); ++dx, sx = dx * bpp) { + destPtr[dx] = makeacol32(sourcePtr[sx + 0], sourcePtr[sx + 1], sourcePtr[sx + 2], sourcePtr[sx + 3]); + } + sourcePtr += retr_rect.GetWidth() * bpp; + } + + if (_pollingCallback) + _pollingCallback(); + + delete [] buffer; + } + return true; +} + +void OGLGraphicsDriver::RenderToBackBuffer() { + throw Ali3DException("OGL driver does not have a back buffer"); +} + +void OGLGraphicsDriver::Render() { + Render(0, 0, kFlip_None); +} + +void OGLGraphicsDriver::Render(int /*xoff*/, int /*yoff*/, GlobalFlipType /*flip*/) { + _render(true); +} + +void OGLGraphicsDriver::_reDrawLastFrame() { + RestoreDrawLists(); +} + +void OGLGraphicsDriver::_renderSprite(const OGLDrawListEntry *drawListEntry, const GLMATRIX &matGlobal) { + OGLBitmap *bmpToDraw = drawListEntry->bitmap; + + if (bmpToDraw->_transparency >= 255) + return; + + const bool do_tint = bmpToDraw->_tintSaturation > 0 && _tintShader.Program > 0; + const bool do_light = bmpToDraw->_tintSaturation == 0 && bmpToDraw->_lightLevel > 0 && _lightShader.Program > 0; + if (do_tint) { + // Use tinting shader + glUseProgram(_tintShader.Program); + float rgb[3]; + float sat_trs_lum[3]; // saturation / transparency / luminance + if (_legacyPixelShader) { + rgb_to_hsv(bmpToDraw->_red, bmpToDraw->_green, bmpToDraw->_blue, &rgb[0], &rgb[1], &rgb[2]); + rgb[0] /= 360.0; // In HSV, Hue is 0-360 + } else { + rgb[0] = (float)bmpToDraw->_red / 255.0; + rgb[1] = (float)bmpToDraw->_green / 255.0; + rgb[2] = (float)bmpToDraw->_blue / 255.0; + } + + sat_trs_lum[0] = (float)bmpToDraw->_tintSaturation / 255.0; + + if (bmpToDraw->_transparency > 0) + sat_trs_lum[1] = (float)bmpToDraw->_transparency / 255.0; + else + sat_trs_lum[1] = 1.0f; + + if (bmpToDraw->_lightLevel > 0) + sat_trs_lum[2] = (float)bmpToDraw->_lightLevel / 255.0; + else + sat_trs_lum[2] = 1.0f; + + glUniform1i(_tintShader.SamplerVar, 0); + glUniform3f(_tintShader.ColorVar, rgb[0], rgb[1], rgb[2]); + glUniform3f(_tintShader.AuxVar, sat_trs_lum[0], sat_trs_lum[1], sat_trs_lum[2]); + } else if (do_light) { + // Use light shader + glUseProgram(_lightShader.Program); + float light_lev = 1.0f; + float alpha = 1.0f; + + // Light level parameter in DDB is weird, it is measured in units of + // 1/255 (although effectively 1/250, see draw.cpp), but contains two + // ranges: 1-255 is darker range and 256-511 is brighter range. + // (light level of 0 means "default color") + if ((bmpToDraw->_lightLevel > 0) && (bmpToDraw->_lightLevel < 256)) { + // darkening the sprite... this stupid calculation is for + // consistency with the allegro software-mode code that does + // a trans blend with a (8,8,8) sprite + light_lev = -((bmpToDraw->_lightLevel * 192) / 256 + 64) / 255.f; // darker, uses MODULATE op + } else if (bmpToDraw->_lightLevel > 256) { + light_lev = ((bmpToDraw->_lightLevel - 256) / 2) / 255.f; // brighter, uses ADD op + } + + if (bmpToDraw->_transparency > 0) + alpha = bmpToDraw->_transparency / 255.f; + + glUniform1i(_lightShader.SamplerVar, 0); + glUniform1f(_lightShader.ColorVar, light_lev); + glUniform1f(_lightShader.AuxVar, alpha); + } else { + // Use default processing + if (bmpToDraw->_transparency == 0) + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + else + glColor4f(1.0f, 1.0f, 1.0f, bmpToDraw->_transparency / 255.0f); + } + + float width = bmpToDraw->GetWidthToRender(); + float height = bmpToDraw->GetHeightToRender(); + float xProportion = (float)width / (float)bmpToDraw->_width; + float yProportion = (float)height / (float)bmpToDraw->_height; + int drawAtX = drawListEntry->x; + int drawAtY = drawListEntry->y; + + for (int ti = 0; ti < bmpToDraw->_numTiles; ti++) { + width = bmpToDraw->_tiles[ti].width * xProportion; + height = bmpToDraw->_tiles[ti].height * yProportion; + float xOffs; + float yOffs = bmpToDraw->_tiles[ti].y * yProportion; + if (bmpToDraw->_flipped) + xOffs = (bmpToDraw->_width - (bmpToDraw->_tiles[ti].x + bmpToDraw->_tiles[ti].width)) * xProportion; + else + xOffs = bmpToDraw->_tiles[ti].x * xProportion; + int thisX = drawAtX + xOffs; + int thisY = drawAtY + yOffs; + thisX = (-(_srcRect.GetWidth() / 2)) + thisX; + thisY = (_srcRect.GetHeight() / 2) - thisY; + + //Setup translation and scaling matrices + float widthToScale = (float)width; + float heightToScale = (float)height; + if (bmpToDraw->_flipped) { + // The usual transform changes 0..1 into 0..width + // So first negate it (which changes 0..w into -w..0) + widthToScale = -widthToScale; + // and now shift it over to make it 0..w again + thisX += width; + } + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // + // IMPORTANT: in OpenGL order of transformation is REVERSE to the order of commands! + // + // Origin is at the middle of the surface + if (_do_render_to_texture) + glTranslatef(_backRenderSize.Width / 2.0f, _backRenderSize.Height / 2.0f, 0.0f); + else + glTranslatef(_srcRect.GetWidth() / 2.0f, _srcRect.GetHeight() / 2.0f, 0.0f); + + // Global batch transform + glMultMatrixf(matGlobal.m); + // Self sprite transform (first scale, then rotate and then translate, reversed) + glTranslatef((float)thisX, (float)thisY, 0.0f); + glRotatef(0.f, 0.f, 0.f, 1.f); + glScalef(widthToScale, heightToScale, 1.0f); + + glBindTexture(GL_TEXTURE_2D, bmpToDraw->_tiles[ti].texture); + + if ((_smoothScaling) && bmpToDraw->_useResampler && (bmpToDraw->_stretchToHeight > 0) && + ((bmpToDraw->_stretchToHeight != bmpToDraw->_height) || + (bmpToDraw->_stretchToWidth != bmpToDraw->_width))) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else if (_do_render_to_texture) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } else { + _filter->SetFilteringForStandardSprite(); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + if (bmpToDraw->_vertex != nullptr) { + glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].tu)); + glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].position)); + } else { + glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].tu); + glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].position); + } + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + glUseProgram(0); +} + +void OGLGraphicsDriver::_render(bool clearDrawListAfterwards) { #if AGS_PLATFORM_OS_IOS - ios_select_buffer(); + ios_select_buffer(); #endif #if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - // TODO: - // For some reason, mobile ports initialize actual display size after a short delay. - // This is why we update display mode and related parameters (projection, viewport) - // at the first render pass. - // Ofcourse this is not a good thing, ideally the display size should be made - // known before graphic mode is initialized. This would require analysis and rewrite - // of the platform-specific part of the code (Java app for Android / XCode for iOS). - if (!device_screen_initialized) - { - UpdateDeviceScreen(); - device_screen_initialized = 1; - } + // TODO: + // For some reason, mobile ports initialize actual display size after a short delay. + // This is why we update display mode and related parameters (projection, viewport) + // at the first render pass. + // Ofcourse this is not a good thing, ideally the display size should be made + // known before graphic mode is initialized. This would require analysis and rewrite + // of the platform-specific part of the code (Java app for Android / XCode for iOS). + if (!device_screen_initialized) { + UpdateDeviceScreen(); + device_screen_initialized = 1; + } #endif - if (_do_render_to_texture) - { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); - - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, _backRenderSize.Width, _backRenderSize.Height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, _backRenderSize.Width, 0, _backRenderSize.Height, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - } - else - { - glDisable(GL_SCISSOR_TEST); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); - - glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - } - - RenderSpriteBatches(); - - if (_do_render_to_texture) - { - // Texture is ready, now create rectangle in the world space and draw texture upon it + if (_do_render_to_texture) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); + + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, _backRenderSize.Width, _backRenderSize.Height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _backRenderSize.Width, 0, _backRenderSize.Height, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } else { + glDisable(GL_SCISSOR_TEST); + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_SCISSOR_TEST); + + glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + + RenderSpriteBatches(); + + if (_do_render_to_texture) { + // Texture is ready, now create rectangle in the world space and draw texture upon it #if AGS_PLATFORM_OS_IOS - ios_select_buffer(); + ios_select_buffer(); #else - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); #endif - glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); - glDisable(GL_BLEND); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_BLEND); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - // use correct sampling method when stretching buffer to the final rect - _filter->SetFilteringForStandardSprite(); + // use correct sampling method when stretching buffer to the final rect + _filter->SetFilteringForStandardSprite(); - glBindTexture(GL_TEXTURE_2D, _backbuffer); + glBindTexture(GL_TEXTURE_2D, _backbuffer); - glTexCoordPointer(2, GL_FLOAT, 0, _backbuffer_texture_coordinates); - glVertexPointer(2, GL_FLOAT, 0, _backbuffer_vertices); - glClear(GL_COLOR_BUFFER_BIT); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glTexCoordPointer(2, GL_FLOAT, 0, _backbuffer_texture_coordinates); + glVertexPointer(2, GL_FLOAT, 0, _backbuffer_vertices); + glClear(GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glEnable(GL_BLEND); - } + glEnable(GL_BLEND); + } - glFinish(); + glFinish(); #if AGS_PLATFORM_OS_WINDOWS - SwapBuffers(_hDC); + SwapBuffers(_hDC); #elif AGS_PLATFORM_OS_LINUX - glXSwapBuffers(_xwin.display, _xwin.window); + glXSwapBuffers(_xwin.display, _xwin.window); #elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - device_swap_buffers(); + device_swap_buffers(); #endif - if (clearDrawListAfterwards) - { - BackupDrawLists(); - ClearDrawLists(); - } - ResetFxPool(); + if (clearDrawListAfterwards) { + BackupDrawLists(); + ClearDrawLists(); + } + ResetFxPool(); +} + +void OGLGraphicsDriver::RenderSpriteBatches() { + // Render all the sprite batches with necessary transformations + Rect main_viewport = _do_render_to_texture ? _srcRect : _viewportRect; + int surface_height = _do_render_to_texture ? _srcRect.GetHeight() : device_screen_physical_height; + // TODO: see if it's possible to refactor and not enable/disable scissor test + // TODO: also maybe sync scissor code logic with D3D renderer + if (_do_render_to_texture) + glEnable(GL_SCISSOR_TEST); + + for (size_t i = 0; i <= _actSpriteBatch; ++i) { + const Rect &viewport = _spriteBatches[i].Viewport; + const OGLSpriteBatch &batch = _spriteBatches[i]; + if (!viewport.IsEmpty()) { + Rect scissor = _do_render_to_texture ? viewport : _scaling.ScaleRange(viewport); + scissor = ConvertTopDownRect(scissor, surface_height); + glScissor(scissor.Left, scissor.Top, scissor.GetWidth(), scissor.GetHeight()); + } else { + glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); + } + _stageVirtualScreen = GetStageScreen(i); + RenderSpriteBatch(batch); + } + + _stageVirtualScreen = GetStageScreen(0); + glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); + if (_do_render_to_texture) + glDisable(GL_SCISSOR_TEST); +} + +void OGLGraphicsDriver::RenderSpriteBatch(const OGLSpriteBatch &batch) { + OGLDrawListEntry stageEntry; // raw-draw plugin support + + const std::vector &listToDraw = batch.List; + for (size_t i = 0; i < listToDraw.size(); i++) { + if (listToDraw[i].skip) + continue; + + const OGLDrawListEntry *sprite = &listToDraw[i]; + if (listToDraw[i].bitmap == nullptr) { + if (DoNullSpriteCallback(listToDraw[i].x, listToDraw[i].y)) + stageEntry = OGLDrawListEntry((OGLBitmap *)_stageVirtualScreenDDB); + else + continue; + sprite = &stageEntry; + } + + this->_renderSprite(sprite, batch.Matrix); + } +} + +void OGLGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) { + if (_spriteBatches.size() <= index) + _spriteBatches.resize(index + 1); + _spriteBatches[index].List.clear(); + + Rect orig_viewport = desc.Viewport; + Rect node_viewport = desc.Viewport; + // Combine both world transform and viewport transform into one matrix for faster perfomance + // NOTE: in OpenGL order of transformation is REVERSE to the order of commands! + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + // Global node transformation (flip and offset) + int node_tx = desc.Offset.X, node_ty = desc.Offset.Y; + float node_sx = 1.f, node_sy = 1.f; + if ((desc.Flip == kFlip_Vertical) || (desc.Flip == kFlip_Both)) { + int left = _srcRect.GetWidth() - (orig_viewport.Right + 1); + node_viewport.MoveToX(left); + node_sx = -1.f; + } + if ((desc.Flip == kFlip_Horizontal) || (desc.Flip == kFlip_Both)) { + int top = _srcRect.GetHeight() - (orig_viewport.Bottom + 1); + node_viewport.MoveToY(top); + node_sy = -1.f; + } + _spriteBatches[index].Viewport = Rect::MoveBy(node_viewport, node_tx, node_ty); + glTranslatef(node_tx, -(node_ty), 0.0f); + glScalef(node_sx, node_sy, 1.f); + // NOTE: before node, translate to viewport position; remove this if this + // is changed to a separate operation at some point + // TODO: find out if this is an optimal way to translate scaled room into Top-Left screen coordinates + float scaled_offx = (_srcRect.GetWidth() - desc.Transform.ScaleX * (float)_srcRect.GetWidth()) / 2.f; + float scaled_offy = (_srcRect.GetHeight() - desc.Transform.ScaleY * (float)_srcRect.GetHeight()) / 2.f; + glTranslatef((float)(orig_viewport.Left - scaled_offx), (float) - (orig_viewport.Top - scaled_offy), 0.0f); + // IMPORTANT: while the sprites are usually transformed in the order of Scale-Rotate-Translate, + // the camera's transformation is essentially reverse world transformation. And the operations + // are inverse: Translate-Rotate-Scale (here they are double inverse because OpenGL). + glScalef(desc.Transform.ScaleX, desc.Transform.ScaleY, 1.f); // scale camera + glRotatef(Math::RadiansToDegrees(desc.Transform.Rotate), 0.f, 0.f, 1.f); // rotate camera + glTranslatef((float)desc.Transform.X, (float) - desc.Transform.Y, 0.0f); // translate camera + glGetFloatv(GL_MODELVIEW_MATRIX, _spriteBatches[index].Matrix.m); + glLoadIdentity(); + + // create stage screen for plugin raw drawing + int src_w = orig_viewport.GetWidth() / desc.Transform.ScaleX; + int src_h = orig_viewport.GetHeight() / desc.Transform.ScaleY; + CreateStageScreen(index, Size(src_w, src_h)); +} + +void OGLGraphicsDriver::ResetAllBatches() { + for (size_t i = 0; i < _spriteBatches.size(); ++i) + _spriteBatches[i].List.clear(); +} + +void OGLGraphicsDriver::ClearDrawBackups() { + _backupBatchDescs.clear(); + _backupBatches.clear(); +} + +void OGLGraphicsDriver::BackupDrawLists() { + ClearDrawBackups(); + for (size_t i = 0; i <= _actSpriteBatch; ++i) { + _backupBatchDescs.push_back(_spriteBatchDesc[i]); + _backupBatches.push_back(_spriteBatches[i]); + } +} + +void OGLGraphicsDriver::RestoreDrawLists() { + if (_backupBatchDescs.size() == 0) { + ClearDrawLists(); + return; + } + _spriteBatchDesc = _backupBatchDescs; + _spriteBatches = _backupBatches; + _actSpriteBatch = _backupBatchDescs.size() - 1; +} + +void OGLGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) { + _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry((OGLBitmap *)bitmap, x, y)); +} + +void OGLGraphicsDriver::DestroyDDB(IDriverDependantBitmap *bitmap) { + // Remove deleted DDB from backups + for (OGLSpriteBatches::iterator it = _backupBatches.begin(); it != _backupBatches.end(); ++it) { + std::vector &drawlist = it->List; + for (size_t i = 0; i < drawlist.size(); i++) { + if (drawlist[i].bitmap == bitmap) + drawlist[i].skip = true; + } + } + delete bitmap; +} + + +void OGLGraphicsDriver::UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha) { + int textureHeight = tile->height; + int textureWidth = tile->width; + + // TODO: this seem to be tad overcomplicated, these conversions were made + // when texture is just created. Check later if this operation here may be removed. + AdjustSizeToNearestSupportedByCard(&textureWidth, &textureHeight); + + int tilex = 0, tiley = 0, tileWidth = tile->width, tileHeight = tile->height; + if (textureWidth > tile->width) { + int texxoff = Math::Min(textureWidth - tile->width - 1, 1); + tilex = texxoff; + tileWidth += 1 + texxoff; + } + if (textureHeight > tile->height) { + int texyoff = Math::Min(textureHeight - tile->height - 1, 1); + tiley = texyoff; + tileHeight += 1 + texyoff; + } + + const bool usingLinearFiltering = _filter->UseLinearFiltering(); + char *origPtr = (char *)malloc(sizeof(int) * tileWidth * tileHeight); + const int pitch = tileWidth * sizeof(int); + char *memPtr = origPtr + pitch * tiley + tilex * sizeof(int); + + TextureTile fixedTile; + fixedTile.x = tile->x; + fixedTile.y = tile->y; + fixedTile.width = Math::Min(tile->width, tileWidth); + fixedTile.height = Math::Min(tile->height, tileHeight); + if (target->_opaque) + BitmapToVideoMemOpaque(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch); + else + BitmapToVideoMem(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch, usingLinearFiltering); + + // Mimic the behaviour of GL_CLAMP_EDGE for the tile edges + // NOTE: on some platforms GL_CLAMP_EDGE does not work with the version of OpenGL we're using. + if (tile->width < tileWidth) { + if (tilex > 0) { + for (int y = 0; y < tileHeight; y++) { + unsigned int *edge_left_col = (unsigned int *)(origPtr + y * pitch + (tilex - 1) * sizeof(int)); + unsigned int *bm_left_col = (unsigned int *)(origPtr + y * pitch + (tilex) * sizeof(int)); + *edge_left_col = *bm_left_col & 0x00FFFFFF; + } + } + for (int y = 0; y < tileHeight; y++) { + unsigned int *edge_right_col = (unsigned int *)(origPtr + y * pitch + (tilex + tile->width) * sizeof(int)); + unsigned int *bm_right_col = edge_right_col - 1; + *edge_right_col = *bm_right_col & 0x00FFFFFF; + } + } + if (tile->height < tileHeight) { + if (tiley > 0) { + unsigned int *edge_top_row = (unsigned int *)(origPtr + pitch * (tiley - 1)); + unsigned int *bm_top_row = (unsigned int *)(origPtr + pitch * (tiley)); + for (int x = 0; x < tileWidth; x++) { + edge_top_row[x] = bm_top_row[x] & 0x00FFFFFF; + } + } + unsigned int *edge_bottom_row = (unsigned int *)(origPtr + pitch * (tiley + tile->height)); + unsigned int *bm_bottom_row = (unsigned int *)(origPtr + pitch * (tiley + tile->height - 1)); + for (int x = 0; x < tileWidth; x++) { + edge_bottom_row[x] = bm_bottom_row[x] & 0x00FFFFFF; + } + } + + glBindTexture(GL_TEXTURE_2D, tile->texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tileWidth, tileHeight, GL_RGBA, GL_UNSIGNED_BYTE, origPtr); + + free(origPtr); +} + +void OGLGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { + OGLBitmap *target = (OGLBitmap *)bitmapToUpdate; + if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) + throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); + const int color_depth = bitmap->GetColorDepth(); + if (color_depth != target->_colDepth) + throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); + + target->_hasAlpha = hasAlpha; + if (color_depth == 8) + select_palette(palette); + + for (int i = 0; i < target->_numTiles; i++) { + UpdateTextureRegion(&target->_tiles[i], bitmap, target, hasAlpha); + } + + if (color_depth == 8) + unselect_palette(); +} + +int OGLGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) { + if (color_depth == 8) + return 8; + if (color_depth > 8 && color_depth <= 16) + return 16; + return 32; +} + +void OGLGraphicsDriver::AdjustSizeToNearestSupportedByCard(int *width, int *height) { + int allocatedWidth = *width, allocatedHeight = *height; + + bool foundWidth = false, foundHeight = false; + int tryThis = 2; + while ((!foundWidth) || (!foundHeight)) { + if ((tryThis >= allocatedWidth) && (!foundWidth)) { + allocatedWidth = tryThis; + foundWidth = true; + } + + if ((tryThis >= allocatedHeight) && (!foundHeight)) { + allocatedHeight = tryThis; + foundHeight = true; + } + + tryThis = tryThis << 1; + } + + *width = allocatedWidth; + *height = allocatedHeight; +} + + + +IDriverDependantBitmap *OGLGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) { + int allocatedWidth = bitmap->GetWidth(); + int allocatedHeight = bitmap->GetHeight(); + // NOTE: original bitmap object is not modified in this function + if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) + throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); + int colourDepth = bitmap->GetColorDepth(); + + OGLBitmap *ddb = new OGLBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); + + AdjustSizeToNearestSupportedByCard(&allocatedWidth, &allocatedHeight); + int tilesAcross = 1, tilesDown = 1; + + // Calculate how many textures will be necessary to + // store this image + + int MaxTextureWidth = 512; + int MaxTextureHeight = 512; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTextureWidth); + MaxTextureHeight = MaxTextureWidth; + + tilesAcross = (allocatedWidth + MaxTextureWidth - 1) / MaxTextureWidth; + tilesDown = (allocatedHeight + MaxTextureHeight - 1) / MaxTextureHeight; + int tileWidth = bitmap->GetWidth() / tilesAcross; + int lastTileExtraWidth = bitmap->GetWidth() % tilesAcross; + int tileHeight = bitmap->GetHeight() / tilesDown; + int lastTileExtraHeight = bitmap->GetHeight() % tilesDown; + int tileAllocatedWidth = tileWidth; + int tileAllocatedHeight = tileHeight; + + AdjustSizeToNearestSupportedByCard(&tileAllocatedWidth, &tileAllocatedHeight); + + int numTiles = tilesAcross * tilesDown; + OGLTextureTile *tiles = (OGLTextureTile *)malloc(sizeof(OGLTextureTile) * numTiles); + memset(tiles, 0, sizeof(OGLTextureTile) * numTiles); + + OGLCUSTOMVERTEX *vertices = nullptr; + + if ((numTiles == 1) && + (allocatedWidth == bitmap->GetWidth()) && + (allocatedHeight == bitmap->GetHeight())) { + // use default whole-image vertices + } else { + // The texture is not the same as the bitmap, so create some custom vertices + // so that only the relevant portion of the texture is rendered + int vertexBufferSize = numTiles * 4 * sizeof(OGLCUSTOMVERTEX); + + ddb->_vertex = vertices = (OGLCUSTOMVERTEX *)malloc(vertexBufferSize); + } + + for (int x = 0; x < tilesAcross; x++) { + for (int y = 0; y < tilesDown; y++) { + OGLTextureTile *thisTile = &tiles[y * tilesAcross + x]; + int thisAllocatedWidth = tileAllocatedWidth; + int thisAllocatedHeight = tileAllocatedHeight; + thisTile->x = x * tileWidth; + thisTile->y = y * tileHeight; + thisTile->width = tileWidth; + thisTile->height = tileHeight; + if (x == tilesAcross - 1) { + thisTile->width += lastTileExtraWidth; + thisAllocatedWidth = thisTile->width; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + if (y == tilesDown - 1) { + thisTile->height += lastTileExtraHeight; + thisAllocatedHeight = thisTile->height; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + + if (vertices != nullptr) { + const int texxoff = (thisAllocatedWidth - thisTile->width) > 1 ? 1 : 0; + const int texyoff = (thisAllocatedHeight - thisTile->height) > 1 ? 1 : 0; + for (int vidx = 0; vidx < 4; vidx++) { + int i = (y * tilesAcross + x) * 4 + vidx; + vertices[i] = defaultVertices[vidx]; + if (vertices[i].tu > 0.0) { + vertices[i].tu = (float)(texxoff + thisTile->width) / (float)thisAllocatedWidth; + } else { + vertices[i].tu = (float)(texxoff) / (float)thisAllocatedWidth; + } + if (vertices[i].tv > 0.0) { + vertices[i].tv = (float)(texyoff + thisTile->height) / (float)thisAllocatedHeight; + } else { + vertices[i].tv = (float)(texyoff) / (float)thisAllocatedHeight; + } + } + } + + glGenTextures(1, &thisTile->texture); + glBindTexture(GL_TEXTURE_2D, thisTile->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + // NOTE: pay attention that the texture format depends on the **display mode**'s format, + // rather than source bitmap's color depth! + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, thisAllocatedWidth, thisAllocatedHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + } + } + + ddb->_numTiles = numTiles; + ddb->_tiles = tiles; + + UpdateDDBFromBitmap(ddb, bitmap, hasAlpha); + + return ddb; +} + +void OGLGraphicsDriver::do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { + // Construct scene in order: game screen, fade fx, post game overlay + // NOTE: please keep in mind: redrawing last saved frame here instead of constructing new one + // is done because of backwards-compatibility issue: originally AGS faded out using frame + // drawn before the script that triggers blocking fade (e.g. instigated by ChangeRoom). + // Unfortunately some existing games were changing looks of the screen during same function, + // but these were not supposed to get on screen until before fade-in. + if (fadingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != nullptr) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(makecol32(targetColourRed, targetColourGreen, targetColourBlue)); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + if (speed <= 0) speed = 16; + speed *= 2; // harmonise speeds with software driver which is faster + for (int a = 1; a < 255; a += speed) { + d3db->SetTransparency(fadingOut ? a : (255 - a)); + this->_render(false); + + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + + if (fadingOut) { + d3db->SetTransparency(0); + this->_render(false); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); +} + +void OGLGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { + do_fade(true, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void OGLGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) { + do_fade(false, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void OGLGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) { + // Construct scene in order: game screen, fade fx, post game overlay + if (blackingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != nullptr) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + size_t fx_batch = _actSpriteBatch; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (!blackingOut) { + // when fading in, draw four black boxes, one + // across each side of the screen + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + } + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); + int boxWidth = speed; + int boxHeight = yspeed; + + while (boxWidth < _srcRect.GetWidth()) { + boxWidth += speed; + boxHeight += yspeed; + OGLSpriteBatch &batch = _spriteBatches[fx_batch]; + std::vector &drawList = batch.List; + size_t last = drawList.size() - 1; + if (blackingOut) { + drawList[last].x = _srcRect.GetWidth() / 2 - boxWidth / 2; + drawList[last].y = _srcRect.GetHeight() / 2 - boxHeight / 2; + d3db->SetStretch(boxWidth, boxHeight, false); + } else { + drawList[last - 3].x = _srcRect.GetWidth() / 2 - boxWidth / 2 - _srcRect.GetWidth(); + drawList[last - 2].y = _srcRect.GetHeight() / 2 - boxHeight / 2 - _srcRect.GetHeight(); + drawList[last - 1].x = _srcRect.GetWidth() / 2 + boxWidth / 2; + drawList[last ].y = _srcRect.GetHeight() / 2 + boxHeight / 2; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + } + + this->_render(false); + + if (_pollingCallback) + _pollingCallback(); + platform->Delay(delay); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); +} + +void OGLGraphicsDriver::SetScreenFade(int red, int green, int blue) { + OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(0); + _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); +} + +void OGLGraphicsDriver::SetScreenTint(int red, int green, int blue) { + if (red == 0 && green == 0 && blue == 0) return; + OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(128); + _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); } -void OGLGraphicsDriver::RenderSpriteBatches() -{ - // Render all the sprite batches with necessary transformations - Rect main_viewport = _do_render_to_texture ? _srcRect : _viewportRect; - int surface_height = _do_render_to_texture ? _srcRect.GetHeight() : device_screen_physical_height; - // TODO: see if it's possible to refactor and not enable/disable scissor test - // TODO: also maybe sync scissor code logic with D3D renderer - if (_do_render_to_texture) - glEnable(GL_SCISSOR_TEST); - - for (size_t i = 0; i <= _actSpriteBatch; ++i) - { - const Rect &viewport = _spriteBatches[i].Viewport; - const OGLSpriteBatch &batch = _spriteBatches[i]; - if (!viewport.IsEmpty()) - { - Rect scissor = _do_render_to_texture ? viewport : _scaling.ScaleRange(viewport); - scissor = ConvertTopDownRect(scissor, surface_height); - glScissor(scissor.Left, scissor.Top, scissor.GetWidth(), scissor.GetHeight()); - } - else - { - glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); - } - _stageVirtualScreen = GetStageScreen(i); - RenderSpriteBatch(batch); - } - - _stageVirtualScreen = GetStageScreen(0); - glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); - if (_do_render_to_texture) - glDisable(GL_SCISSOR_TEST); -} - -void OGLGraphicsDriver::RenderSpriteBatch(const OGLSpriteBatch &batch) -{ - OGLDrawListEntry stageEntry; // raw-draw plugin support - - const std::vector &listToDraw = batch.List; - for (size_t i = 0; i < listToDraw.size(); i++) - { - if (listToDraw[i].skip) - continue; - - const OGLDrawListEntry *sprite = &listToDraw[i]; - if (listToDraw[i].bitmap == nullptr) - { - if (DoNullSpriteCallback(listToDraw[i].x, listToDraw[i].y)) - stageEntry = OGLDrawListEntry((OGLBitmap*)_stageVirtualScreenDDB); - else - continue; - sprite = &stageEntry; - } - - this->_renderSprite(sprite, batch.Matrix); - } -} - -void OGLGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) -{ - if (_spriteBatches.size() <= index) - _spriteBatches.resize(index + 1); - _spriteBatches[index].List.clear(); - - Rect orig_viewport = desc.Viewport; - Rect node_viewport = desc.Viewport; - // Combine both world transform and viewport transform into one matrix for faster perfomance - // NOTE: in OpenGL order of transformation is REVERSE to the order of commands! - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - // Global node transformation (flip and offset) - int node_tx = desc.Offset.X, node_ty = desc.Offset.Y; - float node_sx = 1.f, node_sy = 1.f; - if ((desc.Flip == kFlip_Vertical) || (desc.Flip == kFlip_Both)) - { - int left = _srcRect.GetWidth() - (orig_viewport.Right + 1); - node_viewport.MoveToX(left); - node_sx = -1.f; - } - if ((desc.Flip == kFlip_Horizontal) || (desc.Flip == kFlip_Both)) - { - int top = _srcRect.GetHeight() - (orig_viewport.Bottom + 1); - node_viewport.MoveToY(top); - node_sy = -1.f; - } - _spriteBatches[index].Viewport = Rect::MoveBy(node_viewport, node_tx, node_ty); - glTranslatef(node_tx, -(node_ty), 0.0f); - glScalef(node_sx, node_sy, 1.f); - // NOTE: before node, translate to viewport position; remove this if this - // is changed to a separate operation at some point - // TODO: find out if this is an optimal way to translate scaled room into Top-Left screen coordinates - float scaled_offx = (_srcRect.GetWidth() - desc.Transform.ScaleX * (float)_srcRect.GetWidth()) / 2.f; - float scaled_offy = (_srcRect.GetHeight() - desc.Transform.ScaleY * (float)_srcRect.GetHeight()) / 2.f; - glTranslatef((float)(orig_viewport.Left - scaled_offx), (float)-(orig_viewport.Top - scaled_offy), 0.0f); - // IMPORTANT: while the sprites are usually transformed in the order of Scale-Rotate-Translate, - // the camera's transformation is essentially reverse world transformation. And the operations - // are inverse: Translate-Rotate-Scale (here they are double inverse because OpenGL). - glScalef(desc.Transform.ScaleX, desc.Transform.ScaleY, 1.f); // scale camera - glRotatef(Math::RadiansToDegrees(desc.Transform.Rotate), 0.f, 0.f, 1.f); // rotate camera - glTranslatef((float)desc.Transform.X, (float)-desc.Transform.Y, 0.0f); // translate camera - glGetFloatv(GL_MODELVIEW_MATRIX, _spriteBatches[index].Matrix.m); - glLoadIdentity(); - - // create stage screen for plugin raw drawing - int src_w = orig_viewport.GetWidth() / desc.Transform.ScaleX; - int src_h = orig_viewport.GetHeight() / desc.Transform.ScaleY; - CreateStageScreen(index, Size(src_w, src_h)); -} - -void OGLGraphicsDriver::ResetAllBatches() -{ - for (size_t i = 0; i < _spriteBatches.size(); ++i) - _spriteBatches[i].List.clear(); -} - -void OGLGraphicsDriver::ClearDrawBackups() -{ - _backupBatchDescs.clear(); - _backupBatches.clear(); -} - -void OGLGraphicsDriver::BackupDrawLists() -{ - ClearDrawBackups(); - for (size_t i = 0; i <= _actSpriteBatch; ++i) - { - _backupBatchDescs.push_back(_spriteBatchDesc[i]); - _backupBatches.push_back(_spriteBatches[i]); - } -} - -void OGLGraphicsDriver::RestoreDrawLists() -{ - if (_backupBatchDescs.size() == 0) - { - ClearDrawLists(); - return; - } - _spriteBatchDesc = _backupBatchDescs; - _spriteBatches = _backupBatches; - _actSpriteBatch = _backupBatchDescs.size() - 1; -} - -void OGLGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) -{ - _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry((OGLBitmap*)bitmap, x, y)); -} - -void OGLGraphicsDriver::DestroyDDB(IDriverDependantBitmap* bitmap) -{ - // Remove deleted DDB from backups - for (OGLSpriteBatches::iterator it = _backupBatches.begin(); it != _backupBatches.end(); ++it) - { - std::vector &drawlist = it->List; - for (size_t i = 0; i < drawlist.size(); i++) - { - if (drawlist[i].bitmap == bitmap) - drawlist[i].skip = true; - } - } - delete bitmap; -} - - -void OGLGraphicsDriver::UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha) -{ - int textureHeight = tile->height; - int textureWidth = tile->width; - - // TODO: this seem to be tad overcomplicated, these conversions were made - // when texture is just created. Check later if this operation here may be removed. - AdjustSizeToNearestSupportedByCard(&textureWidth, &textureHeight); - - int tilex = 0, tiley = 0, tileWidth = tile->width, tileHeight = tile->height; - if (textureWidth > tile->width) - { - int texxoff = Math::Min(textureWidth - tile->width - 1, 1); - tilex = texxoff; - tileWidth += 1 + texxoff; - } - if (textureHeight > tile->height) - { - int texyoff = Math::Min(textureHeight - tile->height - 1, 1); - tiley = texyoff; - tileHeight += 1 + texyoff; - } - - const bool usingLinearFiltering = _filter->UseLinearFiltering(); - char *origPtr = (char*)malloc(sizeof(int) * tileWidth * tileHeight); - const int pitch = tileWidth * sizeof(int); - char *memPtr = origPtr + pitch * tiley + tilex * sizeof(int); - - TextureTile fixedTile; - fixedTile.x = tile->x; - fixedTile.y = tile->y; - fixedTile.width = Math::Min(tile->width, tileWidth); - fixedTile.height = Math::Min(tile->height, tileHeight); - if (target->_opaque) - BitmapToVideoMemOpaque(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch); - else - BitmapToVideoMem(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch, usingLinearFiltering); - - // Mimic the behaviour of GL_CLAMP_EDGE for the tile edges - // NOTE: on some platforms GL_CLAMP_EDGE does not work with the version of OpenGL we're using. - if (tile->width < tileWidth) - { - if (tilex > 0) - { - for (int y = 0; y < tileHeight; y++) - { - unsigned int* edge_left_col = (unsigned int*)(origPtr + y * pitch + (tilex - 1) * sizeof(int)); - unsigned int* bm_left_col = (unsigned int*)(origPtr + y * pitch + (tilex) * sizeof(int)); - *edge_left_col = *bm_left_col & 0x00FFFFFF; - } - } - for (int y = 0; y < tileHeight; y++) - { - unsigned int* edge_right_col = (unsigned int*)(origPtr + y * pitch + (tilex + tile->width) * sizeof(int)); - unsigned int* bm_right_col = edge_right_col - 1; - *edge_right_col = *bm_right_col & 0x00FFFFFF; - } - } - if (tile->height < tileHeight) - { - if (tiley > 0) - { - unsigned int* edge_top_row = (unsigned int*)(origPtr + pitch * (tiley - 1)); - unsigned int* bm_top_row = (unsigned int*)(origPtr + pitch * (tiley)); - for (int x = 0; x < tileWidth; x++) - { - edge_top_row[x] = bm_top_row[x] & 0x00FFFFFF; - } - } - unsigned int* edge_bottom_row = (unsigned int*)(origPtr + pitch * (tiley + tile->height)); - unsigned int* bm_bottom_row = (unsigned int*)(origPtr + pitch * (tiley + tile->height - 1)); - for (int x = 0; x < tileWidth; x++) - { - edge_bottom_row[x] = bm_bottom_row[x] & 0x00FFFFFF; - } - } - - glBindTexture(GL_TEXTURE_2D, tile->texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tileWidth, tileHeight, GL_RGBA, GL_UNSIGNED_BYTE, origPtr); - - free(origPtr); -} - -void OGLGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) -{ - OGLBitmap *target = (OGLBitmap*)bitmapToUpdate; - if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) - throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); - const int color_depth = bitmap->GetColorDepth(); - if (color_depth != target->_colDepth) - throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); - target->_hasAlpha = hasAlpha; - if (color_depth == 8) - select_palette(palette); - - for (int i = 0; i < target->_numTiles; i++) - { - UpdateTextureRegion(&target->_tiles[i], bitmap, target, hasAlpha); - } - - if (color_depth == 8) - unselect_palette(); -} - -int OGLGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) -{ - if (color_depth == 8) - return 8; - if (color_depth > 8 && color_depth <= 16) - return 16; - return 32; -} - -void OGLGraphicsDriver::AdjustSizeToNearestSupportedByCard(int *width, int *height) -{ - int allocatedWidth = *width, allocatedHeight = *height; - - bool foundWidth = false, foundHeight = false; - int tryThis = 2; - while ((!foundWidth) || (!foundHeight)) - { - if ((tryThis >= allocatedWidth) && (!foundWidth)) - { - allocatedWidth = tryThis; - foundWidth = true; - } - - if ((tryThis >= allocatedHeight) && (!foundHeight)) - { - allocatedHeight = tryThis; - foundHeight = true; - } - - tryThis = tryThis << 1; - } - - *width = allocatedWidth; - *height = allocatedHeight; -} - - - -IDriverDependantBitmap* OGLGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) -{ - int allocatedWidth = bitmap->GetWidth(); - int allocatedHeight = bitmap->GetHeight(); - // NOTE: original bitmap object is not modified in this function - if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) - throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); - int colourDepth = bitmap->GetColorDepth(); - - OGLBitmap *ddb = new OGLBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); - - AdjustSizeToNearestSupportedByCard(&allocatedWidth, &allocatedHeight); - int tilesAcross = 1, tilesDown = 1; - - // Calculate how many textures will be necessary to - // store this image - - int MaxTextureWidth = 512; - int MaxTextureHeight = 512; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTextureWidth); - MaxTextureHeight = MaxTextureWidth; - - tilesAcross = (allocatedWidth + MaxTextureWidth - 1) / MaxTextureWidth; - tilesDown = (allocatedHeight + MaxTextureHeight - 1) / MaxTextureHeight; - int tileWidth = bitmap->GetWidth() / tilesAcross; - int lastTileExtraWidth = bitmap->GetWidth() % tilesAcross; - int tileHeight = bitmap->GetHeight() / tilesDown; - int lastTileExtraHeight = bitmap->GetHeight() % tilesDown; - int tileAllocatedWidth = tileWidth; - int tileAllocatedHeight = tileHeight; - - AdjustSizeToNearestSupportedByCard(&tileAllocatedWidth, &tileAllocatedHeight); - - int numTiles = tilesAcross * tilesDown; - OGLTextureTile *tiles = (OGLTextureTile*)malloc(sizeof(OGLTextureTile) * numTiles); - memset(tiles, 0, sizeof(OGLTextureTile) * numTiles); - - OGLCUSTOMVERTEX *vertices = nullptr; - - if ((numTiles == 1) && - (allocatedWidth == bitmap->GetWidth()) && - (allocatedHeight == bitmap->GetHeight())) - { - // use default whole-image vertices - } - else - { - // The texture is not the same as the bitmap, so create some custom vertices - // so that only the relevant portion of the texture is rendered - int vertexBufferSize = numTiles * 4 * sizeof(OGLCUSTOMVERTEX); - - ddb->_vertex = vertices = (OGLCUSTOMVERTEX*)malloc(vertexBufferSize); - } - - for (int x = 0; x < tilesAcross; x++) - { - for (int y = 0; y < tilesDown; y++) - { - OGLTextureTile *thisTile = &tiles[y * tilesAcross + x]; - int thisAllocatedWidth = tileAllocatedWidth; - int thisAllocatedHeight = tileAllocatedHeight; - thisTile->x = x * tileWidth; - thisTile->y = y * tileHeight; - thisTile->width = tileWidth; - thisTile->height = tileHeight; - if (x == tilesAcross - 1) - { - thisTile->width += lastTileExtraWidth; - thisAllocatedWidth = thisTile->width; - AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); - } - if (y == tilesDown - 1) - { - thisTile->height += lastTileExtraHeight; - thisAllocatedHeight = thisTile->height; - AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); - } - - if (vertices != nullptr) - { - const int texxoff = (thisAllocatedWidth - thisTile->width) > 1 ? 1 : 0; - const int texyoff = (thisAllocatedHeight - thisTile->height) > 1 ? 1 : 0; - for (int vidx = 0; vidx < 4; vidx++) - { - int i = (y * tilesAcross + x) * 4 + vidx; - vertices[i] = defaultVertices[vidx]; - if (vertices[i].tu > 0.0) - { - vertices[i].tu = (float)(texxoff + thisTile->width) / (float)thisAllocatedWidth; - } - else - { - vertices[i].tu = (float)(texxoff) / (float)thisAllocatedWidth; - } - if (vertices[i].tv > 0.0) - { - vertices[i].tv = (float)(texyoff + thisTile->height) / (float)thisAllocatedHeight; - } - else - { - vertices[i].tv = (float)(texyoff) / (float)thisAllocatedHeight; - } - } - } - - glGenTextures(1, &thisTile->texture); - glBindTexture(GL_TEXTURE_2D, thisTile->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - // NOTE: pay attention that the texture format depends on the **display mode**'s format, - // rather than source bitmap's color depth! - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, thisAllocatedWidth, thisAllocatedHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - } - } - - ddb->_numTiles = numTiles; - ddb->_tiles = tiles; - - UpdateDDBFromBitmap(ddb, bitmap, hasAlpha); - - return ddb; -} - -void OGLGraphicsDriver::do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - // Construct scene in order: game screen, fade fx, post game overlay - // NOTE: please keep in mind: redrawing last saved frame here instead of constructing new one - // is done because of backwards-compatibility issue: originally AGS faded out using frame - // drawn before the script that triggers blocking fade (e.g. instigated by ChangeRoom). - // Unfortunately some existing games were changing looks of the screen during same function, - // but these were not supposed to get on screen until before fade-in. - if (fadingOut) - this->_reDrawLastFrame(); - else if (_drawScreenCallback != nullptr) - _drawScreenCallback(); - Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); - blackSquare->Clear(makecol32(targetColourRed, targetColourGreen, targetColourBlue)); - IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); - delete blackSquare; - BeginSpriteBatch(_srcRect, SpriteTransform()); - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - this->DrawSprite(0, 0, d3db); - if (_drawPostScreenCallback != NULL) - _drawPostScreenCallback(); - - if (speed <= 0) speed = 16; - speed *= 2; // harmonise speeds with software driver which is faster - for (int a = 1; a < 255; a += speed) - { - d3db->SetTransparency(fadingOut ? a : (255 - a)); - this->_render(false); - - if (_pollingCallback) - _pollingCallback(); - WaitForNextFrame(); - } - - if (fadingOut) - { - d3db->SetTransparency(0); - this->_render(false); - } - - this->DestroyDDB(d3db); - this->ClearDrawLists(); - ResetFxPool(); -} - -void OGLGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - do_fade(true, speed, targetColourRed, targetColourGreen, targetColourBlue); -} +OGLGraphicsFactory *OGLGraphicsFactory::_factory = nullptr; -void OGLGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - do_fade(false, speed, targetColourRed, targetColourGreen, targetColourBlue); +OGLGraphicsFactory::~OGLGraphicsFactory() { + _factory = nullptr; } -void OGLGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) -{ - // Construct scene in order: game screen, fade fx, post game overlay - if (blackingOut) - this->_reDrawLastFrame(); - else if (_drawScreenCallback != nullptr) - _drawScreenCallback(); - Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); - blackSquare->Clear(); - IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); - delete blackSquare; - BeginSpriteBatch(_srcRect, SpriteTransform()); - size_t fx_batch = _actSpriteBatch; - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - this->DrawSprite(0, 0, d3db); - if (!blackingOut) - { - // when fading in, draw four black boxes, one - // across each side of the screen - this->DrawSprite(0, 0, d3db); - this->DrawSprite(0, 0, d3db); - this->DrawSprite(0, 0, d3db); - } - if (_drawPostScreenCallback != NULL) - _drawPostScreenCallback(); - - int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); - int boxWidth = speed; - int boxHeight = yspeed; - - while (boxWidth < _srcRect.GetWidth()) - { - boxWidth += speed; - boxHeight += yspeed; - OGLSpriteBatch &batch = _spriteBatches[fx_batch]; - std::vector &drawList = batch.List; - size_t last = drawList.size() - 1; - if (blackingOut) - { - drawList[last].x = _srcRect.GetWidth() / 2- boxWidth / 2; - drawList[last].y = _srcRect.GetHeight() / 2 - boxHeight / 2; - d3db->SetStretch(boxWidth, boxHeight, false); - } - else - { - drawList[last - 3].x = _srcRect.GetWidth() / 2 - boxWidth / 2 - _srcRect.GetWidth(); - drawList[last - 2].y = _srcRect.GetHeight() / 2 - boxHeight / 2 - _srcRect.GetHeight(); - drawList[last - 1].x = _srcRect.GetWidth() / 2 + boxWidth / 2; - drawList[last ].y = _srcRect.GetHeight() / 2 + boxHeight / 2; - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - } - - this->_render(false); - - if (_pollingCallback) - _pollingCallback(); - platform->Delay(delay); - } - - this->DestroyDDB(d3db); - this->ClearDrawLists(); - ResetFxPool(); -} - -void OGLGraphicsDriver::SetScreenFade(int red, int green, int blue) -{ - OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); - ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), - _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); - ddb->SetTransparency(0); - _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); +size_t OGLGraphicsFactory::GetFilterCount() const { + return 2; } -void OGLGraphicsDriver::SetScreenTint(int red, int green, int blue) -{ - if (red == 0 && green == 0 && blue == 0) return; - OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); - ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), - _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); - ddb->SetTransparency(128); - _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); +const GfxFilterInfo *OGLGraphicsFactory::GetFilterInfo(size_t index) const { + switch (index) { + case 0: + return &OGLGfxFilter::FilterInfo; + case 1: + return &AAOGLGfxFilter::FilterInfo; + default: + return nullptr; + } } - -OGLGraphicsFactory *OGLGraphicsFactory::_factory = nullptr; - -OGLGraphicsFactory::~OGLGraphicsFactory() -{ - _factory = nullptr; +String OGLGraphicsFactory::GetDefaultFilterID() const { + return OGLGfxFilter::FilterInfo.Id; } -size_t OGLGraphicsFactory::GetFilterCount() const -{ - return 2; +/* static */ OGLGraphicsFactory *OGLGraphicsFactory::GetFactory() { + if (!_factory) + _factory = new OGLGraphicsFactory(); + return _factory; } -const GfxFilterInfo *OGLGraphicsFactory::GetFilterInfo(size_t index) const -{ - switch (index) - { - case 0: - return &OGLGfxFilter::FilterInfo; - case 1: - return &AAOGLGfxFilter::FilterInfo; - default: - return nullptr; - } -} - -String OGLGraphicsFactory::GetDefaultFilterID() const -{ - return OGLGfxFilter::FilterInfo.Id; -} - -/* static */ OGLGraphicsFactory *OGLGraphicsFactory::GetFactory() -{ - if (!_factory) - _factory = new OGLGraphicsFactory(); - return _factory; +OGLGraphicsDriver *OGLGraphicsFactory::EnsureDriverCreated() { + if (!_driver) + _driver = new OGLGraphicsDriver(); + return _driver; } -OGLGraphicsDriver *OGLGraphicsFactory::EnsureDriverCreated() -{ - if (!_driver) - _driver = new OGLGraphicsDriver(); - return _driver; -} - -OGLGfxFilter *OGLGraphicsFactory::CreateFilter(const String &id) -{ - if (OGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new OGLGfxFilter(); - else if (AAOGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new AAOGLGfxFilter(); - return nullptr; +OGLGfxFilter *OGLGraphicsFactory::CreateFilter(const String &id) { + if (OGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new OGLGfxFilter(); + else if (AAOGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new AAOGLGfxFilter(); + return nullptr; } } // namespace OGL diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h index 2b3a6eece983..38b2c34f19fe 100644 --- a/engines/ags/engine/gfx/ali3dogl.h +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -39,330 +39,333 @@ #include "ogl_headers.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -namespace OGL -{ +namespace OGL { using Common::Bitmap; using Common::String; using Common::Version; typedef struct _OGLVECTOR { - float x; - float y; + float x; + float y; } OGLVECTOR2D; -struct OGLCUSTOMVERTEX -{ - OGLVECTOR2D position; - float tu; - float tv; +struct OGLCUSTOMVERTEX { + OGLVECTOR2D position; + float tu; + float tv; }; -struct OGLTextureTile : public TextureTile -{ - unsigned int texture; +struct OGLTextureTile : public TextureTile { + unsigned int texture; }; -class OGLBitmap : public VideoMemDDB -{ +class OGLBitmap : public VideoMemDDB { public: - // Transparency is a bit counter-intuitive - // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible - void SetTransparency(int transparency) override { _transparency = transparency; } - void SetFlippedLeftRight(bool isFlipped) override { _flipped = isFlipped; } - void SetStretch(int width, int height, bool useResampler = true) override - { - _stretchToWidth = width; - _stretchToHeight = height; - _useResampler = useResampler; - } - void SetLightLevel(int lightLevel) override { _lightLevel = lightLevel; } - void SetTint(int red, int green, int blue, int tintSaturation) override - { - _red = red; - _green = green; - _blue = blue; - _tintSaturation = tintSaturation; - } - - bool _flipped; - int _stretchToWidth, _stretchToHeight; - bool _useResampler; - int _red, _green, _blue; - int _tintSaturation; - int _lightLevel; - bool _hasAlpha; - int _transparency; - OGLCUSTOMVERTEX* _vertex; - OGLTextureTile *_tiles; - int _numTiles; - - OGLBitmap(int width, int height, int colDepth, bool opaque) - { - _width = width; - _height = height; - _colDepth = colDepth; - _flipped = false; - _hasAlpha = false; - _stretchToWidth = 0; - _stretchToHeight = 0; - _useResampler = false; - _red = _green = _blue = 0; - _tintSaturation = 0; - _lightLevel = 0; - _transparency = 0; - _opaque = opaque; - _vertex = nullptr; - _tiles = nullptr; - _numTiles = 0; - } - - int GetWidthToRender() const { return (_stretchToWidth > 0) ? _stretchToWidth : _width; } - int GetHeightToRender() const { return (_stretchToHeight > 0) ? _stretchToHeight : _height; } - - void Dispose(); - - ~OGLBitmap() override - { - Dispose(); - } + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + void SetTransparency(int transparency) override { + _transparency = transparency; + } + void SetFlippedLeftRight(bool isFlipped) override { + _flipped = isFlipped; + } + void SetStretch(int width, int height, bool useResampler = true) override { + _stretchToWidth = width; + _stretchToHeight = height; + _useResampler = useResampler; + } + void SetLightLevel(int lightLevel) override { + _lightLevel = lightLevel; + } + void SetTint(int red, int green, int blue, int tintSaturation) override { + _red = red; + _green = green; + _blue = blue; + _tintSaturation = tintSaturation; + } + + bool _flipped; + int _stretchToWidth, _stretchToHeight; + bool _useResampler; + int _red, _green, _blue; + int _tintSaturation; + int _lightLevel; + bool _hasAlpha; + int _transparency; + OGLCUSTOMVERTEX *_vertex; + OGLTextureTile *_tiles; + int _numTiles; + + OGLBitmap(int width, int height, int colDepth, bool opaque) { + _width = width; + _height = height; + _colDepth = colDepth; + _flipped = false; + _hasAlpha = false; + _stretchToWidth = 0; + _stretchToHeight = 0; + _useResampler = false; + _red = _green = _blue = 0; + _tintSaturation = 0; + _lightLevel = 0; + _transparency = 0; + _opaque = opaque; + _vertex = nullptr; + _tiles = nullptr; + _numTiles = 0; + } + + int GetWidthToRender() const { + return (_stretchToWidth > 0) ? _stretchToWidth : _width; + } + int GetHeightToRender() const { + return (_stretchToHeight > 0) ? _stretchToHeight : _height; + } + + void Dispose(); + + ~OGLBitmap() override { + Dispose(); + } }; typedef SpriteDrawListEntry OGLDrawListEntry; -typedef struct GLMATRIX { GLfloat m[16]; } GLMATRIX; -struct OGLSpriteBatch -{ - // List of sprites to render - std::vector List; - // Clipping viewport - Rect Viewport; - // Transformation matrix, built from the batch description - GLMATRIX Matrix; +typedef struct GLMATRIX { + GLfloat m[16]; +} GLMATRIX; +struct OGLSpriteBatch { + // List of sprites to render + std::vector List; + // Clipping viewport + Rect Viewport; + // Transformation matrix, built from the batch description + GLMATRIX Matrix; }; typedef std::vector OGLSpriteBatches; -class OGLDisplayModeList : public IGfxModeList -{ +class OGLDisplayModeList : public IGfxModeList { public: - OGLDisplayModeList(const std::vector &modes) - : _modes(modes) - { - } - - int GetModeCount() const override - { - return _modes.size(); - } - - bool GetMode(int index, DisplayMode &mode) const override - { - if (index >= 0 && (size_t)index < _modes.size()) - { - mode = _modes[index]; - return true; - } - return false; - } + OGLDisplayModeList(const std::vector &modes) + : _modes(modes) { + } + + int GetModeCount() const override { + return _modes.size(); + } + + bool GetMode(int index, DisplayMode &mode) const override { + if (index >= 0 && (size_t)index < _modes.size()) { + mode = _modes[index]; + return true; + } + return false; + } private: - std::vector _modes; + std::vector _modes; }; class OGLGfxFilter; -class OGLGraphicsDriver : public VideoMemoryGraphicsDriver -{ +class OGLGraphicsDriver : public VideoMemoryGraphicsDriver { public: - const char*GetDriverName() override { return "OpenGL"; } - const char*GetDriverID() override { return "OGL"; } - void SetTintMethod(TintMethod method) override; - bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; - bool SetNativeSize(const Size &src_size) override; - bool SetRenderFrame(const Rect &dst_rect) override; - int GetDisplayDepthForNativeDepth(int native_color_depth) const override; - IGfxModeList *GetSupportedModeList(int color_depth) override; - bool IsModeSupported(const DisplayMode &mode) override; - PGfxFilter GetGraphicsFilter() const override; - void UnInit(); - // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. - void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; - int GetCompatibleBitmapFormat(int color_depth) override; - IDriverDependantBitmap* CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; - void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; - void DestroyDDB(IDriverDependantBitmap* bitmap) override; - void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) override; - void RenderToBackBuffer() override; - void Render() override; - void Render(int xoff, int yoff, GlobalFlipType flip) override; - bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; - void EnableVsyncBeforeRender(bool enabled) override { } - void Vsync() override; - void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override; - void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void BoxOutEffect(bool blackingOut, int speed, int delay) override; - bool SupportsGammaControl() override; - void SetGamma(int newGamma) override; - void UseSmoothScaling(bool enabled) override { _smoothScaling = enabled; } - bool RequiresFullRedrawEachFrame() override { return true; } - bool HasAcceleratedTransform() override { return true; } - void SetScreenFade(int red, int green, int blue) override; - void SetScreenTint(int red, int green, int blue) override; - - typedef std::shared_ptr POGLFilter; - - void SetGraphicsFilter(POGLFilter filter); - - OGLGraphicsDriver(); - ~OGLGraphicsDriver() override; + const char *GetDriverName() override { + return "OpenGL"; + } + const char *GetDriverID() override { + return "OGL"; + } + void SetTintMethod(TintMethod method) override; + bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; + bool SetNativeSize(const Size &src_size) override; + bool SetRenderFrame(const Rect &dst_rect) override; + int GetDisplayDepthForNativeDepth(int native_color_depth) const override; + IGfxModeList *GetSupportedModeList(int color_depth) override; + bool IsModeSupported(const DisplayMode &mode) override; + PGfxFilter GetGraphicsFilter() const override; + void UnInit(); + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; + int GetCompatibleBitmapFormat(int color_depth) override; + IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; + void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; + void DestroyDDB(IDriverDependantBitmap *bitmap) override; + void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) override; + void RenderToBackBuffer() override; + void Render() override; + void Render(int xoff, int yoff, GlobalFlipType flip) override; + bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; + void EnableVsyncBeforeRender(bool enabled) override { } + void Vsync() override; + void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override; + void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void BoxOutEffect(bool blackingOut, int speed, int delay) override; + bool SupportsGammaControl() override; + void SetGamma(int newGamma) override; + void UseSmoothScaling(bool enabled) override { + _smoothScaling = enabled; + } + bool RequiresFullRedrawEachFrame() override { + return true; + } + bool HasAcceleratedTransform() override { + return true; + } + void SetScreenFade(int red, int green, int blue) override; + void SetScreenTint(int red, int green, int blue) override; + + typedef std::shared_ptr POGLFilter; + + void SetGraphicsFilter(POGLFilter filter); + + OGLGraphicsDriver(); + ~OGLGraphicsDriver() override; private: - POGLFilter _filter; + POGLFilter _filter; #if AGS_PLATFORM_OS_WINDOWS - HDC _hDC; - HGLRC _hRC; - HWND _hWnd; - HINSTANCE _hInstance; - GLuint _oldPixelFormat; - PIXELFORMATDESCRIPTOR _oldPixelFormatDesc; + HDC _hDC; + HGLRC _hRC; + HWND _hWnd; + HINSTANCE _hInstance; + GLuint _oldPixelFormat; + PIXELFORMATDESCRIPTOR _oldPixelFormatDesc; #endif #if AGS_PLATFORM_OS_LINUX - bool _have_window; - GLXContext _glxContext; + bool _have_window; + GLXContext _glxContext; #endif - bool _firstTimeInit; - // Position of backbuffer texture in world space - GLfloat _backbuffer_vertices[8]; - // Relative position of source image on the backbuffer texture, - // in local coordinates - GLfloat _backbuffer_texture_coordinates[8]; - OGLCUSTOMVERTEX defaultVertices[4]; - String previousError; - bool _smoothScaling; - bool _legacyPixelShader; - // Shader program and its variable references; - // the variables are rather specific for AGS use (sprite tinting). - struct ShaderProgram - { - GLuint Program; - GLuint SamplerVar; // texture ID - GLuint ColorVar; // primary operation variable - GLuint AuxVar; // auxiliary variable - - ShaderProgram(); - }; - ShaderProgram _tintShader; - ShaderProgram _lightShader; - - int device_screen_physical_width; - int device_screen_physical_height; - - // Viewport and scissor rect, in OpenGL screen coordinates (0,0 is at left-bottom) - Rect _viewportRect; - - // These two flags define whether driver can, and should (respectively) - // render sprites to texture, and then texture to screen, as opposed to - // rendering to screen directly. This is known as supersampling mode - bool _can_render_to_texture; - bool _do_render_to_texture; - // Backbuffer texture multiplier, used to determine a size of texture - // relative to the native game size. - int _super_sampling; - unsigned int _backbuffer; - unsigned int _fbo; - // Size of the backbuffer drawing area, equals to native size - // multiplied by _super_sampling - Size _backRenderSize; - // Actual size of the backbuffer texture, created by OpenGL - Size _backTextureSize; - - OGLSpriteBatches _spriteBatches; - // TODO: these draw list backups are needed only for the fade-in/out effects - // find out if it's possible to reimplement these effects in main drawing routine. - SpriteBatchDescs _backupBatchDescs; - OGLSpriteBatches _backupBatches; - - void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; - void ResetAllBatches() override; - - // Sets up GL objects not related to particular display mode - void FirstTimeInit(); - // Initializes Gl rendering context - bool InitGlScreen(const DisplayMode &mode); - bool CreateGlContext(const DisplayMode &mode); - void DeleteGlContext(); - // Sets up general rendering parameters - void InitGlParams(const DisplayMode &mode); - void SetupDefaultVertices(); - // Test if rendering to texture is supported - void TestRenderToTexture(); - // Test if supersampling should be allowed with the current setup - void TestSupersampling(); - // Create shader programs for sprite tinting and changing light level - void CreateShaders(); - void CreateTintShader(); - void CreateLightShader(); - void CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, - const char *sampler_var, const char *color_var, const char *aux_var); - void DeleteShaderProgram(ShaderProgram &prg); - void OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader); - // Configure backbuffer texture, that is used in render-to-texture mode - void SetupBackbufferTexture(); - void DeleteBackbufferTexture(); + bool _firstTimeInit; + // Position of backbuffer texture in world space + GLfloat _backbuffer_vertices[8]; + // Relative position of source image on the backbuffer texture, + // in local coordinates + GLfloat _backbuffer_texture_coordinates[8]; + OGLCUSTOMVERTEX defaultVertices[4]; + String previousError; + bool _smoothScaling; + bool _legacyPixelShader; + // Shader program and its variable references; + // the variables are rather specific for AGS use (sprite tinting). + struct ShaderProgram { + GLuint Program; + GLuint SamplerVar; // texture ID + GLuint ColorVar; // primary operation variable + GLuint AuxVar; // auxiliary variable + + ShaderProgram(); + }; + ShaderProgram _tintShader; + ShaderProgram _lightShader; + + int device_screen_physical_width; + int device_screen_physical_height; + + // Viewport and scissor rect, in OpenGL screen coordinates (0,0 is at left-bottom) + Rect _viewportRect; + + // These two flags define whether driver can, and should (respectively) + // render sprites to texture, and then texture to screen, as opposed to + // rendering to screen directly. This is known as supersampling mode + bool _can_render_to_texture; + bool _do_render_to_texture; + // Backbuffer texture multiplier, used to determine a size of texture + // relative to the native game size. + int _super_sampling; + unsigned int _backbuffer; + unsigned int _fbo; + // Size of the backbuffer drawing area, equals to native size + // multiplied by _super_sampling + Size _backRenderSize; + // Actual size of the backbuffer texture, created by OpenGL + Size _backTextureSize; + + OGLSpriteBatches _spriteBatches; + // TODO: these draw list backups are needed only for the fade-in/out effects + // find out if it's possible to reimplement these effects in main drawing routine. + SpriteBatchDescs _backupBatchDescs; + OGLSpriteBatches _backupBatches; + + void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; + void ResetAllBatches() override; + + // Sets up GL objects not related to particular display mode + void FirstTimeInit(); + // Initializes Gl rendering context + bool InitGlScreen(const DisplayMode &mode); + bool CreateGlContext(const DisplayMode &mode); + void DeleteGlContext(); + // Sets up general rendering parameters + void InitGlParams(const DisplayMode &mode); + void SetupDefaultVertices(); + // Test if rendering to texture is supported + void TestRenderToTexture(); + // Test if supersampling should be allowed with the current setup + void TestSupersampling(); + // Create shader programs for sprite tinting and changing light level + void CreateShaders(); + void CreateTintShader(); + void CreateLightShader(); + void CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, + const char *sampler_var, const char *color_var, const char *aux_var); + void DeleteShaderProgram(ShaderProgram &prg); + void OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader); + // Configure backbuffer texture, that is used in render-to-texture mode + void SetupBackbufferTexture(); + void DeleteBackbufferTexture(); #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX - void CreateDesktopScreen(int width, int height, int depth); + void CreateDesktopScreen(int width, int height, int depth); #elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - void UpdateDeviceScreen(); + void UpdateDeviceScreen(); #endif - // Unset parameters and release resources related to the display mode - void ReleaseDisplayMode(); - void AdjustSizeToNearestSupportedByCard(int *width, int *height); - void UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha); - void CreateVirtualScreen(); - void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); - void _renderSprite(const OGLDrawListEntry *entry, const GLMATRIX &matGlobal); - void SetupViewport(); - // Converts rectangle in top->down coordinates into OpenGL's native bottom->up coordinates - Rect ConvertTopDownRect(const Rect &top_down_rect, int surface_height); - - // Backup all draw lists in the temp storage - void BackupDrawLists(); - // Restore draw lists from the temp storage - void RestoreDrawLists(); - // Deletes draw list backups - void ClearDrawBackups(); - void _render(bool clearDrawListAfterwards); - void RenderSpriteBatches(); - void RenderSpriteBatch(const OGLSpriteBatch &batch); - void _reDrawLastFrame(); + // Unset parameters and release resources related to the display mode + void ReleaseDisplayMode(); + void AdjustSizeToNearestSupportedByCard(int *width, int *height); + void UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha); + void CreateVirtualScreen(); + void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + void _renderSprite(const OGLDrawListEntry *entry, const GLMATRIX &matGlobal); + void SetupViewport(); + // Converts rectangle in top->down coordinates into OpenGL's native bottom->up coordinates + Rect ConvertTopDownRect(const Rect &top_down_rect, int surface_height); + + // Backup all draw lists in the temp storage + void BackupDrawLists(); + // Restore draw lists from the temp storage + void RestoreDrawLists(); + // Deletes draw list backups + void ClearDrawBackups(); + void _render(bool clearDrawListAfterwards); + void RenderSpriteBatches(); + void RenderSpriteBatch(const OGLSpriteBatch &batch); + void _reDrawLastFrame(); }; -class OGLGraphicsFactory : public GfxDriverFactoryBase -{ +class OGLGraphicsFactory : public GfxDriverFactoryBase { public: - ~OGLGraphicsFactory() override; + ~OGLGraphicsFactory() override; - size_t GetFilterCount() const override; - const GfxFilterInfo *GetFilterInfo(size_t index) const override; - String GetDefaultFilterID() const override; + size_t GetFilterCount() const override; + const GfxFilterInfo *GetFilterInfo(size_t index) const override; + String GetDefaultFilterID() const override; - static OGLGraphicsFactory *GetFactory(); + static OGLGraphicsFactory *GetFactory(); private: - OGLGraphicsDriver *EnsureDriverCreated() override; - OGLGfxFilter *CreateFilter(const String &id) override; + OGLGraphicsDriver *EnsureDriverCreated() override; + OGLGfxFilter *CreateFilter(const String &id) override; - static OGLGraphicsFactory *_factory; + static OGLGraphicsFactory *_factory; }; } // namespace OGL diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index 252d7e9c9bf6..c0f7836b05e8 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -40,12 +40,12 @@ #if AGS_DDRAW_GAMMA_CONTROL // NOTE: this struct and variables are defined internally in Allegro typedef struct DDRAW_SURFACE { - LPDIRECTDRAWSURFACE2 id; - int flags; - int lock_nesting; - BITMAP *parent_bmp; - struct DDRAW_SURFACE *next; - struct DDRAW_SURFACE *prev; + LPDIRECTDRAWSURFACE2 id; + int flags; + int lock_nesting; + BITMAP *parent_bmp; + struct DDRAW_SURFACE *next; + struct DDRAW_SURFACE *prev; } DDRAW_SURFACE; extern "C" extern LPDIRECTDRAW2 directdraw; @@ -53,669 +53,582 @@ extern "C" DDRAW_SURFACE *gfx_directx_primary_surface; #endif // AGS_DDRAW_GAMMA_CONTROL #ifndef AGS_NO_VIDEO_PLAYER -extern int dxmedia_play_video (const char*, bool, int, int); +extern int dxmedia_play_video(const char *, bool, int, int); #endif -namespace AGS -{ -namespace Engine -{ -namespace ALSW -{ +namespace AGS { +namespace Engine { +namespace ALSW { using namespace Common; -bool ALSoftwareGfxModeList::GetMode(int index, DisplayMode &mode) const -{ - if (_gfxModeList && index >= 0 && index < _gfxModeList->num_modes) - { - mode.Width = _gfxModeList->mode[index].width; - mode.Height = _gfxModeList->mode[index].height; - mode.ColorDepth = _gfxModeList->mode[index].bpp; - return true; - } - return false; +bool ALSoftwareGfxModeList::GetMode(int index, DisplayMode &mode) const { + if (_gfxModeList && index >= 0 && index < _gfxModeList->num_modes) { + mode.Width = _gfxModeList->mode[index].width; + mode.Height = _gfxModeList->mode[index].height; + mode.ColorDepth = _gfxModeList->mode[index].bpp; + return true; + } + return false; } unsigned long _trans_alpha_blender32(unsigned long x, unsigned long y, unsigned long n); RGB faded_out_palette[256]; -ALSoftwareGraphicsDriver::ALSoftwareGraphicsDriver() -{ - _tint_red = 0; - _tint_green = 0; - _tint_blue = 0; - _autoVsync = false; - //_spareTintingScreen = nullptr; - _gfxModeList = nullptr; +ALSoftwareGraphicsDriver::ALSoftwareGraphicsDriver() { + _tint_red = 0; + _tint_green = 0; + _tint_blue = 0; + _autoVsync = false; + //_spareTintingScreen = nullptr; + _gfxModeList = nullptr; #if AGS_DDRAW_GAMMA_CONTROL - dxGammaControl = nullptr; + dxGammaControl = nullptr; #endif - _allegroScreenWrapper = nullptr; - _origVirtualScreen = nullptr; - virtualScreen = nullptr; - _stageVirtualScreen = nullptr; - - // Initialize default sprite batch, it will be used when no other batch was activated - ALSoftwareGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); -} - -bool ALSoftwareGraphicsDriver::IsModeSupported(const DisplayMode &mode) -{ - if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) - { - set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); - return false; - } + _allegroScreenWrapper = nullptr; + _origVirtualScreen = nullptr; + virtualScreen = nullptr; + _stageVirtualScreen = nullptr; + + // Initialize default sprite batch, it will be used when no other batch was activated + ALSoftwareGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); +} + +bool ALSoftwareGraphicsDriver::IsModeSupported(const DisplayMode &mode) { + if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) { + set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); + return false; + } #if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_MACOS - // Everything is drawn to a virtual screen, so all resolutions are supported. - return true; + // Everything is drawn to a virtual screen, so all resolutions are supported. + return true; #endif - if (mode.Windowed) - { - return true; - } - if (_gfxModeList == nullptr) - { - _gfxModeList = get_gfx_mode_list(GetAllegroGfxDriverID(mode.Windowed)); - } - if (_gfxModeList != nullptr) - { - // if a list is available, check if the mode exists. This prevents the screen flicking - // between loads of unsupported resolutions - for (int i = 0; i < _gfxModeList->num_modes; i++) - { - if ((_gfxModeList->mode[i].width == mode.Width) && - (_gfxModeList->mode[i].height == mode.Height) && - (_gfxModeList->mode[i].bpp == mode.ColorDepth)) - { - return true; - } - } - set_allegro_error("This graphics mode is not supported"); - return false; - } - return true; -} - -int ALSoftwareGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const -{ - // TODO: check for device caps to know which depth is supported? - if (native_color_depth > 8) - return 32; - return native_color_depth; -} - -IGfxModeList *ALSoftwareGraphicsDriver::GetSupportedModeList(int color_depth) -{ - if (_gfxModeList == nullptr) - { - _gfxModeList = get_gfx_mode_list(GetAllegroGfxDriverID(false)); - } - if (_gfxModeList == nullptr) - { - return nullptr; - } - return new ALSoftwareGfxModeList(_gfxModeList); -} - -PGfxFilter ALSoftwareGraphicsDriver::GetGraphicsFilter() const -{ - return _filter; -} - -int ALSoftwareGraphicsDriver::GetAllegroGfxDriverID(bool windowed) -{ + if (mode.Windowed) { + return true; + } + if (_gfxModeList == nullptr) { + _gfxModeList = get_gfx_mode_list(GetAllegroGfxDriverID(mode.Windowed)); + } + if (_gfxModeList != nullptr) { + // if a list is available, check if the mode exists. This prevents the screen flicking + // between loads of unsupported resolutions + for (int i = 0; i < _gfxModeList->num_modes; i++) { + if ((_gfxModeList->mode[i].width == mode.Width) && + (_gfxModeList->mode[i].height == mode.Height) && + (_gfxModeList->mode[i].bpp == mode.ColorDepth)) { + return true; + } + } + set_allegro_error("This graphics mode is not supported"); + return false; + } + return true; +} + +int ALSoftwareGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const { + // TODO: check for device caps to know which depth is supported? + if (native_color_depth > 8) + return 32; + return native_color_depth; +} + +IGfxModeList *ALSoftwareGraphicsDriver::GetSupportedModeList(int color_depth) { + if (_gfxModeList == nullptr) { + _gfxModeList = get_gfx_mode_list(GetAllegroGfxDriverID(false)); + } + if (_gfxModeList == nullptr) { + return nullptr; + } + return new ALSoftwareGfxModeList(_gfxModeList); +} + +PGfxFilter ALSoftwareGraphicsDriver::GetGraphicsFilter() const { + return _filter; +} + +int ALSoftwareGraphicsDriver::GetAllegroGfxDriverID(bool windowed) { #if AGS_PLATFORM_OS_WINDOWS - if (windowed) - return GFX_DIRECTX_WIN; - return GFX_DIRECTX; + if (windowed) + return GFX_DIRECTX_WIN; + return GFX_DIRECTX; #elif AGS_PLATFORM_OS_LINUX && (!defined (ALLEGRO_MAGIC_DRV)) - if (windowed) - return GFX_XWINDOWS; - return GFX_XWINDOWS_FULLSCREEN; + if (windowed) + return GFX_XWINDOWS; + return GFX_XWINDOWS_FULLSCREEN; #elif AGS_PLATFORM_OS_MACOS - if (windowed) { - return GFX_COCOAGL_WINDOW; - } - return GFX_COCOAGL_FULLSCREEN; + if (windowed) { + return GFX_COCOAGL_WINDOW; + } + return GFX_COCOAGL_FULLSCREEN; #else - if (windowed) - return GFX_AUTODETECT_WINDOWED; - return GFX_AUTODETECT_FULLSCREEN; + if (windowed) + return GFX_AUTODETECT_WINDOWED; + return GFX_AUTODETECT_FULLSCREEN; #endif } -void ALSoftwareGraphicsDriver::SetGraphicsFilter(PALSWFilter filter) -{ - _filter = filter; - OnSetFilter(); +void ALSoftwareGraphicsDriver::SetGraphicsFilter(PALSWFilter filter) { + _filter = filter; + OnSetFilter(); - // If we already have a gfx mode set, then use the new filter to update virtual screen immediately - CreateVirtualScreen(); + // If we already have a gfx mode set, then use the new filter to update virtual screen immediately + CreateVirtualScreen(); } -void ALSoftwareGraphicsDriver::SetTintMethod(TintMethod method) -{ - // TODO: support new D3D-style tint method +void ALSoftwareGraphicsDriver::SetTintMethod(TintMethod method) { + // TODO: support new D3D-style tint method } -bool ALSoftwareGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) -{ - ReleaseDisplayMode(); +bool ALSoftwareGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) { + ReleaseDisplayMode(); - const int driver = GetAllegroGfxDriverID(mode.Windowed); + const int driver = GetAllegroGfxDriverID(mode.Windowed); - set_color_depth(mode.ColorDepth); + set_color_depth(mode.ColorDepth); - if (_initGfxCallback != nullptr) - _initGfxCallback(nullptr); + if (_initGfxCallback != nullptr) + _initGfxCallback(nullptr); - if (!IsModeSupported(mode) || set_gfx_mode(driver, mode.Width, mode.Height, 0, 0) != 0) - return false; + if (!IsModeSupported(mode) || set_gfx_mode(driver, mode.Width, mode.Height, 0, 0) != 0) + return false; - OnInit(loopTimer); - OnModeSet(mode); - // set_gfx_mode is an allegro function that creates screen bitmap; - // following code assumes the screen is already created, therefore we should - // ensure global bitmap wraps over existing allegro screen bitmap. - _allegroScreenWrapper = BitmapHelper::CreateRawBitmapWrapper(screen); - _allegroScreenWrapper->Clear(); + OnInit(loopTimer); + OnModeSet(mode); + // set_gfx_mode is an allegro function that creates screen bitmap; + // following code assumes the screen is already created, therefore we should + // ensure global bitmap wraps over existing allegro screen bitmap. + _allegroScreenWrapper = BitmapHelper::CreateRawBitmapWrapper(screen); + _allegroScreenWrapper->Clear(); - // If we already have a gfx filter, then use it to update virtual screen immediately - CreateVirtualScreen(); + // If we already have a gfx filter, then use it to update virtual screen immediately + CreateVirtualScreen(); #if AGS_DDRAW_GAMMA_CONTROL - if (!mode.Windowed) - { - memset(&ddrawCaps, 0, sizeof(ddrawCaps)); - ddrawCaps.dwSize = sizeof(ddrawCaps); - IDirectDraw2_GetCaps(directdraw, &ddrawCaps, NULL); - - if ((ddrawCaps.dwCaps2 & DDCAPS2_PRIMARYGAMMA) == 0) { } - else if (IDirectDrawSurface2_QueryInterface(gfx_directx_primary_surface->id, IID_IDirectDrawGammaControl, (void **)&dxGammaControl) == 0) - { - dxGammaControl->GetGammaRamp(0, &defaultGammaRamp); - } - } + if (!mode.Windowed) { + memset(&ddrawCaps, 0, sizeof(ddrawCaps)); + ddrawCaps.dwSize = sizeof(ddrawCaps); + IDirectDraw2_GetCaps(directdraw, &ddrawCaps, NULL); + + if ((ddrawCaps.dwCaps2 & DDCAPS2_PRIMARYGAMMA) == 0) { } + else if (IDirectDrawSurface2_QueryInterface(gfx_directx_primary_surface->id, IID_IDirectDrawGammaControl, (void **)&dxGammaControl) == 0) { + dxGammaControl->GetGammaRamp(0, &defaultGammaRamp); + } + } #endif - return true; -} - -void ALSoftwareGraphicsDriver::CreateVirtualScreen() -{ - if (!IsModeSet() || !IsRenderFrameValid() || !IsNativeSizeValid() || !_filter) - return; - DestroyVirtualScreen(); - // Adjust clipping so nothing gets drawn outside the game frame - _allegroScreenWrapper->SetClip(_dstRect); - // Initialize scaling filter and receive virtual screen pointer - // (which may or not be the same as real screen) - _origVirtualScreen = _filter->InitVirtualScreen(_allegroScreenWrapper, _srcRect.GetSize(), _dstRect); - // Apparently we must still create a virtual screen even if its same size and color depth, - // because drawing sprites directly on real screen bitmap causes blinking (unless I missed something here...) - if (_origVirtualScreen == _allegroScreenWrapper) - { - _origVirtualScreen = BitmapHelper::CreateBitmap(_srcRect.GetWidth(), _srcRect.GetHeight(), _mode.ColorDepth); - } - virtualScreen = _origVirtualScreen; - _stageVirtualScreen = virtualScreen; - // Set Allegro's screen pointer to what may be the real or virtual screen - screen = (BITMAP*)_origVirtualScreen->GetAllegroBitmap(); -} - -void ALSoftwareGraphicsDriver::DestroyVirtualScreen() -{ - if (_filter && _origVirtualScreen) - { - screen = (BITMAP*)_filter->ShutdownAndReturnRealScreen()->GetAllegroBitmap(); - } - _origVirtualScreen = nullptr; - virtualScreen = nullptr; - _stageVirtualScreen = nullptr; -} - -void ALSoftwareGraphicsDriver::ReleaseDisplayMode() -{ - OnModeReleased(); - ClearDrawLists(); + return true; +} + +void ALSoftwareGraphicsDriver::CreateVirtualScreen() { + if (!IsModeSet() || !IsRenderFrameValid() || !IsNativeSizeValid() || !_filter) + return; + DestroyVirtualScreen(); + // Adjust clipping so nothing gets drawn outside the game frame + _allegroScreenWrapper->SetClip(_dstRect); + // Initialize scaling filter and receive virtual screen pointer + // (which may or not be the same as real screen) + _origVirtualScreen = _filter->InitVirtualScreen(_allegroScreenWrapper, _srcRect.GetSize(), _dstRect); + // Apparently we must still create a virtual screen even if its same size and color depth, + // because drawing sprites directly on real screen bitmap causes blinking (unless I missed something here...) + if (_origVirtualScreen == _allegroScreenWrapper) { + _origVirtualScreen = BitmapHelper::CreateBitmap(_srcRect.GetWidth(), _srcRect.GetHeight(), _mode.ColorDepth); + } + virtualScreen = _origVirtualScreen; + _stageVirtualScreen = virtualScreen; + // Set Allegro's screen pointer to what may be the real or virtual screen + screen = (BITMAP *)_origVirtualScreen->GetAllegroBitmap(); +} + +void ALSoftwareGraphicsDriver::DestroyVirtualScreen() { + if (_filter && _origVirtualScreen) { + screen = (BITMAP *)_filter->ShutdownAndReturnRealScreen()->GetAllegroBitmap(); + } + _origVirtualScreen = nullptr; + virtualScreen = nullptr; + _stageVirtualScreen = nullptr; +} + +void ALSoftwareGraphicsDriver::ReleaseDisplayMode() { + OnModeReleased(); + ClearDrawLists(); #if AGS_DDRAW_GAMMA_CONTROL - if (dxGammaControl != NULL) - { - dxGammaControl->Release(); - dxGammaControl = NULL; - } + if (dxGammaControl != NULL) { + dxGammaControl->Release(); + dxGammaControl = NULL; + } #endif - DestroyVirtualScreen(); + DestroyVirtualScreen(); - // Note this does not destroy the underlying allegro screen bitmap, only wrapper. - delete _allegroScreenWrapper; - _allegroScreenWrapper = nullptr; + // Note this does not destroy the underlying allegro screen bitmap, only wrapper. + delete _allegroScreenWrapper; + _allegroScreenWrapper = nullptr; } -bool ALSoftwareGraphicsDriver::SetNativeSize(const Size &src_size) -{ - OnSetNativeSize(src_size); - // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately - CreateVirtualScreen(); - return !_srcRect.IsEmpty(); +bool ALSoftwareGraphicsDriver::SetNativeSize(const Size &src_size) { + OnSetNativeSize(src_size); + // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately + CreateVirtualScreen(); + return !_srcRect.IsEmpty(); } -bool ALSoftwareGraphicsDriver::SetRenderFrame(const Rect &dst_rect) -{ - OnSetRenderFrame(dst_rect); - // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately - CreateVirtualScreen(); - return !_dstRect.IsEmpty(); +bool ALSoftwareGraphicsDriver::SetRenderFrame(const Rect &dst_rect) { + OnSetRenderFrame(dst_rect); + // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately + CreateVirtualScreen(); + return !_dstRect.IsEmpty(); } -void ALSoftwareGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) -{ - if (!_filter) return; - int color = 0; - if (colorToUse != nullptr) - color = makecol_depth(_mode.ColorDepth, colorToUse->r, colorToUse->g, colorToUse->b); - // NOTE: filter will do coordinate scaling for us - _filter->ClearRect(x1, y1, x2, y2, color); +void ALSoftwareGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) { + if (!_filter) return; + int color = 0; + if (colorToUse != nullptr) + color = makecol_depth(_mode.ColorDepth, colorToUse->r, colorToUse->g, colorToUse->b); + // NOTE: filter will do coordinate scaling for us + _filter->ClearRect(x1, y1, x2, y2, color); } -ALSoftwareGraphicsDriver::~ALSoftwareGraphicsDriver() -{ - ALSoftwareGraphicsDriver::UnInit(); +ALSoftwareGraphicsDriver::~ALSoftwareGraphicsDriver() { + ALSoftwareGraphicsDriver::UnInit(); } -void ALSoftwareGraphicsDriver::UnInit() -{ - OnUnInit(); - ReleaseDisplayMode(); +void ALSoftwareGraphicsDriver::UnInit() { + OnUnInit(); + ReleaseDisplayMode(); - if (_gfxModeList != nullptr) - { - destroy_gfx_mode_list(_gfxModeList); - _gfxModeList = nullptr; - } + if (_gfxModeList != nullptr) { + destroy_gfx_mode_list(_gfxModeList); + _gfxModeList = nullptr; + } } -bool ALSoftwareGraphicsDriver::SupportsGammaControl() -{ +bool ALSoftwareGraphicsDriver::SupportsGammaControl() { #if AGS_DDRAW_GAMMA_CONTROL - if (dxGammaControl != NULL) - { - return 1; - } + if (dxGammaControl != NULL) { + return 1; + } #endif - return 0; + return 0; } -void ALSoftwareGraphicsDriver::SetGamma(int newGamma) -{ +void ALSoftwareGraphicsDriver::SetGamma(int newGamma) { #if AGS_DDRAW_GAMMA_CONTROL - for (int i = 0; i < 256; i++) { - int newValue = ((int)defaultGammaRamp.red[i] * newGamma) / 100; - if (newValue >= 65535) - newValue = 65535; - gammaRamp.red[i] = newValue; - gammaRamp.green[i] = newValue; - gammaRamp.blue[i] = newValue; - } - - dxGammaControl->SetGammaRamp(0, &gammaRamp); + for (int i = 0; i < 256; i++) { + int newValue = ((int)defaultGammaRamp.red[i] * newGamma) / 100; + if (newValue >= 65535) + newValue = 65535; + gammaRamp.red[i] = newValue; + gammaRamp.green[i] = newValue; + gammaRamp.blue[i] = newValue; + } + + dxGammaControl->SetGammaRamp(0, &gammaRamp); #endif } -int ALSoftwareGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) -{ - return color_depth; -} - -IDriverDependantBitmap* ALSoftwareGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) -{ - ALSoftwareBitmap* newBitmap = new ALSoftwareBitmap(bitmap, opaque, hasAlpha); - return newBitmap; -} - -void ALSoftwareGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) -{ - ALSoftwareBitmap* alSwBmp = (ALSoftwareBitmap*)bitmapToUpdate; - alSwBmp->_bmp = bitmap; - alSwBmp->_hasAlpha = hasAlpha; -} - -void ALSoftwareGraphicsDriver::DestroyDDB(IDriverDependantBitmap* bitmap) -{ - delete bitmap; -} - -void ALSoftwareGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) -{ - if (_spriteBatches.size() <= index) - _spriteBatches.resize(index + 1); - ALSpriteBatch &batch = _spriteBatches[index]; - batch.List.clear(); - // TODO: correct offsets to have pre-scale (source) and post-scale (dest) offsets! - const int src_w = desc.Viewport.GetWidth() / desc.Transform.ScaleX; - const int src_h = desc.Viewport.GetHeight() / desc.Transform.ScaleY; - // Surface was prepared externally (common for room cameras) - if (desc.Surface != nullptr) - { - batch.Surface = std::static_pointer_cast(desc.Surface); - batch.Opaque = true; - batch.IsVirtualScreen = false; - } - // In case something was not initialized - else if (desc.Viewport.IsEmpty() || !virtualScreen) - { - batch.Surface.reset(); - batch.Opaque = false; - batch.IsVirtualScreen = false; - } - // Drawing directly on a viewport without transformation (other than offset) - else if (desc.Transform.ScaleX == 1.f && desc.Transform.ScaleY == 1.f) - { - if (!batch.Surface || !batch.IsVirtualScreen || batch.Surface->GetWidth() != src_w || batch.Surface->GetHeight() != src_h) - { - Rect rc = RectWH(desc.Viewport.Left, desc.Viewport.Top, desc.Viewport.GetWidth(), desc.Viewport.GetHeight()); - batch.Surface.reset(BitmapHelper::CreateSubBitmap(virtualScreen, rc)); - } - batch.Opaque = true; - batch.IsVirtualScreen = true; - } - // No surface prepared and has transformation other than offset - else if (!batch.Surface || batch.IsVirtualScreen || batch.Surface->GetWidth() != src_w || batch.Surface->GetHeight() != src_h) - { - batch.Surface.reset(new Bitmap(src_w, src_h)); - batch.Opaque = false; - batch.IsVirtualScreen = false; - } -} - -void ALSoftwareGraphicsDriver::ResetAllBatches() -{ - for (ALSpriteBatches::iterator it = _spriteBatches.begin(); it != _spriteBatches.end(); ++it) - it->List.clear(); -} - -void ALSoftwareGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) -{ - _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap*)bitmap, x, y)); -} - -void ALSoftwareGraphicsDriver::SetScreenFade(int red, int green, int blue) -{ - // TODO: was not necessary atm -} - -void ALSoftwareGraphicsDriver::SetScreenTint(int red, int green, int blue) -{ - _tint_red = red; _tint_green = green; _tint_blue = blue; - if (((_tint_red > 0) || (_tint_green > 0) || (_tint_blue > 0)) && (_mode.ColorDepth > 8)) - { - _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap*)0x1, 0, 0)); - } -} - -void ALSoftwareGraphicsDriver::RenderToBackBuffer() -{ - // Render all the sprite batches with necessary transformations - // - // NOTE: that's not immediately clear whether it would be faster to first draw upon a camera-sized - // surface then stretch final result to the viewport on screen, or stretch-blit each individual - // sprite right onto screen bitmap. We'd need to do proper profiling to know that. - // An important thing is that Allegro does not provide stretching functions for drawing sprites - // with blending and translucency; it seems you'd have to first stretch the original sprite onto a - // temp buffer and then TransBlendBlt / LitBlendBlt it to the final destination. Of course, doing - // that here would slow things down significantly, so if we ever go that way sprite caching will - // be required (similarily to how AGS caches flipped/scaled object sprites now for). - // - for (size_t i = 0; i <= _actSpriteBatch; ++i) - { - const Rect &viewport = _spriteBatchDesc[i].Viewport; - const SpriteTransform &transform = _spriteBatchDesc[i].Transform; - const ALSpriteBatch &batch = _spriteBatches[i]; - - virtualScreen->SetClip(viewport); - Bitmap *surface = batch.Surface.get(); - const int view_offx = viewport.Left; - const int view_offy = viewport.Top; - if (surface) - { - if (!batch.Opaque) - surface->ClearTransparent(); - _stageVirtualScreen = surface; - RenderSpriteBatch(batch, surface, transform.X, transform.Y); - if (!batch.IsVirtualScreen) - virtualScreen->StretchBlt(surface, RectWH(view_offx, view_offy, viewport.GetWidth(), viewport.GetHeight()), - batch.Opaque ? kBitmap_Copy : kBitmap_Transparency); - } - else - { - RenderSpriteBatch(batch, virtualScreen, view_offx + transform.X, view_offy + transform.Y); - } - _stageVirtualScreen = virtualScreen; - } - ClearDrawLists(); -} - -void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy) -{ - const std::vector &drawlist = batch.List; - for (size_t i = 0; i < drawlist.size(); i++) - { - if (drawlist[i].bitmap == nullptr) - { - if (_nullSpriteCallback) - _nullSpriteCallback(drawlist[i].x, drawlist[i].y); - else - throw Ali3DException("Unhandled attempt to draw null sprite"); - - continue; - } - else if (drawlist[i].bitmap == (ALSoftwareBitmap*)0x1) - { - // draw screen tint fx - set_trans_blender(_tint_red, _tint_green, _tint_blue, 0); - surface->LitBlendBlt(surface, 0, 0, 128); - continue; - } - - ALSoftwareBitmap* bitmap = drawlist[i].bitmap; - int drawAtX = drawlist[i].x + surf_offx; - int drawAtY = drawlist[i].y + surf_offy; - - if (bitmap->_transparency >= 255) {} // fully transparent, do nothing - else if ((bitmap->_opaque) && (bitmap->_bmp == surface) && (bitmap->_transparency == 0)) {} - else if (bitmap->_opaque) - { - surface->Blit(bitmap->_bmp, 0, 0, drawAtX, drawAtY, bitmap->_bmp->GetWidth(), bitmap->_bmp->GetHeight()); - // TODO: we need to also support non-masked translucent blend, but... - // Allegro 4 **does not have such function ready** :( (only masked blends, where it skips magenta pixels); - // I am leaving this problem for the future, as coincidentally software mode does not need this atm. - } - else if (bitmap->_hasAlpha) - { - if (bitmap->_transparency == 0) // no global transparency, simple alpha blend - set_alpha_blender(); - else - // here _transparency is used as alpha (between 1 and 254) - set_blender_mode(nullptr, nullptr, _trans_alpha_blender32, 0, 0, 0, bitmap->_transparency); - - surface->TransBlendBlt(bitmap->_bmp, drawAtX, drawAtY); - } - else - { - // here _transparency is used as alpha (between 1 and 254), but 0 means opaque! - GfxUtil::DrawSpriteWithTransparency(surface, bitmap->_bmp, drawAtX, drawAtY, - bitmap->_transparency ? bitmap->_transparency : 255); - } - } - // NOTE: following is experimental tint code (currently unused) -/* This alternate method gives the correct (D3D-style) result, but is just too slow! - if ((_spareTintingScreen != NULL) && - ((_spareTintingScreen->GetWidth() != surface->GetWidth()) || (_spareTintingScreen->GetHeight() != surface->GetHeight()))) - { - destroy_bitmap(_spareTintingScreen); - _spareTintingScreen = NULL; - } - if (_spareTintingScreen == NULL) - { - _spareTintingScreen = BitmapHelper::CreateBitmap_(GetColorDepth(surface), surface->GetWidth(), surface->GetHeight()); - } - tint_image(surface, _spareTintingScreen, _tint_red, _tint_green, _tint_blue, 100, 255); - Blit(_spareTintingScreen, surface, 0, 0, 0, 0, _spareTintingScreen->GetWidth(), _spareTintingScreen->GetHeight());*/ -} - -void ALSoftwareGraphicsDriver::Render(int xoff, int yoff, GlobalFlipType flip) -{ - RenderToBackBuffer(); - - if (_autoVsync) - this->Vsync(); - - if (flip == kFlip_None) - _filter->RenderScreen(virtualScreen, xoff, yoff); - else - _filter->RenderScreenFlipped(virtualScreen, xoff, yoff, flip); -} - -void ALSoftwareGraphicsDriver::Render() -{ - Render(0, 0, kFlip_None); -} - -void ALSoftwareGraphicsDriver::Vsync() -{ - vsync(); -} - -Bitmap *ALSoftwareGraphicsDriver::GetMemoryBackBuffer() -{ - return virtualScreen; -} - -void ALSoftwareGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) -{ - if (backBuffer) - { - virtualScreen = backBuffer; - } - else - { - virtualScreen = _origVirtualScreen; - } - _stageVirtualScreen = virtualScreen; - - // Reset old virtual screen's subbitmaps - for (auto &batch : _spriteBatches) - { - if (batch.IsVirtualScreen) - batch.Surface.reset(); - } -} - -Bitmap *ALSoftwareGraphicsDriver::GetStageBackBuffer() -{ - return _stageVirtualScreen; -} - -bool ALSoftwareGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) -{ - (void)at_native_res; // software driver always renders at native resolution at the moment - // software filter is taught to copy to any size - if (destination->GetColorDepth() != _mode.ColorDepth) - { - if (want_fmt) - *want_fmt = GraphicResolution(destination->GetWidth(), destination->GetHeight(), _mode.ColorDepth); - return false; - } - _filter->GetCopyOfScreenIntoBitmap(destination); - return true; +int ALSoftwareGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) { + return color_depth; +} + +IDriverDependantBitmap *ALSoftwareGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) { + ALSoftwareBitmap *newBitmap = new ALSoftwareBitmap(bitmap, opaque, hasAlpha); + return newBitmap; +} + +void ALSoftwareGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { + ALSoftwareBitmap *alSwBmp = (ALSoftwareBitmap *)bitmapToUpdate; + alSwBmp->_bmp = bitmap; + alSwBmp->_hasAlpha = hasAlpha; +} + +void ALSoftwareGraphicsDriver::DestroyDDB(IDriverDependantBitmap *bitmap) { + delete bitmap; +} + +void ALSoftwareGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) { + if (_spriteBatches.size() <= index) + _spriteBatches.resize(index + 1); + ALSpriteBatch &batch = _spriteBatches[index]; + batch.List.clear(); + // TODO: correct offsets to have pre-scale (source) and post-scale (dest) offsets! + const int src_w = desc.Viewport.GetWidth() / desc.Transform.ScaleX; + const int src_h = desc.Viewport.GetHeight() / desc.Transform.ScaleY; + // Surface was prepared externally (common for room cameras) + if (desc.Surface != nullptr) { + batch.Surface = std::static_pointer_cast(desc.Surface); + batch.Opaque = true; + batch.IsVirtualScreen = false; + } + // In case something was not initialized + else if (desc.Viewport.IsEmpty() || !virtualScreen) { + batch.Surface.reset(); + batch.Opaque = false; + batch.IsVirtualScreen = false; + } + // Drawing directly on a viewport without transformation (other than offset) + else if (desc.Transform.ScaleX == 1.f && desc.Transform.ScaleY == 1.f) { + if (!batch.Surface || !batch.IsVirtualScreen || batch.Surface->GetWidth() != src_w || batch.Surface->GetHeight() != src_h) { + Rect rc = RectWH(desc.Viewport.Left, desc.Viewport.Top, desc.Viewport.GetWidth(), desc.Viewport.GetHeight()); + batch.Surface.reset(BitmapHelper::CreateSubBitmap(virtualScreen, rc)); + } + batch.Opaque = true; + batch.IsVirtualScreen = true; + } + // No surface prepared and has transformation other than offset + else if (!batch.Surface || batch.IsVirtualScreen || batch.Surface->GetWidth() != src_w || batch.Surface->GetHeight() != src_h) { + batch.Surface.reset(new Bitmap(src_w, src_h)); + batch.Opaque = false; + batch.IsVirtualScreen = false; + } +} + +void ALSoftwareGraphicsDriver::ResetAllBatches() { + for (ALSpriteBatches::iterator it = _spriteBatches.begin(); it != _spriteBatches.end(); ++it) + it->List.clear(); +} + +void ALSoftwareGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) { + _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap *)bitmap, x, y)); +} + +void ALSoftwareGraphicsDriver::SetScreenFade(int red, int green, int blue) { + // TODO: was not necessary atm +} + +void ALSoftwareGraphicsDriver::SetScreenTint(int red, int green, int blue) { + _tint_red = red; + _tint_green = green; + _tint_blue = blue; + if (((_tint_red > 0) || (_tint_green > 0) || (_tint_blue > 0)) && (_mode.ColorDepth > 8)) { + _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap *)0x1, 0, 0)); + } +} + +void ALSoftwareGraphicsDriver::RenderToBackBuffer() { + // Render all the sprite batches with necessary transformations + // + // NOTE: that's not immediately clear whether it would be faster to first draw upon a camera-sized + // surface then stretch final result to the viewport on screen, or stretch-blit each individual + // sprite right onto screen bitmap. We'd need to do proper profiling to know that. + // An important thing is that Allegro does not provide stretching functions for drawing sprites + // with blending and translucency; it seems you'd have to first stretch the original sprite onto a + // temp buffer and then TransBlendBlt / LitBlendBlt it to the final destination. Of course, doing + // that here would slow things down significantly, so if we ever go that way sprite caching will + // be required (similarily to how AGS caches flipped/scaled object sprites now for). + // + for (size_t i = 0; i <= _actSpriteBatch; ++i) { + const Rect &viewport = _spriteBatchDesc[i].Viewport; + const SpriteTransform &transform = _spriteBatchDesc[i].Transform; + const ALSpriteBatch &batch = _spriteBatches[i]; + + virtualScreen->SetClip(viewport); + Bitmap *surface = batch.Surface.get(); + const int view_offx = viewport.Left; + const int view_offy = viewport.Top; + if (surface) { + if (!batch.Opaque) + surface->ClearTransparent(); + _stageVirtualScreen = surface; + RenderSpriteBatch(batch, surface, transform.X, transform.Y); + if (!batch.IsVirtualScreen) + virtualScreen->StretchBlt(surface, RectWH(view_offx, view_offy, viewport.GetWidth(), viewport.GetHeight()), + batch.Opaque ? kBitmap_Copy : kBitmap_Transparency); + } else { + RenderSpriteBatch(batch, virtualScreen, view_offx + transform.X, view_offy + transform.Y); + } + _stageVirtualScreen = virtualScreen; + } + ClearDrawLists(); +} + +void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy) { + const std::vector &drawlist = batch.List; + for (size_t i = 0; i < drawlist.size(); i++) { + if (drawlist[i].bitmap == nullptr) { + if (_nullSpriteCallback) + _nullSpriteCallback(drawlist[i].x, drawlist[i].y); + else + throw Ali3DException("Unhandled attempt to draw null sprite"); + + continue; + } else if (drawlist[i].bitmap == (ALSoftwareBitmap *)0x1) { + // draw screen tint fx + set_trans_blender(_tint_red, _tint_green, _tint_blue, 0); + surface->LitBlendBlt(surface, 0, 0, 128); + continue; + } + + ALSoftwareBitmap *bitmap = drawlist[i].bitmap; + int drawAtX = drawlist[i].x + surf_offx; + int drawAtY = drawlist[i].y + surf_offy; + + if (bitmap->_transparency >= 255) {} // fully transparent, do nothing + else if ((bitmap->_opaque) && (bitmap->_bmp == surface) && (bitmap->_transparency == 0)) {} + else if (bitmap->_opaque) { + surface->Blit(bitmap->_bmp, 0, 0, drawAtX, drawAtY, bitmap->_bmp->GetWidth(), bitmap->_bmp->GetHeight()); + // TODO: we need to also support non-masked translucent blend, but... + // Allegro 4 **does not have such function ready** :( (only masked blends, where it skips magenta pixels); + // I am leaving this problem for the future, as coincidentally software mode does not need this atm. + } else if (bitmap->_hasAlpha) { + if (bitmap->_transparency == 0) // no global transparency, simple alpha blend + set_alpha_blender(); + else + // here _transparency is used as alpha (between 1 and 254) + set_blender_mode(nullptr, nullptr, _trans_alpha_blender32, 0, 0, 0, bitmap->_transparency); + + surface->TransBlendBlt(bitmap->_bmp, drawAtX, drawAtY); + } else { + // here _transparency is used as alpha (between 1 and 254), but 0 means opaque! + GfxUtil::DrawSpriteWithTransparency(surface, bitmap->_bmp, drawAtX, drawAtY, + bitmap->_transparency ? bitmap->_transparency : 255); + } + } + // NOTE: following is experimental tint code (currently unused) + /* This alternate method gives the correct (D3D-style) result, but is just too slow! + if ((_spareTintingScreen != NULL) && + ((_spareTintingScreen->GetWidth() != surface->GetWidth()) || (_spareTintingScreen->GetHeight() != surface->GetHeight()))) + { + destroy_bitmap(_spareTintingScreen); + _spareTintingScreen = NULL; + } + if (_spareTintingScreen == NULL) + { + _spareTintingScreen = BitmapHelper::CreateBitmap_(GetColorDepth(surface), surface->GetWidth(), surface->GetHeight()); + } + tint_image(surface, _spareTintingScreen, _tint_red, _tint_green, _tint_blue, 100, 255); + Blit(_spareTintingScreen, surface, 0, 0, 0, 0, _spareTintingScreen->GetWidth(), _spareTintingScreen->GetHeight());*/ +} + +void ALSoftwareGraphicsDriver::Render(int xoff, int yoff, GlobalFlipType flip) { + RenderToBackBuffer(); + + if (_autoVsync) + this->Vsync(); + + if (flip == kFlip_None) + _filter->RenderScreen(virtualScreen, xoff, yoff); + else + _filter->RenderScreenFlipped(virtualScreen, xoff, yoff, flip); +} + +void ALSoftwareGraphicsDriver::Render() { + Render(0, 0, kFlip_None); +} + +void ALSoftwareGraphicsDriver::Vsync() { + vsync(); +} + +Bitmap *ALSoftwareGraphicsDriver::GetMemoryBackBuffer() { + return virtualScreen; +} + +void ALSoftwareGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) { + if (backBuffer) { + virtualScreen = backBuffer; + } else { + virtualScreen = _origVirtualScreen; + } + _stageVirtualScreen = virtualScreen; + + // Reset old virtual screen's subbitmaps + for (auto &batch : _spriteBatches) { + if (batch.IsVirtualScreen) + batch.Surface.reset(); + } +} + +Bitmap *ALSoftwareGraphicsDriver::GetStageBackBuffer() { + return _stageVirtualScreen; +} + +bool ALSoftwareGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) { + (void)at_native_res; // software driver always renders at native resolution at the moment + // software filter is taught to copy to any size + if (destination->GetColorDepth() != _mode.ColorDepth) { + if (want_fmt) + *want_fmt = GraphicResolution(destination->GetWidth(), destination->GetHeight(), _mode.ColorDepth); + return false; + } + _filter->GetCopyOfScreenIntoBitmap(destination); + return true; } /** - fade.c - High Color Fading Routines + fade.c - High Color Fading Routines - Last Revision: 21 June, 2002 + Last Revision: 21 June, 2002 - Author: Matthew Leverton + Author: Matthew Leverton **/ -void ALSoftwareGraphicsDriver::highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - Bitmap *bmp_orig = vs; - const int col_depth = bmp_orig->GetColorDepth(); - const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); - if (speed <= 0) speed = 16; - - Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), col_depth); - SetMemoryBackBuffer(bmp_buff); - for (int a = 0; a < 256; a+=speed) - { - bmp_buff->Fill(clearColor); - set_trans_blender(0,0,0,a); - bmp_buff->TransBlendBlt(bmp_orig, 0, 0); - if (draw_callback) - { - draw_callback(); - RenderToBackBuffer(); - } - this->Vsync(); - _filter->RenderScreen(bmp_buff, offx, offy); - if (_pollingCallback) - _pollingCallback(); - WaitForNextFrame(); - } - delete bmp_buff; - - SetMemoryBackBuffer(vs); - if (draw_callback) - { - draw_callback(); - RenderToBackBuffer(); - } - _filter->RenderScreen(vs, offx, offy); -} - -void ALSoftwareGraphicsDriver::highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - Bitmap *bmp_orig = vs; - const int col_depth = vs->GetColorDepth(); - const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); - if (speed <= 0) speed = 16; - - Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), col_depth); - SetMemoryBackBuffer(bmp_buff); - for (int a = 255 - speed; a > 0; a -= speed) - { - bmp_buff->Fill(clearColor); - set_trans_blender(0, 0, 0, a); - bmp_buff->TransBlendBlt(bmp_orig, 0, 0); - if (draw_callback) - { - draw_callback(); - RenderToBackBuffer(); - } - this->Vsync(); - _filter->RenderScreen(bmp_buff, offx, offy); - if (_pollingCallback) - _pollingCallback(); - WaitForNextFrame(); - } - delete bmp_buff; - - SetMemoryBackBuffer(vs); - vs->Clear(clearColor); - if (draw_callback) - { - draw_callback(); - RenderToBackBuffer(); - } +void ALSoftwareGraphicsDriver::highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { + Bitmap *bmp_orig = vs; + const int col_depth = bmp_orig->GetColorDepth(); + const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); + if (speed <= 0) speed = 16; + + Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), col_depth); + SetMemoryBackBuffer(bmp_buff); + for (int a = 0; a < 256; a += speed) { + bmp_buff->Fill(clearColor); + set_trans_blender(0, 0, 0, a); + bmp_buff->TransBlendBlt(bmp_orig, 0, 0); + if (draw_callback) { + draw_callback(); + RenderToBackBuffer(); + } + this->Vsync(); + _filter->RenderScreen(bmp_buff, offx, offy); + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + delete bmp_buff; + + SetMemoryBackBuffer(vs); + if (draw_callback) { + draw_callback(); + RenderToBackBuffer(); + } + _filter->RenderScreen(vs, offx, offy); +} + +void ALSoftwareGraphicsDriver::highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { + Bitmap *bmp_orig = vs; + const int col_depth = vs->GetColorDepth(); + const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); + if (speed <= 0) speed = 16; + + Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), col_depth); + SetMemoryBackBuffer(bmp_buff); + for (int a = 255 - speed; a > 0; a -= speed) { + bmp_buff->Fill(clearColor); + set_trans_blender(0, 0, 0, a); + bmp_buff->TransBlendBlt(bmp_orig, 0, 0); + if (draw_callback) { + draw_callback(); + RenderToBackBuffer(); + } + this->Vsync(); + _filter->RenderScreen(bmp_buff, offx, offy); + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + delete bmp_buff; + + SetMemoryBackBuffer(vs); + vs->Clear(clearColor); + if (draw_callback) { + draw_callback(); + RenderToBackBuffer(); + } _filter->RenderScreen(vs, offx, offy); } /** END FADE.C **/ @@ -723,197 +636,173 @@ void ALSoftwareGraphicsDriver::highcolor_fade_out(Bitmap *vs, void(*draw_callbac // palette fading routiens // from allegro, modified for mp3 void initialize_fade_256(int r, int g, int b) { - int a; - for (a = 0; a < 256; a++) { - faded_out_palette[a].r = r / 4; - faded_out_palette[a].g = g / 4; - faded_out_palette[a].b = b / 4; - } + int a; + for (a = 0; a < 256; a++) { + faded_out_palette[a].r = r / 4; + faded_out_palette[a].g = g / 4; + faded_out_palette[a].b = b / 4; + } } -void ALSoftwareGraphicsDriver::__fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) -{ - PALETTE temp; - int c; +void ALSoftwareGraphicsDriver::__fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) { + PALETTE temp; + int c; - for (c=0; c 8) - { - highcolor_fade_out(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue); - } - else - { - __fade_out_range(speed, 0, 255, targetColourRed, targetColourGreen, targetColourBlue); - } + if (_mode.ColorDepth > 8) { + highcolor_fade_out(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue); + } else { + __fade_out_range(speed, 0, 255, targetColourRed, targetColourGreen, targetColourBlue); + } } void ALSoftwareGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) { - if (_drawScreenCallback) - { - _drawScreenCallback(); - RenderToBackBuffer(); - } - if (_mode.ColorDepth > 8) - { - highcolor_fade_in(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue); - } - else - { - initialize_fade_256(targetColourRed, targetColourGreen, targetColourBlue); - __fade_from_range(faded_out_palette, p, speed, 0,255); - } -} - -void ALSoftwareGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) -{ - if (blackingOut) - { - int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); - int boxwid = speed, boxhit = yspeed; - Bitmap *bmp_orig = virtualScreen; - Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), bmp_orig->GetColorDepth()); - SetMemoryBackBuffer(bmp_buff); - - while (boxwid < _srcRect.GetWidth()) { - boxwid += speed; - boxhit += yspeed; - int vcentre = _srcRect.GetHeight() / 2; - bmp_orig->FillRect(Rect(_srcRect.GetWidth() / 2 - boxwid / 2, vcentre - boxhit / 2, - _srcRect.GetWidth() / 2 + boxwid / 2, vcentre + boxhit / 2), 0); - bmp_buff->Fill(0); - bmp_buff->Blit(bmp_orig); - if (_drawPostScreenCallback) - { - _drawPostScreenCallback(); - RenderToBackBuffer(); - } - this->Vsync(); - _filter->RenderScreen(bmp_buff, 0, 0); - - if (_pollingCallback) - _pollingCallback(); - - platform->Delay(delay); - } - delete bmp_buff; - SetMemoryBackBuffer(bmp_orig); - } - else - { - throw Ali3DException("BoxOut fade-in not implemented in sw gfx driver"); - } + if (_drawScreenCallback) { + _drawScreenCallback(); + RenderToBackBuffer(); + } + if (_mode.ColorDepth > 8) { + highcolor_fade_in(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue); + } else { + initialize_fade_256(targetColourRed, targetColourGreen, targetColourBlue); + __fade_from_range(faded_out_palette, p, speed, 0, 255); + } +} + +void ALSoftwareGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) { + if (blackingOut) { + int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); + int boxwid = speed, boxhit = yspeed; + Bitmap *bmp_orig = virtualScreen; + Bitmap *bmp_buff = new Bitmap(bmp_orig->GetWidth(), bmp_orig->GetHeight(), bmp_orig->GetColorDepth()); + SetMemoryBackBuffer(bmp_buff); + + while (boxwid < _srcRect.GetWidth()) { + boxwid += speed; + boxhit += yspeed; + int vcentre = _srcRect.GetHeight() / 2; + bmp_orig->FillRect(Rect(_srcRect.GetWidth() / 2 - boxwid / 2, vcentre - boxhit / 2, + _srcRect.GetWidth() / 2 + boxwid / 2, vcentre + boxhit / 2), 0); + bmp_buff->Fill(0); + bmp_buff->Blit(bmp_orig); + if (_drawPostScreenCallback) { + _drawPostScreenCallback(); + RenderToBackBuffer(); + } + this->Vsync(); + _filter->RenderScreen(bmp_buff, 0, 0); + + if (_pollingCallback) + _pollingCallback(); + + platform->Delay(delay); + } + delete bmp_buff; + SetMemoryBackBuffer(bmp_orig); + } else { + throw Ali3DException("BoxOut fade-in not implemented in sw gfx driver"); + } } // end fading routines #ifndef AGS_NO_VIDEO_PLAYER -bool ALSoftwareGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) -{ +bool ALSoftwareGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) { #if AGS_PLATFORM_OS_WINDOWS - int result = dxmedia_play_video(filename, useAVISound, skipType, stretchToFullScreen ? 1 : 0); - return (result == 0); + int result = dxmedia_play_video(filename, useAVISound, skipType, stretchToFullScreen ? 1 : 0); + return (result == 0); #else - return 0; + return 0; #endif } #endif // add the alpha values together, used for compositing alpha images -unsigned long _trans_alpha_blender32(unsigned long x, unsigned long y, unsigned long n) -{ - unsigned long res, g; +unsigned long _trans_alpha_blender32(unsigned long x, unsigned long y, unsigned long n) { + unsigned long res, g; - n = (n * geta32(x)) / 256; + n = (n * geta32(x)) / 256; - if (n) - n++; + if (n) + n++; - res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y; - y &= 0xFF00; - x &= 0xFF00; - g = (x - y) * n / 256 + y; + res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y; + y &= 0xFF00; + x &= 0xFF00; + g = (x - y) * n / 256 + y; - res &= 0xFF00FF; - g &= 0xFF00; + res &= 0xFF00FF; + g &= 0xFF00; - return res | g; + return res | g; } ALSWGraphicsFactory *ALSWGraphicsFactory::_factory = nullptr; -ALSWGraphicsFactory::~ALSWGraphicsFactory() -{ - _factory = nullptr; +ALSWGraphicsFactory::~ALSWGraphicsFactory() { + _factory = nullptr; } -size_t ALSWGraphicsFactory::GetFilterCount() const -{ - return 2; +size_t ALSWGraphicsFactory::GetFilterCount() const { + return 2; } -const GfxFilterInfo *ALSWGraphicsFactory::GetFilterInfo(size_t index) const -{ - switch (index) - { - case 0: - return &AllegroGfxFilter::FilterInfo; - case 1: - return &HqxGfxFilter::FilterInfo; - default: - return nullptr; - } +const GfxFilterInfo *ALSWGraphicsFactory::GetFilterInfo(size_t index) const { + switch (index) { + case 0: + return &AllegroGfxFilter::FilterInfo; + case 1: + return &HqxGfxFilter::FilterInfo; + default: + return nullptr; + } } -String ALSWGraphicsFactory::GetDefaultFilterID() const -{ - return AllegroGfxFilter::FilterInfo.Id; +String ALSWGraphicsFactory::GetDefaultFilterID() const { + return AllegroGfxFilter::FilterInfo.Id; } -/* static */ ALSWGraphicsFactory *ALSWGraphicsFactory::GetFactory() -{ - if (!_factory) - _factory = new ALSWGraphicsFactory(); - return _factory; +/* static */ ALSWGraphicsFactory *ALSWGraphicsFactory::GetFactory() { + if (!_factory) + _factory = new ALSWGraphicsFactory(); + return _factory; } -ALSoftwareGraphicsDriver *ALSWGraphicsFactory::EnsureDriverCreated() -{ - if (!_driver) - _driver = new ALSoftwareGraphicsDriver(); - return _driver; +ALSoftwareGraphicsDriver *ALSWGraphicsFactory::EnsureDriverCreated() { + if (!_driver) + _driver = new ALSoftwareGraphicsDriver(); + return _driver; } -AllegroGfxFilter *ALSWGraphicsFactory::CreateFilter(const String &id) -{ - if (AllegroGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new AllegroGfxFilter(); - else if (HqxGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new HqxGfxFilter(); - return nullptr; +AllegroGfxFilter *ALSWGraphicsFactory::CreateFilter(const String &id) { + if (AllegroGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new AllegroGfxFilter(); + else if (HqxGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new HqxGfxFilter(); + return nullptr; } } // namespace ALSW diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index d59ae5e0e579..e1d677934069 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -46,231 +46,243 @@ #include "gfx/gfxdriverfactorybase.h" #include "gfx/gfxdriverbase.h" -namespace AGS -{ -namespace Engine -{ -namespace ALSW -{ +namespace AGS { +namespace Engine { +namespace ALSW { class AllegroGfxFilter; using AGS::Common::Bitmap; -class ALSoftwareBitmap : public IDriverDependantBitmap -{ +class ALSoftwareBitmap : public IDriverDependantBitmap { public: - // NOTE by CJ: - // Transparency is a bit counter-intuitive - // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible - void SetTransparency(int transparency) override { _transparency = transparency; } - void SetFlippedLeftRight(bool isFlipped) override { _flipped = isFlipped; } - void SetStretch(int width, int height, bool useResampler = true) override - { - _stretchToWidth = width; - _stretchToHeight = height; - } - int GetWidth() override { return _width; } - int GetHeight() override { return _height; } - int GetColorDepth() override { return _colDepth; } - void SetLightLevel(int lightLevel) override { } - void SetTint(int red, int green, int blue, int tintSaturation) override { } - - Bitmap *_bmp; - int _width, _height; - int _colDepth; - bool _flipped; - int _stretchToWidth, _stretchToHeight; - bool _opaque; // no mask color - bool _hasAlpha; - int _transparency; - - ALSoftwareBitmap(Bitmap *bmp, bool opaque, bool hasAlpha) - { - _bmp = bmp; - _width = bmp->GetWidth(); - _height = bmp->GetHeight(); - _colDepth = bmp->GetColorDepth(); - _flipped = false; - _stretchToWidth = 0; - _stretchToHeight = 0; - _transparency = 0; - _opaque = opaque; - _hasAlpha = hasAlpha; - } - - int GetWidthToRender() { return (_stretchToWidth > 0) ? _stretchToWidth : _width; } - int GetHeightToRender() { return (_stretchToHeight > 0) ? _stretchToHeight : _height; } - - void Dispose() - { - // do we want to free the bitmap? - } - - ~ALSoftwareBitmap() override - { - Dispose(); - } + // NOTE by CJ: + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + void SetTransparency(int transparency) override { + _transparency = transparency; + } + void SetFlippedLeftRight(bool isFlipped) override { + _flipped = isFlipped; + } + void SetStretch(int width, int height, bool useResampler = true) override { + _stretchToWidth = width; + _stretchToHeight = height; + } + int GetWidth() override { + return _width; + } + int GetHeight() override { + return _height; + } + int GetColorDepth() override { + return _colDepth; + } + void SetLightLevel(int lightLevel) override { } + void SetTint(int red, int green, int blue, int tintSaturation) override { } + + Bitmap *_bmp; + int _width, _height; + int _colDepth; + bool _flipped; + int _stretchToWidth, _stretchToHeight; + bool _opaque; // no mask color + bool _hasAlpha; + int _transparency; + + ALSoftwareBitmap(Bitmap *bmp, bool opaque, bool hasAlpha) { + _bmp = bmp; + _width = bmp->GetWidth(); + _height = bmp->GetHeight(); + _colDepth = bmp->GetColorDepth(); + _flipped = false; + _stretchToWidth = 0; + _stretchToHeight = 0; + _transparency = 0; + _opaque = opaque; + _hasAlpha = hasAlpha; + } + + int GetWidthToRender() { + return (_stretchToWidth > 0) ? _stretchToWidth : _width; + } + int GetHeightToRender() { + return (_stretchToHeight > 0) ? _stretchToHeight : _height; + } + + void Dispose() { + // do we want to free the bitmap? + } + + ~ALSoftwareBitmap() override { + Dispose(); + } }; -class ALSoftwareGfxModeList : public IGfxModeList -{ +class ALSoftwareGfxModeList : public IGfxModeList { public: - ALSoftwareGfxModeList(GFX_MODE_LIST *alsw_gfx_mode_list) - : _gfxModeList(alsw_gfx_mode_list) - { - } + ALSoftwareGfxModeList(GFX_MODE_LIST *alsw_gfx_mode_list) + : _gfxModeList(alsw_gfx_mode_list) { + } - int GetModeCount() const override - { - return _gfxModeList ? _gfxModeList->num_modes : 0; - } + int GetModeCount() const override { + return _gfxModeList ? _gfxModeList->num_modes : 0; + } - bool GetMode(int index, DisplayMode &mode) const override; + bool GetMode(int index, DisplayMode &mode) const override; private: - GFX_MODE_LIST *_gfxModeList; + GFX_MODE_LIST *_gfxModeList; }; typedef SpriteDrawListEntry ALDrawListEntry; // Software renderer's sprite batch -struct ALSpriteBatch -{ - // List of sprites to render - std::vector List; - // Intermediate surface which will be drawn upon and transformed if necessary - std::shared_ptr Surface; - // Whether surface is a virtual screen's region - bool IsVirtualScreen; - // Tells whether the surface is treated as opaque or transparent - bool Opaque; +struct ALSpriteBatch { + // List of sprites to render + std::vector List; + // Intermediate surface which will be drawn upon and transformed if necessary + std::shared_ptr Surface; + // Whether surface is a virtual screen's region + bool IsVirtualScreen; + // Tells whether the surface is treated as opaque or transparent + bool Opaque; }; typedef std::vector ALSpriteBatches; -class ALSoftwareGraphicsDriver : public GraphicsDriverBase -{ +class ALSoftwareGraphicsDriver : public GraphicsDriverBase { public: - ALSoftwareGraphicsDriver(); - - const char*GetDriverName() override { return "Software renderer"; } - const char*GetDriverID() override { return "Software"; } - void SetTintMethod(TintMethod method) override; - bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; - bool SetNativeSize(const Size &src_size) override; - bool SetRenderFrame(const Rect &dst_rect) override; - bool IsModeSupported(const DisplayMode &mode) override; - int GetDisplayDepthForNativeDepth(int native_color_depth) const override; - IGfxModeList *GetSupportedModeList(int color_depth) override; - PGfxFilter GetGraphicsFilter() const override; - void UnInit(); - // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. - void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; - int GetCompatibleBitmapFormat(int color_depth) override; - IDriverDependantBitmap* CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; - void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; - void DestroyDDB(IDriverDependantBitmap* bitmap) override; - - void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) override; - void SetScreenFade(int red, int green, int blue) override; - void SetScreenTint(int red, int green, int blue) override; - - void RenderToBackBuffer() override; - void Render() override; - void Render(int xoff, int yoff, GlobalFlipType flip) override; - bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; - void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void FadeIn(int speed, PALETTE pal, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void BoxOutEffect(bool blackingOut, int speed, int delay) override; + ALSoftwareGraphicsDriver(); + + const char *GetDriverName() override { + return "Software renderer"; + } + const char *GetDriverID() override { + return "Software"; + } + void SetTintMethod(TintMethod method) override; + bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; + bool SetNativeSize(const Size &src_size) override; + bool SetRenderFrame(const Rect &dst_rect) override; + bool IsModeSupported(const DisplayMode &mode) override; + int GetDisplayDepthForNativeDepth(int native_color_depth) const override; + IGfxModeList *GetSupportedModeList(int color_depth) override; + PGfxFilter GetGraphicsFilter() const override; + void UnInit(); + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; + int GetCompatibleBitmapFormat(int color_depth) override; + IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; + void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; + void DestroyDDB(IDriverDependantBitmap *bitmap) override; + + void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) override; + void SetScreenFade(int red, int green, int blue) override; + void SetScreenTint(int red, int green, int blue) override; + + void RenderToBackBuffer() override; + void Render() override; + void Render(int xoff, int yoff, GlobalFlipType flip) override; + bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; + void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void FadeIn(int speed, PALETTE pal, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void BoxOutEffect(bool blackingOut, int speed, int delay) override; #ifndef AGS_NO_VIDEO_PLAYER - bool PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) override; + bool PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) override; #endif - bool SupportsGammaControl() override ; - void SetGamma(int newGamma) override; - void UseSmoothScaling(bool enabled) override { } - void EnableVsyncBeforeRender(bool enabled) override { _autoVsync = enabled; } - void Vsync() override; - void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override { } - bool RequiresFullRedrawEachFrame() override { return false; } - bool HasAcceleratedTransform() override { return false; } - bool UsesMemoryBackBuffer() override { return true; } - Bitmap *GetMemoryBackBuffer() override; - void SetMemoryBackBuffer(Bitmap *backBuffer) override; - Bitmap *GetStageBackBuffer() override; - ~ALSoftwareGraphicsDriver() override; - - typedef std::shared_ptr PALSWFilter; - - void SetGraphicsFilter(PALSWFilter filter); + bool SupportsGammaControl() override ; + void SetGamma(int newGamma) override; + void UseSmoothScaling(bool enabled) override { } + void EnableVsyncBeforeRender(bool enabled) override { + _autoVsync = enabled; + } + void Vsync() override; + void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override { } + bool RequiresFullRedrawEachFrame() override { + return false; + } + bool HasAcceleratedTransform() override { + return false; + } + bool UsesMemoryBackBuffer() override { + return true; + } + Bitmap *GetMemoryBackBuffer() override; + void SetMemoryBackBuffer(Bitmap *backBuffer) override; + Bitmap *GetStageBackBuffer() override; + ~ALSoftwareGraphicsDriver() override; + + typedef std::shared_ptr PALSWFilter; + + void SetGraphicsFilter(PALSWFilter filter); private: - PALSWFilter _filter; - - bool _autoVsync; - Bitmap *_allegroScreenWrapper; - // Virtual screen bitmap is either a wrapper over Allegro's real screen - // bitmap, or bitmap provided by the graphics filter. It should not be - // disposed by the renderer: it is up to filter object to manage it. - Bitmap *_origVirtualScreen; - // Current virtual screen bitmap; may be provided either by graphics - // filter or by external user. It should not be disposed by the renderer. - Bitmap *virtualScreen; - // Stage screen meant for particular rendering stages, may be referencing - // actual virtual screen or separate bitmap of different size that is - // blitted to virtual screen at the stage finalization. - Bitmap *_stageVirtualScreen; - //Bitmap *_spareTintingScreen; - int _tint_red, _tint_green, _tint_blue; - - ALSpriteBatches _spriteBatches; - GFX_MODE_LIST *_gfxModeList; + PALSWFilter _filter; + + bool _autoVsync; + Bitmap *_allegroScreenWrapper; + // Virtual screen bitmap is either a wrapper over Allegro's real screen + // bitmap, or bitmap provided by the graphics filter. It should not be + // disposed by the renderer: it is up to filter object to manage it. + Bitmap *_origVirtualScreen; + // Current virtual screen bitmap; may be provided either by graphics + // filter or by external user. It should not be disposed by the renderer. + Bitmap *virtualScreen; + // Stage screen meant for particular rendering stages, may be referencing + // actual virtual screen or separate bitmap of different size that is + // blitted to virtual screen at the stage finalization. + Bitmap *_stageVirtualScreen; + //Bitmap *_spareTintingScreen; + int _tint_red, _tint_green, _tint_blue; + + ALSpriteBatches _spriteBatches; + GFX_MODE_LIST *_gfxModeList; #if AGS_DDRAW_GAMMA_CONTROL - IDirectDrawGammaControl* dxGammaControl; - // The gamma ramp is a lookup table for each possible R, G and B value - // in 32-bit colour (from 0-255) it maps them to a brightness value - // from 0-65535. The default gamma ramp just multiplies each value by 256 - DDGAMMARAMP gammaRamp; - DDGAMMARAMP defaultGammaRamp; - DDCAPS ddrawCaps; + IDirectDrawGammaControl *dxGammaControl; + // The gamma ramp is a lookup table for each possible R, G and B value + // in 32-bit colour (from 0-255) it maps them to a brightness value + // from 0-65535. The default gamma ramp just multiplies each value by 256 + DDGAMMARAMP gammaRamp; + DDGAMMARAMP defaultGammaRamp; + DDCAPS ddrawCaps; #endif - void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; - void ResetAllBatches() override; - - // Use gfx filter to create a new virtual screen - void CreateVirtualScreen(); - void DestroyVirtualScreen(); - // Unset parameters and release resources related to the display mode - void ReleaseDisplayMode(); - // Renders single sprite batch on the precreated surface - void RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy); - - void highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); - void highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); - void __fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) ; - void __fade_out_range(int speed, int from, int to, int targetColourRed, int targetColourGreen, int targetColourBlue) ; - int GetAllegroGfxDriverID(bool windowed); + void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; + void ResetAllBatches() override; + + // Use gfx filter to create a new virtual screen + void CreateVirtualScreen(); + void DestroyVirtualScreen(); + // Unset parameters and release resources related to the display mode + void ReleaseDisplayMode(); + // Renders single sprite batch on the precreated surface + void RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy); + + void highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + void highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + void __fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) ; + void __fade_out_range(int speed, int from, int to, int targetColourRed, int targetColourGreen, int targetColourBlue) ; + int GetAllegroGfxDriverID(bool windowed); }; -class ALSWGraphicsFactory : public GfxDriverFactoryBase -{ +class ALSWGraphicsFactory : public GfxDriverFactoryBase { public: - ~ALSWGraphicsFactory() override; + ~ALSWGraphicsFactory() override; - size_t GetFilterCount() const override; - const GfxFilterInfo *GetFilterInfo(size_t index) const override; - String GetDefaultFilterID() const override; + size_t GetFilterCount() const override; + const GfxFilterInfo *GetFilterInfo(size_t index) const override; + String GetDefaultFilterID() const override; - static ALSWGraphicsFactory *GetFactory(); + static ALSWGraphicsFactory *GetFactory(); private: - ALSoftwareGraphicsDriver *EnsureDriverCreated() override; - AllegroGfxFilter *CreateFilter(const String &id) override; + ALSoftwareGraphicsDriver *EnsureDriverCreated() override; + AllegroGfxFilter *CreateFilter(const String &id) override; - static ALSWGraphicsFactory *_factory; + static ALSWGraphicsFactory *_factory; }; } // namespace ALSW diff --git a/engines/ags/engine/gfx/blender.cpp b/engines/ags/engine/gfx/blender.cpp index a647a9da8a15..8d802b5462ef 100644 --- a/engines/ags/engine/gfx/blender.cpp +++ b/engines/ags/engine/gfx/blender.cpp @@ -25,15 +25,15 @@ #include "util/wgt2allg.h" extern "C" { - // Fallback routine for when we don't have anything better to do. - unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n); - // Standard Allegro 4 trans blenders for 16 and 15-bit color modes - unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n); - unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n); - // Standard Allegro 4 alpha blenders for 16 and 15-bit color modes - unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n); - unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n); - unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n); + // Fallback routine for when we don't have anything better to do. + unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n); + // Standard Allegro 4 trans blenders for 16 and 15-bit color modes + unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n); + unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n); + // Standard Allegro 4 alpha blenders for 16 and 15-bit color modes + unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n); + unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n); + unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n); } // the allegro "inline" ones are not actually inline, so #define @@ -45,264 +45,245 @@ extern "C" { #define makeacol32(r,g,b,a) ((r << _rgb_r_shift_32) | (g << _rgb_g_shift_32) | (b << _rgb_b_shift_32) | (a << _rgb_a_shift_32)) // Take hue and saturation of blend colour, luminance of image -unsigned long _myblender_color15_light(unsigned long x, unsigned long y, unsigned long n) -{ - float xh, xs, xv; - float yh, ys, yv; - int r, g, b; +unsigned long _myblender_color15_light(unsigned long x, unsigned long y, unsigned long n) { + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; - rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv); - rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv); + rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv); + rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv); - // adjust luminance - yv -= (1.0 - ((float)n / 250.0)); - if (yv < 0.0) yv = 0.0; + // adjust luminance + yv -= (1.0 - ((float)n / 250.0)); + if (yv < 0.0) yv = 0.0; - hsv_to_rgb(xh, xs, yv, &r, &g, &b); + hsv_to_rgb(xh, xs, yv, &r, &g, &b); - return makecol15(r, g, b); + return makecol15(r, g, b); } // Take hue and saturation of blend colour, luminance of image // n is the last parameter passed to draw_lit_sprite -unsigned long _myblender_color16_light(unsigned long x, unsigned long y, unsigned long n) -{ - float xh, xs, xv; - float yh, ys, yv; - int r, g, b; +unsigned long _myblender_color16_light(unsigned long x, unsigned long y, unsigned long n) { + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; - rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv); - rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv); + rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv); + rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv); - // adjust luminance - yv -= (1.0 - ((float)n / 250.0)); - if (yv < 0.0) yv = 0.0; + // adjust luminance + yv -= (1.0 - ((float)n / 250.0)); + if (yv < 0.0) yv = 0.0; - hsv_to_rgb(xh, xs, yv, &r, &g, &b); + hsv_to_rgb(xh, xs, yv, &r, &g, &b); - return makecol16(r, g, b); + return makecol16(r, g, b); } // Take hue and saturation of blend colour, luminance of image -unsigned long _myblender_color32_light(unsigned long x, unsigned long y, unsigned long n) -{ - float xh, xs, xv; - float yh, ys, yv; - int r, g, b; +unsigned long _myblender_color32_light(unsigned long x, unsigned long y, unsigned long n) { + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; - rgb_to_hsv(getr32(x), getg32(x), getb32(x), &xh, &xs, &xv); - rgb_to_hsv(getr32(y), getg32(y), getb32(y), &yh, &ys, &yv); + rgb_to_hsv(getr32(x), getg32(x), getb32(x), &xh, &xs, &xv); + rgb_to_hsv(getr32(y), getg32(y), getb32(y), &yh, &ys, &yv); - // adjust luminance - yv -= (1.0 - ((float)n / 250.0)); - if (yv < 0.0) yv = 0.0; + // adjust luminance + yv -= (1.0 - ((float)n / 250.0)); + if (yv < 0.0) yv = 0.0; - hsv_to_rgb(xh, xs, yv, &r, &g, &b); + hsv_to_rgb(xh, xs, yv, &r, &g, &b); - return makeacol32(r, g, b, geta32(y)); + return makeacol32(r, g, b, geta32(y)); } // Take hue and saturation of blend colour, luminance of image -unsigned long _myblender_color15(unsigned long x, unsigned long y, unsigned long n) -{ - float xh, xs, xv; - float yh, ys, yv; - int r, g, b; +unsigned long _myblender_color15(unsigned long x, unsigned long y, unsigned long n) { + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; - rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv); - rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv); + rgb_to_hsv(getr15(x), getg15(x), getb15(x), &xh, &xs, &xv); + rgb_to_hsv(getr15(y), getg15(y), getb15(y), &yh, &ys, &yv); - hsv_to_rgb(xh, xs, yv, &r, &g, &b); + hsv_to_rgb(xh, xs, yv, &r, &g, &b); - return makecol15(r, g, b); + return makecol15(r, g, b); } // Take hue and saturation of blend colour, luminance of image -unsigned long _myblender_color16(unsigned long x, unsigned long y, unsigned long n) -{ - float xh, xs, xv; - float yh, ys, yv; - int r, g, b; +unsigned long _myblender_color16(unsigned long x, unsigned long y, unsigned long n) { + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; - rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv); - rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv); + rgb_to_hsv(getr16(x), getg16(x), getb16(x), &xh, &xs, &xv); + rgb_to_hsv(getr16(y), getg16(y), getb16(y), &yh, &ys, &yv); - hsv_to_rgb(xh, xs, yv, &r, &g, &b); + hsv_to_rgb(xh, xs, yv, &r, &g, &b); - return makecol16(r, g, b); + return makecol16(r, g, b); } // Take hue and saturation of blend colour, luminance of image -unsigned long _myblender_color32(unsigned long x, unsigned long y, unsigned long n) -{ - float xh, xs, xv; - float yh, ys, yv; - int r, g, b; +unsigned long _myblender_color32(unsigned long x, unsigned long y, unsigned long n) { + float xh, xs, xv; + float yh, ys, yv; + int r, g, b; - rgb_to_hsv(getr32(x), getg32(x), getb32(x), &xh, &xs, &xv); - rgb_to_hsv(getr32(y), getg32(y), getb32(y), &yh, &ys, &yv); + rgb_to_hsv(getr32(x), getg32(x), getb32(x), &xh, &xs, &xv); + rgb_to_hsv(getr32(y), getg32(y), getb32(y), &yh, &ys, &yv); - hsv_to_rgb(xh, xs, yv, &r, &g, &b); + hsv_to_rgb(xh, xs, yv, &r, &g, &b); - return makeacol32(r, g, b, geta32(y)); + return makeacol32(r, g, b, geta32(y)); } // trans24 blender, but preserve alpha channel from image -unsigned long _myblender_alpha_trans24(unsigned long x, unsigned long y, unsigned long n) -{ - unsigned long res, g, alph; +unsigned long _myblender_alpha_trans24(unsigned long x, unsigned long y, unsigned long n) { + unsigned long res, g, alph; - if (n) - n++; + if (n) + n++; - alph = y & 0xff000000; - y &= 0x00ffffff; + alph = y & 0xff000000; + y &= 0x00ffffff; - res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y; - y &= 0xFF00; - x &= 0xFF00; - g = (x - y) * n / 256 + y; + res = ((x & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y; + y &= 0xFF00; + x &= 0xFF00; + g = (x - y) * n / 256 + y; - res &= 0xFF00FF; - g &= 0xFF00; + res &= 0xFF00FF; + g &= 0xFF00; - return res | g | alph; + return res | g | alph; } -void set_my_trans_blender(int r, int g, int b, int a) -{ - // use standard allegro 15 and 16 bit blenders, but customize - // the 32-bit one to preserve the alpha channel - set_blender_mode(_blender_trans15, _blender_trans16, _myblender_alpha_trans24, r, g, b, a); +void set_my_trans_blender(int r, int g, int b, int a) { + // use standard allegro 15 and 16 bit blenders, but customize + // the 32-bit one to preserve the alpha channel + set_blender_mode(_blender_trans15, _blender_trans16, _myblender_alpha_trans24, r, g, b, a); } // plain copy source to destination // assign new alpha value as a summ of alphas. -unsigned long _additive_alpha_copysrc_blender(unsigned long x, unsigned long y, unsigned long n) -{ - unsigned long newAlpha = ((x & 0xff000000) >> 24) + ((y & 0xff000000) >> 24); +unsigned long _additive_alpha_copysrc_blender(unsigned long x, unsigned long y, unsigned long n) { + unsigned long newAlpha = ((x & 0xff000000) >> 24) + ((y & 0xff000000) >> 24); - if (newAlpha > 0xff) newAlpha = 0xff; + if (newAlpha > 0xff) newAlpha = 0xff; - return (newAlpha << 24) | (x & 0x00ffffff); + return (newAlpha << 24) | (x & 0x00ffffff); } -FORCEINLINE unsigned long argb2argb_blend_core(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) -{ - unsigned long dst_g, dst_alpha; - src_alpha++; - dst_alpha = geta32(dst_col); - if (dst_alpha) - dst_alpha++; - - // dst_g now contains the green hue from destination color - dst_g = (dst_col & 0x00FF00) * dst_alpha / 256; - // dst_col now contains the red & blue hues from destination color - dst_col = (dst_col & 0xFF00FF) * dst_alpha / 256; - - // res_g now contains the green hue of the pre-final color - dst_g = (((src_col & 0x00FF00) - (dst_g & 0x00FF00)) * src_alpha / 256 + dst_g) & 0x00FF00; - // res_rb now contains the red & blue hues of the pre-final color - dst_col = (((src_col & 0xFF00FF) - (dst_col & 0xFF00FF)) * src_alpha / 256 + dst_col) & 0xFF00FF; - - // dst_alpha now contains the final alpha - // we assume that final alpha will never be zero - dst_alpha = 256 - (256 - src_alpha) * (256 - dst_alpha) / 256; - // src_alpha is now the final alpha factor made for being multiplied by, - // instead of divided by: this makes it possible to use it in faster - // calculation below - src_alpha = /* 256 * 256 == */ 0x10000 / dst_alpha; - - // setting up final color hues - dst_g = (dst_g * src_alpha / 256) & 0x00FF00; - dst_col = (dst_col * src_alpha / 256) & 0xFF00FF; - return dst_col | dst_g | (--dst_alpha << 24); +FORCEINLINE unsigned long argb2argb_blend_core(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) { + unsigned long dst_g, dst_alpha; + src_alpha++; + dst_alpha = geta32(dst_col); + if (dst_alpha) + dst_alpha++; + + // dst_g now contains the green hue from destination color + dst_g = (dst_col & 0x00FF00) * dst_alpha / 256; + // dst_col now contains the red & blue hues from destination color + dst_col = (dst_col & 0xFF00FF) * dst_alpha / 256; + + // res_g now contains the green hue of the pre-final color + dst_g = (((src_col & 0x00FF00) - (dst_g & 0x00FF00)) * src_alpha / 256 + dst_g) & 0x00FF00; + // res_rb now contains the red & blue hues of the pre-final color + dst_col = (((src_col & 0xFF00FF) - (dst_col & 0xFF00FF)) * src_alpha / 256 + dst_col) & 0xFF00FF; + + // dst_alpha now contains the final alpha + // we assume that final alpha will never be zero + dst_alpha = 256 - (256 - src_alpha) * (256 - dst_alpha) / 256; + // src_alpha is now the final alpha factor made for being multiplied by, + // instead of divided by: this makes it possible to use it in faster + // calculation below + src_alpha = /* 256 * 256 == */ 0x10000 / dst_alpha; + + // setting up final color hues + dst_g = (dst_g * src_alpha / 256) & 0x00FF00; + dst_col = (dst_col * src_alpha / 256) & 0xFF00FF; + return dst_col | dst_g | (--dst_alpha << 24); } // blend source to destination with respect to source and destination alphas; // assign new alpha value as a multiplication of translucenses. // combined_alpha = front.alpha + back.alpha * (1 - front.alpha); // combined_rgb = (front.rgb * front.alpha + back.rgb * (1 - front.alpha) * back.alpha) / combined_alpha; -unsigned long _argb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) -{ - if (src_alpha > 0) - src_alpha = geta32(src_col) * ((src_alpha & 0xFF) + 1) / 256; - else - src_alpha = geta32(src_col); - if (src_alpha == 0) - return dst_col; - return argb2argb_blend_core(src_col, dst_col, src_alpha); +unsigned long _argb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) { + if (src_alpha > 0) + src_alpha = geta32(src_col) * ((src_alpha & 0xFF) + 1) / 256; + else + src_alpha = geta32(src_col); + if (src_alpha == 0) + return dst_col; + return argb2argb_blend_core(src_col, dst_col, src_alpha); } -unsigned long _rgb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) -{ - if (src_alpha == 0 || src_alpha == 0xFF) - return src_col | 0xFF000000; - return argb2argb_blend_core(src_col | 0xFF000000, dst_col, src_alpha); +unsigned long _rgb2argb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) { + if (src_alpha == 0 || src_alpha == 0xFF) + return src_col | 0xFF000000; + return argb2argb_blend_core(src_col | 0xFF000000, dst_col, src_alpha); } -unsigned long _argb2rgb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) -{ - unsigned long res, g; +unsigned long _argb2rgb_blender(unsigned long src_col, unsigned long dst_col, unsigned long src_alpha) { + unsigned long res, g; - if (src_alpha > 0) - src_alpha = geta32(src_col) * ((src_alpha & 0xFF) + 1) / 256; - else - src_alpha = geta32(src_col); - if (src_alpha) - src_alpha++; + if (src_alpha > 0) + src_alpha = geta32(src_col) * ((src_alpha & 0xFF) + 1) / 256; + else + src_alpha = geta32(src_col); + if (src_alpha) + src_alpha++; - res = ((src_col & 0xFF00FF) - (dst_col & 0xFF00FF)) * src_alpha / 256 + dst_col; - dst_col &= 0xFF00; - src_col &= 0xFF00; - g = (src_col - dst_col) * src_alpha / 256 + dst_col; + res = ((src_col & 0xFF00FF) - (dst_col & 0xFF00FF)) * src_alpha / 256 + dst_col; + dst_col &= 0xFF00; + src_col &= 0xFF00; + g = (src_col - dst_col) * src_alpha / 256 + dst_col; - res &= 0xFF00FF; - g &= 0xFF00; + res &= 0xFF00FF; + g &= 0xFF00; - return res | g; + return res | g; } // Based on _blender_alpha16, but keep source pixel if dest is transparent -unsigned long skiptranspixels_blender_alpha16(unsigned long x, unsigned long y, unsigned long n) -{ - unsigned long result; - if ((y & 0xFFFF) == 0xF81F) - return x; - n = geta32(x); - if (n) - n = (n + 1) / 8; - x = makecol16(getr32(x), getg32(x), getb32(x)); - x = (x | (x << 16)) & 0x7E0F81F; - y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F; - result = ((x - y) * n / 32 + y) & 0x7E0F81F; - return ((result & 0xFFFF) | (result >> 16)); +unsigned long skiptranspixels_blender_alpha16(unsigned long x, unsigned long y, unsigned long n) { + unsigned long result; + if ((y & 0xFFFF) == 0xF81F) + return x; + n = geta32(x); + if (n) + n = (n + 1) / 8; + x = makecol16(getr32(x), getg32(x), getb32(x)); + x = (x | (x << 16)) & 0x7E0F81F; + y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F; + result = ((x - y) * n / 32 + y) & 0x7E0F81F; + return ((result & 0xFFFF) | (result >> 16)); } -void set_additive_alpha_blender() -{ - set_blender_mode(nullptr, nullptr, _additive_alpha_copysrc_blender, 0, 0, 0, 0); +void set_additive_alpha_blender() { + set_blender_mode(nullptr, nullptr, _additive_alpha_copysrc_blender, 0, 0, 0, 0); } -void set_argb2argb_blender(int alpha) -{ - set_blender_mode(nullptr, nullptr, _argb2argb_blender, 0, 0, 0, alpha); +void set_argb2argb_blender(int alpha) { + set_blender_mode(nullptr, nullptr, _argb2argb_blender, 0, 0, 0, alpha); } // sets the alpha channel to opaque. used when drawing a non-alpha sprite onto an alpha-sprite -unsigned long _opaque_alpha_blender(unsigned long x, unsigned long y, unsigned long n) -{ - return x | 0xff000000; +unsigned long _opaque_alpha_blender(unsigned long x, unsigned long y, unsigned long n) { + return x | 0xff000000; } -void set_opaque_alpha_blender() -{ - set_blender_mode(nullptr, nullptr, _opaque_alpha_blender, 0, 0, 0, 0); +void set_opaque_alpha_blender() { + set_blender_mode(nullptr, nullptr, _opaque_alpha_blender, 0, 0, 0, 0); } -void set_argb2any_blender() -{ - set_blender_mode_ex(_blender_black, _blender_black, _blender_black, _argb2argb_blender, - _blender_alpha15, skiptranspixels_blender_alpha16, _blender_alpha24, - 0, 0, 0, 0xff); // TODO: do we need to support proper 15- and 24-bit here? +void set_argb2any_blender() { + set_blender_mode_ex(_blender_black, _blender_black, _blender_black, _argb2argb_blender, + _blender_alpha15, skiptranspixels_blender_alpha16, _blender_alpha24, + 0, 0, 0, 0xff); // TODO: do we need to support proper 15- and 24-bit here? } diff --git a/engines/ags/engine/gfx/color_engine.cpp b/engines/ags/engine/gfx/color_engine.cpp index a204add5957d..95f39dd88d2f 100644 --- a/engines/ags/engine/gfx/color_engine.cpp +++ b/engines/ags/engine/gfx/color_engine.cpp @@ -31,39 +31,35 @@ #include "util/wgt2allg.h" #include "gfx/bitmap.h" -void __my_setcolor(int *ctset, int newcol, int wantColDep) - { - if (wantColDep == 8) - ctset[0] = newcol; - else if (newcol & 0x40000000) // already calculated it - ctset[0] = newcol; - else if ((newcol >= 32) && (wantColDep > 16)) { - // true-color +void __my_setcolor(int *ctset, int newcol, int wantColDep) { + if (wantColDep == 8) + ctset[0] = newcol; + else if (newcol & 0x40000000) // already calculated it + ctset[0] = newcol; + else if ((newcol >= 32) && (wantColDep > 16)) { + // true-color #ifdef SWAP_RB_HICOL_FOR_32to24_32 - ctset[0] = makeacol32(getb16(newcol), getg16(newcol), getr16(newcol), 255); + ctset[0] = makeacol32(getb16(newcol), getg16(newcol), getr16(newcol), 255); #else - ctset[0] = makeacol32(getr16(newcol), getg16(newcol), getb16(newcol), 255); + ctset[0] = makeacol32(getr16(newcol), getg16(newcol), getb16(newcol), 255); #endif - } - else if (newcol >= 32) { + } else if (newcol >= 32) { - // If it's 15-bit, convert the color - if (wantColDep == 15) - ctset[0] = (newcol & 0x001f) | ((newcol >> 1) & 0x7fe0); - else - ctset[0] = newcol; - } - else - { - ctset[0] = makecol_depth(wantColDep, col_lookups[newcol] >> 16, - (col_lookups[newcol] >> 8) & 0x000ff, col_lookups[newcol] & 0x000ff); + // If it's 15-bit, convert the color + if (wantColDep == 15) + ctset[0] = (newcol & 0x001f) | ((newcol >> 1) & 0x7fe0); + else + ctset[0] = newcol; + } else { + ctset[0] = makecol_depth(wantColDep, col_lookups[newcol] >> 16, + (col_lookups[newcol] >> 8) & 0x000ff, col_lookups[newcol] & 0x000ff); - // in case it's used on an alpha-channel sprite, make sure it's visible - if (wantColDep > 16) - ctset[0] |= 0xff000000; - } + // in case it's used on an alpha-channel sprite, make sure it's visible + if (wantColDep > 16) + ctset[0] |= 0xff000000; + } - // if it's 32-bit color, signify that the colour has been calculated - //if (wantColDep >= 24) + // if it's 32-bit color, signify that the colour has been calculated + //if (wantColDep >= 24) // ctset[0] |= 0x40000000; - } +} diff --git a/engines/ags/engine/gfx/ddb.h b/engines/ags/engine/gfx/ddb.h index 4dc159f7399d..64ab9e2ff6bf 100644 --- a/engines/ags/engine/gfx/ddb.h +++ b/engines/ags/engine/gfx/ddb.h @@ -29,25 +29,22 @@ #ifndef AGS_ENGINE_GFX_DDB_H #define AGS_ENGINE_GFX_DDB_H -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class IDriverDependantBitmap -{ +class IDriverDependantBitmap { public: - virtual ~IDriverDependantBitmap() = default; + virtual ~IDriverDependantBitmap() = default; - virtual void SetTransparency(int transparency) = 0; // 0-255 - virtual void SetFlippedLeftRight(bool isFlipped) = 0; - virtual void SetStretch(int width, int height, bool useResampler = true) = 0; - virtual void SetLightLevel(int light_level) = 0; // 0-255 - virtual void SetTint(int red, int green, int blue, int tintSaturation) = 0; // 0-255 + virtual void SetTransparency(int transparency) = 0; // 0-255 + virtual void SetFlippedLeftRight(bool isFlipped) = 0; + virtual void SetStretch(int width, int height, bool useResampler = true) = 0; + virtual void SetLightLevel(int light_level) = 0; // 0-255 + virtual void SetTint(int red, int green, int blue, int tintSaturation) = 0; // 0-255 - virtual int GetWidth() = 0; - virtual int GetHeight() = 0; - virtual int GetColorDepth() = 0; + virtual int GetWidth() = 0; + virtual int GetHeight() = 0; + virtual int GetColorDepth() = 0; }; } // namespace Engine diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp index ec87092750a7..8fc9629b83d3 100644 --- a/engines/ags/engine/gfx/gfx_util.cpp +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -29,167 +29,138 @@ extern int psp_gfx_renderer; #endif -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using namespace Common; -namespace GfxUtil -{ - -Bitmap *ConvertBitmap(Bitmap *src, int dst_color_depth) -{ - int src_col_depth = src->GetColorDepth(); - if (src_col_depth != dst_color_depth) - { - int old_conv = get_color_conversion(); - // TODO: find out what is this, and why do we need to call this every time (do we?) - set_color_conversion(COLORCONV_KEEP_TRANS | COLORCONV_TOTAL); - Bitmap *dst = BitmapHelper::CreateBitmapCopy(src, dst_color_depth); - set_color_conversion(old_conv); - return dst; - } - return src; +namespace GfxUtil { + +Bitmap *ConvertBitmap(Bitmap *src, int dst_color_depth) { + int src_col_depth = src->GetColorDepth(); + if (src_col_depth != dst_color_depth) { + int old_conv = get_color_conversion(); + // TODO: find out what is this, and why do we need to call this every time (do we?) + set_color_conversion(COLORCONV_KEEP_TRANS | COLORCONV_TOTAL); + Bitmap *dst = BitmapHelper::CreateBitmapCopy(src, dst_color_depth); + set_color_conversion(old_conv); + return dst; + } + return src; } typedef BLENDER_FUNC PfnBlenderCb; -struct BlendModeSetter -{ - // Blender setter for destination with and without alpha channel; - // assign null pointer if not supported - PfnBlenderCb AllAlpha; // src w alpha -> dst w alpha - PfnBlenderCb AlphaToOpaque; // src w alpha -> dst w/o alpha - PfnBlenderCb OpaqueToAlpha; // src w/o alpha -> dst w alpha - PfnBlenderCb OpaqueToAlphaNoTrans; // src w/o alpha -> dst w alpha (opt-ed for no transparency) - PfnBlenderCb AllOpaque; // src w/o alpha -> dst w/o alpha +struct BlendModeSetter { + // Blender setter for destination with and without alpha channel; + // assign null pointer if not supported + PfnBlenderCb AllAlpha; // src w alpha -> dst w alpha + PfnBlenderCb AlphaToOpaque; // src w alpha -> dst w/o alpha + PfnBlenderCb OpaqueToAlpha; // src w/o alpha -> dst w alpha + PfnBlenderCb OpaqueToAlphaNoTrans; // src w/o alpha -> dst w alpha (opt-ed for no transparency) + PfnBlenderCb AllOpaque; // src w/o alpha -> dst w/o alpha }; // Array of blender descriptions // NOTE: set NULL function pointer to fallback to common image blitting -static const BlendModeSetter BlendModeSets[kNumBlendModes] = -{ - { nullptr, nullptr, nullptr, nullptr, nullptr }, // kBlendMode_NoAlpha - { _argb2argb_blender, _argb2rgb_blender, _rgb2argb_blender, _opaque_alpha_blender, nullptr }, // kBlendMode_Alpha - // NOTE: add new modes here +static const BlendModeSetter BlendModeSets[kNumBlendModes] = { + { nullptr, nullptr, nullptr, nullptr, nullptr }, // kBlendMode_NoAlpha + { _argb2argb_blender, _argb2rgb_blender, _rgb2argb_blender, _opaque_alpha_blender, nullptr }, // kBlendMode_Alpha + // NOTE: add new modes here }; -bool SetBlender(BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) -{ - if (blend_mode < 0 || blend_mode > kNumBlendModes) - return false; - const BlendModeSetter &set = BlendModeSets[blend_mode]; - PfnBlenderCb blender; - if (dst_has_alpha) - blender = src_has_alpha ? set.AllAlpha : - (blend_alpha == 0xFF ? set.OpaqueToAlphaNoTrans : set.OpaqueToAlpha); - else - blender = src_has_alpha ? set.AlphaToOpaque : set.AllOpaque; - - if (blender) - { - set_blender_mode(nullptr, nullptr, blender, 0, 0, 0, blend_alpha); - return true; - } - return false; +bool SetBlender(BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) { + if (blend_mode < 0 || blend_mode > kNumBlendModes) + return false; + const BlendModeSetter &set = BlendModeSets[blend_mode]; + PfnBlenderCb blender; + if (dst_has_alpha) + blender = src_has_alpha ? set.AllAlpha : + (blend_alpha == 0xFF ? set.OpaqueToAlphaNoTrans : set.OpaqueToAlpha); + else + blender = src_has_alpha ? set.AlphaToOpaque : set.AllOpaque; + + if (blender) { + set_blender_mode(nullptr, nullptr, blender, 0, 0, 0, blend_alpha); + return true; + } + return false; } void DrawSpriteBlend(Bitmap *ds, const Point &ds_at, Bitmap *sprite, - BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) -{ - if (blend_alpha <= 0) - return; // do not draw 100% transparent image - - if (// support only 32-bit blending at the moment - ds->GetColorDepth() == 32 && sprite->GetColorDepth() == 32 && - // set blenders if applicable and tell if succeeded - SetBlender(blend_mode, dst_has_alpha, src_has_alpha, blend_alpha)) - { - ds->TransBlendBlt(sprite, ds_at.X, ds_at.Y); - } - else - { - GfxUtil::DrawSpriteWithTransparency(ds, sprite, ds_at.X, ds_at.Y, blend_alpha); - } + BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) { + if (blend_alpha <= 0) + return; // do not draw 100% transparent image + + if (// support only 32-bit blending at the moment + ds->GetColorDepth() == 32 && sprite->GetColorDepth() == 32 && + // set blenders if applicable and tell if succeeded + SetBlender(blend_mode, dst_has_alpha, src_has_alpha, blend_alpha)) { + ds->TransBlendBlt(sprite, ds_at.X, ds_at.Y); + } else { + GfxUtil::DrawSpriteWithTransparency(ds, sprite, ds_at.X, ds_at.Y, blend_alpha); + } } -void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int alpha) -{ - if (alpha <= 0) - { - // fully transparent, don't draw it at all - return; - } +void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int alpha) { + if (alpha <= 0) { + // fully transparent, don't draw it at all + return; + } - int surface_depth = ds->GetColorDepth(); - int sprite_depth = sprite->GetColorDepth(); + int surface_depth = ds->GetColorDepth(); + int sprite_depth = sprite->GetColorDepth(); - if (sprite_depth < surface_depth - // CHECKME: what is the purpose of this hack and is this still relevant? + if (sprite_depth < surface_depth + // CHECKME: what is the purpose of this hack and is this still relevant? #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID - || (ds->GetBPP() < surface_depth && psp_gfx_renderer > 0) // Fix for corrupted speechbox outlines with the OGL driver + || (ds->GetBPP() < surface_depth && psp_gfx_renderer > 0) // Fix for corrupted speechbox outlines with the OGL driver #endif - ) - { - // If sprite is lower color depth than destination surface, e.g. - // 8-bit sprites drawn on 16/32-bit surfaces. - if (sprite_depth == 8 && surface_depth >= 24) - { - // 256-col sprite -> truecolor background - // this is automatically supported by allegro, no twiddling needed - ds->Blit(sprite, x, y, kBitmap_Transparency); - return; - } - - // 256-col sprite -> hi-color background, or - // 16-bit sprite -> 32-bit background - Bitmap hctemp; - hctemp.CreateCopy(sprite, surface_depth); - if (sprite_depth == 8) - { - // only do this for 256-col -> hi-color, cos the Blit call converts - // transparency for 16->32 bit - color_t mask_color = hctemp.GetMaskColor(); - for (int scan_y = 0; scan_y < hctemp.GetHeight(); ++scan_y) - { - // we know this must be 1 bpp source and 2 bpp pixel destination - const uint8_t *src_scanline = sprite->GetScanLine(scan_y); - uint16_t *dst_scanline = (uint16_t*)hctemp.GetScanLineForWriting(scan_y); - for (int scan_x = 0; scan_x < hctemp.GetWidth(); ++scan_x) - { - if (src_scanline[scan_x] == 0) - { - dst_scanline[scan_x] = mask_color; - } - } - } - } - - if (alpha < 0xFF) - { - set_trans_blender(0, 0, 0, alpha); - ds->TransBlendBlt(&hctemp, x, y); - } - else - { - ds->Blit(&hctemp, x, y, kBitmap_Transparency); - } - } - else - { - if (alpha < 0xFF && surface_depth > 8 && sprite_depth > 8) - { - set_trans_blender(0, 0, 0, alpha); - ds->TransBlendBlt(sprite, x, y); - } - else - { - ds->Blit(sprite, x, y, kBitmap_Transparency); - } - } + ) { + // If sprite is lower color depth than destination surface, e.g. + // 8-bit sprites drawn on 16/32-bit surfaces. + if (sprite_depth == 8 && surface_depth >= 24) { + // 256-col sprite -> truecolor background + // this is automatically supported by allegro, no twiddling needed + ds->Blit(sprite, x, y, kBitmap_Transparency); + return; + } + + // 256-col sprite -> hi-color background, or + // 16-bit sprite -> 32-bit background + Bitmap hctemp; + hctemp.CreateCopy(sprite, surface_depth); + if (sprite_depth == 8) { + // only do this for 256-col -> hi-color, cos the Blit call converts + // transparency for 16->32 bit + color_t mask_color = hctemp.GetMaskColor(); + for (int scan_y = 0; scan_y < hctemp.GetHeight(); ++scan_y) { + // we know this must be 1 bpp source and 2 bpp pixel destination + const uint8_t *src_scanline = sprite->GetScanLine(scan_y); + uint16_t *dst_scanline = (uint16_t *)hctemp.GetScanLineForWriting(scan_y); + for (int scan_x = 0; scan_x < hctemp.GetWidth(); ++scan_x) { + if (src_scanline[scan_x] == 0) { + dst_scanline[scan_x] = mask_color; + } + } + } + } + + if (alpha < 0xFF) { + set_trans_blender(0, 0, 0, alpha); + ds->TransBlendBlt(&hctemp, x, y); + } else { + ds->Blit(&hctemp, x, y, kBitmap_Transparency); + } + } else { + if (alpha < 0xFF && surface_depth > 8 && sprite_depth > 8) { + set_trans_blender(0, 0, 0, alpha); + ds->TransBlendBlt(sprite, x, y); + } else { + ds->Blit(sprite, x, y, kBitmap_Transparency); + } + } } } // namespace GfxUtil diff --git a/engines/ags/engine/gfx/gfx_util.h b/engines/ags/engine/gfx/gfx_util.h index a782b94f0830..5747699ad419 100644 --- a/engines/ags/engine/gfx/gfx_util.h +++ b/engines/ags/engine/gfx/gfx_util.h @@ -38,30 +38,27 @@ #include "gfx/bitmap.h" #include "gfx/gfx_def.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using Common::Bitmap; -namespace GfxUtil -{ - // Creates a COPY of the source bitmap, converted to the given format. - Bitmap *ConvertBitmap(Bitmap *src, int dst_color_depth); +namespace GfxUtil { +// Creates a COPY of the source bitmap, converted to the given format. +Bitmap *ConvertBitmap(Bitmap *src, int dst_color_depth); - // Considers the given information about source and destination surfaces, - // then draws a bimtap over another either using requested blending mode, - // or fallbacks to common "magic pink" transparency mode; - // optionally uses blending alpha (overall image transparency). - void DrawSpriteBlend(Bitmap *ds, const Point &ds_at, Bitmap *sprite, - Common::BlendMode blend_mode, bool dst_has_alpha = true, bool src_has_alpha = true, int blend_alpha = 0xFF); +// Considers the given information about source and destination surfaces, +// then draws a bimtap over another either using requested blending mode, +// or fallbacks to common "magic pink" transparency mode; +// optionally uses blending alpha (overall image transparency). +void DrawSpriteBlend(Bitmap *ds, const Point &ds_at, Bitmap *sprite, + Common::BlendMode blend_mode, bool dst_has_alpha = true, bool src_has_alpha = true, int blend_alpha = 0xFF); - // Draws a bitmap over another one with given alpha level (0 - 255), - // takes account of the bitmap's mask color, - // ignores image's alpha channel, even if there's one; - // does proper conversion depending on respected color depths. - void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int alpha = 0xFF); +// Draws a bitmap over another one with given alpha level (0 - 255), +// takes account of the bitmap's mask color, +// ignores image's alpha channel, even if there's one; +// does proper conversion depending on respected color depths. +void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int alpha = 0xFF); } // namespace GfxUtil } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxdefines.h b/engines/ags/engine/gfx/gfxdefines.h index 939510f6b26c..f3893bda9621 100644 --- a/engines/ags/engine/gfx/gfxdefines.h +++ b/engines/ags/engine/gfx/gfxdefines.h @@ -25,63 +25,58 @@ #include "core/types.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { // TODO: find the way to merge this with sprite batch transform -enum GlobalFlipType -{ - kFlip_None, - kFlip_Horizontal, // this means - mirror over horizontal middle line - kFlip_Vertical, // this means - mirror over vertical middle line - kFlip_Both +enum GlobalFlipType { + kFlip_None, + kFlip_Horizontal, // this means - mirror over horizontal middle line + kFlip_Vertical, // this means - mirror over vertical middle line + kFlip_Both }; // GraphicResolution struct determines image size and color depth -struct GraphicResolution -{ - int32_t Width; - int32_t Height; - int32_t ColorDepth; +struct GraphicResolution { + int32_t Width; + int32_t Height; + int32_t ColorDepth; - GraphicResolution() - : Width(0) - , Height(0) - , ColorDepth(0) - { - } + GraphicResolution() + : Width(0) + , Height(0) + , ColorDepth(0) { + } - GraphicResolution(int32_t width, int32_t height, int32_t color_depth) - { - Width = width; - Height = height; - ColorDepth = color_depth; - } + GraphicResolution(int32_t width, int32_t height, int32_t color_depth) { + Width = width; + Height = height; + ColorDepth = color_depth; + } - inline bool IsValid() const { return Width > 0 && Height > 0 && ColorDepth > 0; } + inline bool IsValid() const { + return Width > 0 && Height > 0 && ColorDepth > 0; + } }; // DisplayMode struct provides extended description of display mode -struct DisplayMode : public GraphicResolution -{ - int32_t RefreshRate; - bool Vsync; - bool Windowed; +struct DisplayMode : public GraphicResolution { + int32_t RefreshRate; + bool Vsync; + bool Windowed; - DisplayMode() - : RefreshRate(0) - , Vsync(false) - , Windowed(false) - {} + DisplayMode() + : RefreshRate(0) + , Vsync(false) + , Windowed(false) { + } - DisplayMode(const GraphicResolution &res, bool windowed = false, int32_t refresh = 0, bool vsync = false) - : GraphicResolution(res) - , RefreshRate(refresh) - , Vsync(vsync) - , Windowed(windowed) - {} + DisplayMode(const GraphicResolution &res, bool windowed = false, int32_t refresh = 0, bool vsync = false) + : GraphicResolution(res) + , RefreshRate(refresh) + , Vsync(vsync) + , Windowed(windowed) { + } }; } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index e43510fcc9e8..2081c75be90d 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -29,245 +29,210 @@ using namespace AGS::Common; -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { GraphicsDriverBase::GraphicsDriverBase() - : _pollingCallback(nullptr) - , _drawScreenCallback(nullptr) - , _nullSpriteCallback(nullptr) - , _initGfxCallback(nullptr) - , _initSurfaceUpdateCallback(nullptr) -{ - // Initialize default sprite batch, it will be used when no other batch was activated - _actSpriteBatch = 0; - _spriteBatchDesc.push_back(SpriteBatchDesc()); + : _pollingCallback(nullptr) + , _drawScreenCallback(nullptr) + , _nullSpriteCallback(nullptr) + , _initGfxCallback(nullptr) + , _initSurfaceUpdateCallback(nullptr) { + // Initialize default sprite batch, it will be used when no other batch was activated + _actSpriteBatch = 0; + _spriteBatchDesc.push_back(SpriteBatchDesc()); } -bool GraphicsDriverBase::IsModeSet() const -{ - return _mode.Width != 0 && _mode.Height != 0 && _mode.ColorDepth != 0; +bool GraphicsDriverBase::IsModeSet() const { + return _mode.Width != 0 && _mode.Height != 0 && _mode.ColorDepth != 0; } -bool GraphicsDriverBase::IsNativeSizeValid() const -{ - return !_srcRect.IsEmpty(); +bool GraphicsDriverBase::IsNativeSizeValid() const { + return !_srcRect.IsEmpty(); } -bool GraphicsDriverBase::IsRenderFrameValid() const -{ - return !_srcRect.IsEmpty() && !_dstRect.IsEmpty(); +bool GraphicsDriverBase::IsRenderFrameValid() const { + return !_srcRect.IsEmpty() && !_dstRect.IsEmpty(); } -DisplayMode GraphicsDriverBase::GetDisplayMode() const -{ - return _mode; +DisplayMode GraphicsDriverBase::GetDisplayMode() const { + return _mode; } -Size GraphicsDriverBase::GetNativeSize() const -{ - return _srcRect.GetSize(); +Size GraphicsDriverBase::GetNativeSize() const { + return _srcRect.GetSize(); } -Rect GraphicsDriverBase::GetRenderDestination() const -{ - return _dstRect; +Rect GraphicsDriverBase::GetRenderDestination() const { + return _dstRect; } void GraphicsDriverBase::BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, - const Point offset, GlobalFlipType flip, PBitmap surface) -{ - _actSpriteBatch++; - _spriteBatchDesc.push_back(SpriteBatchDesc(viewport, transform, offset, flip, surface)); - InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]); + const Point offset, GlobalFlipType flip, PBitmap surface) { + _actSpriteBatch++; + _spriteBatchDesc.push_back(SpriteBatchDesc(viewport, transform, offset, flip, surface)); + InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]); } -void GraphicsDriverBase::ClearDrawLists() -{ - ResetAllBatches(); - _actSpriteBatch = 0; - _spriteBatchDesc.resize(1); +void GraphicsDriverBase::ClearDrawLists() { + ResetAllBatches(); + _actSpriteBatch = 0; + _spriteBatchDesc.resize(1); } -void GraphicsDriverBase::OnInit(volatile int *loopTimer) -{ +void GraphicsDriverBase::OnInit(volatile int *loopTimer) { } -void GraphicsDriverBase::OnUnInit() -{ +void GraphicsDriverBase::OnUnInit() { } -void GraphicsDriverBase::OnModeSet(const DisplayMode &mode) -{ - _mode = mode; +void GraphicsDriverBase::OnModeSet(const DisplayMode &mode) { + _mode = mode; } -void GraphicsDriverBase::OnModeReleased() -{ - _mode = DisplayMode(); - _dstRect = Rect(); +void GraphicsDriverBase::OnModeReleased() { + _mode = DisplayMode(); + _dstRect = Rect(); } -void GraphicsDriverBase::OnScalingChanged() -{ - PGfxFilter filter = GetGraphicsFilter(); - if (filter) - _filterRect = filter->SetTranslation(_srcRect.GetSize(), _dstRect); - else - _filterRect = Rect(); - _scaling.Init(_srcRect.GetSize(), _dstRect); +void GraphicsDriverBase::OnScalingChanged() { + PGfxFilter filter = GetGraphicsFilter(); + if (filter) + _filterRect = filter->SetTranslation(_srcRect.GetSize(), _dstRect); + else + _filterRect = Rect(); + _scaling.Init(_srcRect.GetSize(), _dstRect); } -void GraphicsDriverBase::OnSetNativeSize(const Size &src_size) -{ - _srcRect = RectWH(0, 0, src_size.Width, src_size.Height); - OnScalingChanged(); +void GraphicsDriverBase::OnSetNativeSize(const Size &src_size) { + _srcRect = RectWH(0, 0, src_size.Width, src_size.Height); + OnScalingChanged(); - // Adjust default sprite batch making it comply to native size - _spriteBatchDesc[0].Viewport = RectWH(src_size); - InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]); + // Adjust default sprite batch making it comply to native size + _spriteBatchDesc[0].Viewport = RectWH(src_size); + InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]); } -void GraphicsDriverBase::OnSetRenderFrame(const Rect &dst_rect) -{ - _dstRect = dst_rect; - OnScalingChanged(); +void GraphicsDriverBase::OnSetRenderFrame(const Rect &dst_rect) { + _dstRect = dst_rect; + OnScalingChanged(); } -void GraphicsDriverBase::OnSetFilter() -{ - _filterRect = GetGraphicsFilter()->SetTranslation(Size(_srcRect.GetSize()), _dstRect); +void GraphicsDriverBase::OnSetFilter() { + _filterRect = GetGraphicsFilter()->SetTranslation(Size(_srcRect.GetSize()), _dstRect); } VideoMemoryGraphicsDriver::VideoMemoryGraphicsDriver() - : _stageVirtualScreenDDB(nullptr) - , _stageScreenDirty(false) - , _fxIndex(0) -{ - // Only to have something meaningful as default - _vmem_a_shift_32 = 24; - _vmem_r_shift_32 = 16; - _vmem_g_shift_32 = 8; - _vmem_b_shift_32 = 0; -} - -VideoMemoryGraphicsDriver::~VideoMemoryGraphicsDriver() -{ - DestroyAllStageScreens(); -} - -bool VideoMemoryGraphicsDriver::UsesMemoryBackBuffer() -{ - // Although we do use ours, we do not let engine draw upon it; - // only plugin handling are allowed to request our mem buffer. - // TODO: find better workaround? - return false; -} - -Bitmap *VideoMemoryGraphicsDriver::GetMemoryBackBuffer() -{ - return nullptr; -} - -void VideoMemoryGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) -{ // do nothing, video-memory drivers don't use main back buffer, only stage bitmaps they pass to plugins -} - -Bitmap *VideoMemoryGraphicsDriver::GetStageBackBuffer() -{ - _stageScreenDirty = true; - return _stageVirtualScreen.get(); -} - -PBitmap VideoMemoryGraphicsDriver::CreateStageScreen(size_t index, const Size &sz) -{ - if (_stageScreens.size() <= index) - _stageScreens.resize(index + 1); - if (sz.IsNull()) - _stageScreens[index].reset(); - else if (_stageScreens[index] == nullptr || _stageScreens[index]->GetSize() != sz) - _stageScreens[index].reset(new Bitmap(sz.Width, sz.Height, _mode.ColorDepth)); - return _stageScreens[index]; -} - -PBitmap VideoMemoryGraphicsDriver::GetStageScreen(size_t index) -{ - if (index < _stageScreens.size()) - return _stageScreens[index]; - return nullptr; -} - -void VideoMemoryGraphicsDriver::DestroyAllStageScreens() -{ - if (_stageVirtualScreenDDB) - this->DestroyDDB(_stageVirtualScreenDDB); - _stageVirtualScreenDDB = nullptr; - - for (size_t i = 0; i < _stageScreens.size(); ++i) - _stageScreens[i].reset(); - _stageVirtualScreen.reset(); -} - -bool VideoMemoryGraphicsDriver::DoNullSpriteCallback(int x, int y) -{ - if (!_nullSpriteCallback) - throw Ali3DException("Unhandled attempt to draw null sprite"); - _stageScreenDirty = false; - _stageVirtualScreen->ClearTransparent(); - // NOTE: this is not clear whether return value of callback may be - // relied on. Existing plugins do not seem to return anything but 0, - // even if they handle this event. - _nullSpriteCallback(x, y); - if (_stageScreenDirty) - { - if (_stageVirtualScreenDDB) - UpdateDDBFromBitmap(_stageVirtualScreenDDB, _stageVirtualScreen.get(), true); - else - _stageVirtualScreenDDB = CreateDDBFromBitmap(_stageVirtualScreen.get(), true); - return true; - } - return false; -} - -IDriverDependantBitmap *VideoMemoryGraphicsDriver::MakeFx(int r, int g, int b) -{ - if (_fxIndex == _fxPool.size()) _fxPool.push_back(ScreenFx()); - ScreenFx &fx = _fxPool[_fxIndex]; - if (fx.DDB == nullptr) - { - fx.Raw = BitmapHelper::CreateBitmap(16, 16, _mode.ColorDepth); - fx.DDB = CreateDDBFromBitmap(fx.Raw, false, true); - } - if (r != fx.Red || g != fx.Green || b != fx.Blue) - { - fx.Raw->Clear(makecol_depth(fx.Raw->GetColorDepth(), r, g, b)); - this->UpdateDDBFromBitmap(fx.DDB, fx.Raw, false); - fx.Red = r; - fx.Green = g; - fx.Blue = b; - } - _fxIndex++; - return fx.DDB; -} - -void VideoMemoryGraphicsDriver::ResetFxPool() -{ - _fxIndex = 0; -} - -void VideoMemoryGraphicsDriver::DestroyFxPool() -{ - for (auto &fx : _fxPool) - { - if (fx.DDB) - DestroyDDB(fx.DDB); - delete fx.Raw; - } - _fxPool.clear(); - _fxIndex = 0; + : _stageVirtualScreenDDB(nullptr) + , _stageScreenDirty(false) + , _fxIndex(0) { + // Only to have something meaningful as default + _vmem_a_shift_32 = 24; + _vmem_r_shift_32 = 16; + _vmem_g_shift_32 = 8; + _vmem_b_shift_32 = 0; +} + +VideoMemoryGraphicsDriver::~VideoMemoryGraphicsDriver() { + DestroyAllStageScreens(); +} + +bool VideoMemoryGraphicsDriver::UsesMemoryBackBuffer() { + // Although we do use ours, we do not let engine draw upon it; + // only plugin handling are allowed to request our mem buffer. + // TODO: find better workaround? + return false; +} + +Bitmap *VideoMemoryGraphicsDriver::GetMemoryBackBuffer() { + return nullptr; +} + +void VideoMemoryGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) { + // do nothing, video-memory drivers don't use main back buffer, only stage bitmaps they pass to plugins +} + +Bitmap *VideoMemoryGraphicsDriver::GetStageBackBuffer() { + _stageScreenDirty = true; + return _stageVirtualScreen.get(); +} + +PBitmap VideoMemoryGraphicsDriver::CreateStageScreen(size_t index, const Size &sz) { + if (_stageScreens.size() <= index) + _stageScreens.resize(index + 1); + if (sz.IsNull()) + _stageScreens[index].reset(); + else if (_stageScreens[index] == nullptr || _stageScreens[index]->GetSize() != sz) + _stageScreens[index].reset(new Bitmap(sz.Width, sz.Height, _mode.ColorDepth)); + return _stageScreens[index]; +} + +PBitmap VideoMemoryGraphicsDriver::GetStageScreen(size_t index) { + if (index < _stageScreens.size()) + return _stageScreens[index]; + return nullptr; +} + +void VideoMemoryGraphicsDriver::DestroyAllStageScreens() { + if (_stageVirtualScreenDDB) + this->DestroyDDB(_stageVirtualScreenDDB); + _stageVirtualScreenDDB = nullptr; + + for (size_t i = 0; i < _stageScreens.size(); ++i) + _stageScreens[i].reset(); + _stageVirtualScreen.reset(); +} + +bool VideoMemoryGraphicsDriver::DoNullSpriteCallback(int x, int y) { + if (!_nullSpriteCallback) + throw Ali3DException("Unhandled attempt to draw null sprite"); + _stageScreenDirty = false; + _stageVirtualScreen->ClearTransparent(); + // NOTE: this is not clear whether return value of callback may be + // relied on. Existing plugins do not seem to return anything but 0, + // even if they handle this event. + _nullSpriteCallback(x, y); + if (_stageScreenDirty) { + if (_stageVirtualScreenDDB) + UpdateDDBFromBitmap(_stageVirtualScreenDDB, _stageVirtualScreen.get(), true); + else + _stageVirtualScreenDDB = CreateDDBFromBitmap(_stageVirtualScreen.get(), true); + return true; + } + return false; +} + +IDriverDependantBitmap *VideoMemoryGraphicsDriver::MakeFx(int r, int g, int b) { + if (_fxIndex == _fxPool.size()) _fxPool.push_back(ScreenFx()); + ScreenFx &fx = _fxPool[_fxIndex]; + if (fx.DDB == nullptr) { + fx.Raw = BitmapHelper::CreateBitmap(16, 16, _mode.ColorDepth); + fx.DDB = CreateDDBFromBitmap(fx.Raw, false, true); + } + if (r != fx.Red || g != fx.Green || b != fx.Blue) { + fx.Raw->Clear(makecol_depth(fx.Raw->GetColorDepth(), r, g, b)); + this->UpdateDDBFromBitmap(fx.DDB, fx.Raw, false); + fx.Red = r; + fx.Green = g; + fx.Blue = b; + } + _fxIndex++; + return fx.DDB; +} + +void VideoMemoryGraphicsDriver::ResetFxPool() { + _fxIndex = 0; +} + +void VideoMemoryGraphicsDriver::DestroyFxPool() { + for (auto &fx : _fxPool) { + if (fx.DDB) + DestroyDDB(fx.DDB); + delete fx.Raw; + } + _fxPool.clear(); + _fxIndex = 0; } @@ -285,221 +250,182 @@ void VideoMemoryGraphicsDriver::DestroyFxPool() #define algetb8(c) getb8(c) -__inline void get_pixel_if_not_transparent8(unsigned char *pixel, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *divisor) -{ - if (pixel[0] != MASK_COLOR_8) - { - *red += algetr8(pixel[0]); - *green += algetg8(pixel[0]); - *blue += algetb8(pixel[0]); - divisor[0]++; - } +__inline void get_pixel_if_not_transparent8(unsigned char *pixel, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *divisor) { + if (pixel[0] != MASK_COLOR_8) { + *red += algetr8(pixel[0]); + *green += algetg8(pixel[0]); + *blue += algetb8(pixel[0]); + divisor[0]++; + } } -__inline void get_pixel_if_not_transparent16(unsigned short *pixel, unsigned short *red, unsigned short *green, unsigned short *blue, unsigned short *divisor) -{ - if (pixel[0] != MASK_COLOR_16) - { - *red += algetr16(pixel[0]); - *green += algetg16(pixel[0]); - *blue += algetb16(pixel[0]); - divisor[0]++; - } +__inline void get_pixel_if_not_transparent16(unsigned short *pixel, unsigned short *red, unsigned short *green, unsigned short *blue, unsigned short *divisor) { + if (pixel[0] != MASK_COLOR_16) { + *red += algetr16(pixel[0]); + *green += algetg16(pixel[0]); + *blue += algetb16(pixel[0]); + divisor[0]++; + } } -__inline void get_pixel_if_not_transparent32(unsigned int *pixel, unsigned int *red, unsigned int *green, unsigned int *blue, unsigned int *divisor) -{ - if (pixel[0] != MASK_COLOR_32) - { - *red += algetr32(pixel[0]); - *green += algetg32(pixel[0]); - *blue += algetb32(pixel[0]); - divisor[0]++; - } +__inline void get_pixel_if_not_transparent32(unsigned int *pixel, unsigned int *red, unsigned int *green, unsigned int *blue, unsigned int *divisor) { + if (pixel[0] != MASK_COLOR_32) { + *red += algetr32(pixel[0]); + *green += algetg32(pixel[0]); + *blue += algetb32(pixel[0]); + divisor[0]++; + } } #define VMEMCOLOR_RGBA(r,g,b,a) \ - ( (((a) & 0xFF) << _vmem_a_shift_32) | (((r) & 0xFF) << _vmem_r_shift_32) | (((g) & 0xFF) << _vmem_g_shift_32) | (((b) & 0xFF) << _vmem_b_shift_32) ) + ( (((a) & 0xFF) << _vmem_a_shift_32) | (((r) & 0xFF) << _vmem_r_shift_32) | (((g) & 0xFF) << _vmem_g_shift_32) | (((b) & 0xFF) << _vmem_b_shift_32) ) void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, - char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering) -{ - const int src_depth = bitmap->GetColorDepth(); - bool lastPixelWasTransparent = false; - for (int y = 0; y < tile->height; y++) - { - lastPixelWasTransparent = false; - const uint8_t *scanline_before = bitmap->GetScanLine(y + tile->y - 1); - const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); - const uint8_t *scanline_after = bitmap->GetScanLine(y + tile->y + 1); - unsigned int* memPtrLong = (unsigned int*)dst_ptr; - - for (int x = 0; x < tile->width; x++) - { - if (src_depth == 8) - { - unsigned char* srcData = (unsigned char*)&scanline_at[(x + tile->x) * sizeof(char)]; - if (*srcData == MASK_COLOR_8) - { - if (!usingLinearFiltering) - memPtrLong[x] = 0; - // set to transparent, but use the colour from the neighbouring - // pixel to stop the linear filter doing black outlines - else - { - unsigned char red = 0, green = 0, blue = 0, divisor = 0; - if (x > 0) - get_pixel_if_not_transparent8(&srcData[-1], &red, &green, &blue, &divisor); - if (x < tile->width - 1) - get_pixel_if_not_transparent8(&srcData[1], &red, &green, &blue, &divisor); - if (y > 0) - get_pixel_if_not_transparent8((unsigned char*)&scanline_before[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); - if (y < tile->height - 1) - get_pixel_if_not_transparent8((unsigned char*)&scanline_after[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); - if (divisor > 0) - memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); - else - memPtrLong[x] = 0; - } - lastPixelWasTransparent = true; - } - else - { - memPtrLong[x] = VMEMCOLOR_RGBA(algetr8(*srcData), algetg8(*srcData), algetb8(*srcData), 0xFF); - if (lastPixelWasTransparent) - { - // update the colour of the previous tranparent pixel, to - // stop black outlines when linear filtering - memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; - lastPixelWasTransparent = false; - } - } - } - else if (src_depth == 16) - { - unsigned short* srcData = (unsigned short*)&scanline_at[(x + tile->x) * sizeof(short)]; - if (*srcData == MASK_COLOR_16) - { - if (!usingLinearFiltering) - memPtrLong[x] = 0; - // set to transparent, but use the colour from the neighbouring - // pixel to stop the linear filter doing black outlines - else - { - unsigned short red = 0, green = 0, blue = 0, divisor = 0; - if (x > 0) - get_pixel_if_not_transparent16(&srcData[-1], &red, &green, &blue, &divisor); - if (x < tile->width - 1) - get_pixel_if_not_transparent16(&srcData[1], &red, &green, &blue, &divisor); - if (y > 0) - get_pixel_if_not_transparent16((unsigned short*)&scanline_before[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); - if (y < tile->height - 1) - get_pixel_if_not_transparent16((unsigned short*)&scanline_after[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); - if (divisor > 0) - memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); - else - memPtrLong[x] = 0; - } - lastPixelWasTransparent = true; - } - else - { - memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); - if (lastPixelWasTransparent) - { - // update the colour of the previous tranparent pixel, to - // stop black outlines when linear filtering - memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; - lastPixelWasTransparent = false; - } - } - } - else if (src_depth == 32) - { - unsigned int* memPtrLong = (unsigned int*)dst_ptr; - unsigned int* srcData = (unsigned int*)&scanline_at[(x + tile->x) * sizeof(int)]; - if (*srcData == MASK_COLOR_32) - { - if (!usingLinearFiltering) - memPtrLong[x] = 0; - // set to transparent, but use the colour from the neighbouring - // pixel to stop the linear filter doing black outlines - else - { - unsigned int red = 0, green = 0, blue = 0, divisor = 0; - if (x > 0) - get_pixel_if_not_transparent32(&srcData[-1], &red, &green, &blue, &divisor); - if (x < tile->width - 1) - get_pixel_if_not_transparent32(&srcData[1], &red, &green, &blue, &divisor); - if (y > 0) - get_pixel_if_not_transparent32((unsigned int*)&scanline_before[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); - if (y < tile->height - 1) - get_pixel_if_not_transparent32((unsigned int*)&scanline_after[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); - if (divisor > 0) - memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); - else - memPtrLong[x] = 0; - } - lastPixelWasTransparent = true; - } - else if (has_alpha) - { - memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); - } - else - { - memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); - if (lastPixelWasTransparent) - { - // update the colour of the previous tranparent pixel, to - // stop black outlines when linear filtering - memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; - lastPixelWasTransparent = false; - } - } - } - } - - dst_ptr += dst_pitch; - } + char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering) { + const int src_depth = bitmap->GetColorDepth(); + bool lastPixelWasTransparent = false; + for (int y = 0; y < tile->height; y++) { + lastPixelWasTransparent = false; + const uint8_t *scanline_before = bitmap->GetScanLine(y + tile->y - 1); + const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); + const uint8_t *scanline_after = bitmap->GetScanLine(y + tile->y + 1); + unsigned int *memPtrLong = (unsigned int *)dst_ptr; + + for (int x = 0; x < tile->width; x++) { + if (src_depth == 8) { + unsigned char *srcData = (unsigned char *)&scanline_at[(x + tile->x) * sizeof(char)]; + if (*srcData == MASK_COLOR_8) { + if (!usingLinearFiltering) + memPtrLong[x] = 0; + // set to transparent, but use the colour from the neighbouring + // pixel to stop the linear filter doing black outlines + else { + unsigned char red = 0, green = 0, blue = 0, divisor = 0; + if (x > 0) + get_pixel_if_not_transparent8(&srcData[-1], &red, &green, &blue, &divisor); + if (x < tile->width - 1) + get_pixel_if_not_transparent8(&srcData[1], &red, &green, &blue, &divisor); + if (y > 0) + get_pixel_if_not_transparent8((unsigned char *)&scanline_before[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); + if (y < tile->height - 1) + get_pixel_if_not_transparent8((unsigned char *)&scanline_after[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); + if (divisor > 0) + memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); + else + memPtrLong[x] = 0; + } + lastPixelWasTransparent = true; + } else { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr8(*srcData), algetg8(*srcData), algetb8(*srcData), 0xFF); + if (lastPixelWasTransparent) { + // update the colour of the previous tranparent pixel, to + // stop black outlines when linear filtering + memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; + lastPixelWasTransparent = false; + } + } + } else if (src_depth == 16) { + unsigned short *srcData = (unsigned short *)&scanline_at[(x + tile->x) * sizeof(short)]; + if (*srcData == MASK_COLOR_16) { + if (!usingLinearFiltering) + memPtrLong[x] = 0; + // set to transparent, but use the colour from the neighbouring + // pixel to stop the linear filter doing black outlines + else { + unsigned short red = 0, green = 0, blue = 0, divisor = 0; + if (x > 0) + get_pixel_if_not_transparent16(&srcData[-1], &red, &green, &blue, &divisor); + if (x < tile->width - 1) + get_pixel_if_not_transparent16(&srcData[1], &red, &green, &blue, &divisor); + if (y > 0) + get_pixel_if_not_transparent16((unsigned short *)&scanline_before[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); + if (y < tile->height - 1) + get_pixel_if_not_transparent16((unsigned short *)&scanline_after[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); + if (divisor > 0) + memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); + else + memPtrLong[x] = 0; + } + lastPixelWasTransparent = true; + } else { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); + if (lastPixelWasTransparent) { + // update the colour of the previous tranparent pixel, to + // stop black outlines when linear filtering + memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; + lastPixelWasTransparent = false; + } + } + } else if (src_depth == 32) { + unsigned int *memPtrLong = (unsigned int *)dst_ptr; + unsigned int *srcData = (unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; + if (*srcData == MASK_COLOR_32) { + if (!usingLinearFiltering) + memPtrLong[x] = 0; + // set to transparent, but use the colour from the neighbouring + // pixel to stop the linear filter doing black outlines + else { + unsigned int red = 0, green = 0, blue = 0, divisor = 0; + if (x > 0) + get_pixel_if_not_transparent32(&srcData[-1], &red, &green, &blue, &divisor); + if (x < tile->width - 1) + get_pixel_if_not_transparent32(&srcData[1], &red, &green, &blue, &divisor); + if (y > 0) + get_pixel_if_not_transparent32((unsigned int *)&scanline_before[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); + if (y < tile->height - 1) + get_pixel_if_not_transparent32((unsigned int *)&scanline_after[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); + if (divisor > 0) + memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); + else + memPtrLong[x] = 0; + } + lastPixelWasTransparent = true; + } else if (has_alpha) { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); + } else { + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); + if (lastPixelWasTransparent) { + // update the colour of the previous tranparent pixel, to + // stop black outlines when linear filtering + memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; + lastPixelWasTransparent = false; + } + } + } + } + + dst_ptr += dst_pitch; + } } void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, - char *dst_ptr, const int dst_pitch) -{ - const int src_depth = bitmap->GetColorDepth(); - for (int y = 0; y < tile->height; y++) - { - const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); - unsigned int* memPtrLong = (unsigned int*)dst_ptr; - - for (int x = 0; x < tile->width; x++) - { - if (src_depth == 8) - { - unsigned char* srcData = (unsigned char*)&scanline_at[(x + tile->x) * sizeof(char)]; - memPtrLong[x] = VMEMCOLOR_RGBA(algetr8(*srcData), algetg8(*srcData), algetb8(*srcData), 0xFF); - } - else if (src_depth == 16) - { - unsigned short* srcData = (unsigned short*)&scanline_at[(x + tile->x) * sizeof(short)]; - memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); - } - else if (src_depth == 32) - { - unsigned int* memPtrLong = (unsigned int*)dst_ptr; - unsigned int* srcData = (unsigned int*)&scanline_at[(x + tile->x) * sizeof(int)]; - if (has_alpha) - memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); - else - memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); - } - } - - dst_ptr += dst_pitch; - } + char *dst_ptr, const int dst_pitch) { + const int src_depth = bitmap->GetColorDepth(); + for (int y = 0; y < tile->height; y++) { + const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); + unsigned int *memPtrLong = (unsigned int *)dst_ptr; + + for (int x = 0; x < tile->width; x++) { + if (src_depth == 8) { + unsigned char *srcData = (unsigned char *)&scanline_at[(x + tile->x) * sizeof(char)]; + memPtrLong[x] = VMEMCOLOR_RGBA(algetr8(*srcData), algetg8(*srcData), algetb8(*srcData), 0xFF); + } else if (src_depth == 16) { + unsigned short *srcData = (unsigned short *)&scanline_at[(x + tile->x) * sizeof(short)]; + memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); + } else if (src_depth == 32) { + unsigned int *memPtrLong = (unsigned int *)dst_ptr; + unsigned int *srcData = (unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; + if (has_alpha) + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); + else + memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); + } + } + + dst_ptr += dst_pitch; + } } } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxdriverbase.h b/engines/ags/engine/gfx/gfxdriverbase.h index ea4a696cfcff..a8200d85b8f0 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.h +++ b/engines/ags/engine/gfx/gfxdriverbase.h @@ -34,226 +34,230 @@ #include "gfx/graphicsdriver.h" #include "util/scaling.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using Common::Bitmap; // Sprite batch, defines viewport and an optional model transformation for the list of sprites -struct SpriteBatchDesc -{ - // View rectangle for positioning and clipping, in resolution coordinates - // (this may be screen or game frame resolution, depending on circumstances) - Rect Viewport; - // Optional model transformation, to be applied to each sprite - SpriteTransform Transform; - // Global node offset applied to the whole batch as the last transform - Point Offset; - // Global node flip applied to the whole batch as the last transform - GlobalFlipType Flip; - // Optional bitmap to draw sprites upon. Used exclusively by the software rendering mode. - PBitmap Surface; - - SpriteBatchDesc() : Flip(kFlip_None) {} - SpriteBatchDesc(const Rect viewport, const SpriteTransform &transform, const Point offset = Point(), - GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) - : Viewport(viewport) - , Transform(transform) - , Offset(offset) - , Flip(flip) - , Surface(surface) - { - } +struct SpriteBatchDesc { + // View rectangle for positioning and clipping, in resolution coordinates + // (this may be screen or game frame resolution, depending on circumstances) + Rect Viewport; + // Optional model transformation, to be applied to each sprite + SpriteTransform Transform; + // Global node offset applied to the whole batch as the last transform + Point Offset; + // Global node flip applied to the whole batch as the last transform + GlobalFlipType Flip; + // Optional bitmap to draw sprites upon. Used exclusively by the software rendering mode. + PBitmap Surface; + + SpriteBatchDesc() : Flip(kFlip_None) {} + SpriteBatchDesc(const Rect viewport, const SpriteTransform &transform, const Point offset = Point(), + GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) + : Viewport(viewport) + , Transform(transform) + , Offset(offset) + , Flip(flip) + , Surface(surface) { + } }; typedef std::vector SpriteBatchDescs; // The single sprite entry in the render list template -struct SpriteDrawListEntry -{ - T_DDB *bitmap; // TODO: use shared pointer? - int x, y; // sprite position, in camera coordinates - bool skip; - - SpriteDrawListEntry() - : bitmap(nullptr) - , x(0) - , y(0) - , skip(false) - { - } - - SpriteDrawListEntry(T_DDB *ddb, int x_ = 0, int y_ = 0) - : bitmap(ddb) - , x(x_) - , y(y_) - , skip(false) - { - } +struct SpriteDrawListEntry { + T_DDB *bitmap; // TODO: use shared pointer? + int x, y; // sprite position, in camera coordinates + bool skip; + + SpriteDrawListEntry() + : bitmap(nullptr) + , x(0) + , y(0) + , skip(false) { + } + + SpriteDrawListEntry(T_DDB *ddb, int x_ = 0, int y_ = 0) + : bitmap(ddb) + , x(x_) + , y(y_) + , skip(false) { + } }; // GraphicsDriverBase - is the parent class for all graphics drivers in AGS, // that incapsulates the most common functionality. -class GraphicsDriverBase : public IGraphicsDriver -{ +class GraphicsDriverBase : public IGraphicsDriver { public: - GraphicsDriverBase(); - - bool IsModeSet() const override; - bool IsNativeSizeValid() const override; - bool IsRenderFrameValid() const override; - DisplayMode GetDisplayMode() const override; - Size GetNativeSize() const override; - Rect GetRenderDestination() const override; - - void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, - const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) override; - void ClearDrawLists() override; - - void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) override { _pollingCallback = callback; } - void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) override - { _drawScreenCallback = callback; _drawPostScreenCallback = post_callback; } - void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) override { _initGfxCallback = callback; } - void SetCallbackOnSurfaceUpdate(GFXDRV_CLIENTCALLBACKSURFACEUPDATE callback) override { _initSurfaceUpdateCallback = callback; } - void SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback) override { _nullSpriteCallback = callback; } + GraphicsDriverBase(); + + bool IsModeSet() const override; + bool IsNativeSizeValid() const override; + bool IsRenderFrameValid() const override; + DisplayMode GetDisplayMode() const override; + Size GetNativeSize() const override; + Rect GetRenderDestination() const override; + + void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, + const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) override; + void ClearDrawLists() override; + + void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) override { + _pollingCallback = callback; + } + void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) override { + _drawScreenCallback = callback; + _drawPostScreenCallback = post_callback; + } + void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) override { + _initGfxCallback = callback; + } + void SetCallbackOnSurfaceUpdate(GFXDRV_CLIENTCALLBACKSURFACEUPDATE callback) override { + _initSurfaceUpdateCallback = callback; + } + void SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback) override { + _nullSpriteCallback = callback; + } protected: - // Called after graphics driver was initialized for use for the first time - virtual void OnInit(volatile int *loopTimer); - // Called just before graphics mode is going to be uninitialized and its - // resources released - virtual void OnUnInit(); - // Called after new mode was successfully initialized - virtual void OnModeSet(const DisplayMode &mode); - // Called when the new native size is set - virtual void OnSetNativeSize(const Size &src_size); - // Called before display mode is going to be released - virtual void OnModeReleased(); - // Called when new render frame is set - virtual void OnSetRenderFrame(const Rect &dst_rect); - // Called when the new filter is set - virtual void OnSetFilter(); - // Initialize sprite batch and allocate necessary resources - virtual void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) = 0; - // Clears sprite lists - virtual void ResetAllBatches() = 0; - - void OnScalingChanged(); - - DisplayMode _mode; // display mode settings - Rect _srcRect; // rendering source rect - Rect _dstRect; // rendering destination rect - Rect _filterRect; // filter scaling destination rect (before final scaling) - PlaneScaling _scaling; // native -> render dest coordinate transformation - - // Callbacks - GFXDRV_CLIENTCALLBACK _pollingCallback; - GFXDRV_CLIENTCALLBACK _drawScreenCallback; - GFXDRV_CLIENTCALLBACK _drawPostScreenCallback; - GFXDRV_CLIENTCALLBACKXY _nullSpriteCallback; - GFXDRV_CLIENTCALLBACKINITGFX _initGfxCallback; - GFXDRV_CLIENTCALLBACKSURFACEUPDATE _initSurfaceUpdateCallback; - - // Sprite batch parameters - SpriteBatchDescs _spriteBatchDesc; // sprite batches list - size_t _actSpriteBatch; // active batch index + // Called after graphics driver was initialized for use for the first time + virtual void OnInit(volatile int *loopTimer); + // Called just before graphics mode is going to be uninitialized and its + // resources released + virtual void OnUnInit(); + // Called after new mode was successfully initialized + virtual void OnModeSet(const DisplayMode &mode); + // Called when the new native size is set + virtual void OnSetNativeSize(const Size &src_size); + // Called before display mode is going to be released + virtual void OnModeReleased(); + // Called when new render frame is set + virtual void OnSetRenderFrame(const Rect &dst_rect); + // Called when the new filter is set + virtual void OnSetFilter(); + // Initialize sprite batch and allocate necessary resources + virtual void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) = 0; + // Clears sprite lists + virtual void ResetAllBatches() = 0; + + void OnScalingChanged(); + + DisplayMode _mode; // display mode settings + Rect _srcRect; // rendering source rect + Rect _dstRect; // rendering destination rect + Rect _filterRect; // filter scaling destination rect (before final scaling) + PlaneScaling _scaling; // native -> render dest coordinate transformation + + // Callbacks + GFXDRV_CLIENTCALLBACK _pollingCallback; + GFXDRV_CLIENTCALLBACK _drawScreenCallback; + GFXDRV_CLIENTCALLBACK _drawPostScreenCallback; + GFXDRV_CLIENTCALLBACKXY _nullSpriteCallback; + GFXDRV_CLIENTCALLBACKINITGFX _initGfxCallback; + GFXDRV_CLIENTCALLBACKSURFACEUPDATE _initSurfaceUpdateCallback; + + // Sprite batch parameters + SpriteBatchDescs _spriteBatchDesc; // sprite batches list + size_t _actSpriteBatch; // active batch index }; // Generic TextureTile base -struct TextureTile -{ - int x, y; - int width, height; +struct TextureTile { + int x, y; + int width, height; }; // Parent class for the video memory DDBs -class VideoMemDDB : public IDriverDependantBitmap -{ +class VideoMemDDB : public IDriverDependantBitmap { public: - int GetWidth() override { return _width; } - int GetHeight() override { return _height; } - int GetColorDepth() override { return _colDepth; } - - int _width, _height; - int _colDepth; - bool _opaque; // no mask color + int GetWidth() override { + return _width; + } + int GetHeight() override { + return _height; + } + int GetColorDepth() override { + return _colDepth; + } + + int _width, _height; + int _colDepth; + bool _opaque; // no mask color }; // VideoMemoryGraphicsDriver - is the parent class for the graphic drivers // which drawing method is based on passing the sprite stack into GPU, // rather than blitting to flat screen bitmap. -class VideoMemoryGraphicsDriver : public GraphicsDriverBase -{ +class VideoMemoryGraphicsDriver : public GraphicsDriverBase { public: - VideoMemoryGraphicsDriver(); - ~VideoMemoryGraphicsDriver() override; + VideoMemoryGraphicsDriver(); + ~VideoMemoryGraphicsDriver() override; - bool UsesMemoryBackBuffer() override; - Bitmap *GetMemoryBackBuffer() override; - void SetMemoryBackBuffer(Bitmap *backBuffer) override; - Bitmap* GetStageBackBuffer() override; + bool UsesMemoryBackBuffer() override; + Bitmap *GetMemoryBackBuffer() override; + void SetMemoryBackBuffer(Bitmap *backBuffer) override; + Bitmap *GetStageBackBuffer() override; protected: - // Stage screens are raw bitmap buffers meant to be sent to plugins on demand - // at certain drawing stages. If used at least once these buffers are then - // rendered as additional sprites in their respected order. - PBitmap CreateStageScreen(size_t index, const Size &sz); - PBitmap GetStageScreen(size_t index); - void DestroyAllStageScreens(); - // Use engine callback to acquire replacement for the null sprite; - // returns true if the sprite was provided onto the virtual screen, - // and false if this entry should be skipped. - bool DoNullSpriteCallback(int x, int y); - - // Prepare and get fx item from the pool - IDriverDependantBitmap *MakeFx(int r, int g, int b); - // Resets fx pool counter - void ResetFxPool(); - // Disposes all items in the fx pool - void DestroyFxPool(); - - // Prepares bitmap to be applied to the texture, copies pixels to the provided buffer - void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, - char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering); - // Same but optimized for opaque source bitmaps which ignore transparent "mask color" - void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, - char *dst_ptr, const int dst_pitch); - - // Stage virtual screen is used to let plugins draw custom graphics - // in between render stages (between room and GUI, after GUI, and so on) - PBitmap _stageVirtualScreen; - IDriverDependantBitmap *_stageVirtualScreenDDB; - - // Color component shifts in video bitmap format (set by implementations) - int _vmem_a_shift_32; - int _vmem_r_shift_32; - int _vmem_g_shift_32; - int _vmem_b_shift_32; + // Stage screens are raw bitmap buffers meant to be sent to plugins on demand + // at certain drawing stages. If used at least once these buffers are then + // rendered as additional sprites in their respected order. + PBitmap CreateStageScreen(size_t index, const Size &sz); + PBitmap GetStageScreen(size_t index); + void DestroyAllStageScreens(); + // Use engine callback to acquire replacement for the null sprite; + // returns true if the sprite was provided onto the virtual screen, + // and false if this entry should be skipped. + bool DoNullSpriteCallback(int x, int y); + + // Prepare and get fx item from the pool + IDriverDependantBitmap *MakeFx(int r, int g, int b); + // Resets fx pool counter + void ResetFxPool(); + // Disposes all items in the fx pool + void DestroyFxPool(); + + // Prepares bitmap to be applied to the texture, copies pixels to the provided buffer + void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, + char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering); + // Same but optimized for opaque source bitmaps which ignore transparent "mask color" + void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, + char *dst_ptr, const int dst_pitch); + + // Stage virtual screen is used to let plugins draw custom graphics + // in between render stages (between room and GUI, after GUI, and so on) + PBitmap _stageVirtualScreen; + IDriverDependantBitmap *_stageVirtualScreenDDB; + + // Color component shifts in video bitmap format (set by implementations) + int _vmem_a_shift_32; + int _vmem_r_shift_32; + int _vmem_g_shift_32; + int _vmem_b_shift_32; private: - // Virtual screens for rendering stages (sprite batches) - std::vector _stageScreens; - // Flag which indicates whether stage screen was drawn upon during engine - // callback and has to be inserted into sprite stack. - bool _stageScreenDirty; - - // Fx quads pool (for screen overlay effects) - struct ScreenFx - { - Bitmap *Raw = nullptr; - IDriverDependantBitmap *DDB = nullptr; - int Red = -1; - int Green = -1; - int Blue = -1; - }; - std::vector _fxPool; - size_t _fxIndex; // next free pool item + // Virtual screens for rendering stages (sprite batches) + std::vector _stageScreens; + // Flag which indicates whether stage screen was drawn upon during engine + // callback and has to be inserted into sprite stack. + bool _stageScreenDirty; + + // Fx quads pool (for screen overlay effects) + struct ScreenFx { + Bitmap *Raw = nullptr; + IDriverDependantBitmap *DDB = nullptr; + int Red = -1; + int Green = -1; + int Blue = -1; + }; + std::vector _fxPool; + size_t _fxIndex; // next free pool item }; } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp index a6b379e2c817..4147c8d9475d 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.cpp +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -42,36 +42,32 @@ #include "main/main_allegro.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -void GetGfxDriverFactoryNames(StringV &ids) -{ +void GetGfxDriverFactoryNames(StringV &ids) { #if AGS_HAS_DIRECT3D - ids.push_back("D3D9"); + ids.push_back("D3D9"); #endif #if AGS_HAS_OPENGL - ids.push_back("OGL"); + ids.push_back("OGL"); #endif - ids.push_back("Software"); + ids.push_back("Software"); } -IGfxDriverFactory *GetGfxDriverFactory(const String id) -{ +IGfxDriverFactory *GetGfxDriverFactory(const String id) { #if AGS_HAS_DIRECT3D - if (id.CompareNoCase("D3D9") == 0) - return D3D::D3DGraphicsFactory::GetFactory(); + if (id.CompareNoCase("D3D9") == 0) + return D3D::D3DGraphicsFactory::GetFactory(); #endif #if AGS_HAS_OPENGL - if (id.CompareNoCase("OGL") == 0) - return OGL::OGLGraphicsFactory::GetFactory(); + if (id.CompareNoCase("OGL") == 0) + return OGL::OGLGraphicsFactory::GetFactory(); #endif - if (id.CompareNoCase("Software") == 0) - return ALSW::ALSWGraphicsFactory::GetFactory(); - set_allegro_error("No graphics factory with such id: %s", id.GetCStr()); - return nullptr; + if (id.CompareNoCase("Software") == 0) + return ALSW::ALSWGraphicsFactory::GetFactory(); + set_allegro_error("No graphics factory with such id: %s", id.GetCStr()); + return nullptr; } } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxdriverfactory.h b/engines/ags/engine/gfx/gfxdriverfactory.h index 75e10ef402a4..3fdc220a4d6f 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.h +++ b/engines/ags/engine/gfx/gfxdriverfactory.h @@ -37,10 +37,8 @@ #include "util/string.h" #include "util/string_types.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using Common::String; using Common::StringV; @@ -50,30 +48,29 @@ struct GfxFilterInfo; typedef std::shared_ptr PGfxFilter; -class IGfxDriverFactory -{ +class IGfxDriverFactory { public: - virtual ~IGfxDriverFactory() = default; + virtual ~IGfxDriverFactory() = default; - // Shutdown graphics factory and deallocate any resources it owns; - // graphics factory will be unusable after calling this function. - virtual void Shutdown() = 0; - // Get graphics driver associated with this factory; creates one if - // it does not exist. - virtual IGraphicsDriver * GetDriver() = 0; - // Destroy graphics driver associated with this factory; does nothing - // if one was not created yet, - virtual void DestroyDriver() = 0; + // Shutdown graphics factory and deallocate any resources it owns; + // graphics factory will be unusable after calling this function. + virtual void Shutdown() = 0; + // Get graphics driver associated with this factory; creates one if + // it does not exist. + virtual IGraphicsDriver *GetDriver() = 0; + // Destroy graphics driver associated with this factory; does nothing + // if one was not created yet, + virtual void DestroyDriver() = 0; - // Get number of supported filters - virtual size_t GetFilterCount() const = 0; - // Get filter description - virtual const GfxFilterInfo *GetFilterInfo(size_t index) const = 0; - // Get ID of the default filter - virtual String GetDefaultFilterID() const = 0; + // Get number of supported filters + virtual size_t GetFilterCount() const = 0; + // Get filter description + virtual const GfxFilterInfo *GetFilterInfo(size_t index) const = 0; + // Get ID of the default filter + virtual String GetDefaultFilterID() const = 0; - // Assign specified filter to graphics driver - virtual PGfxFilter SetFilter(const String &id, String &filter_error) = 0; + // Assign specified filter to graphics driver + virtual PGfxFilter SetFilter(const String &id, String &filter_error) = 0; }; // Query the available graphics factory names diff --git a/engines/ags/engine/gfx/gfxdriverfactorybase.h b/engines/ags/engine/gfx/gfxdriverfactorybase.h index 7962d35d8d85..853fe4c5e47a 100644 --- a/engines/ags/engine/gfx/gfxdriverfactorybase.h +++ b/engines/ags/engine/gfx/gfxdriverfactorybase.h @@ -37,81 +37,68 @@ #include "gfx/gfxdriverfactory.h" #include "gfx/gfxfilter.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { template -class GfxDriverFactoryBase : public IGfxDriverFactory -{ +class GfxDriverFactoryBase : public IGfxDriverFactory { protected: - ~GfxDriverFactoryBase() override - { - delete _driver; - } + ~GfxDriverFactoryBase() override { + delete _driver; + } public: - void Shutdown() override - { - delete this; - } - - IGraphicsDriver *GetDriver() override - { - if (!_driver) - _driver = EnsureDriverCreated(); - return _driver; - } - - void DestroyDriver() override - { - delete _driver; - _driver = nullptr; - } - - PGfxFilter SetFilter(const String &id, String &filter_error) override - { - TGfxDriverClass *driver = EnsureDriverCreated(); - if (!driver) - { - filter_error = "Graphics driver was not created"; - return PGfxFilter(); - } - - const int color_depth = driver->GetDisplayMode().ColorDepth; - if (color_depth == 0) - { - filter_error = "Graphics mode is not set"; - return PGfxFilter(); - } - - std::shared_ptr filter(CreateFilter(id)); - if (!filter) - { - filter_error = "Filter does not exist"; - return PGfxFilter(); - } - - if (!filter->Initialize(color_depth, filter_error)) - { - return PGfxFilter(); - } - - driver->SetGraphicsFilter(filter); - return filter; - } + void Shutdown() override { + delete this; + } + + IGraphicsDriver *GetDriver() override { + if (!_driver) + _driver = EnsureDriverCreated(); + return _driver; + } + + void DestroyDriver() override { + delete _driver; + _driver = nullptr; + } + + PGfxFilter SetFilter(const String &id, String &filter_error) override { + TGfxDriverClass *driver = EnsureDriverCreated(); + if (!driver) { + filter_error = "Graphics driver was not created"; + return PGfxFilter(); + } + + const int color_depth = driver->GetDisplayMode().ColorDepth; + if (color_depth == 0) { + filter_error = "Graphics mode is not set"; + return PGfxFilter(); + } + + std::shared_ptr filter(CreateFilter(id)); + if (!filter) { + filter_error = "Filter does not exist"; + return PGfxFilter(); + } + + if (!filter->Initialize(color_depth, filter_error)) { + return PGfxFilter(); + } + + driver->SetGraphicsFilter(filter); + return filter; + } protected: - GfxDriverFactoryBase() - : _driver(nullptr) - { - } + GfxDriverFactoryBase() + : _driver(nullptr) { + } - virtual TGfxDriverClass *EnsureDriverCreated() = 0; - virtual TGfxFilterClass *CreateFilter(const String &id) = 0; + virtual TGfxDriverClass *EnsureDriverCreated() = 0; + virtual TGfxFilterClass *CreateFilter(const String &id) = 0; - TGfxDriverClass *_driver; + TGfxDriverClass *_driver; }; } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxfilter.h b/engines/ags/engine/gfx/gfxfilter.h index 04e937ac845c..25eb03de4b4e 100644 --- a/engines/ags/engine/gfx/gfxfilter.h +++ b/engines/ags/engine/gfx/gfxfilter.h @@ -33,44 +33,40 @@ #include "util/geometry.h" #include "util/string.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using Common::String; -struct GfxFilterInfo -{ - String Id; - String Name; - int MinScale; - int MaxScale; +struct GfxFilterInfo { + String Id; + String Name; + int MinScale; + int MaxScale; - GfxFilterInfo() - {} - GfxFilterInfo(String id, String name, int min_scale = 0, int max_scale = 0) - : Id(id) - , Name(name) - , MinScale(min_scale) - , MaxScale(max_scale) - {} + GfxFilterInfo() { + } + GfxFilterInfo(String id, String name, int min_scale = 0, int max_scale = 0) + : Id(id) + , Name(name) + , MinScale(min_scale) + , MaxScale(max_scale) { + } }; -class IGfxFilter -{ +class IGfxFilter { public: - virtual ~IGfxFilter() = default; + virtual ~IGfxFilter() = default; - virtual const GfxFilterInfo &GetInfo() const = 0; + virtual const GfxFilterInfo &GetInfo() const = 0; - // Init filter for the specified color depth - virtual bool Initialize(const int color_depth, String &err_str) = 0; - virtual void UnInitialize() = 0; - // Try to set rendering translation; returns actual supported destination rect - virtual Rect SetTranslation(const Size src_size, const Rect dst_rect) = 0; - // Get defined destination rect for this filter - virtual Rect GetDestination() const = 0; + // Init filter for the specified color depth + virtual bool Initialize(const int color_depth, String &err_str) = 0; + virtual void UnInitialize() = 0; + // Try to set rendering translation; returns actual supported destination rect + virtual Rect SetTranslation(const Size src_size, const Rect dst_rect) = 0; + // Get defined destination rect for this filter + virtual Rect GetDestination() const = 0; }; typedef std::shared_ptr PGfxFilter; diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp index 57c76eef9343..c09ee706e872 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp @@ -28,32 +28,26 @@ #include #endif -namespace AGS -{ -namespace Engine -{ -namespace D3D -{ +namespace AGS { +namespace Engine { +namespace D3D { const GfxFilterInfo AAD3DGfxFilter::FilterInfo = GfxFilterInfo("Linear", "Linear interpolation"); -const GfxFilterInfo &AAD3DGfxFilter::GetInfo() const -{ - return FilterInfo; +const GfxFilterInfo &AAD3DGfxFilter::GetInfo() const { + return FilterInfo; } -void AAD3DGfxFilter::SetSamplerStateForStandardSprite(void *direct3ddevice9) -{ +void AAD3DGfxFilter::SetSamplerStateForStandardSprite(void *direct3ddevice9) { #if AGS_PLATFORM_OS_WINDOWS - IDirect3DDevice9* d3d9 = ((IDirect3DDevice9*)direct3ddevice9); - d3d9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - d3d9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9 *d3d9 = ((IDirect3DDevice9 *)direct3ddevice9); + d3d9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + d3d9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); #endif } -bool AAD3DGfxFilter::NeedToColourEdgeLines() -{ - return true; +bool AAD3DGfxFilter::NeedToColourEdgeLines() { + return true; } } // namespace D3D diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.h b/engines/ags/engine/gfx/gfxfilter_aad3d.h index e730cde9b27e..4f5c7de75ca8 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.h +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.h @@ -31,22 +31,18 @@ #include "gfx/gfxfilter_d3d.h" -namespace AGS -{ -namespace Engine -{ -namespace D3D -{ - -class AAD3DGfxFilter : public D3DGfxFilter -{ +namespace AGS { +namespace Engine { +namespace D3D { + +class AAD3DGfxFilter : public D3DGfxFilter { public: - const GfxFilterInfo &GetInfo() const override; + const GfxFilterInfo &GetInfo() const override; - void SetSamplerStateForStandardSprite(void *direct3ddevice9) override; - bool NeedToColourEdgeLines() override; + void SetSamplerStateForStandardSprite(void *direct3ddevice9) override; + bool NeedToColourEdgeLines() override; - static const GfxFilterInfo FilterInfo; + static const GfxFilterInfo FilterInfo; }; } // namespace D3D diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp index 3ad5aa9001e0..cb34a0ae49e3 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp @@ -27,29 +27,23 @@ #include "gfx/gfxfilter_aaogl.h" #include "ogl_headers.h" -namespace AGS -{ -namespace Engine -{ -namespace OGL -{ +namespace AGS { +namespace Engine { +namespace OGL { const GfxFilterInfo AAOGLGfxFilter::FilterInfo = GfxFilterInfo("Linear", "Linear interpolation"); -bool AAOGLGfxFilter::UseLinearFiltering() const -{ - return true; +bool AAOGLGfxFilter::UseLinearFiltering() const { + return true; } -void AAOGLGfxFilter::SetFilteringForStandardSprite() -{ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +void AAOGLGfxFilter::SetFilteringForStandardSprite() { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } -const GfxFilterInfo &AAOGLGfxFilter::GetInfo() const -{ - return FilterInfo; +const GfxFilterInfo &AAOGLGfxFilter::GetInfo() const { + return FilterInfo; } } // namespace OGL diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.h b/engines/ags/engine/gfx/gfxfilter_aaogl.h index d8939efce879..3ed266331b34 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.h +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.h @@ -31,22 +31,18 @@ #include "gfx/gfxfilter_ogl.h" -namespace AGS -{ -namespace Engine -{ -namespace OGL -{ - -class AAOGLGfxFilter : public OGLGfxFilter -{ +namespace AGS { +namespace Engine { +namespace OGL { + +class AAOGLGfxFilter : public OGLGfxFilter { public: - const GfxFilterInfo &GetInfo() const override; + const GfxFilterInfo &GetInfo() const override; - bool UseLinearFiltering() const override; - void SetFilteringForStandardSprite() override; + bool UseLinearFiltering() const override; + void SetFilteringForStandardSprite() override; - static const GfxFilterInfo FilterInfo; + static const GfxFilterInfo FilterInfo; }; } // namespace OGL diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index 0d3e5ebc8ff4..47ac6efb2d20 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -22,157 +22,136 @@ #include "gfx/gfxfilter_allegro.h" -namespace AGS -{ -namespace Engine -{ -namespace ALSW -{ +namespace AGS { +namespace Engine { +namespace ALSW { using namespace Common; const GfxFilterInfo AllegroGfxFilter::FilterInfo = GfxFilterInfo("StdScale", "Nearest-neighbour"); AllegroGfxFilter::AllegroGfxFilter() - : realScreen(nullptr) - , virtualScreen(nullptr) - , realScreenSizedBuffer(nullptr) - , lastBlitFrom(nullptr) - , lastBlitX(0) - , lastBlitY(0) -{ + : realScreen(nullptr) + , virtualScreen(nullptr) + , realScreenSizedBuffer(nullptr) + , lastBlitFrom(nullptr) + , lastBlitX(0) + , lastBlitY(0) { } -const GfxFilterInfo &AllegroGfxFilter::GetInfo() const -{ - return FilterInfo; +const GfxFilterInfo &AllegroGfxFilter::GetInfo() const { + return FilterInfo; } -Bitmap* AllegroGfxFilter::InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) -{ - ShutdownAndReturnRealScreen(); - - realScreen = screen; - SetTranslation(src_size, dst_rect); - - if (src_size == dst_rect.GetSize() && dst_rect.Top == 0 && dst_rect.Left == 0) - { - // Speed up software rendering if no scaling is performed - realScreenSizedBuffer = nullptr; - virtualScreen = realScreen; - } - else - { - realScreenSizedBuffer = BitmapHelper::CreateBitmap(screen->GetWidth(), screen->GetHeight(), screen->GetColorDepth()); - virtualScreen = BitmapHelper::CreateBitmap(src_size.Width, src_size.Height, screen->GetColorDepth()); - } - return virtualScreen; +Bitmap *AllegroGfxFilter::InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) { + ShutdownAndReturnRealScreen(); + + realScreen = screen; + SetTranslation(src_size, dst_rect); + + if (src_size == dst_rect.GetSize() && dst_rect.Top == 0 && dst_rect.Left == 0) { + // Speed up software rendering if no scaling is performed + realScreenSizedBuffer = nullptr; + virtualScreen = realScreen; + } else { + realScreenSizedBuffer = BitmapHelper::CreateBitmap(screen->GetWidth(), screen->GetHeight(), screen->GetColorDepth()); + virtualScreen = BitmapHelper::CreateBitmap(src_size.Width, src_size.Height, screen->GetColorDepth()); + } + return virtualScreen; } -Bitmap *AllegroGfxFilter::ShutdownAndReturnRealScreen() -{ - if (virtualScreen != realScreen) - delete virtualScreen; - delete realScreenSizedBuffer; - virtualScreen = nullptr; - realScreenSizedBuffer = nullptr; - Bitmap *real_scr = realScreen; - realScreen = nullptr; - return real_scr; +Bitmap *AllegroGfxFilter::ShutdownAndReturnRealScreen() { + if (virtualScreen != realScreen) + delete virtualScreen; + delete realScreenSizedBuffer; + virtualScreen = nullptr; + realScreenSizedBuffer = nullptr; + Bitmap *real_scr = realScreen; + realScreen = nullptr; + return real_scr; } void AllegroGfxFilter::RenderScreen(Bitmap *toRender, int x, int y) { - if (toRender != realScreen) - { - x = _scaling.X.ScalePt(x); - y = _scaling.Y.ScalePt(y); - const int width = _scaling.X.ScaleDistance(toRender->GetWidth()); - const int height = _scaling.Y.ScaleDistance(toRender->GetHeight()); - Bitmap *render_src = PreRenderPass(toRender); - if (render_src->GetSize() == _dstRect.GetSize()) - realScreen->Blit(render_src, 0, 0, x, y, width, height); - else - { - realScreen->StretchBlt(render_src, RectWH(x, y, width, height)); - } - } - lastBlitFrom = toRender; - lastBlitX = x; - lastBlitY = y; + if (toRender != realScreen) { + x = _scaling.X.ScalePt(x); + y = _scaling.Y.ScalePt(y); + const int width = _scaling.X.ScaleDistance(toRender->GetWidth()); + const int height = _scaling.Y.ScaleDistance(toRender->GetHeight()); + Bitmap *render_src = PreRenderPass(toRender); + if (render_src->GetSize() == _dstRect.GetSize()) + realScreen->Blit(render_src, 0, 0, x, y, width, height); + else { + realScreen->StretchBlt(render_src, RectWH(x, y, width, height)); + } + } + lastBlitFrom = toRender; + lastBlitX = x; + lastBlitY = y; } void AllegroGfxFilter::RenderScreenFlipped(Bitmap *toRender, int x, int y, GlobalFlipType flipType) { - if (toRender == virtualScreen) - return; - - switch (flipType) - { - case kFlip_Horizontal: - virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HFlip); - break; - case kFlip_Vertical: - virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_VFlip); - break; - case kFlip_Both: - virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HVFlip); - break; - default: - virtualScreen->Blit(toRender, 0, 0); - break; - } - - RenderScreen(virtualScreen, x, y); + if (toRender == virtualScreen) + return; + + switch (flipType) { + case kFlip_Horizontal: + virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HFlip); + break; + case kFlip_Vertical: + virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_VFlip); + break; + case kFlip_Both: + virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HVFlip); + break; + default: + virtualScreen->Blit(toRender, 0, 0); + break; + } + + RenderScreen(virtualScreen, x, y); } -void AllegroGfxFilter::ClearRect(int x1, int y1, int x2, int y2, int color) -{ - if (!realScreen) return; - Rect r = _scaling.ScaleRange(Rect(x1, y1, x2, y2)); - realScreen->FillRect(r, color); +void AllegroGfxFilter::ClearRect(int x1, int y1, int x2, int y2, int color) { + if (!realScreen) return; + Rect r = _scaling.ScaleRange(Rect(x1, y1, x2, y2)); + realScreen->FillRect(r, color); } -void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap) -{ - GetCopyOfScreenIntoBitmap(copyBitmap, true); +void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap) { + GetCopyOfScreenIntoBitmap(copyBitmap, true); } -void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_with_yoffset) -{ - if (copyBitmap == realScreen) - return; - - if (!copy_with_yoffset) - { - if (copyBitmap->GetSize() == _dstRect.GetSize()) - copyBitmap->Blit(realScreen, _dstRect.Left, _dstRect.Top, 0, 0, _dstRect.GetWidth(), _dstRect.GetHeight()); - else - { - // Can't stretch_blit from Video Memory to normal memory, - // so copy the screen to a buffer first. - realScreenSizedBuffer->Blit(realScreen, 0, 0); - copyBitmap->StretchBlt(realScreenSizedBuffer, - _dstRect, - RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); - } - } - else if (!lastBlitFrom) - copyBitmap->Fill(0); - else if (copyBitmap->GetSize() == _dstRect.GetSize()) - copyBitmap->Blit(realScreen, lastBlitX, lastBlitY, 0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight()); - else - { - copyBitmap->StretchBlt(lastBlitFrom, - RectWH(0, 0, lastBlitFrom->GetWidth(), lastBlitFrom->GetHeight()), - RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); - } +void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_with_yoffset) { + if (copyBitmap == realScreen) + return; + + if (!copy_with_yoffset) { + if (copyBitmap->GetSize() == _dstRect.GetSize()) + copyBitmap->Blit(realScreen, _dstRect.Left, _dstRect.Top, 0, 0, _dstRect.GetWidth(), _dstRect.GetHeight()); + else { + // Can't stretch_blit from Video Memory to normal memory, + // so copy the screen to a buffer first. + realScreenSizedBuffer->Blit(realScreen, 0, 0); + copyBitmap->StretchBlt(realScreenSizedBuffer, + _dstRect, + RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); + } + } else if (!lastBlitFrom) + copyBitmap->Fill(0); + else if (copyBitmap->GetSize() == _dstRect.GetSize()) + copyBitmap->Blit(realScreen, lastBlitX, lastBlitY, 0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight()); + else { + copyBitmap->StretchBlt(lastBlitFrom, + RectWH(0, 0, lastBlitFrom->GetWidth(), lastBlitFrom->GetHeight()), + RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); + } } -Bitmap *AllegroGfxFilter::PreRenderPass(Bitmap *toRender) -{ - // do nothing by default - return toRender; +Bitmap *AllegroGfxFilter::PreRenderPass(Bitmap *toRender) { + // do nothing by default + return toRender; } } // namespace ALSW diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h index 9c2497740ead..c2982344f90e 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.h +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -33,45 +33,41 @@ #include "gfx/gfxfilter_scaling.h" #include "gfx/gfxdefines.h" -namespace AGS -{ -namespace Engine -{ -namespace ALSW -{ +namespace AGS { +namespace Engine { +namespace ALSW { using Common::Bitmap; -class AllegroGfxFilter : public ScalingGfxFilter -{ +class AllegroGfxFilter : public ScalingGfxFilter { public: - AllegroGfxFilter(); + AllegroGfxFilter(); - const GfxFilterInfo &GetInfo() const override; - - virtual Bitmap *InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect); - virtual Bitmap *ShutdownAndReturnRealScreen(); - virtual void RenderScreen(Bitmap *toRender, int x, int y); - virtual void RenderScreenFlipped(Bitmap *toRender, int x, int y, GlobalFlipType flipType); - virtual void ClearRect(int x1, int y1, int x2, int y2, int color); - virtual void GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap); - virtual void GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_with_yoffset); + const GfxFilterInfo &GetInfo() const override; - static const GfxFilterInfo FilterInfo; + virtual Bitmap *InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect); + virtual Bitmap *ShutdownAndReturnRealScreen(); + virtual void RenderScreen(Bitmap *toRender, int x, int y); + virtual void RenderScreenFlipped(Bitmap *toRender, int x, int y, GlobalFlipType flipType); + virtual void ClearRect(int x1, int y1, int x2, int y2, int color); + virtual void GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap); + virtual void GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_with_yoffset); + + static const GfxFilterInfo FilterInfo; protected: - virtual Bitmap *PreRenderPass(Bitmap *toRender); + virtual Bitmap *PreRenderPass(Bitmap *toRender); - // pointer to real screen bitmap - Bitmap *realScreen; - // bitmap the size of game resolution - Bitmap *virtualScreen; - // buffer for making a copy of video memory before stretching - // for screen capture - Bitmap *realScreenSizedBuffer; - Bitmap *lastBlitFrom; - int lastBlitX; - int lastBlitY; + // pointer to real screen bitmap + Bitmap *realScreen; + // bitmap the size of game resolution + Bitmap *virtualScreen; + // buffer for making a copy of video memory before stretching + // for screen capture + Bitmap *realScreenSizedBuffer; + Bitmap *lastBlitFrom; + int lastBlitX; + int lastBlitY; }; } // namespace ALSW diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.cpp b/engines/ags/engine/gfx/gfxfilter_d3d.cpp index b3a8dd84d7ad..4ed4890b087a 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_d3d.cpp @@ -26,32 +26,26 @@ #include #endif -namespace AGS -{ -namespace Engine -{ -namespace D3D -{ +namespace AGS { +namespace Engine { +namespace D3D { const GfxFilterInfo D3DGfxFilter::FilterInfo = GfxFilterInfo("StdScale", "Nearest-neighbour"); -const GfxFilterInfo &D3DGfxFilter::GetInfo() const -{ - return FilterInfo; +const GfxFilterInfo &D3DGfxFilter::GetInfo() const { + return FilterInfo; } -void D3DGfxFilter::SetSamplerStateForStandardSprite(void *direct3ddevice9) -{ +void D3DGfxFilter::SetSamplerStateForStandardSprite(void *direct3ddevice9) { #if AGS_PLATFORM_OS_WINDOWS - IDirect3DDevice9* d3d9 = ((IDirect3DDevice9*)direct3ddevice9); - d3d9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - d3d9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + IDirect3DDevice9 *d3d9 = ((IDirect3DDevice9 *)direct3ddevice9); + d3d9->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + d3d9->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); #endif } -bool D3DGfxFilter::NeedToColourEdgeLines() -{ - return false; +bool D3DGfxFilter::NeedToColourEdgeLines() { + return false; } } // namespace D3D diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.h b/engines/ags/engine/gfx/gfxfilter_d3d.h index 1b1798c2cc92..2db3af5d328c 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.h +++ b/engines/ags/engine/gfx/gfxfilter_d3d.h @@ -31,22 +31,18 @@ #include "gfx/gfxfilter_scaling.h" -namespace AGS -{ -namespace Engine -{ -namespace D3D -{ - -class D3DGfxFilter : public ScalingGfxFilter -{ +namespace AGS { +namespace Engine { +namespace D3D { + +class D3DGfxFilter : public ScalingGfxFilter { public: - const GfxFilterInfo &GetInfo() const override; + const GfxFilterInfo &GetInfo() const override; - virtual void SetSamplerStateForStandardSprite(void *direct3ddevice9); - virtual bool NeedToColourEdgeLines(); + virtual void SetSamplerStateForStandardSprite(void *direct3ddevice9); + virtual bool NeedToColourEdgeLines(); - static const GfxFilterInfo FilterInfo; + static const GfxFilterInfo FilterInfo; }; } // namespace D3D diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp index d25347bf4cbd..082fc906a7db 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.cpp +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -24,75 +24,64 @@ #include "gfx/gfxfilter_hqx.h" #include "gfx/hq2x3x.h" -namespace AGS -{ -namespace Engine -{ -namespace ALSW -{ +namespace AGS { +namespace Engine { +namespace ALSW { using namespace Common; const GfxFilterInfo HqxGfxFilter::FilterInfo = GfxFilterInfo("Hqx", "Hqx (High Quality)", 2, 3); HqxGfxFilter::HqxGfxFilter() - : _pfnHqx(nullptr) - , _hqxScalingBuffer(nullptr) -{ + : _pfnHqx(nullptr) + , _hqxScalingBuffer(nullptr) { } -HqxGfxFilter::~HqxGfxFilter() -{ - delete _hqxScalingBuffer; +HqxGfxFilter::~HqxGfxFilter() { + delete _hqxScalingBuffer; } -const GfxFilterInfo &HqxGfxFilter::GetInfo() const -{ - return FilterInfo; +const GfxFilterInfo &HqxGfxFilter::GetInfo() const { + return FilterInfo; } -bool HqxGfxFilter::Initialize(const int color_depth, String &err_str) -{ - if (color_depth < 32) - { - err_str = "Only supports 32-bit colour games"; - return false; - } - return AllegroGfxFilter::Initialize(color_depth, err_str); +bool HqxGfxFilter::Initialize(const int color_depth, String &err_str) { + if (color_depth < 32) { + err_str = "Only supports 32-bit colour games"; + return false; + } + return AllegroGfxFilter::Initialize(color_depth, err_str); } -Bitmap* HqxGfxFilter::InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) -{ - Bitmap *virtual_screen = AllegroGfxFilter::InitVirtualScreen(screen, src_size, dst_rect); +Bitmap *HqxGfxFilter::InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) { + Bitmap *virtual_screen = AllegroGfxFilter::InitVirtualScreen(screen, src_size, dst_rect); - // Choose used algorithm depending on minimal required integer scaling - int min_scaling = Math::Min(dst_rect.GetWidth() / src_size.Width, dst_rect.GetHeight() / src_size.Height); - min_scaling = Math::Clamp(min_scaling, 2, 3); - if (min_scaling == 2) - _pfnHqx = hq2x_32; - else - _pfnHqx = hq3x_32; - _hqxScalingBuffer = BitmapHelper::CreateBitmap(src_size.Width * min_scaling, src_size.Height * min_scaling); + // Choose used algorithm depending on minimal required integer scaling + int min_scaling = Math::Min(dst_rect.GetWidth() / src_size.Width, dst_rect.GetHeight() / src_size.Height); + min_scaling = Math::Clamp(min_scaling, 2, 3); + if (min_scaling == 2) + _pfnHqx = hq2x_32; + else + _pfnHqx = hq3x_32; + _hqxScalingBuffer = BitmapHelper::CreateBitmap(src_size.Width * min_scaling, src_size.Height * min_scaling); - InitLUTs(); - return virtual_screen; + InitLUTs(); + return virtual_screen; } -Bitmap *HqxGfxFilter::ShutdownAndReturnRealScreen() -{ - Bitmap *real_screen = AllegroGfxFilter::ShutdownAndReturnRealScreen(); - delete _hqxScalingBuffer; - _hqxScalingBuffer = nullptr; - return real_screen; +Bitmap *HqxGfxFilter::ShutdownAndReturnRealScreen() { + Bitmap *real_screen = AllegroGfxFilter::ShutdownAndReturnRealScreen(); + delete _hqxScalingBuffer; + _hqxScalingBuffer = nullptr; + return real_screen; } -Bitmap *HqxGfxFilter::PreRenderPass(Bitmap *toRender) -{ - _hqxScalingBuffer->Acquire(); - _pfnHqx(toRender->GetDataForWriting(), _hqxScalingBuffer->GetDataForWriting(), - toRender->GetWidth(), toRender->GetHeight(), _hqxScalingBuffer->GetLineLength()); - _hqxScalingBuffer->Release(); - return _hqxScalingBuffer; +Bitmap *HqxGfxFilter::PreRenderPass(Bitmap *toRender) { + _hqxScalingBuffer->Acquire(); + _pfnHqx(toRender->GetDataForWriting(), _hqxScalingBuffer->GetDataForWriting(), + toRender->GetWidth(), toRender->GetHeight(), _hqxScalingBuffer->GetLineLength()); + _hqxScalingBuffer->Release(); + return _hqxScalingBuffer; } } // namespace ALSW diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h index fc3db3c64f38..b00323a718ca 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.h +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -31,34 +31,30 @@ #include "gfx/gfxfilter_allegro.h" -namespace AGS -{ -namespace Engine -{ -namespace ALSW -{ +namespace AGS { +namespace Engine { +namespace ALSW { -class HqxGfxFilter : public AllegroGfxFilter -{ +class HqxGfxFilter : public AllegroGfxFilter { public: - HqxGfxFilter(); - ~HqxGfxFilter() override; + HqxGfxFilter(); + ~HqxGfxFilter() override; - const GfxFilterInfo &GetInfo() const override; + const GfxFilterInfo &GetInfo() const override; - bool Initialize(const int color_depth, String &err_str) override; - Bitmap *InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) override; - Bitmap *ShutdownAndReturnRealScreen() override; + bool Initialize(const int color_depth, String &err_str) override; + Bitmap *InitVirtualScreen(Bitmap *screen, const Size src_size, const Rect dst_rect) override; + Bitmap *ShutdownAndReturnRealScreen() override; - static const GfxFilterInfo FilterInfo; + static const GfxFilterInfo FilterInfo; protected: - Bitmap *PreRenderPass(Bitmap *toRender) override; + Bitmap *PreRenderPass(Bitmap *toRender) override; - typedef void (*PfnHqx)(unsigned char *in, unsigned char *out, int src_w, int src_h, int bpl); + typedef void (*PfnHqx)(unsigned char *in, unsigned char *out, int src_w, int src_h, int bpl); - PfnHqx _pfnHqx; - Bitmap *_hqxScalingBuffer; + PfnHqx _pfnHqx; + Bitmap *_hqxScalingBuffer; }; } // namespace ALSW diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.cpp b/engines/ags/engine/gfx/gfxfilter_ogl.cpp index 42697b736ba0..7ca95acbb9d0 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_ogl.cpp @@ -27,29 +27,23 @@ #include "gfx/gfxfilter_ogl.h" #include "ogl_headers.h" -namespace AGS -{ -namespace Engine -{ -namespace OGL -{ +namespace AGS { +namespace Engine { +namespace OGL { const GfxFilterInfo OGLGfxFilter::FilterInfo = GfxFilterInfo("StdScale", "Nearest-neighbour"); -bool OGLGfxFilter::UseLinearFiltering() const -{ - return false; +bool OGLGfxFilter::UseLinearFiltering() const { + return false; } -void OGLGfxFilter::SetFilteringForStandardSprite() -{ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +void OGLGfxFilter::SetFilteringForStandardSprite() { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } -const GfxFilterInfo &OGLGfxFilter::GetInfo() const -{ - return FilterInfo; +const GfxFilterInfo &OGLGfxFilter::GetInfo() const { + return FilterInfo; } } // namespace OGL diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.h b/engines/ags/engine/gfx/gfxfilter_ogl.h index 4b90e56c9a9e..194bf95394ec 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.h +++ b/engines/ags/engine/gfx/gfxfilter_ogl.h @@ -31,22 +31,18 @@ #include "gfx/gfxfilter_scaling.h" -namespace AGS -{ -namespace Engine -{ -namespace OGL -{ - -class OGLGfxFilter : public ScalingGfxFilter -{ +namespace AGS { +namespace Engine { +namespace OGL { + +class OGLGfxFilter : public ScalingGfxFilter { public: - const GfxFilterInfo &GetInfo() const override; + const GfxFilterInfo &GetInfo() const override; - virtual bool UseLinearFiltering() const; - virtual void SetFilteringForStandardSprite(); + virtual bool UseLinearFiltering() const; + virtual void SetFilteringForStandardSprite(); - static const GfxFilterInfo FilterInfo; + static const GfxFilterInfo FilterInfo; }; } // namespace D3D diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.cpp b/engines/ags/engine/gfx/gfxfilter_scaling.cpp index 923b36621b40..455015105bb9 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.cpp +++ b/engines/ags/engine/gfx/gfxfilter_scaling.cpp @@ -22,33 +22,27 @@ #include "gfx/gfxfilter_scaling.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -bool ScalingGfxFilter::Initialize(const int color_depth, String &err_str) -{ - // succeed by default - return true; +bool ScalingGfxFilter::Initialize(const int color_depth, String &err_str) { + // succeed by default + return true; } -void ScalingGfxFilter::UnInitialize() -{ - // do nothing by default +void ScalingGfxFilter::UnInitialize() { + // do nothing by default } -Rect ScalingGfxFilter::SetTranslation(const Size src_size, const Rect dst_rect) -{ - // do not restrict scaling by default - _dstRect = dst_rect; - _scaling.Init(src_size, dst_rect); - return _dstRect; +Rect ScalingGfxFilter::SetTranslation(const Size src_size, const Rect dst_rect) { + // do not restrict scaling by default + _dstRect = dst_rect; + _scaling.Init(src_size, dst_rect); + return _dstRect; } -Rect ScalingGfxFilter::GetDestination() const -{ - return _dstRect; +Rect ScalingGfxFilter::GetDestination() const { + return _dstRect; } } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.h b/engines/ags/engine/gfx/gfxfilter_scaling.h index fb1e2f342818..85aeb1b5a1ea 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.h +++ b/engines/ags/engine/gfx/gfxfilter_scaling.h @@ -32,22 +32,19 @@ #include "gfx/gfxfilter.h" #include "util/scaling.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class ScalingGfxFilter : public IGfxFilter -{ +class ScalingGfxFilter : public IGfxFilter { public: - bool Initialize(const int color_depth, String &err_str) override; - void UnInitialize() override; - Rect SetTranslation(const Size src_size, const Rect dst_rect) override; - Rect GetDestination() const override; + bool Initialize(const int color_depth, String &err_str) override; + void UnInitialize() override; + Rect SetTranslation(const Size src_size, const Rect dst_rect) override; + Rect GetDestination() const override; protected: - Rect _dstRect; - PlaneScaling _scaling; + Rect _dstRect; + PlaneScaling _scaling; }; } // namespace Engine diff --git a/engines/ags/engine/gfx/gfxmodelist.h b/engines/ags/engine/gfx/gfxmodelist.h index 7ae841776ed8..0fc28896216a 100644 --- a/engines/ags/engine/gfx/gfxmodelist.h +++ b/engines/ags/engine/gfx/gfxmodelist.h @@ -32,17 +32,14 @@ #include "core/types.h" #include "gfx/gfxdefines.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class IGfxModeList -{ +class IGfxModeList { public: - virtual ~IGfxModeList() = default; - virtual int GetModeCount() const = 0; - virtual bool GetMode(int index, DisplayMode &mode) const = 0; + virtual ~IGfxModeList() = default; + virtual int GetModeCount() const = 0; + virtual bool GetMode(int index, DisplayMode &mode) const = 0; }; } // namespace Engine diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h index 52fb9061983c..0108fad67077 100644 --- a/engines/ags/engine/gfx/graphicsdriver.h +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -34,17 +34,14 @@ #include "gfx/gfxmodelist.h" #include "util/geometry.h" -namespace AGS -{ +namespace AGS { -namespace Common -{ - class Bitmap; - typedef std::shared_ptr PBitmap; +namespace Common { +class Bitmap; +typedef std::shared_ptr PBitmap; } -namespace Engine -{ +namespace Engine { // Forward declaration class IDriverDependantBitmap; @@ -52,34 +49,31 @@ class IGfxFilter; typedef std::shared_ptr PGfxFilter; using Common::PBitmap; -enum TintMethod -{ - TintReColourise = 0, - TintSpecifyMaximum = 1 +enum TintMethod { + TintReColourise = 0, + TintSpecifyMaximum = 1 }; -enum VideoSkipType -{ - VideoSkipNone = 0, - VideoSkipEscape = 1, - VideoSkipAnyKey = 2, - VideoSkipKeyOrMouse = 3 +enum VideoSkipType { + VideoSkipNone = 0, + VideoSkipEscape = 1, + VideoSkipAnyKey = 2, + VideoSkipKeyOrMouse = 3 }; // Sprite transformation // TODO: combine with stretch parameters in the IDriverDependantBitmap? -struct SpriteTransform -{ - // Translate - int X, Y; - float ScaleX, ScaleY; - float Rotate; // angle, in radians - - SpriteTransform() - : X(0), Y(0), ScaleX(1.f), ScaleY(1.f), Rotate(0.f) {} - - SpriteTransform(int x, int y, float scalex = 1.0f, float scaley = 1.0f, float rotate = 0.0f) - : X(x), Y(y), ScaleX(scalex), ScaleY(scaley), Rotate(rotate) {} +struct SpriteTransform { + // Translate + int X, Y; + float ScaleX, ScaleY; + float Rotate; // angle, in radians + + SpriteTransform() + : X(0), Y(0), ScaleX(1.f), ScaleY(1.f), Rotate(0.f) {} + + SpriteTransform(int x, int y, float scalex = 1.0f, float scaley = 1.0f, float rotate = 0.0f) + : X(x), Y(y), ScaleX(scalex), ScaleY(scaley), Rotate(rotate) {} }; typedef void (*GFXDRV_CLIENTCALLBACK)(); @@ -90,108 +84,109 @@ typedef void (*GFXDRV_CLIENTCALLBACKINITGFX)(void *data); // the actual rendering surface size is redefined after IGraphicsDriver initialization. typedef void (*GFXDRV_CLIENTCALLBACKSURFACEUPDATE)(); -class IGraphicsDriver -{ +class IGraphicsDriver { public: - virtual const char*GetDriverName() = 0; - virtual const char*GetDriverID() = 0; - virtual void SetTintMethod(TintMethod method) = 0; - // Initialize given display mode - virtual bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) = 0; - // Gets if a graphics mode was initialized - virtual bool IsModeSet() const = 0; - // Set the size of the native image size - virtual bool SetNativeSize(const Size &src_size) = 0; - virtual bool IsNativeSizeValid() const = 0; - // Set game render frame and translation - virtual bool SetRenderFrame(const Rect &dst_rect) = 0; - virtual bool IsRenderFrameValid() const = 0; - // Report which color depth options are best suited for the given native color depth - virtual int GetDisplayDepthForNativeDepth(int native_color_depth) const = 0; - virtual IGfxModeList *GetSupportedModeList(int color_depth) = 0; - virtual bool IsModeSupported(const DisplayMode &mode) = 0; - virtual DisplayMode GetDisplayMode() const = 0; - virtual PGfxFilter GetGraphicsFilter() const = 0; - virtual Size GetNativeSize() const = 0; - virtual Rect GetRenderDestination() const = 0; - virtual void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) = 0; - // TODO: get rid of draw screen callback at some point when all fade functions are more or less grouped in one - virtual void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) = 0; - virtual void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) = 0; - virtual void SetCallbackOnSurfaceUpdate(GFXDRV_CLIENTCALLBACKSURFACEUPDATE) = 0; - // The NullSprite callback is called in the main render loop when a - // null sprite is encountered. You can use this to hook into the rendering - // process. - virtual void SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback) = 0; - // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. - virtual void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) = 0; - // Gets closest recommended bitmap format (currently - only color depth) for the given original format. - // Engine needs to have game bitmaps brought to the certain range of formats, easing conversion into the video bitmaps. - virtual int GetCompatibleBitmapFormat(int color_depth) = 0; - virtual IDriverDependantBitmap* CreateDDBFromBitmap(Common::Bitmap *bitmap, bool hasAlpha, bool opaque = false) = 0; - virtual void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Common::Bitmap *bitmap, bool hasAlpha) = 0; - virtual void DestroyDDB(IDriverDependantBitmap* bitmap) = 0; - - // Prepares next sprite batch, a list of sprites with defined viewport and optional - // global model transformation; all subsequent calls to DrawSprite will be adding - // sprites to this batch's list. - virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, - const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) = 0; - // Adds sprite to the active batch - virtual void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) = 0; - // Adds fade overlay fx to the active batch - virtual void SetScreenFade(int red, int green, int blue) = 0; - // Adds tint overlay fx to the active batch - // TODO: redesign this to allow various post-fx per sprite batch? - virtual void SetScreenTint(int red, int green, int blue) = 0; - // Clears all sprite batches, resets batch counter - virtual void ClearDrawLists() = 0; - virtual void RenderToBackBuffer() = 0; - virtual void Render() = 0; - // Renders with additional final offset and flip - // TODO: leftover from old code, solely for software renderer; remove when - // software mode either discarded or scene node graph properly implemented. - virtual void Render(int xoff, int yoff, GlobalFlipType flip) = 0; - // Copies contents of the game screen into bitmap using simple blit or pixel copy. - // Bitmap must be of supported size and pixel format. If it's not the method will - // fail and optionally write wanted destination format into 'want_fmt' pointer. - virtual bool GetCopyOfScreenIntoBitmap(Common::Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt = nullptr) = 0; - virtual void EnableVsyncBeforeRender(bool enabled) = 0; - virtual void Vsync() = 0; - // Enables or disables rendering mode that draws sprite list directly into - // the final resolution, as opposed to drawing to native-resolution buffer - // and scaling to final frame. The effect may be that sprites that are - // drawn with additional fractional scaling will appear more detailed than - // the rest of the game. The effect is stronger for the low-res games being - // rendered in the high-res mode. - virtual void RenderSpritesAtScreenResolution(bool enabled, int supersampling = 1) = 0; - // TODO: move fade-in/out/boxout functions out of the graphics driver!! make everything render through - // main drawing procedure. Since currently it does not - we need to init our own sprite batch - // internally to let it set up correct viewport settings instead of relying on a chance. - // Runs fade-out animation in a blocking manner. - virtual void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) = 0; - // Runs fade-in animation in a blocking manner. - virtual void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) = 0; - // Runs box-out animation in a blocking manner. - virtual void BoxOutEffect(bool blackingOut, int speed, int delay) = 0; - virtual bool PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) { return false; } - virtual void UseSmoothScaling(bool enabled) = 0; - virtual bool SupportsGammaControl() = 0; - virtual void SetGamma(int newGamma) = 0; - // Returns the virtual screen. Will return NULL if renderer does not support memory backbuffer. - // In normal case you should use GetStageBackBuffer() instead. - virtual Common::Bitmap* GetMemoryBackBuffer() = 0; - // Sets custom backbuffer bitmap to render to. - // Passing NULL pointer will tell renderer to switch back to its original virtual screen. - // Note that only software renderer supports this. - virtual void SetMemoryBackBuffer(Common::Bitmap *backBuffer) = 0; - // Returns memory backbuffer for the current rendering stage (or base virtual screen if called outside of render pass). - // All renderers should support this. - virtual Common::Bitmap* GetStageBackBuffer() = 0; - virtual bool RequiresFullRedrawEachFrame() = 0; - virtual bool HasAcceleratedTransform() = 0; - virtual bool UsesMemoryBackBuffer() = 0; - virtual ~IGraphicsDriver() = default; + virtual const char *GetDriverName() = 0; + virtual const char *GetDriverID() = 0; + virtual void SetTintMethod(TintMethod method) = 0; + // Initialize given display mode + virtual bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) = 0; + // Gets if a graphics mode was initialized + virtual bool IsModeSet() const = 0; + // Set the size of the native image size + virtual bool SetNativeSize(const Size &src_size) = 0; + virtual bool IsNativeSizeValid() const = 0; + // Set game render frame and translation + virtual bool SetRenderFrame(const Rect &dst_rect) = 0; + virtual bool IsRenderFrameValid() const = 0; + // Report which color depth options are best suited for the given native color depth + virtual int GetDisplayDepthForNativeDepth(int native_color_depth) const = 0; + virtual IGfxModeList *GetSupportedModeList(int color_depth) = 0; + virtual bool IsModeSupported(const DisplayMode &mode) = 0; + virtual DisplayMode GetDisplayMode() const = 0; + virtual PGfxFilter GetGraphicsFilter() const = 0; + virtual Size GetNativeSize() const = 0; + virtual Rect GetRenderDestination() const = 0; + virtual void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) = 0; + // TODO: get rid of draw screen callback at some point when all fade functions are more or less grouped in one + virtual void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) = 0; + virtual void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) = 0; + virtual void SetCallbackOnSurfaceUpdate(GFXDRV_CLIENTCALLBACKSURFACEUPDATE) = 0; + // The NullSprite callback is called in the main render loop when a + // null sprite is encountered. You can use this to hook into the rendering + // process. + virtual void SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback) = 0; + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + virtual void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) = 0; + // Gets closest recommended bitmap format (currently - only color depth) for the given original format. + // Engine needs to have game bitmaps brought to the certain range of formats, easing conversion into the video bitmaps. + virtual int GetCompatibleBitmapFormat(int color_depth) = 0; + virtual IDriverDependantBitmap *CreateDDBFromBitmap(Common::Bitmap *bitmap, bool hasAlpha, bool opaque = false) = 0; + virtual void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Common::Bitmap *bitmap, bool hasAlpha) = 0; + virtual void DestroyDDB(IDriverDependantBitmap *bitmap) = 0; + + // Prepares next sprite batch, a list of sprites with defined viewport and optional + // global model transformation; all subsequent calls to DrawSprite will be adding + // sprites to this batch's list. + virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, + const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) = 0; + // Adds sprite to the active batch + virtual void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) = 0; + // Adds fade overlay fx to the active batch + virtual void SetScreenFade(int red, int green, int blue) = 0; + // Adds tint overlay fx to the active batch + // TODO: redesign this to allow various post-fx per sprite batch? + virtual void SetScreenTint(int red, int green, int blue) = 0; + // Clears all sprite batches, resets batch counter + virtual void ClearDrawLists() = 0; + virtual void RenderToBackBuffer() = 0; + virtual void Render() = 0; + // Renders with additional final offset and flip + // TODO: leftover from old code, solely for software renderer; remove when + // software mode either discarded or scene node graph properly implemented. + virtual void Render(int xoff, int yoff, GlobalFlipType flip) = 0; + // Copies contents of the game screen into bitmap using simple blit or pixel copy. + // Bitmap must be of supported size and pixel format. If it's not the method will + // fail and optionally write wanted destination format into 'want_fmt' pointer. + virtual bool GetCopyOfScreenIntoBitmap(Common::Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt = nullptr) = 0; + virtual void EnableVsyncBeforeRender(bool enabled) = 0; + virtual void Vsync() = 0; + // Enables or disables rendering mode that draws sprite list directly into + // the final resolution, as opposed to drawing to native-resolution buffer + // and scaling to final frame. The effect may be that sprites that are + // drawn with additional fractional scaling will appear more detailed than + // the rest of the game. The effect is stronger for the low-res games being + // rendered in the high-res mode. + virtual void RenderSpritesAtScreenResolution(bool enabled, int supersampling = 1) = 0; + // TODO: move fade-in/out/boxout functions out of the graphics driver!! make everything render through + // main drawing procedure. Since currently it does not - we need to init our own sprite batch + // internally to let it set up correct viewport settings instead of relying on a chance. + // Runs fade-out animation in a blocking manner. + virtual void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) = 0; + // Runs fade-in animation in a blocking manner. + virtual void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) = 0; + // Runs box-out animation in a blocking manner. + virtual void BoxOutEffect(bool blackingOut, int speed, int delay) = 0; + virtual bool PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) { + return false; + } + virtual void UseSmoothScaling(bool enabled) = 0; + virtual bool SupportsGammaControl() = 0; + virtual void SetGamma(int newGamma) = 0; + // Returns the virtual screen. Will return NULL if renderer does not support memory backbuffer. + // In normal case you should use GetStageBackBuffer() instead. + virtual Common::Bitmap *GetMemoryBackBuffer() = 0; + // Sets custom backbuffer bitmap to render to. + // Passing NULL pointer will tell renderer to switch back to its original virtual screen. + // Note that only software renderer supports this. + virtual void SetMemoryBackBuffer(Common::Bitmap *backBuffer) = 0; + // Returns memory backbuffer for the current rendering stage (or base virtual screen if called outside of render pass). + // All renderers should support this. + virtual Common::Bitmap *GetStageBackBuffer() = 0; + virtual bool RequiresFullRedrawEachFrame() = 0; + virtual bool HasAcceleratedTransform() = 0; + virtual bool UsesMemoryBackBuffer() = 0; + virtual ~IGraphicsDriver() = default; }; } // namespace Engine diff --git a/engines/ags/engine/gfx/hq2x3x.h b/engines/ags/engine/gfx/hq2x3x.h index b6d2595936f8..741c31c0b65b 100644 --- a/engines/ags/engine/gfx/hq2x3x.h +++ b/engines/ags/engine/gfx/hq2x3x.h @@ -26,13 +26,13 @@ #include "core/platform.h" #if AGS_PLATFORM_OS_ANDROID -void InitLUTs(){} -void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ){} -void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ){} +void InitLUTs() {} +void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) {} +void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) {} #else void InitLUTs(); -void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); -void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL ); +void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL); +void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL); #endif #endif diff --git a/engines/ags/engine/gui/animatingguibutton.cpp b/engines/ags/engine/gui/animatingguibutton.cpp index 23a3df226ce8..68e7ad1f6697 100644 --- a/engines/ags/engine/gui/animatingguibutton.cpp +++ b/engines/ags/engine/gui/animatingguibutton.cpp @@ -25,28 +25,26 @@ using AGS::Common::Stream; -void AnimatingGUIButton::ReadFromFile(Stream *in) -{ - buttonid = in->ReadInt16(); - ongui = in->ReadInt16(); - onguibut = in->ReadInt16(); - view = in->ReadInt16(); - loop = in->ReadInt16(); - frame = in->ReadInt16(); - speed = in->ReadInt16(); - repeat = in->ReadInt16(); - wait = in->ReadInt16(); +void AnimatingGUIButton::ReadFromFile(Stream *in) { + buttonid = in->ReadInt16(); + ongui = in->ReadInt16(); + onguibut = in->ReadInt16(); + view = in->ReadInt16(); + loop = in->ReadInt16(); + frame = in->ReadInt16(); + speed = in->ReadInt16(); + repeat = in->ReadInt16(); + wait = in->ReadInt16(); } -void AnimatingGUIButton::WriteToFile(Stream *out) -{ - out->WriteInt16(buttonid); - out->WriteInt16(ongui); - out->WriteInt16(onguibut); - out->WriteInt16(view); - out->WriteInt16(loop); - out->WriteInt16(frame); - out->WriteInt16(speed); - out->WriteInt16(repeat); - out->WriteInt16(wait); +void AnimatingGUIButton::WriteToFile(Stream *out) { + out->WriteInt16(buttonid); + out->WriteInt16(ongui); + out->WriteInt16(onguibut); + out->WriteInt16(view); + out->WriteInt16(loop); + out->WriteInt16(frame); + out->WriteInt16(speed); + out->WriteInt16(repeat); + out->WriteInt16(wait); } diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h index 7fb060da90fa..d735d22b0db0 100644 --- a/engines/ags/engine/gui/animatingguibutton.h +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -26,18 +26,22 @@ #include "ac/runtime_defines.h" // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later struct AnimatingGUIButton { - // index into guibuts array, GUI, button - short buttonid, ongui, onguibut; - // current animation status - short view, loop, frame; - short speed, repeat, wait; + // index into guibuts array, GUI, button + short buttonid, ongui, onguibut; + // current animation status + short view, loop, frame; + short speed, repeat, wait; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); }; #endif diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index 9adeb3a436cd..6bd1de88943a 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -73,251 +73,236 @@ int controlid = 0; //----------------------------------------------------------------------------- -void __my_wbutt(Bitmap *ds, int x1, int y1, int x2, int y2) -{ - color_t draw_color = ds->GetCompatibleColor(COL254); //wsetcolor(15); - ds->FillRect(Rect(x1, y1, x2, y2), draw_color); - draw_color = ds->GetCompatibleColor(0); - ds->DrawRect(Rect(x1, y1, x2, y2), draw_color); +void __my_wbutt(Bitmap *ds, int x1, int y1, int x2, int y2) { + color_t draw_color = ds->GetCompatibleColor(COL254); //wsetcolor(15); + ds->FillRect(Rect(x1, y1, x2, y2), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(x1, y1, x2, y2), draw_color); } //----------------------------------------------------------------------------- -OnScreenWindow::OnScreenWindow() -{ - x = y = 0; - handle = -1; - oldtop = -1; +OnScreenWindow::OnScreenWindow() { + x = y = 0; + handle = -1; + oldtop = -1; } -int CSCIGetVersion() -{ - return 0x0100; +int CSCIGetVersion() { + return 0x0100; } int windowcount = 0, curswas = 0; int win_x = 0, win_y = 0, win_width = 0, win_height = 0; -int CSCIDrawWindow(int xx, int yy, int wid, int hit) -{ - ignore_bounds++; - multiply_up(&xx, &yy, &wid, &hit); - int drawit = -1; - for (int aa = 0; aa < MAXSCREENWINDOWS; aa++) { - if (oswi[aa].handle < 0) { - drawit = aa; - break; - } - } - - if (drawit < 0) - quit("Too many windows created."); - - windowcount++; - // ags_domouse(DOMOUSE_DISABLE); - xx -= 2; - yy -= 2; - wid += 4; - hit += 4; - Bitmap *ds = prepare_gui_screen(xx, yy, wid, hit, true); - oswi[drawit].x = xx; - oswi[drawit].y = yy; - __my_wbutt(ds, 0, 0, wid - 1, hit - 1); // wbutt goes outside its area - // ags_domouse(DOMOUSE_ENABLE); - oswi[drawit].oldtop = topwindowhandle; - topwindowhandle = drawit; - oswi[drawit].handle = topwindowhandle; - win_x = xx; - win_y = yy; - win_width = wid; - win_height = hit; - return drawit; +int CSCIDrawWindow(int xx, int yy, int wid, int hit) { + ignore_bounds++; + multiply_up(&xx, &yy, &wid, &hit); + int drawit = -1; + for (int aa = 0; aa < MAXSCREENWINDOWS; aa++) { + if (oswi[aa].handle < 0) { + drawit = aa; + break; + } + } + + if (drawit < 0) + quit("Too many windows created."); + + windowcount++; + // ags_domouse(DOMOUSE_DISABLE); + xx -= 2; + yy -= 2; + wid += 4; + hit += 4; + Bitmap *ds = prepare_gui_screen(xx, yy, wid, hit, true); + oswi[drawit].x = xx; + oswi[drawit].y = yy; + __my_wbutt(ds, 0, 0, wid - 1, hit - 1); // wbutt goes outside its area + // ags_domouse(DOMOUSE_ENABLE); + oswi[drawit].oldtop = topwindowhandle; + topwindowhandle = drawit; + oswi[drawit].handle = topwindowhandle; + win_x = xx; + win_y = yy; + win_width = wid; + win_height = hit; + return drawit; } -void CSCIEraseWindow(int handl) -{ - // ags_domouse(DOMOUSE_DISABLE); - ignore_bounds--; - topwindowhandle = oswi[handl].oldtop; - oswi[handl].handle = -1; - // ags_domouse(DOMOUSE_ENABLE); - windowcount--; - clear_gui_screen(); +void CSCIEraseWindow(int handl) { + // ags_domouse(DOMOUSE_DISABLE); + ignore_bounds--; + topwindowhandle = oswi[handl].oldtop; + oswi[handl].handle = -1; + // ags_domouse(DOMOUSE_ENABLE); + windowcount--; + clear_gui_screen(); } -int CSCIWaitMessage(CSCIMessage * cscim) -{ - for (int uu = 0; uu < MAXCONTROLS; uu++) { - if (vobjs[uu] != nullptr) { - // ags_domouse(DOMOUSE_DISABLE); - vobjs[uu]->drawifneeded(); - // ags_domouse(DOMOUSE_ENABLE); - } - } - - prepare_gui_screen(win_x, win_y, win_width, win_height, true); - - while (1) { - update_audio_system_on_game_loop(); - refresh_gui_screen(); - - cscim->id = -1; - cscim->code = 0; - smcode = 0; - int keywas; - if (run_service_key_controls(keywas) && !play.IsIgnoringInput()) { - if (keywas == 13) { - cscim->id = finddefaultcontrol(CNF_DEFAULT); - cscim->code = CM_COMMAND; - } else if (keywas == 27) { - cscim->id = finddefaultcontrol(CNF_CANCEL); - cscim->code = CM_COMMAND; - } else if ((keywas < 32) && (keywas != 8)) ; - else if ((keywas >= 372) & (keywas <= 381) & (finddefaultcontrol(CNT_LISTBOX) >= 0)) - vobjs[finddefaultcontrol(CNT_LISTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0); - else if (finddefaultcontrol(CNT_TEXTBOX) >= 0) - vobjs[finddefaultcontrol(CNT_TEXTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0); - - if (cscim->id < 0) { - cscim->code = CM_KEYPRESS; - cscim->wParam = keywas; - } - } - - int mbut, mwheelz; - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !play.IsIgnoringInput()) { - if (checkcontrols()) { - cscim->id = controlid; - cscim->code = CM_COMMAND; - } - } - - if (smcode) { - cscim->code = smcode; - cscim->id = controlid; - } - - if (cscim->code > 0) - break; - - WaitForNextFrame(); - } - - return 0; +int CSCIWaitMessage(CSCIMessage *cscim) { + for (int uu = 0; uu < MAXCONTROLS; uu++) { + if (vobjs[uu] != nullptr) { + // ags_domouse(DOMOUSE_DISABLE); + vobjs[uu]->drawifneeded(); + // ags_domouse(DOMOUSE_ENABLE); + } + } + + prepare_gui_screen(win_x, win_y, win_width, win_height, true); + + while (1) { + update_audio_system_on_game_loop(); + refresh_gui_screen(); + + cscim->id = -1; + cscim->code = 0; + smcode = 0; + int keywas; + if (run_service_key_controls(keywas) && !play.IsIgnoringInput()) { + if (keywas == 13) { + cscim->id = finddefaultcontrol(CNF_DEFAULT); + cscim->code = CM_COMMAND; + } else if (keywas == 27) { + cscim->id = finddefaultcontrol(CNF_CANCEL); + cscim->code = CM_COMMAND; + } else if ((keywas < 32) && (keywas != 8)) ; + else if ((keywas >= 372) & (keywas <= 381) & (finddefaultcontrol(CNT_LISTBOX) >= 0)) + vobjs[finddefaultcontrol(CNT_LISTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0); + else if (finddefaultcontrol(CNT_TEXTBOX) >= 0) + vobjs[finddefaultcontrol(CNT_TEXTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0); + + if (cscim->id < 0) { + cscim->code = CM_KEYPRESS; + cscim->wParam = keywas; + } + } + + int mbut, mwheelz; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !play.IsIgnoringInput()) { + if (checkcontrols()) { + cscim->id = controlid; + cscim->code = CM_COMMAND; + } + } + + if (smcode) { + cscim->code = smcode; + cscim->id = controlid; + } + + if (cscim->code > 0) + break; + + WaitForNextFrame(); + } + + return 0; } -int CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title) -{ - multiply_up(&xx, &yy, &wii, &hii); - int usec = -1; - for (int hh = 1; hh < MAXCONTROLS; hh++) { - if (vobjs[hh] == nullptr) { - usec = hh; - break; - } - } - - if (usec < 0) - quit("Too many controls created"); - - int type = typeandflags & 0x00ff; // 256 control types - if (type == CNT_PUSHBUTTON) { - if (wii == -1) - wii = wgettextwidth(title, cbuttfont) + 20; - - vobjs[usec] = new MyPushButton(xx, yy, wii, hii, title); - - } else if (type == CNT_LISTBOX) { - vobjs[usec] = new MyListBox(xx, yy, wii, hii); - } else if (type == CNT_LABEL) { - vobjs[usec] = new MyLabel(xx, yy, wii, title); - } else if (type == CNT_TEXTBOX) { - vobjs[usec] = new MyTextBox(xx, yy, wii, title); - } else - quit("Unknown control type requested"); - - vobjs[usec]->typeandflags = typeandflags; - vobjs[usec]->wlevel = topwindowhandle; - // ags_domouse(DOMOUSE_DISABLE); - vobjs[usec]->draw( get_gui_screen() ); - // ags_domouse(DOMOUSE_ENABLE); - return usec; +int CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title) { + multiply_up(&xx, &yy, &wii, &hii); + int usec = -1; + for (int hh = 1; hh < MAXCONTROLS; hh++) { + if (vobjs[hh] == nullptr) { + usec = hh; + break; + } + } + + if (usec < 0) + quit("Too many controls created"); + + int type = typeandflags & 0x00ff; // 256 control types + if (type == CNT_PUSHBUTTON) { + if (wii == -1) + wii = wgettextwidth(title, cbuttfont) + 20; + + vobjs[usec] = new MyPushButton(xx, yy, wii, hii, title); + + } else if (type == CNT_LISTBOX) { + vobjs[usec] = new MyListBox(xx, yy, wii, hii); + } else if (type == CNT_LABEL) { + vobjs[usec] = new MyLabel(xx, yy, wii, title); + } else if (type == CNT_TEXTBOX) { + vobjs[usec] = new MyTextBox(xx, yy, wii, title); + } else + quit("Unknown control type requested"); + + vobjs[usec]->typeandflags = typeandflags; + vobjs[usec]->wlevel = topwindowhandle; + // ags_domouse(DOMOUSE_DISABLE); + vobjs[usec]->draw(get_gui_screen()); + // ags_domouse(DOMOUSE_ENABLE); + return usec; } -void CSCIDeleteControl(int haa) -{ - delete vobjs[haa]; - vobjs[haa] = nullptr; +void CSCIDeleteControl(int haa) { + delete vobjs[haa]; + vobjs[haa] = nullptr; } -int CSCISendControlMessage(int haa, int mess, int wPar, long lPar) -{ - if (vobjs[haa] == nullptr) - return -1; - return vobjs[haa]->processmessage(mess, wPar, lPar); +int CSCISendControlMessage(int haa, int mess, int wPar, long lPar) { + if (vobjs[haa] == nullptr) + return -1; + return vobjs[haa]->processmessage(mess, wPar, lPar); } -void multiply_up_to_game_res(int *x, int *y) -{ - x[0] = get_fixed_pixel_size(x[0]); - y[0] = get_fixed_pixel_size(y[0]); +void multiply_up_to_game_res(int *x, int *y) { + x[0] = get_fixed_pixel_size(x[0]); + y[0] = get_fixed_pixel_size(y[0]); } // TODO: this is silly, make a uniform formula -void multiply_up(int *x1, int *y1, int *x2, int *y2) -{ - multiply_up_to_game_res(x1, y1); - multiply_up_to_game_res(x2, y2); - - // adjust for 800x600 - if ((GetBaseWidth() == 400) || (GetBaseWidth() == 800)) { - x1[0] = (x1[0] * 5) / 4; - x2[0] = (x2[0] * 5) / 4; - y1[0] = (y1[0] * 3) / 2; - y2[0] = (y2[0] * 3) / 2; - } - else if (GetBaseWidth() == 1024) - { - x1[0] = (x1[0] * 16) / 10; - x2[0] = (x2[0] * 16) / 10; - y1[0] = (y1[0] * 384) / 200; - y2[0] = (y2[0] * 384) / 200; - } +void multiply_up(int *x1, int *y1, int *x2, int *y2) { + multiply_up_to_game_res(x1, y1); + multiply_up_to_game_res(x2, y2); + + // adjust for 800x600 + if ((GetBaseWidth() == 400) || (GetBaseWidth() == 800)) { + x1[0] = (x1[0] * 5) / 4; + x2[0] = (x2[0] * 5) / 4; + y1[0] = (y1[0] * 3) / 2; + y2[0] = (y2[0] * 3) / 2; + } else if (GetBaseWidth() == 1024) { + x1[0] = (x1[0] * 16) / 10; + x2[0] = (x2[0] * 16) / 10; + y1[0] = (y1[0] * 384) / 200; + y2[0] = (y2[0] * 384) / 200; + } } -int checkcontrols() -{ - // NOTE: this is because old code was working with full game screen - const int mousex = ::mousex - win_x; - const int mousey = ::mousey - win_y; - - smcode = 0; - for (int kk = 0; kk < MAXCONTROLS; kk++) { - if (vobjs[kk] != nullptr) { - if (vobjs[kk]->mouseisinarea(mousex, mousey)) { - controlid = kk; - return vobjs[kk]->pressedon(mousex, mousey); - } - } - } - return 0; +int checkcontrols() { + // NOTE: this is because old code was working with full game screen + const int mousex = ::mousex - win_x; + const int mousey = ::mousey - win_y; + + smcode = 0; + for (int kk = 0; kk < MAXCONTROLS; kk++) { + if (vobjs[kk] != nullptr) { + if (vobjs[kk]->mouseisinarea(mousex, mousey)) { + controlid = kk; + return vobjs[kk]->pressedon(mousex, mousey); + } + } + } + return 0; } -int finddefaultcontrol(int flagmask) -{ - for (int ff = 0; ff < MAXCONTROLS; ff++) { - if (vobjs[ff] == nullptr) - continue; +int finddefaultcontrol(int flagmask) { + for (int ff = 0; ff < MAXCONTROLS; ff++) { + if (vobjs[ff] == nullptr) + continue; - if (vobjs[ff]->wlevel != topwindowhandle) - continue; + if (vobjs[ff]->wlevel != topwindowhandle) + continue; - if (vobjs[ff]->typeandflags & flagmask) - return ff; - } + if (vobjs[ff]->typeandflags & flagmask) + return ff; + } - return -1; + return -1; } -int GetBaseWidth () { - return play.GetUIViewport().GetWidth(); +int GetBaseWidth() { + return play.GetUIViewport().GetWidth(); } diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h index ebee093d29fc..0d2930942045 100644 --- a/engines/ags/engine/gui/cscidialog.h +++ b/engines/ags/engine/gui/cscidialog.h @@ -34,7 +34,7 @@ int CSCIGetVersion(); int CSCIDrawWindow(int xx, int yy, int wid, int hit); void CSCIEraseWindow(int handl); -int CSCIWaitMessage(CSCIMessage * cscim); +int CSCIWaitMessage(CSCIMessage *cscim); int CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title); void CSCIDeleteControl(int haa); int CSCISendControlMessage(int haa, int mess, int wPar, long lPar); @@ -42,6 +42,6 @@ void multiply_up_to_game_res(int *x, int *y); void multiply_up(int *x1, int *y1, int *x2, int *y2); int checkcontrols(); int finddefaultcontrol(int flagmask); -int GetBaseWidth (); +int GetBaseWidth(); #endif diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp index b896a816e8f8..154db1160fdf 100644 --- a/engines/ags/engine/gui/gui_engine.cpp +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -48,7 +48,7 @@ using namespace AGS::Common; // For engine these are defined in ac.cpp extern int eip_guiobj; -extern void replace_macro_tokens(const char*, String&); +extern void replace_macro_tokens(const char *, String &); // For engine these are defined in acfonts.cpp extern void ensure_text_valid_for_font(char *, int); @@ -57,123 +57,103 @@ extern void ensure_text_valid_for_font(char *, int); extern SpriteCache spriteset; // in ac_runningame extern GameSetupStruct game; -bool GUIMain::HasAlphaChannel() const -{ - if (this->BgImage > 0) - { - // alpha state depends on background image - return is_sprite_alpha(this->BgImage); - } - if (this->BgColor > 0) - { - // not alpha transparent if there is a background color - return false; - } - // transparent background, enable alpha blending - return game.GetColorDepth() >= 24 && - // transparent background have alpha channel only since 3.2.0; - // "classic" gui rendering mode historically had non-alpha transparent backgrounds - // (3.2.0 broke the compatibility, now we restore it) - loaded_game_file_version >= kGameVersion_320 && game.options[OPT_NEWGUIALPHA] != kGuiAlphaRender_Legacy; +bool GUIMain::HasAlphaChannel() const { + if (this->BgImage > 0) { + // alpha state depends on background image + return is_sprite_alpha(this->BgImage); + } + if (this->BgColor > 0) { + // not alpha transparent if there is a background color + return false; + } + // transparent background, enable alpha blending + return game.GetColorDepth() >= 24 && + // transparent background have alpha channel only since 3.2.0; + // "classic" gui rendering mode historically had non-alpha transparent backgrounds + // (3.2.0 broke the compatibility, now we restore it) + loaded_game_file_version >= kGameVersion_320 && game.options[OPT_NEWGUIALPHA] != kGuiAlphaRender_Legacy; } //============================================================================= // Engine-specific implementation split out of acgui.h //============================================================================= -void check_font(int *fontnum) -{ - // do nothing +void check_font(int *fontnum) { + // do nothing } //============================================================================= // Engine-specific implementation split out of acgui.cpp //============================================================================= -int get_adjusted_spritewidth(int spr) -{ - return spriteset[spr]->GetWidth(); +int get_adjusted_spritewidth(int spr) { + return spriteset[spr]->GetWidth(); } -int get_adjusted_spriteheight(int spr) -{ - return spriteset[spr]->GetHeight(); +int get_adjusted_spriteheight(int spr) { + return spriteset[spr]->GetHeight(); } -bool is_sprite_alpha(int spr) -{ - return ((game.SpriteInfos[spr].Flags & SPF_ALPHACHANNEL) != 0); +bool is_sprite_alpha(int spr) { + return ((game.SpriteInfos[spr].Flags & SPF_ALPHACHANNEL) != 0); } -void set_eip_guiobj(int eip) -{ - eip_guiobj = eip; +void set_eip_guiobj(int eip) { + eip_guiobj = eip; } -int get_eip_guiobj() -{ - return eip_guiobj; +int get_eip_guiobj() { + return eip_guiobj; } bool outlineGuiObjects = false; -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -bool GUIObject::IsClickable() const -{ - return (Flags & kGUICtrl_Clickable) != 0; +bool GUIObject::IsClickable() const { + return (Flags & kGUICtrl_Clickable) != 0; } -void GUILabel::PrepareTextToDraw() -{ - replace_macro_tokens(Flags & kGUICtrl_Translated ? String(get_translation(Text)) : Text, _textToDraw); +void GUILabel::PrepareTextToDraw() { + replace_macro_tokens(Flags & kGUICtrl_Translated ? String(get_translation(Text)) : Text, _textToDraw); } -size_t GUILabel::SplitLinesForDrawing(SplitLines &lines) -{ - // Use the engine's word wrap tool, to have hebrew-style writing and other features - return break_up_text_into_lines(_textToDraw, lines, Width, Font); +size_t GUILabel::SplitLinesForDrawing(SplitLines &lines) { + // Use the engine's word wrap tool, to have hebrew-style writing and other features + return break_up_text_into_lines(_textToDraw, lines, Width, Font); } -void GUITextBox::DrawTextBoxContents(Bitmap *ds, color_t text_color) -{ - wouttext_outline(ds, X + 1 + get_fixed_pixel_size(1), Y + 1 + get_fixed_pixel_size(1), Font, text_color, Text); - if (IsGUIEnabled(this)) - { - // draw a cursor - int draw_at_x = wgettextwidth(Text, Font) + X + 3; - int draw_at_y = Y + 1 + getfontheight(Font); - ds->DrawRect(Rect(draw_at_x, draw_at_y, draw_at_x + get_fixed_pixel_size(5), draw_at_y + (get_fixed_pixel_size(1) - 1)), text_color); - } +void GUITextBox::DrawTextBoxContents(Bitmap *ds, color_t text_color) { + wouttext_outline(ds, X + 1 + get_fixed_pixel_size(1), Y + 1 + get_fixed_pixel_size(1), Font, text_color, Text); + if (IsGUIEnabled(this)) { + // draw a cursor + int draw_at_x = wgettextwidth(Text, Font) + X + 3; + int draw_at_y = Y + 1 + getfontheight(Font); + ds->DrawRect(Rect(draw_at_x, draw_at_y, draw_at_x + get_fixed_pixel_size(5), draw_at_y + (get_fixed_pixel_size(1) - 1)), text_color); + } } -void GUIListBox::DrawItemsFix() -{ - // do nothing +void GUIListBox::DrawItemsFix() { + // do nothing } -void GUIListBox::DrawItemsUnfix() -{ - // do nothing +void GUIListBox::DrawItemsUnfix() { + // do nothing } -void GUIListBox::PrepareTextToDraw(const String &text) -{ - if (Flags & kGUICtrl_Translated) - _textToDraw = get_translation(text); - else - _textToDraw = text; +void GUIListBox::PrepareTextToDraw(const String &text) { + if (Flags & kGUICtrl_Translated) + _textToDraw = get_translation(text); + else + _textToDraw = text; } -void GUIButton::PrepareTextToDraw() -{ - if (Flags & kGUICtrl_Translated) - _textToDraw = get_translation(_text); - else - _textToDraw = _text; +void GUIButton::PrepareTextToDraw() { + if (Flags & kGUICtrl_Translated) + _textToDraw = get_translation(_text); + else + _textToDraw = _text; } } // namespace Common diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index 42b37a9ab501..dde29885dc92 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -64,478 +64,449 @@ int myscrnwid = 320, myscrnhit = 200; } -char *get_gui_dialog_buffer() -{ - return buffer2; +char *get_gui_dialog_buffer() { + return buffer2; } // // TODO: rewrite the whole thing to work inside the main game update and render loop! // -Bitmap *prepare_gui_screen(int x, int y, int width, int height, bool opaque) -{ - windowPosX = x; - windowPosY = y; - windowPosWidth = width; - windowPosHeight = height; - if (windowBuffer) - { - windowBuffer = recycle_bitmap(windowBuffer, windowBuffer->GetColorDepth(), windowPosWidth, windowPosHeight, !opaque); - } - else - { - windowBuffer = BitmapHelper::CreateBitmap(windowPosWidth, windowPosHeight, game.GetColorDepth()); - windowBuffer = ReplaceBitmapWithSupportedFormat(windowBuffer); - } - dialogDDB = recycle_ddb_bitmap(dialogDDB, windowBuffer, false, opaque); - return windowBuffer; +Bitmap *prepare_gui_screen(int x, int y, int width, int height, bool opaque) { + windowPosX = x; + windowPosY = y; + windowPosWidth = width; + windowPosHeight = height; + if (windowBuffer) { + windowBuffer = recycle_bitmap(windowBuffer, windowBuffer->GetColorDepth(), windowPosWidth, windowPosHeight, !opaque); + } else { + windowBuffer = BitmapHelper::CreateBitmap(windowPosWidth, windowPosHeight, game.GetColorDepth()); + windowBuffer = ReplaceBitmapWithSupportedFormat(windowBuffer); + } + dialogDDB = recycle_ddb_bitmap(dialogDDB, windowBuffer, false, opaque); + return windowBuffer; } -Bitmap *get_gui_screen() -{ - return windowBuffer; +Bitmap *get_gui_screen() { + return windowBuffer; } -void clear_gui_screen() -{ - if (dialogDDB) - gfxDriver->DestroyDDB(dialogDDB); - dialogDDB = nullptr; - delete windowBuffer; - windowBuffer = nullptr; +void clear_gui_screen() { + if (dialogDDB) + gfxDriver->DestroyDDB(dialogDDB); + dialogDDB = nullptr; + delete windowBuffer; + windowBuffer = nullptr; } -void refresh_gui_screen() -{ - gfxDriver->UpdateDDBFromBitmap(dialogDDB, windowBuffer, false); - render_graphics(dialogDDB, windowPosX, windowPosY); +void refresh_gui_screen() { + gfxDriver->UpdateDDBFromBitmap(dialogDDB, windowBuffer, false); + render_graphics(dialogDDB, windowPosX, windowPosY); } -int loadgamedialog() -{ - const int wnd_width = 200; - const int wnd_height = 120; - const int boxleft = myscrnwid / 2 - wnd_width / 2; - const int boxtop = myscrnhit / 2 - wnd_height / 2; - const int buttonhit = usetup.textheight + 5; - - int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); - int ctrlok = - CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, get_global_message(MSG_RESTORE)); - int ctrlcancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, - get_global_message(MSG_CANCEL)); - int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 30, 120, 80, nullptr); - int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, 5, 120, 0, get_global_message(MSG_SELECTLOAD)); - CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); - - preparesavegamelist(ctrllist); - CSCIMessage mes; - lpTemp = nullptr; - int toret = -1; - while (1) { - CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); - if (mes.code == CM_COMMAND) { - if (mes.id == ctrlok) { - int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); - if ((cursel >= numsaves) | (cursel < 0)) - lpTemp = nullptr; - else { - toret = filenumbers[cursel]; - String path = get_save_game_path(toret); - strcpy(bufTemp, path); - lpTemp = &bufTemp[0]; - } - } else if (mes.id == ctrlcancel) { - lpTemp = nullptr; - } - - break; - } - } - - CSCIDeleteControl(ctrltex1); - CSCIDeleteControl(ctrllist); - CSCIDeleteControl(ctrlok); - CSCIDeleteControl(ctrlcancel); - CSCIEraseWindow(handl); - return toret; +int loadgamedialog() { + const int wnd_width = 200; + const int wnd_height = 120; + const int boxleft = myscrnwid / 2 - wnd_width / 2; + const int boxtop = myscrnhit / 2 - wnd_height / 2; + const int buttonhit = usetup.textheight + 5; + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrlok = + CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, get_global_message(MSG_RESTORE)); + int ctrlcancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, + get_global_message(MSG_CANCEL)); + int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 30, 120, 80, nullptr); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, 5, 120, 0, get_global_message(MSG_SELECTLOAD)); + CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); + + preparesavegamelist(ctrllist); + CSCIMessage mes; + lpTemp = nullptr; + int toret = -1; + while (1) { + CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); + if (mes.code == CM_COMMAND) { + if (mes.id == ctrlok) { + int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + if ((cursel >= numsaves) | (cursel < 0)) + lpTemp = nullptr; + else { + toret = filenumbers[cursel]; + String path = get_save_game_path(toret); + strcpy(bufTemp, path); + lpTemp = &bufTemp[0]; + } + } else if (mes.id == ctrlcancel) { + lpTemp = nullptr; + } + + break; + } + } + + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrllist); + CSCIDeleteControl(ctrlok); + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + return toret; } -int savegamedialog() -{ - char okbuttontext[50]; - strcpy(okbuttontext, get_global_message(MSG_SAVEBUTTON)); - char labeltext[200]; - strcpy(labeltext, get_global_message(MSG_SAVEDIALOG)); - const int wnd_width = 200; - const int wnd_height = 120; - const int boxleft = myscrnwid / 2 - wnd_width / 2; - const int boxtop = myscrnhit / 2 - wnd_height / 2; - const int buttonhit = usetup.textheight + 5; - int labeltop = 5; - - int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); - int ctrlcancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, - get_global_message(MSG_CANCEL)); - int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 120, 80, nullptr); - int ctrltbox = 0; - - CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box - preparesavegamelist(ctrllist); - if (toomanygames) { - strcpy(okbuttontext, get_global_message(MSG_REPLACE)); - strcpy(labeltext, get_global_message(MSG_MUSTREPLACE)); - labeltop = 2; - } else - ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); - - int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, okbuttontext); - int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, labeltop, 120, 0, labeltext); - CSCIMessage mes; - - lpTemp = nullptr; - if (numsaves > 0) - CSCISendControlMessage(ctrllist, CLB_GETTEXT, 0, (long)&buffer2[0]); - else - buffer2[0] = 0; - - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); - - int toret = -1; - while (1) { - CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); - if (mes.code == CM_COMMAND) { - if (mes.id == ctrlok) { - int cursell = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); - CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); - - if (numsaves > 0) - CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursell, (long)&bufTemp[0]); - else - strcpy(bufTemp, "_NOSAVEGAMENAME"); - - if (toomanygames) { - int nwhand = CSCIDrawWindow(boxleft + 5, boxtop + 20, 190, 65); - int lbl1 = - CSCICreateControl(CNT_LABEL, 15, 5, 160, 0, get_global_message(MSG_REPLACEWITH1)); - int lbl2 = CSCICreateControl(CNT_LABEL, 25, 14, 160, 0, bufTemp); - int lbl3 = - CSCICreateControl(CNT_LABEL, 15, 25, 160, 0, get_global_message(MSG_REPLACEWITH2)); - int txt1 = CSCICreateControl(CNT_TEXTBOX, 15, 35, 160, 0, bufTemp); - int btnOk = - CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 25, 50, 60, 10, - get_global_message(MSG_REPLACE)); - int btnCancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 95, 50, 60, 10, - get_global_message(MSG_CANCEL)); - - CSCIMessage cmes; - do { - CSCIWaitMessage(&cmes); - } while (cmes.code != CM_COMMAND); - - CSCISendControlMessage(txt1, CTB_GETTEXT, 0, (long)&buffer2[0]); - CSCIDeleteControl(btnCancel); - CSCIDeleteControl(btnOk); - CSCIDeleteControl(txt1); - CSCIDeleteControl(lbl3); - CSCIDeleteControl(lbl2); - CSCIDeleteControl(lbl1); - CSCIEraseWindow(nwhand); - bufTemp[0] = 0; - - if (cmes.id == btnCancel) { - lpTemp = nullptr; - break; - } else - toret = filenumbers[cursell]; - - } - else if (strcmp(buffer2, bufTemp) != 0) { // create a new game (description different) - int highestnum = 0; - for (int pp = 0; pp < numsaves; pp++) { - if (filenumbers[pp] > highestnum) - highestnum = filenumbers[pp]; - } - - if (highestnum > 90) - quit("Save game directory overflow"); - - toret = highestnum + 1; - String path = get_save_game_path(toret); - strcpy(bufTemp, path); - } - else { - toret = filenumbers[cursell]; - bufTemp[0] = 0; - } - - if (bufTemp[0] == 0) - { - String path = get_save_game_path(toret); - strcpy(bufTemp, path); - } - - lpTemp = &bufTemp[0]; - lpTemp2 = &buffer2[0]; - } else if (mes.id == ctrlcancel) { - lpTemp = nullptr; - } - break; - } else if (mes.code == CM_SELCHANGE) { - int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); - if (cursel >= 0) { - CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursel, (long)&buffer2[0]); - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); - } - } - } - - CSCIDeleteControl(ctrltbox); - CSCIDeleteControl(ctrltex1); - CSCIDeleteControl(ctrllist); - CSCIDeleteControl(ctrlok); - CSCIDeleteControl(ctrlcancel); - CSCIEraseWindow(handl); - return toret; +int savegamedialog() { + char okbuttontext[50]; + strcpy(okbuttontext, get_global_message(MSG_SAVEBUTTON)); + char labeltext[200]; + strcpy(labeltext, get_global_message(MSG_SAVEDIALOG)); + const int wnd_width = 200; + const int wnd_height = 120; + const int boxleft = myscrnwid / 2 - wnd_width / 2; + const int boxtop = myscrnhit / 2 - wnd_height / 2; + const int buttonhit = usetup.textheight + 5; + int labeltop = 5; + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrlcancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, + get_global_message(MSG_CANCEL)); + int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 120, 80, nullptr); + int ctrltbox = 0; + + CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box + preparesavegamelist(ctrllist); + if (toomanygames) { + strcpy(okbuttontext, get_global_message(MSG_REPLACE)); + strcpy(labeltext, get_global_message(MSG_MUSTREPLACE)); + labeltop = 2; + } else + ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); + + int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, okbuttontext); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, labeltop, 120, 0, labeltext); + CSCIMessage mes; + + lpTemp = nullptr; + if (numsaves > 0) + CSCISendControlMessage(ctrllist, CLB_GETTEXT, 0, (long)&buffer2[0]); + else + buffer2[0] = 0; + + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + + int toret = -1; + while (1) { + CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); + if (mes.code == CM_COMMAND) { + if (mes.id == ctrlok) { + int cursell = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + + if (numsaves > 0) + CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursell, (long)&bufTemp[0]); + else + strcpy(bufTemp, "_NOSAVEGAMENAME"); + + if (toomanygames) { + int nwhand = CSCIDrawWindow(boxleft + 5, boxtop + 20, 190, 65); + int lbl1 = + CSCICreateControl(CNT_LABEL, 15, 5, 160, 0, get_global_message(MSG_REPLACEWITH1)); + int lbl2 = CSCICreateControl(CNT_LABEL, 25, 14, 160, 0, bufTemp); + int lbl3 = + CSCICreateControl(CNT_LABEL, 15, 25, 160, 0, get_global_message(MSG_REPLACEWITH2)); + int txt1 = CSCICreateControl(CNT_TEXTBOX, 15, 35, 160, 0, bufTemp); + int btnOk = + CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 25, 50, 60, 10, + get_global_message(MSG_REPLACE)); + int btnCancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 95, 50, 60, 10, + get_global_message(MSG_CANCEL)); + + CSCIMessage cmes; + do { + CSCIWaitMessage(&cmes); + } while (cmes.code != CM_COMMAND); + + CSCISendControlMessage(txt1, CTB_GETTEXT, 0, (long)&buffer2[0]); + CSCIDeleteControl(btnCancel); + CSCIDeleteControl(btnOk); + CSCIDeleteControl(txt1); + CSCIDeleteControl(lbl3); + CSCIDeleteControl(lbl2); + CSCIDeleteControl(lbl1); + CSCIEraseWindow(nwhand); + bufTemp[0] = 0; + + if (cmes.id == btnCancel) { + lpTemp = nullptr; + break; + } else + toret = filenumbers[cursell]; + + } else if (strcmp(buffer2, bufTemp) != 0) { // create a new game (description different) + int highestnum = 0; + for (int pp = 0; pp < numsaves; pp++) { + if (filenumbers[pp] > highestnum) + highestnum = filenumbers[pp]; + } + + if (highestnum > 90) + quit("Save game directory overflow"); + + toret = highestnum + 1; + String path = get_save_game_path(toret); + strcpy(bufTemp, path); + } else { + toret = filenumbers[cursell]; + bufTemp[0] = 0; + } + + if (bufTemp[0] == 0) { + String path = get_save_game_path(toret); + strcpy(bufTemp, path); + } + + lpTemp = &bufTemp[0]; + lpTemp2 = &buffer2[0]; + } else if (mes.id == ctrlcancel) { + lpTemp = nullptr; + } + break; + } else if (mes.code == CM_SELCHANGE) { + int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + if (cursel >= 0) { + CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursel, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + } + } + } + + CSCIDeleteControl(ctrltbox); + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrllist); + CSCIDeleteControl(ctrlok); + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + return toret; } -void preparesavegamelist(int ctrllist) -{ - numsaves = 0; - toomanygames = 0; - al_ffblk ffb; - int bufix = 0; - - String svg_dir = get_save_game_directory(); - String svg_suff = get_save_game_suffix(); - String searchPath = String::FromFormat("%s""agssave.*%s", svg_dir.GetCStr(), svg_suff.GetCStr()); - - int don = al_findfirst(searchPath, &ffb, -1); - while (!don) { - bufix = 0; - if (numsaves >= MAXSAVEGAMES) { - toomanygames = 1; - break; - } - - // only list games .000 to .099 (to allow higher slots for other purposes) - if (strstr(ffb.name, ".0") == nullptr) { - don = al_findnext(&ffb); - continue; - } - - const char *numberExtension = strstr(ffb.name, ".0") + 1; - int sgNumber = atoi(numberExtension); - - String thisGamePath = get_save_game_path(sgNumber); - - // get description - String description; - read_savedgame_description(thisGamePath, description); - - CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)description.GetCStr()); - // Select the first item - CSCISendControlMessage(ctrllist, CLB_SETCURSEL, 0, 0); - filenumbers[numsaves] = sgNumber; - filedates[numsaves] = (long int)ffb.time; - numsaves++; - don = al_findnext(&ffb); - } - - al_findclose(&ffb); - if (numsaves >= MAXSAVEGAMES) - toomanygames = 1; - - for (int nn = 0; nn < numsaves - 1; nn++) { - for (int kk = 0; kk < numsaves - 1; kk++) { // Date order the games - if (filedates[kk] < filedates[kk + 1]) { // swap them round - CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk, (long)&buff[0]); - CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk + 1, (long)&buffer2[0]); - CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk + 1, (long)&buff[0]); - CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk, (long)&buffer2[0]); - int numtem = filenumbers[kk]; - filenumbers[kk] = filenumbers[kk + 1]; - filenumbers[kk + 1] = numtem; - long numted = filedates[kk]; - filedates[kk] = filedates[kk + 1]; - filedates[kk + 1] = numted; - } - } - } +void preparesavegamelist(int ctrllist) { + numsaves = 0; + toomanygames = 0; + al_ffblk ffb; + int bufix = 0; + + String svg_dir = get_save_game_directory(); + String svg_suff = get_save_game_suffix(); + String searchPath = String::FromFormat("%s""agssave.*%s", svg_dir.GetCStr(), svg_suff.GetCStr()); + + int don = al_findfirst(searchPath, &ffb, -1); + while (!don) { + bufix = 0; + if (numsaves >= MAXSAVEGAMES) { + toomanygames = 1; + break; + } + + // only list games .000 to .099 (to allow higher slots for other purposes) + if (strstr(ffb.name, ".0") == nullptr) { + don = al_findnext(&ffb); + continue; + } + + const char *numberExtension = strstr(ffb.name, ".0") + 1; + int sgNumber = atoi(numberExtension); + + String thisGamePath = get_save_game_path(sgNumber); + + // get description + String description; + read_savedgame_description(thisGamePath, description); + + CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)description.GetCStr()); + // Select the first item + CSCISendControlMessage(ctrllist, CLB_SETCURSEL, 0, 0); + filenumbers[numsaves] = sgNumber; + filedates[numsaves] = (long int)ffb.time; + numsaves++; + don = al_findnext(&ffb); + } + + al_findclose(&ffb); + if (numsaves >= MAXSAVEGAMES) + toomanygames = 1; + + for (int nn = 0; nn < numsaves - 1; nn++) { + for (int kk = 0; kk < numsaves - 1; kk++) { // Date order the games + if (filedates[kk] < filedates[kk + 1]) { // swap them round + CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk, (long)&buff[0]); + CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk + 1, (long)&buffer2[0]); + CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk + 1, (long)&buff[0]); + CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk, (long)&buffer2[0]); + int numtem = filenumbers[kk]; + filenumbers[kk] = filenumbers[kk + 1]; + filenumbers[kk + 1] = numtem; + long numted = filedates[kk]; + filedates[kk] = filedates[kk + 1]; + filedates[kk + 1] = numted; + } + } + } } -void enterstringwindow(const char *prompttext, char *stouse) -{ - const int wnd_width = 200; - const int wnd_height = 40; - const int boxleft = 60, boxtop = 80; - int wantCancel = 0; - if (prompttext[0] == '!') { - wantCancel = 1; - prompttext++; - } - - int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); - int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, "OK"); - int ctrlcancel = -1; - if (wantCancel) - ctrlcancel = CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 20, 60, 10, get_global_message(MSG_CANCEL)); - int ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); - int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, 5, 120, 0, prompttext); - CSCIMessage mes; - - while (1) { - CSCIWaitMessage(&mes); - if (mes.code == CM_COMMAND) { - if (mes.id == ctrlcancel) - buffer2[0] = 0; - else - CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); - break; - } - } - - CSCIDeleteControl(ctrltex1); - CSCIDeleteControl(ctrltbox); - CSCIDeleteControl(ctrlok); - if (wantCancel) - CSCIDeleteControl(ctrlcancel); - CSCIEraseWindow(handl); - strcpy(stouse, buffer2); +void enterstringwindow(const char *prompttext, char *stouse) { + const int wnd_width = 200; + const int wnd_height = 40; + const int boxleft = 60, boxtop = 80; + int wantCancel = 0; + if (prompttext[0] == '!') { + wantCancel = 1; + prompttext++; + } + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, "OK"); + int ctrlcancel = -1; + if (wantCancel) + ctrlcancel = CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 20, 60, 10, get_global_message(MSG_CANCEL)); + int ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, 5, 120, 0, prompttext); + CSCIMessage mes; + + while (1) { + CSCIWaitMessage(&mes); + if (mes.code == CM_COMMAND) { + if (mes.id == ctrlcancel) + buffer2[0] = 0; + else + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + break; + } + } + + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrltbox); + CSCIDeleteControl(ctrlok); + if (wantCancel) + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + strcpy(stouse, buffer2); } -int enternumberwindow(char *prompttext) -{ - char ourbuf[200]; - enterstringwindow(prompttext, ourbuf); - if (ourbuf[0] == 0) - return -9999; - return atoi(ourbuf); +int enternumberwindow(char *prompttext) { + char ourbuf[200]; + enterstringwindow(prompttext, ourbuf); + if (ourbuf[0] == 0) + return -9999; + return atoi(ourbuf); } -int roomSelectorWindow(int currentRoom, int numRooms, int*roomNumbers, char**roomNames) -{ - char labeltext[200]; - strcpy(labeltext, get_global_message(MSG_SAVEDIALOG)); - const int wnd_width = 240; - const int wnd_height = 160; - const int boxleft = myscrnwid / 2 - wnd_width / 2; - const int boxtop = myscrnhit / 2 - wnd_height / 2; - const int labeltop = 5; - - int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); - int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 220, 100, nullptr); - int ctrlcancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 80, 145, 60, 10, "Cancel"); - - CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box - for (int aa = 0; aa < numRooms; aa++) - { - sprintf(buff, "%3d %s", roomNumbers[aa], roomNames[aa]); - CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)&buff[0]); - if (roomNumbers[aa] == currentRoom) - { - CSCISendControlMessage(ctrllist, CLB_SETCURSEL, aa, 0); - } - } - - int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 10, 145, 60, 10, "OK"); - int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, labeltop, 180, 0, "Choose which room to go to:"); - CSCIMessage mes; - - lpTemp = nullptr; - buffer2[0] = 0; - - int ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); - - int toret = -1; - while (1) { - CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); - if (mes.code == CM_COMMAND) - { - if (mes.id == ctrlok) - { - CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); - if (isdigit(buffer2[0])) - { - toret = atoi(buffer2); - } - } - else if (mes.id == ctrlcancel) - { - } - break; - } - else if (mes.code == CM_SELCHANGE) - { - int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); - if (cursel >= 0) - { - sprintf(buffer2, "%d", roomNumbers[cursel]); - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); - } - } - } - - CSCIDeleteControl(ctrltbox); - CSCIDeleteControl(ctrltex1); - CSCIDeleteControl(ctrllist); - CSCIDeleteControl(ctrlok); - CSCIDeleteControl(ctrlcancel); - CSCIEraseWindow(handl); - return toret; +int roomSelectorWindow(int currentRoom, int numRooms, int *roomNumbers, char **roomNames) { + char labeltext[200]; + strcpy(labeltext, get_global_message(MSG_SAVEDIALOG)); + const int wnd_width = 240; + const int wnd_height = 160; + const int boxleft = myscrnwid / 2 - wnd_width / 2; + const int boxtop = myscrnhit / 2 - wnd_height / 2; + const int labeltop = 5; + + int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 220, 100, nullptr); + int ctrlcancel = + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 80, 145, 60, 10, "Cancel"); + + CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box + for (int aa = 0; aa < numRooms; aa++) { + sprintf(buff, "%3d %s", roomNumbers[aa], roomNames[aa]); + CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)&buff[0]); + if (roomNumbers[aa] == currentRoom) { + CSCISendControlMessage(ctrllist, CLB_SETCURSEL, aa, 0); + } + } + + int ctrlok = CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 10, 145, 60, 10, "OK"); + int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, labeltop, 180, 0, "Choose which room to go to:"); + CSCIMessage mes; + + lpTemp = nullptr; + buffer2[0] = 0; + + int ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + + int toret = -1; + while (1) { + CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); + if (mes.code == CM_COMMAND) { + if (mes.id == ctrlok) { + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + if (isdigit(buffer2[0])) { + toret = atoi(buffer2); + } + } else if (mes.id == ctrlcancel) { + } + break; + } else if (mes.code == CM_SELCHANGE) { + int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); + if (cursel >= 0) { + sprintf(buffer2, "%d", roomNumbers[cursel]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + } + } + } + + CSCIDeleteControl(ctrltbox); + CSCIDeleteControl(ctrltex1); + CSCIDeleteControl(ctrllist); + CSCIDeleteControl(ctrlok); + CSCIDeleteControl(ctrlcancel); + CSCIEraseWindow(handl); + return toret; } -int myscimessagebox(const char *lpprompt, char *btn1, char *btn2) -{ - const int wnd_width = 240 - 80; - const int wnd_height = 120 - 80; - const int boxleft = 80; - const int boxtop = 80; +int myscimessagebox(const char *lpprompt, char *btn1, char *btn2) { + const int wnd_width = 240 - 80; + const int wnd_height = 120 - 80; + const int boxleft = 80; + const int boxtop = 80; - int windl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); - int lbl1 = CSCICreateControl(CNT_LABEL, 10, 5, 150, 0, lpprompt); - int btflag = CNT_PUSHBUTTON; + int windl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); + int lbl1 = CSCICreateControl(CNT_LABEL, 10, 5, 150, 0, lpprompt); + int btflag = CNT_PUSHBUTTON; - if (btn2 == nullptr) - btflag |= CNF_DEFAULT | CNF_CANCEL; - else - btflag |= CNF_DEFAULT; + if (btn2 == nullptr) + btflag |= CNF_DEFAULT | CNF_CANCEL; + else + btflag |= CNF_DEFAULT; - int btnQuit = CSCICreateControl(btflag, 10, 25, 60, 10, btn1); - int btnPlay = 0; + int btnQuit = CSCICreateControl(btflag, 10, 25, 60, 10, btn1); + int btnPlay = 0; - if (btn2 != nullptr) - btnPlay = CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 85, 25, 60, 10, btn2); + if (btn2 != nullptr) + btnPlay = CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 85, 25, 60, 10, btn2); - smes.code = 0; + smes.code = 0; - do { - CSCIWaitMessage(&smes); - } while (smes.code != CM_COMMAND); + do { + CSCIWaitMessage(&smes); + } while (smes.code != CM_COMMAND); - if (btnPlay) - CSCIDeleteControl(btnPlay); + if (btnPlay) + CSCIDeleteControl(btnPlay); - CSCIDeleteControl(btnQuit); - CSCIDeleteControl(lbl1); - CSCIEraseWindow(windl); + CSCIDeleteControl(btnQuit); + CSCIDeleteControl(lbl1); + CSCIEraseWindow(windl); - if (smes.id == btnQuit) - return 1; + if (smes.id == btnQuit) + return 1; - return 0; + return 0; } -int quitdialog() -{ - char quitbut[50], playbut[50]; - strcpy(quitbut, get_global_message(MSG_QUITBUTTON)); - strcpy(playbut, get_global_message(MSG_PLAYBUTTON)); - return myscimessagebox(get_global_message(MSG_QUITDIALOG), quitbut, playbut); +int quitdialog() { + char quitbut[50], playbut[50]; + strcpy(quitbut, get_global_message(MSG_QUITBUTTON)); + strcpy(playbut, get_global_message(MSG_PLAYBUTTON)); + return myscimessagebox(get_global_message(MSG_QUITDIALOG), quitbut, playbut); } diff --git a/engines/ags/engine/gui/guidialog.h b/engines/ags/engine/gui/guidialog.h index 1c605e3cc192..883a68009fb3 100644 --- a/engines/ags/engine/gui/guidialog.h +++ b/engines/ags/engine/gui/guidialog.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_GUI_GUIDIALOG_H #define AGS_ENGINE_GUI_GUIDIALOG_H -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} // Functions for handling hard-coded GUIs // Prepares GUI bitmaps which will be passed to the renderer's draw chain @@ -39,7 +43,7 @@ int savegamedialog(); void preparesavegamelist(int ctrllist); void enterstringwindow(const char *prompttext, char *stouse); int enternumberwindow(char *prompttext); -int roomSelectorWindow(int currentRoom, int numRooms, int*roomNumbers, char**roomNames); +int roomSelectorWindow(int currentRoom, int numRooms, int *roomNumbers, char **roomNames); int myscimessagebox(const char *lpprompt, char *btn1, char *btn2); int quitdialog(); diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h index c805a77f3e2d..2cbc25fa0b61 100644 --- a/engines/ags/engine/gui/guidialogdefines.h +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -85,32 +85,33 @@ #define CTB_KEYPRESS 91 -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later // ========= STRUCTS ======== -struct DisplayProperties -{ - int width; - int height; - int colors; - int textheight; +struct DisplayProperties { + int width; + int height; + int colors; + int textheight; }; -struct CSCIMessage -{ - int code; - int id; - int wParam; +struct CSCIMessage { + int code; + int id; + int wParam; }; -struct OnScreenWindow -{ - int x, y; - int handle; - int oldtop; +struct OnScreenWindow { + int x, y; + int handle; + int oldtop; - OnScreenWindow(); + OnScreenWindow(); }; #endif diff --git a/engines/ags/engine/gui/guidialoginternaldefs.h b/engines/ags/engine/gui/guidialoginternaldefs.h index c00842cdde16..cb305e884f1e 100644 --- a/engines/ags/engine/gui/guidialoginternaldefs.h +++ b/engines/ags/engine/gui/guidialoginternaldefs.h @@ -30,7 +30,7 @@ #undef WINAPI #endif #define WINAPI -extern int ags_misbuttondown (int but); +extern int ags_misbuttondown(int but); #define mbutrelease(X) (!ags_misbuttondown(X)) #define TEXT_HT usetup.textheight diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp index 0efed9968488..5068358f177c 100644 --- a/engines/ags/engine/gui/mylabel.cpp +++ b/engines/ags/engine/gui/mylabel.cpp @@ -35,36 +35,32 @@ extern GameSetup usetup; extern int acdialog_font; -MyLabel::MyLabel(int xx, int yy, int wii, const char *tee) -{ - strncpy(text, tee, 150); - text[149] = 0; - x = xx; - y = yy; - wid = wii; - hit = TEXT_HT; +MyLabel::MyLabel(int xx, int yy, int wii, const char *tee) { + strncpy(text, tee, 150); + text[149] = 0; + x = xx; + y = yy; + wid = wii; + hit = TEXT_HT; } -void MyLabel::draw(Bitmap *ds) -{ - int cyp = y; - char *teptr = &text[0]; - color_t text_color = ds->GetCompatibleColor(0); +void MyLabel::draw(Bitmap *ds) { + int cyp = y; + char *teptr = &text[0]; + color_t text_color = ds->GetCompatibleColor(0); - if (break_up_text_into_lines(teptr, Lines, wid, acdialog_font) == 0) - return; - for (size_t ee = 0; ee < Lines.Count(); ee++) { - wouttext_outline(ds, x, cyp, acdialog_font, text_color, Lines[ee]); - cyp += TEXT_HT; - } + if (break_up_text_into_lines(teptr, Lines, wid, acdialog_font) == 0) + return; + for (size_t ee = 0; ee < Lines.Count(); ee++) { + wouttext_outline(ds, x, cyp, acdialog_font, text_color, Lines[ee]); + cyp += TEXT_HT; + } } -int MyLabel::pressedon(int mousex, int mousey) -{ - return 0; +int MyLabel::pressedon(int mousex, int mousey) { + return 0; } -int MyLabel::processmessage(int mcode, int wParam, long lParam) -{ - return -1; // doesn't support messages +int MyLabel::processmessage(int mcode, int wParam, long lParam) { + return -1; // doesn't support messages } diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h index 49f891b28d8e..87ed7cb9f760 100644 --- a/engines/ags/engine/gui/mylabel.h +++ b/engines/ags/engine/gui/mylabel.h @@ -25,16 +25,15 @@ #include "gui/newcontrol.h" -struct MyLabel:public NewControl -{ - char text[150]; - MyLabel(int xx, int yy, int wii, const char *tee); +struct MyLabel: public NewControl { + char text[150]; + MyLabel(int xx, int yy, int wii, const char *tee); - void draw(Common::Bitmap *ds) override; + void draw(Common::Bitmap *ds) override; - int pressedon(int mousex, int mousey) override; + int pressedon(int mousex, int mousey) override; - int processmessage(int mcode, int wParam, long lParam) override; + int processmessage(int mcode, int wParam, long lParam) override; }; #endif diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index 7253ecdde4c6..cee6e3bf1c12 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -39,168 +39,159 @@ extern int windowbackgroundcolor; extern int cbuttfont; extern int smcode; - MyListBox::MyListBox(int xx, int yy, int wii, int hii) - { - x = xx; - y = yy; - wid = wii; - hit = hii; - hit -= (hit - 4) % TEXT_HT; // resize to multiple of text height - numonscreen = (hit - 4) / TEXT_HT; - items = 0; - topitem = 0; - selected = -1; - memset(itemnames, 0, sizeof(itemnames)); - } - - void MyListBox::clearlist() - { - for (int kk = 0; kk < items; kk++) - free(itemnames[kk]); - - items = 0; - } - - MyListBox::~MyListBox() { - clearlist(); - } - - void MyListBox::draw(Bitmap *ds) - { - color_t draw_color = ds->GetCompatibleColor(windowbackgroundcolor); - ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); - draw_color = ds->GetCompatibleColor(0); - ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); - - int widwas = wid; - wid -= ARROWWIDTH; - ds->DrawLine(Line(x + wid, y, x + wid, y + hit), draw_color); // draw the up/down arrows - ds->DrawLine(Line(x + wid, y + hit / 2, x + widwas, y + hit / 2), draw_color); - - int xmidd = x + wid + (widwas - wid) / 2; - if (topitem < 1) - draw_color = ds->GetCompatibleColor(7); - - ds->DrawLine(Line(xmidd, y + 2, xmidd, y + 10), draw_color); // up arrow - ds->DrawLine(Line(xmidd - 1, y + 3, xmidd + 1, y + 3), draw_color); - ds->DrawLine(Line(xmidd - 2, y + 4, xmidd + 2, y + 4), draw_color); - draw_color = ds->GetCompatibleColor(0); - if (topitem + numonscreen >= items) - draw_color = ds->GetCompatibleColor(7); - - ds->DrawLine(Line(xmidd, y + hit - 10, xmidd, y + hit - 3), draw_color); // down arrow - ds->DrawLine(Line(xmidd - 1, y + hit - 4, xmidd + 1, y + hit - 4), draw_color); - ds->DrawLine(Line(xmidd - 2, y + hit - 5, xmidd + 2, y + hit - 5), draw_color); - draw_color = ds->GetCompatibleColor(0); - - for (int tt = 0; tt < numonscreen; tt++) { - int inum = tt + topitem; - if (inum >= items) - break; - - int thisypos = y + 2 + tt * TEXT_HT; - color_t text_color; - if (inum == selected) { - draw_color = ds->GetCompatibleColor(0); - ds->FillRect(Rect(x, thisypos, x + wid, thisypos + TEXT_HT - 1), draw_color); - text_color = ds->GetCompatibleColor(7); - } - else text_color = ds->GetCompatibleColor(0); - - wouttextxy(ds, x + 2, thisypos, cbuttfont, text_color, itemnames[inum]); - } - wid = widwas; - } - - int MyListBox::pressedon(int mousex, int mousey) - { - if (mousex > x + wid - ARROWWIDTH) { - if ((mousey - y < hit / 2) & (topitem > 0)) - topitem--; - else if ((mousey - y > hit / 2) & (topitem + numonscreen < items)) - topitem++; - - } else { - selected = ((mousey - y) - 2) / TEXT_HT + topitem; - if (selected >= items) - selected = items - 1; - - } +MyListBox::MyListBox(int xx, int yy, int wii, int hii) { + x = xx; + y = yy; + wid = wii; + hit = hii; + hit -= (hit - 4) % TEXT_HT; // resize to multiple of text height + numonscreen = (hit - 4) / TEXT_HT; + items = 0; + topitem = 0; + selected = -1; + memset(itemnames, 0, sizeof(itemnames)); +} + +void MyListBox::clearlist() { + for (int kk = 0; kk < items; kk++) + free(itemnames[kk]); + + items = 0; +} + +MyListBox::~MyListBox() { + clearlist(); +} + +void MyListBox::draw(Bitmap *ds) { + color_t draw_color = ds->GetCompatibleColor(windowbackgroundcolor); + ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); + + int widwas = wid; + wid -= ARROWWIDTH; + ds->DrawLine(Line(x + wid, y, x + wid, y + hit), draw_color); // draw the up/down arrows + ds->DrawLine(Line(x + wid, y + hit / 2, x + widwas, y + hit / 2), draw_color); + + int xmidd = x + wid + (widwas - wid) / 2; + if (topitem < 1) + draw_color = ds->GetCompatibleColor(7); + + ds->DrawLine(Line(xmidd, y + 2, xmidd, y + 10), draw_color); // up arrow + ds->DrawLine(Line(xmidd - 1, y + 3, xmidd + 1, y + 3), draw_color); + ds->DrawLine(Line(xmidd - 2, y + 4, xmidd + 2, y + 4), draw_color); + draw_color = ds->GetCompatibleColor(0); + if (topitem + numonscreen >= items) + draw_color = ds->GetCompatibleColor(7); + + ds->DrawLine(Line(xmidd, y + hit - 10, xmidd, y + hit - 3), draw_color); // down arrow + ds->DrawLine(Line(xmidd - 1, y + hit - 4, xmidd + 1, y + hit - 4), draw_color); + ds->DrawLine(Line(xmidd - 2, y + hit - 5, xmidd + 2, y + hit - 5), draw_color); + draw_color = ds->GetCompatibleColor(0); + + for (int tt = 0; tt < numonscreen; tt++) { + int inum = tt + topitem; + if (inum >= items) + break; + + int thisypos = y + 2 + tt * TEXT_HT; + color_t text_color; + if (inum == selected) { + draw_color = ds->GetCompatibleColor(0); + ds->FillRect(Rect(x, thisypos, x + wid, thisypos + TEXT_HT - 1), draw_color); + text_color = ds->GetCompatibleColor(7); + } else text_color = ds->GetCompatibleColor(0); + + wouttextxy(ds, x + 2, thisypos, cbuttfont, text_color, itemnames[inum]); + } + wid = widwas; +} + +int MyListBox::pressedon(int mousex, int mousey) { + if (mousex > x + wid - ARROWWIDTH) { + if ((mousey - y < hit / 2) & (topitem > 0)) + topitem--; + else if ((mousey - y > hit / 2) & (topitem + numonscreen < items)) + topitem++; + + } else { + selected = ((mousey - y) - 2) / TEXT_HT + topitem; + if (selected >= items) + selected = items - 1; + + } // ags_domouse(DOMOUSE_DISABLE); - draw(get_gui_screen()); - // ags_domouse(DOMOUSE_ENABLE); - smcode = CM_SELCHANGE; - return 0; - } - - void MyListBox::additem(char *texx) - { - if (items >= MAXLISTITEM) - quit("!CSCIUSER16: Too many items added to listbox"); - itemnames[items] = (char *)malloc(strlen(texx) + 1); - strcpy(itemnames[items], texx); - items++; - needredraw = 1; - } - - int MyListBox::processmessage(int mcode, int wParam, long lParam) - { - if (mcode == CLB_ADDITEM) { - additem((char *)lParam); - } else if (mcode == CLB_CLEAR) - clearlist(); - else if (mcode == CLB_GETCURSEL) - return selected; - else if (mcode == CLB_SETCURSEL) - { - selected = wParam; - - if ((selected < topitem) && (selected >= 0)) - topitem = selected; - - if (topitem + numonscreen <= selected) - topitem = (selected + 1) - numonscreen; - } - else if (mcode == CLB_GETTEXT) - strcpy((char *)lParam, itemnames[wParam]); - else if (mcode == CLB_SETTEXT) { - if (wParam < items) - free(itemnames[wParam]); - - char *newstri = (char *)lParam; - itemnames[wParam] = (char *)malloc(strlen(newstri) + 2); - strcpy(itemnames[wParam], newstri); - - } else if (mcode == CTB_KEYPRESS) { - if ((wParam == 380) && (selected < items - 1)) - selected++; - - if ((wParam == 372) && (selected > 0)) - selected--; - - if (wParam == 373) - selected -= (numonscreen - 1); - - if (wParam == 381) - selected += (numonscreen - 1); - - if ((selected < 0) && (items > 0)) - selected = 0; - - if (selected >= items) - selected = items - 1; - - if ((selected < topitem) & (selected >= 0)) - topitem = selected; - - if (topitem + numonscreen <= selected) - topitem = (selected + 1) - numonscreen; - - drawandmouse(); - smcode = CM_SELCHANGE; - } else - return -1; - - return 0; - } + draw(get_gui_screen()); + // ags_domouse(DOMOUSE_ENABLE); + smcode = CM_SELCHANGE; + return 0; +} + +void MyListBox::additem(char *texx) { + if (items >= MAXLISTITEM) + quit("!CSCIUSER16: Too many items added to listbox"); + itemnames[items] = (char *)malloc(strlen(texx) + 1); + strcpy(itemnames[items], texx); + items++; + needredraw = 1; +} + +int MyListBox::processmessage(int mcode, int wParam, long lParam) { + if (mcode == CLB_ADDITEM) { + additem((char *)lParam); + } else if (mcode == CLB_CLEAR) + clearlist(); + else if (mcode == CLB_GETCURSEL) + return selected; + else if (mcode == CLB_SETCURSEL) { + selected = wParam; + + if ((selected < topitem) && (selected >= 0)) + topitem = selected; + + if (topitem + numonscreen <= selected) + topitem = (selected + 1) - numonscreen; + } else if (mcode == CLB_GETTEXT) + strcpy((char *)lParam, itemnames[wParam]); + else if (mcode == CLB_SETTEXT) { + if (wParam < items) + free(itemnames[wParam]); + + char *newstri = (char *)lParam; + itemnames[wParam] = (char *)malloc(strlen(newstri) + 2); + strcpy(itemnames[wParam], newstri); + + } else if (mcode == CTB_KEYPRESS) { + if ((wParam == 380) && (selected < items - 1)) + selected++; + + if ((wParam == 372) && (selected > 0)) + selected--; + + if (wParam == 373) + selected -= (numonscreen - 1); + + if (wParam == 381) + selected += (numonscreen - 1); + + if ((selected < 0) && (items > 0)) + selected = 0; + + if (selected >= items) + selected = items - 1; + + if ((selected < topitem) & (selected >= 0)) + topitem = selected; + + if (topitem + numonscreen <= selected) + topitem = (selected + 1) - numonscreen; + + drawandmouse(); + smcode = CM_SELCHANGE; + } else + return -1; + + return 0; +} diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h index d65a6b69cd1b..b9b599b83994 100644 --- a/engines/ags/engine/gui/mylistbox.h +++ b/engines/ags/engine/gui/mylistbox.h @@ -28,18 +28,17 @@ #define MAXLISTITEM 300 #define ARROWWIDTH 8 -struct MyListBox:public NewControl -{ - int items, topitem, numonscreen, selected; - char *itemnames[MAXLISTITEM]; - MyListBox(int xx, int yy, int wii, int hii); - void clearlist(); - ~MyListBox() override; +struct MyListBox: public NewControl { + int items, topitem, numonscreen, selected; + char *itemnames[MAXLISTITEM]; + MyListBox(int xx, int yy, int wii, int hii); + void clearlist(); + ~MyListBox() override; - void draw(Common::Bitmap *ds) override; - int pressedon(int mousex, int mousey) override; - void additem(char *texx); - int processmessage(int mcode, int wParam, long lParam) override; + void draw(Common::Bitmap *ds) override; + int pressedon(int mousex, int mousey) override; + void additem(char *texx); + int processmessage(int mcode, int wParam, long lParam) override; }; #endif diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index a44755418843..f9432db1ac10 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -39,76 +39,73 @@ extern int windowbackgroundcolor, pushbuttondarkcolor; extern int pushbuttonlightcolor; extern int cbuttfont; -MyPushButton::MyPushButton(int xx, int yy, int wi, int hi, const char *tex) -{ //wlevel=2; - x = xx; - y = yy; - wid = wi; - hit = hi + 1; //hit=hi; - state = 0; - strncpy(text, tex, 50); - text[49] = 0; +MyPushButton::MyPushButton(int xx, int yy, int wi, int hi, const char *tex) { + //wlevel=2; + x = xx; + y = yy; + wid = wi; + hit = hi + 1; //hit=hi; + state = 0; + strncpy(text, tex, 50); + text[49] = 0; }; -void MyPushButton::draw(Bitmap *ds) -{ - color_t text_color = ds->GetCompatibleColor(0); - color_t draw_color = ds->GetCompatibleColor(COL254); - ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); - if (state == 0) - draw_color = ds->GetCompatibleColor(pushbuttondarkcolor); - else - draw_color = ds->GetCompatibleColor(pushbuttonlightcolor); +void MyPushButton::draw(Bitmap *ds) { + color_t text_color = ds->GetCompatibleColor(0); + color_t draw_color = ds->GetCompatibleColor(COL254); + ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); + if (state == 0) + draw_color = ds->GetCompatibleColor(pushbuttondarkcolor); + else + draw_color = ds->GetCompatibleColor(pushbuttonlightcolor); - ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); - if (state == 0) - draw_color = ds->GetCompatibleColor(pushbuttonlightcolor); - else - draw_color = ds->GetCompatibleColor(pushbuttondarkcolor); + ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); + if (state == 0) + draw_color = ds->GetCompatibleColor(pushbuttonlightcolor); + else + draw_color = ds->GetCompatibleColor(pushbuttondarkcolor); - ds->DrawLine(Line(x, y, x + wid - 1, y), draw_color); - ds->DrawLine(Line(x, y, x, y + hit - 1), draw_color); - wouttextxy(ds, x + (wid / 2 - wgettextwidth(text, cbuttfont) / 2), y + 2, cbuttfont, text_color, text); - if (typeandflags & CNF_DEFAULT) - draw_color = ds->GetCompatibleColor(0); - else - draw_color = ds->GetCompatibleColor(windowbackgroundcolor); + ds->DrawLine(Line(x, y, x + wid - 1, y), draw_color); + ds->DrawLine(Line(x, y, x, y + hit - 1), draw_color); + wouttextxy(ds, x + (wid / 2 - wgettextwidth(text, cbuttfont) / 2), y + 2, cbuttfont, text_color, text); + if (typeandflags & CNF_DEFAULT) + draw_color = ds->GetCompatibleColor(0); + else + draw_color = ds->GetCompatibleColor(windowbackgroundcolor); - ds->DrawRect(Rect(x - 1, y - 1, x + wid + 1, y + hit + 1), draw_color); + ds->DrawRect(Rect(x - 1, y - 1, x + wid + 1, y + hit + 1), draw_color); } //extern const int LEFT; // in mousew32 -int MyPushButton::pressedon(int mousex, int mousey) -{ - int wasstat; - while (mbutrelease(LEFT) == 0) { +int MyPushButton::pressedon(int mousex, int mousey) { + int wasstat; + while (mbutrelease(LEFT) == 0) { - wasstat = state; - state = mouseisinarea(mousex, mousey); - // stop mp3 skipping if button held down - update_polled_stuff_if_runtime(); - if (wasstat != state) { - // ags_domouse(DOMOUSE_DISABLE); - draw(get_gui_screen()); - //ags_domouse(DOMOUSE_ENABLE); - } + wasstat = state; + state = mouseisinarea(mousex, mousey); + // stop mp3 skipping if button held down + update_polled_stuff_if_runtime(); + if (wasstat != state) { + // ags_domouse(DOMOUSE_DISABLE); + draw(get_gui_screen()); + //ags_domouse(DOMOUSE_ENABLE); + } - // ags_domouse(DOMOUSE_UPDATE); + // ags_domouse(DOMOUSE_UPDATE); - refresh_gui_screen(); + refresh_gui_screen(); - WaitForNextFrame(); - } - wasstat = state; - state = 0; - // ags_domouse(DOMOUSE_DISABLE); - draw(get_gui_screen()); - // ags_domouse(DOMOUSE_ENABLE); - return wasstat; + WaitForNextFrame(); + } + wasstat = state; + state = 0; + // ags_domouse(DOMOUSE_DISABLE); + draw(get_gui_screen()); + // ags_domouse(DOMOUSE_ENABLE); + return wasstat; } -int MyPushButton::processmessage(int mcode, int wParam, long lParam) -{ - return -1; // doesn't support messages +int MyPushButton::processmessage(int mcode, int wParam, long lParam) { + return -1; // doesn't support messages } diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h index 00b21f624e97..92147b484050 100644 --- a/engines/ags/engine/gui/mypushbutton.h +++ b/engines/ags/engine/gui/mypushbutton.h @@ -25,13 +25,12 @@ #include "gui/newcontrol.h" -struct MyPushButton:public NewControl -{ - char text[50]; - MyPushButton(int xx, int yy, int wi, int hi, const char *tex); - void draw(Common::Bitmap *ds) override; - int pressedon(int mousex, int mousey) override; - int processmessage(int mcode, int wParam, long lParam) override; +struct MyPushButton: public NewControl { + char text[50]; + MyPushButton(int xx, int yy, int wi, int hi, const char *tex); + void draw(Common::Bitmap *ds) override; + int pressedon(int mousex, int mousey) override; + int processmessage(int mcode, int wParam, long lParam) override; }; #endif diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp index 945b04706ff1..5f23f9fd54d2 100644 --- a/engines/ags/engine/gui/mytextbox.cpp +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -34,63 +34,59 @@ extern GameSetup usetup; extern int windowbackgroundcolor; extern int cbuttfont; -MyTextBox::MyTextBox(int xx, int yy, int wii, const char *tee) -{ - x = xx; - y = yy; - wid = wii; - if (tee != nullptr) - strcpy(text, tee); - else - text[0] = 0; +MyTextBox::MyTextBox(int xx, int yy, int wii, const char *tee) { + x = xx; + y = yy; + wid = wii; + if (tee != nullptr) + strcpy(text, tee); + else + text[0] = 0; - hit = TEXT_HT + 1; + hit = TEXT_HT + 1; } -void MyTextBox::draw(Bitmap *ds) -{ - color_t draw_color = ds->GetCompatibleColor(windowbackgroundcolor); - ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); - draw_color = ds->GetCompatibleColor(0); - ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); - color_t text_color = ds->GetCompatibleColor(0); - wouttextxy(ds, x + 2, y + 1, cbuttfont, text_color, text); +void MyTextBox::draw(Bitmap *ds) { + color_t draw_color = ds->GetCompatibleColor(windowbackgroundcolor); + ds->FillRect(Rect(x, y, x + wid, y + hit), draw_color); + draw_color = ds->GetCompatibleColor(0); + ds->DrawRect(Rect(x, y, x + wid, y + hit), draw_color); + color_t text_color = ds->GetCompatibleColor(0); + wouttextxy(ds, x + 2, y + 1, cbuttfont, text_color, text); - char tbu[2] = "_"; - wouttextxy(ds, x + 2 + wgettextwidth(text, cbuttfont), y + 1, cbuttfont, text_color, tbu); + char tbu[2] = "_"; + wouttextxy(ds, x + 2 + wgettextwidth(text, cbuttfont), y + 1, cbuttfont, text_color, tbu); } -int MyTextBox::pressedon(int mousex, int mousey) -{ - return 0; +int MyTextBox::pressedon(int mousex, int mousey) { + return 0; } -int MyTextBox::processmessage(int mcode, int wParam, long lParam) -{ - if (mcode == CTB_SETTEXT) { - strcpy(text, (char *)lParam); - needredraw = 1; - } else if (mcode == CTB_GETTEXT) - strcpy((char *)lParam, text); - else if (mcode == CTB_KEYPRESS) { - if (wParam == 8) { - if (text[0] != 0) - text[strlen(text) - 1] = 0; +int MyTextBox::processmessage(int mcode, int wParam, long lParam) { + if (mcode == CTB_SETTEXT) { + strcpy(text, (char *)lParam); + needredraw = 1; + } else if (mcode == CTB_GETTEXT) + strcpy((char *)lParam, text); + else if (mcode == CTB_KEYPRESS) { + if (wParam == 8) { + if (text[0] != 0) + text[strlen(text) - 1] = 0; - drawandmouse(); - } else if (strlen(text) >= TEXTBOX_MAXLEN - 1) - ; - else if (wgettextwidth(text, cbuttfont) >= wid - 5) - ; - else if (wParam > 127) - ; // font only has 128 chars - else { - text[strlen(text) + 1] = 0; - text[strlen(text)] = wParam; - drawandmouse(); - } - } else - return -1; + drawandmouse(); + } else if (strlen(text) >= TEXTBOX_MAXLEN - 1) + ; + else if (wgettextwidth(text, cbuttfont) >= wid - 5) + ; + else if (wParam > 127) + ; // font only has 128 chars + else { + text[strlen(text) + 1] = 0; + text[strlen(text)] = wParam; + drawandmouse(); + } + } else + return -1; - return 0; + return 0; } diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h index 0dd68f4a6327..97d9b687d02f 100644 --- a/engines/ags/engine/gui/mytextbox.h +++ b/engines/ags/engine/gui/mytextbox.h @@ -26,13 +26,12 @@ #include "gui/newcontrol.h" #define TEXTBOX_MAXLEN 49 -struct MyTextBox:public NewControl -{ - char text[TEXTBOX_MAXLEN + 1]; - MyTextBox(int xx, int yy, int wii, const char *tee); - void draw(Common::Bitmap *ds) override; - int pressedon(int mousex, int mousey) override; - int processmessage(int mcode, int wParam, long lParam) override; +struct MyTextBox: public NewControl { + char text[TEXTBOX_MAXLEN + 1]; + MyTextBox(int xx, int yy, int wii, const char *tee); + void draw(Common::Bitmap *ds) override; + int pressedon(int mousex, int mousey) override; + int processmessage(int mcode, int wParam, long lParam) override; }; #endif diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp index f3cc9cdede39..80516ce6f53c 100644 --- a/engines/ags/engine/gui/newcontrol.cpp +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -26,50 +26,46 @@ extern int topwindowhandle; -NewControl::NewControl(int xx, int yy, int wi, int hi) -{ - x = xx; - y = yy; - wid = wi; - hit = hi; - state = 0; - typeandflags = 0; - wlevel = 0; - visible = 1; - enabled = 1; - needredraw = 1; +NewControl::NewControl(int xx, int yy, int wi, int hi) { + x = xx; + y = yy; + wid = wi; + hit = hi; + state = 0; + typeandflags = 0; + wlevel = 0; + visible = 1; + enabled = 1; + needredraw = 1; }; NewControl::NewControl() { - x = y = wid = hit = 0; - state = 0; - typeandflags = 0; - wlevel = 0; - visible = 1; - enabled = 1; - needredraw = 1; + x = y = wid = hit = 0; + state = 0; + typeandflags = 0; + wlevel = 0; + visible = 1; + enabled = 1; + needredraw = 1; } -int NewControl::mouseisinarea(int mousex, int mousey) -{ - if (topwindowhandle != wlevel) - return 0; +int NewControl::mouseisinarea(int mousex, int mousey) { + if (topwindowhandle != wlevel) + return 0; - if ((mousex > x) & (mousex < x + wid) & (mousey > y) & (mousey < y + hit)) - return 1; + if ((mousex > x) & (mousex < x + wid) & (mousey > y) & (mousey < y + hit)) + return 1; - return 0; + return 0; } -void NewControl::drawifneeded() -{ - if (topwindowhandle != wlevel) - return; - if (needredraw) { - needredraw = 0; - draw(get_gui_screen()); - } +void NewControl::drawifneeded() { + if (topwindowhandle != wlevel) + return; + if (needredraw) { + needredraw = 0; + draw(get_gui_screen()); + } } -void NewControl::drawandmouse() -{ - // ags_domouse(DOMOUSE_DISABLE); - draw(get_gui_screen()); - // ags_domouse(DOMOUSE_ENABLE); +void NewControl::drawandmouse() { + // ags_domouse(DOMOUSE_DISABLE); + draw(get_gui_screen()); + // ags_domouse(DOMOUSE_ENABLE); } diff --git a/engines/ags/engine/gui/newcontrol.h b/engines/ags/engine/gui/newcontrol.h index a0b7e2081341..e496be3fce4e 100644 --- a/engines/ags/engine/gui/newcontrol.h +++ b/engines/ags/engine/gui/newcontrol.h @@ -27,21 +27,20 @@ using namespace AGS; // FIXME later -struct NewControl -{ - int x, y, wid, hit, state, typeandflags, wlevel; - char visible, enabled; // not implemented - char needredraw; - virtual void draw(Common::Bitmap *ds) = 0; - virtual int pressedon(int mousex, int mousey) = 0; - virtual int processmessage(int, int, long) = 0; +struct NewControl { + int x, y, wid, hit, state, typeandflags, wlevel; + char visible, enabled; // not implemented + char needredraw; + virtual void draw(Common::Bitmap *ds) = 0; + virtual int pressedon(int mousex, int mousey) = 0; + virtual int processmessage(int, int, long) = 0; - NewControl(int xx, int yy, int wi, int hi); - NewControl(); - virtual ~NewControl() = default; - int mouseisinarea(int mousex, int mousey); - void drawifneeded(); - void drawandmouse(); + NewControl(int xx, int yy, int wi, int hi); + NewControl(); + virtual ~NewControl() = default; + int mouseisinarea(int mousex, int mousey); + void drawifneeded(); + void drawandmouse(); }; #endif diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 5be0cc92564b..54b76d84ca43 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -61,368 +61,325 @@ const String DefaultConfigFileName = "acsetup.cfg"; // Replace the filename part of complete path WASGV with INIFIL // TODO: get rid of this and use proper lib path function instead void INIgetdirec(char *wasgv, const char *inifil) { - int u = strlen(wasgv) - 1; + int u = strlen(wasgv) - 1; - for (u = strlen(wasgv) - 1; u >= 0; u--) { - if ((wasgv[u] == '\\') || (wasgv[u] == '/')) { - memcpy(&wasgv[u + 1], inifil, strlen(inifil) + 1); - break; - } - } + for (u = strlen(wasgv) - 1; u >= 0; u--) { + if ((wasgv[u] == '\\') || (wasgv[u] == '/')) { + memcpy(&wasgv[u + 1], inifil, strlen(inifil) + 1); + break; + } + } - if (u <= 0) { - // no slashes - either the path is just "f:acwin.exe" - if (strchr(wasgv, ':') != nullptr) - memcpy(strchr(wasgv, ':') + 1, inifil, strlen(inifil) + 1); - // or it's just "acwin.exe" (unlikely) - else - strcpy(wasgv, inifil); - } + if (u <= 0) { + // no slashes - either the path is just "f:acwin.exe" + if (strchr(wasgv, ':') != nullptr) + memcpy(strchr(wasgv, ':') + 1, inifil, strlen(inifil) + 1); + // or it's just "acwin.exe" (unlikely) + else + strcpy(wasgv, inifil); + } } -bool INIreaditem(const ConfigTree &cfg, const String §n, const String &item, String &value) -{ - ConfigNode sec_it = cfg.find(sectn); - if (sec_it != cfg.end()) - { - StrStrOIter item_it = sec_it->second.find(item); - if (item_it != sec_it->second.end()) - { - value = item_it->second; - return true; - } - } - return false; +bool INIreaditem(const ConfigTree &cfg, const String §n, const String &item, String &value) { + ConfigNode sec_it = cfg.find(sectn); + if (sec_it != cfg.end()) { + StrStrOIter item_it = sec_it->second.find(item); + if (item_it != sec_it->second.end()) { + value = item_it->second; + return true; + } + } + return false; } -int INIreadint(const ConfigTree &cfg, const String §n, const String &item, int def_value) -{ - String str; - if (!INIreaditem(cfg, sectn, item, str)) - return def_value; +int INIreadint(const ConfigTree &cfg, const String §n, const String &item, int def_value) { + String str; + if (!INIreaditem(cfg, sectn, item, str)) + return def_value; - return atoi(str); + return atoi(str); } -float INIreadfloat(const ConfigTree &cfg, const String §n, const String &item, float def_value) -{ - String str; - if (!INIreaditem(cfg, sectn, item, str)) - return def_value; +float INIreadfloat(const ConfigTree &cfg, const String §n, const String &item, float def_value) { + String str; + if (!INIreaditem(cfg, sectn, item, str)) + return def_value; - return atof(str); + return atof(str); } -String INIreadstring(const ConfigTree &cfg, const String §n, const String &item, const String &def_value) -{ - String str; - if (!INIreaditem(cfg, sectn, item, str)) - return def_value; - return str; +String INIreadstring(const ConfigTree &cfg, const String §n, const String &item, const String &def_value) { + String str; + if (!INIreaditem(cfg, sectn, item, str)) + return def_value; + return str; } -void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int value) -{ - cfg[sectn][item] = StrUtil::IntToString(value); +void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int value) { + cfg[sectn][item] = StrUtil::IntToString(value); } -void INIwritestring(ConfigTree &cfg, const String §n, const String &item, const String &value) -{ - cfg[sectn][item] = value; +void INIwritestring(ConfigTree &cfg, const String §n, const String &item, const String &value) { + cfg[sectn][item] = value; } -void parse_scaling_option(const String &scaling_option, FrameScaleDefinition &scale_def, int &scale_factor) -{ - const char *game_scale_options[kNumFrameScaleDef - 1] = { "max_round", "stretch", "proportional" }; - scale_def = kFrame_IntScale; - for (int i = 0; i < kNumFrameScaleDef - 1; ++i) - { - if (scaling_option.CompareNoCase(game_scale_options[i]) == 0) - { - scale_def = (FrameScaleDefinition)(i + 1); - break; - } - } +void parse_scaling_option(const String &scaling_option, FrameScaleDefinition &scale_def, int &scale_factor) { + const char *game_scale_options[kNumFrameScaleDef - 1] = { "max_round", "stretch", "proportional" }; + scale_def = kFrame_IntScale; + for (int i = 0; i < kNumFrameScaleDef - 1; ++i) { + if (scaling_option.CompareNoCase(game_scale_options[i]) == 0) { + scale_def = (FrameScaleDefinition)(i + 1); + break; + } + } - if (scale_def == kFrame_IntScale) - scale_factor = StrUtil::StringToInt(scaling_option); - else - scale_factor = 0; + if (scale_def == kFrame_IntScale) + scale_factor = StrUtil::StringToInt(scaling_option); + else + scale_factor = 0; } -void parse_scaling_option(const String &scaling_option, GameFrameSetup &frame_setup) -{ - parse_scaling_option(scaling_option, frame_setup.ScaleDef, frame_setup.ScaleFactor); +void parse_scaling_option(const String &scaling_option, GameFrameSetup &frame_setup) { + parse_scaling_option(scaling_option, frame_setup.ScaleDef, frame_setup.ScaleFactor); } // Parses legacy filter ID and converts it into current scaling options -bool parse_legacy_frame_config(const String &scaling_option, String &filter_id, GameFrameSetup &frame) -{ - struct - { - String LegacyName; - String CurrentName; - int Scaling; - } legacy_filters[6] = { {"none", "none", -1}, {"max", "StdScale", 0}, {"StdScale", "StdScale", -1}, - {"AAx", "Linear", -1}, {"Hq2x", "Hqx", 2}, {"Hq3x", "Hqx", 3} }; - - for (int i = 0; i < 6; i++) - { - if (scaling_option.CompareLeftNoCase(legacy_filters[i].LegacyName) == 0) - { - filter_id = legacy_filters[i].CurrentName; - frame.ScaleDef = legacy_filters[i].Scaling == 0 ? kFrame_MaxRound : kFrame_IntScale; - frame.ScaleFactor = legacy_filters[i].Scaling >= 0 ? legacy_filters[i].Scaling : - scaling_option.Mid(legacy_filters[i].LegacyName.GetLength()).ToInt(); - return true; - } - } - return false; -} - -String make_scaling_option(FrameScaleDefinition scale_def, int scale_factor) -{ - switch (scale_def) - { - case kFrame_MaxRound: - return "max_round"; - case kFrame_MaxStretch: - return "stretch"; - case kFrame_MaxProportional: - return "proportional"; - } - return String::FromFormat("%d", scale_factor); -} - -String make_scaling_option(const GameFrameSetup &frame_setup) -{ - return make_scaling_option(frame_setup.ScaleDef, frame_setup.ScaleFactor); -} - -uint32_t convert_scaling_to_fp(int scale_factor) -{ - if (scale_factor >= 0) - return scale_factor <<= kShift; - else - return kUnit / abs(scale_factor); -} - -int convert_fp_to_scaling(uint32_t scaling) -{ - if (scaling == 0) - return 0; - return scaling >= kUnit ? (scaling >> kShift) : -kUnit / (int32_t)scaling; -} - -AlIDStr AlIDToChars(int al_id) -{ - if (al_id == 0) - return AlIDStr {{ 'N', 'O', 'N', 'E', '\0' }}; - else if (al_id == -1) - return AlIDStr {{ 'A', 'U', 'T', 'O', '\0' }}; - else - return AlIDStr {{ - static_cast((al_id >> 24) & 0xFF), - static_cast((al_id >> 16) & 0xFF), - static_cast((al_id >> 8) & 0xFF), - static_cast((al_id) & 0xFF), - '\0' - }}; -} - -AlIDStr AlIDToChars(const String &s) -{ - AlIDStr id_str; - size_t i = 0; - for (; i < s.GetLength(); ++i) - id_str.s[i] = toupper(s[i]); - for (; i < 4; ++i) - id_str.s[i] = ' '; - id_str.s[4] = 0; - return id_str; -} - -int StringToAlID(const char *cstr) -{ - return (int)(AL_ID(cstr[0u], cstr[1u], cstr[2u], cstr[3u])); +bool parse_legacy_frame_config(const String &scaling_option, String &filter_id, GameFrameSetup &frame) { + struct { + String LegacyName; + String CurrentName; + int Scaling; + } legacy_filters[6] = { {"none", "none", -1}, {"max", "StdScale", 0}, {"StdScale", "StdScale", -1}, + {"AAx", "Linear", -1}, {"Hq2x", "Hqx", 2}, {"Hq3x", "Hqx", 3} + }; + + for (int i = 0; i < 6; i++) { + if (scaling_option.CompareLeftNoCase(legacy_filters[i].LegacyName) == 0) { + filter_id = legacy_filters[i].CurrentName; + frame.ScaleDef = legacy_filters[i].Scaling == 0 ? kFrame_MaxRound : kFrame_IntScale; + frame.ScaleFactor = legacy_filters[i].Scaling >= 0 ? legacy_filters[i].Scaling : + scaling_option.Mid(legacy_filters[i].LegacyName.GetLength()).ToInt(); + return true; + } + } + return false; +} + +String make_scaling_option(FrameScaleDefinition scale_def, int scale_factor) { + switch (scale_def) { + case kFrame_MaxRound: + return "max_round"; + case kFrame_MaxStretch: + return "stretch"; + case kFrame_MaxProportional: + return "proportional"; + } + return String::FromFormat("%d", scale_factor); +} + +String make_scaling_option(const GameFrameSetup &frame_setup) { + return make_scaling_option(frame_setup.ScaleDef, frame_setup.ScaleFactor); +} + +uint32_t convert_scaling_to_fp(int scale_factor) { + if (scale_factor >= 0) + return scale_factor <<= kShift; + else + return kUnit / abs(scale_factor); +} + +int convert_fp_to_scaling(uint32_t scaling) { + if (scaling == 0) + return 0; + return scaling >= kUnit ? (scaling >> kShift) : -kUnit / (int32_t)scaling; +} + +AlIDStr AlIDToChars(int al_id) { + if (al_id == 0) + return AlIDStr {{ 'N', 'O', 'N', 'E', '\0' }}; + else if (al_id == -1) + return AlIDStr {{ 'A', 'U', 'T', 'O', '\0' }}; + else + return AlIDStr {{ + static_cast((al_id >> 24) & 0xFF), + static_cast((al_id >> 16) & 0xFF), + static_cast((al_id >> 8) & 0xFF), + static_cast((al_id) & 0xFF), + '\0' + }}; +} + +AlIDStr AlIDToChars(const String &s) { + AlIDStr id_str; + size_t i = 0; + for (; i < s.GetLength(); ++i) + id_str.s[i] = toupper(s[i]); + for (; i < 4; ++i) + id_str.s[i] = ' '; + id_str.s[4] = 0; + return id_str; +} + +int StringToAlID(const char *cstr) { + return (int)(AL_ID(cstr[0u], cstr[1u], cstr[2u], cstr[3u])); } // Parses a config string which may hold plain driver's ID or 4-char ID packed // as a 32-bit integer. -int parse_driverid(const String &id) -{ - int asint; - if (StrUtil::StringToInt(id, asint, 0) == StrUtil::kNoError) - return asint; - if (id.GetLength() > 4) - return -1; // autodetect - if (id.CompareNoCase("AUTO") == 0) - return -1; // autodetect - if (id.CompareNoCase("NONE") == 0) - return 0; // no driver - return StringToAlID(AlIDToChars(id).s); +int parse_driverid(const String &id) { + int asint; + if (StrUtil::StringToInt(id, asint, 0) == StrUtil::kNoError) + return asint; + if (id.GetLength() > 4) + return -1; // autodetect + if (id.CompareNoCase("AUTO") == 0) + return -1; // autodetect + if (id.CompareNoCase("NONE") == 0) + return 0; // no driver + return StringToAlID(AlIDToChars(id).s); } // Reads driver ID from config, where it may be represented as string or number -int read_driverid(const ConfigTree &cfg, const String §n, const String &item, int def_value) -{ - String s = INIreadstring(cfg, sectn, item); - if (s.IsEmpty()) - return def_value; - return parse_driverid(s); -} - -void write_driverid(ConfigTree &cfg, const String §n, const String &item, int value) -{ - INIwritestring(cfg, sectn, item, AlIDToChars(value).s); -} - -void graphics_mode_get_defaults(bool windowed, ScreenSizeSetup &scsz_setup, GameFrameSetup &frame_setup) -{ - scsz_setup.Size = Size(); - if (windowed) - { - // For the windowed we define mode by the scaled game. - scsz_setup.SizeDef = kScreenDef_ByGameScaling; - scsz_setup.MatchDeviceRatio = false; - frame_setup = usetup.Screen.WinGameFrame; - } - else - { - // For the fullscreen we set current desktop resolution, which - // corresponds to most comfortable fullscreen mode for the driver. - scsz_setup.SizeDef = kScreenDef_MaxDisplay; - scsz_setup.MatchDeviceRatio = true; - frame_setup = usetup.Screen.FsGameFrame; - } -} - -String find_default_cfg_file(const char *alt_cfg_file) -{ - // Try current directory for config first; else try exe dir - String filename = String::FromFormat("%s/%s", Directory::GetCurrentDirectory().GetCStr(), DefaultConfigFileName.GetCStr()); - if (!Common::File::TestReadFile(filename)) - { - char conffilebuf[512]; - strcpy(conffilebuf, alt_cfg_file); - fix_filename_case(conffilebuf); - fix_filename_slashes(conffilebuf); - INIgetdirec(conffilebuf, DefaultConfigFileName); - filename = conffilebuf; - } - return filename; -} - -String find_user_global_cfg_file() -{ - String parent_dir = PathOrCurDir(platform->GetUserGlobalConfigDirectory()); - return String::FromFormat("%s/%s", parent_dir.GetCStr(), DefaultConfigFileName.GetCStr()); -} - -String find_user_cfg_file() -{ - String parent_dir = MakeSpecialSubDir(PathOrCurDir(platform->GetUserConfigDirectory())); - return String::FromFormat("%s/%s", parent_dir.GetCStr(), DefaultConfigFileName.GetCStr()); -} - -void config_defaults() -{ +int read_driverid(const ConfigTree &cfg, const String §n, const String &item, int def_value) { + String s = INIreadstring(cfg, sectn, item); + if (s.IsEmpty()) + return def_value; + return parse_driverid(s); +} + +void write_driverid(ConfigTree &cfg, const String §n, const String &item, int value) { + INIwritestring(cfg, sectn, item, AlIDToChars(value).s); +} + +void graphics_mode_get_defaults(bool windowed, ScreenSizeSetup &scsz_setup, GameFrameSetup &frame_setup) { + scsz_setup.Size = Size(); + if (windowed) { + // For the windowed we define mode by the scaled game. + scsz_setup.SizeDef = kScreenDef_ByGameScaling; + scsz_setup.MatchDeviceRatio = false; + frame_setup = usetup.Screen.WinGameFrame; + } else { + // For the fullscreen we set current desktop resolution, which + // corresponds to most comfortable fullscreen mode for the driver. + scsz_setup.SizeDef = kScreenDef_MaxDisplay; + scsz_setup.MatchDeviceRatio = true; + frame_setup = usetup.Screen.FsGameFrame; + } +} + +String find_default_cfg_file(const char *alt_cfg_file) { + // Try current directory for config first; else try exe dir + String filename = String::FromFormat("%s/%s", Directory::GetCurrentDirectory().GetCStr(), DefaultConfigFileName.GetCStr()); + if (!Common::File::TestReadFile(filename)) { + char conffilebuf[512]; + strcpy(conffilebuf, alt_cfg_file); + fix_filename_case(conffilebuf); + fix_filename_slashes(conffilebuf); + INIgetdirec(conffilebuf, DefaultConfigFileName); + filename = conffilebuf; + } + return filename; +} + +String find_user_global_cfg_file() { + String parent_dir = PathOrCurDir(platform->GetUserGlobalConfigDirectory()); + return String::FromFormat("%s/%s", parent_dir.GetCStr(), DefaultConfigFileName.GetCStr()); +} + +String find_user_cfg_file() { + String parent_dir = MakeSpecialSubDir(PathOrCurDir(platform->GetUserConfigDirectory())); + return String::FromFormat("%s/%s", parent_dir.GetCStr(), DefaultConfigFileName.GetCStr()); +} + +void config_defaults() { #if AGS_PLATFORM_OS_WINDOWS - usetup.Screen.DriverID = "D3D9"; + usetup.Screen.DriverID = "D3D9"; #else - usetup.Screen.DriverID = "OGL"; + usetup.Screen.DriverID = "OGL"; #endif #if AGS_PLATFORM_OS_WINDOWS - usetup.digicard = DIGI_DIRECTAMX(0); + usetup.digicard = DIGI_DIRECTAMX(0); #endif - usetup.midicard = MIDI_AUTODETECT; - usetup.translation = ""; -} - -void read_game_data_location(const ConfigTree &cfg) -{ - usetup.data_files_dir = INIreadstring(cfg, "misc", "datadir", usetup.data_files_dir); - if (!usetup.data_files_dir.IsEmpty()) - { - // strip any trailing slash - // TODO: move this to Path namespace later - AGS::Common::Path::FixupPath(usetup.data_files_dir); + usetup.midicard = MIDI_AUTODETECT; + usetup.translation = ""; +} + +void read_game_data_location(const ConfigTree &cfg) { + usetup.data_files_dir = INIreadstring(cfg, "misc", "datadir", usetup.data_files_dir); + if (!usetup.data_files_dir.IsEmpty()) { + // strip any trailing slash + // TODO: move this to Path namespace later + AGS::Common::Path::FixupPath(usetup.data_files_dir); #if AGS_PLATFORM_OS_WINDOWS - // if the path is just x:\ don't strip the slash - if (!(usetup.data_files_dir.GetLength() == 3 && usetup.data_files_dir[1u] == ':')) - { - usetup.data_files_dir.TrimRight('/'); - } + // if the path is just x:\ don't strip the slash + if (!(usetup.data_files_dir.GetLength() == 3 && usetup.data_files_dir[1u] == ':')) { + usetup.data_files_dir.TrimRight('/'); + } #else - usetup.data_files_dir.TrimRight('/'); + usetup.data_files_dir.TrimRight('/'); #endif - } - usetup.main_data_filename = INIreadstring(cfg, "misc", "datafile", usetup.main_data_filename); + } + usetup.main_data_filename = INIreadstring(cfg, "misc", "datafile", usetup.main_data_filename); } -void read_legacy_audio_config(const ConfigTree &cfg) -{ +void read_legacy_audio_config(const ConfigTree &cfg) { #if AGS_PLATFORM_OS_WINDOWS - int idx = INIreadint(cfg, "sound", "digiwinindx", -1); - if (idx == 0) - idx = DIGI_DIRECTAMX(0); - else if (idx == 1) - idx = DIGI_WAVOUTID(0); - else if (idx == 2) - idx = DIGI_NONE; - else if (idx == 3) - idx = DIGI_DIRECTX(0); - else - idx = DIGI_AUTODETECT; - usetup.digicard = idx; - - idx = INIreadint(cfg, "sound", "midiwinindx", -1); - if (idx == 1) - idx = MIDI_NONE; - else if (idx == 2) - idx = MIDI_WIN32MAPPER; - else - idx = MIDI_AUTODETECT; - usetup.midicard = idx; + int idx = INIreadint(cfg, "sound", "digiwinindx", -1); + if (idx == 0) + idx = DIGI_DIRECTAMX(0); + else if (idx == 1) + idx = DIGI_WAVOUTID(0); + else if (idx == 2) + idx = DIGI_NONE; + else if (idx == 3) + idx = DIGI_DIRECTX(0); + else + idx = DIGI_AUTODETECT; + usetup.digicard = idx; + + idx = INIreadint(cfg, "sound", "midiwinindx", -1); + if (idx == 1) + idx = MIDI_NONE; + else if (idx == 2) + idx = MIDI_WIN32MAPPER; + else + idx = MIDI_AUTODETECT; + usetup.midicard = idx; #endif } -void read_legacy_graphics_config(const ConfigTree &cfg) -{ - usetup.Screen.DisplayMode.Windowed = INIreadint(cfg, "misc", "windowed") > 0; - usetup.Screen.DriverID = INIreadstring(cfg, "misc", "gfxdriver", usetup.Screen.DriverID); - - { - String legacy_filter = INIreadstring(cfg, "misc", "gfxfilter"); - if (!legacy_filter.IsEmpty()) - { - // NOTE: legacy scaling config is applied only to windowed setting - if (usetup.Screen.DisplayMode.Windowed) - usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_ByGameScaling; - parse_legacy_frame_config(legacy_filter, usetup.Screen.Filter.ID, usetup.Screen.WinGameFrame); - - // AGS 3.2.1 and 3.3.0 aspect ratio preferences - if (!usetup.Screen.DisplayMode.Windowed) - { - usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = - (INIreadint(cfg, "misc", "sideborders") > 0 || INIreadint(cfg, "misc", "forceletterbox") > 0 || - INIreadint(cfg, "misc", "prefer_sideborders") > 0 || INIreadint(cfg, "misc", "prefer_letterbox") > 0); - } - } - - // AGS 3.4.0 - 3.4.1-rc uniform scaling option - String uniform_frame_scale = INIreadstring(cfg, "graphics", "game_scale"); - if (!uniform_frame_scale.IsEmpty()) - { - GameFrameSetup frame_setup; - parse_scaling_option(uniform_frame_scale, frame_setup); - usetup.Screen.FsGameFrame = frame_setup; - usetup.Screen.WinGameFrame = frame_setup; - } - } - - usetup.Screen.DisplayMode.RefreshRate = INIreadint(cfg, "misc", "refresh"); +void read_legacy_graphics_config(const ConfigTree &cfg) { + usetup.Screen.DisplayMode.Windowed = INIreadint(cfg, "misc", "windowed") > 0; + usetup.Screen.DriverID = INIreadstring(cfg, "misc", "gfxdriver", usetup.Screen.DriverID); + + { + String legacy_filter = INIreadstring(cfg, "misc", "gfxfilter"); + if (!legacy_filter.IsEmpty()) { + // NOTE: legacy scaling config is applied only to windowed setting + if (usetup.Screen.DisplayMode.Windowed) + usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_ByGameScaling; + parse_legacy_frame_config(legacy_filter, usetup.Screen.Filter.ID, usetup.Screen.WinGameFrame); + + // AGS 3.2.1 and 3.3.0 aspect ratio preferences + if (!usetup.Screen.DisplayMode.Windowed) { + usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = + (INIreadint(cfg, "misc", "sideborders") > 0 || INIreadint(cfg, "misc", "forceletterbox") > 0 || + INIreadint(cfg, "misc", "prefer_sideborders") > 0 || INIreadint(cfg, "misc", "prefer_letterbox") > 0); + } + } + + // AGS 3.4.0 - 3.4.1-rc uniform scaling option + String uniform_frame_scale = INIreadstring(cfg, "graphics", "game_scale"); + if (!uniform_frame_scale.IsEmpty()) { + GameFrameSetup frame_setup; + parse_scaling_option(uniform_frame_scale, frame_setup); + usetup.Screen.FsGameFrame = frame_setup; + usetup.Screen.WinGameFrame = frame_setup; + } + } + + usetup.Screen.DisplayMode.RefreshRate = INIreadint(cfg, "misc", "refresh"); } // Variables used for mobile port configs @@ -435,246 +392,220 @@ extern int psp_audio_enabled; extern int psp_midi_enabled; extern char psp_translation[]; -void override_config_ext(ConfigTree &cfg) -{ - // Mobile ports always run in fullscreen mode +void override_config_ext(ConfigTree &cfg) { + // Mobile ports always run in fullscreen mode #if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - INIwriteint(cfg, "graphics", "windowed", 0); + INIwriteint(cfg, "graphics", "windowed", 0); #endif - // psp_gfx_renderer - rendering mode - // * 0 - software renderer - // * 1 - hardware, render to screen - // * 2 - hardware, render to texture - if (psp_gfx_renderer == 0) - { - INIwritestring(cfg, "graphics", "driver", "Software"); - INIwriteint(cfg, "graphics", "render_at_screenres", 1); - } - else - { - INIwritestring(cfg, "graphics", "driver", "OGL"); - INIwriteint(cfg, "graphics", "render_at_screenres", psp_gfx_renderer == 1); - } - - // psp_gfx_scaling - scaling style: - // * 0 - no scaling - // * 1 - stretch and preserve aspect ratio - // * 2 - stretch to whole screen - if (psp_gfx_scaling == 0) - INIwritestring(cfg, "graphics", "game_scale_fs", "1"); - else if (psp_gfx_scaling == 1) - INIwritestring(cfg, "graphics", "game_scale_fs", "proportional"); - else - INIwritestring(cfg, "graphics", "game_scale_fs", "stretch"); - - // psp_gfx_smoothing - scaling filter: - // * 0 - nearest-neighbour - // * 1 - linear - if (psp_gfx_smoothing == 0) - INIwritestring(cfg, "graphics", "filter", "StdScale"); - else - INIwritestring(cfg, "graphics", "filter", "Linear"); - - // psp_gfx_super_sampling - enable super sampling - // * 0 - x1 - // * 1 - x2 - if (psp_gfx_renderer == 2) - INIwriteint(cfg, "graphics", "supersampling", psp_gfx_super_sampling + 1); - else - INIwriteint(cfg, "graphics", "supersampling", 0); - - INIwriteint(cfg, "misc", "antialias", psp_gfx_smooth_sprites != 0); - INIwritestring(cfg, "language", "translation", psp_translation); -} - -void apply_config(const ConfigTree &cfg) -{ - { - // Legacy settings has to be translated into new options; - // they must be read first, to let newer options override them, if ones are present - read_legacy_audio_config(cfg); - if (psp_audio_enabled) - { - usetup.digicard = read_driverid(cfg, "sound", "digiid", usetup.digicard); - if (psp_midi_enabled) - usetup.midicard = read_driverid(cfg, "sound", "midiid", usetup.midicard); - else - usetup.midicard = MIDI_NONE; - } - else - { - usetup.digicard = DIGI_NONE; - usetup.midicard = MIDI_NONE; - } - - psp_audio_multithreaded = INIreadint(cfg, "sound", "threaded", psp_audio_multithreaded); - - // Legacy graphics settings has to be translated into new options; - // they must be read first, to let newer options override them, if ones are present - read_legacy_graphics_config(cfg); - - // Graphics mode - usetup.Screen.DriverID = INIreadstring(cfg, "graphics", "driver", usetup.Screen.DriverID); - - usetup.Screen.DisplayMode.Windowed = INIreadint(cfg, "graphics", "windowed") > 0; - const char *screen_sz_def_options[kNumScreenDef] = { "explicit", "scaling", "max" }; - usetup.Screen.DisplayMode.ScreenSize.SizeDef = usetup.Screen.DisplayMode.Windowed ? kScreenDef_ByGameScaling : kScreenDef_MaxDisplay; - String screen_sz_def_str = INIreadstring(cfg, "graphics", "screen_def"); - for (int i = 0; i < kNumScreenDef; ++i) - { - if (screen_sz_def_str.CompareNoCase(screen_sz_def_options[i]) == 0) - { - usetup.Screen.DisplayMode.ScreenSize.SizeDef = (ScreenSizeDefinition)i; - break; - } - } - - usetup.Screen.DisplayMode.ScreenSize.Size = Size(INIreadint(cfg, "graphics", "screen_width"), - INIreadint(cfg, "graphics", "screen_height")); - usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = INIreadint(cfg, "graphics", "match_device_ratio", 1) != 0; - // TODO: move to config overrides (replace values during config load) + // psp_gfx_renderer - rendering mode + // * 0 - software renderer + // * 1 - hardware, render to screen + // * 2 - hardware, render to texture + if (psp_gfx_renderer == 0) { + INIwritestring(cfg, "graphics", "driver", "Software"); + INIwriteint(cfg, "graphics", "render_at_screenres", 1); + } else { + INIwritestring(cfg, "graphics", "driver", "OGL"); + INIwriteint(cfg, "graphics", "render_at_screenres", psp_gfx_renderer == 1); + } + + // psp_gfx_scaling - scaling style: + // * 0 - no scaling + // * 1 - stretch and preserve aspect ratio + // * 2 - stretch to whole screen + if (psp_gfx_scaling == 0) + INIwritestring(cfg, "graphics", "game_scale_fs", "1"); + else if (psp_gfx_scaling == 1) + INIwritestring(cfg, "graphics", "game_scale_fs", "proportional"); + else + INIwritestring(cfg, "graphics", "game_scale_fs", "stretch"); + + // psp_gfx_smoothing - scaling filter: + // * 0 - nearest-neighbour + // * 1 - linear + if (psp_gfx_smoothing == 0) + INIwritestring(cfg, "graphics", "filter", "StdScale"); + else + INIwritestring(cfg, "graphics", "filter", "Linear"); + + // psp_gfx_super_sampling - enable super sampling + // * 0 - x1 + // * 1 - x2 + if (psp_gfx_renderer == 2) + INIwriteint(cfg, "graphics", "supersampling", psp_gfx_super_sampling + 1); + else + INIwriteint(cfg, "graphics", "supersampling", 0); + + INIwriteint(cfg, "misc", "antialias", psp_gfx_smooth_sprites != 0); + INIwritestring(cfg, "language", "translation", psp_translation); +} + +void apply_config(const ConfigTree &cfg) { + { + // Legacy settings has to be translated into new options; + // they must be read first, to let newer options override them, if ones are present + read_legacy_audio_config(cfg); + if (psp_audio_enabled) { + usetup.digicard = read_driverid(cfg, "sound", "digiid", usetup.digicard); + if (psp_midi_enabled) + usetup.midicard = read_driverid(cfg, "sound", "midiid", usetup.midicard); + else + usetup.midicard = MIDI_NONE; + } else { + usetup.digicard = DIGI_NONE; + usetup.midicard = MIDI_NONE; + } + + psp_audio_multithreaded = INIreadint(cfg, "sound", "threaded", psp_audio_multithreaded); + + // Legacy graphics settings has to be translated into new options; + // they must be read first, to let newer options override them, if ones are present + read_legacy_graphics_config(cfg); + + // Graphics mode + usetup.Screen.DriverID = INIreadstring(cfg, "graphics", "driver", usetup.Screen.DriverID); + + usetup.Screen.DisplayMode.Windowed = INIreadint(cfg, "graphics", "windowed") > 0; + const char *screen_sz_def_options[kNumScreenDef] = { "explicit", "scaling", "max" }; + usetup.Screen.DisplayMode.ScreenSize.SizeDef = usetup.Screen.DisplayMode.Windowed ? kScreenDef_ByGameScaling : kScreenDef_MaxDisplay; + String screen_sz_def_str = INIreadstring(cfg, "graphics", "screen_def"); + for (int i = 0; i < kNumScreenDef; ++i) { + if (screen_sz_def_str.CompareNoCase(screen_sz_def_options[i]) == 0) { + usetup.Screen.DisplayMode.ScreenSize.SizeDef = (ScreenSizeDefinition)i; + break; + } + } + + usetup.Screen.DisplayMode.ScreenSize.Size = Size(INIreadint(cfg, "graphics", "screen_width"), + INIreadint(cfg, "graphics", "screen_height")); + usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = INIreadint(cfg, "graphics", "match_device_ratio", 1) != 0; + // TODO: move to config overrides (replace values during config load) #if AGS_PLATFORM_OS_MACOS - usetup.Screen.Filter.ID = "none"; + usetup.Screen.Filter.ID = "none"; #else - usetup.Screen.Filter.ID = INIreadstring(cfg, "graphics", "filter", "StdScale"); - parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_fs", "proportional"), usetup.Screen.FsGameFrame); - parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_win", "max_round"), usetup.Screen.WinGameFrame); + usetup.Screen.Filter.ID = INIreadstring(cfg, "graphics", "filter", "StdScale"); + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_fs", "proportional"), usetup.Screen.FsGameFrame); + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_win", "max_round"), usetup.Screen.WinGameFrame); #endif - usetup.Screen.DisplayMode.RefreshRate = INIreadint(cfg, "graphics", "refresh"); - usetup.Screen.DisplayMode.VSync = INIreadint(cfg, "graphics", "vsync") > 0; - usetup.RenderAtScreenRes = INIreadint(cfg, "graphics", "render_at_screenres") > 0; - usetup.Supersampling = INIreadint(cfg, "graphics", "supersampling", 1); - - usetup.enable_antialiasing = INIreadint(cfg, "misc", "antialias") > 0; - - // This option is backwards (usevox is 0 if no_speech_pack) - usetup.no_speech_pack = INIreadint(cfg, "sound", "usespeech", 1) == 0; - - usetup.user_data_dir = INIreadstring(cfg, "misc", "user_data_dir"); - usetup.shared_data_dir = INIreadstring(cfg, "misc", "shared_data_dir"); - - usetup.translation = INIreadstring(cfg, "language", "translation"); - - int cache_size_kb = INIreadint(cfg, "misc", "cachemax", DEFAULTCACHESIZE_KB); - if (cache_size_kb > 0) - spriteset.SetMaxCacheSize((size_t)cache_size_kb * 1024); - - usetup.mouse_auto_lock = INIreadint(cfg, "mouse", "auto_lock") > 0; - - usetup.mouse_speed = INIreadfloat(cfg, "mouse", "speed", 1.f); - if (usetup.mouse_speed <= 0.f) - usetup.mouse_speed = 1.f; - const char *mouse_ctrl_options[kNumMouseCtrlOptions] = { "never", "fullscreen", "always" }; - String mouse_str = INIreadstring(cfg, "mouse", "control_when", "fullscreen"); - for (int i = 0; i < kNumMouseCtrlOptions; ++i) - { - if (mouse_str.CompareNoCase(mouse_ctrl_options[i]) == 0) - { - usetup.mouse_ctrl_when = (MouseControlWhen)i; - break; - } - } - usetup.mouse_ctrl_enabled = INIreadint(cfg, "mouse", "control_enabled", 1) > 0; - const char *mouse_speed_options[kNumMouseSpeedDefs] = { "absolute", "current_display" }; - mouse_str = INIreadstring(cfg, "mouse", "speed_def", "current_display"); - for (int i = 0; i < kNumMouseSpeedDefs; ++i) - { - if (mouse_str.CompareNoCase(mouse_speed_options[i]) == 0) - { - usetup.mouse_speed_def = (MouseSpeedDef)i; - break; - } - } - - usetup.override_multitasking = INIreadint(cfg, "override", "multitasking", -1); - String override_os = INIreadstring(cfg, "override", "os"); - usetup.override_script_os = -1; - if (override_os.CompareNoCase("dos") == 0) - { - usetup.override_script_os = eOS_DOS; - } - else if (override_os.CompareNoCase("win") == 0) - { - usetup.override_script_os = eOS_Win; - } - else if (override_os.CompareNoCase("linux") == 0) - { - usetup.override_script_os = eOS_Linux; - } - else if (override_os.CompareNoCase("mac") == 0) - { - usetup.override_script_os = eOS_Mac; - } - usetup.override_upscale = INIreadint(cfg, "override", "upscale") > 0; - } - - // Apply logging configuration - apply_debug_config(cfg); -} - -void post_config() -{ - if (usetup.Screen.DriverID.IsEmpty() || usetup.Screen.DriverID.CompareNoCase("DX5") == 0) - usetup.Screen.DriverID = "Software"; - - // FIXME: this correction is needed at the moment because graphics driver - // implementation requires some filter to be created anyway - usetup.Screen.Filter.UserRequest = usetup.Screen.Filter.ID; - if (usetup.Screen.Filter.ID.IsEmpty() || usetup.Screen.Filter.ID.CompareNoCase("none") == 0) - { - usetup.Screen.Filter.ID = "StdScale"; - } - - if (!usetup.Screen.FsGameFrame.IsValid()) - usetup.Screen.FsGameFrame = GameFrameSetup(kFrame_MaxProportional); - if (!usetup.Screen.WinGameFrame.IsValid()) - usetup.Screen.WinGameFrame = GameFrameSetup(kFrame_MaxRound); - - // TODO: helper functions to remove slash in paths (or distinct path type) - if (usetup.user_data_dir.GetLast() == '/' || usetup.user_data_dir.GetLast() == '\\') - usetup.user_data_dir.ClipRight(1); - if (usetup.shared_data_dir.GetLast() == '/' || usetup.shared_data_dir.GetLast() == '\\') - usetup.shared_data_dir.ClipRight(1); -} - -void save_config_file() -{ - ConfigTree cfg; - - // Last display mode - // TODO: force_window check is a temporary workaround (see comment below) - if (force_window == 0) - { - bool is_windowed = System_GetWindowed() != 0; - cfg["graphics"]["windowed"] = String::FromFormat("%d", is_windowed ? 1 : 0); - // TODO: this is a hack, necessary because the original config system was designed when - // switching mode at runtime was not considered a possibility. - // Normally, two changes need to be done here: - // * the display setup needs to be reviewed and simplified a bit. - // * perhaps there should be two saved setups for fullscreen and windowed saved in memory - // (like ActiveDisplaySetting is saved currently), to know how the window size is defined - // in each modes (by explicit width/height values or from game scaling). - // This specifically *must* be done if there will be script API for modifying fullscreen - // resolution, or size of the window could be changed any way at runtime. - if (is_windowed != usetup.Screen.DisplayMode.Windowed) - { - if (is_windowed) - cfg["graphics"]["screen_def"] = "scaling"; - else - cfg["graphics"]["screen_def"] = "max"; - } - } - - // Other game options that could be changed at runtime - if (game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_UserDefined) - cfg["graphics"]["render_at_screenres"] = String::FromFormat("%d", usetup.RenderAtScreenRes ? 1 : 0); - cfg["mouse"]["control_enabled"] = String::FromFormat("%d", usetup.mouse_ctrl_enabled ? 1 : 0); - cfg["mouse"]["speed"] = String::FromFormat("%f", Mouse::GetSpeed()); - cfg["language"]["translation"] = usetup.translation; - - String cfg_file = find_user_cfg_file(); - if (!cfg_file.IsEmpty()) - IniUtil::Merge(cfg_file, cfg); + usetup.Screen.DisplayMode.RefreshRate = INIreadint(cfg, "graphics", "refresh"); + usetup.Screen.DisplayMode.VSync = INIreadint(cfg, "graphics", "vsync") > 0; + usetup.RenderAtScreenRes = INIreadint(cfg, "graphics", "render_at_screenres") > 0; + usetup.Supersampling = INIreadint(cfg, "graphics", "supersampling", 1); + + usetup.enable_antialiasing = INIreadint(cfg, "misc", "antialias") > 0; + + // This option is backwards (usevox is 0 if no_speech_pack) + usetup.no_speech_pack = INIreadint(cfg, "sound", "usespeech", 1) == 0; + + usetup.user_data_dir = INIreadstring(cfg, "misc", "user_data_dir"); + usetup.shared_data_dir = INIreadstring(cfg, "misc", "shared_data_dir"); + + usetup.translation = INIreadstring(cfg, "language", "translation"); + + int cache_size_kb = INIreadint(cfg, "misc", "cachemax", DEFAULTCACHESIZE_KB); + if (cache_size_kb > 0) + spriteset.SetMaxCacheSize((size_t)cache_size_kb * 1024); + + usetup.mouse_auto_lock = INIreadint(cfg, "mouse", "auto_lock") > 0; + + usetup.mouse_speed = INIreadfloat(cfg, "mouse", "speed", 1.f); + if (usetup.mouse_speed <= 0.f) + usetup.mouse_speed = 1.f; + const char *mouse_ctrl_options[kNumMouseCtrlOptions] = { "never", "fullscreen", "always" }; + String mouse_str = INIreadstring(cfg, "mouse", "control_when", "fullscreen"); + for (int i = 0; i < kNumMouseCtrlOptions; ++i) { + if (mouse_str.CompareNoCase(mouse_ctrl_options[i]) == 0) { + usetup.mouse_ctrl_when = (MouseControlWhen)i; + break; + } + } + usetup.mouse_ctrl_enabled = INIreadint(cfg, "mouse", "control_enabled", 1) > 0; + const char *mouse_speed_options[kNumMouseSpeedDefs] = { "absolute", "current_display" }; + mouse_str = INIreadstring(cfg, "mouse", "speed_def", "current_display"); + for (int i = 0; i < kNumMouseSpeedDefs; ++i) { + if (mouse_str.CompareNoCase(mouse_speed_options[i]) == 0) { + usetup.mouse_speed_def = (MouseSpeedDef)i; + break; + } + } + + usetup.override_multitasking = INIreadint(cfg, "override", "multitasking", -1); + String override_os = INIreadstring(cfg, "override", "os"); + usetup.override_script_os = -1; + if (override_os.CompareNoCase("dos") == 0) { + usetup.override_script_os = eOS_DOS; + } else if (override_os.CompareNoCase("win") == 0) { + usetup.override_script_os = eOS_Win; + } else if (override_os.CompareNoCase("linux") == 0) { + usetup.override_script_os = eOS_Linux; + } else if (override_os.CompareNoCase("mac") == 0) { + usetup.override_script_os = eOS_Mac; + } + usetup.override_upscale = INIreadint(cfg, "override", "upscale") > 0; + } + + // Apply logging configuration + apply_debug_config(cfg); +} + +void post_config() { + if (usetup.Screen.DriverID.IsEmpty() || usetup.Screen.DriverID.CompareNoCase("DX5") == 0) + usetup.Screen.DriverID = "Software"; + + // FIXME: this correction is needed at the moment because graphics driver + // implementation requires some filter to be created anyway + usetup.Screen.Filter.UserRequest = usetup.Screen.Filter.ID; + if (usetup.Screen.Filter.ID.IsEmpty() || usetup.Screen.Filter.ID.CompareNoCase("none") == 0) { + usetup.Screen.Filter.ID = "StdScale"; + } + + if (!usetup.Screen.FsGameFrame.IsValid()) + usetup.Screen.FsGameFrame = GameFrameSetup(kFrame_MaxProportional); + if (!usetup.Screen.WinGameFrame.IsValid()) + usetup.Screen.WinGameFrame = GameFrameSetup(kFrame_MaxRound); + + // TODO: helper functions to remove slash in paths (or distinct path type) + if (usetup.user_data_dir.GetLast() == '/' || usetup.user_data_dir.GetLast() == '\\') + usetup.user_data_dir.ClipRight(1); + if (usetup.shared_data_dir.GetLast() == '/' || usetup.shared_data_dir.GetLast() == '\\') + usetup.shared_data_dir.ClipRight(1); +} + +void save_config_file() { + ConfigTree cfg; + + // Last display mode + // TODO: force_window check is a temporary workaround (see comment below) + if (force_window == 0) { + bool is_windowed = System_GetWindowed() != 0; + cfg["graphics"]["windowed"] = String::FromFormat("%d", is_windowed ? 1 : 0); + // TODO: this is a hack, necessary because the original config system was designed when + // switching mode at runtime was not considered a possibility. + // Normally, two changes need to be done here: + // * the display setup needs to be reviewed and simplified a bit. + // * perhaps there should be two saved setups for fullscreen and windowed saved in memory + // (like ActiveDisplaySetting is saved currently), to know how the window size is defined + // in each modes (by explicit width/height values or from game scaling). + // This specifically *must* be done if there will be script API for modifying fullscreen + // resolution, or size of the window could be changed any way at runtime. + if (is_windowed != usetup.Screen.DisplayMode.Windowed) { + if (is_windowed) + cfg["graphics"]["screen_def"] = "scaling"; + else + cfg["graphics"]["screen_def"] = "max"; + } + } + + // Other game options that could be changed at runtime + if (game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_UserDefined) + cfg["graphics"]["render_at_screenres"] = String::FromFormat("%d", usetup.RenderAtScreenRes ? 1 : 0); + cfg["mouse"]["control_enabled"] = String::FromFormat("%d", usetup.mouse_ctrl_enabled ? 1 : 0); + cfg["mouse"]["speed"] = String::FromFormat("%f", Mouse::GetSpeed()); + cfg["language"]["translation"] = usetup.translation; + + String cfg_file = find_user_cfg_file(); + if (!cfg_file.IsEmpty()) + IniUtil::Merge(cfg_file, cfg); } diff --git a/engines/ags/engine/main/config.h b/engines/ags/engine/main/config.h index 77dab9e32328..4b0c086533fd 100644 --- a/engines/ags/engine/main/config.h +++ b/engines/ags/engine/main/config.h @@ -57,7 +57,9 @@ int convert_fp_to_scaling(uint32_t scaling); // Fill in setup structs with default settings for the given mode (windowed or fullscreen) void graphics_mode_get_defaults(bool windowed, ScreenSizeSetup &scsz_setup, GameFrameSetup &frame_setup); -typedef struct { char s[5]; } AlIDStr; +typedef struct { + char s[5]; +} AlIDStr; // Converts Allegro driver ID type to 4-char string AlIDStr AlIDToChars(int al_id); AlIDStr AlIDToChars(const String &s); diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index af9140e25903..46ce312bd17f 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -93,7 +93,7 @@ extern char pexbuf[STD_BUFFER_SIZE]; extern SpriteCache spriteset; extern ObjectCache objcache[MAX_ROOM_OBJECTS]; extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; -extern ViewStruct*views; +extern ViewStruct *views; extern int displayed_room; extern int eip_guinum; extern int eip_guiobj; @@ -104,7 +104,7 @@ extern IGraphicsDriver *gfxDriver; extern Bitmap **actsps; extern color palette[256]; extern CharacterExtras *charextra; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern Bitmap **guibg; extern IDriverDependantBitmap **guibgbmp; @@ -114,620 +114,545 @@ t_engine_pre_init_callback engine_pre_init_callback = nullptr; #define ALLEGRO_KEYBOARD_HANDLER -bool engine_init_allegro() -{ - Debug::Printf(kDbgMsg_Info, "Initializing allegro"); - - our_eip = -199; - // Initialize allegro - set_uformat(U_ASCII); - if (install_allegro(SYSTEM_AUTODETECT, &errno, atexit)) - { - const char *al_err = get_allegro_error(); - const char *user_hint = platform->GetAllegroFailUserHint(); - platform->DisplayAlert("Unable to initialize Allegro system driver.\n%s\n\n%s", - al_err[0] ? al_err : "Allegro library provided no further information on the problem.", - user_hint); - return false; - } - return true; +bool engine_init_allegro() { + Debug::Printf(kDbgMsg_Info, "Initializing allegro"); + + our_eip = -199; + // Initialize allegro + set_uformat(U_ASCII); + if (install_allegro(SYSTEM_AUTODETECT, &errno, atexit)) { + const char *al_err = get_allegro_error(); + const char *user_hint = platform->GetAllegroFailUserHint(); + platform->DisplayAlert("Unable to initialize Allegro system driver.\n%s\n\n%s", + al_err[0] ? al_err : "Allegro library provided no further information on the problem.", + user_hint); + return false; + } + return true; } -void engine_setup_allegro() -{ - // Setup allegro using constructed config string - const char *al_config_data = "[mouse]\n" - "mouse_accel_factor = 0\n"; - override_config_data(al_config_data, ustrsize(al_config_data)); +void engine_setup_allegro() { + // Setup allegro using constructed config string + const char *al_config_data = "[mouse]\n" + "mouse_accel_factor = 0\n"; + override_config_data(al_config_data, ustrsize(al_config_data)); } void winclosehook() { - want_exit = 1; - abort_engine = 1; - check_dynamic_sprites_at_exit = 0; + want_exit = 1; + abort_engine = 1; + check_dynamic_sprites_at_exit = 0; } -void engine_setup_window() -{ - Debug::Printf(kDbgMsg_Info, "Setting up window"); +void engine_setup_window() { + Debug::Printf(kDbgMsg_Info, "Setting up window"); - our_eip = -198; - set_window_title("Adventure Game Studio"); - set_close_button_callback (winclosehook); - our_eip = -197; + our_eip = -198; + set_window_title("Adventure Game Studio"); + set_close_button_callback(winclosehook); + our_eip = -197; - platform->SetGameWindowIcon(); + platform->SetGameWindowIcon(); } // Starts up setup application, if capable. // Returns TRUE if should continue running the game, otherwise FALSE. -bool engine_run_setup(const String &exe_path, ConfigTree &cfg, int &app_res) -{ - app_res = EXIT_NORMAL; +bool engine_run_setup(const String &exe_path, ConfigTree &cfg, int &app_res) { + app_res = EXIT_NORMAL; #if AGS_PLATFORM_OS_WINDOWS - { - String cfg_file = find_user_cfg_file(); - if (cfg_file.IsEmpty()) - { - app_res = EXIT_ERROR; - return false; - } - - Debug::Printf(kDbgMsg_Info, "Running Setup"); - - ConfigTree cfg_out; - SetupReturnValue res = platform->RunSetup(cfg, cfg_out); - if (res != kSetup_Cancel) - { - if (!IniUtil::Merge(cfg_file, cfg_out)) - { - platform->DisplayAlert("Unable to write to the configuration file (error code 0x%08X).\n%s", - platform->GetLastSystemError(), platform->GetDiskWriteAccessTroubleshootingText()); - } - } - if (res != kSetup_RunGame) - return false; - - // TODO: investigate if the full program restart may (should) be avoided - - // Just re-reading the config file seems to cause a caching - // problem on Win9x, so let's restart the process. - allegro_exit(); - char quotedpath[MAX_PATH]; - snprintf(quotedpath, MAX_PATH, "\"%s\"", exe_path.GetCStr()); - _spawnl (_P_OVERLAY, exe_path, quotedpath, NULL); - } + { + String cfg_file = find_user_cfg_file(); + if (cfg_file.IsEmpty()) { + app_res = EXIT_ERROR; + return false; + } + + Debug::Printf(kDbgMsg_Info, "Running Setup"); + + ConfigTree cfg_out; + SetupReturnValue res = platform->RunSetup(cfg, cfg_out); + if (res != kSetup_Cancel) { + if (!IniUtil::Merge(cfg_file, cfg_out)) { + platform->DisplayAlert("Unable to write to the configuration file (error code 0x%08X).\n%s", + platform->GetLastSystemError(), platform->GetDiskWriteAccessTroubleshootingText()); + } + } + if (res != kSetup_RunGame) + return false; + + // TODO: investigate if the full program restart may (should) be avoided + + // Just re-reading the config file seems to cause a caching + // problem on Win9x, so let's restart the process. + allegro_exit(); + char quotedpath[MAX_PATH]; + snprintf(quotedpath, MAX_PATH, "\"%s\"", exe_path.GetCStr()); + _spawnl(_P_OVERLAY, exe_path, quotedpath, NULL); + } #endif - return true; + return true; } -void engine_force_window() -{ - // Force to run in a window, override the config file - // TODO: actually overwrite config tree instead - if (force_window == 1) - { - usetup.Screen.DisplayMode.Windowed = true; - usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_ByGameScaling; - } - else if (force_window == 2) - { - usetup.Screen.DisplayMode.Windowed = false; - usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_MaxDisplay; - } +void engine_force_window() { + // Force to run in a window, override the config file + // TODO: actually overwrite config tree instead + if (force_window == 1) { + usetup.Screen.DisplayMode.Windowed = true; + usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_ByGameScaling; + } else if (force_window == 2) { + usetup.Screen.DisplayMode.Windowed = false; + usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_MaxDisplay; + } } -String find_game_data_in_directory(const String &path) -{ - al_ffblk ff; - String test_file; - String first_nonstd_fn; - String pattern = path; - pattern.Append("/*"); - - if (al_findfirst(pattern, &ff, FA_ALL & ~(FA_DIREC)) != 0) - return ""; - // Select first found data file; files with standart names (*.ags) have - // higher priority over files with custom names. - do - { - test_file = ff.name; - // Add a bit of sanity and do not parse contents of the 10k-files-large - // digital sound libraries. - // NOTE: we could certainly benefit from any kind of flag in file lib - // that would tell us this is the main lib without extra parsing. - if (test_file.CompareRightNoCase(".vox") == 0) - continue; - - // *.ags is a standart cross-platform file pattern for AGS games, - // ac2game.dat is a legacy file name for very old games, - // *.exe is a MS Win executable; it is included to this case because - // users often run AGS ports with Windows versions of games. - bool is_std_name = test_file.CompareRightNoCase(".ags") == 0 || - test_file.CompareNoCase("ac2game.dat") == 0 || - test_file.CompareRightNoCase(".exe") == 0; - if (is_std_name || first_nonstd_fn.IsEmpty()) - { - test_file.Format("%s/%s", path.GetCStr(), ff.name); - if (IsMainGameLibrary(test_file)) - { - if (is_std_name) - { - al_findclose(&ff); - return test_file; - } - else - first_nonstd_fn = test_file; - } - } - } - while(al_findnext(&ff) == 0); - al_findclose(&ff); - return first_nonstd_fn; +String find_game_data_in_directory(const String &path) { + al_ffblk ff; + String test_file; + String first_nonstd_fn; + String pattern = path; + pattern.Append("/*"); + + if (al_findfirst(pattern, &ff, FA_ALL & ~(FA_DIREC)) != 0) + return ""; + // Select first found data file; files with standart names (*.ags) have + // higher priority over files with custom names. + do { + test_file = ff.name; + // Add a bit of sanity and do not parse contents of the 10k-files-large + // digital sound libraries. + // NOTE: we could certainly benefit from any kind of flag in file lib + // that would tell us this is the main lib without extra parsing. + if (test_file.CompareRightNoCase(".vox") == 0) + continue; + + // *.ags is a standart cross-platform file pattern for AGS games, + // ac2game.dat is a legacy file name for very old games, + // *.exe is a MS Win executable; it is included to this case because + // users often run AGS ports with Windows versions of games. + bool is_std_name = test_file.CompareRightNoCase(".ags") == 0 || + test_file.CompareNoCase("ac2game.dat") == 0 || + test_file.CompareRightNoCase(".exe") == 0; + if (is_std_name || first_nonstd_fn.IsEmpty()) { + test_file.Format("%s/%s", path.GetCStr(), ff.name); + if (IsMainGameLibrary(test_file)) { + if (is_std_name) { + al_findclose(&ff); + return test_file; + } else + first_nonstd_fn = test_file; + } + } + } while (al_findnext(&ff) == 0); + al_findclose(&ff); + return first_nonstd_fn; } -bool search_for_game_data_file(String &filename, String &search_path) -{ - Debug::Printf("Looking for the game data file"); - // 1. From command line argument, treated as a directory - if (!cmdGameDataPath.IsEmpty()) - { - // set from cmd arg (do any conversions if needed) - filename = cmdGameDataPath; - if (!filename.IsEmpty() && Path::IsDirectory(filename)) - { - search_path = filename; - filename = find_game_data_in_directory(search_path); - } - } - // 2.2. Search in the provided data dir - else if (!usetup.data_files_dir.IsEmpty()) - { - search_path = usetup.data_files_dir; - filename = find_game_data_in_directory(search_path); - } - // 3. Look in known locations - else - { - // 3.1. Look for attachment in the running executable - // - // this will use argument zero, the executable's name - filename = GetPathFromCmdArg(0); - if (filename.IsEmpty() || !Common::AssetManager::IsDataFile(filename)) - { - // 3.2 Look in current directory - search_path = Directory::GetCurrentDirectory(); - filename = find_game_data_in_directory(search_path); - if (filename.IsEmpty()) - { - // 3.3 Look in executable's directory (if it's different from current dir) - if (Path::ComparePaths(appDirectory, search_path)) - { - search_path = appDirectory; - filename = find_game_data_in_directory(search_path); - } - } - } - } - - // Finally, store game file's absolute path, or report error - if (filename.IsEmpty()) - { - Debug::Printf(kDbgMsg_Error, "Game data file could not be found. Search path used: '%s'", search_path.GetCStr()); - return false; - } - filename = Path::MakeAbsolutePath(filename); - Debug::Printf(kDbgMsg_Info, "Located game data file: %s", filename.GetCStr()); - return true; +bool search_for_game_data_file(String &filename, String &search_path) { + Debug::Printf("Looking for the game data file"); + // 1. From command line argument, treated as a directory + if (!cmdGameDataPath.IsEmpty()) { + // set from cmd arg (do any conversions if needed) + filename = cmdGameDataPath; + if (!filename.IsEmpty() && Path::IsDirectory(filename)) { + search_path = filename; + filename = find_game_data_in_directory(search_path); + } + } + // 2.2. Search in the provided data dir + else if (!usetup.data_files_dir.IsEmpty()) { + search_path = usetup.data_files_dir; + filename = find_game_data_in_directory(search_path); + } + // 3. Look in known locations + else { + // 3.1. Look for attachment in the running executable + // + // this will use argument zero, the executable's name + filename = GetPathFromCmdArg(0); + if (filename.IsEmpty() || !Common::AssetManager::IsDataFile(filename)) { + // 3.2 Look in current directory + search_path = Directory::GetCurrentDirectory(); + filename = find_game_data_in_directory(search_path); + if (filename.IsEmpty()) { + // 3.3 Look in executable's directory (if it's different from current dir) + if (Path::ComparePaths(appDirectory, search_path)) { + search_path = appDirectory; + filename = find_game_data_in_directory(search_path); + } + } + } + } + + // Finally, store game file's absolute path, or report error + if (filename.IsEmpty()) { + Debug::Printf(kDbgMsg_Error, "Game data file could not be found. Search path used: '%s'", search_path.GetCStr()); + return false; + } + filename = Path::MakeAbsolutePath(filename); + Debug::Printf(kDbgMsg_Info, "Located game data file: %s", filename.GetCStr()); + return true; } // Try to initialize main game package found at the given path -bool engine_try_init_gamedata(String gamepak_path) -{ - // Search for an available game package in the known locations - AssetError err = AssetManager::SetDataFile(gamepak_path); - if (err != kAssetNoError) - { - platform->DisplayAlert("ERROR: The game data is missing, is of unsupported format or corrupt.\nFile: '%s'", gamepak_path.GetCStr()); - return false; - } - return true; +bool engine_try_init_gamedata(String gamepak_path) { + // Search for an available game package in the known locations + AssetError err = AssetManager::SetDataFile(gamepak_path); + if (err != kAssetNoError) { + platform->DisplayAlert("ERROR: The game data is missing, is of unsupported format or corrupt.\nFile: '%s'", gamepak_path.GetCStr()); + return false; + } + return true; } -void engine_init_fonts() -{ - Debug::Printf(kDbgMsg_Info, "Initializing TTF renderer"); +void engine_init_fonts() { + Debug::Printf(kDbgMsg_Info, "Initializing TTF renderer"); - init_font_renderer(); + init_font_renderer(); } -void engine_init_mouse() -{ - int res = minstalled(); - if (res < 0) - Debug::Printf(kDbgMsg_Info, "Initializing mouse: failed"); - else - Debug::Printf(kDbgMsg_Info, "Initializing mouse: number of buttons reported is %d", res); - Mouse::SetSpeed(usetup.mouse_speed); +void engine_init_mouse() { + int res = minstalled(); + if (res < 0) + Debug::Printf(kDbgMsg_Info, "Initializing mouse: failed"); + else + Debug::Printf(kDbgMsg_Info, "Initializing mouse: number of buttons reported is %d", res); + Mouse::SetSpeed(usetup.mouse_speed); } -void engine_locate_speech_pak() -{ - play.want_speech=-2; - - if (!usetup.no_speech_pack) { - String speech_file = "speech.vox"; - String speech_filepath = find_assetlib(speech_file); - if (!speech_filepath.IsEmpty()) { - Debug::Printf("Initializing speech vox"); - if (AssetManager::SetDataFile(speech_filepath)!=Common::kAssetNoError) { - platform->DisplayAlert("Unable to read voice pack, file could be corrupted or of unknown format.\nSpeech voice-over will be disabled."); - AssetManager::SetDataFile(ResPaths.GamePak.Path); // switch back to the main data pack - return; - } - // TODO: why is this read right here??? move this to InitGameState! - Stream *speechsync = AssetManager::OpenAsset("syncdata.dat"); - if (speechsync != nullptr) { - // this game has voice lip sync - int lipsync_fmt = speechsync->ReadInt32(); - if (lipsync_fmt != 4) - { - Debug::Printf(kDbgMsg_Info, "Unknown speech lip sync format (%d).\nLip sync disabled.", lipsync_fmt); - } - else { - numLipLines = speechsync->ReadInt32(); - splipsync = (SpeechLipSyncLine*)malloc (sizeof(SpeechLipSyncLine) * numLipLines); - for (int ee = 0; ee < numLipLines; ee++) - { - splipsync[ee].numPhonemes = speechsync->ReadInt16(); - speechsync->Read(splipsync[ee].filename, 14); - splipsync[ee].endtimeoffs = (int*)malloc(splipsync[ee].numPhonemes * sizeof(int)); - speechsync->ReadArrayOfInt32(splipsync[ee].endtimeoffs, splipsync[ee].numPhonemes); - splipsync[ee].frame = (short*)malloc(splipsync[ee].numPhonemes * sizeof(short)); - speechsync->ReadArrayOfInt16(splipsync[ee].frame, splipsync[ee].numPhonemes); - } - } - delete speechsync; - } - AssetManager::SetDataFile(ResPaths.GamePak.Path); // switch back to the main data pack - Debug::Printf(kDbgMsg_Info, "Voice pack found and initialized."); - play.want_speech=1; - } - else if (Path::ComparePaths(ResPaths.DataDir, get_voice_install_dir()) != 0) - { - // If we have custom voice directory set, we will enable voice-over even if speech.vox does not exist - Debug::Printf(kDbgMsg_Info, "Voice pack was not found, but voice installation directory is defined: enabling voice-over."); - play.want_speech=1; - } - ResPaths.SpeechPak.Name = speech_file; - ResPaths.SpeechPak.Path = speech_filepath; - } +void engine_locate_speech_pak() { + play.want_speech = -2; + + if (!usetup.no_speech_pack) { + String speech_file = "speech.vox"; + String speech_filepath = find_assetlib(speech_file); + if (!speech_filepath.IsEmpty()) { + Debug::Printf("Initializing speech vox"); + if (AssetManager::SetDataFile(speech_filepath) != Common::kAssetNoError) { + platform->DisplayAlert("Unable to read voice pack, file could be corrupted or of unknown format.\nSpeech voice-over will be disabled."); + AssetManager::SetDataFile(ResPaths.GamePak.Path); // switch back to the main data pack + return; + } + // TODO: why is this read right here??? move this to InitGameState! + Stream *speechsync = AssetManager::OpenAsset("syncdata.dat"); + if (speechsync != nullptr) { + // this game has voice lip sync + int lipsync_fmt = speechsync->ReadInt32(); + if (lipsync_fmt != 4) { + Debug::Printf(kDbgMsg_Info, "Unknown speech lip sync format (%d).\nLip sync disabled.", lipsync_fmt); + } else { + numLipLines = speechsync->ReadInt32(); + splipsync = (SpeechLipSyncLine *)malloc(sizeof(SpeechLipSyncLine) * numLipLines); + for (int ee = 0; ee < numLipLines; ee++) { + splipsync[ee].numPhonemes = speechsync->ReadInt16(); + speechsync->Read(splipsync[ee].filename, 14); + splipsync[ee].endtimeoffs = (int *)malloc(splipsync[ee].numPhonemes * sizeof(int)); + speechsync->ReadArrayOfInt32(splipsync[ee].endtimeoffs, splipsync[ee].numPhonemes); + splipsync[ee].frame = (short *)malloc(splipsync[ee].numPhonemes * sizeof(short)); + speechsync->ReadArrayOfInt16(splipsync[ee].frame, splipsync[ee].numPhonemes); + } + } + delete speechsync; + } + AssetManager::SetDataFile(ResPaths.GamePak.Path); // switch back to the main data pack + Debug::Printf(kDbgMsg_Info, "Voice pack found and initialized."); + play.want_speech = 1; + } else if (Path::ComparePaths(ResPaths.DataDir, get_voice_install_dir()) != 0) { + // If we have custom voice directory set, we will enable voice-over even if speech.vox does not exist + Debug::Printf(kDbgMsg_Info, "Voice pack was not found, but voice installation directory is defined: enabling voice-over."); + play.want_speech = 1; + } + ResPaths.SpeechPak.Name = speech_file; + ResPaths.SpeechPak.Path = speech_filepath; + } } -void engine_locate_audio_pak() -{ - play.separate_music_lib = 0; - String music_file = game.GetAudioVOXName(); - String music_filepath = find_assetlib(music_file); - if (!music_filepath.IsEmpty()) - { - if (AssetManager::SetDataFile(music_filepath) == kAssetNoError) - { - AssetManager::SetDataFile(ResPaths.GamePak.Path); - Debug::Printf(kDbgMsg_Info, "%s found and initialized.", music_file.GetCStr()); - play.separate_music_lib = 1; - ResPaths.AudioPak.Name = music_file; - ResPaths.AudioPak.Path = music_filepath; - } - else - { - platform->DisplayAlert("Unable to initialize digital audio pack '%s', file could be corrupt or of unsupported format.", - music_file.GetCStr()); - } - } +void engine_locate_audio_pak() { + play.separate_music_lib = 0; + String music_file = game.GetAudioVOXName(); + String music_filepath = find_assetlib(music_file); + if (!music_filepath.IsEmpty()) { + if (AssetManager::SetDataFile(music_filepath) == kAssetNoError) { + AssetManager::SetDataFile(ResPaths.GamePak.Path); + Debug::Printf(kDbgMsg_Info, "%s found and initialized.", music_file.GetCStr()); + play.separate_music_lib = 1; + ResPaths.AudioPak.Name = music_file; + ResPaths.AudioPak.Path = music_filepath; + } else { + platform->DisplayAlert("Unable to initialize digital audio pack '%s', file could be corrupt or of unsupported format.", + music_file.GetCStr()); + } + } } -void engine_init_keyboard() -{ +void engine_init_keyboard() { #ifdef ALLEGRO_KEYBOARD_HANDLER - Debug::Printf(kDbgMsg_Info, "Initializing keyboard"); + Debug::Printf(kDbgMsg_Info, "Initializing keyboard"); - install_keyboard(); + install_keyboard(); #endif #if AGS_PLATFORM_OS_LINUX - setlocale(LC_NUMERIC, "C"); // needed in X platform because install keyboard affects locale of printfs + setlocale(LC_NUMERIC, "C"); // needed in X platform because install keyboard affects locale of printfs #endif } -void engine_init_timer() -{ - Debug::Printf(kDbgMsg_Info, "Install timer"); +void engine_init_timer() { + Debug::Printf(kDbgMsg_Info, "Install timer"); - skipMissedTicks(); + skipMissedTicks(); } -bool try_install_sound(int digi_id, int midi_id, String *p_err_msg = nullptr) -{ - Debug::Printf(kDbgMsg_Info, "Trying to init: digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", - AlIDToChars(digi_id).s, digi_id, AlIDToChars(midi_id).s, midi_id); - - if (install_sound(digi_id, midi_id, nullptr) == 0) - return true; - // Allegro does not let you try digital and MIDI drivers separately, - // and does not indicate which driver failed by return value. - // Therefore we try to guess. - if (p_err_msg) - *p_err_msg = get_allegro_error(); - if (midi_id != MIDI_NONE) - { - Debug::Printf(kDbgMsg_Error, "Failed to init one of the drivers; Error: '%s'.\nWill try to start without MIDI", get_allegro_error()); - if (install_sound(digi_id, MIDI_NONE, nullptr) == 0) - return true; - } - if (digi_id != DIGI_NONE) - { - Debug::Printf(kDbgMsg_Error, "Failed to init one of the drivers; Error: '%s'.\nWill try to start without DIGI", get_allegro_error()); - if (install_sound(DIGI_NONE, midi_id, nullptr) == 0) - return true; - } - Debug::Printf(kDbgMsg_Error, "Failed to init sound drivers. Error: %s", get_allegro_error()); - return false; +bool try_install_sound(int digi_id, int midi_id, String *p_err_msg = nullptr) { + Debug::Printf(kDbgMsg_Info, "Trying to init: digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", + AlIDToChars(digi_id).s, digi_id, AlIDToChars(midi_id).s, midi_id); + + if (install_sound(digi_id, midi_id, nullptr) == 0) + return true; + // Allegro does not let you try digital and MIDI drivers separately, + // and does not indicate which driver failed by return value. + // Therefore we try to guess. + if (p_err_msg) + *p_err_msg = get_allegro_error(); + if (midi_id != MIDI_NONE) { + Debug::Printf(kDbgMsg_Error, "Failed to init one of the drivers; Error: '%s'.\nWill try to start without MIDI", get_allegro_error()); + if (install_sound(digi_id, MIDI_NONE, nullptr) == 0) + return true; + } + if (digi_id != DIGI_NONE) { + Debug::Printf(kDbgMsg_Error, "Failed to init one of the drivers; Error: '%s'.\nWill try to start without DIGI", get_allegro_error()); + if (install_sound(DIGI_NONE, midi_id, nullptr) == 0) + return true; + } + Debug::Printf(kDbgMsg_Error, "Failed to init sound drivers. Error: %s", get_allegro_error()); + return false; } // Attempts to predict a digital driver Allegro would chose, and get its maximal voices -std::pair autodetect_driver(_DRIVER_INFO *driver_list, int (*detect_audio_driver)(int), const char *type) -{ - for (int i = 0; driver_list[i].driver; ++i) - { - if (driver_list[i].autodetect) - { - int voices = detect_audio_driver(driver_list[i].id); - if (voices != 0) - return std::make_pair(driver_list[i].id, voices); - Debug::Printf(kDbgMsg_Warn, "Failed to detect %s driver %s; Error: '%s'.", - type, AlIDToChars(driver_list[i].id).s, get_allegro_error()); - } - } - return std::make_pair(0, 0); +std::pair autodetect_driver(_DRIVER_INFO *driver_list, int (*detect_audio_driver)(int), const char *type) { + for (int i = 0; driver_list[i].driver; ++i) { + if (driver_list[i].autodetect) { + int voices = detect_audio_driver(driver_list[i].id); + if (voices != 0) + return std::make_pair(driver_list[i].id, voices); + Debug::Printf(kDbgMsg_Warn, "Failed to detect %s driver %s; Error: '%s'.", + type, AlIDToChars(driver_list[i].id).s, get_allegro_error()); + } + } + return std::make_pair(0, 0); } // Decides which audio driver to request from Allegro. // Returns a pair of audio card ID and max available voices. std::pair decide_audiodriver(int try_id, _DRIVER_INFO *driver_list, - int(*detect_audio_driver)(int), int &al_drv_id, const char *type) -{ - if (try_id == 0) // no driver - return std::make_pair(0, 0); - al_drv_id = 0; // the driver id will be set by library if one was found - if (try_id > 0) - { - int voices = detect_audio_driver(try_id); - if (al_drv_id == try_id && voices != 0) // found and detected - return std::make_pair(try_id, voices); - if (voices == 0) // found in list but detect failed - Debug::Printf(kDbgMsg_Error, "Failed to detect %s driver %s; Error: '%s'.", type, AlIDToChars(try_id).s, get_allegro_error()); - else // not found at all - Debug::Printf(kDbgMsg_Error, "Unknown %s driver: %s, will try to find suitable one.", type, AlIDToChars(try_id).s); - } - return autodetect_driver(driver_list, detect_audio_driver, type); + int(*detect_audio_driver)(int), int &al_drv_id, const char *type) { + if (try_id == 0) // no driver + return std::make_pair(0, 0); + al_drv_id = 0; // the driver id will be set by library if one was found + if (try_id > 0) { + int voices = detect_audio_driver(try_id); + if (al_drv_id == try_id && voices != 0) // found and detected + return std::make_pair(try_id, voices); + if (voices == 0) // found in list but detect failed + Debug::Printf(kDbgMsg_Error, "Failed to detect %s driver %s; Error: '%s'.", type, AlIDToChars(try_id).s, get_allegro_error()); + else // not found at all + Debug::Printf(kDbgMsg_Error, "Unknown %s driver: %s, will try to find suitable one.", type, AlIDToChars(try_id).s); + } + return autodetect_driver(driver_list, detect_audio_driver, type); } -void engine_init_audio() -{ - Debug::Printf("Initializing sound drivers"); - int digi_id = usetup.digicard; - int midi_id = usetup.midicard; - int digi_voices = -1; - int midi_voices = -1; - // MOD player would need certain minimal number of voices - // TODO: find out if this is still relevant? - if (usetup.mod_player) - digi_voices = NUM_DIGI_VOICES; - - Debug::Printf(kDbgMsg_Info, "Sound settings: digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", - AlIDToChars(digi_id).s, digi_id, AlIDToChars(midi_id).s, midi_id); - - // First try if drivers are supported, and switch to autodetect if explicit option failed - _DRIVER_INFO *digi_drivers = system_driver->digi_drivers ? system_driver->digi_drivers() : _digi_driver_list; - std::pair digi_drv = decide_audiodriver(digi_id, digi_drivers, detect_digi_driver, digi_card, "digital"); - _DRIVER_INFO *midi_drivers = system_driver->midi_drivers ? system_driver->midi_drivers() : _midi_driver_list; - std::pair midi_drv = decide_audiodriver(midi_id, midi_drivers, detect_midi_driver, midi_card, "MIDI"); - - // Now, knowing which drivers we suppose to install, decide on which voices we reserve - digi_id = digi_drv.first; - midi_id = midi_drv.first; - const int max_digi_voices = digi_drv.second; - const int max_midi_voices = midi_drv.second; - if (digi_voices > max_digi_voices) - digi_voices = max_digi_voices; - // NOTE: we do not specify number of MIDI voices, so don't have to calculate available here - - reserve_voices(digi_voices, midi_voices); - // maybe this line will solve the sound volume? [??? wth is this] - set_volume_per_voice(1); - - String err_msg; - bool sound_res = try_install_sound(digi_id, midi_id, &err_msg); - if (!sound_res) - { - Debug::Printf(kDbgMsg_Error, "Everything failed, disabling sound."); - reserve_voices(0, 0); - install_sound(DIGI_NONE, MIDI_NONE, nullptr); - } - // Only display a warning if they wanted a sound card - const bool digi_failed = usetup.digicard != DIGI_NONE && digi_card == DIGI_NONE; - const bool midi_failed = usetup.midicard != MIDI_NONE && midi_card == MIDI_NONE; - if (digi_failed || midi_failed) - { - platform->DisplayAlert("Warning: cannot enable %s.\nProblem: %s.\n\nYou may supress this message by disabling %s in the game setup.", - (digi_failed && midi_failed ? "game audio" : (digi_failed ? "digital audio" : "MIDI audio") ), - (err_msg.IsEmpty() ? "No compatible drivers found in the system" : err_msg.GetCStr()), - (digi_failed && midi_failed ? "sound" : (digi_failed ? "digital sound" : "MIDI sound") )); - } - - usetup.digicard = digi_card; - usetup.midicard = midi_card; - - Debug::Printf(kDbgMsg_Info, "Installed digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", - AlIDToChars(digi_card).s, digi_card, AlIDToChars(midi_card).s, midi_card); - - if (digi_card == DIGI_NONE) - { - // disable speech and music if no digital sound - // therefore the MIDI soundtrack will be used if present, - // and the voice mode should not go to Voice Only - play.want_speech = -2; - play.separate_music_lib = 0; - } - if (usetup.mod_player && digi_driver->voices < NUM_DIGI_VOICES) - { - // disable MOD player if there's not enough digital voices - // TODO: find out if this is still relevant? - usetup.mod_player = 0; - } +void engine_init_audio() { + Debug::Printf("Initializing sound drivers"); + int digi_id = usetup.digicard; + int midi_id = usetup.midicard; + int digi_voices = -1; + int midi_voices = -1; + // MOD player would need certain minimal number of voices + // TODO: find out if this is still relevant? + if (usetup.mod_player) + digi_voices = NUM_DIGI_VOICES; + + Debug::Printf(kDbgMsg_Info, "Sound settings: digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", + AlIDToChars(digi_id).s, digi_id, AlIDToChars(midi_id).s, midi_id); + + // First try if drivers are supported, and switch to autodetect if explicit option failed + _DRIVER_INFO *digi_drivers = system_driver->digi_drivers ? system_driver->digi_drivers() : _digi_driver_list; + std::pair digi_drv = decide_audiodriver(digi_id, digi_drivers, detect_digi_driver, digi_card, "digital"); + _DRIVER_INFO *midi_drivers = system_driver->midi_drivers ? system_driver->midi_drivers() : _midi_driver_list; + std::pair midi_drv = decide_audiodriver(midi_id, midi_drivers, detect_midi_driver, midi_card, "MIDI"); + + // Now, knowing which drivers we suppose to install, decide on which voices we reserve + digi_id = digi_drv.first; + midi_id = midi_drv.first; + const int max_digi_voices = digi_drv.second; + const int max_midi_voices = midi_drv.second; + if (digi_voices > max_digi_voices) + digi_voices = max_digi_voices; + // NOTE: we do not specify number of MIDI voices, so don't have to calculate available here + + reserve_voices(digi_voices, midi_voices); + // maybe this line will solve the sound volume? [??? wth is this] + set_volume_per_voice(1); + + String err_msg; + bool sound_res = try_install_sound(digi_id, midi_id, &err_msg); + if (!sound_res) { + Debug::Printf(kDbgMsg_Error, "Everything failed, disabling sound."); + reserve_voices(0, 0); + install_sound(DIGI_NONE, MIDI_NONE, nullptr); + } + // Only display a warning if they wanted a sound card + const bool digi_failed = usetup.digicard != DIGI_NONE && digi_card == DIGI_NONE; + const bool midi_failed = usetup.midicard != MIDI_NONE && midi_card == MIDI_NONE; + if (digi_failed || midi_failed) { + platform->DisplayAlert("Warning: cannot enable %s.\nProblem: %s.\n\nYou may supress this message by disabling %s in the game setup.", + (digi_failed && midi_failed ? "game audio" : (digi_failed ? "digital audio" : "MIDI audio")), + (err_msg.IsEmpty() ? "No compatible drivers found in the system" : err_msg.GetCStr()), + (digi_failed && midi_failed ? "sound" : (digi_failed ? "digital sound" : "MIDI sound"))); + } + + usetup.digicard = digi_card; + usetup.midicard = midi_card; + + Debug::Printf(kDbgMsg_Info, "Installed digital driver ID: '%s' (0x%x), MIDI driver ID: '%s' (0x%x)", + AlIDToChars(digi_card).s, digi_card, AlIDToChars(midi_card).s, midi_card); + + if (digi_card == DIGI_NONE) { + // disable speech and music if no digital sound + // therefore the MIDI soundtrack will be used if present, + // and the voice mode should not go to Voice Only + play.want_speech = -2; + play.separate_music_lib = 0; + } + if (usetup.mod_player && digi_driver->voices < NUM_DIGI_VOICES) { + // disable MOD player if there's not enough digital voices + // TODO: find out if this is still relevant? + usetup.mod_player = 0; + } #if AGS_PLATFORM_OS_WINDOWS - if (digi_card == DIGI_DIRECTX(0)) - { - // DirectX mixer seems to buffer an extra sample itself - use_extra_sound_offset = 1; - } + if (digi_card == DIGI_DIRECTX(0)) { + // DirectX mixer seems to buffer an extra sample itself + use_extra_sound_offset = 1; + } #endif } -void engine_init_debug() -{ - //set_volume(255,-1); - if ((debug_flags & (~DBG_DEBUGMODE)) >0) { - platform->DisplayAlert("Engine debugging enabled.\n" - "\nNOTE: You have selected to enable one or more engine debugging options.\n" - "These options cause many parts of the game to behave abnormally, and you\n" - "may not see the game as you are used to it. The point is to test whether\n" - "the engine passes a point where it is crashing on you normally.\n" - "[Debug flags enabled: 0x%02X]",debug_flags); - } +void engine_init_debug() { + //set_volume(255,-1); + if ((debug_flags & (~DBG_DEBUGMODE)) > 0) { + platform->DisplayAlert("Engine debugging enabled.\n" + "\nNOTE: You have selected to enable one or more engine debugging options.\n" + "These options cause many parts of the game to behave abnormally, and you\n" + "may not see the game as you are used to it. The point is to test whether\n" + "the engine passes a point where it is crashing on you normally.\n" + "[Debug flags enabled: 0x%02X]", debug_flags); + } } void atexit_handler() { - if (proper_exit==0) { - platform->DisplayAlert("Error: the program has exited without requesting it.\n" - "Program pointer: %+03d (write this number down), ACI version %s\n" - "If you see a list of numbers above, please write them down and contact\n" - "developers. Otherwise, note down any other information displayed.", - our_eip, EngineVersion.LongString.GetCStr()); - } + if (proper_exit == 0) { + platform->DisplayAlert("Error: the program has exited without requesting it.\n" + "Program pointer: %+03d (write this number down), ACI version %s\n" + "If you see a list of numbers above, please write them down and contact\n" + "developers. Otherwise, note down any other information displayed.", + our_eip, EngineVersion.LongString.GetCStr()); + } } -void engine_init_exit_handler() -{ - Debug::Printf(kDbgMsg_Info, "Install exit handler"); +void engine_init_exit_handler() { + Debug::Printf(kDbgMsg_Info, "Install exit handler"); - atexit(atexit_handler); + atexit(atexit_handler); } -void engine_init_rand() -{ - play.randseed = time(nullptr); - srand (play.randseed); +void engine_init_rand() { + play.randseed = time(nullptr); + srand(play.randseed); } -void engine_init_pathfinder() -{ - init_pathfinder(loaded_game_file_version); +void engine_init_pathfinder() { + init_pathfinder(loaded_game_file_version); } -void engine_pre_init_gfx() -{ - //Debug::Printf("Initialize gfx"); +void engine_pre_init_gfx() { + //Debug::Printf("Initialize gfx"); - //platform->InitialiseAbufAtStartup(); + //platform->InitialiseAbufAtStartup(); } -int engine_load_game_data() -{ - Debug::Printf("Load game data"); - our_eip=-17; - HError err = load_game_file(); - if (!err) - { - proper_exit=1; - platform->FinishedUsingGraphicsMode(); - display_game_file_error(err); - return EXIT_ERROR; - } - return 0; +int engine_load_game_data() { + Debug::Printf("Load game data"); + our_eip = -17; + HError err = load_game_file(); + if (!err) { + proper_exit = 1; + platform->FinishedUsingGraphicsMode(); + display_game_file_error(err); + return EXIT_ERROR; + } + return 0; } -int engine_check_register_game() -{ - if (justRegisterGame) - { - platform->RegisterGameWithGameExplorer(); - proper_exit = 1; - return EXIT_NORMAL; - } - - if (justUnRegisterGame) - { - platform->UnRegisterGameWithGameExplorer(); - proper_exit = 1; - return EXIT_NORMAL; - } - - return 0; +int engine_check_register_game() { + if (justRegisterGame) { + platform->RegisterGameWithGameExplorer(); + proper_exit = 1; + return EXIT_NORMAL; + } + + if (justUnRegisterGame) { + platform->UnRegisterGameWithGameExplorer(); + proper_exit = 1; + return EXIT_NORMAL; + } + + return 0; } -void engine_init_title() -{ - our_eip=-91; - set_window_title(game.gamename); - Debug::Printf(kDbgMsg_Info, "Game title: '%s'", game.gamename); +void engine_init_title() { + our_eip = -91; + set_window_title(game.gamename); + Debug::Printf(kDbgMsg_Info, "Game title: '%s'", game.gamename); } -void engine_init_directories() -{ - Debug::Printf(kDbgMsg_Info, "Data directory: %s", usetup.data_files_dir.GetCStr()); - if (!usetup.install_dir.IsEmpty()) - Debug::Printf(kDbgMsg_Info, "Optional install directory: %s", usetup.install_dir.GetCStr()); - if (!usetup.install_audio_dir.IsEmpty()) - Debug::Printf(kDbgMsg_Info, "Optional audio directory: %s", usetup.install_audio_dir.GetCStr()); - if (!usetup.install_voice_dir.IsEmpty()) - Debug::Printf(kDbgMsg_Info, "Optional voice-over directory: %s", usetup.install_voice_dir.GetCStr()); - if (!usetup.user_data_dir.IsEmpty()) - Debug::Printf(kDbgMsg_Info, "User data directory: %s", usetup.user_data_dir.GetCStr()); - if (!usetup.shared_data_dir.IsEmpty()) - Debug::Printf(kDbgMsg_Info, "Shared data directory: %s", usetup.shared_data_dir.GetCStr()); - - ResPaths.DataDir = usetup.data_files_dir; - ResPaths.GamePak.Path = usetup.main_data_filepath; - ResPaths.GamePak.Name = get_filename(usetup.main_data_filepath); - - set_install_dir(usetup.install_dir, usetup.install_audio_dir, usetup.install_voice_dir); - if (!usetup.install_dir.IsEmpty()) - { - // running in debugger: don't redirect to the game exe folder (_Debug) - // TODO: find out why we need to do this (and do we?) - ResPaths.DataDir = "."; - } - - // if end-user specified custom save path, use it - bool res = false; - if (!usetup.user_data_dir.IsEmpty()) - { - res = SetCustomSaveParent(usetup.user_data_dir); - if (!res) - { - Debug::Printf(kDbgMsg_Warn, "WARNING: custom user save path failed, using default system paths"); - res = false; - } - } - // if there is no custom path, or if custom path failed, use default system path - if (!res) - { - char newDirBuffer[MAX_PATH]; - sprintf(newDirBuffer, "%s/%s", UserSavedgamesRootToken.GetCStr(), game.saveGameFolderName); - SetSaveGameDirectoryPath(newDirBuffer); - } +void engine_init_directories() { + Debug::Printf(kDbgMsg_Info, "Data directory: %s", usetup.data_files_dir.GetCStr()); + if (!usetup.install_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Optional install directory: %s", usetup.install_dir.GetCStr()); + if (!usetup.install_audio_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Optional audio directory: %s", usetup.install_audio_dir.GetCStr()); + if (!usetup.install_voice_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Optional voice-over directory: %s", usetup.install_voice_dir.GetCStr()); + if (!usetup.user_data_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "User data directory: %s", usetup.user_data_dir.GetCStr()); + if (!usetup.shared_data_dir.IsEmpty()) + Debug::Printf(kDbgMsg_Info, "Shared data directory: %s", usetup.shared_data_dir.GetCStr()); + + ResPaths.DataDir = usetup.data_files_dir; + ResPaths.GamePak.Path = usetup.main_data_filepath; + ResPaths.GamePak.Name = get_filename(usetup.main_data_filepath); + + set_install_dir(usetup.install_dir, usetup.install_audio_dir, usetup.install_voice_dir); + if (!usetup.install_dir.IsEmpty()) { + // running in debugger: don't redirect to the game exe folder (_Debug) + // TODO: find out why we need to do this (and do we?) + ResPaths.DataDir = "."; + } + + // if end-user specified custom save path, use it + bool res = false; + if (!usetup.user_data_dir.IsEmpty()) { + res = SetCustomSaveParent(usetup.user_data_dir); + if (!res) { + Debug::Printf(kDbgMsg_Warn, "WARNING: custom user save path failed, using default system paths"); + res = false; + } + } + // if there is no custom path, or if custom path failed, use default system path + if (!res) { + char newDirBuffer[MAX_PATH]; + sprintf(newDirBuffer, "%s/%s", UserSavedgamesRootToken.GetCStr(), game.saveGameFolderName); + SetSaveGameDirectoryPath(newDirBuffer); + } } #if AGS_PLATFORM_OS_ANDROID @@ -736,462 +661,434 @@ extern char android_base_directory[256]; int check_write_access() { - if (platform->GetDiskFreeSpaceMB() < 2) - return 0; + if (platform->GetDiskFreeSpaceMB() < 2) + return 0; - our_eip = -1895; + our_eip = -1895; - // The Save Game Dir is the only place that we should write to - String svg_dir = get_save_game_directory(); - String tempPath = String::FromFormat("%s""tmptest.tmp", svg_dir.GetCStr()); - Stream *temp_s = Common::File::CreateFile(tempPath); - if (!temp_s) - // TODO: move this somewhere else (Android platform driver init?) + // The Save Game Dir is the only place that we should write to + String svg_dir = get_save_game_directory(); + String tempPath = String::FromFormat("%s""tmptest.tmp", svg_dir.GetCStr()); + Stream *temp_s = Common::File::CreateFile(tempPath); + if (!temp_s) + // TODO: move this somewhere else (Android platform driver init?) #if AGS_PLATFORM_OS_ANDROID - { - put_backslash(android_base_directory); - tempPath.Format("%s""tmptest.tmp", android_base_directory); - temp_s = Common::File::CreateFile(tempPath); - if (temp_s == NULL) return 0; - else SetCustomSaveParent(android_base_directory); - } + { + put_backslash(android_base_directory); + tempPath.Format("%s""tmptest.tmp", android_base_directory); + temp_s = Common::File::CreateFile(tempPath); + if (temp_s == NULL) return 0; + else SetCustomSaveParent(android_base_directory); + } #else - return 0; + return 0; #endif // AGS_PLATFORM_OS_ANDROID - our_eip = -1896; + our_eip = -1896; - temp_s->Write("just to test the drive free space", 30); - delete temp_s; + temp_s->Write("just to test the drive free space", 30); + delete temp_s; - our_eip = -1897; + our_eip = -1897; - if (::remove(tempPath)) - return 0; + if (::remove(tempPath)) + return 0; - return 1; + return 1; } -int engine_check_disk_space() -{ - Debug::Printf(kDbgMsg_Info, "Checking for disk space"); +int engine_check_disk_space() { + Debug::Printf(kDbgMsg_Info, "Checking for disk space"); - if (check_write_access()==0) { - platform->DisplayAlert("Unable to write in the savegame directory.\n%s", platform->GetDiskWriteAccessTroubleshootingText()); - proper_exit = 1; - return EXIT_ERROR; - } + if (check_write_access() == 0) { + platform->DisplayAlert("Unable to write in the savegame directory.\n%s", platform->GetDiskWriteAccessTroubleshootingText()); + proper_exit = 1; + return EXIT_ERROR; + } - return 0; + return 0; } -int engine_check_font_was_loaded() -{ - if (!font_first_renderer_loaded()) - { - platform->DisplayAlert("No game fonts found. At least one font is required to run the game."); - proper_exit = 1; - return EXIT_ERROR; - } +int engine_check_font_was_loaded() { + if (!font_first_renderer_loaded()) { + platform->DisplayAlert("No game fonts found. At least one font is required to run the game."); + proper_exit = 1; + return EXIT_ERROR; + } - return 0; + return 0; } -void engine_init_modxm_player() -{ +void engine_init_modxm_player() { #ifndef PSP_NO_MOD_PLAYBACK - if (game.options[OPT_NOMODMUSIC]) - usetup.mod_player = 0; + if (game.options[OPT_NOMODMUSIC]) + usetup.mod_player = 0; - if (usetup.mod_player) { - Debug::Printf(kDbgMsg_Info, "Initializing MOD/XM player"); + if (usetup.mod_player) { + Debug::Printf(kDbgMsg_Info, "Initializing MOD/XM player"); - if (init_mod_player(NUM_MOD_DIGI_VOICES) < 0) { - platform->DisplayAlert("Warning: install_mod: MOD player failed to initialize."); - usetup.mod_player=0; - } - } + if (init_mod_player(NUM_MOD_DIGI_VOICES) < 0) { + platform->DisplayAlert("Warning: install_mod: MOD player failed to initialize."); + usetup.mod_player = 0; + } + } #else - usetup.mod_player = 0; - Debug::Printf(kDbgMsg_Info, "Compiled without MOD/XM player"); + usetup.mod_player = 0; + Debug::Printf(kDbgMsg_Info, "Compiled without MOD/XM player"); #endif } // Do the preload graphic if available -void show_preload() -{ - color temppal[256]; - Bitmap *splashsc = BitmapHelper::CreateRawBitmapOwner( load_pcx("preload.pcx",temppal) ); - if (splashsc != nullptr) - { - Debug::Printf("Displaying preload image"); - if (splashsc->GetColorDepth() == 8) - set_palette_range(temppal, 0, 255, 0); - if (gfxDriver->UsesMemoryBackBuffer()) - gfxDriver->GetMemoryBackBuffer()->Clear(); - - const Rect &view = play.GetMainViewport(); - Bitmap *tsc = BitmapHelper::CreateBitmapCopy(splashsc, game.GetColorDepth()); - if (!gfxDriver->HasAcceleratedTransform() && view.GetSize() != tsc->GetSize()) - { - Bitmap *stretched = new Bitmap(view.GetWidth(), view.GetHeight(), tsc->GetColorDepth()); - stretched->StretchBlt(tsc, RectWH(0, 0, view.GetWidth(), view.GetHeight())); - delete tsc; - tsc = stretched; - } - IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(tsc, false, true); - ddb->SetStretch(view.GetWidth(), view.GetHeight()); - gfxDriver->ClearDrawLists(); - gfxDriver->DrawSprite(0, 0, ddb); - render_to_screen(); - gfxDriver->DestroyDDB(ddb); - delete splashsc; - delete tsc; - platform->Delay(500); - } +void show_preload() { + color temppal[256]; + Bitmap *splashsc = BitmapHelper::CreateRawBitmapOwner(load_pcx("preload.pcx", temppal)); + if (splashsc != nullptr) { + Debug::Printf("Displaying preload image"); + if (splashsc->GetColorDepth() == 8) + set_palette_range(temppal, 0, 255, 0); + if (gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->GetMemoryBackBuffer()->Clear(); + + const Rect &view = play.GetMainViewport(); + Bitmap *tsc = BitmapHelper::CreateBitmapCopy(splashsc, game.GetColorDepth()); + if (!gfxDriver->HasAcceleratedTransform() && view.GetSize() != tsc->GetSize()) { + Bitmap *stretched = new Bitmap(view.GetWidth(), view.GetHeight(), tsc->GetColorDepth()); + stretched->StretchBlt(tsc, RectWH(0, 0, view.GetWidth(), view.GetHeight())); + delete tsc; + tsc = stretched; + } + IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(tsc, false, true); + ddb->SetStretch(view.GetWidth(), view.GetHeight()); + gfxDriver->ClearDrawLists(); + gfxDriver->DrawSprite(0, 0, ddb); + render_to_screen(); + gfxDriver->DestroyDDB(ddb); + delete splashsc; + delete tsc; + platform->Delay(500); + } } -int engine_init_sprites() -{ - Debug::Printf(kDbgMsg_Info, "Initialize sprites"); - - HError err = spriteset.InitFile(SpriteCache::DefaultSpriteFileName, SpriteCache::DefaultSpriteIndexName); - if (!err) - { - platform->FinishedUsingGraphicsMode(); - allegro_exit(); - proper_exit=1; - platform->DisplayAlert("Could not load sprite set file %s\n%s", - SpriteCache::DefaultSpriteFileName.GetCStr(), - err->FullMessage().GetCStr()); - return EXIT_ERROR; - } - - return 0; +int engine_init_sprites() { + Debug::Printf(kDbgMsg_Info, "Initialize sprites"); + + HError err = spriteset.InitFile(SpriteCache::DefaultSpriteFileName, SpriteCache::DefaultSpriteIndexName); + if (!err) { + platform->FinishedUsingGraphicsMode(); + allegro_exit(); + proper_exit = 1; + platform->DisplayAlert("Could not load sprite set file %s\n%s", + SpriteCache::DefaultSpriteFileName.GetCStr(), + err->FullMessage().GetCStr()); + return EXIT_ERROR; + } + + return 0; } -void engine_init_game_settings() -{ - our_eip=-7; - Debug::Printf("Initialize game settings"); - - int ee; - - for (ee = 0; ee < MAX_ROOM_OBJECTS + game.numcharacters; ee++) - actsps[ee] = nullptr; - - for (ee=0;ee<256;ee++) { - if (game.paluses[ee]!=PAL_BACKGROUND) - palette[ee]=game.defpal[ee]; - } - - for (ee = 0; ee < game.numcursors; ee++) - { - // The cursor graphics are assigned to mousecurs[] and so cannot - // be removed from memory - if (game.mcurs[ee].pic >= 0) - spriteset.Precache(game.mcurs[ee].pic); - - // just in case they typed an invalid view number in the editor - if (game.mcurs[ee].view >= game.numviews) - game.mcurs[ee].view = -1; - - if (game.mcurs[ee].view >= 0) - precache_view (game.mcurs[ee].view); - } - // may as well preload the character gfx - if (playerchar->view >= 0) - precache_view (playerchar->view); - - for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++) - objcache[ee].image = nullptr; - - /* dummygui.guiId = -1; - dummyguicontrol.guin = -1; - dummyguicontrol.objn = -1;*/ - - our_eip=-6; - // game.chars[0].talkview=4; - //init_language_text(game.langcodes[0]); - - for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++) { - scrObj[ee].id = ee; - // 64 bit: Using the id instead - // scrObj[ee].obj = NULL; - } - - for (ee=0;ee= 0) { - // set initial loop to 0 - game.chars[ee].loop = 0; - // or to 1 if they don't have up/down frames - if (views[game.chars[ee].view].loops[0].numFrames < 1) - game.chars[ee].loop = 1; - } - charextra[ee].process_idle_this_time = 0; - charextra[ee].invorder_count = 0; - charextra[ee].slow_move_counter = 0; - charextra[ee].animwait = 0; - } - // multiply up gui positions - guibg = (Bitmap **)malloc(sizeof(Bitmap *) * game.numgui); - guibgbmp = (IDriverDependantBitmap**)malloc(sizeof(IDriverDependantBitmap*) * game.numgui); - for (ee=0;eeinv[ee]=1; - else playerchar->inv[ee]=0; - } - play.score=0; - play.sierra_inv_color=7; - // copy the value set by the editor - if (game.options[OPT_GLOBALTALKANIMSPD] >= 0) - { - play.talkanim_speed = game.options[OPT_GLOBALTALKANIMSPD]; - game.options[OPT_GLOBALTALKANIMSPD] = 1; - } - else - { - play.talkanim_speed = -game.options[OPT_GLOBALTALKANIMSPD] - 1; - game.options[OPT_GLOBALTALKANIMSPD] = 0; - } - play.inv_item_wid = 40; - play.inv_item_hit = 22; - play.messagetime=-1; - play.disabled_user_interface=0; - play.gscript_timer=-1; - play.debug_mode=game.options[OPT_DEBUGMODE]; - play.inv_top=0; - play.inv_numdisp=0; - play.obsolete_inv_numorder=0; - play.text_speed=15; - play.text_min_display_time_ms = 1000; - play.ignore_user_input_after_text_timeout_ms = 500; - play.ClearIgnoreInput(); - play.lipsync_speed = 15; - play.close_mouth_speech_time = 10; - play.disable_antialiasing = 0; - play.rtint_enabled = false; - play.rtint_level = 0; - play.rtint_light = 0; - play.text_speed_modifier = 0; - play.text_align = kHAlignLeft; - // Make the default alignment to the right with right-to-left text - if (game.options[OPT_RIGHTLEFTWRITE]) - play.text_align = kHAlignRight; - - play.speech_bubble_width = get_fixed_pixel_size(100); - play.bg_frame=0; - play.bg_frame_locked=0; - play.bg_anim_delay=0; - play.anim_background_speed = 0; - play.silent_midi = 0; - play.current_music_repeating = 0; - play.skip_until_char_stops = -1; - play.get_loc_name_last_time = -1; - play.get_loc_name_save_cursor = -1; - play.restore_cursor_mode_to = -1; - play.restore_cursor_image_to = -1; - play.ground_level_areas_disabled = 0; - play.next_screen_transition = -1; - play.temporarily_turned_off_character = -1; - play.inv_backwards_compatibility = 0; - play.gamma_adjustment = 100; - play.do_once_tokens.resize(0); - play.music_queue_size = 0; - play.shakesc_length = 0; - play.wait_counter=0; - play.key_skip_wait = SKIP_NONE; - play.cur_music_number=-1; - play.music_repeat=1; - play.music_master_volume=100 + LegacyMusicMasterVolumeAdjustment; - play.digital_master_volume = 100; - play.screen_flipped=0; - play.cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)game.options[OPT_NOSKIPTEXT]); - play.sound_volume = 255; - play.speech_volume = 255; - play.normal_font = 0; - play.speech_font = 1; - play.speech_text_shadow = 16; - play.screen_tint = -1; - play.bad_parsed_word[0] = 0; - play.swap_portrait_side = 0; - play.swap_portrait_lastchar = -1; - play.swap_portrait_lastlastchar = -1; - play.in_conversation = 0; - play.skip_display = 3; - play.no_multiloop_repeat = 0; - play.in_cutscene = 0; - play.fast_forward = 0; - play.totalscore = game.totalscore; - play.roomscript_finished = 0; - play.no_textbg_when_voice = 0; - play.max_dialogoption_width = get_fixed_pixel_size(180); - play.no_hicolor_fadein = 0; - play.bgspeech_game_speed = 0; - play.bgspeech_stay_on_display = 0; - play.unfactor_speech_from_textlength = 0; - play.mp3_loop_before_end = 70; - play.speech_music_drop = 60; - play.room_changes = 0; - play.check_interaction_only = 0; - play.replay_hotkey_unused = -1; // StartRecording: not supported. - play.dialog_options_x = 0; - play.dialog_options_y = 0; - play.min_dialogoption_width = 0; - play.disable_dialog_parser = 0; - play.ambient_sounds_persist = 0; - play.screen_is_faded_out = 0; - play.player_on_region = 0; - play.top_bar_backcolor = 8; - play.top_bar_textcolor = 16; - play.top_bar_bordercolor = 8; - play.top_bar_borderwidth = 1; - play.top_bar_ypos = 25; - play.top_bar_font = -1; - play.screenshot_width = 160; - play.screenshot_height = 100; - play.speech_text_align = kHAlignCenter; - play.auto_use_walkto_points = 1; - play.inventory_greys_out = 0; - play.skip_speech_specific_key = 0; - play.abort_key = 324; // Alt+X - play.fade_to_red = 0; - play.fade_to_green = 0; - play.fade_to_blue = 0; - play.show_single_dialog_option = 0; - play.keep_screen_during_instant_transition = 0; - play.read_dialog_option_colour = -1; - play.speech_portrait_placement = 0; - play.speech_portrait_x = 0; - play.speech_portrait_y = 0; - play.speech_display_post_time_ms = 0; - play.dialog_options_highlight_color = DIALOG_OPTIONS_HIGHLIGHT_COLOR_DEFAULT; - play.speech_has_voice = false; - play.speech_voice_blocking = false; - play.speech_in_post_state = false; - play.narrator_speech = game.playercharacter; - play.crossfading_out_channel = 0; - play.speech_textwindow_gui = game.options[OPT_TWCUSTOM]; - if (play.speech_textwindow_gui == 0) - play.speech_textwindow_gui = -1; - strcpy(play.game_name, game.gamename); - play.lastParserEntry[0] = 0; - play.follow_change_room_timer = 150; - for (ee = 0; ee < MAX_ROOM_BGFRAMES; ee++) - play.raw_modified[ee] = 0; - play.game_speed_modifier = 0; - if (debug_flags & DBG_DEBUGMODE) - play.debug_mode = 1; - gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); - play.shake_screen_yoff = 0; - - memset(&play.walkable_areas_on[0],1,MAX_WALK_AREAS+1); - memset(&play.script_timers[0],0,MAX_TIMERS * sizeof(int)); - memset(&play.default_audio_type_volumes[0], -1, MAX_AUDIO_TYPES * sizeof(int)); - - // reset graphical script vars (they're still used by some games) - for (ee = 0; ee < MAXGLOBALVARS; ee++) - play.globalvars[ee] = 0; - - for (ee = 0; ee < MAXGLOBALSTRINGS; ee++) - play.globalstrings[ee][0] = 0; - - if (!usetup.translation.IsEmpty()) - init_translation (usetup.translation, "", true); - - update_invorder(); - displayed_room = -10; - - currentcursor=0; - our_eip=-4; - mousey=100; // stop icon bar popping up - - // We use same variable to read config and be used at runtime for now, - // so update it here with regards to game design option - usetup.RenderAtScreenRes = - (game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_UserDefined && usetup.RenderAtScreenRes) || - game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_Enabled; +void engine_init_game_settings() { + our_eip = -7; + Debug::Printf("Initialize game settings"); + + int ee; + + for (ee = 0; ee < MAX_ROOM_OBJECTS + game.numcharacters; ee++) + actsps[ee] = nullptr; + + for (ee = 0; ee < 256; ee++) { + if (game.paluses[ee] != PAL_BACKGROUND) + palette[ee] = game.defpal[ee]; + } + + for (ee = 0; ee < game.numcursors; ee++) { + // The cursor graphics are assigned to mousecurs[] and so cannot + // be removed from memory + if (game.mcurs[ee].pic >= 0) + spriteset.Precache(game.mcurs[ee].pic); + + // just in case they typed an invalid view number in the editor + if (game.mcurs[ee].view >= game.numviews) + game.mcurs[ee].view = -1; + + if (game.mcurs[ee].view >= 0) + precache_view(game.mcurs[ee].view); + } + // may as well preload the character gfx + if (playerchar->view >= 0) + precache_view(playerchar->view); + + for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++) + objcache[ee].image = nullptr; + + /* dummygui.guiId = -1; + dummyguicontrol.guin = -1; + dummyguicontrol.objn = -1;*/ + + our_eip = -6; + // game.chars[0].talkview=4; + //init_language_text(game.langcodes[0]); + + for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++) { + scrObj[ee].id = ee; + // 64 bit: Using the id instead + // scrObj[ee].obj = NULL; + } + + for (ee = 0; ee < game.numcharacters; ee++) { + memset(&game.chars[ee].inv[0], 0, MAX_INV * sizeof(short)); + game.chars[ee].activeinv = -1; + game.chars[ee].following = -1; + game.chars[ee].followinfo = 97 | (10 << 8); + game.chars[ee].idletime = 20; // can be overridden later with SetIdle or summink + game.chars[ee].idleleft = game.chars[ee].idletime; + game.chars[ee].transparency = 0; + game.chars[ee].baseline = -1; + game.chars[ee].walkwaitcounter = 0; + game.chars[ee].z = 0; + charextra[ee].xwas = INVALID_X; + charextra[ee].zoom = 100; + if (game.chars[ee].view >= 0) { + // set initial loop to 0 + game.chars[ee].loop = 0; + // or to 1 if they don't have up/down frames + if (views[game.chars[ee].view].loops[0].numFrames < 1) + game.chars[ee].loop = 1; + } + charextra[ee].process_idle_this_time = 0; + charextra[ee].invorder_count = 0; + charextra[ee].slow_move_counter = 0; + charextra[ee].animwait = 0; + } + // multiply up gui positions + guibg = (Bitmap **)malloc(sizeof(Bitmap *) * game.numgui); + guibgbmp = (IDriverDependantBitmap **)malloc(sizeof(IDriverDependantBitmap *) * game.numgui); + for (ee = 0; ee < game.numgui; ee++) { + guibg[ee] = nullptr; + guibgbmp[ee] = nullptr; + } + + our_eip = -5; + for (ee = 0; ee < game.numinvitems; ee++) { + if (game.invinfo[ee].flags & IFLG_STARTWITH) playerchar->inv[ee] = 1; + else playerchar->inv[ee] = 0; + } + play.score = 0; + play.sierra_inv_color = 7; + // copy the value set by the editor + if (game.options[OPT_GLOBALTALKANIMSPD] >= 0) { + play.talkanim_speed = game.options[OPT_GLOBALTALKANIMSPD]; + game.options[OPT_GLOBALTALKANIMSPD] = 1; + } else { + play.talkanim_speed = -game.options[OPT_GLOBALTALKANIMSPD] - 1; + game.options[OPT_GLOBALTALKANIMSPD] = 0; + } + play.inv_item_wid = 40; + play.inv_item_hit = 22; + play.messagetime = -1; + play.disabled_user_interface = 0; + play.gscript_timer = -1; + play.debug_mode = game.options[OPT_DEBUGMODE]; + play.inv_top = 0; + play.inv_numdisp = 0; + play.obsolete_inv_numorder = 0; + play.text_speed = 15; + play.text_min_display_time_ms = 1000; + play.ignore_user_input_after_text_timeout_ms = 500; + play.ClearIgnoreInput(); + play.lipsync_speed = 15; + play.close_mouth_speech_time = 10; + play.disable_antialiasing = 0; + play.rtint_enabled = false; + play.rtint_level = 0; + play.rtint_light = 0; + play.text_speed_modifier = 0; + play.text_align = kHAlignLeft; + // Make the default alignment to the right with right-to-left text + if (game.options[OPT_RIGHTLEFTWRITE]) + play.text_align = kHAlignRight; + + play.speech_bubble_width = get_fixed_pixel_size(100); + play.bg_frame = 0; + play.bg_frame_locked = 0; + play.bg_anim_delay = 0; + play.anim_background_speed = 0; + play.silent_midi = 0; + play.current_music_repeating = 0; + play.skip_until_char_stops = -1; + play.get_loc_name_last_time = -1; + play.get_loc_name_save_cursor = -1; + play.restore_cursor_mode_to = -1; + play.restore_cursor_image_to = -1; + play.ground_level_areas_disabled = 0; + play.next_screen_transition = -1; + play.temporarily_turned_off_character = -1; + play.inv_backwards_compatibility = 0; + play.gamma_adjustment = 100; + play.do_once_tokens.resize(0); + play.music_queue_size = 0; + play.shakesc_length = 0; + play.wait_counter = 0; + play.key_skip_wait = SKIP_NONE; + play.cur_music_number = -1; + play.music_repeat = 1; + play.music_master_volume = 100 + LegacyMusicMasterVolumeAdjustment; + play.digital_master_volume = 100; + play.screen_flipped = 0; + play.cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)game.options[OPT_NOSKIPTEXT]); + play.sound_volume = 255; + play.speech_volume = 255; + play.normal_font = 0; + play.speech_font = 1; + play.speech_text_shadow = 16; + play.screen_tint = -1; + play.bad_parsed_word[0] = 0; + play.swap_portrait_side = 0; + play.swap_portrait_lastchar = -1; + play.swap_portrait_lastlastchar = -1; + play.in_conversation = 0; + play.skip_display = 3; + play.no_multiloop_repeat = 0; + play.in_cutscene = 0; + play.fast_forward = 0; + play.totalscore = game.totalscore; + play.roomscript_finished = 0; + play.no_textbg_when_voice = 0; + play.max_dialogoption_width = get_fixed_pixel_size(180); + play.no_hicolor_fadein = 0; + play.bgspeech_game_speed = 0; + play.bgspeech_stay_on_display = 0; + play.unfactor_speech_from_textlength = 0; + play.mp3_loop_before_end = 70; + play.speech_music_drop = 60; + play.room_changes = 0; + play.check_interaction_only = 0; + play.replay_hotkey_unused = -1; // StartRecording: not supported. + play.dialog_options_x = 0; + play.dialog_options_y = 0; + play.min_dialogoption_width = 0; + play.disable_dialog_parser = 0; + play.ambient_sounds_persist = 0; + play.screen_is_faded_out = 0; + play.player_on_region = 0; + play.top_bar_backcolor = 8; + play.top_bar_textcolor = 16; + play.top_bar_bordercolor = 8; + play.top_bar_borderwidth = 1; + play.top_bar_ypos = 25; + play.top_bar_font = -1; + play.screenshot_width = 160; + play.screenshot_height = 100; + play.speech_text_align = kHAlignCenter; + play.auto_use_walkto_points = 1; + play.inventory_greys_out = 0; + play.skip_speech_specific_key = 0; + play.abort_key = 324; // Alt+X + play.fade_to_red = 0; + play.fade_to_green = 0; + play.fade_to_blue = 0; + play.show_single_dialog_option = 0; + play.keep_screen_during_instant_transition = 0; + play.read_dialog_option_colour = -1; + play.speech_portrait_placement = 0; + play.speech_portrait_x = 0; + play.speech_portrait_y = 0; + play.speech_display_post_time_ms = 0; + play.dialog_options_highlight_color = DIALOG_OPTIONS_HIGHLIGHT_COLOR_DEFAULT; + play.speech_has_voice = false; + play.speech_voice_blocking = false; + play.speech_in_post_state = false; + play.narrator_speech = game.playercharacter; + play.crossfading_out_channel = 0; + play.speech_textwindow_gui = game.options[OPT_TWCUSTOM]; + if (play.speech_textwindow_gui == 0) + play.speech_textwindow_gui = -1; + strcpy(play.game_name, game.gamename); + play.lastParserEntry[0] = 0; + play.follow_change_room_timer = 150; + for (ee = 0; ee < MAX_ROOM_BGFRAMES; ee++) + play.raw_modified[ee] = 0; + play.game_speed_modifier = 0; + if (debug_flags & DBG_DEBUGMODE) + play.debug_mode = 1; + gui_disabled_style = convert_gui_disabled_style(game.options[OPT_DISABLEOFF]); + play.shake_screen_yoff = 0; + + memset(&play.walkable_areas_on[0], 1, MAX_WALK_AREAS + 1); + memset(&play.script_timers[0], 0, MAX_TIMERS * sizeof(int)); + memset(&play.default_audio_type_volumes[0], -1, MAX_AUDIO_TYPES * sizeof(int)); + + // reset graphical script vars (they're still used by some games) + for (ee = 0; ee < MAXGLOBALVARS; ee++) + play.globalvars[ee] = 0; + + for (ee = 0; ee < MAXGLOBALSTRINGS; ee++) + play.globalstrings[ee][0] = 0; + + if (!usetup.translation.IsEmpty()) + init_translation(usetup.translation, "", true); + + update_invorder(); + displayed_room = -10; + + currentcursor = 0; + our_eip = -4; + mousey = 100; // stop icon bar popping up + + // We use same variable to read config and be used at runtime for now, + // so update it here with regards to game design option + usetup.RenderAtScreenRes = + (game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_UserDefined && usetup.RenderAtScreenRes) || + game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_Enabled; } -void engine_setup_scsystem_auxiliary() -{ - // ScriptSystem::aci_version is only 10 chars long - strncpy(scsystem.aci_version, EngineVersion.LongString, 10); - if (usetup.override_script_os >= 0) - { - scsystem.os = usetup.override_script_os; - } - else - { - scsystem.os = platform->GetSystemOSID(); - } +void engine_setup_scsystem_auxiliary() { + // ScriptSystem::aci_version is only 10 chars long + strncpy(scsystem.aci_version, EngineVersion.LongString, 10); + if (usetup.override_script_os >= 0) { + scsystem.os = usetup.override_script_os; + } else { + scsystem.os = platform->GetSystemOSID(); + } } -void engine_update_mp3_thread() -{ - update_mp3_thread(); - platform->Delay(50); +void engine_update_mp3_thread() { + update_mp3_thread(); + platform->Delay(50); } -void engine_start_multithreaded_audio() -{ - // PSP: Initialize the sound cache. - clear_sound_cache(); - - // Create sound update thread. This is a workaround for sound stuttering. - if (psp_audio_multithreaded) - { - if (!audioThread.CreateAndStart(engine_update_mp3_thread, true)) - { - Debug::Printf(kDbgMsg_Info, "Failed to start audio thread, audio will be processed on the main thread"); - psp_audio_multithreaded = 0; - } - else - { - Debug::Printf(kDbgMsg_Info, "Audio thread started"); - } - } - else - { - Debug::Printf(kDbgMsg_Info, "Audio is processed on the main thread"); - } +void engine_start_multithreaded_audio() { + // PSP: Initialize the sound cache. + clear_sound_cache(); + + // Create sound update thread. This is a workaround for sound stuttering. + if (psp_audio_multithreaded) { + if (!audioThread.CreateAndStart(engine_update_mp3_thread, true)) { + Debug::Printf(kDbgMsg_Info, "Failed to start audio thread, audio will be processed on the main thread"); + psp_audio_multithreaded = 0; + } else { + Debug::Printf(kDbgMsg_Info, "Audio thread started"); + } + } else { + Debug::Printf(kDbgMsg_Info, "Audio is processed on the main thread"); + } } -void engine_prepare_to_start_game() -{ - Debug::Printf("Prepare to start game"); +void engine_prepare_to_start_game() { + Debug::Printf("Prepare to start game"); - engine_setup_scsystem_auxiliary(); - engine_start_multithreaded_audio(); + engine_setup_scsystem_auxiliary(); + engine_start_multithreaded_audio(); #if AGS_PLATFORM_OS_ANDROID - if (psp_load_latest_savegame) - selectLatestSavegame(); + if (psp_load_latest_savegame) + selectLatestSavegame(); #endif } // TODO: move to test unit Bitmap *test_allegro_bitmap; IDriverDependantBitmap *test_allegro_ddb; -void allegro_bitmap_test_init() -{ +void allegro_bitmap_test_init() { test_allegro_bitmap = nullptr; // Switched the test off for now //test_allegro_bitmap = AllegroBitmap::CreateBitmap(320,200,32); @@ -1201,485 +1098,446 @@ void allegro_bitmap_test_init() // otherwise use explicit argument either from program wrapper, command-line // or read from default config. #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX || AGS_PLATFORM_OS_MACOS - #define AGS_SEARCH_FOR_GAME_ON_LAUNCH +#define AGS_SEARCH_FOR_GAME_ON_LAUNCH #endif // Define location of the game data either using direct settings or searching // for the available resource packs in common locations -HError define_gamedata_location_checkall(const String &exe_path) -{ - // First try if they provided a startup option - if (!cmdGameDataPath.IsEmpty()) - { - // If not a valid path - bail out - if (!Path::IsFileOrDir(cmdGameDataPath)) - return new Error(String::FromFormat("Defined game location is not a valid path.\nPath: '%s'", cmdGameDataPath.GetCStr())); - // Switch working dir to this path to be able to look for config and other assets there - Directory::SetCurrentDirectory(Path::GetDirectoryPath(cmdGameDataPath)); - // If it's a file, then keep it and proceed - if (Path::IsFile(cmdGameDataPath)) - { - usetup.main_data_filepath = cmdGameDataPath; - return HError::None(); - } - } - // Read game data location from the default config file. - // This is an optional setting that may instruct which game file to use as a primary asset library. - ConfigTree cfg; - String def_cfg_file = find_default_cfg_file(exe_path); - IniUtil::Read(def_cfg_file, cfg); - read_game_data_location(cfg); - if (!usetup.main_data_filename.IsEmpty()) - return HError::None(); +HError define_gamedata_location_checkall(const String &exe_path) { + // First try if they provided a startup option + if (!cmdGameDataPath.IsEmpty()) { + // If not a valid path - bail out + if (!Path::IsFileOrDir(cmdGameDataPath)) + return new Error(String::FromFormat("Defined game location is not a valid path.\nPath: '%s'", cmdGameDataPath.GetCStr())); + // Switch working dir to this path to be able to look for config and other assets there + Directory::SetCurrentDirectory(Path::GetDirectoryPath(cmdGameDataPath)); + // If it's a file, then keep it and proceed + if (Path::IsFile(cmdGameDataPath)) { + usetup.main_data_filepath = cmdGameDataPath; + return HError::None(); + } + } + // Read game data location from the default config file. + // This is an optional setting that may instruct which game file to use as a primary asset library. + ConfigTree cfg; + String def_cfg_file = find_default_cfg_file(exe_path); + IniUtil::Read(def_cfg_file, cfg); + read_game_data_location(cfg); + if (!usetup.main_data_filename.IsEmpty()) + return HError::None(); #if defined (AGS_SEARCH_FOR_GAME_ON_LAUNCH) - // No direct filepath provided, search in common locations. - String path, search_path; - if (search_for_game_data_file(path, search_path)) - { - usetup.main_data_filepath = path; - return HError::None(); - } - return new Error("Engine was not able to find any compatible game data.", - search_path.IsEmpty() ? String() : String::FromFormat("Searched in: %s", search_path.GetCStr())); + // No direct filepath provided, search in common locations. + String path, search_path; + if (search_for_game_data_file(path, search_path)) { + usetup.main_data_filepath = path; + return HError::None(); + } + return new Error("Engine was not able to find any compatible game data.", + search_path.IsEmpty() ? String() : String::FromFormat("Searched in: %s", search_path.GetCStr())); #else - return new Error("The game location was not defined by startup settings."); + return new Error("The game location was not defined by startup settings."); #endif } // Define location of the game data -bool define_gamedata_location(const String &exe_path) -{ - HError err = define_gamedata_location_checkall(exe_path); - if (!err) - { - platform->DisplayAlert("ERROR: Unable to determine game data.\n%s", err->FullMessage().GetCStr()); - main_print_help(); - return false; - } - - // On success: set all the necessary path and filename settings, - // derive missing ones from available. - if (usetup.main_data_filename.IsEmpty()) - { - usetup.main_data_filename = get_filename(usetup.main_data_filepath); - } - else if (usetup.main_data_filepath.IsEmpty()) - { - if (usetup.data_files_dir.IsEmpty() || !is_relative_filename(usetup.main_data_filename)) - usetup.main_data_filepath = usetup.main_data_filename; - else - usetup.main_data_filepath = Path::ConcatPaths(usetup.data_files_dir, usetup.main_data_filename); - } - if (usetup.data_files_dir.IsEmpty()) - usetup.data_files_dir = Path::GetDirectoryPath(usetup.main_data_filepath); - return true; +bool define_gamedata_location(const String &exe_path) { + HError err = define_gamedata_location_checkall(exe_path); + if (!err) { + platform->DisplayAlert("ERROR: Unable to determine game data.\n%s", err->FullMessage().GetCStr()); + main_print_help(); + return false; + } + + // On success: set all the necessary path and filename settings, + // derive missing ones from available. + if (usetup.main_data_filename.IsEmpty()) { + usetup.main_data_filename = get_filename(usetup.main_data_filepath); + } else if (usetup.main_data_filepath.IsEmpty()) { + if (usetup.data_files_dir.IsEmpty() || !is_relative_filename(usetup.main_data_filename)) + usetup.main_data_filepath = usetup.main_data_filename; + else + usetup.main_data_filepath = Path::ConcatPaths(usetup.data_files_dir, usetup.main_data_filename); + } + if (usetup.data_files_dir.IsEmpty()) + usetup.data_files_dir = Path::GetDirectoryPath(usetup.main_data_filepath); + return true; } // Find and preload main game data -bool engine_init_gamedata(const String &exe_path) -{ - Debug::Printf(kDbgMsg_Info, "Initializing game data"); - if (!define_gamedata_location(exe_path)) - return false; - if (!engine_try_init_gamedata(usetup.main_data_filepath)) - return false; - - // Pre-load game name and savegame folder names from data file - // TODO: research if that is possible to avoid this step and just - // read the full head game data at this point. This might require - // further changes of the order of initialization. - HError err = preload_game_data(); - if (!err) - { - display_game_file_error(err); - return false; - } - return true; +bool engine_init_gamedata(const String &exe_path) { + Debug::Printf(kDbgMsg_Info, "Initializing game data"); + if (!define_gamedata_location(exe_path)) + return false; + if (!engine_try_init_gamedata(usetup.main_data_filepath)) + return false; + + // Pre-load game name and savegame folder names from data file + // TODO: research if that is possible to avoid this step and just + // read the full head game data at this point. This might require + // further changes of the order of initialization. + HError err = preload_game_data(); + if (!err) { + display_game_file_error(err); + return false; + } + return true; } -void engine_read_config(const String &exe_path, ConfigTree &cfg) -{ - // Read default configuration file - String def_cfg_file = find_default_cfg_file(exe_path); - IniUtil::Read(def_cfg_file, cfg); +void engine_read_config(const String &exe_path, ConfigTree &cfg) { + // Read default configuration file + String def_cfg_file = find_default_cfg_file(exe_path); + IniUtil::Read(def_cfg_file, cfg); - // Disabled on Windows because people were afraid that this config could be mistakenly - // created by some installer and screw up their games. Until any kind of solution is found. - String user_global_cfg_file; + // Disabled on Windows because people were afraid that this config could be mistakenly + // created by some installer and screw up their games. Until any kind of solution is found. + String user_global_cfg_file; #if ! AGS_PLATFORM_OS_WINDOWS - // Read user global configuration file - user_global_cfg_file = find_user_global_cfg_file(); - if (Path::ComparePaths(user_global_cfg_file, def_cfg_file) != 0) - IniUtil::Read(user_global_cfg_file, cfg); + // Read user global configuration file + user_global_cfg_file = find_user_global_cfg_file(); + if (Path::ComparePaths(user_global_cfg_file, def_cfg_file) != 0) + IniUtil::Read(user_global_cfg_file, cfg); #endif - // Read user configuration file - String user_cfg_file = find_user_cfg_file(); - if (Path::ComparePaths(user_cfg_file, def_cfg_file) != 0 && - Path::ComparePaths(user_cfg_file, user_global_cfg_file) != 0) - IniUtil::Read(user_cfg_file, cfg); - - // Apply overriding options from mobile port settings - // TODO: normally, those should be instead stored in the same config file in a uniform way - // NOTE: the variable is historically called "ignore" but we use it in "override" meaning here - if (psp_ignore_acsetup_cfg_file) - override_config_ext(cfg); + // Read user configuration file + String user_cfg_file = find_user_cfg_file(); + if (Path::ComparePaths(user_cfg_file, def_cfg_file) != 0 && + Path::ComparePaths(user_cfg_file, user_global_cfg_file) != 0) + IniUtil::Read(user_cfg_file, cfg); + + // Apply overriding options from mobile port settings + // TODO: normally, those should be instead stored in the same config file in a uniform way + // NOTE: the variable is historically called "ignore" but we use it in "override" meaning here + if (psp_ignore_acsetup_cfg_file) + override_config_ext(cfg); } // Gathers settings from all available sources into single ConfigTree -void engine_prepare_config(ConfigTree &cfg, const String &exe_path, const ConfigTree &startup_opts) -{ - Debug::Printf(kDbgMsg_Info, "Setting up game configuration"); - // Read configuration files - engine_read_config(exe_path, cfg); - // Merge startup options in - for (const auto §n : startup_opts) - for (const auto &opt : sectn.second) - cfg[sectn.first][opt.first] = opt.second; - - // Add "meta" config settings to let setup application(s) - // display correct properties to the user - INIwriteint(cfg, "misc", "defaultres", game.GetResolutionType()); - INIwriteint(cfg, "misc", "letterbox", game.options[OPT_LETTERBOX]); - INIwriteint(cfg, "misc", "game_width", game.GetDefaultRes().Width); - INIwriteint(cfg, "misc", "game_height", game.GetDefaultRes().Height); - INIwriteint(cfg, "misc", "gamecolordepth", game.color_depth * 8); - if (game.options[OPT_RENDERATSCREENRES] != kRenderAtScreenRes_UserDefined) - { - // force enabled/disabled - INIwriteint(cfg, "graphics", "render_at_screenres", game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_Enabled); - INIwriteint(cfg, "disabled", "render_at_screenres", 1); - } +void engine_prepare_config(ConfigTree &cfg, const String &exe_path, const ConfigTree &startup_opts) { + Debug::Printf(kDbgMsg_Info, "Setting up game configuration"); + // Read configuration files + engine_read_config(exe_path, cfg); + // Merge startup options in + for (const auto §n : startup_opts) + for (const auto &opt : sectn.second) + cfg[sectn.first][opt.first] = opt.second; + + // Add "meta" config settings to let setup application(s) + // display correct properties to the user + INIwriteint(cfg, "misc", "defaultres", game.GetResolutionType()); + INIwriteint(cfg, "misc", "letterbox", game.options[OPT_LETTERBOX]); + INIwriteint(cfg, "misc", "game_width", game.GetDefaultRes().Width); + INIwriteint(cfg, "misc", "game_height", game.GetDefaultRes().Height); + INIwriteint(cfg, "misc", "gamecolordepth", game.color_depth * 8); + if (game.options[OPT_RENDERATSCREENRES] != kRenderAtScreenRes_UserDefined) { + // force enabled/disabled + INIwriteint(cfg, "graphics", "render_at_screenres", game.options[OPT_RENDERATSCREENRES] == kRenderAtScreenRes_Enabled); + INIwriteint(cfg, "disabled", "render_at_screenres", 1); + } } // Applies configuration to the running game -void engine_set_config(const ConfigTree cfg) -{ - config_defaults(); - apply_config(cfg); - post_config(); +void engine_set_config(const ConfigTree cfg) { + config_defaults(); + apply_config(cfg); + post_config(); } // // --tell command support: printing engine/game info by request // extern std::set tellInfoKeys; -static bool print_info_needs_game(const std::set &keys) -{ - return keys.count("all") > 0 || keys.count("config") > 0 || keys.count("configpath") > 0 || - keys.count("data") > 0; +static bool print_info_needs_game(const std::set &keys) { + return keys.count("all") > 0 || keys.count("config") > 0 || keys.count("configpath") > 0 || + keys.count("data") > 0; } -static void engine_print_info(const std::set &keys, const String &exe_path, ConfigTree *user_cfg) -{ - const bool all = keys.count("all") > 0; - ConfigTree data; - if (all || keys.count("engine") > 0) - { - data["engine"]["name"] = get_engine_name(); - data["engine"]["version"] = get_engine_version(); - } - if (all || keys.count("graphicdriver") > 0) - { - StringV drv; - AGS::Engine::GetGfxDriverFactoryNames(drv); - for (size_t i = 0; i < drv.size(); ++i) - { - data["graphicdriver"][String::FromFormat("%u", i)] = drv[i]; - } - } - if (all || keys.count("configpath") > 0) - { - String def_cfg_file = find_default_cfg_file(exe_path); - String gl_cfg_file = find_user_global_cfg_file(); - String user_cfg_file = find_user_cfg_file(); - data["config-path"]["default"] = def_cfg_file; - data["config-path"]["global"] = gl_cfg_file; - data["config-path"]["user"] = user_cfg_file; - } - if ((all || keys.count("config") > 0) && user_cfg) - { - for (const auto §n : *user_cfg) - { - String cfg_sectn = String::FromFormat("config@%s", sectn.first.GetCStr()); - for (const auto &opt : sectn.second) - data[cfg_sectn][opt.first] = opt.second; - } - } - if (all || keys.count("data") > 0) - { - data["data"]["gamename"] = game.gamename; - data["data"]["version"] = String::FromFormat("%d", loaded_game_file_version); - data["data"]["compiledwith"] = game.compiled_with; - data["data"]["basepack"] = usetup.main_data_filepath; - } - String full; - IniUtil::WriteToString(full, data); - platform->WriteStdOut("%s", full.GetCStr()); +static void engine_print_info(const std::set &keys, const String &exe_path, ConfigTree *user_cfg) { + const bool all = keys.count("all") > 0; + ConfigTree data; + if (all || keys.count("engine") > 0) { + data["engine"]["name"] = get_engine_name(); + data["engine"]["version"] = get_engine_version(); + } + if (all || keys.count("graphicdriver") > 0) { + StringV drv; + AGS::Engine::GetGfxDriverFactoryNames(drv); + for (size_t i = 0; i < drv.size(); ++i) { + data["graphicdriver"][String::FromFormat("%u", i)] = drv[i]; + } + } + if (all || keys.count("configpath") > 0) { + String def_cfg_file = find_default_cfg_file(exe_path); + String gl_cfg_file = find_user_global_cfg_file(); + String user_cfg_file = find_user_cfg_file(); + data["config-path"]["default"] = def_cfg_file; + data["config-path"]["global"] = gl_cfg_file; + data["config-path"]["user"] = user_cfg_file; + } + if ((all || keys.count("config") > 0) && user_cfg) { + for (const auto §n : *user_cfg) { + String cfg_sectn = String::FromFormat("config@%s", sectn.first.GetCStr()); + for (const auto &opt : sectn.second) + data[cfg_sectn][opt.first] = opt.second; + } + } + if (all || keys.count("data") > 0) { + data["data"]["gamename"] = game.gamename; + data["data"]["version"] = String::FromFormat("%d", loaded_game_file_version); + data["data"]["compiledwith"] = game.compiled_with; + data["data"]["basepack"] = usetup.main_data_filepath; + } + String full; + IniUtil::WriteToString(full, data); + platform->WriteStdOut("%s", full.GetCStr()); } // Custom resource search callback for Allegro's system driver. // It helps us direct Allegro to our game data location, because it won't know. -static int al_find_resource(char *dest, const char* resource, int dest_size) -{ - String path = Path::ConcatPaths(get_install_dir(), resource); - if (File::TestReadFile(path)) - { - snprintf(dest, dest_size, "%s", path.GetCStr()); - return 0; - } - return -1; +static int al_find_resource(char *dest, const char *resource, int dest_size) { + String path = Path::ConcatPaths(get_install_dir(), resource); + if (File::TestReadFile(path)) { + snprintf(dest, dest_size, "%s", path.GetCStr()); + return 0; + } + return -1; } // TODO: this function is still a big mess, engine/system-related initialization // is mixed with game-related data adjustments. Divide it in parts, move game // data init into either InitGameState() or other game method as appropriate. -int initialize_engine(const ConfigTree &startup_opts) -{ - if (engine_pre_init_callback) { - engine_pre_init_callback(); - } +int initialize_engine(const ConfigTree &startup_opts) { + if (engine_pre_init_callback) { + engine_pre_init_callback(); + } + + //----------------------------------------------------- + // Install backend + if (!engine_init_allegro()) + return EXIT_ERROR; - //----------------------------------------------------- - // Install backend - if (!engine_init_allegro()) - return EXIT_ERROR; + //----------------------------------------------------- + // Locate game data and assemble game config + const String exe_path = global_argv[0]; + if (justTellInfo && !print_info_needs_game(tellInfoKeys)) { + engine_print_info(tellInfoKeys, exe_path, nullptr); + return EXIT_NORMAL; + } - //----------------------------------------------------- - // Locate game data and assemble game config - const String exe_path = global_argv[0]; - if (justTellInfo && !print_info_needs_game(tellInfoKeys)) - { - engine_print_info(tellInfoKeys, exe_path, nullptr); - return EXIT_NORMAL; - } + if (!engine_init_gamedata(exe_path)) + return EXIT_ERROR; + ConfigTree cfg; + engine_prepare_config(cfg, exe_path, startup_opts); + if (justTellInfo) { + engine_print_info(tellInfoKeys, exe_path, &cfg); + return EXIT_NORMAL; + } + // Test if need to run built-in setup program (where available) + if (justRunSetup) { + int res; + if (!engine_run_setup(exe_path, cfg, res)) + return res; + } + // Set up game options from user config + engine_set_config(cfg); + engine_setup_allegro(); + engine_force_window(); - if (!engine_init_gamedata(exe_path)) - return EXIT_ERROR; - ConfigTree cfg; - engine_prepare_config(cfg, exe_path, startup_opts); - if (justTellInfo) - { - engine_print_info(tellInfoKeys, exe_path, &cfg); - return EXIT_NORMAL; - } - // Test if need to run built-in setup program (where available) - if (justRunSetup) - { - int res; - if (!engine_run_setup(exe_path, cfg, res)) - return res; - } - // Set up game options from user config - engine_set_config(cfg); - engine_setup_allegro(); - engine_force_window(); + our_eip = -190; - our_eip = -190; + //----------------------------------------------------- + // Init data paths and other directories, locate general data files + engine_init_directories(); - //----------------------------------------------------- - // Init data paths and other directories, locate general data files - engine_init_directories(); + our_eip = -191; - our_eip = -191; + engine_locate_speech_pak(); - engine_locate_speech_pak(); + our_eip = -192; - our_eip = -192; + engine_locate_audio_pak(); - engine_locate_audio_pak(); + our_eip = -193; - our_eip = -193; + // Assign custom find resource callback for limited Allegro operations + system_driver->find_resource = al_find_resource; - // Assign custom find resource callback for limited Allegro operations - system_driver->find_resource = al_find_resource; + //----------------------------------------------------- + // Begin setting up systems + engine_setup_window(); - //----------------------------------------------------- - // Begin setting up systems - engine_setup_window(); + our_eip = -194; - our_eip = -194; + engine_init_fonts(); - engine_init_fonts(); + our_eip = -195; - our_eip = -195; + engine_init_keyboard(); - engine_init_keyboard(); + our_eip = -196; - our_eip = -196; + engine_init_mouse(); - engine_init_mouse(); + our_eip = -197; - our_eip = -197; + engine_init_timer(); - engine_init_timer(); + our_eip = -198; - our_eip = -198; + engine_init_audio(); - engine_init_audio(); + our_eip = -199; - our_eip = -199; + engine_init_debug(); - engine_init_debug(); + our_eip = -10; - our_eip = -10; + engine_init_exit_handler(); - engine_init_exit_handler(); + engine_init_rand(); - engine_init_rand(); + engine_init_pathfinder(); - engine_init_pathfinder(); + set_game_speed(40); - set_game_speed(40); + our_eip = -20; + our_eip = -19; - our_eip=-20; - our_eip=-19; + int res = engine_load_game_data(); + if (res != 0) + return res; - int res = engine_load_game_data(); - if (res != 0) - return res; - - res = engine_check_register_game(); - if (res != 0) - return res; + res = engine_check_register_game(); + if (res != 0) + return res; - engine_init_title(); + engine_init_title(); - our_eip = -189; + our_eip = -189; - res = engine_check_disk_space(); - if (res != 0) - return res; + res = engine_check_disk_space(); + if (res != 0) + return res; - // Make sure that at least one font was loaded in the process of loading - // the game data. - // TODO: Fold this check into engine_load_game_data() - res = engine_check_font_was_loaded(); - if (res != 0) - return res; + // Make sure that at least one font was loaded in the process of loading + // the game data. + // TODO: Fold this check into engine_load_game_data() + res = engine_check_font_was_loaded(); + if (res != 0) + return res; - our_eip = -179; + our_eip = -179; - engine_init_modxm_player(); + engine_init_modxm_player(); - engine_init_resolution_settings(game.GetGameRes()); + engine_init_resolution_settings(game.GetGameRes()); - // Attempt to initialize graphics mode - if (!engine_try_set_gfxmode_any(usetup.Screen)) - return EXIT_ERROR; + // Attempt to initialize graphics mode + if (!engine_try_set_gfxmode_any(usetup.Screen)) + return EXIT_ERROR; - SetMultitasking(0); + SetMultitasking(0); - // [ER] 2014-03-13 - // Hide the system cursor via allegro - show_os_cursor(MOUSE_CURSOR_NONE); + // [ER] 2014-03-13 + // Hide the system cursor via allegro + show_os_cursor(MOUSE_CURSOR_NONE); - show_preload(); + show_preload(); - res = engine_init_sprites(); - if (res != 0) - return res; + res = engine_init_sprites(); + if (res != 0) + return res; - engine_init_game_settings(); + engine_init_game_settings(); - engine_prepare_to_start_game(); + engine_prepare_to_start_game(); allegro_bitmap_test_init(); - initialize_start_and_play_game(override_start_room, loadSaveGameOnStartup); + initialize_start_and_play_game(override_start_room, loadSaveGameOnStartup); - quit("|bye!"); - return EXIT_NORMAL; + quit("|bye!"); + return EXIT_NORMAL; } -bool engine_try_set_gfxmode_any(const ScreenSetup &setup) -{ - engine_shutdown_gfxmode(); +bool engine_try_set_gfxmode_any(const ScreenSetup &setup) { + engine_shutdown_gfxmode(); - const Size init_desktop = get_desktop_size(); - if (!graphics_mode_init_any(game.GetGameRes(), setup, ColorDepthOption(game.GetColorDepth()))) - return false; + const Size init_desktop = get_desktop_size(); + if (!graphics_mode_init_any(game.GetGameRes(), setup, ColorDepthOption(game.GetColorDepth()))) + return false; - engine_post_gfxmode_setup(init_desktop); - return true; + engine_post_gfxmode_setup(init_desktop); + return true; } -bool engine_try_switch_windowed_gfxmode() -{ - if (!gfxDriver || !gfxDriver->IsModeSet()) - return false; - - // Keep previous mode in case we need to revert back - DisplayMode old_dm = gfxDriver->GetDisplayMode(); - GameFrameSetup old_frame = graphics_mode_get_render_frame(); - - // Release engine resources that depend on display mode - engine_pre_gfxmode_release(); - - Size init_desktop = get_desktop_size(); - bool switch_to_windowed = !old_dm.Windowed; - ActiveDisplaySetting setting = graphics_mode_get_last_setting(switch_to_windowed); - DisplayMode last_opposite_mode = setting.Dm; - GameFrameSetup use_frame_setup = setting.FrameSetup; - - // If there are saved parameters for given mode (fullscreen/windowed) - // then use them, if there are not, get default setup for the new mode. - bool res; - if (last_opposite_mode.IsValid()) - { - res = graphics_mode_set_dm(last_opposite_mode); - } - else - { - // we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults() - DisplayModeSetup dm_setup = usetup.Screen.DisplayMode; - dm_setup.Windowed = !old_dm.Windowed; - graphics_mode_get_defaults(dm_setup.Windowed, dm_setup.ScreenSize, use_frame_setup); - res = graphics_mode_set_dm_any(game.GetGameRes(), dm_setup, old_dm.ColorDepth, use_frame_setup); - } - - // Apply corresponding frame render method - if (res) - res = graphics_mode_set_render_frame(use_frame_setup); - - if (!res) - { - // If failed, try switching back to previous gfx mode - res = graphics_mode_set_dm(old_dm) && - graphics_mode_set_render_frame(old_frame); - } - - if (res) - { - // If succeeded (with any case), update engine objects that rely on - // active display mode. - if (gfxDriver->GetDisplayMode().Windowed) - init_desktop = get_desktop_size(); - engine_post_gfxmode_setup(init_desktop); - } - ags_clear_input_buffer(); - return res; +bool engine_try_switch_windowed_gfxmode() { + if (!gfxDriver || !gfxDriver->IsModeSet()) + return false; + + // Keep previous mode in case we need to revert back + DisplayMode old_dm = gfxDriver->GetDisplayMode(); + GameFrameSetup old_frame = graphics_mode_get_render_frame(); + + // Release engine resources that depend on display mode + engine_pre_gfxmode_release(); + + Size init_desktop = get_desktop_size(); + bool switch_to_windowed = !old_dm.Windowed; + ActiveDisplaySetting setting = graphics_mode_get_last_setting(switch_to_windowed); + DisplayMode last_opposite_mode = setting.Dm; + GameFrameSetup use_frame_setup = setting.FrameSetup; + + // If there are saved parameters for given mode (fullscreen/windowed) + // then use them, if there are not, get default setup for the new mode. + bool res; + if (last_opposite_mode.IsValid()) { + res = graphics_mode_set_dm(last_opposite_mode); + } else { + // we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults() + DisplayModeSetup dm_setup = usetup.Screen.DisplayMode; + dm_setup.Windowed = !old_dm.Windowed; + graphics_mode_get_defaults(dm_setup.Windowed, dm_setup.ScreenSize, use_frame_setup); + res = graphics_mode_set_dm_any(game.GetGameRes(), dm_setup, old_dm.ColorDepth, use_frame_setup); + } + + // Apply corresponding frame render method + if (res) + res = graphics_mode_set_render_frame(use_frame_setup); + + if (!res) { + // If failed, try switching back to previous gfx mode + res = graphics_mode_set_dm(old_dm) && + graphics_mode_set_render_frame(old_frame); + } + + if (res) { + // If succeeded (with any case), update engine objects that rely on + // active display mode. + if (gfxDriver->GetDisplayMode().Windowed) + init_desktop = get_desktop_size(); + engine_post_gfxmode_setup(init_desktop); + } + ags_clear_input_buffer(); + return res; } -void engine_shutdown_gfxmode() -{ - if (!gfxDriver) - return; +void engine_shutdown_gfxmode() { + if (!gfxDriver) + return; - engine_pre_gfxsystem_shutdown(); - graphics_mode_shutdown(); + engine_pre_gfxsystem_shutdown(); + graphics_mode_shutdown(); } -const char *get_engine_name() -{ - return "Adventure Game Studio run-time engine"; +const char *get_engine_name() { + return "Adventure Game Studio run-time engine"; } const char *get_engine_version() { - return EngineVersion.LongString.GetCStr(); + return EngineVersion.LongString.GetCStr(); } void engine_set_pre_init_callback(t_engine_pre_init_callback callback) { - engine_pre_init_callback = callback; + engine_pre_init_callback = callback; } diff --git a/engines/ags/engine/main/engine.h b/engines/ags/engine/main/engine.h index ef3e96796e0e..030d48c09e22 100644 --- a/engines/ags/engine/main/engine.h +++ b/engines/ags/engine/main/engine.h @@ -44,18 +44,16 @@ void engine_shutdown_gfxmode(); using AGS::Common::String; // Defines a package file location -struct PackLocation -{ - String Name; // filename, for the reference or to use as an ID - String Path; // full path +struct PackLocation { + String Name; // filename, for the reference or to use as an ID + String Path; // full path }; // Game resource paths -struct ResourcePaths -{ - String DataDir; // path to the data directory - PackLocation GamePak; // main game package - PackLocation AudioPak; // audio package - PackLocation SpeechPak; // voice-over package +struct ResourcePaths { + String DataDir; // path to the data directory + PackLocation GamePak; // main game package + PackLocation AudioPak; // audio package + PackLocation SpeechPak; // voice-over package }; extern ResourcePaths ResPaths; diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp index ef4f7c1887ab..f29f5bb39965 100644 --- a/engines/ags/engine/main/engine_setup.cpp +++ b/engines/ags/engine/main/engine_setup.cpp @@ -56,320 +56,287 @@ int convert_16bit_bgr = 0; // Convert guis position and size to proper game resolution. // Necessary for pre 3.1.0 games only to sync with modern engine. -void convert_gui_to_game_resolution(GameDataVersion filever) -{ - if (filever > kGameVersion_310) - return; - - const int mul = game.GetDataUpscaleMult(); - for (int i = 0; i < game.numcursors; ++i) - { - game.mcurs[i].hotx *= mul; - game.mcurs[i].hoty *= mul; - } - - for (int i = 0; i < game.numinvitems; ++i) - { - game.invinfo[i].hotx *= mul; - game.invinfo[i].hoty *= mul; - } - - for (int i = 0; i < game.numgui; ++i) - { - GUIMain*cgp = &guis[i]; - cgp->X *= mul; - cgp->Y *= mul; - if (cgp->Width < 1) - cgp->Width = 1; - if (cgp->Height < 1) - cgp->Height = 1; - // This is probably a way to fix GUIs meant to be covering whole screen - if (cgp->Width == game.GetDataRes().Width - 1) - cgp->Width = game.GetDataRes().Width; - - cgp->Width *= mul; - cgp->Height *= mul; - - cgp->PopupAtMouseY *= mul; - - for (int j = 0; j < cgp->GetControlCount(); ++j) - { - GUIObject *guio = cgp->GetControl(j); - guio->X *= mul; - guio->Y *= mul; - guio->Width *= mul; - guio->Height *= mul; - guio->IsActivated = false; - guio->OnResized(); - } - } +void convert_gui_to_game_resolution(GameDataVersion filever) { + if (filever > kGameVersion_310) + return; + + const int mul = game.GetDataUpscaleMult(); + for (int i = 0; i < game.numcursors; ++i) { + game.mcurs[i].hotx *= mul; + game.mcurs[i].hoty *= mul; + } + + for (int i = 0; i < game.numinvitems; ++i) { + game.invinfo[i].hotx *= mul; + game.invinfo[i].hoty *= mul; + } + + for (int i = 0; i < game.numgui; ++i) { + GUIMain *cgp = &guis[i]; + cgp->X *= mul; + cgp->Y *= mul; + if (cgp->Width < 1) + cgp->Width = 1; + if (cgp->Height < 1) + cgp->Height = 1; + // This is probably a way to fix GUIs meant to be covering whole screen + if (cgp->Width == game.GetDataRes().Width - 1) + cgp->Width = game.GetDataRes().Width; + + cgp->Width *= mul; + cgp->Height *= mul; + + cgp->PopupAtMouseY *= mul; + + for (int j = 0; j < cgp->GetControlCount(); ++j) { + GUIObject *guio = cgp->GetControl(j); + guio->X *= mul; + guio->Y *= mul; + guio->Width *= mul; + guio->Height *= mul; + guio->IsActivated = false; + guio->OnResized(); + } + } } // Convert certain coordinates to data resolution (only if it's different from game resolution). // Necessary for 3.1.0 and above games with legacy "low-res coordinates" setting. -void convert_objects_to_data_resolution(GameDataVersion filever) -{ - if (filever < kGameVersion_310 || game.GetDataUpscaleMult() == 1) - return; - - const int mul = game.GetDataUpscaleMult(); - for (int i = 0; i < game.numcharacters; ++i) - { - game.chars[i].x /= mul; - game.chars[i].y /= mul; - } - - for (int i = 0; i < numguiinv; ++i) - { - guiinv[i].ItemWidth /= mul; - guiinv[i].ItemHeight /= mul; - guiinv[i].OnResized(); - } +void convert_objects_to_data_resolution(GameDataVersion filever) { + if (filever < kGameVersion_310 || game.GetDataUpscaleMult() == 1) + return; + + const int mul = game.GetDataUpscaleMult(); + for (int i = 0; i < game.numcharacters; ++i) { + game.chars[i].x /= mul; + game.chars[i].y /= mul; + } + + for (int i = 0; i < numguiinv; ++i) { + guiinv[i].ItemWidth /= mul; + guiinv[i].ItemHeight /= mul; + guiinv[i].OnResized(); + } } -void engine_setup_system_gamesize() -{ - scsystem.width = game.GetGameRes().Width; - scsystem.height = game.GetGameRes().Height; - scsystem.viewport_width = game_to_data_coord(play.GetMainViewport().GetWidth()); - scsystem.viewport_height = game_to_data_coord(play.GetMainViewport().GetHeight()); +void engine_setup_system_gamesize() { + scsystem.width = game.GetGameRes().Width; + scsystem.height = game.GetGameRes().Height; + scsystem.viewport_width = game_to_data_coord(play.GetMainViewport().GetWidth()); + scsystem.viewport_height = game_to_data_coord(play.GetMainViewport().GetHeight()); } -void engine_init_resolution_settings(const Size game_size) -{ - Debug::Printf("Initializing resolution settings"); - usetup.textheight = getfontheight_outlined(0) + 1; +void engine_init_resolution_settings(const Size game_size) { + Debug::Printf("Initializing resolution settings"); + usetup.textheight = getfontheight_outlined(0) + 1; - Debug::Printf(kDbgMsg_Info, "Game native resolution: %d x %d (%d bit)%s", game_size.Width, game_size.Height, game.color_depth * 8, - game.IsLegacyLetterbox() ? " letterbox-by-design" : ""); + Debug::Printf(kDbgMsg_Info, "Game native resolution: %d x %d (%d bit)%s", game_size.Width, game_size.Height, game.color_depth * 8, + game.IsLegacyLetterbox() ? " letterbox-by-design" : ""); - convert_gui_to_game_resolution(loaded_game_file_version); - convert_objects_to_data_resolution(loaded_game_file_version); + convert_gui_to_game_resolution(loaded_game_file_version); + convert_objects_to_data_resolution(loaded_game_file_version); - Rect viewport = RectWH(game_size); - play.SetMainViewport(viewport); - play.SetUIViewport(viewport); - engine_setup_system_gamesize(); + Rect viewport = RectWH(game_size); + play.SetMainViewport(viewport); + play.SetUIViewport(viewport); + engine_setup_system_gamesize(); } // Setup gfx driver callbacks and options -void engine_post_gfxmode_driver_setup() -{ - gfxDriver->SetCallbackForPolling(update_polled_stuff_if_runtime); - gfxDriver->SetCallbackToDrawScreen(draw_game_screen_callback, construct_engine_overlay); - gfxDriver->SetCallbackForNullSprite(GfxDriverNullSpriteCallback); +void engine_post_gfxmode_driver_setup() { + gfxDriver->SetCallbackForPolling(update_polled_stuff_if_runtime); + gfxDriver->SetCallbackToDrawScreen(draw_game_screen_callback, construct_engine_overlay); + gfxDriver->SetCallbackForNullSprite(GfxDriverNullSpriteCallback); } // Reset gfx driver callbacks -void engine_pre_gfxmode_driver_cleanup() -{ - gfxDriver->SetCallbackForPolling(nullptr); - gfxDriver->SetCallbackToDrawScreen(nullptr, nullptr); - gfxDriver->SetCallbackForNullSprite(nullptr); - gfxDriver->SetMemoryBackBuffer(nullptr); +void engine_pre_gfxmode_driver_cleanup() { + gfxDriver->SetCallbackForPolling(nullptr); + gfxDriver->SetCallbackToDrawScreen(nullptr, nullptr); + gfxDriver->SetCallbackForNullSprite(nullptr); + gfxDriver->SetMemoryBackBuffer(nullptr); } // Setup virtual screen -void engine_post_gfxmode_screen_setup(const DisplayMode &dm, bool recreate_bitmaps) -{ - if (recreate_bitmaps) - { - // TODO: find out if - // - we need to support this case at all; - // - if yes then which bitmaps need to be recreated (probably only video bitmaps and textures?) - } +void engine_post_gfxmode_screen_setup(const DisplayMode &dm, bool recreate_bitmaps) { + if (recreate_bitmaps) { + // TODO: find out if + // - we need to support this case at all; + // - if yes then which bitmaps need to be recreated (probably only video bitmaps and textures?) + } } -void engine_pre_gfxmode_screen_cleanup() -{ +void engine_pre_gfxmode_screen_cleanup() { } // Release virtual screen -void engine_pre_gfxsystem_screen_destroy() -{ +void engine_pre_gfxsystem_screen_destroy() { } // Setup color conversion parameters -void engine_setup_color_conversions(int coldepth) -{ - // default shifts for how we store the sprite data1 - _rgb_r_shift_32 = 16; - _rgb_g_shift_32 = 8; - _rgb_b_shift_32 = 0; - _rgb_r_shift_16 = 11; - _rgb_g_shift_16 = 5; - _rgb_b_shift_16 = 0; - _rgb_r_shift_15 = 10; - _rgb_g_shift_15 = 5; - _rgb_b_shift_15 = 0; - - // Most cards do 5-6-5 RGB, which is the format the files are saved in - // Some do 5-6-5 BGR, or 6-5-5 RGB, in which case convert the gfx - if ((coldepth == 16) && ((_rgb_b_shift_16 != 0) || (_rgb_r_shift_16 != 11))) - { - convert_16bit_bgr = 1; - if (_rgb_r_shift_16 == 10) { - // some very old graphics cards lie about being 16-bit when they - // are in fact 15-bit ... get around this - _places_r = 3; - _places_g = 3; - } - } - if (coldepth > 16) - { - // when we're using 32-bit colour, it converts hi-color images - // the wrong way round - so fix that +void engine_setup_color_conversions(int coldepth) { + // default shifts for how we store the sprite data1 + _rgb_r_shift_32 = 16; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 0; + _rgb_r_shift_16 = 11; + _rgb_g_shift_16 = 5; + _rgb_b_shift_16 = 0; + _rgb_r_shift_15 = 10; + _rgb_g_shift_15 = 5; + _rgb_b_shift_15 = 0; + + // Most cards do 5-6-5 RGB, which is the format the files are saved in + // Some do 5-6-5 BGR, or 6-5-5 RGB, in which case convert the gfx + if ((coldepth == 16) && ((_rgb_b_shift_16 != 0) || (_rgb_r_shift_16 != 11))) { + convert_16bit_bgr = 1; + if (_rgb_r_shift_16 == 10) { + // some very old graphics cards lie about being 16-bit when they + // are in fact 15-bit ... get around this + _places_r = 3; + _places_g = 3; + } + } + if (coldepth > 16) { + // when we're using 32-bit colour, it converts hi-color images + // the wrong way round - so fix that #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID - _rgb_b_shift_16 = 0; - _rgb_g_shift_16 = 5; - _rgb_r_shift_16 = 11; + _rgb_b_shift_16 = 0; + _rgb_g_shift_16 = 5; + _rgb_r_shift_16 = 11; - _rgb_b_shift_15 = 0; - _rgb_g_shift_15 = 5; - _rgb_r_shift_15 = 10; + _rgb_b_shift_15 = 0; + _rgb_g_shift_15 = 5; + _rgb_r_shift_15 = 10; - _rgb_r_shift_32 = 0; - _rgb_g_shift_32 = 8; - _rgb_b_shift_32 = 16; + _rgb_r_shift_32 = 0; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 16; #else - _rgb_r_shift_16 = 11; - _rgb_g_shift_16 = 5; - _rgb_b_shift_16 = 0; + _rgb_r_shift_16 = 11; + _rgb_g_shift_16 = 5; + _rgb_b_shift_16 = 0; #endif - } - else if (coldepth == 16) - { - // ensure that any 32-bit graphics displayed are converted - // properly to the current depth - _rgb_r_shift_32 = 16; - _rgb_g_shift_32 = 8; - _rgb_b_shift_32 = 0; - } - else if (coldepth < 16) - { - // ensure that any 32-bit graphics displayed are converted - // properly to the current depth + } else if (coldepth == 16) { + // ensure that any 32-bit graphics displayed are converted + // properly to the current depth + _rgb_r_shift_32 = 16; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 0; + } else if (coldepth < 16) { + // ensure that any 32-bit graphics displayed are converted + // properly to the current depth #if AGS_PLATFORM_OS_WINDOWS - _rgb_r_shift_32 = 16; - _rgb_g_shift_32 = 8; - _rgb_b_shift_32 = 0; + _rgb_r_shift_32 = 16; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 0; #else - _rgb_r_shift_32 = 0; - _rgb_g_shift_32 = 8; - _rgb_b_shift_32 = 16; + _rgb_r_shift_32 = 0; + _rgb_g_shift_32 = 8; + _rgb_b_shift_32 = 16; - _rgb_b_shift_15 = 0; - _rgb_g_shift_15 = 5; - _rgb_r_shift_15 = 10; + _rgb_b_shift_15 = 0; + _rgb_g_shift_15 = 5; + _rgb_r_shift_15 = 10; #endif - } + } - set_color_conversion(COLORCONV_MOST | COLORCONV_EXPAND_256); + set_color_conversion(COLORCONV_MOST | COLORCONV_EXPAND_256); } // Setup drawing modes and color conversions; // they depend primarily on gfx driver capabilities and new color depth -void engine_post_gfxmode_draw_setup(const DisplayMode &dm) -{ - engine_setup_color_conversions(dm.ColorDepth); - init_draw_method(); +void engine_post_gfxmode_draw_setup(const DisplayMode &dm) { + engine_setup_color_conversions(dm.ColorDepth); + init_draw_method(); } // Cleanup auxiliary drawing objects -void engine_pre_gfxmode_draw_cleanup() -{ - dispose_draw_method(); +void engine_pre_gfxmode_draw_cleanup() { + dispose_draw_method(); } // Setup mouse control mode and graphic area -void engine_post_gfxmode_mouse_setup(const DisplayMode &dm, const Size &init_desktop) -{ - // Assign mouse control parameters. - // - // NOTE that we setup speed and other related properties regardless of - // whether mouse control was requested because it may be enabled later. - Mouse::SetSpeedUnit(1.f); - if (usetup.mouse_speed_def == kMouseSpeed_CurrentDisplay) - { - Size cur_desktop; - if (get_desktop_resolution(&cur_desktop.Width, &cur_desktop.Height) == 0) - Mouse::SetSpeedUnit(Math::Max((float)cur_desktop.Width / (float)init_desktop.Width, - (float)cur_desktop.Height / (float)init_desktop.Height)); - } - - Mouse_EnableControl(usetup.mouse_ctrl_enabled); - Debug::Printf(kDbgMsg_Info, "Mouse control: %s, base: %f, speed: %f", Mouse::IsControlEnabled() ? "on" : "off", - Mouse::GetSpeedUnit(), Mouse::GetSpeed()); - - on_coordinates_scaling_changed(); - - // If auto lock option is set, lock mouse to the game window - if (usetup.mouse_auto_lock && scsystem.windowed != 0) - Mouse::TryLockToWindow(); +void engine_post_gfxmode_mouse_setup(const DisplayMode &dm, const Size &init_desktop) { + // Assign mouse control parameters. + // + // NOTE that we setup speed and other related properties regardless of + // whether mouse control was requested because it may be enabled later. + Mouse::SetSpeedUnit(1.f); + if (usetup.mouse_speed_def == kMouseSpeed_CurrentDisplay) { + Size cur_desktop; + if (get_desktop_resolution(&cur_desktop.Width, &cur_desktop.Height) == 0) + Mouse::SetSpeedUnit(Math::Max((float)cur_desktop.Width / (float)init_desktop.Width, + (float)cur_desktop.Height / (float)init_desktop.Height)); + } + + Mouse_EnableControl(usetup.mouse_ctrl_enabled); + Debug::Printf(kDbgMsg_Info, "Mouse control: %s, base: %f, speed: %f", Mouse::IsControlEnabled() ? "on" : "off", + Mouse::GetSpeedUnit(), Mouse::GetSpeed()); + + on_coordinates_scaling_changed(); + + // If auto lock option is set, lock mouse to the game window + if (usetup.mouse_auto_lock && scsystem.windowed != 0) + Mouse::TryLockToWindow(); } // Reset mouse controls before changing gfx mode -void engine_pre_gfxmode_mouse_cleanup() -{ - // Always disable mouse control and unlock mouse when releasing down gfx mode - Mouse::DisableControl(); - Mouse::UnlockFromWindow(); +void engine_pre_gfxmode_mouse_cleanup() { + // Always disable mouse control and unlock mouse when releasing down gfx mode + Mouse::DisableControl(); + Mouse::UnlockFromWindow(); } // Fill in scsystem struct with display mode parameters -void engine_setup_scsystem_screen(const DisplayMode &dm) -{ - scsystem.coldepth = dm.ColorDepth; - scsystem.windowed = dm.Windowed; - scsystem.vsync = dm.Vsync; +void engine_setup_scsystem_screen(const DisplayMode &dm) { + scsystem.coldepth = dm.ColorDepth; + scsystem.windowed = dm.Windowed; + scsystem.vsync = dm.Vsync; } -void engine_post_gfxmode_setup(const Size &init_desktop) -{ - DisplayMode dm = gfxDriver->GetDisplayMode(); - // If color depth has changed (or graphics mode was inited for the - // very first time), we also need to recreate bitmaps - bool has_driver_changed = scsystem.coldepth != dm.ColorDepth; - - engine_setup_scsystem_screen(dm); - engine_post_gfxmode_driver_setup(); - engine_post_gfxmode_screen_setup(dm, has_driver_changed); - if (has_driver_changed) - engine_post_gfxmode_draw_setup(dm); - engine_post_gfxmode_mouse_setup(dm, init_desktop); - - // TODO: the only reason this call was put here is that it requires - // "windowed" flag to be specified. Find out whether this function - // has anything to do with graphics mode at all. It is quite possible - // that we may split it into two functions, or remove parameter. - platform->PostAllegroInit(scsystem.windowed != 0); - - video_on_gfxmode_changed(); - invalidate_screen(); +void engine_post_gfxmode_setup(const Size &init_desktop) { + DisplayMode dm = gfxDriver->GetDisplayMode(); + // If color depth has changed (or graphics mode was inited for the + // very first time), we also need to recreate bitmaps + bool has_driver_changed = scsystem.coldepth != dm.ColorDepth; + + engine_setup_scsystem_screen(dm); + engine_post_gfxmode_driver_setup(); + engine_post_gfxmode_screen_setup(dm, has_driver_changed); + if (has_driver_changed) + engine_post_gfxmode_draw_setup(dm); + engine_post_gfxmode_mouse_setup(dm, init_desktop); + + // TODO: the only reason this call was put here is that it requires + // "windowed" flag to be specified. Find out whether this function + // has anything to do with graphics mode at all. It is quite possible + // that we may split it into two functions, or remove parameter. + platform->PostAllegroInit(scsystem.windowed != 0); + + video_on_gfxmode_changed(); + invalidate_screen(); } -void engine_pre_gfxmode_release() -{ - engine_pre_gfxmode_mouse_cleanup(); - engine_pre_gfxmode_driver_cleanup(); - engine_pre_gfxmode_screen_cleanup(); +void engine_pre_gfxmode_release() { + engine_pre_gfxmode_mouse_cleanup(); + engine_pre_gfxmode_driver_cleanup(); + engine_pre_gfxmode_screen_cleanup(); } -void engine_pre_gfxsystem_shutdown() -{ - engine_pre_gfxmode_release(); - engine_pre_gfxmode_draw_cleanup(); - engine_pre_gfxsystem_screen_destroy(); +void engine_pre_gfxsystem_shutdown() { + engine_pre_gfxmode_release(); + engine_pre_gfxmode_draw_cleanup(); + engine_pre_gfxsystem_screen_destroy(); } -void on_coordinates_scaling_changed() -{ - // Reset mouse graphic area and bounds - Mouse::SetGraphicArea(); - // If mouse bounds do not have valid values yet, then limit cursor to viewport - if (play.mboundx1 == 0 && play.mboundy1 == 0 && play.mboundx2 == 0 && play.mboundy2 == 0) - Mouse::SetMoveLimit(play.GetMainViewport()); - else - Mouse::SetMoveLimit(Rect(play.mboundx1, play.mboundy1, play.mboundx2, play.mboundy2)); +void on_coordinates_scaling_changed() { + // Reset mouse graphic area and bounds + Mouse::SetGraphicArea(); + // If mouse bounds do not have valid values yet, then limit cursor to viewport + if (play.mboundx1 == 0 && play.mboundy1 == 0 && play.mboundx2 == 0 && play.mboundy2 == 0) + Mouse::SetMoveLimit(play.GetMainViewport()); + else + Mouse::SetMoveLimit(Rect(play.mboundx1, play.mboundy1, play.mboundx2, play.mboundy2)); } diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp index 4b38de3fd13b..e97e63491066 100644 --- a/engines/ags/engine/main/game_file.cpp +++ b/engines/ags/engine/main/game_file.cpp @@ -59,7 +59,7 @@ using namespace AGS::Engine; extern int ifacepopped; extern GameSetupStruct game; -extern ViewStruct*views; +extern ViewStruct *views; extern DialogTopic *dialog; extern AGSPlatformDriver *platform; @@ -67,103 +67,91 @@ extern int numScriptModules; // Test if engine supports extended capabilities required to run the game -bool test_game_caps(const std::set &caps, std::set &failed_caps) -{ - // Currently we support nothing special - failed_caps = caps; - return caps.size() == 0; +bool test_game_caps(const std::set &caps, std::set &failed_caps) { + // Currently we support nothing special + failed_caps = caps; + return caps.size() == 0; } // Forms a simple list of capability names -String get_caps_list(const std::set &caps) -{ - String caps_list; - for (std::set::const_iterator it = caps.begin(); it != caps.end(); ++it) - { - caps_list.Append("\n\t"); - caps_list.Append(*it); - } - return caps_list; +String get_caps_list(const std::set &caps) { + String caps_list; + for (std::set::const_iterator it = caps.begin(); it != caps.end(); ++it) { + caps_list.Append("\n\t"); + caps_list.Append(*it); + } + return caps_list; } // Called when the game file is opened for the first time (when preloading game data); // it logs information on data version and reports first found errors, if any. -HGameFileError game_file_first_open(MainGameSource &src) -{ - HGameFileError err = OpenMainGameFileFromDefaultAsset(src); - if (err || - err->Code() == kMGFErr_SignatureFailed || - err->Code() == kMGFErr_FormatVersionTooOld || - err->Code() == kMGFErr_FormatVersionNotSupported) - { - // Log data description for debugging - Debug::Printf(kDbgMsg_Info, "Opened game data file: %s", src.Filename.GetCStr()); - Debug::Printf(kDbgMsg_Info, "Game data version: %d", src.DataVersion); - Debug::Printf(kDbgMsg_Info, "Compiled with: %s", src.CompiledWith.GetCStr()); - if (src.Caps.size() > 0) - { - String caps_list = get_caps_list(src.Caps); - Debug::Printf(kDbgMsg_Info, "Requested engine caps: %s", caps_list.GetCStr()); - } - } - // Quit in case of error - if (!err) - return err; +HGameFileError game_file_first_open(MainGameSource &src) { + HGameFileError err = OpenMainGameFileFromDefaultAsset(src); + if (err || + err->Code() == kMGFErr_SignatureFailed || + err->Code() == kMGFErr_FormatVersionTooOld || + err->Code() == kMGFErr_FormatVersionNotSupported) { + // Log data description for debugging + Debug::Printf(kDbgMsg_Info, "Opened game data file: %s", src.Filename.GetCStr()); + Debug::Printf(kDbgMsg_Info, "Game data version: %d", src.DataVersion); + Debug::Printf(kDbgMsg_Info, "Compiled with: %s", src.CompiledWith.GetCStr()); + if (src.Caps.size() > 0) { + String caps_list = get_caps_list(src.Caps); + Debug::Printf(kDbgMsg_Info, "Requested engine caps: %s", caps_list.GetCStr()); + } + } + // Quit in case of error + if (!err) + return err; - // Test the extended caps - std::set failed_caps; - if (!test_game_caps(src.Caps, failed_caps)) - { - String caps_list = get_caps_list(failed_caps); - return new MainGameFileError(kMGFErr_CapsNotSupported, String::FromFormat("Missing engine caps: %s", caps_list.GetCStr())); - } - return HGameFileError::None(); + // Test the extended caps + std::set failed_caps; + if (!test_game_caps(src.Caps, failed_caps)) { + String caps_list = get_caps_list(failed_caps); + return new MainGameFileError(kMGFErr_CapsNotSupported, String::FromFormat("Missing engine caps: %s", caps_list.GetCStr())); + } + return HGameFileError::None(); } -void PreReadSaveFileInfo(Stream *in, GameDataVersion data_ver) -{ - AlignedStream align_s(in, Common::kAligned_Read); - game.ReadFromFile(&align_s); - // Discard game messages we do not need here - delete [] game.load_messages; - game.load_messages = nullptr; - game.read_savegame_info(in, data_ver); +void PreReadSaveFileInfo(Stream *in, GameDataVersion data_ver) { + AlignedStream align_s(in, Common::kAligned_Read); + game.ReadFromFile(&align_s); + // Discard game messages we do not need here + delete [] game.load_messages; + game.load_messages = nullptr; + game.read_savegame_info(in, data_ver); } -HError preload_game_data() -{ - MainGameSource src; - HGameFileError err = game_file_first_open(src); - if (!err) - return (HError)err; - // Read only the particular data we need for preliminary game analysis - PreReadSaveFileInfo(src.InputStream.get(), src.DataVersion); - game.compiled_with = src.CompiledWith; - FixupSaveDirectory(game); - return HError::None(); +HError preload_game_data() { + MainGameSource src; + HGameFileError err = game_file_first_open(src); + if (!err) + return (HError)err; + // Read only the particular data we need for preliminary game analysis + PreReadSaveFileInfo(src.InputStream.get(), src.DataVersion); + game.compiled_with = src.CompiledWith; + FixupSaveDirectory(game); + return HError::None(); } -HError load_game_file() -{ - MainGameSource src; - LoadedGameEntities ents(game, dialog, views); - HGameFileError load_err = OpenMainGameFileFromDefaultAsset(src); - if (load_err) - { - load_err = ReadGameData(ents, src.InputStream.get(), src.DataVersion); - if (load_err) - load_err = UpdateGameData(ents, src.DataVersion); - } - if (!load_err) - return (HError)load_err; - HGameInitError init_err = InitGameState(ents, src.DataVersion); - if (!init_err) - return (HError)init_err; - return HError::None(); +HError load_game_file() { + MainGameSource src; + LoadedGameEntities ents(game, dialog, views); + HGameFileError load_err = OpenMainGameFileFromDefaultAsset(src); + if (load_err) { + load_err = ReadGameData(ents, src.InputStream.get(), src.DataVersion); + if (load_err) + load_err = UpdateGameData(ents, src.DataVersion); + } + if (!load_err) + return (HError)load_err; + HGameInitError init_err = InitGameState(ents, src.DataVersion); + if (!init_err) + return (HError)init_err; + return HError::None(); } -void display_game_file_error(HError err) -{ - platform->DisplayAlert("Loading game failed with error:\n%s.\n\nThe game files may be incomplete, corrupt or from unsupported version of AGS.", - err->FullMessage().GetCStr()); +void display_game_file_error(HError err) { + platform->DisplayAlert("Loading game failed with error:\n%s.\n\nThe game files may be incomplete, corrupt or from unsupported version of AGS.", + err->FullMessage().GetCStr()); } diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 744680bbe3bd..589a6b78be13 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -74,26 +74,26 @@ extern int mouse_on_iface; // mouse cursor is over this interface extern int ifacepopped; extern int is_text_overlay; extern volatile char want_exit, abort_engine; -extern int proper_exit,our_eip; +extern int proper_exit, our_eip; extern int displayed_room, starting_room, in_new_room, new_room_was; extern GameSetupStruct game; extern RoomStruct thisroom; extern int game_paused; extern int getloctype_index; -extern int in_enters_screen,done_es_error; +extern int in_enters_screen, done_es_error; extern int in_leaves_screen; -extern int inside_script,in_graph_script; +extern int inside_script, in_graph_script; extern int no_blocking_functions; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern GameState play; -extern int mouse_ifacebut_xoffs,mouse_ifacebut_yoffs; +extern int mouse_ifacebut_xoffs, mouse_ifacebut_yoffs; extern int cur_mode; -extern RoomObject*objs; +extern RoomObject *objs; extern char noWalkBehindsAtAll; -extern RoomStatus*croom; +extern RoomStatus *croom; extern CharacterExtras *charextra; extern SpriteCache spriteset; -extern int cur_mode,cur_cursor; +extern int cur_mode, cur_cursor; // Checks if user interface should remain disabled for now static int ShouldStayInWaitMode(); @@ -112,177 +112,163 @@ static auto t1 = AGS_Clock::now(); // timer for FPS // ... 't1'... how very app // Following 3 parameters instruct the engine to run game loops until // certain condition is not fullfilled. -static int restrict_until=0; +static int restrict_until = 0; static int user_disabled_for = 0; static const void *user_disabled_data = nullptr; -unsigned int loopcounter=0; -static unsigned int lastcounter=0; - -static void ProperExit() -{ - want_exit = 0; - proper_exit = 1; - quit("||exit!"); -} - -static void game_loop_check_problems_at_start() -{ - if ((in_enters_screen != 0) & (displayed_room == starting_room)) - quit("!A text script run in the Player Enters Screen event caused the\n" - "screen to be updated. If you need to use Wait(), do so in After Fadein"); - if ((in_enters_screen != 0) && (done_es_error == 0)) { - debug_script_warn("Wait() was used in Player Enters Screen - use Enters Screen After Fadein instead"); - done_es_error = 1; - } - if (no_blocking_functions) - quit("!A blocking function was called from within a non-blocking event such as " REP_EXEC_ALWAYS_NAME); -} - -static void game_loop_check_new_room() -{ - if (in_new_room == 0) { - // Run the room and game script repeatedly_execute - run_function_on_non_blocking_thread(&repExecAlways); - setevent(EV_TEXTSCRIPT,TS_REPEAT); - setevent(EV_RUNEVBLOCK,EVB_ROOM,0,6); - } - // run this immediately to make sure it gets done before fade-in - // (player enters screen) - check_new_room (); -} - -static void game_loop_do_late_update() -{ - if (in_new_room == 0) - { - // Run the room and game script late_repeatedly_execute - run_function_on_non_blocking_thread(&lateRepExecAlways); - } -} - -static int game_loop_check_ground_level_interactions() -{ - if ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0) { - // check if he's standing on a hotspot - int hotspotThere = get_hotspot_at(playerchar->x, playerchar->y); - // run Stands on Hotspot event - setevent(EV_RUNEVBLOCK, EVB_HOTSPOT, hotspotThere, 0); - - // check current region - int onRegion = GetRegionIDAtRoom(playerchar->x, playerchar->y); - int inRoom = displayed_room; - - if (onRegion != play.player_on_region) { - // we need to save this and set play.player_on_region - // now, so it's correct going into RunRegionInteraction - int oldRegion = play.player_on_region; - - play.player_on_region = onRegion; - // Walks Off last region - if (oldRegion > 0) - RunRegionInteraction (oldRegion, 2); - // Walks Onto new region - if (onRegion > 0) - RunRegionInteraction (onRegion, 1); - } - if (play.player_on_region > 0) // player stands on region - RunRegionInteraction (play.player_on_region, 0); - - // one of the region interactions sent us to another room - if (inRoom != displayed_room) { - check_new_room(); - } - - // if in a Wait loop which is no longer valid (probably - // because the Region interaction did a NewRoom), abort - // the rest of the loop - if ((restrict_until) && (!ShouldStayInWaitMode())) { - // cancel the Rep Exec and Stands on Hotspot events that - // we just added -- otherwise the event queue gets huge - numevents = numEventsAtStartOfFunction; - return 0; - } - } // end if checking ground level interactions - - return RETURN_CONTINUE; -} - -static void lock_mouse_on_click() -{ - if (usetup.mouse_auto_lock && scsystem.windowed) - Mouse::TryLockToWindow(); -} - -static void toggle_mouse_lock() -{ - if (scsystem.windowed) - { - if (Mouse::IsLockedToWindow()) - Mouse::UnlockFromWindow(); - else - Mouse::TryLockToWindow(); - } +unsigned int loopcounter = 0; +static unsigned int lastcounter = 0; + +static void ProperExit() { + want_exit = 0; + proper_exit = 1; + quit("||exit!"); +} + +static void game_loop_check_problems_at_start() { + if ((in_enters_screen != 0) & (displayed_room == starting_room)) + quit("!A text script run in the Player Enters Screen event caused the\n" + "screen to be updated. If you need to use Wait(), do so in After Fadein"); + if ((in_enters_screen != 0) && (done_es_error == 0)) { + debug_script_warn("Wait() was used in Player Enters Screen - use Enters Screen After Fadein instead"); + done_es_error = 1; + } + if (no_blocking_functions) + quit("!A blocking function was called from within a non-blocking event such as " REP_EXEC_ALWAYS_NAME); +} + +static void game_loop_check_new_room() { + if (in_new_room == 0) { + // Run the room and game script repeatedly_execute + run_function_on_non_blocking_thread(&repExecAlways); + setevent(EV_TEXTSCRIPT, TS_REPEAT); + setevent(EV_RUNEVBLOCK, EVB_ROOM, 0, 6); + } + // run this immediately to make sure it gets done before fade-in + // (player enters screen) + check_new_room(); +} + +static void game_loop_do_late_update() { + if (in_new_room == 0) { + // Run the room and game script late_repeatedly_execute + run_function_on_non_blocking_thread(&lateRepExecAlways); + } +} + +static int game_loop_check_ground_level_interactions() { + if ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0) { + // check if he's standing on a hotspot + int hotspotThere = get_hotspot_at(playerchar->x, playerchar->y); + // run Stands on Hotspot event + setevent(EV_RUNEVBLOCK, EVB_HOTSPOT, hotspotThere, 0); + + // check current region + int onRegion = GetRegionIDAtRoom(playerchar->x, playerchar->y); + int inRoom = displayed_room; + + if (onRegion != play.player_on_region) { + // we need to save this and set play.player_on_region + // now, so it's correct going into RunRegionInteraction + int oldRegion = play.player_on_region; + + play.player_on_region = onRegion; + // Walks Off last region + if (oldRegion > 0) + RunRegionInteraction(oldRegion, 2); + // Walks Onto new region + if (onRegion > 0) + RunRegionInteraction(onRegion, 1); + } + if (play.player_on_region > 0) // player stands on region + RunRegionInteraction(play.player_on_region, 0); + + // one of the region interactions sent us to another room + if (inRoom != displayed_room) { + check_new_room(); + } + + // if in a Wait loop which is no longer valid (probably + // because the Region interaction did a NewRoom), abort + // the rest of the loop + if ((restrict_until) && (!ShouldStayInWaitMode())) { + // cancel the Rep Exec and Stands on Hotspot events that + // we just added -- otherwise the event queue gets huge + numevents = numEventsAtStartOfFunction; + return 0; + } + } // end if checking ground level interactions + + return RETURN_CONTINUE; +} + +static void lock_mouse_on_click() { + if (usetup.mouse_auto_lock && scsystem.windowed) + Mouse::TryLockToWindow(); +} + +static void toggle_mouse_lock() { + if (scsystem.windowed) { + if (Mouse::IsLockedToWindow()) + Mouse::UnlockFromWindow(); + else + Mouse::TryLockToWindow(); + } } // Runs default mouse button handling -static void check_mouse_controls() -{ - int mongu=-1; - - mongu = gui_on_mouse_move(); - - mouse_on_iface=mongu; - if ((ifacepopped>=0) && (mousey>=guis[ifacepopped].Y+guis[ifacepopped].Height)) - remove_popup_interface(ifacepopped); - - // check mouse clicks on GUIs - static int wasbutdown=0,wasongui=0; - - if ((wasbutdown>0) && (ags_misbuttondown(wasbutdown-1))) { - gui_on_mouse_hold(wasongui, wasbutdown); - } - else if ((wasbutdown>0) && (!ags_misbuttondown(wasbutdown-1))) { - gui_on_mouse_up(wasongui, wasbutdown); - wasbutdown=0; - } - - int mbut = NONE; - int mwheelz = 0; - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) { - - check_skip_cutscene_mclick(mbut); - - if (play.fast_forward || play.IsIgnoringInput()) { /* do nothing if skipping cutscene or input disabled */ } - else if ((play.wait_counter != 0) && (play.key_skip_wait & SKIP_MOUSECLICK) != 0) { - play.wait_counter = 0; - play.wait_skipped_by = SKIP_MOUSECLICK; - play.wait_skipped_by_data = mbut; - } - else if (is_text_overlay > 0) { - if (play.cant_skip_speech & SKIP_MOUSECLICK) - remove_screen_overlay(OVER_TEXTMSG); - } - else if (!IsInterfaceEnabled()) ; // blocking cutscene, ignore mouse - else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut+1)) { - // plugin took the click - debug_script_log("Plugin handled mouse button %d", mbut+1); - } - else if (mongu>=0) { - if (wasbutdown==0) { - gui_on_mouse_down(mongu, mbut+1); - } - wasongui=mongu; - wasbutdown=mbut+1; - } - else setevent(EV_TEXTSCRIPT,TS_MCLICK,mbut+1); - // else RunTextScriptIParam(gameinst,"on_mouse_click",aa+1); - } - - if (mwheelz < 0) - setevent (EV_TEXTSCRIPT, TS_MCLICK, 9); - else if (mwheelz > 0) - setevent (EV_TEXTSCRIPT, TS_MCLICK, 8); +static void check_mouse_controls() { + int mongu = -1; + + mongu = gui_on_mouse_move(); + + mouse_on_iface = mongu; + if ((ifacepopped >= 0) && (mousey >= guis[ifacepopped].Y + guis[ifacepopped].Height)) + remove_popup_interface(ifacepopped); + + // check mouse clicks on GUIs + static int wasbutdown = 0, wasongui = 0; + + if ((wasbutdown > 0) && (ags_misbuttondown(wasbutdown - 1))) { + gui_on_mouse_hold(wasongui, wasbutdown); + } else if ((wasbutdown > 0) && (!ags_misbuttondown(wasbutdown - 1))) { + gui_on_mouse_up(wasongui, wasbutdown); + wasbutdown = 0; + } + + int mbut = NONE; + int mwheelz = 0; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0) { + + check_skip_cutscene_mclick(mbut); + + if (play.fast_forward || play.IsIgnoringInput()) { + /* do nothing if skipping cutscene or input disabled */ + } else if ((play.wait_counter != 0) && (play.key_skip_wait & SKIP_MOUSECLICK) != 0) { + play.wait_counter = 0; + play.wait_skipped_by = SKIP_MOUSECLICK; + play.wait_skipped_by_data = mbut; + } else if (is_text_overlay > 0) { + if (play.cant_skip_speech & SKIP_MOUSECLICK) + remove_screen_overlay(OVER_TEXTMSG); + } else if (!IsInterfaceEnabled()) ; // blocking cutscene, ignore mouse + else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut + 1)) { + // plugin took the click + debug_script_log("Plugin handled mouse button %d", mbut + 1); + } else if (mongu >= 0) { + if (wasbutdown == 0) { + gui_on_mouse_down(mongu, mbut + 1); + } + wasongui = mongu; + wasbutdown = mbut + 1; + } else setevent(EV_TEXTSCRIPT, TS_MCLICK, mbut + 1); + // else RunTextScriptIParam(gameinst,"on_mouse_click",aa+1); + } + + if (mwheelz < 0) + setevent(EV_TEXTSCRIPT, TS_MCLICK, 9); + else if (mwheelz > 0) + setevent(EV_TEXTSCRIPT, TS_MCLICK, 8); } // Returns current key modifiers; @@ -290,16 +276,15 @@ static void check_mouse_controls() // Allegro API's 'key_shifts' variable seem to be always one step behind real // situation: if first modifier gets pressed, 'key_shifts' will be zero, // when second modifier gets pressed it will only contain first one, and so on. -static int get_active_shifts() -{ - int shifts = 0; - if (key[KEY_LSHIFT] || key[KEY_RSHIFT]) - shifts |= KB_SHIFT_FLAG; - if (key[KEY_LCONTROL] || key[KEY_RCONTROL]) - shifts |= KB_CTRL_FLAG; - if (key[KEY_ALT] || key[KEY_ALTGR]) - shifts |= KB_ALT_FLAG; - return shifts; +static int get_active_shifts() { + int shifts = 0; + if (key[KEY_LSHIFT] || key[KEY_RSHIFT]) + shifts |= KB_SHIFT_FLAG; + if (key[KEY_LCONTROL] || key[KEY_RCONTROL]) + shifts |= KB_CTRL_FLAG; + if (key[KEY_ALT] || key[KEY_ALTGR]) + shifts |= KB_ALT_FLAG; + return shifts; } // Special flags to OR saved shift flags with: @@ -308,751 +293,721 @@ static int get_active_shifts() // Runs service key controls, returns false if service key combinations were handled // and no more processing required, otherwise returns true and provides current keycode and key shifts. -bool run_service_key_controls(int &kgn) -{ - // check keypresses - static int old_key_shifts = 0; // for saving shift modes - - bool handled = false; - int kbhit_res = ags_kbhit(); - // First, check shifts - const int act_shifts = get_active_shifts(); - // If shifts combination have already triggered an action, then do nothing - // until new shifts are empty, in which case reset saved shifts - if (old_key_shifts & KEY_SHIFTS_FIRED) - { - if (act_shifts == 0) - old_key_shifts = 0; - } - else - { - // If any non-shift key is pressed, add fired flag to indicate that - // this is no longer a pure shifts key combination - if (kbhit_res) - { - old_key_shifts = act_shifts | KEY_SHIFTS_FIRED; - } - // If all the previously registered shifts are still pressed, - // then simply resave new shift state. - else if ((old_key_shifts & act_shifts) == old_key_shifts) - { - old_key_shifts = act_shifts; - } - // Otherwise some of the shifts were released, then run key combo action - // and set KEY_COMBO_FIRED flag to prevent multiple execution - else if (old_key_shifts) - { - // Toggle mouse lock on Ctrl + Alt - if (old_key_shifts == (KB_ALT_FLAG | KB_CTRL_FLAG)) - { - toggle_mouse_lock(); - handled = true; - } - old_key_shifts |= KEY_SHIFTS_FIRED; - } - } - - if (!kbhit_res || handled) - return false; - - int keycode = ags_getch(); - // NS: I'm still not sure why we read a second key. - // Perhaps it's of a time when we read the keyboard one byte at a time? - // if (keycode == 0) - // keycode = ags_getch() + AGS_EXT_KEY_SHIFT; - if (keycode == 0) - return false; - - // LAlt or RAlt + Enter - // NOTE: for some reason LAlt + Enter produces same code as F9 - if (act_shifts == KB_ALT_FLAG && ((keycode == eAGSKeyCodeF9 && !key[KEY_F9]) || keycode == eAGSKeyCodeReturn)) - { - engine_try_switch_windowed_gfxmode(); - return false; - } - - // No service operation triggered? return active keypress and shifts to caller - kgn = keycode; - return true; -} - -bool run_service_mb_controls(int &mbut, int &mwheelz) -{ - int mb = ags_mgetbutton(); - int mz = ags_check_mouse_wheel(); - if (mb == NONE && mz == 0) - return false; - lock_mouse_on_click(); // do not claim - mbut = mb; - mwheelz = mz; - return true; +bool run_service_key_controls(int &kgn) { + // check keypresses + static int old_key_shifts = 0; // for saving shift modes + + bool handled = false; + int kbhit_res = ags_kbhit(); + // First, check shifts + const int act_shifts = get_active_shifts(); + // If shifts combination have already triggered an action, then do nothing + // until new shifts are empty, in which case reset saved shifts + if (old_key_shifts & KEY_SHIFTS_FIRED) { + if (act_shifts == 0) + old_key_shifts = 0; + } else { + // If any non-shift key is pressed, add fired flag to indicate that + // this is no longer a pure shifts key combination + if (kbhit_res) { + old_key_shifts = act_shifts | KEY_SHIFTS_FIRED; + } + // If all the previously registered shifts are still pressed, + // then simply resave new shift state. + else if ((old_key_shifts & act_shifts) == old_key_shifts) { + old_key_shifts = act_shifts; + } + // Otherwise some of the shifts were released, then run key combo action + // and set KEY_COMBO_FIRED flag to prevent multiple execution + else if (old_key_shifts) { + // Toggle mouse lock on Ctrl + Alt + if (old_key_shifts == (KB_ALT_FLAG | KB_CTRL_FLAG)) { + toggle_mouse_lock(); + handled = true; + } + old_key_shifts |= KEY_SHIFTS_FIRED; + } + } + + if (!kbhit_res || handled) + return false; + + int keycode = ags_getch(); + // NS: I'm still not sure why we read a second key. + // Perhaps it's of a time when we read the keyboard one byte at a time? + // if (keycode == 0) + // keycode = ags_getch() + AGS_EXT_KEY_SHIFT; + if (keycode == 0) + return false; + + // LAlt or RAlt + Enter + // NOTE: for some reason LAlt + Enter produces same code as F9 + if (act_shifts == KB_ALT_FLAG && ((keycode == eAGSKeyCodeF9 && !key[KEY_F9]) || keycode == eAGSKeyCodeReturn)) { + engine_try_switch_windowed_gfxmode(); + return false; + } + + // No service operation triggered? return active keypress and shifts to caller + kgn = keycode; + return true; +} + +bool run_service_mb_controls(int &mbut, int &mwheelz) { + int mb = ags_mgetbutton(); + int mz = ags_check_mouse_wheel(); + if (mb == NONE && mz == 0) + return false; + lock_mouse_on_click(); // do not claim + mbut = mb; + mwheelz = mz; + return true; } // Runs default keyboard handling -static void check_keyboard_controls() -{ - // First check for service engine's combinations (mouse lock, display mode switch, and so forth) - int kgn; - if (!run_service_key_controls(kgn)) { - return; - } - // Then, check cutscene skip - check_skip_cutscene_keypress(kgn); - if (play.fast_forward) { - return; - } - if (play.IsIgnoringInput()) { - return; - } - // Now check for in-game controls - if (pl_run_plugin_hooks(AGSE_KEYPRESS, kgn)) { - // plugin took the keypress - debug_script_log("Keypress code %d taken by plugin", kgn); - return; - } - - // debug console - if ((kgn == '`') && (play.debug_mode > 0)) { - display_console = !display_console; - return; - } - - // skip speech if desired by Speech.SkipStyle - if ((is_text_overlay > 0) && (play.cant_skip_speech & SKIP_KEYPRESS)) { - // only allow a key to remove the overlay if the icon bar isn't up - if (IsGamePaused() == 0) { - // check if it requires a specific keypress - if ((play.skip_speech_specific_key > 0) && - (kgn != play.skip_speech_specific_key)) { } - else - remove_screen_overlay(OVER_TEXTMSG); - } - - return; - } - - if ((play.wait_counter != 0) && (play.key_skip_wait & SKIP_KEYPRESS) != 0) { - play.wait_counter = 0; - play.wait_skipped_by = SKIP_KEYPRESS; - play.wait_skipped_by_data = kgn; - debug_script_log("Keypress code %d ignored - in Wait", kgn); - return; - } - - if ((kgn == eAGSKeyCodeCtrlE) && (display_fps == kFPS_Forced)) { - // if --fps paramter is used, Ctrl+E will max out frame rate - setTimerFps( isTimerFpsMaxed() ? frames_per_second : 1000 ); - return; - } - - if ((kgn == eAGSKeyCodeCtrlD) && (play.debug_mode > 0)) { - // ctrl+D - show info - char infobuf[900]; - int ff; - // MACPORT FIX 9/6/5: added last %s - sprintf(infobuf,"In room %d %s[Player at %d, %d (view %d, loop %d, frame %d)%s%s%s", - displayed_room, (noWalkBehindsAtAll ? "(has no walk-behinds)" : ""), playerchar->x,playerchar->y, - playerchar->view + 1, playerchar->loop,playerchar->frame, - (IsGamePaused() == 0) ? "" : "[Game paused.", - (play.ground_level_areas_disabled == 0) ? "" : "[Ground areas disabled.", - (IsInterfaceEnabled() == 0) ? "[Game in Wait state" : ""); - for (ff=0;ffnumobj;ff++) { - if (ff >= 8) break; // buffer not big enough for more than 7 - sprintf(&infobuf[strlen(infobuf)], - "[Object %d: (%d,%d) size (%d x %d) on:%d moving:%s animating:%d slot:%d trnsp:%d clkble:%d", - ff, objs[ff].x, objs[ff].y, - (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Width : 0, - (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Height : 0, - objs[ff].on, - (objs[ff].moving > 0) ? "yes" : "no", objs[ff].cycling, - objs[ff].num, objs[ff].transparent, - ((objs[ff].flags & OBJF_NOINTERACT) != 0) ? 0 : 1 ); - } - Display(infobuf); - int chd = game.playercharacter; - char bigbuffer[STD_BUFFER_SIZE] = "CHARACTERS IN THIS ROOM:["; - for (ff = 0; ff < game.numcharacters; ff++) { - if (game.chars[ff].room != displayed_room) continue; - if (strlen(bigbuffer) > 430) { - strcat(bigbuffer, "and more..."); - Display(bigbuffer); - strcpy(bigbuffer, "CHARACTERS IN THIS ROOM (cont'd):["); - } - chd = ff; - sprintf(&bigbuffer[strlen(bigbuffer)], - "%s (view/loop/frm:%d,%d,%d x/y/z:%d,%d,%d idleview:%d,time:%d,left:%d walk:%d anim:%d follow:%d flags:%X wait:%d zoom:%d)[", - game.chars[chd].scrname, game.chars[chd].view+1, game.chars[chd].loop, game.chars[chd].frame, - game.chars[chd].x, game.chars[chd].y, game.chars[chd].z, - game.chars[chd].idleview, game.chars[chd].idletime, game.chars[chd].idleleft, - game.chars[chd].walking, game.chars[chd].animating, game.chars[chd].following, - game.chars[chd].flags, game.chars[chd].wait, charextra[chd].zoom); - } - Display(bigbuffer); - - return; - } - - // if (kgn == key_ctrl_u) { - // play.debug_mode++; - // script_debug(5,0); - // play.debug_mode--; - // return; - // } - - if ((kgn == eAGSKeyCodeAltV) && (key[KEY_LCONTROL] || key[KEY_RCONTROL]) && (play.wait_counter < 1) && (is_text_overlay == 0) && (restrict_until == 0)) { - // make sure we can't interrupt a Wait() - // and desync the music to cutscene - play.debug_mode++; - script_debug (1,0); - play.debug_mode--; - - return; - } - - if (inside_script) { - // Don't queue up another keypress if it can't be run instantly - debug_script_log("Keypress %d ignored (game blocked)", kgn); - return; - } - - int keywasprocessed = 0; - - // determine if a GUI Text Box should steal the click - // it should do if a displayable character (32-255) is - // pressed, but exclude control characters (<32) and - // extended keys (eg. up/down arrow; 256+) - if ( (((kgn >= 32) && (kgn <= 255) && (kgn != '[')) || (kgn == eAGSKeyCodeReturn) || (kgn == eAGSKeyCodeBackspace)) - && !all_buttons_disabled) { - for (int guiIndex = 0; guiIndex < game.numgui; guiIndex++) { - auto &gui = guis[guiIndex]; - - if (!gui.IsDisplayed()) continue; - - for (int controlIndex = 0; controlIndex < gui.GetControlCount(); controlIndex++) { - // not a text box, ignore it - if (gui.GetControlType(controlIndex) != kGUITextBox) { continue; } - - auto *guitex = static_cast(gui.GetControl(controlIndex)); - if (guitex == nullptr) { continue; } - - // if the text box is disabled, it cannot accept keypresses - if (!guitex->IsEnabled()) { continue; } - if (!guitex->IsVisible()) { continue; } - - keywasprocessed = 1; - - guitex->OnKeyPress(kgn); - - if (guitex->IsActivated) { - guitex->IsActivated = false; - setevent(EV_IFACECLICK, guiIndex, controlIndex, 1); - } - } - } - } - - if (!keywasprocessed) { - kgn = GetKeyForKeyPressCb(kgn); - debug_script_log("Running on_key_press keycode %d", kgn); - setevent(EV_TEXTSCRIPT,TS_KEYPRESS,kgn); - } - - // RunTextScriptIParam(gameinst,"on_key_press",kgn); +static void check_keyboard_controls() { + // First check for service engine's combinations (mouse lock, display mode switch, and so forth) + int kgn; + if (!run_service_key_controls(kgn)) { + return; + } + // Then, check cutscene skip + check_skip_cutscene_keypress(kgn); + if (play.fast_forward) { + return; + } + if (play.IsIgnoringInput()) { + return; + } + // Now check for in-game controls + if (pl_run_plugin_hooks(AGSE_KEYPRESS, kgn)) { + // plugin took the keypress + debug_script_log("Keypress code %d taken by plugin", kgn); + return; + } + + // debug console + if ((kgn == '`') && (play.debug_mode > 0)) { + display_console = !display_console; + return; + } + + // skip speech if desired by Speech.SkipStyle + if ((is_text_overlay > 0) && (play.cant_skip_speech & SKIP_KEYPRESS)) { + // only allow a key to remove the overlay if the icon bar isn't up + if (IsGamePaused() == 0) { + // check if it requires a specific keypress + if ((play.skip_speech_specific_key > 0) && + (kgn != play.skip_speech_specific_key)) { } + else + remove_screen_overlay(OVER_TEXTMSG); + } + + return; + } + + if ((play.wait_counter != 0) && (play.key_skip_wait & SKIP_KEYPRESS) != 0) { + play.wait_counter = 0; + play.wait_skipped_by = SKIP_KEYPRESS; + play.wait_skipped_by_data = kgn; + debug_script_log("Keypress code %d ignored - in Wait", kgn); + return; + } + + if ((kgn == eAGSKeyCodeCtrlE) && (display_fps == kFPS_Forced)) { + // if --fps paramter is used, Ctrl+E will max out frame rate + setTimerFps(isTimerFpsMaxed() ? frames_per_second : 1000); + return; + } + + if ((kgn == eAGSKeyCodeCtrlD) && (play.debug_mode > 0)) { + // ctrl+D - show info + char infobuf[900]; + int ff; + // MACPORT FIX 9/6/5: added last %s + sprintf(infobuf, "In room %d %s[Player at %d, %d (view %d, loop %d, frame %d)%s%s%s", + displayed_room, (noWalkBehindsAtAll ? "(has no walk-behinds)" : ""), playerchar->x, playerchar->y, + playerchar->view + 1, playerchar->loop, playerchar->frame, + (IsGamePaused() == 0) ? "" : "[Game paused.", + (play.ground_level_areas_disabled == 0) ? "" : "[Ground areas disabled.", + (IsInterfaceEnabled() == 0) ? "[Game in Wait state" : ""); + for (ff = 0; ff < croom->numobj; ff++) { + if (ff >= 8) break; // buffer not big enough for more than 7 + sprintf(&infobuf[strlen(infobuf)], + "[Object %d: (%d,%d) size (%d x %d) on:%d moving:%s animating:%d slot:%d trnsp:%d clkble:%d", + ff, objs[ff].x, objs[ff].y, + (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Width : 0, + (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Height : 0, + objs[ff].on, + (objs[ff].moving > 0) ? "yes" : "no", objs[ff].cycling, + objs[ff].num, objs[ff].transparent, + ((objs[ff].flags & OBJF_NOINTERACT) != 0) ? 0 : 1); + } + Display(infobuf); + int chd = game.playercharacter; + char bigbuffer[STD_BUFFER_SIZE] = "CHARACTERS IN THIS ROOM:["; + for (ff = 0; ff < game.numcharacters; ff++) { + if (game.chars[ff].room != displayed_room) continue; + if (strlen(bigbuffer) > 430) { + strcat(bigbuffer, "and more..."); + Display(bigbuffer); + strcpy(bigbuffer, "CHARACTERS IN THIS ROOM (cont'd):["); + } + chd = ff; + sprintf(&bigbuffer[strlen(bigbuffer)], + "%s (view/loop/frm:%d,%d,%d x/y/z:%d,%d,%d idleview:%d,time:%d,left:%d walk:%d anim:%d follow:%d flags:%X wait:%d zoom:%d)[", + game.chars[chd].scrname, game.chars[chd].view + 1, game.chars[chd].loop, game.chars[chd].frame, + game.chars[chd].x, game.chars[chd].y, game.chars[chd].z, + game.chars[chd].idleview, game.chars[chd].idletime, game.chars[chd].idleleft, + game.chars[chd].walking, game.chars[chd].animating, game.chars[chd].following, + game.chars[chd].flags, game.chars[chd].wait, charextra[chd].zoom); + } + Display(bigbuffer); + + return; + } + + // if (kgn == key_ctrl_u) { + // play.debug_mode++; + // script_debug(5,0); + // play.debug_mode--; + // return; + // } + + if ((kgn == eAGSKeyCodeAltV) && (key[KEY_LCONTROL] || key[KEY_RCONTROL]) && (play.wait_counter < 1) && (is_text_overlay == 0) && (restrict_until == 0)) { + // make sure we can't interrupt a Wait() + // and desync the music to cutscene + play.debug_mode++; + script_debug(1, 0); + play.debug_mode--; + + return; + } + + if (inside_script) { + // Don't queue up another keypress if it can't be run instantly + debug_script_log("Keypress %d ignored (game blocked)", kgn); + return; + } + + int keywasprocessed = 0; + + // determine if a GUI Text Box should steal the click + // it should do if a displayable character (32-255) is + // pressed, but exclude control characters (<32) and + // extended keys (eg. up/down arrow; 256+) + if ((((kgn >= 32) && (kgn <= 255) && (kgn != '[')) || (kgn == eAGSKeyCodeReturn) || (kgn == eAGSKeyCodeBackspace)) + && !all_buttons_disabled) { + for (int guiIndex = 0; guiIndex < game.numgui; guiIndex++) { + auto &gui = guis[guiIndex]; + + if (!gui.IsDisplayed()) continue; + + for (int controlIndex = 0; controlIndex < gui.GetControlCount(); controlIndex++) { + // not a text box, ignore it + if (gui.GetControlType(controlIndex) != kGUITextBox) { + continue; + } + + auto *guitex = static_cast(gui.GetControl(controlIndex)); + if (guitex == nullptr) { + continue; + } + + // if the text box is disabled, it cannot accept keypresses + if (!guitex->IsEnabled()) { + continue; + } + if (!guitex->IsVisible()) { + continue; + } + + keywasprocessed = 1; + + guitex->OnKeyPress(kgn); + + if (guitex->IsActivated) { + guitex->IsActivated = false; + setevent(EV_IFACECLICK, guiIndex, controlIndex, 1); + } + } + } + } + + if (!keywasprocessed) { + kgn = GetKeyForKeyPressCb(kgn); + debug_script_log("Running on_key_press keycode %d", kgn); + setevent(EV_TEXTSCRIPT, TS_KEYPRESS, kgn); + } + + // RunTextScriptIParam(gameinst,"on_key_press",kgn); } // check_controls: checks mouse & keyboard interface static void check_controls() { - our_eip = 1007; - - check_mouse_controls(); - check_keyboard_controls(); -} - -static void check_room_edges(int numevents_was) -{ - if ((IsInterfaceEnabled()) && (IsGamePaused() == 0) && - (in_new_room == 0) && (new_room_was == 0)) { - // Only allow walking off edges if not in wait mode, and - // if not in Player Enters Screen (allow walking in from off-screen) - int edgesActivated[4] = {0, 0, 0, 0}; - // Only do it if nothing else has happened (eg. mouseclick) - if ((numevents == numevents_was) && - ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0)) { - - if (playerchar->x <= thisroom.Edges.Left) - edgesActivated[0] = 1; - else if (playerchar->x >= thisroom.Edges.Right) - edgesActivated[1] = 1; - if (playerchar->y >= thisroom.Edges.Bottom) - edgesActivated[2] = 1; - else if (playerchar->y <= thisroom.Edges.Top) - edgesActivated[3] = 1; - - if ((play.entered_edge >= 0) && (play.entered_edge <= 3)) { - // once the player is no longer outside the edge, forget the stored edge - if (edgesActivated[play.entered_edge] == 0) - play.entered_edge = -10; - // if we are walking in from off-screen, don't activate edges - else - edgesActivated[play.entered_edge] = 0; - } - - for (int ii = 0; ii < 4; ii++) { - if (edgesActivated[ii]) - setevent(EV_RUNEVBLOCK, EVB_ROOM, 0, ii); - } - } - } - our_eip = 1008; - -} - -static void game_loop_check_controls(bool checkControls) -{ - // don't let the player do anything before the screen fades in - if ((in_new_room == 0) && (checkControls)) { - int inRoom = displayed_room; - int numevents_was = numevents; - check_controls(); - check_room_edges(numevents_was); - // If an inventory interaction changed the room - if (inRoom != displayed_room) - check_new_room(); - } -} - -static void game_loop_do_update() -{ - if (debug_flags & DBG_NOUPDATE) ; - else if (game_paused==0) update_stuff(); -} - -static void game_loop_update_animated_buttons() -{ - // update animating GUI buttons - // this bit isn't in update_stuff because it always needs to - // happen, even when the game is paused - for (int aa = 0; aa < numAnimButs; aa++) { - if (UpdateAnimatingButton(aa)) { - StopButtonAnimation(aa); - aa--; - } - } -} - -static void game_loop_do_render_and_check_mouse(IDriverDependantBitmap *extraBitmap, int extraX, int extraY) -{ - if (!play.fast_forward) { - int mwasatx=mousex,mwasaty=mousey; - - // Only do this if we are not skipping a cutscene - render_graphics(extraBitmap, extraX, extraY); - - // Check Mouse Moves Over Hotspot event - // TODO: move this out of render related function? find out why we remember mwasatx and mwasaty before render - // TODO: do not use static variables! - // TODO: if we support rotation then we also need to compare full transform! - if (displayed_room < 0) - return; - auto view = play.GetRoomViewportAt(mousex, mousey); - auto cam = view ? view->GetCamera() : nullptr; - if (cam) - { - // NOTE: all cameras are in same room right now, so their positions are in same coordinate system; - // therefore we may use this as an indication that mouse is over different camera too. - static int offsetxWas = -1000, offsetyWas = -1000; - int offsetx = cam->GetRect().Left; - int offsety = cam->GetRect().Top; - - if (((mwasatx!=mousex) || (mwasaty!=mousey) || - (offsetxWas != offsetx) || (offsetyWas != offsety))) - { - // mouse moves over hotspot - if (__GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey), 1) == LOCTYPE_HOTSPOT) { - int onhs = getloctype_index; - - setevent(EV_RUNEVBLOCK,EVB_HOTSPOT,onhs,6); - } - } - - offsetxWas = offsetx; - offsetyWas = offsety; - } // camera found under mouse - } -} - -static void game_loop_update_events() -{ - new_room_was = in_new_room; - if (in_new_room>0) - setevent(EV_FADEIN,0,0,0); - in_new_room=0; - update_events(); - if ((new_room_was > 0) && (in_new_room == 0)) { - // if in a new room, and the room wasn't just changed again in update_events, - // then queue the Enters Screen scripts - // run these next time round, when it's faded in - if (new_room_was==2) // first time enters screen - setevent(EV_RUNEVBLOCK,EVB_ROOM,0,4); - if (new_room_was!=3) // enters screen after fadein - setevent(EV_RUNEVBLOCK,EVB_ROOM,0,7); - } -} - -static void game_loop_update_background_animation() -{ - if (play.bg_anim_delay > 0) play.bg_anim_delay--; - else if (play.bg_frame_locked) ; - else { - play.bg_anim_delay = play.anim_background_speed; - play.bg_frame++; - if ((size_t)play.bg_frame >= thisroom.BgFrameCount) - play.bg_frame=0; - if (thisroom.BgFrameCount >= 2) { - // get the new frame's palette - on_background_frame_change(); - } - } -} - -static void game_loop_update_loop_counter() -{ - loopcounter++; - - if (play.wait_counter > 0) play.wait_counter--; - if (play.shakesc_length > 0) play.shakesc_length--; - - if (loopcounter % 5 == 0) - { - update_ambient_sound_vol(); - update_directional_sound_vol(); - } -} - -static void game_loop_update_fps() -{ - auto t2 = AGS_Clock::now(); - auto duration = std::chrono::duration_cast(t2 - t1); - auto frames = loopcounter - lastcounter; - - if (duration >= std::chrono::milliseconds(1000) && frames > 0) { - fps = 1000.0f * frames / duration.count(); - t1 = t2; - lastcounter = loopcounter; - } + our_eip = 1007; + + check_mouse_controls(); + check_keyboard_controls(); +} + +static void check_room_edges(int numevents_was) { + if ((IsInterfaceEnabled()) && (IsGamePaused() == 0) && + (in_new_room == 0) && (new_room_was == 0)) { + // Only allow walking off edges if not in wait mode, and + // if not in Player Enters Screen (allow walking in from off-screen) + int edgesActivated[4] = {0, 0, 0, 0}; + // Only do it if nothing else has happened (eg. mouseclick) + if ((numevents == numevents_was) && + ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0)) { + + if (playerchar->x <= thisroom.Edges.Left) + edgesActivated[0] = 1; + else if (playerchar->x >= thisroom.Edges.Right) + edgesActivated[1] = 1; + if (playerchar->y >= thisroom.Edges.Bottom) + edgesActivated[2] = 1; + else if (playerchar->y <= thisroom.Edges.Top) + edgesActivated[3] = 1; + + if ((play.entered_edge >= 0) && (play.entered_edge <= 3)) { + // once the player is no longer outside the edge, forget the stored edge + if (edgesActivated[play.entered_edge] == 0) + play.entered_edge = -10; + // if we are walking in from off-screen, don't activate edges + else + edgesActivated[play.entered_edge] = 0; + } + + for (int ii = 0; ii < 4; ii++) { + if (edgesActivated[ii]) + setevent(EV_RUNEVBLOCK, EVB_ROOM, 0, ii); + } + } + } + our_eip = 1008; + +} + +static void game_loop_check_controls(bool checkControls) { + // don't let the player do anything before the screen fades in + if ((in_new_room == 0) && (checkControls)) { + int inRoom = displayed_room; + int numevents_was = numevents; + check_controls(); + check_room_edges(numevents_was); + // If an inventory interaction changed the room + if (inRoom != displayed_room) + check_new_room(); + } +} + +static void game_loop_do_update() { + if (debug_flags & DBG_NOUPDATE) ; + else if (game_paused == 0) update_stuff(); +} + +static void game_loop_update_animated_buttons() { + // update animating GUI buttons + // this bit isn't in update_stuff because it always needs to + // happen, even when the game is paused + for (int aa = 0; aa < numAnimButs; aa++) { + if (UpdateAnimatingButton(aa)) { + StopButtonAnimation(aa); + aa--; + } + } +} + +static void game_loop_do_render_and_check_mouse(IDriverDependantBitmap *extraBitmap, int extraX, int extraY) { + if (!play.fast_forward) { + int mwasatx = mousex, mwasaty = mousey; + + // Only do this if we are not skipping a cutscene + render_graphics(extraBitmap, extraX, extraY); + + // Check Mouse Moves Over Hotspot event + // TODO: move this out of render related function? find out why we remember mwasatx and mwasaty before render + // TODO: do not use static variables! + // TODO: if we support rotation then we also need to compare full transform! + if (displayed_room < 0) + return; + auto view = play.GetRoomViewportAt(mousex, mousey); + auto cam = view ? view->GetCamera() : nullptr; + if (cam) { + // NOTE: all cameras are in same room right now, so their positions are in same coordinate system; + // therefore we may use this as an indication that mouse is over different camera too. + static int offsetxWas = -1000, offsetyWas = -1000; + int offsetx = cam->GetRect().Left; + int offsety = cam->GetRect().Top; + + if (((mwasatx != mousex) || (mwasaty != mousey) || + (offsetxWas != offsetx) || (offsetyWas != offsety))) { + // mouse moves over hotspot + if (__GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey), 1) == LOCTYPE_HOTSPOT) { + int onhs = getloctype_index; + + setevent(EV_RUNEVBLOCK, EVB_HOTSPOT, onhs, 6); + } + } + + offsetxWas = offsetx; + offsetyWas = offsety; + } // camera found under mouse + } +} + +static void game_loop_update_events() { + new_room_was = in_new_room; + if (in_new_room > 0) + setevent(EV_FADEIN, 0, 0, 0); + in_new_room = 0; + update_events(); + if ((new_room_was > 0) && (in_new_room == 0)) { + // if in a new room, and the room wasn't just changed again in update_events, + // then queue the Enters Screen scripts + // run these next time round, when it's faded in + if (new_room_was == 2) // first time enters screen + setevent(EV_RUNEVBLOCK, EVB_ROOM, 0, 4); + if (new_room_was != 3) // enters screen after fadein + setevent(EV_RUNEVBLOCK, EVB_ROOM, 0, 7); + } +} + +static void game_loop_update_background_animation() { + if (play.bg_anim_delay > 0) play.bg_anim_delay--; + else if (play.bg_frame_locked) ; + else { + play.bg_anim_delay = play.anim_background_speed; + play.bg_frame++; + if ((size_t)play.bg_frame >= thisroom.BgFrameCount) + play.bg_frame = 0; + if (thisroom.BgFrameCount >= 2) { + // get the new frame's palette + on_background_frame_change(); + } + } +} + +static void game_loop_update_loop_counter() { + loopcounter++; + + if (play.wait_counter > 0) play.wait_counter--; + if (play.shakesc_length > 0) play.shakesc_length--; + + if (loopcounter % 5 == 0) { + update_ambient_sound_vol(); + update_directional_sound_vol(); + } +} + +static void game_loop_update_fps() { + auto t2 = AGS_Clock::now(); + auto duration = std::chrono::duration_cast(t2 - t1); + auto frames = loopcounter - lastcounter; + + if (duration >= std::chrono::milliseconds(1000) && frames > 0) { + fps = 1000.0f * frames / duration.count(); + t1 = t2; + lastcounter = loopcounter; + } } float get_current_fps() { - // if we have maxed out framerate then return the frame rate we're seeing instead - // fps must be greater that 0 or some timings will take forever. - if (isTimerFpsMaxed() && fps > 0.0f) { - return fps; - } - return frames_per_second; + // if we have maxed out framerate then return the frame rate we're seeing instead + // fps must be greater that 0 or some timings will take forever. + if (isTimerFpsMaxed() && fps > 0.0f) { + return fps; + } + return frames_per_second; } void set_loop_counter(unsigned int new_counter) { - loopcounter = new_counter; - t1 = AGS_Clock::now(); - lastcounter = loopcounter; - fps = std::numeric_limits::quiet_NaN(); + loopcounter = new_counter; + t1 = AGS_Clock::now(); + lastcounter = loopcounter; + fps = std::numeric_limits::quiet_NaN(); } void UpdateGameOnce(bool checkControls, IDriverDependantBitmap *extraBitmap, int extraX, int extraY) { - int res; + int res; - update_polled_mp3(); + update_polled_mp3(); - numEventsAtStartOfFunction = numevents; + numEventsAtStartOfFunction = numevents; - if (want_exit) { - ProperExit(); - } + if (want_exit) { + ProperExit(); + } - ccNotifyScriptStillAlive (); - our_eip=1; + ccNotifyScriptStillAlive(); + our_eip = 1; - game_loop_check_problems_at_start(); + game_loop_check_problems_at_start(); - // if we're not fading in, don't count the fadeouts - if ((play.no_hicolor_fadein) && (game.options[OPT_FADETYPE] == FADE_NORMAL)) - play.screen_is_faded_out = 0; + // if we're not fading in, don't count the fadeouts + if ((play.no_hicolor_fadein) && (game.options[OPT_FADETYPE] == FADE_NORMAL)) + play.screen_is_faded_out = 0; - our_eip = 1014; + our_eip = 1014; - update_gui_disabled_status(); + update_gui_disabled_status(); - our_eip = 1004; + our_eip = 1004; - game_loop_check_new_room(); + game_loop_check_new_room(); - our_eip = 1005; + our_eip = 1005; - res = game_loop_check_ground_level_interactions(); - if (res != RETURN_CONTINUE) { - return; - } + res = game_loop_check_ground_level_interactions(); + if (res != RETURN_CONTINUE) { + return; + } - mouse_on_iface=-1; + mouse_on_iface = -1; - check_debug_keys(); + check_debug_keys(); - game_loop_check_controls(checkControls); + game_loop_check_controls(checkControls); - our_eip=2; + our_eip = 2; - game_loop_do_update(); + game_loop_do_update(); - game_loop_update_animated_buttons(); + game_loop_update_animated_buttons(); - game_loop_do_late_update(); + game_loop_do_late_update(); - update_audio_system_on_game_loop(); + update_audio_system_on_game_loop(); - game_loop_do_render_and_check_mouse(extraBitmap, extraX, extraY); + game_loop_do_render_and_check_mouse(extraBitmap, extraX, extraY); - our_eip=6; + our_eip = 6; - game_loop_update_events(); + game_loop_update_events(); - our_eip=7; + our_eip = 7; - // if (ags_mgetbutton()>NONE) break; - update_polled_stuff_if_runtime(); + // if (ags_mgetbutton()>NONE) break; + update_polled_stuff_if_runtime(); - game_loop_update_background_animation(); + game_loop_update_background_animation(); - game_loop_update_loop_counter(); + game_loop_update_loop_counter(); - // Immediately start the next frame if we are skipping a cutscene - if (play.fast_forward) - return; + // Immediately start the next frame if we are skipping a cutscene + if (play.fast_forward) + return; - our_eip=72; + our_eip = 72; - game_loop_update_fps(); + game_loop_update_fps(); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - WaitForNextFrame(); + WaitForNextFrame(); } -static void UpdateMouseOverLocation() -{ - // Call GetLocationName - it will internally force a GUI refresh - // if the result it returns has changed from last time - char tempo[STD_BUFFER_SIZE]; - GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); - - if ((play.get_loc_name_save_cursor >= 0) && - (play.get_loc_name_save_cursor != play.get_loc_name_last_time) && - (mouse_on_iface < 0) && (ifacepopped < 0)) { - // we have saved the cursor, but the mouse location has changed - // and it's time to restore it - play.get_loc_name_save_cursor = -1; - set_cursor_mode(play.restore_cursor_mode_to); - - if (cur_mode == play.restore_cursor_mode_to) - { - // make sure it changed -- the new mode might have been disabled - // in which case don't change the image - set_mouse_cursor(play.restore_cursor_image_to); - } - debug_script_log("Restore mouse to mode %d cursor %d", play.restore_cursor_mode_to, play.restore_cursor_image_to); - } +static void UpdateMouseOverLocation() { + // Call GetLocationName - it will internally force a GUI refresh + // if the result it returns has changed from last time + char tempo[STD_BUFFER_SIZE]; + GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + + if ((play.get_loc_name_save_cursor >= 0) && + (play.get_loc_name_save_cursor != play.get_loc_name_last_time) && + (mouse_on_iface < 0) && (ifacepopped < 0)) { + // we have saved the cursor, but the mouse location has changed + // and it's time to restore it + play.get_loc_name_save_cursor = -1; + set_cursor_mode(play.restore_cursor_mode_to); + + if (cur_mode == play.restore_cursor_mode_to) { + // make sure it changed -- the new mode might have been disabled + // in which case don't change the image + set_mouse_cursor(play.restore_cursor_image_to); + } + debug_script_log("Restore mouse to mode %d cursor %d", play.restore_cursor_mode_to, play.restore_cursor_image_to); + } } // Checks if user interface should remain disabled for now static int ShouldStayInWaitMode() { - if (restrict_until == 0) - quit("end_wait_loop called but game not in loop_until state"); - int retval = restrict_until; - - if (restrict_until==UNTIL_MOVEEND) { - short*wkptr=(short*)user_disabled_data; - if (wkptr[0]<1) retval=0; - } - else if (restrict_until==UNTIL_CHARIS0) { - char*chptr=(char*)user_disabled_data; - if (chptr[0]==0) retval=0; - } - else if (restrict_until==UNTIL_NEGATIVE) { - short*wkptr=(short*)user_disabled_data; - if (wkptr[0]<0) retval=0; - } - else if (restrict_until==UNTIL_INTISNEG) { - int*wkptr=(int*)user_disabled_data; - if (wkptr[0]<0) retval=0; - } - else if (restrict_until==UNTIL_NOOVERLAY) { - if (is_text_overlay < 1) retval=0; - } - else if (restrict_until==UNTIL_INTIS0) { - int*wkptr=(int*)user_disabled_data; - if (wkptr[0]==0) retval=0; - } - else if (restrict_until==UNTIL_SHORTIS0) { - short*wkptr=(short*)user_disabled_data; - if (wkptr[0]==0) retval=0; - } - else quit("loop_until: unknown until event"); - - return retval; -} - -static int UpdateWaitMode() -{ - if (restrict_until==0) { return RETURN_CONTINUE; } - - restrict_until = ShouldStayInWaitMode(); - our_eip = 77; - - if (restrict_until!=0) { return RETURN_CONTINUE; } - - auto was_disabled_for = user_disabled_for; - - set_default_cursor(); - guis_need_update = 1; - play.disabled_user_interface--; - user_disabled_for = 0; - - switch (was_disabled_for) { - // case FOR_ANIMATION: - // run_animation((FullAnimation*)user_disabled_data2,user_disabled_data3); - // break; - case FOR_EXITLOOP: - return -1; - case FOR_SCRIPT: - quit("err: for_script obsolete (v2.1 and earlier only)"); - break; - default: - quit("Unknown user_disabled_for in end restrict_until"); - } - - // we shouldn't get here. - return RETURN_CONTINUE; + if (restrict_until == 0) + quit("end_wait_loop called but game not in loop_until state"); + int retval = restrict_until; + + if (restrict_until == UNTIL_MOVEEND) { + short *wkptr = (short *)user_disabled_data; + if (wkptr[0] < 1) retval = 0; + } else if (restrict_until == UNTIL_CHARIS0) { + char *chptr = (char *)user_disabled_data; + if (chptr[0] == 0) retval = 0; + } else if (restrict_until == UNTIL_NEGATIVE) { + short *wkptr = (short *)user_disabled_data; + if (wkptr[0] < 0) retval = 0; + } else if (restrict_until == UNTIL_INTISNEG) { + int *wkptr = (int *)user_disabled_data; + if (wkptr[0] < 0) retval = 0; + } else if (restrict_until == UNTIL_NOOVERLAY) { + if (is_text_overlay < 1) retval = 0; + } else if (restrict_until == UNTIL_INTIS0) { + int *wkptr = (int *)user_disabled_data; + if (wkptr[0] == 0) retval = 0; + } else if (restrict_until == UNTIL_SHORTIS0) { + short *wkptr = (short *)user_disabled_data; + if (wkptr[0] == 0) retval = 0; + } else quit("loop_until: unknown until event"); + + return retval; +} + +static int UpdateWaitMode() { + if (restrict_until == 0) { + return RETURN_CONTINUE; + } + + restrict_until = ShouldStayInWaitMode(); + our_eip = 77; + + if (restrict_until != 0) { + return RETURN_CONTINUE; + } + + auto was_disabled_for = user_disabled_for; + + set_default_cursor(); + guis_need_update = 1; + play.disabled_user_interface--; + user_disabled_for = 0; + + switch (was_disabled_for) { + // case FOR_ANIMATION: + // run_animation((FullAnimation*)user_disabled_data2,user_disabled_data3); + // break; + case FOR_EXITLOOP: + return -1; + case FOR_SCRIPT: + quit("err: for_script obsolete (v2.1 and earlier only)"); + break; + default: + quit("Unknown user_disabled_for in end restrict_until"); + } + + // we shouldn't get here. + return RETURN_CONTINUE; } // Run single game iteration; calls UpdateGameOnce() internally -static int GameTick() -{ - if (displayed_room < 0) - quit("!A blocking function was called before the first room has been loaded"); +static int GameTick() { + if (displayed_room < 0) + quit("!A blocking function was called before the first room has been loaded"); - UpdateGameOnce(true); - UpdateMouseOverLocation(); + UpdateGameOnce(true); + UpdateMouseOverLocation(); - our_eip=76; + our_eip = 76; - int res = UpdateWaitMode(); - if (res == RETURN_CONTINUE) { return 0; } // continue looping - return res; + int res = UpdateWaitMode(); + if (res == RETURN_CONTINUE) { + return 0; // continue looping + } + return res; } -static void SetupLoopParameters(int untilwhat,const void* udata) { - play.disabled_user_interface++; - guis_need_update = 1; - // Only change the mouse cursor if it hasn't been specifically changed first - // (or if it's speech, always change it) - if (((cur_cursor == cur_mode) || (untilwhat == UNTIL_NOOVERLAY)) && - (cur_mode != CURS_WAIT)) - set_mouse_cursor(CURS_WAIT); - - restrict_until=untilwhat; - user_disabled_data=udata; - user_disabled_for=FOR_EXITLOOP; +static void SetupLoopParameters(int untilwhat, const void *udata) { + play.disabled_user_interface++; + guis_need_update = 1; + // Only change the mouse cursor if it hasn't been specifically changed first + // (or if it's speech, always change it) + if (((cur_cursor == cur_mode) || (untilwhat == UNTIL_NOOVERLAY)) && + (cur_mode != CURS_WAIT)) + set_mouse_cursor(CURS_WAIT); + + restrict_until = untilwhat; + user_disabled_data = udata; + user_disabled_for = FOR_EXITLOOP; } // This function is called from lot of various functions // in the game core, character, room object etc -static void GameLoopUntilEvent(int untilwhat,const void* daaa) { - // blocking cutscene - end skipping - EndSkippingUntilCharStops(); +static void GameLoopUntilEvent(int untilwhat, const void *daaa) { + // blocking cutscene - end skipping + EndSkippingUntilCharStops(); - // this function can get called in a nested context, so - // remember the state of these vars in case a higher level - // call needs them - auto cached_restrict_until = restrict_until; - auto cached_user_disabled_data = user_disabled_data; - auto cached_user_disabled_for = user_disabled_for; + // this function can get called in a nested context, so + // remember the state of these vars in case a higher level + // call needs them + auto cached_restrict_until = restrict_until; + auto cached_user_disabled_data = user_disabled_data; + auto cached_user_disabled_for = user_disabled_for; - SetupLoopParameters(untilwhat,daaa); - while (GameTick()==0); + SetupLoopParameters(untilwhat, daaa); + while (GameTick() == 0); - our_eip = 78; + our_eip = 78; - restrict_until = cached_restrict_until; - user_disabled_data = cached_user_disabled_data; - user_disabled_for = cached_user_disabled_for; + restrict_until = cached_restrict_until; + user_disabled_data = cached_user_disabled_data; + user_disabled_for = cached_user_disabled_for; } -void GameLoopUntilValueIsZero(const char *value) -{ - GameLoopUntilEvent(UNTIL_CHARIS0, value); +void GameLoopUntilValueIsZero(const char *value) { + GameLoopUntilEvent(UNTIL_CHARIS0, value); } -void GameLoopUntilValueIsZero(const short *value) -{ - GameLoopUntilEvent(UNTIL_SHORTIS0, value); +void GameLoopUntilValueIsZero(const short *value) { + GameLoopUntilEvent(UNTIL_SHORTIS0, value); } -void GameLoopUntilValueIsZero(const int *value) -{ - GameLoopUntilEvent(UNTIL_INTIS0, value); +void GameLoopUntilValueIsZero(const int *value) { + GameLoopUntilEvent(UNTIL_INTIS0, value); } -void GameLoopUntilValueIsZeroOrLess(const short *value) -{ - GameLoopUntilEvent(UNTIL_MOVEEND, value); +void GameLoopUntilValueIsZeroOrLess(const short *value) { + GameLoopUntilEvent(UNTIL_MOVEEND, value); } -void GameLoopUntilValueIsNegative(const short *value) -{ - GameLoopUntilEvent(UNTIL_NEGATIVE, value); +void GameLoopUntilValueIsNegative(const short *value) { + GameLoopUntilEvent(UNTIL_NEGATIVE, value); } -void GameLoopUntilValueIsNegative(const int *value) -{ - GameLoopUntilEvent(UNTIL_INTISNEG, value); +void GameLoopUntilValueIsNegative(const int *value) { + GameLoopUntilEvent(UNTIL_INTISNEG, value); } -void GameLoopUntilNotMoving(const short *move) -{ - GameLoopUntilEvent(UNTIL_MOVEEND, move); +void GameLoopUntilNotMoving(const short *move) { + GameLoopUntilEvent(UNTIL_MOVEEND, move); } -void GameLoopUntilNoOverlay() -{ - GameLoopUntilEvent(UNTIL_NOOVERLAY, 0); +void GameLoopUntilNoOverlay() { + GameLoopUntilEvent(UNTIL_NOOVERLAY, 0); } extern unsigned int load_new_game; -void RunGameUntilAborted() -{ - // skip ticks to account for time spent starting game. - skipMissedTicks(); - - while (!abort_engine) { - GameTick(); - - if (load_new_game) { - RunAGSGame (nullptr, load_new_game, 0); - load_new_game = 0; - } - } +void RunGameUntilAborted() { + // skip ticks to account for time spent starting game. + skipMissedTicks(); + + while (!abort_engine) { + GameTick(); + + if (load_new_game) { + RunAGSGame(nullptr, load_new_game, 0); + load_new_game = 0; + } + } } -void update_polled_stuff_if_runtime() -{ - if (want_exit) { - want_exit = 0; - quit("||exit!"); - } +void update_polled_stuff_if_runtime() { + if (want_exit) { + want_exit = 0; + quit("||exit!"); + } - update_polled_mp3(); + update_polled_mp3(); - if (editor_debugging_initialized) - check_for_messages_from_editor(); + if (editor_debugging_initialized) + check_for_messages_from_editor(); } diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h index 58ddaa6ddb2f..e2d8431e6f37 100644 --- a/engines/ags/engine/main/game_run.h +++ b/engines/ags/engine/main/game_run.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_MAIN_GAME_RUN_H #define AGS_ENGINE_MAIN_GAME_RUN_H -namespace AGS { namespace Engine { class IDriverDependantBitmap; }} +namespace AGS { +namespace Engine { +class IDriverDependantBitmap; +} +} using namespace AGS::Engine; // FIXME later // Loops game frames until certain event takes place (for blocking actions) diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 99e799948715..0b4c609c6b3c 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -54,114 +54,104 @@ extern GameState play; extern const char *loadSaveGameOnStartup; extern std::vector moduleInst; extern int numScriptModules; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern int convert_16bit_bgr; -void start_game_init_editor_debugging() -{ - if (editor_debugging_enabled) - { - SetMultitasking(1); - if (init_editor_debugging()) - { - auto waitUntil = AGS_Clock::now() + std::chrono::milliseconds(500); - while (waitUntil > AGS_Clock::now()) - { - // pick up any breakpoints in game_start - check_for_messages_from_editor(); - } - - ccSetDebugHook(scriptDebugHook); - } - } +void start_game_init_editor_debugging() { + if (editor_debugging_enabled) { + SetMultitasking(1); + if (init_editor_debugging()) { + auto waitUntil = AGS_Clock::now() + std::chrono::milliseconds(500); + while (waitUntil > AGS_Clock::now()) { + // pick up any breakpoints in game_start + check_for_messages_from_editor(); + } + + ccSetDebugHook(scriptDebugHook); + } + } } -void start_game_load_savegame_on_startup() -{ - if (loadSaveGameOnStartup != nullptr) - { - int saveGameNumber = 1000; - const char *sgName = strstr(loadSaveGameOnStartup, "agssave."); - if (sgName != nullptr) - { - sscanf(sgName, "agssave.%03d", &saveGameNumber); - } - current_fade_out_effect(); - try_restore_save(loadSaveGameOnStartup, saveGameNumber); - } +void start_game_load_savegame_on_startup() { + if (loadSaveGameOnStartup != nullptr) { + int saveGameNumber = 1000; + const char *sgName = strstr(loadSaveGameOnStartup, "agssave."); + if (sgName != nullptr) { + sscanf(sgName, "agssave.%03d", &saveGameNumber); + } + current_fade_out_effect(); + try_restore_save(loadSaveGameOnStartup, saveGameNumber); + } } void start_game() { - set_cursor_mode(MODE_WALK); - Mouse::SetPosition(Point(160, 100)); - newmusic(0); + set_cursor_mode(MODE_WALK); + Mouse::SetPosition(Point(160, 100)); + newmusic(0); - our_eip = -42; + our_eip = -42; - // skip ticks to account for initialisation or a restored game. - skipMissedTicks(); + // skip ticks to account for initialisation or a restored game. + skipMissedTicks(); - for (int kk = 0; kk < numScriptModules; kk++) - RunTextScript(moduleInst[kk], "game_start"); + for (int kk = 0; kk < numScriptModules; kk++) + RunTextScript(moduleInst[kk], "game_start"); - RunTextScript(gameinst, "game_start"); + RunTextScript(gameinst, "game_start"); - our_eip = -43; + our_eip = -43; - SetRestartPoint(); + SetRestartPoint(); - our_eip=-3; + our_eip = -3; - if (displayed_room < 0) { - current_fade_out_effect(); - load_new_room(playerchar->room,playerchar); - // load_new_room updates it, but it should be -1 in the first room - playerchar->prevroom = -1; - } + if (displayed_room < 0) { + current_fade_out_effect(); + load_new_room(playerchar->room, playerchar); + // load_new_room updates it, but it should be -1 in the first room + playerchar->prevroom = -1; + } - first_room_initialization(); + first_room_initialization(); } -void do_start_game() -{ - // only start if replay playback hasn't loaded a game - if (displayed_room < 0) - start_game(); +void do_start_game() { + // only start if replay playback hasn't loaded a game + if (displayed_room < 0) + start_game(); } -void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup) -{ - try { // BEGIN try for ALI3DEXception +void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup) { + try { // BEGIN try for ALI3DEXception - set_cursor_mode (MODE_WALK); + set_cursor_mode(MODE_WALK); - if (convert_16bit_bgr) { - // Disable text as speech while displaying the warning message - // This happens if the user's graphics card does BGR order 16-bit colour - int oldalways = game.options[OPT_ALWAYSSPCH]; - game.options[OPT_ALWAYSSPCH] = 0; - // PSP: This is normal. Don't show a warning. - //Display ("WARNING: AGS has detected that you have an incompatible graphics card for this game. You may experience colour problems during the game. Try running the game with \"--15bit\" command line parameter and see if that helps.[[Click the mouse to continue."); - game.options[OPT_ALWAYSSPCH] = oldalways; - } + if (convert_16bit_bgr) { + // Disable text as speech while displaying the warning message + // This happens if the user's graphics card does BGR order 16-bit colour + int oldalways = game.options[OPT_ALWAYSSPCH]; + game.options[OPT_ALWAYSSPCH] = 0; + // PSP: This is normal. Don't show a warning. + //Display ("WARNING: AGS has detected that you have an incompatible graphics card for this game. You may experience colour problems during the game. Try running the game with \"--15bit\" command line parameter and see if that helps.[[Click the mouse to continue."); + game.options[OPT_ALWAYSSPCH] = oldalways; + } - srand (play.randseed); - if (override_start_room) - playerchar->room = override_start_room; + srand(play.randseed); + if (override_start_room) + playerchar->room = override_start_room; - Debug::Printf(kDbgMsg_Info, "Engine initialization complete"); - Debug::Printf(kDbgMsg_Info, "Starting game"); + Debug::Printf(kDbgMsg_Info, "Engine initialization complete"); + Debug::Printf(kDbgMsg_Info, "Starting game"); - start_game_init_editor_debugging(); + start_game_init_editor_debugging(); - start_game_load_savegame_on_startup(); + start_game_load_savegame_on_startup(); - do_start_game(); + do_start_game(); - RunGameUntilAborted(); + RunGameUntilAborted(); - } catch (Ali3DException gfxException) - { - quit((char*)gfxException._message); - } + } catch (Ali3DException gfxException) { + quit((char *)gfxException._message); + } } diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp index e99adca30018..c99ac6096ced 100644 --- a/engines/ags/engine/main/graphics_mode.cpp +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -67,621 +67,566 @@ PlaneScaling GameScaling; GameFrameSetup::GameFrameSetup() - : ScaleDef(kFrame_IntScale) - , ScaleFactor(1) -{ + : ScaleDef(kFrame_IntScale) + , ScaleFactor(1) { } GameFrameSetup::GameFrameSetup(FrameScaleDefinition def, int factor) - : ScaleDef(def) - , ScaleFactor(factor) -{ + : ScaleDef(def) + , ScaleFactor(factor) { } -bool GameFrameSetup::IsValid() const -{ - return ScaleDef != kFrame_IntScale || ScaleFactor > 0; +bool GameFrameSetup::IsValid() const { + return ScaleDef != kFrame_IntScale || ScaleFactor > 0; } ScreenSizeSetup::ScreenSizeSetup() - : SizeDef(kScreenDef_MaxDisplay) - , MatchDeviceRatio(true) -{ + : SizeDef(kScreenDef_MaxDisplay) + , MatchDeviceRatio(true) { } DisplayModeSetup::DisplayModeSetup() - : RefreshRate(0) - , VSync(false) - , Windowed(false) -{ + : RefreshRate(0) + , VSync(false) + , Windowed(false) { } -Size get_desktop_size() -{ - Size sz; - get_desktop_resolution(&sz.Width, &sz.Height); - return sz; +Size get_desktop_size() { + Size sz; + get_desktop_resolution(&sz.Width, &sz.Height); + return sz; } -Size get_max_display_size(bool windowed) -{ - Size device_size = get_desktop_size(); - if (windowed) - platform->ValidateWindowSize(device_size.Width, device_size.Height, false); - return device_size; +Size get_max_display_size(bool windowed) { + Size device_size = get_desktop_size(); + if (windowed) + platform->ValidateWindowSize(device_size.Width, device_size.Height, false); + return device_size; } -bool create_gfx_driver(const String &gfx_driver_id) -{ - GfxFactory = GetGfxDriverFactory(gfx_driver_id); - if (!GfxFactory) - { - Debug::Printf(kDbgMsg_Error, "Failed to initialize %s graphics factory. Error: %s", gfx_driver_id.GetCStr(), get_allegro_error()); - return false; - } - Debug::Printf("Using graphics factory: %s", gfx_driver_id.GetCStr()); - gfxDriver = GfxFactory->GetDriver(); - if (!gfxDriver) - { - Debug::Printf(kDbgMsg_Error, "Failed to create graphics driver. Error: %s", get_allegro_error()); - return false; - } - Debug::Printf("Created graphics driver: %s", gfxDriver->GetDriverName()); - return true; +bool create_gfx_driver(const String &gfx_driver_id) { + GfxFactory = GetGfxDriverFactory(gfx_driver_id); + if (!GfxFactory) { + Debug::Printf(kDbgMsg_Error, "Failed to initialize %s graphics factory. Error: %s", gfx_driver_id.GetCStr(), get_allegro_error()); + return false; + } + Debug::Printf("Using graphics factory: %s", gfx_driver_id.GetCStr()); + gfxDriver = GfxFactory->GetDriver(); + if (!gfxDriver) { + Debug::Printf(kDbgMsg_Error, "Failed to create graphics driver. Error: %s", get_allegro_error()); + return false; + } + Debug::Printf("Created graphics driver: %s", gfxDriver->GetDriverName()); + return true; } // Set requested graphics filter, or default filter if the requested one failed -bool graphics_mode_set_filter_any(const GfxFilterSetup &setup) -{ - Debug::Printf("Requested gfx filter: %s", setup.UserRequest.GetCStr()); - if (!graphics_mode_set_filter(setup.ID)) - { - String def_filter = GfxFactory->GetDefaultFilterID(); - if (def_filter.CompareNoCase(setup.ID) == 0) - return false; - Debug::Printf(kDbgMsg_Error, "Failed to apply gfx filter: %s; will try to use factory default filter '%s' instead", - setup.UserRequest.GetCStr(), def_filter.GetCStr()); - if (!graphics_mode_set_filter(def_filter)) - return false; - } - Debug::Printf("Using gfx filter: %s", GfxFactory->GetDriver()->GetGraphicsFilter()->GetInfo().Id.GetCStr()); - return true; +bool graphics_mode_set_filter_any(const GfxFilterSetup &setup) { + Debug::Printf("Requested gfx filter: %s", setup.UserRequest.GetCStr()); + if (!graphics_mode_set_filter(setup.ID)) { + String def_filter = GfxFactory->GetDefaultFilterID(); + if (def_filter.CompareNoCase(setup.ID) == 0) + return false; + Debug::Printf(kDbgMsg_Error, "Failed to apply gfx filter: %s; will try to use factory default filter '%s' instead", + setup.UserRequest.GetCStr(), def_filter.GetCStr()); + if (!graphics_mode_set_filter(def_filter)) + return false; + } + Debug::Printf("Using gfx filter: %s", GfxFactory->GetDriver()->GetGraphicsFilter()->GetInfo().Id.GetCStr()); + return true; } bool find_nearest_supported_mode(const IGfxModeList &modes, const Size &wanted_size, const int color_depth, - const Size *ratio_reference, const Size *upper_bound, DisplayMode &dm, int *mode_index) -{ - uint32_t wanted_ratio = 0; - if (ratio_reference && !ratio_reference->IsNull()) - { - wanted_ratio = (ratio_reference->Height << kShift) / ratio_reference->Width; - } - - int nearest_width = 0; - int nearest_height = 0; - int nearest_width_diff = 0; - int nearest_height_diff = 0; - DisplayMode nearest_mode; - int nearest_mode_index = -1; - int mode_count = modes.GetModeCount(); - for (int i = 0; i < mode_count; ++i) - { - DisplayMode mode; - if (!modes.GetMode(i, mode)) - { - continue; - } - if (mode.ColorDepth != color_depth) - { - continue; - } - if (wanted_ratio > 0) - { - uint32_t mode_ratio = (mode.Height << kShift) / mode.Width; - if (mode_ratio != wanted_ratio) - { - continue; - } - } - if (upper_bound && (mode.Width > upper_bound->Width || mode.Height > upper_bound->Height)) - continue; - if (mode.Width == wanted_size.Width && mode.Height == wanted_size.Height) - { - nearest_width = mode.Width; - nearest_height = mode.Height; - nearest_mode_index = i; - nearest_mode = mode; - break; - } - - int diff_w = abs(wanted_size.Width - mode.Width); - int diff_h = abs(wanted_size.Height - mode.Height); - bool same_diff_w_higher = (diff_w == nearest_width_diff && nearest_width < wanted_size.Width); - bool same_diff_h_higher = (diff_h == nearest_height_diff && nearest_height < wanted_size.Height); - - if (nearest_width == 0 || - ((diff_w < nearest_width_diff || same_diff_w_higher) && diff_h <= nearest_height_diff) || - ((diff_h < nearest_height_diff || same_diff_h_higher) && diff_w <= nearest_width_diff)) - { - nearest_width = mode.Width; - nearest_width_diff = diff_w; - nearest_height = mode.Height; - nearest_height_diff = diff_h; - nearest_mode = mode; - nearest_mode_index = i; - } - } - - if (nearest_width > 0 && nearest_height > 0) - { - dm = nearest_mode; - if (mode_index) - *mode_index = nearest_mode_index; - return true; - } - return false; + const Size *ratio_reference, const Size *upper_bound, DisplayMode &dm, int *mode_index) { + uint32_t wanted_ratio = 0; + if (ratio_reference && !ratio_reference->IsNull()) { + wanted_ratio = (ratio_reference->Height << kShift) / ratio_reference->Width; + } + + int nearest_width = 0; + int nearest_height = 0; + int nearest_width_diff = 0; + int nearest_height_diff = 0; + DisplayMode nearest_mode; + int nearest_mode_index = -1; + int mode_count = modes.GetModeCount(); + for (int i = 0; i < mode_count; ++i) { + DisplayMode mode; + if (!modes.GetMode(i, mode)) { + continue; + } + if (mode.ColorDepth != color_depth) { + continue; + } + if (wanted_ratio > 0) { + uint32_t mode_ratio = (mode.Height << kShift) / mode.Width; + if (mode_ratio != wanted_ratio) { + continue; + } + } + if (upper_bound && (mode.Width > upper_bound->Width || mode.Height > upper_bound->Height)) + continue; + if (mode.Width == wanted_size.Width && mode.Height == wanted_size.Height) { + nearest_width = mode.Width; + nearest_height = mode.Height; + nearest_mode_index = i; + nearest_mode = mode; + break; + } + + int diff_w = abs(wanted_size.Width - mode.Width); + int diff_h = abs(wanted_size.Height - mode.Height); + bool same_diff_w_higher = (diff_w == nearest_width_diff && nearest_width < wanted_size.Width); + bool same_diff_h_higher = (diff_h == nearest_height_diff && nearest_height < wanted_size.Height); + + if (nearest_width == 0 || + ((diff_w < nearest_width_diff || same_diff_w_higher) && diff_h <= nearest_height_diff) || + ((diff_h < nearest_height_diff || same_diff_h_higher) && diff_w <= nearest_width_diff)) { + nearest_width = mode.Width; + nearest_width_diff = diff_w; + nearest_height = mode.Height; + nearest_height_diff = diff_h; + nearest_mode = mode; + nearest_mode_index = i; + } + } + + if (nearest_width > 0 && nearest_height > 0) { + dm = nearest_mode; + if (mode_index) + *mode_index = nearest_mode_index; + return true; + } + return false; } -Size set_game_frame_after_screen_size(const Size &game_size, const Size screen_size, const GameFrameSetup &setup) -{ - // Set game frame as native game resolution scaled by particular method - Size frame_size; - if (setup.ScaleDef == kFrame_MaxStretch) - { - frame_size = screen_size; - } - else if (setup.ScaleDef == kFrame_MaxProportional) - { - frame_size = ProportionalStretch(screen_size, game_size); - } - else - { - int scale; - if (setup.ScaleDef == kFrame_MaxRound) - scale = Math::Min((screen_size.Width / game_size.Width) << kShift, - (screen_size.Height / game_size.Height) << kShift); - else - scale = convert_scaling_to_fp(setup.ScaleFactor); - - // Ensure scaling factors are sane - if (scale <= 0) - scale = kUnit; - - frame_size = Size((game_size.Width * scale) >> kShift, (game_size.Height * scale) >> kShift); - // If the scaled game size appear larger than the screen, - // use "proportional stretch" method instead - if (frame_size.ExceedsByAny(screen_size)) - frame_size = ProportionalStretch(screen_size, game_size); - } - return frame_size; +Size set_game_frame_after_screen_size(const Size &game_size, const Size screen_size, const GameFrameSetup &setup) { + // Set game frame as native game resolution scaled by particular method + Size frame_size; + if (setup.ScaleDef == kFrame_MaxStretch) { + frame_size = screen_size; + } else if (setup.ScaleDef == kFrame_MaxProportional) { + frame_size = ProportionalStretch(screen_size, game_size); + } else { + int scale; + if (setup.ScaleDef == kFrame_MaxRound) + scale = Math::Min((screen_size.Width / game_size.Width) << kShift, + (screen_size.Height / game_size.Height) << kShift); + else + scale = convert_scaling_to_fp(setup.ScaleFactor); + + // Ensure scaling factors are sane + if (scale <= 0) + scale = kUnit; + + frame_size = Size((game_size.Width * scale) >> kShift, (game_size.Height * scale) >> kShift); + // If the scaled game size appear larger than the screen, + // use "proportional stretch" method instead + if (frame_size.ExceedsByAny(screen_size)) + frame_size = ProportionalStretch(screen_size, game_size); + } + return frame_size; } -Size precalc_screen_size(const Size &game_size, const DisplayModeSetup &dm_setup, const GameFrameSetup &frame_setup) -{ - Size screen_size, frame_size; - Size device_size = get_max_display_size(dm_setup.Windowed); - - // Set requested screen (window) size, depending on screen definition option - ScreenSizeSetup scsz = dm_setup.ScreenSize; - switch (scsz.SizeDef) - { - case kScreenDef_Explicit: - // Use resolution from user config - screen_size = scsz.Size; - if (screen_size.IsNull()) - { - // If the configuration did not define proper screen size, - // use the scaled game size instead - frame_size = set_game_frame_after_screen_size(game_size, device_size, frame_setup); - if (screen_size.Width <= 0) - screen_size.Width = frame_size.Width; - if (screen_size.Height <= 0) - screen_size.Height = frame_size.Height; - } - break; - case kScreenDef_ByGameScaling: - // Use game frame (scaled game) size - frame_size = set_game_frame_after_screen_size(game_size, device_size, frame_setup); - screen_size = frame_size; - break; - case kScreenDef_MaxDisplay: - // Set as big as current device size - screen_size = device_size; - break; - } - return screen_size; +Size precalc_screen_size(const Size &game_size, const DisplayModeSetup &dm_setup, const GameFrameSetup &frame_setup) { + Size screen_size, frame_size; + Size device_size = get_max_display_size(dm_setup.Windowed); + + // Set requested screen (window) size, depending on screen definition option + ScreenSizeSetup scsz = dm_setup.ScreenSize; + switch (scsz.SizeDef) { + case kScreenDef_Explicit: + // Use resolution from user config + screen_size = scsz.Size; + if (screen_size.IsNull()) { + // If the configuration did not define proper screen size, + // use the scaled game size instead + frame_size = set_game_frame_after_screen_size(game_size, device_size, frame_setup); + if (screen_size.Width <= 0) + screen_size.Width = frame_size.Width; + if (screen_size.Height <= 0) + screen_size.Height = frame_size.Height; + } + break; + case kScreenDef_ByGameScaling: + // Use game frame (scaled game) size + frame_size = set_game_frame_after_screen_size(game_size, device_size, frame_setup); + screen_size = frame_size; + break; + case kScreenDef_MaxDisplay: + // Set as big as current device size + screen_size = device_size; + break; + } + return screen_size; } // Find closest possible compatible display mode and initialize it -bool try_init_compatible_mode(const DisplayMode &dm, const bool match_device_ratio) -{ - const Size &screen_size = Size(dm.Width, dm.Height); - // Find nearest compatible mode and init that - Debug::Printf("Attempting to find nearest supported resolution for screen size %d x %d (%d-bit) %s", - dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); - const Size device_size = get_max_display_size(dm.Windowed); - if (dm.Windowed) - Debug::Printf("Maximal allowed window size: %d x %d", device_size.Width, device_size.Height); - DisplayMode dm_compat = dm; - - std::unique_ptr modes(gfxDriver->GetSupportedModeList(dm.ColorDepth)); // TODO: use unique_ptr when available - - // Windowed mode - if (dm.Windowed) - { - // If windowed mode, make the resolution stay in the generally supported limits - dm_compat.Width = Math::Min(dm_compat.Width, device_size.Width); - dm_compat.Height = Math::Min(dm_compat.Height, device_size.Height); - } - // Fullscreen mode - else - { - // If told to find mode with aspect ratio matching current desktop resolution, then first - // try find matching one, and if failed then try any compatible one - bool mode_found = false; - if (modes.get()) - { - if (match_device_ratio) - mode_found = find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, &device_size, nullptr, dm_compat); - if (!mode_found) - mode_found = find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, nullptr, nullptr, dm_compat); - } - if (!mode_found) - Debug::Printf("Could not find compatible fullscreen mode. Will try to force-set mode requested by user and fallback to windowed mode if that fails."); - dm_compat.Vsync = dm.Vsync; - dm_compat.Windowed = false; - } - - bool result = graphics_mode_set_dm(dm_compat); - if (!result && dm.Windowed) - { - // When initializing windowed mode we could start with any random window size; - // if that did not work, try to find nearest supported mode, as with fullscreen mode, - // except refering to max window size as an upper bound - if (find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, nullptr, &device_size, dm_compat)) - { - dm_compat.Vsync = dm.Vsync; - dm_compat.Windowed = true; - result = graphics_mode_set_dm(dm_compat); - } - } - return result; +bool try_init_compatible_mode(const DisplayMode &dm, const bool match_device_ratio) { + const Size &screen_size = Size(dm.Width, dm.Height); + // Find nearest compatible mode and init that + Debug::Printf("Attempting to find nearest supported resolution for screen size %d x %d (%d-bit) %s", + dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); + const Size device_size = get_max_display_size(dm.Windowed); + if (dm.Windowed) + Debug::Printf("Maximal allowed window size: %d x %d", device_size.Width, device_size.Height); + DisplayMode dm_compat = dm; + + std::unique_ptr modes(gfxDriver->GetSupportedModeList(dm.ColorDepth)); // TODO: use unique_ptr when available + + // Windowed mode + if (dm.Windowed) { + // If windowed mode, make the resolution stay in the generally supported limits + dm_compat.Width = Math::Min(dm_compat.Width, device_size.Width); + dm_compat.Height = Math::Min(dm_compat.Height, device_size.Height); + } + // Fullscreen mode + else { + // If told to find mode with aspect ratio matching current desktop resolution, then first + // try find matching one, and if failed then try any compatible one + bool mode_found = false; + if (modes.get()) { + if (match_device_ratio) + mode_found = find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, &device_size, nullptr, dm_compat); + if (!mode_found) + mode_found = find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, nullptr, nullptr, dm_compat); + } + if (!mode_found) + Debug::Printf("Could not find compatible fullscreen mode. Will try to force-set mode requested by user and fallback to windowed mode if that fails."); + dm_compat.Vsync = dm.Vsync; + dm_compat.Windowed = false; + } + + bool result = graphics_mode_set_dm(dm_compat); + if (!result && dm.Windowed) { + // When initializing windowed mode we could start with any random window size; + // if that did not work, try to find nearest supported mode, as with fullscreen mode, + // except refering to max window size as an upper bound + if (find_nearest_supported_mode(*modes.get(), screen_size, dm.ColorDepth, nullptr, &device_size, dm_compat)) { + dm_compat.Vsync = dm.Vsync; + dm_compat.Windowed = true; + result = graphics_mode_set_dm(dm_compat); + } + } + return result; } // Try to find and initialize compatible display mode as close to given setup as possible bool try_init_mode_using_setup(const Size &game_size, const DisplayModeSetup &dm_setup, const int col_depth, const GameFrameSetup &frame_setup, - const GfxFilterSetup &filter_setup) -{ - // We determine the requested size of the screen using setup options - const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); - DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, col_depth), - dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); - if (!try_init_compatible_mode(dm, dm_setup.ScreenSize.SizeDef == kScreenDef_Explicit ? false : dm_setup.ScreenSize.MatchDeviceRatio)) - return false; - - // Set up native size and render frame - if (!graphics_mode_set_native_size(game_size) || !graphics_mode_set_render_frame(frame_setup)) - return false; - - // Set up graphics filter - if (!graphics_mode_set_filter_any(filter_setup)) - return false; - return true; + const GfxFilterSetup &filter_setup) { + // We determine the requested size of the screen using setup options + const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); + DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, col_depth), + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + if (!try_init_compatible_mode(dm, dm_setup.ScreenSize.SizeDef == kScreenDef_Explicit ? false : dm_setup.ScreenSize.MatchDeviceRatio)) + return false; + + // Set up native size and render frame + if (!graphics_mode_set_native_size(game_size) || !graphics_mode_set_render_frame(frame_setup)) + return false; + + // Set up graphics filter + if (!graphics_mode_set_filter_any(filter_setup)) + return false; + return true; } -void log_out_driver_modes(const int color_depth) -{ - IGfxModeList *modes = gfxDriver->GetSupportedModeList(color_depth); - if (!modes) - { - Debug::Printf(kDbgMsg_Error, "Couldn't get a list of supported resolutions for color depth = %d", color_depth); - return; - } - const int mode_count = modes->GetModeCount(); - DisplayMode mode; - String mode_str; - for (int i = 0, in_str = 0; i < mode_count; ++i) - { - if (!modes->GetMode(i, mode) || mode.ColorDepth != color_depth) - continue; - mode_str.Append(String::FromFormat("%dx%d;", mode.Width, mode.Height)); - if (++in_str % 8 == 0) - mode_str.Append("\n\t"); - } - delete modes; - - String out_str = String::FromFormat("Supported gfx modes (%d-bit): ", color_depth); - if (!mode_str.IsEmpty()) - { - out_str.Append("\n\t"); - out_str.Append(mode_str); - } - else - out_str.Append("none"); - Debug::Printf(out_str); +void log_out_driver_modes(const int color_depth) { + IGfxModeList *modes = gfxDriver->GetSupportedModeList(color_depth); + if (!modes) { + Debug::Printf(kDbgMsg_Error, "Couldn't get a list of supported resolutions for color depth = %d", color_depth); + return; + } + const int mode_count = modes->GetModeCount(); + DisplayMode mode; + String mode_str; + for (int i = 0, in_str = 0; i < mode_count; ++i) { + if (!modes->GetMode(i, mode) || mode.ColorDepth != color_depth) + continue; + mode_str.Append(String::FromFormat("%dx%d;", mode.Width, mode.Height)); + if (++in_str % 8 == 0) + mode_str.Append("\n\t"); + } + delete modes; + + String out_str = String::FromFormat("Supported gfx modes (%d-bit): ", color_depth); + if (!mode_str.IsEmpty()) { + out_str.Append("\n\t"); + out_str.Append(mode_str); + } else + out_str.Append("none"); + Debug::Printf(out_str); } // Create requested graphics driver and try to find and initialize compatible display mode as close to user setup as possible; // if the given setup fails, gets default setup for the opposite type of mode (fullscreen/windowed) and tries that instead. bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id, const Size &game_size, const DisplayModeSetup &dm_setup, - const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup, const GfxFilterSetup &filter_setup) -{ - if (!graphics_mode_create_renderer(gfx_driver_id)) - return false; - - const int use_col_depth = - color_depth.Forced ? color_depth.Bits : gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); - // Log out supported driver modes - log_out_driver_modes(use_col_depth); - - bool result = try_init_mode_using_setup(game_size, dm_setup, use_col_depth, frame_setup, filter_setup); - // Try windowed mode if fullscreen failed, and vice versa - if (!result && editor_debugging_enabled == 0) - { - // we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults() - DisplayModeSetup dm_setup_alt = dm_setup; - dm_setup_alt.Windowed = !dm_setup.Windowed; - GameFrameSetup frame_setup_alt; - graphics_mode_get_defaults(dm_setup_alt.Windowed, dm_setup_alt.ScreenSize, frame_setup_alt); - result = try_init_mode_using_setup(game_size, dm_setup_alt, use_col_depth, frame_setup_alt, filter_setup); - } - return result; + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup, const GfxFilterSetup &filter_setup) { + if (!graphics_mode_create_renderer(gfx_driver_id)) + return false; + + const int use_col_depth = + color_depth.Forced ? color_depth.Bits : gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); + // Log out supported driver modes + log_out_driver_modes(use_col_depth); + + bool result = try_init_mode_using_setup(game_size, dm_setup, use_col_depth, frame_setup, filter_setup); + // Try windowed mode if fullscreen failed, and vice versa + if (!result && editor_debugging_enabled == 0) { + // we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults() + DisplayModeSetup dm_setup_alt = dm_setup; + dm_setup_alt.Windowed = !dm_setup.Windowed; + GameFrameSetup frame_setup_alt; + graphics_mode_get_defaults(dm_setup_alt.Windowed, dm_setup_alt.ScreenSize, frame_setup_alt); + result = try_init_mode_using_setup(game_size, dm_setup_alt, use_col_depth, frame_setup_alt, filter_setup); + } + return result; } bool simple_create_gfx_driver_and_init_mode(const String &gfx_driver_id, - const Size &game_size, - const DisplayModeSetup &dm_setup, - const ColorDepthOption &color_depth, - const GameFrameSetup &frame_setup, - const GfxFilterSetup &filter_setup) -{ - if (!graphics_mode_create_renderer(gfx_driver_id)) { return false; } - - const int col_depth = gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); - - DisplayMode dm(GraphicResolution(game_size.Width, game_size.Height, col_depth), - dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); - - if (!graphics_mode_set_dm(dm)) { return false; } - if (!graphics_mode_set_native_size(game_size)) { return false; } - if (!graphics_mode_set_render_frame(frame_setup)) { return false; } - if (!graphics_mode_set_filter_any(filter_setup)) { return false; } - - return true; + const Size &game_size, + const DisplayModeSetup &dm_setup, + const ColorDepthOption &color_depth, + const GameFrameSetup &frame_setup, + const GfxFilterSetup &filter_setup) { + if (!graphics_mode_create_renderer(gfx_driver_id)) { + return false; + } + + const int col_depth = gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); + + DisplayMode dm(GraphicResolution(game_size.Width, game_size.Height, col_depth), + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + + if (!graphics_mode_set_dm(dm)) { + return false; + } + if (!graphics_mode_set_native_size(game_size)) { + return false; + } + if (!graphics_mode_set_render_frame(frame_setup)) { + return false; + } + if (!graphics_mode_set_filter_any(filter_setup)) { + return false; + } + + return true; } -void display_gfx_mode_error(const Size &game_size, const ScreenSetup &setup, const int color_depth) -{ - proper_exit=1; - platform->FinishedUsingGraphicsMode(); - - String main_error; - ScreenSizeSetup scsz = setup.DisplayMode.ScreenSize; - PGfxFilter filter = gfxDriver ? gfxDriver->GetGraphicsFilter() : PGfxFilter(); - Size wanted_screen; - if (scsz.SizeDef == kScreenDef_Explicit) - main_error.Format("There was a problem initializing graphics mode %d x %d (%d-bit), or finding nearest compatible mode, with game size %d x %d and filter '%s'.", - scsz.Size.Width, scsz.Size.Height, color_depth, game_size.Width, game_size.Height, filter ? filter->GetInfo().Id.GetCStr() : "Undefined"); - else - main_error.Format("There was a problem finding and/or creating valid graphics mode for game size %d x %d (%d-bit) and requested filter '%s'.", - game_size.Width, game_size.Height, color_depth, setup.Filter.UserRequest.IsEmpty() ? "Undefined" : setup.Filter.UserRequest.GetCStr()); - - platform->DisplayAlert("%s\n" - "(Problem: '%s')\n" - "Try to correct the problem, or seek help from the AGS homepage." - "%s", - main_error.GetCStr(), get_allegro_error(), platform->GetGraphicsTroubleshootingText()); +void display_gfx_mode_error(const Size &game_size, const ScreenSetup &setup, const int color_depth) { + proper_exit = 1; + platform->FinishedUsingGraphicsMode(); + + String main_error; + ScreenSizeSetup scsz = setup.DisplayMode.ScreenSize; + PGfxFilter filter = gfxDriver ? gfxDriver->GetGraphicsFilter() : PGfxFilter(); + Size wanted_screen; + if (scsz.SizeDef == kScreenDef_Explicit) + main_error.Format("There was a problem initializing graphics mode %d x %d (%d-bit), or finding nearest compatible mode, with game size %d x %d and filter '%s'.", + scsz.Size.Width, scsz.Size.Height, color_depth, game_size.Width, game_size.Height, filter ? filter->GetInfo().Id.GetCStr() : "Undefined"); + else + main_error.Format("There was a problem finding and/or creating valid graphics mode for game size %d x %d (%d-bit) and requested filter '%s'.", + game_size.Width, game_size.Height, color_depth, setup.Filter.UserRequest.IsEmpty() ? "Undefined" : setup.Filter.UserRequest.GetCStr()); + + platform->DisplayAlert("%s\n" + "(Problem: '%s')\n" + "Try to correct the problem, or seek help from the AGS homepage." + "%s", + main_error.GetCStr(), get_allegro_error(), platform->GetGraphicsTroubleshootingText()); } -bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, const ColorDepthOption &color_depth) -{ - // Log out display information - Size device_size; - if (get_desktop_resolution(&device_size.Width, &device_size.Height) == 0) - Debug::Printf("Device display resolution: %d x %d", device_size.Width, device_size.Height); - else - Debug::Printf(kDbgMsg_Error, "Unable to obtain device resolution"); - - const char *screen_sz_def_options[kNumScreenDef] = { "explicit", "scaling", "max" }; - ScreenSizeSetup scsz = setup.DisplayMode.ScreenSize; - const bool ignore_device_ratio = setup.DisplayMode.Windowed || scsz.SizeDef == kScreenDef_Explicit; - GameFrameSetup gameframe = setup.DisplayMode.Windowed ? setup.WinGameFrame : setup.FsGameFrame; - const String scale_option = make_scaling_option(gameframe); - Debug::Printf(kDbgMsg_Info, "Graphic settings: driver: %s, windowed: %s, screen def: %s, screen size: %d x %d, match device ratio: %s, game scale: %s", - setup.DriverID.GetCStr(), - setup.DisplayMode.Windowed ? "yes" : "no", screen_sz_def_options[scsz.SizeDef], - scsz.Size.Width, scsz.Size.Height, - ignore_device_ratio ? "ignore" : (scsz.MatchDeviceRatio ? "yes" : "no"), scale_option.GetCStr()); - - // Prepare the list of available gfx factories, having the one requested by user at first place - // TODO: make factory & driver IDs case-insensitive! - StringV ids; - GetGfxDriverFactoryNames(ids); - StringV::iterator it = ids.begin(); - for (; it != ids.end(); ++it) - { - if (it->CompareNoCase(setup.DriverID) == 0) break; - } - if (it != ids.end()) - std::rotate(ids.begin(), it, ids.end()); - else - Debug::Printf(kDbgMsg_Error, "Requested graphics driver '%s' not found, will try existing drivers instead", setup.DriverID.GetCStr()); - - // Try to create renderer and init gfx mode, choosing one factory at a time - bool result = false; - for (StringV::const_iterator it = ids.begin(); it != ids.end(); ++it) - { - result = +bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, const ColorDepthOption &color_depth) { + // Log out display information + Size device_size; + if (get_desktop_resolution(&device_size.Width, &device_size.Height) == 0) + Debug::Printf("Device display resolution: %d x %d", device_size.Width, device_size.Height); + else + Debug::Printf(kDbgMsg_Error, "Unable to obtain device resolution"); + + const char *screen_sz_def_options[kNumScreenDef] = { "explicit", "scaling", "max" }; + ScreenSizeSetup scsz = setup.DisplayMode.ScreenSize; + const bool ignore_device_ratio = setup.DisplayMode.Windowed || scsz.SizeDef == kScreenDef_Explicit; + GameFrameSetup gameframe = setup.DisplayMode.Windowed ? setup.WinGameFrame : setup.FsGameFrame; + const String scale_option = make_scaling_option(gameframe); + Debug::Printf(kDbgMsg_Info, "Graphic settings: driver: %s, windowed: %s, screen def: %s, screen size: %d x %d, match device ratio: %s, game scale: %s", + setup.DriverID.GetCStr(), + setup.DisplayMode.Windowed ? "yes" : "no", screen_sz_def_options[scsz.SizeDef], + scsz.Size.Width, scsz.Size.Height, + ignore_device_ratio ? "ignore" : (scsz.MatchDeviceRatio ? "yes" : "no"), scale_option.GetCStr()); + + // Prepare the list of available gfx factories, having the one requested by user at first place + // TODO: make factory & driver IDs case-insensitive! + StringV ids; + GetGfxDriverFactoryNames(ids); + StringV::iterator it = ids.begin(); + for (; it != ids.end(); ++it) { + if (it->CompareNoCase(setup.DriverID) == 0) break; + } + if (it != ids.end()) + std::rotate(ids.begin(), it, ids.end()); + else + Debug::Printf(kDbgMsg_Error, "Requested graphics driver '%s' not found, will try existing drivers instead", setup.DriverID.GetCStr()); + + // Try to create renderer and init gfx mode, choosing one factory at a time + bool result = false; + for (StringV::const_iterator it = ids.begin(); it != ids.end(); ++it) { + result = #ifdef USE_SIMPLE_GFX_INIT - simple_create_gfx_driver_and_init_mode + simple_create_gfx_driver_and_init_mode #else - create_gfx_driver_and_init_mode_any + create_gfx_driver_and_init_mode_any #endif - (*it, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter); - - if (result) - break; - graphics_mode_shutdown(); - } - // If all possibilities failed, display error message and quit - if (!result) - { - display_gfx_mode_error(game_size, setup, color_depth.Bits); - return false; - } - return true; + (*it, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter); + + if (result) + break; + graphics_mode_shutdown(); + } + // If all possibilities failed, display error message and quit + if (!result) { + display_gfx_mode_error(game_size, setup, color_depth.Bits); + return false; + } + return true; } -ActiveDisplaySetting graphics_mode_get_last_setting(bool windowed) -{ - return windowed ? SavedWindowedSetting : SavedFullscreenSetting; +ActiveDisplaySetting graphics_mode_get_last_setting(bool windowed) { + return windowed ? SavedWindowedSetting : SavedFullscreenSetting; } bool graphics_mode_update_render_frame(); -void GfxDriverOnSurfaceUpdate() -{ - // Resize render frame using current scaling settings - graphics_mode_update_render_frame(); - on_coordinates_scaling_changed(); +void GfxDriverOnSurfaceUpdate() { + // Resize render frame using current scaling settings + graphics_mode_update_render_frame(); + on_coordinates_scaling_changed(); } -bool graphics_mode_create_renderer(const String &driver_id) -{ - if (!create_gfx_driver(driver_id)) - return false; - - gfxDriver->SetCallbackOnInit(GfxDriverOnInitCallback); - gfxDriver->SetCallbackOnSurfaceUpdate(GfxDriverOnSurfaceUpdate); - // TODO: this is remains of the old code; find out if this is really - // the best time and place to set the tint method - gfxDriver->SetTintMethod(TintReColourise); - return true; +bool graphics_mode_create_renderer(const String &driver_id) { + if (!create_gfx_driver(driver_id)) + return false; + + gfxDriver->SetCallbackOnInit(GfxDriverOnInitCallback); + gfxDriver->SetCallbackOnSurfaceUpdate(GfxDriverOnSurfaceUpdate); + // TODO: this is remains of the old code; find out if this is really + // the best time and place to set the tint method + gfxDriver->SetTintMethod(TintReColourise); + return true; } bool graphics_mode_set_dm_any(const Size &game_size, const DisplayModeSetup &dm_setup, - const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup) -{ - // We determine the requested size of the screen using setup options - const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); - DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, color_depth.Bits), - dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); - return try_init_compatible_mode(dm, dm_setup.ScreenSize.MatchDeviceRatio); + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup) { + // We determine the requested size of the screen using setup options + const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); + DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, color_depth.Bits), + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + return try_init_compatible_mode(dm, dm_setup.ScreenSize.MatchDeviceRatio); } -bool graphics_mode_set_dm(const DisplayMode &dm) -{ - Debug::Printf("Attempt to switch gfx mode to %d x %d (%d-bit) %s", - dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); - - // Tell Allegro new default bitmap color depth (must be done before set_gfx_mode) - // TODO: this is also done inside ALSoftwareGraphicsDriver implementation; can remove one? - set_color_depth(dm.ColorDepth); - // TODO: this is remains of the old code; find out what it means and do we - // need this if we are not using allegro software driver? - if (dm.RefreshRate >= 50) - request_refresh_rate(dm.RefreshRate); - - if (!gfxDriver->SetDisplayMode(dm, nullptr)) - { - Debug::Printf(kDbgMsg_Error, "Failed to init gfx mode. Error: %s", get_allegro_error()); - return false; - } - - DisplayMode rdm = gfxDriver->GetDisplayMode(); - if (rdm.Windowed) - SavedWindowedSetting.Dm = rdm; - else - SavedFullscreenSetting.Dm = rdm; - Debug::Printf("Succeeded. Using gfx mode %d x %d (%d-bit) %s", - rdm.Width, rdm.Height, rdm.ColorDepth, rdm.Windowed ? "windowed" : "fullscreen"); - return true; +bool graphics_mode_set_dm(const DisplayMode &dm) { + Debug::Printf("Attempt to switch gfx mode to %d x %d (%d-bit) %s", + dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); + + // Tell Allegro new default bitmap color depth (must be done before set_gfx_mode) + // TODO: this is also done inside ALSoftwareGraphicsDriver implementation; can remove one? + set_color_depth(dm.ColorDepth); + // TODO: this is remains of the old code; find out what it means and do we + // need this if we are not using allegro software driver? + if (dm.RefreshRate >= 50) + request_refresh_rate(dm.RefreshRate); + + if (!gfxDriver->SetDisplayMode(dm, nullptr)) { + Debug::Printf(kDbgMsg_Error, "Failed to init gfx mode. Error: %s", get_allegro_error()); + return false; + } + + DisplayMode rdm = gfxDriver->GetDisplayMode(); + if (rdm.Windowed) + SavedWindowedSetting.Dm = rdm; + else + SavedFullscreenSetting.Dm = rdm; + Debug::Printf("Succeeded. Using gfx mode %d x %d (%d-bit) %s", + rdm.Width, rdm.Height, rdm.ColorDepth, rdm.Windowed ? "windowed" : "fullscreen"); + return true; } -bool graphics_mode_update_render_frame() -{ - if (!gfxDriver || !gfxDriver->IsModeSet() || !gfxDriver->IsNativeSizeValid()) - return false; - - DisplayMode dm = gfxDriver->GetDisplayMode(); - Size screen_size = Size(dm.Width, dm.Height); - Size native_size = gfxDriver->GetNativeSize(); - Size frame_size = set_game_frame_after_screen_size(native_size, screen_size, CurFrameSetup); - Rect render_frame = CenterInRect(RectWH(screen_size), RectWH(frame_size)); - - if (!gfxDriver->SetRenderFrame(render_frame)) - { - Debug::Printf(kDbgMsg_Error, "Failed to set render frame (%d, %d, %d, %d : %d x %d). Error: %s", - render_frame.Left, render_frame.Top, render_frame.Right, render_frame.Bottom, - render_frame.GetWidth(), render_frame.GetHeight(), get_allegro_error()); - return false; - } - - Rect dst_rect = gfxDriver->GetRenderDestination(); - Debug::Printf("Render frame set, render dest (%d, %d, %d, %d : %d x %d)", - dst_rect.Left, dst_rect.Top, dst_rect.Right, dst_rect.Bottom, dst_rect.GetWidth(), dst_rect.GetHeight()); - // init game scaling transformation - GameScaling.Init(native_size, gfxDriver->GetRenderDestination()); - return true; +bool graphics_mode_update_render_frame() { + if (!gfxDriver || !gfxDriver->IsModeSet() || !gfxDriver->IsNativeSizeValid()) + return false; + + DisplayMode dm = gfxDriver->GetDisplayMode(); + Size screen_size = Size(dm.Width, dm.Height); + Size native_size = gfxDriver->GetNativeSize(); + Size frame_size = set_game_frame_after_screen_size(native_size, screen_size, CurFrameSetup); + Rect render_frame = CenterInRect(RectWH(screen_size), RectWH(frame_size)); + + if (!gfxDriver->SetRenderFrame(render_frame)) { + Debug::Printf(kDbgMsg_Error, "Failed to set render frame (%d, %d, %d, %d : %d x %d). Error: %s", + render_frame.Left, render_frame.Top, render_frame.Right, render_frame.Bottom, + render_frame.GetWidth(), render_frame.GetHeight(), get_allegro_error()); + return false; + } + + Rect dst_rect = gfxDriver->GetRenderDestination(); + Debug::Printf("Render frame set, render dest (%d, %d, %d, %d : %d x %d)", + dst_rect.Left, dst_rect.Top, dst_rect.Right, dst_rect.Bottom, dst_rect.GetWidth(), dst_rect.GetHeight()); + // init game scaling transformation + GameScaling.Init(native_size, gfxDriver->GetRenderDestination()); + return true; } -bool graphics_mode_set_native_size(const Size &native_size) -{ - if (!gfxDriver || native_size.IsNull()) - return false; - if (!gfxDriver->SetNativeSize(native_size)) - return false; - // if render frame translation was already set, then update it with new native size - if (gfxDriver->IsRenderFrameValid()) - graphics_mode_update_render_frame(); - return true; +bool graphics_mode_set_native_size(const Size &native_size) { + if (!gfxDriver || native_size.IsNull()) + return false; + if (!gfxDriver->SetNativeSize(native_size)) + return false; + // if render frame translation was already set, then update it with new native size + if (gfxDriver->IsRenderFrameValid()) + graphics_mode_update_render_frame(); + return true; } -GameFrameSetup graphics_mode_get_render_frame() -{ - return CurFrameSetup; +GameFrameSetup graphics_mode_get_render_frame() { + return CurFrameSetup; } -bool graphics_mode_set_render_frame(const GameFrameSetup &frame_setup) -{ - if (!frame_setup.IsValid()) - return false; - CurFrameSetup = frame_setup; - if (gfxDriver->GetDisplayMode().Windowed) - SavedWindowedSetting.FrameSetup = frame_setup; - else - SavedFullscreenSetting.FrameSetup = frame_setup; - graphics_mode_update_render_frame(); - return true; +bool graphics_mode_set_render_frame(const GameFrameSetup &frame_setup) { + if (!frame_setup.IsValid()) + return false; + CurFrameSetup = frame_setup; + if (gfxDriver->GetDisplayMode().Windowed) + SavedWindowedSetting.FrameSetup = frame_setup; + else + SavedFullscreenSetting.FrameSetup = frame_setup; + graphics_mode_update_render_frame(); + return true; } -bool graphics_mode_set_filter(const String &filter_id) -{ - if (!GfxFactory) - return false; - - String filter_error; - PGfxFilter filter = GfxFactory->SetFilter(filter_id, filter_error); - if (!filter) - { - Debug::Printf(kDbgMsg_Error, "Unable to set graphics filter '%s'. Error: %s", filter_id.GetCStr(), filter_error.GetCStr()); - return false; - } - Rect filter_rect = filter->GetDestination(); - Debug::Printf("Graphics filter set: '%s', filter dest (%d, %d, %d, %d : %d x %d)", filter->GetInfo().Id.GetCStr(), - filter_rect.Left, filter_rect.Top, filter_rect.Right, filter_rect.Bottom, filter_rect.GetWidth(), filter_rect.GetHeight()); - return true; +bool graphics_mode_set_filter(const String &filter_id) { + if (!GfxFactory) + return false; + + String filter_error; + PGfxFilter filter = GfxFactory->SetFilter(filter_id, filter_error); + if (!filter) { + Debug::Printf(kDbgMsg_Error, "Unable to set graphics filter '%s'. Error: %s", filter_id.GetCStr(), filter_error.GetCStr()); + return false; + } + Rect filter_rect = filter->GetDestination(); + Debug::Printf("Graphics filter set: '%s', filter dest (%d, %d, %d, %d : %d x %d)", filter->GetInfo().Id.GetCStr(), + filter_rect.Left, filter_rect.Top, filter_rect.Right, filter_rect.Bottom, filter_rect.GetWidth(), filter_rect.GetHeight()); + return true; } -void graphics_mode_shutdown() -{ - if (GfxFactory) - GfxFactory->Shutdown(); - GfxFactory = nullptr; - gfxDriver = nullptr; +void graphics_mode_shutdown() { + if (GfxFactory) + GfxFactory->Shutdown(); + GfxFactory = nullptr; + gfxDriver = nullptr; - // Tell Allegro that we are no longer in graphics mode - set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); + // Tell Allegro that we are no longer in graphics mode + set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); } diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h index 8e5f7a23e619..a75f85f19b3b 100644 --- a/engines/ags/engine/main/graphics_mode.h +++ b/engines/ags/engine/main/graphics_mode.h @@ -33,7 +33,11 @@ using AGS::Engine::DisplayMode; Size get_desktop_size(); String make_scaling_factor_string(uint32_t scaling); -namespace AGS { namespace Engine { class IGfxModeList; }} +namespace AGS { +namespace Engine { +class IGfxModeList; +} +} bool find_nearest_supported_mode(const AGS::Engine::IGfxModeList &modes, const Size &wanted_size, const int color_depth, const Size *ratio_reference, const Size *upper_bound, AGS::Engine::DisplayMode &dm, int *mode_index = nullptr); @@ -46,93 +50,84 @@ extern AGS::Engine::PlaneScaling GameScaling; // Filter configuration -struct GfxFilterSetup -{ - String ID; // internal filter ID - String UserRequest; // filter name, requested by user +struct GfxFilterSetup { + String ID; // internal filter ID + String UserRequest; // filter name, requested by user }; -enum FrameScaleDefinition -{ - kFrame_IntScale, // explicit integer scaling x/y factors - kFrame_MaxRound, // calculate max round uniform scaling factor - kFrame_MaxStretch, // resize to maximal possible inside the display box - kFrame_MaxProportional, // same as stretch, but keep game's aspect ratio - kNumFrameScaleDef +enum FrameScaleDefinition { + kFrame_IntScale, // explicit integer scaling x/y factors + kFrame_MaxRound, // calculate max round uniform scaling factor + kFrame_MaxStretch, // resize to maximal possible inside the display box + kFrame_MaxProportional, // same as stretch, but keep game's aspect ratio + kNumFrameScaleDef }; // Game frame configuration -struct GameFrameSetup -{ - FrameScaleDefinition ScaleDef; // a method used to determine game frame scaling - int ScaleFactor; // explicit scale factor - - GameFrameSetup(); - GameFrameSetup(FrameScaleDefinition def, int factor = 0); - bool IsValid() const; +struct GameFrameSetup { + FrameScaleDefinition ScaleDef; // a method used to determine game frame scaling + int ScaleFactor; // explicit scale factor + + GameFrameSetup(); + GameFrameSetup(FrameScaleDefinition def, int factor = 0); + bool IsValid() const; }; -enum ScreenSizeDefinition -{ - kScreenDef_Explicit, // define by width & height - kScreenDef_ByGameScaling, // define by game scale factor - kScreenDef_MaxDisplay, // set to maximal supported (desktop/device screen size) - kNumScreenDef +enum ScreenSizeDefinition { + kScreenDef_Explicit, // define by width & height + kScreenDef_ByGameScaling, // define by game scale factor + kScreenDef_MaxDisplay, // set to maximal supported (desktop/device screen size) + kNumScreenDef }; // Configuration that is used to determine the size of the screen -struct ScreenSizeSetup -{ - ScreenSizeDefinition SizeDef; // a method used to determine screen size - ::Size Size; // explicitly defined screen metrics - bool MatchDeviceRatio; // whether to choose resolution matching device aspect ratio +struct ScreenSizeSetup { + ScreenSizeDefinition SizeDef; // a method used to determine screen size + ::Size Size; // explicitly defined screen metrics + bool MatchDeviceRatio; // whether to choose resolution matching device aspect ratio - ScreenSizeSetup(); + ScreenSizeSetup(); }; // Display mode configuration -struct DisplayModeSetup -{ - ScreenSizeSetup ScreenSize; +struct DisplayModeSetup { + ScreenSizeSetup ScreenSize; - int RefreshRate; // gfx mode refresh rate - bool VSync; // vertical sync - bool Windowed; // is mode windowed + int RefreshRate; // gfx mode refresh rate + bool VSync; // vertical sync + bool Windowed; // is mode windowed - DisplayModeSetup(); + DisplayModeSetup(); }; // Full graphics configuration -struct ScreenSetup -{ - String DriverID; // graphics driver ID - DisplayModeSetup DisplayMode; // definition of the initial display mode - - // Definitions for the fullscreen and windowed scaling methods. - // When the initial display mode is set, corresponding scaling method from this pair is used. - // The second method is meant to be saved and used if display mode is switched at runtime. - GameFrameSetup FsGameFrame; // how the game frame should be scaled/positioned in fullscreen mode - GameFrameSetup WinGameFrame; // how the game frame should be scaled/positioned in windowed mode - - GfxFilterSetup Filter; // graphics filter definition +struct ScreenSetup { + String DriverID; // graphics driver ID + DisplayModeSetup DisplayMode; // definition of the initial display mode + + // Definitions for the fullscreen and windowed scaling methods. + // When the initial display mode is set, corresponding scaling method from this pair is used. + // The second method is meant to be saved and used if display mode is switched at runtime. + GameFrameSetup FsGameFrame; // how the game frame should be scaled/positioned in fullscreen mode + GameFrameSetup WinGameFrame; // how the game frame should be scaled/positioned in windowed mode + + GfxFilterSetup Filter; // graphics filter definition }; // Display mode color depth variants suggested for the use -struct ColorDepthOption -{ - int Bits; // color depth value in bits - bool Forced; // whether the depth should be forced, or driver's recommendation used +struct ColorDepthOption { + int Bits; // color depth value in bits + bool Forced; // whether the depth should be forced, or driver's recommendation used - ColorDepthOption() : Bits(0), Forced(false) {} - ColorDepthOption(int bits, bool forced = false) : Bits(bits), Forced(forced) {} + ColorDepthOption() : Bits(0), Forced(false) {} + ColorDepthOption(int bits, bool forced = false) : Bits(bits), Forced(forced) {} }; // ActiveDisplaySetting struct merges DisplayMode and GameFrameSetup, // which is useful if you need to save active settings and reapply them later. -struct ActiveDisplaySetting -{ - DisplayMode Dm; - GameFrameSetup FrameSetup; +struct ActiveDisplaySetting { + DisplayMode Dm; + GameFrameSetup FrameSetup; }; // Initializes any possible gfx mode, using user config as a recommendation; diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp index ef135fd15813..4ed51f38e02d 100644 --- a/engines/ags/engine/main/main.cpp +++ b/engines/ags/engine/main/main.cpp @@ -117,16 +117,14 @@ int psp_gfx_smooth_sprites = 0; #endif -void main_pre_init() -{ - our_eip = -999; - Common::AssetManager::SetSearchPriority(Common::kAssetPriorityDir); - play.takeover_data = 0; +void main_pre_init() { + our_eip = -999; + Common::AssetManager::SetSearchPriority(Common::kAssetPriorityDir); + play.takeover_data = 0; } -void main_create_platform_driver() -{ - platform = AGSPlatformDriver::GetDriver(); +void main_create_platform_driver() { + platform = AGSPlatformDriver::GetDriver(); } // this needs to be updated if the "play" struct changes @@ -148,32 +146,30 @@ AGS::Common::Version SavedgameLowestBackwardCompatVersion; // Lowest engine version, which would accept current savedgames AGS::Common::Version SavedgameLowestForwardCompatVersion; -void main_init(int argc, char*argv[]) -{ - EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); +void main_init(int argc, char *argv[]) { + EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); #if defined (BUILD_STR) - EngineVersion.BuildInfo = BUILD_STR; + EngineVersion.BuildInfo = BUILD_STR; #endif - SavedgameLowestBackwardCompatVersion = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); - SavedgameLowestForwardCompatVersion = Version(SVG_VERSION_FWCOMPAT_MAJOR, SVG_VERSION_FWCOMPAT_MINOR, SVG_VERSION_FWCOMPAT_RELEASE, SVG_VERSION_FWCOMPAT_REVISION); + SavedgameLowestBackwardCompatVersion = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); + SavedgameLowestForwardCompatVersion = Version(SVG_VERSION_FWCOMPAT_MAJOR, SVG_VERSION_FWCOMPAT_MINOR, SVG_VERSION_FWCOMPAT_RELEASE, SVG_VERSION_FWCOMPAT_REVISION); - Common::AssetManager::CreateInstance(); - main_pre_init(); - main_create_platform_driver(); + Common::AssetManager::CreateInstance(); + main_pre_init(); + main_create_platform_driver(); - global_argv = argv; - global_argc = argc; + global_argv = argv; + global_argc = argc; } -String get_engine_string() -{ - return String::FromFormat("Adventure Game Studio v%s Interpreter\n" - "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" +String get_engine_string() { + return String::FromFormat("Adventure Game Studio v%s Interpreter\n" + "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" #ifdef BUILD_STR - "ACI version %s (Build: %s)\n", - EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr(), EngineVersion.BuildInfo.GetCStr()); + "ACI version %s (Build: %s)\n", + EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr(), EngineVersion.BuildInfo.GetCStr()); #else - "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); + "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); #endif } @@ -181,323 +177,285 @@ extern char return_to_roomedit[30]; extern char return_to_room[150]; void main_print_help() { - platform->WriteStdOut( - "Usage: ags [OPTIONS] [GAMEFILE or DIRECTORY]\n\n" - //--------------------------------------------------------------------------------| - "Options:\n" + platform->WriteStdOut( + "Usage: ags [OPTIONS] [GAMEFILE or DIRECTORY]\n\n" + //--------------------------------------------------------------------------------| + "Options:\n" #if AGS_PLATFORM_OS_WINDOWS - " --console-attach Write output to the parent process's console\n" + " --console-attach Write output to the parent process's console\n" #endif - " --fps Display fps counter\n" - " --fullscreen Force display mode to fullscreen\n" - " --gfxdriver Request graphics driver. Available options:\n" + " --fps Display fps counter\n" + " --fullscreen Force display mode to fullscreen\n" + " --gfxdriver Request graphics driver. Available options:\n" #if AGS_PLATFORM_OS_WINDOWS - " d3d9, ogl, software\n" + " d3d9, ogl, software\n" #else - " ogl, software\n" + " ogl, software\n" #endif - " --gfxfilter FILTER [SCALING]\n" - " Request graphics filter. Available options:\n" - " hqx, linear, none, stdscale\n" - " (support differs between graphic drivers);\n" - " scaling is specified by integer number\n" - " --help Print this help message and stop\n" - " --log-OUTPUT=GROUP[:LEVEL][,GROUP[:LEVEL]][,...]\n" - " --log-OUTPUT=+GROUPLIST[:LEVEL]\n" - " Setup logging to the chosen OUTPUT with given\n" - " log groups and verbosity levels. Groups may\n" - " be also defined by a LIST of one-letter IDs,\n" - " preceded by '+', e.g. +ABCD:LEVEL. Verbosity may\n" - " be also defined by a numberic ID.\n" - " OUTPUTs are\n" - " stdout, file, console\n" - " (where \"console\" is internal engine's console)\n" - " GROUPs are:\n" - " all, main (m), game (g), manobj (o),\n" - " script (s), sprcache (c)\n" - " LEVELs are:\n" - " all, alert (1), fatal (2), error (3), warn (4),\n" - " info (5), debug (6)\n" - " Examples:\n" - " --log-stdout=+mgs:debug\n" - " --log-file=all:warn\n" - " --log-file-path=PATH Define custom path for the log file\n" - //--------------------------------------------------------------------------------| + " --gfxfilter FILTER [SCALING]\n" + " Request graphics filter. Available options:\n" + " hqx, linear, none, stdscale\n" + " (support differs between graphic drivers);\n" + " scaling is specified by integer number\n" + " --help Print this help message and stop\n" + " --log-OUTPUT=GROUP[:LEVEL][,GROUP[:LEVEL]][,...]\n" + " --log-OUTPUT=+GROUPLIST[:LEVEL]\n" + " Setup logging to the chosen OUTPUT with given\n" + " log groups and verbosity levels. Groups may\n" + " be also defined by a LIST of one-letter IDs,\n" + " preceded by '+', e.g. +ABCD:LEVEL. Verbosity may\n" + " be also defined by a numberic ID.\n" + " OUTPUTs are\n" + " stdout, file, console\n" + " (where \"console\" is internal engine's console)\n" + " GROUPs are:\n" + " all, main (m), game (g), manobj (o),\n" + " script (s), sprcache (c)\n" + " LEVELs are:\n" + " all, alert (1), fatal (2), error (3), warn (4),\n" + " info (5), debug (6)\n" + " Examples:\n" + " --log-stdout=+mgs:debug\n" + " --log-file=all:warn\n" + " --log-file-path=PATH Define custom path for the log file\n" + //--------------------------------------------------------------------------------| #if AGS_PLATFORM_OS_WINDOWS - " --no-message-box Disable reporting of alerts to message boxes\n" - " --setup Run setup application\n" + " --no-message-box Disable reporting of alerts to message boxes\n" + " --setup Run setup application\n" #endif - " --tell Print various information concerning engine\n" - " and the game; for selected output use:\n" - " --tell-config Print contents of merged game config\n" - " --tell-configpath Print paths to available config files\n" - " --tell-data Print information on game data and its location\n" - " --tell-engine Print engine name and version\n" - " --tell-graphicdriver Print list of supported graphic drivers\n" - "\n" - " --version Print engine's version and stop\n" - " --windowed Force display mode to windowed\n" - "\n" - "Gamefile options:\n" - " /dir/path/game/ Launch the game in specified directory\n" - " /dir/path/game/penguin.exe Launch penguin.exe\n" - " [nothing] Launch the game in the current directory\n" - //--------------------------------------------------------------------------------| - ); + " --tell Print various information concerning engine\n" + " and the game; for selected output use:\n" + " --tell-config Print contents of merged game config\n" + " --tell-configpath Print paths to available config files\n" + " --tell-data Print information on game data and its location\n" + " --tell-engine Print engine name and version\n" + " --tell-graphicdriver Print list of supported graphic drivers\n" + "\n" + " --version Print engine's version and stop\n" + " --windowed Force display mode to windowed\n" + "\n" + "Gamefile options:\n" + " /dir/path/game/ Launch the game in specified directory\n" + " /dir/path/game/penguin.exe Launch penguin.exe\n" + " [nothing] Launch the game in the current directory\n" + //--------------------------------------------------------------------------------| + ); } -static int main_process_cmdline(ConfigTree &cfg, int argc, char *argv[]) -{ - int datafile_argv = 0; - for (int ee = 1; ee < argc; ++ee) - { - const char *arg = argv[ee]; - // - // Startup options - // - if (ags_stricmp(arg,"--help") == 0 || ags_stricmp(arg,"/?") == 0 || ags_stricmp(arg,"-?") == 0) - { - justDisplayHelp = true; - return 0; - } - if (ags_stricmp(arg, "-v") == 0 || ags_stricmp(arg, "--version") == 0) - { - justDisplayVersion = true; - return 0; - } - else if (ags_stricmp(arg,"-updatereg") == 0) - debug_flags |= DBG_REGONLY; +static int main_process_cmdline(ConfigTree &cfg, int argc, char *argv[]) { + int datafile_argv = 0; + for (int ee = 1; ee < argc; ++ee) { + const char *arg = argv[ee]; + // + // Startup options + // + if (ags_stricmp(arg, "--help") == 0 || ags_stricmp(arg, "/?") == 0 || ags_stricmp(arg, "-?") == 0) { + justDisplayHelp = true; + return 0; + } + if (ags_stricmp(arg, "-v") == 0 || ags_stricmp(arg, "--version") == 0) { + justDisplayVersion = true; + return 0; + } else if (ags_stricmp(arg, "-updatereg") == 0) + debug_flags |= DBG_REGONLY; #if AGS_PLATFORM_DEBUG - else if ((ags_stricmp(arg,"--startr") == 0) && (ee < argc-1)) { - override_start_room = atoi(argv[ee+1]); - ee++; - } + else if ((ags_stricmp(arg, "--startr") == 0) && (ee < argc - 1)) { + override_start_room = atoi(argv[ee + 1]); + ee++; + } #endif - else if ((ags_stricmp(arg,"--testre") == 0) && (ee < argc-2)) { - strcpy(return_to_roomedit, argv[ee+1]); - strcpy(return_to_room, argv[ee+2]); - ee+=2; - } - else if (ags_stricmp(arg,"-noexceptionhandler")==0) usetup.disable_exception_handling = true; - else if (ags_stricmp(arg, "--setup") == 0) - { - justRunSetup = true; - } - else if (ags_stricmp(arg,"-registergame") == 0) - { - justRegisterGame = true; - } - else if (ags_stricmp(arg,"-unregistergame") == 0) - { - justUnRegisterGame = true; - } - else if ((ags_stricmp(arg,"-loadsavedgame") == 0) && (argc > ee + 1)) - { - loadSaveGameOnStartup = argv[ee + 1]; - ee++; - } - else if ((ags_stricmp(arg,"--enabledebugger") == 0) && (argc > ee + 1)) - { - strcpy(editor_debugger_instance_token, argv[ee + 1]); - editor_debugging_enabled = 1; - force_window = 1; - ee++; - } - else if (ags_stricmp(arg, "--runfromide") == 0 && (argc > ee + 3)) - { - usetup.install_dir = argv[ee + 1]; - usetup.install_audio_dir = argv[ee + 2]; - usetup.install_voice_dir = argv[ee + 3]; - ee += 3; - } - else if (ags_stricmp(arg,"--takeover")==0) { - if (argc < ee+2) - break; - play.takeover_data = atoi (argv[ee + 1]); - strncpy (play.takeover_from, argv[ee + 2], 49); - play.takeover_from[49] = 0; - ee += 2; - } - else if (ags_strnicmp(arg, "--tell", 6) == 0) { - if (arg[6] == 0) - tellInfoKeys.insert(String("all")); - else if (arg[6] == '-' && arg[7] != 0) - tellInfoKeys.insert(String(arg + 7)); - } - // - // Config overrides - // - else if (ags_stricmp(arg, "-windowed") == 0 || ags_stricmp(arg, "--windowed") == 0) - force_window = 1; - else if (ags_stricmp(arg, "-fullscreen") == 0 || ags_stricmp(arg, "--fullscreen") == 0) - force_window = 2; - else if ((ags_stricmp(arg, "-gfxdriver") == 0 || ags_stricmp(arg, "--gfxdriver") == 0) && (argc > ee + 1)) - { - INIwritestring(cfg, "graphics", "driver", argv[++ee]); - } - else if ((ags_stricmp(arg, "-gfxfilter") == 0 || ags_stricmp(arg, "--gfxfilter") == 0) && (argc > ee + 1)) - { - // NOTE: we make an assumption here that if user provides scaling factor, - // this factor means to be applied to windowed mode only. - INIwritestring(cfg, "graphics", "filter", argv[++ee]); - if (argc > ee + 1 && argv[ee + 1][0] != '-') - INIwritestring(cfg, "graphics", "game_scale_win", argv[++ee]); - else - INIwritestring(cfg, "graphics", "game_scale_win", "max_round"); - } - else if (ags_stricmp(arg, "--fps") == 0) display_fps = kFPS_Forced; - else if (ags_stricmp(arg, "--test") == 0) debug_flags |= DBG_DEBUGMODE; - else if (ags_stricmp(arg, "-noiface") == 0) debug_flags |= DBG_NOIFACE; - else if (ags_stricmp(arg, "-nosprdisp") == 0) debug_flags |= DBG_NODRAWSPRITES; - else if (ags_stricmp(arg, "-nospr") == 0) debug_flags |= DBG_NOOBJECTS; - else if (ags_stricmp(arg, "-noupdate") == 0) debug_flags |= DBG_NOUPDATE; - else if (ags_stricmp(arg, "-nosound") == 0) debug_flags |= DBG_NOSFX; - else if (ags_stricmp(arg, "-nomusic") == 0) debug_flags |= DBG_NOMUSIC; - else if (ags_stricmp(arg, "-noscript") == 0) debug_flags |= DBG_NOSCRIPT; - else if (ags_stricmp(arg, "-novideo") == 0) debug_flags |= DBG_NOVIDEO; - else if (ags_stricmp(arg, "-dbgscript") == 0) debug_flags |= DBG_DBGSCRIPT; - else if (ags_strnicmp(arg, "--log-", 6) == 0 && arg[6] != 0) - { - String logarg = arg + 6; - size_t split_at = logarg.FindChar('='); - if (split_at >= 0) - cfg["log"][logarg.Left(split_at)] = logarg.Mid(split_at + 1); - else - cfg["log"][logarg] = ""; - } - else if (ags_stricmp(arg, "--console-attach") == 0) attachToParentConsole = true; - else if (ags_stricmp(arg, "--no-message-box") == 0) hideMessageBoxes = true; - // - // Special case: data file location - // - else if (arg[0]!='-') datafile_argv=ee; - } - - if (datafile_argv > 0) - { - cmdGameDataPath = GetPathFromCmdArg(datafile_argv); - } - else - { - // assign standard path for mobile/consoles (defined in their own platform implementation) - cmdGameDataPath = psp_game_file_name; - } - - if (tellInfoKeys.size() > 0) - justTellInfo = true; - - return 0; + else if ((ags_stricmp(arg, "--testre") == 0) && (ee < argc - 2)) { + strcpy(return_to_roomedit, argv[ee + 1]); + strcpy(return_to_room, argv[ee + 2]); + ee += 2; + } else if (ags_stricmp(arg, "-noexceptionhandler") == 0) usetup.disable_exception_handling = true; + else if (ags_stricmp(arg, "--setup") == 0) { + justRunSetup = true; + } else if (ags_stricmp(arg, "-registergame") == 0) { + justRegisterGame = true; + } else if (ags_stricmp(arg, "-unregistergame") == 0) { + justUnRegisterGame = true; + } else if ((ags_stricmp(arg, "-loadsavedgame") == 0) && (argc > ee + 1)) { + loadSaveGameOnStartup = argv[ee + 1]; + ee++; + } else if ((ags_stricmp(arg, "--enabledebugger") == 0) && (argc > ee + 1)) { + strcpy(editor_debugger_instance_token, argv[ee + 1]); + editor_debugging_enabled = 1; + force_window = 1; + ee++; + } else if (ags_stricmp(arg, "--runfromide") == 0 && (argc > ee + 3)) { + usetup.install_dir = argv[ee + 1]; + usetup.install_audio_dir = argv[ee + 2]; + usetup.install_voice_dir = argv[ee + 3]; + ee += 3; + } else if (ags_stricmp(arg, "--takeover") == 0) { + if (argc < ee + 2) + break; + play.takeover_data = atoi(argv[ee + 1]); + strncpy(play.takeover_from, argv[ee + 2], 49); + play.takeover_from[49] = 0; + ee += 2; + } else if (ags_strnicmp(arg, "--tell", 6) == 0) { + if (arg[6] == 0) + tellInfoKeys.insert(String("all")); + else if (arg[6] == '-' && arg[7] != 0) + tellInfoKeys.insert(String(arg + 7)); + } + // + // Config overrides + // + else if (ags_stricmp(arg, "-windowed") == 0 || ags_stricmp(arg, "--windowed") == 0) + force_window = 1; + else if (ags_stricmp(arg, "-fullscreen") == 0 || ags_stricmp(arg, "--fullscreen") == 0) + force_window = 2; + else if ((ags_stricmp(arg, "-gfxdriver") == 0 || ags_stricmp(arg, "--gfxdriver") == 0) && (argc > ee + 1)) { + INIwritestring(cfg, "graphics", "driver", argv[++ee]); + } else if ((ags_stricmp(arg, "-gfxfilter") == 0 || ags_stricmp(arg, "--gfxfilter") == 0) && (argc > ee + 1)) { + // NOTE: we make an assumption here that if user provides scaling factor, + // this factor means to be applied to windowed mode only. + INIwritestring(cfg, "graphics", "filter", argv[++ee]); + if (argc > ee + 1 && argv[ee + 1][0] != '-') + INIwritestring(cfg, "graphics", "game_scale_win", argv[++ee]); + else + INIwritestring(cfg, "graphics", "game_scale_win", "max_round"); + } else if (ags_stricmp(arg, "--fps") == 0) display_fps = kFPS_Forced; + else if (ags_stricmp(arg, "--test") == 0) debug_flags |= DBG_DEBUGMODE; + else if (ags_stricmp(arg, "-noiface") == 0) debug_flags |= DBG_NOIFACE; + else if (ags_stricmp(arg, "-nosprdisp") == 0) debug_flags |= DBG_NODRAWSPRITES; + else if (ags_stricmp(arg, "-nospr") == 0) debug_flags |= DBG_NOOBJECTS; + else if (ags_stricmp(arg, "-noupdate") == 0) debug_flags |= DBG_NOUPDATE; + else if (ags_stricmp(arg, "-nosound") == 0) debug_flags |= DBG_NOSFX; + else if (ags_stricmp(arg, "-nomusic") == 0) debug_flags |= DBG_NOMUSIC; + else if (ags_stricmp(arg, "-noscript") == 0) debug_flags |= DBG_NOSCRIPT; + else if (ags_stricmp(arg, "-novideo") == 0) debug_flags |= DBG_NOVIDEO; + else if (ags_stricmp(arg, "-dbgscript") == 0) debug_flags |= DBG_DBGSCRIPT; + else if (ags_strnicmp(arg, "--log-", 6) == 0 && arg[6] != 0) { + String logarg = arg + 6; + size_t split_at = logarg.FindChar('='); + if (split_at >= 0) + cfg["log"][logarg.Left(split_at)] = logarg.Mid(split_at + 1); + else + cfg["log"][logarg] = ""; + } else if (ags_stricmp(arg, "--console-attach") == 0) attachToParentConsole = true; + else if (ags_stricmp(arg, "--no-message-box") == 0) hideMessageBoxes = true; + // + // Special case: data file location + // + else if (arg[0] != '-') datafile_argv = ee; + } + + if (datafile_argv > 0) { + cmdGameDataPath = GetPathFromCmdArg(datafile_argv); + } else { + // assign standard path for mobile/consoles (defined in their own platform implementation) + cmdGameDataPath = psp_game_file_name; + } + + if (tellInfoKeys.size() > 0) + justTellInfo = true; + + return 0; } -void main_set_gamedir(int argc, char*argv[]) -{ - appDirectory = Path::GetDirectoryPath(GetPathFromCmdArg(0)); - - if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) - { - // When launched by double-clicking a save game file, the curdir will - // be the save game folder unless we correct it - Directory::SetCurrentDirectory(appDirectory); - } - else - { - // It looks like Allegro library does not like ANSI (ACP) paths. - // When *not* working in U_UNICODE filepath mode, whenever it gets - // current directory for its own operations, it "fixes" it by - // substituting non-ASCII symbols with '^'. - // Here we explicitly set current directory to ASCII path. - String cur_dir = Directory::GetCurrentDirectory(); - String path = Path::GetPathInASCII(cur_dir); - if (!path.IsEmpty()) - Directory::SetCurrentDirectory(Path::MakeAbsolutePath(path)); - else - Debug::Printf(kDbgMsg_Error, "Unable to determine current directory: GetPathInASCII failed.\nArg: %s", cur_dir.GetCStr()); - } +void main_set_gamedir(int argc, char *argv[]) { + appDirectory = Path::GetDirectoryPath(GetPathFromCmdArg(0)); + + if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) { + // When launched by double-clicking a save game file, the curdir will + // be the save game folder unless we correct it + Directory::SetCurrentDirectory(appDirectory); + } else { + // It looks like Allegro library does not like ANSI (ACP) paths. + // When *not* working in U_UNICODE filepath mode, whenever it gets + // current directory for its own operations, it "fixes" it by + // substituting non-ASCII symbols with '^'. + // Here we explicitly set current directory to ASCII path. + String cur_dir = Directory::GetCurrentDirectory(); + String path = Path::GetPathInASCII(cur_dir); + if (!path.IsEmpty()) + Directory::SetCurrentDirectory(Path::MakeAbsolutePath(path)); + else + Debug::Printf(kDbgMsg_Error, "Unable to determine current directory: GetPathInASCII failed.\nArg: %s", cur_dir.GetCStr()); + } } -String GetPathFromCmdArg(int arg_index) -{ - if (arg_index < 0 || arg_index >= global_argc) - return ""; - String path = Path::GetCmdLinePathInASCII(global_argv[arg_index], arg_index); - if (!path.IsEmpty()) - return Path::MakeAbsolutePath(path); - Debug::Printf(kDbgMsg_Error, "Unable to determine path: GetCmdLinePathInASCII failed.\nCommand line argument %i: %s", arg_index, global_argv[arg_index]); - return global_argv[arg_index]; +String GetPathFromCmdArg(int arg_index) { + if (arg_index < 0 || arg_index >= global_argc) + return ""; + String path = Path::GetCmdLinePathInASCII(global_argv[arg_index], arg_index); + if (!path.IsEmpty()) + return Path::MakeAbsolutePath(path); + Debug::Printf(kDbgMsg_Error, "Unable to determine path: GetCmdLinePathInASCII failed.\nCommand line argument %i: %s", arg_index, global_argv[arg_index]); + return global_argv[arg_index]; } -const char *get_allegro_error() -{ - return allegro_error; +const char *get_allegro_error() { + return allegro_error; } -const char *set_allegro_error(const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - uvszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(format), argptr); - va_end(argptr); - return allegro_error; +const char *set_allegro_error(const char *format, ...) { + va_list argptr; + va_start(argptr, format); + uvszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(format), argptr); + va_end(argptr); + return allegro_error; } -int ags_entry_point(int argc, char *argv[]) { +int ags_entry_point(int argc, char *argv[]) { #ifdef AGS_RUN_TESTS - Test_DoAllTests(); + Test_DoAllTests(); #endif - main_init(argc, argv); + main_init(argc, argv); #if AGS_PLATFORM_OS_WINDOWS - setup_malloc_handling(); + setup_malloc_handling(); #endif - debug_flags=0; + debug_flags = 0; - ConfigTree startup_opts; - int res = main_process_cmdline(startup_opts, argc, argv); - if (res != 0) - return res; + ConfigTree startup_opts; + int res = main_process_cmdline(startup_opts, argc, argv); + if (res != 0) + return res; - if (attachToParentConsole) - platform->AttachToParentConsole(); + if (attachToParentConsole) + platform->AttachToParentConsole(); - if (justDisplayVersion) - { - platform->WriteStdOut(get_engine_string()); - return EXIT_NORMAL; - } + if (justDisplayVersion) { + platform->WriteStdOut(get_engine_string()); + return EXIT_NORMAL; + } - if (justDisplayHelp) - { - main_print_help(); - return EXIT_NORMAL; - } + if (justDisplayHelp) { + main_print_help(); + return EXIT_NORMAL; + } - if (!justTellInfo && !hideMessageBoxes) - platform->SetGUIMode(true); + if (!justTellInfo && !hideMessageBoxes) + platform->SetGUIMode(true); - init_debug(startup_opts, justTellInfo); - Debug::Printf(kDbgMsg_Alert, get_engine_string()); + init_debug(startup_opts, justTellInfo); + Debug::Printf(kDbgMsg_Alert, get_engine_string()); - main_set_gamedir(argc, argv); + main_set_gamedir(argc, argv); - // Update shell associations and exit - if (debug_flags & DBG_REGONLY) - exit(EXIT_NORMAL); + // Update shell associations and exit + if (debug_flags & DBG_REGONLY) + exit(EXIT_NORMAL); #ifdef USE_CUSTOM_EXCEPTION_HANDLER - if (usetup.disable_exception_handling) + if (usetup.disable_exception_handling) #endif - { - int result = initialize_engine(startup_opts); - // TODO: refactor engine shutdown routine (must shutdown and delete everything started and created) - allegro_exit(); - platform->PostAllegroExit(); - return result; - } + { + int result = initialize_engine(startup_opts); + // TODO: refactor engine shutdown routine (must shutdown and delete everything started and created) + allegro_exit(); + platform->PostAllegroExit(); + return result; + } #ifdef USE_CUSTOM_EXCEPTION_HANDLER - else - { - return initialize_engine_with_exception_handling(initialize_engine, startup_opts); - } + else { + return initialize_engine_with_exception_handling(initialize_engine, startup_opts); + } #endif } diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index ce039abe1586..45f7036d3b8f 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -67,173 +67,148 @@ extern IGraphicsDriver *gfxDriver; bool handledErrorInEditor; -void quit_tell_editor_debugger(const String &qmsg, QuitReason qreason) -{ - if (editor_debugging_initialized) - { - if (qreason & kQuitKind_GameException) - handledErrorInEditor = send_exception_to_editor(qmsg); - send_message_to_editor("EXIT"); - editor_debugger->Shutdown(); - } +void quit_tell_editor_debugger(const String &qmsg, QuitReason qreason) { + if (editor_debugging_initialized) { + if (qreason & kQuitKind_GameException) + handledErrorInEditor = send_exception_to_editor(qmsg); + send_message_to_editor("EXIT"); + editor_debugger->Shutdown(); + } } -void quit_stop_cd() -{ - if (need_to_stop_cd) - cd_manager(3,0); +void quit_stop_cd() { + if (need_to_stop_cd) + cd_manager(3, 0); } -void quit_shutdown_scripts() -{ - ccUnregisterAllObjects(); +void quit_shutdown_scripts() { + ccUnregisterAllObjects(); } -void quit_check_dynamic_sprites(QuitReason qreason) -{ - if ((qreason & kQuitKind_NormalExit) && (check_dynamic_sprites_at_exit) && - (game.options[OPT_DEBUGMODE] != 0)) { - // game exiting normally -- make sure the dynamic sprites - // have been deleted - for (int i = 1; i < spriteset.GetSpriteSlotCount(); i++) { - if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) - debug_script_warn("Dynamic sprite %d was never deleted", i); - } - } +void quit_check_dynamic_sprites(QuitReason qreason) { + if ((qreason & kQuitKind_NormalExit) && (check_dynamic_sprites_at_exit) && + (game.options[OPT_DEBUGMODE] != 0)) { + // game exiting normally -- make sure the dynamic sprites + // have been deleted + for (int i = 1; i < spriteset.GetSpriteSlotCount(); i++) { + if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) + debug_script_warn("Dynamic sprite %d was never deleted", i); + } + } } -void quit_shutdown_platform(QuitReason qreason) -{ - // Be sure to unlock mouse on exit, or users will hate us - platform->UnlockMouse(); - platform->AboutToQuitGame(); +void quit_shutdown_platform(QuitReason qreason) { + // Be sure to unlock mouse on exit, or users will hate us + platform->UnlockMouse(); + platform->AboutToQuitGame(); - our_eip = 9016; + our_eip = 9016; - pl_stop_plugins(); + pl_stop_plugins(); - quit_check_dynamic_sprites(qreason); + quit_check_dynamic_sprites(qreason); - platform->FinishedUsingGraphicsMode(); + platform->FinishedUsingGraphicsMode(); - if (use_cdplayer) - platform->ShutdownCDPlayer(); + if (use_cdplayer) + platform->ShutdownCDPlayer(); } -void quit_shutdown_audio() -{ - our_eip = 9917; - game.options[OPT_CROSSFADEMUSIC] = 0; - stopmusic(); +void quit_shutdown_audio() { + our_eip = 9917; + game.options[OPT_CROSSFADEMUSIC] = 0; + stopmusic(); #ifndef PSP_NO_MOD_PLAYBACK - if (usetup.mod_player) - remove_mod_player(); + if (usetup.mod_player) + remove_mod_player(); #endif - // Quit the sound thread. - audioThread.Stop(); + // Quit the sound thread. + audioThread.Stop(); - remove_sound(); + remove_sound(); } -QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) -{ - if (qmsg[0]=='|') - { - return kQuit_GameRequest; - } - else if (qmsg[0]=='!') - { - QuitReason qreason; - qmsg++; - - if (qmsg[0] == '|') - { - qreason = kQuit_UserAbort; - alertis = "Abort key pressed.\n\n"; - } - else if (qmsg[0] == '?') - { - qmsg++; - qreason = kQuit_ScriptAbort; - alertis = "A fatal error has been generated by the script using the AbortGame function. Please contact the game author for support.\n\n"; - } - else - { - qreason = kQuit_GameError; - alertis.Format("An error has occurred. Please contact the game author for support, as this " - "is likely to be a scripting error and not a bug in AGS.\n" - "(ACI version %s)\n\n", EngineVersion.LongString.GetCStr()); - } - - alertis.Append(get_cur_script(5)); - - if (qreason != kQuit_UserAbort) - alertis.Append("\nError: "); - else - qmsg = ""; - return qreason; - } - else if (qmsg[0] == '%') - { - qmsg++; - alertis.Format("A warning has been generated. This is not normally fatal, but you have selected " - "to treat warnings as errors.\n" - "(ACI version %s)\n\n%s\n", EngineVersion.LongString.GetCStr(), get_cur_script(5).GetCStr()); - return kQuit_GameWarning; - } - else - { - alertis.Format("An internal error has occurred. Please note down the following information.\n" - "If the problem persists, post the details on the AGS Technical Forum.\n" - "(ACI version %s)\n" - "\nError: ", EngineVersion.LongString.GetCStr()); - return kQuit_FatalError; - } +QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) { + if (qmsg[0] == '|') { + return kQuit_GameRequest; + } else if (qmsg[0] == '!') { + QuitReason qreason; + qmsg++; + + if (qmsg[0] == '|') { + qreason = kQuit_UserAbort; + alertis = "Abort key pressed.\n\n"; + } else if (qmsg[0] == '?') { + qmsg++; + qreason = kQuit_ScriptAbort; + alertis = "A fatal error has been generated by the script using the AbortGame function. Please contact the game author for support.\n\n"; + } else { + qreason = kQuit_GameError; + alertis.Format("An error has occurred. Please contact the game author for support, as this " + "is likely to be a scripting error and not a bug in AGS.\n" + "(ACI version %s)\n\n", EngineVersion.LongString.GetCStr()); + } + + alertis.Append(get_cur_script(5)); + + if (qreason != kQuit_UserAbort) + alertis.Append("\nError: "); + else + qmsg = ""; + return qreason; + } else if (qmsg[0] == '%') { + qmsg++; + alertis.Format("A warning has been generated. This is not normally fatal, but you have selected " + "to treat warnings as errors.\n" + "(ACI version %s)\n\n%s\n", EngineVersion.LongString.GetCStr(), get_cur_script(5).GetCStr()); + return kQuit_GameWarning; + } else { + alertis.Format("An internal error has occurred. Please note down the following information.\n" + "If the problem persists, post the details on the AGS Technical Forum.\n" + "(ACI version %s)\n" + "\nError: ", EngineVersion.LongString.GetCStr()); + return kQuit_FatalError; + } } -void quit_message_on_exit(const char *qmsg, String &alertis, QuitReason qreason) -{ - // successful exit displays no messages (because Windoze closes the dos-box - // if it is empty). - if ((qreason & kQuitKind_NormalExit) == 0 && !handledErrorInEditor) - { - // Display the message (at this point the window still exists) - sprintf(pexbuf,"%s\n",qmsg); - alertis.Append(pexbuf); - platform->DisplayAlert("%s", alertis.GetCStr()); - } +void quit_message_on_exit(const char *qmsg, String &alertis, QuitReason qreason) { + // successful exit displays no messages (because Windoze closes the dos-box + // if it is empty). + if ((qreason & kQuitKind_NormalExit) == 0 && !handledErrorInEditor) { + // Display the message (at this point the window still exists) + sprintf(pexbuf, "%s\n", qmsg); + alertis.Append(pexbuf); + platform->DisplayAlert("%s", alertis.GetCStr()); + } } -void quit_release_data() -{ - resetRoomStatuses(); - thisroom.Free(); - play.Free(); +void quit_release_data() { + resetRoomStatuses(); + thisroom.Free(); + play.Free(); - /* _CrtMemState memstart; - _CrtMemCheckpoint(&memstart); - _CrtMemDumpStatistics( &memstart );*/ + /* _CrtMemState memstart; + _CrtMemCheckpoint(&memstart); + _CrtMemDumpStatistics( &memstart );*/ - Common::AssetManager::DestroyInstance(); + Common::AssetManager::DestroyInstance(); } -void quit_delete_temp_files() -{ - al_ffblk dfb; - int dun = al_findfirst("~ac*.tmp",&dfb,FA_SEARCH); - while (!dun) { - ::remove(dfb.name); - dun = al_findnext(&dfb); - } - al_findclose (&dfb); +void quit_delete_temp_files() { + al_ffblk dfb; + int dun = al_findfirst("~ac*.tmp", &dfb, FA_SEARCH); + while (!dun) { + ::remove(dfb.name); + dun = al_findnext(&dfb); + } + al_findclose(&dfb); } // TODO: move to test unit extern Bitmap *test_allegro_bitmap; extern IDriverDependantBitmap *test_allegro_ddb; -void allegro_bitmap_test_release() -{ +void allegro_bitmap_test_release() { delete test_allegro_bitmap; if (test_allegro_ddb) gfxDriver->DestroyDDB(test_allegro_ddb); @@ -248,81 +223,80 @@ char return_to_room[150] = "\0"; // message. If it begins with anything else, it is treated as an internal // error. // "!|" is a special code used to mean that the player has aborted (Alt+X) -void quit(const char *quitmsg) -{ - String alertis; - QuitReason qreason = quit_check_for_error_state(quitmsg, alertis); - // Need to copy it in case it's from a plugin (since we're - // about to free plugins) - String qmsg = quitmsg; +void quit(const char *quitmsg) { + String alertis; + QuitReason qreason = quit_check_for_error_state(quitmsg, alertis); + // Need to copy it in case it's from a plugin (since we're + // about to free plugins) + String qmsg = quitmsg; - if (qreason & kQuitKind_NormalExit) - save_config_file(); + if (qreason & kQuitKind_NormalExit) + save_config_file(); allegro_bitmap_test_release(); - handledErrorInEditor = false; + handledErrorInEditor = false; - quit_tell_editor_debugger(qmsg, qreason); + quit_tell_editor_debugger(qmsg, qreason); - our_eip = 9900; + our_eip = 9900; - quit_stop_cd(); + quit_stop_cd(); - our_eip = 9020; + our_eip = 9020; - quit_shutdown_scripts(); + quit_shutdown_scripts(); - quit_shutdown_platform(qreason); + quit_shutdown_platform(qreason); - our_eip = 9019; + our_eip = 9019; - quit_shutdown_audio(); - - our_eip = 9901; + quit_shutdown_audio(); - shutdown_font_renderer(); - our_eip = 9902; + our_eip = 9901; - spriteset.Reset(); + shutdown_font_renderer(); + our_eip = 9902; - our_eip = 9907; + spriteset.Reset(); - close_translation(); + our_eip = 9907; - our_eip = 9908; + close_translation(); - shutdown_pathfinder(); + our_eip = 9908; - engine_shutdown_gfxmode(); + shutdown_pathfinder(); - quit_message_on_exit(qmsg, alertis, qreason); + engine_shutdown_gfxmode(); - quit_release_data(); + quit_message_on_exit(qmsg, alertis, qreason); - // release backed library - // WARNING: no Allegro objects should remain in memory after this, - // if their destruction is called later, program will crash! - allegro_exit(); + quit_release_data(); - platform->PostAllegroExit(); + // release backed library + // WARNING: no Allegro objects should remain in memory after this, + // if their destruction is called later, program will crash! + allegro_exit(); - our_eip = 9903; + platform->PostAllegroExit(); - quit_delete_temp_files(); + our_eip = 9903; - proper_exit=1; + quit_delete_temp_files(); - Debug::Printf(kDbgMsg_Alert, "***** ENGINE HAS SHUTDOWN"); + proper_exit = 1; - shutdown_debug(); + Debug::Printf(kDbgMsg_Alert, "***** ENGINE HAS SHUTDOWN"); - our_eip = 9904; - exit(EXIT_NORMAL); + shutdown_debug(); + + our_eip = 9904; + exit(EXIT_NORMAL); } extern "C" { - void quit_c(char*msg) { - quit(msg); - } + void quit_c(char *msg) { + quit(msg); + } } diff --git a/engines/ags/engine/main/quit.h b/engines/ags/engine/main/quit.h index 569aa90e5e06..cc1fab41e4a4 100644 --- a/engines/ags/engine/main/quit.h +++ b/engines/ags/engine/main/quit.h @@ -23,28 +23,27 @@ #ifndef AGS_ENGINE_MAIN_QUIT_H #define AGS_ENGINE_MAIN_QUIT_H -enum QuitReason -{ - kQuitKind_NormalExit = 0x01, - kQuitKind_DeliberateAbort = 0x02, - kQuitKind_GameException = 0x04, - kQuitKind_EngineException = 0x08, +enum QuitReason { + kQuitKind_NormalExit = 0x01, + kQuitKind_DeliberateAbort = 0x02, + kQuitKind_GameException = 0x04, + kQuitKind_EngineException = 0x08, - // user closed the window or script command QuitGame was executed - kQuit_GameRequest = kQuitKind_NormalExit | 0x10, + // user closed the window or script command QuitGame was executed + kQuit_GameRequest = kQuitKind_NormalExit | 0x10, - // user pressed abort game key - kQuit_UserAbort = kQuitKind_DeliberateAbort | 0x20, - - // script command AbortGame was executed - kQuit_ScriptAbort = kQuitKind_GameException | 0x10, - // game logic has generated a warning and warnings are treated as error - kQuit_GameWarning = kQuitKind_GameException | 0x20, - // game logic has generated an error (often script error) - kQuit_GameError = kQuitKind_GameException | 0x30, + // user pressed abort game key + kQuit_UserAbort = kQuitKind_DeliberateAbort | 0x20, - // any kind of a fatal engine error - kQuit_FatalError = kQuitKind_EngineException + // script command AbortGame was executed + kQuit_ScriptAbort = kQuitKind_GameException | 0x10, + // game logic has generated a warning and warnings are treated as error + kQuit_GameWarning = kQuitKind_GameException | 0x20, + // game logic has generated an error (often script error) + kQuit_GameError = kQuitKind_GameException | 0x30, + + // any kind of a fatal engine error + kQuit_FatalError = kQuitKind_EngineException }; #endif diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp index e7eeb09e6ba4..48ad214c2c17 100644 --- a/engines/ags/engine/main/update.cpp +++ b/engines/ags/engine/main/update.cpp @@ -53,17 +53,17 @@ using namespace AGS::Common; using namespace AGS::Engine; extern MoveList *mls; -extern RoomStatus*croom; +extern RoomStatus *croom; extern GameSetupStruct game; extern GameState play; extern RoomStruct thisroom; -extern RoomObject*objs; -extern ViewStruct*views; +extern RoomObject *objs; +extern ViewStruct *views; extern int our_eip; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern CharacterExtras *charextra; extern CharacterInfo *facetalkchar; -extern int face_talking,facetalkview,facetalkwait,facetalkframe; +extern int face_talking, facetalkview, facetalkwait, facetalkframe; extern int facetalkloop, facetalkrepeat, facetalkAllowBlink; extern int facetalkBlinkLoop; extern bool facetalk_qfg4_override_placement_x, facetalk_qfg4_override_placement_y; @@ -72,434 +72,399 @@ extern int numLipLines, curLipLine, curLipLinePhoneme; extern int is_text_overlay; extern IGraphicsDriver *gfxDriver; -int do_movelist_move(short*mlnum,int*xx,int*yy) { - int need_to_fix_sprite=0; - if (mlnum[0]<1) quit("movelist_move: attempted to move on a non-exist movelist"); - MoveList*cmls; cmls=&mls[mlnum[0]]; - fixed xpermove=cmls->xpermove[cmls->onstage],ypermove=cmls->ypermove[cmls->onstage]; - - short targetx=short((cmls->pos[cmls->onstage+1] >> 16) & 0x00ffff); - short targety=short(cmls->pos[cmls->onstage+1] & 0x00ffff); - int xps=xx[0],yps=yy[0]; - if (cmls->doneflag & 1) { - // if the X-movement has finished, and the Y-per-move is < 1, finish - // This can cause jump at the end, but without it the character will - // walk on the spot for a while if the Y-per-move is for example 0.2 +int do_movelist_move(short *mlnum, int *xx, int *yy) { + int need_to_fix_sprite = 0; + if (mlnum[0] < 1) quit("movelist_move: attempted to move on a non-exist movelist"); + MoveList *cmls; + cmls = &mls[mlnum[0]]; + fixed xpermove = cmls->xpermove[cmls->onstage], ypermove = cmls->ypermove[cmls->onstage]; + + short targetx = short((cmls->pos[cmls->onstage + 1] >> 16) & 0x00ffff); + short targety = short(cmls->pos[cmls->onstage + 1] & 0x00ffff); + int xps = xx[0], yps = yy[0]; + if (cmls->doneflag & 1) { + // if the X-movement has finished, and the Y-per-move is < 1, finish + // This can cause jump at the end, but without it the character will + // walk on the spot for a while if the Y-per-move is for example 0.2 // if ((ypermove & 0xfffff000) == 0) cmls->doneflag|=2; // int ypmm=(ypermove >> 16) & 0x0000ffff; - // NEW 2.15 SR-1 plan: if X-movement has finished, and Y-per-move is < 1, - // allow it to finish more easily by moving target zone - - int adjAmnt = 3; - // 2.70: if the X permove is also <=1, don't do the skipping - if (((xpermove & 0xffff0000) == 0xffff0000) || - ((xpermove & 0xffff0000) == 0x00000000)) - adjAmnt = 2; - - // 2.61 RC1: correct this to work with > -1 as well as < 1 - if (ypermove == 0) { } - // Y per move is < 1, so finish the move - else if ((ypermove & 0xffff0000) == 0) - targety -= adjAmnt; - // Y per move is -1 exactly, don't snap to finish - else if (ypermove == 0xffff0000) { } - // Y per move is > -1, so finish the move - else if ((ypermove & 0xffff0000) == 0xffff0000) - targety += adjAmnt; - } - else xps=cmls->fromx+(int)(fixtof(xpermove)*(float)cmls->onpart); - - if (cmls->doneflag & 2) { - // Y-movement has finished - - int adjAmnt = 3; - - // if the Y permove is also <=1, don't skip as far - if (((ypermove & 0xffff0000) == 0xffff0000) || - ((ypermove & 0xffff0000) == 0x00000000)) - adjAmnt = 2; - - if (xpermove == 0) { } - // Y per move is < 1, so finish the move - else if ((xpermove & 0xffff0000) == 0) - targetx -= adjAmnt; - // X per move is -1 exactly, don't snap to finish - else if (xpermove == 0xffff0000) { } - // X per move is > -1, so finish the move - else if ((xpermove & 0xffff0000) == 0xffff0000) - targetx += adjAmnt; - -/* int xpmm=(xpermove >> 16) & 0x0000ffff; -// if ((xpmm==0) | (xpmm==0xffff)) cmls->doneflag|=1; - if (xpmm==0) cmls->doneflag|=1;*/ - } - else yps=cmls->fromy+(int)(fixtof(ypermove)*(float)cmls->onpart); - // check if finished horizontal movement - if (((xpermove > 0) && (xps >= targetx)) || - ((xpermove < 0) && (xps <= targetx))) { - cmls->doneflag|=1; - xps = targetx; - // if the Y is almost there too, finish it - // this is new in v2.40 - // removed in 2.70 - /*if (abs(yps - targety) <= 2) - yps = targety;*/ - } - else if (xpermove == 0) - cmls->doneflag|=1; - // check if finished vertical movement - if ((ypermove > 0) & (yps>=targety)) { - cmls->doneflag|=2; - yps = targety; - } - else if ((ypermove < 0) & (yps<=targety)) { - cmls->doneflag|=2; - yps = targety; - } - else if (ypermove == 0) - cmls->doneflag|=2; - - if ((cmls->doneflag & 0x03)==3) { - // this stage is done, go on to the next stage - // signed shorts to ensure that numbers like -20 do not become 65515 - cmls->fromx=(signed short)((cmls->pos[cmls->onstage+1] >> 16) & 0x000ffff); - cmls->fromy=(signed short)(cmls->pos[cmls->onstage+1] & 0x000ffff); - if ((cmls->fromx > 65000) || (cmls->fromy > 65000)) - quit("do_movelist: int to short rounding error"); - - cmls->onstage++; cmls->onpart=-1; cmls->doneflag&=0xf0; - cmls->lastx=-1; - if (cmls->onstage < cmls->numstage) { - xps=cmls->fromx; yps=cmls->fromy; } - if (cmls->onstage>=cmls->numstage-1) { // last stage is just dest pos - cmls->numstage=0; - mlnum[0]=0; - need_to_fix_sprite=1; - } - else need_to_fix_sprite=2; - } - cmls->onpart++; - xx[0]=xps; yy[0]=yps; - return need_to_fix_sprite; - } - - -void update_script_timers() -{ - if (play.gscript_timer > 0) play.gscript_timer--; - for (int aa=0;aa 1) play.script_timers[aa]--; - } + // NEW 2.15 SR-1 plan: if X-movement has finished, and Y-per-move is < 1, + // allow it to finish more easily by moving target zone + + int adjAmnt = 3; + // 2.70: if the X permove is also <=1, don't do the skipping + if (((xpermove & 0xffff0000) == 0xffff0000) || + ((xpermove & 0xffff0000) == 0x00000000)) + adjAmnt = 2; + + // 2.61 RC1: correct this to work with > -1 as well as < 1 + if (ypermove == 0) { } + // Y per move is < 1, so finish the move + else if ((ypermove & 0xffff0000) == 0) + targety -= adjAmnt; + // Y per move is -1 exactly, don't snap to finish + else if (ypermove == 0xffff0000) { } + // Y per move is > -1, so finish the move + else if ((ypermove & 0xffff0000) == 0xffff0000) + targety += adjAmnt; + } else xps = cmls->fromx + (int)(fixtof(xpermove) * (float)cmls->onpart); + + if (cmls->doneflag & 2) { + // Y-movement has finished + + int adjAmnt = 3; + + // if the Y permove is also <=1, don't skip as far + if (((ypermove & 0xffff0000) == 0xffff0000) || + ((ypermove & 0xffff0000) == 0x00000000)) + adjAmnt = 2; + + if (xpermove == 0) { } + // Y per move is < 1, so finish the move + else if ((xpermove & 0xffff0000) == 0) + targetx -= adjAmnt; + // X per move is -1 exactly, don't snap to finish + else if (xpermove == 0xffff0000) { } + // X per move is > -1, so finish the move + else if ((xpermove & 0xffff0000) == 0xffff0000) + targetx += adjAmnt; + + /* int xpmm=(xpermove >> 16) & 0x0000ffff; + // if ((xpmm==0) | (xpmm==0xffff)) cmls->doneflag|=1; + if (xpmm==0) cmls->doneflag|=1;*/ + } else yps = cmls->fromy + (int)(fixtof(ypermove) * (float)cmls->onpart); + // check if finished horizontal movement + if (((xpermove > 0) && (xps >= targetx)) || + ((xpermove < 0) && (xps <= targetx))) { + cmls->doneflag |= 1; + xps = targetx; + // if the Y is almost there too, finish it + // this is new in v2.40 + // removed in 2.70 + /*if (abs(yps - targety) <= 2) + yps = targety;*/ + } else if (xpermove == 0) + cmls->doneflag |= 1; + // check if finished vertical movement + if ((ypermove > 0) & (yps >= targety)) { + cmls->doneflag |= 2; + yps = targety; + } else if ((ypermove < 0) & (yps <= targety)) { + cmls->doneflag |= 2; + yps = targety; + } else if (ypermove == 0) + cmls->doneflag |= 2; + + if ((cmls->doneflag & 0x03) == 3) { + // this stage is done, go on to the next stage + // signed shorts to ensure that numbers like -20 do not become 65515 + cmls->fromx = (signed short)((cmls->pos[cmls->onstage + 1] >> 16) & 0x000ffff); + cmls->fromy = (signed short)(cmls->pos[cmls->onstage + 1] & 0x000ffff); + if ((cmls->fromx > 65000) || (cmls->fromy > 65000)) + quit("do_movelist: int to short rounding error"); + + cmls->onstage++; + cmls->onpart = -1; + cmls->doneflag &= 0xf0; + cmls->lastx = -1; + if (cmls->onstage < cmls->numstage) { + xps = cmls->fromx; + yps = cmls->fromy; + } + if (cmls->onstage >= cmls->numstage - 1) { // last stage is just dest pos + cmls->numstage = 0; + mlnum[0] = 0; + need_to_fix_sprite = 1; + } else need_to_fix_sprite = 2; + } + cmls->onpart++; + xx[0] = xps; + yy[0] = yps; + return need_to_fix_sprite; } -void update_cycling_views() -{ + +void update_script_timers() { + if (play.gscript_timer > 0) play.gscript_timer--; + for (int aa = 0; aa < MAX_TIMERS; aa++) { + if (play.script_timers[aa] > 1) play.script_timers[aa]--; + } +} + +void update_cycling_views() { // update graphics for object if cycling view - for (int aa=0;aanumobj;aa++) { + for (int aa = 0; aa < croom->numobj; aa++) { - RoomObject * obj = &objs[aa]; + RoomObject *obj = &objs[aa]; - obj->UpdateCyclingView(); - } + obj->UpdateCyclingView(); + } } -void update_shadow_areas() -{ +void update_shadow_areas() { // shadow areas - int onwalkarea = get_walkable_area_at_character (game.playercharacter); - if (onwalkarea<0) ; - else if (playerchar->flags & CHF_FIXVIEW) ; - else { onwalkarea=thisroom.WalkAreas[onwalkarea].Light; - if (onwalkarea>0) playerchar->view=onwalkarea-1; - else if (thisroom.Options.PlayerView==0) playerchar->view=playerchar->defview; - else playerchar->view=thisroom.Options.PlayerView-1; - } + int onwalkarea = get_walkable_area_at_character(game.playercharacter); + if (onwalkarea < 0) ; + else if (playerchar->flags & CHF_FIXVIEW) ; + else { + onwalkarea = thisroom.WalkAreas[onwalkarea].Light; + if (onwalkarea > 0) playerchar->view = onwalkarea - 1; + else if (thisroom.Options.PlayerView == 0) playerchar->view = playerchar->defview; + else playerchar->view = thisroom.Options.PlayerView - 1; + } } -void update_character_move_and_anim(int &numSheep, int *followingAsSheep) -{ +void update_character_move_and_anim(int &numSheep, int *followingAsSheep) { // move & animate characters - for (int aa=0;aaUpdateMoveAndAnim(aa, chex, numSheep, followingAsSheep); - } + chi->UpdateMoveAndAnim(aa, chex, numSheep, followingAsSheep); + } } -void update_following_exactly_characters(int &numSheep, int *followingAsSheep) -{ +void update_following_exactly_characters(int &numSheep, int *followingAsSheep) { // update location of all following_exactly characters - for (int aa = 0; aa < numSheep; aa++) { - CharacterInfo *chi = &game.chars[followingAsSheep[aa]]; + for (int aa = 0; aa < numSheep; aa++) { + CharacterInfo *chi = &game.chars[followingAsSheep[aa]]; - chi->UpdateFollowingExactlyCharacter(); - } + chi->UpdateFollowingExactlyCharacter(); + } } -void update_overlay_timers() -{ +void update_overlay_timers() { // update overlay timers - for (size_t i = 0; i < screenover.size();) { - if (screenover[i].timeout > 0) { - screenover[i].timeout--; - if (screenover[i].timeout == 0) - { - remove_screen_overlay_index(i); - continue; - } - } - i++; - } + for (size_t i = 0; i < screenover.size();) { + if (screenover[i].timeout > 0) { + screenover[i].timeout--; + if (screenover[i].timeout == 0) { + remove_screen_overlay_index(i); + continue; + } + } + i++; + } } -void update_speech_and_messages() -{ - bool is_voice_playing = false; - if (play.speech_has_voice) - { - AudioChannelsLock lock; - auto *ch = lock.GetChannel(SCHAN_SPEECH); - is_voice_playing = ch && ch->is_playing(); - } - // determine if speech text should be removed - if (play.messagetime>=0) { - play.messagetime--; - // extend life of text if the voice hasn't finished yet - if (play.speech_has_voice && !play.speech_in_post_state) { - if ((is_voice_playing) && (play.fast_forward == 0)) { - if (play.messagetime <= 1) - play.messagetime = 1; - } - else // if the voice has finished, remove the speech - play.messagetime = 0; - } - - if (play.messagetime < 1 && play.speech_display_post_time_ms > 0 && - play.fast_forward == 0) - { - if (!play.speech_in_post_state) - { - play.messagetime = ::lround(play.speech_display_post_time_ms * get_current_fps() / 1000.0f); - } - play.speech_in_post_state = !play.speech_in_post_state; - } - - if (play.messagetime < 1) - { - if (play.fast_forward > 0) - { - remove_screen_overlay(OVER_TEXTMSG); - } - else if (play.cant_skip_speech & SKIP_AUTOTIMER) - { - remove_screen_overlay(OVER_TEXTMSG); - play.SetIgnoreInput(play.ignore_user_input_after_text_timeout_ms); - } - } - } +void update_speech_and_messages() { + bool is_voice_playing = false; + if (play.speech_has_voice) { + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_SPEECH); + is_voice_playing = ch && ch->is_playing(); + } + // determine if speech text should be removed + if (play.messagetime >= 0) { + play.messagetime--; + // extend life of text if the voice hasn't finished yet + if (play.speech_has_voice && !play.speech_in_post_state) { + if ((is_voice_playing) && (play.fast_forward == 0)) { + if (play.messagetime <= 1) + play.messagetime = 1; + } else // if the voice has finished, remove the speech + play.messagetime = 0; + } + + if (play.messagetime < 1 && play.speech_display_post_time_ms > 0 && + play.fast_forward == 0) { + if (!play.speech_in_post_state) { + play.messagetime = ::lround(play.speech_display_post_time_ms * get_current_fps() / 1000.0f); + } + play.speech_in_post_state = !play.speech_in_post_state; + } + + if (play.messagetime < 1) { + if (play.fast_forward > 0) { + remove_screen_overlay(OVER_TEXTMSG); + } else if (play.cant_skip_speech & SKIP_AUTOTIMER) { + remove_screen_overlay(OVER_TEXTMSG); + play.SetIgnoreInput(play.ignore_user_input_after_text_timeout_ms); + } + } + } } // update sierra-style speech -void update_sierra_speech() -{ - int voice_pos_ms = -1; - if (play.speech_has_voice) - { - AudioChannelsLock lock; - auto *ch = lock.GetChannel(SCHAN_SPEECH); - voice_pos_ms = ch ? ch->get_pos_ms() : -1; - } - if ((face_talking >= 0) && (play.fast_forward == 0)) - { - int updatedFrame = 0; - - if ((facetalkchar->blinkview > 0) && (facetalkAllowBlink)) { - if (facetalkchar->blinktimer > 0) { - // countdown to playing blink anim - facetalkchar->blinktimer--; - if (facetalkchar->blinktimer == 0) { - facetalkchar->blinkframe = 0; - facetalkchar->blinktimer = -1; - updatedFrame = 2; - } - } - else if (facetalkchar->blinktimer < 0) { - // currently playing blink anim - if (facetalkchar->blinktimer < ( (0 - 6) - views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe].speed)) { - // time to advance to next frame - facetalkchar->blinktimer = -1; - facetalkchar->blinkframe++; - updatedFrame = 2; - if (facetalkchar->blinkframe >= views[facetalkchar->blinkview].loops[facetalkBlinkLoop].numFrames) - { - facetalkchar->blinkframe = 0; - facetalkchar->blinktimer = facetalkchar->blinkinterval; - } - } - else - facetalkchar->blinktimer--; - } - - } - - if (curLipLine >= 0) { - // check voice lip sync - if (curLipLinePhoneme >= splipsync[curLipLine].numPhonemes) { - // the lip-sync has finished, so just stay idle - } - else - { - while ((curLipLinePhoneme < splipsync[curLipLine].numPhonemes) && - ((curLipLinePhoneme < 0) || (voice_pos_ms >= splipsync[curLipLine].endtimeoffs[curLipLinePhoneme]))) - { - curLipLinePhoneme ++; - if (curLipLinePhoneme >= splipsync[curLipLine].numPhonemes) - facetalkframe = game.default_lipsync_frame; - else - facetalkframe = splipsync[curLipLine].frame[curLipLinePhoneme]; - - if (facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) - facetalkframe = 0; - - updatedFrame |= 1; - } - } - } - else if (facetalkwait>0) facetalkwait--; - // don't animate if the speech has finished - else if ((play.messagetime < 1) && (facetalkframe == 0) && - // if play.close_mouth_speech_time = 0, this means animation should play till - // the speech ends; but this should not work in voice mode, and also if the - // speech is in the "post" state - (play.speech_has_voice || play.speech_in_post_state || play.close_mouth_speech_time > 0)) - ; - else { - // Close mouth at end of sentence: if speech has entered the "post" state, - // or if this is a text only mode and close_mouth_speech_time is set - if (play.speech_in_post_state || - (!play.speech_has_voice && - (play.messagetime < play.close_mouth_speech_time) && - (play.close_mouth_speech_time > 0))) { - facetalkframe = 0; - facetalkwait = play.messagetime; - } - else if ((game.options[OPT_LIPSYNCTEXT]) && (facetalkrepeat > 0)) { - // lip-sync speech (and not a thought) - facetalkwait = update_lip_sync (facetalkview, facetalkloop, &facetalkframe); - // It is actually displayed for facetalkwait+1 loops - // (because when it's 1, it gets --'d then wait for next time) - facetalkwait --; - } - else { - // normal non-lip-sync - facetalkframe++; - if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) || - (!play.speech_has_voice && (play.messagetime < 1) && (play.close_mouth_speech_time > 0))) { - - if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) && - (views[facetalkview].loops[facetalkloop].RunNextLoop())) - { - facetalkloop++; - } - else - { - facetalkloop = 0; - } - facetalkframe = 0; - if (!facetalkrepeat) - facetalkwait = 999999; - } - if ((facetalkframe != 0) || (facetalkrepeat == 1)) - facetalkwait = views[facetalkview].loops[facetalkloop].frames[facetalkframe].speed + GetCharacterSpeechAnimationDelay(facetalkchar); - } - updatedFrame |= 1; - } - - // is_text_overlay might be 0 if it was only just destroyed this loop - if ((updatedFrame) && (is_text_overlay > 0)) { - - if (updatedFrame & 1) - CheckViewFrame (facetalkview, facetalkloop, facetalkframe); - if (updatedFrame & 2) - CheckViewFrame (facetalkchar->blinkview, facetalkBlinkLoop, facetalkchar->blinkframe); - - int thisPic = views[facetalkview].loops[facetalkloop].frames[facetalkframe].pic; - int view_frame_x = 0; - int view_frame_y = 0; - - if (game.options[OPT_SPEECHTYPE] == 3) { - // QFG4-style fullscreen dialog - if (facetalk_qfg4_override_placement_x) - { - view_frame_x = play.speech_portrait_x; - } - if (facetalk_qfg4_override_placement_y) - { - view_frame_y = play.speech_portrait_y; - } - else - { - view_frame_y = (screenover[face_talking].pic->GetHeight() / 2) - (game.SpriteInfos[thisPic].Height / 2); - } - screenover[face_talking].pic->Clear(0); - } - else { - screenover[face_talking].pic->ClearTransparent(); - } - - Bitmap *frame_pic = screenover[face_talking].pic; - const ViewFrame *face_vf = &views[facetalkview].loops[facetalkloop].frames[facetalkframe]; - bool face_has_alpha = (game.SpriteInfos[face_vf->pic].Flags & SPF_ALPHACHANNEL) != 0; - DrawViewFrame(frame_pic, face_vf, view_frame_x, view_frame_y); - - if ((facetalkchar->blinkview > 0) && (facetalkchar->blinktimer < 0)) { - ViewFrame *blink_vf = &views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe]; - face_has_alpha |= (game.SpriteInfos[blink_vf->pic].Flags & SPF_ALPHACHANNEL) != 0; - // draw the blinking sprite on top - DrawViewFrame(frame_pic, blink_vf, view_frame_x, view_frame_y, face_has_alpha); - } - - gfxDriver->UpdateDDBFromBitmap(screenover[face_talking].bmp, screenover[face_talking].pic, face_has_alpha); - } // end if updatedFrame - } +void update_sierra_speech() { + int voice_pos_ms = -1; + if (play.speech_has_voice) { + AudioChannelsLock lock; + auto *ch = lock.GetChannel(SCHAN_SPEECH); + voice_pos_ms = ch ? ch->get_pos_ms() : -1; + } + if ((face_talking >= 0) && (play.fast_forward == 0)) { + int updatedFrame = 0; + + if ((facetalkchar->blinkview > 0) && (facetalkAllowBlink)) { + if (facetalkchar->blinktimer > 0) { + // countdown to playing blink anim + facetalkchar->blinktimer--; + if (facetalkchar->blinktimer == 0) { + facetalkchar->blinkframe = 0; + facetalkchar->blinktimer = -1; + updatedFrame = 2; + } + } else if (facetalkchar->blinktimer < 0) { + // currently playing blink anim + if (facetalkchar->blinktimer < ((0 - 6) - views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe].speed)) { + // time to advance to next frame + facetalkchar->blinktimer = -1; + facetalkchar->blinkframe++; + updatedFrame = 2; + if (facetalkchar->blinkframe >= views[facetalkchar->blinkview].loops[facetalkBlinkLoop].numFrames) { + facetalkchar->blinkframe = 0; + facetalkchar->blinktimer = facetalkchar->blinkinterval; + } + } else + facetalkchar->blinktimer--; + } + + } + + if (curLipLine >= 0) { + // check voice lip sync + if (curLipLinePhoneme >= splipsync[curLipLine].numPhonemes) { + // the lip-sync has finished, so just stay idle + } else { + while ((curLipLinePhoneme < splipsync[curLipLine].numPhonemes) && + ((curLipLinePhoneme < 0) || (voice_pos_ms >= splipsync[curLipLine].endtimeoffs[curLipLinePhoneme]))) { + curLipLinePhoneme ++; + if (curLipLinePhoneme >= splipsync[curLipLine].numPhonemes) + facetalkframe = game.default_lipsync_frame; + else + facetalkframe = splipsync[curLipLine].frame[curLipLinePhoneme]; + + if (facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) + facetalkframe = 0; + + updatedFrame |= 1; + } + } + } else if (facetalkwait > 0) facetalkwait--; + // don't animate if the speech has finished + else if ((play.messagetime < 1) && (facetalkframe == 0) && + // if play.close_mouth_speech_time = 0, this means animation should play till + // the speech ends; but this should not work in voice mode, and also if the + // speech is in the "post" state + (play.speech_has_voice || play.speech_in_post_state || play.close_mouth_speech_time > 0)) + ; + else { + // Close mouth at end of sentence: if speech has entered the "post" state, + // or if this is a text only mode and close_mouth_speech_time is set + if (play.speech_in_post_state || + (!play.speech_has_voice && + (play.messagetime < play.close_mouth_speech_time) && + (play.close_mouth_speech_time > 0))) { + facetalkframe = 0; + facetalkwait = play.messagetime; + } else if ((game.options[OPT_LIPSYNCTEXT]) && (facetalkrepeat > 0)) { + // lip-sync speech (and not a thought) + facetalkwait = update_lip_sync(facetalkview, facetalkloop, &facetalkframe); + // It is actually displayed for facetalkwait+1 loops + // (because when it's 1, it gets --'d then wait for next time) + facetalkwait --; + } else { + // normal non-lip-sync + facetalkframe++; + if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) || + (!play.speech_has_voice && (play.messagetime < 1) && (play.close_mouth_speech_time > 0))) { + + if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) && + (views[facetalkview].loops[facetalkloop].RunNextLoop())) { + facetalkloop++; + } else { + facetalkloop = 0; + } + facetalkframe = 0; + if (!facetalkrepeat) + facetalkwait = 999999; + } + if ((facetalkframe != 0) || (facetalkrepeat == 1)) + facetalkwait = views[facetalkview].loops[facetalkloop].frames[facetalkframe].speed + GetCharacterSpeechAnimationDelay(facetalkchar); + } + updatedFrame |= 1; + } + + // is_text_overlay might be 0 if it was only just destroyed this loop + if ((updatedFrame) && (is_text_overlay > 0)) { + + if (updatedFrame & 1) + CheckViewFrame(facetalkview, facetalkloop, facetalkframe); + if (updatedFrame & 2) + CheckViewFrame(facetalkchar->blinkview, facetalkBlinkLoop, facetalkchar->blinkframe); + + int thisPic = views[facetalkview].loops[facetalkloop].frames[facetalkframe].pic; + int view_frame_x = 0; + int view_frame_y = 0; + + if (game.options[OPT_SPEECHTYPE] == 3) { + // QFG4-style fullscreen dialog + if (facetalk_qfg4_override_placement_x) { + view_frame_x = play.speech_portrait_x; + } + if (facetalk_qfg4_override_placement_y) { + view_frame_y = play.speech_portrait_y; + } else { + view_frame_y = (screenover[face_talking].pic->GetHeight() / 2) - (game.SpriteInfos[thisPic].Height / 2); + } + screenover[face_talking].pic->Clear(0); + } else { + screenover[face_talking].pic->ClearTransparent(); + } + + Bitmap *frame_pic = screenover[face_talking].pic; + const ViewFrame *face_vf = &views[facetalkview].loops[facetalkloop].frames[facetalkframe]; + bool face_has_alpha = (game.SpriteInfos[face_vf->pic].Flags & SPF_ALPHACHANNEL) != 0; + DrawViewFrame(frame_pic, face_vf, view_frame_x, view_frame_y); + + if ((facetalkchar->blinkview > 0) && (facetalkchar->blinktimer < 0)) { + ViewFrame *blink_vf = &views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe]; + face_has_alpha |= (game.SpriteInfos[blink_vf->pic].Flags & SPF_ALPHACHANNEL) != 0; + // draw the blinking sprite on top + DrawViewFrame(frame_pic, blink_vf, view_frame_x, view_frame_y, face_has_alpha); + } + + gfxDriver->UpdateDDBFromBitmap(screenover[face_talking].bmp, screenover[face_talking].pic, face_has_alpha); + } // end if updatedFrame + } } // update_stuff: moves and animates objects, executes repeat scripts, and // the like. void update_stuff() { - - our_eip = 20; - update_script_timers(); + our_eip = 20; + + update_script_timers(); + + update_cycling_views(); - update_cycling_views(); + our_eip = 21; - our_eip = 21; + update_shadow_areas(); - update_shadow_areas(); - - our_eip = 22; + our_eip = 22; - int numSheep = 0; - int followingAsSheep[MAX_SHEEP]; + int numSheep = 0; + int followingAsSheep[MAX_SHEEP]; - update_character_move_and_anim(numSheep, followingAsSheep); + update_character_move_and_anim(numSheep, followingAsSheep); - update_following_exactly_characters(numSheep, followingAsSheep); + update_following_exactly_characters(numSheep, followingAsSheep); - our_eip = 23; + our_eip = 23; - update_overlay_timers(); + update_overlay_timers(); - update_speech_and_messages(); + update_speech_and_messages(); - our_eip = 24; + our_eip = 24; - update_sierra_speech(); + update_sierra_speech(); - our_eip = 25; + our_eip = 25; } diff --git a/engines/ags/engine/main/update.h b/engines/ags/engine/main/update.h index c7bcde862e54..45dd6158b395 100644 --- a/engines/ags/engine/main/update.h +++ b/engines/ags/engine/main/update.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_MAIN_UPDATE_H #define AGS_ENGINE_MAIN_UPDATE_H -#define MAX_SHEEP 30 // sheep == follower +#define MAX_SHEEP 30 // sheep == follower -int do_movelist_move(short*mlnum,int*xx,int*yy); +int do_movelist_move(short *mlnum, int *xx, int *yy); void update_stuff(); #endif diff --git a/engines/ags/engine/media/audio/ambientsound.cpp b/engines/ags/engine/media/audio/ambientsound.cpp index 89a353a81b28..a2676a85c7ce 100644 --- a/engines/ags/engine/media/audio/ambientsound.cpp +++ b/engines/ags/engine/media/audio/ambientsound.cpp @@ -27,28 +27,26 @@ using AGS::Common::Stream; -bool AmbientSound::IsPlaying () { - if (channel <= 0) - return false; - return channel_is_playing(channel); +bool AmbientSound::IsPlaying() { + if (channel <= 0) + return false; + return channel_is_playing(channel); } -void AmbientSound::ReadFromFile(Stream *in) -{ - channel = in->ReadInt32(); - x = in->ReadInt32(); - y = in->ReadInt32(); - vol = in->ReadInt32(); - num = in->ReadInt32(); - maxdist = in->ReadInt32(); +void AmbientSound::ReadFromFile(Stream *in) { + channel = in->ReadInt32(); + x = in->ReadInt32(); + y = in->ReadInt32(); + vol = in->ReadInt32(); + num = in->ReadInt32(); + maxdist = in->ReadInt32(); } -void AmbientSound::WriteToFile(Stream *out) -{ - out->WriteInt32(channel); - out->WriteInt32(x); - out->WriteInt32(y); - out->WriteInt32(vol); - out->WriteInt32(num); - out->WriteInt32(maxdist); +void AmbientSound::WriteToFile(Stream *out) { + out->WriteInt32(channel); + out->WriteInt32(x); + out->WriteInt32(y); + out->WriteInt32(vol); + out->WriteInt32(num); + out->WriteInt32(maxdist); } diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h index edefea665ca7..3a4fb9dc23ed 100644 --- a/engines/ags/engine/media/audio/ambientsound.h +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -24,22 +24,26 @@ #define AGS_ENGINE_MEDIA_AUDIO_AMBIENTSOUND_H // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define AMBIENCE_FULL_DIST 25 struct AmbientSound { - int channel; // channel number, 1 upwards - int x,y; - int vol; - int num; // sound number, eg. 3 = sound3.wav - int maxdist; + int channel; // channel number, 1 upwards + int x, y; + int vol; + int num; // sound number, eg. 3 = sound3.wav + int maxdist; - bool IsPlaying(); + bool IsPlaying(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); }; #endif diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 656e06d5dc50..12f818882451 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -53,57 +53,50 @@ using namespace AGS::Engine; //----------------------- //sound channel management; all access goes through here, which can't be done without a lock -static std::array _channels; +static std::array < SOUNDCLIP *, MAX_SOUND_CHANNELS + 1 > _channels; AGS::Engine::Mutex AudioChannelsLock::s_mutex; -SOUNDCLIP *AudioChannelsLock::GetChannel(int index) -{ - return _channels[index]; +SOUNDCLIP *AudioChannelsLock::GetChannel(int index) { + return _channels[index]; } -SOUNDCLIP *AudioChannelsLock::GetChannelIfPlaying(int index) -{ - auto *ch = _channels[index]; - return (ch != nullptr && ch->is_playing()) ? ch : nullptr; +SOUNDCLIP *AudioChannelsLock::GetChannelIfPlaying(int index) { + auto *ch = _channels[index]; + return (ch != nullptr && ch->is_playing()) ? ch : nullptr; } -SOUNDCLIP *AudioChannelsLock::SetChannel(int index, SOUNDCLIP* ch) -{ - // TODO: store clips in smart pointers - if (_channels[index] == ch) - Debug::Printf(kDbgMsg_Warn, "WARNING: channel %d - same clip assigned", index); - else if (_channels[index] != nullptr && ch != nullptr) - Debug::Printf(kDbgMsg_Warn, "WARNING: channel %d - clip overwritten", index); - _channels[index] = ch; - return ch; +SOUNDCLIP *AudioChannelsLock::SetChannel(int index, SOUNDCLIP *ch) { + // TODO: store clips in smart pointers + if (_channels[index] == ch) + Debug::Printf(kDbgMsg_Warn, "WARNING: channel %d - same clip assigned", index); + else if (_channels[index] != nullptr && ch != nullptr) + Debug::Printf(kDbgMsg_Warn, "WARNING: channel %d - clip overwritten", index); + _channels[index] = ch; + return ch; } -SOUNDCLIP *AudioChannelsLock::MoveChannel(int to, int from) -{ - auto from_ch = _channels[from]; - _channels[from] = nullptr; - return SetChannel(to, from_ch); +SOUNDCLIP *AudioChannelsLock::MoveChannel(int to, int from) { + auto from_ch = _channels[from]; + _channels[from] = nullptr; + return SetChannel(to, from_ch); } //----------------------- // Channel helpers -bool channel_has_clip(int chanid) -{ - AudioChannelsLock lock; - return lock.GetChannel(chanid) != nullptr; +bool channel_has_clip(int chanid) { + AudioChannelsLock lock; + return lock.GetChannel(chanid) != nullptr; } -bool channel_is_playing(int chanid) -{ - AudioChannelsLock lock; - return lock.GetChannelIfPlaying(chanid) != nullptr; +bool channel_is_playing(int chanid) { + AudioChannelsLock lock; + return lock.GetChannelIfPlaying(chanid) != nullptr; } -void set_clip_to_channel(int chanid, SOUNDCLIP *clip) -{ - AudioChannelsLock lock; - lock.SetChannel(chanid, clip); +void set_clip_to_channel(int chanid, SOUNDCLIP *clip) { + AudioChannelsLock lock; + lock.SetChannel(chanid, clip); } //----------------------- @@ -113,7 +106,7 @@ extern GameSetupStruct game; extern GameSetup usetup; extern GameState play; extern RoomStruct thisroom; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; extern volatile int switching_away_from_game; @@ -127,676 +120,598 @@ int reserved_channel_count = 0; AGS::Engine::Thread audioThread; -void calculate_reserved_channel_count() -{ - int reservedChannels = 0; - for (size_t i = 0; i < game.audioClipTypes.size(); i++) - { - reservedChannels += game.audioClipTypes[i].reservedChannels; - } - reserved_channel_count = reservedChannels; +void calculate_reserved_channel_count() { + int reservedChannels = 0; + for (size_t i = 0; i < game.audioClipTypes.size(); i++) { + reservedChannels += game.audioClipTypes[i].reservedChannels; + } + reserved_channel_count = reservedChannels; } -void update_clip_default_volume(ScriptAudioClip *audioClip) -{ - if (play.default_audio_type_volumes[audioClip->type] >= 0) - { - audioClip->defaultVolume = play.default_audio_type_volumes[audioClip->type]; - } +void update_clip_default_volume(ScriptAudioClip *audioClip) { + if (play.default_audio_type_volumes[audioClip->type] >= 0) { + audioClip->defaultVolume = play.default_audio_type_volumes[audioClip->type]; + } } -void start_fading_in_new_track_if_applicable(int fadeInChannel, ScriptAudioClip *newSound) -{ - int crossfadeSpeed = game.audioClipTypes[newSound->type].crossfadeSpeed; - if (crossfadeSpeed > 0) - { - update_clip_default_volume(newSound); - play.crossfade_in_volume_per_step = crossfadeSpeed; - play.crossfade_final_volume_in = newSound->defaultVolume; - play.crossfading_in_channel = fadeInChannel; - } +void start_fading_in_new_track_if_applicable(int fadeInChannel, ScriptAudioClip *newSound) { + int crossfadeSpeed = game.audioClipTypes[newSound->type].crossfadeSpeed; + if (crossfadeSpeed > 0) { + update_clip_default_volume(newSound); + play.crossfade_in_volume_per_step = crossfadeSpeed; + play.crossfade_final_volume_in = newSound->defaultVolume; + play.crossfading_in_channel = fadeInChannel; + } } -static void move_track_to_crossfade_channel(int currentChannel, int crossfadeSpeed, int fadeInChannel, ScriptAudioClip *newSound) -{ - AudioChannelsLock lock; - stop_and_destroy_channel(SPECIAL_CROSSFADE_CHANNEL); - auto *cfade_clip = lock.MoveChannel(SPECIAL_CROSSFADE_CHANNEL, currentChannel); - if (!cfade_clip) - return; - - play.crossfading_out_channel = SPECIAL_CROSSFADE_CHANNEL; - play.crossfade_step = 0; - play.crossfade_initial_volume_out = cfade_clip->get_volume(); - play.crossfade_out_volume_per_step = crossfadeSpeed; - - play.crossfading_in_channel = fadeInChannel; - if (newSound != nullptr) - { - start_fading_in_new_track_if_applicable(fadeInChannel, newSound); - } +static void move_track_to_crossfade_channel(int currentChannel, int crossfadeSpeed, int fadeInChannel, ScriptAudioClip *newSound) { + AudioChannelsLock lock; + stop_and_destroy_channel(SPECIAL_CROSSFADE_CHANNEL); + auto *cfade_clip = lock.MoveChannel(SPECIAL_CROSSFADE_CHANNEL, currentChannel); + if (!cfade_clip) + return; + + play.crossfading_out_channel = SPECIAL_CROSSFADE_CHANNEL; + play.crossfade_step = 0; + play.crossfade_initial_volume_out = cfade_clip->get_volume(); + play.crossfade_out_volume_per_step = crossfadeSpeed; + + play.crossfading_in_channel = fadeInChannel; + if (newSound != nullptr) { + start_fading_in_new_track_if_applicable(fadeInChannel, newSound); + } } -void stop_or_fade_out_channel(int fadeOutChannel, int fadeInChannel, ScriptAudioClip *newSound) -{ - ScriptAudioClip *sourceClip = AudioChannel_GetPlayingClip(&scrAudioChannel[fadeOutChannel]); - if ((sourceClip != nullptr) && (game.audioClipTypes[sourceClip->type].crossfadeSpeed > 0)) - { - move_track_to_crossfade_channel(fadeOutChannel, game.audioClipTypes[sourceClip->type].crossfadeSpeed, fadeInChannel, newSound); - } - else - { - stop_and_destroy_channel(fadeOutChannel); - } +void stop_or_fade_out_channel(int fadeOutChannel, int fadeInChannel, ScriptAudioClip *newSound) { + ScriptAudioClip *sourceClip = AudioChannel_GetPlayingClip(&scrAudioChannel[fadeOutChannel]); + if ((sourceClip != nullptr) && (game.audioClipTypes[sourceClip->type].crossfadeSpeed > 0)) { + move_track_to_crossfade_channel(fadeOutChannel, game.audioClipTypes[sourceClip->type].crossfadeSpeed, fadeInChannel, newSound); + } else { + stop_and_destroy_channel(fadeOutChannel); + } } -static int find_free_audio_channel(ScriptAudioClip *clip, int priority, bool interruptEqualPriority) -{ - AudioChannelsLock lock; - - int lowestPrioritySoFar = 9999999; - int lowestPriorityID = -1; - int channelToUse = -1; - - if (!interruptEqualPriority) - priority--; - - int startAtChannel = reserved_channel_count; - int endBeforeChannel = MAX_SOUND_CHANNELS; - - if (game.audioClipTypes[clip->type].reservedChannels > 0) - { - startAtChannel = 0; - for (int i = 0; i < clip->type; i++) - { - startAtChannel += game.audioClipTypes[i].reservedChannels; - } - endBeforeChannel = startAtChannel + game.audioClipTypes[clip->type].reservedChannels; - } - - for (int i = startAtChannel; i < endBeforeChannel; i++) - { - auto* ch = lock.GetChannelIfPlaying(i); - if (ch == nullptr) - { - channelToUse = i; - stop_and_destroy_channel(i); - break; - } - if ((ch->priority < lowestPrioritySoFar) && - (ch->sourceClipType == clip->type)) - { - lowestPrioritySoFar = ch->priority; - lowestPriorityID = i; - } - } - - if ((channelToUse < 0) && (lowestPriorityID >= 0) && - (lowestPrioritySoFar <= priority)) - { - stop_or_fade_out_channel(lowestPriorityID, lowestPriorityID, clip); - channelToUse = lowestPriorityID; - } - else if ((channelToUse >= 0) && (play.crossfading_in_channel < 1)) - { - start_fading_in_new_track_if_applicable(channelToUse, clip); - } - return channelToUse; +static int find_free_audio_channel(ScriptAudioClip *clip, int priority, bool interruptEqualPriority) { + AudioChannelsLock lock; + + int lowestPrioritySoFar = 9999999; + int lowestPriorityID = -1; + int channelToUse = -1; + + if (!interruptEqualPriority) + priority--; + + int startAtChannel = reserved_channel_count; + int endBeforeChannel = MAX_SOUND_CHANNELS; + + if (game.audioClipTypes[clip->type].reservedChannels > 0) { + startAtChannel = 0; + for (int i = 0; i < clip->type; i++) { + startAtChannel += game.audioClipTypes[i].reservedChannels; + } + endBeforeChannel = startAtChannel + game.audioClipTypes[clip->type].reservedChannels; + } + + for (int i = startAtChannel; i < endBeforeChannel; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if (ch == nullptr) { + channelToUse = i; + stop_and_destroy_channel(i); + break; + } + if ((ch->priority < lowestPrioritySoFar) && + (ch->sourceClipType == clip->type)) { + lowestPrioritySoFar = ch->priority; + lowestPriorityID = i; + } + } + + if ((channelToUse < 0) && (lowestPriorityID >= 0) && + (lowestPrioritySoFar <= priority)) { + stop_or_fade_out_channel(lowestPriorityID, lowestPriorityID, clip); + channelToUse = lowestPriorityID; + } else if ((channelToUse >= 0) && (play.crossfading_in_channel < 1)) { + start_fading_in_new_track_if_applicable(channelToUse, clip); + } + return channelToUse; } -bool is_audiotype_allowed_to_play(AudioFileType type) -{ - return (type == eAudioFileMIDI && usetup.midicard != MIDI_NONE) || - (type != eAudioFileMIDI && usetup.digicard != DIGI_NONE); +bool is_audiotype_allowed_to_play(AudioFileType type) { + return (type == eAudioFileMIDI && usetup.midicard != MIDI_NONE) || + (type != eAudioFileMIDI && usetup.digicard != DIGI_NONE); } -SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat) -{ - if (!is_audiotype_allowed_to_play((AudioFileType)audioClip->fileType)) - { - return nullptr; - } - - update_clip_default_volume(audioClip); - - SOUNDCLIP *soundClip = nullptr; - AssetPath asset_name = get_audio_clip_assetpath(audioClip->bundlingType, audioClip->fileName); - switch (audioClip->fileType) - { - case eAudioFileOGG: - soundClip = my_load_static_ogg(asset_name, audioClip->defaultVolume, repeat); - break; - case eAudioFileMP3: - soundClip = my_load_static_mp3(asset_name, audioClip->defaultVolume, repeat); - break; - case eAudioFileWAV: - case eAudioFileVOC: - soundClip = my_load_wave(asset_name, audioClip->defaultVolume, repeat); - break; - case eAudioFileMIDI: - soundClip = my_load_midi(asset_name, repeat); - break; - case eAudioFileMOD: +SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat) { + if (!is_audiotype_allowed_to_play((AudioFileType)audioClip->fileType)) { + return nullptr; + } + + update_clip_default_volume(audioClip); + + SOUNDCLIP *soundClip = nullptr; + AssetPath asset_name = get_audio_clip_assetpath(audioClip->bundlingType, audioClip->fileName); + switch (audioClip->fileType) { + case eAudioFileOGG: + soundClip = my_load_static_ogg(asset_name, audioClip->defaultVolume, repeat); + break; + case eAudioFileMP3: + soundClip = my_load_static_mp3(asset_name, audioClip->defaultVolume, repeat); + break; + case eAudioFileWAV: + case eAudioFileVOC: + soundClip = my_load_wave(asset_name, audioClip->defaultVolume, repeat); + break; + case eAudioFileMIDI: + soundClip = my_load_midi(asset_name, repeat); + break; + case eAudioFileMOD: #ifndef PSP_NO_MOD_PLAYBACK - soundClip = my_load_mod(asset_name, repeat); + soundClip = my_load_mod(asset_name, repeat); #else - soundClip = NULL; + soundClip = NULL; #endif - break; - default: - quitprintf("AudioClip.Play: invalid audio file type encountered: %d", audioClip->fileType); - } - if (soundClip != nullptr) - { - soundClip->set_volume_percent(audioClip->defaultVolume); - soundClip->sourceClip = audioClip; - soundClip->sourceClipType = audioClip->type; - } - return soundClip; + break; + default: + quitprintf("AudioClip.Play: invalid audio file type encountered: %d", audioClip->fileType); + } + if (soundClip != nullptr) { + soundClip->set_volume_percent(audioClip->defaultVolume); + soundClip->sourceClip = audioClip; + soundClip->sourceClipType = audioClip->type; + } + return soundClip; } -static void audio_update_polled_stuff() -{ - /////////////////////////////////////////////////////////////////////////// - // Do crossfade - play.crossfade_step++; - - AudioChannelsLock lock; - - if (play.crossfading_out_channel > 0 && !lock.GetChannelIfPlaying(play.crossfading_out_channel)) - play.crossfading_out_channel = 0; - - if (play.crossfading_out_channel > 0) - { - SOUNDCLIP* ch = lock.GetChannel(play.crossfading_out_channel); - int newVolume = ch ? ch->get_volume() - play.crossfade_out_volume_per_step : 0; - if (newVolume > 0) - { - AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_out_channel], newVolume); - } - else - { - stop_and_destroy_channel(play.crossfading_out_channel); - play.crossfading_out_channel = 0; - } - } - - if (play.crossfading_in_channel > 0 && !lock.GetChannelIfPlaying(play.crossfading_in_channel)) - play.crossfading_in_channel = 0; - - if (play.crossfading_in_channel > 0) - { - SOUNDCLIP* ch = lock.GetChannel(play.crossfading_in_channel); - int newVolume = ch ? ch->get_volume() + play.crossfade_in_volume_per_step : 0; - if (newVolume > play.crossfade_final_volume_in) - { - newVolume = play.crossfade_final_volume_in; - } - - AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_in_channel], newVolume); - - if (newVolume >= play.crossfade_final_volume_in) - { - play.crossfading_in_channel = 0; - } - } - - /////////////////////////////////////////////////////////////////////////// - // Do audio queue - if (play.new_music_queue_size > 0) - { - for (int i = 0; i < play.new_music_queue_size; i++) - { - ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[i].audioClipIndex]; - int channel = find_free_audio_channel(clip, clip->defaultPriority, false); - if (channel >= 0) - { - QueuedAudioItem itemToPlay = play.new_music_queue[i]; - - play.new_music_queue_size--; - for (int j = i; j < play.new_music_queue_size; j++) - { - play.new_music_queue[j] = play.new_music_queue[j + 1]; - } - - play_audio_clip_on_channel(channel, clip, itemToPlay.priority, itemToPlay.repeat, 0, itemToPlay.cachedClip); - i--; - } - } - } - - /////////////////////////////////////////////////////////////////////////// - // Do non-blocking voice speech - // NOTE: there's only one speech channel, therefore it's either blocking - // or non-blocking at any given time. If it's changed, we'd need to keep - // record of every channel, or keep a count of active channels. - if (play.IsNonBlockingVoiceSpeech()) - { - if (!channel_is_playing(SCHAN_SPEECH)) - { - stop_voice_nonblocking(); - } - } +static void audio_update_polled_stuff() { + /////////////////////////////////////////////////////////////////////////// + // Do crossfade + play.crossfade_step++; + + AudioChannelsLock lock; + + if (play.crossfading_out_channel > 0 && !lock.GetChannelIfPlaying(play.crossfading_out_channel)) + play.crossfading_out_channel = 0; + + if (play.crossfading_out_channel > 0) { + SOUNDCLIP *ch = lock.GetChannel(play.crossfading_out_channel); + int newVolume = ch ? ch->get_volume() - play.crossfade_out_volume_per_step : 0; + if (newVolume > 0) { + AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_out_channel], newVolume); + } else { + stop_and_destroy_channel(play.crossfading_out_channel); + play.crossfading_out_channel = 0; + } + } + + if (play.crossfading_in_channel > 0 && !lock.GetChannelIfPlaying(play.crossfading_in_channel)) + play.crossfading_in_channel = 0; + + if (play.crossfading_in_channel > 0) { + SOUNDCLIP *ch = lock.GetChannel(play.crossfading_in_channel); + int newVolume = ch ? ch->get_volume() + play.crossfade_in_volume_per_step : 0; + if (newVolume > play.crossfade_final_volume_in) { + newVolume = play.crossfade_final_volume_in; + } + + AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_in_channel], newVolume); + + if (newVolume >= play.crossfade_final_volume_in) { + play.crossfading_in_channel = 0; + } + } + + /////////////////////////////////////////////////////////////////////////// + // Do audio queue + if (play.new_music_queue_size > 0) { + for (int i = 0; i < play.new_music_queue_size; i++) { + ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[i].audioClipIndex]; + int channel = find_free_audio_channel(clip, clip->defaultPriority, false); + if (channel >= 0) { + QueuedAudioItem itemToPlay = play.new_music_queue[i]; + + play.new_music_queue_size--; + for (int j = i; j < play.new_music_queue_size; j++) { + play.new_music_queue[j] = play.new_music_queue[j + 1]; + } + + play_audio_clip_on_channel(channel, clip, itemToPlay.priority, itemToPlay.repeat, 0, itemToPlay.cachedClip); + i--; + } + } + } + + /////////////////////////////////////////////////////////////////////////// + // Do non-blocking voice speech + // NOTE: there's only one speech channel, therefore it's either blocking + // or non-blocking at any given time. If it's changed, we'd need to keep + // record of every channel, or keep a count of active channels. + if (play.IsNonBlockingVoiceSpeech()) { + if (!channel_is_playing(SCHAN_SPEECH)) { + stop_voice_nonblocking(); + } + } } // Applies a volume drop modifier to the clip, in accordance to its audio type -static void apply_volume_drop_to_clip(SOUNDCLIP *clip) -{ - int audiotype = clip->sourceClipType; - clip->apply_volume_modifier(-(game.audioClipTypes[audiotype].volume_reduction_while_speech_playing * 255 / 100)); +static void apply_volume_drop_to_clip(SOUNDCLIP *clip) { + int audiotype = clip->sourceClipType; + clip->apply_volume_modifier(-(game.audioClipTypes[audiotype].volume_reduction_while_speech_playing * 255 / 100)); } -static void queue_audio_clip_to_play(ScriptAudioClip *clip, int priority, int repeat) -{ - if (play.new_music_queue_size >= MAX_QUEUED_MUSIC) { - debug_script_log("Too many queued music, cannot add %s", clip->scriptName.GetCStr()); - return; - } - - SOUNDCLIP *cachedClip = load_sound_clip(clip, (repeat != 0)); - if (cachedClip != nullptr) - { - play.new_music_queue[play.new_music_queue_size].audioClipIndex = clip->id; - play.new_music_queue[play.new_music_queue_size].priority = priority; - play.new_music_queue[play.new_music_queue_size].repeat = (repeat != 0); - play.new_music_queue[play.new_music_queue_size].cachedClip = cachedClip; - play.new_music_queue_size++; - } - - update_polled_mp3(); +static void queue_audio_clip_to_play(ScriptAudioClip *clip, int priority, int repeat) { + if (play.new_music_queue_size >= MAX_QUEUED_MUSIC) { + debug_script_log("Too many queued music, cannot add %s", clip->scriptName.GetCStr()); + return; + } + + SOUNDCLIP *cachedClip = load_sound_clip(clip, (repeat != 0)); + if (cachedClip != nullptr) { + play.new_music_queue[play.new_music_queue_size].audioClipIndex = clip->id; + play.new_music_queue[play.new_music_queue_size].priority = priority; + play.new_music_queue[play.new_music_queue_size].repeat = (repeat != 0); + play.new_music_queue[play.new_music_queue_size].cachedClip = cachedClip; + play.new_music_queue_size++; + } + + update_polled_mp3(); } -ScriptAudioChannel* play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *soundfx) -{ - if (soundfx == nullptr) - { - soundfx = load_sound_clip(clip, (repeat) ? true : false); - } - if (soundfx == nullptr) - { - debug_script_log("AudioClip.Play: unable to load sound file"); - if (play.crossfading_in_channel == channel) - { - play.crossfading_in_channel = 0; - } - return nullptr; - } - soundfx->priority = priority; - - if (play.crossfading_in_channel == channel) - { - soundfx->set_volume_percent(0); - } - - // Mute the audio clip if fast-forwarding the cutscene - if (play.fast_forward) - { - soundfx->set_mute(true); - - // CHECKME!! - // [IKM] According to the 3.2.1 logic the clip will restore - // its value after cutscene, but only if originalVolAsPercentage - // is not zeroed. Something I am not sure about: why does it - // disable the clip under condition that there's more than one - // channel for this audio type? It does not even check if - // anything of this type is currently playing. - if (game.audioClipTypes[clip->type].reservedChannels != 1) - soundfx->set_volume_percent(0); - } - - if (soundfx->play_from(fromOffset) == 0) - { - // not assigned to a channel, so clean up manually. - soundfx->destroy(); - delete soundfx; - soundfx = nullptr; - debug_script_log("AudioClip.Play: failed to play sound file"); - return nullptr; - } - - // Apply volume drop if any speech voice-over is currently playing - // NOTE: there is a confusing logic in sound clip classes, that they do not use - // any modifiers when begin playing, therefore we must apply this only after - // playback was started. - if (!play.fast_forward && play.speech_has_voice) - apply_volume_drop_to_clip(soundfx); - - set_clip_to_channel(channel, soundfx); - return &scrAudioChannel[channel]; +ScriptAudioChannel *play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *soundfx) { + if (soundfx == nullptr) { + soundfx = load_sound_clip(clip, (repeat) ? true : false); + } + if (soundfx == nullptr) { + debug_script_log("AudioClip.Play: unable to load sound file"); + if (play.crossfading_in_channel == channel) { + play.crossfading_in_channel = 0; + } + return nullptr; + } + soundfx->priority = priority; + + if (play.crossfading_in_channel == channel) { + soundfx->set_volume_percent(0); + } + + // Mute the audio clip if fast-forwarding the cutscene + if (play.fast_forward) { + soundfx->set_mute(true); + + // CHECKME!! + // [IKM] According to the 3.2.1 logic the clip will restore + // its value after cutscene, but only if originalVolAsPercentage + // is not zeroed. Something I am not sure about: why does it + // disable the clip under condition that there's more than one + // channel for this audio type? It does not even check if + // anything of this type is currently playing. + if (game.audioClipTypes[clip->type].reservedChannels != 1) + soundfx->set_volume_percent(0); + } + + if (soundfx->play_from(fromOffset) == 0) { + // not assigned to a channel, so clean up manually. + soundfx->destroy(); + delete soundfx; + soundfx = nullptr; + debug_script_log("AudioClip.Play: failed to play sound file"); + return nullptr; + } + + // Apply volume drop if any speech voice-over is currently playing + // NOTE: there is a confusing logic in sound clip classes, that they do not use + // any modifiers when begin playing, therefore we must apply this only after + // playback was started. + if (!play.fast_forward && play.speech_has_voice) + apply_volume_drop_to_clip(soundfx); + + set_clip_to_channel(channel, soundfx); + return &scrAudioChannel[channel]; } -void remove_clips_of_type_from_queue(int audioType) -{ - int aa; - for (aa = 0; aa < play.new_music_queue_size; aa++) - { - ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[aa].audioClipIndex]; - if (clip->type == audioType) - { - play.new_music_queue_size--; - for (int bb = aa; bb < play.new_music_queue_size; bb++) - play.new_music_queue[bb] = play.new_music_queue[bb + 1]; - aa--; - } - } +void remove_clips_of_type_from_queue(int audioType) { + int aa; + for (aa = 0; aa < play.new_music_queue_size; aa++) { + ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[aa].audioClipIndex]; + if (clip->type == audioType) { + play.new_music_queue_size--; + for (int bb = aa; bb < play.new_music_queue_size; bb++) + play.new_music_queue[bb] = play.new_music_queue[bb + 1]; + aa--; + } + } } -void update_queued_clips_volume(int audioType, int new_vol) -{ - for (int i = 0; i < play.new_music_queue_size; ++i) - { - // NOTE: if clip is uncached, the volume will be set from defaults when it is loaded - SOUNDCLIP *sndclip = play.new_music_queue[i].cachedClip; - if (sndclip) - { - ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[i].audioClipIndex]; - if (clip->type == audioType) - sndclip->set_volume_percent(new_vol); - } - } +void update_queued_clips_volume(int audioType, int new_vol) { + for (int i = 0; i < play.new_music_queue_size; ++i) { + // NOTE: if clip is uncached, the volume will be set from defaults when it is loaded + SOUNDCLIP *sndclip = play.new_music_queue[i].cachedClip; + if (sndclip) { + ScriptAudioClip *clip = &game.audioClips[play.new_music_queue[i].audioClipIndex]; + if (clip->type == audioType) + sndclip->set_volume_percent(new_vol); + } + } } -ScriptAudioChannel* play_audio_clip(ScriptAudioClip *clip, int priority, int repeat, int fromOffset, bool queueIfNoChannel) -{ - if (!queueIfNoChannel) - remove_clips_of_type_from_queue(clip->type); +ScriptAudioChannel *play_audio_clip(ScriptAudioClip *clip, int priority, int repeat, int fromOffset, bool queueIfNoChannel) { + if (!queueIfNoChannel) + remove_clips_of_type_from_queue(clip->type); - if (priority == SCR_NO_VALUE) - priority = clip->defaultPriority; - if (repeat == SCR_NO_VALUE) - repeat = clip->defaultRepeat; + if (priority == SCR_NO_VALUE) + priority = clip->defaultPriority; + if (repeat == SCR_NO_VALUE) + repeat = clip->defaultRepeat; - int channel = find_free_audio_channel(clip, priority, !queueIfNoChannel); - if (channel < 0) - { - if (queueIfNoChannel) - queue_audio_clip_to_play(clip, priority, repeat); - else - debug_script_log("AudioClip.Play: no channels available to interrupt PRI:%d TYPE:%d", priority, clip->type); + int channel = find_free_audio_channel(clip, priority, !queueIfNoChannel); + if (channel < 0) { + if (queueIfNoChannel) + queue_audio_clip_to_play(clip, priority, repeat); + else + debug_script_log("AudioClip.Play: no channels available to interrupt PRI:%d TYPE:%d", priority, clip->type); - return nullptr; - } + return nullptr; + } - return play_audio_clip_on_channel(channel, clip, priority, repeat, fromOffset); + return play_audio_clip_on_channel(channel, clip, priority, repeat, fromOffset); } -ScriptAudioChannel* play_audio_clip_by_index(int audioClipIndex) -{ - if ((audioClipIndex >= 0) && ((size_t)audioClipIndex < game.audioClips.size())) - return AudioClip_Play(&game.audioClips[audioClipIndex], SCR_NO_VALUE, SCR_NO_VALUE); - else - return nullptr; +ScriptAudioChannel *play_audio_clip_by_index(int audioClipIndex) { + if ((audioClipIndex >= 0) && ((size_t)audioClipIndex < game.audioClips.size())) + return AudioClip_Play(&game.audioClips[audioClipIndex], SCR_NO_VALUE, SCR_NO_VALUE); + else + return nullptr; } -void stop_and_destroy_channel_ex(int chid, bool resetLegacyMusicSettings) -{ - if ((chid < 0) || (chid > MAX_SOUND_CHANNELS)) - quit("!StopChannel: invalid channel ID"); - - AudioChannelsLock lock; - SOUNDCLIP* ch = lock.GetChannel(chid); - - if (ch != nullptr) { - ch->destroy(); - delete ch; - lock.SetChannel(chid, nullptr); - ch = nullptr; - } - - if (play.crossfading_in_channel == chid) - play.crossfading_in_channel = 0; - if (play.crossfading_out_channel == chid) - play.crossfading_out_channel = 0; - // don't update 'crossFading' here as it is updated in all the cross-fading functions. - - // destroyed an ambient sound channel - if (ambient[chid].channel > 0) - ambient[chid].channel = 0; - - if ((chid == SCHAN_MUSIC) && (resetLegacyMusicSettings)) - { - play.cur_music_number = -1; - current_music_type = 0; - } +void stop_and_destroy_channel_ex(int chid, bool resetLegacyMusicSettings) { + if ((chid < 0) || (chid > MAX_SOUND_CHANNELS)) + quit("!StopChannel: invalid channel ID"); + + AudioChannelsLock lock; + SOUNDCLIP *ch = lock.GetChannel(chid); + + if (ch != nullptr) { + ch->destroy(); + delete ch; + lock.SetChannel(chid, nullptr); + ch = nullptr; + } + + if (play.crossfading_in_channel == chid) + play.crossfading_in_channel = 0; + if (play.crossfading_out_channel == chid) + play.crossfading_out_channel = 0; + // don't update 'crossFading' here as it is updated in all the cross-fading functions. + + // destroyed an ambient sound channel + if (ambient[chid].channel > 0) + ambient[chid].channel = 0; + + if ((chid == SCHAN_MUSIC) && (resetLegacyMusicSettings)) { + play.cur_music_number = -1; + current_music_type = 0; + } } -void stop_and_destroy_channel(int chid) -{ - stop_and_destroy_channel_ex(chid, true); +void stop_and_destroy_channel(int chid) { + stop_and_destroy_channel_ex(chid, true); } // ***** BACKWARDS COMPATIBILITY WITH OLD AUDIO SYSTEM ***** // -int get_old_style_number_for_sound(int sound_number) -{ - int audio_clip_id = 0; - - if (game.IsLegacyAudioSystem()) - { - // No sound assigned. - if (sound_number < 1) - return 0; - - // Sound number is not yet updated to audio clip id. - if (sound_number <= 0x10000000) - return sound_number; - - // Remove audio clip id flag. - audio_clip_id = sound_number - 0x10000000; - } - else - audio_clip_id = sound_number; - - if (audio_clip_id >= 0) - { - int old_style_number = 0; - if (sscanf(game.audioClips[audio_clip_id].scriptName.GetCStr(), "aSound%d", &old_style_number) == 1) - return old_style_number; - } - return 0; +int get_old_style_number_for_sound(int sound_number) { + int audio_clip_id = 0; + + if (game.IsLegacyAudioSystem()) { + // No sound assigned. + if (sound_number < 1) + return 0; + + // Sound number is not yet updated to audio clip id. + if (sound_number <= 0x10000000) + return sound_number; + + // Remove audio clip id flag. + audio_clip_id = sound_number - 0x10000000; + } else + audio_clip_id = sound_number; + + if (audio_clip_id >= 0) { + int old_style_number = 0; + if (sscanf(game.audioClips[audio_clip_id].scriptName.GetCStr(), "aSound%d", &old_style_number) == 1) + return old_style_number; + } + return 0; } -SOUNDCLIP *load_sound_clip_from_old_style_number(bool isMusic, int indexNumber, bool repeat) -{ - ScriptAudioClip* audioClip = GetAudioClipForOldStyleNumber(game, isMusic, indexNumber); +SOUNDCLIP *load_sound_clip_from_old_style_number(bool isMusic, int indexNumber, bool repeat) { + ScriptAudioClip *audioClip = GetAudioClipForOldStyleNumber(game, isMusic, indexNumber); - if (audioClip != nullptr) - { - return load_sound_clip(audioClip, repeat); - } + if (audioClip != nullptr) { + return load_sound_clip(audioClip, repeat); + } - return nullptr; + return nullptr; } //============================================================================= void force_audiostream_include() { - // This should never happen, but the call is here to make it - // link the audiostream libraries - stop_audio_stream(nullptr); + // This should never happen, but the call is here to make it + // link the audiostream libraries + stop_audio_stream(nullptr); } // TODO: double check that ambient sounds array actually needs +1 -std::array ambient; - -int get_volume_adjusted_for_distance(int volume, int sndX, int sndY, int sndMaxDist) -{ - int distx = playerchar->x - sndX; - int disty = playerchar->y - sndY; - // it uses Allegro's "fix" sqrt without the :: - int dist = (int)::sqrt((double)(distx*distx + disty*disty)); - - // if they're quite close, full volume - int wantvol = volume; - - if (dist >= AMBIENCE_FULL_DIST) - { - // get the relative volume - wantvol = ((dist - AMBIENCE_FULL_DIST) * volume) / sndMaxDist; - // closer is louder - wantvol = volume - wantvol; - } - - return wantvol; +std::array < AmbientSound, MAX_SOUND_CHANNELS + 1 > ambient; + +int get_volume_adjusted_for_distance(int volume, int sndX, int sndY, int sndMaxDist) { + int distx = playerchar->x - sndX; + int disty = playerchar->y - sndY; + // it uses Allegro's "fix" sqrt without the :: + int dist = (int)::sqrt((double)(distx * distx + disty * disty)); + + // if they're quite close, full volume + int wantvol = volume; + + if (dist >= AMBIENCE_FULL_DIST) { + // get the relative volume + wantvol = ((dist - AMBIENCE_FULL_DIST) * volume) / sndMaxDist; + // closer is louder + wantvol = volume - wantvol; + } + + return wantvol; } -void update_directional_sound_vol() -{ - AudioChannelsLock lock; - - for (int chnum = 1; chnum < MAX_SOUND_CHANNELS; chnum++) - { - auto* ch = lock.GetChannelIfPlaying(chnum); - if ((ch != nullptr) && (ch->xSource >= 0)) - { - ch->apply_directional_modifier( - get_volume_adjusted_for_distance(ch->vol, - ch->xSource, - ch->ySource, - ch->maximumPossibleDistanceAway) - - ch->vol); - } - } +void update_directional_sound_vol() { + AudioChannelsLock lock; + + for (int chnum = 1; chnum < MAX_SOUND_CHANNELS; chnum++) { + auto *ch = lock.GetChannelIfPlaying(chnum); + if ((ch != nullptr) && (ch->xSource >= 0)) { + ch->apply_directional_modifier( + get_volume_adjusted_for_distance(ch->vol, + ch->xSource, + ch->ySource, + ch->maximumPossibleDistanceAway) - + ch->vol); + } + } } -void update_ambient_sound_vol () -{ - AudioChannelsLock lock; +void update_ambient_sound_vol() { + AudioChannelsLock lock; - for (int chan = 1; chan < MAX_SOUND_CHANNELS; chan++) { + for (int chan = 1; chan < MAX_SOUND_CHANNELS; chan++) { - AmbientSound *thisSound = &ambient[chan]; + AmbientSound *thisSound = &ambient[chan]; - if (thisSound->channel == 0) - continue; + if (thisSound->channel == 0) + continue; - int sourceVolume = thisSound->vol; + int sourceVolume = thisSound->vol; - if (play.speech_has_voice) { - // Negative value means set exactly; positive means drop that amount - if (play.speech_music_drop < 0) - sourceVolume = -play.speech_music_drop; - else - sourceVolume -= play.speech_music_drop; + if (play.speech_has_voice) { + // Negative value means set exactly; positive means drop that amount + if (play.speech_music_drop < 0) + sourceVolume = -play.speech_music_drop; + else + sourceVolume -= play.speech_music_drop; - if (sourceVolume < 0) - sourceVolume = 0; - if (sourceVolume > 255) - sourceVolume = 255; - } + if (sourceVolume < 0) + sourceVolume = 0; + if (sourceVolume > 255) + sourceVolume = 255; + } - // Adjust ambient volume so it maxes out at overall sound volume - int ambientvol = (sourceVolume * play.sound_volume) / 255; + // Adjust ambient volume so it maxes out at overall sound volume + int ambientvol = (sourceVolume * play.sound_volume) / 255; - int wantvol; + int wantvol; - if ((thisSound->x == 0) && (thisSound->y == 0)) { - wantvol = ambientvol; - } - else { - wantvol = get_volume_adjusted_for_distance(ambientvol, thisSound->x, thisSound->y, thisSound->maxdist); - } + if ((thisSound->x == 0) && (thisSound->y == 0)) { + wantvol = ambientvol; + } else { + wantvol = get_volume_adjusted_for_distance(ambientvol, thisSound->x, thisSound->y, thisSound->maxdist); + } - auto *ch = lock.GetChannelIfPlaying(thisSound->channel); - if (ch) - ch->set_volume(wantvol); - } + auto *ch = lock.GetChannelIfPlaying(thisSound->channel); + if (ch) + ch->set_volume(wantvol); + } } -SOUNDCLIP *load_sound_and_play(ScriptAudioClip *aclip, bool repeat) -{ - SOUNDCLIP *soundfx = load_sound_clip(aclip, repeat); - if (!soundfx) { return nullptr; } +SOUNDCLIP *load_sound_and_play(ScriptAudioClip *aclip, bool repeat) { + SOUNDCLIP *soundfx = load_sound_clip(aclip, repeat); + if (!soundfx) { + return nullptr; + } - if (soundfx->play() == 0) { - // not assigned to a channel, so clean up manually. - soundfx->destroy(); - delete soundfx; - return nullptr; - } + if (soundfx->play() == 0) { + // not assigned to a channel, so clean up manually. + soundfx->destroy(); + delete soundfx; + return nullptr; + } - return soundfx; + return soundfx; } -void stop_all_sound_and_music() -{ - int a; - stopmusic(); - stop_voice_nonblocking(); - // make sure it doesn't start crossfading when it comes back - crossFading = 0; - // any ambient sound will be aborted - for (a = 0; a <= MAX_SOUND_CHANNELS; a++) - stop_and_destroy_channel(a); +void stop_all_sound_and_music() { + int a; + stopmusic(); + stop_voice_nonblocking(); + // make sure it doesn't start crossfading when it comes back + crossFading = 0; + // any ambient sound will be aborted + for (a = 0; a <= MAX_SOUND_CHANNELS; a++) + stop_and_destroy_channel(a); } -void shutdown_sound() -{ - stop_all_sound_and_music(); +void shutdown_sound() { + stop_all_sound_and_music(); #ifndef PSP_NO_MOD_PLAYBACK - if (usetup.mod_player) - remove_mod_player(); + if (usetup.mod_player) + remove_mod_player(); #endif - remove_sound(); + remove_sound(); } // the sound will only be played if there is a free channel or // it has a priority >= an existing sound to override -static int play_sound_priority (int val1, int priority) { - int lowest_pri = 9999, lowest_pri_id = -1; - - AudioChannelsLock lock; - - // find a free channel to play it on - for (int i = SCHAN_NORMAL; i < MAX_SOUND_CHANNELS; i++) { - auto* ch = lock.GetChannelIfPlaying(i); - if (val1 < 0) { - // Playing sound -1 means iterate through and stop all sound - if (ch) - stop_and_destroy_channel (i); - } - else if (ch == nullptr || !ch->is_playing()) { - // PlaySoundEx will destroy the previous channel value. - const int usechan = PlaySoundEx(val1, i); - if (usechan >= 0) - { // channel will hold a different clip here - assert(usechan == i); - auto *ch = lock.GetChannel(usechan); - if (ch) - ch->priority = priority; - } - return usechan; - } - else if (ch->priority < lowest_pri) { - lowest_pri = ch->priority; - lowest_pri_id = i; - } - - } - if (val1 < 0) - return -1; - - // no free channels, see if we have a high enough priority - // to override one - if (priority >= lowest_pri) { - const int usechan = PlaySoundEx(val1, lowest_pri_id); - if (usechan >= 0) { - assert(usechan == lowest_pri_id); - auto *ch = lock.GetChannel(usechan); - if (ch) - ch->priority = priority; - return usechan; - } - } - - return -1; +static int play_sound_priority(int val1, int priority) { + int lowest_pri = 9999, lowest_pri_id = -1; + + AudioChannelsLock lock; + + // find a free channel to play it on + for (int i = SCHAN_NORMAL; i < MAX_SOUND_CHANNELS; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if (val1 < 0) { + // Playing sound -1 means iterate through and stop all sound + if (ch) + stop_and_destroy_channel(i); + } else if (ch == nullptr || !ch->is_playing()) { + // PlaySoundEx will destroy the previous channel value. + const int usechan = PlaySoundEx(val1, i); + if (usechan >= 0) { + // channel will hold a different clip here + assert(usechan == i); + auto *ch = lock.GetChannel(usechan); + if (ch) + ch->priority = priority; + } + return usechan; + } else if (ch->priority < lowest_pri) { + lowest_pri = ch->priority; + lowest_pri_id = i; + } + + } + if (val1 < 0) + return -1; + + // no free channels, see if we have a high enough priority + // to override one + if (priority >= lowest_pri) { + const int usechan = PlaySoundEx(val1, lowest_pri_id); + if (usechan >= 0) { + assert(usechan == lowest_pri_id); + auto *ch = lock.GetChannel(usechan); + if (ch) + ch->priority = priority; + return usechan; + } + } + + return -1; } int play_sound(int val1) { - return play_sound_priority(val1, 10); + return play_sound_priority(val1, 10); } @@ -819,418 +734,401 @@ static bool music_update_scheduled = false; static auto music_update_at = AGS_Clock::now(); void cancel_scheduled_music_update() { - music_update_scheduled = false; + music_update_scheduled = false; } void schedule_music_update_at(AGS_Clock::time_point at) { - music_update_scheduled = true; - music_update_at = at; + music_update_scheduled = true; + music_update_at = at; } void postpone_scheduled_music_update_by(std::chrono::milliseconds duration) { - if (!music_update_scheduled) { return; } - music_update_at += duration; + if (!music_update_scheduled) { + return; + } + music_update_at += duration; } void process_scheduled_music_update() { - if (!music_update_scheduled) { return; } - if (music_update_at > AGS_Clock::now()) { return; } - cancel_scheduled_music_update(); - update_music_volume(); - apply_volume_drop_modifier(false); - update_ambient_sound_vol(); + if (!music_update_scheduled) { + return; + } + if (music_update_at > AGS_Clock::now()) { + return; + } + cancel_scheduled_music_update(); + update_music_volume(); + apply_volume_drop_modifier(false); + update_ambient_sound_vol(); } // end scheduled music update functions //============================================================================= void clear_music_cache() { - if (cachedQueuedMusic != nullptr) { - cachedQueuedMusic->destroy(); - delete cachedQueuedMusic; - cachedQueuedMusic = nullptr; - } + if (cachedQueuedMusic != nullptr) { + cachedQueuedMusic->destroy(); + delete cachedQueuedMusic; + cachedQueuedMusic = nullptr; + } } static void play_new_music(int mnum, SOUNDCLIP *music); void play_next_queued() { - // check if there's a queued one to play - if (play.music_queue_size > 0) { - - int tuneToPlay = play.music_queue[0]; - - if (tuneToPlay >= QUEUED_MUSIC_REPEAT) { - // Loop it! - play.music_repeat++; - play_new_music(tuneToPlay - QUEUED_MUSIC_REPEAT, cachedQueuedMusic); - play.music_repeat--; - } - else { - // Don't loop it! - int repeatWas = play.music_repeat; - play.music_repeat = 0; - play_new_music(tuneToPlay, cachedQueuedMusic); - play.music_repeat = repeatWas; - } - - // don't free the memory, as it has been transferred onto the - // main music channel - cachedQueuedMusic = nullptr; - - play.music_queue_size--; - for (int i = 0; i < play.music_queue_size; i++) - play.music_queue[i] = play.music_queue[i + 1]; - - if (play.music_queue_size > 0) - cachedQueuedMusic = load_music_from_disk(play.music_queue[0], 0); - } + // check if there's a queued one to play + if (play.music_queue_size > 0) { + + int tuneToPlay = play.music_queue[0]; + + if (tuneToPlay >= QUEUED_MUSIC_REPEAT) { + // Loop it! + play.music_repeat++; + play_new_music(tuneToPlay - QUEUED_MUSIC_REPEAT, cachedQueuedMusic); + play.music_repeat--; + } else { + // Don't loop it! + int repeatWas = play.music_repeat; + play.music_repeat = 0; + play_new_music(tuneToPlay, cachedQueuedMusic); + play.music_repeat = repeatWas; + } + + // don't free the memory, as it has been transferred onto the + // main music channel + cachedQueuedMusic = nullptr; + + play.music_queue_size--; + for (int i = 0; i < play.music_queue_size; i++) + play.music_queue[i] = play.music_queue[i + 1]; + + if (play.music_queue_size > 0) + cachedQueuedMusic = load_music_from_disk(play.music_queue[0], 0); + } } int calculate_max_volume() { - // quieter so that sounds can be heard better - int newvol=play.music_master_volume + ((int)thisroom.Options.MusicVolume) * LegacyRoomVolumeFactor; - if (newvol>255) newvol=255; - if (newvol<0) newvol=0; + // quieter so that sounds can be heard better + int newvol = play.music_master_volume + ((int)thisroom.Options.MusicVolume) * LegacyRoomVolumeFactor; + if (newvol > 255) newvol = 255; + if (newvol < 0) newvol = 0; - if (play.fast_forward) - newvol = 0; + if (play.fast_forward) + newvol = 0; - return newvol; + return newvol; } // add/remove the volume drop to the audio channels while speech is playing -void apply_volume_drop_modifier(bool applyModifier) -{ - AudioChannelsLock lock; - - for (int i = 0; i < MAX_SOUND_CHANNELS; i++) - { - auto* ch = lock.GetChannelIfPlaying(i); - if (ch && ch->sourceClip != nullptr) - { - if (applyModifier) - apply_volume_drop_to_clip(ch); - else - ch->apply_volume_modifier(0); // reset modifier - } - } +void apply_volume_drop_modifier(bool applyModifier) { + AudioChannelsLock lock; + + for (int i = 0; i < MAX_SOUND_CHANNELS; i++) { + auto *ch = lock.GetChannelIfPlaying(i); + if (ch && ch->sourceClip != nullptr) { + if (applyModifier) + apply_volume_drop_to_clip(ch); + else + ch->apply_volume_modifier(0); // reset modifier + } + } } // Checks if speech voice-over is currently playing, and reapply volume drop to all other active clips -void update_volume_drop_if_voiceover() -{ - apply_volume_drop_modifier(play.speech_has_voice); +void update_volume_drop_if_voiceover() { + apply_volume_drop_modifier(play.speech_has_voice); } extern volatile char want_exit; -void update_mp3_thread() -{ - if (switching_away_from_game) { return; } +void update_mp3_thread() { + if (switching_away_from_game) { + return; + } - AudioChannelsLock lock; + AudioChannelsLock lock; - for(int i = 0; i <= MAX_SOUND_CHANNELS; ++i) - { - auto* ch = lock.GetChannel(i); - if (ch) - ch->poll(); - } + for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { + auto *ch = lock.GetChannel(i); + if (ch) + ch->poll(); + } } //this is called at various points to give streaming logic a chance to update //it seems those calls have been littered around and points where it ameliorated skipping //a better solution would be to forcibly thread the streaming logic -void update_polled_mp3() -{ - if (psp_audio_multithreaded) { return; } - update_mp3_thread(); +void update_polled_mp3() { + if (psp_audio_multithreaded) { + return; + } + update_mp3_thread(); } // Update the music, and advance the crossfade on a step // (this should only be called once per game loop) -void update_audio_system_on_game_loop () -{ - update_polled_stuff_if_runtime (); - - AudioChannelsLock lock; - - process_scheduled_music_update(); - - _audio_doing_crossfade = true; - - audio_update_polled_stuff(); - - if (crossFading) { - crossFadeStep++; - update_music_volume(); - } - - // Check if the current music has finished playing - if ((play.cur_music_number >= 0) && (play.fast_forward == 0)) { - if (IsMusicPlaying() == 0) { - // The current music has finished - play.cur_music_number = -1; - play_next_queued(); - } - else if ((game.options[OPT_CROSSFADEMUSIC] > 0) && - (play.music_queue_size > 0) && (!crossFading)) { - // want to crossfade, and new tune in the queue - auto *ch = lock.GetChannel(SCHAN_MUSIC); - if (ch) { - int curpos = ch->get_pos_ms(); - int muslen = ch->get_length_ms(); - if ((curpos > 0) && (muslen > 0)) { - // we want to crossfade, and we know how far through - // the tune we are - int takesSteps = calculate_max_volume() / game.options[OPT_CROSSFADEMUSIC]; - int takesMs = ::lround(takesSteps * 1000.0f / get_current_fps()); - if (curpos >= muslen - takesMs) - play_next_queued(); - } - } - } - } - - _audio_doing_crossfade = false; +void update_audio_system_on_game_loop() { + update_polled_stuff_if_runtime(); + + AudioChannelsLock lock; + + process_scheduled_music_update(); + + _audio_doing_crossfade = true; + + audio_update_polled_stuff(); + + if (crossFading) { + crossFadeStep++; + update_music_volume(); + } + + // Check if the current music has finished playing + if ((play.cur_music_number >= 0) && (play.fast_forward == 0)) { + if (IsMusicPlaying() == 0) { + // The current music has finished + play.cur_music_number = -1; + play_next_queued(); + } else if ((game.options[OPT_CROSSFADEMUSIC] > 0) && + (play.music_queue_size > 0) && (!crossFading)) { + // want to crossfade, and new tune in the queue + auto *ch = lock.GetChannel(SCHAN_MUSIC); + if (ch) { + int curpos = ch->get_pos_ms(); + int muslen = ch->get_length_ms(); + if ((curpos > 0) && (muslen > 0)) { + // we want to crossfade, and we know how far through + // the tune we are + int takesSteps = calculate_max_volume() / game.options[OPT_CROSSFADEMUSIC]; + int takesMs = ::lround(takesSteps * 1000.0f / get_current_fps()); + if (curpos >= muslen - takesMs) + play_next_queued(); + } + } + } + } + + _audio_doing_crossfade = false; } -void stopmusic() -{ - AudioChannelsLock lock; - - if (crossFading > 0) { - // stop in the middle of a new track fading in - // Abort the new track, and let the old one finish fading out - stop_and_destroy_channel (crossFading); - crossFading = -1; - } - else if (crossFading < 0) { - // the music is already fading out - if (game.options[OPT_CROSSFADEMUSIC] <= 0) { - // If they have since disabled crossfading, stop the fadeout - stop_and_destroy_channel(SCHAN_MUSIC); - crossFading = 0; - crossFadeStep = 0; - update_music_volume(); - } - } - else if ((game.options[OPT_CROSSFADEMUSIC] > 0) - && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) - && (current_music_type != 0) - && (current_music_type != MUS_MIDI) - && (current_music_type != MUS_MOD)) { - - crossFading = -1; - crossFadeStep = 0; - crossFadeVolumePerStep = game.options[OPT_CROSSFADEMUSIC]; - crossFadeVolumeAtStart = calculate_max_volume(); - } - else - stop_and_destroy_channel (SCHAN_MUSIC); - - play.cur_music_number = -1; - current_music_type = 0; +void stopmusic() { + AudioChannelsLock lock; + + if (crossFading > 0) { + // stop in the middle of a new track fading in + // Abort the new track, and let the old one finish fading out + stop_and_destroy_channel(crossFading); + crossFading = -1; + } else if (crossFading < 0) { + // the music is already fading out + if (game.options[OPT_CROSSFADEMUSIC] <= 0) { + // If they have since disabled crossfading, stop the fadeout + stop_and_destroy_channel(SCHAN_MUSIC); + crossFading = 0; + crossFadeStep = 0; + update_music_volume(); + } + } else if ((game.options[OPT_CROSSFADEMUSIC] > 0) + && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) + && (current_music_type != 0) + && (current_music_type != MUS_MIDI) + && (current_music_type != MUS_MOD)) { + + crossFading = -1; + crossFadeStep = 0; + crossFadeVolumePerStep = game.options[OPT_CROSSFADEMUSIC]; + crossFadeVolumeAtStart = calculate_max_volume(); + } else + stop_and_destroy_channel(SCHAN_MUSIC); + + play.cur_music_number = -1; + current_music_type = 0; } -void update_music_volume() -{ - AudioChannelsLock lock; - - if ((current_music_type) || (crossFading < 0)) - { - // targetVol is the maximum volume we're fading in to - // newvol is the starting volume that we faded out from - int targetVol = calculate_max_volume(); - int newvol; - if (crossFading) - newvol = crossFadeVolumeAtStart; - else - newvol = targetVol; - - // fading out old track, target volume is silence - if (crossFading < 0) - targetVol = 0; - - if (crossFading) { - int curvol = crossFadeVolumePerStep * crossFadeStep; - - if ((curvol > targetVol) && (curvol > newvol)) { - // it has fully faded to the new track - newvol = targetVol; - stop_and_destroy_channel_ex(SCHAN_MUSIC, false); - if (crossFading > 0) { - lock.MoveChannel(SCHAN_MUSIC, crossFading); - } - crossFading = 0; - } - else { - if (crossFading > 0) - { - auto *ch = lock.GetChannel(crossFading); - if (ch) - ch->set_volume((curvol > targetVol) ? targetVol : curvol); - } - - newvol -= curvol; - if (newvol < 0) - newvol = 0; - } - } - auto *ch = lock.GetChannel(SCHAN_MUSIC); - if (ch) - ch->set_volume(newvol); - } +void update_music_volume() { + AudioChannelsLock lock; + + if ((current_music_type) || (crossFading < 0)) { + // targetVol is the maximum volume we're fading in to + // newvol is the starting volume that we faded out from + int targetVol = calculate_max_volume(); + int newvol; + if (crossFading) + newvol = crossFadeVolumeAtStart; + else + newvol = targetVol; + + // fading out old track, target volume is silence + if (crossFading < 0) + targetVol = 0; + + if (crossFading) { + int curvol = crossFadeVolumePerStep * crossFadeStep; + + if ((curvol > targetVol) && (curvol > newvol)) { + // it has fully faded to the new track + newvol = targetVol; + stop_and_destroy_channel_ex(SCHAN_MUSIC, false); + if (crossFading > 0) { + lock.MoveChannel(SCHAN_MUSIC, crossFading); + } + crossFading = 0; + } else { + if (crossFading > 0) { + auto *ch = lock.GetChannel(crossFading); + if (ch) + ch->set_volume((curvol > targetVol) ? targetVol : curvol); + } + + newvol -= curvol; + if (newvol < 0) + newvol = 0; + } + } + auto *ch = lock.GetChannel(SCHAN_MUSIC); + if (ch) + ch->set_volume(newvol); + } } // Ensures crossfader is stable after loading (or failing to load) // new music -void post_new_music_check (int newchannel) -{ - AudioChannelsLock lock; - if ((crossFading > 0) && (lock.GetChannel(crossFading) == nullptr)) { - crossFading = 0; - // Was fading out but then they played invalid music, continue to fade out - if (lock.GetChannel(SCHAN_MUSIC) != nullptr) - crossFading = -1; - } +void post_new_music_check(int newchannel) { + AudioChannelsLock lock; + if ((crossFading > 0) && (lock.GetChannel(crossFading) == nullptr)) { + crossFading = 0; + // Was fading out but then they played invalid music, continue to fade out + if (lock.GetChannel(SCHAN_MUSIC) != nullptr) + crossFading = -1; + } } -int prepare_for_new_music () -{ - AudioChannelsLock lock; - - int useChannel = SCHAN_MUSIC; - - if ((game.options[OPT_CROSSFADEMUSIC] > 0) - && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) - && (current_music_type != MUS_MIDI) - && (current_music_type != MUS_MOD)) { - - if (crossFading > 0) { - // It's still crossfading to the previous track - stop_and_destroy_channel_ex(SCHAN_MUSIC, false); - lock.MoveChannel(SCHAN_MUSIC, crossFading); - crossFading = 0; - update_music_volume(); - } - else if (crossFading < 0) { - // an old track is still fading out, no new music yet - // Do nothing, and keep the current crossfade step - } - else { - // start crossfading - crossFadeStep = 0; - crossFadeVolumePerStep = game.options[OPT_CROSSFADEMUSIC]; - crossFadeVolumeAtStart = calculate_max_volume(); - } - useChannel = SPECIAL_CROSSFADE_CHANNEL; - crossFading = useChannel; - } - else { - // crossfading is now turned off - stopmusic(); - // ensure that any traces of old tunes fading are eliminated - // (otherwise the new track will be faded out) - crossFading = 0; - } - - // Just make sure, because it will be overwritten in a sec - if (lock.GetChannel(useChannel) != nullptr) - stop_and_destroy_channel (useChannel); - - return useChannel; +int prepare_for_new_music() { + AudioChannelsLock lock; + + int useChannel = SCHAN_MUSIC; + + if ((game.options[OPT_CROSSFADEMUSIC] > 0) + && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) + && (current_music_type != MUS_MIDI) + && (current_music_type != MUS_MOD)) { + + if (crossFading > 0) { + // It's still crossfading to the previous track + stop_and_destroy_channel_ex(SCHAN_MUSIC, false); + lock.MoveChannel(SCHAN_MUSIC, crossFading); + crossFading = 0; + update_music_volume(); + } else if (crossFading < 0) { + // an old track is still fading out, no new music yet + // Do nothing, and keep the current crossfade step + } else { + // start crossfading + crossFadeStep = 0; + crossFadeVolumePerStep = game.options[OPT_CROSSFADEMUSIC]; + crossFadeVolumeAtStart = calculate_max_volume(); + } + useChannel = SPECIAL_CROSSFADE_CHANNEL; + crossFading = useChannel; + } else { + // crossfading is now turned off + stopmusic(); + // ensure that any traces of old tunes fading are eliminated + // (otherwise the new track will be faded out) + crossFading = 0; + } + + // Just make sure, because it will be overwritten in a sec + if (lock.GetChannel(useChannel) != nullptr) + stop_and_destroy_channel(useChannel); + + return useChannel; } -ScriptAudioClip *get_audio_clip_for_music(int mnum) -{ - if (mnum >= QUEUED_MUSIC_REPEAT) - mnum -= QUEUED_MUSIC_REPEAT; - return GetAudioClipForOldStyleNumber(game, true, mnum); +ScriptAudioClip *get_audio_clip_for_music(int mnum) { + if (mnum >= QUEUED_MUSIC_REPEAT) + mnum -= QUEUED_MUSIC_REPEAT; + return GetAudioClipForOldStyleNumber(game, true, mnum); } SOUNDCLIP *load_music_from_disk(int mnum, bool doRepeat) { - if (mnum >= QUEUED_MUSIC_REPEAT) { - mnum -= QUEUED_MUSIC_REPEAT; - doRepeat = true; - } + if (mnum >= QUEUED_MUSIC_REPEAT) { + mnum -= QUEUED_MUSIC_REPEAT; + doRepeat = true; + } - SOUNDCLIP *loaded = load_sound_clip_from_old_style_number(true, mnum, doRepeat); + SOUNDCLIP *loaded = load_sound_clip_from_old_style_number(true, mnum, doRepeat); - if ((loaded == nullptr) && (mnum > 0)) - { - debug_script_warn("Music %d not found",mnum); - debug_script_log("FAILED to load music %d", mnum); - } + if ((loaded == nullptr) && (mnum > 0)) { + debug_script_warn("Music %d not found", mnum); + debug_script_log("FAILED to load music %d", mnum); + } - return loaded; + return loaded; } -static void play_new_music(int mnum, SOUNDCLIP *music) -{ - if (debug_flags & DBG_NOMUSIC) - return; - - if ((play.cur_music_number == mnum) && (music == nullptr)) { - debug_script_log("PlayMusic %d but already playing", mnum); - return; // don't play the music if it's already playing - } - - ScriptAudioClip *aclip = get_audio_clip_for_music(mnum); - if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) - return; - - int useChannel = SCHAN_MUSIC; - debug_script_log("Playing music %d", mnum); - - if (mnum<0) { - stopmusic(); - return; - } - - if (play.fast_forward) { - // while skipping cutscene, don't change the music - play.end_cutscene_music = mnum; - return; - } - - useChannel = prepare_for_new_music(); - play.cur_music_number = mnum; - current_music_type = 0; - - play.current_music_repeating = play.music_repeat; - // now that all the previous music is unloaded, load in the new one - - SOUNDCLIP *new_clip; - if (music != nullptr) - new_clip = music; - else - new_clip = load_music_from_disk(mnum, (play.music_repeat > 0)); - - AudioChannelsLock lock; - auto* ch = lock.SetChannel(useChannel, new_clip); - if (ch != nullptr) { - if (!ch->play()) { - // previous behavior was to set channel[] to null on error, so continue to do that here. - ch->destroy(); - delete ch; - ch = nullptr; - lock.SetChannel(useChannel, nullptr); - } else - current_music_type = ch->get_sound_type(); - } - - post_new_music_check(useChannel); - update_music_volume(); +static void play_new_music(int mnum, SOUNDCLIP *music) { + if (debug_flags & DBG_NOMUSIC) + return; + + if ((play.cur_music_number == mnum) && (music == nullptr)) { + debug_script_log("PlayMusic %d but already playing", mnum); + return; // don't play the music if it's already playing + } + + ScriptAudioClip *aclip = get_audio_clip_for_music(mnum); + if (aclip && !is_audiotype_allowed_to_play((AudioFileType)aclip->fileType)) + return; + + int useChannel = SCHAN_MUSIC; + debug_script_log("Playing music %d", mnum); + + if (mnum < 0) { + stopmusic(); + return; + } + + if (play.fast_forward) { + // while skipping cutscene, don't change the music + play.end_cutscene_music = mnum; + return; + } + + useChannel = prepare_for_new_music(); + play.cur_music_number = mnum; + current_music_type = 0; + + play.current_music_repeating = play.music_repeat; + // now that all the previous music is unloaded, load in the new one + + SOUNDCLIP *new_clip; + if (music != nullptr) + new_clip = music; + else + new_clip = load_music_from_disk(mnum, (play.music_repeat > 0)); + + AudioChannelsLock lock; + auto *ch = lock.SetChannel(useChannel, new_clip); + if (ch != nullptr) { + if (!ch->play()) { + // previous behavior was to set channel[] to null on error, so continue to do that here. + ch->destroy(); + delete ch; + ch = nullptr; + lock.SetChannel(useChannel, nullptr); + } else + current_music_type = ch->get_sound_type(); + } + + post_new_music_check(useChannel); + update_music_volume(); } -void newmusic(int mnum) -{ - play_new_music(mnum, nullptr); +void newmusic(int mnum) { + play_new_music(mnum, nullptr); } diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index eff2c5dd6a50..32079d872265 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -40,27 +40,25 @@ struct SOUNDCLIP; //yes, we will have more recursive traffic on mutexes than we need //however this should mostly be happening only when playing sounds, and possibly when sounds numbering only several //the load should not be high -class AudioChannelsLock : public AGS::Engine::MutexLock -{ +class AudioChannelsLock : public AGS::Engine::MutexLock { private: - AudioChannelsLock(AudioChannelsLock const &); // non-copyable - AudioChannelsLock& operator=(AudioChannelsLock const &); // not copy-assignable + AudioChannelsLock(AudioChannelsLock const &); // non-copyable + AudioChannelsLock &operator=(AudioChannelsLock const &); // not copy-assignable public: - static AGS::Engine::Mutex s_mutex; - AudioChannelsLock() - : MutexLock(s_mutex) - { - } - - // Gets a clip from the channel - SOUNDCLIP *GetChannel(int index); - // Gets a clip from the channel but only if it's in playback state - SOUNDCLIP *GetChannelIfPlaying(int index); - // Assign new clip to the channel - SOUNDCLIP *SetChannel(int index, SOUNDCLIP *clip); - // Move clip from one channel to another, clearing the first channel - SOUNDCLIP *MoveChannel(int to, int from); + static AGS::Engine::Mutex s_mutex; + AudioChannelsLock() + : MutexLock(s_mutex) { + } + + // Gets a clip from the channel + SOUNDCLIP *GetChannel(int index); + // Gets a clip from the channel but only if it's in playback state + SOUNDCLIP *GetChannelIfPlaying(int index); + // Assign new clip to the channel + SOUNDCLIP *SetChannel(int index, SOUNDCLIP *clip); + // Move clip from one channel to another, clearing the first channel + SOUNDCLIP *MoveChannel(int to, int from); }; // @@ -78,20 +76,20 @@ void calculate_reserved_channel_count(); void update_clip_default_volume(ScriptAudioClip *audioClip); void start_fading_in_new_track_if_applicable(int fadeInChannel, ScriptAudioClip *newSound); void stop_or_fade_out_channel(int fadeOutChannel, int fadeInChannel = -1, ScriptAudioClip *newSound = nullptr); -SOUNDCLIP* load_sound_clip(ScriptAudioClip *audioClip, bool repeat); -ScriptAudioChannel* play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *cachedClip = nullptr); +SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat); +ScriptAudioChannel *play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *cachedClip = nullptr); void remove_clips_of_type_from_queue(int audioType); void update_queued_clips_volume(int audioType, int new_vol); // Checks if speech voice-over is currently playing, and reapply volume drop to all other active clips void update_volume_drop_if_voiceover(); -ScriptAudioChannel* play_audio_clip(ScriptAudioClip *clip, int priority, int repeat, int fromOffset, bool queueIfNoChannel); -ScriptAudioChannel* play_audio_clip_by_index(int audioClipIndex); +ScriptAudioChannel *play_audio_clip(ScriptAudioClip *clip, int priority, int repeat, int fromOffset, bool queueIfNoChannel); +ScriptAudioChannel *play_audio_clip_by_index(int audioClipIndex); void stop_and_destroy_channel_ex(int chid, bool resetLegacyMusicSettings); -void stop_and_destroy_channel (int chid); +void stop_and_destroy_channel(int chid); // ***** BACKWARDS COMPATIBILITY WITH OLD AUDIO SYSTEM ***** // int get_old_style_number_for_sound(int sound_number); -SOUNDCLIP * load_sound_clip_from_old_style_number(bool isMusic, int indexNumber, bool repeat); +SOUNDCLIP *load_sound_clip_from_old_style_number(bool isMusic, int indexNumber, bool repeat); //============================================================================= @@ -100,12 +98,12 @@ void remove_mod_player(); void force_audiostream_include(); int get_volume_adjusted_for_distance(int volume, int sndX, int sndY, int sndMaxDist); void update_directional_sound_vol(); -void update_ambient_sound_vol (); +void update_ambient_sound_vol(); // Tells if the audio type is allowed to play with regards to current sound config bool is_audiotype_allowed_to_play(AudioFileType type); // Loads sound data referenced by audio clip item, and starts playback; // returns NULL on failure -SOUNDCLIP * load_sound_and_play(ScriptAudioClip *aclip, bool repeat); +SOUNDCLIP *load_sound_and_play(ScriptAudioClip *aclip, bool repeat); void stop_all_sound_and_music(); void shutdown_sound(); int play_sound(int val1); @@ -125,16 +123,16 @@ int calculate_max_volume(); void apply_volume_drop_modifier(bool applyModifier); // Update the music, and advance the crossfade on a step // (this should only be called once per game loop); -void update_audio_system_on_game_loop (); +void update_audio_system_on_game_loop(); void stopmusic(); void update_music_volume(); -void post_new_music_check (int newchannel); +void post_new_music_check(int newchannel); // Sets up the crossfading for playing the new music track, // and returns the channel number to use; the channel is guaranteed to be free -int prepare_for_new_music (); +int prepare_for_new_music(); // Gets audio clip from legacy music number, which also may contain queue flag ScriptAudioClip *get_audio_clip_for_music(int mnum); -SOUNDCLIP * load_music_from_disk(int mnum, bool doRepeat); +SOUNDCLIP *load_music_from_disk(int mnum, bool doRepeat); void newmusic(int mnum); extern AGS::Engine::Thread audioThread; @@ -156,6 +154,6 @@ extern int crossFadeVolumeAtStart; extern SOUNDCLIP *cachedQueuedMusic; // TODO: double check that ambient sounds array actually needs +1 -extern std::array ambient; +extern std::array < AmbientSound, MAX_SOUND_CHANNELS + 1 > ambient; #endif diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp index 3efe1c3ef3dc..ddf8b2e43900 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.cpp +++ b/engines/ags/engine/media/audio/clip_mydumbmod.cpp @@ -28,144 +28,152 @@ #include "media/audio/audiointernaldefs.h" void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop) { - DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(dp); - DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); - if (itsr == nullptr) - return; - - if (loop) - dumb_it_set_loop_callback(itsr, nullptr, nullptr); - else - dumb_it_set_loop_callback(itsr, dumb_it_callback_terminate, itsr); + DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(dp); + DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); + if (itsr == nullptr) + return; + + if (loop) + dumb_it_set_loop_callback(itsr, nullptr, nullptr); + else + dumb_it_set_loop_callback(itsr, dumb_it_callback_terminate, itsr); } -void MYMOD::poll() -{ - if (state_ != SoundClipPlaying) { return; } +void MYMOD::poll() { + if (state_ != SoundClipPlaying) { + return; + } - if (al_poll_duh(duhPlayer)) { - state_ = SoundClipStopped; - } + if (al_poll_duh(duhPlayer)) { + state_ = SoundClipStopped; + } } -void MYMOD::adjust_volume() -{ - if (!is_playing()) { return; } - al_duh_set_volume(duhPlayer, VOLUME_TO_DUMB_VOL(get_final_volume())); +void MYMOD::adjust_volume() { + if (!is_playing()) { + return; + } + al_duh_set_volume(duhPlayer, VOLUME_TO_DUMB_VOL(get_final_volume())); } -void MYMOD::set_volume(int newvol) -{ - vol = newvol; - adjust_volume(); +void MYMOD::set_volume(int newvol) { + vol = newvol; + adjust_volume(); } -void MYMOD::destroy() -{ - if (duhPlayer) { - al_stop_duh(duhPlayer); - } - duhPlayer = nullptr; +void MYMOD::destroy() { + if (duhPlayer) { + al_stop_duh(duhPlayer); + } + duhPlayer = nullptr; - if (tune) { - unload_duh(tune); - } - tune = nullptr; + if (tune) { + unload_duh(tune); + } + tune = nullptr; - state_ = SoundClipStopped; + state_ = SoundClipStopped; } -void MYMOD::seek(int patnum) -{ - if (!is_playing()) { return; } +void MYMOD::seek(int patnum) { + if (!is_playing()) { + return; + } - al_stop_duh(duhPlayer); - state_ = SoundClipInitial; + al_stop_duh(duhPlayer); + state_ = SoundClipInitial; - DUH_SIGRENDERER *sr = dumb_it_start_at_order(tune, 2, patnum); - duhPlayer = al_duh_encapsulate_sigrenderer(sr, VOLUME_TO_DUMB_VOL(vol), 8192, 22050); - if (!duhPlayer) { - duh_end_sigrenderer(sr); - return; - } + DUH_SIGRENDERER *sr = dumb_it_start_at_order(tune, 2, patnum); + duhPlayer = al_duh_encapsulate_sigrenderer(sr, VOLUME_TO_DUMB_VOL(vol), 8192, 22050); + if (!duhPlayer) { + duh_end_sigrenderer(sr); + return; + } - al_duh_set_loop(duhPlayer, repeat); - state_ = SoundClipPlaying; + al_duh_set_loop(duhPlayer, repeat); + state_ = SoundClipPlaying; } -int MYMOD::get_pos() -{ - if (!is_playing()) { return -1; } +int MYMOD::get_pos() { + if (!is_playing()) { + return -1; + } - // determine the current track number (DUMB calls them 'orders') - DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(duhPlayer); - DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); - if (itsr == nullptr) - return -1; + // determine the current track number (DUMB calls them 'orders') + DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(duhPlayer); + DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); + if (itsr == nullptr) + return -1; - return dumb_it_sr_get_current_order(itsr); + return dumb_it_sr_get_current_order(itsr); } -int MYMOD::get_real_mod_pos() -{ - if (!is_playing()) { return -1; } - return al_duh_get_position(duhPlayer); +int MYMOD::get_real_mod_pos() { + if (!is_playing()) { + return -1; + } + return al_duh_get_position(duhPlayer); } -int MYMOD::get_pos_ms() -{ - if (!is_playing()) { return -1; } - return (get_real_mod_pos() * 10) / 655; +int MYMOD::get_pos_ms() { + if (!is_playing()) { + return -1; + } + return (get_real_mod_pos() * 10) / 655; } -int MYMOD::get_length_ms() -{ - if (tune == nullptr) - return 0; +int MYMOD::get_length_ms() { + if (tune == nullptr) + return 0; - // duh_get_length represents time as 65536ths of a second - return (duh_get_length(tune) * 10) / 655; + // duh_get_length represents time as 65536ths of a second + return (duh_get_length(tune) * 10) / 655; } -int MYMOD::get_voice() -{ - // MOD uses so many different voices it's not practical to keep track - return -1; +int MYMOD::get_voice() { + // MOD uses so many different voices it's not practical to keep track + return -1; } void MYMOD::pause() { - if (state_ != SoundClipPlaying) { return; } - al_pause_duh(duhPlayer); - state_ = SoundClipPaused; + if (state_ != SoundClipPlaying) { + return; + } + al_pause_duh(duhPlayer); + state_ = SoundClipPaused; } void MYMOD::resume() { - if (state_ != SoundClipPaused) { return; } - al_resume_duh(duhPlayer); - state_ = SoundClipPlaying; + if (state_ != SoundClipPaused) { + return; + } + al_resume_duh(duhPlayer); + state_ = SoundClipPlaying; } int MYMOD::get_sound_type() { - return MUS_MOD; + return MUS_MOD; } int MYMOD::play() { - if (tune == nullptr) { return 0; } - - duhPlayer = al_start_duh(tune, 2, 0, 1.0, 8192, 22050); - if (!duhPlayer) { - return 0; - } - al_duh_set_loop(duhPlayer, repeat); - set_volume(vol); - - state_ = SoundClipPlaying; - return 1; -} + if (tune == nullptr) { + return 0; + } + + duhPlayer = al_start_duh(tune, 2, 0, 1.0, 8192, 22050); + if (!duhPlayer) { + return 0; + } + al_duh_set_loop(duhPlayer, repeat); + set_volume(vol); + + state_ = SoundClipPlaying; + return 1; +} MYMOD::MYMOD() : SOUNDCLIP() { - tune = nullptr; - duhPlayer = nullptr; + tune = nullptr; + duhPlayer = nullptr; } #endif // DUMB_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index bb7e2741746a..55efab4d1c4d 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -31,47 +31,46 @@ void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop); // MOD/XM (DUMB) -struct MYMOD : public SOUNDCLIP -{ - DUH *tune; - AL_DUH_PLAYER *duhPlayer; +struct MYMOD : public SOUNDCLIP { + DUH *tune; + AL_DUH_PLAYER *duhPlayer; - void poll() override; + void poll() override; - void set_volume(int newvol) override; + void set_volume(int newvol) override; - void destroy() override; + void destroy() override; - void seek(int patnum) override; + void seek(int patnum) override; - // NOTE: this implementation of the virtual function returns a MOD/XM - // "order" index, not actual playing position; - // this does not make much sense in the context of the interface itself, - // and, as it seems, was implemented so solely for the purpose of emulating - // deprecated "GetMODPattern" script function. - // (see Game_GetMODPattern(), and documentation for AudioChannel.Position property) - // TODO: find a way to redesign this behavior - int get_pos() override; + // NOTE: this implementation of the virtual function returns a MOD/XM + // "order" index, not actual playing position; + // this does not make much sense in the context of the interface itself, + // and, as it seems, was implemented so solely for the purpose of emulating + // deprecated "GetMODPattern" script function. + // (see Game_GetMODPattern(), and documentation for AudioChannel.Position property) + // TODO: find a way to redesign this behavior + int get_pos() override; - int get_pos_ms() override; + int get_pos_ms() override; - int get_length_ms() override; + int get_length_ms() override; - void pause() override; + void pause() override; - void resume() override; + void resume() override; - int get_sound_type() override; + int get_sound_type() override; - int play() override; + int play() override; - MYMOD(); + MYMOD(); protected: - int get_voice() override; - void adjust_volume() override; - // Returns real MOD/XM playing position - int get_real_mod_pos(); + int get_voice() override; + void adjust_volume() override; + // Returns real MOD/XM playing position + int get_real_mod_pos(); }; #endif diff --git a/engines/ags/engine/media/audio/clip_myjgmod.cpp b/engines/ags/engine/media/audio/clip_myjgmod.cpp index be3758aa264e..2dbbc01c748e 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.cpp +++ b/engines/ags/engine/media/audio/clip_myjgmod.cpp @@ -27,68 +27,61 @@ #include "media/audio/clip_myjgmod.h" #include "media/audio/audiointernaldefs.h" -int MYMOD::poll() -{ - if (done) - return done; +int MYMOD::poll() { + if (done) + return done; - if (is_mod_playing() == 0) - done = 1; + if (is_mod_playing() == 0) + done = 1; - return done; + return done; } -void MYMOD::set_volume(int newvol) -{ - vol = newvol; - if (!done) - set_mod_volume(newvol); +void MYMOD::set_volume(int newvol) { + vol = newvol; + if (!done) + set_mod_volume(newvol); } -void MYMOD::destroy() -{ - stop_mod(); - destroy_mod(tune); - tune = NULL; +void MYMOD::destroy() { + stop_mod(); + destroy_mod(tune); + tune = NULL; } -void MYMOD::seek(int patnum) -{ - if (is_mod_playing() != 0) - goto_mod_track(patnum); +void MYMOD::seek(int patnum) { + if (is_mod_playing() != 0) + goto_mod_track(patnum); } -int MYMOD::get_pos() -{ - if (!is_mod_playing()) - return -1; - return mi.trk; +int MYMOD::get_pos() { + if (!is_mod_playing()) + return -1; + return mi.trk; } -int MYMOD::get_pos_ms() -{ - return 0; // we don't know ms offset +int MYMOD::get_pos_ms() { + return 0; // we don't know ms offset } -int MYMOD::get_length_ms() -{ // we don't know ms - return 0; +int MYMOD::get_length_ms() { + // we don't know ms + return 0; } -int MYMOD::get_voice() -{ - // MOD uses so many different voices it's not practical to keep track - return -1; +int MYMOD::get_voice() { + // MOD uses so many different voices it's not practical to keep track + return -1; } int MYMOD::get_sound_type() { - return MUS_MOD; + return MUS_MOD; } int MYMOD::play() { - play_mod(tune, repeat); + play_mod(tune, repeat); - return 1; + return 1; } MYMOD::MYMOD() : SOUNDCLIP() { diff --git a/engines/ags/engine/media/audio/clip_myjgmod.h b/engines/ags/engine/media/audio/clip_myjgmod.h index 82d7ff3e038d..72e6032230fb 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.h +++ b/engines/ags/engine/media/audio/clip_myjgmod.h @@ -27,31 +27,30 @@ #include "media/audio/soundclip.h" // MOD/XM (JGMOD) -struct MYMOD:public SOUNDCLIP -{ - JGMOD *tune; +struct MYMOD: public SOUNDCLIP { + JGMOD *tune; - int poll(); + int poll(); - void set_volume(int newvol); + void set_volume(int newvol); - void destroy(); + void destroy(); - void seek(int patnum); + void seek(int patnum); - int get_pos(); + int get_pos(); - int get_pos_ms(); + int get_pos_ms(); - int get_length_ms(); + int get_length_ms(); - int get_voice(); + int get_voice(); - int get_sound_type(); + int get_sound_type(); - int play(); + int play(); - MYMOD(); + MYMOD(); }; #endif diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index 5241c9471b62..06f5bf986fd7 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -25,95 +25,100 @@ #include "media/audio/clip_mymidi.h" #include "media/audio/audiointernaldefs.h" -void MYMIDI::poll() -{ - if (state_ != SoundClipPlaying) { return; } +void MYMIDI::poll() { + if (state_ != SoundClipPlaying) { + return; + } - if (midi_pos < 0) - state_ = SoundClipStopped; + if (midi_pos < 0) + state_ = SoundClipStopped; } -void MYMIDI::adjust_volume() -{ - if (!is_playing()) { return; } - ::set_volume(-1, get_final_volume()); +void MYMIDI::adjust_volume() { + if (!is_playing()) { + return; + } + ::set_volume(-1, get_final_volume()); } -void MYMIDI::set_volume(int newvol) -{ - vol = newvol; - adjust_volume(); +void MYMIDI::set_volume(int newvol) { + vol = newvol; + adjust_volume(); } -void MYMIDI::destroy() -{ - stop_midi(); - - if (tune) { - destroy_midi(tune); - } - tune = nullptr; +void MYMIDI::destroy() { + stop_midi(); - state_ = SoundClipStopped; + if (tune) { + destroy_midi(tune); + } + tune = nullptr; + + state_ = SoundClipStopped; } -void MYMIDI::seek(int pos) -{ - if (!is_playing()) { return; } - midi_seek(pos); +void MYMIDI::seek(int pos) { + if (!is_playing()) { + return; + } + midi_seek(pos); } -int MYMIDI::get_pos() -{ - if (!is_playing()) { return -1; } - return midi_pos; +int MYMIDI::get_pos() { + if (!is_playing()) { + return -1; + } + return midi_pos; } -int MYMIDI::get_pos_ms() -{ - return 0; // we don't know ms with midi +int MYMIDI::get_pos_ms() { + return 0; // we don't know ms with midi } -int MYMIDI::get_length_ms() -{ - return lengthInSeconds * 1000; +int MYMIDI::get_length_ms() { + return lengthInSeconds * 1000; } -int MYMIDI::get_voice() -{ - // voice is N/A for midi - return -1; +int MYMIDI::get_voice() { + // voice is N/A for midi + return -1; } void MYMIDI::pause() { - if (state_ != SoundClipPlaying) { return; } - midi_pause(); - state_ = SoundClipPaused; + if (state_ != SoundClipPlaying) { + return; + } + midi_pause(); + state_ = SoundClipPaused; } void MYMIDI::resume() { - if (state_ != SoundClipPaused) { return; } - midi_resume(); - state_ = SoundClipPlaying; + if (state_ != SoundClipPaused) { + return; + } + midi_resume(); + state_ = SoundClipPlaying; } int MYMIDI::get_sound_type() { - return MUS_MIDI; + return MUS_MIDI; } int MYMIDI::play() { - if (tune == nullptr) { return 0; } + if (tune == nullptr) { + return 0; + } - lengthInSeconds = get_midi_length(tune); - if (::play_midi(tune, repeat)) { - return 0; - } + lengthInSeconds = get_midi_length(tune); + if (::play_midi(tune, repeat)) { + return 0; + } - state_ = SoundClipPlaying; - return 1; + state_ = SoundClipPlaying; + return 1; } MYMIDI::MYMIDI() : SOUNDCLIP() { - tune = nullptr; - lengthInSeconds = 0; + tune = nullptr; + lengthInSeconds = 0; } diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index b7970f60efd5..e250c346f8a3 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -26,38 +26,37 @@ #include "media/audio/soundclip.h" // MIDI -struct MYMIDI:public SOUNDCLIP -{ - MIDI *tune; - int lengthInSeconds; +struct MYMIDI: public SOUNDCLIP { + MIDI *tune; + int lengthInSeconds; - void poll() override; + void poll() override; - void set_volume(int newvol) override; + void set_volume(int newvol) override; - void destroy() override; + void destroy() override; - void seek(int pos) override; + void seek(int pos) override; - int get_pos() override; + int get_pos() override; - int get_pos_ms() override; + int get_pos_ms() override; - int get_length_ms() override; + int get_length_ms() override; - void pause() override; + void pause() override; - void resume() override; + void resume() override; - int get_sound_type() override; + int get_sound_type() override; - int play() override; + int play() override; - MYMIDI(); + MYMIDI(); protected: - int get_voice() override; - void adjust_volume() override; + int get_voice() override; + void adjust_volume() override; }; #endif diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp index d4aff270c58b..792c563fb4a7 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -33,149 +33,152 @@ #include "platform/base/agsplatformdriver.h" -void MYMP3::poll() -{ - if (state_ != SoundClipPlaying) { return; } - - // update the buffer - char *tempbuf = nullptr; - { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - tempbuf = (char *)almp3_get_mp3stream_buffer(stream); - } - - if (tempbuf != nullptr) { - AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)in->userdata; - int free_val = -1; - if (chunksize >= obj->remains) { - chunksize = obj->remains; - free_val = chunksize; - } - pack_fread(tempbuf, chunksize, in); - - { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - almp3_free_mp3stream_buffer(stream, free_val); - } - } - - { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - if (almp3_poll_mp3stream(stream) == ALMP3_POLL_PLAYJUSTFINISHED) { - state_ = SoundClipStopped; - } - } +void MYMP3::poll() { + if (state_ != SoundClipPlaying) { + return; + } + + // update the buffer + char *tempbuf = nullptr; + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + tempbuf = (char *)almp3_get_mp3stream_buffer(stream); + } + + if (tempbuf != nullptr) { + AGS_PACKFILE_OBJ *obj = (AGS_PACKFILE_OBJ *)in->userdata; + int free_val = -1; + if (chunksize >= obj->remains) { + chunksize = obj->remains; + free_val = chunksize; + } + pack_fread(tempbuf, chunksize, in); + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_free_mp3stream_buffer(stream, free_val); + } + } + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + if (almp3_poll_mp3stream(stream) == ALMP3_POLL_PLAYJUSTFINISHED) { + state_ = SoundClipStopped; + } + } } -void MYMP3::adjust_stream() -{ - if (!is_playing()) { return; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - almp3_adjust_mp3stream(stream, get_final_volume(), panning, speed); +void MYMP3::adjust_stream() { + if (!is_playing()) { + return; + } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_adjust_mp3stream(stream, get_final_volume(), panning, speed); } -void MYMP3::adjust_volume() -{ - adjust_stream(); +void MYMP3::adjust_volume() { + adjust_stream(); } -void MYMP3::set_volume(int newvol) -{ - // boost MP3 volume - newvol += 20; - if (newvol > 255) - newvol = 255; +void MYMP3::set_volume(int newvol) { + // boost MP3 volume + newvol += 20; + if (newvol > 255) + newvol = 255; - vol = newvol; - adjust_stream(); + vol = newvol; + adjust_stream(); } -void MYMP3::set_speed(int new_speed) -{ - speed = new_speed; - adjust_stream(); +void MYMP3::set_speed(int new_speed) { + speed = new_speed; + adjust_stream(); } -void MYMP3::destroy() -{ - if (stream) { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - almp3_stop_mp3stream(stream); - almp3_destroy_mp3stream(stream); - } - stream = nullptr; +void MYMP3::destroy() { + if (stream) { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_stop_mp3stream(stream); + almp3_destroy_mp3stream(stream); + } + stream = nullptr; - if (buffer) - free(buffer); - buffer = nullptr; + if (buffer) + free(buffer); + buffer = nullptr; - pack_fclose(in); + pack_fclose(in); - state_ = SoundClipStopped; + state_ = SoundClipStopped; } -void MYMP3::seek(int pos) -{ - if (!is_playing()) { return; } - quit("Tried to seek an mp3stream"); +void MYMP3::seek(int pos) { + if (!is_playing()) { + return; + } + quit("Tried to seek an mp3stream"); } -int MYMP3::get_pos() -{ - return 0; // Return 0 to signify that Seek is not supported - // return almp3_get_pos_msecs_mp3stream (stream); +int MYMP3::get_pos() { + return 0; // Return 0 to signify that Seek is not supported + // return almp3_get_pos_msecs_mp3stream (stream); } -int MYMP3::get_pos_ms() -{ - if (!is_playing()) { return -1; } +int MYMP3::get_pos_ms() { + if (!is_playing()) { + return -1; + } AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - return almp3_get_pos_msecs_mp3stream(stream); + return almp3_get_pos_msecs_mp3stream(stream); } -int MYMP3::get_length_ms() -{ - if (!is_playing()) { return -1; } +int MYMP3::get_length_ms() { + if (!is_playing()) { + return -1; + } AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - return almp3_get_length_msecs_mp3stream(stream, filesize); + return almp3_get_length_msecs_mp3stream(stream, filesize); } -int MYMP3::get_voice() -{ - if (!is_playing()) { return -1; } +int MYMP3::get_voice() { + if (!is_playing()) { + return -1; + } AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - AUDIOSTREAM *ast = almp3_get_audiostream_mp3stream(stream); - return (ast != nullptr ? ast->voice : -1); + AUDIOSTREAM *ast = almp3_get_audiostream_mp3stream(stream); + return (ast != nullptr ? ast->voice : -1); } int MYMP3::get_sound_type() { - return MUS_MP3; + return MUS_MP3; } int MYMP3::play() { - if (in == nullptr) { return 0; } + if (in == nullptr) { + return 0; + } - { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - if (almp3_play_mp3stream(stream, chunksize, (vol > 230) ? vol : vol + 20, panning) != ALMP3_OK) { - return 0; - } - } + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + if (almp3_play_mp3stream(stream, chunksize, (vol > 230) ? vol : vol + 20, panning) != ALMP3_OK) { + return 0; + } + } - state_ = SoundClipPlaying; + state_ = SoundClipPlaying; - if (!psp_audio_multithreaded) - poll(); + if (!psp_audio_multithreaded) + poll(); - return 1; + return 1; } MYMP3::MYMP3() : SOUNDCLIP() { - stream = nullptr; - in = nullptr; - filesize = 0; - buffer = nullptr; - chunksize = 0; + stream = nullptr; + in = nullptr; + filesize = 0; + buffer = nullptr; + chunksize = 0; } #endif // !NO_MP3_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index c7cde052f122..d4fafabe9819 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -28,31 +28,30 @@ extern AGS::Engine::Mutex _mp3_mutex; -struct MYMP3:public SOUNDCLIP -{ - ALMP3_MP3STREAM *stream; - PACKFILE *in; - size_t filesize; - char *buffer; - int chunksize; +struct MYMP3: public SOUNDCLIP { + ALMP3_MP3STREAM *stream; + PACKFILE *in; + size_t filesize; + char *buffer; + int chunksize; - void poll() override; - void set_volume(int newvol) override; - void set_speed(int new_speed) override; - void destroy() override; - void seek(int pos) override; - int get_pos() override; - int get_pos_ms() override; - int get_length_ms() override; - int get_sound_type() override; - int play() override; - MYMP3(); + void poll() override; + void set_volume(int newvol) override; + void set_speed(int new_speed) override; + void destroy() override; + void seek(int pos) override; + int get_pos() override; + int get_pos_ms() override; + int get_length_ms() override; + int get_sound_type() override; + int play() override; + MYMP3(); protected: - int get_voice() override; - void adjust_volume() override; + int get_voice() override; + void adjust_volume() override; private: - void adjust_stream(); + void adjust_stream(); }; #endif diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp index 6cc9be62813a..98a2d1485b4f 100644 --- a/engines/ags/engine/media/audio/clip_myogg.cpp +++ b/engines/ags/engine/media/audio/clip_myogg.cpp @@ -30,182 +30,179 @@ #include "platform/base/agsplatformdriver.h" extern "C" { - extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); - extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); - extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); - extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); + extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); + extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); + extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); + extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); } -void MYOGG::poll() -{ - if (state_ != SoundClipPlaying) { return; } - - AGS_PACKFILE_OBJ* obj = (AGS_PACKFILE_OBJ*)in->userdata; - if (obj->remains > 0) - { - // update the buffer - char *tempbuf = (char *)alogg_get_oggstream_buffer(stream); - if (tempbuf != nullptr) - { - int free_val = -1; - if (chunksize >= obj->remains) - { - chunksize = obj->remains; - free_val = chunksize; - } - pack_fread(tempbuf, chunksize, in); - alogg_free_oggstream_buffer(stream, free_val); - } - } - - int ret = alogg_poll_oggstream(stream); - if (ret == ALOGG_OK || ret == ALOGG_POLL_BUFFERUNDERRUN) - get_pos_ms(); // call this to keep the last_but_one stuff up to date - else { - // finished playing or error - state_ = SoundClipStopped; - } +void MYOGG::poll() { + if (state_ != SoundClipPlaying) { + return; + } + + AGS_PACKFILE_OBJ *obj = (AGS_PACKFILE_OBJ *)in->userdata; + if (obj->remains > 0) { + // update the buffer + char *tempbuf = (char *)alogg_get_oggstream_buffer(stream); + if (tempbuf != nullptr) { + int free_val = -1; + if (chunksize >= obj->remains) { + chunksize = obj->remains; + free_val = chunksize; + } + pack_fread(tempbuf, chunksize, in); + alogg_free_oggstream_buffer(stream, free_val); + } + } + + int ret = alogg_poll_oggstream(stream); + if (ret == ALOGG_OK || ret == ALOGG_POLL_BUFFERUNDERRUN) + get_pos_ms(); // call this to keep the last_but_one stuff up to date + else { + // finished playing or error + state_ = SoundClipStopped; + } } -void MYOGG::adjust_stream() -{ - if (!is_playing()) { return; } - alogg_adjust_oggstream(stream, get_final_volume(), panning, speed); +void MYOGG::adjust_stream() { + if (!is_playing()) { + return; + } + alogg_adjust_oggstream(stream, get_final_volume(), panning, speed); } -void MYOGG::adjust_volume() -{ - adjust_stream(); +void MYOGG::adjust_volume() { + adjust_stream(); } -void MYOGG::set_volume(int newvol) -{ - // boost MP3 volume - newvol += 20; - if (newvol > 255) - newvol = 255; - vol = newvol; - adjust_stream(); +void MYOGG::set_volume(int newvol) { + // boost MP3 volume + newvol += 20; + if (newvol > 255) + newvol = 255; + vol = newvol; + adjust_stream(); } -void MYOGG::set_speed(int new_speed) -{ - speed = new_speed; - adjust_stream(); +void MYOGG::set_speed(int new_speed) { + speed = new_speed; + adjust_stream(); } -void MYOGG::destroy() -{ - if (stream) { - alogg_stop_oggstream(stream); - alogg_destroy_oggstream(stream); - } - stream = nullptr; +void MYOGG::destroy() { + if (stream) { + alogg_stop_oggstream(stream); + alogg_destroy_oggstream(stream); + } + stream = nullptr; - if (buffer) - free(buffer); - buffer = nullptr; + if (buffer) + free(buffer); + buffer = nullptr; - pack_fclose(in); + pack_fclose(in); - state_ = SoundClipStopped; + state_ = SoundClipStopped; } -void MYOGG::seek(int pos) -{ - if (!is_playing()) { return; } - quit("Attempted to seek an oggstream; operation not permitted"); +void MYOGG::seek(int pos) { + if (!is_playing()) { + return; + } + quit("Attempted to seek an oggstream; operation not permitted"); } -int MYOGG::get_pos() -{ - return 0; +int MYOGG::get_pos() { + return 0; } -int MYOGG::get_pos_ms() -{ - // Unfortunately the alogg_get_pos_msecs_oggstream function - // returns the ms offset that was last decoded, so it's always - // ahead of the actual playback. Therefore we have this - // hideous hack below to sort it out. - if ((!is_playing()) || (!alogg_is_playing_oggstream(stream))) - return 0; - - AUDIOSTREAM *str = alogg_get_audiostream_oggstream(stream); - long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; - - if (last_ms_offs != alogg_get_pos_msecs_oggstream(stream)) { - last_but_one_but_one = last_but_one; - last_but_one = last_ms_offs; - last_ms_offs = alogg_get_pos_msecs_oggstream(stream); - } - - // just about to switch buffers - if (offs < 0) - return last_but_one; - - int end_of_stream = alogg_is_end_of_oggstream(stream); - - if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { - switch (end_of_stream) { -case 0: -case 2: - offs -= (last_but_one - last_but_one_but_one); - break; -case 1: - offs -= (last_but_one - last_but_one_but_one); - break; - } - } - - if (end_of_stream == 1) { - - return offs + last_but_one; - } - - return offs + last_but_one_but_one; +int MYOGG::get_pos_ms() { + // Unfortunately the alogg_get_pos_msecs_oggstream function + // returns the ms offset that was last decoded, so it's always + // ahead of the actual playback. Therefore we have this + // hideous hack below to sort it out. + if ((!is_playing()) || (!alogg_is_playing_oggstream(stream))) + return 0; + + AUDIOSTREAM *str = alogg_get_audiostream_oggstream(stream); + long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; + + if (last_ms_offs != alogg_get_pos_msecs_oggstream(stream)) { + last_but_one_but_one = last_but_one; + last_but_one = last_ms_offs; + last_ms_offs = alogg_get_pos_msecs_oggstream(stream); + } + + // just about to switch buffers + if (offs < 0) + return last_but_one; + + int end_of_stream = alogg_is_end_of_oggstream(stream); + + if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { + switch (end_of_stream) { + case 0: + case 2: + offs -= (last_but_one - last_but_one_but_one); + break; + case 1: + offs -= (last_but_one - last_but_one_but_one); + break; + } + } + + if (end_of_stream == 1) { + + return offs + last_but_one; + } + + return offs + last_but_one_but_one; } -int MYOGG::get_length_ms() -{ // streamed OGG is variable bitrate so we don't know - return 0; +int MYOGG::get_length_ms() { + // streamed OGG is variable bitrate so we don't know + return 0; } -int MYOGG::get_voice() -{ - if (!is_playing()) { return -1; } +int MYOGG::get_voice() { + if (!is_playing()) { + return -1; + } - AUDIOSTREAM *ast = alogg_get_audiostream_oggstream(stream); - if (ast) - return ast->voice; - return -1; + AUDIOSTREAM *ast = alogg_get_audiostream_oggstream(stream); + if (ast) + return ast->voice; + return -1; } int MYOGG::get_sound_type() { - return MUS_OGG; + return MUS_OGG; } int MYOGG::play() { - if (in == nullptr) { return 0; } - - if (alogg_play_oggstream(stream, MP3CHUNKSIZE, (vol > 230) ? vol : vol + 20, panning) != ALOGG_OK) { - return 0; - } + if (in == nullptr) { + return 0; + } - state_ = SoundClipPlaying; + if (alogg_play_oggstream(stream, MP3CHUNKSIZE, (vol > 230) ? vol : vol + 20, panning) != ALOGG_OK) { + return 0; + } - if (!psp_audio_multithreaded) - poll(); + state_ = SoundClipPlaying; - return 1; + if (!psp_audio_multithreaded) + poll(); + + return 1; } MYOGG::MYOGG() : SOUNDCLIP() { - stream = nullptr; - in = nullptr; - buffer = nullptr; - chunksize = 0; - last_but_one_but_one = 0; - last_but_one = 0; - last_ms_offs = 0; + stream = nullptr; + in = nullptr; + buffer = nullptr; + chunksize = 0; + last_but_one_but_one = 0; + last_but_one = 0; + last_ms_offs = 0; } diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h index 06793a8e3182..b8fbd0dace0e 100644 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -26,43 +26,42 @@ #include "alogg.h" #include "media/audio/soundclip.h" -struct MYOGG:public SOUNDCLIP -{ - ALOGG_OGGSTREAM *stream; - PACKFILE *in; - char *buffer; - int chunksize; +struct MYOGG: public SOUNDCLIP { + ALOGG_OGGSTREAM *stream; + PACKFILE *in; + char *buffer; + int chunksize; - int last_but_one_but_one; - int last_but_one; - int last_ms_offs; + int last_but_one_but_one; + int last_but_one; + int last_ms_offs; - void poll() override; + void poll() override; - void set_volume(int newvol) override; - void set_speed(int new_speed) override; + void set_volume(int newvol) override; + void set_speed(int new_speed) override; - void destroy() override; + void destroy() override; - void seek(int pos) override; + void seek(int pos) override; - int get_pos() override; + int get_pos() override; - int get_pos_ms() override; + int get_pos_ms() override; - int get_length_ms() override; + int get_length_ms() override; - int get_sound_type() override; + int get_sound_type() override; - int play() override; + int play() override; - MYOGG(); + MYOGG(); protected: - int get_voice() override; - void adjust_volume() override; + int get_voice() override; + void adjust_volume() override; private: - void adjust_stream(); + void adjust_stream(); }; #endif diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp index aef22b4d1537..63b760bdaf12 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -37,128 +37,129 @@ extern int our_eip; // of the mp3 functions and unlocked afterwards. AGS::Engine::Mutex _mp3_mutex; -void MYSTATICMP3::poll() -{ - if (state_ != SoundClipPlaying) { return; } - - int oldeip = our_eip; - our_eip = 5997; - - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - int result = almp3_poll_mp3(tune); - - if (result == ALMP3_POLL_PLAYJUSTFINISHED) - { - if (!repeat) - { - state_ = SoundClipStopped; - } - } - our_eip = oldeip; +void MYSTATICMP3::poll() { + if (state_ != SoundClipPlaying) { + return; + } + + int oldeip = our_eip; + our_eip = 5997; + + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + int result = almp3_poll_mp3(tune); + + if (result == ALMP3_POLL_PLAYJUSTFINISHED) { + if (!repeat) { + state_ = SoundClipStopped; + } + } + our_eip = oldeip; } -void MYSTATICMP3::adjust_stream() -{ - if (!is_playing()) { return; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - almp3_adjust_mp3(tune, get_final_volume(), panning, speed, repeat); +void MYSTATICMP3::adjust_stream() { + if (!is_playing()) { + return; + } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_adjust_mp3(tune, get_final_volume(), panning, speed, repeat); } -void MYSTATICMP3::adjust_volume() -{ - adjust_stream(); +void MYSTATICMP3::adjust_volume() { + adjust_stream(); } -void MYSTATICMP3::set_volume(int newvol) -{ - vol = newvol; - adjust_stream(); +void MYSTATICMP3::set_volume(int newvol) { + vol = newvol; + adjust_stream(); } -void MYSTATICMP3::set_speed(int new_speed) -{ - speed = new_speed; - adjust_stream(); +void MYSTATICMP3::set_speed(int new_speed) { + speed = new_speed; + adjust_stream(); } -void MYSTATICMP3::destroy() -{ - if (tune) { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - almp3_stop_mp3(tune); - almp3_destroy_mp3(tune); - } - tune = nullptr; - - if (mp3buffer) { - sound_cache_free(mp3buffer, false); - } - mp3buffer = nullptr; - - state_ = SoundClipStopped; +void MYSTATICMP3::destroy() { + if (tune) { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_stop_mp3(tune); + almp3_destroy_mp3(tune); + } + tune = nullptr; + + if (mp3buffer) { + sound_cache_free(mp3buffer, false); + } + mp3buffer = nullptr; + + state_ = SoundClipStopped; } -void MYSTATICMP3::seek(int pos) -{ - if (!is_playing()) { return; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - almp3_seek_abs_msecs_mp3(tune, pos); +void MYSTATICMP3::seek(int pos) { + if (!is_playing()) { + return; + } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + almp3_seek_abs_msecs_mp3(tune, pos); } -int MYSTATICMP3::get_pos() -{ - if (!is_playing()) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - return almp3_get_pos_msecs_mp3(tune); +int MYSTATICMP3::get_pos() { + if (!is_playing()) { + return -1; + } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + return almp3_get_pos_msecs_mp3(tune); } -int MYSTATICMP3::get_pos_ms() -{ - int result = get_pos(); - return result; +int MYSTATICMP3::get_pos_ms() { + int result = get_pos(); + return result; } -int MYSTATICMP3::get_length_ms() -{ - if (tune == nullptr) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - return almp3_get_length_msecs_mp3(tune); +int MYSTATICMP3::get_length_ms() { + if (tune == nullptr) { + return -1; + } + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + return almp3_get_length_msecs_mp3(tune); } -int MYSTATICMP3::get_voice() -{ - if (!is_playing()) { return -1; } +int MYSTATICMP3::get_voice() { + if (!is_playing()) { + return -1; + } AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - AUDIOSTREAM *ast = almp3_get_audiostream_mp3(tune); + AUDIOSTREAM *ast = almp3_get_audiostream_mp3(tune); return (ast != nullptr ? ast->voice : -1); } int MYSTATICMP3::get_sound_type() { - return MUS_MP3; + return MUS_MP3; } int MYSTATICMP3::play() { - if (tune == nullptr) { return 0; } + if (tune == nullptr) { + return 0; + } - { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - int result = almp3_play_ex_mp3(tune, 16384, vol, panning, 1000, repeat); - if (result != ALMP3_OK) { - return 0; - } - } + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + int result = almp3_play_ex_mp3(tune, 16384, vol, panning, 1000, repeat); + if (result != ALMP3_OK) { + return 0; + } + } - state_ = SoundClipPlaying; + state_ = SoundClipPlaying; - if (!psp_audio_multithreaded) - poll(); + if (!psp_audio_multithreaded) + poll(); - return 1; + return 1; } MYSTATICMP3::MYSTATICMP3() : SOUNDCLIP() { - tune = nullptr; - mp3buffer = nullptr; + tune = nullptr; + mp3buffer = nullptr; } #endif // !NO_MP3_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index 0c992cd0ac8e..6492518430cb 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -29,37 +29,36 @@ extern AGS::Engine::Mutex _mp3_mutex; // pre-loaded (non-streaming) MP3 file -struct MYSTATICMP3:public SOUNDCLIP -{ - ALMP3_MP3 *tune; - char *mp3buffer; +struct MYSTATICMP3: public SOUNDCLIP { + ALMP3_MP3 *tune; + char *mp3buffer; - void poll() override; + void poll() override; - void set_volume(int newvol) override; - void set_speed(int new_speed) override; + void set_volume(int newvol) override; + void set_speed(int new_speed) override; - void destroy() override; + void destroy() override; - void seek(int pos) override; + void seek(int pos) override; - int get_pos() override; + int get_pos() override; - int get_pos_ms() override; + int get_pos_ms() override; - int get_length_ms() override; + int get_length_ms() override; - int get_sound_type() override; + int get_sound_type() override; - int play() override; + int play() override; - MYSTATICMP3(); + MYSTATICMP3(); protected: - int get_voice() override; - void adjust_volume() override; + int get_voice() override; + void adjust_volume() override; private: - void adjust_stream(); + void adjust_stream(); }; #endif diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp index 759559643fbc..1efb47f45a25 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticogg.cpp @@ -29,185 +29,187 @@ #include "platform/base/agsplatformdriver.h" extern "C" { - extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); - extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); - extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); - extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); + extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); + extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); + extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); + extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); } extern int use_extra_sound_offset; // defined in ac.cpp -void MYSTATICOGG::poll() -{ - if (state_ != SoundClipPlaying) { return; } +void MYSTATICOGG::poll() { + if (state_ != SoundClipPlaying) { + return; + } - if (alogg_poll_ogg(tune) == ALOGG_POLL_PLAYJUSTFINISHED) { - if (!repeat) - { - state_ = SoundClipStopped; - } - } - else get_pos(); // call this to keep the last_but_one stuff up to date + if (alogg_poll_ogg(tune) == ALOGG_POLL_PLAYJUSTFINISHED) { + if (!repeat) { + state_ = SoundClipStopped; + } + } else get_pos(); // call this to keep the last_but_one stuff up to date } -void MYSTATICOGG::adjust_stream() -{ - if (!is_playing()) { return; } - alogg_adjust_ogg(tune, get_final_volume(), panning, speed, repeat); +void MYSTATICOGG::adjust_stream() { + if (!is_playing()) { + return; + } + alogg_adjust_ogg(tune, get_final_volume(), panning, speed, repeat); } -void MYSTATICOGG::adjust_volume() -{ - adjust_stream(); +void MYSTATICOGG::adjust_volume() { + adjust_stream(); } -void MYSTATICOGG::set_volume(int newvol) -{ - vol = newvol; - adjust_stream(); +void MYSTATICOGG::set_volume(int newvol) { + vol = newvol; + adjust_stream(); } -void MYSTATICOGG::set_speed(int new_speed) -{ - speed = new_speed; - adjust_stream(); +void MYSTATICOGG::set_speed(int new_speed) { + speed = new_speed; + adjust_stream(); } -void MYSTATICOGG::destroy() -{ - if (tune) { - alogg_stop_ogg(tune); - alogg_destroy_ogg(tune); - } - tune = nullptr; +void MYSTATICOGG::destroy() { + if (tune) { + alogg_stop_ogg(tune); + alogg_destroy_ogg(tune); + } + tune = nullptr; - if (mp3buffer) { - sound_cache_free(mp3buffer, false); - } - mp3buffer = nullptr; + if (mp3buffer) { + sound_cache_free(mp3buffer, false); + } + mp3buffer = nullptr; - state_ = SoundClipStopped; + state_ = SoundClipStopped; } -void MYSTATICOGG::seek(int pos) -{ - if (!is_playing()) { return; } +void MYSTATICOGG::seek(int pos) { + if (!is_playing()) { + return; + } - // we stop and restart it because otherwise the buffer finishes - // playing first and the seek isn't quite accurate - alogg_stop_ogg(tune); - state_ = SoundClipInitial; - play_from(pos); + // we stop and restart it because otherwise the buffer finishes + // playing first and the seek isn't quite accurate + alogg_stop_ogg(tune); + state_ = SoundClipInitial; + play_from(pos); } -int MYSTATICOGG::get_pos() -{ - if (!is_playing()) { return -1; } - return get_pos_ms(); +int MYSTATICOGG::get_pos() { + if (!is_playing()) { + return -1; + } + return get_pos_ms(); } -int MYSTATICOGG::get_pos_ms() -{ - if (!is_playing()) { return -1; } +int MYSTATICOGG::get_pos_ms() { + if (!is_playing()) { + return -1; + } - // Unfortunately the alogg_get_pos_msecs function - // returns the ms offset that was last decoded, so it's always - // ahead of the actual playback. Therefore we have this - // hideous hack below to sort it out. - if (!alogg_is_playing_ogg(tune)) - return 0; + // Unfortunately the alogg_get_pos_msecs function + // returns the ms offset that was last decoded, so it's always + // ahead of the actual playback. Therefore we have this + // hideous hack below to sort it out. + if (!alogg_is_playing_ogg(tune)) + return 0; - AUDIOSTREAM *str = alogg_get_audiostream_ogg(tune); - long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; + AUDIOSTREAM *str = alogg_get_audiostream_ogg(tune); + long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; - if (last_ms_offs != alogg_get_pos_msecs_ogg(tune)) { - last_but_one_but_one = last_but_one; - last_but_one = last_ms_offs; - last_ms_offs = alogg_get_pos_msecs_ogg(tune); - } + if (last_ms_offs != alogg_get_pos_msecs_ogg(tune)) { + last_but_one_but_one = last_but_one; + last_but_one = last_ms_offs; + last_ms_offs = alogg_get_pos_msecs_ogg(tune); + } - // just about to switch buffers - if (offs < 0) - return last_but_one; + // just about to switch buffers + if (offs < 0) + return last_but_one; - int end_of_stream = alogg_is_end_of_ogg(tune); + int end_of_stream = alogg_is_end_of_ogg(tune); - if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { - switch (end_of_stream) { -case 0: -case 2: - offs -= (last_but_one - last_but_one_but_one); - break; -case 1: - offs -= (last_but_one - last_but_one_but_one); - break; - } - } + if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { + switch (end_of_stream) { + case 0: + case 2: + offs -= (last_but_one - last_but_one_but_one); + break; + case 1: + offs -= (last_but_one - last_but_one_but_one); + break; + } + } - if (end_of_stream == 1) { - return offs + last_but_one + extraOffset; - } + if (end_of_stream == 1) { + return offs + last_but_one + extraOffset; + } - return offs + last_but_one_but_one + extraOffset; + return offs + last_but_one_but_one + extraOffset; } -int MYSTATICOGG::get_length_ms() -{ - if (tune == nullptr) { return -1; } - return alogg_get_length_msecs_ogg(tune); +int MYSTATICOGG::get_length_ms() { + if (tune == nullptr) { + return -1; + } + return alogg_get_length_msecs_ogg(tune); } -int MYSTATICOGG::get_voice() -{ - if (!is_playing()) { return -1; } - AUDIOSTREAM *ast = alogg_get_audiostream_ogg(tune); - if (ast) - return ast->voice; - return -1; +int MYSTATICOGG::get_voice() { + if (!is_playing()) { + return -1; + } + AUDIOSTREAM *ast = alogg_get_audiostream_ogg(tune); + if (ast) + return ast->voice; + return -1; } int MYSTATICOGG::get_sound_type() { - return MUS_OGG; + return MUS_OGG; } -int MYSTATICOGG::play_from(int position) -{ - if (tune == nullptr) { return 0; } +int MYSTATICOGG::play_from(int position) { + if (tune == nullptr) { + return 0; + } - if (use_extra_sound_offset) - extraOffset = ((16384 / (alogg_get_wave_is_stereo_ogg(tune) ? 2 : 1)) * 1000) / alogg_get_wave_freq_ogg(tune); - else - extraOffset = 0; + if (use_extra_sound_offset) + extraOffset = ((16384 / (alogg_get_wave_is_stereo_ogg(tune) ? 2 : 1)) * 1000) / alogg_get_wave_freq_ogg(tune); + else + extraOffset = 0; - if (alogg_play_ex_ogg(tune, 16384, vol, panning, 1000, repeat) != ALOGG_OK) { - return 0; - } + if (alogg_play_ex_ogg(tune, 16384, vol, panning, 1000, repeat) != ALOGG_OK) { + return 0; + } - last_ms_offs = position; - last_but_one = position; - last_but_one_but_one = position; + last_ms_offs = position; + last_but_one = position; + last_but_one_but_one = position; - if (position > 0) - alogg_seek_abs_msecs_ogg(tune, position); + if (position > 0) + alogg_seek_abs_msecs_ogg(tune, position); - state_ = SoundClipPlaying; + state_ = SoundClipPlaying; - if (!psp_audio_multithreaded) - poll(); + if (!psp_audio_multithreaded) + poll(); - return 1; + return 1; } int MYSTATICOGG::play() { - return play_from(0); + return play_from(0); } MYSTATICOGG::MYSTATICOGG() : SOUNDCLIP() { - tune = nullptr; - mp3buffer = nullptr; - mp3buffersize = 0; - extraOffset = 0; - last_but_one = 0; - last_ms_offs = 0; - last_but_one_but_one = 0; + tune = nullptr; + mp3buffer = nullptr; + mp3buffersize = 0; + extraOffset = 0; + last_but_one = 0; + last_ms_offs = 0; + last_but_one_but_one = 0; } diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h index e40bc2b792f5..18972ce79ba2 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -27,45 +27,44 @@ #include "media/audio/soundclip.h" // pre-loaded (non-streaming) OGG file -struct MYSTATICOGG:public SOUNDCLIP -{ - ALOGG_OGG *tune; - char *mp3buffer; - int mp3buffersize; - int extraOffset; +struct MYSTATICOGG: public SOUNDCLIP { + ALOGG_OGG *tune; + char *mp3buffer; + int mp3buffersize; + int extraOffset; - int last_but_one_but_one; - int last_but_one; - int last_ms_offs; + int last_but_one_but_one; + int last_but_one; + int last_ms_offs; - void poll() override; + void poll() override; - void set_volume(int newvol) override; - void set_speed(int new_speed) override; + void set_volume(int newvol) override; + void set_speed(int new_speed) override; - void destroy() override; + void destroy() override; - void seek(int pos) override; + void seek(int pos) override; - int get_pos() override; + int get_pos() override; - int get_pos_ms() override; + int get_pos_ms() override; - int get_length_ms() override; + int get_length_ms() override; - int get_sound_type() override; + int get_sound_type() override; - int play_from(int position) override; + int play_from(int position) override; - int play() override; + int play() override; - MYSTATICOGG(); + MYSTATICOGG(); protected: - int get_voice() override; - void adjust_volume() override; + int get_voice() override; + void adjust_volume() override; private: - void adjust_stream(); + void adjust_stream(); }; #endif diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp index d298f174bed7..34ab83cc04f8 100644 --- a/engines/ags/engine/media/audio/clip_mywave.cpp +++ b/engines/ags/engine/media/audio/clip_mywave.cpp @@ -29,96 +29,102 @@ #include "platform/base/agsplatformdriver.h" -void MYWAVE::poll() -{ - if (state_ != SoundClipPlaying) { return; } - - if (voice_get_position(voice) < 0) - { - state_ = SoundClipStopped; - } +void MYWAVE::poll() { + if (state_ != SoundClipPlaying) { + return; + } + + if (voice_get_position(voice) < 0) { + state_ = SoundClipStopped; + } } -void MYWAVE::adjust_volume() -{ - if (!is_playing()) { return; } - if (voice < 0) { return; } - voice_set_volume(voice, get_final_volume()); +void MYWAVE::adjust_volume() { + if (!is_playing()) { + return; + } + if (voice < 0) { + return; + } + voice_set_volume(voice, get_final_volume()); } -void MYWAVE::set_volume(int newvol) -{ - vol = newvol; - adjust_volume(); +void MYWAVE::set_volume(int newvol) { + vol = newvol; + adjust_volume(); } -void MYWAVE::destroy() -{ - // Stop sound and decrease reference count. - if (wave) { - stop_sample(wave); - sound_cache_free((char*)wave, true); - } - wave = nullptr; +void MYWAVE::destroy() { + // Stop sound and decrease reference count. + if (wave) { + stop_sample(wave); + sound_cache_free((char *)wave, true); + } + wave = nullptr; - state_ = SoundClipStopped; + state_ = SoundClipStopped; } -void MYWAVE::seek(int pos) -{ - if (!is_playing()) { return; } - voice_set_position(voice, pos); +void MYWAVE::seek(int pos) { + if (!is_playing()) { + return; + } + voice_set_position(voice, pos); } -int MYWAVE::get_pos() -{ - if (!is_playing()) { return -1; } - return voice_get_position(voice); +int MYWAVE::get_pos() { + if (!is_playing()) { + return -1; + } + return voice_get_position(voice); } -int MYWAVE::get_pos_ms() -{ - // convert the offset in samples into the offset in ms - //return ((1000000 / voice_get_frequency(voice)) * voice_get_position(voice)) / 1000; +int MYWAVE::get_pos_ms() { + // convert the offset in samples into the offset in ms + //return ((1000000 / voice_get_frequency(voice)) * voice_get_position(voice)) / 1000; - if (voice_get_frequency(voice) < 100) - return 0; - // (number of samples / (samples per second / 100)) * 10 = ms - return (voice_get_position(voice) / (voice_get_frequency(voice) / 100)) * 10; + if (voice_get_frequency(voice) < 100) + return 0; + // (number of samples / (samples per second / 100)) * 10 = ms + return (voice_get_position(voice) / (voice_get_frequency(voice) / 100)) * 10; } -int MYWAVE::get_length_ms() -{ - if (wave == nullptr) { return -1; } - if (wave->freq < 100) - return 0; - return (wave->len / (wave->freq / 100)) * 10; +int MYWAVE::get_length_ms() { + if (wave == nullptr) { + return -1; + } + if (wave->freq < 100) + return 0; + return (wave->len / (wave->freq / 100)) * 10; } -int MYWAVE::get_voice() -{ - if (!is_playing()) { return -1; } - return voice; +int MYWAVE::get_voice() { + if (!is_playing()) { + return -1; + } + return voice; } int MYWAVE::get_sound_type() { - return MUS_WAVE; + return MUS_WAVE; } int MYWAVE::play() { - if (wave == nullptr) { return 0; } + if (wave == nullptr) { + return 0; + } - voice = play_sample(wave, vol, panning, 1000, repeat); - if (voice < 0) { - return 0; - } + voice = play_sample(wave, vol, panning, 1000, repeat); + if (voice < 0) { + return 0; + } - state_ = SoundClipPlaying; + state_ = SoundClipPlaying; - return 1; + return 1; } MYWAVE::MYWAVE() : SOUNDCLIP() { - wave = nullptr; - voice = -1; + wave = nullptr; + voice = -1; } diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h index d80947bf5371..4c479b4cffb3 100644 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -26,33 +26,32 @@ #include "media/audio/soundclip.h" // My new MP3STREAM wrapper -struct MYWAVE:public SOUNDCLIP -{ - SAMPLE *wave; - int voice; +struct MYWAVE: public SOUNDCLIP { + SAMPLE *wave; + int voice; - void poll() override; + void poll() override; - void set_volume(int new_speed) override; + void set_volume(int new_speed) override; - void destroy() override; + void destroy() override; - void seek(int pos) override; + void seek(int pos) override; - int get_pos() override; - int get_pos_ms() override; + int get_pos() override; + int get_pos_ms() override; - int get_length_ms() override; + int get_length_ms() override; - int get_sound_type() override; + int get_sound_type() override; - int play() override; + int play() override; - MYWAVE(); + MYWAVE(); protected: - int get_voice() override; - void adjust_volume() override; + int get_voice() override; + void adjust_volume() override; }; #endif diff --git a/engines/ags/engine/media/audio/queuedaudioitem.cpp b/engines/ags/engine/media/audio/queuedaudioitem.cpp index c8fe331ef147..d2b93302406b 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.cpp +++ b/engines/ags/engine/media/audio/queuedaudioitem.cpp @@ -29,18 +29,16 @@ using AGS::Common::Stream; // [IKM] 2012-07-02: these functions are used during load/save game, // and read/written as-is, hence cachedClip pointer should be serialized // simply like pointer (although that probably does not mean much sense?) -void QueuedAudioItem::ReadFromFile(Stream *in) -{ - audioClipIndex = in->ReadInt16(); - priority = in->ReadInt16(); - repeat = in->ReadBool(); - in->ReadInt32(); // cachedClip +void QueuedAudioItem::ReadFromFile(Stream *in) { + audioClipIndex = in->ReadInt16(); + priority = in->ReadInt16(); + repeat = in->ReadBool(); + in->ReadInt32(); // cachedClip } -void QueuedAudioItem::WriteToFile(Stream *out) const -{ - out->WriteInt16(audioClipIndex); - out->WriteInt16(priority); - out->WriteBool(repeat); - out->WriteInt32(0); // cachedClip +void QueuedAudioItem::WriteToFile(Stream *out) const { + out->WriteInt16(audioClipIndex); + out->WriteInt16(priority); + out->WriteBool(repeat); + out->WriteInt32(0); // cachedClip } diff --git a/engines/ags/engine/media/audio/queuedaudioitem.h b/engines/ags/engine/media/audio/queuedaudioitem.h index 7b548da50b55..f73fd0de1439 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.h +++ b/engines/ags/engine/media/audio/queuedaudioitem.h @@ -25,17 +25,21 @@ struct SOUNDCLIP; -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later struct QueuedAudioItem { - short audioClipIndex; - short priority; - bool repeat; - SOUNDCLIP *cachedClip; + short audioClipIndex; + short priority; + bool repeat; + SOUNDCLIP *cachedClip; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out) const; + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out) const; }; #endif diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index 43f398a7d2b3..557c066c931a 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -62,7 +62,7 @@ extern "C" { // Load MIDI from PACKFILE stream -MIDI *load_midi_pf(PACKFILE *pf); + MIDI *load_midi_pf(PACKFILE *pf); } @@ -71,21 +71,20 @@ int use_extra_sound_offset = 0; MYWAVE *thiswave; -SOUNDCLIP *my_load_wave(const AssetPath &asset_name, int voll, int loop) -{ - // Load via soundcache. - size_t dummy; - SAMPLE *new_sample = (SAMPLE*)get_cached_sound(asset_name, true, dummy); +SOUNDCLIP *my_load_wave(const AssetPath &asset_name, int voll, int loop) { + // Load via soundcache. + size_t dummy; + SAMPLE *new_sample = (SAMPLE *)get_cached_sound(asset_name, true, dummy); - if (new_sample == nullptr) - return nullptr; + if (new_sample == nullptr) + return nullptr; - thiswave = new MYWAVE(); - thiswave->wave = new_sample; - thiswave->vol = voll; - thiswave->repeat = (loop != 0); + thiswave = new MYWAVE(); + thiswave->wave = new_sample; + thiswave->vol = voll; + thiswave->repeat = (loop != 0); - return thiswave; + return thiswave; } PACKFILE *mp3in; @@ -93,93 +92,89 @@ PACKFILE *mp3in; #ifndef NO_MP3_PLAYER MYMP3 *thistune; -SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) -{ - size_t asset_size; - mp3in = PackfileFromAsset(asset_name, asset_size); - if (mp3in == nullptr) - return nullptr; - - char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); - if (tmpbuffer == nullptr) { - pack_fclose(mp3in); - return nullptr; - } - thistune = new MYMP3(); - thistune->in = mp3in; - thistune->chunksize = MP3CHUNKSIZE; - thistune->filesize = asset_size; - thistune->vol = voll; - - if (thistune->chunksize > thistune->filesize) - thistune->chunksize = thistune->filesize; - - pack_fread(tmpbuffer, thistune->chunksize, mp3in); - - thistune->buffer = (char *)tmpbuffer; - - { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - thistune->stream = almp3_create_mp3stream(tmpbuffer, thistune->chunksize, (thistune->filesize < 1)); - } - - if (thistune->stream == nullptr) { - free(tmpbuffer); - pack_fclose(mp3in); - delete thistune; - return nullptr; - } - - return thistune; +SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) { + size_t asset_size; + mp3in = PackfileFromAsset(asset_name, asset_size); + if (mp3in == nullptr) + return nullptr; + + char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); + if (tmpbuffer == nullptr) { + pack_fclose(mp3in); + return nullptr; + } + thistune = new MYMP3(); + thistune->in = mp3in; + thistune->chunksize = MP3CHUNKSIZE; + thistune->filesize = asset_size; + thistune->vol = voll; + + if (thistune->chunksize > thistune->filesize) + thistune->chunksize = thistune->filesize; + + pack_fread(tmpbuffer, thistune->chunksize, mp3in); + + thistune->buffer = (char *)tmpbuffer; + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + thistune->stream = almp3_create_mp3stream(tmpbuffer, thistune->chunksize, (thistune->filesize < 1)); + } + + if (thistune->stream == nullptr) { + free(tmpbuffer); + pack_fclose(mp3in); + delete thistune; + return nullptr; + } + + return thistune; } MYSTATICMP3 *thismp3; -SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) -{ - // Load via soundcache. - size_t muslen = 0; - char* mp3buffer = get_cached_sound(asset_name, false, muslen); - if (mp3buffer == nullptr) - return nullptr; - - // now, create an MP3 structure for it - thismp3 = new MYSTATICMP3(); - if (thismp3 == nullptr) { - free(mp3buffer); - return nullptr; - } - thismp3->vol = voll; - thismp3->mp3buffer = nullptr; - thismp3->repeat = loop; - - { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); - thismp3->tune = almp3_create_mp3(mp3buffer, muslen); - } - - if (thismp3->tune == nullptr) { - free(mp3buffer); - delete thismp3; - return nullptr; - } - - thismp3->mp3buffer = mp3buffer; - - return thismp3; +SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) { + // Load via soundcache. + size_t muslen = 0; + char *mp3buffer = get_cached_sound(asset_name, false, muslen); + if (mp3buffer == nullptr) + return nullptr; + + // now, create an MP3 structure for it + thismp3 = new MYSTATICMP3(); + if (thismp3 == nullptr) { + free(mp3buffer); + return nullptr; + } + thismp3->vol = voll; + thismp3->mp3buffer = nullptr; + thismp3->repeat = loop; + + { + AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + thismp3->tune = almp3_create_mp3(mp3buffer, muslen); + } + + if (thismp3->tune == nullptr) { + free(mp3buffer); + delete thismp3; + return nullptr; + } + + thismp3->mp3buffer = mp3buffer; + + return thismp3; } #else // NO_MP3_PLAYER -SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) -{ - return NULL; +SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) { + return NULL; } -SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) -{ - return NULL; +SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) { + return NULL; } #endif // NO_MP3_PLAYER @@ -187,180 +182,171 @@ SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) MYSTATICOGG *thissogg; -SOUNDCLIP *my_load_static_ogg(const AssetPath &asset_name, int voll, bool loop) -{ - // Load via soundcache. - size_t muslen = 0; - char* mp3buffer = get_cached_sound(asset_name, false, muslen); - if (mp3buffer == nullptr) - return nullptr; - - // now, create an OGG structure for it - thissogg = new MYSTATICOGG(); - thissogg->vol = voll; - thissogg->repeat = loop; - thissogg->mp3buffer = mp3buffer; - thissogg->mp3buffersize = muslen; - - thissogg->tune = alogg_create_ogg_from_buffer(mp3buffer, muslen); - - if (thissogg->tune == nullptr) { - thissogg->destroy(); - delete thissogg; - return nullptr; - } - - return thissogg; +SOUNDCLIP *my_load_static_ogg(const AssetPath &asset_name, int voll, bool loop) { + // Load via soundcache. + size_t muslen = 0; + char *mp3buffer = get_cached_sound(asset_name, false, muslen); + if (mp3buffer == nullptr) + return nullptr; + + // now, create an OGG structure for it + thissogg = new MYSTATICOGG(); + thissogg->vol = voll; + thissogg->repeat = loop; + thissogg->mp3buffer = mp3buffer; + thissogg->mp3buffersize = muslen; + + thissogg->tune = alogg_create_ogg_from_buffer(mp3buffer, muslen); + + if (thissogg->tune == nullptr) { + thissogg->destroy(); + delete thissogg; + return nullptr; + } + + return thissogg; } MYOGG *thisogg; -SOUNDCLIP *my_load_ogg(const AssetPath &asset_name, int voll) -{ - size_t asset_size; - mp3in = PackfileFromAsset(asset_name, asset_size); - if (mp3in == nullptr) - return nullptr; - - char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); - if (tmpbuffer == nullptr) { - pack_fclose(mp3in); - return nullptr; - } - - thisogg = new MYOGG(); - thisogg->in = mp3in; - thisogg->vol = voll; - thisogg->chunksize = MP3CHUNKSIZE; - thisogg->last_but_one = 0; - thisogg->last_ms_offs = 0; - thisogg->last_but_one_but_one = 0; - - if (thisogg->chunksize > asset_size) - thisogg->chunksize = asset_size; - - pack_fread(tmpbuffer, thisogg->chunksize, mp3in); - - thisogg->buffer = (char *)tmpbuffer; - thisogg->stream = alogg_create_oggstream(tmpbuffer, thisogg->chunksize, (asset_size < 1)); - - if (thisogg->stream == nullptr) { - free(tmpbuffer); - pack_fclose(mp3in); - delete thisogg; - return nullptr; - } - - return thisogg; +SOUNDCLIP *my_load_ogg(const AssetPath &asset_name, int voll) { + size_t asset_size; + mp3in = PackfileFromAsset(asset_name, asset_size); + if (mp3in == nullptr) + return nullptr; + + char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); + if (tmpbuffer == nullptr) { + pack_fclose(mp3in); + return nullptr; + } + + thisogg = new MYOGG(); + thisogg->in = mp3in; + thisogg->vol = voll; + thisogg->chunksize = MP3CHUNKSIZE; + thisogg->last_but_one = 0; + thisogg->last_ms_offs = 0; + thisogg->last_but_one_but_one = 0; + + if (thisogg->chunksize > asset_size) + thisogg->chunksize = asset_size; + + pack_fread(tmpbuffer, thisogg->chunksize, mp3in); + + thisogg->buffer = (char *)tmpbuffer; + thisogg->stream = alogg_create_oggstream(tmpbuffer, thisogg->chunksize, (asset_size < 1)); + + if (thisogg->stream == nullptr) { + free(tmpbuffer); + pack_fclose(mp3in); + delete thisogg; + return nullptr; + } + + return thisogg; } MYMIDI *thismidi; -SOUNDCLIP *my_load_midi(const AssetPath &asset_name, int repet) -{ - // The first a midi is played, preload all patches. - if (!thismidi && psp_midi_preload_patches) - load_midi_patches(); +SOUNDCLIP *my_load_midi(const AssetPath &asset_name, int repet) { + // The first a midi is played, preload all patches. + if (!thismidi && psp_midi_preload_patches) + load_midi_patches(); - size_t asset_size; - PACKFILE *pf = PackfileFromAsset(asset_name, asset_size); - if (!pf) - return nullptr; + size_t asset_size; + PACKFILE *pf = PackfileFromAsset(asset_name, asset_size); + if (!pf) + return nullptr; - MIDI* midiPtr = load_midi_pf(pf); - pack_fclose(pf); + MIDI *midiPtr = load_midi_pf(pf); + pack_fclose(pf); - if (midiPtr == nullptr) - return nullptr; + if (midiPtr == nullptr) + return nullptr; - thismidi = new MYMIDI(); - thismidi->tune = midiPtr; - thismidi->repeat = (repet != 0); + thismidi = new MYMIDI(); + thismidi->tune = midiPtr; + thismidi->repeat = (repet != 0); - return thismidi; + return thismidi; } #ifdef JGMOD_MOD_PLAYER MYMOD *thismod = NULL; -SOUNDCLIP *my_load_mod(const char *filname, int repet) -{ +SOUNDCLIP *my_load_mod(const char *filname, int repet) { - JGMOD *modPtr = load_mod((char *)filname); - if (modPtr == NULL) - return NULL; + JGMOD *modPtr = load_mod((char *)filname); + if (modPtr == NULL) + return NULL; - thismod = new MYMOD(); - thismod->tune = modPtr; - thismod->repeat = (repet != 0); + thismod = new MYMOD(); + thismod->tune = modPtr; + thismod->repeat = (repet != 0); - return thismod; + return thismod; } int init_mod_player(int numVoices) { - return install_mod(numVoices); + return install_mod(numVoices); } void remove_mod_player() { - remove_mod(); + remove_mod(); } //#endif // JGMOD_MOD_PLAYER #elif defined DUMB_MOD_PLAYER MYMOD *thismod = nullptr; -SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet) -{ - size_t asset_size; - DUMBFILE *df = DUMBfileFromAsset(asset_name, asset_size); - if (!df) - return nullptr; - - DUH *modPtr = nullptr; - // determine the file extension - const char *lastDot = strrchr(asset_name.second, '.'); - if (lastDot == nullptr) - { - dumbfile_close(df); - return nullptr; - } - // get the first char of the extensin - int charAfterDot = toupper(lastDot[1]); - - // use the appropriate loader - if (charAfterDot == 'I') { - modPtr = dumb_read_it(df); - } - else if (charAfterDot == 'X') { - modPtr = dumb_read_xm(df); - } - else if (charAfterDot == 'S') { - modPtr = dumb_read_s3m(df); - } - else if (charAfterDot == 'M') { - modPtr = dumb_read_mod(df); - } - - dumbfile_close(df); - if (modPtr == nullptr) - return nullptr; - - thismod = new MYMOD(); - thismod->tune = modPtr; - thismod->vol = 255; - thismod->repeat = (repet != 0); - - return thismod; +SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet) { + size_t asset_size; + DUMBFILE *df = DUMBfileFromAsset(asset_name, asset_size); + if (!df) + return nullptr; + + DUH *modPtr = nullptr; + // determine the file extension + const char *lastDot = strrchr(asset_name.second, '.'); + if (lastDot == nullptr) { + dumbfile_close(df); + return nullptr; + } + // get the first char of the extensin + int charAfterDot = toupper(lastDot[1]); + + // use the appropriate loader + if (charAfterDot == 'I') { + modPtr = dumb_read_it(df); + } else if (charAfterDot == 'X') { + modPtr = dumb_read_xm(df); + } else if (charAfterDot == 'S') { + modPtr = dumb_read_s3m(df); + } else if (charAfterDot == 'M') { + modPtr = dumb_read_mod(df); + } + + dumbfile_close(df); + if (modPtr == nullptr) + return nullptr; + + thismod = new MYMOD(); + thismod->tune = modPtr; + thismod->vol = 255; + thismod->repeat = (repet != 0); + + return thismod; } int init_mod_player(int numVoices) { - dumb_register_packfiles(); - return 0; + dumb_register_packfiles(); + return 0; } void remove_mod_player() { - dumb_exit(); + dumb_exit(); } #endif // DUMB_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index e32526604726..fed227a0ffde 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -33,210 +33,180 @@ using namespace Common; -sound_cache_entry_t* sound_cache_entries = nullptr; +sound_cache_entry_t *sound_cache_entries = nullptr; unsigned int sound_cache_counter = 0; AGS::Engine::Mutex _sound_cache_mutex; -void clear_sound_cache() -{ - AGS::Engine::MutexLock _lock(_sound_cache_mutex); - - if (sound_cache_entries) - { - int i; - for (i = 0; i < psp_audio_cachesize; i++) - { - if (sound_cache_entries[i].data) - { - free(sound_cache_entries[i].data); - sound_cache_entries[i].data = nullptr; - free(sound_cache_entries[i].file_name); - sound_cache_entries[i].file_name = nullptr; - sound_cache_entries[i].reference = 0; - } - } - } - else - { - sound_cache_entries = (sound_cache_entry_t*)malloc(psp_audio_cachesize * sizeof(sound_cache_entry_t)); - memset(sound_cache_entries, 0, psp_audio_cachesize * sizeof(sound_cache_entry_t)); - } +void clear_sound_cache() { + AGS::Engine::MutexLock _lock(_sound_cache_mutex); + + if (sound_cache_entries) { + int i; + for (i = 0; i < psp_audio_cachesize; i++) { + if (sound_cache_entries[i].data) { + free(sound_cache_entries[i].data); + sound_cache_entries[i].data = nullptr; + free(sound_cache_entries[i].file_name); + sound_cache_entries[i].file_name = nullptr; + sound_cache_entries[i].reference = 0; + } + } + } else { + sound_cache_entries = (sound_cache_entry_t *)malloc(psp_audio_cachesize * sizeof(sound_cache_entry_t)); + memset(sound_cache_entries, 0, psp_audio_cachesize * sizeof(sound_cache_entry_t)); + } } -void sound_cache_free(char* buffer, bool is_wave) -{ - AGS::Engine::MutexLock _lock(_sound_cache_mutex); +void sound_cache_free(char *buffer, bool is_wave) { + AGS::Engine::MutexLock _lock(_sound_cache_mutex); #ifdef SOUND_CACHE_DEBUG - Debug::Printf("sound_cache_free(%p %d)\n", buffer, (unsigned int)is_wave); + Debug::Printf("sound_cache_free(%p %d)\n", buffer, (unsigned int)is_wave); #endif - int i; - for (i = 0; i < psp_audio_cachesize; i++) - { - if (sound_cache_entries[i].data == buffer) - { - if (sound_cache_entries[i].reference > 0) - sound_cache_entries[i].reference--; + int i; + for (i = 0; i < psp_audio_cachesize; i++) { + if (sound_cache_entries[i].data == buffer) { + if (sound_cache_entries[i].reference > 0) + sound_cache_entries[i].reference--; #ifdef SOUND_CACHE_DEBUG - Debug::Printf("..decreased reference count of slot %d to %d\n", i, sound_cache_entries[i].reference); + Debug::Printf("..decreased reference count of slot %d to %d\n", i, sound_cache_entries[i].reference); #endif - return; - } - } + return; + } + } #ifdef SOUND_CACHE_DEBUG - Debug::Printf("..freeing uncached sound\n"); + Debug::Printf("..freeing uncached sound\n"); #endif - // Sound is uncached - if (i == psp_audio_cachesize) - { - if (is_wave) - destroy_sample((SAMPLE*)buffer); - else - free(buffer); - } + // Sound is uncached + if (i == psp_audio_cachesize) { + if (is_wave) + destroy_sample((SAMPLE *)buffer); + else + free(buffer); + } } -char* get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) -{ +char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) { AGS::Engine::MutexLock _lock(_sound_cache_mutex); #ifdef SOUND_CACHE_DEBUG - Debug::Printf("get_cached_sound(%s %d)\n", asset_name.first.GetCStr(), (unsigned int)is_wave); + Debug::Printf("get_cached_sound(%s %d)\n", asset_name.first.GetCStr(), (unsigned int)is_wave); #endif - size = 0; + size = 0; - int i; - for (i = 0; i < psp_audio_cachesize; i++) - { - if (sound_cache_entries[i].data == nullptr) - continue; + int i; + for (i = 0; i < psp_audio_cachesize; i++) { + if (sound_cache_entries[i].data == nullptr) + continue; - if (strcmp(asset_name.second, sound_cache_entries[i].file_name) == 0) - { + if (strcmp(asset_name.second, sound_cache_entries[i].file_name) == 0) { #ifdef SOUND_CACHE_DEBUG - Debug::Printf("..found in slot %d\n", i); + Debug::Printf("..found in slot %d\n", i); #endif - sound_cache_entries[i].reference++; - sound_cache_entries[i].last_used = sound_cache_counter++; - size = sound_cache_entries[i].size; - - return sound_cache_entries[i].data; - } - } - - // Not found - PACKFILE *mp3in = nullptr; - SAMPLE* wave = nullptr; - - if (is_wave) - { - PACKFILE *wavin = PackfileFromAsset(asset_name, size); - if (wavin != nullptr) - { - wave = load_wav_pf(wavin); - pack_fclose(wavin); - } - } - else - { - mp3in = PackfileFromAsset(asset_name, size); - if (mp3in == nullptr) - { - return nullptr; - } - } - - // Find free slot - for (i = 0; i < psp_audio_cachesize; i++) - { - if (sound_cache_entries[i].data == nullptr) - break; - } - - // No free slot? - if (i == psp_audio_cachesize) - { - unsigned int oldest = sound_cache_counter; - int index = -1; - - for (i = 0; i < psp_audio_cachesize; i++) - { - if (sound_cache_entries[i].reference == 0) - { - if (sound_cache_entries[i].last_used < oldest) - { - oldest = sound_cache_entries[i].last_used; - index = i; - } - } - } - - i = index; - } - - // Load new file - char* newdata; - - if (is_wave) - { - size = 0; // ??? CHECKME - newdata = (char*)wave; - } - else - { - newdata = (char *)malloc(size); - - if (newdata == nullptr) - { - pack_fclose(mp3in); - return nullptr; - } - - pack_fread(newdata, size, mp3in); - pack_fclose(mp3in); - } - - if (i == -1) - { - // No cache slot empty, return uncached data + sound_cache_entries[i].reference++; + sound_cache_entries[i].last_used = sound_cache_counter++; + size = sound_cache_entries[i].size; + + return sound_cache_entries[i].data; + } + } + + // Not found + PACKFILE *mp3in = nullptr; + SAMPLE *wave = nullptr; + + if (is_wave) { + PACKFILE *wavin = PackfileFromAsset(asset_name, size); + if (wavin != nullptr) { + wave = load_wav_pf(wavin); + pack_fclose(wavin); + } + } else { + mp3in = PackfileFromAsset(asset_name, size); + if (mp3in == nullptr) { + return nullptr; + } + } + + // Find free slot + for (i = 0; i < psp_audio_cachesize; i++) { + if (sound_cache_entries[i].data == nullptr) + break; + } + + // No free slot? + if (i == psp_audio_cachesize) { + unsigned int oldest = sound_cache_counter; + int index = -1; + + for (i = 0; i < psp_audio_cachesize; i++) { + if (sound_cache_entries[i].reference == 0) { + if (sound_cache_entries[i].last_used < oldest) { + oldest = sound_cache_entries[i].last_used; + index = i; + } + } + } + + i = index; + } + + // Load new file + char *newdata; + + if (is_wave) { + size = 0; // ??? CHECKME + newdata = (char *)wave; + } else { + newdata = (char *)malloc(size); + + if (newdata == nullptr) { + pack_fclose(mp3in); + return nullptr; + } + + pack_fread(newdata, size, mp3in); + pack_fclose(mp3in); + } + + if (i == -1) { + // No cache slot empty, return uncached data #ifdef SOUND_CACHE_DEBUG - Debug::Printf("..loading uncached\n"); + Debug::Printf("..loading uncached\n"); #endif - return newdata; - } - else - { - // Add to cache, free old sound first + return newdata; + } else { + // Add to cache, free old sound first #ifdef SOUND_CACHE_DEBUG - Debug::Printf("..loading cached in slot %d\n", i); -#endif - - if (sound_cache_entries[i].data) { - if (sound_cache_entries[i].is_wave) - destroy_sample((SAMPLE*)sound_cache_entries[i].data); - else - free(sound_cache_entries[i].data); + Debug::Printf("..loading cached in slot %d\n", i); +#endif + + if (sound_cache_entries[i].data) { + if (sound_cache_entries[i].is_wave) + destroy_sample((SAMPLE *)sound_cache_entries[i].data); + else + free(sound_cache_entries[i].data); + } + + sound_cache_entries[i].size = size; + sound_cache_entries[i].data = newdata; + + if (sound_cache_entries[i].file_name) + free(sound_cache_entries[i].file_name); + sound_cache_entries[i].file_name = (char *)malloc(strlen(asset_name.second) + 1); + strcpy(sound_cache_entries[i].file_name, asset_name.second); + sound_cache_entries[i].reference = 1; + sound_cache_entries[i].last_used = sound_cache_counter++; + sound_cache_entries[i].is_wave = is_wave; + + return sound_cache_entries[i].data; } - - sound_cache_entries[i].size = size; - sound_cache_entries[i].data = newdata; - - if (sound_cache_entries[i].file_name) - free(sound_cache_entries[i].file_name); - sound_cache_entries[i].file_name = (char*)malloc(strlen(asset_name.second) + 1); - strcpy(sound_cache_entries[i].file_name, asset_name.second); - sound_cache_entries[i].reference = 1; - sound_cache_entries[i].last_used = sound_cache_counter++; - sound_cache_entries[i].is_wave = is_wave; - - return sound_cache_entries[i].data; - } } diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h index 1943462cc2b2..09e88138a691 100644 --- a/engines/ags/engine/media/audio/soundcache.h +++ b/engines/ags/engine/media/audio/soundcache.h @@ -31,16 +31,15 @@ //#define SOUND_CACHE_DEBUG -typedef struct -{ - char* file_name; - int number; - int free; - unsigned int last_used; - unsigned int size; - char* data; - int reference; - bool is_wave; +typedef struct { + char *file_name; + int number; + int free; + unsigned int last_used; + unsigned int size; + char *data; + int reference; + bool is_wave; } sound_cache_entry_t; extern int psp_use_sound_cache; @@ -49,8 +48,8 @@ extern int psp_audio_cachesize; extern int psp_midi_preload_patches; void clear_sound_cache(); -void sound_cache_free(char* buffer, bool is_wave); -char* get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size); +void sound_cache_free(char *buffer, bool is_wave); +char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size); #endif diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index 86ae041863f8..28298057d4ac 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -26,63 +26,67 @@ #include "media/audio/soundclip.h" #include "media/audio/audiointernaldefs.h" -int SOUNDCLIP::play_from(int position) -{ - int retVal = play(); - if ((retVal != 0) && (position > 0)) - { - seek(position); - } - return retVal; +int SOUNDCLIP::play_from(int position) { + int retVal = play(); + if ((retVal != 0) && (position > 0)) { + seek(position); + } + return retVal; } void SOUNDCLIP::set_panning(int newPanning) { - if (!is_playing()) { return; } - - int voice = get_voice(); - if (voice >= 0) { - voice_set_pan(voice, newPanning); - panning = newPanning; - } + if (!is_playing()) { + return; + } + + int voice = get_voice(); + if (voice >= 0) { + voice_set_pan(voice, newPanning); + panning = newPanning; + } } void SOUNDCLIP::pause() { - if (state_ != SoundClipPlaying) { return; } + if (state_ != SoundClipPlaying) { + return; + } - int voice = get_voice(); - if (voice >= 0) { - voice_stop(voice); - state_ = SoundClipPaused; - } + int voice = get_voice(); + if (voice >= 0) { + voice_stop(voice); + state_ = SoundClipPaused; + } } void SOUNDCLIP::resume() { - if (state_ != SoundClipPaused) { return; } + if (state_ != SoundClipPaused) { + return; + } - int voice = get_voice(); - if (voice >= 0) { - voice_start(voice); - state_ = SoundClipPlaying; - } + int voice = get_voice(); + if (voice >= 0) { + voice_start(voice); + state_ = SoundClipPlaying; + } } SOUNDCLIP::SOUNDCLIP() { - state_ = SoundClipInitial; - priority = 50; - panning = 128; - panningAsPercentage = 0; - speed = 1000; - sourceClipType = 0; - sourceClip = nullptr; - vol = 0; - volAsPercentage = 0; - volModifier = 0; - muted = false; - repeat = false; - xSource = -1; - ySource = -1; - maximumPossibleDistanceAway = 0; - directionalVolModifier = 0; + state_ = SoundClipInitial; + priority = 50; + panning = 128; + panningAsPercentage = 0; + speed = 1000; + sourceClipType = 0; + sourceClip = nullptr; + vol = 0; + volAsPercentage = 0; + volModifier = 0; + muted = false; + repeat = false; + xSource = -1; + ySource = -1; + maximumPossibleDistanceAway = 0; + directionalVolModifier = 0; } SOUNDCLIP::~SOUNDCLIP() = default; diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index e2f2300fda68..2158dbac22cb 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -42,139 +42,133 @@ extern volatile int psp_audio_multithreaded; enum SoundClipState { SoundClipInitial, SoundClipPlaying, SoundClipPaused, SoundClipStopped }; -struct SOUNDCLIP -{ - int priority; - int sourceClipType; - // absolute volume, set by implementations only! - int vol; - // current relative volume, in percents - int volAsPercentage; - // volModifier is used when there's a need to temporarily change and - // the restore the clip's absolute volume (vol) - int volModifier; - int panning; - int panningAsPercentage; - int xSource, ySource; - int maximumPossibleDistanceAway; - int directionalVolModifier; - bool repeat; - void *sourceClip; - - virtual void poll() = 0; - virtual void destroy() = 0; - // apply volume directly to playback; volume is given in units of 255 - // NOTE: this completely ignores volAsPercentage and muted property - virtual void set_volume(int) = 0; - virtual void seek(int) = 0; - virtual int get_pos() = 0; // return 0 to indicate seek not supported - virtual int get_pos_ms() = 0; // this must always return valid value if poss - virtual int get_length_ms() = 0; // return total track length in ms (or 0) - virtual int get_sound_type() = 0; - virtual int play() = 0; - - virtual int play_from(int position); - - virtual void set_panning(int newPanning); - virtual void set_speed(int new_speed) { speed = new_speed; } - - virtual void pause(); - virtual void resume(); - - inline bool is_playing() const { return state_ == SoundClipPlaying || state_ == SoundClipPaused; } - - inline int get_speed() const - { - return speed; - } - - // Gets clip's volume property, as percentage (0 - 100); - // note this may not be the real volume of playback (which could e.g. be muted) - inline int get_volume() const - { - return volAsPercentage; - } - - inline bool is_muted() const - { - return muted; - } - - // Sets the current volume property, as percentage (0 - 100). - inline void set_volume_percent(int volume) - { - volAsPercentage = volume; - if (!muted) - set_volume((volume * 255) / 100); - } - - // Explicitly defines both percentage and absolute volume value, - // without calculating it from given percentage. - // NOTE: this overrides the mute - inline void set_volume_direct(int vol_percent, int vol_absolute) - { - muted = false; - volAsPercentage = vol_percent; - set_volume(vol_absolute); - } - - // Mutes sound clip, while preserving current volume property - // for the future reference; when unmuted, that property is - // used to restart previous volume. - inline void set_mute(bool enable) - { - muted = enable; - if (enable) - set_volume(0); - else - set_volume((volAsPercentage * 255) / 100); - } - - // Apply arbitrary permanent volume modifier, in absolute units (0 - 255); - // this is distinct value that is used in conjunction with current volume - // (can be both positive and negative). - inline void apply_volume_modifier(int mod) - { - volModifier = mod; - adjust_volume(); - } - - // Apply permanent directional volume modifier, in absolute units (0 - 255) - // this is distinct value that is used in conjunction with current volume - // (can be both positive and negative). - inline void apply_directional_modifier(int mod) - { - directionalVolModifier = mod; - adjust_volume(); - } - - virtual void adjust_volume() = 0; - - SOUNDCLIP(); - virtual ~SOUNDCLIP(); +struct SOUNDCLIP { + int priority; + int sourceClipType; + // absolute volume, set by implementations only! + int vol; + // current relative volume, in percents + int volAsPercentage; + // volModifier is used when there's a need to temporarily change and + // the restore the clip's absolute volume (vol) + int volModifier; + int panning; + int panningAsPercentage; + int xSource, ySource; + int maximumPossibleDistanceAway; + int directionalVolModifier; + bool repeat; + void *sourceClip; + + virtual void poll() = 0; + virtual void destroy() = 0; + // apply volume directly to playback; volume is given in units of 255 + // NOTE: this completely ignores volAsPercentage and muted property + virtual void set_volume(int) = 0; + virtual void seek(int) = 0; + virtual int get_pos() = 0; // return 0 to indicate seek not supported + virtual int get_pos_ms() = 0; // this must always return valid value if poss + virtual int get_length_ms() = 0; // return total track length in ms (or 0) + virtual int get_sound_type() = 0; + virtual int play() = 0; + + virtual int play_from(int position); + + virtual void set_panning(int newPanning); + virtual void set_speed(int new_speed) { + speed = new_speed; + } + + virtual void pause(); + virtual void resume(); + + inline bool is_playing() const { + return state_ == SoundClipPlaying || state_ == SoundClipPaused; + } + + inline int get_speed() const { + return speed; + } + + // Gets clip's volume property, as percentage (0 - 100); + // note this may not be the real volume of playback (which could e.g. be muted) + inline int get_volume() const { + return volAsPercentage; + } + + inline bool is_muted() const { + return muted; + } + + // Sets the current volume property, as percentage (0 - 100). + inline void set_volume_percent(int volume) { + volAsPercentage = volume; + if (!muted) + set_volume((volume * 255) / 100); + } + + // Explicitly defines both percentage and absolute volume value, + // without calculating it from given percentage. + // NOTE: this overrides the mute + inline void set_volume_direct(int vol_percent, int vol_absolute) { + muted = false; + volAsPercentage = vol_percent; + set_volume(vol_absolute); + } + + // Mutes sound clip, while preserving current volume property + // for the future reference; when unmuted, that property is + // used to restart previous volume. + inline void set_mute(bool enable) { + muted = enable; + if (enable) + set_volume(0); + else + set_volume((volAsPercentage * 255) / 100); + } + + // Apply arbitrary permanent volume modifier, in absolute units (0 - 255); + // this is distinct value that is used in conjunction with current volume + // (can be both positive and negative). + inline void apply_volume_modifier(int mod) { + volModifier = mod; + adjust_volume(); + } + + // Apply permanent directional volume modifier, in absolute units (0 - 255) + // this is distinct value that is used in conjunction with current volume + // (can be both positive and negative). + inline void apply_directional_modifier(int mod) { + directionalVolModifier = mod; + adjust_volume(); + } + + virtual void adjust_volume() = 0; + + SOUNDCLIP(); + virtual ~SOUNDCLIP(); protected: - SoundClipState state_; + SoundClipState state_; - // mute mode overrides the volume; if set, any volume assigned is stored - // in properties, but not applied to playback itself - bool muted; + // mute mode overrides the volume; if set, any volume assigned is stored + // in properties, but not applied to playback itself + bool muted; - // speed of playback, in clip ms per real second - int speed; + // speed of playback, in clip ms per real second + int speed; - // Return the allegro voice number (or -1 if none) - // Used by generic pause/resume functions. - virtual int get_voice() = 0; + // Return the allegro voice number (or -1 if none) + // Used by generic pause/resume functions. + virtual int get_voice() = 0; - // helper function for calculating volume with applied modifiers - inline int get_final_volume() const - { - int final_vol = vol + volModifier + directionalVolModifier; - return final_vol >= 0 ? final_vol : 0; - } + // helper function for calculating volume with applied modifiers + inline int get_final_volume() const { + int final_vol = vol + volModifier + directionalVolModifier; + return final_vol >= 0 ? final_vol : 0; + } }; #endif diff --git a/engines/ags/engine/media/video/VMR9Graph.h b/engines/ags/engine/media/video/VMR9Graph.h index 2b6b52011f4a..e850d6b741a5 100644 --- a/engines/ags/engine/media/video/VMR9Graph.h +++ b/engines/ags/engine/media/video/VMR9Graph.h @@ -41,10 +41,9 @@ //#pragma comment( lib, "d3d9.lib" ) //#pragma comment( lib, "d3dx9.lib" ) -#define WM_MEDIA_NOTIF (WM_APP + 777) +#define WM_MEDIA_NOTIF (WM_APP + 777) -class CVMR9Graph -{ +class CVMR9Graph { // Constructor / destructor public: CVMR9Graph(); @@ -56,19 +55,19 @@ class CVMR9Graph // Graph configuration void SetNumberOfLayer(int nNumberOfLayer); BOOL SetMediaWindow(HWND MediaWindow); - BOOL SetMediaFile(const char* pszFileName, bool withSound, int nLayer = 0); + BOOL SetMediaFile(const char *pszFileName, bool withSound, int nLayer = 0); BOOL PreserveAspectRatio(BOOL bPreserve = TRUE); - IBaseFilter* AddFilter(const char* pszName, const GUID& clsid); + IBaseFilter *AddFilter(const char *pszName, const GUID &clsid); // Graph control BOOL PlayGraph(); BOOL StopGraph(); BOOL ResetGraph(); - OAFilterState GetState(); - IMediaEvent* GetPtrMediaEvent(); - IMediaControl* GetPtrMediaControl(); - IMediaSeeking* GetPtrMediaSeeking(); - IBasicAudio* GetPtrBasicAudio(); + OAFilterState GetState(); + IMediaEvent *GetPtrMediaEvent(); + IMediaControl *GetPtrMediaControl(); + IMediaSeeking *GetPtrMediaSeeking(); + IBasicAudio *GetPtrBasicAudio(); // Layer control @@ -89,7 +88,7 @@ class CVMR9Graph // helper LPCTSTR GetLastError(); - // Internal + // Internal BOOL BuildAndRenderGraph(bool withSound); protected: @@ -114,47 +113,47 @@ class CVMR9Graph // DSOW helper methods HRESULT AddToRot(IUnknown *pUnkGraph); void RemoveFromRot(); - IPin* GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir); - void ReportError(const char* pszError, HRESULT hrCode); + IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir); + void ReportError(const char *pszError, HRESULT hrCode); HRESULT GetNextFilter(IBaseFilter *pFilter, PIN_DIRECTION Dir, IBaseFilter **ppNext); - BOOL RemoveFilterChain(IBaseFilter* pFilter, IBaseFilter* pStopFilter); - HRESULT AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, const GUID& clsid, IBaseFilter **ppF); + BOOL RemoveFilterChain(IBaseFilter *pFilter, IBaseFilter *pStopFilter); + HRESULT AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, const GUID &clsid, IBaseFilter **ppF); // Attributes public: - bool UseAVISound; + bool UseAVISound; protected: - DWORD m_dwRotId; - char m_pszErrorDescription[1024+MAX_ERROR_TEXT_LEN]; - int m_nNumberOfStream; - const char* m_pszFileName; - long m_oldWndProc; + DWORD m_dwRotId; + char m_pszErrorDescription[1024 + MAX_ERROR_TEXT_LEN]; + int m_nNumberOfStream; + const char *m_pszFileName; + long m_oldWndProc; // MEDIA WINDOW - HWND m_hMediaWindow; + HWND m_hMediaWindow; // SRC interfaces array - IBaseFilter* m_srcFilterArray[10]; + IBaseFilter *m_srcFilterArray[10]; // SOUND interfaces - IBaseFilter* m_pDirectSoundFilter; + IBaseFilter *m_pDirectSoundFilter; // GRAPH interfaces - IUnknown* m_pGraphUnknown; - IGraphBuilder* m_pGraphBuilder; - IFilterGraph* m_pFilterGraph; - IFilterGraph2* m_pFilterGraph2; - IMediaControl* m_pMediaControl; - IMediaSeeking* m_pMediaSeeking; - //IMediaEvent* m_pMediaEvent; - IMediaEventEx* m_pMediaEventEx; + IUnknown *m_pGraphUnknown; + IGraphBuilder *m_pGraphBuilder; + IFilterGraph *m_pFilterGraph; + IFilterGraph2 *m_pFilterGraph2; + IMediaControl *m_pMediaControl; + IMediaSeeking *m_pMediaSeeking; + //IMediaEvent* m_pMediaEvent; + IMediaEventEx *m_pMediaEventEx; // VMR9 interfaces - IBaseFilter* m_pVMRBaseFilter; - IVMRFilterConfig9* m_pVMRFilterConfig; - IVMRMixerBitmap9* m_pVMRMixerBitmap; - IVMRMixerControl9* m_pVMRMixerControl; - IVMRMonitorConfig9* m_pVMRMonitorConfig; - IVMRWindowlessControl9* m_pVMRWindowlessControl; + IBaseFilter *m_pVMRBaseFilter; + IVMRFilterConfig9 *m_pVMRFilterConfig; + IVMRMixerBitmap9 *m_pVMRMixerBitmap; + IVMRMixerControl9 *m_pVMRMixerControl; + IVMRMonitorConfig9 *m_pVMRMonitorConfig; + IVMRWindowlessControl9 *m_pVMRWindowlessControl; // DIRECT3D interfaces - //IDirect3DDevice9* m_pD3DDevice; - IDirect3DSurface9* m_pD3DSurface; + //IDirect3DDevice9* m_pD3DDevice; + IDirect3DSurface9 *m_pD3DSurface; }; #endif diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index 0ecf7e965f53..e1930078d6db 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -58,36 +58,34 @@ extern GameSetupStruct game; extern IGraphicsDriver *gfxDriver; extern int psp_video_framedrop; -enum VideoPlaybackType -{ - kVideoNone, - kVideoFlic, - kVideoTheora +enum VideoPlaybackType { + kVideoNone, + kVideoFlic, + kVideoTheora }; VideoPlaybackType video_type = kVideoNone; // FLIC player start Bitmap *fli_buffer = nullptr; -short fliwidth,fliheight; -int canabort=0, stretch_flc = 1; -Bitmap *hicol_buf=nullptr; +short fliwidth, fliheight; +int canabort = 0, stretch_flc = 1; +Bitmap *hicol_buf = nullptr; IDriverDependantBitmap *fli_ddb = nullptr; Bitmap *fli_target = nullptr; int fliTargetWidth, fliTargetHeight; -int check_if_user_input_should_cancel_video() -{ - int key, mbut, mwheelz; - if (run_service_key_controls(key)) { - if ((key==27) && (canabort==1)) - return 1; - if (canabort >= 2) - return 1; // skip on any key - } - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && canabort == 3) { - return 1; // skip on mouse click - } - return 0; +int check_if_user_input_should_cancel_video() { + int key, mbut, mwheelz; + if (run_service_key_controls(key)) { + if ((key == 27) && (canabort == 1)) + return 1; + if (canabort >= 2) + return 1; // skip on any key + } + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && canabort == 3) { + return 1; // skip on mouse click + } + return 0; } #if AGS_PLATFORM_OS_WINDOWS @@ -95,143 +93,138 @@ int __cdecl fli_callback() { #else extern "C" int fli_callback() { #endif - Bitmap *usebuf = fli_buffer; + Bitmap *usebuf = fli_buffer; - update_audio_system_on_game_loop (); + update_audio_system_on_game_loop(); - if (game.color_depth > 1) { - hicol_buf->Blit(fli_buffer,0,0,0,0,fliwidth,fliheight); - usebuf=hicol_buf; - } + if (game.color_depth > 1) { + hicol_buf->Blit(fli_buffer, 0, 0, 0, 0, fliwidth, fliheight); + usebuf = hicol_buf; + } - const Rect &view = play.GetMainViewport(); - if (stretch_flc == 0) - fli_target->Blit(usebuf, 0,0, view.GetWidth()/2-fliwidth/2, view.GetHeight()/2-fliheight/2, view.GetWidth(), view.GetHeight()); - else - fli_target->StretchBlt(usebuf, RectWH(0,0,fliwidth,fliheight), RectWH(0,0, view.GetWidth(), view.GetHeight())); + const Rect &view = play.GetMainViewport(); + if (stretch_flc == 0) + fli_target->Blit(usebuf, 0, 0, view.GetWidth() / 2 - fliwidth / 2, view.GetHeight() / 2 - fliheight / 2, view.GetWidth(), view.GetHeight()); + else + fli_target->StretchBlt(usebuf, RectWH(0, 0, fliwidth, fliheight), RectWH(0, 0, view.GetWidth(), view.GetHeight())); - gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); - gfxDriver->DrawSprite(0, 0, fli_ddb); - render_to_screen(); + gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); + gfxDriver->DrawSprite(0, 0, fli_ddb); + render_to_screen(); - return check_if_user_input_should_cancel_video(); + return check_if_user_input_should_cancel_video(); } -void play_flc_file(int numb,int playflags) { - color oldpal[256]; - - // AGS 2.x: If the screen is faded out, fade in again when playing a movie. - if (loaded_game_file_version <= kGameVersion_272) - play.screen_is_faded_out = 0; - - if (play.fast_forward) - return; - - get_palette_range(oldpal, 0, 255); - - int clearScreenAtStart = 1; - canabort = playflags % 10; - playflags -= canabort; - - if (canabort == 2) // convert to PlayVideo-compatible setting - canabort = 3; - - if (playflags % 100 == 0) - stretch_flc = 1; - else - stretch_flc = 0; - - if (playflags / 100) - clearScreenAtStart = 0; - - String flicname = String::FromFormat("flic%d.flc", numb); - Stream *in = AssetManager::OpenAsset(flicname); - if (!in) - { - flicname.Format("flic%d.fli", numb); - in = AssetManager::OpenAsset(flicname); - } - if (!in) - { - debug_script_warn("FLIC animation flic%d.flc nor flic%d.fli not found", numb, numb); - return; - } - - in->Seek(8); - fliwidth = in->ReadInt16(); - fliheight = in->ReadInt16(); - delete in; - - if (game.color_depth > 1) { - hicol_buf=BitmapHelper::CreateBitmap(fliwidth,fliheight,game.GetColorDepth()); - hicol_buf->Clear(); - } - // override the stretch option if necessary - const Rect &view = play.GetMainViewport(); - if ((fliwidth == view.GetWidth()) && (fliheight == view.GetHeight())) - stretch_flc = 0; - else if ((fliwidth > view.GetWidth()) || (fliheight >view.GetHeight())) - stretch_flc = 1; - fli_buffer=BitmapHelper::CreateBitmap(fliwidth,fliheight,8); - if (fli_buffer==nullptr) quit("Not enough memory to play animation"); - fli_buffer->Clear(); - - if (clearScreenAtStart) - { - if (gfxDriver->UsesMemoryBackBuffer()) - { - Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); - screen_bmp->Clear(); - } - render_to_screen(); - } - - video_type = kVideoFlic; - fli_target = BitmapHelper::CreateBitmap(view.GetWidth(), view.GetHeight(), game.GetColorDepth()); - fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); - - // TODO: find a better solution. - // Make only certain versions of the engineuse play_fli_pf from the patched version of Allegro for now. - // Add more versions as their Allegro lib becomes patched too, or they use newer version of Allegro 4. - // Ports can still play FLI if separate file is put into game's directory. +void play_flc_file(int numb, int playflags) { + color oldpal[256]; + + // AGS 2.x: If the screen is faded out, fade in again when playing a movie. + if (loaded_game_file_version <= kGameVersion_272) + play.screen_is_faded_out = 0; + + if (play.fast_forward) + return; + + get_palette_range(oldpal, 0, 255); + + int clearScreenAtStart = 1; + canabort = playflags % 10; + playflags -= canabort; + + if (canabort == 2) // convert to PlayVideo-compatible setting + canabort = 3; + + if (playflags % 100 == 0) + stretch_flc = 1; + else + stretch_flc = 0; + + if (playflags / 100) + clearScreenAtStart = 0; + + String flicname = String::FromFormat("flic%d.flc", numb); + Stream *in = AssetManager::OpenAsset(flicname); + if (!in) { + flicname.Format("flic%d.fli", numb); + in = AssetManager::OpenAsset(flicname); + } + if (!in) { + debug_script_warn("FLIC animation flic%d.flc nor flic%d.fli not found", numb, numb); + return; + } + + in->Seek(8); + fliwidth = in->ReadInt16(); + fliheight = in->ReadInt16(); + delete in; + + if (game.color_depth > 1) { + hicol_buf = BitmapHelper::CreateBitmap(fliwidth, fliheight, game.GetColorDepth()); + hicol_buf->Clear(); + } + // override the stretch option if necessary + const Rect &view = play.GetMainViewport(); + if ((fliwidth == view.GetWidth()) && (fliheight == view.GetHeight())) + stretch_flc = 0; + else if ((fliwidth > view.GetWidth()) || (fliheight > view.GetHeight())) + stretch_flc = 1; + fli_buffer = BitmapHelper::CreateBitmap(fliwidth, fliheight, 8); + if (fli_buffer == nullptr) quit("Not enough memory to play animation"); + fli_buffer->Clear(); + + if (clearScreenAtStart) { + if (gfxDriver->UsesMemoryBackBuffer()) { + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + screen_bmp->Clear(); + } + render_to_screen(); + } + + video_type = kVideoFlic; + fli_target = BitmapHelper::CreateBitmap(view.GetWidth(), view.GetHeight(), game.GetColorDepth()); + fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); + + // TODO: find a better solution. + // Make only certain versions of the engineuse play_fli_pf from the patched version of Allegro for now. + // Add more versions as their Allegro lib becomes patched too, or they use newer version of Allegro 4. + // Ports can still play FLI if separate file is put into game's directory. #if AGS_FLI_FROM_PACK_FILE - size_t asset_size; - PACKFILE *pf = PackfileFromAsset(AssetPath("", flicname), asset_size); - if (play_fli_pf(pf, (BITMAP*)fli_buffer->GetAllegroBitmap(), fli_callback)==FLI_ERROR) + size_t asset_size; + PACKFILE *pf = PackfileFromAsset(AssetPath("", flicname), asset_size); + if (play_fli_pf(pf, (BITMAP *)fli_buffer->GetAllegroBitmap(), fli_callback) == FLI_ERROR) #else - if (play_fli(flicname, (BITMAP*)fli_buffer->GetAllegroBitmap(), 0, fli_callback)==FLI_ERROR) + if (play_fli(flicname, (BITMAP *)fli_buffer->GetAllegroBitmap(), 0, fli_callback) == FLI_ERROR) #endif - { - // This is not a fatal error that should prevent the game from continuing - Debug::Printf("FLI/FLC animation play error"); - } + { + // This is not a fatal error that should prevent the game from continuing + Debug::Printf("FLI/FLC animation play error"); + } #if AGS_FLI_FROM_PACK_FILE - pack_fclose(pf); + pack_fclose(pf); #endif - video_type = kVideoNone; - delete fli_buffer; - fli_buffer = nullptr; - // NOTE: the screen bitmap could change in the meanwhile, if the display mode has changed - if (gfxDriver->UsesMemoryBackBuffer()) - { - Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); - screen_bmp->Clear(); - } - set_palette_range(oldpal, 0, 255, 0); - render_to_screen(); - - delete fli_target; - gfxDriver->DestroyDDB(fli_ddb); - fli_target = nullptr; - fli_ddb = nullptr; - - - delete hicol_buf; - hicol_buf=nullptr; - // SetVirtualScreen(screen); wputblock(0,0,backbuffer,0); - while (ags_mgetbutton()!=NONE) { } // clear any queued mouse events. - invalidate_screen(); + video_type = kVideoNone; + delete fli_buffer; + fli_buffer = nullptr; + // NOTE: the screen bitmap could change in the meanwhile, if the display mode has changed + if (gfxDriver->UsesMemoryBackBuffer()) { + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + screen_bmp->Clear(); + } + set_palette_range(oldpal, 0, 255, 0); + render_to_screen(); + + delete fli_target; + gfxDriver->DestroyDDB(fli_ddb); + fli_target = nullptr; + fli_ddb = nullptr; + + + delete hicol_buf; + hicol_buf = nullptr; + // SetVirtualScreen(screen); wputblock(0,0,backbuffer,0); + while (ags_mgetbutton() != NONE) { } // clear any queued mouse events. + invalidate_screen(); } // FLIC player end @@ -239,52 +232,43 @@ void play_flc_file(int numb,int playflags) { // Theora player begin // TODO: find a way to take Bitmap here? Bitmap gl_TheoraBuffer; -int theora_playing_callback(BITMAP *theoraBuffer) -{ - if (theoraBuffer == nullptr) - { - // No video, only sound - return check_if_user_input_should_cancel_video(); - } - - gl_TheoraBuffer.WrapAllegroBitmap(theoraBuffer, true); - - int drawAtX = 0, drawAtY = 0; - const Rect &viewport = play.GetMainViewport(); - if (fli_ddb == nullptr) - { - fli_ddb = gfxDriver->CreateDDBFromBitmap(&gl_TheoraBuffer, false, true); - } - if (stretch_flc) - { - drawAtX = viewport.GetWidth() / 2 - fliTargetWidth / 2; - drawAtY = viewport.GetHeight() / 2 - fliTargetHeight / 2; - if (!gfxDriver->HasAcceleratedTransform()) - { - fli_target->StretchBlt(&gl_TheoraBuffer, RectWH(0, 0, gl_TheoraBuffer.GetWidth(), gl_TheoraBuffer.GetHeight()), - RectWH(drawAtX, drawAtY, fliTargetWidth, fliTargetHeight)); - gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); - drawAtX = 0; - drawAtY = 0; - } - else - { - gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); - fli_ddb->SetStretch(fliTargetWidth, fliTargetHeight, false); - } - } - else - { - gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); - drawAtX = viewport.GetWidth() / 2 - gl_TheoraBuffer.GetWidth() / 2; - drawAtY = viewport.GetHeight() / 2 - gl_TheoraBuffer.GetHeight() / 2; - } - - gfxDriver->DrawSprite(drawAtX, drawAtY, fli_ddb); - update_audio_system_on_game_loop (); - render_to_screen(); - - return check_if_user_input_should_cancel_video(); +int theora_playing_callback(BITMAP *theoraBuffer) { + if (theoraBuffer == nullptr) { + // No video, only sound + return check_if_user_input_should_cancel_video(); + } + + gl_TheoraBuffer.WrapAllegroBitmap(theoraBuffer, true); + + int drawAtX = 0, drawAtY = 0; + const Rect &viewport = play.GetMainViewport(); + if (fli_ddb == nullptr) { + fli_ddb = gfxDriver->CreateDDBFromBitmap(&gl_TheoraBuffer, false, true); + } + if (stretch_flc) { + drawAtX = viewport.GetWidth() / 2 - fliTargetWidth / 2; + drawAtY = viewport.GetHeight() / 2 - fliTargetHeight / 2; + if (!gfxDriver->HasAcceleratedTransform()) { + fli_target->StretchBlt(&gl_TheoraBuffer, RectWH(0, 0, gl_TheoraBuffer.GetWidth(), gl_TheoraBuffer.GetHeight()), + RectWH(drawAtX, drawAtY, fliTargetWidth, fliTargetHeight)); + gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); + drawAtX = 0; + drawAtY = 0; + } else { + gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); + fli_ddb->SetStretch(fliTargetWidth, fliTargetHeight, false); + } + } else { + gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); + drawAtX = viewport.GetWidth() / 2 - gl_TheoraBuffer.GetWidth() / 2; + drawAtY = viewport.GetHeight() / 2 - gl_TheoraBuffer.GetHeight() / 2; + } + + gfxDriver->DrawSprite(drawAtX, drawAtY, fli_ddb); + update_audio_system_on_game_loop(); + render_to_screen(); + + return check_if_user_input_should_cancel_video(); } // @@ -292,148 +276,125 @@ int theora_playing_callback(BITMAP *theoraBuffer) // provide means to supply user's PACKFILE directly. // // Open stream for reading (return suggested cache buffer size). -int apeg_stream_init(void *ptr) -{ - return ptr != nullptr ? F_BUF_SIZE : 0; +int apeg_stream_init(void *ptr) { + return ptr != nullptr ? F_BUF_SIZE : 0; } // Read requested number of bytes into provided buffer, // return actual number of bytes managed to read. -int apeg_stream_read(void *buffer, int bytes, void *ptr) -{ - return ((Stream*)ptr)->Read(buffer, bytes); +int apeg_stream_read(void *buffer, int bytes, void *ptr) { + return ((Stream *)ptr)->Read(buffer, bytes); } // Skip requested number of bytes -void apeg_stream_skip(int bytes, void *ptr) -{ - ((Stream*)ptr)->Seek(bytes); +void apeg_stream_skip(int bytes, void *ptr) { + ((Stream *)ptr)->Seek(bytes); } // -APEG_STREAM* get_theora_size(Stream *video_stream, int *width, int *height) -{ - APEG_STREAM* oggVid = apeg_open_stream_ex(video_stream); - if (oggVid != nullptr) - { - apeg_get_video_size(oggVid, width, height); - } - else - { - *width = 0; - *height = 0; - } - return oggVid; +APEG_STREAM *get_theora_size(Stream *video_stream, int *width, int *height) { + APEG_STREAM *oggVid = apeg_open_stream_ex(video_stream); + if (oggVid != nullptr) { + apeg_get_video_size(oggVid, width, height); + } else { + *width = 0; + *height = 0; + } + return oggVid; } // TODO: use shared utility function for placing rect in rect -void calculate_destination_size_maintain_aspect_ratio(int vidWidth, int vidHeight, int *targetWidth, int *targetHeight) -{ - const Rect &viewport = play.GetMainViewport(); - float aspectRatioVideo = (float)vidWidth / (float)vidHeight; - float aspectRatioScreen = (float)viewport.GetWidth() / (float)viewport.GetHeight(); - - if (aspectRatioVideo == aspectRatioScreen) - { - *targetWidth = viewport.GetWidth(); - *targetHeight = viewport.GetHeight(); - } - else if (aspectRatioVideo > aspectRatioScreen) - { - *targetWidth = viewport.GetWidth(); - *targetHeight = (int)(((float)viewport.GetWidth() / aspectRatioVideo) + 0.5f); - } - else - { - *targetHeight = viewport.GetHeight(); - *targetWidth = (float)viewport.GetHeight() * aspectRatioVideo; - } +void calculate_destination_size_maintain_aspect_ratio(int vidWidth, int vidHeight, int *targetWidth, int *targetHeight) { + const Rect &viewport = play.GetMainViewport(); + float aspectRatioVideo = (float)vidWidth / (float)vidHeight; + float aspectRatioScreen = (float)viewport.GetWidth() / (float)viewport.GetHeight(); + + if (aspectRatioVideo == aspectRatioScreen) { + *targetWidth = viewport.GetWidth(); + *targetHeight = viewport.GetHeight(); + } else if (aspectRatioVideo > aspectRatioScreen) { + *targetWidth = viewport.GetWidth(); + *targetHeight = (int)(((float)viewport.GetWidth() / aspectRatioVideo) + 0.5f); + } else { + *targetHeight = viewport.GetHeight(); + *targetWidth = (float)viewport.GetHeight() * aspectRatioVideo; + } } -void play_theora_video(const char *name, int skip, int flags) -{ - std::unique_ptr video_stream(AssetManager::OpenAsset(name)); - apeg_set_stream_reader(apeg_stream_init, apeg_stream_read, apeg_stream_skip); - apeg_set_display_depth(game.GetColorDepth()); - // we must disable length detection, otherwise it takes ages to start - // playing if the file is large because it seeks through the whole thing - apeg_disable_length_detection(TRUE); - // Disable framedrop because it can lead to the PSP not playing the video at all. - apeg_enable_framedrop(psp_video_framedrop); - update_polled_stuff_if_runtime(); - - stretch_flc = (flags % 10); - canabort = skip; - apeg_ignore_audio((flags >= 10) ? 1 : 0); - - int videoWidth, videoHeight; - APEG_STREAM *oggVid = get_theora_size(video_stream.get(), &videoWidth, &videoHeight); - - if (videoWidth == 0) - { - Display("Unable to load theora video '%s'", name); - return; - } - - if (flags < 10) - { - stop_all_sound_and_music(); - } - - //fli_buffer = BitmapHelper::CreateBitmap_(scsystem.coldepth, videoWidth, videoHeight); - calculate_destination_size_maintain_aspect_ratio(videoWidth, videoHeight, &fliTargetWidth, &fliTargetHeight); - - if ((fliTargetWidth == videoWidth) && (fliTargetHeight == videoHeight) && (stretch_flc)) - { - // don't need to stretch after all - stretch_flc = 0; - } - - if ((stretch_flc) && (!gfxDriver->HasAcceleratedTransform())) - { - fli_target = BitmapHelper::CreateBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight(), game.GetColorDepth()); - fli_target->Clear(); - fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); - } - else - { - fli_ddb = nullptr; - } - - update_polled_stuff_if_runtime(); - - if (gfxDriver->UsesMemoryBackBuffer()) - gfxDriver->GetMemoryBackBuffer()->Clear(); - - video_type = kVideoTheora; - if (apeg_play_apeg_stream(oggVid, nullptr, 0, theora_playing_callback) == APEG_ERROR) - { - Display("Error playing theora video '%s'", name); - } - apeg_close_stream(oggVid); - video_type = kVideoNone; - - //destroy_bitmap(fli_buffer); - delete fli_target; - gfxDriver->DestroyDDB(fli_ddb); - fli_target = nullptr; - fli_ddb = nullptr; - invalidate_screen(); +void play_theora_video(const char *name, int skip, int flags) { + std::unique_ptr video_stream(AssetManager::OpenAsset(name)); + apeg_set_stream_reader(apeg_stream_init, apeg_stream_read, apeg_stream_skip); + apeg_set_display_depth(game.GetColorDepth()); + // we must disable length detection, otherwise it takes ages to start + // playing if the file is large because it seeks through the whole thing + apeg_disable_length_detection(TRUE); + // Disable framedrop because it can lead to the PSP not playing the video at all. + apeg_enable_framedrop(psp_video_framedrop); + update_polled_stuff_if_runtime(); + + stretch_flc = (flags % 10); + canabort = skip; + apeg_ignore_audio((flags >= 10) ? 1 : 0); + + int videoWidth, videoHeight; + APEG_STREAM *oggVid = get_theora_size(video_stream.get(), &videoWidth, &videoHeight); + + if (videoWidth == 0) { + Display("Unable to load theora video '%s'", name); + return; + } + + if (flags < 10) { + stop_all_sound_and_music(); + } + + //fli_buffer = BitmapHelper::CreateBitmap_(scsystem.coldepth, videoWidth, videoHeight); + calculate_destination_size_maintain_aspect_ratio(videoWidth, videoHeight, &fliTargetWidth, &fliTargetHeight); + + if ((fliTargetWidth == videoWidth) && (fliTargetHeight == videoHeight) && (stretch_flc)) { + // don't need to stretch after all + stretch_flc = 0; + } + + if ((stretch_flc) && (!gfxDriver->HasAcceleratedTransform())) { + fli_target = BitmapHelper::CreateBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight(), game.GetColorDepth()); + fli_target->Clear(); + fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); + } else { + fli_ddb = nullptr; + } + + update_polled_stuff_if_runtime(); + + if (gfxDriver->UsesMemoryBackBuffer()) + gfxDriver->GetMemoryBackBuffer()->Clear(); + + video_type = kVideoTheora; + if (apeg_play_apeg_stream(oggVid, nullptr, 0, theora_playing_callback) == APEG_ERROR) { + Display("Error playing theora video '%s'", name); + } + apeg_close_stream(oggVid); + video_type = kVideoNone; + + //destroy_bitmap(fli_buffer); + delete fli_target; + gfxDriver->DestroyDDB(fli_ddb); + fli_target = nullptr; + fli_ddb = nullptr; + invalidate_screen(); } // Theora player end -void video_on_gfxmode_changed() -{ - if (video_type == kVideoFlic) - { - // If the FLIC video is playing, restore its palette - set_palette_range(fli_palette, 0, 255, 0); - } +void video_on_gfxmode_changed() { + if (video_type == kVideoFlic) { + // If the FLIC video is playing, restore its palette + set_palette_range(fli_palette, 0, 255, 0); + } } #else void play_theora_video(const char *name, int skip, int flags) {} -void play_flc_file(int numb,int playflags) {} +void play_flc_file(int numb, int playflags) {} void video_on_gfxmode_changed() {} #endif diff --git a/engines/ags/engine/media/video/video.h b/engines/ags/engine/media/video/video.h index fd330820550d..16c037f7da7d 100644 --- a/engines/ags/engine/media/video/video.h +++ b/engines/ags/engine/media/video/video.h @@ -24,7 +24,7 @@ #define AGS_ENGINE_MEDIA_VIDEO_VIDEO_H void play_theora_video(const char *name, int skip, int flags); -void play_flc_file(int numb,int playflags); +void play_flc_file(int numb, int playflags); // Update video playback if the display mode has changed void video_on_gfxmode_changed(); diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp index 64e21ea45943..640691c5f87e 100644 --- a/engines/ags/engine/platform/android/acpland.cpp +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -31,7 +31,7 @@ #include "plugin/agsplugin.h" #include #include -#include +#include #include #include #include "util/string_compat.h" @@ -45,25 +45,27 @@ using namespace AGS::Common; #define ANDROID_CONFIG_FILENAME "android.cfg" -bool ReadConfiguration(char* filename, bool read_everything); +bool ReadConfiguration(char *filename, bool read_everything); void ResetConfiguration(); struct AGSAndroid : AGSPlatformDriver { - virtual int CDPlayerCommand(int cmdd, int datt); - virtual void Delay(int millis); - virtual void DisplayAlert(const char*, ...); - virtual const char *GetAppOutputDirectory(); - virtual unsigned long GetDiskFreeSpaceMB(); - virtual const char* GetNoMouseErrorString(); - virtual bool IsBackendResponsibleForMouseScaling() { return true; } - virtual eScriptSystemOSID GetSystemOSID(); - virtual int InitializeCDPlayer(); - virtual void PostAllegroExit(); - virtual void SetGameWindowIcon(); - virtual void ShutdownCDPlayer(); - virtual void WriteStdOut(const char *fmt, ...); - virtual void WriteStdErr(const char *fmt, ...); + virtual int CDPlayerCommand(int cmdd, int datt); + virtual void Delay(int millis); + virtual void DisplayAlert(const char *, ...); + virtual const char *GetAppOutputDirectory(); + virtual unsigned long GetDiskFreeSpaceMB(); + virtual const char *GetNoMouseErrorString(); + virtual bool IsBackendResponsibleForMouseScaling() { + return true; + } + virtual eScriptSystemOSID GetSystemOSID(); + virtual int InitializeCDPlayer(); + virtual void PostAllegroExit(); + virtual void SetGameWindowIcon(); + virtual void ShutdownCDPlayer(); + virtual void WriteStdOut(const char *fmt, ...); + virtual void WriteStdErr(const char *fmt, ...); }; @@ -73,7 +75,7 @@ int psp_clear_cache_on_room_change = 0; int psp_rotation = 0; int psp_config_enabled = 0; char psp_translation[100]; -char* psp_translations[100]; +char *psp_translations[100]; // Mouse option from Allegro. extern int config_mouse_control_mode; @@ -106,12 +108,12 @@ extern int display_fps; extern int want_exit; extern void PauseGame(); extern void UnPauseGame(); -extern int main(int argc,char*argv[]); +extern int main(int argc, char *argv[]); char android_base_directory[256]; char android_app_directory[256]; char psp_game_file_name[256]; -char* psp_game_file_name_pointer = psp_game_file_name; +char *psp_game_file_name_pointer = psp_game_file_name; bool psp_load_latest_savegame = false; extern char saveGameDirectory[260]; @@ -119,7 +121,7 @@ extern const char *loadSaveGameOnStartup; char lastSaveGameName[200]; -extern JavaVM* android_jni_vm; +extern JavaVM *android_jni_vm; JNIEnv *java_environment; jobject java_object; jclass java_class; @@ -131,635 +133,596 @@ jmethodID java_enableLongclick; bool reset_configuration = false; -extern "C" +extern "C" { -const int CONFIG_IGNORE_ACSETUP = 0; -const int CONFIG_CLEAR_CACHE = 1; -const int CONFIG_AUDIO_RATE = 2; -const int CONFIG_AUDIO_ENABLED = 3; -const int CONFIG_AUDIO_THREADED = 4; -const int CONFIG_AUDIO_CACHESIZE = 5; -const int CONFIG_MIDI_ENABLED = 6; -const int CONFIG_MIDI_PRELOAD = 7; -const int CONFIG_VIDEO_FRAMEDROP = 8; -const int CONFIG_GFX_RENDERER = 9; -const int CONFIG_GFX_SMOOTHING = 10; -const int CONFIG_GFX_SCALING = 11; -const int CONFIG_GFX_SS = 12; -const int CONFIG_ROTATION = 13; -const int CONFIG_ENABLED = 14; -const int CONFIG_DEBUG_FPS = 15; -const int CONFIG_GFX_SMOOTH_SPRITES = 16; -const int CONFIG_TRANSLATION = 17; -const int CONFIG_DEBUG_LOGCAT = 18; -const int CONFIG_MOUSE_METHOD = 19; -const int CONFIG_MOUSE_LONGCLICK = 20; - -extern void android_debug_printf(const char* format, ...); - -JNIEXPORT jboolean JNICALL - Java_com_bigbluecup_android_PreferencesActivity_readConfigFile(JNIEnv* env, jobject object, jstring directory) -{ - const char* cdirectory = env->GetStringUTFChars(directory, NULL); - chdir(cdirectory); - env->ReleaseStringUTFChars(directory, cdirectory); - - ResetConfiguration(); - - return ReadConfiguration(ANDROID_CONFIG_FILENAME, true); -} - - -JNIEXPORT jboolean JNICALL - Java_com_bigbluecup_android_PreferencesActivity_writeConfigFile(JNIEnv* env, jobject object) -{ - FILE* config = fopen(ANDROID_CONFIG_FILENAME, "wb"); - if (config) - { - fprintf(config, "[misc]\n"); - fprintf(config, "config_enabled = %d\n", psp_config_enabled); - fprintf(config, "rotation = %d\n", psp_rotation); - fprintf(config, "translation = %s\n", psp_translation); - - fprintf(config, "[controls]\n"); - fprintf(config, "mouse_method = %d\n", config_mouse_control_mode); - fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick); - - fprintf(config, "[compatibility]\n"); + const int CONFIG_IGNORE_ACSETUP = 0; + const int CONFIG_CLEAR_CACHE = 1; + const int CONFIG_AUDIO_RATE = 2; + const int CONFIG_AUDIO_ENABLED = 3; + const int CONFIG_AUDIO_THREADED = 4; + const int CONFIG_AUDIO_CACHESIZE = 5; + const int CONFIG_MIDI_ENABLED = 6; + const int CONFIG_MIDI_PRELOAD = 7; + const int CONFIG_VIDEO_FRAMEDROP = 8; + const int CONFIG_GFX_RENDERER = 9; + const int CONFIG_GFX_SMOOTHING = 10; + const int CONFIG_GFX_SCALING = 11; + const int CONFIG_GFX_SS = 12; + const int CONFIG_ROTATION = 13; + const int CONFIG_ENABLED = 14; + const int CONFIG_DEBUG_FPS = 15; + const int CONFIG_GFX_SMOOTH_SPRITES = 16; + const int CONFIG_TRANSLATION = 17; + const int CONFIG_DEBUG_LOGCAT = 18; + const int CONFIG_MOUSE_METHOD = 19; + const int CONFIG_MOUSE_LONGCLICK = 20; + + extern void android_debug_printf(const char *format, ...); + + JNIEXPORT jboolean JNICALL + Java_com_bigbluecup_android_PreferencesActivity_readConfigFile(JNIEnv *env, jobject object, jstring directory) { + const char *cdirectory = env->GetStringUTFChars(directory, NULL); + chdir(cdirectory); + env->ReleaseStringUTFChars(directory, cdirectory); + + ResetConfiguration(); + + return ReadConfiguration(ANDROID_CONFIG_FILENAME, true); + } + + + JNIEXPORT jboolean JNICALL + Java_com_bigbluecup_android_PreferencesActivity_writeConfigFile(JNIEnv *env, jobject object) { + FILE *config = fopen(ANDROID_CONFIG_FILENAME, "wb"); + if (config) { + fprintf(config, "[misc]\n"); + fprintf(config, "config_enabled = %d\n", psp_config_enabled); + fprintf(config, "rotation = %d\n", psp_rotation); + fprintf(config, "translation = %s\n", psp_translation); + + fprintf(config, "[controls]\n"); + fprintf(config, "mouse_method = %d\n", config_mouse_control_mode); + fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick); + + fprintf(config, "[compatibility]\n"); // fprintf(config, "ignore_acsetup_cfg_file = %d\n", psp_ignore_acsetup_cfg_file); - fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change); - - fprintf(config, "[sound]\n"); - fprintf(config, "samplerate = %d\n", psp_audio_samplerate ); - fprintf(config, "enabled = %d\n", psp_audio_enabled); - fprintf(config, "threaded = %d\n", psp_audio_multithreaded); - fprintf(config, "cache_size = %d\n", psp_audio_cachesize); - - fprintf(config, "[midi]\n"); - fprintf(config, "enabled = %d\n", psp_midi_enabled); - fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches); - - fprintf(config, "[video]\n"); - fprintf(config, "framedrop = %d\n", psp_video_framedrop); - - fprintf(config, "[graphics]\n"); - fprintf(config, "renderer = %d\n", psp_gfx_renderer); - fprintf(config, "smoothing = %d\n", psp_gfx_smoothing); - fprintf(config, "scaling = %d\n", psp_gfx_scaling); - fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling); - fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites); - - fprintf(config, "[debug]\n"); - fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0); - fprintf(config, "logging = %d\n", psp_debug_write_to_logcat); - - fclose(config); - - return true; - } - - return false; -} - - -JNIEXPORT jint JNICALL - Java_com_bigbluecup_android_PreferencesActivity_readIntConfigValue(JNIEnv* env, jobject object, jint id) -{ - switch (id) - { - case CONFIG_IGNORE_ACSETUP: - return psp_ignore_acsetup_cfg_file; - break; - case CONFIG_CLEAR_CACHE: - return psp_clear_cache_on_room_change; - break; - case CONFIG_AUDIO_RATE: - return psp_audio_samplerate; - break; - case CONFIG_AUDIO_ENABLED: - return psp_audio_enabled; - break; - case CONFIG_AUDIO_THREADED: - return psp_audio_multithreaded; - break; - case CONFIG_AUDIO_CACHESIZE: - return psp_audio_cachesize; - break; - case CONFIG_MIDI_ENABLED: - return psp_midi_enabled; - break; - case CONFIG_MIDI_PRELOAD: - return psp_midi_preload_patches; - break; - case CONFIG_VIDEO_FRAMEDROP: - return psp_video_framedrop; - break; - case CONFIG_GFX_RENDERER: - return psp_gfx_renderer; - break; - case CONFIG_GFX_SMOOTHING: - return psp_gfx_smoothing; - break; - case CONFIG_GFX_SCALING: - return psp_gfx_scaling; - break; - case CONFIG_GFX_SS: - return psp_gfx_super_sampling; - break; - case CONFIG_GFX_SMOOTH_SPRITES: - return psp_gfx_smooth_sprites; - break; - case CONFIG_ROTATION: - return psp_rotation; - break; - case CONFIG_ENABLED: - return psp_config_enabled; - break; - case CONFIG_DEBUG_FPS: - return (display_fps == 2) ? 1 : 0; - break; - case CONFIG_DEBUG_LOGCAT: - return psp_debug_write_to_logcat; - break; - case CONFIG_MOUSE_METHOD: - return config_mouse_control_mode; - break; - case CONFIG_MOUSE_LONGCLICK: - return config_mouse_longclick; - break; - default: - return 0; - break; - } -} - - -JNIEXPORT jstring JNICALL - Java_com_bigbluecup_android_PreferencesActivity_readStringConfigValue(JNIEnv* env, jobject object, jint id, jstring value) -{ - switch (id) - { - case CONFIG_TRANSLATION: - return env->NewStringUTF(&psp_translation[0]); - break; - } -} - - -JNIEXPORT void JNICALL - Java_com_bigbluecup_android_PreferencesActivity_setIntConfigValue(JNIEnv* env, jobject object, jint id, jint value) -{ - switch (id) - { - case CONFIG_IGNORE_ACSETUP: - psp_ignore_acsetup_cfg_file = value; - break; - case CONFIG_CLEAR_CACHE: - psp_clear_cache_on_room_change = value; - break; - case CONFIG_AUDIO_RATE: - psp_audio_samplerate = value; - break; - case CONFIG_AUDIO_ENABLED: - psp_audio_enabled = value; - break; - case CONFIG_AUDIO_THREADED: - psp_audio_multithreaded = value; - break; - case CONFIG_AUDIO_CACHESIZE: - psp_audio_cachesize = value; - break; - case CONFIG_MIDI_ENABLED: - psp_midi_enabled = value; - break; - case CONFIG_MIDI_PRELOAD: - psp_midi_preload_patches = value; - break; - case CONFIG_VIDEO_FRAMEDROP: - psp_video_framedrop = value; - break; - case CONFIG_GFX_RENDERER: - psp_gfx_renderer = value; - break; - case CONFIG_GFX_SMOOTHING: - psp_gfx_smoothing = value; - break; - case CONFIG_GFX_SCALING: - psp_gfx_scaling = value; - break; - case CONFIG_GFX_SS: - psp_gfx_super_sampling = value; - break; - case CONFIG_GFX_SMOOTH_SPRITES: - psp_gfx_smooth_sprites = value; - break; - case CONFIG_ROTATION: - psp_rotation = value; - break; - case CONFIG_ENABLED: - psp_config_enabled = value; - break; - case CONFIG_DEBUG_FPS: - display_fps = (value == 1) ? 2 : 0; - break; - case CONFIG_DEBUG_LOGCAT: - psp_debug_write_to_logcat = value; - break; - case CONFIG_MOUSE_METHOD: - config_mouse_control_mode = value; - break; - case CONFIG_MOUSE_LONGCLICK: - config_mouse_longclick = value; - break; - default: - break; - } -} - - -JNIEXPORT void JNICALL - Java_com_bigbluecup_android_PreferencesActivity_setStringConfigValue(JNIEnv* env, jobject object, jint id, jstring value) -{ - const char* cstring = env->GetStringUTFChars(value, NULL); - - switch (id) - { - case CONFIG_TRANSLATION: - strcpy(psp_translation, cstring); - break; - default: - break; - } - - env->ReleaseStringUTFChars(value, cstring); -} - - -JNIEXPORT jint JNICALL -Java_com_bigbluecup_android_PreferencesActivity_getAvailableTranslations(JNIEnv* env, jobject object, jobjectArray translations) -{ - int i = 0; - int length; - DIR* dir; - struct dirent* entry; - char buffer[200]; - - dir = opendir("."); - if (dir) - { - while ((entry = readdir(dir)) != 0) - { - length = strlen(entry->d_name); - if (length > 4) - { - if (ags_stricmp(&entry->d_name[length - 4], ".tra") == 0) - { - memset(buffer, 0, 200); - strncpy(buffer, entry->d_name, length - 4); - psp_translations[i] = (char*)malloc(strlen(buffer) + 1); - strcpy(psp_translations[i], buffer); - env->SetObjectArrayElement(translations, i, env->NewStringUTF(&buffer[0])); - i++; - } - } - } - closedir(dir); - } - - return i; -} - + fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change); + + fprintf(config, "[sound]\n"); + fprintf(config, "samplerate = %d\n", psp_audio_samplerate); + fprintf(config, "enabled = %d\n", psp_audio_enabled); + fprintf(config, "threaded = %d\n", psp_audio_multithreaded); + fprintf(config, "cache_size = %d\n", psp_audio_cachesize); + + fprintf(config, "[midi]\n"); + fprintf(config, "enabled = %d\n", psp_midi_enabled); + fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches); + + fprintf(config, "[video]\n"); + fprintf(config, "framedrop = %d\n", psp_video_framedrop); + + fprintf(config, "[graphics]\n"); + fprintf(config, "renderer = %d\n", psp_gfx_renderer); + fprintf(config, "smoothing = %d\n", psp_gfx_smoothing); + fprintf(config, "scaling = %d\n", psp_gfx_scaling); + fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling); + fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites); + + fprintf(config, "[debug]\n"); + fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0); + fprintf(config, "logging = %d\n", psp_debug_write_to_logcat); + + fclose(config); + + return true; + } + + return false; + } + + + JNIEXPORT jint JNICALL + Java_com_bigbluecup_android_PreferencesActivity_readIntConfigValue(JNIEnv *env, jobject object, jint id) { + switch (id) { + case CONFIG_IGNORE_ACSETUP: + return psp_ignore_acsetup_cfg_file; + break; + case CONFIG_CLEAR_CACHE: + return psp_clear_cache_on_room_change; + break; + case CONFIG_AUDIO_RATE: + return psp_audio_samplerate; + break; + case CONFIG_AUDIO_ENABLED: + return psp_audio_enabled; + break; + case CONFIG_AUDIO_THREADED: + return psp_audio_multithreaded; + break; + case CONFIG_AUDIO_CACHESIZE: + return psp_audio_cachesize; + break; + case CONFIG_MIDI_ENABLED: + return psp_midi_enabled; + break; + case CONFIG_MIDI_PRELOAD: + return psp_midi_preload_patches; + break; + case CONFIG_VIDEO_FRAMEDROP: + return psp_video_framedrop; + break; + case CONFIG_GFX_RENDERER: + return psp_gfx_renderer; + break; + case CONFIG_GFX_SMOOTHING: + return psp_gfx_smoothing; + break; + case CONFIG_GFX_SCALING: + return psp_gfx_scaling; + break; + case CONFIG_GFX_SS: + return psp_gfx_super_sampling; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + return psp_gfx_smooth_sprites; + break; + case CONFIG_ROTATION: + return psp_rotation; + break; + case CONFIG_ENABLED: + return psp_config_enabled; + break; + case CONFIG_DEBUG_FPS: + return (display_fps == 2) ? 1 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + return psp_debug_write_to_logcat; + break; + case CONFIG_MOUSE_METHOD: + return config_mouse_control_mode; + break; + case CONFIG_MOUSE_LONGCLICK: + return config_mouse_longclick; + break; + default: + return 0; + break; + } + } + + + JNIEXPORT jstring JNICALL + Java_com_bigbluecup_android_PreferencesActivity_readStringConfigValue(JNIEnv *env, jobject object, jint id, jstring value) { + switch (id) { + case CONFIG_TRANSLATION: + return env->NewStringUTF(&psp_translation[0]); + break; + } + } + + + JNIEXPORT void JNICALL + Java_com_bigbluecup_android_PreferencesActivity_setIntConfigValue(JNIEnv *env, jobject object, jint id, jint value) { + switch (id) { + case CONFIG_IGNORE_ACSETUP: + psp_ignore_acsetup_cfg_file = value; + break; + case CONFIG_CLEAR_CACHE: + psp_clear_cache_on_room_change = value; + break; + case CONFIG_AUDIO_RATE: + psp_audio_samplerate = value; + break; + case CONFIG_AUDIO_ENABLED: + psp_audio_enabled = value; + break; + case CONFIG_AUDIO_THREADED: + psp_audio_multithreaded = value; + break; + case CONFIG_AUDIO_CACHESIZE: + psp_audio_cachesize = value; + break; + case CONFIG_MIDI_ENABLED: + psp_midi_enabled = value; + break; + case CONFIG_MIDI_PRELOAD: + psp_midi_preload_patches = value; + break; + case CONFIG_VIDEO_FRAMEDROP: + psp_video_framedrop = value; + break; + case CONFIG_GFX_RENDERER: + psp_gfx_renderer = value; + break; + case CONFIG_GFX_SMOOTHING: + psp_gfx_smoothing = value; + break; + case CONFIG_GFX_SCALING: + psp_gfx_scaling = value; + break; + case CONFIG_GFX_SS: + psp_gfx_super_sampling = value; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + psp_gfx_smooth_sprites = value; + break; + case CONFIG_ROTATION: + psp_rotation = value; + break; + case CONFIG_ENABLED: + psp_config_enabled = value; + break; + case CONFIG_DEBUG_FPS: + display_fps = (value == 1) ? 2 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + psp_debug_write_to_logcat = value; + break; + case CONFIG_MOUSE_METHOD: + config_mouse_control_mode = value; + break; + case CONFIG_MOUSE_LONGCLICK: + config_mouse_longclick = value; + break; + default: + break; + } + } + + + JNIEXPORT void JNICALL + Java_com_bigbluecup_android_PreferencesActivity_setStringConfigValue(JNIEnv *env, jobject object, jint id, jstring value) { + const char *cstring = env->GetStringUTFChars(value, NULL); + + switch (id) { + case CONFIG_TRANSLATION: + strcpy(psp_translation, cstring); + break; + default: + break; + } + + env->ReleaseStringUTFChars(value, cstring); + } + + + JNIEXPORT jint JNICALL + Java_com_bigbluecup_android_PreferencesActivity_getAvailableTranslations(JNIEnv *env, jobject object, jobjectArray translations) { + int i = 0; + int length; + DIR *dir; + struct dirent *entry; + char buffer[200]; + + dir = opendir("."); + if (dir) { + while ((entry = readdir(dir)) != 0) { + length = strlen(entry->d_name); + if (length > 4) { + if (ags_stricmp(&entry->d_name[length - 4], ".tra") == 0) { + memset(buffer, 0, 200); + strncpy(buffer, entry->d_name, length - 4); + psp_translations[i] = (char *)malloc(strlen(buffer) + 1); + strcpy(psp_translations[i], buffer); + env->SetObjectArrayElement(translations, i, env->NewStringUTF(&buffer[0])); + i++; + } + } + } + closedir(dir); + } + + return i; + } + + + JNIEXPORT void JNICALL + Java_com_bigbluecup_android_EngineGlue_pauseEngine(JNIEnv *env, jobject object) { + PauseGame(); + } + + JNIEXPORT void JNICALL + Java_com_bigbluecup_android_EngineGlue_resumeEngine(JNIEnv *env, jobject object) { + UnPauseGame(); + } + + + JNIEXPORT void JNICALL + Java_com_bigbluecup_android_EngineGlue_shutdownEngine(JNIEnv *env, jobject object) { + want_exit = 1; + } + + + JNIEXPORT jboolean JNICALL + Java_com_bigbluecup_android_EngineGlue_startEngine(JNIEnv *env, jobject object, jclass stringclass, jstring filename, jstring directory, jstring appDirectory, jboolean loadLastSave) { + // Get JNI interfaces. + java_object = env->NewGlobalRef(object); + java_environment = env; + java_class = (jclass)java_environment->NewGlobalRef(java_environment->GetObjectClass(object)); + java_messageCallback = java_environment->GetMethodID(java_class, "showMessage", "(Ljava/lang/String;)V"); + java_blockExecution = java_environment->GetMethodID(java_class, "blockExecution", "()V"); + java_setRotation = java_environment->GetMethodID(java_class, "setRotation", "(I)V"); + java_enableLongclick = java_environment->GetMethodID(java_class, "enableLongclick", "()V"); + + // Initialize JNI for Allegro. + android_allegro_initialize_jni(java_environment, java_class, java_object); + + // Get the file to run from Java. + const char *cpath = java_environment->GetStringUTFChars(filename, NULL); + strcpy(psp_game_file_name, cpath); + java_environment->ReleaseStringUTFChars(filename, cpath); + + // Get the base directory (usually "/sdcard/ags"). + const char *cdirectory = java_environment->GetStringUTFChars(directory, NULL); + chdir(cdirectory); + strcpy(android_base_directory, cdirectory); + java_environment->ReleaseStringUTFChars(directory, cdirectory); + + // Get the app directory (something like "/data/data/com.bigbluecup.android.launcher") + const char *cappDirectory = java_environment->GetStringUTFChars(appDirectory, NULL); + strcpy(android_app_directory, cappDirectory); + java_environment->ReleaseStringUTFChars(appDirectory, cappDirectory); + + // Reset configuration. + ResetConfiguration(); + + // Read general configuration. + ReadConfiguration(ANDROID_CONFIG_FILENAME, true); + + // Get the games path. + char path[256]; + strcpy(path, psp_game_file_name); + int lastindex = strlen(path) - 1; + while (path[lastindex] != '/') { + path[lastindex] = 0; + lastindex--; + } + chdir(path); + + setenv("ULTRADIR", "..", 1); + + // Read game specific configuration. + ReadConfiguration(ANDROID_CONFIG_FILENAME, false); + + // Set the screen rotation. + if (psp_rotation > 0) + java_environment->CallVoidMethod(java_object, java_setRotation, psp_rotation); + + if (config_mouse_longclick > 0) + java_environment->CallVoidMethod(java_object, java_enableLongclick); + + psp_load_latest_savegame = loadLastSave; + + // Start the engine main function. + main(1, &psp_game_file_name_pointer); + + // Explicitly quit here, otherwise the app will hang forever. + exit(0); + + return true; + } + + + void selectLatestSavegame() { + DIR *dir; + struct dirent *entry; + struct stat statBuffer; + char buffer[200]; + time_t lastTime = 0; + + dir = opendir(saveGameDirectory); + + if (dir) { + while ((entry = readdir(dir)) != 0) { + if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) { + if (ags_stricmp(entry->d_name, "agssave.999") != 0) { + strcpy(buffer, saveGameDirectory); + strcat(buffer, entry->d_name); + stat(buffer, &statBuffer); + if (statBuffer.st_mtime > lastTime) { + strcpy(lastSaveGameName, buffer); + loadSaveGameOnStartup = lastSaveGameName; + lastTime = statBuffer.st_mtime; + } + } + } + } + closedir(dir); + } + } -JNIEXPORT void JNICALL - Java_com_bigbluecup_android_EngineGlue_pauseEngine(JNIEnv* env, jobject object) -{ - PauseGame(); -} - -JNIEXPORT void JNICALL - Java_com_bigbluecup_android_EngineGlue_resumeEngine(JNIEnv* env, jobject object) -{ - UnPauseGame(); } -JNIEXPORT void JNICALL - Java_com_bigbluecup_android_EngineGlue_shutdownEngine(JNIEnv* env, jobject object) -{ - want_exit = 1; -} +int ReadInteger(int *variable, const ConfigTree &cfg, char *section, char *name, int minimum, int maximum, int default_value) { + if (reset_configuration) { + *variable = default_value; + return 0; + } + int temp = INIreadint(cfg, section, name); -JNIEXPORT jboolean JNICALL - Java_com_bigbluecup_android_EngineGlue_startEngine(JNIEnv* env, jobject object, jclass stringclass, jstring filename, jstring directory, jstring appDirectory, jboolean loadLastSave) -{ - // Get JNI interfaces. - java_object = env->NewGlobalRef(object); - java_environment = env; - java_class = (jclass)java_environment->NewGlobalRef(java_environment->GetObjectClass(object)); - java_messageCallback = java_environment->GetMethodID(java_class, "showMessage", "(Ljava/lang/String;)V"); - java_blockExecution = java_environment->GetMethodID(java_class, "blockExecution", "()V"); - java_setRotation = java_environment->GetMethodID(java_class, "setRotation", "(I)V"); - java_enableLongclick = java_environment->GetMethodID(java_class, "enableLongclick", "()V"); - - // Initialize JNI for Allegro. - android_allegro_initialize_jni(java_environment, java_class, java_object); - - // Get the file to run from Java. - const char* cpath = java_environment->GetStringUTFChars(filename, NULL); - strcpy(psp_game_file_name, cpath); - java_environment->ReleaseStringUTFChars(filename, cpath); - - // Get the base directory (usually "/sdcard/ags"). - const char* cdirectory = java_environment->GetStringUTFChars(directory, NULL); - chdir(cdirectory); - strcpy(android_base_directory, cdirectory); - java_environment->ReleaseStringUTFChars(directory, cdirectory); - - // Get the app directory (something like "/data/data/com.bigbluecup.android.launcher") - const char* cappDirectory = java_environment->GetStringUTFChars(appDirectory, NULL); - strcpy(android_app_directory, cappDirectory); - java_environment->ReleaseStringUTFChars(appDirectory, cappDirectory); - - // Reset configuration. - ResetConfiguration(); - - // Read general configuration. - ReadConfiguration(ANDROID_CONFIG_FILENAME, true); - - // Get the games path. - char path[256]; - strcpy(path, psp_game_file_name); - int lastindex = strlen(path) - 1; - while (path[lastindex] != '/') - { - path[lastindex] = 0; - lastindex--; - } - chdir(path); - - setenv("ULTRADIR", "..", 1); - - // Read game specific configuration. - ReadConfiguration(ANDROID_CONFIG_FILENAME, false); - - // Set the screen rotation. - if (psp_rotation > 0) - java_environment->CallVoidMethod(java_object, java_setRotation, psp_rotation); - - if (config_mouse_longclick > 0) - java_environment->CallVoidMethod(java_object, java_enableLongclick); - - psp_load_latest_savegame = loadLastSave; - - // Start the engine main function. - main(1, &psp_game_file_name_pointer); - - // Explicitly quit here, otherwise the app will hang forever. - exit(0); - - return true; -} + if (temp == -1) + return 0; + if ((temp < minimum) || (temp > maximum)) + temp = default_value; -void selectLatestSavegame() -{ - DIR* dir; - struct dirent* entry; - struct stat statBuffer; - char buffer[200]; - time_t lastTime = 0; - - dir = opendir(saveGameDirectory); - - if (dir) - { - while ((entry = readdir(dir)) != 0) - { - if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) - { - if (ags_stricmp(entry->d_name, "agssave.999") != 0) - { - strcpy(buffer, saveGameDirectory); - strcat(buffer, entry->d_name); - stat(buffer, &statBuffer); - if (statBuffer.st_mtime > lastTime) - { - strcpy(lastSaveGameName, buffer); - loadSaveGameOnStartup = lastSaveGameName; - lastTime = statBuffer.st_mtime; - } - } - } - } - closedir(dir); - } -} + *variable = temp; + return 1; } -int ReadInteger(int* variable, const ConfigTree &cfg, char* section, char* name, int minimum, int maximum, int default_value) -{ - if (reset_configuration) - { - *variable = default_value; - return 0; - } - - int temp = INIreadint(cfg, section, name); - if (temp == -1) - return 0; +int ReadString(char *variable, const ConfigTree &cfg, char *section, char *name, char *default_value) { + if (reset_configuration) { + strcpy(variable, default_value); + return 0; + } - if ((temp < minimum) || (temp > maximum)) - temp = default_value; + String temp; + if (!INIreaditem(cfg, section, name, temp)) + temp = default_value; - *variable = temp; + strcpy(variable, temp); - return 1; + return 1; } -int ReadString(char* variable, const ConfigTree &cfg, char* section, char* name, char* default_value) -{ - if (reset_configuration) - { - strcpy(variable, default_value); - return 0; - } - - String temp; - if (!INIreaditem(cfg, section, name, temp)) - temp = default_value; +void ResetConfiguration() { + reset_configuration = true; - strcpy(variable, temp); + ReadConfiguration(ANDROID_CONFIG_FILENAME, true); - return 1; + reset_configuration = false; } -void ResetConfiguration() -{ - reset_configuration = true; - - ReadConfiguration(ANDROID_CONFIG_FILENAME, true); - - reset_configuration = false; -} - - - -bool ReadConfiguration(char* filename, bool read_everything) -{ - ConfigTree cfg; - if (IniUtil::Read(filename, cfg) || reset_configuration) - { +bool ReadConfiguration(char *filename, bool read_everything) { + ConfigTree cfg; + if (IniUtil::Read(filename, cfg) || reset_configuration) { // ReadInteger((int*)&psp_disable_powersaving, "misc", "disable_power_saving", 0, 1, 1); // ReadInteger((int*)&psp_return_to_menu, "misc", "return_to_menu", 0, 1, 1); - ReadString(&psp_translation[0], cfg, "misc", "translation", "default"); + ReadString(&psp_translation[0], cfg, "misc", "translation", "default"); - ReadInteger((int*)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0); - if (!psp_config_enabled && !read_everything) - return true; + ReadInteger((int *)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0); + if (!psp_config_enabled && !read_everything) + return true; - ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0); - ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0); - if (display_fps == 1) - display_fps = 2; + ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0); + ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0); + if (display_fps == 1) + display_fps = 2; - ReadInteger((int*)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0); + ReadInteger((int *)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0); // ReadInteger((int*)&psp_ignore_acsetup_cfg_file, "compatibility", "ignore_acsetup_cfg_file", 0, 1, 0); - ReadInteger((int*)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0); + ReadInteger((int *)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0); - ReadInteger((int*)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100); - ReadInteger((int*)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1); - ReadInteger((int*)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1); - ReadInteger((int*)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10); + ReadInteger((int *)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100); + ReadInteger((int *)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1); + ReadInteger((int *)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1); + ReadInteger((int *)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10); - ReadInteger((int*)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1); - ReadInteger((int*)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0); + ReadInteger((int *)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1); + ReadInteger((int *)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0); - ReadInteger((int*)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0); + ReadInteger((int *)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0); - ReadInteger((int*)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0); - ReadInteger((int*)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1); - ReadInteger((int*)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1); - ReadInteger((int*)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0); - ReadInteger((int*)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0); + ReadInteger((int *)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0); + ReadInteger((int *)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1); + ReadInteger((int *)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1); + ReadInteger((int *)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0); + ReadInteger((int *)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0); - ReadInteger((int*)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0); - ReadInteger((int*)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1); + ReadInteger((int *)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0); + ReadInteger((int *)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1); - return true; - } + return true; + } - return false; + return false; } int AGSAndroid::CDPlayerCommand(int cmdd, int datt) { - return 1;//cd_player_control(cmdd, datt); + return 1;//cd_player_control(cmdd, datt); } void AGSAndroid::DisplayAlert(const char *text, ...) { - char displbuf[2000]; - va_list ap; - va_start(ap, text); - vsprintf(displbuf, text, ap); - va_end(ap); + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); - // It is possible that this is called from a thread that is not yet known - // to the Java VM. So attach it first before displaying the message. - JNIEnv* thread_env; - android_jni_vm->AttachCurrentThread(&thread_env, NULL); + // It is possible that this is called from a thread that is not yet known + // to the Java VM. So attach it first before displaying the message. + JNIEnv *thread_env; + android_jni_vm->AttachCurrentThread(&thread_env, NULL); - __android_log_print(ANDROID_LOG_DEBUG, "AGSNative", "%s", displbuf); + __android_log_print(ANDROID_LOG_DEBUG, "AGSNative", "%s", displbuf); - jstring java_string = thread_env->NewStringUTF(displbuf); - thread_env->CallVoidMethod(java_object, java_messageCallback, java_string); - usleep(1000 * 1000); - thread_env->CallVoidMethod(java_object, java_blockExecution); + jstring java_string = thread_env->NewStringUTF(displbuf); + thread_env->CallVoidMethod(java_object, java_messageCallback, java_string); + usleep(1000 * 1000); + thread_env->CallVoidMethod(java_object, java_blockExecution); // android_jni_vm->DetachCurrentThread(); } void AGSAndroid::Delay(int millis) { - usleep(millis * 1000); + usleep(millis * 1000); } unsigned long AGSAndroid::GetDiskFreeSpaceMB() { - // placeholder - return 100; + // placeholder + return 100; } -const char* AGSAndroid::GetNoMouseErrorString() { - return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +const char *AGSAndroid::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; } eScriptSystemOSID AGSAndroid::GetSystemOSID() { - return eOS_Android; + return eOS_Android; } int AGSAndroid::InitializeCDPlayer() { - return 1;//cd_player_init(); + return 1;//cd_player_init(); } void AGSAndroid::PostAllegroExit() { - java_environment->DeleteGlobalRef(java_class); + java_environment->DeleteGlobalRef(java_class); } void AGSAndroid::SetGameWindowIcon() { - // do nothing + // do nothing } -void AGSAndroid::WriteStdOut(const char *fmt, ...) -{ - // TODO: this check should probably be done once when setting up output targets for logging - if (psp_debug_write_to_logcat) - { - va_list args; - va_start(args, fmt); - __android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args); - // NOTE: __android_log_* functions add trailing '\n' - va_end(args); - } +void AGSAndroid::WriteStdOut(const char *fmt, ...) { + // TODO: this check should probably be done once when setting up output targets for logging + if (psp_debug_write_to_logcat) { + va_list args; + va_start(args, fmt); + __android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args); + // NOTE: __android_log_* functions add trailing '\n' + va_end(args); + } } -void AGSAndroid::WriteStdErr(const char *fmt, ...) -{ - // TODO: find out if Android needs separate implementation for stderr - if (psp_debug_write_to_logcat) - { - va_list args; - va_start(args, fmt); - __android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args); - // NOTE: __android_log_* functions add trailing '\n' - va_end(args); - } +void AGSAndroid::WriteStdErr(const char *fmt, ...) { + // TODO: find out if Android needs separate implementation for stderr + if (psp_debug_write_to_logcat) { + va_list args; + va_start(args, fmt); + __android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args); + // NOTE: __android_log_* functions add trailing '\n' + va_end(args); + } } void AGSAndroid::ShutdownCDPlayer() { - //cd_exit(); + //cd_exit(); } -const char *AGSAndroid::GetAppOutputDirectory() -{ - return android_base_directory; +const char *AGSAndroid::GetAppOutputDirectory() { + return android_base_directory; } -AGSPlatformDriver* AGSPlatformDriver::GetDriver() { - if (instance == NULL) - instance = new AGSAndroid(); +AGSPlatformDriver *AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSAndroid(); - return instance; + return instance; } #endif diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index 94649d08aacf..3c64c6759ae3 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -50,7 +50,7 @@ using namespace AGS::Engine; // 16 milliseconds is rough period for 60fps const auto MaximumDelayBetweenPolling = std::chrono::milliseconds(16); -AGSPlatformDriver* AGSPlatformDriver::instance = nullptr; +AGSPlatformDriver *AGSPlatformDriver::instance = nullptr; AGSPlatformDriver *platform = nullptr; // ******** DEFAULT IMPLEMENTATIONS ******* @@ -63,114 +63,109 @@ void AGSPlatformDriver::DisplaySwitchIn() { } void AGSPlatformDriver::PauseApplication() { } void AGSPlatformDriver::ResumeApplication() { } void AGSPlatformDriver::GetSystemDisplayModes(std::vector &dms) { } -bool AGSPlatformDriver::EnterFullscreenMode(const DisplayMode &dm) { return true; } -bool AGSPlatformDriver::ExitFullscreenMode() { return true; } +bool AGSPlatformDriver::EnterFullscreenMode(const DisplayMode &dm) { + return true; +} +bool AGSPlatformDriver::ExitFullscreenMode() { + return true; +} void AGSPlatformDriver::AdjustWindowStyleForFullscreen() { } void AGSPlatformDriver::AdjustWindowStyleForWindowed() { } void AGSPlatformDriver::RegisterGameWithGameExplorer() { } void AGSPlatformDriver::UnRegisterGameWithGameExplorer() { } -void AGSPlatformDriver::PlayVideo(const char* name, int skip, int flags) {} +void AGSPlatformDriver::PlayVideo(const char *name, int skip, int flags) {} -const char* AGSPlatformDriver::GetAllegroFailUserHint() -{ - return "Make sure you have latest version of Allegro 4 libraries installed, and your system is running in graphical mode."; +const char *AGSPlatformDriver::GetAllegroFailUserHint() { + return "Make sure you have latest version of Allegro 4 libraries installed, and your system is running in graphical mode."; } -const char *AGSPlatformDriver::GetDiskWriteAccessTroubleshootingText() -{ - return "Make sure you have write permissions, and also check the disk's free space."; +const char *AGSPlatformDriver::GetDiskWriteAccessTroubleshootingText() { + return "Make sure you have write permissions, and also check the disk's free space."; } void AGSPlatformDriver::GetSystemTime(ScriptDateTime *sdt) { - time_t t = time(nullptr); - - //note: subject to year 2038 problem due to shoving time_t in an integer - sdt->rawUnixTime = static_cast(t); - - struct tm *newtime = localtime(&t); - sdt->hour = newtime->tm_hour; - sdt->minute = newtime->tm_min; - sdt->second = newtime->tm_sec; - sdt->day = newtime->tm_mday; - sdt->month = newtime->tm_mon + 1; - sdt->year = newtime->tm_year + 1900; + time_t t = time(nullptr); + + //note: subject to year 2038 problem due to shoving time_t in an integer + sdt->rawUnixTime = static_cast(t); + + struct tm *newtime = localtime(&t); + sdt->hour = newtime->tm_hour; + sdt->minute = newtime->tm_min; + sdt->second = newtime->tm_sec; + sdt->day = newtime->tm_mday; + sdt->month = newtime->tm_mon + 1; + sdt->year = newtime->tm_year + 1900; } void AGSPlatformDriver::WriteStdOut(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - printf("\n"); - fflush(stdout); + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + printf("\n"); + fflush(stdout); } -void AGSPlatformDriver::WriteStdErr(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, "\n"); - fflush(stdout); +void AGSPlatformDriver::WriteStdErr(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + fflush(stdout); } void AGSPlatformDriver::YieldCPU() { - // NOTE: this is called yield, but if we actually yield instead of delay, - // we get a massive increase in CPU usage. - this->Delay(1); - //std::this_thread::yield(); + // NOTE: this is called yield, but if we actually yield instead of delay, + // we get a massive increase in CPU usage. + this->Delay(1); + //std::this_thread::yield(); } -void AGSPlatformDriver::InitialiseAbufAtStartup() -{ - // because loading the game file accesses abuf, it must exist - // No no no, David Blain, no magic here :P - //abuf = BitmapHelper::CreateBitmap(10,10,8); +void AGSPlatformDriver::InitialiseAbufAtStartup() { + // because loading the game file accesses abuf, it must exist + // No no no, David Blain, no magic here :P + //abuf = BitmapHelper::CreateBitmap(10,10,8); } -void AGSPlatformDriver::FinishedUsingGraphicsMode() -{ - // don't need to do anything on any OS except DOS +void AGSPlatformDriver::FinishedUsingGraphicsMode() { + // don't need to do anything on any OS except DOS } -SetupReturnValue AGSPlatformDriver::RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out) -{ - return kSetup_Cancel; +SetupReturnValue AGSPlatformDriver::RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out) { + return kSetup_Cancel; } void AGSPlatformDriver::SetGameWindowIcon() { - // do nothing + // do nothing } -int AGSPlatformDriver::ConvertKeycodeToScanCode(int keycode) -{ - keycode -= ('A' - KEY_A); - return keycode; +int AGSPlatformDriver::ConvertKeycodeToScanCode(int keycode) { + keycode -= ('A' - KEY_A); + return keycode; } -bool AGSPlatformDriver::LockMouseToWindow() { return false; } +bool AGSPlatformDriver::LockMouseToWindow() { + return false; +} void AGSPlatformDriver::UnlockMouse() { } //----------------------------------------------- // IOutputHandler implementation //----------------------------------------------- -void AGSPlatformDriver::PrintMessage(const Common::DebugMessage &msg) -{ - if (_logToStdErr) - { - if (msg.GroupName.IsEmpty()) - WriteStdErr("%s", msg.Text.GetCStr()); - else - WriteStdErr("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr()); - } - else - { - if (msg.GroupName.IsEmpty()) - WriteStdOut("%s", msg.Text.GetCStr()); - else - WriteStdOut("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr()); - } +void AGSPlatformDriver::PrintMessage(const Common::DebugMessage &msg) { + if (_logToStdErr) { + if (msg.GroupName.IsEmpty()) + WriteStdErr("%s", msg.Text.GetCStr()); + else + WriteStdErr("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr()); + } else { + if (msg.GroupName.IsEmpty()) + WriteStdOut("%s", msg.Text.GetCStr()); + else + WriteStdOut("%s : %s", msg.GroupName.GetCStr(), msg.Text.GetCStr()); + } } // ********** CD Player Functions common to Win and Linux ******** @@ -181,66 +176,67 @@ void AGSPlatformDriver::PrintMessage(const Common::DebugMessage &msg) extern int use_cdplayer; extern int need_to_stop_cd; -int numcddrives=0; +int numcddrives = 0; int cd_player_init() { - int erro = cd_init(); - if (erro) return -1; - numcddrives=1; - use_cdplayer=1; - return 0; + int erro = cd_init(); + if (erro) return -1; + numcddrives = 1; + use_cdplayer = 1; + return 0; } int cd_player_control(int cmdd, int datt) { - // WINDOWS & LINUX VERSION - if (cmdd==1) { - if (cd_current_track() > 0) return 1; - return 0; - } - else if (cmdd==2) { - cd_play_from(datt); - need_to_stop_cd=1; - } - else if (cmdd==3) - cd_pause(); - else if (cmdd==4) - cd_resume(); - else if (cmdd==5) { - int first,last; - if (cd_get_tracks(&first,&last)==0) - return (last-first)+1; - else return 0; - } - else if (cmdd==6) - cd_eject(); - else if (cmdd==7) - cd_close(); - else if (cmdd==8) - return numcddrives; - else if (cmdd==9) ; - else quit("!CDAudio: Unknown command code"); - - return 0; + // WINDOWS & LINUX VERSION + if (cmdd == 1) { + if (cd_current_track() > 0) return 1; + return 0; + } else if (cmdd == 2) { + cd_play_from(datt); + need_to_stop_cd = 1; + } else if (cmdd == 3) + cd_pause(); + else if (cmdd == 4) + cd_resume(); + else if (cmdd == 5) { + int first, last; + if (cd_get_tracks(&first, &last) == 0) + return (last - first) + 1; + else return 0; + } else if (cmdd == 6) + cd_eject(); + else if (cmdd == 7) + cd_close(); + else if (cmdd == 8) + return numcddrives; + else if (cmdd == 9) ; + else quit("!CDAudio: Unknown command code"); + + return 0; } #endif // AGS_HAS_CD_AUDIO void AGSPlatformDriver::Delay(int millis) { - auto now = AGS_Clock::now(); - auto delayUntil = now + std::chrono::milliseconds(millis); - - for (;;) { - if (now >= delayUntil) { break; } - - auto duration = std::min(delayUntil - now, MaximumDelayBetweenPolling); - std::this_thread::sleep_for(duration); - now = AGS_Clock::now(); // update now - - if (now >= delayUntil) { break; } - - // don't allow it to check for debug messages, since this Delay() - // call might be from within a debugger polling loop - update_polled_mp3(); - now = AGS_Clock::now(); // update now - } + auto now = AGS_Clock::now(); + auto delayUntil = now + std::chrono::milliseconds(millis); + + for (;;) { + if (now >= delayUntil) { + break; + } + + auto duration = std::min(delayUntil - now, MaximumDelayBetweenPolling); + std::this_thread::sleep_for(duration); + now = AGS_Clock::now(); // update now + + if (now >= delayUntil) { + break; + } + + // don't allow it to check for debug messages, since this Delay() + // call might be from within a debugger polling loop + update_polled_mp3(); + now = AGS_Clock::now(); // update now + } } diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index c8b6975c6aac..03a7a6141605 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -35,137 +35,161 @@ #include "debug/outputhandler.h" #include "util/ini_util.h" -namespace AGS -{ - namespace Common { class Stream; } - namespace Engine { struct DisplayMode; } +namespace AGS { +namespace Common { +class Stream; +} +namespace Engine { +struct DisplayMode; +} } using namespace AGS; // FIXME later -enum eScriptSystemOSID -{ - eOS_DOS = 1, - eOS_Win, - eOS_Linux, - eOS_Mac, - eOS_Android, - eOS_iOS, - eOS_PSP +enum eScriptSystemOSID { + eOS_DOS = 1, + eOS_Win, + eOS_Linux, + eOS_Mac, + eOS_Android, + eOS_iOS, + eOS_PSP }; -enum SetupReturnValue -{ - kSetup_Cancel, - kSetup_Done, - kSetup_RunGame +enum SetupReturnValue { + kSetup_Cancel, + kSetup_Done, + kSetup_RunGame }; struct AGSPlatformDriver - // be used as a output target for logging system - : public AGS::Common::IOutputHandler -{ - virtual void AboutToQuitGame(); - virtual void Delay(int millis); - virtual void DisplayAlert(const char*, ...) = 0; - virtual void AttachToParentConsole(); - virtual int GetLastSystemError() { return errno; } - // Get root directory for storing per-game shared data - virtual const char *GetAllUsersDataDirectory() { return "."; } - // Get root directory for storing per-game saved games - virtual const char *GetUserSavedgamesDirectory() { return "."; } - // Get root directory for storing per-game user configuration files - virtual const char *GetUserConfigDirectory() { return "."; } - // Get directory for storing all-games user configuration files - virtual const char *GetUserGlobalConfigDirectory() { return "."; } - // Get default directory for program output (logs) - virtual const char *GetAppOutputDirectory() { return "."; } - // Returns array of characters illegal to use in file names - virtual const char *GetIllegalFileChars() { return "\\/"; } - virtual const char *GetDiskWriteAccessTroubleshootingText(); - virtual const char *GetGraphicsTroubleshootingText() { return ""; } - virtual unsigned long GetDiskFreeSpaceMB() = 0; - virtual const char* GetNoMouseErrorString() = 0; - // Tells whether build is capable of controlling mouse movement properly - virtual bool IsMouseControlSupported(bool windowed) { return false; } - // Tells whether this platform's backend library deals with mouse cursor - // virtual->real coordinate transformation itself (otherwise AGS engine should do it) - virtual bool IsBackendResponsibleForMouseScaling() { return false; } - virtual const char* GetAllegroFailUserHint(); - virtual eScriptSystemOSID GetSystemOSID() = 0; - virtual void GetSystemTime(ScriptDateTime*); - virtual void PlayVideo(const char* name, int skip, int flags); - virtual void InitialiseAbufAtStartup(); - virtual void PostAllegroInit(bool windowed); - virtual void PostAllegroExit() = 0; - virtual void FinishedUsingGraphicsMode(); - virtual SetupReturnValue RunSetup(const Common::ConfigTree &cfg_in, Common::ConfigTree &cfg_out); - virtual void SetGameWindowIcon(); - // Formats message and writes to standard platform's output; - // Always adds trailing '\n' after formatted string - virtual void WriteStdOut(const char *fmt, ...); - // Formats message and writes to platform's error output; - // Always adds trailing '\n' after formatted string - virtual void WriteStdErr(const char *fmt, ...); - virtual void YieldCPU(); - // Called when the game window is being switch out from - virtual void DisplaySwitchOut(); - // Called when the game window is being switch back to - virtual void DisplaySwitchIn(); - // Called when the application is being paused completely (e.g. when player alt+tabbed from it). - // This function should suspend any platform-specific realtime processing. - virtual void PauseApplication(); - // Called when the application is being resumed. - virtual void ResumeApplication(); - // Returns a list of supported display modes - virtual void GetSystemDisplayModes(std::vector &dms); - // Switch to system fullscreen mode; store previous mode parameters - virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm); - // Return back to the mode was before switching to fullscreen - virtual bool ExitFullscreenMode(); - // Adjust application window's parameters to suit fullscreen mode - virtual void AdjustWindowStyleForFullscreen(); - // Adjust application window's parameters to suit windowed mode - virtual void AdjustWindowStyleForWindowed(); - virtual void RegisterGameWithGameExplorer(); - virtual void UnRegisterGameWithGameExplorer(); - virtual int ConvertKeycodeToScanCode(int keyCode); - // Adjust window size to ensure it is in the supported limits - virtual void ValidateWindowSize(int &x, int &y, bool borderless) const {} - - virtual int InitializeCDPlayer() = 0; // return 0 on success - virtual int CDPlayerCommand(int cmdd, int datt) = 0; - virtual void ShutdownCDPlayer() = 0; - - virtual bool LockMouseToWindow(); - virtual void UnlockMouse(); - - static AGSPlatformDriver *GetDriver(); - - // Set whether PrintMessage should output to stdout or stderr - void SetOutputToErr(bool on) { _logToStdErr = on; } - // Set whether DisplayAlert is allowed to show modal GUIs on some systems; - // it will print to either stdout or stderr otherwise, depending on above flag - void SetGUIMode(bool on) { _guiMode = on; } - - //----------------------------------------------- - // IOutputHandler implementation - //----------------------------------------------- - // Writes to the standard platform's output, prepending "AGS: " prefix to the message - void PrintMessage(const AGS::Common::DebugMessage &msg) override; +// be used as a output target for logging system + : public AGS::Common::IOutputHandler { + virtual void AboutToQuitGame(); + virtual void Delay(int millis); + virtual void DisplayAlert(const char *, ...) = 0; + virtual void AttachToParentConsole(); + virtual int GetLastSystemError() { + return errno; + } + // Get root directory for storing per-game shared data + virtual const char *GetAllUsersDataDirectory() { + return "."; + } + // Get root directory for storing per-game saved games + virtual const char *GetUserSavedgamesDirectory() { + return "."; + } + // Get root directory for storing per-game user configuration files + virtual const char *GetUserConfigDirectory() { + return "."; + } + // Get directory for storing all-games user configuration files + virtual const char *GetUserGlobalConfigDirectory() { + return "."; + } + // Get default directory for program output (logs) + virtual const char *GetAppOutputDirectory() { + return "."; + } + // Returns array of characters illegal to use in file names + virtual const char *GetIllegalFileChars() { + return "\\/"; + } + virtual const char *GetDiskWriteAccessTroubleshootingText(); + virtual const char *GetGraphicsTroubleshootingText() { + return ""; + } + virtual unsigned long GetDiskFreeSpaceMB() = 0; + virtual const char *GetNoMouseErrorString() = 0; + // Tells whether build is capable of controlling mouse movement properly + virtual bool IsMouseControlSupported(bool windowed) { + return false; + } + // Tells whether this platform's backend library deals with mouse cursor + // virtual->real coordinate transformation itself (otherwise AGS engine should do it) + virtual bool IsBackendResponsibleForMouseScaling() { + return false; + } + virtual const char *GetAllegroFailUserHint(); + virtual eScriptSystemOSID GetSystemOSID() = 0; + virtual void GetSystemTime(ScriptDateTime *); + virtual void PlayVideo(const char *name, int skip, int flags); + virtual void InitialiseAbufAtStartup(); + virtual void PostAllegroInit(bool windowed); + virtual void PostAllegroExit() = 0; + virtual void FinishedUsingGraphicsMode(); + virtual SetupReturnValue RunSetup(const Common::ConfigTree &cfg_in, Common::ConfigTree &cfg_out); + virtual void SetGameWindowIcon(); + // Formats message and writes to standard platform's output; + // Always adds trailing '\n' after formatted string + virtual void WriteStdOut(const char *fmt, ...); + // Formats message and writes to platform's error output; + // Always adds trailing '\n' after formatted string + virtual void WriteStdErr(const char *fmt, ...); + virtual void YieldCPU(); + // Called when the game window is being switch out from + virtual void DisplaySwitchOut(); + // Called when the game window is being switch back to + virtual void DisplaySwitchIn(); + // Called when the application is being paused completely (e.g. when player alt+tabbed from it). + // This function should suspend any platform-specific realtime processing. + virtual void PauseApplication(); + // Called when the application is being resumed. + virtual void ResumeApplication(); + // Returns a list of supported display modes + virtual void GetSystemDisplayModes(std::vector &dms); + // Switch to system fullscreen mode; store previous mode parameters + virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm); + // Return back to the mode was before switching to fullscreen + virtual bool ExitFullscreenMode(); + // Adjust application window's parameters to suit fullscreen mode + virtual void AdjustWindowStyleForFullscreen(); + // Adjust application window's parameters to suit windowed mode + virtual void AdjustWindowStyleForWindowed(); + virtual void RegisterGameWithGameExplorer(); + virtual void UnRegisterGameWithGameExplorer(); + virtual int ConvertKeycodeToScanCode(int keyCode); + // Adjust window size to ensure it is in the supported limits + virtual void ValidateWindowSize(int &x, int &y, bool borderless) const {} + + virtual int InitializeCDPlayer() = 0; // return 0 on success + virtual int CDPlayerCommand(int cmdd, int datt) = 0; + virtual void ShutdownCDPlayer() = 0; + + virtual bool LockMouseToWindow(); + virtual void UnlockMouse(); + + static AGSPlatformDriver *GetDriver(); + + // Set whether PrintMessage should output to stdout or stderr + void SetOutputToErr(bool on) { + _logToStdErr = on; + } + // Set whether DisplayAlert is allowed to show modal GUIs on some systems; + // it will print to either stdout or stderr otherwise, depending on above flag + void SetGUIMode(bool on) { + _guiMode = on; + } + + //----------------------------------------------- + // IOutputHandler implementation + //----------------------------------------------- + // Writes to the standard platform's output, prepending "AGS: " prefix to the message + void PrintMessage(const AGS::Common::DebugMessage &msg) override; protected: - // TODO: this is a quick solution for IOutputHandler implementation - // logging either to stdout or stderr. Normally there should be - // separate implementation, one for each kind of output, but - // with both going through PlatformDriver need to figure a better - // design first. - bool _logToStdErr = false; - // Defines whether engine is allowed to display important warnings - // and errors by showing a message box kind of GUI. - bool _guiMode = false; + // TODO: this is a quick solution for IOutputHandler implementation + // logging either to stdout or stderr. Normally there should be + // separate implementation, one for each kind of output, but + // with both going through PlatformDriver need to figure a better + // design first. + bool _logToStdErr = false; + // Defines whether engine is allowed to display important warnings + // and errors by showing a message box kind of GUI. + bool _guiMode = false; private: - static AGSPlatformDriver *instance; + static AGSPlatformDriver *instance; }; #if defined (AGS_HAS_CD_AUDIO) diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp index e01dd821ce44..6d545dc316e7 100644 --- a/engines/ags/engine/platform/ios/acplios.cpp +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include @@ -40,9 +40,9 @@ using namespace AGS::Common; #define IOS_CONFIG_FILENAME "ios.cfg" -extern char* ios_document_directory; +extern char *ios_document_directory; -bool ReadConfiguration(char* filename, bool read_everything); +bool ReadConfiguration(char *filename, bool read_everything); void ResetConfiguration(); //int psp_return_to_menu = 1; @@ -51,7 +51,7 @@ int psp_clear_cache_on_room_change = 0; int psp_rotation = 0; int psp_config_enabled = 0; char psp_translation[100]; -char* psp_translations[100]; +char *psp_translations[100]; // Mouse option from Allegro. extern int config_mouse_control_mode; @@ -84,10 +84,10 @@ extern int display_fps; extern int want_exit; extern void PauseGame(); extern void UnPauseGame(); -extern int main(int argc,char*argv[]); +extern int main(int argc, char *argv[]); char psp_game_file_name[256]; -char* psp_game_file_name_pointer = psp_game_file_name; +char *psp_game_file_name_pointer = psp_game_file_name; bool psp_load_latest_savegame = false; extern char saveGameDirectory[260]; @@ -122,244 +122,235 @@ const int CONFIG_MOUSE_LONGCLICK = 20; struct AGSIOS : AGSPlatformDriver { - virtual int CDPlayerCommand(int cmdd, int datt); - virtual void Delay(int millis); - virtual void DisplayAlert(const char*, ...); - virtual const char *GetAppOutputDirectory(); - virtual unsigned long GetDiskFreeSpaceMB(); - virtual const char* GetNoMouseErrorString(); - virtual bool IsBackendResponsibleForMouseScaling() { return true; } - virtual eScriptSystemOSID GetSystemOSID(); - virtual int InitializeCDPlayer(); - virtual void PostAllegroExit(); - virtual void SetGameWindowIcon(); - virtual void ShutdownCDPlayer(); + virtual int CDPlayerCommand(int cmdd, int datt); + virtual void Delay(int millis); + virtual void DisplayAlert(const char *, ...); + virtual const char *GetAppOutputDirectory(); + virtual unsigned long GetDiskFreeSpaceMB(); + virtual const char *GetNoMouseErrorString(); + virtual bool IsBackendResponsibleForMouseScaling() { + return true; + } + virtual eScriptSystemOSID GetSystemOSID(); + virtual int InitializeCDPlayer(); + virtual void PostAllegroExit(); + virtual void SetGameWindowIcon(); + virtual void ShutdownCDPlayer(); }; -bool readConfigFile(char* directory) -{ - chdir(directory); +bool readConfigFile(char *directory) { + chdir(directory); - ResetConfiguration(); + ResetConfiguration(); - return ReadConfiguration(IOS_CONFIG_FILENAME, true); + return ReadConfiguration(IOS_CONFIG_FILENAME, true); } -bool writeConfigFile() -{ - FILE* config = fopen(IOS_CONFIG_FILENAME, "wb"); - if (config) - { - fprintf(config, "[misc]\n"); - fprintf(config, "config_enabled = %d\n", psp_config_enabled); - fprintf(config, "rotation = %d\n", psp_rotation); - fprintf(config, "translation = %s\n", psp_translation); - - fprintf(config, "[controls]\n"); - fprintf(config, "mouse_method = %d\n", config_mouse_control_mode); - fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick); - - fprintf(config, "[compatibility]\n"); - fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change); - - fprintf(config, "[sound]\n"); - fprintf(config, "samplerate = %d\n", psp_audio_samplerate ); - fprintf(config, "enabled = %d\n", psp_audio_enabled); - fprintf(config, "threaded = %d\n", psp_audio_multithreaded); - fprintf(config, "cache_size = %d\n", psp_audio_cachesize); - - fprintf(config, "[midi]\n"); - fprintf(config, "enabled = %d\n", psp_midi_enabled); - fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches); - - fprintf(config, "[video]\n"); - fprintf(config, "framedrop = %d\n", psp_video_framedrop); - - fprintf(config, "[graphics]\n"); - fprintf(config, "renderer = %d\n", psp_gfx_renderer); - fprintf(config, "smoothing = %d\n", psp_gfx_smoothing); - fprintf(config, "scaling = %d\n", psp_gfx_scaling); - fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling); - fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites); - - fprintf(config, "[debug]\n"); - fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0); - fprintf(config, "logging = %d\n", psp_debug_write_to_logcat); - - fclose(config); - - return true; - } +bool writeConfigFile() { + FILE *config = fopen(IOS_CONFIG_FILENAME, "wb"); + if (config) { + fprintf(config, "[misc]\n"); + fprintf(config, "config_enabled = %d\n", psp_config_enabled); + fprintf(config, "rotation = %d\n", psp_rotation); + fprintf(config, "translation = %s\n", psp_translation); + + fprintf(config, "[controls]\n"); + fprintf(config, "mouse_method = %d\n", config_mouse_control_mode); + fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick); + + fprintf(config, "[compatibility]\n"); + fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change); + + fprintf(config, "[sound]\n"); + fprintf(config, "samplerate = %d\n", psp_audio_samplerate); + fprintf(config, "enabled = %d\n", psp_audio_enabled); + fprintf(config, "threaded = %d\n", psp_audio_multithreaded); + fprintf(config, "cache_size = %d\n", psp_audio_cachesize); + + fprintf(config, "[midi]\n"); + fprintf(config, "enabled = %d\n", psp_midi_enabled); + fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches); - return false; + fprintf(config, "[video]\n"); + fprintf(config, "framedrop = %d\n", psp_video_framedrop); + + fprintf(config, "[graphics]\n"); + fprintf(config, "renderer = %d\n", psp_gfx_renderer); + fprintf(config, "smoothing = %d\n", psp_gfx_smoothing); + fprintf(config, "scaling = %d\n", psp_gfx_scaling); + fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling); + fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites); + + fprintf(config, "[debug]\n"); + fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0); + fprintf(config, "logging = %d\n", psp_debug_write_to_logcat); + + fclose(config); + + return true; + } + + return false; } -int readIntConfigValue(int id) -{ - switch (id) - { - case CONFIG_IGNORE_ACSETUP: - return psp_ignore_acsetup_cfg_file; - break; - case CONFIG_CLEAR_CACHE: - return psp_clear_cache_on_room_change; - break; - case CONFIG_AUDIO_RATE: - return psp_audio_samplerate; - break; - case CONFIG_AUDIO_ENABLED: - return psp_audio_enabled; - break; - case CONFIG_AUDIO_THREADED: - return psp_audio_multithreaded; - break; - case CONFIG_AUDIO_CACHESIZE: - return psp_audio_cachesize; - break; - case CONFIG_MIDI_ENABLED: - return psp_midi_enabled; - break; - case CONFIG_MIDI_PRELOAD: - return psp_midi_preload_patches; - break; - case CONFIG_VIDEO_FRAMEDROP: - return psp_video_framedrop; - break; - case CONFIG_GFX_RENDERER: - return psp_gfx_renderer; - break; - case CONFIG_GFX_SMOOTHING: - return psp_gfx_smoothing; - break; - case CONFIG_GFX_SCALING: - return psp_gfx_scaling; - break; - case CONFIG_GFX_SS: - return psp_gfx_super_sampling; - break; - case CONFIG_GFX_SMOOTH_SPRITES: - return psp_gfx_smooth_sprites; - break; - case CONFIG_ROTATION: - return psp_rotation; - break; - case CONFIG_ENABLED: - return psp_config_enabled; - break; - case CONFIG_DEBUG_FPS: - return (display_fps == 2) ? 1 : 0; - break; - case CONFIG_DEBUG_LOGCAT: - return psp_debug_write_to_logcat; - break; - case CONFIG_MOUSE_METHOD: - return config_mouse_control_mode; - break; - case CONFIG_MOUSE_LONGCLICK: - return config_mouse_longclick; - break; - default: - return 0; - break; - } +int readIntConfigValue(int id) { + switch (id) { + case CONFIG_IGNORE_ACSETUP: + return psp_ignore_acsetup_cfg_file; + break; + case CONFIG_CLEAR_CACHE: + return psp_clear_cache_on_room_change; + break; + case CONFIG_AUDIO_RATE: + return psp_audio_samplerate; + break; + case CONFIG_AUDIO_ENABLED: + return psp_audio_enabled; + break; + case CONFIG_AUDIO_THREADED: + return psp_audio_multithreaded; + break; + case CONFIG_AUDIO_CACHESIZE: + return psp_audio_cachesize; + break; + case CONFIG_MIDI_ENABLED: + return psp_midi_enabled; + break; + case CONFIG_MIDI_PRELOAD: + return psp_midi_preload_patches; + break; + case CONFIG_VIDEO_FRAMEDROP: + return psp_video_framedrop; + break; + case CONFIG_GFX_RENDERER: + return psp_gfx_renderer; + break; + case CONFIG_GFX_SMOOTHING: + return psp_gfx_smoothing; + break; + case CONFIG_GFX_SCALING: + return psp_gfx_scaling; + break; + case CONFIG_GFX_SS: + return psp_gfx_super_sampling; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + return psp_gfx_smooth_sprites; + break; + case CONFIG_ROTATION: + return psp_rotation; + break; + case CONFIG_ENABLED: + return psp_config_enabled; + break; + case CONFIG_DEBUG_FPS: + return (display_fps == 2) ? 1 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + return psp_debug_write_to_logcat; + break; + case CONFIG_MOUSE_METHOD: + return config_mouse_control_mode; + break; + case CONFIG_MOUSE_LONGCLICK: + return config_mouse_longclick; + break; + default: + return 0; + break; + } } -char* readStringConfigValue(int id) -{ - switch (id) - { - case CONFIG_TRANSLATION: - return &psp_translation[0]; - break; - } +char *readStringConfigValue(int id) { + switch (id) { + case CONFIG_TRANSLATION: + return &psp_translation[0]; + break; + } } -void setIntConfigValue(int id, int value) -{ - switch (id) - { - case CONFIG_IGNORE_ACSETUP: - psp_ignore_acsetup_cfg_file = value; - break; - case CONFIG_CLEAR_CACHE: - psp_clear_cache_on_room_change = value; - break; - case CONFIG_AUDIO_RATE: - psp_audio_samplerate = value; - break; - case CONFIG_AUDIO_ENABLED: - psp_audio_enabled = value; - break; - case CONFIG_AUDIO_THREADED: - psp_audio_multithreaded = value; - break; - case CONFIG_AUDIO_CACHESIZE: - psp_audio_cachesize = value; - break; - case CONFIG_MIDI_ENABLED: - psp_midi_enabled = value; - break; - case CONFIG_MIDI_PRELOAD: - psp_midi_preload_patches = value; - break; - case CONFIG_VIDEO_FRAMEDROP: - psp_video_framedrop = value; - break; - case CONFIG_GFX_RENDERER: - psp_gfx_renderer = value; - break; - case CONFIG_GFX_SMOOTHING: - psp_gfx_smoothing = value; - break; - case CONFIG_GFX_SCALING: - psp_gfx_scaling = value; - break; - case CONFIG_GFX_SS: - psp_gfx_super_sampling = value; - break; - case CONFIG_GFX_SMOOTH_SPRITES: - psp_gfx_smooth_sprites = value; - break; - case CONFIG_ROTATION: - psp_rotation = value; - break; - case CONFIG_ENABLED: - psp_config_enabled = value; - break; - case CONFIG_DEBUG_FPS: - display_fps = (value == 1) ? 2 : 0; - break; - case CONFIG_DEBUG_LOGCAT: - psp_debug_write_to_logcat = value; - break; - case CONFIG_MOUSE_METHOD: - config_mouse_control_mode = value; - break; - case CONFIG_MOUSE_LONGCLICK: - config_mouse_longclick = value; - break; - default: - break; - } +void setIntConfigValue(int id, int value) { + switch (id) { + case CONFIG_IGNORE_ACSETUP: + psp_ignore_acsetup_cfg_file = value; + break; + case CONFIG_CLEAR_CACHE: + psp_clear_cache_on_room_change = value; + break; + case CONFIG_AUDIO_RATE: + psp_audio_samplerate = value; + break; + case CONFIG_AUDIO_ENABLED: + psp_audio_enabled = value; + break; + case CONFIG_AUDIO_THREADED: + psp_audio_multithreaded = value; + break; + case CONFIG_AUDIO_CACHESIZE: + psp_audio_cachesize = value; + break; + case CONFIG_MIDI_ENABLED: + psp_midi_enabled = value; + break; + case CONFIG_MIDI_PRELOAD: + psp_midi_preload_patches = value; + break; + case CONFIG_VIDEO_FRAMEDROP: + psp_video_framedrop = value; + break; + case CONFIG_GFX_RENDERER: + psp_gfx_renderer = value; + break; + case CONFIG_GFX_SMOOTHING: + psp_gfx_smoothing = value; + break; + case CONFIG_GFX_SCALING: + psp_gfx_scaling = value; + break; + case CONFIG_GFX_SS: + psp_gfx_super_sampling = value; + break; + case CONFIG_GFX_SMOOTH_SPRITES: + psp_gfx_smooth_sprites = value; + break; + case CONFIG_ROTATION: + psp_rotation = value; + break; + case CONFIG_ENABLED: + psp_config_enabled = value; + break; + case CONFIG_DEBUG_FPS: + display_fps = (value == 1) ? 2 : 0; + break; + case CONFIG_DEBUG_LOGCAT: + psp_debug_write_to_logcat = value; + break; + case CONFIG_MOUSE_METHOD: + config_mouse_control_mode = value; + break; + case CONFIG_MOUSE_LONGCLICK: + config_mouse_longclick = value; + break; + default: + break; + } } -void setStringConfigValue(int id, char* value) -{ - switch (id) - { - case CONFIG_TRANSLATION: - strcpy(psp_translation, value); - break; - default: - break; - } +void setStringConfigValue(int id, char *value) { + switch (id) { + case CONFIG_TRANSLATION: + strcpy(psp_translation, value); + break; + default: + break; + } } /* @@ -400,253 +391,237 @@ int getAvailableTranslations(char* translations) -void selectLatestSavegame() -{ - DIR* dir; - struct dirent* entry; - struct stat statBuffer; - char buffer[200]; - time_t lastTime = 0; - - dir = opendir(saveGameDirectory); - - if (dir) - { - while ((entry = readdir(dir)) != 0) - { - if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) - { - if (ags_stricmp(entry->d_name, "agssave.999") != 0) - { - strcpy(buffer, saveGameDirectory); - strcat(buffer, entry->d_name); - stat(buffer, &statBuffer); - if (statBuffer.st_mtime > lastTime) - { - strcpy(lastSaveGameName, buffer); - loadSaveGameOnStartup = lastSaveGameName; - lastTime = statBuffer.st_mtime; - } - } - } - } - closedir(dir); - } +void selectLatestSavegame() { + DIR *dir; + struct dirent *entry; + struct stat statBuffer; + char buffer[200]; + time_t lastTime = 0; + + dir = opendir(saveGameDirectory); + + if (dir) { + while ((entry = readdir(dir)) != 0) { + if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) { + if (ags_stricmp(entry->d_name, "agssave.999") != 0) { + strcpy(buffer, saveGameDirectory); + strcat(buffer, entry->d_name); + stat(buffer, &statBuffer); + if (statBuffer.st_mtime > lastTime) { + strcpy(lastSaveGameName, buffer); + loadSaveGameOnStartup = lastSaveGameName; + lastTime = statBuffer.st_mtime; + } + } + } + } + closedir(dir); + } } -int ReadInteger(int* variable, const ConfigTree &cfg, char* section, char* name, int minimum, int maximum, int default_value) -{ - if (reset_configuration) - { - *variable = default_value; - return 0; - } +int ReadInteger(int *variable, const ConfigTree &cfg, char *section, char *name, int minimum, int maximum, int default_value) { + if (reset_configuration) { + *variable = default_value; + return 0; + } - int temp = INIreadint(cfg, section, name); + int temp = INIreadint(cfg, section, name); - if (temp == -1) - return 0; + if (temp == -1) + return 0; - if ((temp < minimum) || (temp > maximum)) - temp = default_value; + if ((temp < minimum) || (temp > maximum)) + temp = default_value; - *variable = temp; + *variable = temp; - return 1; + return 1; } -int ReadString(char* variable, const ConfigTree &cfg, char* section, char* name, char* default_value) -{ - if (reset_configuration) - { - strcpy(variable, default_value); - return 0; - } +int ReadString(char *variable, const ConfigTree &cfg, char *section, char *name, char *default_value) { + if (reset_configuration) { + strcpy(variable, default_value); + return 0; + } - String temp; - if (!INIreaditem(cfg, section, name, temp)) - temp = default_value; + String temp; + if (!INIreaditem(cfg, section, name, temp)) + temp = default_value; - strcpy(variable, temp); + strcpy(variable, temp); - return 1; + return 1; } -void ResetConfiguration() -{ - reset_configuration = true; +void ResetConfiguration() { + reset_configuration = true; - ReadConfiguration(IOS_CONFIG_FILENAME, true); + ReadConfiguration(IOS_CONFIG_FILENAME, true); - reset_configuration = false; + reset_configuration = false; } -bool ReadConfiguration(char* filename, bool read_everything) -{ - ConfigTree cfg; - if (IniUtil::Read(filename, cfg) || reset_configuration) - { +bool ReadConfiguration(char *filename, bool read_everything) { + ConfigTree cfg; + if (IniUtil::Read(filename, cfg) || reset_configuration) { // ReadInteger((int*)&psp_disable_powersaving, "misc", "disable_power_saving", 0, 1, 1); // ReadInteger((int*)&psp_return_to_menu, "misc", "return_to_menu", 0, 1, 1); - ReadString(&psp_translation[0], cfg, "misc", "translation", "default"); + ReadString(&psp_translation[0], cfg, "misc", "translation", "default"); - ReadInteger((int*)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0); - if (!psp_config_enabled && !read_everything) - return true; + ReadInteger((int *)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0); + if (!psp_config_enabled && !read_everything) + return true; - ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0); - ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0); - if (display_fps == 1) - display_fps = 2; + ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0); + ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0); + if (display_fps == 1) + display_fps = 2; - ReadInteger((int*)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0); + ReadInteger((int *)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0); // ReadInteger((int*)&psp_ignore_acsetup_cfg_file, "compatibility", "ignore_acsetup_cfg_file", 0, 1, 0); - ReadInteger((int*)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0); + ReadInteger((int *)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0); - ReadInteger((int*)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100); - ReadInteger((int*)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1); - ReadInteger((int*)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1); - ReadInteger((int*)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10); + ReadInteger((int *)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100); + ReadInteger((int *)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1); + ReadInteger((int *)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1); + ReadInteger((int *)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10); - ReadInteger((int*)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1); - ReadInteger((int*)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0); + ReadInteger((int *)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1); + ReadInteger((int *)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0); - ReadInteger((int*)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0); + ReadInteger((int *)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0); - ReadInteger((int*)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0); - ReadInteger((int*)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1); - ReadInteger((int*)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1); - ReadInteger((int*)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0); - ReadInteger((int*)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0); + ReadInteger((int *)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0); + ReadInteger((int *)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1); + ReadInteger((int *)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1); + ReadInteger((int *)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0); + ReadInteger((int *)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0); - ReadInteger((int*)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0); - ReadInteger((int*)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1); + ReadInteger((int *)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0); + ReadInteger((int *)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1); - return true; - } + return true; + } - return false; + return false; } -extern void ios_show_message_box(char* buffer); +extern void ios_show_message_box(char *buffer); volatile int ios_wait_for_ui = 0; -void startEngine(char* filename, char* directory, int loadLastSave) -{ - strcpy(psp_game_file_name, filename); +void startEngine(char *filename, char *directory, int loadLastSave) { + strcpy(psp_game_file_name, filename); - // Get the base directory (usually "/sdcard/ags"). - chdir(directory); + // Get the base directory (usually "/sdcard/ags"). + chdir(directory); - // Reset configuration. - ResetConfiguration(); + // Reset configuration. + ResetConfiguration(); - // Read general configuration. - ReadConfiguration(IOS_CONFIG_FILENAME, true); + // Read general configuration. + ReadConfiguration(IOS_CONFIG_FILENAME, true); - // Get the games path. - char path[256]; - strcpy(path, psp_game_file_name); - int lastindex = strlen(path) - 1; - while (path[lastindex] != '/') - { - path[lastindex] = 0; - lastindex--; - } - chdir(path); - - setenv("ULTRADIR", "..", 1); + // Get the games path. + char path[256]; + strcpy(path, psp_game_file_name); + int lastindex = strlen(path) - 1; + while (path[lastindex] != '/') { + path[lastindex] = 0; + lastindex--; + } + chdir(path); - // Read game specific configuration. - ReadConfiguration(IOS_CONFIG_FILENAME, false); + setenv("ULTRADIR", "..", 1); - psp_load_latest_savegame = loadLastSave; + // Read game specific configuration. + ReadConfiguration(IOS_CONFIG_FILENAME, false); - // Start the engine main function. - main(1, &psp_game_file_name_pointer); - - // Explicitly quit here, otherwise the app will hang forever. - exit(0); + psp_load_latest_savegame = loadLastSave; + + // Start the engine main function. + main(1, &psp_game_file_name_pointer); + + // Explicitly quit here, otherwise the app will hang forever. + exit(0); } int AGSIOS::CDPlayerCommand(int cmdd, int datt) { - return 0;//cd_player_control(cmdd, datt); + return 0;//cd_player_control(cmdd, datt); } void AGSIOS::DisplayAlert(const char *text, ...) { - char displbuf[2000]; - va_list ap; - va_start(ap, text); - vsprintf(displbuf, text, ap); - va_end(ap); - printf("%s", displbuf); - ios_show_message_box(displbuf); - - while (ios_wait_for_ui) - usleep(200); + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + printf("%s", displbuf); + ios_show_message_box(displbuf); + + while (ios_wait_for_ui) + usleep(200); } void AGSIOS::Delay(int millis) { - usleep(millis); + usleep(millis); } unsigned long AGSIOS::GetDiskFreeSpaceMB() { - // placeholder - return 100; + // placeholder + return 100; } -const char* AGSIOS::GetNoMouseErrorString() { - return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +const char *AGSIOS::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; } eScriptSystemOSID AGSIOS::GetSystemOSID() { - return eOS_iOS; + return eOS_iOS; } int AGSIOS::InitializeCDPlayer() { - return 0;//cd_player_init(); + return 0;//cd_player_init(); } void AGSIOS::PostAllegroExit() { - // do nothing + // do nothing } void AGSIOS::SetGameWindowIcon() { - // do nothing + // do nothing } void AGSIOS::ShutdownCDPlayer() { - //cd_exit(); + //cd_exit(); } -const char *AGSIOS::GetAppOutputDirectory() -{ - return ios_document_directory; +const char *AGSIOS::GetAppOutputDirectory() { + return ios_document_directory; } -AGSPlatformDriver* AGSPlatformDriver::GetDriver() { - if (instance == NULL) - instance = new AGSIOS(); - return instance; +AGSPlatformDriver *AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSIOS(); + return instance; } #endif diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 3d041962bfd0..06491c2fa349 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -45,175 +45,160 @@ using AGS::Common::String; // Replace the default Allegro icon. The original defintion is in the // Allegro 4.4 source under "src/x/xwin.c". #include "icon.xpm" -void* allegro_icon = icon_xpm; +void *allegro_icon = icon_xpm; String CommonDataDirectory; String UserDataDirectory; struct AGSLinux : AGSPlatformDriver { - int CDPlayerCommand(int cmdd, int datt) override; - void DisplayAlert(const char*, ...) override; - const char *GetAllUsersDataDirectory() override; - const char *GetUserSavedgamesDirectory() override; - const char *GetUserConfigDirectory() override; - const char *GetUserGlobalConfigDirectory() override; - const char *GetAppOutputDirectory() override; - unsigned long GetDiskFreeSpaceMB() override; - const char* GetNoMouseErrorString() override; - const char* GetAllegroFailUserHint() override; - eScriptSystemOSID GetSystemOSID() override; - int InitializeCDPlayer() override; - void PostAllegroExit() override; - void SetGameWindowIcon() override; - void ShutdownCDPlayer() override; - bool LockMouseToWindow() override; - void UnlockMouse() override; - void GetSystemDisplayModes(std::vector &dms) override; + int CDPlayerCommand(int cmdd, int datt) override; + void DisplayAlert(const char *, ...) override; + const char *GetAllUsersDataDirectory() override; + const char *GetUserSavedgamesDirectory() override; + const char *GetUserConfigDirectory() override; + const char *GetUserGlobalConfigDirectory() override; + const char *GetAppOutputDirectory() override; + unsigned long GetDiskFreeSpaceMB() override; + const char *GetNoMouseErrorString() override; + const char *GetAllegroFailUserHint() override; + eScriptSystemOSID GetSystemOSID() override; + int InitializeCDPlayer() override; + void PostAllegroExit() override; + void SetGameWindowIcon() override; + void ShutdownCDPlayer() override; + bool LockMouseToWindow() override; + void UnlockMouse() override; + void GetSystemDisplayModes(std::vector &dms) override; }; int AGSLinux::CDPlayerCommand(int cmdd, int datt) { - return cd_player_control(cmdd, datt); + return cd_player_control(cmdd, datt); } void AGSLinux::DisplayAlert(const char *text, ...) { - char displbuf[2000]; - va_list ap; - va_start(ap, text); - vsprintf(displbuf, text, ap); - va_end(ap); - if (_logToStdErr) - fprintf(stderr, "%s\n", displbuf); - else - fprintf(stdout, "%s\n", displbuf); -} - -size_t BuildXDGPath(char *destPath, size_t destSize) -{ - // Check to see if XDG_DATA_HOME is set in the enviroment - const char* home_dir = getenv("XDG_DATA_HOME"); - size_t l = 0; - if (home_dir) - { - l = snprintf(destPath, destSize, "%s", home_dir); - } - else - { - // No evironment variable, so we fall back to home dir in /etc/passwd - struct passwd *p = getpwuid(getuid()); - l = snprintf(destPath, destSize, "%s/.local", p->pw_dir); - if (mkdir(destPath, 0755) != 0 && errno != EEXIST) - return 0; - l += snprintf(destPath + l, destSize - l, "/share"); - if (mkdir(destPath, 0755) != 0 && errno != EEXIST) - return 0; - } - return l; -} - -void DetermineDataDirectories() -{ - if (!UserDataDirectory.IsEmpty()) - return; - char xdg_path[256]; - if (BuildXDGPath(xdg_path, sizeof(xdg_path)) == 0) - sprintf(xdg_path, "%s", "/tmp"); - UserDataDirectory.Format("%s/ags", xdg_path); - mkdir(UserDataDirectory.GetCStr(), 0755); - CommonDataDirectory.Format("%s/ags-common", xdg_path); - mkdir(CommonDataDirectory.GetCStr(), 0755); -} - -const char *AGSLinux::GetAllUsersDataDirectory() -{ - DetermineDataDirectories(); - return CommonDataDirectory; -} - -const char *AGSLinux::GetUserSavedgamesDirectory() -{ - DetermineDataDirectories(); - return UserDataDirectory; -} - -const char *AGSLinux::GetUserConfigDirectory() -{ - return GetUserSavedgamesDirectory(); -} - -const char *AGSLinux::GetUserGlobalConfigDirectory() -{ - return GetUserSavedgamesDirectory(); -} - -const char *AGSLinux::GetAppOutputDirectory() -{ - DetermineDataDirectories(); - return UserDataDirectory; + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + if (_logToStdErr) + fprintf(stderr, "%s\n", displbuf); + else + fprintf(stdout, "%s\n", displbuf); +} + +size_t BuildXDGPath(char *destPath, size_t destSize) { + // Check to see if XDG_DATA_HOME is set in the enviroment + const char *home_dir = getenv("XDG_DATA_HOME"); + size_t l = 0; + if (home_dir) { + l = snprintf(destPath, destSize, "%s", home_dir); + } else { + // No evironment variable, so we fall back to home dir in /etc/passwd + struct passwd *p = getpwuid(getuid()); + l = snprintf(destPath, destSize, "%s/.local", p->pw_dir); + if (mkdir(destPath, 0755) != 0 && errno != EEXIST) + return 0; + l += snprintf(destPath + l, destSize - l, "/share"); + if (mkdir(destPath, 0755) != 0 && errno != EEXIST) + return 0; + } + return l; +} + +void DetermineDataDirectories() { + if (!UserDataDirectory.IsEmpty()) + return; + char xdg_path[256]; + if (BuildXDGPath(xdg_path, sizeof(xdg_path)) == 0) + sprintf(xdg_path, "%s", "/tmp"); + UserDataDirectory.Format("%s/ags", xdg_path); + mkdir(UserDataDirectory.GetCStr(), 0755); + CommonDataDirectory.Format("%s/ags-common", xdg_path); + mkdir(CommonDataDirectory.GetCStr(), 0755); +} + +const char *AGSLinux::GetAllUsersDataDirectory() { + DetermineDataDirectories(); + return CommonDataDirectory; +} + +const char *AGSLinux::GetUserSavedgamesDirectory() { + DetermineDataDirectories(); + return UserDataDirectory; +} + +const char *AGSLinux::GetUserConfigDirectory() { + return GetUserSavedgamesDirectory(); +} + +const char *AGSLinux::GetUserGlobalConfigDirectory() { + return GetUserSavedgamesDirectory(); +} + +const char *AGSLinux::GetAppOutputDirectory() { + DetermineDataDirectories(); + return UserDataDirectory; } unsigned long AGSLinux::GetDiskFreeSpaceMB() { - // placeholder - return 100; + // placeholder + return 100; } -const char* AGSLinux::GetNoMouseErrorString() { - return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +const char *AGSLinux::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; } -const char* AGSLinux::GetAllegroFailUserHint() -{ - return "Make sure you have latest version of Allegro 4 libraries installed, and X server is running."; +const char *AGSLinux::GetAllegroFailUserHint() { + return "Make sure you have latest version of Allegro 4 libraries installed, and X server is running."; } eScriptSystemOSID AGSLinux::GetSystemOSID() { - return eOS_Linux; + return eOS_Linux; } int AGSLinux::InitializeCDPlayer() { - return cd_player_init(); + return cd_player_init(); } void AGSLinux::PostAllegroExit() { - // do nothing + // do nothing } void AGSLinux::SetGameWindowIcon() { - // do nothing + // do nothing } void AGSLinux::ShutdownCDPlayer() { - cd_exit(); + cd_exit(); } -AGSPlatformDriver* AGSPlatformDriver::GetDriver() { - if (instance == nullptr) - instance = new AGSLinux(); - return instance; +AGSPlatformDriver *AGSPlatformDriver::GetDriver() { + if (instance == nullptr) + instance = new AGSLinux(); + return instance; } -bool AGSLinux::LockMouseToWindow() -{ - return XGrabPointer(_xwin.display, _xwin.window, False, - PointerMotionMask | ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, _xwin.window, None, CurrentTime) == GrabSuccess; +bool AGSLinux::LockMouseToWindow() { + return XGrabPointer(_xwin.display, _xwin.window, False, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, _xwin.window, None, CurrentTime) == GrabSuccess; } -void AGSLinux::UnlockMouse() -{ - XUngrabPointer(_xwin.display, CurrentTime); +void AGSLinux::UnlockMouse() { + XUngrabPointer(_xwin.display, CurrentTime); } -void AGSLinux::GetSystemDisplayModes(std::vector &dms) -{ - dms.clear(); - GFX_MODE_LIST *gmlist = get_gfx_mode_list(GFX_XWINDOWS_FULLSCREEN); - for (int i = 0; i < gmlist->num_modes; ++i) - { - const GFX_MODE &m = gmlist->mode[i]; - dms.push_back(Engine::DisplayMode(Engine::GraphicResolution(m.width, m.height, m.bpp))); - } - destroy_gfx_mode_list(gmlist); +void AGSLinux::GetSystemDisplayModes(std::vector &dms) { + dms.clear(); + GFX_MODE_LIST *gmlist = get_gfx_mode_list(GFX_XWINDOWS_FULLSCREEN); + for (int i = 0; i < gmlist->num_modes; ++i) { + const GFX_MODE &m = gmlist->mode[i]; + dms.push_back(Engine::DisplayMode(Engine::GraphicResolution(m.width, m.height, m.bpp))); + } + destroy_gfx_mode_list(gmlist); } #endif diff --git a/engines/ags/engine/platform/osx/acplmac.cpp b/engines/ags/engine/platform/osx/acplmac.cpp index f859e2243b78..1fb3489c13b0 100644 --- a/engines/ags/engine/platform/osx/acplmac.cpp +++ b/engines/ags/engine/platform/osx/acplmac.cpp @@ -47,111 +47,105 @@ static char libraryApplicationSupport[PATH_MAX]; static char commonDataPath[PATH_MAX]; struct AGSMac : AGSPlatformDriver { - AGSMac(); - - virtual int CDPlayerCommand(int cmdd, int datt) override; - virtual void DisplayAlert(const char*, ...) override; - virtual unsigned long GetDiskFreeSpaceMB() override; - virtual const char* GetNoMouseErrorString() override; - virtual eScriptSystemOSID GetSystemOSID() override; - virtual int InitializeCDPlayer() override; - virtual void PostAllegroExit() override; - virtual void SetGameWindowIcon() override; - virtual void ShutdownCDPlayer() override; - - virtual const char *GetUserSavedgamesDirectory() override; - virtual const char *GetAllUsersDataDirectory() override; - virtual const char *GetUserConfigDirectory() override; - virtual const char *GetAppOutputDirectory() override; - virtual const char *GetIllegalFileChars() override; + AGSMac(); + + virtual int CDPlayerCommand(int cmdd, int datt) override; + virtual void DisplayAlert(const char *, ...) override; + virtual unsigned long GetDiskFreeSpaceMB() override; + virtual const char *GetNoMouseErrorString() override; + virtual eScriptSystemOSID GetSystemOSID() override; + virtual int InitializeCDPlayer() override; + virtual void PostAllegroExit() override; + virtual void SetGameWindowIcon() override; + virtual void ShutdownCDPlayer() override; + + virtual const char *GetUserSavedgamesDirectory() override; + virtual const char *GetAllUsersDataDirectory() override; + virtual const char *GetUserConfigDirectory() override; + virtual const char *GetAppOutputDirectory() override; + virtual const char *GetIllegalFileChars() override; }; -AGSMac::AGSMac() -{ - AGSMacInitPaths(psp_game_file_name, libraryApplicationSupport); - - snprintf(commonDataPath, PATH_MAX, "%s/uk.co.adventuregamestudio", libraryApplicationSupport); - AGS::Common::Directory::CreateDirectory(commonDataPath); +AGSMac::AGSMac() { + AGSMacInitPaths(psp_game_file_name, libraryApplicationSupport); - strcpy(psp_translation, "default"); + snprintf(commonDataPath, PATH_MAX, "%s/uk.co.adventuregamestudio", libraryApplicationSupport); + AGS::Common::Directory::CreateDirectory(commonDataPath); + + strcpy(psp_translation, "default"); } int AGSMac::CDPlayerCommand(int cmdd, int datt) { - return 0;//cd_player_control(cmdd, datt); + return 0;//cd_player_control(cmdd, datt); } void AGSMac::DisplayAlert(const char *text, ...) { - char displbuf[2000]; - va_list ap; - va_start(ap, text); - vsprintf(displbuf, text, ap); - va_end(ap); - if (_logToStdErr) - fprintf(stderr, "%s\n", displbuf); - else - fprintf(stdout, "%s\n", displbuf); + char displbuf[2000]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + if (_logToStdErr) + fprintf(stderr, "%s\n", displbuf); + else + fprintf(stdout, "%s\n", displbuf); } unsigned long AGSMac::GetDiskFreeSpaceMB() { - // placeholder - return 100; + // placeholder + return 100; } -const char* AGSMac::GetNoMouseErrorString() { - return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; +const char *AGSMac::GetNoMouseErrorString() { + return "This game requires a mouse. You need to configure and setup your mouse to play this game.\n"; } eScriptSystemOSID AGSMac::GetSystemOSID() { - // override performed if `override.os` is set in config. - return eOS_Mac; + // override performed if `override.os` is set in config. + return eOS_Mac; } int AGSMac::InitializeCDPlayer() { - //return cd_player_init(); - return 0; + //return cd_player_init(); + return 0; } void AGSMac::PostAllegroExit() { - // do nothing + // do nothing } void AGSMac::SetGameWindowIcon() { - // do nothing + // do nothing } void AGSMac::ShutdownCDPlayer() { - //cd_exit(); + //cd_exit(); } -const char* AGSMac::GetAllUsersDataDirectory() -{ - return commonDataPath; +const char *AGSMac::GetAllUsersDataDirectory() { + return commonDataPath; } -const char *AGSMac::GetUserSavedgamesDirectory() -{ - return libraryApplicationSupport; +const char *AGSMac::GetUserSavedgamesDirectory() { + return libraryApplicationSupport; } -const char *AGSMac::GetUserConfigDirectory() -{ - return libraryApplicationSupport; +const char *AGSMac::GetUserConfigDirectory() { + return libraryApplicationSupport; } -const char *AGSMac::GetAppOutputDirectory() -{ - return commonDataPath; +const char *AGSMac::GetAppOutputDirectory() { + return commonDataPath; } -const char *AGSMac::GetIllegalFileChars() -{ - return "\\/:?\"<>|*"; // keep same as Windows so we can sync. +const char *AGSMac::GetIllegalFileChars() { + return "\\/:?\"<>|*"; // keep same as Windows so we can sync. } -AGSPlatformDriver* AGSPlatformDriver::GetDriver() { - if (instance == NULL) - instance = new AGSMac(); - return instance; +AGSPlatformDriver *AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSMac(); + return instance; } #endif diff --git a/engines/ags/engine/platform/util/pe.h b/engines/ags/engine/platform/util/pe.h index 871079f4d36e..f6ab17c9102c 100644 --- a/engines/ags/engine/platform/util/pe.h +++ b/engines/ags/engine/platform/util/pe.h @@ -28,12 +28,12 @@ extern "C" { #endif typedef struct { - char version[15]; - char description[100]; - char internal_name[100]; + char version[15]; + char description[100]; + char internal_name[100]; } version_info_t; -int getVersionInformation(char* filename, version_info_t* version_info); +int getVersionInformation(char *filename, version_info_t *version_info); #ifdef __cplusplus } diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index 37244d32e4c0..0d330d595993 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -80,11 +80,11 @@ extern color palette[256]; #endif typedef struct BMP_EXTRA_INFO { - LPDIRECTDRAWSURFACE2 surf; - struct BMP_EXTRA_INFO *next; - struct BMP_EXTRA_INFO *prev; - int flags; - int lock_nesting; + LPDIRECTDRAWSURFACE2 surf; + struct BMP_EXTRA_INFO *next; + struct BMP_EXTRA_INFO *prev; + int flags; + int lock_nesting; } BMP_EXTRA_INFO; // from Allegro DDraw driver @@ -99,472 +99,422 @@ String win32OutputDirectory; const unsigned int win32TimerPeriod = 1; -extern SetupReturnValue acwsetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &game_data_dir, const char*, const char*); +extern SetupReturnValue acwsetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &game_data_dir, const char *, const char *); struct AGSWin32 : AGSPlatformDriver { - AGSWin32(); - ~AGSWin32(); - - virtual void AboutToQuitGame(); - virtual int CDPlayerCommand(int cmdd, int datt); - virtual void AttachToParentConsole(); - virtual void DisplayAlert(const char*, ...); - virtual int GetLastSystemError(); - virtual const char *GetAllUsersDataDirectory(); - virtual const char *GetUserSavedgamesDirectory(); - virtual const char *GetUserConfigDirectory(); - virtual const char *GetUserGlobalConfigDirectory(); - virtual const char *GetAppOutputDirectory(); - virtual const char *GetIllegalFileChars(); - virtual const char *GetGraphicsTroubleshootingText(); - virtual unsigned long GetDiskFreeSpaceMB(); - virtual const char* GetNoMouseErrorString(); - virtual bool IsMouseControlSupported(bool windowed); - virtual const char* GetAllegroFailUserHint(); - virtual eScriptSystemOSID GetSystemOSID(); - virtual int InitializeCDPlayer(); - virtual void PostAllegroInit(bool windowed); - virtual void PostAllegroExit(); - virtual SetupReturnValue RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out); - virtual void SetGameWindowIcon(); - virtual void ShutdownCDPlayer(); - virtual void WriteStdOut(const char *fmt, ...); - virtual void WriteStdErr(const char *fmt, ...); - virtual void DisplaySwitchOut(); - virtual void DisplaySwitchIn(); - virtual void PauseApplication(); - virtual void ResumeApplication(); - virtual void GetSystemDisplayModes(std::vector &dms); - virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm); - virtual bool ExitFullscreenMode(); - virtual void AdjustWindowStyleForFullscreen(); - virtual void AdjustWindowStyleForWindowed(); - virtual void RegisterGameWithGameExplorer(); - virtual void UnRegisterGameWithGameExplorer(); - virtual int ConvertKeycodeToScanCode(int keyCode); - virtual void ValidateWindowSize(int &x, int &y, bool borderless) const; - virtual bool LockMouseToWindow(); - virtual void UnlockMouse(); + AGSWin32(); + ~AGSWin32(); + + virtual void AboutToQuitGame(); + virtual int CDPlayerCommand(int cmdd, int datt); + virtual void AttachToParentConsole(); + virtual void DisplayAlert(const char *, ...); + virtual int GetLastSystemError(); + virtual const char *GetAllUsersDataDirectory(); + virtual const char *GetUserSavedgamesDirectory(); + virtual const char *GetUserConfigDirectory(); + virtual const char *GetUserGlobalConfigDirectory(); + virtual const char *GetAppOutputDirectory(); + virtual const char *GetIllegalFileChars(); + virtual const char *GetGraphicsTroubleshootingText(); + virtual unsigned long GetDiskFreeSpaceMB(); + virtual const char *GetNoMouseErrorString(); + virtual bool IsMouseControlSupported(bool windowed); + virtual const char *GetAllegroFailUserHint(); + virtual eScriptSystemOSID GetSystemOSID(); + virtual int InitializeCDPlayer(); + virtual void PostAllegroInit(bool windowed); + virtual void PostAllegroExit(); + virtual SetupReturnValue RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out); + virtual void SetGameWindowIcon(); + virtual void ShutdownCDPlayer(); + virtual void WriteStdOut(const char *fmt, ...); + virtual void WriteStdErr(const char *fmt, ...); + virtual void DisplaySwitchOut(); + virtual void DisplaySwitchIn(); + virtual void PauseApplication(); + virtual void ResumeApplication(); + virtual void GetSystemDisplayModes(std::vector &dms); + virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm); + virtual bool ExitFullscreenMode(); + virtual void AdjustWindowStyleForFullscreen(); + virtual void AdjustWindowStyleForWindowed(); + virtual void RegisterGameWithGameExplorer(); + virtual void UnRegisterGameWithGameExplorer(); + virtual int ConvertKeycodeToScanCode(int keyCode); + virtual void ValidateWindowSize(int &x, int &y, bool borderless) const; + virtual bool LockMouseToWindow(); + virtual void UnlockMouse(); #ifndef AGS_NO_VIDEO_PLAYER - virtual void PlayVideo(const char* name, int skip, int flags); + virtual void PlayVideo(const char *name, int skip, int flags); #endif private: - void add_game_to_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers); - void remove_game_from_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers); - void add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers); - void get_tasks_directory(char *directoryNameBuffer, const char *guidAsText, bool allUsers); - void update_game_explorer(bool add); - void create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath); - void register_file_extension(const char *exePath); - void unregister_file_extension(); - - bool SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen); - - bool _isDebuggerPresent; // indicates if the win app is running in the context of a debugger - DisplayMode _preFullscreenMode; // saved display mode before switching system to fullscreen - bool _isAttachedToParentConsole; // indicates if the win app is attached to the parent console + void add_game_to_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers); + void remove_game_from_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers); + void add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers); + void get_tasks_directory(char *directoryNameBuffer, const char *guidAsText, bool allUsers); + void update_game_explorer(bool add); + void create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath); + void register_file_extension(const char *exePath); + void unregister_file_extension(); + + bool SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen); + + bool _isDebuggerPresent; // indicates if the win app is running in the context of a debugger + DisplayMode _preFullscreenMode; // saved display mode before switching system to fullscreen + bool _isAttachedToParentConsole; // indicates if the win app is attached to the parent console }; AGSWin32::AGSWin32() : - _isDebuggerPresent(::IsDebuggerPresent() != FALSE), - _isAttachedToParentConsole(false) -{ - // Do nothing. + _isDebuggerPresent(::IsDebuggerPresent() != FALSE), + _isAttachedToParentConsole(false) { + // Do nothing. } AGSWin32::~AGSWin32() { - if (_isAttachedToParentConsole) - { - ::FreeConsole(); - } + if (_isAttachedToParentConsole) { + ::FreeConsole(); + } } void check_parental_controls() { - /* this doesn't work, it always just returns access depedning - on whether unrated games are allowed because of digital signature - BOOL bHasAccess = FALSE; - IGameExplorer* pFwGameExplorer = NULL; - - CoInitialize(NULL); - // Create an instance of the Game Explorer Interface - HRESULT hr = CoCreateInstance( __uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void**)&pFwGameExplorer); - if( FAILED(hr) || pFwGameExplorer == NULL ) { - // not Vista, do nothing - } - else { - char theexename[MAX_PATH] = "e:\\code\\ags\\acwin\\release\\acwin.exe"; - WCHAR wstrBinPath[MAX_PATH] = {0}; - MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrBinPath, MAX_PATH); - BSTR bstrGDFBinPath = SysAllocString(wstrBinPath); - - hr = pFwGameExplorer->VerifyAccess( bstrGDFBinPath, &bHasAccess ); - SysFreeString(bstrGDFBinPath); - - if( FAILED(hr) || !bHasAccess ) { - char buff[300]; - sprintf(buff, "Parental controls block: %X b: %d", hr, bHasAccess); - quit(buff); - } - else { - platform->DisplayAlert("Parental controls: Access granted."); - } - - } - - if( pFwGameExplorer ) pFwGameExplorer->Release(); - CoUninitialize(); - */ -} - -void AGSWin32::create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath) -{ - IShellLink* pShellLink = NULL; - HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pShellLink); - - if ((SUCCEEDED(hr)) && (pShellLink != NULL)) - { - IPersistFile *pPersistFile = NULL; - if (FAILED(pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile))) - { - this->DisplayAlert("Unable to add game tasks: QueryInterface for IPersistFile failed"); - pShellLink->Release(); - return; - } - - // Set the path to the shortcut target and add the description - if (FAILED(pShellLink->SetPath(pathToEXE))) - { - this->DisplayAlert("Unable to add game tasks: SetPath failed"); - } - else if (FAILED(pShellLink->SetWorkingDirectory(workingFolder))) - { - this->DisplayAlert("Unable to add game tasks: SetWorkingDirectory failed"); - } - else if ((arguments != NULL) && (FAILED(pShellLink->SetArguments(arguments)))) - { - this->DisplayAlert("Unable to add game tasks: SetArguments failed"); - } - else - { - WCHAR wstrTemp[MAX_PATH] = {0}; - MultiByteToWideChar(CP_ACP, 0, shortcutPath, -1, wstrTemp, MAX_PATH); - - if (FAILED(pPersistFile->Save(wstrTemp, TRUE))) - { - this->DisplayAlert("Unable to add game tasks: IPersistFile::Save failed"); - } - } - - pPersistFile->Release(); - } - - if (pShellLink) pShellLink->Release(); -} - -void CopyStringAndRemoveInvalidFilenameChars(const char *source, char *destinationBuffer) -{ - int destIdx = 0; - for (int i = 0; i < (int)strlen(source); i++) - { - if ((source[i] != '/') && - (source[i] != '\\') && - (source[i] != ':') && - (source[i] != '*') && - (source[i] != '?') && - (source[i] != '"') && - (source[i] != '<') && - (source[i] != '>') && - (source[i] != '|') && - (source[i] >= 32)) - { - destinationBuffer[destIdx] = source[i]; - destIdx++; - } - } - destinationBuffer[destIdx] = 0; -} - -void AGSWin32::get_tasks_directory(char *pathBuffer, const char *guidAsText, bool allUsers) -{ - if (SHGetSpecialFolderPath(NULL, pathBuffer, allUsers ? CSIDL_COMMON_APPDATA : CSIDL_LOCAL_APPDATA, FALSE) == FALSE) - { - this->DisplayAlert("Unable to register game: SHGetSpecialFolderPath failed"); - return; - } - - if (pathBuffer[strlen(pathBuffer) - 1] != '\\') - { - strcat(pathBuffer, "\\"); - } - - strcat(pathBuffer, "Microsoft\\Windows\\GameExplorer\\"); - strcat(pathBuffer, guidAsText); - mkdir(pathBuffer); - strcat(pathBuffer, "\\"); - strcat(pathBuffer, "PlayTasks"); - mkdir(pathBuffer); -} - -void AGSWin32::add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers) -{ - char pathBuffer[MAX_PATH]; - get_tasks_directory(pathBuffer, guidAsText, allUsers); - strcat(pathBuffer, "\\"); - strcat(pathBuffer, "0"); - mkdir(pathBuffer); - - // Remove any existing "Play.lnk" from a previous version - char shortcutLocation[MAX_PATH]; - sprintf(shortcutLocation, "%s\\Play.lnk", pathBuffer); - ::remove(shortcutLocation); - - // Generate the shortcut file name (because it can appear on - // the start menu's Recent area) - char sanitisedGameName[MAX_PATH]; - CopyStringAndRemoveInvalidFilenameChars(game.gamename, sanitisedGameName); - if (sanitisedGameName[0] == 0) - strcpy(sanitisedGameName, "Play"); - sprintf(shortcutLocation, "%s\\%s.lnk", pathBuffer, sanitisedGameName); - - create_shortcut(gameEXE, workingFolder, NULL, shortcutLocation); - - pathBuffer[strlen(pathBuffer) - 1] = '1'; - mkdir(pathBuffer); - - sprintf(shortcutLocation, "%s\\Setup game.lnk", pathBuffer); - create_shortcut(gameEXE, workingFolder, "--setup", shortcutLocation); -} - -void AGSWin32::add_game_to_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) -{ - WCHAR wstrTemp[MAX_PATH] = {0}; - bool hadError = false; - - char theexename[MAX_PATH]; - GetModuleFileName(NULL, theexename, MAX_PATH); - - MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrTemp, MAX_PATH); - BSTR bstrGDFBinPath = SysAllocString(wstrTemp); - - char gameDirectory[MAX_PATH]; - strcpy(gameDirectory, theexename); - strrchr(gameDirectory, '\\')[0] = 0; - - MultiByteToWideChar(CP_ACP, 0, gameDirectory, MAX_PATH, wstrTemp, MAX_PATH); - BSTR bstrGameDirectory = SysAllocString(wstrTemp); - - HRESULT hr = pFwGameExplorer->AddGame(bstrGDFBinPath, bstrGameDirectory, allUsers ? GIS_ALL_USERS : GIS_CURRENT_USER, guid); - if ((FAILED(hr)) || (hr == S_FALSE)) - { - if (hr == 0x80070715) - { - // No GDF XML -- do nothing. This means the game was compiled - // without Game Explorer support. - hadError = true; + /* this doesn't work, it always just returns access depedning + on whether unrated games are allowed because of digital signature + BOOL bHasAccess = FALSE; + IGameExplorer* pFwGameExplorer = NULL; + + CoInitialize(NULL); + // Create an instance of the Game Explorer Interface + HRESULT hr = CoCreateInstance( __uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void**)&pFwGameExplorer); + if( FAILED(hr) || pFwGameExplorer == NULL ) { + // not Vista, do nothing + } + else { + char theexename[MAX_PATH] = "e:\\code\\ags\\acwin\\release\\acwin.exe"; + WCHAR wstrBinPath[MAX_PATH] = {0}; + MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrBinPath, MAX_PATH); + BSTR bstrGDFBinPath = SysAllocString(wstrBinPath); + + hr = pFwGameExplorer->VerifyAccess( bstrGDFBinPath, &bHasAccess ); + SysFreeString(bstrGDFBinPath); + + if( FAILED(hr) || !bHasAccess ) { + char buff[300]; + sprintf(buff, "Parental controls block: %X b: %d", hr, bHasAccess); + quit(buff); + } + else { + platform->DisplayAlert("Parental controls: Access granted."); + } + + } + + if( pFwGameExplorer ) pFwGameExplorer->Release(); + CoUninitialize(); + */ +} + +void AGSWin32::create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath) { + IShellLink *pShellLink = NULL; + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&pShellLink); + + if ((SUCCEEDED(hr)) && (pShellLink != NULL)) { + IPersistFile *pPersistFile = NULL; + if (FAILED(pShellLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile))) { + this->DisplayAlert("Unable to add game tasks: QueryInterface for IPersistFile failed"); + pShellLink->Release(); + return; + } + + // Set the path to the shortcut target and add the description + if (FAILED(pShellLink->SetPath(pathToEXE))) { + this->DisplayAlert("Unable to add game tasks: SetPath failed"); + } else if (FAILED(pShellLink->SetWorkingDirectory(workingFolder))) { + this->DisplayAlert("Unable to add game tasks: SetWorkingDirectory failed"); + } else if ((arguments != NULL) && (FAILED(pShellLink->SetArguments(arguments)))) { + this->DisplayAlert("Unable to add game tasks: SetArguments failed"); + } else { + WCHAR wstrTemp[MAX_PATH] = {0}; + MultiByteToWideChar(CP_ACP, 0, shortcutPath, -1, wstrTemp, MAX_PATH); + + if (FAILED(pPersistFile->Save(wstrTemp, TRUE))) { + this->DisplayAlert("Unable to add game tasks: IPersistFile::Save failed"); + } + } + + pPersistFile->Release(); + } + + if (pShellLink) pShellLink->Release(); +} + +void CopyStringAndRemoveInvalidFilenameChars(const char *source, char *destinationBuffer) { + int destIdx = 0; + for (int i = 0; i < (int)strlen(source); i++) { + if ((source[i] != '/') && + (source[i] != '\\') && + (source[i] != ':') && + (source[i] != '*') && + (source[i] != '?') && + (source[i] != '"') && + (source[i] != '<') && + (source[i] != '>') && + (source[i] != '|') && + (source[i] >= 32)) { + destinationBuffer[destIdx] = source[i]; + destIdx++; } - else - { + } + destinationBuffer[destIdx] = 0; +} + +void AGSWin32::get_tasks_directory(char *pathBuffer, const char *guidAsText, bool allUsers) { + if (SHGetSpecialFolderPath(NULL, pathBuffer, allUsers ? CSIDL_COMMON_APPDATA : CSIDL_LOCAL_APPDATA, FALSE) == FALSE) { + this->DisplayAlert("Unable to register game: SHGetSpecialFolderPath failed"); + return; + } + + if (pathBuffer[strlen(pathBuffer) - 1] != '\\') { + strcat(pathBuffer, "\\"); + } + + strcat(pathBuffer, "Microsoft\\Windows\\GameExplorer\\"); + strcat(pathBuffer, guidAsText); + mkdir(pathBuffer); + strcat(pathBuffer, "\\"); + strcat(pathBuffer, "PlayTasks"); + mkdir(pathBuffer); +} + +void AGSWin32::add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers) { + char pathBuffer[MAX_PATH]; + get_tasks_directory(pathBuffer, guidAsText, allUsers); + strcat(pathBuffer, "\\"); + strcat(pathBuffer, "0"); + mkdir(pathBuffer); + + // Remove any existing "Play.lnk" from a previous version + char shortcutLocation[MAX_PATH]; + sprintf(shortcutLocation, "%s\\Play.lnk", pathBuffer); + ::remove(shortcutLocation); + + // Generate the shortcut file name (because it can appear on + // the start menu's Recent area) + char sanitisedGameName[MAX_PATH]; + CopyStringAndRemoveInvalidFilenameChars(game.gamename, sanitisedGameName); + if (sanitisedGameName[0] == 0) + strcpy(sanitisedGameName, "Play"); + sprintf(shortcutLocation, "%s\\%s.lnk", pathBuffer, sanitisedGameName); + + create_shortcut(gameEXE, workingFolder, NULL, shortcutLocation); + + pathBuffer[strlen(pathBuffer) - 1] = '1'; + mkdir(pathBuffer); + + sprintf(shortcutLocation, "%s\\Setup game.lnk", pathBuffer); + create_shortcut(gameEXE, workingFolder, "--setup", shortcutLocation); +} + +void AGSWin32::add_game_to_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) { + WCHAR wstrTemp[MAX_PATH] = {0}; + bool hadError = false; + + char theexename[MAX_PATH]; + GetModuleFileName(NULL, theexename, MAX_PATH); + + MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrTemp, MAX_PATH); + BSTR bstrGDFBinPath = SysAllocString(wstrTemp); + + char gameDirectory[MAX_PATH]; + strcpy(gameDirectory, theexename); + strrchr(gameDirectory, '\\')[0] = 0; + + MultiByteToWideChar(CP_ACP, 0, gameDirectory, MAX_PATH, wstrTemp, MAX_PATH); + BSTR bstrGameDirectory = SysAllocString(wstrTemp); + + HRESULT hr = pFwGameExplorer->AddGame(bstrGDFBinPath, bstrGameDirectory, allUsers ? GIS_ALL_USERS : GIS_CURRENT_USER, guid); + if ((FAILED(hr)) || (hr == S_FALSE)) { + if (hr == 0x80070715) { + // No GDF XML -- do nothing. This means the game was compiled + // without Game Explorer support. + hadError = true; + } else { // Game already exists or error HRESULT updateHr = pFwGameExplorer->UpdateGame(*guid); - if (FAILED(updateHr)) - { - this->DisplayAlert("Failed to add the game to the game explorer: %08X, %08X", hr, updateHr); - hadError = true; + if (FAILED(updateHr)) { + this->DisplayAlert("Failed to add the game to the game explorer: %08X, %08X", hr, updateHr); + hadError = true; } } - } - else - { - add_tasks_for_game(guidAsText, theexename, gameDirectory, allUsers); - } + } else { + add_tasks_for_game(guidAsText, theexename, gameDirectory, allUsers); + } - BOOL bHasAccess = FALSE; - hr = pFwGameExplorer->VerifyAccess( bstrGDFBinPath, &bHasAccess ); + BOOL bHasAccess = FALSE; + hr = pFwGameExplorer->VerifyAccess(bstrGDFBinPath, &bHasAccess); - if (( FAILED(hr) || !bHasAccess ) && (!hadError)) - { - this->DisplayAlert("Windows Parental Controls will not allow you to run this game."); - } + if ((FAILED(hr) || !bHasAccess) && (!hadError)) { + this->DisplayAlert("Windows Parental Controls will not allow you to run this game."); + } - SysFreeString(bstrGDFBinPath); - SysFreeString(bstrGameDirectory); + SysFreeString(bstrGDFBinPath); + SysFreeString(bstrGameDirectory); } #define FA_SEARCH -1 -void delete_files_in_directory(const char *directoryName, const char *fileMask) -{ - char srchBuffer[MAX_PATH]; - sprintf(srchBuffer, "%s\\%s", directoryName, fileMask); - al_ffblk dfb; - int dun = al_findfirst(srchBuffer, &dfb, FA_SEARCH); - while (!dun) { - ::remove(dfb.name); - dun = al_findnext(&dfb); - } - al_findclose(&dfb); -} - -void AGSWin32::remove_game_from_game_explorer(IGameExplorer* pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) -{ - HRESULT hr = pFwGameExplorer->RemoveGame(*guid); - if (FAILED(hr)) - { - this->DisplayAlert("Failed to un-register game: 0x%08X", hr); - } -} - -void AGSWin32::update_game_explorer(bool add) -{ - IGameExplorer* pFwGameExplorer = NULL; - - CoInitialize(NULL); - // Create an instance of the Game Explorer Interface - HRESULT hr = CoCreateInstance( __uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void**)&pFwGameExplorer); - if( FAILED(hr) || pFwGameExplorer == NULL ) - { - Debug::Printf(kDbgMsg_Warn, "Game Explorer not found to register game, Windows Vista required"); - } - else - { - ags_strupr(game.guid); - WCHAR wstrTemp[MAX_PATH] = {0}; - GUID guid = GUID_NULL; - MultiByteToWideChar(CP_ACP, 0, game.guid, MAX_GUID_LENGTH, wstrTemp, MAX_GUID_LENGTH); - if (IIDFromString(wstrTemp, &guid) != S_OK) - { - this->DisplayAlert("Failed to register game: IIDFromString failed"); - } - else if (add) - { - add_game_to_game_explorer(pFwGameExplorer, &guid, game.guid, true); - } - else - { - remove_game_from_game_explorer(pFwGameExplorer, &guid, game.guid, true); - } - } - - if( pFwGameExplorer ) pFwGameExplorer->Release(); - CoUninitialize(); -} - -void AGSWin32::unregister_file_extension() -{ - char keyname[MAX_PATH]; - sprintf(keyname, ".%s", game.saveGameFileExtension); - if (SHDeleteKey(HKEY_CLASSES_ROOT, keyname) != ERROR_SUCCESS) - { - this->DisplayAlert("Unable to un-register the file extension. Make sure you are running this with admin rights."); - return; - } - - sprintf(keyname, "AGS.SaveGames.%s", game.saveGameFileExtension); - SHDeleteKey(HKEY_CLASSES_ROOT, keyname); - - sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension); - SHDeleteKey(HKEY_LOCAL_MACHINE, keyname); - - // Tell Explorer to refresh its file association data - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); -} - -void AGSWin32::register_file_extension(const char *exePath) -{ - DWORD valType, valBufLen = MAX_PATH; - valType = REG_SZ; - char valBuf[MAX_PATH], keyname[MAX_PATH]; - char saveGameRegistryType[MAX_PATH]; - sprintf(saveGameRegistryType, "AGS.SaveGames.%s", game.saveGameFileExtension); - - // write HKEY_CLASSES_ROOT\.Extension = AGS.SaveGames.Extension - strcpy(valBuf, saveGameRegistryType); - sprintf(keyname, ".%s", game.saveGameFileExtension); - if (RegSetValue(HKEY_CLASSES_ROOT, keyname, valType, valBuf, valBufLen)) - { - this->DisplayAlert("Unable to register file type. Make sure you are running this with Administrator rights."); - return; - } - - // create HKEY_CLASSES_ROOT\AGS.SaveGames.Extension - strcpy(keyname, saveGameRegistryType); - sprintf(valBuf, "%s Saved Game", game.gamename); - RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); - - // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\DefaultIcon - sprintf(keyname, "%s\\DefaultIcon", saveGameRegistryType); - sprintf(valBuf, "\"%s\", 0", exePath); - RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); - - // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\Shell\Open\Command - sprintf(keyname, "%s\\Shell\\Open\\Command", saveGameRegistryType); - sprintf(valBuf, "\"%s\" -loadSavedGame \"%%1\"", exePath); - RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); - - // ** BELOW IS VISTA-ONLY - - // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewTitle - strcpy(keyname, saveGameRegistryType); - strcpy(valBuf, "prop:System.Game.RichSaveName;System.Game.RichApplicationName"); - SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewTitle", REG_SZ, valBuf, strlen(valBuf)); - - // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewDetails - strcpy(keyname, saveGameRegistryType); - strcpy(valBuf, "prop:System.Game.RichLevel;System.DateChanged;System.Game.RichComment;System.DisplayName;System.DisplayType"); - SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewDetails", REG_SZ, valBuf, strlen(valBuf)); - - // write HKEY_CLASSES_ROOT\.Extension\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1} - sprintf(keyname, ".%s\\ShellEx\\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}", game.saveGameFileExtension); - strcpy(valBuf, "{4E5BFBF8-F59A-4E87-9805-1F9B42CC254A}"); - RegSetValue (HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); - - // write HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.Extension - sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension); - strcpy(valBuf, "{ECDD6472-2B9B-4B4B-AE36-F316DF3C8D60}"); - RegSetValue (HKEY_LOCAL_MACHINE, keyname, REG_SZ, valBuf, strlen(valBuf)); - - // Tell Explorer to refresh its file association data - SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); -} - -void AGSWin32::RegisterGameWithGameExplorer() -{ - update_game_explorer(true); - - if (game.saveGameFileExtension[0] != 0) - { - char theexename[MAX_PATH]; - GetModuleFileName(NULL, theexename, MAX_PATH); - - register_file_extension(theexename); - } -} - -void AGSWin32::UnRegisterGameWithGameExplorer() -{ - update_game_explorer(false); +void delete_files_in_directory(const char *directoryName, const char *fileMask) { + char srchBuffer[MAX_PATH]; + sprintf(srchBuffer, "%s\\%s", directoryName, fileMask); + al_ffblk dfb; + int dun = al_findfirst(srchBuffer, &dfb, FA_SEARCH); + while (!dun) { + ::remove(dfb.name); + dun = al_findnext(&dfb); + } + al_findclose(&dfb); +} + +void AGSWin32::remove_game_from_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) { + HRESULT hr = pFwGameExplorer->RemoveGame(*guid); + if (FAILED(hr)) { + this->DisplayAlert("Failed to un-register game: 0x%08X", hr); + } +} + +void AGSWin32::update_game_explorer(bool add) { + IGameExplorer *pFwGameExplorer = NULL; + + CoInitialize(NULL); + // Create an instance of the Game Explorer Interface + HRESULT hr = CoCreateInstance(__uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void **)&pFwGameExplorer); + if (FAILED(hr) || pFwGameExplorer == NULL) { + Debug::Printf(kDbgMsg_Warn, "Game Explorer not found to register game, Windows Vista required"); + } else { + ags_strupr(game.guid); + WCHAR wstrTemp[MAX_PATH] = {0}; + GUID guid = GUID_NULL; + MultiByteToWideChar(CP_ACP, 0, game.guid, MAX_GUID_LENGTH, wstrTemp, MAX_GUID_LENGTH); + if (IIDFromString(wstrTemp, &guid) != S_OK) { + this->DisplayAlert("Failed to register game: IIDFromString failed"); + } else if (add) { + add_game_to_game_explorer(pFwGameExplorer, &guid, game.guid, true); + } else { + remove_game_from_game_explorer(pFwGameExplorer, &guid, game.guid, true); + } + } - if (game.saveGameFileExtension[0] != 0) - { - unregister_file_extension(); - } + if (pFwGameExplorer) pFwGameExplorer->Release(); + CoUninitialize(); } -void AGSWin32::PostAllegroInit(bool windowed) -{ - check_parental_controls(); - - // Set the Windows timer resolution to 1 ms so that calls to - // Sleep() don't take more time than specified - MMRESULT result = timeBeginPeriod(win32TimerPeriod); - if (result != TIMERR_NOERROR) - Debug::Printf(kDbgMsg_Error, "Failed to set the timer resolution to %d ms", win32TimerPeriod); +void AGSWin32::unregister_file_extension() { + char keyname[MAX_PATH]; + sprintf(keyname, ".%s", game.saveGameFileExtension); + if (SHDeleteKey(HKEY_CLASSES_ROOT, keyname) != ERROR_SUCCESS) { + this->DisplayAlert("Unable to un-register the file extension. Make sure you are running this with admin rights."); + return; + } + + sprintf(keyname, "AGS.SaveGames.%s", game.saveGameFileExtension); + SHDeleteKey(HKEY_CLASSES_ROOT, keyname); + + sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension); + SHDeleteKey(HKEY_LOCAL_MACHINE, keyname); + + // Tell Explorer to refresh its file association data + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); } -typedef UINT (CALLBACK* Dynamic_SHGetKnownFolderPathType) (GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); -GUID FOLDERID_SAVEDGAMES = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}}; +void AGSWin32::register_file_extension(const char *exePath) { + DWORD valType, valBufLen = MAX_PATH; + valType = REG_SZ; + char valBuf[MAX_PATH], keyname[MAX_PATH]; + char saveGameRegistryType[MAX_PATH]; + sprintf(saveGameRegistryType, "AGS.SaveGames.%s", game.saveGameFileExtension); + + // write HKEY_CLASSES_ROOT\.Extension = AGS.SaveGames.Extension + strcpy(valBuf, saveGameRegistryType); + sprintf(keyname, ".%s", game.saveGameFileExtension); + if (RegSetValue(HKEY_CLASSES_ROOT, keyname, valType, valBuf, valBufLen)) { + this->DisplayAlert("Unable to register file type. Make sure you are running this with Administrator rights."); + return; + } + + // create HKEY_CLASSES_ROOT\AGS.SaveGames.Extension + strcpy(keyname, saveGameRegistryType); + sprintf(valBuf, "%s Saved Game", game.gamename); + RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\DefaultIcon + sprintf(keyname, "%s\\DefaultIcon", saveGameRegistryType); + sprintf(valBuf, "\"%s\", 0", exePath); + RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\Shell\Open\Command + sprintf(keyname, "%s\\Shell\\Open\\Command", saveGameRegistryType); + sprintf(valBuf, "\"%s\" -loadSavedGame \"%%1\"", exePath); + RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // ** BELOW IS VISTA-ONLY + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewTitle + strcpy(keyname, saveGameRegistryType); + strcpy(valBuf, "prop:System.Game.RichSaveName;System.Game.RichApplicationName"); + SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewTitle", REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewDetails + strcpy(keyname, saveGameRegistryType); + strcpy(valBuf, "prop:System.Game.RichLevel;System.DateChanged;System.Game.RichComment;System.DisplayName;System.DisplayType"); + SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewDetails", REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_CLASSES_ROOT\.Extension\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1} + sprintf(keyname, ".%s\\ShellEx\\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}", game.saveGameFileExtension); + strcpy(valBuf, "{4E5BFBF8-F59A-4E87-9805-1F9B42CC254A}"); + RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // write HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.Extension + sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension); + strcpy(valBuf, "{ECDD6472-2B9B-4B4B-AE36-F316DF3C8D60}"); + RegSetValue(HKEY_LOCAL_MACHINE, keyname, REG_SZ, valBuf, strlen(valBuf)); + + // Tell Explorer to refresh its file association data + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); +} + +void AGSWin32::RegisterGameWithGameExplorer() { + update_game_explorer(true); + + if (game.saveGameFileExtension[0] != 0) { + char theexename[MAX_PATH]; + GetModuleFileName(NULL, theexename, MAX_PATH); + + register_file_extension(theexename); + } +} + +void AGSWin32::UnRegisterGameWithGameExplorer() { + update_game_explorer(false); + + if (game.saveGameFileExtension[0] != 0) { + unregister_file_extension(); + } +} + +void AGSWin32::PostAllegroInit(bool windowed) { + check_parental_controls(); + + // Set the Windows timer resolution to 1 ms so that calls to + // Sleep() don't take more time than specified + MMRESULT result = timeBeginPeriod(win32TimerPeriod); + if (result != TIMERR_NOERROR) + Debug::Printf(kDbgMsg_Error, "Failed to set the timer resolution to %d ms", win32TimerPeriod); +} + +typedef UINT(CALLBACK *Dynamic_SHGetKnownFolderPathType)(GUID &rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); +GUID FOLDERID_SAVEDGAMES = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}}; #define _WIN32_WINNT_VISTA 0x0600 #define VER_MINORVERSION 0x0000001 #define VER_MAJORVERSION 0x0000002 @@ -572,372 +522,331 @@ GUID FOLDERID_SAVEDGAMES = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, #define VER_GREATER_EQUAL 3 // These helpers copied from VersionHelpers.h in the Windows 8.1 SDK -bool IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) -{ - OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; - DWORDLONG const dwlConditionMask = VerSetConditionMask( - VerSetConditionMask( - VerSetConditionMask( - 0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL), - VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); +bool IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) { + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - osvi.dwMajorVersion = wMajorVersion; - osvi.dwMinorVersion = wMinorVersion; - osvi.wServicePackMajor = wServicePackMajor; + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; - return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; } bool IsWindowsVistaOrGreater() { - return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); -} - -void determine_app_data_folder() -{ - if (win32AppDataDirectory[0] != 0) - { - // already discovered - return; - } - - WCHAR unicodePath[MAX_PATH]; - WCHAR unicodeShortPath[MAX_PATH]; - SHGetSpecialFolderPathW(NULL, unicodePath, CSIDL_COMMON_APPDATA, FALSE); - if (GetShortPathNameW(unicodePath, unicodeShortPath, MAX_PATH) == 0) - { - platform->DisplayAlert("Unable to get App Data dir: GetShortPathNameW failed"); - return; - } - WideCharToMultiByte(CP_ACP, 0, unicodeShortPath, -1, win32AppDataDirectory, MAX_PATH, NULL, NULL); - - strcat(win32AppDataDirectory, "\\Adventure Game Studio"); - mkdir(win32AppDataDirectory); -} - -void determine_saved_games_folder() -{ - if (win32SavedGamesDirectory[0] != 0) - { - // already discovered - return; - } - - WCHAR unicodeSaveGameDir[MAX_PATH] = L""; - WCHAR unicodeShortSaveGameDir[MAX_PATH] = L""; - - if (IsWindowsVistaOrGreater()) - { - HINSTANCE hShellDLL = LoadLibrary("shell32.dll"); - Dynamic_SHGetKnownFolderPathType Dynamic_SHGetKnownFolderPath = (Dynamic_SHGetKnownFolderPathType)GetProcAddress(hShellDLL, "SHGetKnownFolderPath"); - - if (Dynamic_SHGetKnownFolderPath != NULL) - { - PWSTR path = NULL; - if (SUCCEEDED(Dynamic_SHGetKnownFolderPath(FOLDERID_SAVEDGAMES, 0, NULL, &path))) - { - if (GetShortPathNameW(path, unicodeShortSaveGameDir, MAX_PATH) > 0) { - WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL); - } - CoTaskMemFree(path); - } - } - - FreeLibrary(hShellDLL); - } - else - { - // Windows XP didn't have a "My Saved Games" folder, so create one under "My Documents" - SHGetSpecialFolderPathW(NULL, unicodeSaveGameDir, CSIDL_PERSONAL, FALSE); - // workaround for case where My Documents path has unicode chars (eg. - // with Russian Windows) -- so use Short File Name instead - if (GetShortPathNameW(unicodeSaveGameDir, unicodeShortSaveGameDir, MAX_PATH) > 0) - { - WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL); - strcat(win32SavedGamesDirectory, "\\My Saved Games"); - mkdir(win32SavedGamesDirectory); - } - } - - // Fallback to a subdirectory of the app data directory - if (win32SavedGamesDirectory[0] == '\0') - { - determine_app_data_folder(); - strcpy(win32SavedGamesDirectory, win32AppDataDirectory); - strcat(win32SavedGamesDirectory, "\\Saved Games"); - mkdir(win32SavedGamesDirectory); - } -} - -void DetermineAppOutputDirectory() -{ - if (!win32OutputDirectory.IsEmpty()) - { - return; - } - - determine_saved_games_folder(); - bool log_to_saves_dir = false; - if (win32SavedGamesDirectory[0]) - { - win32OutputDirectory = win32SavedGamesDirectory; - win32OutputDirectory.Append("\\.ags"); - log_to_saves_dir = mkdir(win32OutputDirectory) == 0 || errno == EEXIST; - } - - if (!log_to_saves_dir) - { - char theexename[MAX_PATH + 1] = {0}; - GetModuleFileName(NULL, theexename, MAX_PATH); - PathRemoveFileSpec(theexename); - win32OutputDirectory = theexename; - } -} - -const char* AGSWin32::GetAllUsersDataDirectory() -{ - determine_app_data_folder(); - return &win32AppDataDirectory[0]; -} - -const char *AGSWin32::GetUserSavedgamesDirectory() -{ - determine_saved_games_folder(); - return win32SavedGamesDirectory; -} - -const char *AGSWin32::GetUserConfigDirectory() -{ - determine_saved_games_folder(); - return win32SavedGamesDirectory; -} - -const char *AGSWin32::GetUserGlobalConfigDirectory() -{ - DetermineAppOutputDirectory(); - return win32OutputDirectory; -} - -const char *AGSWin32::GetAppOutputDirectory() -{ - DetermineAppOutputDirectory(); - return win32OutputDirectory; -} - -const char *AGSWin32::GetIllegalFileChars() -{ - return "\\/:?\"<>|*"; -} - -const char *AGSWin32::GetGraphicsTroubleshootingText() -{ - return "\n\nPossible causes:\n" - "* your graphics card drivers do not support requested resolution. " - "Run the game setup program and try another resolution.\n" - "* the graphics driver you have selected does not work. Try switching to another graphics driver.\n" - "* the graphics filter you have selected does not work. Try another filter.\n" - "* your graphics card drivers are out of date. " - "Try downloading updated graphics card drivers from your manufacturer's website.\n" - "* there is a problem with your graphics card driver configuration. " - "Run DXDiag using the Run command (Start->Run, type \"dxdiag.exe\") and correct any problems reported there."; -} - -void AGSWin32::DisplaySwitchOut() -{ - // If we have explicitly set up fullscreen mode then minimize the window - if (_preFullscreenMode.IsValid()) - ShowWindow(win_get_window(), SW_MINIMIZE); + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +} + +void determine_app_data_folder() { + if (win32AppDataDirectory[0] != 0) { + // already discovered + return; + } + + WCHAR unicodePath[MAX_PATH]; + WCHAR unicodeShortPath[MAX_PATH]; + SHGetSpecialFolderPathW(NULL, unicodePath, CSIDL_COMMON_APPDATA, FALSE); + if (GetShortPathNameW(unicodePath, unicodeShortPath, MAX_PATH) == 0) { + platform->DisplayAlert("Unable to get App Data dir: GetShortPathNameW failed"); + return; + } + WideCharToMultiByte(CP_ACP, 0, unicodeShortPath, -1, win32AppDataDirectory, MAX_PATH, NULL, NULL); + + strcat(win32AppDataDirectory, "\\Adventure Game Studio"); + mkdir(win32AppDataDirectory); +} + +void determine_saved_games_folder() { + if (win32SavedGamesDirectory[0] != 0) { + // already discovered + return; + } + + WCHAR unicodeSaveGameDir[MAX_PATH] = L""; + WCHAR unicodeShortSaveGameDir[MAX_PATH] = L""; + + if (IsWindowsVistaOrGreater()) { + HINSTANCE hShellDLL = LoadLibrary("shell32.dll"); + Dynamic_SHGetKnownFolderPathType Dynamic_SHGetKnownFolderPath = (Dynamic_SHGetKnownFolderPathType)GetProcAddress(hShellDLL, "SHGetKnownFolderPath"); + + if (Dynamic_SHGetKnownFolderPath != NULL) { + PWSTR path = NULL; + if (SUCCEEDED(Dynamic_SHGetKnownFolderPath(FOLDERID_SAVEDGAMES, 0, NULL, &path))) { + if (GetShortPathNameW(path, unicodeShortSaveGameDir, MAX_PATH) > 0) { + WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL); + } + CoTaskMemFree(path); + } + } + + FreeLibrary(hShellDLL); + } else { + // Windows XP didn't have a "My Saved Games" folder, so create one under "My Documents" + SHGetSpecialFolderPathW(NULL, unicodeSaveGameDir, CSIDL_PERSONAL, FALSE); + // workaround for case where My Documents path has unicode chars (eg. + // with Russian Windows) -- so use Short File Name instead + if (GetShortPathNameW(unicodeSaveGameDir, unicodeShortSaveGameDir, MAX_PATH) > 0) { + WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL); + strcat(win32SavedGamesDirectory, "\\My Saved Games"); + mkdir(win32SavedGamesDirectory); + } + } + + // Fallback to a subdirectory of the app data directory + if (win32SavedGamesDirectory[0] == '\0') { + determine_app_data_folder(); + strcpy(win32SavedGamesDirectory, win32AppDataDirectory); + strcat(win32SavedGamesDirectory, "\\Saved Games"); + mkdir(win32SavedGamesDirectory); + } +} + +void DetermineAppOutputDirectory() { + if (!win32OutputDirectory.IsEmpty()) { + return; + } + + determine_saved_games_folder(); + bool log_to_saves_dir = false; + if (win32SavedGamesDirectory[0]) { + win32OutputDirectory = win32SavedGamesDirectory; + win32OutputDirectory.Append("\\.ags"); + log_to_saves_dir = mkdir(win32OutputDirectory) == 0 || errno == EEXIST; + } + + if (!log_to_saves_dir) { + char theexename[MAX_PATH + 1] = {0}; + GetModuleFileName(NULL, theexename, MAX_PATH); + PathRemoveFileSpec(theexename); + win32OutputDirectory = theexename; + } +} + +const char *AGSWin32::GetAllUsersDataDirectory() { + determine_app_data_folder(); + return &win32AppDataDirectory[0]; +} + +const char *AGSWin32::GetUserSavedgamesDirectory() { + determine_saved_games_folder(); + return win32SavedGamesDirectory; +} + +const char *AGSWin32::GetUserConfigDirectory() { + determine_saved_games_folder(); + return win32SavedGamesDirectory; +} + +const char *AGSWin32::GetUserGlobalConfigDirectory() { + DetermineAppOutputDirectory(); + return win32OutputDirectory; +} + +const char *AGSWin32::GetAppOutputDirectory() { + DetermineAppOutputDirectory(); + return win32OutputDirectory; +} + +const char *AGSWin32::GetIllegalFileChars() { + return "\\/:?\"<>|*"; +} + +const char *AGSWin32::GetGraphicsTroubleshootingText() { + return "\n\nPossible causes:\n" + "* your graphics card drivers do not support requested resolution. " + "Run the game setup program and try another resolution.\n" + "* the graphics driver you have selected does not work. Try switching to another graphics driver.\n" + "* the graphics filter you have selected does not work. Try another filter.\n" + "* your graphics card drivers are out of date. " + "Try downloading updated graphics card drivers from your manufacturer's website.\n" + "* there is a problem with your graphics card driver configuration. " + "Run DXDiag using the Run command (Start->Run, type \"dxdiag.exe\") and correct any problems reported there."; +} + +void AGSWin32::DisplaySwitchOut() { + // If we have explicitly set up fullscreen mode then minimize the window + if (_preFullscreenMode.IsValid()) + ShowWindow(win_get_window(), SW_MINIMIZE); } void AGSWin32::DisplaySwitchIn() { - // If we have explicitly set up fullscreen mode then restore the window - if (_preFullscreenMode.IsValid()) - ShowWindow(win_get_window(), SW_RESTORE); + // If we have explicitly set up fullscreen mode then restore the window + if (_preFullscreenMode.IsValid()) + ShowWindow(win_get_window(), SW_RESTORE); } -void AGSWin32::PauseApplication() -{ +void AGSWin32::PauseApplication() { #ifndef AGS_NO_VIDEO_PLAYER - dxmedia_pause_video(); + dxmedia_pause_video(); #endif } -void AGSWin32::ResumeApplication() -{ +void AGSWin32::ResumeApplication() { #ifndef AGS_NO_VIDEO_PLAYER - dxmedia_resume_video(); + dxmedia_resume_video(); #endif } -void AGSWin32::GetSystemDisplayModes(std::vector &dms) -{ - dms.clear(); - GFX_MODE_LIST *gmlist = get_gfx_mode_list(GFX_DIRECTX); - for (int i = 0; i < gmlist->num_modes; ++i) - { - const GFX_MODE &m = gmlist->mode[i]; - dms.push_back(DisplayMode(GraphicResolution(m.width, m.height, m.bpp))); - } - destroy_gfx_mode_list(gmlist); +void AGSWin32::GetSystemDisplayModes(std::vector &dms) { + dms.clear(); + GFX_MODE_LIST *gmlist = get_gfx_mode_list(GFX_DIRECTX); + for (int i = 0; i < gmlist->num_modes; ++i) { + const GFX_MODE &m = gmlist->mode[i]; + dms.push_back(DisplayMode(GraphicResolution(m.width, m.height, m.bpp))); + } + destroy_gfx_mode_list(gmlist); } -bool AGSWin32::SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen) -{ - DEVMODE devmode; - memset(&devmode, 0, sizeof(devmode)); - devmode.dmSize = sizeof(devmode); - devmode.dmPelsWidth = dm.Width; - devmode.dmPelsHeight = dm.Height; - devmode.dmBitsPerPel = dm.ColorDepth; - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - return ChangeDisplaySettings(&devmode, fullscreen ? CDS_FULLSCREEN : 0) == DISP_CHANGE_SUCCESSFUL; +bool AGSWin32::SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen) { + DEVMODE devmode; + memset(&devmode, 0, sizeof(devmode)); + devmode.dmSize = sizeof(devmode); + devmode.dmPelsWidth = dm.Width; + devmode.dmPelsHeight = dm.Height; + devmode.dmBitsPerPel = dm.ColorDepth; + devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + return ChangeDisplaySettings(&devmode, fullscreen ? CDS_FULLSCREEN : 0) == DISP_CHANGE_SUCCESSFUL; } -bool AGSWin32::EnterFullscreenMode(const DisplayMode &dm) -{ - // Remember current mode - get_desktop_resolution(&_preFullscreenMode.Width, &_preFullscreenMode.Height); - _preFullscreenMode.ColorDepth = desktop_color_depth(); +bool AGSWin32::EnterFullscreenMode(const DisplayMode &dm) { + // Remember current mode + get_desktop_resolution(&_preFullscreenMode.Width, &_preFullscreenMode.Height); + _preFullscreenMode.ColorDepth = desktop_color_depth(); - // Set requested desktop mode - return SetSystemDisplayMode(dm, true); + // Set requested desktop mode + return SetSystemDisplayMode(dm, true); } -bool AGSWin32::ExitFullscreenMode() -{ - if (!_preFullscreenMode.IsValid()) - return false; +bool AGSWin32::ExitFullscreenMode() { + if (!_preFullscreenMode.IsValid()) + return false; - DisplayMode dm = _preFullscreenMode; - _preFullscreenMode = DisplayMode(); - return SetSystemDisplayMode(dm, false); + DisplayMode dm = _preFullscreenMode; + _preFullscreenMode = DisplayMode(); + return SetSystemDisplayMode(dm, false); } -void AGSWin32::AdjustWindowStyleForFullscreen() -{ - // Remove the border in full-screen mode - Size sz; - get_desktop_resolution(&sz.Width, &sz.Height); - HWND allegro_wnd = win_get_window(); - LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE); - SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_OVERLAPPEDWINDOW) | WS_POPUP); - SetWindowPos(allegro_wnd, HWND_TOP, 0, 0, sz.Width, sz.Height, 0); +void AGSWin32::AdjustWindowStyleForFullscreen() { + // Remove the border in full-screen mode + Size sz; + get_desktop_resolution(&sz.Width, &sz.Height); + HWND allegro_wnd = win_get_window(); + LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE); + SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_OVERLAPPEDWINDOW) | WS_POPUP); + SetWindowPos(allegro_wnd, HWND_TOP, 0, 0, sz.Width, sz.Height, 0); } -void AGSWin32::AdjustWindowStyleForWindowed() -{ - // Make a regular window with a border - HWND allegro_wnd = win_get_window(); - LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE); - SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_POPUP) | (WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX)); - // Make window go on top, but at the same time remove WS_EX_TOPMOST style (applied by Direct3D fullscreen mode) - SetWindowPos(allegro_wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); +void AGSWin32::AdjustWindowStyleForWindowed() { + // Make a regular window with a border + HWND allegro_wnd = win_get_window(); + LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE); + SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_POPUP) | (WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX)); + // Make window go on top, but at the same time remove WS_EX_TOPMOST style (applied by Direct3D fullscreen mode) + SetWindowPos(allegro_wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); } int AGSWin32::CDPlayerCommand(int cmdd, int datt) { #if defined (AGS_HAS_CD_AUDIO) - return cd_player_control(cmdd, datt); + return cd_player_control(cmdd, datt); #else - return -1; + return -1; #endif } void AGSWin32::AttachToParentConsole() { - if (_isAttachedToParentConsole) - return; - - _isAttachedToParentConsole = ::AttachConsole(ATTACH_PARENT_PROCESS) != FALSE; - if (_isAttachedToParentConsole) - { - // Require that both STDOUT and STDERR are valid handles from the parent process. - if (::GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE && - ::GetStdHandle(STD_ERROR_HANDLE) != INVALID_HANDLE_VALUE) - { - // Re-open STDOUT and STDERR to the parent's. - FILE* fp = NULL; - freopen_s(&fp, "CONOUT$", "w", stdout); - setvbuf(stdout, NULL, _IONBF, 0); - - freopen_s(&fp, "CONOUT$", "w", stderr); - setvbuf(stderr, NULL, _IONBF, 0); - } - else - { - ::FreeConsole(); - _isAttachedToParentConsole = false; - } - } + if (_isAttachedToParentConsole) + return; + + _isAttachedToParentConsole = ::AttachConsole(ATTACH_PARENT_PROCESS) != FALSE; + if (_isAttachedToParentConsole) { + // Require that both STDOUT and STDERR are valid handles from the parent process. + if (::GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE && + ::GetStdHandle(STD_ERROR_HANDLE) != INVALID_HANDLE_VALUE) { + // Re-open STDOUT and STDERR to the parent's. + FILE *fp = NULL; + freopen_s(&fp, "CONOUT$", "w", stdout); + setvbuf(stdout, NULL, _IONBF, 0); + + freopen_s(&fp, "CONOUT$", "w", stderr); + setvbuf(stderr, NULL, _IONBF, 0); + } else { + ::FreeConsole(); + _isAttachedToParentConsole = false; + } + } } void AGSWin32::DisplayAlert(const char *text, ...) { - char displbuf[2500]; - va_list ap; - va_start(ap, text); - vsprintf(displbuf, text, ap); - va_end(ap); - if (_guiMode) - MessageBox(win_get_window(), displbuf, "Adventure Game Studio", MB_OK | MB_ICONEXCLAMATION); + char displbuf[2500]; + va_list ap; + va_start(ap, text); + vsprintf(displbuf, text, ap); + va_end(ap); + if (_guiMode) + MessageBox(win_get_window(), displbuf, "Adventure Game Studio", MB_OK | MB_ICONEXCLAMATION); - // Always write to either stderr or stdout, even if message boxes are enabled. - if (_logToStdErr) - AGSWin32::WriteStdErr("%s", displbuf); - else - AGSWin32::WriteStdOut("%s", displbuf); + // Always write to either stderr or stdout, even if message boxes are enabled. + if (_logToStdErr) + AGSWin32::WriteStdErr("%s", displbuf); + else + AGSWin32::WriteStdOut("%s", displbuf); } -int AGSWin32::GetLastSystemError() -{ - return ::GetLastError(); +int AGSWin32::GetLastSystemError() { + return ::GetLastError(); } unsigned long AGSWin32::GetDiskFreeSpaceMB() { - DWORD returnMb = 0; - BOOL fResult; - our_eip = -1891; + DWORD returnMb = 0; + BOOL fResult; + our_eip = -1891; - // On Win9x, the last 3 params cannot be null, so need to supply values for all - __int64 i64FreeBytesToCaller, i64Unused1, i64Unused2; + // On Win9x, the last 3 params cannot be null, so need to supply values for all + __int64 i64FreeBytesToCaller, i64Unused1, i64Unused2; - // Win95 OSR2 or higher - use GetDiskFreeSpaceEx, since the - // normal GetDiskFreeSpace returns erroneous values if the - // free space is > 2 GB - fResult = GetDiskFreeSpaceEx(NULL, - (PULARGE_INTEGER)&i64FreeBytesToCaller, - (PULARGE_INTEGER)&i64Unused1, - (PULARGE_INTEGER)&i64Unused2); + // Win95 OSR2 or higher - use GetDiskFreeSpaceEx, since the + // normal GetDiskFreeSpace returns erroneous values if the + // free space is > 2 GB + fResult = GetDiskFreeSpaceEx(NULL, + (PULARGE_INTEGER)&i64FreeBytesToCaller, + (PULARGE_INTEGER)&i64Unused1, + (PULARGE_INTEGER)&i64Unused2); - our_eip = -1893; + our_eip = -1893; - // convert down to MB so we can fit it in a 32-bit long - i64FreeBytesToCaller /= 1000000; - returnMb = i64FreeBytesToCaller; + // convert down to MB so we can fit it in a 32-bit long + i64FreeBytesToCaller /= 1000000; + returnMb = i64FreeBytesToCaller; - return returnMb; + return returnMb; } -const char* AGSWin32::GetNoMouseErrorString() { - return "No mouse was detected on your system, or your mouse is not configured to work with DirectInput. You must have a mouse to play this game."; +const char *AGSWin32::GetNoMouseErrorString() { + return "No mouse was detected on your system, or your mouse is not configured to work with DirectInput. You must have a mouse to play this game."; } -bool AGSWin32::IsMouseControlSupported(bool windowed) -{ - return true; // supported for both fullscreen and windowed modes +bool AGSWin32::IsMouseControlSupported(bool windowed) { + return true; // supported for both fullscreen and windowed modes } -const char* AGSWin32::GetAllegroFailUserHint() -{ - return "Make sure you have DirectX 5 or above installed."; +const char *AGSWin32::GetAllegroFailUserHint() { + return "Make sure you have DirectX 5 or above installed."; } eScriptSystemOSID AGSWin32::GetSystemOSID() { - return eOS_Win; + return eOS_Win; } int AGSWin32::InitializeCDPlayer() { #if defined (AGS_HAS_CD_AUDIO) - return cd_player_init(); + return cd_player_init(); #else - return -1; + return -1; #endif } @@ -945,213 +854,195 @@ int AGSWin32::InitializeCDPlayer() { void AGSWin32::PlayVideo(const char *name, int skip, int flags) { - char useloc[250]; - sprintf(useloc, "%s\\%s", ResPaths.DataDir.GetCStr(), name); - - bool useSound = true; - if (flags >= 10) { - flags -= 10; - useSound = false; - } - else { - // for some reason DirectSound can't be shared, so uninstall - // allegro sound before playing the video - shutdown_sound(); - } - - bool isError = false; - if (Common::File::TestReadFile(useloc)) - { - isError = (gfxDriver->PlayVideo(useloc, useSound, (VideoSkipType)skip, (flags > 0)) == 0); - } - else - { - isError = true; - sprintf(lastError, "File not found: %s", useloc); - } - - if (isError) { - // turn "Always display as speech" off, to make sure error - // gets displayed correctly - int oldalways = game.options[OPT_ALWAYSSPCH]; - game.options[OPT_ALWAYSSPCH] = 0; - Display("Video playing error: %s", lastError); - game.options[OPT_ALWAYSSPCH] = oldalways; - } - - if (useSound) - { - // Restore sound system - install_sound(usetup.digicard,usetup.midicard,NULL); - if (usetup.mod_player) - init_mod_player(NUM_MOD_DIGI_VOICES); - } - - set_palette_range(palette, 0, 255, 0); + char useloc[250]; + sprintf(useloc, "%s\\%s", ResPaths.DataDir.GetCStr(), name); + + bool useSound = true; + if (flags >= 10) { + flags -= 10; + useSound = false; + } else { + // for some reason DirectSound can't be shared, so uninstall + // allegro sound before playing the video + shutdown_sound(); + } + + bool isError = false; + if (Common::File::TestReadFile(useloc)) { + isError = (gfxDriver->PlayVideo(useloc, useSound, (VideoSkipType)skip, (flags > 0)) == 0); + } else { + isError = true; + sprintf(lastError, "File not found: %s", useloc); + } + + if (isError) { + // turn "Always display as speech" off, to make sure error + // gets displayed correctly + int oldalways = game.options[OPT_ALWAYSSPCH]; + game.options[OPT_ALWAYSSPCH] = 0; + Display("Video playing error: %s", lastError); + game.options[OPT_ALWAYSSPCH] = oldalways; + } + + if (useSound) { + // Restore sound system + install_sound(usetup.digicard, usetup.midicard, NULL); + if (usetup.mod_player) + init_mod_player(NUM_MOD_DIGI_VOICES); + } + + set_palette_range(palette, 0, 255, 0); } #endif -void AGSWin32::AboutToQuitGame() -{ +void AGSWin32::AboutToQuitGame() { #ifndef AGS_NO_VIDEO_PLAYER - dxmedia_abort_video(); + dxmedia_abort_video(); #endif } void AGSWin32::PostAllegroExit() { - // Release the timer setting - timeEndPeriod(win32TimerPeriod); + // Release the timer setting + timeEndPeriod(win32TimerPeriod); } -SetupReturnValue AGSWin32::RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out) -{ - String version_str = String::FromFormat("Adventure Game Studio v%s setup", get_engine_version()); - return AGS::Engine::WinSetup(cfg_in, cfg_out, usetup.data_files_dir, version_str); +SetupReturnValue AGSWin32::RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out) { + String version_str = String::FromFormat("Adventure Game Studio v%s setup", get_engine_version()); + return AGS::Engine::WinSetup(cfg_in, cfg_out, usetup.data_files_dir, version_str); } void AGSWin32::SetGameWindowIcon() { - SetWinIcon(); + SetWinIcon(); } void AGSWin32::WriteStdOut(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - if (_isDebuggerPresent) - { - // Add "AGS:" prefix when outputting to debugger, to make it clear that this - // is a text from the program log - char buf[STD_BUFFER_SIZE] = "AGS: "; - vsnprintf(buf + 5, STD_BUFFER_SIZE - 5, fmt, ap); - OutputDebugString(buf); - OutputDebugString("\n"); - } - else - { - vprintf(fmt, ap); - printf("\n"); - } - va_end(ap); + va_list ap; + va_start(ap, fmt); + if (_isDebuggerPresent) { + // Add "AGS:" prefix when outputting to debugger, to make it clear that this + // is a text from the program log + char buf[STD_BUFFER_SIZE] = "AGS: "; + vsnprintf(buf + 5, STD_BUFFER_SIZE - 5, fmt, ap); + OutputDebugString(buf); + OutputDebugString("\n"); + } else { + vprintf(fmt, ap); + printf("\n"); + } + va_end(ap); } void AGSWin32::WriteStdErr(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - if (_isDebuggerPresent) - { - // Add "AGS:" prefix when outputting to debugger, to make it clear that this - // is a text from the program log - char buf[STD_BUFFER_SIZE] = "AGS ERR: "; - vsnprintf(buf + 9, STD_BUFFER_SIZE - 9, fmt, ap); - OutputDebugString(buf); - OutputDebugString("\n"); - } - else - { - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } - va_end(ap); + va_list ap; + va_start(ap, fmt); + if (_isDebuggerPresent) { + // Add "AGS:" prefix when outputting to debugger, to make it clear that this + // is a text from the program log + char buf[STD_BUFFER_SIZE] = "AGS ERR: "; + vsnprintf(buf + 9, STD_BUFFER_SIZE - 9, fmt, ap); + OutputDebugString(buf); + OutputDebugString("\n"); + } else { + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + } + va_end(ap); } void AGSWin32::ShutdownCDPlayer() { - cd_exit(); + cd_exit(); } extern "C" const unsigned char hw_to_mycode[256]; -int AGSWin32::ConvertKeycodeToScanCode(int keycode) -{ - // ** HIDEOUS HACK TO WORK AROUND ALLEGRO BUG - // the key[] array is hardcoded to qwerty keyboards, so we - // have to re-map it to make it work on other keyboard layouts - keycode += ('a' - 'A'); - int vkey = VkKeyScan(keycode); - int scancode = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - if ((scancode >= 0) && (scancode < 256)) - keycode = hw_to_mycode[scancode]; - return keycode; -} - -void AGSWin32::ValidateWindowSize(int &x, int &y, bool borderless) const -{ - RECT wa_rc, nc_rc; - // This is the size of the available workspace on user's desktop - SystemParametersInfo(SPI_GETWORKAREA, 0, &wa_rc, 0); - // This is the maximal size that OS can reliably resize the window to (including any frame) - const Size max_win(GetSystemMetrics(SM_CXMAXTRACK), GetSystemMetrics(SM_CYMAXTRACK)); - // This is the size of window's non-client area (frame, caption, etc) - HWND allegro_wnd = win_get_window(); - LONG winstyle = borderless ? WS_POPUP : WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX; - LONG winstyle_al = GetWindowLong(allegro_wnd, GWL_STYLE); - SetRectEmpty(&nc_rc); - AdjustWindowRect(&nc_rc, winstyle, FALSE); - // Limit the window's full size to the system's window size limit, - // and limit window's client size to the work space (visible area) - x = Math::Min(x, (int)(max_win.Width - (nc_rc.right - nc_rc.left))); - y = Math::Min(y, (int)(max_win.Height - (nc_rc.bottom - nc_rc.top))); - x = Math::Clamp(x, 1, (int)(wa_rc.right - wa_rc.left)); - y = Math::Clamp(y, 1, (int)(wa_rc.bottom - wa_rc.top)); -} - -bool AGSWin32::LockMouseToWindow() -{ - RECT rc; - HWND allegro_wnd = win_get_window(); - GetClientRect(allegro_wnd, &rc); - ClientToScreen(allegro_wnd, (POINT*)&rc); - ClientToScreen(allegro_wnd, (POINT*)&rc.right); - --rc.right; - --rc.bottom; - return ::ClipCursor(&rc) != 0; -} - -void AGSWin32::UnlockMouse() -{ - ::ClipCursor(NULL); -} - -AGSPlatformDriver* AGSPlatformDriver::GetDriver() { - if (instance == NULL) - instance = new AGSWin32(); - return instance; +int AGSWin32::ConvertKeycodeToScanCode(int keycode) { + // ** HIDEOUS HACK TO WORK AROUND ALLEGRO BUG + // the key[] array is hardcoded to qwerty keyboards, so we + // have to re-map it to make it work on other keyboard layouts + keycode += ('a' - 'A'); + int vkey = VkKeyScan(keycode); + int scancode = MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + if ((scancode >= 0) && (scancode < 256)) + keycode = hw_to_mycode[scancode]; + return keycode; +} + +void AGSWin32::ValidateWindowSize(int &x, int &y, bool borderless) const { + RECT wa_rc, nc_rc; + // This is the size of the available workspace on user's desktop + SystemParametersInfo(SPI_GETWORKAREA, 0, &wa_rc, 0); + // This is the maximal size that OS can reliably resize the window to (including any frame) + const Size max_win(GetSystemMetrics(SM_CXMAXTRACK), GetSystemMetrics(SM_CYMAXTRACK)); + // This is the size of window's non-client area (frame, caption, etc) + HWND allegro_wnd = win_get_window(); + LONG winstyle = borderless ? WS_POPUP : WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX; + LONG winstyle_al = GetWindowLong(allegro_wnd, GWL_STYLE); + SetRectEmpty(&nc_rc); + AdjustWindowRect(&nc_rc, winstyle, FALSE); + // Limit the window's full size to the system's window size limit, + // and limit window's client size to the work space (visible area) + x = Math::Min(x, (int)(max_win.Width - (nc_rc.right - nc_rc.left))); + y = Math::Min(y, (int)(max_win.Height - (nc_rc.bottom - nc_rc.top))); + x = Math::Clamp(x, 1, (int)(wa_rc.right - wa_rc.left)); + y = Math::Clamp(y, 1, (int)(wa_rc.bottom - wa_rc.top)); +} + +bool AGSWin32::LockMouseToWindow() { + RECT rc; + HWND allegro_wnd = win_get_window(); + GetClientRect(allegro_wnd, &rc); + ClientToScreen(allegro_wnd, (POINT *)&rc); + ClientToScreen(allegro_wnd, (POINT *)&rc.right); + --rc.right; + --rc.bottom; + return ::ClipCursor(&rc) != 0; +} + +void AGSWin32::UnlockMouse() { + ::ClipCursor(NULL); +} + +AGSPlatformDriver *AGSPlatformDriver::GetDriver() { + if (instance == NULL) + instance = new AGSWin32(); + return instance; } // *********** WINDOWS-SPECIFIC PLUGIN API FUNCTIONS ************* -HWND IAGSEngine::GetWindowHandle () { - return win_get_window(); +HWND IAGSEngine::GetWindowHandle() { + return win_get_window(); } -LPDIRECTDRAW2 IAGSEngine::GetDirectDraw2 () { - if (directdraw == NULL) - quit("!This plugin requires DirectDraw based graphics driver (software driver)."); +LPDIRECTDRAW2 IAGSEngine::GetDirectDraw2() { + if (directdraw == NULL) + quit("!This plugin requires DirectDraw based graphics driver (software driver)."); - return directdraw; + return directdraw; } -LPDIRECTDRAWSURFACE2 IAGSEngine::GetBitmapSurface (BITMAP *bmp) -{ - if (directdraw == NULL) - quit("!This plugin requires DirectDraw based graphics driver (software driver)."); +LPDIRECTDRAWSURFACE2 IAGSEngine::GetBitmapSurface(BITMAP *bmp) { + if (directdraw == NULL) + quit("!This plugin requires DirectDraw based graphics driver (software driver)."); - BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO*)bmp->extra; + BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO *)bmp->extra; - if (bmp == gfxDriver->GetMemoryBackBuffer()->GetAllegroBitmap()) - invalidate_screen(); + if (bmp == gfxDriver->GetMemoryBackBuffer()->GetAllegroBitmap()) + invalidate_screen(); - return bei->surf; + return bei->surf; } LPDIRECTSOUND IAGSEngine::GetDirectSound() { - return directsound; + return directsound; } LPDIRECTINPUTDEVICE IAGSEngine::GetDirectInputKeyboard() { - return key_dinput_device; + return key_dinput_device; } LPDIRECTINPUTDEVICE IAGSEngine::GetDirectInputMouse() { - return mouse_dinput_device; + return mouse_dinput_device; } #endif diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp index d540ddb7c774..f2b22812bc5a 100644 --- a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp @@ -28,80 +28,69 @@ #include // sprintf -void NamedPipesAGSDebugger::SendAcknowledgement() -{ - DWORD bytesWritten; - WriteFile(_hPipeSending, "MSGACK", 6, &bytesWritten, NULL); +void NamedPipesAGSDebugger::SendAcknowledgement() { + DWORD bytesWritten; + WriteFile(_hPipeSending, "MSGACK", 6, &bytesWritten, NULL); } -NamedPipesAGSDebugger::NamedPipesAGSDebugger(const char *instanceToken) -{ - _hPipeSending = NULL; - _hPipeReading = NULL; - _instanceToken = instanceToken; +NamedPipesAGSDebugger::NamedPipesAGSDebugger(const char *instanceToken) { + _hPipeSending = NULL; + _hPipeReading = NULL; + _instanceToken = instanceToken; } -bool NamedPipesAGSDebugger::Initialize() -{ - // can't use a single duplex pipe as it was deadlocking - char pipeNameBuffer[MAX_PATH]; - sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerGameToEd%s", _instanceToken); - _hPipeSending = CreateFile(pipeNameBuffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, NULL); +bool NamedPipesAGSDebugger::Initialize() { + // can't use a single duplex pipe as it was deadlocking + char pipeNameBuffer[MAX_PATH]; + sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerGameToEd%s", _instanceToken); + _hPipeSending = CreateFile(pipeNameBuffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerEdToGame%s", _instanceToken); - _hPipeReading = CreateFile(pipeNameBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING,0, NULL); + sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerEdToGame%s", _instanceToken); + _hPipeReading = CreateFile(pipeNameBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - if ((_hPipeReading == INVALID_HANDLE_VALUE) || - (_hPipeSending == INVALID_HANDLE_VALUE)) - return false; + if ((_hPipeReading == INVALID_HANDLE_VALUE) || + (_hPipeSending == INVALID_HANDLE_VALUE)) + return false; - return true; + return true; } -void NamedPipesAGSDebugger::Shutdown() -{ - if (_hPipeReading != NULL) - { - CloseHandle(_hPipeReading); - CloseHandle(_hPipeSending); - _hPipeReading = NULL; - } +void NamedPipesAGSDebugger::Shutdown() { + if (_hPipeReading != NULL) { + CloseHandle(_hPipeReading); + CloseHandle(_hPipeSending); + _hPipeReading = NULL; + } } -bool NamedPipesAGSDebugger::SendMessageToEditor(const char *message) -{ - DWORD bytesWritten; - return (WriteFile(_hPipeSending, message, strlen(message), &bytesWritten, NULL ) != 0); +bool NamedPipesAGSDebugger::SendMessageToEditor(const char *message) { + DWORD bytesWritten; + return (WriteFile(_hPipeSending, message, strlen(message), &bytesWritten, NULL) != 0); } -bool NamedPipesAGSDebugger::IsMessageAvailable() -{ - DWORD bytesAvailable = 0; - PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL); +bool NamedPipesAGSDebugger::IsMessageAvailable() { + DWORD bytesAvailable = 0; + PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL); - return (bytesAvailable > 0); + return (bytesAvailable > 0); } -char* NamedPipesAGSDebugger::GetNextMessage() -{ - DWORD bytesAvailable = 0; - PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL); - - if (bytesAvailable > 0) - { - char* buffer = (char*)malloc(bytesAvailable + 1); - DWORD bytesRead = 0; - ReadFile(_hPipeReading, buffer, bytesAvailable, &bytesRead, NULL); - buffer[bytesRead] = 0; - - SendAcknowledgement(); - return buffer; - } - else - { - return NULL; - } +char *NamedPipesAGSDebugger::GetNextMessage() { + DWORD bytesAvailable = 0; + PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL); + + if (bytesAvailable > 0) { + char *buffer = (char *)malloc(bytesAvailable + 1); + DWORD bytesRead = 0; + ReadFile(_hPipeReading, buffer, bytesAvailable, &bytesRead, NULL); + buffer[bytesRead] = 0; + + SendAcknowledgement(); + return buffer; + } else { + return NULL; + } } diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h index 104e31804f33..01a192bdb2ab 100644 --- a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h @@ -27,22 +27,21 @@ #include #include "debug/agseditordebugger.h" -struct NamedPipesAGSDebugger : IAGSEditorDebugger -{ +struct NamedPipesAGSDebugger : IAGSEditorDebugger { private: - HANDLE _hPipeSending; - HANDLE _hPipeReading; - const char *_instanceToken; + HANDLE _hPipeSending; + HANDLE _hPipeReading; + const char *_instanceToken; - void SendAcknowledgement(); + void SendAcknowledgement(); public: - NamedPipesAGSDebugger(const char *instanceToken); - virtual bool Initialize() override; - virtual void Shutdown() override; - virtual bool SendMessageToEditor(const char *message) override; - virtual bool IsMessageAvailable() override; - virtual char* GetNextMessage() override; + NamedPipesAGSDebugger(const char *instanceToken); + virtual bool Initialize() override; + virtual void Shutdown() override; + virtual bool SendMessageToEditor(const char *message) override; + virtual bool IsMessageAvailable() override; + virtual char *GetNextMessage() override; }; #endif diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index bf1003698b1b..70d176d594e8 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -46,7 +46,7 @@ #include "util/library.h" #ifndef AGS_NO_VIDEO_PLAYER -extern int dxmedia_play_video_3d(const char*filename, IDirect3DDevice9 *device, bool useAVISound, int canskip, int stretch); +extern int dxmedia_play_video_3d(const char *filename, IDirect3DDevice9 *device, bool useAVISound, int canskip, int stretch); extern void dxmedia_shutdown_3d(); #endif @@ -60,122 +60,106 @@ extern RGB palette[256]; // but we do not want AGS to be dependent on it. // // Setup identity matrix -void MatrixIdentity(D3DMATRIX &m) -{ - m = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }; +void MatrixIdentity(D3DMATRIX &m) { + m = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; } // Setup translation matrix -void MatrixTranslate(D3DMATRIX &m, float x, float y, float z) -{ - MatrixIdentity(m); - m.m[3][0] = x; - m.m[3][1] = y; - m.m[3][2] = z; +void MatrixTranslate(D3DMATRIX &m, float x, float y, float z) { + MatrixIdentity(m); + m.m[3][0] = x; + m.m[3][1] = y; + m.m[3][2] = z; } // Setup scaling matrix -void MatrixScale(D3DMATRIX &m, float sx, float sy, float sz) -{ - MatrixIdentity(m); - m.m[0][0] = sx; - m.m[1][1] = sy; - m.m[2][2] = sz; +void MatrixScale(D3DMATRIX &m, float sx, float sy, float sz) { + MatrixIdentity(m); + m.m[0][0] = sx; + m.m[1][1] = sy; + m.m[2][2] = sz; } // Setup rotation around Z axis; angle is in radians -void MatrixRotateZ(D3DMATRIX &m, float angle) -{ - MatrixIdentity(m); - m.m[0][0] = cos(angle); - m.m[1][1] = cos(angle); - m.m[0][1] = sin(angle); - m.m[1][0] = -sin(angle); +void MatrixRotateZ(D3DMATRIX &m, float angle) { + MatrixIdentity(m); + m.m[0][0] = cos(angle); + m.m[1][1] = cos(angle); + m.m[0][1] = sin(angle); + m.m[1][0] = -sin(angle); } // Matrix multiplication -void MatrixMultiply(D3DMATRIX &mr, const D3DMATRIX &m1, const D3DMATRIX &m2) -{ - for (int i = 0; i < 4; ++i) - for (int j = 0; j < 4; ++j) - mr.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j]; +void MatrixMultiply(D3DMATRIX &mr, const D3DMATRIX &m1, const D3DMATRIX &m2) { + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + mr.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j]; } // Setup full 2D transformation matrix -void MatrixTransform2D(D3DMATRIX &m, float x, float y, float sx, float sy, float anglez) -{ - D3DMATRIX translate; - D3DMATRIX rotate; - D3DMATRIX scale; - MatrixTranslate(translate, x, y, 0.f); - MatrixRotateZ(rotate, anglez); - MatrixScale(scale, sx, sy, 1.f); - - D3DMATRIX tr1; - MatrixMultiply(tr1, scale, rotate); - MatrixMultiply(m, tr1, translate); +void MatrixTransform2D(D3DMATRIX &m, float x, float y, float sx, float sy, float anglez) { + D3DMATRIX translate; + D3DMATRIX rotate; + D3DMATRIX scale; + MatrixTranslate(translate, x, y, 0.f); + MatrixRotateZ(rotate, anglez); + MatrixScale(scale, sx, sy, 1.f); + + D3DMATRIX tr1; + MatrixMultiply(tr1, scale, rotate); + MatrixMultiply(m, tr1, translate); } // Setup inverse 2D transformation matrix -void MatrixTransformInverse2D(D3DMATRIX &m, float x, float y, float sx, float sy, float anglez) -{ - D3DMATRIX translate; - D3DMATRIX rotate; - D3DMATRIX scale; - MatrixTranslate(translate, x, y, 0.f); - MatrixRotateZ(rotate, anglez); - MatrixScale(scale, sx, sy, 1.f); +void MatrixTransformInverse2D(D3DMATRIX &m, float x, float y, float sx, float sy, float anglez) { + D3DMATRIX translate; + D3DMATRIX rotate; + D3DMATRIX scale; + MatrixTranslate(translate, x, y, 0.f); + MatrixRotateZ(rotate, anglez); + MatrixScale(scale, sx, sy, 1.f); - D3DMATRIX tr1; - MatrixMultiply(tr1, translate, rotate); - MatrixMultiply(m, tr1, scale); + D3DMATRIX tr1; + MatrixMultiply(tr1, translate, rotate); + MatrixMultiply(m, tr1, scale); } -namespace AGS -{ -namespace Engine -{ -namespace D3D -{ +namespace AGS { +namespace Engine { +namespace D3D { using namespace Common; -void D3DBitmap::Dispose() -{ - if (_tiles != NULL) - { - for (int i = 0; i < _numTiles; i++) - _tiles[i].texture->Release(); +void D3DBitmap::Dispose() { + if (_tiles != NULL) { + for (int i = 0; i < _numTiles; i++) + _tiles[i].texture->Release(); - free(_tiles); - _tiles = NULL; - _numTiles = 0; - } - if (_vertex != NULL) - { - _vertex->Release(); - _vertex = NULL; - } + free(_tiles); + _tiles = NULL; + _numTiles = 0; + } + if (_vertex != NULL) { + _vertex->Release(); + _vertex = NULL; + } } static D3DFORMAT color_depth_to_d3d_format(int color_depth, bool wantAlpha); static int d3d_format_to_color_depth(D3DFORMAT format, bool secondary); -bool D3DGfxModeList::GetMode(int index, DisplayMode &mode) const -{ - if (_direct3d && index >= 0 && index < _modeCount) - { - D3DDISPLAYMODE d3d_mode; - if (SUCCEEDED(_direct3d->EnumAdapterModes(D3DADAPTER_DEFAULT, _pixelFormat, index, &d3d_mode))) - { - mode.Width = d3d_mode.Width; - mode.Height = d3d_mode.Height; - mode.ColorDepth = d3d_format_to_color_depth(d3d_mode.Format, false); - mode.RefreshRate = d3d_mode.RefreshRate; - return true; - } - } - return false; +bool D3DGfxModeList::GetMode(int index, DisplayMode &mode) const { + if (_direct3d && index >= 0 && index < _modeCount) { + D3DDISPLAYMODE d3d_mode; + if (SUCCEEDED(_direct3d->EnumAdapterModes(D3DADAPTER_DEFAULT, _pixelFormat, index, &d3d_mode))) { + mode.Width = d3d_mode.Width; + mode.Height = d3d_mode.Height; + mode.ColorDepth = d3d_format_to_color_depth(d3d_mode.Format, false); + mode.RefreshRate = d3d_mode.RefreshRate; + return true; + } + } + return false; } @@ -184,80 +168,78 @@ void dummy_vsync() { } #define GFX_DIRECT3D_WIN AL_ID('D','X','3','W') #define GFX_DIRECT3D_FULL AL_ID('D','X','3','D') -GFX_DRIVER gfx_direct3d_win = -{ - GFX_DIRECT3D_WIN, - empty_string, - empty_string, - "Direct3D windowed", - NULL, // init - NULL, // exit - NULL, // AL_METHOD(int, scroll, (int x, int y)); - dummy_vsync, // vsync - NULL, // setpalette - NULL, // AL_METHOD(int, request_scroll, (int x, int y)); - NULL, // AL_METHOD(int, poll_scroll, (void)); - NULL, // AL_METHOD(void, enable_triple_buffer, (void)); - NULL, //create_video_bitmap - NULL, //destroy_video_bitmap - NULL, //show_video_bitmap - NULL, - NULL, //gfx_directx_create_system_bitmap, - NULL, //gfx_directx_destroy_system_bitmap, - NULL, //gfx_directx_set_mouse_sprite, - NULL, //gfx_directx_show_mouse, - NULL, //gfx_directx_hide_mouse, - NULL, //gfx_directx_move_mouse, - NULL, // AL_METHOD(void, drawing_mode, (void)); - NULL, // AL_METHOD(void, save_video_state, (void*)); - NULL, // AL_METHOD(void, restore_video_state, (void*)); - NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); - NULL, // AL_METHOD(int, fetch_mode_list, (void)); - 0, 0, // int w, h; - FALSE, // int linear; - 0, // long bank_size; - 0, // long bank_gran; - 0, // long vid_mem; - 0, // long vid_phys_base; - TRUE // int windowed; +GFX_DRIVER gfx_direct3d_win = { + GFX_DIRECT3D_WIN, + empty_string, + empty_string, + "Direct3D windowed", + NULL, // init + NULL, // exit + NULL, // AL_METHOD(int, scroll, (int x, int y)); + dummy_vsync, // vsync + NULL, // setpalette + NULL, // AL_METHOD(int, request_scroll, (int x, int y)); + NULL, // AL_METHOD(int, poll_scroll, (void)); + NULL, // AL_METHOD(void, enable_triple_buffer, (void)); + NULL, //create_video_bitmap + NULL, //destroy_video_bitmap + NULL, //show_video_bitmap + NULL, + NULL, //gfx_directx_create_system_bitmap, + NULL, //gfx_directx_destroy_system_bitmap, + NULL, //gfx_directx_set_mouse_sprite, + NULL, //gfx_directx_show_mouse, + NULL, //gfx_directx_hide_mouse, + NULL, //gfx_directx_move_mouse, + NULL, // AL_METHOD(void, drawing_mode, (void)); + NULL, // AL_METHOD(void, save_video_state, (void*)); + NULL, // AL_METHOD(void, restore_video_state, (void*)); + NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); + NULL, // AL_METHOD(int, fetch_mode_list, (void)); + 0, 0, // int w, h; + FALSE, // int linear; + 0, // long bank_size; + 0, // long bank_gran; + 0, // long vid_mem; + 0, // long vid_phys_base; + TRUE // int windowed; }; -GFX_DRIVER gfx_direct3d_full = -{ - GFX_DIRECT3D_FULL, - empty_string, - empty_string, - "Direct3D fullscreen", - NULL, // init - NULL, // exit - NULL, // AL_METHOD(int, scroll, (int x, int y)); - dummy_vsync, // sync - NULL, // setpalette - NULL, // AL_METHOD(int, request_scroll, (int x, int y)); - NULL, // AL_METHOD(int, poll_scroll, (void)); - NULL, // AL_METHOD(void, enable_triple_buffer, (void)); - NULL, //create_video_bitmap - NULL, //destroy_video_bitmap - NULL, //show_video_bitmap - NULL, - NULL, //gfx_directx_create_system_bitmap, - NULL, //gfx_directx_destroy_system_bitmap, - NULL, //gfx_directx_set_mouse_sprite, - NULL, //gfx_directx_show_mouse, - NULL, //gfx_directx_hide_mouse, - NULL, //gfx_directx_move_mouse, - NULL, // AL_METHOD(void, drawing_mode, (void)); - NULL, // AL_METHOD(void, save_video_state, (void*)); - NULL, // AL_METHOD(void, restore_video_state, (void*)); - NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); - NULL, // AL_METHOD(int, fetch_mode_list, (void)); - 0, 0, // int w, h; - FALSE, // int linear; - 0, // long bank_size; - 0, // long bank_gran; - 0, // long vid_mem; - 0, // long vid_phys_base; - FALSE // int windowed; +GFX_DRIVER gfx_direct3d_full = { + GFX_DIRECT3D_FULL, + empty_string, + empty_string, + "Direct3D fullscreen", + NULL, // init + NULL, // exit + NULL, // AL_METHOD(int, scroll, (int x, int y)); + dummy_vsync, // sync + NULL, // setpalette + NULL, // AL_METHOD(int, request_scroll, (int x, int y)); + NULL, // AL_METHOD(int, poll_scroll, (void)); + NULL, // AL_METHOD(void, enable_triple_buffer, (void)); + NULL, //create_video_bitmap + NULL, //destroy_video_bitmap + NULL, //show_video_bitmap + NULL, + NULL, //gfx_directx_create_system_bitmap, + NULL, //gfx_directx_destroy_system_bitmap, + NULL, //gfx_directx_set_mouse_sprite, + NULL, //gfx_directx_show_mouse, + NULL, //gfx_directx_hide_mouse, + NULL, //gfx_directx_move_mouse, + NULL, // AL_METHOD(void, drawing_mode, (void)); + NULL, // AL_METHOD(void, save_video_state, (void*)); + NULL, // AL_METHOD(void, restore_video_state, (void*)); + NULL, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); + NULL, // AL_METHOD(int, fetch_mode_list, (void)); + 0, 0, // int w, h; + FALSE, // int linear; + 0, // long bank_size; + 0, // long bank_gran; + 0, // long vid_mem; + 0, // long vid_phys_base; + FALSE // int windowed; }; // The custom FVF, which describes the custom vertex structure. @@ -269,266 +251,242 @@ static int wnd_create_device(); // user parameters. static DisplayMode d3d_mode_to_init; -D3DGraphicsDriver::D3DGraphicsDriver(IDirect3D9 *d3d) -{ - direct3d = d3d; - direct3ddevice = NULL; - vertexbuffer = NULL; - pixelShader = NULL; - _legacyPixelShader = false; - set_up_default_vertices(); - pNativeSurface = NULL; - pNativeTexture = NULL; - availableVideoMemory = 0; - _smoothScaling = false; - _pixelRenderXOffset = 0; - _pixelRenderYOffset = 0; - _renderSprAtScreenRes = false; - - // Shifts comply to D3DFMT_A8R8G8B8 - _vmem_a_shift_32 = 24; - _vmem_r_shift_32 = 16; - _vmem_g_shift_32 = 8; - _vmem_b_shift_32 = 0; - - // Initialize default sprite batch, it will be used when no other batch was activated - D3DGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); -} - -void D3DGraphicsDriver::set_up_default_vertices() -{ - defaultVertices[0].position.x = 0.0f; - defaultVertices[0].position.y = 0.0f; - defaultVertices[0].position.z = 0.0f; - defaultVertices[0].normal.x = 0.0f; - defaultVertices[0].normal.y = 0.0f; - defaultVertices[0].normal.z = -1.0f; - //defaultVertices[0].color=0xffffffff; - defaultVertices[0].tu=0.0; - defaultVertices[0].tv=0.0; - defaultVertices[1].position.x = 1.0f; - defaultVertices[1].position.y = 0.0f; - defaultVertices[1].position.z = 0.0f; - defaultVertices[1].normal.x = 0.0f; - defaultVertices[1].normal.y = 0.0f; - defaultVertices[1].normal.z = -1.0f; - //defaultVertices[1].color=0xffffffff; - defaultVertices[1].tu=1.0; - defaultVertices[1].tv=0.0; - defaultVertices[2].position.x = 0.0f; - defaultVertices[2].position.y = -1.0f; - defaultVertices[2].position.z = 0.0f; - defaultVertices[2].normal.x = 0.0f; - defaultVertices[2].normal.y = 0.0f; - defaultVertices[2].normal.z = -1.0f; - //defaultVertices[2].color=0xffffffff; - defaultVertices[2].tu=0.0; - defaultVertices[2].tv=1.0; - defaultVertices[3].position.x = 1.0f; - defaultVertices[3].position.y = -1.0f; - defaultVertices[3].position.z = 0.0f; - defaultVertices[3].normal.x = 0.0f; - defaultVertices[3].normal.y = 0.0f; - defaultVertices[3].normal.z = -1.0f; - //defaultVertices[3].color=0xffffffff; - defaultVertices[3].tu=1.0; - defaultVertices[3].tv=1.0; -} - -void D3DGraphicsDriver::Vsync() -{ - // do nothing on D3D -} - -void D3DGraphicsDriver::OnModeSet(const DisplayMode &mode) -{ - GraphicsDriverBase::OnModeSet(mode); - - // The display mode has been set up successfully, save the - // final refresh rate that we are using - D3DDISPLAYMODE final_display_mode; - if (direct3ddevice->GetDisplayMode(0, &final_display_mode) == D3D_OK) { - _mode.RefreshRate = final_display_mode.RefreshRate; - } - else { - _mode.RefreshRate = 0; - } -} - -void D3DGraphicsDriver::ReleaseDisplayMode() -{ - if (!IsModeSet()) - return; - - OnModeReleased(); - ClearDrawLists(); - ClearDrawBackups(); - DestroyFxPool(); - DestroyAllStageScreens(); - - gfx_driver = NULL; -} - -int D3DGraphicsDriver::FirstTimeInit() -{ - HRESULT hr; - - direct3ddevice->GetDeviceCaps(&direct3ddevicecaps); - - // the PixelShader.fx uses ps_1_4 - // the PixelShaderLegacy.fx needs ps_2_0 - int requiredPSMajorVersion = 1; - int requiredPSMinorVersion = 4; - if (_legacyPixelShader) { - requiredPSMajorVersion = 2; - requiredPSMinorVersion = 0; - } - - if (direct3ddevicecaps.PixelShaderVersion < D3DPS_VERSION(requiredPSMajorVersion, requiredPSMinorVersion)) - { - direct3ddevice->Release(); - direct3ddevice = NULL; - previousError = - set_allegro_error("Graphics card does not support Pixel Shader %d.%d", requiredPSMajorVersion, requiredPSMinorVersion); - return -1; - } - - // Load the pixel shader!! - HMODULE exeHandle = GetModuleHandle(NULL); - HRSRC hRes = FindResource(exeHandle, (_legacyPixelShader) ? "PIXEL_SHADER_LEGACY" : "PIXEL_SHADER", "DATA"); - if (hRes) - { - HGLOBAL hGlobal = LoadResource(exeHandle, hRes); - if (hGlobal) - { - DWORD resourceSize = SizeofResource(exeHandle, hRes); - DWORD *dataPtr = (DWORD*)LockResource(hGlobal); - hr = direct3ddevice->CreatePixelShader(dataPtr, &pixelShader); - if (hr != D3D_OK) - { - direct3ddevice->Release(); - direct3ddevice = NULL; - previousError = set_allegro_error("Failed to create pixel shader: 0x%08X", hr); - return -1; - } - UnlockResource(hGlobal); - } - } - - if (pixelShader == NULL) - { - direct3ddevice->Release(); - direct3ddevice = NULL; - previousError = set_allegro_error("Failed to load pixel shader resource"); - return -1; - } - - if (direct3ddevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, - D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &vertexbuffer, NULL) != D3D_OK) - { - direct3ddevice->Release(); - direct3ddevice = NULL; - previousError = set_allegro_error("Failed to create vertex buffer"); - return -1; - } - - // This line crashes because my card doesn't support 8-bit textures - //direct3ddevice->SetCurrentTexturePalette(0); - - CUSTOMVERTEX *vertices; - vertexbuffer->Lock(0, 0, (void**)&vertices, D3DLOCK_DISCARD); - - for (int i = 0; i < 4; i++) - { - vertices[i] = defaultVertices[i]; - } - - vertexbuffer->Unlock(); - - direct3ddevice->GetGammaRamp(0, &defaultgammaramp); - - if (defaultgammaramp.red[255] < 256) - { - // correct bug in some gfx drivers that returns gamma ramp - // values from 0-255 instead of 0-65535 - for (int i = 0; i < 256; i++) - { - defaultgammaramp.red[i] *= 256; - defaultgammaramp.green[i] *= 256; - defaultgammaramp.blue[i] *= 256; - } - } - currentgammaramp = defaultgammaramp; - - return 0; -} - -void D3DGraphicsDriver::initD3DDLL(const DisplayMode &mode) -{ - if (!IsModeSupported(mode)) - { - throw Ali3DException(get_allegro_error()); - } - - _enter_critical(); - - d3d_mode_to_init = mode; - // Set the display mode in the window's thread - if (wnd_call_proc(wnd_create_device)) { - _exit_critical(); - throw Ali3DException(get_allegro_error()); - } - - availableVideoMemory = direct3ddevice->GetAvailableTextureMem(); - - _exit_critical(); - - // Set up a fake allegro gfx driver so that things like - // the allegro mouse handler still work - if (mode.Windowed) - gfx_driver = &gfx_direct3d_win; - else - gfx_driver = &gfx_direct3d_full; - - return; +D3DGraphicsDriver::D3DGraphicsDriver(IDirect3D9 *d3d) { + direct3d = d3d; + direct3ddevice = NULL; + vertexbuffer = NULL; + pixelShader = NULL; + _legacyPixelShader = false; + set_up_default_vertices(); + pNativeSurface = NULL; + pNativeTexture = NULL; + availableVideoMemory = 0; + _smoothScaling = false; + _pixelRenderXOffset = 0; + _pixelRenderYOffset = 0; + _renderSprAtScreenRes = false; + + // Shifts comply to D3DFMT_A8R8G8B8 + _vmem_a_shift_32 = 24; + _vmem_r_shift_32 = 16; + _vmem_g_shift_32 = 8; + _vmem_b_shift_32 = 0; + + // Initialize default sprite batch, it will be used when no other batch was activated + D3DGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); +} + +void D3DGraphicsDriver::set_up_default_vertices() { + defaultVertices[0].position.x = 0.0f; + defaultVertices[0].position.y = 0.0f; + defaultVertices[0].position.z = 0.0f; + defaultVertices[0].normal.x = 0.0f; + defaultVertices[0].normal.y = 0.0f; + defaultVertices[0].normal.z = -1.0f; + //defaultVertices[0].color=0xffffffff; + defaultVertices[0].tu = 0.0; + defaultVertices[0].tv = 0.0; + defaultVertices[1].position.x = 1.0f; + defaultVertices[1].position.y = 0.0f; + defaultVertices[1].position.z = 0.0f; + defaultVertices[1].normal.x = 0.0f; + defaultVertices[1].normal.y = 0.0f; + defaultVertices[1].normal.z = -1.0f; + //defaultVertices[1].color=0xffffffff; + defaultVertices[1].tu = 1.0; + defaultVertices[1].tv = 0.0; + defaultVertices[2].position.x = 0.0f; + defaultVertices[2].position.y = -1.0f; + defaultVertices[2].position.z = 0.0f; + defaultVertices[2].normal.x = 0.0f; + defaultVertices[2].normal.y = 0.0f; + defaultVertices[2].normal.z = -1.0f; + //defaultVertices[2].color=0xffffffff; + defaultVertices[2].tu = 0.0; + defaultVertices[2].tv = 1.0; + defaultVertices[3].position.x = 1.0f; + defaultVertices[3].position.y = -1.0f; + defaultVertices[3].position.z = 0.0f; + defaultVertices[3].normal.x = 0.0f; + defaultVertices[3].normal.y = 0.0f; + defaultVertices[3].normal.z = -1.0f; + //defaultVertices[3].color=0xffffffff; + defaultVertices[3].tu = 1.0; + defaultVertices[3].tv = 1.0; +} + +void D3DGraphicsDriver::Vsync() { + // do nothing on D3D +} + +void D3DGraphicsDriver::OnModeSet(const DisplayMode &mode) { + GraphicsDriverBase::OnModeSet(mode); + + // The display mode has been set up successfully, save the + // final refresh rate that we are using + D3DDISPLAYMODE final_display_mode; + if (direct3ddevice->GetDisplayMode(0, &final_display_mode) == D3D_OK) { + _mode.RefreshRate = final_display_mode.RefreshRate; + } else { + _mode.RefreshRate = 0; + } +} + +void D3DGraphicsDriver::ReleaseDisplayMode() { + if (!IsModeSet()) + return; + + OnModeReleased(); + ClearDrawLists(); + ClearDrawBackups(); + DestroyFxPool(); + DestroyAllStageScreens(); + + gfx_driver = NULL; +} + +int D3DGraphicsDriver::FirstTimeInit() { + HRESULT hr; + + direct3ddevice->GetDeviceCaps(&direct3ddevicecaps); + + // the PixelShader.fx uses ps_1_4 + // the PixelShaderLegacy.fx needs ps_2_0 + int requiredPSMajorVersion = 1; + int requiredPSMinorVersion = 4; + if (_legacyPixelShader) { + requiredPSMajorVersion = 2; + requiredPSMinorVersion = 0; + } + + if (direct3ddevicecaps.PixelShaderVersion < D3DPS_VERSION(requiredPSMajorVersion, requiredPSMinorVersion)) { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = + set_allegro_error("Graphics card does not support Pixel Shader %d.%d", requiredPSMajorVersion, requiredPSMinorVersion); + return -1; + } + + // Load the pixel shader!! + HMODULE exeHandle = GetModuleHandle(NULL); + HRSRC hRes = FindResource(exeHandle, (_legacyPixelShader) ? "PIXEL_SHADER_LEGACY" : "PIXEL_SHADER", "DATA"); + if (hRes) { + HGLOBAL hGlobal = LoadResource(exeHandle, hRes); + if (hGlobal) { + DWORD resourceSize = SizeofResource(exeHandle, hRes); + DWORD *dataPtr = (DWORD *)LockResource(hGlobal); + hr = direct3ddevice->CreatePixelShader(dataPtr, &pixelShader); + if (hr != D3D_OK) { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = set_allegro_error("Failed to create pixel shader: 0x%08X", hr); + return -1; + } + UnlockResource(hGlobal); + } + } + + if (pixelShader == NULL) { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = set_allegro_error("Failed to load pixel shader resource"); + return -1; + } + + if (direct3ddevice->CreateVertexBuffer(4 * sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, + D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &vertexbuffer, NULL) != D3D_OK) { + direct3ddevice->Release(); + direct3ddevice = NULL; + previousError = set_allegro_error("Failed to create vertex buffer"); + return -1; + } + + // This line crashes because my card doesn't support 8-bit textures + //direct3ddevice->SetCurrentTexturePalette(0); + + CUSTOMVERTEX *vertices; + vertexbuffer->Lock(0, 0, (void **)&vertices, D3DLOCK_DISCARD); + + for (int i = 0; i < 4; i++) { + vertices[i] = defaultVertices[i]; + } + + vertexbuffer->Unlock(); + + direct3ddevice->GetGammaRamp(0, &defaultgammaramp); + + if (defaultgammaramp.red[255] < 256) { + // correct bug in some gfx drivers that returns gamma ramp + // values from 0-255 instead of 0-65535 + for (int i = 0; i < 256; i++) { + defaultgammaramp.red[i] *= 256; + defaultgammaramp.green[i] *= 256; + defaultgammaramp.blue[i] *= 256; + } + } + currentgammaramp = defaultgammaramp; + + return 0; +} + +void D3DGraphicsDriver::initD3DDLL(const DisplayMode &mode) { + if (!IsModeSupported(mode)) { + throw Ali3DException(get_allegro_error()); + } + + _enter_critical(); + + d3d_mode_to_init = mode; + // Set the display mode in the window's thread + if (wnd_call_proc(wnd_create_device)) { + _exit_critical(); + throw Ali3DException(get_allegro_error()); + } + + availableVideoMemory = direct3ddevice->GetAvailableTextureMem(); + + _exit_critical(); + + // Set up a fake allegro gfx driver so that things like + // the allegro mouse handler still work + if (mode.Windowed) + gfx_driver = &gfx_direct3d_win; + else + gfx_driver = &gfx_direct3d_full; + + return; } /* color_depth_to_d3d_format: * Convert a colour depth into the appropriate D3D tag */ -static D3DFORMAT color_depth_to_d3d_format(int color_depth, bool wantAlpha) -{ - if (wantAlpha) - { - switch (color_depth) - { - case 8: - return D3DFMT_P8; - case 15: - case 16: - return D3DFMT_A1R5G5B5; - case 24: - case 32: - return D3DFMT_A8R8G8B8; - } - } - else - { - switch (color_depth) - { - case 8: - return D3DFMT_P8; - case 15: // don't use X1R5G5B5 because some cards don't support it - return D3DFMT_A1R5G5B5; - case 16: - return D3DFMT_R5G6B5; - case 24: - return D3DFMT_R8G8B8; - case 32: - return D3DFMT_X8R8G8B8; - } - } - return D3DFMT_UNKNOWN; +static D3DFORMAT color_depth_to_d3d_format(int color_depth, bool wantAlpha) { + if (wantAlpha) { + switch (color_depth) { + case 8: + return D3DFMT_P8; + case 15: + case 16: + return D3DFMT_A1R5G5B5; + case 24: + case 32: + return D3DFMT_A8R8G8B8; + } + } else { + switch (color_depth) { + case 8: + return D3DFMT_P8; + case 15: // don't use X1R5G5B5 because some cards don't support it + return D3DFMT_A1R5G5B5; + case 16: + return D3DFMT_R5G6B5; + case 24: + return D3DFMT_R8G8B8; + case 32: + return D3DFMT_X8R8G8B8; + } + } + return D3DFMT_UNKNOWN; } /* d3d_format_to_color_depth: @@ -537,1560 +495,1372 @@ static D3DFORMAT color_depth_to_d3d_format(int color_depth, bool wantAlpha) * TODO: this is currently an inversion of color_depth_to_d3d_format; * check later if more formats should be handled */ -static int d3d_format_to_color_depth(D3DFORMAT format, bool secondary) -{ - switch (format) - { - case D3DFMT_P8: - return 8; - case D3DFMT_A1R5G5B5: - return secondary ? 15 : 16; - case D3DFMT_X1R5G5B5: - return secondary ? 15 : 16; - case D3DFMT_R5G6B5: - return 16; - case D3DFMT_R8G8B8: - return secondary ? 24 : 32; - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - return 32; - } - return 0; -} - -bool D3DGraphicsDriver::IsModeSupported(const DisplayMode &mode) -{ - if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) - { - set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); - return false; - } - - if (mode.Windowed) - { - return true; - } - - D3DFORMAT pixelFormat = color_depth_to_d3d_format(mode.ColorDepth, false); - D3DDISPLAYMODE d3d_mode; - - int mode_count = direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, pixelFormat); - for (int i = 0; i < mode_count; i++) - { - if (FAILED(direct3d->EnumAdapterModes(D3DADAPTER_DEFAULT, pixelFormat, i, &d3d_mode))) - { - set_allegro_error("IDirect3D9::EnumAdapterModes failed"); - return false; - } - - if ((d3d_mode.Width == mode.Width) && (d3d_mode.Height == mode.Height)) - { - return true; - } - } - - set_allegro_error("The requested adapter mode is not supported"); - return false; -} - -bool D3DGraphicsDriver::SupportsGammaControl() -{ - if ((direct3ddevicecaps.Caps2 & D3DCAPS2_FULLSCREENGAMMA) == 0) - return false; - - if (_mode.Windowed) - return false; - - return true; -} - -void D3DGraphicsDriver::SetGamma(int newGamma) -{ - for (int i = 0; i < 256; i++) - { - int newValue = ((int)defaultgammaramp.red[i] * newGamma) / 100; - if (newValue >= 65535) - newValue = 65535; - currentgammaramp.red[i] = newValue; - currentgammaramp.green[i] = newValue; - currentgammaramp.blue[i] = newValue; - } - - direct3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, ¤tgammaramp); +static int d3d_format_to_color_depth(D3DFORMAT format, bool secondary) { + switch (format) { + case D3DFMT_P8: + return 8; + case D3DFMT_A1R5G5B5: + return secondary ? 15 : 16; + case D3DFMT_X1R5G5B5: + return secondary ? 15 : 16; + case D3DFMT_R5G6B5: + return 16; + case D3DFMT_R8G8B8: + return secondary ? 24 : 32; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + return 32; + } + return 0; +} + +bool D3DGraphicsDriver::IsModeSupported(const DisplayMode &mode) { + if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) { + set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); + return false; + } + + if (mode.Windowed) { + return true; + } + + D3DFORMAT pixelFormat = color_depth_to_d3d_format(mode.ColorDepth, false); + D3DDISPLAYMODE d3d_mode; + + int mode_count = direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, pixelFormat); + for (int i = 0; i < mode_count; i++) { + if (FAILED(direct3d->EnumAdapterModes(D3DADAPTER_DEFAULT, pixelFormat, i, &d3d_mode))) { + set_allegro_error("IDirect3D9::EnumAdapterModes failed"); + return false; + } + + if ((d3d_mode.Width == mode.Width) && (d3d_mode.Height == mode.Height)) { + return true; + } + } + + set_allegro_error("The requested adapter mode is not supported"); + return false; +} + +bool D3DGraphicsDriver::SupportsGammaControl() { + if ((direct3ddevicecaps.Caps2 & D3DCAPS2_FULLSCREENGAMMA) == 0) + return false; + + if (_mode.Windowed) + return false; + + return true; +} + +void D3DGraphicsDriver::SetGamma(int newGamma) { + for (int i = 0; i < 256; i++) { + int newValue = ((int)defaultgammaramp.red[i] * newGamma) / 100; + if (newValue >= 65535) + newValue = 65535; + currentgammaramp.red[i] = newValue; + currentgammaramp.green[i] = newValue; + currentgammaramp.blue[i] = newValue; + } + + direct3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, ¤tgammaramp); } /* wnd_set_video_mode: * Called by window thread to set a gfx mode; this is needed because DirectDraw can only * change the mode in the thread that handles the window. */ -static int wnd_create_device() -{ - return D3DGraphicsFactory::GetD3DDriver()->_initDLLCallback(d3d_mode_to_init); -} - -static int wnd_reset_device() -{ - return D3DGraphicsFactory::GetD3DDriver()->_resetDeviceIfNecessary(); -} - -int D3DGraphicsDriver::_resetDeviceIfNecessary() -{ - HRESULT hr = direct3ddevice->TestCooperativeLevel(); - - if (hr == D3DERR_DEVICELOST) - { - Debug::Printf("D3DGraphicsDriver: D3D Device Lost"); - // user has alt+tabbed away from the game - return 1; - } - - if (hr == D3DERR_DEVICENOTRESET) - { - Debug::Printf("D3DGraphicsDriver: D3D Device Not Reset"); - hr = ResetD3DDevice(); - if (hr != D3D_OK) - { - Debug::Printf("D3DGraphicsDriver: Failed to reset D3D device"); - // can't throw exception because we're in the wrong thread, - // so just return a value instead - return 2; - } - - InitializeD3DState(); - CreateVirtualScreen(); - direct3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, ¤tgammaramp); - } - - return 0; -} - -int D3DGraphicsDriver::_initDLLCallback(const DisplayMode &mode) -{ - HWND allegro_wnd = win_get_window(); - - if (mode.Windowed) - platform->AdjustWindowStyleForWindowed(); - else - platform->AdjustWindowStyleForFullscreen(); - - memset( &d3dpp, 0, sizeof(d3dpp) ); - d3dpp.BackBufferWidth = mode.Width; - d3dpp.BackBufferHeight = mode.Height; - d3dpp.BackBufferFormat = color_depth_to_d3d_format(mode.ColorDepth, false); - d3dpp.BackBufferCount = 1; - d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; - // THIS MUST BE SWAPEFFECT_COPY FOR PlayVideo TO WORK - d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; //D3DSWAPEFFECT_DISCARD; - d3dpp.hDeviceWindow = allegro_wnd; - d3dpp.Windowed = mode.Windowed; - d3dpp.EnableAutoDepthStencil = FALSE; - d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; // we need this flag to access the backbuffer with lockrect - d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - if(mode.Vsync) - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - else - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - - /* If full screen, specify the refresh rate */ - // TODO find a way to avoid the wrong refreshrate to be set on mode.RefreshRate - // for now it's best to let it set automatically, so we prevent alt tab delays due to mismatching refreshrates - //if ((d3dpp.Windowed == FALSE) && (mode.RefreshRate > 0)) - // d3dpp.FullScreen_RefreshRateInHz = mode.RefreshRate; - - if (_initGfxCallback != NULL) - _initGfxCallback(&d3dpp); - - bool first_time_init = direct3ddevice == NULL; - HRESULT hr = 0; - if (direct3ddevice) - { - hr = ResetD3DDevice(); - } - else - hr = direct3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, allegro_wnd, - D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, // multithreaded required for AVI player - &d3dpp, &direct3ddevice); - if (hr != D3D_OK) - { - if (!previousError.IsEmpty()) - set_allegro_error(previousError); - else - set_allegro_error("Failed to create Direct3D Device: 0x%08X", hr); - return -1; - } - - if (mode.Windowed) - { - if (adjust_window(mode.Width, mode.Height) != 0) - { - direct3ddevice->Release(); - direct3ddevice = NULL; - set_allegro_error("Window size not supported"); - return -1; - } - } - - win_grab_input(); - - if (first_time_init) - { - int ft_res = FirstTimeInit(); - if (ft_res != 0) - return ft_res; - } - return 0; -} - -void D3DGraphicsDriver::InitializeD3DState() -{ - direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); - - // set the render flags. - direct3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - - direct3ddevice->SetRenderState(D3DRS_LIGHTING, true); - direct3ddevice->SetRenderState(D3DRS_ZENABLE, FALSE); - - direct3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - direct3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - direct3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - - direct3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - direct3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); - direct3ddevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)0); - - direct3ddevice->SetFVF(D3DFVF_CUSTOMVERTEX); - - D3DMATERIAL9 material; - ZeroMemory(&material, sizeof(material)); //zero memory ( NEW ) - material.Diffuse.r = 1.0f; //diffuse color ( NEW ) - material.Diffuse.g = 1.0f; - material.Diffuse.b = 1.0f; - direct3ddevice->SetMaterial(&material); - - D3DLIGHT9 d3dLight; - ZeroMemory(&d3dLight, sizeof(D3DLIGHT9)); - - // Set up a white point light. - d3dLight.Type = D3DLIGHT_DIRECTIONAL; - d3dLight.Diffuse.r = 1.0f; - d3dLight.Diffuse.g = 1.0f; - d3dLight.Diffuse.b = 1.0f; - d3dLight.Diffuse.a = 1.0f; - d3dLight.Ambient.r = 1.0f; - d3dLight.Ambient.g = 1.0f; - d3dLight.Ambient.b = 1.0f; - d3dLight.Specular.r = 1.0f; - d3dLight.Specular.g = 1.0f; - d3dLight.Specular.b = 1.0f; - - // Position it high in the scene and behind the user. - // Remember, these coordinates are in world space, so - // the user could be anywhere in world space, too. - // For the purposes of this example, assume the user - // is at the origin of world space. - d3dLight.Direction.x = 0.0f; - d3dLight.Direction.y = 0.0f; - d3dLight.Direction.z = 1.0f; - - // Don't attenuate. - d3dLight.Attenuation0 = 1.0f; - d3dLight.Range = 1000.0f; - - // Set the property information for the first light. - direct3ddevice->SetLight(0, &d3dLight); - direct3ddevice->LightEnable(0, TRUE); - - // If we already have a render frame configured, then setup viewport immediately - SetupViewport(); -} - -void D3DGraphicsDriver::SetupViewport() -{ - if (!IsModeSet() || !IsRenderFrameValid() || !IsNativeSizeValid()) - return; - - const float src_width = _srcRect.GetWidth(); - const float src_height = _srcRect.GetHeight(); - const float disp_width = _mode.Width; - const float disp_height = _mode.Height; - - // Setup orthographic projection matrix - D3DMATRIX matOrtho = { - (2.0f / src_width), 0.0, 0.0, 0.0, - 0.0, (2.0f / src_height), 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }; - - D3DMATRIX matIdentity = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }; - - direct3ddevice->SetTransform(D3DTS_PROJECTION, &matOrtho); - direct3ddevice->SetTransform(D3DTS_WORLD, &matIdentity); - direct3ddevice->SetTransform(D3DTS_VIEW, &matIdentity); - - // See "Directly Mapping Texels to Pixels" MSDN article for why this is necessary - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb219690.aspx - _pixelRenderXOffset = (src_width / disp_width) / 2.0f; - _pixelRenderYOffset = (src_height / disp_height) / 2.0f; - - // Clear the screen before setting a viewport. - ClearScreenRect(RectWH(0, 0, _mode.Width, _mode.Height), nullptr); - - // Set Viewport. - ZeroMemory(&_d3dViewport, sizeof(D3DVIEWPORT9)); - _d3dViewport.X = _dstRect.Left; - _d3dViewport.Y = _dstRect.Top; - _d3dViewport.Width = _dstRect.GetWidth(); - _d3dViewport.Height = _dstRect.GetHeight(); - _d3dViewport.MinZ = 0.0f; - _d3dViewport.MaxZ = 1.0f; - direct3ddevice->SetViewport(&_d3dViewport); - - viewport_rect.left = _dstRect.Left; - viewport_rect.right = _dstRect.Right + 1; - viewport_rect.top = _dstRect.Top; - viewport_rect.bottom = _dstRect.Bottom + 1; -} - -void D3DGraphicsDriver::SetGraphicsFilter(PD3DFilter filter) -{ - _filter = filter; - OnSetFilter(); -} - -void D3DGraphicsDriver::SetTintMethod(TintMethod method) -{ - _legacyPixelShader = (method == TintReColourise); -} - -bool D3DGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) -{ - ReleaseDisplayMode(); - - if (mode.ColorDepth < 15) - { - set_allegro_error("Direct3D driver does not support 256-color display mode"); - return false; - } - - try - { - initD3DDLL(mode); - } - catch (Ali3DException exception) - { - if (exception._message != get_allegro_error()) - set_allegro_error(exception._message); - return false; - } - OnInit(loopTimer); - OnModeSet(mode); - InitializeD3DState(); - CreateVirtualScreen(); - return true; -} - -void D3DGraphicsDriver::CreateVirtualScreen() -{ - if (!IsModeSet() || !IsNativeSizeValid()) - return; - - // set up native surface - if (pNativeSurface != NULL) - { - pNativeSurface->Release(); - pNativeSurface = NULL; - } - if (pNativeTexture != NULL) - { - pNativeTexture->Release(); - pNativeTexture = NULL; - } - if (direct3ddevice->CreateTexture( - _srcRect.GetWidth(), - _srcRect.GetHeight(), - 1, - D3DUSAGE_RENDERTARGET, - color_depth_to_d3d_format(_mode.ColorDepth, false), - D3DPOOL_DEFAULT, - &pNativeTexture, - NULL) != D3D_OK) - { - throw Ali3DException("CreateTexture failed"); - } - if (pNativeTexture->GetSurfaceLevel(0, &pNativeSurface) != D3D_OK) - { - throw Ali3DException("GetSurfaceLevel failed"); - } - - direct3ddevice->ColorFill(pNativeSurface, NULL, 0); - - // create initial stage screen for plugin raw drawing - _stageVirtualScreen = CreateStageScreen(0, _srcRect.GetSize()); - // we must set Allegro's screen pointer to **something** - screen = (BITMAP*)_stageVirtualScreen->GetAllegroBitmap(); -} - -HRESULT D3DGraphicsDriver::ResetD3DDevice() -{ - // Direct3D documentation: - // Before calling the IDirect3DDevice9::Reset method for a device, - // an application should release any explicit render targets, depth stencil - // surfaces, additional swap chains, state blocks, and D3DPOOL_DEFAULT - // resources associated with the device. - if (pNativeSurface != NULL) - { - pNativeSurface->Release(); - pNativeSurface = NULL; - } - if (pNativeTexture != NULL) - { - pNativeTexture->Release(); - pNativeTexture = NULL; - } - return direct3ddevice->Reset(&d3dpp); -} - -bool D3DGraphicsDriver::SetNativeSize(const Size &src_size) -{ - OnSetNativeSize(src_size); - // Also make sure viewport is updated using new native & destination rectangles - SetupViewport(); - CreateVirtualScreen(); - return !_srcRect.IsEmpty(); -} - -bool D3DGraphicsDriver::SetRenderFrame(const Rect &dst_rect) -{ - OnSetRenderFrame(dst_rect); - // Also make sure viewport is updated using new native & destination rectangles - SetupViewport(); - return !_dstRect.IsEmpty(); -} - -int D3DGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const -{ - // TODO: check for device caps to know which depth is supported? - return 32; -} - -IGfxModeList *D3DGraphicsDriver::GetSupportedModeList(int color_depth) -{ - direct3d->AddRef(); - return new D3DGfxModeList(direct3d, color_depth_to_d3d_format(color_depth, false)); -} - -PGfxFilter D3DGraphicsDriver::GetGraphicsFilter() const -{ - return _filter; -} - -void D3DGraphicsDriver::UnInit() -{ +static int wnd_create_device() { + return D3DGraphicsFactory::GetD3DDriver()->_initDLLCallback(d3d_mode_to_init); +} + +static int wnd_reset_device() { + return D3DGraphicsFactory::GetD3DDriver()->_resetDeviceIfNecessary(); +} + +int D3DGraphicsDriver::_resetDeviceIfNecessary() { + HRESULT hr = direct3ddevice->TestCooperativeLevel(); + + if (hr == D3DERR_DEVICELOST) { + Debug::Printf("D3DGraphicsDriver: D3D Device Lost"); + // user has alt+tabbed away from the game + return 1; + } + + if (hr == D3DERR_DEVICENOTRESET) { + Debug::Printf("D3DGraphicsDriver: D3D Device Not Reset"); + hr = ResetD3DDevice(); + if (hr != D3D_OK) { + Debug::Printf("D3DGraphicsDriver: Failed to reset D3D device"); + // can't throw exception because we're in the wrong thread, + // so just return a value instead + return 2; + } + + InitializeD3DState(); + CreateVirtualScreen(); + direct3ddevice->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, ¤tgammaramp); + } + + return 0; +} + +int D3DGraphicsDriver::_initDLLCallback(const DisplayMode &mode) { + HWND allegro_wnd = win_get_window(); + + if (mode.Windowed) + platform->AdjustWindowStyleForWindowed(); + else + platform->AdjustWindowStyleForFullscreen(); + + memset(&d3dpp, 0, sizeof(d3dpp)); + d3dpp.BackBufferWidth = mode.Width; + d3dpp.BackBufferHeight = mode.Height; + d3dpp.BackBufferFormat = color_depth_to_d3d_format(mode.ColorDepth, false); + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + // THIS MUST BE SWAPEFFECT_COPY FOR PlayVideo TO WORK + d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; //D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = allegro_wnd; + d3dpp.Windowed = mode.Windowed; + d3dpp.EnableAutoDepthStencil = FALSE; + d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; // we need this flag to access the backbuffer with lockrect + d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + if (mode.Vsync) + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + else + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + /* If full screen, specify the refresh rate */ + // TODO find a way to avoid the wrong refreshrate to be set on mode.RefreshRate + // for now it's best to let it set automatically, so we prevent alt tab delays due to mismatching refreshrates + //if ((d3dpp.Windowed == FALSE) && (mode.RefreshRate > 0)) + // d3dpp.FullScreen_RefreshRateInHz = mode.RefreshRate; + + if (_initGfxCallback != NULL) + _initGfxCallback(&d3dpp); + + bool first_time_init = direct3ddevice == NULL; + HRESULT hr = 0; + if (direct3ddevice) { + hr = ResetD3DDevice(); + } else + hr = direct3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, allegro_wnd, + D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, // multithreaded required for AVI player + &d3dpp, &direct3ddevice); + if (hr != D3D_OK) { + if (!previousError.IsEmpty()) + set_allegro_error(previousError); + else + set_allegro_error("Failed to create Direct3D Device: 0x%08X", hr); + return -1; + } + + if (mode.Windowed) { + if (adjust_window(mode.Width, mode.Height) != 0) { + direct3ddevice->Release(); + direct3ddevice = NULL; + set_allegro_error("Window size not supported"); + return -1; + } + } + + win_grab_input(); + + if (first_time_init) { + int ft_res = FirstTimeInit(); + if (ft_res != 0) + return ft_res; + } + return 0; +} + +void D3DGraphicsDriver::InitializeD3DState() { + direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); + + // set the render flags. + direct3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + + direct3ddevice->SetRenderState(D3DRS_LIGHTING, true); + direct3ddevice->SetRenderState(D3DRS_ZENABLE, FALSE); + + direct3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + direct3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + direct3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + direct3ddevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); + direct3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER); + direct3ddevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)0); + + direct3ddevice->SetFVF(D3DFVF_CUSTOMVERTEX); + + D3DMATERIAL9 material; + ZeroMemory(&material, sizeof(material)); //zero memory ( NEW ) + material.Diffuse.r = 1.0f; //diffuse color ( NEW ) + material.Diffuse.g = 1.0f; + material.Diffuse.b = 1.0f; + direct3ddevice->SetMaterial(&material); + + D3DLIGHT9 d3dLight; + ZeroMemory(&d3dLight, sizeof(D3DLIGHT9)); + + // Set up a white point light. + d3dLight.Type = D3DLIGHT_DIRECTIONAL; + d3dLight.Diffuse.r = 1.0f; + d3dLight.Diffuse.g = 1.0f; + d3dLight.Diffuse.b = 1.0f; + d3dLight.Diffuse.a = 1.0f; + d3dLight.Ambient.r = 1.0f; + d3dLight.Ambient.g = 1.0f; + d3dLight.Ambient.b = 1.0f; + d3dLight.Specular.r = 1.0f; + d3dLight.Specular.g = 1.0f; + d3dLight.Specular.b = 1.0f; + + // Position it high in the scene and behind the user. + // Remember, these coordinates are in world space, so + // the user could be anywhere in world space, too. + // For the purposes of this example, assume the user + // is at the origin of world space. + d3dLight.Direction.x = 0.0f; + d3dLight.Direction.y = 0.0f; + d3dLight.Direction.z = 1.0f; + + // Don't attenuate. + d3dLight.Attenuation0 = 1.0f; + d3dLight.Range = 1000.0f; + + // Set the property information for the first light. + direct3ddevice->SetLight(0, &d3dLight); + direct3ddevice->LightEnable(0, TRUE); + + // If we already have a render frame configured, then setup viewport immediately + SetupViewport(); +} + +void D3DGraphicsDriver::SetupViewport() { + if (!IsModeSet() || !IsRenderFrameValid() || !IsNativeSizeValid()) + return; + + const float src_width = _srcRect.GetWidth(); + const float src_height = _srcRect.GetHeight(); + const float disp_width = _mode.Width; + const float disp_height = _mode.Height; + + // Setup orthographic projection matrix + D3DMATRIX matOrtho = { + (2.0f / src_width), 0.0, 0.0, 0.0, + 0.0, (2.0f / src_height), 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + D3DMATRIX matIdentity = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + direct3ddevice->SetTransform(D3DTS_PROJECTION, &matOrtho); + direct3ddevice->SetTransform(D3DTS_WORLD, &matIdentity); + direct3ddevice->SetTransform(D3DTS_VIEW, &matIdentity); + + // See "Directly Mapping Texels to Pixels" MSDN article for why this is necessary + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb219690.aspx + _pixelRenderXOffset = (src_width / disp_width) / 2.0f; + _pixelRenderYOffset = (src_height / disp_height) / 2.0f; + + // Clear the screen before setting a viewport. + ClearScreenRect(RectWH(0, 0, _mode.Width, _mode.Height), nullptr); + + // Set Viewport. + ZeroMemory(&_d3dViewport, sizeof(D3DVIEWPORT9)); + _d3dViewport.X = _dstRect.Left; + _d3dViewport.Y = _dstRect.Top; + _d3dViewport.Width = _dstRect.GetWidth(); + _d3dViewport.Height = _dstRect.GetHeight(); + _d3dViewport.MinZ = 0.0f; + _d3dViewport.MaxZ = 1.0f; + direct3ddevice->SetViewport(&_d3dViewport); + + viewport_rect.left = _dstRect.Left; + viewport_rect.right = _dstRect.Right + 1; + viewport_rect.top = _dstRect.Top; + viewport_rect.bottom = _dstRect.Bottom + 1; +} + +void D3DGraphicsDriver::SetGraphicsFilter(PD3DFilter filter) { + _filter = filter; + OnSetFilter(); +} + +void D3DGraphicsDriver::SetTintMethod(TintMethod method) { + _legacyPixelShader = (method == TintReColourise); +} + +bool D3DGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) { + ReleaseDisplayMode(); + + if (mode.ColorDepth < 15) { + set_allegro_error("Direct3D driver does not support 256-color display mode"); + return false; + } + + try { + initD3DDLL(mode); + } catch (Ali3DException exception) { + if (exception._message != get_allegro_error()) + set_allegro_error(exception._message); + return false; + } + OnInit(loopTimer); + OnModeSet(mode); + InitializeD3DState(); + CreateVirtualScreen(); + return true; +} + +void D3DGraphicsDriver::CreateVirtualScreen() { + if (!IsModeSet() || !IsNativeSizeValid()) + return; + + // set up native surface + if (pNativeSurface != NULL) { + pNativeSurface->Release(); + pNativeSurface = NULL; + } + if (pNativeTexture != NULL) { + pNativeTexture->Release(); + pNativeTexture = NULL; + } + if (direct3ddevice->CreateTexture( + _srcRect.GetWidth(), + _srcRect.GetHeight(), + 1, + D3DUSAGE_RENDERTARGET, + color_depth_to_d3d_format(_mode.ColorDepth, false), + D3DPOOL_DEFAULT, + &pNativeTexture, + NULL) != D3D_OK) { + throw Ali3DException("CreateTexture failed"); + } + if (pNativeTexture->GetSurfaceLevel(0, &pNativeSurface) != D3D_OK) { + throw Ali3DException("GetSurfaceLevel failed"); + } + + direct3ddevice->ColorFill(pNativeSurface, NULL, 0); + + // create initial stage screen for plugin raw drawing + _stageVirtualScreen = CreateStageScreen(0, _srcRect.GetSize()); + // we must set Allegro's screen pointer to **something** + screen = (BITMAP *)_stageVirtualScreen->GetAllegroBitmap(); +} + +HRESULT D3DGraphicsDriver::ResetD3DDevice() { + // Direct3D documentation: + // Before calling the IDirect3DDevice9::Reset method for a device, + // an application should release any explicit render targets, depth stencil + // surfaces, additional swap chains, state blocks, and D3DPOOL_DEFAULT + // resources associated with the device. + if (pNativeSurface != NULL) { + pNativeSurface->Release(); + pNativeSurface = NULL; + } + if (pNativeTexture != NULL) { + pNativeTexture->Release(); + pNativeTexture = NULL; + } + return direct3ddevice->Reset(&d3dpp); +} + +bool D3DGraphicsDriver::SetNativeSize(const Size &src_size) { + OnSetNativeSize(src_size); + // Also make sure viewport is updated using new native & destination rectangles + SetupViewport(); + CreateVirtualScreen(); + return !_srcRect.IsEmpty(); +} + +bool D3DGraphicsDriver::SetRenderFrame(const Rect &dst_rect) { + OnSetRenderFrame(dst_rect); + // Also make sure viewport is updated using new native & destination rectangles + SetupViewport(); + return !_dstRect.IsEmpty(); +} + +int D3DGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const { + // TODO: check for device caps to know which depth is supported? + return 32; +} + +IGfxModeList *D3DGraphicsDriver::GetSupportedModeList(int color_depth) { + direct3d->AddRef(); + return new D3DGfxModeList(direct3d, color_depth_to_d3d_format(color_depth, false)); +} + +PGfxFilter D3DGraphicsDriver::GetGraphicsFilter() const { + return _filter; +} + +void D3DGraphicsDriver::UnInit() { #ifndef AGS_NO_VIDEO_PLAYER - // TODO: this should not be done inside the graphics driver! - dxmedia_shutdown_3d(); + // TODO: this should not be done inside the graphics driver! + dxmedia_shutdown_3d(); #endif - OnUnInit(); - ReleaseDisplayMode(); - - if (pNativeSurface) - { - pNativeSurface->Release(); - pNativeSurface = NULL; - } - if (pNativeTexture) - { - pNativeTexture->Release(); - pNativeTexture = NULL; - } - - if (vertexbuffer) - { - vertexbuffer->Release(); - vertexbuffer = NULL; - } - - if (pixelShader) - { - pixelShader->Release(); - pixelShader = NULL; - } - - if (direct3ddevice) - { - direct3ddevice->Release(); - direct3ddevice = NULL; - } -} - -D3DGraphicsDriver::~D3DGraphicsDriver() -{ - D3DGraphicsDriver::UnInit(); - - if (direct3d) - direct3d->Release(); -} - -void D3DGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) -{ - // NOTE: this function is practically useless at the moment, because D3D redraws whole game frame each time - if (!direct3ddevice) return; - Rect r(x1, y1, x2, y2); - r = _scaling.ScaleRange(r); - ClearScreenRect(r, colorToUse); -} - -void D3DGraphicsDriver::ClearScreenRect(const Rect &r, RGB *colorToUse) -{ - D3DRECT rectToClear; - rectToClear.x1 = r.Left; - rectToClear.y1 = r.Top; - rectToClear.x2 = r.Right + 1; - rectToClear.y2 = r.Bottom + 1; - DWORD colorDword = 0; - if (colorToUse != NULL) - colorDword = D3DCOLOR_XRGB(colorToUse->r, colorToUse->g, colorToUse->b); - direct3ddevice->Clear(1, &rectToClear, D3DCLEAR_TARGET, colorDword, 0.5f, 0); -} - -bool D3DGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) -{ - // Currently don't support copying in screen resolution when we are rendering in native - if (!_renderSprAtScreenRes) - at_native_res = true; - Size need_size = at_native_res ? _srcRect.GetSize() : _dstRect.GetSize(); - if (destination->GetColorDepth() != _mode.ColorDepth || destination->GetSize() != need_size) - { - if (want_fmt) - *want_fmt = GraphicResolution(need_size.Width, need_size.Height, _mode.ColorDepth); - return false; - } - // If we are rendering sprites at the screen resolution, and requested native res, - // re-render last frame to the native surface - if (at_native_res && _renderSprAtScreenRes) - { - _renderSprAtScreenRes = false; - _reDrawLastFrame(); - _render(true); - _renderSprAtScreenRes = true; - } - - IDirect3DSurface9* surface = NULL; - { - if (_pollingCallback) - _pollingCallback(); - - if (at_native_res) - { - // with render to texture the texture mipmap surface can't be locked directly - // we have to create a surface with D3DPOOL_SYSTEMMEM for GetRenderTargetData - if (direct3ddevice->CreateOffscreenPlainSurface( - _srcRect.GetWidth(), - _srcRect.GetHeight(), - color_depth_to_d3d_format(_mode.ColorDepth, false), - D3DPOOL_SYSTEMMEM, - &surface, - NULL) != D3D_OK) - { - throw Ali3DException("CreateOffscreenPlainSurface failed"); - } - if (direct3ddevice->GetRenderTargetData(pNativeSurface, surface) != D3D_OK) - { - throw Ali3DException("GetRenderTargetData failed"); - } - - } - // Get the back buffer surface - else if (direct3ddevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface) != D3D_OK) - { - throw Ali3DException("IDirect3DDevice9::GetBackBuffer failed"); - } - - if (_pollingCallback) - _pollingCallback(); - - D3DLOCKED_RECT lockedRect; - if (surface->LockRect(&lockedRect, (at_native_res ? NULL : &viewport_rect), D3DLOCK_READONLY ) != D3D_OK) - { - throw Ali3DException("IDirect3DSurface9::LockRect failed"); - } - - BitmapHelper::ReadPixelsFromMemory(destination, (uint8_t*)lockedRect.pBits, lockedRect.Pitch); - - surface->UnlockRect(); - surface->Release(); - - if (_pollingCallback) - _pollingCallback(); - } - return true; -} - -void D3DGraphicsDriver::RenderToBackBuffer() -{ - throw Ali3DException("D3D driver does not have a back buffer"); -} - -void D3DGraphicsDriver::Render() -{ - Render(0, 0, kFlip_None); -} - -void D3DGraphicsDriver::Render(int /*xoff*/, int /*yoff*/, GlobalFlipType /*flip*/) -{ - if (wnd_call_proc(wnd_reset_device)) - { - throw Ali3DFullscreenLostException(); - } - - _renderAndPresent(true); -} - -void D3DGraphicsDriver::_reDrawLastFrame() -{ - RestoreDrawLists(); -} - -void D3DGraphicsDriver::_renderSprite(const D3DDrawListEntry *drawListEntry, const D3DMATRIX &matGlobal) -{ - HRESULT hr; - D3DBitmap *bmpToDraw = drawListEntry->bitmap; - D3DMATRIX matSelfTransform; - D3DMATRIX matTransform; - - if (bmpToDraw->_transparency >= 255) - return; - - if (bmpToDraw->_tintSaturation > 0) - { - // Use custom pixel shader - float vector[8]; - if (_legacyPixelShader) - { - rgb_to_hsv(bmpToDraw->_red, bmpToDraw->_green, bmpToDraw->_blue, &vector[0], &vector[1], &vector[2]); - vector[0] /= 360.0; // In HSV, Hue is 0-360 - } - else - { - vector[0] = (float)bmpToDraw->_red / 256.0; - vector[1] = (float)bmpToDraw->_green / 256.0; - vector[2] = (float)bmpToDraw->_blue / 256.0; - } - - vector[3] = (float)bmpToDraw->_tintSaturation / 256.0; - - if (bmpToDraw->_transparency > 0) - vector[4] = (float)bmpToDraw->_transparency / 256.0; - else - vector[4] = 1.0f; - - if (bmpToDraw->_lightLevel > 0) - vector[5] = (float)bmpToDraw->_lightLevel / 256.0; - else - vector[5] = 1.0f; - - direct3ddevice->SetPixelShaderConstantF(0, &vector[0], 2); - direct3ddevice->SetPixelShader(pixelShader); - } - else - { - // Not using custom pixel shader; set up the default one - direct3ddevice->SetPixelShader(NULL); - int useTintRed = 255; - int useTintGreen = 255; - int useTintBlue = 255; - int useTransparency = 0xff; - int textureColorOp = D3DTOP_MODULATE; - - if ((bmpToDraw->_lightLevel > 0) && (bmpToDraw->_lightLevel < 256)) - { - // darkening the sprite... this stupid calculation is for - // consistency with the allegro software-mode code that does - // a trans blend with a (8,8,8) sprite - useTintRed = (bmpToDraw->_lightLevel * 192) / 256 + 64; - useTintGreen = useTintRed; - useTintBlue = useTintRed; - } - else if (bmpToDraw->_lightLevel > 256) - { - // ideally we would use a multi-stage operation here - // because we need to do TEXTURE + (TEXTURE x LIGHT) - // but is it worth having to set the device to 2-stage? - textureColorOp = D3DTOP_ADD; - useTintRed = (bmpToDraw->_lightLevel - 256) / 2; - useTintGreen = useTintRed; - useTintBlue = useTintRed; - } - - if (bmpToDraw->_transparency > 0) - { - useTransparency = bmpToDraw->_transparency; - } - - direct3ddevice->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(useTintRed, useTintGreen, useTintBlue, useTransparency)); - direct3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, textureColorOp); - direct3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - direct3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - - if (bmpToDraw->_transparency == 0) - { - // No transparency, use texture alpha component - direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - } - else - { - // Fixed transparency, use (TextureAlpha x FixedTranslucency) - direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - } - } - - if (bmpToDraw->_vertex == NULL) - { - hr = direct3ddevice->SetStreamSource(0, vertexbuffer, 0, sizeof(CUSTOMVERTEX)); - } - else - { - hr = direct3ddevice->SetStreamSource(0, bmpToDraw->_vertex, 0, sizeof(CUSTOMVERTEX)); - } - if (hr != D3D_OK) - { - throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); - } - - float width = bmpToDraw->GetWidthToRender(); - float height = bmpToDraw->GetHeightToRender(); - float xProportion = width / (float)bmpToDraw->_width; - float yProportion = height / (float)bmpToDraw->_height; - float drawAtX = drawListEntry->x; - float drawAtY = drawListEntry->y; - - for (int ti = 0; ti < bmpToDraw->_numTiles; ti++) - { - width = bmpToDraw->_tiles[ti].width * xProportion; - height = bmpToDraw->_tiles[ti].height * yProportion; - float xOffs; - float yOffs = bmpToDraw->_tiles[ti].y * yProportion; - if (bmpToDraw->_flipped) - xOffs = (bmpToDraw->_width - (bmpToDraw->_tiles[ti].x + bmpToDraw->_tiles[ti].width)) * xProportion; - else - xOffs = bmpToDraw->_tiles[ti].x * xProportion; - float thisX = drawAtX + xOffs; - float thisY = drawAtY + yOffs; - thisX = (-(_srcRect.GetWidth() / 2)) + thisX; - thisY = (_srcRect.GetHeight() / 2) - thisY; - - //Setup translation and scaling matrices - float widthToScale = (float)width; - float heightToScale = (float)height; - if (bmpToDraw->_flipped) - { - // The usual transform changes 0..1 into 0..width - // So first negate it (which changes 0..w into -w..0) - widthToScale = -widthToScale; - // and now shift it over to make it 0..w again - thisX += width; - } - - // Multiply object's own and global matrixes - MatrixTransform2D(matSelfTransform, (float)thisX - _pixelRenderXOffset, (float)thisY + _pixelRenderYOffset, widthToScale, heightToScale, 0.f); - MatrixMultiply(matTransform, matSelfTransform, matGlobal); - - if ((_smoothScaling) && bmpToDraw->_useResampler && (bmpToDraw->_stretchToHeight > 0) && - ((bmpToDraw->_stretchToHeight != bmpToDraw->_height) || - (bmpToDraw->_stretchToWidth != bmpToDraw->_width))) - { - direct3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - direct3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - } - else if (!_renderSprAtScreenRes) - { - direct3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - direct3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - } - else - { - _filter->SetSamplerStateForStandardSprite(direct3ddevice); - } - - direct3ddevice->SetTransform(D3DTS_WORLD, &matTransform); - direct3ddevice->SetTexture(0, bmpToDraw->_tiles[ti].texture); - - hr = direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, ti * 4, 2); - if (hr != D3D_OK) - { - throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); - } - - } -} - -void D3DGraphicsDriver::_renderFromTexture() -{ - if (direct3ddevice->SetStreamSource(0, vertexbuffer, 0, sizeof(CUSTOMVERTEX)) != D3D_OK) - { - throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); - } - - float width = _srcRect.GetWidth(); - float height = _srcRect.GetHeight(); - float drawAtX = -(_srcRect.GetWidth() / 2); - float drawAtY = _srcRect.GetHeight() / 2; - - D3DMATRIX matrix; - MatrixTransform2D(matrix, (float)drawAtX - _pixelRenderXOffset, (float)drawAtY + _pixelRenderYOffset, width, height, 0.f); - - direct3ddevice->SetTransform(D3DTS_WORLD, &matrix); - - direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - - _filter->SetSamplerStateForStandardSprite(direct3ddevice); - - direct3ddevice->SetTexture(0, pNativeTexture); - - if (direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2) != D3D_OK) - { - throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); - } -} - -void D3DGraphicsDriver::_renderAndPresent(bool clearDrawListAfterwards) -{ - _render(clearDrawListAfterwards); - direct3ddevice->Present(NULL, NULL, NULL, NULL); -} - -void D3DGraphicsDriver::_render(bool clearDrawListAfterwards) -{ - IDirect3DSurface9 *pBackBuffer = NULL; - - if (direct3ddevice->GetRenderTarget(0, &pBackBuffer) != D3D_OK) { - throw Ali3DException("IDirect3DSurface9::GetRenderTarget failed"); - } - direct3ddevice->ColorFill(pBackBuffer, nullptr, D3DCOLOR_RGBA(0, 0, 0, 255)); - - if (!_renderSprAtScreenRes) { - if (direct3ddevice->SetRenderTarget(0, pNativeSurface) != D3D_OK) - { - throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); - } - } - - direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); - if (direct3ddevice->BeginScene() != D3D_OK) - throw Ali3DException("IDirect3DDevice9::BeginScene failed"); - - // if showing at 2x size, the sprite can get distorted otherwise - direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP); - - RenderSpriteBatches(); - - if (!_renderSprAtScreenRes) { - if (direct3ddevice->SetRenderTarget(0, pBackBuffer)!= D3D_OK) - { - throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); - } - direct3ddevice->SetViewport(&_d3dViewport); - _renderFromTexture(); - } - - direct3ddevice->EndScene(); - - pBackBuffer->Release(); - - if (clearDrawListAfterwards) - { - BackupDrawLists(); - ClearDrawLists(); - } - ResetFxPool(); -} - -void D3DGraphicsDriver::RenderSpriteBatches() -{ - // Render all the sprite batches with necessary transformations - for (size_t i = 0; i <= _actSpriteBatch; ++i) - { - const Rect &viewport = _spriteBatches[i].Viewport; - const D3DSpriteBatch &batch = _spriteBatches[i]; - if (!viewport.IsEmpty()) - { - direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - RECT scissor; - if (_renderSprAtScreenRes) - { - scissor.left = _scaling.X.ScalePt(viewport.Left); - scissor.top = _scaling.Y.ScalePt(viewport.Top); - scissor.right = _scaling.X.ScalePt(viewport.Right + 1); - scissor.bottom = _scaling.Y.ScalePt(viewport.Bottom + 1); - } - else - { - scissor.left = viewport.Left; - scissor.top = viewport.Top; - scissor.right = viewport.Right + 1; - scissor.bottom = viewport.Bottom + 1; - } - direct3ddevice->SetScissorRect(&scissor); - } - else - { - direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - } - _stageVirtualScreen = GetStageScreen(i); - RenderSpriteBatch(batch); - } - - _stageVirtualScreen = GetStageScreen(0); - direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); -} - -void D3DGraphicsDriver::RenderSpriteBatch(const D3DSpriteBatch &batch) -{ - D3DDrawListEntry stageEntry; // raw-draw plugin support - - const std::vector &listToDraw = batch.List; - for (size_t i = 0; i < listToDraw.size(); ++i) - { - if (listToDraw[i].skip) - continue; - - const D3DDrawListEntry *sprite = &listToDraw[i]; - if (listToDraw[i].bitmap == NULL) - { - if (DoNullSpriteCallback(listToDraw[i].x, (int)direct3ddevice)) - stageEntry = D3DDrawListEntry((D3DBitmap*)_stageVirtualScreenDDB); - else - continue; - sprite = &stageEntry; - } - - this->_renderSprite(sprite, batch.Matrix); - } -} - -void D3DGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) -{ - if (_spriteBatches.size() <= index) - _spriteBatches.resize(index + 1); - _spriteBatches[index].List.clear(); - - Rect viewport = desc.Viewport; - // Combine both world transform and viewport transform into one matrix for faster perfomance - D3DMATRIX matRoomToViewport, matViewport, matViewportFinal; - // IMPORTANT: while the sprites are usually transformed in the order of Scale-Rotate-Translate, - // the camera's transformation is essentially reverse world transformation. And the operations - // are inverse: Translate-Rotate-Scale - MatrixTransformInverse2D(matRoomToViewport, - desc.Transform.X, -(desc.Transform.Y), - desc.Transform.ScaleX, desc.Transform.ScaleY, desc.Transform.Rotate); - // Next step is translate to viewport position; remove this if this is - // changed to a separate operation at some point - // TODO: find out if this is an optimal way to translate scaled room into Top-Left screen coordinates - float scaled_offx = (_srcRect.GetWidth() - desc.Transform.ScaleX * (float)_srcRect.GetWidth()) / 2.f; - float scaled_offy = (_srcRect.GetHeight() - desc.Transform.ScaleY * (float)_srcRect.GetHeight()) / 2.f; - MatrixTranslate(matViewport, viewport.Left - scaled_offx, -(viewport.Top - scaled_offy), 0.f); - MatrixMultiply(matViewportFinal, matRoomToViewport, matViewport); - - // Then apply global node transformation (flip and offset) - int node_tx = desc.Offset.X, node_ty = desc.Offset.Y; - float node_sx = 1.f, node_sy = 1.f; - if ((desc.Flip == kFlip_Vertical) || (desc.Flip == kFlip_Both)) - { - int left = _srcRect.GetWidth() - (viewport.Right + 1); - viewport.MoveToX(left); - node_sx = -1.f; - } - if ((desc.Flip == kFlip_Horizontal) || (desc.Flip == kFlip_Both)) - { - int top = _srcRect.GetHeight() - (viewport.Bottom + 1); - viewport.MoveToY(top); - node_sy = -1.f; - } - viewport = Rect::MoveBy(viewport, node_tx, node_ty); - D3DMATRIX matFlip; - MatrixTransform2D(matFlip, node_tx, -(node_ty), node_sx, node_sy, 0.f); - MatrixMultiply(_spriteBatches[index].Matrix, matViewportFinal, matFlip); - _spriteBatches[index].Viewport = viewport; - - // create stage screen for plugin raw drawing - int src_w = viewport.GetWidth() / desc.Transform.ScaleX; - int src_h = viewport.GetHeight() / desc.Transform.ScaleY; - CreateStageScreen(index, Size(src_w, src_h)); -} - -void D3DGraphicsDriver::ResetAllBatches() -{ - for (size_t i = 0; i < _spriteBatches.size(); ++i) - _spriteBatches[i].List.clear(); -} - -void D3DGraphicsDriver::ClearDrawBackups() -{ - _backupBatchDescs.clear(); - _backupBatches.clear(); -} - -void D3DGraphicsDriver::BackupDrawLists() -{ - ClearDrawBackups(); - for (size_t i = 0; i <= _actSpriteBatch; ++i) - { - _backupBatchDescs.push_back(_spriteBatchDesc[i]); - _backupBatches.push_back(_spriteBatches[i]); - } -} - -void D3DGraphicsDriver::RestoreDrawLists() -{ - if (_backupBatchDescs.size() == 0) - { - ClearDrawLists(); - return; - } - _spriteBatchDesc = _backupBatchDescs; - _spriteBatches = _backupBatches; - _actSpriteBatch = _backupBatchDescs.size() - 1; -} - -void D3DGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) -{ - _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry((D3DBitmap*)bitmap, x, y)); -} - -void D3DGraphicsDriver::DestroyDDB(IDriverDependantBitmap* bitmap) -{ - // Remove deleted DDB from backups - for (D3DSpriteBatches::iterator it = _backupBatches.begin(); it != _backupBatches.end(); ++it) - { - std::vector &drawlist = it->List; - for (size_t i = 0; i < drawlist.size(); i++) - { - if (drawlist[i].bitmap == bitmap) - drawlist[i].skip = true; - } - } - delete bitmap; -} - -void D3DGraphicsDriver::UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap, D3DBitmap *target, bool hasAlpha) -{ - IDirect3DTexture9* newTexture = tile->texture; - - D3DLOCKED_RECT lockedRegion; - HRESULT hr = newTexture->LockRect(0, &lockedRegion, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD); - if (hr != D3D_OK) - { - throw Ali3DException("Unable to lock texture"); - } - - bool usingLinearFiltering = _filter->NeedToColourEdgeLines(); - char *memPtr = (char*)lockedRegion.pBits; - - if (target->_opaque) - BitmapToVideoMemOpaque(bitmap, hasAlpha, tile, target, memPtr, lockedRegion.Pitch); - else - BitmapToVideoMem(bitmap, hasAlpha, tile, target, memPtr, lockedRegion.Pitch, usingLinearFiltering); - - newTexture->UnlockRect(0); -} - -void D3DGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) -{ - D3DBitmap *target = (D3DBitmap*)bitmapToUpdate; - if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) - throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); - const int color_depth = bitmap->GetColorDepth(); - if (color_depth != target->_colDepth) - throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); - - target->_hasAlpha = hasAlpha; - if (color_depth == 8) - select_palette(palette); - - for (int i = 0; i < target->_numTiles; i++) - { - UpdateTextureRegion(&target->_tiles[i], bitmap, target, hasAlpha); - } - - if (color_depth == 8) - unselect_palette(); -} - -int D3DGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) -{ - if (color_depth == 8) - return 8; - if (color_depth > 8 && color_depth <= 16) - return 16; - return 32; -} - -void D3DGraphicsDriver::AdjustSizeToNearestSupportedByCard(int *width, int *height) -{ - int allocatedWidth = *width, allocatedHeight = *height; - - if (direct3ddevicecaps.TextureCaps & D3DPTEXTURECAPS_POW2) - { - bool foundWidth = false, foundHeight = false; - int tryThis = 2; - while ((!foundWidth) || (!foundHeight)) - { - if ((tryThis >= allocatedWidth) && (!foundWidth)) - { - allocatedWidth = tryThis; - foundWidth = true; - } - - if ((tryThis >= allocatedHeight) && (!foundHeight)) - { - allocatedHeight = tryThis; - foundHeight = true; - } - - tryThis = tryThis << 1; - } - } - - if (direct3ddevicecaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) - { - if (allocatedWidth > allocatedHeight) - { - allocatedHeight = allocatedWidth; - } - else - { - allocatedWidth = allocatedHeight; - } - } - - *width = allocatedWidth; - *height = allocatedHeight; -} - -bool D3DGraphicsDriver::IsTextureFormatOk( D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat ) -{ - HRESULT hr = direct3d->CheckDeviceFormat( D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - AdapterFormat, - 0, - D3DRTYPE_TEXTURE, - TextureFormat); - - return SUCCEEDED( hr ); -} - -IDriverDependantBitmap* D3DGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) -{ - int allocatedWidth = bitmap->GetWidth(); - int allocatedHeight = bitmap->GetHeight(); - if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) - throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); - int colourDepth = bitmap->GetColorDepth(); - - D3DBitmap *ddb = new D3DBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); - - AdjustSizeToNearestSupportedByCard(&allocatedWidth, &allocatedHeight); - int tilesAcross = 1, tilesDown = 1; - - // *************** REMOVE THESE LINES ************* - //direct3ddevicecaps.MaxTextureWidth = 64; - //direct3ddevicecaps.MaxTextureHeight = 256; - // *************** END REMOVE THESE LINES ************* - - // Calculate how many textures will be necessary to - // store this image - tilesAcross = (allocatedWidth + direct3ddevicecaps.MaxTextureWidth - 1) / direct3ddevicecaps.MaxTextureWidth; - tilesDown = (allocatedHeight + direct3ddevicecaps.MaxTextureHeight - 1) / direct3ddevicecaps.MaxTextureHeight; - int tileWidth = bitmap->GetWidth() / tilesAcross; - int lastTileExtraWidth = bitmap->GetWidth() % tilesAcross; - int tileHeight = bitmap->GetHeight() / tilesDown; - int lastTileExtraHeight = bitmap->GetHeight() % tilesDown; - int tileAllocatedWidth = tileWidth; - int tileAllocatedHeight = tileHeight; - - AdjustSizeToNearestSupportedByCard(&tileAllocatedWidth, &tileAllocatedHeight); - - int numTiles = tilesAcross * tilesDown; - D3DTextureTile *tiles = (D3DTextureTile*)malloc(sizeof(D3DTextureTile) * numTiles); - memset(tiles, 0, sizeof(D3DTextureTile) * numTiles); - - CUSTOMVERTEX *vertices = NULL; - - if ((numTiles == 1) && - (allocatedWidth == bitmap->GetWidth()) && - (allocatedHeight == bitmap->GetHeight())) - { - // use default whole-image vertices - } - else - { - // The texture is not the same as the bitmap, so create some custom vertices - // so that only the relevant portion of the texture is rendered - int vertexBufferSize = numTiles * 4 * sizeof(CUSTOMVERTEX); - HRESULT hr = direct3ddevice->CreateVertexBuffer(vertexBufferSize, 0, - D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &ddb->_vertex, NULL); - - if (hr != D3D_OK) - { - free(tiles); - char errorMessage[200]; - sprintf(errorMessage, "Direct3DDevice9::CreateVertexBuffer(Length=%d) for texture failed: error code %08X", vertexBufferSize, hr); - throw Ali3DException(errorMessage); - } - - if (ddb->_vertex->Lock(0, 0, (void**)&vertices, D3DLOCK_DISCARD) != D3D_OK) - { - free(tiles); - throw Ali3DException("Failed to lock vertex buffer"); - } - } - - for (int x = 0; x < tilesAcross; x++) - { - for (int y = 0; y < tilesDown; y++) - { - D3DTextureTile *thisTile = &tiles[y * tilesAcross + x]; - int thisAllocatedWidth = tileAllocatedWidth; - int thisAllocatedHeight = tileAllocatedHeight; - thisTile->x = x * tileWidth; - thisTile->y = y * tileHeight; - thisTile->width = tileWidth; - thisTile->height = tileHeight; - if (x == tilesAcross - 1) - { - thisTile->width += lastTileExtraWidth; - thisAllocatedWidth = thisTile->width; - AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); - } - if (y == tilesDown - 1) - { - thisTile->height += lastTileExtraHeight; - thisAllocatedHeight = thisTile->height; - AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); - } - - if (vertices != NULL) - { - for (int vidx = 0; vidx < 4; vidx++) - { - int i = (y * tilesAcross + x) * 4 + vidx; - vertices[i] = defaultVertices[vidx]; - if (vertices[i].tu > 0.0) - { - vertices[i].tu = (float)thisTile->width / (float)thisAllocatedWidth; - } - if (vertices[i].tv > 0.0) - { - vertices[i].tv = (float)thisTile->height / (float)thisAllocatedHeight; - } - } - } - - // NOTE: pay attention that the texture format depends on the **display mode**'s color format, - // rather than source bitmap's color depth! - D3DFORMAT textureFormat = color_depth_to_d3d_format(_mode.ColorDepth, !opaque); - HRESULT hr = direct3ddevice->CreateTexture(thisAllocatedWidth, thisAllocatedHeight, 1, 0, - textureFormat, - D3DPOOL_MANAGED, &thisTile->texture, NULL); - if (hr != D3D_OK) - { - char errorMessage[200]; - sprintf(errorMessage, "Direct3DDevice9::CreateTexture(X=%d, Y=%d, FMT=%d) failed: error code %08X", thisAllocatedWidth, thisAllocatedHeight, textureFormat, hr); - throw Ali3DException(errorMessage); - } - - } - } - - if (vertices != NULL) - { - ddb->_vertex->Unlock(); - } - - ddb->_numTiles = numTiles; - ddb->_tiles = tiles; - - UpdateDDBFromBitmap(ddb, bitmap, hasAlpha); - - return ddb; -} - -void D3DGraphicsDriver::do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - // Construct scene in order: game screen, fade fx, post game overlay - // NOTE: please keep in mind: redrawing last saved frame here instead of constructing new one - // is done because of backwards-compatibility issue: originally AGS faded out using frame - // drawn before the script that triggers blocking fade (e.g. instigated by ChangeRoom). - // Unfortunately some existing games were changing looks of the screen during same function, - // but these were not supposed to get on screen until before fade-in. - if (fadingOut) - this->_reDrawLastFrame(); - else if (_drawScreenCallback != NULL) - _drawScreenCallback(); - Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); - blackSquare->Clear(makecol32(targetColourRed, targetColourGreen, targetColourBlue)); - IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); - delete blackSquare; - BeginSpriteBatch(_srcRect, SpriteTransform()); - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - this->DrawSprite(0, 0, d3db); - if (_drawPostScreenCallback != NULL) - _drawPostScreenCallback(); - - if (speed <= 0) speed = 16; - speed *= 2; // harmonise speeds with software driver which is faster - for (int a = 1; a < 255; a += speed) - { - d3db->SetTransparency(fadingOut ? a : (255 - a)); - this->_renderAndPresent(false); - - if (_pollingCallback) - _pollingCallback(); - WaitForNextFrame(); - } - - if (fadingOut) - { - d3db->SetTransparency(0); - this->_renderAndPresent(false); - } - - this->DestroyDDB(d3db); - this->ClearDrawLists(); - ResetFxPool(); -} - -void D3DGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - do_fade(true, speed, targetColourRed, targetColourGreen, targetColourBlue); -} - -void D3DGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) -{ - do_fade(false, speed, targetColourRed, targetColourGreen, targetColourBlue); -} - -void D3DGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) -{ - // Construct scene in order: game screen, fade fx, post game overlay - if (blackingOut) - this->_reDrawLastFrame(); - else if (_drawScreenCallback != NULL) - _drawScreenCallback(); - Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); - blackSquare->Clear(); - IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); - delete blackSquare; - BeginSpriteBatch(_srcRect, SpriteTransform()); - size_t fx_batch = _actSpriteBatch; - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - this->DrawSprite(0, 0, d3db); - if (!blackingOut) - { - // when fading in, draw four black boxes, one - // across each side of the screen - this->DrawSprite(0, 0, d3db); - this->DrawSprite(0, 0, d3db); - this->DrawSprite(0, 0, d3db); - } - if (_drawPostScreenCallback != NULL) - _drawPostScreenCallback(); - - int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); - int boxWidth = speed; - int boxHeight = yspeed; - - while (boxWidth < _srcRect.GetWidth()) - { - boxWidth += speed; - boxHeight += yspeed; - D3DSpriteBatch &batch = _spriteBatches[fx_batch]; - std::vector &drawList = batch.List; - const size_t last = drawList.size() - 1; - if (blackingOut) - { - drawList[last].x = _srcRect.GetWidth() / 2- boxWidth / 2; - drawList[last].y = _srcRect.GetHeight() / 2 - boxHeight / 2; - d3db->SetStretch(boxWidth, boxHeight, false); - } - else - { - drawList[last - 3].x = _srcRect.GetWidth() / 2 - boxWidth / 2 - _srcRect.GetWidth(); - drawList[last - 2].y = _srcRect.GetHeight() / 2 - boxHeight / 2 - _srcRect.GetHeight(); - drawList[last - 1].x = _srcRect.GetWidth() / 2 + boxWidth / 2; - drawList[last ].y = _srcRect.GetHeight() / 2 + boxHeight / 2; - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - } - - this->_renderAndPresent(false); - - if (_pollingCallback) - _pollingCallback(); - platform->Delay(delay); - } - - this->DestroyDDB(d3db); - this->ClearDrawLists(); - ResetFxPool(); + OnUnInit(); + ReleaseDisplayMode(); + + if (pNativeSurface) { + pNativeSurface->Release(); + pNativeSurface = NULL; + } + if (pNativeTexture) { + pNativeTexture->Release(); + pNativeTexture = NULL; + } + + if (vertexbuffer) { + vertexbuffer->Release(); + vertexbuffer = NULL; + } + + if (pixelShader) { + pixelShader->Release(); + pixelShader = NULL; + } + + if (direct3ddevice) { + direct3ddevice->Release(); + direct3ddevice = NULL; + } +} + +D3DGraphicsDriver::~D3DGraphicsDriver() { + D3DGraphicsDriver::UnInit(); + + if (direct3d) + direct3d->Release(); +} + +void D3DGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) { + // NOTE: this function is practically useless at the moment, because D3D redraws whole game frame each time + if (!direct3ddevice) return; + Rect r(x1, y1, x2, y2); + r = _scaling.ScaleRange(r); + ClearScreenRect(r, colorToUse); +} + +void D3DGraphicsDriver::ClearScreenRect(const Rect &r, RGB *colorToUse) { + D3DRECT rectToClear; + rectToClear.x1 = r.Left; + rectToClear.y1 = r.Top; + rectToClear.x2 = r.Right + 1; + rectToClear.y2 = r.Bottom + 1; + DWORD colorDword = 0; + if (colorToUse != NULL) + colorDword = D3DCOLOR_XRGB(colorToUse->r, colorToUse->g, colorToUse->b); + direct3ddevice->Clear(1, &rectToClear, D3DCLEAR_TARGET, colorDword, 0.5f, 0); +} + +bool D3DGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) { + // Currently don't support copying in screen resolution when we are rendering in native + if (!_renderSprAtScreenRes) + at_native_res = true; + Size need_size = at_native_res ? _srcRect.GetSize() : _dstRect.GetSize(); + if (destination->GetColorDepth() != _mode.ColorDepth || destination->GetSize() != need_size) { + if (want_fmt) + *want_fmt = GraphicResolution(need_size.Width, need_size.Height, _mode.ColorDepth); + return false; + } + // If we are rendering sprites at the screen resolution, and requested native res, + // re-render last frame to the native surface + if (at_native_res && _renderSprAtScreenRes) { + _renderSprAtScreenRes = false; + _reDrawLastFrame(); + _render(true); + _renderSprAtScreenRes = true; + } + + IDirect3DSurface9 *surface = NULL; + { + if (_pollingCallback) + _pollingCallback(); + + if (at_native_res) { + // with render to texture the texture mipmap surface can't be locked directly + // we have to create a surface with D3DPOOL_SYSTEMMEM for GetRenderTargetData + if (direct3ddevice->CreateOffscreenPlainSurface( + _srcRect.GetWidth(), + _srcRect.GetHeight(), + color_depth_to_d3d_format(_mode.ColorDepth, false), + D3DPOOL_SYSTEMMEM, + &surface, + NULL) != D3D_OK) { + throw Ali3DException("CreateOffscreenPlainSurface failed"); + } + if (direct3ddevice->GetRenderTargetData(pNativeSurface, surface) != D3D_OK) { + throw Ali3DException("GetRenderTargetData failed"); + } + + } + // Get the back buffer surface + else if (direct3ddevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface) != D3D_OK) { + throw Ali3DException("IDirect3DDevice9::GetBackBuffer failed"); + } + + if (_pollingCallback) + _pollingCallback(); + + D3DLOCKED_RECT lockedRect; + if (surface->LockRect(&lockedRect, (at_native_res ? NULL : &viewport_rect), D3DLOCK_READONLY) != D3D_OK) { + throw Ali3DException("IDirect3DSurface9::LockRect failed"); + } + + BitmapHelper::ReadPixelsFromMemory(destination, (uint8_t *)lockedRect.pBits, lockedRect.Pitch); + + surface->UnlockRect(); + surface->Release(); + + if (_pollingCallback) + _pollingCallback(); + } + return true; +} + +void D3DGraphicsDriver::RenderToBackBuffer() { + throw Ali3DException("D3D driver does not have a back buffer"); +} + +void D3DGraphicsDriver::Render() { + Render(0, 0, kFlip_None); +} + +void D3DGraphicsDriver::Render(int /*xoff*/, int /*yoff*/, GlobalFlipType /*flip*/) { + if (wnd_call_proc(wnd_reset_device)) { + throw Ali3DFullscreenLostException(); + } + + _renderAndPresent(true); +} + +void D3DGraphicsDriver::_reDrawLastFrame() { + RestoreDrawLists(); +} + +void D3DGraphicsDriver::_renderSprite(const D3DDrawListEntry *drawListEntry, const D3DMATRIX &matGlobal) { + HRESULT hr; + D3DBitmap *bmpToDraw = drawListEntry->bitmap; + D3DMATRIX matSelfTransform; + D3DMATRIX matTransform; + + if (bmpToDraw->_transparency >= 255) + return; + + if (bmpToDraw->_tintSaturation > 0) { + // Use custom pixel shader + float vector[8]; + if (_legacyPixelShader) { + rgb_to_hsv(bmpToDraw->_red, bmpToDraw->_green, bmpToDraw->_blue, &vector[0], &vector[1], &vector[2]); + vector[0] /= 360.0; // In HSV, Hue is 0-360 + } else { + vector[0] = (float)bmpToDraw->_red / 256.0; + vector[1] = (float)bmpToDraw->_green / 256.0; + vector[2] = (float)bmpToDraw->_blue / 256.0; + } + + vector[3] = (float)bmpToDraw->_tintSaturation / 256.0; + + if (bmpToDraw->_transparency > 0) + vector[4] = (float)bmpToDraw->_transparency / 256.0; + else + vector[4] = 1.0f; + + if (bmpToDraw->_lightLevel > 0) + vector[5] = (float)bmpToDraw->_lightLevel / 256.0; + else + vector[5] = 1.0f; + + direct3ddevice->SetPixelShaderConstantF(0, &vector[0], 2); + direct3ddevice->SetPixelShader(pixelShader); + } else { + // Not using custom pixel shader; set up the default one + direct3ddevice->SetPixelShader(NULL); + int useTintRed = 255; + int useTintGreen = 255; + int useTintBlue = 255; + int useTransparency = 0xff; + int textureColorOp = D3DTOP_MODULATE; + + if ((bmpToDraw->_lightLevel > 0) && (bmpToDraw->_lightLevel < 256)) { + // darkening the sprite... this stupid calculation is for + // consistency with the allegro software-mode code that does + // a trans blend with a (8,8,8) sprite + useTintRed = (bmpToDraw->_lightLevel * 192) / 256 + 64; + useTintGreen = useTintRed; + useTintBlue = useTintRed; + } else if (bmpToDraw->_lightLevel > 256) { + // ideally we would use a multi-stage operation here + // because we need to do TEXTURE + (TEXTURE x LIGHT) + // but is it worth having to set the device to 2-stage? + textureColorOp = D3DTOP_ADD; + useTintRed = (bmpToDraw->_lightLevel - 256) / 2; + useTintGreen = useTintRed; + useTintBlue = useTintRed; + } + + if (bmpToDraw->_transparency > 0) { + useTransparency = bmpToDraw->_transparency; + } + + direct3ddevice->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(useTintRed, useTintGreen, useTintBlue, useTransparency)); + direct3ddevice->SetTextureStageState(0, D3DTSS_COLOROP, textureColorOp); + direct3ddevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + direct3ddevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + + if (bmpToDraw->_transparency == 0) { + // No transparency, use texture alpha component + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + } else { + // Fixed transparency, use (TextureAlpha x FixedTranslucency) + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); + } + } + + if (bmpToDraw->_vertex == NULL) { + hr = direct3ddevice->SetStreamSource(0, vertexbuffer, 0, sizeof(CUSTOMVERTEX)); + } else { + hr = direct3ddevice->SetStreamSource(0, bmpToDraw->_vertex, 0, sizeof(CUSTOMVERTEX)); + } + if (hr != D3D_OK) { + throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); + } + + float width = bmpToDraw->GetWidthToRender(); + float height = bmpToDraw->GetHeightToRender(); + float xProportion = width / (float)bmpToDraw->_width; + float yProportion = height / (float)bmpToDraw->_height; + float drawAtX = drawListEntry->x; + float drawAtY = drawListEntry->y; + + for (int ti = 0; ti < bmpToDraw->_numTiles; ti++) { + width = bmpToDraw->_tiles[ti].width * xProportion; + height = bmpToDraw->_tiles[ti].height * yProportion; + float xOffs; + float yOffs = bmpToDraw->_tiles[ti].y * yProportion; + if (bmpToDraw->_flipped) + xOffs = (bmpToDraw->_width - (bmpToDraw->_tiles[ti].x + bmpToDraw->_tiles[ti].width)) * xProportion; + else + xOffs = bmpToDraw->_tiles[ti].x * xProportion; + float thisX = drawAtX + xOffs; + float thisY = drawAtY + yOffs; + thisX = (-(_srcRect.GetWidth() / 2)) + thisX; + thisY = (_srcRect.GetHeight() / 2) - thisY; + + //Setup translation and scaling matrices + float widthToScale = (float)width; + float heightToScale = (float)height; + if (bmpToDraw->_flipped) { + // The usual transform changes 0..1 into 0..width + // So first negate it (which changes 0..w into -w..0) + widthToScale = -widthToScale; + // and now shift it over to make it 0..w again + thisX += width; + } + + // Multiply object's own and global matrixes + MatrixTransform2D(matSelfTransform, (float)thisX - _pixelRenderXOffset, (float)thisY + _pixelRenderYOffset, widthToScale, heightToScale, 0.f); + MatrixMultiply(matTransform, matSelfTransform, matGlobal); + + if ((_smoothScaling) && bmpToDraw->_useResampler && (bmpToDraw->_stretchToHeight > 0) && + ((bmpToDraw->_stretchToHeight != bmpToDraw->_height) || + (bmpToDraw->_stretchToWidth != bmpToDraw->_width))) { + direct3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + direct3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + } else if (!_renderSprAtScreenRes) { + direct3ddevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + direct3ddevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + } else { + _filter->SetSamplerStateForStandardSprite(direct3ddevice); + } + + direct3ddevice->SetTransform(D3DTS_WORLD, &matTransform); + direct3ddevice->SetTexture(0, bmpToDraw->_tiles[ti].texture); + + hr = direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, ti * 4, 2); + if (hr != D3D_OK) { + throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); + } + + } +} + +void D3DGraphicsDriver::_renderFromTexture() { + if (direct3ddevice->SetStreamSource(0, vertexbuffer, 0, sizeof(CUSTOMVERTEX)) != D3D_OK) { + throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); + } + + float width = _srcRect.GetWidth(); + float height = _srcRect.GetHeight(); + float drawAtX = -(_srcRect.GetWidth() / 2); + float drawAtY = _srcRect.GetHeight() / 2; + + D3DMATRIX matrix; + MatrixTransform2D(matrix, (float)drawAtX - _pixelRenderXOffset, (float)drawAtY + _pixelRenderYOffset, width, height, 0.f); + + direct3ddevice->SetTransform(D3DTS_WORLD, &matrix); + + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + direct3ddevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + + _filter->SetSamplerStateForStandardSprite(direct3ddevice); + + direct3ddevice->SetTexture(0, pNativeTexture); + + if (direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2) != D3D_OK) { + throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); + } +} + +void D3DGraphicsDriver::_renderAndPresent(bool clearDrawListAfterwards) { + _render(clearDrawListAfterwards); + direct3ddevice->Present(NULL, NULL, NULL, NULL); +} + +void D3DGraphicsDriver::_render(bool clearDrawListAfterwards) { + IDirect3DSurface9 *pBackBuffer = NULL; + + if (direct3ddevice->GetRenderTarget(0, &pBackBuffer) != D3D_OK) { + throw Ali3DException("IDirect3DSurface9::GetRenderTarget failed"); + } + direct3ddevice->ColorFill(pBackBuffer, nullptr, D3DCOLOR_RGBA(0, 0, 0, 255)); + + if (!_renderSprAtScreenRes) { + if (direct3ddevice->SetRenderTarget(0, pNativeSurface) != D3D_OK) { + throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); + } + } + + direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); + if (direct3ddevice->BeginScene() != D3D_OK) + throw Ali3DException("IDirect3DDevice9::BeginScene failed"); + + // if showing at 2x size, the sprite can get distorted otherwise + direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP); + + RenderSpriteBatches(); + + if (!_renderSprAtScreenRes) { + if (direct3ddevice->SetRenderTarget(0, pBackBuffer) != D3D_OK) { + throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); + } + direct3ddevice->SetViewport(&_d3dViewport); + _renderFromTexture(); + } + + direct3ddevice->EndScene(); + + pBackBuffer->Release(); + + if (clearDrawListAfterwards) { + BackupDrawLists(); + ClearDrawLists(); + } + ResetFxPool(); +} + +void D3DGraphicsDriver::RenderSpriteBatches() { + // Render all the sprite batches with necessary transformations + for (size_t i = 0; i <= _actSpriteBatch; ++i) { + const Rect &viewport = _spriteBatches[i].Viewport; + const D3DSpriteBatch &batch = _spriteBatches[i]; + if (!viewport.IsEmpty()) { + direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + RECT scissor; + if (_renderSprAtScreenRes) { + scissor.left = _scaling.X.ScalePt(viewport.Left); + scissor.top = _scaling.Y.ScalePt(viewport.Top); + scissor.right = _scaling.X.ScalePt(viewport.Right + 1); + scissor.bottom = _scaling.Y.ScalePt(viewport.Bottom + 1); + } else { + scissor.left = viewport.Left; + scissor.top = viewport.Top; + scissor.right = viewport.Right + 1; + scissor.bottom = viewport.Bottom + 1; + } + direct3ddevice->SetScissorRect(&scissor); + } else { + direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + } + _stageVirtualScreen = GetStageScreen(i); + RenderSpriteBatch(batch); + } + + _stageVirtualScreen = GetStageScreen(0); + direct3ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); +} + +void D3DGraphicsDriver::RenderSpriteBatch(const D3DSpriteBatch &batch) { + D3DDrawListEntry stageEntry; // raw-draw plugin support + + const std::vector &listToDraw = batch.List; + for (size_t i = 0; i < listToDraw.size(); ++i) { + if (listToDraw[i].skip) + continue; + + const D3DDrawListEntry *sprite = &listToDraw[i]; + if (listToDraw[i].bitmap == NULL) { + if (DoNullSpriteCallback(listToDraw[i].x, (int)direct3ddevice)) + stageEntry = D3DDrawListEntry((D3DBitmap *)_stageVirtualScreenDDB); + else + continue; + sprite = &stageEntry; + } + + this->_renderSprite(sprite, batch.Matrix); + } +} + +void D3DGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) { + if (_spriteBatches.size() <= index) + _spriteBatches.resize(index + 1); + _spriteBatches[index].List.clear(); + + Rect viewport = desc.Viewport; + // Combine both world transform and viewport transform into one matrix for faster perfomance + D3DMATRIX matRoomToViewport, matViewport, matViewportFinal; + // IMPORTANT: while the sprites are usually transformed in the order of Scale-Rotate-Translate, + // the camera's transformation is essentially reverse world transformation. And the operations + // are inverse: Translate-Rotate-Scale + MatrixTransformInverse2D(matRoomToViewport, + desc.Transform.X, -(desc.Transform.Y), + desc.Transform.ScaleX, desc.Transform.ScaleY, desc.Transform.Rotate); + // Next step is translate to viewport position; remove this if this is + // changed to a separate operation at some point + // TODO: find out if this is an optimal way to translate scaled room into Top-Left screen coordinates + float scaled_offx = (_srcRect.GetWidth() - desc.Transform.ScaleX * (float)_srcRect.GetWidth()) / 2.f; + float scaled_offy = (_srcRect.GetHeight() - desc.Transform.ScaleY * (float)_srcRect.GetHeight()) / 2.f; + MatrixTranslate(matViewport, viewport.Left - scaled_offx, -(viewport.Top - scaled_offy), 0.f); + MatrixMultiply(matViewportFinal, matRoomToViewport, matViewport); + + // Then apply global node transformation (flip and offset) + int node_tx = desc.Offset.X, node_ty = desc.Offset.Y; + float node_sx = 1.f, node_sy = 1.f; + if ((desc.Flip == kFlip_Vertical) || (desc.Flip == kFlip_Both)) { + int left = _srcRect.GetWidth() - (viewport.Right + 1); + viewport.MoveToX(left); + node_sx = -1.f; + } + if ((desc.Flip == kFlip_Horizontal) || (desc.Flip == kFlip_Both)) { + int top = _srcRect.GetHeight() - (viewport.Bottom + 1); + viewport.MoveToY(top); + node_sy = -1.f; + } + viewport = Rect::MoveBy(viewport, node_tx, node_ty); + D3DMATRIX matFlip; + MatrixTransform2D(matFlip, node_tx, -(node_ty), node_sx, node_sy, 0.f); + MatrixMultiply(_spriteBatches[index].Matrix, matViewportFinal, matFlip); + _spriteBatches[index].Viewport = viewport; + + // create stage screen for plugin raw drawing + int src_w = viewport.GetWidth() / desc.Transform.ScaleX; + int src_h = viewport.GetHeight() / desc.Transform.ScaleY; + CreateStageScreen(index, Size(src_w, src_h)); +} + +void D3DGraphicsDriver::ResetAllBatches() { + for (size_t i = 0; i < _spriteBatches.size(); ++i) + _spriteBatches[i].List.clear(); +} + +void D3DGraphicsDriver::ClearDrawBackups() { + _backupBatchDescs.clear(); + _backupBatches.clear(); +} + +void D3DGraphicsDriver::BackupDrawLists() { + ClearDrawBackups(); + for (size_t i = 0; i <= _actSpriteBatch; ++i) { + _backupBatchDescs.push_back(_spriteBatchDesc[i]); + _backupBatches.push_back(_spriteBatches[i]); + } +} + +void D3DGraphicsDriver::RestoreDrawLists() { + if (_backupBatchDescs.size() == 0) { + ClearDrawLists(); + return; + } + _spriteBatchDesc = _backupBatchDescs; + _spriteBatches = _backupBatches; + _actSpriteBatch = _backupBatchDescs.size() - 1; +} + +void D3DGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) { + _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry((D3DBitmap *)bitmap, x, y)); +} + +void D3DGraphicsDriver::DestroyDDB(IDriverDependantBitmap *bitmap) { + // Remove deleted DDB from backups + for (D3DSpriteBatches::iterator it = _backupBatches.begin(); it != _backupBatches.end(); ++it) { + std::vector &drawlist = it->List; + for (size_t i = 0; i < drawlist.size(); i++) { + if (drawlist[i].bitmap == bitmap) + drawlist[i].skip = true; + } + } + delete bitmap; +} + +void D3DGraphicsDriver::UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap, D3DBitmap *target, bool hasAlpha) { + IDirect3DTexture9 *newTexture = tile->texture; + + D3DLOCKED_RECT lockedRegion; + HRESULT hr = newTexture->LockRect(0, &lockedRegion, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD); + if (hr != D3D_OK) { + throw Ali3DException("Unable to lock texture"); + } + + bool usingLinearFiltering = _filter->NeedToColourEdgeLines(); + char *memPtr = (char *)lockedRegion.pBits; + + if (target->_opaque) + BitmapToVideoMemOpaque(bitmap, hasAlpha, tile, target, memPtr, lockedRegion.Pitch); + else + BitmapToVideoMem(bitmap, hasAlpha, tile, target, memPtr, lockedRegion.Pitch, usingLinearFiltering); + + newTexture->UnlockRect(0); +} + +void D3DGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { + D3DBitmap *target = (D3DBitmap *)bitmapToUpdate; + if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) + throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); + const int color_depth = bitmap->GetColorDepth(); + if (color_depth != target->_colDepth) + throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); + + target->_hasAlpha = hasAlpha; + if (color_depth == 8) + select_palette(palette); + + for (int i = 0; i < target->_numTiles; i++) { + UpdateTextureRegion(&target->_tiles[i], bitmap, target, hasAlpha); + } + + if (color_depth == 8) + unselect_palette(); +} + +int D3DGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) { + if (color_depth == 8) + return 8; + if (color_depth > 8 && color_depth <= 16) + return 16; + return 32; +} + +void D3DGraphicsDriver::AdjustSizeToNearestSupportedByCard(int *width, int *height) { + int allocatedWidth = *width, allocatedHeight = *height; + + if (direct3ddevicecaps.TextureCaps & D3DPTEXTURECAPS_POW2) { + bool foundWidth = false, foundHeight = false; + int tryThis = 2; + while ((!foundWidth) || (!foundHeight)) { + if ((tryThis >= allocatedWidth) && (!foundWidth)) { + allocatedWidth = tryThis; + foundWidth = true; + } + + if ((tryThis >= allocatedHeight) && (!foundHeight)) { + allocatedHeight = tryThis; + foundHeight = true; + } + + tryThis = tryThis << 1; + } + } + + if (direct3ddevicecaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) { + if (allocatedWidth > allocatedHeight) { + allocatedHeight = allocatedWidth; + } else { + allocatedWidth = allocatedHeight; + } + } + + *width = allocatedWidth; + *height = allocatedHeight; +} + +bool D3DGraphicsDriver::IsTextureFormatOk(D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat) { + HRESULT hr = direct3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + AdapterFormat, + 0, + D3DRTYPE_TEXTURE, + TextureFormat); + + return SUCCEEDED(hr); +} + +IDriverDependantBitmap *D3DGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) { + int allocatedWidth = bitmap->GetWidth(); + int allocatedHeight = bitmap->GetHeight(); + if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) + throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); + int colourDepth = bitmap->GetColorDepth(); + + D3DBitmap *ddb = new D3DBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); + + AdjustSizeToNearestSupportedByCard(&allocatedWidth, &allocatedHeight); + int tilesAcross = 1, tilesDown = 1; + + // *************** REMOVE THESE LINES ************* + //direct3ddevicecaps.MaxTextureWidth = 64; + //direct3ddevicecaps.MaxTextureHeight = 256; + // *************** END REMOVE THESE LINES ************* + + // Calculate how many textures will be necessary to + // store this image + tilesAcross = (allocatedWidth + direct3ddevicecaps.MaxTextureWidth - 1) / direct3ddevicecaps.MaxTextureWidth; + tilesDown = (allocatedHeight + direct3ddevicecaps.MaxTextureHeight - 1) / direct3ddevicecaps.MaxTextureHeight; + int tileWidth = bitmap->GetWidth() / tilesAcross; + int lastTileExtraWidth = bitmap->GetWidth() % tilesAcross; + int tileHeight = bitmap->GetHeight() / tilesDown; + int lastTileExtraHeight = bitmap->GetHeight() % tilesDown; + int tileAllocatedWidth = tileWidth; + int tileAllocatedHeight = tileHeight; + + AdjustSizeToNearestSupportedByCard(&tileAllocatedWidth, &tileAllocatedHeight); + + int numTiles = tilesAcross * tilesDown; + D3DTextureTile *tiles = (D3DTextureTile *)malloc(sizeof(D3DTextureTile) * numTiles); + memset(tiles, 0, sizeof(D3DTextureTile) * numTiles); + + CUSTOMVERTEX *vertices = NULL; + + if ((numTiles == 1) && + (allocatedWidth == bitmap->GetWidth()) && + (allocatedHeight == bitmap->GetHeight())) { + // use default whole-image vertices + } else { + // The texture is not the same as the bitmap, so create some custom vertices + // so that only the relevant portion of the texture is rendered + int vertexBufferSize = numTiles * 4 * sizeof(CUSTOMVERTEX); + HRESULT hr = direct3ddevice->CreateVertexBuffer(vertexBufferSize, 0, + D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &ddb->_vertex, NULL); + + if (hr != D3D_OK) { + free(tiles); + char errorMessage[200]; + sprintf(errorMessage, "Direct3DDevice9::CreateVertexBuffer(Length=%d) for texture failed: error code %08X", vertexBufferSize, hr); + throw Ali3DException(errorMessage); + } + + if (ddb->_vertex->Lock(0, 0, (void **)&vertices, D3DLOCK_DISCARD) != D3D_OK) { + free(tiles); + throw Ali3DException("Failed to lock vertex buffer"); + } + } + + for (int x = 0; x < tilesAcross; x++) { + for (int y = 0; y < tilesDown; y++) { + D3DTextureTile *thisTile = &tiles[y * tilesAcross + x]; + int thisAllocatedWidth = tileAllocatedWidth; + int thisAllocatedHeight = tileAllocatedHeight; + thisTile->x = x * tileWidth; + thisTile->y = y * tileHeight; + thisTile->width = tileWidth; + thisTile->height = tileHeight; + if (x == tilesAcross - 1) { + thisTile->width += lastTileExtraWidth; + thisAllocatedWidth = thisTile->width; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + if (y == tilesDown - 1) { + thisTile->height += lastTileExtraHeight; + thisAllocatedHeight = thisTile->height; + AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); + } + + if (vertices != NULL) { + for (int vidx = 0; vidx < 4; vidx++) { + int i = (y * tilesAcross + x) * 4 + vidx; + vertices[i] = defaultVertices[vidx]; + if (vertices[i].tu > 0.0) { + vertices[i].tu = (float)thisTile->width / (float)thisAllocatedWidth; + } + if (vertices[i].tv > 0.0) { + vertices[i].tv = (float)thisTile->height / (float)thisAllocatedHeight; + } + } + } + + // NOTE: pay attention that the texture format depends on the **display mode**'s color format, + // rather than source bitmap's color depth! + D3DFORMAT textureFormat = color_depth_to_d3d_format(_mode.ColorDepth, !opaque); + HRESULT hr = direct3ddevice->CreateTexture(thisAllocatedWidth, thisAllocatedHeight, 1, 0, + textureFormat, + D3DPOOL_MANAGED, &thisTile->texture, NULL); + if (hr != D3D_OK) { + char errorMessage[200]; + sprintf(errorMessage, "Direct3DDevice9::CreateTexture(X=%d, Y=%d, FMT=%d) failed: error code %08X", thisAllocatedWidth, thisAllocatedHeight, textureFormat, hr); + throw Ali3DException(errorMessage); + } + + } + } + + if (vertices != NULL) { + ddb->_vertex->Unlock(); + } + + ddb->_numTiles = numTiles; + ddb->_tiles = tiles; + + UpdateDDBFromBitmap(ddb, bitmap, hasAlpha); + + return ddb; +} + +void D3DGraphicsDriver::do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { + // Construct scene in order: game screen, fade fx, post game overlay + // NOTE: please keep in mind: redrawing last saved frame here instead of constructing new one + // is done because of backwards-compatibility issue: originally AGS faded out using frame + // drawn before the script that triggers blocking fade (e.g. instigated by ChangeRoom). + // Unfortunately some existing games were changing looks of the screen during same function, + // but these were not supposed to get on screen until before fade-in. + if (fadingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != NULL) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(makecol32(targetColourRed, targetColourGreen, targetColourBlue)); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + if (speed <= 0) speed = 16; + speed *= 2; // harmonise speeds with software driver which is faster + for (int a = 1; a < 255; a += speed) { + d3db->SetTransparency(fadingOut ? a : (255 - a)); + this->_renderAndPresent(false); + + if (_pollingCallback) + _pollingCallback(); + WaitForNextFrame(); + } + + if (fadingOut) { + d3db->SetTransparency(0); + this->_renderAndPresent(false); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); +} + +void D3DGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { + do_fade(true, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void D3DGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) { + do_fade(false, speed, targetColourRed, targetColourGreen, targetColourBlue); +} + +void D3DGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) { + // Construct scene in order: game screen, fade fx, post game overlay + if (blackingOut) + this->_reDrawLastFrame(); + else if (_drawScreenCallback != NULL) + _drawScreenCallback(); + Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); + blackSquare->Clear(); + IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); + delete blackSquare; + BeginSpriteBatch(_srcRect, SpriteTransform()); + size_t fx_batch = _actSpriteBatch; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + this->DrawSprite(0, 0, d3db); + if (!blackingOut) { + // when fading in, draw four black boxes, one + // across each side of the screen + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + this->DrawSprite(0, 0, d3db); + } + if (_drawPostScreenCallback != NULL) + _drawPostScreenCallback(); + + int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); + int boxWidth = speed; + int boxHeight = yspeed; + + while (boxWidth < _srcRect.GetWidth()) { + boxWidth += speed; + boxHeight += yspeed; + D3DSpriteBatch &batch = _spriteBatches[fx_batch]; + std::vector &drawList = batch.List; + const size_t last = drawList.size() - 1; + if (blackingOut) { + drawList[last].x = _srcRect.GetWidth() / 2 - boxWidth / 2; + drawList[last].y = _srcRect.GetHeight() / 2 - boxHeight / 2; + d3db->SetStretch(boxWidth, boxHeight, false); + } else { + drawList[last - 3].x = _srcRect.GetWidth() / 2 - boxWidth / 2 - _srcRect.GetWidth(); + drawList[last - 2].y = _srcRect.GetHeight() / 2 - boxHeight / 2 - _srcRect.GetHeight(); + drawList[last - 1].x = _srcRect.GetWidth() / 2 + boxWidth / 2; + drawList[last ].y = _srcRect.GetHeight() / 2 + boxHeight / 2; + d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); + } + + this->_renderAndPresent(false); + + if (_pollingCallback) + _pollingCallback(); + platform->Delay(delay); + } + + this->DestroyDDB(d3db); + this->ClearDrawLists(); + ResetFxPool(); } #ifndef AGS_NO_VIDEO_PLAYER -bool D3DGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) -{ - direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); +bool D3DGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) { + direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); - int result = dxmedia_play_video_3d(filename, direct3ddevice, useAVISound, skipType, stretchToFullScreen ? 1 : 0); - return (result == 0); + int result = dxmedia_play_video_3d(filename, direct3ddevice, useAVISound, skipType, stretchToFullScreen ? 1 : 0); + return (result == 0); } #endif -void D3DGraphicsDriver::SetScreenFade(int red, int green, int blue) -{ - D3DBitmap *ddb = static_cast(MakeFx(red, green, blue)); - ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), - _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); - ddb->SetTransparency(0); - _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry(ddb)); +void D3DGraphicsDriver::SetScreenFade(int red, int green, int blue) { + D3DBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(0); + _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry(ddb)); } -void D3DGraphicsDriver::SetScreenTint(int red, int green, int blue) -{ - if (red == 0 && green == 0 && blue == 0) return; - D3DBitmap *ddb = static_cast(MakeFx(red, green, blue)); - ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), - _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); - ddb->SetTransparency(128); - _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry(ddb)); +void D3DGraphicsDriver::SetScreenTint(int red, int green, int blue) { + if (red == 0 && green == 0 && blue == 0) return; + D3DBitmap *ddb = static_cast(MakeFx(red, green, blue)); + ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), + _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); + ddb->SetTransparency(128); + _spriteBatches[_actSpriteBatch].List.push_back(D3DDrawListEntry(ddb)); } D3DGraphicsFactory *D3DGraphicsFactory::_factory = NULL; Library D3DGraphicsFactory::_library; -D3DGraphicsFactory::~D3DGraphicsFactory() -{ - DestroyDriver(); // driver must be destroyed before d3d library is disposed - ULONG ref_cnt = _direct3d->Release(); - if (ref_cnt > 0) - Debug::Printf(kDbgMsg_Warn, "WARNING: Not all of the Direct3D resources have been disposed; ID3D ref count: %d", ref_cnt); - _factory = NULL; +D3DGraphicsFactory::~D3DGraphicsFactory() { + DestroyDriver(); // driver must be destroyed before d3d library is disposed + ULONG ref_cnt = _direct3d->Release(); + if (ref_cnt > 0) + Debug::Printf(kDbgMsg_Warn, "WARNING: Not all of the Direct3D resources have been disposed; ID3D ref count: %d", ref_cnt); + _factory = NULL; } -size_t D3DGraphicsFactory::GetFilterCount() const -{ - return 2; +size_t D3DGraphicsFactory::GetFilterCount() const { + return 2; } -const GfxFilterInfo *D3DGraphicsFactory::GetFilterInfo(size_t index) const -{ - switch (index) - { - case 0: - return &D3DGfxFilter::FilterInfo; - case 1: - return &AAD3DGfxFilter::FilterInfo; - default: - return NULL; - } +const GfxFilterInfo *D3DGraphicsFactory::GetFilterInfo(size_t index) const { + switch (index) { + case 0: + return &D3DGfxFilter::FilterInfo; + case 1: + return &AAD3DGfxFilter::FilterInfo; + default: + return NULL; + } } -String D3DGraphicsFactory::GetDefaultFilterID() const -{ - return D3DGfxFilter::FilterInfo.Id; +String D3DGraphicsFactory::GetDefaultFilterID() const { + return D3DGfxFilter::FilterInfo.Id; } -/* static */ D3DGraphicsFactory *D3DGraphicsFactory::GetFactory() -{ - if (!_factory) - { - _factory = new D3DGraphicsFactory(); - if (!_factory->Init()) - { - delete _factory; - _factory = NULL; - } - } - return _factory; +/* static */ D3DGraphicsFactory *D3DGraphicsFactory::GetFactory() { + if (!_factory) { + _factory = new D3DGraphicsFactory(); + if (!_factory->Init()) { + delete _factory; + _factory = NULL; + } + } + return _factory; } -/* static */ D3DGraphicsDriver *D3DGraphicsFactory::GetD3DDriver() -{ - if (!_factory) - _factory = GetFactory(); - if (_factory) - return _factory->EnsureDriverCreated(); - return NULL; +/* static */ D3DGraphicsDriver *D3DGraphicsFactory::GetD3DDriver() { + if (!_factory) + _factory = GetFactory(); + if (_factory) + return _factory->EnsureDriverCreated(); + return NULL; } D3DGraphicsFactory::D3DGraphicsFactory() - : _direct3d(NULL) -{ -} - -D3DGraphicsDriver *D3DGraphicsFactory::EnsureDriverCreated() -{ - if (!_driver) - { - _factory->_direct3d->AddRef(); - _driver = new D3DGraphicsDriver(_factory->_direct3d); - } - return _driver; -} - -D3DGfxFilter *D3DGraphicsFactory::CreateFilter(const String &id) -{ - if (D3DGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new D3DGfxFilter(); - else if (AAD3DGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new AAD3DGfxFilter(); - return NULL; -} - -bool D3DGraphicsFactory::Init() -{ - assert(_direct3d == NULL); - if (_direct3d) - return true; - - if (!_library.Load("d3d9")) - { - set_allegro_error("Direct3D 9 is not installed"); - return false; - } - - typedef IDirect3D9 * WINAPI D3D9CreateFn(UINT); - D3D9CreateFn *lpDirect3DCreate9 = (D3D9CreateFn*)_library.GetFunctionAddress("Direct3DCreate9"); - if (!lpDirect3DCreate9) - { - _library.Unload(); - set_allegro_error("Entry point not found in d3d9.dll"); - return false; - } - _direct3d = lpDirect3DCreate9(D3D_SDK_VERSION); - if (!_direct3d) - { - _library.Unload(); - set_allegro_error("Direct3DCreate failed!"); - return false; - } - return true; + : _direct3d(NULL) { +} + +D3DGraphicsDriver *D3DGraphicsFactory::EnsureDriverCreated() { + if (!_driver) { + _factory->_direct3d->AddRef(); + _driver = new D3DGraphicsDriver(_factory->_direct3d); + } + return _driver; +} + +D3DGfxFilter *D3DGraphicsFactory::CreateFilter(const String &id) { + if (D3DGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new D3DGfxFilter(); + else if (AAD3DGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) + return new AAD3DGfxFilter(); + return NULL; +} + +bool D3DGraphicsFactory::Init() { + assert(_direct3d == NULL); + if (_direct3d) + return true; + + if (!_library.Load("d3d9")) { + set_allegro_error("Direct3D 9 is not installed"); + return false; + } + + typedef IDirect3D9 *WINAPI D3D9CreateFn(UINT); + D3D9CreateFn *lpDirect3DCreate9 = (D3D9CreateFn *)_library.GetFunctionAddress("Direct3DCreate9"); + if (!lpDirect3DCreate9) { + _library.Unload(); + set_allegro_error("Entry point not found in d3d9.dll"); + return false; + } + _direct3d = lpDirect3DCreate9(D3D_SDK_VERSION); + if (!_direct3d) { + _library.Unload(); + set_allegro_error("Direct3DCreate failed!"); + return false; + } + return true; } } // namespace D3D diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index f809f43a3859..622a7f55d24e 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -46,297 +46,302 @@ #include "util/library.h" #include "util/string.h" -namespace AGS -{ -namespace Engine -{ -namespace D3D -{ +namespace AGS { +namespace Engine { +namespace D3D { using AGS::Common::Bitmap; using AGS::Common::String; class D3DGfxFilter; -struct D3DTextureTile : public TextureTile -{ - IDirect3DTexture9* texture; +struct D3DTextureTile : public TextureTile { + IDirect3DTexture9 *texture; }; -class D3DBitmap : public VideoMemDDB -{ +class D3DBitmap : public VideoMemDDB { public: - // Transparency is a bit counter-intuitive - // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible - void SetTransparency(int transparency) override { _transparency = transparency; } - void SetFlippedLeftRight(bool isFlipped) override { _flipped = isFlipped; } - void SetStretch(int width, int height, bool useResampler = true) override - { - _stretchToWidth = width; - _stretchToHeight = height; - _useResampler = useResampler; - } - void SetLightLevel(int lightLevel) override { _lightLevel = lightLevel; } - void SetTint(int red, int green, int blue, int tintSaturation) override - { - _red = red; - _green = green; - _blue = blue; - _tintSaturation = tintSaturation; - } - - bool _flipped; - int _stretchToWidth, _stretchToHeight; - bool _useResampler; - int _red, _green, _blue; - int _tintSaturation; - int _lightLevel; - bool _hasAlpha; - int _transparency; - IDirect3DVertexBuffer9* _vertex; - D3DTextureTile *_tiles; - int _numTiles; - - D3DBitmap(int width, int height, int colDepth, bool opaque) - { - _width = width; - _height = height; - _colDepth = colDepth; - _flipped = false; - _hasAlpha = false; - _stretchToWidth = 0; - _stretchToHeight = 0; - _useResampler = false; - _red = _green = _blue = 0; - _tintSaturation = 0; - _lightLevel = 0; - _transparency = 0; - _opaque = opaque; - _vertex = NULL; - _tiles = NULL; - _numTiles = 0; - } - - int GetWidthToRender() { return (_stretchToWidth > 0) ? _stretchToWidth : _width; } - int GetHeightToRender() { return (_stretchToHeight > 0) ? _stretchToHeight : _height; } - - void Dispose(); - - ~D3DBitmap() override - { - Dispose(); - } + // Transparency is a bit counter-intuitive + // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible + void SetTransparency(int transparency) override { + _transparency = transparency; + } + void SetFlippedLeftRight(bool isFlipped) override { + _flipped = isFlipped; + } + void SetStretch(int width, int height, bool useResampler = true) override { + _stretchToWidth = width; + _stretchToHeight = height; + _useResampler = useResampler; + } + void SetLightLevel(int lightLevel) override { + _lightLevel = lightLevel; + } + void SetTint(int red, int green, int blue, int tintSaturation) override { + _red = red; + _green = green; + _blue = blue; + _tintSaturation = tintSaturation; + } + + bool _flipped; + int _stretchToWidth, _stretchToHeight; + bool _useResampler; + int _red, _green, _blue; + int _tintSaturation; + int _lightLevel; + bool _hasAlpha; + int _transparency; + IDirect3DVertexBuffer9 *_vertex; + D3DTextureTile *_tiles; + int _numTiles; + + D3DBitmap(int width, int height, int colDepth, bool opaque) { + _width = width; + _height = height; + _colDepth = colDepth; + _flipped = false; + _hasAlpha = false; + _stretchToWidth = 0; + _stretchToHeight = 0; + _useResampler = false; + _red = _green = _blue = 0; + _tintSaturation = 0; + _lightLevel = 0; + _transparency = 0; + _opaque = opaque; + _vertex = NULL; + _tiles = NULL; + _numTiles = 0; + } + + int GetWidthToRender() { + return (_stretchToWidth > 0) ? _stretchToWidth : _width; + } + int GetHeightToRender() { + return (_stretchToHeight > 0) ? _stretchToHeight : _height; + } + + void Dispose(); + + ~D3DBitmap() override { + Dispose(); + } }; -class D3DGfxModeList : public IGfxModeList -{ +class D3DGfxModeList : public IGfxModeList { public: - D3DGfxModeList(IDirect3D9 *direct3d, D3DFORMAT d3dformat) - : _direct3d(direct3d) - , _pixelFormat(d3dformat) - { - _modeCount = _direct3d ? _direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, _pixelFormat) : 0; - } - - ~D3DGfxModeList() override - { - if (_direct3d) - _direct3d->Release(); - } - - int GetModeCount() const override - { - return _modeCount; - } - - bool GetMode(int index, DisplayMode &mode) const override; + D3DGfxModeList(IDirect3D9 *direct3d, D3DFORMAT d3dformat) + : _direct3d(direct3d) + , _pixelFormat(d3dformat) { + _modeCount = _direct3d ? _direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, _pixelFormat) : 0; + } + + ~D3DGfxModeList() override { + if (_direct3d) + _direct3d->Release(); + } + + int GetModeCount() const override { + return _modeCount; + } + + bool GetMode(int index, DisplayMode &mode) const override; private: - IDirect3D9 *_direct3d; - D3DFORMAT _pixelFormat; - int _modeCount; + IDirect3D9 *_direct3d; + D3DFORMAT _pixelFormat; + int _modeCount; }; -struct CUSTOMVERTEX -{ - D3DVECTOR position; // The position. - D3DVECTOR normal; - FLOAT tu, tv; // The texture coordinates. +struct CUSTOMVERTEX { + D3DVECTOR position; // The position. + D3DVECTOR normal; + FLOAT tu, tv; // The texture coordinates. }; typedef SpriteDrawListEntry D3DDrawListEntry; // D3D renderer's sprite batch -struct D3DSpriteBatch -{ - // List of sprites to render - std::vector List; - // Clipping viewport - Rect Viewport; - // Transformation matrix, built from the batch description - D3DMATRIX Matrix; +struct D3DSpriteBatch { + // List of sprites to render + std::vector List; + // Clipping viewport + Rect Viewport; + // Transformation matrix, built from the batch description + D3DMATRIX Matrix; }; typedef std::vector D3DSpriteBatches; -class D3DGraphicsDriver : public VideoMemoryGraphicsDriver -{ +class D3DGraphicsDriver : public VideoMemoryGraphicsDriver { public: - const char*GetDriverName() override { return "Direct3D 9"; } - const char*GetDriverID() override { return "D3D9"; } - void SetTintMethod(TintMethod method) override; - bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; - bool SetNativeSize(const Size &src_size) override; - bool SetRenderFrame(const Rect &dst_rect) override; - int GetDisplayDepthForNativeDepth(int native_color_depth) const override; - IGfxModeList *GetSupportedModeList(int color_depth) override; - bool IsModeSupported(const DisplayMode &mode) override; - PGfxFilter GetGraphicsFilter() const override; - // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. - void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; - int GetCompatibleBitmapFormat(int color_depth) override; - IDriverDependantBitmap* CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; - void UpdateDDBFromBitmap(IDriverDependantBitmap* bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; - void DestroyDDB(IDriverDependantBitmap* bitmap) override; - void DrawSprite(int x, int y, IDriverDependantBitmap* bitmap) override; - void SetScreenFade(int red, int green, int blue) override; - void SetScreenTint(int red, int green, int blue) override; - void RenderToBackBuffer() override; - void Render() override; - void Render(int xoff, int yoff, GlobalFlipType flip) override; - bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; - void EnableVsyncBeforeRender(bool enabled) override { } - void Vsync() override; - void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override { _renderSprAtScreenRes = enabled; }; - void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void BoxOutEffect(bool blackingOut, int speed, int delay) override; + const char *GetDriverName() override { + return "Direct3D 9"; + } + const char *GetDriverID() override { + return "D3D9"; + } + void SetTintMethod(TintMethod method) override; + bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; + bool SetNativeSize(const Size &src_size) override; + bool SetRenderFrame(const Rect &dst_rect) override; + int GetDisplayDepthForNativeDepth(int native_color_depth) const override; + IGfxModeList *GetSupportedModeList(int color_depth) override; + bool IsModeSupported(const DisplayMode &mode) override; + PGfxFilter GetGraphicsFilter() const override; + // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. + void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; + int GetCompatibleBitmapFormat(int color_depth) override; + IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; + void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; + void DestroyDDB(IDriverDependantBitmap *bitmap) override; + void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) override; + void SetScreenFade(int red, int green, int blue) override; + void SetScreenTint(int red, int green, int blue) override; + void RenderToBackBuffer() override; + void Render() override; + void Render(int xoff, int yoff, GlobalFlipType flip) override; + bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; + void EnableVsyncBeforeRender(bool enabled) override { } + void Vsync() override; + void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override { + _renderSprAtScreenRes = enabled; + }; + void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override; + void BoxOutEffect(bool blackingOut, int speed, int delay) override; #ifndef AGS_NO_VIDEO_PLAYER - bool PlayVideo(const char *filename, bool useSound, VideoSkipType skipType, bool stretchToFullScreen) override; + bool PlayVideo(const char *filename, bool useSound, VideoSkipType skipType, bool stretchToFullScreen) override; #endif - bool SupportsGammaControl() override; - void SetGamma(int newGamma) override; - void UseSmoothScaling(bool enabled) override { _smoothScaling = enabled; } - bool RequiresFullRedrawEachFrame() override { return true; } - bool HasAcceleratedTransform() override { return true; } - - typedef std::shared_ptr PD3DFilter; - - // Clears screen rect, coordinates are expected in display resolution - void ClearScreenRect(const Rect &r, RGB *colorToUse); - void UnInit(); - void SetGraphicsFilter(PD3DFilter filter); - - // Internal; TODO: find a way to hide these - int _initDLLCallback(const DisplayMode &mode); - int _resetDeviceIfNecessary(); - - D3DGraphicsDriver(IDirect3D9 *d3d); - ~D3DGraphicsDriver() override; + bool SupportsGammaControl() override; + void SetGamma(int newGamma) override; + void UseSmoothScaling(bool enabled) override { + _smoothScaling = enabled; + } + bool RequiresFullRedrawEachFrame() override { + return true; + } + bool HasAcceleratedTransform() override { + return true; + } + + typedef std::shared_ptr PD3DFilter; + + // Clears screen rect, coordinates are expected in display resolution + void ClearScreenRect(const Rect &r, RGB *colorToUse); + void UnInit(); + void SetGraphicsFilter(PD3DFilter filter); + + // Internal; TODO: find a way to hide these + int _initDLLCallback(const DisplayMode &mode); + int _resetDeviceIfNecessary(); + + D3DGraphicsDriver(IDirect3D9 *d3d); + ~D3DGraphicsDriver() override; private: - PD3DFilter _filter; - - IDirect3D9 *direct3d; - D3DPRESENT_PARAMETERS d3dpp; - IDirect3DDevice9* direct3ddevice; - D3DGAMMARAMP defaultgammaramp; - D3DGAMMARAMP currentgammaramp; - D3DCAPS9 direct3ddevicecaps; - IDirect3DVertexBuffer9* vertexbuffer; - IDirect3DSurface9 *pNativeSurface; - IDirect3DTexture9 *pNativeTexture; - RECT viewport_rect; - UINT availableVideoMemory; - CUSTOMVERTEX defaultVertices[4]; - String previousError; - IDirect3DPixelShader9* pixelShader; - bool _smoothScaling; - bool _legacyPixelShader; - float _pixelRenderXOffset; - float _pixelRenderYOffset; - bool _renderSprAtScreenRes; - - D3DSpriteBatches _spriteBatches; - // TODO: these draw list backups are needed only for the fade-in/out effects - // find out if it's possible to reimplement these effects in main drawing routine. - SpriteBatchDescs _backupBatchDescs; - D3DSpriteBatches _backupBatches; - - D3DVIEWPORT9 _d3dViewport; - - // Called after new mode was successfully initialized - void OnModeSet(const DisplayMode &mode) override; - void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; - void ResetAllBatches() override; - // Called when the direct3d device is created for the first time - int FirstTimeInit(); - void initD3DDLL(const DisplayMode &mode); - void InitializeD3DState(); - void SetupViewport(); - HRESULT ResetD3DDevice(); - // Unset parameters and release resources related to the display mode - void ReleaseDisplayMode(); - void set_up_default_vertices(); - void AdjustSizeToNearestSupportedByCard(int *width, int *height); - void UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap, D3DBitmap *target, bool hasAlpha); - void CreateVirtualScreen(); - void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); - bool IsTextureFormatOk( D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat ); - // Backup all draw lists in the temp storage - void BackupDrawLists(); - // Restore draw lists from the temp storage - void RestoreDrawLists(); - // Deletes draw list backups - void ClearDrawBackups(); - void _renderAndPresent(bool clearDrawListAfterwards); - void _render(bool clearDrawListAfterwards); - void _reDrawLastFrame(); - void RenderSpriteBatches(); - void RenderSpriteBatch(const D3DSpriteBatch &batch); - void _renderSprite(const D3DDrawListEntry *entry, const D3DMATRIX &matGlobal); - void _renderFromTexture(); + PD3DFilter _filter; + + IDirect3D9 *direct3d; + D3DPRESENT_PARAMETERS d3dpp; + IDirect3DDevice9 *direct3ddevice; + D3DGAMMARAMP defaultgammaramp; + D3DGAMMARAMP currentgammaramp; + D3DCAPS9 direct3ddevicecaps; + IDirect3DVertexBuffer9 *vertexbuffer; + IDirect3DSurface9 *pNativeSurface; + IDirect3DTexture9 *pNativeTexture; + RECT viewport_rect; + UINT availableVideoMemory; + CUSTOMVERTEX defaultVertices[4]; + String previousError; + IDirect3DPixelShader9 *pixelShader; + bool _smoothScaling; + bool _legacyPixelShader; + float _pixelRenderXOffset; + float _pixelRenderYOffset; + bool _renderSprAtScreenRes; + + D3DSpriteBatches _spriteBatches; + // TODO: these draw list backups are needed only for the fade-in/out effects + // find out if it's possible to reimplement these effects in main drawing routine. + SpriteBatchDescs _backupBatchDescs; + D3DSpriteBatches _backupBatches; + + D3DVIEWPORT9 _d3dViewport; + + // Called after new mode was successfully initialized + void OnModeSet(const DisplayMode &mode) override; + void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; + void ResetAllBatches() override; + // Called when the direct3d device is created for the first time + int FirstTimeInit(); + void initD3DDLL(const DisplayMode &mode); + void InitializeD3DState(); + void SetupViewport(); + HRESULT ResetD3DDevice(); + // Unset parameters and release resources related to the display mode + void ReleaseDisplayMode(); + void set_up_default_vertices(); + void AdjustSizeToNearestSupportedByCard(int *width, int *height); + void UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap, D3DBitmap *target, bool hasAlpha); + void CreateVirtualScreen(); + void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); + bool IsTextureFormatOk(D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat); + // Backup all draw lists in the temp storage + void BackupDrawLists(); + // Restore draw lists from the temp storage + void RestoreDrawLists(); + // Deletes draw list backups + void ClearDrawBackups(); + void _renderAndPresent(bool clearDrawListAfterwards); + void _render(bool clearDrawListAfterwards); + void _reDrawLastFrame(); + void RenderSpriteBatches(); + void RenderSpriteBatch(const D3DSpriteBatch &batch); + void _renderSprite(const D3DDrawListEntry *entry, const D3DMATRIX &matGlobal); + void _renderFromTexture(); }; -class D3DGraphicsFactory : public GfxDriverFactoryBase -{ +class D3DGraphicsFactory : public GfxDriverFactoryBase { public: - ~D3DGraphicsFactory() override; + ~D3DGraphicsFactory() override; - size_t GetFilterCount() const override; - const GfxFilterInfo *GetFilterInfo(size_t index) const override; - String GetDefaultFilterID() const override; + size_t GetFilterCount() const override; + const GfxFilterInfo *GetFilterInfo(size_t index) const override; + String GetDefaultFilterID() const override; - static D3DGraphicsFactory *GetFactory(); - static D3DGraphicsDriver *GetD3DDriver(); + static D3DGraphicsFactory *GetFactory(); + static D3DGraphicsDriver *GetD3DDriver(); private: - D3DGraphicsFactory(); - - D3DGraphicsDriver *EnsureDriverCreated() override; - D3DGfxFilter *CreateFilter(const String &id) override; - - bool Init(); - - static D3DGraphicsFactory *_factory; - // - // IMPORTANT NOTE: since the Direct3d9 device is created with - // D3DCREATE_MULTITHREADED behavior flag, once it is created the d3d9.dll may - // only be unloaded after window is destroyed, as noted in the MSDN's article - // on "D3DCREATE" - // (http://msdn.microsoft.com/en-us/library/windows/desktop/bb172527.aspx). - // Otherwise window becomes either destroyed prematurely or broken (details - // are unclear), which causes errors during Allegro deinitialization. - // - // Curiously, this problem was only confirmed under WinXP so far. - // - // For the purpose of avoiding this problem, we have a static library wrapper - // that unloads library only at the very program exit (except cases of device - // creation failure). - // - // TODO: find out if there is better solution. - // - static Library _library; - IDirect3D9 *_direct3d; + D3DGraphicsFactory(); + + D3DGraphicsDriver *EnsureDriverCreated() override; + D3DGfxFilter *CreateFilter(const String &id) override; + + bool Init(); + + static D3DGraphicsFactory *_factory; + // + // IMPORTANT NOTE: since the Direct3d9 device is created with + // D3DCREATE_MULTITHREADED behavior flag, once it is created the d3d9.dll may + // only be unloaded after window is destroyed, as noted in the MSDN's article + // on "D3DCREATE" + // (http://msdn.microsoft.com/en-us/library/windows/desktop/bb172527.aspx). + // Otherwise window becomes either destroyed prematurely or broken (details + // are unclear), which causes errors during Allegro deinitialization. + // + // Curiously, this problem was only confirmed under WinXP so far. + // + // For the purpose of avoiding this problem, we have a static library wrapper + // that unloads library only at the very program exit (except cases of device + // creation failure). + // + // TODO: find out if there is better solution. + // + static Library _library; + IDirect3D9 *_direct3d; }; } // namespace D3D diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp index f17b55be5088..56e7f1fc7148 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -38,8 +38,8 @@ #include #include #include -#include // Multimedia stream interfaces -#include // DirectDraw multimedia stream interfaces +#include // Multimedia stream interfaces +#include // DirectDraw multimedia stream interfaces #include // Defines DEFINE_GUID macro and enables GUID initialization #include "ac/draw.h" #include "gfx/bitmap.h" @@ -51,7 +51,7 @@ using namespace AGS::Common; using namespace AGS::Engine; //link with the following libraries under project/settings/link... -//amstrmid.lib quartz.lib strmbase.lib ddraw.lib +//amstrmid.lib quartz.lib strmbase.lib ddraw.lib extern void update_audio_system_on_game_loop(); extern void update_polled_stuff_if_runtime(); @@ -74,347 +74,341 @@ extern "C" extern LPDIRECTDRAW2 directdraw; extern "C" extern BITMAP *gfx_directx_create_system_bitmap(int width, int height); //Global MultiMedia streaming interfaces -IMultiMediaStream *g_pMMStream=NULL; -IMediaStream *g_pPrimaryVidStream=NULL; -IDirectDrawMediaStream *g_pDDStream=NULL; -IDirectDrawStreamSample *g_pSample=NULL; +IMultiMediaStream *g_pMMStream = NULL; +IMediaStream *g_pPrimaryVidStream = NULL; +IDirectDrawMediaStream *g_pDDStream = NULL; +IDirectDrawStreamSample *g_pSample = NULL; Bitmap *vscreen = NULL; Bitmap *vsMemory = NULL; //Function prototypes -HRESULT RenderFileToMMStream(LPCTSTR szFilename); +HRESULT RenderFileToMMStream(LPCTSTR szFilename); HRESULT InitRenderToSurface(); void RenderToSurface(); void ExitCode() { - //Release MultiMedia streaming Objects - if (g_pMMStream != NULL) { - g_pMMStream->Release(); - g_pMMStream= NULL; - } - if (g_pSample != NULL) { - g_pSample->Release(); - g_pSample = NULL; - } - if (g_pDDStream != NULL) { - g_pDDStream->Release(); - g_pDDStream= NULL; - } - if (g_pPrimaryVidStream != NULL) { - g_pPrimaryVidStream->Release(); - g_pPrimaryVidStream= NULL; - } + //Release MultiMedia streaming Objects + if (g_pMMStream != NULL) { + g_pMMStream->Release(); + g_pMMStream = NULL; + } + if (g_pSample != NULL) { + g_pSample->Release(); + g_pSample = NULL; + } + if (g_pDDStream != NULL) { + g_pDDStream->Release(); + g_pDDStream = NULL; + } + if (g_pPrimaryVidStream != NULL) { + g_pPrimaryVidStream->Release(); + g_pPrimaryVidStream = NULL; + } } typedef struct BMP_EXTRA_INFO { - LPDIRECTDRAWSURFACE2 surf; - struct BMP_EXTRA_INFO *next; - struct BMP_EXTRA_INFO *prev; - int flags; - int lock_nesting; + LPDIRECTDRAWSURFACE2 surf; + struct BMP_EXTRA_INFO *next; + struct BMP_EXTRA_INFO *prev; + int flags; + int lock_nesting; } BMP_EXTRA_INFO; -LPDIRECTDRAWSURFACE get_bitmap_surface (Bitmap *bmp) { - BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO*)((BITMAP*)bmp->GetAllegroBitmap())->extra; +LPDIRECTDRAWSURFACE get_bitmap_surface(Bitmap *bmp) { + BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO *)((BITMAP *)bmp->GetAllegroBitmap())->extra; - // convert the DDSurface2 back to a standard DDSurface - return (LPDIRECTDRAWSURFACE)bei->surf; + // convert the DDSurface2 back to a standard DDSurface + return (LPDIRECTDRAWSURFACE)bei->surf; } -LPDIRECTDRAWSURFACE2 get_bitmap_surface2 (Bitmap *bmp) { - BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO*)((BITMAP*)bmp->GetAllegroBitmap())->extra; +LPDIRECTDRAWSURFACE2 get_bitmap_surface2(Bitmap *bmp) { + BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO *)((BITMAP *)bmp->GetAllegroBitmap())->extra; - return bei->surf; + return bei->surf; } //Create the stream sample which will be used to call updates on the video HRESULT InitRenderToSurface() { - HRESULT hr; - DDSURFACEDESC ddsd; - - //Use the multimedia stream to get the primary video media stream - hr = g_pMMStream->GetMediaStream(MSPID_PrimaryVideo, &g_pPrimaryVidStream); - if (FAILED(hr)) { - strcpy (lastError, "MMStream::GetMediaStream failed to create the primary video stream."); - return E_FAIL; - } - - //Use the media stream to get the IDirectDrawMediaStream - hr = g_pPrimaryVidStream->QueryInterface(IID_IDirectDrawMediaStream, (void **)&g_pDDStream); - if (FAILED(hr)) { - strcpy(lastError, "The video stream does not support the IDirectDrawMediaStream interface; ensure you have the latest DirectX version installed."); - return E_FAIL; - } - - //Must set dwSize before calling GetFormat - ddsd.dwSize = sizeof(ddsd); - hr = g_pDDStream->GetFormat(&ddsd, NULL, NULL, NULL); - if (FAILED(hr)) { - strcpy(lastError, "IDirectDrawMediaStream::GetFormat failed"); - return E_FAIL; - } - - RECT rect; - rect.top = rect.left = 0; - // these are the width and height of the video - rect.bottom = ddsd.dwHeight; - rect.right = ddsd.dwWidth; - - if (vscreen == NULL) - vscreen = BitmapHelper::CreateRawBitmapOwner(gfx_directx_create_system_bitmap(ddsd.dwWidth, ddsd.dwHeight)); - - if (vscreen == NULL) { - strcpy(lastError, "Unable to create the DX Video System Bitmap"); - return E_FAIL; - } - - vsMemory = BitmapHelper::CreateBitmap(vscreen->GetWidth(), vscreen->GetHeight(), vscreen->GetColorDepth()); - - IDirectDrawSurface *g_pDDSOffscreen; - g_pDDSOffscreen = get_bitmap_surface (vscreen); - - //Create the stream sample - hr = g_pDDStream->CreateSample(g_pDDSOffscreen, &rect, 0, &g_pSample); - if (FAILED(hr)) { - strcpy (lastError, "VideoStream::CreateSample failed"); - return E_FAIL; - } - - return NOERROR; + HRESULT hr; + DDSURFACEDESC ddsd; + + //Use the multimedia stream to get the primary video media stream + hr = g_pMMStream->GetMediaStream(MSPID_PrimaryVideo, &g_pPrimaryVidStream); + if (FAILED(hr)) { + strcpy(lastError, "MMStream::GetMediaStream failed to create the primary video stream."); + return E_FAIL; + } + + //Use the media stream to get the IDirectDrawMediaStream + hr = g_pPrimaryVidStream->QueryInterface(IID_IDirectDrawMediaStream, (void **)&g_pDDStream); + if (FAILED(hr)) { + strcpy(lastError, "The video stream does not support the IDirectDrawMediaStream interface; ensure you have the latest DirectX version installed."); + return E_FAIL; + } + + //Must set dwSize before calling GetFormat + ddsd.dwSize = sizeof(ddsd); + hr = g_pDDStream->GetFormat(&ddsd, NULL, NULL, NULL); + if (FAILED(hr)) { + strcpy(lastError, "IDirectDrawMediaStream::GetFormat failed"); + return E_FAIL; + } + + RECT rect; + rect.top = rect.left = 0; + // these are the width and height of the video + rect.bottom = ddsd.dwHeight; + rect.right = ddsd.dwWidth; + + if (vscreen == NULL) + vscreen = BitmapHelper::CreateRawBitmapOwner(gfx_directx_create_system_bitmap(ddsd.dwWidth, ddsd.dwHeight)); + + if (vscreen == NULL) { + strcpy(lastError, "Unable to create the DX Video System Bitmap"); + return E_FAIL; + } + + vsMemory = BitmapHelper::CreateBitmap(vscreen->GetWidth(), vscreen->GetHeight(), vscreen->GetColorDepth()); + + IDirectDrawSurface *g_pDDSOffscreen; + g_pDDSOffscreen = get_bitmap_surface(vscreen); + + //Create the stream sample + hr = g_pDDStream->CreateSample(g_pDDSOffscreen, &rect, 0, &g_pSample); + if (FAILED(hr)) { + strcpy(lastError, "VideoStream::CreateSample failed"); + return E_FAIL; + } + + return NOERROR; } //Renders a file to a multimedia stream -HRESULT RenderFileToMMStream(LPCTSTR szFilename) { - HRESULT hr; - IAMMultiMediaStream *pAMStream=NULL; - - //Convert filename to Unicode - WCHAR wFile[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, szFilename, -1, wFile, - sizeof(wFile)/sizeof(wFile[0])); - - //Create the AMMultiMediaStream object - hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, - IID_IAMMultiMediaStream, (void **)&pAMStream); - - if (FAILED(hr)) { - strcpy(lastError, "Could not create a CLSID_MultiMediaStream object. " - "Make sure you have the latest version of DirectX installed."); - return E_FAIL; - } - - //Initialize stream - hr = pAMStream->Initialize(STREAMTYPE_READ, 0, NULL); - if (FAILED(hr)) { - strcpy(lastError, "AMStream::Initialize failed."); - return E_FAIL; - } - //Add primary video stream - hr = pAMStream->AddMediaStream(directdraw, &MSPID_PrimaryVideo, 0, NULL); - if (FAILED(hr)) { - strcpy(lastError, "AddMediaStream failed."); - return E_FAIL; - } - //Add primary audio stream - if (useSound) { - //hr = pAMStream->AddMediaStream(directsound, &MSPID_PrimaryAudio, 0, NULL); - hr = pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL); - if (FAILED(hr)) { - strcpy(lastError, "AddMediaStream failed."); - return E_FAIL; - } - } - //Opens and automatically creates a filter graph for the specified media file - hr = pAMStream->OpenFile(wFile, 0); - if (FAILED(hr)) { - pAMStream->Release(); - sprintf(lastError, "File not found or format not supported: %s", szFilename); - return E_FAIL; - } - - //save the local stream to the global variable - g_pMMStream = pAMStream; - // Add a reference to the file - //pAMStream->AddRef(); - - return NOERROR; +HRESULT RenderFileToMMStream(LPCTSTR szFilename) { + HRESULT hr; + IAMMultiMediaStream *pAMStream = NULL; + + //Convert filename to Unicode + WCHAR wFile[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, szFilename, -1, wFile, + sizeof(wFile) / sizeof(wFile[0])); + + //Create the AMMultiMediaStream object + hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, + IID_IAMMultiMediaStream, (void **)&pAMStream); + + if (FAILED(hr)) { + strcpy(lastError, "Could not create a CLSID_MultiMediaStream object. " + "Make sure you have the latest version of DirectX installed."); + return E_FAIL; + } + + //Initialize stream + hr = pAMStream->Initialize(STREAMTYPE_READ, 0, NULL); + if (FAILED(hr)) { + strcpy(lastError, "AMStream::Initialize failed."); + return E_FAIL; + } + //Add primary video stream + hr = pAMStream->AddMediaStream(directdraw, &MSPID_PrimaryVideo, 0, NULL); + if (FAILED(hr)) { + strcpy(lastError, "AddMediaStream failed."); + return E_FAIL; + } + //Add primary audio stream + if (useSound) { + //hr = pAMStream->AddMediaStream(directsound, &MSPID_PrimaryAudio, 0, NULL); + hr = pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL); + if (FAILED(hr)) { + strcpy(lastError, "AddMediaStream failed."); + return E_FAIL; + } + } + //Opens and automatically creates a filter graph for the specified media file + hr = pAMStream->OpenFile(wFile, 0); + if (FAILED(hr)) { + pAMStream->Release(); + sprintf(lastError, "File not found or format not supported: %s", szFilename); + return E_FAIL; + } + + //save the local stream to the global variable + g_pMMStream = pAMStream; + // Add a reference to the file + //pAMStream->AddRef(); + + return NOERROR; } int newWidth, newHeight; -//Perform frame by frame updates and blits. Set the stream +//Perform frame by frame updates and blits. Set the stream //state to STOP if there are no more frames to update. void RenderToSurface(Bitmap *vscreen) { - //update each frame - if (g_pSample->Update(0, NULL, NULL, 0) != S_OK) { - g_bAppactive = FALSE; - g_pMMStream->SetState(STREAMSTATE_STOP); - } - else { - g_bAppactive = TRUE; - Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); - // TODO: don't render on screen bitmap, use gfxDriver->DrawSprite instead! - screen_bmp->Acquire(); - // Because vscreen is a DX Video Bitmap, it can be stretched - // onto the screen (also a Video Bmp) but not onto a memory - // bitmap (which is what "screen" is when using gfx filters) - if (screen_bmp->IsVideoBitmap()) - { - screen_bmp->StretchBlt(vscreen, - RectWH(0, 0, vscreen->GetWidth(), vscreen->GetHeight()), - RectWH(screen_bmp->GetWidth() / 2 - newWidth / 2, - screen_bmp->GetHeight() / 2 - newHeight / 2, - newWidth, newHeight)); - } - else - { - vsMemory->Blit(vscreen, 0, 0, 0, 0, vscreen->GetWidth(), vscreen->GetHeight()); - screen_bmp->StretchBlt(vsMemory, - RectWH(0, 0, vscreen->GetWidth(), vscreen->GetHeight()), - RectWH(screen_bmp->GetWidth() / 2 - newWidth / 2, - screen_bmp->GetHeight() / 2 - newHeight / 2, - newWidth, newHeight)); - } - screen_bmp->Release(); - - // if we're not playing AVI sound, poll the audio system - if (!useSound) - update_audio_system_on_game_loop(); - - render_to_screen(); - } + //update each frame + if (g_pSample->Update(0, NULL, NULL, 0) != S_OK) { + g_bAppactive = FALSE; + g_pMMStream->SetState(STREAMSTATE_STOP); + } else { + g_bAppactive = TRUE; + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + // TODO: don't render on screen bitmap, use gfxDriver->DrawSprite instead! + screen_bmp->Acquire(); + // Because vscreen is a DX Video Bitmap, it can be stretched + // onto the screen (also a Video Bmp) but not onto a memory + // bitmap (which is what "screen" is when using gfx filters) + if (screen_bmp->IsVideoBitmap()) { + screen_bmp->StretchBlt(vscreen, + RectWH(0, 0, vscreen->GetWidth(), vscreen->GetHeight()), + RectWH(screen_bmp->GetWidth() / 2 - newWidth / 2, + screen_bmp->GetHeight() / 2 - newHeight / 2, + newWidth, newHeight)); + } else { + vsMemory->Blit(vscreen, 0, 0, 0, 0, vscreen->GetWidth(), vscreen->GetHeight()); + screen_bmp->StretchBlt(vsMemory, + RectWH(0, 0, vscreen->GetWidth(), vscreen->GetHeight()), + RectWH(screen_bmp->GetWidth() / 2 - newWidth / 2, + screen_bmp->GetHeight() / 2 - newHeight / 2, + newWidth, newHeight)); + } + screen_bmp->Release(); + + // if we're not playing AVI sound, poll the audio system + if (!useSound) + update_audio_system_on_game_loop(); + + render_to_screen(); + } } void dxmedia_pause_video() { - if (currentlyPlaying) { - currentlyPaused = true; - g_pMMStream->SetState(STREAMSTATE_STOP); - } + if (currentlyPlaying) { + currentlyPaused = true; + g_pMMStream->SetState(STREAMSTATE_STOP); + } } void dxmedia_resume_video() { - if (currentlyPlaying) { - currentlyPaused = false; - g_pMMStream->SetState(STREAMSTATE_RUN); - } + if (currentlyPlaying) { + currentlyPaused = false; + g_pMMStream->SetState(STREAMSTATE_RUN); + } } void dxmedia_abort_video() { - if (currentlyPlaying) { + if (currentlyPlaying) { - currentlyPlaying = false; - g_pMMStream->SetState(STREAMSTATE_STOP); + currentlyPlaying = false; + g_pMMStream->SetState(STREAMSTATE_STOP); - ExitCode(); - CoUninitialize(); - delete vscreen; - vscreen = NULL; - if (vsMemory != NULL) - { - delete vsMemory; - vsMemory = NULL; - } - strcpy (lastError, "Played successfully."); - } + ExitCode(); + CoUninitialize(); + delete vscreen; + vscreen = NULL; + if (vsMemory != NULL) { + delete vsMemory; + vsMemory = NULL; + } + strcpy(lastError, "Played successfully."); + } } -int dxmedia_play_video(const char* filename, bool pUseSound, int canskip, int stretch) { - HRESULT hr; - - useSound = pUseSound; - ghWnd = win_get_window(); - - CoInitialize(NULL); - - if (!useSound) - update_polled_stuff_if_runtime(); - - hr = RenderFileToMMStream(filename); - if (FAILED(hr)) { - ExitCode(); - CoUninitialize(); - return -1; - } - - if (!useSound) - update_polled_stuff_if_runtime(); - - hr = InitRenderToSurface(); - if (FAILED(hr)) { - ExitCode(); - CoUninitialize(); - return -1; - } - - newWidth = vscreen->GetWidth(); - newHeight = vscreen->GetHeight(); - - Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); - - if ((stretch == 1) || - (vscreen->GetWidth() > screen_bmp->GetWidth()) || - (vscreen->GetHeight() > screen_bmp->GetHeight())) { - // If they want to stretch, or if it's bigger than the screen, then stretch - float widthRatio = (float)vscreen->GetWidth() / (float)screen_bmp->GetWidth(); - float heightRatio = (float)vscreen->GetHeight() / (float)screen_bmp->GetHeight(); - - if (widthRatio > heightRatio) { - newWidth = vscreen->GetWidth() / widthRatio; - newHeight = vscreen->GetHeight() / widthRatio; - } - else { - newWidth = vscreen->GetWidth() / heightRatio; - newHeight = vscreen->GetHeight() / heightRatio; - } - } - - //Now set the multimedia stream to RUN - hr = g_pMMStream->SetState(STREAMSTATE_RUN); - g_bAppactive = TRUE; - - if (FAILED(hr)) { - sprintf(lastError, "Unable to play stream: 0x%08X", hr); - ExitCode(); - CoUninitialize(); - delete vscreen; - return -1; - } - // in case we're not full screen, clear the background - screen_bmp->Clear(); - - currentlyPlaying = true; - - gfxDriver->ClearDrawLists(); - - while ((g_bAppactive) && (!want_exit)) { - - while (currentlyPaused) { - platform->YieldCPU(); - } - - RenderToSurface(vscreen); - //Sleep(0); - int key, mbut, mwheelz; - if (run_service_key_controls(key)) { - if ((canskip == 1) && (key == 27)) - break; - if (canskip >= 2) - break; - } - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && (canskip == 3)) - break; - } - - dxmedia_abort_video(); - - return 0; +int dxmedia_play_video(const char *filename, bool pUseSound, int canskip, int stretch) { + HRESULT hr; + + useSound = pUseSound; + ghWnd = win_get_window(); + + CoInitialize(NULL); + + if (!useSound) + update_polled_stuff_if_runtime(); + + hr = RenderFileToMMStream(filename); + if (FAILED(hr)) { + ExitCode(); + CoUninitialize(); + return -1; + } + + if (!useSound) + update_polled_stuff_if_runtime(); + + hr = InitRenderToSurface(); + if (FAILED(hr)) { + ExitCode(); + CoUninitialize(); + return -1; + } + + newWidth = vscreen->GetWidth(); + newHeight = vscreen->GetHeight(); + + Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); + + if ((stretch == 1) || + (vscreen->GetWidth() > screen_bmp->GetWidth()) || + (vscreen->GetHeight() > screen_bmp->GetHeight())) { + // If they want to stretch, or if it's bigger than the screen, then stretch + float widthRatio = (float)vscreen->GetWidth() / (float)screen_bmp->GetWidth(); + float heightRatio = (float)vscreen->GetHeight() / (float)screen_bmp->GetHeight(); + + if (widthRatio > heightRatio) { + newWidth = vscreen->GetWidth() / widthRatio; + newHeight = vscreen->GetHeight() / widthRatio; + } else { + newWidth = vscreen->GetWidth() / heightRatio; + newHeight = vscreen->GetHeight() / heightRatio; + } + } + + //Now set the multimedia stream to RUN + hr = g_pMMStream->SetState(STREAMSTATE_RUN); + g_bAppactive = TRUE; + + if (FAILED(hr)) { + sprintf(lastError, "Unable to play stream: 0x%08X", hr); + ExitCode(); + CoUninitialize(); + delete vscreen; + return -1; + } + // in case we're not full screen, clear the background + screen_bmp->Clear(); + + currentlyPlaying = true; + + gfxDriver->ClearDrawLists(); + + while ((g_bAppactive) && (!want_exit)) { + + while (currentlyPaused) { + platform->YieldCPU(); + } + + RenderToSurface(vscreen); + //Sleep(0); + int key, mbut, mwheelz; + if (run_service_key_controls(key)) { + if ((canskip == 1) && (key == 27)) + break; + if (canskip >= 2) + break; + } + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && (canskip == 3)) + break; + } + + dxmedia_abort_video(); + + return 0; } #if 0 @@ -425,19 +419,19 @@ int WINAPI WinMain( LPSTR lpCmdLine, // pointer to command line int nCmdShow) { - install_allegro(SYSTEM_AUTODETECT, &errno, atexit); + install_allegro(SYSTEM_AUTODETECT, &errno, atexit); - install_keyboard(); + install_keyboard(); - set_color_depth(16); - set_gfx_mode (GFX_DIRECTX_WIN, 640, 480, 0,0); + set_color_depth(16); + set_gfx_mode(GFX_DIRECTX_WIN, 640, 480, 0, 0); - set_display_switch_mode(SWITCH_BACKGROUND); + set_display_switch_mode(SWITCH_BACKGROUND); - dxmedia_play_video ("f:\\download\\Seinfeld S05E04 - The Sniffing Accountant.mpg", 1, 1); - dxmedia_play_video ("f:\\download\\Family Guy S02E16 - There's Something About Paulie.mpg", 2, 1); + dxmedia_play_video("f:\\download\\Seinfeld S05E04 - The Sniffing Accountant.mpg", 1, 1); + dxmedia_play_video("f:\\download\\Family Guy S02E16 - There's Something About Paulie.mpg", 2, 1); - return 0; + return 0; } #endif diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp index a7cd8f38c3a5..c964e3412713 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -52,8 +52,7 @@ typedef float D3DVALUE, *LPD3DVALUE; #define USES_CONVERSION int _convert = 0; _convert; UINT _acp = CP_ACP; _acp; LPCWSTR _lpw = NULL; _lpw; LPCSTR _lpa = NULL; _lpa -inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp) -{ +inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp) { // verify that no illegal character present // since lpw was allocated based on the size of lpa // don't worry about the number of chars @@ -61,16 +60,15 @@ inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp) MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars); return lpw; } -inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars) -{ +inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars) { return AtlA2WHelper(lpw, lpa, nChars, CP_ACP); } #define ATLA2WHELPER AtlA2WHelper - #define A2W(lpa) (\ - ((_lpa = lpa) == NULL) ? NULL : (\ - _convert = (lstrlenA(_lpa)+1),\ - ATLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert))) +#define A2W(lpa) (\ + ((_lpa = lpa) == NULL) ? NULL : (\ + _convert = (lstrlenA(_lpa)+1),\ + ATLA2WHELPER((LPWSTR) alloca(_convert*2), _lpa, _convert))) // Interface from main game @@ -81,71 +79,64 @@ extern volatile char want_exit; extern char lastError[300]; CVMR9Graph *graph = NULL; -void dxmedia_shutdown_3d() -{ - if (graph != NULL) - { - delete graph; - graph = NULL; - } +void dxmedia_shutdown_3d() { + if (graph != NULL) { + delete graph; + graph = NULL; + } } -int dxmedia_play_video_3d(const char* filename, IDirect3DDevice9 *device, bool useAVISound, int canskip, int stretch) -{ - HWND gameWindow = win_get_window(); +int dxmedia_play_video_3d(const char *filename, IDirect3DDevice9 *device, bool useAVISound, int canskip, int stretch) { + HWND gameWindow = win_get_window(); - if (graph == NULL) - { - graph = new CVMR9Graph(gameWindow, device); - } + if (graph == NULL) { + graph = new CVMR9Graph(gameWindow, device); + } - if (!useAVISound) - update_audio_system_on_game_loop(); + if (!useAVISound) + update_audio_system_on_game_loop(); - if (!graph->SetMediaFile(filename, useAVISound)) - { - dxmedia_shutdown_3d(); - return -1; - } - graph->SetLayerZOrder(0, 0); + if (!graph->SetMediaFile(filename, useAVISound)) { + dxmedia_shutdown_3d(); + return -1; + } + graph->SetLayerZOrder(0, 0); - if (!useAVISound) - update_audio_system_on_game_loop(); + if (!useAVISound) + update_audio_system_on_game_loop(); - if (!graph->PlayGraph()) - { - dxmedia_shutdown_3d(); - return -1; - } + if (!graph->PlayGraph()) { + dxmedia_shutdown_3d(); + return -1; + } - OAFilterState filterState = State_Running; - while ((filterState != State_Stopped) && (!want_exit)) - { - WaitForNextFrame(); + OAFilterState filterState = State_Running; + while ((filterState != State_Stopped) && (!want_exit)) { + WaitForNextFrame(); - if (!useAVISound) - update_audio_system_on_game_loop(); + if (!useAVISound) + update_audio_system_on_game_loop(); - filterState = graph->GetState(); + filterState = graph->GetState(); - int key, mbut, mwheelz; - if (run_service_key_controls(key)) { - if ((canskip == 1) && (key == 27)) - break; - if (canskip >= 2) - break; - } - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && (canskip == 3)) - break; + int key, mbut, mwheelz; + if (run_service_key_controls(key)) { + if ((canskip == 1) && (key == 27)) + break; + if (canskip >= 2) + break; + } + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && (canskip == 3)) + break; - //device->Present(NULL, NULL, 0, NULL); + //device->Present(NULL, NULL, 0, NULL); } - graph->StopGraph(); + graph->StopGraph(); - dxmedia_shutdown_3d(); - return 0; + dxmedia_shutdown_3d(); + return 0; } @@ -158,7 +149,7 @@ int dxmedia_play_video_3d(const char* filename, IDirect3DDevice9 *device, bool u #if AGS_PLATFORM_DEBUG #undef THIS_FILE -static char THIS_FILE[]=__FILE__; +static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif @@ -166,26 +157,23 @@ static char THIS_FILE[]=__FILE__; // Construction/Destruction ////////////////////////////////////////////////////////////////////// -// Function name : CVMR9Graph::CVMR9Graph -// Description : constructor -// Return type : -CVMR9Graph::CVMR9Graph() -{ +// Function name : CVMR9Graph::CVMR9Graph +// Description : constructor +// Return type : +CVMR9Graph::CVMR9Graph() { InitDefaultValues(); } -// Function name : CVMR9Graph -// Description : constructor -// Return type : +// Function name : CVMR9Graph +// Description : constructor +// Return type : // Argument : HWND MediaWindow // Argument : int NumberOfStream -CVMR9Graph::CVMR9Graph(HWND MediaWindow, IDirect3DDevice9 *device, int NumberOfStream) -{ +CVMR9Graph::CVMR9Graph(HWND MediaWindow, IDirect3DDevice9 *device, int NumberOfStream) { InitDefaultValues(); - - if (MediaWindow != NULL) - { + + if (MediaWindow != NULL) { m_hMediaWindow = MediaWindow; } @@ -193,67 +181,64 @@ CVMR9Graph::CVMR9Graph(HWND MediaWindow, IDirect3DDevice9 *device, int NumberOfS m_nNumberOfStream = NumberOfStream; } - //m_pD3DDevice = device; - m_oldWndProc = GetWindowLong(m_hMediaWindow, GWL_WNDPROC); + //m_pD3DDevice = device; + m_oldWndProc = GetWindowLong(m_hMediaWindow, GWL_WNDPROC); } -// Function name : CVMR9Graph::~CVMR9Graph -// Description : destructor -// Return type : -CVMR9Graph::~CVMR9Graph() -{ +// Function name : CVMR9Graph::~CVMR9Graph +// Description : destructor +// Return type : +CVMR9Graph::~CVMR9Graph() { ReleaseAllInterfaces(); - long newProc = GetWindowLong(m_hMediaWindow, GWL_WNDPROC); + long newProc = GetWindowLong(m_hMediaWindow, GWL_WNDPROC); } -// Function name : CVMR9Graph::InitDefaultValues -// Description : initialize all default values -// Return type : void -void CVMR9Graph::InitDefaultValues() -{ +// Function name : CVMR9Graph::InitDefaultValues +// Description : initialize all default values +// Return type : void +void CVMR9Graph::InitDefaultValues() { ZeroMemory(m_pszErrorDescription, 1024); - m_dwRotId = -1; - m_nNumberOfStream = 4; // default VMR9 config - m_hMediaWindow = NULL; + m_dwRotId = -1; + m_nNumberOfStream = 4; // default VMR9 config + m_hMediaWindow = NULL; // SRC interfaces - for (int i=0; i<10; i++) { + for (int i = 0; i < 10; i++) { m_srcFilterArray[i] = NULL; } // SOUND interface - m_pDirectSoundFilter = NULL; + m_pDirectSoundFilter = NULL; // GRAPH interfaces - m_pGraphUnknown = NULL; - m_pGraphBuilder = NULL; - m_pFilterGraph = NULL; - m_pFilterGraph2 = NULL; - m_pMediaControl = NULL; - m_pMediaSeeking = NULL; - //m_pMediaEvent = NULL; - m_pMediaEventEx = NULL; + m_pGraphUnknown = NULL; + m_pGraphBuilder = NULL; + m_pFilterGraph = NULL; + m_pFilterGraph2 = NULL; + m_pMediaControl = NULL; + m_pMediaSeeking = NULL; + //m_pMediaEvent = NULL; + m_pMediaEventEx = NULL; // VMR9 interfaces - m_pVMRBaseFilter = NULL; - m_pVMRFilterConfig = NULL; - m_pVMRMixerBitmap = NULL; - m_pVMRMixerControl = NULL; - m_pVMRMonitorConfig = NULL; - m_pVMRWindowlessControl = NULL; + m_pVMRBaseFilter = NULL; + m_pVMRFilterConfig = NULL; + m_pVMRMixerBitmap = NULL; + m_pVMRMixerControl = NULL; + m_pVMRMonitorConfig = NULL; + m_pVMRWindowlessControl = NULL; // DIRECT3D interfaces - m_pD3DSurface = NULL; + m_pD3DSurface = NULL; } -// Function name : CVMR9Graph::ReleaseAllInterfaces -// Description : release all of the graph interfaces -// Return type : void -void CVMR9Graph::ReleaseAllInterfaces() -{ +// Function name : CVMR9Graph::ReleaseAllInterfaces +// Description : release all of the graph interfaces +// Return type : void +void CVMR9Graph::ReleaseAllInterfaces() { // CALLBACK handle /*if (m_pMediaEventEx != NULL) { - m_pMediaEventEx->SetNotifyWindow(NULL, WM_MEDIA_NOTIF, NULL); + m_pMediaEventEx->SetNotifyWindow(NULL, WM_MEDIA_NOTIF, NULL); }*/ // SRC interfaces - for (int i=0; i<10; i++) { - IBaseFilter* pSrcFilter = m_srcFilterArray[i]; + for (int i = 0; i < 10; i++) { + IBaseFilter *pSrcFilter = m_srcFilterArray[i]; if (pSrcFilter != NULL) { pSrcFilter->Release(); m_srcFilterArray[i] = NULL; @@ -306,17 +291,17 @@ void CVMR9Graph::ReleaseAllInterfaces() m_pMediaControl->Release(); m_pMediaControl = NULL; } - if (m_pMediaSeeking!= NULL) { + if (m_pMediaSeeking != NULL) { m_pMediaSeeking->Release(); m_pMediaSeeking = NULL; } /*if (m_pMediaEvent != NULL) { - m_pMediaEvent->Release(); - m_pMediaEvent = NULL; + m_pMediaEvent->Release(); + m_pMediaEvent = NULL; }*/ /*if (m_pMediaEventEx != NULL) { - m_pMediaEventEx->Release(); - m_pMediaEventEx = NULL; + m_pMediaEventEx->Release(); + m_pMediaEventEx = NULL; }*/ if (m_pGraphUnknown != NULL) { m_pGraphUnknown->Release(); @@ -334,49 +319,46 @@ void CVMR9Graph::ReleaseAllInterfaces() ////////////////////////////////////////////////////////////////////// -// Function name : CVMR9Graph::GetLastError -// Description : get the last error description -// Return type : LPCTSTR -LPCTSTR CVMR9Graph::GetLastError() -{ - return (const char*)m_pszErrorDescription; +// Function name : CVMR9Graph::GetLastError +// Description : get the last error description +// Return type : LPCTSTR +LPCTSTR CVMR9Graph::GetLastError() { + return (const char *)m_pszErrorDescription; } -// Function name : CVMR9Graph::AddToRot -// Description : let the graph instance be accessible from graphedit -// Return type : HRESULT +// Function name : CVMR9Graph::AddToRot +// Description : let the graph instance be accessible from graphedit +// Return type : HRESULT // Argument : IUnknown *pUnkGraph // Argument : DWORD *pdwRegister -HRESULT CVMR9Graph::AddToRot(IUnknown *pUnkGraph) -{ +HRESULT CVMR9Graph::AddToRot(IUnknown *pUnkGraph) { if (pUnkGraph == NULL) { return E_INVALIDARG; } - IMoniker * pMoniker; - IRunningObjectTable *pROT; - if (FAILED(GetRunningObjectTable(0, &pROT))) { - return E_FAIL; - } - WCHAR wsz[256]; - wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); - HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); - if (SUCCEEDED(hr)) { - hr = pROT->Register(0, pUnkGraph, pMoniker, &m_dwRotId); - pMoniker->Release(); - } - pROT->Release(); + IMoniker *pMoniker; + IRunningObjectTable *pROT; + if (FAILED(GetRunningObjectTable(0, &pROT))) { + return E_FAIL; + } + WCHAR wsz[256]; + wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); + HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); + if (SUCCEEDED(hr)) { + hr = pROT->Register(0, pUnkGraph, pMoniker, &m_dwRotId); + pMoniker->Release(); + } + pROT->Release(); - return hr; + return hr; } -// Function name : CVMR9Graph::RemoveFromRot -// Description : remove the graph instance accessibility from graphedit -// Return type : void -void CVMR9Graph::RemoveFromRot() -{ +// Function name : CVMR9Graph::RemoveFromRot +// Description : remove the graph instance accessibility from graphedit +// Return type : void +void CVMR9Graph::RemoveFromRot() { if (m_dwRotId != -1) { IRunningObjectTable *pROT; if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) { @@ -388,126 +370,116 @@ void CVMR9Graph::RemoveFromRot() } -// Function name : CVMR9Graph::GetPin -// Description : return the desired pin -// Return type : IPin* +// Function name : CVMR9Graph::GetPin +// Description : return the desired pin +// Return type : IPin* // Argument : IBaseFilter *pFilter // Argument : PIN_DIRECTION PinDir -IPin* CVMR9Graph::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) -{ - BOOL bFound = FALSE; - IEnumPins *pEnum; - IPin *pPin; - - pFilter->EnumPins(&pEnum); - while(pEnum->Next(1, &pPin, 0) == S_OK) { - PIN_DIRECTION PinDirThis; - pPin->QueryDirection(&PinDirThis); - if (PinDir == PinDirThis) - { - IPin *pTmp = 0; - if (SUCCEEDED(pPin->ConnectedTo(&pTmp))) // Already connected, not the pin we want. - { - pTmp->Release(); - } - else // Unconnected, this is the pin we want. - { - bFound = true; - break; - } - } - pPin->Release(); - } - pEnum->Release(); - - return (bFound ? pPin : 0); -} - - -// Function name : CVMR9Graph::ReportError -// Description : report an error in the dump device -// Return type : void +IPin *CVMR9Graph::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) { + BOOL bFound = FALSE; + IEnumPins *pEnum; + IPin *pPin; + + pFilter->EnumPins(&pEnum); + while (pEnum->Next(1, &pPin, 0) == S_OK) { + PIN_DIRECTION PinDirThis; + pPin->QueryDirection(&PinDirThis); + if (PinDir == PinDirThis) { + IPin *pTmp = 0; + if (SUCCEEDED(pPin->ConnectedTo(&pTmp))) { // Already connected, not the pin we want. + pTmp->Release(); + } else { // Unconnected, this is the pin we want. + bFound = true; + break; + } + } + pPin->Release(); + } + pEnum->Release(); + + return (bFound ? pPin : 0); +} + + +// Function name : CVMR9Graph::ReportError +// Description : report an error in the dump device +// Return type : void // Argument : const char* pszError // Argument : HRESULT hrCode -void CVMR9Graph::ReportError(const char* pszError, HRESULT hrCode) -{ +void CVMR9Graph::ReportError(const char *pszError, HRESULT hrCode) { TCHAR szErr[MAX_ERROR_TEXT_LEN]; DWORD res = AMGetErrorText(hrCode, szErr, MAX_ERROR_TEXT_LEN); if (res != 0) { - sprintf(m_pszErrorDescription, "[ERROR in %s, line %d] %s : COM Error 0x%x, %s", __FILE__, __LINE__, pszError, hrCode, szErr); + sprintf(m_pszErrorDescription, "[ERROR in %s, line %d] %s : COM Error 0x%x, %s", __FILE__, __LINE__, pszError, hrCode, szErr); } else { sprintf(m_pszErrorDescription, "[ERROR in %s, line %d] %s : COM Error 0x%x", __FILE__, __LINE__, pszError, hrCode); } - strcpy(lastError, m_pszErrorDescription); + strcpy(lastError, m_pszErrorDescription); //TRACE("%s \r\n", m_pszErrorDescription); } -// Function name : CVMR9Graph::GetNextFilter -// Description : -// Return type : HRESULT +// Function name : CVMR9Graph::GetNextFilter +// Description : +// Return type : HRESULT // Argument : IBaseFilter *pFilter // Argument : PIN_DIRECTION Dir // Argument : IBaseFilter **ppNext -HRESULT CVMR9Graph::GetNextFilter(IBaseFilter *pFilter, PIN_DIRECTION Dir, IBaseFilter **ppNext) -{ - if (!pFilter || !ppNext) return E_POINTER; - - IEnumPins *pEnum = 0; - IPin *pPin = 0; - HRESULT hr = pFilter->EnumPins(&pEnum); - if (FAILED(hr)) return hr; - while (S_OK == pEnum->Next(1, &pPin, 0)) { - // See if this pin matches the specified direction. - PIN_DIRECTION ThisPinDir; - hr = pPin->QueryDirection(&ThisPinDir); - if (FAILED(hr)) { - // Something strange happened. - hr = E_UNEXPECTED; - pPin->Release(); - break; - } - if (ThisPinDir == Dir) { - // Check if the pin is connected to another pin. - IPin *pPinNext = 0; - hr = pPin->ConnectedTo(&pPinNext); - if (SUCCEEDED(hr)) - { - // Get the filter that owns that pin. - PIN_INFO PinInfo; - hr = pPinNext->QueryPinInfo(&PinInfo); - pPinNext->Release(); - pPin->Release(); - pEnum->Release(); - if (FAILED(hr) || (PinInfo.pFilter == NULL)) - { - // Something strange happened. - return E_UNEXPECTED; - } - // This is the filter we're looking for. - *ppNext = PinInfo.pFilter; // Client must release. - return S_OK; - } - } - pPin->Release(); - } - pEnum->Release(); - // Did not find a matching filter. - return E_FAIL; -} - - -// Function name : CVMR9Graph::RemoveFilterChain -// Description : remove a chain of filter, stopping at pStopFilter -// Return type : BOOL +HRESULT CVMR9Graph::GetNextFilter(IBaseFilter *pFilter, PIN_DIRECTION Dir, IBaseFilter **ppNext) { + if (!pFilter || !ppNext) return E_POINTER; + + IEnumPins *pEnum = 0; + IPin *pPin = 0; + HRESULT hr = pFilter->EnumPins(&pEnum); + if (FAILED(hr)) return hr; + while (S_OK == pEnum->Next(1, &pPin, 0)) { + // See if this pin matches the specified direction. + PIN_DIRECTION ThisPinDir; + hr = pPin->QueryDirection(&ThisPinDir); + if (FAILED(hr)) { + // Something strange happened. + hr = E_UNEXPECTED; + pPin->Release(); + break; + } + if (ThisPinDir == Dir) { + // Check if the pin is connected to another pin. + IPin *pPinNext = 0; + hr = pPin->ConnectedTo(&pPinNext); + if (SUCCEEDED(hr)) { + // Get the filter that owns that pin. + PIN_INFO PinInfo; + hr = pPinNext->QueryPinInfo(&PinInfo); + pPinNext->Release(); + pPin->Release(); + pEnum->Release(); + if (FAILED(hr) || (PinInfo.pFilter == NULL)) { + // Something strange happened. + return E_UNEXPECTED; + } + // This is the filter we're looking for. + *ppNext = PinInfo.pFilter; // Client must release. + return S_OK; + } + } + pPin->Release(); + } + pEnum->Release(); + // Did not find a matching filter. + return E_FAIL; +} + + +// Function name : CVMR9Graph::RemoveFilterChain +// Description : remove a chain of filter, stopping at pStopFilter +// Return type : BOOL // Argument : IBaseFilter* pFilter // Argument : IBaseFilter* pStopFilter -BOOL CVMR9Graph::RemoveFilterChain(IBaseFilter* pFilter, IBaseFilter* pStopFilter) -{ +BOOL CVMR9Graph::RemoveFilterChain(IBaseFilter *pFilter, IBaseFilter *pStopFilter) { HRESULT hr; - IBaseFilter* pFilterFound = NULL; - + IBaseFilter *pFilterFound = NULL; + hr = GetNextFilter(pFilter, PINDIR_OUTPUT, &pFilterFound); if (SUCCEEDED(hr) && pFilterFound != pStopFilter) { RemoveFilterChain(pFilterFound, pStopFilter); @@ -520,22 +492,20 @@ BOOL CVMR9Graph::RemoveFilterChain(IBaseFilter* pFilter, IBaseFilter* pStopFilte } -// Function name : CVMR9Graph::AddFilterByClsid -// Description : add a filter in the chain -// Return type : HRESULT +// Function name : CVMR9Graph::AddFilterByClsid +// Description : add a filter in the chain +// Return type : HRESULT // Argument : IGraphBuilder *pGraph // Argument : LPCWSTR wszName // Argument : const GUID& clsid // Argument : IBaseFilter **ppF -HRESULT CVMR9Graph::AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, const GUID& clsid, IBaseFilter **ppF) -{ - *ppF = NULL; - HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)ppF); - if (SUCCEEDED(hr)) - { - hr = pGraph->AddFilter((*ppF), wszName); - } - return hr; +HRESULT CVMR9Graph::AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, const GUID &clsid, IBaseFilter **ppF) { + *ppF = NULL; + HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)ppF); + if (SUCCEEDED(hr)) { + hr = pGraph->AddFilter((*ppF), wszName); + } + return hr; } @@ -544,16 +514,15 @@ HRESULT CVMR9Graph::AddFilterByClsid(IGraphBuilder *pGraph, LPCWSTR wszName, con ////////////////////////////////////////////////////////////////////// -// Function name : CVMR9Graph::IsValidLayer -// Description : check for valid layer -// Return type : BOOL +// Function name : CVMR9Graph::IsValidLayer +// Description : check for valid layer +// Return type : BOOL // Argument : int nLayer -BOOL CVMR9Graph::IsValidLayer(int nLayer) -{ +BOOL CVMR9Graph::IsValidLayer(int nLayer) { if (nLayer > 9 || nLayer < 0) return FALSE; - - IBaseFilter* pBaseFilter = m_srcFilterArray[nLayer]; - if (pBaseFilter == NULL) + + IBaseFilter *pBaseFilter = m_srcFilterArray[nLayer]; + if (pBaseFilter == NULL) return FALSE; else return TRUE; @@ -568,17 +537,15 @@ BOOL CVMR9Graph::IsValidLayer(int nLayer) // We need this because the filter graph must be built // on the D3D thread -static int wndproc_build_filter_graph() -{ - return graph->BuildAndRenderGraph(graph->UseAVISound); +static int wndproc_build_filter_graph() { + return graph->BuildAndRenderGraph(graph->UseAVISound); } -BOOL CVMR9Graph::BuildAndRenderGraph(bool withSound) -{ +BOOL CVMR9Graph::BuildAndRenderGraph(bool withSound) { USES_CONVERSION; - int nLayer = 0; - HRESULT hr; + int nLayer = 0; + HRESULT hr; // ENSURE that a valid graph builder is available if (m_pGraphBuilder == NULL) { @@ -586,18 +553,18 @@ BOOL CVMR9Graph::BuildAndRenderGraph(bool withSound) if (!bRet) return bRet; } - // ENSURE that the filter graph is in a stop state + // ENSURE that the filter graph is in a stop state OAFilterState filterState; m_pMediaControl->GetState(500, &filterState); if (filterState != State_Stopped) { m_pMediaControl->Stop(); } - // CHECK a source filter availaibility for the layer + // CHECK a source filter availaibility for the layer if (m_srcFilterArray[nLayer] == NULL) { char pszFilterName[10]; sprintf(pszFilterName, "SRC%02d", nLayer); - IBaseFilter* pBaseFilter = NULL; + IBaseFilter *pBaseFilter = NULL; hr = m_pGraphBuilder->AddSourceFilter(A2W(m_pszFileName), A2W(pszFilterName), &pBaseFilter); if (FAILED(hr)) { ReportError("Could not find a source filter for this file", hr); @@ -606,7 +573,7 @@ BOOL CVMR9Graph::BuildAndRenderGraph(bool withSound) m_srcFilterArray[nLayer] = pBaseFilter; } else { // suppress the old src filter - IBaseFilter* pBaseFilter = m_srcFilterArray[nLayer]; + IBaseFilter *pBaseFilter = m_srcFilterArray[nLayer]; RemoveFilterChain(pBaseFilter, m_pVMRBaseFilter); pBaseFilter->Release(); m_srcFilterArray[nLayer] = NULL; @@ -626,79 +593,76 @@ BOOL CVMR9Graph::BuildAndRenderGraph(bool withSound) BOOL bRet = RenderGraph(); if (!bRet) return bRet; - return TRUE; + return TRUE; } -// Function name : CVMR9Graph::SetMediaFile -// Description : set a media source -// Return type : BOOL +// Function name : CVMR9Graph::SetMediaFile +// Description : set a media source +// Return type : BOOL // Argument : const char* pszFileName // Argument : int nLayer = 0 -BOOL CVMR9Graph::SetMediaFile(const char* pszFileName, bool withSound, int nLayer) -{ +BOOL CVMR9Graph::SetMediaFile(const char *pszFileName, bool withSound, int nLayer) { if (pszFileName == NULL) { ReportError("Could not load a file with an empty file name", E_INVALIDARG); return FALSE; } - UseAVISound = withSound; - m_pszFileName = pszFileName; + UseAVISound = withSound; + m_pszFileName = pszFileName; - if (!wnd_call_proc(wndproc_build_filter_graph)) - return FALSE; + if (!wnd_call_proc(wndproc_build_filter_graph)) + return FALSE; return TRUE; } -// Function name : CVMR9Graph::BuildFilterGraph -// Description : construct the filter graph -// Return type : BOOL -BOOL CVMR9Graph::BuildFilterGraph(bool withSound) -{ +// Function name : CVMR9Graph::BuildFilterGraph +// Description : construct the filter graph +// Return type : BOOL +BOOL CVMR9Graph::BuildFilterGraph(bool withSound) { HRESULT hr; ReleaseAllInterfaces(); RemoveFromRot(); - + // BUILD the filter graph - hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IUnknown, (void**) &m_pGraphUnknown); + hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IUnknown, (void **) &m_pGraphUnknown); if (FAILED(hr)) { ReportError("Could not build the graph", hr); return FALSE; } // QUERY the filter graph interfaces - hr = m_pGraphUnknown->QueryInterface(IID_IGraphBuilder, (void**) &m_pGraphBuilder); - hr = m_pGraphUnknown->QueryInterface(IID_IFilterGraph, (void**) &m_pFilterGraph); - hr = m_pGraphUnknown->QueryInterface(IID_IFilterGraph2, (void**) &m_pFilterGraph2); - hr = m_pGraphUnknown->QueryInterface(IID_IMediaControl, (void**) & m_pMediaControl); - hr = m_pGraphUnknown->QueryInterface(IID_IMediaSeeking, (void**) & m_pMediaSeeking); + hr = m_pGraphUnknown->QueryInterface(IID_IGraphBuilder, (void **) &m_pGraphBuilder); + hr = m_pGraphUnknown->QueryInterface(IID_IFilterGraph, (void **) &m_pFilterGraph); + hr = m_pGraphUnknown->QueryInterface(IID_IFilterGraph2, (void **) &m_pFilterGraph2); + hr = m_pGraphUnknown->QueryInterface(IID_IMediaControl, (void **) & m_pMediaControl); + hr = m_pGraphUnknown->QueryInterface(IID_IMediaSeeking, (void **) & m_pMediaSeeking); //hr = m_pGraphUnknown->QueryInterface(IID_IMediaEvent, (void**) &m_pMediaEvent); //hr = m_pGraphUnknown->QueryInterface(IID_IMediaEventEx, (void**) &m_pMediaEventEx); -/* // SET the graph state window callback - if (m_pMediaEventEx != NULL) { - m_pMediaEventEx->SetNotifyWindow((OAHWND)m_hMediaWindow, WM_MEDIA_NOTIF, NULL); - //m_pMediaEventEx->SetNotifyWindow(NULL, NULL, NULL); - }*/ + /* // SET the graph state window callback + if (m_pMediaEventEx != NULL) { + m_pMediaEventEx->SetNotifyWindow((OAHWND)m_hMediaWindow, WM_MEDIA_NOTIF, NULL); + //m_pMediaEventEx->SetNotifyWindow(NULL, NULL, NULL); + }*/ - if (withSound) - BuildSoundRenderer(); + if (withSound) + BuildSoundRenderer(); // Don't known what's wrong... but RenderEx crash when playing whith graphedit build 021204 ... - //do we need this?? + //do we need this?? //AddToRot(m_pGraphUnknown); return BuildVMR(); } -// Function name : CVMR9Graph::BuildVMR -// Description : construct and add the VMR9 renderer to the graph -// Return type : BOOL -BOOL CVMR9Graph::BuildVMR() -{ +// Function name : CVMR9Graph::BuildVMR +// Description : construct and add the VMR9 renderer to the graph +// Return type : BOOL +BOOL CVMR9Graph::BuildVMR() { HRESULT hr; if (m_hMediaWindow == NULL) { @@ -713,7 +677,7 @@ BOOL CVMR9Graph::BuildVMR() // BUILD the VMR9 IBaseFilter *pVmr = NULL; - hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**) &m_pVMRBaseFilter); + hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **) &m_pVMRBaseFilter); if (FAILED(hr)) { ReportError("Could not create an instance ofthe VMR9", hr); return FALSE; @@ -730,33 +694,32 @@ BOOL CVMR9Graph::BuildVMR() //BOOL bD3D = BuildDirect3d(); // QUERY the VMR9 interfaces - hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRFilterConfig9, (void**) &m_pVMRFilterConfig); + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRFilterConfig9, (void **) &m_pVMRFilterConfig); if (SUCCEEDED(hr)) { // CONFIGURE the VMR9 m_pVMRFilterConfig->SetRenderingMode(VMR9Mode_Windowless); m_pVMRFilterConfig->SetNumberOfStreams(m_nNumberOfStream); } - hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRWindowlessControl9, (void**) &m_pVMRWindowlessControl); + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRWindowlessControl9, (void **) &m_pVMRWindowlessControl); if (SUCCEEDED(hr)) { // CONFIGURE the VMR9 m_pVMRWindowlessControl->SetVideoClippingWindow(m_hMediaWindow); m_pVMRWindowlessControl->SetAspectRatioMode(VMR9ARMode_LetterBox); } - hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMixerBitmap9, (void**) &m_pVMRMixerBitmap); - hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMixerControl9, (void**) &m_pVMRMixerControl); - hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMonitorConfig9, (void**) &m_pVMRMonitorConfig); + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMixerBitmap9, (void **) &m_pVMRMixerBitmap); + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMixerControl9, (void **) &m_pVMRMixerControl); + hr = m_pVMRBaseFilter->QueryInterface(IID_IVMRMonitorConfig9, (void **) &m_pVMRMonitorConfig); return TRUE; } -// Function name : CVMR9Graph::BuildSoundRendered -// Description : build the DirectSound renderer -// Return type : BOOL -BOOL CVMR9Graph::BuildSoundRenderer() -{ +// Function name : CVMR9Graph::BuildSoundRendered +// Description : build the DirectSound renderer +// Return type : BOOL +BOOL CVMR9Graph::BuildSoundRenderer() { HRESULT hr; hr = AddFilterByClsid(m_pGraphBuilder, L"DirectSound", CLSID_DSoundRender, &m_pDirectSoundFilter); @@ -767,11 +730,10 @@ BOOL CVMR9Graph::BuildSoundRenderer() return TRUE; } -// Function name : CVMR9Graph::RenderGraph -// Description : render the graph -// Return type : BOOL -BOOL CVMR9Graph::RenderGraph() -{ +// Function name : CVMR9Graph::RenderGraph +// Description : render the graph +// Return type : BOOL +BOOL CVMR9Graph::RenderGraph() { HRESULT hr; if (m_pFilterGraph2 == NULL) { @@ -779,31 +741,28 @@ BOOL CVMR9Graph::RenderGraph() return FALSE; } - for (int i=0; i<10; i++) { - IBaseFilter* pBaseFilter = m_srcFilterArray[i]; + for (int i = 0; i < 10; i++) { + IBaseFilter *pBaseFilter = m_srcFilterArray[i]; if (pBaseFilter != NULL) { - IPin* pPin; - while ((pPin = GetPin(pBaseFilter, PINDIR_OUTPUT)) != NULL) - { - hr = m_pFilterGraph2->RenderEx(pPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL); - if (FAILED(hr)) - { - ReportError("Unable to render the pin", hr); - return FALSE; - } - } + IPin *pPin; + while ((pPin = GetPin(pBaseFilter, PINDIR_OUTPUT)) != NULL) { + hr = m_pFilterGraph2->RenderEx(pPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL); + if (FAILED(hr)) { + ReportError("Unable to render the pin", hr); + return FALSE; + } + } } } return TRUE; } -// Function name : CVMR9Graph::PreserveAspectRatio -// Description : set aspect ratio mode -// Return type : BOOL +// Function name : CVMR9Graph::PreserveAspectRatio +// Description : set aspect ratio mode +// Return type : BOOL // Argument : BOOL bPreserve -BOOL CVMR9Graph::PreserveAspectRatio(BOOL bPreserve) -{ +BOOL CVMR9Graph::PreserveAspectRatio(BOOL bPreserve) { if (m_pVMRWindowlessControl == NULL) { ReportError("Can't set aspect ratio, no VMR", E_FAIL); return FALSE; @@ -818,18 +777,17 @@ BOOL CVMR9Graph::PreserveAspectRatio(BOOL bPreserve) } -// Function name : CVMR9Graph::AddFilter -// Description : manually add a filter in the graph -// Return type : IBaseFilter* : caller responsible of release +// Function name : CVMR9Graph::AddFilter +// Description : manually add a filter in the graph +// Return type : IBaseFilter* : caller responsible of release // Argument : const char* pszName // Argument : const GUID& clsid -IBaseFilter* CVMR9Graph::AddFilter(const char* pszName, const GUID& clsid) -{ +IBaseFilter *CVMR9Graph::AddFilter(const char *pszName, const GUID &clsid) { USES_CONVERSION; HRESULT hr; - IBaseFilter* pBaseFilter = NULL; + IBaseFilter *pBaseFilter = NULL; if (pszName == NULL) { ReportError("Can't add filter, no valid name", E_INVALIDARG); @@ -845,11 +803,10 @@ IBaseFilter* CVMR9Graph::AddFilter(const char* pszName, const GUID& clsid) return pBaseFilter; } -// Function name : CVMR9Graph::PlayGraph -// Description : run the graph -// Return type : BOOL -BOOL CVMR9Graph::PlayGraph() -{ +// Function name : CVMR9Graph::PlayGraph +// Description : run the graph +// Return type : BOOL +BOOL CVMR9Graph::PlayGraph() { if (m_pMediaControl == NULL) { ReportError("Can't play, no graph", E_FAIL); return FALSE; @@ -884,11 +841,10 @@ BOOL CVMR9Graph::PlayGraph() } -// Function name : CVMR9Graph::StopGraph -// Description : stop the graph -// Return type : BOOL -BOOL CVMR9Graph::StopGraph() -{ +// Function name : CVMR9Graph::StopGraph +// Description : stop the graph +// Return type : BOOL +BOOL CVMR9Graph::StopGraph() { if (m_pMediaControl == NULL) { ReportError("Can't stop, no graph", E_FAIL); return FALSE; @@ -899,32 +855,28 @@ BOOL CVMR9Graph::StopGraph() return TRUE; } -OAFilterState CVMR9Graph::GetState() -{ - OAFilterState filterState; - m_pMediaControl->GetState(500, &filterState); - if (filterState == State_Running) - { - LONGLONG curPos; - m_pMediaSeeking->GetCurrentPosition(&curPos); - LONGLONG length; - m_pMediaSeeking->GetDuration(&length); - - if (curPos >= length) - { - filterState = State_Stopped; - } - } +OAFilterState CVMR9Graph::GetState() { + OAFilterState filterState; + m_pMediaControl->GetState(500, &filterState); + if (filterState == State_Running) { + LONGLONG curPos; + m_pMediaSeeking->GetCurrentPosition(&curPos); + LONGLONG length; + m_pMediaSeeking->GetDuration(&length); + + if (curPos >= length) { + filterState = State_Stopped; + } + } - return filterState; + return filterState; } -// Function name : CVMR9Graph::ResetGraph -// Description : reset the graph - clean interfaces -// Return type : BOOL -BOOL CVMR9Graph::ResetGraph() -{ +// Function name : CVMR9Graph::ResetGraph +// Description : reset the graph - clean interfaces +// Return type : BOOL +BOOL CVMR9Graph::ResetGraph() { // STOP the graph if (m_pMediaControl != NULL) { m_pMediaControl->Stop(); @@ -932,7 +884,7 @@ BOOL CVMR9Graph::ResetGraph() try { ReleaseAllInterfaces(); - } catch(...) { + } catch (...) { ReportError("Can't reset graph, we have serious bugs...", E_FAIL); return FALSE; } @@ -941,13 +893,12 @@ BOOL CVMR9Graph::ResetGraph() } -// Function name : SetLayerZOrder -// Description : set z order of the layer -// Return type : BOOL +// Function name : SetLayerZOrder +// Description : set z order of the layer +// Return type : BOOL // Argument : int nLayer -// Argument : DWORD dwZOrder : bigger is away -BOOL CVMR9Graph::SetLayerZOrder(int nLayer, DWORD dwZOrder) -{ +// Argument : DWORD dwZOrder : bigger is away +BOOL CVMR9Graph::SetLayerZOrder(int nLayer, DWORD dwZOrder) { HRESULT hr; if (!IsValidLayer(nLayer)) { diff --git a/engines/ags/engine/platform/windows/minidump.cpp b/engines/ags/engine/platform/windows/minidump.cpp index 75e5df3bc1d5..8f6314817a54 100644 --- a/engines/ags/engine/platform/windows/minidump.cpp +++ b/engines/ags/engine/platform/windows/minidump.cpp @@ -34,87 +34,82 @@ EXCEPTION_RECORD excinfo; int miniDumpResultCode = 0; typedef enum _MINIDUMP_TYPE { - MiniDumpNormal = 0x0000, - MiniDumpWithDataSegs = 0x0001, - MiniDumpWithFullMemory = 0x0002, - MiniDumpWithHandleData = 0x0004, - MiniDumpFilterMemory = 0x0008, - MiniDumpScanMemory = 0x0010, - MiniDumpWithUnloadedModules = 0x0020, - MiniDumpWithIndirectlyReferencedMemory = 0x0040, - MiniDumpFilterModulePaths = 0x0080, - MiniDumpWithProcessThreadData = 0x0100, - MiniDumpWithPrivateReadWriteMemory = 0x0200, - MiniDumpWithoutOptionalData = 0x0400, + MiniDumpNormal = 0x0000, + MiniDumpWithDataSegs = 0x0001, + MiniDumpWithFullMemory = 0x0002, + MiniDumpWithHandleData = 0x0004, + MiniDumpFilterMemory = 0x0008, + MiniDumpScanMemory = 0x0010, + MiniDumpWithUnloadedModules = 0x0020, + MiniDumpWithIndirectlyReferencedMemory = 0x0040, + MiniDumpFilterModulePaths = 0x0080, + MiniDumpWithProcessThreadData = 0x0100, + MiniDumpWithPrivateReadWriteMemory = 0x0200, + MiniDumpWithoutOptionalData = 0x0400, } MINIDUMP_TYPE; typedef struct _MINIDUMP_EXCEPTION_INFORMATION { - DWORD ThreadId; - PEXCEPTION_POINTERS ExceptionPointers; - BOOL ClientPointers; + DWORD ThreadId; + PEXCEPTION_POINTERS ExceptionPointers; + BOOL ClientPointers; } MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; -typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, - HANDLE hFile, MINIDUMP_TYPE DumpType, - CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - CONST void* UserStreamParam, - CONST void* CallbackParam); +typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, + HANDLE hFile, MINIDUMP_TYPE DumpType, + CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + CONST void *UserStreamParam, + CONST void *CallbackParam); MINIDUMPWRITEDUMP _MiniDumpWriteDump; -void CreateMiniDump( EXCEPTION_POINTERS* pep ) -{ - HMODULE dllHandle = LoadLibrary(L"dbghelp.dll"); - if (dllHandle == NULL) - { - miniDumpResultCode = 1; - return; - } +void CreateMiniDump(EXCEPTION_POINTERS *pep) { + HMODULE dllHandle = LoadLibrary(L"dbghelp.dll"); + if (dllHandle == NULL) { + miniDumpResultCode = 1; + return; + } - _MiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress(dllHandle, "MiniDumpWriteDump"); - if (_MiniDumpWriteDump == NULL) - { - FreeLibrary(dllHandle); - miniDumpResultCode = 2; - return; - } + _MiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress(dllHandle, "MiniDumpWriteDump"); + if (_MiniDumpWriteDump == NULL) { + FreeLibrary(dllHandle); + miniDumpResultCode = 2; + return; + } - char fileName[80]; - sprintf(fileName, "CrashInfo.%s.dmp", EngineVersion.LongString.GetCStr()); - HANDLE hFile = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, - 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + char fileName[80]; + sprintf(fileName, "CrashInfo.%s.dmp", EngineVersion.LongString.GetCStr()); + HANDLE hFile = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, + 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) - { - MINIDUMP_EXCEPTION_INFORMATION mdei; + if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) { + MINIDUMP_EXCEPTION_INFORMATION mdei; - mdei.ThreadId = GetCurrentThreadId(); - mdei.ExceptionPointers = pep; - mdei.ClientPointers = FALSE; + mdei.ThreadId = GetCurrentThreadId(); + mdei.ExceptionPointers = pep; + mdei.ClientPointers = FALSE; - MINIDUMP_TYPE mdt = MiniDumpNormal; //MiniDumpWithPrivateReadWriteMemory; + MINIDUMP_TYPE mdt = MiniDumpNormal; //MiniDumpWithPrivateReadWriteMemory; - BOOL rv = _MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), - hFile, mdt, (pep != 0) ? &mdei : 0, NULL, NULL); + BOOL rv = _MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), + hFile, mdt, (pep != 0) ? &mdei : 0, NULL, NULL); - if (!rv) - miniDumpResultCode = 4; + if (!rv) + miniDumpResultCode = 4; - CloseHandle(hFile); - } - else - miniDumpResultCode = 3; + CloseHandle(hFile); + } else + miniDumpResultCode = 3; - FreeLibrary(dllHandle); + FreeLibrary(dllHandle); } -int CustomExceptionHandler (LPEXCEPTION_POINTERS exinfo) { - cpustate = exinfo->ContextRecord[0]; - excinfo = exinfo->ExceptionRecord[0]; - CreateMiniDump(exinfo); +int CustomExceptionHandler(LPEXCEPTION_POINTERS exinfo) { + cpustate = exinfo->ContextRecord[0]; + excinfo = exinfo->ExceptionRecord[0]; + CreateMiniDump(exinfo); - return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_EXECUTE_HANDLER; } -#endif // AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG +#endif // AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG diff --git a/engines/ags/engine/platform/windows/setup/winsetup.cpp b/engines/ags/engine/platform/windows/setup/winsetup.cpp index a0147381b46c..bb9b49a4219d 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.cpp +++ b/engines/ags/engine/platform/windows/setup/winsetup.cpp @@ -56,19 +56,17 @@ #define DIGI_DIRECTX(n) AL_ID('D','X','A'+(n),' ') #define DIGI_WAVOUTID(n) AL_ID('W','O','A'+(n),' ') #define DIGI_NONE 0 -#define MIDI_AUTODETECT -1 -#define MIDI_NONE 0 +#define MIDI_AUTODETECT -1 +#define MIDI_NONE 0 #define MIDI_WIN32MAPPER AL_ID('W','3','2','M') extern "C" { - HWND win_get_window(); + HWND win_get_window(); } -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using namespace AGS::Common; @@ -77,157 +75,152 @@ using namespace AGS::Common; // WinConfig struct, keeps all configurable data. // //============================================================================= -struct WinConfig -{ - String Title; - String VersionString; - - String DataDirectory; - String UserSaveDir; - GameResolutionType GameResType; - Size GameResolution; - int GameColourDepth; - bool LetterboxByDesign; - - String GfxDriverId; - String GfxFilterId; - Size ScreenSize; - GameFrameSetup FsGameFrame; - GameFrameSetup WinGameFrame; - int RefreshRate; - bool Windowed; - bool VSync; - bool RenderAtScreenRes; - bool AntialiasSprites; - - int DigiID; - int MidiID; - bool ThreadedAudio; - bool UseVoicePack; - - bool MouseAutoLock; - float MouseSpeed; - - int SpriteCacheSize; - String DefaultLanguageName; - String Language; - - WinConfig(); - void SetDefaults(); - void Load(const ConfigTree &cfg); - void Save(ConfigTree &cfg); +struct WinConfig { + String Title; + String VersionString; + + String DataDirectory; + String UserSaveDir; + GameResolutionType GameResType; + Size GameResolution; + int GameColourDepth; + bool LetterboxByDesign; + + String GfxDriverId; + String GfxFilterId; + Size ScreenSize; + GameFrameSetup FsGameFrame; + GameFrameSetup WinGameFrame; + int RefreshRate; + bool Windowed; + bool VSync; + bool RenderAtScreenRes; + bool AntialiasSprites; + + int DigiID; + int MidiID; + bool ThreadedAudio; + bool UseVoicePack; + + bool MouseAutoLock; + float MouseSpeed; + + int SpriteCacheSize; + String DefaultLanguageName; + String Language; + + WinConfig(); + void SetDefaults(); + void Load(const ConfigTree &cfg); + void Save(ConfigTree &cfg); }; -WinConfig::WinConfig() -{ - SetDefaults(); +WinConfig::WinConfig() { + SetDefaults(); } -void WinConfig::SetDefaults() -{ - DataDirectory = "."; - GameResType = kGameResolution_Undefined; - GameColourDepth = 0; - LetterboxByDesign = false; - - GfxFilterId = "StdScale"; - GfxDriverId = "D3D9"; - ScreenSize = get_desktop_size(); - FsGameFrame.ScaleDef = kFrame_MaxProportional; - WinGameFrame.ScaleDef = kFrame_MaxRound; - RefreshRate = 0; - Windowed = false; - VSync = false; - RenderAtScreenRes = false; - AntialiasSprites = false; - - MouseAutoLock = false; - MouseSpeed = 1.f; - - DigiID = -1; // autodetect - MidiID = -1; - ThreadedAudio = false; - UseVoicePack = true; - - SpriteCacheSize = 1024 * 128; - DefaultLanguageName = "Game Default"; - - Title = "Game Setup"; +void WinConfig::SetDefaults() { + DataDirectory = "."; + GameResType = kGameResolution_Undefined; + GameColourDepth = 0; + LetterboxByDesign = false; + + GfxFilterId = "StdScale"; + GfxDriverId = "D3D9"; + ScreenSize = get_desktop_size(); + FsGameFrame.ScaleDef = kFrame_MaxProportional; + WinGameFrame.ScaleDef = kFrame_MaxRound; + RefreshRate = 0; + Windowed = false; + VSync = false; + RenderAtScreenRes = false; + AntialiasSprites = false; + + MouseAutoLock = false; + MouseSpeed = 1.f; + + DigiID = -1; // autodetect + MidiID = -1; + ThreadedAudio = false; + UseVoicePack = true; + + SpriteCacheSize = 1024 * 128; + DefaultLanguageName = "Game Default"; + + Title = "Game Setup"; } -void WinConfig::Load(const ConfigTree &cfg) -{ - DataDirectory = INIreadstring(cfg, "misc", "datadir", DataDirectory); - UserSaveDir = INIreadstring(cfg, "misc", "user_data_dir"); - // Backward-compatible resolution type - GameResType = (GameResolutionType)INIreadint(cfg, "misc", "defaultres", GameResType); - if (GameResType < kGameResolution_Undefined || GameResType >= kNumGameResolutions) - GameResType = kGameResolution_Undefined; - GameResolution.Width = INIreadint(cfg, "misc", "game_width", GameResolution.Width); - GameResolution.Height = INIreadint(cfg, "misc", "game_height", GameResolution.Height); - GameColourDepth = INIreadint(cfg, "misc", "gamecolordepth", GameColourDepth); - LetterboxByDesign = INIreadint(cfg, "misc", "letterbox", 0) != 0; - - GfxDriverId = INIreadstring(cfg, "graphics", "driver", GfxDriverId); - GfxFilterId = INIreadstring(cfg, "graphics", "filter", GfxFilterId); - ScreenSize.Width = INIreadint(cfg, "graphics", "screen_width", ScreenSize.Width); - ScreenSize.Height = INIreadint(cfg, "graphics", "screen_height", ScreenSize.Height); - - parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_fs", make_scaling_option(FsGameFrame)), FsGameFrame); - parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_win", make_scaling_option(WinGameFrame)), WinGameFrame); - - RefreshRate = INIreadint(cfg, "graphics", "refresh", RefreshRate); - Windowed = INIreadint(cfg, "graphics", "windowed", Windowed ? 1 : 0) != 0; - VSync = INIreadint(cfg, "graphics", "vsync", VSync ? 1 : 0) != 0; - RenderAtScreenRes = INIreadint(cfg, "graphics", "render_at_screenres", RenderAtScreenRes ? 1 : 0) != 0; - - AntialiasSprites = INIreadint(cfg, "misc", "antialias", AntialiasSprites ? 1 : 0) != 0; - - DigiID = read_driverid(cfg, "sound", "digiid", DigiID); - MidiID = read_driverid(cfg, "sound", "midiid", MidiID); - ThreadedAudio = INIreadint(cfg, "sound", "threaded", ThreadedAudio ? 1 : 0) != 0; - UseVoicePack = INIreadint(cfg, "sound", "usespeech", UseVoicePack ? 1 : 0) != 0; - - MouseAutoLock = INIreadint(cfg, "mouse", "auto_lock", MouseAutoLock ? 1 : 0) != 0; - MouseSpeed = INIreadfloat(cfg, "mouse", "speed", 1.f); - if (MouseSpeed <= 0.f) - MouseSpeed = 1.f; - - SpriteCacheSize = INIreadint(cfg, "misc", "cachemax", SpriteCacheSize); - Language = INIreadstring(cfg, "language", "translation", Language); - DefaultLanguageName = INIreadstring(cfg, "language", "default_translation_name", DefaultLanguageName); - - Title = INIreadstring(cfg, "misc", "titletext", Title); +void WinConfig::Load(const ConfigTree &cfg) { + DataDirectory = INIreadstring(cfg, "misc", "datadir", DataDirectory); + UserSaveDir = INIreadstring(cfg, "misc", "user_data_dir"); + // Backward-compatible resolution type + GameResType = (GameResolutionType)INIreadint(cfg, "misc", "defaultres", GameResType); + if (GameResType < kGameResolution_Undefined || GameResType >= kNumGameResolutions) + GameResType = kGameResolution_Undefined; + GameResolution.Width = INIreadint(cfg, "misc", "game_width", GameResolution.Width); + GameResolution.Height = INIreadint(cfg, "misc", "game_height", GameResolution.Height); + GameColourDepth = INIreadint(cfg, "misc", "gamecolordepth", GameColourDepth); + LetterboxByDesign = INIreadint(cfg, "misc", "letterbox", 0) != 0; + + GfxDriverId = INIreadstring(cfg, "graphics", "driver", GfxDriverId); + GfxFilterId = INIreadstring(cfg, "graphics", "filter", GfxFilterId); + ScreenSize.Width = INIreadint(cfg, "graphics", "screen_width", ScreenSize.Width); + ScreenSize.Height = INIreadint(cfg, "graphics", "screen_height", ScreenSize.Height); + + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_fs", make_scaling_option(FsGameFrame)), FsGameFrame); + parse_scaling_option(INIreadstring(cfg, "graphics", "game_scale_win", make_scaling_option(WinGameFrame)), WinGameFrame); + + RefreshRate = INIreadint(cfg, "graphics", "refresh", RefreshRate); + Windowed = INIreadint(cfg, "graphics", "windowed", Windowed ? 1 : 0) != 0; + VSync = INIreadint(cfg, "graphics", "vsync", VSync ? 1 : 0) != 0; + RenderAtScreenRes = INIreadint(cfg, "graphics", "render_at_screenres", RenderAtScreenRes ? 1 : 0) != 0; + + AntialiasSprites = INIreadint(cfg, "misc", "antialias", AntialiasSprites ? 1 : 0) != 0; + + DigiID = read_driverid(cfg, "sound", "digiid", DigiID); + MidiID = read_driverid(cfg, "sound", "midiid", MidiID); + ThreadedAudio = INIreadint(cfg, "sound", "threaded", ThreadedAudio ? 1 : 0) != 0; + UseVoicePack = INIreadint(cfg, "sound", "usespeech", UseVoicePack ? 1 : 0) != 0; + + MouseAutoLock = INIreadint(cfg, "mouse", "auto_lock", MouseAutoLock ? 1 : 0) != 0; + MouseSpeed = INIreadfloat(cfg, "mouse", "speed", 1.f); + if (MouseSpeed <= 0.f) + MouseSpeed = 1.f; + + SpriteCacheSize = INIreadint(cfg, "misc", "cachemax", SpriteCacheSize); + Language = INIreadstring(cfg, "language", "translation", Language); + DefaultLanguageName = INIreadstring(cfg, "language", "default_translation_name", DefaultLanguageName); + + Title = INIreadstring(cfg, "misc", "titletext", Title); } -void WinConfig::Save(ConfigTree &cfg) -{ - INIwritestring(cfg, "misc", "user_data_dir", UserSaveDir); - - INIwritestring(cfg, "graphics", "driver", GfxDriverId); - INIwritestring(cfg, "graphics", "filter", GfxFilterId); - INIwritestring(cfg, "graphics", "screen_def", Windowed ? "scaling" : "explicit"); - INIwriteint(cfg, "graphics", "screen_width", ScreenSize.Width); - INIwriteint(cfg, "graphics", "screen_height", ScreenSize.Height); - INIwritestring(cfg, "graphics", "game_scale_fs", make_scaling_option(FsGameFrame)); - INIwritestring(cfg, "graphics", "game_scale_win", make_scaling_option(WinGameFrame)); - INIwriteint(cfg, "graphics", "refresh", RefreshRate); - INIwriteint(cfg, "graphics", "windowed", Windowed ? 1 : 0); - INIwriteint(cfg, "graphics", "vsync", VSync ? 1 : 0); - INIwriteint(cfg, "graphics", "render_at_screenres", RenderAtScreenRes ? 1 : 0); - - INIwriteint(cfg, "misc", "antialias", AntialiasSprites ? 1 : 0); - - write_driverid(cfg, "sound", "digiid", DigiID); - write_driverid(cfg, "sound", "midiid", MidiID); - INIwriteint(cfg, "sound", "threaded", ThreadedAudio ? 1 : 0); - INIwriteint(cfg, "sound", "usespeech", UseVoicePack ? 1 : 0); - - INIwriteint(cfg, "mouse", "auto_lock", MouseAutoLock ? 1 : 0); - INIwritestring(cfg, "mouse", "speed", String::FromFormat("%0.1f", MouseSpeed)); - - INIwriteint(cfg, "misc", "cachemax", SpriteCacheSize); - INIwritestring(cfg, "language", "translation", Language); +void WinConfig::Save(ConfigTree &cfg) { + INIwritestring(cfg, "misc", "user_data_dir", UserSaveDir); + + INIwritestring(cfg, "graphics", "driver", GfxDriverId); + INIwritestring(cfg, "graphics", "filter", GfxFilterId); + INIwritestring(cfg, "graphics", "screen_def", Windowed ? "scaling" : "explicit"); + INIwriteint(cfg, "graphics", "screen_width", ScreenSize.Width); + INIwriteint(cfg, "graphics", "screen_height", ScreenSize.Height); + INIwritestring(cfg, "graphics", "game_scale_fs", make_scaling_option(FsGameFrame)); + INIwritestring(cfg, "graphics", "game_scale_win", make_scaling_option(WinGameFrame)); + INIwriteint(cfg, "graphics", "refresh", RefreshRate); + INIwriteint(cfg, "graphics", "windowed", Windowed ? 1 : 0); + INIwriteint(cfg, "graphics", "vsync", VSync ? 1 : 0); + INIwriteint(cfg, "graphics", "render_at_screenres", RenderAtScreenRes ? 1 : 0); + + INIwriteint(cfg, "misc", "antialias", AntialiasSprites ? 1 : 0); + + write_driverid(cfg, "sound", "digiid", DigiID); + write_driverid(cfg, "sound", "midiid", MidiID); + INIwriteint(cfg, "sound", "threaded", ThreadedAudio ? 1 : 0); + INIwriteint(cfg, "sound", "usespeech", UseVoicePack ? 1 : 0); + + INIwriteint(cfg, "mouse", "auto_lock", MouseAutoLock ? 1 : 0); + INIwritestring(cfg, "mouse", "speed", String::FromFormat("%0.1f", MouseSpeed)); + + INIwriteint(cfg, "misc", "cachemax", SpriteCacheSize); + INIwritestring(cfg, "language", "translation", Language); } @@ -237,131 +230,110 @@ void WinConfig::Save(ConfigTree &cfg) // //============================================================================= -int AddString(HWND hwnd, LPCTSTR text, DWORD_PTR data = 0L) -{ - int index = SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)text); - if (index >= 0) - SendMessage(hwnd, CB_SETITEMDATA, index, data); - return index; +int AddString(HWND hwnd, LPCTSTR text, DWORD_PTR data = 0L) { + int index = SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)text); + if (index >= 0) + SendMessage(hwnd, CB_SETITEMDATA, index, data); + return index; } -int InsertString(HWND hwnd, LPCTSTR text, int at_index, DWORD_PTR data = 0L) -{ - int index = SendMessage(hwnd, CB_INSERTSTRING, at_index, (LPARAM)text); - if (index >= 0) - SendMessage(hwnd, CB_SETITEMDATA, index, data); - return index; +int InsertString(HWND hwnd, LPCTSTR text, int at_index, DWORD_PTR data = 0L) { + int index = SendMessage(hwnd, CB_INSERTSTRING, at_index, (LPARAM)text); + if (index >= 0) + SendMessage(hwnd, CB_SETITEMDATA, index, data); + return index; } -int GetItemCount(HWND hwnd) -{ - return SendMessage(hwnd, CB_GETCOUNT, 0, 0L); +int GetItemCount(HWND hwnd) { + return SendMessage(hwnd, CB_GETCOUNT, 0, 0L); } -bool GetCheck(HWND hwnd) -{ - return SendMessage(hwnd, BM_GETCHECK, 0, 0) != FALSE; +bool GetCheck(HWND hwnd) { + return SendMessage(hwnd, BM_GETCHECK, 0, 0) != FALSE; } -void SetCheck(HWND hwnd, bool check) -{ - SendMessage(hwnd, BM_SETCHECK, check ? BST_CHECKED : BST_UNCHECKED, 0); +void SetCheck(HWND hwnd, bool check) { + SendMessage(hwnd, BM_SETCHECK, check ? BST_CHECKED : BST_UNCHECKED, 0); } -int GetCurSel(HWND hwnd) -{ - return SendMessage(hwnd, CB_GETCURSEL, 0, 0); +int GetCurSel(HWND hwnd) { + return SendMessage(hwnd, CB_GETCURSEL, 0, 0); } -void SetCurSel(HWND hwnd, int cur_sel) -{ - SendMessage(hwnd, CB_SETCURSEL, cur_sel, 0); +void SetCurSel(HWND hwnd, int cur_sel) { + SendMessage(hwnd, CB_SETCURSEL, cur_sel, 0); } typedef bool (*PfnCompareCBItemData)(DWORD_PTR data1, DWORD_PTR data2); -bool CmpICBItemDataAsStr(DWORD_PTR data1, DWORD_PTR data2) -{ - LPCTSTR text_ptr1 = (LPCTSTR)data1; - LPCTSTR text_ptr2 = (LPCTSTR)data2; - return text_ptr1 && text_ptr2 && StrCmpI(text_ptr1, text_ptr2) == 0 || !text_ptr1 && !text_ptr2; +bool CmpICBItemDataAsStr(DWORD_PTR data1, DWORD_PTR data2) { + LPCTSTR text_ptr1 = (LPCTSTR)data1; + LPCTSTR text_ptr2 = (LPCTSTR)data2; + return text_ptr1 && text_ptr2 && StrCmpI(text_ptr1, text_ptr2) == 0 || !text_ptr1 && !text_ptr2; } -int SetCurSelToItemData(HWND hwnd, DWORD_PTR data, PfnCompareCBItemData pfn_cmp = NULL, int def_sel = -1) -{ - int count = SendMessage(hwnd, CB_GETCOUNT, 0, 0); - for (int i = 0; i < count; ++i) - { - DWORD_PTR item_data = SendMessage(hwnd, CB_GETITEMDATA, i, 0); - if (pfn_cmp && pfn_cmp(item_data, data) || !pfn_cmp && item_data == data) - { - LRESULT res = SendMessage(hwnd, CB_SETCURSEL, i, 0); - if (res != CB_ERR) - return res; - break; - } - } - return SendMessage(hwnd, CB_SETCURSEL, def_sel, 0); +int SetCurSelToItemData(HWND hwnd, DWORD_PTR data, PfnCompareCBItemData pfn_cmp = NULL, int def_sel = -1) { + int count = SendMessage(hwnd, CB_GETCOUNT, 0, 0); + for (int i = 0; i < count; ++i) { + DWORD_PTR item_data = SendMessage(hwnd, CB_GETITEMDATA, i, 0); + if (pfn_cmp && pfn_cmp(item_data, data) || !pfn_cmp && item_data == data) { + LRESULT res = SendMessage(hwnd, CB_SETCURSEL, i, 0); + if (res != CB_ERR) + return res; + break; + } + } + return SendMessage(hwnd, CB_SETCURSEL, def_sel, 0); } -int SetCurSelToItemDataStr(HWND hwnd, LPCTSTR text, int def_sel = -1) -{ - return SetCurSelToItemData(hwnd, (DWORD_PTR)text, CmpICBItemDataAsStr, def_sel); +int SetCurSelToItemDataStr(HWND hwnd, LPCTSTR text, int def_sel = -1) { + return SetCurSelToItemData(hwnd, (DWORD_PTR)text, CmpICBItemDataAsStr, def_sel); } -DWORD_PTR GetCurItemData(HWND hwnd, DWORD_PTR def_value = 0) -{ - int index = SendMessage(hwnd, CB_GETCURSEL, 0, 0); - if (index >= 0) - return SendMessage(hwnd, CB_GETITEMDATA, index, 0); - return def_value; +DWORD_PTR GetCurItemData(HWND hwnd, DWORD_PTR def_value = 0) { + int index = SendMessage(hwnd, CB_GETCURSEL, 0, 0); + if (index >= 0) + return SendMessage(hwnd, CB_GETITEMDATA, index, 0); + return def_value; } -String GetText(HWND hwnd) -{ - TCHAR short_buf[MAX_PATH + 1]; - int len = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); - if (len > 0) - { - TCHAR *buf = len >= sizeof(short_buf) ? new TCHAR[len + 1] : short_buf; - SendMessage(hwnd, WM_GETTEXT, len + 1, (LPARAM)buf); - String s = buf; - if (buf != short_buf) - delete [] buf; - return s; - } - return ""; +String GetText(HWND hwnd) { + TCHAR short_buf[MAX_PATH + 1]; + int len = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); + if (len > 0) { + TCHAR *buf = len >= sizeof(short_buf) ? new TCHAR[len + 1] : short_buf; + SendMessage(hwnd, WM_GETTEXT, len + 1, (LPARAM)buf); + String s = buf; + if (buf != short_buf) + delete [] buf; + return s; + } + return ""; } -void SetText(HWND hwnd, LPCTSTR text) -{ - SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)text); +void SetText(HWND hwnd, LPCTSTR text) { + SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)text); } -void ResetContent(HWND hwnd) -{ - SendMessage(hwnd, CB_RESETCONTENT, 0, 0); +void ResetContent(HWND hwnd) { + SendMessage(hwnd, CB_RESETCONTENT, 0, 0); } -void SetSliderRange(HWND hwnd, int min, int max) -{ - SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(min, max)); +void SetSliderRange(HWND hwnd, int min, int max) { + SendMessage(hwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(min, max)); } -int GetSliderPos(HWND hwnd) -{ - return SendMessage(hwnd, TBM_GETPOS, 0, 0); +int GetSliderPos(HWND hwnd) { + return SendMessage(hwnd, TBM_GETPOS, 0, 0); } -void SetSliderPos(HWND hwnd, int pos) -{ - SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); +void SetSliderPos(HWND hwnd, int pos) { + SendMessage(hwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos); } -void MakeFullLongPath(const char *path, char *out_buf, int buf_len) -{ - GetFullPathName(path, buf_len, out_buf, NULL); - GetLongPathName(out_buf, out_buf, buf_len); +void MakeFullLongPath(const char *path, char *out_buf, int buf_len) { + GetFullPathName(path, buf_len, out_buf, NULL); + GetLongPathName(out_buf, out_buf, buf_len); } @@ -371,40 +343,35 @@ void MakeFullLongPath(const char *path, char *out_buf, int buf_len) // //============================================================================= -int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) -{ - if (uMsg == BFFM_INITIALIZED) - { - // Set initial selection - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpData); - } - return 0; +int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { + if (uMsg == BFFM_INITIALIZED) { + // Set initial selection + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpData); + } + return 0; } -bool BrowseForFolder(String &dir_buf) -{ - bool res = false; - CoInitialize(NULL); - - BROWSEINFO bi = { 0 }; - bi.lpszTitle = "Select location for game saves and custom data files"; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS; - bi.lpfn = BrowseCallbackProc; - bi.lParam = (LPARAM)dir_buf.GetCStr(); - LPITEMIDLIST pidl = SHBrowseForFolder ( &bi ); - if (pidl) - { - char path[MAX_PATH]; - if (SHGetPathFromIDList(pidl, path) != FALSE) - { - dir_buf = path; - res = true; - } - CoTaskMemFree(pidl); - } - - CoUninitialize(); - return res; +bool BrowseForFolder(String &dir_buf) { + bool res = false; + CoInitialize(NULL); + + BROWSEINFO bi = { 0 }; + bi.lpszTitle = "Select location for game saves and custom data files"; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS; + bi.lpfn = BrowseCallbackProc; + bi.lParam = (LPARAM)dir_buf.GetCStr(); + LPITEMIDLIST pidl = SHBrowseForFolder(&bi); + if (pidl) { + char path[MAX_PATH]; + if (SHGetPathFromIDList(pidl, path) != FALSE) { + dir_buf = path; + res = true; + } + CoTaskMemFree(pidl); + } + + CoUninitialize(); + return res; } @@ -413,831 +380,763 @@ bool BrowseForFolder(String &dir_buf) // WinSetupDialog, handles the dialog UI. // //============================================================================= -class WinSetupDialog -{ +class WinSetupDialog { public: - enum GfxModeSpecial - { - kGfxMode_None = -1, - kGfxMode_Desktop = -2, - kGfxMode_GameRes = -3, - }; + enum GfxModeSpecial { + kGfxMode_None = -1, + kGfxMode_Desktop = -2, + kGfxMode_GameRes = -3, + }; - static const int MouseSpeedMin = 1; - static const int MouseSpeedMax = 100; + static const int MouseSpeedMin = 1; + static const int MouseSpeedMax = 100; public: - WinSetupDialog(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &data_dir, const String &version_str); - ~WinSetupDialog(); - static SetupReturnValue ShowModal(const ConfigTree &cfg_in, ConfigTree &cfg_out, - const String &data_dir, const String &version_str); + WinSetupDialog(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &data_dir, const String &version_str); + ~WinSetupDialog(); + static SetupReturnValue ShowModal(const ConfigTree &cfg_in, ConfigTree &cfg_out, + const String &data_dir, const String &version_str); private: - static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - - // Event handlers - INT_PTR OnInitDialog(HWND hwnd); - INT_PTR OnCommand(WORD id); - INT_PTR OnListSelection(WORD id); - void OnCustomSaveDirBtn(); - void OnCustomSaveDirCheck(); - void OnGfxDriverUpdate(); - void OnGfxFilterUpdate(); - void OnGfxModeUpdate(); - void OnScalingUpdate(HWND hlist, GameFrameSetup &frame_setup, bool windowed); - void OnWindowedUpdate(); - void ShowAdvancedOptions(); - - // Helper structs - typedef std::vector VDispModes; - // NOTE: we have to implement IGfxModeList for now because we are using - // few engine functions that take IGfxModeList as parameter - struct GfxModes : public IGfxModeList - { - VDispModes Modes; - - virtual int GetModeCount() const; - virtual bool GetMode(int index, DisplayMode &mode) const; - }; - - typedef std::vector VFilters; - struct DriverDesc - { - String Id; // internal id - String UserName; // human-friendly driver name - GfxModes GfxModeList; // list of supported modes - VFilters FilterList; // list of supported filters - int UseColorDepth; // recommended display depth - }; - - // Operations - void AddScalingString(HWND hlist, int scaling_factor); - void FillGfxFilterList(); - void FillGfxModeList(); - void FillLanguageList(); - void FillScalingList(HWND hlist, GameFrameSetup &frame_setup, bool windowed); - void InitGfxModes(); - void InitDriverDescFromFactory(const String &id); - void SaveSetup(); - void SelectNearestGfxMode(const Size screen_size); - void SetGfxModeText(); - void UpdateMouseSpeedText(); - - // Dialog singleton and properties - static WinSetupDialog *_dlg; - HWND _hwnd; - WinConfig _winCfg; - const ConfigTree &_cfgIn; - ConfigTree &_cfgOut; - // Window size - Size _winSize; - Size _baseSize; - // Driver descriptions - typedef std::shared_ptr PDriverDesc; - typedef std::map DriverDescMap; - DriverDescMap _drvDescMap; - PDriverDesc _drvDesc; - GfxFilterInfo _gfxFilterInfo; - // Resolution limits - Size _desktopSize; - Size _maxWindowSize; - Size _minGameSize; - int _maxGameScale = 0; - int _minGameScale = 0; - - // Dialog controls - HWND _hVersionText = NULL; - HWND _hCustomSaveDir = NULL; - HWND _hCustomSaveDirBtn = NULL; - HWND _hCustomSaveDirCheck = NULL; - HWND _hGfxDriverList = NULL; - HWND _hGfxModeList = NULL; - HWND _hGfxFilterList = NULL; - HWND _hFsScalingList = NULL; - HWND _hWinScalingList = NULL; - HWND _hDigiDriverList = NULL; - HWND _hMidiDriverList = NULL; - HWND _hLanguageList = NULL; - HWND _hSpriteCacheList = NULL; - HWND _hWindowed = NULL; - HWND _hVSync = NULL; - HWND _hRenderAtScreenRes = NULL; - HWND _hRefresh85Hz = NULL; - HWND _hAntialiasSprites = NULL; - HWND _hThreadedAudio = NULL; - HWND _hUseVoicePack = NULL; - HWND _hAdvanced = NULL; - HWND _hGameResolutionText = NULL; - HWND _hGfxModeText = NULL; - HWND _hMouseLock = NULL; - HWND _hMouseSpeed = NULL; - HWND _hMouseSpeedText = NULL; + static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + + // Event handlers + INT_PTR OnInitDialog(HWND hwnd); + INT_PTR OnCommand(WORD id); + INT_PTR OnListSelection(WORD id); + void OnCustomSaveDirBtn(); + void OnCustomSaveDirCheck(); + void OnGfxDriverUpdate(); + void OnGfxFilterUpdate(); + void OnGfxModeUpdate(); + void OnScalingUpdate(HWND hlist, GameFrameSetup &frame_setup, bool windowed); + void OnWindowedUpdate(); + void ShowAdvancedOptions(); + + // Helper structs + typedef std::vector VDispModes; + // NOTE: we have to implement IGfxModeList for now because we are using + // few engine functions that take IGfxModeList as parameter + struct GfxModes : public IGfxModeList { + VDispModes Modes; + + virtual int GetModeCount() const; + virtual bool GetMode(int index, DisplayMode &mode) const; + }; + + typedef std::vector VFilters; + struct DriverDesc { + String Id; // internal id + String UserName; // human-friendly driver name + GfxModes GfxModeList; // list of supported modes + VFilters FilterList; // list of supported filters + int UseColorDepth; // recommended display depth + }; + + // Operations + void AddScalingString(HWND hlist, int scaling_factor); + void FillGfxFilterList(); + void FillGfxModeList(); + void FillLanguageList(); + void FillScalingList(HWND hlist, GameFrameSetup &frame_setup, bool windowed); + void InitGfxModes(); + void InitDriverDescFromFactory(const String &id); + void SaveSetup(); + void SelectNearestGfxMode(const Size screen_size); + void SetGfxModeText(); + void UpdateMouseSpeedText(); + + // Dialog singleton and properties + static WinSetupDialog *_dlg; + HWND _hwnd; + WinConfig _winCfg; + const ConfigTree &_cfgIn; + ConfigTree &_cfgOut; + // Window size + Size _winSize; + Size _baseSize; + // Driver descriptions + typedef std::shared_ptr PDriverDesc; + typedef std::map DriverDescMap; + DriverDescMap _drvDescMap; + PDriverDesc _drvDesc; + GfxFilterInfo _gfxFilterInfo; + // Resolution limits + Size _desktopSize; + Size _maxWindowSize; + Size _minGameSize; + int _maxGameScale = 0; + int _minGameScale = 0; + + // Dialog controls + HWND _hVersionText = NULL; + HWND _hCustomSaveDir = NULL; + HWND _hCustomSaveDirBtn = NULL; + HWND _hCustomSaveDirCheck = NULL; + HWND _hGfxDriverList = NULL; + HWND _hGfxModeList = NULL; + HWND _hGfxFilterList = NULL; + HWND _hFsScalingList = NULL; + HWND _hWinScalingList = NULL; + HWND _hDigiDriverList = NULL; + HWND _hMidiDriverList = NULL; + HWND _hLanguageList = NULL; + HWND _hSpriteCacheList = NULL; + HWND _hWindowed = NULL; + HWND _hVSync = NULL; + HWND _hRenderAtScreenRes = NULL; + HWND _hRefresh85Hz = NULL; + HWND _hAntialiasSprites = NULL; + HWND _hThreadedAudio = NULL; + HWND _hUseVoicePack = NULL; + HWND _hAdvanced = NULL; + HWND _hGameResolutionText = NULL; + HWND _hGfxModeText = NULL; + HWND _hMouseLock = NULL; + HWND _hMouseSpeed = NULL; + HWND _hMouseSpeedText = NULL; }; WinSetupDialog *WinSetupDialog::_dlg = NULL; WinSetupDialog::WinSetupDialog(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &data_dir, const String &version_str) - : _hwnd(NULL) - , _cfgIn(cfg_in) - , _cfgOut(cfg_out) -{ - _winCfg.DataDirectory = data_dir; - _winCfg.VersionString = version_str; + : _hwnd(NULL) + , _cfgIn(cfg_in) + , _cfgOut(cfg_out) { + _winCfg.DataDirectory = data_dir; + _winCfg.VersionString = version_str; } -WinSetupDialog::~WinSetupDialog() -{ +WinSetupDialog::~WinSetupDialog() { } SetupReturnValue WinSetupDialog::ShowModal(const ConfigTree &cfg_in, ConfigTree &cfg_out, - const String &data_dir, const String &version_str) -{ - _dlg = new WinSetupDialog(cfg_in, cfg_out, data_dir, version_str); - INT_PTR dlg_res = DialogBoxParam(GetModuleHandle(NULL), (LPCTSTR)IDD_SETUP, win_get_window(), - (DLGPROC)WinSetupDialog::DialogProc, 0L); - delete _dlg; - _dlg = NULL; - - switch (dlg_res) - { - case IDOKRUN: return kSetup_RunGame; - case IDOK: return kSetup_Done; - default: return kSetup_Cancel; - } + const String &data_dir, const String &version_str) { + _dlg = new WinSetupDialog(cfg_in, cfg_out, data_dir, version_str); + INT_PTR dlg_res = DialogBoxParam(GetModuleHandle(NULL), (LPCTSTR)IDD_SETUP, win_get_window(), + (DLGPROC)WinSetupDialog::DialogProc, 0L); + delete _dlg; + _dlg = NULL; + + switch (dlg_res) { + case IDOKRUN: + return kSetup_RunGame; + case IDOK: + return kSetup_Done; + default: + return kSetup_Cancel; + } } -INT_PTR WinSetupDialog::OnInitDialog(HWND hwnd) -{ - _hwnd = hwnd; - _hVersionText = GetDlgItem(_hwnd, IDC_VERSION); - _hCustomSaveDir = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIR); - _hCustomSaveDirBtn = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIRBTN); - _hCustomSaveDirCheck = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIRCHECK); - _hGfxDriverList = GetDlgItem(_hwnd, IDC_GFXDRIVER); - _hGfxModeList = GetDlgItem(_hwnd, IDC_GFXMODE); - _hGfxFilterList = GetDlgItem(_hwnd, IDC_GFXFILTER); - _hFsScalingList = GetDlgItem(_hwnd, IDC_FSSCALING); - _hWinScalingList = GetDlgItem(_hwnd, IDC_WINDOWSCALING); - _hDigiDriverList = GetDlgItem(_hwnd, IDC_DIGISOUND); - _hMidiDriverList = GetDlgItem(_hwnd, IDC_MIDIMUSIC); - _hLanguageList = GetDlgItem(_hwnd, IDC_LANGUAGE); - _hSpriteCacheList = GetDlgItem(_hwnd, IDC_SPRITECACHE); - _hWindowed = GetDlgItem(_hwnd, IDC_WINDOWED); - _hVSync = GetDlgItem(_hwnd, IDC_VSYNC); - _hRenderAtScreenRes = GetDlgItem(_hwnd, IDC_RENDERATSCREENRES); - _hRefresh85Hz = GetDlgItem(_hwnd, IDC_REFRESH_85HZ); - _hAntialiasSprites = GetDlgItem(_hwnd, IDC_ANTIALIAS); - _hThreadedAudio = GetDlgItem(_hwnd, IDC_THREADEDAUDIO); - _hUseVoicePack = GetDlgItem(_hwnd, IDC_VOICEPACK); - _hAdvanced = GetDlgItem(_hwnd, IDC_ADVANCED); - _hGameResolutionText = GetDlgItem(_hwnd, IDC_RESOLUTION); - _hGfxModeText = GetDlgItem(_hwnd, IDC_GFXMODETEXT); - _hMouseLock = GetDlgItem(_hwnd, IDC_MOUSE_AUTOLOCK); - _hMouseSpeed = GetDlgItem(_hwnd, IDC_MOUSESPEED); - _hMouseSpeedText = GetDlgItem(_hwnd, IDC_MOUSESPEED_TEXT); - - _desktopSize = get_desktop_size(); - _maxWindowSize = _desktopSize; - AGSPlatformDriver::GetDriver()->ValidateWindowSize(_maxWindowSize.Width, _maxWindowSize.Height, false); - _minGameSize = Size(320, 200); - _maxGameScale = 1; - _minGameScale = 1; - - _winCfg.Load(_cfgIn); - - // Custom save dir controls - String custom_save_dir = _winCfg.UserSaveDir; - bool has_save_dir = !custom_save_dir.IsEmpty(); - if (!has_save_dir) - custom_save_dir = _winCfg.DataDirectory; - SetCheck(_hCustomSaveDirCheck, has_save_dir); - char full_save_dir[MAX_PATH] = {0}; - MakeFullLongPath(custom_save_dir, full_save_dir, MAX_PATH); - SetText(_hCustomSaveDir, full_save_dir); - EnableWindow(_hCustomSaveDir, has_save_dir ? TRUE : FALSE); - EnableWindow(_hCustomSaveDirBtn, has_save_dir ? TRUE : FALSE); - - // Resolution controls - if (_winCfg.GameResolution.IsNull() && - (_winCfg.GameResType == kGameResolution_Undefined || _winCfg.GameResType == kGameResolution_Custom) || - _winCfg.GameColourDepth == 0) - MessageBox(_hwnd, "Essential information about the game is missing in the configuration file. Setup program may be unable to deduce graphic modes properly.", "Initialization error", MB_OK | MB_ICONWARNING); - - if (_winCfg.GameResolution.IsNull()) - _winCfg.GameResolution = ResolutionTypeToSize(_winCfg.GameResType, _winCfg.LetterboxByDesign); - - SetText(_hwnd, _winCfg.Title); - SetText(win_get_window(), _winCfg.Title); - SetText(_hGameResolutionText, String::FromFormat("Native game resolution: %d x %d x %d", - _winCfg.GameResolution.Width, _winCfg.GameResolution.Height, _winCfg.GameColourDepth)); - - SetText(_hVersionText, _winCfg.VersionString); - - InitGfxModes(); - - for (DriverDescMap::const_iterator it = _drvDescMap.begin(); it != _drvDescMap.end(); ++it) - AddString(_hGfxDriverList, it->second->UserName, (DWORD_PTR)it->second->Id.GetCStr()); - SetCurSelToItemDataStr(_hGfxDriverList, _winCfg.GfxDriverId.GetCStr(), 0); - OnGfxDriverUpdate(); - - SetCheck(_hWindowed, _winCfg.Windowed); - OnWindowedUpdate(); - - FillScalingList(_hFsScalingList, _winCfg.FsGameFrame, false); - FillScalingList(_hWinScalingList, _winCfg.WinGameFrame, true); - - SetCheck(_hVSync, _winCfg.VSync); - - SetCheck(_hRenderAtScreenRes, _winCfg.RenderAtScreenRes); - - AddString(_hDigiDriverList, "No Digital Sound", DIGI_NONE); - AddString(_hDigiDriverList, "Default device (auto)", MIDI_AUTODETECT); - AddString(_hDigiDriverList, "Default DirectSound Device", DIGI_DIRECTAMX(0)); - AddString(_hDigiDriverList, "Default WaveOut Device", DIGI_WAVOUTID(0)); - AddString(_hDigiDriverList, "DirectSound (Hardware mixer)", DIGI_DIRECTX(0)); - SetCurSelToItemData(_hDigiDriverList, _winCfg.DigiID); - - AddString(_hMidiDriverList, "No MIDI music", MIDI_NONE); - AddString(_hMidiDriverList, "Default device (auto)", MIDI_AUTODETECT); - AddString(_hMidiDriverList, "Win32 MIDI Mapper", MIDI_WIN32MAPPER); - SetCurSelToItemData(_hMidiDriverList, _winCfg.MidiID); - - FillLanguageList(); - - SetCheck(_hMouseLock, _winCfg.MouseAutoLock); - - SetSliderRange(_hMouseSpeed, MouseSpeedMin, MouseSpeedMax); - int slider_pos = (int)(_winCfg.MouseSpeed * 10.f + .5f); - SetSliderPos(_hMouseSpeed, slider_pos); - UpdateMouseSpeedText(); - - AddString(_hSpriteCacheList, "16 MB", 16); - AddString(_hSpriteCacheList, "32 MB", 32); - AddString(_hSpriteCacheList, "64 MB", 64); - AddString(_hSpriteCacheList, "128 MB (default)", 128); - AddString(_hSpriteCacheList, "256 MB", 256); - AddString(_hSpriteCacheList, "384 MB", 384); - AddString(_hSpriteCacheList, "512 MB", 512); - SetCurSelToItemData(_hSpriteCacheList, _winCfg.SpriteCacheSize / 1024, NULL, 3); - - SetCheck(_hRefresh85Hz, _winCfg.RefreshRate == 85); - SetCheck(_hAntialiasSprites, _winCfg.AntialiasSprites); - SetCheck(_hThreadedAudio, _winCfg.ThreadedAudio); - SetCheck(_hUseVoicePack, _winCfg.UseVoicePack); - if (!File::TestReadFile("speech.vox")) - EnableWindow(_hUseVoicePack, FALSE); - - if (INIreadint(_cfgIn, "disabled", "threaded_audio", 0) != 0) - EnableWindow(_hThreadedAudio, FALSE); - if (INIreadint(_cfgIn, "disabled", "speechvox", 0) != 0) - EnableWindow(_hUseVoicePack, FALSE); - if (INIreadint(_cfgIn, "disabled", "filters", 0) != 0) - EnableWindow(_hGfxFilterList, FALSE); - if (INIreadint(_cfgIn, "disabled", "render_at_screenres", 0) != 0) - EnableWindow(_hRenderAtScreenRes, FALSE); - - RECT win_rect, gfx_rect, adv_rect, border; - GetWindowRect(_hwnd, &win_rect); - GetWindowRect(GetDlgItem(_hwnd, IDC_GFXOPTIONS), &gfx_rect); - _winSize.Width = win_rect.right - win_rect.left; - _winSize.Height = win_rect.bottom - win_rect.top; - GetWindowRect(_hAdvanced, &adv_rect); - border.left = border.top = border.right = border.bottom = 9; - MapDialogRect(_hwnd, &border); - _baseSize.Width = (adv_rect.right + (gfx_rect.left - win_rect.left)) - win_rect.left; - _baseSize.Height = adv_rect.bottom - win_rect.top + border.bottom; - - MoveWindow(_hwnd, max(0, win_rect.left + (_winSize.Width - _baseSize.Width) / 2), - max(0, win_rect.top + (_winSize.Height - _baseSize.Height) / 2), - _baseSize.Width, _baseSize.Height, TRUE); - SetFocus(GetDlgItem(_hwnd, IDOK)); - return FALSE; // notify WinAPI that we set focus ourselves +INT_PTR WinSetupDialog::OnInitDialog(HWND hwnd) { + _hwnd = hwnd; + _hVersionText = GetDlgItem(_hwnd, IDC_VERSION); + _hCustomSaveDir = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIR); + _hCustomSaveDirBtn = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIRBTN); + _hCustomSaveDirCheck = GetDlgItem(_hwnd, IDC_CUSTOMSAVEDIRCHECK); + _hGfxDriverList = GetDlgItem(_hwnd, IDC_GFXDRIVER); + _hGfxModeList = GetDlgItem(_hwnd, IDC_GFXMODE); + _hGfxFilterList = GetDlgItem(_hwnd, IDC_GFXFILTER); + _hFsScalingList = GetDlgItem(_hwnd, IDC_FSSCALING); + _hWinScalingList = GetDlgItem(_hwnd, IDC_WINDOWSCALING); + _hDigiDriverList = GetDlgItem(_hwnd, IDC_DIGISOUND); + _hMidiDriverList = GetDlgItem(_hwnd, IDC_MIDIMUSIC); + _hLanguageList = GetDlgItem(_hwnd, IDC_LANGUAGE); + _hSpriteCacheList = GetDlgItem(_hwnd, IDC_SPRITECACHE); + _hWindowed = GetDlgItem(_hwnd, IDC_WINDOWED); + _hVSync = GetDlgItem(_hwnd, IDC_VSYNC); + _hRenderAtScreenRes = GetDlgItem(_hwnd, IDC_RENDERATSCREENRES); + _hRefresh85Hz = GetDlgItem(_hwnd, IDC_REFRESH_85HZ); + _hAntialiasSprites = GetDlgItem(_hwnd, IDC_ANTIALIAS); + _hThreadedAudio = GetDlgItem(_hwnd, IDC_THREADEDAUDIO); + _hUseVoicePack = GetDlgItem(_hwnd, IDC_VOICEPACK); + _hAdvanced = GetDlgItem(_hwnd, IDC_ADVANCED); + _hGameResolutionText = GetDlgItem(_hwnd, IDC_RESOLUTION); + _hGfxModeText = GetDlgItem(_hwnd, IDC_GFXMODETEXT); + _hMouseLock = GetDlgItem(_hwnd, IDC_MOUSE_AUTOLOCK); + _hMouseSpeed = GetDlgItem(_hwnd, IDC_MOUSESPEED); + _hMouseSpeedText = GetDlgItem(_hwnd, IDC_MOUSESPEED_TEXT); + + _desktopSize = get_desktop_size(); + _maxWindowSize = _desktopSize; + AGSPlatformDriver::GetDriver()->ValidateWindowSize(_maxWindowSize.Width, _maxWindowSize.Height, false); + _minGameSize = Size(320, 200); + _maxGameScale = 1; + _minGameScale = 1; + + _winCfg.Load(_cfgIn); + + // Custom save dir controls + String custom_save_dir = _winCfg.UserSaveDir; + bool has_save_dir = !custom_save_dir.IsEmpty(); + if (!has_save_dir) + custom_save_dir = _winCfg.DataDirectory; + SetCheck(_hCustomSaveDirCheck, has_save_dir); + char full_save_dir[MAX_PATH] = {0}; + MakeFullLongPath(custom_save_dir, full_save_dir, MAX_PATH); + SetText(_hCustomSaveDir, full_save_dir); + EnableWindow(_hCustomSaveDir, has_save_dir ? TRUE : FALSE); + EnableWindow(_hCustomSaveDirBtn, has_save_dir ? TRUE : FALSE); + + // Resolution controls + if (_winCfg.GameResolution.IsNull() && + (_winCfg.GameResType == kGameResolution_Undefined || _winCfg.GameResType == kGameResolution_Custom) || + _winCfg.GameColourDepth == 0) + MessageBox(_hwnd, "Essential information about the game is missing in the configuration file. Setup program may be unable to deduce graphic modes properly.", "Initialization error", MB_OK | MB_ICONWARNING); + + if (_winCfg.GameResolution.IsNull()) + _winCfg.GameResolution = ResolutionTypeToSize(_winCfg.GameResType, _winCfg.LetterboxByDesign); + + SetText(_hwnd, _winCfg.Title); + SetText(win_get_window(), _winCfg.Title); + SetText(_hGameResolutionText, String::FromFormat("Native game resolution: %d x %d x %d", + _winCfg.GameResolution.Width, _winCfg.GameResolution.Height, _winCfg.GameColourDepth)); + + SetText(_hVersionText, _winCfg.VersionString); + + InitGfxModes(); + + for (DriverDescMap::const_iterator it = _drvDescMap.begin(); it != _drvDescMap.end(); ++it) + AddString(_hGfxDriverList, it->second->UserName, (DWORD_PTR)it->second->Id.GetCStr()); + SetCurSelToItemDataStr(_hGfxDriverList, _winCfg.GfxDriverId.GetCStr(), 0); + OnGfxDriverUpdate(); + + SetCheck(_hWindowed, _winCfg.Windowed); + OnWindowedUpdate(); + + FillScalingList(_hFsScalingList, _winCfg.FsGameFrame, false); + FillScalingList(_hWinScalingList, _winCfg.WinGameFrame, true); + + SetCheck(_hVSync, _winCfg.VSync); + + SetCheck(_hRenderAtScreenRes, _winCfg.RenderAtScreenRes); + + AddString(_hDigiDriverList, "No Digital Sound", DIGI_NONE); + AddString(_hDigiDriverList, "Default device (auto)", MIDI_AUTODETECT); + AddString(_hDigiDriverList, "Default DirectSound Device", DIGI_DIRECTAMX(0)); + AddString(_hDigiDriverList, "Default WaveOut Device", DIGI_WAVOUTID(0)); + AddString(_hDigiDriverList, "DirectSound (Hardware mixer)", DIGI_DIRECTX(0)); + SetCurSelToItemData(_hDigiDriverList, _winCfg.DigiID); + + AddString(_hMidiDriverList, "No MIDI music", MIDI_NONE); + AddString(_hMidiDriverList, "Default device (auto)", MIDI_AUTODETECT); + AddString(_hMidiDriverList, "Win32 MIDI Mapper", MIDI_WIN32MAPPER); + SetCurSelToItemData(_hMidiDriverList, _winCfg.MidiID); + + FillLanguageList(); + + SetCheck(_hMouseLock, _winCfg.MouseAutoLock); + + SetSliderRange(_hMouseSpeed, MouseSpeedMin, MouseSpeedMax); + int slider_pos = (int)(_winCfg.MouseSpeed * 10.f + .5f); + SetSliderPos(_hMouseSpeed, slider_pos); + UpdateMouseSpeedText(); + + AddString(_hSpriteCacheList, "16 MB", 16); + AddString(_hSpriteCacheList, "32 MB", 32); + AddString(_hSpriteCacheList, "64 MB", 64); + AddString(_hSpriteCacheList, "128 MB (default)", 128); + AddString(_hSpriteCacheList, "256 MB", 256); + AddString(_hSpriteCacheList, "384 MB", 384); + AddString(_hSpriteCacheList, "512 MB", 512); + SetCurSelToItemData(_hSpriteCacheList, _winCfg.SpriteCacheSize / 1024, NULL, 3); + + SetCheck(_hRefresh85Hz, _winCfg.RefreshRate == 85); + SetCheck(_hAntialiasSprites, _winCfg.AntialiasSprites); + SetCheck(_hThreadedAudio, _winCfg.ThreadedAudio); + SetCheck(_hUseVoicePack, _winCfg.UseVoicePack); + if (!File::TestReadFile("speech.vox")) + EnableWindow(_hUseVoicePack, FALSE); + + if (INIreadint(_cfgIn, "disabled", "threaded_audio", 0) != 0) + EnableWindow(_hThreadedAudio, FALSE); + if (INIreadint(_cfgIn, "disabled", "speechvox", 0) != 0) + EnableWindow(_hUseVoicePack, FALSE); + if (INIreadint(_cfgIn, "disabled", "filters", 0) != 0) + EnableWindow(_hGfxFilterList, FALSE); + if (INIreadint(_cfgIn, "disabled", "render_at_screenres", 0) != 0) + EnableWindow(_hRenderAtScreenRes, FALSE); + + RECT win_rect, gfx_rect, adv_rect, border; + GetWindowRect(_hwnd, &win_rect); + GetWindowRect(GetDlgItem(_hwnd, IDC_GFXOPTIONS), &gfx_rect); + _winSize.Width = win_rect.right - win_rect.left; + _winSize.Height = win_rect.bottom - win_rect.top; + GetWindowRect(_hAdvanced, &adv_rect); + border.left = border.top = border.right = border.bottom = 9; + MapDialogRect(_hwnd, &border); + _baseSize.Width = (adv_rect.right + (gfx_rect.left - win_rect.left)) - win_rect.left; + _baseSize.Height = adv_rect.bottom - win_rect.top + border.bottom; + + MoveWindow(_hwnd, max(0, win_rect.left + (_winSize.Width - _baseSize.Width) / 2), + max(0, win_rect.top + (_winSize.Height - _baseSize.Height) / 2), + _baseSize.Width, _baseSize.Height, TRUE); + SetFocus(GetDlgItem(_hwnd, IDOK)); + return FALSE; // notify WinAPI that we set focus ourselves } -INT_PTR WinSetupDialog::OnCommand(WORD id) -{ - switch (id) - { - case IDC_ADVANCED: ShowAdvancedOptions(); break; - case IDC_WINDOWED: OnWindowedUpdate(); break; - case IDC_CUSTOMSAVEDIRBTN: OnCustomSaveDirBtn(); break; - case IDC_CUSTOMSAVEDIRCHECK: OnCustomSaveDirCheck(); break; - case IDOK: - case IDOKRUN: - SaveSetup(); - // fall-through intended - case IDCANCEL: - EndDialog(_hwnd, id); - return TRUE; - default: - return FALSE; - } - return TRUE; +INT_PTR WinSetupDialog::OnCommand(WORD id) { + switch (id) { + case IDC_ADVANCED: + ShowAdvancedOptions(); + break; + case IDC_WINDOWED: + OnWindowedUpdate(); + break; + case IDC_CUSTOMSAVEDIRBTN: + OnCustomSaveDirBtn(); + break; + case IDC_CUSTOMSAVEDIRCHECK: + OnCustomSaveDirCheck(); + break; + case IDOK: + case IDOKRUN: + SaveSetup(); + // fall-through intended + case IDCANCEL: + EndDialog(_hwnd, id); + return TRUE; + default: + return FALSE; + } + return TRUE; } -INT_PTR WinSetupDialog::OnListSelection(WORD id) -{ - switch (id) - { - case IDC_GFXDRIVER: OnGfxDriverUpdate(); break; - case IDC_GFXFILTER: OnGfxFilterUpdate(); break; - case IDC_GFXMODE: OnGfxModeUpdate(); break; - case IDC_FSSCALING: OnScalingUpdate(_hFsScalingList, _winCfg.FsGameFrame, false); break; - case IDC_WINDOWSCALING: OnScalingUpdate(_hWinScalingList, _winCfg.WinGameFrame, true); break; - default: - return FALSE; - } - return TRUE; +INT_PTR WinSetupDialog::OnListSelection(WORD id) { + switch (id) { + case IDC_GFXDRIVER: + OnGfxDriverUpdate(); + break; + case IDC_GFXFILTER: + OnGfxFilterUpdate(); + break; + case IDC_GFXMODE: + OnGfxModeUpdate(); + break; + case IDC_FSSCALING: + OnScalingUpdate(_hFsScalingList, _winCfg.FsGameFrame, false); + break; + case IDC_WINDOWSCALING: + OnScalingUpdate(_hWinScalingList, _winCfg.WinGameFrame, true); + break; + default: + return FALSE; + } + return TRUE; } -void WinSetupDialog::OnCustomSaveDirBtn() -{ - String save_dir = GetText(_hCustomSaveDir); - if (BrowseForFolder(save_dir)) - { - SetText(_hCustomSaveDir, save_dir); - } +void WinSetupDialog::OnCustomSaveDirBtn() { + String save_dir = GetText(_hCustomSaveDir); + if (BrowseForFolder(save_dir)) { + SetText(_hCustomSaveDir, save_dir); + } } -void WinSetupDialog::OnCustomSaveDirCheck() -{ - bool custom_save_dir = GetCheck(_hCustomSaveDirCheck); - EnableWindow(_hCustomSaveDir, custom_save_dir ? TRUE : FALSE); - EnableWindow(_hCustomSaveDirBtn, custom_save_dir ? TRUE : FALSE); +void WinSetupDialog::OnCustomSaveDirCheck() { + bool custom_save_dir = GetCheck(_hCustomSaveDirCheck); + EnableWindow(_hCustomSaveDir, custom_save_dir ? TRUE : FALSE); + EnableWindow(_hCustomSaveDirBtn, custom_save_dir ? TRUE : FALSE); } -void WinSetupDialog::OnGfxDriverUpdate() -{ - _winCfg.GfxDriverId = (LPCTSTR)GetCurItemData(_hGfxDriverList); +void WinSetupDialog::OnGfxDriverUpdate() { + _winCfg.GfxDriverId = (LPCTSTR)GetCurItemData(_hGfxDriverList); - DriverDescMap::const_iterator it = _drvDescMap.find(_winCfg.GfxDriverId); - if (it != _drvDescMap.end()) - _drvDesc = it->second; - else - _drvDesc.reset(); + DriverDescMap::const_iterator it = _drvDescMap.find(_winCfg.GfxDriverId); + if (it != _drvDescMap.end()) + _drvDesc = it->second; + else + _drvDesc.reset(); - FillGfxModeList(); - FillGfxFilterList(); + FillGfxModeList(); + FillGfxFilterList(); } -void WinSetupDialog::OnGfxFilterUpdate() -{ - _winCfg.GfxFilterId = (LPCTSTR)GetCurItemData(_hGfxFilterList); - - _gfxFilterInfo = GfxFilterInfo(); - for (size_t i = 0; i < _drvDesc->FilterList.size(); ++i) - { - if (_drvDesc->FilterList[i].Id.CompareNoCase(_winCfg.GfxFilterId) == 0) - { - _gfxFilterInfo = _drvDesc->FilterList[i]; - break; - } - } +void WinSetupDialog::OnGfxFilterUpdate() { + _winCfg.GfxFilterId = (LPCTSTR)GetCurItemData(_hGfxFilterList); + + _gfxFilterInfo = GfxFilterInfo(); + for (size_t i = 0; i < _drvDesc->FilterList.size(); ++i) { + if (_drvDesc->FilterList[i].Id.CompareNoCase(_winCfg.GfxFilterId) == 0) { + _gfxFilterInfo = _drvDesc->FilterList[i]; + break; + } + } } -void WinSetupDialog::OnGfxModeUpdate() -{ - DWORD_PTR sel = GetCurItemData(_hGfxModeList); - if (sel == kGfxMode_Desktop) - _winCfg.ScreenSize = _desktopSize; - else if (sel == kGfxMode_GameRes) - _winCfg.ScreenSize = _winCfg.GameResolution; - else - { - const DisplayMode &mode = _drvDesc->GfxModeList.Modes[sel]; - _winCfg.ScreenSize = Size(mode.Width, mode.Height); - } +void WinSetupDialog::OnGfxModeUpdate() { + DWORD_PTR sel = GetCurItemData(_hGfxModeList); + if (sel == kGfxMode_Desktop) + _winCfg.ScreenSize = _desktopSize; + else if (sel == kGfxMode_GameRes) + _winCfg.ScreenSize = _winCfg.GameResolution; + else { + const DisplayMode &mode = _drvDesc->GfxModeList.Modes[sel]; + _winCfg.ScreenSize = Size(mode.Width, mode.Height); + } } -void WinSetupDialog::OnScalingUpdate(HWND hlist, GameFrameSetup &frame_setup, bool windowed) -{ - int scale = GetCurItemData(hlist); - if (scale >= 0 && scale < kNumFrameScaleDef) - { - frame_setup.ScaleDef = (FrameScaleDefinition)scale; - frame_setup.ScaleFactor = 0; - } - else - { - frame_setup.ScaleDef = kFrame_IntScale; - frame_setup.ScaleFactor = scale >= 0 ? scale - kNumFrameScaleDef : scale; - } - - if (windowed) - SetGfxModeText(); +void WinSetupDialog::OnScalingUpdate(HWND hlist, GameFrameSetup &frame_setup, bool windowed) { + int scale = GetCurItemData(hlist); + if (scale >= 0 && scale < kNumFrameScaleDef) { + frame_setup.ScaleDef = (FrameScaleDefinition)scale; + frame_setup.ScaleFactor = 0; + } else { + frame_setup.ScaleDef = kFrame_IntScale; + frame_setup.ScaleFactor = scale >= 0 ? scale - kNumFrameScaleDef : scale; + } + + if (windowed) + SetGfxModeText(); } -void WinSetupDialog::OnWindowedUpdate() -{ - _winCfg.Windowed = GetCheck(_hWindowed); - - if (_winCfg.Windowed) - { - ShowWindow(_hGfxModeList, SW_HIDE); - ShowWindow(_hGfxModeText, SW_SHOW); - SetGfxModeText(); - } - else - { - ShowWindow(_hGfxModeList, SW_SHOW); - ShowWindow(_hGfxModeText, SW_HIDE); - } - - SelectNearestGfxMode(_winCfg.ScreenSize); +void WinSetupDialog::OnWindowedUpdate() { + _winCfg.Windowed = GetCheck(_hWindowed); + + if (_winCfg.Windowed) { + ShowWindow(_hGfxModeList, SW_HIDE); + ShowWindow(_hGfxModeText, SW_SHOW); + SetGfxModeText(); + } else { + ShowWindow(_hGfxModeList, SW_SHOW); + ShowWindow(_hGfxModeText, SW_HIDE); + } + + SelectNearestGfxMode(_winCfg.ScreenSize); } -void WinSetupDialog::ShowAdvancedOptions() -{ - // Reveal the advanced bit of the window - ShowWindow(_hAdvanced, SW_HIDE); - - RECT win_rect; - GetWindowRect(_hwnd, &win_rect); - MoveWindow(_hwnd, max(0, win_rect.left + (_baseSize.Width - _winSize.Width) / 2), - max(0, win_rect.top + (_baseSize.Height - _winSize.Height) / 2), - _winSize.Width, _winSize.Height, TRUE); - - int offset = _winSize.Height - _baseSize.Height; - RECT rc; - int ctrl_ids[] = { IDC_VERSION, IDOK, IDOKRUN, IDCANCEL, 0 }; - for (int i = 0; ctrl_ids[i]; ++i) - { - HWND hctrl = GetDlgItem(_hwnd, ctrl_ids[i]); - GetWindowRect(hctrl, &rc); - ScreenToClient(_hwnd, (POINT*)&rc); - ScreenToClient(_hwnd, (POINT*)&rc.right); - MoveWindow(hctrl, rc.left, rc.top + offset, rc.right - rc.left, rc.bottom - rc.top, TRUE); - } +void WinSetupDialog::ShowAdvancedOptions() { + // Reveal the advanced bit of the window + ShowWindow(_hAdvanced, SW_HIDE); + + RECT win_rect; + GetWindowRect(_hwnd, &win_rect); + MoveWindow(_hwnd, max(0, win_rect.left + (_baseSize.Width - _winSize.Width) / 2), + max(0, win_rect.top + (_baseSize.Height - _winSize.Height) / 2), + _winSize.Width, _winSize.Height, TRUE); + + int offset = _winSize.Height - _baseSize.Height; + RECT rc; + int ctrl_ids[] = { IDC_VERSION, IDOK, IDOKRUN, IDCANCEL, 0 }; + for (int i = 0; ctrl_ids[i]; ++i) { + HWND hctrl = GetDlgItem(_hwnd, ctrl_ids[i]); + GetWindowRect(hctrl, &rc); + ScreenToClient(_hwnd, (POINT *)&rc); + ScreenToClient(_hwnd, (POINT *)&rc.right); + MoveWindow(hctrl, rc.left, rc.top + offset, rc.right - rc.left, rc.bottom - rc.top, TRUE); + } } -INT_PTR CALLBACK WinSetupDialog::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_INITDIALOG: - _ASSERT(_dlg != NULL && _dlg->_hwnd == NULL); - return _dlg->OnInitDialog(hwndDlg); - case WM_COMMAND: - _ASSERT(_dlg != NULL && _dlg->_hwnd != NULL); - if (HIWORD(wParam) == CBN_SELCHANGE) - return _dlg->OnListSelection(LOWORD(wParam)); - return _dlg->OnCommand(LOWORD(wParam)); - case WM_HSCROLL: - _ASSERT(_dlg != NULL && _dlg->_hwnd != NULL); - _dlg->UpdateMouseSpeedText(); - return TRUE; - default: - return FALSE; - } +INT_PTR CALLBACK WinSetupDialog::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) { + case WM_INITDIALOG: + _ASSERT(_dlg != NULL && _dlg->_hwnd == NULL); + return _dlg->OnInitDialog(hwndDlg); + case WM_COMMAND: + _ASSERT(_dlg != NULL && _dlg->_hwnd != NULL); + if (HIWORD(wParam) == CBN_SELCHANGE) + return _dlg->OnListSelection(LOWORD(wParam)); + return _dlg->OnCommand(LOWORD(wParam)); + case WM_HSCROLL: + _ASSERT(_dlg != NULL && _dlg->_hwnd != NULL); + _dlg->UpdateMouseSpeedText(); + return TRUE; + default: + return FALSE; + } } -int WinSetupDialog::GfxModes::GetModeCount() const -{ - return Modes.size(); +int WinSetupDialog::GfxModes::GetModeCount() const { + return Modes.size(); } -bool WinSetupDialog::GfxModes::GetMode(int index, DisplayMode &mode) const -{ - if (index >= 0 && (size_t)index < Modes.size()) - { - mode = Modes[index]; - return true; - } - return false; +bool WinSetupDialog::GfxModes::GetMode(int index, DisplayMode &mode) const { + if (index >= 0 && (size_t)index < Modes.size()) { + mode = Modes[index]; + return true; + } + return false; } -void WinSetupDialog::AddScalingString(HWND hlist, int scaling_factor) -{ - String s; - if (scaling_factor >= 0) - s = String::FromFormat("x%d", scaling_factor); - else - s = String::FromFormat("1/%d", -scaling_factor); - AddString(hlist, s, (DWORD_PTR)(scaling_factor >= 0 ? scaling_factor + kNumFrameScaleDef : scaling_factor)); +void WinSetupDialog::AddScalingString(HWND hlist, int scaling_factor) { + String s; + if (scaling_factor >= 0) + s = String::FromFormat("x%d", scaling_factor); + else + s = String::FromFormat("1/%d", -scaling_factor); + AddString(hlist, s, (DWORD_PTR)(scaling_factor >= 0 ? scaling_factor + kNumFrameScaleDef : scaling_factor)); } -void WinSetupDialog::FillGfxFilterList() -{ - ResetContent(_hGfxFilterList); - - if (!_drvDesc) - { - _gfxFilterInfo = GfxFilterInfo(); - return; - } - - for (size_t i = 0; i < _drvDesc->FilterList.size(); ++i) - { - const GfxFilterInfo &info = _drvDesc->FilterList[i]; - if (INIreadint(_cfgIn, "disabled", info.Id, 0) == 0) - AddString(_hGfxFilterList, info.Name, (DWORD_PTR)info.Id.GetCStr()); - } - - SetCurSelToItemDataStr(_hGfxFilterList, _winCfg.GfxFilterId, 0); - OnGfxFilterUpdate(); +void WinSetupDialog::FillGfxFilterList() { + ResetContent(_hGfxFilterList); + + if (!_drvDesc) { + _gfxFilterInfo = GfxFilterInfo(); + return; + } + + for (size_t i = 0; i < _drvDesc->FilterList.size(); ++i) { + const GfxFilterInfo &info = _drvDesc->FilterList[i]; + if (INIreadint(_cfgIn, "disabled", info.Id, 0) == 0) + AddString(_hGfxFilterList, info.Name, (DWORD_PTR)info.Id.GetCStr()); + } + + SetCurSelToItemDataStr(_hGfxFilterList, _winCfg.GfxFilterId, 0); + OnGfxFilterUpdate(); } -void WinSetupDialog::FillGfxModeList() -{ - ResetContent(_hGfxModeList); - - if (!_drvDesc) - { - OnGfxModeUpdate(); - return; - } - - const VDispModes &modes = _drvDesc->GfxModeList.Modes; - bool has_desktop_mode = false; - bool has_native_mode = false; - String buf; - for (VDispModes::const_iterator mode = modes.begin(); mode != modes.end(); ++mode) - { - if (mode->Width == _desktopSize.Width && mode->Height == _desktopSize.Height) - { - has_desktop_mode = true; - continue; - } - else if (mode->Width == _winCfg.GameResolution.Width && mode->Height == _winCfg.GameResolution.Height) - { - has_native_mode = true; - continue; - } - buf.Format("%d x %d", mode->Width, mode->Height); - AddString(_hGfxModeList, buf, (DWORD_PTR)(mode - modes.begin())); - } - - int spec_mode_idx = 0; - if (has_desktop_mode) - InsertString(_hGfxModeList, String::FromFormat("Desktop resolution (%d x %d)", - _desktopSize.Width, _desktopSize.Height), spec_mode_idx++, (DWORD_PTR)kGfxMode_Desktop); - if (has_native_mode) - InsertString(_hGfxModeList, String::FromFormat("Native game resolution (%d x %d)", - _winCfg.GameResolution.Width, _winCfg.GameResolution.Height), spec_mode_idx++, (DWORD_PTR)kGfxMode_GameRes); - - SelectNearestGfxMode(_winCfg.ScreenSize); +void WinSetupDialog::FillGfxModeList() { + ResetContent(_hGfxModeList); + + if (!_drvDesc) { + OnGfxModeUpdate(); + return; + } + + const VDispModes &modes = _drvDesc->GfxModeList.Modes; + bool has_desktop_mode = false; + bool has_native_mode = false; + String buf; + for (VDispModes::const_iterator mode = modes.begin(); mode != modes.end(); ++mode) { + if (mode->Width == _desktopSize.Width && mode->Height == _desktopSize.Height) { + has_desktop_mode = true; + continue; + } else if (mode->Width == _winCfg.GameResolution.Width && mode->Height == _winCfg.GameResolution.Height) { + has_native_mode = true; + continue; + } + buf.Format("%d x %d", mode->Width, mode->Height); + AddString(_hGfxModeList, buf, (DWORD_PTR)(mode - modes.begin())); + } + + int spec_mode_idx = 0; + if (has_desktop_mode) + InsertString(_hGfxModeList, String::FromFormat("Desktop resolution (%d x %d)", + _desktopSize.Width, _desktopSize.Height), spec_mode_idx++, (DWORD_PTR)kGfxMode_Desktop); + if (has_native_mode) + InsertString(_hGfxModeList, String::FromFormat("Native game resolution (%d x %d)", + _winCfg.GameResolution.Width, _winCfg.GameResolution.Height), spec_mode_idx++, (DWORD_PTR)kGfxMode_GameRes); + + SelectNearestGfxMode(_winCfg.ScreenSize); } -void WinSetupDialog::FillLanguageList() -{ - ResetContent(_hLanguageList); - AddString(_hLanguageList, _winCfg.DefaultLanguageName.GetCStr()); - SetCurSel(_hLanguageList, 0); - - String path_mask = String::FromFormat("%s\\*.tra", _winCfg.DataDirectory.GetCStr()); - WIN32_FIND_DATAA file_data; - HANDLE find_handle = FindFirstFile(path_mask, &file_data); - if (find_handle != INVALID_HANDLE_VALUE) - { - bool found_sel = false; - do - { - LPTSTR ext = PathFindExtension(file_data.cFileName); - if (ext && StrCmpI(ext, ".tra") == 0) - { - file_data.cFileName[0] = toupper(file_data.cFileName[0]); - *ext = 0; - int index = AddString(_hLanguageList, file_data.cFileName); - if (!found_sel && _winCfg.Language.CompareNoCase(file_data.cFileName) == 0) - { - SetCurSel(_hLanguageList, index); - found_sel = true; - } - } - } - while (FindNextFileA(find_handle, &file_data) != FALSE); - FindClose(find_handle); - } +void WinSetupDialog::FillLanguageList() { + ResetContent(_hLanguageList); + AddString(_hLanguageList, _winCfg.DefaultLanguageName.GetCStr()); + SetCurSel(_hLanguageList, 0); + + String path_mask = String::FromFormat("%s\\*.tra", _winCfg.DataDirectory.GetCStr()); + WIN32_FIND_DATAA file_data; + HANDLE find_handle = FindFirstFile(path_mask, &file_data); + if (find_handle != INVALID_HANDLE_VALUE) { + bool found_sel = false; + do { + LPTSTR ext = PathFindExtension(file_data.cFileName); + if (ext && StrCmpI(ext, ".tra") == 0) { + file_data.cFileName[0] = toupper(file_data.cFileName[0]); + *ext = 0; + int index = AddString(_hLanguageList, file_data.cFileName); + if (!found_sel && _winCfg.Language.CompareNoCase(file_data.cFileName) == 0) { + SetCurSel(_hLanguageList, index); + found_sel = true; + } + } + } while (FindNextFileA(find_handle, &file_data) != FALSE); + FindClose(find_handle); + } } -void WinSetupDialog::FillScalingList(HWND hlist, GameFrameSetup &frame_setup, bool windowed) -{ - ResetContent(hlist); - - const int min_scale = min(_winCfg.GameResolution.Width / _minGameSize.Width, _winCfg.GameResolution.Height / _minGameSize.Height); - const Size max_size = windowed ? _maxWindowSize : _winCfg.ScreenSize; - const int max_scale = _winCfg.GameResolution.IsNull() ? 1 : - min(max_size.Width / _winCfg.GameResolution.Width, max_size.Height / _winCfg.GameResolution.Height); - _maxGameScale = max(1, max_scale); - _minGameScale = -max(1, min_scale); - - if (windowed) - AddString(hlist, "None (original game size)", 1 + kNumFrameScaleDef); - - AddString(hlist, "Max round multiplier", kFrame_MaxRound); - AddString(hlist, "Fill whole screen", kFrame_MaxStretch); - AddString(hlist, "Stretch, preserving aspect ratio", kFrame_MaxProportional); - - if (windowed && !_winCfg.GameResolution.IsNull()) - { - // Add integer multipliers - for (int scale = 2; scale <= _maxGameScale; ++scale) - AddScalingString(hlist, scale); - } - - SetCurSelToItemData(hlist, - frame_setup.ScaleDef == kFrame_IntScale ? frame_setup.ScaleFactor + kNumFrameScaleDef : frame_setup.ScaleDef, NULL, 0); - - EnableWindow(hlist, SendMessage(hlist, CB_GETCOUNT, 0, 0) > 1 ? TRUE : FALSE); - OnScalingUpdate(hlist, frame_setup, windowed); +void WinSetupDialog::FillScalingList(HWND hlist, GameFrameSetup &frame_setup, bool windowed) { + ResetContent(hlist); + + const int min_scale = min(_winCfg.GameResolution.Width / _minGameSize.Width, _winCfg.GameResolution.Height / _minGameSize.Height); + const Size max_size = windowed ? _maxWindowSize : _winCfg.ScreenSize; + const int max_scale = _winCfg.GameResolution.IsNull() ? 1 : + min(max_size.Width / _winCfg.GameResolution.Width, max_size.Height / _winCfg.GameResolution.Height); + _maxGameScale = max(1, max_scale); + _minGameScale = -max(1, min_scale); + + if (windowed) + AddString(hlist, "None (original game size)", 1 + kNumFrameScaleDef); + + AddString(hlist, "Max round multiplier", kFrame_MaxRound); + AddString(hlist, "Fill whole screen", kFrame_MaxStretch); + AddString(hlist, "Stretch, preserving aspect ratio", kFrame_MaxProportional); + + if (windowed && !_winCfg.GameResolution.IsNull()) { + // Add integer multipliers + for (int scale = 2; scale <= _maxGameScale; ++scale) + AddScalingString(hlist, scale); + } + + SetCurSelToItemData(hlist, + frame_setup.ScaleDef == kFrame_IntScale ? frame_setup.ScaleFactor + kNumFrameScaleDef : frame_setup.ScaleDef, NULL, 0); + + EnableWindow(hlist, SendMessage(hlist, CB_GETCOUNT, 0, 0) > 1 ? TRUE : FALSE); + OnScalingUpdate(hlist, frame_setup, windowed); } -void WinSetupDialog::InitGfxModes() -{ - InitDriverDescFromFactory("D3D9"); - InitDriverDescFromFactory("OGL"); - InitDriverDescFromFactory("Software"); +void WinSetupDialog::InitGfxModes() { + InitDriverDescFromFactory("D3D9"); + InitDriverDescFromFactory("OGL"); + InitDriverDescFromFactory("Software"); - if (_drvDescMap.size() == 0) - MessageBox(_hwnd, "Unable to detect any supported graphic drivers!", "Initialization error", MB_OK | MB_ICONERROR); + if (_drvDescMap.size() == 0) + MessageBox(_hwnd, "Unable to detect any supported graphic drivers!", "Initialization error", MB_OK | MB_ICONERROR); } // "Less" predicate that compares two display modes only by their screen metrics -bool SizeLess(const DisplayMode &first, const DisplayMode &second) -{ - return Size(first.Width, first.Height) < Size(second.Width, second.Height); +bool SizeLess(const DisplayMode &first, const DisplayMode &second) { + return Size(first.Width, first.Height) < Size(second.Width, second.Height); } -void WinSetupDialog::InitDriverDescFromFactory(const String &id) -{ - IGfxDriverFactory *gfx_factory = GetGfxDriverFactory(id); - if (!gfx_factory) - return; - IGraphicsDriver *gfx_driver = gfx_factory->GetDriver(); - if (!gfx_driver) - { - gfx_factory->Shutdown(); - return; - } - - PDriverDesc drv_desc(new DriverDesc()); - drv_desc->Id = gfx_driver->GetDriverID(); - drv_desc->UserName = gfx_driver->GetDriverName(); - drv_desc->UseColorDepth = - gfx_driver->GetDisplayDepthForNativeDepth(_winCfg.GameColourDepth ? _winCfg.GameColourDepth : 32); - - IGfxModeList *gfxm_list = gfx_driver->GetSupportedModeList(drv_desc->UseColorDepth); - VDispModes &modes = drv_desc->GfxModeList.Modes; - if (gfxm_list) - { - std::set unique_sizes; // trying to hide modes which only have different refresh rates - for (int i = 0; i < gfxm_list->GetModeCount(); ++i) - { - DisplayMode mode; - gfxm_list->GetMode(i, mode); - if (mode.ColorDepth != drv_desc->UseColorDepth || unique_sizes.count(Size(mode.Width, mode.Height)) != 0) - continue; - unique_sizes.insert(Size(mode.Width, mode.Height)); - modes.push_back(mode); - } - std::sort(modes.begin(), modes.end(), SizeLess); - delete gfxm_list; - } - if (modes.size() == 0) - { - // Add two default modes in hope that engine will be able to handle them (or fallbacks to something else) - modes.push_back(DisplayMode(GraphicResolution(_desktopSize.Width, _desktopSize.Height, drv_desc->UseColorDepth))); - modes.push_back(DisplayMode(GraphicResolution(_winCfg.GameResolution.Width, _winCfg.GameResolution.Height, drv_desc->UseColorDepth))); - } - - drv_desc->FilterList.resize(gfx_factory->GetFilterCount()); - for (size_t i = 0; i < drv_desc->FilterList.size(); ++i) - { - drv_desc->FilterList[i] = *gfx_factory->GetFilterInfo(i); - } - - gfx_factory->Shutdown(); - _drvDescMap[drv_desc->Id] = drv_desc; +void WinSetupDialog::InitDriverDescFromFactory(const String &id) { + IGfxDriverFactory *gfx_factory = GetGfxDriverFactory(id); + if (!gfx_factory) + return; + IGraphicsDriver *gfx_driver = gfx_factory->GetDriver(); + if (!gfx_driver) { + gfx_factory->Shutdown(); + return; + } + + PDriverDesc drv_desc(new DriverDesc()); + drv_desc->Id = gfx_driver->GetDriverID(); + drv_desc->UserName = gfx_driver->GetDriverName(); + drv_desc->UseColorDepth = + gfx_driver->GetDisplayDepthForNativeDepth(_winCfg.GameColourDepth ? _winCfg.GameColourDepth : 32); + + IGfxModeList *gfxm_list = gfx_driver->GetSupportedModeList(drv_desc->UseColorDepth); + VDispModes &modes = drv_desc->GfxModeList.Modes; + if (gfxm_list) { + std::set unique_sizes; // trying to hide modes which only have different refresh rates + for (int i = 0; i < gfxm_list->GetModeCount(); ++i) { + DisplayMode mode; + gfxm_list->GetMode(i, mode); + if (mode.ColorDepth != drv_desc->UseColorDepth || unique_sizes.count(Size(mode.Width, mode.Height)) != 0) + continue; + unique_sizes.insert(Size(mode.Width, mode.Height)); + modes.push_back(mode); + } + std::sort(modes.begin(), modes.end(), SizeLess); + delete gfxm_list; + } + if (modes.size() == 0) { + // Add two default modes in hope that engine will be able to handle them (or fallbacks to something else) + modes.push_back(DisplayMode(GraphicResolution(_desktopSize.Width, _desktopSize.Height, drv_desc->UseColorDepth))); + modes.push_back(DisplayMode(GraphicResolution(_winCfg.GameResolution.Width, _winCfg.GameResolution.Height, drv_desc->UseColorDepth))); + } + + drv_desc->FilterList.resize(gfx_factory->GetFilterCount()); + for (size_t i = 0; i < drv_desc->FilterList.size(); ++i) { + drv_desc->FilterList[i] = *gfx_factory->GetFilterInfo(i); + } + + gfx_factory->Shutdown(); + _drvDescMap[drv_desc->Id] = drv_desc; } -void WinSetupDialog::SaveSetup() -{ - const bool custom_save_dir = GetCheck(_hCustomSaveDirCheck); - if (custom_save_dir) - { - // Compare user path with the game data directory. If user chose - // path pointing inside game's directory, then store relative - // path instead; thus the path will keep pointing at game's - // directory if user moves game elsewhere. - String save_dir; - save_dir = GetText(_hCustomSaveDir); - char full_data_dir[MAX_PATH] = {0}; - char full_save_dir[MAX_PATH] = {0}; - MakeFullLongPath(_winCfg.DataDirectory, full_data_dir, MAX_PATH); - MakeFullLongPath(save_dir, full_save_dir, MAX_PATH); - char rel_save_dir[MAX_PATH] = {0}; - if (PathRelativePathTo(rel_save_dir, full_data_dir, FILE_ATTRIBUTE_DIRECTORY, full_save_dir, FILE_ATTRIBUTE_DIRECTORY) && - strstr(rel_save_dir, "..") == NULL) - { - _winCfg.UserSaveDir = rel_save_dir; - } - else - { - _winCfg.UserSaveDir = save_dir; - } - } - else - { - _winCfg.UserSaveDir = ""; - } - - _winCfg.DigiID = GetCurItemData(_hDigiDriverList); - _winCfg.MidiID = GetCurItemData(_hMidiDriverList); - - if (GetCurSel(_hLanguageList) == 0) - _winCfg.Language.Empty(); - else - _winCfg.Language = GetText(_hLanguageList); - _winCfg.SpriteCacheSize = GetCurItemData(_hSpriteCacheList) * 1024; - _winCfg.ThreadedAudio = GetCheck(_hThreadedAudio); - _winCfg.UseVoicePack = GetCheck(_hUseVoicePack); - _winCfg.VSync = GetCheck(_hVSync); - _winCfg.RenderAtScreenRes = GetCheck(_hRenderAtScreenRes); - _winCfg.AntialiasSprites = GetCheck(_hAntialiasSprites); - _winCfg.RefreshRate = GetCheck(_hRefresh85Hz) ? 85 : 0; - _winCfg.GfxFilterId = (LPCTSTR)GetCurItemData(_hGfxFilterList); - - _winCfg.MouseAutoLock = GetCheck(_hMouseLock); - int slider_pos = GetSliderPos(_hMouseSpeed); - _winCfg.MouseSpeed = (float)slider_pos / 10.f; - - _winCfg.Save(_cfgOut); +void WinSetupDialog::SaveSetup() { + const bool custom_save_dir = GetCheck(_hCustomSaveDirCheck); + if (custom_save_dir) { + // Compare user path with the game data directory. If user chose + // path pointing inside game's directory, then store relative + // path instead; thus the path will keep pointing at game's + // directory if user moves game elsewhere. + String save_dir; + save_dir = GetText(_hCustomSaveDir); + char full_data_dir[MAX_PATH] = {0}; + char full_save_dir[MAX_PATH] = {0}; + MakeFullLongPath(_winCfg.DataDirectory, full_data_dir, MAX_PATH); + MakeFullLongPath(save_dir, full_save_dir, MAX_PATH); + char rel_save_dir[MAX_PATH] = {0}; + if (PathRelativePathTo(rel_save_dir, full_data_dir, FILE_ATTRIBUTE_DIRECTORY, full_save_dir, FILE_ATTRIBUTE_DIRECTORY) && + strstr(rel_save_dir, "..") == NULL) { + _winCfg.UserSaveDir = rel_save_dir; + } else { + _winCfg.UserSaveDir = save_dir; + } + } else { + _winCfg.UserSaveDir = ""; + } + + _winCfg.DigiID = GetCurItemData(_hDigiDriverList); + _winCfg.MidiID = GetCurItemData(_hMidiDriverList); + + if (GetCurSel(_hLanguageList) == 0) + _winCfg.Language.Empty(); + else + _winCfg.Language = GetText(_hLanguageList); + _winCfg.SpriteCacheSize = GetCurItemData(_hSpriteCacheList) * 1024; + _winCfg.ThreadedAudio = GetCheck(_hThreadedAudio); + _winCfg.UseVoicePack = GetCheck(_hUseVoicePack); + _winCfg.VSync = GetCheck(_hVSync); + _winCfg.RenderAtScreenRes = GetCheck(_hRenderAtScreenRes); + _winCfg.AntialiasSprites = GetCheck(_hAntialiasSprites); + _winCfg.RefreshRate = GetCheck(_hRefresh85Hz) ? 85 : 0; + _winCfg.GfxFilterId = (LPCTSTR)GetCurItemData(_hGfxFilterList); + + _winCfg.MouseAutoLock = GetCheck(_hMouseLock); + int slider_pos = GetSliderPos(_hMouseSpeed); + _winCfg.MouseSpeed = (float)slider_pos / 10.f; + + _winCfg.Save(_cfgOut); } -void WinSetupDialog::SelectNearestGfxMode(const Size screen_size) -{ - if (!_drvDesc) - { - OnGfxModeUpdate(); - return; - } - - // First check two special modes - if (screen_size == _desktopSize) - { - SetCurSelToItemData(_hGfxModeList, kGfxMode_Desktop); - } - else if (screen_size == _winCfg.GameResolution) - { - SetCurSelToItemData(_hGfxModeList, kGfxMode_GameRes); - } - else - { - // Look up for the nearest supported mode - int index = -1; - DisplayMode dm; - if (find_nearest_supported_mode(_drvDesc->GfxModeList, screen_size, _drvDesc->UseColorDepth, - NULL, NULL, dm, &index)) - { - SetCurSelToItemData(_hGfxModeList, index, NULL, kGfxMode_Desktop); - } - else - SetCurSelToItemData(_hGfxModeList, kGfxMode_Desktop); - } - OnGfxModeUpdate(); +void WinSetupDialog::SelectNearestGfxMode(const Size screen_size) { + if (!_drvDesc) { + OnGfxModeUpdate(); + return; + } + + // First check two special modes + if (screen_size == _desktopSize) { + SetCurSelToItemData(_hGfxModeList, kGfxMode_Desktop); + } else if (screen_size == _winCfg.GameResolution) { + SetCurSelToItemData(_hGfxModeList, kGfxMode_GameRes); + } else { + // Look up for the nearest supported mode + int index = -1; + DisplayMode dm; + if (find_nearest_supported_mode(_drvDesc->GfxModeList, screen_size, _drvDesc->UseColorDepth, + NULL, NULL, dm, &index)) { + SetCurSelToItemData(_hGfxModeList, index, NULL, kGfxMode_Desktop); + } else + SetCurSelToItemData(_hGfxModeList, kGfxMode_Desktop); + } + OnGfxModeUpdate(); } -void WinSetupDialog::SetGfxModeText() -{ - Size sz; - const GameFrameSetup &frame_setup = _winCfg.WinGameFrame; - if (frame_setup.ScaleDef == kFrame_MaxStretch) - { - sz = _maxWindowSize; - } - else if (frame_setup.ScaleDef == kFrame_MaxProportional) - { - sz = ProportionalStretch(_maxWindowSize, _winCfg.GameResolution); - } - else - { - int scale = 0; - if (frame_setup.ScaleDef == kFrame_MaxRound) - scale = _maxGameScale; - else - scale = frame_setup.ScaleFactor; - - if (scale >= 0) - { - sz.Width = _winCfg.GameResolution.Width * scale; - sz.Height = _winCfg.GameResolution.Height * scale; - } - else - { - sz.Width = _winCfg.GameResolution.Width / (-scale); - sz.Height = _winCfg.GameResolution.Height / (-scale); - } - } - String text = String::FromFormat("%d x %d", sz.Width, sz.Height); - SetText(_hGfxModeText, text); +void WinSetupDialog::SetGfxModeText() { + Size sz; + const GameFrameSetup &frame_setup = _winCfg.WinGameFrame; + if (frame_setup.ScaleDef == kFrame_MaxStretch) { + sz = _maxWindowSize; + } else if (frame_setup.ScaleDef == kFrame_MaxProportional) { + sz = ProportionalStretch(_maxWindowSize, _winCfg.GameResolution); + } else { + int scale = 0; + if (frame_setup.ScaleDef == kFrame_MaxRound) + scale = _maxGameScale; + else + scale = frame_setup.ScaleFactor; + + if (scale >= 0) { + sz.Width = _winCfg.GameResolution.Width * scale; + sz.Height = _winCfg.GameResolution.Height * scale; + } else { + sz.Width = _winCfg.GameResolution.Width / (-scale); + sz.Height = _winCfg.GameResolution.Height / (-scale); + } + } + String text = String::FromFormat("%d x %d", sz.Width, sz.Height); + SetText(_hGfxModeText, text); } -void WinSetupDialog::UpdateMouseSpeedText() -{ - int slider_pos = GetSliderPos(_hMouseSpeed); - float mouse_speed = (float)slider_pos / 10.f; - String text = mouse_speed == 1.f ? "Mouse speed: x 1.0 (Default)" : String::FromFormat("Mouse speed: x %0.1f", mouse_speed); - SetText(_hMouseSpeedText, text); +void WinSetupDialog::UpdateMouseSpeedText() { + int slider_pos = GetSliderPos(_hMouseSpeed); + float mouse_speed = (float)slider_pos / 10.f; + String text = mouse_speed == 1.f ? "Mouse speed: x 1.0 (Default)" : String::FromFormat("Mouse speed: x %0.1f", mouse_speed); + SetText(_hMouseSpeedText, text); } //============================================================================= @@ -1245,16 +1144,14 @@ void WinSetupDialog::UpdateMouseSpeedText() // Windows setup entry point. // //============================================================================= -void SetWinIcon() -{ - SetClassLong(win_get_window(),GCL_HICON, - (LONG) LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON))); +void SetWinIcon() { + SetClassLong(win_get_window(), GCL_HICON, + (LONG) LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON))); } SetupReturnValue WinSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, - const String &game_data_dir, const String &version_str) -{ - return WinSetupDialog::ShowModal(cfg_in, cfg_out, game_data_dir, version_str); + const String &game_data_dir, const String &version_str) { + return WinSetupDialog::ShowModal(cfg_in, cfg_out, game_data_dir, version_str); } } // namespace Engine diff --git a/engines/ags/engine/platform/windows/setup/winsetup.h b/engines/ags/engine/platform/windows/setup/winsetup.h index 0b59f4b6631d..fb14fd789989 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.h +++ b/engines/ags/engine/platform/windows/setup/winsetup.h @@ -31,10 +31,8 @@ #include "util/ini_util.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { using namespace Common; diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index ad1a159a492c..e27e30aaa037 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -54,53 +54,46 @@ extern int CustomExceptionHandler(LPEXCEPTION_POINTERS exinfo); extern EXCEPTION_RECORD excinfo; extern int miniDumpResultCode; -static void DisplayException() -{ - String script_callstack = get_cur_script(5); - sprintf(printfworkingspace, "An exception 0x%X occurred in ACWIN.EXE at EIP = 0x%08X; program pointer is %+d, ACI version %s, gtags (%d,%d)\n\n" - "AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and post the details on the AGS Technical Forum.\n\n%s\n\n" - "Most versions of Windows allow you to press Ctrl+C now to copy this entire message to the clipboard for easy reporting.\n\n%s (code %d)", - excinfo.ExceptionCode, (intptr_t)excinfo.ExceptionAddress, our_eip, EngineVersion.LongString.GetCStr(), eip_guinum, eip_guiobj, script_callstack.GetCStr(), - (miniDumpResultCode == 0) ? "An error file CrashInfo.dmp has been created. You may be asked to upload this file when reporting this problem on the AGS Forums." : - "Unable to create an error dump file.", miniDumpResultCode); - MessageBoxA(win_get_window(), printfworkingspace, "Illegal exception", MB_ICONSTOP | MB_OK); +static void DisplayException() { + String script_callstack = get_cur_script(5); + sprintf(printfworkingspace, "An exception 0x%X occurred in ACWIN.EXE at EIP = 0x%08X; program pointer is %+d, ACI version %s, gtags (%d,%d)\n\n" + "AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and post the details on the AGS Technical Forum.\n\n%s\n\n" + "Most versions of Windows allow you to press Ctrl+C now to copy this entire message to the clipboard for easy reporting.\n\n%s (code %d)", + excinfo.ExceptionCode, (intptr_t)excinfo.ExceptionAddress, our_eip, EngineVersion.LongString.GetCStr(), eip_guinum, eip_guiobj, script_callstack.GetCStr(), + (miniDumpResultCode == 0) ? "An error file CrashInfo.dmp has been created. You may be asked to upload this file when reporting this problem on the AGS Forums." : + "Unable to create an error dump file.", miniDumpResultCode); + MessageBoxA(win_get_window(), printfworkingspace, "Illegal exception", MB_ICONSTOP | MB_OK); } int initialize_engine_with_exception_handling( int (initialize_engine)(const AGS::Common::ConfigTree &startup_opts), - const ConfigTree &startup_opts) -{ - __try - { - Debug::Printf(kDbgMsg_Info, "Installing exception handler"); - return initialize_engine(startup_opts); - } - __except (CustomExceptionHandler(GetExceptionInformation())) - { - DisplayException(); - proper_exit = 1; - } - return EXIT_CRASH; + const ConfigTree &startup_opts) { + __try { + Debug::Printf(kDbgMsg_Info, "Installing exception handler"); + return initialize_engine(startup_opts); + } __except (CustomExceptionHandler(GetExceptionInformation())) { + DisplayException(); + proper_exit = 1; + } + return EXIT_CRASH; } #endif // USE_CUSTOM_EXCEPTION_HANDLER -int malloc_fail_handler(size_t amountwanted) -{ +int malloc_fail_handler(size_t amountwanted) { #ifdef USE_CUSTOM_EXCEPTION_HANDLER - CreateMiniDump(NULL); + CreateMiniDump(NULL); #endif - free(printfworkingspace); - sprintf(tempmsg, "Out of memory: failed to allocate %ld bytes (at PP=%d)", amountwanted, our_eip); - quit(tempmsg); - return 0; + free(printfworkingspace); + sprintf(tempmsg, "Out of memory: failed to allocate %ld bytes (at PP=%d)", amountwanted, our_eip); + quit(tempmsg); + return 0; } -void setup_malloc_handling() -{ - _set_new_handler(malloc_fail_handler); - _set_new_mode(1); - printfworkingspace = (char*)malloc(7000); +void setup_malloc_handling() { + _set_new_handler(malloc_fail_handler); + _set_new_mode(1); + printfworkingspace = (char *)malloc(7000); } #endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index ac078a95d00d..82bcc771fa10 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -96,9 +96,9 @@ extern int mousex, mousey; extern int displayed_room; extern RoomStruct thisroom; extern GameSetupStruct game; -extern RoomStatus*croom; +extern RoomStatus *croom; extern SpriteCache spriteset; -extern ViewStruct*views; +extern ViewStruct *views; extern int game_paused; extern GameSetup usetup; extern int inside_script; @@ -121,32 +121,32 @@ extern ScriptString myScriptStringImpl; struct EnginePlugin { - char filename[PLUGIN_FILENAME_MAX+1]; - AGS::Engine::Library library; - bool available; - char *savedata; - int savedatasize; - int wantHook; - int invalidatedRegion; - void (*engineStartup) (IAGSEngine *) = nullptr; - void (*engineShutdown) () = nullptr; - int (*onEvent) (int, int) = nullptr; - void (*initGfxHook) (const char *driverName, void *data) = nullptr; - int (*debugHook) (const char * whichscript, int lineNumber, int reserved) = nullptr; - IAGSEngine eiface; - bool builtin; - - EnginePlugin() { - filename[0] = 0; - wantHook = 0; - invalidatedRegion = 0; - savedata = nullptr; - savedatasize = 0; - builtin = false; - available = false; - eiface.version = 0; - eiface.pluginId = 0; - } + char filename[PLUGIN_FILENAME_MAX + 1]; + AGS::Engine::Library library; + bool available; + char *savedata; + int savedatasize; + int wantHook; + int invalidatedRegion; + void (*engineStartup)(IAGSEngine *) = nullptr; + void (*engineShutdown)() = nullptr; + int (*onEvent)(int, int) = nullptr; + void (*initGfxHook)(const char *driverName, void *data) = nullptr; + int (*debugHook)(const char *whichscript, int lineNumber, int reserved) = nullptr; + IAGSEngine eiface; + bool builtin; + + EnginePlugin() { + filename[0] = 0; + wantHook = 0; + invalidatedRegion = 0; + savedata = nullptr; + savedatasize = 0; + builtin = false; + available = false; + eiface.version = 0; + eiface.pluginId = 0; + } }; #define MAXPLUGINS 20 EnginePlugin plugins[MAXPLUGINS]; @@ -155,157 +155,150 @@ int pluginsWantingDebugHooks = 0; std::vector _registered_builtin_plugins; -void IAGSEngine::AbortGame (const char *reason) { - quit ((char*)reason); +void IAGSEngine::AbortGame(const char *reason) { + quit((char *)reason); } -const char* IAGSEngine::GetEngineVersion () { - return get_engine_version(); +const char *IAGSEngine::GetEngineVersion() { + return get_engine_version(); } -void IAGSEngine::RegisterScriptFunction (const char*name, void*addy) { - ccAddExternalPluginFunction (name, addy); +void IAGSEngine::RegisterScriptFunction(const char *name, void *addy) { + ccAddExternalPluginFunction(name, addy); } -const char* IAGSEngine::GetGraphicsDriverID() -{ - if (gfxDriver == nullptr) - return nullptr; +const char *IAGSEngine::GetGraphicsDriverID() { + if (gfxDriver == nullptr) + return nullptr; - return gfxDriver->GetDriverID(); + return gfxDriver->GetDriverID(); } -BITMAP *IAGSEngine::GetScreen () -{ - // TODO: we could actually return stage buffer here, will that make a difference? - if (!gfxDriver->UsesMemoryBackBuffer()) - quit("!This plugin requires software graphics driver."); +BITMAP *IAGSEngine::GetScreen() { + // TODO: we could actually return stage buffer here, will that make a difference? + if (!gfxDriver->UsesMemoryBackBuffer()) + quit("!This plugin requires software graphics driver."); - Bitmap *buffer = gfxDriver->GetMemoryBackBuffer(); - return buffer ? (BITMAP*)buffer->GetAllegroBitmap() : nullptr; + Bitmap *buffer = gfxDriver->GetMemoryBackBuffer(); + return buffer ? (BITMAP *)buffer->GetAllegroBitmap() : nullptr; } -BITMAP *IAGSEngine::GetVirtualScreen () -{ - Bitmap *stage = gfxDriver->GetStageBackBuffer(); - return stage ? (BITMAP*)stage->GetAllegroBitmap() : nullptr; +BITMAP *IAGSEngine::GetVirtualScreen() { + Bitmap *stage = gfxDriver->GetStageBackBuffer(); + return stage ? (BITMAP *)stage->GetAllegroBitmap() : nullptr; } -void IAGSEngine::RequestEventHook (int32 event) { - if (event >= AGSE_TOOHIGH) - quit("!IAGSEngine::RequestEventHook: invalid event requested"); +void IAGSEngine::RequestEventHook(int32 event) { + if (event >= AGSE_TOOHIGH) + quit("!IAGSEngine::RequestEventHook: invalid event requested"); - if (plugins[this->pluginId].onEvent == nullptr) - quit("!IAGSEngine::RequestEventHook: no callback AGS_EngineOnEvent function exported from plugin"); + if (plugins[this->pluginId].onEvent == nullptr) + quit("!IAGSEngine::RequestEventHook: no callback AGS_EngineOnEvent function exported from plugin"); - if ((event & AGSE_SCRIPTDEBUG) && - ((plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG) == 0)) { - pluginsWantingDebugHooks++; - ccSetDebugHook(scriptDebugHook); - } + if ((event & AGSE_SCRIPTDEBUG) && + ((plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG) == 0)) { + pluginsWantingDebugHooks++; + ccSetDebugHook(scriptDebugHook); + } - if (event & AGSE_AUDIODECODE) { - quit("Plugin requested AUDIODECODE, which is no longer supported"); - } + if (event & AGSE_AUDIODECODE) { + quit("Plugin requested AUDIODECODE, which is no longer supported"); + } - plugins[this->pluginId].wantHook |= event; + plugins[this->pluginId].wantHook |= event; } void IAGSEngine::UnrequestEventHook(int32 event) { - if (event >= AGSE_TOOHIGH) - quit("!IAGSEngine::UnrequestEventHook: invalid event requested"); + if (event >= AGSE_TOOHIGH) + quit("!IAGSEngine::UnrequestEventHook: invalid event requested"); - if ((event & AGSE_SCRIPTDEBUG) && - (plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG)) { - pluginsWantingDebugHooks--; - if (pluginsWantingDebugHooks < 1) - ccSetDebugHook(nullptr); - } + if ((event & AGSE_SCRIPTDEBUG) && + (plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG)) { + pluginsWantingDebugHooks--; + if (pluginsWantingDebugHooks < 1) + ccSetDebugHook(nullptr); + } - plugins[this->pluginId].wantHook &= ~event; + plugins[this->pluginId].wantHook &= ~event; } -int IAGSEngine::GetSavedData (char *buffer, int32 bufsize) { - int savedatasize = plugins[this->pluginId].savedatasize; +int IAGSEngine::GetSavedData(char *buffer, int32 bufsize) { + int savedatasize = plugins[this->pluginId].savedatasize; - if (bufsize < savedatasize) - quit("!IAGSEngine::GetSavedData: buffer too small"); + if (bufsize < savedatasize) + quit("!IAGSEngine::GetSavedData: buffer too small"); - if (savedatasize > 0) - memcpy (buffer, plugins[this->pluginId].savedata, savedatasize); + if (savedatasize > 0) + memcpy(buffer, plugins[this->pluginId].savedata, savedatasize); - return savedatasize; + return savedatasize; } -void IAGSEngine::DrawText (int32 x, int32 y, int32 font, int32 color, char *text) -{ - Bitmap *ds = gfxDriver->GetStageBackBuffer(); - if (!ds) - return; - color_t text_color = ds->GetCompatibleColor(color); - draw_and_invalidate_text(ds, x, y, font, text_color, text); +void IAGSEngine::DrawText(int32 x, int32 y, int32 font, int32 color, char *text) { + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + color_t text_color = ds->GetCompatibleColor(color); + draw_and_invalidate_text(ds, x, y, font, text_color, text); } -void IAGSEngine::GetScreenDimensions (int32 *width, int32 *height, int32 *coldepth) { - if (width != nullptr) - width[0] = play.GetMainViewport().GetWidth(); - if (height != nullptr) - height[0] = play.GetMainViewport().GetHeight(); - if (coldepth != nullptr) - coldepth[0] = scsystem.coldepth; +void IAGSEngine::GetScreenDimensions(int32 *width, int32 *height, int32 *coldepth) { + if (width != nullptr) + width[0] = play.GetMainViewport().GetWidth(); + if (height != nullptr) + height[0] = play.GetMainViewport().GetHeight(); + if (coldepth != nullptr) + coldepth[0] = scsystem.coldepth; } -unsigned char ** IAGSEngine::GetRawBitmapSurface (BITMAP *bmp) -{ - if (!is_linear_bitmap(bmp)) - quit("!IAGSEngine::GetRawBitmapSurface: invalid bitmap for access to surface"); - acquire_bitmap(bmp); +unsigned char **IAGSEngine::GetRawBitmapSurface(BITMAP *bmp) { + if (!is_linear_bitmap(bmp)) + quit("!IAGSEngine::GetRawBitmapSurface: invalid bitmap for access to surface"); + acquire_bitmap(bmp); - Bitmap *stage = gfxDriver->GetStageBackBuffer(); - if (stage && bmp == stage->GetAllegroBitmap()) - plugins[this->pluginId].invalidatedRegion = 0; + Bitmap *stage = gfxDriver->GetStageBackBuffer(); + if (stage && bmp == stage->GetAllegroBitmap()) + plugins[this->pluginId].invalidatedRegion = 0; - return bmp->line; + return bmp->line; } -void IAGSEngine::ReleaseBitmapSurface (BITMAP *bmp) -{ - release_bitmap (bmp); +void IAGSEngine::ReleaseBitmapSurface(BITMAP *bmp) { + release_bitmap(bmp); - Bitmap *stage = gfxDriver->GetStageBackBuffer(); - if (stage && bmp == stage->GetAllegroBitmap()) - { - // plugin does not manaually invalidate stuff, so - // we must invalidate the whole screen to be safe - if (!plugins[this->pluginId].invalidatedRegion) - invalidate_screen(); - } + Bitmap *stage = gfxDriver->GetStageBackBuffer(); + if (stage && bmp == stage->GetAllegroBitmap()) { + // plugin does not manaually invalidate stuff, so + // we must invalidate the whole screen to be safe + if (!plugins[this->pluginId].invalidatedRegion) + invalidate_screen(); + } } -void IAGSEngine::GetMousePosition (int32 *x, int32 *y) { - if (x) x[0] = mousex; - if (y) y[0] = mousey; +void IAGSEngine::GetMousePosition(int32 *x, int32 *y) { + if (x) x[0] = mousex; + if (y) y[0] = mousey; } -int IAGSEngine::GetCurrentRoom () { - return displayed_room; +int IAGSEngine::GetCurrentRoom() { + return displayed_room; } -int IAGSEngine::GetNumBackgrounds () { - return thisroom.BgFrameCount; +int IAGSEngine::GetNumBackgrounds() { + return thisroom.BgFrameCount; } -int IAGSEngine::GetCurrentBackground () { - return play.bg_frame; +int IAGSEngine::GetCurrentBackground() { + return play.bg_frame; } -BITMAP *IAGSEngine::GetBackgroundScene (int32 index) { - return (BITMAP*)thisroom.BgFrames[index].Graphic->GetAllegroBitmap(); +BITMAP *IAGSEngine::GetBackgroundScene(int32 index) { + return (BITMAP *)thisroom.BgFrames[index].Graphic->GetAllegroBitmap(); } -void IAGSEngine::GetBitmapDimensions (BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth) { - if (bmp == nullptr) - return; +void IAGSEngine::GetBitmapDimensions(BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth) { + if (bmp == nullptr) + return; - if (width != nullptr) - width[0] = bmp->w; - if (height != nullptr) - height[0] = bmp->h; - if (coldepth != nullptr) - coldepth[0] = bitmap_color_depth(bmp); + if (width != nullptr) + width[0] = bmp->w; + if (height != nullptr) + height[0] = bmp->h; + if (coldepth != nullptr) + coldepth[0] = bitmap_color_depth(bmp); } // On save/restore, the Engine will provide the plugin with a handle. Because we only ever save to one file at a time, @@ -315,803 +308,760 @@ static long pl_file_handle = -1; static Stream *pl_file_stream = nullptr; void pl_set_file_handle(long data, Stream *stream) { - pl_file_handle = data; - pl_file_stream = stream; + pl_file_handle = data; + pl_file_stream = stream; } void pl_clear_file_handle() { - pl_file_handle = -1; - pl_file_stream = nullptr; + pl_file_handle = -1; + pl_file_stream = nullptr; } -int IAGSEngine::FRead (void *buffer, int32 len, int32 handle) { - if (handle != pl_file_handle) { - quitprintf("IAGSEngine::FRead: invalid file handle: %d", handle); - } - if (!pl_file_stream) { - quit("IAGSEngine::FRead: file stream not set"); - } - return pl_file_stream->Read(buffer, len); +int IAGSEngine::FRead(void *buffer, int32 len, int32 handle) { + if (handle != pl_file_handle) { + quitprintf("IAGSEngine::FRead: invalid file handle: %d", handle); + } + if (!pl_file_stream) { + quit("IAGSEngine::FRead: file stream not set"); + } + return pl_file_stream->Read(buffer, len); } -int IAGSEngine::FWrite (void *buffer, int32 len, int32 handle) { - if (handle != pl_file_handle) { - quitprintf("IAGSEngine::FWrite: invalid file handle: %d", handle); - } - if (!pl_file_stream) { - quit("IAGSEngine::FWrite: file stream not set"); - } - return pl_file_stream->Write(buffer, len); +int IAGSEngine::FWrite(void *buffer, int32 len, int32 handle) { + if (handle != pl_file_handle) { + quitprintf("IAGSEngine::FWrite: invalid file handle: %d", handle); + } + if (!pl_file_stream) { + quit("IAGSEngine::FWrite: file stream not set"); + } + return pl_file_stream->Write(buffer, len); } -void IAGSEngine::DrawTextWrapped (int32 xx, int32 yy, int32 wid, int32 font, int32 color, const char*text) -{ - // TODO: use generic function from the engine instead of having copy&pasted code here - int linespacing = getfontspacing_outlined(font); +void IAGSEngine::DrawTextWrapped(int32 xx, int32 yy, int32 wid, int32 font, int32 color, const char *text) { + // TODO: use generic function from the engine instead of having copy&pasted code here + int linespacing = getfontspacing_outlined(font); - if (break_up_text_into_lines(text, Lines, wid, font) == 0) - return; + if (break_up_text_into_lines(text, Lines, wid, font) == 0) + return; - Bitmap *ds = gfxDriver->GetStageBackBuffer(); - if (!ds) - return; - color_t text_color = ds->GetCompatibleColor(color); - data_to_game_coords((int*)&xx, (int*)&yy); // stupid! quick tweak - for (size_t i = 0; i < Lines.Count(); i++) - draw_and_invalidate_text(ds, xx, yy + linespacing*i, font, text_color, Lines[i]); + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + color_t text_color = ds->GetCompatibleColor(color); + data_to_game_coords((int *)&xx, (int *)&yy); // stupid! quick tweak + for (size_t i = 0; i < Lines.Count(); i++) + draw_and_invalidate_text(ds, xx, yy + linespacing * i, font, text_color, Lines[i]); } Bitmap glVirtualScreenWrap; -void IAGSEngine::SetVirtualScreen (BITMAP *bmp) -{ - if (!gfxDriver->UsesMemoryBackBuffer()) - { - debug_script_warn("SetVirtualScreen: this plugin requires software graphics driver to work correctly."); - // we let it continue since gfxDriver is supposed to ignore this request without throwing an exception - } - - if (bmp) - { - glVirtualScreenWrap.WrapAllegroBitmap(bmp, true); - gfxDriver->SetMemoryBackBuffer(&glVirtualScreenWrap); - } - else - { - glVirtualScreenWrap.Destroy(); - gfxDriver->SetMemoryBackBuffer(nullptr); - } -} - -int IAGSEngine::LookupParserWord (const char *word) { - return find_word_in_dictionary ((char*)word); -} - -void IAGSEngine::BlitBitmap (int32 x, int32 y, BITMAP *bmp, int32 masked) -{ - Bitmap *ds = gfxDriver->GetStageBackBuffer(); - if (!ds) - return; - wputblock_raw(ds, x, y, bmp, masked); - invalidate_rect(x, y, x + bmp->w, y + bmp->h, false); -} - -void IAGSEngine::BlitSpriteTranslucent(int32 x, int32 y, BITMAP *bmp, int32 trans) -{ - Bitmap *ds = gfxDriver->GetStageBackBuffer(); - if (!ds) - return; - Bitmap wrap(bmp, true); - if (gfxDriver->UsesMemoryBackBuffer()) - GfxUtil::DrawSpriteWithTransparency(ds, &wrap, x, y, trans); - else - GfxUtil::DrawSpriteBlend(ds, Point(x,y), &wrap, kBlendMode_Alpha, true, false, trans); -} - -void IAGSEngine::BlitSpriteRotated(int32 x, int32 y, BITMAP *bmp, int32 angle) -{ - Bitmap *ds = gfxDriver->GetStageBackBuffer(); - if (!ds) - return; - // FIXME: call corresponding Graphics Blit - rotate_sprite(ds->GetAllegroBitmap(), bmp, x, y, itofix(angle)); +void IAGSEngine::SetVirtualScreen(BITMAP *bmp) { + if (!gfxDriver->UsesMemoryBackBuffer()) { + debug_script_warn("SetVirtualScreen: this plugin requires software graphics driver to work correctly."); + // we let it continue since gfxDriver is supposed to ignore this request without throwing an exception + } + + if (bmp) { + glVirtualScreenWrap.WrapAllegroBitmap(bmp, true); + gfxDriver->SetMemoryBackBuffer(&glVirtualScreenWrap); + } else { + glVirtualScreenWrap.Destroy(); + gfxDriver->SetMemoryBackBuffer(nullptr); + } +} + +int IAGSEngine::LookupParserWord(const char *word) { + return find_word_in_dictionary((char *)word); +} + +void IAGSEngine::BlitBitmap(int32 x, int32 y, BITMAP *bmp, int32 masked) { + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + wputblock_raw(ds, x, y, bmp, masked); + invalidate_rect(x, y, x + bmp->w, y + bmp->h, false); +} + +void IAGSEngine::BlitSpriteTranslucent(int32 x, int32 y, BITMAP *bmp, int32 trans) { + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + Bitmap wrap(bmp, true); + if (gfxDriver->UsesMemoryBackBuffer()) + GfxUtil::DrawSpriteWithTransparency(ds, &wrap, x, y, trans); + else + GfxUtil::DrawSpriteBlend(ds, Point(x, y), &wrap, kBlendMode_Alpha, true, false, trans); +} + +void IAGSEngine::BlitSpriteRotated(int32 x, int32 y, BITMAP *bmp, int32 angle) { + Bitmap *ds = gfxDriver->GetStageBackBuffer(); + if (!ds) + return; + // FIXME: call corresponding Graphics Blit + rotate_sprite(ds->GetAllegroBitmap(), bmp, x, y, itofix(angle)); } extern void domouse(int); -void IAGSEngine::PollSystem () { +void IAGSEngine::PollSystem() { - domouse(DOMOUSE_NOCURSOR); - update_polled_stuff_if_runtime(); - int mbut, mwheelz; - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !play.IsIgnoringInput()) - pl_run_plugin_hooks (AGSE_MOUSECLICK, mbut); - int kp; - if (run_service_key_controls(kp) && !play.IsIgnoringInput()) { - pl_run_plugin_hooks (AGSE_KEYPRESS, kp); - } + domouse(DOMOUSE_NOCURSOR); + update_polled_stuff_if_runtime(); + int mbut, mwheelz; + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !play.IsIgnoringInput()) + pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut); + int kp; + if (run_service_key_controls(kp) && !play.IsIgnoringInput()) { + pl_run_plugin_hooks(AGSE_KEYPRESS, kp); + } } -AGSCharacter* IAGSEngine::GetCharacter (int32 charnum) { - if (charnum >= game.numcharacters) - quit("!AGSEngine::GetCharacter: invalid character request"); +AGSCharacter *IAGSEngine::GetCharacter(int32 charnum) { + if (charnum >= game.numcharacters) + quit("!AGSEngine::GetCharacter: invalid character request"); - return (AGSCharacter*)&game.chars[charnum]; + return (AGSCharacter *)&game.chars[charnum]; } -AGSGameOptions* IAGSEngine::GetGameOptions () { - return (AGSGameOptions*)&play; +AGSGameOptions *IAGSEngine::GetGameOptions() { + return (AGSGameOptions *)&play; } -AGSColor* IAGSEngine::GetPalette () { - return (AGSColor*)&palette[0]; +AGSColor *IAGSEngine::GetPalette() { + return (AGSColor *)&palette[0]; } -void IAGSEngine::SetPalette (int32 start, int32 finish, AGSColor *cpl) { - set_palette_range((color*)cpl, start, finish, 0); +void IAGSEngine::SetPalette(int32 start, int32 finish, AGSColor *cpl) { + set_palette_range((color *)cpl, start, finish, 0); } -int IAGSEngine::GetNumCharacters () { - return game.numcharacters; +int IAGSEngine::GetNumCharacters() { + return game.numcharacters; } -int IAGSEngine::GetPlayerCharacter () { - return game.playercharacter; +int IAGSEngine::GetPlayerCharacter() { + return game.playercharacter; } -void IAGSEngine::RoomToViewport (int32 *x, int32 *y) { - Point scrp = play.RoomToScreen(x ? data_to_game_coord(*x) : 0, y ? data_to_game_coord(*y) : 0); - if (x) - *x = scrp.X; - if (y) - *y = scrp.Y; +void IAGSEngine::RoomToViewport(int32 *x, int32 *y) { + Point scrp = play.RoomToScreen(x ? data_to_game_coord(*x) : 0, y ? data_to_game_coord(*y) : 0); + if (x) + *x = scrp.X; + if (y) + *y = scrp.Y; } -void IAGSEngine::ViewportToRoom (int32 *x, int32 *y) { - // NOTE: This is an old function that did not account for custom/multiple viewports - // and does not expect to fail, therefore we always use primary viewport here. - // (Not sure if it's good though) - VpPoint vpt = play.ScreenToRoom(x ? game_to_data_coord(*x) : 0, y ? game_to_data_coord(*y) : 0); - if (x) - *x = vpt.first.X; - if (y) - *y = vpt.first.Y; +void IAGSEngine::ViewportToRoom(int32 *x, int32 *y) { + // NOTE: This is an old function that did not account for custom/multiple viewports + // and does not expect to fail, therefore we always use primary viewport here. + // (Not sure if it's good though) + VpPoint vpt = play.ScreenToRoom(x ? game_to_data_coord(*x) : 0, y ? game_to_data_coord(*y) : 0); + if (x) + *x = vpt.first.X; + if (y) + *y = vpt.first.Y; } -int IAGSEngine::GetNumObjects () { - return croom->numobj; +int IAGSEngine::GetNumObjects() { + return croom->numobj; } -AGSObject *IAGSEngine::GetObject (int32 num) { - if (num >= croom->numobj) - quit("!IAGSEngine::GetObject: invalid object"); +AGSObject *IAGSEngine::GetObject(int32 num) { + if (num >= croom->numobj) + quit("!IAGSEngine::GetObject: invalid object"); - return (AGSObject*)&croom->obj[num]; + return (AGSObject *)&croom->obj[num]; } -BITMAP *IAGSEngine::CreateBlankBitmap (int32 width, int32 height, int32 coldep) { +BITMAP *IAGSEngine::CreateBlankBitmap(int32 width, int32 height, int32 coldep) { // [IKM] We should not create Bitmap object here, because // a) we are returning raw allegro bitmap and therefore loosing control over it // b) plugin won't use Bitmap anyway - BITMAP *tempb = create_bitmap_ex(coldep, width, height); - clear_to_color(tempb, bitmap_mask_color(tempb)); - return tempb; -} -void IAGSEngine::FreeBitmap (BITMAP *tofree) { - if (tofree) - destroy_bitmap (tofree); -} -BITMAP *IAGSEngine::GetSpriteGraphic (int32 num) { - return (BITMAP*)spriteset[num]->GetAllegroBitmap(); -} -BITMAP *IAGSEngine::GetRoomMask (int32 index) { - if (index == MASK_WALKABLE) - return (BITMAP*)thisroom.WalkAreaMask->GetAllegroBitmap(); - else if (index == MASK_WALKBEHIND) - return (BITMAP*)thisroom.WalkBehindMask->GetAllegroBitmap(); - else if (index == MASK_HOTSPOT) - return (BITMAP*)thisroom.HotspotMask->GetAllegroBitmap(); - else if (index == MASK_REGIONS) - return (BITMAP*)thisroom.RegionMask->GetAllegroBitmap(); - else - quit("!IAGSEngine::GetRoomMask: invalid mask requested"); - return nullptr; -} -AGSViewFrame *IAGSEngine::GetViewFrame (int32 view, int32 loop, int32 frame) { - view--; - if ((view < 0) || (view >= game.numviews)) - quit("!IAGSEngine::GetViewFrame: invalid view"); - if ((loop < 0) || (loop >= views[view].numLoops)) - quit("!IAGSEngine::GetViewFrame: invalid loop"); - if ((frame < 0) || (frame >= views[view].loops[loop].numFrames)) - return nullptr; - - return (AGSViewFrame*)&views[view].loops[loop].frames[frame]; -} - -int IAGSEngine::GetRawPixelColor(int32 color) -{ - // Convert the standardized colour to the local gfx mode color - // NOTE: it is unclear whether this has to be game colour depth or display color depth. - // there was no difference in the original engine, but there is now. - int result; - __my_setcolor(&result, color, game.GetColorDepth()); - return result; -} - -int IAGSEngine::GetWalkbehindBaseline (int32 wa) { - if ((wa < 1) || (wa >= MAX_WALK_BEHINDS)) - quit("!IAGSEngine::GetWalkBehindBase: invalid walk-behind area specified"); - return croom->walkbehind_base[wa]; -} -void* IAGSEngine::GetScriptFunctionAddress (const char *funcName) { - return ccGetSymbolAddressForPlugin ((char*)funcName); + BITMAP *tempb = create_bitmap_ex(coldep, width, height); + clear_to_color(tempb, bitmap_mask_color(tempb)); + return tempb; +} +void IAGSEngine::FreeBitmap(BITMAP *tofree) { + if (tofree) + destroy_bitmap(tofree); +} +BITMAP *IAGSEngine::GetSpriteGraphic(int32 num) { + return (BITMAP *)spriteset[num]->GetAllegroBitmap(); +} +BITMAP *IAGSEngine::GetRoomMask(int32 index) { + if (index == MASK_WALKABLE) + return (BITMAP *)thisroom.WalkAreaMask->GetAllegroBitmap(); + else if (index == MASK_WALKBEHIND) + return (BITMAP *)thisroom.WalkBehindMask->GetAllegroBitmap(); + else if (index == MASK_HOTSPOT) + return (BITMAP *)thisroom.HotspotMask->GetAllegroBitmap(); + else if (index == MASK_REGIONS) + return (BITMAP *)thisroom.RegionMask->GetAllegroBitmap(); + else + quit("!IAGSEngine::GetRoomMask: invalid mask requested"); + return nullptr; +} +AGSViewFrame *IAGSEngine::GetViewFrame(int32 view, int32 loop, int32 frame) { + view--; + if ((view < 0) || (view >= game.numviews)) + quit("!IAGSEngine::GetViewFrame: invalid view"); + if ((loop < 0) || (loop >= views[view].numLoops)) + quit("!IAGSEngine::GetViewFrame: invalid loop"); + if ((frame < 0) || (frame >= views[view].loops[loop].numFrames)) + return nullptr; + + return (AGSViewFrame *)&views[view].loops[loop].frames[frame]; +} + +int IAGSEngine::GetRawPixelColor(int32 color) { + // Convert the standardized colour to the local gfx mode color + // NOTE: it is unclear whether this has to be game colour depth or display color depth. + // there was no difference in the original engine, but there is now. + int result; + __my_setcolor(&result, color, game.GetColorDepth()); + return result; +} + +int IAGSEngine::GetWalkbehindBaseline(int32 wa) { + if ((wa < 1) || (wa >= MAX_WALK_BEHINDS)) + quit("!IAGSEngine::GetWalkBehindBase: invalid walk-behind area specified"); + return croom->walkbehind_base[wa]; +} +void *IAGSEngine::GetScriptFunctionAddress(const char *funcName) { + return ccGetSymbolAddressForPlugin((char *)funcName); } int IAGSEngine::GetBitmapTransparentColor(BITMAP *bmp) { - return bitmap_mask_color (bmp); + return bitmap_mask_color(bmp); } // get the character scaling level at a particular point -int IAGSEngine::GetAreaScaling (int32 x, int32 y) { - return GetScalingAt(x,y); -} -int IAGSEngine::IsGamePaused () { - return game_paused; -} -int IAGSEngine::GetSpriteWidth (int32 slot) { - return game.SpriteInfos[slot].Width; -} -int IAGSEngine::GetSpriteHeight (int32 slot) { - return game.SpriteInfos[slot].Height; -} -void IAGSEngine::GetTextExtent (int32 font, const char *text, int32 *width, int32 *height) { - if ((font < 0) || (font >= game.numfonts)) { - if (width != nullptr) width[0] = 0; - if (height != nullptr) height[0] = 0; - return; - } - - if (width != nullptr) - width[0] = wgettextwidth_compensate (text, font); - if (height != nullptr) - height[0] = wgettextheight ((char*)text, font); -} -void IAGSEngine::PrintDebugConsole (const char *text) { - debug_script_log("[PLUGIN] %s", text); - platform->WriteStdOut("[PLUGIN] %s", text); -} -int IAGSEngine::IsChannelPlaying (int32 channel) { - return ::IsChannelPlaying (channel); -} -void IAGSEngine::PlaySoundChannel (int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename) { - stop_and_destroy_channel (channel); - // Not sure if it's right to let it play on *any* channel, but this is plugin so let it go... - // we must correctly stop background voice speech if it takes over speech chan - if (channel == SCHAN_SPEECH && play.IsNonBlockingVoiceSpeech()) - stop_voice_nonblocking(); - - SOUNDCLIP *newcha = nullptr; - - if (((soundType == PSND_MP3STREAM) || (soundType == PSND_OGGSTREAM)) - && (loop != 0)) - quit("IAGSEngine::PlaySoundChannel: streamed samples cannot loop"); - - // TODO: find out how engine was supposed to decide on where to load the sound from - AssetPath asset_name("", filename); - - if (soundType == PSND_WAVE) - newcha = my_load_wave (asset_name, volume, loop); - else if (soundType == PSND_MP3STREAM) - newcha = my_load_mp3 (asset_name, volume); - else if (soundType == PSND_OGGSTREAM) - newcha = my_load_ogg (asset_name, volume); - else if (soundType == PSND_MP3STATIC) - newcha = my_load_static_mp3 (asset_name, volume, (loop != 0)); - else if (soundType == PSND_OGGSTATIC) - newcha = my_load_static_ogg (asset_name, volume, (loop != 0)); - else if (soundType == PSND_MIDI) { - if (midi_pos >= 0) - quit("!IAGSEngine::PlaySoundChannel: MIDI already in use"); - newcha = my_load_midi (asset_name, loop); - newcha->set_volume (volume); - } +int IAGSEngine::GetAreaScaling(int32 x, int32 y) { + return GetScalingAt(x, y); +} +int IAGSEngine::IsGamePaused() { + return game_paused; +} +int IAGSEngine::GetSpriteWidth(int32 slot) { + return game.SpriteInfos[slot].Width; +} +int IAGSEngine::GetSpriteHeight(int32 slot) { + return game.SpriteInfos[slot].Height; +} +void IAGSEngine::GetTextExtent(int32 font, const char *text, int32 *width, int32 *height) { + if ((font < 0) || (font >= game.numfonts)) { + if (width != nullptr) width[0] = 0; + if (height != nullptr) height[0] = 0; + return; + } + + if (width != nullptr) + width[0] = wgettextwidth_compensate(text, font); + if (height != nullptr) + height[0] = wgettextheight((char *)text, font); +} +void IAGSEngine::PrintDebugConsole(const char *text) { + debug_script_log("[PLUGIN] %s", text); + platform->WriteStdOut("[PLUGIN] %s", text); +} +int IAGSEngine::IsChannelPlaying(int32 channel) { + return ::IsChannelPlaying(channel); +} +void IAGSEngine::PlaySoundChannel(int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename) { + stop_and_destroy_channel(channel); + // Not sure if it's right to let it play on *any* channel, but this is plugin so let it go... + // we must correctly stop background voice speech if it takes over speech chan + if (channel == SCHAN_SPEECH && play.IsNonBlockingVoiceSpeech()) + stop_voice_nonblocking(); + + SOUNDCLIP *newcha = nullptr; + + if (((soundType == PSND_MP3STREAM) || (soundType == PSND_OGGSTREAM)) + && (loop != 0)) + quit("IAGSEngine::PlaySoundChannel: streamed samples cannot loop"); + + // TODO: find out how engine was supposed to decide on where to load the sound from + AssetPath asset_name("", filename); + + if (soundType == PSND_WAVE) + newcha = my_load_wave(asset_name, volume, loop); + else if (soundType == PSND_MP3STREAM) + newcha = my_load_mp3(asset_name, volume); + else if (soundType == PSND_OGGSTREAM) + newcha = my_load_ogg(asset_name, volume); + else if (soundType == PSND_MP3STATIC) + newcha = my_load_static_mp3(asset_name, volume, (loop != 0)); + else if (soundType == PSND_OGGSTATIC) + newcha = my_load_static_ogg(asset_name, volume, (loop != 0)); + else if (soundType == PSND_MIDI) { + if (midi_pos >= 0) + quit("!IAGSEngine::PlaySoundChannel: MIDI already in use"); + newcha = my_load_midi(asset_name, loop); + newcha->set_volume(volume); + } #ifndef PSP_NO_MOD_PLAYBACK - else if (soundType == PSND_MOD) { - newcha = my_load_mod (asset_name, loop); - newcha->set_volume (volume); - } + else if (soundType == PSND_MOD) { + newcha = my_load_mod(asset_name, loop); + newcha->set_volume(volume); + } #endif - else - quit("!IAGSEngine::PlaySoundChannel: unknown sound type"); + else + quit("!IAGSEngine::PlaySoundChannel: unknown sound type"); - set_clip_to_channel(channel, newcha); + set_clip_to_channel(channel, newcha); } // Engine interface 12 and above are below void IAGSEngine::MarkRegionDirty(int32 left, int32 top, int32 right, int32 bottom) { - invalidate_rect(left, top, right, bottom, false); - plugins[this->pluginId].invalidatedRegion++; + invalidate_rect(left, top, right, bottom, false); + plugins[this->pluginId].invalidatedRegion++; } -AGSMouseCursor * IAGSEngine::GetMouseCursor(int32 cursor) { - if ((cursor < 0) || (cursor >= game.numcursors)) - return nullptr; +AGSMouseCursor *IAGSEngine::GetMouseCursor(int32 cursor) { + if ((cursor < 0) || (cursor >= game.numcursors)) + return nullptr; - return (AGSMouseCursor*)&game.mcurs[cursor]; + return (AGSMouseCursor *)&game.mcurs[cursor]; } void IAGSEngine::GetRawColorComponents(int32 coldepth, int32 color, int32 *red, int32 *green, int32 *blue, int32 *alpha) { - if (red) - *red = getr_depth(coldepth, color); - if (green) - *green = getg_depth(coldepth, color); - if (blue) - *blue = getb_depth(coldepth, color); - if (alpha) - *alpha = geta_depth(coldepth, color); + if (red) + *red = getr_depth(coldepth, color); + if (green) + *green = getg_depth(coldepth, color); + if (blue) + *blue = getb_depth(coldepth, color); + if (alpha) + *alpha = geta_depth(coldepth, color); } int IAGSEngine::MakeRawColorPixel(int32 coldepth, int32 red, int32 green, int32 blue, int32 alpha) { - return makeacol_depth(coldepth, red, green, blue, alpha); + return makeacol_depth(coldepth, red, green, blue, alpha); } int IAGSEngine::GetFontType(int32 fontNum) { - if ((fontNum < 0) || (fontNum >= game.numfonts)) - return FNT_INVALID; + if ((fontNum < 0) || (fontNum >= game.numfonts)) + return FNT_INVALID; - if (font_supports_extended_characters(fontNum)) - return FNT_TTF; + if (font_supports_extended_characters(fontNum)) + return FNT_TTF; - return FNT_SCI; + return FNT_SCI; } int IAGSEngine::CreateDynamicSprite(int32 coldepth, int32 width, int32 height) { - // TODO: why is this implemented right here, should not an existing - // script handling implementation be called instead? + // TODO: why is this implemented right here, should not an existing + // script handling implementation be called instead? - int gotSlot = spriteset.GetFreeIndex(); - if (gotSlot <= 0) - return 0; + int gotSlot = spriteset.GetFreeIndex(); + if (gotSlot <= 0) + return 0; - if ((width < 1) || (height < 1)) - quit("!IAGSEngine::CreateDynamicSprite: invalid width/height requested by plugin"); + if ((width < 1) || (height < 1)) + quit("!IAGSEngine::CreateDynamicSprite: invalid width/height requested by plugin"); - // resize the sprite to the requested size - Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, coldepth); - if (newPic == nullptr) - return 0; + // resize the sprite to the requested size + Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, coldepth); + if (newPic == nullptr) + return 0; - // add it into the sprite set - add_dynamic_sprite(gotSlot, newPic); - return gotSlot; + // add it into the sprite set + add_dynamic_sprite(gotSlot, newPic); + return gotSlot; } void IAGSEngine::DeleteDynamicSprite(int32 slot) { - free_dynamic_sprite(slot); + free_dynamic_sprite(slot); } int IAGSEngine::IsSpriteAlphaBlended(int32 slot) { - if (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) - return 1; - return 0; + if (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) + return 1; + return 0; } // disable AGS's sound engine void IAGSEngine::DisableSound() { - shutdown_sound(); - usetup.digicard = DIGI_NONE; - usetup.midicard = MIDI_NONE; - reserve_voices(0, 0); - install_sound(DIGI_NONE, MIDI_NONE, nullptr); + shutdown_sound(); + usetup.digicard = DIGI_NONE; + usetup.midicard = MIDI_NONE; + reserve_voices(0, 0); + install_sound(DIGI_NONE, MIDI_NONE, nullptr); } int IAGSEngine::CanRunScriptFunctionNow() { - if (inside_script) - return 0; - return 1; + if (inside_script) + return 0; + return 1; } int IAGSEngine::CallGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1, long arg2, long arg3) { - if (inside_script) - return -300; + if (inside_script) + return -300; - ccInstance *toRun = GetScriptInstanceByType(globalScript ? kScInstGame : kScInstRoom); + ccInstance *toRun = GetScriptInstanceByType(globalScript ? kScInstGame : kScInstRoom); - RuntimeScriptValue params[3]; - params[0].SetPluginArgument(arg1); - params[1].SetPluginArgument(arg2); - params[2].SetPluginArgument(arg3); - int toret = RunScriptFunctionIfExists(toRun, (char*)name, numArgs, params); - return toret; + RuntimeScriptValue params[3]; + params[0].SetPluginArgument(arg1); + params[1].SetPluginArgument(arg2); + params[2].SetPluginArgument(arg3); + int toret = RunScriptFunctionIfExists(toRun, (char *)name, numArgs, params); + return toret; } void IAGSEngine::NotifySpriteUpdated(int32 slot) { - int ff; - // wipe the character cache when we change rooms - for (ff = 0; ff < game.numcharacters; ff++) { - if ((charcache[ff].inUse) && (charcache[ff].sppic == slot)) { - delete charcache[ff].image; - charcache[ff].image = nullptr; - charcache[ff].inUse = 0; - } - } - - // clear the object cache - for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) { - if ((objcache[ff].image != nullptr) && (objcache[ff].sppic == slot)) { - delete objcache[ff].image; - objcache[ff].image = nullptr; - } - } + int ff; + // wipe the character cache when we change rooms + for (ff = 0; ff < game.numcharacters; ff++) { + if ((charcache[ff].inUse) && (charcache[ff].sppic == slot)) { + delete charcache[ff].image; + charcache[ff].image = nullptr; + charcache[ff].inUse = 0; + } + } + + // clear the object cache + for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) { + if ((objcache[ff].image != nullptr) && (objcache[ff].sppic == slot)) { + delete objcache[ff].image; + objcache[ff].image = nullptr; + } + } } void IAGSEngine::SetSpriteAlphaBlended(int32 slot, int32 isAlphaBlended) { - game.SpriteInfos[slot].Flags &= ~SPF_ALPHACHANNEL; + game.SpriteInfos[slot].Flags &= ~SPF_ALPHACHANNEL; - if (isAlphaBlended) - game.SpriteInfos[slot].Flags |= SPF_ALPHACHANNEL; + if (isAlphaBlended) + game.SpriteInfos[slot].Flags |= SPF_ALPHACHANNEL; } void IAGSEngine::QueueGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1, long arg2) { - if (!inside_script) { - this->CallGameScriptFunction(name, globalScript, numArgs, arg1, arg2, 0); - return; - } + if (!inside_script) { + this->CallGameScriptFunction(name, globalScript, numArgs, arg1, arg2, 0); + return; + } - if (numArgs < 0 || numArgs > 2) - quit("IAGSEngine::QueueGameScriptFunction: invalid number of arguments"); + if (numArgs < 0 || numArgs > 2) + quit("IAGSEngine::QueueGameScriptFunction: invalid number of arguments"); - curscript->run_another(name, globalScript ? kScInstGame : kScInstRoom, numArgs, - RuntimeScriptValue().SetPluginArgument(arg1), RuntimeScriptValue().SetPluginArgument(arg2)); + curscript->run_another(name, globalScript ? kScInstGame : kScInstRoom, numArgs, + RuntimeScriptValue().SetPluginArgument(arg1), RuntimeScriptValue().SetPluginArgument(arg2)); } int IAGSEngine::RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback) { - GlobalReturnValue.SetPluginObject((void*)object, (ICCDynamicObject*)callback); - return ccRegisterManagedObject(object, (ICCDynamicObject*)callback, true); + GlobalReturnValue.SetPluginObject((void *)object, (ICCDynamicObject *)callback); + return ccRegisterManagedObject(object, (ICCDynamicObject *)callback, true); } void IAGSEngine::AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader) { - if (numPluginReaders >= MAX_PLUGIN_OBJECT_READERS) - quit("Plugin error: IAGSEngine::AddObjectReader: Too many object readers added"); + if (numPluginReaders >= MAX_PLUGIN_OBJECT_READERS) + quit("Plugin error: IAGSEngine::AddObjectReader: Too many object readers added"); - if ((typeName == nullptr) || (typeName[0] == 0)) - quit("Plugin error: IAGSEngine::AddObjectReader: invalid name for type"); + if ((typeName == nullptr) || (typeName[0] == 0)) + quit("Plugin error: IAGSEngine::AddObjectReader: invalid name for type"); - for (int ii = 0; ii < numPluginReaders; ii++) { - if (strcmp(pluginReaders[ii].type, typeName) == 0) - quitprintf("Plugin error: IAGSEngine::AddObjectReader: type '%s' has been registered already", typeName); - } + for (int ii = 0; ii < numPluginReaders; ii++) { + if (strcmp(pluginReaders[ii].type, typeName) == 0) + quitprintf("Plugin error: IAGSEngine::AddObjectReader: type '%s' has been registered already", typeName); + } - pluginReaders[numPluginReaders].reader = reader; - pluginReaders[numPluginReaders].type = typeName; - numPluginReaders++; + pluginReaders[numPluginReaders].reader = reader; + pluginReaders[numPluginReaders].type = typeName; + numPluginReaders++; } void IAGSEngine::RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback) { - GlobalReturnValue.SetPluginObject((void*)object, (ICCDynamicObject*)callback); - ccRegisterUnserializedObject(key, object, (ICCDynamicObject*)callback, true); + GlobalReturnValue.SetPluginObject((void *)object, (ICCDynamicObject *)callback); + ccRegisterUnserializedObject(key, object, (ICCDynamicObject *)callback, true); } int IAGSEngine::GetManagedObjectKeyByAddress(const char *address) { - return ccGetObjectHandleFromAddress(address); + return ccGetObjectHandleFromAddress(address); } -void* IAGSEngine::GetManagedObjectAddressByKey(int key) { - void *object; - ICCDynamicObject *manager; - ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(key, object, manager); - if (obj_type == kScValPluginObject) - { - GlobalReturnValue.SetPluginObject(object, manager); - } - else - { - GlobalReturnValue.SetDynamicObject(object, manager); - } - return object; +void *IAGSEngine::GetManagedObjectAddressByKey(int key) { + void *object; + ICCDynamicObject *manager; + ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(key, object, manager); + if (obj_type == kScValPluginObject) { + GlobalReturnValue.SetPluginObject(object, manager); + } else { + GlobalReturnValue.SetDynamicObject(object, manager); + } + return object; } -const char* IAGSEngine::CreateScriptString(const char *fromText) { - const char *string = CreateNewScriptString(fromText); - // Should be still standard dynamic object, because not managed by plugin - GlobalReturnValue.SetDynamicObject((void*)string, &myScriptStringImpl); - return string; +const char *IAGSEngine::CreateScriptString(const char *fromText) { + const char *string = CreateNewScriptString(fromText); + // Should be still standard dynamic object, because not managed by plugin + GlobalReturnValue.SetDynamicObject((void *)string, &myScriptStringImpl); + return string; } int IAGSEngine::IncrementManagedObjectRefCount(const char *address) { - return ccAddObjectReference(GetManagedObjectKeyByAddress(address)); + return ccAddObjectReference(GetManagedObjectKeyByAddress(address)); } int IAGSEngine::DecrementManagedObjectRefCount(const char *address) { - return ccReleaseObjectReference(GetManagedObjectKeyByAddress(address)); + return ccReleaseObjectReference(GetManagedObjectKeyByAddress(address)); } void IAGSEngine::SetMousePosition(int32 x, int32 y) { - Mouse::SetPosition(Point(x, y)); - RefreshMouse(); + Mouse::SetPosition(Point(x, y)); + RefreshMouse(); } void IAGSEngine::SimulateMouseClick(int32 button) { - PluginSimulateMouseClick(button); + PluginSimulateMouseClick(button); } int IAGSEngine::GetMovementPathWaypointCount(int32 pathId) { - return mls[pathId % TURNING_AROUND].numstage; + return mls[pathId % TURNING_AROUND].numstage; } int IAGSEngine::GetMovementPathLastWaypoint(int32 pathId) { - return mls[pathId % TURNING_AROUND].onstage; + return mls[pathId % TURNING_AROUND].onstage; } void IAGSEngine::GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y) { - *x = (mls[pathId % TURNING_AROUND].pos[waypoint] >> 16) & 0x0000ffff; - *y = (mls[pathId % TURNING_AROUND].pos[waypoint] & 0x0000ffff); + *x = (mls[pathId % TURNING_AROUND].pos[waypoint] >> 16) & 0x0000ffff; + *y = (mls[pathId % TURNING_AROUND].pos[waypoint] & 0x0000ffff); } void IAGSEngine::GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed) { - *xSpeed = mls[pathId % TURNING_AROUND].xpermove[waypoint]; - *ySpeed = mls[pathId % TURNING_AROUND].ypermove[waypoint]; + *xSpeed = mls[pathId % TURNING_AROUND].xpermove[waypoint]; + *ySpeed = mls[pathId % TURNING_AROUND].ypermove[waypoint]; } -int IAGSEngine::IsRunningUnderDebugger() -{ - return (editor_debugging_enabled != 0) ? 1 : 0; +int IAGSEngine::IsRunningUnderDebugger() { + return (editor_debugging_enabled != 0) ? 1 : 0; } -void IAGSEngine::GetPathToFileInCompiledFolder(const char*fileName, char *buffer) -{ - get_install_dir_path(buffer, fileName); +void IAGSEngine::GetPathToFileInCompiledFolder(const char *fileName, char *buffer) { + get_install_dir_path(buffer, fileName); } -void IAGSEngine::BreakIntoDebugger() -{ - break_on_next_script_step = 1; +void IAGSEngine::BreakIntoDebugger() { + break_on_next_script_step = 1; } -IAGSFontRenderer* IAGSEngine::ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer) -{ - return font_replace_renderer(fontNumber, newRenderer); +IAGSFontRenderer *IAGSEngine::ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer) { + return font_replace_renderer(fontNumber, newRenderer); } // *********** General plugin implementation ********** void pl_stop_plugins() { - int a; - ccSetDebugHook(nullptr); - - for (a = 0; a < numPlugins; a++) { - if (plugins[a].available) { - if (plugins[a].engineShutdown != nullptr) - plugins[a].engineShutdown(); - plugins[a].wantHook = 0; - if (plugins[a].savedata) { - free(plugins[a].savedata); - plugins[a].savedata = nullptr; - } - if (!plugins[a].builtin) { - plugins[a].library.Unload(); - } - } - } - numPlugins = 0; + int a; + ccSetDebugHook(nullptr); + + for (a = 0; a < numPlugins; a++) { + if (plugins[a].available) { + if (plugins[a].engineShutdown != nullptr) + plugins[a].engineShutdown(); + plugins[a].wantHook = 0; + if (plugins[a].savedata) { + free(plugins[a].savedata); + plugins[a].savedata = nullptr; + } + if (!plugins[a].builtin) { + plugins[a].library.Unload(); + } + } + } + numPlugins = 0; } void pl_startup_plugins() { - int i; - for (i = 0; i < numPlugins; i++) { - if (plugins[i].available) - plugins[i].engineStartup (&plugins[i].eiface); - } -} - -int pl_run_plugin_hooks (int event, int data) { - int i, retval = 0; - for (i = 0; i < numPlugins; i++) { - if (plugins[i].wantHook & event) { - retval = plugins[i].onEvent (event, data); - if (retval) - return retval; - } - } - return 0; -} - -int pl_run_plugin_debug_hooks (const char *scriptfile, int linenum) { - int i, retval = 0; - for (i = 0; i < numPlugins; i++) { - if (plugins[i].wantHook & AGSE_SCRIPTDEBUG) { - retval = plugins[i].debugHook(scriptfile, linenum, 0); - if (retval) - return retval; - } - } - return 0; -} - -void pl_run_plugin_init_gfx_hooks (const char *driverName, void *data) { - for (int i = 0; i < numPlugins; i++) - { - if (plugins[i].initGfxHook != nullptr) - { - plugins[i].initGfxHook(driverName, data); - } - } + int i; + for (i = 0; i < numPlugins; i++) { + if (plugins[i].available) + plugins[i].engineStartup(&plugins[i].eiface); + } +} + +int pl_run_plugin_hooks(int event, int data) { + int i, retval = 0; + for (i = 0; i < numPlugins; i++) { + if (plugins[i].wantHook & event) { + retval = plugins[i].onEvent(event, data); + if (retval) + return retval; + } + } + return 0; +} + +int pl_run_plugin_debug_hooks(const char *scriptfile, int linenum) { + int i, retval = 0; + for (i = 0; i < numPlugins; i++) { + if (plugins[i].wantHook & AGSE_SCRIPTDEBUG) { + retval = plugins[i].debugHook(scriptfile, linenum, 0); + if (retval) + return retval; + } + } + return 0; +} + +void pl_run_plugin_init_gfx_hooks(const char *driverName, void *data) { + for (int i = 0; i < numPlugins; i++) { + if (plugins[i].initGfxHook != nullptr) { + plugins[i].initGfxHook(driverName, data); + } + } } int pl_register_builtin_plugin(InbuiltPluginDetails const &details) { - _registered_builtin_plugins.push_back(details); - return 0; + _registered_builtin_plugins.push_back(details); + return 0; } -bool pl_use_builtin_plugin(EnginePlugin* apl) -{ +bool pl_use_builtin_plugin(EnginePlugin *apl) { #if defined(BUILTIN_PLUGINS) - if (ags_stricmp(apl->filename, "agsflashlight") == 0) - { - apl->engineStartup = agsflashlight::AGS_EngineStartup; - apl->engineShutdown = agsflashlight::AGS_EngineShutdown; - apl->onEvent = agsflashlight::AGS_EngineOnEvent; - apl->debugHook = agsflashlight::AGS_EngineDebugHook; - apl->initGfxHook = agsflashlight::AGS_EngineInitGfx; - apl->available = true; - apl->builtin = true; - return true; - } - else if (ags_stricmp(apl->filename, "agsblend") == 0) - { - apl->engineStartup = agsblend::AGS_EngineStartup; - apl->engineShutdown = agsblend::AGS_EngineShutdown; - apl->onEvent = agsblend::AGS_EngineOnEvent; - apl->debugHook = agsblend::AGS_EngineDebugHook; - apl->initGfxHook = agsblend::AGS_EngineInitGfx; - apl->available = true; - apl->builtin = true; - return true; - } - else if (ags_stricmp(apl->filename, "ags_snowrain") == 0) - { - apl->engineStartup = ags_snowrain::AGS_EngineStartup; - apl->engineShutdown = ags_snowrain::AGS_EngineShutdown; - apl->onEvent = ags_snowrain::AGS_EngineOnEvent; - apl->debugHook = ags_snowrain::AGS_EngineDebugHook; - apl->initGfxHook = ags_snowrain::AGS_EngineInitGfx; - apl->available = true; - apl->builtin = true; - return true; - } - else if (ags_stricmp(apl->filename, "ags_parallax") == 0) - { - apl->engineStartup = ags_parallax::AGS_EngineStartup; - apl->engineShutdown = ags_parallax::AGS_EngineShutdown; - apl->onEvent = ags_parallax::AGS_EngineOnEvent; - apl->debugHook = ags_parallax::AGS_EngineDebugHook; - apl->initGfxHook = ags_parallax::AGS_EngineInitGfx; - apl->available = true; - apl->builtin = true; - return true; - } - else if (ags_stricmp(apl->filename, "agspalrender") == 0) - { - apl->engineStartup = agspalrender::AGS_EngineStartup; - apl->engineShutdown = agspalrender::AGS_EngineShutdown; - apl->onEvent = agspalrender::AGS_EngineOnEvent; - apl->debugHook = agspalrender::AGS_EngineDebugHook; - apl->initGfxHook = agspalrender::AGS_EngineInitGfx; - apl->available = true; - apl->builtin = true; - return true; - } + if (ags_stricmp(apl->filename, "agsflashlight") == 0) { + apl->engineStartup = agsflashlight::AGS_EngineStartup; + apl->engineShutdown = agsflashlight::AGS_EngineShutdown; + apl->onEvent = agsflashlight::AGS_EngineOnEvent; + apl->debugHook = agsflashlight::AGS_EngineDebugHook; + apl->initGfxHook = agsflashlight::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } else if (ags_stricmp(apl->filename, "agsblend") == 0) { + apl->engineStartup = agsblend::AGS_EngineStartup; + apl->engineShutdown = agsblend::AGS_EngineShutdown; + apl->onEvent = agsblend::AGS_EngineOnEvent; + apl->debugHook = agsblend::AGS_EngineDebugHook; + apl->initGfxHook = agsblend::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } else if (ags_stricmp(apl->filename, "ags_snowrain") == 0) { + apl->engineStartup = ags_snowrain::AGS_EngineStartup; + apl->engineShutdown = ags_snowrain::AGS_EngineShutdown; + apl->onEvent = ags_snowrain::AGS_EngineOnEvent; + apl->debugHook = ags_snowrain::AGS_EngineDebugHook; + apl->initGfxHook = ags_snowrain::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } else if (ags_stricmp(apl->filename, "ags_parallax") == 0) { + apl->engineStartup = ags_parallax::AGS_EngineStartup; + apl->engineShutdown = ags_parallax::AGS_EngineShutdown; + apl->onEvent = ags_parallax::AGS_EngineOnEvent; + apl->debugHook = ags_parallax::AGS_EngineDebugHook; + apl->initGfxHook = ags_parallax::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } else if (ags_stricmp(apl->filename, "agspalrender") == 0) { + apl->engineStartup = agspalrender::AGS_EngineStartup; + apl->engineShutdown = agspalrender::AGS_EngineShutdown; + apl->onEvent = agspalrender::AGS_EngineOnEvent; + apl->debugHook = agspalrender::AGS_EngineDebugHook; + apl->initGfxHook = agspalrender::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } #if AGS_PLATFORM_OS_IOS - else if (ags_stricmp(apl->filename, "agstouch") == 0) - { - apl->engineStartup = agstouch::AGS_EngineStartup; - apl->engineShutdown = agstouch::AGS_EngineShutdown; - apl->onEvent = agstouch::AGS_EngineOnEvent; - apl->debugHook = agstouch::AGS_EngineDebugHook; - apl->initGfxHook = agstouch::AGS_EngineInitGfx; - apl->available = true; - apl->builtin = true; - return true; - } + else if (ags_stricmp(apl->filename, "agstouch") == 0) { + apl->engineStartup = agstouch::AGS_EngineStartup; + apl->engineShutdown = agstouch::AGS_EngineShutdown; + apl->onEvent = agstouch::AGS_EngineOnEvent; + apl->debugHook = agstouch::AGS_EngineDebugHook; + apl->initGfxHook = agstouch::AGS_EngineInitGfx; + apl->available = true; + apl->builtin = true; + return true; + } #endif // IOS_VERSION #endif // BUILTIN_PLUGINS - for(std::vector::iterator it = _registered_builtin_plugins.begin(); it != _registered_builtin_plugins.end(); ++it) { - if (ags_stricmp(apl->filename, it->filename) == 0) { - apl->engineStartup = it->engineStartup; - apl->engineShutdown = it->engineShutdown; - apl->onEvent = it->onEvent; - apl->debugHook = it->debugHook; - apl->initGfxHook = it->initGfxHook; - apl->available = true; - apl->builtin = true; - return true; - } - } - return false; -} - -Engine::GameInitError pl_register_plugins(const std::vector &infos) -{ - numPlugins = 0; - for (size_t inf_index = 0; inf_index < infos.size(); ++inf_index) - { - const Common::PluginInfo &info = infos[inf_index]; - String name = info.Name; - if (name.GetLast() == '!') - continue; // editor-only plugin, ignore it - if (numPlugins == MAXPLUGINS) - return kGameInitErr_TooManyPlugins; - // AGS Editor currently saves plugin names in game data with - // ".dll" extension appended; we need to take care of that - const String name_ext = ".dll"; - if (name.GetLength() <= name_ext.GetLength() || name.GetLength() > PLUGIN_FILENAME_MAX + name_ext.GetLength() || - name.CompareRightNoCase(name_ext, name_ext.GetLength())) { - return kGameInitErr_PluginNameInvalid; - } - // remove ".dll" from plugin's name - name.ClipRight(name_ext.GetLength()); - - EnginePlugin *apl = &plugins[numPlugins++]; - // Copy plugin info - snprintf(apl->filename, sizeof(apl->filename), "%s", name.GetCStr()); - if (info.DataLen) - { - apl->savedata = (char*)malloc(info.DataLen); - memcpy(apl->savedata, info.Data.get(), info.DataLen); - } - apl->savedatasize = info.DataLen; - - // Compatibility with the old SnowRain module - if (ags_stricmp(apl->filename, "ags_SnowRain20") == 0) { - strcpy(apl->filename, "ags_snowrain"); - } - - String expect_filename = apl->library.GetFilenameForLib(apl->filename); - if (apl->library.Load(apl->filename)) - { - AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' loaded as '%s', resolving imports...", apl->filename, expect_filename.GetCStr()); - - if (apl->library.GetFunctionAddress("AGS_PluginV2") == nullptr) { - quitprintf("Plugin '%s' is an old incompatible version.", apl->filename); - } - apl->engineStartup = (void(*)(IAGSEngine*))apl->library.GetFunctionAddress("AGS_EngineStartup"); - apl->engineShutdown = (void(*)())apl->library.GetFunctionAddress("AGS_EngineShutdown"); - - if (apl->engineStartup == nullptr) { - quitprintf("Plugin '%s' is not a valid AGS plugin (no engine startup entry point)", apl->filename); - } - apl->onEvent = (int(*)(int,int))apl->library.GetFunctionAddress("AGS_EngineOnEvent"); - apl->debugHook = (int(*)(const char*,int,int))apl->library.GetFunctionAddress("AGS_EngineDebugHook"); - apl->initGfxHook = (void(*)(const char*, void*))apl->library.GetFunctionAddress("AGS_EngineInitGfx"); - } - else - { - AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' could not be loaded (expected '%s'), trying built-in plugins...", - apl->filename, expect_filename.GetCStr()); - if (pl_use_builtin_plugin(apl)) - { - AGS::Common::Debug::Printf(kDbgMsg_Info, "Build-in plugin '%s' found and being used.", apl->filename); - } - else - { - // Plugin loading has failed at this point, try using built-in plugin function stubs - if (RegisterPluginStubs((const char*)apl->filename)) - AGS::Common::Debug::Printf(kDbgMsg_Info, "Placeholder functions for the plugin '%s' found.", apl->filename); - else - AGS::Common::Debug::Printf(kDbgMsg_Info, "No placeholder functions for the plugin '%s' found. The game might fail to load!", apl->filename); - continue; - } - } - - apl->eiface.pluginId = numPlugins - 1; - apl->eiface.version = 24; - apl->wantHook = 0; - apl->available = true; - } - return kGameInitErr_NoError; -} - -bool pl_is_plugin_loaded(const char *pl_name) -{ - if (!pl_name) - return false; - - for (int i = 0; i < numPlugins; ++i) - { - if (ags_stricmp(pl_name, plugins[i].filename) == 0) - return plugins[i].available; - } - return false; -} - -bool pl_any_want_hook(int event) -{ - for (int i = 0; i < numPlugins; ++i) - { - if(plugins[i].wantHook & event) - return true; - } - return false; + for (std::vector::iterator it = _registered_builtin_plugins.begin(); it != _registered_builtin_plugins.end(); ++it) { + if (ags_stricmp(apl->filename, it->filename) == 0) { + apl->engineStartup = it->engineStartup; + apl->engineShutdown = it->engineShutdown; + apl->onEvent = it->onEvent; + apl->debugHook = it->debugHook; + apl->initGfxHook = it->initGfxHook; + apl->available = true; + apl->builtin = true; + return true; + } + } + return false; +} + +Engine::GameInitError pl_register_plugins(const std::vector &infos) { + numPlugins = 0; + for (size_t inf_index = 0; inf_index < infos.size(); ++inf_index) { + const Common::PluginInfo &info = infos[inf_index]; + String name = info.Name; + if (name.GetLast() == '!') + continue; // editor-only plugin, ignore it + if (numPlugins == MAXPLUGINS) + return kGameInitErr_TooManyPlugins; + // AGS Editor currently saves plugin names in game data with + // ".dll" extension appended; we need to take care of that + const String name_ext = ".dll"; + if (name.GetLength() <= name_ext.GetLength() || name.GetLength() > PLUGIN_FILENAME_MAX + name_ext.GetLength() || + name.CompareRightNoCase(name_ext, name_ext.GetLength())) { + return kGameInitErr_PluginNameInvalid; + } + // remove ".dll" from plugin's name + name.ClipRight(name_ext.GetLength()); + + EnginePlugin *apl = &plugins[numPlugins++]; + // Copy plugin info + snprintf(apl->filename, sizeof(apl->filename), "%s", name.GetCStr()); + if (info.DataLen) { + apl->savedata = (char *)malloc(info.DataLen); + memcpy(apl->savedata, info.Data.get(), info.DataLen); + } + apl->savedatasize = info.DataLen; + + // Compatibility with the old SnowRain module + if (ags_stricmp(apl->filename, "ags_SnowRain20") == 0) { + strcpy(apl->filename, "ags_snowrain"); + } + + String expect_filename = apl->library.GetFilenameForLib(apl->filename); + if (apl->library.Load(apl->filename)) { + AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' loaded as '%s', resolving imports...", apl->filename, expect_filename.GetCStr()); + + if (apl->library.GetFunctionAddress("AGS_PluginV2") == nullptr) { + quitprintf("Plugin '%s' is an old incompatible version.", apl->filename); + } + apl->engineStartup = (void(*)(IAGSEngine *))apl->library.GetFunctionAddress("AGS_EngineStartup"); + apl->engineShutdown = (void(*)())apl->library.GetFunctionAddress("AGS_EngineShutdown"); + + if (apl->engineStartup == nullptr) { + quitprintf("Plugin '%s' is not a valid AGS plugin (no engine startup entry point)", apl->filename); + } + apl->onEvent = (int(*)(int, int))apl->library.GetFunctionAddress("AGS_EngineOnEvent"); + apl->debugHook = (int(*)(const char *, int, int))apl->library.GetFunctionAddress("AGS_EngineDebugHook"); + apl->initGfxHook = (void(*)(const char *, void *))apl->library.GetFunctionAddress("AGS_EngineInitGfx"); + } else { + AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' could not be loaded (expected '%s'), trying built-in plugins...", + apl->filename, expect_filename.GetCStr()); + if (pl_use_builtin_plugin(apl)) { + AGS::Common::Debug::Printf(kDbgMsg_Info, "Build-in plugin '%s' found and being used.", apl->filename); + } else { + // Plugin loading has failed at this point, try using built-in plugin function stubs + if (RegisterPluginStubs((const char *)apl->filename)) + AGS::Common::Debug::Printf(kDbgMsg_Info, "Placeholder functions for the plugin '%s' found.", apl->filename); + else + AGS::Common::Debug::Printf(kDbgMsg_Info, "No placeholder functions for the plugin '%s' found. The game might fail to load!", apl->filename); + continue; + } + } + + apl->eiface.pluginId = numPlugins - 1; + apl->eiface.version = 24; + apl->wantHook = 0; + apl->available = true; + } + return kGameInitErr_NoError; +} + +bool pl_is_plugin_loaded(const char *pl_name) { + if (!pl_name) + return false; + + for (int i = 0; i < numPlugins; ++i) { + if (ags_stricmp(pl_name, plugins[i].filename) == 0) + return plugins[i].available; + } + return false; +} + +bool pl_any_want_hook(int event) { + for (int i = 0; i < numPlugins; ++i) { + if (plugins[i].wantHook & event) + return true; + } + return false; } diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/engine/plugin/agsplugin.h index a480f6905359..5b1926674cfc 100644 --- a/engines/ags/engine/plugin/agsplugin.h +++ b/engines/ags/engine/plugin/agsplugin.h @@ -58,13 +58,13 @@ typedef int HWND; // This file is distributed as part of the Plugin API docs, so // ensure that WINDOWS_VERSION is defined (if applicable) #if defined(_WIN32) - #undef WINDOWS_VERSION - #define WINDOWS_VERSION +#undef WINDOWS_VERSION +#define WINDOWS_VERSION #endif // DOS engine doesn't know about stdcall / neither does Linux version #if !defined (_WIN32) - #define __stdcall +#define __stdcall #endif #ifndef int32 @@ -84,45 +84,45 @@ typedef int HWND; // **** WILL CRASH THE SYSTEM. struct AGSColor { - unsigned char r,g,b; - unsigned char padding; + unsigned char r, g, b; + unsigned char padding; }; struct AGSGameOptions { - int32 score; // player's current score - int32 usedmode; // set by ProcessClick to last cursor mode used - int32 disabled_user_interface; // >0 while in cutscene/etc - int32 gscript_timer; // obsolete - int32 debug_mode; // whether we're in debug mode - int32 globalvars[50]; // obsolete - int32 messagetime; // time left for auto-remove messages - int32 usedinv; // inventory item last used - int32 inv_top,inv_numdisp,inv_numorder,inv_numinline; - int32 text_speed; // how quickly text is removed - int32 sierra_inv_color; // background used to paint defualt inv window - int32 talkanim_speed; // animation speed of talking anims - int32 inv_item_wid,inv_item_hit; // set by SetInvDimensions - int32 speech_text_shadow; // colour of outline fonts (default black) - int32 swap_portrait_side; // sierra-style speech swap sides - int32 speech_textwindow_gui; // textwindow used for sierra-style speech - int32 follow_change_room_timer; // delay before moving following characters into new room - int32 totalscore; // maximum possible score - int32 skip_display; // how the user can skip normal Display windows - int32 no_multiloop_repeat; // for backwards compatibility - int32 roomscript_finished; // on_call finished in room - int32 used_inv_on; // inv item they clicked on - int32 no_textbg_when_voice; // no textwindow bgrnd when voice speech is used - int32 max_dialogoption_width; // max width of dialog options text window - int32 no_hicolor_fadein; // fade out but instant in for hi-color - int32 bgspeech_game_speed; // is background speech relative to game speed - int32 bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used - int32 unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay - int32 mp3_loop_before_end; // loop this time before end of track (ms) - int32 speech_music_drop; // how much to drop music volume by when speech is played - int32 in_cutscene; // we are between a StartCutscene and EndCutscene - int32 fast_forward; // player has elected to skip cutscene - int32 room_width; // width of current room - int32 room_height; // height of current room + int32 score; // player's current score + int32 usedmode; // set by ProcessClick to last cursor mode used + int32 disabled_user_interface; // >0 while in cutscene/etc + int32 gscript_timer; // obsolete + int32 debug_mode; // whether we're in debug mode + int32 globalvars[50]; // obsolete + int32 messagetime; // time left for auto-remove messages + int32 usedinv; // inventory item last used + int32 inv_top, inv_numdisp, inv_numorder, inv_numinline; + int32 text_speed; // how quickly text is removed + int32 sierra_inv_color; // background used to paint defualt inv window + int32 talkanim_speed; // animation speed of talking anims + int32 inv_item_wid, inv_item_hit; // set by SetInvDimensions + int32 speech_text_shadow; // colour of outline fonts (default black) + int32 swap_portrait_side; // sierra-style speech swap sides + int32 speech_textwindow_gui; // textwindow used for sierra-style speech + int32 follow_change_room_timer; // delay before moving following characters into new room + int32 totalscore; // maximum possible score + int32 skip_display; // how the user can skip normal Display windows + int32 no_multiloop_repeat; // for backwards compatibility + int32 roomscript_finished; // on_call finished in room + int32 used_inv_on; // inv item they clicked on + int32 no_textbg_when_voice; // no textwindow bgrnd when voice speech is used + int32 max_dialogoption_width; // max width of dialog options text window + int32 no_hicolor_fadein; // fade out but instant in for hi-color + int32 bgspeech_game_speed; // is background speech relative to game speed + int32 bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used + int32 unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay + int32 mp3_loop_before_end; // loop this time before end of track (ms) + int32 speech_music_drop; // how much to drop music volume by when speech is played + int32 in_cutscene; // we are between a StartCutscene and EndCutscene + int32 fast_forward; // player has elected to skip cutscene + int32 room_width; // width of current room + int32 room_height; // height of current room }; // AGSCharacter.flags @@ -136,33 +136,33 @@ struct AGSGameOptions { #define CHF_NOWALKBEHINDS 0x80 struct AGSCharacter { - int32 defview; - int32 talkview; - int32 view; - int32 room, prevroom; - int32 x, y, wait; - int32 flags; - short following; - short followinfo; - int32 idleview; // the loop will be randomly picked - short idletime, idleleft; // num seconds idle before playing anim - short transparency; // if character is transparent - short baseline; - int32 activeinv; - int32 talkcolor; - int32 thinkview; - int32 reserved[2]; - short walkspeed_y, pic_yoffs; - int32 z; - int32 reserved2[5]; - short loop, frame; - short walking, animating; - short walkspeed, animspeed; - short inv[301]; - short actx, acty; - char name[40]; - char scrname[20]; - char on; + int32 defview; + int32 talkview; + int32 view; + int32 room, prevroom; + int32 x, y, wait; + int32 flags; + short following; + short followinfo; + int32 idleview; // the loop will be randomly picked + short idletime, idleleft; // num seconds idle before playing anim + short transparency; // if character is transparent + short baseline; + int32 activeinv; + int32 talkcolor; + int32 thinkview; + int32 reserved[2]; + short walkspeed_y, pic_yoffs; + int32 z; + int32 reserved2[5]; + short loop, frame; + short walking, animating; + short walkspeed, animspeed; + short inv[301]; + short actx, acty; + char name[40]; + char scrname[20]; + char on; }; // AGSObject.flags @@ -170,29 +170,29 @@ struct AGSCharacter { #define OBJF_NOWALKBEHINDS 2 // ignore walk-behinds struct AGSObject { - int32 x,y; - int32 transparent; // current transparency setting - int32 reserved[4]; - short num; // sprite slot number - short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline - short view,loop,frame; // only used to track animation - 'num' holds the current sprite - short wait,moving; - char cycling; // is it currently animating? - char overall_speed; - char on; - char flags; + int32 x, y; + int32 transparent; // current transparency setting + int32 reserved[4]; + short num; // sprite slot number + short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline + short view, loop, frame; // only used to track animation - 'num' holds the current sprite + short wait, moving; + char cycling; // is it currently animating? + char overall_speed; + char on; + char flags; }; // AGSViewFrame.flags #define FRAF_MIRRORED 1 // flipped left to right struct AGSViewFrame { - int32 pic; // sprite slot number - short xoffs, yoffs; - short speed; - int32 flags; - int32 sound; // play sound when this frame comes round - int32 reserved_for_future[2]; + int32 pic; // sprite slot number + short xoffs, yoffs; + short speed; + int32 flags; + int32 sound; // play sound when this frame comes round + int32 reserved_for_future[2]; }; // AGSMouseCursor.flags @@ -202,28 +202,28 @@ struct AGSViewFrame { #define MCF_ONLYANIMOVERHOTSPOT 8 struct AGSMouseCursor { - int32 pic; // sprite slot number - short hotx, hoty; // x,y hotspot co-ordinates - short view; // view (for animating cursors) or -1 - char name[10]; // name of cursor mode - char flags; // MCF_flags above + int32 pic; // sprite slot number + short hotx, hoty; // x,y hotspot co-ordinates + short view; // view (for animating cursors) or -1 + char name[10]; // name of cursor mode + char flags; // MCF_flags above }; // The editor-to-plugin interface class IAGSEditor { public: - int32 version; - int32 pluginId; // used internally, do not touch this + int32 version; + int32 pluginId; // used internally, do not touch this public: - // get the HWND of the main editor frame - AGSIFUNC(HWND) GetEditorHandle (); - // get the HWND of the current active window - AGSIFUNC(HWND) GetWindowHandle (); - // add some script to the default header - AGSIFUNC(void) RegisterScriptHeader (const char *header); - // de-register a script header (pass same pointer as when added) - AGSIFUNC(void) UnregisterScriptHeader (const char *header); + // get the HWND of the main editor frame + AGSIFUNC(HWND) GetEditorHandle(); + // get the HWND of the current active window + AGSIFUNC(HWND) GetWindowHandle(); + // add some script to the default header + AGSIFUNC(void) RegisterScriptHeader(const char *header); + // de-register a script header (pass same pointer as when added) + AGSIFUNC(void) UnregisterScriptHeader(const char *header); }; @@ -274,281 +274,281 @@ class IAGSEditor { class IAGSScriptManagedObject { public: - // when a ref count reaches 0, this is called with the address - // of the object. Return 1 to remove the object from memory, 0 to - // leave it - virtual int Dispose(const char *address, bool force) = 0; - // return the type name of the object - virtual const char *GetType() = 0; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; + // when a ref count reaches 0, this is called with the address + // of the object. Return 1 to remove the object from memory, 0 to + // leave it + virtual int Dispose(const char *address, bool force) = 0; + // return the type name of the object + virtual const char *GetType() = 0; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; protected: - IAGSScriptManagedObject() {}; - ~IAGSScriptManagedObject() {}; + IAGSScriptManagedObject() {}; + ~IAGSScriptManagedObject() {}; }; class IAGSManagedObjectReader { public: - virtual void Unserialize(int key, const char *serializedData, int dataSize) = 0; + virtual void Unserialize(int key, const char *serializedData, int dataSize) = 0; protected: - IAGSManagedObjectReader() {}; - ~IAGSManagedObjectReader() {}; + IAGSManagedObjectReader() {}; + ~IAGSManagedObjectReader() {}; }; class IAGSFontRenderer { public: - virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; - virtual void FreeMemory(int fontNumber) = 0; - virtual bool SupportsExtendedCharacters(int fontNumber) = 0; - virtual int GetTextWidth(const char *text, int fontNumber) = 0; - virtual int GetTextHeight(const char *text, int fontNumber) = 0; - virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; - virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; - virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; + virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; + virtual void FreeMemory(int fontNumber) = 0; + virtual bool SupportsExtendedCharacters(int fontNumber) = 0; + virtual int GetTextWidth(const char *text, int fontNumber) = 0; + virtual int GetTextHeight(const char *text, int fontNumber) = 0; + virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; + virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; + virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; protected: - IAGSFontRenderer() {}; - ~IAGSFontRenderer() {}; + IAGSFontRenderer() {}; + ~IAGSFontRenderer() {}; }; // The plugin-to-engine interface class IAGSEngine { public: - int32 version; - int32 pluginId; // used internally, do not touch + int32 version; + int32 pluginId; // used internally, do not touch public: - // quit the game - AGSIFUNC(void) AbortGame (const char *reason); - // get engine version - AGSIFUNC(const char*) GetEngineVersion (); - // register a script function with the system - AGSIFUNC(void) RegisterScriptFunction (const char *name, void *address); + // quit the game + AGSIFUNC(void) AbortGame(const char *reason); + // get engine version + AGSIFUNC(const char *) GetEngineVersion(); + // register a script function with the system + AGSIFUNC(void) RegisterScriptFunction(const char *name, void *address); #ifdef WINDOWS_VERSION - // get game window handle - AGSIFUNC(HWND) GetWindowHandle(); - // get reference to main DirectDraw interface - AGSIFUNC(LPDIRECTDRAW2) GetDirectDraw2 (); - // get the DDraw surface associated with a bitmap - AGSIFUNC(LPDIRECTDRAWSURFACE2) GetBitmapSurface (BITMAP *); + // get game window handle + AGSIFUNC(HWND) GetWindowHandle(); + // get reference to main DirectDraw interface + AGSIFUNC(LPDIRECTDRAW2) GetDirectDraw2(); + // get the DDraw surface associated with a bitmap + AGSIFUNC(LPDIRECTDRAWSURFACE2) GetBitmapSurface(BITMAP *); #endif - // get a reference to the screen bitmap - AGSIFUNC(BITMAP *) GetScreen (); - - // *** BELOW ARE INTERFACE VERSION 2 AND ABOVE ONLY - // ask the engine to call back when a certain event happens - AGSIFUNC(void) RequestEventHook (int32 event); - // get the options data saved in the editor - AGSIFUNC(int) GetSavedData (char *buffer, int32 bufsize); - - // *** BELOW ARE INTERFACE VERSION 3 AND ABOVE ONLY - // get the virtual screen - AGSIFUNC(BITMAP *) GetVirtualScreen (); - // write text to the screen in the specified font and colour - AGSIFUNC(void) DrawText (int32 x, int32 y, int32 font, int32 color, char *text); - // get screen dimensions - AGSIFUNC(void) GetScreenDimensions (int32 *width, int32 *height, int32 *coldepth); - // get screen surface to draw on - AGSIFUNC(unsigned char**) GetRawBitmapSurface (BITMAP *); - // release the surface - AGSIFUNC(void) ReleaseBitmapSurface (BITMAP *); - // get the current mouse co-ordinates - AGSIFUNC(void) GetMousePosition (int32 *x, int32 *y); - - // *** BELOW ARE INTERFACE VERSION 4 AND ABOVE ONLY - // get the current room number - AGSIFUNC(int) GetCurrentRoom (); - // get the number of background scenes in this room - AGSIFUNC(int) GetNumBackgrounds (); - // get the current background frame - AGSIFUNC(int) GetCurrentBackground (); - // get a background scene bitmap - AGSIFUNC(BITMAP *) GetBackgroundScene (int32); - // get dimensions of a bitmap - AGSIFUNC(void) GetBitmapDimensions (BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth); - - // *** BELOW ARE INTERFACE VERSION 5 AND ABOVE ONLY - // similar to fwrite - buffer, size, filehandle - AGSIFUNC(int) FWrite (void *, int32, int32); - // similar to fread - buffer, size, filehandle - AGSIFUNC(int) FRead (void *, int32, int32); - // print text, wrapping as usual - AGSIFUNC(void) DrawTextWrapped (int32 x, int32 y, int32 width, int32 font, int32 color, const char *text); - // set the current active 'screen' - AGSIFUNC(void) SetVirtualScreen (BITMAP *); - // look up a word in the parser dictionary - AGSIFUNC(int) LookupParserWord (const char *word); - // draw a bitmap to the active screen - AGSIFUNC(void) BlitBitmap (int32 x, int32 y, BITMAP *, int32 masked); - // update the mouse and music - AGSIFUNC(void) PollSystem (); - - // *** BELOW ARE INTERFACE VERSION 6 AND ABOVE ONLY - // get number of characters in game - AGSIFUNC(int) GetNumCharacters (); - // get reference to specified character struct - AGSIFUNC(AGSCharacter*) GetCharacter (int32); - // get reference to game struct - AGSIFUNC(AGSGameOptions*) GetGameOptions (); - // get reference to current palette - AGSIFUNC(AGSColor*) GetPalette(); - // update palette - AGSIFUNC(void) SetPalette (int32 start, int32 finish, AGSColor*); - - // *** BELOW ARE INTERFACE VERSION 7 AND ABOVE ONLY - // get the current player character - AGSIFUNC(int) GetPlayerCharacter (); - // adjust to main viewport co-ordinates - AGSIFUNC(void) RoomToViewport (int32 *x, int32 *y); - // adjust from main viewport co-ordinates (ignores viewport bounds) - AGSIFUNC(void) ViewportToRoom (int32 *x, int32 *y); - // number of objects in current room - AGSIFUNC(int) GetNumObjects (); - // get reference to specified object - AGSIFUNC(AGSObject*) GetObject (int32); - // get sprite graphic - AGSIFUNC(BITMAP *) GetSpriteGraphic (int32); - // create a new blank bitmap - AGSIFUNC(BITMAP *) CreateBlankBitmap (int32 width, int32 height, int32 coldep); - // free a created bitamp - AGSIFUNC(void) FreeBitmap (BITMAP *); - - // *** BELOW ARE INTERFACE VERSION 8 AND ABOVE ONLY - // get one of the room area masks - AGSIFUNC(BITMAP *) GetRoomMask(int32); - - // *** BELOW ARE INTERFACE VERSION 9 AND ABOVE ONLY - // get a particular view frame - AGSIFUNC(AGSViewFrame *) GetViewFrame(int32 view, int32 loop, int32 frame); - // get the walk-behind baseline of a specific WB area - AGSIFUNC(int) GetWalkbehindBaseline(int32 walkbehind); - // get the address of a script function - AGSIFUNC(void *) GetScriptFunctionAddress(const char * funcName); - // get the transparent colour of a bitmap - AGSIFUNC(int) GetBitmapTransparentColor(BITMAP *); - // get the character scaling level at a particular point - AGSIFUNC(int) GetAreaScaling (int32 x, int32 y); - // equivalent to the text script function - AGSIFUNC(int) IsGamePaused(); - - // *** BELOW ARE INTERFACE VERSION 10 AND ABOVE ONLY - // get the raw pixel value to use for the specified AGS colour - AGSIFUNC(int) GetRawPixelColor (int32 color); - - // *** BELOW ARE INTERFACE VERSION 11 AND ABOVE ONLY - // get the width / height of the specified sprite - AGSIFUNC(int) GetSpriteWidth (int32); - AGSIFUNC(int) GetSpriteHeight (int32); - // get the dimensions of the specified string in the specified font - AGSIFUNC(void) GetTextExtent (int32 font, const char *text, int32 *width, int32 *height); - // print a message to the debug console - AGSIFUNC(void) PrintDebugConsole (const char *text); - // play a sound on the specified channel - AGSIFUNC(void) PlaySoundChannel (int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename); - // same as text script function - AGSIFUNC(int) IsChannelPlaying (int32 channel); - - // *** BELOW ARE INTERFACE VERSION 12 AND ABOVE ONLY - // invalidate a region of the virtual screen - AGSIFUNC(void) MarkRegionDirty(int32 left, int32 top, int32 right, int32 bottom); - // get mouse cursor details - AGSIFUNC(AGSMouseCursor *) GetMouseCursor(int32 cursor); - // get the various components of a pixel - AGSIFUNC(void) GetRawColorComponents(int32 coldepth, int32 color, int32 *red, int32 *green, int32 *blue, int32 *alpha); - // make a pixel colour from the supplied components - AGSIFUNC(int) MakeRawColorPixel(int32 coldepth, int32 red, int32 green, int32 blue, int32 alpha); - // get whether the font is TTF or SCI - AGSIFUNC(int) GetFontType(int32 fontNum); - // create a new dynamic sprite slot - AGSIFUNC(int) CreateDynamicSprite(int32 coldepth, int32 width, int32 height); - // free a created dynamic sprite - AGSIFUNC(void) DeleteDynamicSprite(int32 slot); - // check if a sprite has an alpha channel - AGSIFUNC(int) IsSpriteAlphaBlended(int32 slot); - - // *** BELOW ARE INTERFACE VERSION 13 AND ABOVE ONLY - // un-request an event, requested earlier with RequestEventHook - AGSIFUNC(void) UnrequestEventHook(int32 event); - // draw a translucent bitmap to the active screen - AGSIFUNC(void) BlitSpriteTranslucent(int32 x, int32 y, BITMAP *, int32 trans); - // draw a sprite to the screen, but rotated around its centre - AGSIFUNC(void) BlitSpriteRotated(int32 x, int32 y, BITMAP *, int32 angle); - - // *** BELOW ARE INTERFACE VERSION 14 AND ABOVE ONLY + // get a reference to the screen bitmap + AGSIFUNC(BITMAP *) GetScreen(); + + // *** BELOW ARE INTERFACE VERSION 2 AND ABOVE ONLY + // ask the engine to call back when a certain event happens + AGSIFUNC(void) RequestEventHook(int32 event); + // get the options data saved in the editor + AGSIFUNC(int) GetSavedData(char *buffer, int32 bufsize); + + // *** BELOW ARE INTERFACE VERSION 3 AND ABOVE ONLY + // get the virtual screen + AGSIFUNC(BITMAP *) GetVirtualScreen(); + // write text to the screen in the specified font and colour + AGSIFUNC(void) DrawText(int32 x, int32 y, int32 font, int32 color, char *text); + // get screen dimensions + AGSIFUNC(void) GetScreenDimensions(int32 *width, int32 *height, int32 *coldepth); + // get screen surface to draw on + AGSIFUNC(unsigned char **) GetRawBitmapSurface(BITMAP *); + // release the surface + AGSIFUNC(void) ReleaseBitmapSurface(BITMAP *); + // get the current mouse co-ordinates + AGSIFUNC(void) GetMousePosition(int32 *x, int32 *y); + + // *** BELOW ARE INTERFACE VERSION 4 AND ABOVE ONLY + // get the current room number + AGSIFUNC(int) GetCurrentRoom(); + // get the number of background scenes in this room + AGSIFUNC(int) GetNumBackgrounds(); + // get the current background frame + AGSIFUNC(int) GetCurrentBackground(); + // get a background scene bitmap + AGSIFUNC(BITMAP *) GetBackgroundScene(int32); + // get dimensions of a bitmap + AGSIFUNC(void) GetBitmapDimensions(BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth); + + // *** BELOW ARE INTERFACE VERSION 5 AND ABOVE ONLY + // similar to fwrite - buffer, size, filehandle + AGSIFUNC(int) FWrite(void *, int32, int32); + // similar to fread - buffer, size, filehandle + AGSIFUNC(int) FRead(void *, int32, int32); + // print text, wrapping as usual + AGSIFUNC(void) DrawTextWrapped(int32 x, int32 y, int32 width, int32 font, int32 color, const char *text); + // set the current active 'screen' + AGSIFUNC(void) SetVirtualScreen(BITMAP *); + // look up a word in the parser dictionary + AGSIFUNC(int) LookupParserWord(const char *word); + // draw a bitmap to the active screen + AGSIFUNC(void) BlitBitmap(int32 x, int32 y, BITMAP *, int32 masked); + // update the mouse and music + AGSIFUNC(void) PollSystem(); + + // *** BELOW ARE INTERFACE VERSION 6 AND ABOVE ONLY + // get number of characters in game + AGSIFUNC(int) GetNumCharacters(); + // get reference to specified character struct + AGSIFUNC(AGSCharacter *) GetCharacter(int32); + // get reference to game struct + AGSIFUNC(AGSGameOptions *) GetGameOptions(); + // get reference to current palette + AGSIFUNC(AGSColor *) GetPalette(); + // update palette + AGSIFUNC(void) SetPalette(int32 start, int32 finish, AGSColor *); + + // *** BELOW ARE INTERFACE VERSION 7 AND ABOVE ONLY + // get the current player character + AGSIFUNC(int) GetPlayerCharacter(); + // adjust to main viewport co-ordinates + AGSIFUNC(void) RoomToViewport(int32 *x, int32 *y); + // adjust from main viewport co-ordinates (ignores viewport bounds) + AGSIFUNC(void) ViewportToRoom(int32 *x, int32 *y); + // number of objects in current room + AGSIFUNC(int) GetNumObjects(); + // get reference to specified object + AGSIFUNC(AGSObject *) GetObject(int32); + // get sprite graphic + AGSIFUNC(BITMAP *) GetSpriteGraphic(int32); + // create a new blank bitmap + AGSIFUNC(BITMAP *) CreateBlankBitmap(int32 width, int32 height, int32 coldep); + // free a created bitamp + AGSIFUNC(void) FreeBitmap(BITMAP *); + + // *** BELOW ARE INTERFACE VERSION 8 AND ABOVE ONLY + // get one of the room area masks + AGSIFUNC(BITMAP *) GetRoomMask(int32); + + // *** BELOW ARE INTERFACE VERSION 9 AND ABOVE ONLY + // get a particular view frame + AGSIFUNC(AGSViewFrame *) GetViewFrame(int32 view, int32 loop, int32 frame); + // get the walk-behind baseline of a specific WB area + AGSIFUNC(int) GetWalkbehindBaseline(int32 walkbehind); + // get the address of a script function + AGSIFUNC(void *) GetScriptFunctionAddress(const char *funcName); + // get the transparent colour of a bitmap + AGSIFUNC(int) GetBitmapTransparentColor(BITMAP *); + // get the character scaling level at a particular point + AGSIFUNC(int) GetAreaScaling(int32 x, int32 y); + // equivalent to the text script function + AGSIFUNC(int) IsGamePaused(); + + // *** BELOW ARE INTERFACE VERSION 10 AND ABOVE ONLY + // get the raw pixel value to use for the specified AGS colour + AGSIFUNC(int) GetRawPixelColor(int32 color); + + // *** BELOW ARE INTERFACE VERSION 11 AND ABOVE ONLY + // get the width / height of the specified sprite + AGSIFUNC(int) GetSpriteWidth(int32); + AGSIFUNC(int) GetSpriteHeight(int32); + // get the dimensions of the specified string in the specified font + AGSIFUNC(void) GetTextExtent(int32 font, const char *text, int32 *width, int32 *height); + // print a message to the debug console + AGSIFUNC(void) PrintDebugConsole(const char *text); + // play a sound on the specified channel + AGSIFUNC(void) PlaySoundChannel(int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename); + // same as text script function + AGSIFUNC(int) IsChannelPlaying(int32 channel); + + // *** BELOW ARE INTERFACE VERSION 12 AND ABOVE ONLY + // invalidate a region of the virtual screen + AGSIFUNC(void) MarkRegionDirty(int32 left, int32 top, int32 right, int32 bottom); + // get mouse cursor details + AGSIFUNC(AGSMouseCursor *) GetMouseCursor(int32 cursor); + // get the various components of a pixel + AGSIFUNC(void) GetRawColorComponents(int32 coldepth, int32 color, int32 *red, int32 *green, int32 *blue, int32 *alpha); + // make a pixel colour from the supplied components + AGSIFUNC(int) MakeRawColorPixel(int32 coldepth, int32 red, int32 green, int32 blue, int32 alpha); + // get whether the font is TTF or SCI + AGSIFUNC(int) GetFontType(int32 fontNum); + // create a new dynamic sprite slot + AGSIFUNC(int) CreateDynamicSprite(int32 coldepth, int32 width, int32 height); + // free a created dynamic sprite + AGSIFUNC(void) DeleteDynamicSprite(int32 slot); + // check if a sprite has an alpha channel + AGSIFUNC(int) IsSpriteAlphaBlended(int32 slot); + + // *** BELOW ARE INTERFACE VERSION 13 AND ABOVE ONLY + // un-request an event, requested earlier with RequestEventHook + AGSIFUNC(void) UnrequestEventHook(int32 event); + // draw a translucent bitmap to the active screen + AGSIFUNC(void) BlitSpriteTranslucent(int32 x, int32 y, BITMAP *, int32 trans); + // draw a sprite to the screen, but rotated around its centre + AGSIFUNC(void) BlitSpriteRotated(int32 x, int32 y, BITMAP *, int32 angle); + + // *** BELOW ARE INTERFACE VERSION 14 AND ABOVE ONLY #ifdef WINDOWS_VERSION - // get reference to main DirectSound interface - AGSIFUNC(LPDIRECTSOUND) GetDirectSound(); + // get reference to main DirectSound interface + AGSIFUNC(LPDIRECTSOUND) GetDirectSound(); #endif - // disable AGS sound engine - AGSIFUNC(void) DisableSound(); - // check whether a script function can be run now - AGSIFUNC(int) CanRunScriptFunctionNow(); - // call a user-defined script function - AGSIFUNC(int) CallGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0, long arg3 = 0); - - // *** BELOW ARE INTERFACE VERSION 15 AND ABOVE ONLY - // force any sprites on-screen using the slot to be updated - AGSIFUNC(void) NotifySpriteUpdated(int32 slot); - // change whether the specified sprite is a 32-bit alpha blended image - AGSIFUNC(void) SetSpriteAlphaBlended(int32 slot, int32 isAlphaBlended); - // run the specified script function whenever script engine is available - AGSIFUNC(void) QueueGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0); - // register a new dynamic managed script object - AGSIFUNC(int) RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback); - // add an object reader for the specified object type - AGSIFUNC(void) AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader); - // register an un-serialized managed script object - AGSIFUNC(void) RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback); - - // *** BELOW ARE INTERFACE VERSION 16 AND ABOVE ONLY - // get the address of a managed object based on its key - AGSIFUNC(void*) GetManagedObjectAddressByKey(int key); - // get managed object's key from its address - AGSIFUNC(int) GetManagedObjectKeyByAddress(const char *address); - - // *** BELOW ARE INTERFACE VERSION 17 AND ABOVE ONLY - // create a new script string - AGSIFUNC(const char*) CreateScriptString(const char *fromText); - - // *** BELOW ARE INTERFACE VERSION 18 AND ABOVE ONLY - // increment reference count - AGSIFUNC(int) IncrementManagedObjectRefCount(const char *address); - // decrement reference count - AGSIFUNC(int) DecrementManagedObjectRefCount(const char *address); - // set mouse position - AGSIFUNC(void) SetMousePosition(int32 x, int32 y); - // simulate the mouse being clicked - AGSIFUNC(void) SimulateMouseClick(int32 button); - // get number of waypoints on this movement path - AGSIFUNC(int) GetMovementPathWaypointCount(int32 pathId); - // get the last waypoint that the char/obj passed - AGSIFUNC(int) GetMovementPathLastWaypoint(int32 pathId); - // get the co-ordinates of the specified waypoint - AGSIFUNC(void) GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y); - // get the speeds of the specified waypoint - AGSIFUNC(void) GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed); - - // *** BELOW ARE INTERFACE VERSION 19 AND ABOVE ONLY - // get the current graphics driver ID - AGSIFUNC(const char*) GetGraphicsDriverID(); - - // *** BELOW ARE INTERFACE VERSION 22 AND ABOVE ONLY - // get whether we are running under the editor's debugger - AGSIFUNC(int) IsRunningUnderDebugger(); - // tells the engine to break into the debugger when the next line of script is run - AGSIFUNC(void) BreakIntoDebugger(); - // fills buffer with \fileName, as appropriate - AGSIFUNC(void) GetPathToFileInCompiledFolder(const char* fileName, char* buffer); - - // *** BELOW ARE INTERFACE VERSION 23 AND ABOVE ONLY + // disable AGS sound engine + AGSIFUNC(void) DisableSound(); + // check whether a script function can be run now + AGSIFUNC(int) CanRunScriptFunctionNow(); + // call a user-defined script function + AGSIFUNC(int) CallGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0, long arg3 = 0); + + // *** BELOW ARE INTERFACE VERSION 15 AND ABOVE ONLY + // force any sprites on-screen using the slot to be updated + AGSIFUNC(void) NotifySpriteUpdated(int32 slot); + // change whether the specified sprite is a 32-bit alpha blended image + AGSIFUNC(void) SetSpriteAlphaBlended(int32 slot, int32 isAlphaBlended); + // run the specified script function whenever script engine is available + AGSIFUNC(void) QueueGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0); + // register a new dynamic managed script object + AGSIFUNC(int) RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback); + // add an object reader for the specified object type + AGSIFUNC(void) AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader); + // register an un-serialized managed script object + AGSIFUNC(void) RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback); + + // *** BELOW ARE INTERFACE VERSION 16 AND ABOVE ONLY + // get the address of a managed object based on its key + AGSIFUNC(void *) GetManagedObjectAddressByKey(int key); + // get managed object's key from its address + AGSIFUNC(int) GetManagedObjectKeyByAddress(const char *address); + + // *** BELOW ARE INTERFACE VERSION 17 AND ABOVE ONLY + // create a new script string + AGSIFUNC(const char *) CreateScriptString(const char *fromText); + + // *** BELOW ARE INTERFACE VERSION 18 AND ABOVE ONLY + // increment reference count + AGSIFUNC(int) IncrementManagedObjectRefCount(const char *address); + // decrement reference count + AGSIFUNC(int) DecrementManagedObjectRefCount(const char *address); + // set mouse position + AGSIFUNC(void) SetMousePosition(int32 x, int32 y); + // simulate the mouse being clicked + AGSIFUNC(void) SimulateMouseClick(int32 button); + // get number of waypoints on this movement path + AGSIFUNC(int) GetMovementPathWaypointCount(int32 pathId); + // get the last waypoint that the char/obj passed + AGSIFUNC(int) GetMovementPathLastWaypoint(int32 pathId); + // get the co-ordinates of the specified waypoint + AGSIFUNC(void) GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y); + // get the speeds of the specified waypoint + AGSIFUNC(void) GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed); + + // *** BELOW ARE INTERFACE VERSION 19 AND ABOVE ONLY + // get the current graphics driver ID + AGSIFUNC(const char *) GetGraphicsDriverID(); + + // *** BELOW ARE INTERFACE VERSION 22 AND ABOVE ONLY + // get whether we are running under the editor's debugger + AGSIFUNC(int) IsRunningUnderDebugger(); + // tells the engine to break into the debugger when the next line of script is run + AGSIFUNC(void) BreakIntoDebugger(); + // fills buffer with \fileName, as appropriate + AGSIFUNC(void) GetPathToFileInCompiledFolder(const char *fileName, char *buffer); + + // *** BELOW ARE INTERFACE VERSION 23 AND ABOVE ONLY #ifdef WINDOWS_VERSION - // get reference to keyboard Direct Input device - AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputKeyboard(); - // get reference to mouse Direct Input device - AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputMouse(); + // get reference to keyboard Direct Input device + AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputKeyboard(); + // get reference to mouse Direct Input device + AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputMouse(); #endif - // install a replacement renderer for the specified font number - AGSIFUNC(IAGSFontRenderer*) ReplaceFontRenderer(int fontNumber, IAGSFontRenderer* newRenderer); + // install a replacement renderer for the specified font number + AGSIFUNC(IAGSFontRenderer *) ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer); }; #ifdef THIS_IS_THE_PLUGIN @@ -561,19 +561,21 @@ class IAGSEngine { #define DLLEXPORT extern "C" __attribute__((visibility("default"))) #endif -DLLEXPORT const char * AGS_GetPluginName(void); -DLLEXPORT int AGS_EditorStartup (IAGSEditor *); -DLLEXPORT void AGS_EditorShutdown (void); -DLLEXPORT void AGS_EditorProperties (HWND); -DLLEXPORT int AGS_EditorSaveGame (char *, int); -DLLEXPORT void AGS_EditorLoadGame (char *, int); -DLLEXPORT void AGS_EngineStartup (IAGSEngine *); -DLLEXPORT void AGS_EngineShutdown (void); -DLLEXPORT int AGS_EngineOnEvent (int, int); +DLLEXPORT const char *AGS_GetPluginName(void); +DLLEXPORT int AGS_EditorStartup(IAGSEditor *); +DLLEXPORT void AGS_EditorShutdown(void); +DLLEXPORT void AGS_EditorProperties(HWND); +DLLEXPORT int AGS_EditorSaveGame(char *, int); +DLLEXPORT void AGS_EditorLoadGame(char *, int); +DLLEXPORT void AGS_EngineStartup(IAGSEngine *); +DLLEXPORT void AGS_EngineShutdown(void); +DLLEXPORT int AGS_EngineOnEvent(int, int); DLLEXPORT int AGS_EngineDebugHook(const char *, int, int); -DLLEXPORT void AGS_EngineInitGfx(const char* driverID, void *data); +DLLEXPORT void AGS_EngineInitGfx(const char *driverID, void *data); // We export this to verify that we are an AGS Plugin -DLLEXPORT int AGS_PluginV2 ( ) { return 1; } +DLLEXPORT int AGS_PluginV2() { + return 1; +} #endif // THIS_IS_THE_PLUGIN diff --git a/engines/ags/engine/plugin/global_plugin.cpp b/engines/ags/engine/plugin/global_plugin.cpp index 6d7b5282a103..0be249c80a66 100644 --- a/engines/ags/engine/plugin/global_plugin.cpp +++ b/engines/ags/engine/plugin/global_plugin.cpp @@ -34,7 +34,7 @@ int pluginSimulatedClick = NONE; void PluginSimulateMouseClick(int pluginButtonID) { - pluginSimulatedClick = pluginButtonID - 1; + pluginSimulatedClick = pluginButtonID - 1; } //============================================================================= @@ -45,226 +45,203 @@ void PluginSimulateMouseClick(int pluginButtonID) { #include "script/script_runtime.h" -RuntimeScriptValue Sc_PluginStub_Void(const RuntimeScriptValue *params, int32_t param_count) -{ - return RuntimeScriptValue((int32_t)0); +RuntimeScriptValue Sc_PluginStub_Void(const RuntimeScriptValue *params, int32_t param_count) { + return RuntimeScriptValue((int32_t)0); } -RuntimeScriptValue Sc_PluginStub_Int0(const RuntimeScriptValue *params, int32_t param_count) -{ - return RuntimeScriptValue().SetInt32(0); +RuntimeScriptValue Sc_PluginStub_Int0(const RuntimeScriptValue *params, int32_t param_count) { + return RuntimeScriptValue().SetInt32(0); } -RuntimeScriptValue Sc_PluginStub_IntNeg1(const RuntimeScriptValue *params, int32_t param_count) -{ - return RuntimeScriptValue().SetInt32(-1); +RuntimeScriptValue Sc_PluginStub_IntNeg1(const RuntimeScriptValue *params, int32_t param_count) { + return RuntimeScriptValue().SetInt32(-1); } -RuntimeScriptValue Sc_PluginStub_NullStr(const RuntimeScriptValue *params, int32_t param_count) -{ +RuntimeScriptValue Sc_PluginStub_NullStr(const RuntimeScriptValue *params, int32_t param_count) { return RuntimeScriptValue().SetStringLiteral(NULL); } -bool RegisterPluginStubs(const char* name) -{ - // Stubs for plugin functions. +bool RegisterPluginStubs(const char *name) { + // Stubs for plugin functions. - bool is_agsteam = (ags_stricmp(name, "agsteam") == 0) || (ags_stricmp(name, "agsteam-unified") == 0) || - (ags_stricmp(name, "agsteam-disjoint") == 0); - bool is_agsgalaxy = (ags_stricmp(name, "agsgalaxy") == 0) || (ags_stricmp(name, "agsgalaxy-unified") == 0) || - (ags_stricmp(name, "agsgalaxy-disjoint") == 0); + bool is_agsteam = (ags_stricmp(name, "agsteam") == 0) || (ags_stricmp(name, "agsteam-unified") == 0) || + (ags_stricmp(name, "agsteam-disjoint") == 0); + bool is_agsgalaxy = (ags_stricmp(name, "agsgalaxy") == 0) || (ags_stricmp(name, "agsgalaxy-unified") == 0) || + (ags_stricmp(name, "agsgalaxy-disjoint") == 0); - if (ags_stricmp(name, "ags_shell") == 0) - { - // ags_shell.dll - ccAddExternalStaticFunction("ShellExecute", Sc_PluginStub_Void); - return true; - } - else if (ags_stricmp(name, "ags_snowrain") == 0) - { - // ags_snowrain.dll - ccAddExternalStaticFunction("srSetSnowDriftRange", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowDriftSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowFallSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srChangeSnowAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowBaseline", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowTransparency", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowDefaultView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowWindSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srChangeRainAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainDefaultView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainTransparency", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainWindSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainBaseline", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainFallSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetWindSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetBaseline", Sc_PluginStub_Void); - return true; - } - else if (ags_stricmp(name, "agsjoy") == 0) - { - // agsjoy.dll - ccAddExternalStaticFunction("JoystickCount", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("JoystickName", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("JoystickRescan", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Open^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::IsOpen^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Click^1", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::Close^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::Valid^0", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Unplugged^0", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::GetName^0", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::GetAxis^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::IsButtonDown^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::IsJoyBtnDown^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Update^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::DisableEvents^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::EnableEvents^1", Sc_PluginStub_Void); - return true; - } - else if (ags_stricmp(name, "agsblend") == 0) - { - // agsblend.dll - ccAddExternalStaticFunction("DrawAlpha", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetAlpha", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("PutAlpha", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Blur", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("HighPass", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("DrawAdd", Sc_PluginStub_Int0); - return true; - } - else if (ags_stricmp(name, "agsflashlight") == 0) - { - // agsflashlight.dll - ccAddExternalStaticFunction("SetFlashlightTint", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightTintRed", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightTintGreen", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightTintBlue", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightMinLightLevel", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightMaxLightLevel", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightDarkness", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightDarkness", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightDarknessSize", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightDarknessSize", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightBrightness", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightBrightness", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightBrightnessSize", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightBrightnessSize", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightPosition", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightPositionX", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightPositionY", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightFollowMouse", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightFollowMouse", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightFollowCharacter", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightFollowCharacter", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterDX", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterDY", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterHorz", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterVert", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightMask", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightMask", Sc_PluginStub_Int0); - return true; - } - else if (ags_stricmp(name, "agswadjetutil") == 0) - { - // agswadjetutil.dll - ccAddExternalStaticFunction("IsOnPhone", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("FakeKeypress", Sc_PluginStub_Void); - ccAddExternalStaticFunction("IosSetAchievementValue", Sc_PluginStub_Void); - ccAddExternalStaticFunction("IosGetAchievementValue", Sc_PluginStub_IntNeg1); - ccAddExternalStaticFunction("IosShowAchievements", Sc_PluginStub_Void); - ccAddExternalStaticFunction("IosResetAchievements", Sc_PluginStub_Void); - ccAddExternalStaticFunction("MobileGetAchievement", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("MobileSetAchievement", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("MobileShowAchievements", Sc_PluginStub_Void); - ccAddExternalStaticFunction("MobileResetAchievements", Sc_PluginStub_Void); - return true; - } - else if (ags_stricmp(name, "agsspritefont") == 0) - { - ccAddExternalStaticFunction("SetSpriteFont", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetVariableSpriteFont", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetGlyph", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetSpacing", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetLineHeightAdjust", Sc_PluginStub_Void); - return true; - } - else if (is_agsteam || is_agsgalaxy) - { - // agsteam.dll or agsgalaxy.dll - ccAddExternalStaticFunction("AGS2Client::IsAchievementAchieved^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::SetAchievementAchieved^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::ResetAchievement^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::GetIntStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::GetFloatStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::GetAverageRateStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::SetIntStat^2", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::SetFloatStat^2", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::UpdateAverageRateStat^3", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::ResetStatsAndAchievements^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("AGS2Client::get_Initialized", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGS2Client::RequestLeaderboard^3", Sc_PluginStub_Void); - ccAddExternalStaticFunction("AGS2Client::UploadScore^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::geti_LeaderboardNames", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGS2Client::geti_LeaderboardScores", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::get_LeaderboardCount", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGS2Client::GetUserName^0", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGS2Client::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGS2Client::FindLeaderboard^1", Sc_PluginStub_Void); - ccAddExternalStaticFunction("AGS2Client::Initialize^2", Sc_PluginStub_Int0); - if (is_agsteam) - { - ccAddExternalStaticFunction("AGSteam::IsAchievementAchieved^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::SetAchievementAchieved^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::ResetAchievement^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::GetIntStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::GetFloatStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::GetAverageRateStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::SetIntStat^2", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::SetFloatStat^2", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::UpdateAverageRateStat^3", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::ResetStatsAndAchievements^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("AGSteam::get_Initialized", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSteam::RequestLeaderboard^3", Sc_PluginStub_Void); - ccAddExternalStaticFunction("AGSteam::UploadScore^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::geti_LeaderboardNames", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSteam::geti_LeaderboardScores", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::get_LeaderboardCount", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSteam::GetUserName^0", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSteam::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSteam::FindLeaderboard^1", Sc_PluginStub_Void); - } - else // agsgalaxy - { - ccAddExternalStaticFunction("AGSGalaxy::IsAchievementAchieved^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::SetAchievementAchieved^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::ResetAchievement^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::GetIntStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::GetFloatStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::GetAverageRateStat^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::SetIntStat^2", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::SetFloatStat^2", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::UpdateAverageRateStat^3", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::ResetStatsAndAchievements^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("AGSGalaxy::get_Initialized", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSGalaxy::RequestLeaderboard^3", Sc_PluginStub_Void); - ccAddExternalStaticFunction("AGSGalaxy::UploadScore^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::geti_LeaderboardNames", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSGalaxy::geti_LeaderboardScores", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::get_LeaderboardCount", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("AGSGalaxy::GetUserName^0", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSGalaxy::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); - ccAddExternalStaticFunction("AGSGalaxy::Initialize^2", Sc_PluginStub_Int0); - } - return true; - } + if (ags_stricmp(name, "ags_shell") == 0) { + // ags_shell.dll + ccAddExternalStaticFunction("ShellExecute", Sc_PluginStub_Void); + return true; + } else if (ags_stricmp(name, "ags_snowrain") == 0) { + // ags_snowrain.dll + ccAddExternalStaticFunction("srSetSnowDriftRange", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowDriftSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowFallSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srChangeSnowAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowBaseline", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowTransparency", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowDefaultView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srChangeRainAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainDefaultView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainTransparency", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainBaseline", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainFallSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetBaseline", Sc_PluginStub_Void); + return true; + } else if (ags_stricmp(name, "agsjoy") == 0) { + // agsjoy.dll + ccAddExternalStaticFunction("JoystickCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("JoystickName", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("JoystickRescan", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Open^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsOpen^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Click^1", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::Close^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::Valid^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Unplugged^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::GetName^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::GetAxis^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsButtonDown^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsJoyBtnDown^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Update^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::DisableEvents^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::EnableEvents^1", Sc_PluginStub_Void); + return true; + } else if (ags_stricmp(name, "agsblend") == 0) { + // agsblend.dll + ccAddExternalStaticFunction("DrawAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("PutAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Blur", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("HighPass", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("DrawAdd", Sc_PluginStub_Int0); + return true; + } else if (ags_stricmp(name, "agsflashlight") == 0) { + // agsflashlight.dll + ccAddExternalStaticFunction("SetFlashlightTint", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightTintRed", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightTintGreen", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightTintBlue", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightMinLightLevel", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightMaxLightLevel", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightDarkness", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightDarkness", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightDarknessSize", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightDarknessSize", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightBrightness", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightBrightness", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightBrightnessSize", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightBrightnessSize", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightPosition", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightPositionX", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightPositionY", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightFollowMouse", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightFollowMouse", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightFollowCharacter", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightFollowCharacter", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterDX", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterDY", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterHorz", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterVert", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightMask", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightMask", Sc_PluginStub_Int0); + return true; + } else if (ags_stricmp(name, "agswadjetutil") == 0) { + // agswadjetutil.dll + ccAddExternalStaticFunction("IsOnPhone", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("FakeKeypress", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosSetAchievementValue", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosGetAchievementValue", Sc_PluginStub_IntNeg1); + ccAddExternalStaticFunction("IosShowAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosResetAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("MobileGetAchievement", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("MobileSetAchievement", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("MobileShowAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("MobileResetAchievements", Sc_PluginStub_Void); + return true; + } else if (ags_stricmp(name, "agsspritefont") == 0) { + ccAddExternalStaticFunction("SetSpriteFont", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetVariableSpriteFont", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetGlyph", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetSpacing", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetLineHeightAdjust", Sc_PluginStub_Void); + return true; + } else if (is_agsteam || is_agsgalaxy) { + // agsteam.dll or agsgalaxy.dll + ccAddExternalStaticFunction("AGS2Client::IsAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::SetAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::ResetAchievement^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetIntStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetFloatStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetAverageRateStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::SetIntStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::SetFloatStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::UpdateAverageRateStat^3", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::ResetStatsAndAchievements^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGS2Client::get_Initialized", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::RequestLeaderboard^3", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGS2Client::UploadScore^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::geti_LeaderboardNames", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::geti_LeaderboardScores", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::get_LeaderboardCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGS2Client::GetUserName^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGS2Client::FindLeaderboard^1", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGS2Client::Initialize^2", Sc_PluginStub_Int0); + if (is_agsteam) { + ccAddExternalStaticFunction("AGSteam::IsAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::SetAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::ResetAchievement^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetIntStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetFloatStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetAverageRateStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::SetIntStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::SetFloatStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::UpdateAverageRateStat^3", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::ResetStatsAndAchievements^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSteam::get_Initialized", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::RequestLeaderboard^3", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSteam::UploadScore^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::geti_LeaderboardNames", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::geti_LeaderboardScores", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::get_LeaderboardCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSteam::GetUserName^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSteam::FindLeaderboard^1", Sc_PluginStub_Void); + } else { // agsgalaxy + ccAddExternalStaticFunction("AGSGalaxy::IsAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::SetAchievementAchieved^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::ResetAchievement^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetIntStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetFloatStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetAverageRateStat^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::SetIntStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::SetFloatStat^2", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::UpdateAverageRateStat^3", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::ResetStatsAndAchievements^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSGalaxy::get_Initialized", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::get_CurrentLeaderboardName", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::RequestLeaderboard^3", Sc_PluginStub_Void); + ccAddExternalStaticFunction("AGSGalaxy::UploadScore^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::geti_LeaderboardNames", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::geti_LeaderboardScores", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::get_LeaderboardCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("AGSGalaxy::GetUserName^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::GetCurrentGameLanguage^0", Sc_PluginStub_NullStr); + ccAddExternalStaticFunction("AGSGalaxy::Initialize^2", Sc_PluginStub_Int0); + } + return true; + } - return false; + return false; } diff --git a/engines/ags/engine/plugin/plugin_builtin.h b/engines/ags/engine/plugin/plugin_builtin.h index d5caec7bc263..d598609f02c0 100644 --- a/engines/ags/engine/plugin/plugin_builtin.h +++ b/engines/ags/engine/plugin/plugin_builtin.h @@ -38,12 +38,12 @@ using namespace AGS; // FIXME later // Initial implementation for apps to register their own inbuilt plugins struct InbuiltPluginDetails { - char filename[PLUGIN_FILENAME_MAX+1]; - void (*engineStartup) (IAGSEngine *); - void (*engineShutdown) (); - int (*onEvent) (int, int); - void (*initGfxHook) (const char *driverName, void *data); - int (*debugHook) (const char * whichscript, int lineNumber, int reserved); + char filename[PLUGIN_FILENAME_MAX + 1]; + void (*engineStartup)(IAGSEngine *); + void (*engineShutdown)(); + int (*onEvent)(int, int); + void (*initGfxHook)(const char *driverName, void *data); + int (*debugHook)(const char *whichscript, int lineNumber, int reserved); }; // Register a builtin plugin. diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/engine/plugin/plugin_engine.h index 9c6f1282e3b7..17aef598caef 100644 --- a/engines/ags/engine/plugin/plugin_engine.h +++ b/engines/ags/engine/plugin/plugin_engine.h @@ -36,14 +36,18 @@ #define PLUGIN_FILENAME_MAX (49) class IAGSEngine; -namespace AGS { namespace Common { class Stream; }} +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later void pl_stop_plugins(); void pl_startup_plugins(); -int pl_run_plugin_hooks (int event, int data); +int pl_run_plugin_hooks(int event, int data); void pl_run_plugin_init_gfx_hooks(const char *driverName, void *data); -int pl_run_plugin_debug_hooks (const char *scriptfile, int linenum); +int pl_run_plugin_debug_hooks(const char *scriptfile, int linenum); // Tries to register plugins, either by loading dynamic libraries, or getting any kind of replacement Engine::GameInitError pl_register_plugins(const std::vector &infos); bool pl_is_plugin_loaded(const char *pl_name); diff --git a/engines/ags/engine/plugin/pluginobjectreader.h b/engines/ags/engine/plugin/pluginobjectreader.h index a768ad00dcb0..e789c9172491 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.h +++ b/engines/ags/engine/plugin/pluginobjectreader.h @@ -26,8 +26,8 @@ class IAGSManagedObjectReader; struct PluginObjectReader { - IAGSManagedObjectReader *reader; - const char *type; + IAGSManagedObjectReader *reader; + const char *type; }; #endif diff --git a/engines/ags/engine/resource/resource.h b/engines/ags/engine/resource/resource.h index 84d5685e83f0..6014a0b56aef 100644 --- a/engines/ags/engine/resource/resource.h +++ b/engines/ags/engine/resource/resource.h @@ -57,7 +57,7 @@ #define IDC_CUSTOMSAVEDIRBTN 1041 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 109 diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index 75a2c37162da..9a7055135b10 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -51,117 +51,113 @@ using namespace AGS::Common::Memory; extern ccInstance *loadedInstances[MAX_LOADED_INSTANCES]; // in script/script_runtime extern int gameHasBeenRestored; // in ac/game -extern ExecutingScript*curscript; // in script/script +extern ExecutingScript *curscript; // in script/script extern int maxWhileLoops; extern new_line_hook_type new_line_hook; extern ScriptString myScriptStringImpl; -enum ScriptOpArgIsReg -{ - kScOpNoArgIsReg = 0, - kScOpArg1IsReg = 0x0001, - kScOpArg2IsReg = 0x0002, - kScOpArg3IsReg = 0x0004, - kScOpOneArgIsReg = kScOpArg1IsReg, - kScOpTwoArgsAreReg = kScOpArg1IsReg | kScOpArg2IsReg, - kScOpTreeArgsAreReg = kScOpArg1IsReg | kScOpArg2IsReg | kScOpArg3IsReg +enum ScriptOpArgIsReg { + kScOpNoArgIsReg = 0, + kScOpArg1IsReg = 0x0001, + kScOpArg2IsReg = 0x0002, + kScOpArg3IsReg = 0x0004, + kScOpOneArgIsReg = kScOpArg1IsReg, + kScOpTwoArgsAreReg = kScOpArg1IsReg | kScOpArg2IsReg, + kScOpTreeArgsAreReg = kScOpArg1IsReg | kScOpArg2IsReg | kScOpArg3IsReg }; -struct ScriptCommandInfo -{ - ScriptCommandInfo(int32_t code, const char *cmdname, int arg_count, ScriptOpArgIsReg arg_is_reg) - { - Code = code; - CmdName = cmdname; - ArgCount = arg_count; - ArgIsReg[0] = (arg_is_reg & kScOpArg1IsReg) != 0; - ArgIsReg[1] = (arg_is_reg & kScOpArg2IsReg) != 0; - ArgIsReg[2] = (arg_is_reg & kScOpArg3IsReg) != 0; - } - - int32_t Code; - const char *CmdName; - int ArgCount; - bool ArgIsReg[3]; +struct ScriptCommandInfo { + ScriptCommandInfo(int32_t code, const char *cmdname, int arg_count, ScriptOpArgIsReg arg_is_reg) { + Code = code; + CmdName = cmdname; + ArgCount = arg_count; + ArgIsReg[0] = (arg_is_reg & kScOpArg1IsReg) != 0; + ArgIsReg[1] = (arg_is_reg & kScOpArg2IsReg) != 0; + ArgIsReg[2] = (arg_is_reg & kScOpArg3IsReg) != 0; + } + + int32_t Code; + const char *CmdName; + int ArgCount; + bool ArgIsReg[3]; }; -const ScriptCommandInfo sccmd_info[CC_NUM_SCCMDS] = -{ - ScriptCommandInfo( 0 , "NULL" , 0, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_ADD , "addi" , 2, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_SUB , "subi" , 2, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_REGTOREG , "mov" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_WRITELIT , "memwritelit" , 2, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_RET , "ret" , 0, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_LITTOREG , "movl" , 2, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMREAD , "memread4" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMWRITE , "memwrite4" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MULREG , "mul" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_DIVREG , "div" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_ADDREG , "add" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_SUBREG , "sub" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_BITAND , "and" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_BITOR , "or" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_ISEQUAL , "cmpeq" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_NOTEQUAL , "cmpne" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_GREATER , "gt" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_LESSTHAN , "lt" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_GTE , "gte" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_LTE , "lte" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_AND , "land" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_OR , "lor" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_CALL , "call" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMREADB , "memread1" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMREADW , "memread2" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMWRITEB , "memwrite1" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMWRITEW , "memwrite2" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_JZ , "jzi" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_PUSHREG , "push" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_POPREG , "pop" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_JMP , "jmpi" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_MUL , "muli" , 2, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_CALLEXT , "farcall" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_PUSHREAL , "farpush" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_SUBREALSTACK , "farsubsp" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_LINENUM , "sourceline" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_CALLAS , "callscr" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_THISBASE , "thisaddr" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_NUMFUNCARGS , "setfuncargs" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_MODREG , "mod" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_XORREG , "xor" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_NOTREG , "not" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_SHIFTLEFT , "shl" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_SHIFTRIGHT , "shr" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_CALLOBJ , "callobj" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_CHECKBOUNDS , "checkbounds" , 2, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMWRITEPTR , "memwrite.ptr" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMREADPTR , "memread.ptr" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_MEMZEROPTR , "memwrite.ptr.0" , 0, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_MEMINITPTR , "meminit.ptr" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_LOADSPOFFS , "load.sp.offs" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_CHECKNULL , "checknull.ptr" , 0, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_FADD , "faddi" , 2, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_FSUB , "fsubi" , 2, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_FMULREG , "fmul" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_FDIVREG , "fdiv" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_FADDREG , "fadd" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_FSUBREG , "fsub" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_FGREATER , "fgt" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_FLESSTHAN , "flt" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_FGTE , "fgte" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_FLTE , "flte" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_ZEROMEMORY , "zeromem" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_CREATESTRING , "newstring" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_STRINGSEQUAL , "streq" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_STRINGSNOTEQ , "strne" , 2, kScOpTwoArgsAreReg ), - ScriptCommandInfo( SCMD_CHECKNULLREG , "checknull" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_LOOPCHECKOFF , "loopcheckoff" , 0, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_MEMZEROPTRND , "memwrite.ptr.0.nd" , 0, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_JNZ , "jnzi" , 1, kScOpNoArgIsReg ), - ScriptCommandInfo( SCMD_DYNAMICBOUNDS , "dynamicbounds" , 1, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_NEWARRAY , "newarray" , 3, kScOpOneArgIsReg ), - ScriptCommandInfo( SCMD_NEWUSEROBJECT , "newuserobject" , 2, kScOpOneArgIsReg ), +const ScriptCommandInfo sccmd_info[CC_NUM_SCCMDS] = { + ScriptCommandInfo(0 , "NULL" , 0, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_ADD , "addi" , 2, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_SUB , "subi" , 2, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_REGTOREG , "mov" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_WRITELIT , "memwritelit" , 2, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_RET , "ret" , 0, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_LITTOREG , "movl" , 2, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMREAD , "memread4" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMWRITE , "memwrite4" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MULREG , "mul" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_DIVREG , "div" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_ADDREG , "add" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_SUBREG , "sub" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_BITAND , "and" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_BITOR , "or" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_ISEQUAL , "cmpeq" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_NOTEQUAL , "cmpne" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_GREATER , "gt" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_LESSTHAN , "lt" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_GTE , "gte" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_LTE , "lte" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_AND , "land" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_OR , "lor" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_CALL , "call" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMREADB , "memread1" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMREADW , "memread2" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMWRITEB , "memwrite1" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMWRITEW , "memwrite2" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_JZ , "jzi" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_PUSHREG , "push" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_POPREG , "pop" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_JMP , "jmpi" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_MUL , "muli" , 2, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_CALLEXT , "farcall" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_PUSHREAL , "farpush" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_SUBREALSTACK , "farsubsp" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_LINENUM , "sourceline" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_CALLAS , "callscr" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_THISBASE , "thisaddr" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_NUMFUNCARGS , "setfuncargs" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_MODREG , "mod" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_XORREG , "xor" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_NOTREG , "not" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_SHIFTLEFT , "shl" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_SHIFTRIGHT , "shr" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_CALLOBJ , "callobj" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_CHECKBOUNDS , "checkbounds" , 2, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMWRITEPTR , "memwrite.ptr" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMREADPTR , "memread.ptr" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_MEMZEROPTR , "memwrite.ptr.0" , 0, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_MEMINITPTR , "meminit.ptr" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_LOADSPOFFS , "load.sp.offs" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_CHECKNULL , "checknull.ptr" , 0, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_FADD , "faddi" , 2, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_FSUB , "fsubi" , 2, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_FMULREG , "fmul" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_FDIVREG , "fdiv" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_FADDREG , "fadd" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_FSUBREG , "fsub" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_FGREATER , "fgt" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_FLESSTHAN , "flt" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_FGTE , "fgte" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_FLTE , "flte" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_ZEROMEMORY , "zeromem" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_CREATESTRING , "newstring" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_STRINGSEQUAL , "streq" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_STRINGSNOTEQ , "strne" , 2, kScOpTwoArgsAreReg), + ScriptCommandInfo(SCMD_CHECKNULLREG , "checknull" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_LOOPCHECKOFF , "loopcheckoff" , 0, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_MEMZEROPTRND , "memwrite.ptr.0.nd" , 0, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_JNZ , "jnzi" , 1, kScOpNoArgIsReg), + ScriptCommandInfo(SCMD_DYNAMICBOUNDS , "dynamicbounds" , 1, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_NEWARRAY , "newarray" , 3, kScOpOneArgIsReg), + ScriptCommandInfo(SCMD_NEWUSEROBJECT , "newuserobject" , 2, kScOpOneArgIsReg), }; const char *regnames[] = { "null", "sp", "mar", "ax", "bx", "cx", "op", "dx" }; @@ -179,1604 +175,1448 @@ RuntimeScriptValue GlobalReturnValue; // values before passing them to script function #define MAX_FUNC_PARAMS 20 // An inverted parameter stack -struct FunctionCallStack -{ - FunctionCallStack() - { - Head = MAX_FUNC_PARAMS - 1; - Count = 0; - } - - inline RuntimeScriptValue *GetHead() - { - return &Entries[Head]; - } - inline RuntimeScriptValue *GetTail() - { - return &Entries[Head + Count]; - } - - RuntimeScriptValue Entries[MAX_FUNC_PARAMS + 1]; - int Head; - int Count; +struct FunctionCallStack { + FunctionCallStack() { + Head = MAX_FUNC_PARAMS - 1; + Count = 0; + } + + inline RuntimeScriptValue *GetHead() { + return &Entries[Head]; + } + inline RuntimeScriptValue *GetTail() { + return &Entries[Head + Count]; + } + + RuntimeScriptValue Entries[MAX_FUNC_PARAMS + 1]; + int Head; + int Count; }; -ccInstance *ccInstance::GetCurrentInstance() -{ - return current_instance; +ccInstance *ccInstance::GetCurrentInstance() { + return current_instance; } -ccInstance *ccInstance::CreateFromScript(PScript scri) -{ - return CreateEx(scri, nullptr); +ccInstance *ccInstance::CreateFromScript(PScript scri) { + return CreateEx(scri, nullptr); } -ccInstance *ccInstance::CreateEx(PScript scri, ccInstance * joined) -{ - // allocate and copy all the memory with data, code and strings across - ccInstance *cinst = new ccInstance(); - if (!cinst->_Create(scri, joined)) - { - delete cinst; - return nullptr; - } +ccInstance *ccInstance::CreateEx(PScript scri, ccInstance *joined) { + // allocate and copy all the memory with data, code and strings across + ccInstance *cinst = new ccInstance(); + if (!cinst->_Create(scri, joined)) { + delete cinst; + return nullptr; + } - return cinst; + return cinst; } -ccInstance::ccInstance() -{ - flags = 0; - globaldata = nullptr; - globaldatasize = 0; - code = nullptr; - runningInst = nullptr; - codesize = 0; - strings = nullptr; - stringssize = 0; - exports = nullptr; - stack = nullptr; - num_stackentries = 0; - stackdata = nullptr; - stackdatasize = 0; - stackdata_ptr = nullptr; - pc = 0; - line_number = 0; - callStackSize = 0; - loadedInstanceId = 0; - returnValue = 0; - numimports = 0; - resolved_imports = nullptr; - code_fixups = nullptr; - - memset(callStackLineNumber, 0, sizeof(callStackLineNumber)); - memset(callStackAddr, 0, sizeof(callStackAddr)); - memset(callStackCodeInst, 0, sizeof(callStackCodeInst)); +ccInstance::ccInstance() { + flags = 0; + globaldata = nullptr; + globaldatasize = 0; + code = nullptr; + runningInst = nullptr; + codesize = 0; + strings = nullptr; + stringssize = 0; + exports = nullptr; + stack = nullptr; + num_stackentries = 0; + stackdata = nullptr; + stackdatasize = 0; + stackdata_ptr = nullptr; + pc = 0; + line_number = 0; + callStackSize = 0; + loadedInstanceId = 0; + returnValue = 0; + numimports = 0; + resolved_imports = nullptr; + code_fixups = nullptr; + + memset(callStackLineNumber, 0, sizeof(callStackLineNumber)); + memset(callStackAddr, 0, sizeof(callStackAddr)); + memset(callStackCodeInst, 0, sizeof(callStackCodeInst)); } -ccInstance::~ccInstance() -{ - Free(); +ccInstance::~ccInstance() { + Free(); } -ccInstance *ccInstance::Fork() -{ - return CreateEx(instanceof, this); +ccInstance *ccInstance::Fork() { + return CreateEx(instanceof, this); } -void ccInstance::Abort() -{ - if ((this != nullptr) && (pc != 0)) - flags |= INSTF_ABORTED; +void ccInstance::Abort() { + if ((this != nullptr) && (pc != 0)) + flags |= INSTF_ABORTED; } -void ccInstance::AbortAndDestroy() -{ - if (this != nullptr) { - Abort(); - flags |= INSTF_FREE; - } +void ccInstance::AbortAndDestroy() { + if (this != nullptr) { + Abort(); + flags |= INSTF_FREE; + } } #define ASSERT_STACK_SPACE_AVAILABLE(N) \ - if (registers[SREG_SP].RValue + N - &stack[0] >= CC_STACK_SIZE) \ - { \ - cc_error("stack overflow"); \ - return -1; \ - } + if (registers[SREG_SP].RValue + N - &stack[0] >= CC_STACK_SIZE) \ + { \ + cc_error("stack overflow"); \ + return -1; \ + } #define ASSERT_STACK_SIZE(N) \ - if (registers[SREG_SP].RValue - N < &stack[0]) \ - { \ - cc_error("stack underflow"); \ - return -1; \ - } - -int ccInstance::CallScriptFunction(const char *funcname, int32_t numargs, const RuntimeScriptValue *params) -{ - ccError = 0; - currentline = 0; - - if (numargs > 0 && !params) - { - cc_error("internal error in ccInstance::CallScriptFunction"); - return -1; // TODO: correct error value - } - - if ((numargs >= 20) || (numargs < 0)) { - cc_error("too many arguments to function"); - return -3; - } - - if (pc != 0) { - cc_error("instance already being executed"); - return -4; - } - - int32_t startat = -1; - int k; - char mangledName[200]; - sprintf(mangledName, "%s$", funcname); - - for (k = 0; k < instanceof->numexports; k++) { - char *thisExportName = instanceof->exports[k]; - int match = 0; - - // check for a mangled name match - if (strncmp(thisExportName, mangledName, strlen(mangledName)) == 0) { - // found, compare the number of parameters - char *numParams = thisExportName + strlen(mangledName); - if (atoi(numParams) != numargs) { - cc_error("wrong number of parameters to exported function '%s' (expected %d, supplied %d)", funcname, atoi(numParams), numargs); - return -1; - } - match = 1; - } - // check for an exact match (if the script was compiled with - // an older version) - if ((match == 1) || (strcmp(thisExportName, funcname) == 0)) { - int32_t etype = (instanceof->export_addr[k] >> 24L) & 0x000ff; - if (etype != EXPORT_FUNCTION) { - cc_error("symbol is not a function"); - return -1; - } - startat = (instanceof->export_addr[k] & 0x00ffffff); - break; - } - } - - if (startat < 0) { - cc_error("function '%s' not found", funcname); - return -2; - } - - //numargs++; // account for return address - flags &= ~INSTF_ABORTED; - - // object pointer needs to start zeroed - registers[SREG_OP].SetDynamicObject(nullptr, nullptr); - - ccInstance* currentInstanceWas = current_instance; - registers[SREG_SP].SetStackPtr( &stack[0] ); - stackdata_ptr = stackdata; - // NOTE: Pushing parameters to stack in reverse order - ASSERT_STACK_SPACE_AVAILABLE(numargs + 1 /* return address */) - for (int i = numargs - 1; i >= 0; --i) - { - PushValueToStack(params[i]); - } - PushValueToStack(RuntimeScriptValue().SetInt32(0)); // return address on stack - if (ccError) - { - return -1; - } - runningInst = this; - - int reterr = Run(startat); - ASSERT_STACK_SIZE(numargs); - PopValuesFromStack(numargs); - pc = 0; - current_instance = currentInstanceWas; - - // NOTE that if proper multithreading is added this will need - // to be reconsidered, since the GC could be run in the middle - // of a RET from a function or something where there is an - // object with ref count 0 that is in use - pool.RunGarbageCollectionIfAppropriate(); - - if (new_line_hook) - new_line_hook(nullptr, 0); - - if (reterr) - return -6; - - if (flags & INSTF_ABORTED) { - flags &= ~INSTF_ABORTED; - - if (flags & INSTF_FREE) - Free(); - return 100; - } - - if (registers[SREG_SP].RValue != &stack[0]) { - cc_error("stack pointer was not zero at completion of script"); - return -5; - } - return ccError; + if (registers[SREG_SP].RValue - N < &stack[0]) \ + { \ + cc_error("stack underflow"); \ + return -1; \ + } + +int ccInstance::CallScriptFunction(const char *funcname, int32_t numargs, const RuntimeScriptValue *params) { + ccError = 0; + currentline = 0; + + if (numargs > 0 && !params) { + cc_error("internal error in ccInstance::CallScriptFunction"); + return -1; // TODO: correct error value + } + + if ((numargs >= 20) || (numargs < 0)) { + cc_error("too many arguments to function"); + return -3; + } + + if (pc != 0) { + cc_error("instance already being executed"); + return -4; + } + + int32_t startat = -1; + int k; + char mangledName[200]; + sprintf(mangledName, "%s$", funcname); + + for (k = 0; k < instanceof->numexports; k++) { + char *thisExportName = instanceof->exports[k]; + int match = 0; + + // check for a mangled name match + if (strncmp(thisExportName, mangledName, strlen(mangledName)) == 0) { + // found, compare the number of parameters + char *numParams = thisExportName + strlen(mangledName); + if (atoi(numParams) != numargs) { + cc_error("wrong number of parameters to exported function '%s' (expected %d, supplied %d)", funcname, atoi(numParams), numargs); + return -1; + } + match = 1; + } + // check for an exact match (if the script was compiled with + // an older version) + if ((match == 1) || (strcmp(thisExportName, funcname) == 0)) { + int32_t etype = (instanceof->export_addr[k] >> 24L) & 0x000ff; + if (etype != EXPORT_FUNCTION) { + cc_error("symbol is not a function"); + return -1; + } + startat = (instanceof->export_addr[k] & 0x00ffffff); + break; + } + } + + if (startat < 0) { + cc_error("function '%s' not found", funcname); + return -2; + } + + //numargs++; // account for return address + flags &= ~INSTF_ABORTED; + + // object pointer needs to start zeroed + registers[SREG_OP].SetDynamicObject(nullptr, nullptr); + + ccInstance *currentInstanceWas = current_instance; + registers[SREG_SP].SetStackPtr(&stack[0]); + stackdata_ptr = stackdata; + // NOTE: Pushing parameters to stack in reverse order + ASSERT_STACK_SPACE_AVAILABLE(numargs + 1 /* return address */) + for (int i = numargs - 1; i >= 0; --i) { + PushValueToStack(params[i]); + } + PushValueToStack(RuntimeScriptValue().SetInt32(0)); // return address on stack + if (ccError) { + return -1; + } + runningInst = this; + + int reterr = Run(startat); + ASSERT_STACK_SIZE(numargs); + PopValuesFromStack(numargs); + pc = 0; + current_instance = currentInstanceWas; + + // NOTE that if proper multithreading is added this will need + // to be reconsidered, since the GC could be run in the middle + // of a RET from a function or something where there is an + // object with ref count 0 that is in use + pool.RunGarbageCollectionIfAppropriate(); + + if (new_line_hook) + new_line_hook(nullptr, 0); + + if (reterr) + return -6; + + if (flags & INSTF_ABORTED) { + flags &= ~INSTF_ABORTED; + + if (flags & INSTF_FREE) + Free(); + return 100; + } + + if (registers[SREG_SP].RValue != &stack[0]) { + cc_error("stack pointer was not zero at completion of script"); + return -5; + } + return ccError; } // Macros to maintain the call stack #define PUSH_CALL_STACK \ - if (callStackSize >= MAX_CALL_STACK) { \ - cc_error("CallScriptFunction stack overflow (recursive call error?)"); \ - return -1; \ - } \ - callStackLineNumber[callStackSize] = line_number; \ - callStackCodeInst[callStackSize] = runningInst; \ - callStackAddr[callStackSize] = pc; \ - callStackSize++ + if (callStackSize >= MAX_CALL_STACK) { \ + cc_error("CallScriptFunction stack overflow (recursive call error?)"); \ + return -1; \ + } \ + callStackLineNumber[callStackSize] = line_number; \ + callStackCodeInst[callStackSize] = runningInst; \ + callStackAddr[callStackSize] = pc; \ + callStackSize++ #define POP_CALL_STACK \ - if (callStackSize < 1) { \ - cc_error("CallScriptFunction stack underflow -- internal error"); \ - return -1; \ - } \ - callStackSize--;\ - line_number = callStackLineNumber[callStackSize];\ - currentline = line_number + if (callStackSize < 1) { \ + cc_error("CallScriptFunction stack underflow -- internal error"); \ + return -1; \ + } \ + callStackSize--;\ + line_number = callStackLineNumber[callStackSize];\ + currentline = line_number #define MAXNEST 50 // number of recursive function calls allowed -int ccInstance::Run(int32_t curpc) -{ - pc = curpc; - returnValue = -1; - - if ((curpc < 0) || (curpc >= runningInst->codesize)) { - cc_error("specified code offset is not valid"); - return -1; - } - - int32_t thisbase[MAXNEST], funcstart[MAXNEST]; - int was_just_callas = -1; - int curnest = 0; - int loopIterations = 0; - int num_args_to_func = -1; - int next_call_needs_object = 0; - int loopIterationCheckDisabled = 0; - thisbase[0] = 0; - funcstart[0] = pc; - current_instance = this; - ccInstance *codeInst = runningInst; - int write_debug_dump = ccGetOption(SCOPT_DEBUGRUN); +int ccInstance::Run(int32_t curpc) { + pc = curpc; + returnValue = -1; + + if ((curpc < 0) || (curpc >= runningInst->codesize)) { + cc_error("specified code offset is not valid"); + return -1; + } + + int32_t thisbase[MAXNEST], funcstart[MAXNEST]; + int was_just_callas = -1; + int curnest = 0; + int loopIterations = 0; + int num_args_to_func = -1; + int next_call_needs_object = 0; + int loopIterationCheckDisabled = 0; + thisbase[0] = 0; + funcstart[0] = pc; + current_instance = this; + ccInstance *codeInst = runningInst; + int write_debug_dump = ccGetOption(SCOPT_DEBUGRUN); ScriptOperation codeOp; - FunctionCallStack func_callstack; + FunctionCallStack func_callstack; - while (1) { + while (1) { - /* + /* if (!codeInst->ReadOperation(codeOp, pc)) - { - return -1; - } - */ - /* ReadOperation */ - //===================================================================== - codeOp.Instruction.Code = codeInst->code[pc]; - codeOp.Instruction.InstanceId = (codeOp.Instruction.Code >> INSTANCE_ID_SHIFT) & INSTANCE_ID_MASK; - codeOp.Instruction.Code &= INSTANCE_ID_REMOVEMASK; // now this is pure instruction code - - if (codeOp.Instruction.Code < 0 || codeOp.Instruction.Code >= CC_NUM_SCCMDS) - { - cc_error("invalid instruction %d found in code stream", codeOp.Instruction.Code); - return -1; - } - - codeOp.ArgCount = sccmd_info[codeOp.Instruction.Code].ArgCount; - if (pc + codeOp.ArgCount >= codeInst->codesize) - { - cc_error("unexpected end of code data (%d; %d)", pc + codeOp.ArgCount, codeInst->codesize); - return -1; - } - - int pc_at = pc + 1; - for (int i = 0; i < codeOp.ArgCount; ++i, ++pc_at) - { - char fixup = codeInst->code_fixups[pc_at]; - if (fixup > 0) - { - // could be relative pointer or import address - /* - if (!FixupArgument(code[pc], fixup, codeOp.Args[i])) - { - return -1; - } - */ - /* FixupArgument */ - //===================================================================== - switch (fixup) - { - case FIXUP_GLOBALDATA: - { - ScriptVariable *gl_var = (ScriptVariable*)codeInst->code[pc_at]; - codeOp.Args[i].SetGlobalVar(&gl_var->RValue); - } - break; - case FIXUP_FUNCTION: - // originally commented -- CHECKME: could this be used in very old versions of AGS? - // code[fixup] += (long)&code[0]; - // This is a program counter value, presumably will be used as SCMD_CALL argument - codeOp.Args[i].SetInt32((int32_t)codeInst->code[pc_at]); - break; - case FIXUP_STRING: - codeOp.Args[i].SetStringLiteral(&codeInst->strings[0] + codeInst->code[pc_at]); - break; - case FIXUP_IMPORT: - { - const ScriptImport *import = simp.getByIndex((int32_t)codeInst->code[pc_at]); - if (import) - { - codeOp.Args[i] = import->Value; - } - else - { - cc_error("cannot resolve import, key = %ld", codeInst->code[pc_at]); - return -1; - } - } - break; - case FIXUP_STACK: - codeOp.Args[i] = GetStackPtrOffsetFw((int32_t)codeInst->code[pc_at]); - break; - default: - cc_error("internal fixup type error: %d", fixup); - return -1; - } - /* End FixupArgument */ - //===================================================================== - } - else - { - // should be a numeric literal (int32 or float) - codeOp.Args[i].SetInt32( (int32_t)codeInst->code[pc_at] ); - } - } - /* End ReadOperation */ - //===================================================================== - - // save the arguments for quick access - RuntimeScriptValue &arg1 = codeOp.Args[0]; - RuntimeScriptValue &arg2 = codeOp.Args[1]; - RuntimeScriptValue &arg3 = codeOp.Args[2]; - RuntimeScriptValue ®1 = - registers[arg1.IValue >= 0 && arg1.IValue < CC_NUM_REGISTERS ? arg1.IValue : 0]; - RuntimeScriptValue ®2 = - registers[arg2.IValue >= 0 && arg2.IValue < CC_NUM_REGISTERS ? arg2.IValue : 0]; - - const char *direct_ptr1; - const char *direct_ptr2; - - if (write_debug_dump) - { - DumpInstruction(codeOp); - } - - switch (codeOp.Instruction.Code) { - case SCMD_LINENUM: - line_number = arg1.IValue; - currentline = arg1.IValue; - if (new_line_hook) - new_line_hook(this, currentline); - break; - case SCMD_ADD: - // If the the register is SREG_SP, we are allocating new variable on the stack - if (arg1.IValue == SREG_SP) - { - // Only allocate new data if current stack entry is invalid; - // in some cases this may be advancing over value that was written by MEMWRITE* - ASSERT_STACK_SPACE_AVAILABLE(1); - if (reg1.RValue->IsValid()) - { - // TODO: perhaps should add a flag here to ensure this happens only after MEMWRITE-ing to stack - registers[SREG_SP].RValue++; - } - else - { - PushDataToStack(arg2.IValue); - if (ccError) - { - return -1; - } - } - } - else - { - reg1.IValue += arg2.IValue; - } - break; - case SCMD_SUB: - if (reg1.Type == kScValStackPtr) - { - // If this is SREG_SP, this is stack pop, which frees local variables; - // Other than SREG_SP this may be AGS 2.x method to offset stack in SREG_MAR; - // quote JJS: - // // AGS 2.x games also perform relative stack access by copying SREG_SP to SREG_MAR - // // and then subtracting from that. - if (arg1.IValue == SREG_SP) - { - PopDataFromStack(arg2.IValue); - } - else - { - // This is practically LOADSPOFFS - reg1 = GetStackPtrOffsetRw(arg2.IValue); - } - if (ccError) - { - return -1; - } - } - else - { - reg1.IValue -= arg2.IValue; - } - break; - case SCMD_REGTOREG: - reg2 = reg1; - break; - case SCMD_WRITELIT: - // Take the data address from reg[MAR] and copy there arg1 bytes from arg2 address - // - // NOTE: since it reads directly from arg2 (which originally was - // long, or rather int32 due x32 build), written value may normally - // be only up to 4 bytes large; - // I guess that's an obsolete way to do WRITE, WRITEW and WRITEB - switch (arg1.IValue) - { - case sizeof(char): - registers[SREG_MAR].WriteByte(arg2.IValue); - break; - case sizeof(int16_t): - registers[SREG_MAR].WriteInt16(arg2.IValue); - break; - case sizeof(int32_t): - // We do not know if this is math integer or some pointer, etc - registers[SREG_MAR].WriteValue(arg2); - break; - default: - cc_error("unexpected data size for WRITELIT op: %d", arg1.IValue); - break; - } - break; - case SCMD_RET: - { - if (loopIterationCheckDisabled > 0) - loopIterationCheckDisabled--; - - ASSERT_STACK_SIZE(1); - RuntimeScriptValue rval = PopValueFromStack(); - curnest--; - pc = rval.IValue; - if (pc == 0) - { - returnValue = registers[SREG_AX].IValue; - return 0; - } - current_instance = this; - POP_CALL_STACK; - continue; // continue so that the PC doesn't get overwritten - } - case SCMD_LITTOREG: - reg1 = arg2; - break; - case SCMD_MEMREAD: - // Take the data address from reg[MAR] and copy int32_t to reg[arg1] - reg1 = registers[SREG_MAR].ReadValue(); - break; - case SCMD_MEMWRITE: - // Take the data address from reg[MAR] and copy there int32_t from reg[arg1] - registers[SREG_MAR].WriteValue(reg1); - break; - case SCMD_LOADSPOFFS: - registers[SREG_MAR] = GetStackPtrOffsetRw(arg1.IValue); - if (ccError) - { - return -1; - } - break; - - // 64 bit: Force 32 bit math - case SCMD_MULREG: - reg1.SetInt32(reg1.IValue * reg2.IValue); - break; - case SCMD_DIVREG: - if (reg2.IValue == 0) { - cc_error("!Integer divide by zero"); - return -1; - } - reg1.SetInt32(reg1.IValue / reg2.IValue); - break; - case SCMD_ADDREG: - // This may be pointer arithmetics, in which case IValue stores offset from base pointer - reg1.IValue += reg2.IValue; - break; - case SCMD_SUBREG: - // This may be pointer arithmetics, in which case IValue stores offset from base pointer - reg1.IValue -= reg2.IValue; - break; - case SCMD_BITAND: - reg1.SetInt32(reg1.IValue & reg2.IValue); - break; - case SCMD_BITOR: - reg1.SetInt32(reg1.IValue | reg2.IValue); - break; - case SCMD_ISEQUAL: - reg1.SetInt32AsBool(reg1 == reg2); - break; - case SCMD_NOTEQUAL: - reg1.SetInt32AsBool(reg1 != reg2); - break; - case SCMD_GREATER: - reg1.SetInt32AsBool(reg1.IValue > reg2.IValue); - break; - case SCMD_LESSTHAN: - reg1.SetInt32AsBool(reg1.IValue < reg2.IValue); - break; - case SCMD_GTE: - reg1.SetInt32AsBool(reg1.IValue >= reg2.IValue); - break; - case SCMD_LTE: - reg1.SetInt32AsBool(reg1.IValue <= reg2.IValue); - break; - case SCMD_AND: - reg1.SetInt32AsBool(reg1.IValue && reg2.IValue); - break; - case SCMD_OR: - reg1.SetInt32AsBool(reg1.IValue || reg2.IValue); - break; - case SCMD_XORREG: - reg1.SetInt32(reg1.IValue ^ reg2.IValue); - break; - case SCMD_MODREG: - if (reg2.IValue == 0) { - cc_error("!Integer divide by zero"); - return -1; - } - reg1.SetInt32(reg1.IValue % reg2.IValue); - break; - case SCMD_NOTREG: - reg1 = !(reg1); - break; - case SCMD_CALL: - // CallScriptFunction another function within same script, just save PC - // and continue from there - if (curnest >= MAXNEST - 1) { - cc_error("!call stack overflow, recursive call problem?"); - return -1; - } - - PUSH_CALL_STACK; - - ASSERT_STACK_SPACE_AVAILABLE(1); - PushValueToStack(RuntimeScriptValue().SetInt32(pc + codeOp.ArgCount + 1)); - if (ccError) - { - return -1; - } - - if (thisbase[curnest] == 0) - pc = reg1.IValue; - else { - pc = funcstart[curnest]; - pc += (reg1.IValue - thisbase[curnest]); - } - - next_call_needs_object = 0; - - if (loopIterationCheckDisabled) - loopIterationCheckDisabled++; - - curnest++; - thisbase[curnest] = 0; - funcstart[curnest] = pc; - continue; // continue so that the PC doesn't get overwritten - case SCMD_MEMREADB: - // Take the data address from reg[MAR] and copy byte to reg[arg1] - reg1.SetUInt8(registers[SREG_MAR].ReadByte()); - break; - case SCMD_MEMREADW: - // Take the data address from reg[MAR] and copy int16_t to reg[arg1] - reg1.SetInt16(registers[SREG_MAR].ReadInt16()); - break; - case SCMD_MEMWRITEB: - // Take the data address from reg[MAR] and copy there byte from reg[arg1] - registers[SREG_MAR].WriteByte(reg1.IValue); - break; - case SCMD_MEMWRITEW: - // Take the data address from reg[MAR] and copy there int16_t from reg[arg1] - registers[SREG_MAR].WriteInt16(reg1.IValue); - break; - case SCMD_JZ: - if (registers[SREG_AX].IsNull()) - pc += arg1.IValue; - break; - case SCMD_JNZ: - if (!registers[SREG_AX].IsNull()) - pc += arg1.IValue; - break; - case SCMD_PUSHREG: - // Push reg[arg1] value to the stack - ASSERT_STACK_SPACE_AVAILABLE(1); - PushValueToStack(reg1); - if (ccError) - { - return -1; - } - break; - case SCMD_POPREG: - ASSERT_STACK_SIZE(1); - reg1 = PopValueFromStack(); - break; - case SCMD_JMP: - pc += arg1.IValue; - - if ((arg1.IValue < 0) && (maxWhileLoops > 0) && (loopIterationCheckDisabled == 0)) { - // Make sure it's not stuck in a While loop - loopIterations ++; - if (flags & INSTF_RUNNING) { - loopIterations = 0; - flags &= ~INSTF_RUNNING; - } - else if (loopIterations > maxWhileLoops) { - cc_error("!Script appears to be hung (a while loop ran %d times). The problem may be in a calling function; check the call stack.", loopIterations); - return -1; - } - } - break; - case SCMD_MUL: - reg1.IValue *= arg2.IValue; - break; - case SCMD_CHECKBOUNDS: - if ((reg1.IValue < 0) || - (reg1.IValue >= arg2.IValue)) { - cc_error("!Array index out of bounds (index: %d, bounds: 0..%d)", reg1.IValue, arg2.IValue - 1); - return -1; - } - break; - case SCMD_DYNAMICBOUNDS: - { - // TODO: test reg[MAR] type here; - // That might be dynamic object, but also a non-managed dynamic array, "allocated" - // on global or local memspace (buffer) - int32_t upperBoundInBytes = *((int32_t *)(registers[SREG_MAR].GetPtrWithOffset() - 4)); - if ((reg1.IValue < 0) || - (reg1.IValue >= upperBoundInBytes)) { - int32_t upperBound = *((int32_t *)(registers[SREG_MAR].GetPtrWithOffset() - 8)) & (~ARRAY_MANAGED_TYPE_FLAG); - if (upperBound <= 0) - { - cc_error("!Array has an invalid size (%d) and cannot be accessed", upperBound); - } - else - { - int elementSize = (upperBoundInBytes / upperBound); - cc_error("!Array index out of bounds (index: %d, bounds: 0..%d)", reg1.IValue / elementSize, upperBound - 1); - } - return -1; - } - break; - } - - // 64 bit: Handles are always 32 bit values. They are not C pointer. - - case SCMD_MEMREADPTR: { - ccError = 0; - - int32_t handle = registers[SREG_MAR].ReadInt32(); - void *object; - ICCDynamicObject *manager; - ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(handle, object, manager); - if (obj_type == kScValPluginObject) - { - reg1.SetPluginObject( object, manager ); - } - else - { - reg1.SetDynamicObject( object, manager ); - } - - // if error occurred, cc_error will have been set - if (ccError) - return -1; - break; } - case SCMD_MEMWRITEPTR: { - - int32_t handle = registers[SREG_MAR].ReadInt32(); - char *address = nullptr; - - if (reg1.Type == kScValStaticArray && reg1.StcArr->GetDynamicManager()) - { - address = (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); - } - else if (reg1.Type == kScValDynamicObject || - reg1.Type == kScValPluginObject) - { - address = reg1.Ptr; - } - else if (reg1.Type == kScValPluginArg) - {// TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems - address = Int32ToPtr(reg1.IValue); - } - // There's one possible case when the reg1 is 0, which means writing nullptr - else if (!reg1.IsNull()) - { - cc_error("internal error: MEMWRITEPTR argument is not dynamic object"); - return -1; - } - - int32_t newHandle = ccGetObjectHandleFromAddress(address); - if (newHandle == -1) - return -1; - - if (handle != newHandle) { - ccReleaseObjectReference(handle); - ccAddObjectReference(newHandle); - registers[SREG_MAR].WriteInt32(newHandle); - } - break; - } - case SCMD_MEMINITPTR: { - char *address = nullptr; - - if (reg1.Type == kScValStaticArray && reg1.StcArr->GetDynamicManager()) - { - address = (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); - } - else if (reg1.Type == kScValDynamicObject || - reg1.Type == kScValPluginObject) - { - address = reg1.Ptr; - } - else if (reg1.Type == kScValPluginArg) - {// TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems - address = Int32ToPtr(reg1.IValue); - } - // There's one possible case when the reg1 is 0, which means writing nullptr - else if (!reg1.IsNull()) - { - cc_error("internal error: SCMD_MEMINITPTR argument is not dynamic object"); - return -1; - } - // like memwriteptr, but doesn't attempt to free the old one - int32_t newHandle = ccGetObjectHandleFromAddress(address); - if (newHandle == -1) - return -1; - - ccAddObjectReference(newHandle); - registers[SREG_MAR].WriteInt32(newHandle); - break; - } - case SCMD_MEMZEROPTR: { - int32_t handle = registers[SREG_MAR].ReadInt32(); - ccReleaseObjectReference(handle); - registers[SREG_MAR].WriteInt32(0); - break; - } - case SCMD_MEMZEROPTRND: { - int32_t handle = registers[SREG_MAR].ReadInt32(); - - // don't do the Dispose check for the object being returned -- this is - // for returning a String (or other pointer) from a custom function. - // Note: we might be freeing a dynamic array which contains the DisableDispose - // object, that will be handled inside the recursive call to SubRef. - // CHECKME!! what type of data may reg1 point to? - pool.disableDisposeForObject = (const char*)registers[SREG_AX].Ptr; - ccReleaseObjectReference(handle); - pool.disableDisposeForObject = nullptr; - registers[SREG_MAR].WriteInt32(0); - break; - } - case SCMD_CHECKNULL: - if (registers[SREG_MAR].IsNull()) { - cc_error("!Null pointer referenced"); - return -1; - } - break; - case SCMD_CHECKNULLREG: - if (reg1.IsNull()) { - cc_error("!Null string referenced"); - return -1; - } - break; - case SCMD_NUMFUNCARGS: - num_args_to_func = arg1.IValue; - break; - case SCMD_CALLAS:{ - PUSH_CALL_STACK; - - // CallScriptFunction to a function in another script - - // If there are nested CALLAS calls, the stack might - // contain 2 calls worth of parameters, so only - // push args for this call - if (num_args_to_func < 0) - { - num_args_to_func = func_callstack.Count; - } - ASSERT_STACK_SPACE_AVAILABLE(num_args_to_func + 1 /* return address */); - for (const RuntimeScriptValue *prval = func_callstack.GetHead() + num_args_to_func; - prval > func_callstack.GetHead(); --prval) - { - PushValueToStack(*prval); - } - - // 0, so that the cc_run_code returns - RuntimeScriptValue oldstack = registers[SREG_SP]; - PushValueToStack(RuntimeScriptValue().SetInt32(0)); - if (ccError) - { - return -1; - } - - int oldpc = pc; - ccInstance *wasRunning = runningInst; - - // extract the instance ID - int32_t instId = codeOp.Instruction.InstanceId; - // determine the offset into the code of the instance we want - runningInst = loadedInstances[instId]; - intptr_t callAddr = reg1.Ptr - (char*)&runningInst->code[0]; - if (callAddr % sizeof(intptr_t) != 0) { - cc_error("call address not aligned"); - return -1; - } - callAddr /= sizeof(intptr_t); // size of ccScript::code elements - - if (Run((int32_t)callAddr)) - return -1; - - runningInst = wasRunning; - - if (flags & INSTF_ABORTED) - return 0; - - if (oldstack != registers[SREG_SP]) { - cc_error("stack corrupt after function call"); - return -1; - } - - next_call_needs_object = 0; - - pc = oldpc; - was_just_callas = func_callstack.Count; - num_args_to_func = -1; - POP_CALL_STACK; - break; - } - case SCMD_CALLEXT: { - // CallScriptFunction to a real 'C' code function - was_just_callas = -1; - if (num_args_to_func < 0) - { - num_args_to_func = func_callstack.Count; - } - - // Convert pointer arguments to simple types - for (RuntimeScriptValue *prval = func_callstack.GetHead() + num_args_to_func; - prval > func_callstack.GetHead(); --prval) - { - prval->DirectPtr(); - } - - RuntimeScriptValue return_value; - - if (reg1.Type == kScValPluginFunction) - { - GlobalReturnValue.Invalidate(); - int32_t int_ret_val; - if (next_call_needs_object) - { - RuntimeScriptValue obj_rval = registers[SREG_OP]; - obj_rval.DirectPtrObj(); - int_ret_val = call_function((intptr_t)reg1.Ptr, &obj_rval, num_args_to_func, func_callstack.GetHead() + 1); - } - else - { - int_ret_val = call_function((intptr_t)reg1.Ptr, nullptr, num_args_to_func, func_callstack.GetHead() + 1); - } - - if (GlobalReturnValue.IsValid()) - { - return_value = GlobalReturnValue; - } - else - { - return_value.SetPluginArgument(int_ret_val); - } - } - else if (next_call_needs_object) - { - // member function call - if (reg1.Type == kScValObjectFunction) - { - RuntimeScriptValue obj_rval = registers[SREG_OP]; - obj_rval.DirectPtrObj(); - return_value = reg1.ObjPfn(obj_rval.Ptr, func_callstack.GetHead() + 1, num_args_to_func); - } - else - { - cc_error("invalid pointer type for object function call: %d", reg1.Type); - } - } - else if (reg1.Type == kScValStaticFunction) - { - return_value = reg1.SPfn(func_callstack.GetHead() + 1, num_args_to_func); - } - else if (reg1.Type == kScValObjectFunction) - { - cc_error("unexpected object function pointer on SCMD_CALLEXT"); - } - else - { - cc_error("invalid pointer type for function call: %d", reg1.Type); - } - - if (ccError) - { - return -1; - } - - registers[SREG_AX] = return_value; - current_instance = this; - next_call_needs_object = 0; - num_args_to_func = -1; - break; - } - case SCMD_PUSHREAL: - PushToFuncCallStack(func_callstack, reg1); - break; - case SCMD_SUBREALSTACK: - PopFromFuncCallStack(func_callstack, arg1.IValue); - if (was_just_callas >= 0) - { - ASSERT_STACK_SIZE(arg1.IValue); - PopValuesFromStack(arg1.IValue); - was_just_callas = -1; - } - break; - case SCMD_CALLOBJ: - // set the OP register - if (reg1.IsNull()) { - cc_error("!Null pointer referenced"); - return -1; - } - switch (reg1.Type) - { - // This might be a static object, passed to the user-defined extender function - case kScValStaticObject: - case kScValDynamicObject: - case kScValPluginObject: - case kScValPluginArg: - // This might be an object of USER-DEFINED type, calling its MEMBER-FUNCTION. - // Note, that this is the only case known when such object is written into reg[SREG_OP]; - // in any other case that would count as error. - case kScValGlobalVar: - case kScValStackPtr: - registers[SREG_OP] = reg1; - break; - case kScValStaticArray: - if (reg1.StcArr->GetDynamicManager()) - { - registers[SREG_OP].SetDynamicObject( - (char*)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue), - reg1.StcArr->GetDynamicManager()); - break; - } - // fall-through intended - default: - cc_error("internal error: SCMD_CALLOBJ argument is not an object of built-in or user-defined type"); - return -1; - } - next_call_needs_object = 1; - break; - case SCMD_SHIFTLEFT: - reg1.SetInt32(reg1.IValue << reg2.IValue); - break; - case SCMD_SHIFTRIGHT: - reg1.SetInt32(reg1.IValue >> reg2.IValue); - break; - case SCMD_THISBASE: - thisbase[curnest] = arg1.IValue; - break; - case SCMD_NEWARRAY: - { - int numElements = reg1.IValue; - if (numElements < 1) - { - cc_error("invalid size for dynamic array; requested: %d, range: 1..%d", numElements, INT32_MAX); - return -1; - } - DynObjectRef ref = globalDynamicArray.Create(numElements, arg2.IValue, arg3.GetAsBool()); - reg1.SetDynamicObject(ref.second, &globalDynamicArray); - break; - } - case SCMD_NEWUSEROBJECT: - { - const int32_t size = arg2.IValue; - if (size < 0) - { - cc_error("Invalid size for user object; requested: %u (or %d), range: 0..%d", (uint32_t)size, size, INT_MAX); - return -1; - } - ScriptUserObject *suo = ScriptUserObject::CreateManaged(size); - reg1.SetDynamicObject(suo, suo); - break; - } - case SCMD_FADD: - reg1.SetFloat(reg1.FValue + arg2.IValue); // arg2 was used as int here originally - break; - case SCMD_FSUB: - reg1.SetFloat(reg1.FValue - arg2.IValue); // arg2 was used as int here originally - break; - case SCMD_FMULREG: - reg1.SetFloat(reg1.FValue * reg2.FValue); - break; - case SCMD_FDIVREG: - if (reg2.FValue == 0.0) { - cc_error("!Floating point divide by zero"); - return -1; - } - reg1.SetFloat(reg1.FValue / reg2.FValue); - break; - case SCMD_FADDREG: - reg1.SetFloat(reg1.FValue + reg2.FValue); - break; - case SCMD_FSUBREG: - reg1.SetFloat(reg1.FValue - reg2.FValue); - break; - case SCMD_FGREATER: - reg1.SetFloatAsBool(reg1.FValue > reg2.FValue); - break; - case SCMD_FLESSTHAN: - reg1.SetFloatAsBool(reg1.FValue < reg2.FValue); - break; - case SCMD_FGTE: - reg1.SetFloatAsBool(reg1.FValue >= reg2.FValue); - break; - case SCMD_FLTE: - reg1.SetFloatAsBool(reg1.FValue <= reg2.FValue); - break; - case SCMD_ZEROMEMORY: - // Check if we are zeroing at stack tail - if (registers[SREG_MAR] == registers[SREG_SP]) { - // creating a local variable -- check the stack to ensure no mem overrun - int currentStackSize = registers[SREG_SP].RValue - &stack[0]; - int currentDataSize = stackdata_ptr - stackdata; - if (currentStackSize + 1 >= CC_STACK_SIZE || - currentDataSize + arg1.IValue >= CC_STACK_DATA_SIZE) - { - cc_error("stack overflow, attempted grow to %d bytes", currentDataSize + arg1.IValue); - return -1; - } - // NOTE: according to compiler's logic, this is always followed - // by SCMD_ADD, and that is where the data is "allocated", here we - // just clean the place. - // CHECKME -- since we zero memory in PushDataToStack anyway, this is not needed at all? - memset(stackdata_ptr, 0, arg1.IValue); - } - else - { - cc_error("internal error: stack tail address expected on SCMD_ZEROMEMORY instruction, reg[MAR] type is %d", - registers[SREG_MAR].Type); - return -1; - } - break; - case SCMD_CREATESTRING: - if (stringClassImpl == nullptr) { - cc_error("No string class implementation set, but opcode was used"); - return -1; - } - direct_ptr1 = (const char*)reg1.GetDirectPtr(); - reg1.SetDynamicObject( - stringClassImpl->CreateString(direct_ptr1).second, - &myScriptStringImpl); - break; - case SCMD_STRINGSEQUAL: - if ((reg1.IsNull()) || (reg2.IsNull())) { - cc_error("!Null pointer referenced"); - return -1; - } - direct_ptr1 = (const char*)reg1.GetDirectPtr(); - direct_ptr2 = (const char*)reg2.GetDirectPtr(); - reg1.SetInt32AsBool(strcmp(direct_ptr1, direct_ptr2) == 0); - - break; - case SCMD_STRINGSNOTEQ: - if ((reg1.IsNull()) || (reg2.IsNull())) { - cc_error("!Null pointer referenced"); - return -1; - } - direct_ptr1 = (const char*)reg1.GetDirectPtr(); - direct_ptr2 = (const char*)reg2.GetDirectPtr(); - reg1.SetInt32AsBool(strcmp(direct_ptr1, direct_ptr2) != 0 ); - break; - case SCMD_LOOPCHECKOFF: - if (loopIterationCheckDisabled == 0) - loopIterationCheckDisabled++; - break; - default: - cc_error("instruction %d is not implemented", codeOp.Instruction.Code); - return -1; - } - - if (flags & INSTF_ABORTED) - return 0; - - pc += codeOp.ArgCount + 1; - } + { + return -1; + } + */ + /* ReadOperation */ + //===================================================================== + codeOp.Instruction.Code = codeInst->code[pc]; + codeOp.Instruction.InstanceId = (codeOp.Instruction.Code >> INSTANCE_ID_SHIFT) & INSTANCE_ID_MASK; + codeOp.Instruction.Code &= INSTANCE_ID_REMOVEMASK; // now this is pure instruction code + + if (codeOp.Instruction.Code < 0 || codeOp.Instruction.Code >= CC_NUM_SCCMDS) { + cc_error("invalid instruction %d found in code stream", codeOp.Instruction.Code); + return -1; + } + + codeOp.ArgCount = sccmd_info[codeOp.Instruction.Code].ArgCount; + if (pc + codeOp.ArgCount >= codeInst->codesize) { + cc_error("unexpected end of code data (%d; %d)", pc + codeOp.ArgCount, codeInst->codesize); + return -1; + } + + int pc_at = pc + 1; + for (int i = 0; i < codeOp.ArgCount; ++i, ++pc_at) { + char fixup = codeInst->code_fixups[pc_at]; + if (fixup > 0) { + // could be relative pointer or import address + /* + if (!FixupArgument(code[pc], fixup, codeOp.Args[i])) + { + return -1; + } + */ + /* FixupArgument */ + //===================================================================== + switch (fixup) { + case FIXUP_GLOBALDATA: { + ScriptVariable *gl_var = (ScriptVariable *)codeInst->code[pc_at]; + codeOp.Args[i].SetGlobalVar(&gl_var->RValue); + } + break; + case FIXUP_FUNCTION: + // originally commented -- CHECKME: could this be used in very old versions of AGS? + // code[fixup] += (long)&code[0]; + // This is a program counter value, presumably will be used as SCMD_CALL argument + codeOp.Args[i].SetInt32((int32_t)codeInst->code[pc_at]); + break; + case FIXUP_STRING: + codeOp.Args[i].SetStringLiteral(&codeInst->strings[0] + codeInst->code[pc_at]); + break; + case FIXUP_IMPORT: { + const ScriptImport *import = simp.getByIndex((int32_t)codeInst->code[pc_at]); + if (import) { + codeOp.Args[i] = import->Value; + } else { + cc_error("cannot resolve import, key = %ld", codeInst->code[pc_at]); + return -1; + } + } + break; + case FIXUP_STACK: + codeOp.Args[i] = GetStackPtrOffsetFw((int32_t)codeInst->code[pc_at]); + break; + default: + cc_error("internal fixup type error: %d", fixup); + return -1; + } + /* End FixupArgument */ + //===================================================================== + } else { + // should be a numeric literal (int32 or float) + codeOp.Args[i].SetInt32((int32_t)codeInst->code[pc_at]); + } + } + /* End ReadOperation */ + //===================================================================== + + // save the arguments for quick access + RuntimeScriptValue &arg1 = codeOp.Args[0]; + RuntimeScriptValue &arg2 = codeOp.Args[1]; + RuntimeScriptValue &arg3 = codeOp.Args[2]; + RuntimeScriptValue ®1 = + registers[arg1.IValue >= 0 && arg1.IValue < CC_NUM_REGISTERS ? arg1.IValue : 0]; + RuntimeScriptValue ®2 = + registers[arg2.IValue >= 0 && arg2.IValue < CC_NUM_REGISTERS ? arg2.IValue : 0]; + + const char *direct_ptr1; + const char *direct_ptr2; + + if (write_debug_dump) { + DumpInstruction(codeOp); + } + + switch (codeOp.Instruction.Code) { + case SCMD_LINENUM: + line_number = arg1.IValue; + currentline = arg1.IValue; + if (new_line_hook) + new_line_hook(this, currentline); + break; + case SCMD_ADD: + // If the the register is SREG_SP, we are allocating new variable on the stack + if (arg1.IValue == SREG_SP) { + // Only allocate new data if current stack entry is invalid; + // in some cases this may be advancing over value that was written by MEMWRITE* + ASSERT_STACK_SPACE_AVAILABLE(1); + if (reg1.RValue->IsValid()) { + // TODO: perhaps should add a flag here to ensure this happens only after MEMWRITE-ing to stack + registers[SREG_SP].RValue++; + } else { + PushDataToStack(arg2.IValue); + if (ccError) { + return -1; + } + } + } else { + reg1.IValue += arg2.IValue; + } + break; + case SCMD_SUB: + if (reg1.Type == kScValStackPtr) { + // If this is SREG_SP, this is stack pop, which frees local variables; + // Other than SREG_SP this may be AGS 2.x method to offset stack in SREG_MAR; + // quote JJS: + // // AGS 2.x games also perform relative stack access by copying SREG_SP to SREG_MAR + // // and then subtracting from that. + if (arg1.IValue == SREG_SP) { + PopDataFromStack(arg2.IValue); + } else { + // This is practically LOADSPOFFS + reg1 = GetStackPtrOffsetRw(arg2.IValue); + } + if (ccError) { + return -1; + } + } else { + reg1.IValue -= arg2.IValue; + } + break; + case SCMD_REGTOREG: + reg2 = reg1; + break; + case SCMD_WRITELIT: + // Take the data address from reg[MAR] and copy there arg1 bytes from arg2 address + // + // NOTE: since it reads directly from arg2 (which originally was + // long, or rather int32 due x32 build), written value may normally + // be only up to 4 bytes large; + // I guess that's an obsolete way to do WRITE, WRITEW and WRITEB + switch (arg1.IValue) { + case sizeof(char): + registers[SREG_MAR].WriteByte(arg2.IValue); + break; + case sizeof(int16_t): + registers[SREG_MAR].WriteInt16(arg2.IValue); + break; + case sizeof(int32_t): + // We do not know if this is math integer or some pointer, etc + registers[SREG_MAR].WriteValue(arg2); + break; + default: + cc_error("unexpected data size for WRITELIT op: %d", arg1.IValue); + break; + } + break; + case SCMD_RET: { + if (loopIterationCheckDisabled > 0) + loopIterationCheckDisabled--; + + ASSERT_STACK_SIZE(1); + RuntimeScriptValue rval = PopValueFromStack(); + curnest--; + pc = rval.IValue; + if (pc == 0) { + returnValue = registers[SREG_AX].IValue; + return 0; + } + current_instance = this; + POP_CALL_STACK; + continue; // continue so that the PC doesn't get overwritten + } + case SCMD_LITTOREG: + reg1 = arg2; + break; + case SCMD_MEMREAD: + // Take the data address from reg[MAR] and copy int32_t to reg[arg1] + reg1 = registers[SREG_MAR].ReadValue(); + break; + case SCMD_MEMWRITE: + // Take the data address from reg[MAR] and copy there int32_t from reg[arg1] + registers[SREG_MAR].WriteValue(reg1); + break; + case SCMD_LOADSPOFFS: + registers[SREG_MAR] = GetStackPtrOffsetRw(arg1.IValue); + if (ccError) { + return -1; + } + break; + + // 64 bit: Force 32 bit math + case SCMD_MULREG: + reg1.SetInt32(reg1.IValue * reg2.IValue); + break; + case SCMD_DIVREG: + if (reg2.IValue == 0) { + cc_error("!Integer divide by zero"); + return -1; + } + reg1.SetInt32(reg1.IValue / reg2.IValue); + break; + case SCMD_ADDREG: + // This may be pointer arithmetics, in which case IValue stores offset from base pointer + reg1.IValue += reg2.IValue; + break; + case SCMD_SUBREG: + // This may be pointer arithmetics, in which case IValue stores offset from base pointer + reg1.IValue -= reg2.IValue; + break; + case SCMD_BITAND: + reg1.SetInt32(reg1.IValue & reg2.IValue); + break; + case SCMD_BITOR: + reg1.SetInt32(reg1.IValue | reg2.IValue); + break; + case SCMD_ISEQUAL: + reg1.SetInt32AsBool(reg1 == reg2); + break; + case SCMD_NOTEQUAL: + reg1.SetInt32AsBool(reg1 != reg2); + break; + case SCMD_GREATER: + reg1.SetInt32AsBool(reg1.IValue > reg2.IValue); + break; + case SCMD_LESSTHAN: + reg1.SetInt32AsBool(reg1.IValue < reg2.IValue); + break; + case SCMD_GTE: + reg1.SetInt32AsBool(reg1.IValue >= reg2.IValue); + break; + case SCMD_LTE: + reg1.SetInt32AsBool(reg1.IValue <= reg2.IValue); + break; + case SCMD_AND: + reg1.SetInt32AsBool(reg1.IValue && reg2.IValue); + break; + case SCMD_OR: + reg1.SetInt32AsBool(reg1.IValue || reg2.IValue); + break; + case SCMD_XORREG: + reg1.SetInt32(reg1.IValue ^ reg2.IValue); + break; + case SCMD_MODREG: + if (reg2.IValue == 0) { + cc_error("!Integer divide by zero"); + return -1; + } + reg1.SetInt32(reg1.IValue % reg2.IValue); + break; + case SCMD_NOTREG: + reg1 = !(reg1); + break; + case SCMD_CALL: + // CallScriptFunction another function within same script, just save PC + // and continue from there + if (curnest >= MAXNEST - 1) { + cc_error("!call stack overflow, recursive call problem?"); + return -1; + } + + PUSH_CALL_STACK; + + ASSERT_STACK_SPACE_AVAILABLE(1); + PushValueToStack(RuntimeScriptValue().SetInt32(pc + codeOp.ArgCount + 1)); + if (ccError) { + return -1; + } + + if (thisbase[curnest] == 0) + pc = reg1.IValue; + else { + pc = funcstart[curnest]; + pc += (reg1.IValue - thisbase[curnest]); + } + + next_call_needs_object = 0; + + if (loopIterationCheckDisabled) + loopIterationCheckDisabled++; + + curnest++; + thisbase[curnest] = 0; + funcstart[curnest] = pc; + continue; // continue so that the PC doesn't get overwritten + case SCMD_MEMREADB: + // Take the data address from reg[MAR] and copy byte to reg[arg1] + reg1.SetUInt8(registers[SREG_MAR].ReadByte()); + break; + case SCMD_MEMREADW: + // Take the data address from reg[MAR] and copy int16_t to reg[arg1] + reg1.SetInt16(registers[SREG_MAR].ReadInt16()); + break; + case SCMD_MEMWRITEB: + // Take the data address from reg[MAR] and copy there byte from reg[arg1] + registers[SREG_MAR].WriteByte(reg1.IValue); + break; + case SCMD_MEMWRITEW: + // Take the data address from reg[MAR] and copy there int16_t from reg[arg1] + registers[SREG_MAR].WriteInt16(reg1.IValue); + break; + case SCMD_JZ: + if (registers[SREG_AX].IsNull()) + pc += arg1.IValue; + break; + case SCMD_JNZ: + if (!registers[SREG_AX].IsNull()) + pc += arg1.IValue; + break; + case SCMD_PUSHREG: + // Push reg[arg1] value to the stack + ASSERT_STACK_SPACE_AVAILABLE(1); + PushValueToStack(reg1); + if (ccError) { + return -1; + } + break; + case SCMD_POPREG: + ASSERT_STACK_SIZE(1); + reg1 = PopValueFromStack(); + break; + case SCMD_JMP: + pc += arg1.IValue; + + if ((arg1.IValue < 0) && (maxWhileLoops > 0) && (loopIterationCheckDisabled == 0)) { + // Make sure it's not stuck in a While loop + loopIterations ++; + if (flags & INSTF_RUNNING) { + loopIterations = 0; + flags &= ~INSTF_RUNNING; + } else if (loopIterations > maxWhileLoops) { + cc_error("!Script appears to be hung (a while loop ran %d times). The problem may be in a calling function; check the call stack.", loopIterations); + return -1; + } + } + break; + case SCMD_MUL: + reg1.IValue *= arg2.IValue; + break; + case SCMD_CHECKBOUNDS: + if ((reg1.IValue < 0) || + (reg1.IValue >= arg2.IValue)) { + cc_error("!Array index out of bounds (index: %d, bounds: 0..%d)", reg1.IValue, arg2.IValue - 1); + return -1; + } + break; + case SCMD_DYNAMICBOUNDS: { + // TODO: test reg[MAR] type here; + // That might be dynamic object, but also a non-managed dynamic array, "allocated" + // on global or local memspace (buffer) + int32_t upperBoundInBytes = *((int32_t *)(registers[SREG_MAR].GetPtrWithOffset() - 4)); + if ((reg1.IValue < 0) || + (reg1.IValue >= upperBoundInBytes)) { + int32_t upperBound = *((int32_t *)(registers[SREG_MAR].GetPtrWithOffset() - 8)) & (~ARRAY_MANAGED_TYPE_FLAG); + if (upperBound <= 0) { + cc_error("!Array has an invalid size (%d) and cannot be accessed", upperBound); + } else { + int elementSize = (upperBoundInBytes / upperBound); + cc_error("!Array index out of bounds (index: %d, bounds: 0..%d)", reg1.IValue / elementSize, upperBound - 1); + } + return -1; + } + break; + } + + // 64 bit: Handles are always 32 bit values. They are not C pointer. + + case SCMD_MEMREADPTR: { + ccError = 0; + + int32_t handle = registers[SREG_MAR].ReadInt32(); + void *object; + ICCDynamicObject *manager; + ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(handle, object, manager); + if (obj_type == kScValPluginObject) { + reg1.SetPluginObject(object, manager); + } else { + reg1.SetDynamicObject(object, manager); + } + + // if error occurred, cc_error will have been set + if (ccError) + return -1; + break; + } + case SCMD_MEMWRITEPTR: { + + int32_t handle = registers[SREG_MAR].ReadInt32(); + char *address = nullptr; + + if (reg1.Type == kScValStaticArray && reg1.StcArr->GetDynamicManager()) { + address = (char *)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); + } else if (reg1.Type == kScValDynamicObject || + reg1.Type == kScValPluginObject) { + address = reg1.Ptr; + } else if (reg1.Type == kScValPluginArg) { + // TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems + address = Int32ToPtr(reg1.IValue); + } + // There's one possible case when the reg1 is 0, which means writing nullptr + else if (!reg1.IsNull()) { + cc_error("internal error: MEMWRITEPTR argument is not dynamic object"); + return -1; + } + + int32_t newHandle = ccGetObjectHandleFromAddress(address); + if (newHandle == -1) + return -1; + + if (handle != newHandle) { + ccReleaseObjectReference(handle); + ccAddObjectReference(newHandle); + registers[SREG_MAR].WriteInt32(newHandle); + } + break; + } + case SCMD_MEMINITPTR: { + char *address = nullptr; + + if (reg1.Type == kScValStaticArray && reg1.StcArr->GetDynamicManager()) { + address = (char *)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); + } else if (reg1.Type == kScValDynamicObject || + reg1.Type == kScValPluginObject) { + address = reg1.Ptr; + } else if (reg1.Type == kScValPluginArg) { + // TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems + address = Int32ToPtr(reg1.IValue); + } + // There's one possible case when the reg1 is 0, which means writing nullptr + else if (!reg1.IsNull()) { + cc_error("internal error: SCMD_MEMINITPTR argument is not dynamic object"); + return -1; + } + // like memwriteptr, but doesn't attempt to free the old one + int32_t newHandle = ccGetObjectHandleFromAddress(address); + if (newHandle == -1) + return -1; + + ccAddObjectReference(newHandle); + registers[SREG_MAR].WriteInt32(newHandle); + break; + } + case SCMD_MEMZEROPTR: { + int32_t handle = registers[SREG_MAR].ReadInt32(); + ccReleaseObjectReference(handle); + registers[SREG_MAR].WriteInt32(0); + break; + } + case SCMD_MEMZEROPTRND: { + int32_t handle = registers[SREG_MAR].ReadInt32(); + + // don't do the Dispose check for the object being returned -- this is + // for returning a String (or other pointer) from a custom function. + // Note: we might be freeing a dynamic array which contains the DisableDispose + // object, that will be handled inside the recursive call to SubRef. + // CHECKME!! what type of data may reg1 point to? + pool.disableDisposeForObject = (const char *)registers[SREG_AX].Ptr; + ccReleaseObjectReference(handle); + pool.disableDisposeForObject = nullptr; + registers[SREG_MAR].WriteInt32(0); + break; + } + case SCMD_CHECKNULL: + if (registers[SREG_MAR].IsNull()) { + cc_error("!Null pointer referenced"); + return -1; + } + break; + case SCMD_CHECKNULLREG: + if (reg1.IsNull()) { + cc_error("!Null string referenced"); + return -1; + } + break; + case SCMD_NUMFUNCARGS: + num_args_to_func = arg1.IValue; + break; + case SCMD_CALLAS: { + PUSH_CALL_STACK; + + // CallScriptFunction to a function in another script + + // If there are nested CALLAS calls, the stack might + // contain 2 calls worth of parameters, so only + // push args for this call + if (num_args_to_func < 0) { + num_args_to_func = func_callstack.Count; + } + ASSERT_STACK_SPACE_AVAILABLE(num_args_to_func + 1 /* return address */); + for (const RuntimeScriptValue *prval = func_callstack.GetHead() + num_args_to_func; + prval > func_callstack.GetHead(); --prval) { + PushValueToStack(*prval); + } + + // 0, so that the cc_run_code returns + RuntimeScriptValue oldstack = registers[SREG_SP]; + PushValueToStack(RuntimeScriptValue().SetInt32(0)); + if (ccError) { + return -1; + } + + int oldpc = pc; + ccInstance *wasRunning = runningInst; + + // extract the instance ID + int32_t instId = codeOp.Instruction.InstanceId; + // determine the offset into the code of the instance we want + runningInst = loadedInstances[instId]; + intptr_t callAddr = reg1.Ptr - (char *)&runningInst->code[0]; + if (callAddr % sizeof(intptr_t) != 0) { + cc_error("call address not aligned"); + return -1; + } + callAddr /= sizeof(intptr_t); // size of ccScript::code elements + + if (Run((int32_t)callAddr)) + return -1; + + runningInst = wasRunning; + + if (flags & INSTF_ABORTED) + return 0; + + if (oldstack != registers[SREG_SP]) { + cc_error("stack corrupt after function call"); + return -1; + } + + next_call_needs_object = 0; + + pc = oldpc; + was_just_callas = func_callstack.Count; + num_args_to_func = -1; + POP_CALL_STACK; + break; + } + case SCMD_CALLEXT: { + // CallScriptFunction to a real 'C' code function + was_just_callas = -1; + if (num_args_to_func < 0) { + num_args_to_func = func_callstack.Count; + } + + // Convert pointer arguments to simple types + for (RuntimeScriptValue *prval = func_callstack.GetHead() + num_args_to_func; + prval > func_callstack.GetHead(); --prval) { + prval->DirectPtr(); + } + + RuntimeScriptValue return_value; + + if (reg1.Type == kScValPluginFunction) { + GlobalReturnValue.Invalidate(); + int32_t int_ret_val; + if (next_call_needs_object) { + RuntimeScriptValue obj_rval = registers[SREG_OP]; + obj_rval.DirectPtrObj(); + int_ret_val = call_function((intptr_t)reg1.Ptr, &obj_rval, num_args_to_func, func_callstack.GetHead() + 1); + } else { + int_ret_val = call_function((intptr_t)reg1.Ptr, nullptr, num_args_to_func, func_callstack.GetHead() + 1); + } + + if (GlobalReturnValue.IsValid()) { + return_value = GlobalReturnValue; + } else { + return_value.SetPluginArgument(int_ret_val); + } + } else if (next_call_needs_object) { + // member function call + if (reg1.Type == kScValObjectFunction) { + RuntimeScriptValue obj_rval = registers[SREG_OP]; + obj_rval.DirectPtrObj(); + return_value = reg1.ObjPfn(obj_rval.Ptr, func_callstack.GetHead() + 1, num_args_to_func); + } else { + cc_error("invalid pointer type for object function call: %d", reg1.Type); + } + } else if (reg1.Type == kScValStaticFunction) { + return_value = reg1.SPfn(func_callstack.GetHead() + 1, num_args_to_func); + } else if (reg1.Type == kScValObjectFunction) { + cc_error("unexpected object function pointer on SCMD_CALLEXT"); + } else { + cc_error("invalid pointer type for function call: %d", reg1.Type); + } + + if (ccError) { + return -1; + } + + registers[SREG_AX] = return_value; + current_instance = this; + next_call_needs_object = 0; + num_args_to_func = -1; + break; + } + case SCMD_PUSHREAL: + PushToFuncCallStack(func_callstack, reg1); + break; + case SCMD_SUBREALSTACK: + PopFromFuncCallStack(func_callstack, arg1.IValue); + if (was_just_callas >= 0) { + ASSERT_STACK_SIZE(arg1.IValue); + PopValuesFromStack(arg1.IValue); + was_just_callas = -1; + } + break; + case SCMD_CALLOBJ: + // set the OP register + if (reg1.IsNull()) { + cc_error("!Null pointer referenced"); + return -1; + } + switch (reg1.Type) { + // This might be a static object, passed to the user-defined extender function + case kScValStaticObject: + case kScValDynamicObject: + case kScValPluginObject: + case kScValPluginArg: + // This might be an object of USER-DEFINED type, calling its MEMBER-FUNCTION. + // Note, that this is the only case known when such object is written into reg[SREG_OP]; + // in any other case that would count as error. + case kScValGlobalVar: + case kScValStackPtr: + registers[SREG_OP] = reg1; + break; + case kScValStaticArray: + if (reg1.StcArr->GetDynamicManager()) { + registers[SREG_OP].SetDynamicObject( + (char *)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue), + reg1.StcArr->GetDynamicManager()); + break; + } + // fall-through intended + default: + cc_error("internal error: SCMD_CALLOBJ argument is not an object of built-in or user-defined type"); + return -1; + } + next_call_needs_object = 1; + break; + case SCMD_SHIFTLEFT: + reg1.SetInt32(reg1.IValue << reg2.IValue); + break; + case SCMD_SHIFTRIGHT: + reg1.SetInt32(reg1.IValue >> reg2.IValue); + break; + case SCMD_THISBASE: + thisbase[curnest] = arg1.IValue; + break; + case SCMD_NEWARRAY: { + int numElements = reg1.IValue; + if (numElements < 1) { + cc_error("invalid size for dynamic array; requested: %d, range: 1..%d", numElements, INT32_MAX); + return -1; + } + DynObjectRef ref = globalDynamicArray.Create(numElements, arg2.IValue, arg3.GetAsBool()); + reg1.SetDynamicObject(ref.second, &globalDynamicArray); + break; + } + case SCMD_NEWUSEROBJECT: { + const int32_t size = arg2.IValue; + if (size < 0) { + cc_error("Invalid size for user object; requested: %u (or %d), range: 0..%d", (uint32_t)size, size, INT_MAX); + return -1; + } + ScriptUserObject *suo = ScriptUserObject::CreateManaged(size); + reg1.SetDynamicObject(suo, suo); + break; + } + case SCMD_FADD: + reg1.SetFloat(reg1.FValue + arg2.IValue); // arg2 was used as int here originally + break; + case SCMD_FSUB: + reg1.SetFloat(reg1.FValue - arg2.IValue); // arg2 was used as int here originally + break; + case SCMD_FMULREG: + reg1.SetFloat(reg1.FValue * reg2.FValue); + break; + case SCMD_FDIVREG: + if (reg2.FValue == 0.0) { + cc_error("!Floating point divide by zero"); + return -1; + } + reg1.SetFloat(reg1.FValue / reg2.FValue); + break; + case SCMD_FADDREG: + reg1.SetFloat(reg1.FValue + reg2.FValue); + break; + case SCMD_FSUBREG: + reg1.SetFloat(reg1.FValue - reg2.FValue); + break; + case SCMD_FGREATER: + reg1.SetFloatAsBool(reg1.FValue > reg2.FValue); + break; + case SCMD_FLESSTHAN: + reg1.SetFloatAsBool(reg1.FValue < reg2.FValue); + break; + case SCMD_FGTE: + reg1.SetFloatAsBool(reg1.FValue >= reg2.FValue); + break; + case SCMD_FLTE: + reg1.SetFloatAsBool(reg1.FValue <= reg2.FValue); + break; + case SCMD_ZEROMEMORY: + // Check if we are zeroing at stack tail + if (registers[SREG_MAR] == registers[SREG_SP]) { + // creating a local variable -- check the stack to ensure no mem overrun + int currentStackSize = registers[SREG_SP].RValue - &stack[0]; + int currentDataSize = stackdata_ptr - stackdata; + if (currentStackSize + 1 >= CC_STACK_SIZE || + currentDataSize + arg1.IValue >= CC_STACK_DATA_SIZE) { + cc_error("stack overflow, attempted grow to %d bytes", currentDataSize + arg1.IValue); + return -1; + } + // NOTE: according to compiler's logic, this is always followed + // by SCMD_ADD, and that is where the data is "allocated", here we + // just clean the place. + // CHECKME -- since we zero memory in PushDataToStack anyway, this is not needed at all? + memset(stackdata_ptr, 0, arg1.IValue); + } else { + cc_error("internal error: stack tail address expected on SCMD_ZEROMEMORY instruction, reg[MAR] type is %d", + registers[SREG_MAR].Type); + return -1; + } + break; + case SCMD_CREATESTRING: + if (stringClassImpl == nullptr) { + cc_error("No string class implementation set, but opcode was used"); + return -1; + } + direct_ptr1 = (const char *)reg1.GetDirectPtr(); + reg1.SetDynamicObject( + stringClassImpl->CreateString(direct_ptr1).second, + &myScriptStringImpl); + break; + case SCMD_STRINGSEQUAL: + if ((reg1.IsNull()) || (reg2.IsNull())) { + cc_error("!Null pointer referenced"); + return -1; + } + direct_ptr1 = (const char *)reg1.GetDirectPtr(); + direct_ptr2 = (const char *)reg2.GetDirectPtr(); + reg1.SetInt32AsBool(strcmp(direct_ptr1, direct_ptr2) == 0); + + break; + case SCMD_STRINGSNOTEQ: + if ((reg1.IsNull()) || (reg2.IsNull())) { + cc_error("!Null pointer referenced"); + return -1; + } + direct_ptr1 = (const char *)reg1.GetDirectPtr(); + direct_ptr2 = (const char *)reg2.GetDirectPtr(); + reg1.SetInt32AsBool(strcmp(direct_ptr1, direct_ptr2) != 0); + break; + case SCMD_LOOPCHECKOFF: + if (loopIterationCheckDisabled == 0) + loopIterationCheckDisabled++; + break; + default: + cc_error("instruction %d is not implemented", codeOp.Instruction.Code); + return -1; + } + + if (flags & INSTF_ABORTED) + return 0; + + pc += codeOp.ArgCount + 1; + } } -String ccInstance::GetCallStack(int maxLines) -{ - String buffer = String::FromFormat("in \"%s\", line %d\n", runningInst->instanceof->GetSectionName(pc), line_number); - - int linesDone = 0; - for (int j = callStackSize - 1; (j >= 0) && (linesDone < maxLines); j--, linesDone++) - { - String lineBuffer = String::FromFormat("from \"%s\", line %d\n", - callStackCodeInst[j]->instanceof->GetSectionName(callStackAddr[j]), callStackLineNumber[j]); - buffer.Append(lineBuffer); - if (linesDone == maxLines - 1) - buffer.Append("(and more...)\n"); - } - return buffer; +String ccInstance::GetCallStack(int maxLines) { + String buffer = String::FromFormat("in \"%s\", line %d\n", runningInst->instanceof->GetSectionName(pc), line_number); + + int linesDone = 0; + for (int j = callStackSize - 1; (j >= 0) && (linesDone < maxLines); j--, linesDone++) { + String lineBuffer = String::FromFormat("from \"%s\", line %d\n", + callStackCodeInst[j]->instanceof->GetSectionName(callStackAddr[j]), callStackLineNumber[j]); + buffer.Append(lineBuffer); + if (linesDone == maxLines - 1) + buffer.Append("(and more...)\n"); + } + return buffer; } -void ccInstance::GetScriptPosition(ScriptPosition &script_pos) -{ - script_pos.Section = runningInst->instanceof->GetSectionName(pc); - script_pos.Line = line_number; +void ccInstance::GetScriptPosition(ScriptPosition &script_pos) { + script_pos.Section = runningInst->instanceof->GetSectionName(pc); + script_pos.Line = line_number; } // get a pointer to a variable or function exported by the script -RuntimeScriptValue ccInstance::GetSymbolAddress(const char *symname) -{ - int k; - char altName[200]; - sprintf(altName, "%s$", symname); - RuntimeScriptValue rval_null; - - for (k = 0; k < instanceof->numexports; k++) { - if (strcmp(instanceof->exports[k], symname) == 0) - return exports[k]; - // mangled function name - if (strncmp(instanceof->exports[k], altName, strlen(altName)) == 0) - return exports[k]; - } - return rval_null; +RuntimeScriptValue ccInstance::GetSymbolAddress(const char *symname) { + int k; + char altName[200]; + sprintf(altName, "%s$", symname); + RuntimeScriptValue rval_null; + + for (k = 0; k < instanceof->numexports; k++) { + if (strcmp(instanceof->exports[k], symname) == 0) + return exports[k]; + // mangled function name + if (strncmp(instanceof->exports[k], altName, strlen(altName)) == 0) + return exports[k]; + } + return rval_null; } -void ccInstance::DumpInstruction(const ScriptOperation &op) -{ - // line_num local var should be shared between all the instances - static int line_num = 0; - - if (op.Instruction.Code == SCMD_LINENUM) - { - line_num = op.Args[0].IValue; - return; - } - - Stream *data_s = ci_fopen("script.log", kFile_Create, kFile_Write); - TextStreamWriter writer(data_s); - writer.WriteFormat("Line %3d, IP:%8d (SP:%p) ", line_num, pc, registers[SREG_SP].RValue); - - const ScriptCommandInfo &cmd_info = sccmd_info[op.Instruction.Code]; - writer.WriteString(cmd_info.CmdName); - - for (int i = 0; i < cmd_info.ArgCount; ++i) - { - if (i > 0) - { - writer.WriteChar(','); - } - if (cmd_info.ArgIsReg[i]) - { - writer.WriteFormat(" %s", regnames[op.Args[i].IValue]); - } - else - { - // MACPORT FIX 9/6/5: changed %d to %ld - // FIXME: check type and write appropriate values - writer.WriteFormat(" %ld", op.Args[i].GetPtrWithOffset()); - } - } - writer.WriteLineBreak(); - // the writer will delete data stream internally +void ccInstance::DumpInstruction(const ScriptOperation &op) { + // line_num local var should be shared between all the instances + static int line_num = 0; + + if (op.Instruction.Code == SCMD_LINENUM) { + line_num = op.Args[0].IValue; + return; + } + + Stream *data_s = ci_fopen("script.log", kFile_Create, kFile_Write); + TextStreamWriter writer(data_s); + writer.WriteFormat("Line %3d, IP:%8d (SP:%p) ", line_num, pc, registers[SREG_SP].RValue); + + const ScriptCommandInfo &cmd_info = sccmd_info[op.Instruction.Code]; + writer.WriteString(cmd_info.CmdName); + + for (int i = 0; i < cmd_info.ArgCount; ++i) { + if (i > 0) { + writer.WriteChar(','); + } + if (cmd_info.ArgIsReg[i]) { + writer.WriteFormat(" %s", regnames[op.Args[i].IValue]); + } else { + // MACPORT FIX 9/6/5: changed %d to %ld + // FIXME: check type and write appropriate values + writer.WriteFormat(" %ld", op.Args[i].GetPtrWithOffset()); + } + } + writer.WriteLineBreak(); + // the writer will delete data stream internally } -bool ccInstance::IsBeingRun() const -{ - return pc != 0; +bool ccInstance::IsBeingRun() const { + return pc != 0; } -bool ccInstance::_Create(PScript scri, ccInstance * joined) -{ - int i; - currentline = -1; - if ((scri == nullptr) && (joined != nullptr)) - scri = joined->instanceof; - - if (scri == nullptr) { - cc_error("null pointer passed"); - return false; - } - - if (joined != nullptr) { - // share memory space with an existing instance (ie. this is a thread/fork) - globalvars = joined->globalvars; - globaldatasize = joined->globaldatasize; - globaldata = joined->globaldata; - code = joined->code; - codesize = joined->codesize; - } - else { - // create own memory space - // NOTE: globalvars are created in CreateGlobalVars() - globalvars.reset(new ScVarMap()); - globaldatasize = scri->globaldatasize; - globaldata = nullptr; - if (globaldatasize > 0) - { - globaldata = (char *)malloc(globaldatasize); - memcpy(globaldata, scri->globaldata, globaldatasize); - } - - codesize = scri->codesize; - code = nullptr; - if (codesize > 0) - { - code = (intptr_t*)malloc(codesize * sizeof(intptr_t)); - // 64 bit: Read code into 8 byte array, necessary for being able to perform - // relocations on the references. - for (int i = 0; i < codesize; ++i) - code[i] = scri->code[i]; - } - } - - // just use the pointer to the strings since they don't change - strings = scri->strings; - stringssize = scri->stringssize; - // create a stack - stackdatasize = CC_STACK_DATA_SIZE; - // This is quite a random choice; there's no way to deduce number of stack - // entries needed without knowing amount of local variables (at least) - num_stackentries = CC_STACK_SIZE; - stack = new RuntimeScriptValue[num_stackentries]; - stackdata = new char[stackdatasize]; - if (stack == nullptr || stackdata == nullptr) { - cc_error("not enough memory to allocate stack"); - return false; - } - - // find a LoadedInstance slot for it - for (i = 0; i < MAX_LOADED_INSTANCES; i++) { - if (loadedInstances[i] == nullptr) { - loadedInstances[i] = this; - loadedInstanceId = i; - break; - } - if (i == MAX_LOADED_INSTANCES - 1) { - cc_error("too many active instances"); - return false; - } - } - - if (joined) - { - resolved_imports = joined->resolved_imports; - code_fixups = joined->code_fixups; - } - else - { - if (!ResolveScriptImports(scri)) - { - return false; - } - if (!CreateGlobalVars(scri)) - { - return false; - } - if (!CreateRuntimeCodeFixups(scri)) - { - return false; - } - } - - exports = new RuntimeScriptValue[scri->numexports]; - - // find the real address of the exports - for (i = 0; i < scri->numexports; i++) { - int32_t etype = (scri->export_addr[i] >> 24L) & 0x000ff; - int32_t eaddr = (scri->export_addr[i] & 0x00ffffff); - if (etype == EXPORT_FUNCTION) - { - // NOTE: unfortunately, there seems to be no way to know if - // that's an extender function that expects object pointer - exports[i].SetCodePtr((char *)((intptr_t)eaddr * sizeof(intptr_t) + (char*)(&code[0]))); - } - else if (etype == EXPORT_DATA) - { - ScriptVariable *gl_var = FindGlobalVar(eaddr); - if (gl_var) - { - exports[i].SetGlobalVar(&gl_var->RValue); - } - else - { - cc_error("cannot resolve global variable, key = %d", eaddr); - return false; - } - } - else { - cc_error("internal export fixup error"); - return false; - } - } - instanceof = scri; - pc = 0; - flags = 0; - if (joined != nullptr) - flags = INSTF_SHAREDATA; - scri->instances++; - - if ((scri->instances == 1) && (ccGetOption(SCOPT_AUTOIMPORT) != 0)) { - // import all the exported stuff from this script - for (i = 0; i < scri->numexports; i++) { - if (!ccAddExternalScriptSymbol(scri->exports[i], exports[i], this)) { - cc_error("Export table overflow at '%s'", scri->exports[i]); - return false; - } - } - } - return true; +bool ccInstance::_Create(PScript scri, ccInstance *joined) { + int i; + currentline = -1; + if ((scri == nullptr) && (joined != nullptr)) + scri = joined->instanceof; + + if (scri == nullptr) { + cc_error("null pointer passed"); + return false; + } + + if (joined != nullptr) { + // share memory space with an existing instance (ie. this is a thread/fork) + globalvars = joined->globalvars; + globaldatasize = joined->globaldatasize; + globaldata = joined->globaldata; + code = joined->code; + codesize = joined->codesize; + } else { + // create own memory space + // NOTE: globalvars are created in CreateGlobalVars() + globalvars.reset(new ScVarMap()); + globaldatasize = scri->globaldatasize; + globaldata = nullptr; + if (globaldatasize > 0) { + globaldata = (char *)malloc(globaldatasize); + memcpy(globaldata, scri->globaldata, globaldatasize); + } + + codesize = scri->codesize; + code = nullptr; + if (codesize > 0) { + code = (intptr_t *)malloc(codesize * sizeof(intptr_t)); + // 64 bit: Read code into 8 byte array, necessary for being able to perform + // relocations on the references. + for (int i = 0; i < codesize; ++i) + code[i] = scri->code[i]; + } + } + + // just use the pointer to the strings since they don't change + strings = scri->strings; + stringssize = scri->stringssize; + // create a stack + stackdatasize = CC_STACK_DATA_SIZE; + // This is quite a random choice; there's no way to deduce number of stack + // entries needed without knowing amount of local variables (at least) + num_stackentries = CC_STACK_SIZE; + stack = new RuntimeScriptValue[num_stackentries]; + stackdata = new char[stackdatasize]; + if (stack == nullptr || stackdata == nullptr) { + cc_error("not enough memory to allocate stack"); + return false; + } + + // find a LoadedInstance slot for it + for (i = 0; i < MAX_LOADED_INSTANCES; i++) { + if (loadedInstances[i] == nullptr) { + loadedInstances[i] = this; + loadedInstanceId = i; + break; + } + if (i == MAX_LOADED_INSTANCES - 1) { + cc_error("too many active instances"); + return false; + } + } + + if (joined) { + resolved_imports = joined->resolved_imports; + code_fixups = joined->code_fixups; + } else { + if (!ResolveScriptImports(scri)) { + return false; + } + if (!CreateGlobalVars(scri)) { + return false; + } + if (!CreateRuntimeCodeFixups(scri)) { + return false; + } + } + + exports = new RuntimeScriptValue[scri->numexports]; + + // find the real address of the exports + for (i = 0; i < scri->numexports; i++) { + int32_t etype = (scri->export_addr[i] >> 24L) & 0x000ff; + int32_t eaddr = (scri->export_addr[i] & 0x00ffffff); + if (etype == EXPORT_FUNCTION) { + // NOTE: unfortunately, there seems to be no way to know if + // that's an extender function that expects object pointer + exports[i].SetCodePtr((char *)((intptr_t)eaddr * sizeof(intptr_t) + (char *)(&code[0]))); + } else if (etype == EXPORT_DATA) { + ScriptVariable *gl_var = FindGlobalVar(eaddr); + if (gl_var) { + exports[i].SetGlobalVar(&gl_var->RValue); + } else { + cc_error("cannot resolve global variable, key = %d", eaddr); + return false; + } + } else { + cc_error("internal export fixup error"); + return false; + } + } + instanceof = scri; + pc = 0; + flags = 0; + if (joined != nullptr) + flags = INSTF_SHAREDATA; + scri->instances++; + + if ((scri->instances == 1) && (ccGetOption(SCOPT_AUTOIMPORT) != 0)) { + // import all the exported stuff from this script + for (i = 0; i < scri->numexports; i++) { + if (!ccAddExternalScriptSymbol(scri->exports[i], exports[i], this)) { + cc_error("Export table overflow at '%s'", scri->exports[i]); + return false; + } + } + } + return true; } -void ccInstance::Free() -{ - if (instanceof != nullptr) { - instanceof->instances--; - if (instanceof->instances == 0) - { - simp.RemoveScriptExports(this); - } - } - - // remove from the Active Instances list - if (loadedInstances[loadedInstanceId] == this) - loadedInstances[loadedInstanceId] = nullptr; - - if ((flags & INSTF_SHAREDATA) == 0) - { - nullfree(globaldata); - nullfree(code); - } - globalvars.reset(); - globaldata = nullptr; - code = nullptr; - strings = nullptr; - - delete [] stack; - delete [] stackdata; - delete [] exports; - stack = nullptr; - stackdata = nullptr; - exports = nullptr; - - if ((flags & INSTF_SHAREDATA) == 0) - { - delete [] resolved_imports; - delete [] code_fixups; - } - resolved_imports = nullptr; - code_fixups = nullptr; +void ccInstance::Free() { + if (instanceof != nullptr) { + instanceof->instances--; + if (instanceof->instances == 0) { + simp.RemoveScriptExports(this); + } + } + + // remove from the Active Instances list + if (loadedInstances[loadedInstanceId] == this) + loadedInstances[loadedInstanceId] = nullptr; + + if ((flags & INSTF_SHAREDATA) == 0) { + nullfree(globaldata); + nullfree(code); + } + globalvars.reset(); + globaldata = nullptr; + code = nullptr; + strings = nullptr; + + delete [] stack; + delete [] stackdata; + delete [] exports; + stack = nullptr; + stackdata = nullptr; + exports = nullptr; + + if ((flags & INSTF_SHAREDATA) == 0) { + delete [] resolved_imports; + delete [] code_fixups; + } + resolved_imports = nullptr; + code_fixups = nullptr; } -bool ccInstance::ResolveScriptImports(PScript scri) -{ - // When the import is referenced in code, it's being addressed - // by it's index in the script imports array. That index is - // NOT unique and relative to script only. - // Script keeps information of used imports as an array of - // names. - // To allow real-time import use we should put resolved imports - // to the array keeping the order of their names in script's - // array of names. - - // resolve all imports referenced in the script - numimports = scri->numimports; - if (numimports == 0) - { - resolved_imports = nullptr; - return false; - } - resolved_imports = new int[numimports]; - - for (int i = 0; i < scri->numimports; ++i) { - // MACPORT FIX 9/6/5: changed from NULL TO 0 - if (scri->imports[i] == nullptr) { - continue; - } - - resolved_imports[i] = simp.get_index_of(scri->imports[i]); - if (resolved_imports[i] < 0) { - cc_error("unresolved import '%s'", scri->imports[i]); - return false; - } - } - return true; +bool ccInstance::ResolveScriptImports(PScript scri) { + // When the import is referenced in code, it's being addressed + // by it's index in the script imports array. That index is + // NOT unique and relative to script only. + // Script keeps information of used imports as an array of + // names. + // To allow real-time import use we should put resolved imports + // to the array keeping the order of their names in script's + // array of names. + + // resolve all imports referenced in the script + numimports = scri->numimports; + if (numimports == 0) { + resolved_imports = nullptr; + return false; + } + resolved_imports = new int[numimports]; + + for (int i = 0; i < scri->numimports; ++i) { + // MACPORT FIX 9/6/5: changed from NULL TO 0 + if (scri->imports[i] == nullptr) { + continue; + } + + resolved_imports[i] = simp.get_index_of(scri->imports[i]); + if (resolved_imports[i] < 0) { + cc_error("unresolved import '%s'", scri->imports[i]); + return false; + } + } + return true; } // TODO: it is possible to deduce global var's size at start with // certain accuracy after all global vars are registered. Each // global var's size would be limited by closest next var's ScAddress // and globaldatasize. -bool ccInstance::CreateGlobalVars(PScript scri) -{ - ScriptVariable glvar; - - // Step One: deduce global variables from fixups - for (int i = 0; i < scri->numfixups; ++i) - { - switch (scri->fixuptypes[i]) - { - case FIXUP_GLOBALDATA: - // GLOBALDATA fixup takes relative address of global data element from code array; - // this is the address of actual data - glvar.ScAddress = (int32_t)code[scri->fixups[i]]; - glvar.RValue.SetData(globaldata + glvar.ScAddress, 0); - break; - case FIXUP_DATADATA: - { - // DATADATA fixup takes relative address of global data element from fixups array; - // this is the address of element, which stores address of actual data - glvar.ScAddress = scri->fixups[i]; - int32_t data_addr = BBOp::Int32FromLE(*(int32_t*)&globaldata[glvar.ScAddress]); - if (glvar.ScAddress - data_addr != 200 /* size of old AGS string */) - { - // CHECKME: probably replace with mere warning in the log? - cc_error("unexpected old-style string's alignment"); - return false; - } - // TODO: register this explicitly as a string instead (can do this later) - glvar.RValue.SetStaticObject(globaldata + data_addr, &GlobalStaticManager); - } - break; - default: - // other fixups are of no use here - continue; - } - - AddGlobalVar(glvar); - } - - // Step Two: deduce global variables from exports - for (int i = 0; i < scri->numexports; ++i) - { - int32_t etype = (scri->export_addr[i] >> 24L) & 0x000ff; - int32_t eaddr = (scri->export_addr[i] & 0x00ffffff); - if (etype == EXPORT_DATA) - { - // NOTE: old-style strings could not be exported in AGS, - // no need to worry about these here - glvar.ScAddress = eaddr; - glvar.RValue.SetData(globaldata + glvar.ScAddress, 0); - AddGlobalVar(glvar); - } - } - - return true; +bool ccInstance::CreateGlobalVars(PScript scri) { + ScriptVariable glvar; + + // Step One: deduce global variables from fixups + for (int i = 0; i < scri->numfixups; ++i) { + switch (scri->fixuptypes[i]) { + case FIXUP_GLOBALDATA: + // GLOBALDATA fixup takes relative address of global data element from code array; + // this is the address of actual data + glvar.ScAddress = (int32_t)code[scri->fixups[i]]; + glvar.RValue.SetData(globaldata + glvar.ScAddress, 0); + break; + case FIXUP_DATADATA: { + // DATADATA fixup takes relative address of global data element from fixups array; + // this is the address of element, which stores address of actual data + glvar.ScAddress = scri->fixups[i]; + int32_t data_addr = BBOp::Int32FromLE(*(int32_t *)&globaldata[glvar.ScAddress]); + if (glvar.ScAddress - data_addr != 200 /* size of old AGS string */) { + // CHECKME: probably replace with mere warning in the log? + cc_error("unexpected old-style string's alignment"); + return false; + } + // TODO: register this explicitly as a string instead (can do this later) + glvar.RValue.SetStaticObject(globaldata + data_addr, &GlobalStaticManager); + } + break; + default: + // other fixups are of no use here + continue; + } + + AddGlobalVar(glvar); + } + + // Step Two: deduce global variables from exports + for (int i = 0; i < scri->numexports; ++i) { + int32_t etype = (scri->export_addr[i] >> 24L) & 0x000ff; + int32_t eaddr = (scri->export_addr[i] & 0x00ffffff); + if (etype == EXPORT_DATA) { + // NOTE: old-style strings could not be exported in AGS, + // no need to worry about these here + glvar.ScAddress = eaddr; + glvar.RValue.SetData(globaldata + glvar.ScAddress, 0); + AddGlobalVar(glvar); + } + } + + return true; } -bool ccInstance::AddGlobalVar(const ScriptVariable &glvar) -{ - // [IKM] 2013-02-23: - // !!! TODO - // "Metal Dead" game (built with AGS 3.21.1115) fails to pass this check, - // because one of its fixups in script creates reference beyond global - // data buffer. The error will be suppressed until root of the problem is - // found, and some proper workaround invented. - if (glvar.ScAddress < 0 || glvar.ScAddress >= globaldatasize) - { - /* - return false; - */ - Debug::Printf(kDbgMsg_Warn, "WARNING: global variable refers to data beyond allocated buffer (%d, %d)", glvar.ScAddress, globaldatasize); - } - globalvars->insert(std::make_pair(glvar.ScAddress, glvar)); - return true; +bool ccInstance::AddGlobalVar(const ScriptVariable &glvar) { + // [IKM] 2013-02-23: + // !!! TODO + // "Metal Dead" game (built with AGS 3.21.1115) fails to pass this check, + // because one of its fixups in script creates reference beyond global + // data buffer. The error will be suppressed until root of the problem is + // found, and some proper workaround invented. + if (glvar.ScAddress < 0 || glvar.ScAddress >= globaldatasize) { + /* + return false; + */ + Debug::Printf(kDbgMsg_Warn, "WARNING: global variable refers to data beyond allocated buffer (%d, %d)", glvar.ScAddress, globaldatasize); + } + globalvars->insert(std::make_pair(glvar.ScAddress, glvar)); + return true; } -ScriptVariable *ccInstance::FindGlobalVar(int32_t var_addr) -{ - // NOTE: see comment for AddGlobalVar() - if (var_addr < 0 || var_addr >= globaldatasize) - { - /* - return NULL; - */ - Debug::Printf(kDbgMsg_Warn, "WARNING: looking up for global variable beyond allocated buffer (%d, %d)", var_addr, globaldatasize); - } - ScVarMap::iterator it = globalvars->find(var_addr); - return it != globalvars->end() ? &it->second : nullptr; +ScriptVariable *ccInstance::FindGlobalVar(int32_t var_addr) { + // NOTE: see comment for AddGlobalVar() + if (var_addr < 0 || var_addr >= globaldatasize) { + /* + return NULL; + */ + Debug::Printf(kDbgMsg_Warn, "WARNING: looking up for global variable beyond allocated buffer (%d, %d)", var_addr, globaldatasize); + } + ScVarMap::iterator it = globalvars->find(var_addr); + return it != globalvars->end() ? &it->second : nullptr; } -bool ccInstance::CreateRuntimeCodeFixups(PScript scri) -{ - code_fixups = new char[scri->codesize]; - memset(code_fixups, 0, scri->codesize); - for (int i = 0; i < scri->numfixups; ++i) - { - if (scri->fixuptypes[i] == FIXUP_DATADATA) - { - continue; - } - - int32_t fixup = scri->fixups[i]; - code_fixups[fixup] = scri->fixuptypes[i]; - - switch (scri->fixuptypes[i]) - { - case FIXUP_GLOBALDATA: - { - ScriptVariable *gl_var = FindGlobalVar((int32_t)code[fixup]); - if (!gl_var) - { - cc_error("cannot resolve global variable, key = %d", (int32_t)code[fixup]); - return false; - } - code[fixup] = (intptr_t)gl_var; - } - break; - case FIXUP_FUNCTION: - case FIXUP_STRING: - case FIXUP_STACK: - break; // do nothing yet - case FIXUP_IMPORT: - // we do not need to save import's address now when we have - // resolved imports kept so far as instance exists, but we - // must fixup the following instruction in certain case - { - int import_index = resolved_imports[code[fixup]]; - const ScriptImport *import = simp.getByIndex(import_index); - if (!import) - { - cc_error("cannot resolve import, key = %d", import_index); - return false; - } - code[fixup] = import_index; - // If the call is to another script function next CALLEXT - // must be replaced with CALLAS - if (import->InstancePtr != nullptr && (code[fixup + 1] & INSTANCE_ID_REMOVEMASK) == SCMD_CALLEXT) - { - code[fixup + 1] = SCMD_CALLAS | (import->InstancePtr->loadedInstanceId << INSTANCE_ID_SHIFT); - } - } - break; - default: - cc_error("internal fixup index error: %d", scri->fixuptypes[i]); - return false; - } - } - return true; +bool ccInstance::CreateRuntimeCodeFixups(PScript scri) { + code_fixups = new char[scri->codesize]; + memset(code_fixups, 0, scri->codesize); + for (int i = 0; i < scri->numfixups; ++i) { + if (scri->fixuptypes[i] == FIXUP_DATADATA) { + continue; + } + + int32_t fixup = scri->fixups[i]; + code_fixups[fixup] = scri->fixuptypes[i]; + + switch (scri->fixuptypes[i]) { + case FIXUP_GLOBALDATA: { + ScriptVariable *gl_var = FindGlobalVar((int32_t)code[fixup]); + if (!gl_var) { + cc_error("cannot resolve global variable, key = %d", (int32_t)code[fixup]); + return false; + } + code[fixup] = (intptr_t)gl_var; + } + break; + case FIXUP_FUNCTION: + case FIXUP_STRING: + case FIXUP_STACK: + break; // do nothing yet + case FIXUP_IMPORT: + // we do not need to save import's address now when we have + // resolved imports kept so far as instance exists, but we + // must fixup the following instruction in certain case + { + int import_index = resolved_imports[code[fixup]]; + const ScriptImport *import = simp.getByIndex(import_index); + if (!import) { + cc_error("cannot resolve import, key = %d", import_index); + return false; + } + code[fixup] = import_index; + // If the call is to another script function next CALLEXT + // must be replaced with CALLAS + if (import->InstancePtr != nullptr && (code[fixup + 1] & INSTANCE_ID_REMOVEMASK) == SCMD_CALLEXT) { + code[fixup + 1] = SCMD_CALLAS | (import->InstancePtr->loadedInstanceId << INSTANCE_ID_SHIFT); + } + } + break; + default: + cc_error("internal fixup index error: %d", scri->fixuptypes[i]); + return false; + } + } + return true; } /* bool ccInstance::ReadOperation(ScriptOperation &op, int32_t at_pc) { - op.Instruction.Code = code[at_pc]; - op.Instruction.InstanceId = (op.Instruction.Code >> INSTANCE_ID_SHIFT) & INSTANCE_ID_MASK; - op.Instruction.Code &= INSTANCE_ID_REMOVEMASK; // now this is pure instruction code + op.Instruction.Code = code[at_pc]; + op.Instruction.InstanceId = (op.Instruction.Code >> INSTANCE_ID_SHIFT) & INSTANCE_ID_MASK; + op.Instruction.Code &= INSTANCE_ID_REMOVEMASK; // now this is pure instruction code int want_args = sccmd_info[op.Instruction.Code].ArgCount; if (at_pc + want_args >= codesize) @@ -1854,158 +1694,128 @@ bool ccInstance::FixupArgument(intptr_t code_value, char fixup_type, RuntimeScri */ //----------------------------------------------------------------------------- -void ccInstance::PushValueToStack(const RuntimeScriptValue &rval) -{ - // Write value to the stack tail and advance stack ptr - registers[SREG_SP].WriteValue(rval); - registers[SREG_SP].RValue++; +void ccInstance::PushValueToStack(const RuntimeScriptValue &rval) { + // Write value to the stack tail and advance stack ptr + registers[SREG_SP].WriteValue(rval); + registers[SREG_SP].RValue++; } -void ccInstance::PushDataToStack(int32_t num_bytes) -{ - if (registers[SREG_SP].RValue->IsValid()) - { - cc_error("internal error: valid data beyond stack ptr"); - return; - } - // Zero memory, assign pointer to data block to the stack tail, advance both stack ptr and stack data ptr - memset(stackdata_ptr, 0, num_bytes); - registers[SREG_SP].RValue->SetData(stackdata_ptr, num_bytes); - stackdata_ptr += num_bytes; - registers[SREG_SP].RValue++; +void ccInstance::PushDataToStack(int32_t num_bytes) { + if (registers[SREG_SP].RValue->IsValid()) { + cc_error("internal error: valid data beyond stack ptr"); + return; + } + // Zero memory, assign pointer to data block to the stack tail, advance both stack ptr and stack data ptr + memset(stackdata_ptr, 0, num_bytes); + registers[SREG_SP].RValue->SetData(stackdata_ptr, num_bytes); + stackdata_ptr += num_bytes; + registers[SREG_SP].RValue++; } -RuntimeScriptValue ccInstance::PopValueFromStack() -{ - // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail - registers[SREG_SP].RValue--; - RuntimeScriptValue rval = *registers[SREG_SP].RValue; - if (rval.Type == kScValData) - { - stackdata_ptr -= rval.Size; - } - registers[SREG_SP].RValue->Invalidate(); - return rval; +RuntimeScriptValue ccInstance::PopValueFromStack() { + // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail + registers[SREG_SP].RValue--; + RuntimeScriptValue rval = *registers[SREG_SP].RValue; + if (rval.Type == kScValData) { + stackdata_ptr -= rval.Size; + } + registers[SREG_SP].RValue->Invalidate(); + return rval; } -void ccInstance::PopValuesFromStack(int32_t num_entries = 1) -{ - for (int i = 0; i < num_entries; ++i) - { - // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail - registers[SREG_SP].RValue--; - if (registers[SREG_SP].RValue->Type == kScValData) - { - stackdata_ptr -= registers[SREG_SP].RValue->Size; - } - registers[SREG_SP].RValue->Invalidate(); - } +void ccInstance::PopValuesFromStack(int32_t num_entries = 1) { + for (int i = 0; i < num_entries; ++i) { + // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail + registers[SREG_SP].RValue--; + if (registers[SREG_SP].RValue->Type == kScValData) { + stackdata_ptr -= registers[SREG_SP].RValue->Size; + } + registers[SREG_SP].RValue->Invalidate(); + } } -void ccInstance::PopDataFromStack(int32_t num_bytes) -{ - int32_t total_pop = 0; - while (total_pop < num_bytes && registers[SREG_SP].RValue > &stack[0]) - { - // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail - registers[SREG_SP].RValue--; - // remember popped bytes count - total_pop += registers[SREG_SP].RValue->Size; - if (registers[SREG_SP].RValue->Type == kScValData) - { - stackdata_ptr -= registers[SREG_SP].RValue->Size; - } - registers[SREG_SP].RValue->Invalidate(); - } - if (total_pop < num_bytes) - { - cc_error("stack underflow"); - } - else if (total_pop > num_bytes) - { - cc_error("stack pointer points inside local variable after pop, stack corrupted?"); - } +void ccInstance::PopDataFromStack(int32_t num_bytes) { + int32_t total_pop = 0; + while (total_pop < num_bytes && registers[SREG_SP].RValue > &stack[0]) { + // rewind stack ptr to the last valid value, decrement stack data ptr if needed and invalidate the stack tail + registers[SREG_SP].RValue--; + // remember popped bytes count + total_pop += registers[SREG_SP].RValue->Size; + if (registers[SREG_SP].RValue->Type == kScValData) { + stackdata_ptr -= registers[SREG_SP].RValue->Size; + } + registers[SREG_SP].RValue->Invalidate(); + } + if (total_pop < num_bytes) { + cc_error("stack underflow"); + } else if (total_pop > num_bytes) { + cc_error("stack pointer points inside local variable after pop, stack corrupted?"); + } } -RuntimeScriptValue ccInstance::GetStackPtrOffsetFw(int32_t fw_offset) -{ - int32_t total_off = 0; - RuntimeScriptValue *stack_entry = &stack[0]; - while (total_off < fw_offset && stack_entry - &stack[0] < CC_STACK_SIZE ) - { - if (stack_entry->Size > 0) - { - total_off += stack_entry->Size; - } - stack_entry++; - } - if (total_off < fw_offset) - { - cc_error("accessing address beyond stack's tail"); - return RuntimeScriptValue(); - } - RuntimeScriptValue stack_ptr; - stack_ptr.SetStackPtr(stack_entry); - if (total_off > fw_offset) - { - // Forward offset should always set ptr at the beginning of stack entry - cc_error("stack offset forward: trying to access stack data inside stack entry, stack corrupted?"); - } - return stack_ptr; +RuntimeScriptValue ccInstance::GetStackPtrOffsetFw(int32_t fw_offset) { + int32_t total_off = 0; + RuntimeScriptValue *stack_entry = &stack[0]; + while (total_off < fw_offset && stack_entry - &stack[0] < CC_STACK_SIZE) { + if (stack_entry->Size > 0) { + total_off += stack_entry->Size; + } + stack_entry++; + } + if (total_off < fw_offset) { + cc_error("accessing address beyond stack's tail"); + return RuntimeScriptValue(); + } + RuntimeScriptValue stack_ptr; + stack_ptr.SetStackPtr(stack_entry); + if (total_off > fw_offset) { + // Forward offset should always set ptr at the beginning of stack entry + cc_error("stack offset forward: trying to access stack data inside stack entry, stack corrupted?"); + } + return stack_ptr; } -RuntimeScriptValue ccInstance::GetStackPtrOffsetRw(int32_t rw_offset) -{ - int32_t total_off = 0; - RuntimeScriptValue *stack_entry = registers[SREG_SP].RValue; - while (total_off < rw_offset && stack_entry >= &stack[0]) - { - stack_entry--; - total_off += stack_entry->Size; - } - if (total_off < rw_offset) - { - cc_error("accessing address before stack's head"); - return RuntimeScriptValue(); - } - RuntimeScriptValue stack_ptr; - stack_ptr.SetStackPtr(stack_entry); - if (total_off > rw_offset) - { - // Could be accessing array element, so state error only if stack entry does not refer to data array - if (stack_entry->Type == kScValData) - { - stack_ptr.IValue += total_off - rw_offset; - } - else - { - cc_error("stack offset backward: trying to access stack data inside stack entry, stack corrupted?"); - } - } - return stack_ptr; +RuntimeScriptValue ccInstance::GetStackPtrOffsetRw(int32_t rw_offset) { + int32_t total_off = 0; + RuntimeScriptValue *stack_entry = registers[SREG_SP].RValue; + while (total_off < rw_offset && stack_entry >= &stack[0]) { + stack_entry--; + total_off += stack_entry->Size; + } + if (total_off < rw_offset) { + cc_error("accessing address before stack's head"); + return RuntimeScriptValue(); + } + RuntimeScriptValue stack_ptr; + stack_ptr.SetStackPtr(stack_entry); + if (total_off > rw_offset) { + // Could be accessing array element, so state error only if stack entry does not refer to data array + if (stack_entry->Type == kScValData) { + stack_ptr.IValue += total_off - rw_offset; + } else { + cc_error("stack offset backward: trying to access stack data inside stack entry, stack corrupted?"); + } + } + return stack_ptr; } -void ccInstance::PushToFuncCallStack(FunctionCallStack &func_callstack, const RuntimeScriptValue &rval) -{ - if (func_callstack.Count >= MAX_FUNC_PARAMS) - { - cc_error("function callstack overflow"); - return; - } +void ccInstance::PushToFuncCallStack(FunctionCallStack &func_callstack, const RuntimeScriptValue &rval) { + if (func_callstack.Count >= MAX_FUNC_PARAMS) { + cc_error("function callstack overflow"); + return; + } - func_callstack.Entries[func_callstack.Head] = rval; - func_callstack.Head--; - func_callstack.Count++; + func_callstack.Entries[func_callstack.Head] = rval; + func_callstack.Head--; + func_callstack.Count++; } -void ccInstance::PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries) -{ - if (func_callstack.Count == 0) - { - cc_error("function callstack underflow"); - return; - } +void ccInstance::PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries) { + if (func_callstack.Count == 0) { + cc_error("function callstack underflow"); + return; + } - func_callstack.Head += num_entries; - func_callstack.Count -= num_entries; + func_callstack.Head += num_entries; + func_callstack.Count -= num_entries; } diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h index 725f3681e64c..1826feb79d6b 100644 --- a/engines/ags/engine/script/cc_instance.h +++ b/engines/ags/engine/script/cc_instance.h @@ -57,175 +57,165 @@ using namespace AGS; struct ccInstance; struct ScriptImport; -struct ScriptInstruction -{ - ScriptInstruction() - { - Code = 0; - InstanceId = 0; - } - - int32_t Code; - int32_t InstanceId; +struct ScriptInstruction { + ScriptInstruction() { + Code = 0; + InstanceId = 0; + } + + int32_t Code; + int32_t InstanceId; }; -struct ScriptOperation -{ - ScriptOperation() - { +struct ScriptOperation { + ScriptOperation() { ArgCount = 0; } ScriptInstruction Instruction; - RuntimeScriptValue Args[MAX_SCMD_ARGS]; - int ArgCount; + RuntimeScriptValue Args[MAX_SCMD_ARGS]; + int ArgCount; }; -struct ScriptVariable -{ - ScriptVariable() - { - ScAddress = -1; // address = 0 is valid one, -1 means undefined - } +struct ScriptVariable { + ScriptVariable() { + ScAddress = -1; // address = 0 is valid one, -1 means undefined + } - int32_t ScAddress; // original 32-bit relative data address, written in compiled script; - // if we are to use Map or HashMap, this could be used as Key - RuntimeScriptValue RValue; + int32_t ScAddress; // original 32-bit relative data address, written in compiled script; + // if we are to use Map or HashMap, this could be used as Key + RuntimeScriptValue RValue; }; struct FunctionCallStack; -struct ScriptPosition -{ - ScriptPosition() - : Line(0) - { - } - - ScriptPosition(const Common::String §ion, int32_t line) - : Section(section) - , Line(line) - { - } - - Common::String Section; - int32_t Line; +struct ScriptPosition { + ScriptPosition() + : Line(0) { + } + + ScriptPosition(const Common::String §ion, int32_t line) + : Section(section) + , Line(line) { + } + + Common::String Section; + int32_t Line; }; // Running instance of the script -struct ccInstance -{ +struct ccInstance { public: - // TODO: change to std:: if moved to C++11 - typedef std::unordered_map ScVarMap; - typedef std::shared_ptr PScVarMap; + // TODO: change to std:: if moved to C++11 + typedef std::unordered_map ScVarMap; + typedef std::shared_ptr PScVarMap; public: - int32_t flags; - PScVarMap globalvars; - char *globaldata; - int32_t globaldatasize; - // Executed byte-code. Unlike ccScript's code array which is int32_t, the one - // in ccInstance must be intptr_t to accomodate real pointers placed after - // performing fixups. - intptr_t *code; - ccInstance *runningInst; // might point to another instance if in far call - int32_t codesize; - char *strings; - int32_t stringssize; - RuntimeScriptValue *exports; - RuntimeScriptValue *stack; - int num_stackentries; - // An array for keeping stack data; stack entries reference unknown data from here - // TODO: probably change to dynamic array later - char *stackdata; // for storing stack data of unknown type - char *stackdata_ptr;// works similar to original stack pointer, points to the next unused byte in stack data array - int32_t stackdatasize; // conventional size of stack data in bytes - // - RuntimeScriptValue registers[CC_NUM_REGISTERS]; - int32_t pc; // program counter - int32_t line_number; // source code line number - PScript instanceof; - int loadedInstanceId; - int returnValue; - - int callStackSize; - int32_t callStackLineNumber[MAX_CALL_STACK]; - int32_t callStackAddr[MAX_CALL_STACK]; - ccInstance *callStackCodeInst[MAX_CALL_STACK]; - - // array of real import indexes used in script - int *resolved_imports; - int numimports; - - char *code_fixups; - - // returns the currently executing instance, or NULL if none - static ccInstance *GetCurrentInstance(void); - // create a runnable instance of the supplied script - static ccInstance *CreateFromScript(PScript script); - static ccInstance *CreateEx(PScript scri, ccInstance * joined); - - ccInstance(); - ~ccInstance(); - // Create a runnable instance of the same script, sharing global memory - ccInstance *Fork(); - // Specifies that when the current function returns to the script, it - // will stop and return from CallInstance - void Abort(); - // Aborts instance, then frees the memory later when it is done with - void AbortAndDestroy(); - - // Call an exported function in the script - int CallScriptFunction(const char *funcname, int32_t num_params, const RuntimeScriptValue *params); - // Begin executing script starting from the given bytecode index - int Run(int32_t curpc); - - // Get the script's execution position and callstack as human-readable text - Common::String GetCallStack(int maxLines); - // Get the script's execution position - void GetScriptPosition(ScriptPosition &script_pos); - // Get the address of an exported symbol (function or variable) in the script - RuntimeScriptValue GetSymbolAddress(const char *symname); - void DumpInstruction(const ScriptOperation &op); - // Tells whether this instance is in the process of executing the byte-code - bool IsBeingRun() const; + int32_t flags; + PScVarMap globalvars; + char *globaldata; + int32_t globaldatasize; + // Executed byte-code. Unlike ccScript's code array which is int32_t, the one + // in ccInstance must be intptr_t to accomodate real pointers placed after + // performing fixups. + intptr_t *code; + ccInstance *runningInst; // might point to another instance if in far call + int32_t codesize; + char *strings; + int32_t stringssize; + RuntimeScriptValue *exports; + RuntimeScriptValue *stack; + int num_stackentries; + // An array for keeping stack data; stack entries reference unknown data from here + // TODO: probably change to dynamic array later + char *stackdata; // for storing stack data of unknown type + char *stackdata_ptr;// works similar to original stack pointer, points to the next unused byte in stack data array + int32_t stackdatasize; // conventional size of stack data in bytes + // + RuntimeScriptValue registers[CC_NUM_REGISTERS]; + int32_t pc; // program counter + int32_t line_number; // source code line number + PScript instanceof; + int loadedInstanceId; + int returnValue; + + int callStackSize; + int32_t callStackLineNumber[MAX_CALL_STACK]; + int32_t callStackAddr[MAX_CALL_STACK]; + ccInstance *callStackCodeInst[MAX_CALL_STACK]; + + // array of real import indexes used in script + int *resolved_imports; + int numimports; + + char *code_fixups; + + // returns the currently executing instance, or NULL if none + static ccInstance *GetCurrentInstance(void); + // create a runnable instance of the supplied script + static ccInstance *CreateFromScript(PScript script); + static ccInstance *CreateEx(PScript scri, ccInstance *joined); + + ccInstance(); + ~ccInstance(); + // Create a runnable instance of the same script, sharing global memory + ccInstance *Fork(); + // Specifies that when the current function returns to the script, it + // will stop and return from CallInstance + void Abort(); + // Aborts instance, then frees the memory later when it is done with + void AbortAndDestroy(); + + // Call an exported function in the script + int CallScriptFunction(const char *funcname, int32_t num_params, const RuntimeScriptValue *params); + // Begin executing script starting from the given bytecode index + int Run(int32_t curpc); + + // Get the script's execution position and callstack as human-readable text + Common::String GetCallStack(int maxLines); + // Get the script's execution position + void GetScriptPosition(ScriptPosition &script_pos); + // Get the address of an exported symbol (function or variable) in the script + RuntimeScriptValue GetSymbolAddress(const char *symname); + void DumpInstruction(const ScriptOperation &op); + // Tells whether this instance is in the process of executing the byte-code + bool IsBeingRun() const; protected: - bool _Create(PScript scri, ccInstance * joined); - // free the memory associated with the instance - void Free(); - - bool ResolveScriptImports(PScript scri); - bool CreateGlobalVars(PScript scri); - bool AddGlobalVar(const ScriptVariable &glvar); - ScriptVariable *FindGlobalVar(int32_t var_addr); - bool CreateRuntimeCodeFixups(PScript scri); + bool _Create(PScript scri, ccInstance *joined); + // free the memory associated with the instance + void Free(); + + bool ResolveScriptImports(PScript scri); + bool CreateGlobalVars(PScript scri); + bool AddGlobalVar(const ScriptVariable &glvar); + ScriptVariable *FindGlobalVar(int32_t var_addr); + bool CreateRuntimeCodeFixups(PScript scri); //bool ReadOperation(ScriptOperation &op, int32_t at_pc); - // Runtime fixups - //bool FixupArgument(intptr_t code_value, char fixup_type, RuntimeScriptValue &argument); - - // Stack processing - // Push writes new value and increments stack ptr; - // stack ptr now points to the __next empty__ entry - void PushValueToStack(const RuntimeScriptValue &rval); - void PushDataToStack(int32_t num_bytes); - // Pop decrements stack ptr, returns last stored value and invalidates! stack tail; - // stack ptr now points to the __next empty__ entry - RuntimeScriptValue PopValueFromStack(); - // helper function to pop & dump several values - void PopValuesFromStack(int32_t num_entries); - void PopDataFromStack(int32_t num_bytes); - // Return stack ptr at given offset from stack head; - // Offset is in data bytes; program stack ptr is __not__ changed - RuntimeScriptValue GetStackPtrOffsetFw(int32_t fw_offset); - // Return stack ptr at given offset from stack tail; - // Offset is in data bytes; program stack ptr is __not__ changed - RuntimeScriptValue GetStackPtrOffsetRw(int32_t rw_offset); - - // Function call stack processing - void PushToFuncCallStack(FunctionCallStack &func_callstack, const RuntimeScriptValue &rval); - void PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries); + // Runtime fixups + //bool FixupArgument(intptr_t code_value, char fixup_type, RuntimeScriptValue &argument); + + // Stack processing + // Push writes new value and increments stack ptr; + // stack ptr now points to the __next empty__ entry + void PushValueToStack(const RuntimeScriptValue &rval); + void PushDataToStack(int32_t num_bytes); + // Pop decrements stack ptr, returns last stored value and invalidates! stack tail; + // stack ptr now points to the __next empty__ entry + RuntimeScriptValue PopValueFromStack(); + // helper function to pop & dump several values + void PopValuesFromStack(int32_t num_entries); + void PopDataFromStack(int32_t num_bytes); + // Return stack ptr at given offset from stack head; + // Offset is in data bytes; program stack ptr is __not__ changed + RuntimeScriptValue GetStackPtrOffsetFw(int32_t fw_offset); + // Return stack ptr at given offset from stack tail; + // Offset is in data bytes; program stack ptr is __not__ changed + RuntimeScriptValue GetStackPtrOffsetRw(int32_t rw_offset); + + // Function call stack processing + void PushToFuncCallStack(FunctionCallStack &func_callstack, const RuntimeScriptValue &rval); + void PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries); }; #endif diff --git a/engines/ags/engine/script/executingscript.cpp b/engines/ags/engine/script/executingscript.cpp index 634b5352cb78..41d8f87a17cc 100644 --- a/engines/ags/engine/script/executingscript.cpp +++ b/engines/ags/engine/script/executingscript.cpp @@ -26,71 +26,70 @@ #include "debug/debugger.h" QueuedScript::QueuedScript() - : Instance(kScInstGame) - , ParamCount(0) -{ + : Instance(kScInstGame) + , ParamCount(0) { } int ExecutingScript::queue_action(PostScriptAction act, int data, const char *aname) { - if (numPostScriptActions >= MAX_QUEUED_ACTIONS) - quitprintf("!%s: Cannot queue action, post-script queue full", aname); + if (numPostScriptActions >= MAX_QUEUED_ACTIONS) + quitprintf("!%s: Cannot queue action, post-script queue full", aname); - if (numPostScriptActions > 0) { - // if something that will terminate the room has already - // been queued, don't allow a second thing to be queued - switch (postScriptActions[numPostScriptActions - 1]) { - case ePSANewRoom: - case ePSARestoreGame: - case ePSARestoreGameDialog: - case ePSARunAGSGame: - case ePSARestartGame: - quitprintf("!%s: Cannot run this command, since there was a %s command already queued to run in \"%s\", line %d", - aname, postScriptActionNames[numPostScriptActions - 1], - postScriptActionPositions[numPostScriptActions - 1].Section.GetCStr(), postScriptActionPositions[numPostScriptActions - 1].Line); - break; - // MACPORT FIX 9/6/5: added default clause to remove warning - default: - break; - } - } + if (numPostScriptActions > 0) { + // if something that will terminate the room has already + // been queued, don't allow a second thing to be queued + switch (postScriptActions[numPostScriptActions - 1]) { + case ePSANewRoom: + case ePSARestoreGame: + case ePSARestoreGameDialog: + case ePSARunAGSGame: + case ePSARestartGame: + quitprintf("!%s: Cannot run this command, since there was a %s command already queued to run in \"%s\", line %d", + aname, postScriptActionNames[numPostScriptActions - 1], + postScriptActionPositions[numPostScriptActions - 1].Section.GetCStr(), postScriptActionPositions[numPostScriptActions - 1].Line); + break; + // MACPORT FIX 9/6/5: added default clause to remove warning + default: + break; + } + } - postScriptActions[numPostScriptActions] = act; - postScriptActionData[numPostScriptActions] = data; - postScriptActionNames[numPostScriptActions] = aname; - get_script_position(postScriptActionPositions[numPostScriptActions]); - numPostScriptActions++; - return numPostScriptActions - 1; + postScriptActions[numPostScriptActions] = act; + postScriptActionData[numPostScriptActions] = data; + postScriptActionNames[numPostScriptActions] = aname; + get_script_position(postScriptActionPositions[numPostScriptActions]); + numPostScriptActions++; + return numPostScriptActions - 1; } void ExecutingScript::run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) { - if (numanother < MAX_QUEUED_SCRIPTS) - numanother++; - else { - /*debug_script_warn("Warning: too many scripts to run, ignored %s(%d,%d)", - script_run_another[numanother - 1], run_another_p1[numanother - 1], - run_another_p2[numanother - 1]);*/ - } - int thisslot = numanother - 1; - QueuedScript &script = ScFnQueue[thisslot]; - script.FnName.SetString(namm, MAX_FUNCTION_NAME_LEN); - script.Instance = scinst; - script.ParamCount = param_count; - script.Param1 = p1; - script.Param2 = p2; + if (numanother < MAX_QUEUED_SCRIPTS) + numanother++; + else { + /*debug_script_warn("Warning: too many scripts to run, ignored %s(%d,%d)", + script_run_another[numanother - 1], run_another_p1[numanother - 1], + run_another_p2[numanother - 1]);*/ + } + int thisslot = numanother - 1; + QueuedScript &script = ScFnQueue[thisslot]; + script.FnName.SetString(namm, MAX_FUNCTION_NAME_LEN); + script.Instance = scinst; + script.ParamCount = param_count; + script.Param1 = p1; + script.Param2 = p2; } void ExecutingScript::init() { - inst = nullptr; - forked = 0; - numanother = 0; - numPostScriptActions = 0; + inst = nullptr; + forked = 0; + numanother = 0; + numPostScriptActions = 0; - memset(postScriptActions, 0, sizeof(postScriptActions)); - memset(postScriptActionNames, 0, sizeof(postScriptActionNames)); - memset(postScriptSaveSlotDescription, 0, sizeof(postScriptSaveSlotDescription)); - memset(postScriptActionData, 0, sizeof(postScriptActionData)); + memset(postScriptActions, 0, sizeof(postScriptActions)); + memset(postScriptActionNames, 0, sizeof(postScriptActionNames)); + memset(postScriptSaveSlotDescription, 0, sizeof(postScriptSaveSlotDescription)); + memset(postScriptActionData, 0, sizeof(postScriptActionData)); } ExecutingScript::ExecutingScript() { - init(); + init(); } diff --git a/engines/ags/engine/script/executingscript.h b/engines/ags/engine/script/executingscript.h index 1d09f6781b51..bcc74128a441 100644 --- a/engines/ags/engine/script/executingscript.h +++ b/engines/ags/engine/script/executingscript.h @@ -26,54 +26,52 @@ #include "script/cc_instance.h" enum PostScriptAction { - ePSANewRoom, - ePSAInvScreen, - ePSARestoreGame, - ePSARestoreGameDialog, - ePSARunAGSGame, - ePSARunDialog, - ePSARestartGame, - ePSASaveGame, - ePSASaveGameDialog + ePSANewRoom, + ePSAInvScreen, + ePSARestoreGame, + ePSARestoreGameDialog, + ePSARunAGSGame, + ePSARunDialog, + ePSARestartGame, + ePSASaveGame, + ePSASaveGameDialog }; #define MAX_QUEUED_SCRIPTS 4 #define MAX_QUEUED_ACTIONS 5 #define MAX_FUNCTION_NAME_LEN 60 -enum ScriptInstType -{ - kScInstGame, - kScInstRoom +enum ScriptInstType { + kScInstGame, + kScInstRoom }; -struct QueuedScript -{ - Common::String FnName; - ScriptInstType Instance; - size_t ParamCount; - RuntimeScriptValue Param1; - RuntimeScriptValue Param2; +struct QueuedScript { + Common::String FnName; + ScriptInstType Instance; + size_t ParamCount; + RuntimeScriptValue Param1; + RuntimeScriptValue Param2; - QueuedScript(); + QueuedScript(); }; struct ExecutingScript { - ccInstance *inst; - PostScriptAction postScriptActions[MAX_QUEUED_ACTIONS]; - const char *postScriptActionNames[MAX_QUEUED_ACTIONS]; - ScriptPosition postScriptActionPositions[MAX_QUEUED_ACTIONS]; - char postScriptSaveSlotDescription[MAX_QUEUED_ACTIONS][100]; - int postScriptActionData[MAX_QUEUED_ACTIONS]; - int numPostScriptActions; - QueuedScript ScFnQueue[MAX_QUEUED_SCRIPTS]; - int numanother; - char forked; + ccInstance *inst; + PostScriptAction postScriptActions[MAX_QUEUED_ACTIONS]; + const char *postScriptActionNames[MAX_QUEUED_ACTIONS]; + ScriptPosition postScriptActionPositions[MAX_QUEUED_ACTIONS]; + char postScriptSaveSlotDescription[MAX_QUEUED_ACTIONS][100]; + int postScriptActionData[MAX_QUEUED_ACTIONS]; + int numPostScriptActions; + QueuedScript ScFnQueue[MAX_QUEUED_SCRIPTS]; + int numanother; + char forked; - int queue_action(PostScriptAction act, int data, const char *aname); - void run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2); - void init(); - ExecutingScript(); + int queue_action(PostScriptAction act, int data, const char *aname); + void run_another(const char *namm, ScriptInstType scinst, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2); + void init(); + ExecutingScript(); }; #endif diff --git a/engines/ags/engine/script/exports.cpp b/engines/ags/engine/script/exports.cpp index 2832902275d2..ce217931c2d7 100644 --- a/engines/ags/engine/script/exports.cpp +++ b/engines/ags/engine/script/exports.cpp @@ -66,43 +66,42 @@ extern void RegisterViewportAPI(); extern void RegisterStaticObjects(); -void setup_script_exports(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) -{ - RegisterAudioChannelAPI(); - RegisterAudioClipAPI(); - RegisterButtonAPI(); - RegisterCharacterAPI(base_api, compat_api); - RegisterContainerAPI(); - RegisterDateTimeAPI(); - RegisterDialogAPI(); - RegisterDialogOptionsRenderingAPI(); - RegisterDrawingSurfaceAPI(base_api, compat_api); - RegisterDynamicSpriteAPI(); - RegisterFileAPI(); - RegisterGameAPI(); - RegisterGlobalAPI(); - RegisterGUIAPI(); - RegisterGUIControlAPI(); - RegisterHotspotAPI(); - RegisterInventoryItemAPI(); - RegisterInventoryWindowAPI(); - RegisterLabelAPI(); - RegisterListBoxAPI(); - RegisterMathAPI(); - RegisterMouseAPI(); - RegisterObjectAPI(); - RegisterOverlayAPI(); - RegisterParserAPI(); - RegisterRegionAPI(); - RegisterRoomAPI(); - RegisterScreenAPI(); - RegisterSliderAPI(); - RegisterSpeechAPI(base_api, compat_api); - RegisterStringAPI(); - RegisterSystemAPI(); - RegisterTextBoxAPI(); - RegisterViewFrameAPI(); - RegisterViewportAPI(); +void setup_script_exports(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) { + RegisterAudioChannelAPI(); + RegisterAudioClipAPI(); + RegisterButtonAPI(); + RegisterCharacterAPI(base_api, compat_api); + RegisterContainerAPI(); + RegisterDateTimeAPI(); + RegisterDialogAPI(); + RegisterDialogOptionsRenderingAPI(); + RegisterDrawingSurfaceAPI(base_api, compat_api); + RegisterDynamicSpriteAPI(); + RegisterFileAPI(); + RegisterGameAPI(); + RegisterGlobalAPI(); + RegisterGUIAPI(); + RegisterGUIControlAPI(); + RegisterHotspotAPI(); + RegisterInventoryItemAPI(); + RegisterInventoryWindowAPI(); + RegisterLabelAPI(); + RegisterListBoxAPI(); + RegisterMathAPI(); + RegisterMouseAPI(); + RegisterObjectAPI(); + RegisterOverlayAPI(); + RegisterParserAPI(); + RegisterRegionAPI(); + RegisterRoomAPI(); + RegisterScreenAPI(); + RegisterSliderAPI(); + RegisterSpeechAPI(base_api, compat_api); + RegisterStringAPI(); + RegisterSystemAPI(); + RegisterTextBoxAPI(); + RegisterViewFrameAPI(); + RegisterViewportAPI(); - RegisterStaticObjects(); + RegisterStaticObjects(); } diff --git a/engines/ags/engine/script/nonblockingscriptfunction.h b/engines/ags/engine/script/nonblockingscriptfunction.h index 61b6af800168..9e5da93df7cf 100644 --- a/engines/ags/engine/script/nonblockingscriptfunction.h +++ b/engines/ags/engine/script/nonblockingscriptfunction.h @@ -28,26 +28,24 @@ #include -struct NonBlockingScriptFunction -{ - const char* functionName; - int numParameters; - //void* param1; - //void* param2; - RuntimeScriptValue params[2]; - bool roomHasFunction; - bool globalScriptHasFunction; - std::vector moduleHasFunction; - bool atLeastOneImplementationExists; +struct NonBlockingScriptFunction { + const char *functionName; + int numParameters; + //void* param1; + //void* param2; + RuntimeScriptValue params[2]; + bool roomHasFunction; + bool globalScriptHasFunction; + std::vector moduleHasFunction; + bool atLeastOneImplementationExists; - NonBlockingScriptFunction(const char*funcName, int numParams) - { - this->functionName = funcName; - this->numParameters = numParams; - atLeastOneImplementationExists = false; - roomHasFunction = true; - globalScriptHasFunction = true; - } + NonBlockingScriptFunction(const char *funcName, int numParams) { + this->functionName = funcName; + this->numParameters = numParams; + atLeastOneImplementationExists = false; + roomHasFunction = true; + globalScriptHasFunction = true; + } }; #endif diff --git a/engines/ags/engine/script/runtimescriptvalue.cpp b/engines/ags/engine/script/runtimescriptvalue.cpp index e69a7b0825e5..dac99d5a09dc 100644 --- a/engines/ags/engine/script/runtimescriptvalue.cpp +++ b/engines/ags/engine/script/runtimescriptvalue.cpp @@ -39,304 +39,199 @@ using namespace AGS::Common; // TODO: use endian-agnostic method to access global vars -uint8_t RuntimeScriptValue::ReadByte() -{ - if (this->Type == kScValStackPtr || this->Type == kScValGlobalVar) - { - if (RValue->Type == kScValData) - { - return *(uint8_t*)(RValue->GetPtrWithOffset() + this->IValue); - } - else - { - return RValue->IValue; // get RValue as int - } - } - else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) - { - return this->StcMgr->ReadInt8(this->Ptr, this->IValue); - } - else if (this->Type == kScValDynamicObject) - { - return this->DynMgr->ReadInt8(this->Ptr, this->IValue); - } - return *((uint8_t*)this->GetPtrWithOffset()); +uint8_t RuntimeScriptValue::ReadByte() { + if (this->Type == kScValStackPtr || this->Type == kScValGlobalVar) { + if (RValue->Type == kScValData) { + return *(uint8_t *)(RValue->GetPtrWithOffset() + this->IValue); + } else { + return RValue->IValue; // get RValue as int + } + } else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) { + return this->StcMgr->ReadInt8(this->Ptr, this->IValue); + } else if (this->Type == kScValDynamicObject) { + return this->DynMgr->ReadInt8(this->Ptr, this->IValue); + } + return *((uint8_t *)this->GetPtrWithOffset()); } -int16_t RuntimeScriptValue::ReadInt16() -{ - if (this->Type == kScValStackPtr) - { - if (RValue->Type == kScValData) - { - return *(int16_t*)(RValue->GetPtrWithOffset() + this->IValue); - } - else - { - return RValue->IValue; // get RValue as int - } - } - else if (this->Type == kScValGlobalVar) - { - if (RValue->Type == kScValData) - { - return Memory::ReadInt16LE(RValue->GetPtrWithOffset() + this->IValue); - } - else - { - return RValue->IValue; // get RValue as int - } - } - else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) - { - return this->StcMgr->ReadInt16(this->Ptr, this->IValue); - } - else if (this->Type == kScValDynamicObject) - { - return this->DynMgr->ReadInt16(this->Ptr, this->IValue); - } - return *((int16_t*)this->GetPtrWithOffset()); +int16_t RuntimeScriptValue::ReadInt16() { + if (this->Type == kScValStackPtr) { + if (RValue->Type == kScValData) { + return *(int16_t *)(RValue->GetPtrWithOffset() + this->IValue); + } else { + return RValue->IValue; // get RValue as int + } + } else if (this->Type == kScValGlobalVar) { + if (RValue->Type == kScValData) { + return Memory::ReadInt16LE(RValue->GetPtrWithOffset() + this->IValue); + } else { + return RValue->IValue; // get RValue as int + } + } else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) { + return this->StcMgr->ReadInt16(this->Ptr, this->IValue); + } else if (this->Type == kScValDynamicObject) { + return this->DynMgr->ReadInt16(this->Ptr, this->IValue); + } + return *((int16_t *)this->GetPtrWithOffset()); } -int32_t RuntimeScriptValue::ReadInt32() -{ - if (this->Type == kScValStackPtr) - { - if (RValue->Type == kScValData) - { - return *(int32_t*)(RValue->GetPtrWithOffset() + this->IValue); - } - else - { - return RValue->IValue; // get RValue as int - } - } - else if (this->Type == kScValGlobalVar) - { - if (RValue->Type == kScValData) - { - return Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue); - } - else - { - return RValue->IValue; // get RValue as int - } - } - else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) - { - return this->StcMgr->ReadInt32(this->Ptr, this->IValue); - } - else if (this->Type == kScValDynamicObject) - { - return this->DynMgr->ReadInt32(this->Ptr, this->IValue); - } - return *((int32_t*)this->GetPtrWithOffset()); +int32_t RuntimeScriptValue::ReadInt32() { + if (this->Type == kScValStackPtr) { + if (RValue->Type == kScValData) { + return *(int32_t *)(RValue->GetPtrWithOffset() + this->IValue); + } else { + return RValue->IValue; // get RValue as int + } + } else if (this->Type == kScValGlobalVar) { + if (RValue->Type == kScValData) { + return Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue); + } else { + return RValue->IValue; // get RValue as int + } + } else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) { + return this->StcMgr->ReadInt32(this->Ptr, this->IValue); + } else if (this->Type == kScValDynamicObject) { + return this->DynMgr->ReadInt32(this->Ptr, this->IValue); + } + return *((int32_t *)this->GetPtrWithOffset()); } -bool RuntimeScriptValue::WriteByte(uint8_t val) -{ - if (this->Type == kScValStackPtr || this->Type == kScValGlobalVar) - { - if (RValue->Type == kScValData) - { - *(uint8_t*)(RValue->GetPtrWithOffset() + this->IValue) = val; - } - else - { - RValue->SetUInt8(val); // set RValue as int - } - } - else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) - { - this->StcMgr->WriteInt8(this->Ptr, this->IValue, val); - } - else if (this->Type == kScValDynamicObject) - { - this->DynMgr->WriteInt8(this->Ptr, this->IValue, val); - } - else - { - *((uint8_t*)this->GetPtrWithOffset()) = val; - } - return true; +bool RuntimeScriptValue::WriteByte(uint8_t val) { + if (this->Type == kScValStackPtr || this->Type == kScValGlobalVar) { + if (RValue->Type == kScValData) { + *(uint8_t *)(RValue->GetPtrWithOffset() + this->IValue) = val; + } else { + RValue->SetUInt8(val); // set RValue as int + } + } else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) { + this->StcMgr->WriteInt8(this->Ptr, this->IValue, val); + } else if (this->Type == kScValDynamicObject) { + this->DynMgr->WriteInt8(this->Ptr, this->IValue, val); + } else { + *((uint8_t *)this->GetPtrWithOffset()) = val; + } + return true; } -bool RuntimeScriptValue::WriteInt16(int16_t val) -{ - if (this->Type == kScValStackPtr) - { - if (RValue->Type == kScValData) - { - *(int16_t*)(RValue->GetPtrWithOffset() + this->IValue) = val; - } - else - { - RValue->SetInt16(val); // set RValue as int - } - } - else if (this->Type == kScValGlobalVar) - { - if (RValue->Type == kScValData) - { - Memory::WriteInt16LE(RValue->GetPtrWithOffset() + this->IValue, val); - } - else - { - RValue->SetInt16(val); // set RValue as int - } - } - else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) - { - this->StcMgr->WriteInt16(this->Ptr, this->IValue, val); - } - else if (this->Type == kScValDynamicObject) - { - this->DynMgr->WriteInt16(this->Ptr, this->IValue, val); - } - else - { - *((int16_t*)this->GetPtrWithOffset()) = val; - } - return true; +bool RuntimeScriptValue::WriteInt16(int16_t val) { + if (this->Type == kScValStackPtr) { + if (RValue->Type == kScValData) { + *(int16_t *)(RValue->GetPtrWithOffset() + this->IValue) = val; + } else { + RValue->SetInt16(val); // set RValue as int + } + } else if (this->Type == kScValGlobalVar) { + if (RValue->Type == kScValData) { + Memory::WriteInt16LE(RValue->GetPtrWithOffset() + this->IValue, val); + } else { + RValue->SetInt16(val); // set RValue as int + } + } else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) { + this->StcMgr->WriteInt16(this->Ptr, this->IValue, val); + } else if (this->Type == kScValDynamicObject) { + this->DynMgr->WriteInt16(this->Ptr, this->IValue, val); + } else { + *((int16_t *)this->GetPtrWithOffset()) = val; + } + return true; } -bool RuntimeScriptValue::WriteInt32(int32_t val) -{ - if (this->Type == kScValStackPtr) - { - if (RValue->Type == kScValData) - { - *(int32_t*)(RValue->GetPtrWithOffset() + this->IValue) = val; - } - else - { - RValue->SetInt32(val); // set RValue as int - } - } - else if (this->Type == kScValGlobalVar) - { - if (RValue->Type == kScValData) - { - Memory::WriteInt32LE(RValue->GetPtrWithOffset() + this->IValue, val); - } - else - { - RValue->SetInt32(val); // set RValue as int - } - } - else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) - { - this->StcMgr->WriteInt32(this->Ptr, this->IValue, val); - } - else if (this->Type == kScValDynamicObject) - { - this->DynMgr->WriteInt32(this->Ptr, this->IValue, val); - } - else - { - *((int32_t*)this->GetPtrWithOffset()) = val; - } - return true; +bool RuntimeScriptValue::WriteInt32(int32_t val) { + if (this->Type == kScValStackPtr) { + if (RValue->Type == kScValData) { + *(int32_t *)(RValue->GetPtrWithOffset() + this->IValue) = val; + } else { + RValue->SetInt32(val); // set RValue as int + } + } else if (this->Type == kScValGlobalVar) { + if (RValue->Type == kScValData) { + Memory::WriteInt32LE(RValue->GetPtrWithOffset() + this->IValue, val); + } else { + RValue->SetInt32(val); // set RValue as int + } + } else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) { + this->StcMgr->WriteInt32(this->Ptr, this->IValue, val); + } else if (this->Type == kScValDynamicObject) { + this->DynMgr->WriteInt32(this->Ptr, this->IValue, val); + } else { + *((int32_t *)this->GetPtrWithOffset()) = val; + } + return true; } // Notice, that there are only two valid cases when a pointer may be written: // when the destination is a stack entry or global variable of free type // (not kScValData type). // In any other case, only the numeric value (integer/float) will be written. -bool RuntimeScriptValue::WriteValue(const RuntimeScriptValue &rval) -{ - if (this->Type == kScValStackPtr) - { - if (RValue->Type == kScValData) - { - *(int32_t*)(RValue->GetPtrWithOffset() + this->IValue) = rval.IValue; - } - else - { - // NOTE: we cannot just WriteValue here because when an integer - // is pushed to the stack, script assumes that it is always 4 - // bytes and uses that size when calculating offsets to local - // variables; - // Therefore if pushed value is of integer type, we should rather - // act as WriteInt32 (for int8, int16 and int32). - if (rval.Type == kScValInteger) - { - RValue->SetInt32(rval.IValue); - } - else - { - *RValue = rval; - } - } - } - else if (this->Type == kScValGlobalVar) - { - if (RValue->Type == kScValData) - { - Memory::WriteInt32LE(RValue->GetPtrWithOffset() + this->IValue, rval.IValue); - } - else - { - *RValue = rval; - } - } - else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) - { - this->StcMgr->WriteInt32(this->Ptr, this->IValue, rval.IValue); - } - else if (this->Type == kScValDynamicObject) - { - this->DynMgr->WriteInt32(this->Ptr, this->IValue, rval.IValue); - } - else - { - *((int32_t*)this->GetPtrWithOffset()) = rval.IValue; - } - return true; +bool RuntimeScriptValue::WriteValue(const RuntimeScriptValue &rval) { + if (this->Type == kScValStackPtr) { + if (RValue->Type == kScValData) { + *(int32_t *)(RValue->GetPtrWithOffset() + this->IValue) = rval.IValue; + } else { + // NOTE: we cannot just WriteValue here because when an integer + // is pushed to the stack, script assumes that it is always 4 + // bytes and uses that size when calculating offsets to local + // variables; + // Therefore if pushed value is of integer type, we should rather + // act as WriteInt32 (for int8, int16 and int32). + if (rval.Type == kScValInteger) { + RValue->SetInt32(rval.IValue); + } else { + *RValue = rval; + } + } + } else if (this->Type == kScValGlobalVar) { + if (RValue->Type == kScValData) { + Memory::WriteInt32LE(RValue->GetPtrWithOffset() + this->IValue, rval.IValue); + } else { + *RValue = rval; + } + } else if (this->Type == kScValStaticObject || this->Type == kScValStaticArray) { + this->StcMgr->WriteInt32(this->Ptr, this->IValue, rval.IValue); + } else if (this->Type == kScValDynamicObject) { + this->DynMgr->WriteInt32(this->Ptr, this->IValue, rval.IValue); + } else { + *((int32_t *)this->GetPtrWithOffset()) = rval.IValue; + } + return true; } -RuntimeScriptValue &RuntimeScriptValue::DirectPtr() -{ - if (Type == kScValGlobalVar || Type == kScValStackPtr) - { - int ival = IValue; - *this = *RValue; - IValue += ival; - } - - if (Ptr) - { - if (Type == kScValDynamicObject) - Ptr = const_cast(DynMgr->GetFieldPtr(Ptr, IValue)); - else if (Type == kScValStaticObject) - Ptr = const_cast(StcMgr->GetFieldPtr(Ptr, IValue)); - else - Ptr += IValue; - IValue = 0; - } - return *this; +RuntimeScriptValue &RuntimeScriptValue::DirectPtr() { + if (Type == kScValGlobalVar || Type == kScValStackPtr) { + int ival = IValue; + *this = *RValue; + IValue += ival; + } + + if (Ptr) { + if (Type == kScValDynamicObject) + Ptr = const_cast(DynMgr->GetFieldPtr(Ptr, IValue)); + else if (Type == kScValStaticObject) + Ptr = const_cast(StcMgr->GetFieldPtr(Ptr, IValue)); + else + Ptr += IValue; + IValue = 0; + } + return *this; } -RuntimeScriptValue &RuntimeScriptValue::DirectPtrObj() -{ - if (Type == kScValGlobalVar || Type == kScValStackPtr) - *this = *RValue; - return *this; +RuntimeScriptValue &RuntimeScriptValue::DirectPtrObj() { + if (Type == kScValGlobalVar || Type == kScValStackPtr) + *this = *RValue; + return *this; } -intptr_t RuntimeScriptValue::GetDirectPtr() const -{ - const RuntimeScriptValue *temp_val = this; - int ival = temp_val->IValue; - if (temp_val->Type == kScValGlobalVar || temp_val->Type == kScValStackPtr) - { - temp_val = temp_val->RValue; - ival += temp_val->IValue; - } - if (temp_val->Type == kScValDynamicObject) - return (intptr_t)temp_val->DynMgr->GetFieldPtr(temp_val->Ptr, ival); - else if (temp_val->Type == kScValStaticObject) - return (intptr_t)temp_val->StcMgr->GetFieldPtr(temp_val->Ptr, ival); - else - return (intptr_t)(temp_val->Ptr + ival); +intptr_t RuntimeScriptValue::GetDirectPtr() const { + const RuntimeScriptValue *temp_val = this; + int ival = temp_val->IValue; + if (temp_val->Type == kScValGlobalVar || temp_val->Type == kScValStackPtr) { + temp_val = temp_val->RValue; + ival += temp_val->IValue; + } + if (temp_val->Type == kScValDynamicObject) + return (intptr_t)temp_val->DynMgr->GetFieldPtr(temp_val->Ptr, ival); + else if (temp_val->Type == kScValStaticObject) + return (intptr_t)temp_val->StcMgr->GetFieldPtr(temp_val->Ptr, ival); + else + return (intptr_t)(temp_val->Ptr + ival); } diff --git a/engines/ags/engine/script/runtimescriptvalue.h b/engines/ags/engine/script/runtimescriptvalue.h index 7397a8346ce7..91a02368e2db 100644 --- a/engines/ags/engine/script/runtimescriptvalue.h +++ b/engines/ags/engine/script/runtimescriptvalue.h @@ -36,361 +36,316 @@ struct ICCStaticObject; struct StaticArray; -enum ScriptValueType -{ - kScValUndefined, // to detect errors - kScValInteger, // as strictly 32-bit integer (for integer math) - kScValFloat, // as float (for floating point math), 32-bit - kScValPluginArg, // an 32-bit value, passed to a script function when called - // directly by plugin; is allowed to represent object pointer - kScValStackPtr, // as a pointer to stack entry - kScValData, // as a container for randomly sized data (usually array) - kScValGlobalVar, // as a pointer to script variable; used only for global vars, - // as pointer to local vars must have StackPtr type so that the - // stack allocation could work - kScValStringLiteral,// as a pointer to literal string (array of chars) - kScValStaticObject, // as a pointer to static global script object - kScValStaticArray, // as a pointer to static global array (of static or dynamic objects) - kScValDynamicObject,// as a pointer to managed script object - kScValPluginObject, // as a pointer to object managed by plugin (similar to - // kScValDynamicObject, but has backward-compatible limitations) - kScValStaticFunction,// as a pointer to static function - kScValPluginFunction,// temporary workaround for plugins (unsafe function ptr) - kScValObjectFunction,// as a pointer to object member function, gets object pointer as - // first parameter - kScValCodePtr, // as a pointer to element in byte-code array +enum ScriptValueType { + kScValUndefined, // to detect errors + kScValInteger, // as strictly 32-bit integer (for integer math) + kScValFloat, // as float (for floating point math), 32-bit + kScValPluginArg, // an 32-bit value, passed to a script function when called + // directly by plugin; is allowed to represent object pointer + kScValStackPtr, // as a pointer to stack entry + kScValData, // as a container for randomly sized data (usually array) + kScValGlobalVar, // as a pointer to script variable; used only for global vars, + // as pointer to local vars must have StackPtr type so that the + // stack allocation could work + kScValStringLiteral,// as a pointer to literal string (array of chars) + kScValStaticObject, // as a pointer to static global script object + kScValStaticArray, // as a pointer to static global array (of static or dynamic objects) + kScValDynamicObject,// as a pointer to managed script object + kScValPluginObject, // as a pointer to object managed by plugin (similar to + // kScValDynamicObject, but has backward-compatible limitations) + kScValStaticFunction,// as a pointer to static function + kScValPluginFunction,// temporary workaround for plugins (unsafe function ptr) + kScValObjectFunction,// as a pointer to object member function, gets object pointer as + // first parameter + kScValCodePtr, // as a pointer to element in byte-code array }; -struct RuntimeScriptValue -{ +struct RuntimeScriptValue { public: - RuntimeScriptValue() - { - Type = kScValUndefined; - IValue = 0; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 0; - } + RuntimeScriptValue() { + Type = kScValUndefined; + IValue = 0; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 0; + } - RuntimeScriptValue(int32_t val) - { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; - } + RuntimeScriptValue(int32_t val) { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + } - ScriptValueType Type; - // The 32-bit value used for integer/float math and for storing - // variable/element offset relative to object (and array) address - union - { - int32_t IValue; // access Value as int32 type - float FValue; // access Value as float type - }; - // Pointer is used for storing... pointers - to objects, arrays, - // functions and stack entries (other RSV) - union - { - char *Ptr; // generic data pointer - RuntimeScriptValue *RValue;// access ptr as a pointer to Runtime Value - ScriptAPIFunction *SPfn; // access ptr as a pointer to Script API Static Function - ScriptAPIObjectFunction *ObjPfn; // access ptr as a pointer to Script API Object Function - }; - // TODO: separation to Ptr and MgrPtr is only needed so far as there's - // a separation between Script*, Dynamic* and game entity classes. - // Once those classes are merged, it will no longer be needed. - union - { - void *MgrPtr;// generic object manager pointer - ICCStaticObject *StcMgr;// static object manager - StaticArray *StcArr;// static array manager - ICCDynamicObject *DynMgr;// dynamic object manager - }; - // The "real" size of data, either one stored in I/FValue, - // or the one referenced by Ptr. Used for calculating stack - // offsets. - // Original AGS scripts always assumed pointer is 32-bit. - // Therefore for stored pointers Size is always 4 both for x32 - // and x64 builds, so that the script is interpreted correctly. - int Size; + ScriptValueType Type; + // The 32-bit value used for integer/float math and for storing + // variable/element offset relative to object (and array) address + union { + int32_t IValue; // access Value as int32 type + float FValue; // access Value as float type + }; + // Pointer is used for storing... pointers - to objects, arrays, + // functions and stack entries (other RSV) + union { + char *Ptr; // generic data pointer + RuntimeScriptValue *RValue;// access ptr as a pointer to Runtime Value + ScriptAPIFunction *SPfn; // access ptr as a pointer to Script API Static Function + ScriptAPIObjectFunction *ObjPfn; // access ptr as a pointer to Script API Object Function + }; + // TODO: separation to Ptr and MgrPtr is only needed so far as there's + // a separation between Script*, Dynamic* and game entity classes. + // Once those classes are merged, it will no longer be needed. + union { + void *MgrPtr;// generic object manager pointer + ICCStaticObject *StcMgr;// static object manager + StaticArray *StcArr;// static array manager + ICCDynamicObject *DynMgr;// dynamic object manager + }; + // The "real" size of data, either one stored in I/FValue, + // or the one referenced by Ptr. Used for calculating stack + // offsets. + // Original AGS scripts always assumed pointer is 32-bit. + // Therefore for stored pointers Size is always 4 both for x32 + // and x64 builds, so that the script is interpreted correctly. + int Size; - inline bool IsValid() const - { - return Type != kScValUndefined; - } - inline bool IsNull() const - { - return Ptr == nullptr && IValue == 0; - } - - inline bool GetAsBool() const - { - return !IsNull(); - } - inline char* GetPtrWithOffset() const - { - return Ptr + IValue; - } - - inline RuntimeScriptValue &Invalidate() - { - Type = kScValUndefined; - IValue = 0; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 0; - return *this; - } - inline RuntimeScriptValue &SetUInt8(uint8_t val) - { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 1; - return *this; - } - inline RuntimeScriptValue &SetInt16(int16_t val) - { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 2; - return *this; - } - inline RuntimeScriptValue &SetInt32(int32_t val) - { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetFloat(float val) - { - Type = kScValFloat; - FValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetInt32AsBool(bool val) - { - return SetInt32(val ? 1 : 0); - } - inline RuntimeScriptValue &SetFloatAsBool(bool val) - { - return SetFloat(val ? 1.0F : 0.0F); - } - inline RuntimeScriptValue &SetPluginArgument(int32_t val) - { - Type = kScValPluginArg; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetStackPtr(RuntimeScriptValue *stack_entry) - { - Type = kScValStackPtr; - IValue = 0; - RValue = stack_entry; - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetData(char *data, int size) - { - Type = kScValData; - IValue = 0; - Ptr = data; - MgrPtr = nullptr; - Size = size; - return *this; - } - inline RuntimeScriptValue &SetGlobalVar(RuntimeScriptValue *glvar_value) - { - Type = kScValGlobalVar; - IValue = 0; - RValue = glvar_value; - MgrPtr = nullptr; - Size = 4; - return *this; - } - // TODO: size? - inline RuntimeScriptValue &SetStringLiteral(const char *str) - { - Type = kScValStringLiteral; - IValue = 0; - Ptr = const_cast(str); - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetStaticObject(void *object, ICCStaticObject *manager) - { - Type = kScValStaticObject; - IValue = 0; - Ptr = (char*)object; - StcMgr = manager; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetStaticArray(void *object, StaticArray *manager) - { - Type = kScValStaticArray; - IValue = 0; - Ptr = (char*)object; - StcArr = manager; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetDynamicObject(void *object, ICCDynamicObject *manager) - { - Type = kScValDynamicObject; - IValue = 0; - Ptr = (char*)object; - DynMgr = manager; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetPluginObject(void *object, ICCDynamicObject *manager) - { - Type = kScValPluginObject; - IValue = 0; - Ptr = (char*)object; - DynMgr = manager; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetStaticFunction(ScriptAPIFunction *pfn) - { - Type = kScValStaticFunction; - IValue = 0; - SPfn = pfn; - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetPluginFunction(void *pfn) - { - Type = kScValPluginFunction; - IValue = 0; - Ptr = (char*)pfn; - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetObjectFunction(ScriptAPIObjectFunction *pfn) - { - Type = kScValObjectFunction; - IValue = 0; - ObjPfn = pfn; - MgrPtr = nullptr; - Size = 4; - return *this; - } - inline RuntimeScriptValue &SetCodePtr(char *ptr) - { - Type = kScValCodePtr; - IValue = 0; - Ptr = ptr; - MgrPtr = nullptr; - Size = 4; - return *this; - } + inline bool IsValid() const { + return Type != kScValUndefined; + } + inline bool IsNull() const { + return Ptr == nullptr && IValue == 0; + } - inline RuntimeScriptValue operator !() const - { - return RuntimeScriptValue().SetInt32AsBool(!GetAsBool()); - } + inline bool GetAsBool() const { + return !IsNull(); + } + inline char *GetPtrWithOffset() const { + return Ptr + IValue; + } - inline bool operator ==(const RuntimeScriptValue &rval) - { - return ((intptr_t)Ptr + (intptr_t)IValue) == ((intptr_t)rval.Ptr + (intptr_t)rval.IValue); - } - inline bool operator !=(const RuntimeScriptValue &rval) - { - return !(*this == rval); - } + inline RuntimeScriptValue &Invalidate() { + Type = kScValUndefined; + IValue = 0; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 0; + return *this; + } + inline RuntimeScriptValue &SetUInt8(uint8_t val) { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 1; + return *this; + } + inline RuntimeScriptValue &SetInt16(int16_t val) { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 2; + return *this; + } + inline RuntimeScriptValue &SetInt32(int32_t val) { + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetFloat(float val) { + Type = kScValFloat; + FValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetInt32AsBool(bool val) { + return SetInt32(val ? 1 : 0); + } + inline RuntimeScriptValue &SetFloatAsBool(bool val) { + return SetFloat(val ? 1.0F : 0.0F); + } + inline RuntimeScriptValue &SetPluginArgument(int32_t val) { + Type = kScValPluginArg; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStackPtr(RuntimeScriptValue *stack_entry) { + Type = kScValStackPtr; + IValue = 0; + RValue = stack_entry; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetData(char *data, int size) { + Type = kScValData; + IValue = 0; + Ptr = data; + MgrPtr = nullptr; + Size = size; + return *this; + } + inline RuntimeScriptValue &SetGlobalVar(RuntimeScriptValue *glvar_value) { + Type = kScValGlobalVar; + IValue = 0; + RValue = glvar_value; + MgrPtr = nullptr; + Size = 4; + return *this; + } + // TODO: size? + inline RuntimeScriptValue &SetStringLiteral(const char *str) { + Type = kScValStringLiteral; + IValue = 0; + Ptr = const_cast(str); + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStaticObject(void *object, ICCStaticObject *manager) { + Type = kScValStaticObject; + IValue = 0; + Ptr = (char *)object; + StcMgr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStaticArray(void *object, StaticArray *manager) { + Type = kScValStaticArray; + IValue = 0; + Ptr = (char *)object; + StcArr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetDynamicObject(void *object, ICCDynamicObject *manager) { + Type = kScValDynamicObject; + IValue = 0; + Ptr = (char *)object; + DynMgr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetPluginObject(void *object, ICCDynamicObject *manager) { + Type = kScValPluginObject; + IValue = 0; + Ptr = (char *)object; + DynMgr = manager; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetStaticFunction(ScriptAPIFunction *pfn) { + Type = kScValStaticFunction; + IValue = 0; + SPfn = pfn; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetPluginFunction(void *pfn) { + Type = kScValPluginFunction; + IValue = 0; + Ptr = (char *)pfn; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetObjectFunction(ScriptAPIObjectFunction *pfn) { + Type = kScValObjectFunction; + IValue = 0; + ObjPfn = pfn; + MgrPtr = nullptr; + Size = 4; + return *this; + } + inline RuntimeScriptValue &SetCodePtr(char *ptr) { + Type = kScValCodePtr; + IValue = 0; + Ptr = ptr; + MgrPtr = nullptr; + Size = 4; + return *this; + } - // FIXME: find out all certain cases when we are reading a pointer and store it - // as 32-bit value here. There should be a solution to distinct these cases and - // store value differently, otherwise it won't work for 64-bit build. - inline RuntimeScriptValue ReadValue() - { - RuntimeScriptValue rval; - switch(this->Type) { - case kScValStackPtr: - { - if (RValue->Type == kScValData) - { - rval.SetInt32(*(int32_t*)(RValue->GetPtrWithOffset() + this->IValue)); - } - else - { - rval = *RValue; - } - } - break; - case kScValGlobalVar: - { - if (RValue->Type == kScValData) - { - rval.SetInt32(AGS::Common::Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue)); - } - else - { - rval = *RValue; - } - } - break; - case kScValStaticObject: case kScValStaticArray: - { - rval.SetInt32(this->StcMgr->ReadInt32(this->Ptr, this->IValue)); - } - break; - case kScValDynamicObject: - { - rval.SetInt32(this->DynMgr->ReadInt32(this->Ptr, this->IValue)); - } - break; - default: - { - // 64 bit: Memory reads are still 32 bit - rval.SetInt32(*(int32_t*)this->GetPtrWithOffset()); - } - } - return rval; - } + inline RuntimeScriptValue operator !() const { + return RuntimeScriptValue().SetInt32AsBool(!GetAsBool()); + } + inline bool operator ==(const RuntimeScriptValue &rval) { + return ((intptr_t)Ptr + (intptr_t)IValue) == ((intptr_t)rval.Ptr + (intptr_t)rval.IValue); + } + inline bool operator !=(const RuntimeScriptValue &rval) { + return !(*this == rval); + } - // Helper functions for reading or writing values from/to - // object, referenced by this Runtime Value. - // Copy implementation depends on value type. - uint8_t ReadByte(); - int16_t ReadInt16(); - int32_t ReadInt32(); - bool WriteByte(uint8_t val); - bool WriteInt16(int16_t val); - bool WriteInt32(int32_t val); - bool WriteValue(const RuntimeScriptValue &rval); + // FIXME: find out all certain cases when we are reading a pointer and store it + // as 32-bit value here. There should be a solution to distinct these cases and + // store value differently, otherwise it won't work for 64-bit build. + inline RuntimeScriptValue ReadValue() { + RuntimeScriptValue rval; + switch (this->Type) { + case kScValStackPtr: { + if (RValue->Type == kScValData) { + rval.SetInt32(*(int32_t *)(RValue->GetPtrWithOffset() + this->IValue)); + } else { + rval = *RValue; + } + } + break; + case kScValGlobalVar: { + if (RValue->Type == kScValData) { + rval.SetInt32(AGS::Common::Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue)); + } else { + rval = *RValue; + } + } + break; + case kScValStaticObject: + case kScValStaticArray: { + rval.SetInt32(this->StcMgr->ReadInt32(this->Ptr, this->IValue)); + } + break; + case kScValDynamicObject: { + rval.SetInt32(this->DynMgr->ReadInt32(this->Ptr, this->IValue)); + } + break; + default: { + // 64 bit: Memory reads are still 32 bit + rval.SetInt32(*(int32_t *)this->GetPtrWithOffset()); + } + } + return rval; + } - // Convert to most simple pointer type by resolving RValue ptrs and applying offsets; - // non pointer types are left unmodified - RuntimeScriptValue &DirectPtr(); - // Similar to above, a slightly speed-optimised version for situations when we can - // tell for certain that we are expecting a pointer to the object and not its (first) field. - RuntimeScriptValue &DirectPtrObj(); - // Resolve and return direct pointer to the referenced data; non pointer types return IValue - intptr_t GetDirectPtr() const; + + // Helper functions for reading or writing values from/to + // object, referenced by this Runtime Value. + // Copy implementation depends on value type. + uint8_t ReadByte(); + int16_t ReadInt16(); + int32_t ReadInt32(); + bool WriteByte(uint8_t val); + bool WriteInt16(int16_t val); + bool WriteInt32(int32_t val); + bool WriteValue(const RuntimeScriptValue &rval); + + // Convert to most simple pointer type by resolving RValue ptrs and applying offsets; + // non pointer types are left unmodified + RuntimeScriptValue &DirectPtr(); + // Similar to above, a slightly speed-optimised version for situations when we can + // tell for certain that we are expecting a pointer to the object and not its (first) field. + RuntimeScriptValue &DirectPtrObj(); + // Resolve and return direct pointer to the referenced data; non pointer types return IValue + intptr_t GetDirectPtr() const; }; #endif diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp index 3762be9509f1..92c4a3a9433a 100644 --- a/engines/ags/engine/script/script.cpp +++ b/engines/ags/engine/script/script.cpp @@ -56,12 +56,12 @@ extern GameSetupStruct game; extern GameState play; extern int gameHasBeenRestored, displayed_room; extern unsigned int load_new_game; -extern RoomObject*objs; +extern RoomObject *objs; extern int our_eip; -extern CharacterInfo*playerchar; +extern CharacterInfo *playerchar; ExecutingScript scripts[MAX_SCRIPT_AT_ONCE]; -ExecutingScript*curscript = nullptr; +ExecutingScript *curscript = nullptr; PScript gamescript; PScript dialogScriptsScript; @@ -69,10 +69,10 @@ ccInstance *gameinst = nullptr, *roominst = nullptr; ccInstance *dialogScriptsInst = nullptr; ccInstance *gameinstFork = nullptr, *roominstFork = nullptr; -int num_scripts=0; +int num_scripts = 0; int post_script_cleanup_stack = 0; -int inside_script=0,in_graph_script=0; +int inside_script = 0, in_graph_script = 0; int no_blocking_functions = 0; // set to 1 while in rep_Exec_always NonBlockingScriptFunction repExecAlways(REP_EXEC_ALWAYS_NAME, 0); @@ -97,51 +97,51 @@ String objectScriptObjNames[MAX_ROOM_OBJECTS]; std::vector guiScriptObjNames; -int run_dialog_request (int parmtr) { - play.stop_dialog_at_end = DIALOG_RUNNING; - RunTextScriptIParam(gameinst, "dialog_request", RuntimeScriptValue().SetInt32(parmtr)); - - if (play.stop_dialog_at_end == DIALOG_STOP) { - play.stop_dialog_at_end = DIALOG_NONE; - return -2; - } - if (play.stop_dialog_at_end >= DIALOG_NEWTOPIC) { - int tval = play.stop_dialog_at_end - DIALOG_NEWTOPIC; - play.stop_dialog_at_end = DIALOG_NONE; - return tval; - } - if (play.stop_dialog_at_end >= DIALOG_NEWROOM) { - int roomnum = play.stop_dialog_at_end - DIALOG_NEWROOM; - play.stop_dialog_at_end = DIALOG_NONE; - NewRoom(roomnum); - return -2; - } - play.stop_dialog_at_end = DIALOG_NONE; - return -1; +int run_dialog_request(int parmtr) { + play.stop_dialog_at_end = DIALOG_RUNNING; + RunTextScriptIParam(gameinst, "dialog_request", RuntimeScriptValue().SetInt32(parmtr)); + + if (play.stop_dialog_at_end == DIALOG_STOP) { + play.stop_dialog_at_end = DIALOG_NONE; + return -2; + } + if (play.stop_dialog_at_end >= DIALOG_NEWTOPIC) { + int tval = play.stop_dialog_at_end - DIALOG_NEWTOPIC; + play.stop_dialog_at_end = DIALOG_NONE; + return tval; + } + if (play.stop_dialog_at_end >= DIALOG_NEWROOM) { + int roomnum = play.stop_dialog_at_end - DIALOG_NEWROOM; + play.stop_dialog_at_end = DIALOG_NONE; + NewRoom(roomnum); + return -2; + } + play.stop_dialog_at_end = DIALOG_NONE; + return -1; } -void run_function_on_non_blocking_thread(NonBlockingScriptFunction* funcToRun) { +void run_function_on_non_blocking_thread(NonBlockingScriptFunction *funcToRun) { - update_script_mouse_coords(); + update_script_mouse_coords(); - int room_changes_was = play.room_changes; - funcToRun->atLeastOneImplementationExists = false; + int room_changes_was = play.room_changes; + funcToRun->atLeastOneImplementationExists = false; - // run modules - // modules need a forkedinst for this to work - for (int kk = 0; kk < numScriptModules; kk++) { - funcToRun->moduleHasFunction[kk] = DoRunScriptFuncCantBlock(moduleInstFork[kk], funcToRun, funcToRun->moduleHasFunction[kk]); + // run modules + // modules need a forkedinst for this to work + for (int kk = 0; kk < numScriptModules; kk++) { + funcToRun->moduleHasFunction[kk] = DoRunScriptFuncCantBlock(moduleInstFork[kk], funcToRun, funcToRun->moduleHasFunction[kk]); - if (room_changes_was != play.room_changes) - return; - } + if (room_changes_was != play.room_changes) + return; + } - funcToRun->globalScriptHasFunction = DoRunScriptFuncCantBlock(gameinstFork, funcToRun, funcToRun->globalScriptHasFunction); + funcToRun->globalScriptHasFunction = DoRunScriptFuncCantBlock(gameinstFork, funcToRun, funcToRun->globalScriptHasFunction); - if (room_changes_was != play.room_changes) - return; + if (room_changes_was != play.room_changes) + return; - funcToRun->roomHasFunction = DoRunScriptFuncCantBlock(roominstFork, funcToRun, funcToRun->roomHasFunction); + funcToRun->roomHasFunction = DoRunScriptFuncCantBlock(roominstFork, funcToRun, funcToRun->roomHasFunction); } //----------------------------------------------------------- @@ -157,38 +157,38 @@ void run_function_on_non_blocking_thread(NonBlockingScriptFunction* funcToRun) { // Returns 0 normally, or -1 to indicate that the NewInteraction has // become invalid and don't run another interaction on it // (eg. a room change occured) -int run_interaction_event (Interaction *nint, int evnt, int chkAny, int isInv) { - - if (evnt < 0 || (size_t)evnt >= nint->Events.size() || - (nint->Events[evnt].Response.get() == nullptr) || (nint->Events[evnt].Response->Cmds.size() == 0)) { - // no response defined for this event - // If there is a response for "Any Click", then abort now so as to - // run that instead - if (chkAny < 0) ; - else if ((size_t)chkAny < nint->Events.size() && - (nint->Events[chkAny].Response.get() != nullptr) && (nint->Events[chkAny].Response->Cmds.size() > 0)) - return 0; - - // Otherwise, run unhandled_event - run_unhandled_event(evnt); - - return 0; - } - - if (play.check_interaction_only) { - play.check_interaction_only = 2; - return -1; - } - - int cmdsrun = 0, retval = 0; - // Right, so there were some commands defined in response to the event. - retval = run_interaction_commandlist (nint->Events[evnt].Response.get(), &nint->Events[evnt].TimesRun, &cmdsrun); - - // An inventory interaction, but the wrong item was used - if ((isInv) && (cmdsrun == 0)) - run_unhandled_event (evnt); - - return retval; +int run_interaction_event(Interaction *nint, int evnt, int chkAny, int isInv) { + + if (evnt < 0 || (size_t)evnt >= nint->Events.size() || + (nint->Events[evnt].Response.get() == nullptr) || (nint->Events[evnt].Response->Cmds.size() == 0)) { + // no response defined for this event + // If there is a response for "Any Click", then abort now so as to + // run that instead + if (chkAny < 0) ; + else if ((size_t)chkAny < nint->Events.size() && + (nint->Events[chkAny].Response.get() != nullptr) && (nint->Events[chkAny].Response->Cmds.size() > 0)) + return 0; + + // Otherwise, run unhandled_event + run_unhandled_event(evnt); + + return 0; + } + + if (play.check_interaction_only) { + play.check_interaction_only = 2; + return -1; + } + + int cmdsrun = 0, retval = 0; + // Right, so there were some commands defined in response to the event. + retval = run_interaction_commandlist(nint->Events[evnt].Response.get(), &nint->Events[evnt].TimesRun, &cmdsrun); + + // An inventory interaction, but the wrong item was used + if ((isInv) && (cmdsrun == 0)) + run_unhandled_event(evnt); + + return retval; } // Returns 0 normally, or -1 to indicate that the NewInteraction has @@ -196,470 +196,447 @@ int run_interaction_event (Interaction *nint, int evnt, int chkAny, int isInv) { // (eg. a room change occured) int run_interaction_script(InteractionScripts *nint, int evnt, int chkAny, int isInv) { - if ((nint->ScriptFuncNames[evnt] == nullptr) || (nint->ScriptFuncNames[evnt][0u] == 0)) { - // no response defined for this event - // If there is a response for "Any Click", then abort now so as to - // run that instead - if (chkAny < 0) ; - else if ((nint->ScriptFuncNames[chkAny] != nullptr) && (nint->ScriptFuncNames[chkAny][0u] != 0)) - return 0; - - // Otherwise, run unhandled_event - run_unhandled_event(evnt); - - return 0; - } - - if (play.check_interaction_only) { - play.check_interaction_only = 2; - return -1; - } - - int room_was = play.room_changes; - - RuntimeScriptValue rval_null; - - update_polled_mp3(); - if ((strstr(evblockbasename,"character")!=nullptr) || (strstr(evblockbasename,"inventory")!=nullptr)) { - // Character or Inventory (global script) - QueueScriptFunction(kScInstGame, nint->ScriptFuncNames[evnt]); - } - else { - // Other (room script) - QueueScriptFunction(kScInstRoom, nint->ScriptFuncNames[evnt]); - } - update_polled_mp3(); - - int retval = 0; - // if the room changed within the action - if (room_was != play.room_changes) - retval = -1; - - return retval; + if ((nint->ScriptFuncNames[evnt] == nullptr) || (nint->ScriptFuncNames[evnt][0u] == 0)) { + // no response defined for this event + // If there is a response for "Any Click", then abort now so as to + // run that instead + if (chkAny < 0) ; + else if ((nint->ScriptFuncNames[chkAny] != nullptr) && (nint->ScriptFuncNames[chkAny][0u] != 0)) + return 0; + + // Otherwise, run unhandled_event + run_unhandled_event(evnt); + + return 0; + } + + if (play.check_interaction_only) { + play.check_interaction_only = 2; + return -1; + } + + int room_was = play.room_changes; + + RuntimeScriptValue rval_null; + + update_polled_mp3(); + if ((strstr(evblockbasename, "character") != nullptr) || (strstr(evblockbasename, "inventory") != nullptr)) { + // Character or Inventory (global script) + QueueScriptFunction(kScInstGame, nint->ScriptFuncNames[evnt]); + } else { + // Other (room script) + QueueScriptFunction(kScInstRoom, nint->ScriptFuncNames[evnt]); + } + update_polled_mp3(); + + int retval = 0; + // if the room changed within the action + if (room_was != play.room_changes) + retval = -1; + + return retval; } int create_global_script() { - ccSetOption(SCOPT_AUTOIMPORT, 1); - for (int kk = 0; kk < numScriptModules; kk++) { - moduleInst[kk] = ccInstance::CreateFromScript(scriptModules[kk]); - if (moduleInst[kk] == nullptr) - return -3; - // create a forked instance for rep_exec_always - moduleInstFork[kk] = moduleInst[kk]->Fork(); - if (moduleInstFork[kk] == nullptr) - return -3; - - moduleRepExecAddr[kk] = moduleInst[kk]->GetSymbolAddress(REP_EXEC_NAME); - } - gameinst = ccInstance::CreateFromScript(gamescript); - if (gameinst == nullptr) - return -3; - // create a forked instance for rep_exec_always - gameinstFork = gameinst->Fork(); - if (gameinstFork == nullptr) - return -3; - - if (dialogScriptsScript != nullptr) - { - dialogScriptsInst = ccInstance::CreateFromScript(dialogScriptsScript); - if (dialogScriptsInst == nullptr) - return -3; - } - - ccSetOption(SCOPT_AUTOIMPORT, 0); - return 0; + ccSetOption(SCOPT_AUTOIMPORT, 1); + for (int kk = 0; kk < numScriptModules; kk++) { + moduleInst[kk] = ccInstance::CreateFromScript(scriptModules[kk]); + if (moduleInst[kk] == nullptr) + return -3; + // create a forked instance for rep_exec_always + moduleInstFork[kk] = moduleInst[kk]->Fork(); + if (moduleInstFork[kk] == nullptr) + return -3; + + moduleRepExecAddr[kk] = moduleInst[kk]->GetSymbolAddress(REP_EXEC_NAME); + } + gameinst = ccInstance::CreateFromScript(gamescript); + if (gameinst == nullptr) + return -3; + // create a forked instance for rep_exec_always + gameinstFork = gameinst->Fork(); + if (gameinstFork == nullptr) + return -3; + + if (dialogScriptsScript != nullptr) { + dialogScriptsInst = ccInstance::CreateFromScript(dialogScriptsScript); + if (dialogScriptsInst == nullptr) + return -3; + } + + ccSetOption(SCOPT_AUTOIMPORT, 0); + return 0; } void cancel_all_scripts() { - int aa; - - for (aa = 0; aa < num_scripts; aa++) { - if (scripts[aa].forked) - scripts[aa].inst->AbortAndDestroy(); - else - scripts[aa].inst->Abort(); - scripts[aa].numanother = 0; - } - num_scripts = 0; - /* if (gameinst!=NULL) ->Abort(gameinst); - if (roominst!=NULL) ->Abort(roominst);*/ + int aa; + + for (aa = 0; aa < num_scripts; aa++) { + if (scripts[aa].forked) + scripts[aa].inst->AbortAndDestroy(); + else + scripts[aa].inst->Abort(); + scripts[aa].numanother = 0; + } + num_scripts = 0; + /* if (gameinst!=NULL) ->Abort(gameinst); + if (roominst!=NULL) ->Abort(roominst);*/ } -ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst) -{ - if (sc_inst == kScInstGame) - return gameinst; - else if (sc_inst == kScInstRoom) - return roominst; - return nullptr; +ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst) { + if (sc_inst == kScInstGame) + return gameinst; + else if (sc_inst == kScInstRoom) + return roominst; + return nullptr; } -void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) -{ - if (inside_script) - // queue the script for the run after current script is finished - curscript->run_another (fn_name, sc_inst, param_count, p1, p2); - else - // if no script is currently running, run the requested script right away - RunScriptFunction(sc_inst, fn_name, param_count, p1, p2); +void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) { + if (inside_script) + // queue the script for the run after current script is finished + curscript->run_another(fn_name, sc_inst, param_count, p1, p2); + else + // if no script is currently running, run the requested script right away + RunScriptFunction(sc_inst, fn_name, param_count, p1, p2); } -void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) -{ - ccInstance *sci = GetScriptInstanceByType(sc_inst); - if (sci) - { - if (param_count == 2) - RunTextScript2IParam(sci, fn_name, p1, p2); - else if (param_count == 1) - RunTextScriptIParam(sci, fn_name, p1); - else if (param_count == 0) - RunTextScript(sci, fn_name); - } +void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count, const RuntimeScriptValue &p1, const RuntimeScriptValue &p2) { + ccInstance *sci = GetScriptInstanceByType(sc_inst); + if (sci) { + if (param_count == 2) + RunTextScript2IParam(sci, fn_name, p1, p2); + else if (param_count == 1) + RunTextScriptIParam(sci, fn_name, p1); + else if (param_count == 0) + RunTextScript(sci, fn_name); + } } -bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction* funcToRun, bool hasTheFunc) -{ - if (!hasTheFunc) - return(false); - - no_blocking_functions++; - int result = 0; - - if (funcToRun->numParameters < 3) - { - result = sci->CallScriptFunction((char*)funcToRun->functionName, funcToRun->numParameters, funcToRun->params); - } - else - quit("DoRunScriptFuncCantBlock called with too many parameters"); - - if (result == -2) { - // the function doens't exist, so don't try and run it again - hasTheFunc = false; - } - else if ((result != 0) && (result != 100)) { - quit_with_script_error(funcToRun->functionName); - } - else - { - funcToRun->atLeastOneImplementationExists = true; - } - // this might be nested, so don't disrupt blocked scripts - ccErrorString = ""; - ccError = 0; - no_blocking_functions--; - return(hasTheFunc); +bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcToRun, bool hasTheFunc) { + if (!hasTheFunc) + return (false); + + no_blocking_functions++; + int result = 0; + + if (funcToRun->numParameters < 3) { + result = sci->CallScriptFunction((char *)funcToRun->functionName, funcToRun->numParameters, funcToRun->params); + } else + quit("DoRunScriptFuncCantBlock called with too many parameters"); + + if (result == -2) { + // the function doens't exist, so don't try and run it again + hasTheFunc = false; + } else if ((result != 0) && (result != 100)) { + quit_with_script_error(funcToRun->functionName); + } else { + funcToRun->atLeastOneImplementationExists = true; + } + // this might be nested, so don't disrupt blocked scripts + ccErrorString = ""; + ccError = 0; + no_blocking_functions--; + return (hasTheFunc); } char scfunctionname[MAX_FUNCTION_NAME_LEN + 1]; -int PrepareTextScript(ccInstance *sci, const char**tsname) -{ - ccError = 0; - // FIXME: try to make it so this function is not called with NULL sci - if (sci == nullptr) return -1; - if (sci->GetSymbolAddress(tsname[0]).IsNull()) { - ccErrorString = "no such function in script"; - return -2; - } - if (sci->IsBeingRun()) { - ccErrorString = "script is already in execution"; - return -3; - } - scripts[num_scripts].init(); - scripts[num_scripts].inst = sci; - // CHECKME: this conditional block will never run, because - // function would have quit earlier (deprecated functionality?) - if (sci->IsBeingRun()) { - scripts[num_scripts].inst = sci->Fork(); - if (scripts[num_scripts].inst == nullptr) - quit("unable to fork instance for secondary script"); - scripts[num_scripts].forked = 1; - } - curscript = &scripts[num_scripts]; - num_scripts++; - if (num_scripts >= MAX_SCRIPT_AT_ONCE) - quit("too many nested text script instances created"); - // in case script_run_another is the function name, take a backup - strncpy(scfunctionname, tsname[0], MAX_FUNCTION_NAME_LEN); - tsname[0] = &scfunctionname[0]; - update_script_mouse_coords(); - inside_script++; - // aborted_ip=0; - // abort_executor=0; - return 0; +int PrepareTextScript(ccInstance *sci, const char **tsname) { + ccError = 0; + // FIXME: try to make it so this function is not called with NULL sci + if (sci == nullptr) return -1; + if (sci->GetSymbolAddress(tsname[0]).IsNull()) { + ccErrorString = "no such function in script"; + return -2; + } + if (sci->IsBeingRun()) { + ccErrorString = "script is already in execution"; + return -3; + } + scripts[num_scripts].init(); + scripts[num_scripts].inst = sci; + // CHECKME: this conditional block will never run, because + // function would have quit earlier (deprecated functionality?) + if (sci->IsBeingRun()) { + scripts[num_scripts].inst = sci->Fork(); + if (scripts[num_scripts].inst == nullptr) + quit("unable to fork instance for secondary script"); + scripts[num_scripts].forked = 1; + } + curscript = &scripts[num_scripts]; + num_scripts++; + if (num_scripts >= MAX_SCRIPT_AT_ONCE) + quit("too many nested text script instances created"); + // in case script_run_another is the function name, take a backup + strncpy(scfunctionname, tsname[0], MAX_FUNCTION_NAME_LEN); + tsname[0] = &scfunctionname[0]; + update_script_mouse_coords(); + inside_script++; + // aborted_ip=0; + // abort_executor=0; + return 0; } -int RunScriptFunctionIfExists(ccInstance *sci, const char*tsname, int numParam, const RuntimeScriptValue *params) -{ - int oldRestoreCount = gameHasBeenRestored; - // First, save the current ccError state - // This is necessary because we might be attempting - // to run Script B, while Script A is still running in the - // background. - // If CallInstance here has an error, it would otherwise - // also abort Script A because ccError is a global variable. - int cachedCcError = ccError; - ccError = 0; +int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, int numParam, const RuntimeScriptValue *params) { + int oldRestoreCount = gameHasBeenRestored; + // First, save the current ccError state + // This is necessary because we might be attempting + // to run Script B, while Script A is still running in the + // background. + // If CallInstance here has an error, it would otherwise + // also abort Script A because ccError is a global variable. + int cachedCcError = ccError; + ccError = 0; - int toret = PrepareTextScript(sci, &tsname); - if (toret) { - ccError = cachedCcError; - return -18; - } + int toret = PrepareTextScript(sci, &tsname); + if (toret) { + ccError = cachedCcError; + return -18; + } - // Clear the error message - ccErrorString = ""; + // Clear the error message + ccErrorString = ""; - if (numParam < 3) - { - toret = curscript->inst->CallScriptFunction(tsname, numParam, params); - } - else - quit("Too many parameters to RunScriptFunctionIfExists"); + if (numParam < 3) { + toret = curscript->inst->CallScriptFunction(tsname, numParam, params); + } else + quit("Too many parameters to RunScriptFunctionIfExists"); - // 100 is if Aborted (eg. because we are LoadAGSGame'ing) - if ((toret != 0) && (toret != -2) && (toret != 100)) { - quit_with_script_error(tsname); - } + // 100 is if Aborted (eg. because we are LoadAGSGame'ing) + if ((toret != 0) && (toret != -2) && (toret != 100)) { + quit_with_script_error(tsname); + } - post_script_cleanup_stack++; + post_script_cleanup_stack++; - if (post_script_cleanup_stack > 50) - quitprintf("!post_script_cleanup call stack exceeded: possible recursive function call? running %s", tsname); + if (post_script_cleanup_stack > 50) + quitprintf("!post_script_cleanup call stack exceeded: possible recursive function call? running %s", tsname); - post_script_cleanup(); + post_script_cleanup(); - post_script_cleanup_stack--; + post_script_cleanup_stack--; - // restore cached error state - ccError = cachedCcError; + // restore cached error state + ccError = cachedCcError; - // if the game has been restored, ensure that any further scripts are not run - if ((oldRestoreCount != gameHasBeenRestored) && (eventClaimed == EVENT_INPROGRESS)) - eventClaimed = EVENT_CLAIMED; + // if the game has been restored, ensure that any further scripts are not run + if ((oldRestoreCount != gameHasBeenRestored) && (eventClaimed == EVENT_INPROGRESS)) + eventClaimed = EVENT_CLAIMED; - return toret; + return toret; } -int RunTextScript(ccInstance *sci, const char *tsname) -{ - if (strcmp(tsname, REP_EXEC_NAME) == 0) { - // run module rep_execs - // FIXME: in theory the function may be already called for moduleInst[i], - // in which case this should not be executed; need to rearrange the code somehow - int room_changes_was = play.room_changes; - int restore_game_count_was = gameHasBeenRestored; - - for (int kk = 0; kk < numScriptModules; kk++) { - if (!moduleRepExecAddr[kk].IsNull()) - RunScriptFunctionIfExists(moduleInst[kk], tsname, 0, nullptr); - - if ((room_changes_was != play.room_changes) || - (restore_game_count_was != gameHasBeenRestored)) - return 0; - } - } - - int toret = RunScriptFunctionIfExists(sci, tsname, 0, nullptr); - if ((toret == -18) && (sci == roominst)) { - // functions in room script must exist - quitprintf("prepare_script: error %d (%s) trying to run '%s' (Room %d)", toret, ccErrorString.GetCStr(), tsname, displayed_room); - } - return toret; +int RunTextScript(ccInstance *sci, const char *tsname) { + if (strcmp(tsname, REP_EXEC_NAME) == 0) { + // run module rep_execs + // FIXME: in theory the function may be already called for moduleInst[i], + // in which case this should not be executed; need to rearrange the code somehow + int room_changes_was = play.room_changes; + int restore_game_count_was = gameHasBeenRestored; + + for (int kk = 0; kk < numScriptModules; kk++) { + if (!moduleRepExecAddr[kk].IsNull()) + RunScriptFunctionIfExists(moduleInst[kk], tsname, 0, nullptr); + + if ((room_changes_was != play.room_changes) || + (restore_game_count_was != gameHasBeenRestored)) + return 0; + } + } + + int toret = RunScriptFunctionIfExists(sci, tsname, 0, nullptr); + if ((toret == -18) && (sci == roominst)) { + // functions in room script must exist + quitprintf("prepare_script: error %d (%s) trying to run '%s' (Room %d)", toret, ccErrorString.GetCStr(), tsname, displayed_room); + } + return toret; } -int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam) -{ - if ((strcmp(tsname, "on_key_press") == 0) || (strcmp(tsname, "on_mouse_click") == 0)) { - bool eventWasClaimed; - int toret = run_claimable_event(tsname, true, 1, &iparam, &eventWasClaimed); +int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam) { + if ((strcmp(tsname, "on_key_press") == 0) || (strcmp(tsname, "on_mouse_click") == 0)) { + bool eventWasClaimed; + int toret = run_claimable_event(tsname, true, 1, &iparam, &eventWasClaimed); - if (eventWasClaimed) - return toret; - } + if (eventWasClaimed) + return toret; + } - return RunScriptFunctionIfExists(sci, tsname, 1, &iparam); + return RunScriptFunctionIfExists(sci, tsname, 1, &iparam); } -int RunTextScript2IParam(ccInstance *sci, const char*tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2) -{ - RuntimeScriptValue params[2]; - params[0] = iparam; - params[1] = param2; +int RunTextScript2IParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2) { + RuntimeScriptValue params[2]; + params[0] = iparam; + params[1] = param2; - if (strcmp(tsname, "on_event") == 0) { - bool eventWasClaimed; - int toret = run_claimable_event(tsname, true, 2, params, &eventWasClaimed); + if (strcmp(tsname, "on_event") == 0) { + bool eventWasClaimed; + int toret = run_claimable_event(tsname, true, 2, params, &eventWasClaimed); - if (eventWasClaimed) - return toret; - } + if (eventWasClaimed) + return toret; + } - // response to a button click, better update guis - if (ags_strnicmp(tsname, "interface_click", 15) == 0) - guis_need_update = 1; + // response to a button click, better update guis + if (ags_strnicmp(tsname, "interface_click", 15) == 0) + guis_need_update = 1; - return RunScriptFunctionIfExists(sci, tsname, 2, params); + return RunScriptFunctionIfExists(sci, tsname, 2, params); } -String GetScriptName(ccInstance *sci) -{ - // TODO: have script name a ccScript's member? - // TODO: check script modules too? - if (!sci) - return "Not in a script"; - else if (sci->instanceof == gamescript) - return "Global script"; - else if (sci->instanceof == thisroom.CompiledScript) - return String::FromFormat("Room %d script", displayed_room); - return "Unknown script"; +String GetScriptName(ccInstance *sci) { + // TODO: have script name a ccScript's member? + // TODO: check script modules too? + if (!sci) + return "Not in a script"; + else if (sci->instanceof == gamescript) + return "Global script"; + else if (sci->instanceof == thisroom.CompiledScript) + return String::FromFormat("Room %d script", displayed_room); + return "Unknown script"; } //============================================================================= -char bname[MAX_FUNCTION_NAME_LEN+1],bne[MAX_FUNCTION_NAME_LEN+1]; -char* make_ts_func_name(const char*base,int iii,int subd) { - int err = snprintf(bname,MAX_FUNCTION_NAME_LEN,base,iii); - if (err >= sizeof(bname)) - debug_script_warn("Function name length limit exceeded: %s (%d)", base, iii); - err = snprintf(bne,MAX_FUNCTION_NAME_LEN,"%s_%c",bname,subd+'a'); - if (err >= sizeof(bne)) - debug_script_warn("Function name length limit exceeded: %s", bname); - return &bne[0]; +char bname[MAX_FUNCTION_NAME_LEN + 1], bne[MAX_FUNCTION_NAME_LEN + 1]; +char *make_ts_func_name(const char *base, int iii, int subd) { + int err = snprintf(bname, MAX_FUNCTION_NAME_LEN, base, iii); + if (err >= sizeof(bname)) + debug_script_warn("Function name length limit exceeded: %s (%d)", base, iii); + err = snprintf(bne, MAX_FUNCTION_NAME_LEN, "%s_%c", bname, subd + 'a'); + if (err >= sizeof(bne)) + debug_script_warn("Function name length limit exceeded: %s", bname); + return &bne[0]; } void post_script_cleanup() { - // should do any post-script stuff here, like go to new room - if (ccError) quit(ccErrorString); - ExecutingScript copyof = scripts[num_scripts-1]; - if (scripts[num_scripts-1].forked) - delete scripts[num_scripts-1].inst; - num_scripts--; - inside_script--; - - if (num_scripts > 0) - curscript = &scripts[num_scripts-1]; - else { - curscript = nullptr; - } - // if (abort_executor) user_disabled_data2=aborted_ip; - - int old_room_number = displayed_room; - - // run the queued post-script actions - for (int ii = 0; ii < copyof.numPostScriptActions; ii++) { - int thisData = copyof.postScriptActionData[ii]; - - switch (copyof.postScriptActions[ii]) { - case ePSANewRoom: - // only change rooms when all scripts are done - if (num_scripts == 0) { - new_room(thisData, playerchar); - // don't allow any pending room scripts from the old room - // in run_another to be executed - return; - } - else - curscript->queue_action(ePSANewRoom, thisData, "NewRoom"); - break; - case ePSAInvScreen: - invscreen(); - break; - case ePSARestoreGame: - cancel_all_scripts(); - try_restore_save(thisData); - return; - case ePSARestoreGameDialog: - restore_game_dialog(); - return; - case ePSARunAGSGame: - cancel_all_scripts(); - load_new_game = thisData; - return; - case ePSARunDialog: - do_conversation(thisData); - break; - case ePSARestartGame: - cancel_all_scripts(); - restart_game(); - return; - case ePSASaveGame: - save_game(thisData, copyof.postScriptSaveSlotDescription[ii]); - break; - case ePSASaveGameDialog: - save_game_dialog(); - break; - default: - quitprintf("undefined post script action found: %d", copyof.postScriptActions[ii]); - } - // if the room changed in a conversation, for example, abort - if (old_room_number != displayed_room) { - return; - } - } - - - int jj; - for (jj = 0; jj < copyof.numanother; jj++) { - old_room_number = displayed_room; - QueuedScript &script = copyof.ScFnQueue[jj]; - RunScriptFunction(script.Instance, script.FnName, script.ParamCount, script.Param1, script.Param2); - if (script.Instance == kScInstRoom && script.ParamCount == 1) - { - // some bogus hack for "on_call" event handler - play.roomscript_finished = 1; - } - - // if they've changed rooms, cancel any further pending scripts - if ((displayed_room != old_room_number) || (load_new_game)) - break; - } - copyof.numanother = 0; + // should do any post-script stuff here, like go to new room + if (ccError) quit(ccErrorString); + ExecutingScript copyof = scripts[num_scripts - 1]; + if (scripts[num_scripts - 1].forked) + delete scripts[num_scripts - 1].inst; + num_scripts--; + inside_script--; + + if (num_scripts > 0) + curscript = &scripts[num_scripts - 1]; + else { + curscript = nullptr; + } + // if (abort_executor) user_disabled_data2=aborted_ip; + + int old_room_number = displayed_room; + + // run the queued post-script actions + for (int ii = 0; ii < copyof.numPostScriptActions; ii++) { + int thisData = copyof.postScriptActionData[ii]; + + switch (copyof.postScriptActions[ii]) { + case ePSANewRoom: + // only change rooms when all scripts are done + if (num_scripts == 0) { + new_room(thisData, playerchar); + // don't allow any pending room scripts from the old room + // in run_another to be executed + return; + } else + curscript->queue_action(ePSANewRoom, thisData, "NewRoom"); + break; + case ePSAInvScreen: + invscreen(); + break; + case ePSARestoreGame: + cancel_all_scripts(); + try_restore_save(thisData); + return; + case ePSARestoreGameDialog: + restore_game_dialog(); + return; + case ePSARunAGSGame: + cancel_all_scripts(); + load_new_game = thisData; + return; + case ePSARunDialog: + do_conversation(thisData); + break; + case ePSARestartGame: + cancel_all_scripts(); + restart_game(); + return; + case ePSASaveGame: + save_game(thisData, copyof.postScriptSaveSlotDescription[ii]); + break; + case ePSASaveGameDialog: + save_game_dialog(); + break; + default: + quitprintf("undefined post script action found: %d", copyof.postScriptActions[ii]); + } + // if the room changed in a conversation, for example, abort + if (old_room_number != displayed_room) { + return; + } + } + + + int jj; + for (jj = 0; jj < copyof.numanother; jj++) { + old_room_number = displayed_room; + QueuedScript &script = copyof.ScFnQueue[jj]; + RunScriptFunction(script.Instance, script.FnName, script.ParamCount, script.Param1, script.Param2); + if (script.Instance == kScInstRoom && script.ParamCount == 1) { + // some bogus hack for "on_call" event handler + play.roomscript_finished = 1; + } + + // if they've changed rooms, cancel any further pending scripts + if ((displayed_room != old_room_number) || (load_new_game)) + break; + } + copyof.numanother = 0; } -void quit_with_script_error(const char *functionName) -{ - // TODO: clean up the error reporting logic. Now engine will append call - // stack info in quit_check_for_error_state() but only in case of explicit - // script error ("!" type), and not in other case. - if (ccErrorIsUserError) - quitprintf("!Error running function '%s':\n%s", functionName, ccErrorString.GetCStr()); - else - quitprintf("Error running function '%s':\n%s\n\n%s", functionName, ccErrorString.GetCStr(), get_cur_script(5).GetCStr()); +void quit_with_script_error(const char *functionName) { + // TODO: clean up the error reporting logic. Now engine will append call + // stack info in quit_check_for_error_state() but only in case of explicit + // script error ("!" type), and not in other case. + if (ccErrorIsUserError) + quitprintf("!Error running function '%s':\n%s", functionName, ccErrorString.GetCStr()); + else + quitprintf("Error running function '%s':\n%s\n\n%s", functionName, ccErrorString.GetCStr(), get_cur_script(5).GetCStr()); } -int get_nivalue (InteractionCommandList *nic, int idx, int parm) { - if (nic->Cmds[idx].Data[parm].Type == AGS::Common::kInterValVariable) { - // return the value of the variable - return get_interaction_variable(nic->Cmds[idx].Data[parm].Value)->Value; - } - return nic->Cmds[idx].Data[parm].Value; +int get_nivalue(InteractionCommandList *nic, int idx, int parm) { + if (nic->Cmds[idx].Data[parm].Type == AGS::Common::kInterValVariable) { + // return the value of the variable + return get_interaction_variable(nic->Cmds[idx].Data[parm].Value)->Value; + } + return nic->Cmds[idx].Data[parm].Value; } -InteractionVariable *get_interaction_variable (int varindx) { +InteractionVariable *get_interaction_variable(int varindx) { - if ((varindx >= LOCAL_VARIABLE_OFFSET) && ((size_t)varindx < LOCAL_VARIABLE_OFFSET + thisroom.LocalVariables.size())) - return &thisroom.LocalVariables[varindx - LOCAL_VARIABLE_OFFSET]; + if ((varindx >= LOCAL_VARIABLE_OFFSET) && ((size_t)varindx < LOCAL_VARIABLE_OFFSET + thisroom.LocalVariables.size())) + return &thisroom.LocalVariables[varindx - LOCAL_VARIABLE_OFFSET]; - if ((varindx < 0) || (varindx >= numGlobalVars)) - quit("!invalid interaction variable specified"); + if ((varindx < 0) || (varindx >= numGlobalVars)) + quit("!invalid interaction variable specified"); - return &globalvars[varindx]; + return &globalvars[varindx]; } InteractionVariable *FindGraphicalVariable(const char *varName) { - int ii; - for (ii = 0; ii < numGlobalVars; ii++) { - if (ags_stricmp (globalvars[ii].Name, varName) == 0) - return &globalvars[ii]; - } - for (size_t i = 0; i < thisroom.LocalVariables.size(); ++i) { - if (ags_stricmp (thisroom.LocalVariables[i].Name, varName) == 0) - return &thisroom.LocalVariables[i]; - } - return nullptr; + int ii; + for (ii = 0; ii < numGlobalVars; ii++) { + if (ags_stricmp(globalvars[ii].Name, varName) == 0) + return &globalvars[ii]; + } + for (size_t i = 0; i < thisroom.LocalVariables.size(); ++i) { + if (ags_stricmp(thisroom.LocalVariables[i].Name, varName) == 0) + return &thisroom.LocalVariables[i]; + } + return nullptr; } #define IPARAM1 get_nivalue(nicl, i, 0) @@ -669,269 +646,268 @@ InteractionVariable *FindGraphicalVariable(const char *varName) { #define IPARAM5 get_nivalue(nicl, i, 4) struct TempEip { - int oldval; - TempEip (int newval) { - oldval = our_eip; - our_eip = newval; - } - ~TempEip () { our_eip = oldval; } + int oldval; + TempEip(int newval) { + oldval = our_eip; + our_eip = newval; + } + ~TempEip() { + our_eip = oldval; + } }; // the 'cmdsrun' parameter counts how many commands are run. // if a 'Inv Item Was Used' check does not pass, it doesn't count // so cmdsrun remains 0 if no inventory items matched -int run_interaction_commandlist (InteractionCommandList *nicl, int *timesrun, int*cmdsrun) { - size_t i; - - if (nicl == nullptr) - return -1; - - for (i = 0; i < nicl->Cmds.size(); i++) { - cmdsrun[0] ++; - int room_was = play.room_changes; - - switch (nicl->Cmds[i].Type) { - case 0: // Do nothing - break; - case 1: // Run script - { - TempEip tempip(4001); - RuntimeScriptValue rval_null; - update_polled_mp3(); - if ((strstr(evblockbasename,"character")!=nullptr) || (strstr(evblockbasename,"inventory")!=nullptr)) { - // Character or Inventory (global script) - const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); - // we are already inside the mouseclick event of the script, can't nest calls - QueueScriptFunction(kScInstGame, torun); - } - else { - // Other (room script) - const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); - QueueScriptFunction(kScInstRoom, torun); - } - update_polled_mp3(); - break; - } - case 2: // Add score (first time) - if (timesrun[0] > 0) - break; - timesrun[0] ++; - case 3: // Add score - GiveScore (IPARAM1); - break; - case 4: // Display Message - /* if (comprdata<0) - display_message_aschar=evb->data[ss];*/ - DisplayMessage(IPARAM1); - break; - case 5: // Play Music - PlayMusicResetQueue(IPARAM1); - break; - case 6: // Stop Music - stopmusic (); - break; - case 7: // Play Sound - play_sound (IPARAM1); - break; - case 8: // Play Flic - play_flc_file(IPARAM1, IPARAM2); - break; - case 9: // Run Dialog - { int room_was = play.room_changes; - RunDialog(IPARAM1); - // if they changed room within the dialog script, - // the interaction command list is no longer valid - if (room_was != play.room_changes) - return -1; - } - break; - case 10: // Enable Dialog Option - SetDialogOption (IPARAM1, IPARAM2, 1); - break; - case 11: // Disable Dialog Option - SetDialogOption (IPARAM1, IPARAM2, 0); - break; - case 12: // Go To Screen - Character_ChangeRoomAutoPosition(playerchar, IPARAM1, IPARAM2); - return -1; - case 13: // Add Inventory - add_inventory (IPARAM1); - break; - case 14: // Move Object - MoveObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); - // if they want to wait until finished, do so - if (IPARAM5) - GameLoopUntilNotMoving(&objs[IPARAM1].moving); - break; - case 15: // Object Off - ObjectOff (IPARAM1); - break; - case 16: // Object On - ObjectOn (IPARAM1); - break; - case 17: // Set Object View - SetObjectView (IPARAM1, IPARAM2); - break; - case 18: // Animate Object - AnimateObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); - break; - case 19: // Move Character - if (IPARAM4) - MoveCharacterBlocking (IPARAM1, IPARAM2, IPARAM3, 0); - else - MoveCharacter (IPARAM1, IPARAM2, IPARAM3); - break; - case 20: // If Inventory Item was used - if (play.usedinv == IPARAM1) { - if (game.options[OPT_NOLOSEINV] == 0) - lose_inventory (play.usedinv); - if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) - return -1; - } - else - cmdsrun[0] --; - break; - case 21: // if player has inventory item - if (playerchar->inv[IPARAM1] > 0) - if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) - return -1; - break; - case 22: // if a character is moving - if (game.chars[IPARAM1].walking) - if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) - return -1; - break; - case 23: // if two variables are equal - if (IPARAM1 == IPARAM2) - if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) - return -1; - break; - case 24: // Stop character walking - StopMoving (IPARAM1); - break; - case 25: // Go to screen at specific co-ordinates - NewRoomEx (IPARAM1, IPARAM2, IPARAM3); - return -1; - case 26: // Move NPC to different room - if (!is_valid_character(IPARAM1)) - quit("!Move NPC to different room: invalid character specified"); - game.chars[IPARAM1].room = IPARAM2; - break; - case 27: // Set character view - SetCharacterView (IPARAM1, IPARAM2); - break; - case 28: // Release character view - ReleaseCharacterView (IPARAM1); - break; - case 29: // Follow character - FollowCharacter (IPARAM1, IPARAM2); - break; - case 30: // Stop following - FollowCharacter (IPARAM1, -1); - break; - case 31: // Disable hotspot - DisableHotspot (IPARAM1); - break; - case 32: // Enable hotspot - EnableHotspot (IPARAM1); - break; - case 33: // Set variable value - get_interaction_variable(nicl->Cmds[i].Data[0].Value)->Value = IPARAM2; - break; - case 34: // Run animation - scAnimateCharacter(IPARAM1, IPARAM2, IPARAM3, 0); - GameLoopUntilValueIsZero(&game.chars[IPARAM1].animating); - break; - case 35: // Quick animation - SetCharacterView (IPARAM1, IPARAM2); - scAnimateCharacter(IPARAM1, IPARAM3, IPARAM4, 0); - GameLoopUntilValueIsZero(&game.chars[IPARAM1].animating); - ReleaseCharacterView (IPARAM1); - break; - case 36: // Set idle animation - SetCharacterIdle (IPARAM1, IPARAM2, IPARAM3); - break; - case 37: // Disable idle animation - SetCharacterIdle (IPARAM1, -1, -1); - break; - case 38: // Lose inventory item - lose_inventory (IPARAM1); - break; - case 39: // Show GUI - InterfaceOn (IPARAM1); - break; - case 40: // Hide GUI - InterfaceOff (IPARAM1); - break; - case 41: // Stop running more commands - return -1; - case 42: // Face location - FaceLocation (IPARAM1, IPARAM2, IPARAM3); - break; - case 43: // Pause command processor - scrWait (IPARAM1); - break; - case 44: // Change character view - ChangeCharacterView (IPARAM1, IPARAM2); - break; - case 45: // If player character is - if (GetPlayerCharacter() == IPARAM1) - if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) - return -1; - break; - case 46: // if cursor mode is - if (GetCursorMode() == IPARAM1) - if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) - return -1; - break; - case 47: // if player has been to room - if (HasBeenToRoom(IPARAM1)) - if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) - return -1; - break; - default: - quit("unknown new interaction command"); - break; - } - - // if the room changed within the action, nicl is no longer valid - if (room_was != play.room_changes) - return -1; - } - return 0; +int run_interaction_commandlist(InteractionCommandList *nicl, int *timesrun, int *cmdsrun) { + size_t i; + + if (nicl == nullptr) + return -1; + + for (i = 0; i < nicl->Cmds.size(); i++) { + cmdsrun[0] ++; + int room_was = play.room_changes; + + switch (nicl->Cmds[i].Type) { + case 0: // Do nothing + break; + case 1: { // Run script + TempEip tempip(4001); + RuntimeScriptValue rval_null; + update_polled_mp3(); + if ((strstr(evblockbasename, "character") != nullptr) || (strstr(evblockbasename, "inventory") != nullptr)) { + // Character or Inventory (global script) + const char *torun = make_ts_func_name(evblockbasename, evblocknum, nicl->Cmds[i].Data[0].Value); + // we are already inside the mouseclick event of the script, can't nest calls + QueueScriptFunction(kScInstGame, torun); + } else { + // Other (room script) + const char *torun = make_ts_func_name(evblockbasename, evblocknum, nicl->Cmds[i].Data[0].Value); + QueueScriptFunction(kScInstRoom, torun); + } + update_polled_mp3(); + break; + } + case 2: // Add score (first time) + if (timesrun[0] > 0) + break; + timesrun[0] ++; + case 3: // Add score + GiveScore(IPARAM1); + break; + case 4: // Display Message + /* if (comprdata<0) + display_message_aschar=evb->data[ss];*/ + DisplayMessage(IPARAM1); + break; + case 5: // Play Music + PlayMusicResetQueue(IPARAM1); + break; + case 6: // Stop Music + stopmusic(); + break; + case 7: // Play Sound + play_sound(IPARAM1); + break; + case 8: // Play Flic + play_flc_file(IPARAM1, IPARAM2); + break; + case 9: { // Run Dialog + int room_was = play.room_changes; + RunDialog(IPARAM1); + // if they changed room within the dialog script, + // the interaction command list is no longer valid + if (room_was != play.room_changes) + return -1; + } + break; + case 10: // Enable Dialog Option + SetDialogOption(IPARAM1, IPARAM2, 1); + break; + case 11: // Disable Dialog Option + SetDialogOption(IPARAM1, IPARAM2, 0); + break; + case 12: // Go To Screen + Character_ChangeRoomAutoPosition(playerchar, IPARAM1, IPARAM2); + return -1; + case 13: // Add Inventory + add_inventory(IPARAM1); + break; + case 14: // Move Object + MoveObject(IPARAM1, IPARAM2, IPARAM3, IPARAM4); + // if they want to wait until finished, do so + if (IPARAM5) + GameLoopUntilNotMoving(&objs[IPARAM1].moving); + break; + case 15: // Object Off + ObjectOff(IPARAM1); + break; + case 16: // Object On + ObjectOn(IPARAM1); + break; + case 17: // Set Object View + SetObjectView(IPARAM1, IPARAM2); + break; + case 18: // Animate Object + AnimateObject(IPARAM1, IPARAM2, IPARAM3, IPARAM4); + break; + case 19: // Move Character + if (IPARAM4) + MoveCharacterBlocking(IPARAM1, IPARAM2, IPARAM3, 0); + else + MoveCharacter(IPARAM1, IPARAM2, IPARAM3); + break; + case 20: // If Inventory Item was used + if (play.usedinv == IPARAM1) { + if (game.options[OPT_NOLOSEINV] == 0) + lose_inventory(play.usedinv); + if (run_interaction_commandlist(nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + } else + cmdsrun[0] --; + break; + case 21: // if player has inventory item + if (playerchar->inv[IPARAM1] > 0) + if (run_interaction_commandlist(nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 22: // if a character is moving + if (game.chars[IPARAM1].walking) + if (run_interaction_commandlist(nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 23: // if two variables are equal + if (IPARAM1 == IPARAM2) + if (run_interaction_commandlist(nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 24: // Stop character walking + StopMoving(IPARAM1); + break; + case 25: // Go to screen at specific co-ordinates + NewRoomEx(IPARAM1, IPARAM2, IPARAM3); + return -1; + case 26: // Move NPC to different room + if (!is_valid_character(IPARAM1)) + quit("!Move NPC to different room: invalid character specified"); + game.chars[IPARAM1].room = IPARAM2; + break; + case 27: // Set character view + SetCharacterView(IPARAM1, IPARAM2); + break; + case 28: // Release character view + ReleaseCharacterView(IPARAM1); + break; + case 29: // Follow character + FollowCharacter(IPARAM1, IPARAM2); + break; + case 30: // Stop following + FollowCharacter(IPARAM1, -1); + break; + case 31: // Disable hotspot + DisableHotspot(IPARAM1); + break; + case 32: // Enable hotspot + EnableHotspot(IPARAM1); + break; + case 33: // Set variable value + get_interaction_variable(nicl->Cmds[i].Data[0].Value)->Value = IPARAM2; + break; + case 34: // Run animation + scAnimateCharacter(IPARAM1, IPARAM2, IPARAM3, 0); + GameLoopUntilValueIsZero(&game.chars[IPARAM1].animating); + break; + case 35: // Quick animation + SetCharacterView(IPARAM1, IPARAM2); + scAnimateCharacter(IPARAM1, IPARAM3, IPARAM4, 0); + GameLoopUntilValueIsZero(&game.chars[IPARAM1].animating); + ReleaseCharacterView(IPARAM1); + break; + case 36: // Set idle animation + SetCharacterIdle(IPARAM1, IPARAM2, IPARAM3); + break; + case 37: // Disable idle animation + SetCharacterIdle(IPARAM1, -1, -1); + break; + case 38: // Lose inventory item + lose_inventory(IPARAM1); + break; + case 39: // Show GUI + InterfaceOn(IPARAM1); + break; + case 40: // Hide GUI + InterfaceOff(IPARAM1); + break; + case 41: // Stop running more commands + return -1; + case 42: // Face location + FaceLocation(IPARAM1, IPARAM2, IPARAM3); + break; + case 43: // Pause command processor + scrWait(IPARAM1); + break; + case 44: // Change character view + ChangeCharacterView(IPARAM1, IPARAM2); + break; + case 45: // If player character is + if (GetPlayerCharacter() == IPARAM1) + if (run_interaction_commandlist(nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 46: // if cursor mode is + if (GetCursorMode() == IPARAM1) + if (run_interaction_commandlist(nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + case 47: // if player has been to room + if (HasBeenToRoom(IPARAM1)) + if (run_interaction_commandlist(nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) + return -1; + break; + default: + quit("unknown new interaction command"); + break; + } + + // if the room changed within the action, nicl is no longer valid + if (room_was != play.room_changes) + return -1; + } + return 0; } // check and abort game if the script is currently // inside the rep_exec_always function void can_run_delayed_command() { - if (no_blocking_functions) - quit("!This command cannot be used within non-blocking events such as " REP_EXEC_ALWAYS_NAME); + if (no_blocking_functions) + quit("!This command cannot be used within non-blocking events such as " REP_EXEC_ALWAYS_NAME); } -void run_unhandled_event (int evnt) { - - if (play.check_interaction_only) - return; - - int evtype=0; - if (ags_strnicmp(evblockbasename,"hotspot",7)==0) evtype=1; - else if (ags_strnicmp(evblockbasename,"object",6)==0) evtype=2; - else if (ags_strnicmp(evblockbasename,"character",9)==0) evtype=3; - else if (ags_strnicmp(evblockbasename,"inventory",9)==0) evtype=5; - else if (ags_strnicmp(evblockbasename,"region",6)==0) - return; // no unhandled_events for regions - - // clicked Hotspot 0, so change the type code - if ((evtype == 1) & (evblocknum == 0) & (evnt != 0) & (evnt != 5) & (evnt != 6)) - evtype = 4; - if ((evtype==1) & ((evnt==0) | (evnt==5) | (evnt==6))) - ; // character stands on hotspot, mouse moves over hotspot, any click - else if ((evtype==2) & (evnt==4)) ; // any click on object - else if ((evtype==3) & (evnt==4)) ; // any click on character - else if (evtype > 0) { - can_run_delayed_command(); - - QueueScriptFunction(kScInstGame, "unhandled_event", 2, RuntimeScriptValue().SetInt32(evtype), RuntimeScriptValue().SetInt32(evnt)); - } +void run_unhandled_event(int evnt) { + + if (play.check_interaction_only) + return; + + int evtype = 0; + if (ags_strnicmp(evblockbasename, "hotspot", 7) == 0) evtype = 1; + else if (ags_strnicmp(evblockbasename, "object", 6) == 0) evtype = 2; + else if (ags_strnicmp(evblockbasename, "character", 9) == 0) evtype = 3; + else if (ags_strnicmp(evblockbasename, "inventory", 9) == 0) evtype = 5; + else if (ags_strnicmp(evblockbasename, "region", 6) == 0) + return; // no unhandled_events for regions + + // clicked Hotspot 0, so change the type code + if ((evtype == 1) & (evblocknum == 0) & (evnt != 0) & (evnt != 5) & (evnt != 6)) + evtype = 4; + if ((evtype == 1) & ((evnt == 0) | (evnt == 5) | (evnt == 6))) + ; // character stands on hotspot, mouse moves over hotspot, any click + else if ((evtype == 2) & (evnt == 4)) ; // any click on object + else if ((evtype == 3) & (evnt == 4)) ; // any click on character + else if (evtype > 0) { + can_run_delayed_command(); + + QueueScriptFunction(kScInstGame, "unhandled_event", 2, RuntimeScriptValue().SetInt32(evtype), RuntimeScriptValue().SetInt32(evnt)); + } } diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h index 68ac9d598b30..14d635a2f929 100644 --- a/engines/ags/engine/script/script.h +++ b/engines/ags/engine/script/script.h @@ -42,9 +42,9 @@ using AGS::Common::InteractionVariable; #define REP_EXEC_ALWAYS_NAME "repeatedly_execute_always" #define REP_EXEC_NAME "repeatedly_execute" -int run_dialog_request (int parmtr); -void run_function_on_non_blocking_thread(NonBlockingScriptFunction* funcToRun); -int run_interaction_event (Interaction *nint, int evnt, int chkAny = -1, int isInv = 0); +int run_dialog_request(int parmtr); +void run_function_on_non_blocking_thread(NonBlockingScriptFunction *funcToRun); +int run_interaction_event(Interaction *nint, int evnt, int chkAny = -1, int isInv = 0); int run_interaction_script(InteractionScripts *nint, int evnt, int chkAny = -1, int isInv = 0); int create_global_script(); void cancel_all_scripts(); @@ -63,28 +63,28 @@ int RunTextScriptIParam(ccInstance *sci, const char *tsname, const RuntimeSc int RunTextScript2IParam(ccInstance *sci, const char *tsname, const RuntimeScriptValue &iparam, const RuntimeScriptValue ¶m2); int PrepareTextScript(ccInstance *sci, const char **tsname); -bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction* funcToRun, bool hasTheFunc); +bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcToRun, bool hasTheFunc); AGS::Common::String GetScriptName(ccInstance *sci); //============================================================================= -char* make_ts_func_name(const char*base,int iii,int subd); +char *make_ts_func_name(const char *base, int iii, int subd); // Performs various updates to the game after script interpreter returns control to the engine. // Executes actions and does changes that are not executed immediately at script command, for // optimisation and other reasons. void post_script_cleanup(); void quit_with_script_error(const char *functionName); -int get_nivalue (InteractionCommandList *nic, int idx, int parm); -int run_interaction_commandlist (InteractionCommandList *nicl, int *timesrun, int*cmdsrun); -InteractionVariable *get_interaction_variable (int varindx); +int get_nivalue(InteractionCommandList *nic, int idx, int parm); +int run_interaction_commandlist(InteractionCommandList *nicl, int *timesrun, int *cmdsrun); +InteractionVariable *get_interaction_variable(int varindx); InteractionVariable *FindGraphicalVariable(const char *varName); -void run_unhandled_event (int evnt); +void run_unhandled_event(int evnt); void can_run_delayed_command(); extern ExecutingScript scripts[MAX_SCRIPT_AT_ONCE]; -extern ExecutingScript*curscript; +extern ExecutingScript *curscript; extern PScript gamescript; extern PScript dialogScriptsScript; @@ -95,7 +95,7 @@ extern ccInstance *gameinstFork, *roominstFork; extern int num_scripts; extern int post_script_cleanup_stack; -extern int inside_script,in_graph_script; +extern int inside_script, in_graph_script; extern int no_blocking_functions; // set to 1 while in rep_Exec_always extern NonBlockingScriptFunction repExecAlways; diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp index 706a44877910..99c01cd45a1d 100644 --- a/engines/ags/engine/script/script_api.cpp +++ b/engines/ags/engine/script/script_api.cpp @@ -30,44 +30,40 @@ namespace Math = AGS::Common::Math; -enum FormatParseResult -{ - kFormatParseNone, - kFormatParseInvalid, - kFormatParseLiteralPercent, - kFormatParseArgInteger, - kFormatParseArgFloat, - kFormatParseArgString, - kFormatParseArgPointer, - - kFormatParseArgFirst = kFormatParseArgInteger, - kFormatParseArgLast = kFormatParseArgPointer +enum FormatParseResult { + kFormatParseNone, + kFormatParseInvalid, + kFormatParseLiteralPercent, + kFormatParseArgInteger, + kFormatParseArgFloat, + kFormatParseArgString, + kFormatParseArgPointer, + + kFormatParseArgFirst = kFormatParseArgInteger, + kFormatParseArgLast = kFormatParseArgPointer }; // Helper functions for getting parameter value either from script val array or va_list -inline int GetArgInt(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) -{ - if (varg_ptr) - return va_arg(*varg_ptr, int); - else - return sc_args[arg_idx].IValue; +inline int GetArgInt(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) { + if (varg_ptr) + return va_arg(*varg_ptr, int); + else + return sc_args[arg_idx].IValue; } -inline float GetArgFloat(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) -{ - // note that script variables store only floats, but va_list has floats promoted to double - if (varg_ptr) - return (float)va_arg(*varg_ptr, double); - else - return sc_args[arg_idx].FValue; +inline float GetArgFloat(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) { + // note that script variables store only floats, but va_list has floats promoted to double + if (varg_ptr) + return (float)va_arg(*varg_ptr, double); + else + return sc_args[arg_idx].FValue; } -inline const char *GetArgPtr(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) -{ - if (varg_ptr) - return va_arg(*varg_ptr, const char*); - else - return sc_args[arg_idx].Ptr; +inline const char *GetArgPtr(const RuntimeScriptValue *sc_args, va_list *varg_ptr, int arg_idx) { + if (varg_ptr) + return va_arg(*varg_ptr, const char *); + else + return sc_args[arg_idx].Ptr; } @@ -75,177 +71,156 @@ inline const char *GetArgPtr(const RuntimeScriptValue *sc_args, va_list *varg_pt // snprintf but formatting values ourselves, or by using some library method // that supports customizing, such as getting arguments in a custom way. const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, - const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr) -{ - if (!buffer || buf_length == 0) - { - cc_error("Internal error in ScriptSprintf: buffer is null"); - return ""; - } - if (!format) - {// NOTE: interpreter (usually) catches null-pointer sent as format at some stage earlier - cc_error("Internal error in ScriptSprintf: format string is null"); - return ""; - } - if (!varg_ptr && sc_argc > 0 && !sc_args) - { - cc_error("Internal error in ScriptSprintf: args pointer is null"); - return ""; - } - - // Expected format character count: - // percent sign: 1 - // flag: 1 - // field width 10 (an uint32 number) - // precision sign 1 - // precision 10 (an uint32 number) - // length modifier 2 - // type 1 - // NOTE: although width and precision will - // not likely be defined by a 10-digit - // number, such case is theoretically valid. - const size_t fmtbuf_size = 27; - char fmtbuf[fmtbuf_size]; - char *fmt_bufptr; - char *fmt_bufendptr = &fmtbuf[fmtbuf_size - 1]; - - char *out_ptr = buffer; - // save 1 character for null terminator - const char *out_endptr = buffer + buf_length - 1; - const char *fmt_ptr = format; - int32_t arg_idx = 0; - - ptrdiff_t avail_outbuf; - int snprintf_res; - FormatParseResult fmt_done; - - // Parse the format string, looking for argument placeholders - while (*fmt_ptr && out_ptr != out_endptr) - { - // Try to put argument into placeholder - if (*fmt_ptr == '%') - { - avail_outbuf = out_endptr - out_ptr; - fmt_bufptr = fmtbuf; - *(fmt_bufptr++) = '%'; - snprintf_res = 0; - fmt_done = kFormatParseNone; - - // Parse placeholder - while (*(++fmt_ptr) && fmt_done == kFormatParseNone && fmt_bufptr != fmt_bufendptr) - { - *(fmt_bufptr++) = *fmt_ptr; - switch (*fmt_ptr) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - fmt_done = kFormatParseArgInteger; - break; - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': - case 'a': - case 'A': - fmt_done = kFormatParseArgFloat; - break; - case 'p': - fmt_done = kFormatParseArgPointer; - break; - case 's': - fmt_done = kFormatParseArgString; - break; - case '%': - // This may be a literal percent sign ('%%') - if (fmt_bufptr - fmtbuf == 2) - { - fmt_done = kFormatParseLiteralPercent; - } - // ...Otherwise we reached the next placeholder - else - { - fmt_ptr--; - fmt_bufptr--; - fmt_done = kFormatParseInvalid; - } - break; - } - } - - // Deal with the placeholder parsing results - if (fmt_done == kFormatParseLiteralPercent) - { - // literal percent sign - *(out_ptr++) = '%'; - continue; - } - else if (fmt_done >= kFormatParseArgFirst && fmt_done <= kFormatParseArgLast && - (varg_ptr || arg_idx < sc_argc)) - { - // Print the actual value - // NOTE: snprintf is called with avail_outbuf + 1 here, because we let it use our reserved - // character for null-terminator, in case we are at the end of the buffer - *fmt_bufptr = 0; // terminate the format buffer, we are going to use it - if (fmt_done == kFormatParseArgInteger) - snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgInt(sc_args, varg_ptr, arg_idx)); - else if (fmt_done == kFormatParseArgFloat) - snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgFloat(sc_args, varg_ptr, arg_idx)); - else - { - const char *p = GetArgPtr(sc_args, varg_ptr, arg_idx); - // Do extra checks for %s placeholder - if (fmt_done == kFormatParseArgString && !p) - { - if (loaded_game_file_version < kGameVersion_320) - { - // explicitly put "(null)" into the placeholder - p = "(null)"; - } - else - { - cc_error("!ScriptSprintf: formatting argument %d is expected to be a string, but it is a null pointer", arg_idx + 1); - return ""; - } - } - else if (fmt_done == kFormatParseArgString && p == buffer) - { - cc_error("!ScriptSprintf: formatting argument %d is a pointer to output buffer", arg_idx + 1); - return ""; - } - snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, p); - } - - arg_idx++; - if (snprintf_res >= 0) - { - // snprintf returns maximal number of characters, so limit it with buffer size - out_ptr += Math::Min(snprintf_res, avail_outbuf); - continue; - } - // -- pass further to invalid format case - } - - // If format was not valid, or there are no available - // parameters, just copy stored format buffer as it is - size_t copy_len = Math::Min(Math::Min(fmt_bufptr - fmtbuf, fmtbuf_size - 1), avail_outbuf); - memcpy(out_ptr, fmtbuf, copy_len); - out_ptr += copy_len; - } - // If there's no placeholder, simply copy the character to output buffer - else - { - *(out_ptr++) = *(fmt_ptr++); - } - } - - // Terminate the string - *out_ptr = 0; - return buffer; + const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr) { + if (!buffer || buf_length == 0) { + cc_error("Internal error in ScriptSprintf: buffer is null"); + return ""; + } + if (!format) { + // NOTE: interpreter (usually) catches null-pointer sent as format at some stage earlier + cc_error("Internal error in ScriptSprintf: format string is null"); + return ""; + } + if (!varg_ptr && sc_argc > 0 && !sc_args) { + cc_error("Internal error in ScriptSprintf: args pointer is null"); + return ""; + } + + // Expected format character count: + // percent sign: 1 + // flag: 1 + // field width 10 (an uint32 number) + // precision sign 1 + // precision 10 (an uint32 number) + // length modifier 2 + // type 1 + // NOTE: although width and precision will + // not likely be defined by a 10-digit + // number, such case is theoretically valid. + const size_t fmtbuf_size = 27; + char fmtbuf[fmtbuf_size]; + char *fmt_bufptr; + char *fmt_bufendptr = &fmtbuf[fmtbuf_size - 1]; + + char *out_ptr = buffer; + // save 1 character for null terminator + const char *out_endptr = buffer + buf_length - 1; + const char *fmt_ptr = format; + int32_t arg_idx = 0; + + ptrdiff_t avail_outbuf; + int snprintf_res; + FormatParseResult fmt_done; + + // Parse the format string, looking for argument placeholders + while (*fmt_ptr && out_ptr != out_endptr) { + // Try to put argument into placeholder + if (*fmt_ptr == '%') { + avail_outbuf = out_endptr - out_ptr; + fmt_bufptr = fmtbuf; + *(fmt_bufptr++) = '%'; + snprintf_res = 0; + fmt_done = kFormatParseNone; + + // Parse placeholder + while (*(++fmt_ptr) && fmt_done == kFormatParseNone && fmt_bufptr != fmt_bufendptr) { + *(fmt_bufptr++) = *fmt_ptr; + switch (*fmt_ptr) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + fmt_done = kFormatParseArgInteger; + break; + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'a': + case 'A': + fmt_done = kFormatParseArgFloat; + break; + case 'p': + fmt_done = kFormatParseArgPointer; + break; + case 's': + fmt_done = kFormatParseArgString; + break; + case '%': + // This may be a literal percent sign ('%%') + if (fmt_bufptr - fmtbuf == 2) { + fmt_done = kFormatParseLiteralPercent; + } + // ...Otherwise we reached the next placeholder + else { + fmt_ptr--; + fmt_bufptr--; + fmt_done = kFormatParseInvalid; + } + break; + } + } + + // Deal with the placeholder parsing results + if (fmt_done == kFormatParseLiteralPercent) { + // literal percent sign + *(out_ptr++) = '%'; + continue; + } else if (fmt_done >= kFormatParseArgFirst && fmt_done <= kFormatParseArgLast && + (varg_ptr || arg_idx < sc_argc)) { + // Print the actual value + // NOTE: snprintf is called with avail_outbuf + 1 here, because we let it use our reserved + // character for null-terminator, in case we are at the end of the buffer + *fmt_bufptr = 0; // terminate the format buffer, we are going to use it + if (fmt_done == kFormatParseArgInteger) + snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgInt(sc_args, varg_ptr, arg_idx)); + else if (fmt_done == kFormatParseArgFloat) + snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgFloat(sc_args, varg_ptr, arg_idx)); + else { + const char *p = GetArgPtr(sc_args, varg_ptr, arg_idx); + // Do extra checks for %s placeholder + if (fmt_done == kFormatParseArgString && !p) { + if (loaded_game_file_version < kGameVersion_320) { + // explicitly put "(null)" into the placeholder + p = "(null)"; + } else { + cc_error("!ScriptSprintf: formatting argument %d is expected to be a string, but it is a null pointer", arg_idx + 1); + return ""; + } + } else if (fmt_done == kFormatParseArgString && p == buffer) { + cc_error("!ScriptSprintf: formatting argument %d is a pointer to output buffer", arg_idx + 1); + return ""; + } + snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, p); + } + + arg_idx++; + if (snprintf_res >= 0) { + // snprintf returns maximal number of characters, so limit it with buffer size + out_ptr += Math::Min(snprintf_res, avail_outbuf); + continue; + } + // -- pass further to invalid format case + } + + // If format was not valid, or there are no available + // parameters, just copy stored format buffer as it is + size_t copy_len = Math::Min(Math::Min(fmt_bufptr - fmtbuf, fmtbuf_size - 1), avail_outbuf); + memcpy(out_ptr, fmtbuf, copy_len); + out_ptr += copy_len; + } + // If there's no placeholder, simply copy the character to output buffer + else { + *(out_ptr++) = *(fmt_ptr++); + } + } + + // Terminate the string + *out_ptr = 0; + return buffer; } diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h index e333c7dc86f0..73eca53983d9 100644 --- a/engines/ags/engine/script/script_api.h +++ b/engines/ags/engine/script/script_api.h @@ -48,61 +48,59 @@ typedef RuntimeScriptValue ScriptAPIObjectFunction(void *self, const RuntimeScri const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr); // Sprintf that takes script values as arguments -inline const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, const RuntimeScriptValue *args, int32_t argc) -{ - return ScriptSprintf(buffer, buf_length, format, args, argc, nullptr); +inline const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, const RuntimeScriptValue *args, int32_t argc) { + return ScriptSprintf(buffer, buf_length, format, args, argc, nullptr); } // Variadic sprintf (needed, because all arguments are pushed as pointer-sized values). Currently used only when plugin calls // exported engine function. Should be removed when this plugin issue is resolved. -inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *format, va_list &arg_ptr) -{ - return ScriptSprintf(buffer, buf_length, format, nullptr, 0, &arg_ptr); +inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *format, va_list &arg_ptr) { + return ScriptSprintf(buffer, buf_length, format, nullptr, 0, &arg_ptr); } // Helper macros for script functions #define ASSERT_SELF(METHOD) \ - assert((self != NULL) && "Object pointer is null in call to API function") + assert((self != NULL) && "Object pointer is null in call to API function") #define ASSERT_PARAM_COUNT(FUNCTION, X) \ - assert((params != NULL && param_count >= X) && "Not enough parameters in call to API function") + assert((params != NULL && param_count >= X) && "Not enough parameters in call to API function") #define ASSERT_VARIABLE_VALUE(VARIABLE) \ - assert((params != NULL && param_count >= 1) && "Not enough parameters to set API property") + assert((params != NULL && param_count >= 1) && "Not enough parameters to set API property") #define ASSERT_OBJ_PARAM_COUNT(METHOD, X) \ - ASSERT_SELF(METHOD); \ - ASSERT_PARAM_COUNT(METHOD, X) + ASSERT_SELF(METHOD); \ + ASSERT_PARAM_COUNT(METHOD, X) //----------------------------------------------------------------------------- // Get/set variables #define API_VARGET_INT(VARIABLE) \ - return RuntimeScriptValue().SetInt32(VARIABLE) + return RuntimeScriptValue().SetInt32(VARIABLE) #define API_VARSET_PINT(VARIABLE) \ - ASSERT_VARIABLE_VALUE(VARIABLE); \ - VARIABLE = params[0].IValue; \ - return RuntimeScriptValue() + ASSERT_VARIABLE_VALUE(VARIABLE); \ + VARIABLE = params[0].IValue; \ + return RuntimeScriptValue() //----------------------------------------------------------------------------- // Calls to ScriptSprintf #define API_SCALL_SCRIPT_SPRINTF(FUNCTION, PARAM_COUNT) \ - ASSERT_PARAM_COUNT(FUNCTION, PARAM_COUNT); \ - char ScSfBuffer[STD_BUFFER_SIZE]; \ - const char *scsf_buffer = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(params[PARAM_COUNT - 1].Ptr), params + PARAM_COUNT, param_count - PARAM_COUNT) + ASSERT_PARAM_COUNT(FUNCTION, PARAM_COUNT); \ + char ScSfBuffer[STD_BUFFER_SIZE]; \ + const char *scsf_buffer = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(params[PARAM_COUNT - 1].Ptr), params + PARAM_COUNT, param_count - PARAM_COUNT) #define API_OBJCALL_SCRIPT_SPRINTF(METHOD, PARAM_COUNT) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, PARAM_COUNT); \ - char ScSfBuffer[STD_BUFFER_SIZE]; \ - const char *scsf_buffer = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(params[PARAM_COUNT - 1].Ptr), params + PARAM_COUNT, param_count - PARAM_COUNT) + ASSERT_OBJ_PARAM_COUNT(METHOD, PARAM_COUNT); \ + char ScSfBuffer[STD_BUFFER_SIZE]; \ + const char *scsf_buffer = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(params[PARAM_COUNT - 1].Ptr), params + PARAM_COUNT, param_count - PARAM_COUNT) //----------------------------------------------------------------------------- // Calls to ScriptSprintfV (unsafe plugin variant) #define API_PLUGIN_SCRIPT_SPRINTF(FORMAT_STR) \ - va_list args; \ - va_start(args, FORMAT_STR); \ - char ScSfBuffer[STD_BUFFER_SIZE]; \ - const char *scsf_buffer = ScriptVSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(FORMAT_STR), args); \ - va_end(args) + va_list args; \ + va_start(args, FORMAT_STR); \ + char ScSfBuffer[STD_BUFFER_SIZE]; \ + const char *scsf_buffer = ScriptVSprintf(ScSfBuffer, STD_BUFFER_SIZE, get_translation(FORMAT_STR), args); \ + va_end(args) //----------------------------------------------------------------------------- // Calls to static functions @@ -115,447 +113,447 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f // #define API_SCALL_VOID(FUNCTION) \ - FUNCTION(); \ - return RuntimeScriptValue((int32_t)0) + FUNCTION(); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PBOOL(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - FUNCTION(params[0].GetAsBool()); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + FUNCTION(params[0].GetAsBool()); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - FUNCTION(params[0].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + FUNCTION(params[0].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT2(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - FUNCTION(params[0].IValue, params[1].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION(params[0].IValue, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT3(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT4(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 4); \ - FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT5(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 5); \ - FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT6(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 6); \ - FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 6); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT_POBJ(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr, (P2CLASS*)params[2].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr, (P2CLASS*)params[2].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT2_POBJ(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - FUNCTION(params[0].IValue, params[1].IValue, (P1CLASS*)params[2].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION(params[0].IValue, params[1].IValue, (P1CLASS*)params[2].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT3_POBJ_PINT(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 5); \ - FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr, params[4].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr, params[4].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PINT4_POBJ(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 5); \ - FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, (P1CLASS*)params[4].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, (P1CLASS*)params[4].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_PFLOAT2(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - FUNCTION(params[0].FValue, params[1].FValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION(params[0].FValue, params[1].FValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_POBJ(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - FUNCTION((P1CLASS*)params[0].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + FUNCTION((P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_POBJ_PINT(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_POBJ_PINT2(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_VOID_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_SCALL_INT(FUNCTION) \ - return RuntimeScriptValue().SetInt32(FUNCTION()) + return RuntimeScriptValue().SetInt32(FUNCTION()) #define API_SCALL_INT_PINT(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue)) #define API_SCALL_INT_PINT2(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue)) #define API_SCALL_INT_PINT3(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue)) #define API_SCALL_INT_PINT4(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 4); \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue)) #define API_SCALL_INT_PINT4_PFLOAT(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 5) \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[3].FValue)) + ASSERT_PARAM_COUNT(FUNCTION, 5) \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[3].FValue)) #define API_SCALL_INT_PINT5(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 5); \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue)) #define API_SCALL_INT_PFLOAT_PINT(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].FValue, params[1].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].FValue, params[1].IValue)) #define API_SCALL_INT_POBJ(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr)) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr)) #define API_SCALL_INT_POBJ_PINT(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue)) #define API_SCALL_INT_POBJ_PINT2(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue)) #define API_SCALL_INT_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) #define API_SCALL_INT_PINT_POBJ(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32(FUNCTION(params[0].IValue, (P1CLASS*)params[1].Ptr)) #define API_SCALL_FLOAT(FUNCTION) \ - return RuntimeScriptValue().SetFloat(FUNCTION()) + return RuntimeScriptValue().SetFloat(FUNCTION()) #define API_SCALL_FLOAT_PINT(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - return RuntimeScriptValue().SetFloat(FUNCTION(params[0].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetFloat(FUNCTION(params[0].IValue)) #define API_SCALL_FLOAT_PFLOAT(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - return RuntimeScriptValue().SetFloat(FUNCTION(params[0].FValue)) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetFloat(FUNCTION(params[0].FValue)) #define API_SCALL_FLOAT_PFLOAT2(FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetFloat(FUNCTION(params[0].FValue, params[1].FValue)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetFloat(FUNCTION(params[0].FValue, params[1].FValue)) #define API_SCALL_BOOL(FUNCTION) \ - return RuntimeScriptValue().SetInt32AsBool(FUNCTION()) + return RuntimeScriptValue().SetInt32AsBool(FUNCTION()) #define API_SCALL_BOOL_OBJ(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr)) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr)) #define API_SCALL_BOOL_POBJ_PINT(FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue)) #define API_SCALL_BOOL_POBJ2(FUNCTION, P1CLASS, P2CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetInt32AsBool(FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) #define API_SCALL_OBJ(RET_CLASS, RET_MGR, FUNCTION) \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(), &RET_MGR) + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(), &RET_MGR) #define API_SCALL_OBJ_PINT(RET_CLASS, RET_MGR, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue), &RET_MGR) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue), &RET_MGR) #define API_SCALL_OBJ_POBJ_PINT_PBOOL(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].GetAsBool()), &RET_MGR) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].GetAsBool()), &RET_MGR) #define API_SCALL_OBJ_PINT2(RET_CLASS, RET_MGR, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue), &RET_MGR) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue), &RET_MGR) #define API_SCALL_OBJ_PINT3_POBJ(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 4); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr), &RET_MGR) + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr), &RET_MGR) #define API_SCALL_OBJ_POBJ(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr), &RET_MGR) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr), &RET_MGR) #define API_SCALL_OBJAUTO(RET_CLASS, FUNCTION) \ - RET_CLASS* ret_obj = FUNCTION(); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + RET_CLASS* ret_obj = FUNCTION(); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_PINT(RET_CLASS, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - RET_CLASS* ret_obj = FUNCTION(params[0].IValue); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_PINT2(RET_CLASS, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_PINT3(RET_CLASS, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 3); \ - RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 3); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_PINT4(RET_CLASS, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 4); \ - RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 4); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_PINT5(RET_CLASS, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 5); \ - RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + RET_CLASS* ret_obj = FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_PBOOL2(RET_CLASS, FUNCTION) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - RET_CLASS* ret_obj = FUNCTION(params[0].GetAsBool(), params[1].GetAsBool()); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = FUNCTION(params[0].GetAsBool(), params[1].GetAsBool()); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_POBJ(RET_CLASS, FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 1); \ - RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_POBJ_PINT(RET_CLASS, FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - RET_CLASS* ret_obj = (RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = (RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_OBJAUTO_POBJ_PINT4(RET_CLASS, FUNCTION, P1CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 5); \ - RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_PARAM_COUNT(FUNCTION, 5); \ + RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_SCALL_STOBJ_POBJ2(RET_CLASS, FUNCTION, P1CLASS, P2CLASS) \ - ASSERT_PARAM_COUNT(FUNCTION, 2); \ - RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ - return RuntimeScriptValue().SetStaticObject(ret_obj, &GlobalStaticManager) + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + RET_CLASS* ret_obj = FUNCTION((P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ + return RuntimeScriptValue().SetStaticObject(ret_obj, &GlobalStaticManager) //----------------------------------------------------------------------------- // Calls to object functions #define API_OBJCALL_VOID(CLASS, METHOD) \ - ASSERT_SELF(METHOD); \ - METHOD((CLASS*)self); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_SELF(METHOD); \ + METHOD((CLASS*)self); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - METHOD((CLASS*)self, params[0].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, params[0].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT2(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - METHOD((CLASS*)self, params[0].IValue, params[1].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT3(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ - METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT4(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 4); \ - METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 4); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT5(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 5); \ - METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 5); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT6(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 6); \ - METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 6); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PFLOAT(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - METHOD((CLASS*)self, params[0].FValue); \ - return RuntimeScriptValue() + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, params[0].FValue); \ + return RuntimeScriptValue() #define API_OBJCALL_VOID_PFLOAT2(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - METHOD((CLASS*)self, params[0].FValue, params[1].FValue); \ - return RuntimeScriptValue() + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].FValue, params[1].FValue); \ + return RuntimeScriptValue() #define API_OBJCALL_VOID_PBOOL(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - METHOD((CLASS*)self, params[0].GetAsBool()); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, params[0].GetAsBool()); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT_PBOOL(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - METHOD((CLASS*)self, params[0].IValue, params[1].GetAsBool()); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].IValue, params[1].GetAsBool()); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT_POBJ(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - METHOD((CLASS*)self, params[0].IValue, (P1CLASS*)params[1].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, params[0].IValue, (P1CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT3_POBJ(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 4); \ - METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 4); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_PINT5_POBJ(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 6); \ - METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, (P1CLASS*)params[5].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 6); \ + METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, (P1CLASS*)params[5].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_POBJ(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_POBJ_PINT(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_POBJ_PINT2(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ - METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue, params[2].IValue); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_VOID_POBJ2(CLASS, METHOD, P1CLASS, P2CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ - return RuntimeScriptValue((int32_t)0) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr); \ + return RuntimeScriptValue((int32_t)0) #define API_OBJCALL_INT(CLASS, METHOD) \ - ASSERT_SELF(METHOD); \ - return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self)) + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self)) #define API_OBJCALL_INT_PINT(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue)) #define API_OBJCALL_INT_PINT_POBJ(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue, params[1].Ptr)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue, params[1].Ptr)) #define API_OBJCALL_INT_PINT2(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue, params[1].IValue)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, params[0].IValue, params[1].IValue)) #define API_OBJCALL_INT_POBJ(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr)) #define API_OBJCALL_INT_POBJ_PINT(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue)) #define API_OBJCALL_INT_POBJ_PBOOL(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].GetAsBool())) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].GetAsBool())) #define API_OBJCALL_FLOAT(CLASS, METHOD) \ - ASSERT_SELF(METHOD); \ - return RuntimeScriptValue().SetFloat(METHOD((CLASS*)self)) + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetFloat(METHOD((CLASS*)self)) #define API_OBJCALL_BOOL(CLASS, METHOD) \ - ASSERT_SELF(METHOD); \ - return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self)) + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self)) #define API_OBJCALL_BOOL_PINT(CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, params[0].IValue)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, params[0].IValue)) #define API_OBJCALL_BOOL_POBJ(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr)) #define API_OBJCALL_BOOL_POBJ_PINT(CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, params[1].IValue)) #define API_OBJCALL_BOOL_POBJ2(CLASS, METHOD, P1CLASS, P2CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr)) #define API_OBJCALL_BOOL(CLASS, METHOD) \ - ASSERT_SELF(METHOD); \ - return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self)) + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetInt32AsBool(METHOD((CLASS*)self)) #define API_OBJCALL_OBJ_PINT_POBJ(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, params[0].IValue, (P1CLASS*)params[1].Ptr), &RET_MGR) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, params[0].IValue, (P1CLASS*)params[1].Ptr), &RET_MGR) #define API_OBJCALL_OBJ_POBJ2_PINT(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS, P2CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ - return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].IValue), &RET_MGR) + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].IValue), &RET_MGR) #define API_OBJCALL_OBJ_POBJ2_PBOOL(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS, P2CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ - return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].GetAsBool()), &RET_MGR) + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].GetAsBool()), &RET_MGR) #define API_OBJCALL_OBJ(CLASS, RET_CLASS, RET_MGR, METHOD) \ - ASSERT_SELF(METHOD); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self), &RET_MGR) + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self), &RET_MGR) #define API_OBJCALL_OBJ_PINT(CLASS, RET_CLASS, RET_MGR, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue), &RET_MGR) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue), &RET_MGR) #define API_OBJCALL_OBJ_PINT2(CLASS, RET_CLASS, RET_MGR, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue), &RET_MGR) + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue), &RET_MGR) #define API_OBJCALL_OBJ_PINT3(CLASS, RET_CLASS, RET_MGR, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue), &RET_MGR) + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue), &RET_MGR) #define API_OBJCALL_OBJ_POBJ(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr), &RET_MGR) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr), &RET_MGR) #define API_OBJCALL_OBJAUTO(CLASS, RET_CLASS, METHOD) \ - ASSERT_SELF(METHOD); \ - RET_CLASS* ret_obj = METHOD((CLASS*)self); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_SELF(METHOD); \ + RET_CLASS* ret_obj = METHOD((CLASS*)self); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_OBJCALL_OBJAUTO_PINT2_PBOOL(CLASS, RET_CLASS, METHOD) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ - RET_CLASS* ret_obj = METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].GetAsBool()); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + RET_CLASS* ret_obj = METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].GetAsBool()); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #define API_OBJCALL_OBJAUTO_POBJ(CLASS, RET_CLASS, METHOD, P1CLASS) \ - ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ - RET_CLASS* ret_obj = METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ - return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + RET_CLASS* ret_obj = METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ + return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) #endif diff --git a/engines/ags/engine/script/script_engine.cpp b/engines/ags/engine/script/script_engine.cpp index 7dbb6cc0f755..c84c9546c042 100644 --- a/engines/ags/engine/script/script_engine.cpp +++ b/engines/ags/engine/script/script_engine.cpp @@ -37,26 +37,25 @@ #include "util/file.h" #include "util/stream.h" -namespace AGS { namespace Common { class RoomStruct; } } +namespace AGS { +namespace Common { +class RoomStruct; +} +} using namespace AGS::Common; extern void quit(const char *); extern int currentline; // in script/script_common -std::pair cc_error_at_line(const char *error_msg) -{ - ccInstance *sci = ccInstance::GetCurrentInstance(); - if (!sci) - { - return std::make_pair(String::FromFormat("Error (line %d): %s", currentline, error_msg), String()); - } - else - { - return std::make_pair(String::FromFormat("Error: %s\n", error_msg), ccInstance::GetCurrentInstance()->GetCallStack(5)); - } +std::pair cc_error_at_line(const char *error_msg) { + ccInstance *sci = ccInstance::GetCurrentInstance(); + if (!sci) { + return std::make_pair(String::FromFormat("Error (line %d): %s", currentline, error_msg), String()); + } else { + return std::make_pair(String::FromFormat("Error: %s\n", error_msg), ccInstance::GetCurrentInstance()->GetCallStack(5)); + } } -String cc_error_without_line(const char *error_msg) -{ - return String::FromFormat("Runtime error: %s", error_msg); +String cc_error_without_line(const char *error_msg) { + return String::FromFormat("Runtime error: %s", error_msg); } diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp index 939c9fb76d0d..014c86c16cfd 100644 --- a/engines/ags/engine/script/script_runtime.cpp +++ b/engines/ags/engine/script/script_runtime.cpp @@ -47,93 +47,76 @@ extern ccInstance *current_instance; // in script/cc_instance -bool ccAddExternalStaticFunction(const String &name, ScriptAPIFunction *pfn) -{ - return simp.add(name, RuntimeScriptValue().SetStaticFunction(pfn), nullptr) == 0; +bool ccAddExternalStaticFunction(const String &name, ScriptAPIFunction *pfn) { + return simp.add(name, RuntimeScriptValue().SetStaticFunction(pfn), nullptr) == 0; } -bool ccAddExternalPluginFunction(const String &name, void *pfn) -{ - return simp.add(name, RuntimeScriptValue().SetPluginFunction(pfn), nullptr) == 0; +bool ccAddExternalPluginFunction(const String &name, void *pfn) { + return simp.add(name, RuntimeScriptValue().SetPluginFunction(pfn), nullptr) == 0; } -bool ccAddExternalStaticObject(const String &name, void *ptr, ICCStaticObject *manager) -{ - return simp.add(name, RuntimeScriptValue().SetStaticObject(ptr, manager), nullptr) == 0; +bool ccAddExternalStaticObject(const String &name, void *ptr, ICCStaticObject *manager) { + return simp.add(name, RuntimeScriptValue().SetStaticObject(ptr, manager), nullptr) == 0; } -bool ccAddExternalStaticArray(const String &name, void *ptr, StaticArray *array_mgr) -{ - return simp.add(name, RuntimeScriptValue().SetStaticArray(ptr, array_mgr), nullptr) == 0; +bool ccAddExternalStaticArray(const String &name, void *ptr, StaticArray *array_mgr) { + return simp.add(name, RuntimeScriptValue().SetStaticArray(ptr, array_mgr), nullptr) == 0; } -bool ccAddExternalDynamicObject(const String &name, void *ptr, ICCDynamicObject *manager) -{ - return simp.add(name, RuntimeScriptValue().SetDynamicObject(ptr, manager), nullptr) == 0; +bool ccAddExternalDynamicObject(const String &name, void *ptr, ICCDynamicObject *manager) { + return simp.add(name, RuntimeScriptValue().SetDynamicObject(ptr, manager), nullptr) == 0; } -bool ccAddExternalObjectFunction(const String &name, ScriptAPIObjectFunction *pfn) -{ - return simp.add(name, RuntimeScriptValue().SetObjectFunction(pfn), nullptr) == 0; +bool ccAddExternalObjectFunction(const String &name, ScriptAPIObjectFunction *pfn) { + return simp.add(name, RuntimeScriptValue().SetObjectFunction(pfn), nullptr) == 0; } -bool ccAddExternalScriptSymbol(const String &name, const RuntimeScriptValue &prval, ccInstance *inst) -{ - return simp.add(name, prval, inst) == 0; +bool ccAddExternalScriptSymbol(const String &name, const RuntimeScriptValue &prval, ccInstance *inst) { + return simp.add(name, prval, inst) == 0; } -void ccRemoveExternalSymbol(const String &name) -{ - simp.remove(name); +void ccRemoveExternalSymbol(const String &name) { + simp.remove(name); } -void ccRemoveAllSymbols() -{ - simp.clear(); +void ccRemoveAllSymbols() { + simp.clear(); } ccInstance *loadedInstances[MAX_LOADED_INSTANCES] = {nullptr, -nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, -nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr + }; -void nullfree(void *data) -{ - if (data != nullptr) - free(data); +void nullfree(void *data) { + if (data != nullptr) + free(data); } -void *ccGetSymbolAddress(const String &name) -{ - const ScriptImport *import = simp.getByName(name); - if (import) - { - return import->Value.Ptr; - } - return nullptr; +void *ccGetSymbolAddress(const String &name) { + const ScriptImport *import = simp.getByName(name); + if (import) { + return import->Value.Ptr; + } + return nullptr; } -bool ccAddExternalFunctionForPlugin(const String &name, void *pfn) -{ - return simp_for_plugin.add(name, RuntimeScriptValue().SetPluginFunction(pfn), nullptr) == 0; +bool ccAddExternalFunctionForPlugin(const String &name, void *pfn) { + return simp_for_plugin.add(name, RuntimeScriptValue().SetPluginFunction(pfn), nullptr) == 0; } -void *ccGetSymbolAddressForPlugin(const String &name) -{ - const ScriptImport *import = simp_for_plugin.getByName(name); - if (import) - { - return import->Value.Ptr; - } - else - { - // Also search the internal symbol table for non-function symbols - import = simp.getByName(name); - if (import) - { - return import->Value.Ptr; - } - } - return nullptr; +void *ccGetSymbolAddressForPlugin(const String &name) { + const ScriptImport *import = simp_for_plugin.getByName(name); + if (import) { + return import->Value.Ptr; + } else { + // Also search the internal symbol table for non-function symbols + import = simp.getByName(name); + if (import) { + return import->Value.Ptr; + } + } + return nullptr; } new_line_hook_type new_line_hook = nullptr; @@ -144,158 +127,140 @@ int maxWhileLoops = 0; // If a while loop does this many iterations without the // NofityScriptAlive function getting called, the script // aborts. Set to 0 to disable. -void ccSetScriptAliveTimer (int numloop) { - maxWhileLoops = numloop; +void ccSetScriptAliveTimer(int numloop) { + maxWhileLoops = numloop; } -void ccNotifyScriptStillAlive () { - if (current_instance != nullptr) - current_instance->flags |= INSTF_RUNNING; +void ccNotifyScriptStillAlive() { + if (current_instance != nullptr) + current_instance->flags |= INSTF_RUNNING; } -void ccSetDebugHook(new_line_hook_type jibble) -{ - new_line_hook = jibble; +void ccSetDebugHook(new_line_hook_type jibble) { + new_line_hook = jibble; } -int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms) -{ - if (!addr) - { - cc_error("null function pointer in call_function"); - return -1; - } - if (numparm > 0 && !parms) - { - cc_error("invalid parameters array in call_function"); - return -1; - } +int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms) { + if (!addr) { + cc_error("null function pointer in call_function"); + return -1; + } + if (numparm > 0 && !parms) { + cc_error("invalid parameters array in call_function"); + return -1; + } - intptr_t parm_value[9]; - if (object) - { - parm_value[0] = (intptr_t)object->GetPtrWithOffset(); - numparm++; - } + intptr_t parm_value[9]; + if (object) { + parm_value[0] = (intptr_t)object->GetPtrWithOffset(); + numparm++; + } - for (int ival = object ? 1 : 0, iparm = 0; ival < numparm; ++ival, ++iparm) - { - switch (parms[iparm].Type) - { - case kScValInteger: - case kScValFloat: // AGS passes floats, copying their values into long variable - case kScValPluginArg: - parm_value[ival] = (intptr_t)parms[iparm].IValue; - break; - break; - default: - parm_value[ival] = (intptr_t)parms[iparm].GetPtrWithOffset(); - break; - } - } + for (int ival = object ? 1 : 0, iparm = 0; ival < numparm; ++ival, ++iparm) { + switch (parms[iparm].Type) { + case kScValInteger: + case kScValFloat: // AGS passes floats, copying their values into long variable + case kScValPluginArg: + parm_value[ival] = (intptr_t)parms[iparm].IValue; + break; + break; + default: + parm_value[ival] = (intptr_t)parms[iparm].GetPtrWithOffset(); + break; + } + } - // - // AN IMPORTANT NOTE ON PARAM TYPE - // of 2012-11-10 - // - //// NOTE of 2012-12-20: - //// Everything said below is applicable only for calling - //// exported plugin functions. - // - // Here we are sending parameters of type intptr_t to registered - // function of unknown kind. Intptr_t is 32-bit for x32 build and - // 64-bit for x64 build. - // The exported functions usually have two types of parameters: - // pointer and 'int' (32-bit). For x32 build those two have the - // same size, but for x64 build first has 64-bit size while the - // second remains 32-bit. - // In formal case that would cause 'overflow' - function will - // receive more data than needed (written to stack), with some - // values shifted further by 32 bits. - // - // Upon testing, however, it was revealed that AMD64 processor, - // the only platform we support x64 Linux AGS build on right now, - // treats all the function parameters pushed to stack as 64-bit - // values (few first parameters are sent via registers, and hence - // are least concern anyway). Therefore, no 'overflow' occurs, - // and 64-bit values are being effectively truncated to 32-bit - // integers in the callee. - // - // Since this is still quite unreliable, this should be - // reimplemented when there's enough free time available for - // developers both for coding & testing. - // - // Most basic idea is to pass array of RuntimeScriptValue - // objects (that hold type description) and get same RSV as a - // return result. Keep in mind, though, that this solution will - // require fixing ALL exported functions, so a good amount of - // time and energy should be allocated for this task. - // + // + // AN IMPORTANT NOTE ON PARAM TYPE + // of 2012-11-10 + // + //// NOTE of 2012-12-20: + //// Everything said below is applicable only for calling + //// exported plugin functions. + // + // Here we are sending parameters of type intptr_t to registered + // function of unknown kind. Intptr_t is 32-bit for x32 build and + // 64-bit for x64 build. + // The exported functions usually have two types of parameters: + // pointer and 'int' (32-bit). For x32 build those two have the + // same size, but for x64 build first has 64-bit size while the + // second remains 32-bit. + // In formal case that would cause 'overflow' - function will + // receive more data than needed (written to stack), with some + // values shifted further by 32 bits. + // + // Upon testing, however, it was revealed that AMD64 processor, + // the only platform we support x64 Linux AGS build on right now, + // treats all the function parameters pushed to stack as 64-bit + // values (few first parameters are sent via registers, and hence + // are least concern anyway). Therefore, no 'overflow' occurs, + // and 64-bit values are being effectively truncated to 32-bit + // integers in the callee. + // + // Since this is still quite unreliable, this should be + // reimplemented when there's enough free time available for + // developers both for coding & testing. + // + // Most basic idea is to pass array of RuntimeScriptValue + // objects (that hold type description) and get same RSV as a + // return result. Keep in mind, though, that this solution will + // require fixing ALL exported functions, so a good amount of + // time and energy should be allocated for this task. + // - switch (numparm) - { - case 0: - { - int (*fparam) (); - fparam = (int (*)())addr; - return fparam(); - } - case 1: - { - int (*fparam) (intptr_t); - fparam = (int (*)(intptr_t))addr; - return fparam(parm_value[0]); - } - case 2: - { - int (*fparam) (intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1]); - } - case 3: - { - int (*fparam) (intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2]); - } - case 4: - { - int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3]); - } - case 5: - { - int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4]); - } - case 6: - { - int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5]); - } - case 7: - { - int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6]); - } - case 8: - { - int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7]); - } - case 9: - { - int (*fparam) (intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7], parm_value[8]); - } - } + switch (numparm) { + case 0: { + int (*fparam)(); + fparam = (int (*)())addr; + return fparam(); + } + case 1: { + int (*fparam)(intptr_t); + fparam = (int (*)(intptr_t))addr; + return fparam(parm_value[0]); + } + case 2: { + int (*fparam)(intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1]); + } + case 3: { + int (*fparam)(intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2]); + } + case 4: { + int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3]); + } + case 5: { + int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4]); + } + case 6: { + int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5]); + } + case 7: { + int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6]); + } + case 8: { + int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7]); + } + case 9: { + int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); + fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; + return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7], parm_value[8]); + } + } - cc_error("too many arguments in call to function"); - return -1; + cc_error("too many arguments in call to function"); + return -1; } diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h index a98f075f5f19..5318859002ed 100644 --- a/engines/ags/engine/script/script_runtime.h +++ b/engines/ags/engine/script/script_runtime.h @@ -72,13 +72,13 @@ extern bool ccAddExternalFunctionForPlugin(const String &name, void *pfn); extern void *ccGetSymbolAddressForPlugin(const String &name); // DEBUG HOOK -typedef void (*new_line_hook_type) (ccInstance *, int); +typedef void (*new_line_hook_type)(ccInstance *, int); extern void ccSetDebugHook(new_line_hook_type jibble); // Set the number of while loop iterations that aborts the script -extern void ccSetScriptAliveTimer (int); +extern void ccSetScriptAliveTimer(int); // reset the current while loop counter -extern void ccNotifyScriptStillAlive (); +extern void ccNotifyScriptStillAlive(); // for calling exported plugin functions old-style extern int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms); extern void nullfree(void *data); // in script/script_runtime diff --git a/engines/ags/engine/script/systemimports.cpp b/engines/ags/engine/script/systemimports.cpp index 980e191e43e5..67a06b78360f 100644 --- a/engines/ags/engine/script/systemimports.cpp +++ b/engines/ags/engine/script/systemimports.cpp @@ -30,115 +30,102 @@ extern void quit(const char *); SystemImports simp; SystemImports simp_for_plugin; -int SystemImports::add(const String &name, const RuntimeScriptValue &value, ccInstance *anotherscr) -{ - int ixof; - - if ((ixof = get_index_of(name)) >= 0) { - // Only allow override if not a script-exported function - if (anotherscr == nullptr) { - imports[ixof].Value = value; - imports[ixof].InstancePtr = anotherscr; - } - return 0; - } - - ixof = imports.size(); - for (size_t i = 0; i < imports.size(); ++i) - { - if (imports[i].Name == nullptr) - { - ixof = i; - break; - } - } - - btree[name] = ixof; - if (ixof == imports.size()) - imports.push_back(ScriptImport()); - imports[ixof].Name = name; // TODO: rather make a string copy here for safety reasons - imports[ixof].Value = value; - imports[ixof].InstancePtr = anotherscr; - return 0; +int SystemImports::add(const String &name, const RuntimeScriptValue &value, ccInstance *anotherscr) { + int ixof; + + if ((ixof = get_index_of(name)) >= 0) { + // Only allow override if not a script-exported function + if (anotherscr == nullptr) { + imports[ixof].Value = value; + imports[ixof].InstancePtr = anotherscr; + } + return 0; + } + + ixof = imports.size(); + for (size_t i = 0; i < imports.size(); ++i) { + if (imports[i].Name == nullptr) { + ixof = i; + break; + } + } + + btree[name] = ixof; + if (ixof == imports.size()) + imports.push_back(ScriptImport()); + imports[ixof].Name = name; // TODO: rather make a string copy here for safety reasons + imports[ixof].Value = value; + imports[ixof].InstancePtr = anotherscr; + return 0; } void SystemImports::remove(const String &name) { - int idx = get_index_of(name); - if (idx < 0) - return; - btree.erase(imports[idx].Name); - imports[idx].Name = nullptr; - imports[idx].Value.Invalidate(); - imports[idx].InstancePtr = nullptr; + int idx = get_index_of(name); + if (idx < 0) + return; + btree.erase(imports[idx].Name); + imports[idx].Name = nullptr; + imports[idx].Value.Invalidate(); + imports[idx].InstancePtr = nullptr; } -const ScriptImport *SystemImports::getByName(const String &name) -{ - int o = get_index_of(name); - if (o < 0) - return nullptr; +const ScriptImport *SystemImports::getByName(const String &name) { + int o = get_index_of(name); + if (o < 0) + return nullptr; - return &imports[o]; + return &imports[o]; } -const ScriptImport *SystemImports::getByIndex(int index) -{ - if ((size_t)index >= imports.size()) - return nullptr; +const ScriptImport *SystemImports::getByIndex(int index) { + if ((size_t)index >= imports.size()) + return nullptr; - return &imports[index]; + return &imports[index]; } -int SystemImports::get_index_of(const String &name) -{ - IndexMap::const_iterator it = btree.find(name); - if (it != btree.end()) - return it->second; - - // CHECKME: what are "mangled names" and where do they come from? - String mangled_name = String::FromFormat("%s$", name.GetCStr()); - // if it's a function with a mangled name, allow it - it = btree.lower_bound(mangled_name); - if (it != btree.end() && it->first.CompareLeft(mangled_name) == 0) - return it->second; - - if (name.GetLength() > 3) - { - size_t c = name.FindCharReverse('^'); - if (c != -1 && (c == name.GetLength() - 2 || c == name.GetLength() - 3)) - { - // Function with number of prametrs on the end - // attempt to find it without the param count - return get_index_of(name.Left(c)); - } - } - return -1; +int SystemImports::get_index_of(const String &name) { + IndexMap::const_iterator it = btree.find(name); + if (it != btree.end()) + return it->second; + + // CHECKME: what are "mangled names" and where do they come from? + String mangled_name = String::FromFormat("%s$", name.GetCStr()); + // if it's a function with a mangled name, allow it + it = btree.lower_bound(mangled_name); + if (it != btree.end() && it->first.CompareLeft(mangled_name) == 0) + return it->second; + + if (name.GetLength() > 3) { + size_t c = name.FindCharReverse('^'); + if (c != -1 && (c == name.GetLength() - 2 || c == name.GetLength() - 3)) { + // Function with number of prametrs on the end + // attempt to find it without the param count + return get_index_of(name.Left(c)); + } + } + return -1; } -void SystemImports::RemoveScriptExports(ccInstance *inst) -{ - if (!inst) - { - return; - } - - for (size_t i = 0; i < imports.size(); ++i) - { - if (imports[i].Name == nullptr) - continue; - - if (imports[i].InstancePtr == inst) - { - btree.erase(imports[i].Name); - imports[i].Name = nullptr; - imports[i].Value.Invalidate(); - imports[i].InstancePtr = nullptr; - } - } +void SystemImports::RemoveScriptExports(ccInstance *inst) { + if (!inst) { + return; + } + + for (size_t i = 0; i < imports.size(); ++i) { + if (imports[i].Name == nullptr) + continue; + + if (imports[i].InstancePtr == inst) { + btree.erase(imports[i].Name); + imports[i].Name = nullptr; + imports[i].Value.Invalidate(); + imports[i].InstancePtr = nullptr; + } + } } -void SystemImports::clear() -{ - btree.clear(); - imports.clear(); +void SystemImports::clear() { + btree.clear(); + imports.clear(); } diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index 99392bdadda5..ba715d7e4b5c 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -31,36 +31,33 @@ struct ICCStaticObject; using AGS::Common::String; -struct ScriptImport -{ - ScriptImport() - { - InstancePtr = nullptr; - } +struct ScriptImport { + ScriptImport() { + InstancePtr = nullptr; + } - String Name; // import's uid - RuntimeScriptValue Value; - ccInstance *InstancePtr; // script instance + String Name; // import's uid + RuntimeScriptValue Value; + ccInstance *InstancePtr; // script instance }; -struct SystemImports -{ +struct SystemImports { private: - // Note we can't use a hash-map here, because we sometimes need to search - // by partial keys. - typedef std::map IndexMap; + // Note we can't use a hash-map here, because we sometimes need to search + // by partial keys. + typedef std::map IndexMap; - std::vector imports; - IndexMap btree; + std::vector imports; + IndexMap btree; public: - int add(const String &name, const RuntimeScriptValue &value, ccInstance *inst); - void remove(const String &name); - const ScriptImport *getByName(const String &name); - int get_index_of(const String &name); - const ScriptImport *getByIndex(int index); - void RemoveScriptExports(ccInstance *inst); - void clear(); + int add(const String &name, const RuntimeScriptValue &value, ccInstance *inst); + void remove(const String &name); + const ScriptImport *getByName(const String &name); + int get_index_of(const String &name); + const ScriptImport *getByIndex(int index); + void RemoveScriptExports(ccInstance *inst); + void clear(); }; extern SystemImports simp; diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h index c5c6976977db..a818248bdbd3 100644 --- a/engines/ags/engine/util/library.h +++ b/engines/ags/engine/util/library.h @@ -26,25 +26,22 @@ #include "core/platform.h" #include "util/string.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class BaseLibrary -{ +class BaseLibrary { public: - BaseLibrary() = default; + BaseLibrary() = default; - virtual ~BaseLibrary() = default; + virtual ~BaseLibrary() = default; - virtual AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) = 0; + virtual AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) = 0; - virtual bool Load(AGS::Common::String libraryName) = 0; + virtual bool Load(AGS::Common::String libraryName) = 0; - virtual bool Unload() = 0; + virtual bool Unload() = 0; - virtual void *GetFunctionAddress(AGS::Common::String functionName) = 0; + virtual void *GetFunctionAddress(AGS::Common::String functionName) = 0; }; diff --git a/engines/ags/engine/util/library_dummy.h b/engines/ags/engine/util/library_dummy.h index 189f5c6110d8..c9ee518e455e 100644 --- a/engines/ags/engine/util/library_dummy.h +++ b/engines/ags/engine/util/library_dummy.h @@ -23,42 +23,33 @@ #ifndef AGS_ENGINE_UTIL_LIBRARY_DUMMY_H #define AGS_ENGINE_UTIL_LIBRARY_DUMMY_H -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class DummyLibrary : BaseLibrary -{ +class DummyLibrary : BaseLibrary { public: - DummyLibrary() - { - }; + DummyLibrary() { + }; - ~DummyLibrary() override - { - }; + ~DummyLibrary() override { + }; - AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override - { - return libraryName; - } + AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override { + return libraryName; + } - bool Load(AGS::Common::String libraryName) override - { - return false; - } + bool Load(AGS::Common::String libraryName) override { + return false; + } - bool Unload() override - { - return true; - } + bool Unload() override { + return true; + } - void *GetFunctionAddress(AGS::Common::String functionName) override - { - return NULL; - } + void *GetFunctionAddress(AGS::Common::String functionName) override { + return NULL; + } }; diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index 4cf166ed1816..a9eb85019550 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -36,116 +36,96 @@ extern AGS::Common::String appDirectory; #endif -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class PosixLibrary : BaseLibrary -{ +class PosixLibrary : BaseLibrary { public: - PosixLibrary() - : _library(nullptr) - { - }; - - ~PosixLibrary() override - { - Unload(); - }; - - AGS::Common::String BuildFilename(AGS::Common::String libraryName) - { - return String::FromFormat( + PosixLibrary() + : _library(nullptr) { + }; + + ~PosixLibrary() override { + Unload(); + }; + + AGS::Common::String BuildFilename(AGS::Common::String libraryName) { + return String::FromFormat( #if AGS_PLATFORM_OS_MACOS - "lib%s.dylib" + "lib%s.dylib" #else - "lib%s.so" + "lib%s.so" #endif - , libraryName.GetCStr()); - } - - AGS::Common::String BuildPath(const char *path, AGS::Common::String libraryName) - { - AGS::Common::String platformLibraryName = ""; - if (path) - { - platformLibraryName = path; - platformLibraryName.Append("/"); - } - platformLibraryName.Append(BuildFilename(libraryName)); - - AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); - return platformLibraryName; - } - - AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override - { - return BuildFilename(libraryName); - } - - bool Load(AGS::Common::String libraryName) override - { - Unload(); - - // Try rpath first - _library = dlopen(BuildPath(nullptr, libraryName).GetCStr(), RTLD_LAZY); - AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); - if (_library != nullptr) - { - return true; - } - - // Try current path - _library = dlopen(BuildPath(".", libraryName).GetCStr(), RTLD_LAZY); - - AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); - - if (_library == nullptr) - { - // Try the engine directory + , libraryName.GetCStr()); + } + + AGS::Common::String BuildPath(const char *path, AGS::Common::String libraryName) { + AGS::Common::String platformLibraryName = ""; + if (path) { + platformLibraryName = path; + platformLibraryName.Append("/"); + } + platformLibraryName.Append(BuildFilename(libraryName)); + + AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + return platformLibraryName; + } + + AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override { + return BuildFilename(libraryName); + } + + bool Load(AGS::Common::String libraryName) override { + Unload(); + + // Try rpath first + _library = dlopen(BuildPath(nullptr, libraryName).GetCStr(), RTLD_LAZY); + AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + if (_library != nullptr) { + return true; + } + + // Try current path + _library = dlopen(BuildPath(".", libraryName).GetCStr(), RTLD_LAZY); + + AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + + if (_library == nullptr) { + // Try the engine directory #if AGS_PLATFORM_OS_ANDROID - char buffer[200]; - sprintf(buffer, "%s%s", android_app_directory, "/lib"); - _library = dlopen(BuildPath(buffer, libraryName).GetCStr(), RTLD_LAZY); + char buffer[200]; + sprintf(buffer, "%s%s", android_app_directory, "/lib"); + _library = dlopen(BuildPath(buffer, libraryName).GetCStr(), RTLD_LAZY); #else - _library = dlopen(BuildPath(appDirectory, libraryName).GetCStr(), RTLD_LAZY); + _library = dlopen(BuildPath(appDirectory, libraryName).GetCStr(), RTLD_LAZY); #endif - AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); - } - - return (_library != nullptr); - } - - bool Unload() override - { - if (_library) - { - return (dlclose(_library) == 0); - } - else - { - return true; - } - } - - void *GetFunctionAddress(AGS::Common::String functionName) override - { - if (_library) - { - return dlsym(_library, functionName.GetCStr()); - } - else - { - return nullptr; - } - } + AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + } + + return (_library != nullptr); + } + + bool Unload() override { + if (_library) { + return (dlclose(_library) == 0); + } else { + return true; + } + } + + void *GetFunctionAddress(AGS::Common::String functionName) override { + if (_library) { + return dlsym(_library, functionName.GetCStr()); + } else { + return nullptr; + } + } private: - void *_library; + void *_library; }; diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h index 845f7b35f77a..8e5e064042dc 100644 --- a/engines/ags/engine/util/library_psp.h +++ b/engines/ags/engine/util/library_psp.h @@ -27,129 +27,100 @@ #include "util/string.h" #include "debug/out.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class PSPLibrary : BaseLibrary -{ +class PSPLibrary : BaseLibrary { public: - PSPLibrary() - : _library(-1) - { - }; - - virtual ~PSPLibrary() - { - Unload(); - }; - - AGS::Common::String BuildPath(char *path, AGS::Common::String libraryName) - { - AGS::Common::String platformLibraryName = path; - platformLibraryName.Append(libraryName); - platformLibraryName.Append(".prx"); - - AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); - - return platformLibraryName; - } - - bool Load(AGS::Common::String libraryName) - { - Unload(); - - // Try current path - _library = pspSdkLoadStartModule(BuildPath("./", libraryName).GetCStr(), PSP_MEMORY_PARTITION_USER); - - if (_library < 0) - { - // Try one directory higher, usually the AGS base directory - _library = pspSdkLoadStartModule(BuildPath("../", libraryName).GetCStr(), PSP_MEMORY_PARTITION_USER); - } - - // The PSP module and PSP library name are assumed to be the same as the file name - _moduleName = libraryName; - _moduleName.MakeLower(); - - AGS::Common::Debug::Printf("Result is %s %d", _moduleName.GetCStr(), _library); - - return (_library > -1); - } - - bool Unload() - { - if (_library > -1) - { - return (sceKernelUnloadModule(_library) > -1); - } - else - { - return true; - } - } - - void *GetFunctionAddress(AGS::Common::String functionName) - { - if (_library > -1) - { - // On the PSP functions are identified by an ID that is the first 4 byte of the SHA1 of the name. - int functionId; + PSPLibrary() + : _library(-1) { + }; + + virtual ~PSPLibrary() { + Unload(); + }; + + AGS::Common::String BuildPath(char *path, AGS::Common::String libraryName) { + AGS::Common::String platformLibraryName = path; + platformLibraryName.Append(libraryName); + platformLibraryName.Append(".prx"); + + AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + + return platformLibraryName; + } + + bool Load(AGS::Common::String libraryName) { + Unload(); + + // Try current path + _library = pspSdkLoadStartModule(BuildPath("./", libraryName).GetCStr(), PSP_MEMORY_PARTITION_USER); + + if (_library < 0) { + // Try one directory higher, usually the AGS base directory + _library = pspSdkLoadStartModule(BuildPath("../", libraryName).GetCStr(), PSP_MEMORY_PARTITION_USER); + } + + // The PSP module and PSP library name are assumed to be the same as the file name + _moduleName = libraryName; + _moduleName.MakeLower(); + + AGS::Common::Debug::Printf("Result is %s %d", _moduleName.GetCStr(), _library); + + return (_library > -1); + } + + bool Unload() { + if (_library > -1) { + return (sceKernelUnloadModule(_library) > -1); + } else { + return true; + } + } + + void *GetFunctionAddress(AGS::Common::String functionName) { + if (_library > -1) { + // On the PSP functions are identified by an ID that is the first 4 byte of the SHA1 of the name. + int functionId; #if 1 - // Hardcoded values for plugin loading. - if (functionName == "AGS_PluginV2") - { - functionId = 0x960C49BD; - } - else if (functionName == "AGS_EngineStartup") - { - functionId = 0x0F13D9E8; - } - else if (functionName == "AGS_EngineShutdown") - { - functionId = 0x2F131C76; - } - else if (functionName == "AGS_EngineOnEvent") - { - functionId = 0xE3DFFC5A; - } - else if (functionName == "AGS_EngineDebugHook") - { - functionId = 0xC37D6879; - } - else if (functionName == "AGS_EngineInitGfx") - { - functionId = 0xA428D254; - } - else - { - AGS::Common::Debug::Printf("Function ID not found: %s", functionName.GetCStr()); - functionId = -1; - } + // Hardcoded values for plugin loading. + if (functionName == "AGS_PluginV2") { + functionId = 0x960C49BD; + } else if (functionName == "AGS_EngineStartup") { + functionId = 0x0F13D9E8; + } else if (functionName == "AGS_EngineShutdown") { + functionId = 0x2F131C76; + } else if (functionName == "AGS_EngineOnEvent") { + functionId = 0xE3DFFC5A; + } else if (functionName == "AGS_EngineDebugHook") { + functionId = 0xC37D6879; + } else if (functionName == "AGS_EngineInitGfx") { + functionId = 0xA428D254; + } else { + AGS::Common::Debug::Printf("Function ID not found: %s", functionName.GetCStr()); + functionId = -1; + } #else - // This is a possible SHA1 implementation. - SceKernelUtilsSha1Context ctx; - uint8_t digest[20]; - sceKernelUtilsSha1BlockInit(&ctx); - sceKernelUtilsSha1BlockUpdate(&ctx, (uint8_t *)functionName.GetCStr(), functionName.GetLength()); - sceKernelUtilsSha1BlockResult(&ctx, digest); - - functionId = strtol(digest, NULL, 8); + // This is a possible SHA1 implementation. + SceKernelUtilsSha1Context ctx; + uint8_t digest[20]; + sceKernelUtilsSha1BlockInit(&ctx); + sceKernelUtilsSha1BlockUpdate(&ctx, (uint8_t *)functionName.GetCStr(), functionName.GetLength()); + sceKernelUtilsSha1BlockResult(&ctx, digest); + + functionId = strtol(digest, NULL, 8); #endif - return (void *)kernel_sctrlHENFindFunction((char *)_moduleName.GetCStr(), (char *)_moduleName.GetCStr(), functionId); - } - else - { - return NULL; - } - } + return (void *)kernel_sctrlHENFindFunction((char *)_moduleName.GetCStr(), (char *)_moduleName.GetCStr(), functionId); + } else { + return NULL; + } + } private: - SceUID _library; - AGS::Common::String _moduleName; + SceUID _library; + AGS::Common::String _moduleName; }; diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h index 27e804aafa55..f439f0382860 100644 --- a/engines/ags/engine/util/library_windows.h +++ b/engines/ags/engine/util/library_windows.h @@ -33,81 +33,67 @@ extern "C" { #endif - WINBASEAPI BOOL WINAPI FreeLibrary(HMODULE hLibModule); - WINBASEAPI FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName); - WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName); +WINBASEAPI BOOL WINAPI FreeLibrary(HMODULE hLibModule); +WINBASEAPI FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName); +WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName); #ifdef __cplusplus } // extern "C" #endif -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class WindowsLibrary : BaseLibrary -{ +class WindowsLibrary : BaseLibrary { public: - WindowsLibrary() - : _library(NULL) - { - }; - - virtual ~WindowsLibrary() - { - Unload(); - }; - - AGS::Common::String BuildFilename(AGS::Common::String libraryName) - { - return String::FromFormat("%s.dll", libraryName.GetCStr()); - } - - AGS::Common::String BuildPath(AGS::Common::String libraryName) - { - AGS::Common::String platformLibraryName = BuildFilename(libraryName); - - AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); - - return platformLibraryName; - } - - AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override - { - return BuildFilename(libraryName); - } - - bool Load(AGS::Common::String libraryName) - { - Unload(); - - _library = LoadLibraryA(BuildPath(libraryName).GetCStr()); - - return (_library != NULL); - } - - bool Unload() - { - if (_library) - { - return (FreeLibrary(_library) != 0); - } - else - { - return true; - } - } - - void *GetFunctionAddress(AGS::Common::String functionName) - { - return GetProcAddress(_library, functionName.GetCStr()); - } + WindowsLibrary() + : _library(NULL) { + }; + + virtual ~WindowsLibrary() { + Unload(); + }; + + AGS::Common::String BuildFilename(AGS::Common::String libraryName) { + return String::FromFormat("%s.dll", libraryName.GetCStr()); + } + + AGS::Common::String BuildPath(AGS::Common::String libraryName) { + AGS::Common::String platformLibraryName = BuildFilename(libraryName); + + AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + + return platformLibraryName; + } + + AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override { + return BuildFilename(libraryName); + } + + bool Load(AGS::Common::String libraryName) { + Unload(); + + _library = LoadLibraryA(BuildPath(libraryName).GetCStr()); + + return (_library != NULL); + } + + bool Unload() { + if (_library) { + return (FreeLibrary(_library) != 0); + } else { + return true; + } + } + + void *GetFunctionAddress(AGS::Common::String functionName) { + return GetProcAddress(_library, functionName.GetCStr()); + } private: - HANDLE _library; + HANDLE _library; }; diff --git a/engines/ags/engine/util/mutex.h b/engines/ags/engine/util/mutex.h index 7919a1c44269..ea398db9be97 100644 --- a/engines/ags/engine/util/mutex.h +++ b/engines/ags/engine/util/mutex.h @@ -23,25 +23,22 @@ #ifndef AGS_ENGINE_UTIL_MUTEX_H #define AGS_ENGINE_UTIL_MUTEX_H -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class BaseMutex -{ +class BaseMutex { public: - BaseMutex() = default; + BaseMutex() = default; - virtual ~BaseMutex() = default; + virtual ~BaseMutex() = default; - BaseMutex &operator=(const BaseMutex &) = delete; - BaseMutex(const BaseMutex &) = delete; + BaseMutex &operator=(const BaseMutex &) = delete; + BaseMutex(const BaseMutex &) = delete; - virtual void Lock() = 0; + virtual void Lock() = 0; - virtual void Unlock() = 0; + virtual void Unlock() = 0; }; @@ -50,7 +47,7 @@ class BaseMutex #if 0 - // insert platforms here +// insert platforms here #else #include "mutex_std.h" #endif diff --git a/engines/ags/engine/util/mutex_base.h b/engines/ags/engine/util/mutex_base.h index e4d63f48e5ad..5a0debc9e783 100644 --- a/engines/ags/engine/util/mutex_base.h +++ b/engines/ags/engine/util/mutex_base.h @@ -23,19 +23,16 @@ #ifndef AGS_ENGINE_UTIL_MUTEX_BASE_H #define AGS_ENGINE_UTIL_MUTEX_BASE_H -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class BaseMutex -{ +class BaseMutex { public: - BaseMutex() = 0; - virtual ~BaseMutex() = 0; - virtual void Lock() = 0; - virtual void Unlock() = 0; + BaseMutex() = 0; + virtual ~BaseMutex() = 0; + virtual void Lock() = 0; + virtual void Unlock() = 0; }; diff --git a/engines/ags/engine/util/mutex_lock.h b/engines/ags/engine/util/mutex_lock.h index a6d5873991b8..6a4524499b31 100644 --- a/engines/ags/engine/util/mutex_lock.h +++ b/engines/ags/engine/util/mutex_lock.h @@ -25,44 +25,36 @@ #include "util/mutex.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class MutexLock -{ +class MutexLock { private: BaseMutex *_m; MutexLock(MutexLock const &); // non-copyable - MutexLock& operator=(MutexLock const &); // not copy-assignable + MutexLock &operator=(MutexLock const &); // not copy-assignable public: - void Release() - { + void Release() { if (_m != nullptr) _m->Unlock(); _m = nullptr; } - void Acquire(BaseMutex &mutex) - { + void Acquire(BaseMutex &mutex) { Release(); _m = &mutex; _m->Lock(); } - MutexLock() : _m(nullptr) - { + MutexLock() : _m(nullptr) { } - explicit MutexLock(BaseMutex &mutex) : _m(nullptr) - { + explicit MutexLock(BaseMutex &mutex) : _m(nullptr) { Acquire(mutex); } - ~MutexLock() - { + ~MutexLock() { Release(); } }; // class MutexLock diff --git a/engines/ags/engine/util/mutex_psp.h b/engines/ags/engine/util/mutex_psp.h index 8e40697e8be7..83511ee9c368 100644 --- a/engines/ags/engine/util/mutex_psp.h +++ b/engines/ags/engine/util/mutex_psp.h @@ -27,37 +27,30 @@ #include #include -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class PSPMutex : public BaseMutex -{ +class PSPMutex : public BaseMutex { public: - PSPMutex() - { - _mutex = sceKernelCreateSema("", 0, 1, 1, 0); - } + PSPMutex() { + _mutex = sceKernelCreateSema("", 0, 1, 1, 0); + } - ~PSPMutex() - { - sceKernelDeleteSema(_mutex); - } + ~PSPMutex() { + sceKernelDeleteSema(_mutex); + } - inline void Lock() - { - sceKernelWaitSema(_mutex, 1, 0); - } + inline void Lock() { + sceKernelWaitSema(_mutex, 1, 0); + } - inline void Unlock() - { - sceKernelSignalSema(_mutex, 1); - } + inline void Unlock() { + sceKernelSignalSema(_mutex, 1); + } private: - SceUID _mutex; + SceUID _mutex; }; diff --git a/engines/ags/engine/util/mutex_pthread.h b/engines/ags/engine/util/mutex_pthread.h index 9716e3f7fdbe..ae81f9e67138 100644 --- a/engines/ags/engine/util/mutex_pthread.h +++ b/engines/ags/engine/util/mutex_pthread.h @@ -25,37 +25,30 @@ #include -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class PThreadMutex : public BaseMutex -{ +class PThreadMutex : public BaseMutex { public: - inline PThreadMutex() - { - pthread_mutex_init(&_mutex, NULL); - } + inline PThreadMutex() { + pthread_mutex_init(&_mutex, NULL); + } - inline ~PThreadMutex() - { - pthread_mutex_destroy(&_mutex); - } + inline ~PThreadMutex() { + pthread_mutex_destroy(&_mutex); + } - inline void Lock() - { - pthread_mutex_lock(&_mutex); - } + inline void Lock() { + pthread_mutex_lock(&_mutex); + } - inline void Unlock() - { - pthread_mutex_unlock(&_mutex); - } + inline void Unlock() { + pthread_mutex_unlock(&_mutex); + } private: - pthread_mutex_t _mutex; + pthread_mutex_t _mutex; }; typedef PThreadMutex Mutex; diff --git a/engines/ags/engine/util/mutex_std.h b/engines/ags/engine/util/mutex_std.h index 28ad2f44ff5c..0565db6579f3 100644 --- a/engines/ags/engine/util/mutex_std.h +++ b/engines/ags/engine/util/mutex_std.h @@ -25,25 +25,26 @@ #include -namespace AGS -{ -namespace Engine -{ - -class StdMutex : public BaseMutex -{ - public: - inline StdMutex() : mutex_() {} - inline ~StdMutex() override = default; - - StdMutex &operator=(const StdMutex &) = delete; - StdMutex(const StdMutex &) = delete; - - inline void Lock() override { mutex_.lock(); } - inline void Unlock() override { mutex_.unlock(); } - - private: - std::recursive_mutex mutex_; +namespace AGS { +namespace Engine { + +class StdMutex : public BaseMutex { +public: + inline StdMutex() : mutex_() {} + inline ~StdMutex() override = default; + + StdMutex &operator=(const StdMutex &) = delete; + StdMutex(const StdMutex &) = delete; + + inline void Lock() override { + mutex_.lock(); + } + inline void Unlock() override { + mutex_.unlock(); + } + +private: + std::recursive_mutex mutex_; }; typedef StdMutex Mutex; diff --git a/engines/ags/engine/util/mutex_wii.h b/engines/ags/engine/util/mutex_wii.h index fbc635993dcb..45b935e8a23e 100644 --- a/engines/ags/engine/util/mutex_wii.h +++ b/engines/ags/engine/util/mutex_wii.h @@ -25,37 +25,30 @@ #include -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class WiiMutex : public BaseMutex -{ +class WiiMutex : public BaseMutex { public: - inline WiiMutex() - { - LWP_MutexInit(&_mutex, 0); - } + inline WiiMutex() { + LWP_MutexInit(&_mutex, 0); + } - inline ~WiiMutex() - { - LWP_MutexDestroy(_mutex); - } + inline ~WiiMutex() { + LWP_MutexDestroy(_mutex); + } - inline void Lock() - { - LWP_MutexLock(_mutex); - } + inline void Lock() { + LWP_MutexLock(_mutex); + } - inline void Unlock() - { - LWP_MutexUnlock(_mutex); - } + inline void Unlock() { + LWP_MutexUnlock(_mutex); + } private: - mutex_t _mutex; + mutex_t _mutex; }; diff --git a/engines/ags/engine/util/mutex_windows.h b/engines/ags/engine/util/mutex_windows.h index 4f4748451cac..0e27e000bd61 100644 --- a/engines/ags/engine/util/mutex_windows.h +++ b/engines/ags/engine/util/mutex_windows.h @@ -23,45 +23,38 @@ #ifndef AGS_ENGINE_UTIL_MUTEXT_WINDOWS_H #define AGS_ENGINE_UTIL_MUTEXT_WINDOWS_H -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class WindowsMutex : public BaseMutex -{ +class WindowsMutex : public BaseMutex { public: - WindowsMutex() - { - _mutex = CreateMutex(NULL, FALSE, NULL); + WindowsMutex() { + _mutex = CreateMutex(NULL, FALSE, NULL); - _ASSERT(_mutex != NULL); - } + _ASSERT(_mutex != NULL); + } - ~WindowsMutex() - { - _ASSERT(_mutex != NULL); + ~WindowsMutex() { + _ASSERT(_mutex != NULL); - CloseHandle(_mutex); - } + CloseHandle(_mutex); + } - inline void Lock() - { - _ASSERT(_mutex != NULL); + inline void Lock() { + _ASSERT(_mutex != NULL); - WaitForSingleObject(_mutex, INFINITE); - } + WaitForSingleObject(_mutex, INFINITE); + } - inline void Unlock() - { - _ASSERT(_mutex != NULL); + inline void Unlock() { + _ASSERT(_mutex != NULL); - ReleaseMutex(_mutex); - } + ReleaseMutex(_mutex); + } private: - HANDLE _mutex; + HANDLE _mutex; }; diff --git a/engines/ags/engine/util/scaling.h b/engines/ags/engine/util/scaling.h index d8c2b1e6cd81..98881e7b6853 100644 --- a/engines/ags/engine/util/scaling.h +++ b/engines/ags/engine/util/scaling.h @@ -35,147 +35,123 @@ #include "core/types.h" #include "util/geometry.h" -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class AxisScaling -{ +class AxisScaling { public: - AxisScaling() - : _scale(kUnit) - , _unscale(kUnit) - , _srcOffset(0) - , _dstOffset(0) - { - } - - bool IsIdentity() const - { - return _scale == kUnit && _srcOffset == 0 && _dstOffset == 0; - } - - bool IsTranslateOnly() const - { - return _scale == kUnit; - } - - void Init(const int32_t src_length, const int32_t dst_length, const int32_t src_offset = 0, const int32_t dst_offset = 0) - { - _scale = kUnit; - _unscale = kUnit; - _srcOffset = src_offset; - _dstOffset = dst_offset; - - if (src_length != 0) - { - int32_t scale = (dst_length << kShift) / src_length; - if (scale != 0) - { - _scale = scale; - _unscale = scale; - int32_t scaled_val = ScaleDistance(src_length); - if (scaled_val < dst_length) - _scale++; - } - } - } - - void SetSrcOffset(int32_t x) - { - _srcOffset = x; - } - - void SetDstOffset(int32_t x) - { - _dstOffset = x; - } - - inline int32_t GetSrcOffset() const { return _srcOffset; } - - inline int32_t ScalePt(int32_t x) const - { - return (((x - _srcOffset) * _scale) >> kShift) + _dstOffset; - } - inline int32_t ScaleDistance(int32_t x) const - { - return ((x * _scale) >> kShift); - } - inline int32_t UnScalePt(int32_t x) const - { - return ((x - _dstOffset) << kShift) / _unscale + _srcOffset; - } - inline int32_t UnScaleDistance(int32_t x) const - { - return (x << kShift) / _unscale; - } + AxisScaling() + : _scale(kUnit) + , _unscale(kUnit) + , _srcOffset(0) + , _dstOffset(0) { + } + + bool IsIdentity() const { + return _scale == kUnit && _srcOffset == 0 && _dstOffset == 0; + } + + bool IsTranslateOnly() const { + return _scale == kUnit; + } + + void Init(const int32_t src_length, const int32_t dst_length, const int32_t src_offset = 0, const int32_t dst_offset = 0) { + _scale = kUnit; + _unscale = kUnit; + _srcOffset = src_offset; + _dstOffset = dst_offset; + + if (src_length != 0) { + int32_t scale = (dst_length << kShift) / src_length; + if (scale != 0) { + _scale = scale; + _unscale = scale; + int32_t scaled_val = ScaleDistance(src_length); + if (scaled_val < dst_length) + _scale++; + } + } + } + + void SetSrcOffset(int32_t x) { + _srcOffset = x; + } + + void SetDstOffset(int32_t x) { + _dstOffset = x; + } + + inline int32_t GetSrcOffset() const { + return _srcOffset; + } + + inline int32_t ScalePt(int32_t x) const { + return (((x - _srcOffset) * _scale) >> kShift) + _dstOffset; + } + inline int32_t ScaleDistance(int32_t x) const { + return ((x * _scale) >> kShift); + } + inline int32_t UnScalePt(int32_t x) const { + return ((x - _dstOffset) << kShift) / _unscale + _srcOffset; + } + inline int32_t UnScaleDistance(int32_t x) const { + return (x << kShift) / _unscale; + } private: - int32_t _scale; - int32_t _unscale; - int32_t _srcOffset; - int32_t _dstOffset; + int32_t _scale; + int32_t _unscale; + int32_t _srcOffset; + int32_t _dstOffset; }; -struct PlaneScaling -{ - AxisScaling X; - AxisScaling Y; - - bool IsIdentity() const - { - return X.IsIdentity() && Y.IsIdentity(); - } - - bool IsTranslateOnly() const - { - return X.IsTranslateOnly() && Y.IsTranslateOnly(); - } - - void Init(const Size &src_size, const Rect &dst_rect) - { - X.Init(src_size.Width, dst_rect.GetWidth(), 0, dst_rect.Left); - Y.Init(src_size.Height, dst_rect.GetHeight(), 0, dst_rect.Top); - } - - void Init(const Rect &src_rect, const Rect &dst_rect) - { - X.Init(src_rect.GetWidth(), dst_rect.GetWidth(), src_rect.Left, dst_rect.Left); - Y.Init(src_rect.GetHeight(), dst_rect.GetHeight(), src_rect.Top, dst_rect.Top); - } - - void SetSrcOffsets(int x, int y) - { - X.SetSrcOffset(x); - Y.SetSrcOffset(y); - } - - void SetDestOffsets(int x, int y) - { - X.SetDstOffset(x); - Y.SetDstOffset(y); - } - - inline Point Scale(const Point p) const - { - return Point(X.ScalePt(p.X), Y.ScalePt(p.Y)); - } - - inline Rect ScaleRange(const Rect r) const - { - return RectWH(X.ScalePt(r.Left), Y.ScalePt(r.Top), X.ScaleDistance(r.GetWidth()), Y.ScaleDistance(r.GetHeight())); - } - - inline Point UnScale(const Point p) const - { - return Point(X.UnScalePt(p.X), Y.UnScalePt(p.Y)); - } - - inline Rect UnScaleRange(const Rect r) const - { - return RectWH(X.UnScalePt(r.Left), Y.UnScalePt(r.Top), X.UnScaleDistance(r.GetWidth()), Y.UnScaleDistance(r.GetHeight())); - } +struct PlaneScaling { + AxisScaling X; + AxisScaling Y; + + bool IsIdentity() const { + return X.IsIdentity() && Y.IsIdentity(); + } + + bool IsTranslateOnly() const { + return X.IsTranslateOnly() && Y.IsTranslateOnly(); + } + + void Init(const Size &src_size, const Rect &dst_rect) { + X.Init(src_size.Width, dst_rect.GetWidth(), 0, dst_rect.Left); + Y.Init(src_size.Height, dst_rect.GetHeight(), 0, dst_rect.Top); + } + + void Init(const Rect &src_rect, const Rect &dst_rect) { + X.Init(src_rect.GetWidth(), dst_rect.GetWidth(), src_rect.Left, dst_rect.Left); + Y.Init(src_rect.GetHeight(), dst_rect.GetHeight(), src_rect.Top, dst_rect.Top); + } + + void SetSrcOffsets(int x, int y) { + X.SetSrcOffset(x); + Y.SetSrcOffset(y); + } + + void SetDestOffsets(int x, int y) { + X.SetDstOffset(x); + Y.SetDstOffset(y); + } + + inline Point Scale(const Point p) const { + return Point(X.ScalePt(p.X), Y.ScalePt(p.Y)); + } + + inline Rect ScaleRange(const Rect r) const { + return RectWH(X.ScalePt(r.Left), Y.ScalePt(r.Top), X.ScaleDistance(r.GetWidth()), Y.ScaleDistance(r.GetHeight())); + } + + inline Point UnScale(const Point p) const { + return Point(X.UnScalePt(p.X), Y.UnScalePt(p.Y)); + } + + inline Rect UnScaleRange(const Rect r) const { + return RectWH(X.UnScalePt(r.Left), Y.UnScalePt(r.Top), X.UnScaleDistance(r.GetWidth()), Y.UnScaleDistance(r.GetHeight())); + } }; } // namespace Engine diff --git a/engines/ags/engine/util/thread.h b/engines/ags/engine/util/thread.h index 00625915a660..482d3de9857b 100644 --- a/engines/ags/engine/util/thread.h +++ b/engines/ags/engine/util/thread.h @@ -23,39 +23,37 @@ #ifndef AGS_ENGINE_UTIL_THREAD_H #define AGS_ENGINE_UTIL_THREAD_H -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class BaseThread -{ +class BaseThread { public: - typedef void(* AGSThreadEntry)(); + typedef void(* AGSThreadEntry)(); - BaseThread() = default; - virtual ~BaseThread() = default; + BaseThread() = default; + virtual ~BaseThread() = default; - BaseThread &operator=(const BaseThread &) = delete; - BaseThread(const BaseThread &) = delete; + BaseThread &operator=(const BaseThread &) = delete; + BaseThread(const BaseThread &) = delete; - virtual bool Create(AGSThreadEntry entryPoint, bool looping) = 0; - virtual bool Start() = 0; - virtual bool Stop() = 0; + virtual bool Create(AGSThreadEntry entryPoint, bool looping) = 0; + virtual bool Start() = 0; + virtual bool Stop() = 0; - inline bool CreateAndStart(AGSThreadEntry entryPoint, bool looping) - { - if (!Create(entryPoint, looping)) { return false; } - return Start(); - } + inline bool CreateAndStart(AGSThreadEntry entryPoint, bool looping) { + if (!Create(entryPoint, looping)) { + return false; + } + return Start(); + } }; } // namespace Engine } // namespace AGS #if 0 - // insert platforms here +// insert platforms here #else #include "thread_std.h" #endif diff --git a/engines/ags/engine/util/thread_psp.h b/engines/ags/engine/util/thread_psp.h index 10d7d059ed5e..eab3e5df018b 100644 --- a/engines/ags/engine/util/thread_psp.h +++ b/engines/ags/engine/util/thread_psp.h @@ -27,90 +27,72 @@ #include #include -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class PSPThread : public BaseThread -{ +class PSPThread : public BaseThread { public: - PSPThread() - { - _thread = -1; - _entry = NULL; - _running = false; - _looping = false; - } - - ~PSPThread() - { - Stop(); - } - - inline bool Create(AGSThreadEntry entryPoint, bool looping) - { - _looping = looping; - _entry = entryPoint; - _thread = sceKernelCreateThread("ags", _thread_start, 0x20, 0x10000, THREAD_ATTR_USER, 0); - - return (_thread > -1); - } - - inline bool Start() - { - if ((_thread > -1) && (!_running)) - { - PSPThread* thisPointer = this; - SceUID result = sceKernelStartThread(_thread, sizeof(this), &thisPointer); - - _running = (result > -1); - return _running; - } - else - { - return false; - } - } - - bool Stop() - { - if ((_thread > -1) && (_running)) - { - if (_looping) - { - _looping = false; - sceKernelWaitThreadEnd(_thread, 0); - } - - _running = false; - return (sceKernelTerminateDeleteThread(_thread) > -1); - } - else - { - return false; - } - } + PSPThread() { + _thread = -1; + _entry = NULL; + _running = false; + _looping = false; + } + + ~PSPThread() { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) { + _looping = looping; + _entry = entryPoint; + _thread = sceKernelCreateThread("ags", _thread_start, 0x20, 0x10000, THREAD_ATTR_USER, 0); + + return (_thread > -1); + } + + inline bool Start() { + if ((_thread > -1) && (!_running)) { + PSPThread *thisPointer = this; + SceUID result = sceKernelStartThread(_thread, sizeof(this), &thisPointer); + + _running = (result > -1); + return _running; + } else { + return false; + } + } + + bool Stop() { + if ((_thread > -1) && (_running)) { + if (_looping) { + _looping = false; + sceKernelWaitThreadEnd(_thread, 0); + } + + _running = false; + return (sceKernelTerminateDeleteThread(_thread) > -1); + } else { + return false; + } + } private: - SceUID _thread; - bool _running; - bool _looping; - - AGSThreadEntry _entry; - - static int _thread_start(SceSize args, void *argp) - { - AGSThreadEntry entry = (*(PSPThread **)argp)->_entry; - bool *looping = &(*(PSPThread **)argp)->_looping; - - do - { - entry(); - } - while (*looping); - } + SceUID _thread; + bool _running; + bool _looping; + + AGSThreadEntry _entry; + + static int _thread_start(SceSize args, void *argp) { + AGSThreadEntry entry = (*(PSPThread **)argp)->_entry; + bool *looping = &(*(PSPThread **)argp)->_looping; + + do { + entry(); + } while (*looping); + } }; diff --git a/engines/ags/engine/util/thread_pthread.h b/engines/ags/engine/util/thread_pthread.h index 5a8ecc6a8708..89e9180f8cba 100644 --- a/engines/ags/engine/util/thread_pthread.h +++ b/engines/ags/engine/util/thread_pthread.h @@ -25,91 +25,73 @@ #include -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class PThreadThread : public BaseThread -{ +class PThreadThread : public BaseThread { public: - PThreadThread() - { - _thread = 0; - _entry = NULL; - _running = false; - _looping = false; - } - - ~PThreadThread() - { - Stop(); - } - - inline bool Create(AGSThreadEntry entryPoint, bool looping) - { - _looping = looping; - _entry = entryPoint; - - // Thread creation is delayed till the thread is started - return true; - } - - inline bool Start() - { - if (!_running) - { - _running = (pthread_create(&_thread, NULL, _thread_start, this) == 0); - - return _running; - } - else - { - return false; - } - } - - bool Stop() - { - if (_running) - { - if (_looping) - { - _looping = false; - } - - pthread_join(_thread, NULL); - - _running = false; - return true; - } - else - { - return false; - } - } + PThreadThread() { + _thread = 0; + _entry = NULL; + _running = false; + _looping = false; + } + + ~PThreadThread() { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) { + _looping = looping; + _entry = entryPoint; + + // Thread creation is delayed till the thread is started + return true; + } + + inline bool Start() { + if (!_running) { + _running = (pthread_create(&_thread, NULL, _thread_start, this) == 0); + + return _running; + } else { + return false; + } + } + + bool Stop() { + if (_running) { + if (_looping) { + _looping = false; + } + + pthread_join(_thread, NULL); + + _running = false; + return true; + } else { + return false; + } + } private: - pthread_t _thread; - bool _running; - bool _looping; + pthread_t _thread; + bool _running; + bool _looping; - AGSThreadEntry _entry; + AGSThreadEntry _entry; - static void *_thread_start(void *arg) - { - AGSThreadEntry entry = ((PThreadThread *)arg)->_entry; - bool *looping = &((PThreadThread *)arg)->_looping; + static void *_thread_start(void *arg) { + AGSThreadEntry entry = ((PThreadThread *)arg)->_entry; + bool *looping = &((PThreadThread *)arg)->_looping; - do - { - entry(); - } - while (*looping); + do { + entry(); + } while (*looping); - return NULL; - } + return NULL; + } }; diff --git a/engines/ags/engine/util/thread_std.h b/engines/ags/engine/util/thread_std.h index 8bb4501ef32c..24b870b28b54 100644 --- a/engines/ags/engine/util/thread_std.h +++ b/engines/ags/engine/util/thread_std.h @@ -26,75 +26,72 @@ #include #include -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class StdThread : public BaseThread -{ +class StdThread : public BaseThread { public: - StdThread() : thread_(), entry_(nullptr), looping_(false) - { - } - - ~StdThread() override - { - Stop(); - } - - StdThread &operator=(const StdThread &) = delete; - StdThread(const StdThread &) = delete; - - bool Create(AGSThreadEntry entryPoint, bool looping) override - { - if (!entryPoint) { return false; } - - entry_ = entryPoint; - looping_ = looping; - return true; - } - - bool Start() override - { - if (thread_.joinable()) { return true; } - if (!entry_) { return false; } - - try { - thread_ = std::thread(thread_start_, this); - } catch (std::system_error) { - return false; - } - return thread_.joinable(); - } - - bool Stop() override - { - if (!thread_.joinable()) { return true; } - - looping_ = false; // signal thread to stop - thread_.join(); - return true; - } + StdThread() : thread_(), entry_(nullptr), looping_(false) { + } + + ~StdThread() override { + Stop(); + } + + StdThread &operator=(const StdThread &) = delete; + StdThread(const StdThread &) = delete; + + bool Create(AGSThreadEntry entryPoint, bool looping) override { + if (!entryPoint) { + return false; + } + + entry_ = entryPoint; + looping_ = looping; + return true; + } + + bool Start() override { + if (thread_.joinable()) { + return true; + } + if (!entry_) { + return false; + } + + try { + thread_ = std::thread(thread_start_, this); + } catch (std::system_error) { + return false; + } + return thread_.joinable(); + } + + bool Stop() override { + if (!thread_.joinable()) { + return true; + } + + looping_ = false; // signal thread to stop + thread_.join(); + return true; + } private: - std::thread thread_; - AGSThreadEntry entry_; - bool looping_; - - static void thread_start_(StdThread *self) - { - auto entry = self->entry_; - for (;;) - { - entry(); - if (!self->looping_) - { - break; - } - std::this_thread::yield(); - } - } + std::thread thread_; + AGSThreadEntry entry_; + bool looping_; + + static void thread_start_(StdThread *self) { + auto entry = self->entry_; + for (;;) { + entry(); + if (!self->looping_) { + break; + } + std::this_thread::yield(); + } + } }; typedef StdThread Thread; diff --git a/engines/ags/engine/util/thread_wii.h b/engines/ags/engine/util/thread_wii.h index 134ded3f9f6b..91a67ef8a42c 100644 --- a/engines/ags/engine/util/thread_wii.h +++ b/engines/ags/engine/util/thread_wii.h @@ -25,91 +25,73 @@ #include -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class WiiThread : public BaseThread -{ +class WiiThread : public BaseThread { public: - WiiThread() - { - _thread = (lwp_t)NULL; - _entry = NULL; - _running = false; - _looping = false; - } - - ~WiiThread() - { - Stop(); - } - - inline bool Create(AGSThreadEntry entryPoint, bool looping) - { - _looping = looping; - _entry = entryPoint; - - // Thread creation is delayed till the thread is started - return true; - } - - inline bool Start() - { - if (!_running) - { - _running = (LWP_CreateThread(&_thread, _thread_start, this, 0, 8 * 1024, 64) != 0); - - return _running; - } - else - { - return false; - } - } - - bool Stop() - { - if (_running) - { - if (_looping) - { - _looping = false; - } - - LWP_JoinThread(_thread, NULL); - - _running = false; - return true; - } - else - { - return false; - } - } + WiiThread() { + _thread = (lwp_t)NULL; + _entry = NULL; + _running = false; + _looping = false; + } + + ~WiiThread() { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) { + _looping = looping; + _entry = entryPoint; + + // Thread creation is delayed till the thread is started + return true; + } + + inline bool Start() { + if (!_running) { + _running = (LWP_CreateThread(&_thread, _thread_start, this, 0, 8 * 1024, 64) != 0); + + return _running; + } else { + return false; + } + } + + bool Stop() { + if (_running) { + if (_looping) { + _looping = false; + } + + LWP_JoinThread(_thread, NULL); + + _running = false; + return true; + } else { + return false; + } + } private: - lwp_t _thread; - bool _running; - bool _looping; + lwp_t _thread; + bool _running; + bool _looping; - AGSThreadEntry _entry; + AGSThreadEntry _entry; - static void *_thread_start(void *arg) - { - AGSThreadEntry entry = ((WiiThread *)arg)->_entry; - bool *looping = &((WiiThread *)arg)->_looping; + static void *_thread_start(void *arg) { + AGSThreadEntry entry = ((WiiThread *)arg)->_entry; + bool *looping = &((WiiThread *)arg)->_looping; - do - { - entry(); - } - while (*looping); + do { + entry(); + } while (*looping); - return NULL; - } + return NULL; + } }; diff --git a/engines/ags/engine/util/thread_windows.h b/engines/ags/engine/util/thread_windows.h index a27c4018ad44..e55b243aa351 100644 --- a/engines/ags/engine/util/thread_windows.h +++ b/engines/ags/engine/util/thread_windows.h @@ -23,94 +23,76 @@ #ifndef AGS_ENGINE_UTIL_THREAD_WINDOWS_H #define AGS_ENGINE_UTIL_THREAD_WINDOWS_H -namespace AGS -{ -namespace Engine -{ +namespace AGS { +namespace Engine { -class WindowsThread : public BaseThread -{ +class WindowsThread : public BaseThread { public: - WindowsThread() - { - _thread = NULL; - _entry = NULL; - _running = false; - _looping = false; - } - - ~WindowsThread() - { - Stop(); - } - - inline bool Create(AGSThreadEntry entryPoint, bool looping) - { - _looping = looping; - _entry = entryPoint; - _thread = CreateThread(NULL, 0, _thread_start, this, CREATE_SUSPENDED, NULL); - - return (_thread != NULL); - } - - inline bool Start() - { - if ((_thread != NULL) && (!_running)) - { - DWORD result = ResumeThread(_thread); - - _running = (result != (DWORD) - 1); - return _running; - } - else - { - return false; - } - } - - bool Stop() - { - if ((_thread != NULL) && (_running)) - { - if (_looping) - { - _looping = false; - WaitForSingleObject(_thread, INFINITE); - } - - CloseHandle(_thread); - - _running = false; - _thread = NULL; - return true; - } - else - { - return false; - } - } + WindowsThread() { + _thread = NULL; + _entry = NULL; + _running = false; + _looping = false; + } + + ~WindowsThread() { + Stop(); + } + + inline bool Create(AGSThreadEntry entryPoint, bool looping) { + _looping = looping; + _entry = entryPoint; + _thread = CreateThread(NULL, 0, _thread_start, this, CREATE_SUSPENDED, NULL); + + return (_thread != NULL); + } + + inline bool Start() { + if ((_thread != NULL) && (!_running)) { + DWORD result = ResumeThread(_thread); + + _running = (result != (DWORD) - 1); + return _running; + } else { + return false; + } + } + + bool Stop() { + if ((_thread != NULL) && (_running)) { + if (_looping) { + _looping = false; + WaitForSingleObject(_thread, INFINITE); + } + + CloseHandle(_thread); + + _running = false; + _thread = NULL; + return true; + } else { + return false; + } + } private: - HANDLE _thread; - bool _running; - bool _looping; + HANDLE _thread; + bool _running; + bool _looping; - AGSThreadEntry _entry; + AGSThreadEntry _entry; - static DWORD __stdcall _thread_start(LPVOID lpParam) - { - AGSThreadEntry entry = ((WindowsThread *)lpParam)->_entry; - bool *looping = &((WindowsThread *)lpParam)->_looping; + static DWORD __stdcall _thread_start(LPVOID lpParam) { + AGSThreadEntry entry = ((WindowsThread *)lpParam)->_entry; + bool *looping = &((WindowsThread *)lpParam)->_looping; - do - { - entry(); - } - while (*looping); + do { + entry(); + } while (*looping); - return 0; - } + return 0; + } }; diff --git a/engines/ags/shared/ac/audiocliptype.cpp b/engines/ags/shared/ac/audiocliptype.cpp index 935b3b5e8c30..d33ccfad84b5 100644 --- a/engines/ags/shared/ac/audiocliptype.cpp +++ b/engines/ags/shared/ac/audiocliptype.cpp @@ -25,32 +25,28 @@ using AGS::Common::Stream; -void AudioClipType::ReadFromFile(Stream *in) -{ - id = in->ReadInt32(); - reservedChannels = in->ReadInt32(); - volume_reduction_while_speech_playing = in->ReadInt32(); - crossfadeSpeed = in->ReadInt32(); - reservedForFuture = in->ReadInt32(); +void AudioClipType::ReadFromFile(Stream *in) { + id = in->ReadInt32(); + reservedChannels = in->ReadInt32(); + volume_reduction_while_speech_playing = in->ReadInt32(); + crossfadeSpeed = in->ReadInt32(); + reservedForFuture = in->ReadInt32(); } -void AudioClipType::WriteToFile(Stream *out) -{ - out->WriteInt32(id); - out->WriteInt32(reservedChannels); - out->WriteInt32(volume_reduction_while_speech_playing); - out->WriteInt32(crossfadeSpeed); - out->WriteInt32(reservedForFuture); +void AudioClipType::WriteToFile(Stream *out) { + out->WriteInt32(id); + out->WriteInt32(reservedChannels); + out->WriteInt32(volume_reduction_while_speech_playing); + out->WriteInt32(crossfadeSpeed); + out->WriteInt32(reservedForFuture); } -void AudioClipType::ReadFromSavegame(Common::Stream *in) -{ - volume_reduction_while_speech_playing = in->ReadInt32(); - crossfadeSpeed = in->ReadInt32(); +void AudioClipType::ReadFromSavegame(Common::Stream *in) { + volume_reduction_while_speech_playing = in->ReadInt32(); + crossfadeSpeed = in->ReadInt32(); } -void AudioClipType::WriteToSavegame(Common::Stream *out) const -{ - out->WriteInt32(volume_reduction_while_speech_playing); - out->WriteInt32(crossfadeSpeed); +void AudioClipType::WriteToSavegame(Common::Stream *out) const { + out->WriteInt32(volume_reduction_while_speech_playing); + out->WriteInt32(crossfadeSpeed); } diff --git a/engines/ags/shared/ac/audiocliptype.h b/engines/ags/shared/ac/audiocliptype.h index c7997705fb2b..8b36ad01dd45 100644 --- a/engines/ags/shared/ac/audiocliptype.h +++ b/engines/ags/shared/ac/audiocliptype.h @@ -24,21 +24,25 @@ #define AGS_SHARED_AC_AUDIOCLIPTYPE_H // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define AUDIO_CLIP_TYPE_SOUND 1 struct AudioClipType { - int id; - int reservedChannels; - int volume_reduction_while_speech_playing; - int crossfadeSpeed; - int reservedForFuture; + int id; + int reservedChannels; + int volume_reduction_while_speech_playing; + int crossfadeSpeed; + int reservedForFuture; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; }; #endif diff --git a/engines/ags/shared/ac/characterinfo.cpp b/engines/ags/shared/ac/characterinfo.cpp index efc3d87af7bb..9ec843cf6c75 100644 --- a/engines/ags/shared/ac/characterinfo.cpp +++ b/engines/ags/shared/ac/characterinfo.cpp @@ -27,137 +27,135 @@ using AGS::Common::Stream; -void CharacterInfo::ReadFromFile(Stream *in) -{ - defview = in->ReadInt32(); - talkview = in->ReadInt32(); - view = in->ReadInt32(); - room = in->ReadInt32(); - prevroom = in->ReadInt32(); - x = in->ReadInt32(); - y = in->ReadInt32(); - wait = in->ReadInt32(); - flags = in->ReadInt32(); - following = in->ReadInt16(); - followinfo = in->ReadInt16(); - idleview = in->ReadInt32(); - idletime = in->ReadInt16(); - idleleft = in->ReadInt16(); - transparency = in->ReadInt16(); - baseline = in->ReadInt16(); - activeinv = in->ReadInt32(); - talkcolor = in->ReadInt32(); - thinkview = in->ReadInt32(); - blinkview = in->ReadInt16(); - blinkinterval = in->ReadInt16(); - blinktimer = in->ReadInt16(); - blinkframe = in->ReadInt16(); - walkspeed_y = in->ReadInt16(); - pic_yoffs = in->ReadInt16(); - z = in->ReadInt32(); - walkwait = in->ReadInt32(); - speech_anim_speed = in->ReadInt16(); - reserved1 = in->ReadInt16(); - blocking_width = in->ReadInt16(); - blocking_height = in->ReadInt16();; - index_id = in->ReadInt32(); - pic_xoffs = in->ReadInt16(); - walkwaitcounter = in->ReadInt16(); - loop = in->ReadInt16(); - frame = in->ReadInt16(); - walking = in->ReadInt16(); - animating = in->ReadInt16(); - walkspeed = in->ReadInt16(); - animspeed = in->ReadInt16(); - in->ReadArrayOfInt16(inv, MAX_INV); - actx = in->ReadInt16(); - acty = in->ReadInt16(); - in->Read(name, 40); - in->Read(scrname, MAX_SCRIPT_NAME_LEN); - on = in->ReadInt8(); +void CharacterInfo::ReadFromFile(Stream *in) { + defview = in->ReadInt32(); + talkview = in->ReadInt32(); + view = in->ReadInt32(); + room = in->ReadInt32(); + prevroom = in->ReadInt32(); + x = in->ReadInt32(); + y = in->ReadInt32(); + wait = in->ReadInt32(); + flags = in->ReadInt32(); + following = in->ReadInt16(); + followinfo = in->ReadInt16(); + idleview = in->ReadInt32(); + idletime = in->ReadInt16(); + idleleft = in->ReadInt16(); + transparency = in->ReadInt16(); + baseline = in->ReadInt16(); + activeinv = in->ReadInt32(); + talkcolor = in->ReadInt32(); + thinkview = in->ReadInt32(); + blinkview = in->ReadInt16(); + blinkinterval = in->ReadInt16(); + blinktimer = in->ReadInt16(); + blinkframe = in->ReadInt16(); + walkspeed_y = in->ReadInt16(); + pic_yoffs = in->ReadInt16(); + z = in->ReadInt32(); + walkwait = in->ReadInt32(); + speech_anim_speed = in->ReadInt16(); + reserved1 = in->ReadInt16(); + blocking_width = in->ReadInt16(); + blocking_height = in->ReadInt16();; + index_id = in->ReadInt32(); + pic_xoffs = in->ReadInt16(); + walkwaitcounter = in->ReadInt16(); + loop = in->ReadInt16(); + frame = in->ReadInt16(); + walking = in->ReadInt16(); + animating = in->ReadInt16(); + walkspeed = in->ReadInt16(); + animspeed = in->ReadInt16(); + in->ReadArrayOfInt16(inv, MAX_INV); + actx = in->ReadInt16(); + acty = in->ReadInt16(); + in->Read(name, 40); + in->Read(scrname, MAX_SCRIPT_NAME_LEN); + on = in->ReadInt8(); } -void CharacterInfo::WriteToFile(Stream *out) -{ - out->WriteInt32(defview); - out->WriteInt32(talkview); - out->WriteInt32(view); - out->WriteInt32(room); - out->WriteInt32(prevroom); - out->WriteInt32(x); - out->WriteInt32(y); - out->WriteInt32(wait); - out->WriteInt32(flags); - out->WriteInt16(following); - out->WriteInt16(followinfo); - out->WriteInt32(idleview); - out->WriteInt16(idletime); - out->WriteInt16(idleleft); - out->WriteInt16(transparency); - out->WriteInt16(baseline); - out->WriteInt32(activeinv); - out->WriteInt32(talkcolor); - out->WriteInt32(thinkview); - out->WriteInt16(blinkview); - out->WriteInt16(blinkinterval); - out->WriteInt16(blinktimer); - out->WriteInt16(blinkframe); - out->WriteInt16(walkspeed_y); - out->WriteInt16(pic_yoffs); - out->WriteInt32(z); - out->WriteInt32(walkwait); - out->WriteInt16(speech_anim_speed); - out->WriteInt16(reserved1); - out->WriteInt16(blocking_width); - out->WriteInt16(blocking_height);; - out->WriteInt32(index_id); - out->WriteInt16(pic_xoffs); - out->WriteInt16(walkwaitcounter); - out->WriteInt16(loop); - out->WriteInt16(frame); - out->WriteInt16(walking); - out->WriteInt16(animating); - out->WriteInt16(walkspeed); - out->WriteInt16(animspeed); - out->WriteArrayOfInt16(inv, MAX_INV); - out->WriteInt16(actx); - out->WriteInt16(acty); - out->Write(name, 40); - out->Write(scrname, MAX_SCRIPT_NAME_LEN); - out->WriteInt8(on); +void CharacterInfo::WriteToFile(Stream *out) { + out->WriteInt32(defview); + out->WriteInt32(talkview); + out->WriteInt32(view); + out->WriteInt32(room); + out->WriteInt32(prevroom); + out->WriteInt32(x); + out->WriteInt32(y); + out->WriteInt32(wait); + out->WriteInt32(flags); + out->WriteInt16(following); + out->WriteInt16(followinfo); + out->WriteInt32(idleview); + out->WriteInt16(idletime); + out->WriteInt16(idleleft); + out->WriteInt16(transparency); + out->WriteInt16(baseline); + out->WriteInt32(activeinv); + out->WriteInt32(talkcolor); + out->WriteInt32(thinkview); + out->WriteInt16(blinkview); + out->WriteInt16(blinkinterval); + out->WriteInt16(blinktimer); + out->WriteInt16(blinkframe); + out->WriteInt16(walkspeed_y); + out->WriteInt16(pic_yoffs); + out->WriteInt32(z); + out->WriteInt32(walkwait); + out->WriteInt16(speech_anim_speed); + out->WriteInt16(reserved1); + out->WriteInt16(blocking_width); + out->WriteInt16(blocking_height);; + out->WriteInt32(index_id); + out->WriteInt16(pic_xoffs); + out->WriteInt16(walkwaitcounter); + out->WriteInt16(loop); + out->WriteInt16(frame); + out->WriteInt16(walking); + out->WriteInt16(animating); + out->WriteInt16(walkspeed); + out->WriteInt16(animspeed); + out->WriteArrayOfInt16(inv, MAX_INV); + out->WriteInt16(actx); + out->WriteInt16(acty); + out->Write(name, 40); + out->Write(scrname, MAX_SCRIPT_NAME_LEN); + out->WriteInt8(on); } -void ConvertOldCharacterToNew (OldCharacterInfo *oci, CharacterInfo *ci) { - COPY_CHAR_VAR (defview); - COPY_CHAR_VAR (talkview); - COPY_CHAR_VAR (view); - COPY_CHAR_VAR (room); - COPY_CHAR_VAR (prevroom); - COPY_CHAR_VAR (x); - COPY_CHAR_VAR (y); - COPY_CHAR_VAR (wait); - COPY_CHAR_VAR (flags); - COPY_CHAR_VAR (following); - COPY_CHAR_VAR (followinfo); - COPY_CHAR_VAR (idleview); - COPY_CHAR_VAR (idletime); - COPY_CHAR_VAR (idleleft); - COPY_CHAR_VAR (transparency); - COPY_CHAR_VAR (baseline); - COPY_CHAR_VAR (activeinv); - COPY_CHAR_VAR (loop); - COPY_CHAR_VAR (frame); - COPY_CHAR_VAR (walking); - COPY_CHAR_VAR (animating); - COPY_CHAR_VAR (walkspeed); - COPY_CHAR_VAR (animspeed); - COPY_CHAR_VAR (actx); - COPY_CHAR_VAR (acty); - COPY_CHAR_VAR (on); - strcpy (ci->name, oci->name); - strcpy (ci->scrname, oci->scrname); - memcpy (&ci->inv[0], &oci->inv[0], sizeof(short) * 100); - // move the talking colour into the struct and remove from flags - ci->talkcolor = (oci->flags & OCHF_SPEECHCOL) >> OCHF_SPEECHCOLSHIFT; - ci->flags = ci->flags & (~OCHF_SPEECHCOL); +void ConvertOldCharacterToNew(OldCharacterInfo *oci, CharacterInfo *ci) { + COPY_CHAR_VAR(defview); + COPY_CHAR_VAR(talkview); + COPY_CHAR_VAR(view); + COPY_CHAR_VAR(room); + COPY_CHAR_VAR(prevroom); + COPY_CHAR_VAR(x); + COPY_CHAR_VAR(y); + COPY_CHAR_VAR(wait); + COPY_CHAR_VAR(flags); + COPY_CHAR_VAR(following); + COPY_CHAR_VAR(followinfo); + COPY_CHAR_VAR(idleview); + COPY_CHAR_VAR(idletime); + COPY_CHAR_VAR(idleleft); + COPY_CHAR_VAR(transparency); + COPY_CHAR_VAR(baseline); + COPY_CHAR_VAR(activeinv); + COPY_CHAR_VAR(loop); + COPY_CHAR_VAR(frame); + COPY_CHAR_VAR(walking); + COPY_CHAR_VAR(animating); + COPY_CHAR_VAR(walkspeed); + COPY_CHAR_VAR(animspeed); + COPY_CHAR_VAR(actx); + COPY_CHAR_VAR(acty); + COPY_CHAR_VAR(on); + strcpy(ci->name, oci->name); + strcpy(ci->scrname, oci->scrname); + memcpy(&ci->inv[0], &oci->inv[0], sizeof(short) * 100); + // move the talking colour into the struct and remove from flags + ci->talkcolor = (oci->flags & OCHF_SPEECHCOL) >> OCHF_SPEECHCOLSHIFT; + ci->flags = ci->flags & (~OCHF_SPEECHCOL); } diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h index 614179ec662c..4f3cad6ebf0b 100644 --- a/engines/ags/shared/ac/characterinfo.h +++ b/engines/ags/shared/ac/characterinfo.h @@ -25,7 +25,11 @@ #include "ac/common_defines.h" // constants -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define MAX_INV 301 @@ -58,56 +62,60 @@ struct CharacterExtras; // forward declaration // remember - if change this struct, also change AGSDEFNS.SH and // plugin header file struct struct CharacterInfo { - int defview; - int talkview; - int view; - int room, prevroom; - int x, y, wait; - int flags; - short following; - short followinfo; - int idleview; // the loop will be randomly picked - short idletime, idleleft; // num seconds idle before playing anim - short transparency; // if character is transparent - short baseline; - int activeinv; - int talkcolor; - int thinkview; - short blinkview, blinkinterval; // design time - short blinktimer, blinkframe; // run time - short walkspeed_y; - short pic_yoffs; // this is fixed in screen coordinates - int z; // z-location, for flying etc - int walkwait; - short speech_anim_speed, reserved1; // only 1 reserved left!! - short blocking_width, blocking_height; - int index_id; // used for object functions to know the id - short pic_xoffs; // this is fixed in screen coordinates - short walkwaitcounter; - short loop, frame; - short walking, animating; - short walkspeed, animspeed; - short inv[MAX_INV]; - short actx, acty; - char name[40]; - char scrname[MAX_SCRIPT_NAME_LEN]; - char on; + int defview; + int talkview; + int view; + int room, prevroom; + int x, y, wait; + int flags; + short following; + short followinfo; + int idleview; // the loop will be randomly picked + short idletime, idleleft; // num seconds idle before playing anim + short transparency; // if character is transparent + short baseline; + int activeinv; + int talkcolor; + int thinkview; + short blinkview, blinkinterval; // design time + short blinktimer, blinkframe; // run time + short walkspeed_y; + short pic_yoffs; // this is fixed in screen coordinates + int z; // z-location, for flying etc + int walkwait; + short speech_anim_speed, reserved1; // only 1 reserved left!! + short blocking_width, blocking_height; + int index_id; // used for object functions to know the id + short pic_xoffs; // this is fixed in screen coordinates + short walkwaitcounter; + short loop, frame; + short walking, animating; + short walkspeed, animspeed; + short inv[MAX_INV]; + short actx, acty; + char name[40]; + char scrname[MAX_SCRIPT_NAME_LEN]; + char on; - int get_effective_y(); // return Y - Z - int get_baseline(); // return baseline, or Y if not set - int get_blocking_top(); // return Y - BlockingHeight/2 - int get_blocking_bottom(); // return Y + BlockingHeight/2 + int get_effective_y(); // return Y - Z + int get_baseline(); // return baseline, or Y if not set + int get_blocking_top(); // return Y - BlockingHeight/2 + int get_blocking_bottom(); // return Y + BlockingHeight/2 - inline bool has_explicit_light() const { return (flags & CHF_HASLIGHT) != 0; } - inline bool has_explicit_tint() const { return (flags & CHF_HASTINT) != 0; } + inline bool has_explicit_light() const { + return (flags & CHF_HASLIGHT) != 0; + } + inline bool has_explicit_tint() const { + return (flags & CHF_HASTINT) != 0; + } // [IKM] 2012-06-28: I still have to pass char_index to some of those functions // either because they use it to set some variables with it, // or because they pass it further to other functions, that are called from various places // and it would be too much to change them all simultaneously - // - // [IKM] 2016-08-26: these methods should NOT be in CharacterInfo class, - // bit in distinct runtime character class! + // + // [IKM] 2016-08-26: these methods should NOT be in CharacterInfo class, + // bit in distinct runtime character class! void UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, int &numSheep, int *followingAsSheep); void UpdateFollowingExactlyCharacter(); @@ -117,36 +125,36 @@ struct CharacterInfo { void update_character_idle(CharacterExtras *chex, int &doing_nothing); void update_character_follower(int &char_index, int &numSheep, int *followingAsSheep, int &doing_nothing); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); }; struct OldCharacterInfo { - int defview; - int talkview; - int view; - int room, prevroom; - int x, y, wait; - int flags; - short following; - short followinfo; - int idleview; // the loop will be randomly picked - short idletime, idleleft; // num seconds idle before playing anim - short transparency; // if character is transparent - short baseline; - int activeinv; // this is an INT to support SeeR (no signed shorts) - short loop, frame; - short walking, animating; - short walkspeed, animspeed; - short inv[100]; - short actx, acty; - char name[30]; - char scrname[16]; - char on; + int defview; + int talkview; + int view; + int room, prevroom; + int x, y, wait; + int flags; + short following; + short followinfo; + int idleview; // the loop will be randomly picked + short idletime, idleleft; // num seconds idle before playing anim + short transparency; // if character is transparent + short baseline; + int activeinv; // this is an INT to support SeeR (no signed shorts) + short loop, frame; + short walking, animating; + short walkspeed, animspeed; + short inv[100]; + short actx, acty; + char name[30]; + char scrname[16]; + char on; }; #define COPY_CHAR_VAR(name) ci->name = oci->name -void ConvertOldCharacterToNew (OldCharacterInfo *oci, CharacterInfo *ci); +void ConvertOldCharacterToNew(OldCharacterInfo *oci, CharacterInfo *ci); #endif diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index cb5dc92f270d..d7a2b148a353 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -27,11 +27,10 @@ using namespace AGS::Common; const char *game_file_sig = "Adventure Creator Game File v2"; -void quitprintf(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - String text = String::FromFormatV(fmt, ap); - va_end(ap); - quit(text); +void quitprintf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + String text = String::FromFormatV(fmt, ap); + va_end(ap); + quit(text); } diff --git a/engines/ags/shared/ac/dialogtopic.cpp b/engines/ags/shared/ac/dialogtopic.cpp index 0def805ee250..7ae5189ddf0e 100644 --- a/engines/ags/shared/ac/dialogtopic.cpp +++ b/engines/ags/shared/ac/dialogtopic.cpp @@ -25,26 +25,23 @@ using AGS::Common::Stream; -void DialogTopic::ReadFromFile(Stream *in) -{ - in->ReadArray(optionnames, 150*sizeof(char), MAXTOPICOPTIONS); - in->ReadArrayOfInt32(optionflags, MAXTOPICOPTIONS); - // optionscripts pointer is not used anywhere in the engine - optionscripts = nullptr; - in->ReadInt32(); // optionscripts 32-bit pointer - in->ReadArrayOfInt16(entrypoints, MAXTOPICOPTIONS); - startupentrypoint = in->ReadInt16(); - codesize = in->ReadInt16(); - numoptions = in->ReadInt32(); - topicFlags = in->ReadInt32(); +void DialogTopic::ReadFromFile(Stream *in) { + in->ReadArray(optionnames, 150 * sizeof(char), MAXTOPICOPTIONS); + in->ReadArrayOfInt32(optionflags, MAXTOPICOPTIONS); + // optionscripts pointer is not used anywhere in the engine + optionscripts = nullptr; + in->ReadInt32(); // optionscripts 32-bit pointer + in->ReadArrayOfInt16(entrypoints, MAXTOPICOPTIONS); + startupentrypoint = in->ReadInt16(); + codesize = in->ReadInt16(); + numoptions = in->ReadInt32(); + topicFlags = in->ReadInt32(); } -void DialogTopic::ReadFromSavegame(Common::Stream *in) -{ - in->ReadArrayOfInt32(optionflags, MAXTOPICOPTIONS); +void DialogTopic::ReadFromSavegame(Common::Stream *in) { + in->ReadArrayOfInt32(optionflags, MAXTOPICOPTIONS); } -void DialogTopic::WriteToSavegame(Common::Stream *out) const -{ - out->WriteArrayOfInt32(optionflags, MAXTOPICOPTIONS); +void DialogTopic::WriteToSavegame(Common::Stream *out) const { + out->WriteArrayOfInt32(optionflags, MAXTOPICOPTIONS); } diff --git a/engines/ags/shared/ac/dialogtopic.h b/engines/ags/shared/ac/dialogtopic.h index 431123b062e7..dbffaf2a0bea 100644 --- a/engines/ags/shared/ac/dialogtopic.h +++ b/engines/ags/shared/ac/dialogtopic.h @@ -23,7 +23,11 @@ #ifndef AGS_SHARED_AC_DIALOGTOPIC_H #define AGS_SHARED_AC_DIALOGTOPIC_H -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later // [IKM] This is *conversation* dialog, not *gui* dialog, mind you! @@ -54,19 +58,19 @@ using namespace AGS; // FIXME later #define DCHAR_NARRATOR 999 #define DCHAR_PLAYER 998 struct DialogTopic { - char optionnames[MAXTOPICOPTIONS][150]; - int optionflags[MAXTOPICOPTIONS]; - unsigned char *optionscripts; - short entrypoints[MAXTOPICOPTIONS]; - short startupentrypoint; - short codesize; - int numoptions; - int topicFlags; + char optionnames[MAXTOPICOPTIONS][150]; + int optionflags[MAXTOPICOPTIONS]; + unsigned char *optionscripts; + short entrypoints[MAXTOPICOPTIONS]; + short startupentrypoint; + short codesize; + int numoptions; + int topicFlags; - void ReadFromFile(Common::Stream *in); + void ReadFromFile(Common::Stream *in); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; }; diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp index 820a67d31cb0..e858f0d63f43 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp @@ -25,16 +25,15 @@ using namespace AGS::Common; -void ScriptAudioClip::ReadFromFile(Stream *in) -{ - id = in->ReadInt32(); - scriptName.ReadCount(in, SCRIPTAUDIOCLIP_SCRIPTNAMELENGTH); - fileName.ReadCount(in, SCRIPTAUDIOCLIP_FILENAMELENGTH); - bundlingType = in->ReadInt8(); - type = in->ReadInt8(); - fileType = in->ReadInt8(); - defaultRepeat = in->ReadInt8(); - defaultPriority = in->ReadInt16(); - defaultVolume = in->ReadInt16(); - in->ReadInt32(); // reserved +void ScriptAudioClip::ReadFromFile(Stream *in) { + id = in->ReadInt32(); + scriptName.ReadCount(in, SCRIPTAUDIOCLIP_SCRIPTNAMELENGTH); + fileName.ReadCount(in, SCRIPTAUDIOCLIP_FILENAMELENGTH); + bundlingType = in->ReadInt8(); + type = in->ReadInt8(); + fileType = in->ReadInt8(); + defaultRepeat = in->ReadInt8(); + defaultPriority = in->ReadInt16(); + defaultVolume = in->ReadInt16(); + in->ReadInt32(); // reserved } diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index adad724dcdfd..c8e18fa50241 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -25,16 +25,20 @@ #include "util/string.h" -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later enum AudioFileType { - eAudioFileOGG = 1, - eAudioFileMP3 = 2, - eAudioFileWAV = 3, - eAudioFileVOC = 4, - eAudioFileMIDI = 5, - eAudioFileMOD = 6 + eAudioFileOGG = 1, + eAudioFileMP3 = 2, + eAudioFileWAV = 3, + eAudioFileVOC = 4, + eAudioFileMIDI = 5, + eAudioFileMOD = 6 }; #define AUCL_BUNDLE_EXE 1 @@ -43,17 +47,17 @@ enum AudioFileType { #define SCRIPTAUDIOCLIP_SCRIPTNAMELENGTH 30 #define SCRIPTAUDIOCLIP_FILENAMELENGTH 15 struct ScriptAudioClip { - int id = 0; - Common::String scriptName; - Common::String fileName; - char bundlingType = AUCL_BUNDLE_EXE; - char type = 0; - char fileType = eAudioFileOGG; - char defaultRepeat = 0; - short defaultPriority = 50; - short defaultVolume = 100; - - void ReadFromFile(Common::Stream *in); + int id = 0; + Common::String scriptName; + Common::String fileName; + char bundlingType = AUCL_BUNDLE_EXE; + char type = 0; + char fileType = eAudioFileOGG; + char defaultRepeat = 0; + short defaultPriority = 50; + short defaultVolume = 100; + + void ReadFromFile(Common::Stream *in); }; #endif diff --git a/engines/ags/shared/ac/game_version.h b/engines/ags/shared/ac/game_version.h index 7706953f8583..9a11424b5648 100644 --- a/engines/ags/shared/ac/game_version.h +++ b/engines/ags/shared/ac/game_version.h @@ -116,39 +116,38 @@ Fonts have adjustable outline */ -enum GameDataVersion -{ - kGameVersion_Undefined = 0, - kGameVersion_230 = 12, - kGameVersion_240 = 12, - kGameVersion_250 = 18, - kGameVersion_251 = 19, // same as 2.52 - kGameVersion_253 = 20, - kGameVersion_254 = 21, - kGameVersion_255 = 22, - kGameVersion_256 = 24, - kGameVersion_260 = 25, - kGameVersion_261 = 26, - kGameVersion_262 = 27, - kGameVersion_270 = 31, - kGameVersion_272 = 32, - kGameVersion_300 = 35, - kGameVersion_301 = 36, - kGameVersion_310 = 37, - kGameVersion_311 = 39, - kGameVersion_312 = 40, - kGameVersion_320 = 41, - kGameVersion_321 = 42, - kGameVersion_330 = 43, - kGameVersion_331 = 44, - kGameVersion_340_1 = 45, - kGameVersion_340_2 = 46, - kGameVersion_340_4 = 47, - kGameVersion_341 = 48, - kGameVersion_341_2 = 49, - kGameVersion_350 = 50, - kGameVersion_351 = 51, - kGameVersion_Current = kGameVersion_351 +enum GameDataVersion { + kGameVersion_Undefined = 0, + kGameVersion_230 = 12, + kGameVersion_240 = 12, + kGameVersion_250 = 18, + kGameVersion_251 = 19, // same as 2.52 + kGameVersion_253 = 20, + kGameVersion_254 = 21, + kGameVersion_255 = 22, + kGameVersion_256 = 24, + kGameVersion_260 = 25, + kGameVersion_261 = 26, + kGameVersion_262 = 27, + kGameVersion_270 = 31, + kGameVersion_272 = 32, + kGameVersion_300 = 35, + kGameVersion_301 = 36, + kGameVersion_310 = 37, + kGameVersion_311 = 39, + kGameVersion_312 = 40, + kGameVersion_320 = 41, + kGameVersion_321 = 42, + kGameVersion_330 = 43, + kGameVersion_331 = 44, + kGameVersion_340_1 = 45, + kGameVersion_340_2 = 46, + kGameVersion_340_4 = 47, + kGameVersion_341 = 48, + kGameVersion_341_2 = 49, + kGameVersion_350 = 50, + kGameVersion_351 = 51, + kGameVersion_Current = kGameVersion_351 }; extern GameDataVersion loaded_game_file_version; diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp index b5c0d9fbceb0..872c7c933d5c 100644 --- a/engines/ags/shared/ac/gamesetupstruct.cpp +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -31,476 +31,415 @@ using namespace AGS::Common; GameSetupStruct::GameSetupStruct() - : filever(0) - , roomCount(0) - , roomNumbers(nullptr) - , roomNames(nullptr) - , scoreClipID(0) -{ - memset(invinfo, 0, sizeof(invinfo)); - memset(mcurs, 0, sizeof(mcurs)); - memset(lipSyncFrameLetters, 0, sizeof(lipSyncFrameLetters)); - memset(guid, 0, sizeof(guid)); - memset(saveGameFileExtension, 0, sizeof(saveGameFileExtension)); - memset(saveGameFolderName, 0, sizeof(saveGameFolderName)); + : filever(0) + , roomCount(0) + , roomNumbers(nullptr) + , roomNames(nullptr) + , scoreClipID(0) { + memset(invinfo, 0, sizeof(invinfo)); + memset(mcurs, 0, sizeof(mcurs)); + memset(lipSyncFrameLetters, 0, sizeof(lipSyncFrameLetters)); + memset(guid, 0, sizeof(guid)); + memset(saveGameFileExtension, 0, sizeof(saveGameFileExtension)); + memset(saveGameFolderName, 0, sizeof(saveGameFolderName)); } -GameSetupStruct::~GameSetupStruct() -{ - Free(); +GameSetupStruct::~GameSetupStruct() { + Free(); } -void GameSetupStruct::Free() -{ - GameSetupStructBase::Free(); +void GameSetupStruct::Free() { + GameSetupStructBase::Free(); - intrChar.clear(); - charScripts.clear(); - numcharacters = 0; + intrChar.clear(); + charScripts.clear(); + numcharacters = 0; - // TODO: find out if it really needs to begin with 1 here? - for (size_t i = 1; i < (size_t)MAX_INV; i++) - intrInv[i].reset(); - invScripts.clear(); - numinvitems = 0; + // TODO: find out if it really needs to begin with 1 here? + for (size_t i = 1; i < (size_t)MAX_INV; i++) + intrInv[i].reset(); + invScripts.clear(); + numinvitems = 0; - for (int i = 0; i < roomCount; i++) - delete roomNames[i]; - delete[] roomNames; - delete[] roomNumbers; - roomCount = 0; + for (int i = 0; i < roomCount; i++) + delete roomNames[i]; + delete[] roomNames; + delete[] roomNumbers; + roomCount = 0; - audioClips.clear(); - audioClipTypes.clear(); + audioClips.clear(); + audioClipTypes.clear(); - charProps.clear(); - viewNames.clear(); + charProps.clear(); + viewNames.clear(); } // Assigns font info parameters using legacy flags value read from the game data -void SetFontInfoFromLegacyFlags(FontInfo &finfo, const uint8_t data) -{ - finfo.Flags = (data >> 6) & 0xFF; - finfo.SizePt = data & FFLG_LEGACY_SIZEMASK; +void SetFontInfoFromLegacyFlags(FontInfo &finfo, const uint8_t data) { + finfo.Flags = (data >> 6) & 0xFF; + finfo.SizePt = data & FFLG_LEGACY_SIZEMASK; } -void AdjustFontInfoUsingFlags(FontInfo &finfo, const uint32_t flags) -{ - finfo.Flags = flags; - if ((flags & FFLG_SIZEMULTIPLIER) != 0) - { - finfo.SizeMultiplier = finfo.SizePt; - finfo.SizePt = 0; - } +void AdjustFontInfoUsingFlags(FontInfo &finfo, const uint32_t flags) { + finfo.Flags = flags; + if ((flags & FFLG_SIZEMULTIPLIER) != 0) { + finfo.SizeMultiplier = finfo.SizePt; + finfo.SizePt = 0; + } } -ScriptAudioClip* GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num) -{ - String clip_name; - if (is_music) - clip_name.Format("aMusic%d", num); - else - clip_name.Format("aSound%d", num); - - for (size_t i = 0; i < game.audioClips.size(); ++i) - { - if (clip_name.Compare(game.audioClips[i].scriptName) == 0) - return &game.audioClips[i]; - } - return nullptr; +ScriptAudioClip *GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num) { + String clip_name; + if (is_music) + clip_name.Format("aMusic%d", num); + else + clip_name.Format("aSound%d", num); + + for (size_t i = 0; i < game.audioClips.size(); ++i) { + if (clip_name.Compare(game.audioClips[i].scriptName) == 0) + return &game.audioClips[i]; + } + return nullptr; } //----------------------------------------------------------------------------- // Reading Part 1 -void GameSetupStruct::read_savegame_info(Common::Stream *in, GameDataVersion data_ver) -{ - if (data_ver > kGameVersion_272) // only 3.x - { - in->Read(&guid[0], MAX_GUID_LENGTH); - in->Read(&saveGameFileExtension[0], MAX_SG_EXT_LENGTH); - in->Read(&saveGameFolderName[0], MAX_SG_FOLDER_LEN); - } +void GameSetupStruct::read_savegame_info(Common::Stream *in, GameDataVersion data_ver) { + if (data_ver > kGameVersion_272) { // only 3.x + in->Read(&guid[0], MAX_GUID_LENGTH); + in->Read(&saveGameFileExtension[0], MAX_SG_EXT_LENGTH); + in->Read(&saveGameFolderName[0], MAX_SG_FOLDER_LEN); + } } -void GameSetupStruct::read_font_infos(Common::Stream *in, GameDataVersion data_ver) -{ - fonts.resize(numfonts); - if (data_ver < kGameVersion_350) - { - for (int i = 0; i < numfonts; ++i) - SetFontInfoFromLegacyFlags(fonts[i], in->ReadInt8()); - for (int i = 0; i < numfonts; ++i) - fonts[i].Outline = in->ReadInt8(); // size of char - if (data_ver < kGameVersion_341) - return; - for (int i = 0; i < numfonts; ++i) - { - fonts[i].YOffset = in->ReadInt32(); - if (data_ver >= kGameVersion_341_2) - fonts[i].LineSpacing = Math::Max(0, in->ReadInt32()); - } - } - else - { - for (int i = 0; i < numfonts; ++i) - { - uint32_t flags = in->ReadInt32(); - fonts[i].SizePt = in->ReadInt32(); - fonts[i].Outline = in->ReadInt32(); - fonts[i].YOffset = in->ReadInt32(); - fonts[i].LineSpacing = Math::Max(0, in->ReadInt32()); - AdjustFontInfoUsingFlags(fonts[i], flags); - if (data_ver >= kGameVersion_351) - { - fonts[i].AutoOutlineThickness = in->ReadInt32(); - fonts[i].AutoOutlineStyle = - static_cast(in->ReadInt32()); - } - } - } +void GameSetupStruct::read_font_infos(Common::Stream *in, GameDataVersion data_ver) { + fonts.resize(numfonts); + if (data_ver < kGameVersion_350) { + for (int i = 0; i < numfonts; ++i) + SetFontInfoFromLegacyFlags(fonts[i], in->ReadInt8()); + for (int i = 0; i < numfonts; ++i) + fonts[i].Outline = in->ReadInt8(); // size of char + if (data_ver < kGameVersion_341) + return; + for (int i = 0; i < numfonts; ++i) { + fonts[i].YOffset = in->ReadInt32(); + if (data_ver >= kGameVersion_341_2) + fonts[i].LineSpacing = Math::Max(0, in->ReadInt32()); + } + } else { + for (int i = 0; i < numfonts; ++i) { + uint32_t flags = in->ReadInt32(); + fonts[i].SizePt = in->ReadInt32(); + fonts[i].Outline = in->ReadInt32(); + fonts[i].YOffset = in->ReadInt32(); + fonts[i].LineSpacing = Math::Max(0, in->ReadInt32()); + AdjustFontInfoUsingFlags(fonts[i], flags); + if (data_ver >= kGameVersion_351) { + fonts[i].AutoOutlineThickness = in->ReadInt32(); + fonts[i].AutoOutlineStyle = + static_cast(in->ReadInt32()); + } + } + } } -void GameSetupStruct::ReadInvInfo_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) - { - invinfo[iteratorCount].ReadFromFile(&align_s); - align_s.Reset(); - } +void GameSetupStruct::ReadInvInfo_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) { + invinfo[iteratorCount].ReadFromFile(&align_s); + align_s.Reset(); + } } -void GameSetupStruct::WriteInvInfo_Aligned(Stream *out) -{ - AlignedStream align_s(out, Common::kAligned_Write); - for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) - { - invinfo[iteratorCount].WriteToFile(&align_s); - align_s.Reset(); - } +void GameSetupStruct::WriteInvInfo_Aligned(Stream *out) { + AlignedStream align_s(out, Common::kAligned_Write); + for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) { + invinfo[iteratorCount].WriteToFile(&align_s); + align_s.Reset(); + } } -HGameFileError GameSetupStruct::read_cursors(Common::Stream *in, GameDataVersion data_ver) -{ - if (numcursors > MAX_CURSOR) - return new MainGameFileError(kMGFErr_TooManyCursors, String::FromFormat("Count: %d, max: %d", numcursors, MAX_CURSOR)); +HGameFileError GameSetupStruct::read_cursors(Common::Stream *in, GameDataVersion data_ver) { + if (numcursors > MAX_CURSOR) + return new MainGameFileError(kMGFErr_TooManyCursors, String::FromFormat("Count: %d, max: %d", numcursors, MAX_CURSOR)); - ReadMouseCursors_Aligned(in); - return HGameFileError::None(); + ReadMouseCursors_Aligned(in); + return HGameFileError::None(); } -void GameSetupStruct::read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver) -{ - numGlobalVars = 0; - - if (data_ver > kGameVersion_272) // 3.x - { - charScripts.resize(numcharacters); - invScripts.resize(numinvitems); - for (size_t i = 0; i < (size_t)numcharacters; ++i) - charScripts[i].reset(InteractionScripts::CreateFromStream(in)); - // NOTE: new inventory items' events are loaded starting from 1 for some reason - for (size_t i = 1; i < (size_t)numinvitems; ++i) - invScripts[i].reset(InteractionScripts::CreateFromStream(in)); - } - else // 2.x - { - intrChar.resize(numcharacters); - for (size_t i = 0; i < (size_t)numcharacters; ++i) - intrChar[i].reset(Interaction::CreateFromStream(in)); - for (size_t i = 0; i < (size_t)numinvitems; ++i) - intrInv[i].reset(Interaction::CreateFromStream(in)); - - numGlobalVars = in->ReadInt32(); - for (size_t i = 0; i < (size_t)numGlobalVars; ++i) - globalvars[i].Read(in); - } +void GameSetupStruct::read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver) { + numGlobalVars = 0; + + if (data_ver > kGameVersion_272) { // 3.x + charScripts.resize(numcharacters); + invScripts.resize(numinvitems); + for (size_t i = 0; i < (size_t)numcharacters; ++i) + charScripts[i].reset(InteractionScripts::CreateFromStream(in)); + // NOTE: new inventory items' events are loaded starting from 1 for some reason + for (size_t i = 1; i < (size_t)numinvitems; ++i) + invScripts[i].reset(InteractionScripts::CreateFromStream(in)); + } else { // 2.x + intrChar.resize(numcharacters); + for (size_t i = 0; i < (size_t)numcharacters; ++i) + intrChar[i].reset(Interaction::CreateFromStream(in)); + for (size_t i = 0; i < (size_t)numinvitems; ++i) + intrInv[i].reset(Interaction::CreateFromStream(in)); + + numGlobalVars = in->ReadInt32(); + for (size_t i = 0; i < (size_t)numGlobalVars; ++i) + globalvars[i].Read(in); + } } -void GameSetupStruct::read_words_dictionary(Common::Stream *in) -{ - if (load_dictionary) { - dict = new WordsDictionary(); - read_dictionary (dict, in); - } +void GameSetupStruct::read_words_dictionary(Common::Stream *in) { + if (load_dictionary) { + dict = new WordsDictionary(); + read_dictionary(dict, in); + } } -void GameSetupStruct::ReadMouseCursors_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) - { - mcurs[iteratorCount].ReadFromFile(&align_s); - align_s.Reset(); - } +void GameSetupStruct::ReadMouseCursors_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) { + mcurs[iteratorCount].ReadFromFile(&align_s); + align_s.Reset(); + } } -void GameSetupStruct::WriteMouseCursors_Aligned(Stream *out) -{ - AlignedStream align_s(out, Common::kAligned_Write); - for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) - { - mcurs[iteratorCount].WriteToFile(&align_s); - align_s.Reset(); - } +void GameSetupStruct::WriteMouseCursors_Aligned(Stream *out) { + AlignedStream align_s(out, Common::kAligned_Write); + for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) { + mcurs[iteratorCount].WriteToFile(&align_s); + align_s.Reset(); + } } //----------------------------------------------------------------------------- // Reading Part 2 -void GameSetupStruct::read_characters(Common::Stream *in, GameDataVersion data_ver) -{ - chars = new CharacterInfo[numcharacters + 5]; // TODO: why +5, is this really needed? +void GameSetupStruct::read_characters(Common::Stream *in, GameDataVersion data_ver) { + chars = new CharacterInfo[numcharacters + 5]; // TODO: why +5, is this really needed? - ReadCharacters_Aligned(in); + ReadCharacters_Aligned(in); } -void GameSetupStruct::read_lipsync(Common::Stream *in, GameDataVersion data_ver) -{ - if (data_ver >= kGameVersion_254) // lip syncing was introduced in 2.54 - in->ReadArray(&lipSyncFrameLetters[0][0], MAXLIPSYNCFRAMES, 50); +void GameSetupStruct::read_lipsync(Common::Stream *in, GameDataVersion data_ver) { + if (data_ver >= kGameVersion_254) // lip syncing was introduced in 2.54 + in->ReadArray(&lipSyncFrameLetters[0][0], MAXLIPSYNCFRAMES, 50); } -void GameSetupStruct::read_messages(Common::Stream *in, GameDataVersion data_ver) -{ - for (int ee=0;eeReadInt8(); - if (*nextchar == 0) - break; - nextchar++; - } - } - else - read_string_decrypt(in, messages[ee], GLOBALMESLENGTH); - } - delete [] load_messages; - load_messages = nullptr; +void GameSetupStruct::read_messages(Common::Stream *in, GameDataVersion data_ver) { + for (int ee = 0; ee < MAXGLOBALMES; ee++) { + if (!load_messages[ee]) continue; + messages[ee] = new char[GLOBALMESLENGTH]; + + if (data_ver < kGameVersion_261) { // Global messages are not encrypted on < 2.61 + char *nextchar = messages[ee]; + + // TODO: probably this is same as fgetstring + while (1) { + *nextchar = in->ReadInt8(); + if (*nextchar == 0) + break; + nextchar++; + } + } else + read_string_decrypt(in, messages[ee], GLOBALMESLENGTH); + } + delete [] load_messages; + load_messages = nullptr; } -void GameSetupStruct::ReadCharacters_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) - { - chars[iteratorCount].ReadFromFile(&align_s); - align_s.Reset(); - } +void GameSetupStruct::ReadCharacters_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) { + chars[iteratorCount].ReadFromFile(&align_s); + align_s.Reset(); + } } -void GameSetupStruct::WriteCharacters_Aligned(Stream *out) -{ - AlignedStream align_s(out, Common::kAligned_Write); - for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) - { - chars[iteratorCount].WriteToFile(&align_s); - align_s.Reset(); - } +void GameSetupStruct::WriteCharacters_Aligned(Stream *out) { + AlignedStream align_s(out, Common::kAligned_Write); + for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) { + chars[iteratorCount].WriteToFile(&align_s); + align_s.Reset(); + } } //----------------------------------------------------------------------------- // Reading Part 3 -HGameFileError GameSetupStruct::read_customprops(Common::Stream *in, GameDataVersion data_ver) -{ - dialogScriptNames.resize(numdialog); - viewNames.resize(numviews); - if (data_ver >= kGameVersion_260) // >= 2.60 - { - if (Properties::ReadSchema(propSchema, in) != kPropertyErr_NoError) - return new MainGameFileError(kMGFErr_InvalidPropertySchema); - - int errors = 0; - - charProps.resize(numcharacters); - for (int i = 0; i < numcharacters; ++i) - { - errors += Properties::ReadValues(charProps[i], in); - } - for (int i = 0; i < numinvitems; ++i) - { - errors += Properties::ReadValues(invProps[i], in); - } - - if (errors > 0) - return new MainGameFileError(kMGFErr_InvalidPropertyValues); - - for (int i = 0; i < numviews; ++i) - viewNames[i] = String::FromStream(in); - - for (int i = 0; i < numinvitems; ++i) - invScriptNames[i] = String::FromStream(in); - - for (int i = 0; i < numdialog; ++i) - dialogScriptNames[i] = String::FromStream(in); - } - return HGameFileError::None(); +HGameFileError GameSetupStruct::read_customprops(Common::Stream *in, GameDataVersion data_ver) { + dialogScriptNames.resize(numdialog); + viewNames.resize(numviews); + if (data_ver >= kGameVersion_260) { // >= 2.60 + if (Properties::ReadSchema(propSchema, in) != kPropertyErr_NoError) + return new MainGameFileError(kMGFErr_InvalidPropertySchema); + + int errors = 0; + + charProps.resize(numcharacters); + for (int i = 0; i < numcharacters; ++i) { + errors += Properties::ReadValues(charProps[i], in); + } + for (int i = 0; i < numinvitems; ++i) { + errors += Properties::ReadValues(invProps[i], in); + } + + if (errors > 0) + return new MainGameFileError(kMGFErr_InvalidPropertyValues); + + for (int i = 0; i < numviews; ++i) + viewNames[i] = String::FromStream(in); + + for (int i = 0; i < numinvitems; ++i) + invScriptNames[i] = String::FromStream(in); + + for (int i = 0; i < numdialog; ++i) + dialogScriptNames[i] = String::FromStream(in); + } + return HGameFileError::None(); } -HGameFileError GameSetupStruct::read_audio(Common::Stream *in, GameDataVersion data_ver) -{ - if (data_ver >= kGameVersion_320) - { - size_t audiotype_count = in->ReadInt32(); - audioClipTypes.resize(audiotype_count); - for (size_t i = 0; i < audiotype_count; ++i) - { - audioClipTypes[i].ReadFromFile(in); - } - - size_t audioclip_count = in->ReadInt32(); - audioClips.resize(audioclip_count); - ReadAudioClips_Aligned(in, audioclip_count); - - scoreClipID = in->ReadInt32(); - } - return HGameFileError::None(); +HGameFileError GameSetupStruct::read_audio(Common::Stream *in, GameDataVersion data_ver) { + if (data_ver >= kGameVersion_320) { + size_t audiotype_count = in->ReadInt32(); + audioClipTypes.resize(audiotype_count); + for (size_t i = 0; i < audiotype_count; ++i) { + audioClipTypes[i].ReadFromFile(in); + } + + size_t audioclip_count = in->ReadInt32(); + audioClips.resize(audioclip_count); + ReadAudioClips_Aligned(in, audioclip_count); + + scoreClipID = in->ReadInt32(); + } + return HGameFileError::None(); } // Temporarily copied this from acruntim.h; // it is unknown if this should be defined for all solution, or only runtime #define STD_BUFFER_SIZE 3000 -void GameSetupStruct::read_room_names(Stream *in, GameDataVersion data_ver) -{ - if ((data_ver >= kGameVersion_301) && (options[OPT_DEBUGMODE] != 0)) - { - roomCount = in->ReadInt32(); - roomNumbers = new int[roomCount]; - roomNames = new char*[roomCount]; - String pexbuf; - for (int bb = 0; bb < roomCount; bb++) - { - roomNumbers[bb] = in->ReadInt32(); - pexbuf.Read(in, STD_BUFFER_SIZE); - roomNames[bb] = new char[pexbuf.GetLength() + 1]; - strcpy(roomNames[bb], pexbuf); - } - } - else - { - roomCount = 0; - } +void GameSetupStruct::read_room_names(Stream *in, GameDataVersion data_ver) { + if ((data_ver >= kGameVersion_301) && (options[OPT_DEBUGMODE] != 0)) { + roomCount = in->ReadInt32(); + roomNumbers = new int[roomCount]; + roomNames = new char *[roomCount]; + String pexbuf; + for (int bb = 0; bb < roomCount; bb++) { + roomNumbers[bb] = in->ReadInt32(); + pexbuf.Read(in, STD_BUFFER_SIZE); + roomNames[bb] = new char[pexbuf.GetLength() + 1]; + strcpy(roomNames[bb], pexbuf); + } + } else { + roomCount = 0; + } } -void GameSetupStruct::ReadAudioClips_Aligned(Common::Stream *in, size_t count) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (size_t i = 0; i < count; ++i) - { - audioClips[i].ReadFromFile(&align_s); - align_s.Reset(); - } +void GameSetupStruct::ReadAudioClips_Aligned(Common::Stream *in, size_t count) { + AlignedStream align_s(in, Common::kAligned_Read); + for (size_t i = 0; i < count; ++i) { + audioClips[i].ReadFromFile(&align_s); + align_s.Reset(); + } } -void GameSetupStruct::ReadFromSaveGame_v321(Stream *in, char* gswas, ccScript* compsc, CharacterInfo* chwas, - WordsDictionary *olddict, char** mesbk) -{ - int bb; - - ReadInvInfo_Aligned(in); - ReadMouseCursors_Aligned(in); - - if (loaded_game_file_version <= kGameVersion_272) - { - for (bb = 0; bb < numinvitems; bb++) - intrInv[bb]->ReadTimesRunFromSave_v321(in); - for (bb = 0; bb < numcharacters; bb++) - intrChar[bb]->ReadTimesRunFromSave_v321(in); - } - - // restore pointer members - globalscript=gswas; - compiled_script=compsc; - chars=chwas; - dict = olddict; - for (int vv=0;vvReadArrayOfInt32(&options[0], OPT_HIGHESTOPTION_321 + 1); - options[OPT_LIPSYNCTEXT] = in->ReadByte(); - - ReadCharacters_Aligned(in); +void GameSetupStruct::ReadFromSaveGame_v321(Stream *in, char *gswas, ccScript *compsc, CharacterInfo *chwas, + WordsDictionary *olddict, char **mesbk) { + int bb; + + ReadInvInfo_Aligned(in); + ReadMouseCursors_Aligned(in); + + if (loaded_game_file_version <= kGameVersion_272) { + for (bb = 0; bb < numinvitems; bb++) + intrInv[bb]->ReadTimesRunFromSave_v321(in); + for (bb = 0; bb < numcharacters; bb++) + intrChar[bb]->ReadTimesRunFromSave_v321(in); + } + + // restore pointer members + globalscript = gswas; + compiled_script = compsc; + chars = chwas; + dict = olddict; + for (int vv = 0; vv < MAXGLOBALMES; vv++) messages[vv] = mesbk[vv]; + + in->ReadArrayOfInt32(&options[0], OPT_HIGHESTOPTION_321 + 1); + options[OPT_LIPSYNCTEXT] = in->ReadByte(); + + ReadCharacters_Aligned(in); } //============================================================================= -void ConvertOldGameStruct (OldGameSetupStruct *ogss, GameSetupStruct *gss) { - strcpy (gss->gamename, ogss->gamename); - for (int i = 0; i < 20; i++) - gss->options[i] = ogss->options[i]; - memcpy (&gss->paluses[0], &ogss->paluses[0], 256); - memcpy (&gss->defpal[0], &ogss->defpal[0], 256 * sizeof(color)); - gss->numviews = ogss->numviews; - gss->numcharacters = ogss->numcharacters; - gss->playercharacter = ogss->playercharacter; - gss->totalscore = ogss->totalscore; - gss->numinvitems = ogss->numinvitems; - gss->numdialog = ogss->numdialog; - gss->numdlgmessage = ogss->numdlgmessage; - gss->numfonts = ogss->numfonts; - gss->color_depth = ogss->color_depth; - gss->target_win = ogss->target_win; - gss->dialog_bullet = ogss->dialog_bullet; - gss->hotdot = ogss->hotdot; - gss->hotdotouter = ogss->hotdotouter; - gss->uniqueid = ogss->uniqueid; - gss->numgui = ogss->numgui; - for (int i = 0; i < 10; ++i) - { - SetFontInfoFromLegacyFlags(gss->fonts[i], ogss->fontflags[i]); - gss->fonts[i].Outline = ogss->fontoutline[i]; - } - - for (int i = 0; i < LEGACY_MAX_SPRITES_V25; ++i) - { - gss->SpriteInfos[i].Flags = ogss->spriteflags[i]; - } - - memcpy (&gss->invinfo[0], &ogss->invinfo[0], 100 * sizeof(InventoryItemInfo)); - memcpy (&gss->mcurs[0], &ogss->mcurs[0], 10 * sizeof(MouseCursor)); - for (int i = 0; i < MAXGLOBALMES; i++) - gss->messages[i] = ogss->messages[i]; - gss->dict = ogss->dict; - gss->globalscript = ogss->globalscript; - gss->chars = nullptr; //ogss->chars; - gss->compiled_script = ogss->compiled_script; - gss->numcursors = 10; +void ConvertOldGameStruct(OldGameSetupStruct *ogss, GameSetupStruct *gss) { + strcpy(gss->gamename, ogss->gamename); + for (int i = 0; i < 20; i++) + gss->options[i] = ogss->options[i]; + memcpy(&gss->paluses[0], &ogss->paluses[0], 256); + memcpy(&gss->defpal[0], &ogss->defpal[0], 256 * sizeof(color)); + gss->numviews = ogss->numviews; + gss->numcharacters = ogss->numcharacters; + gss->playercharacter = ogss->playercharacter; + gss->totalscore = ogss->totalscore; + gss->numinvitems = ogss->numinvitems; + gss->numdialog = ogss->numdialog; + gss->numdlgmessage = ogss->numdlgmessage; + gss->numfonts = ogss->numfonts; + gss->color_depth = ogss->color_depth; + gss->target_win = ogss->target_win; + gss->dialog_bullet = ogss->dialog_bullet; + gss->hotdot = ogss->hotdot; + gss->hotdotouter = ogss->hotdotouter; + gss->uniqueid = ogss->uniqueid; + gss->numgui = ogss->numgui; + for (int i = 0; i < 10; ++i) { + SetFontInfoFromLegacyFlags(gss->fonts[i], ogss->fontflags[i]); + gss->fonts[i].Outline = ogss->fontoutline[i]; + } + + for (int i = 0; i < LEGACY_MAX_SPRITES_V25; ++i) { + gss->SpriteInfos[i].Flags = ogss->spriteflags[i]; + } + + memcpy(&gss->invinfo[0], &ogss->invinfo[0], 100 * sizeof(InventoryItemInfo)); + memcpy(&gss->mcurs[0], &ogss->mcurs[0], 10 * sizeof(MouseCursor)); + for (int i = 0; i < MAXGLOBALMES; i++) + gss->messages[i] = ogss->messages[i]; + gss->dict = ogss->dict; + gss->globalscript = ogss->globalscript; + gss->chars = nullptr; //ogss->chars; + gss->compiled_script = ogss->compiled_script; + gss->numcursors = 10; } -void GameSetupStruct::ReadFromSavegame(PStream in) -{ - // of GameSetupStruct - in->ReadArrayOfInt32(options, OPT_HIGHESTOPTION_321 + 1); - options[OPT_LIPSYNCTEXT] = in->ReadInt32(); - // of GameSetupStructBase - playercharacter = in->ReadInt32(); - dialog_bullet = in->ReadInt32(); - hotdot = in->ReadInt16(); - hotdotouter = in->ReadInt16(); - invhotdotsprite = in->ReadInt32(); - default_lipsync_frame = in->ReadInt32(); +void GameSetupStruct::ReadFromSavegame(PStream in) { + // of GameSetupStruct + in->ReadArrayOfInt32(options, OPT_HIGHESTOPTION_321 + 1); + options[OPT_LIPSYNCTEXT] = in->ReadInt32(); + // of GameSetupStructBase + playercharacter = in->ReadInt32(); + dialog_bullet = in->ReadInt32(); + hotdot = in->ReadInt16(); + hotdotouter = in->ReadInt16(); + invhotdotsprite = in->ReadInt32(); + default_lipsync_frame = in->ReadInt32(); } -void GameSetupStruct::WriteForSavegame(PStream out) -{ - // of GameSetupStruct - out->WriteArrayOfInt32(options, OPT_HIGHESTOPTION_321 + 1); - out->WriteInt32(options[OPT_LIPSYNCTEXT]); - // of GameSetupStructBase - out->WriteInt32(playercharacter); - out->WriteInt32(dialog_bullet); - out->WriteInt16(hotdot); - out->WriteInt16(hotdotouter); - out->WriteInt32(invhotdotsprite); - out->WriteInt32(default_lipsync_frame); +void GameSetupStruct::WriteForSavegame(PStream out) { + // of GameSetupStruct + out->WriteArrayOfInt32(options, OPT_HIGHESTOPTION_321 + 1); + out->WriteInt32(options[OPT_LIPSYNCTEXT]); + // of GameSetupStructBase + out->WriteInt32(playercharacter); + out->WriteInt32(dialog_bullet); + out->WriteInt16(hotdot); + out->WriteInt16(hotdotouter); + out->WriteInt32(invhotdotsprite); + out->WriteInt32(default_lipsync_frame); } diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index dce49ef7d8da..43d689602216 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -33,16 +33,14 @@ #include "game/customproperties.h" #include "game/main_game_file.h" // TODO: constants to separate header or split out reading functions -namespace AGS -{ - namespace Common - { - struct AssetLibInfo; - struct Interaction; - struct InteractionScripts; - typedef std::shared_ptr PInteraction; - typedef std::shared_ptr PInteractionScripts; - } +namespace AGS { +namespace Common { +struct AssetLibInfo; +struct Interaction; +struct InteractionScripts; +typedef std::shared_ptr PInteraction; +typedef std::shared_ptr PInteractionScripts; +} } using AGS::Common::PInteraction; @@ -53,118 +51,120 @@ struct OldGameSetupStruct; // TODO: split GameSetupStruct into struct used to hold loaded game data, and actual runtime object struct GameSetupStruct: public GameSetupStructBase { - // This array is used only to read data into; - // font parameters are then put and queried in the fonts module - // TODO: split into installation params (used only when reading) and runtime params - std::vector fonts; - InventoryItemInfo invinfo[MAX_INV]; - MouseCursor mcurs[MAX_CURSOR]; - std::vector intrChar; - PInteraction intrInv[MAX_INV]; - std::vector charScripts; - std::vector invScripts; - // TODO: why we do not use this in the engine instead of - // loaded_game_file_version? - int filever; // just used by editor - Common::String compiled_with; // version of AGS this data was created by - char lipSyncFrameLetters[MAXLIPSYNCFRAMES][50]; - AGS::Common::PropertySchema propSchema; - std::vector charProps; - AGS::Common::StringIMap invProps[MAX_INV]; - // NOTE: although the view names are stored in game data, they are never - // used, nor registered as script exports; numeric IDs are used to - // reference views instead. - std::vector viewNames; - Common::String invScriptNames[MAX_INV]; - std::vector dialogScriptNames; - char guid[MAX_GUID_LENGTH]; - char saveGameFileExtension[MAX_SG_EXT_LENGTH]; - char saveGameFolderName[MAX_SG_FOLDER_LEN]; - int roomCount; - int *roomNumbers; - char **roomNames; - std::vector audioClips; - std::vector audioClipTypes; - // A clip to play when player gains score in game - // TODO: find out why OPT_SCORESOUND option cannot be used to store this in >=3.2 games - int scoreClipID; - - // TODO: I converted original array of sprite infos to vector here, because - // statistically in most games sprites go in long continious sequences with minimal - // gaps, and standard hash-map will have relatively big memory overhead compared. - // Of course vector will not behave very well if user has created e.g. only - // sprite #1 and sprite #1000000. For that reason I decided to still limit static - // sprite count to some reasonable number for the time being. Dynamic sprite IDs are - // added in sequence, so there won't be any issue with these. - // There could be other collection types, more optimal for this case. For example, - // we could use a kind of hash map containing fixed-sized arrays, where size of - // array is calculated based on key spread factor. - std::vector SpriteInfos; - - // Get game's native color depth (bits per pixel) - inline int GetColorDepth() const { return color_depth * 8; } - - - GameSetupStruct(); - ~GameSetupStruct(); - - void Free(); - - // [IKM] Game struct loading code is moved here from Engine's load_game_file - // function; for now it is not supposed to be called by Editor; although it - // is possible that eventually will be. - // - // Since reading game data is made in a bit inconvenient way I had to - // a) divide process into three functions (there's some extra stuff - // being read between them; - // b) use a helper struct to pass some arguments - // - // I also had to move BuildAudioClipArray from the engine and make it - // GameSetupStruct member. - - //-------------------------------------------------------------------- - // Do not call these directly - //------------------------------ - // Part 1 - void read_savegame_info(Common::Stream *in, GameDataVersion data_ver); - void read_font_infos(Common::Stream *in, GameDataVersion data_ver); - HGameFileError read_cursors(Common::Stream *in, GameDataVersion data_ver); - void read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver); - void read_words_dictionary(Common::Stream *in); - - void ReadInvInfo_Aligned(Common::Stream *in); - void WriteInvInfo_Aligned(Common::Stream *out); - void ReadMouseCursors_Aligned(Common::Stream *in); - void WriteMouseCursors_Aligned(Common::Stream *out); - //------------------------------ - // Part 2 - void read_characters(Common::Stream *in, GameDataVersion data_ver); - void read_lipsync(Common::Stream *in, GameDataVersion data_ver); - void read_messages(Common::Stream *in, GameDataVersion data_ver); - - void ReadCharacters_Aligned(Common::Stream *in); - void WriteCharacters_Aligned(Common::Stream *out); - //------------------------------ - // Part 3 - HGameFileError read_customprops(Common::Stream *in, GameDataVersion data_ver); - HGameFileError read_audio(Common::Stream *in, GameDataVersion data_ver); - void read_room_names(Common::Stream *in, GameDataVersion data_ver); - - void ReadAudioClips_Aligned(Common::Stream *in, size_t count); - //-------------------------------------------------------------------- - - // Functions for reading and writing appropriate data from/to save game - void ReadFromSaveGame_v321(Common::Stream *in, char* gswas, ccScript* compsc, CharacterInfo* chwas, - WordsDictionary *olddict, char** mesbk); - - void ReadFromSavegame(Common::PStream in); - void WriteForSavegame(Common::PStream out); + // This array is used only to read data into; + // font parameters are then put and queried in the fonts module + // TODO: split into installation params (used only when reading) and runtime params + std::vector fonts; + InventoryItemInfo invinfo[MAX_INV]; + MouseCursor mcurs[MAX_CURSOR]; + std::vector intrChar; + PInteraction intrInv[MAX_INV]; + std::vector charScripts; + std::vector invScripts; + // TODO: why we do not use this in the engine instead of + // loaded_game_file_version? + int filever; // just used by editor + Common::String compiled_with; // version of AGS this data was created by + char lipSyncFrameLetters[MAXLIPSYNCFRAMES][50]; + AGS::Common::PropertySchema propSchema; + std::vector charProps; + AGS::Common::StringIMap invProps[MAX_INV]; + // NOTE: although the view names are stored in game data, they are never + // used, nor registered as script exports; numeric IDs are used to + // reference views instead. + std::vector viewNames; + Common::String invScriptNames[MAX_INV]; + std::vector dialogScriptNames; + char guid[MAX_GUID_LENGTH]; + char saveGameFileExtension[MAX_SG_EXT_LENGTH]; + char saveGameFolderName[MAX_SG_FOLDER_LEN]; + int roomCount; + int *roomNumbers; + char **roomNames; + std::vector audioClips; + std::vector audioClipTypes; + // A clip to play when player gains score in game + // TODO: find out why OPT_SCORESOUND option cannot be used to store this in >=3.2 games + int scoreClipID; + + // TODO: I converted original array of sprite infos to vector here, because + // statistically in most games sprites go in long continious sequences with minimal + // gaps, and standard hash-map will have relatively big memory overhead compared. + // Of course vector will not behave very well if user has created e.g. only + // sprite #1 and sprite #1000000. For that reason I decided to still limit static + // sprite count to some reasonable number for the time being. Dynamic sprite IDs are + // added in sequence, so there won't be any issue with these. + // There could be other collection types, more optimal for this case. For example, + // we could use a kind of hash map containing fixed-sized arrays, where size of + // array is calculated based on key spread factor. + std::vector SpriteInfos; + + // Get game's native color depth (bits per pixel) + inline int GetColorDepth() const { + return color_depth * 8; + } + + + GameSetupStruct(); + ~GameSetupStruct(); + + void Free(); + + // [IKM] Game struct loading code is moved here from Engine's load_game_file + // function; for now it is not supposed to be called by Editor; although it + // is possible that eventually will be. + // + // Since reading game data is made in a bit inconvenient way I had to + // a) divide process into three functions (there's some extra stuff + // being read between them; + // b) use a helper struct to pass some arguments + // + // I also had to move BuildAudioClipArray from the engine and make it + // GameSetupStruct member. + + //-------------------------------------------------------------------- + // Do not call these directly + //------------------------------ + // Part 1 + void read_savegame_info(Common::Stream *in, GameDataVersion data_ver); + void read_font_infos(Common::Stream *in, GameDataVersion data_ver); + HGameFileError read_cursors(Common::Stream *in, GameDataVersion data_ver); + void read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver); + void read_words_dictionary(Common::Stream *in); + + void ReadInvInfo_Aligned(Common::Stream *in); + void WriteInvInfo_Aligned(Common::Stream *out); + void ReadMouseCursors_Aligned(Common::Stream *in); + void WriteMouseCursors_Aligned(Common::Stream *out); + //------------------------------ + // Part 2 + void read_characters(Common::Stream *in, GameDataVersion data_ver); + void read_lipsync(Common::Stream *in, GameDataVersion data_ver); + void read_messages(Common::Stream *in, GameDataVersion data_ver); + + void ReadCharacters_Aligned(Common::Stream *in); + void WriteCharacters_Aligned(Common::Stream *out); + //------------------------------ + // Part 3 + HGameFileError read_customprops(Common::Stream *in, GameDataVersion data_ver); + HGameFileError read_audio(Common::Stream *in, GameDataVersion data_ver); + void read_room_names(Common::Stream *in, GameDataVersion data_ver); + + void ReadAudioClips_Aligned(Common::Stream *in, size_t count); + //-------------------------------------------------------------------- + + // Functions for reading and writing appropriate data from/to save game + void ReadFromSaveGame_v321(Common::Stream *in, char *gswas, ccScript *compsc, CharacterInfo *chwas, + WordsDictionary *olddict, char **mesbk); + + void ReadFromSavegame(Common::PStream in); + void WriteForSavegame(Common::PStream out); }; //============================================================================= // TODO: find out how this function was supposed to be used -void ConvertOldGameStruct (OldGameSetupStruct *ogss, GameSetupStruct *gss); +void ConvertOldGameStruct(OldGameSetupStruct *ogss, GameSetupStruct *gss); // Finds an audio clip using legacy convention index -ScriptAudioClip* GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num); +ScriptAudioClip *GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num); #endif diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp index e3faab100650..810697592d74 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.cpp +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -30,246 +30,224 @@ using AGS::Common::Stream; GameSetupStructBase::GameSetupStructBase() - : numviews(0) - , numcharacters(0) - , playercharacter(-1) - , totalscore(0) - , numinvitems(0) - , numdialog(0) - , numdlgmessage(0) - , numfonts(0) - , color_depth(0) - , target_win(0) - , dialog_bullet(0) - , hotdot(0) - , hotdotouter(0) - , uniqueid(0) - , numgui(0) - , numcursors(0) - , default_lipsync_frame(0) - , invhotdotsprite(0) - , dict(nullptr) - , globalscript(nullptr) - , chars(nullptr) - , compiled_script(nullptr) - , load_messages(nullptr) - , load_dictionary(false) - , load_compiled_script(false) - , _resolutionType(kGameResolution_Undefined) - , _dataUpscaleMult(1) - , _screenUpscaleMult(1) -{ - memset(gamename, 0, sizeof(gamename)); - memset(options, 0, sizeof(options)); - memset(paluses, 0, sizeof(paluses)); - memset(defpal, 0, sizeof(defpal)); - memset(reserved, 0, sizeof(reserved)); - memset(messages, 0, sizeof(messages)); + : numviews(0) + , numcharacters(0) + , playercharacter(-1) + , totalscore(0) + , numinvitems(0) + , numdialog(0) + , numdlgmessage(0) + , numfonts(0) + , color_depth(0) + , target_win(0) + , dialog_bullet(0) + , hotdot(0) + , hotdotouter(0) + , uniqueid(0) + , numgui(0) + , numcursors(0) + , default_lipsync_frame(0) + , invhotdotsprite(0) + , dict(nullptr) + , globalscript(nullptr) + , chars(nullptr) + , compiled_script(nullptr) + , load_messages(nullptr) + , load_dictionary(false) + , load_compiled_script(false) + , _resolutionType(kGameResolution_Undefined) + , _dataUpscaleMult(1) + , _screenUpscaleMult(1) { + memset(gamename, 0, sizeof(gamename)); + memset(options, 0, sizeof(options)); + memset(paluses, 0, sizeof(paluses)); + memset(defpal, 0, sizeof(defpal)); + memset(reserved, 0, sizeof(reserved)); + memset(messages, 0, sizeof(messages)); } -GameSetupStructBase::~GameSetupStructBase() -{ - Free(); +GameSetupStructBase::~GameSetupStructBase() { + Free(); } -void GameSetupStructBase::Free() -{ - for (int i = 0; i < MAXGLOBALMES; ++i) - { - delete[] messages[i]; - messages[i] = nullptr; - } - delete[] load_messages; - load_messages = nullptr; - delete dict; - dict = nullptr; - delete globalscript; - globalscript = nullptr; - delete compiled_script; - compiled_script = nullptr; - delete[] chars; - chars = nullptr; +void GameSetupStructBase::Free() { + for (int i = 0; i < MAXGLOBALMES; ++i) { + delete[] messages[i]; + messages[i] = nullptr; + } + delete[] load_messages; + load_messages = nullptr; + delete dict; + dict = nullptr; + delete globalscript; + globalscript = nullptr; + delete compiled_script; + compiled_script = nullptr; + delete[] chars; + chars = nullptr; } -void GameSetupStructBase::SetDefaultResolution(GameResolutionType type) -{ - SetDefaultResolution(type, Size()); +void GameSetupStructBase::SetDefaultResolution(GameResolutionType type) { + SetDefaultResolution(type, Size()); } -void GameSetupStructBase::SetDefaultResolution(Size size) -{ - SetDefaultResolution(kGameResolution_Custom, size); +void GameSetupStructBase::SetDefaultResolution(Size size) { + SetDefaultResolution(kGameResolution_Custom, size); } -void GameSetupStructBase::SetDefaultResolution(GameResolutionType type, Size size) -{ - // Calculate native res first then remember it - SetNativeResolution(type, size); - _defGameResolution = _gameResolution; - // Setup data resolution according to legacy settings (if set) - _dataResolution = _defGameResolution; - if (IsLegacyHiRes() && options[OPT_NATIVECOORDINATES] == 0) - { - _dataResolution = _defGameResolution / HIRES_COORD_MULTIPLIER; - } - OnResolutionSet(); +void GameSetupStructBase::SetDefaultResolution(GameResolutionType type, Size size) { + // Calculate native res first then remember it + SetNativeResolution(type, size); + _defGameResolution = _gameResolution; + // Setup data resolution according to legacy settings (if set) + _dataResolution = _defGameResolution; + if (IsLegacyHiRes() && options[OPT_NATIVECOORDINATES] == 0) { + _dataResolution = _defGameResolution / HIRES_COORD_MULTIPLIER; + } + OnResolutionSet(); } -void GameSetupStructBase::SetNativeResolution(GameResolutionType type, Size game_res) -{ - if (type == kGameResolution_Custom) - { - _resolutionType = kGameResolution_Custom; - _gameResolution = game_res; - _letterboxSize = _gameResolution; - } - else - { - _resolutionType = type; - _gameResolution = ResolutionTypeToSize(_resolutionType, IsLegacyLetterbox()); - _letterboxSize = ResolutionTypeToSize(_resolutionType, false); - } +void GameSetupStructBase::SetNativeResolution(GameResolutionType type, Size game_res) { + if (type == kGameResolution_Custom) { + _resolutionType = kGameResolution_Custom; + _gameResolution = game_res; + _letterboxSize = _gameResolution; + } else { + _resolutionType = type; + _gameResolution = ResolutionTypeToSize(_resolutionType, IsLegacyLetterbox()); + _letterboxSize = ResolutionTypeToSize(_resolutionType, false); + } } -void GameSetupStructBase::SetGameResolution(GameResolutionType type) -{ - SetNativeResolution(type, Size()); - OnResolutionSet(); +void GameSetupStructBase::SetGameResolution(GameResolutionType type) { + SetNativeResolution(type, Size()); + OnResolutionSet(); } -void GameSetupStructBase::SetGameResolution(Size game_res) -{ - SetNativeResolution(kGameResolution_Custom, game_res); - OnResolutionSet(); +void GameSetupStructBase::SetGameResolution(Size game_res) { + SetNativeResolution(kGameResolution_Custom, game_res); + OnResolutionSet(); } -void GameSetupStructBase::OnResolutionSet() -{ - // The final data-to-game multiplier is always set after actual game resolution (not default one) - if (!_dataResolution.IsNull()) - _dataUpscaleMult = _gameResolution.Width / _dataResolution.Width; - else - _dataUpscaleMult = 1; - if (!_defGameResolution.IsNull()) - _screenUpscaleMult = _gameResolution.Width / _defGameResolution.Width; - else - _screenUpscaleMult = 1; - _relativeUIMult = IsLegacyHiRes() ? HIRES_COORD_MULTIPLIER : 1; +void GameSetupStructBase::OnResolutionSet() { + // The final data-to-game multiplier is always set after actual game resolution (not default one) + if (!_dataResolution.IsNull()) + _dataUpscaleMult = _gameResolution.Width / _dataResolution.Width; + else + _dataUpscaleMult = 1; + if (!_defGameResolution.IsNull()) + _screenUpscaleMult = _gameResolution.Width / _defGameResolution.Width; + else + _screenUpscaleMult = 1; + _relativeUIMult = IsLegacyHiRes() ? HIRES_COORD_MULTIPLIER : 1; } -void GameSetupStructBase::ReadFromFile(Stream *in) -{ - in->Read(&gamename[0], GAME_NAME_LENGTH); - in->ReadArrayOfInt32(options, MAX_OPTIONS); - if (loaded_game_file_version < kGameVersion_340_4) - { // TODO: this should probably be possible to deduce script API level - // using game data version and other options like OPT_STRICTSCRIPTING - options[OPT_BASESCRIPTAPI] = kScriptAPI_Undefined; - options[OPT_SCRIPTCOMPATLEV] = kScriptAPI_Undefined; - } - in->Read(&paluses[0], 256); - // colors are an array of chars - in->Read(&defpal[0], sizeof(color)*256); - numviews = in->ReadInt32(); - numcharacters = in->ReadInt32(); - playercharacter = in->ReadInt32(); - totalscore = in->ReadInt32(); - numinvitems = in->ReadInt16(); - numdialog = in->ReadInt32(); - numdlgmessage = in->ReadInt32(); - numfonts = in->ReadInt32(); - color_depth = in->ReadInt32(); - target_win = in->ReadInt32(); - dialog_bullet = in->ReadInt32(); - hotdot = in->ReadInt16(); - hotdotouter = in->ReadInt16(); - uniqueid = in->ReadInt32(); - numgui = in->ReadInt32(); - numcursors = in->ReadInt32(); - GameResolutionType resolution_type = (GameResolutionType)in->ReadInt32(); - Size game_size; - if (resolution_type == kGameResolution_Custom && loaded_game_file_version >= kGameVersion_330) - { - game_size.Width = in->ReadInt32(); - game_size.Height = in->ReadInt32(); - } - SetDefaultResolution(resolution_type, game_size); - - default_lipsync_frame = in->ReadInt32(); - invhotdotsprite = in->ReadInt32(); - in->ReadArrayOfInt32(reserved, NUM_INTS_RESERVED); - load_messages = new int32_t[MAXGLOBALMES]; - in->ReadArrayOfInt32(load_messages, MAXGLOBALMES); - - // - GameSetupStruct::read_words_dictionary() checks load_dictionary - // - load_game_file() checks load_compiled_script - load_dictionary = in->ReadInt32() != 0; - in->ReadInt32(); // globalscript - in->ReadInt32(); // chars - load_compiled_script = in->ReadInt32() != 0; +void GameSetupStructBase::ReadFromFile(Stream *in) { + in->Read(&gamename[0], GAME_NAME_LENGTH); + in->ReadArrayOfInt32(options, MAX_OPTIONS); + if (loaded_game_file_version < kGameVersion_340_4) { + // TODO: this should probably be possible to deduce script API level + // using game data version and other options like OPT_STRICTSCRIPTING + options[OPT_BASESCRIPTAPI] = kScriptAPI_Undefined; + options[OPT_SCRIPTCOMPATLEV] = kScriptAPI_Undefined; + } + in->Read(&paluses[0], 256); + // colors are an array of chars + in->Read(&defpal[0], sizeof(color) * 256); + numviews = in->ReadInt32(); + numcharacters = in->ReadInt32(); + playercharacter = in->ReadInt32(); + totalscore = in->ReadInt32(); + numinvitems = in->ReadInt16(); + numdialog = in->ReadInt32(); + numdlgmessage = in->ReadInt32(); + numfonts = in->ReadInt32(); + color_depth = in->ReadInt32(); + target_win = in->ReadInt32(); + dialog_bullet = in->ReadInt32(); + hotdot = in->ReadInt16(); + hotdotouter = in->ReadInt16(); + uniqueid = in->ReadInt32(); + numgui = in->ReadInt32(); + numcursors = in->ReadInt32(); + GameResolutionType resolution_type = (GameResolutionType)in->ReadInt32(); + Size game_size; + if (resolution_type == kGameResolution_Custom && loaded_game_file_version >= kGameVersion_330) { + game_size.Width = in->ReadInt32(); + game_size.Height = in->ReadInt32(); + } + SetDefaultResolution(resolution_type, game_size); + + default_lipsync_frame = in->ReadInt32(); + invhotdotsprite = in->ReadInt32(); + in->ReadArrayOfInt32(reserved, NUM_INTS_RESERVED); + load_messages = new int32_t[MAXGLOBALMES]; + in->ReadArrayOfInt32(load_messages, MAXGLOBALMES); + + // - GameSetupStruct::read_words_dictionary() checks load_dictionary + // - load_game_file() checks load_compiled_script + load_dictionary = in->ReadInt32() != 0; + in->ReadInt32(); // globalscript + in->ReadInt32(); // chars + load_compiled_script = in->ReadInt32() != 0; } -void GameSetupStructBase::WriteToFile(Stream *out) -{ - out->Write(&gamename[0], 50); - out->WriteArrayOfInt32(options, 100); - out->Write(&paluses[0], 256); - // colors are an array of chars - out->Write(&defpal[0], sizeof(color)*256); - out->WriteInt32(numviews); - out->WriteInt32(numcharacters); - out->WriteInt32(playercharacter); - out->WriteInt32(totalscore); - out->WriteInt16(numinvitems); - out->WriteInt32(numdialog); - out->WriteInt32(numdlgmessage); - out->WriteInt32(numfonts); - out->WriteInt32(color_depth); - out->WriteInt32(target_win); - out->WriteInt32(dialog_bullet); - out->WriteInt16(hotdot); - out->WriteInt16(hotdotouter); - out->WriteInt32(uniqueid); - out->WriteInt32(numgui); - out->WriteInt32(numcursors); - out->WriteInt32(_resolutionType); - if (_resolutionType == kGameResolution_Custom) - { - out->WriteInt32(_defGameResolution.Width); - out->WriteInt32(_defGameResolution.Height); - } - out->WriteInt32(default_lipsync_frame); - out->WriteInt32(invhotdotsprite); - out->WriteArrayOfInt32(reserved, 17); - for (int i = 0; i < MAXGLOBALMES; ++i) - { - out->WriteInt32(messages[i] ? 1 : 0); - } - out->WriteInt32(dict ? 1 : 0); - out->WriteInt32(0); // globalscript - out->WriteInt32(0); // chars - out->WriteInt32(compiled_script ? 1 : 0); +void GameSetupStructBase::WriteToFile(Stream *out) { + out->Write(&gamename[0], 50); + out->WriteArrayOfInt32(options, 100); + out->Write(&paluses[0], 256); + // colors are an array of chars + out->Write(&defpal[0], sizeof(color) * 256); + out->WriteInt32(numviews); + out->WriteInt32(numcharacters); + out->WriteInt32(playercharacter); + out->WriteInt32(totalscore); + out->WriteInt16(numinvitems); + out->WriteInt32(numdialog); + out->WriteInt32(numdlgmessage); + out->WriteInt32(numfonts); + out->WriteInt32(color_depth); + out->WriteInt32(target_win); + out->WriteInt32(dialog_bullet); + out->WriteInt16(hotdot); + out->WriteInt16(hotdotouter); + out->WriteInt32(uniqueid); + out->WriteInt32(numgui); + out->WriteInt32(numcursors); + out->WriteInt32(_resolutionType); + if (_resolutionType == kGameResolution_Custom) { + out->WriteInt32(_defGameResolution.Width); + out->WriteInt32(_defGameResolution.Height); + } + out->WriteInt32(default_lipsync_frame); + out->WriteInt32(invhotdotsprite); + out->WriteArrayOfInt32(reserved, 17); + for (int i = 0; i < MAXGLOBALMES; ++i) { + out->WriteInt32(messages[i] ? 1 : 0); + } + out->WriteInt32(dict ? 1 : 0); + out->WriteInt32(0); // globalscript + out->WriteInt32(0); // chars + out->WriteInt32(compiled_script ? 1 : 0); } -Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox) -{ - switch (resolution) - { - case kGameResolution_Default: - case kGameResolution_320x200: - return letterbox ? Size(320, 240) : Size(320, 200); - case kGameResolution_320x240: - return Size(320, 240); - case kGameResolution_640x400: - return letterbox ? Size(640, 480) : Size(640, 400); - case kGameResolution_640x480: - return Size(640, 480); - case kGameResolution_800x600: - return Size(800, 600); - case kGameResolution_1024x768: - return Size(1024, 768); - case kGameResolution_1280x720: - return Size(1280,720); - } - return Size(); +Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox) { + switch (resolution) { + case kGameResolution_Default: + case kGameResolution_320x200: + return letterbox ? Size(320, 240) : Size(320, 200); + case kGameResolution_320x240: + return Size(320, 240); + case kGameResolution_640x400: + return letterbox ? Size(640, 480) : Size(640, 400); + case kGameResolution_640x480: + return Size(640, 480); + case kGameResolution_800x600: + return Size(800, 600); + case kGameResolution_1024x768: + return Size(1024, 768); + case kGameResolution_1280x720: + return Size(1280, 720); + } + return Size(); } diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h index 1dd2c6fc2a0b..70b0818ad37f 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.h +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -29,7 +29,11 @@ #include "util/wgt2allg.h" // color (allegro RGB) // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later struct WordsDictionary; @@ -38,190 +42,206 @@ struct ccScript; struct GameSetupStructBase { - static const int GAME_NAME_LENGTH = 50; - static const int MAX_OPTIONS = 100; - static const int NUM_INTS_RESERVED = 17; - - char gamename[GAME_NAME_LENGTH]; - int options[MAX_OPTIONS]; - unsigned char paluses[256]; - color defpal[256]; - int numviews; - int numcharacters; - int playercharacter; - int totalscore; - short numinvitems; - int numdialog, numdlgmessage; - int numfonts; - int color_depth; // in bytes per pixel (ie. 1 or 2) - int target_win; - int dialog_bullet; // 0 for none, otherwise slot num of bullet point - unsigned short hotdot, hotdotouter; // inv cursor hotspot dot color - int uniqueid; // random key identifying the game - int numgui; - int numcursors; - int default_lipsync_frame; // used for unknown chars - int invhotdotsprite; - int reserved[NUM_INTS_RESERVED]; - char *messages[MAXGLOBALMES]; - WordsDictionary *dict; - char *globalscript; - CharacterInfo *chars; - ccScript *compiled_script; - - int *load_messages; - bool load_dictionary; - bool load_compiled_script; - // [IKM] 2013-03-30 - // NOTE: it looks like nor 'globalscript', not 'compiled_script' are used - // to store actual script data anytime; 'ccScript* gamescript' global - // pointer is used for that instead. - - GameSetupStructBase(); - ~GameSetupStructBase(); - void Free(); - void SetDefaultResolution(GameResolutionType type); - void SetDefaultResolution(Size game_res); - void SetGameResolution(GameResolutionType type); - void SetGameResolution(Size game_res); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); - - - // - // ** On game resolution. - // - // Game resolution is a size of a native game screen in pixels. - // This is the "game resolution" that developer sets up in AGS Editor. - // It is in the same units in which sprite and font sizes are defined. - // - // Graphic renderer may scale and stretch game's frame as requested by - // player or system, which will not affect native coordinates in any way. - // - // ** Legacy upscale mode. - // - // In the past engine had a separation between logical and native screen - // coordinates and supported running games "upscaled". E.g. 320x200 games - // could be run as 640x400. This was not done by simply stretching final - // game's drawn frame to the larger window, but by multiplying all data - // containing coordinates and graphics either on load or real-time. - // Games of 640x400 and above were scripted and set up in coordinate units - // that were always x2 times smaller than the one developer chose. - // For example, choosing a 640x400 resolution would make game draw itself - // as 640x400, but all the game logic (object properties, script commands) - // would work in 320x200 (this also let run 640x400 downscaled to 320x200). - // Ignoring the obvious complications, the known benefit from such approach - // was that developers could supply separate sets of fonts and sprites for - // low-res and high-res modes. - // The 3rd generation of AGS still allows to achieve same effect by using - // backwards-compatible option (although it is not recommended except when - // importing and continuing old projects). - // - // In order to support this legacy behavior we have a set of functions for - // coordinate conversion. They are required to move from "data" resolution - // to "final game" resolution and back. - // - // Some of the script commands, as well as some internal engine data use - // coordinates in "game resolution" instead (this should be documented). - // In such case there's another conversion which translates these from - // default to actual resolution; e.g. when 320x200 game is run as 640x400 - // they should be multiplied by 2. - // - // ** TODO. - // - // Truth be told, all this is still implemented incorrectly, because no one - // found time to rewrite the thing. The correct way would perhaps be: - // 1) treat old games as x2 lower resolution than they say. - // 2) support drawing particular sprites and texts in x2 higher resolution - // (assuming display resolution allows). The latter is potentially enabled - // by "sprite batches" system in the engine and will benefit new games too. - - inline GameResolutionType GetResolutionType() const - { - return _resolutionType; - } - - // Get actual game's resolution - const Size &GetGameRes() const { return _gameResolution; } - // Get default resolution the game was created for; - // this is usually equal to GetGameRes except for legacy modes. - const Size &GetDefaultRes() const { return _defGameResolution; } - // Get data & script resolution; - // this is usually equal to GetGameRes except for legacy modes. - const Size &GetDataRes() const { return _dataResolution; } - // Get game data-->final game resolution coordinate multiplier - inline int GetDataUpscaleMult() const { return _dataUpscaleMult; } - // Get multiplier for various default UI sizes, meant to keep UI looks - // more or less readable in any game resolution. - // TODO: find a better solution for UI sizes, perhaps make variables. - inline int GetRelativeUIMult() const { return _relativeUIMult; } - // Get game default res-->final game resolution coordinate multiplier; - // used to convert coordinates from original game res to actual one - inline int GetScreenUpscaleMult() const { return _screenUpscaleMult; } - // Tells if game allows assets defined in relative resolution; - // that is - have to be converted to this game resolution type - inline bool AllowRelativeRes() const { return options[OPT_RELATIVEASSETRES] != 0; } - // Legacy definition of high and low game resolution. - // Used to determine certain hardcoded coordinate conversion logic, but - // does not make much sense today when the resolution is arbitrary. - inline bool IsLegacyHiRes() const - { - if (_resolutionType == kGameResolution_Custom) - return (_gameResolution.Width * _gameResolution.Height) > (320 * 240); - return ::IsLegacyHiRes(_resolutionType); - } - // Tells if data has coordinates in default game resolution - inline bool IsDataInNativeCoordinates() const { return options[OPT_NATIVECOORDINATES] != 0; } - - // Tells if game runs in native letterbox mode (legacy option) - inline bool IsLegacyLetterbox() const { return options[OPT_LETTERBOX] != 0; } - // Get letterboxed frame size - const Size &GetLetterboxSize() const { return _letterboxSize; } - - // Room region/hotspot masks are traditionally 1:1 of the room's size in - // low-resolution games and 1:2 of the room size in high-resolution games. - // This also means that mask relation to data resolution is 1:1 if the - // game uses low-res coordinates in script and 1:2 if high-res. - - // Test if the game is built around old audio system - inline bool IsLegacyAudioSystem() const - { - return loaded_game_file_version < kGameVersion_320; - } - - // Returns the expected filename of a digital audio package - inline AGS::Common::String GetAudioVOXName() const - { - return IsLegacyAudioSystem() ? "music.vox" : "audio.vox"; - } + static const int GAME_NAME_LENGTH = 50; + static const int MAX_OPTIONS = 100; + static const int NUM_INTS_RESERVED = 17; + + char gamename[GAME_NAME_LENGTH]; + int options[MAX_OPTIONS]; + unsigned char paluses[256]; + color defpal[256]; + int numviews; + int numcharacters; + int playercharacter; + int totalscore; + short numinvitems; + int numdialog, numdlgmessage; + int numfonts; + int color_depth; // in bytes per pixel (ie. 1 or 2) + int target_win; + int dialog_bullet; // 0 for none, otherwise slot num of bullet point + unsigned short hotdot, hotdotouter; // inv cursor hotspot dot color + int uniqueid; // random key identifying the game + int numgui; + int numcursors; + int default_lipsync_frame; // used for unknown chars + int invhotdotsprite; + int reserved[NUM_INTS_RESERVED]; + char *messages[MAXGLOBALMES]; + WordsDictionary *dict; + char *globalscript; + CharacterInfo *chars; + ccScript *compiled_script; + + int *load_messages; + bool load_dictionary; + bool load_compiled_script; + // [IKM] 2013-03-30 + // NOTE: it looks like nor 'globalscript', not 'compiled_script' are used + // to store actual script data anytime; 'ccScript* gamescript' global + // pointer is used for that instead. + + GameSetupStructBase(); + ~GameSetupStructBase(); + void Free(); + void SetDefaultResolution(GameResolutionType type); + void SetDefaultResolution(Size game_res); + void SetGameResolution(GameResolutionType type); + void SetGameResolution(Size game_res); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + + + // + // ** On game resolution. + // + // Game resolution is a size of a native game screen in pixels. + // This is the "game resolution" that developer sets up in AGS Editor. + // It is in the same units in which sprite and font sizes are defined. + // + // Graphic renderer may scale and stretch game's frame as requested by + // player or system, which will not affect native coordinates in any way. + // + // ** Legacy upscale mode. + // + // In the past engine had a separation between logical and native screen + // coordinates and supported running games "upscaled". E.g. 320x200 games + // could be run as 640x400. This was not done by simply stretching final + // game's drawn frame to the larger window, but by multiplying all data + // containing coordinates and graphics either on load or real-time. + // Games of 640x400 and above were scripted and set up in coordinate units + // that were always x2 times smaller than the one developer chose. + // For example, choosing a 640x400 resolution would make game draw itself + // as 640x400, but all the game logic (object properties, script commands) + // would work in 320x200 (this also let run 640x400 downscaled to 320x200). + // Ignoring the obvious complications, the known benefit from such approach + // was that developers could supply separate sets of fonts and sprites for + // low-res and high-res modes. + // The 3rd generation of AGS still allows to achieve same effect by using + // backwards-compatible option (although it is not recommended except when + // importing and continuing old projects). + // + // In order to support this legacy behavior we have a set of functions for + // coordinate conversion. They are required to move from "data" resolution + // to "final game" resolution and back. + // + // Some of the script commands, as well as some internal engine data use + // coordinates in "game resolution" instead (this should be documented). + // In such case there's another conversion which translates these from + // default to actual resolution; e.g. when 320x200 game is run as 640x400 + // they should be multiplied by 2. + // + // ** TODO. + // + // Truth be told, all this is still implemented incorrectly, because no one + // found time to rewrite the thing. The correct way would perhaps be: + // 1) treat old games as x2 lower resolution than they say. + // 2) support drawing particular sprites and texts in x2 higher resolution + // (assuming display resolution allows). The latter is potentially enabled + // by "sprite batches" system in the engine and will benefit new games too. + + inline GameResolutionType GetResolutionType() const { + return _resolutionType; + } + + // Get actual game's resolution + const Size &GetGameRes() const { + return _gameResolution; + } + // Get default resolution the game was created for; + // this is usually equal to GetGameRes except for legacy modes. + const Size &GetDefaultRes() const { + return _defGameResolution; + } + // Get data & script resolution; + // this is usually equal to GetGameRes except for legacy modes. + const Size &GetDataRes() const { + return _dataResolution; + } + // Get game data-->final game resolution coordinate multiplier + inline int GetDataUpscaleMult() const { + return _dataUpscaleMult; + } + // Get multiplier for various default UI sizes, meant to keep UI looks + // more or less readable in any game resolution. + // TODO: find a better solution for UI sizes, perhaps make variables. + inline int GetRelativeUIMult() const { + return _relativeUIMult; + } + // Get game default res-->final game resolution coordinate multiplier; + // used to convert coordinates from original game res to actual one + inline int GetScreenUpscaleMult() const { + return _screenUpscaleMult; + } + // Tells if game allows assets defined in relative resolution; + // that is - have to be converted to this game resolution type + inline bool AllowRelativeRes() const { + return options[OPT_RELATIVEASSETRES] != 0; + } + // Legacy definition of high and low game resolution. + // Used to determine certain hardcoded coordinate conversion logic, but + // does not make much sense today when the resolution is arbitrary. + inline bool IsLegacyHiRes() const { + if (_resolutionType == kGameResolution_Custom) + return (_gameResolution.Width * _gameResolution.Height) > (320 * 240); + return ::IsLegacyHiRes(_resolutionType); + } + // Tells if data has coordinates in default game resolution + inline bool IsDataInNativeCoordinates() const { + return options[OPT_NATIVECOORDINATES] != 0; + } + + // Tells if game runs in native letterbox mode (legacy option) + inline bool IsLegacyLetterbox() const { + return options[OPT_LETTERBOX] != 0; + } + // Get letterboxed frame size + const Size &GetLetterboxSize() const { + return _letterboxSize; + } + + // Room region/hotspot masks are traditionally 1:1 of the room's size in + // low-resolution games and 1:2 of the room size in high-resolution games. + // This also means that mask relation to data resolution is 1:1 if the + // game uses low-res coordinates in script and 1:2 if high-res. + + // Test if the game is built around old audio system + inline bool IsLegacyAudioSystem() const { + return loaded_game_file_version < kGameVersion_320; + } + + // Returns the expected filename of a digital audio package + inline AGS::Common::String GetAudioVOXName() const { + return IsLegacyAudioSystem() ? "music.vox" : "audio.vox"; + } private: - void SetDefaultResolution(GameResolutionType type, Size game_res); - void SetNativeResolution(GameResolutionType type, Size game_res); - void OnResolutionSet(); - - // Game's native resolution ID, used to init following values. - GameResolutionType _resolutionType; - - // Determines game's default screen resolution. Use for the reference - // when comparing with actual screen resolution, which may be modified - // by certain overriding game modes. - Size _defGameResolution; - // Determines game's actual resolution. - Size _gameResolution; - // Determines resolution in which loaded data and script define coordinates - // and sizes (with very little exception). - Size _dataResolution; - // Letterboxed frame size. Used when old game is run in native letterbox - // mode. In all other situations is equal to game's resolution. - Size _letterboxSize; - - // Game logic to game resolution coordinate factor - int _dataUpscaleMult; - // Multiplier for various UI drawin sizes, meant to keep UI elements readable - int _relativeUIMult; - // Game default resolution to actual game resolution factor - int _screenUpscaleMult; + void SetDefaultResolution(GameResolutionType type, Size game_res); + void SetNativeResolution(GameResolutionType type, Size game_res); + void OnResolutionSet(); + + // Game's native resolution ID, used to init following values. + GameResolutionType _resolutionType; + + // Determines game's default screen resolution. Use for the reference + // when comparing with actual screen resolution, which may be modified + // by certain overriding game modes. + Size _defGameResolution; + // Determines game's actual resolution. + Size _gameResolution; + // Determines resolution in which loaded data and script define coordinates + // and sizes (with very little exception). + Size _dataResolution; + // Letterboxed frame size. Used when old game is run in native letterbox + // mode. In all other situations is equal to game's resolution. + Size _letterboxSize; + + // Game logic to game resolution coordinate factor + int _dataUpscaleMult; + // Multiplier for various UI drawin sizes, meant to keep UI elements readable + int _relativeUIMult; + // Game default resolution to actual game resolution factor + int _screenUpscaleMult; }; #endif diff --git a/engines/ags/shared/ac/gamestructdefines.h b/engines/ags/shared/ac/gamestructdefines.h index d079c08d0b8b..705c3bf37a0e 100644 --- a/engines/ags/shared/ac/gamestructdefines.h +++ b/engines/ags/shared/ac/gamestructdefines.h @@ -116,38 +116,35 @@ #define MAX_SG_EXT_LENGTH 20 #define MAX_SG_FOLDER_LEN 50 -enum GameResolutionType -{ - kGameResolution_Undefined = -1, - // definition of 320x200 in very old versions of the engine (somewhere pre-2.56) - kGameResolution_Default = 0, - kGameResolution_320x200 = 1, - kGameResolution_320x240 = 2, - kGameResolution_640x400 = 3, - kGameResolution_640x480 = 4, - kGameResolution_800x600 = 5, - kGameResolution_1024x768 = 6, - kGameResolution_1280x720 = 7, - kGameResolution_Custom = 8, - kNumGameResolutions, - - kGameResolution_LastLoRes = kGameResolution_320x240, - kGameResolution_FirstHiRes = kGameResolution_640x400 +enum GameResolutionType { + kGameResolution_Undefined = -1, + // definition of 320x200 in very old versions of the engine (somewhere pre-2.56) + kGameResolution_Default = 0, + kGameResolution_320x200 = 1, + kGameResolution_320x240 = 2, + kGameResolution_640x400 = 3, + kGameResolution_640x480 = 4, + kGameResolution_800x600 = 5, + kGameResolution_1024x768 = 6, + kGameResolution_1280x720 = 7, + kGameResolution_Custom = 8, + kNumGameResolutions, + + kGameResolution_LastLoRes = kGameResolution_320x240, + kGameResolution_FirstHiRes = kGameResolution_640x400 }; -inline bool IsLegacyHiRes(GameResolutionType resolution) -{ - return resolution > kGameResolution_LastLoRes; +inline bool IsLegacyHiRes(GameResolutionType resolution) { + return resolution > kGameResolution_LastLoRes; } Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox = false); // Automatic numbering of dialog options (OPT_DIALOGNUMBERED) -enum DialogOptionNumbering -{ - kDlgOptNoNumbering = -1, - kDlgOptKeysOnly = 0, // implicit key shortcuts - kDlgOptNumbering = 1 // draw option indices and use key shortcuts +enum DialogOptionNumbering { + kDlgOptNoNumbering = -1, + kDlgOptKeysOnly = 0, // implicit key shortcuts + kDlgOptNumbering = 1 // draw option indices and use key shortcuts }; // Version of the script api (OPT_BASESCRIPTAPI and OPT_SCRIPTCOMPATLEV). @@ -156,43 +153,39 @@ enum DialogOptionNumbering // two options. // NOTE: please remember that those values are valid only for games made with // 3.4.0 final and above. -enum ScriptAPIVersion -{ - kScriptAPI_Undefined = INT32_MIN, - kScriptAPI_v321 = 0, - kScriptAPI_v330 = 1, - kScriptAPI_v334 = 2, - kScriptAPI_v335 = 3, - kScriptAPI_v340 = 4, - kScriptAPI_v341 = 5, - kScriptAPI_v350 = 6, - kScriptAPI_v3507= 7, - kScriptAPI_v351 = 8, - kScriptAPI_Current = kScriptAPI_v351 +enum ScriptAPIVersion { + kScriptAPI_Undefined = INT32_MIN, + kScriptAPI_v321 = 0, + kScriptAPI_v330 = 1, + kScriptAPI_v334 = 2, + kScriptAPI_v335 = 3, + kScriptAPI_v340 = 4, + kScriptAPI_v341 = 5, + kScriptAPI_v350 = 6, + kScriptAPI_v3507 = 7, + kScriptAPI_v351 = 8, + kScriptAPI_Current = kScriptAPI_v351 }; // Determines whether the graphics renderer should scale sprites at the final // screen resolution, as opposed to native resolution -enum RenderAtScreenRes -{ - kRenderAtScreenRes_UserDefined = 0, - kRenderAtScreenRes_Enabled = 1, - kRenderAtScreenRes_Disabled = 2, +enum RenderAtScreenRes { + kRenderAtScreenRes_UserDefined = 0, + kRenderAtScreenRes_Enabled = 1, + kRenderAtScreenRes_Disabled = 2, }; // Method to use when blending two sprites with alpha channel -enum GameSpriteAlphaRenderingStyle -{ - kSpriteAlphaRender_Legacy = 0, - kSpriteAlphaRender_Proper +enum GameSpriteAlphaRenderingStyle { + kSpriteAlphaRender_Legacy = 0, + kSpriteAlphaRender_Proper }; // Method to use when blending two GUI elements with alpha channel -enum GameGuiAlphaRenderingStyle -{ - kGuiAlphaRender_Legacy = 0, - kGuiAlphaRender_AdditiveAlpha, - kGuiAlphaRender_Proper +enum GameGuiAlphaRenderingStyle { + kGuiAlphaRender_Legacy = 0, + kGuiAlphaRender_AdditiveAlpha, + kGuiAlphaRender_Proper }; @@ -206,23 +199,26 @@ enum GameGuiAlphaRenderingStyle #define SPF_HADALPHACHANNEL 0x80 // the saved sprite on disk has one // General information about sprite (properties, size) -struct SpriteInfo -{ - uint32_t Flags; - int Width; - int Height; - - SpriteInfo(); - - // - // Legacy game support - // - // Gets if sprite should adjust its base size depending on game's resolution - inline bool IsRelativeRes() const { return (Flags & SPF_VAR_RESOLUTION) != 0; } - // Gets if sprite belongs to high resolution; hi-res sprites should be - // downscaled in low-res games, and low-res sprites should be upscaled - // in hi-res games - inline bool IsLegacyHiRes() const { return (Flags & SPF_HIRES) != 0; } +struct SpriteInfo { + uint32_t Flags; + int Width; + int Height; + + SpriteInfo(); + + // + // Legacy game support + // + // Gets if sprite should adjust its base size depending on game's resolution + inline bool IsRelativeRes() const { + return (Flags & SPF_VAR_RESOLUTION) != 0; + } + // Gets if sprite belongs to high resolution; hi-res sprites should be + // downscaled in low-res games, and low-res sprites should be upscaled + // in hi-res games + inline bool IsLegacyHiRes() const { + return (Flags & SPF_HIRES) != 0; + } }; // Various font parameters, defining and extending font rendering behavior. @@ -230,32 +226,30 @@ struct SpriteInfo // the strictly determined position on canvas, FontInfo may additionally // provide instructions on adjusting drawing position, as well as arranging // multiple lines, and similar cases. -struct FontInfo -{ - enum AutoOutlineStyle : int - { - kRounded = 0, - kSquared = 1, - }; - - // General font's loading and rendering flags - uint32_t Flags; - // Font size, in points (basically means pixels in AGS) - int SizePt; - // Factor to multiply base font size by - int SizeMultiplier; - // Outlining font index, or auto-outline flag - char Outline; - // Custom vertical render offset, used mainly for fixing broken fonts - int YOffset; - // custom line spacing between two lines of text (0 = use font height) - int LineSpacing; - // When automatic outlining, thickness of the outline (0 = use legacy thickness) - int AutoOutlineThickness; - // When automatic outlining, style of the outline - AutoOutlineStyle AutoOutlineStyle; - - FontInfo(); +struct FontInfo { + enum AutoOutlineStyle : int { + kRounded = 0, + kSquared = 1, + }; + + // General font's loading and rendering flags + uint32_t Flags; + // Font size, in points (basically means pixels in AGS) + int SizePt; + // Factor to multiply base font size by + int SizeMultiplier; + // Outlining font index, or auto-outline flag + char Outline; + // Custom vertical render offset, used mainly for fixing broken fonts + int YOffset; + // custom line spacing between two lines of text (0 = use font height) + int LineSpacing; + // When automatic outlining, thickness of the outline (0 = use legacy thickness) + int AutoOutlineThickness; + // When automatic outlining, style of the outline + AutoOutlineStyle AutoOutlineStyle; + + FontInfo(); }; #endif diff --git a/engines/ags/shared/ac/interfacebutton.h b/engines/ags/shared/ac/interfacebutton.h index b5990dda812a..3918b8e17280 100644 --- a/engines/ags/shared/ac/interfacebutton.h +++ b/engines/ags/shared/ac/interfacebutton.h @@ -27,11 +27,11 @@ #define IBFLG_ENABLED 1 #define IBFLG_INVBOX 2 struct InterfaceButton { - int x, y, pic, overpic, pushpic, leftclick; - int rightclick; // if inv, then leftclick = wid, rightclick = hit - int reserved_for_future; - char flags; - void set(int xx, int yy, int picc, int overpicc, int actionn); + int x, y, pic, overpic, pushpic, leftclick; + int rightclick; // if inv, then leftclick = wid, rightclick = hit + int reserved_for_future; + char flags; + void set(int xx, int yy, int picc, int overpicc, int actionn); }; #endif diff --git a/engines/ags/shared/ac/interfaceelement.h b/engines/ags/shared/ac/interfaceelement.h index 4ecd3d5116bd..a81a9d6562bb 100644 --- a/engines/ags/shared/ac/interfaceelement.h +++ b/engines/ags/shared/ac/interfaceelement.h @@ -27,18 +27,18 @@ // this struct should go in a Game struct, not the room structure. struct InterfaceElement { - int x, y, x2, y2; - int bgcol, fgcol, bordercol; - int vtextxp, vtextyp, vtextalign; // X & Y relative to topleft of interface - char vtext[40]; - int numbuttons; - InterfaceButton button[MAXBUTTON]; - int flags; - int reserved_for_future; - int popupyp; // pops up when mousey < this - char popup; // does it pop up? (like sierra icon bar) - char on; - InterfaceElement(); + int x, y, x2, y2; + int bgcol, fgcol, bordercol; + int vtextxp, vtextyp, vtextalign; // X & Y relative to topleft of interface + char vtext[40]; + int numbuttons; + InterfaceButton button[MAXBUTTON]; + int flags; + int reserved_for_future; + int popupyp; // pops up when mousey < this + char popup; // does it pop up? (like sierra icon bar) + char on; + InterfaceElement(); }; /*struct InterfaceStyle { diff --git a/engines/ags/shared/ac/inventoryiteminfo.cpp b/engines/ags/shared/ac/inventoryiteminfo.cpp index 308178bbd970..89f9d1784225 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.cpp +++ b/engines/ags/shared/ac/inventoryiteminfo.cpp @@ -26,38 +26,34 @@ using namespace AGS::Common; -void InventoryItemInfo::ReadFromFile(Stream *in) -{ - in->Read(name, 25); - pic = in->ReadInt32(); - cursorPic = in->ReadInt32(); - hotx = in->ReadInt32(); - hoty = in->ReadInt32(); - in->ReadArrayOfInt32(reserved, 5); - flags = in->ReadInt8(); +void InventoryItemInfo::ReadFromFile(Stream *in) { + in->Read(name, 25); + pic = in->ReadInt32(); + cursorPic = in->ReadInt32(); + hotx = in->ReadInt32(); + hoty = in->ReadInt32(); + in->ReadArrayOfInt32(reserved, 5); + flags = in->ReadInt8(); } -void InventoryItemInfo::WriteToFile(Stream *out) -{ - out->Write(name, 25); - out->WriteInt32(pic); - out->WriteInt32(cursorPic); - out->WriteInt32(hotx); - out->WriteInt32(hoty); - out->WriteArrayOfInt32(reserved, 5); - out->WriteInt8(flags); +void InventoryItemInfo::WriteToFile(Stream *out) { + out->Write(name, 25); + out->WriteInt32(pic); + out->WriteInt32(cursorPic); + out->WriteInt32(hotx); + out->WriteInt32(hoty); + out->WriteArrayOfInt32(reserved, 5); + out->WriteInt8(flags); } -void InventoryItemInfo::ReadFromSavegame(Stream *in) -{ - StrUtil::ReadString(name, in, 25); - pic = in->ReadInt32(); - cursorPic = in->ReadInt32(); +void InventoryItemInfo::ReadFromSavegame(Stream *in) { + StrUtil::ReadString(name, in, 25); + pic = in->ReadInt32(); + cursorPic = in->ReadInt32(); } -void InventoryItemInfo::WriteToSavegame(Stream *out) const -{ - StrUtil::WriteString(name, out); - out->WriteInt32(pic); - out->WriteInt32(cursorPic); +void InventoryItemInfo::WriteToSavegame(Stream *out) const { + StrUtil::WriteString(name, out); + out->WriteInt32(pic); + out->WriteInt32(cursorPic); } diff --git a/engines/ags/shared/ac/inventoryiteminfo.h b/engines/ags/shared/ac/inventoryiteminfo.h index 1506622a5215..dce76e5c10e8 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.h +++ b/engines/ags/shared/ac/inventoryiteminfo.h @@ -23,21 +23,25 @@ #ifndef AGS_SHARED_AC_INVENTORYITEMINFO_H #define AGS_SHARED_AC_INVENTORYITEMINFO_H -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define IFLG_STARTWITH 1 struct InventoryItemInfo { - char name[25]; - int pic; - int cursorPic, hotx, hoty; - int reserved[5]; - char flags; + char name[25]; + int pic; + int cursorPic, hotx, hoty; + int reserved[5]; + char flags; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; }; #endif diff --git a/engines/ags/shared/ac/mousecursor.cpp b/engines/ags/shared/ac/mousecursor.cpp index f9d8c9f30dd2..2f5e4d80d29c 100644 --- a/engines/ags/shared/ac/mousecursor.cpp +++ b/engines/ags/shared/ac/mousecursor.cpp @@ -25,42 +25,45 @@ using AGS::Common::Stream; -MouseCursor::MouseCursor() { pic = 2054; hotx = 0; hoty = 0; name[0] = 0; flags = 0; view = -1; } +MouseCursor::MouseCursor() { + pic = 2054; + hotx = 0; + hoty = 0; + name[0] = 0; + flags = 0; + view = -1; +} -void MouseCursor::ReadFromFile(Stream *in) -{ - pic = in->ReadInt32(); - hotx = in->ReadInt16(); - hoty = in->ReadInt16(); - view = in->ReadInt16(); - in->Read(name, 10); - flags = in->ReadInt8(); +void MouseCursor::ReadFromFile(Stream *in) { + pic = in->ReadInt32(); + hotx = in->ReadInt16(); + hoty = in->ReadInt16(); + view = in->ReadInt16(); + in->Read(name, 10); + flags = in->ReadInt8(); } -void MouseCursor::WriteToFile(Stream *out) -{ - out->WriteInt32(pic); - out->WriteInt16(hotx); - out->WriteInt16(hoty); - out->WriteInt16(view); - out->Write(name, 10); - out->WriteInt8(flags); +void MouseCursor::WriteToFile(Stream *out) { + out->WriteInt32(pic); + out->WriteInt16(hotx); + out->WriteInt16(hoty); + out->WriteInt16(view); + out->Write(name, 10); + out->WriteInt8(flags); } -void MouseCursor::ReadFromSavegame(Stream *in) -{ - pic = in->ReadInt32(); - hotx = in->ReadInt32(); - hoty = in->ReadInt32(); - view = in->ReadInt32(); - flags = in->ReadInt32(); +void MouseCursor::ReadFromSavegame(Stream *in) { + pic = in->ReadInt32(); + hotx = in->ReadInt32(); + hoty = in->ReadInt32(); + view = in->ReadInt32(); + flags = in->ReadInt32(); } -void MouseCursor::WriteToSavegame(Stream *out) const -{ - out->WriteInt32(pic); - out->WriteInt32(hotx); - out->WriteInt32(hoty); - out->WriteInt32(view); - out->WriteInt32(flags); +void MouseCursor::WriteToSavegame(Stream *out) const { + out->WriteInt32(pic); + out->WriteInt32(hotx); + out->WriteInt32(hoty); + out->WriteInt32(view); + out->WriteInt32(flags); } diff --git a/engines/ags/shared/ac/mousecursor.h b/engines/ags/shared/ac/mousecursor.h index 732b6b49fca0..72484896ff9e 100644 --- a/engines/ags/shared/ac/mousecursor.h +++ b/engines/ags/shared/ac/mousecursor.h @@ -23,7 +23,11 @@ #ifndef AGS_SHARED_AC_MOUSECURSOR_H #define AGS_SHARED_AC_MOUSECURSOR_H -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define MCF_ANIMMOVE 1 @@ -32,17 +36,17 @@ using namespace AGS; // FIXME later #define MCF_HOTSPOT 8 // only animate when over hotspot // this struct is also in the plugin header file struct MouseCursor { - int pic; - short hotx, hoty; - short view; - char name[10]; - char flags; - MouseCursor(); + int pic; + short hotx, hoty; + short view; + char name[10]; + char flags; + MouseCursor(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); + void ReadFromSavegame(Common::Stream *in); + void WriteToSavegame(Common::Stream *out) const; }; #endif diff --git a/engines/ags/shared/ac/oldgamesetupstruct.h b/engines/ags/shared/ac/oldgamesetupstruct.h index b0cd0f23d95f..ee9f24b29105 100644 --- a/engines/ags/shared/ac/oldgamesetupstruct.h +++ b/engines/ags/shared/ac/oldgamesetupstruct.h @@ -34,50 +34,50 @@ #include "script/cc_script.h" // ccScript struct OriGameSetupStruct { - char gamename[30]; - char options[20]; - unsigned char paluses[256]; - color defpal[256]; - InterfaceElement iface[10]; - int numiface; - int numviews; - MouseCursor mcurs[10]; - char *globalscript; - int numcharacters; - OldCharacterInfo *chars; + char gamename[30]; + char options[20]; + unsigned char paluses[256]; + color defpal[256]; + InterfaceElement iface[10]; + int numiface; + int numviews; + MouseCursor mcurs[10]; + char *globalscript; + int numcharacters; + OldCharacterInfo *chars; #ifdef UNUSED_CODE - EventBlock __charcond[50]; // [IKM] 2012-06-22: does not seem to be used anywhere - EventBlock __invcond[100]; // same + EventBlock __charcond[50]; // [IKM] 2012-06-22: does not seem to be used anywhere + EventBlock __invcond[100]; // same #endif - ccScript *compiled_script; - int playercharacter; - unsigned char __old_spriteflags[2100]; - int totalscore; - short numinvitems; - InventoryItemInfo invinfo[100]; - int numdialog, numdlgmessage; - int numfonts; - int color_depth; // in bytes per pixel (ie. 1 or 2) - int target_win; - int dialog_bullet; // 0 for none, otherwise slot num of bullet point - short hotdot, hotdotouter; // inv cursor hotspot dot - int uniqueid; // random key identifying the game - int reserved[2]; - short numlang; - char langcodes[MAXLANGUAGE][3]; - char *messages[MAXGLOBALMES]; + ccScript *compiled_script; + int playercharacter; + unsigned char __old_spriteflags[2100]; + int totalscore; + short numinvitems; + InventoryItemInfo invinfo[100]; + int numdialog, numdlgmessage; + int numfonts; + int color_depth; // in bytes per pixel (ie. 1 or 2) + int target_win; + int dialog_bullet; // 0 for none, otherwise slot num of bullet point + short hotdot, hotdotouter; // inv cursor hotspot dot + int uniqueid; // random key identifying the game + int reserved[2]; + short numlang; + char langcodes[MAXLANGUAGE][3]; + char *messages[MAXGLOBALMES]; }; struct OriGameSetupStruct2 : public OriGameSetupStruct { - unsigned char fontflags[10]; - char fontoutline[10]; - int numgui; - WordsDictionary *dict; - int reserved2[8]; + unsigned char fontflags[10]; + char fontoutline[10]; + int numgui; + WordsDictionary *dict; + int reserved2[8]; }; struct OldGameSetupStruct : public OriGameSetupStruct2 { - unsigned char spriteflags[LEGACY_MAX_SPRITES_V25]; + unsigned char spriteflags[LEGACY_MAX_SPRITES_V25]; }; #endif diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp index bce6796b3764..79d79f713bce 100644 --- a/engines/ags/shared/ac/spritecache.cpp +++ b/engines/ags/shared/ac/spritecache.cpp @@ -60,934 +60,805 @@ const String SpriteCache::DefaultSpriteIndexName = "sprindex.dat"; SpriteInfo::SpriteInfo() - : Flags(0) - , Width(0) - , Height(0) -{ + : Flags(0) + , Width(0) + , Height(0) { } SpriteCache::SpriteData::SpriteData() - : Offset(0) - , Size(0) - , Flags(0) - , Image(nullptr) -{ + : Offset(0) + , Size(0) + , Flags(0) + , Image(nullptr) { } -SpriteCache::SpriteData::~SpriteData() -{ - // TODO: investigate, if it's actually safe/preferred to delete bitmap here - // (some of these bitmaps may be assigned from outside of the cache) +SpriteCache::SpriteData::~SpriteData() { + // TODO: investigate, if it's actually safe/preferred to delete bitmap here + // (some of these bitmaps may be assigned from outside of the cache) } SpriteCache::SpriteCache(std::vector &sprInfos) - : _sprInfos(sprInfos) -{ - _compressed = false; - Init(); + : _sprInfos(sprInfos) { + _compressed = false; + Init(); } -SpriteCache::~SpriteCache() -{ - Reset(); +SpriteCache::~SpriteCache() { + Reset(); } -size_t SpriteCache::GetCacheSize() const -{ - return _cacheSize; +size_t SpriteCache::GetCacheSize() const { + return _cacheSize; } -size_t SpriteCache::GetLockedSize() const -{ - return _lockedSize; +size_t SpriteCache::GetLockedSize() const { + return _lockedSize; } -size_t SpriteCache::GetMaxCacheSize() const -{ - return _maxCacheSize; +size_t SpriteCache::GetMaxCacheSize() const { + return _maxCacheSize; } -sprkey_t SpriteCache::GetSpriteSlotCount() const -{ - return _spriteData.size(); +sprkey_t SpriteCache::GetSpriteSlotCount() const { + return _spriteData.size(); } -sprkey_t SpriteCache::FindTopmostSprite() const -{ - sprkey_t topmost = -1; - for (sprkey_t i = 0; i < static_cast(_spriteData.size()); ++i) - if (DoesSpriteExist(i)) - topmost = i; - return topmost; +sprkey_t SpriteCache::FindTopmostSprite() const { + sprkey_t topmost = -1; + for (sprkey_t i = 0; i < static_cast(_spriteData.size()); ++i) + if (DoesSpriteExist(i)) + topmost = i; + return topmost; } -void SpriteCache::SetMaxCacheSize(size_t size) -{ - _maxCacheSize = size; +void SpriteCache::SetMaxCacheSize(size_t size) { + _maxCacheSize = size; } -void SpriteCache::Init() -{ - _cacheSize = 0; - _lockedSize = 0; - _maxCacheSize = (size_t)DEFAULTCACHESIZE_KB * 1024; - _liststart = -1; - _listend = -1; - _lastLoad = -2; +void SpriteCache::Init() { + _cacheSize = 0; + _lockedSize = 0; + _maxCacheSize = (size_t)DEFAULTCACHESIZE_KB * 1024; + _liststart = -1; + _listend = -1; + _lastLoad = -2; } -void SpriteCache::Reset() -{ - _stream.reset(); - // TODO: find out if it's safe to simply always delete _spriteData.Image with array element - for (size_t i = 0; i < _spriteData.size(); ++i) - { - if (_spriteData[i].Image) - { - delete _spriteData[i].Image; - _spriteData[i].Image = nullptr; - } - } - _spriteData.clear(); +void SpriteCache::Reset() { + _stream.reset(); + // TODO: find out if it's safe to simply always delete _spriteData.Image with array element + for (size_t i = 0; i < _spriteData.size(); ++i) { + if (_spriteData[i].Image) { + delete _spriteData[i].Image; + _spriteData[i].Image = nullptr; + } + } + _spriteData.clear(); - _mrulist.clear(); - _mrubacklink.clear(); + _mrulist.clear(); + _mrubacklink.clear(); - Init(); + Init(); } -void SpriteCache::SetSprite(sprkey_t index, Bitmap *sprite) -{ - if (index < 0 || EnlargeTo(index) != index) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetSprite: unable to use index %d", index); - return; - } - if (!sprite) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetSprite: attempt to assign nullptr to index %d", index); - return; - } - _spriteData[index].Image = sprite; - _spriteData[index].Flags = SPRCACHEFLAG_LOCKED; // NOT from asset file - _spriteData[index].Offset = 0; - _spriteData[index].Size = 0; +void SpriteCache::SetSprite(sprkey_t index, Bitmap *sprite) { + if (index < 0 || EnlargeTo(index) != index) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetSprite: unable to use index %d", index); + return; + } + if (!sprite) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetSprite: attempt to assign nullptr to index %d", index); + return; + } + _spriteData[index].Image = sprite; + _spriteData[index].Flags = SPRCACHEFLAG_LOCKED; // NOT from asset file + _spriteData[index].Offset = 0; + _spriteData[index].Size = 0; #ifdef DEBUG_SPRITECACHE - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "SetSprite: (external) %d", index); + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "SetSprite: (external) %d", index); #endif } -void SpriteCache::SetEmptySprite(sprkey_t index, bool as_asset) -{ - if (index < 0 || EnlargeTo(index) != index) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetEmptySprite: unable to use index %d", index); - return; - } - if (as_asset) - _spriteData[index].Flags = SPRCACHEFLAG_ISASSET; - RemapSpriteToSprite0(index); -} - -void SpriteCache::SubstituteBitmap(sprkey_t index, Common::Bitmap *sprite) -{ - if (!DoesSpriteExist(index)) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SubstituteBitmap: attempt to set for non-existing sprite %d", index); - return; - } - _spriteData[index].Image = sprite; +void SpriteCache::SetEmptySprite(sprkey_t index, bool as_asset) { + if (index < 0 || EnlargeTo(index) != index) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetEmptySprite: unable to use index %d", index); + return; + } + if (as_asset) + _spriteData[index].Flags = SPRCACHEFLAG_ISASSET; + RemapSpriteToSprite0(index); +} + +void SpriteCache::SubstituteBitmap(sprkey_t index, Common::Bitmap *sprite) { + if (!DoesSpriteExist(index)) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SubstituteBitmap: attempt to set for non-existing sprite %d", index); + return; + } + _spriteData[index].Image = sprite; #ifdef DEBUG_SPRITECACHE - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "SubstituteBitmap: %d", index); + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "SubstituteBitmap: %d", index); #endif } -void SpriteCache::RemoveSprite(sprkey_t index, bool freeMemory) -{ - if (freeMemory) - delete _spriteData[index].Image; - InitNullSpriteParams(index); +void SpriteCache::RemoveSprite(sprkey_t index, bool freeMemory) { + if (freeMemory) + delete _spriteData[index].Image; + InitNullSpriteParams(index); #ifdef DEBUG_SPRITECACHE - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "RemoveSprite: %d", index); + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "RemoveSprite: %d", index); #endif } -sprkey_t SpriteCache::EnlargeTo(sprkey_t topmost) -{ - if (topmost < 0 || topmost > MAX_SPRITE_INDEX) - return -1; - if ((size_t)topmost < _spriteData.size()) - return topmost; - - size_t newsize = topmost + 1; - _sprInfos.resize(newsize); - _spriteData.resize(newsize); - _mrulist.resize(newsize); - _mrubacklink.resize(newsize); - return topmost; -} - -sprkey_t SpriteCache::GetFreeIndex() -{ - for (size_t i = MIN_SPRITE_INDEX; i < _spriteData.size(); ++i) - { - // slot empty - if (!DoesSpriteExist(i)) - { - _sprInfos[i] = SpriteInfo(); - _spriteData[i] = SpriteData(); - return i; - } - } - // enlarge the sprite bank to find a free slot and return the first new free slot - return EnlargeTo(_spriteData.size()); -} - -bool SpriteCache::SpriteData::DoesSpriteExist() const -{ - return (Image != nullptr) || // HAS loaded bitmap - ((Flags & SPRCACHEFLAG_ISASSET) != 0); // OR found in the game resources -} - -bool SpriteCache::SpriteData::IsAssetSprite() const -{ - return (Flags & SPRCACHEFLAG_ISASSET) != 0; // found in game resources -} - -bool SpriteCache::SpriteData::IsExternalSprite() const -{ - return (Image != nullptr) && // HAS loaded bitmap - ((Flags & SPRCACHEFLAG_ISASSET) == 0) && // AND NOT found in game resources - ((Flags & SPRCACHEFLAG_REMAPPED) == 0); // AND was NOT remapped to another sprite -} - -bool SpriteCache::SpriteData::IsLocked() const -{ - return (Flags & SPRCACHEFLAG_LOCKED) != 0; -} - -bool SpriteCache::DoesSpriteExist(sprkey_t index) const -{ - return index >= 0 && (size_t)index < _spriteData.size() && _spriteData[index].DoesSpriteExist(); -} - -Bitmap *SpriteCache::operator [] (sprkey_t index) -{ - // invalid sprite slot - if (index < 0 || (size_t)index >= _spriteData.size()) - return nullptr; - - // Externally added sprite, don't put it into MRU list - if (_spriteData[index].IsExternalSprite()) - return _spriteData[index].Image; - - // Sprite exists in file but is not in mem, load it - if ((_spriteData[index].Image == nullptr) && _spriteData[index].IsAssetSprite()) - LoadSprite(index); - - // Locked sprite that shouldn't be put into MRU list - if (_spriteData[index].IsLocked()) - return _spriteData[index].Image; - - if (_liststart < 0) - { - _liststart = index; - _listend = index; - _mrulist[index] = END_OF_LIST; - _mrubacklink[index] = START_OF_LIST; - } - else if (_listend != index) - { - // this is the oldest element being bumped to newest, so update start link - if (index == _liststart) - { - _liststart = _mrulist[index]; - _mrubacklink[_liststart] = START_OF_LIST; - } - // already in list, link previous to next - else if (_mrulist[index] > 0) - { - _mrulist[_mrubacklink[index]] = _mrulist[index]; - _mrubacklink[_mrulist[index]] = _mrubacklink[index]; - } - - // set this as the newest element in the list - _mrulist[index] = END_OF_LIST; - _mrulist[_listend] = index; - _mrubacklink[index] = _listend; - _listend = index; - } - - return _spriteData[index].Image; -} - -void SpriteCache::DisposeOldest() -{ - if (_liststart < 0) - return; - - sprkey_t sprnum = _liststart; - - if ((_spriteData[sprnum].Image != nullptr) && !_spriteData[sprnum].IsLocked()) - { - // Free the memory - // Sprites that are not from the game resources should not normally be in a MRU list; - // if such is met here there's something wrong with the internal cache logic! - if (!_spriteData[sprnum].IsAssetSprite()) - { - quitprintf("SpriteCache::DisposeOldest: attempted to remove sprite %d that was added externally or does not exist", sprnum); - } - _cacheSize -= _spriteData[sprnum].Size; - - delete _spriteData[sprnum].Image; - _spriteData[sprnum].Image = nullptr; - } - - if (_liststart == _listend) - { - // there was one huge sprite, removing it has now emptied the cache completely - if (_cacheSize > 0) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SPRITE CACHE ERROR: Sprite cache should be empty, but still has %d bytes", _cacheSize); - } - _mrulist[_liststart] = 0; - _liststart = -1; - _listend = -1; - } - else - { - sprkey_t oldstart = _liststart; - _liststart = _mrulist[_liststart]; - _mrulist[oldstart] = 0; - _mrubacklink[_liststart] = START_OF_LIST; - if (oldstart == _liststart) - { - // Somehow, we have got a recursive link to itself, so we - // the game will freeze (since it is not actually freeing any - // memory) - // There must be a bug somewhere causing this, but for now - // let's just reset the cache - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: CACHE INCONSISTENT: RESETTING\n\tAt size %d (of %d), start %d end %d fwdlink=%d", - _cacheSize, _maxCacheSize, oldstart, _listend, _liststart); - DisposeAll(); - } - } +sprkey_t SpriteCache::EnlargeTo(sprkey_t topmost) { + if (topmost < 0 || topmost > MAX_SPRITE_INDEX) + return -1; + if ((size_t)topmost < _spriteData.size()) + return topmost; + + size_t newsize = topmost + 1; + _sprInfos.resize(newsize); + _spriteData.resize(newsize); + _mrulist.resize(newsize); + _mrubacklink.resize(newsize); + return topmost; +} + +sprkey_t SpriteCache::GetFreeIndex() { + for (size_t i = MIN_SPRITE_INDEX; i < _spriteData.size(); ++i) { + // slot empty + if (!DoesSpriteExist(i)) { + _sprInfos[i] = SpriteInfo(); + _spriteData[i] = SpriteData(); + return i; + } + } + // enlarge the sprite bank to find a free slot and return the first new free slot + return EnlargeTo(_spriteData.size()); +} + +bool SpriteCache::SpriteData::DoesSpriteExist() const { + return (Image != nullptr) || // HAS loaded bitmap + ((Flags & SPRCACHEFLAG_ISASSET) != 0); // OR found in the game resources +} + +bool SpriteCache::SpriteData::IsAssetSprite() const { + return (Flags & SPRCACHEFLAG_ISASSET) != 0; // found in game resources +} + +bool SpriteCache::SpriteData::IsExternalSprite() const { + return (Image != nullptr) && // HAS loaded bitmap + ((Flags & SPRCACHEFLAG_ISASSET) == 0) && // AND NOT found in game resources + ((Flags & SPRCACHEFLAG_REMAPPED) == 0); // AND was NOT remapped to another sprite +} + +bool SpriteCache::SpriteData::IsLocked() const { + return (Flags & SPRCACHEFLAG_LOCKED) != 0; +} + +bool SpriteCache::DoesSpriteExist(sprkey_t index) const { + return index >= 0 && (size_t)index < _spriteData.size() && _spriteData[index].DoesSpriteExist(); +} + +Bitmap *SpriteCache::operator [](sprkey_t index) { + // invalid sprite slot + if (index < 0 || (size_t)index >= _spriteData.size()) + return nullptr; + + // Externally added sprite, don't put it into MRU list + if (_spriteData[index].IsExternalSprite()) + return _spriteData[index].Image; + + // Sprite exists in file but is not in mem, load it + if ((_spriteData[index].Image == nullptr) && _spriteData[index].IsAssetSprite()) + LoadSprite(index); + + // Locked sprite that shouldn't be put into MRU list + if (_spriteData[index].IsLocked()) + return _spriteData[index].Image; + + if (_liststart < 0) { + _liststart = index; + _listend = index; + _mrulist[index] = END_OF_LIST; + _mrubacklink[index] = START_OF_LIST; + } else if (_listend != index) { + // this is the oldest element being bumped to newest, so update start link + if (index == _liststart) { + _liststart = _mrulist[index]; + _mrubacklink[_liststart] = START_OF_LIST; + } + // already in list, link previous to next + else if (_mrulist[index] > 0) { + _mrulist[_mrubacklink[index]] = _mrulist[index]; + _mrubacklink[_mrulist[index]] = _mrubacklink[index]; + } + + // set this as the newest element in the list + _mrulist[index] = END_OF_LIST; + _mrulist[_listend] = index; + _mrubacklink[index] = _listend; + _listend = index; + } + + return _spriteData[index].Image; +} + +void SpriteCache::DisposeOldest() { + if (_liststart < 0) + return; + + sprkey_t sprnum = _liststart; + + if ((_spriteData[sprnum].Image != nullptr) && !_spriteData[sprnum].IsLocked()) { + // Free the memory + // Sprites that are not from the game resources should not normally be in a MRU list; + // if such is met here there's something wrong with the internal cache logic! + if (!_spriteData[sprnum].IsAssetSprite()) { + quitprintf("SpriteCache::DisposeOldest: attempted to remove sprite %d that was added externally or does not exist", sprnum); + } + _cacheSize -= _spriteData[sprnum].Size; + + delete _spriteData[sprnum].Image; + _spriteData[sprnum].Image = nullptr; + } + + if (_liststart == _listend) { + // there was one huge sprite, removing it has now emptied the cache completely + if (_cacheSize > 0) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SPRITE CACHE ERROR: Sprite cache should be empty, but still has %d bytes", _cacheSize); + } + _mrulist[_liststart] = 0; + _liststart = -1; + _listend = -1; + } else { + sprkey_t oldstart = _liststart; + _liststart = _mrulist[_liststart]; + _mrulist[oldstart] = 0; + _mrubacklink[_liststart] = START_OF_LIST; + if (oldstart == _liststart) { + // Somehow, we have got a recursive link to itself, so we + // the game will freeze (since it is not actually freeing any + // memory) + // There must be a bug somewhere causing this, but for now + // let's just reset the cache + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: CACHE INCONSISTENT: RESETTING\n\tAt size %d (of %d), start %d end %d fwdlink=%d", + _cacheSize, _maxCacheSize, oldstart, _listend, _liststart); + DisposeAll(); + } + } #ifdef DEBUG_SPRITECACHE - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "DisposeOldest: disposed %d, size now %d KB", sprnum, _cacheSize / 1024); + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "DisposeOldest: disposed %d, size now %d KB", sprnum, _cacheSize / 1024); #endif } -void SpriteCache::DisposeAll() -{ - _liststart = -1; - _listend = -1; - for (size_t i = 0; i < _spriteData.size(); ++i) - { - if (!_spriteData[i].IsLocked() && // not locked - _spriteData[i].IsAssetSprite()) // sprite from game resource - { - delete _spriteData[i].Image; - _spriteData[i].Image = nullptr; - } - _mrulist[i] = 0; - _mrubacklink[i] = 0; - } - _cacheSize = _lockedSize; +void SpriteCache::DisposeAll() { + _liststart = -1; + _listend = -1; + for (size_t i = 0; i < _spriteData.size(); ++i) { + if (!_spriteData[i].IsLocked() && // not locked + _spriteData[i].IsAssetSprite()) { // sprite from game resource + delete _spriteData[i].Image; + _spriteData[i].Image = nullptr; + } + _mrulist[i] = 0; + _mrubacklink[i] = 0; + } + _cacheSize = _lockedSize; } -void SpriteCache::Precache(sprkey_t index) -{ - if (index < 0 || (size_t)index >= _spriteData.size()) - return; +void SpriteCache::Precache(sprkey_t index) { + if (index < 0 || (size_t)index >= _spriteData.size()) + return; - soff_t sprSize = 0; + soff_t sprSize = 0; - if (_spriteData[index].Image == nullptr) - sprSize = LoadSprite(index); - else if (!_spriteData[index].IsLocked()) - sprSize = _spriteData[index].Size; + if (_spriteData[index].Image == nullptr) + sprSize = LoadSprite(index); + else if (!_spriteData[index].IsLocked()) + sprSize = _spriteData[index].Size; - // make sure locked sprites can't fill the cache - _maxCacheSize += sprSize; - _lockedSize += sprSize; + // make sure locked sprites can't fill the cache + _maxCacheSize += sprSize; + _lockedSize += sprSize; - _spriteData[index].Flags |= SPRCACHEFLAG_LOCKED; + _spriteData[index].Flags |= SPRCACHEFLAG_LOCKED; #ifdef DEBUG_SPRITECACHE - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "Precached %d", index); + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "Precached %d", index); #endif } -sprkey_t SpriteCache::GetDataIndex(sprkey_t index) -{ - return (_spriteData[index].Flags & SPRCACHEFLAG_REMAPPED) == 0 ? index : 0; -} - -void SpriteCache::SeekToSprite(sprkey_t index) -{ - // If we didn't just load the previous sprite, seek to it - if (index - 1 != _lastLoad) - _stream->Seek(_spriteData[index].Offset, kSeekBegin); -} - -size_t SpriteCache::LoadSprite(sprkey_t index) -{ - int hh = 0; - - while (_cacheSize > _maxCacheSize) - { - DisposeOldest(); - hh++; - if (hh > 1000) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: STUCK IN FREE_UP_MEM; RESETTING CACHE"); - DisposeAll(); - } - } - - if (index < 0 || (size_t)index >= _spriteData.size()) - quit("sprite cache array index out of bounds"); - - sprkey_t load_index = GetDataIndex(index); - SeekToSprite(load_index); - - int coldep = _stream->ReadInt16(); - - if (coldep == 0) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "LoadSprite: asked to load sprite %d (for slot %d) which does not exist.", load_index, index); - _lastLoad = load_index; - return 0; - } - - int wdd = _stream->ReadInt16(); - int htt = _stream->ReadInt16(); - // update the stored width/height - _sprInfos[index].Width = wdd; - _sprInfos[index].Height = htt; - - _spriteData[index].Image = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); - if (_spriteData[index].Image == nullptr) - { - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Warn, "LoadSprite: failed to init sprite %d, remapping to sprite 0.", index); - RemapSpriteToSprite0(index); - return 0; - } - - Bitmap *image = _spriteData[index].Image; - if (this->_compressed) - { - _stream->ReadInt32(); // skip data size - UnCompressSprite(image, _stream.get()); - } - else - { - if (coldep == 1) - { - for (hh = 0; hh < htt; hh++) - _stream->ReadArray(&image->GetScanLineForWriting(hh)[0], coldep, wdd); - } - else if (coldep == 2) - { - for (hh = 0; hh < htt; hh++) - _stream->ReadArrayOfInt16((int16_t*)&image->GetScanLineForWriting(hh)[0], wdd); - } - else - { - for (hh = 0; hh < htt; hh++) - _stream->ReadArrayOfInt32((int32_t*)&image->GetScanLineForWriting(hh)[0], wdd); - } - } - - _lastLoad = load_index; - - // Stop it adding the sprite to the used list just because it's loaded - // TODO: this messy hack is required, because initialize_sprite calls operator[] - // which puts the sprite to the MRU list. - _spriteData[index].Flags |= SPRCACHEFLAG_LOCKED; - - // TODO: this is ugly: asks the engine to convert the sprite using its own knowledge. - // And engine assigns new bitmap using SpriteCache::SubstituteBitmap(). - // Perhaps change to the callback function pointer? - initialize_sprite(index); - - if (index != 0) // leave sprite 0 locked - _spriteData[index].Flags &= ~SPRCACHEFLAG_LOCKED; - - // we need to store this because the main program might - // alter spritewidth/height if it resizes stuff - size_t size = _sprInfos[index].Width * _sprInfos[index].Height * coldep; - _spriteData[index].Size = size; - _cacheSize += size; +sprkey_t SpriteCache::GetDataIndex(sprkey_t index) { + return (_spriteData[index].Flags & SPRCACHEFLAG_REMAPPED) == 0 ? index : 0; +} + +void SpriteCache::SeekToSprite(sprkey_t index) { + // If we didn't just load the previous sprite, seek to it + if (index - 1 != _lastLoad) + _stream->Seek(_spriteData[index].Offset, kSeekBegin); +} + +size_t SpriteCache::LoadSprite(sprkey_t index) { + int hh = 0; + + while (_cacheSize > _maxCacheSize) { + DisposeOldest(); + hh++; + if (hh > 1000) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: STUCK IN FREE_UP_MEM; RESETTING CACHE"); + DisposeAll(); + } + } + + if (index < 0 || (size_t)index >= _spriteData.size()) + quit("sprite cache array index out of bounds"); + + sprkey_t load_index = GetDataIndex(index); + SeekToSprite(load_index); + + int coldep = _stream->ReadInt16(); + + if (coldep == 0) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "LoadSprite: asked to load sprite %d (for slot %d) which does not exist.", load_index, index); + _lastLoad = load_index; + return 0; + } + + int wdd = _stream->ReadInt16(); + int htt = _stream->ReadInt16(); + // update the stored width/height + _sprInfos[index].Width = wdd; + _sprInfos[index].Height = htt; + + _spriteData[index].Image = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); + if (_spriteData[index].Image == nullptr) { + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Warn, "LoadSprite: failed to init sprite %d, remapping to sprite 0.", index); + RemapSpriteToSprite0(index); + return 0; + } + + Bitmap *image = _spriteData[index].Image; + if (this->_compressed) { + _stream->ReadInt32(); // skip data size + UnCompressSprite(image, _stream.get()); + } else { + if (coldep == 1) { + for (hh = 0; hh < htt; hh++) + _stream->ReadArray(&image->GetScanLineForWriting(hh)[0], coldep, wdd); + } else if (coldep == 2) { + for (hh = 0; hh < htt; hh++) + _stream->ReadArrayOfInt16((int16_t *)&image->GetScanLineForWriting(hh)[0], wdd); + } else { + for (hh = 0; hh < htt; hh++) + _stream->ReadArrayOfInt32((int32_t *)&image->GetScanLineForWriting(hh)[0], wdd); + } + } + + _lastLoad = load_index; + + // Stop it adding the sprite to the used list just because it's loaded + // TODO: this messy hack is required, because initialize_sprite calls operator[] + // which puts the sprite to the MRU list. + _spriteData[index].Flags |= SPRCACHEFLAG_LOCKED; + + // TODO: this is ugly: asks the engine to convert the sprite using its own knowledge. + // And engine assigns new bitmap using SpriteCache::SubstituteBitmap(). + // Perhaps change to the callback function pointer? + initialize_sprite(index); + + if (index != 0) // leave sprite 0 locked + _spriteData[index].Flags &= ~SPRCACHEFLAG_LOCKED; + + // we need to store this because the main program might + // alter spritewidth/height if it resizes stuff + size_t size = _sprInfos[index].Width * _sprInfos[index].Height * coldep; + _spriteData[index].Size = size; + _cacheSize += size; #ifdef DEBUG_SPRITECACHE - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "Loaded %d, size now %u KB", index, _cacheSize / 1024); + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "Loaded %d, size now %u KB", index, _cacheSize / 1024); #endif - return size; + return size; } -void SpriteCache::RemapSpriteToSprite0(sprkey_t index) -{ - _sprInfos[index].Flags = _sprInfos[0].Flags; - _sprInfos[index].Width = _sprInfos[0].Width; - _sprInfos[index].Height = _sprInfos[0].Height; - _spriteData[index].Image = nullptr; - _spriteData[index].Offset = _spriteData[0].Offset; - _spriteData[index].Size = _spriteData[0].Size; - _spriteData[index].Flags |= SPRCACHEFLAG_REMAPPED; +void SpriteCache::RemapSpriteToSprite0(sprkey_t index) { + _sprInfos[index].Flags = _sprInfos[0].Flags; + _sprInfos[index].Width = _sprInfos[0].Width; + _sprInfos[index].Height = _sprInfos[0].Height; + _spriteData[index].Image = nullptr; + _spriteData[index].Offset = _spriteData[0].Offset; + _spriteData[index].Size = _spriteData[0].Size; + _spriteData[index].Flags |= SPRCACHEFLAG_REMAPPED; #ifdef DEBUG_SPRITECACHE - Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "RemapSpriteToSprite0: %d", index); + Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Debug, "RemapSpriteToSprite0: %d", index); #endif } const char *spriteFileSig = " Sprite File "; -void SpriteCache::CompressSprite(Bitmap *sprite, Stream *out) -{ - const int depth = sprite->GetBPP(); - if (depth == 1) - { - for (int y = 0; y < sprite->GetHeight(); y++) - cpackbitl(&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), out); - } - else if (depth == 2) - { - for (int y = 0; y < sprite->GetHeight(); y++) - cpackbitl16((unsigned short *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); - } - else - { - for (int y = 0; y < sprite->GetHeight(); y++) - cpackbitl32((unsigned int *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); - } -} - -void SpriteCache::UnCompressSprite(Bitmap *sprite, Stream *in) -{ - const int depth = sprite->GetBPP(); - if (depth == 1) - { - for (int y = 0; y < sprite->GetHeight(); y++) - cunpackbitl(&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); - } - else if (depth == 2) - { - for (int y = 0; y < sprite->GetHeight(); y++) - cunpackbitl16((unsigned short*)&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); - } - else - { - for (int y = 0; y < sprite->GetHeight(); y++) - cunpackbitl32((unsigned int*)&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); - } -} - -int SpriteCache::SaveToFile(const char *filename, bool compressOutput, SpriteFileIndex &index) -{ - Stream *output = Common::File::CreateFile(filename); - if (output == nullptr) - return -1; - - if (compressOutput) - { - // re-open the file so that it can be seeked - delete output; - output = File::OpenFile(filename, Common::kFile_Open, Common::kFile_ReadWrite); // CHECKME why mode was "r+" here? - if (output == nullptr) - return -1; - } - - int spriteFileIDCheck = (int)time(nullptr); - - // sprite file version - output->WriteInt16(kSprfVersion_Current); - - output->WriteArray(spriteFileSig, strlen(spriteFileSig), 1); - - output->WriteInt8(compressOutput ? 1 : 0); - output->WriteInt32(spriteFileIDCheck); - - sprkey_t lastslot = FindTopmostSprite(); - output->WriteInt32(lastslot); - - // allocate buffers to store the indexing info - sprkey_t numsprits = lastslot + 1; - std::vector spritewidths, spriteheights; - std::vector spriteoffs; - spritewidths.resize(numsprits); - spriteheights.resize(numsprits); - spriteoffs.resize(numsprits); - - const int memBufferSize = 100000; - char *memBuffer = new char[memBufferSize]; - - for (sprkey_t i = 0; i <= lastslot; ++i) - { - spriteoffs[i] = output->GetPosition(); - - // if compressing uncompressed sprites, load the sprite into memory - if ((_spriteData[i].Image == nullptr) && (this->_compressed != compressOutput)) - (*this)[i]; - - if (_spriteData[i].Image != nullptr) - { - // image in memory -- write it out - pre_save_sprite(i); - Bitmap *image = _spriteData[i].Image; - int bpss = image->GetColorDepth() / 8; - spritewidths[i] = image->GetWidth(); - spriteheights[i] = image->GetHeight(); - output->WriteInt16(bpss); - output->WriteInt16(spritewidths[i]); - output->WriteInt16(spriteheights[i]); - - if (compressOutput) - { - size_t lenloc = output->GetPosition(); - // write some space for the length data - output->WriteInt32(0); - - CompressSprite(image, output); - - size_t fileSizeSoFar = output->GetPosition(); - // write the length of the compressed data - output->Seek(lenloc, kSeekBegin); - output->WriteInt32((fileSizeSoFar - lenloc) - 4); - output->Seek(0, kSeekEnd); - } - else - { - output->WriteArray(image->GetDataForWriting(), spritewidths[i] * bpss, spriteheights[i]); - } - continue; - } - - if (_spriteData[i].Offset == 0) - { - // sprite doesn't exist - output->WriteInt16(0); // colour depth - spritewidths[i] = 0; - spriteheights[i] = 0; - spriteoffs[i] = 0; - continue; - } - - // not in memory -- seek to it in the source file - sprkey_t load_index = GetDataIndex(i); - SeekToSprite(load_index); - _lastLoad = load_index; - - short colDepth = _stream->ReadInt16(); - output->WriteInt16(colDepth); - - if (colDepth == 0) - continue; - - if (this->_compressed != compressOutput) - { - // shouldn't be able to get here - delete [] memBuffer; - delete output; - return -2; - } - - // and copy the data across - int width = _stream->ReadInt16(); - int height = _stream->ReadInt16(); - - spritewidths[i] = width; - spriteheights[i] = height; - - output->WriteInt16(width); - output->WriteInt16(height); - - int sizeToCopy; - if (this->_compressed) - { - sizeToCopy = _stream->ReadInt32(); - output->WriteInt32(sizeToCopy); - } - else - { - sizeToCopy = width * height * (int)colDepth; - } - - while (sizeToCopy > memBufferSize) - { - _stream->ReadArray(memBuffer, memBufferSize, 1); - output->WriteArray(memBuffer, memBufferSize, 1); - sizeToCopy -= memBufferSize; - } - - _stream->ReadArray(memBuffer, sizeToCopy, 1); - output->WriteArray(memBuffer, sizeToCopy, 1); - } - - delete [] memBuffer; - delete output; - - index.SpriteFileIDCheck = spriteFileIDCheck; - index.LastSlot = lastslot; - index.SpriteCount = numsprits; - index.Widths = spritewidths; - index.Heights = spriteheights; - index.Offsets = spriteoffs; - return 0; -} - -int SpriteCache::SaveSpriteIndex(const char *filename, const SpriteFileIndex &index) -{ - // write the sprite index file - Stream *out = File::CreateFile(filename); - if (!out) - return -1; - // write "SPRINDEX" id - out->WriteArray(spindexid, strlen(spindexid), 1); - // write version - out->WriteInt32(kSpridxfVersion_Current); - out->WriteInt32(index.SpriteFileIDCheck); - // write last sprite number and num sprites, to verify that - // it matches the spr file - out->WriteInt32(index.LastSlot); - out->WriteInt32(index.SpriteCount); - if (index.SpriteCount > 0) - { - out->WriteArrayOfInt16(&index.Widths.front(), index.Widths.size()); - out->WriteArrayOfInt16(&index.Heights.front(), index.Heights.size()); - out->WriteArrayOfInt64(&index.Offsets.front(), index.Offsets.size()); - } - delete out; - return 0; -} - -HError SpriteCache::InitFile(const char *filename, const char *sprindex_filename) -{ - SpriteFileVersion vers; - char buff[20]; - soff_t spr_initial_offs = 0; - int spriteFileID = 0; - - _stream.reset(Common::AssetManager::OpenAsset(filename)); - if (_stream == nullptr) - return new Error(String::FromFormat("Failed to open spriteset file '%s'.", filename)); - - spr_initial_offs = _stream->GetPosition(); - - vers = (SpriteFileVersion)_stream->ReadInt16(); - // read the "Sprite File" signature - _stream->ReadArray(&buff[0], 13, 1); - - if (vers < kSprfVersion_Uncompressed || vers > kSprfVersion_Current) - { - _stream.reset(); - return new Error(String::FromFormat("Unsupported spriteset format (requested %d, supported %d - %d).", vers, kSprfVersion_Uncompressed, kSprfVersion_Current)); - } - - // unknown version - buff[13] = 0; - if (strcmp(buff, spriteFileSig)) - { - _stream.reset(); - return new Error("Uknown spriteset format."); - } - - if (vers == kSprfVersion_Uncompressed) - { - this->_compressed = false; - } - else if (vers == kSprfVersion_Compressed) - { - this->_compressed = true; - } - else if (vers >= kSprfVersion_Last32bit) - { - this->_compressed = (_stream->ReadInt8() == 1); - spriteFileID = _stream->ReadInt32(); - } - - if (vers < kSprfVersion_Compressed) - { - // skip the palette - _stream->Seek(256 * 3); // sizeof(RGB) * 256 - } - - sprkey_t topmost; - if (vers < kSprfVersion_HighSpriteLimit) - topmost = _stream->ReadInt16(); - else - topmost = _stream->ReadInt32(); - if (vers < kSprfVersion_Uncompressed) - topmost = 200; - - EnlargeTo(topmost); - - // if there is a sprite index file, use it - if (LoadSpriteIndexFile(sprindex_filename, spriteFileID, spr_initial_offs, topmost)) - { - // Succeeded - return HError::None(); - } - - // Failed, index file is invalid; index sprites manually - return RebuildSpriteIndex(_stream.get(), topmost, vers); -} - -HError SpriteCache::RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers) -{ - for (sprkey_t i = 0; i <= topmost; ++i) - { - _spriteData[i].Offset = in->GetPosition(); - _spriteData[i].Flags = 0; - - int coldep = in->ReadInt16(); - - if (coldep == 0) - { - // Empty slot - if (i > 0) - InitNullSpriteParams(i); - - if (in->EOS()) - break; - continue; - } - - if (in->EOS()) - break; - - if ((size_t)i >= _spriteData.size()) - break; - - _spriteData[i].Flags = SPRCACHEFLAG_ISASSET; - _spriteData[i].Image = nullptr; - - int wdd = in->ReadInt16(); - int htt = in->ReadInt16(); - _sprInfos[i].Width = wdd; - _sprInfos[i].Height = htt; - get_new_size_for_sprite(i, wdd, htt, _sprInfos[i].Width, _sprInfos[i].Height); - - size_t spriteDataSize; - if (vers == kSprfVersion_Compressed) - { - spriteDataSize = in->ReadInt32(); - } - else if (vers >= kSprfVersion_Last32bit) - { - spriteDataSize = this->_compressed ? in->ReadInt32() : wdd * coldep * htt; - } - else - { - spriteDataSize = wdd * coldep * htt; - } - in->Seek(spriteDataSize); - } - return HError::None(); -} - -bool SpriteCache::LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost) -{ - Stream *fidx = Common::AssetManager::OpenAsset(filename); - if (fidx == nullptr) - { - return false; - } - - char buffer[9]; - // check "SPRINDEX" id - fidx->ReadArray(&buffer[0], strlen(spindexid), 1); - buffer[8] = 0; - if (strcmp(buffer, spindexid)) - { - delete fidx; - return false; - } - // check version - SpriteIndexFileVersion vers = (SpriteIndexFileVersion)fidx->ReadInt32(); - if (vers < kSpridxfVersion_Initial || vers > kSpridxfVersion_Current) - { - delete fidx; - return false; - } - if (vers >= kSpridxfVersion_Last32bit) - { - if (fidx->ReadInt32() != expectedFileID) - { - delete fidx; - return false; - } - } - - sprkey_t topmost_index = fidx->ReadInt32(); - // end index+1 should be the same as num sprites - if (fidx->ReadInt32() != topmost_index + 1) - { - delete fidx; - return false; - } - - if (topmost_index != topmost) - { - delete fidx; - return false; - } - - sprkey_t numsprits = topmost_index + 1; - short *rspritewidths = new short[numsprits]; - short *rspriteheights = new short[numsprits]; - soff_t *spriteoffs = new soff_t[numsprits]; - - fidx->ReadArrayOfInt16(&rspritewidths[0], numsprits); - fidx->ReadArrayOfInt16(&rspriteheights[0], numsprits); - if (vers <= kSpridxfVersion_Last32bit) - { - for (sprkey_t i = 0; i < numsprits; ++i) - spriteoffs[i] = fidx->ReadInt32(); - } - else // large file support - { - fidx->ReadArrayOfInt64(spriteoffs, numsprits); - } - - for (sprkey_t i = 0; i <= topmost_index; ++i) - { - if (spriteoffs[i] != 0) - { - _spriteData[i].Flags = SPRCACHEFLAG_ISASSET; - _spriteData[i].Offset = spriteoffs[i] + spr_initial_offs; - get_new_size_for_sprite(i, rspritewidths[i], rspriteheights[i], _sprInfos[i].Width, _sprInfos[i].Height); - } - else if (i > 0) - { - InitNullSpriteParams(i); - } - } - - delete [] rspritewidths; - delete [] rspriteheights; - delete [] spriteoffs; - delete fidx; - return true; -} - -void SpriteCache::DetachFile() -{ - _stream.reset(); - _lastLoad = -2; -} - -int SpriteCache::AttachFile(const char *filename) -{ - _stream.reset(Common::AssetManager::OpenAsset((char *)filename)); - if (_stream == nullptr) - return -1; - return 0; -} - -bool SpriteCache::IsFileCompressed() const -{ - return _compressed; +void SpriteCache::CompressSprite(Bitmap *sprite, Stream *out) { + const int depth = sprite->GetBPP(); + if (depth == 1) { + for (int y = 0; y < sprite->GetHeight(); y++) + cpackbitl(&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), out); + } else if (depth == 2) { + for (int y = 0; y < sprite->GetHeight(); y++) + cpackbitl16((unsigned short *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); + } else { + for (int y = 0; y < sprite->GetHeight(); y++) + cpackbitl32((unsigned int *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); + } +} + +void SpriteCache::UnCompressSprite(Bitmap *sprite, Stream *in) { + const int depth = sprite->GetBPP(); + if (depth == 1) { + for (int y = 0; y < sprite->GetHeight(); y++) + cunpackbitl(&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); + } else if (depth == 2) { + for (int y = 0; y < sprite->GetHeight(); y++) + cunpackbitl16((unsigned short *)&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); + } else { + for (int y = 0; y < sprite->GetHeight(); y++) + cunpackbitl32((unsigned int *)&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), in); + } +} + +int SpriteCache::SaveToFile(const char *filename, bool compressOutput, SpriteFileIndex &index) { + Stream *output = Common::File::CreateFile(filename); + if (output == nullptr) + return -1; + + if (compressOutput) { + // re-open the file so that it can be seeked + delete output; + output = File::OpenFile(filename, Common::kFile_Open, Common::kFile_ReadWrite); // CHECKME why mode was "r+" here? + if (output == nullptr) + return -1; + } + + int spriteFileIDCheck = (int)time(nullptr); + + // sprite file version + output->WriteInt16(kSprfVersion_Current); + + output->WriteArray(spriteFileSig, strlen(spriteFileSig), 1); + + output->WriteInt8(compressOutput ? 1 : 0); + output->WriteInt32(spriteFileIDCheck); + + sprkey_t lastslot = FindTopmostSprite(); + output->WriteInt32(lastslot); + + // allocate buffers to store the indexing info + sprkey_t numsprits = lastslot + 1; + std::vector spritewidths, spriteheights; + std::vector spriteoffs; + spritewidths.resize(numsprits); + spriteheights.resize(numsprits); + spriteoffs.resize(numsprits); + + const int memBufferSize = 100000; + char *memBuffer = new char[memBufferSize]; + + for (sprkey_t i = 0; i <= lastslot; ++i) { + spriteoffs[i] = output->GetPosition(); + + // if compressing uncompressed sprites, load the sprite into memory + if ((_spriteData[i].Image == nullptr) && (this->_compressed != compressOutput)) + (*this)[i]; + + if (_spriteData[i].Image != nullptr) { + // image in memory -- write it out + pre_save_sprite(i); + Bitmap *image = _spriteData[i].Image; + int bpss = image->GetColorDepth() / 8; + spritewidths[i] = image->GetWidth(); + spriteheights[i] = image->GetHeight(); + output->WriteInt16(bpss); + output->WriteInt16(spritewidths[i]); + output->WriteInt16(spriteheights[i]); + + if (compressOutput) { + size_t lenloc = output->GetPosition(); + // write some space for the length data + output->WriteInt32(0); + + CompressSprite(image, output); + + size_t fileSizeSoFar = output->GetPosition(); + // write the length of the compressed data + output->Seek(lenloc, kSeekBegin); + output->WriteInt32((fileSizeSoFar - lenloc) - 4); + output->Seek(0, kSeekEnd); + } else { + output->WriteArray(image->GetDataForWriting(), spritewidths[i] * bpss, spriteheights[i]); + } + continue; + } + + if (_spriteData[i].Offset == 0) { + // sprite doesn't exist + output->WriteInt16(0); // colour depth + spritewidths[i] = 0; + spriteheights[i] = 0; + spriteoffs[i] = 0; + continue; + } + + // not in memory -- seek to it in the source file + sprkey_t load_index = GetDataIndex(i); + SeekToSprite(load_index); + _lastLoad = load_index; + + short colDepth = _stream->ReadInt16(); + output->WriteInt16(colDepth); + + if (colDepth == 0) + continue; + + if (this->_compressed != compressOutput) { + // shouldn't be able to get here + delete [] memBuffer; + delete output; + return -2; + } + + // and copy the data across + int width = _stream->ReadInt16(); + int height = _stream->ReadInt16(); + + spritewidths[i] = width; + spriteheights[i] = height; + + output->WriteInt16(width); + output->WriteInt16(height); + + int sizeToCopy; + if (this->_compressed) { + sizeToCopy = _stream->ReadInt32(); + output->WriteInt32(sizeToCopy); + } else { + sizeToCopy = width * height * (int)colDepth; + } + + while (sizeToCopy > memBufferSize) { + _stream->ReadArray(memBuffer, memBufferSize, 1); + output->WriteArray(memBuffer, memBufferSize, 1); + sizeToCopy -= memBufferSize; + } + + _stream->ReadArray(memBuffer, sizeToCopy, 1); + output->WriteArray(memBuffer, sizeToCopy, 1); + } + + delete [] memBuffer; + delete output; + + index.SpriteFileIDCheck = spriteFileIDCheck; + index.LastSlot = lastslot; + index.SpriteCount = numsprits; + index.Widths = spritewidths; + index.Heights = spriteheights; + index.Offsets = spriteoffs; + return 0; +} + +int SpriteCache::SaveSpriteIndex(const char *filename, const SpriteFileIndex &index) { + // write the sprite index file + Stream *out = File::CreateFile(filename); + if (!out) + return -1; + // write "SPRINDEX" id + out->WriteArray(spindexid, strlen(spindexid), 1); + // write version + out->WriteInt32(kSpridxfVersion_Current); + out->WriteInt32(index.SpriteFileIDCheck); + // write last sprite number and num sprites, to verify that + // it matches the spr file + out->WriteInt32(index.LastSlot); + out->WriteInt32(index.SpriteCount); + if (index.SpriteCount > 0) { + out->WriteArrayOfInt16(&index.Widths.front(), index.Widths.size()); + out->WriteArrayOfInt16(&index.Heights.front(), index.Heights.size()); + out->WriteArrayOfInt64(&index.Offsets.front(), index.Offsets.size()); + } + delete out; + return 0; +} + +HError SpriteCache::InitFile(const char *filename, const char *sprindex_filename) { + SpriteFileVersion vers; + char buff[20]; + soff_t spr_initial_offs = 0; + int spriteFileID = 0; + + _stream.reset(Common::AssetManager::OpenAsset(filename)); + if (_stream == nullptr) + return new Error(String::FromFormat("Failed to open spriteset file '%s'.", filename)); + + spr_initial_offs = _stream->GetPosition(); + + vers = (SpriteFileVersion)_stream->ReadInt16(); + // read the "Sprite File" signature + _stream->ReadArray(&buff[0], 13, 1); + + if (vers < kSprfVersion_Uncompressed || vers > kSprfVersion_Current) { + _stream.reset(); + return new Error(String::FromFormat("Unsupported spriteset format (requested %d, supported %d - %d).", vers, kSprfVersion_Uncompressed, kSprfVersion_Current)); + } + + // unknown version + buff[13] = 0; + if (strcmp(buff, spriteFileSig)) { + _stream.reset(); + return new Error("Uknown spriteset format."); + } + + if (vers == kSprfVersion_Uncompressed) { + this->_compressed = false; + } else if (vers == kSprfVersion_Compressed) { + this->_compressed = true; + } else if (vers >= kSprfVersion_Last32bit) { + this->_compressed = (_stream->ReadInt8() == 1); + spriteFileID = _stream->ReadInt32(); + } + + if (vers < kSprfVersion_Compressed) { + // skip the palette + _stream->Seek(256 * 3); // sizeof(RGB) * 256 + } + + sprkey_t topmost; + if (vers < kSprfVersion_HighSpriteLimit) + topmost = _stream->ReadInt16(); + else + topmost = _stream->ReadInt32(); + if (vers < kSprfVersion_Uncompressed) + topmost = 200; + + EnlargeTo(topmost); + + // if there is a sprite index file, use it + if (LoadSpriteIndexFile(sprindex_filename, spriteFileID, spr_initial_offs, topmost)) { + // Succeeded + return HError::None(); + } + + // Failed, index file is invalid; index sprites manually + return RebuildSpriteIndex(_stream.get(), topmost, vers); +} + +HError SpriteCache::RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers) { + for (sprkey_t i = 0; i <= topmost; ++i) { + _spriteData[i].Offset = in->GetPosition(); + _spriteData[i].Flags = 0; + + int coldep = in->ReadInt16(); + + if (coldep == 0) { + // Empty slot + if (i > 0) + InitNullSpriteParams(i); + + if (in->EOS()) + break; + continue; + } + + if (in->EOS()) + break; + + if ((size_t)i >= _spriteData.size()) + break; + + _spriteData[i].Flags = SPRCACHEFLAG_ISASSET; + _spriteData[i].Image = nullptr; + + int wdd = in->ReadInt16(); + int htt = in->ReadInt16(); + _sprInfos[i].Width = wdd; + _sprInfos[i].Height = htt; + get_new_size_for_sprite(i, wdd, htt, _sprInfos[i].Width, _sprInfos[i].Height); + + size_t spriteDataSize; + if (vers == kSprfVersion_Compressed) { + spriteDataSize = in->ReadInt32(); + } else if (vers >= kSprfVersion_Last32bit) { + spriteDataSize = this->_compressed ? in->ReadInt32() : wdd * coldep * htt; + } else { + spriteDataSize = wdd * coldep * htt; + } + in->Seek(spriteDataSize); + } + return HError::None(); +} + +bool SpriteCache::LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost) { + Stream *fidx = Common::AssetManager::OpenAsset(filename); + if (fidx == nullptr) { + return false; + } + + char buffer[9]; + // check "SPRINDEX" id + fidx->ReadArray(&buffer[0], strlen(spindexid), 1); + buffer[8] = 0; + if (strcmp(buffer, spindexid)) { + delete fidx; + return false; + } + // check version + SpriteIndexFileVersion vers = (SpriteIndexFileVersion)fidx->ReadInt32(); + if (vers < kSpridxfVersion_Initial || vers > kSpridxfVersion_Current) { + delete fidx; + return false; + } + if (vers >= kSpridxfVersion_Last32bit) { + if (fidx->ReadInt32() != expectedFileID) { + delete fidx; + return false; + } + } + + sprkey_t topmost_index = fidx->ReadInt32(); + // end index+1 should be the same as num sprites + if (fidx->ReadInt32() != topmost_index + 1) { + delete fidx; + return false; + } + + if (topmost_index != topmost) { + delete fidx; + return false; + } + + sprkey_t numsprits = topmost_index + 1; + short *rspritewidths = new short[numsprits]; + short *rspriteheights = new short[numsprits]; + soff_t *spriteoffs = new soff_t[numsprits]; + + fidx->ReadArrayOfInt16(&rspritewidths[0], numsprits); + fidx->ReadArrayOfInt16(&rspriteheights[0], numsprits); + if (vers <= kSpridxfVersion_Last32bit) { + for (sprkey_t i = 0; i < numsprits; ++i) + spriteoffs[i] = fidx->ReadInt32(); + } else { // large file support + fidx->ReadArrayOfInt64(spriteoffs, numsprits); + } + + for (sprkey_t i = 0; i <= topmost_index; ++i) { + if (spriteoffs[i] != 0) { + _spriteData[i].Flags = SPRCACHEFLAG_ISASSET; + _spriteData[i].Offset = spriteoffs[i] + spr_initial_offs; + get_new_size_for_sprite(i, rspritewidths[i], rspriteheights[i], _sprInfos[i].Width, _sprInfos[i].Height); + } else if (i > 0) { + InitNullSpriteParams(i); + } + } + + delete [] rspritewidths; + delete [] rspriteheights; + delete [] spriteoffs; + delete fidx; + return true; +} + +void SpriteCache::DetachFile() { + _stream.reset(); + _lastLoad = -2; +} + +int SpriteCache::AttachFile(const char *filename) { + _stream.reset(Common::AssetManager::OpenAsset((char *)filename)); + if (_stream == nullptr) + return -1; + return 0; +} + +bool SpriteCache::IsFileCompressed() const { + return _compressed; } diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index c1bdfe1803e6..1f11d9e70e94 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -50,7 +50,12 @@ #include "core/platform.h" #include "util/error.h" -namespace AGS { namespace Common { class Stream; class Bitmap; } } +namespace AGS { +namespace Common { +class Stream; +class Bitmap; +} +} using namespace AGS; // FIXME later typedef AGS::Common::HError HAGSError; @@ -71,178 +76,173 @@ struct SpriteInfo; #endif // TODO: research old version differences -enum SpriteFileVersion -{ - kSprfVersion_Uncompressed = 4, - kSprfVersion_Compressed = 5, - kSprfVersion_Last32bit = 6, - kSprfVersion_64bit = 10, - kSprfVersion_HighSpriteLimit = 11, - kSprfVersion_Current = kSprfVersion_HighSpriteLimit +enum SpriteFileVersion { + kSprfVersion_Uncompressed = 4, + kSprfVersion_Compressed = 5, + kSprfVersion_Last32bit = 6, + kSprfVersion_64bit = 10, + kSprfVersion_HighSpriteLimit = 11, + kSprfVersion_Current = kSprfVersion_HighSpriteLimit }; -enum SpriteIndexFileVersion -{ - kSpridxfVersion_Initial = 1, - kSpridxfVersion_Last32bit = 2, - kSpridxfVersion_64bit = 10, - kSpridxfVersion_HighSpriteLimit = 11, - kSpridxfVersion_Current = kSpridxfVersion_HighSpriteLimit +enum SpriteIndexFileVersion { + kSpridxfVersion_Initial = 1, + kSpridxfVersion_Last32bit = 2, + kSpridxfVersion_64bit = 10, + kSpridxfVersion_HighSpriteLimit = 11, + kSpridxfVersion_Current = kSpridxfVersion_HighSpriteLimit }; typedef int32_t sprkey_t; // SpriteFileIndex contains sprite file's table of contents -struct SpriteFileIndex -{ - int SpriteFileIDCheck = 0; // tag matching sprite file and index file - sprkey_t LastSlot = -1; - sprkey_t SpriteCount = 0; - std::vector Widths; - std::vector Heights; - std::vector Offsets; +struct SpriteFileIndex { + int SpriteFileIDCheck = 0; // tag matching sprite file and index file + sprkey_t LastSlot = -1; + sprkey_t SpriteCount = 0; + std::vector Widths; + std::vector Heights; + std::vector Offsets; }; -class SpriteCache -{ +class SpriteCache { public: - static const sprkey_t MIN_SPRITE_INDEX = 1; // 0 is reserved for "empty sprite" - static const sprkey_t MAX_SPRITE_INDEX = INT32_MAX - 1; - static const size_t MAX_SPRITE_SLOTS = INT32_MAX; - - // Standart sprite file and sprite index names - static const Common::String DefaultSpriteFileName; - static const Common::String DefaultSpriteIndexName; - - SpriteCache(std::vector &sprInfos); - ~SpriteCache(); - - // Tells if there is a sprite registered for the given index; - // this includes sprites that were explicitly assigned but failed to init and were remapped - bool DoesSpriteExist(sprkey_t index) const; - // Makes sure sprite cache has allocated slots for all sprites up to the given inclusive limit; - // returns requested index on success, or -1 on failure. - sprkey_t EnlargeTo(sprkey_t topmost); - // Finds a free slot index, if all slots are occupied enlarges sprite bank; returns index - sprkey_t GetFreeIndex(); - // Returns current size of the cache, in bytes - size_t GetCacheSize() const; - // Gets the total size of the locked sprites, in bytes - size_t GetLockedSize() const; - // Returns maximal size limit of the cache, in bytes - size_t GetMaxCacheSize() const; - // Returns number of sprite slots in the bank (this includes both actual sprites and free slots) - sprkey_t GetSpriteSlotCount() const; - // Finds the topmost occupied slot index. Warning: may be slow. - sprkey_t FindTopmostSprite() const; - // Loads sprite and and locks in memory (so it cannot get removed implicitly) - void Precache(sprkey_t index); - // Remap the given index to the sprite 0 - void RemapSpriteToSprite0(sprkey_t index); - // Unregisters sprite from the bank and optionally deletes bitmap - void RemoveSprite(sprkey_t index, bool freeMemory); - // Deletes all loaded (non-locked, non-external) images from the cache; - // this keeps all the auxiliary sprite information intact - void DisposeAll(); - // Deletes all data and resets cache to the clear state - void Reset(); - // Assigns new sprite for the given index; this sprite won't be auto disposed - void SetSprite(sprkey_t index, Common::Bitmap *); - // Assigns new sprite for the given index, remapping it to sprite 0; - // optionally marks it as an asset placeholder - void SetEmptySprite(sprkey_t index, bool as_asset); - // Assigns new bitmap for the *registered* sprite without changing its properties - void SubstituteBitmap(sprkey_t index, Common::Bitmap *); - // Sets max cache size in bytes - void SetMaxCacheSize(size_t size); - - // Loads sprite reference information and inits sprite stream - HAGSError InitFile(const char *filename, const char *sprindex_filename); - // Tells if bitmaps in the file are compressed - bool IsFileCompressed() const; - // Opens file stream - int AttachFile(const char *filename); - // Closes file stream - void DetachFile(); - // Saves all sprites to file; fills in index data for external use - // TODO: refactor to be able to save main file and index file separately (separate function for gather data?) - int SaveToFile(const char *filename, bool compressOutput, SpriteFileIndex &index); - // Saves sprite index table in a separate file - int SaveSpriteIndex(const char *filename, const SpriteFileIndex &index); - - // Loads (if it's not in cache yet) and returns bitmap by the sprite index - Common::Bitmap *operator[] (sprkey_t index); + static const sprkey_t MIN_SPRITE_INDEX = 1; // 0 is reserved for "empty sprite" + static const sprkey_t MAX_SPRITE_INDEX = INT32_MAX - 1; + static const size_t MAX_SPRITE_SLOTS = INT32_MAX; + + // Standart sprite file and sprite index names + static const Common::String DefaultSpriteFileName; + static const Common::String DefaultSpriteIndexName; + + SpriteCache(std::vector &sprInfos); + ~SpriteCache(); + + // Tells if there is a sprite registered for the given index; + // this includes sprites that were explicitly assigned but failed to init and were remapped + bool DoesSpriteExist(sprkey_t index) const; + // Makes sure sprite cache has allocated slots for all sprites up to the given inclusive limit; + // returns requested index on success, or -1 on failure. + sprkey_t EnlargeTo(sprkey_t topmost); + // Finds a free slot index, if all slots are occupied enlarges sprite bank; returns index + sprkey_t GetFreeIndex(); + // Returns current size of the cache, in bytes + size_t GetCacheSize() const; + // Gets the total size of the locked sprites, in bytes + size_t GetLockedSize() const; + // Returns maximal size limit of the cache, in bytes + size_t GetMaxCacheSize() const; + // Returns number of sprite slots in the bank (this includes both actual sprites and free slots) + sprkey_t GetSpriteSlotCount() const; + // Finds the topmost occupied slot index. Warning: may be slow. + sprkey_t FindTopmostSprite() const; + // Loads sprite and and locks in memory (so it cannot get removed implicitly) + void Precache(sprkey_t index); + // Remap the given index to the sprite 0 + void RemapSpriteToSprite0(sprkey_t index); + // Unregisters sprite from the bank and optionally deletes bitmap + void RemoveSprite(sprkey_t index, bool freeMemory); + // Deletes all loaded (non-locked, non-external) images from the cache; + // this keeps all the auxiliary sprite information intact + void DisposeAll(); + // Deletes all data and resets cache to the clear state + void Reset(); + // Assigns new sprite for the given index; this sprite won't be auto disposed + void SetSprite(sprkey_t index, Common::Bitmap *); + // Assigns new sprite for the given index, remapping it to sprite 0; + // optionally marks it as an asset placeholder + void SetEmptySprite(sprkey_t index, bool as_asset); + // Assigns new bitmap for the *registered* sprite without changing its properties + void SubstituteBitmap(sprkey_t index, Common::Bitmap *); + // Sets max cache size in bytes + void SetMaxCacheSize(size_t size); + + // Loads sprite reference information and inits sprite stream + HAGSError InitFile(const char *filename, const char *sprindex_filename); + // Tells if bitmaps in the file are compressed + bool IsFileCompressed() const; + // Opens file stream + int AttachFile(const char *filename); + // Closes file stream + void DetachFile(); + // Saves all sprites to file; fills in index data for external use + // TODO: refactor to be able to save main file and index file separately (separate function for gather data?) + int SaveToFile(const char *filename, bool compressOutput, SpriteFileIndex &index); + // Saves sprite index table in a separate file + int SaveSpriteIndex(const char *filename, const SpriteFileIndex &index); + + // Loads (if it's not in cache yet) and returns bitmap by the sprite index + Common::Bitmap *operator[](sprkey_t index); private: - void Init(); - // Gets the index of a sprite which data is used for the given slot; - // in case of remapped sprite this will return the one given sprite is remapped to - sprkey_t GetDataIndex(sprkey_t index); - // Load sprite from game resource - size_t LoadSprite(sprkey_t index); - // Seek stream to sprite - void SeekToSprite(sprkey_t index); - // Delete the oldest image in cache - void DisposeOldest(); - - // Information required for the sprite streaming - // TODO: split into sprite cache and sprite stream data - struct SpriteData - { - soff_t Offset; // data offset - soff_t Size; // cache size of element, in bytes - uint32_t Flags; - // TODO: investigate if we may safely use unique_ptr here - // (some of these bitmaps may be assigned from outside of the cache) - Common::Bitmap *Image; // actual bitmap - - // Tells if there actually is a registered sprite in this slot - bool DoesSpriteExist() const; - // Tells if there's a game resource corresponding to this slot - bool IsAssetSprite() const; - // Tells if sprite was added externally, not loaded from game resources - bool IsExternalSprite() const; - // Tells if sprite is locked and should not be disposed by cache logic - bool IsLocked() const; - - SpriteData(); - ~SpriteData(); - }; - - // Provided map of sprite infos, to fill in loaded sprite properties - std::vector &_sprInfos; - // Array of sprite references - std::vector _spriteData; - bool _compressed; // are sprites compressed - - std::unique_ptr _stream; // the sprite stream - sprkey_t _lastLoad; // last loaded sprite index - - size_t _maxCacheSize; // cache size limit - size_t _lockedSize; // size in bytes of currently locked images - size_t _cacheSize; // size in bytes of currently cached images - - // MRU list: the way to track which sprites were used recently. - // When clearing up space for new sprites, cache first deletes the sprites - // that were last time used long ago. - std::vector _mrulist; - std::vector _mrubacklink; - int _liststart; - int _listend; - - // Loads sprite index file - bool LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost); - // Rebuilds sprite index from the main sprite file - HAGSError RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers); - // Writes compressed sprite to the stream - void CompressSprite(Common::Bitmap *sprite, Common::Stream *out); - // Uncompresses sprite from stream into the given bitmap - void UnCompressSprite(Common::Bitmap *sprite, Common::Stream *in); - - // Initialize the empty sprite slot - void InitNullSpriteParams(sprkey_t index); + void Init(); + // Gets the index of a sprite which data is used for the given slot; + // in case of remapped sprite this will return the one given sprite is remapped to + sprkey_t GetDataIndex(sprkey_t index); + // Load sprite from game resource + size_t LoadSprite(sprkey_t index); + // Seek stream to sprite + void SeekToSprite(sprkey_t index); + // Delete the oldest image in cache + void DisposeOldest(); + + // Information required for the sprite streaming + // TODO: split into sprite cache and sprite stream data + struct SpriteData { + soff_t Offset; // data offset + soff_t Size; // cache size of element, in bytes + uint32_t Flags; + // TODO: investigate if we may safely use unique_ptr here + // (some of these bitmaps may be assigned from outside of the cache) + Common::Bitmap *Image; // actual bitmap + + // Tells if there actually is a registered sprite in this slot + bool DoesSpriteExist() const; + // Tells if there's a game resource corresponding to this slot + bool IsAssetSprite() const; + // Tells if sprite was added externally, not loaded from game resources + bool IsExternalSprite() const; + // Tells if sprite is locked and should not be disposed by cache logic + bool IsLocked() const; + + SpriteData(); + ~SpriteData(); + }; + + // Provided map of sprite infos, to fill in loaded sprite properties + std::vector &_sprInfos; + // Array of sprite references + std::vector _spriteData; + bool _compressed; // are sprites compressed + + std::unique_ptr _stream; // the sprite stream + sprkey_t _lastLoad; // last loaded sprite index + + size_t _maxCacheSize; // cache size limit + size_t _lockedSize; // size in bytes of currently locked images + size_t _cacheSize; // size in bytes of currently cached images + + // MRU list: the way to track which sprites were used recently. + // When clearing up space for new sprites, cache first deletes the sprites + // that were last time used long ago. + std::vector _mrulist; + std::vector _mrubacklink; + int _liststart; + int _listend; + + // Loads sprite index file + bool LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost); + // Rebuilds sprite index from the main sprite file + HAGSError RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers); + // Writes compressed sprite to the stream + void CompressSprite(Common::Bitmap *sprite, Common::Stream *out); + // Uncompresses sprite from stream into the given bitmap + void UnCompressSprite(Common::Bitmap *sprite, Common::Stream *in); + + // Initialize the empty sprite slot + void InitNullSpriteParams(sprkey_t index); }; extern SpriteCache spriteset; diff --git a/engines/ags/shared/ac/view.cpp b/engines/ags/shared/ac/view.cpp index 5130b23e3b09..c464989f554a 100644 --- a/engines/ags/shared/ac/view.cpp +++ b/engines/ags/shared/ac/view.cpp @@ -28,195 +28,163 @@ using AGS::Common::AlignedStream; using AGS::Common::Stream; ViewFrame::ViewFrame() - : pic(0) - , xoffs(0) - , yoffs(0) - , speed(0) - , flags(0) - , sound(0) -{ - reserved_for_future[0] = 0; - reserved_for_future[1] = 0; -} - -void ViewFrame::ReadFromFile(Stream *in) -{ - pic = in->ReadInt32(); - xoffs = in->ReadInt16(); - yoffs = in->ReadInt16(); - speed = in->ReadInt16(); - flags = in->ReadInt32(); - sound = in->ReadInt32(); - reserved_for_future[0] = in->ReadInt32(); - reserved_for_future[1] = in->ReadInt32(); -} - -void ViewFrame::WriteToFile(Stream *out) -{ - out->WriteInt32(pic); - out->WriteInt16(xoffs); - out->WriteInt16(yoffs); - out->WriteInt16(speed); - out->WriteInt32(flags); - out->WriteInt32(sound); - out->WriteInt32(reserved_for_future[0]); - out->WriteInt32(reserved_for_future[1]); + : pic(0) + , xoffs(0) + , yoffs(0) + , speed(0) + , flags(0) + , sound(0) { + reserved_for_future[0] = 0; + reserved_for_future[1] = 0; +} + +void ViewFrame::ReadFromFile(Stream *in) { + pic = in->ReadInt32(); + xoffs = in->ReadInt16(); + yoffs = in->ReadInt16(); + speed = in->ReadInt16(); + flags = in->ReadInt32(); + sound = in->ReadInt32(); + reserved_for_future[0] = in->ReadInt32(); + reserved_for_future[1] = in->ReadInt32(); +} + +void ViewFrame::WriteToFile(Stream *out) { + out->WriteInt32(pic); + out->WriteInt16(xoffs); + out->WriteInt16(yoffs); + out->WriteInt16(speed); + out->WriteInt32(flags); + out->WriteInt32(sound); + out->WriteInt32(reserved_for_future[0]); + out->WriteInt32(reserved_for_future[1]); } ViewLoopNew::ViewLoopNew() - : numFrames(0) - , flags(0) - , frames(nullptr) -{ + : numFrames(0) + , flags(0) + , frames(nullptr) { } -bool ViewLoopNew::RunNextLoop() -{ - return (flags & LOOPFLAG_RUNNEXTLOOP); +bool ViewLoopNew::RunNextLoop() { + return (flags & LOOPFLAG_RUNNEXTLOOP); } -void ViewLoopNew::Initialize(int frameCount) -{ - numFrames = frameCount; - flags = 0; - frames = (ViewFrame*)calloc(numFrames + 1, sizeof(ViewFrame)); +void ViewLoopNew::Initialize(int frameCount) { + numFrames = frameCount; + flags = 0; + frames = (ViewFrame *)calloc(numFrames + 1, sizeof(ViewFrame)); } -void ViewLoopNew::Dispose() -{ - if (frames != nullptr) - { - free(frames); - frames = nullptr; - numFrames = 0; - } +void ViewLoopNew::Dispose() { + if (frames != nullptr) { + free(frames); + frames = nullptr; + numFrames = 0; + } } -void ViewLoopNew::WriteToFile_v321(Stream *out) -{ - out->WriteInt16(numFrames); - out->WriteInt32(flags); - WriteFrames_Aligned(out); +void ViewLoopNew::WriteToFile_v321(Stream *out) { + out->WriteInt16(numFrames); + out->WriteInt32(flags); + WriteFrames_Aligned(out); } -void ViewLoopNew::WriteFrames_Aligned(Stream *out) -{ - AlignedStream align_s(out, Common::kAligned_Write); - for (int i = 0; i < numFrames; ++i) - { - frames[i].WriteToFile(&align_s); - align_s.Reset(); - } +void ViewLoopNew::WriteFrames_Aligned(Stream *out) { + AlignedStream align_s(out, Common::kAligned_Write); + for (int i = 0; i < numFrames; ++i) { + frames[i].WriteToFile(&align_s); + align_s.Reset(); + } } -void ViewLoopNew::ReadFromFile_v321(Stream *in) -{ - Initialize(in->ReadInt16()); - flags = in->ReadInt32(); - ReadFrames_Aligned(in); +void ViewLoopNew::ReadFromFile_v321(Stream *in) { + Initialize(in->ReadInt16()); + flags = in->ReadInt32(); + ReadFrames_Aligned(in); - // an extra frame is allocated in memory to prevent - // crashes with empty loops -- set its picture to teh BLUE CUP!! - frames[numFrames].pic = 0; + // an extra frame is allocated in memory to prevent + // crashes with empty loops -- set its picture to teh BLUE CUP!! + frames[numFrames].pic = 0; } -void ViewLoopNew::ReadFrames_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int i = 0; i < numFrames; ++i) - { - frames[i].ReadFromFile(&align_s); - align_s.Reset(); - } +void ViewLoopNew::ReadFrames_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < numFrames; ++i) { + frames[i].ReadFromFile(&align_s); + align_s.Reset(); + } } ViewStruct::ViewStruct() - : numLoops(0) - , loops(nullptr) -{ + : numLoops(0) + , loops(nullptr) { } -void ViewStruct::Initialize(int loopCount) -{ - numLoops = loopCount; - if (numLoops > 0) - { - loops = (ViewLoopNew*)calloc(numLoops, sizeof(ViewLoopNew)); - } +void ViewStruct::Initialize(int loopCount) { + numLoops = loopCount; + if (numLoops > 0) { + loops = (ViewLoopNew *)calloc(numLoops, sizeof(ViewLoopNew)); + } } -void ViewStruct::Dispose() -{ - if (numLoops > 0) - { - free(loops); - numLoops = 0; - } +void ViewStruct::Dispose() { + if (numLoops > 0) { + free(loops); + numLoops = 0; + } } -void ViewStruct::WriteToFile(Stream *out) -{ - out->WriteInt16(numLoops); - for (int i = 0; i < numLoops; i++) - { - loops[i].WriteToFile_v321(out); - } +void ViewStruct::WriteToFile(Stream *out) { + out->WriteInt16(numLoops); + for (int i = 0; i < numLoops; i++) { + loops[i].WriteToFile_v321(out); + } } -void ViewStruct::ReadFromFile(Stream *in) -{ - Initialize(in->ReadInt16()); +void ViewStruct::ReadFromFile(Stream *in) { + Initialize(in->ReadInt16()); - for (int i = 0; i < numLoops; i++) - { - loops[i].ReadFromFile_v321(in); - } + for (int i = 0; i < numLoops; i++) { + loops[i].ReadFromFile_v321(in); + } } ViewStruct272::ViewStruct272() - : numloops(0) -{ - memset(numframes, 0, sizeof(numframes)); - memset(loopflags, 0, sizeof(loopflags)); -} - -void ViewStruct272::ReadFromFile(Stream *in) -{ - numloops = in->ReadInt16(); - for (int i = 0; i < 16; ++i) - { - numframes[i] = in->ReadInt16(); - } - in->ReadArrayOfInt32(loopflags, 16); - for (int j = 0; j < 16; ++j) - { - for (int i = 0; i < 20; ++i) - { - frames[j][i].ReadFromFile(in); - } - } -} - -void Convert272ViewsToNew (const std::vector &oldv, ViewStruct *newv) -{ - for (size_t a = 0; a < oldv.size(); a++) { - newv[a].Initialize(oldv[a].numloops); - - for (int b = 0; b < oldv[a].numloops; b++) - { - newv[a].loops[b].Initialize(oldv[a].numframes[b]); - - if ((oldv[a].numframes[b] > 0) && - (oldv[a].frames[b][oldv[a].numframes[b] - 1].pic == -1)) - { - newv[a].loops[b].flags = LOOPFLAG_RUNNEXTLOOP; - newv[a].loops[b].numFrames--; - } - else - newv[a].loops[b].flags = 0; - - for (int c = 0; c < newv[a].loops[b].numFrames; c++) - newv[a].loops[b].frames[c] = oldv[a].frames[b][c]; - } - } + : numloops(0) { + memset(numframes, 0, sizeof(numframes)); + memset(loopflags, 0, sizeof(loopflags)); +} + +void ViewStruct272::ReadFromFile(Stream *in) { + numloops = in->ReadInt16(); + for (int i = 0; i < 16; ++i) { + numframes[i] = in->ReadInt16(); + } + in->ReadArrayOfInt32(loopflags, 16); + for (int j = 0; j < 16; ++j) { + for (int i = 0; i < 20; ++i) { + frames[j][i].ReadFromFile(in); + } + } +} + +void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *newv) { + for (size_t a = 0; a < oldv.size(); a++) { + newv[a].Initialize(oldv[a].numloops); + + for (int b = 0; b < oldv[a].numloops; b++) { + newv[a].loops[b].Initialize(oldv[a].numframes[b]); + + if ((oldv[a].numframes[b] > 0) && + (oldv[a].frames[b][oldv[a].numframes[b] - 1].pic == -1)) { + newv[a].loops[b].flags = LOOPFLAG_RUNNEXTLOOP; + newv[a].loops[b].numFrames--; + } else + newv[a].loops[b].flags = 0; + + for (int c = 0; c < newv[a].loops[b].numFrames; c++) + newv[a].loops[b].frames[c] = oldv[a].frames[b][c]; + } + } } diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index 6a257e14f4ed..824c3c8cde30 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -25,62 +25,64 @@ #include -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define VFLG_FLIPSPRITE 1 struct ViewFrame { - int pic; - short xoffs, yoffs; - short speed; - int flags; - int sound; // play sound when this frame comes round - int reserved_for_future[2]; - ViewFrame(); + int pic; + short xoffs, yoffs; + short speed; + int flags; + int sound; // play sound when this frame comes round + int reserved_for_future[2]; + ViewFrame(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); + void WriteToFile(Common::Stream *out); }; #define LOOPFLAG_RUNNEXTLOOP 1 -struct ViewLoopNew -{ - short numFrames; - int flags; - ViewFrame *frames; +struct ViewLoopNew { + short numFrames; + int flags; + ViewFrame *frames; - ViewLoopNew(); - void Initialize(int frameCount); - void Dispose(); - bool RunNextLoop(); - void WriteToFile_v321(Common::Stream *out); - void ReadFromFile_v321(Common::Stream *in); - void WriteFrames_Aligned(Common::Stream *out); - void ReadFrames_Aligned(Common::Stream *in); + ViewLoopNew(); + void Initialize(int frameCount); + void Dispose(); + bool RunNextLoop(); + void WriteToFile_v321(Common::Stream *out); + void ReadFromFile_v321(Common::Stream *in); + void WriteFrames_Aligned(Common::Stream *out); + void ReadFrames_Aligned(Common::Stream *in); }; -struct ViewStruct -{ - short numLoops; - ViewLoopNew *loops; +struct ViewStruct { + short numLoops; + ViewLoopNew *loops; - ViewStruct(); - void Initialize(int loopCount); - void Dispose(); - void WriteToFile(Common::Stream *out); - void ReadFromFile(Common::Stream *in); + ViewStruct(); + void Initialize(int loopCount); + void Dispose(); + void WriteToFile(Common::Stream *out); + void ReadFromFile(Common::Stream *in); }; struct ViewStruct272 { - short numloops; - short numframes[16]; - int loopflags[16]; - ViewFrame frames[16][20]; + short numloops; + short numframes[16]; + int loopflags[16]; + ViewFrame frames[16][20]; - ViewStruct272(); - void ReadFromFile(Common::Stream *in); + ViewStruct272(); + void ReadFromFile(Common::Stream *in); }; void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *newv); diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp index a90b0bf02f1d..362179481962 100644 --- a/engines/ags/shared/ac/wordsdictionary.cpp +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -29,153 +29,146 @@ using AGS::Common::Stream; WordsDictionary::WordsDictionary() - : num_words(0) - , word(nullptr) - , wordnum(nullptr) -{ + : num_words(0) + , word(nullptr) + , wordnum(nullptr) { } -WordsDictionary::~WordsDictionary() -{ - free_memory(); +WordsDictionary::~WordsDictionary() { + free_memory(); } -void WordsDictionary::allocate_memory(int wordCount) -{ - num_words = wordCount; - if (num_words > 0) - { - word = new char*[wordCount]; - word[0] = new char[wordCount * MAX_PARSER_WORD_LENGTH]; - wordnum = new short[wordCount]; - for (int i = 1; i < wordCount; i++) - { - word[i] = word[0] + MAX_PARSER_WORD_LENGTH * i; - } - } +void WordsDictionary::allocate_memory(int wordCount) { + num_words = wordCount; + if (num_words > 0) { + word = new char *[wordCount]; + word[0] = new char[wordCount * MAX_PARSER_WORD_LENGTH]; + wordnum = new short[wordCount]; + for (int i = 1; i < wordCount; i++) { + word[i] = word[0] + MAX_PARSER_WORD_LENGTH * i; + } + } } -void WordsDictionary::free_memory() -{ - if (num_words > 0) - { - delete [] word[0]; - delete [] word; - delete [] wordnum; - word = nullptr; - wordnum = nullptr; - num_words = 0; - } +void WordsDictionary::free_memory() { + if (num_words > 0) { + delete [] word[0]; + delete [] word; + delete [] wordnum; + word = nullptr; + wordnum = nullptr; + num_words = 0; + } } -void WordsDictionary::sort () { - int aa, bb; - for (aa = 0; aa < num_words; aa++) { - for (bb = aa + 1; bb < num_words; bb++) { - if (((wordnum[aa] == wordnum[bb]) && (ags_stricmp(word[aa], word[bb]) > 0)) - || (wordnum[aa] > wordnum[bb])) { - short temp = wordnum[aa]; - char tempst[30]; - - wordnum[aa] = wordnum[bb]; - wordnum[bb] = temp; - strcpy(tempst, word[aa]); - strcpy(word[aa], word[bb]); - strcpy(word[bb], tempst); - bb = aa; - } - } - } +void WordsDictionary::sort() { + int aa, bb; + for (aa = 0; aa < num_words; aa++) { + for (bb = aa + 1; bb < num_words; bb++) { + if (((wordnum[aa] == wordnum[bb]) && (ags_stricmp(word[aa], word[bb]) > 0)) + || (wordnum[aa] > wordnum[bb])) { + short temp = wordnum[aa]; + char tempst[30]; + + wordnum[aa] = wordnum[bb]; + wordnum[bb] = temp; + strcpy(tempst, word[aa]); + strcpy(word[aa], word[bb]); + strcpy(word[bb], tempst); + bb = aa; + } + } + } } -int WordsDictionary::find_index (const char*wrem) { - int aa; - for (aa = 0; aa < num_words; aa++) { - if (ags_stricmp (wrem, word[aa]) == 0) - return aa; - } - return -1; +int WordsDictionary::find_index(const char *wrem) { + int aa; + for (aa = 0; aa < num_words; aa++) { + if (ags_stricmp(wrem, word[aa]) == 0) + return aa; + } + return -1; } const char *passwencstring = "Avis Durgan"; -void decrypt_text(char*toenc) { - int adx = 0; +void decrypt_text(char *toenc) { + int adx = 0; - while (1) { - toenc[0] -= passwencstring[adx]; - if (toenc[0] == 0) - break; + while (1) { + toenc[0] -= passwencstring[adx]; + if (toenc[0] == 0) + break; - adx++; - toenc++; + adx++; + toenc++; - if (adx > 10) - adx = 0; - } + if (adx > 10) + adx = 0; + } } void read_string_decrypt(Stream *in, char *buf, size_t buf_sz) { - size_t len = in->ReadInt32(); - size_t slen = std::min(buf_sz - 1, len); - in->Read(buf, slen); - if (len > slen) - in->Seek(len - slen); - buf[slen] = 0; - decrypt_text(buf); + size_t len = in->ReadInt32(); + size_t slen = std::min(buf_sz - 1, len); + in->Read(buf, slen); + if (len > slen) + in->Seek(len - slen); + buf[slen] = 0; + decrypt_text(buf); } -void read_dictionary (WordsDictionary *dict, Stream *out) { - int ii; +void read_dictionary(WordsDictionary *dict, Stream *out) { + int ii; - dict->allocate_memory(out->ReadInt32()); - for (ii = 0; ii < dict->num_words; ii++) { - read_string_decrypt (out, dict->word[ii], MAX_PARSER_WORD_LENGTH); - dict->wordnum[ii] = out->ReadInt16(); - } + dict->allocate_memory(out->ReadInt32()); + for (ii = 0; ii < dict->num_words; ii++) { + read_string_decrypt(out, dict->word[ii], MAX_PARSER_WORD_LENGTH); + dict->wordnum[ii] = out->ReadInt16(); + } } #if defined (OBSOLETE) // TODO: not a part of wordsdictionary, move to obsoletes void freadmissout(short *pptr, Stream *in) { - in->ReadArrayOfInt16(&pptr[0], 5); - in->ReadArrayOfInt16(&pptr[7], NUM_CONDIT - 7); - pptr[5] = pptr[6] = 0; + in->ReadArrayOfInt16(&pptr[0], 5); + in->ReadArrayOfInt16(&pptr[7], NUM_CONDIT - 7); + pptr[5] = pptr[6] = 0; } #endif void encrypt_text(char *toenc) { - int adx = 0, tobreak = 0; + int adx = 0, tobreak = 0; - while (tobreak == 0) { - if (toenc[0] == 0) - tobreak = 1; + while (tobreak == 0) { + if (toenc[0] == 0) + tobreak = 1; - toenc[0] += passwencstring[adx]; - adx++; - toenc++; + toenc[0] += passwencstring[adx]; + adx++; + toenc++; - if (adx > 10) - adx = 0; - } + if (adx > 10) + adx = 0; + } } void write_string_encrypt(Stream *out, const char *s) { - int stlent = (int)strlen(s) + 1; + int stlent = (int)strlen(s) + 1; - out->WriteInt32(stlent); - char *enc = ags_strdup(s); - encrypt_text(enc); - out->WriteArray(enc, stlent, 1); - free(enc); + out->WriteInt32(stlent); + char *enc = ags_strdup(s); + encrypt_text(enc); + out->WriteArray(enc, stlent, 1); + free(enc); } -void write_dictionary (WordsDictionary *dict, Stream *out) { - int ii; +void write_dictionary(WordsDictionary *dict, Stream *out) { + int ii; - out->WriteInt32(dict->num_words); - for (ii = 0; ii < dict->num_words; ii++) { - write_string_encrypt (out, dict->word[ii]); - out->WriteInt16(dict->wordnum[ii]);//__putshort__lilendian(dict->wordnum[ii], writeto); - } + out->WriteInt32(dict->num_words); + for (ii = 0; ii < dict->num_words; ii++) { + write_string_encrypt(out, dict->word[ii]); + out->WriteInt16(dict->wordnum[ii]);//__putshort__lilendian(dict->wordnum[ii], writeto); + } } diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h index dd499f7b69d8..8acf1250f35d 100644 --- a/engines/ags/shared/ac/wordsdictionary.h +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -25,7 +25,11 @@ #include "core/types.h" -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later #define MAX_PARSER_WORD_LENGTH 30 @@ -33,23 +37,23 @@ using namespace AGS; // FIXME later #define RESTOFLINE 30000 struct WordsDictionary { - int num_words; - char**word; - short*wordnum; - - WordsDictionary(); - ~WordsDictionary(); - void allocate_memory(int wordCount); - void free_memory(); - void sort(); - int find_index (const char *); + int num_words; + char **word; + short *wordnum; + + WordsDictionary(); + ~WordsDictionary(); + void allocate_memory(int wordCount); + void free_memory(); + void sort(); + int find_index(const char *); }; extern const char *passwencstring; -extern void decrypt_text(char*toenc); +extern void decrypt_text(char *toenc); extern void read_string_decrypt(Common::Stream *in, char *buf, size_t buf_sz); -extern void read_dictionary (WordsDictionary *dict, Common::Stream *in); +extern void read_dictionary(WordsDictionary *dict, Common::Stream *in); #if defined (OBSOLETE) // TODO: not a part of wordsdictionary, move to obsoletes @@ -58,6 +62,6 @@ extern void freadmissout(short *pptr, Common::Stream *in); extern void encrypt_text(char *toenc); extern void write_string_encrypt(Common::Stream *out, const char *s); -extern void write_dictionary (WordsDictionary *dict, Common::Stream *out); +extern void write_dictionary(WordsDictionary *dict, Common::Stream *out); #endif diff --git a/engines/ags/shared/api/stream_api.h b/engines/ags/shared/api/stream_api.h index 283a44012829..b0b03dc2f361 100644 --- a/engines/ags/shared/api/stream_api.h +++ b/engines/ags/shared/api/stream_api.h @@ -38,61 +38,57 @@ // plugins, and let plugin developers include them manually in plugin sources. #include "core/types.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -enum StreamSeek -{ - kSeekBegin, - kSeekCurrent, - kSeekEnd +enum StreamSeek { + kSeekBegin, + kSeekCurrent, + kSeekEnd }; -class IAGSStream -{ +class IAGSStream { public: - virtual ~IAGSStream() = default; + virtual ~IAGSStream() = default; - virtual void Close() = 0; + virtual void Close() = 0; - virtual bool IsValid() const = 0; - virtual bool EOS() const = 0; - virtual soff_t GetLength() const = 0; - virtual soff_t GetPosition() const = 0; - virtual bool CanRead() const = 0; - virtual bool CanWrite() const = 0; - virtual bool CanSeek() const = 0; + virtual bool IsValid() const = 0; + virtual bool EOS() const = 0; + virtual soff_t GetLength() const = 0; + virtual soff_t GetPosition() const = 0; + virtual bool CanRead() const = 0; + virtual bool CanWrite() const = 0; + virtual bool CanSeek() const = 0; - virtual size_t Read(void *buffer, size_t size) = 0; - virtual int32_t ReadByte() = 0; - virtual size_t Write(const void *buffer, size_t size) = 0; - virtual int32_t WriteByte(uint8_t b) = 0; + virtual size_t Read(void *buffer, size_t size) = 0; + virtual int32_t ReadByte() = 0; + virtual size_t Write(const void *buffer, size_t size) = 0; + virtual int32_t WriteByte(uint8_t b) = 0; - virtual int8_t ReadInt8() = 0; - virtual int16_t ReadInt16() = 0; - virtual int32_t ReadInt32() = 0; - virtual int64_t ReadInt64() = 0; - virtual bool ReadBool() = 0; - virtual size_t ReadArray(void *buffer, size_t elem_size, size_t count) = 0; - virtual size_t ReadArrayOfInt8(int8_t *buffer, size_t count) = 0; - virtual size_t ReadArrayOfInt16(int16_t *buffer, size_t count) = 0; - virtual size_t ReadArrayOfInt32(int32_t *buffer, size_t count) = 0; - virtual size_t ReadArrayOfInt64(int64_t *buffer, size_t count) = 0; + virtual int8_t ReadInt8() = 0; + virtual int16_t ReadInt16() = 0; + virtual int32_t ReadInt32() = 0; + virtual int64_t ReadInt64() = 0; + virtual bool ReadBool() = 0; + virtual size_t ReadArray(void *buffer, size_t elem_size, size_t count) = 0; + virtual size_t ReadArrayOfInt8(int8_t *buffer, size_t count) = 0; + virtual size_t ReadArrayOfInt16(int16_t *buffer, size_t count) = 0; + virtual size_t ReadArrayOfInt32(int32_t *buffer, size_t count) = 0; + virtual size_t ReadArrayOfInt64(int64_t *buffer, size_t count) = 0; - virtual size_t WriteInt8(int8_t val) = 0;; - virtual size_t WriteInt16(int16_t val) = 0; - virtual size_t WriteInt32(int32_t val) = 0; - virtual size_t WriteInt64(int64_t val) = 0; - virtual size_t WriteBool(bool val) = 0; - virtual size_t WriteArray(const void *buffer, size_t elem_size, size_t count) = 0; - virtual size_t WriteArrayOfInt8(const int8_t *buffer, size_t count) = 0; - virtual size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) = 0; - virtual size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) = 0; - virtual size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) = 0; + virtual size_t WriteInt8(int8_t val) = 0;; + virtual size_t WriteInt16(int16_t val) = 0; + virtual size_t WriteInt32(int32_t val) = 0; + virtual size_t WriteInt64(int64_t val) = 0; + virtual size_t WriteBool(bool val) = 0; + virtual size_t WriteArray(const void *buffer, size_t elem_size, size_t count) = 0; + virtual size_t WriteArrayOfInt8(const int8_t *buffer, size_t count) = 0; + virtual size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) = 0; + virtual size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) = 0; + virtual size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) = 0; - virtual bool Seek(soff_t offset, StreamSeek origin = kSeekCurrent) = 0; + virtual bool Seek(soff_t offset, StreamSeek origin = kSeekCurrent) = 0; }; } // namespace Common diff --git a/engines/ags/shared/core/asset.cpp b/engines/ags/shared/core/asset.cpp index aded7d497ce6..24f988be4403 100644 --- a/engines/ags/shared/core/asset.cpp +++ b/engines/ags/shared/core/asset.cpp @@ -22,23 +22,19 @@ #include "core/asset.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { AssetInfo::AssetInfo() - : LibUid(0) - , Offset(0) - , Size(0) -{ + : LibUid(0) + , Offset(0) + , Size(0) { } -void AssetLibInfo::Unload() -{ - BaseFileName = ""; - BaseFilePath = ""; - LibFileNames.clear(); - AssetInfos.clear(); +void AssetLibInfo::Unload() { + BaseFileName = ""; + BaseFilePath = ""; + LibFileNames.clear(); + AssetInfos.clear(); } } // namespace Common diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index 14f906f5be8b..c5601a266cd0 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -32,36 +32,32 @@ #include #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // Information on single asset -struct AssetInfo -{ - // A pair of filename and libuid is assumed to be unique in game scope - String FileName; // filename associated with asset - int32_t LibUid; // uid of library, containing this asset - soff_t Offset; // asset's position in library file (in bytes) - soff_t Size; // asset's size (in bytes) +struct AssetInfo { + // A pair of filename and libuid is assumed to be unique in game scope + String FileName; // filename associated with asset + int32_t LibUid; // uid of library, containing this asset + soff_t Offset; // asset's position in library file (in bytes) + soff_t Size; // asset's size (in bytes) - AssetInfo(); + AssetInfo(); }; typedef std::vector AssetVec; // Information on multifile asset library -struct AssetLibInfo -{ - String BaseFileName; // library's base (head) filename - String BaseFilePath; // full path to the base filename - std::vector LibFileNames; // filename for each library part +struct AssetLibInfo { + String BaseFileName; // library's base (head) filename + String BaseFilePath; // full path to the base filename + std::vector LibFileNames; // filename for each library part - // Library contents - AssetVec AssetInfos; // information on contained assets + // Library contents + AssetVec AssetInfos; // information on contained assets - void Unload(); + void Unload(); }; } // namespace Common diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp index 1f38a81d1250..de80f63d5ee7 100644 --- a/engines/ags/shared/core/assetmanager.cpp +++ b/engines/ags/shared/core/assetmanager.cpp @@ -27,409 +27,344 @@ #include "util/string_utils.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { AssetLocation::AssetLocation() - : Offset(0) - , Size(0) -{ + : Offset(0) + , Size(0) { } AssetManager *AssetManager::_theAssetManager = nullptr; -/* static */ bool AssetManager::CreateInstance() -{ - // Issue a warning - recreating asset manager is not a normal behavior - assert(_theAssetManager == NULL); - delete _theAssetManager; - _theAssetManager = new AssetManager(); - _theAssetManager->SetSearchPriority(kAssetPriorityDir); - return _theAssetManager != nullptr; // well, we should return _something_ +/* static */ bool AssetManager::CreateInstance() { + // Issue a warning - recreating asset manager is not a normal behavior + assert(_theAssetManager == NULL); + delete _theAssetManager; + _theAssetManager = new AssetManager(); + _theAssetManager->SetSearchPriority(kAssetPriorityDir); + return _theAssetManager != nullptr; // well, we should return _something_ } -/* static */ void AssetManager::DestroyInstance() -{ - delete _theAssetManager; - _theAssetManager = nullptr; +/* static */ void AssetManager::DestroyInstance() { + delete _theAssetManager; + _theAssetManager = nullptr; } -AssetManager::~AssetManager() -{ - delete &_assetLib; +AssetManager::~AssetManager() { + delete &_assetLib; } -/* static */ bool AssetManager::SetSearchPriority(AssetSearchPriority priority) -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_SetSearchPriority(priority) : false; +/* static */ bool AssetManager::SetSearchPriority(AssetSearchPriority priority) { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_SetSearchPriority(priority) : false; } -/* static */ AssetSearchPriority AssetManager::GetSearchPriority() -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetSearchPriority() : kAssetPriorityUndefined; +/* static */ AssetSearchPriority AssetManager::GetSearchPriority() { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetSearchPriority() : kAssetPriorityUndefined; } -/* static */ bool AssetManager::IsDataFile(const String &data_file) -{ - Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); - if (in) - { - MFLUtil::MFLError err = MFLUtil::TestIsMFL(in, true); - delete in; - return err == MFLUtil::kMFLNoError; - } - return false; +/* static */ bool AssetManager::IsDataFile(const String &data_file) { + Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + if (in) { + MFLUtil::MFLError err = MFLUtil::TestIsMFL(in, true); + delete in; + return err == MFLUtil::kMFLNoError; + } + return false; } -AssetError AssetManager::ReadDataFileTOC(const String &data_file, AssetLibInfo &lib) -{ - Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); - if (in) - { - MFLUtil::MFLError err = MFLUtil::ReadHeader(lib, in); - delete in; - return (err != MFLUtil::kMFLNoError) ? kAssetErrLibParse : kAssetNoError; - } - return kAssetErrNoLibFile; +AssetError AssetManager::ReadDataFileTOC(const String &data_file, AssetLibInfo &lib) { + Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + if (in) { + MFLUtil::MFLError err = MFLUtil::ReadHeader(lib, in); + delete in; + return (err != MFLUtil::kMFLNoError) ? kAssetErrLibParse : kAssetNoError; + } + return kAssetErrNoLibFile; } -/* static */ AssetError AssetManager::SetDataFile(const String &data_file) -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_SetDataFile(data_file) : kAssetErrNoManager; +/* static */ AssetError AssetManager::SetDataFile(const String &data_file) { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_SetDataFile(data_file) : kAssetErrNoManager; } -/* static */ String AssetManager::GetLibraryForAsset(const String &asset_name) -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetLibraryForAsset(asset_name) : ""; +/* static */ String AssetManager::GetLibraryForAsset(const String &asset_name) { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetLibraryForAsset(asset_name) : ""; } -/* static */ soff_t AssetManager::GetAssetOffset(const String &asset_name) -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetAssetOffset(asset_name) : 0; +/* static */ soff_t AssetManager::GetAssetOffset(const String &asset_name) { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetOffset(asset_name) : 0; } -/* static */ soff_t AssetManager::GetAssetSize(const String &asset_name) -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetAssetSize(asset_name) : 0; +/* static */ soff_t AssetManager::GetAssetSize(const String &asset_name) { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetSize(asset_name) : 0; } -/* static */ soff_t AssetManager::GetLastAssetSize() -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetLastAssetSize() : 0; +/* static */ soff_t AssetManager::GetLastAssetSize() { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetLastAssetSize() : 0; } -/* static */ int AssetManager::GetAssetCount() -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetAssetCount() : 0; +/* static */ int AssetManager::GetAssetCount() { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetCount() : 0; } -/* static */ String AssetManager::GetAssetFileByIndex(int index) -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetAssetFileByIndex(index) : ""; +/* static */ String AssetManager::GetAssetFileByIndex(int index) { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetAssetFileByIndex(index) : ""; } -/* static */ String AssetManager::GetLibraryBaseFile() -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->_GetLibraryBaseFile() : ""; +/* static */ String AssetManager::GetLibraryBaseFile() { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->_GetLibraryBaseFile() : ""; } -/* static */ const AssetLibInfo *AssetManager::GetLibraryTOC() -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? &_theAssetManager->_GetLibraryTOC() : nullptr; +/* static */ const AssetLibInfo *AssetManager::GetLibraryTOC() { + assert(_theAssetManager != NULL); + return _theAssetManager ? &_theAssetManager->_GetLibraryTOC() : nullptr; } -/* static */ bool AssetManager::GetAssetLocation(const String &asset_name, AssetLocation &loc) -{ - assert(_theAssetManager != NULL); - return _theAssetManager ? _theAssetManager->GetAssetByPriority(asset_name, loc, kFile_Open, kFile_Read) : false; +/* static */ bool AssetManager::GetAssetLocation(const String &asset_name, AssetLocation &loc) { + assert(_theAssetManager != NULL); + return _theAssetManager ? _theAssetManager->GetAssetByPriority(asset_name, loc, kFile_Open, kFile_Read) : false; } -/* static */ bool AssetManager::DoesAssetExist(const String &asset_name) -{ - assert(_theAssetManager != NULL); - if (!_theAssetManager) - { - return false; - } - return _theAssetManager->_DoesAssetExist(asset_name); +/* static */ bool AssetManager::DoesAssetExist(const String &asset_name) { + assert(_theAssetManager != NULL); + if (!_theAssetManager) { + return false; + } + return _theAssetManager->_DoesAssetExist(asset_name); } /* static */ Stream *AssetManager::OpenAsset(const String &asset_name, - FileOpenMode open_mode, - FileWorkMode work_mode) -{ - assert(_theAssetManager != NULL); - if (!_theAssetManager) - { - return nullptr; - } - return _theAssetManager->OpenAssetAsStream(asset_name, open_mode, work_mode); + FileOpenMode open_mode, + FileWorkMode work_mode) { + assert(_theAssetManager != NULL); + if (!_theAssetManager) { + return nullptr; + } + return _theAssetManager->OpenAssetAsStream(asset_name, open_mode, work_mode); } AssetManager::AssetManager() - : _assetLib(*new AssetLibInfo()) - , _searchPriority(kAssetPriorityDir) - , _lastAssetSize(0) -{ + : _assetLib(*new AssetLibInfo()) + , _searchPriority(kAssetPriorityDir) + , _lastAssetSize(0) { } -bool AssetManager::_SetSearchPriority(AssetSearchPriority priority) -{ - _searchPriority = priority; - return true; +bool AssetManager::_SetSearchPriority(AssetSearchPriority priority) { + _searchPriority = priority; + return true; } -AssetSearchPriority AssetManager::_GetSearchPriority() -{ - return _searchPriority; +AssetSearchPriority AssetManager::_GetSearchPriority() { + return _searchPriority; } -AssetError AssetManager::_SetDataFile(const String &data_file) -{ - if (data_file.IsEmpty()) - { - return kAssetErrNoLibFile; - } - if (Path::ComparePaths(_assetLib.BaseFilePath, data_file) == 0) - { - return kAssetNoError; - } - AssetError err = RegisterAssetLib(data_file, ""); - return err; +AssetError AssetManager::_SetDataFile(const String &data_file) { + if (data_file.IsEmpty()) { + return kAssetErrNoLibFile; + } + if (Path::ComparePaths(_assetLib.BaseFilePath, data_file) == 0) { + return kAssetNoError; + } + AssetError err = RegisterAssetLib(data_file, ""); + return err; } -String AssetManager::_GetLibraryForAsset(const String &asset_name) -{ - if (asset_name.IsEmpty()) - { - return ""; - } - AssetInfo *asset = FindAssetByFileName(asset_name); - if (!asset) - { - // asset not found - return ""; - } - - return MakeLibraryFileNameForAsset(asset); -} - -soff_t AssetManager::_GetAssetOffset(const String &asset_name) -{ - if (asset_name.IsEmpty()) - { - return -1; - } - AssetInfo *asset = FindAssetByFileName(asset_name); - if (asset) - { - return asset->Offset; - } - return -1; -} - -soff_t AssetManager::_GetAssetSize(const String &asset_name) -{ - if (asset_name.IsEmpty()) - { - return -1; - } - AssetInfo *asset = FindAssetByFileName(asset_name); - if (asset) - { - return asset->Size; - } - return -1; -} - -soff_t AssetManager::_GetLastAssetSize() -{ - return _lastAssetSize; -} - -int AssetManager::_GetAssetCount() -{ - return _assetLib.AssetInfos.size(); -} - -String AssetManager::_GetAssetFileByIndex(int index) -{ - if ((index < 0) || ((size_t)index >= _assetLib.AssetInfos.size())) - return nullptr; - - return _assetLib.AssetInfos[index].FileName; -} - -String AssetManager::_GetLibraryBaseFile() -{ - return _assetLib.BaseFileName; -} - -const AssetLibInfo &AssetManager::_GetLibraryTOC() const -{ - return _assetLib; -} - -bool AssetManager::_DoesAssetExist(const String &asset_name) -{ - return FindAssetByFileName(asset_name) != nullptr || - File::TestReadFile(asset_name); -} - -AssetError AssetManager::RegisterAssetLib(const String &data_file, const String &password) -{ - // base path is current directory - _basePath = "."; - - // open data library - Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); - if (!in) - return kAssetErrNoLibFile; // can't be opened, return error code - - // read MultiFileLibrary header (CLIB) - // PSP: allocate struct on the heap to avoid overflowing the stack. - MFLUtil::MFLError mfl_err = MFLUtil::ReadHeader(_assetLib, in); - delete in; - - if (mfl_err != MFLUtil::kMFLNoError) - { - _assetLib.Unload(); - return kAssetErrLibParse; - } - - // fixup base library filename - String nammwas = data_file; - String data_file_fixed = data_file; - // TODO: this algorythm should be in path/string utils - data_file_fixed.TruncateToRightSection('\\'); - data_file_fixed.TruncateToRightSection('/'); - if (data_file_fixed.Compare(nammwas) != 0) - { - // store complete path - _basePath = nammwas; - _basePath.TruncateToLeft(nammwas.GetLength() - data_file_fixed.GetLength()); - _basePath.TrimRight('\\'); - _basePath.TrimRight('/'); - } - - // set library filename - _assetLib.LibFileNames[0] = data_file_fixed; - // make a lowercase backup of the original file name - _assetLib.BaseFileName = data_file_fixed; - _assetLib.BaseFileName.MakeLower(); - _assetLib.BaseFilePath = Path::MakeAbsolutePath(data_file); - return kAssetNoError; -} - -AssetInfo *AssetManager::FindAssetByFileName(const String &asset_name) -{ - for (size_t i = 0; i < _assetLib.AssetInfos.size(); ++i) - { - if (_assetLib.AssetInfos[i].FileName.CompareNoCase(asset_name) == 0) - { - return &_assetLib.AssetInfos[i]; - } - } - return nullptr; -} - -String AssetManager::MakeLibraryFileNameForAsset(const AssetInfo *asset) -{ - // deduce asset library file containing this asset - return String::FromFormat("%s/%s",_basePath.GetCStr(), _assetLib.LibFileNames[asset->LibUid].GetCStr()); -} - -bool AssetManager::GetAssetFromLib(const String &asset_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) -{ - if (open_mode != Common::kFile_Open || work_mode != Common::kFile_Read) - return false; // creating/writing is allowed only for common files on disk - - AssetInfo *asset = FindAssetByFileName(asset_name); - if (!asset) - return false; // asset not found - - String libfile = cbuf_to_string_and_free( ci_find_file(nullptr, MakeLibraryFileNameForAsset(asset)) ); - if (libfile.IsEmpty()) - return false; - loc.FileName = libfile; - loc.Offset = asset->Offset; - loc.Size = asset->Size; - return true; -} - -bool AssetManager::GetAssetFromDir(const String &file_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) -{ - String exfile = cbuf_to_string_and_free( ci_find_file(nullptr, file_name) ); - if (exfile.IsEmpty() || !Path::IsFile(exfile)) - return false; - loc.FileName = exfile; - loc.Offset = 0; - loc.Size = File::GetFileSize(exfile); - return true; -} - -bool AssetManager::GetAssetByPriority(const String &asset_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) -{ - if (_searchPriority == kAssetPriorityDir) - { - // check for disk, otherwise use datafile - return GetAssetFromDir(asset_name, loc, open_mode, work_mode) || - GetAssetFromLib(asset_name, loc, open_mode, work_mode); - } - else if (_searchPriority == kAssetPriorityLib) - { - // check datafile first, then scan directory - return GetAssetFromLib(asset_name, loc, open_mode, work_mode) || - GetAssetFromDir(asset_name, loc, open_mode, work_mode); - } - return false; -} - -Stream *AssetManager::OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode) -{ - AssetLocation loc; - if (GetAssetByPriority(asset_name, loc, open_mode, work_mode)) - { - Stream *s = File::OpenFile(loc.FileName, open_mode, work_mode); - if (s) - { - s->Seek(loc.Offset, kSeekBegin); - _lastAssetSize = loc.Size; - } - return s; - } - return nullptr; -} - - -String GetAssetErrorText(AssetError err) -{ - switch (err) - { - case kAssetNoError: - return "No error."; - case kAssetErrNoLibFile: - return "Asset library file not found or could not be opened."; - case kAssetErrLibParse: - return "Not an asset library or unsupported format."; - case kAssetErrNoManager: - return "Asset manager is not initialized."; - } - return "Unknown error."; +String AssetManager::_GetLibraryForAsset(const String &asset_name) { + if (asset_name.IsEmpty()) { + return ""; + } + AssetInfo *asset = FindAssetByFileName(asset_name); + if (!asset) { + // asset not found + return ""; + } + + return MakeLibraryFileNameForAsset(asset); +} + +soff_t AssetManager::_GetAssetOffset(const String &asset_name) { + if (asset_name.IsEmpty()) { + return -1; + } + AssetInfo *asset = FindAssetByFileName(asset_name); + if (asset) { + return asset->Offset; + } + return -1; +} + +soff_t AssetManager::_GetAssetSize(const String &asset_name) { + if (asset_name.IsEmpty()) { + return -1; + } + AssetInfo *asset = FindAssetByFileName(asset_name); + if (asset) { + return asset->Size; + } + return -1; +} + +soff_t AssetManager::_GetLastAssetSize() { + return _lastAssetSize; +} + +int AssetManager::_GetAssetCount() { + return _assetLib.AssetInfos.size(); +} + +String AssetManager::_GetAssetFileByIndex(int index) { + if ((index < 0) || ((size_t)index >= _assetLib.AssetInfos.size())) + return nullptr; + + return _assetLib.AssetInfos[index].FileName; +} + +String AssetManager::_GetLibraryBaseFile() { + return _assetLib.BaseFileName; +} + +const AssetLibInfo &AssetManager::_GetLibraryTOC() const { + return _assetLib; +} + +bool AssetManager::_DoesAssetExist(const String &asset_name) { + return FindAssetByFileName(asset_name) != nullptr || + File::TestReadFile(asset_name); +} + +AssetError AssetManager::RegisterAssetLib(const String &data_file, const String &password) { + // base path is current directory + _basePath = "."; + + // open data library + Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + if (!in) + return kAssetErrNoLibFile; // can't be opened, return error code + + // read MultiFileLibrary header (CLIB) + // PSP: allocate struct on the heap to avoid overflowing the stack. + MFLUtil::MFLError mfl_err = MFLUtil::ReadHeader(_assetLib, in); + delete in; + + if (mfl_err != MFLUtil::kMFLNoError) { + _assetLib.Unload(); + return kAssetErrLibParse; + } + + // fixup base library filename + String nammwas = data_file; + String data_file_fixed = data_file; + // TODO: this algorythm should be in path/string utils + data_file_fixed.TruncateToRightSection('\\'); + data_file_fixed.TruncateToRightSection('/'); + if (data_file_fixed.Compare(nammwas) != 0) { + // store complete path + _basePath = nammwas; + _basePath.TruncateToLeft(nammwas.GetLength() - data_file_fixed.GetLength()); + _basePath.TrimRight('\\'); + _basePath.TrimRight('/'); + } + + // set library filename + _assetLib.LibFileNames[0] = data_file_fixed; + // make a lowercase backup of the original file name + _assetLib.BaseFileName = data_file_fixed; + _assetLib.BaseFileName.MakeLower(); + _assetLib.BaseFilePath = Path::MakeAbsolutePath(data_file); + return kAssetNoError; +} + +AssetInfo *AssetManager::FindAssetByFileName(const String &asset_name) { + for (size_t i = 0; i < _assetLib.AssetInfos.size(); ++i) { + if (_assetLib.AssetInfos[i].FileName.CompareNoCase(asset_name) == 0) { + return &_assetLib.AssetInfos[i]; + } + } + return nullptr; +} + +String AssetManager::MakeLibraryFileNameForAsset(const AssetInfo *asset) { + // deduce asset library file containing this asset + return String::FromFormat("%s/%s", _basePath.GetCStr(), _assetLib.LibFileNames[asset->LibUid].GetCStr()); +} + +bool AssetManager::GetAssetFromLib(const String &asset_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) { + if (open_mode != Common::kFile_Open || work_mode != Common::kFile_Read) + return false; // creating/writing is allowed only for common files on disk + + AssetInfo *asset = FindAssetByFileName(asset_name); + if (!asset) + return false; // asset not found + + String libfile = cbuf_to_string_and_free(ci_find_file(nullptr, MakeLibraryFileNameForAsset(asset))); + if (libfile.IsEmpty()) + return false; + loc.FileName = libfile; + loc.Offset = asset->Offset; + loc.Size = asset->Size; + return true; +} + +bool AssetManager::GetAssetFromDir(const String &file_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) { + String exfile = cbuf_to_string_and_free(ci_find_file(nullptr, file_name)); + if (exfile.IsEmpty() || !Path::IsFile(exfile)) + return false; + loc.FileName = exfile; + loc.Offset = 0; + loc.Size = File::GetFileSize(exfile); + return true; +} + +bool AssetManager::GetAssetByPriority(const String &asset_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) { + if (_searchPriority == kAssetPriorityDir) { + // check for disk, otherwise use datafile + return GetAssetFromDir(asset_name, loc, open_mode, work_mode) || + GetAssetFromLib(asset_name, loc, open_mode, work_mode); + } else if (_searchPriority == kAssetPriorityLib) { + // check datafile first, then scan directory + return GetAssetFromLib(asset_name, loc, open_mode, work_mode) || + GetAssetFromDir(asset_name, loc, open_mode, work_mode); + } + return false; +} + +Stream *AssetManager::OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode) { + AssetLocation loc; + if (GetAssetByPriority(asset_name, loc, open_mode, work_mode)) { + Stream *s = File::OpenFile(loc.FileName, open_mode, work_mode); + if (s) { + s->Seek(loc.Offset, kSeekBegin); + _lastAssetSize = loc.Size; + } + return s; + } + return nullptr; +} + + +String GetAssetErrorText(AssetError err) { + switch (err) { + case kAssetNoError: + return "No error."; + case kAssetErrNoLibFile: + return "Asset library file not found or could not be opened."; + case kAssetErrLibParse: + return "Not an asset library or unsupported format."; + case kAssetErrNoManager: + return "Asset manager is not initialized."; + } + return "Unknown error."; } } // namespace Common diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h index f12fccba13fb..70b1c4c596cc 100644 --- a/engines/ags/shared/core/assetmanager.h +++ b/engines/ags/shared/core/assetmanager.h @@ -46,114 +46,108 @@ #include "util/file.h" // TODO: extract filestream mode constants or introduce generic ones -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class Stream; struct MultiFileLib; struct AssetLibInfo; struct AssetInfo; -enum AssetSearchPriority -{ - // TODO: rename this to something more obvious - kAssetPriorityUndefined, - kAssetPriorityLib, - kAssetPriorityDir +enum AssetSearchPriority { + // TODO: rename this to something more obvious + kAssetPriorityUndefined, + kAssetPriorityLib, + kAssetPriorityDir }; -enum AssetError -{ - kAssetNoError = 0, - kAssetErrNoLibFile = -1, // library file not found or can't be read - kAssetErrLibParse = -2, // bad library file format or read error - kAssetErrNoManager = -6, // asset manager not initialized +enum AssetError { + kAssetNoError = 0, + kAssetErrNoLibFile = -1, // library file not found or can't be read + kAssetErrLibParse = -2, // bad library file format or read error + kAssetErrNoManager = -6, // asset manager not initialized }; // Explicit location of asset data -struct AssetLocation -{ - String FileName; // file where asset is located - soff_t Offset; // asset's position in file (in bytes) - soff_t Size; // asset's size (in bytes) +struct AssetLocation { + String FileName; // file where asset is located + soff_t Offset; // asset's position in file (in bytes) + soff_t Size; // asset's size (in bytes) - AssetLocation(); + AssetLocation(); }; -class AssetManager -{ +class AssetManager { public: - static bool CreateInstance(); - static void DestroyInstance(); - ~AssetManager(); - - static bool SetSearchPriority(AssetSearchPriority priority); - static AssetSearchPriority GetSearchPriority(); - - // Test if given file is main data file - static bool IsDataFile(const String &data_file); - // Read data file table of contents into provided struct - static AssetError ReadDataFileTOC(const String &data_file, AssetLibInfo &lib); - - // NOTE: this group of methods are only temporarily public - static AssetError SetDataFile(const String &data_file); - static String GetLibraryBaseFile(); - static const AssetLibInfo *GetLibraryTOC(); - static int GetAssetCount(); - static String GetLibraryForAsset(const String &asset_name); - static String GetAssetFileByIndex(int index); - static soff_t GetAssetOffset(const String &asset_name); - static soff_t GetAssetSize(const String &asset_name); - // TODO: instead of this support streams that work in a file subsection, limited by size - static soff_t GetLastAssetSize(); - // TODO: this is a workaround that lets us use back-end specific kind of streams - // to read the asset data. This is not ideal, because it limits us to reading from file. - // The better solution could be returning a standart stream object (like std::stream, - // or even std::streambuf), which is used to initialize both AGS and back-end compatible - // stream wrappers. - static bool GetAssetLocation(const String &asset_name, AssetLocation &loc); - - static bool DoesAssetExist(const String &asset_name); - static Stream *OpenAsset(const String &asset_name, - FileOpenMode open_mode = kFile_Open, - FileWorkMode work_mode = kFile_Read); + static bool CreateInstance(); + static void DestroyInstance(); + ~AssetManager(); + + static bool SetSearchPriority(AssetSearchPriority priority); + static AssetSearchPriority GetSearchPriority(); + + // Test if given file is main data file + static bool IsDataFile(const String &data_file); + // Read data file table of contents into provided struct + static AssetError ReadDataFileTOC(const String &data_file, AssetLibInfo &lib); + + // NOTE: this group of methods are only temporarily public + static AssetError SetDataFile(const String &data_file); + static String GetLibraryBaseFile(); + static const AssetLibInfo *GetLibraryTOC(); + static int GetAssetCount(); + static String GetLibraryForAsset(const String &asset_name); + static String GetAssetFileByIndex(int index); + static soff_t GetAssetOffset(const String &asset_name); + static soff_t GetAssetSize(const String &asset_name); + // TODO: instead of this support streams that work in a file subsection, limited by size + static soff_t GetLastAssetSize(); + // TODO: this is a workaround that lets us use back-end specific kind of streams + // to read the asset data. This is not ideal, because it limits us to reading from file. + // The better solution could be returning a standart stream object (like std::stream, + // or even std::streambuf), which is used to initialize both AGS and back-end compatible + // stream wrappers. + static bool GetAssetLocation(const String &asset_name, AssetLocation &loc); + + static bool DoesAssetExist(const String &asset_name); + static Stream *OpenAsset(const String &asset_name, + FileOpenMode open_mode = kFile_Open, + FileWorkMode work_mode = kFile_Read); private: - AssetManager(); - - bool _SetSearchPriority(AssetSearchPriority priority); - AssetSearchPriority _GetSearchPriority(); - AssetError _SetDataFile(const String &data_file); - String _GetLibraryBaseFile(); - const AssetLibInfo &_GetLibraryTOC() const; - int _GetAssetCount(); - String _GetLibraryForAsset(const String &asset_name); - String _GetAssetFileByIndex(int index); - soff_t _GetAssetOffset(const String &asset_name); - soff_t _GetAssetSize(const String &asset_name); - soff_t _GetLastAssetSize(); - - AssetError RegisterAssetLib(const String &data_file, const String &password); - - bool _DoesAssetExist(const String &asset_name); - - AssetInfo *FindAssetByFileName(const String &asset_name); - String MakeLibraryFileNameForAsset(const AssetInfo *asset); - - bool GetAssetFromLib(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); - bool GetAssetFromDir(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); - bool GetAssetByPriority(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); - Stream *OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode); - - static AssetManager *_theAssetManager; - AssetSearchPriority _searchPriority; - - AssetLibInfo &_assetLib; - String _basePath; // library's parent path (directory) - soff_t _lastAssetSize; // size of asset that was opened last time + AssetManager(); + + bool _SetSearchPriority(AssetSearchPriority priority); + AssetSearchPriority _GetSearchPriority(); + AssetError _SetDataFile(const String &data_file); + String _GetLibraryBaseFile(); + const AssetLibInfo &_GetLibraryTOC() const; + int _GetAssetCount(); + String _GetLibraryForAsset(const String &asset_name); + String _GetAssetFileByIndex(int index); + soff_t _GetAssetOffset(const String &asset_name); + soff_t _GetAssetSize(const String &asset_name); + soff_t _GetLastAssetSize(); + + AssetError RegisterAssetLib(const String &data_file, const String &password); + + bool _DoesAssetExist(const String &asset_name); + + AssetInfo *FindAssetByFileName(const String &asset_name); + String MakeLibraryFileNameForAsset(const AssetInfo *asset); + + bool GetAssetFromLib(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); + bool GetAssetFromDir(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); + bool GetAssetByPriority(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); + Stream *OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode); + + static AssetManager *_theAssetManager; + AssetSearchPriority _searchPriority; + + AssetLibInfo &_assetLib; + String _basePath; // library's parent path (directory) + soff_t _lastAssetSize; // size of asset that was opened last time }; diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h index 85f640973e35..c97ba949cd5f 100644 --- a/engines/ags/shared/core/platform.h +++ b/engines/ags/shared/core/platform.h @@ -27,101 +27,101 @@ // check Android first because sometimes it can get confused with host OS #if defined(__ANDROID__) || defined(ANDROID) - #define AGS_PLATFORM_OS_WINDOWS (0) - #define AGS_PLATFORM_OS_LINUX (0) - #define AGS_PLATFORM_OS_MACOS (0) - #define AGS_PLATFORM_OS_ANDROID (1) - #define AGS_PLATFORM_OS_IOS (0) - #define AGS_PLATFORM_OS_PSP (0) +#define AGS_PLATFORM_OS_WINDOWS (0) +#define AGS_PLATFORM_OS_LINUX (0) +#define AGS_PLATFORM_OS_MACOS (0) +#define AGS_PLATFORM_OS_ANDROID (1) +#define AGS_PLATFORM_OS_IOS (0) +#define AGS_PLATFORM_OS_PSP (0) #elif defined(_WIN32) - //define something for Windows (32-bit and 64-bit) - #define AGS_PLATFORM_OS_WINDOWS (1) - #define AGS_PLATFORM_OS_LINUX (0) - #define AGS_PLATFORM_OS_MACOS (0) - #define AGS_PLATFORM_OS_ANDROID (0) - #define AGS_PLATFORM_OS_IOS (0) - #define AGS_PLATFORM_OS_PSP (0) +//define something for Windows (32-bit and 64-bit) +#define AGS_PLATFORM_OS_WINDOWS (1) +#define AGS_PLATFORM_OS_LINUX (0) +#define AGS_PLATFORM_OS_MACOS (0) +#define AGS_PLATFORM_OS_ANDROID (0) +#define AGS_PLATFORM_OS_IOS (0) +#define AGS_PLATFORM_OS_PSP (0) #elif defined(__APPLE__) - #include "TargetConditionals.h" - #ifndef TARGET_OS_SIMULATOR - #define TARGET_OS_SIMULATOR (0) - #endif - #ifndef TARGET_OS_IOS - #define TARGET_OS_IOS (0) - #endif - #ifndef TARGET_OS_OSX - #define TARGET_OS_OSX (0) - #endif +#include "TargetConditionals.h" +#ifndef TARGET_OS_SIMULATOR +#define TARGET_OS_SIMULATOR (0) +#endif +#ifndef TARGET_OS_IOS +#define TARGET_OS_IOS (0) +#endif +#ifndef TARGET_OS_OSX +#define TARGET_OS_OSX (0) +#endif - #if TARGET_OS_SIMULATOR || TARGET_IPHONE_SIMULATOR - #define AGS_PLATFORM_OS_WINDOWS (0) - #define AGS_PLATFORM_OS_LINUX (0) - #define AGS_PLATFORM_OS_MACOS (0) - #define AGS_PLATFORM_OS_ANDROID (0) - #define AGS_PLATFORM_OS_IOS (1) - #define AGS_PLATFORM_OS_PSP (0) - #elif TARGET_OS_IOS || TARGET_OS_IPHONE - #define AGS_PLATFORM_OS_WINDOWS (0) - #define AGS_PLATFORM_OS_LINUX (0) - #define AGS_PLATFORM_OS_MACOS (0) - #define AGS_PLATFORM_OS_ANDROID (0) - #define AGS_PLATFORM_OS_IOS (1) - #define AGS_PLATFORM_OS_PSP (0) - #elif TARGET_OS_OSX || TARGET_OS_MAC - #define AGS_PLATFORM_OS_WINDOWS (0) - #define AGS_PLATFORM_OS_LINUX (0) - #define AGS_PLATFORM_OS_MACOS (1) - #define AGS_PLATFORM_OS_ANDROID (0) - #define AGS_PLATFORM_OS_IOS (0) - #define AGS_PLATFORM_OS_PSP (0) - #else - #error "Unknown Apple platform" - #endif +#if TARGET_OS_SIMULATOR || TARGET_IPHONE_SIMULATOR +#define AGS_PLATFORM_OS_WINDOWS (0) +#define AGS_PLATFORM_OS_LINUX (0) +#define AGS_PLATFORM_OS_MACOS (0) +#define AGS_PLATFORM_OS_ANDROID (0) +#define AGS_PLATFORM_OS_IOS (1) +#define AGS_PLATFORM_OS_PSP (0) +#elif TARGET_OS_IOS || TARGET_OS_IPHONE +#define AGS_PLATFORM_OS_WINDOWS (0) +#define AGS_PLATFORM_OS_LINUX (0) +#define AGS_PLATFORM_OS_MACOS (0) +#define AGS_PLATFORM_OS_ANDROID (0) +#define AGS_PLATFORM_OS_IOS (1) +#define AGS_PLATFORM_OS_PSP (0) +#elif TARGET_OS_OSX || TARGET_OS_MAC +#define AGS_PLATFORM_OS_WINDOWS (0) +#define AGS_PLATFORM_OS_LINUX (0) +#define AGS_PLATFORM_OS_MACOS (1) +#define AGS_PLATFORM_OS_ANDROID (0) +#define AGS_PLATFORM_OS_IOS (0) +#define AGS_PLATFORM_OS_PSP (0) +#else +#error "Unknown Apple platform" +#endif #elif defined(__linux__) - #define AGS_PLATFORM_OS_WINDOWS (0) - #define AGS_PLATFORM_OS_LINUX (1) - #define AGS_PLATFORM_OS_MACOS (0) - #define AGS_PLATFORM_OS_ANDROID (0) - #define AGS_PLATFORM_OS_IOS (0) - #define AGS_PLATFORM_OS_PSP (0) +#define AGS_PLATFORM_OS_WINDOWS (0) +#define AGS_PLATFORM_OS_LINUX (1) +#define AGS_PLATFORM_OS_MACOS (0) +#define AGS_PLATFORM_OS_ANDROID (0) +#define AGS_PLATFORM_OS_IOS (0) +#define AGS_PLATFORM_OS_PSP (0) #else - #error "Unknown platform" +#error "Unknown platform" #endif #if defined(__LP64__) - // LP64 machine, OS X or Linux - // int 32bit | long 64bit | long long 64bit | void* 64bit - #define AGS_PLATFORM_64BIT (1) +// LP64 machine, OS X or Linux +// int 32bit | long 64bit | long long 64bit | void* 64bit +#define AGS_PLATFORM_64BIT (1) #elif defined(_WIN64) - // LLP64 machine, Windows - // int 32bit | long 32bit | long long 64bit | void* 64bit - #define AGS_PLATFORM_64BIT (1) +// LLP64 machine, Windows +// int 32bit | long 32bit | long long 64bit | void* 64bit +#define AGS_PLATFORM_64BIT (1) #else - // 32-bit machine, Windows or Linux or OS X - // int 32bit | long 32bit | long long 64bit | void* 32bit - #define AGS_PLATFORM_64BIT (0) +// 32-bit machine, Windows or Linux or OS X +// int 32bit | long 32bit | long long 64bit | void* 32bit +#define AGS_PLATFORM_64BIT (0) #endif #if defined(_WIN32) - #define AGS_PLATFORM_ENDIAN_LITTLE (1) - #define AGS_PLATFORM_ENDIAN_BIG (0) +#define AGS_PLATFORM_ENDIAN_LITTLE (1) +#define AGS_PLATFORM_ENDIAN_BIG (0) #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - #define AGS_PLATFORM_ENDIAN_LITTLE (1) - #define AGS_PLATFORM_ENDIAN_BIG (0) +#define AGS_PLATFORM_ENDIAN_LITTLE (1) +#define AGS_PLATFORM_ENDIAN_BIG (0) #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - #define AGS_PLATFORM_ENDIAN_LITTLE (0) - #define AGS_PLATFORM_ENDIAN_BIG (1) +#define AGS_PLATFORM_ENDIAN_LITTLE (0) +#define AGS_PLATFORM_ENDIAN_BIG (1) #else - #error "Unknown platform" +#error "Unknown platform" #endif #if defined(_DEBUG) - #define AGS_PLATFORM_DEBUG (1) +#define AGS_PLATFORM_DEBUG (1) #elif ! defined(NDEBUG) - #define AGS_PLATFORM_DEBUG (1) +#define AGS_PLATFORM_DEBUG (1) #else - #define AGS_PLATFORM_DEBUG (0) +#define AGS_PLATFORM_DEBUG (0) #endif #endif diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index d476de63e6e5..90cf583270b2 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -40,20 +40,20 @@ // Not all compilers have this. Added in clang and gcc followed #ifndef __has_attribute - #define __has_attribute(x) 0 +#define __has_attribute(x) 0 #endif #ifndef FORCEINLINE - #ifdef _MSC_VER - #define FORCEINLINE __forceinline +#ifdef _MSC_VER +#define FORCEINLINE __forceinline - #elif defined (__GNUC__) || __has_attribute(__always_inline__) - #define FORCEINLINE inline __attribute__((__always_inline__)) +#elif defined (__GNUC__) || __has_attribute(__always_inline__) +#define FORCEINLINE inline __attribute__((__always_inline__)) - #else - #define FORCEINLINE inline +#else +#define FORCEINLINE inline - #endif +#endif #endif // Stream offset type @@ -63,10 +63,9 @@ typedef int64_t soff_t; #define color_t int32_t // TODO: use distinct fixed point class -enum -{ - kShift = 16, - kUnit = 1 << kShift +enum { + kShift = 16, + kUnit = 1 << kShift }; #endif diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp index d474241d4c3e..afddfdee2f8e 100644 --- a/engines/ags/shared/debugging/debugmanager.cpp +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -24,237 +24,202 @@ #include "debug/debugmanager.h" #include "util/string_types.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { DebugOutput::DebugOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity, bool enabled) - : _id(id) - , _handler(handler) - , _enabled(enabled) - , _defaultVerbosity(def_verbosity) -{ - _groupFilter.resize(DbgMgr._lastGroupID + 1, _defaultVerbosity); + : _id(id) + , _handler(handler) + , _enabled(enabled) + , _defaultVerbosity(def_verbosity) { + _groupFilter.resize(DbgMgr._lastGroupID + 1, _defaultVerbosity); } -String DebugOutput::GetID() const -{ - return _id; +String DebugOutput::GetID() const { + return _id; } -IOutputHandler *DebugOutput::GetHandler() const -{ - return _handler; +IOutputHandler *DebugOutput::GetHandler() const { + return _handler; } -bool DebugOutput::IsEnabled() const -{ - return _enabled; +bool DebugOutput::IsEnabled() const { + return _enabled; } -void DebugOutput::SetEnabled(bool enable) -{ - _enabled = enable; +void DebugOutput::SetEnabled(bool enable) { + _enabled = enable; } -void DebugOutput::SetGroupFilter(DebugGroupID id, MessageType verbosity) -{ - uint32_t key = DbgMgr.GetGroup(id).UID.ID; - if (key != kDbgGroup_None) - _groupFilter[key] = verbosity; - else - _unresolvedGroups.insert(std::make_pair(id.SID, verbosity)); +void DebugOutput::SetGroupFilter(DebugGroupID id, MessageType verbosity) { + uint32_t key = DbgMgr.GetGroup(id).UID.ID; + if (key != kDbgGroup_None) + _groupFilter[key] = verbosity; + else + _unresolvedGroups.insert(std::make_pair(id.SID, verbosity)); } -void DebugOutput::SetAllGroupFilters(MessageType verbosity) -{ - for (auto &group : _groupFilter) - group = verbosity; - for (auto &group : _unresolvedGroups) - group.second = verbosity; +void DebugOutput::SetAllGroupFilters(MessageType verbosity) { + for (auto &group : _groupFilter) + group = verbosity; + for (auto &group : _unresolvedGroups) + group.second = verbosity; } -void DebugOutput::ClearGroupFilters() -{ - for (auto &gf : _groupFilter) - gf = kDbgMsg_None; - _unresolvedGroups.clear(); +void DebugOutput::ClearGroupFilters() { + for (auto &gf : _groupFilter) + gf = kDbgMsg_None; + _unresolvedGroups.clear(); } -void DebugOutput::ResolveGroupID(DebugGroupID id) -{ - if (!id.IsValid()) - return; - - DebugGroupID real_id = DbgMgr.GetGroup(id).UID; - if (real_id.IsValid()) - { - if (_groupFilter.size() <= id.ID) - _groupFilter.resize(id.ID + 1, _defaultVerbosity); - GroupNameToMTMap::const_iterator it = _unresolvedGroups.find(real_id.SID); - if (it != _unresolvedGroups.end()) - { - _groupFilter[real_id.ID] = it->second; - _unresolvedGroups.erase(it); - } - } +void DebugOutput::ResolveGroupID(DebugGroupID id) { + if (!id.IsValid()) + return; + + DebugGroupID real_id = DbgMgr.GetGroup(id).UID; + if (real_id.IsValid()) { + if (_groupFilter.size() <= id.ID) + _groupFilter.resize(id.ID + 1, _defaultVerbosity); + GroupNameToMTMap::const_iterator it = _unresolvedGroups.find(real_id.SID); + if (it != _unresolvedGroups.end()) { + _groupFilter[real_id.ID] = it->second; + _unresolvedGroups.erase(it); + } + } } -bool DebugOutput::TestGroup(DebugGroupID id, MessageType mt) const -{ - DebugGroupID real_id = DbgMgr.GetGroup(id).UID; - if (real_id.ID == kDbgGroup_None || real_id.ID >= _groupFilter.size()) - return false; - return (_groupFilter[real_id.ID] >= mt) != 0; +bool DebugOutput::TestGroup(DebugGroupID id, MessageType mt) const { + DebugGroupID real_id = DbgMgr.GetGroup(id).UID; + if (real_id.ID == kDbgGroup_None || real_id.ID >= _groupFilter.size()) + return false; + return (_groupFilter[real_id.ID] >= mt) != 0; } -DebugManager::DebugManager() -{ - // Add hardcoded groups - RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Main, "main"), "")); - RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Game, "game"), "Game")); - RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Script, "script"), "Script")); - RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_SprCache, "sprcache"), "Sprite cache")); - RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_ManObj, "manobj"), "Managed obj")); - _firstFreeGroupID = _groups.size(); - _lastGroupID = _firstFreeGroupID; +DebugManager::DebugManager() { + // Add hardcoded groups + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Main, "main"), "")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Game, "game"), "Game")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_Script, "script"), "Script")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_SprCache, "sprcache"), "Sprite cache")); + RegisterGroup(DebugGroup(DebugGroupID(kDbgGroup_ManObj, "manobj"), "Managed obj")); + _firstFreeGroupID = _groups.size(); + _lastGroupID = _firstFreeGroupID; } -DebugGroup DebugManager::GetGroup(DebugGroupID id) -{ - if (id.ID != kDbgGroup_None) - { - return id.ID < _groups.size() ? _groups[id.ID] : DebugGroup(); - } - else if (!id.SID.IsEmpty()) - { - GroupByStringMap::const_iterator it = _groupByStrLookup.find(id.SID); - return it != _groupByStrLookup.end() ? _groups[it->second.ID] : DebugGroup(); - } - return DebugGroup(); +DebugGroup DebugManager::GetGroup(DebugGroupID id) { + if (id.ID != kDbgGroup_None) { + return id.ID < _groups.size() ? _groups[id.ID] : DebugGroup(); + } else if (!id.SID.IsEmpty()) { + GroupByStringMap::const_iterator it = _groupByStrLookup.find(id.SID); + return it != _groupByStrLookup.end() ? _groups[it->second.ID] : DebugGroup(); + } + return DebugGroup(); } -PDebugOutput DebugManager::GetOutput(const String &id) -{ - OutMap::const_iterator it = _outputs.find(id); - return it != _outputs.end() ? it->second.Target : PDebugOutput(); +PDebugOutput DebugManager::GetOutput(const String &id) { + OutMap::const_iterator it = _outputs.find(id); + return it != _outputs.end() ? it->second.Target : PDebugOutput(); } -DebugGroup DebugManager::RegisterGroup(const String &id, const String &out_name) -{ - DebugGroup group = GetGroup(id); - if (group.UID.IsValid()) - return group; - group = DebugGroup(DebugGroupID(++DbgMgr._lastGroupID, id), out_name); - _groups.push_back(group); - _groupByStrLookup[group.UID.SID] = group.UID; - - // Resolve group reference on every output target - for (OutMap::const_iterator it = _outputs.begin(); it != _outputs.end(); ++it) - { - it->second.Target->ResolveGroupID(group.UID); - } - return group; +DebugGroup DebugManager::RegisterGroup(const String &id, const String &out_name) { + DebugGroup group = GetGroup(id); + if (group.UID.IsValid()) + return group; + group = DebugGroup(DebugGroupID(++DbgMgr._lastGroupID, id), out_name); + _groups.push_back(group); + _groupByStrLookup[group.UID.SID] = group.UID; + + // Resolve group reference on every output target + for (OutMap::const_iterator it = _outputs.begin(); it != _outputs.end(); ++it) { + it->second.Target->ResolveGroupID(group.UID); + } + return group; } -void DebugManager::RegisterGroup(const DebugGroup &group) -{ - _groups.push_back(group); - _groupByStrLookup[group.UID.SID] = group.UID; +void DebugManager::RegisterGroup(const DebugGroup &group) { + _groups.push_back(group); + _groupByStrLookup[group.UID.SID] = group.UID; } -PDebugOutput DebugManager::RegisterOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity, bool enabled) -{ - _outputs[id].Target = PDebugOutput(new DebugOutput(id, handler, def_verbosity, enabled)); - _outputs[id].Suppressed = false; - return _outputs[id].Target; +PDebugOutput DebugManager::RegisterOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity, bool enabled) { + _outputs[id].Target = PDebugOutput(new DebugOutput(id, handler, def_verbosity, enabled)); + _outputs[id].Suppressed = false; + return _outputs[id].Target; } -void DebugManager::UnregisterAll() -{ - _lastGroupID = _firstFreeGroupID; - _groups.clear(); - _groupByStrLookup.clear(); - _outputs.clear(); +void DebugManager::UnregisterAll() { + _lastGroupID = _firstFreeGroupID; + _groups.clear(); + _groupByStrLookup.clear(); + _outputs.clear(); } -void DebugManager::UnregisterGroup(DebugGroupID id) -{ - DebugGroup group = GetGroup(id); - if (!group.UID.IsValid()) - return; - _groups[group.UID.ID] = DebugGroup(); - _groupByStrLookup.erase(group.UID.SID); +void DebugManager::UnregisterGroup(DebugGroupID id) { + DebugGroup group = GetGroup(id); + if (!group.UID.IsValid()) + return; + _groups[group.UID.ID] = DebugGroup(); + _groupByStrLookup.erase(group.UID.SID); } -void DebugManager::UnregisterOutput(const String &id) -{ - _outputs.erase(id); +void DebugManager::UnregisterOutput(const String &id) { + _outputs.erase(id); } -void DebugManager::Print(DebugGroupID group_id, MessageType mt, const String &text) -{ - const DebugGroup &group = GetGroup(group_id); - DebugMessage msg(text, group.UID.ID, group.OutputName, mt); +void DebugManager::Print(DebugGroupID group_id, MessageType mt, const String &text) { + const DebugGroup &group = GetGroup(group_id); + DebugMessage msg(text, group.UID.ID, group.OutputName, mt); - for (OutMap::iterator it = _outputs.begin(); it != _outputs.end(); ++it) - { - SendMessage(it->second, msg); - } + for (OutMap::iterator it = _outputs.begin(); it != _outputs.end(); ++it) { + SendMessage(it->second, msg); + } } -void DebugManager::SendMessage(const String &out_id, const DebugMessage &msg) -{ - OutMap::iterator it = _outputs.find(out_id); - if (it != _outputs.end()) - SendMessage(it->second, msg); +void DebugManager::SendMessage(const String &out_id, const DebugMessage &msg) { + OutMap::iterator it = _outputs.find(out_id); + if (it != _outputs.end()) + SendMessage(it->second, msg); } -void DebugManager::SendMessage(OutputSlot &out, const DebugMessage &msg) -{ - IOutputHandler *handler = out.Target->GetHandler(); - if (!handler || !out.Target->IsEnabled() || out.Suppressed) - return; - if (!out.Target->TestGroup(msg.GroupID, msg.MT)) - return; - // We suppress current target before the call so that if it makes - // a call to output system itself, message would not print to the - // same target - out.Suppressed = true; - handler->PrintMessage(msg); - out.Suppressed = false; +void DebugManager::SendMessage(OutputSlot &out, const DebugMessage &msg) { + IOutputHandler *handler = out.Target->GetHandler(); + if (!handler || !out.Target->IsEnabled() || out.Suppressed) + return; + if (!out.Target->TestGroup(msg.GroupID, msg.MT)) + return; + // We suppress current target before the call so that if it makes + // a call to output system itself, message would not print to the + // same target + out.Suppressed = true; + handler->PrintMessage(msg); + out.Suppressed = false; } // TODO: move this to the dynamically allocated engine object whenever it is implemented DebugManager DbgMgr; -namespace Debug -{ +namespace Debug { -void Printf(const char *fmt, ...) -{ - va_list argptr; - va_start(argptr, fmt); - DbgMgr.Print(kDbgGroup_Main, kDbgMsg_Default, String::FromFormatV(fmt, argptr)); - va_end(argptr); +void Printf(const char *fmt, ...) { + va_list argptr; + va_start(argptr, fmt); + DbgMgr.Print(kDbgGroup_Main, kDbgMsg_Default, String::FromFormatV(fmt, argptr)); + va_end(argptr); } -void Printf(MessageType mt, const char *fmt, ...) -{ - va_list argptr; - va_start(argptr, fmt); - DbgMgr.Print(kDbgGroup_Main, mt, String::FromFormatV(fmt, argptr)); - va_end(argptr); +void Printf(MessageType mt, const char *fmt, ...) { + va_list argptr; + va_start(argptr, fmt); + DbgMgr.Print(kDbgGroup_Main, mt, String::FromFormatV(fmt, argptr)); + va_end(argptr); } -void Printf(DebugGroupID group, MessageType mt, const char *fmt, ...) -{ - va_list argptr; - va_start(argptr, fmt); - DbgMgr.Print(group, mt, String::FromFormatV(fmt, argptr)); - va_end(argptr); +void Printf(DebugGroupID group, MessageType mt, const char *fmt, ...) { + va_list argptr; + va_start(argptr, fmt); + DbgMgr.Print(group, mt, String::FromFormatV(fmt, argptr)); + va_end(argptr); } } // namespace Debug diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index d001012d5a5a..696881b65d88 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -54,114 +54,108 @@ #include "util/string.h" #include "util/string_types.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // DebugGroup is a message sender definition, identified by DebugGroupID // and providing OutputName that could be used when printing its messages. // OutputName may or may not be same as DebugGroupID.SID. -struct DebugGroup -{ - DebugGroupID UID; - String OutputName; +struct DebugGroup { + DebugGroupID UID; + String OutputName; - DebugGroup() {} - DebugGroup(DebugGroupID id, String out_name) : UID(id), OutputName(out_name) {} + DebugGroup() {} + DebugGroup(DebugGroupID id, String out_name) : UID(id), OutputName(out_name) {} }; // DebugOutput is a slot for IOutputHandler with its own group filter -class DebugOutput -{ +class DebugOutput { public: - DebugOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true); - - String GetID() const; - IOutputHandler *GetHandler() const; - - bool IsEnabled() const; - void SetEnabled(bool enable); - // Setup group filter: either allow or disallow a group with the given ID - void SetGroupFilter(DebugGroupID id, MessageType verbosity); - // Assign same verbosity level to all known groups - void SetAllGroupFilters(MessageType verbosity); - // Clear all group filters; this efficiently disables everything - void ClearGroupFilters(); - // Try to resolve group filter unknown IDs - void ResolveGroupID(DebugGroupID id); - // Test if given group id is permitted - bool TestGroup(DebugGroupID id, MessageType mt) const; + DebugOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true); + + String GetID() const; + IOutputHandler *GetHandler() const; + + bool IsEnabled() const; + void SetEnabled(bool enable); + // Setup group filter: either allow or disallow a group with the given ID + void SetGroupFilter(DebugGroupID id, MessageType verbosity); + // Assign same verbosity level to all known groups + void SetAllGroupFilters(MessageType verbosity); + // Clear all group filters; this efficiently disables everything + void ClearGroupFilters(); + // Try to resolve group filter unknown IDs + void ResolveGroupID(DebugGroupID id); + // Test if given group id is permitted + bool TestGroup(DebugGroupID id, MessageType mt) const; private: - String _id; - IOutputHandler *_handler; - bool _enabled; - MessageType _defaultVerbosity; - // Set of permitted groups' numeric IDs - std::vector _groupFilter; - // Set of unresolved groups, which numeric IDs are not yet known - typedef std::unordered_map GroupNameToMTMap; - GroupNameToMTMap _unresolvedGroups; + String _id; + IOutputHandler *_handler; + bool _enabled; + MessageType _defaultVerbosity; + // Set of permitted groups' numeric IDs + std::vector _groupFilter; + // Set of unresolved groups, which numeric IDs are not yet known + typedef std::unordered_map GroupNameToMTMap; + GroupNameToMTMap _unresolvedGroups; }; typedef std::shared_ptr PDebugOutput; -class DebugManager -{ - friend class DebugOutput; +class DebugManager { + friend class DebugOutput; public: - DebugManager(); - - // Gets full group ID for any partial one; if the group is not registered returns unset ID - DebugGroup GetGroup(DebugGroupID id); - // Gets output control interface for the given ID - PDebugOutput GetOutput(const String &id); - // Registers debugging group with the given string ID; numeric ID - // will be assigned internally. Returns full ID pair. - // If the group with such string id already exists, returns existing ID. - DebugGroup RegisterGroup(const String &id, const String &out_name); - // Registers output delegate for passing debug messages to; - // if the output with such id already exists, replaces the old one - PDebugOutput RegisterOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true); - // Unregisters all groups and all targets - void UnregisterAll(); - // Unregisters debugging group with the given ID - void UnregisterGroup(DebugGroupID id); - // Unregisters output delegate with the given ID - void UnregisterOutput(const String &id); - - // Output message of given group and message type - void Print(DebugGroupID group_id, MessageType mt, const String &text); - // Send message directly to the output with given id; the message - // must pass the output's message filter though - void SendMessage(const String &out_id, const DebugMessage &msg); + DebugManager(); + + // Gets full group ID for any partial one; if the group is not registered returns unset ID + DebugGroup GetGroup(DebugGroupID id); + // Gets output control interface for the given ID + PDebugOutput GetOutput(const String &id); + // Registers debugging group with the given string ID; numeric ID + // will be assigned internally. Returns full ID pair. + // If the group with such string id already exists, returns existing ID. + DebugGroup RegisterGroup(const String &id, const String &out_name); + // Registers output delegate for passing debug messages to; + // if the output with such id already exists, replaces the old one + PDebugOutput RegisterOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true); + // Unregisters all groups and all targets + void UnregisterAll(); + // Unregisters debugging group with the given ID + void UnregisterGroup(DebugGroupID id); + // Unregisters output delegate with the given ID + void UnregisterOutput(const String &id); + + // Output message of given group and message type + void Print(DebugGroupID group_id, MessageType mt, const String &text); + // Send message directly to the output with given id; the message + // must pass the output's message filter though + void SendMessage(const String &out_id, const DebugMessage &msg); private: - // OutputSlot struct wraps over output target and adds a flag which indicates - // that this target is temporarily disabled (for internal use only) - struct OutputSlot - { - PDebugOutput Target; - bool Suppressed; - - OutputSlot() : Suppressed(false) {} - }; - - typedef std::vector GroupVector; - typedef std::unordered_map GroupByStringMap; - typedef std::unordered_map OutMap; - - void RegisterGroup(const DebugGroup &id); - void SendMessage(OutputSlot &out, const DebugMessage &msg); - - uint32_t _firstFreeGroupID; - uint32_t _lastGroupID; - GroupVector _groups; - GroupByStringMap _groupByStrLookup; - OutMap _outputs; + // OutputSlot struct wraps over output target and adds a flag which indicates + // that this target is temporarily disabled (for internal use only) + struct OutputSlot { + PDebugOutput Target; + bool Suppressed; + + OutputSlot() : Suppressed(false) {} + }; + + typedef std::vector GroupVector; + typedef std::unordered_map GroupByStringMap; + typedef std::unordered_map OutMap; + + void RegisterGroup(const DebugGroup &id); + void SendMessage(OutputSlot &out, const DebugMessage &msg); + + uint32_t _firstFreeGroupID; + uint32_t _lastGroupID; + GroupVector _groups; + GroupByStringMap _groupByStrLookup; + OutMap _outputs; }; // TODO: move this to the dynamically allocated engine object whenever it is implemented diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h index 7e18324357bd..9f00c411dcf9 100644 --- a/engines/ags/shared/debugging/out.h +++ b/engines/ags/shared/debugging/out.h @@ -79,83 +79,81 @@ #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // Message types provide distinction for debug messages by their intent. -enum MessageType -{ - kDbgMsg_None = 0, - // Alerts may be informative messages with topmost level of importance, - // such as reporting engine startup and shutdown. - kDbgMsg_Alert , - // Fatal errors are ones that make program abort immediately. - kDbgMsg_Fatal , - // Error messages are about engine not being able to perform requested - // operation in a situation when that will affect game playability and - // further execution. - kDbgMsg_Error , - // Warnings are made when unexpected or non-standart behavior - // is detected in program, which is not immediately critical, - // but may be a symptom of a bigger problem. - kDbgMsg_Warn , - // General information messages. - kDbgMsg_Info , - // Debug reason is for arbitrary information about events and current - // game state. - kDbgMsg_Debug , +enum MessageType { + kDbgMsg_None = 0, + // Alerts may be informative messages with topmost level of importance, + // such as reporting engine startup and shutdown. + kDbgMsg_Alert , + // Fatal errors are ones that make program abort immediately. + kDbgMsg_Fatal , + // Error messages are about engine not being able to perform requested + // operation in a situation when that will affect game playability and + // further execution. + kDbgMsg_Error , + // Warnings are made when unexpected or non-standart behavior + // is detected in program, which is not immediately critical, + // but may be a symptom of a bigger problem. + kDbgMsg_Warn , + // General information messages. + kDbgMsg_Info , + // Debug reason is for arbitrary information about events and current + // game state. + kDbgMsg_Debug , - // Convenient aliases - kDbgMsg_Default = kDbgMsg_Debug, - kDbgMsg_All = kDbgMsg_Debug + // Convenient aliases + kDbgMsg_Default = kDbgMsg_Debug, + kDbgMsg_All = kDbgMsg_Debug }; // This enumeration is a list of common hard-coded groups, but more could // be added via debugging configuration interface (see 'debug/debug.h'). -enum CommonDebugGroup -{ - kDbgGroup_None = -1, - // Main debug group is for reporting general engine status and issues - kDbgGroup_Main = 0, - // Game group is for logging game logic state and issues - kDbgGroup_Game, - // Log from the game script - kDbgGroup_Script, - // Sprite cache logging - kDbgGroup_SprCache, - // Group for debugging managed object state (can slow engine down!) - kDbgGroup_ManObj +enum CommonDebugGroup { + kDbgGroup_None = -1, + // Main debug group is for reporting general engine status and issues + kDbgGroup_Main = 0, + // Game group is for logging game logic state and issues + kDbgGroup_Game, + // Log from the game script + kDbgGroup_Script, + // Sprite cache logging + kDbgGroup_SprCache, + // Group for debugging managed object state (can slow engine down!) + kDbgGroup_ManObj }; // Debug group identifier defining either numeric or string id, or both -struct DebugGroupID -{ - uint32_t ID; - String SID; +struct DebugGroupID { + uint32_t ID; + String SID; - DebugGroupID() : ID(kDbgGroup_None) {} - DebugGroupID(uint32_t id, const String &sid = "") : ID(id), SID(sid) {} - DebugGroupID(const String &sid) : ID(kDbgGroup_None), SID(sid) {} - // Tells if any of the id components is valid - bool IsValid() const { return ID != kDbgGroup_None || !SID.IsEmpty(); } - // Tells if both id components are properly set - bool IsComplete() const { return ID != kDbgGroup_None && !SID.IsEmpty(); } + DebugGroupID() : ID(kDbgGroup_None) {} + DebugGroupID(uint32_t id, const String &sid = "") : ID(id), SID(sid) {} + DebugGroupID(const String &sid) : ID(kDbgGroup_None), SID(sid) {} + // Tells if any of the id components is valid + bool IsValid() const { + return ID != kDbgGroup_None || !SID.IsEmpty(); + } + // Tells if both id components are properly set + bool IsComplete() const { + return ID != kDbgGroup_None && !SID.IsEmpty(); + } }; -namespace Debug -{ - // - // Debug output - // - // Output formatted message of default group and default type - void Printf(const char *fmt, ...); - // Output formatted message of default group and given type - void Printf(MessageType mt, const char *fmt, ...); - // Output formatted message of given group and type - void Printf(DebugGroupID group_id, MessageType mt, const char *fmt, ...); +namespace Debug { +// +// Debug output +// +// Output formatted message of default group and default type +void Printf(const char *fmt, ...); +// Output formatted message of default group and given type +void Printf(MessageType mt, const char *fmt, ...); +// Output formatted message of given group and type +void Printf(DebugGroupID group_id, MessageType mt, const char *fmt, ...); } // namespace Debug diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h index 397e4cbfd787..8fc4a1717177 100644 --- a/engines/ags/shared/debugging/outputhandler.h +++ b/engines/ags/shared/debugging/outputhandler.h @@ -33,35 +33,31 @@ #include "debug/out.h" #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -struct DebugMessage -{ - String Text; - uint32_t GroupID; - String GroupName; - MessageType MT; +struct DebugMessage { + String Text; + uint32_t GroupID; + String GroupName; + MessageType MT; - DebugMessage() : GroupID(kDbgGroup_None), MT(kDbgMsg_None) {} - DebugMessage(const String &text, uint32_t group_id, const String &group_name, MessageType mt) - : Text(text) - , GroupID(group_id) - , GroupName(group_name) - , MT(mt) - {} + DebugMessage() : GroupID(kDbgGroup_None), MT(kDbgMsg_None) {} + DebugMessage(const String &text, uint32_t group_id, const String &group_name, MessageType mt) + : Text(text) + , GroupID(group_id) + , GroupName(group_name) + , MT(mt) { + } }; -class IOutputHandler -{ +class IOutputHandler { public: - virtual ~IOutputHandler() = default; - - // Print the given text sent from the debug group. - // Implementations are free to decide which message components are to be printed, and how. - virtual void PrintMessage(const DebugMessage &msg) = 0; + virtual ~IOutputHandler() = default; + + // Print the given text sent from the debug group. + // Implementations are free to decide which message components are to be printed, and how. + virtual void PrintMessage(const DebugMessage &msg) = 0; }; } // namespace Common diff --git a/engines/ags/shared/font/agsfontrenderer.h b/engines/ags/shared/font/agsfontrenderer.h index 4d25170eec76..dad4a7a529a3 100644 --- a/engines/ags/shared/font/agsfontrenderer.h +++ b/engines/ags/shared/font/agsfontrenderer.h @@ -26,42 +26,39 @@ struct BITMAP; // WARNING: this interface is exposed for plugins and declared for the second time in agsplugin.h -class IAGSFontRenderer -{ +class IAGSFontRenderer { public: - virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; - virtual void FreeMemory(int fontNumber) = 0; - virtual bool SupportsExtendedCharacters(int fontNumber) = 0; - virtual int GetTextWidth(const char *text, int fontNumber) = 0; - // Get actual height of the given line of text - virtual int GetTextHeight(const char *text, int fontNumber) = 0; - virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; - virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; - virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; + virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; + virtual void FreeMemory(int fontNumber) = 0; + virtual bool SupportsExtendedCharacters(int fontNumber) = 0; + virtual int GetTextWidth(const char *text, int fontNumber) = 0; + // Get actual height of the given line of text + virtual int GetTextHeight(const char *text, int fontNumber) = 0; + virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; + virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; + virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; protected: - IAGSFontRenderer() = default; - ~IAGSFontRenderer() = default; + IAGSFontRenderer() = default; + ~IAGSFontRenderer() = default; }; // Font render params, mainly for dealing with various compatibility issues and // broken fonts. NOTE: currently left empty as a result of rewrite, but may be // used again in the future. -struct FontRenderParams -{ - // Font's render multiplier - int SizeMultiplier = 1; +struct FontRenderParams { + // Font's render multiplier + int SizeMultiplier = 1; }; // NOTE: this extending interface is not yet exposed to plugins -class IAGSFontRenderer2 -{ +class IAGSFontRenderer2 { public: - virtual bool IsBitmapFont() = 0; - // Load font, applying extended font rendering parameters - virtual bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) = 0; + virtual bool IsBitmapFont() = 0; + // Load font, applying extended font rendering parameters + virtual bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) = 0; protected: - IAGSFontRenderer2() = default; - ~IAGSFontRenderer2() = default; + IAGSFontRenderer2() = default; + ~IAGSFontRenderer2() = default; }; #endif diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 9a9648fdaa88..0763bad8c651 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -36,24 +36,21 @@ using namespace AGS::Common; -namespace AGS -{ -namespace Common -{ - -struct Font -{ - IAGSFontRenderer *Renderer; - IAGSFontRenderer2 *Renderer2; - FontInfo Info; - - Font(); +namespace AGS { +namespace Common { + +struct Font { + IAGSFontRenderer *Renderer; + IAGSFontRenderer2 *Renderer2; + FontInfo Info; + + Font(); }; Font::Font() - : Renderer(nullptr) - , Renderer2(nullptr) -{} + : Renderer(nullptr) + , Renderer2(nullptr) { +} } // Common } // AGS @@ -64,345 +61,313 @@ static WFNFontRenderer wfnRenderer; FontInfo::FontInfo() - : Flags(0) - , SizePt(0) - , SizeMultiplier(1) - , Outline(FONT_OUTLINE_NONE) - , YOffset(0) - , LineSpacing(0) - , AutoOutlineStyle(kRounded) - , AutoOutlineThickness(1) -{} - - -void init_font_renderer() -{ - alfont_init(); - alfont_text_mode(-1); + : Flags(0) + , SizePt(0) + , SizeMultiplier(1) + , Outline(FONT_OUTLINE_NONE) + , YOffset(0) + , LineSpacing(0) + , AutoOutlineStyle(kRounded) + , AutoOutlineThickness(1) { } -void shutdown_font_renderer() -{ - set_our_eip(9919); - alfont_exit(); + +void init_font_renderer() { + alfont_init(); + alfont_text_mode(-1); } -void adjust_y_coordinate_for_text(int* ypos, size_t fontnum) -{ - if (fontnum >= fonts.size() || !fonts[fontnum].Renderer) - return; - fonts[fontnum].Renderer->AdjustYCoordinateForFont(ypos, fontnum); +void shutdown_font_renderer() { + set_our_eip(9919); + alfont_exit(); } -bool font_first_renderer_loaded() -{ - return fonts.size() > 0 && fonts[0].Renderer != nullptr; +void adjust_y_coordinate_for_text(int *ypos, size_t fontnum) { + if (fontnum >= fonts.size() || !fonts[fontnum].Renderer) + return; + fonts[fontnum].Renderer->AdjustYCoordinateForFont(ypos, fontnum); } -bool is_font_loaded(size_t fontNumber) -{ - return fontNumber < fonts.size() && fonts[fontNumber].Renderer != nullptr;; +bool font_first_renderer_loaded() { + return fonts.size() > 0 && fonts[0].Renderer != nullptr; } -IAGSFontRenderer* font_replace_renderer(size_t fontNumber, IAGSFontRenderer* renderer) -{ - if (fontNumber >= fonts.size()) - return nullptr; - IAGSFontRenderer* oldRender = fonts[fontNumber].Renderer; - fonts[fontNumber].Renderer = renderer; - fonts[fontNumber].Renderer2 = nullptr; - return oldRender; +bool is_font_loaded(size_t fontNumber) { + return fontNumber < fonts.size() && fonts[fontNumber].Renderer != nullptr;; } -bool is_bitmap_font(size_t fontNumber) -{ - if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer2) - return false; - return fonts[fontNumber].Renderer2->IsBitmapFont(); +IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer) { + if (fontNumber >= fonts.size()) + return nullptr; + IAGSFontRenderer *oldRender = fonts[fontNumber].Renderer; + fonts[fontNumber].Renderer = renderer; + fonts[fontNumber].Renderer2 = nullptr; + return oldRender; } -bool font_supports_extended_characters(size_t fontNumber) -{ - if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) - return false; - return fonts[fontNumber].Renderer->SupportsExtendedCharacters(fontNumber); +bool is_bitmap_font(size_t fontNumber) { + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer2) + return false; + return fonts[fontNumber].Renderer2->IsBitmapFont(); } -void ensure_text_valid_for_font(char *text, size_t fontnum) -{ - if (fontnum >= fonts.size() || !fonts[fontnum].Renderer) - return; - fonts[fontnum].Renderer->EnsureTextValidForFont(text, fontnum); +bool font_supports_extended_characters(size_t fontNumber) { + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return false; + return fonts[fontNumber].Renderer->SupportsExtendedCharacters(fontNumber); } -int get_font_scaling_mul(size_t fontNumber) -{ - if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) - return 0; - return fonts[fontNumber].Info.SizeMultiplier; +void ensure_text_valid_for_font(char *text, size_t fontnum) { + if (fontnum >= fonts.size() || !fonts[fontnum].Renderer) + return; + fonts[fontnum].Renderer->EnsureTextValidForFont(text, fontnum); } -int wgettextwidth(const char *texx, size_t fontNumber) -{ - if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) - return 0; - return fonts[fontNumber].Renderer->GetTextWidth(texx, fontNumber); +int get_font_scaling_mul(size_t fontNumber) { + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + return fonts[fontNumber].Info.SizeMultiplier; } -int wgettextheight(const char *text, size_t fontNumber) -{ - if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) - return 0; - return fonts[fontNumber].Renderer->GetTextHeight(text, fontNumber); +int wgettextwidth(const char *texx, size_t fontNumber) { + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + return fonts[fontNumber].Renderer->GetTextWidth(texx, fontNumber); } -int get_font_outline(size_t font_number) -{ - if (font_number >= fonts.size()) - return FONT_OUTLINE_NONE; - return fonts[font_number].Info.Outline; +int wgettextheight(const char *text, size_t fontNumber) { + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + return fonts[fontNumber].Renderer->GetTextHeight(text, fontNumber); } -int get_font_outline_thickness(size_t font_number) -{ - if (font_number >= fonts.size()) - return 0; - return fonts[font_number].Info.AutoOutlineThickness; +int get_font_outline(size_t font_number) { + if (font_number >= fonts.size()) + return FONT_OUTLINE_NONE; + return fonts[font_number].Info.Outline; } -void set_font_outline(size_t font_number, int outline_type) -{ - if (font_number >= fonts.size()) - return; - fonts[font_number].Info.Outline = FONT_OUTLINE_AUTO; +int get_font_outline_thickness(size_t font_number) { + if (font_number >= fonts.size()) + return 0; + return fonts[font_number].Info.AutoOutlineThickness; } -int getfontheight(size_t fontNumber) -{ - if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) - return 0; - // There is no explicit method for getting maximal possible height of any - // random font renderer at the moment; the implementations of GetTextHeight - // are allowed to return varied results depending on the text parameter. - // We use special line of text to get more or less reliable font height. - const char *height_test_string = "ZHwypgfjqhkilIK"; - return fonts[fontNumber].Renderer->GetTextHeight(height_test_string, fontNumber); +void set_font_outline(size_t font_number, int outline_type) { + if (font_number >= fonts.size()) + return; + fonts[font_number].Info.Outline = FONT_OUTLINE_AUTO; } -int getfontlinespacing(size_t fontNumber) -{ - if (fontNumber >= fonts.size()) - return 0; - int spacing = fonts[fontNumber].Info.LineSpacing; - // If the spacing parameter is not provided, then return default - // spacing, that is font's height. - return spacing > 0 ? spacing : getfontheight(fontNumber); +int getfontheight(size_t fontNumber) { + if (fontNumber >= fonts.size() || !fonts[fontNumber].Renderer) + return 0; + // There is no explicit method for getting maximal possible height of any + // random font renderer at the moment; the implementations of GetTextHeight + // are allowed to return varied results depending on the text parameter. + // We use special line of text to get more or less reliable font height. + const char *height_test_string = "ZHwypgfjqhkilIK"; + return fonts[fontNumber].Renderer->GetTextHeight(height_test_string, fontNumber); } -bool use_default_linespacing(size_t fontNumber) -{ - if (fontNumber >= fonts.size()) - return false; - return fonts[fontNumber].Info.LineSpacing == 0; +int getfontlinespacing(size_t fontNumber) { + if (fontNumber >= fonts.size()) + return 0; + int spacing = fonts[fontNumber].Info.LineSpacing; + // If the spacing parameter is not provided, then return default + // spacing, that is font's height. + return spacing > 0 ? spacing : getfontheight(fontNumber); +} + +bool use_default_linespacing(size_t fontNumber) { + if (fontNumber >= fonts.size()) + return false; + return fonts[fontNumber].Info.LineSpacing == 0; } // Project-dependent implementation extern int wgettextwidth_compensate(const char *tex, int font); -namespace AGS { namespace Common { SplitLines Lines; } } +namespace AGS { +namespace Common { +SplitLines Lines; +} +} // Replaces AGS-specific linebreak tags with common '\n' -void unescape_script_string(const char *cstr, std::vector &out) -{ - out.clear(); - // Handle the special case of the first char - if (cstr[0] == '[') - { - out.push_back('\n'); - cstr++; - } - // Replace all other occurrences as they're found - const char *off; - for (off = cstr; *off; ++off) - { - if (*off != '[') continue; - if (*(off - 1) == '\\') - { - // convert \[ into [ - out.insert(out.end(), cstr, off - 1); - out.push_back('['); - } - else - { - // convert [ into \n - out.insert(out.end(), cstr, off); - out.push_back('\n'); - } - cstr = off + 1; - } - out.insert(out.end(), cstr, off + 1); +void unescape_script_string(const char *cstr, std::vector &out) { + out.clear(); + // Handle the special case of the first char + if (cstr[0] == '[') { + out.push_back('\n'); + cstr++; + } + // Replace all other occurrences as they're found + const char *off; + for (off = cstr; *off; ++off) { + if (*off != '[') continue; + if (*(off - 1) == '\\') { + // convert \[ into [ + out.insert(out.end(), cstr, off - 1); + out.push_back('['); + } else { + // convert [ into \n + out.insert(out.end(), cstr, off); + out.push_back('\n'); + } + cstr = off + 1; + } + out.insert(out.end(), cstr, off + 1); } // Break up the text into lines size_t split_lines(const char *todis, SplitLines &lines, int wii, int fonnt, size_t max_lines) { - // NOTE: following hack accomodates for the legacy math mistake in split_lines. - // It's hard to tell how cruicial it is for the game looks, so research may be needed. - // TODO: IMHO this should rely not on game format, but script API level, because it - // defines necessary adjustments to game scripts. If you want to fix this, find a way to - // pass this flag here all the way from game.options[OPT_BASESCRIPTAPI] (or game format). - // - // if (game.options[OPT_BASESCRIPTAPI] < $Your current version$) - wii -= 1; - - lines.Reset(); - unescape_script_string(todis, lines.LineBuf); - char *theline = &lines.LineBuf.front(); - - size_t i = 0; - size_t splitAt; - char nextCharWas; - while (1) { - splitAt = -1; - - if (theline[i] == 0) { - // end of the text, add the last line if necessary - if (i > 0) { - lines.Add(theline); - } - break; - } - - // temporarily terminate the line here and test its width - nextCharWas = theline[i + 1]; - theline[i + 1] = 0; - - // force end of line with the \n character - if (theline[i] == '\n') - splitAt = i; - // otherwise, see if we are too wide - else if (wgettextwidth_compensate(theline, fonnt) > wii) { - int endline = i; - while ((theline[endline] != ' ') && (endline > 0)) - endline--; - - // single very wide word, display as much as possible - if (endline == 0) - endline = i - 1; - - splitAt = endline; - } - - // restore the character that was there before - theline[i + 1] = nextCharWas; - - if (splitAt != -1) { - if (splitAt == 0 && !((theline[0] == ' ') || (theline[0] == '\n'))) { - // cannot split with current width restriction - lines.Reset(); - break; - } - // add this line - nextCharWas = theline[splitAt]; - theline[splitAt] = 0; - lines.Add(theline); - theline[splitAt] = nextCharWas; - if (lines.Count() >= max_lines) { - lines[lines.Count() - 1].Append("..."); - break; - } - // the next line starts from here - theline += splitAt; - // skip the space or new line that caused the line break - if ((theline[0] == ' ') || (theline[0] == '\n')) - theline++; - i = -1; - } - - i++; - } - return lines.Count(); + // NOTE: following hack accomodates for the legacy math mistake in split_lines. + // It's hard to tell how cruicial it is for the game looks, so research may be needed. + // TODO: IMHO this should rely not on game format, but script API level, because it + // defines necessary adjustments to game scripts. If you want to fix this, find a way to + // pass this flag here all the way from game.options[OPT_BASESCRIPTAPI] (or game format). + // + // if (game.options[OPT_BASESCRIPTAPI] < $Your current version$) + wii -= 1; + + lines.Reset(); + unescape_script_string(todis, lines.LineBuf); + char *theline = &lines.LineBuf.front(); + + size_t i = 0; + size_t splitAt; + char nextCharWas; + while (1) { + splitAt = -1; + + if (theline[i] == 0) { + // end of the text, add the last line if necessary + if (i > 0) { + lines.Add(theline); + } + break; + } + + // temporarily terminate the line here and test its width + nextCharWas = theline[i + 1]; + theline[i + 1] = 0; + + // force end of line with the \n character + if (theline[i] == '\n') + splitAt = i; + // otherwise, see if we are too wide + else if (wgettextwidth_compensate(theline, fonnt) > wii) { + int endline = i; + while ((theline[endline] != ' ') && (endline > 0)) + endline--; + + // single very wide word, display as much as possible + if (endline == 0) + endline = i - 1; + + splitAt = endline; + } + + // restore the character that was there before + theline[i + 1] = nextCharWas; + + if (splitAt != -1) { + if (splitAt == 0 && !((theline[0] == ' ') || (theline[0] == '\n'))) { + // cannot split with current width restriction + lines.Reset(); + break; + } + // add this line + nextCharWas = theline[splitAt]; + theline[splitAt] = 0; + lines.Add(theline); + theline[splitAt] = nextCharWas; + if (lines.Count() >= max_lines) { + lines[lines.Count() - 1].Append("..."); + break; + } + // the next line starts from here + theline += splitAt; + // skip the space or new line that caused the line break + if ((theline[0] == ' ') || (theline[0] == '\n')) + theline++; + i = -1; + } + + i++; + } + return lines.Count(); } -void wouttextxy(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx) -{ - if (fontNumber >= fonts.size()) - return; - yyy += fonts[fontNumber].Info.YOffset; - if (yyy > ds->GetClip().Bottom) - return; // each char is clipped but this speeds it up - - if (fonts[fontNumber].Renderer != nullptr) - { - fonts[fontNumber].Renderer->RenderText(texx, fontNumber, (BITMAP*)ds->GetAllegroBitmap(), xxx, yyy, text_color); - } +void wouttextxy(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx) { + if (fontNumber >= fonts.size()) + return; + yyy += fonts[fontNumber].Info.YOffset; + if (yyy > ds->GetClip().Bottom) + return; // each char is clipped but this speeds it up + + if (fonts[fontNumber].Renderer != nullptr) { + fonts[fontNumber].Renderer->RenderText(texx, fontNumber, (BITMAP *)ds->GetAllegroBitmap(), xxx, yyy, text_color); + } } -void set_fontinfo(size_t fontNumber, const FontInfo &finfo) -{ - if (fontNumber < fonts.size() && fonts[fontNumber].Renderer) - fonts[fontNumber].Info = finfo; +void set_fontinfo(size_t fontNumber, const FontInfo &finfo) { + if (fontNumber < fonts.size() && fonts[fontNumber].Renderer) + fonts[fontNumber].Info = finfo; } // Loads a font from disk -bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) -{ - if (fonts.size() <= fontNumber) - fonts.resize(fontNumber + 1); - else - wfreefont(fontNumber); - FontRenderParams params; - params.SizeMultiplier = font_info.SizeMultiplier; - - if (ttfRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) - { - fonts[fontNumber].Renderer = &ttfRenderer; - fonts[fontNumber].Renderer2 = &ttfRenderer; - } - else if (wfnRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) - { - fonts[fontNumber].Renderer = &wfnRenderer; - fonts[fontNumber].Renderer2 = &wfnRenderer; - } - - if (fonts[fontNumber].Renderer) - { - fonts[fontNumber].Info = font_info; - return true; - } - return false; +bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) { + if (fonts.size() <= fontNumber) + fonts.resize(fontNumber + 1); + else + wfreefont(fontNumber); + FontRenderParams params; + params.SizeMultiplier = font_info.SizeMultiplier; + + if (ttfRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) { + fonts[fontNumber].Renderer = &ttfRenderer; + fonts[fontNumber].Renderer2 = &ttfRenderer; + } else if (wfnRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) { + fonts[fontNumber].Renderer = &wfnRenderer; + fonts[fontNumber].Renderer2 = &wfnRenderer; + } + + if (fonts[fontNumber].Renderer) { + fonts[fontNumber].Info = font_info; + return true; + } + return false; } -void wgtprintf(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...) -{ - if (fontNumber >= fonts.size()) - return; +void wgtprintf(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...) { + if (fontNumber >= fonts.size()) + return; - char tbuffer[2000]; - va_list ap; + char tbuffer[2000]; + va_list ap; - va_start(ap, fmt); - vsprintf(tbuffer, fmt, ap); - va_end(ap); - wouttextxy(ds, xxx, yyy, fontNumber, text_color, tbuffer); + va_start(ap, fmt); + vsprintf(tbuffer, fmt, ap); + va_end(ap); + wouttextxy(ds, xxx, yyy, fontNumber, text_color, tbuffer); } -void wfreefont(size_t fontNumber) -{ - if (fontNumber >= fonts.size()) - return; +void wfreefont(size_t fontNumber) { + if (fontNumber >= fonts.size()) + return; - if (fonts[fontNumber].Renderer != nullptr) - fonts[fontNumber].Renderer->FreeMemory(fontNumber); + if (fonts[fontNumber].Renderer != nullptr) + fonts[fontNumber].Renderer->FreeMemory(fontNumber); - fonts[fontNumber].Renderer = nullptr; + fonts[fontNumber].Renderer = nullptr; } -void free_all_fonts() -{ - for (size_t i = 0; i < fonts.size(); ++i) - { - if (fonts[i].Renderer != nullptr) - fonts[i].Renderer->FreeMemory(i); - } - fonts.clear(); +void free_all_fonts() { + for (size_t i = 0; i < fonts.size(); ++i) { + if (fonts[i].Renderer != nullptr) + fonts[i].Renderer->FreeMemory(i); + } + fonts.clear(); } diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index 7c71b232f83b..81bdc67ef920 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -29,7 +29,11 @@ // TODO: we need to make some kind of TextManager class of this module -namespace AGS { namespace Common { class Bitmap; } } +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; class IAGSFontRenderer; @@ -39,8 +43,8 @@ struct FontRenderParams; void init_font_renderer(); void shutdown_font_renderer(); -void adjust_y_coordinate_for_text(int* ypos, size_t fontnum); -IAGSFontRenderer* font_replace_renderer(size_t fontNumber, IAGSFontRenderer* renderer); +void adjust_y_coordinate_for_text(int *ypos, size_t fontnum); +IAGSFontRenderer *font_replace_renderer(size_t fontNumber, IAGSFontRenderer *renderer); bool font_first_renderer_loaded(); bool is_font_loaded(size_t fontNumber); bool is_bitmap_font(size_t fontNumber); @@ -89,32 +93,45 @@ void free_all_fonts(); // and drawing. For that reason it is not equivalent to std::vector, // but keeps constructed String buffers intact for most time. // TODO: implement proper strings pool. -class SplitLines -{ +class SplitLines { public: - inline size_t Count() const { return _count; } - inline const Common::String &operator[](size_t i) const { return _pool[i]; } - inline Common::String &operator[](size_t i) { return _pool[i]; } - inline void Clear() { _pool.clear(); _count = 0; } - inline void Reset() { _count = 0; } - inline void Add(const char *cstr) - { - if (_pool.size() == _count) _pool.resize(_count + 1); - _pool[_count++].SetString(cstr); - } + inline size_t Count() const { + return _count; + } + inline const Common::String &operator[](size_t i) const { + return _pool[i]; + } + inline Common::String &operator[](size_t i) { + return _pool[i]; + } + inline void Clear() { + _pool.clear(); + _count = 0; + } + inline void Reset() { + _count = 0; + } + inline void Add(const char *cstr) { + if (_pool.size() == _count) _pool.resize(_count + 1); + _pool[_count++].SetString(cstr); + } - // An auxiliary line processing buffer - std::vector LineBuf; + // An auxiliary line processing buffer + std::vector LineBuf; private: - std::vector _pool; - size_t _count; // actual number of lines in use + std::vector _pool; + size_t _count; // actual number of lines in use }; // Break up the text into lines restricted by the given width; // returns number of lines, or 0 if text cannot be split well to fit in this width size_t split_lines(const char *texx, SplitLines &lines, int width, int fontNumber, size_t max_lines = -1); -namespace AGS { namespace Common { extern SplitLines Lines; } } +namespace AGS { +namespace Common { +extern SplitLines Lines; +} +} #endif diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp index 668b3ea57993..54d32ffb09c9 100644 --- a/engines/ags/shared/font/ttffontrenderer.cpp +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -40,111 +40,101 @@ using namespace AGS::Common; extern bool ShouldAntiAliasText(); ALFONT_FONT *tempttffnt; -ALFONT_FONT *get_ttf_block(unsigned char* fontptr) -{ - memcpy(&tempttffnt, &fontptr[4], sizeof(tempttffnt)); - return tempttffnt; +ALFONT_FONT *get_ttf_block(unsigned char *fontptr) { + memcpy(&tempttffnt, &fontptr[4], sizeof(tempttffnt)); + return tempttffnt; } // ***** TTF RENDERER ***** -void TTFFontRenderer::AdjustYCoordinateForFont(int *ycoord, int fontNumber) -{ - // TTF fonts already have space at the top, so try to remove the gap - // TODO: adding -1 was here before (check the comment above), - // but how universal is this "space at the top"? - // Also, why is this function used only in one case of text rendering? - // Review this after we upgrade the font library. - ycoord[0]--; +void TTFFontRenderer::AdjustYCoordinateForFont(int *ycoord, int fontNumber) { + // TTF fonts already have space at the top, so try to remove the gap + // TODO: adding -1 was here before (check the comment above), + // but how universal is this "space at the top"? + // Also, why is this function used only in one case of text rendering? + // Review this after we upgrade the font library. + ycoord[0]--; } -void TTFFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) -{ - // do nothing, TTF can handle all characters +void TTFFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) { + // do nothing, TTF can handle all characters } -int TTFFontRenderer::GetTextWidth(const char *text, int fontNumber) -{ - return alfont_text_length(_fontData[fontNumber].AlFont, text); +int TTFFontRenderer::GetTextWidth(const char *text, int fontNumber) { + return alfont_text_length(_fontData[fontNumber].AlFont, text); } -int TTFFontRenderer::GetTextHeight(const char *text, int fontNumber) -{ - return alfont_text_height(_fontData[fontNumber].AlFont); +int TTFFontRenderer::GetTextHeight(const char *text, int fontNumber) { + return alfont_text_height(_fontData[fontNumber].AlFont); } -void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) -{ - if (y > destination->cb) // optimisation - return; +void TTFFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) { + if (y > destination->cb) // optimisation + return; - // Y - 1 because it seems to get drawn down a bit - if ((ShouldAntiAliasText()) && (bitmap_color_depth(destination) > 8)) - alfont_textout_aa(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour); - else - alfont_textout(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour); + // Y - 1 because it seems to get drawn down a bit + if ((ShouldAntiAliasText()) && (bitmap_color_depth(destination) > 8)) + alfont_textout_aa(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour); + else + alfont_textout(destination, _fontData[fontNumber].AlFont, text, x, y - 1, colour); } -bool TTFFontRenderer::LoadFromDisk(int fontNumber, int fontSize) -{ - return LoadFromDiskEx(fontNumber, fontSize, nullptr); +bool TTFFontRenderer::LoadFromDisk(int fontNumber, int fontSize) { + return LoadFromDiskEx(fontNumber, fontSize, nullptr); } -bool TTFFontRenderer::IsBitmapFont() -{ - return false; +bool TTFFontRenderer::IsBitmapFont() { + return false; } -bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) -{ - String file_name = String::FromFormat("agsfnt%d.ttf", fontNumber); - Stream *reader = AssetManager::OpenAsset(file_name); - char *membuffer; +bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) { + String file_name = String::FromFormat("agsfnt%d.ttf", fontNumber); + Stream *reader = AssetManager::OpenAsset(file_name); + char *membuffer; - if (reader == nullptr) - return false; + if (reader == nullptr) + return false; - long lenof = AssetManager::GetLastAssetSize(); + long lenof = AssetManager::GetLastAssetSize(); - membuffer = (char *)malloc(lenof); - reader->ReadArray(membuffer, lenof, 1); - delete reader; + membuffer = (char *)malloc(lenof); + reader->ReadArray(membuffer, lenof, 1); + delete reader; - ALFONT_FONT *alfptr = alfont_load_font_from_mem(membuffer, lenof); - free(membuffer); + ALFONT_FONT *alfptr = alfont_load_font_from_mem(membuffer, lenof); + free(membuffer); - if (alfptr == nullptr) - return false; + if (alfptr == nullptr) + return false; - // TODO: move this somewhere, should not be right here + // TODO: move this somewhere, should not be right here #if AGS_OUTLINE_FONT_FIX - // FIXME: (!!!) this fix should be done differently: - // 1. Find out which OUTLINE font was causing troubles; - // 2. Replace outline method ONLY if that troublesome font is used as outline. - // 3. Move this fix somewhere else!! (right after game load routine?) - // - // Check for the LucasFan font since it comes with an outline font that - // is drawn incorrectly with Freetype versions > 2.1.3. - // A simple workaround is to disable outline fonts for it and use - // automatic outline drawing. - if (get_font_outline(fontNumber) >=0 && - strcmp(alfont_get_name(alfptr), "LucasFan-Font") == 0) - set_font_outline(fontNumber, FONT_OUTLINE_AUTO); + // FIXME: (!!!) this fix should be done differently: + // 1. Find out which OUTLINE font was causing troubles; + // 2. Replace outline method ONLY if that troublesome font is used as outline. + // 3. Move this fix somewhere else!! (right after game load routine?) + // + // Check for the LucasFan font since it comes with an outline font that + // is drawn incorrectly with Freetype versions > 2.1.3. + // A simple workaround is to disable outline fonts for it and use + // automatic outline drawing. + if (get_font_outline(fontNumber) >= 0 && + strcmp(alfont_get_name(alfptr), "LucasFan-Font") == 0) + set_font_outline(fontNumber, FONT_OUTLINE_AUTO); #endif - if (fontSize == 0) - fontSize = 8; // compatibility fix - if (params && params->SizeMultiplier > 1) - fontSize *= params->SizeMultiplier; - if (fontSize > 0) - alfont_set_font_size(alfptr, fontSize); - - _fontData[fontNumber].AlFont = alfptr; - _fontData[fontNumber].Params = params ? *params : FontRenderParams(); - return true; + if (fontSize == 0) + fontSize = 8; // compatibility fix + if (params && params->SizeMultiplier > 1) + fontSize *= params->SizeMultiplier; + if (fontSize > 0) + alfont_set_font_size(alfptr, fontSize); + + _fontData[fontNumber].AlFont = alfptr; + _fontData[fontNumber].Params = params ? *params : FontRenderParams(); + return true; } -void TTFFontRenderer::FreeMemory(int fontNumber) -{ - alfont_destroy_font(_fontData[fontNumber].AlFont); - _fontData.erase(fontNumber); +void TTFFontRenderer::FreeMemory(int fontNumber) { + alfont_destroy_font(_fontData[fontNumber].AlFont); + _fontData.erase(fontNumber); } diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 1fbb0883458b..6f29bd2490b6 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -30,27 +30,28 @@ struct ALFONT_FONT; class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { public: - // IAGSFontRenderer implementation - bool LoadFromDisk(int fontNumber, int fontSize) override; - void FreeMemory(int fontNumber) override; - bool SupportsExtendedCharacters(int fontNumber) override { return true; } - int GetTextWidth(const char *text, int fontNumber) override; - int GetTextHeight(const char *text, int fontNumber) override; - void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override ; - void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override; - void EnsureTextValidForFont(char *text, int fontNumber) override; + // IAGSFontRenderer implementation + bool LoadFromDisk(int fontNumber, int fontSize) override; + void FreeMemory(int fontNumber) override; + bool SupportsExtendedCharacters(int fontNumber) override { + return true; + } + int GetTextWidth(const char *text, int fontNumber) override; + int GetTextHeight(const char *text, int fontNumber) override; + void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override ; + void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override; + void EnsureTextValidForFont(char *text, int fontNumber) override; - // IAGSFontRenderer2 implementation - bool IsBitmapFont() override; - bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override; + // IAGSFontRenderer2 implementation + bool IsBitmapFont() override; + bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override; private: - struct FontData - { - ALFONT_FONT *AlFont; - FontRenderParams Params; - }; - std::map _fontData; + struct FontData { + ALFONT_FONT *AlFont; + FontRenderParams Params; + }; + std::map _fontData; }; #endif diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index 341fe3a06d3e..6825805b4e11 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -33,169 +33,153 @@ static const size_t WFN_FILE_SIG_LENGTH = 15; static const size_t MinCharDataSize = sizeof(uint16_t) * 2; WFNChar::WFNChar() - : Width(0) - , Height(0) - , Data(nullptr) -{ + : Width(0) + , Height(0) + , Data(nullptr) { } -void WFNChar::RestrictToBytes(size_t bytes) -{ - if (bytes < GetRequiredPixelSize()) - Height = static_cast(bytes / GetRowByteCount()); +void WFNChar::RestrictToBytes(size_t bytes) { + if (bytes < GetRequiredPixelSize()) + Height = static_cast(bytes / GetRowByteCount()); } const WFNChar WFNFont::_emptyChar; -void WFNFont::Clear() -{ - _refs.clear(); - _items.clear(); - _pixelData.clear(); +void WFNFont::Clear() { + _refs.clear(); + _items.clear(); + _pixelData.clear(); } -WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) -{ - Clear(); - - const soff_t used_data_size = data_size > 0 ? data_size : in->GetLength(); - - // Read font header - char sig[WFN_FILE_SIG_LENGTH]; - in->Read(sig, WFN_FILE_SIG_LENGTH); - if (strncmp(sig, WFN_FILE_SIGNATURE, WFN_FILE_SIG_LENGTH) != 0) - { - Debug::Printf(kDbgMsg_Error, "\tWFN: bad format signature"); - return kWFNErr_BadSignature; // bad format - } - - const soff_t table_addr = static_cast(in->ReadInt16()); // offset table relative address - if (table_addr < WFN_FILE_SIG_LENGTH + sizeof(uint16_t) || table_addr >= used_data_size) - { - Debug::Printf(kDbgMsg_Error, "\tWFN: bad table address: %lld (%d - %d)", table_addr, WFN_FILE_SIG_LENGTH + sizeof(uint16_t), used_data_size); - return kWFNErr_BadTableAddress; // bad table address - } - - const soff_t offset_table_size = used_data_size - table_addr; - const soff_t raw_data_offset = WFN_FILE_SIG_LENGTH + sizeof(uint16_t); - const size_t total_char_data = static_cast(table_addr - raw_data_offset); - const size_t char_count = static_cast(offset_table_size / sizeof(uint16_t)); - - // We process character data in three steps: - // 1. For every character store offset of character item, excluding - // duplicates. - // 2. Allocate memory for character items and pixel array and copy - // appropriate data; test for possible format corruption. - // 3. Create array of references from characters to items; same item may be - // referenced by many characters. - WFNError err = kWFNErr_NoError; - - // Read character data array - uint8_t *raw_data = new uint8_t[total_char_data]; - in->Read(raw_data, total_char_data); - - // Read offset table - uint16_t *offset_table = new uint16_t[char_count]; - in->ReadArrayOfInt16((int16_t*)offset_table, char_count); - - // Read all referenced offsets in an unsorted vector - std::vector offs; - offs.reserve(char_count); // reserve max possible offsets - for (size_t i = 0; i < char_count; ++i) - { - const uint16_t off = offset_table[i]; - if (off < raw_data_offset || off + MinCharDataSize > table_addr) - { - Debug::Printf("\tWFN: character %d -- bad item offset: %d (%d - %d, +%d)", - i, off, raw_data_offset, table_addr, MinCharDataSize); - err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format - continue; // bad character offset - } - offs.push_back(off); - } - // sort offsets vector and remove any duplicates - std::sort(offs.begin(), offs.end()); - std::vector(offs.begin(), std::unique(offs.begin(), offs.end())).swap(offs); - - // Now that we know number of valid character items, parse and store character data - WFNChar init_ch; - _items.resize(offs.size()); - size_t total_pixel_size = 0; - for (size_t i = 0; i < _items.size(); ++i) - { - const uint8_t *p_data = raw_data + offs[i] - raw_data_offset; - init_ch.Width = Memory::ReadInt16LE(p_data); - init_ch.Height = Memory::ReadInt16LE(p_data + sizeof(uint16_t)); - total_pixel_size += init_ch.GetRequiredPixelSize(); - _items[i] = init_ch; - } - - // Now that we know actual size of pixels in use, create pixel data array; - // since the items are sorted, the pixel data will be stored sequentially as well. - // At this point offs and _items have related elements in the same order. - _pixelData.resize(total_pixel_size); - std::vector::iterator pixel_it = _pixelData.begin(); // write ptr - for (size_t i = 0; i < _items.size(); ++i) - { - const size_t pixel_data_size = _items[i].GetRequiredPixelSize(); - if (pixel_data_size == 0) - { - Debug::Printf("\tWFN: item at off %d -- null size", offs[i]); - err = kWFNErr_HasBadCharacters; - continue; // just an empty character - } - const uint16_t raw_off = offs[i] - raw_data_offset + MinCharDataSize; // offset in raw array - size_t src_size = pixel_data_size; - if (i + 1 != _items.size() && raw_off + src_size > offs[i + 1] - raw_data_offset) - { // character pixel data overlaps next character - Debug::Printf("\tWFN: item at off %d -- pixel data overlaps next known item (at %d, +%d)", - offs[i], offs[i + 1], MinCharDataSize + src_size); - err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format - src_size = offs[i + 1] - offs[i] - MinCharDataSize; - } - - if (raw_off + src_size > total_char_data) - { // character pixel data overflow buffer - Debug::Printf("\tWFN: item at off %d -- pixel data exceeds available data (at %d, +%d)", - offs[i], table_addr, MinCharDataSize + src_size); - err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format - src_size = total_char_data - raw_off; - } - _items[i].RestrictToBytes(src_size); - - assert(pixel_it + pixel_data_size <= _pixelData.end()); // should not normally fail - std::copy(raw_data + raw_off, raw_data + raw_off + src_size, pixel_it); - _items[i].Data = &(*pixel_it); - pixel_it += pixel_data_size; - } - - // Create final reference array - _refs.resize(char_count); - for (size_t i = 0; i < char_count; ++i) - { - const uint16_t off = offset_table[i]; - // if bad character offset - reference empty character - if (off < raw_data_offset || off + MinCharDataSize > table_addr) - { - _refs[i] = &_emptyChar; - } - else - { - // in usual case the offset table references items in strict order - if (i < _items.size() && offs[i] == off) - _refs[i] = &_items[i]; - else - { - // we know beforehand that such item must exist - std::vector::const_iterator at = std::lower_bound(offs.begin(), offs.end(), off); - assert(at != offs.end() && *at == off && // should not normally fail - at - offs.begin() >= 0 && static_cast(at - offs.begin()) < _items.size()); - _refs[i] = &_items[at - offs.begin()]; // set up reference to item - } - } - } - - delete [] raw_data; - delete [] offset_table; - return err; +WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { + Clear(); + + const soff_t used_data_size = data_size > 0 ? data_size : in->GetLength(); + + // Read font header + char sig[WFN_FILE_SIG_LENGTH]; + in->Read(sig, WFN_FILE_SIG_LENGTH); + if (strncmp(sig, WFN_FILE_SIGNATURE, WFN_FILE_SIG_LENGTH) != 0) { + Debug::Printf(kDbgMsg_Error, "\tWFN: bad format signature"); + return kWFNErr_BadSignature; // bad format + } + + const soff_t table_addr = static_cast(in->ReadInt16()); // offset table relative address + if (table_addr < WFN_FILE_SIG_LENGTH + sizeof(uint16_t) || table_addr >= used_data_size) { + Debug::Printf(kDbgMsg_Error, "\tWFN: bad table address: %lld (%d - %d)", table_addr, WFN_FILE_SIG_LENGTH + sizeof(uint16_t), used_data_size); + return kWFNErr_BadTableAddress; // bad table address + } + + const soff_t offset_table_size = used_data_size - table_addr; + const soff_t raw_data_offset = WFN_FILE_SIG_LENGTH + sizeof(uint16_t); + const size_t total_char_data = static_cast(table_addr - raw_data_offset); + const size_t char_count = static_cast(offset_table_size / sizeof(uint16_t)); + + // We process character data in three steps: + // 1. For every character store offset of character item, excluding + // duplicates. + // 2. Allocate memory for character items and pixel array and copy + // appropriate data; test for possible format corruption. + // 3. Create array of references from characters to items; same item may be + // referenced by many characters. + WFNError err = kWFNErr_NoError; + + // Read character data array + uint8_t *raw_data = new uint8_t[total_char_data]; + in->Read(raw_data, total_char_data); + + // Read offset table + uint16_t *offset_table = new uint16_t[char_count]; + in->ReadArrayOfInt16((int16_t *)offset_table, char_count); + + // Read all referenced offsets in an unsorted vector + std::vector offs; + offs.reserve(char_count); // reserve max possible offsets + for (size_t i = 0; i < char_count; ++i) { + const uint16_t off = offset_table[i]; + if (off < raw_data_offset || off + MinCharDataSize > table_addr) { + Debug::Printf("\tWFN: character %d -- bad item offset: %d (%d - %d, +%d)", + i, off, raw_data_offset, table_addr, MinCharDataSize); + err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format + continue; // bad character offset + } + offs.push_back(off); + } + // sort offsets vector and remove any duplicates + std::sort(offs.begin(), offs.end()); + std::vector(offs.begin(), std::unique(offs.begin(), offs.end())).swap(offs); + + // Now that we know number of valid character items, parse and store character data + WFNChar init_ch; + _items.resize(offs.size()); + size_t total_pixel_size = 0; + for (size_t i = 0; i < _items.size(); ++i) { + const uint8_t *p_data = raw_data + offs[i] - raw_data_offset; + init_ch.Width = Memory::ReadInt16LE(p_data); + init_ch.Height = Memory::ReadInt16LE(p_data + sizeof(uint16_t)); + total_pixel_size += init_ch.GetRequiredPixelSize(); + _items[i] = init_ch; + } + + // Now that we know actual size of pixels in use, create pixel data array; + // since the items are sorted, the pixel data will be stored sequentially as well. + // At this point offs and _items have related elements in the same order. + _pixelData.resize(total_pixel_size); + std::vector::iterator pixel_it = _pixelData.begin(); // write ptr + for (size_t i = 0; i < _items.size(); ++i) { + const size_t pixel_data_size = _items[i].GetRequiredPixelSize(); + if (pixel_data_size == 0) { + Debug::Printf("\tWFN: item at off %d -- null size", offs[i]); + err = kWFNErr_HasBadCharacters; + continue; // just an empty character + } + const uint16_t raw_off = offs[i] - raw_data_offset + MinCharDataSize; // offset in raw array + size_t src_size = pixel_data_size; + if (i + 1 != _items.size() && raw_off + src_size > offs[i + 1] - raw_data_offset) { + // character pixel data overlaps next character + Debug::Printf("\tWFN: item at off %d -- pixel data overlaps next known item (at %d, +%d)", + offs[i], offs[i + 1], MinCharDataSize + src_size); + err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format + src_size = offs[i + 1] - offs[i] - MinCharDataSize; + } + + if (raw_off + src_size > total_char_data) { + // character pixel data overflow buffer + Debug::Printf("\tWFN: item at off %d -- pixel data exceeds available data (at %d, +%d)", + offs[i], table_addr, MinCharDataSize + src_size); + err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format + src_size = total_char_data - raw_off; + } + _items[i].RestrictToBytes(src_size); + + assert(pixel_it + pixel_data_size <= _pixelData.end()); // should not normally fail + std::copy(raw_data + raw_off, raw_data + raw_off + src_size, pixel_it); + _items[i].Data = &(*pixel_it); + pixel_it += pixel_data_size; + } + + // Create final reference array + _refs.resize(char_count); + for (size_t i = 0; i < char_count; ++i) { + const uint16_t off = offset_table[i]; + // if bad character offset - reference empty character + if (off < raw_data_offset || off + MinCharDataSize > table_addr) { + _refs[i] = &_emptyChar; + } else { + // in usual case the offset table references items in strict order + if (i < _items.size() && offs[i] == off) + _refs[i] = &_items[i]; + else { + // we know beforehand that such item must exist + std::vector::const_iterator at = std::lower_bound(offs.begin(), offs.end(), off); + assert(at != offs.end() && *at == off && // should not normally fail + at - offs.begin() >= 0 && static_cast(at - offs.begin()) < _items.size()); + _refs[i] = &_items[at - offs.begin()]; // set up reference to item + } + } + } + + delete [] raw_data; + delete [] offset_table; + return err; } diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index 1f85d65d9f27..e5020fe76423 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -49,64 +49,61 @@ #include #include "core/types.h" -namespace AGS { namespace Common { class Stream; } } - -enum WFNError -{ - kWFNErr_NoError, - kWFNErr_BadSignature, - kWFNErr_BadTableAddress, - kWFNErr_HasBadCharacters +namespace AGS { +namespace Common { +class Stream; +} +} + +enum WFNError { + kWFNErr_NoError, + kWFNErr_BadSignature, + kWFNErr_BadTableAddress, + kWFNErr_HasBadCharacters }; -struct WFNChar -{ - uint16_t Width; - uint16_t Height; - const uint8_t *Data; +struct WFNChar { + uint16_t Width; + uint16_t Height; + const uint8_t *Data; - WFNChar(); + WFNChar(); - inline size_t GetRowByteCount() const - { - return (Width + 7) / 8; - } + inline size_t GetRowByteCount() const { + return (Width + 7) / 8; + } - inline size_t GetRequiredPixelSize() const - { - return GetRowByteCount() * Height; - } + inline size_t GetRequiredPixelSize() const { + return GetRowByteCount() * Height; + } - // Ensure character's width & height fit in given number of pixel bytes - void RestrictToBytes(size_t bytes); + // Ensure character's width & height fit in given number of pixel bytes + void RestrictToBytes(size_t bytes); }; -class WFNFont -{ +class WFNFont { public: - inline uint16_t GetCharCount() const - { - return static_cast(_refs.size()); - } - - // Get WFN character for the given code; if the character is missing, returns empty character - inline const WFNChar &GetChar(uint8_t code) const - { - return code < _refs.size() ? *_refs[code] : _emptyChar; - } - - void Clear(); - // Reads WFNFont object, using data_size bytes from stream; if data_size = 0, - // the available stream's length is used instead. Returns error code. - WFNError ReadFromFile(AGS::Common::Stream *in, const soff_t data_size = 0); + inline uint16_t GetCharCount() const { + return static_cast(_refs.size()); + } + + // Get WFN character for the given code; if the character is missing, returns empty character + inline const WFNChar &GetChar(uint8_t code) const { + return code < _refs.size() ? *_refs[code] : _emptyChar; + } + + void Clear(); + // Reads WFNFont object, using data_size bytes from stream; if data_size = 0, + // the available stream's length is used instead. Returns error code. + WFNError ReadFromFile(AGS::Common::Stream *in, const soff_t data_size = 0); protected: - std::vector _refs; // reference array, contains pointers to elements of _items - std::vector _items; // actual character items - std::vector _pixelData; // pixel data array + std::vector _refs; // reference array, contains pointers to elements of _items + std::vector _items; // actual character items + std::vector _pixelData; // pixel data array - static const WFNChar _emptyChar; // a dummy character to substitute bad symbols + static const WFNChar _emptyChar; // a dummy character to substitute bad symbols }; #endif diff --git a/engines/ags/shared/font/wfnfontrenderer.cpp b/engines/ags/shared/font/wfnfontrenderer.cpp index 828a4d9fad80..3db79fe0ee31 100644 --- a/engines/ags/shared/font/wfnfontrenderer.cpp +++ b/engines/ags/shared/font/wfnfontrenderer.cpp @@ -30,158 +30,135 @@ using namespace AGS::Common; -static unsigned char GetCharCode(unsigned char wanted_code, const WFNFont* font) -{ - return wanted_code < font->GetCharCount() ? wanted_code : '?'; +static unsigned char GetCharCode(unsigned char wanted_code, const WFNFont *font) { + return wanted_code < font->GetCharCount() ? wanted_code : '?'; } static int RenderChar(Bitmap *ds, const int at_x, const int at_y, const WFNChar &wfn_char, const int scale, const color_t text_color); -void WFNFontRenderer::AdjustYCoordinateForFont(int *ycoord, int fontNumber) -{ - // Do nothing +void WFNFontRenderer::AdjustYCoordinateForFont(int *ycoord, int fontNumber) { + // Do nothing } -void WFNFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) -{ - const WFNFont* font = _fontData[fontNumber].Font; - // replace any extended characters with question marks - for (; *text; ++text) - { - if ((unsigned char)*text >= font->GetCharCount()) - { - *text = '?'; - } - } +void WFNFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) { + const WFNFont *font = _fontData[fontNumber].Font; + // replace any extended characters with question marks + for (; *text; ++text) { + if ((unsigned char)*text >= font->GetCharCount()) { + *text = '?'; + } + } } -int WFNFontRenderer::GetTextWidth(const char *text, int fontNumber) -{ - const WFNFont* font = _fontData[fontNumber].Font; - const FontRenderParams ¶ms = _fontData[fontNumber].Params; - int text_width = 0; - - for (; *text; ++text) - { - const WFNChar &wfn_char = font->GetChar(GetCharCode(*text, font)); - text_width += wfn_char.Width; - } - return text_width * params.SizeMultiplier; +int WFNFontRenderer::GetTextWidth(const char *text, int fontNumber) { + const WFNFont *font = _fontData[fontNumber].Font; + const FontRenderParams ¶ms = _fontData[fontNumber].Params; + int text_width = 0; + + for (; *text; ++text) { + const WFNChar &wfn_char = font->GetChar(GetCharCode(*text, font)); + text_width += wfn_char.Width; + } + return text_width * params.SizeMultiplier; } -int WFNFontRenderer::GetTextHeight(const char *text, int fontNumber) -{ - const WFNFont* font = _fontData[fontNumber].Font; - const FontRenderParams ¶ms = _fontData[fontNumber].Params; - int max_height = 0; - - for (; *text; ++text) - { - const WFNChar &wfn_char = font->GetChar(GetCharCode(*text, font)); - const uint16_t height = wfn_char.Height; - if (height > max_height) - max_height = height; - } - return max_height * params.SizeMultiplier; +int WFNFontRenderer::GetTextHeight(const char *text, int fontNumber) { + const WFNFont *font = _fontData[fontNumber].Font; + const FontRenderParams ¶ms = _fontData[fontNumber].Params; + int max_height = 0; + + for (; *text; ++text) { + const WFNChar &wfn_char = font->GetChar(GetCharCode(*text, font)); + const uint16_t height = wfn_char.Height; + if (height > max_height) + max_height = height; + } + return max_height * params.SizeMultiplier; } Bitmap render_wrapper; -void WFNFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) -{ - int oldeip = get_our_eip(); - set_our_eip(415); +void WFNFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) { + int oldeip = get_our_eip(); + set_our_eip(415); - const WFNFont* font = _fontData[fontNumber].Font; - const FontRenderParams ¶ms = _fontData[fontNumber].Params; - render_wrapper.WrapAllegroBitmap(destination, true); + const WFNFont *font = _fontData[fontNumber].Font; + const FontRenderParams ¶ms = _fontData[fontNumber].Params; + render_wrapper.WrapAllegroBitmap(destination, true); - for (; *text; ++text) - x += RenderChar(&render_wrapper, x, y, font->GetChar(GetCharCode(*text, font)), params.SizeMultiplier, colour); + for (; *text; ++text) + x += RenderChar(&render_wrapper, x, y, font->GetChar(GetCharCode(*text, font)), params.SizeMultiplier, colour); - set_our_eip(oldeip); + set_our_eip(oldeip); } -int RenderChar(Bitmap *ds, const int at_x, const int at_y, const WFNChar &wfn_char, const int scale, const color_t text_color) -{ - const int width = wfn_char.Width; - const int height = wfn_char.Height; - const unsigned char *actdata = wfn_char.Data; - const int bytewid = wfn_char.GetRowByteCount(); - - int x = at_x; - int y = at_y; - for (int h = 0; h < height; ++h) - { - for (int w = 0; w < width; ++w) - { - if (((actdata[h * bytewid + (w / 8)] & (0x80 >> (w % 8))) != 0)) { - if (scale > 1) - { - ds->FillRect(Rect(x + w, y + h, x + w + (scale - 1), - y + h + (scale - 1)), text_color); - } - else - { - ds->PutPixel(x + w, y + h, text_color); - } - } - - x += scale - 1; - } - y += scale - 1; - x = at_x; - } - return width * scale; +int RenderChar(Bitmap *ds, const int at_x, const int at_y, const WFNChar &wfn_char, const int scale, const color_t text_color) { + const int width = wfn_char.Width; + const int height = wfn_char.Height; + const unsigned char *actdata = wfn_char.Data; + const int bytewid = wfn_char.GetRowByteCount(); + + int x = at_x; + int y = at_y; + for (int h = 0; h < height; ++h) { + for (int w = 0; w < width; ++w) { + if (((actdata[h * bytewid + (w / 8)] & (0x80 >> (w % 8))) != 0)) { + if (scale > 1) { + ds->FillRect(Rect(x + w, y + h, x + w + (scale - 1), + y + h + (scale - 1)), text_color); + } else { + ds->PutPixel(x + w, y + h, text_color); + } + } + + x += scale - 1; + } + y += scale - 1; + x = at_x; + } + return width * scale; } -bool WFNFontRenderer::LoadFromDisk(int fontNumber, int fontSize) -{ - return LoadFromDiskEx(fontNumber, fontSize, nullptr); +bool WFNFontRenderer::LoadFromDisk(int fontNumber, int fontSize) { + return LoadFromDiskEx(fontNumber, fontSize, nullptr); } -bool WFNFontRenderer::IsBitmapFont() -{ - return true; +bool WFNFontRenderer::IsBitmapFont() { + return true; } -bool WFNFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) -{ - String file_name; - Stream *ffi = nullptr; - - file_name.Format("agsfnt%d.wfn", fontNumber); - ffi = AssetManager::OpenAsset(file_name); - if (ffi == nullptr) - { - // actual font not found, try font 0 instead - file_name = "agsfnt0.wfn"; - ffi = AssetManager::OpenAsset(file_name); - if (ffi == nullptr) - return false; - } - - WFNFont *font = new WFNFont(); - WFNError err = font->ReadFromFile(ffi, AssetManager::GetLastAssetSize()); - delete ffi; - if (err == kWFNErr_HasBadCharacters) - Debug::Printf(kDbgMsg_Warn, "WARNING: font '%s' has mistakes in data format, some characters may be displayed incorrectly", file_name.GetCStr()); - else if (err != kWFNErr_NoError) - { - delete font; - return false; - } - _fontData[fontNumber].Font = font; - _fontData[fontNumber].Params = params ? *params : FontRenderParams(); - return true; +bool WFNFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) { + String file_name; + Stream *ffi = nullptr; + + file_name.Format("agsfnt%d.wfn", fontNumber); + ffi = AssetManager::OpenAsset(file_name); + if (ffi == nullptr) { + // actual font not found, try font 0 instead + file_name = "agsfnt0.wfn"; + ffi = AssetManager::OpenAsset(file_name); + if (ffi == nullptr) + return false; + } + + WFNFont *font = new WFNFont(); + WFNError err = font->ReadFromFile(ffi, AssetManager::GetLastAssetSize()); + delete ffi; + if (err == kWFNErr_HasBadCharacters) + Debug::Printf(kDbgMsg_Warn, "WARNING: font '%s' has mistakes in data format, some characters may be displayed incorrectly", file_name.GetCStr()); + else if (err != kWFNErr_NoError) { + delete font; + return false; + } + _fontData[fontNumber].Font = font; + _fontData[fontNumber].Params = params ? *params : FontRenderParams(); + return true; } -void WFNFontRenderer::FreeMemory(int fontNumber) -{ - delete _fontData[fontNumber].Font; - _fontData.erase(fontNumber); +void WFNFontRenderer::FreeMemory(int fontNumber) { + delete _fontData[fontNumber].Font; + _fontData.erase(fontNumber); } -bool WFNFontRenderer::SupportsExtendedCharacters(int fontNumber) -{ - return _fontData[fontNumber].Font->GetCharCount() > 128; +bool WFNFontRenderer::SupportsExtendedCharacters(int fontNumber) { + return _fontData[fontNumber].Font->GetCharCount() > 128; } diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index 4a164bac9274..c2fed5015983 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -30,25 +30,24 @@ class WFNFont; class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { public: - bool LoadFromDisk(int fontNumber, int fontSize) override; - void FreeMemory(int fontNumber) override; - bool SupportsExtendedCharacters(int fontNumber) override; - int GetTextWidth(const char *text, int fontNumber) override; - int GetTextHeight(const char *text, int fontNumber) override; - void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override; - void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override; - void EnsureTextValidForFont(char *text, int fontNumber) override; + bool LoadFromDisk(int fontNumber, int fontSize) override; + void FreeMemory(int fontNumber) override; + bool SupportsExtendedCharacters(int fontNumber) override; + int GetTextWidth(const char *text, int fontNumber) override; + int GetTextHeight(const char *text, int fontNumber) override; + void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override; + void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override; + void EnsureTextValidForFont(char *text, int fontNumber) override; - bool IsBitmapFont() override; - bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override; + bool IsBitmapFont() override; + bool LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) override; private: - struct FontData - { - WFNFont *Font; - FontRenderParams Params; - }; - std::map _fontData; + struct FontData { + WFNFont *Font; + FontRenderParams Params; + }; + std::map _fontData; }; #endif diff --git a/engines/ags/shared/game/customproperties.cpp b/engines/ags/shared/game/customproperties.cpp index db1071874723..61232af84cea 100644 --- a/engines/ags/shared/game/customproperties.cpp +++ b/engines/ags/shared/game/customproperties.cpp @@ -24,118 +24,95 @@ #include "util/stream.h" #include "util/string_utils.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -PropertyDesc::PropertyDesc() -{ - Type = kPropertyBoolean; +PropertyDesc::PropertyDesc() { + Type = kPropertyBoolean; } -PropertyDesc::PropertyDesc(const String &name, PropertyType type, const String &desc, const String &def_value) -{ - Name = name; - Type = type; - Description = desc; - DefaultValue = def_value; +PropertyDesc::PropertyDesc(const String &name, PropertyType type, const String &desc, const String &def_value) { + Name = name; + Type = type; + Description = desc; + DefaultValue = def_value; } -namespace Properties -{ +namespace Properties { -PropertyError ReadSchema(PropertySchema &schema, Stream *in) -{ - PropertyVersion version = (PropertyVersion)in->ReadInt32(); - if (version < kPropertyVersion_Initial || - version > kPropertyVersion_Current) - { - return kPropertyErr_UnsupportedFormat; - } +PropertyError ReadSchema(PropertySchema &schema, Stream *in) { + PropertyVersion version = (PropertyVersion)in->ReadInt32(); + if (version < kPropertyVersion_Initial || + version > kPropertyVersion_Current) { + return kPropertyErr_UnsupportedFormat; + } - PropertyDesc prop; - int count = in->ReadInt32(); - if (version == kPropertyVersion_Initial) - { - for (int i = 0; i < count; ++i) - { - prop.Name.Read(in, LEGACY_MAX_CUSTOM_PROP_SCHEMA_NAME_LENGTH); - prop.Description.Read(in, LEGACY_MAX_CUSTOM_PROP_DESC_LENGTH); - prop.DefaultValue.Read(in, LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH); - prop.Type = (PropertyType)in->ReadInt32(); - schema[prop.Name] = prop; - } - } - else - { - for (int i = 0; i < count; ++i) - { - prop.Name = StrUtil::ReadString(in); - prop.Type = (PropertyType)in->ReadInt32(); - prop.Description = StrUtil::ReadString(in); - prop.DefaultValue = StrUtil::ReadString(in); - schema[prop.Name] = prop; - } - } - return kPropertyErr_NoError; + PropertyDesc prop; + int count = in->ReadInt32(); + if (version == kPropertyVersion_Initial) { + for (int i = 0; i < count; ++i) { + prop.Name.Read(in, LEGACY_MAX_CUSTOM_PROP_SCHEMA_NAME_LENGTH); + prop.Description.Read(in, LEGACY_MAX_CUSTOM_PROP_DESC_LENGTH); + prop.DefaultValue.Read(in, LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH); + prop.Type = (PropertyType)in->ReadInt32(); + schema[prop.Name] = prop; + } + } else { + for (int i = 0; i < count; ++i) { + prop.Name = StrUtil::ReadString(in); + prop.Type = (PropertyType)in->ReadInt32(); + prop.Description = StrUtil::ReadString(in); + prop.DefaultValue = StrUtil::ReadString(in); + schema[prop.Name] = prop; + } + } + return kPropertyErr_NoError; } -void WriteSchema(const PropertySchema &schema, Stream *out) -{ - out->WriteInt32(kPropertyVersion_Current); - out->WriteInt32(schema.size()); - for (PropertySchema::const_iterator it = schema.begin(); - it != schema.end(); ++it) - { - const PropertyDesc &prop = it->second; - StrUtil::WriteString(prop.Name, out); - out->WriteInt32(prop.Type); - StrUtil::WriteString(prop.Description, out); - StrUtil::WriteString(prop.DefaultValue, out); - } +void WriteSchema(const PropertySchema &schema, Stream *out) { + out->WriteInt32(kPropertyVersion_Current); + out->WriteInt32(schema.size()); + for (PropertySchema::const_iterator it = schema.begin(); + it != schema.end(); ++it) { + const PropertyDesc &prop = it->second; + StrUtil::WriteString(prop.Name, out); + out->WriteInt32(prop.Type); + StrUtil::WriteString(prop.Description, out); + StrUtil::WriteString(prop.DefaultValue, out); + } } -PropertyError ReadValues(StringIMap &map, Stream *in) -{ - PropertyVersion version = (PropertyVersion)in->ReadInt32(); - if (version < kPropertyVersion_Initial || - version > kPropertyVersion_Current) - { - return kPropertyErr_UnsupportedFormat; - } +PropertyError ReadValues(StringIMap &map, Stream *in) { + PropertyVersion version = (PropertyVersion)in->ReadInt32(); + if (version < kPropertyVersion_Initial || + version > kPropertyVersion_Current) { + return kPropertyErr_UnsupportedFormat; + } - int count = in->ReadInt32(); - if (version == kPropertyVersion_Initial) - { - for (int i = 0; i < count; ++i) - { - String name = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_NAME_LENGTH); - map[name] = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH); - } - } - else - { - for (int i = 0; i < count; ++i) - { - String name = StrUtil::ReadString(in); - map[name] = StrUtil::ReadString(in); - } - } - return kPropertyErr_NoError; + int count = in->ReadInt32(); + if (version == kPropertyVersion_Initial) { + for (int i = 0; i < count; ++i) { + String name = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_NAME_LENGTH); + map[name] = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH); + } + } else { + for (int i = 0; i < count; ++i) { + String name = StrUtil::ReadString(in); + map[name] = StrUtil::ReadString(in); + } + } + return kPropertyErr_NoError; } -void WriteValues(const StringIMap &map, Stream *out) -{ - out->WriteInt32(kPropertyVersion_Current); - out->WriteInt32(map.size()); - for (StringIMap::const_iterator it = map.begin(); - it != map.end(); ++it) - { - StrUtil::WriteString(it->first, out); - StrUtil::WriteString(it->second, out); - } +void WriteValues(const StringIMap &map, Stream *out) { + out->WriteInt32(kPropertyVersion_Current); + out->WriteInt32(map.size()); + for (StringIMap::const_iterator it = map.begin(); + it != map.end(); ++it) { + StrUtil::WriteString(it->first, out); + StrUtil::WriteString(it->second, out); + } } } // namespace Properties diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index 325cc21ac919..51d546448112 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -49,44 +49,38 @@ #define LEGACY_MAX_CUSTOM_PROP_DESC_LENGTH 100 #define LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH 500 -namespace AGS -{ -namespace Common -{ - -enum PropertyVersion -{ - kPropertyVersion_Initial = 1, - kPropertyVersion_340, - kPropertyVersion_Current = kPropertyVersion_340 +namespace AGS { +namespace Common { + +enum PropertyVersion { + kPropertyVersion_Initial = 1, + kPropertyVersion_340, + kPropertyVersion_Current = kPropertyVersion_340 }; -enum PropertyType -{ - kPropertyUndefined = 0, - kPropertyBoolean, - kPropertyInteger, - kPropertyString +enum PropertyType { + kPropertyUndefined = 0, + kPropertyBoolean, + kPropertyInteger, + kPropertyString }; -enum PropertyError -{ - kPropertyErr_NoError, - kPropertyErr_UnsupportedFormat +enum PropertyError { + kPropertyErr_NoError, + kPropertyErr_UnsupportedFormat }; // // PropertyDesc - a description of a single custom property // -struct PropertyDesc -{ - String Name; - PropertyType Type; - String Description; - String DefaultValue; - - PropertyDesc(); - PropertyDesc(const String &name, PropertyType type, const String &desc, const String &def_value); +struct PropertyDesc { + String Name; + PropertyType Type; + String Description; + String DefaultValue; + + PropertyDesc(); + PropertyDesc(const String &name, PropertyType type, const String &desc, const String &def_value); }; // NOTE: AGS has case-insensitive property IDs @@ -94,16 +88,15 @@ struct PropertyDesc typedef std::unordered_map PropertySchema; -namespace Properties -{ - PropertyError ReadSchema(PropertySchema &schema, Stream *in); - void WriteSchema(const PropertySchema &schema, Stream *out); +namespace Properties { +PropertyError ReadSchema(PropertySchema &schema, Stream *in); +void WriteSchema(const PropertySchema &schema, Stream *out); - // Reads property values from the stream and assign them to map. - // The non-matching existing map items, if any, are NOT erased. - PropertyError ReadValues(StringIMap &map, Stream *in); - // Writes property values chunk to the stream - void WriteValues(const StringIMap &map, Stream *out); +// Reads property values from the stream and assign them to map. +// The non-matching existing map items, if any, are NOT erased. +PropertyError ReadValues(StringIMap &map, Stream *in); +// Writes property values chunk to the stream +void WriteValues(const StringIMap &map, Stream *out); } // namespace Properties diff --git a/engines/ags/shared/game/interactions.cpp b/engines/ags/shared/game/interactions.cpp index be596c8279d5..7b8c2508c603 100644 --- a/engines/ags/shared/game/interactions.cpp +++ b/engines/ags/shared/game/interactions.cpp @@ -31,355 +31,301 @@ using namespace AGS::Common; InteractionVariable globalvars[MAX_GLOBAL_VARIABLES] = {InteractionVariable("Global 1", 0, 0)}; int numGlobalVars = 1; -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -InteractionValue::InteractionValue() -{ - Type = kInterValLiteralInt; - Value = 0; - Extra = 0; +InteractionValue::InteractionValue() { + Type = kInterValLiteralInt; + Value = 0; + Extra = 0; } -void InteractionValue::Read(Stream *in) -{ - Type = (InterValType)in->ReadInt8(); - Value = in->ReadInt32(); - Extra = in->ReadInt32(); +void InteractionValue::Read(Stream *in) { + Type = (InterValType)in->ReadInt8(); + Value = in->ReadInt32(); + Extra = in->ReadInt32(); } -void InteractionValue::Write(Stream *out) const -{ - out->WriteInt8(Type); - out->WriteInt32(Value); - out->WriteInt32(Extra); +void InteractionValue::Write(Stream *out) const { + out->WriteInt8(Type); + out->WriteInt32(Value); + out->WriteInt32(Extra); } //----------------------------------------------------------------------------- InteractionCommand::InteractionCommand() - : Type(0) - , Parent(nullptr) -{ + : Type(0) + , Parent(nullptr) { } -InteractionCommand::InteractionCommand(const InteractionCommand &ic) -{ - *this = ic; +InteractionCommand::InteractionCommand(const InteractionCommand &ic) { + *this = ic; } -void InteractionCommand::Assign(const InteractionCommand &ic, InteractionCommandList *parent) -{ - Type = ic.Type; - memcpy(Data, ic.Data, sizeof(Data)); - Children.reset(ic.Children.get() ? new InteractionCommandList(*ic.Children) : nullptr); - Parent = parent; +void InteractionCommand::Assign(const InteractionCommand &ic, InteractionCommandList *parent) { + Type = ic.Type; + memcpy(Data, ic.Data, sizeof(Data)); + Children.reset(ic.Children.get() ? new InteractionCommandList(*ic.Children) : nullptr); + Parent = parent; } -void InteractionCommand::Reset() -{ - Type = 0; - memset(Data, 0, sizeof(Data)); - Children.reset(); - Parent = nullptr; +void InteractionCommand::Reset() { + Type = 0; + memset(Data, 0, sizeof(Data)); + Children.reset(); + Parent = nullptr; } -void InteractionCommand::ReadValues_Aligned(Stream *in) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (int i = 0; i < MAX_ACTION_ARGS; ++i) - { - Data[i].Read(&align_s); - align_s.Reset(); - } +void InteractionCommand::ReadValues_Aligned(Stream *in) { + AlignedStream align_s(in, Common::kAligned_Read); + for (int i = 0; i < MAX_ACTION_ARGS; ++i) { + Data[i].Read(&align_s); + align_s.Reset(); + } } -void InteractionCommand::Read_v321(Stream *in, bool &has_children) -{ - in->ReadInt32(); // skip the 32-bit vtbl ptr (the old serialization peculiarity) - Type = in->ReadInt32(); - ReadValues_Aligned(in); - has_children = in->ReadInt32() != 0; - in->ReadInt32(); // skip 32-bit Parent pointer +void InteractionCommand::Read_v321(Stream *in, bool &has_children) { + in->ReadInt32(); // skip the 32-bit vtbl ptr (the old serialization peculiarity) + Type = in->ReadInt32(); + ReadValues_Aligned(in); + has_children = in->ReadInt32() != 0; + in->ReadInt32(); // skip 32-bit Parent pointer } -void InteractionCommand::WriteValues_Aligned(Stream *out) const -{ - AlignedStream align_s(out, Common::kAligned_Write); - for (int i = 0; i < MAX_ACTION_ARGS; ++i) - { - Data[i].Write(&align_s); - align_s.Reset(); - } +void InteractionCommand::WriteValues_Aligned(Stream *out) const { + AlignedStream align_s(out, Common::kAligned_Write); + for (int i = 0; i < MAX_ACTION_ARGS; ++i) { + Data[i].Write(&align_s); + align_s.Reset(); + } } -void InteractionCommand::Write_v321(Stream *out) const -{ - out->WriteInt32(0); // write dummy 32-bit vtbl ptr - out->WriteInt32(Type); - WriteValues_Aligned(out); - out->WriteInt32(Children.get() ? 1 : 0); - out->WriteInt32(Parent ? 1 : 0); +void InteractionCommand::Write_v321(Stream *out) const { + out->WriteInt32(0); // write dummy 32-bit vtbl ptr + out->WriteInt32(Type); + WriteValues_Aligned(out); + out->WriteInt32(Children.get() ? 1 : 0); + out->WriteInt32(Parent ? 1 : 0); } -InteractionCommand &InteractionCommand::operator = (const InteractionCommand &ic) -{ - Type = ic.Type; - memcpy(Data, ic.Data, sizeof(Data)); - Children.reset(ic.Children.get() ? new InteractionCommandList(*ic.Children) : nullptr); - Parent = ic.Parent; - return *this; +InteractionCommand &InteractionCommand::operator = (const InteractionCommand &ic) { + Type = ic.Type; + memcpy(Data, ic.Data, sizeof(Data)); + Children.reset(ic.Children.get() ? new InteractionCommandList(*ic.Children) : nullptr); + Parent = ic.Parent; + return *this; } //----------------------------------------------------------------------------- InteractionCommandList::InteractionCommandList() - : TimesRun(0) -{ -} - -InteractionCommandList::InteractionCommandList(const InteractionCommandList &icmd_list) -{ - TimesRun = icmd_list.TimesRun; - Cmds.resize(icmd_list.Cmds.size()); - for (size_t i = 0; i < icmd_list.Cmds.size(); ++i) - { - Cmds[i].Assign(icmd_list.Cmds[i], this); - } -} - -void InteractionCommandList::Reset() -{ - Cmds.clear(); - TimesRun = 0; -} - -void InteractionCommandList::Read_Aligned(Stream *in, std::vector &cmd_children) -{ - AlignedStream align_s(in, Common::kAligned_Read); - for (size_t i = 0; i < Cmds.size(); ++i) - { - bool has_children; - Cmds[i].Read_v321(&align_s, has_children); - cmd_children[i] = has_children; - align_s.Reset(); - } -} - -void InteractionCommandList::Read_v321(Stream *in) -{ - size_t cmd_count = in->ReadInt32(); - TimesRun = in->ReadInt32(); - - std::vector cmd_children; - Cmds.resize(cmd_count); - cmd_children.resize(cmd_count); - Read_Aligned(in, cmd_children); - - for (size_t i = 0; i < cmd_count; ++i) - { - if (cmd_children[i]) - { - Cmds[i].Children.reset(new InteractionCommandList()); - Cmds[i].Children->Read_v321(in); - } - Cmds[i].Parent = this; - } -} - -void InteractionCommandList::Write_Aligned(Stream *out) const -{ - AlignedStream align_s(out, Common::kAligned_Write); - for (InterCmdVector::const_iterator it = Cmds.begin(); it != Cmds.end(); ++it) - { - it->Write_v321(&align_s); - align_s.Reset(); - } -} - -void InteractionCommandList::Write_v321(Stream *out) const -{ - size_t cmd_count = Cmds.size(); - out->WriteInt32(cmd_count); - out->WriteInt32(TimesRun); - - Write_Aligned(out); - - for (size_t i = 0; i < cmd_count; ++i) - { - if (Cmds[i].Children.get() != nullptr) - Cmds[i].Children->Write_v321(out); - } + : TimesRun(0) { +} + +InteractionCommandList::InteractionCommandList(const InteractionCommandList &icmd_list) { + TimesRun = icmd_list.TimesRun; + Cmds.resize(icmd_list.Cmds.size()); + for (size_t i = 0; i < icmd_list.Cmds.size(); ++i) { + Cmds[i].Assign(icmd_list.Cmds[i], this); + } +} + +void InteractionCommandList::Reset() { + Cmds.clear(); + TimesRun = 0; +} + +void InteractionCommandList::Read_Aligned(Stream *in, std::vector &cmd_children) { + AlignedStream align_s(in, Common::kAligned_Read); + for (size_t i = 0; i < Cmds.size(); ++i) { + bool has_children; + Cmds[i].Read_v321(&align_s, has_children); + cmd_children[i] = has_children; + align_s.Reset(); + } +} + +void InteractionCommandList::Read_v321(Stream *in) { + size_t cmd_count = in->ReadInt32(); + TimesRun = in->ReadInt32(); + + std::vector cmd_children; + Cmds.resize(cmd_count); + cmd_children.resize(cmd_count); + Read_Aligned(in, cmd_children); + + for (size_t i = 0; i < cmd_count; ++i) { + if (cmd_children[i]) { + Cmds[i].Children.reset(new InteractionCommandList()); + Cmds[i].Children->Read_v321(in); + } + Cmds[i].Parent = this; + } +} + +void InteractionCommandList::Write_Aligned(Stream *out) const { + AlignedStream align_s(out, Common::kAligned_Write); + for (InterCmdVector::const_iterator it = Cmds.begin(); it != Cmds.end(); ++it) { + it->Write_v321(&align_s); + align_s.Reset(); + } +} + +void InteractionCommandList::Write_v321(Stream *out) const { + size_t cmd_count = Cmds.size(); + out->WriteInt32(cmd_count); + out->WriteInt32(TimesRun); + + Write_Aligned(out); + + for (size_t i = 0; i < cmd_count; ++i) { + if (Cmds[i].Children.get() != nullptr) + Cmds[i].Children->Write_v321(out); + } } //----------------------------------------------------------------------------- InteractionEvent::InteractionEvent() - : Type(0) - , TimesRun(0) -{ + : Type(0) + , TimesRun(0) { } -InteractionEvent::InteractionEvent(const InteractionEvent &ie) -{ - *this = ie; +InteractionEvent::InteractionEvent(const InteractionEvent &ie) { + *this = ie; } -InteractionEvent &InteractionEvent::operator = (const InteractionEvent &ie) -{ - Type = ie.Type; - TimesRun = ie.TimesRun; - Response.reset(ie.Response.get() ? new InteractionCommandList(*ie.Response) : nullptr); - return *this; +InteractionEvent &InteractionEvent::operator = (const InteractionEvent &ie) { + Type = ie.Type; + TimesRun = ie.TimesRun; + Response.reset(ie.Response.get() ? new InteractionCommandList(*ie.Response) : nullptr); + return *this; } //----------------------------------------------------------------------------- -Interaction::Interaction() -{ -} - -Interaction::Interaction(const Interaction &ni) -{ - *this = ni; -} - -Interaction &Interaction::operator =(const Interaction &ni) -{ - Events.resize(ni.Events.size()); - for (size_t i = 0; i < ni.Events.size(); ++i) - { - Events[i] = InteractionEvent(ni.Events[i]); - } - return *this; -} - -void Interaction::CopyTimesRun(const Interaction &inter) -{ - assert(Events.size() == inter.Events.size()); - size_t count = Math::Min(Events.size(), inter.Events.size()); - for (size_t i = 0; i < count; ++i) - { - Events[i].TimesRun = inter.Events[i].TimesRun; - } -} - -void Interaction::Reset() -{ - Events.clear(); -} - -Interaction *Interaction::CreateFromStream(Stream *in) -{ - if (in->ReadInt32() != kInteractionVersion_Initial) - return nullptr; // unsupported format - - const size_t evt_count = in->ReadInt32(); - if (evt_count > MAX_NEWINTERACTION_EVENTS) - quit("Can't deserialize interaction: too many events"); - - int types[MAX_NEWINTERACTION_EVENTS]; - int load_response[MAX_NEWINTERACTION_EVENTS]; - in->ReadArrayOfInt32(types, evt_count); - in->ReadArrayOfInt32(load_response, evt_count); - - Interaction *inter = new Interaction(); - inter->Events.resize(evt_count); - for (size_t i = 0; i < evt_count; ++i) - { - InteractionEvent &evt = inter->Events[i]; - evt.Type = types[i]; - if (load_response[i] != 0) - { - evt.Response.reset(new InteractionCommandList()); - evt.Response->Read_v321(in); - } - } - return inter; -} - -void Interaction::Write(Stream *out) const -{ - out->WriteInt32(kInteractionVersion_Initial); // Version - const size_t evt_count = Events.size(); - out->WriteInt32(evt_count); - for (size_t i = 0; i < evt_count; ++i) - { - out->WriteInt32(Events[i].Type); - } - - // The pointer is only checked against NULL to determine whether the event exists - for (size_t i = 0; i < evt_count; ++i) - { - out->WriteInt32 (Events[i].Response.get() ? 1 : 0); - } - - for (size_t i = 0; i < evt_count; ++i) - { - if (Events[i].Response.get()) - Events[i].Response->Write_v321(out); - } -} - -void Interaction::ReadFromSavedgame_v321(Stream *in) -{ - const size_t evt_count = in->ReadInt32(); - if (evt_count > MAX_NEWINTERACTION_EVENTS) - quit("Can't deserialize interaction: too many events"); - - Events.resize(evt_count); - for (size_t i = 0; i < evt_count; ++i) - { - Events[i].Type = in->ReadInt32(); - } - const size_t padding = (MAX_NEWINTERACTION_EVENTS - evt_count); - for (size_t i = 0; i < padding; ++i) - in->ReadInt32(); // cannot skip when reading aligned structs - ReadTimesRunFromSave_v321(in); - - // Skip an array of dummy 32-bit pointers - for (size_t i = 0; i < MAX_NEWINTERACTION_EVENTS; ++i) - in->ReadInt32(); -} - -void Interaction::WriteToSavedgame_v321(Stream *out) const -{ - const size_t evt_count = Events.size(); - out->WriteInt32(evt_count); - - for (size_t i = 0; i < evt_count; ++i) - { - out->WriteInt32(Events[i].Type); - } - out->WriteByteCount(0, (MAX_NEWINTERACTION_EVENTS - evt_count) * sizeof(int32_t)); - WriteTimesRunToSave_v321(out); - - // Array of dummy 32-bit pointers - out->WriteByteCount(0, MAX_NEWINTERACTION_EVENTS * sizeof(int32_t)); -} - -void Interaction::ReadTimesRunFromSave_v321(Stream *in) -{ - const size_t evt_count = Events.size(); - for (size_t i = 0; i < evt_count; ++i) - { - Events[i].TimesRun = in->ReadInt32(); - } - const size_t padding = (MAX_NEWINTERACTION_EVENTS - evt_count); - for (size_t i = 0; i < padding; ++i) - in->ReadInt32(); // cannot skip when reading aligned structs -} - -void Interaction::WriteTimesRunToSave_v321(Stream *out) const -{ - const size_t evt_count = Events.size(); - for (size_t i = 0; i < Events.size(); ++i) - { - out->WriteInt32(Events[i].TimesRun); - } - out->WriteByteCount(0, (MAX_NEWINTERACTION_EVENTS - evt_count) * sizeof(int32_t)); +Interaction::Interaction() { +} + +Interaction::Interaction(const Interaction &ni) { + *this = ni; +} + +Interaction &Interaction::operator =(const Interaction &ni) { + Events.resize(ni.Events.size()); + for (size_t i = 0; i < ni.Events.size(); ++i) { + Events[i] = InteractionEvent(ni.Events[i]); + } + return *this; +} + +void Interaction::CopyTimesRun(const Interaction &inter) { + assert(Events.size() == inter.Events.size()); + size_t count = Math::Min(Events.size(), inter.Events.size()); + for (size_t i = 0; i < count; ++i) { + Events[i].TimesRun = inter.Events[i].TimesRun; + } +} + +void Interaction::Reset() { + Events.clear(); +} + +Interaction *Interaction::CreateFromStream(Stream *in) { + if (in->ReadInt32() != kInteractionVersion_Initial) + return nullptr; // unsupported format + + const size_t evt_count = in->ReadInt32(); + if (evt_count > MAX_NEWINTERACTION_EVENTS) + quit("Can't deserialize interaction: too many events"); + + int types[MAX_NEWINTERACTION_EVENTS]; + int load_response[MAX_NEWINTERACTION_EVENTS]; + in->ReadArrayOfInt32(types, evt_count); + in->ReadArrayOfInt32(load_response, evt_count); + + Interaction *inter = new Interaction(); + inter->Events.resize(evt_count); + for (size_t i = 0; i < evt_count; ++i) { + InteractionEvent &evt = inter->Events[i]; + evt.Type = types[i]; + if (load_response[i] != 0) { + evt.Response.reset(new InteractionCommandList()); + evt.Response->Read_v321(in); + } + } + return inter; +} + +void Interaction::Write(Stream *out) const { + out->WriteInt32(kInteractionVersion_Initial); // Version + const size_t evt_count = Events.size(); + out->WriteInt32(evt_count); + for (size_t i = 0; i < evt_count; ++i) { + out->WriteInt32(Events[i].Type); + } + + // The pointer is only checked against NULL to determine whether the event exists + for (size_t i = 0; i < evt_count; ++i) { + out->WriteInt32(Events[i].Response.get() ? 1 : 0); + } + + for (size_t i = 0; i < evt_count; ++i) { + if (Events[i].Response.get()) + Events[i].Response->Write_v321(out); + } +} + +void Interaction::ReadFromSavedgame_v321(Stream *in) { + const size_t evt_count = in->ReadInt32(); + if (evt_count > MAX_NEWINTERACTION_EVENTS) + quit("Can't deserialize interaction: too many events"); + + Events.resize(evt_count); + for (size_t i = 0; i < evt_count; ++i) { + Events[i].Type = in->ReadInt32(); + } + const size_t padding = (MAX_NEWINTERACTION_EVENTS - evt_count); + for (size_t i = 0; i < padding; ++i) + in->ReadInt32(); // cannot skip when reading aligned structs + ReadTimesRunFromSave_v321(in); + + // Skip an array of dummy 32-bit pointers + for (size_t i = 0; i < MAX_NEWINTERACTION_EVENTS; ++i) + in->ReadInt32(); +} + +void Interaction::WriteToSavedgame_v321(Stream *out) const { + const size_t evt_count = Events.size(); + out->WriteInt32(evt_count); + + for (size_t i = 0; i < evt_count; ++i) { + out->WriteInt32(Events[i].Type); + } + out->WriteByteCount(0, (MAX_NEWINTERACTION_EVENTS - evt_count) * sizeof(int32_t)); + WriteTimesRunToSave_v321(out); + + // Array of dummy 32-bit pointers + out->WriteByteCount(0, MAX_NEWINTERACTION_EVENTS * sizeof(int32_t)); +} + +void Interaction::ReadTimesRunFromSave_v321(Stream *in) { + const size_t evt_count = Events.size(); + for (size_t i = 0; i < evt_count; ++i) { + Events[i].TimesRun = in->ReadInt32(); + } + const size_t padding = (MAX_NEWINTERACTION_EVENTS - evt_count); + for (size_t i = 0; i < padding; ++i) + in->ReadInt32(); // cannot skip when reading aligned structs +} + +void Interaction::WriteTimesRunToSave_v321(Stream *out) const { + const size_t evt_count = Events.size(); + for (size_t i = 0; i < Events.size(); ++i) { + out->WriteInt32(Events[i].TimesRun); + } + out->WriteByteCount(0, (MAX_NEWINTERACTION_EVENTS - evt_count) * sizeof(int32_t)); } //----------------------------------------------------------------------------- @@ -387,50 +333,43 @@ void Interaction::WriteTimesRunToSave_v321(Stream *out) const #define INTER_VAR_NAME_LENGTH 23 InteractionVariable::InteractionVariable() - : Type(0) - , Value(0) -{ + : Type(0) + , Value(0) { } InteractionVariable::InteractionVariable(const String &name, char type, int val) - : Name(name) - , Type(type) - , Value(val) -{ + : Name(name) + , Type(type) + , Value(val) { } -void InteractionVariable::Read(Stream *in) -{ - Name.ReadCount(in, INTER_VAR_NAME_LENGTH); - Type = in->ReadInt8(); - Value = in->ReadInt32(); +void InteractionVariable::Read(Stream *in) { + Name.ReadCount(in, INTER_VAR_NAME_LENGTH); + Type = in->ReadInt8(); + Value = in->ReadInt32(); } -void InteractionVariable::Write(Common::Stream *out) const -{ - out->Write(Name, INTER_VAR_NAME_LENGTH); - out->WriteInt8(Type); - out->WriteInt32(Value); +void InteractionVariable::Write(Common::Stream *out) const { + out->Write(Name, INTER_VAR_NAME_LENGTH); + out->WriteInt8(Type); + out->WriteInt32(Value); } //----------------------------------------------------------------------------- -InteractionScripts *InteractionScripts::CreateFromStream(Stream *in) -{ - const size_t evt_count = in->ReadInt32(); - if (evt_count > MAX_NEWINTERACTION_EVENTS) - { - quit("Can't deserialize interaction scripts: too many events"); - return nullptr; - } - - InteractionScripts *scripts = new InteractionScripts(); - for (size_t i = 0; i < evt_count; ++i) - { - String name = String::FromStream(in); - scripts->ScriptFuncNames.push_back(name); - } - return scripts; +InteractionScripts *InteractionScripts::CreateFromStream(Stream *in) { + const size_t evt_count = in->ReadInt32(); + if (evt_count > MAX_NEWINTERACTION_EVENTS) { + quit("Can't deserialize interaction scripts: too many events"); + return nullptr; + } + + InteractionScripts *scripts = new InteractionScripts(); + for (size_t i = 0; i < evt_count; ++i) { + String name = String::FromStream(in); + scripts->ScriptFuncNames.push_back(name); + } + return scripts; } } // namespace Common diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index a82b6b7ff37b..61728294cb67 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -58,35 +58,30 @@ #define MAX_NEWINTERACTION_EVENTS 30 #define MAX_COMMANDS_PER_LIST 40 -namespace AGS -{ -namespace Common -{ - -enum InterValType -{ - kInterValLiteralInt = 1, - kInterValVariable = 2, - kInterValBoolean = 3, - kInterValCharnum = 4 +namespace AGS { +namespace Common { + +enum InterValType { + kInterValLiteralInt = 1, + kInterValVariable = 2, + kInterValBoolean = 3, + kInterValCharnum = 4 }; -enum InteractionVersion -{ - kInteractionVersion_Initial = 1 +enum InteractionVersion { + kInteractionVersion_Initial = 1 }; // InteractionValue represents an argument of interaction command -struct InteractionValue -{ - InterValType Type; // value type - int Value; // value definition - int Extra; +struct InteractionValue { + InterValType Type; // value type + int Value; // value definition + int Extra; - InteractionValue(); + InteractionValue(); - void Read(Stream *in); - void Write(Stream *out) const; + void Read(Stream *in); + void Write(Stream *out) const; }; @@ -94,121 +89,115 @@ struct InteractionCommandList; typedef std::unique_ptr UInterCmdList; // InteractionCommand represents a single command (action), an item of Command List -struct InteractionCommand -{ - int Type; // type of action - InteractionValue Data[MAX_ACTION_ARGS]; // action arguments - UInterCmdList Children; // list of sub-actions - InteractionCommandList *Parent; // action parent (optional) +struct InteractionCommand { + int Type; // type of action + InteractionValue Data[MAX_ACTION_ARGS]; // action arguments + UInterCmdList Children; // list of sub-actions + InteractionCommandList *Parent; // action parent (optional) - InteractionCommand(); - InteractionCommand(const InteractionCommand &ic); + InteractionCommand(); + InteractionCommand(const InteractionCommand &ic); - void Assign(const InteractionCommand &ic, InteractionCommandList *parent); - void Reset(); + void Assign(const InteractionCommand &ic, InteractionCommandList *parent); + void Reset(); - void Read_v321(Stream *in, bool &has_children); - void Write_v321(Stream *out) const; + void Read_v321(Stream *in, bool &has_children); + void Write_v321(Stream *out) const; - InteractionCommand &operator = (const InteractionCommand &ic); + InteractionCommand &operator = (const InteractionCommand &ic); private: - void ReadValues_Aligned(Stream *in); - void WriteValues_Aligned(Stream *out) const; + void ReadValues_Aligned(Stream *in); + void WriteValues_Aligned(Stream *out) const; }; typedef std::vector InterCmdVector; // InteractionCommandList represents a list of commands (actions) that need to be // performed on particular game event -struct InteractionCommandList -{ - InterCmdVector Cmds; // actions to run - int TimesRun; // used by engine to track score changes +struct InteractionCommandList { + InterCmdVector Cmds; // actions to run + int TimesRun; // used by engine to track score changes - InteractionCommandList(); - InteractionCommandList(const InteractionCommandList &icmd_list); + InteractionCommandList(); + InteractionCommandList(const InteractionCommandList &icmd_list); - void Reset(); + void Reset(); - void Read_v321(Stream *in); - void Write_v321(Stream *out) const; + void Read_v321(Stream *in); + void Write_v321(Stream *out) const; protected: - void Read_Aligned(Common::Stream *in, std::vector &cmd_children); - void Write_Aligned(Common::Stream *out) const; + void Read_Aligned(Common::Stream *in, std::vector &cmd_children); + void Write_Aligned(Common::Stream *out) const; }; // InteractionEvent is a single event with a list of commands to performed -struct InteractionEvent -{ - int Type; // type of event - int TimesRun; // used by engine to track score changes - UInterCmdList Response; // list of commands to run +struct InteractionEvent { + int Type; // type of event + int TimesRun; // used by engine to track score changes + UInterCmdList Response; // list of commands to run - InteractionEvent(); - InteractionEvent(const InteractionEvent &ie); + InteractionEvent(); + InteractionEvent(const InteractionEvent &ie); - InteractionEvent &operator = (const InteractionEvent &ic); + InteractionEvent &operator = (const InteractionEvent &ic); }; typedef std::vector InterEvtVector; // Interaction is the list of events and responses for a game or game object -struct Interaction -{ - // The first few event types depend on the item - ID's of 100+ are - // custom events (used for subroutines) - InterEvtVector Events; - - Interaction(); - Interaction(const Interaction &inter); - - // Copy information on number of times events of this interaction were fired - void CopyTimesRun(const Interaction &inter); - void Reset(); - - // Game static data (de)serialization - static Interaction *CreateFromStream(Stream *in); - void Write(Stream *out) const; - - // Reading and writing runtime data from/to savedgame; - // NOTE: these are backwards-compatible methods, that do not always - // have practical sense - void ReadFromSavedgame_v321(Stream *in); - void WriteToSavedgame_v321(Stream *out) const; - void ReadTimesRunFromSave_v321(Stream *in); - void WriteTimesRunToSave_v321(Stream *out) const; - - Interaction &operator =(const Interaction &inter); +struct Interaction { + // The first few event types depend on the item - ID's of 100+ are + // custom events (used for subroutines) + InterEvtVector Events; + + Interaction(); + Interaction(const Interaction &inter); + + // Copy information on number of times events of this interaction were fired + void CopyTimesRun(const Interaction &inter); + void Reset(); + + // Game static data (de)serialization + static Interaction *CreateFromStream(Stream *in); + void Write(Stream *out) const; + + // Reading and writing runtime data from/to savedgame; + // NOTE: these are backwards-compatible methods, that do not always + // have practical sense + void ReadFromSavedgame_v321(Stream *in); + void WriteToSavedgame_v321(Stream *out) const; + void ReadTimesRunFromSave_v321(Stream *in); + void WriteTimesRunToSave_v321(Stream *out) const; + + Interaction &operator =(const Interaction &inter); }; typedef std::shared_ptr PInteraction; // Legacy pre-3.0 kind of global and local room variables -struct InteractionVariable -{ - String Name {}; - char Type {'\0'}; - int Value {0}; +struct InteractionVariable { + String Name {}; + char Type {'\0'}; + int Value {0}; - InteractionVariable(); - InteractionVariable(const String &name, char type, int val); + InteractionVariable(); + InteractionVariable(const String &name, char type, int val); - void Read(Stream *in); - void Write(Stream *out) const; + void Read(Stream *in); + void Write(Stream *out) const; }; typedef std::vector InterVarVector; // A list of script function names for all supported events -struct InteractionScripts -{ - StringV ScriptFuncNames; +struct InteractionScripts { + StringV ScriptFuncNames; - static InteractionScripts *CreateFromStream(Stream *in); + static InteractionScripts *CreateFromStream(Stream *in); }; typedef std::shared_ptr PInteractionScripts; diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index a64e4c235b93..48dd4a26c9cc 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -39,800 +39,698 @@ #include "util/string_utils.h" #include "font/fonts.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { const String MainGameSource::DefaultFilename_v3 = "game28.dta"; const String MainGameSource::DefaultFilename_v2 = "ac2game.dta"; const String MainGameSource::Signature = "Adventure Creator Game File v2"; MainGameSource::MainGameSource() - : DataVersion(kGameVersion_Undefined) -{ + : DataVersion(kGameVersion_Undefined) { } -String GetMainGameFileErrorText(MainGameFileErrorType err) -{ - switch (err) - { - case kMGFErr_NoError: - return "No error."; - case kMGFErr_FileOpenFailed: - return "Main game file not found or could not be opened."; - case kMGFErr_SignatureFailed: - return "Not an AGS main game file or unsupported format."; - case kMGFErr_FormatVersionTooOld: - return "Format version is too old; this engine can only run games made with AGS 2.5 or later."; - case kMGFErr_FormatVersionNotSupported: - return "Format version not supported."; - case kMGFErr_CapsNotSupported: - return "The game requires extended capabilities which aren't supported by the engine."; - case kMGFErr_InvalidNativeResolution: - return "Unable to determine native game resolution."; - case kMGFErr_TooManySprites: - return "Too many sprites for this engine to handle."; - case kMGFErr_TooManyCursors: - return "Too many cursors for this engine to handle."; - case kMGFErr_InvalidPropertySchema: - return "Failed to deserialize custom properties schema."; - case kMGFErr_InvalidPropertyValues: - return "Errors encountered when reading custom properties."; - case kMGFErr_NoGlobalScript: - return "No global script in game."; - case kMGFErr_CreateGlobalScriptFailed: - return "Failed to load global script."; - case kMGFErr_CreateDialogScriptFailed: - return "Failed to load dialog script."; - case kMGFErr_CreateScriptModuleFailed: - return "Failed to load script module."; - case kMGFErr_GameEntityFailed: - return "Failed to load one or more game entities."; - case kMGFErr_PluginDataFmtNotSupported: - return "Format version of plugin data is not supported."; - case kMGFErr_PluginDataSizeTooLarge: - return "Plugin data size is too large."; - } - return "Unknown error."; +String GetMainGameFileErrorText(MainGameFileErrorType err) { + switch (err) { + case kMGFErr_NoError: + return "No error."; + case kMGFErr_FileOpenFailed: + return "Main game file not found or could not be opened."; + case kMGFErr_SignatureFailed: + return "Not an AGS main game file or unsupported format."; + case kMGFErr_FormatVersionTooOld: + return "Format version is too old; this engine can only run games made with AGS 2.5 or later."; + case kMGFErr_FormatVersionNotSupported: + return "Format version not supported."; + case kMGFErr_CapsNotSupported: + return "The game requires extended capabilities which aren't supported by the engine."; + case kMGFErr_InvalidNativeResolution: + return "Unable to determine native game resolution."; + case kMGFErr_TooManySprites: + return "Too many sprites for this engine to handle."; + case kMGFErr_TooManyCursors: + return "Too many cursors for this engine to handle."; + case kMGFErr_InvalidPropertySchema: + return "Failed to deserialize custom properties schema."; + case kMGFErr_InvalidPropertyValues: + return "Errors encountered when reading custom properties."; + case kMGFErr_NoGlobalScript: + return "No global script in game."; + case kMGFErr_CreateGlobalScriptFailed: + return "Failed to load global script."; + case kMGFErr_CreateDialogScriptFailed: + return "Failed to load dialog script."; + case kMGFErr_CreateScriptModuleFailed: + return "Failed to load script module."; + case kMGFErr_GameEntityFailed: + return "Failed to load one or more game entities."; + case kMGFErr_PluginDataFmtNotSupported: + return "Format version of plugin data is not supported."; + case kMGFErr_PluginDataSizeTooLarge: + return "Plugin data size is too large."; + } + return "Unknown error."; } LoadedGameEntities::LoadedGameEntities(GameSetupStruct &game, DialogTopic *&dialogs, ViewStruct *&views) - : Game(game) - , Dialogs(dialogs) - , Views(views) - , SpriteCount(0) -{ + : Game(game) + , Dialogs(dialogs) + , Views(views) + , SpriteCount(0) { } LoadedGameEntities::~LoadedGameEntities() = default; -bool IsMainGameLibrary(const String &filename) -{ - // We must not only detect if the given file is a correct AGS data library, - // we also have to assure that this library contains main game asset. - // Library may contain some optional data (digital audio, speech etc), but - // that is not what we want. - AssetLibInfo lib; - if (AssetManager::ReadDataFileTOC(filename, lib) != kAssetNoError) - return false; - for (size_t i = 0; i < lib.AssetInfos.size(); ++i) - { - if (lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v3) == 0 || - lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v2) == 0) - { - return true; - } - } - return false; +bool IsMainGameLibrary(const String &filename) { + // We must not only detect if the given file is a correct AGS data library, + // we also have to assure that this library contains main game asset. + // Library may contain some optional data (digital audio, speech etc), but + // that is not what we want. + AssetLibInfo lib; + if (AssetManager::ReadDataFileTOC(filename, lib) != kAssetNoError) + return false; + for (size_t i = 0; i < lib.AssetInfos.size(); ++i) { + if (lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v3) == 0 || + lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v2) == 0) { + return true; + } + } + return false; } // Begins reading main game file from a generic stream -HGameFileError OpenMainGameFileBase(PStream &in, MainGameSource &src) -{ - // Check data signature - String data_sig = String::FromStreamCount(in.get(), MainGameSource::Signature.GetLength()); - if (data_sig.Compare(MainGameSource::Signature)) - return new MainGameFileError(kMGFErr_SignatureFailed); - // Read data format version and requested engine version - src.DataVersion = (GameDataVersion)in->ReadInt32(); - if (src.DataVersion >= kGameVersion_230) - src.CompiledWith = StrUtil::ReadString(in.get()); - if (src.DataVersion < kGameVersion_250) - return new MainGameFileError(kMGFErr_FormatVersionTooOld, String::FromFormat("Required format version: %d, supported %d - %d", src.DataVersion, kGameVersion_250, kGameVersion_Current)); - if (src.DataVersion > kGameVersion_Current) - return new MainGameFileError(kMGFErr_FormatVersionNotSupported, - String::FromFormat("Game was compiled with %s. Required format version: %d, supported %d - %d", src.CompiledWith.GetCStr(), src.DataVersion, kGameVersion_250, kGameVersion_Current)); - // Read required capabilities - if (src.DataVersion >= kGameVersion_341) - { - size_t count = in->ReadInt32(); - for (size_t i = 0; i < count; ++i) - src.Caps.insert(StrUtil::ReadString(in.get())); - } - // Everything is fine, return opened stream - src.InputStream = in; - // Remember loaded game data version - // NOTE: this global variable is embedded in the code too much to get - // rid of it too easily; the easy way is to set it whenever the main - // game file is opened. - loaded_game_file_version = src.DataVersion; - return HGameFileError::None(); +HGameFileError OpenMainGameFileBase(PStream &in, MainGameSource &src) { + // Check data signature + String data_sig = String::FromStreamCount(in.get(), MainGameSource::Signature.GetLength()); + if (data_sig.Compare(MainGameSource::Signature)) + return new MainGameFileError(kMGFErr_SignatureFailed); + // Read data format version and requested engine version + src.DataVersion = (GameDataVersion)in->ReadInt32(); + if (src.DataVersion >= kGameVersion_230) + src.CompiledWith = StrUtil::ReadString(in.get()); + if (src.DataVersion < kGameVersion_250) + return new MainGameFileError(kMGFErr_FormatVersionTooOld, String::FromFormat("Required format version: %d, supported %d - %d", src.DataVersion, kGameVersion_250, kGameVersion_Current)); + if (src.DataVersion > kGameVersion_Current) + return new MainGameFileError(kMGFErr_FormatVersionNotSupported, + String::FromFormat("Game was compiled with %s. Required format version: %d, supported %d - %d", src.CompiledWith.GetCStr(), src.DataVersion, kGameVersion_250, kGameVersion_Current)); + // Read required capabilities + if (src.DataVersion >= kGameVersion_341) { + size_t count = in->ReadInt32(); + for (size_t i = 0; i < count; ++i) + src.Caps.insert(StrUtil::ReadString(in.get())); + } + // Everything is fine, return opened stream + src.InputStream = in; + // Remember loaded game data version + // NOTE: this global variable is embedded in the code too much to get + // rid of it too easily; the easy way is to set it whenever the main + // game file is opened. + loaded_game_file_version = src.DataVersion; + return HGameFileError::None(); } -HGameFileError OpenMainGameFile(const String &filename, MainGameSource &src) -{ - // Cleanup source struct - src = MainGameSource(); - // Try to open given file - PStream in(File::OpenFileRead(filename)); - if (!in) - return new MainGameFileError(kMGFErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); - src.Filename = filename; - return OpenMainGameFileBase(in, src); +HGameFileError OpenMainGameFile(const String &filename, MainGameSource &src) { + // Cleanup source struct + src = MainGameSource(); + // Try to open given file + PStream in(File::OpenFileRead(filename)); + if (!in) + return new MainGameFileError(kMGFErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); + src.Filename = filename; + return OpenMainGameFileBase(in, src); } -HGameFileError OpenMainGameFileFromDefaultAsset(MainGameSource &src) -{ - // Cleanup source struct - src = MainGameSource(); - // Try to find and open main game file - String filename = MainGameSource::DefaultFilename_v3; - PStream in(AssetManager::OpenAsset(filename)); - if (!in) - { - filename = MainGameSource::DefaultFilename_v2; - in = PStream(AssetManager::OpenAsset(filename)); - } - if (!in) - return new MainGameFileError(kMGFErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); - src.Filename = filename; - return OpenMainGameFileBase(in, src); +HGameFileError OpenMainGameFileFromDefaultAsset(MainGameSource &src) { + // Cleanup source struct + src = MainGameSource(); + // Try to find and open main game file + String filename = MainGameSource::DefaultFilename_v3; + PStream in(AssetManager::OpenAsset(filename)); + if (!in) { + filename = MainGameSource::DefaultFilename_v2; + in = PStream(AssetManager::OpenAsset(filename)); + } + if (!in) + return new MainGameFileError(kMGFErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); + src.Filename = filename; + return OpenMainGameFileBase(in, src); } -HGameFileError ReadDialogScript(PScript &dialog_script, Stream *in, GameDataVersion data_ver) -{ - if (data_ver > kGameVersion_310) // 3.1.1+ dialog script - { - dialog_script.reset(ccScript::CreateFromStream(in)); - if (dialog_script == nullptr) - return new MainGameFileError(kMGFErr_CreateDialogScriptFailed, ccErrorString); - } - else // 2.x and < 3.1.1 dialog - { - dialog_script.reset(); - } - return HGameFileError::None(); +HGameFileError ReadDialogScript(PScript &dialog_script, Stream *in, GameDataVersion data_ver) { + if (data_ver > kGameVersion_310) { // 3.1.1+ dialog script + dialog_script.reset(ccScript::CreateFromStream(in)); + if (dialog_script == nullptr) + return new MainGameFileError(kMGFErr_CreateDialogScriptFailed, ccErrorString); + } else { // 2.x and < 3.1.1 dialog + dialog_script.reset(); + } + return HGameFileError::None(); } -HGameFileError ReadScriptModules(std::vector &sc_mods, Stream *in, GameDataVersion data_ver) -{ - if (data_ver >= kGameVersion_270) // 2.7.0+ script modules - { - int count = in->ReadInt32(); - sc_mods.resize(count); - for (int i = 0; i < count; ++i) - { - sc_mods[i].reset(ccScript::CreateFromStream(in)); - if (sc_mods[i] == nullptr) - return new MainGameFileError(kMGFErr_CreateScriptModuleFailed, ccErrorString); - } - } - else - { - sc_mods.resize(0); - } - return HGameFileError::None(); +HGameFileError ReadScriptModules(std::vector &sc_mods, Stream *in, GameDataVersion data_ver) { + if (data_ver >= kGameVersion_270) { // 2.7.0+ script modules + int count = in->ReadInt32(); + sc_mods.resize(count); + for (int i = 0; i < count; ++i) { + sc_mods[i].reset(ccScript::CreateFromStream(in)); + if (sc_mods[i] == nullptr) + return new MainGameFileError(kMGFErr_CreateScriptModuleFailed, ccErrorString); + } + } else { + sc_mods.resize(0); + } + return HGameFileError::None(); } -void ReadViewStruct272_Aligned(std::vector &oldv, Stream *in, size_t count) -{ - AlignedStream align_s(in, Common::kAligned_Read); - oldv.resize(count); - for (size_t i = 0; i < count; ++i) - { - oldv[i].ReadFromFile(&align_s); - align_s.Reset(); - } +void ReadViewStruct272_Aligned(std::vector &oldv, Stream *in, size_t count) { + AlignedStream align_s(in, Common::kAligned_Read); + oldv.resize(count); + for (size_t i = 0; i < count; ++i) { + oldv[i].ReadFromFile(&align_s); + align_s.Reset(); + } } -void ReadViews(GameSetupStruct &game, ViewStruct *&views, Stream *in, GameDataVersion data_ver) -{ - int count = game.numviews; - views = (ViewStruct*)calloc(sizeof(ViewStruct) * count, 1); - if (data_ver > kGameVersion_272) // 3.x views - { - for (int i = 0; i < game.numviews; ++i) - { - views[i].ReadFromFile(in); - } - } - else // 2.x views - { - std::vector oldv; - ReadViewStruct272_Aligned(oldv, in, count); - Convert272ViewsToNew(oldv, views); - } +void ReadViews(GameSetupStruct &game, ViewStruct *&views, Stream *in, GameDataVersion data_ver) { + int count = game.numviews; + views = (ViewStruct *)calloc(sizeof(ViewStruct) * count, 1); + if (data_ver > kGameVersion_272) { // 3.x views + for (int i = 0; i < game.numviews; ++i) { + views[i].ReadFromFile(in); + } + } else { // 2.x views + std::vector oldv; + ReadViewStruct272_Aligned(oldv, in, count); + Convert272ViewsToNew(oldv, views); + } } void ReadDialogs(DialogTopic *&dialog, std::vector< std::shared_ptr > &old_dialog_scripts, std::vector &old_dialog_src, std::vector &old_speech_lines, - Stream *in, GameDataVersion data_ver, int dlg_count) -{ - // TODO: I suspect +5 was a hacky way to "supress" memory access mistakes; - // double check and remove if proved unnecessary - dialog = (DialogTopic*)malloc(sizeof(DialogTopic) * dlg_count + 5); - for (int i = 0; i < dlg_count; ++i) - { - dialog[i].ReadFromFile(in); - } - - if (data_ver > kGameVersion_310) - return; - - old_dialog_scripts.resize(dlg_count); - old_dialog_src.resize(dlg_count); - for (int i = 0; i < dlg_count; ++i) - { - // NOTE: originally this was read into dialog[i].optionscripts - old_dialog_scripts[i].reset(new unsigned char[dialog[i].codesize]); - in->Read(old_dialog_scripts[i].get(), dialog[i].codesize); - - // Encrypted text script - int script_text_len = in->ReadInt32(); - if (script_text_len > 1) - { - // Originally in the Editor +20000 bytes more were allocated, with comment: - // "add a large buffer because it will get added to if another option is added" - // which probably refered to this data used by old editor directly to edit dialogs - char *buffer = new char[script_text_len]; - in->Read(buffer, script_text_len); - if (data_ver > kGameVersion_260) - decrypt_text(buffer); - old_dialog_src[i] = buffer; - delete [] buffer; - } - else - { - in->Seek(script_text_len); - } - } - - // Read the dialog lines - // - // TODO: investigate this: these strings were read much simplier in the editor, see code: - /* - char stringbuffer[1000]; - for (bb=0;bb= 26) && (encrypted)) - read_string_decrypt(iii, stringbuffer); - else - fgetstring(stringbuffer, iii); - } - */ - int i = 0; - char buffer[1000]; - if (data_ver <= kGameVersion_260) - { - // Plain text on <= 2.60 - bool end_reached = false; - - while (!end_reached) - { - char* nextchar = buffer; - - while (1) - { - *nextchar = in->ReadInt8(); - if (*nextchar == 0) - break; - - if ((unsigned char)*nextchar == 0xEF) - { - end_reached = true; - in->Seek(-1); - break; - } - - nextchar++; - } - - if (end_reached) - break; - - old_speech_lines.push_back(buffer); - i++; - } - } - else - { - // Encrypted text on > 2.60 - while (1) - { - size_t newlen = in->ReadInt32(); - if (static_cast(newlen) == 0xCAFEBEEF) // GUI magic - { - in->Seek(-4); - break; - } - - newlen = Math::Min(newlen, sizeof(buffer) - 1); - in->Read(buffer, newlen); - buffer[newlen] = 0; - decrypt_text(buffer); - old_speech_lines.push_back(buffer); - i++; - } - } + Stream *in, GameDataVersion data_ver, int dlg_count) { + // TODO: I suspect +5 was a hacky way to "supress" memory access mistakes; + // double check and remove if proved unnecessary + dialog = (DialogTopic *)malloc(sizeof(DialogTopic) * dlg_count + 5); + for (int i = 0; i < dlg_count; ++i) { + dialog[i].ReadFromFile(in); + } + + if (data_ver > kGameVersion_310) + return; + + old_dialog_scripts.resize(dlg_count); + old_dialog_src.resize(dlg_count); + for (int i = 0; i < dlg_count; ++i) { + // NOTE: originally this was read into dialog[i].optionscripts + old_dialog_scripts[i].reset(new unsigned char[dialog[i].codesize]); + in->Read(old_dialog_scripts[i].get(), dialog[i].codesize); + + // Encrypted text script + int script_text_len = in->ReadInt32(); + if (script_text_len > 1) { + // Originally in the Editor +20000 bytes more were allocated, with comment: + // "add a large buffer because it will get added to if another option is added" + // which probably refered to this data used by old editor directly to edit dialogs + char *buffer = new char[script_text_len]; + in->Read(buffer, script_text_len); + if (data_ver > kGameVersion_260) + decrypt_text(buffer); + old_dialog_src[i] = buffer; + delete [] buffer; + } else { + in->Seek(script_text_len); + } + } + + // Read the dialog lines + // + // TODO: investigate this: these strings were read much simplier in the editor, see code: + /* + char stringbuffer[1000]; + for (bb=0;bb= 26) && (encrypted)) + read_string_decrypt(iii, stringbuffer); + else + fgetstring(stringbuffer, iii); + } + */ + int i = 0; + char buffer[1000]; + if (data_ver <= kGameVersion_260) { + // Plain text on <= 2.60 + bool end_reached = false; + + while (!end_reached) { + char *nextchar = buffer; + + while (1) { + *nextchar = in->ReadInt8(); + if (*nextchar == 0) + break; + + if ((unsigned char)*nextchar == 0xEF) { + end_reached = true; + in->Seek(-1); + break; + } + + nextchar++; + } + + if (end_reached) + break; + + old_speech_lines.push_back(buffer); + i++; + } + } else { + // Encrypted text on > 2.60 + while (1) { + size_t newlen = in->ReadInt32(); + if (static_cast(newlen) == 0xCAFEBEEF) { // GUI magic + in->Seek(-4); + break; + } + + newlen = Math::Min(newlen, sizeof(buffer) - 1); + in->Read(buffer, newlen); + buffer[newlen] = 0; + decrypt_text(buffer); + old_speech_lines.push_back(buffer); + i++; + } + } } -HGameFileError ReadPlugins(std::vector &infos, Stream *in) -{ - int fmt_ver = in->ReadInt32(); - if (fmt_ver != 1) - return new MainGameFileError(kMGFErr_PluginDataFmtNotSupported, String::FromFormat("Version: %d, supported: %d", fmt_ver, 1)); - - int pl_count = in->ReadInt32(); - for (int i = 0; i < pl_count; ++i) - { - String name = String::FromStream(in); - size_t datasize = in->ReadInt32(); - // just check for silly datasizes - if (datasize > PLUGIN_SAVEBUFFERSIZE) - return new MainGameFileError(kMGFErr_PluginDataSizeTooLarge, String::FromFormat("Required: %u, max: %u", datasize, PLUGIN_SAVEBUFFERSIZE)); - - PluginInfo info; - info.Name = name; - if (datasize > 0) - { - info.Data.reset(new char[datasize]); - in->Read(info.Data.get(), datasize); - } - info.DataLen = datasize; - infos.push_back(info); - } - return HGameFileError::None(); +HGameFileError ReadPlugins(std::vector &infos, Stream *in) { + int fmt_ver = in->ReadInt32(); + if (fmt_ver != 1) + return new MainGameFileError(kMGFErr_PluginDataFmtNotSupported, String::FromFormat("Version: %d, supported: %d", fmt_ver, 1)); + + int pl_count = in->ReadInt32(); + for (int i = 0; i < pl_count; ++i) { + String name = String::FromStream(in); + size_t datasize = in->ReadInt32(); + // just check for silly datasizes + if (datasize > PLUGIN_SAVEBUFFERSIZE) + return new MainGameFileError(kMGFErr_PluginDataSizeTooLarge, String::FromFormat("Required: %u, max: %u", datasize, PLUGIN_SAVEBUFFERSIZE)); + + PluginInfo info; + info.Name = name; + if (datasize > 0) { + info.Data.reset(new char[datasize]); + in->Read(info.Data.get(), datasize); + } + info.DataLen = datasize; + infos.push_back(info); + } + return HGameFileError::None(); } // Create the missing audioClips data structure for 3.1.x games. // This is done by going through the data files and adding all music*.* // and sound*.* files to it. -void BuildAudioClipArray(const std::vector &assets, std::vector &audioclips) -{ - char temp_name[30]; - int temp_number; - char temp_extension[10]; - - for (const String &asset : assets) - { - if (sscanf(asset.GetCStr(), "%5s%d.%3s", temp_name, &temp_number, temp_extension) != 3) - continue; - - ScriptAudioClip clip; - if (ags_stricmp(temp_extension, "mp3") == 0) - clip.fileType = eAudioFileMP3; - else if (ags_stricmp(temp_extension, "wav") == 0) - clip.fileType = eAudioFileWAV; - else if (ags_stricmp(temp_extension, "voc") == 0) - clip.fileType = eAudioFileVOC; - else if (ags_stricmp(temp_extension, "mid") == 0) - clip.fileType = eAudioFileMIDI; - else if ((ags_stricmp(temp_extension, "mod") == 0) || (ags_stricmp(temp_extension, "xm") == 0) - || (ags_stricmp(temp_extension, "s3m") == 0) || (ags_stricmp(temp_extension, "it") == 0)) - clip.fileType = eAudioFileMOD; - else if (ags_stricmp(temp_extension, "ogg") == 0) - clip.fileType = eAudioFileOGG; - else - continue; - - if (ags_stricmp(temp_name, "music") == 0) - { - clip.scriptName.Format("aMusic%d", temp_number); - clip.fileName.Format("music%d.%s", temp_number, temp_extension); - clip.bundlingType = (ags_stricmp(temp_extension, "mid") == 0) ? AUCL_BUNDLE_EXE : AUCL_BUNDLE_VOX; - clip.type = 2; - clip.defaultRepeat = 1; - } - else if (ags_stricmp(temp_name, "sound") == 0) - { - clip.scriptName.Format("aSound%d", temp_number); - clip.fileName.Format("sound%d.%s", temp_number, temp_extension); - clip.bundlingType = AUCL_BUNDLE_EXE; - clip.type = 3; - clip.defaultRepeat = 0; - } - else - { - continue; - } - - clip.defaultVolume = 100; - clip.defaultPriority = 50; - clip.id = audioclips.size(); - audioclips.push_back(clip); - } +void BuildAudioClipArray(const std::vector &assets, std::vector &audioclips) { + char temp_name[30]; + int temp_number; + char temp_extension[10]; + + for (const String &asset : assets) { + if (sscanf(asset.GetCStr(), "%5s%d.%3s", temp_name, &temp_number, temp_extension) != 3) + continue; + + ScriptAudioClip clip; + if (ags_stricmp(temp_extension, "mp3") == 0) + clip.fileType = eAudioFileMP3; + else if (ags_stricmp(temp_extension, "wav") == 0) + clip.fileType = eAudioFileWAV; + else if (ags_stricmp(temp_extension, "voc") == 0) + clip.fileType = eAudioFileVOC; + else if (ags_stricmp(temp_extension, "mid") == 0) + clip.fileType = eAudioFileMIDI; + else if ((ags_stricmp(temp_extension, "mod") == 0) || (ags_stricmp(temp_extension, "xm") == 0) + || (ags_stricmp(temp_extension, "s3m") == 0) || (ags_stricmp(temp_extension, "it") == 0)) + clip.fileType = eAudioFileMOD; + else if (ags_stricmp(temp_extension, "ogg") == 0) + clip.fileType = eAudioFileOGG; + else + continue; + + if (ags_stricmp(temp_name, "music") == 0) { + clip.scriptName.Format("aMusic%d", temp_number); + clip.fileName.Format("music%d.%s", temp_number, temp_extension); + clip.bundlingType = (ags_stricmp(temp_extension, "mid") == 0) ? AUCL_BUNDLE_EXE : AUCL_BUNDLE_VOX; + clip.type = 2; + clip.defaultRepeat = 1; + } else if (ags_stricmp(temp_name, "sound") == 0) { + clip.scriptName.Format("aSound%d", temp_number); + clip.fileName.Format("sound%d.%s", temp_number, temp_extension); + clip.bundlingType = AUCL_BUNDLE_EXE; + clip.type = 3; + clip.defaultRepeat = 0; + } else { + continue; + } + + clip.defaultVolume = 100; + clip.defaultPriority = 50; + clip.id = audioclips.size(); + audioclips.push_back(clip); + } } -void ApplySpriteData(GameSetupStruct &game, const LoadedGameEntities &ents, GameDataVersion data_ver) -{ - // Apply sprite flags read from original format (sequential array) - spriteset.EnlargeTo(ents.SpriteCount - 1); - for (size_t i = 0; i < ents.SpriteCount; ++i) - { - game.SpriteInfos[i].Flags = ents.SpriteFlags[i]; - } - - // Promote sprite resolutions and mark legacy resolution setting - if (data_ver < kGameVersion_350) - { - for (size_t i = 0; i < ents.SpriteCount; ++i) - { - SpriteInfo &info = game.SpriteInfos[i]; - if (game.IsLegacyHiRes() == info.IsLegacyHiRes()) - info.Flags &= ~(SPF_HIRES | SPF_VAR_RESOLUTION); - else - info.Flags |= SPF_VAR_RESOLUTION; - } - } +void ApplySpriteData(GameSetupStruct &game, const LoadedGameEntities &ents, GameDataVersion data_ver) { + // Apply sprite flags read from original format (sequential array) + spriteset.EnlargeTo(ents.SpriteCount - 1); + for (size_t i = 0; i < ents.SpriteCount; ++i) { + game.SpriteInfos[i].Flags = ents.SpriteFlags[i]; + } + + // Promote sprite resolutions and mark legacy resolution setting + if (data_ver < kGameVersion_350) { + for (size_t i = 0; i < ents.SpriteCount; ++i) { + SpriteInfo &info = game.SpriteInfos[i]; + if (game.IsLegacyHiRes() == info.IsLegacyHiRes()) + info.Flags &= ~(SPF_HIRES | SPF_VAR_RESOLUTION); + else + info.Flags |= SPF_VAR_RESOLUTION; + } + } } -void UpgradeFonts(GameSetupStruct &game, GameDataVersion data_ver) -{ - if (data_ver < kGameVersion_350) - { - for (int i = 0; i < game.numfonts; ++i) - { - FontInfo &finfo = game.fonts[i]; - // If the game is hi-res but font is designed for low-res, then scale it up - if (game.IsLegacyHiRes() && game.options[OPT_HIRES_FONTS] == 0) - { - finfo.SizeMultiplier = HIRES_COORD_MULTIPLIER; - } - else - { - finfo.SizeMultiplier = 1; - } - } - } - if (data_ver < kGameVersion_351) - { - for (size_t font = 0; font < game.numfonts; font++) - { - FontInfo &finfo = game.fonts[font]; - // Thickness that corresponds to 1 game pixel - finfo.AutoOutlineThickness = - // if it's a scaled up bitmap font, move the outline out more - (is_bitmap_font(font) && get_font_scaling_mul(font) > 1) ? - get_fixed_pixel_size(1) : 1; - finfo.AutoOutlineStyle = FontInfo::kSquared; - } - } +void UpgradeFonts(GameSetupStruct &game, GameDataVersion data_ver) { + if (data_ver < kGameVersion_350) { + for (int i = 0; i < game.numfonts; ++i) { + FontInfo &finfo = game.fonts[i]; + // If the game is hi-res but font is designed for low-res, then scale it up + if (game.IsLegacyHiRes() && game.options[OPT_HIRES_FONTS] == 0) { + finfo.SizeMultiplier = HIRES_COORD_MULTIPLIER; + } else { + finfo.SizeMultiplier = 1; + } + } + } + if (data_ver < kGameVersion_351) { + for (size_t font = 0; font < game.numfonts; font++) { + FontInfo &finfo = game.fonts[font]; + // Thickness that corresponds to 1 game pixel + finfo.AutoOutlineThickness = + // if it's a scaled up bitmap font, move the outline out more + (is_bitmap_font(font) && get_font_scaling_mul(font) > 1) ? + get_fixed_pixel_size(1) : 1; + finfo.AutoOutlineStyle = FontInfo::kSquared; + } + } } // Convert audio data to the current version -void UpgradeAudio(GameSetupStruct &game, GameDataVersion data_ver) -{ - if (data_ver >= kGameVersion_320) - return; - - // An explanation of building audio clips array for pre-3.2 games. - // - // When AGS version 3.2 was released, it contained new audio system. - // In the nutshell, prior to 3.2 audio files had to be manually put - // to game project directory and their IDs were taken out of filenames. - // Since 3.2 this information is stored inside the game data. - // To make the modern engine compatible with pre-3.2 games, we have - // to scan game data packages for audio files, and enumerate them - // ourselves, then add this information to game struct. - - // Create soundClips and audioClipTypes structures. - std::vector audiocliptypes; - std::vector audioclips; - - // TODO: find out what is 4 (maybe music, sound, ambient sound, voice?) - audiocliptypes.resize(4); - for (int i = 0; i < 4; i++) - { - audiocliptypes[i].reservedChannels = 1; - audiocliptypes[i].id = i; - audiocliptypes[i].volume_reduction_while_speech_playing = 10; - } - audiocliptypes[3].reservedChannels = 0; - - audioclips.reserve(1000); - // Read audio clip names from "music.vox", then from main library - // TODO: this may become inconvenient that this code has to know about - // "music.vox"; there might be better ways to handle this. - // possibly making AssetManager download several libraries at once will - // resolve this (as well as make it unnecessary to switch between them) - std::vector assets; - // Append contents of "music.vox" - AssetLibInfo music_lib; - if (AssetManager::ReadDataFileTOC("music.vox", music_lib) == kAssetNoError) - { - for (const AssetInfo &info : music_lib.AssetInfos) - { - if (info.FileName.CompareLeftNoCase("music", 5) == 0 || info.FileName.CompareLeftNoCase("sound", 5) == 0) - assets.push_back(info.FileName); - } - } - // Append contents of the main game file - const AssetLibInfo *game_lib = AssetManager::GetLibraryTOC(); - if (game_lib) - { - for (const AssetInfo &info : game_lib->AssetInfos) - { - if (info.FileName.CompareLeftNoCase("music", 5) == 0 || info.FileName.CompareLeftNoCase("sound", 5) == 0) - assets.push_back(info.FileName); - } - } - // Append contents of the game directory - // TODO: use explicit path instead of cwd? keep this consistent with AssetManager! - { - al_ffblk ff; - if (al_findfirst("*.*", &ff, FA_ALL & ~(FA_DIREC)) == 0) - { - do - { - if (ags_strnicmp(ff.name, "music", 5) == 0 || ags_strnicmp(ff.name, "sound", 5) == 0) - assets.push_back(ff.name); - } - while (al_findnext(&ff) == 0); - al_findclose(&ff); - } - } - BuildAudioClipArray(assets, audioclips); - - // Copy gathered data over to game - game.audioClipTypes = audiocliptypes; - game.audioClips = audioclips; - - // Setup sound clip played on score event - game.scoreClipID = -1; +void UpgradeAudio(GameSetupStruct &game, GameDataVersion data_ver) { + if (data_ver >= kGameVersion_320) + return; + + // An explanation of building audio clips array for pre-3.2 games. + // + // When AGS version 3.2 was released, it contained new audio system. + // In the nutshell, prior to 3.2 audio files had to be manually put + // to game project directory and their IDs were taken out of filenames. + // Since 3.2 this information is stored inside the game data. + // To make the modern engine compatible with pre-3.2 games, we have + // to scan game data packages for audio files, and enumerate them + // ourselves, then add this information to game struct. + + // Create soundClips and audioClipTypes structures. + std::vector audiocliptypes; + std::vector audioclips; + + // TODO: find out what is 4 (maybe music, sound, ambient sound, voice?) + audiocliptypes.resize(4); + for (int i = 0; i < 4; i++) { + audiocliptypes[i].reservedChannels = 1; + audiocliptypes[i].id = i; + audiocliptypes[i].volume_reduction_while_speech_playing = 10; + } + audiocliptypes[3].reservedChannels = 0; + + audioclips.reserve(1000); + // Read audio clip names from "music.vox", then from main library + // TODO: this may become inconvenient that this code has to know about + // "music.vox"; there might be better ways to handle this. + // possibly making AssetManager download several libraries at once will + // resolve this (as well as make it unnecessary to switch between them) + std::vector assets; + // Append contents of "music.vox" + AssetLibInfo music_lib; + if (AssetManager::ReadDataFileTOC("music.vox", music_lib) == kAssetNoError) { + for (const AssetInfo &info : music_lib.AssetInfos) { + if (info.FileName.CompareLeftNoCase("music", 5) == 0 || info.FileName.CompareLeftNoCase("sound", 5) == 0) + assets.push_back(info.FileName); + } + } + // Append contents of the main game file + const AssetLibInfo *game_lib = AssetManager::GetLibraryTOC(); + if (game_lib) { + for (const AssetInfo &info : game_lib->AssetInfos) { + if (info.FileName.CompareLeftNoCase("music", 5) == 0 || info.FileName.CompareLeftNoCase("sound", 5) == 0) + assets.push_back(info.FileName); + } + } + // Append contents of the game directory + // TODO: use explicit path instead of cwd? keep this consistent with AssetManager! + { + al_ffblk ff; + if (al_findfirst("*.*", &ff, FA_ALL & ~(FA_DIREC)) == 0) { + do { + if (ags_strnicmp(ff.name, "music", 5) == 0 || ags_strnicmp(ff.name, "sound", 5) == 0) + assets.push_back(ff.name); + } while (al_findnext(&ff) == 0); + al_findclose(&ff); + } + } + BuildAudioClipArray(assets, audioclips); + + // Copy gathered data over to game + game.audioClipTypes = audiocliptypes; + game.audioClips = audioclips; + + // Setup sound clip played on score event + game.scoreClipID = -1; } // Convert character data to the current version -void UpgradeCharacters(GameSetupStruct &game, GameDataVersion data_ver) -{ - // TODO: this was done to simplify code transition; ideally we should be - // working with GameSetupStruct's getters and setters here - CharacterInfo *&chars = game.chars; - const int numcharacters = game.numcharacters; - - // Fixup charakter script names for 2.x (EGO -> cEgo) - if (data_ver <= kGameVersion_272) - { - String tempbuffer; - for (int i = 0; i < numcharacters; i++) - { - if (chars[i].scrname[0] == 0) - continue; - tempbuffer.Format("c%c%s", chars[i].scrname[0], ags_strlwr(&chars[i].scrname[1])); - snprintf(chars[i].scrname, MAX_SCRIPT_NAME_LEN, "%s", tempbuffer.GetCStr()); - } - } - - // Fix character walk speed for < 3.1.1 - if (data_ver <= kGameVersion_310) - { - for (int i = 0; i < numcharacters; i++) - { - if (game.options[OPT_ANTIGLIDE]) - chars[i].flags |= CHF_ANTIGLIDE; - } - } - - // Characters can always walk through each other on < 2.54 - if (data_ver < kGameVersion_254) - { - for (int i = 0; i < numcharacters; i++) - { - chars[i].flags |= CHF_NOBLOCKING; - } - } +void UpgradeCharacters(GameSetupStruct &game, GameDataVersion data_ver) { + // TODO: this was done to simplify code transition; ideally we should be + // working with GameSetupStruct's getters and setters here + CharacterInfo *&chars = game.chars; + const int numcharacters = game.numcharacters; + + // Fixup charakter script names for 2.x (EGO -> cEgo) + if (data_ver <= kGameVersion_272) { + String tempbuffer; + for (int i = 0; i < numcharacters; i++) { + if (chars[i].scrname[0] == 0) + continue; + tempbuffer.Format("c%c%s", chars[i].scrname[0], ags_strlwr(&chars[i].scrname[1])); + snprintf(chars[i].scrname, MAX_SCRIPT_NAME_LEN, "%s", tempbuffer.GetCStr()); + } + } + + // Fix character walk speed for < 3.1.1 + if (data_ver <= kGameVersion_310) { + for (int i = 0; i < numcharacters; i++) { + if (game.options[OPT_ANTIGLIDE]) + chars[i].flags |= CHF_ANTIGLIDE; + } + } + + // Characters can always walk through each other on < 2.54 + if (data_ver < kGameVersion_254) { + for (int i = 0; i < numcharacters; i++) { + chars[i].flags |= CHF_NOBLOCKING; + } + } } -void UpgradeMouseCursors(GameSetupStruct &game, GameDataVersion data_ver) -{ - if (data_ver <= kGameVersion_272) - { - // Change cursor.view from 0 to -1 for non-animating cursors. - for (int i = 0; i < game.numcursors; ++i) - { - if (game.mcurs[i].view == 0) - game.mcurs[i].view = -1; - } - } +void UpgradeMouseCursors(GameSetupStruct &game, GameDataVersion data_ver) { + if (data_ver <= kGameVersion_272) { + // Change cursor.view from 0 to -1 for non-animating cursors. + for (int i = 0; i < game.numcursors; ++i) { + if (game.mcurs[i].view == 0) + game.mcurs[i].view = -1; + } + } } // Adjusts score clip id, depending on game data version -void AdjustScoreSound(GameSetupStruct &game, GameDataVersion data_ver) -{ - if (data_ver < kGameVersion_320) - { - game.scoreClipID = -1; - if (game.options[OPT_SCORESOUND] > 0) - { - ScriptAudioClip* clip = GetAudioClipForOldStyleNumber(game, false, game.options[OPT_SCORESOUND]); - if (clip) - game.scoreClipID = clip->id; - else - game.scoreClipID = -1; - } - } +void AdjustScoreSound(GameSetupStruct &game, GameDataVersion data_ver) { + if (data_ver < kGameVersion_320) { + game.scoreClipID = -1; + if (game.options[OPT_SCORESOUND] > 0) { + ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(game, false, game.options[OPT_SCORESOUND]); + if (clip) + game.scoreClipID = clip->id; + else + game.scoreClipID = -1; + } + } } // Assigns default global message at given index -void SetDefaultGlmsg(GameSetupStruct &game, int msgnum, const char *val) -{ - // TODO: find out why the index should be lowered by 500 - // (or rather if we may pass correct index right away) - msgnum -= 500; - if (game.messages[msgnum] == nullptr) - game.messages[msgnum] = ags_strdup(val); +void SetDefaultGlmsg(GameSetupStruct &game, int msgnum, const char *val) { + // TODO: find out why the index should be lowered by 500 + // (or rather if we may pass correct index right away) + msgnum -= 500; + if (game.messages[msgnum] == nullptr) + game.messages[msgnum] = ags_strdup(val); } // Sets up default global messages (these are used mainly in older games) -void SetDefaultGlobalMessages(GameSetupStruct &game) -{ - SetDefaultGlmsg(game, 983, "Sorry, not now."); - SetDefaultGlmsg(game, 984, "Restore"); - SetDefaultGlmsg(game, 985, "Cancel"); - SetDefaultGlmsg(game, 986, "Select a game to restore:"); - SetDefaultGlmsg(game, 987, "Save"); - SetDefaultGlmsg(game, 988, "Type a name to save as:"); - SetDefaultGlmsg(game, 989, "Replace"); - SetDefaultGlmsg(game, 990, "The save directory is full. You must replace an existing game:"); - SetDefaultGlmsg(game, 991, "Replace:"); - SetDefaultGlmsg(game, 992, "With:"); - SetDefaultGlmsg(game, 993, "Quit"); - SetDefaultGlmsg(game, 994, "Play"); - SetDefaultGlmsg(game, 995, "Are you sure you want to quit?"); - SetDefaultGlmsg(game, 996, "You are carrying nothing."); +void SetDefaultGlobalMessages(GameSetupStruct &game) { + SetDefaultGlmsg(game, 983, "Sorry, not now."); + SetDefaultGlmsg(game, 984, "Restore"); + SetDefaultGlmsg(game, 985, "Cancel"); + SetDefaultGlmsg(game, 986, "Select a game to restore:"); + SetDefaultGlmsg(game, 987, "Save"); + SetDefaultGlmsg(game, 988, "Type a name to save as:"); + SetDefaultGlmsg(game, 989, "Replace"); + SetDefaultGlmsg(game, 990, "The save directory is full. You must replace an existing game:"); + SetDefaultGlmsg(game, 991, "Replace:"); + SetDefaultGlmsg(game, 992, "With:"); + SetDefaultGlmsg(game, 993, "Quit"); + SetDefaultGlmsg(game, 994, "Play"); + SetDefaultGlmsg(game, 995, "Are you sure you want to quit?"); + SetDefaultGlmsg(game, 996, "You are carrying nothing."); } -void FixupSaveDirectory(GameSetupStruct &game) -{ - // If the save game folder was not specified by game author, create one of - // the game name, game GUID, or uniqueid, as a last resort - if (!game.saveGameFolderName[0]) - { - if (game.gamename[0]) - snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", game.gamename); - else if (game.guid[0]) - snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", game.guid); - else - snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "AGS-Game-%d", game.uniqueid); - } - // Lastly, fixup folder name by removing any illegal characters - String s = Path::FixupSharedFilename(game.saveGameFolderName); - snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", s.GetCStr()); +void FixupSaveDirectory(GameSetupStruct &game) { + // If the save game folder was not specified by game author, create one of + // the game name, game GUID, or uniqueid, as a last resort + if (!game.saveGameFolderName[0]) { + if (game.gamename[0]) + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", game.gamename); + else if (game.guid[0]) + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", game.guid); + else + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "AGS-Game-%d", game.uniqueid); + } + // Lastly, fixup folder name by removing any illegal characters + String s = Path::FixupSharedFilename(game.saveGameFolderName); + snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", s.GetCStr()); } -HGameFileError ReadSpriteFlags(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver) -{ - uint32_t sprcount; - if (data_ver < kGameVersion_256) - sprcount = LEGACY_MAX_SPRITES_V25; - else - sprcount = in->ReadInt32(); - if (sprcount > (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1) - return new MainGameFileError(kMGFErr_TooManySprites, String::FromFormat("Count: %u, max: %u", sprcount, (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1)); - - ents.SpriteCount = sprcount; - ents.SpriteFlags.reset(new char[sprcount]); - in->Read(ents.SpriteFlags.get(), sprcount); - return HGameFileError::None(); +HGameFileError ReadSpriteFlags(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver) { + uint32_t sprcount; + if (data_ver < kGameVersion_256) + sprcount = LEGACY_MAX_SPRITES_V25; + else + sprcount = in->ReadInt32(); + if (sprcount > (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1) + return new MainGameFileError(kMGFErr_TooManySprites, String::FromFormat("Count: %u, max: %u", sprcount, (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1)); + + ents.SpriteCount = sprcount; + ents.SpriteFlags.reset(new char[sprcount]); + in->Read(ents.SpriteFlags.get(), sprcount); + return HGameFileError::None(); } -HGameFileError ReadGameData(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver) -{ - GameSetupStruct &game = ents.Game; - - { - AlignedStream align_s(in, Common::kAligned_Read); - game.GameSetupStructBase::ReadFromFile(&align_s); - } - - if (game.GetGameRes().IsNull()) - return new MainGameFileError(kMGFErr_InvalidNativeResolution); - - game.read_savegame_info(in, data_ver); - game.read_font_infos(in, data_ver); - HGameFileError err = ReadSpriteFlags(ents, in, data_ver); - if (!err) - return err; - game.ReadInvInfo_Aligned(in); - err = game.read_cursors(in, data_ver); - if (!err) - return err; - game.read_interaction_scripts(in, data_ver); - game.read_words_dictionary(in); - - if (!game.load_compiled_script) - return new MainGameFileError(kMGFErr_NoGlobalScript); - ents.GlobalScript.reset(ccScript::CreateFromStream(in)); - if (!ents.GlobalScript) - return new MainGameFileError(kMGFErr_CreateGlobalScriptFailed, ccErrorString); - err = ReadDialogScript(ents.DialogScript, in, data_ver); - if (!err) - return err; - err = ReadScriptModules(ents.ScriptModules, in, data_ver); - if (!err) - return err; - - ReadViews(game, ents.Views, in, data_ver); - - if (data_ver <= kGameVersion_251) - { - // skip unknown data - int count = in->ReadInt32(); - in->Seek(count * 0x204); - } - - game.read_characters(in, data_ver); - game.read_lipsync(in, data_ver); - game.read_messages(in, data_ver); - - ReadDialogs(ents.Dialogs, ents.OldDialogScripts, ents.OldDialogSources, ents.OldSpeechLines, - in, data_ver, game.numdialog); - HError err2 = GUI::ReadGUI(guis, in); - if (!err2) - return new MainGameFileError(kMGFErr_GameEntityFailed, err2); - game.numgui = guis.size(); - - if (data_ver >= kGameVersion_260) - { - err = ReadPlugins(ents.PluginInfos, in); - if (!err) - return err; - } - - err = game.read_customprops(in, data_ver); - if (!err) - return err; - err = game.read_audio(in, data_ver); - if (!err) - return err; - game.read_room_names(in, data_ver); - return err; +HGameFileError ReadGameData(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver) { + GameSetupStruct &game = ents.Game; + + { + AlignedStream align_s(in, Common::kAligned_Read); + game.GameSetupStructBase::ReadFromFile(&align_s); + } + + if (game.GetGameRes().IsNull()) + return new MainGameFileError(kMGFErr_InvalidNativeResolution); + + game.read_savegame_info(in, data_ver); + game.read_font_infos(in, data_ver); + HGameFileError err = ReadSpriteFlags(ents, in, data_ver); + if (!err) + return err; + game.ReadInvInfo_Aligned(in); + err = game.read_cursors(in, data_ver); + if (!err) + return err; + game.read_interaction_scripts(in, data_ver); + game.read_words_dictionary(in); + + if (!game.load_compiled_script) + return new MainGameFileError(kMGFErr_NoGlobalScript); + ents.GlobalScript.reset(ccScript::CreateFromStream(in)); + if (!ents.GlobalScript) + return new MainGameFileError(kMGFErr_CreateGlobalScriptFailed, ccErrorString); + err = ReadDialogScript(ents.DialogScript, in, data_ver); + if (!err) + return err; + err = ReadScriptModules(ents.ScriptModules, in, data_ver); + if (!err) + return err; + + ReadViews(game, ents.Views, in, data_ver); + + if (data_ver <= kGameVersion_251) { + // skip unknown data + int count = in->ReadInt32(); + in->Seek(count * 0x204); + } + + game.read_characters(in, data_ver); + game.read_lipsync(in, data_ver); + game.read_messages(in, data_ver); + + ReadDialogs(ents.Dialogs, ents.OldDialogScripts, ents.OldDialogSources, ents.OldSpeechLines, + in, data_ver, game.numdialog); + HError err2 = GUI::ReadGUI(guis, in); + if (!err2) + return new MainGameFileError(kMGFErr_GameEntityFailed, err2); + game.numgui = guis.size(); + + if (data_ver >= kGameVersion_260) { + err = ReadPlugins(ents.PluginInfos, in); + if (!err) + return err; + } + + err = game.read_customprops(in, data_ver); + if (!err) + return err; + err = game.read_audio(in, data_ver); + if (!err) + return err; + game.read_room_names(in, data_ver); + return err; } -HGameFileError UpdateGameData(LoadedGameEntities &ents, GameDataVersion data_ver) -{ - GameSetupStruct &game = ents.Game; - ApplySpriteData(game, ents, data_ver); - UpgradeFonts(game, data_ver); - UpgradeAudio(game, data_ver); - AdjustScoreSound(game, data_ver); - UpgradeCharacters(game, data_ver); - UpgradeMouseCursors(game, data_ver); - SetDefaultGlobalMessages(game); - // Global talking animation speed - if (data_ver < kGameVersion_312) - { - // Fix animation speed for old formats - game.options[OPT_GLOBALTALKANIMSPD] = 5; - } - else if (data_ver < kGameVersion_330) - { - // Convert game option for 3.1.2 - 3.2 games - game.options[OPT_GLOBALTALKANIMSPD] = game.options[OPT_GLOBALTALKANIMSPD] != 0 ? 5 : (-5 - 1); - } - // Old dialog options API for pre-3.4.0.2 games - if (data_ver < kGameVersion_340_2) - { - game.options[OPT_DIALOGOPTIONSAPI] = -1; - } - // Relative asset resolution in pre-3.5.0.8 (always enabled) - if (data_ver < kGameVersion_350) - { - game.options[OPT_RELATIVEASSETRES] = 1; - } - FixupSaveDirectory(game); - return HGameFileError::None(); +HGameFileError UpdateGameData(LoadedGameEntities &ents, GameDataVersion data_ver) { + GameSetupStruct &game = ents.Game; + ApplySpriteData(game, ents, data_ver); + UpgradeFonts(game, data_ver); + UpgradeAudio(game, data_ver); + AdjustScoreSound(game, data_ver); + UpgradeCharacters(game, data_ver); + UpgradeMouseCursors(game, data_ver); + SetDefaultGlobalMessages(game); + // Global talking animation speed + if (data_ver < kGameVersion_312) { + // Fix animation speed for old formats + game.options[OPT_GLOBALTALKANIMSPD] = 5; + } else if (data_ver < kGameVersion_330) { + // Convert game option for 3.1.2 - 3.2 games + game.options[OPT_GLOBALTALKANIMSPD] = game.options[OPT_GLOBALTALKANIMSPD] != 0 ? 5 : (-5 - 1); + } + // Old dialog options API for pre-3.4.0.2 games + if (data_ver < kGameVersion_340_2) { + game.options[OPT_DIALOGOPTIONSAPI] = -1; + } + // Relative asset resolution in pre-3.5.0.8 (always enabled) + if (data_ver < kGameVersion_350) { + game.options[OPT_RELATIVEASSETRES] = 1; + } + FixupSaveDirectory(game); + return HGameFileError::None(); } } // namespace Common diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 2ed4f483d4c5..31eb11a56833 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -46,33 +46,30 @@ struct GameSetupStruct; struct DialogTopic; struct ViewStruct; -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // Error codes for main game file reading -enum MainGameFileErrorType -{ - kMGFErr_NoError, - kMGFErr_FileOpenFailed, - kMGFErr_SignatureFailed, - // separate error given for "too old" format to provide clarifying message - kMGFErr_FormatVersionTooOld, - kMGFErr_FormatVersionNotSupported, - kMGFErr_CapsNotSupported, - kMGFErr_InvalidNativeResolution, - kMGFErr_TooManySprites, - kMGFErr_TooManyCursors, - kMGFErr_InvalidPropertySchema, - kMGFErr_InvalidPropertyValues, - kMGFErr_NoGlobalScript, - kMGFErr_CreateGlobalScriptFailed, - kMGFErr_CreateDialogScriptFailed, - kMGFErr_CreateScriptModuleFailed, - kMGFErr_GameEntityFailed, - kMGFErr_PluginDataFmtNotSupported, - kMGFErr_PluginDataSizeTooLarge +enum MainGameFileErrorType { + kMGFErr_NoError, + kMGFErr_FileOpenFailed, + kMGFErr_SignatureFailed, + // separate error given for "too old" format to provide clarifying message + kMGFErr_FormatVersionTooOld, + kMGFErr_FormatVersionNotSupported, + kMGFErr_CapsNotSupported, + kMGFErr_InvalidNativeResolution, + kMGFErr_TooManySprites, + kMGFErr_TooManyCursors, + kMGFErr_InvalidPropertySchema, + kMGFErr_InvalidPropertyValues, + kMGFErr_NoGlobalScript, + kMGFErr_CreateGlobalScriptFailed, + kMGFErr_CreateDialogScriptFailed, + kMGFErr_CreateScriptModuleFailed, + kMGFErr_GameEntityFailed, + kMGFErr_PluginDataFmtNotSupported, + kMGFErr_PluginDataSizeTooLarge }; String GetMainGameFileErrorText(MainGameFileErrorType err); @@ -82,27 +79,26 @@ typedef ErrorHandle HGameFileError; typedef std::shared_ptr PStream; // MainGameSource defines a successfully opened main game file -struct MainGameSource -{ - // Standart main game file names for 3.* and 2.* games respectively - static const String DefaultFilename_v3; - static const String DefaultFilename_v2; - // Signature of the current game format - static const String Signature; - - // Name of the asset file - String Filename; - // Game file format version - GameDataVersion DataVersion; - // Tool identifier (like version) this game was compiled with - String CompiledWith; - // Extended engine capabilities required by the game; their primary use - // currently is to let "alternate" game formats indicate themselves - std::set Caps; - // A ponter to the opened stream - PStream InputStream; - - MainGameSource(); +struct MainGameSource { + // Standart main game file names for 3.* and 2.* games respectively + static const String DefaultFilename_v3; + static const String DefaultFilename_v2; + // Signature of the current game format + static const String Signature; + + // Name of the asset file + String Filename; + // Game file format version + GameDataVersion DataVersion; + // Tool identifier (like version) this game was compiled with + String CompiledWith; + // Extended engine capabilities required by the game; their primary use + // currently is to let "alternate" game formats indicate themselves + std::set Caps; + // A ponter to the opened stream + PStream InputStream; + + MainGameSource(); }; // LoadedGameEntities is meant for keeping objects loaded from the game file. @@ -110,31 +106,30 @@ struct MainGameSource // of these objects yet, they have to be attached using references to be read // directly. This is temporary solution that has to be resolved by the future // code refactoring. -struct LoadedGameEntities -{ - GameSetupStruct &Game; - DialogTopic *&Dialogs; - ViewStruct *&Views; - PScript GlobalScript; - PScript DialogScript; - std::vector ScriptModules; - std::vector PluginInfos; - - // Original sprite data (when it was read into const-sized arrays) - size_t SpriteCount; - std::unique_ptr SpriteFlags; - - // Old dialog support - // legacy compiled dialog script of its own format, - // requires separate interpreting - std::vector< std::shared_ptr > OldDialogScripts; - // probably, actual dialog script sources kept within some older games - std::vector OldDialogSources; - // speech texts displayed during dialog - std::vector OldSpeechLines; - - LoadedGameEntities(GameSetupStruct &game, DialogTopic *&dialogs, ViewStruct *&views); - ~LoadedGameEntities(); +struct LoadedGameEntities { + GameSetupStruct &Game; + DialogTopic *&Dialogs; + ViewStruct *&Views; + PScript GlobalScript; + PScript DialogScript; + std::vector ScriptModules; + std::vector PluginInfos; + + // Original sprite data (when it was read into const-sized arrays) + size_t SpriteCount; + std::unique_ptr SpriteFlags; + + // Old dialog support + // legacy compiled dialog script of its own format, + // requires separate interpreting + std::vector< std::shared_ptr > OldDialogScripts; + // probably, actual dialog script sources kept within some older games + std::vector OldDialogSources; + // speech texts displayed during dialog + std::vector OldSpeechLines; + + LoadedGameEntities(GameSetupStruct &game, DialogTopic *&dialogs, ViewStruct *&views); + ~LoadedGameEntities(); }; // Tells if the given path (library filename) contains main game file diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index ec068cc8bfd3..53a922689f5b 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -35,20 +35,17 @@ // TODO: why 10 MB limit? #define PLUGIN_SAVEBUFFERSIZE 10247680 -namespace AGS -{ -namespace Common -{ - -struct PluginInfo -{ - // (File)name of plugin - String Name; - // Custom data for plugin - std::shared_ptr Data; - size_t DataLen; - - PluginInfo() : DataLen(0) {} +namespace AGS { +namespace Common { + +struct PluginInfo { + // (File)name of plugin + String Name; + // Custom data for plugin + std::shared_ptr Data; + size_t DataLen; + + PluginInfo() : DataLen(0) {} }; } // namespace Common diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index 6f4670633f3f..c2c3996c8bf9 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -44,930 +44,841 @@ #define ROOM_LEGACY_OPTIONS_SIZE 10 #define LEGACY_TINT_IS_ENABLED 0x80000000 -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { RoomDataSource::RoomDataSource() - : DataVersion(kRoomVersion_Undefined) -{ + : DataVersion(kRoomVersion_Undefined) { } -String GetRoomFileErrorText(RoomFileErrorType err) -{ - switch (err) - { - case kRoomFileErr_NoError: - return "No error."; - case kRoomFileErr_FileOpenFailed: - return "Room file was not found or could not be opened."; - case kRoomFileErr_FormatNotSupported: - return "Format version not supported."; - case kRoomFileErr_UnexpectedEOF: - return "Unexpected end of file."; - case kRoomFileErr_UnknownBlockType: - return "Unknown block type."; - case kRoomFileErr_OldBlockNotSupported: - return "Block type is too old and not supported by this version of the engine."; - case kRoomFileErr_BlockDataOverlapping: - return "Block data overlapping."; - case kRoomFileErr_IncompatibleEngine: - return "This engine cannot handle requested room content."; - case kRoomFileErr_ScriptLoadFailed: - return "Script load failed."; - case kRoomFileErr_InconsistentData: - return "Inconsistent room data, or file is corrupted."; - case kRoomFileErr_PropertiesBlockFormat: - return "Unknown format of the custom properties block."; - case kRoomFileErr_InvalidPropertyValues: - return "Errors encountered when reading custom properties."; - case kRoomFileErr_BlockNotFound: - return "Required block was not found."; - } - return "Unknown error."; +String GetRoomFileErrorText(RoomFileErrorType err) { + switch (err) { + case kRoomFileErr_NoError: + return "No error."; + case kRoomFileErr_FileOpenFailed: + return "Room file was not found or could not be opened."; + case kRoomFileErr_FormatNotSupported: + return "Format version not supported."; + case kRoomFileErr_UnexpectedEOF: + return "Unexpected end of file."; + case kRoomFileErr_UnknownBlockType: + return "Unknown block type."; + case kRoomFileErr_OldBlockNotSupported: + return "Block type is too old and not supported by this version of the engine."; + case kRoomFileErr_BlockDataOverlapping: + return "Block data overlapping."; + case kRoomFileErr_IncompatibleEngine: + return "This engine cannot handle requested room content."; + case kRoomFileErr_ScriptLoadFailed: + return "Script load failed."; + case kRoomFileErr_InconsistentData: + return "Inconsistent room data, or file is corrupted."; + case kRoomFileErr_PropertiesBlockFormat: + return "Unknown format of the custom properties block."; + case kRoomFileErr_InvalidPropertyValues: + return "Errors encountered when reading custom properties."; + case kRoomFileErr_BlockNotFound: + return "Required block was not found."; + } + return "Unknown error."; } -HRoomFileError OpenRoomFile(const String &filename, RoomDataSource &src) -{ - // Cleanup source struct - src = RoomDataSource(); - // Try to open room file - Stream *in = AssetManager::OpenAsset(filename); - if (in == nullptr) - return new RoomFileError(kRoomFileErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); - // Read room header - src.Filename = filename; - src.DataVersion = (RoomFileVersion)in->ReadInt16(); - if (src.DataVersion < kRoomVersion_250b || src.DataVersion > kRoomVersion_Current) - return new RoomFileError(kRoomFileErr_FormatNotSupported, String::FromFormat("Required format version: %d, supported %d - %d", src.DataVersion, kRoomVersion_250b, kRoomVersion_Current)); - // Everything is fine, return opened stream - src.InputStream.reset(in); - return HRoomFileError::None(); +HRoomFileError OpenRoomFile(const String &filename, RoomDataSource &src) { + // Cleanup source struct + src = RoomDataSource(); + // Try to open room file + Stream *in = AssetManager::OpenAsset(filename); + if (in == nullptr) + return new RoomFileError(kRoomFileErr_FileOpenFailed, String::FromFormat("Filename: %s.", filename.GetCStr())); + // Read room header + src.Filename = filename; + src.DataVersion = (RoomFileVersion)in->ReadInt16(); + if (src.DataVersion < kRoomVersion_250b || src.DataVersion > kRoomVersion_Current) + return new RoomFileError(kRoomFileErr_FormatNotSupported, String::FromFormat("Required format version: %d, supported %d - %d", src.DataVersion, kRoomVersion_250b, kRoomVersion_Current)); + // Everything is fine, return opened stream + src.InputStream.reset(in); + return HRoomFileError::None(); } -enum RoomFileBlock -{ - kRoomFblk_None = 0, - // Main room data - kRoomFblk_Main = 1, - // Room script text source (was present in older room formats) - kRoomFblk_Script = 2, - // Old versions of compiled script (no longer supported) - kRoomFblk_CompScript = 3, - kRoomFblk_CompScript2 = 4, - // Names of the room objects - kRoomFblk_ObjectNames = 5, - // Secondary room backgrounds - kRoomFblk_AnimBg = 6, - // Contemporary compiled script - kRoomFblk_CompScript3 = 7, - // Custom properties - kRoomFblk_Properties = 8, - // Script names of the room objects - kRoomFblk_ObjectScNames = 9, - // End of room data tag - kRoomFile_EOF = 0xFF +enum RoomFileBlock { + kRoomFblk_None = 0, + // Main room data + kRoomFblk_Main = 1, + // Room script text source (was present in older room formats) + kRoomFblk_Script = 2, + // Old versions of compiled script (no longer supported) + kRoomFblk_CompScript = 3, + kRoomFblk_CompScript2 = 4, + // Names of the room objects + kRoomFblk_ObjectNames = 5, + // Secondary room backgrounds + kRoomFblk_AnimBg = 6, + // Contemporary compiled script + kRoomFblk_CompScript3 = 7, + // Custom properties + kRoomFblk_Properties = 8, + // Script names of the room objects + kRoomFblk_ObjectScNames = 9, + // End of room data tag + kRoomFile_EOF = 0xFF }; -void ReadRoomObject(RoomObjectInfo &obj, Stream *in) -{ - obj.Sprite = in->ReadInt16(); - obj.X = in->ReadInt16(); - obj.Y = in->ReadInt16(); - obj.Room = in->ReadInt16(); - obj.IsOn = in->ReadInt16() != 0; +void ReadRoomObject(RoomObjectInfo &obj, Stream *in) { + obj.Sprite = in->ReadInt16(); + obj.X = in->ReadInt16(); + obj.Y = in->ReadInt16(); + obj.Room = in->ReadInt16(); + obj.IsOn = in->ReadInt16() != 0; } -void WriteRoomObject(const RoomObjectInfo &obj, Stream *out) -{ - // TODO: expand serialization into 32-bit values at least for the sprite index!! - out->WriteInt16((int16_t)obj.Sprite); - out->WriteInt16((int16_t)obj.X); - out->WriteInt16((int16_t)obj.Y); - out->WriteInt16((int16_t)obj.Room); - out->WriteInt16(obj.IsOn ? 1 : 0); +void WriteRoomObject(const RoomObjectInfo &obj, Stream *out) { + // TODO: expand serialization into 32-bit values at least for the sprite index!! + out->WriteInt16((int16_t)obj.Sprite); + out->WriteInt16((int16_t)obj.X); + out->WriteInt16((int16_t)obj.Y); + out->WriteInt16((int16_t)obj.Room); + out->WriteInt16(obj.IsOn ? 1 : 0); } // Main room data -HRoomFileError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) -{ - int bpp; - if (data_ver >= kRoomVersion_208) - bpp = in->ReadInt32(); - else - bpp = 1; - - if (bpp < 1) - bpp = 1; - - room->BackgroundBPP = bpp; - room->WalkBehindCount = in->ReadInt16(); - if (room->WalkBehindCount > MAX_WALK_BEHINDS) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many walk-behinds (in room: %d, max: %d).", room->WalkBehindCount, MAX_WALK_BEHINDS)); - - // Walk-behinds baselines - for (size_t i = 0; i < room->WalkBehindCount; ++i) - room->WalkBehinds[i].Baseline = in->ReadInt16(); - - room->HotspotCount = in->ReadInt32(); - if (room->HotspotCount == 0) - room->HotspotCount = MIN_ROOM_HOTSPOTS; - if (room->HotspotCount > MAX_ROOM_HOTSPOTS) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many hotspots (in room: %d, max: %d).", room->HotspotCount, MAX_ROOM_HOTSPOTS)); - - // Hotspots walk-to points - for (size_t i = 0; i < room->HotspotCount; ++i) - { - room->Hotspots[i].WalkTo.X = in->ReadInt16(); - room->Hotspots[i].WalkTo.Y = in->ReadInt16(); - } - - // Hotspots names and script names - for (size_t i = 0; i < room->HotspotCount; ++i) - { - if (data_ver >= kRoomVersion_3415) - room->Hotspots[i].Name = StrUtil::ReadString(in); - else if (data_ver >= kRoomVersion_303a) - room->Hotspots[i].Name = String::FromStream(in); - else - room->Hotspots[i].Name = String::FromStreamCount(in, LEGACY_HOTSPOT_NAME_LEN); - } - - if (data_ver >= kRoomVersion_270) - { - for (size_t i = 0; i < room->HotspotCount; ++i) - { - if (data_ver >= kRoomVersion_3415) - room->Hotspots[i].ScriptName = StrUtil::ReadString(in); - else - room->Hotspots[i].ScriptName = String::FromStreamCount(in, MAX_SCRIPT_NAME_LEN); - } - } - - // TODO: remove from format later - size_t polypoint_areas = in->ReadInt32(); - if (polypoint_areas > 0) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Legacy poly-point areas are no longer supported."); - /* NOTE: implementation hidden in room_file_deprecated.cpp - for (size_t i = 0; i < polypoint_areas; ++i) - wallpoints[i].Read(in); - */ - - update_polled_stuff_if_runtime(); - - room->Edges.Top = in->ReadInt16(); - room->Edges.Bottom = in->ReadInt16(); - room->Edges.Left = in->ReadInt16(); - room->Edges.Right = in->ReadInt16(); - - // Room objects - room->ObjectCount = in->ReadInt16(); - if (room->ObjectCount > MAX_ROOM_OBJECTS) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many objects (in room: %d, max: %d).", room->ObjectCount, MAX_ROOM_OBJECTS)); - - for (size_t i = 0; i < room->ObjectCount; ++i) - ReadRoomObject(room->Objects[i], in); - - // Legacy interactions - if (data_ver >= kRoomVersion_253) - { - size_t localvar_count = in->ReadInt32(); - if (localvar_count > 0) - { - room->LocalVariables.resize(localvar_count); - for (size_t i = 0; i < localvar_count; ++i) - room->LocalVariables[i].Read(in); - } - } - - if (data_ver >= kRoomVersion_241 && data_ver < kRoomVersion_300a) - { - for (size_t i = 0; i < room->HotspotCount; ++i) - room->Hotspots[i].Interaction.reset(Interaction::CreateFromStream(in)); - for (size_t i = 0; i < room->ObjectCount; ++i) - room->Objects[i].Interaction.reset(Interaction::CreateFromStream(in)); - room->Interaction.reset(Interaction::CreateFromStream(in)); - } - - if (data_ver >= kRoomVersion_255b) - { - room->RegionCount = in->ReadInt32(); - if (room->RegionCount > MAX_ROOM_REGIONS) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many regions (in room: %d, max: %d).", room->RegionCount, MAX_ROOM_REGIONS)); - - if (data_ver < kRoomVersion_300a) - { - for (size_t i = 0; i < room->RegionCount; ++i) - room->Regions[i].Interaction.reset(Interaction::CreateFromStream(in)); - } - } - - // Event script links - if (data_ver >= kRoomVersion_300a) - { - room->EventHandlers.reset(InteractionScripts::CreateFromStream(in)); - for (size_t i = 0; i < room->HotspotCount; ++i) - room->Hotspots[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); - for (size_t i = 0; i < room->ObjectCount; ++i) - room->Objects[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); - for (size_t i = 0; i < room->RegionCount; ++i) - room->Regions[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); - } - - if (data_ver >= kRoomVersion_200_alpha) - { - for (size_t i = 0; i < room->ObjectCount; ++i) - room->Objects[i].Baseline = in->ReadInt32(); - room->Width = in->ReadInt16(); - room->Height = in->ReadInt16(); - } - - if (data_ver >= kRoomVersion_262) - for (size_t i = 0; i < room->ObjectCount; ++i) - room->Objects[i].Flags = in->ReadInt16(); - - if (data_ver >= kRoomVersion_200_final) - room->MaskResolution = in->ReadInt16(); - - room->WalkAreaCount = MAX_WALK_AREAS; - if (data_ver >= kRoomVersion_240) - room->WalkAreaCount = in->ReadInt32(); - if (room->WalkAreaCount > MAX_WALK_AREAS + 1) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many walkable areas (in room: %d, max: %d).", room->WalkAreaCount, MAX_WALK_AREAS + 1)); - - if (data_ver >= kRoomVersion_200_alpha7) - for (size_t i = 0; i < room->WalkAreaCount; ++i) - room->WalkAreas[i].ScalingFar = in->ReadInt16(); - if (data_ver >= kRoomVersion_214) - for (size_t i = 0; i < room->WalkAreaCount; ++i) - room->WalkAreas[i].Light = in->ReadInt16(); - if (data_ver >= kRoomVersion_251) - { - for (size_t i = 0; i < room->WalkAreaCount; ++i) - room->WalkAreas[i].ScalingNear = in->ReadInt16(); - for (size_t i = 0; i < room->WalkAreaCount; ++i) - room->WalkAreas[i].Top = in->ReadInt16(); - for (size_t i = 0; i < room->WalkAreaCount; ++i) - room->WalkAreas[i].Bottom = in->ReadInt16(); - } - - in->Seek(LEGACY_ROOM_PASSWORD_LENGTH); // skip password - room->Options.StartupMusic = in->ReadInt8(); - room->Options.SaveLoadDisabled = in->ReadInt8() != 0; - room->Options.PlayerCharOff = in->ReadInt8() != 0; - room->Options.PlayerView = in->ReadInt8(); - room->Options.MusicVolume = (RoomVolumeMod)in->ReadInt8(); - in->Seek(ROOM_LEGACY_OPTIONS_SIZE - 5); - - room->MessageCount = in->ReadInt16(); - if (room->MessageCount > MAX_MESSAGES) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many room messages (in room: %d, max: %d).", room->MessageCount, MAX_MESSAGES)); - - if (data_ver >= kRoomVersion_272) - room->GameID = in->ReadInt32(); - - if (data_ver >= kRoomVersion_pre114_3) - { - for (size_t i = 0; i < room->MessageCount; ++i) - { - room->MessageInfos[i].DisplayAs = in->ReadInt8(); - room->MessageInfos[i].Flags = in->ReadInt8(); - } - } - - char buffer[3000]; - for (size_t i = 0; i < room->MessageCount; ++i) - { - if (data_ver >= kRoomVersion_261) - read_string_decrypt(in, buffer, sizeof(buffer)); - else - StrUtil::ReadCStr(buffer, in, sizeof(buffer)); - room->Messages[i] = buffer; - } - - // Very old format legacy room animations (FullAnimation) - if (data_ver >= kRoomVersion_pre114_6) - { - // TODO: remove from format later - size_t fullanim_count = in->ReadInt16(); - if (fullanim_count > 0) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Room animations are no longer supported."); - /* NOTE: implementation hidden in room_file_deprecated.cpp - in->ReadArray(&fullanims[0], sizeof(FullAnimation), fullanim_count); - */ - } - - // Ancient "graphical scripts". We currently don't support them because - // there's no knowledge on how to convert them to modern engine. - if ((data_ver >= kRoomVersion_pre114_4) && (data_ver < kRoomVersion_250a)) - { - return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Pre-2.5 graphical scripts are no longer supported."); - /* NOTE: implementation hidden in room_file_deprecated.cpp - ReadPre250Scripts(in); - */ - } - - if (data_ver >= kRoomVersion_114) - { - for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) - room->WalkAreas[i].Light = in->ReadInt16(); - } - if (data_ver >= kRoomVersion_255b) - { - for (size_t i = 0; i < room->RegionCount; ++i) - room->Regions[i].Light = in->ReadInt16(); - for (size_t i = 0; i < room->RegionCount; ++i) - room->Regions[i].Tint = in->ReadInt32(); - } - - update_polled_stuff_if_runtime(); - // Primary background - Bitmap *mask = nullptr; - if (data_ver >= kRoomVersion_pre114_5) - load_lzw(in, &mask, room->BackgroundBPP, room->Palette); - else - loadcompressed_allegro(in, &mask, room->Palette); - room->BgFrames[0].Graphic.reset(mask); - - update_polled_stuff_if_runtime(); - // Mask bitmaps - if (data_ver >= kRoomVersion_255b) - { - loadcompressed_allegro(in, &mask, room->Palette); - } - else if (data_ver >= kRoomVersion_114) - { - // an old version - clear the 'shadow' area into a blank regions bmp - loadcompressed_allegro(in, &mask, room->Palette); - delete mask; - mask = nullptr; - } - room->RegionMask.reset(mask); - update_polled_stuff_if_runtime(); - loadcompressed_allegro(in, &mask, room->Palette); - room->WalkAreaMask.reset(mask); - update_polled_stuff_if_runtime(); - loadcompressed_allegro(in, &mask, room->Palette); - room->WalkBehindMask.reset(mask); - update_polled_stuff_if_runtime(); - loadcompressed_allegro(in, &mask, room->Palette); - room->HotspotMask.reset(mask); - return HRoomFileError::None(); +HRoomFileError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { + int bpp; + if (data_ver >= kRoomVersion_208) + bpp = in->ReadInt32(); + else + bpp = 1; + + if (bpp < 1) + bpp = 1; + + room->BackgroundBPP = bpp; + room->WalkBehindCount = in->ReadInt16(); + if (room->WalkBehindCount > MAX_WALK_BEHINDS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many walk-behinds (in room: %d, max: %d).", room->WalkBehindCount, MAX_WALK_BEHINDS)); + + // Walk-behinds baselines + for (size_t i = 0; i < room->WalkBehindCount; ++i) + room->WalkBehinds[i].Baseline = in->ReadInt16(); + + room->HotspotCount = in->ReadInt32(); + if (room->HotspotCount == 0) + room->HotspotCount = MIN_ROOM_HOTSPOTS; + if (room->HotspotCount > MAX_ROOM_HOTSPOTS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many hotspots (in room: %d, max: %d).", room->HotspotCount, MAX_ROOM_HOTSPOTS)); + + // Hotspots walk-to points + for (size_t i = 0; i < room->HotspotCount; ++i) { + room->Hotspots[i].WalkTo.X = in->ReadInt16(); + room->Hotspots[i].WalkTo.Y = in->ReadInt16(); + } + + // Hotspots names and script names + for (size_t i = 0; i < room->HotspotCount; ++i) { + if (data_ver >= kRoomVersion_3415) + room->Hotspots[i].Name = StrUtil::ReadString(in); + else if (data_ver >= kRoomVersion_303a) + room->Hotspots[i].Name = String::FromStream(in); + else + room->Hotspots[i].Name = String::FromStreamCount(in, LEGACY_HOTSPOT_NAME_LEN); + } + + if (data_ver >= kRoomVersion_270) { + for (size_t i = 0; i < room->HotspotCount; ++i) { + if (data_ver >= kRoomVersion_3415) + room->Hotspots[i].ScriptName = StrUtil::ReadString(in); + else + room->Hotspots[i].ScriptName = String::FromStreamCount(in, MAX_SCRIPT_NAME_LEN); + } + } + + // TODO: remove from format later + size_t polypoint_areas = in->ReadInt32(); + if (polypoint_areas > 0) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Legacy poly-point areas are no longer supported."); + /* NOTE: implementation hidden in room_file_deprecated.cpp + for (size_t i = 0; i < polypoint_areas; ++i) + wallpoints[i].Read(in); + */ + + update_polled_stuff_if_runtime(); + + room->Edges.Top = in->ReadInt16(); + room->Edges.Bottom = in->ReadInt16(); + room->Edges.Left = in->ReadInt16(); + room->Edges.Right = in->ReadInt16(); + + // Room objects + room->ObjectCount = in->ReadInt16(); + if (room->ObjectCount > MAX_ROOM_OBJECTS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many objects (in room: %d, max: %d).", room->ObjectCount, MAX_ROOM_OBJECTS)); + + for (size_t i = 0; i < room->ObjectCount; ++i) + ReadRoomObject(room->Objects[i], in); + + // Legacy interactions + if (data_ver >= kRoomVersion_253) { + size_t localvar_count = in->ReadInt32(); + if (localvar_count > 0) { + room->LocalVariables.resize(localvar_count); + for (size_t i = 0; i < localvar_count; ++i) + room->LocalVariables[i].Read(in); + } + } + + if (data_ver >= kRoomVersion_241 && data_ver < kRoomVersion_300a) { + for (size_t i = 0; i < room->HotspotCount; ++i) + room->Hotspots[i].Interaction.reset(Interaction::CreateFromStream(in)); + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Interaction.reset(Interaction::CreateFromStream(in)); + room->Interaction.reset(Interaction::CreateFromStream(in)); + } + + if (data_ver >= kRoomVersion_255b) { + room->RegionCount = in->ReadInt32(); + if (room->RegionCount > MAX_ROOM_REGIONS) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many regions (in room: %d, max: %d).", room->RegionCount, MAX_ROOM_REGIONS)); + + if (data_ver < kRoomVersion_300a) { + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].Interaction.reset(Interaction::CreateFromStream(in)); + } + } + + // Event script links + if (data_ver >= kRoomVersion_300a) { + room->EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + for (size_t i = 0; i < room->HotspotCount; ++i) + room->Hotspots[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in)); + } + + if (data_ver >= kRoomVersion_200_alpha) { + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Baseline = in->ReadInt32(); + room->Width = in->ReadInt16(); + room->Height = in->ReadInt16(); + } + + if (data_ver >= kRoomVersion_262) + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Flags = in->ReadInt16(); + + if (data_ver >= kRoomVersion_200_final) + room->MaskResolution = in->ReadInt16(); + + room->WalkAreaCount = MAX_WALK_AREAS; + if (data_ver >= kRoomVersion_240) + room->WalkAreaCount = in->ReadInt32(); + if (room->WalkAreaCount > MAX_WALK_AREAS + 1) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many walkable areas (in room: %d, max: %d).", room->WalkAreaCount, MAX_WALK_AREAS + 1)); + + if (data_ver >= kRoomVersion_200_alpha7) + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].ScalingFar = in->ReadInt16(); + if (data_ver >= kRoomVersion_214) + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].Light = in->ReadInt16(); + if (data_ver >= kRoomVersion_251) { + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].ScalingNear = in->ReadInt16(); + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].Top = in->ReadInt16(); + for (size_t i = 0; i < room->WalkAreaCount; ++i) + room->WalkAreas[i].Bottom = in->ReadInt16(); + } + + in->Seek(LEGACY_ROOM_PASSWORD_LENGTH); // skip password + room->Options.StartupMusic = in->ReadInt8(); + room->Options.SaveLoadDisabled = in->ReadInt8() != 0; + room->Options.PlayerCharOff = in->ReadInt8() != 0; + room->Options.PlayerView = in->ReadInt8(); + room->Options.MusicVolume = (RoomVolumeMod)in->ReadInt8(); + in->Seek(ROOM_LEGACY_OPTIONS_SIZE - 5); + + room->MessageCount = in->ReadInt16(); + if (room->MessageCount > MAX_MESSAGES) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many room messages (in room: %d, max: %d).", room->MessageCount, MAX_MESSAGES)); + + if (data_ver >= kRoomVersion_272) + room->GameID = in->ReadInt32(); + + if (data_ver >= kRoomVersion_pre114_3) { + for (size_t i = 0; i < room->MessageCount; ++i) { + room->MessageInfos[i].DisplayAs = in->ReadInt8(); + room->MessageInfos[i].Flags = in->ReadInt8(); + } + } + + char buffer[3000]; + for (size_t i = 0; i < room->MessageCount; ++i) { + if (data_ver >= kRoomVersion_261) + read_string_decrypt(in, buffer, sizeof(buffer)); + else + StrUtil::ReadCStr(buffer, in, sizeof(buffer)); + room->Messages[i] = buffer; + } + + // Very old format legacy room animations (FullAnimation) + if (data_ver >= kRoomVersion_pre114_6) { + // TODO: remove from format later + size_t fullanim_count = in->ReadInt16(); + if (fullanim_count > 0) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Room animations are no longer supported."); + /* NOTE: implementation hidden in room_file_deprecated.cpp + in->ReadArray(&fullanims[0], sizeof(FullAnimation), fullanim_count); + */ + } + + // Ancient "graphical scripts". We currently don't support them because + // there's no knowledge on how to convert them to modern engine. + if ((data_ver >= kRoomVersion_pre114_4) && (data_ver < kRoomVersion_250a)) { + return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Pre-2.5 graphical scripts are no longer supported."); + /* NOTE: implementation hidden in room_file_deprecated.cpp + ReadPre250Scripts(in); + */ + } + + if (data_ver >= kRoomVersion_114) { + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + room->WalkAreas[i].Light = in->ReadInt16(); + } + if (data_ver >= kRoomVersion_255b) { + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].Light = in->ReadInt16(); + for (size_t i = 0; i < room->RegionCount; ++i) + room->Regions[i].Tint = in->ReadInt32(); + } + + update_polled_stuff_if_runtime(); + // Primary background + Bitmap *mask = nullptr; + if (data_ver >= kRoomVersion_pre114_5) + load_lzw(in, &mask, room->BackgroundBPP, room->Palette); + else + loadcompressed_allegro(in, &mask, room->Palette); + room->BgFrames[0].Graphic.reset(mask); + + update_polled_stuff_if_runtime(); + // Mask bitmaps + if (data_ver >= kRoomVersion_255b) { + loadcompressed_allegro(in, &mask, room->Palette); + } else if (data_ver >= kRoomVersion_114) { + // an old version - clear the 'shadow' area into a blank regions bmp + loadcompressed_allegro(in, &mask, room->Palette); + delete mask; + mask = nullptr; + } + room->RegionMask.reset(mask); + update_polled_stuff_if_runtime(); + loadcompressed_allegro(in, &mask, room->Palette); + room->WalkAreaMask.reset(mask); + update_polled_stuff_if_runtime(); + loadcompressed_allegro(in, &mask, room->Palette); + room->WalkBehindMask.reset(mask); + update_polled_stuff_if_runtime(); + loadcompressed_allegro(in, &mask, room->Palette); + room->HotspotMask.reset(mask); + return HRoomFileError::None(); } // Room script sources (original text) -HRoomFileError ReadScriptBlock(char *&buf, Stream *in, RoomFileVersion data_ver) -{ - size_t len = in->ReadInt32(); - buf = new char[len + 1]; - in->Read(buf, len); - buf[len] = 0; - for (size_t i = 0; i < len; ++i) - buf[i] += passwencstring[i % 11]; - return HRoomFileError::None(); +HRoomFileError ReadScriptBlock(char *&buf, Stream *in, RoomFileVersion data_ver) { + size_t len = in->ReadInt32(); + buf = new char[len + 1]; + in->Read(buf, len); + buf[len] = 0; + for (size_t i = 0; i < len; ++i) + buf[i] += passwencstring[i % 11]; + return HRoomFileError::None(); } // Compiled room script -HRoomFileError ReadCompSc3Block(RoomStruct *room, Stream *in, RoomFileVersion data_ver) -{ - room->CompiledScript.reset(ccScript::CreateFromStream(in)); - if (room->CompiledScript == nullptr) - return new RoomFileError(kRoomFileErr_ScriptLoadFailed, ccErrorString); - return HRoomFileError::None(); +HRoomFileError ReadCompSc3Block(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { + room->CompiledScript.reset(ccScript::CreateFromStream(in)); + if (room->CompiledScript == nullptr) + return new RoomFileError(kRoomFileErr_ScriptLoadFailed, ccErrorString); + return HRoomFileError::None(); } // Room object names -HRoomFileError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) -{ - int name_count = in->ReadByte(); - if (name_count != room->ObjectCount) - return new RoomFileError(kRoomFileErr_InconsistentData, - String::FromFormat("In the object names block, expected name count: %d, got %d", room->ObjectCount, name_count)); - - for (size_t i = 0; i < room->ObjectCount; ++i) - { - if (data_ver >= kRoomVersion_3415) - room->Objects[i].Name = StrUtil::ReadString(in); - else - room->Objects[i].Name.ReadCount(in, LEGACY_MAXOBJNAMELEN); - } - return HRoomFileError::None(); +HRoomFileError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { + int name_count = in->ReadByte(); + if (name_count != room->ObjectCount) + return new RoomFileError(kRoomFileErr_InconsistentData, + String::FromFormat("In the object names block, expected name count: %d, got %d", room->ObjectCount, name_count)); + + for (size_t i = 0; i < room->ObjectCount; ++i) { + if (data_ver >= kRoomVersion_3415) + room->Objects[i].Name = StrUtil::ReadString(in); + else + room->Objects[i].Name.ReadCount(in, LEGACY_MAXOBJNAMELEN); + } + return HRoomFileError::None(); } // Room object script names -HRoomFileError ReadObjScNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) -{ - int name_count = in->ReadByte(); - if (name_count != room->ObjectCount) - return new RoomFileError(kRoomFileErr_InconsistentData, - String::FromFormat("In the object script names block, expected name count: %d, got %d", room->ObjectCount, name_count)); - - for (size_t i = 0; i < room->ObjectCount; ++i) - { - if (data_ver >= kRoomVersion_3415) - room->Objects[i].ScriptName = StrUtil::ReadString(in); - else - room->Objects[i].ScriptName.ReadCount(in, MAX_SCRIPT_NAME_LEN); - } - return HRoomFileError::None(); +HRoomFileError ReadObjScNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { + int name_count = in->ReadByte(); + if (name_count != room->ObjectCount) + return new RoomFileError(kRoomFileErr_InconsistentData, + String::FromFormat("In the object script names block, expected name count: %d, got %d", room->ObjectCount, name_count)); + + for (size_t i = 0; i < room->ObjectCount; ++i) { + if (data_ver >= kRoomVersion_3415) + room->Objects[i].ScriptName = StrUtil::ReadString(in); + else + room->Objects[i].ScriptName.ReadCount(in, MAX_SCRIPT_NAME_LEN); + } + return HRoomFileError::None(); } // Secondary backgrounds -HRoomFileError ReadAnimBgBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) -{ - room->BgFrameCount = in->ReadByte(); - if (room->BgFrameCount > MAX_ROOM_BGFRAMES) - return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many room backgrounds (in room: %d, max: %d).", room->BgFrameCount, MAX_ROOM_BGFRAMES)); - - room->BgAnimSpeed = in->ReadByte(); - if (data_ver >= kRoomVersion_255a) - { - for (size_t i = 0; i < room->BgFrameCount; ++i) - room->BgFrames[i].IsPaletteShared = in->ReadInt8() != 0; - } - - for (size_t i = 1; i < room->BgFrameCount; ++i) - { - update_polled_stuff_if_runtime(); - Bitmap *frame = nullptr; - load_lzw(in, &frame, room->BackgroundBPP, room->BgFrames[i].Palette); - room->BgFrames[i].Graphic.reset(frame); - } - return HRoomFileError::None(); +HRoomFileError ReadAnimBgBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { + room->BgFrameCount = in->ReadByte(); + if (room->BgFrameCount > MAX_ROOM_BGFRAMES) + return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many room backgrounds (in room: %d, max: %d).", room->BgFrameCount, MAX_ROOM_BGFRAMES)); + + room->BgAnimSpeed = in->ReadByte(); + if (data_ver >= kRoomVersion_255a) { + for (size_t i = 0; i < room->BgFrameCount; ++i) + room->BgFrames[i].IsPaletteShared = in->ReadInt8() != 0; + } + + for (size_t i = 1; i < room->BgFrameCount; ++i) { + update_polled_stuff_if_runtime(); + Bitmap *frame = nullptr; + load_lzw(in, &frame, room->BackgroundBPP, room->BgFrames[i].Palette); + room->BgFrames[i].Graphic.reset(frame); + } + return HRoomFileError::None(); } // Read custom properties -HRoomFileError ReadPropertiesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) -{ - int prop_ver = in->ReadInt32(); - if (prop_ver != 1) - return new RoomFileError(kRoomFileErr_PropertiesBlockFormat, String::FromFormat("Expected version %d, got %d", 1, prop_ver)); - - int errors = 0; - errors += Properties::ReadValues(room->Properties, in); - for (size_t i = 0; i < room->HotspotCount; ++i) - errors += Properties::ReadValues(room->Hotspots[i].Properties, in); - for (size_t i = 0; i < room->ObjectCount; ++i) - errors += Properties::ReadValues(room->Objects[i].Properties, in); - - if (errors > 0) - return new RoomFileError(kRoomFileErr_InvalidPropertyValues); - return HRoomFileError::None(); +HRoomFileError ReadPropertiesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { + int prop_ver = in->ReadInt32(); + if (prop_ver != 1) + return new RoomFileError(kRoomFileErr_PropertiesBlockFormat, String::FromFormat("Expected version %d, got %d", 1, prop_ver)); + + int errors = 0; + errors += Properties::ReadValues(room->Properties, in); + for (size_t i = 0; i < room->HotspotCount; ++i) + errors += Properties::ReadValues(room->Hotspots[i].Properties, in); + for (size_t i = 0; i < room->ObjectCount; ++i) + errors += Properties::ReadValues(room->Objects[i].Properties, in); + + if (errors > 0) + return new RoomFileError(kRoomFileErr_InvalidPropertyValues); + return HRoomFileError::None(); } -HRoomFileError ReadRoomBlock(RoomStruct *room, Stream *in, RoomFileBlock block, RoomFileVersion data_ver) -{ - soff_t block_len = data_ver < kRoomVersion_350 ? in->ReadInt32() : in->ReadInt64(); - soff_t block_end = in->GetPosition() + block_len; - - HRoomFileError err; - switch (block) - { - case kRoomFblk_Main: - err = ReadMainBlock(room, in, data_ver); - break; - case kRoomFblk_Script: - in->Seek(block_len); // no longer read source script text into RoomStruct - break; - case kRoomFblk_CompScript3: - err = ReadCompSc3Block(room, in, data_ver); - break; - case kRoomFblk_ObjectNames: - err = ReadObjNamesBlock(room, in, data_ver); - break; - case kRoomFblk_ObjectScNames: - err = ReadObjScNamesBlock(room, in, data_ver); - break; - case kRoomFblk_AnimBg: - err = ReadAnimBgBlock(room, in, data_ver); - break; - case kRoomFblk_Properties: - err = ReadPropertiesBlock(room, in, data_ver); - break; - case kRoomFblk_CompScript: - case kRoomFblk_CompScript2: - return new RoomFileError(kRoomFileErr_OldBlockNotSupported, - String::FromFormat("Type: %d.", block)); - default: - return new RoomFileError(kRoomFileErr_UnknownBlockType, - String::FromFormat("Type: %d, known range: %d - %d.", block, kRoomFblk_Main, kRoomFblk_ObjectScNames)); - } - - if (!err) - return err; - - soff_t cur_pos = in->GetPosition(); - if (cur_pos > block_end) - { - return new RoomFileError(kRoomFileErr_BlockDataOverlapping, - String::FromFormat("Type: %d, expected to end at offset: %u, finished reading at %u.", block, block_end, cur_pos)); - } - else if (cur_pos < block_end) - { - Debug::Printf(kDbgMsg_Warn, "WARNING: room data blocks nonsequential, block type %d expected to end at %u, finished reading at %u", - block, block_end, cur_pos); - in->Seek(block_end, Common::kSeekBegin); - } - return HRoomFileError::None(); +HRoomFileError ReadRoomBlock(RoomStruct *room, Stream *in, RoomFileBlock block, RoomFileVersion data_ver) { + soff_t block_len = data_ver < kRoomVersion_350 ? in->ReadInt32() : in->ReadInt64(); + soff_t block_end = in->GetPosition() + block_len; + + HRoomFileError err; + switch (block) { + case kRoomFblk_Main: + err = ReadMainBlock(room, in, data_ver); + break; + case kRoomFblk_Script: + in->Seek(block_len); // no longer read source script text into RoomStruct + break; + case kRoomFblk_CompScript3: + err = ReadCompSc3Block(room, in, data_ver); + break; + case kRoomFblk_ObjectNames: + err = ReadObjNamesBlock(room, in, data_ver); + break; + case kRoomFblk_ObjectScNames: + err = ReadObjScNamesBlock(room, in, data_ver); + break; + case kRoomFblk_AnimBg: + err = ReadAnimBgBlock(room, in, data_ver); + break; + case kRoomFblk_Properties: + err = ReadPropertiesBlock(room, in, data_ver); + break; + case kRoomFblk_CompScript: + case kRoomFblk_CompScript2: + return new RoomFileError(kRoomFileErr_OldBlockNotSupported, + String::FromFormat("Type: %d.", block)); + default: + return new RoomFileError(kRoomFileErr_UnknownBlockType, + String::FromFormat("Type: %d, known range: %d - %d.", block, kRoomFblk_Main, kRoomFblk_ObjectScNames)); + } + + if (!err) + return err; + + soff_t cur_pos = in->GetPosition(); + if (cur_pos > block_end) { + return new RoomFileError(kRoomFileErr_BlockDataOverlapping, + String::FromFormat("Type: %d, expected to end at offset: %u, finished reading at %u.", block, block_end, cur_pos)); + } else if (cur_pos < block_end) { + Debug::Printf(kDbgMsg_Warn, "WARNING: room data blocks nonsequential, block type %d expected to end at %u, finished reading at %u", + block, block_end, cur_pos); + in->Seek(block_end, Common::kSeekBegin); + } + return HRoomFileError::None(); } -HRoomFileError ReadRoomData(RoomStruct *room, Stream *in, RoomFileVersion data_ver) -{ - room->DataVersion = data_ver; - - RoomFileBlock block; - do - { - update_polled_stuff_if_runtime(); - int b = in->ReadByte(); - if (b < 0) - return new RoomFileError(kRoomFileErr_UnexpectedEOF); - block = (RoomFileBlock)b; - if (block != kRoomFile_EOF) - { - HRoomFileError err = ReadRoomBlock(room, in, block, data_ver); - if (!err) - return err; - } - } - while (block != kRoomFile_EOF); - return HRoomFileError::None(); +HRoomFileError ReadRoomData(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { + room->DataVersion = data_ver; + + RoomFileBlock block; + do { + update_polled_stuff_if_runtime(); + int b = in->ReadByte(); + if (b < 0) + return new RoomFileError(kRoomFileErr_UnexpectedEOF); + block = (RoomFileBlock)b; + if (block != kRoomFile_EOF) { + HRoomFileError err = ReadRoomBlock(room, in, block, data_ver); + if (!err) + return err; + } + } while (block != kRoomFile_EOF); + return HRoomFileError::None(); } -HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool game_is_hires, const std::vector &sprinfos) -{ - if (data_ver < kRoomVersion_200_final) - room->MaskResolution = room->BgFrames[0].Graphic->GetWidth() > 320 ? kRoomHiRes : kRoomLoRes; - if (data_ver < kRoomVersion_3508) - { - // Save legacy resolution if it DOES NOT match game's; - // otherwise it gets promoted to "real resolution" - if (room->MaskResolution == 1 && game_is_hires) - room->SetResolution(kRoomLoRes); - else if (room->MaskResolution > 1 && !game_is_hires) - room->SetResolution(kRoomHiRes); - } - - // Old version - copy walkable areas to regions - if (data_ver < kRoomVersion_255b) - { - if (!room->RegionMask) - room->RegionMask.reset(BitmapHelper::CreateBitmap(room->WalkAreaMask->GetWidth(), room->WalkAreaMask->GetHeight(), 8)); - room->RegionMask->Blit(room->WalkAreaMask.get(), 0, 0, 0, 0, room->RegionMask->GetWidth(), room->RegionMask->GetHeight()); - for (size_t i = 0; i < MAX_ROOM_REGIONS; ++i) - { - room->Regions[i].Light = room->WalkAreas[i].Light; - room->Regions[i].Tint = 255; - } - } - - // Fill in dummy interaction objects into unused slots - // TODO: remove this later, need to rework the legacy interaction usage around the engine code to prevent crashes - if (data_ver < kRoomVersion_300a) - { - if (!room->Interaction) - room->Interaction.reset(new Interaction()); - for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) - if (!room->Hotspots[i].Interaction) - room->Hotspots[i].Interaction.reset(new Interaction()); - for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) - if (!room->Objects[i].Interaction) - room->Objects[i].Interaction.reset(new Interaction()); - for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) - if (!room->Regions[i].Interaction) - room->Regions[i].Interaction.reset(new Interaction()); - } - - // Upgade room object script names - if (data_ver < kRoomVersion_300a) - { - for (size_t i = 0; i < room->ObjectCount; ++i) - { - if (room->Objects[i].ScriptName.GetLength() > 0) - { - String jibbledScriptName; - jibbledScriptName.Format("o%s", room->Objects[i].ScriptName.GetCStr()); - jibbledScriptName.MakeLower(); - if (jibbledScriptName.GetLength() >= 2) - jibbledScriptName.SetAt(1, toupper(jibbledScriptName[1u])); - room->Objects[i].ScriptName = jibbledScriptName; - } - } - } - - // Pre-3.0.3, multiply up co-ordinates for high-res games to bring them - // to the proper game coordinate system. - // If you change this, also change convert_room_coordinates_to_data_res - // function in the engine - if (data_ver < kRoomVersion_303b && game_is_hires) - { - const int mul = HIRES_COORD_MULTIPLIER; - for (size_t i = 0; i < room->ObjectCount; ++i) - { - room->Objects[i].X *= mul; - room->Objects[i].Y *= mul; - if (room->Objects[i].Baseline > 0) - { - room->Objects[i].Baseline *= mul; - } - } - - for (size_t i = 0; i < room->HotspotCount; ++i) - { - room->Hotspots[i].WalkTo.X *= mul; - room->Hotspots[i].WalkTo.Y *= mul; - } - - for (size_t i = 0; i < room->WalkBehindCount; ++i) - { - room->WalkBehinds[i].Baseline *= mul; - } - - room->Edges.Left *= mul; - room->Edges.Top *= mul; - room->Edges.Bottom *= mul; - room->Edges.Right *= mul; - room->Width *= mul; - room->Height *= mul; - } - - // Adjust object Y coordinate by adding sprite's height - // NOTE: this is impossible to do without game sprite information loaded beforehand - // NOTE: this should be done after coordinate conversion above for simplicity - if (data_ver < kRoomVersion_300a) - { - for (size_t i = 0; i < room->ObjectCount; ++i) - room->Objects[i].Y += sprinfos[room->Objects[i].Sprite].Height; - } - - if (data_ver >= kRoomVersion_251) - { - // if they set a contiuously scaled area where the top - // and bottom zoom levels are identical, set it as a normal - // scaled area - for (size_t i = 0; i < room->WalkAreaCount; ++i) - { - if (room->WalkAreas[i].ScalingFar == room->WalkAreas[i].ScalingNear) - room->WalkAreas[i].ScalingNear = NOT_VECTOR_SCALED; - } - } - - // Convert the old format region tint saturation - if (data_ver < kRoomVersion_3404) - { - for (size_t i = 0; i < room->RegionCount; ++i) - { - if ((room->Regions[i].Tint & LEGACY_TINT_IS_ENABLED) != 0) - { - room->Regions[i].Tint &= ~LEGACY_TINT_IS_ENABLED; - // older versions of the editor had a bug - work around it - int tint_amount = (room->Regions[i].Light > 0 ? room->Regions[i].Light : 50); - room->Regions[i].Tint |= (tint_amount & 0xFF) << 24; - room->Regions[i].Light = 255; - } - } - } - - // Older format room messages had flags appended to the message string - // TODO: find out which data versions had these; is it safe to assume this was before kRoomVersion_pre114_3? - for (size_t i = 0; i < room->MessageCount; ++i) - { - if (!room->Messages[i].IsEmpty() && room->Messages[i].GetLast() == (char)ROOM_MESSAGE_FLAG_DISPLAYNEXT) - { - room->Messages[i].ClipRight(1); - room->MessageInfos[i].Flags |= MSG_DISPLAYNEXT; - } - } - - // sync bpalettes[0] with room.pal - memcpy(room->BgFrames[0].Palette, room->Palette, sizeof(color) * 256); - return HRoomFileError::None(); +HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool game_is_hires, const std::vector &sprinfos) { + if (data_ver < kRoomVersion_200_final) + room->MaskResolution = room->BgFrames[0].Graphic->GetWidth() > 320 ? kRoomHiRes : kRoomLoRes; + if (data_ver < kRoomVersion_3508) { + // Save legacy resolution if it DOES NOT match game's; + // otherwise it gets promoted to "real resolution" + if (room->MaskResolution == 1 && game_is_hires) + room->SetResolution(kRoomLoRes); + else if (room->MaskResolution > 1 && !game_is_hires) + room->SetResolution(kRoomHiRes); + } + + // Old version - copy walkable areas to regions + if (data_ver < kRoomVersion_255b) { + if (!room->RegionMask) + room->RegionMask.reset(BitmapHelper::CreateBitmap(room->WalkAreaMask->GetWidth(), room->WalkAreaMask->GetHeight(), 8)); + room->RegionMask->Blit(room->WalkAreaMask.get(), 0, 0, 0, 0, room->RegionMask->GetWidth(), room->RegionMask->GetHeight()); + for (size_t i = 0; i < MAX_ROOM_REGIONS; ++i) { + room->Regions[i].Light = room->WalkAreas[i].Light; + room->Regions[i].Tint = 255; + } + } + + // Fill in dummy interaction objects into unused slots + // TODO: remove this later, need to rework the legacy interaction usage around the engine code to prevent crashes + if (data_ver < kRoomVersion_300a) { + if (!room->Interaction) + room->Interaction.reset(new Interaction()); + for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) + if (!room->Hotspots[i].Interaction) + room->Hotspots[i].Interaction.reset(new Interaction()); + for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) + if (!room->Objects[i].Interaction) + room->Objects[i].Interaction.reset(new Interaction()); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + if (!room->Regions[i].Interaction) + room->Regions[i].Interaction.reset(new Interaction()); + } + + // Upgade room object script names + if (data_ver < kRoomVersion_300a) { + for (size_t i = 0; i < room->ObjectCount; ++i) { + if (room->Objects[i].ScriptName.GetLength() > 0) { + String jibbledScriptName; + jibbledScriptName.Format("o%s", room->Objects[i].ScriptName.GetCStr()); + jibbledScriptName.MakeLower(); + if (jibbledScriptName.GetLength() >= 2) + jibbledScriptName.SetAt(1, toupper(jibbledScriptName[1u])); + room->Objects[i].ScriptName = jibbledScriptName; + } + } + } + + // Pre-3.0.3, multiply up co-ordinates for high-res games to bring them + // to the proper game coordinate system. + // If you change this, also change convert_room_coordinates_to_data_res + // function in the engine + if (data_ver < kRoomVersion_303b && game_is_hires) { + const int mul = HIRES_COORD_MULTIPLIER; + for (size_t i = 0; i < room->ObjectCount; ++i) { + room->Objects[i].X *= mul; + room->Objects[i].Y *= mul; + if (room->Objects[i].Baseline > 0) { + room->Objects[i].Baseline *= mul; + } + } + + for (size_t i = 0; i < room->HotspotCount; ++i) { + room->Hotspots[i].WalkTo.X *= mul; + room->Hotspots[i].WalkTo.Y *= mul; + } + + for (size_t i = 0; i < room->WalkBehindCount; ++i) { + room->WalkBehinds[i].Baseline *= mul; + } + + room->Edges.Left *= mul; + room->Edges.Top *= mul; + room->Edges.Bottom *= mul; + room->Edges.Right *= mul; + room->Width *= mul; + room->Height *= mul; + } + + // Adjust object Y coordinate by adding sprite's height + // NOTE: this is impossible to do without game sprite information loaded beforehand + // NOTE: this should be done after coordinate conversion above for simplicity + if (data_ver < kRoomVersion_300a) { + for (size_t i = 0; i < room->ObjectCount; ++i) + room->Objects[i].Y += sprinfos[room->Objects[i].Sprite].Height; + } + + if (data_ver >= kRoomVersion_251) { + // if they set a contiuously scaled area where the top + // and bottom zoom levels are identical, set it as a normal + // scaled area + for (size_t i = 0; i < room->WalkAreaCount; ++i) { + if (room->WalkAreas[i].ScalingFar == room->WalkAreas[i].ScalingNear) + room->WalkAreas[i].ScalingNear = NOT_VECTOR_SCALED; + } + } + + // Convert the old format region tint saturation + if (data_ver < kRoomVersion_3404) { + for (size_t i = 0; i < room->RegionCount; ++i) { + if ((room->Regions[i].Tint & LEGACY_TINT_IS_ENABLED) != 0) { + room->Regions[i].Tint &= ~LEGACY_TINT_IS_ENABLED; + // older versions of the editor had a bug - work around it + int tint_amount = (room->Regions[i].Light > 0 ? room->Regions[i].Light : 50); + room->Regions[i].Tint |= (tint_amount & 0xFF) << 24; + room->Regions[i].Light = 255; + } + } + } + + // Older format room messages had flags appended to the message string + // TODO: find out which data versions had these; is it safe to assume this was before kRoomVersion_pre114_3? + for (size_t i = 0; i < room->MessageCount; ++i) { + if (!room->Messages[i].IsEmpty() && room->Messages[i].GetLast() == (char)ROOM_MESSAGE_FLAG_DISPLAYNEXT) { + room->Messages[i].ClipRight(1); + room->MessageInfos[i].Flags |= MSG_DISPLAYNEXT; + } + } + + // sync bpalettes[0] with room.pal + memcpy(room->BgFrames[0].Palette, room->Palette, sizeof(color) * 256); + return HRoomFileError::None(); } -HRoomFileError ExtractScriptText(String &script, Stream *in, RoomFileVersion data_ver) -{ - RoomFileBlock block; - do - { - int b = in->ReadByte(); - if (b < 0) - return new RoomFileError(kRoomFileErr_UnexpectedEOF); - block = (RoomFileBlock)b; - soff_t block_len = data_ver < kRoomVersion_350 ? in->ReadInt32() : in->ReadInt64(); - if (block == kRoomFblk_Script) - { - char *buf = nullptr; - HRoomFileError err = ReadScriptBlock(buf, in, data_ver); - if (err) - { - script = buf; - delete buf; - } - return err; - } - if (block != kRoomFile_EOF) - in->Seek(block_len); // skip block - } while (block != kRoomFile_EOF); - return new RoomFileError(kRoomFileErr_BlockNotFound); +HRoomFileError ExtractScriptText(String &script, Stream *in, RoomFileVersion data_ver) { + RoomFileBlock block; + do { + int b = in->ReadByte(); + if (b < 0) + return new RoomFileError(kRoomFileErr_UnexpectedEOF); + block = (RoomFileBlock)b; + soff_t block_len = data_ver < kRoomVersion_350 ? in->ReadInt32() : in->ReadInt64(); + if (block == kRoomFblk_Script) { + char *buf = nullptr; + HRoomFileError err = ReadScriptBlock(buf, in, data_ver); + if (err) { + script = buf; + delete buf; + } + return err; + } + if (block != kRoomFile_EOF) + in->Seek(block_len); // skip block + } while (block != kRoomFile_EOF); + return new RoomFileError(kRoomFileErr_BlockNotFound); } // Type of function that writes single room block. typedef void(*PfnWriteBlock)(const RoomStruct *room, Stream *out); // Generic function that saves a block and automatically adds its size into header -void WriteBlock(const RoomStruct *room, RoomFileBlock block, PfnWriteBlock writer, Stream *out) -{ - // Write block's header - out->WriteByte(block); - soff_t sz_at = out->GetPosition(); - out->WriteInt64(0); // block size placeholder - // Call writer to save actual block contents - writer(room, out); - - // Now calculate the block's size... - soff_t end_at = out->GetPosition(); - soff_t block_size = (end_at - sz_at) - sizeof(int64_t); - // ...return back and write block's size in the placeholder - out->Seek(sz_at, Common::kSeekBegin); - out->WriteInt64(block_size); - // ...and get back to the end of the file - out->Seek(0, Common::kSeekEnd); +void WriteBlock(const RoomStruct *room, RoomFileBlock block, PfnWriteBlock writer, Stream *out) { + // Write block's header + out->WriteByte(block); + soff_t sz_at = out->GetPosition(); + out->WriteInt64(0); // block size placeholder + // Call writer to save actual block contents + writer(room, out); + + // Now calculate the block's size... + soff_t end_at = out->GetPosition(); + soff_t block_size = (end_at - sz_at) - sizeof(int64_t); + // ...return back and write block's size in the placeholder + out->Seek(sz_at, Common::kSeekBegin); + out->WriteInt64(block_size); + // ...and get back to the end of the file + out->Seek(0, Common::kSeekEnd); } -void WriteInteractionScripts(const InteractionScripts *interactions, Stream *out) -{ - out->WriteInt32(interactions->ScriptFuncNames.size()); - for (size_t i = 0; i < interactions->ScriptFuncNames.size(); ++i) - interactions->ScriptFuncNames[i].Write(out); +void WriteInteractionScripts(const InteractionScripts *interactions, Stream *out) { + out->WriteInt32(interactions->ScriptFuncNames.size()); + for (size_t i = 0; i < interactions->ScriptFuncNames.size(); ++i) + interactions->ScriptFuncNames[i].Write(out); } -void WriteMainBlock(const RoomStruct *room, Stream *out) -{ - out->WriteInt32(room->BackgroundBPP); - out->WriteInt16((int16_t)room->WalkBehindCount); - for (size_t i = 0; i < room->WalkBehindCount; ++i) - out->WriteInt16(room->WalkBehinds[i].Baseline); - - out->WriteInt32(room->HotspotCount); - for (size_t i = 0; i < room->HotspotCount; ++i) - { - out->WriteInt16(room->Hotspots[i].WalkTo.X); - out->WriteInt16(room->Hotspots[i].WalkTo.Y); - } - for (size_t i = 0; i < room->HotspotCount; ++i) - Common::StrUtil::WriteString(room->Hotspots[i].Name, out); - for (size_t i = 0; i < room->HotspotCount; ++i) - Common::StrUtil::WriteString(room->Hotspots[i].ScriptName, out); - - out->WriteInt32(0); // legacy poly-point areas - - out->WriteInt16(room->Edges.Top); - out->WriteInt16(room->Edges.Bottom); - out->WriteInt16(room->Edges.Left); - out->WriteInt16(room->Edges.Right); - - out->WriteInt16((int16_t)room->ObjectCount); - for (size_t i = 0; i < room->ObjectCount; ++i) - { - WriteRoomObject(room->Objects[i], out); - } - - out->WriteInt32(0); // legacy interaction vars - out->WriteInt32(MAX_ROOM_REGIONS); - - WriteInteractionScripts(room->EventHandlers.get(), out); - for (size_t i = 0; i < room->HotspotCount; ++i) - WriteInteractionScripts(room->Hotspots[i].EventHandlers.get(), out); - for (size_t i = 0; i < room->ObjectCount; ++i) - WriteInteractionScripts(room->Objects[i].EventHandlers.get(), out); - for (size_t i = 0; i < room->RegionCount; ++i) - WriteInteractionScripts(room->Regions[i].EventHandlers.get(), out); - - for (size_t i = 0; i < room->ObjectCount; ++i) - out->WriteInt32(room->Objects[i].Baseline); - out->WriteInt16(room->Width); - out->WriteInt16(room->Height); - for (size_t i = 0; i < room->ObjectCount; ++i) - out->WriteInt16(room->Objects[i].Flags); - out->WriteInt16(room->MaskResolution); - - out->WriteInt32(MAX_WALK_AREAS + 1); - for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) - out->WriteInt16(room->WalkAreas[i].ScalingFar); - for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) - out->WriteInt16(room->WalkAreas[i].Light); - for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) - out->WriteInt16(room->WalkAreas[i].ScalingNear); - for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) - out->WriteInt16(room->WalkAreas[i].Top); - for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) - out->WriteInt16(room->WalkAreas[i].Bottom); - - out->WriteByteCount(0, LEGACY_ROOM_PASSWORD_LENGTH); - out->WriteInt8(room->Options.StartupMusic); - out->WriteInt8(room->Options.SaveLoadDisabled ? 1 : 0); - out->WriteInt8(room->Options.PlayerCharOff ? 1 : 0); - out->WriteInt8(room->Options.PlayerView); - out->WriteInt8(room->Options.MusicVolume); - out->WriteByteCount(0, ROOM_LEGACY_OPTIONS_SIZE - 5); - out->WriteInt16((int16_t)room->MessageCount); - out->WriteInt32(room->GameID); - for (size_t i = 0; i < room->MessageCount; ++i) - { - out->WriteInt8(room->MessageInfos[i].DisplayAs); - out->WriteInt8(room->MessageInfos[i].Flags); - } - for (size_t i = 0; i < room->MessageCount; ++i) - write_string_encrypt(out, room->Messages[i]); - - out->WriteInt16(0); // legacy room animations - - for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) - out->WriteInt16(room->WalkAreas[i].Light); - for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) - out->WriteInt16(room->Regions[i].Light); - for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) - out->WriteInt32(room->Regions[i].Tint); - - save_lzw(out, room->BgFrames[0].Graphic.get(), room->Palette); - savecompressed_allegro(out, room->RegionMask.get(), room->Palette); - savecompressed_allegro(out, room->WalkAreaMask.get(), room->Palette); - savecompressed_allegro(out, room->WalkBehindMask.get(), room->Palette); - savecompressed_allegro(out, room->HotspotMask.get(), room->Palette); +void WriteMainBlock(const RoomStruct *room, Stream *out) { + out->WriteInt32(room->BackgroundBPP); + out->WriteInt16((int16_t)room->WalkBehindCount); + for (size_t i = 0; i < room->WalkBehindCount; ++i) + out->WriteInt16(room->WalkBehinds[i].Baseline); + + out->WriteInt32(room->HotspotCount); + for (size_t i = 0; i < room->HotspotCount; ++i) { + out->WriteInt16(room->Hotspots[i].WalkTo.X); + out->WriteInt16(room->Hotspots[i].WalkTo.Y); + } + for (size_t i = 0; i < room->HotspotCount; ++i) + Common::StrUtil::WriteString(room->Hotspots[i].Name, out); + for (size_t i = 0; i < room->HotspotCount; ++i) + Common::StrUtil::WriteString(room->Hotspots[i].ScriptName, out); + + out->WriteInt32(0); // legacy poly-point areas + + out->WriteInt16(room->Edges.Top); + out->WriteInt16(room->Edges.Bottom); + out->WriteInt16(room->Edges.Left); + out->WriteInt16(room->Edges.Right); + + out->WriteInt16((int16_t)room->ObjectCount); + for (size_t i = 0; i < room->ObjectCount; ++i) { + WriteRoomObject(room->Objects[i], out); + } + + out->WriteInt32(0); // legacy interaction vars + out->WriteInt32(MAX_ROOM_REGIONS); + + WriteInteractionScripts(room->EventHandlers.get(), out); + for (size_t i = 0; i < room->HotspotCount; ++i) + WriteInteractionScripts(room->Hotspots[i].EventHandlers.get(), out); + for (size_t i = 0; i < room->ObjectCount; ++i) + WriteInteractionScripts(room->Objects[i].EventHandlers.get(), out); + for (size_t i = 0; i < room->RegionCount; ++i) + WriteInteractionScripts(room->Regions[i].EventHandlers.get(), out); + + for (size_t i = 0; i < room->ObjectCount; ++i) + out->WriteInt32(room->Objects[i].Baseline); + out->WriteInt16(room->Width); + out->WriteInt16(room->Height); + for (size_t i = 0; i < room->ObjectCount; ++i) + out->WriteInt16(room->Objects[i].Flags); + out->WriteInt16(room->MaskResolution); + + out->WriteInt32(MAX_WALK_AREAS + 1); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].ScalingFar); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Light); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].ScalingNear); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Top); + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Bottom); + + out->WriteByteCount(0, LEGACY_ROOM_PASSWORD_LENGTH); + out->WriteInt8(room->Options.StartupMusic); + out->WriteInt8(room->Options.SaveLoadDisabled ? 1 : 0); + out->WriteInt8(room->Options.PlayerCharOff ? 1 : 0); + out->WriteInt8(room->Options.PlayerView); + out->WriteInt8(room->Options.MusicVolume); + out->WriteByteCount(0, ROOM_LEGACY_OPTIONS_SIZE - 5); + out->WriteInt16((int16_t)room->MessageCount); + out->WriteInt32(room->GameID); + for (size_t i = 0; i < room->MessageCount; ++i) { + out->WriteInt8(room->MessageInfos[i].DisplayAs); + out->WriteInt8(room->MessageInfos[i].Flags); + } + for (size_t i = 0; i < room->MessageCount; ++i) + write_string_encrypt(out, room->Messages[i]); + + out->WriteInt16(0); // legacy room animations + + for (size_t i = 0; i < (size_t)MAX_WALK_AREAS + 1; ++i) + out->WriteInt16(room->WalkAreas[i].Light); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + out->WriteInt16(room->Regions[i].Light); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + out->WriteInt32(room->Regions[i].Tint); + + save_lzw(out, room->BgFrames[0].Graphic.get(), room->Palette); + savecompressed_allegro(out, room->RegionMask.get(), room->Palette); + savecompressed_allegro(out, room->WalkAreaMask.get(), room->Palette); + savecompressed_allegro(out, room->WalkBehindMask.get(), room->Palette); + savecompressed_allegro(out, room->HotspotMask.get(), room->Palette); } -void WriteCompSc3Block(const RoomStruct *room, Stream *out) -{ - room->CompiledScript->Write(out); +void WriteCompSc3Block(const RoomStruct *room, Stream *out) { + room->CompiledScript->Write(out); } -void WriteObjNamesBlock(const RoomStruct *room, Stream *out) -{ - out->WriteByte((int8_t)room->ObjectCount); - for (size_t i = 0; i < room->ObjectCount; ++i) - Common::StrUtil::WriteString(room->Objects[i].Name, out); +void WriteObjNamesBlock(const RoomStruct *room, Stream *out) { + out->WriteByte((int8_t)room->ObjectCount); + for (size_t i = 0; i < room->ObjectCount; ++i) + Common::StrUtil::WriteString(room->Objects[i].Name, out); } -void WriteObjScNamesBlock(const RoomStruct *room, Stream *out) -{ - out->WriteByte((int8_t)room->ObjectCount); - for (size_t i = 0; i < room->ObjectCount; ++i) - Common::StrUtil::WriteString(room->Objects[i].ScriptName, out); +void WriteObjScNamesBlock(const RoomStruct *room, Stream *out) { + out->WriteByte((int8_t)room->ObjectCount); + for (size_t i = 0; i < room->ObjectCount; ++i) + Common::StrUtil::WriteString(room->Objects[i].ScriptName, out); } -void WriteAnimBgBlock(const RoomStruct *room, Stream *out) -{ - out->WriteByte((int8_t)room->BgFrameCount); - out->WriteByte(room->BgAnimSpeed); +void WriteAnimBgBlock(const RoomStruct *room, Stream *out) { + out->WriteByte((int8_t)room->BgFrameCount); + out->WriteByte(room->BgAnimSpeed); - for (size_t i = 0; i < room->BgFrameCount; ++i) - out->WriteInt8(room->BgFrames[i].IsPaletteShared ? 1 : 0); - for (size_t i = 1; i < room->BgFrameCount; ++i) - save_lzw(out, room->BgFrames[i].Graphic.get(), room->BgFrames[i].Palette); + for (size_t i = 0; i < room->BgFrameCount; ++i) + out->WriteInt8(room->BgFrames[i].IsPaletteShared ? 1 : 0); + for (size_t i = 1; i < room->BgFrameCount; ++i) + save_lzw(out, room->BgFrames[i].Graphic.get(), room->BgFrames[i].Palette); } -void WritePropertiesBlock(const RoomStruct *room, Stream *out) -{ - out->WriteInt32(1); // Version 1 of properties block - Properties::WriteValues(room->Properties, out); - for (size_t i = 0; i < room->HotspotCount; ++i) - Properties::WriteValues(room->Hotspots[i].Properties, out); - for (size_t i = 0; i < room->ObjectCount; ++i) - Properties::WriteValues(room->Objects[i].Properties, out); +void WritePropertiesBlock(const RoomStruct *room, Stream *out) { + out->WriteInt32(1); // Version 1 of properties block + Properties::WriteValues(room->Properties, out); + for (size_t i = 0; i < room->HotspotCount; ++i) + Properties::WriteValues(room->Hotspots[i].Properties, out); + for (size_t i = 0; i < room->ObjectCount; ++i) + Properties::WriteValues(room->Objects[i].Properties, out); } -HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersion data_ver) -{ - if (data_ver < kRoomVersion_Current) - return new RoomFileError(kRoomFileErr_FormatNotSupported, "We no longer support saving room in the older format."); - - // Header - out->WriteInt16(data_ver); - // Main data - WriteBlock(room, kRoomFblk_Main, WriteMainBlock, out); - // Compiled script - if (room->CompiledScript) - WriteBlock(room, kRoomFblk_CompScript3, WriteCompSc3Block, out); - // Object names - if (room->ObjectCount > 0) - { - WriteBlock(room, kRoomFblk_ObjectNames, WriteObjNamesBlock, out); - WriteBlock(room, kRoomFblk_ObjectScNames, WriteObjScNamesBlock, out); - } - // Secondary background frames - if (room->BgFrameCount > 1) - WriteBlock(room, kRoomFblk_AnimBg, WriteAnimBgBlock, out); - // Custom properties - WriteBlock(room, kRoomFblk_Properties, WritePropertiesBlock, out); - - // Write end of room file - out->WriteByte(kRoomFile_EOF); - return HRoomFileError::None(); +HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersion data_ver) { + if (data_ver < kRoomVersion_Current) + return new RoomFileError(kRoomFileErr_FormatNotSupported, "We no longer support saving room in the older format."); + + // Header + out->WriteInt16(data_ver); + // Main data + WriteBlock(room, kRoomFblk_Main, WriteMainBlock, out); + // Compiled script + if (room->CompiledScript) + WriteBlock(room, kRoomFblk_CompScript3, WriteCompSc3Block, out); + // Object names + if (room->ObjectCount > 0) { + WriteBlock(room, kRoomFblk_ObjectNames, WriteObjNamesBlock, out); + WriteBlock(room, kRoomFblk_ObjectScNames, WriteObjScNamesBlock, out); + } + // Secondary background frames + if (room->BgFrameCount > 1) + WriteBlock(room, kRoomFblk_AnimBg, WriteAnimBgBlock, out); + // Custom properties + WriteBlock(room, kRoomFblk_Properties, WritePropertiesBlock, out); + + // Write end of room file + out->WriteByte(kRoomFile_EOF); + return HRoomFileError::None(); } } // namespace Common diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index 727a97c47625..0a08f66597bc 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -39,28 +39,25 @@ #include "util/string.h" struct SpriteInfo; -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class RoomStruct; -enum RoomFileErrorType -{ - kRoomFileErr_NoError, - kRoomFileErr_FileOpenFailed, - kRoomFileErr_FormatNotSupported, - kRoomFileErr_UnexpectedEOF, - kRoomFileErr_UnknownBlockType, - kRoomFileErr_OldBlockNotSupported, - kRoomFileErr_BlockDataOverlapping, - kRoomFileErr_IncompatibleEngine, - kRoomFileErr_ScriptLoadFailed, - kRoomFileErr_InconsistentData, - kRoomFileErr_PropertiesBlockFormat, - kRoomFileErr_InvalidPropertyValues, - kRoomFileErr_BlockNotFound +enum RoomFileErrorType { + kRoomFileErr_NoError, + kRoomFileErr_FileOpenFailed, + kRoomFileErr_FormatNotSupported, + kRoomFileErr_UnexpectedEOF, + kRoomFileErr_UnknownBlockType, + kRoomFileErr_OldBlockNotSupported, + kRoomFileErr_BlockDataOverlapping, + kRoomFileErr_IncompatibleEngine, + kRoomFileErr_ScriptLoadFailed, + kRoomFileErr_InconsistentData, + kRoomFileErr_PropertiesBlockFormat, + kRoomFileErr_InvalidPropertyValues, + kRoomFileErr_BlockNotFound }; String GetRoomFileErrorText(RoomFileErrorType err); @@ -71,16 +68,15 @@ typedef std::shared_ptr PStream; // RoomDataSource defines a successfully opened room file -struct RoomDataSource -{ - // Name of the asset file - String Filename; - // Room file format version - RoomFileVersion DataVersion; - // A ponter to the opened stream - PStream InputStream; +struct RoomDataSource { + // Name of the asset file + String Filename; + // Room file format version + RoomFileVersion DataVersion; + // A ponter to the opened stream + PStream InputStream; - RoomDataSource(); + RoomDataSource(); }; // Opens room file for reading from an arbitrary file diff --git a/engines/ags/shared/game/room_file_deprecated.cpp b/engines/ags/shared/game/room_file_deprecated.cpp index d902751ad7bf..7fdae6e1f501 100644 --- a/engines/ags/shared/game/room_file_deprecated.cpp +++ b/engines/ags/shared/game/room_file_deprecated.cpp @@ -37,68 +37,71 @@ using namespace AGS::Common; #define AE_WAITFLAG 0x80000000 #define MAXANIMSTAGES 10 -struct AnimationStruct -{ - int x, y; - int data; - int object; - int speed; - char action; - char wait; - AnimationStruct() { action = 0; object = 0; wait = 1; speed = 5; } +struct AnimationStruct { + int x, y; + int data; + int object; + int speed; + char action; + char wait; + AnimationStruct() { + action = 0; + object = 0; + wait = 1; + speed = 5; + } }; -struct FullAnimation -{ - AnimationStruct stage[MAXANIMSTAGES]; - int numstages; - FullAnimation() { numstages = 0; } +struct FullAnimation { + AnimationStruct stage[MAXANIMSTAGES]; + int numstages; + FullAnimation() { + numstages = 0; + } }; #define MAXPOINTS 30 -struct PolyPoints -{ - int x[MAXPOINTS]; - int y[MAXPOINTS]; - int numpoints; - void add_point(int x, int y); - PolyPoints() { numpoints = 0; } - - void Read(AGS::Common::Stream *in); +struct PolyPoints { + int x[MAXPOINTS]; + int y[MAXPOINTS]; + int numpoints; + void add_point(int x, int y); + PolyPoints() { + numpoints = 0; + } + + void Read(AGS::Common::Stream *in); }; #define MAXANIMS 10 // Just a list of cut out data -struct DeprecatedRoomStruct -{ - // Full-room animations - int16_t numanims; - FullAnimation anims[MAXANIMS]; - // Polygonal walkable areas (unknown version) - int32_t numwalkareas; - PolyPoints wallpoints[MAX_WALK_AREAS]; - // Unknown flags - int16_t flagstates[MAX_FLAGS]; +struct DeprecatedRoomStruct { + // Full-room animations + int16_t numanims; + FullAnimation anims[MAXANIMS]; + // Polygonal walkable areas (unknown version) + int32_t numwalkareas; + PolyPoints wallpoints[MAX_WALK_AREAS]; + // Unknown flags + int16_t flagstates[MAX_FLAGS]; }; -void PolyPoints::add_point(int x, int y) -{ - x[numpoints] = x; - y[numpoints] = y; - numpoints++; +void PolyPoints::add_point(int x, int y) { + x[numpoints] = x; + y[numpoints] = y; + numpoints++; - if (numpoints >= MAXPOINTS) - quit("too many poly points added"); + if (numpoints >= MAXPOINTS) + quit("too many poly points added"); } -void PolyPoints::Read(Stream *in) -{ - in->ReadArrayOfInt32(x, MAXPOINTS); - in->ReadArrayOfInt32(y, MAXPOINTS); - numpoints = in->ReadInt32(); +void PolyPoints::Read(Stream *in) { + in->ReadArrayOfInt32(x, MAXPOINTS); + in->ReadArrayOfInt32(y, MAXPOINTS); + numpoints = in->ReadInt32(); } @@ -106,40 +109,35 @@ void PolyPoints::Read(Stream *in) // Pre-2.5 scripts (we don't know how to convert them for the modern engine) // #define SCRIPT_CONFIG_VERSION 1 -HRoomFileError ReadAncientScriptConfig(Stream *in) -{ - int fmt = in->ReadInt32(); - if (fmt != SCRIPT_CONFIG_VERSION) - return new RoomFileError(kRoomFileErr_FormatNotSupported, String::FromFormat("Invalid script configuration format (in room: %d, expected: %d).", fmt, SCRIPT_CONFIG_VERSION)); - - size_t var_count = in->ReadInt32(); - for (size_t i = 0; i < var_count; ++i) - { - size_t len = in->ReadByte(); - in->Seek(len); - } - return HRoomFileError::None(); +HRoomFileError ReadAncientScriptConfig(Stream *in) { + int fmt = in->ReadInt32(); + if (fmt != SCRIPT_CONFIG_VERSION) + return new RoomFileError(kRoomFileErr_FormatNotSupported, String::FromFormat("Invalid script configuration format (in room: %d, expected: %d).", fmt, SCRIPT_CONFIG_VERSION)); + + size_t var_count = in->ReadInt32(); + for (size_t i = 0; i < var_count; ++i) { + size_t len = in->ReadByte(); + in->Seek(len); + } + return HRoomFileError::None(); } -HRoomFileError ReadAncientGraphicalScripts(Stream *in) -{ - do - { - int ct = in->ReadInt32(); - if (ct == -1 || in->EOS()) - break; - size_t len = in->ReadInt32(); - in->Seek(len); - } while (true); - return HRoomFileError::None(); +HRoomFileError ReadAncientGraphicalScripts(Stream *in) { + do { + int ct = in->ReadInt32(); + if (ct == -1 || in->EOS()) + break; + size_t len = in->ReadInt32(); + in->Seek(len); + } while (true); + return HRoomFileError::None(); } -HRoomFileError ReadPre250Scripts(Stream *in) -{ - HRoomFileError err = ReadAncientScriptConfig(in); - if (err) - err = ReadAncientGraphicalScripts(in); - return err; +HRoomFileError ReadPre250Scripts(Stream *in) { + HRoomFileError err = ReadAncientScriptConfig(in); + if (err) + err = ReadAncientGraphicalScripts(in); + return err; } #endif // OBSOLETE diff --git a/engines/ags/shared/game/room_version.h b/engines/ags/shared/game/room_version.h index f5a14998e228..5c099110f822 100644 --- a/engines/ags/shared/game/room_version.h +++ b/engines/ags/shared/game/room_version.h @@ -57,40 +57,39 @@ 32: v3.5.0 - 64-bit file offsets 33: v3.5.0.8 - deprecated room resolution, added mask resolution */ -enum RoomFileVersion -{ - kRoomVersion_Undefined = 0, - kRoomVersion_pre114_3 = 3, // exact version unknown - kRoomVersion_pre114_4 = 4, // exact version unknown - kRoomVersion_pre114_5 = 5, // exact version unknown - kRoomVersion_pre114_6 = 6, // exact version unknown - kRoomVersion_114 = 8, - kRoomVersion_200_alpha = 9, - kRoomVersion_200_alpha7 = 10, - kRoomVersion_200_final = 11, - kRoomVersion_208 = 12, - kRoomVersion_214 = 13, - kRoomVersion_240 = 14, - kRoomVersion_241 = 15, - kRoomVersion_250a = 16, - kRoomVersion_250b = 17, - kRoomVersion_251 = 18, - kRoomVersion_253 = 19, - kRoomVersion_255a = 20, - kRoomVersion_255b = 21, - kRoomVersion_261 = 22, - kRoomVersion_262 = 23, - kRoomVersion_270 = 24, - kRoomVersion_272 = 25, - kRoomVersion_300a = 26, - kRoomVersion_300b = 27, - kRoomVersion_303a = 28, - kRoomVersion_303b = 29, - kRoomVersion_3404 = 30, - kRoomVersion_3415 = 31, - kRoomVersion_350 = 32, - kRoomVersion_3508 = 33, - kRoomVersion_Current = kRoomVersion_3508 +enum RoomFileVersion { + kRoomVersion_Undefined = 0, + kRoomVersion_pre114_3 = 3, // exact version unknown + kRoomVersion_pre114_4 = 4, // exact version unknown + kRoomVersion_pre114_5 = 5, // exact version unknown + kRoomVersion_pre114_6 = 6, // exact version unknown + kRoomVersion_114 = 8, + kRoomVersion_200_alpha = 9, + kRoomVersion_200_alpha7 = 10, + kRoomVersion_200_final = 11, + kRoomVersion_208 = 12, + kRoomVersion_214 = 13, + kRoomVersion_240 = 14, + kRoomVersion_241 = 15, + kRoomVersion_250a = 16, + kRoomVersion_250b = 17, + kRoomVersion_251 = 18, + kRoomVersion_253 = 19, + kRoomVersion_255a = 20, + kRoomVersion_255b = 21, + kRoomVersion_261 = 22, + kRoomVersion_262 = 23, + kRoomVersion_270 = 24, + kRoomVersion_272 = 25, + kRoomVersion_300a = 26, + kRoomVersion_300b = 27, + kRoomVersion_303a = 28, + kRoomVersion_303b = 29, + kRoomVersion_3404 = 30, + kRoomVersion_3415 = 31, + kRoomVersion_350 = 32, + kRoomVersion_3508 = 33, + kRoomVersion_Current = kRoomVersion_3508 }; #endif diff --git a/engines/ags/shared/game/roomstruct.cpp b/engines/ags/shared/game/roomstruct.cpp index 4dbbd5326326..91bb1b2e5bd1 100644 --- a/engines/ags/shared/game/roomstruct.cpp +++ b/engines/ags/shared/game/roomstruct.cpp @@ -25,308 +25,277 @@ #include "game/roomstruct.h" #include "gfx/bitmap.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { RoomOptions::RoomOptions() - : StartupMusic(0) - , SaveLoadDisabled(false) - , PlayerCharOff(false) - , PlayerView(0) - , MusicVolume(kRoomVolumeNormal) -{ + : StartupMusic(0) + , SaveLoadDisabled(false) + , PlayerCharOff(false) + , PlayerView(0) + , MusicVolume(kRoomVolumeNormal) { } RoomBgFrame::RoomBgFrame() - : IsPaletteShared(false) -{ - memset(Palette, 0, sizeof(Palette)); + : IsPaletteShared(false) { + memset(Palette, 0, sizeof(Palette)); } RoomEdges::RoomEdges() - : Left(0) - , Right(0) - , Top(0) - , Bottom(0) -{ + : Left(0) + , Right(0) + , Top(0) + , Bottom(0) { } RoomEdges::RoomEdges(int l, int r, int t, int b) - : Left(l) - , Right(r) - , Top(t) - , Bottom(b) -{ + : Left(l) + , Right(r) + , Top(t) + , Bottom(b) { } RoomObjectInfo::RoomObjectInfo() - : Sprite(0) - , X(0) - , Y(0) - , Room(-1) - , IsOn(false) - , Baseline(0xFF) - , Flags(0) -{ + : Sprite(0) + , X(0) + , Y(0) + , Room(-1) + , IsOn(false) + , Baseline(0xFF) + , Flags(0) { } RoomRegion::RoomRegion() - : Light(0) - , Tint(0) -{ + : Light(0) + , Tint(0) { } WalkArea::WalkArea() - : CharacterView(0) - , ScalingFar(0) - , ScalingNear(NOT_VECTOR_SCALED) - , Light(0) - , Top(-1) - , Bottom(-1) -{ + : CharacterView(0) + , ScalingFar(0) + , ScalingNear(NOT_VECTOR_SCALED) + , Light(0) + , Top(-1) + , Bottom(-1) { } WalkBehind::WalkBehind() - : Baseline(0) -{ + : Baseline(0) { } MessageInfo::MessageInfo() - : DisplayAs(0) - , Flags(0) -{ + : DisplayAs(0) + , Flags(0) { } -RoomStruct::RoomStruct() -{ - InitDefaults(); +RoomStruct::RoomStruct() { + InitDefaults(); } -RoomStruct::~RoomStruct() -{ - Free(); +RoomStruct::~RoomStruct() { + Free(); } -void RoomStruct::Free() -{ - for (size_t i = 0; i < (size_t)MAX_ROOM_BGFRAMES; ++i) - BgFrames[i].Graphic.reset(); - HotspotMask.reset(); - RegionMask.reset(); - WalkAreaMask.reset(); - WalkBehindMask.reset(); - - LocalVariables.clear(); - Interaction.reset(); - Properties.clear(); - for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) - { - Hotspots[i].Interaction.reset(); - Hotspots[i].Properties.clear(); - } - for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) - { - Objects[i].Interaction.reset(); - Objects[i].Properties.clear(); - } - for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) - { - Regions[i].Interaction.reset(); - Regions[i].Properties.clear(); - } - - FreeMessages(); - FreeScripts(); +void RoomStruct::Free() { + for (size_t i = 0; i < (size_t)MAX_ROOM_BGFRAMES; ++i) + BgFrames[i].Graphic.reset(); + HotspotMask.reset(); + RegionMask.reset(); + WalkAreaMask.reset(); + WalkBehindMask.reset(); + + LocalVariables.clear(); + Interaction.reset(); + Properties.clear(); + for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) { + Hotspots[i].Interaction.reset(); + Hotspots[i].Properties.clear(); + } + for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) { + Objects[i].Interaction.reset(); + Objects[i].Properties.clear(); + } + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) { + Regions[i].Interaction.reset(); + Regions[i].Properties.clear(); + } + + FreeMessages(); + FreeScripts(); } -void RoomStruct::FreeMessages() -{ - for (size_t i = 0; i < MessageCount; ++i) - { - Messages[i].Free(); - MessageInfos[i] = MessageInfo(); - } - MessageCount = 0; +void RoomStruct::FreeMessages() { + for (size_t i = 0; i < MessageCount; ++i) { + Messages[i].Free(); + MessageInfos[i] = MessageInfo(); + } + MessageCount = 0; } -void RoomStruct::FreeScripts() -{ - CompiledScript.reset(); - - EventHandlers.reset(); - for (size_t i = 0; i < HotspotCount; ++i) - Hotspots[i].EventHandlers.reset(); - for (size_t i = 0; i < ObjectCount; ++i) - Objects[i].EventHandlers.reset(); - for (size_t i = 0; i < RegionCount; ++i) - Regions[i].EventHandlers.reset(); +void RoomStruct::FreeScripts() { + CompiledScript.reset(); + + EventHandlers.reset(); + for (size_t i = 0; i < HotspotCount; ++i) + Hotspots[i].EventHandlers.reset(); + for (size_t i = 0; i < ObjectCount; ++i) + Objects[i].EventHandlers.reset(); + for (size_t i = 0; i < RegionCount; ++i) + Regions[i].EventHandlers.reset(); } -void RoomStruct::InitDefaults() -{ - DataVersion = kRoomVersion_Current; - GameID = NO_GAME_ID_IN_ROOM_FILE; - - _resolution = kRoomRealRes; - MaskResolution = 1; - Width = 320; - Height = 200; - - Options = RoomOptions(); - Edges = RoomEdges(0, 317, 40, 199); - - BgFrameCount = 1; - HotspotCount = 0; - ObjectCount = 0; - RegionCount = 0; - WalkAreaCount = 0; - WalkBehindCount = 0; - MessageCount = 0; - - for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) - { - Hotspots[i] = RoomHotspot(); - if (i == 0) - Hotspots[i].Name = "No hotspot"; - else - Hotspots[i].Name.Format("Hotspot %u", i); - } - for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) - Objects[i] = RoomObjectInfo(); - for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) - Regions[i] = RoomRegion(); - for (size_t i = 0; i <= (size_t)MAX_WALK_AREAS; ++i) - WalkAreas[i] = WalkArea(); - for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i) - WalkBehinds[i] = WalkBehind(); - - BackgroundBPP = 1; - BgAnimSpeed = 5; - - memset(Palette, 0, sizeof(Palette)); +void RoomStruct::InitDefaults() { + DataVersion = kRoomVersion_Current; + GameID = NO_GAME_ID_IN_ROOM_FILE; + + _resolution = kRoomRealRes; + MaskResolution = 1; + Width = 320; + Height = 200; + + Options = RoomOptions(); + Edges = RoomEdges(0, 317, 40, 199); + + BgFrameCount = 1; + HotspotCount = 0; + ObjectCount = 0; + RegionCount = 0; + WalkAreaCount = 0; + WalkBehindCount = 0; + MessageCount = 0; + + for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) { + Hotspots[i] = RoomHotspot(); + if (i == 0) + Hotspots[i].Name = "No hotspot"; + else + Hotspots[i].Name.Format("Hotspot %u", i); + } + for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) + Objects[i] = RoomObjectInfo(); + for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) + Regions[i] = RoomRegion(); + for (size_t i = 0; i <= (size_t)MAX_WALK_AREAS; ++i) + WalkAreas[i] = WalkArea(); + for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i) + WalkBehinds[i] = WalkBehind(); + + BackgroundBPP = 1; + BgAnimSpeed = 5; + + memset(Palette, 0, sizeof(Palette)); } -void RoomStruct::SetResolution(RoomResolutionType type) -{ - _resolution = type; +void RoomStruct::SetResolution(RoomResolutionType type) { + _resolution = type; } -Bitmap *RoomStruct::GetMask(RoomAreaMask mask) const -{ - switch (mask) - { - case kRoomAreaHotspot: return HotspotMask.get(); - case kRoomAreaWalkBehind: return WalkBehindMask.get(); - case kRoomAreaWalkable: return WalkAreaMask.get(); - case kRoomAreaRegion: return RegionMask.get(); - } - return nullptr; +Bitmap *RoomStruct::GetMask(RoomAreaMask mask) const { + switch (mask) { + case kRoomAreaHotspot: + return HotspotMask.get(); + case kRoomAreaWalkBehind: + return WalkBehindMask.get(); + case kRoomAreaWalkable: + return WalkAreaMask.get(); + case kRoomAreaRegion: + return RegionMask.get(); + } + return nullptr; } -float RoomStruct::GetMaskScale(RoomAreaMask mask) const -{ - switch (mask) - { - case kRoomAreaWalkBehind: return 1.f; // walk-behinds always 1:1 with room size - case kRoomAreaHotspot: - case kRoomAreaWalkable: - case kRoomAreaRegion: - return 1.f / MaskResolution; - } - return 0.f; +float RoomStruct::GetMaskScale(RoomAreaMask mask) const { + switch (mask) { + case kRoomAreaWalkBehind: + return 1.f; // walk-behinds always 1:1 with room size + case kRoomAreaHotspot: + case kRoomAreaWalkable: + case kRoomAreaRegion: + return 1.f / MaskResolution; + } + return 0.f; } -bool RoomStruct::HasRegionLightLevel(int id) const -{ - if (id >= 0 && id < MAX_ROOM_REGIONS) - return Regions[id].Tint == 0; - return false; +bool RoomStruct::HasRegionLightLevel(int id) const { + if (id >= 0 && id < MAX_ROOM_REGIONS) + return Regions[id].Tint == 0; + return false; } -bool RoomStruct::HasRegionTint(int id) const -{ - if (id >= 0 && id < MAX_ROOM_REGIONS) - return Regions[id].Tint != 0; - return false; +bool RoomStruct::HasRegionTint(int id) const { + if (id >= 0 && id < MAX_ROOM_REGIONS) + return Regions[id].Tint != 0; + return false; } -int RoomStruct::GetRegionLightLevel(int id) const -{ - if (id >= 0 && id < MAX_ROOM_REGIONS) - return HasRegionLightLevel(id) ? Regions[id].Light : 0; - return 0; +int RoomStruct::GetRegionLightLevel(int id) const { + if (id >= 0 && id < MAX_ROOM_REGIONS) + return HasRegionLightLevel(id) ? Regions[id].Light : 0; + return 0; } -int RoomStruct::GetRegionTintLuminance(int id) const -{ - if (id >= 0 && id < MAX_ROOM_REGIONS) - return HasRegionTint(id) ? (Regions[id].Light * 10) / 25 : 0; - return 0; +int RoomStruct::GetRegionTintLuminance(int id) const { + if (id >= 0 && id < MAX_ROOM_REGIONS) + return HasRegionTint(id) ? (Regions[id].Light * 10) / 25 : 0; + return 0; } -void load_room(const char *filename, RoomStruct *room, bool game_is_hires, const std::vector &sprinfos) -{ - room->Free(); - room->InitDefaults(); - - update_polled_stuff_if_runtime(); - - RoomDataSource src; - HRoomFileError err = OpenRoomFile(filename, src); - if (err) - { - update_polled_stuff_if_runtime(); // it can take a while to load the file sometimes - err = ReadRoomData(room, src.InputStream.get(), src.DataVersion); - if (err) - err = UpdateRoomData(room, src.DataVersion, game_is_hires, sprinfos); - } - if (!err) - quitprintf("Unable to load the room file '%s'.\n%s.", filename, err->FullMessage().GetCStr()); +void load_room(const char *filename, RoomStruct *room, bool game_is_hires, const std::vector &sprinfos) { + room->Free(); + room->InitDefaults(); + + update_polled_stuff_if_runtime(); + + RoomDataSource src; + HRoomFileError err = OpenRoomFile(filename, src); + if (err) { + update_polled_stuff_if_runtime(); // it can take a while to load the file sometimes + err = ReadRoomData(room, src.InputStream.get(), src.DataVersion); + if (err) + err = UpdateRoomData(room, src.DataVersion, game_is_hires, sprinfos); + } + if (!err) + quitprintf("Unable to load the room file '%s'.\n%s.", filename, err->FullMessage().GetCStr()); } -PBitmap FixBitmap(PBitmap bmp, int width, int height) -{ - Bitmap *new_bmp = BitmapHelper::AdjustBitmapSize(bmp.get(), width, height); - if (new_bmp != bmp.get()) - return PBitmap(new_bmp); - return bmp; +PBitmap FixBitmap(PBitmap bmp, int width, int height) { + Bitmap *new_bmp = BitmapHelper::AdjustBitmapSize(bmp.get(), width, height); + if (new_bmp != bmp.get()) + return PBitmap(new_bmp); + return bmp; } -void UpscaleRoomBackground(RoomStruct *room, bool game_is_hires) -{ - if (room->DataVersion >= kRoomVersion_303b || !game_is_hires) - return; - for (size_t i = 0; i < room->BgFrameCount; ++i) - room->BgFrames[i].Graphic = FixBitmap(room->BgFrames[i].Graphic, room->Width, room->Height); - FixRoomMasks(room); +void UpscaleRoomBackground(RoomStruct *room, bool game_is_hires) { + if (room->DataVersion >= kRoomVersion_303b || !game_is_hires) + return; + for (size_t i = 0; i < room->BgFrameCount; ++i) + room->BgFrames[i].Graphic = FixBitmap(room->BgFrames[i].Graphic, room->Width, room->Height); + FixRoomMasks(room); } -void FixRoomMasks(RoomStruct *room) -{ - if (room->MaskResolution <= 0) - return; - Bitmap *bkg = room->BgFrames[0].Graphic.get(); - if (bkg == nullptr) - return; - // TODO: this issue is somewhat complicated. Original code was relying on - // room->Width and Height properties. But in the engine these are saved - // already converted to data resolution which may be "low-res". Since this - // function is shared between engine and editor we do not know if we need - // to upscale them. - // For now room width/height is always equal to background bitmap. - int base_width = bkg->GetWidth(); - int base_height = bkg->GetHeight(); - int low_width = base_width / room->MaskResolution; - int low_height = base_height / room->MaskResolution; - - // Walk-behinds are always 1:1 of the primary background. - // Other masks are 1:x where X is MaskResolution. - room->WalkBehindMask = FixBitmap(room->WalkBehindMask, base_width, base_height); - room->HotspotMask = FixBitmap(room->HotspotMask, low_width, low_height); - room->RegionMask = FixBitmap(room->RegionMask, low_width, low_height); - room->WalkAreaMask = FixBitmap(room->WalkAreaMask, low_width, low_height); +void FixRoomMasks(RoomStruct *room) { + if (room->MaskResolution <= 0) + return; + Bitmap *bkg = room->BgFrames[0].Graphic.get(); + if (bkg == nullptr) + return; + // TODO: this issue is somewhat complicated. Original code was relying on + // room->Width and Height properties. But in the engine these are saved + // already converted to data resolution which may be "low-res". Since this + // function is shared between engine and editor we do not know if we need + // to upscale them. + // For now room width/height is always equal to background bitmap. + int base_width = bkg->GetWidth(); + int base_height = bkg->GetHeight(); + int low_width = base_width / room->MaskResolution; + int low_height = base_height / room->MaskResolution; + + // Walk-behinds are always 1:1 of the primary background. + // Other masks are 1:x where X is MaskResolution. + room->WalkBehindMask = FixBitmap(room->WalkBehindMask, base_width, base_height); + room->HotspotMask = FixBitmap(room->HotspotMask, low_width, low_height); + room->RegionMask = FixBitmap(room->RegionMask, low_width, low_height); + room->WalkAreaMask = FixBitmap(room->WalkAreaMask, low_width, low_height); } } // namespace Common diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index 722c60ce5c02..590275c5017a 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -25,12 +25,12 @@ // RoomStruct, a class describing initial room data. // // Because of the imperfect implementation there is inconsistency in how -// this data is interpreted at the runtime. +// this data is interpreted at the runtime. // Some of that data is never supposed to be changed at runtime. Another // may be changed, but these changes are lost as soon as room is unloaded. // The changes that must remain in memory are kept as separate classes: // see RoomStatus, RoomObject etc. -// +// // Partially this is because same class was used for both engine and editor, // while runtime code was not available for the editor. // @@ -63,31 +63,29 @@ typedef std::shared_ptr PScript; // refactored. // Room's area mask type -enum RoomAreaMask -{ - kRoomAreaNone = 0, - kRoomAreaHotspot, - kRoomAreaWalkBehind, - kRoomAreaWalkable, - kRoomAreaRegion +enum RoomAreaMask { + kRoomAreaNone = 0, + kRoomAreaHotspot, + kRoomAreaWalkBehind, + kRoomAreaWalkable, + kRoomAreaRegion }; // Room's audio volume modifier -enum RoomVolumeMod -{ - kRoomVolumeQuietest = -3, - kRoomVolumeQuieter = -2, - kRoomVolumeQuiet = -1, - kRoomVolumeNormal = 0, - kRoomVolumeLoud = 1, - kRoomVolumeLouder = 2, - kRoomVolumeLoudest = 3, - // These two options are only settable at runtime by SetMusicVolume() - kRoomVolumeExtra1 = 4, - kRoomVolumeExtra2 = 5, - - kRoomVolumeMin = kRoomVolumeQuietest, - kRoomVolumeMax = kRoomVolumeExtra2, +enum RoomVolumeMod { + kRoomVolumeQuietest = -3, + kRoomVolumeQuieter = -2, + kRoomVolumeQuiet = -1, + kRoomVolumeNormal = 0, + kRoomVolumeLoud = 1, + kRoomVolumeLouder = 2, + kRoomVolumeLoudest = 3, + // These two options are only settable at runtime by SetMusicVolume() + kRoomVolumeExtra1 = 4, + kRoomVolumeExtra2 = 5, + + kRoomVolumeMin = kRoomVolumeQuietest, + kRoomVolumeMax = kRoomVolumeExtra2, }; // Flag tells that walkable area does not have continious zoom @@ -109,10 +107,8 @@ enum RoomVolumeMod #define MAX_MESSAGES 100 -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class Bitmap; class Stream; @@ -120,128 +116,120 @@ class Stream; typedef std::shared_ptr PBitmap; // Various room options -struct RoomOptions -{ - // Index of the startup music in the room - int StartupMusic; - // If saving and loading game is disabled in the room - bool SaveLoadDisabled; - // If player character is turned off in the room - bool PlayerCharOff; - // Apply player character's normal view when entering this room - int PlayerView; - // Room's music volume modifier - RoomVolumeMod MusicVolume; - - RoomOptions(); +struct RoomOptions { + // Index of the startup music in the room + int StartupMusic; + // If saving and loading game is disabled in the room + bool SaveLoadDisabled; + // If player character is turned off in the room + bool PlayerCharOff; + // Apply player character's normal view when entering this room + int PlayerView; + // Room's music volume modifier + RoomVolumeMod MusicVolume; + + RoomOptions(); }; // Single room background frame -struct RoomBgFrame -{ - PBitmap Graphic; - // Palette is only valid in 8-bit games - color Palette[256]; - // Tells if this frame should keep previous frame palette instead of using its own - bool IsPaletteShared; - - RoomBgFrame(); +struct RoomBgFrame { + PBitmap Graphic; + // Palette is only valid in 8-bit games + color Palette[256]; + // Tells if this frame should keep previous frame palette instead of using its own + bool IsPaletteShared; + + RoomBgFrame(); }; // Describes room edges (coordinates of four edges) -struct RoomEdges -{ - int32_t Left; - int32_t Right; - int32_t Top; - int32_t Bottom; - - RoomEdges(); - RoomEdges(int l, int r, int t, int b); +struct RoomEdges { + int32_t Left; + int32_t Right; + int32_t Top; + int32_t Bottom; + + RoomEdges(); + RoomEdges(int l, int r, int t, int b); }; // Room hotspot description -struct RoomHotspot -{ - String Name; - String ScriptName; - // Custom properties - StringIMap Properties; - // Old-style interactions - PInteraction Interaction; - // Event script links - PInteractionScripts EventHandlers; - - // Player will automatically walk here when interacting with hotspot - Point WalkTo; +struct RoomHotspot { + String Name; + String ScriptName; + // Custom properties + StringIMap Properties; + // Old-style interactions + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + + // Player will automatically walk here when interacting with hotspot + Point WalkTo; }; // Room object description -struct RoomObjectInfo -{ - int32_t Room; - int32_t X; - int32_t Y; - int32_t Sprite; - bool IsOn; - // Object's z-order in the room, or -1 (use Y) - int32_t Baseline; - int32_t Flags; - String Name; - String ScriptName; - // Custom properties - StringIMap Properties; - // Old-style interactions - PInteraction Interaction; - // Event script links - PInteractionScripts EventHandlers; - - RoomObjectInfo(); +struct RoomObjectInfo { + int32_t Room; + int32_t X; + int32_t Y; + int32_t Sprite; + bool IsOn; + // Object's z-order in the room, or -1 (use Y) + int32_t Baseline; + int32_t Flags; + String Name; + String ScriptName; + // Custom properties + StringIMap Properties; + // Old-style interactions + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + + RoomObjectInfo(); }; // Room region description -struct RoomRegion -{ - // Light level (-100 -> +100) or Tint luminance (0 - 255) - int32_t Light; - // Tint setting (R-B-G-S) - int32_t Tint; - // Custom properties - StringIMap Properties; - // Old-style interactions - PInteraction Interaction; - // Event script links - PInteractionScripts EventHandlers; - - RoomRegion(); +struct RoomRegion { + // Light level (-100 -> +100) or Tint luminance (0 - 255) + int32_t Light; + // Tint setting (R-B-G-S) + int32_t Tint; + // Custom properties + StringIMap Properties; + // Old-style interactions + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + + RoomRegion(); }; // Walkable area description -struct WalkArea -{ - // Apply player character's normal view on this area - int32_t CharacterView; - // Character's scaling (-100 -> +100 %) - // General scaling, or scaling at the farthest point - int32_t ScalingFar; - // Scaling at the nearest point, or NOT_VECTOR_SCALED for uniform scaling - int32_t ScalingNear; - // Light level (-100 -> +100) - int32_t Light; - // Top and bottom Y of the area - int32_t Top; - int32_t Bottom; - - WalkArea(); +struct WalkArea { + // Apply player character's normal view on this area + int32_t CharacterView; + // Character's scaling (-100 -> +100 %) + // General scaling, or scaling at the farthest point + int32_t ScalingFar; + // Scaling at the nearest point, or NOT_VECTOR_SCALED for uniform scaling + int32_t ScalingNear; + // Light level (-100 -> +100) + int32_t Light; + // Top and bottom Y of the area + int32_t Top; + int32_t Bottom; + + WalkArea(); }; // Walk-behind description -struct WalkBehind -{ - // Object's z-order in the room - int32_t Baseline; +struct WalkBehind { + // Object's z-order in the room + int32_t Baseline; - WalkBehind(); + WalkBehind(); }; // Room messages @@ -249,21 +237,19 @@ struct WalkBehind #define MSG_DISPLAYNEXT 0x01 // supercedes using alt-200 at end of message #define MSG_TIMELIMIT 0x02 -struct MessageInfo -{ - char DisplayAs; // 0 - std display window, >=1 - as character's speech - char Flags; // combination of MSG_xxx flags +struct MessageInfo { + char DisplayAs; // 0 - std display window, >=1 - as character's speech + char Flags; // combination of MSG_xxx flags - MessageInfo(); + MessageInfo(); }; // Room's legacy resolution type -enum RoomResolutionType -{ - kRoomRealRes = 0, // room should always be treated as-is - kRoomLoRes = 1, // created for low-resolution game - kRoomHiRes = 2 // created for high-resolution game +enum RoomResolutionType { + kRoomRealRes = 0, // room should always be treated as-is + kRoomLoRes = 1, // created for low-resolution game + kRoomHiRes = 2 // created for high-resolution game }; @@ -272,111 +258,116 @@ enum RoomResolutionType // This class contains initial room data. Some of it may still be modified // at the runtime, but then these changes get lost as soon as room is unloaded. // -class RoomStruct -{ +class RoomStruct { public: - RoomStruct(); - ~RoomStruct(); - - // Gets if room should adjust its base size depending on game's resolution - inline bool IsRelativeRes() const { return _resolution != kRoomRealRes; } - // Gets if room belongs to high resolution - inline bool IsLegacyHiRes() const { return _resolution == kRoomHiRes; } - // Gets legacy resolution type - inline RoomResolutionType GetResolutionType() const { return _resolution; } - - // Releases room resources - void Free(); - // Release room messages and scripts correspondingly. These two functions are needed - // at very specific occasion when only part of the room resources has to be freed. - void FreeMessages(); - void FreeScripts(); - // Init default room state - void InitDefaults(); - // Set legacy resolution type - void SetResolution(RoomResolutionType type); - - // Gets bitmap of particular mask layer - Bitmap *GetMask(RoomAreaMask mask) const; - // Gets mask's scale relative to the room's background size - float GetMaskScale(RoomAreaMask mask) const; - - // TODO: see later whether it may be more convenient to move these to the Region class instead. - // Gets if the given region has light level set - bool HasRegionLightLevel(int id) const; - // Gets if the given region has a tint set - bool HasRegionTint(int id) const; - // Gets region's light level in -100 to 100 range value; returns 0 (default level) if region's tint is set - int GetRegionLightLevel(int id) const; - // Gets region's tint luminance in 0 to 100 range value; returns 0 if region's light level is set - int GetRegionTintLuminance(int id) const; + RoomStruct(); + ~RoomStruct(); + + // Gets if room should adjust its base size depending on game's resolution + inline bool IsRelativeRes() const { + return _resolution != kRoomRealRes; + } + // Gets if room belongs to high resolution + inline bool IsLegacyHiRes() const { + return _resolution == kRoomHiRes; + } + // Gets legacy resolution type + inline RoomResolutionType GetResolutionType() const { + return _resolution; + } + + // Releases room resources + void Free(); + // Release room messages and scripts correspondingly. These two functions are needed + // at very specific occasion when only part of the room resources has to be freed. + void FreeMessages(); + void FreeScripts(); + // Init default room state + void InitDefaults(); + // Set legacy resolution type + void SetResolution(RoomResolutionType type); + + // Gets bitmap of particular mask layer + Bitmap *GetMask(RoomAreaMask mask) const; + // Gets mask's scale relative to the room's background size + float GetMaskScale(RoomAreaMask mask) const; + + // TODO: see later whether it may be more convenient to move these to the Region class instead. + // Gets if the given region has light level set + bool HasRegionLightLevel(int id) const; + // Gets if the given region has a tint set + bool HasRegionTint(int id) const; + // Gets region's light level in -100 to 100 range value; returns 0 (default level) if region's tint is set + int GetRegionLightLevel(int id) const; + // Gets region's tint luminance in 0 to 100 range value; returns 0 if region's light level is set + int GetRegionTintLuminance(int id) const; // TODO: all members are currently public because they are used everywhere; hide them later public: - // Game's unique ID, corresponds to GameSetupStructBase::uniqueid. - // If this field has a valid value and does not match actual game's id, - // then engine will refuse to start this room. - // May be set to NO_GAME_ID_IN_ROOM_FILE to let it run within any game. - int32_t GameID; - // Loaded room file's data version. This value may be used to know when - // the room must have behavior specific to certain version of AGS. - int32_t DataVersion; - - // Room region masks resolution. Defines the relation between room and mask units. - // Mask point is calculated as roompt / MaskResolution. Must be >= 1. - int32_t MaskResolution; - // Size of the room, in logical coordinates (= pixels) - int32_t Width; - int32_t Height; - // Primary room palette (8-bit games) - color Palette[256]; - - // Basic room options - RoomOptions Options; - - // Background frames - int32_t BackgroundBPP; // bytes per pixel - size_t BgFrameCount; - RoomBgFrame BgFrames[MAX_ROOM_BGFRAMES]; - // Speed at which background frames are changing, 0 - no auto animation - int32_t BgAnimSpeed; - // Edges - RoomEdges Edges; - // Region masks - PBitmap HotspotMask; - PBitmap RegionMask; - PBitmap WalkAreaMask; - PBitmap WalkBehindMask; - // Room entities - size_t HotspotCount; - RoomHotspot Hotspots[MAX_ROOM_HOTSPOTS]; - size_t ObjectCount; - RoomObjectInfo Objects[MAX_ROOM_OBJECTS]; - size_t RegionCount; - RoomRegion Regions[MAX_ROOM_REGIONS]; - size_t WalkAreaCount; - WalkArea WalkAreas[MAX_WALK_AREAS + 1]; - size_t WalkBehindCount; - WalkBehind WalkBehinds[MAX_WALK_BEHINDS]; - - // Old numbered room messages (used with DisplayMessage, etc) - size_t MessageCount; - String Messages[MAX_MESSAGES]; - MessageInfo MessageInfos[MAX_MESSAGES]; - - // Custom properties - StringIMap Properties; - // Old-style interactions - InterVarVector LocalVariables; - PInteraction Interaction; - // Event script links - PInteractionScripts EventHandlers; - // Compiled room script - PScript CompiledScript; + // Game's unique ID, corresponds to GameSetupStructBase::uniqueid. + // If this field has a valid value and does not match actual game's id, + // then engine will refuse to start this room. + // May be set to NO_GAME_ID_IN_ROOM_FILE to let it run within any game. + int32_t GameID; + // Loaded room file's data version. This value may be used to know when + // the room must have behavior specific to certain version of AGS. + int32_t DataVersion; + + // Room region masks resolution. Defines the relation between room and mask units. + // Mask point is calculated as roompt / MaskResolution. Must be >= 1. + int32_t MaskResolution; + // Size of the room, in logical coordinates (= pixels) + int32_t Width; + int32_t Height; + // Primary room palette (8-bit games) + color Palette[256]; + + // Basic room options + RoomOptions Options; + + // Background frames + int32_t BackgroundBPP; // bytes per pixel + size_t BgFrameCount; + RoomBgFrame BgFrames[MAX_ROOM_BGFRAMES]; + // Speed at which background frames are changing, 0 - no auto animation + int32_t BgAnimSpeed; + // Edges + RoomEdges Edges; + // Region masks + PBitmap HotspotMask; + PBitmap RegionMask; + PBitmap WalkAreaMask; + PBitmap WalkBehindMask; + // Room entities + size_t HotspotCount; + RoomHotspot Hotspots[MAX_ROOM_HOTSPOTS]; + size_t ObjectCount; + RoomObjectInfo Objects[MAX_ROOM_OBJECTS]; + size_t RegionCount; + RoomRegion Regions[MAX_ROOM_REGIONS]; + size_t WalkAreaCount; + WalkArea WalkAreas[MAX_WALK_AREAS + 1]; + size_t WalkBehindCount; + WalkBehind WalkBehinds[MAX_WALK_BEHINDS]; + + // Old numbered room messages (used with DisplayMessage, etc) + size_t MessageCount; + String Messages[MAX_MESSAGES]; + MessageInfo MessageInfos[MAX_MESSAGES]; + + // Custom properties + StringIMap Properties; + // Old-style interactions + InterVarVector LocalVariables; + PInteraction Interaction; + // Event script links + PInteractionScripts EventHandlers; + // Compiled room script + PScript CompiledScript; private: - // Room's legacy resolution type, defines relation room and game's resolution - RoomResolutionType _resolution; + // Room's legacy resolution type, defines relation room and game's resolution + RoomResolutionType _resolution; }; diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index 806976bad145..75284d19b6dc 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -26,159 +26,131 @@ extern void __my_setcolor(int *ctset, int newcol, int wantColDep); -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { Bitmap::Bitmap() - : _alBitmap(nullptr) - , _isDataOwner(false) -{ + : _alBitmap(nullptr) + , _isDataOwner(false) { } Bitmap::Bitmap(int width, int height, int color_depth) - : _alBitmap(nullptr) - , _isDataOwner(false) -{ - Create(width, height, color_depth); + : _alBitmap(nullptr) + , _isDataOwner(false) { + Create(width, height, color_depth); } Bitmap::Bitmap(Bitmap *src, const Rect &rc) - : _alBitmap(nullptr) - , _isDataOwner(false) -{ - CreateSubBitmap(src, rc); + : _alBitmap(nullptr) + , _isDataOwner(false) { + CreateSubBitmap(src, rc); } Bitmap::Bitmap(BITMAP *al_bmp, bool shared_data) - : _alBitmap(nullptr) - , _isDataOwner(false) -{ - WrapAllegroBitmap(al_bmp, shared_data); + : _alBitmap(nullptr) + , _isDataOwner(false) { + WrapAllegroBitmap(al_bmp, shared_data); } -Bitmap::~Bitmap() -{ - Destroy(); +Bitmap::~Bitmap() { + Destroy(); } //============================================================================= // Creation and destruction //============================================================================= -bool Bitmap::Create(int width, int height, int color_depth) -{ - Destroy(); - if (color_depth) - { - _alBitmap = create_bitmap_ex(color_depth, width, height); - } - else - { - _alBitmap = create_bitmap(width, height); - } - _isDataOwner = true; - return _alBitmap != nullptr; -} - -bool Bitmap::CreateTransparent(int width, int height, int color_depth) -{ - if (Create(width, height, color_depth)) - { - clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); - return true; - } - return false; -} - -bool Bitmap::CreateSubBitmap(Bitmap *src, const Rect &rc) -{ - Destroy(); - _alBitmap = create_sub_bitmap(src->_alBitmap, rc.Left, rc.Top, rc.GetWidth(), rc.GetHeight()); - _isDataOwner = true; - return _alBitmap != nullptr; -} - -bool Bitmap::CreateCopy(Bitmap *src, int color_depth) -{ - if (Create(src->_alBitmap->w, src->_alBitmap->h, color_depth ? color_depth : bitmap_color_depth(src->_alBitmap))) - { - blit(src->_alBitmap, _alBitmap, 0, 0, 0, 0, _alBitmap->w, _alBitmap->h); - return true; - } - return false; -} - -bool Bitmap::WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data) -{ - Destroy(); - _alBitmap = al_bmp; - _isDataOwner = !shared_data; - return _alBitmap != nullptr; -} - -void Bitmap::Destroy() -{ - if (_isDataOwner && _alBitmap) - { - destroy_bitmap(_alBitmap); - } - _alBitmap = nullptr; - _isDataOwner = false; -} - -bool Bitmap::LoadFromFile(const char *filename) -{ - Destroy(); +bool Bitmap::Create(int width, int height, int color_depth) { + Destroy(); + if (color_depth) { + _alBitmap = create_bitmap_ex(color_depth, width, height); + } else { + _alBitmap = create_bitmap(width, height); + } + _isDataOwner = true; + return _alBitmap != nullptr; +} + +bool Bitmap::CreateTransparent(int width, int height, int color_depth) { + if (Create(width, height, color_depth)) { + clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); + return true; + } + return false; +} + +bool Bitmap::CreateSubBitmap(Bitmap *src, const Rect &rc) { + Destroy(); + _alBitmap = create_sub_bitmap(src->_alBitmap, rc.Left, rc.Top, rc.GetWidth(), rc.GetHeight()); + _isDataOwner = true; + return _alBitmap != nullptr; +} + +bool Bitmap::CreateCopy(Bitmap *src, int color_depth) { + if (Create(src->_alBitmap->w, src->_alBitmap->h, color_depth ? color_depth : bitmap_color_depth(src->_alBitmap))) { + blit(src->_alBitmap, _alBitmap, 0, 0, 0, 0, _alBitmap->w, _alBitmap->h); + return true; + } + return false; +} + +bool Bitmap::WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data) { + Destroy(); + _alBitmap = al_bmp; + _isDataOwner = !shared_data; + return _alBitmap != nullptr; +} + +void Bitmap::Destroy() { + if (_isDataOwner && _alBitmap) { + destroy_bitmap(_alBitmap); + } + _alBitmap = nullptr; + _isDataOwner = false; +} + +bool Bitmap::LoadFromFile(const char *filename) { + Destroy(); BITMAP *al_bmp = load_bitmap(filename, nullptr); - if (al_bmp) - { + if (al_bmp) { _alBitmap = al_bmp; - _isDataOwner = true; + _isDataOwner = true; } return _alBitmap != nullptr; } -bool Bitmap::SaveToFile(const char *filename, const void *palette) -{ - return save_bitmap(filename, _alBitmap, (const RGB*)palette) == 0; +bool Bitmap::SaveToFile(const char *filename, const void *palette) { + return save_bitmap(filename, _alBitmap, (const RGB *)palette) == 0; } -void Bitmap::SetMaskColor(color_t color) -{ +void Bitmap::SetMaskColor(color_t color) { // not supported? CHECKME } -void Bitmap::Acquire() -{ +void Bitmap::Acquire() { acquire_bitmap(_alBitmap); } -void Bitmap::Release() -{ +void Bitmap::Release() { release_bitmap(_alBitmap); } -color_t Bitmap::GetCompatibleColor(color_t color) -{ - color_t compat_color = 0; - __my_setcolor(&compat_color, color, bitmap_color_depth(_alBitmap)); - return compat_color; +color_t Bitmap::GetCompatibleColor(color_t color) { + color_t compat_color = 0; + __my_setcolor(&compat_color, color, bitmap_color_depth(_alBitmap)); + return compat_color; } //============================================================================= // Clipping //============================================================================= -void Bitmap::SetClip(const Rect &rc) -{ +void Bitmap::SetClip(const Rect &rc) { set_clip_rect(_alBitmap, rc.Left, rc.Top, rc.Right, rc.Bottom); } -Rect Bitmap::GetClip() const -{ +Rect Bitmap::GetClip() const { Rect temp; get_clip_rect(_alBitmap, &temp.Left, &temp.Top, &temp.Right, &temp.Bottom); return temp; @@ -188,144 +160,109 @@ Rect Bitmap::GetClip() const // Blitting operations (drawing one bitmap over another) //============================================================================= -void Bitmap::Blit(Bitmap *src, int dst_x, int dst_y, BitmapMaskOption mask) -{ +void Bitmap::Blit(Bitmap *src, int dst_x, int dst_y, BitmapMaskOption mask) { BITMAP *al_src_bmp = src->_alBitmap; // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite - if (mask == kBitmap_Transparency) - { + if (mask == kBitmap_Transparency) { draw_sprite(_alBitmap, al_src_bmp, dst_x, dst_y); - } - else - { + } else { blit(al_src_bmp, _alBitmap, 0, 0, dst_x, dst_y, al_src_bmp->w, al_src_bmp->h); } } -void Bitmap::Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask) -{ +void Bitmap::Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask) { BITMAP *al_src_bmp = src->_alBitmap; - if (mask == kBitmap_Transparency) - { + if (mask == kBitmap_Transparency) { masked_blit(al_src_bmp, _alBitmap, src_x, src_y, dst_x, dst_y, width, height); - } - else - { + } else { blit(al_src_bmp, _alBitmap, src_x, src_y, dst_x, dst_y, width, height); } } -void Bitmap::MaskedBlit(Bitmap *src, int dst_x, int dst_y) -{ - draw_sprite(_alBitmap, src->_alBitmap, dst_x, dst_y); +void Bitmap::MaskedBlit(Bitmap *src, int dst_x, int dst_y) { + draw_sprite(_alBitmap, src->_alBitmap, dst_x, dst_y); } -void Bitmap::StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask) -{ +void Bitmap::StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask) { BITMAP *al_src_bmp = src->_alBitmap; // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite - if (mask == kBitmap_Transparency) - { + if (mask == kBitmap_Transparency) { stretch_sprite(_alBitmap, al_src_bmp, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); - } - else - { + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } else { stretch_blit(al_src_bmp, _alBitmap, - 0, 0, al_src_bmp->w, al_src_bmp->h, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + 0, 0, al_src_bmp->w, al_src_bmp->h, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } -void Bitmap::StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask) -{ +void Bitmap::StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask) { BITMAP *al_src_bmp = src->_alBitmap; - if (mask == kBitmap_Transparency) - { + if (mask == kBitmap_Transparency) { masked_stretch_blit(al_src_bmp, _alBitmap, - src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); - } - else - { + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } else { stretch_blit(al_src_bmp, _alBitmap, - src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } -void Bitmap::AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask) -{ +void Bitmap::AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask) { BITMAP *al_src_bmp = src->_alBitmap; // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite - if (mask == kBitmap_Transparency) - { + if (mask == kBitmap_Transparency) { aa_stretch_sprite(_alBitmap, al_src_bmp, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); - } - else - { + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + } else { aa_stretch_blit(al_src_bmp, _alBitmap, - 0, 0, al_src_bmp->w, al_src_bmp->h, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + 0, 0, al_src_bmp->w, al_src_bmp->h, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } -void Bitmap::AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask) -{ +void Bitmap::AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask) { BITMAP *al_src_bmp = src->_alBitmap; - if (mask == kBitmap_Transparency) - { - // TODO: aastr lib does not expose method for masked stretch blit; should do that at some point since + if (mask == kBitmap_Transparency) { + // TODO: aastr lib does not expose method for masked stretch blit; should do that at some point since // the source code is a gift-ware anyway // aa_masked_blit(_alBitmap, al_src_bmp, src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); throw "aa_masked_blit is not yet supported!"; - } - else - { + } else { aa_stretch_blit(al_src_bmp, _alBitmap, - src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } -void Bitmap::TransBlendBlt(Bitmap *src, int dst_x, int dst_y) -{ +void Bitmap::TransBlendBlt(Bitmap *src, int dst_x, int dst_y) { BITMAP *al_src_bmp = src->_alBitmap; draw_trans_sprite(_alBitmap, al_src_bmp, dst_x, dst_y); } -void Bitmap::LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount) -{ +void Bitmap::LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount) { BITMAP *al_src_bmp = src->_alBitmap; draw_lit_sprite(_alBitmap, al_src_bmp, dst_x, dst_y, light_amount); } -void Bitmap::FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip) -{ +void Bitmap::FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip) { BITMAP *al_src_bmp = src->_alBitmap; - if (flip == kBitmap_HFlip) - { + if (flip == kBitmap_HFlip) { draw_sprite_h_flip(_alBitmap, al_src_bmp, dst_x, dst_y); - } - else if (flip == kBitmap_VFlip) - { + } else if (flip == kBitmap_VFlip) { draw_sprite_v_flip(_alBitmap, al_src_bmp, dst_x, dst_y); - } - else if (flip == kBitmap_HVFlip) - { + } else if (flip == kBitmap_HVFlip) { draw_sprite_vh_flip(_alBitmap, al_src_bmp, dst_x, dst_y); } } -void Bitmap::RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle) -{ +void Bitmap::RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle) { BITMAP *al_src_bmp = src->_alBitmap; rotate_sprite(_alBitmap, al_src_bmp, dst_x, dst_y, angle); } -void Bitmap::RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle) -{ +void Bitmap::RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle) { BITMAP *al_src_bmp = src->_alBitmap; pivot_sprite(_alBitmap, al_src_bmp, dst_x, dst_y, pivot_x, pivot_y, angle); } @@ -334,32 +271,24 @@ void Bitmap::RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot // Pixel operations //============================================================================= -void Bitmap::Clear(color_t color) -{ - if (color) - { +void Bitmap::Clear(color_t color) { + if (color) { clear_to_color(_alBitmap, color); - } - else - { - clear_bitmap(_alBitmap); + } else { + clear_bitmap(_alBitmap); } } -void Bitmap::ClearTransparent() -{ - clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); +void Bitmap::ClearTransparent() { + clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); } -void Bitmap::PutPixel(int x, int y, color_t color) -{ - if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h) - { - return; - } +void Bitmap::PutPixel(int x, int y, color_t color) { + if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h) { + return; + } - switch (bitmap_color_depth(_alBitmap)) - { + switch (bitmap_color_depth(_alBitmap)) { case 8: return _putpixel(_alBitmap, x, y, color); case 15: @@ -371,19 +300,16 @@ void Bitmap::PutPixel(int x, int y, color_t color) case 32: return _putpixel32(_alBitmap, x, y, color); } - assert(0); // this should not normally happen + assert(0); // this should not normally happen return putpixel(_alBitmap, x, y, color); } -int Bitmap::GetPixel(int x, int y) const -{ - if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h) - { - return -1; // Allegros getpixel() implementation returns -1 in this case - } +int Bitmap::GetPixel(int x, int y) const { + if (x < 0 || x >= _alBitmap->w || y < 0 || y >= _alBitmap->h) { + return -1; // Allegros getpixel() implementation returns -1 in this case + } - switch (bitmap_color_depth(_alBitmap)) - { + switch (bitmap_color_depth(_alBitmap)) { case 8: return _getpixel(_alBitmap, x, y); case 15: @@ -395,7 +321,7 @@ int Bitmap::GetPixel(int x, int y) const case 32: return _getpixel32(_alBitmap, x, y); } - assert(0); // this should not normally happen + assert(0); // this should not normally happen return getpixel(_alBitmap, x, y); } @@ -403,51 +329,40 @@ int Bitmap::GetPixel(int x, int y) const // Vector drawing operations //============================================================================= -void Bitmap::DrawLine(const Line &ln, color_t color) -{ +void Bitmap::DrawLine(const Line &ln, color_t color) { line(_alBitmap, ln.X1, ln.Y1, ln.X2, ln.Y2, color); } -void Bitmap::DrawTriangle(const Triangle &tr, color_t color) -{ +void Bitmap::DrawTriangle(const Triangle &tr, color_t color) { triangle(_alBitmap, - tr.X1, tr.Y1, tr.X2, tr.Y2, tr.X3, tr.Y3, color); + tr.X1, tr.Y1, tr.X2, tr.Y2, tr.X3, tr.Y3, color); } -void Bitmap::DrawRect(const Rect &rc, color_t color) -{ +void Bitmap::DrawRect(const Rect &rc, color_t color) { rect(_alBitmap, rc.Left, rc.Top, rc.Right, rc.Bottom, color); } -void Bitmap::FillRect(const Rect &rc, color_t color) -{ +void Bitmap::FillRect(const Rect &rc, color_t color) { rectfill(_alBitmap, rc.Left, rc.Top, rc.Right, rc.Bottom, color); } -void Bitmap::FillCircle(const Circle &circle, color_t color) -{ +void Bitmap::FillCircle(const Circle &circle, color_t color) { circlefill(_alBitmap, circle.X, circle.Y, circle.Radius, color); } -void Bitmap::Fill(color_t color) -{ - if (color) - { +void Bitmap::Fill(color_t color) { + if (color) { clear_to_color(_alBitmap, color); - } - else - { - clear_bitmap(_alBitmap); + } else { + clear_bitmap(_alBitmap); } } -void Bitmap::FillTransparent() -{ - clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); +void Bitmap::FillTransparent() { + clear_to_color(_alBitmap, bitmap_mask_color(_alBitmap)); } -void Bitmap::FloodFill(int x, int y, color_t color) -{ +void Bitmap::FloodFill(int x, int y, color_t color) { floodfill(_alBitmap, x, y, color); } @@ -455,48 +370,38 @@ void Bitmap::FloodFill(int x, int y, color_t color) // Direct access operations //============================================================================= -void Bitmap::SetScanLine(int index, unsigned char *data, int data_size) -{ - if (index < 0 || index >= GetHeight()) - { +void Bitmap::SetScanLine(int index, unsigned char *data, int data_size) { + if (index < 0 || index >= GetHeight()) { return; } int copy_length = data_size; - if (copy_length < 0) - { - copy_length = GetLineLength(); - } - else // TODO: use Math namespace here - if (copy_length > GetLineLength()) - { + if (copy_length < 0) { copy_length = GetLineLength(); - } + } else // TODO: use Math namespace here + if (copy_length > GetLineLength()) { + copy_length = GetLineLength(); + } memcpy(_alBitmap->line[index], data, copy_length); } -namespace BitmapHelper -{ +namespace BitmapHelper { -Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp) -{ +Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp) { Bitmap *bitmap = new Bitmap(); - if (!bitmap->WrapAllegroBitmap(al_bmp, false)) - { + if (!bitmap->WrapAllegroBitmap(al_bmp, false)) { delete bitmap; bitmap = nullptr; } return bitmap; } -Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp) -{ +Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp) { Bitmap *bitmap = new Bitmap(); - if (!bitmap->WrapAllegroBitmap(al_bmp, true)) - { + if (!bitmap->WrapAllegroBitmap(al_bmp, true)) { delete bitmap; bitmap = nullptr; } diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 94c22a4b887c..98771376e03c 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -36,222 +36,200 @@ #include "core/types.h" #include "gfx/bitmap.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class Bitmap -{ +class Bitmap { public: - Bitmap(); - Bitmap(int width, int height, int color_depth = 0); - Bitmap(Bitmap *src, const Rect &rc); - Bitmap(BITMAP *al_bmp, bool shared_data); - ~Bitmap(); - - // Allocate new bitmap - // CHECKME: color_depth = 0 is used to call Allegro's create_bitmap, which uses - // some global color depth setting; not sure if this is OK to use for generic class, - // revise this in future - bool Create(int width, int height, int color_depth = 0); - bool CreateTransparent(int width, int height, int color_depth = 0); - // Allow this object to share existing bitmap data - bool CreateSubBitmap(Bitmap *src, const Rect &rc); - // Create a copy of given bitmap - bool CreateCopy(Bitmap *src, int color_depth = 0); - // TODO: a temporary solution for plugin support - bool WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data); - // Deallocate bitmap - void Destroy(); - - bool LoadFromFile(const char *filename); - bool SaveToFile(const char *filename, const void *palette); - - // TODO: This is temporary solution for cases when we cannot replace + Bitmap(); + Bitmap(int width, int height, int color_depth = 0); + Bitmap(Bitmap *src, const Rect &rc); + Bitmap(BITMAP *al_bmp, bool shared_data); + ~Bitmap(); + + // Allocate new bitmap + // CHECKME: color_depth = 0 is used to call Allegro's create_bitmap, which uses + // some global color depth setting; not sure if this is OK to use for generic class, + // revise this in future + bool Create(int width, int height, int color_depth = 0); + bool CreateTransparent(int width, int height, int color_depth = 0); + // Allow this object to share existing bitmap data + bool CreateSubBitmap(Bitmap *src, const Rect &rc); + // Create a copy of given bitmap + bool CreateCopy(Bitmap *src, int color_depth = 0); + // TODO: a temporary solution for plugin support + bool WrapAllegroBitmap(BITMAP *al_bmp, bool shared_data); + // Deallocate bitmap + void Destroy(); + + bool LoadFromFile(const char *filename); + bool SaveToFile(const char *filename, const void *palette); + + // TODO: This is temporary solution for cases when we cannot replace // use of raw BITMAP struct with Bitmap - inline BITMAP *GetAllegroBitmap() - { - return _alBitmap; - } - - // Is this a "normal" bitmap created by application which data can be directly accessed for reading and writing - inline bool IsMemoryBitmap() const - { - return is_memory_bitmap(_alBitmap) != 0; - } - // Is this a video bitmap - inline bool IsVideoBitmap() const - { - return is_video_bitmap(_alBitmap) != 0; - } - // Is this a linear bitmap, the one that can be accessed linearly within each scanline - inline bool IsLinearBitmap() const - { - return is_linear_bitmap(_alBitmap) != 0; - } - - // Checks if bitmap cannot be used - inline bool IsNull() const - { - return !_alBitmap; - } - // Checks if bitmap has zero size: either width or height (or both) is zero - inline bool IsEmpty() const - { - return GetWidth() == 0 || GetHeight() == 0; - } - inline int GetWidth() const - { - return _alBitmap->w; - } - inline int GetHeight() const - { - return _alBitmap->h; - } - inline Size GetSize() const - { - return Size(_alBitmap->w, _alBitmap->h); - } - inline int GetColorDepth() const - { - return bitmap_color_depth(_alBitmap); - } - // BPP: bytes per pixel - inline int GetBPP() const - { - return (GetColorDepth() + 7) / 8; - } - - // CHECKME: probably should not be exposed, see comment to GetData() - inline int GetDataSize() const - { - return GetWidth() * GetHeight() * GetBPP(); - } - // Gets scanline length in bytes (is the same for any scanline) - inline int GetLineLength() const - { - return GetWidth() * GetBPP(); - } + inline BITMAP *GetAllegroBitmap() { + return _alBitmap; + } + + // Is this a "normal" bitmap created by application which data can be directly accessed for reading and writing + inline bool IsMemoryBitmap() const { + return is_memory_bitmap(_alBitmap) != 0; + } + // Is this a video bitmap + inline bool IsVideoBitmap() const { + return is_video_bitmap(_alBitmap) != 0; + } + // Is this a linear bitmap, the one that can be accessed linearly within each scanline + inline bool IsLinearBitmap() const { + return is_linear_bitmap(_alBitmap) != 0; + } + + // Checks if bitmap cannot be used + inline bool IsNull() const { + return !_alBitmap; + } + // Checks if bitmap has zero size: either width or height (or both) is zero + inline bool IsEmpty() const { + return GetWidth() == 0 || GetHeight() == 0; + } + inline int GetWidth() const { + return _alBitmap->w; + } + inline int GetHeight() const { + return _alBitmap->h; + } + inline Size GetSize() const { + return Size(_alBitmap->w, _alBitmap->h); + } + inline int GetColorDepth() const { + return bitmap_color_depth(_alBitmap); + } + // BPP: bytes per pixel + inline int GetBPP() const { + return (GetColorDepth() + 7) / 8; + } + + // CHECKME: probably should not be exposed, see comment to GetData() + inline int GetDataSize() const { + return GetWidth() * GetHeight() * GetBPP(); + } + // Gets scanline length in bytes (is the same for any scanline) + inline int GetLineLength() const { + return GetWidth() * GetBPP(); + } // TODO: replace with byte * // Gets a pointer to underlying graphic data // FIXME: actually not a very good idea, since there's no 100% guarantee the scanline positions in memory are sequential - inline const unsigned char *GetData() const - { - return _alBitmap->line[0]; - } + inline const unsigned char *GetData() const { + return _alBitmap->line[0]; + } - // Get scanline for direct reading - inline const unsigned char *GetScanLine(int index) const - { - return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; - } + // Get scanline for direct reading + inline const unsigned char *GetScanLine(int index) const { + return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; + } - void SetMaskColor(color_t color); - inline color_t GetMaskColor() const - { - return bitmap_mask_color(_alBitmap); - } + void SetMaskColor(color_t color); + inline color_t GetMaskColor() const { + return bitmap_mask_color(_alBitmap); + } - // FIXME: allegro manual states these should not be used externally; + // FIXME: allegro manual states these should not be used externally; // should hide or totally remove those later - void Acquire(); - void Release(); + void Acquire(); + void Release(); - // Converts AGS color-index into RGB color according to the bitmap format. - // TODO: this method was added to the Bitmap class during large refactoring, - // but that's a mistake, because in retrospect is has nothing to do with - // bitmap itself and should rather be a part of the game data logic. - color_t GetCompatibleColor(color_t color); + // Converts AGS color-index into RGB color according to the bitmap format. + // TODO: this method was added to the Bitmap class during large refactoring, + // but that's a mistake, because in retrospect is has nothing to do with + // bitmap itself and should rather be a part of the game data logic. + color_t GetCompatibleColor(color_t color); - //========================================================================= - // Clipping - //========================================================================= - void SetClip(const Rect &rc); - Rect GetClip() const; + //========================================================================= + // Clipping + //========================================================================= + void SetClip(const Rect &rc); + Rect GetClip() const; - //========================================================================= - // Blitting operations (drawing one bitmap over another) - //========================================================================= - // Draw other bitmap over current one - void Blit(Bitmap *src, int dst_x = 0, int dst_y = 0, BitmapMaskOption mask = kBitmap_Copy); - void Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask = kBitmap_Copy); - // Draw other bitmap in a masked mode (kBitmap_Transparency) - void MaskedBlit(Bitmap *src, int dst_x, int dst_y); - // Draw other bitmap, stretching or shrinking its size to given values - void StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); - void StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); - // Antia-aliased stretch-blit - void AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); - void AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); - // TODO: find more general way to call these operations, probably require pointer to Blending data struct? - // Draw bitmap using translucency preset - void TransBlendBlt(Bitmap *src, int dst_x, int dst_y); - // Draw bitmap using lighting preset - void LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount); - // TODO: generic "draw transformed" function? What about mask option? - void FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip); - void RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle); - void RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle); + //========================================================================= + // Blitting operations (drawing one bitmap over another) + //========================================================================= + // Draw other bitmap over current one + void Blit(Bitmap *src, int dst_x = 0, int dst_y = 0, BitmapMaskOption mask = kBitmap_Copy); + void Blit(Bitmap *src, int src_x, int src_y, int dst_x, int dst_y, int width, int height, BitmapMaskOption mask = kBitmap_Copy); + // Draw other bitmap in a masked mode (kBitmap_Transparency) + void MaskedBlit(Bitmap *src, int dst_x, int dst_y); + // Draw other bitmap, stretching or shrinking its size to given values + void StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + void StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + // Antia-aliased stretch-blit + void AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + void AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, BitmapMaskOption mask = kBitmap_Copy); + // TODO: find more general way to call these operations, probably require pointer to Blending data struct? + // Draw bitmap using translucency preset + void TransBlendBlt(Bitmap *src, int dst_x, int dst_y); + // Draw bitmap using lighting preset + void LitBlendBlt(Bitmap *src, int dst_x, int dst_y, int light_amount); + // TODO: generic "draw transformed" function? What about mask option? + void FlipBlt(Bitmap *src, int dst_x, int dst_y, BitmapFlip flip); + void RotateBlt(Bitmap *src, int dst_x, int dst_y, fixed_t angle); + void RotateBlt(Bitmap *src, int dst_x, int dst_y, int pivot_x, int pivot_y, fixed_t angle); - //========================================================================= - // Pixel operations - //========================================================================= - // Fills the whole bitmap with given color (black by default) - void Clear(color_t color = 0); - void ClearTransparent(); - // The PutPixel and GetPixel are supposed to be safe and therefore - // relatively slow operations. They should not be used for changing large - // blocks of bitmap memory - reading/writing from/to scan lines should be - // done in such cases. - void PutPixel(int x, int y, color_t color); - int GetPixel(int x, int y) const; + //========================================================================= + // Pixel operations + //========================================================================= + // Fills the whole bitmap with given color (black by default) + void Clear(color_t color = 0); + void ClearTransparent(); + // The PutPixel and GetPixel are supposed to be safe and therefore + // relatively slow operations. They should not be used for changing large + // blocks of bitmap memory - reading/writing from/to scan lines should be + // done in such cases. + void PutPixel(int x, int y, color_t color); + int GetPixel(int x, int y) const; - //========================================================================= - // Vector drawing operations - //========================================================================= - void DrawLine(const Line &ln, color_t color); - void DrawTriangle(const Triangle &tr, color_t color); - void DrawRect(const Rect &rc, color_t color); - void FillRect(const Rect &rc, color_t color); - void FillCircle(const Circle &circle, color_t color); - // Fills the whole bitmap with given color - void Fill(color_t color); - void FillTransparent(); - // Floodfills an enclosed area, starting at point - void FloodFill(int x, int y, color_t color); + //========================================================================= + // Vector drawing operations + //========================================================================= + void DrawLine(const Line &ln, color_t color); + void DrawTriangle(const Triangle &tr, color_t color); + void DrawRect(const Rect &rc, color_t color); + void FillRect(const Rect &rc, color_t color); + void FillCircle(const Circle &circle, color_t color); + // Fills the whole bitmap with given color + void Fill(color_t color); + void FillTransparent(); + // Floodfills an enclosed area, starting at point + void FloodFill(int x, int y, color_t color); //========================================================================= // Direct access operations //========================================================================= - // TODO: think how to increase safety over this (some fixed memory buffer class with iterator?) + // TODO: think how to increase safety over this (some fixed memory buffer class with iterator?) // Gets scanline for directly writing into it - inline unsigned char *GetScanLineForWriting(int index) - { - return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; - } - inline unsigned char *GetDataForWriting() - { - return _alBitmap->line[0]; - } - // Copies buffer contents into scanline - void SetScanLine(int index, unsigned char *data, int data_size = -1); + inline unsigned char *GetScanLineForWriting(int index) { + return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; + } + inline unsigned char *GetDataForWriting() { + return _alBitmap->line[0]; + } + // Copies buffer contents into scanline + void SetScanLine(int index, unsigned char *data, int data_size = -1); private: - BITMAP *_alBitmap; - bool _isDataOwner; + BITMAP *_alBitmap; + bool _isDataOwner; }; -namespace BitmapHelper -{ - // TODO: revise those functions later (currently needed in a few very specific cases) - // NOTE: the resulting object __owns__ bitmap data from now on - Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp); - // NOTE: the resulting object __does not own__ bitmap data - Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp); +namespace BitmapHelper { +// TODO: revise those functions later (currently needed in a few very specific cases) +// NOTE: the resulting object __owns__ bitmap data from now on +Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp); +// NOTE: the resulting object __does not own__ bitmap data +Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp); } // namespace BitmapHelper } // namespace Common diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp index 8f55ef9ddc86..85b22374cacb 100644 --- a/engines/ags/shared/gfx/bitmap.cpp +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -23,178 +23,148 @@ #include "gfx/bitmap.h" #include "util/memory.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // TODO: revise this construction later -namespace BitmapHelper -{ +namespace BitmapHelper { -Bitmap *CreateBitmap(int width, int height, int color_depth) -{ +Bitmap *CreateBitmap(int width, int height, int color_depth) { Bitmap *bitmap = new Bitmap(); - if (!bitmap->Create(width, height, color_depth)) - { + if (!bitmap->Create(width, height, color_depth)) { delete bitmap; bitmap = nullptr; } return bitmap; } -Bitmap *CreateTransparentBitmap(int width, int height, int color_depth) -{ - Bitmap *bitmap = new Bitmap(); - if (!bitmap->CreateTransparent(width, height, color_depth)) - { +Bitmap *CreateTransparentBitmap(int width, int height, int color_depth) { + Bitmap *bitmap = new Bitmap(); + if (!bitmap->CreateTransparent(width, height, color_depth)) { delete bitmap; bitmap = nullptr; } return bitmap; } -Bitmap *CreateSubBitmap(Bitmap *src, const Rect &rc) -{ +Bitmap *CreateSubBitmap(Bitmap *src, const Rect &rc) { Bitmap *bitmap = new Bitmap(); - if (!bitmap->CreateSubBitmap(src, rc)) - { + if (!bitmap->CreateSubBitmap(src, rc)) { delete bitmap; bitmap = nullptr; } return bitmap; } -Bitmap *CreateBitmapCopy(Bitmap *src, int color_depth) -{ - Bitmap *bitmap = new Bitmap(); - if (!bitmap->CreateCopy(src, color_depth)) - { +Bitmap *CreateBitmapCopy(Bitmap *src, int color_depth) { + Bitmap *bitmap = new Bitmap(); + if (!bitmap->CreateCopy(src, color_depth)) { delete bitmap; bitmap = nullptr; } return bitmap; } -Bitmap *LoadFromFile(const char *filename) -{ +Bitmap *LoadFromFile(const char *filename) { Bitmap *bitmap = new Bitmap(); - if (!bitmap->LoadFromFile(filename)) - { + if (!bitmap->LoadFromFile(filename)) { delete bitmap; bitmap = nullptr; } return bitmap; } -Bitmap *AdjustBitmapSize(Bitmap *src, int width, int height) -{ - int oldw = src->GetWidth(), oldh = src->GetHeight(); - if ((oldw == width) && (oldh == height)) - return src; - Bitmap *bmp = BitmapHelper::CreateBitmap(width, height, src->GetColorDepth()); - bmp->StretchBlt(src, RectWH(0, 0, oldw, oldh), RectWH(0, 0, width, height)); - return bmp; +Bitmap *AdjustBitmapSize(Bitmap *src, int width, int height) { + int oldw = src->GetWidth(), oldh = src->GetHeight(); + if ((oldw == width) && (oldh == height)) + return src; + Bitmap *bmp = BitmapHelper::CreateBitmap(width, height, src->GetColorDepth()); + bmp->StretchBlt(src, RectWH(0, 0, oldw, oldh), RectWH(0, 0, width, height)); + return bmp; } template -struct PixelTransCpy -{ - static const size_t BPP = BPP_; - inline void operator ()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const - { - if (*(TPx*)src == mask_color) - *(TPx*)dst = mask_color; - } +struct PixelTransCpy { + static const size_t BPP = BPP_; + inline void operator()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const { + if (*(TPx *)src == mask_color) + *(TPx *)dst = mask_color; + } }; -struct PixelNoSkip -{ - inline bool operator ()(uint8_t *data, color_t mask_color, bool use_alpha) const - { - return false; - } +struct PixelNoSkip { + inline bool operator()(uint8_t *data, color_t mask_color, bool use_alpha) const { + return false; + } }; typedef PixelTransCpy PixelTransCpy8; typedef PixelTransCpy PixelTransCpy16; -struct PixelTransCpy24 -{ - static const size_t BPP = 3; - inline void operator ()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const - { - const uint8_t *mcol_ptr = (const uint8_t*)&mask_color; - if (src[0] == mcol_ptr[0] && src[1] == mcol_ptr[1] && src[2] == mcol_ptr[2]) - { - dst[0] = mcol_ptr[0]; - dst[1] = mcol_ptr[1]; - dst[2] = mcol_ptr[2]; - } - } +struct PixelTransCpy24 { + static const size_t BPP = 3; + inline void operator()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const { + const uint8_t *mcol_ptr = (const uint8_t *)&mask_color; + if (src[0] == mcol_ptr[0] && src[1] == mcol_ptr[1] && src[2] == mcol_ptr[2]) { + dst[0] = mcol_ptr[0]; + dst[1] = mcol_ptr[1]; + dst[2] = mcol_ptr[2]; + } + } }; -struct PixelTransCpy32 -{ - static const size_t BPP = 4; - inline void operator ()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const - { - if (*(const uint32_t*)src == mask_color) - *(uint32_t*)dst = mask_color; - else if (use_alpha) - dst[3] = src[3]; // copy alpha channel - else - dst[3] = 0xFF; // set the alpha channel byte to opaque - } +struct PixelTransCpy32 { + static const size_t BPP = 4; + inline void operator()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const { + if (*(const uint32_t *)src == mask_color) + *(uint32_t *)dst = mask_color; + else if (use_alpha) + dst[3] = src[3]; // copy alpha channel + else + dst[3] = 0xFF; // set the alpha channel byte to opaque + } }; -struct PixelTransSkip32 -{ - inline bool operator ()(uint8_t *data, color_t mask_color, bool use_alpha) const - { - return *(uint32_t*)data == mask_color || (use_alpha && data[3] == 0); - } +struct PixelTransSkip32 { + inline bool operator()(uint8_t *data, color_t mask_color, bool use_alpha) const { + return *(uint32_t *)data == mask_color || (use_alpha && data[3] == 0); + } }; template -void ApplyMask(uint8_t *dst, const uint8_t *src, size_t pitch, size_t height, FnPxProc proc, FnSkip skip, color_t mask_color, bool dst_has_alpha, bool mask_has_alpha) -{ - for (size_t y = 0; y < height; ++y) - { - for (size_t x = 0; x < pitch; x += FnPxProc::BPP, src += FnPxProc::BPP, dst += FnPxProc::BPP) - { - if (!skip(dst, mask_color, dst_has_alpha)) - proc(dst, src, mask_color, mask_has_alpha); - } - } +void ApplyMask(uint8_t *dst, const uint8_t *src, size_t pitch, size_t height, FnPxProc proc, FnSkip skip, color_t mask_color, bool dst_has_alpha, bool mask_has_alpha) { + for (size_t y = 0; y < height; ++y) { + for (size_t x = 0; x < pitch; x += FnPxProc::BPP, src += FnPxProc::BPP, dst += FnPxProc::BPP) { + if (!skip(dst, mask_color, dst_has_alpha)) + proc(dst, src, mask_color, mask_has_alpha); + } + } } -void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bool mask_has_alpha) -{ - color_t mask_color = mask->GetMaskColor(); - uint8_t *dst_ptr = dst->GetDataForWriting(); - const uint8_t *src_ptr = mask->GetData(); - const size_t bpp = mask->GetBPP(); - const size_t pitch = mask->GetLineLength(); - const size_t height = mask->GetHeight(); - - if (bpp == 1) - ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy8(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); - else if (bpp == 2) - ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy16(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); - else if (bpp == 3) - ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy24(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); - else - ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy32(), PixelTransSkip32(), mask_color, dst_has_alpha, mask_has_alpha); +void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bool mask_has_alpha) { + color_t mask_color = mask->GetMaskColor(); + uint8_t *dst_ptr = dst->GetDataForWriting(); + const uint8_t *src_ptr = mask->GetData(); + const size_t bpp = mask->GetBPP(); + const size_t pitch = mask->GetLineLength(); + const size_t height = mask->GetHeight(); + + if (bpp == 1) + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy8(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); + else if (bpp == 2) + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy16(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); + else if (bpp == 3) + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy24(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); + else + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy32(), PixelTransSkip32(), mask_color, dst_has_alpha, mask_has_alpha); } -void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t src_pitch, const size_t src_px_offset) -{ - const size_t bpp = dst->GetBPP(); - const size_t src_px_pitch = src_pitch / bpp; - if (src_px_offset >= src_px_pitch) - return; // nothing to copy - Memory::BlockCopy(dst->GetDataForWriting(), dst->GetLineLength(), 0, src_buffer, src_pitch, src_px_offset * bpp, dst->GetHeight()); +void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t src_pitch, const size_t src_px_offset) { + const size_t bpp = dst->GetBPP(); + const size_t src_px_pitch = src_pitch / bpp; + if (src_px_offset >= src_px_pitch) + return; // nothing to copy + Memory::BlockCopy(dst->GetDataForWriting(), dst->GetLineLength(), 0, src_buffer, src_pitch, src_px_offset * bpp, dst->GetHeight()); } } // namespace BitmapHelper diff --git a/engines/ags/shared/gfx/bitmap.h b/engines/ags/shared/gfx/bitmap.h index 7d0a7e99a2eb..3dac81c1e60a 100644 --- a/engines/ags/shared/gfx/bitmap.h +++ b/engines/ags/shared/gfx/bitmap.h @@ -31,22 +31,18 @@ #include "util/geometry.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // Mask option for blitting one bitmap on another -enum BitmapMaskOption -{ +enum BitmapMaskOption { // Plain copies bitmap pixels kBitmap_Copy, // Consider mask color fully transparent and do not copy pixels having it kBitmap_Transparency }; -enum BitmapFlip -{ +enum BitmapFlip { kBitmap_HFlip, kBitmap_VFlip, kBitmap_HVFlip @@ -59,37 +55,34 @@ enum BitmapFlip // Declare the actual bitmap class #include "gfx/allegrobitmap.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class Bitmap; // TODO: revise this construction later -namespace BitmapHelper -{ - // Helper functions, that delete faulty bitmaps automatically, and return - // NULL if bitmap could not be created. - Bitmap *CreateBitmap(int width, int height, int color_depth = 0); - Bitmap *CreateTransparentBitmap(int width, int height, int color_depth = 0); - Bitmap *CreateSubBitmap(Bitmap *src, const Rect &rc); - Bitmap *CreateBitmapCopy(Bitmap *src, int color_depth = 0); - Bitmap *LoadFromFile(const char *filename); +namespace BitmapHelper { +// Helper functions, that delete faulty bitmaps automatically, and return +// NULL if bitmap could not be created. +Bitmap *CreateBitmap(int width, int height, int color_depth = 0); +Bitmap *CreateTransparentBitmap(int width, int height, int color_depth = 0); +Bitmap *CreateSubBitmap(Bitmap *src, const Rect &rc); +Bitmap *CreateBitmapCopy(Bitmap *src, int color_depth = 0); +Bitmap *LoadFromFile(const char *filename); - // Stretches bitmap to the requested size. The new bitmap will have same - // colour depth. Returns original bitmap if no changes are necessary. - Bitmap *AdjustBitmapSize(Bitmap *src, int width, int height); - // Copy transparency mask and/or alpha channel from one bitmap into another. - // Destination and mask bitmaps must be of the same pixel format. - // Transparency is merged, meaning that fully transparent pixels on - // destination should remain such regardless of mask pixel values. - void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bool mask_has_alpha); - // Copy pixel data into bitmap from memory buffer. It is required that the - // source matches bitmap format and has enough data. - // Pitch is given in bytes and defines the length of the source scan line. - // Offset is optional and defines horizontal offset, in pixels. - void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t src_pitch, const size_t src_px_offset = 0); +// Stretches bitmap to the requested size. The new bitmap will have same +// colour depth. Returns original bitmap if no changes are necessary. +Bitmap *AdjustBitmapSize(Bitmap *src, int width, int height); +// Copy transparency mask and/or alpha channel from one bitmap into another. +// Destination and mask bitmaps must be of the same pixel format. +// Transparency is merged, meaning that fully transparent pixels on +// destination should remain such regardless of mask pixel values. +void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bool mask_has_alpha); +// Copy pixel data into bitmap from memory buffer. It is required that the +// source matches bitmap format and has enough data. +// Pitch is given in bytes and defines the length of the source scan line. +// Offset is optional and defines horizontal offset, in pixels. +void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t src_pitch, const size_t src_px_offset = 0); } // namespace BitmapHelper } // namespace Common diff --git a/engines/ags/shared/gfx/gfx_def.h b/engines/ags/shared/gfx/gfx_def.h index af0582ae1d55..787839fd8dae 100644 --- a/engines/ags/shared/gfx/gfx_def.h +++ b/engines/ags/shared/gfx/gfx_def.h @@ -29,97 +29,77 @@ #ifndef AGS_SHARED_GFX_GFXDEF_H #define AGS_SHARED_GFX_GFXDEF_H -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -enum BlendMode -{ - // free blending (ARGB -> ARGB) modes - kBlendMode_NoAlpha = 0, // ignore alpha channel - kBlendMode_Alpha, // alpha-blend src to dest, combining src & dest alphas - // NOTE: add new modes here +enum BlendMode { + // free blending (ARGB -> ARGB) modes + kBlendMode_NoAlpha = 0, // ignore alpha channel + kBlendMode_Alpha, // alpha-blend src to dest, combining src & dest alphas + // NOTE: add new modes here - kNumBlendModes + kNumBlendModes }; -namespace GfxDef -{ - inline int Trans100ToAlpha255(int transparency) - { - return ((100 - transparency) * 255) / 100; - } +namespace GfxDef { +inline int Trans100ToAlpha255(int transparency) { + return ((100 - transparency) * 255) / 100; +} - inline int Alpha255ToTrans100(int alpha) - { - return 100 - ((alpha * 100) / 255); - } +inline int Alpha255ToTrans100(int alpha) { + return 100 - ((alpha * 100) / 255); +} - // Special formulae to reduce precision loss and support flawless forth & - // reverse conversion for multiplies of 10% - inline int Trans100ToAlpha250(int transparency) - { - return ((100 - transparency) * 25) / 10; - } +// Special formulae to reduce precision loss and support flawless forth & +// reverse conversion for multiplies of 10% +inline int Trans100ToAlpha250(int transparency) { + return ((100 - transparency) * 25) / 10; +} - inline int Alpha250ToTrans100(int alpha) - { - return 100 - ((alpha * 10) / 25); - } +inline int Alpha250ToTrans100(int alpha) { + return 100 - ((alpha * 10) / 25); +} - // Convert correct 100-ranged transparency into legacy 255-ranged - // transparency; legacy inconsistent transparency value range: - // 0 = opaque, - // 255 = invisible, - // 1 -to- 254 = barely visible -to- mostly visible (as proper alpha) - inline int Trans100ToLegacyTrans255(int transparency) - { - if (transparency == 0) - { - return 0; // this means opaque - } - else if (transparency == 100) - { - return 255; // this means invisible - } - // the rest of the range works as alpha - return Trans100ToAlpha250(transparency); - } +// Convert correct 100-ranged transparency into legacy 255-ranged +// transparency; legacy inconsistent transparency value range: +// 0 = opaque, +// 255 = invisible, +// 1 -to- 254 = barely visible -to- mostly visible (as proper alpha) +inline int Trans100ToLegacyTrans255(int transparency) { + if (transparency == 0) { + return 0; // this means opaque + } else if (transparency == 100) { + return 255; // this means invisible + } + // the rest of the range works as alpha + return Trans100ToAlpha250(transparency); +} - // Convert legacy 255-ranged "incorrect" transparency into proper - // 100-ranged transparency. - inline int LegacyTrans255ToTrans100(int legacy_transparency) - { - if (legacy_transparency == 0) - { - return 0; // this means opaque - } - else if (legacy_transparency == 255) - { - return 100; // this means invisible - } - // the rest of the range works as alpha - return Alpha250ToTrans100(legacy_transparency); - } +// Convert legacy 255-ranged "incorrect" transparency into proper +// 100-ranged transparency. +inline int LegacyTrans255ToTrans100(int legacy_transparency) { + if (legacy_transparency == 0) { + return 0; // this means opaque + } else if (legacy_transparency == 255) { + return 100; // this means invisible + } + // the rest of the range works as alpha + return Alpha250ToTrans100(legacy_transparency); +} - // Convert legacy 100-ranged transparency into proper 255-ranged alpha - // 0 => alpha 255 - // 100 => alpha 0 - // 1 - 99 => alpha 1 - 244 - inline int LegacyTrans100ToAlpha255(int legacy_transparency) - { - if (legacy_transparency == 0) - { - return 255; // this means opaque - } - else if (legacy_transparency == 100) - { - return 0; // this means invisible - } - // the rest of the range works as alpha (only 100-ranged) - return legacy_transparency * 255 / 100; - } +// Convert legacy 100-ranged transparency into proper 255-ranged alpha +// 0 => alpha 255 +// 100 => alpha 0 +// 1 - 99 => alpha 1 - 244 +inline int LegacyTrans100ToAlpha255(int legacy_transparency) { + if (legacy_transparency == 0) { + return 255; // this means opaque + } else if (legacy_transparency == 100) { + return 0; // this means invisible + } + // the rest of the range works as alpha (only 100-ranged) + return legacy_transparency * 255 / 100; +} } // namespace GfxDef } // namespace Common diff --git a/engines/ags/shared/gui/guibutton.cpp b/engines/ags/shared/gui/guibutton.cpp index 171a203d1213..9859e4e312e9 100644 --- a/engines/ags/shared/gui/guibutton.cpp +++ b/engines/ags/shared/gui/guibutton.cpp @@ -29,363 +29,321 @@ std::vector guibuts; int numguibuts = 0; -namespace AGS -{ -namespace Common -{ - -FrameAlignment ConvertLegacyButtonAlignment(LegacyButtonAlignment align) -{ - switch (align) - { - case kLegacyButtonAlign_TopCenter: - return kAlignTopCenter; - case kLegacyButtonAlign_TopLeft: - return kAlignTopLeft; - case kLegacyButtonAlign_TopRight: - return kAlignTopRight; - case kLegacyButtonAlign_CenterLeft: - return kAlignMiddleLeft; - case kLegacyButtonAlign_Centered: - return kAlignMiddleCenter; - case kLegacyButtonAlign_CenterRight: - return kAlignMiddleRight; - case kLegacyButtonAlign_BottomLeft: - return kAlignBottomLeft; - case kLegacyButtonAlign_BottomCenter: - return kAlignBottomCenter; - case kLegacyButtonAlign_BottomRight: - return kAlignBottomRight; - } - return kAlignNone; +namespace AGS { +namespace Common { + +FrameAlignment ConvertLegacyButtonAlignment(LegacyButtonAlignment align) { + switch (align) { + case kLegacyButtonAlign_TopCenter: + return kAlignTopCenter; + case kLegacyButtonAlign_TopLeft: + return kAlignTopLeft; + case kLegacyButtonAlign_TopRight: + return kAlignTopRight; + case kLegacyButtonAlign_CenterLeft: + return kAlignMiddleLeft; + case kLegacyButtonAlign_Centered: + return kAlignMiddleCenter; + case kLegacyButtonAlign_CenterRight: + return kAlignMiddleRight; + case kLegacyButtonAlign_BottomLeft: + return kAlignBottomLeft; + case kLegacyButtonAlign_BottomCenter: + return kAlignBottomCenter; + case kLegacyButtonAlign_BottomRight: + return kAlignBottomRight; + } + return kAlignNone; } -GUIButton::GUIButton() -{ - Image = -1; - MouseOverImage = -1; - PushedImage = -1; - CurrentImage = -1; - Font = 0; - TextColor = 0; - TextAlignment = kAlignTopCenter; - ClickAction[kMouseLeft] = kGUIAction_RunScript; - ClickAction[kMouseRight] = kGUIAction_RunScript; - ClickData[kMouseLeft] = 0; - ClickData[kMouseRight] = 0; - - IsPushed = false; - IsMouseOver = false; - _placeholder = kButtonPlace_None; - _unnamed = false; - - _scEventCount = 1; - _scEventNames[0] = "Click"; - _scEventArgs[0] = "GUIControl *control, MouseButton button"; +GUIButton::GUIButton() { + Image = -1; + MouseOverImage = -1; + PushedImage = -1; + CurrentImage = -1; + Font = 0; + TextColor = 0; + TextAlignment = kAlignTopCenter; + ClickAction[kMouseLeft] = kGUIAction_RunScript; + ClickAction[kMouseRight] = kGUIAction_RunScript; + ClickData[kMouseLeft] = 0; + ClickData[kMouseRight] = 0; + + IsPushed = false; + IsMouseOver = false; + _placeholder = kButtonPlace_None; + _unnamed = false; + + _scEventCount = 1; + _scEventNames[0] = "Click"; + _scEventArgs[0] = "GUIControl *control, MouseButton button"; } -const String &GUIButton::GetText() const -{ - return _text; +const String &GUIButton::GetText() const { + return _text; } -bool GUIButton::IsClippingImage() const -{ - return (Flags & kGUICtrl_Clip) != 0; +bool GUIButton::IsClippingImage() const { + return (Flags & kGUICtrl_Clip) != 0; } -void GUIButton::Draw(Bitmap *ds) -{ - bool draw_disabled = !IsGUIEnabled(this); - - check_font(&Font); - // if it's "Unchanged when disabled" or "GUI Off", don't grey out - if (gui_disabled_style == GUIDIS_UNCHANGED || - gui_disabled_style == GUIDIS_GUIOFF) - { - draw_disabled = false; - } - // TODO: should only change properties in reaction to particular events - if (CurrentImage <= 0 || draw_disabled) - CurrentImage = Image; - - if (draw_disabled && gui_disabled_style == GUIDIS_BLACKOUT) - // buttons off when disabled - no point carrying on - return; - - // CHECKME: why testing both CurrentImage and Image? - if (CurrentImage > 0 && Image > 0) - DrawImageButton(ds, draw_disabled); - // CHECKME: why don't draw frame if no Text? this will make button completely invisible! - else if (!_text.IsEmpty()) - DrawTextButton(ds, draw_disabled); +void GUIButton::Draw(Bitmap *ds) { + bool draw_disabled = !IsGUIEnabled(this); + + check_font(&Font); + // if it's "Unchanged when disabled" or "GUI Off", don't grey out + if (gui_disabled_style == GUIDIS_UNCHANGED || + gui_disabled_style == GUIDIS_GUIOFF) { + draw_disabled = false; + } + // TODO: should only change properties in reaction to particular events + if (CurrentImage <= 0 || draw_disabled) + CurrentImage = Image; + + if (draw_disabled && gui_disabled_style == GUIDIS_BLACKOUT) + // buttons off when disabled - no point carrying on + return; + + // CHECKME: why testing both CurrentImage and Image? + if (CurrentImage > 0 && Image > 0) + DrawImageButton(ds, draw_disabled); + // CHECKME: why don't draw frame if no Text? this will make button completely invisible! + else if (!_text.IsEmpty()) + DrawTextButton(ds, draw_disabled); } -void GUIButton::SetClipImage(bool on) -{ - if (on) - Flags |= kGUICtrl_Clip; - else - Flags &= ~kGUICtrl_Clip; +void GUIButton::SetClipImage(bool on) { + if (on) + Flags |= kGUICtrl_Clip; + else + Flags &= ~kGUICtrl_Clip; } -void GUIButton::SetText(const String &text) -{ - _text = text; - // Active inventory item placeholders - if (_text.CompareNoCase("(INV)") == 0) - // Stretch to fit button - _placeholder = kButtonPlace_InvItemStretch; - else if (_text.CompareNoCase("(INVNS)") == 0) - // Draw at actual size - _placeholder = kButtonPlace_InvItemCenter; - else if (_text.CompareNoCase("(INVSHR)") == 0) - // Stretch if too big, actual size if not - _placeholder = kButtonPlace_InvItemAuto; - else - _placeholder = kButtonPlace_None; - - // TODO: find a way to remove this bogus limitation ("New Button" is a valid Text too) - _unnamed = _text.Compare("New Button") == 0; +void GUIButton::SetText(const String &text) { + _text = text; + // Active inventory item placeholders + if (_text.CompareNoCase("(INV)") == 0) + // Stretch to fit button + _placeholder = kButtonPlace_InvItemStretch; + else if (_text.CompareNoCase("(INVNS)") == 0) + // Draw at actual size + _placeholder = kButtonPlace_InvItemCenter; + else if (_text.CompareNoCase("(INVSHR)") == 0) + // Stretch if too big, actual size if not + _placeholder = kButtonPlace_InvItemAuto; + else + _placeholder = kButtonPlace_None; + + // TODO: find a way to remove this bogus limitation ("New Button" is a valid Text too) + _unnamed = _text.Compare("New Button") == 0; } -bool GUIButton::OnMouseDown() -{ - if (PushedImage > 0) - CurrentImage = PushedImage; - IsPushed = true; - return false; +bool GUIButton::OnMouseDown() { + if (PushedImage > 0) + CurrentImage = PushedImage; + IsPushed = true; + return false; } -void GUIButton::OnMouseEnter() -{ - CurrentImage = IsPushed ? PushedImage : MouseOverImage; - IsMouseOver = true; +void GUIButton::OnMouseEnter() { + CurrentImage = IsPushed ? PushedImage : MouseOverImage; + IsMouseOver = true; } -void GUIButton::OnMouseLeave() -{ - CurrentImage = Image; - IsMouseOver = false; +void GUIButton::OnMouseLeave() { + CurrentImage = Image; + IsMouseOver = false; } -void GUIButton::OnMouseUp() -{ - if (IsMouseOver) - { - CurrentImage = MouseOverImage; - if (IsGUIEnabled(this) && IsClickable()) - IsActivated = true; - } - else - { - CurrentImage = Image; - } - - IsPushed = false; +void GUIButton::OnMouseUp() { + if (IsMouseOver) { + CurrentImage = MouseOverImage; + if (IsGUIEnabled(this) && IsClickable()) + IsActivated = true; + } else { + CurrentImage = Image; + } + + IsPushed = false; } // TODO: replace string serialization with StrUtil::ReadString and WriteString // methods in the future, to keep this organized. -void GUIButton::WriteToFile(Stream *out) const -{ - GUIObject::WriteToFile(out); - - out->WriteInt32(Image); - out->WriteInt32(MouseOverImage); - out->WriteInt32(PushedImage); - out->WriteInt32(Font); - out->WriteInt32(TextColor); - out->WriteInt32(ClickAction[kMouseLeft]); - out->WriteInt32(ClickAction[kMouseRight]); - out->WriteInt32(ClickData[kMouseLeft]); - out->WriteInt32(ClickData[kMouseRight]); - - StrUtil::WriteString(_text, out); - out->WriteInt32(TextAlignment); +void GUIButton::WriteToFile(Stream *out) const { + GUIObject::WriteToFile(out); + + out->WriteInt32(Image); + out->WriteInt32(MouseOverImage); + out->WriteInt32(PushedImage); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(ClickAction[kMouseLeft]); + out->WriteInt32(ClickAction[kMouseRight]); + out->WriteInt32(ClickData[kMouseLeft]); + out->WriteInt32(ClickData[kMouseRight]); + + StrUtil::WriteString(_text, out); + out->WriteInt32(TextAlignment); } -void GUIButton::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - GUIObject::ReadFromFile(in, gui_version); - - Image = in->ReadInt32(); - MouseOverImage = in->ReadInt32(); - PushedImage = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - { // NOTE: reading into actual variables only for old savegame support - CurrentImage = in->ReadInt32(); - IsPushed = in->ReadInt32() != 0; - IsMouseOver = in->ReadInt32() != 0; - } - Font = in->ReadInt32(); - TextColor = in->ReadInt32(); - ClickAction[kMouseLeft] = (GUIClickAction)in->ReadInt32(); - ClickAction[kMouseRight] = (GUIClickAction)in->ReadInt32(); - ClickData[kMouseLeft] = in->ReadInt32(); - ClickData[kMouseRight] = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - SetText(String::FromStreamCount(in, GUIBUTTON_LEGACY_TEXTLENGTH)); - else - SetText(StrUtil::ReadString(in)); - - if (gui_version >= kGuiVersion_272a) - { - if (gui_version < kGuiVersion_350) - { - TextAlignment = ConvertLegacyButtonAlignment((LegacyButtonAlignment)in->ReadInt32()); - in->ReadInt32(); // reserved1 - } - else - { - TextAlignment = (FrameAlignment)in->ReadInt32(); - } - } - else - { - TextAlignment = kAlignTopCenter; - } - - if (TextColor == 0) - TextColor = 16; - CurrentImage = Image; - // All buttons are translated at the moment - Flags |= kGUICtrl_Translated; +void GUIButton::ReadFromFile(Stream *in, GuiVersion gui_version) { + GUIObject::ReadFromFile(in, gui_version); + + Image = in->ReadInt32(); + MouseOverImage = in->ReadInt32(); + PushedImage = in->ReadInt32(); + if (gui_version < kGuiVersion_350) { + // NOTE: reading into actual variables only for old savegame support + CurrentImage = in->ReadInt32(); + IsPushed = in->ReadInt32() != 0; + IsMouseOver = in->ReadInt32() != 0; + } + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + ClickAction[kMouseLeft] = (GUIClickAction)in->ReadInt32(); + ClickAction[kMouseRight] = (GUIClickAction)in->ReadInt32(); + ClickData[kMouseLeft] = in->ReadInt32(); + ClickData[kMouseRight] = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + SetText(String::FromStreamCount(in, GUIBUTTON_LEGACY_TEXTLENGTH)); + else + SetText(StrUtil::ReadString(in)); + + if (gui_version >= kGuiVersion_272a) { + if (gui_version < kGuiVersion_350) { + TextAlignment = ConvertLegacyButtonAlignment((LegacyButtonAlignment)in->ReadInt32()); + in->ReadInt32(); // reserved1 + } else { + TextAlignment = (FrameAlignment)in->ReadInt32(); + } + } else { + TextAlignment = kAlignTopCenter; + } + + if (TextColor == 0) + TextColor = 16; + CurrentImage = Image; + // All buttons are translated at the moment + Flags |= kGUICtrl_Translated; } -void GUIButton::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) -{ - GUIObject::ReadFromSavegame(in, svg_ver); - // Properties - Image = in->ReadInt32(); - MouseOverImage = in->ReadInt32(); - PushedImage = in->ReadInt32(); - Font = in->ReadInt32(); - TextColor = in->ReadInt32(); - SetText(StrUtil::ReadString(in)); - if (svg_ver >= kGuiSvgVersion_350) - TextAlignment = (FrameAlignment)in->ReadInt32(); - // Dynamic state - Image = in->ReadInt32(); +void GUIButton::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { + GUIObject::ReadFromSavegame(in, svg_ver); + // Properties + Image = in->ReadInt32(); + MouseOverImage = in->ReadInt32(); + PushedImage = in->ReadInt32(); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + SetText(StrUtil::ReadString(in)); + if (svg_ver >= kGuiSvgVersion_350) + TextAlignment = (FrameAlignment)in->ReadInt32(); + // Dynamic state + Image = in->ReadInt32(); } -void GUIButton::WriteToSavegame(Stream *out) const -{ - // Properties - GUIObject::WriteToSavegame(out); - out->WriteInt32(Image); - out->WriteInt32(MouseOverImage); - out->WriteInt32(PushedImage); - out->WriteInt32(Font); - out->WriteInt32(TextColor); - StrUtil::WriteString(GetText(), out); - out->WriteInt32(TextAlignment); - // Dynamic state - out->WriteInt32(Image); +void GUIButton::WriteToSavegame(Stream *out) const { + // Properties + GUIObject::WriteToSavegame(out); + out->WriteInt32(Image); + out->WriteInt32(MouseOverImage); + out->WriteInt32(PushedImage); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + StrUtil::WriteString(GetText(), out); + out->WriteInt32(TextAlignment); + // Dynamic state + out->WriteInt32(Image); } -void GUIButton::DrawImageButton(Bitmap *ds, bool draw_disabled) -{ - // NOTE: the CLIP flag only clips the image, not the text - if (IsClippingImage()) - ds->SetClip(Rect(X, Y, X + Width - 1, Y + Height - 1)); - if (spriteset[CurrentImage] != nullptr) - draw_gui_sprite(ds, CurrentImage, X, Y, true); - - // Draw active inventory item - if (_placeholder != kButtonPlace_None && gui_inv_pic >= 0) - { - GUIButtonPlaceholder place = _placeholder; - if (place == kButtonPlace_InvItemAuto) - { - if ((get_adjusted_spritewidth(gui_inv_pic) > Width - 6) || - (get_adjusted_spriteheight(gui_inv_pic) > Height - 6)) - { - place = kButtonPlace_InvItemStretch; - } - else - { - place = kButtonPlace_InvItemCenter; - } - } - - if (place == kButtonPlace_InvItemStretch) - { - ds->StretchBlt(spriteset[gui_inv_pic], RectWH(X + 3, Y + 3, Width - 6, Height - 6), Common::kBitmap_Transparency); - } - else if (place == kButtonPlace_InvItemCenter) - { - draw_gui_sprite(ds, gui_inv_pic, - X + Width / 2 - get_adjusted_spritewidth(gui_inv_pic) / 2, - Y + Height / 2 - get_adjusted_spriteheight(gui_inv_pic) / 2, - true); - } - } - - if ((draw_disabled) && (gui_disabled_style == GUIDIS_GREYOUT)) - { - // darken the button when disabled - GUI::DrawDisabledEffect(ds, RectWH(X, Y, - spriteset[CurrentImage]->GetWidth(), - spriteset[CurrentImage]->GetHeight())); - } - ds->SetClip(Rect(0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1)); - - // Don't print Text of (INV) (INVSHR) (INVNS) - if (_placeholder == kButtonPlace_None && !_unnamed) - DrawText(ds, draw_disabled); +void GUIButton::DrawImageButton(Bitmap *ds, bool draw_disabled) { + // NOTE: the CLIP flag only clips the image, not the text + if (IsClippingImage()) + ds->SetClip(Rect(X, Y, X + Width - 1, Y + Height - 1)); + if (spriteset[CurrentImage] != nullptr) + draw_gui_sprite(ds, CurrentImage, X, Y, true); + + // Draw active inventory item + if (_placeholder != kButtonPlace_None && gui_inv_pic >= 0) { + GUIButtonPlaceholder place = _placeholder; + if (place == kButtonPlace_InvItemAuto) { + if ((get_adjusted_spritewidth(gui_inv_pic) > Width - 6) || + (get_adjusted_spriteheight(gui_inv_pic) > Height - 6)) { + place = kButtonPlace_InvItemStretch; + } else { + place = kButtonPlace_InvItemCenter; + } + } + + if (place == kButtonPlace_InvItemStretch) { + ds->StretchBlt(spriteset[gui_inv_pic], RectWH(X + 3, Y + 3, Width - 6, Height - 6), Common::kBitmap_Transparency); + } else if (place == kButtonPlace_InvItemCenter) { + draw_gui_sprite(ds, gui_inv_pic, + X + Width / 2 - get_adjusted_spritewidth(gui_inv_pic) / 2, + Y + Height / 2 - get_adjusted_spriteheight(gui_inv_pic) / 2, + true); + } + } + + if ((draw_disabled) && (gui_disabled_style == GUIDIS_GREYOUT)) { + // darken the button when disabled + GUI::DrawDisabledEffect(ds, RectWH(X, Y, + spriteset[CurrentImage]->GetWidth(), + spriteset[CurrentImage]->GetHeight())); + } + ds->SetClip(Rect(0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1)); + + // Don't print Text of (INV) (INVSHR) (INVNS) + if (_placeholder == kButtonPlace_None && !_unnamed) + DrawText(ds, draw_disabled); } -void GUIButton::DrawText(Bitmap *ds, bool draw_disabled) -{ - if (_text.IsEmpty()) - return; - // TODO: need to find a way to cache Text prior to drawing; - // but that will require to update all gui controls when translation is changed in game - PrepareTextToDraw(); - - Rect frame = RectWH(X + 2, Y + 2, Width - 4, Height - 4); - if (IsPushed && IsMouseOver) - { - // move the Text a bit while pushed - frame.Left++; - frame.Top++; - } - color_t text_color = ds->GetCompatibleColor(TextColor); - if (draw_disabled) - text_color = ds->GetCompatibleColor(8); - GUI::DrawTextAligned(ds, _textToDraw, Font, text_color, frame, TextAlignment); +void GUIButton::DrawText(Bitmap *ds, bool draw_disabled) { + if (_text.IsEmpty()) + return; + // TODO: need to find a way to cache Text prior to drawing; + // but that will require to update all gui controls when translation is changed in game + PrepareTextToDraw(); + + Rect frame = RectWH(X + 2, Y + 2, Width - 4, Height - 4); + if (IsPushed && IsMouseOver) { + // move the Text a bit while pushed + frame.Left++; + frame.Top++; + } + color_t text_color = ds->GetCompatibleColor(TextColor); + if (draw_disabled) + text_color = ds->GetCompatibleColor(8); + GUI::DrawTextAligned(ds, _textToDraw, Font, text_color, frame, TextAlignment); } -void GUIButton::DrawTextButton(Bitmap *ds, bool draw_disabled) -{ - color_t draw_color = ds->GetCompatibleColor(7); - ds->FillRect(Rect(X, Y, X + Width - 1, Y + Height - 1), draw_color); - if (Flags & kGUICtrl_Default) - { - draw_color = ds->GetCompatibleColor(16); - ds->DrawRect(Rect(X - 1, Y - 1, X + Width, Y + Height), draw_color); - } - - // TODO: use color constants instead of literal numbers - if (!draw_disabled && IsMouseOver && IsPushed) - draw_color = ds->GetCompatibleColor(15); - else - draw_color = ds->GetCompatibleColor(8); - - ds->DrawLine(Line(X, Y + Height - 1, X + Width - 1, Y + Height - 1), draw_color); - ds->DrawLine(Line(X + Width - 1, Y, X + Width - 1, Y + Height - 1), draw_color); - - if (draw_disabled || (IsMouseOver && IsPushed)) - draw_color = ds->GetCompatibleColor(8); - else - draw_color = ds->GetCompatibleColor(15); - - ds->DrawLine(Line(X, Y, X + Width - 1, Y), draw_color); - ds->DrawLine(Line(X, Y, X, Y + Height - 1), draw_color); - - DrawText(ds, draw_disabled); +void GUIButton::DrawTextButton(Bitmap *ds, bool draw_disabled) { + color_t draw_color = ds->GetCompatibleColor(7); + ds->FillRect(Rect(X, Y, X + Width - 1, Y + Height - 1), draw_color); + if (Flags & kGUICtrl_Default) { + draw_color = ds->GetCompatibleColor(16); + ds->DrawRect(Rect(X - 1, Y - 1, X + Width, Y + Height), draw_color); + } + + // TODO: use color constants instead of literal numbers + if (!draw_disabled && IsMouseOver && IsPushed) + draw_color = ds->GetCompatibleColor(15); + else + draw_color = ds->GetCompatibleColor(8); + + ds->DrawLine(Line(X, Y + Height - 1, X + Width - 1, Y + Height - 1), draw_color); + ds->DrawLine(Line(X + Width - 1, Y, X + Width - 1, Y + Height - 1), draw_color); + + if (draw_disabled || (IsMouseOver && IsPushed)) + draw_color = ds->GetCompatibleColor(8); + else + draw_color = ds->GetCompatibleColor(15); + + ds->DrawLine(Line(X, Y, X + Width - 1, Y), draw_color); + ds->DrawLine(Line(X, Y, X, Y + Height - 1), draw_color); + + DrawText(ds, draw_disabled); } } // namespace Common diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index 8637c05aab4b..72315b66bde0 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -29,107 +29,100 @@ #define GUIBUTTON_LEGACY_TEXTLENGTH 50 -namespace AGS -{ -namespace Common -{ - -enum MouseButton -{ - kMouseNone = -1, - kMouseLeft = 0, - kMouseRight = 1, +namespace AGS { +namespace Common { + +enum MouseButton { + kMouseNone = -1, + kMouseLeft = 0, + kMouseRight = 1, }; -enum GUIClickAction -{ - kGUIAction_None = 0, - kGUIAction_SetMode = 1, - kGUIAction_RunScript = 2, +enum GUIClickAction { + kGUIAction_None = 0, + kGUIAction_SetMode = 1, + kGUIAction_RunScript = 2, }; -enum LegacyButtonAlignment -{ - kLegacyButtonAlign_TopCenter = 0, - kLegacyButtonAlign_TopLeft = 1, - kLegacyButtonAlign_TopRight = 2, - kLegacyButtonAlign_CenterLeft = 3, - kLegacyButtonAlign_Centered = 4, - kLegacyButtonAlign_CenterRight = 5, - kLegacyButtonAlign_BottomLeft = 6, - kLegacyButtonAlign_BottomCenter = 7, - kLegacyButtonAlign_BottomRight = 8, +enum LegacyButtonAlignment { + kLegacyButtonAlign_TopCenter = 0, + kLegacyButtonAlign_TopLeft = 1, + kLegacyButtonAlign_TopRight = 2, + kLegacyButtonAlign_CenterLeft = 3, + kLegacyButtonAlign_Centered = 4, + kLegacyButtonAlign_CenterRight = 5, + kLegacyButtonAlign_BottomLeft = 6, + kLegacyButtonAlign_BottomCenter = 7, + kLegacyButtonAlign_BottomRight = 8, }; -class GUIButton : public GUIObject -{ +class GUIButton : public GUIObject { public: - GUIButton(); - - const String &GetText() const; - bool IsClippingImage() const; - - // Operations - void Draw(Bitmap *ds) override; - void SetClipImage(bool on); - void SetText(const String &text); - - // Events - bool OnMouseDown() override; - void OnMouseEnter() override; - void OnMouseLeave() override; - void OnMouseUp() override; - - // Serialization - void ReadFromFile(Stream *in, GuiVersion gui_version) override; - void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + GUIButton(); + + const String &GetText() const; + bool IsClippingImage() const; + + // Operations + void Draw(Bitmap *ds) override; + void SetClipImage(bool on); + void SetText(const String &text); + + // Events + bool OnMouseDown() override; + void OnMouseEnter() override; + void OnMouseLeave() override; + void OnMouseUp() override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; // TODO: these members are currently public; hide them later public: - int32_t Image; - int32_t MouseOverImage; - int32_t PushedImage; - int32_t CurrentImage; - int32_t Font; - color_t TextColor; - FrameAlignment TextAlignment; - // Click actions for left and right mouse buttons - // NOTE: only left click is currently in use - static const int ClickCount = kMouseRight + 1; - GUIClickAction ClickAction[ClickCount]; - int32_t ClickData[ClickCount]; - - bool IsPushed; - bool IsMouseOver; + int32_t Image; + int32_t MouseOverImage; + int32_t PushedImage; + int32_t CurrentImage; + int32_t Font; + color_t TextColor; + FrameAlignment TextAlignment; + // Click actions for left and right mouse buttons + // NOTE: only left click is currently in use + static const int ClickCount = kMouseRight + 1; + GUIClickAction ClickAction[ClickCount]; + int32_t ClickData[ClickCount]; + + bool IsPushed; + bool IsMouseOver; private: - void DrawImageButton(Bitmap *ds, bool draw_disabled); - void DrawText(Bitmap *ds, bool draw_disabled); - void DrawTextButton(Bitmap *ds, bool draw_disabled); - void PrepareTextToDraw(); - - // Defines button placeholder mode; the mode is set - // depending on special tags found in button text - enum GUIButtonPlaceholder - { - kButtonPlace_None, - kButtonPlace_InvItemStretch, - kButtonPlace_InvItemCenter, - kButtonPlace_InvItemAuto - }; - - // Text property set by user - String _text; - // type of content placeholder, if any - GUIButtonPlaceholder _placeholder; - // A flag indicating unnamed button; this is a convenience trick: - // buttons are created named "New Button" in the editor, and users - // often do not clear text when they want a graphic button. - bool _unnamed; - // Prepared text buffer/cache - String _textToDraw; + void DrawImageButton(Bitmap *ds, bool draw_disabled); + void DrawText(Bitmap *ds, bool draw_disabled); + void DrawTextButton(Bitmap *ds, bool draw_disabled); + void PrepareTextToDraw(); + + // Defines button placeholder mode; the mode is set + // depending on special tags found in button text + enum GUIButtonPlaceholder { + kButtonPlace_None, + kButtonPlace_InvItemStretch, + kButtonPlace_InvItemCenter, + kButtonPlace_InvItemAuto + }; + + // Text property set by user + String _text; + // type of content placeholder, if any + GUIButtonPlaceholder _placeholder; + // A flag indicating unnamed button; this is a convenience trick: + // buttons are created named "New Button" in the editor, and users + // often do not clear text when they want a graphic button. + bool _unnamed; + // Prepared text buffer/cache + String _textToDraw; }; } // namespace Common diff --git a/engines/ags/shared/gui/guidefines.h b/engines/ags/shared/gui/guidefines.h index d9c27e42bb79..b2aef37410c1 100644 --- a/engines/ags/shared/gui/guidefines.h +++ b/engines/ags/shared/gui/guidefines.h @@ -55,134 +55,123 @@ // //============================================================================= -enum GuiVersion -{ - // TODO: find out all corresponding engine version numbers - kGuiVersion_Initial = 0, - kGuiVersion_214 = 100, - kGuiVersion_222 = 101, - kGuiVersion_230 = 102, - kGuiVersion_unkn_103 = 103, - kGuiVersion_unkn_104 = 104, - kGuiVersion_260 = 105, - kGuiVersion_unkn_106 = 106, - kGuiVersion_unkn_107 = 107, - kGuiVersion_unkn_108 = 108, - kGuiVersion_unkn_109 = 109, - kGuiVersion_270 = 110, - kGuiVersion_272a = 111, - kGuiVersion_272b = 112, - kGuiVersion_272c = 113, - kGuiVersion_272d = 114, - kGuiVersion_272e = 115, - - kGuiVersion_330 = 116, - kGuiVersion_331 = 117, - kGuiVersion_340 = 118, - kGuiVersion_350 = 119, - kGuiVersion_Current = kGuiVersion_350, +enum GuiVersion { + // TODO: find out all corresponding engine version numbers + kGuiVersion_Initial = 0, + kGuiVersion_214 = 100, + kGuiVersion_222 = 101, + kGuiVersion_230 = 102, + kGuiVersion_unkn_103 = 103, + kGuiVersion_unkn_104 = 104, + kGuiVersion_260 = 105, + kGuiVersion_unkn_106 = 106, + kGuiVersion_unkn_107 = 107, + kGuiVersion_unkn_108 = 108, + kGuiVersion_unkn_109 = 109, + kGuiVersion_270 = 110, + kGuiVersion_272a = 111, + kGuiVersion_272b = 112, + kGuiVersion_272c = 113, + kGuiVersion_272d = 114, + kGuiVersion_272e = 115, + + kGuiVersion_330 = 116, + kGuiVersion_331 = 117, + kGuiVersion_340 = 118, + kGuiVersion_350 = 119, + kGuiVersion_Current = kGuiVersion_350, }; -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // GUIMain's style and behavior flags -enum GUIMainFlags -{ - kGUIMain_Clickable = 0x0001, - kGUIMain_TextWindow = 0x0002, - kGUIMain_Visible = 0x0004, - kGUIMain_Concealed = 0x0008, - - // NOTE: currently default state is Visible to keep this backwards compatible; - // check later if this is still a wanted behavior - kGUIMain_DefFlags = kGUIMain_Clickable | kGUIMain_Visible, - // flags that had inverse meaning in old formats - kGUIMain_OldFmtXorMask = kGUIMain_Clickable +enum GUIMainFlags { + kGUIMain_Clickable = 0x0001, + kGUIMain_TextWindow = 0x0002, + kGUIMain_Visible = 0x0004, + kGUIMain_Concealed = 0x0008, + + // NOTE: currently default state is Visible to keep this backwards compatible; + // check later if this is still a wanted behavior + kGUIMain_DefFlags = kGUIMain_Clickable | kGUIMain_Visible, + // flags that had inverse meaning in old formats + kGUIMain_OldFmtXorMask = kGUIMain_Clickable }; // GUIMain's legacy flags, now converted to GUIMainFlags on load -enum GUIMainLegacyFlags -{ - kGUIMain_LegacyTextWindow = 5 +enum GUIMainLegacyFlags { + kGUIMain_LegacyTextWindow = 5 }; // GUIMain's style of getting displayed on screen -enum GUIPopupStyle -{ - // Normal GUI - kGUIPopupNormal = 0, - // Shown when the mouse cursor moves to the top of the screen - kGUIPopupMouseY = 1, - // Same as Normal, but pauses the game when shown - kGUIPopupModal = 2, - // Same as Normal, but is not removed when interface is off - kGUIPopupNoAutoRemove = 3, - // (legacy option) Normal GUI, initially off - // converts to kGUIPopupNormal with Visible = false - kGUIPopupLegacyNormalOff = 4 +enum GUIPopupStyle { + // Normal GUI + kGUIPopupNormal = 0, + // Shown when the mouse cursor moves to the top of the screen + kGUIPopupMouseY = 1, + // Same as Normal, but pauses the game when shown + kGUIPopupModal = 2, + // Same as Normal, but is not removed when interface is off + kGUIPopupNoAutoRemove = 3, + // (legacy option) Normal GUI, initially off + // converts to kGUIPopupNormal with Visible = false + kGUIPopupLegacyNormalOff = 4 }; // The type of GUIControl -enum GUIControlType -{ - kGUIControlUndefined = -1, - kGUIButton = 1, - kGUILabel = 2, - kGUIInvWindow = 3, - kGUISlider = 4, - kGUITextBox = 5, - kGUIListBox = 6 +enum GUIControlType { + kGUIControlUndefined = -1, + kGUIButton = 1, + kGUILabel = 2, + kGUIInvWindow = 3, + kGUISlider = 4, + kGUITextBox = 5, + kGUIListBox = 6 }; // GUIControl general style and behavior flags -enum GUIControlFlags -{ - kGUICtrl_Default = 0x0001, // only button - kGUICtrl_Cancel = 0x0002, // unused - kGUICtrl_Enabled = 0x0004, - kGUICtrl_TabStop = 0x0008, // unused - kGUICtrl_Visible = 0x0010, - kGUICtrl_Clip = 0x0020, // only button - kGUICtrl_Clickable = 0x0040, - kGUICtrl_Translated = 0x0080, // 3.3.0.1132 - kGUICtrl_Deleted = 0x8000, // unused (probably remains from the old editor?) - - kGUICtrl_DefFlags = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable, - // flags that had inverse meaning in old formats - kGUICtrl_OldFmtXorMask = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable +enum GUIControlFlags { + kGUICtrl_Default = 0x0001, // only button + kGUICtrl_Cancel = 0x0002, // unused + kGUICtrl_Enabled = 0x0004, + kGUICtrl_TabStop = 0x0008, // unused + kGUICtrl_Visible = 0x0010, + kGUICtrl_Clip = 0x0020, // only button + kGUICtrl_Clickable = 0x0040, + kGUICtrl_Translated = 0x0080, // 3.3.0.1132 + kGUICtrl_Deleted = 0x8000, // unused (probably remains from the old editor?) + + kGUICtrl_DefFlags = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable, + // flags that had inverse meaning in old formats + kGUICtrl_OldFmtXorMask = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable }; // GUIListBox style and behavior flags -enum GUIListBoxFlags -{ - kListBox_ShowBorder = 0x01, - kListBox_ShowArrows = 0x02, - kListBox_SvgIndex = 0x04, - - kListBox_DefFlags = kListBox_ShowBorder | kListBox_ShowArrows, - // flags that had inverse meaning in old formats - kListBox_OldFmtXorMask = kListBox_ShowBorder | kListBox_ShowArrows +enum GUIListBoxFlags { + kListBox_ShowBorder = 0x01, + kListBox_ShowArrows = 0x02, + kListBox_SvgIndex = 0x04, + + kListBox_DefFlags = kListBox_ShowBorder | kListBox_ShowArrows, + // flags that had inverse meaning in old formats + kListBox_OldFmtXorMask = kListBox_ShowBorder | kListBox_ShowArrows }; // GUITextBox style and behavior flags -enum GUITextBoxFlags -{ - kTextBox_ShowBorder = 0x0001, +enum GUITextBoxFlags { + kTextBox_ShowBorder = 0x0001, - kTextBox_DefFlags = kTextBox_ShowBorder, - // flags that had inverse meaning in old formats - kTextBox_OldFmtXorMask = kTextBox_ShowBorder + kTextBox_DefFlags = kTextBox_ShowBorder, + // flags that had inverse meaning in old formats + kTextBox_OldFmtXorMask = kTextBox_ShowBorder }; // Savegame data format // TODO: move to the engine code -enum GuiSvgVersion -{ - kGuiSvgVersion_Initial = 0, - kGuiSvgVersion_350 = 1 +enum GuiSvgVersion { + kGuiSvgVersion_Initial = 0, + kGuiSvgVersion_350 = 1 }; } // namespace Common diff --git a/engines/ags/shared/gui/guiinv.cpp b/engines/ags/shared/gui/guiinv.cpp index cd354b780546..368d0beca390 100644 --- a/engines/ags/shared/gui/guiinv.cpp +++ b/engines/ags/shared/gui/guiinv.cpp @@ -29,123 +29,102 @@ std::vector guiinv; int numguiinv = 0; -namespace AGS -{ -namespace Common -{ - -GUIInvWindow::GUIInvWindow() -{ - IsMouseOver = false; - CharId = -1; - ItemWidth = 40; - ItemHeight = 22; - ColCount = 0; - RowCount = 0; - TopItem = 0; - CalculateNumCells(); - - _scEventCount = 0; +namespace AGS { +namespace Common { + +GUIInvWindow::GUIInvWindow() { + IsMouseOver = false; + CharId = -1; + ItemWidth = 40; + ItemHeight = 22; + ColCount = 0; + RowCount = 0; + TopItem = 0; + CalculateNumCells(); + + _scEventCount = 0; } -void GUIInvWindow::OnMouseEnter() -{ - IsMouseOver = true; +void GUIInvWindow::OnMouseEnter() { + IsMouseOver = true; } -void GUIInvWindow::OnMouseLeave() -{ - IsMouseOver = false; +void GUIInvWindow::OnMouseLeave() { + IsMouseOver = false; } -void GUIInvWindow::OnMouseUp() -{ - if (IsMouseOver) - IsActivated = true; +void GUIInvWindow::OnMouseUp() { + if (IsMouseOver) + IsActivated = true; } -void GUIInvWindow::OnResized() -{ - CalculateNumCells(); +void GUIInvWindow::OnResized() { + CalculateNumCells(); } -void GUIInvWindow::WriteToFile(Stream *out) const -{ - GUIObject::WriteToFile(out); - out->WriteInt32(CharId); - out->WriteInt32(ItemWidth); - out->WriteInt32(ItemHeight); +void GUIInvWindow::WriteToFile(Stream *out) const { + GUIObject::WriteToFile(out); + out->WriteInt32(CharId); + out->WriteInt32(ItemWidth); + out->WriteInt32(ItemHeight); } -void GUIInvWindow::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - GUIObject::ReadFromFile(in, gui_version); - if (gui_version >= kGuiVersion_unkn_109) - { - CharId = in->ReadInt32(); - ItemWidth = in->ReadInt32(); - ItemHeight = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - { // NOTE: reading into actual variables only for old savegame support - TopItem = in->ReadInt32(); - } - } - else - { - CharId = -1; - ItemWidth = 40; - ItemHeight = 22; - TopItem = 0; - } - - if (loaded_game_file_version >= kGameVersion_270) - { - // ensure that some items are visible - if (ItemWidth > Width) - ItemWidth = Width; - if (ItemHeight > Height) - ItemHeight = Height; - } - - CalculateNumCells(); +void GUIInvWindow::ReadFromFile(Stream *in, GuiVersion gui_version) { + GUIObject::ReadFromFile(in, gui_version); + if (gui_version >= kGuiVersion_unkn_109) { + CharId = in->ReadInt32(); + ItemWidth = in->ReadInt32(); + ItemHeight = in->ReadInt32(); + if (gui_version < kGuiVersion_350) { + // NOTE: reading into actual variables only for old savegame support + TopItem = in->ReadInt32(); + } + } else { + CharId = -1; + ItemWidth = 40; + ItemHeight = 22; + TopItem = 0; + } + + if (loaded_game_file_version >= kGameVersion_270) { + // ensure that some items are visible + if (ItemWidth > Width) + ItemWidth = Width; + if (ItemHeight > Height) + ItemHeight = Height; + } + + CalculateNumCells(); } -void GUIInvWindow::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) -{ - GUIObject::ReadFromSavegame(in, svg_ver); - ItemWidth = in->ReadInt32(); - ItemHeight = in->ReadInt32(); - CharId = in->ReadInt32(); - TopItem = in->ReadInt32(); - CalculateNumCells(); +void GUIInvWindow::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { + GUIObject::ReadFromSavegame(in, svg_ver); + ItemWidth = in->ReadInt32(); + ItemHeight = in->ReadInt32(); + CharId = in->ReadInt32(); + TopItem = in->ReadInt32(); + CalculateNumCells(); } -void GUIInvWindow::WriteToSavegame(Stream *out) const -{ - GUIObject::WriteToSavegame(out); - out->WriteInt32(ItemWidth); - out->WriteInt32(ItemHeight); - out->WriteInt32(CharId); - out->WriteInt32(TopItem); +void GUIInvWindow::WriteToSavegame(Stream *out) const { + GUIObject::WriteToSavegame(out); + out->WriteInt32(ItemWidth); + out->WriteInt32(ItemHeight); + out->WriteInt32(CharId); + out->WriteInt32(TopItem); } -void GUIInvWindow::CalculateNumCells() -{ - if (ItemWidth <= 0 || ItemHeight <= 0) - { - ColCount = 0; - RowCount = 0; - } - else if (loaded_game_file_version >= kGameVersion_270) - { - ColCount = Width / data_to_game_coord(ItemWidth); - RowCount = Height / data_to_game_coord(ItemHeight); - } - else - { - ColCount = floor((float)Width / (float)data_to_game_coord(ItemWidth) + 0.5f); - RowCount = floor((float)Height / (float)data_to_game_coord(ItemHeight) + 0.5f); - } +void GUIInvWindow::CalculateNumCells() { + if (ItemWidth <= 0 || ItemHeight <= 0) { + ColCount = 0; + RowCount = 0; + } else if (loaded_game_file_version >= kGameVersion_270) { + ColCount = Width / data_to_game_coord(ItemWidth); + RowCount = Height / data_to_game_coord(ItemHeight); + } else { + ColCount = floor((float)Width / (float)data_to_game_coord(ItemWidth) + 0.5f); + RowCount = floor((float)Height / (float)data_to_game_coord(ItemHeight) + 0.5f); + } } } // namespace Common diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index 0acab662d132..caf85c703d27 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -26,47 +26,44 @@ #include #include "gui/guiobject.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class GUIInvWindow : public GUIObject -{ +class GUIInvWindow : public GUIObject { public: - GUIInvWindow(); + GUIInvWindow(); - // This function has distinct implementations in Engine and Editor - int GetCharacterId() const; + // This function has distinct implementations in Engine and Editor + int GetCharacterId() const; - // Operations - // This function has distinct implementations in Engine and Editor - void Draw(Bitmap *ds) override; + // Operations + // This function has distinct implementations in Engine and Editor + void Draw(Bitmap *ds) override; - // Events - void OnMouseEnter() override; - void OnMouseLeave() override; - void OnMouseUp() override; - void OnResized() override; + // Events + void OnMouseEnter() override; + void OnMouseLeave() override; + void OnMouseUp() override; + void OnResized() override; - // Serialization - void ReadFromFile(Stream *in, GuiVersion gui_version) override; - void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; // TODO: these members are currently public; hide them later public: - bool IsMouseOver; - int32_t CharId; // whose inventory (-1 = current player) - int32_t ItemWidth; - int32_t ItemHeight; - int32_t ColCount; - int32_t RowCount; - int32_t TopItem; + bool IsMouseOver; + int32_t CharId; // whose inventory (-1 = current player) + int32_t ItemWidth; + int32_t ItemHeight; + int32_t ColCount; + int32_t RowCount; + int32_t TopItem; private: - void CalculateNumCells(); + void CalculateNumCells(); }; } // namespace Common diff --git a/engines/ags/shared/gui/guilabel.cpp b/engines/ags/shared/gui/guilabel.cpp index d814e04691bd..480c6acb0859 100644 --- a/engines/ags/shared/gui/guilabel.cpp +++ b/engines/ags/shared/gui/guilabel.cpp @@ -32,104 +32,93 @@ int numguilabels = 0; #define GUILABEL_TEXTLENGTH_PRE272 200 -namespace AGS -{ -namespace Common -{ - -GUILabel::GUILabel() -{ - Font = 0; - TextColor = 0; - TextAlignment = kHAlignLeft; - - _scEventCount = 0; +namespace AGS { +namespace Common { + +GUILabel::GUILabel() { + Font = 0; + TextColor = 0; + TextAlignment = kHAlignLeft; + + _scEventCount = 0; } -String GUILabel::GetText() const -{ - return Text; +String GUILabel::GetText() const { + return Text; } -void GUILabel::Draw(Common::Bitmap *ds) -{ - check_font(&Font); - - // TODO: need to find a way to cache text prior to drawing; - // but that will require to update all gui controls when translation is changed in game - PrepareTextToDraw(); - if (SplitLinesForDrawing(Lines) == 0) - return; - - color_t text_color = ds->GetCompatibleColor(TextColor); - const int linespacing = getfontlinespacing(Font) + 1; - // < 2.72 labels did not limit vertical size of text - const bool limit_by_label_frame = loaded_game_file_version >= kGameVersion_272; - int at_y = Y; - for (size_t i = 0; - i < Lines.Count() && (!limit_by_label_frame || at_y <= Y + Height); - ++i, at_y += linespacing) - { - GUI::DrawTextAlignedHor(ds, Lines[i], Font, text_color, X, X + Width - 1, at_y, - (FrameAlignment)TextAlignment); - } +void GUILabel::Draw(Common::Bitmap *ds) { + check_font(&Font); + + // TODO: need to find a way to cache text prior to drawing; + // but that will require to update all gui controls when translation is changed in game + PrepareTextToDraw(); + if (SplitLinesForDrawing(Lines) == 0) + return; + + color_t text_color = ds->GetCompatibleColor(TextColor); + const int linespacing = getfontlinespacing(Font) + 1; + // < 2.72 labels did not limit vertical size of text + const bool limit_by_label_frame = loaded_game_file_version >= kGameVersion_272; + int at_y = Y; + for (size_t i = 0; + i < Lines.Count() && (!limit_by_label_frame || at_y <= Y + Height); + ++i, at_y += linespacing) { + GUI::DrawTextAlignedHor(ds, Lines[i], Font, text_color, X, X + Width - 1, at_y, + (FrameAlignment)TextAlignment); + } } -void GUILabel::SetText(const String &text) -{ - Text = text; +void GUILabel::SetText(const String &text) { + Text = text; } // TODO: replace string serialization with StrUtil::ReadString and WriteString // methods in the future, to keep this organized. -void GUILabel::WriteToFile(Stream *out) const -{ - GUIObject::WriteToFile(out); - StrUtil::WriteString(Text, out); - out->WriteInt32(Font); - out->WriteInt32(TextColor); - out->WriteInt32(TextAlignment); +void GUILabel::WriteToFile(Stream *out) const { + GUIObject::WriteToFile(out); + StrUtil::WriteString(Text, out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(TextAlignment); } -void GUILabel::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - GUIObject::ReadFromFile(in, gui_version); - - if (gui_version < kGuiVersion_272c) - Text.ReadCount(in, GUILABEL_TEXTLENGTH_PRE272); - else - Text = StrUtil::ReadString(in); - - Font = in->ReadInt32(); - TextColor = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - TextAlignment = ConvertLegacyGUIAlignment((LegacyGUIAlignment)in->ReadInt32()); - else - TextAlignment = (HorAlignment)in->ReadInt32(); - - if (TextColor == 0) - TextColor = 16; - // All labels are translated at the moment - Flags |= kGUICtrl_Translated; +void GUILabel::ReadFromFile(Stream *in, GuiVersion gui_version) { + GUIObject::ReadFromFile(in, gui_version); + + if (gui_version < kGuiVersion_272c) + Text.ReadCount(in, GUILABEL_TEXTLENGTH_PRE272); + else + Text = StrUtil::ReadString(in); + + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + TextAlignment = ConvertLegacyGUIAlignment((LegacyGUIAlignment)in->ReadInt32()); + else + TextAlignment = (HorAlignment)in->ReadInt32(); + + if (TextColor == 0) + TextColor = 16; + // All labels are translated at the moment + Flags |= kGUICtrl_Translated; } -void GUILabel::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) -{ - GUIObject::ReadFromSavegame(in, svg_ver); - Font = in->ReadInt32(); - TextColor = in->ReadInt32(); - Text = StrUtil::ReadString(in); - if (svg_ver >= kGuiSvgVersion_350) - TextAlignment = (HorAlignment)in->ReadInt32(); +void GUILabel::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { + GUIObject::ReadFromSavegame(in, svg_ver); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + Text = StrUtil::ReadString(in); + if (svg_ver >= kGuiSvgVersion_350) + TextAlignment = (HorAlignment)in->ReadInt32(); } -void GUILabel::WriteToSavegame(Stream *out) const -{ - GUIObject::WriteToSavegame(out); - out->WriteInt32(Font); - out->WriteInt32(TextColor); - StrUtil::WriteString(Text, out); - out->WriteInt32(TextAlignment); +void GUILabel::WriteToSavegame(Stream *out) const { + GUIObject::WriteToSavegame(out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + StrUtil::WriteString(Text, out); + out->WriteInt32(TextAlignment); } } // namespace Common diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index 86ea4b9e3791..745e6bf019c9 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -29,41 +29,38 @@ class SplitLines; -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class GUILabel:public GUIObject -{ +class GUILabel: public GUIObject { public: - GUILabel(); - - String GetText() const; + GUILabel(); - // Operations - void Draw(Bitmap *ds) override; - void SetText(const String &text); + String GetText() const; - // Serialization - void ReadFromFile(Stream *in, GuiVersion gui_version) override; - void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + // Operations + void Draw(Bitmap *ds) override; + void SetText(const String &text); + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; // TODO: these members are currently public; hide them later public: - String Text; - int32_t Font; - color_t TextColor; - HorAlignment TextAlignment; + String Text; + int32_t Font; + color_t TextColor; + HorAlignment TextAlignment; private: - void PrepareTextToDraw(); - size_t SplitLinesForDrawing(SplitLines &lines); + void PrepareTextToDraw(); + size_t SplitLinesForDrawing(SplitLines &lines); - // prepared text buffer/cache - String _textToDraw; + // prepared text buffer/cache + String _textToDraw; }; } // namespace Common diff --git a/engines/ags/shared/gui/guilistbox.cpp b/engines/ags/shared/gui/guilistbox.cpp index 831177466397..5cb14fe264d7 100644 --- a/engines/ags/shared/gui/guilistbox.cpp +++ b/engines/ags/shared/gui/guilistbox.cpp @@ -29,412 +29,365 @@ std::vector guilist; int numguilist = 0; -namespace AGS -{ -namespace Common -{ - -GUIListBox::GUIListBox() -{ - ItemCount = 0; - SelectedItem = 0; - TopItem = 0; - RowHeight = 0; - VisibleItemCount = 0; - Font = 0; - TextColor = 0; - SelectedTextColor = 7; - ListBoxFlags = kListBox_DefFlags; - SelectedBgColor = 16; - TextAlignment = kHAlignLeft; - - _scEventCount = 1; - _scEventNames[0] = "SelectionChanged"; - _scEventArgs[0] = "GUIControl *control"; +namespace AGS { +namespace Common { + +GUIListBox::GUIListBox() { + ItemCount = 0; + SelectedItem = 0; + TopItem = 0; + RowHeight = 0; + VisibleItemCount = 0; + Font = 0; + TextColor = 0; + SelectedTextColor = 7; + ListBoxFlags = kListBox_DefFlags; + SelectedBgColor = 16; + TextAlignment = kHAlignLeft; + + _scEventCount = 1; + _scEventNames[0] = "SelectionChanged"; + _scEventArgs[0] = "GUIControl *control"; } -int GUIListBox::GetItemAt(int x, int y) const -{ - if (RowHeight <= 0 || IsInRightMargin(x)) - return -1; +int GUIListBox::GetItemAt(int x, int y) const { + if (RowHeight <= 0 || IsInRightMargin(x)) + return -1; - int index = y / RowHeight + TopItem; - if (index < 0 || index >= ItemCount) - return -1; - return index; + int index = y / RowHeight + TopItem; + if (index < 0 || index >= ItemCount) + return -1; + return index; } -bool GUIListBox::AreArrowsShown() const -{ - return (ListBoxFlags & kListBox_ShowArrows) != 0; +bool GUIListBox::AreArrowsShown() const { + return (ListBoxFlags & kListBox_ShowArrows) != 0; } -bool GUIListBox::IsBorderShown() const -{ - return (ListBoxFlags & kListBox_ShowBorder) != 0; +bool GUIListBox::IsBorderShown() const { + return (ListBoxFlags & kListBox_ShowBorder) != 0; } -bool GUIListBox::IsSvgIndex() const -{ - return (ListBoxFlags & kListBox_SvgIndex) != 0; +bool GUIListBox::IsSvgIndex() const { + return (ListBoxFlags & kListBox_SvgIndex) != 0; } -bool GUIListBox::IsInRightMargin(int x) const -{ - if (x >= (Width - get_fixed_pixel_size(6)) && IsBorderShown() && AreArrowsShown()) - return 1; - return 0; +bool GUIListBox::IsInRightMargin(int x) const { + if (x >= (Width - get_fixed_pixel_size(6)) && IsBorderShown() && AreArrowsShown()) + return 1; + return 0; } -int GUIListBox::AddItem(const String &text) -{ - guis_need_update = 1; - Items.push_back(text); - SavedGameIndex.push_back(-1); - ItemCount++; - return ItemCount - 1; +int GUIListBox::AddItem(const String &text) { + guis_need_update = 1; + Items.push_back(text); + SavedGameIndex.push_back(-1); + ItemCount++; + return ItemCount - 1; } -void GUIListBox::Clear() -{ - Items.clear(); - SavedGameIndex.clear(); - ItemCount = 0; - SelectedItem = 0; - TopItem = 0; - guis_need_update = 1; +void GUIListBox::Clear() { + Items.clear(); + SavedGameIndex.clear(); + ItemCount = 0; + SelectedItem = 0; + TopItem = 0; + guis_need_update = 1; } -void GUIListBox::Draw(Common::Bitmap *ds) -{ - const int width = Width - 1; - const int height = Height - 1; - const int pixel_size = get_fixed_pixel_size(1); - - check_font(&Font); - color_t text_color = ds->GetCompatibleColor(TextColor); - color_t draw_color = ds->GetCompatibleColor(TextColor); - if (IsBorderShown()) - { - ds->DrawRect(Rect(X, Y, X + width + (pixel_size - 1), Y + height + (pixel_size - 1)), draw_color); - if (pixel_size > 1) - ds->DrawRect(Rect(X + 1, Y + 1, X + width, Y + height), draw_color); - } - - int right_hand_edge = (X + width) - pixel_size - 1; - - // use SetFont to update the RowHeight and VisibleItemCount - SetFont(Font); - - // draw the scroll bar in if necessary - if (ItemCount > VisibleItemCount && IsBorderShown() && AreArrowsShown()) - { - int xstrt, ystrt; - ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y, (X + (pixel_size - 1) + width) - get_fixed_pixel_size(7), Y + height), draw_color); - ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y + height / 2, X + width, Y + height / 2 + (pixel_size - 1)), draw_color); - - xstrt = (X + width - get_fixed_pixel_size(6)) + (pixel_size - 1); - ystrt = (Y + height - 3) - get_fixed_pixel_size(5); - - draw_color = ds->GetCompatibleColor(TextColor); - ds->DrawTriangle(Triangle(xstrt, ystrt, xstrt + get_fixed_pixel_size(4), ystrt, - xstrt + get_fixed_pixel_size(2), - ystrt + get_fixed_pixel_size(5)), draw_color); - - ystrt = Y + 3; - ds->DrawTriangle(Triangle(xstrt, ystrt + get_fixed_pixel_size(5), - xstrt + get_fixed_pixel_size(4), - ystrt + get_fixed_pixel_size(5), - xstrt + get_fixed_pixel_size(2), ystrt), draw_color); - - right_hand_edge -= get_fixed_pixel_size(7); - } - - DrawItemsFix(); - - for (int item = 0; item < VisibleItemCount; ++item) - { - if (item + TopItem >= ItemCount) - break; - - int at_y = Y + pixel_size + item * RowHeight; - if (item + TopItem == SelectedItem) - { - text_color = ds->GetCompatibleColor(SelectedTextColor); - if (SelectedBgColor > 0) - { - int stretch_to = (X + width) - pixel_size; - // draw the SelectedItem item bar (if colour not transparent) - draw_color = ds->GetCompatibleColor(SelectedBgColor); - if ((VisibleItemCount < ItemCount) && IsBorderShown() && AreArrowsShown()) - stretch_to -= get_fixed_pixel_size(7); - - ds->FillRect(Rect(X + pixel_size, at_y, stretch_to, at_y + RowHeight - pixel_size), draw_color); - } - } - else - text_color = ds->GetCompatibleColor(TextColor); - - int item_index = item + TopItem; - PrepareTextToDraw(Items[item_index]); - - GUI::DrawTextAlignedHor(ds, _textToDraw, Font, text_color, X + 1 + pixel_size, right_hand_edge, at_y + 1, - (FrameAlignment)TextAlignment); - } - - DrawItemsUnfix(); +void GUIListBox::Draw(Common::Bitmap *ds) { + const int width = Width - 1; + const int height = Height - 1; + const int pixel_size = get_fixed_pixel_size(1); + + check_font(&Font); + color_t text_color = ds->GetCompatibleColor(TextColor); + color_t draw_color = ds->GetCompatibleColor(TextColor); + if (IsBorderShown()) { + ds->DrawRect(Rect(X, Y, X + width + (pixel_size - 1), Y + height + (pixel_size - 1)), draw_color); + if (pixel_size > 1) + ds->DrawRect(Rect(X + 1, Y + 1, X + width, Y + height), draw_color); + } + + int right_hand_edge = (X + width) - pixel_size - 1; + + // use SetFont to update the RowHeight and VisibleItemCount + SetFont(Font); + + // draw the scroll bar in if necessary + if (ItemCount > VisibleItemCount && IsBorderShown() && AreArrowsShown()) { + int xstrt, ystrt; + ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y, (X + (pixel_size - 1) + width) - get_fixed_pixel_size(7), Y + height), draw_color); + ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y + height / 2, X + width, Y + height / 2 + (pixel_size - 1)), draw_color); + + xstrt = (X + width - get_fixed_pixel_size(6)) + (pixel_size - 1); + ystrt = (Y + height - 3) - get_fixed_pixel_size(5); + + draw_color = ds->GetCompatibleColor(TextColor); + ds->DrawTriangle(Triangle(xstrt, ystrt, xstrt + get_fixed_pixel_size(4), ystrt, + xstrt + get_fixed_pixel_size(2), + ystrt + get_fixed_pixel_size(5)), draw_color); + + ystrt = Y + 3; + ds->DrawTriangle(Triangle(xstrt, ystrt + get_fixed_pixel_size(5), + xstrt + get_fixed_pixel_size(4), + ystrt + get_fixed_pixel_size(5), + xstrt + get_fixed_pixel_size(2), ystrt), draw_color); + + right_hand_edge -= get_fixed_pixel_size(7); + } + + DrawItemsFix(); + + for (int item = 0; item < VisibleItemCount; ++item) { + if (item + TopItem >= ItemCount) + break; + + int at_y = Y + pixel_size + item * RowHeight; + if (item + TopItem == SelectedItem) { + text_color = ds->GetCompatibleColor(SelectedTextColor); + if (SelectedBgColor > 0) { + int stretch_to = (X + width) - pixel_size; + // draw the SelectedItem item bar (if colour not transparent) + draw_color = ds->GetCompatibleColor(SelectedBgColor); + if ((VisibleItemCount < ItemCount) && IsBorderShown() && AreArrowsShown()) + stretch_to -= get_fixed_pixel_size(7); + + ds->FillRect(Rect(X + pixel_size, at_y, stretch_to, at_y + RowHeight - pixel_size), draw_color); + } + } else + text_color = ds->GetCompatibleColor(TextColor); + + int item_index = item + TopItem; + PrepareTextToDraw(Items[item_index]); + + GUI::DrawTextAlignedHor(ds, _textToDraw, Font, text_color, X + 1 + pixel_size, right_hand_edge, at_y + 1, + (FrameAlignment)TextAlignment); + } + + DrawItemsUnfix(); } -int GUIListBox::InsertItem(int index, const String &text) -{ - if (index < 0 || index > ItemCount) - return -1; +int GUIListBox::InsertItem(int index, const String &text) { + if (index < 0 || index > ItemCount) + return -1; - Items.insert(Items.begin() + index, text); - SavedGameIndex.insert(SavedGameIndex.begin() + index, -1); - if (SelectedItem >= index) - SelectedItem++; + Items.insert(Items.begin() + index, text); + SavedGameIndex.insert(SavedGameIndex.begin() + index, -1); + if (SelectedItem >= index) + SelectedItem++; - ItemCount++; - guis_need_update = 1; - return ItemCount - 1; + ItemCount++; + guis_need_update = 1; + return ItemCount - 1; } -void GUIListBox::RemoveItem(int index) -{ - if (index < 0 || index >= ItemCount) - return; +void GUIListBox::RemoveItem(int index) { + if (index < 0 || index >= ItemCount) + return; - Items.erase(Items.begin() + index); - SavedGameIndex.erase(SavedGameIndex.begin() + index); - ItemCount--; + Items.erase(Items.begin() + index); + SavedGameIndex.erase(SavedGameIndex.begin() + index); + ItemCount--; - if (SelectedItem > index) - SelectedItem--; - if (SelectedItem >= ItemCount) - SelectedItem = -1; - guis_need_update = 1; + if (SelectedItem > index) + SelectedItem--; + if (SelectedItem >= ItemCount) + SelectedItem = -1; + guis_need_update = 1; } -void GUIListBox::SetShowArrows(bool on) -{ - if (on) - ListBoxFlags |= kListBox_ShowArrows; - else - ListBoxFlags &= ~kListBox_ShowArrows; +void GUIListBox::SetShowArrows(bool on) { + if (on) + ListBoxFlags |= kListBox_ShowArrows; + else + ListBoxFlags &= ~kListBox_ShowArrows; } -void GUIListBox::SetShowBorder(bool on) -{ - if (on) - ListBoxFlags |= kListBox_ShowBorder; - else - ListBoxFlags &= ~kListBox_ShowBorder; +void GUIListBox::SetShowBorder(bool on) { + if (on) + ListBoxFlags |= kListBox_ShowBorder; + else + ListBoxFlags &= ~kListBox_ShowBorder; } -void GUIListBox::SetSvgIndex(bool on) -{ - if (on) - ListBoxFlags |= kListBox_SvgIndex; - else - ListBoxFlags &= ~kListBox_SvgIndex; +void GUIListBox::SetSvgIndex(bool on) { + if (on) + ListBoxFlags |= kListBox_SvgIndex; + else + ListBoxFlags &= ~kListBox_SvgIndex; } -void GUIListBox::SetFont(int font) -{ - Font = font; - RowHeight = getfontheight(Font) + get_fixed_pixel_size(2); - VisibleItemCount = Height / RowHeight; +void GUIListBox::SetFont(int font) { + Font = font; + RowHeight = getfontheight(Font) + get_fixed_pixel_size(2); + VisibleItemCount = Height / RowHeight; } -void GUIListBox::SetItemText(int index, const String &text) -{ - if (index >= 0 && index < ItemCount) - { - guis_need_update = 1; - Items[index] = text; - } +void GUIListBox::SetItemText(int index, const String &text) { + if (index >= 0 && index < ItemCount) { + guis_need_update = 1; + Items[index] = text; + } } -bool GUIListBox::OnMouseDown() -{ - if (IsInRightMargin(MousePos.X)) - { - if (MousePos.Y < Height / 2 && TopItem > 0) - TopItem--; - if (MousePos.Y >= Height / 2 && ItemCount > TopItem + VisibleItemCount) - TopItem++; - return false; - } - - int sel = GetItemAt(MousePos.X, MousePos.Y); - if (sel < 0) - return false; - SelectedItem = sel; - IsActivated = true; - return false; +bool GUIListBox::OnMouseDown() { + if (IsInRightMargin(MousePos.X)) { + if (MousePos.Y < Height / 2 && TopItem > 0) + TopItem--; + if (MousePos.Y >= Height / 2 && ItemCount > TopItem + VisibleItemCount) + TopItem++; + return false; + } + + int sel = GetItemAt(MousePos.X, MousePos.Y); + if (sel < 0) + return false; + SelectedItem = sel; + IsActivated = true; + return false; } -void GUIListBox::OnMouseMove(int x_, int y_) -{ - MousePos.X = x_ - X; - MousePos.Y = y_ - Y; +void GUIListBox::OnMouseMove(int x_, int y_) { + MousePos.X = x_ - X; + MousePos.Y = y_ - Y; } -void GUIListBox::OnResized() -{ - if (RowHeight == 0) - { - check_font(&Font); - SetFont(Font); - } - if (RowHeight > 0) - VisibleItemCount = Height / RowHeight; +void GUIListBox::OnResized() { + if (RowHeight == 0) { + check_font(&Font); + SetFont(Font); + } + if (RowHeight > 0) + VisibleItemCount = Height / RowHeight; } // TODO: replace string serialization with StrUtil::ReadString and WriteString // methods in the future, to keep this organized. -void GUIListBox::WriteToFile(Stream *out) const -{ - GUIObject::WriteToFile(out); - out->WriteInt32(ItemCount); - out->WriteInt32(Font); - out->WriteInt32(TextColor); - out->WriteInt32(SelectedTextColor); - out->WriteInt32(ListBoxFlags); - out->WriteInt32(TextAlignment); - out->WriteInt32(SelectedBgColor); - for (int i = 0; i < ItemCount; ++i) - Items[i].Write(out); +void GUIListBox::WriteToFile(Stream *out) const { + GUIObject::WriteToFile(out); + out->WriteInt32(ItemCount); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(SelectedTextColor); + out->WriteInt32(ListBoxFlags); + out->WriteInt32(TextAlignment); + out->WriteInt32(SelectedBgColor); + for (int i = 0; i < ItemCount; ++i) + Items[i].Write(out); } -void GUIListBox::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - Clear(); - - GUIObject::ReadFromFile(in, gui_version); - ItemCount = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - { // NOTE: reading into actual variables only for old savegame support - SelectedItem = in->ReadInt32(); - TopItem = in->ReadInt32(); - MousePos.X = in->ReadInt32(); - MousePos.Y = in->ReadInt32(); - RowHeight = in->ReadInt32(); - VisibleItemCount = in->ReadInt32(); - } - Font = in->ReadInt32(); - TextColor = in->ReadInt32(); - SelectedTextColor = in->ReadInt32(); - ListBoxFlags = in->ReadInt32(); - // reverse particular flags from older format - if (gui_version < kGuiVersion_350) - ListBoxFlags ^= kListBox_OldFmtXorMask; - - if (gui_version >= kGuiVersion_272b) - { - if (gui_version < kGuiVersion_350) - { - TextAlignment = ConvertLegacyGUIAlignment((LegacyGUIAlignment)in->ReadInt32()); - in->ReadInt32(); // reserved1 - } - else - { - TextAlignment = (HorAlignment)in->ReadInt32(); - } - } - else - { - TextAlignment = kHAlignLeft; - } - - if (gui_version >= kGuiVersion_unkn_107) - { - SelectedBgColor = in->ReadInt32(); - } - else - { - SelectedBgColor = TextColor; - if (SelectedBgColor == 0) - SelectedBgColor = 16; - } - - // NOTE: we leave items in game data format as a potential support for defining - // ListBox contents at design-time, although Editor does not support it as of 3.5.0. - Items.resize(ItemCount); - SavedGameIndex.resize(ItemCount, -1); - for (int i = 0; i < ItemCount; ++i) - { - Items[i].Read(in); - } - - if (gui_version >= kGuiVersion_272d && gui_version < kGuiVersion_350 && - (ListBoxFlags & kListBox_SvgIndex)) - { // NOTE: reading into actual variables only for old savegame support - for (int i = 0; i < ItemCount; ++i) - SavedGameIndex[i] = in->ReadInt16(); - } - - if (TextColor == 0) - TextColor = 16; +void GUIListBox::ReadFromFile(Stream *in, GuiVersion gui_version) { + Clear(); + + GUIObject::ReadFromFile(in, gui_version); + ItemCount = in->ReadInt32(); + if (gui_version < kGuiVersion_350) { + // NOTE: reading into actual variables only for old savegame support + SelectedItem = in->ReadInt32(); + TopItem = in->ReadInt32(); + MousePos.X = in->ReadInt32(); + MousePos.Y = in->ReadInt32(); + RowHeight = in->ReadInt32(); + VisibleItemCount = in->ReadInt32(); + } + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + SelectedTextColor = in->ReadInt32(); + ListBoxFlags = in->ReadInt32(); + // reverse particular flags from older format + if (gui_version < kGuiVersion_350) + ListBoxFlags ^= kListBox_OldFmtXorMask; + + if (gui_version >= kGuiVersion_272b) { + if (gui_version < kGuiVersion_350) { + TextAlignment = ConvertLegacyGUIAlignment((LegacyGUIAlignment)in->ReadInt32()); + in->ReadInt32(); // reserved1 + } else { + TextAlignment = (HorAlignment)in->ReadInt32(); + } + } else { + TextAlignment = kHAlignLeft; + } + + if (gui_version >= kGuiVersion_unkn_107) { + SelectedBgColor = in->ReadInt32(); + } else { + SelectedBgColor = TextColor; + if (SelectedBgColor == 0) + SelectedBgColor = 16; + } + + // NOTE: we leave items in game data format as a potential support for defining + // ListBox contents at design-time, although Editor does not support it as of 3.5.0. + Items.resize(ItemCount); + SavedGameIndex.resize(ItemCount, -1); + for (int i = 0; i < ItemCount; ++i) { + Items[i].Read(in); + } + + if (gui_version >= kGuiVersion_272d && gui_version < kGuiVersion_350 && + (ListBoxFlags & kListBox_SvgIndex)) { + // NOTE: reading into actual variables only for old savegame support + for (int i = 0; i < ItemCount; ++i) + SavedGameIndex[i] = in->ReadInt16(); + } + + if (TextColor == 0) + TextColor = 16; } -void GUIListBox::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) -{ - GUIObject::ReadFromSavegame(in, svg_ver); - // Properties - ListBoxFlags = in->ReadInt32(); - Font = in->ReadInt32(); - if (svg_ver < kGuiSvgVersion_350) - { - // reverse particular flags from older format - ListBoxFlags ^= kListBox_OldFmtXorMask; - } - else - { - SelectedBgColor = in->ReadInt32(); - SelectedTextColor = in->ReadInt32(); - TextAlignment = (HorAlignment)in->ReadInt32(); - TextColor = in->ReadInt32(); - } - - // Items - ItemCount = in->ReadInt32(); - Items.resize(ItemCount); - SavedGameIndex.resize(ItemCount); - for (int i = 0; i < ItemCount; ++i) - Items[i] = StrUtil::ReadString(in); - // TODO: investigate this, it might be unreasonable to save and read - // savegame index like that because list of savegames may easily change - // in between writing and restoring the game. Perhaps clearing and forcing - // this list to update on load somehow may make more sense. - if (ListBoxFlags & kListBox_SvgIndex) - for (int i = 0; i < ItemCount; ++i) - SavedGameIndex[i] = in->ReadInt16(); - TopItem = in->ReadInt32(); - SelectedItem = in->ReadInt32(); +void GUIListBox::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { + GUIObject::ReadFromSavegame(in, svg_ver); + // Properties + ListBoxFlags = in->ReadInt32(); + Font = in->ReadInt32(); + if (svg_ver < kGuiSvgVersion_350) { + // reverse particular flags from older format + ListBoxFlags ^= kListBox_OldFmtXorMask; + } else { + SelectedBgColor = in->ReadInt32(); + SelectedTextColor = in->ReadInt32(); + TextAlignment = (HorAlignment)in->ReadInt32(); + TextColor = in->ReadInt32(); + } + + // Items + ItemCount = in->ReadInt32(); + Items.resize(ItemCount); + SavedGameIndex.resize(ItemCount); + for (int i = 0; i < ItemCount; ++i) + Items[i] = StrUtil::ReadString(in); + // TODO: investigate this, it might be unreasonable to save and read + // savegame index like that because list of savegames may easily change + // in between writing and restoring the game. Perhaps clearing and forcing + // this list to update on load somehow may make more sense. + if (ListBoxFlags & kListBox_SvgIndex) + for (int i = 0; i < ItemCount; ++i) + SavedGameIndex[i] = in->ReadInt16(); + TopItem = in->ReadInt32(); + SelectedItem = in->ReadInt32(); } -void GUIListBox::WriteToSavegame(Stream *out) const -{ - GUIObject::WriteToSavegame(out); - // Properties - out->WriteInt32(ListBoxFlags); - out->WriteInt32(Font); - out->WriteInt32(SelectedBgColor); - out->WriteInt32(SelectedTextColor); - out->WriteInt32(TextAlignment); - out->WriteInt32(TextColor); - - // Items - out->WriteInt32(ItemCount); - for (int i = 0; i < ItemCount; ++i) - StrUtil::WriteString(Items[i], out); - if (ListBoxFlags & kListBox_SvgIndex) - for (int i = 0; i < ItemCount; ++i) - out->WriteInt16(SavedGameIndex[i]); - out->WriteInt32(TopItem); - out->WriteInt32(SelectedItem); +void GUIListBox::WriteToSavegame(Stream *out) const { + GUIObject::WriteToSavegame(out); + // Properties + out->WriteInt32(ListBoxFlags); + out->WriteInt32(Font); + out->WriteInt32(SelectedBgColor); + out->WriteInt32(SelectedTextColor); + out->WriteInt32(TextAlignment); + out->WriteInt32(TextColor); + + // Items + out->WriteInt32(ItemCount); + for (int i = 0; i < ItemCount; ++i) + StrUtil::WriteString(Items[i], out); + if (ListBoxFlags & kListBox_SvgIndex) + for (int i = 0; i < ItemCount; ++i) + out->WriteInt16(SavedGameIndex[i]); + out->WriteInt32(TopItem); + out->WriteInt32(SelectedItem); } } // namespace Common diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index fcee121ce694..73974415e138 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -27,74 +27,71 @@ #include "gui/guiobject.h" #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class GUIListBox : public GUIObject -{ +class GUIListBox : public GUIObject { public: - GUIListBox(); - - bool AreArrowsShown() const; - bool IsBorderShown() const; - bool IsSvgIndex() const; - bool IsInRightMargin(int x) const; - int GetItemAt(int x, int y) const; - - // Operations - int AddItem(const String &text); - void Clear(); - void Draw(Bitmap *ds) override; - int InsertItem(int index, const String &text); - void RemoveItem(int index); - void SetShowArrows(bool on); - void SetShowBorder(bool on); - void SetSvgIndex(bool on); // TODO: work around this - void SetFont(int font); - void SetItemText(int index, const String &textt); - - // Events - bool OnMouseDown() override; - void OnMouseMove(int x, int y) override; - void OnResized() override; - - // Serialization - void ReadFromFile(Stream *in, GuiVersion gui_version) override; - void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + GUIListBox(); + + bool AreArrowsShown() const; + bool IsBorderShown() const; + bool IsSvgIndex() const; + bool IsInRightMargin(int x) const; + int GetItemAt(int x, int y) const; + + // Operations + int AddItem(const String &text); + void Clear(); + void Draw(Bitmap *ds) override; + int InsertItem(int index, const String &text); + void RemoveItem(int index); + void SetShowArrows(bool on); + void SetShowBorder(bool on); + void SetSvgIndex(bool on); // TODO: work around this + void SetFont(int font); + void SetItemText(int index, const String &textt); + + // Events + bool OnMouseDown() override; + void OnMouseMove(int x, int y) override; + void OnResized() override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Common::Stream *out) const override; // TODO: these members are currently public; hide them later public: - int32_t Font; - color_t TextColor; - HorAlignment TextAlignment; - color_t SelectedBgColor; - color_t SelectedTextColor; - int32_t RowHeight; - int32_t VisibleItemCount; - - std::vector Items; - std::vector SavedGameIndex; - int32_t SelectedItem; - int32_t TopItem; - Point MousePos; - - // TODO: remove these later - int32_t ItemCount; + int32_t Font; + color_t TextColor; + HorAlignment TextAlignment; + color_t SelectedBgColor; + color_t SelectedTextColor; + int32_t RowHeight; + int32_t VisibleItemCount; + + std::vector Items; + std::vector SavedGameIndex; + int32_t SelectedItem; + int32_t TopItem; + Point MousePos; + + // TODO: remove these later + int32_t ItemCount; private: - int32_t ListBoxFlags; + int32_t ListBoxFlags; - // A temporary solution for special drawing in the Editor - void DrawItemsFix(); - void DrawItemsUnfix(); - void PrepareTextToDraw(const String &text); + // A temporary solution for special drawing in the Editor + void DrawItemsFix(); + void DrawItemsUnfix(); + void PrepareTextToDraw(const String &text); - // prepared text buffer/cache - String _textToDraw; + // prepared text buffer/cache + String _textToDraw; }; } // namespace Common diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index 1b87cf1829ad..d71a9c8e3853 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -43,882 +43,775 @@ int guis_need_update = 1; int all_buttons_disabled = 0, gui_inv_pic = -1; int gui_disabled_style = 0; -namespace AGS -{ -namespace Common -{ - -/* static */ String GUIMain::FixupGUIName(const String &name) -{ - if (name.GetLength() > 0 && name[0u] != 'g') - return String::FromFormat("g%c%s", name[0u], name.Mid(1).Lower().GetCStr()); - return name; -} - -GUIMain::GUIMain() -{ - InitDefaults(); -} - -void GUIMain::InitDefaults() -{ - ID = 0; - Name.Empty(); - _flags = kGUIMain_DefFlags; - - X = 0; - Y = 0; - Width = 0; - Height = 0; - BgColor = 8; - BgImage = 0; - FgColor = 1; - Padding = TEXTWINDOW_PADDING_DEFAULT; - PopupStyle = kGUIPopupNormal; - PopupAtMouseY = -1; - Transparency = 0; - ZOrder = -1; - - FocusCtrl = 0; - HighlightCtrl = -1; - MouseOverCtrl = -1; - MouseDownCtrl = -1; - MouseWasAt.X = -1; - MouseWasAt.Y = -1; - - OnClickHandler.Empty(); - - _controls.clear(); - _ctrlRefs.clear(); - _ctrlDrawOrder.clear(); -} - -int GUIMain::FindControlUnderMouse(int leeway, bool must_be_clickable) const -{ - if (loaded_game_file_version <= kGameVersion_262) - { - // Ignore draw order On 2.6.2 and lower - for (size_t i = 0; i < _controls.size(); ++i) - { - if (!_controls[i]->IsVisible()) - continue; - if (!_controls[i]->IsClickable() && must_be_clickable) - continue; - if (_controls[i]->IsOverControl(mousex, mousey, leeway)) - return i; - } - } - else - { - for (size_t i = _controls.size(); i-- > 0;) - { - const int ctrl_index = _ctrlDrawOrder[i]; - if (!_controls[ctrl_index]->IsVisible()) - continue; - if (!_controls[ctrl_index]->IsClickable() && must_be_clickable) - continue; - if (_controls[ctrl_index]->IsOverControl(mousex, mousey, leeway)) - return ctrl_index; - } - } - return -1; +namespace AGS { +namespace Common { + +/* static */ String GUIMain::FixupGUIName(const String &name) { + if (name.GetLength() > 0 && name[0u] != 'g') + return String::FromFormat("g%c%s", name[0u], name.Mid(1).Lower().GetCStr()); + return name; +} + +GUIMain::GUIMain() { + InitDefaults(); } -int GUIMain::FindControlUnderMouse() const -{ - return FindControlUnderMouse(0, true); +void GUIMain::InitDefaults() { + ID = 0; + Name.Empty(); + _flags = kGUIMain_DefFlags; + + X = 0; + Y = 0; + Width = 0; + Height = 0; + BgColor = 8; + BgImage = 0; + FgColor = 1; + Padding = TEXTWINDOW_PADDING_DEFAULT; + PopupStyle = kGUIPopupNormal; + PopupAtMouseY = -1; + Transparency = 0; + ZOrder = -1; + + FocusCtrl = 0; + HighlightCtrl = -1; + MouseOverCtrl = -1; + MouseDownCtrl = -1; + MouseWasAt.X = -1; + MouseWasAt.Y = -1; + + OnClickHandler.Empty(); + + _controls.clear(); + _ctrlRefs.clear(); + _ctrlDrawOrder.clear(); } -int GUIMain::FindControlUnderMouse(int leeway) const -{ - return FindControlUnderMouse(leeway, true); +int GUIMain::FindControlUnderMouse(int leeway, bool must_be_clickable) const { + if (loaded_game_file_version <= kGameVersion_262) { + // Ignore draw order On 2.6.2 and lower + for (size_t i = 0; i < _controls.size(); ++i) { + if (!_controls[i]->IsVisible()) + continue; + if (!_controls[i]->IsClickable() && must_be_clickable) + continue; + if (_controls[i]->IsOverControl(mousex, mousey, leeway)) + return i; + } + } else { + for (size_t i = _controls.size(); i-- > 0;) { + const int ctrl_index = _ctrlDrawOrder[i]; + if (!_controls[ctrl_index]->IsVisible()) + continue; + if (!_controls[ctrl_index]->IsClickable() && must_be_clickable) + continue; + if (_controls[ctrl_index]->IsOverControl(mousex, mousey, leeway)) + return ctrl_index; + } + } + return -1; } -int GUIMain::GetControlCount() const -{ - return (int32_t)_controls.size(); +int GUIMain::FindControlUnderMouse() const { + return FindControlUnderMouse(0, true); } -GUIObject *GUIMain::GetControl(int index) const -{ - if (index < 0 || (size_t)index >= _controls.size()) - return nullptr; - return _controls[index]; +int GUIMain::FindControlUnderMouse(int leeway) const { + return FindControlUnderMouse(leeway, true); } -GUIControlType GUIMain::GetControlType(int index) const -{ - if (index < 0 || (size_t)index >= _ctrlRefs.size()) - return kGUIControlUndefined; - return _ctrlRefs[index].first; +int GUIMain::GetControlCount() const { + return (int32_t)_controls.size(); } -int32_t GUIMain::GetControlID(int index) const -{ - if (index < 0 || (size_t)index >= _ctrlRefs.size()) - return -1; - return _ctrlRefs[index].second; +GUIObject *GUIMain::GetControl(int index) const { + if (index < 0 || (size_t)index >= _controls.size()) + return nullptr; + return _controls[index]; } -bool GUIMain::IsClickable() const -{ - return (_flags & kGUIMain_Clickable) != 0; +GUIControlType GUIMain::GetControlType(int index) const { + if (index < 0 || (size_t)index >= _ctrlRefs.size()) + return kGUIControlUndefined; + return _ctrlRefs[index].first; } -bool GUIMain::IsConcealed() const -{ - return (_flags & kGUIMain_Concealed) != 0; +int32_t GUIMain::GetControlID(int index) const { + if (index < 0 || (size_t)index >= _ctrlRefs.size()) + return -1; + return _ctrlRefs[index].second; } -bool GUIMain::IsDisplayed() const -{ - if(!IsVisible()) return false; - if(IsConcealed()) return false; - if(Transparency == 255) return false; - return true; +bool GUIMain::IsClickable() const { + return (_flags & kGUIMain_Clickable) != 0; } -bool GUIMain::IsInteractableAt(int x, int y) const -{ - if (!IsDisplayed()) - return false; - if (!IsClickable()) - return false; - if ((x >= X) & (y >= Y) & (x < X + Width) & (y < Y + Height)) - return true; - return false; +bool GUIMain::IsConcealed() const { + return (_flags & kGUIMain_Concealed) != 0; } -bool GUIMain::IsTextWindow() const -{ - return (_flags & kGUIMain_TextWindow) != 0; +bool GUIMain::IsDisplayed() const { + if (!IsVisible()) return false; + if (IsConcealed()) return false; + if (Transparency == 255) return false; + return true; } -bool GUIMain::IsVisible() const -{ - return (_flags & kGUIMain_Visible) != 0; +bool GUIMain::IsInteractableAt(int x, int y) const { + if (!IsDisplayed()) + return false; + if (!IsClickable()) + return false; + if ((x >= X) & (y >= Y) & (x < X + Width) & (y < Y + Height)) + return true; + return false; } -void GUIMain::AddControl(GUIControlType type, int id, GUIObject *control) -{ - _ctrlRefs.push_back(std::make_pair(type, id)); - _controls.push_back(control); +bool GUIMain::IsTextWindow() const { + return (_flags & kGUIMain_TextWindow) != 0; } -void GUIMain::RemoveAllControls() -{ - _ctrlRefs.clear(); - _controls.clear(); +bool GUIMain::IsVisible() const { + return (_flags & kGUIMain_Visible) != 0; } -bool GUIMain::BringControlToFront(int index) -{ - return SetControlZOrder(index, (int)_controls.size() - 1); +void GUIMain::AddControl(GUIControlType type, int id, GUIObject *control) { + _ctrlRefs.push_back(std::make_pair(type, id)); + _controls.push_back(control); } -void GUIMain::Draw(Bitmap *ds) -{ - DrawAt(ds, X, Y); +void GUIMain::RemoveAllControls() { + _ctrlRefs.clear(); + _controls.clear(); } -void GUIMain::DrawAt(Bitmap *ds, int x, int y) -{ - SET_EIP(375) +bool GUIMain::BringControlToFront(int index) { + return SetControlZOrder(index, (int)_controls.size() - 1); +} + +void GUIMain::Draw(Bitmap *ds) { + DrawAt(ds, X, Y); +} + +void GUIMain::DrawAt(Bitmap *ds, int x, int y) { + SET_EIP(375) + + if ((Width < 1) || (Height < 1)) + return; + + Bitmap subbmp; + subbmp.CreateSubBitmap(ds, RectWH(x, y, Width, Height)); + + SET_EIP(376) + // stop border being transparent, if the whole GUI isn't + if ((FgColor == 0) && (BgColor != 0)) + FgColor = 16; + + if (BgColor != 0) + subbmp.Fill(subbmp.GetCompatibleColor(BgColor)); - if ((Width < 1) || (Height < 1)) - return; + SET_EIP(377) - Bitmap subbmp; - subbmp.CreateSubBitmap(ds, RectWH(x, y, Width, Height)); + color_t draw_color; + if (FgColor != BgColor) { + draw_color = subbmp.GetCompatibleColor(FgColor); + subbmp.DrawRect(Rect(0, 0, subbmp.GetWidth() - 1, subbmp.GetHeight() - 1), draw_color); + if (get_fixed_pixel_size(1) > 1) + subbmp.DrawRect(Rect(1, 1, subbmp.GetWidth() - 2, subbmp.GetHeight() - 2), draw_color); + } + + SET_EIP(378) + + if (BgImage > 0 && spriteset[BgImage] != nullptr) + draw_gui_sprite(&subbmp, BgImage, 0, 0, false); + + SET_EIP(379) + + if (all_buttons_disabled && gui_disabled_style == GUIDIS_BLACKOUT) + return; // don't draw GUI controls + + for (size_t ctrl_index = 0; ctrl_index < _controls.size(); ++ctrl_index) { + set_eip_guiobj(_ctrlDrawOrder[ctrl_index]); + + GUIObject *objToDraw = _controls[_ctrlDrawOrder[ctrl_index]]; + + if (!objToDraw->IsEnabled() && gui_disabled_style == GUIDIS_BLACKOUT) + continue; + if (!objToDraw->IsVisible()) + continue; + + objToDraw->Draw(&subbmp); + + int selectedColour = 14; + + if (HighlightCtrl == _ctrlDrawOrder[ctrl_index]) { + if (outlineGuiObjects) + selectedColour = 13; + draw_color = subbmp.GetCompatibleColor(selectedColour); + DrawBlob(&subbmp, objToDraw->X + objToDraw->Width - get_fixed_pixel_size(1) - 1, objToDraw->Y, draw_color); + DrawBlob(&subbmp, objToDraw->X, objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); + DrawBlob(&subbmp, objToDraw->X, objToDraw->Y, draw_color); + DrawBlob(&subbmp, objToDraw->X + objToDraw->Width - get_fixed_pixel_size(1) - 1, + objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); + } + if (outlineGuiObjects) { + // draw a dotted outline round all objects + draw_color = subbmp.GetCompatibleColor(selectedColour); + for (int i = 0; i < objToDraw->Width; i += 2) { + subbmp.PutPixel(i + objToDraw->X, objToDraw->Y, draw_color); + subbmp.PutPixel(i + objToDraw->X, objToDraw->Y + objToDraw->Height - 1, draw_color); + } + for (int i = 0; i < objToDraw->Height; i += 2) { + subbmp.PutPixel(objToDraw->X, i + objToDraw->Y, draw_color); + subbmp.PutPixel(objToDraw->X + objToDraw->Width - 1, i + objToDraw->Y, draw_color); + } + } + } + + SET_EIP(380) +} + +void GUIMain::DrawBlob(Bitmap *ds, int x, int y, color_t draw_color) { + ds->FillRect(Rect(x, y, x + get_fixed_pixel_size(1), y + get_fixed_pixel_size(1)), draw_color); +} - SET_EIP(376) - // stop border being transparent, if the whole GUI isn't - if ((FgColor == 0) && (BgColor != 0)) - FgColor = 16; +void GUIMain::Poll() { + int mxwas = mousex, mywas = mousey; - if (BgColor != 0) - subbmp.Fill(subbmp.GetCompatibleColor(BgColor)); + mousex -= X; + mousey -= Y; + if (mousex != MouseWasAt.X || mousey != MouseWasAt.Y) { + int ctrl_index = FindControlUnderMouse(); - SET_EIP(377) + if (MouseOverCtrl == MOVER_MOUSEDOWNLOCKED) + _controls[MouseDownCtrl]->OnMouseMove(mousex, mousey); + else if (ctrl_index != MouseOverCtrl) { + if (MouseOverCtrl >= 0) + _controls[MouseOverCtrl]->OnMouseLeave(); - color_t draw_color; - if (FgColor != BgColor) - { - draw_color = subbmp.GetCompatibleColor(FgColor); - subbmp.DrawRect(Rect(0, 0, subbmp.GetWidth() - 1, subbmp.GetHeight() - 1), draw_color); - if (get_fixed_pixel_size(1) > 1) - subbmp.DrawRect(Rect(1, 1, subbmp.GetWidth() - 2, subbmp.GetHeight() - 2), draw_color); - } - - SET_EIP(378) - - if (BgImage > 0 && spriteset[BgImage] != nullptr) - draw_gui_sprite(&subbmp, BgImage, 0, 0, false); - - SET_EIP(379) - - if (all_buttons_disabled && gui_disabled_style == GUIDIS_BLACKOUT) - return; // don't draw GUI controls - - for (size_t ctrl_index = 0; ctrl_index < _controls.size(); ++ctrl_index) - { - set_eip_guiobj(_ctrlDrawOrder[ctrl_index]); - - GUIObject *objToDraw = _controls[_ctrlDrawOrder[ctrl_index]]; - - if (!objToDraw->IsEnabled() && gui_disabled_style == GUIDIS_BLACKOUT) - continue; - if (!objToDraw->IsVisible()) - continue; - - objToDraw->Draw(&subbmp); - - int selectedColour = 14; - - if (HighlightCtrl == _ctrlDrawOrder[ctrl_index]) - { - if (outlineGuiObjects) - selectedColour = 13; - draw_color = subbmp.GetCompatibleColor(selectedColour); - DrawBlob(&subbmp, objToDraw->X + objToDraw->Width - get_fixed_pixel_size(1) - 1, objToDraw->Y, draw_color); - DrawBlob(&subbmp, objToDraw->X, objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); - DrawBlob(&subbmp, objToDraw->X, objToDraw->Y, draw_color); - DrawBlob(&subbmp, objToDraw->X + objToDraw->Width - get_fixed_pixel_size(1) - 1, - objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); - } - if (outlineGuiObjects) - { - // draw a dotted outline round all objects - draw_color = subbmp.GetCompatibleColor(selectedColour); - for (int i = 0; i < objToDraw->Width; i += 2) - { - subbmp.PutPixel(i + objToDraw->X, objToDraw->Y, draw_color); - subbmp.PutPixel(i + objToDraw->X, objToDraw->Y + objToDraw->Height - 1, draw_color); - } - for (int i = 0; i < objToDraw->Height; i += 2) - { - subbmp.PutPixel(objToDraw->X, i + objToDraw->Y, draw_color); - subbmp.PutPixel(objToDraw->X + objToDraw->Width - 1, i + objToDraw->Y, draw_color); - } - } - } - - SET_EIP(380) -} - -void GUIMain::DrawBlob(Bitmap *ds, int x, int y, color_t draw_color) -{ - ds->FillRect(Rect(x, y, x + get_fixed_pixel_size(1), y + get_fixed_pixel_size(1)), draw_color); -} - -void GUIMain::Poll() -{ - int mxwas = mousex, mywas = mousey; - - mousex -= X; - mousey -= Y; - if (mousex != MouseWasAt.X || mousey != MouseWasAt.Y) - { - int ctrl_index = FindControlUnderMouse(); - - if (MouseOverCtrl == MOVER_MOUSEDOWNLOCKED) - _controls[MouseDownCtrl]->OnMouseMove(mousex, mousey); - else if (ctrl_index != MouseOverCtrl) - { - if (MouseOverCtrl >= 0) - _controls[MouseOverCtrl]->OnMouseLeave(); - - if (ctrl_index >= 0 && !IsGUIEnabled(_controls[ctrl_index])) - // the control is disabled - ignore it - MouseOverCtrl = -1; - else if (ctrl_index >= 0 && !_controls[ctrl_index]->IsClickable()) - // the control is not clickable - ignore it - MouseOverCtrl = -1; - else - { - // over a different control - MouseOverCtrl = ctrl_index; - if (MouseOverCtrl >= 0) - { - _controls[MouseOverCtrl]->OnMouseEnter(); - _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); - } - } - guis_need_update = 1; - } - else if (MouseOverCtrl >= 0) - _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); - } - - MouseWasAt.X = mousex; - MouseWasAt.Y = mousey; - mousex = mxwas; - mousey = mywas; -} - -HError GUIMain::RebuildArray() -{ - GUIControlType thistype; - int32_t thisnum; - - _controls.resize(_ctrlRefs.size()); - for (size_t i = 0; i < _controls.size(); ++i) - { - thistype = _ctrlRefs[i].first; - thisnum = _ctrlRefs[i].second; - - if (thisnum < 0) - return new Error(String::FromFormat("GUIMain (%d): invalid control ID %d in ref #%d", ID, thisnum, i)); - - if (thistype == kGUIButton) - _controls[i] = &guibuts[thisnum]; - else if (thistype == kGUILabel) - _controls[i] = &guilabels[thisnum]; - else if (thistype == kGUIInvWindow) - _controls[i] = &guiinv[thisnum]; - else if (thistype == kGUISlider) - _controls[i] = &guislider[thisnum]; - else if (thistype == kGUITextBox) - _controls[i] = &guitext[thisnum]; - else if (thistype == kGUIListBox) - _controls[i] = &guilist[thisnum]; - else - return new Error(String::FromFormat("GUIMain (%d): unknown control type %d in ref #%d", ID, thistype, i)); - - _controls[i]->ParentId = ID; - _controls[i]->Id = i; - } - - ResortZOrder(); - return HError::None(); -} - -bool GUIControlZOrder(const GUIObject *e1, const GUIObject *e2) -{ - return e1->ZOrder < e2->ZOrder; -} - -void GUIMain::ResortZOrder() -{ - std::vector ctrl_sort = _controls; - std::sort(ctrl_sort.begin(), ctrl_sort.end(), GUIControlZOrder); - - _ctrlDrawOrder.resize(ctrl_sort.size()); - for (size_t i = 0; i < ctrl_sort.size(); ++i) - _ctrlDrawOrder[i] = ctrl_sort[i]->Id; -} - -void GUIMain::SetClickable(bool on) -{ - if (on) - _flags |= kGUIMain_Clickable; - else - _flags &= ~kGUIMain_Clickable; -} - -void GUIMain::SetConceal(bool on) -{ - if (on) - _flags |= kGUIMain_Concealed; - else - _flags &= ~kGUIMain_Concealed; -} - -bool GUIMain::SendControlToBack(int index) -{ - return SetControlZOrder(index, 0); -} - -bool GUIMain::SetControlZOrder(int index, int zorder) -{ - if (index < 0 || (size_t)index >= _controls.size()) - return false; // no such control - - zorder = Math::Clamp(zorder, 0, (int)_controls.size() - 1); - const int old_zorder = _controls[index]->ZOrder; - if (old_zorder == zorder) - return false; // no change - - const bool move_back = zorder < old_zorder; // back is at zero index - const int left = move_back ? zorder : old_zorder; - const int right = move_back ? old_zorder : zorder; - for (size_t i = 0; i < _controls.size(); ++i) - { - const int i_zorder = _controls[i]->ZOrder; - if (i_zorder == old_zorder) - _controls[i]->ZOrder = zorder; // the control we are moving - else if (i_zorder >= left && i_zorder <= right) - { - // controls in between old and new positions shift towards free place - if (move_back) - _controls[i]->ZOrder++; // move to front - else - _controls[i]->ZOrder--; // move to back - } - } - ResortZOrder(); - OnControlPositionChanged(); - return true; -} - -void GUIMain::SetTextWindow(bool on) -{ - if (on) - _flags |= kGUIMain_TextWindow; - else - _flags &= ~kGUIMain_TextWindow; -} - -void GUIMain::SetTransparencyAsPercentage(int percent) -{ - Transparency = GfxDef::Trans100ToLegacyTrans255(percent); - guis_need_update = 1; -} - -void GUIMain::SetVisible(bool on) -{ - if (on) - _flags |= kGUIMain_Visible; - else - _flags &= ~kGUIMain_Visible; -} - -void GUIMain::OnControlPositionChanged() -{ - // force it to re-check for which control is under the mouse - MouseWasAt.X = -1; - MouseWasAt.Y = -1; -} - -void GUIMain::OnMouseButtonDown() -{ - if (MouseOverCtrl < 0) - return; - - // don't activate disabled buttons - if (!IsGUIEnabled(_controls[MouseOverCtrl]) || !_controls[MouseOverCtrl]->IsVisible() || - !_controls[MouseOverCtrl]->IsClickable()) - return; - - MouseDownCtrl = MouseOverCtrl; - if (_controls[MouseOverCtrl]->OnMouseDown()) - MouseOverCtrl = MOVER_MOUSEDOWNLOCKED; - _controls[MouseDownCtrl]->OnMouseMove(mousex - X, mousey - Y); - guis_need_update = 1; -} - -void GUIMain::OnMouseButtonUp() -{ - // FocusCtrl was locked - reset it back to normal, but On the - // locked object so that a OnMouseLeave gets fired if necessary - if (MouseOverCtrl == MOVER_MOUSEDOWNLOCKED) - { - MouseOverCtrl = MouseDownCtrl; - MouseWasAt.X = -1; // force update - } - - if (MouseDownCtrl < 0) - return; - - _controls[MouseDownCtrl]->OnMouseUp(); - MouseDownCtrl = -1; - guis_need_update = 1; -} - -void GUIMain::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - // Legacy text window tag - char tw_flags[GUIMAIN_LEGACY_TW_FLAGS_SIZE] = {0}; - if (gui_version < kGuiVersion_350) - in->Read(tw_flags, sizeof(tw_flags)); - - if (gui_version < kGuiVersion_340) - { - Name.ReadCount(in, GUIMAIN_LEGACY_NAME_LENGTH); - OnClickHandler.ReadCount(in, GUIMAIN_LEGACY_EVENTHANDLER_LENGTH); - } - else - { - Name = StrUtil::ReadString(in); - OnClickHandler = StrUtil::ReadString(in); - } - X = in->ReadInt32(); - Y = in->ReadInt32(); - Width = in->ReadInt32(); - Height = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - { // NOTE: reading into actual variables only for old savegame support - FocusCtrl = in->ReadInt32(); - } - const size_t ctrl_count = in->ReadInt32(); - PopupStyle = (GUIPopupStyle)in->ReadInt32(); - PopupAtMouseY = in->ReadInt32(); - BgColor = in->ReadInt32(); - BgImage = in->ReadInt32(); - FgColor = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - { // NOTE: reading into actual variables only for old savegame support - MouseOverCtrl = in->ReadInt32(); - MouseWasAt.X = in->ReadInt32(); - MouseWasAt.Y = in->ReadInt32(); - MouseDownCtrl = in->ReadInt32(); - HighlightCtrl = in->ReadInt32(); - } - _flags = in->ReadInt32(); - Transparency = in->ReadInt32(); - ZOrder = in->ReadInt32(); - ID = in->ReadInt32(); - Padding = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - in->Seek(sizeof(int32_t) * GUIMAIN_LEGACY_RESERVED_INTS); - - if (gui_version < kGuiVersion_350) - { - if (tw_flags[0] == kGUIMain_LegacyTextWindow) - _flags |= kGUIMain_TextWindow; - // reverse particular flags from older format - _flags ^= kGUIMain_OldFmtXorMask; - GUI::ApplyLegacyVisibility(*this, (LegacyGUIVisState)in->ReadInt32()); - } - - // pre-3.4.0 games contained array of 32-bit pointers; these values are unused - // TODO: error if ctrl_count > LEGACY_MAX_OBJS_ON_GUI - if (gui_version < kGuiVersion_340) - in->Seek(LEGACY_MAX_OBJS_ON_GUI * sizeof(int32_t)); - if (ctrl_count > 0) - { - _ctrlRefs.resize(ctrl_count); - for (size_t i = 0; i < ctrl_count; ++i) - { - const int32_t ref_packed = in->ReadInt32(); - _ctrlRefs[i].first = (GUIControlType)((ref_packed >> 16) & 0xFFFF); - _ctrlRefs[i].second = ref_packed & 0xFFFF; - } - } - // Skip unused control slots in pre-3.4.0 games - if (gui_version < kGuiVersion_340 && ctrl_count < LEGACY_MAX_OBJS_ON_GUI) - in->Seek((LEGACY_MAX_OBJS_ON_GUI - ctrl_count) * sizeof(int32_t)); -} - -void GUIMain::WriteToFile(Stream *out) const -{ - StrUtil::WriteString(Name, out); - StrUtil::WriteString(OnClickHandler, out); - out->WriteInt32(X); - out->WriteInt32(Y); - out->WriteInt32(Width); - out->WriteInt32(Height); - out->WriteInt32(_ctrlRefs.size()); - out->WriteInt32(PopupStyle); - out->WriteInt32(PopupAtMouseY); - out->WriteInt32(BgColor); - out->WriteInt32(BgImage); - out->WriteInt32(FgColor); - out->WriteInt32(_flags); - out->WriteInt32(Transparency); - out->WriteInt32(ZOrder); - out->WriteInt32(ID); - out->WriteInt32(Padding); - for (size_t i = 0; i < _ctrlRefs.size(); ++i) - { - int32_t ref_packed = ((_ctrlRefs[i].first & 0xFFFF) << 16) | (_ctrlRefs[i].second & 0xFFFF); - out->WriteInt32(ref_packed); - } -} - -void GUIMain::ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_version) -{ - // Properties - _flags = in->ReadInt32(); - X = in->ReadInt32(); - Y = in->ReadInt32(); - Width = in->ReadInt32(); - Height = in->ReadInt32(); - BgImage = in->ReadInt32(); - Transparency = in->ReadInt32(); - if (svg_version < kGuiSvgVersion_350) - { - // reverse particular flags from older format - _flags ^= kGUIMain_OldFmtXorMask; - GUI::ApplyLegacyVisibility(*this, (LegacyGUIVisState)in->ReadInt32()); - } - ZOrder = in->ReadInt32(); - - if (svg_version >= kGuiSvgVersion_350) - { - BgColor = in->ReadInt32(); - FgColor = in->ReadInt32(); - Padding = in->ReadInt32(); - PopupAtMouseY = in->ReadInt32(); - } - - // Dynamic values - FocusCtrl = in->ReadInt32(); - HighlightCtrl = in->ReadInt32(); - MouseOverCtrl = in->ReadInt32(); - MouseDownCtrl = in->ReadInt32(); - MouseWasAt.X = in->ReadInt32(); - MouseWasAt.Y = in->ReadInt32(); -} - -void GUIMain::WriteToSavegame(Common::Stream *out) const -{ - // Properties - out->WriteInt32(_flags); - out->WriteInt32(X); - out->WriteInt32(Y); - out->WriteInt32(Width); - out->WriteInt32(Height); - out->WriteInt32(BgImage); - out->WriteInt32(Transparency); - out->WriteInt32(ZOrder); - out->WriteInt32(BgColor); - out->WriteInt32(FgColor); - out->WriteInt32(Padding); - out->WriteInt32(PopupAtMouseY); - // Dynamic values - out->WriteInt32(FocusCtrl); - out->WriteInt32(HighlightCtrl); - out->WriteInt32(MouseOverCtrl); - out->WriteInt32(MouseDownCtrl); - out->WriteInt32(MouseWasAt.X); - out->WriteInt32(MouseWasAt.Y); -} - - -namespace GUI -{ + if (ctrl_index >= 0 && !IsGUIEnabled(_controls[ctrl_index])) + // the control is disabled - ignore it + MouseOverCtrl = -1; + else if (ctrl_index >= 0 && !_controls[ctrl_index]->IsClickable()) + // the control is not clickable - ignore it + MouseOverCtrl = -1; + else { + // over a different control + MouseOverCtrl = ctrl_index; + if (MouseOverCtrl >= 0) { + _controls[MouseOverCtrl]->OnMouseEnter(); + _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); + } + } + guis_need_update = 1; + } else if (MouseOverCtrl >= 0) + _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); + } + + MouseWasAt.X = mousex; + MouseWasAt.Y = mousey; + mousex = mxwas; + mousey = mywas; +} + +HError GUIMain::RebuildArray() { + GUIControlType thistype; + int32_t thisnum; + + _controls.resize(_ctrlRefs.size()); + for (size_t i = 0; i < _controls.size(); ++i) { + thistype = _ctrlRefs[i].first; + thisnum = _ctrlRefs[i].second; + + if (thisnum < 0) + return new Error(String::FromFormat("GUIMain (%d): invalid control ID %d in ref #%d", ID, thisnum, i)); + + if (thistype == kGUIButton) + _controls[i] = &guibuts[thisnum]; + else if (thistype == kGUILabel) + _controls[i] = &guilabels[thisnum]; + else if (thistype == kGUIInvWindow) + _controls[i] = &guiinv[thisnum]; + else if (thistype == kGUISlider) + _controls[i] = &guislider[thisnum]; + else if (thistype == kGUITextBox) + _controls[i] = &guitext[thisnum]; + else if (thistype == kGUIListBox) + _controls[i] = &guilist[thisnum]; + else + return new Error(String::FromFormat("GUIMain (%d): unknown control type %d in ref #%d", ID, thistype, i)); + + _controls[i]->ParentId = ID; + _controls[i]->Id = i; + } + + ResortZOrder(); + return HError::None(); +} + +bool GUIControlZOrder(const GUIObject *e1, const GUIObject *e2) { + return e1->ZOrder < e2->ZOrder; +} + +void GUIMain::ResortZOrder() { + std::vector ctrl_sort = _controls; + std::sort(ctrl_sort.begin(), ctrl_sort.end(), GUIControlZOrder); + + _ctrlDrawOrder.resize(ctrl_sort.size()); + for (size_t i = 0; i < ctrl_sort.size(); ++i) + _ctrlDrawOrder[i] = ctrl_sort[i]->Id; +} + +void GUIMain::SetClickable(bool on) { + if (on) + _flags |= kGUIMain_Clickable; + else + _flags &= ~kGUIMain_Clickable; +} + +void GUIMain::SetConceal(bool on) { + if (on) + _flags |= kGUIMain_Concealed; + else + _flags &= ~kGUIMain_Concealed; +} + +bool GUIMain::SendControlToBack(int index) { + return SetControlZOrder(index, 0); +} + +bool GUIMain::SetControlZOrder(int index, int zorder) { + if (index < 0 || (size_t)index >= _controls.size()) + return false; // no such control + + zorder = Math::Clamp(zorder, 0, (int)_controls.size() - 1); + const int old_zorder = _controls[index]->ZOrder; + if (old_zorder == zorder) + return false; // no change + + const bool move_back = zorder < old_zorder; // back is at zero index + const int left = move_back ? zorder : old_zorder; + const int right = move_back ? old_zorder : zorder; + for (size_t i = 0; i < _controls.size(); ++i) { + const int i_zorder = _controls[i]->ZOrder; + if (i_zorder == old_zorder) + _controls[i]->ZOrder = zorder; // the control we are moving + else if (i_zorder >= left && i_zorder <= right) { + // controls in between old and new positions shift towards free place + if (move_back) + _controls[i]->ZOrder++; // move to front + else + _controls[i]->ZOrder--; // move to back + } + } + ResortZOrder(); + OnControlPositionChanged(); + return true; +} + +void GUIMain::SetTextWindow(bool on) { + if (on) + _flags |= kGUIMain_TextWindow; + else + _flags &= ~kGUIMain_TextWindow; +} + +void GUIMain::SetTransparencyAsPercentage(int percent) { + Transparency = GfxDef::Trans100ToLegacyTrans255(percent); + guis_need_update = 1; +} + +void GUIMain::SetVisible(bool on) { + if (on) + _flags |= kGUIMain_Visible; + else + _flags &= ~kGUIMain_Visible; +} + +void GUIMain::OnControlPositionChanged() { + // force it to re-check for which control is under the mouse + MouseWasAt.X = -1; + MouseWasAt.Y = -1; +} + +void GUIMain::OnMouseButtonDown() { + if (MouseOverCtrl < 0) + return; + + // don't activate disabled buttons + if (!IsGUIEnabled(_controls[MouseOverCtrl]) || !_controls[MouseOverCtrl]->IsVisible() || + !_controls[MouseOverCtrl]->IsClickable()) + return; + + MouseDownCtrl = MouseOverCtrl; + if (_controls[MouseOverCtrl]->OnMouseDown()) + MouseOverCtrl = MOVER_MOUSEDOWNLOCKED; + _controls[MouseDownCtrl]->OnMouseMove(mousex - X, mousey - Y); + guis_need_update = 1; +} + +void GUIMain::OnMouseButtonUp() { + // FocusCtrl was locked - reset it back to normal, but On the + // locked object so that a OnMouseLeave gets fired if necessary + if (MouseOverCtrl == MOVER_MOUSEDOWNLOCKED) { + MouseOverCtrl = MouseDownCtrl; + MouseWasAt.X = -1; // force update + } + + if (MouseDownCtrl < 0) + return; + + _controls[MouseDownCtrl]->OnMouseUp(); + MouseDownCtrl = -1; + guis_need_update = 1; +} + +void GUIMain::ReadFromFile(Stream *in, GuiVersion gui_version) { + // Legacy text window tag + char tw_flags[GUIMAIN_LEGACY_TW_FLAGS_SIZE] = {0}; + if (gui_version < kGuiVersion_350) + in->Read(tw_flags, sizeof(tw_flags)); + + if (gui_version < kGuiVersion_340) { + Name.ReadCount(in, GUIMAIN_LEGACY_NAME_LENGTH); + OnClickHandler.ReadCount(in, GUIMAIN_LEGACY_EVENTHANDLER_LENGTH); + } else { + Name = StrUtil::ReadString(in); + OnClickHandler = StrUtil::ReadString(in); + } + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + if (gui_version < kGuiVersion_350) { + // NOTE: reading into actual variables only for old savegame support + FocusCtrl = in->ReadInt32(); + } + const size_t ctrl_count = in->ReadInt32(); + PopupStyle = (GUIPopupStyle)in->ReadInt32(); + PopupAtMouseY = in->ReadInt32(); + BgColor = in->ReadInt32(); + BgImage = in->ReadInt32(); + FgColor = in->ReadInt32(); + if (gui_version < kGuiVersion_350) { + // NOTE: reading into actual variables only for old savegame support + MouseOverCtrl = in->ReadInt32(); + MouseWasAt.X = in->ReadInt32(); + MouseWasAt.Y = in->ReadInt32(); + MouseDownCtrl = in->ReadInt32(); + HighlightCtrl = in->ReadInt32(); + } + _flags = in->ReadInt32(); + Transparency = in->ReadInt32(); + ZOrder = in->ReadInt32(); + ID = in->ReadInt32(); + Padding = in->ReadInt32(); + if (gui_version < kGuiVersion_350) + in->Seek(sizeof(int32_t) * GUIMAIN_LEGACY_RESERVED_INTS); + + if (gui_version < kGuiVersion_350) { + if (tw_flags[0] == kGUIMain_LegacyTextWindow) + _flags |= kGUIMain_TextWindow; + // reverse particular flags from older format + _flags ^= kGUIMain_OldFmtXorMask; + GUI::ApplyLegacyVisibility(*this, (LegacyGUIVisState)in->ReadInt32()); + } + + // pre-3.4.0 games contained array of 32-bit pointers; these values are unused + // TODO: error if ctrl_count > LEGACY_MAX_OBJS_ON_GUI + if (gui_version < kGuiVersion_340) + in->Seek(LEGACY_MAX_OBJS_ON_GUI * sizeof(int32_t)); + if (ctrl_count > 0) { + _ctrlRefs.resize(ctrl_count); + for (size_t i = 0; i < ctrl_count; ++i) { + const int32_t ref_packed = in->ReadInt32(); + _ctrlRefs[i].first = (GUIControlType)((ref_packed >> 16) & 0xFFFF); + _ctrlRefs[i].second = ref_packed & 0xFFFF; + } + } + // Skip unused control slots in pre-3.4.0 games + if (gui_version < kGuiVersion_340 && ctrl_count < LEGACY_MAX_OBJS_ON_GUI) + in->Seek((LEGACY_MAX_OBJS_ON_GUI - ctrl_count) * sizeof(int32_t)); +} + +void GUIMain::WriteToFile(Stream *out) const { + StrUtil::WriteString(Name, out); + StrUtil::WriteString(OnClickHandler, out); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(_ctrlRefs.size()); + out->WriteInt32(PopupStyle); + out->WriteInt32(PopupAtMouseY); + out->WriteInt32(BgColor); + out->WriteInt32(BgImage); + out->WriteInt32(FgColor); + out->WriteInt32(_flags); + out->WriteInt32(Transparency); + out->WriteInt32(ZOrder); + out->WriteInt32(ID); + out->WriteInt32(Padding); + for (size_t i = 0; i < _ctrlRefs.size(); ++i) { + int32_t ref_packed = ((_ctrlRefs[i].first & 0xFFFF) << 16) | (_ctrlRefs[i].second & 0xFFFF); + out->WriteInt32(ref_packed); + } +} + +void GUIMain::ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_version) { + // Properties + _flags = in->ReadInt32(); + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + BgImage = in->ReadInt32(); + Transparency = in->ReadInt32(); + if (svg_version < kGuiSvgVersion_350) { + // reverse particular flags from older format + _flags ^= kGUIMain_OldFmtXorMask; + GUI::ApplyLegacyVisibility(*this, (LegacyGUIVisState)in->ReadInt32()); + } + ZOrder = in->ReadInt32(); + + if (svg_version >= kGuiSvgVersion_350) { + BgColor = in->ReadInt32(); + FgColor = in->ReadInt32(); + Padding = in->ReadInt32(); + PopupAtMouseY = in->ReadInt32(); + } + + // Dynamic values + FocusCtrl = in->ReadInt32(); + HighlightCtrl = in->ReadInt32(); + MouseOverCtrl = in->ReadInt32(); + MouseDownCtrl = in->ReadInt32(); + MouseWasAt.X = in->ReadInt32(); + MouseWasAt.Y = in->ReadInt32(); +} + +void GUIMain::WriteToSavegame(Common::Stream *out) const { + // Properties + out->WriteInt32(_flags); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(BgImage); + out->WriteInt32(Transparency); + out->WriteInt32(ZOrder); + out->WriteInt32(BgColor); + out->WriteInt32(FgColor); + out->WriteInt32(Padding); + out->WriteInt32(PopupAtMouseY); + // Dynamic values + out->WriteInt32(FocusCtrl); + out->WriteInt32(HighlightCtrl); + out->WriteInt32(MouseOverCtrl); + out->WriteInt32(MouseDownCtrl); + out->WriteInt32(MouseWasAt.X); + out->WriteInt32(MouseWasAt.Y); +} + + +namespace GUI { GuiVersion GameGuiVersion = kGuiVersion_Initial; -void DrawDisabledEffect(Bitmap *ds, const Rect &rc) -{ - color_t draw_color = ds->GetCompatibleColor(8); - for (int at_x = rc.Left; at_x <= rc.Right; ++at_x) - { - for (int at_y = rc.Top + at_x % 2; at_y <= rc.Bottom; at_y += 2) - { - ds->PutPixel(at_x, at_y, draw_color); - } - } -} - -void DrawTextAligned(Bitmap *ds, const char *text, int font, color_t text_color, const Rect &frame, FrameAlignment align) -{ - int text_height = wgettextheight(text, font); - if (align & kMAlignVCenter) - text_height++; // CHECKME - Rect item = AlignInRect(frame, RectWH(0, 0, wgettextwidth(text, font), text_height), align); - wouttext_outline(ds, item.Left, item.Top, font, text_color, text); -} - -void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_color, int x1, int x2, int y, FrameAlignment align) -{ - int x = AlignInHRange(x1, x2, 0, wgettextwidth(text, font), align); - wouttext_outline(ds, x, y, font, text_color, text); -} - -HError ResortGUI(std::vector &guis, bool bwcompat_ctrl_zorder = false) -{ - // set up the reverse-lookup array - for (size_t gui_index = 0; gui_index < guis.size(); ++gui_index) - { - GUIMain &gui = guis[gui_index]; - HError err = gui.RebuildArray(); - if (!err) - return err; - for (int ctrl_index = 0; ctrl_index < gui.GetControlCount(); ++ctrl_index) - { - GUIObject *gui_ctrl = gui.GetControl(ctrl_index); - gui_ctrl->ParentId = gui_index; - gui_ctrl->Id = ctrl_index; - if (bwcompat_ctrl_zorder) - gui_ctrl->ZOrder = ctrl_index; - } - gui.ResortZOrder(); - } - guis_need_update = 1; - return HError::None(); -} - -HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame) -{ - if (in->ReadInt32() != (int)GUIMAGIC) - return new Error("ReadGUI: unknown format or file is corrupt"); - - GameGuiVersion = (GuiVersion)in->ReadInt32(); - Debug::Printf(kDbgMsg_Info, "Game GUI version: %d", GameGuiVersion); - size_t gui_count; - if (GameGuiVersion < kGuiVersion_214) - { - gui_count = (size_t)GameGuiVersion; - GameGuiVersion = kGuiVersion_Initial; - } - else if (GameGuiVersion > kGuiVersion_Current) - return new Error(String::FromFormat("ReadGUI: format version not supported (required %d, supported %d - %d)", - GameGuiVersion, kGuiVersion_Initial, kGuiVersion_Current)); - else - gui_count = in->ReadInt32(); - guis.resize(gui_count); - - // import the main GUI elements - for (size_t i = 0; i < gui_count; ++i) - { - GUIMain &gui = guis[i]; - gui.InitDefaults(); - gui.ReadFromFile(in, GameGuiVersion); - - // perform fixups - if (gui.Height < 2) - gui.Height = 2; - if (GameGuiVersion < kGuiVersion_unkn_103) - gui.Name.Format("GUI%d", i); - if (GameGuiVersion < kGuiVersion_260) - gui.ZOrder = i; - if (GameGuiVersion < kGuiVersion_270) - gui.OnClickHandler.Empty(); - if (GameGuiVersion < kGuiVersion_331) - gui.Padding = TEXTWINDOW_PADDING_DEFAULT; - // fix names for 2.x: "GUI" -> "gGui" - if (loaded_game_file_version <= kGameVersion_272) - gui.Name = GUIMain::FixupGUIName(gui.Name); - - // GUI popup style and visibility - if (GameGuiVersion < kGuiVersion_350 && !is_savegame) - { - // Convert legacy normal-off style into normal one - if (gui.PopupStyle == kGUIPopupLegacyNormalOff) - { - gui.PopupStyle = kGUIPopupNormal; - gui.SetVisible(false); - } - // Normal GUIs and PopupMouseY GUIs should start with Visible = true - else - { - gui.SetVisible(gui.PopupStyle != kGUIPopupModal); - } - } - - // PopupMouseY GUIs should be initially concealed - if (gui.PopupStyle == kGUIPopupMouseY) - gui.SetConceal(true); - // Assign ID to order in array - gui.ID = i; - } - - // buttons - numguibuts = in->ReadInt32(); - guibuts.resize(numguibuts); - for (int i = 0; i < numguibuts; ++i) - { - guibuts[i].ReadFromFile(in, GameGuiVersion); - } - // labels - numguilabels = in->ReadInt32(); - guilabels.resize(numguilabels); - for (int i = 0; i < numguilabels; ++i) - { - guilabels[i].ReadFromFile(in, GameGuiVersion); - } - // inv controls - numguiinv = in->ReadInt32(); - guiinv.resize(numguiinv); - for (int i = 0; i < numguiinv; ++i) - { - guiinv[i].ReadFromFile(in, GameGuiVersion); - } - - if (GameGuiVersion >= kGuiVersion_214) - { - // sliders - numguislider = in->ReadInt32(); - guislider.resize(numguislider); - for (int i = 0; i < numguislider; ++i) - { - guislider[i].ReadFromFile(in, GameGuiVersion); - } - } - if (GameGuiVersion >= kGuiVersion_222) - { - // text boxes - numguitext = in->ReadInt32(); - guitext.resize(numguitext); - for (int i = 0; i < numguitext; ++i) - { - guitext[i].ReadFromFile(in, GameGuiVersion); - } - } - if (GameGuiVersion >= kGuiVersion_230) - { - // list boxes - numguilist = in->ReadInt32(); - guilist.resize(numguilist); - for (int i = 0; i < numguilist; ++i) - { - guilist[i].ReadFromFile(in, GameGuiVersion); - } - } - return ResortGUI(guis, GameGuiVersion < kGuiVersion_272e); -} - -void WriteGUI(const std::vector &guis, Stream *out) -{ - out->WriteInt32(GUIMAGIC); - out->WriteInt32(kGuiVersion_Current); - out->WriteInt32(guis.size()); - - for (size_t i = 0; i < guis.size(); ++i) - { - guis[i].WriteToFile(out); - } - out->WriteInt32(numguibuts); - for (int i = 0; i < numguibuts; ++i) - { - guibuts[i].WriteToFile(out); - } - out->WriteInt32(numguilabels); - for (int i = 0; i < numguilabels; ++i) - { - guilabels[i].WriteToFile(out); - } - out->WriteInt32(numguiinv); - for (int i = 0; i < numguiinv; ++i) - { - guiinv[i].WriteToFile(out); - } - out->WriteInt32(numguislider); - for (int i = 0; i < numguislider; ++i) - { - guislider[i].WriteToFile(out); - } - out->WriteInt32(numguitext); - for (int i = 0; i < numguitext; ++i) - { - guitext[i].WriteToFile(out); - } - out->WriteInt32(numguilist); - for (int i = 0; i < numguilist; ++i) - { - guilist[i].WriteToFile(out); - } -} - -void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis) -{ - // kGUIPopupMouseY had its own rules, which we practically reverted now - if (gui.PopupStyle == kGUIPopupMouseY) - { - // it was only !Visible if the legacy Visibility was Concealed - gui.SetVisible(vis != kGUIVisibility_Concealed); - // and you could tell it's overridden by behavior when legacy Visibility is Off - gui.SetConceal(vis == kGUIVisibility_Off); - } - // Other GUI styles were simple - else - { - gui.SetVisible(vis != kGUIVisibility_Off); - gui.SetConceal(false); - } +void DrawDisabledEffect(Bitmap *ds, const Rect &rc) { + color_t draw_color = ds->GetCompatibleColor(8); + for (int at_x = rc.Left; at_x <= rc.Right; ++at_x) { + for (int at_y = rc.Top + at_x % 2; at_y <= rc.Bottom; at_y += 2) { + ds->PutPixel(at_x, at_y, draw_color); + } + } +} + +void DrawTextAligned(Bitmap *ds, const char *text, int font, color_t text_color, const Rect &frame, FrameAlignment align) { + int text_height = wgettextheight(text, font); + if (align & kMAlignVCenter) + text_height++; // CHECKME + Rect item = AlignInRect(frame, RectWH(0, 0, wgettextwidth(text, font), text_height), align); + wouttext_outline(ds, item.Left, item.Top, font, text_color, text); +} + +void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_color, int x1, int x2, int y, FrameAlignment align) { + int x = AlignInHRange(x1, x2, 0, wgettextwidth(text, font), align); + wouttext_outline(ds, x, y, font, text_color, text); +} + +HError ResortGUI(std::vector &guis, bool bwcompat_ctrl_zorder = false) { + // set up the reverse-lookup array + for (size_t gui_index = 0; gui_index < guis.size(); ++gui_index) { + GUIMain &gui = guis[gui_index]; + HError err = gui.RebuildArray(); + if (!err) + return err; + for (int ctrl_index = 0; ctrl_index < gui.GetControlCount(); ++ctrl_index) { + GUIObject *gui_ctrl = gui.GetControl(ctrl_index); + gui_ctrl->ParentId = gui_index; + gui_ctrl->Id = ctrl_index; + if (bwcompat_ctrl_zorder) + gui_ctrl->ZOrder = ctrl_index; + } + gui.ResortZOrder(); + } + guis_need_update = 1; + return HError::None(); +} + +HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame) { + if (in->ReadInt32() != (int)GUIMAGIC) + return new Error("ReadGUI: unknown format or file is corrupt"); + + GameGuiVersion = (GuiVersion)in->ReadInt32(); + Debug::Printf(kDbgMsg_Info, "Game GUI version: %d", GameGuiVersion); + size_t gui_count; + if (GameGuiVersion < kGuiVersion_214) { + gui_count = (size_t)GameGuiVersion; + GameGuiVersion = kGuiVersion_Initial; + } else if (GameGuiVersion > kGuiVersion_Current) + return new Error(String::FromFormat("ReadGUI: format version not supported (required %d, supported %d - %d)", + GameGuiVersion, kGuiVersion_Initial, kGuiVersion_Current)); + else + gui_count = in->ReadInt32(); + guis.resize(gui_count); + + // import the main GUI elements + for (size_t i = 0; i < gui_count; ++i) { + GUIMain &gui = guis[i]; + gui.InitDefaults(); + gui.ReadFromFile(in, GameGuiVersion); + + // perform fixups + if (gui.Height < 2) + gui.Height = 2; + if (GameGuiVersion < kGuiVersion_unkn_103) + gui.Name.Format("GUI%d", i); + if (GameGuiVersion < kGuiVersion_260) + gui.ZOrder = i; + if (GameGuiVersion < kGuiVersion_270) + gui.OnClickHandler.Empty(); + if (GameGuiVersion < kGuiVersion_331) + gui.Padding = TEXTWINDOW_PADDING_DEFAULT; + // fix names for 2.x: "GUI" -> "gGui" + if (loaded_game_file_version <= kGameVersion_272) + gui.Name = GUIMain::FixupGUIName(gui.Name); + + // GUI popup style and visibility + if (GameGuiVersion < kGuiVersion_350 && !is_savegame) { + // Convert legacy normal-off style into normal one + if (gui.PopupStyle == kGUIPopupLegacyNormalOff) { + gui.PopupStyle = kGUIPopupNormal; + gui.SetVisible(false); + } + // Normal GUIs and PopupMouseY GUIs should start with Visible = true + else { + gui.SetVisible(gui.PopupStyle != kGUIPopupModal); + } + } + + // PopupMouseY GUIs should be initially concealed + if (gui.PopupStyle == kGUIPopupMouseY) + gui.SetConceal(true); + // Assign ID to order in array + gui.ID = i; + } + + // buttons + numguibuts = in->ReadInt32(); + guibuts.resize(numguibuts); + for (int i = 0; i < numguibuts; ++i) { + guibuts[i].ReadFromFile(in, GameGuiVersion); + } + // labels + numguilabels = in->ReadInt32(); + guilabels.resize(numguilabels); + for (int i = 0; i < numguilabels; ++i) { + guilabels[i].ReadFromFile(in, GameGuiVersion); + } + // inv controls + numguiinv = in->ReadInt32(); + guiinv.resize(numguiinv); + for (int i = 0; i < numguiinv; ++i) { + guiinv[i].ReadFromFile(in, GameGuiVersion); + } + + if (GameGuiVersion >= kGuiVersion_214) { + // sliders + numguislider = in->ReadInt32(); + guislider.resize(numguislider); + for (int i = 0; i < numguislider; ++i) { + guislider[i].ReadFromFile(in, GameGuiVersion); + } + } + if (GameGuiVersion >= kGuiVersion_222) { + // text boxes + numguitext = in->ReadInt32(); + guitext.resize(numguitext); + for (int i = 0; i < numguitext; ++i) { + guitext[i].ReadFromFile(in, GameGuiVersion); + } + } + if (GameGuiVersion >= kGuiVersion_230) { + // list boxes + numguilist = in->ReadInt32(); + guilist.resize(numguilist); + for (int i = 0; i < numguilist; ++i) { + guilist[i].ReadFromFile(in, GameGuiVersion); + } + } + return ResortGUI(guis, GameGuiVersion < kGuiVersion_272e); +} + +void WriteGUI(const std::vector &guis, Stream *out) { + out->WriteInt32(GUIMAGIC); + out->WriteInt32(kGuiVersion_Current); + out->WriteInt32(guis.size()); + + for (size_t i = 0; i < guis.size(); ++i) { + guis[i].WriteToFile(out); + } + out->WriteInt32(numguibuts); + for (int i = 0; i < numguibuts; ++i) { + guibuts[i].WriteToFile(out); + } + out->WriteInt32(numguilabels); + for (int i = 0; i < numguilabels; ++i) { + guilabels[i].WriteToFile(out); + } + out->WriteInt32(numguiinv); + for (int i = 0; i < numguiinv; ++i) { + guiinv[i].WriteToFile(out); + } + out->WriteInt32(numguislider); + for (int i = 0; i < numguislider; ++i) { + guislider[i].WriteToFile(out); + } + out->WriteInt32(numguitext); + for (int i = 0; i < numguitext; ++i) { + guitext[i].WriteToFile(out); + } + out->WriteInt32(numguilist); + for (int i = 0; i < numguilist; ++i) { + guilist[i].WriteToFile(out); + } +} + +void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis) { + // kGUIPopupMouseY had its own rules, which we practically reverted now + if (gui.PopupStyle == kGUIPopupMouseY) { + // it was only !Visible if the legacy Visibility was Concealed + gui.SetVisible(vis != kGUIVisibility_Concealed); + // and you could tell it's overridden by behavior when legacy Visibility is Off + gui.SetConceal(vis == kGUIVisibility_Off); + } + // Other GUI styles were simple + else { + gui.SetVisible(vis != kGUIVisibility_Off); + gui.SetConceal(false); + } } } // namespace GUI diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index 5ec98205dad0..b56f8f28ec33 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -32,7 +32,11 @@ #include "util/string.h" // Forward declaration -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later // There were issues when including header caused conflicts @@ -45,171 +49,166 @@ struct GameSetupStruct; #define GUIMAIN_LEGACY_EVENTHANDLER_LENGTH 20 #define GUIMAIN_LEGACY_TW_FLAGS_SIZE 4 -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // Legacy GUIMain visibility state, which combined Visible property and override factor -enum LegacyGUIVisState -{ - kGUIVisibility_Concealed = -1, // gui is hidden by command - kGUIVisibility_Off = 0, // gui is disabled (won't show up by command) - kGUIVisibility_On = 1 // gui is shown by command +enum LegacyGUIVisState { + kGUIVisibility_Concealed = -1, // gui is hidden by command + kGUIVisibility_Off = 0, // gui is disabled (won't show up by command) + kGUIVisibility_On = 1 // gui is shown by command }; class Bitmap; class GUIObject; -class GUIMain -{ +class GUIMain { public: - static String FixupGUIName(const String &name); + static String FixupGUIName(const String &name); public: - GUIMain(); - - void InitDefaults(); - - // Tells if the gui background supports alpha channel - bool HasAlphaChannel() const; - // Tells if GUI will react on clicking on it - bool IsClickable() const; - // Tells if GUI's visibility is overridden and it won't be displayed on - // screen regardless of Visible property (until concealed mode is off). - bool IsConcealed() const; - // Tells if gui is actually displayed on screen. Normally Visible property - // determines whether GUI is allowed to be seen, but there may be other - // settings that override GUI's visibility. - bool IsDisplayed() const; - // Tells if given coordinates are within interactable area of gui - // NOTE: this currently tests for actual visibility and Clickable property - bool IsInteractableAt(int x, int y) const; - // Tells if gui is a text window - bool IsTextWindow() const; - // Tells if GUI is *allowed* to be displayed and interacted with. - // This does not necessarily mean that it is displayed right now, because - // GUI may be hidden for other reasons, including overriding behavior. - // For example GUI with kGUIPopupMouseY style will not be shown unless - // mouse cursor is at certain position on screen. - bool IsVisible() const; - - int32_t FindControlUnderMouse() const; - // this version allows some extra leeway in the Editor so that - // the user can grab tiny controls - int32_t FindControlUnderMouse(int leeway) const; - int32_t FindControlUnderMouse(int leeway, bool must_be_clickable) const; - // Gets the number of the GUI child controls - int32_t GetControlCount() const; - // Gets control by its child's index - GUIObject *GetControl(int index) const; - // Gets child control's type, looks up with child's index - GUIControlType GetControlType(int index) const; - // Gets child control's global ID, looks up with child's index - int32_t GetControlID(int index) const; - - // Child control management - // Note that currently GUIMain does not own controls (should not delete them) - void AddControl(GUIControlType type, int id, GUIObject *control); - void RemoveAllControls(); - - // Operations - bool BringControlToFront(int index); - void Draw(Bitmap *ds); - void DrawAt(Bitmap *ds, int x, int y); - void Poll(); - HError RebuildArray(); - void ResortZOrder(); - bool SendControlToBack(int index); - // Sets whether GUI should react to player clicking on it - void SetClickable(bool on); - // Override GUI visibility; when in concealed mode GUI won't show up - // even if Visible = true - void SetConceal(bool on); - // Attempts to change control's zorder; returns if zorder changed - bool SetControlZOrder(int index, int zorder); - // Changes GUI style to the text window or back - void SetTextWindow(bool on); - // Sets GUI transparency as a percentage (0 - 100) where 100 = invisible - void SetTransparencyAsPercentage(int percent); - // Sets whether GUI is allowed to be displayed on screen - void SetVisible(bool on); - - // Events - void OnMouseButtonDown(); - void OnMouseButtonUp(); - void OnControlPositionChanged(); - - // Serialization - void ReadFromFile(Stream *in, GuiVersion gui_version); - void WriteToFile(Stream *out) const; - // TODO: move to engine, into gui savegame component unit - // (should read/write GUI properties accessing them by interface) - void ReadFromSavegame(Stream *in, GuiSvgVersion svg_version); - void WriteToSavegame(Stream *out) const; + GUIMain(); + + void InitDefaults(); + + // Tells if the gui background supports alpha channel + bool HasAlphaChannel() const; + // Tells if GUI will react on clicking on it + bool IsClickable() const; + // Tells if GUI's visibility is overridden and it won't be displayed on + // screen regardless of Visible property (until concealed mode is off). + bool IsConcealed() const; + // Tells if gui is actually displayed on screen. Normally Visible property + // determines whether GUI is allowed to be seen, but there may be other + // settings that override GUI's visibility. + bool IsDisplayed() const; + // Tells if given coordinates are within interactable area of gui + // NOTE: this currently tests for actual visibility and Clickable property + bool IsInteractableAt(int x, int y) const; + // Tells if gui is a text window + bool IsTextWindow() const; + // Tells if GUI is *allowed* to be displayed and interacted with. + // This does not necessarily mean that it is displayed right now, because + // GUI may be hidden for other reasons, including overriding behavior. + // For example GUI with kGUIPopupMouseY style will not be shown unless + // mouse cursor is at certain position on screen. + bool IsVisible() const; + + int32_t FindControlUnderMouse() const; + // this version allows some extra leeway in the Editor so that + // the user can grab tiny controls + int32_t FindControlUnderMouse(int leeway) const; + int32_t FindControlUnderMouse(int leeway, bool must_be_clickable) const; + // Gets the number of the GUI child controls + int32_t GetControlCount() const; + // Gets control by its child's index + GUIObject *GetControl(int index) const; + // Gets child control's type, looks up with child's index + GUIControlType GetControlType(int index) const; + // Gets child control's global ID, looks up with child's index + int32_t GetControlID(int index) const; + + // Child control management + // Note that currently GUIMain does not own controls (should not delete them) + void AddControl(GUIControlType type, int id, GUIObject *control); + void RemoveAllControls(); + + // Operations + bool BringControlToFront(int index); + void Draw(Bitmap *ds); + void DrawAt(Bitmap *ds, int x, int y); + void Poll(); + HError RebuildArray(); + void ResortZOrder(); + bool SendControlToBack(int index); + // Sets whether GUI should react to player clicking on it + void SetClickable(bool on); + // Override GUI visibility; when in concealed mode GUI won't show up + // even if Visible = true + void SetConceal(bool on); + // Attempts to change control's zorder; returns if zorder changed + bool SetControlZOrder(int index, int zorder); + // Changes GUI style to the text window or back + void SetTextWindow(bool on); + // Sets GUI transparency as a percentage (0 - 100) where 100 = invisible + void SetTransparencyAsPercentage(int percent); + // Sets whether GUI is allowed to be displayed on screen + void SetVisible(bool on); + + // Events + void OnMouseButtonDown(); + void OnMouseButtonUp(); + void OnControlPositionChanged(); + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version); + void WriteToFile(Stream *out) const; + // TODO: move to engine, into gui savegame component unit + // (should read/write GUI properties accessing them by interface) + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_version); + void WriteToSavegame(Stream *out) const; private: - void DrawBlob(Bitmap *ds, int x, int y, color_t draw_color); + void DrawBlob(Bitmap *ds, int x, int y, color_t draw_color); - // TODO: all members are currently public; hide them later + // TODO: all members are currently public; hide them later public: - int32_t ID; // GUI identifier - String Name; // the name of the GUI - - int32_t X; - int32_t Y; - int32_t Width; - int32_t Height; - color_t BgColor; // background color - int32_t BgImage; // background sprite index - color_t FgColor; // foreground color (used as border color in normal GUIs, - // and text color in text windows) - int32_t Padding; // padding surrounding a GUI text window - GUIPopupStyle PopupStyle; // GUI popup behavior - int32_t PopupAtMouseY; // popup when mousey < this - int32_t Transparency; // "incorrect" alpha (in legacy 255-range units) - int32_t ZOrder; - - int32_t FocusCtrl; // which control has the focus - int32_t HighlightCtrl; // which control has the bounding selection rect - int32_t MouseOverCtrl; // which control has the mouse cursor over it - int32_t MouseDownCtrl; // which control has the mouse button pressed on it - Point MouseWasAt; // last mouse cursor position - - String OnClickHandler; // script function name + int32_t ID; // GUI identifier + String Name; // the name of the GUI + + int32_t X; + int32_t Y; + int32_t Width; + int32_t Height; + color_t BgColor; // background color + int32_t BgImage; // background sprite index + color_t FgColor; // foreground color (used as border color in normal GUIs, + // and text color in text windows) + int32_t Padding; // padding surrounding a GUI text window + GUIPopupStyle PopupStyle; // GUI popup behavior + int32_t PopupAtMouseY; // popup when mousey < this + int32_t Transparency; // "incorrect" alpha (in legacy 255-range units) + int32_t ZOrder; + + int32_t FocusCtrl; // which control has the focus + int32_t HighlightCtrl; // which control has the bounding selection rect + int32_t MouseOverCtrl; // which control has the mouse cursor over it + int32_t MouseDownCtrl; // which control has the mouse button pressed on it + Point MouseWasAt; // last mouse cursor position + + String OnClickHandler; // script function name private: - int32_t _flags; // style and behavior flags - - // Array of types and control indexes in global GUI object arrays; - // maps GUI child slots to actual controls and used for rebuilding Controls array - typedef std::pair ControlRef; - std::vector _ctrlRefs; - // Array of child control references (not exclusively owned!) - std::vector _controls; - // Sorted array of controls in z-order. - std::vector _ctrlDrawOrder; + int32_t _flags; // style and behavior flags + + // Array of types and control indexes in global GUI object arrays; + // maps GUI child slots to actual controls and used for rebuilding Controls array + typedef std::pair ControlRef; + std::vector _ctrlRefs; + // Array of child control references (not exclusively owned!) + std::vector _controls; + // Sorted array of controls in z-order. + std::vector _ctrlDrawOrder; }; -namespace GUI -{ - extern GuiVersion GameGuiVersion; +namespace GUI { +extern GuiVersion GameGuiVersion; - // Draw standart "shading" effect over rectangle - void DrawDisabledEffect(Bitmap *ds, const Rect &rc); - // Draw text aligned inside rectangle - void DrawTextAligned(Bitmap *ds, const char *text, int font, color_t text_color, const Rect &frame, FrameAlignment align); - // Draw text aligned horizontally inside given bounds - void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_color, int x1, int x2, int y, FrameAlignment align); +// Draw standart "shading" effect over rectangle +void DrawDisabledEffect(Bitmap *ds, const Rect &rc); +// Draw text aligned inside rectangle +void DrawTextAligned(Bitmap *ds, const char *text, int font, color_t text_color, const Rect &frame, FrameAlignment align); +// Draw text aligned horizontally inside given bounds +void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_color, int x1, int x2, int y, FrameAlignment align); - // TODO: remove is_savegame param after dropping support for old saves - // because only they use ReadGUI to read runtime GUI data - HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame = false); - void WriteGUI(const std::vector &guis, Stream *out); - // Converts legacy GUIVisibility into appropriate GUIMain properties - void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis); +// TODO: remove is_savegame param after dropping support for old saves +// because only they use ReadGUI to read runtime GUI data +HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame = false); +void WriteGUI(const std::vector &guis, Stream *out); +// Converts legacy GUIVisibility into appropriate GUIMain properties +void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis); } } // namespace Common diff --git a/engines/ags/shared/gui/guiobject.cpp b/engines/ags/shared/gui/guiobject.cpp index 7ec7d4cf20e9..8f278025f14e 100644 --- a/engines/ags/shared/gui/guiobject.cpp +++ b/engines/ags/shared/gui/guiobject.cpp @@ -25,197 +25,173 @@ #include "gui/guiobject.h" #include "util/stream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -GUIObject::GUIObject() -{ - Id = 0; - ParentId = 0; - Flags = kGUICtrl_DefFlags; - X = 0; - Y = 0; - Width = 0; - Height = 0; - ZOrder = -1; - IsActivated = false; - _scEventCount = 0; +GUIObject::GUIObject() { + Id = 0; + ParentId = 0; + Flags = kGUICtrl_DefFlags; + X = 0; + Y = 0; + Width = 0; + Height = 0; + ZOrder = -1; + IsActivated = false; + _scEventCount = 0; } -int GUIObject::GetEventCount() const -{ - return _scEventCount; +int GUIObject::GetEventCount() const { + return _scEventCount; } -String GUIObject::GetEventName(int event) const -{ - if (event < 0 || event >= _scEventCount) - return ""; - return _scEventNames[event]; +String GUIObject::GetEventName(int event) const { + if (event < 0 || event >= _scEventCount) + return ""; + return _scEventNames[event]; } -String GUIObject::GetEventArgs(int event) const -{ - if (event < 0 || event >= _scEventCount) - return ""; - return _scEventArgs[event]; +String GUIObject::GetEventArgs(int event) const { + if (event < 0 || event >= _scEventCount) + return ""; + return _scEventArgs[event]; } -bool GUIObject::IsDeleted() const -{ - return (Flags & kGUICtrl_Deleted) != 0; +bool GUIObject::IsDeleted() const { + return (Flags & kGUICtrl_Deleted) != 0; } -bool GUIObject::IsEnabled() const -{ - return (Flags & kGUICtrl_Enabled) != 0; +bool GUIObject::IsEnabled() const { + return (Flags & kGUICtrl_Enabled) != 0; } -bool GUIObject::IsOverControl(int x, int y, int leeway) const -{ - return x >= X && y >= Y && x < (X + Width + leeway) && y < (Y + Height + leeway); +bool GUIObject::IsOverControl(int x, int y, int leeway) const { + return x >= X && y >= Y && x < (X + Width + leeway) && y < (Y + Height + leeway); } -bool GUIObject::IsTranslated() const -{ - return (Flags & kGUICtrl_Translated) != 0; +bool GUIObject::IsTranslated() const { + return (Flags & kGUICtrl_Translated) != 0; } -bool GUIObject::IsVisible() const -{ - return (Flags & kGUICtrl_Visible) != 0; +bool GUIObject::IsVisible() const { + return (Flags & kGUICtrl_Visible) != 0; } -void GUIObject::SetClickable(bool on) -{ - if (on) - Flags |= kGUICtrl_Clickable; - else - Flags &= ~kGUICtrl_Clickable; +void GUIObject::SetClickable(bool on) { + if (on) + Flags |= kGUICtrl_Clickable; + else + Flags &= ~kGUICtrl_Clickable; } -void GUIObject::SetEnabled(bool on) -{ - if (on) - Flags |= kGUICtrl_Enabled; - else - Flags &= ~kGUICtrl_Enabled; +void GUIObject::SetEnabled(bool on) { + if (on) + Flags |= kGUICtrl_Enabled; + else + Flags &= ~kGUICtrl_Enabled; } -void GUIObject::SetTranslated(bool on) -{ - if (on) - Flags |= kGUICtrl_Translated; - else - Flags &= ~kGUICtrl_Translated; +void GUIObject::SetTranslated(bool on) { + if (on) + Flags |= kGUICtrl_Translated; + else + Flags &= ~kGUICtrl_Translated; } -void GUIObject::SetVisible(bool on) -{ - if (on) - Flags |= kGUICtrl_Visible; - else - Flags &= ~kGUICtrl_Visible; +void GUIObject::SetVisible(bool on) { + if (on) + Flags |= kGUICtrl_Visible; + else + Flags &= ~kGUICtrl_Visible; } // TODO: replace string serialization with StrUtil::ReadString and WriteString // methods in the future, to keep this organized. -void GUIObject::WriteToFile(Stream *out) const -{ - out->WriteInt32(Flags); - out->WriteInt32(X); - out->WriteInt32(Y); - out->WriteInt32(Width); - out->WriteInt32(Height); - out->WriteInt32(ZOrder); - Name.Write(out); - out->WriteInt32(_scEventCount); - for (int i = 0; i < _scEventCount; ++i) - EventHandlers[i].Write(out); -} - -void GUIObject::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - Flags = in->ReadInt32(); - // reverse particular flags from older format - if (gui_version < kGuiVersion_350) - Flags ^= kGUICtrl_OldFmtXorMask; - X = in->ReadInt32(); - Y = in->ReadInt32(); - Width = in->ReadInt32(); - Height = in->ReadInt32(); - ZOrder = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - { // NOTE: reading into actual variables only for old savegame support - IsActivated = in->ReadInt32() != 0; - } - - if (gui_version >= kGuiVersion_unkn_106) - Name.Read(in); - else - Name.Free(); - - for (int i = 0; i < _scEventCount; ++i) - { - EventHandlers[i].Free(); - } - - if (gui_version >= kGuiVersion_unkn_108) - { - int evt_count = in->ReadInt32(); - if (evt_count > _scEventCount) - quit("Error: too many control events, need newer version"); - for (int i = 0; i < evt_count; ++i) - { - EventHandlers[i].Read(in); - } - } -} - -void GUIObject::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) -{ - // Properties - Flags = in->ReadInt32(); - // reverse particular flags from older format - if (svg_ver < kGuiSvgVersion_350) - Flags ^= kGUICtrl_OldFmtXorMask; - X = in->ReadInt32(); - Y = in->ReadInt32(); - Width = in->ReadInt32(); - Height = in->ReadInt32(); - ZOrder = in->ReadInt32(); - // Dynamic state - IsActivated = in->ReadBool() ? 1 : 0; -} - -void GUIObject::WriteToSavegame(Stream *out) const -{ - // Properties - out->WriteInt32(Flags); - out->WriteInt32(X); - out->WriteInt32(Y); - out->WriteInt32(Width); - out->WriteInt32(Height); - out->WriteInt32(ZOrder); - // Dynamic state - out->WriteBool(IsActivated != 0); -} - - -HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align) -{ - switch (align) - { - case kLegacyGUIAlign_Left: - return kHAlignLeft; - case kLegacyGUIAlign_Right: - return kHAlignRight; - case kLegacyGUIAlign_Center: - return kHAlignCenter; - } - return kHAlignNone; +void GUIObject::WriteToFile(Stream *out) const { + out->WriteInt32(Flags); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(ZOrder); + Name.Write(out); + out->WriteInt32(_scEventCount); + for (int i = 0; i < _scEventCount; ++i) + EventHandlers[i].Write(out); +} + +void GUIObject::ReadFromFile(Stream *in, GuiVersion gui_version) { + Flags = in->ReadInt32(); + // reverse particular flags from older format + if (gui_version < kGuiVersion_350) + Flags ^= kGUICtrl_OldFmtXorMask; + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + ZOrder = in->ReadInt32(); + if (gui_version < kGuiVersion_350) { + // NOTE: reading into actual variables only for old savegame support + IsActivated = in->ReadInt32() != 0; + } + + if (gui_version >= kGuiVersion_unkn_106) + Name.Read(in); + else + Name.Free(); + + for (int i = 0; i < _scEventCount; ++i) { + EventHandlers[i].Free(); + } + + if (gui_version >= kGuiVersion_unkn_108) { + int evt_count = in->ReadInt32(); + if (evt_count > _scEventCount) + quit("Error: too many control events, need newer version"); + for (int i = 0; i < evt_count; ++i) { + EventHandlers[i].Read(in); + } + } +} + +void GUIObject::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { + // Properties + Flags = in->ReadInt32(); + // reverse particular flags from older format + if (svg_ver < kGuiSvgVersion_350) + Flags ^= kGUICtrl_OldFmtXorMask; + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + ZOrder = in->ReadInt32(); + // Dynamic state + IsActivated = in->ReadBool() ? 1 : 0; +} + +void GUIObject::WriteToSavegame(Stream *out) const { + // Properties + out->WriteInt32(Flags); + out->WriteInt32(X); + out->WriteInt32(Y); + out->WriteInt32(Width); + out->WriteInt32(Height); + out->WriteInt32(ZOrder); + // Dynamic state + out->WriteBool(IsActivated != 0); +} + + +HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align) { + switch (align) { + case kLegacyGUIAlign_Left: + return kHAlignLeft; + case kLegacyGUIAlign_Right: + return kHAlignRight; + case kLegacyGUIAlign_Center: + return kHAlignCenter; + } + return kHAlignNone; } } // namespace Common diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h index 2768dd9a6662..8f2f5e26202f 100644 --- a/engines/ags/shared/gui/guiobject.h +++ b/engines/ags/shared/gui/guiobject.h @@ -36,88 +36,86 @@ -namespace AGS -{ -namespace Common -{ - -enum LegacyGUIAlignment -{ - kLegacyGUIAlign_Left = 0, - kLegacyGUIAlign_Right = 1, - kLegacyGUIAlign_Center = 2 +namespace AGS { +namespace Common { + +enum LegacyGUIAlignment { + kLegacyGUIAlign_Left = 0, + kLegacyGUIAlign_Right = 1, + kLegacyGUIAlign_Center = 2 }; -class GUIObject -{ +class GUIObject { public: - GUIObject(); - virtual ~GUIObject() = default; - - String GetEventArgs(int event) const; - int GetEventCount() const; - String GetEventName(int event) const; - bool IsDeleted() const; - // tells if control itself is enabled - bool IsEnabled() const; - // overridable routine to determine whether the mouse is over the control - virtual bool IsOverControl(int x, int y, int leeway) const; - bool IsTranslated() const; - bool IsVisible() const; - // implemented separately in engine and editor - bool IsClickable() const; - - // Operations - virtual void Draw(Bitmap *ds) { } - void SetClickable(bool on); - void SetEnabled(bool on); - void SetTranslated(bool on); - void SetVisible(bool on); - - // Events - // Key pressed for control - virtual void OnKeyPress(int keycode) { } - // Mouse button down - return 'True' to lock focus - virtual bool OnMouseDown() { return false; } - // Mouse moves onto control - virtual void OnMouseEnter() { } - // Mouse moves off control - virtual void OnMouseLeave() { } - // Mouse moves over control - x,y relative to gui - virtual void OnMouseMove(int x, int y) { } - // Mouse button up - virtual void OnMouseUp() { } - // Control was resized - virtual void OnResized() { } - - // Serialization - virtual void ReadFromFile(Common::Stream *in, GuiVersion gui_version); - virtual void WriteToFile(Common::Stream *out) const; - virtual void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver); - virtual void WriteToSavegame(Common::Stream *out) const; + GUIObject(); + virtual ~GUIObject() = default; + + String GetEventArgs(int event) const; + int GetEventCount() const; + String GetEventName(int event) const; + bool IsDeleted() const; + // tells if control itself is enabled + bool IsEnabled() const; + // overridable routine to determine whether the mouse is over the control + virtual bool IsOverControl(int x, int y, int leeway) const; + bool IsTranslated() const; + bool IsVisible() const; + // implemented separately in engine and editor + bool IsClickable() const; + + // Operations + virtual void Draw(Bitmap *ds) { } + void SetClickable(bool on); + void SetEnabled(bool on); + void SetTranslated(bool on); + void SetVisible(bool on); + + // Events + // Key pressed for control + virtual void OnKeyPress(int keycode) { } + // Mouse button down - return 'True' to lock focus + virtual bool OnMouseDown() { + return false; + } + // Mouse moves onto control + virtual void OnMouseEnter() { } + // Mouse moves off control + virtual void OnMouseLeave() { } + // Mouse moves over control - x,y relative to gui + virtual void OnMouseMove(int x, int y) { } + // Mouse button up + virtual void OnMouseUp() { } + // Control was resized + virtual void OnResized() { } + + // Serialization + virtual void ReadFromFile(Common::Stream *in, GuiVersion gui_version); + virtual void WriteToFile(Common::Stream *out) const; + virtual void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver); + virtual void WriteToSavegame(Common::Stream *out) const; // TODO: these members are currently public; hide them later public: - int32_t Id; // GUI object's identifier - int32_t ParentId; // id of parent GUI - String Name; // script name - - int32_t X; - int32_t Y; - int32_t Width; - int32_t Height; - int32_t ZOrder; - bool IsActivated; // signals user interaction - - String EventHandlers[MAX_GUIOBJ_EVENTS]; // script function names - + int32_t Id; // GUI object's identifier + int32_t ParentId; // id of parent GUI + String Name; // script name + + int32_t X; + int32_t Y; + int32_t Width; + int32_t Height; + int32_t ZOrder; + bool IsActivated; // signals user interaction + + String EventHandlers[MAX_GUIOBJ_EVENTS]; // script function names + protected: - uint32_t Flags; // generic style and behavior flags + uint32_t Flags; // generic style and behavior flags - // TODO: explicit event names & handlers for every event - int32_t _scEventCount; // number of supported script events - String _scEventNames[MAX_GUIOBJ_EVENTS]; // script event names - String _scEventArgs[MAX_GUIOBJ_EVENTS]; // script handler params + // TODO: explicit event names & handlers for every event + int32_t _scEventCount; // number of supported script events + String _scEventNames[MAX_GUIOBJ_EVENTS]; // script event names + String _scEventArgs[MAX_GUIOBJ_EVENTS]; // script handler params }; // Converts legacy alignment type used in GUI Label/ListBox data (only left/right/center) @@ -129,6 +127,8 @@ HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align); // Tells if all controls are disabled extern int all_buttons_disabled; // Tells if the given control is considered enabled, taking global flag into account -inline bool IsGUIEnabled(AGS::Common::GUIObject *g) { return !all_buttons_disabled && g->IsEnabled(); } +inline bool IsGUIEnabled(AGS::Common::GUIObject *g) { + return !all_buttons_disabled && g->IsEnabled(); +} #endif diff --git a/engines/ags/shared/gui/guislider.cpp b/engines/ags/shared/gui/guislider.cpp index a58864572837..fee93194a268 100644 --- a/engines/ags/shared/gui/guislider.cpp +++ b/engines/ags/shared/gui/guislider.cpp @@ -28,247 +28,216 @@ std::vector guislider; int numguislider = 0; -namespace AGS -{ -namespace Common -{ - -GUISlider::GUISlider() -{ - MinValue = 0; - MaxValue = 10; - Value = 0; - BgImage = 0; - HandleImage = 0; - HandleOffset = 0; - IsMousePressed = false; - - _scEventCount = 1; - _scEventNames[0] = "Change"; - _scEventArgs[0] = "GUIControl *control"; +namespace AGS { +namespace Common { + +GUISlider::GUISlider() { + MinValue = 0; + MaxValue = 10; + Value = 0; + BgImage = 0; + HandleImage = 0; + HandleOffset = 0; + IsMousePressed = false; + + _scEventCount = 1; + _scEventNames[0] = "Change"; + _scEventArgs[0] = "GUIControl *control"; } -bool GUISlider::IsHorizontal() const -{ - return Width > Height; +bool GUISlider::IsHorizontal() const { + return Width > Height; } -bool GUISlider::IsOverControl(int X, int Y, int leeway) const -{ - // check the overall boundary - if (GUIObject::IsOverControl(X, Y, leeway)) - return true; - // now check the handle too - return _cachedHandle.IsInside(Point(X, Y)); +bool GUISlider::IsOverControl(int X, int Y, int leeway) const { + // check the overall boundary + if (GUIObject::IsOverControl(X, Y, leeway)) + return true; + // now check the handle too + return _cachedHandle.IsInside(Point(X, Y)); } -void GUISlider::Draw(Common::Bitmap *ds) -{ - Rect bar; - Rect handle; - int thickness; - - if (MinValue >= MaxValue) - MaxValue = MinValue + 1; - Value = Math::Clamp(Value, MinValue, MaxValue); - - // it's a horizontal slider - if (IsHorizontal()) - { - thickness = Height / 3; - bar.Left = X + 1; - bar.Top = Y + Height / 2 - thickness; - bar.Right = X + Width - 1; - bar.Bottom = Y + Height / 2 + thickness + 1; - handle.Left = (int)(((float)(Value - MinValue) / (float)(MaxValue - MinValue)) * (float)(Width - 4) - 2) + bar.Left + 1; - handle.Top = bar.Top - (thickness - 1); - handle.Right = handle.Left + get_fixed_pixel_size(4); - handle.Bottom = bar.Bottom + (thickness - 1); - if (HandleImage > 0) - { - // store the centre of the pic rather than the top - handle.Top = bar.Top + (bar.Bottom - bar.Top) / 2 + get_fixed_pixel_size(1); - handle.Left += get_fixed_pixel_size(2); - } - handle.Top += data_to_game_coord(HandleOffset); - handle.Bottom += data_to_game_coord(HandleOffset); - } - // vertical slider - else - { - thickness = Width / 3; - bar.Left = X + Width / 2 - thickness; - bar.Top = Y + 1; - bar.Right = X + Width / 2 + thickness + 1; - bar.Bottom = Y + Height - 1; - handle.Top = (int)(((float)(MaxValue - Value) / (float)(MaxValue - MinValue)) * (float)(Height - 4) - 2) + bar.Top + 1; - handle.Left = bar.Left - (thickness - 1); - handle.Bottom = handle.Top + get_fixed_pixel_size(4); - handle.Right = bar.Right + (thickness - 1); - if (HandleImage > 0) - { - // store the centre of the pic rather than the left - handle.Left = bar.Left + (bar.Right - bar.Left) / 2 + get_fixed_pixel_size(1); - handle.Top += get_fixed_pixel_size(2); - } - handle.Left += data_to_game_coord(HandleOffset); - handle.Right += data_to_game_coord(HandleOffset); - } - - color_t draw_color; - if (BgImage > 0) - { - // tiled image as slider background - int x_inc = 0; - int y_inc = 0; - if (IsHorizontal()) - { - x_inc = get_adjusted_spritewidth(BgImage); - // centre the image vertically - bar.Top = Y + (Height / 2) - get_adjusted_spriteheight(BgImage) / 2; - } - else - { - y_inc = get_adjusted_spriteheight(BgImage); - // centre the image horizontally - bar.Left = X + (Width / 2) - get_adjusted_spritewidth(BgImage) / 2; - } - int cx = bar.Left; - int cy = bar.Top; - // draw the tiled background image - do - { - draw_gui_sprite(ds, BgImage, cx, cy, true); - cx += x_inc; - cy += y_inc; - // done as a do..while so that at least one of the image is drawn - } - while ((cx + x_inc <= bar.Right) && (cy + y_inc <= bar.Bottom)); - } - else - { - // normal grey background - draw_color = ds->GetCompatibleColor(16); - ds->FillRect(Rect(bar.Left + 1, bar.Top + 1, bar.Right - 1, bar.Bottom - 1), draw_color); - draw_color = ds->GetCompatibleColor(8); - ds->DrawLine(Line(bar.Left, bar.Top, bar.Left, bar.Bottom), draw_color); - ds->DrawLine(Line(bar.Left, bar.Top, bar.Right, bar.Top), draw_color); - draw_color = ds->GetCompatibleColor(15); - ds->DrawLine(Line(bar.Right, bar.Top + 1, bar.Right, bar.Bottom), draw_color); - ds->DrawLine(Line(bar.Left, bar.Bottom, bar.Right, bar.Bottom), draw_color); - } - - if (HandleImage > 0) - { - // an image for the slider handle - // TODO: react to sprites initialization/deletion instead! - if (spriteset[HandleImage] == nullptr) - HandleImage = 0; - - handle.Left -= get_adjusted_spritewidth(HandleImage) / 2; - handle.Top -= get_adjusted_spriteheight(HandleImage) / 2; - draw_gui_sprite(ds, HandleImage, handle.Left, handle.Top, true); - handle.Right = handle.Left + get_adjusted_spritewidth(HandleImage); - handle.Bottom = handle.Top + get_adjusted_spriteheight(HandleImage); - } - else - { - // normal grey tracker handle - draw_color = ds->GetCompatibleColor(7); - ds->FillRect(Rect(handle.Left, handle.Top, handle.Right, handle.Bottom), draw_color); - draw_color = ds->GetCompatibleColor(15); - ds->DrawLine(Line(handle.Left, handle.Top, handle.Right, handle.Top), draw_color); - ds->DrawLine(Line(handle.Left, handle.Top, handle.Left, handle.Bottom), draw_color); - draw_color = ds->GetCompatibleColor(16); - ds->DrawLine(Line(handle.Right, handle.Top + 1, handle.Right, handle.Bottom), draw_color); - ds->DrawLine(Line(handle.Left + 1, handle.Bottom, handle.Right, handle.Bottom), draw_color); - } - - _cachedHandle = handle; +void GUISlider::Draw(Common::Bitmap *ds) { + Rect bar; + Rect handle; + int thickness; + + if (MinValue >= MaxValue) + MaxValue = MinValue + 1; + Value = Math::Clamp(Value, MinValue, MaxValue); + + // it's a horizontal slider + if (IsHorizontal()) { + thickness = Height / 3; + bar.Left = X + 1; + bar.Top = Y + Height / 2 - thickness; + bar.Right = X + Width - 1; + bar.Bottom = Y + Height / 2 + thickness + 1; + handle.Left = (int)(((float)(Value - MinValue) / (float)(MaxValue - MinValue)) * (float)(Width - 4) - 2) + bar.Left + 1; + handle.Top = bar.Top - (thickness - 1); + handle.Right = handle.Left + get_fixed_pixel_size(4); + handle.Bottom = bar.Bottom + (thickness - 1); + if (HandleImage > 0) { + // store the centre of the pic rather than the top + handle.Top = bar.Top + (bar.Bottom - bar.Top) / 2 + get_fixed_pixel_size(1); + handle.Left += get_fixed_pixel_size(2); + } + handle.Top += data_to_game_coord(HandleOffset); + handle.Bottom += data_to_game_coord(HandleOffset); + } + // vertical slider + else { + thickness = Width / 3; + bar.Left = X + Width / 2 - thickness; + bar.Top = Y + 1; + bar.Right = X + Width / 2 + thickness + 1; + bar.Bottom = Y + Height - 1; + handle.Top = (int)(((float)(MaxValue - Value) / (float)(MaxValue - MinValue)) * (float)(Height - 4) - 2) + bar.Top + 1; + handle.Left = bar.Left - (thickness - 1); + handle.Bottom = handle.Top + get_fixed_pixel_size(4); + handle.Right = bar.Right + (thickness - 1); + if (HandleImage > 0) { + // store the centre of the pic rather than the left + handle.Left = bar.Left + (bar.Right - bar.Left) / 2 + get_fixed_pixel_size(1); + handle.Top += get_fixed_pixel_size(2); + } + handle.Left += data_to_game_coord(HandleOffset); + handle.Right += data_to_game_coord(HandleOffset); + } + + color_t draw_color; + if (BgImage > 0) { + // tiled image as slider background + int x_inc = 0; + int y_inc = 0; + if (IsHorizontal()) { + x_inc = get_adjusted_spritewidth(BgImage); + // centre the image vertically + bar.Top = Y + (Height / 2) - get_adjusted_spriteheight(BgImage) / 2; + } else { + y_inc = get_adjusted_spriteheight(BgImage); + // centre the image horizontally + bar.Left = X + (Width / 2) - get_adjusted_spritewidth(BgImage) / 2; + } + int cx = bar.Left; + int cy = bar.Top; + // draw the tiled background image + do { + draw_gui_sprite(ds, BgImage, cx, cy, true); + cx += x_inc; + cy += y_inc; + // done as a do..while so that at least one of the image is drawn + } while ((cx + x_inc <= bar.Right) && (cy + y_inc <= bar.Bottom)); + } else { + // normal grey background + draw_color = ds->GetCompatibleColor(16); + ds->FillRect(Rect(bar.Left + 1, bar.Top + 1, bar.Right - 1, bar.Bottom - 1), draw_color); + draw_color = ds->GetCompatibleColor(8); + ds->DrawLine(Line(bar.Left, bar.Top, bar.Left, bar.Bottom), draw_color); + ds->DrawLine(Line(bar.Left, bar.Top, bar.Right, bar.Top), draw_color); + draw_color = ds->GetCompatibleColor(15); + ds->DrawLine(Line(bar.Right, bar.Top + 1, bar.Right, bar.Bottom), draw_color); + ds->DrawLine(Line(bar.Left, bar.Bottom, bar.Right, bar.Bottom), draw_color); + } + + if (HandleImage > 0) { + // an image for the slider handle + // TODO: react to sprites initialization/deletion instead! + if (spriteset[HandleImage] == nullptr) + HandleImage = 0; + + handle.Left -= get_adjusted_spritewidth(HandleImage) / 2; + handle.Top -= get_adjusted_spriteheight(HandleImage) / 2; + draw_gui_sprite(ds, HandleImage, handle.Left, handle.Top, true); + handle.Right = handle.Left + get_adjusted_spritewidth(HandleImage); + handle.Bottom = handle.Top + get_adjusted_spriteheight(HandleImage); + } else { + // normal grey tracker handle + draw_color = ds->GetCompatibleColor(7); + ds->FillRect(Rect(handle.Left, handle.Top, handle.Right, handle.Bottom), draw_color); + draw_color = ds->GetCompatibleColor(15); + ds->DrawLine(Line(handle.Left, handle.Top, handle.Right, handle.Top), draw_color); + ds->DrawLine(Line(handle.Left, handle.Top, handle.Left, handle.Bottom), draw_color); + draw_color = ds->GetCompatibleColor(16); + ds->DrawLine(Line(handle.Right, handle.Top + 1, handle.Right, handle.Bottom), draw_color); + ds->DrawLine(Line(handle.Left + 1, handle.Bottom, handle.Right, handle.Bottom), draw_color); + } + + _cachedHandle = handle; } -bool GUISlider::OnMouseDown() -{ - IsMousePressed = true; - // lock focus to ourselves - return true; +bool GUISlider::OnMouseDown() { + IsMousePressed = true; + // lock focus to ourselves + return true; } -void GUISlider::OnMouseMove(int x, int y) -{ - if (!IsMousePressed) - return; +void GUISlider::OnMouseMove(int x, int y) { + if (!IsMousePressed) + return; - if (IsHorizontal()) - Value = (int)(((float)((x - X) - 2) / (float)(Width - 4)) * (float)(MaxValue - MinValue)) + MinValue; - else - Value = (int)(((float)(((Y + Height) - y) - 2) / (float)(Height - 4)) * (float)(MaxValue - MinValue)) + MinValue; + if (IsHorizontal()) + Value = (int)(((float)((x - X) - 2) / (float)(Width - 4)) * (float)(MaxValue - MinValue)) + MinValue; + else + Value = (int)(((float)(((Y + Height) - y) - 2) / (float)(Height - 4)) * (float)(MaxValue - MinValue)) + MinValue; - Value = Math::Clamp(Value, MinValue, MaxValue); - guis_need_update = 1; - IsActivated = true; + Value = Math::Clamp(Value, MinValue, MaxValue); + guis_need_update = 1; + IsActivated = true; } -void GUISlider::OnMouseUp() -{ - IsMousePressed = false; +void GUISlider::OnMouseUp() { + IsMousePressed = false; } -void GUISlider::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - GUIObject::ReadFromFile(in, gui_version); - MinValue = in->ReadInt32(); - MaxValue = in->ReadInt32(); - Value = in->ReadInt32(); - if (gui_version < kGuiVersion_350) - { // NOTE: reading into actual variables only for old savegame support - IsMousePressed = in->ReadInt32() != 0; - } - if (gui_version >= kGuiVersion_unkn_104) - { - HandleImage = in->ReadInt32(); - HandleOffset = in->ReadInt32(); - BgImage = in->ReadInt32(); - } - else - { - HandleImage = -1; - HandleOffset = 0; - BgImage = 0; - } +void GUISlider::ReadFromFile(Stream *in, GuiVersion gui_version) { + GUIObject::ReadFromFile(in, gui_version); + MinValue = in->ReadInt32(); + MaxValue = in->ReadInt32(); + Value = in->ReadInt32(); + if (gui_version < kGuiVersion_350) { + // NOTE: reading into actual variables only for old savegame support + IsMousePressed = in->ReadInt32() != 0; + } + if (gui_version >= kGuiVersion_unkn_104) { + HandleImage = in->ReadInt32(); + HandleOffset = in->ReadInt32(); + BgImage = in->ReadInt32(); + } else { + HandleImage = -1; + HandleOffset = 0; + BgImage = 0; + } } -void GUISlider::WriteToFile(Stream *out) const -{ - GUIObject::WriteToFile(out); - out->WriteInt32(MinValue); - out->WriteInt32(MaxValue); - out->WriteInt32(Value); - out->WriteInt32(HandleImage); - out->WriteInt32(HandleOffset); - out->WriteInt32(BgImage); +void GUISlider::WriteToFile(Stream *out) const { + GUIObject::WriteToFile(out); + out->WriteInt32(MinValue); + out->WriteInt32(MaxValue); + out->WriteInt32(Value); + out->WriteInt32(HandleImage); + out->WriteInt32(HandleOffset); + out->WriteInt32(BgImage); } -void GUISlider::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) -{ - GUIObject::ReadFromSavegame(in, svg_ver); - BgImage = in->ReadInt32(); - HandleImage = in->ReadInt32(); - HandleOffset = in->ReadInt32(); - MinValue = in->ReadInt32(); - MaxValue = in->ReadInt32(); - Value = in->ReadInt32(); +void GUISlider::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { + GUIObject::ReadFromSavegame(in, svg_ver); + BgImage = in->ReadInt32(); + HandleImage = in->ReadInt32(); + HandleOffset = in->ReadInt32(); + MinValue = in->ReadInt32(); + MaxValue = in->ReadInt32(); + Value = in->ReadInt32(); } -void GUISlider::WriteToSavegame(Stream *out) const -{ - GUIObject::WriteToSavegame(out); - out->WriteInt32(BgImage); - out->WriteInt32(HandleImage); - out->WriteInt32(HandleOffset); - out->WriteInt32(MinValue); - out->WriteInt32(MaxValue); - out->WriteInt32(Value); +void GUISlider::WriteToSavegame(Stream *out) const { + GUIObject::WriteToSavegame(out); + out->WriteInt32(BgImage); + out->WriteInt32(HandleImage); + out->WriteInt32(HandleOffset); + out->WriteInt32(MinValue); + out->WriteInt32(MaxValue); + out->WriteInt32(Value); } } // namespace Common diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index c5dd69c6b0c4..95b5721af9e6 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -26,48 +26,45 @@ #include #include "gui/guiobject.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class GUISlider : public GUIObject -{ +class GUISlider : public GUIObject { public: - GUISlider(); + GUISlider(); - // Tells if the slider is horizontal (otherwise - vertical) - bool IsHorizontal() const; - bool IsOverControl(int x, int y, int leeway) const override; + // Tells if the slider is horizontal (otherwise - vertical) + bool IsHorizontal() const; + bool IsOverControl(int x, int y, int leeway) const override; - // Operations - void Draw(Bitmap *ds) override; + // Operations + void Draw(Bitmap *ds) override; - // Events - bool OnMouseDown() override; - void OnMouseMove(int xp, int yp) override; - void OnMouseUp() override; + // Events + bool OnMouseDown() override; + void OnMouseMove(int xp, int yp) override; + void OnMouseUp() override; - // Serialization - void ReadFromFile(Stream *in, GuiVersion gui_version) override; - void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Stream *out) const override; + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; // TODO: these members are currently public; hide them later public: - int32_t MinValue; - int32_t MaxValue; - int32_t Value; - int32_t BgImage; - int32_t HandleImage; - int32_t HandleOffset; - bool IsMousePressed; + int32_t MinValue; + int32_t MaxValue; + int32_t Value; + int32_t BgImage; + int32_t HandleImage; + int32_t HandleOffset; + bool IsMousePressed; private: - // The following variables are not persisted on disk - // Cached coordinates of slider handle - Rect _cachedHandle; + // The following variables are not persisted on disk + // Cached coordinates of slider handle + Rect _cachedHandle; }; } // namespace Common diff --git a/engines/ags/shared/gui/guitextbox.cpp b/engines/ags/shared/gui/guitextbox.cpp index 1fae191f3c3f..307ce31bd94e 100644 --- a/engines/ags/shared/gui/guitextbox.cpp +++ b/engines/ags/shared/gui/guitextbox.cpp @@ -31,123 +31,108 @@ std::vector guitext; int numguitext = 0; -namespace AGS -{ -namespace Common -{ - -GUITextBox::GUITextBox() -{ - Font = 0; - TextColor = 0; - TextBoxFlags = kTextBox_DefFlags; - - _scEventCount = 1; - _scEventNames[0] = "Activate"; - _scEventArgs[0] = "GUIControl *control"; +namespace AGS { +namespace Common { + +GUITextBox::GUITextBox() { + Font = 0; + TextColor = 0; + TextBoxFlags = kTextBox_DefFlags; + + _scEventCount = 1; + _scEventNames[0] = "Activate"; + _scEventArgs[0] = "GUIControl *control"; } -bool GUITextBox::IsBorderShown() const -{ - return (TextBoxFlags & kTextBox_ShowBorder) != 0; +bool GUITextBox::IsBorderShown() const { + return (TextBoxFlags & kTextBox_ShowBorder) != 0; } -void GUITextBox::Draw(Bitmap *ds) -{ - check_font(&Font); - color_t text_color = ds->GetCompatibleColor(TextColor); - color_t draw_color = ds->GetCompatibleColor(TextColor); - if (IsBorderShown()) - { - ds->DrawRect(RectWH(X, Y, Width, Height), draw_color); - if (get_fixed_pixel_size(1) > 1) - { - ds->DrawRect(Rect(X + 1, Y + 1, X + Width - get_fixed_pixel_size(1), Y + Height - get_fixed_pixel_size(1)), draw_color); - } - } - DrawTextBoxContents(ds, text_color); +void GUITextBox::Draw(Bitmap *ds) { + check_font(&Font); + color_t text_color = ds->GetCompatibleColor(TextColor); + color_t draw_color = ds->GetCompatibleColor(TextColor); + if (IsBorderShown()) { + ds->DrawRect(RectWH(X, Y, Width, Height), draw_color); + if (get_fixed_pixel_size(1) > 1) { + ds->DrawRect(Rect(X + 1, Y + 1, X + Width - get_fixed_pixel_size(1), Y + Height - get_fixed_pixel_size(1)), draw_color); + } + } + DrawTextBoxContents(ds, text_color); } -void GUITextBox::OnKeyPress(int keycode) -{ - guis_need_update = 1; - // TODO: use keycode constants - // backspace, remove character - if (keycode == 8) - { - Text.ClipRight(1); - return; - } - // other key, continue - if ((keycode >= 128) && (!font_supports_extended_characters(Font))) - return; - // return/enter - if (keycode == 13) - { - IsActivated = true; - return; - } - - Text.AppendChar(keycode); - // if the new string is too long, remove the new character - if (wgettextwidth(Text, Font) > (Width - (6 + get_fixed_pixel_size(5)))) - Text.ClipRight(1); +void GUITextBox::OnKeyPress(int keycode) { + guis_need_update = 1; + // TODO: use keycode constants + // backspace, remove character + if (keycode == 8) { + Text.ClipRight(1); + return; + } + // other key, continue + if ((keycode >= 128) && (!font_supports_extended_characters(Font))) + return; + // return/enter + if (keycode == 13) { + IsActivated = true; + return; + } + + Text.AppendChar(keycode); + // if the new string is too long, remove the new character + if (wgettextwidth(Text, Font) > (Width - (6 + get_fixed_pixel_size(5)))) + Text.ClipRight(1); } -void GUITextBox::SetShowBorder(bool on) -{ - if (on) - TextBoxFlags |= kTextBox_ShowBorder; - else - TextBoxFlags &= ~kTextBox_ShowBorder; +void GUITextBox::SetShowBorder(bool on) { + if (on) + TextBoxFlags |= kTextBox_ShowBorder; + else + TextBoxFlags &= ~kTextBox_ShowBorder; } // TODO: replace string serialization with StrUtil::ReadString and WriteString // methods in the future, to keep this organized. -void GUITextBox::WriteToFile(Stream *out) const -{ - GUIObject::WriteToFile(out); - StrUtil::WriteString(Text, out); - out->WriteInt32(Font); - out->WriteInt32(TextColor); - out->WriteInt32(TextBoxFlags); +void GUITextBox::WriteToFile(Stream *out) const { + GUIObject::WriteToFile(out); + StrUtil::WriteString(Text, out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + out->WriteInt32(TextBoxFlags); } -void GUITextBox::ReadFromFile(Stream *in, GuiVersion gui_version) -{ - GUIObject::ReadFromFile(in, gui_version); - if (gui_version < kGuiVersion_350) - Text.ReadCount(in, GUITEXTBOX_LEGACY_TEXTLEN); - else - Text = StrUtil::ReadString(in); - Font = in->ReadInt32(); - TextColor = in->ReadInt32(); - TextBoxFlags = in->ReadInt32(); - // reverse particular flags from older format - if (gui_version < kGuiVersion_350) - TextBoxFlags ^= kTextBox_OldFmtXorMask; - - if (TextColor == 0) - TextColor = 16; +void GUITextBox::ReadFromFile(Stream *in, GuiVersion gui_version) { + GUIObject::ReadFromFile(in, gui_version); + if (gui_version < kGuiVersion_350) + Text.ReadCount(in, GUITEXTBOX_LEGACY_TEXTLEN); + else + Text = StrUtil::ReadString(in); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + TextBoxFlags = in->ReadInt32(); + // reverse particular flags from older format + if (gui_version < kGuiVersion_350) + TextBoxFlags ^= kTextBox_OldFmtXorMask; + + if (TextColor == 0) + TextColor = 16; } -void GUITextBox::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) -{ - GUIObject::ReadFromSavegame(in, svg_ver); - Font = in->ReadInt32(); - TextColor = in->ReadInt32(); - Text = StrUtil::ReadString(in); - if (svg_ver >= kGuiSvgVersion_350) - TextBoxFlags = in->ReadInt32(); +void GUITextBox::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { + GUIObject::ReadFromSavegame(in, svg_ver); + Font = in->ReadInt32(); + TextColor = in->ReadInt32(); + Text = StrUtil::ReadString(in); + if (svg_ver >= kGuiSvgVersion_350) + TextBoxFlags = in->ReadInt32(); } -void GUITextBox::WriteToSavegame(Stream *out) const -{ - GUIObject::WriteToSavegame(out); - out->WriteInt32(Font); - out->WriteInt32(TextColor); - StrUtil::WriteString(Text, out); - out->WriteInt32(TextBoxFlags); +void GUITextBox::WriteToSavegame(Stream *out) const { + GUIObject::WriteToSavegame(out); + out->WriteInt32(Font); + out->WriteInt32(TextColor); + StrUtil::WriteString(Text, out); + out->WriteInt32(TextBoxFlags); } } // namespace Common diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index 0617e8c35853..d78b44787ca8 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -27,41 +27,38 @@ #include "gui/guiobject.h" #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class GUITextBox : public GUIObject -{ +class GUITextBox : public GUIObject { public: - GUITextBox(); + GUITextBox(); - bool IsBorderShown() const; + bool IsBorderShown() const; + + // Operations + void Draw(Bitmap *ds) override; + void SetShowBorder(bool on); + + // Events + void OnKeyPress(int keycode) override; + + // Serialization + void ReadFromFile(Stream *in, GuiVersion gui_version) override; + void WriteToFile(Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; - // Operations - void Draw(Bitmap *ds) override; - void SetShowBorder(bool on); - - // Events - void OnKeyPress(int keycode) override; - - // Serialization - void ReadFromFile(Stream *in, GuiVersion gui_version) override; - void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Stream *out) const override; - // TODO: these members are currently public; hide them later public: - int32_t Font; - String Text; - color_t TextColor; + int32_t Font; + String Text; + color_t TextColor; private: - int32_t TextBoxFlags; + int32_t TextBoxFlags; - void DrawTextBoxContents(Bitmap *ds, color_t text_color); + void DrawTextBoxContents(Bitmap *ds, color_t text_color); }; } // namespace Common diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp index 23c511cce67e..71f328df98cd 100644 --- a/engines/ags/shared/script/cc_error.cpp +++ b/engines/ags/shared/script/cc_error.cpp @@ -39,33 +39,28 @@ String ccErrorCallStack; bool ccErrorIsUserError = false; const char *ccCurScriptName = ""; -void cc_error(const char *descr, ...) -{ - ccErrorIsUserError = false; - if (descr[0] == '!') - { - ccErrorIsUserError = true; - descr++; - } +void cc_error(const char *descr, ...) { + ccErrorIsUserError = false; + if (descr[0] == '!') { + ccErrorIsUserError = true; + descr++; + } - va_list ap; - va_start(ap, descr); - String displbuf = String::FromFormatV(descr, ap); - va_end(ap); + va_list ap; + va_start(ap, descr); + String displbuf = String::FromFormatV(descr, ap); + va_end(ap); - if (currentline > 0) - { - // [IKM] Implementation is project-specific - std::pair errinfo = cc_error_at_line(displbuf); - ccErrorString = errinfo.first; - ccErrorCallStack = errinfo.second; - } - else - { - ccErrorString = cc_error_without_line(displbuf); - ccErrorCallStack = ""; - } + if (currentline > 0) { + // [IKM] Implementation is project-specific + std::pair errinfo = cc_error_at_line(displbuf); + ccErrorString = errinfo.first; + ccErrorCallStack = errinfo.second; + } else { + ccErrorString = cc_error_without_line(displbuf); + ccErrorCallStack = ""; + } - ccError = 1; - ccErrorLine = currentline; + ccError = 1; + ccErrorLine = currentline; } diff --git a/engines/ags/shared/script/cc_options.cpp b/engines/ags/shared/script/cc_options.cpp index f56579d4bf33..6bb3c610e343 100644 --- a/engines/ags/shared/script/cc_options.cpp +++ b/engines/ags/shared/script/cc_options.cpp @@ -24,18 +24,16 @@ int ccCompOptions = SCOPT_LEFTTORIGHT; -void ccSetOption(int optbit, int onoroff) -{ - if (onoroff) - ccCompOptions |= optbit; - else - ccCompOptions &= ~optbit; +void ccSetOption(int optbit, int onoroff) { + if (onoroff) + ccCompOptions |= optbit; + else + ccCompOptions &= ~optbit; } -int ccGetOption(int optbit) -{ - if (ccCompOptions & optbit) - return 1; +int ccGetOption(int optbit) { + if (ccCompOptions & optbit) + return 1; - return 0; + return 0; } diff --git a/engines/ags/shared/script/cc_script.cpp b/engines/ags/shared/script/cc_script.cpp index cf405d3e47c2..bd5c5b81f853 100644 --- a/engines/ags/shared/script/cc_script.cpp +++ b/engines/ags/shared/script/cc_script.cpp @@ -36,377 +36,337 @@ int currentline; const char scfilesig[5] = "SCOM"; // [IKM] I reckon this function is almost identical to fgetstring in string_utils -void freadstring(char **strptr, Stream *in) -{ - static char ibuffer[300]; - int idxx = 0; +void freadstring(char **strptr, Stream *in) { + static char ibuffer[300]; + int idxx = 0; - while ((ibuffer[idxx] = in->ReadInt8()) != 0) - idxx++; + while ((ibuffer[idxx] = in->ReadInt8()) != 0) + idxx++; - if (ibuffer[0] == 0) { - strptr[0] = nullptr; - return; - } + if (ibuffer[0] == 0) { + strptr[0] = nullptr; + return; + } - strptr[0] = (char *)malloc(strlen(ibuffer) + 1); - strcpy(strptr[0], ibuffer); + strptr[0] = (char *)malloc(strlen(ibuffer) + 1); + strcpy(strptr[0], ibuffer); } -void fwritestring(const char *strptr, Stream *out) -{ - if(strptr == nullptr){ - out->WriteByte(0); - } else { - out->Write(strptr, strlen(strptr) + 1); - } +void fwritestring(const char *strptr, Stream *out) { + if (strptr == nullptr) { + out->WriteByte(0); + } else { + out->Write(strptr, strlen(strptr) + 1); + } } -ccScript *ccScript::CreateFromStream(Stream *in) -{ - ccScript *scri = new ccScript(); - if (!scri->Read(in)) - { - delete scri; - return nullptr; - } - return scri; +ccScript *ccScript::CreateFromStream(Stream *in) { + ccScript *scri = new ccScript(); + if (!scri->Read(in)) { + delete scri; + return nullptr; + } + return scri; } -ccScript::ccScript() -{ - globaldata = nullptr; - globaldatasize = 0; - code = nullptr; - codesize = 0; - strings = nullptr; - stringssize = 0; - fixuptypes = nullptr; - fixups = nullptr; - numfixups = 0; - importsCapacity = 0; - imports = nullptr; - numimports = 0; - exportsCapacity = 0; - exports = nullptr; - export_addr = nullptr; - numexports = 0; - instances = 0; - sectionNames = nullptr; - sectionOffsets = nullptr; - numSections = 0; - capacitySections = 0; +ccScript::ccScript() { + globaldata = nullptr; + globaldatasize = 0; + code = nullptr; + codesize = 0; + strings = nullptr; + stringssize = 0; + fixuptypes = nullptr; + fixups = nullptr; + numfixups = 0; + importsCapacity = 0; + imports = nullptr; + numimports = 0; + exportsCapacity = 0; + exports = nullptr; + export_addr = nullptr; + numexports = 0; + instances = 0; + sectionNames = nullptr; + sectionOffsets = nullptr; + numSections = 0; + capacitySections = 0; } -ccScript::ccScript(const ccScript &src) -{ - globaldatasize = src.globaldatasize; - if (globaldatasize > 0) - { - globaldata = (char*)malloc(globaldatasize); - memcpy(globaldata, src.globaldata, globaldatasize); - } - else - { - globaldata = nullptr; - } - - codesize = src.codesize; - if (codesize > 0) - { - code = (int32_t*)malloc(codesize * sizeof(int32_t)); - memcpy(code, src.code, sizeof(int32_t) * codesize); - } - else - { - code = nullptr; - } - - stringssize = src.stringssize; - if (stringssize > 0) - { - strings = (char*)malloc(stringssize); - memcpy(strings, src.strings, stringssize); - } - else - { - strings = nullptr; - } - - numfixups = src.numfixups; - if (numfixups > 0) - { - fixuptypes = (char*)malloc(numfixups); - fixups = (int32_t*)malloc(numfixups * sizeof(int32_t)); - memcpy(fixuptypes, src.fixuptypes, numfixups); - memcpy(fixups, src.fixups, numfixups * sizeof(int32_t)); - } - else - { - fixups = nullptr; - fixuptypes = nullptr; - } - - importsCapacity = src.numimports; - numimports = src.numimports; - if (numimports > 0) - { - imports = (char**)malloc(sizeof(char*) * numimports); - for (int i = 0; i < numimports; ++i) - imports[i] = ags_strdup(src.imports[i]); - } - else - { - imports = nullptr; - } - - exportsCapacity = src.numexports; - numexports = src.numexports; - if (numexports > 0) - { - exports = (char**)malloc(sizeof(char*) * numexports); - export_addr = (int32_t*)malloc(sizeof(int32_t) * numexports); - for (int i = 0; i < numexports; ++i) - { - exports[i] = ags_strdup(src.exports[i]); - export_addr[i] = src.export_addr[i]; - } - } - else - { - exports = nullptr; - export_addr = nullptr; - } - - capacitySections = src.numSections; - numSections = src.numSections; - if (numSections > 0) - { - sectionNames = (char**)malloc(numSections * sizeof(char*)); - sectionOffsets = (int32_t*)malloc(numSections * sizeof(int32_t)); - for (int i = 0; i < numSections; ++i) - { - sectionNames[i] = ags_strdup(src.sectionNames[i]); - sectionOffsets[i] = src.sectionOffsets[i]; - } - } - else - { - numSections = 0; - sectionNames = nullptr; - sectionOffsets = nullptr; - } - - instances = 0; +ccScript::ccScript(const ccScript &src) { + globaldatasize = src.globaldatasize; + if (globaldatasize > 0) { + globaldata = (char *)malloc(globaldatasize); + memcpy(globaldata, src.globaldata, globaldatasize); + } else { + globaldata = nullptr; + } + + codesize = src.codesize; + if (codesize > 0) { + code = (int32_t *)malloc(codesize * sizeof(int32_t)); + memcpy(code, src.code, sizeof(int32_t) * codesize); + } else { + code = nullptr; + } + + stringssize = src.stringssize; + if (stringssize > 0) { + strings = (char *)malloc(stringssize); + memcpy(strings, src.strings, stringssize); + } else { + strings = nullptr; + } + + numfixups = src.numfixups; + if (numfixups > 0) { + fixuptypes = (char *)malloc(numfixups); + fixups = (int32_t *)malloc(numfixups * sizeof(int32_t)); + memcpy(fixuptypes, src.fixuptypes, numfixups); + memcpy(fixups, src.fixups, numfixups * sizeof(int32_t)); + } else { + fixups = nullptr; + fixuptypes = nullptr; + } + + importsCapacity = src.numimports; + numimports = src.numimports; + if (numimports > 0) { + imports = (char **)malloc(sizeof(char *) * numimports); + for (int i = 0; i < numimports; ++i) + imports[i] = ags_strdup(src.imports[i]); + } else { + imports = nullptr; + } + + exportsCapacity = src.numexports; + numexports = src.numexports; + if (numexports > 0) { + exports = (char **)malloc(sizeof(char *) * numexports); + export_addr = (int32_t *)malloc(sizeof(int32_t) * numexports); + for (int i = 0; i < numexports; ++i) { + exports[i] = ags_strdup(src.exports[i]); + export_addr[i] = src.export_addr[i]; + } + } else { + exports = nullptr; + export_addr = nullptr; + } + + capacitySections = src.numSections; + numSections = src.numSections; + if (numSections > 0) { + sectionNames = (char **)malloc(numSections * sizeof(char *)); + sectionOffsets = (int32_t *)malloc(numSections * sizeof(int32_t)); + for (int i = 0; i < numSections; ++i) { + sectionNames[i] = ags_strdup(src.sectionNames[i]); + sectionOffsets[i] = src.sectionOffsets[i]; + } + } else { + numSections = 0; + sectionNames = nullptr; + sectionOffsets = nullptr; + } + + instances = 0; } -ccScript::~ccScript() -{ - Free(); +ccScript::~ccScript() { + Free(); } void ccScript::Write(Stream *out) { - int n; - out->Write(scfilesig,4); - out->WriteInt32(SCOM_VERSION); - out->WriteInt32(globaldatasize); - out->WriteInt32(codesize); - out->WriteInt32(stringssize); - if (globaldatasize > 0) - out->WriteArray(globaldata,globaldatasize,1); - if (codesize > 0) - out->WriteArrayOfInt32(code,codesize); - if (stringssize > 0) - out->WriteArray(strings,stringssize,1); - out->WriteInt32(numfixups); - if (numfixups > 0) { - out->WriteArray(fixuptypes,numfixups,1); - out->WriteArrayOfInt32(fixups,numfixups); - } - out->WriteInt32(numimports); - for (n=0;nWriteInt32(numexports); - for (n=0;nWriteInt32(export_addr[n]); - } - out->WriteInt32(numSections); - for (n = 0; n < numSections; n++) { - fwritestring(sectionNames[n], out); - out->WriteInt32(sectionOffsets[n]); - } - out->WriteInt32(ENDFILESIG); + int n; + out->Write(scfilesig, 4); + out->WriteInt32(SCOM_VERSION); + out->WriteInt32(globaldatasize); + out->WriteInt32(codesize); + out->WriteInt32(stringssize); + if (globaldatasize > 0) + out->WriteArray(globaldata, globaldatasize, 1); + if (codesize > 0) + out->WriteArrayOfInt32(code, codesize); + if (stringssize > 0) + out->WriteArray(strings, stringssize, 1); + out->WriteInt32(numfixups); + if (numfixups > 0) { + out->WriteArray(fixuptypes, numfixups, 1); + out->WriteArrayOfInt32(fixups, numfixups); + } + out->WriteInt32(numimports); + for (n = 0; n < numimports; n++) + fwritestring(imports[n], out); + out->WriteInt32(numexports); + for (n = 0; n < numexports; n++) { + fwritestring(exports[n], out); + out->WriteInt32(export_addr[n]); + } + out->WriteInt32(numSections); + for (n = 0; n < numSections; n++) { + fwritestring(sectionNames[n], out); + out->WriteInt32(sectionOffsets[n]); + } + out->WriteInt32(ENDFILESIG); } -bool ccScript::Read(Stream *in) -{ - instances = 0; - int n; - char gotsig[5]; - currentline = -1; - // MACPORT FIX: swap 'size' and 'nmemb' - in->Read(gotsig, 4); - gotsig[4] = 0; - - int fileVer = in->ReadInt32(); - - if ((strcmp(gotsig, scfilesig) != 0) || (fileVer > SCOM_VERSION)) { - cc_error("file was not written by ccScript::Write or seek position is incorrect"); - return false; - } - - globaldatasize = in->ReadInt32(); - codesize = in->ReadInt32(); - stringssize = in->ReadInt32(); - - if (globaldatasize > 0) { - globaldata = (char *)malloc(globaldatasize); - // MACPORT FIX: swap - in->Read(globaldata, globaldatasize); - } - else - globaldata = nullptr; - - if (codesize > 0) { - code = (int32_t *)malloc(codesize * sizeof(int32_t)); - // MACPORT FIX: swap - - // 64 bit: Read code into 8 byte array, necessary for being able to perform - // relocations on the references. - in->ReadArrayOfInt32(code, codesize); - } - else - code = nullptr; - - if (stringssize > 0) { - strings = (char *)malloc(stringssize); - // MACPORT FIX: swap - in->Read(strings, stringssize); - } - else - strings = nullptr; - - numfixups = in->ReadInt32(); - if (numfixups > 0) { - fixuptypes = (char *)malloc(numfixups); - fixups = (int32_t *)malloc(numfixups * sizeof(int32_t)); - // MACPORT FIX: swap 'size' and 'nmemb' - in->Read(fixuptypes, numfixups); - in->ReadArrayOfInt32(fixups, numfixups); - } - else { - fixups = nullptr; - fixuptypes = nullptr; - } - - numimports = in->ReadInt32(); - - imports = (char**)malloc(sizeof(char*) * numimports); - for (n = 0; n < numimports; n++) - freadstring(&imports[n], in); - - numexports = in->ReadInt32(); - exports = (char**)malloc(sizeof(char*) * numexports); - export_addr = (int32_t*)malloc(sizeof(int32_t) * numexports); - for (n = 0; n < numexports; n++) { - freadstring(&exports[n], in); - export_addr[n] = in->ReadInt32(); - } - - if (fileVer >= 83) { - // read in the Sections - numSections = in->ReadInt32(); - sectionNames = (char**)malloc(numSections * sizeof(char*)); - sectionOffsets = (int32_t*)malloc(numSections * sizeof(int32_t)); - for (n = 0; n < numSections; n++) { - freadstring(§ionNames[n], in); - sectionOffsets[n] = in->ReadInt32(); - } - } - else - { - numSections = 0; - sectionNames = nullptr; - sectionOffsets = nullptr; - } - - if (in->ReadInt32() != ENDFILESIG) { - cc_error("internal error rebuilding script"); - return false; - } - return true; +bool ccScript::Read(Stream *in) { + instances = 0; + int n; + char gotsig[5]; + currentline = -1; + // MACPORT FIX: swap 'size' and 'nmemb' + in->Read(gotsig, 4); + gotsig[4] = 0; + + int fileVer = in->ReadInt32(); + + if ((strcmp(gotsig, scfilesig) != 0) || (fileVer > SCOM_VERSION)) { + cc_error("file was not written by ccScript::Write or seek position is incorrect"); + return false; + } + + globaldatasize = in->ReadInt32(); + codesize = in->ReadInt32(); + stringssize = in->ReadInt32(); + + if (globaldatasize > 0) { + globaldata = (char *)malloc(globaldatasize); + // MACPORT FIX: swap + in->Read(globaldata, globaldatasize); + } else + globaldata = nullptr; + + if (codesize > 0) { + code = (int32_t *)malloc(codesize * sizeof(int32_t)); + // MACPORT FIX: swap + + // 64 bit: Read code into 8 byte array, necessary for being able to perform + // relocations on the references. + in->ReadArrayOfInt32(code, codesize); + } else + code = nullptr; + + if (stringssize > 0) { + strings = (char *)malloc(stringssize); + // MACPORT FIX: swap + in->Read(strings, stringssize); + } else + strings = nullptr; + + numfixups = in->ReadInt32(); + if (numfixups > 0) { + fixuptypes = (char *)malloc(numfixups); + fixups = (int32_t *)malloc(numfixups * sizeof(int32_t)); + // MACPORT FIX: swap 'size' and 'nmemb' + in->Read(fixuptypes, numfixups); + in->ReadArrayOfInt32(fixups, numfixups); + } else { + fixups = nullptr; + fixuptypes = nullptr; + } + + numimports = in->ReadInt32(); + + imports = (char **)malloc(sizeof(char *) * numimports); + for (n = 0; n < numimports; n++) + freadstring(&imports[n], in); + + numexports = in->ReadInt32(); + exports = (char **)malloc(sizeof(char *) * numexports); + export_addr = (int32_t *)malloc(sizeof(int32_t) * numexports); + for (n = 0; n < numexports; n++) { + freadstring(&exports[n], in); + export_addr[n] = in->ReadInt32(); + } + + if (fileVer >= 83) { + // read in the Sections + numSections = in->ReadInt32(); + sectionNames = (char **)malloc(numSections * sizeof(char *)); + sectionOffsets = (int32_t *)malloc(numSections * sizeof(int32_t)); + for (n = 0; n < numSections; n++) { + freadstring(§ionNames[n], in); + sectionOffsets[n] = in->ReadInt32(); + } + } else { + numSections = 0; + sectionNames = nullptr; + sectionOffsets = nullptr; + } + + if (in->ReadInt32() != ENDFILESIG) { + cc_error("internal error rebuilding script"); + return false; + } + return true; } -void ccScript::Free() -{ - if (globaldata != nullptr) - free(globaldata); - - if (code != nullptr) - free(code); - - if (strings != nullptr) - free(strings); - - if (fixups != nullptr && numfixups > 0) - free(fixups); - - if (fixuptypes != nullptr && numfixups > 0) - free(fixuptypes); - - globaldata = nullptr; - code = nullptr; - strings = nullptr; - fixups = nullptr; - fixuptypes = nullptr; - - int aa; - for (aa = 0; aa < numimports; aa++) { - if (imports[aa] != nullptr) - free(imports[aa]); - } - - for (aa = 0; aa < numexports; aa++) - free(exports[aa]); - - for (aa = 0; aa < numSections; aa++) - free(sectionNames[aa]); - - if (sectionNames != nullptr) - { - free(sectionNames); - free(sectionOffsets); - sectionNames = nullptr; - sectionOffsets = nullptr; - } - - if (imports != nullptr) - { - free(imports); - free(exports); - free(export_addr); - imports = nullptr; - exports = nullptr; - export_addr = nullptr; - } - numimports = 0; - numexports = 0; - numSections = 0; +void ccScript::Free() { + if (globaldata != nullptr) + free(globaldata); + + if (code != nullptr) + free(code); + + if (strings != nullptr) + free(strings); + + if (fixups != nullptr && numfixups > 0) + free(fixups); + + if (fixuptypes != nullptr && numfixups > 0) + free(fixuptypes); + + globaldata = nullptr; + code = nullptr; + strings = nullptr; + fixups = nullptr; + fixuptypes = nullptr; + + int aa; + for (aa = 0; aa < numimports; aa++) { + if (imports[aa] != nullptr) + free(imports[aa]); + } + + for (aa = 0; aa < numexports; aa++) + free(exports[aa]); + + for (aa = 0; aa < numSections; aa++) + free(sectionNames[aa]); + + if (sectionNames != nullptr) { + free(sectionNames); + free(sectionOffsets); + sectionNames = nullptr; + sectionOffsets = nullptr; + } + + if (imports != nullptr) { + free(imports); + free(exports); + free(export_addr); + imports = nullptr; + exports = nullptr; + export_addr = nullptr; + } + numimports = 0; + numexports = 0; + numSections = 0; } -const char* ccScript::GetSectionName(int32_t offs) { +const char *ccScript::GetSectionName(int32_t offs) { - int i; - for (i = 0; i < numSections; i++) { - if (sectionOffsets[i] < offs) - continue; - break; - } + int i; + for (i = 0; i < numSections; i++) { + if (sectionOffsets[i] < offs) + continue; + break; + } - // if no sections in script, return unknown - if (i == 0) - return "(unknown section)"; + // if no sections in script, return unknown + if (i == 0) + return "(unknown section)"; - return sectionNames[i - 1]; + return sectionNames[i - 1]; } diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index 07f8d86de0cd..5cbdd14c9405 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -32,52 +32,55 @@ #include #include "core/types.h" -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later -struct ccScript -{ +struct ccScript { public: - char *globaldata; - int32_t globaldatasize; - int32_t *code; // executable byte-code, 32-bit per op or arg - int32_t codesize; // TODO: find out if we can make it size_t - char *strings; - int32_t stringssize; - char *fixuptypes; // global data/string area/ etc - int32_t *fixups; // code array index to fixup (in ints) - int numfixups; - int importsCapacity; - char **imports; - int numimports; - int exportsCapacity; - char **exports; // names of exports - int32_t *export_addr; // high byte is type; low 24-bits are offset - int numexports; - int instances; - // 'sections' allow the interpreter to find out which bit - // of the code came from header files, and which from the main file - char **sectionNames; - int32_t *sectionOffsets; - int numSections; - int capacitySections; + char *globaldata; + int32_t globaldatasize; + int32_t *code; // executable byte-code, 32-bit per op or arg + int32_t codesize; // TODO: find out if we can make it size_t + char *strings; + int32_t stringssize; + char *fixuptypes; // global data/string area/ etc + int32_t *fixups; // code array index to fixup (in ints) + int numfixups; + int importsCapacity; + char **imports; + int numimports; + int exportsCapacity; + char **exports; // names of exports + int32_t *export_addr; // high byte is type; low 24-bits are offset + int numexports; + int instances; + // 'sections' allow the interpreter to find out which bit + // of the code came from header files, and which from the main file + char **sectionNames; + int32_t *sectionOffsets; + int numSections; + int capacitySections; - static ccScript *CreateFromStream(Common::Stream *in); + static ccScript *CreateFromStream(Common::Stream *in); - ccScript(); - ccScript(const ccScript &src); - virtual ~ccScript(); // there are few derived classes, so dtor should be virtual + ccScript(); + ccScript(const ccScript &src); + virtual ~ccScript(); // there are few derived classes, so dtor should be virtual - // write the script to disk (after compiling) - void Write(Common::Stream *out); - // read back a script written with Write - bool Read(Common::Stream *in); - const char* GetSectionName(int32_t offset); + // write the script to disk (after compiling) + void Write(Common::Stream *out); + // read back a script written with Write + bool Read(Common::Stream *in); + const char *GetSectionName(int32_t offset); protected: - // free the memory occupied by the script - do NOT attempt to run the - // script after calling this function - void Free(); + // free the memory occupied by the script - do NOT attempt to run the + // script after calling this function + void Free(); }; typedef std::shared_ptr PScript; diff --git a/engines/ags/shared/util/alignedstream.cpp b/engines/ags/shared/util/alignedstream.cpp index c65a54ed6b31..d1a760a593f9 100644 --- a/engines/ags/shared/util/alignedstream.cpp +++ b/engines/ags/shared/util/alignedstream.cpp @@ -24,373 +24,308 @@ #include "util/alignedstream.h" #include "util/math.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { AlignedStream::AlignedStream(Stream *stream, AlignedStreamMode mode, ObjectOwnershipPolicy stream_ownership_policy, size_t base_alignment) - : ProxyStream(stream, stream_ownership_policy) - , _mode(mode) - , _baseAlignment(base_alignment) - , _maxAlignment(0) - , _block(0) -{ + : ProxyStream(stream, stream_ownership_policy) + , _mode(mode) + , _baseAlignment(base_alignment) + , _maxAlignment(0) + , _block(0) { } -AlignedStream::~AlignedStream() -{ - AlignedStream::Close(); +AlignedStream::~AlignedStream() { + AlignedStream::Close(); } -void AlignedStream::Reset() -{ - if (!_stream) - { - return; - } +void AlignedStream::Reset() { + if (!_stream) { + return; + } - FinalizeBlock(); + FinalizeBlock(); } -void AlignedStream::Close() -{ - if (!_stream) - { - return; - } +void AlignedStream::Close() { + if (!_stream) { + return; + } - FinalizeBlock(); - ProxyStream::Close(); + FinalizeBlock(); + ProxyStream::Close(); } -bool AlignedStream::CanRead() const -{ - return _stream ? (_mode == kAligned_Read && _stream->CanRead()) : false; +bool AlignedStream::CanRead() const { + return _stream ? (_mode == kAligned_Read && _stream->CanRead()) : false; } -bool AlignedStream::CanWrite() const -{ - return _stream ? (_mode == kAligned_Write && _stream->CanWrite()) : false; +bool AlignedStream::CanWrite() const { + return _stream ? (_mode == kAligned_Write && _stream->CanWrite()) : false; } -bool AlignedStream::CanSeek() const -{ - // Aligned stream does not support seeking, hence that will break padding count - return false; +bool AlignedStream::CanSeek() const { + // Aligned stream does not support seeking, hence that will break padding count + return false; } -size_t AlignedStream::Read(void *buffer, size_t size) -{ - if (_stream) - { - ReadPadding(sizeof(int8_t)); - size = _stream->Read(buffer, size); - _block += size; - return size; - } - return 0; +size_t AlignedStream::Read(void *buffer, size_t size) { + if (_stream) { + ReadPadding(sizeof(int8_t)); + size = _stream->Read(buffer, size); + _block += size; + return size; + } + return 0; } -int32_t AlignedStream::ReadByte() -{ - uint8_t b = 0; - if (_stream) - { - ReadPadding(sizeof(uint8_t)); - b = _stream->ReadByte(); - _block += sizeof(uint8_t); - } - return b; +int32_t AlignedStream::ReadByte() { + uint8_t b = 0; + if (_stream) { + ReadPadding(sizeof(uint8_t)); + b = _stream->ReadByte(); + _block += sizeof(uint8_t); + } + return b; } -int16_t AlignedStream::ReadInt16() -{ - int16_t val = 0; - if (_stream) - { - ReadPadding(sizeof(int16_t)); - val = _stream->ReadInt16(); - _block += sizeof(int16_t); - } - return val; +int16_t AlignedStream::ReadInt16() { + int16_t val = 0; + if (_stream) { + ReadPadding(sizeof(int16_t)); + val = _stream->ReadInt16(); + _block += sizeof(int16_t); + } + return val; } -int32_t AlignedStream::ReadInt32() -{ - int32_t val = 0; - if (_stream) - { - ReadPadding(sizeof(int32_t)); - val = _stream->ReadInt32(); - _block += sizeof(int32_t); - } - return val; +int32_t AlignedStream::ReadInt32() { + int32_t val = 0; + if (_stream) { + ReadPadding(sizeof(int32_t)); + val = _stream->ReadInt32(); + _block += sizeof(int32_t); + } + return val; } -int64_t AlignedStream::ReadInt64() -{ - int64_t val = 0; - if (_stream) - { - ReadPadding(sizeof(int64_t)); - val = _stream->ReadInt64(); - _block += sizeof(int64_t); - } - return val; +int64_t AlignedStream::ReadInt64() { + int64_t val = 0; + if (_stream) { + ReadPadding(sizeof(int64_t)); + val = _stream->ReadInt64(); + _block += sizeof(int64_t); + } + return val; } -size_t AlignedStream::ReadArray(void *buffer, size_t elem_size, size_t count) -{ - if (_stream) - { - ReadPadding(elem_size); - count = _stream->ReadArray(buffer, elem_size, count); - _block += count * elem_size; - return count; - } - return 0; +size_t AlignedStream::ReadArray(void *buffer, size_t elem_size, size_t count) { + if (_stream) { + ReadPadding(elem_size); + count = _stream->ReadArray(buffer, elem_size, count); + _block += count * elem_size; + return count; + } + return 0; } -size_t AlignedStream::ReadArrayOfInt16(int16_t *buffer, size_t count) -{ - if (_stream) - { - ReadPadding(sizeof(int16_t)); - count = _stream->ReadArrayOfInt16(buffer, count); - _block += count * sizeof(int16_t); - return count; - } - return 0; +size_t AlignedStream::ReadArrayOfInt16(int16_t *buffer, size_t count) { + if (_stream) { + ReadPadding(sizeof(int16_t)); + count = _stream->ReadArrayOfInt16(buffer, count); + _block += count * sizeof(int16_t); + return count; + } + return 0; } -size_t AlignedStream::ReadArrayOfInt32(int32_t *buffer, size_t count) -{ - if (_stream) - { - ReadPadding(sizeof(int32_t)); - count = _stream->ReadArrayOfInt32(buffer, count); - _block += count * sizeof(int32_t); - return count; - } - return 0; +size_t AlignedStream::ReadArrayOfInt32(int32_t *buffer, size_t count) { + if (_stream) { + ReadPadding(sizeof(int32_t)); + count = _stream->ReadArrayOfInt32(buffer, count); + _block += count * sizeof(int32_t); + return count; + } + return 0; } -size_t AlignedStream::ReadArrayOfInt64(int64_t *buffer, size_t count) -{ - if (_stream) - { - ReadPadding(sizeof(int64_t)); - count = _stream->ReadArrayOfInt64(buffer, count); - _block += count * sizeof(int64_t); - return count; - } - return 0; +size_t AlignedStream::ReadArrayOfInt64(int64_t *buffer, size_t count) { + if (_stream) { + ReadPadding(sizeof(int64_t)); + count = _stream->ReadArrayOfInt64(buffer, count); + _block += count * sizeof(int64_t); + return count; + } + return 0; } -size_t AlignedStream::Write(const void *buffer, size_t size) -{ - if (_stream) - { - WritePadding(sizeof(int8_t)); - size = _stream->Write(buffer, size); - _block += size; - return size; - } - return 0; +size_t AlignedStream::Write(const void *buffer, size_t size) { + if (_stream) { + WritePadding(sizeof(int8_t)); + size = _stream->Write(buffer, size); + _block += size; + return size; + } + return 0; } -int32_t AlignedStream::WriteByte(uint8_t b) -{ - if (_stream) - { - WritePadding(sizeof(uint8_t)); - b = _stream->WriteByte(b); - _block += sizeof(uint8_t); - return b; - } - return 0; +int32_t AlignedStream::WriteByte(uint8_t b) { + if (_stream) { + WritePadding(sizeof(uint8_t)); + b = _stream->WriteByte(b); + _block += sizeof(uint8_t); + return b; + } + return 0; } -size_t AlignedStream::WriteInt16(int16_t val) -{ - if (_stream) - { - WritePadding(sizeof(int16_t)); - size_t size = _stream->WriteInt16(val); - _block += sizeof(int16_t); - return size; - } - return 0; +size_t AlignedStream::WriteInt16(int16_t val) { + if (_stream) { + WritePadding(sizeof(int16_t)); + size_t size = _stream->WriteInt16(val); + _block += sizeof(int16_t); + return size; + } + return 0; } -size_t AlignedStream::WriteInt32(int32_t val) -{ - if (_stream) - { - WritePadding(sizeof(int32_t)); - size_t size = _stream->WriteInt32(val); - _block += sizeof(int32_t); - return size; - } - return 0; +size_t AlignedStream::WriteInt32(int32_t val) { + if (_stream) { + WritePadding(sizeof(int32_t)); + size_t size = _stream->WriteInt32(val); + _block += sizeof(int32_t); + return size; + } + return 0; } -size_t AlignedStream::WriteInt64(int64_t val) -{ - if (_stream) - { - WritePadding(sizeof(int64_t)); - size_t size = _stream->WriteInt64(val); - _block += sizeof(int64_t); - return size; - } - return 0; +size_t AlignedStream::WriteInt64(int64_t val) { + if (_stream) { + WritePadding(sizeof(int64_t)); + size_t size = _stream->WriteInt64(val); + _block += sizeof(int64_t); + return size; + } + return 0; } -size_t AlignedStream::WriteArray(const void *buffer, size_t elem_size, size_t count) -{ - if (_stream) - { - WritePadding(elem_size); - count = _stream->WriteArray(buffer, elem_size, count); - _block += count * elem_size; - return count; - } - return 0; +size_t AlignedStream::WriteArray(const void *buffer, size_t elem_size, size_t count) { + if (_stream) { + WritePadding(elem_size); + count = _stream->WriteArray(buffer, elem_size, count); + _block += count * elem_size; + return count; + } + return 0; } -size_t AlignedStream::WriteArrayOfInt16(const int16_t *buffer, size_t count) -{ - if (_stream) - { - WritePadding(sizeof(int16_t)); - count = _stream->WriteArrayOfInt16(buffer, count); - _block += count * sizeof(int16_t); - return count; - } - return 0; +size_t AlignedStream::WriteArrayOfInt16(const int16_t *buffer, size_t count) { + if (_stream) { + WritePadding(sizeof(int16_t)); + count = _stream->WriteArrayOfInt16(buffer, count); + _block += count * sizeof(int16_t); + return count; + } + return 0; } -size_t AlignedStream::WriteArrayOfInt32(const int32_t *buffer, size_t count) -{ - if (_stream) - { - WritePadding(sizeof(int32_t)); - count = _stream->WriteArrayOfInt32(buffer, count); - _block += count * sizeof(int32_t); - return count; - } - return 0; +size_t AlignedStream::WriteArrayOfInt32(const int32_t *buffer, size_t count) { + if (_stream) { + WritePadding(sizeof(int32_t)); + count = _stream->WriteArrayOfInt32(buffer, count); + _block += count * sizeof(int32_t); + return count; + } + return 0; } -size_t AlignedStream::WriteArrayOfInt64(const int64_t *buffer, size_t count) -{ - if (_stream) - { - WritePadding(sizeof(int64_t)); - count = _stream->WriteArrayOfInt64(buffer, count); - _block += count * sizeof(int64_t); - return count; - } - return 0; +size_t AlignedStream::WriteArrayOfInt64(const int64_t *buffer, size_t count) { + if (_stream) { + WritePadding(sizeof(int64_t)); + count = _stream->WriteArrayOfInt64(buffer, count); + _block += count * sizeof(int64_t); + return count; + } + return 0; } -bool AlignedStream::Seek(soff_t offset, StreamSeek origin) -{ - // TODO: split out Seekable Stream interface - return false; +bool AlignedStream::Seek(soff_t offset, StreamSeek origin) { + // TODO: split out Seekable Stream interface + return false; } -void AlignedStream::ReadPadding(size_t next_type) -{ - if (!IsValid()) - { - return; - } - - if (next_type == 0) - { - return; - } - - // The next is going to be evenly aligned data type, - // therefore a padding check must be made - if (next_type % _baseAlignment == 0) - { - int pad = _block % next_type; - // Read padding only if have to - if (pad) - { - // We do not know and should not care if the underlying stream - // supports seek, so use read to skip the padding instead. - for (size_t i = next_type - pad; i > 0; --i) - _stream->ReadByte(); - _block += next_type - pad; - } - - _maxAlignment = Math::Max(_maxAlignment, next_type); - // Data is evenly aligned now - if (_block % LargestPossibleType == 0) - { - _block = 0; - } - } +void AlignedStream::ReadPadding(size_t next_type) { + if (!IsValid()) { + return; + } + + if (next_type == 0) { + return; + } + + // The next is going to be evenly aligned data type, + // therefore a padding check must be made + if (next_type % _baseAlignment == 0) { + int pad = _block % next_type; + // Read padding only if have to + if (pad) { + // We do not know and should not care if the underlying stream + // supports seek, so use read to skip the padding instead. + for (size_t i = next_type - pad; i > 0; --i) + _stream->ReadByte(); + _block += next_type - pad; + } + + _maxAlignment = Math::Max(_maxAlignment, next_type); + // Data is evenly aligned now + if (_block % LargestPossibleType == 0) { + _block = 0; + } + } } -void AlignedStream::WritePadding(size_t next_type) -{ - if (!IsValid()) - { - return; - } - - if (next_type == 0) - { - return; - } - - // The next is going to be evenly aligned data type, - // therefore a padding check must be made - if (next_type % _baseAlignment == 0) - { - int pad = _block % next_type; - // Write padding only if have to - if (pad) - { - _stream->WriteByteCount(0, next_type - pad); - _block += next_type - pad; - } - - _maxAlignment = Math::Max(_maxAlignment, next_type); - // Data is evenly aligned now - if (_block % LargestPossibleType == 0) - { - _block = 0; - } - } +void AlignedStream::WritePadding(size_t next_type) { + if (!IsValid()) { + return; + } + + if (next_type == 0) { + return; + } + + // The next is going to be evenly aligned data type, + // therefore a padding check must be made + if (next_type % _baseAlignment == 0) { + int pad = _block % next_type; + // Write padding only if have to + if (pad) { + _stream->WriteByteCount(0, next_type - pad); + _block += next_type - pad; + } + + _maxAlignment = Math::Max(_maxAlignment, next_type); + // Data is evenly aligned now + if (_block % LargestPossibleType == 0) { + _block = 0; + } + } } -void AlignedStream::FinalizeBlock() -{ - if (!IsValid()) - { - return; - } - - // Force the stream to read or write remaining padding to match the alignment - if (_mode == kAligned_Read) - { - ReadPadding(_maxAlignment); - } - else if (_mode == kAligned_Write) - { - WritePadding(_maxAlignment); - } - - _maxAlignment = 0; - _block = 0; +void AlignedStream::FinalizeBlock() { + if (!IsValid()) { + return; + } + + // Force the stream to read or write remaining padding to match the alignment + if (_mode == kAligned_Read) { + ReadPadding(_maxAlignment); + } else if (_mode == kAligned_Write) { + WritePadding(_maxAlignment); + } + + _maxAlignment = 0; + _block = 0; } } // namespace Common diff --git a/engines/ags/shared/util/alignedstream.h b/engines/ags/shared/util/alignedstream.h index fd158b4937a2..e74517f24ca4 100644 --- a/engines/ags/shared/util/alignedstream.h +++ b/engines/ags/shared/util/alignedstream.h @@ -24,7 +24,7 @@ // // Class AlignedStream // A simple wrapper around stream that controls data padding. -// +// // Originally, a number of objects in AGS were read and written directly // as a data struct in a whole. In order to support backwards compatibility // with games made by older versions of AGS, some of the game objects must @@ -47,68 +47,64 @@ #include "util/proxystream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -enum AlignedStreamMode -{ - kAligned_Read, - kAligned_Write +enum AlignedStreamMode { + kAligned_Read, + kAligned_Write }; -class AlignedStream : public ProxyStream -{ +class AlignedStream : public ProxyStream { public: - AlignedStream(Stream *stream, AlignedStreamMode mode, - ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse, - size_t base_alignment = sizeof(int16_t)); - ~AlignedStream() override; - - // Read/Write cumulated padding and reset block counter - void Reset(); - - void Close() override; - - bool CanRead() const override; - bool CanWrite() const override; - bool CanSeek() const override; - - size_t Read(void *buffer, size_t size) override; - int32_t ReadByte() override; - int16_t ReadInt16() override; - int32_t ReadInt32() override; - int64_t ReadInt64() override; - size_t ReadArray(void *buffer, size_t elem_size, size_t count) override; - size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override; - size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override; - size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override; - - size_t Write(const void *buffer, size_t size) override; - int32_t WriteByte(uint8_t b) override; - size_t WriteInt16(int16_t val) override; - size_t WriteInt32(int32_t val) override; - size_t WriteInt64(int64_t val) override; - size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override; - size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override; - size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override; - size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override; - - bool Seek(soff_t offset, StreamSeek origin) override; + AlignedStream(Stream *stream, AlignedStreamMode mode, + ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse, + size_t base_alignment = sizeof(int16_t)); + ~AlignedStream() override; + + // Read/Write cumulated padding and reset block counter + void Reset(); + + void Close() override; + + bool CanRead() const override; + bool CanWrite() const override; + bool CanSeek() const override; + + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + int16_t ReadInt16() override; + int32_t ReadInt32() override; + int64_t ReadInt64() override; + size_t ReadArray(void *buffer, size_t elem_size, size_t count) override; + size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override; + size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override; + size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override; + + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; + size_t WriteInt16(int16_t val) override; + size_t WriteInt32(int32_t val) override; + size_t WriteInt64(int64_t val) override; + size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override; + size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override; + size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override; + size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override; + + bool Seek(soff_t offset, StreamSeek origin) override; protected: - void ReadPadding(size_t next_type); - void WritePadding(size_t next_type); - void FinalizeBlock(); + void ReadPadding(size_t next_type); + void WritePadding(size_t next_type); + void FinalizeBlock(); private: - static const size_t LargestPossibleType = sizeof(int64_t); + static const size_t LargestPossibleType = sizeof(int64_t); - AlignedStreamMode _mode; - size_t _baseAlignment; - size_t _maxAlignment; - int64_t _block; + AlignedStreamMode _mode; + size_t _baseAlignment; + size_t _maxAlignment; + int64_t _block; }; } // namespace Common diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h index 4b80fe66a7a0..f56b3ba50a1c 100644 --- a/engines/ags/shared/util/bbop.h +++ b/engines/ags/shared/util/bbop.h @@ -36,125 +36,108 @@ #define BITBYTE_BIG_ENDIAN #endif -namespace AGS -{ -namespace Common -{ - -enum DataEndianess -{ - kBigEndian, - kLittleEndian, +namespace AGS { +namespace Common { + +enum DataEndianess { + kBigEndian, + kLittleEndian, #if defined (BITBYTE_BIG_ENDIAN) - kDefaultSystemEndianess = kBigEndian + kDefaultSystemEndianess = kBigEndian #else - kDefaultSystemEndianess = kLittleEndian + kDefaultSystemEndianess = kLittleEndian #endif }; -namespace BitByteOperations -{ - inline int16_t SwapBytesInt16(const int16_t val) - { - return ((val >> 8) & 0xFF) | ((val << 8) & 0xFF00); - } - - inline int32_t SwapBytesInt32(const int32_t val) - { - return ((val >> 24) & 0xFF) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | ((val << 24) & 0xFF000000); - } - - inline int64_t SwapBytesInt64(const int64_t val) - { - return ((val >> 56) & 0xFF) | ((val >> 40) & 0xFF00) | ((val >> 24) & 0xFF0000) | - ((val >> 8) & 0xFF000000) | ((val << 8) & 0xFF00000000LL) | - ((val << 24) & 0xFF0000000000LL) | ((val << 40) & 0xFF000000000000LL) | ((val << 56) & 0xFF00000000000000LL); - } - - inline float SwapBytesFloat(const float val) - { - // (c) SDL2 - union - { - float f; - uint32_t ui32; - } swapper; - swapper.f = val; - swapper.ui32 = SwapBytesInt32(swapper.ui32); - return swapper.f; - } - - inline int16_t Int16FromLE(const int16_t val) - { +namespace BitByteOperations { +inline int16_t SwapBytesInt16(const int16_t val) { + return ((val >> 8) & 0xFF) | ((val << 8) & 0xFF00); +} + +inline int32_t SwapBytesInt32(const int32_t val) { + return ((val >> 24) & 0xFF) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | ((val << 24) & 0xFF000000); +} + +inline int64_t SwapBytesInt64(const int64_t val) { + return ((val >> 56) & 0xFF) | ((val >> 40) & 0xFF00) | ((val >> 24) & 0xFF0000) | + ((val >> 8) & 0xFF000000) | ((val << 8) & 0xFF00000000LL) | + ((val << 24) & 0xFF0000000000LL) | ((val << 40) & 0xFF000000000000LL) | ((val << 56) & 0xFF00000000000000LL); +} + +inline float SwapBytesFloat(const float val) { + // (c) SDL2 + union { + float f; + uint32_t ui32; + } swapper; + swapper.f = val; + swapper.ui32 = SwapBytesInt32(swapper.ui32); + return swapper.f; +} + +inline int16_t Int16FromLE(const int16_t val) { #if defined (BITBYTE_BIG_ENDIAN) - return SwapBytesInt16(val); + return SwapBytesInt16(val); #else - return val; + return val; #endif - } +} - inline int32_t Int32FromLE(const int32_t val) - { +inline int32_t Int32FromLE(const int32_t val) { #if defined (BITBYTE_BIG_ENDIAN) - return SwapBytesInt32(val); + return SwapBytesInt32(val); #else - return val; + return val; #endif - } +} - inline int64_t Int64FromLE(const int64_t val) - { +inline int64_t Int64FromLE(const int64_t val) { #if defined (BITBYTE_BIG_ENDIAN) - return SwapBytesInt64(val); + return SwapBytesInt64(val); #else - return val; + return val; #endif - } +} - inline float FloatFromLE(const float val) - { +inline float FloatFromLE(const float val) { #if defined (BITBYTE_BIG_ENDIAN) - return SwapBytesFloat(val); + return SwapBytesFloat(val); #else - return val; + return val; #endif - } +} - inline int16_t Int16FromBE(const int16_t val) - { +inline int16_t Int16FromBE(const int16_t val) { #if defined (BITBYTE_BIG_ENDIAN) - return val; + return val; #else - return SwapBytesInt16(val); + return SwapBytesInt16(val); #endif - } +} - inline int32_t Int32FromBE(const int32_t val) - { +inline int32_t Int32FromBE(const int32_t val) { #if defined (BITBYTE_BIG_ENDIAN) - return val; + return val; #else - return SwapBytesInt32(val); + return SwapBytesInt32(val); #endif - } +} - inline int64_t Int64FromBE(const int64_t val) - { +inline int64_t Int64FromBE(const int64_t val) { #if defined (BITBYTE_BIG_ENDIAN) - return val; + return val; #else - return SwapBytesInt64(val); + return SwapBytesInt64(val); #endif - } +} - inline float FloatFromBE(const float val) - { +inline float FloatFromBE(const float val) { #if defined (BITBYTE_BIG_ENDIAN) - return val; + return val; #else - return SwapBytesFloat(val); + return SwapBytesFloat(val); #endif - } +} } // namespace BitByteOperations diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index 5198b49b571b..a1a8f0dd0654 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -27,116 +27,114 @@ #include "util/stdio_compat.h" #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { BufferedStream::BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) - : FileStream(file_name, open_mode, work_mode, stream_endianess), _buffer(BufferStreamSize), _bufferPosition(0), _position(0) -{ - if (FileStream::Seek(0, kSeekEnd) == false) - throw std::runtime_error("Error determining stream end."); + : FileStream(file_name, open_mode, work_mode, stream_endianess), _buffer(BufferStreamSize), _bufferPosition(0), _position(0) { + if (FileStream::Seek(0, kSeekEnd) == false) + throw std::runtime_error("Error determining stream end."); - _end = FileStream::GetPosition(); - if (_end == -1) - throw std::runtime_error("Error determining stream end."); + _end = FileStream::GetPosition(); + if (_end == -1) + throw std::runtime_error("Error determining stream end."); - if (FileStream::Seek(0, kSeekBegin) == false) - throw std::runtime_error("Error determining stream end."); + if (FileStream::Seek(0, kSeekBegin) == false) + throw std::runtime_error("Error determining stream end."); - _buffer.resize(0); + _buffer.resize(0); } -void BufferedStream::FillBufferFromPosition(soff_t position) -{ - FileStream::Seek(position, kSeekBegin); +void BufferedStream::FillBufferFromPosition(soff_t position) { + FileStream::Seek(position, kSeekBegin); - _buffer.resize(BufferStreamSize); - auto sz = FileStream::Read(_buffer.data(), BufferStreamSize); - _buffer.resize(sz); + _buffer.resize(BufferStreamSize); + auto sz = FileStream::Read(_buffer.data(), BufferStreamSize); + _buffer.resize(sz); - _bufferPosition = position; + _bufferPosition = position; } -bool BufferedStream::EOS() const -{ - return _position == _end; +bool BufferedStream::EOS() const { + return _position == _end; } -soff_t BufferedStream::GetPosition() const -{ - return _position; +soff_t BufferedStream::GetPosition() const { + return _position; } -size_t BufferedStream::Read(void *toBuffer, size_t toSize) -{ - auto to = static_cast(toBuffer); +size_t BufferedStream::Read(void *toBuffer, size_t toSize) { + auto to = static_cast(toBuffer); - while(toSize > 0) - { - if (_position < _bufferPosition || _position >= _bufferPosition + _buffer.size()) - { - FillBufferFromPosition(_position); - } - if (_buffer.size() <= 0) { break; } // reached EOS - assert(_position >= _bufferPosition && _position < _bufferPosition + _buffer.size()); // sanity check only, should be checked by above. + while (toSize > 0) { + if (_position < _bufferPosition || _position >= _bufferPosition + _buffer.size()) { + FillBufferFromPosition(_position); + } + if (_buffer.size() <= 0) { + break; // reached EOS + } + assert(_position >= _bufferPosition && _position < _bufferPosition + _buffer.size()); // sanity check only, should be checked by above. - soff_t bufferOffset = _position - _bufferPosition; - assert(bufferOffset >= 0); - size_t bytesLeft = _buffer.size() - (size_t)bufferOffset; - size_t chunkSize = std::min(bytesLeft, toSize); + soff_t bufferOffset = _position - _bufferPosition; + assert(bufferOffset >= 0); + size_t bytesLeft = _buffer.size() - (size_t)bufferOffset; + size_t chunkSize = std::min(bytesLeft, toSize); - std::memcpy(to, _buffer.data()+bufferOffset, chunkSize); + std::memcpy(to, _buffer.data() + bufferOffset, chunkSize); - to += chunkSize; - _position += chunkSize; - toSize -= chunkSize; - } + to += chunkSize; + _position += chunkSize; + toSize -= chunkSize; + } - return to - (char*)toBuffer; + return to - (char *)toBuffer; } -int32_t BufferedStream::ReadByte() -{ - uint8_t ch; - auto bytesRead = Read(&ch, 1); - if (bytesRead != 1) { return EOF; } - return ch; +int32_t BufferedStream::ReadByte() { + uint8_t ch; + auto bytesRead = Read(&ch, 1); + if (bytesRead != 1) { + return EOF; + } + return ch; } -size_t BufferedStream::Write(const void *buffer, size_t size) -{ - FileStream::Seek(_position, kSeekBegin); - auto sz = FileStream::Write(buffer, size); - if (_position == _end) - _end += sz; - _position += sz; - return sz; +size_t BufferedStream::Write(const void *buffer, size_t size) { + FileStream::Seek(_position, kSeekBegin); + auto sz = FileStream::Write(buffer, size); + if (_position == _end) + _end += sz; + _position += sz; + return sz; } -int32_t BufferedStream::WriteByte(uint8_t val) -{ - auto sz = Write(&val, 1); - if (sz != 1) { return -1; } - return sz; +int32_t BufferedStream::WriteByte(uint8_t val) { + auto sz = Write(&val, 1); + if (sz != 1) { + return -1; + } + return sz; } -bool BufferedStream::Seek(soff_t offset, StreamSeek origin) -{ - soff_t want_pos = -1; - switch(origin) - { - case StreamSeek::kSeekCurrent: want_pos = _position + offset; break; - case StreamSeek::kSeekBegin: want_pos = 0 + offset; break; - case StreamSeek::kSeekEnd: want_pos = _end + offset; break; - break; - } - - // clamp - _position = std::min(std::max(want_pos, (soff_t)0), _end); - return _position == want_pos; +bool BufferedStream::Seek(soff_t offset, StreamSeek origin) { + soff_t want_pos = -1; + switch (origin) { + case StreamSeek::kSeekCurrent: + want_pos = _position + offset; + break; + case StreamSeek::kSeekBegin: + want_pos = 0 + offset; + break; + case StreamSeek::kSeekEnd: + want_pos = _end + offset; + break; + break; + } + + // clamp + _position = std::min(std::max(want_pos, (soff_t)0), _end); + return _position == want_pos; } } // namespace Common diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h index efb2cdc78505..27c938d21ea5 100644 --- a/engines/ags/shared/util/bufferedstream.h +++ b/engines/ags/shared/util/bufferedstream.h @@ -27,45 +27,42 @@ #include "util/filestream.h" #include "util/file.h" // TODO: extract filestream mode constants -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // Needs tuning depending on the platform. -const auto BufferStreamSize = 8*1024; +const auto BufferStreamSize = 8 * 1024; -class BufferedStream : public FileStream -{ +class BufferedStream : public FileStream { public: - // Represents an open _buffered_ file object - // The constructor may raise std::runtime_error if - // - there is an issue opening the file (does not exist, locked, permissions, etc) - // - the open mode could not be determined - // - could not determine the length of the stream - // It is recommended to use File::OpenFile to safely construct this object. - BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess = kLittleEndian); + // Represents an open _buffered_ file object + // The constructor may raise std::runtime_error if + // - there is an issue opening the file (does not exist, locked, permissions, etc) + // - the open mode could not be determined + // - could not determine the length of the stream + // It is recommended to use File::OpenFile to safely construct this object. + BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess = kLittleEndian); - bool EOS() const override; ///< Is end of stream - soff_t GetPosition() const override; ///< Current position (if known) + bool EOS() const override; ///< Is end of stream + soff_t GetPosition() const override; ///< Current position (if known) - size_t Read(void *buffer, size_t size) override; - int32_t ReadByte() override; - size_t Write(const void *buffer, size_t size) override; - int32_t WriteByte(uint8_t b) override; + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; - bool Seek(soff_t offset, StreamSeek origin) override; + bool Seek(soff_t offset, StreamSeek origin) override; private: - soff_t _bufferPosition; - std::vector _buffer; + soff_t _bufferPosition; + std::vector _buffer; - soff_t _position; - soff_t _end; + soff_t _position; + soff_t _end; - void FillBufferFromPosition(soff_t position); + void FillBufferFromPosition(soff_t position); }; } // namespace Common diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp index cf542ea7ad1f..cb0cf21e8cb9 100644 --- a/engines/ags/shared/util/compress.cpp +++ b/engines/ags/shared/util/compress.cpp @@ -27,7 +27,7 @@ #include #include -#include "ac/common.h" // quit, update_polled_stuff +#include "ac/common.h" // quit, update_polled_stuff #include "gfx/bitmap.h" #include "util/compress.h" #include "util/lzw.h" @@ -39,404 +39,391 @@ using namespace AGS::Common; -void cpackbitl(const uint8_t *line, int size, Stream *out) -{ - int cnt = 0; // bytes encoded - - while (cnt < size) { - int i = cnt; - int j = i + 1; - int jmax = i + 126; - if (jmax >= size) - jmax = size - 1; - - if (i == size - 1) { //................last byte alone - out->WriteInt8(0); - out->WriteInt8(line[i]); - cnt++; - - } else if (line[i] == line[j]) { //....run - while ((j < jmax) && (line[j] == line[j + 1])) - j++; - - out->WriteInt8(i - j); - out->WriteInt8(line[i]); - cnt += j - i + 1; - - } else { //.............................sequence - while ((j < jmax) && (line[j] != line[j + 1])) - j++; - - out->WriteInt8(j - i); - out->WriteArray(line + i, j - i + 1, 1); - cnt += j - i + 1; - - } - } // end while +void cpackbitl(const uint8_t *line, int size, Stream *out) { + int cnt = 0; // bytes encoded + + while (cnt < size) { + int i = cnt; + int j = i + 1; + int jmax = i + 126; + if (jmax >= size) + jmax = size - 1; + + if (i == size - 1) { //................last byte alone + out->WriteInt8(0); + out->WriteInt8(line[i]); + cnt++; + + } else if (line[i] == line[j]) { //....run + while ((j < jmax) && (line[j] == line[j + 1])) + j++; + + out->WriteInt8(i - j); + out->WriteInt8(line[i]); + cnt += j - i + 1; + + } else { //.............................sequence + while ((j < jmax) && (line[j] != line[j + 1])) + j++; + + out->WriteInt8(j - i); + out->WriteArray(line + i, j - i + 1, 1); + cnt += j - i + 1; + + } + } // end while } -void cpackbitl16(const uint16_t *line, int size, Stream *out) -{ - int cnt = 0; // bytes encoded - - while (cnt < size) { - int i = cnt; - int j = i + 1; - int jmax = i + 126; - if (jmax >= size) - jmax = size - 1; - - if (i == size - 1) { //................last byte alone - out->WriteInt8(0); - out->WriteInt16(line[i]); - cnt++; - - } else if (line[i] == line[j]) { //....run - while ((j < jmax) && (line[j] == line[j + 1])) - j++; - - out->WriteInt8(i - j); - out->WriteInt16(line[i]); - cnt += j - i + 1; - - } else { //.............................sequence - while ((j < jmax) && (line[j] != line[j + 1])) - j++; - - out->WriteInt8(j - i); - out->WriteArray(line + i, j - i + 1, 2); - cnt += j - i + 1; - - } - } // end while +void cpackbitl16(const uint16_t *line, int size, Stream *out) { + int cnt = 0; // bytes encoded + + while (cnt < size) { + int i = cnt; + int j = i + 1; + int jmax = i + 126; + if (jmax >= size) + jmax = size - 1; + + if (i == size - 1) { //................last byte alone + out->WriteInt8(0); + out->WriteInt16(line[i]); + cnt++; + + } else if (line[i] == line[j]) { //....run + while ((j < jmax) && (line[j] == line[j + 1])) + j++; + + out->WriteInt8(i - j); + out->WriteInt16(line[i]); + cnt += j - i + 1; + + } else { //.............................sequence + while ((j < jmax) && (line[j] != line[j + 1])) + j++; + + out->WriteInt8(j - i); + out->WriteArray(line + i, j - i + 1, 2); + cnt += j - i + 1; + + } + } // end while } -void cpackbitl32(const uint32_t *line, int size, Stream *out) -{ - int cnt = 0; // bytes encoded - - while (cnt < size) { - int i = cnt; - int j = i + 1; - int jmax = i + 126; - if (jmax >= size) - jmax = size - 1; - - if (i == size - 1) { //................last byte alone - out->WriteInt8(0); - out->WriteInt32(line[i]); - cnt++; - - } else if (line[i] == line[j]) { //....run - while ((j < jmax) && (line[j] == line[j + 1])) - j++; - - out->WriteInt8(i - j); - out->WriteInt32(line[i]); - cnt += j - i + 1; - - } else { //.............................sequence - while ((j < jmax) && (line[j] != line[j + 1])) - j++; - - out->WriteInt8(j - i); - out->WriteArray(line + i, j - i + 1, 4); - cnt += j - i + 1; - - } - } // end while +void cpackbitl32(const uint32_t *line, int size, Stream *out) { + int cnt = 0; // bytes encoded + + while (cnt < size) { + int i = cnt; + int j = i + 1; + int jmax = i + 126; + if (jmax >= size) + jmax = size - 1; + + if (i == size - 1) { //................last byte alone + out->WriteInt8(0); + out->WriteInt32(line[i]); + cnt++; + + } else if (line[i] == line[j]) { //....run + while ((j < jmax) && (line[j] == line[j + 1])) + j++; + + out->WriteInt8(i - j); + out->WriteInt32(line[i]); + cnt += j - i + 1; + + } else { //.............................sequence + while ((j < jmax) && (line[j] != line[j + 1])) + j++; + + out->WriteInt8(j - i); + out->WriteArray(line + i, j - i + 1, 4); + cnt += j - i + 1; + + } + } // end while } -void csavecompressed(Stream *out, const unsigned char * tobesaved, const color pala[256]) -{ - int widt, hit; - widt = *tobesaved++; - widt += (*tobesaved++) * 256; - hit = *tobesaved++; - hit += (*tobesaved++) * 256; - // Those were originally written as shorts, although they are ints - out->WriteInt16(widt); - out->WriteInt16(hit); - - unsigned char *ress = (unsigned char *)malloc(widt + 1); - int ww; - - for (ww = 0; ww < hit; ww++) { - for (int ss = 0; ss < widt; ss++) - (*ress++) = (*tobesaved++); - - ress -= widt; - cpackbitl(ress, widt, out); - } - - for (ww = 0; ww < 256; ww++) { - out->WriteInt8(pala[ww].r); - out->WriteInt8(pala[ww].g); - out->WriteInt8(pala[ww].b); - } - free(ress); +void csavecompressed(Stream *out, const unsigned char *tobesaved, const color pala[256]) { + int widt, hit; + widt = *tobesaved++; + widt += (*tobesaved++) * 256; + hit = *tobesaved++; + hit += (*tobesaved++) * 256; + // Those were originally written as shorts, although they are ints + out->WriteInt16(widt); + out->WriteInt16(hit); + + unsigned char *ress = (unsigned char *)malloc(widt + 1); + int ww; + + for (ww = 0; ww < hit; ww++) { + for (int ss = 0; ss < widt; ss++) + (*ress++) = (*tobesaved++); + + ress -= widt; + cpackbitl(ress, widt, out); + } + + for (ww = 0; ww < 256; ww++) { + out->WriteInt8(pala[ww].r); + out->WriteInt8(pala[ww].g); + out->WriteInt8(pala[ww].b); + } + free(ress); } -int cunpackbitl(uint8_t *line, int size, Stream *in) -{ - int n = 0; // number of bytes decoded - - while (n < size) { - int ix = in->ReadByte(); // get index byte - if (in->HasErrors()) - break; - - char cx = ix; - if (cx == -128) - cx = 0; - - if (cx < 0) { //.............run - int i = 1 - cx; - char ch = in->ReadInt8(); - while (i--) { - // test for buffer overflow - if (n >= size) - return -1; - - line[n++] = ch; - } - } else { //.....................seq - int i = cx + 1; - while (i--) { - // test for buffer overflow - if (n >= size) - return -1; - - line[n++] = in->ReadByte(); - } - } - } - - return in->HasErrors() ? -1 : 0; +int cunpackbitl(uint8_t *line, int size, Stream *in) { + int n = 0; // number of bytes decoded + + while (n < size) { + int ix = in->ReadByte(); // get index byte + if (in->HasErrors()) + break; + + char cx = ix; + if (cx == -128) + cx = 0; + + if (cx < 0) { //.............run + int i = 1 - cx; + char ch = in->ReadInt8(); + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = ch; + } + } else { //.....................seq + int i = cx + 1; + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = in->ReadByte(); + } + } + } + + return in->HasErrors() ? -1 : 0; } -int cunpackbitl16(uint16_t *line, int size, Stream *in) -{ - int n = 0; // number of bytes decoded - - while (n < size) { - int ix = in->ReadByte(); // get index byte - if (in->HasErrors()) - break; - - char cx = ix; - if (cx == -128) - cx = 0; - - if (cx < 0) { //.............run - int i = 1 - cx; - unsigned short ch = in->ReadInt16(); - while (i--) { - // test for buffer overflow - if (n >= size) - return -1; - - line[n++] = ch; - } - } else { //.....................seq - int i = cx + 1; - while (i--) { - // test for buffer overflow - if (n >= size) - return -1; - - line[n++] = in->ReadInt16(); - } - } - } - - return in->HasErrors() ? -1 : 0; +int cunpackbitl16(uint16_t *line, int size, Stream *in) { + int n = 0; // number of bytes decoded + + while (n < size) { + int ix = in->ReadByte(); // get index byte + if (in->HasErrors()) + break; + + char cx = ix; + if (cx == -128) + cx = 0; + + if (cx < 0) { //.............run + int i = 1 - cx; + unsigned short ch = in->ReadInt16(); + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = ch; + } + } else { //.....................seq + int i = cx + 1; + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = in->ReadInt16(); + } + } + } + + return in->HasErrors() ? -1 : 0; } -int cunpackbitl32(uint32_t *line, int size, Stream *in) -{ - int n = 0; // number of bytes decoded - - while (n < size) { - int ix = in->ReadByte(); // get index byte - if (in->HasErrors()) - break; - - char cx = ix; - if (cx == -128) - cx = 0; - - if (cx < 0) { //.............run - int i = 1 - cx; - unsigned int ch = in->ReadInt32(); - while (i--) { - // test for buffer overflow - if (n >= size) - return -1; - - line[n++] = ch; - } - } else { //.....................seq - int i = cx + 1; - while (i--) { - // test for buffer overflow - if (n >= size) - return -1; - - line[n++] = (unsigned int)in->ReadInt32(); - } - } - } - - return in->HasErrors() ? -1 : 0; +int cunpackbitl32(uint32_t *line, int size, Stream *in) { + int n = 0; // number of bytes decoded + + while (n < size) { + int ix = in->ReadByte(); // get index byte + if (in->HasErrors()) + break; + + char cx = ix; + if (cx == -128) + cx = 0; + + if (cx < 0) { //.............run + int i = 1 - cx; + unsigned int ch = in->ReadInt32(); + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = ch; + } + } else { //.....................seq + int i = cx + 1; + while (i--) { + // test for buffer overflow + if (n >= size) + return -1; + + line[n++] = (unsigned int)in->ReadInt32(); + } + } + } + + return in->HasErrors() ? -1 : 0; } //============================================================================= const char *lztempfnm = "~aclzw.tmp"; -void save_lzw(Stream *out, const Bitmap *bmpp, const color *pall) -{ - // First write original bitmap into temporary file - Stream *lz_temp_s = ci_fopen(lztempfnm, kFile_CreateAlways, kFile_Write); - lz_temp_s->WriteInt32(bmpp->GetWidth() * bmpp->GetBPP()); - lz_temp_s->WriteInt32(bmpp->GetHeight()); - lz_temp_s->WriteArray(bmpp->GetData(), bmpp->GetLineLength(), bmpp->GetHeight()); - delete lz_temp_s; - - // Now open same file for reading, and begin writing compressed data into required output stream - lz_temp_s = ci_fopen(lztempfnm); - soff_t temp_sz = lz_temp_s->GetLength(); - out->WriteArray(&pall[0], sizeof(color), 256); - out->WriteInt32(temp_sz); - soff_t gobacto = out->GetPosition(); - - // reserve space for compressed size - out->WriteInt32(temp_sz); - lzwcompress(lz_temp_s, out); - soff_t toret = out->GetPosition(); - out->Seek(gobacto, kSeekBegin); - soff_t compressed_sz = (toret - gobacto) - 4; - out->WriteInt32(compressed_sz); // write compressed size - - // Delete temp file - delete lz_temp_s; - ::remove(lztempfnm); - - // Seek back to the end of the output stream - out->Seek(toret, kSeekBegin); +void save_lzw(Stream *out, const Bitmap *bmpp, const color *pall) { + // First write original bitmap into temporary file + Stream *lz_temp_s = ci_fopen(lztempfnm, kFile_CreateAlways, kFile_Write); + lz_temp_s->WriteInt32(bmpp->GetWidth() * bmpp->GetBPP()); + lz_temp_s->WriteInt32(bmpp->GetHeight()); + lz_temp_s->WriteArray(bmpp->GetData(), bmpp->GetLineLength(), bmpp->GetHeight()); + delete lz_temp_s; + + // Now open same file for reading, and begin writing compressed data into required output stream + lz_temp_s = ci_fopen(lztempfnm); + soff_t temp_sz = lz_temp_s->GetLength(); + out->WriteArray(&pall[0], sizeof(color), 256); + out->WriteInt32(temp_sz); + soff_t gobacto = out->GetPosition(); + + // reserve space for compressed size + out->WriteInt32(temp_sz); + lzwcompress(lz_temp_s, out); + soff_t toret = out->GetPosition(); + out->Seek(gobacto, kSeekBegin); + soff_t compressed_sz = (toret - gobacto) - 4; + out->WriteInt32(compressed_sz); // write compressed size + + // Delete temp file + delete lz_temp_s; + ::remove(lztempfnm); + + // Seek back to the end of the output stream + out->Seek(toret, kSeekBegin); } void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, color *pall) { - soff_t uncompsiz; - int *loptr; - unsigned char *membuffer; - int arin; + soff_t uncompsiz; + int *loptr; + unsigned char *membuffer; + int arin; - in->Read(&pall[0], sizeof(color)*256); - maxsize = in->ReadInt32(); - uncompsiz = in->ReadInt32(); + in->Read(&pall[0], sizeof(color) * 256); + maxsize = in->ReadInt32(); + uncompsiz = in->ReadInt32(); - uncompsiz += in->GetPosition(); - outbytes = 0; putbytes = 0; + uncompsiz += in->GetPosition(); + outbytes = 0; + putbytes = 0; - update_polled_stuff_if_runtime(); - membuffer = lzwexpand_to_mem(in); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); + membuffer = lzwexpand_to_mem(in); + update_polled_stuff_if_runtime(); - loptr = (int *)&membuffer[0]; - membuffer += 8; + loptr = (int *)&membuffer[0]; + membuffer += 8; #if AGS_PLATFORM_ENDIAN_BIG - loptr[0] = BBOp::SwapBytesInt32(loptr[0]); - loptr[1] = BBOp::SwapBytesInt32(loptr[1]); - int bitmapNumPixels = loptr[0]*loptr[1]/ dst_bpp; - switch (dst_bpp) // bytes per pixel! - { - case 1: - { - // all done - break; - } - case 2: - { - short *sp = (short *)membuffer; - for (int i = 0; i < bitmapNumPixels; ++i) - { - sp[i] = BBOp::SwapBytesInt16(sp[i]); - } - // all done - break; - } - case 4: - { - int *ip = (int *)membuffer; - for (int i = 0; i < bitmapNumPixels; ++i) - { - ip[i] = BBOp::SwapBytesInt32(ip[i]); - } - // all done - break; - } - } + loptr[0] = BBOp::SwapBytesInt32(loptr[0]); + loptr[1] = BBOp::SwapBytesInt32(loptr[1]); + int bitmapNumPixels = loptr[0] * loptr[1] / dst_bpp; + switch (dst_bpp) { // bytes per pixel! + case 1: { + // all done + break; + } + case 2: { + short *sp = (short *)membuffer; + for (int i = 0; i < bitmapNumPixels; ++i) { + sp[i] = BBOp::SwapBytesInt16(sp[i]); + } + // all done + break; + } + case 4: { + int *ip = (int *)membuffer; + for (int i = 0; i < bitmapNumPixels; ++i) { + ip[i] = BBOp::SwapBytesInt32(ip[i]); + } + // all done + break; + } + } #endif // AGS_PLATFORM_ENDIAN_BIG - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - Bitmap *bmm = BitmapHelper::CreateBitmap((loptr[0] / dst_bpp), loptr[1], dst_bpp * 8); - if (bmm == nullptr) - quit("!load_room: not enough memory to load room background"); + Bitmap *bmm = BitmapHelper::CreateBitmap((loptr[0] / dst_bpp), loptr[1], dst_bpp * 8); + if (bmm == nullptr) + quit("!load_room: not enough memory to load room background"); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - bmm->Acquire (); + bmm->Acquire(); - for (arin = 0; arin < loptr[1]; arin++) - memcpy(&bmm->GetScanLineForWriting(arin)[0], &membuffer[arin * loptr[0]], loptr[0]); + for (arin = 0; arin < loptr[1]; arin++) + memcpy(&bmm->GetScanLineForWriting(arin)[0], &membuffer[arin * loptr[0]], loptr[0]); - bmm->Release (); + bmm->Release(); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - free(membuffer-8); + free(membuffer - 8); - if (in->GetPosition() != uncompsiz) - in->Seek(uncompsiz, kSeekBegin); + if (in->GetPosition() != uncompsiz) + in->Seek(uncompsiz, kSeekBegin); - update_polled_stuff_if_runtime(); + update_polled_stuff_if_runtime(); - *dst_bmp = bmm; + *dst_bmp = bmm; } void savecompressed_allegro(Stream *out, const Bitmap *bmpp, const color *pall) { - unsigned char *wgtbl = (unsigned char *)malloc(bmpp->GetWidth() * bmpp->GetHeight() + 4); - short *sss = (short *)wgtbl; + unsigned char *wgtbl = (unsigned char *)malloc(bmpp->GetWidth() * bmpp->GetHeight() + 4); + short *sss = (short *)wgtbl; - sss[0] = bmpp->GetWidth(); - sss[1] = bmpp->GetHeight(); + sss[0] = bmpp->GetWidth(); + sss[1] = bmpp->GetHeight(); - memcpy(&wgtbl[4], bmpp->GetData(), bmpp->GetWidth() * bmpp->GetHeight()); + memcpy(&wgtbl[4], bmpp->GetData(), bmpp->GetWidth() * bmpp->GetHeight()); - csavecompressed(out, wgtbl, pall); - free(wgtbl); + csavecompressed(out, wgtbl, pall); + free(wgtbl); } void loadcompressed_allegro(Stream *in, Bitmap **bimpp, color *pall) { - short widd,hitt; - int ii; - - widd = in->ReadInt16(); - hitt = in->ReadInt16(); - Bitmap *bim = BitmapHelper::CreateBitmap(widd, hitt, 8); - if (bim == nullptr) - quit("!load_room: not enough memory to decompress masks"); - - for (ii = 0; ii < hitt; ii++) { - cunpackbitl(&bim->GetScanLineForWriting(ii)[0], widd, in); - if (ii % 20 == 0) - update_polled_stuff_if_runtime(); - } - - in->Seek(768); // skip palette - *bimpp = bim; + short widd, hitt; + int ii; + + widd = in->ReadInt16(); + hitt = in->ReadInt16(); + Bitmap *bim = BitmapHelper::CreateBitmap(widd, hitt, 8); + if (bim == nullptr) + quit("!load_room: not enough memory to decompress masks"); + + for (ii = 0; ii < hitt; ii++) { + cunpackbitl(&bim->GetScanLineForWriting(ii)[0], widd, in); + if (ii % 20 == 0) + update_polled_stuff_if_runtime(); + } + + in->Seek(768); // skip palette + *bimpp = bim; } diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h index 199020deab8a..783b4a9bb103 100644 --- a/engines/ags/shared/util/compress.h +++ b/engines/ags/shared/util/compress.h @@ -25,10 +25,15 @@ #include "util/wgt2allg.h" // color (allegro RGB) -namespace AGS { namespace Common { class Stream; class Bitmap; } } +namespace AGS { +namespace Common { +class Stream; +class Bitmap; +} +} using namespace AGS; // FIXME later -void csavecompressed(Common::Stream *out, const unsigned char * tobesaved, const color pala[256]); +void csavecompressed(Common::Stream *out, const unsigned char *tobesaved, const color pala[256]); // RLE compression void cpackbitl(const uint8_t *line, int size, Common::Stream *out); void cpackbitl16(const uint16_t *line, int size, Common::Stream *out); diff --git a/engines/ags/shared/util/datastream.cpp b/engines/ags/shared/util/datastream.cpp index a05c4a7821f5..ff170d184c98 100644 --- a/engines/ags/shared/util/datastream.cpp +++ b/engines/ags/shared/util/datastream.cpp @@ -22,163 +22,133 @@ #include "util/datastream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { DataStream::DataStream(DataEndianess stream_endianess) - : _streamEndianess(stream_endianess) -{ + : _streamEndianess(stream_endianess) { } DataStream::~DataStream() = default; -int16_t DataStream::ReadInt16() -{ - int16_t val = 0; - Read(&val, sizeof(int16_t)); - ConvertInt16(val); - return val; +int16_t DataStream::ReadInt16() { + int16_t val = 0; + Read(&val, sizeof(int16_t)); + ConvertInt16(val); + return val; } -int32_t DataStream::ReadInt32() -{ - int32_t val = 0; - Read(&val, sizeof(int32_t)); - ConvertInt32(val); - return val; +int32_t DataStream::ReadInt32() { + int32_t val = 0; + Read(&val, sizeof(int32_t)); + ConvertInt32(val); + return val; } -int64_t DataStream::ReadInt64() -{ - int64_t val = 0; - Read(&val, sizeof(int64_t)); - ConvertInt64(val); - return val; +int64_t DataStream::ReadInt64() { + int64_t val = 0; + Read(&val, sizeof(int64_t)); + ConvertInt64(val); + return val; } -size_t DataStream::WriteInt16(int16_t val) -{ - ConvertInt16(val); - return Write(&val, sizeof(int16_t)); +size_t DataStream::WriteInt16(int16_t val) { + ConvertInt16(val); + return Write(&val, sizeof(int16_t)); } -size_t DataStream::WriteInt32(int32_t val) -{ - ConvertInt32(val); - return Write(&val, sizeof(int32_t)); +size_t DataStream::WriteInt32(int32_t val) { + ConvertInt32(val); + return Write(&val, sizeof(int32_t)); } -size_t DataStream::WriteInt64(int64_t val) -{ - ConvertInt64(val); - return Write(&val, sizeof(int64_t)); +size_t DataStream::WriteInt64(int64_t val) { + ConvertInt64(val); + return Write(&val, sizeof(int64_t)); } -size_t DataStream::ReadAndConvertArrayOfInt16(int16_t *buffer, size_t count) -{ - if (!CanRead() || !buffer) - { - return 0; - } - - count = ReadArray(buffer, sizeof(int16_t), count); - for (size_t i = 0; i < count; ++i, ++buffer) - { - *buffer = BBOp::SwapBytesInt16(*buffer); - } - return count; +size_t DataStream::ReadAndConvertArrayOfInt16(int16_t *buffer, size_t count) { + if (!CanRead() || !buffer) { + return 0; + } + + count = ReadArray(buffer, sizeof(int16_t), count); + for (size_t i = 0; i < count; ++i, ++buffer) { + *buffer = BBOp::SwapBytesInt16(*buffer); + } + return count; } -size_t DataStream::ReadAndConvertArrayOfInt32(int32_t *buffer, size_t count) -{ - if (!CanRead() || !buffer) - { - return 0; - } - - count = ReadArray(buffer, sizeof(int32_t), count); - for (size_t i = 0; i < count; ++i, ++buffer) - { - *buffer = BBOp::SwapBytesInt32(*buffer); - } - return count; +size_t DataStream::ReadAndConvertArrayOfInt32(int32_t *buffer, size_t count) { + if (!CanRead() || !buffer) { + return 0; + } + + count = ReadArray(buffer, sizeof(int32_t), count); + for (size_t i = 0; i < count; ++i, ++buffer) { + *buffer = BBOp::SwapBytesInt32(*buffer); + } + return count; } -size_t DataStream::ReadAndConvertArrayOfInt64(int64_t *buffer, size_t count) -{ - if (!CanRead() || !buffer) - { - return 0; - } - - count = ReadArray(buffer, sizeof(int64_t), count); - for (size_t i = 0; i < count; ++i, ++buffer) - { - *buffer = BBOp::SwapBytesInt64(*buffer); - } - return count; +size_t DataStream::ReadAndConvertArrayOfInt64(int64_t *buffer, size_t count) { + if (!CanRead() || !buffer) { + return 0; + } + + count = ReadArray(buffer, sizeof(int64_t), count); + for (size_t i = 0; i < count; ++i, ++buffer) { + *buffer = BBOp::SwapBytesInt64(*buffer); + } + return count; } -size_t DataStream::WriteAndConvertArrayOfInt16(const int16_t *buffer, size_t count) -{ - if (!CanWrite() || !buffer) - { - return 0; - } - - size_t elem; - for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) - { - int16_t val = *buffer; - ConvertInt16(val); - if (Write(&val, sizeof(int16_t)) < sizeof(int16_t)) - { - break; - } - } - return elem; +size_t DataStream::WriteAndConvertArrayOfInt16(const int16_t *buffer, size_t count) { + if (!CanWrite() || !buffer) { + return 0; + } + + size_t elem; + for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) { + int16_t val = *buffer; + ConvertInt16(val); + if (Write(&val, sizeof(int16_t)) < sizeof(int16_t)) { + break; + } + } + return elem; } -size_t DataStream::WriteAndConvertArrayOfInt32(const int32_t *buffer, size_t count) -{ - if (!CanWrite() || !buffer) - { - return 0; - } - - size_t elem; - for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) - { - int32_t val = *buffer; - ConvertInt32(val); - if (Write(&val, sizeof(int32_t)) < sizeof(int32_t)) - { - break; - } - } - return elem; +size_t DataStream::WriteAndConvertArrayOfInt32(const int32_t *buffer, size_t count) { + if (!CanWrite() || !buffer) { + return 0; + } + + size_t elem; + for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) { + int32_t val = *buffer; + ConvertInt32(val); + if (Write(&val, sizeof(int32_t)) < sizeof(int32_t)) { + break; + } + } + return elem; } -size_t DataStream::WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t count) -{ - if (!CanWrite() || !buffer) - { - return 0; - } - - size_t elem; - for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) - { - int64_t val = *buffer; - ConvertInt64(val); - if (Write(&val, sizeof(int64_t)) < sizeof(int64_t)) - { - break; - } - } - return elem; +size_t DataStream::WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t count) { + if (!CanWrite() || !buffer) { + return 0; + } + + size_t elem; + for (elem = 0; elem < count && !EOS(); ++elem, ++buffer) { + int64_t val = *buffer; + ConvertInt64(val); + if (Write(&val, sizeof(int64_t)) < sizeof(int64_t)) { + break; + } + } + return elem; } } // namespace Common diff --git a/engines/ags/shared/util/datastream.h b/engines/ags/shared/util/datastream.h index 6bbc92ff3f6c..78234a4e1d4f 100644 --- a/engines/ags/shared/util/datastream.h +++ b/engines/ags/shared/util/datastream.h @@ -34,107 +34,92 @@ #include "util/bbop.h" #include "util/stream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class DataStream : public Stream -{ +class DataStream : public Stream { public: - DataStream(DataEndianess stream_endianess = kLittleEndian); - ~DataStream() override; - - int16_t ReadInt16() override; - int32_t ReadInt32() override; - int64_t ReadInt64() override; - - // - // Read- and WriteArray methods return number of full elements (NOT bytes) - // read or written, or -1 if end of stream is reached - // - // Note that ReadArray and WriteArray do NOT convert byte order even when - // work with data of different endianess; they are meant for optimal - // reading and writing blocks of raw bytes - inline size_t ReadArray(void *buffer, size_t elem_size, size_t count) override - { - return Read(buffer, elem_size * count) / elem_size; - } - - inline size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override - { - return MustSwapBytes() ? - ReadAndConvertArrayOfInt16(buffer, count) : ReadArray(buffer, sizeof(int16_t), count); - } - - inline size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override - { - return MustSwapBytes() ? - ReadAndConvertArrayOfInt32(buffer, count) : ReadArray(buffer, sizeof(int32_t), count); - } - - inline size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override - { - return MustSwapBytes() ? - ReadAndConvertArrayOfInt64(buffer, count) : ReadArray(buffer, sizeof(int64_t), count); - } - - size_t WriteInt16(int16_t val) override; - size_t WriteInt32(int32_t val) override; - size_t WriteInt64(int64_t val) override; - - inline size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override - { - return Write(buffer, elem_size * count) / elem_size; - } - - inline size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override - { - return MustSwapBytes() ? - WriteAndConvertArrayOfInt16(buffer, count) : WriteArray(buffer, sizeof(int16_t), count); - } - - inline size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override - { - return MustSwapBytes() ? - WriteAndConvertArrayOfInt32(buffer, count) : WriteArray(buffer, sizeof(int32_t), count); - } - - inline size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override - { - return MustSwapBytes() ? - WriteAndConvertArrayOfInt64(buffer, count) : WriteArray(buffer, sizeof(int64_t), count); - } + DataStream(DataEndianess stream_endianess = kLittleEndian); + ~DataStream() override; + + int16_t ReadInt16() override; + int32_t ReadInt32() override; + int64_t ReadInt64() override; + + // + // Read- and WriteArray methods return number of full elements (NOT bytes) + // read or written, or -1 if end of stream is reached + // + // Note that ReadArray and WriteArray do NOT convert byte order even when + // work with data of different endianess; they are meant for optimal + // reading and writing blocks of raw bytes + inline size_t ReadArray(void *buffer, size_t elem_size, size_t count) override { + return Read(buffer, elem_size * count) / elem_size; + } + + inline size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override { + return MustSwapBytes() ? + ReadAndConvertArrayOfInt16(buffer, count) : ReadArray(buffer, sizeof(int16_t), count); + } + + inline size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override { + return MustSwapBytes() ? + ReadAndConvertArrayOfInt32(buffer, count) : ReadArray(buffer, sizeof(int32_t), count); + } + + inline size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override { + return MustSwapBytes() ? + ReadAndConvertArrayOfInt64(buffer, count) : ReadArray(buffer, sizeof(int64_t), count); + } + + size_t WriteInt16(int16_t val) override; + size_t WriteInt32(int32_t val) override; + size_t WriteInt64(int64_t val) override; + + inline size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override { + return Write(buffer, elem_size * count) / elem_size; + } + + inline size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override { + return MustSwapBytes() ? + WriteAndConvertArrayOfInt16(buffer, count) : WriteArray(buffer, sizeof(int16_t), count); + } + + inline size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override { + return MustSwapBytes() ? + WriteAndConvertArrayOfInt32(buffer, count) : WriteArray(buffer, sizeof(int32_t), count); + } + + inline size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override { + return MustSwapBytes() ? + WriteAndConvertArrayOfInt64(buffer, count) : WriteArray(buffer, sizeof(int64_t), count); + } protected: - DataEndianess _streamEndianess; - - // Helper methods for reading/writing arrays of basic types and - // converting their elements to opposite endianess (swapping bytes). - size_t ReadAndConvertArrayOfInt16(int16_t *buffer, size_t count); - size_t ReadAndConvertArrayOfInt32(int32_t *buffer, size_t count); - size_t ReadAndConvertArrayOfInt64(int64_t *buffer, size_t count); - size_t WriteAndConvertArrayOfInt16(const int16_t *buffer, size_t count); - size_t WriteAndConvertArrayOfInt32(const int32_t *buffer, size_t count); - size_t WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t count); - - inline bool MustSwapBytes() - { - return kDefaultSystemEndianess != _streamEndianess; - } - - inline void ConvertInt16(int16_t &val) - { - if (MustSwapBytes()) val = BBOp::SwapBytesInt16(val); - } - inline void ConvertInt32(int32_t &val) - { - if (MustSwapBytes()) val = BBOp::SwapBytesInt32(val); - } - inline void ConvertInt64(int64_t &val) - { - if (MustSwapBytes()) val = BBOp::SwapBytesInt64(val); - } + DataEndianess _streamEndianess; + + // Helper methods for reading/writing arrays of basic types and + // converting their elements to opposite endianess (swapping bytes). + size_t ReadAndConvertArrayOfInt16(int16_t *buffer, size_t count); + size_t ReadAndConvertArrayOfInt32(int32_t *buffer, size_t count); + size_t ReadAndConvertArrayOfInt64(int64_t *buffer, size_t count); + size_t WriteAndConvertArrayOfInt16(const int16_t *buffer, size_t count); + size_t WriteAndConvertArrayOfInt32(const int32_t *buffer, size_t count); + size_t WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t count); + + inline bool MustSwapBytes() { + return kDefaultSystemEndianess != _streamEndianess; + } + + inline void ConvertInt16(int16_t &val) { + if (MustSwapBytes()) val = BBOp::SwapBytesInt16(val); + } + inline void ConvertInt32(int32_t &val) { + if (MustSwapBytes()) val = BBOp::SwapBytesInt32(val); + } + inline void ConvertInt64(int64_t &val) { + if (MustSwapBytes()) val = BBOp::SwapBytesInt64(val); + } }; } // namespace Common diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp index 8ed1095f7a8e..fa58dfc3ebea 100644 --- a/engines/ags/shared/util/directory.cpp +++ b/engines/ags/shared/util/directory.cpp @@ -32,59 +32,51 @@ #include "util/path.h" #include "stdio_compat.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -namespace Directory -{ +namespace Directory { -bool CreateDirectory(const String &path) -{ - return mkdir(path +bool CreateDirectory(const String &path) { + return mkdir(path #if ! AGS_PLATFORM_OS_WINDOWS - , 0755 + , 0755 #endif - ) == 0 || errno == EEXIST; + ) == 0 || errno == EEXIST; } -bool CreateAllDirectories(const String &parent, const String &path) -{ - if (!ags_directory_exists(parent.GetCStr())) - return false; - if (path.IsEmpty()) - return true; - if (!Path::IsSameOrSubDir(parent, path)) - return false; +bool CreateAllDirectories(const String &parent, const String &path) { + if (!ags_directory_exists(parent.GetCStr())) + return false; + if (path.IsEmpty()) + return true; + if (!Path::IsSameOrSubDir(parent, path)) + return false; - String sub_path = Path::MakeRelativePath(parent, path); - String make_path = parent; - std::vector dirs = sub_path.Split('/'); - for (const String &dir : dirs) - { - if (dir.IsEmpty() || dir.Compare(".") == 0) continue; - make_path.AppendChar('/'); - make_path.Append(dir); - if (!CreateDirectory(make_path)) - return false; - } - return true; + String sub_path = Path::MakeRelativePath(parent, path); + String make_path = parent; + std::vector dirs = sub_path.Split('/'); + for (const String &dir : dirs) { + if (dir.IsEmpty() || dir.Compare(".") == 0) continue; + make_path.AppendChar('/'); + make_path.Append(dir); + if (!CreateDirectory(make_path)) + return false; + } + return true; } -String SetCurrentDirectory(const String &path) -{ - chdir(path); - return GetCurrentDirectory(); +String SetCurrentDirectory(const String &path) { + chdir(path); + return GetCurrentDirectory(); } -String GetCurrentDirectory() -{ - char buf[512]; - getcwd(buf, 512); - String str(buf); - Path::FixupPath(str); - return str; +String GetCurrentDirectory() { + char buf[512]; + getcwd(buf, 512); + String str(buf); + Path::FixupPath(str); + return str; } } // namespace Directory diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h index 85164e9bf106..078f777b760f 100644 --- a/engines/ags/shared/util/directory.h +++ b/engines/ags/shared/util/directory.h @@ -32,22 +32,19 @@ #include "core/platform.h" #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -namespace Directory -{ - // Creates new directory (if it does not exist) - bool CreateDirectory(const String &path); - // Makes sure all directories in the path are created. Parent path is - // not touched, and function must fail if parent path is not accessible. - bool CreateAllDirectories(const String &parent, const String &path); - // Sets current working directory, returns the resulting path - String SetCurrentDirectory(const String &path); - // Gets current working directory - String GetCurrentDirectory(); +namespace Directory { +// Creates new directory (if it does not exist) +bool CreateDirectory(const String &path); +// Makes sure all directories in the path are created. Parent path is +// not touched, and function must fail if parent path is not accessible. +bool CreateAllDirectories(const String &parent, const String &path); +// Sets current working directory, returns the resulting path +String SetCurrentDirectory(const String &path); +// Gets current working directory +String GetCurrentDirectory(); } // namespace Directory } // namespace Common diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h index 7024c37005d2..09ae192346f1 100644 --- a/engines/ags/shared/util/error.h +++ b/engines/ags/shared/util/error.h @@ -33,10 +33,8 @@ #include #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class Error; typedef std::shared_ptr PError; @@ -45,50 +43,54 @@ typedef std::shared_ptr PError; // A simple struct, that provides several fields to describe an error in the program. // If wanted, may be reworked into subclass of std::exception. // -class Error -{ +class Error { public: - Error(int code, String general, PError inner_error = PError()) : _code(code), _general(general), _innerError(inner_error) {} - Error(int code, String general, String comment, PError inner_error = PError()) : _code(code), _general(general), _comment(comment), _innerError(inner_error) {} - Error(String general, PError inner_error = PError()) : _code(0), _general(general), _innerError(inner_error) {} - Error(String general, String comment, PError inner_error = PError()) : _code(0), _general(general), _comment(comment), _innerError(inner_error) {} - - - // Error code is a number, defining error subtype. It is not much use to the end-user, - // but may be checked in the program to know more precise cause of the error. - int Code() const { return _code; } - // General description of this error type and subtype. - String General() const { return _general; } - // Any complementary information. - String Comment() const { return _comment; } - PError InnerError() const { return _innerError; } - // Full error message combines general description and comment. - // NOTE: if made a child of std::exception, FullMessage may be substituted - // or complemented with virtual const char* what(). - String FullMessage() const - { - String msg; - const Error *err = this; - do - { - msg.Append(err->General()); - if (!err->Comment().IsEmpty()) - { - msg.AppendChar('\n'); - msg.Append(err->Comment()); - } - err = err->InnerError().get(); - if (err) - msg.AppendChar('\n'); - } while (err); - return msg; - } + Error(int code, String general, PError inner_error = PError()) : _code(code), _general(general), _innerError(inner_error) {} + Error(int code, String general, String comment, PError inner_error = PError()) : _code(code), _general(general), _comment(comment), _innerError(inner_error) {} + Error(String general, PError inner_error = PError()) : _code(0), _general(general), _innerError(inner_error) {} + Error(String general, String comment, PError inner_error = PError()) : _code(0), _general(general), _comment(comment), _innerError(inner_error) {} + + + // Error code is a number, defining error subtype. It is not much use to the end-user, + // but may be checked in the program to know more precise cause of the error. + int Code() const { + return _code; + } + // General description of this error type and subtype. + String General() const { + return _general; + } + // Any complementary information. + String Comment() const { + return _comment; + } + PError InnerError() const { + return _innerError; + } + // Full error message combines general description and comment. + // NOTE: if made a child of std::exception, FullMessage may be substituted + // or complemented with virtual const char* what(). + String FullMessage() const { + String msg; + const Error *err = this; + do { + msg.Append(err->General()); + if (!err->Comment().IsEmpty()) { + msg.AppendChar('\n'); + msg.Append(err->Comment()); + } + err = err->InnerError().get(); + if (err) + msg.AppendChar('\n'); + } while (err); + return msg; + } private: - int _code; // numeric code, for specific uses - String _general; // general description of this error class - String _comment; // additional information about particular case - PError _innerError; // previous error that caused this one + int _code; // numeric code, for specific uses + String _general; // general description of this error class + String _comment; // additional information about particular case + PError _innerError; // previous error that caused this one }; @@ -101,23 +103,34 @@ class Error // shared_ptr converts to 'true' when it contains an object, but ErrorHandle // returns 'true' when it *does NOT* contain an object, meaning there // is no error. -template class ErrorHandle -{ +template class ErrorHandle { public: - static ErrorHandle None() { return ErrorHandle(); } - - ErrorHandle() = default; - ErrorHandle(T *err) : _error(err) {} - ErrorHandle(std::shared_ptr err) : _error(err) {} - - bool HasError() const { return _error.get() != NULL; } - explicit operator bool() const { return _error.get() == nullptr; } - operator PError() const { return _error; } - T *operator ->() const { return _error.operator->(); } - T &operator *() const { return _error.operator*(); } + static ErrorHandle None() { + return ErrorHandle(); + } + + ErrorHandle() = default; + ErrorHandle(T *err) : _error(err) {} + ErrorHandle(std::shared_ptr err) : _error(err) {} + + bool HasError() const { + return _error.get() != NULL; + } + explicit operator bool() const { + return _error.get() == nullptr; + } + operator PError() const { + return _error; + } + T *operator ->() const { + return _error.operator->(); + } + T &operator *() const { + return _error.operator * (); + } private: - std::shared_ptr _error; + std::shared_ptr _error; }; @@ -128,15 +141,16 @@ typedef ErrorHandle HError; // TypedCodeError is the Error's subclass, which only purpose is to override // error code type in constructor and Code() getter, that may be useful if // you'd like to restrict code values to particular enumerator. -template -class TypedCodeError : public Error -{ +template +class TypedCodeError : public Error { public: - TypedCodeError(CodeType code, PError inner_error = PError()) : Error(code, GetErrorText(code), inner_error) {} - TypedCodeError(CodeType code, String comment, PError inner_error = PError()) : - Error(code, GetErrorText(code), comment, inner_error) {} + TypedCodeError(CodeType code, PError inner_error = PError()) : Error(code, GetErrorText(code), inner_error) {} + TypedCodeError(CodeType code, String comment, PError inner_error = PError()) : + Error(code, GetErrorText(code), comment, inner_error) {} - CodeType Code() const { return (CodeType)Error::Code(); } + CodeType Code() const { + return (CodeType)Error::Code(); + } }; } // namespace Common diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp index 71f2a6368d43..3b597748ded8 100644 --- a/engines/ags/shared/util/file.cpp +++ b/engines/ags/shared/util/file.cpp @@ -29,156 +29,126 @@ #include "util/filestream.h" #include "util/bufferedstream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -soff_t File::GetFileSize(const String &filename) -{ - return ags_file_size(filename.GetCStr()); +soff_t File::GetFileSize(const String &filename) { + return ags_file_size(filename.GetCStr()); } -bool File::TestReadFile(const String &filename) -{ - FILE *test_file = fopen(filename, "rb"); - if (test_file) - { - fclose(test_file); - return true; - } - return false; +bool File::TestReadFile(const String &filename) { + FILE *test_file = fopen(filename, "rb"); + if (test_file) { + fclose(test_file); + return true; + } + return false; } -bool File::TestWriteFile(const String &filename) -{ - FILE *test_file = fopen(filename, "r+"); - if (test_file) - { - fclose(test_file); - return true; - } - return TestCreateFile(filename); +bool File::TestWriteFile(const String &filename) { + FILE *test_file = fopen(filename, "r+"); + if (test_file) { + fclose(test_file); + return true; + } + return TestCreateFile(filename); } -bool File::TestCreateFile(const String &filename) -{ - FILE *test_file = fopen(filename, "wb"); - if (test_file) - { - fclose(test_file); - ::remove(filename); - return true; - } - return false; +bool File::TestCreateFile(const String &filename) { + FILE *test_file = fopen(filename, "wb"); + if (test_file) { + fclose(test_file); + ::remove(filename); + return true; + } + return false; } -bool File::DeleteFile(const String &filename) -{ - if (::remove(filename) != 0) - { - int err; +bool File::DeleteFile(const String &filename) { + if (::remove(filename) != 0) { + int err; #if AGS_PLATFORM_OS_WINDOWS - _get_errno(&err); + _get_errno(&err); #else - err = errno; + err = errno; #endif - if (err == EACCES) - { - return false; - } - } - return true; + if (err == EACCES) { + return false; + } + } + return true; } -bool File::GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, FileWorkMode &work_mode) -{ - // We do not test for 'b' and 't' here, because text mode reading/writing should be done with - // the use of ITextReader and ITextWriter implementations. - // The number of supported variants here is quite limited due the restrictions AGS makes on them. - bool read_base_mode = false; - // Default mode is open/read for safety reasons - open_mode = kFile_Open; - work_mode = kFile_Read; - for (size_t c = 0; c < cmode.GetLength(); ++c) - { - if (read_base_mode) - { - if (cmode[c] == '+') - { - work_mode = kFile_ReadWrite; - } - break; - } - else - { - if (cmode[c] == 'r') - { - open_mode = kFile_Open; - work_mode = kFile_Read; - read_base_mode = true; - } - else if (cmode[c] == 'a') - { - open_mode = kFile_Create; - work_mode = kFile_Write; - read_base_mode = true; - } - else if (cmode[c] == 'w') - { - open_mode = kFile_CreateAlways; - work_mode = kFile_Write; - read_base_mode = true; - } - } - } - return read_base_mode; +bool File::GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, FileWorkMode &work_mode) { + // We do not test for 'b' and 't' here, because text mode reading/writing should be done with + // the use of ITextReader and ITextWriter implementations. + // The number of supported variants here is quite limited due the restrictions AGS makes on them. + bool read_base_mode = false; + // Default mode is open/read for safety reasons + open_mode = kFile_Open; + work_mode = kFile_Read; + for (size_t c = 0; c < cmode.GetLength(); ++c) { + if (read_base_mode) { + if (cmode[c] == '+') { + work_mode = kFile_ReadWrite; + } + break; + } else { + if (cmode[c] == 'r') { + open_mode = kFile_Open; + work_mode = kFile_Read; + read_base_mode = true; + } else if (cmode[c] == 'a') { + open_mode = kFile_Create; + work_mode = kFile_Write; + read_base_mode = true; + } else if (cmode[c] == 'w') { + open_mode = kFile_CreateAlways; + work_mode = kFile_Write; + read_base_mode = true; + } + } + } + return read_base_mode; } -String File::GetCMode(FileOpenMode open_mode, FileWorkMode work_mode) -{ - String mode; - if (open_mode == kFile_Open) - { - if (work_mode == kFile_Read) - mode.AppendChar('r'); - else if (work_mode == kFile_Write || work_mode == kFile_ReadWrite) - mode.Append("r+"); - } - else if (open_mode == kFile_Create) - { - if (work_mode == kFile_Write) - mode.AppendChar('a'); - else if (work_mode == kFile_Read || work_mode == kFile_ReadWrite) - mode.Append("a+"); - } - else if (open_mode == kFile_CreateAlways) - { - if (work_mode == kFile_Write) - mode.AppendChar('w'); - else if (work_mode == kFile_Read || work_mode == kFile_ReadWrite) - mode.Append("w+"); - } - mode.AppendChar('b'); - return mode; +String File::GetCMode(FileOpenMode open_mode, FileWorkMode work_mode) { + String mode; + if (open_mode == kFile_Open) { + if (work_mode == kFile_Read) + mode.AppendChar('r'); + else if (work_mode == kFile_Write || work_mode == kFile_ReadWrite) + mode.Append("r+"); + } else if (open_mode == kFile_Create) { + if (work_mode == kFile_Write) + mode.AppendChar('a'); + else if (work_mode == kFile_Read || work_mode == kFile_ReadWrite) + mode.Append("a+"); + } else if (open_mode == kFile_CreateAlways) { + if (work_mode == kFile_Write) + mode.AppendChar('w'); + else if (work_mode == kFile_Read || work_mode == kFile_ReadWrite) + mode.Append("w+"); + } + mode.AppendChar('b'); + return mode; } -Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode) -{ - FileStream *fs = nullptr; - try { - if (work_mode == kFile_Read) // NOTE: BufferedStream does not work correctly in the write mode - fs = new BufferedStream(filename, open_mode, work_mode); - else - fs = new FileStream(filename, open_mode, work_mode); - if (fs != nullptr && !fs->IsValid()) { - delete fs; - fs = nullptr; - } - } catch(std::runtime_error) { - fs = nullptr; - } - return fs; +Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode) { + FileStream *fs = nullptr; + try { + if (work_mode == kFile_Read) // NOTE: BufferedStream does not work correctly in the write mode + fs = new BufferedStream(filename, open_mode, work_mode); + else + fs = new FileStream(filename, open_mode, work_mode); + if (fs != nullptr && !fs->IsValid()) { + delete fs; + fs = nullptr; + } + } catch (std::runtime_error) { + fs = nullptr; + } + return fs; } } // namespace Common diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h index 5b1d830ab345..e2a9227557d9 100644 --- a/engines/ags/shared/util/file.h +++ b/engines/ags/shared/util/file.h @@ -32,63 +32,55 @@ #include "core/platform.h" #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // Forward declarations class Stream; -enum FileOpenMode -{ - kFile_Open, // Open existing file - kFile_Create, // Create new file, or open existing one - kFile_CreateAlways // Always create a new file, replacing any existing one +enum FileOpenMode { + kFile_Open, // Open existing file + kFile_Create, // Create new file, or open existing one + kFile_CreateAlways // Always create a new file, replacing any existing one }; -enum FileWorkMode -{ - kFile_Read, - kFile_Write, - kFile_ReadWrite +enum FileWorkMode { + kFile_Read, + kFile_Write, + kFile_ReadWrite }; -namespace File -{ - // Returns size of a file, or -1 if no such file found - soff_t GetFileSize(const String &filename); - // Tests if file could be opened for reading - bool TestReadFile(const String &filename); - // Opens a file for writing or creates new one if it does not exist; deletes file if it was created during test - bool TestWriteFile(const String &filename); - // Create new empty file and deletes it; returns TRUE if was able to create file - bool TestCreateFile(const String &filename); - // Deletes existing file; returns TRUE if was able to delete one - bool DeleteFile(const String &filename); +namespace File { +// Returns size of a file, or -1 if no such file found +soff_t GetFileSize(const String &filename); +// Tests if file could be opened for reading +bool TestReadFile(const String &filename); +// Opens a file for writing or creates new one if it does not exist; deletes file if it was created during test +bool TestWriteFile(const String &filename); +// Create new empty file and deletes it; returns TRUE if was able to create file +bool TestCreateFile(const String &filename); +// Deletes existing file; returns TRUE if was able to delete one +bool DeleteFile(const String &filename); - // Sets FileOpenMode and FileWorkMode values corresponding to C-style file open mode string - bool GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, FileWorkMode &work_mode); - // Gets C-style file mode from FileOpenMode and FileWorkMode - String GetCMode(FileOpenMode open_mode, FileWorkMode work_mode); +// Sets FileOpenMode and FileWorkMode values corresponding to C-style file open mode string +bool GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, FileWorkMode &work_mode); +// Gets C-style file mode from FileOpenMode and FileWorkMode +String GetCMode(FileOpenMode open_mode, FileWorkMode work_mode); - Stream *OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode); - // Convenience helpers - // Create a totally new file, overwrite existing one - inline Stream *CreateFile(const String &filename) - { - return OpenFile(filename, kFile_CreateAlways, kFile_Write); - } - // Open existing file for reading - inline Stream *OpenFileRead(const String &filename) - { - return OpenFile(filename, kFile_Open, kFile_Read); - } - // Open existing file for writing (append) or create if it does not exist - inline Stream *OpenFileWrite(const String &filename) - { - return OpenFile(filename, kFile_Create, kFile_Write); - } +Stream *OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode); +// Convenience helpers +// Create a totally new file, overwrite existing one +inline Stream *CreateFile(const String &filename) { + return OpenFile(filename, kFile_CreateAlways, kFile_Write); +} +// Open existing file for reading +inline Stream *OpenFileRead(const String &filename) { + return OpenFile(filename, kFile_Open, kFile_Read); +} +// Open existing file for writing (append) or create if it does not exist +inline Stream *OpenFileWrite(const String &filename) { + return OpenFile(filename, kFile_Create, kFile_Write); +} } // namespace File } // namespace Common diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index 2ce838035772..aa08fa407a7b 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -26,162 +26,138 @@ #include "util/stdio_compat.h" #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { FileStream::FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, - DataEndianess stream_endianess) - : DataStream(stream_endianess) - , _file(nullptr) - , _openMode(open_mode) - , _workMode(work_mode) -{ - Open(file_name, open_mode, work_mode); + DataEndianess stream_endianess) + : DataStream(stream_endianess) + , _file(nullptr) + , _openMode(open_mode) + , _workMode(work_mode) { + Open(file_name, open_mode, work_mode); } -FileStream::~FileStream() -{ - FileStream::Close(); +FileStream::~FileStream() { + FileStream::Close(); } -bool FileStream::HasErrors() const -{ - return IsValid() && ferror(_file) != 0; +bool FileStream::HasErrors() const { + return IsValid() && ferror(_file) != 0; } -void FileStream::Close() -{ - if (_file) - { - fclose(_file); - } - _file = nullptr; +void FileStream::Close() { + if (_file) { + fclose(_file); + } + _file = nullptr; } -bool FileStream::Flush() -{ - if (_file) - { - return fflush(_file) == 0; - } - return false; +bool FileStream::Flush() { + if (_file) { + return fflush(_file) == 0; + } + return false; } -bool FileStream::IsValid() const -{ - return _file != nullptr; +bool FileStream::IsValid() const { + return _file != nullptr; } -bool FileStream::EOS() const -{ - return !IsValid() || feof(_file) != 0; +bool FileStream::EOS() const { + return !IsValid() || feof(_file) != 0; } -soff_t FileStream::GetLength() const -{ - if (IsValid()) - { - soff_t pos = (soff_t)ags_ftell(_file); - ags_fseek(_file, 0, SEEK_END); - soff_t end = (soff_t)ags_ftell(_file); - ags_fseek(_file, pos, SEEK_SET); - return end; - } +soff_t FileStream::GetLength() const { + if (IsValid()) { + soff_t pos = (soff_t)ags_ftell(_file); + ags_fseek(_file, 0, SEEK_END); + soff_t end = (soff_t)ags_ftell(_file); + ags_fseek(_file, pos, SEEK_SET); + return end; + } - return 0; + return 0; } -soff_t FileStream::GetPosition() const -{ - if (IsValid()) - { - return (soff_t) ags_ftell(_file); - } - return -1; +soff_t FileStream::GetPosition() const { + if (IsValid()) { + return (soff_t) ags_ftell(_file); + } + return -1; } -bool FileStream::CanRead() const -{ - return IsValid() && _workMode != kFile_Write; +bool FileStream::CanRead() const { + return IsValid() && _workMode != kFile_Write; } -bool FileStream::CanWrite() const -{ - return IsValid() && _workMode != kFile_Read; +bool FileStream::CanWrite() const { + return IsValid() && _workMode != kFile_Read; } -bool FileStream::CanSeek() const -{ - return IsValid(); +bool FileStream::CanSeek() const { + return IsValid(); } -size_t FileStream::Read(void *buffer, size_t size) -{ - if (_file && buffer) - { - return fread(buffer, sizeof(uint8_t), size, _file); - } - return 0; +size_t FileStream::Read(void *buffer, size_t size) { + if (_file && buffer) { + return fread(buffer, sizeof(uint8_t), size, _file); + } + return 0; } -int32_t FileStream::ReadByte() -{ - if (_file) - { - return fgetc(_file); - } - return -1; +int32_t FileStream::ReadByte() { + if (_file) { + return fgetc(_file); + } + return -1; } -size_t FileStream::Write(const void *buffer, size_t size) -{ - if (_file && buffer) - { - return fwrite(buffer, sizeof(uint8_t), size, _file); - } - return 0; +size_t FileStream::Write(const void *buffer, size_t size) { + if (_file && buffer) { + return fwrite(buffer, sizeof(uint8_t), size, _file); + } + return 0; } -int32_t FileStream::WriteByte(uint8_t val) -{ - if (_file) - { - return fputc(val, _file); - } - return -1; -} - -bool FileStream::Seek(soff_t offset, StreamSeek origin) -{ - if (!_file) - { - return false; - } +int32_t FileStream::WriteByte(uint8_t val) { + if (_file) { + return fputc(val, _file); + } + return -1; +} + +bool FileStream::Seek(soff_t offset, StreamSeek origin) { + if (!_file) { + return false; + } - int stdclib_origin; - switch (origin) - { - case kSeekBegin: stdclib_origin = SEEK_SET; break; - case kSeekCurrent: stdclib_origin = SEEK_CUR; break; - case kSeekEnd: stdclib_origin = SEEK_END; break; - default: - // TODO: warning to the log - return false; - } - - return ags_fseek(_file, (file_off_t)offset, stdclib_origin) == 0; + int stdclib_origin; + switch (origin) { + case kSeekBegin: + stdclib_origin = SEEK_SET; + break; + case kSeekCurrent: + stdclib_origin = SEEK_CUR; + break; + case kSeekEnd: + stdclib_origin = SEEK_END; + break; + default: + // TODO: warning to the log + return false; + } + + return ags_fseek(_file, (file_off_t)offset, stdclib_origin) == 0; } - -void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode) -{ - String mode = File::GetCMode(open_mode, work_mode); - if (mode.IsEmpty()) - throw std::runtime_error("Error determining open mode"); - _file = fopen(file_name, mode); - if (_file == nullptr) - throw std::runtime_error("Error opening file."); + +void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode) { + String mode = File::GetCMode(open_mode, work_mode); + if (mode.IsEmpty()) + throw std::runtime_error("Error determining open mode"); + _file = fopen(file_name, mode); + if (_file == nullptr) + throw std::runtime_error("Error opening file."); } } // namespace Common diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index 4397b0dd28e6..231f42ea7ad8 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -28,52 +28,49 @@ #include "util/datastream.h" #include "util/file.h" // TODO: extract filestream mode constants -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class FileStream : public DataStream -{ +class FileStream : public DataStream { public: - // Represents an open file object - // The constructor may raise std::runtime_error if - // - there is an issue opening the file (does not exist, locked, permissions, etc) - // - the open mode could not be determined - FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, - DataEndianess stream_endianess = kLittleEndian); - ~FileStream() override; + // Represents an open file object + // The constructor may raise std::runtime_error if + // - there is an issue opening the file (does not exist, locked, permissions, etc) + // - the open mode could not be determined + FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, + DataEndianess stream_endianess = kLittleEndian); + ~FileStream() override; - bool HasErrors() const override; - void Close() override; - bool Flush() override; + bool HasErrors() const override; + void Close() override; + bool Flush() override; - // Is stream valid (underlying data initialized properly) - bool IsValid() const override; - // Is end of stream - bool EOS() const override; - // Total length of stream (if known) - soff_t GetLength() const override; - // Current position (if known) - soff_t GetPosition() const override; - bool CanRead() const override; - bool CanWrite() const override; - bool CanSeek() const override; + // Is stream valid (underlying data initialized properly) + bool IsValid() const override; + // Is end of stream + bool EOS() const override; + // Total length of stream (if known) + soff_t GetLength() const override; + // Current position (if known) + soff_t GetPosition() const override; + bool CanRead() const override; + bool CanWrite() const override; + bool CanSeek() const override; - size_t Read(void *buffer, size_t size) override; - int32_t ReadByte() override; - size_t Write(const void *buffer, size_t size) override; - int32_t WriteByte(uint8_t b) override; + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; - bool Seek(soff_t offset, StreamSeek origin) override; + bool Seek(soff_t offset, StreamSeek origin) override; private: - void Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode); + void Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode); - FILE *_file; - const FileOpenMode _openMode; - const FileWorkMode _workMode; + FILE *_file; + const FileOpenMode _openMode; + const FileWorkMode _workMode; }; } // namespace Common diff --git a/engines/ags/shared/util/geometry.cpp b/engines/ags/shared/util/geometry.cpp index 5bde02d5b7b1..c4e4c9a8932c 100644 --- a/engines/ags/shared/util/geometry.cpp +++ b/engines/ags/shared/util/geometry.cpp @@ -29,113 +29,100 @@ //namespace Common //{ -bool AreRectsIntersecting(const Rect &r1, const Rect &r2) -{ // NOTE: remember that in AGS Y axis is pointed downwards - return r1.Left <= r2.Right && r1.Right >= r2.Left && - r1.Top <= r2.Bottom && r1.Bottom >= r2.Top; +bool AreRectsIntersecting(const Rect &r1, const Rect &r2) { + // NOTE: remember that in AGS Y axis is pointed downwards + return r1.Left <= r2.Right && r1.Right >= r2.Left && + r1.Top <= r2.Bottom && r1.Bottom >= r2.Top; } -bool IsRectInsideRect(const Rect &place, const Rect &item) -{ - return item.Left >= place.Left && item.Right <= place.Right && - item.Top >= place.Top && item.Bottom <= place.Bottom; +bool IsRectInsideRect(const Rect &place, const Rect &item) { + return item.Left >= place.Left && item.Right <= place.Right && + item.Top >= place.Top && item.Bottom <= place.Bottom; } -float DistanceBetween(const Rect &r1, const Rect &r2) -{ - // https://gamedev.stackexchange.com/a/154040 - Rect rect_outer( - std::min(r1.Left, r2.Left), - std::min(r1.Top, r2.Top), - std::max(r1.Right, r2.Right), - std::max(r1.Bottom, r2.Bottom) - ); - int inner_width = std::max(0, rect_outer.GetWidth() - r1.GetWidth() - r2.GetWidth()); - int inner_height = std::max(0, rect_outer.GetHeight() - r1.GetHeight() - r2.GetHeight()); - return std::sqrt(inner_width ^ 2 + inner_height ^ 2); +float DistanceBetween(const Rect &r1, const Rect &r2) { + // https://gamedev.stackexchange.com/a/154040 + Rect rect_outer( + std::min(r1.Left, r2.Left), + std::min(r1.Top, r2.Top), + std::max(r1.Right, r2.Right), + std::max(r1.Bottom, r2.Bottom) + ); + int inner_width = std::max(0, rect_outer.GetWidth() - r1.GetWidth() - r2.GetWidth()); + int inner_height = std::max(0, rect_outer.GetHeight() - r1.GetHeight() - r2.GetHeight()); + return std::sqrt(inner_width ^ 2 + inner_height ^ 2); } -Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h) -{ - int width = item_w ? dest_w : 0; - int height = item_w ? (dest_w * item_h / item_w) : 0; - if (height > dest_h) - { - width = item_h ? (dest_h * item_w / item_h) : 0; - height = dest_h; - } - return Size(width, height); +Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h) { + int width = item_w ? dest_w : 0; + int height = item_w ? (dest_w * item_h / item_w) : 0; + if (height > dest_h) { + width = item_h ? (dest_h * item_w / item_h) : 0; + height = dest_h; + } + return Size(width, height); } -Size ProportionalStretch(const Size &dest, const Size &item) -{ - return ProportionalStretch(dest.Width, dest.Height, item.Width, item.Height); +Size ProportionalStretch(const Size &dest, const Size &item) { + return ProportionalStretch(dest.Width, dest.Height, item.Width, item.Height); } -int AlignInHRange(int x1, int x2, int off_x, int width, FrameAlignment align) -{ - if (align & kMAlignRight) - return off_x + x2 - width; - else if (align & kMAlignHCenter) - return off_x + x1 + ((x2 - x1 + 1) >> 1) - (width >> 1); - return off_x + x1; // kAlignLeft is default +int AlignInHRange(int x1, int x2, int off_x, int width, FrameAlignment align) { + if (align & kMAlignRight) + return off_x + x2 - width; + else if (align & kMAlignHCenter) + return off_x + x1 + ((x2 - x1 + 1) >> 1) - (width >> 1); + return off_x + x1; // kAlignLeft is default } -int AlignInVRange(int y1, int y2, int off_y, int height, FrameAlignment align) -{ - if (align & kMAlignBottom) - return off_y + y2 - height; - else if (align & kMAlignVCenter) - return off_y + y1 + ((y2 - y1 + 1) >> 1) - (height >> 1); - return off_y + y1; // kAlignTop is default +int AlignInVRange(int y1, int y2, int off_y, int height, FrameAlignment align) { + if (align & kMAlignBottom) + return off_y + y2 - height; + else if (align & kMAlignVCenter) + return off_y + y1 + ((y2 - y1 + 1) >> 1) - (height >> 1); + return off_y + y1; // kAlignTop is default } -Rect AlignInRect(const Rect &frame, const Rect &item, FrameAlignment align) -{ - int x = AlignInHRange(frame.Left, frame.Right, item.Left, item.GetWidth(), align); - int y = AlignInVRange(frame.Top, frame.Bottom, item.Top, item.GetHeight(), align); +Rect AlignInRect(const Rect &frame, const Rect &item, FrameAlignment align) { + int x = AlignInHRange(frame.Left, frame.Right, item.Left, item.GetWidth(), align); + int y = AlignInVRange(frame.Top, frame.Bottom, item.Top, item.GetHeight(), align); - Rect dst_item = item; - dst_item.MoveTo(Point(x, y)); - return dst_item; + Rect dst_item = item; + dst_item.MoveTo(Point(x, y)); + return dst_item; } -Rect OffsetRect(const Rect &r, const Point off) -{ - return Rect(r.Left + off.X, r.Top + off.Y, r.Right + off.X, r.Bottom + off.Y); +Rect OffsetRect(const Rect &r, const Point off) { + return Rect(r.Left + off.X, r.Top + off.Y, r.Right + off.X, r.Bottom + off.Y); } -Rect CenterInRect(const Rect &place, const Rect &item) -{ - return RectWH((place.GetWidth() >> 1) - (item.GetWidth() >> 1), - (place.GetHeight() >> 1) - (item.GetHeight() >> 1), - item.GetWidth(), item.GetHeight()); +Rect CenterInRect(const Rect &place, const Rect &item) { + return RectWH((place.GetWidth() >> 1) - (item.GetWidth() >> 1), + (place.GetHeight() >> 1) - (item.GetHeight() >> 1), + item.GetWidth(), item.GetHeight()); } -Rect ClampToRect(const Rect &place, const Rect &item) -{ - return Rect( - AGSMath::Clamp(item.Left, place.Left, place.Right), - AGSMath::Clamp(item.Top, place.Top, place.Bottom), - AGSMath::Clamp(item.Right, place.Left, place.Right), - AGSMath::Clamp(item.Bottom, place.Top, place.Bottom) - ); +Rect ClampToRect(const Rect &place, const Rect &item) { + return Rect( + AGSMath::Clamp(item.Left, place.Left, place.Right), + AGSMath::Clamp(item.Top, place.Top, place.Bottom), + AGSMath::Clamp(item.Right, place.Left, place.Right), + AGSMath::Clamp(item.Bottom, place.Top, place.Bottom) + ); } -Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement) -{ - switch (placement) - { - case kPlaceCenter: - return CenterInRect(place, item); - case kPlaceStretch: - return place; - case kPlaceStretchProportional: - return CenterInRect(place, - RectWH(ProportionalStretch(place.GetWidth(), place.GetHeight(), item.GetWidth(), item.GetHeight()))); - default: - return RectWH(place.Left + item.Left, place.Top + item.Top, item.GetWidth(), item.GetHeight()); - } +Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement) { + switch (placement) { + case kPlaceCenter: + return CenterInRect(place, item); + case kPlaceStretch: + return place; + case kPlaceStretchProportional: + return CenterInRect(place, + RectWH(ProportionalStretch(place.GetWidth(), place.GetHeight(), item.GetWidth(), item.GetHeight()))); + default: + return RectWH(place.Left + item.Left, place.Top + item.Top, item.GetWidth(), item.GetHeight()); + } } //} // namespace Common diff --git a/engines/ags/shared/util/geometry.h b/engines/ags/shared/util/geometry.h index c0ebbaa9b526..a40b0b475d4c 100644 --- a/engines/ags/shared/util/geometry.h +++ b/engines/ags/shared/util/geometry.h @@ -38,104 +38,92 @@ namespace AGSMath = AGS::Common::Math; //{ // Type of alignment of a geometric item of rectangular boundaries. -enum FrameAlignment -{ - kAlignNone = 0, - - // Alignment options are representing 8 sides of a frame (rectangle); - // they are implemented as flags that may be combined together if it - // is wanted to define alignment to multiple sides at once. - kAlignTopLeft = 0x0001, - kAlignTopCenter = 0x0002, - kAlignTopRight = 0x0004, - kAlignMiddleLeft = 0x0008, - kAlignMiddleCenter = 0x0010, - kAlignMiddleRight = 0x0020, - kAlignBottomLeft = 0x0040, - kAlignBottomCenter = 0x0080, - kAlignBottomRight = 0x0100, - - // Masks are helping to determine whether alignment parameter contains - // particular horizontal or vertical component (for example: left side - // or bottom side) - kMAlignLeft = kAlignTopLeft | kAlignMiddleLeft | kAlignBottomLeft, - kMAlignRight = kAlignTopRight | kAlignMiddleRight | kAlignBottomRight, - kMAlignTop = kAlignTopLeft | kAlignTopCenter | kAlignTopRight, - kMAlignBottom = kAlignBottomLeft | kAlignBottomCenter | kAlignBottomRight, - kMAlignHCenter = kAlignTopCenter | kAlignMiddleCenter | kAlignBottomCenter, - kMAlignVCenter = kAlignMiddleLeft | kAlignMiddleCenter | kAlignMiddleRight +enum FrameAlignment { + kAlignNone = 0, + + // Alignment options are representing 8 sides of a frame (rectangle); + // they are implemented as flags that may be combined together if it + // is wanted to define alignment to multiple sides at once. + kAlignTopLeft = 0x0001, + kAlignTopCenter = 0x0002, + kAlignTopRight = 0x0004, + kAlignMiddleLeft = 0x0008, + kAlignMiddleCenter = 0x0010, + kAlignMiddleRight = 0x0020, + kAlignBottomLeft = 0x0040, + kAlignBottomCenter = 0x0080, + kAlignBottomRight = 0x0100, + + // Masks are helping to determine whether alignment parameter contains + // particular horizontal or vertical component (for example: left side + // or bottom side) + kMAlignLeft = kAlignTopLeft | kAlignMiddleLeft | kAlignBottomLeft, + kMAlignRight = kAlignTopRight | kAlignMiddleRight | kAlignBottomRight, + kMAlignTop = kAlignTopLeft | kAlignTopCenter | kAlignTopRight, + kMAlignBottom = kAlignBottomLeft | kAlignBottomCenter | kAlignBottomRight, + kMAlignHCenter = kAlignTopCenter | kAlignMiddleCenter | kAlignBottomCenter, + kMAlignVCenter = kAlignMiddleLeft | kAlignMiddleCenter | kAlignMiddleRight }; // Horizontal alignment; based on FrameAlignment, used to restrict alignment // setting to left/right/center option, while keeping compatibility with any // alignment in case it will be supported in the future. -enum HorAlignment -{ - kHAlignNone = kAlignNone, - kHAlignLeft = kAlignTopLeft, - kHAlignRight = kAlignTopRight, - kHAlignCenter = kAlignTopCenter +enum HorAlignment { + kHAlignNone = kAlignNone, + kHAlignLeft = kAlignTopLeft, + kHAlignRight = kAlignTopRight, + kHAlignCenter = kAlignTopCenter }; -enum RectPlacement -{ - kPlaceOffset, - kPlaceCenter, - kPlaceStretch, - kPlaceStretchProportional, - kNumRectPlacement +enum RectPlacement { + kPlaceOffset, + kPlaceCenter, + kPlaceStretch, + kPlaceStretchProportional, + kNumRectPlacement }; -struct Point -{ - int X; - int Y; - - Point() - { - X = 0; - Y = 0; - } - - Point(int x, int y) - { - X = x; - Y = y; - } - - inline bool operator ==(const Point &p) const - { - return X == p.X && Y == p.Y; - } - - inline bool operator !=(const Point &p) const - { - return X != p.X || Y != p.Y; - } - - inline Point operator +(const Point &p) const - { - return Point(X + p.X, Y + p.Y); - } +struct Point { + int X; + int Y; + + Point() { + X = 0; + Y = 0; + } + + Point(int x, int y) { + X = x; + Y = y; + } + + inline bool operator ==(const Point &p) const { + return X == p.X && Y == p.Y; + } + + inline bool operator !=(const Point &p) const { + return X != p.X || Y != p.Y; + } + + inline Point operator +(const Point &p) const { + return Point(X + p.X, Y + p.Y); + } }; -struct Line -{ +struct Line { int X1; int Y1; int X2; int Y2; - Line() - { + Line() { X1 = 0; Y1 = 0; X2 = 0; Y2 = 0; } - Line(int x1, int y1, int x2, int y2) - { + Line(int x1, int y1, int x2, int y2) { X1 = x1; Y1 = y1; X2 = x2; @@ -144,203 +132,169 @@ struct Line }; // Helper factory functions -inline Line HLine(int x1, int x2, int y) -{ +inline Line HLine(int x1, int x2, int y) { return Line(x1, y, x2, y); } -inline Line VLine(int x, int y1, int y2) -{ +inline Line VLine(int x, int y1, int y2) { return Line(x, y1, x, y2); } -struct Size -{ - int Width; - int Height; - - Size() - { - Width = 0; - Height = 0; - } - - Size(int width, int height) - { - Width = width; - Height = height; - } - - inline bool IsNull() const - { - return Width <= 0 || Height <= 0; - } - - inline static Size Clamp(const Size &sz, const Size &floor, const Size &ceil) - { - return Size(AGSMath::Clamp(sz.Width, floor.Width, ceil.Width), - AGSMath::Clamp(sz.Height, floor.Height, ceil.Height)); - } - - // Indicates if current size exceeds other size by any metric - inline bool ExceedsByAny(const Size size) const - { - return Width > size.Width || Height > size.Height; - } - - inline bool operator==(const Size size) const - { - return Width == size.Width && Height == size.Height; - } - - inline bool operator!=(const Size size) const - { - return Width != size.Width || Height != size.Height; - } - - inline bool operator<(const Size &other) const - { // TODO: this implementation is silly and not universally useful; make a realistic one and replace with another function where necessary - return Width < other.Width || (Width == other.Width && Height < other.Height); - } - - inline Size operator *(int x) const - { - return Size(Width * x, Height * x); - } - - inline Size operator /(int x) const - { - return Size(Width / x, Height / x); - } - - inline Size &operator *=(int x) - { - Width *= x; - Height *= x; - return *this; - } - - inline Size &operator /=(int x) - { - Width /= x; - Height /= x; - return *this; - } +struct Size { + int Width; + int Height; + + Size() { + Width = 0; + Height = 0; + } + + Size(int width, int height) { + Width = width; + Height = height; + } + + inline bool IsNull() const { + return Width <= 0 || Height <= 0; + } + + inline static Size Clamp(const Size &sz, const Size &floor, const Size &ceil) { + return Size(AGSMath::Clamp(sz.Width, floor.Width, ceil.Width), + AGSMath::Clamp(sz.Height, floor.Height, ceil.Height)); + } + + // Indicates if current size exceeds other size by any metric + inline bool ExceedsByAny(const Size size) const { + return Width > size.Width || Height > size.Height; + } + + inline bool operator==(const Size size) const { + return Width == size.Width && Height == size.Height; + } + + inline bool operator!=(const Size size) const { + return Width != size.Width || Height != size.Height; + } + + inline bool operator<(const Size &other) const { + // TODO: this implementation is silly and not universally useful; make a realistic one and replace with another function where necessary + return Width < other.Width || (Width == other.Width && Height < other.Height); + } + + inline Size operator *(int x) const { + return Size(Width * x, Height * x); + } + + inline Size operator /(int x) const { + return Size(Width / x, Height / x); + } + + inline Size &operator *=(int x) { + Width *= x; + Height *= x; + return *this; + } + + inline Size &operator /=(int x) { + Width /= x; + Height /= x; + return *this; + } }; // TODO: consider making Rect have right-bottom coordinate with +1 offset // to comply with many other libraries (i.e. Right - Left == Width) -struct Rect -{ +struct Rect { int Left; int Top; int Right; int Bottom; - Rect() - { - Left = 0; - Top = 0; - Right = -1; - Bottom = -1; + Rect() { + Left = 0; + Top = 0; + Right = -1; + Bottom = -1; } - Rect(int l, int t, int r, int b) - { - Left = l; - Top = t; - Right = r; - Bottom = b; + Rect(int l, int t, int r, int b) { + Left = l; + Top = t; + Right = r; + Bottom = b; } - inline Point GetLT() const - { - return Point(Left, Top); - } + inline Point GetLT() const { + return Point(Left, Top); + } - inline Point GetCenter() const - { - return Point(Left + GetWidth() / 2, Top + GetHeight() / 2); - } + inline Point GetCenter() const { + return Point(Left + GetWidth() / 2, Top + GetHeight() / 2); + } - inline int GetWidth() const - { + inline int GetWidth() const { return Right - Left + 1; } - inline int GetHeight() const - { + inline int GetHeight() const { return Bottom - Top + 1; } - inline Size GetSize() const - { - return Size(GetWidth(), GetHeight()); - } - - inline bool IsEmpty() const - { - return Right < Left || Bottom < Top; - } - - inline bool IsInside(int x, int y) const - { - return x >= Left && y >= Top && (x <= Right) && (y <= Bottom); - } - - inline bool IsInside(const Point &pt) const - { - return IsInside(pt.X, pt.Y); - } - - inline void MoveToX(int x) - { - Right += x - Left; - Left = x; - } - - inline void MoveToY(int y) - { - Bottom += y - Top; - Top = y; - } - - inline void MoveTo(const Point &pt) - { - MoveToX(pt.X); - MoveToY(pt.Y); - } - - inline void SetWidth(int width) - { - Right = Left + width - 1; - } - - inline void SetHeight(int height) - { - Bottom = Top + height - 1; - } - - inline static Rect MoveBy(const Rect &r, int x, int y) - { - return Rect(r.Left + x, r.Top + y, r.Right + x, r.Bottom + y); - } + inline Size GetSize() const { + return Size(GetWidth(), GetHeight()); + } + + inline bool IsEmpty() const { + return Right < Left || Bottom < Top; + } + + inline bool IsInside(int x, int y) const { + return x >= Left && y >= Top && (x <= Right) && (y <= Bottom); + } + + inline bool IsInside(const Point &pt) const { + return IsInside(pt.X, pt.Y); + } + + inline void MoveToX(int x) { + Right += x - Left; + Left = x; + } + + inline void MoveToY(int y) { + Bottom += y - Top; + Top = y; + } + + inline void MoveTo(const Point &pt) { + MoveToX(pt.X); + MoveToY(pt.Y); + } + + inline void SetWidth(int width) { + Right = Left + width - 1; + } + + inline void SetHeight(int height) { + Bottom = Top + height - 1; + } + + inline static Rect MoveBy(const Rect &r, int x, int y) { + return Rect(r.Left + x, r.Top + y, r.Right + x, r.Bottom + y); + } }; // Helper factory function -inline Rect RectWH(int x, int y, int width, int height) -{ +inline Rect RectWH(int x, int y, int width, int height) { return Rect(x, y, x + width - 1, y + height - 1); } -inline Rect RectWH(const Size &sz) -{ - return Rect(0, 0, sz.Width - 1, sz.Height - 1); +inline Rect RectWH(const Size &sz) { + return Rect(0, 0, sz.Width - 1, sz.Height - 1); } -struct Triangle -{ +struct Triangle { int X1; int Y1; int X2; @@ -348,8 +302,7 @@ struct Triangle int X3; int Y3; - Triangle() - { + Triangle() { X1 = 0; Y1 = 0; X2 = 0; @@ -358,8 +311,7 @@ struct Triangle Y3 = 0; } - Triangle(int x1, int y1, int x2, int y2, int x3, int y3) - { + Triangle(int x1, int y1, int x2, int y2, int x3, int y3) { X1 = x1; Y1 = y1; X2 = x2; @@ -369,21 +321,18 @@ struct Triangle } }; -struct Circle -{ +struct Circle { int X; int Y; int Radius; - Circle() - { + Circle() { X = 0; Y = 0; Radius = 0; } - Circle(int x, int y, int radius) - { + Circle(int x, int y, int radius) { X = x; Y = y; Radius = radius; diff --git a/engines/ags/shared/util/ini_util.cpp b/engines/ags/shared/util/ini_util.cpp index 5557da9cf268..b18321f256e3 100644 --- a/engines/ags/shared/util/ini_util.cpp +++ b/engines/ags/shared/util/ini_util.cpp @@ -27,10 +27,8 @@ #include "util/stream.h" #include "util/textstreamwriter.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { typedef std::unique_ptr UStream; typedef IniFile::SectionIterator SectionIterator; @@ -38,164 +36,147 @@ typedef IniFile::ConstSectionIterator CSectionIterator; typedef IniFile::ItemIterator ItemIterator; typedef IniFile::ConstItemIterator CItemIterator; -static bool ReadIni(const String &file, IniFile &ini) -{ - UStream fs(File::OpenFileRead(file)); - if (fs.get()) - { - ini.Read(fs.get()); - return true; - } - return false; +static bool ReadIni(const String &file, IniFile &ini) { + UStream fs(File::OpenFileRead(file)); + if (fs.get()) { + ini.Read(fs.get()); + return true; + } + return false; } -bool IniUtil::Read(const String &file, ConfigTree &tree) -{ - // Read ini content - IniFile ini; - if (!ReadIni(file, ini)) - return false; - - // Copy items into key-value tree - for (CSectionIterator sec = ini.CBegin(); sec != ini.CEnd(); ++sec) - { - if (!sec->GetItemCount()) - continue; // skip empty sections - StringOrderMap &subtree = tree[sec->GetName()]; - for (CItemIterator item = sec->CBegin(); item != sec->CEnd(); ++item) - { - if (!item->IsKeyValue()) - continue; // skip non key-value items - subtree[item->GetKey()] = item->GetValue(); - } - } - return true; +bool IniUtil::Read(const String &file, ConfigTree &tree) { + // Read ini content + IniFile ini; + if (!ReadIni(file, ini)) + return false; + + // Copy items into key-value tree + for (CSectionIterator sec = ini.CBegin(); sec != ini.CEnd(); ++sec) { + if (!sec->GetItemCount()) + continue; // skip empty sections + StringOrderMap &subtree = tree[sec->GetName()]; + for (CItemIterator item = sec->CBegin(); item != sec->CEnd(); ++item) { + if (!item->IsKeyValue()) + continue; // skip non key-value items + subtree[item->GetKey()] = item->GetValue(); + } + } + return true; } -void IniUtil::Write(const String &file, const ConfigTree &tree) -{ - UStream fs(File::CreateFile(file)); - TextStreamWriter writer(fs.get()); - - for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) - { - const String &sec_key = it_sec->first; - const StringOrderMap &sec_tree = it_sec->second; - - if (!sec_tree.size()) - continue; // skip empty sections - // write section name - if (!sec_key.IsEmpty()) - { - writer.WriteFormat("[%s]", sec_key.GetCStr()); - writer.WriteLineBreak(); - } - // write all items - for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) - { - const String &item_key = keyval->first; - const String &item_value = keyval->second; - - writer.WriteFormat("%s = %s", item_key.GetCStr(), item_value.GetCStr()); - writer.WriteLineBreak(); - } - } - - writer.ReleaseStream(); +void IniUtil::Write(const String &file, const ConfigTree &tree) { + UStream fs(File::CreateFile(file)); + TextStreamWriter writer(fs.get()); + + for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) { + const String &sec_key = it_sec->first; + const StringOrderMap &sec_tree = it_sec->second; + + if (!sec_tree.size()) + continue; // skip empty sections + // write section name + if (!sec_key.IsEmpty()) { + writer.WriteFormat("[%s]", sec_key.GetCStr()); + writer.WriteLineBreak(); + } + // write all items + for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) { + const String &item_key = keyval->first; + const String &item_value = keyval->second; + + writer.WriteFormat("%s = %s", item_key.GetCStr(), item_value.GetCStr()); + writer.WriteLineBreak(); + } + } + + writer.ReleaseStream(); } -void IniUtil::WriteToString(String &s, const ConfigTree &tree) -{ - for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) - { - const String &sec_key = it_sec->first; - const StringOrderMap &sec_tree = it_sec->second; - if (!sec_tree.size()) - continue; // skip empty sections - // write section name - if (!sec_key.IsEmpty()) - s.Append(String::FromFormat("[%s]\n", sec_key.GetCStr())); - // write all items - for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) - s.Append(String::FromFormat("%s = %s\n", keyval->first.GetCStr(), keyval->second.GetCStr())); - } +void IniUtil::WriteToString(String &s, const ConfigTree &tree) { + for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) { + const String &sec_key = it_sec->first; + const StringOrderMap &sec_tree = it_sec->second; + if (!sec_tree.size()) + continue; // skip empty sections + // write section name + if (!sec_key.IsEmpty()) + s.Append(String::FromFormat("[%s]\n", sec_key.GetCStr())); + // write all items + for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) + s.Append(String::FromFormat("%s = %s\n", keyval->first.GetCStr(), keyval->second.GetCStr())); + } } -bool IniUtil::Merge(const String &file, const ConfigTree &tree) -{ - // Read ini content - IniFile ini; - ReadIni(file, ini); // NOTE: missing file is a valid case - - // Remember the sections we find in file, if some sections are not found, - // they will be appended to the end of file. - std::map sections_found; - for (ConfigNode it = tree.begin(); it != tree.end(); ++it) - sections_found[it->first] = false; - - // Merge existing sections - for (SectionIterator sec = ini.Begin(); sec != ini.End(); ++sec) - { - if (!sec->GetItemCount()) - continue; // skip empty sections - String secname = sec->GetName(); - ConfigNode tree_node = tree.find(secname); - if (tree_node == tree.end()) - continue; // this section is not interesting for us - - // Remember the items we find in this section, if some items are not found, - // they will be appended to the end of section. - const StringOrderMap &subtree = tree_node->second; - std::map items_found; - for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) - items_found[keyval->first] = false; - - // Replace matching items - for (ItemIterator item = sec->Begin(); item != sec->End(); ++item) - { - String key = item->GetKey(); - StrStrOIter keyval = subtree.find(key); - if (keyval == subtree.end()) - continue; // this item is not interesting for us - - String old_value = item->GetValue(); - String new_value = keyval->second; - if (old_value != new_value) - item->SetValue(new_value); - items_found[key] = true; - } - - // Append new items - if (!sections_found[secname]) - { - for (std::map::const_iterator item_f = items_found.begin(); item_f != items_found.end(); ++item_f) - { - if (item_f->second) - continue; // item was already found - StrStrOIter keyval = subtree.find(item_f->first); - ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); - } - sections_found[secname] = true; // mark section as known - } - } - - // Add new sections - for (std::map::const_iterator sec_f = sections_found.begin(); sec_f != sections_found.end(); ++sec_f) - { - if (sec_f->second) - continue; - SectionIterator sec = ini.InsertSection(ini.End(), sec_f->first); - const StringOrderMap &subtree = tree.find(sec_f->first)->second; - for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) - ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); - } - - // Write the resulting set of lines - UStream fs(File::CreateFile(file)); - if (!fs.get()) - return false; - ini.Write(fs.get()); - return true; +bool IniUtil::Merge(const String &file, const ConfigTree &tree) { + // Read ini content + IniFile ini; + ReadIni(file, ini); // NOTE: missing file is a valid case + + // Remember the sections we find in file, if some sections are not found, + // they will be appended to the end of file. + std::map sections_found; + for (ConfigNode it = tree.begin(); it != tree.end(); ++it) + sections_found[it->first] = false; + + // Merge existing sections + for (SectionIterator sec = ini.Begin(); sec != ini.End(); ++sec) { + if (!sec->GetItemCount()) + continue; // skip empty sections + String secname = sec->GetName(); + ConfigNode tree_node = tree.find(secname); + if (tree_node == tree.end()) + continue; // this section is not interesting for us + + // Remember the items we find in this section, if some items are not found, + // they will be appended to the end of section. + const StringOrderMap &subtree = tree_node->second; + std::map items_found; + for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) + items_found[keyval->first] = false; + + // Replace matching items + for (ItemIterator item = sec->Begin(); item != sec->End(); ++item) { + String key = item->GetKey(); + StrStrOIter keyval = subtree.find(key); + if (keyval == subtree.end()) + continue; // this item is not interesting for us + + String old_value = item->GetValue(); + String new_value = keyval->second; + if (old_value != new_value) + item->SetValue(new_value); + items_found[key] = true; + } + + // Append new items + if (!sections_found[secname]) { + for (std::map::const_iterator item_f = items_found.begin(); item_f != items_found.end(); ++item_f) { + if (item_f->second) + continue; // item was already found + StrStrOIter keyval = subtree.find(item_f->first); + ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); + } + sections_found[secname] = true; // mark section as known + } + } + + // Add new sections + for (std::map::const_iterator sec_f = sections_found.begin(); sec_f != sections_found.end(); ++sec_f) { + if (sec_f->second) + continue; + SectionIterator sec = ini.InsertSection(ini.End(), sec_f->first); + const StringOrderMap &subtree = tree.find(sec_f->first)->second; + for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) + ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); + } + + // Write the resulting set of lines + UStream fs(File::CreateFile(file)); + if (!fs.get()) + return false; + ini.Write(fs.get()); + return true; } } // namespace Common diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h index 9f3d7b3aa502..7a837780f47a 100644 --- a/engines/ags/shared/util/ini_util.h +++ b/engines/ags/shared/util/ini_util.h @@ -33,10 +33,8 @@ #include #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { typedef std::map StringOrderMap; typedef StringOrderMap::const_iterator StrStrOIter; @@ -44,31 +42,30 @@ typedef StringOrderMap::const_iterator StrStrOIter; typedef std::map ConfigTree; typedef ConfigTree::const_iterator ConfigNode; -namespace IniUtil -{ - // Parse the contents of given file as INI format and insert values - // into the tree. The pre-existing tree items, if any, are NOT erased. - // Returns FALSE if the file could not be opened. - bool Read(const String &file, ConfigTree &tree); - // Serialize given tree to the stream in INI text format. - // The INI format suggests only one nested level (group - items). - // The first level values are treated as a global section items. - // The sub-nodes beyond 2nd level are ignored completely. - void Write(const String &file, const ConfigTree &tree); - // Serialize given tree to the string in INI text format. - // TODO: implement proper memory/string stream compatible with base Stream - // class and merge this with Write function. - void WriteToString(String &s, const ConfigTree &tree); - // Parse the contents of given source stream as INI format and merge - // with values of the given tree while doing only minimal replaces; - // write the result into destination stream. - // If item already exists, only value is overwrited, if section exists, - // new items are appended to the end of it; completely new sections are - // appended to the end of text. - // Source and destination streams may refer either to different objects, - // or same stream opened for both reading and writing. - // Returns FALSE if the file could not be opened for writing. - bool Merge(const String &file, const ConfigTree &tree); +namespace IniUtil { +// Parse the contents of given file as INI format and insert values +// into the tree. The pre-existing tree items, if any, are NOT erased. +// Returns FALSE if the file could not be opened. +bool Read(const String &file, ConfigTree &tree); +// Serialize given tree to the stream in INI text format. +// The INI format suggests only one nested level (group - items). +// The first level values are treated as a global section items. +// The sub-nodes beyond 2nd level are ignored completely. +void Write(const String &file, const ConfigTree &tree); +// Serialize given tree to the string in INI text format. +// TODO: implement proper memory/string stream compatible with base Stream +// class and merge this with Write function. +void WriteToString(String &s, const ConfigTree &tree); +// Parse the contents of given source stream as INI format and merge +// with values of the given tree while doing only minimal replaces; +// write the result into destination stream. +// If item already exists, only value is overwrited, if section exists, +// new items are appended to the end of it; completely new sections are +// appended to the end of text. +// Source and destination streams may refer either to different objects, +// or same stream opened for both reading and writing. +// Returns FALSE if the file could not be opened for writing. +bool Merge(const String &file, const ConfigTree &tree); }; } // namespace Common diff --git a/engines/ags/shared/util/inifile.cpp b/engines/ags/shared/util/inifile.cpp index 07f43025c22d..0e39d9586380 100644 --- a/engines/ags/shared/util/inifile.cpp +++ b/engines/ags/shared/util/inifile.cpp @@ -27,161 +27,134 @@ #include "util/textstreamwriter.h" // TODO: replace with C++11 std::isblank library function -namespace agsstd -{ -inline int isblank(int ch) -{ - return ch == ' ' || ch == '\t'; +namespace agsstd { +inline int isblank(int ch) { + return ch == ' ' || ch == '\t'; } } // std -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -inline static void ReplaceSubString(String &line, IniFile::StrPos &sub_pos, const String &new_sub) -{ - line.ReplaceMid(sub_pos.first, sub_pos.second - sub_pos.first, new_sub); +inline static void ReplaceSubString(String &line, IniFile::StrPos &sub_pos, const String &new_sub) { + line.ReplaceMid(sub_pos.first, sub_pos.second - sub_pos.first, new_sub); } -IniFile::ItemDef::ItemDef(const String &key, const String &value) -{ - Line = String::FromFormat("%s=%s", key.GetCStr(), value.GetCStr()); - Key.first = 0; - Key.second = Key.first + key.GetLength(); - SepAt = Key.second; - Value.first = Key.second + 1; - Value.second = Value.first + value.GetLength(); +IniFile::ItemDef::ItemDef(const String &key, const String &value) { + Line = String::FromFormat("%s=%s", key.GetCStr(), value.GetCStr()); + Key.first = 0; + Key.second = Key.first + key.GetLength(); + SepAt = Key.second; + Value.first = Key.second + 1; + Value.second = Value.first + value.GetLength(); } -IniFile::ItemDef::ItemDef(const String &line, const StrPos &key, const StrPos &value, int sep_at) -{ - Line = line; - Key = key; - Value = value; - SepAt = sep_at; +IniFile::ItemDef::ItemDef(const String &line, const StrPos &key, const StrPos &value, int sep_at) { + Line = line; + Key = key; + Value = value; + SepAt = sep_at; } -void IniFile::ItemDef::SetKey(const String &key) -{ - if (key.IsEmpty()) - return; - - if (IsKeyValue()) - { - int diff = key.GetLength() - (Key.second - Key.first); - ReplaceSubString(Line, Key, key); - Key.second += diff; - Value.first += diff; - Value.second += diff; - } - else - { - *this = ItemDef(key, ""); - } +void IniFile::ItemDef::SetKey(const String &key) { + if (key.IsEmpty()) + return; + + if (IsKeyValue()) { + int diff = key.GetLength() - (Key.second - Key.first); + ReplaceSubString(Line, Key, key); + Key.second += diff; + Value.first += diff; + Value.second += diff; + } else { + *this = ItemDef(key, ""); + } } -void IniFile::ItemDef::SetValue(const String &value) -{ - if (!IsKeyValue()) - return; // no key - - if (SepAt > 0) - { // replacing existing value - int diff = static_cast(value.GetLength()) - (Value.second - Value.first); - ReplaceSubString(Line, Value, value); - Value.second += diff; - } - else - { // inserting value behind the key - StrPos valpos(Key.second, Key.second); - ReplaceSubString(Line, valpos, String::FromFormat("=%s", value.GetCStr())); - } +void IniFile::ItemDef::SetValue(const String &value) { + if (!IsKeyValue()) + return; // no key + + if (SepAt > 0) { + // replacing existing value + int diff = static_cast(value.GetLength()) - (Value.second - Value.first); + ReplaceSubString(Line, Value, value); + Value.second += diff; + } else { + // inserting value behind the key + StrPos valpos(Key.second, Key.second); + ReplaceSubString(Line, valpos, String::FromFormat("=%s", value.GetCStr())); + } } -IniFile::SectionDef::SectionDef(const String &name) -{ - if (name.IsEmpty()) - { - // global section - Name = StrPos(0,0); - } - else - { - // named section - Header = String::FromFormat("[%s]", name.GetCStr()); - Name.first = 1; - Name.second = 1 + Header.GetLength(); - } +IniFile::SectionDef::SectionDef(const String &name) { + if (name.IsEmpty()) { + // global section + Name = StrPos(0, 0); + } else { + // named section + Header = String::FromFormat("[%s]", name.GetCStr()); + Name.first = 1; + Name.second = 1 + Header.GetLength(); + } } -IniFile::SectionDef::SectionDef(const String &line, const StrPos &name) -{ - Header = line; - Name = name; +IniFile::SectionDef::SectionDef(const String &line, const StrPos &name) { + Header = line; + Name = name; } -void IniFile::SectionDef::SetName(const String &sec_name) -{ - if (sec_name.IsEmpty()) - return; +void IniFile::SectionDef::SetName(const String &sec_name) { + if (sec_name.IsEmpty()) + return; - int diff = sec_name.GetLength() - (Name.second - Name.first); - ReplaceSubString(Header, Name, sec_name); - Name.second += diff; + int diff = sec_name.GetLength() - (Name.second - Name.first); + ReplaceSubString(Header, Name, sec_name); + Name.second += diff; } -void IniFile::SectionDef::Clear() -{ - Items.clear(); +void IniFile::SectionDef::Clear() { + Items.clear(); } -IniFile::ItemIterator IniFile::SectionDef::InsertItem(ItemIterator item, const ItemDef &itemdef) -{ - return Items.insert(item, itemdef); +IniFile::ItemIterator IniFile::SectionDef::InsertItem(ItemIterator item, const ItemDef &itemdef) { + return Items.insert(item, itemdef); } -void IniFile::SectionDef::EraseItem(ItemIterator item) -{ - Items.erase(item); +void IniFile::SectionDef::EraseItem(ItemIterator item) { + Items.erase(item); } -IniFile::ItemIterator IniFile::InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value) -{ - ItemDef itemdef(key, value); - return sec->InsertItem(item, itemdef); +IniFile::ItemIterator IniFile::InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value) { + ItemDef itemdef(key, value); + return sec->InsertItem(item, itemdef); } -IniFile::SectionIterator IniFile::InsertSection(SectionIterator sec, const String &name) -{ - if (name.IsEmpty()) - return _sections.end(); // do not allow adding random global sections +IniFile::SectionIterator IniFile::InsertSection(SectionIterator sec, const String &name) { + if (name.IsEmpty()) + return _sections.end(); // do not allow adding random global sections - SectionDef secdef(name); - return _sections.insert(sec, secdef); + SectionDef secdef(name); + return _sections.insert(sec, secdef); } -void IniFile::RemoveItem(SectionIterator sec, ItemIterator item) -{ - sec->EraseItem(item); +void IniFile::RemoveItem(SectionIterator sec, ItemIterator item) { + sec->EraseItem(item); } -void IniFile::RemoveSection(SectionIterator sec) -{ - if (sec == _sections.begin()) - // do not remove global section, clear items instead - sec->Clear(); - else - _sections.erase(sec); +void IniFile::RemoveSection(SectionIterator sec) { + if (sec == _sections.begin()) + // do not remove global section, clear items instead + sec->Clear(); + else + _sections.erase(sec); } // Moves string pointer forward to the first non-space character -const char *SkipSpace(const char *line, const char *endl) -{ - for (; line != endl && isspace(*line); ++line); - return line; +const char *SkipSpace(const char *line, const char *endl) { + for (; line != endl && isspace(*line); ++line); + return line; } // Parse given line and extract a meaningful string; @@ -191,118 +164,106 @@ const char *SkipSpace(const char *line, const char *endl) // The 'endl' must point beyond the last character of the string // (e.g. terminator). const char *ParsePaddedString(const char *line, const char *endl, - const char *&str_at, const char *&str_end) -{ - // skip left padding - for (; line != endl && agsstd::isblank(*line); ++line); - str_at = line; - // skip right padding - const char *p_value = line; - for (line = endl; line != p_value && agsstd::isblank(*(line - 1)); --line); - str_end = line; - return line; + const char *&str_at, const char *&str_end) { + // skip left padding + for (; line != endl && agsstd::isblank(*line); ++line); + str_at = line; + // skip right padding + const char *p_value = line; + for (line = endl; line != p_value && agsstd::isblank(*(line - 1)); --line); + str_end = line; + return line; } -IniFile::IniFile() -{ - // precreate global section - _sections.push_back(SectionDef("")); +IniFile::IniFile() { + // precreate global section + _sections.push_back(SectionDef("")); } -void IniFile::Read(Stream *in) -{ - TextStreamReader reader(in); - - _sections.clear(); - // Create a global section; - // all the items we meet before explicit section declaration - // will be treated as "global" items. - _sections.push_back(SectionDef("")); - SectionDef *cur_section = &_sections.back(); - - do - { - String line = reader.ReadLine(); - if (line.IsEmpty() && reader.EOS()) - break; - - const char *cstr = line.GetCStr(); - const char *pstr = cstr; - const char *endl = cstr + line.GetLength(); - - // Find first non-space character - pstr = SkipSpace(pstr, endl); - if (pstr == endl) - continue; // empty line - - // Detect the kind of string we found - if ((endl - pstr >= 2 && *pstr == '/' && *(pstr + 1) == '/') || - (endl - pstr >= 1 && (*pstr == '#' || *pstr == ';'))) - { - StrPos nullpos(0,0); - cur_section->InsertItem(cur_section->End(), ItemDef(line, nullpos, nullpos, -1)); - continue; - } - - if (*pstr == '[') - { - // Parse this as section - const char *pstr_end = strrchr(pstr, ']'); - if (pstr_end < pstr) - continue; // no closing bracket - // Parse the section name - const char *str_at, *str_end; - ParsePaddedString(++pstr, pstr_end, str_at, str_end); - if (str_end == str_at) - continue; // inappropriate data or empty string - StrPos namepos(str_at - cstr, str_end - cstr); - _sections.push_back(SectionDef(line, namepos)); - cur_section = &_sections.back(); - } - else - { - // Parse this as a key-value pair - const char *pstr_end = strchr(pstr, '='); - if (pstr_end == pstr) - continue; // no key part, skip the line - if (!pstr_end) - pstr_end = endl; // no value part - // Parse key - const char *str_at, *str_end; - ParsePaddedString(pstr, pstr_end, str_at, str_end); - pstr = pstr_end; - if (str_end == str_at) - continue; // inappropriate data or empty string - // Create an item and parse value, if any - StrPos keypos(str_at - cstr, str_end - cstr); - StrPos valpos(0, 0); - int sep_at = -1; - if (pstr != endl) - { - sep_at = pstr - cstr; - ParsePaddedString(++pstr, endl, str_at, str_end); - valpos.first = str_at - cstr; - valpos.second = str_end - cstr; - } - cur_section->InsertItem(cur_section->End(), ItemDef(line, keypos, valpos, sep_at)); - } - } - while (!reader.EOS()); - - reader.ReleaseStream(); +void IniFile::Read(Stream *in) { + TextStreamReader reader(in); + + _sections.clear(); + // Create a global section; + // all the items we meet before explicit section declaration + // will be treated as "global" items. + _sections.push_back(SectionDef("")); + SectionDef *cur_section = &_sections.back(); + + do { + String line = reader.ReadLine(); + if (line.IsEmpty() && reader.EOS()) + break; + + const char *cstr = line.GetCStr(); + const char *pstr = cstr; + const char *endl = cstr + line.GetLength(); + + // Find first non-space character + pstr = SkipSpace(pstr, endl); + if (pstr == endl) + continue; // empty line + + // Detect the kind of string we found + if ((endl - pstr >= 2 && *pstr == '/' && *(pstr + 1) == '/') || + (endl - pstr >= 1 && (*pstr == '#' || *pstr == ';'))) { + StrPos nullpos(0, 0); + cur_section->InsertItem(cur_section->End(), ItemDef(line, nullpos, nullpos, -1)); + continue; + } + + if (*pstr == '[') { + // Parse this as section + const char *pstr_end = strrchr(pstr, ']'); + if (pstr_end < pstr) + continue; // no closing bracket + // Parse the section name + const char *str_at, *str_end; + ParsePaddedString(++pstr, pstr_end, str_at, str_end); + if (str_end == str_at) + continue; // inappropriate data or empty string + StrPos namepos(str_at - cstr, str_end - cstr); + _sections.push_back(SectionDef(line, namepos)); + cur_section = &_sections.back(); + } else { + // Parse this as a key-value pair + const char *pstr_end = strchr(pstr, '='); + if (pstr_end == pstr) + continue; // no key part, skip the line + if (!pstr_end) + pstr_end = endl; // no value part + // Parse key + const char *str_at, *str_end; + ParsePaddedString(pstr, pstr_end, str_at, str_end); + pstr = pstr_end; + if (str_end == str_at) + continue; // inappropriate data or empty string + // Create an item and parse value, if any + StrPos keypos(str_at - cstr, str_end - cstr); + StrPos valpos(0, 0); + int sep_at = -1; + if (pstr != endl) { + sep_at = pstr - cstr; + ParsePaddedString(++pstr, endl, str_at, str_end); + valpos.first = str_at - cstr; + valpos.second = str_end - cstr; + } + cur_section->InsertItem(cur_section->End(), ItemDef(line, keypos, valpos, sep_at)); + } + } while (!reader.EOS()); + + reader.ReleaseStream(); } -void IniFile::Write(Stream *out) const -{ - TextStreamWriter writer(out); - for (ConstSectionIterator sec = _sections.begin(); sec != _sections.end(); ++sec) - { - if (sec != _sections.begin()) // do not write global section's name - writer.WriteLine(sec->GetLine()); - for (ConstItemIterator item = sec->CBegin(); item != sec->CEnd(); ++item) - writer.WriteLine(item->GetLine()); - } - writer.ReleaseStream(); +void IniFile::Write(Stream *out) const { + TextStreamWriter writer(out); + for (ConstSectionIterator sec = _sections.begin(); sec != _sections.end(); ++sec) { + if (sec != _sections.begin()) // do not write global section's name + writer.WriteLine(sec->GetLine()); + for (ConstItemIterator item = sec->CBegin(); item != sec->CEnd(); ++item) + writer.WriteLine(item->GetLine()); + } + writer.ReleaseStream(); } } // namespace Common diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h index b69b89582ae8..2064dd827e58 100644 --- a/engines/ags/shared/util/inifile.h +++ b/engines/ags/shared/util/inifile.h @@ -36,107 +36,135 @@ #include #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class IniFile -{ +class IniFile { public: - // Position of a string in the line of text: - // is defined by a pair of first and next-after-last character indices - typedef std::pair StrPos; - // Location of section in the array of text lines: - // is defined by a pair of first and next-after-last line indices - typedef std::pair SectionPos; - - // Item definition - // Valid key indicates a key-value line; no key means unparsed - // line of text, e.g. comment or incorrectly formatted item. - class ItemDef - { - public: - ItemDef(const String &key, const String &value); - ItemDef(const String &line, const StrPos &key, const StrPos &value, int sep_at); - String GetLine() const { return Line; } - String GetKey() const { return SubString(Line, Key); } - String GetValue() const { return SubString(Line, Value); } - bool IsKeyValue() const { return Key.second - Key.first > 0; } - void SetKey(const String &key); - void SetValue(const String &value); - - private: - String Line; // actual text - StrPos Key; // position of item key - int SepAt; // position of the separator (assignment) symbol - StrPos Value; // position of item value - }; - // Linked list of items - typedef std::list LItems; - typedef LItems::iterator ItemIterator; - typedef LItems::const_iterator ConstItemIterator; - - // Section definition - class SectionDef - { - public: - SectionDef(const String &name); - SectionDef(const String &line, const StrPos &name); - String GetLine() const { return Header; } - String GetName() const { return SubString(Header, Name); } - size_t GetItemCount() const { return Items.size(); } - bool IsGlobal() const { return Name.second - Name.first <= 0; } - ItemIterator Begin() { return Items.begin(); } - ItemIterator End() { return Items.end(); } - ConstItemIterator CBegin() const { return Items.begin(); } - ConstItemIterator CEnd() const { return Items.end(); } - void SetName(const String &sec_name); - void Clear(); - ItemIterator InsertItem(ItemIterator item, const ItemDef &itemdef); - void EraseItem(ItemIterator item); - - private: - String Header;// section's heading line - StrPos Name; // location of section name in the header line - LItems Items; // linked list of items belonging to the section - }; - // Linked list of sections - typedef std::list LSections; - typedef LSections::iterator SectionIterator; - typedef LSections::const_iterator ConstSectionIterator; + // Position of a string in the line of text: + // is defined by a pair of first and next-after-last character indices + typedef std::pair StrPos; + // Location of section in the array of text lines: + // is defined by a pair of first and next-after-last line indices + typedef std::pair SectionPos; + + // Item definition + // Valid key indicates a key-value line; no key means unparsed + // line of text, e.g. comment or incorrectly formatted item. + class ItemDef { + public: + ItemDef(const String &key, const String &value); + ItemDef(const String &line, const StrPos &key, const StrPos &value, int sep_at); + String GetLine() const { + return Line; + } + String GetKey() const { + return SubString(Line, Key); + } + String GetValue() const { + return SubString(Line, Value); + } + bool IsKeyValue() const { + return Key.second - Key.first > 0; + } + void SetKey(const String &key); + void SetValue(const String &value); + + private: + String Line; // actual text + StrPos Key; // position of item key + int SepAt; // position of the separator (assignment) symbol + StrPos Value; // position of item value + }; + // Linked list of items + typedef std::list LItems; + typedef LItems::iterator ItemIterator; + typedef LItems::const_iterator ConstItemIterator; + + // Section definition + class SectionDef { + public: + SectionDef(const String &name); + SectionDef(const String &line, const StrPos &name); + String GetLine() const { + return Header; + } + String GetName() const { + return SubString(Header, Name); + } + size_t GetItemCount() const { + return Items.size(); + } + bool IsGlobal() const { + return Name.second - Name.first <= 0; + } + ItemIterator Begin() { + return Items.begin(); + } + ItemIterator End() { + return Items.end(); + } + ConstItemIterator CBegin() const { + return Items.begin(); + } + ConstItemIterator CEnd() const { + return Items.end(); + } + void SetName(const String &sec_name); + void Clear(); + ItemIterator InsertItem(ItemIterator item, const ItemDef &itemdef); + void EraseItem(ItemIterator item); + + private: + String Header;// section's heading line + StrPos Name; // location of section name in the header line + LItems Items; // linked list of items belonging to the section + }; + // Linked list of sections + typedef std::list LSections; + typedef LSections::iterator SectionIterator; + typedef LSections::const_iterator ConstSectionIterator; private: - inline static String SubString(const String &line, const StrPos &pos) - { - return line.Mid(pos.first, pos.second - pos.first); - } + inline static String SubString(const String &line, const StrPos &pos) { + return line.Mid(pos.first, pos.second - pos.first); + } public: - IniFile(); - - SectionIterator Begin() { return _sections.begin(); } - SectionIterator End() { return _sections.end(); } - ConstSectionIterator CBegin() const { return _sections.begin(); } - ConstSectionIterator CEnd() const { return _sections.end(); } - - void Read(Stream *in); - void Write(Stream *out) const; - - // Return number of sections - size_t GetSectionCount() const { return _sections.size(); } - // Insert new item *before* existing item - ItemIterator InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value); - // Insert new section *before* existing section - SectionIterator InsertSection(SectionIterator sec, const String &name); - // Remove a single item - void RemoveItem(SectionIterator sec, ItemIterator item); - // Completely remove whole section; this removes all lines between section - // header and the last item found in that section (inclusive). - void RemoveSection(SectionIterator sec); + IniFile(); + + SectionIterator Begin() { + return _sections.begin(); + } + SectionIterator End() { + return _sections.end(); + } + ConstSectionIterator CBegin() const { + return _sections.begin(); + } + ConstSectionIterator CEnd() const { + return _sections.end(); + } + + void Read(Stream *in); + void Write(Stream *out) const; + + // Return number of sections + size_t GetSectionCount() const { + return _sections.size(); + } + // Insert new item *before* existing item + ItemIterator InsertItem(SectionIterator sec, ItemIterator item, const String &key, const String &value); + // Insert new section *before* existing section + SectionIterator InsertSection(SectionIterator sec, const String &name); + // Remove a single item + void RemoveItem(SectionIterator sec, ItemIterator item); + // Completely remove whole section; this removes all lines between section + // header and the last item found in that section (inclusive). + void RemoveSection(SectionIterator sec); private: - LSections _sections; + LSections _sections; }; } // namespace Common diff --git a/engines/ags/shared/util/lzw.cpp b/engines/ags/shared/util/lzw.cpp index 85ca1454a04f..d6667f1bf5fc 100644 --- a/engines/ags/shared/util/lzw.cpp +++ b/engines/ags/shared/util/lzw.cpp @@ -56,226 +56,220 @@ int *node; int pos; long outbytes = 0, maxsize = 0, putbytes = 0; -int insert(int i, int run) -{ - int c, j, k, l, n, match; - int *p; - - c = NIL; - - k = l = 1; - match = THRESHOLD - 1; - p = &root[(unsigned char)lzbuffer[i]]; - lson[i] = rson[i] = NIL; - while ((j = *p) != NIL) { - for (n = min(k, l); n < run && (c = (lzbuffer[j + n] - lzbuffer[i + n])) == 0; n++) ; - - if (n > match) { - match = n; - pos = j; - } - - if (c < 0) { - p = &lson[j]; - k = n; - } else if (c > 0) { - p = &rson[j]; - l = n; - } else { - dad[j] = NIL; - dad[lson[j]] = lson + i - node; - dad[rson[j]] = rson + i - node; - lson[i] = lson[j]; - rson[i] = rson[j]; - break; - } - } - - dad[i] = p - node; - *p = i; - return match; +int insert(int i, int run) { + int c, j, k, l, n, match; + int *p; + + c = NIL; + + k = l = 1; + match = THRESHOLD - 1; + p = &root[(unsigned char)lzbuffer[i]]; + lson[i] = rson[i] = NIL; + while ((j = *p) != NIL) { + for (n = min(k, l); n < run && (c = (lzbuffer[j + n] - lzbuffer[i + n])) == 0; n++) ; + + if (n > match) { + match = n; + pos = j; + } + + if (c < 0) { + p = &lson[j]; + k = n; + } else if (c > 0) { + p = &rson[j]; + l = n; + } else { + dad[j] = NIL; + dad[lson[j]] = lson + i - node; + dad[rson[j]] = rson + i - node; + lson[i] = lson[j]; + rson[i] = rson[j]; + break; + } + } + + dad[i] = p - node; + *p = i; + return match; } -void _delete(int z) -{ - int j; - - if (dad[z] != NIL) { - if (rson[z] == NIL) - j = lson[z]; - else if (lson[z] == NIL) - j = rson[z]; - else { - j = lson[z]; - if (rson[j] != NIL) { - do { - j = rson[j]; - } while (rson[j] != NIL); - - node[dad[j]] = lson[j]; - dad[lson[j]] = dad[j]; - lson[j] = lson[z]; - dad[lson[z]] = lson + j - node; - } - - rson[j] = rson[z]; - dad[rson[z]] = rson + j - node; - } - - dad[j] = dad[z]; - node[dad[z]] = j; - dad[z] = NIL; - } +void _delete(int z) { + int j; + + if (dad[z] != NIL) { + if (rson[z] == NIL) + j = lson[z]; + else if (lson[z] == NIL) + j = rson[z]; + else { + j = lson[z]; + if (rson[j] != NIL) { + do { + j = rson[j]; + } while (rson[j] != NIL); + + node[dad[j]] = lson[j]; + dad[lson[j]] = dad[j]; + lson[j] = lson[z]; + dad[lson[z]] = lson + j - node; + } + + rson[j] = rson[z]; + dad[rson[z]] = rson + j - node; + } + + dad[j] = dad[z]; + node[dad[z]] = j; + dad[z] = NIL; + } } -void lzwcompress(Stream *lzw_in, Stream *out) -{ - int ch, i, run, len, match, size, mask; - char buf[17]; - - lzbuffer = (char *)malloc(N + F + (N + 1 + N + N + 256) * sizeof(int)); // 28.5 k ! - if (lzbuffer == nullptr) { - quit("unable to compress: out of memory"); - } - - node = (int *)(lzbuffer + N + F); - for (i = 0; i < 256; i++) - root[i] = NIL; - - for (i = NIL; i < N; i++) - dad[i] = NIL; - - size = mask = 1; - buf[0] = 0; - i = N - F - F; - - for (len = 0; len < F && (ch = lzw_in->ReadByte()) != -1; len++) { - lzbuffer[i + F] = ch; - i = (i + 1) & (N - 1); - } - - run = len; - - do { - ch = lzw_in->ReadByte(); - if (i >= N - F) { - _delete(i + F - N); - lzbuffer[i + F] = lzbuffer[i + F - N] = ch; - } else { - _delete(i + F); - lzbuffer[i + F] = ch; - } - - match = insert(i, run); - if (ch == -1) { - run--; - len--; - } - - if (len++ >= run) { - if (match >= THRESHOLD) { - buf[0] |= mask; - // possible fix: change int* to short* ?? - *(short *)(buf + size) = ((match - 3) << 12) | ((i - pos - 1) & (N - 1)); - size += 2; - len -= match; - } else { - buf[size++] = lzbuffer[i]; - len--; - } - - if (!((mask += mask) & 0xFF)) { - out->WriteArray(buf, size, 1); - outbytes += size; - size = mask = 1; - buf[0] = 0; - } - } - i = (i + 1) & (N - 1); - } while (len > 0); - - if (size > 1) { - out->WriteArray(buf, size, 1); - outbytes += size; - } - - free(lzbuffer); +void lzwcompress(Stream *lzw_in, Stream *out) { + int ch, i, run, len, match, size, mask; + char buf[17]; + + lzbuffer = (char *)malloc(N + F + (N + 1 + N + N + 256) * sizeof(int)); // 28.5 k ! + if (lzbuffer == nullptr) { + quit("unable to compress: out of memory"); + } + + node = (int *)(lzbuffer + N + F); + for (i = 0; i < 256; i++) + root[i] = NIL; + + for (i = NIL; i < N; i++) + dad[i] = NIL; + + size = mask = 1; + buf[0] = 0; + i = N - F - F; + + for (len = 0; len < F && (ch = lzw_in->ReadByte()) != -1; len++) { + lzbuffer[i + F] = ch; + i = (i + 1) & (N - 1); + } + + run = len; + + do { + ch = lzw_in->ReadByte(); + if (i >= N - F) { + _delete(i + F - N); + lzbuffer[i + F] = lzbuffer[i + F - N] = ch; + } else { + _delete(i + F); + lzbuffer[i + F] = ch; + } + + match = insert(i, run); + if (ch == -1) { + run--; + len--; + } + + if (len++ >= run) { + if (match >= THRESHOLD) { + buf[0] |= mask; + // possible fix: change int* to short* ?? + *(short *)(buf + size) = ((match - 3) << 12) | ((i - pos - 1) & (N - 1)); + size += 2; + len -= match; + } else { + buf[size++] = lzbuffer[i]; + len--; + } + + if (!((mask += mask) & 0xFF)) { + out->WriteArray(buf, size, 1); + outbytes += size; + size = mask = 1; + buf[0] = 0; + } + } + i = (i + 1) & (N - 1); + } while (len > 0); + + if (size > 1) { + out->WriteArray(buf, size, 1); + outbytes += size; + } + + free(lzbuffer); } int expand_to_mem = 0; unsigned char *membfptr = nullptr; -void myputc(int ccc, Stream *out) -{ - if (maxsize > 0) { - putbytes++; - if (putbytes > maxsize) - return; - } - - outbytes++; - if (expand_to_mem) { - membfptr[0] = ccc; - membfptr++; - } else - out->WriteInt8(ccc); +void myputc(int ccc, Stream *out) { + if (maxsize > 0) { + putbytes++; + if (putbytes > maxsize) + return; + } + + outbytes++; + if (expand_to_mem) { + membfptr[0] = ccc; + membfptr++; + } else + out->WriteInt8(ccc); } -void lzwexpand(Stream *lzw_in, Stream *out) -{ - int bits, ch, i, j, len, mask; - char *lzbuffer; +void lzwexpand(Stream *lzw_in, Stream *out) { + int bits, ch, i, j, len, mask; + char *lzbuffer; // printf(" UnShrinking: %s ",filena); - putbytes = 0; - - lzbuffer = (char *)malloc(N); - if (lzbuffer == nullptr) { - quit("compress.cpp: unable to decompress: insufficient memory"); - } - i = N - F; - - // this end condition just checks for EOF, which is no good to us - while ((bits = lzw_in->ReadByte()) != -1) { - for (mask = 0x01; mask & 0xFF; mask <<= 1) { - if (bits & mask) { - // MACPORT FIX: read to short and expand - short jshort = 0; - jshort = lzw_in->ReadInt16(); - j = jshort; - - len = ((j >> 12) & 15) + 3; - j = (i - j - 1) & (N - 1); - - while (len--) { - myputc(lzbuffer[i] = lzbuffer[j], out); - j = (j + 1) & (N - 1); - i = (i + 1) & (N - 1); - } - } else { - ch = lzw_in->ReadByte(); - myputc(lzbuffer[i] = ch, out); - i = (i + 1) & (N - 1); - } - - if ((putbytes >= maxsize) && (maxsize > 0)) - break; - - if ((lzw_in->EOS()) && (maxsize > 0)) - quit("Read error decompressing image - file is corrupt"); - } // end for mask - - if ((putbytes >= maxsize) && (maxsize > 0)) - break; - } - - free(lzbuffer); - expand_to_mem = 0; + putbytes = 0; + + lzbuffer = (char *)malloc(N); + if (lzbuffer == nullptr) { + quit("compress.cpp: unable to decompress: insufficient memory"); + } + i = N - F; + + // this end condition just checks for EOF, which is no good to us + while ((bits = lzw_in->ReadByte()) != -1) { + for (mask = 0x01; mask & 0xFF; mask <<= 1) { + if (bits & mask) { + // MACPORT FIX: read to short and expand + short jshort = 0; + jshort = lzw_in->ReadInt16(); + j = jshort; + + len = ((j >> 12) & 15) + 3; + j = (i - j - 1) & (N - 1); + + while (len--) { + myputc(lzbuffer[i] = lzbuffer[j], out); + j = (j + 1) & (N - 1); + i = (i + 1) & (N - 1); + } + } else { + ch = lzw_in->ReadByte(); + myputc(lzbuffer[i] = ch, out); + i = (i + 1) & (N - 1); + } + + if ((putbytes >= maxsize) && (maxsize > 0)) + break; + + if ((lzw_in->EOS()) && (maxsize > 0)) + quit("Read error decompressing image - file is corrupt"); + } // end for mask + + if ((putbytes >= maxsize) && (maxsize > 0)) + break; + } + + free(lzbuffer); + expand_to_mem = 0; } -unsigned char *lzwexpand_to_mem(Stream *in) -{ - unsigned char *membuff = (unsigned char *)malloc(maxsize + 10); - expand_to_mem = 1; - membfptr = membuff; - lzwexpand(in, nullptr); - return membuff; +unsigned char *lzwexpand_to_mem(Stream *in) { + unsigned char *membuff = (unsigned char *)malloc(maxsize + 10); + expand_to_mem = 1; + membfptr = membuff; + lzwexpand(in, nullptr); + return membuff; } diff --git a/engines/ags/shared/util/lzw.h b/engines/ags/shared/util/lzw.h index f4a7b459151f..c62c2c826517 100644 --- a/engines/ags/shared/util/lzw.h +++ b/engines/ags/shared/util/lzw.h @@ -23,7 +23,11 @@ #ifndef AGS_SHARED_UTIL_LZW_H #define AGS_SHARED_UTIL_LZW_H -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later void lzwcompress(Common::Stream *lzw_in, Common::Stream *out); diff --git a/engines/ags/shared/util/math.h b/engines/ags/shared/util/math.h index 02da48ff1ea0..52d760a50617 100644 --- a/engines/ags/shared/util/math.h +++ b/engines/ags/shared/util/math.h @@ -33,66 +33,53 @@ #define M_PI 3.14159265358979323846 #endif -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -namespace Math -{ - template - inline const T &Max(const T &a, const T &b) - { - return a < b ? b : a; - } +namespace Math { +template +inline const T &Max(const T &a, const T &b) { + return a < b ? b : a; +} - template - inline const T &Min(const T &a, const T &b) - { - return a < b ? a : b; - } +template +inline const T &Min(const T &a, const T &b) { + return a < b ? a : b; +} - template - inline const T &Clamp(const T &val, const T &floor, const T &ceil) - { - return Max(floor, Min(val, ceil)); - } +template +inline const T &Clamp(const T &val, const T &floor, const T &ceil) { + return Max(floor, Min(val, ceil)); +} - template - inline void ClampLength(T &from, T &length, const T &floor, const T &height) - { - if (from < floor) - { - length -= floor - from; - from = floor; - } - else if (from >= floor + height) - { - from = floor + height; - length = 0; - } +template +inline void ClampLength(T &from, T &length, const T &floor, const T &height) { + if (from < floor) { + length -= floor - from; + from = floor; + } else if (from >= floor + height) { + from = floor + height; + length = 0; + } - length = Max(length, 0); - length = Min(length, height - from); - } + length = Max(length, 0); + length = Min(length, height - from); +} - // Get a measure of how value A is greater than value B; - // if A is smaller than or equal to B, returns 0. - template - inline T Surplus(const T &larger, const T &smaller) - { - return larger > smaller ? larger - smaller : 0; - } +// Get a measure of how value A is greater than value B; +// if A is smaller than or equal to B, returns 0. +template +inline T Surplus(const T &larger, const T &smaller) { + return larger > smaller ? larger - smaller : 0; +} - inline float RadiansToDegrees(float rads) - { - return rads * (float)(180.0 / M_PI); - } +inline float RadiansToDegrees(float rads) { + return rads * (float)(180.0 / M_PI); +} - inline float DegreesToRadians(float deg) - { - return deg * (float)(M_PI / 180.0); - } +inline float DegreesToRadians(float deg) { + return deg * (float)(M_PI / 180.0); +} } // namespace Math } // namespace Common diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h index 0b4761d24607..8ab235a3e915 100644 --- a/engines/ags/shared/util/memory.h +++ b/engines/ags/shared/util/memory.h @@ -37,216 +37,192 @@ #define MEMORY_STRICT_ALIGNMENT #endif -namespace AGS -{ -namespace Common -{ - -namespace Memory -{ - //------------------------------------------------------------------------- - // Converts pointer to 32-bit integer value and vice-versa. - // Only for use in special cases for compatibility with 32-bit plugin API. - // Dangerous on 64-bit systems. - //------------------------------------------------------------------------- - template - inline int32_t PtrToInt32(T *ptr) - { - return static_cast(reinterpret_cast(ptr)); - } - template - inline T *Int32ToPtr(int32_t value) - { - return reinterpret_cast(static_cast(value)); - } - - //------------------------------------------------------------------------- - // Functions for reading and writing basic types from/to the memory. - // Implement safety workaround for CPUs with alignment restrictions - // (e.g. MIPS). - //------------------------------------------------------------------------- - inline int16_t ReadInt16(const void *ptr) - { - #if defined (MEMORY_STRICT_ALIGNMENT) - const uint8_t *b = (const uint8_t *)ptr; - #if defined (BITBYTE_BIG_ENDIAN) - return (b[0] << 8) | b[1]; - #else - return (b[1] << 8) | b[0]; - #endif - #else - return *(int16_t*)ptr; - #endif - } - - inline int32_t ReadInt32(const void *ptr) - { - #if defined (MEMORY_STRICT_ALIGNMENT) - const uint8_t *b = (const uint8_t *)ptr; - #if defined (BITBYTE_BIG_ENDIAN) - return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; - #else - return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; - #endif - #else - return *(int32_t*)ptr; - #endif - } - - inline int64_t ReadInt64(const void *ptr) - { - #if defined (MEMORY_STRICT_ALIGNMENT) - const uint8_t *b = (const uint8_t *)ptr; - #if defined (BITBYTE_BIG_ENDIAN) - return ((uint64_t)b[0] << 56) | ((uint64_t)b[1] << 48) | ((uint64_t)b[2] << 40) | ((uint64_t)b[3] << 32) | - (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; - #else - return ((uint64_t)b[7] << 56) | ((uint64_t)b[6] << 48) | ((uint64_t)b[5] << 40) | ((uint64_t)b[4] << 32) | - (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; - #endif - #else - return *(int64_t*)ptr; - #endif - } - - inline void WriteInt16(void *ptr, int16_t value) - { - #if defined (MEMORY_STRICT_ALIGNMENT) - uint8_t *b = (uint8_t *)ptr; - #if defined (BITBYTE_BIG_ENDIAN) - b[0] = (uint8_t)(value >> 8); - b[1] = (uint8_t)(value); - #else - b[1] = (uint8_t)(value >> 8); - b[0] = (uint8_t)(value); - #endif - #else - *(int16_t*)ptr = value; - #endif - } - - inline void WriteInt32(void *ptr, int32_t value) - { - #if defined (MEMORY_STRICT_ALIGNMENT) - uint8_t *b = (uint8_t *)ptr; - #if defined (BITBYTE_BIG_ENDIAN) - b[0] = (uint8_t)(value >> 24); - b[1] = (uint8_t)(value >> 16); - b[2] = (uint8_t)(value >> 8); - b[3] = (uint8_t)(value); - #else - b[3] = (uint8_t)(value >> 24); - b[2] = (uint8_t)(value >> 16); - b[1] = (uint8_t)(value >> 8); - b[0] = (uint8_t)(value); - #endif - #else - *(int32_t*)ptr = value; - #endif - } - - inline void WriteInt64(void *ptr, int64_t value) - { - #if defined (MEMORY_STRICT_ALIGNMENT) - uint8_t *b = (uint8_t *)ptr; - #if defined (BITBYTE_BIG_ENDIAN) - b[0] = (uint8_t)(value >> 56); - b[1] = (uint8_t)(value >> 48); - b[2] = (uint8_t)(value >> 40); - b[3] = (uint8_t)(value >> 32); - b[4] = (uint8_t)(value >> 24); - b[5] = (uint8_t)(value >> 16); - b[6] = (uint8_t)(value >> 8); - b[7] = (uint8_t)(value); - #else - b[7] = (uint8_t)(value >> 56); - b[6] = (uint8_t)(value >> 48); - b[5] = (uint8_t)(value >> 40); - b[4] = (uint8_t)(value >> 32); - b[3] = (uint8_t)(value >> 24); - b[2] = (uint8_t)(value >> 16); - b[1] = (uint8_t)(value >> 8); - b[0] = (uint8_t)(value); - #endif - #else - *(int64_t*)ptr = value; - #endif - } - - //------------------------------------------------------------------------- - // Helpers for reading and writing from memory with respect for endianess. - //------------------------------------------------------------------------- - inline int16_t ReadInt16LE(const void *ptr) - { - return BBOp::Int16FromLE(ReadInt16(ptr)); - } - - inline int32_t ReadInt32LE(const void *ptr) - { - return BBOp::Int32FromLE(ReadInt32(ptr)); - } - - inline int64_t ReadInt64LE(const void *ptr) - { - return BBOp::Int64FromLE(ReadInt64(ptr)); - } - - inline void WriteInt16LE(void *ptr, int16_t value) - { - WriteInt16(ptr, BBOp::Int16FromLE(value)); - } - - inline void WriteInt32LE(void *ptr, int32_t value) - { - WriteInt32(ptr, BBOp::Int32FromLE(value)); - } - - inline void WriteInt64LE(void *ptr, int64_t value) - { - WriteInt64(ptr, BBOp::Int64FromLE(value)); - } - - inline int16_t ReadInt16BE(const void *ptr) - { - return BBOp::Int16FromBE(ReadInt16(ptr)); - } - - inline int32_t ReadInt32BE(const void *ptr) - { - return BBOp::Int32FromBE(ReadInt32(ptr)); - } - - inline int64_t ReadInt64BE(const void *ptr) - { - return BBOp::Int64FromBE(ReadInt64(ptr)); - } - - inline void WriteInt16BE(void *ptr, int16_t value) - { - WriteInt16(ptr, BBOp::Int16FromBE(value)); - } - - inline void WriteInt32BE(void *ptr, int32_t value) - { - WriteInt32(ptr, BBOp::Int32FromBE(value)); - } - - inline void WriteInt64BE(void *ptr, int64_t value) - { - WriteInt64(ptr, BBOp::Int64FromBE(value)); - } - - //------------------------------------------------------------------------- - // Memory data manipulation - //------------------------------------------------------------------------- - // Copies block of 2d data from source into destination. - inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_offset, - const uint8_t *src, const size_t src_pitch, const size_t src_offset, - const size_t height) - { - for (size_t y = 0; y < height; ++y, src += src_pitch, dst += dst_pitch) - memcpy(dst + dst_offset, src + src_offset, Math::Min(dst_pitch - dst_offset, src_pitch - src_offset)); - } +namespace AGS { +namespace Common { + +namespace Memory { +//------------------------------------------------------------------------- +// Converts pointer to 32-bit integer value and vice-versa. +// Only for use in special cases for compatibility with 32-bit plugin API. +// Dangerous on 64-bit systems. +//------------------------------------------------------------------------- +template +inline int32_t PtrToInt32(T *ptr) { + return static_cast(reinterpret_cast(ptr)); +} +template +inline T *Int32ToPtr(int32_t value) { + return reinterpret_cast(static_cast(value)); +} + +//------------------------------------------------------------------------- +// Functions for reading and writing basic types from/to the memory. +// Implement safety workaround for CPUs with alignment restrictions +// (e.g. MIPS). +//------------------------------------------------------------------------- +inline int16_t ReadInt16(const void *ptr) { +#if defined (MEMORY_STRICT_ALIGNMENT) + const uint8_t *b = (const uint8_t *)ptr; +#if defined (BITBYTE_BIG_ENDIAN) + return (b[0] << 8) | b[1]; +#else + return (b[1] << 8) | b[0]; +#endif +#else + return *(int16_t *)ptr; +#endif +} + +inline int32_t ReadInt32(const void *ptr) { +#if defined (MEMORY_STRICT_ALIGNMENT) + const uint8_t *b = (const uint8_t *)ptr; +#if defined (BITBYTE_BIG_ENDIAN) + return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; +#else + return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; +#endif +#else + return *(int32_t *)ptr; +#endif +} + +inline int64_t ReadInt64(const void *ptr) { +#if defined (MEMORY_STRICT_ALIGNMENT) + const uint8_t *b = (const uint8_t *)ptr; +#if defined (BITBYTE_BIG_ENDIAN) + return ((uint64_t)b[0] << 56) | ((uint64_t)b[1] << 48) | ((uint64_t)b[2] << 40) | ((uint64_t)b[3] << 32) | + (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; +#else + return ((uint64_t)b[7] << 56) | ((uint64_t)b[6] << 48) | ((uint64_t)b[5] << 40) | ((uint64_t)b[4] << 32) | + (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; +#endif +#else + return *(int64_t *)ptr; +#endif +} + +inline void WriteInt16(void *ptr, int16_t value) { +#if defined (MEMORY_STRICT_ALIGNMENT) + uint8_t *b = (uint8_t *)ptr; +#if defined (BITBYTE_BIG_ENDIAN) + b[0] = (uint8_t)(value >> 8); + b[1] = (uint8_t)(value); +#else + b[1] = (uint8_t)(value >> 8); + b[0] = (uint8_t)(value); +#endif +#else + *(int16_t *)ptr = value; +#endif +} + +inline void WriteInt32(void *ptr, int32_t value) { +#if defined (MEMORY_STRICT_ALIGNMENT) + uint8_t *b = (uint8_t *)ptr; +#if defined (BITBYTE_BIG_ENDIAN) + b[0] = (uint8_t)(value >> 24); + b[1] = (uint8_t)(value >> 16); + b[2] = (uint8_t)(value >> 8); + b[3] = (uint8_t)(value); +#else + b[3] = (uint8_t)(value >> 24); + b[2] = (uint8_t)(value >> 16); + b[1] = (uint8_t)(value >> 8); + b[0] = (uint8_t)(value); +#endif +#else + *(int32_t *)ptr = value; +#endif +} + +inline void WriteInt64(void *ptr, int64_t value) { +#if defined (MEMORY_STRICT_ALIGNMENT) + uint8_t *b = (uint8_t *)ptr; +#if defined (BITBYTE_BIG_ENDIAN) + b[0] = (uint8_t)(value >> 56); + b[1] = (uint8_t)(value >> 48); + b[2] = (uint8_t)(value >> 40); + b[3] = (uint8_t)(value >> 32); + b[4] = (uint8_t)(value >> 24); + b[5] = (uint8_t)(value >> 16); + b[6] = (uint8_t)(value >> 8); + b[7] = (uint8_t)(value); +#else + b[7] = (uint8_t)(value >> 56); + b[6] = (uint8_t)(value >> 48); + b[5] = (uint8_t)(value >> 40); + b[4] = (uint8_t)(value >> 32); + b[3] = (uint8_t)(value >> 24); + b[2] = (uint8_t)(value >> 16); + b[1] = (uint8_t)(value >> 8); + b[0] = (uint8_t)(value); +#endif +#else + *(int64_t *)ptr = value; +#endif +} + +//------------------------------------------------------------------------- +// Helpers for reading and writing from memory with respect for endianess. +//------------------------------------------------------------------------- +inline int16_t ReadInt16LE(const void *ptr) { + return BBOp::Int16FromLE(ReadInt16(ptr)); +} + +inline int32_t ReadInt32LE(const void *ptr) { + return BBOp::Int32FromLE(ReadInt32(ptr)); +} + +inline int64_t ReadInt64LE(const void *ptr) { + return BBOp::Int64FromLE(ReadInt64(ptr)); +} + +inline void WriteInt16LE(void *ptr, int16_t value) { + WriteInt16(ptr, BBOp::Int16FromLE(value)); +} + +inline void WriteInt32LE(void *ptr, int32_t value) { + WriteInt32(ptr, BBOp::Int32FromLE(value)); +} + +inline void WriteInt64LE(void *ptr, int64_t value) { + WriteInt64(ptr, BBOp::Int64FromLE(value)); +} + +inline int16_t ReadInt16BE(const void *ptr) { + return BBOp::Int16FromBE(ReadInt16(ptr)); +} + +inline int32_t ReadInt32BE(const void *ptr) { + return BBOp::Int32FromBE(ReadInt32(ptr)); +} + +inline int64_t ReadInt64BE(const void *ptr) { + return BBOp::Int64FromBE(ReadInt64(ptr)); +} + +inline void WriteInt16BE(void *ptr, int16_t value) { + WriteInt16(ptr, BBOp::Int16FromBE(value)); +} + +inline void WriteInt32BE(void *ptr, int32_t value) { + WriteInt32(ptr, BBOp::Int32FromBE(value)); +} + +inline void WriteInt64BE(void *ptr, int64_t value) { + WriteInt64(ptr, BBOp::Int64FromBE(value)); +} + +//------------------------------------------------------------------------- +// Memory data manipulation +//------------------------------------------------------------------------- +// Copies block of 2d data from source into destination. +inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_offset, + const uint8_t *src, const size_t src_pitch, const size_t src_offset, + const size_t height) { + for (size_t y = 0; y < height; ++y, src += src_pitch, dst += dst_pitch) + memcpy(dst + dst_offset, src + src_offset, Math::Min(dst_pitch - dst_offset, src_pitch - src_offset)); +} } // namespace Memory diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp index ea6c4c96c481..a2210e8ae874 100644 --- a/engines/ags/shared/util/misc.cpp +++ b/engines/ags/shared/util/misc.cpp @@ -23,11 +23,11 @@ /* Copyright (c) 2003, Shawn R. Walker All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright @@ -36,7 +36,7 @@ * Neither the name of Shawn R. Walker nor names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -68,141 +68,138 @@ using namespace AGS::Common; #if !defined (AGS_CASE_SENSITIVE_FILESYSTEM) #include /* File Name Concatenator basically on Windows / DOS */ -char *ci_find_file(const char *dir_name, const char *file_name) -{ - char *diamond = NULL; - - if (dir_name == NULL && file_name == NULL) - return NULL; - - if (dir_name == NULL) { - diamond = (char *)malloc(strlen(file_name) + 3); - strcpy(diamond, file_name); - } else { - diamond = (char *)malloc(strlen(dir_name) + strlen(file_name) + 2); - append_filename(diamond, dir_name, file_name, strlen(dir_name) + strlen(file_name) + 2); - } - fix_filename_case(diamond); - fix_filename_slashes(diamond); - return diamond; +char *ci_find_file(const char *dir_name, const char *file_name) { + char *diamond = NULL; + + if (dir_name == NULL && file_name == NULL) + return NULL; + + if (dir_name == NULL) { + diamond = (char *)malloc(strlen(file_name) + 3); + strcpy(diamond, file_name); + } else { + diamond = (char *)malloc(strlen(dir_name) + strlen(file_name) + 2); + append_filename(diamond, dir_name, file_name, strlen(dir_name) + strlen(file_name) + 2); + } + fix_filename_case(diamond); + fix_filename_slashes(diamond); + return diamond; } #else /* Case Insensitive File Find */ -char *ci_find_file(const char *dir_name, const char *file_name) -{ - struct stat statbuf; - struct dirent *entry = nullptr; - DIR *rough = nullptr; - DIR *prevdir = nullptr; - char *diamond = nullptr; - char *directory = nullptr; - char *filename = nullptr; - - if (dir_name == nullptr && file_name == nullptr) - return nullptr; - - if (dir_name != nullptr) { - directory = (char *)malloc(strlen(dir_name) + 1); - strcpy(directory, dir_name); - - fix_filename_case(directory); - fix_filename_slashes(directory); - } - - if (file_name != nullptr) { - filename = (char *)malloc(strlen(file_name) + 1); - strcpy(filename, file_name); - - fix_filename_case(filename); - fix_filename_slashes(filename); - } - - if (directory == nullptr) { - char *match = nullptr; - int match_len = 0; - int dir_len = 0; - - match = get_filename(filename); - if (match == nullptr) - return nullptr; - - match_len = strlen(match); - dir_len = (match - filename); - - if (dir_len == 0) { - directory = (char *)malloc(2); - strcpy(directory,"."); - } else { - directory = (char *)malloc(dir_len + 1); - strncpy(directory, file_name, dir_len); - directory[dir_len] = '\0'; - } - - filename = (char *)malloc(match_len + 1); - strncpy(filename, match, match_len); - filename[match_len] = '\0'; - } - - if ((prevdir = opendir(".")) == nullptr) { - fprintf(stderr, "ci_find_file: cannot open current working directory\n"); - return nullptr; - } - - if (chdir(directory) == -1) { - fprintf(stderr, "ci_find_file: cannot change to directory: %s\n", directory); - return nullptr; - } - - if ((rough = opendir(directory)) == nullptr) { - fprintf(stderr, "ci_find_file: cannot open directory: %s\n", directory); - return nullptr; - } - - while ((entry = readdir(rough)) != nullptr) { - lstat(entry->d_name, &statbuf); - if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { - if (strcasecmp(filename, entry->d_name) == 0) { +char *ci_find_file(const char *dir_name, const char *file_name) { + struct stat statbuf; + struct dirent *entry = nullptr; + DIR *rough = nullptr; + DIR *prevdir = nullptr; + char *diamond = nullptr; + char *directory = nullptr; + char *filename = nullptr; + + if (dir_name == nullptr && file_name == nullptr) + return nullptr; + + if (dir_name != nullptr) { + directory = (char *)malloc(strlen(dir_name) + 1); + strcpy(directory, dir_name); + + fix_filename_case(directory); + fix_filename_slashes(directory); + } + + if (file_name != nullptr) { + filename = (char *)malloc(strlen(file_name) + 1); + strcpy(filename, file_name); + + fix_filename_case(filename); + fix_filename_slashes(filename); + } + + if (directory == nullptr) { + char *match = nullptr; + int match_len = 0; + int dir_len = 0; + + match = get_filename(filename); + if (match == nullptr) + return nullptr; + + match_len = strlen(match); + dir_len = (match - filename); + + if (dir_len == 0) { + directory = (char *)malloc(2); + strcpy(directory, "."); + } else { + directory = (char *)malloc(dir_len + 1); + strncpy(directory, file_name, dir_len); + directory[dir_len] = '\0'; + } + + filename = (char *)malloc(match_len + 1); + strncpy(filename, match, match_len); + filename[match_len] = '\0'; + } + + if ((prevdir = opendir(".")) == nullptr) { + fprintf(stderr, "ci_find_file: cannot open current working directory\n"); + return nullptr; + } + + if (chdir(directory) == -1) { + fprintf(stderr, "ci_find_file: cannot change to directory: %s\n", directory); + return nullptr; + } + + if ((rough = opendir(directory)) == nullptr) { + fprintf(stderr, "ci_find_file: cannot open directory: %s\n", directory); + return nullptr; + } + + while ((entry = readdir(rough)) != nullptr) { + lstat(entry->d_name, &statbuf); + if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { + if (strcasecmp(filename, entry->d_name) == 0) { #if AGS_PLATFORM_DEBUG - fprintf(stderr, "ci_find_file: Looked for %s in rough %s, found diamond %s.\n", filename, directory, entry->d_name); + fprintf(stderr, "ci_find_file: Looked for %s in rough %s, found diamond %s.\n", filename, directory, entry->d_name); #endif // AGS_PLATFORM_DEBUG - diamond = (char *)malloc(strlen(directory) + strlen(entry->d_name) + 2); - append_filename(diamond, directory, entry->d_name, strlen(directory) + strlen(entry->d_name) + 2); - break; - } - } - } - closedir(rough); + diamond = (char *)malloc(strlen(directory) + strlen(entry->d_name) + 2); + append_filename(diamond, directory, entry->d_name, strlen(directory) + strlen(entry->d_name) + 2); + break; + } + } + } + closedir(rough); - fchdir(dirfd(prevdir)); - closedir(prevdir); + fchdir(dirfd(prevdir)); + closedir(prevdir); - free(directory); - free(filename); + free(directory); + free(filename); - return diamond; + return diamond; } #endif /* Case Insensitive fopen */ -Stream *ci_fopen(const char *file_name, FileOpenMode open_mode, FileWorkMode work_mode) -{ +Stream *ci_fopen(const char *file_name, FileOpenMode open_mode, FileWorkMode work_mode) { #if !defined (AGS_CASE_SENSITIVE_FILESYSTEM) - return File::OpenFile(file_name, open_mode, work_mode); + return File::OpenFile(file_name, open_mode, work_mode); #else - Stream *fs = nullptr; - char *fullpath = ci_find_file(nullptr, (char*)file_name); - - /* If I didn't find a file, this could be writing a new file, - so use whatever file_name they passed */ - if (fullpath == nullptr) { - fs = File::OpenFile(file_name, open_mode, work_mode); - } else { - fs = File::OpenFile(fullpath, open_mode, work_mode); - free(fullpath); - } - - return fs; + Stream *fs = nullptr; + char *fullpath = ci_find_file(nullptr, (char *)file_name); + + /* If I didn't find a file, this could be writing a new file, + so use whatever file_name they passed */ + if (fullpath == nullptr) { + fs = File::OpenFile(file_name, open_mode, work_mode); + } else { + fs = File::OpenFile(fullpath, open_mode, work_mode); + free(fullpath); + } + + return fs; #endif } diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h index bac661c35d77..e658ebf2bd6d 100644 --- a/engines/ags/shared/util/misc.h +++ b/engines/ags/shared/util/misc.h @@ -23,11 +23,11 @@ /* Copyright (c) 2003, Shawn R. Walker All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright @@ -36,7 +36,7 @@ * Neither the name of Shawn R. Walker nor names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -54,7 +54,11 @@ #include "util/file.h" // TODO: extract filestream mode constants -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later // Case-insensitive file lookup functions. On case-insensitive systems @@ -64,8 +68,8 @@ using namespace AGS; // FIXME later // They are used as a system-independent way to open a file when its name // case can be ignored. Common::Stream *ci_fopen(const char *file_name, - Common::FileOpenMode open_mode = Common::kFile_Open, - Common::FileWorkMode work_mode = Common::kFile_Read); + Common::FileOpenMode open_mode = Common::kFile_Open, + Common::FileWorkMode work_mode = Common::kFile_Read); // TODO: return String object char *ci_find_file(const char *dir_name, const char *file_name); diff --git a/engines/ags/shared/util/multifilelib.h b/engines/ags/shared/util/multifilelib.h index c7a0eea819c6..5def30343673 100644 --- a/engines/ags/shared/util/multifilelib.h +++ b/engines/ags/shared/util/multifilelib.h @@ -37,44 +37,39 @@ #include "core/asset.h" #include "util/stream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // // MultiFileLib utilities: (de)serialization of asset library in MFL format // -namespace MFLUtil -{ - enum MFLError - { - kMFLNoError = 0, - kMFLErrNoLibSig = -1, // library signature does not match - kMFLErrLibVersion = -2, // library version unsupported - kMFLErrNoLibBase = -3, // file is not library base (head) - kMFLErrLibAssetCount = -4, // too many assets in library - }; +namespace MFLUtil { +enum MFLError { + kMFLNoError = 0, + kMFLErrNoLibSig = -1, // library signature does not match + kMFLErrLibVersion = -2, // library version unsupported + kMFLErrNoLibBase = -3, // file is not library base (head) + kMFLErrLibAssetCount = -4, // too many assets in library +}; - enum MFLVersion - { - kMFLVersion_SingleLib = 6, - kMFLVersion_MultiV10 = 10, - kMFLVersion_MultiV11 = 11, - kMFLVersion_MultiV15 = 15, // unknown differences - kMFLVersion_MultiV20 = 20, - kMFLVersion_MultiV21 = 21, - kMFLVersion_MultiV30 = 30 // 64-bit file support, loose limits - }; +enum MFLVersion { + kMFLVersion_SingleLib = 6, + kMFLVersion_MultiV10 = 10, + kMFLVersion_MultiV11 = 11, + kMFLVersion_MultiV15 = 15, // unknown differences + kMFLVersion_MultiV20 = 20, + kMFLVersion_MultiV21 = 21, + kMFLVersion_MultiV30 = 30 // 64-bit file support, loose limits +}; - // Maximal number of the data files in one library chain (1-byte index) - const size_t MaxMultiLibFiles = 256; +// Maximal number of the data files in one library chain (1-byte index) +const size_t MaxMultiLibFiles = 256; - MFLError TestIsMFL(Stream *in, bool test_is_main = false); - MFLError ReadHeader(AssetLibInfo &lib, Stream *in); +MFLError TestIsMFL(Stream *in, bool test_is_main = false); +MFLError ReadHeader(AssetLibInfo &lib, Stream *in); - void WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_index, Stream *out); - void WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out); +void WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_index, Stream *out); +void WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out); }; } // namespace Common diff --git a/engines/ags/shared/util/mutifilelib.cpp b/engines/ags/shared/util/mutifilelib.cpp index 7f053bb74cf5..490d3ba1f428 100644 --- a/engines/ags/shared/util/mutifilelib.cpp +++ b/engines/ags/shared/util/mutifilelib.cpp @@ -25,449 +25,396 @@ #include "util/stream.h" #include "util/string_utils.h" -namespace AGS -{ -namespace Common -{ - -namespace MFLUtil -{ - const String HeadSig = "CLIB\x1a"; - const String TailSig = "CLIB\x1\x2\x3\x4SIGE"; - - static const size_t SingleFilePswLen = 13; - - static const size_t MaxAssetFileLen = 100; - static const size_t MaxDataFileLen = 50; - static const size_t V10LibFileLen = 20; - static const size_t V10AssetFileLen = 25; - - static const int EncryptionRandSeed = 9338638; - static const String EncryptionString = "My\x1\xde\x4Jibzle"; - - MFLError ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_version, soff_t *p_abs_offset); - MFLError ReadSingleFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); - MFLError ReadMultiFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); - MFLError ReadV10(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); - MFLError ReadV20(AssetLibInfo &lib, Stream *in); - MFLError ReadV21(AssetLibInfo &lib, Stream *in); - MFLError ReadV30(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); - - void WriteV30(const AssetLibInfo &lib, MFLVersion lib_version, Stream *out); - - // Encryption / decryption - int GetNextPseudoRand(int &rand_val); - void DecryptText(char *text); - void ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &rand_val); - int8_t ReadEncInt8(Stream *in, int &rand_val); - int32_t ReadEncInt32(Stream *in, int &rand_val); - void ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_val); +namespace AGS { +namespace Common { + +namespace MFLUtil { +const String HeadSig = "CLIB\x1a"; +const String TailSig = "CLIB\x1\x2\x3\x4SIGE"; + +static const size_t SingleFilePswLen = 13; + +static const size_t MaxAssetFileLen = 100; +static const size_t MaxDataFileLen = 50; +static const size_t V10LibFileLen = 20; +static const size_t V10AssetFileLen = 25; + +static const int EncryptionRandSeed = 9338638; +static const String EncryptionString = "My\x1\xde\x4Jibzle"; + +MFLError ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_version, soff_t *p_abs_offset); +MFLError ReadSingleFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); +MFLError ReadMultiFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); +MFLError ReadV10(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); +MFLError ReadV20(AssetLibInfo &lib, Stream *in); +MFLError ReadV21(AssetLibInfo &lib, Stream *in); +MFLError ReadV30(AssetLibInfo &lib, Stream *in, MFLVersion lib_version); + +void WriteV30(const AssetLibInfo &lib, MFLVersion lib_version, Stream *out); + +// Encryption / decryption +int GetNextPseudoRand(int &rand_val); +void DecryptText(char *text); +void ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &rand_val); +int8_t ReadEncInt8(Stream *in, int &rand_val); +int32_t ReadEncInt32(Stream *in, int &rand_val); +void ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_val); }; -MFLUtil::MFLError MFLUtil::TestIsMFL(Stream *in, bool test_is_main) -{ - MFLVersion lib_version; - MFLError err = ReadSigsAndVersion(in, &lib_version, nullptr); - if (err == kMFLNoError) - { - if (lib_version >= kMFLVersion_MultiV10 && test_is_main) - { - // this version supports multiple data files, check if it is the first one - if (in->ReadByte() != 0) - return kMFLErrNoLibBase; // not first datafile in chain - } - } - return err; +MFLUtil::MFLError MFLUtil::TestIsMFL(Stream *in, bool test_is_main) { + MFLVersion lib_version; + MFLError err = ReadSigsAndVersion(in, &lib_version, nullptr); + if (err == kMFLNoError) { + if (lib_version >= kMFLVersion_MultiV10 && test_is_main) { + // this version supports multiple data files, check if it is the first one + if (in->ReadByte() != 0) + return kMFLErrNoLibBase; // not first datafile in chain + } + } + return err; } -MFLUtil::MFLError MFLUtil::ReadHeader(AssetLibInfo &lib, Stream *in) -{ - MFLVersion lib_version; - soff_t abs_offset; - MFLError err = ReadSigsAndVersion(in, &lib_version, &abs_offset); - if (err != kMFLNoError) - return err; - - if (lib_version >= kMFLVersion_MultiV10) - { - // read newer clib versions (versions 10+) - err = ReadMultiFileLib(lib, in, lib_version); - } - else - { - // read older clib versions (versions 1 to 9) - err = ReadSingleFileLib(lib, in, lib_version); - } - - // apply absolute offset for the assets contained in base data file - // (since only base data file may be EXE file, other clib parts are always on their own) - if (abs_offset > 0) - { - for (AssetVec::iterator it = lib.AssetInfos.begin(); - it != lib.AssetInfos.end(); ++it) - { - if (it->LibUid == 0) - it->Offset += abs_offset; - } - } - return err; +MFLUtil::MFLError MFLUtil::ReadHeader(AssetLibInfo &lib, Stream *in) { + MFLVersion lib_version; + soff_t abs_offset; + MFLError err = ReadSigsAndVersion(in, &lib_version, &abs_offset); + if (err != kMFLNoError) + return err; + + if (lib_version >= kMFLVersion_MultiV10) { + // read newer clib versions (versions 10+) + err = ReadMultiFileLib(lib, in, lib_version); + } else { + // read older clib versions (versions 1 to 9) + err = ReadSingleFileLib(lib, in, lib_version); + } + + // apply absolute offset for the assets contained in base data file + // (since only base data file may be EXE file, other clib parts are always on their own) + if (abs_offset > 0) { + for (AssetVec::iterator it = lib.AssetInfos.begin(); + it != lib.AssetInfos.end(); ++it) { + if (it->LibUid == 0) + it->Offset += abs_offset; + } + } + return err; } -MFLUtil::MFLError MFLUtil::ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_version, soff_t *p_abs_offset) -{ - soff_t abs_offset = 0; // library offset in this file - String sig; - // check multifile lib signature at the beginning of file - sig.ReadCount(in, HeadSig.GetLength()); - if (HeadSig.Compare(sig) != 0) - { - // signature not found, check signature at the end of file - in->Seek(-(soff_t)TailSig.GetLength(), kSeekEnd); - // by definition, tail marks the max absolute offset value - auto tail_abs_offset = in->GetPosition(); - sig.ReadCount(in, TailSig.GetLength()); - // signature not found, return error code - if (TailSig.Compare(sig) != 0) - return kMFLErrNoLibSig; - - // it's an appended-to-end-of-exe thing; - // now we need to read multifile lib offset value, but we do not know - // if its 32-bit or 64-bit yet, so we'll have to test both - in->Seek(-(soff_t)TailSig.GetLength() - sizeof(int64_t), kSeekEnd); - abs_offset = in->ReadInt64(); - in->Seek(-(soff_t)sizeof(int32_t), kSeekCurrent); - soff_t abs_offset_32 = in->ReadInt32(); - - // test for header signature again, with 64-bit and 32-bit offsets if necessary - if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) - { - in->Seek(abs_offset, kSeekBegin); - sig.ReadCount(in, HeadSig.GetLength()); - } - - // try again with 32-bit offset - if (HeadSig.Compare(sig) != 0) - { - abs_offset = abs_offset_32; - if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) - { - in->Seek(abs_offset, kSeekBegin); - sig.ReadCount(in, HeadSig.GetLength()); - } - if (HeadSig.Compare(sig) != 0) - { - // nope, no luck, bad / unknown format - return kMFLErrNoLibSig; - } - } - } - // if we've reached this point we must be right behind the header signature - - // read library header - MFLVersion lib_version = (MFLVersion)in->ReadByte(); - if ((lib_version != kMFLVersion_SingleLib) && (lib_version != kMFLVersion_MultiV10) && - (lib_version != kMFLVersion_MultiV11) && (lib_version != kMFLVersion_MultiV15) && - (lib_version != kMFLVersion_MultiV20) && (lib_version != kMFLVersion_MultiV21) && - lib_version != kMFLVersion_MultiV30) - return kMFLErrLibVersion; // unsupported version - - if (p_lib_version) - *p_lib_version = lib_version; - if (p_abs_offset) - *p_abs_offset = abs_offset; - return kMFLNoError; +MFLUtil::MFLError MFLUtil::ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_version, soff_t *p_abs_offset) { + soff_t abs_offset = 0; // library offset in this file + String sig; + // check multifile lib signature at the beginning of file + sig.ReadCount(in, HeadSig.GetLength()); + if (HeadSig.Compare(sig) != 0) { + // signature not found, check signature at the end of file + in->Seek(-(soff_t)TailSig.GetLength(), kSeekEnd); + // by definition, tail marks the max absolute offset value + auto tail_abs_offset = in->GetPosition(); + sig.ReadCount(in, TailSig.GetLength()); + // signature not found, return error code + if (TailSig.Compare(sig) != 0) + return kMFLErrNoLibSig; + + // it's an appended-to-end-of-exe thing; + // now we need to read multifile lib offset value, but we do not know + // if its 32-bit or 64-bit yet, so we'll have to test both + in->Seek(-(soff_t)TailSig.GetLength() - sizeof(int64_t), kSeekEnd); + abs_offset = in->ReadInt64(); + in->Seek(-(soff_t)sizeof(int32_t), kSeekCurrent); + soff_t abs_offset_32 = in->ReadInt32(); + + // test for header signature again, with 64-bit and 32-bit offsets if necessary + if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) { + in->Seek(abs_offset, kSeekBegin); + sig.ReadCount(in, HeadSig.GetLength()); + } + + // try again with 32-bit offset + if (HeadSig.Compare(sig) != 0) { + abs_offset = abs_offset_32; + if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) { + in->Seek(abs_offset, kSeekBegin); + sig.ReadCount(in, HeadSig.GetLength()); + } + if (HeadSig.Compare(sig) != 0) { + // nope, no luck, bad / unknown format + return kMFLErrNoLibSig; + } + } + } + // if we've reached this point we must be right behind the header signature + + // read library header + MFLVersion lib_version = (MFLVersion)in->ReadByte(); + if ((lib_version != kMFLVersion_SingleLib) && (lib_version != kMFLVersion_MultiV10) && + (lib_version != kMFLVersion_MultiV11) && (lib_version != kMFLVersion_MultiV15) && + (lib_version != kMFLVersion_MultiV20) && (lib_version != kMFLVersion_MultiV21) && + lib_version != kMFLVersion_MultiV30) + return kMFLErrLibVersion; // unsupported version + + if (p_lib_version) + *p_lib_version = lib_version; + if (p_abs_offset) + *p_abs_offset = abs_offset; + return kMFLNoError; } -MFLUtil::MFLError MFLUtil::ReadSingleFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) -{ - int passwmodifier = in->ReadByte(); - in->ReadInt8(); // unused byte - lib.LibFileNames.resize(1); // only one library part - size_t asset_count = in->ReadInt16(); - lib.AssetInfos.resize(asset_count); - - in->Seek(SingleFilePswLen, kSeekCurrent); // skip password dooberry - char fn_buf[SingleFilePswLen + 1]; - // read information on contents - for (size_t i = 0; i < asset_count; ++i) - { - in->Read(fn_buf, SingleFilePswLen); - fn_buf[SingleFilePswLen] = 0; - for (char *c = fn_buf; *c; ++c) - *c -= passwmodifier; - lib.AssetInfos[i].FileName = fn_buf; - lib.AssetInfos[i].LibUid = 0; - } - for (size_t i = 0; i < asset_count; ++i) - { - lib.AssetInfos[i].Size = in->ReadInt32(); - } - in->Seek(2 * asset_count, kSeekCurrent); // skip flags & ratio - lib.AssetInfos[0].Offset = in->GetPosition(); - // set offsets (assets are positioned in sequence) - for (size_t i = 1; i < asset_count; ++i) - { - lib.AssetInfos[i].Offset = lib.AssetInfos[i - 1].Offset + lib.AssetInfos[i - 1].Size; - } - // return success - return kMFLNoError; +MFLUtil::MFLError MFLUtil::ReadSingleFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) { + int passwmodifier = in->ReadByte(); + in->ReadInt8(); // unused byte + lib.LibFileNames.resize(1); // only one library part + size_t asset_count = in->ReadInt16(); + lib.AssetInfos.resize(asset_count); + + in->Seek(SingleFilePswLen, kSeekCurrent); // skip password dooberry + char fn_buf[SingleFilePswLen + 1]; + // read information on contents + for (size_t i = 0; i < asset_count; ++i) { + in->Read(fn_buf, SingleFilePswLen); + fn_buf[SingleFilePswLen] = 0; + for (char *c = fn_buf; *c; ++c) + *c -= passwmodifier; + lib.AssetInfos[i].FileName = fn_buf; + lib.AssetInfos[i].LibUid = 0; + } + for (size_t i = 0; i < asset_count; ++i) { + lib.AssetInfos[i].Size = in->ReadInt32(); + } + in->Seek(2 * asset_count, kSeekCurrent); // skip flags & ratio + lib.AssetInfos[0].Offset = in->GetPosition(); + // set offsets (assets are positioned in sequence) + for (size_t i = 1; i < asset_count; ++i) { + lib.AssetInfos[i].Offset = lib.AssetInfos[i - 1].Offset + lib.AssetInfos[i - 1].Size; + } + // return success + return kMFLNoError; } -MFLUtil::MFLError MFLUtil::ReadMultiFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) -{ - if (in->ReadByte() != 0) - return kMFLErrNoLibBase; // not first datafile in chain - - if (lib_version >= kMFLVersion_MultiV30) - { - // read new clib format with 64-bit files support - return ReadV30(lib, in, lib_version); - } - if (lib_version >= kMFLVersion_MultiV21) - { - // read new clib format with encoding support (versions 21+) - return ReadV21(lib, in); - } - else if (lib_version == kMFLVersion_MultiV20) - { - // read new clib format without encoding support (version 20) - return ReadV20(lib, in); - } - // read older clib format (versions 10 to 19), the ones with shorter filenames - return ReadV10(lib, in, lib_version); +MFLUtil::MFLError MFLUtil::ReadMultiFileLib(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) { + if (in->ReadByte() != 0) + return kMFLErrNoLibBase; // not first datafile in chain + + if (lib_version >= kMFLVersion_MultiV30) { + // read new clib format with 64-bit files support + return ReadV30(lib, in, lib_version); + } + if (lib_version >= kMFLVersion_MultiV21) { + // read new clib format with encoding support (versions 21+) + return ReadV21(lib, in); + } else if (lib_version == kMFLVersion_MultiV20) { + // read new clib format without encoding support (version 20) + return ReadV20(lib, in); + } + // read older clib format (versions 10 to 19), the ones with shorter filenames + return ReadV10(lib, in, lib_version); } -MFLUtil::MFLError MFLUtil::ReadV10(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) -{ - // number of clib parts - size_t mf_count = in->ReadInt32(); - lib.LibFileNames.resize(mf_count); - // filenames for all clib parts; filenames are only 20 chars long in this format version - for (size_t i = 0; i < mf_count; ++i) - { - lib.LibFileNames[i].ReadCount(in, V10LibFileLen); - } - - // number of files in clib - size_t asset_count = in->ReadInt32(); - // read information on clib contents - lib.AssetInfos.resize(asset_count); - // filename array is only 25 chars long in this format version - char fn_buf[V10AssetFileLen]; - for (size_t i = 0; i < asset_count; ++i) - { - in->Read(fn_buf, V10AssetFileLen); - if (lib_version >= kMFLVersion_MultiV11) - DecryptText(fn_buf); - lib.AssetInfos[i].FileName = fn_buf; - } - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].Offset = in->ReadInt32(); - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].Size = in->ReadInt32(); - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].LibUid = in->ReadInt8(); - return kMFLNoError; +MFLUtil::MFLError MFLUtil::ReadV10(AssetLibInfo &lib, Stream *in, MFLVersion lib_version) { + // number of clib parts + size_t mf_count = in->ReadInt32(); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts; filenames are only 20 chars long in this format version + for (size_t i = 0; i < mf_count; ++i) { + lib.LibFileNames[i].ReadCount(in, V10LibFileLen); + } + + // number of files in clib + size_t asset_count = in->ReadInt32(); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + // filename array is only 25 chars long in this format version + char fn_buf[V10AssetFileLen]; + for (size_t i = 0; i < asset_count; ++i) { + in->Read(fn_buf, V10AssetFileLen); + if (lib_version >= kMFLVersion_MultiV11) + DecryptText(fn_buf); + lib.AssetInfos[i].FileName = fn_buf; + } + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Offset = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Size = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].LibUid = in->ReadInt8(); + return kMFLNoError; } -MFLUtil::MFLError MFLUtil::ReadV20(AssetLibInfo &lib, Stream *in) -{ - // number of clib parts - size_t mf_count = in->ReadInt32(); - lib.LibFileNames.resize(mf_count); - // filenames for all clib parts - for (size_t i = 0; i < mf_count; ++i) - { - lib.LibFileNames[i].Read(in, MaxDataFileLen); - } - - // number of files in clib - size_t asset_count = in->ReadInt32(); - // read information on clib contents - lib.AssetInfos.resize(asset_count); - char fn_buf[MaxAssetFileLen]; - for (size_t i = 0; i < asset_count; ++i) - { - short len = in->ReadInt16(); - len /= 5; // CHECKME: why 5? - in->Read(fn_buf, len); - // decrypt filenames - DecryptText(fn_buf); - lib.AssetInfos[i].FileName = fn_buf; - } - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].Offset = in->ReadInt32(); - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].Size = in->ReadInt32(); - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].LibUid = in->ReadInt8(); - return kMFLNoError; +MFLUtil::MFLError MFLUtil::ReadV20(AssetLibInfo &lib, Stream *in) { + // number of clib parts + size_t mf_count = in->ReadInt32(); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts + for (size_t i = 0; i < mf_count; ++i) { + lib.LibFileNames[i].Read(in, MaxDataFileLen); + } + + // number of files in clib + size_t asset_count = in->ReadInt32(); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + char fn_buf[MaxAssetFileLen]; + for (size_t i = 0; i < asset_count; ++i) { + short len = in->ReadInt16(); + len /= 5; // CHECKME: why 5? + in->Read(fn_buf, len); + // decrypt filenames + DecryptText(fn_buf); + lib.AssetInfos[i].FileName = fn_buf; + } + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Offset = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Size = in->ReadInt32(); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].LibUid = in->ReadInt8(); + return kMFLNoError; } -MFLUtil::MFLError MFLUtil::ReadV21(AssetLibInfo &lib, Stream *in) -{ - // init randomizer - int rand_val = in->ReadInt32() + EncryptionRandSeed; - // number of clib parts - size_t mf_count = ReadEncInt32(in, rand_val); - lib.LibFileNames.resize(mf_count); - // filenames for all clib parts - char fn_buf[MaxDataFileLen > MaxAssetFileLen ? MaxDataFileLen : MaxAssetFileLen]; - for (size_t i = 0; i < mf_count; ++i) - { - ReadEncString(fn_buf, MaxDataFileLen, in, rand_val); - lib.LibFileNames[i] = fn_buf; - } - - // number of files in clib - size_t asset_count = ReadEncInt32(in, rand_val); - // read information on clib contents - lib.AssetInfos.resize(asset_count); - for (size_t i = 0; i < asset_count; ++i) - { - ReadEncString(fn_buf, MaxAssetFileLen, in, rand_val); - lib.AssetInfos[i].FileName = fn_buf; - } - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].Offset = ReadEncInt32(in, rand_val); - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].Size = ReadEncInt32(in, rand_val); - for (size_t i = 0; i < asset_count; ++i) - lib.AssetInfos[i].LibUid = ReadEncInt8(in, rand_val); - return kMFLNoError; +MFLUtil::MFLError MFLUtil::ReadV21(AssetLibInfo &lib, Stream *in) { + // init randomizer + int rand_val = in->ReadInt32() + EncryptionRandSeed; + // number of clib parts + size_t mf_count = ReadEncInt32(in, rand_val); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts + char fn_buf[MaxDataFileLen > MaxAssetFileLen ? MaxDataFileLen : MaxAssetFileLen]; + for (size_t i = 0; i < mf_count; ++i) { + ReadEncString(fn_buf, MaxDataFileLen, in, rand_val); + lib.LibFileNames[i] = fn_buf; + } + + // number of files in clib + size_t asset_count = ReadEncInt32(in, rand_val); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + for (size_t i = 0; i < asset_count; ++i) { + ReadEncString(fn_buf, MaxAssetFileLen, in, rand_val); + lib.AssetInfos[i].FileName = fn_buf; + } + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Offset = ReadEncInt32(in, rand_val); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].Size = ReadEncInt32(in, rand_val); + for (size_t i = 0; i < asset_count; ++i) + lib.AssetInfos[i].LibUid = ReadEncInt8(in, rand_val); + return kMFLNoError; } -MFLUtil::MFLError MFLUtil::ReadV30(AssetLibInfo &lib, Stream *in, MFLVersion /* lib_version */) -{ - // NOTE: removed encryption like in v21, because it makes little sense - // with open-source program. But if really wanted it may be restored - // as one of the options here. - /* int flags = */ in->ReadInt32(); // reserved options - // number of clib parts - size_t mf_count = in->ReadInt32(); - lib.LibFileNames.resize(mf_count); - // filenames for all clib parts - for (size_t i = 0; i < mf_count; ++i) - lib.LibFileNames[i] = String::FromStream(in); - - // number of files in clib - size_t asset_count = in->ReadInt32(); - // read information on clib contents - lib.AssetInfos.resize(asset_count); - for (AssetVec::iterator it = lib.AssetInfos.begin(); it != lib.AssetInfos.end(); ++it) - { - it->FileName = String::FromStream(in); - it->LibUid = in->ReadInt8(); - it->Offset = in->ReadInt64(); - it->Size = in->ReadInt64(); - } - return kMFLNoError; +MFLUtil::MFLError MFLUtil::ReadV30(AssetLibInfo &lib, Stream *in, MFLVersion /* lib_version */) { + // NOTE: removed encryption like in v21, because it makes little sense + // with open-source program. But if really wanted it may be restored + // as one of the options here. + /* int flags = */ in->ReadInt32(); // reserved options + // number of clib parts + size_t mf_count = in->ReadInt32(); + lib.LibFileNames.resize(mf_count); + // filenames for all clib parts + for (size_t i = 0; i < mf_count; ++i) + lib.LibFileNames[i] = String::FromStream(in); + + // number of files in clib + size_t asset_count = in->ReadInt32(); + // read information on clib contents + lib.AssetInfos.resize(asset_count); + for (AssetVec::iterator it = lib.AssetInfos.begin(); it != lib.AssetInfos.end(); ++it) { + it->FileName = String::FromStream(in); + it->LibUid = in->ReadInt8(); + it->Offset = in->ReadInt64(); + it->Size = in->ReadInt64(); + } + return kMFLNoError; } -void MFLUtil::WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_index, Stream *out) -{ - out->Write(MFLUtil::HeadSig, MFLUtil::HeadSig.GetLength()); - out->WriteByte(lib_version); - out->WriteByte(lib_index); // file number - - // First datafile in chain: write the table of contents - if (lib_index == 0) - { - WriteV30(lib, lib_version, out); - } +void MFLUtil::WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_index, Stream *out) { + out->Write(MFLUtil::HeadSig, MFLUtil::HeadSig.GetLength()); + out->WriteByte(lib_version); + out->WriteByte(lib_index); // file number + + // First datafile in chain: write the table of contents + if (lib_index == 0) { + WriteV30(lib, lib_version, out); + } } -void MFLUtil::WriteV30(const AssetLibInfo &lib, MFLVersion lib_version, Stream *out) -{ - out->WriteInt32(0); // reserved options - // filenames for all library parts - out->WriteInt32(lib.LibFileNames.size()); - for (size_t i = 0; i < lib.LibFileNames.size(); ++i) - { - StrUtil::WriteCStr(lib.LibFileNames[i], out); - } - - // table of contents for all assets in library - out->WriteInt32(lib.AssetInfos.size()); - for (AssetVec::const_iterator it = lib.AssetInfos.begin(); it != lib.AssetInfos.end(); ++it) - { - StrUtil::WriteCStr(it->FileName, out); - out->WriteInt8(it->LibUid); - out->WriteInt64(it->Offset); - out->WriteInt64(it->Size); - } +void MFLUtil::WriteV30(const AssetLibInfo &lib, MFLVersion lib_version, Stream *out) { + out->WriteInt32(0); // reserved options + // filenames for all library parts + out->WriteInt32(lib.LibFileNames.size()); + for (size_t i = 0; i < lib.LibFileNames.size(); ++i) { + StrUtil::WriteCStr(lib.LibFileNames[i], out); + } + + // table of contents for all assets in library + out->WriteInt32(lib.AssetInfos.size()); + for (AssetVec::const_iterator it = lib.AssetInfos.begin(); it != lib.AssetInfos.end(); ++it) { + StrUtil::WriteCStr(it->FileName, out); + out->WriteInt8(it->LibUid); + out->WriteInt64(it->Offset); + out->WriteInt64(it->Size); + } } -void MFLUtil::WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out) -{ - if (lib_index < kMFLVersion_MultiV30) - out->WriteInt32((int32_t)lib_offset); - else - out->WriteInt64(lib_offset); - out->Write(TailSig, TailSig.GetLength()); +void MFLUtil::WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out) { + if (lib_index < kMFLVersion_MultiV30) + out->WriteInt32((int32_t)lib_offset); + else + out->WriteInt64(lib_offset); + out->Write(TailSig, TailSig.GetLength()); } -void MFLUtil::DecryptText(char *text) -{ - size_t adx = 0; - while (true) - { - text[0] -= EncryptionString[adx]; - if (text[0] == 0) - break; - - adx++; - text++; - - if (adx > 10) // CHECKME: why 10? - adx = 0; - } +void MFLUtil::DecryptText(char *text) { + size_t adx = 0; + while (true) { + text[0] -= EncryptionString[adx]; + if (text[0] == 0) + break; + + adx++; + text++; + + if (adx > 10) // CHECKME: why 10? + adx = 0; + } } -int MFLUtil::GetNextPseudoRand(int &rand_val) -{ - return( ((rand_val = rand_val * 214013L - + 2531011L) >> 16) & 0x7fff ); +int MFLUtil::GetNextPseudoRand(int &rand_val) { + return (((rand_val = rand_val * 214013L + + 2531011L) >> 16) & 0x7fff); } -void MFLUtil::ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &rand_val) -{ - in->ReadArray(data, size, count); - uint8_t *ch = (uint8_t*)data; - const size_t len = size * count; - for (size_t i = 0; i < len; ++i) - { - ch[i] -= GetNextPseudoRand(rand_val); - } +void MFLUtil::ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &rand_val) { + in->ReadArray(data, size, count); + uint8_t *ch = (uint8_t *)data; + const size_t len = size * count; + for (size_t i = 0; i < len; ++i) { + ch[i] -= GetNextPseudoRand(rand_val); + } } -int8_t MFLUtil::ReadEncInt8(Stream *in, int &rand_val) -{ - return in->ReadByte() - GetNextPseudoRand(rand_val); +int8_t MFLUtil::ReadEncInt8(Stream *in, int &rand_val) { + return in->ReadByte() - GetNextPseudoRand(rand_val); } -int32_t MFLUtil::ReadEncInt32(Stream *in, int &rand_val) -{ - int val; - ReadEncArray(&val, sizeof(int32_t), 1, in, rand_val); +int32_t MFLUtil::ReadEncInt32(Stream *in, int &rand_val) { + int val; + ReadEncArray(&val, sizeof(int32_t), 1, in, rand_val); #if AGS_PLATFORM_ENDIAN_BIG - AGS::Common::BitByteOperations::SwapBytesInt32(val); + AGS::Common::BitByteOperations::SwapBytesInt32(val); #endif - return val; + return val; } -void MFLUtil::ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_val) -{ - size_t i = 0; - while ((i == 0) || (buffer[i - 1] != 0)) - { - buffer[i] = in->ReadByte() - GetNextPseudoRand(rand_val); - if (i < max_len - 1) - i++; - else - break; // avoid an endless loop - } +void MFLUtil::ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_val) { + size_t i = 0; + while ((i == 0) || (buffer[i - 1] != 0)) { + buffer[i] = in->ReadByte() - GetNextPseudoRand(rand_val); + if (i < max_len - 1) + i++; + else + break; // avoid an endless loop + } } } // namespace AGS diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp index cd007457983b..2b75fe894337 100644 --- a/engines/ags/shared/util/path.cpp +++ b/engines/ags/shared/util/path.cpp @@ -33,235 +33,209 @@ #define MAX_PATH 512 #endif -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -namespace Path -{ +namespace Path { -bool IsDirectory(const String &filename) -{ - // stat() does not like trailing slashes, remove them - String fixed_path = MakePathNoSlash(filename); - return ags_directory_exists(fixed_path.GetCStr()) != 0; +bool IsDirectory(const String &filename) { + // stat() does not like trailing slashes, remove them + String fixed_path = MakePathNoSlash(filename); + return ags_directory_exists(fixed_path.GetCStr()) != 0; } -bool IsFile(const String &filename) -{ - return ags_file_exists(filename.GetCStr()) != 0; +bool IsFile(const String &filename) { + return ags_file_exists(filename.GetCStr()) != 0; } -bool IsFileOrDir(const String &filename) -{ - // stat() does not like trailing slashes, remove them - String fixed_path = MakePathNoSlash(filename); - return ags_path_exists(fixed_path.GetCStr()) != 0; +bool IsFileOrDir(const String &filename) { + // stat() does not like trailing slashes, remove them + String fixed_path = MakePathNoSlash(filename); + return ags_path_exists(fixed_path.GetCStr()) != 0; } -int ComparePaths(const String &path1, const String &path2) -{ - // Make minimal absolute paths - String fixed_path1 = MakeAbsolutePath(path1); - String fixed_path2 = MakeAbsolutePath(path2); +int ComparePaths(const String &path1, const String &path2) { + // Make minimal absolute paths + String fixed_path1 = MakeAbsolutePath(path1); + String fixed_path2 = MakeAbsolutePath(path2); - fixed_path1.TrimRight('/'); - fixed_path2.TrimRight('/'); + fixed_path1.TrimRight('/'); + fixed_path2.TrimRight('/'); - int cmp_result = + int cmp_result = #if defined AGS_CASE_SENSITIVE_FILESYSTEM - fixed_path1.Compare(fixed_path2); + fixed_path1.Compare(fixed_path2); #else - fixed_path1.CompareNoCase(fixed_path2); + fixed_path1.CompareNoCase(fixed_path2); #endif // AGS_CASE_SENSITIVE_FILESYSTEM - return cmp_result; -} - -String GetDirectoryPath(const String &path) -{ - if (IsDirectory(path)) - return path; - - String dir = path; - FixupPath(dir); - size_t slash_at = dir.FindCharReverse('/'); - if (slash_at != -1) - { - dir.ClipMid(slash_at + 1); - return dir; - } - return "./"; -} - -bool IsSameOrSubDir(const String &parent, const String &path) -{ - char can_parent[MAX_PATH]; - char can_path[MAX_PATH]; - char relative[MAX_PATH]; - // canonicalize_filename treats "." as "./." (file in working dir) - const char *use_parent = parent == "." ? "./" : parent; - const char *use_path = path == "." ? "./" : path; - canonicalize_filename(can_parent, use_parent, MAX_PATH); - canonicalize_filename(can_path, use_path, MAX_PATH); - const char *pstr = make_relative_filename(relative, can_parent, can_path, MAX_PATH); - if (!pstr) - return false; - for (pstr = strstr(pstr, ".."); pstr && *pstr; pstr = strstr(pstr, "..")) - { - pstr += 2; - if (*pstr == '/' || *pstr == '\\' || *pstr == 0) - return false; - } - return true; -} - -void FixupPath(String &path) -{ + return cmp_result; +} + +String GetDirectoryPath(const String &path) { + if (IsDirectory(path)) + return path; + + String dir = path; + FixupPath(dir); + size_t slash_at = dir.FindCharReverse('/'); + if (slash_at != -1) { + dir.ClipMid(slash_at + 1); + return dir; + } + return "./"; +} + +bool IsSameOrSubDir(const String &parent, const String &path) { + char can_parent[MAX_PATH]; + char can_path[MAX_PATH]; + char relative[MAX_PATH]; + // canonicalize_filename treats "." as "./." (file in working dir) + const char *use_parent = parent == "." ? "./" : parent; + const char *use_path = path == "." ? "./" : path; + canonicalize_filename(can_parent, use_parent, MAX_PATH); + canonicalize_filename(can_path, use_path, MAX_PATH); + const char *pstr = make_relative_filename(relative, can_parent, can_path, MAX_PATH); + if (!pstr) + return false; + for (pstr = strstr(pstr, ".."); pstr && *pstr; pstr = strstr(pstr, "..")) { + pstr += 2; + if (*pstr == '/' || *pstr == '\\' || *pstr == 0) + return false; + } + return true; +} + +void FixupPath(String &path) { #if AGS_PLATFORM_OS_WINDOWS - path.Replace('\\', '/'); // bring Windows path separators to uniform style + path.Replace('\\', '/'); // bring Windows path separators to uniform style #endif } -String MakePathNoSlash(const String &path) -{ - String dir_path = path; - FixupPath(dir_path); +String MakePathNoSlash(const String &path) { + String dir_path = path; + FixupPath(dir_path); #if AGS_PLATFORM_OS_WINDOWS - // if the path is 'x:/' don't strip the slash - if (path.GetLength() == 3 && path[1u] == ':') - ; - else + // if the path is 'x:/' don't strip the slash + if (path.GetLength() == 3 && path[1u] == ':') + ; + else #endif - // if the path is '/' don't strip the slash - if (dir_path.GetLength() > 1) - dir_path.TrimRight('/'); - return dir_path; -} - -String MakeTrailingSlash(const String &path) -{ - String dir_path = path; - FixupPath(dir_path); - if (dir_path.GetLast() != '/') - dir_path.AppendChar('/'); - return dir_path; -} - -String MakeAbsolutePath(const String &path) -{ - if (path.IsEmpty()) - { - return ""; - } - // canonicalize_filename treats "." as "./." (file in working dir) - String abs_path = path == "." ? "./" : path; + // if the path is '/' don't strip the slash + if (dir_path.GetLength() > 1) + dir_path.TrimRight('/'); + return dir_path; +} + +String MakeTrailingSlash(const String &path) { + String dir_path = path; + FixupPath(dir_path); + if (dir_path.GetLast() != '/') + dir_path.AppendChar('/'); + return dir_path; +} + +String MakeAbsolutePath(const String &path) { + if (path.IsEmpty()) { + return ""; + } + // canonicalize_filename treats "." as "./." (file in working dir) + String abs_path = path == "." ? "./" : path; #if AGS_PLATFORM_OS_WINDOWS - // NOTE: cannot use long path names in the engine, because it does not have unicode strings support - // - //char long_path_buffer[MAX_PATH]; - //if (GetLongPathNameA(path, long_path_buffer, MAX_PATH) > 0) - //{ - // abs_path = long_path_buffer; - //} + // NOTE: cannot use long path names in the engine, because it does not have unicode strings support + // + //char long_path_buffer[MAX_PATH]; + //if (GetLongPathNameA(path, long_path_buffer, MAX_PATH) > 0) + //{ + // abs_path = long_path_buffer; + //} #endif - char buf[MAX_PATH]; - canonicalize_filename(buf, abs_path, MAX_PATH); - abs_path = buf; - FixupPath(abs_path); - return abs_path; -} - -String MakeRelativePath(const String &base, const String &path) -{ - char can_parent[MAX_PATH]; - char can_path[MAX_PATH]; - char relative[MAX_PATH]; - // canonicalize_filename treats "." as "./." (file in working dir) - const char *use_parent = base == "." ? "./" : base; - const char *use_path = path == "." ? "./" : path; - canonicalize_filename(can_parent, use_parent, MAX_PATH); - canonicalize_filename(can_path, use_path, MAX_PATH); - String rel_path = make_relative_filename(relative, can_parent, can_path, MAX_PATH); - FixupPath(rel_path); - return rel_path; -} - -String ConcatPaths(const String &parent, const String &child) -{ - String path = parent; - FixupPath(path); - if (path.GetLast() != '/') - path.AppendChar('/'); - path.Append(child); - return path; -} - -String FixupSharedFilename(const String &filename) -{ - const char *illegal_chars = "\\/:?\"<>|*"; - String fixed_name = filename; - for (size_t i = 0; i < filename.GetLength(); ++i) - { - if (filename[i] < ' ') - { - fixed_name.SetAt(i, '_'); - } - else - { - for (const char *ch_ptr = illegal_chars; *ch_ptr; ++ch_ptr) - if (filename[i] == *ch_ptr) - fixed_name.SetAt(i, '_'); - } - } - return fixed_name; -} - -String GetPathInASCII(const String &path) -{ + char buf[MAX_PATH]; + canonicalize_filename(buf, abs_path, MAX_PATH); + abs_path = buf; + FixupPath(abs_path); + return abs_path; +} + +String MakeRelativePath(const String &base, const String &path) { + char can_parent[MAX_PATH]; + char can_path[MAX_PATH]; + char relative[MAX_PATH]; + // canonicalize_filename treats "." as "./." (file in working dir) + const char *use_parent = base == "." ? "./" : base; + const char *use_path = path == "." ? "./" : path; + canonicalize_filename(can_parent, use_parent, MAX_PATH); + canonicalize_filename(can_path, use_path, MAX_PATH); + String rel_path = make_relative_filename(relative, can_parent, can_path, MAX_PATH); + FixupPath(rel_path); + return rel_path; +} + +String ConcatPaths(const String &parent, const String &child) { + String path = parent; + FixupPath(path); + if (path.GetLast() != '/') + path.AppendChar('/'); + path.Append(child); + return path; +} + +String FixupSharedFilename(const String &filename) { + const char *illegal_chars = "\\/:?\"<>|*"; + String fixed_name = filename; + for (size_t i = 0; i < filename.GetLength(); ++i) { + if (filename[i] < ' ') { + fixed_name.SetAt(i, '_'); + } else { + for (const char *ch_ptr = illegal_chars; *ch_ptr; ++ch_ptr) + if (filename[i] == *ch_ptr) + fixed_name.SetAt(i, '_'); + } + } + return fixed_name; +} + +String GetPathInASCII(const String &path) { #if AGS_PLATFORM_OS_WINDOWS - char ascii_buffer[MAX_PATH]; - if (GetShortPathNameA(path, ascii_buffer, MAX_PATH) == 0) - return ""; - return ascii_buffer; + char ascii_buffer[MAX_PATH]; + if (GetShortPathNameA(path, ascii_buffer, MAX_PATH) == 0) + return ""; + return ascii_buffer; #else - // TODO: implement conversion for other platforms! - return path; + // TODO: implement conversion for other platforms! + return path; #endif } #if AGS_PLATFORM_OS_WINDOWS -String WidePathNameToAnsi(LPCWSTR pathw) -{ - WCHAR short_path[MAX_PATH]; - char ascii_buffer[MAX_PATH]; - LPCWSTR arg_path = pathw; - if (GetShortPathNameW(arg_path, short_path, MAX_PATH) == 0) - return ""; - WideCharToMultiByte(CP_ACP, 0, short_path, -1, ascii_buffer, MAX_PATH, NULL, NULL); - return ascii_buffer; +String WidePathNameToAnsi(LPCWSTR pathw) { + WCHAR short_path[MAX_PATH]; + char ascii_buffer[MAX_PATH]; + LPCWSTR arg_path = pathw; + if (GetShortPathNameW(arg_path, short_path, MAX_PATH) == 0) + return ""; + WideCharToMultiByte(CP_ACP, 0, short_path, -1, ascii_buffer, MAX_PATH, NULL, NULL); + return ascii_buffer; } #endif -String GetCmdLinePathInASCII(const char *arg, int arg_index) -{ +String GetCmdLinePathInASCII(const char *arg, int arg_index) { #if AGS_PLATFORM_OS_WINDOWS - // Hack for Windows in case there are unicode chars in the path. - // The normal argv[] array has ????? instead of the unicode chars - // and fails, so instead we manually get the short file name, which - // is always using ASCII chars. - int wargc = 0; - LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); - if (wargv == nullptr) - return ""; - String path; - if (arg_index <= wargc) - path = WidePathNameToAnsi(wargv[arg_index]); - LocalFree(wargv); - return path; + // Hack for Windows in case there are unicode chars in the path. + // The normal argv[] array has ????? instead of the unicode chars + // and fails, so instead we manually get the short file name, which + // is always using ASCII chars. + int wargc = 0; + LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); + if (wargv == nullptr) + return ""; + String path; + if (arg_index <= wargc) + path = WidePathNameToAnsi(wargv[arg_index]); + LocalFree(wargv); + return path; #else - // TODO: implement conversion for other platforms! - return arg; + // TODO: implement conversion for other platforms! + return arg; #endif } diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h index 87d1e0596ab9..6b4da1924f54 100644 --- a/engines/ags/shared/util/path.h +++ b/engines/ags/shared/util/path.h @@ -31,60 +31,57 @@ #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -namespace Path -{ - // Tells if the given path is a directory - bool IsDirectory(const String &directory); - // Tells if the given path is a file - bool IsFile(const String &filename); - // Tells if the given path is file or directory; - // may be used to check if it's valid to use - bool IsFileOrDir(const String &filename); +namespace Path { +// Tells if the given path is a directory +bool IsDirectory(const String &directory); +// Tells if the given path is a file +bool IsFile(const String &filename); +// Tells if the given path is file or directory; +// may be used to check if it's valid to use +bool IsFileOrDir(const String &filename); - // Makes a platform-dependant path comparison. - // This takes into consideration platform's filename case (in)sensivity and - // DOS-compatible 8.3 filenames; - // The result value corresponds to stdlib strcmp function. - int ComparePaths(const String &path1, const String &path2); +// Makes a platform-dependant path comparison. +// This takes into consideration platform's filename case (in)sensivity and +// DOS-compatible 8.3 filenames; +// The result value corresponds to stdlib strcmp function. +int ComparePaths(const String &path1, const String &path2); - // Returns path to the actual directory, referenced by given path; - // if path is a directory, returns path unchanged, if path is a file, returns - // parent directory containing that file. - String GetDirectoryPath(const String &path); - // Tells if the path points to the parent path's location or lower directory; - // return FALSE if the path points to outside of the parent location. - bool IsSameOrSubDir(const String &parent, const String &path); +// Returns path to the actual directory, referenced by given path; +// if path is a directory, returns path unchanged, if path is a file, returns +// parent directory containing that file. +String GetDirectoryPath(const String &path); +// Tells if the path points to the parent path's location or lower directory; +// return FALSE if the path points to outside of the parent location. +bool IsSameOrSubDir(const String &parent, const String &path); - // Makes a path have only '/' slashes; this is to make it easier to work - // with path, knowing it contains only one type of directory separators - void FixupPath(String &path); - // Fixups path and removes trailing slash - String MakePathNoSlash(const String &path); - // Fixups path and adds trailing slash if it's missing - String MakeTrailingSlash(const String &path); - // Converts any path to an absolute path; relative paths are assumed to - // refer to the current working directory. - String MakeAbsolutePath(const String &path); - // Tries to create a relative path that would point to 'path' location - // if walking out of the 'base'. Returns empty string on failure. - String MakeRelativePath(const String &base, const String &path); - // Concatenates parent and relative paths - String ConcatPaths(const String &parent, const String &child); +// Makes a path have only '/' slashes; this is to make it easier to work +// with path, knowing it contains only one type of directory separators +void FixupPath(String &path); +// Fixups path and removes trailing slash +String MakePathNoSlash(const String &path); +// Fixups path and adds trailing slash if it's missing +String MakeTrailingSlash(const String &path); +// Converts any path to an absolute path; relative paths are assumed to +// refer to the current working directory. +String MakeAbsolutePath(const String &path); +// Tries to create a relative path that would point to 'path' location +// if walking out of the 'base'. Returns empty string on failure. +String MakeRelativePath(const String &base, const String &path); +// Concatenates parent and relative paths +String ConcatPaths(const String &parent, const String &child); - // Subsitutes illegal characters with '_'. This function uses a combined set - // of illegal chars from all the supported platforms to make a name that - // could be copied across systems without problems. - String FixupSharedFilename(const String &filename); +// Subsitutes illegal characters with '_'. This function uses a combined set +// of illegal chars from all the supported platforms to make a name that +// could be copied across systems without problems. +String FixupSharedFilename(const String &filename); - // Converts filepath into ASCII variant; returns empty string on failure - String GetPathInASCII(const String &path); - // Converts filepath from command line's argument into ASCII variant - String GetCmdLinePathInASCII(const char *arg, int arg_index); +// Converts filepath into ASCII variant; returns empty string on failure +String GetPathInASCII(const String &path); +// Converts filepath from command line's argument into ASCII variant +String GetCmdLinePathInASCII(const char *arg, int arg_index); } // namespace Path } // namespace Common diff --git a/engines/ags/shared/util/proxystream.cpp b/engines/ags/shared/util/proxystream.cpp index f22465a9b27b..cdd979569d04 100644 --- a/engines/ags/shared/util/proxystream.cpp +++ b/engines/ags/shared/util/proxystream.cpp @@ -22,168 +22,134 @@ #include "util/proxystream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { ProxyStream::ProxyStream(Stream *stream, ObjectOwnershipPolicy stream_ownership_policy) - : _stream(stream) - , _streamOwnershipPolicy(stream_ownership_policy) -{ + : _stream(stream) + , _streamOwnershipPolicy(stream_ownership_policy) { } -ProxyStream::~ProxyStream() -{ - ProxyStream::Close(); +ProxyStream::~ProxyStream() { + ProxyStream::Close(); } -void ProxyStream::Close() -{ - if (_stream && _streamOwnershipPolicy == kDisposeAfterUse) - { - delete _stream; - } - _stream = nullptr; +void ProxyStream::Close() { + if (_stream && _streamOwnershipPolicy == kDisposeAfterUse) { + delete _stream; + } + _stream = nullptr; } -bool ProxyStream::Flush() -{ - if (_stream) - { - return _stream->Flush(); - } - return false; +bool ProxyStream::Flush() { + if (_stream) { + return _stream->Flush(); + } + return false; } -bool ProxyStream::IsValid() const -{ - return _stream && _stream->IsValid(); +bool ProxyStream::IsValid() const { + return _stream && _stream->IsValid(); } -bool ProxyStream::EOS() const -{ - return _stream ? _stream->EOS() : true; +bool ProxyStream::EOS() const { + return _stream ? _stream->EOS() : true; } -soff_t ProxyStream::GetLength() const -{ - return _stream ? _stream->GetLength() : 0; +soff_t ProxyStream::GetLength() const { + return _stream ? _stream->GetLength() : 0; } -soff_t ProxyStream::GetPosition() const -{ - return _stream ? _stream->GetPosition() : -1; +soff_t ProxyStream::GetPosition() const { + return _stream ? _stream->GetPosition() : -1; } -bool ProxyStream::CanRead() const -{ - return _stream ? _stream->CanRead() : false; +bool ProxyStream::CanRead() const { + return _stream ? _stream->CanRead() : false; } -bool ProxyStream::CanWrite() const -{ - return _stream ? _stream->CanWrite() : false; +bool ProxyStream::CanWrite() const { + return _stream ? _stream->CanWrite() : false; } -bool ProxyStream::CanSeek() const -{ - return _stream ? _stream->CanSeek() : false; +bool ProxyStream::CanSeek() const { + return _stream ? _stream->CanSeek() : false; } -size_t ProxyStream::Read(void *buffer, size_t size) -{ - return _stream ? _stream->Read(buffer, size) : 0; +size_t ProxyStream::Read(void *buffer, size_t size) { + return _stream ? _stream->Read(buffer, size) : 0; } -int32_t ProxyStream::ReadByte() -{ - return _stream ? _stream->ReadByte() : 0; +int32_t ProxyStream::ReadByte() { + return _stream ? _stream->ReadByte() : 0; } -int16_t ProxyStream::ReadInt16() -{ - return _stream ? _stream->ReadInt16() : 0; +int16_t ProxyStream::ReadInt16() { + return _stream ? _stream->ReadInt16() : 0; } -int32_t ProxyStream::ReadInt32() -{ - return _stream ? _stream->ReadInt32() : 0; +int32_t ProxyStream::ReadInt32() { + return _stream ? _stream->ReadInt32() : 0; } -int64_t ProxyStream::ReadInt64() -{ - return _stream ? _stream->ReadInt64() : 0; +int64_t ProxyStream::ReadInt64() { + return _stream ? _stream->ReadInt64() : 0; } -size_t ProxyStream::ReadArray(void *buffer, size_t elem_size, size_t count) -{ - return _stream ? _stream->ReadArray(buffer, elem_size, count) : 0; +size_t ProxyStream::ReadArray(void *buffer, size_t elem_size, size_t count) { + return _stream ? _stream->ReadArray(buffer, elem_size, count) : 0; } -size_t ProxyStream::ReadArrayOfInt16(int16_t *buffer, size_t count) -{ - return _stream ? _stream->ReadArrayOfInt16(buffer, count) : 0; +size_t ProxyStream::ReadArrayOfInt16(int16_t *buffer, size_t count) { + return _stream ? _stream->ReadArrayOfInt16(buffer, count) : 0; } -size_t ProxyStream::ReadArrayOfInt32(int32_t *buffer, size_t count) -{ - return _stream ? _stream->ReadArrayOfInt32(buffer, count) : 0; +size_t ProxyStream::ReadArrayOfInt32(int32_t *buffer, size_t count) { + return _stream ? _stream->ReadArrayOfInt32(buffer, count) : 0; } -size_t ProxyStream::ReadArrayOfInt64(int64_t *buffer, size_t count) -{ - return _stream ? _stream->ReadArrayOfInt64(buffer, count) : 0; +size_t ProxyStream::ReadArrayOfInt64(int64_t *buffer, size_t count) { + return _stream ? _stream->ReadArrayOfInt64(buffer, count) : 0; } -size_t ProxyStream::Write(const void *buffer, size_t size) -{ - return _stream ? _stream->Write(buffer, size) : 0; +size_t ProxyStream::Write(const void *buffer, size_t size) { + return _stream ? _stream->Write(buffer, size) : 0; } -int32_t ProxyStream::WriteByte(uint8_t b) -{ - return _stream ? _stream->WriteByte(b) : 0; +int32_t ProxyStream::WriteByte(uint8_t b) { + return _stream ? _stream->WriteByte(b) : 0; } -size_t ProxyStream::WriteInt16(int16_t val) -{ - return _stream ? _stream->WriteInt16(val) : 0; +size_t ProxyStream::WriteInt16(int16_t val) { + return _stream ? _stream->WriteInt16(val) : 0; } -size_t ProxyStream::WriteInt32(int32_t val) -{ - return _stream ? _stream->WriteInt32(val) : 0; +size_t ProxyStream::WriteInt32(int32_t val) { + return _stream ? _stream->WriteInt32(val) : 0; } -size_t ProxyStream::WriteInt64(int64_t val) -{ - return _stream ? _stream->WriteInt64(val) : 0; +size_t ProxyStream::WriteInt64(int64_t val) { + return _stream ? _stream->WriteInt64(val) : 0; } -size_t ProxyStream::WriteArray(const void *buffer, size_t elem_size, size_t count) -{ - return _stream ? _stream->WriteArray(buffer, elem_size, count) : 0; +size_t ProxyStream::WriteArray(const void *buffer, size_t elem_size, size_t count) { + return _stream ? _stream->WriteArray(buffer, elem_size, count) : 0; } -size_t ProxyStream::WriteArrayOfInt16(const int16_t *buffer, size_t count) -{ - return _stream ? _stream->WriteArrayOfInt16(buffer, count) : 0; +size_t ProxyStream::WriteArrayOfInt16(const int16_t *buffer, size_t count) { + return _stream ? _stream->WriteArrayOfInt16(buffer, count) : 0; } -size_t ProxyStream::WriteArrayOfInt32(const int32_t *buffer, size_t count) -{ - return _stream ? _stream->WriteArrayOfInt32(buffer, count) : 0; +size_t ProxyStream::WriteArrayOfInt32(const int32_t *buffer, size_t count) { + return _stream ? _stream->WriteArrayOfInt32(buffer, count) : 0; } -size_t ProxyStream::WriteArrayOfInt64(const int64_t *buffer, size_t count) -{ - return _stream ? _stream->WriteArrayOfInt64(buffer, count) : 0; +size_t ProxyStream::WriteArrayOfInt64(const int64_t *buffer, size_t count) { + return _stream ? _stream->WriteArrayOfInt64(buffer, count) : 0; } -bool ProxyStream::Seek(soff_t offset, StreamSeek origin) -{ - return _stream ? _stream->Seek(offset, origin) : false; +bool ProxyStream::Seek(soff_t offset, StreamSeek origin) { + return _stream ? _stream->Seek(offset, origin) : false; } } // namespace Common diff --git a/engines/ags/shared/util/proxystream.h b/engines/ags/shared/util/proxystream.h index cc45cde33a0e..70e47617458f 100644 --- a/engines/ags/shared/util/proxystream.h +++ b/engines/ags/shared/util/proxystream.h @@ -25,65 +25,61 @@ #include "util/stream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { // TODO: replace with std::shared_ptr!!! -enum ObjectOwnershipPolicy -{ - kReleaseAfterUse, - kDisposeAfterUse +enum ObjectOwnershipPolicy { + kReleaseAfterUse, + kDisposeAfterUse }; -class ProxyStream : public Stream -{ +class ProxyStream : public Stream { public: - ProxyStream(Stream *stream, ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse); - ~ProxyStream() override; + ProxyStream(Stream *stream, ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse); + ~ProxyStream() override; - void Close() override; - bool Flush() override; + void Close() override; + bool Flush() override; - // Is stream valid (underlying data initialized properly) - bool IsValid() const override; - // Is end of stream - bool EOS() const override; - // Total length of stream (if known) - soff_t GetLength() const override; - // Current position (if known) - soff_t GetPosition() const override; + // Is stream valid (underlying data initialized properly) + bool IsValid() const override; + // Is end of stream + bool EOS() const override; + // Total length of stream (if known) + soff_t GetLength() const override; + // Current position (if known) + soff_t GetPosition() const override; - bool CanRead() const override; - bool CanWrite() const override; - bool CanSeek() const override; + bool CanRead() const override; + bool CanWrite() const override; + bool CanSeek() const override; - size_t Read(void *buffer, size_t size) override; - int32_t ReadByte() override; - int16_t ReadInt16() override; - int32_t ReadInt32() override; - int64_t ReadInt64() override; - size_t ReadArray(void *buffer, size_t elem_size, size_t count) override; - size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override; - size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override; - size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override; + size_t Read(void *buffer, size_t size) override; + int32_t ReadByte() override; + int16_t ReadInt16() override; + int32_t ReadInt32() override; + int64_t ReadInt64() override; + size_t ReadArray(void *buffer, size_t elem_size, size_t count) override; + size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override; + size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override; + size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override; - size_t Write(const void *buffer, size_t size) override; - int32_t WriteByte(uint8_t b) override; - size_t WriteInt16(int16_t val) override; - size_t WriteInt32(int32_t val) override; - size_t WriteInt64(int64_t val) override; - size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override; - size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override; - size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override; - size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override; + size_t Write(const void *buffer, size_t size) override; + int32_t WriteByte(uint8_t b) override; + size_t WriteInt16(int16_t val) override; + size_t WriteInt32(int32_t val) override; + size_t WriteInt64(int64_t val) override; + size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override; + size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override; + size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override; + size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override; - bool Seek(soff_t offset, StreamSeek origin) override; + bool Seek(soff_t offset, StreamSeek origin) override; protected: - Stream *_stream; - ObjectOwnershipPolicy _streamOwnershipPolicy; + Stream *_stream; + ObjectOwnershipPolicy _streamOwnershipPolicy; }; } // namespace Common diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h index e57dbbba66aa..203d600c3c27 100644 --- a/engines/ags/shared/util/stdio_compat.h +++ b/engines/ags/shared/util/stdio_compat.h @@ -32,8 +32,8 @@ typedef int64_t file_off_t; extern "C" { #endif -int ags_fseek(FILE * stream, file_off_t offset, int whence); -file_off_t ags_ftell(FILE * stream); +int ags_fseek(FILE *stream, file_off_t offset, int whence); +file_off_t ags_ftell(FILE *stream); int ags_file_exists(const char *path); int ags_directory_exists(const char *path); diff --git a/engines/ags/shared/util/stream.cpp b/engines/ags/shared/util/stream.cpp index 48c6388ad796..737496ec4378 100644 --- a/engines/ags/shared/util/stream.cpp +++ b/engines/ags/shared/util/stream.cpp @@ -22,22 +22,18 @@ #include "util/stream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -size_t Stream::WriteByteCount(uint8_t b, size_t count) -{ - if (!CanWrite()) - return 0; - size_t size = 0; - for (; count > 0; --count, ++size) - { - if (WriteByte(b) < 0) - break; - } - return size; +size_t Stream::WriteByteCount(uint8_t b, size_t count) { + if (!CanWrite()) + return 0; + size_t size = 0; + for (; count > 0; --count, ++size) { + if (WriteByte(b) < 0) + break; + } + return size; } } // namespace Common diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index e70f9bbfa897..d97cd26621df 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -25,7 +25,7 @@ // Base stream class. // // Provides default implementation for a few helper methods. -// +// // Only streams with uncommon behavior should be derived directly from Stream. // Most I/O devices should inherit DataStream instead. // Streams that wrap other streams should inherit ProxyStream. @@ -37,56 +37,49 @@ #include "api/stream_api.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class Stream : public IAGSStream -{ +class Stream : public IAGSStream { public: - // Tells if the stream has errors - virtual bool HasErrors() const { return false; } - // Flush stream buffer to the underlying device - virtual bool Flush() = 0; + // Tells if the stream has errors + virtual bool HasErrors() const { + return false; + } + // Flush stream buffer to the underlying device + virtual bool Flush() = 0; - //----------------------------------------------------- - // Helper methods - //----------------------------------------------------- - inline int8_t ReadInt8() override - { - return ReadByte(); - } + //----------------------------------------------------- + // Helper methods + //----------------------------------------------------- + inline int8_t ReadInt8() override { + return ReadByte(); + } - inline size_t WriteInt8(int8_t val) override - { - int32_t ival = WriteByte(val); - return ival >= 0 ? ival : 0; - } + inline size_t WriteInt8(int8_t val) override { + int32_t ival = WriteByte(val); + return ival >= 0 ? ival : 0; + } - inline bool ReadBool() override - { - return ReadInt8() != 0; - } + inline bool ReadBool() override { + return ReadInt8() != 0; + } - inline size_t WriteBool(bool val) override - { - return WriteInt8(val ? 1 : 0); - } + inline size_t WriteBool(bool val) override { + return WriteInt8(val ? 1 : 0); + } - // Practically identical to Read() and Write(), these two helpers' only - // meaning is to underline the purpose of data being (de)serialized - inline size_t ReadArrayOfInt8(int8_t *buffer, size_t count) override - { - return Read(buffer, count); - } - inline size_t WriteArrayOfInt8(const int8_t *buffer, size_t count) override - { - return Write(buffer, count); - } + // Practically identical to Read() and Write(), these two helpers' only + // meaning is to underline the purpose of data being (de)serialized + inline size_t ReadArrayOfInt8(int8_t *buffer, size_t count) override { + return Read(buffer, count); + } + inline size_t WriteArrayOfInt8(const int8_t *buffer, size_t count) override { + return Write(buffer, count); + } - // Fill the requested number of bytes with particular value - size_t WriteByteCount(uint8_t b, size_t count); + // Fill the requested number of bytes with particular value + size_t WriteByteCount(uint8_t b, size_t count); }; } // namespace Common diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp index 37db3ead1264..c6f9eb85d028 100644 --- a/engines/ags/shared/util/string.cpp +++ b/engines/ags/shared/util/string.cpp @@ -28,1002 +28,822 @@ #include "util/string.h" #include "util/string_compat.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { String::String() - : _cstr(nullptr) - , _len(0) - , _buf(nullptr) -{ + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) { } String::String(const String &str) - : _cstr(nullptr) - , _len(0) - , _buf(nullptr) -{ - *this = str; + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) { + *this = str; } String::String(const char *cstr) - : _cstr(nullptr) - , _len(0) - , _buf(nullptr) -{ - *this = cstr; + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) { + *this = cstr; } String::String(const char *cstr, size_t length) - : _cstr(nullptr) - , _len(0) - , _buf(nullptr) -{ - SetString(cstr, length); + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) { + SetString(cstr, length); } String::String(char c, size_t count) - : _cstr(nullptr) - , _len(0) - , _buf(nullptr) -{ - FillString(c, count); -} - -String::~String() -{ - Free(); -} - -void String::Read(Stream *in, size_t max_chars, bool stop_at_limit) -{ - Empty(); - if (!in) - { - return; - } - if (max_chars == 0 && stop_at_limit) - { - return; - } - - char buffer[1024]; - char *read_ptr = buffer; - size_t read_size = 0; - int ichar; - do - { - ichar = in->ReadByte(); - read_size++; - if (read_size > max_chars) - { - continue; - } - *read_ptr = (char)(ichar >= 0 ? ichar : 0); - if (!*read_ptr || ((read_ptr - buffer) == (sizeof(buffer) - 1 - 1))) - { - buffer[sizeof(buffer) - 1] = 0; - Append(buffer); - read_ptr = buffer; - } - else - { - read_ptr++; - } - } - while(ichar > 0 && !(stop_at_limit && read_size == max_chars)); -} - -void String::ReadCount(Stream *in, size_t count) -{ - Empty(); - if (in && count > 0) - { - ReserveAndShift(false, count); - count = in->Read(_cstr, count); - _cstr[count] = 0; - _len = strlen(_cstr); - } -} - -void String::Write(Stream *out) const -{ - if (out) - { - out->Write(GetCStr(), GetLength() + 1); - } -} - -void String::WriteCount(Stream *out, size_t count) const -{ - if (out) - { - size_t str_out_len = Math::Min(count - 1, GetLength()); - if (str_out_len > 0) - out->Write(GetCStr(), str_out_len); - size_t null_out_len = count - str_out_len; - if (null_out_len > 0) - out->WriteByteCount(0, null_out_len); - } -} - -/* static */ void String::WriteString(const char *cstr, Stream *out) -{ - if (out) - { - cstr = cstr ? cstr : ""; - out->Write(cstr, strlen(cstr) + 1); - } -} - -int String::Compare(const char *cstr) const -{ - return strcmp(GetCStr(), cstr ? cstr : ""); -} - -int String::CompareNoCase(const char *cstr) const -{ - return ags_stricmp(GetCStr(), cstr ? cstr : ""); -} - -int String::CompareLeft(const char *cstr, size_t count) const -{ - cstr = cstr ? cstr : ""; - return strncmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); -} - -int String::CompareLeftNoCase(const char *cstr, size_t count) const -{ - cstr = cstr ? cstr : ""; - return ags_strnicmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); -} - -int String::CompareMid(const char *cstr, size_t from, size_t count) const -{ - cstr = cstr ? cstr : ""; - from = Math::Min(from, GetLength()); - return strncmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); -} - -int String::CompareMidNoCase(const char *cstr, size_t from, size_t count) const -{ - cstr = cstr ? cstr : ""; - from = Math::Min(from, GetLength()); - return ags_strnicmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); -} - -int String::CompareRight(const char *cstr, size_t count) const -{ - cstr = cstr ? cstr : ""; - count = count != -1 ? count : strlen(cstr); - size_t off = Math::Min(GetLength(), count); - return strncmp(GetCStr() + GetLength() - off, cstr, count); -} - -int String::CompareRightNoCase(const char *cstr, size_t count) const -{ - cstr = cstr ? cstr : ""; - count = count != -1 ? count : strlen(cstr); - size_t off = Math::Min(GetLength(), count); - return ags_strnicmp(GetCStr() + GetLength() - off, cstr, count); -} - -size_t String::FindChar(char c, size_t from) const -{ - if (c && from < _len) - { - const char * found_cstr = strchr(_cstr + from, c); - return found_cstr ? found_cstr - _cstr : -1; - } - return -1; -} - -size_t String::FindCharReverse(char c, size_t from) const -{ - if (!_cstr || !c) - { - return -1; - } + : _cstr(nullptr) + , _len(0) + , _buf(nullptr) { + FillString(c, count); +} + +String::~String() { + Free(); +} + +void String::Read(Stream *in, size_t max_chars, bool stop_at_limit) { + Empty(); + if (!in) { + return; + } + if (max_chars == 0 && stop_at_limit) { + return; + } + + char buffer[1024]; + char *read_ptr = buffer; + size_t read_size = 0; + int ichar; + do { + ichar = in->ReadByte(); + read_size++; + if (read_size > max_chars) { + continue; + } + *read_ptr = (char)(ichar >= 0 ? ichar : 0); + if (!*read_ptr || ((read_ptr - buffer) == (sizeof(buffer) - 1 - 1))) { + buffer[sizeof(buffer) - 1] = 0; + Append(buffer); + read_ptr = buffer; + } else { + read_ptr++; + } + } while (ichar > 0 && !(stop_at_limit && read_size == max_chars)); +} + +void String::ReadCount(Stream *in, size_t count) { + Empty(); + if (in && count > 0) { + ReserveAndShift(false, count); + count = in->Read(_cstr, count); + _cstr[count] = 0; + _len = strlen(_cstr); + } +} + +void String::Write(Stream *out) const { + if (out) { + out->Write(GetCStr(), GetLength() + 1); + } +} + +void String::WriteCount(Stream *out, size_t count) const { + if (out) { + size_t str_out_len = Math::Min(count - 1, GetLength()); + if (str_out_len > 0) + out->Write(GetCStr(), str_out_len); + size_t null_out_len = count - str_out_len; + if (null_out_len > 0) + out->WriteByteCount(0, null_out_len); + } +} + +/* static */ void String::WriteString(const char *cstr, Stream *out) { + if (out) { + cstr = cstr ? cstr : ""; + out->Write(cstr, strlen(cstr) + 1); + } +} + +int String::Compare(const char *cstr) const { + return strcmp(GetCStr(), cstr ? cstr : ""); +} + +int String::CompareNoCase(const char *cstr) const { + return ags_stricmp(GetCStr(), cstr ? cstr : ""); +} - from = Math::Min(from, _len - 1); - const char *seek_ptr = _cstr + from; - while (seek_ptr >= _cstr) - { - if (*seek_ptr == c) - { - return seek_ptr - _cstr; - } - seek_ptr--; - } - return -1; -} +int String::CompareLeft(const char *cstr, size_t count) const { + cstr = cstr ? cstr : ""; + return strncmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); +} + +int String::CompareLeftNoCase(const char *cstr, size_t count) const { + cstr = cstr ? cstr : ""; + return ags_strnicmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); +} + +int String::CompareMid(const char *cstr, size_t from, size_t count) const { + cstr = cstr ? cstr : ""; + from = Math::Min(from, GetLength()); + return strncmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); +} -size_t String::FindString(const char *cstr, size_t from) const -{ - if (cstr && from < _len) - { - const char * found_cstr = strstr(_cstr + from, cstr); - return found_cstr ? found_cstr - _cstr : -1; - } - return -1; +int String::CompareMidNoCase(const char *cstr, size_t from, size_t count) const { + cstr = cstr ? cstr : ""; + from = Math::Min(from, GetLength()); + return ags_strnicmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); +} + +int String::CompareRight(const char *cstr, size_t count) const { + cstr = cstr ? cstr : ""; + count = count != -1 ? count : strlen(cstr); + size_t off = Math::Min(GetLength(), count); + return strncmp(GetCStr() + GetLength() - off, cstr, count); +} + +int String::CompareRightNoCase(const char *cstr, size_t count) const { + cstr = cstr ? cstr : ""; + count = count != -1 ? count : strlen(cstr); + size_t off = Math::Min(GetLength(), count); + return ags_strnicmp(GetCStr() + GetLength() - off, cstr, count); +} + +size_t String::FindChar(char c, size_t from) const { + if (c && from < _len) { + const char *found_cstr = strchr(_cstr + from, c); + return found_cstr ? found_cstr - _cstr : -1; + } + return -1; +} + +size_t String::FindCharReverse(char c, size_t from) const { + if (!_cstr || !c) { + return -1; + } + + from = Math::Min(from, _len - 1); + const char *seek_ptr = _cstr + from; + while (seek_ptr >= _cstr) { + if (*seek_ptr == c) { + return seek_ptr - _cstr; + } + seek_ptr--; + } + return -1; +} + +size_t String::FindString(const char *cstr, size_t from) const { + if (cstr && from < _len) { + const char *found_cstr = strstr(_cstr + from, cstr); + return found_cstr ? found_cstr - _cstr : -1; + } + return -1; } bool String::FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, - size_t &from, size_t &to) const -{ - if (!_cstr || !separator) - { - return false; - } - if (first > last) - { - return false; - } - - size_t this_field = 0; - size_t slice_from = 0; - size_t slice_to = _len; - size_t slice_at = -1; - do - { - slice_at = FindChar(separator, slice_at + 1); - if (slice_at == -1) - slice_at = _len; - // found where previous field ends - if (this_field == last) - { - // if previous field is the last one to be included, - // then set the section tail - slice_to = exclude_last_sep ? slice_at : slice_at + 1; - } - if (slice_at != _len) - { - this_field++; - if (this_field == first) - { - // if the new field is the first one to be included, - // then set the section head - slice_from = exclude_first_sep ? slice_at + 1 : slice_at; - } - } - } - while (slice_at < _len && this_field <= last); - - // the search is a success if at least the first field was found - if (this_field >= first) - { - // correct the indices to stay in the [0; length] range - assert(slice_from <= slice_to); - from = Math::Clamp(slice_from, (size_t)0, _len); - to = Math::Clamp(slice_to, (size_t)0, _len); - return true; - } - return false; -} - -int String::ToInt() const -{ - return atoi(GetCStr()); -} - -String String::Wrapper(const char *cstr) -{ - String str; - str.Wrap(cstr); - return str; -} - -/* static */ String String::FromFormat(const char *fcstr, ...) -{ - fcstr = fcstr ? fcstr : ""; - String str; - va_list argptr; - va_start(argptr, fcstr); - str.FormatV(fcstr, argptr); - va_end(argptr); - return str; -} - -/* static */ String String::FromFormatV(const char *fcstr, va_list argptr) -{ - String str; - str.FormatV(fcstr, argptr); - return str; -} - -/* static */ String String::FromStream(Stream *in, size_t max_chars, bool stop_at_limit) -{ - String str; - str.Read(in, max_chars, stop_at_limit); - return str; -} - -/* static */ String String::FromStreamCount(Stream *in, size_t count) -{ - String str; - str.ReadCount(in, count); - return str; -} - -String String::Lower() const -{ - String str = *this; - str.MakeLower(); - return str; -} - -String String::Upper() const -{ - String str = *this; - str.MakeUpper(); - return str; -} - -String String::Left(size_t count) const -{ - count = Math::Min(count, GetLength()); - return count == GetLength() ? *this : String(GetCStr(), count); -} - -String String::Mid(size_t from, size_t count) const -{ - Math::ClampLength(from, count, (size_t)0, GetLength()); - return count == GetLength() ? *this : String(GetCStr() + from, count); -} - -String String::Right(size_t count) const -{ - count = Math::Min(count, GetLength()); - return count == GetLength() ? *this : String(GetCStr() + GetLength() - count, count); -} - -String String::LeftSection(char separator, bool exclude_separator) const -{ - if (_cstr && separator) - { - size_t slice_at = FindChar(separator); - if (slice_at != -1) - { - slice_at = exclude_separator ? slice_at : slice_at + 1; - return Left(slice_at); - } - } - return *this; -} + size_t &from, size_t &to) const { + if (!_cstr || !separator) { + return false; + } + if (first > last) { + return false; + } + + size_t this_field = 0; + size_t slice_from = 0; + size_t slice_to = _len; + size_t slice_at = -1; + do { + slice_at = FindChar(separator, slice_at + 1); + if (slice_at == -1) + slice_at = _len; + // found where previous field ends + if (this_field == last) { + // if previous field is the last one to be included, + // then set the section tail + slice_to = exclude_last_sep ? slice_at : slice_at + 1; + } + if (slice_at != _len) { + this_field++; + if (this_field == first) { + // if the new field is the first one to be included, + // then set the section head + slice_from = exclude_first_sep ? slice_at + 1 : slice_at; + } + } + } while (slice_at < _len && this_field <= last); + + // the search is a success if at least the first field was found + if (this_field >= first) { + // correct the indices to stay in the [0; length] range + assert(slice_from <= slice_to); + from = Math::Clamp(slice_from, (size_t)0, _len); + to = Math::Clamp(slice_to, (size_t)0, _len); + return true; + } + return false; +} + +int String::ToInt() const { + return atoi(GetCStr()); +} + +String String::Wrapper(const char *cstr) { + String str; + str.Wrap(cstr); + return str; +} + +/* static */ String String::FromFormat(const char *fcstr, ...) { + fcstr = fcstr ? fcstr : ""; + String str; + va_list argptr; + va_start(argptr, fcstr); + str.FormatV(fcstr, argptr); + va_end(argptr); + return str; +} + +/* static */ String String::FromFormatV(const char *fcstr, va_list argptr) { + String str; + str.FormatV(fcstr, argptr); + return str; +} + +/* static */ String String::FromStream(Stream *in, size_t max_chars, bool stop_at_limit) { + String str; + str.Read(in, max_chars, stop_at_limit); + return str; +} + +/* static */ String String::FromStreamCount(Stream *in, size_t count) { + String str; + str.ReadCount(in, count); + return str; +} + +String String::Lower() const { + String str = *this; + str.MakeLower(); + return str; +} + +String String::Upper() const { + String str = *this; + str.MakeUpper(); + return str; +} + +String String::Left(size_t count) const { + count = Math::Min(count, GetLength()); + return count == GetLength() ? *this : String(GetCStr(), count); +} + +String String::Mid(size_t from, size_t count) const { + Math::ClampLength(from, count, (size_t)0, GetLength()); + return count == GetLength() ? *this : String(GetCStr() + from, count); +} + +String String::Right(size_t count) const { + count = Math::Min(count, GetLength()); + return count == GetLength() ? *this : String(GetCStr() + GetLength() - count, count); +} + +String String::LeftSection(char separator, bool exclude_separator) const { + if (_cstr && separator) { + size_t slice_at = FindChar(separator); + if (slice_at != -1) { + slice_at = exclude_separator ? slice_at : slice_at + 1; + return Left(slice_at); + } + } + return *this; +} -String String::RightSection(char separator, bool exclude_separator) const -{ - if (_cstr && separator) - { - size_t slice_at = FindCharReverse(separator); - if (slice_at != -1) - { - size_t count = exclude_separator ? _len - slice_at - 1 : _len - slice_at; - return Right(count); - } - } - return *this; +String String::RightSection(char separator, bool exclude_separator) const { + if (_cstr && separator) { + size_t slice_at = FindCharReverse(separator); + if (slice_at != -1) { + size_t count = exclude_separator ? _len - slice_at - 1 : _len - slice_at; + return Right(count); + } + } + return *this; } String String::Section(char separator, size_t first, size_t last, - bool exclude_first_sep, bool exclude_last_sep) const -{ - if (!_cstr || !separator) - { - return String(); - } - - size_t slice_from; - size_t slice_to; - if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, - slice_from, slice_to)) - { - return Mid(slice_from, slice_to - slice_from); - } - return String(); -} - -std::vector String::Split(char separator) const -{ - std::vector result; - if (!_cstr || !separator) - return result; - const char *ptr = _cstr; - while (*ptr) - { - const char *found_cstr = strchr(ptr, separator); - if (!found_cstr) break; - result.push_back(String(ptr, found_cstr - ptr)); - ptr = found_cstr + 1; - } - result.push_back(String(ptr)); - return result; -} - -void String::Reserve(size_t max_length) -{ - if (_bufHead) - { - if (max_length > _bufHead->Capacity) - { - // grow by 50% - size_t grow_length = _bufHead->Capacity + (_bufHead->Capacity / 2); - Copy(Math::Max(max_length, grow_length)); - } - } - else - { - Create(max_length); - } -} - -void String::ReserveMore(size_t more_length) -{ - Reserve(GetLength() + more_length); -} - -void String::Compact() -{ - if (_bufHead && _bufHead->Capacity > _len) - { - Copy(_len); - } -} - -void String::Append(const char *cstr) -{ - if (cstr) - { - size_t length = strlen(cstr); - if (length > 0) - { - ReserveAndShift(false, length); - memcpy(_cstr + _len, cstr, length); - _len += length; - _cstr[_len] = 0; - } - } -} - -void String::AppendChar(char c) -{ - if (c) - { - ReserveAndShift(false, 1); - _cstr[_len++] = c; - _cstr[_len] = 0; - } -} - -void String::ClipLeft(size_t count) -{ - if (_len > 0 && count > 0) - { - count = Math::Min(count, _len); - BecomeUnique(); - _len -= count; - _cstr += count; - } -} - -void String::ClipMid(size_t from, size_t count) -{ - if (from < _len) - { - count = Math::Min(count, _len - from); - if (count > 0) - { - BecomeUnique(); - if (!from) - { - _len -= count; - _cstr += count; - } - else if (from + count == _len) - { - _len -= count; - _cstr[_len] = 0; - } - else - { - char *cstr_mid = _cstr + from; - memmove(cstr_mid, _cstr + from + count, _len - from - count + 1); - _len -= count; - } - } - } -} - -void String::ClipRight(size_t count) -{ - if (count > 0) - { - count = Math::Min(count, GetLength()); - BecomeUnique(); - _len -= count; - _cstr[_len] = 0; - } -} - -void String::ClipLeftSection(char separator, bool include_separator) -{ - if (_cstr && separator) - { - size_t slice_at = FindChar(separator); - if (slice_at != -1) - { - ClipLeft(include_separator ? slice_at + 1 : slice_at); - } - else - Empty(); - } -} - -void String::ClipRightSection(char separator, bool include_separator) -{ - if (_cstr && separator) - { - size_t slice_at = FindCharReverse(separator); - if (slice_at != -1) - { - ClipRight(include_separator ? _len - slice_at : _len - slice_at - 1); - } - else - Empty(); - } + bool exclude_first_sep, bool exclude_last_sep) const { + if (!_cstr || !separator) { + return String(); + } + + size_t slice_from; + size_t slice_to; + if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, + slice_from, slice_to)) { + return Mid(slice_from, slice_to - slice_from); + } + return String(); +} + +std::vector String::Split(char separator) const { + std::vector result; + if (!_cstr || !separator) + return result; + const char *ptr = _cstr; + while (*ptr) { + const char *found_cstr = strchr(ptr, separator); + if (!found_cstr) break; + result.push_back(String(ptr, found_cstr - ptr)); + ptr = found_cstr + 1; + } + result.push_back(String(ptr)); + return result; +} + +void String::Reserve(size_t max_length) { + if (_bufHead) { + if (max_length > _bufHead->Capacity) { + // grow by 50% + size_t grow_length = _bufHead->Capacity + (_bufHead->Capacity / 2); + Copy(Math::Max(max_length, grow_length)); + } + } else { + Create(max_length); + } +} + +void String::ReserveMore(size_t more_length) { + Reserve(GetLength() + more_length); +} + +void String::Compact() { + if (_bufHead && _bufHead->Capacity > _len) { + Copy(_len); + } +} + +void String::Append(const char *cstr) { + if (cstr) { + size_t length = strlen(cstr); + if (length > 0) { + ReserveAndShift(false, length); + memcpy(_cstr + _len, cstr, length); + _len += length; + _cstr[_len] = 0; + } + } +} + +void String::AppendChar(char c) { + if (c) { + ReserveAndShift(false, 1); + _cstr[_len++] = c; + _cstr[_len] = 0; + } +} + +void String::ClipLeft(size_t count) { + if (_len > 0 && count > 0) { + count = Math::Min(count, _len); + BecomeUnique(); + _len -= count; + _cstr += count; + } +} + +void String::ClipMid(size_t from, size_t count) { + if (from < _len) { + count = Math::Min(count, _len - from); + if (count > 0) { + BecomeUnique(); + if (!from) { + _len -= count; + _cstr += count; + } else if (from + count == _len) { + _len -= count; + _cstr[_len] = 0; + } else { + char *cstr_mid = _cstr + from; + memmove(cstr_mid, _cstr + from + count, _len - from - count + 1); + _len -= count; + } + } + } +} + +void String::ClipRight(size_t count) { + if (count > 0) { + count = Math::Min(count, GetLength()); + BecomeUnique(); + _len -= count; + _cstr[_len] = 0; + } +} + +void String::ClipLeftSection(char separator, bool include_separator) { + if (_cstr && separator) { + size_t slice_at = FindChar(separator); + if (slice_at != -1) { + ClipLeft(include_separator ? slice_at + 1 : slice_at); + } else + Empty(); + } +} + +void String::ClipRightSection(char separator, bool include_separator) { + if (_cstr && separator) { + size_t slice_at = FindCharReverse(separator); + if (slice_at != -1) { + ClipRight(include_separator ? _len - slice_at : _len - slice_at - 1); + } else + Empty(); + } } void String::ClipSection(char separator, size_t first, size_t last, - bool include_first_sep, bool include_last_sep) -{ - if (!_cstr || !separator) - { - return; - } - - size_t slice_from; - size_t slice_to; - if (FindSection(separator, first, last, !include_first_sep, !include_last_sep, - slice_from, slice_to)) - { - ClipMid(slice_from, slice_to - slice_from); - } -} - -void String::Empty() -{ - if (_cstr) - { - BecomeUnique(); - _len = 0; - _cstr[0] = 0; - } -} - -void String::FillString(char c, size_t count) -{ - Empty(); - if (count > 0) - { - ReserveAndShift(false, count); - memset(_cstr, c, count); - _len = count; - _cstr[count] = 0; - } -} - -void String::Format(const char *fcstr, ...) -{ - va_list argptr; - va_start(argptr, fcstr); - FormatV(fcstr, argptr); - va_end(argptr); -} - -void String::FormatV(const char *fcstr, va_list argptr) -{ - fcstr = fcstr ? fcstr : ""; - va_list argptr_cpy; - va_copy(argptr_cpy, argptr); - size_t length = vsnprintf(nullptr, 0u, fcstr, argptr); - ReserveAndShift(false, Math::Surplus(length, GetLength())); - vsprintf(_cstr, fcstr, argptr_cpy); - va_end(argptr_cpy); - _len = length; - _cstr[_len] = 0; -} - -void String::Free() -{ - if (_bufHead) - { - assert(_bufHead->RefCount > 0); - _bufHead->RefCount--; - if (!_bufHead->RefCount) - { - delete [] _buf; - } - } - _buf = nullptr; - _cstr = nullptr; - _len = 0; -} - -void String::MakeLower() -{ - if (_cstr) - { - BecomeUnique(); - ags_strlwr(_cstr); - } -} - -void String::MakeUpper() -{ - if (_cstr) - { - BecomeUnique(); - ags_strupr(_cstr); - } -} - -void String::Prepend(const char *cstr) -{ - if (cstr) - { - size_t length = strlen(cstr); - if (length > 0) - { - ReserveAndShift(true, length); - memcpy(_cstr - length, cstr, length); - _len += length; - _cstr -= length; - } - } -} - -void String::PrependChar(char c) -{ - if (c) - { - ReserveAndShift(true, 1); - _len++; - _cstr--; - _cstr[0] = c; - } -} - -void String::Replace(char what, char with) -{ - if (_cstr && what && with && what != with) - { - BecomeUnique(); - char *rep_ptr = _cstr; - while (*rep_ptr) - { - if (*rep_ptr == what) - { - *rep_ptr = with; - } - rep_ptr++; - } - } -} - -void String::ReplaceMid(size_t from, size_t count, const char *cstr) -{ - if (!cstr) - cstr = ""; - size_t length = strlen(cstr); - Math::ClampLength(from, count, (size_t)0, GetLength()); - ReserveAndShift(false, Math::Surplus(length, count)); - memmove(_cstr + from + length, _cstr + from + count, GetLength() - (from + count) + 1); - memcpy(_cstr + from, cstr, length); - _len += length - count; -} - -void String::Reverse() -{ - if (!_cstr || GetLength() <= 1) - return; - for (char *fw = _cstr, *bw = _cstr + _len - 1; - *fw; ++fw, --bw) - { - std::swap(*fw, *bw); - } -} - -void String::SetAt(size_t index, char c) -{ - if (_cstr && index < GetLength() && c) - { - BecomeUnique(); - _cstr[index] = c; - } -} - -void String::SetString(const char *cstr, size_t length) -{ - if (cstr) - { - length = Math::Min(length, strlen(cstr)); - if (length > 0) - { - ReserveAndShift(false, Math::Surplus(length, GetLength())); - memcpy(_cstr, cstr, length); - _len = length; - _cstr[length] = 0; - } - else - { - Empty(); - } - } - else - { - Empty(); - } -} - -void String::Trim(char c) -{ - TrimLeft(c); - TrimRight(c); -} - -void String::TrimLeft(char c) -{ - if (!_cstr || !_len) - { - return; - } - - const char *trim_ptr = _cstr; - for (;;) - { - auto t = *trim_ptr; - if (t == 0) { break; } - if (c && t != c) { break; } - if (!c && !isspace(t)) { break; } - trim_ptr++; - } - size_t trimmed = trim_ptr - _cstr; - if (trimmed > 0) - { - BecomeUnique(); - _len -= trimmed; - _cstr += trimmed; - } -} - -void String::TrimRight(char c) -{ - if (!_cstr || !_len) - { - return; - } - - const char *trim_ptr = _cstr + _len - 1; - for (;;) - { - if (trim_ptr < _cstr) { break; } - auto t = *trim_ptr; - if (c && t != c) { break; } - if (!c && !isspace(t)) { break; } - trim_ptr--; - } - size_t trimmed = (_cstr + _len - 1) - trim_ptr; - if (trimmed > 0) - { - BecomeUnique(); - _len -= trimmed; - _cstr[_len] = 0; - } -} - -void String::TruncateToLeft(size_t count) -{ - if (_cstr) - { - count = Math::Min(count, _len); - if (count < _len) - { - BecomeUnique(); - _len = count; - _cstr[_len] = 0; - } - } -} - -void String::TruncateToMid(size_t from, size_t count) -{ - if (_cstr) - { - Math::ClampLength(from, count, (size_t)0, _len); - if (from > 0 || count < _len) - { - BecomeUnique(); - _len = count; - _cstr += from; - _cstr[_len] = 0; - } - } -} - -void String::TruncateToRight(size_t count) -{ - if (_cstr) - { - count = Math::Min(count, GetLength()); - if (count < _len) - { - BecomeUnique(); - _cstr += _len - count; - _len = count; - } - } -} - -void String::TruncateToLeftSection(char separator, bool exclude_separator) -{ - if (_cstr && separator) - { - size_t slice_at = FindChar(separator); - if (slice_at != -1) - { - TruncateToLeft(exclude_separator ? slice_at : slice_at + 1); - } - } -} - -void String::TruncateToRightSection(char separator, bool exclude_separator) -{ - if (_cstr && separator) - { - size_t slice_at = FindCharReverse(separator); - if (slice_at != -1) - { - TruncateToRight(exclude_separator ? _len - slice_at - 1 : _len - slice_at); - } - } + bool include_first_sep, bool include_last_sep) { + if (!_cstr || !separator) { + return; + } + + size_t slice_from; + size_t slice_to; + if (FindSection(separator, first, last, !include_first_sep, !include_last_sep, + slice_from, slice_to)) { + ClipMid(slice_from, slice_to - slice_from); + } +} + +void String::Empty() { + if (_cstr) { + BecomeUnique(); + _len = 0; + _cstr[0] = 0; + } +} + +void String::FillString(char c, size_t count) { + Empty(); + if (count > 0) { + ReserveAndShift(false, count); + memset(_cstr, c, count); + _len = count; + _cstr[count] = 0; + } +} + +void String::Format(const char *fcstr, ...) { + va_list argptr; + va_start(argptr, fcstr); + FormatV(fcstr, argptr); + va_end(argptr); +} + +void String::FormatV(const char *fcstr, va_list argptr) { + fcstr = fcstr ? fcstr : ""; + va_list argptr_cpy; + va_copy(argptr_cpy, argptr); + size_t length = vsnprintf(nullptr, 0u, fcstr, argptr); + ReserveAndShift(false, Math::Surplus(length, GetLength())); + vsprintf(_cstr, fcstr, argptr_cpy); + va_end(argptr_cpy); + _len = length; + _cstr[_len] = 0; +} + +void String::Free() { + if (_bufHead) { + assert(_bufHead->RefCount > 0); + _bufHead->RefCount--; + if (!_bufHead->RefCount) { + delete [] _buf; + } + } + _buf = nullptr; + _cstr = nullptr; + _len = 0; +} + +void String::MakeLower() { + if (_cstr) { + BecomeUnique(); + ags_strlwr(_cstr); + } +} + +void String::MakeUpper() { + if (_cstr) { + BecomeUnique(); + ags_strupr(_cstr); + } +} + +void String::Prepend(const char *cstr) { + if (cstr) { + size_t length = strlen(cstr); + if (length > 0) { + ReserveAndShift(true, length); + memcpy(_cstr - length, cstr, length); + _len += length; + _cstr -= length; + } + } +} + +void String::PrependChar(char c) { + if (c) { + ReserveAndShift(true, 1); + _len++; + _cstr--; + _cstr[0] = c; + } +} + +void String::Replace(char what, char with) { + if (_cstr && what && with && what != with) { + BecomeUnique(); + char *rep_ptr = _cstr; + while (*rep_ptr) { + if (*rep_ptr == what) { + *rep_ptr = with; + } + rep_ptr++; + } + } +} + +void String::ReplaceMid(size_t from, size_t count, const char *cstr) { + if (!cstr) + cstr = ""; + size_t length = strlen(cstr); + Math::ClampLength(from, count, (size_t)0, GetLength()); + ReserveAndShift(false, Math::Surplus(length, count)); + memmove(_cstr + from + length, _cstr + from + count, GetLength() - (from + count) + 1); + memcpy(_cstr + from, cstr, length); + _len += length - count; +} + +void String::Reverse() { + if (!_cstr || GetLength() <= 1) + return; + for (char *fw = _cstr, *bw = _cstr + _len - 1; + *fw; ++fw, --bw) { + std::swap(*fw, *bw); + } +} + +void String::SetAt(size_t index, char c) { + if (_cstr && index < GetLength() && c) { + BecomeUnique(); + _cstr[index] = c; + } +} + +void String::SetString(const char *cstr, size_t length) { + if (cstr) { + length = Math::Min(length, strlen(cstr)); + if (length > 0) { + ReserveAndShift(false, Math::Surplus(length, GetLength())); + memcpy(_cstr, cstr, length); + _len = length; + _cstr[length] = 0; + } else { + Empty(); + } + } else { + Empty(); + } +} + +void String::Trim(char c) { + TrimLeft(c); + TrimRight(c); +} + +void String::TrimLeft(char c) { + if (!_cstr || !_len) { + return; + } + + const char *trim_ptr = _cstr; + for (;;) { + auto t = *trim_ptr; + if (t == 0) { + break; + } + if (c && t != c) { + break; + } + if (!c && !isspace(t)) { + break; + } + trim_ptr++; + } + size_t trimmed = trim_ptr - _cstr; + if (trimmed > 0) { + BecomeUnique(); + _len -= trimmed; + _cstr += trimmed; + } +} + +void String::TrimRight(char c) { + if (!_cstr || !_len) { + return; + } + + const char *trim_ptr = _cstr + _len - 1; + for (;;) { + if (trim_ptr < _cstr) { + break; + } + auto t = *trim_ptr; + if (c && t != c) { + break; + } + if (!c && !isspace(t)) { + break; + } + trim_ptr--; + } + size_t trimmed = (_cstr + _len - 1) - trim_ptr; + if (trimmed > 0) { + BecomeUnique(); + _len -= trimmed; + _cstr[_len] = 0; + } +} + +void String::TruncateToLeft(size_t count) { + if (_cstr) { + count = Math::Min(count, _len); + if (count < _len) { + BecomeUnique(); + _len = count; + _cstr[_len] = 0; + } + } +} + +void String::TruncateToMid(size_t from, size_t count) { + if (_cstr) { + Math::ClampLength(from, count, (size_t)0, _len); + if (from > 0 || count < _len) { + BecomeUnique(); + _len = count; + _cstr += from; + _cstr[_len] = 0; + } + } +} + +void String::TruncateToRight(size_t count) { + if (_cstr) { + count = Math::Min(count, GetLength()); + if (count < _len) { + BecomeUnique(); + _cstr += _len - count; + _len = count; + } + } +} + +void String::TruncateToLeftSection(char separator, bool exclude_separator) { + if (_cstr && separator) { + size_t slice_at = FindChar(separator); + if (slice_at != -1) { + TruncateToLeft(exclude_separator ? slice_at : slice_at + 1); + } + } +} + +void String::TruncateToRightSection(char separator, bool exclude_separator) { + if (_cstr && separator) { + size_t slice_at = FindCharReverse(separator); + if (slice_at != -1) { + TruncateToRight(exclude_separator ? _len - slice_at - 1 : _len - slice_at); + } + } } void String::TruncateToSection(char separator, size_t first, size_t last, - bool exclude_first_sep, bool exclude_last_sep) -{ - if (!_cstr || !separator) - { - return; - } - - size_t slice_from; - size_t slice_to; - if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, - slice_from, slice_to)) - { - TruncateToMid(slice_from, slice_to - slice_from); - } - else - { - Empty(); - } -} - -void String::Wrap(const char *cstr) -{ - Free(); - _buf = nullptr; - // Note that String is NOT supposed to *modify* the const buffer. - // Any non-read operation on the buffer is preceded by a call to BecomeUnique, - // which in turn will allocate a reference-counted buffer copy. - _cstr = const_cast(cstr); - _len = strlen(cstr); -} - -String &String::operator=(const String& str) -{ - if (_cstr != str._cstr) - { - Free(); - _buf = str._buf; - _cstr = str._cstr; - _len = str._len; - if (_bufHead) - { - _bufHead->RefCount++; - } - } - return *this; -} - -String &String::operator=(const char *cstr) -{ - SetString(cstr); - return *this; -} - -void String::Create(size_t max_length) -{ - _buf = new char[sizeof(String::BufHeader) + max_length + 1]; - _bufHead->RefCount = 1; - _bufHead->Capacity = max_length; - _len = 0; - _cstr = _buf + sizeof(String::BufHeader); - _cstr[_len] = 0; -} - -void String::Copy(size_t max_length, size_t offset) -{ - if (!_cstr) - { - return; - } - - char *new_data = new char[sizeof(String::BufHeader) + max_length + 1]; - // remember, that _cstr may point to any address in buffer - char *cstr_head = new_data + sizeof(String::BufHeader) + offset; - size_t copy_length = Math::Min(_len, max_length); - memcpy(cstr_head, _cstr, copy_length); - Free(); - _buf = new_data; - _bufHead->RefCount = 1; - _bufHead->Capacity = max_length; - _len = copy_length; - _cstr = cstr_head; - _cstr[_len] = 0; -} - -void String::Align(size_t offset) -{ - char *cstr_head = _buf + sizeof(String::BufHeader) + offset; - memmove(cstr_head, _cstr, _len + 1); - _cstr = cstr_head; -} - -void String::BecomeUnique() -{ - if (_cstr && (_bufHead && _bufHead->RefCount > 1 || !_bufHead)) - { - Copy(_len); - } -} - -void String::ReserveAndShift(bool left, size_t more_length) -{ - if (_bufHead) - { - size_t total_length = _len + more_length; - if (_bufHead->Capacity < total_length) - { - // grow by 50% or at least to total_size - size_t grow_length = _bufHead->Capacity + (_bufHead->Capacity >> 1); - Copy(Math::Max(total_length, grow_length), left ? more_length : 0u); - } - else if (_bufHead->RefCount > 1) - { - Copy(total_length, left ? more_length : 0u); - } - else - { - // make sure we make use of all of our space - const char *cstr_head = _buf + sizeof(String::BufHeader); - size_t free_space = left ? - _cstr - cstr_head : - (cstr_head + _bufHead->Capacity) - (_cstr + _len); - if (free_space < more_length) - { - Align((left ? - _cstr + (more_length - free_space) : - _cstr - (more_length - free_space)) - cstr_head); - } - } - } - else - { - Create(more_length); - } + bool exclude_first_sep, bool exclude_last_sep) { + if (!_cstr || !separator) { + return; + } + + size_t slice_from; + size_t slice_to; + if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, + slice_from, slice_to)) { + TruncateToMid(slice_from, slice_to - slice_from); + } else { + Empty(); + } +} + +void String::Wrap(const char *cstr) { + Free(); + _buf = nullptr; + // Note that String is NOT supposed to *modify* the const buffer. + // Any non-read operation on the buffer is preceded by a call to BecomeUnique, + // which in turn will allocate a reference-counted buffer copy. + _cstr = const_cast(cstr); + _len = strlen(cstr); +} + +String &String::operator=(const String &str) { + if (_cstr != str._cstr) { + Free(); + _buf = str._buf; + _cstr = str._cstr; + _len = str._len; + if (_bufHead) { + _bufHead->RefCount++; + } + } + return *this; +} + +String &String::operator=(const char *cstr) { + SetString(cstr); + return *this; +} + +void String::Create(size_t max_length) { + _buf = new char[sizeof(String::BufHeader) + max_length + 1]; + _bufHead->RefCount = 1; + _bufHead->Capacity = max_length; + _len = 0; + _cstr = _buf + sizeof(String::BufHeader); + _cstr[_len] = 0; +} + +void String::Copy(size_t max_length, size_t offset) { + if (!_cstr) { + return; + } + + char *new_data = new char[sizeof(String::BufHeader) + max_length + 1]; + // remember, that _cstr may point to any address in buffer + char *cstr_head = new_data + sizeof(String::BufHeader) + offset; + size_t copy_length = Math::Min(_len, max_length); + memcpy(cstr_head, _cstr, copy_length); + Free(); + _buf = new_data; + _bufHead->RefCount = 1; + _bufHead->Capacity = max_length; + _len = copy_length; + _cstr = cstr_head; + _cstr[_len] = 0; +} + +void String::Align(size_t offset) { + char *cstr_head = _buf + sizeof(String::BufHeader) + offset; + memmove(cstr_head, _cstr, _len + 1); + _cstr = cstr_head; +} + +void String::BecomeUnique() { + if (_cstr && (_bufHead && _bufHead->RefCount > 1 || !_bufHead)) { + Copy(_len); + } +} + +void String::ReserveAndShift(bool left, size_t more_length) { + if (_bufHead) { + size_t total_length = _len + more_length; + if (_bufHead->Capacity < total_length) { + // grow by 50% or at least to total_size + size_t grow_length = _bufHead->Capacity + (_bufHead->Capacity >> 1); + Copy(Math::Max(total_length, grow_length), left ? more_length : 0u); + } else if (_bufHead->RefCount > 1) { + Copy(total_length, left ? more_length : 0u); + } else { + // make sure we make use of all of our space + const char *cstr_head = _buf + sizeof(String::BufHeader); + size_t free_space = left ? + _cstr - cstr_head : + (cstr_head + _bufHead->Capacity) - (_cstr + _len); + if (free_space < more_length) { + Align((left ? + _cstr + (more_length - free_space) : + _cstr - (more_length - free_space)) - cstr_head); + } + } + } else { + Create(more_length); + } } } // namespace Common diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index 9bc56a504536..0272468e0d0f 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -52,335 +52,316 @@ #include "core/types.h" #include "debug/assert.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class Stream; -class String -{ +class String { public: - // Standard constructor: intialize empty string - String(); - // Copy constructor - String(const String&); - // Initialize with C-string - String(const char *cstr); - // Initialize by copying up to N chars from C-string - String(const char *cstr, size_t length); - // Initialize by filling N chars with certain value - String(char c, size_t count); - ~String(); - - // Get underlying C-string for reading; this method guarantees valid C-string - inline const char *GetCStr() const - { - return _cstr ? _cstr : ""; - } - // Get C-string or nullptr - inline const char *GetNullableCStr() const - { - return _cstr ? _cstr : nullptr; - } - // Get character count - inline size_t GetLength() const - { - return _len; - } - // Know if the string is empty (has no meaningful characters) - inline bool IsEmpty() const - { - return _len == 0; - } - - // Those getters are for tests only, hence if AGS_PLATFORM_DEBUG + // Standard constructor: intialize empty string + String(); + // Copy constructor + String(const String &); + // Initialize with C-string + String(const char *cstr); + // Initialize by copying up to N chars from C-string + String(const char *cstr, size_t length); + // Initialize by filling N chars with certain value + String(char c, size_t count); + ~String(); + + // Get underlying C-string for reading; this method guarantees valid C-string + inline const char *GetCStr() const { + return _cstr ? _cstr : ""; + } + // Get C-string or nullptr + inline const char *GetNullableCStr() const { + return _cstr ? _cstr : nullptr; + } + // Get character count + inline size_t GetLength() const { + return _len; + } + // Know if the string is empty (has no meaningful characters) + inline bool IsEmpty() const { + return _len == 0; + } + + // Those getters are for tests only, hence if AGS_PLATFORM_DEBUG #if AGS_PLATFORM_DEBUG - inline const char *GetBuffer() const - { - return _buf; - } - - inline size_t GetCapacity() const - { - return _bufHead ? _bufHead->Capacity : 0; - } - - inline size_t GetRefCount() const - { - return _bufHead ? _bufHead->RefCount : 0; - } + inline const char *GetBuffer() const { + return _buf; + } + + inline size_t GetCapacity() const { + return _bufHead ? _bufHead->Capacity : 0; + } + + inline size_t GetRefCount() const { + return _bufHead ? _bufHead->RefCount : 0; + } #endif - // Read() method implies that string length is initially unknown. - // max_chars parameter determine the buffer size limit. - // If stop_at_limit flag is set, it will read only up to the max_chars. - // Otherwise (by default) hitting the limit won't stop stream reading; - // the data will be read until null-terminator or EOS is met, and buffer - // will contain only leftmost part of the longer string that fits in. - // This method is better fit for reading from binary streams. - void Read(Stream *in, size_t max_chars = 5 * 1024 * 1024, bool stop_at_limit = false); - // ReadCount() reads up to N characters from stream, ignoring null- - // terminator. This method is better fit for reading from text - // streams, or when the length of string is known beforehand. - void ReadCount(Stream *in, size_t count); - // Write() puts the null-terminated string into the stream. - void Write(Stream *out) const; - // WriteCount() writes N characters to stream, filling the remaining - // space with null-terminators when needed. - void WriteCount(Stream *out, size_t count) const; - - static void WriteString(const char *cstr, Stream *out); - - //------------------------------------------------------------------------- - // String analysis methods - //------------------------------------------------------------------------- - - // Compares with given C-string - int Compare(const char *cstr) const; - int CompareNoCase(const char *cstr) const; - // Compares the leftmost part of this string with given C-string - int CompareLeft(const char *cstr, size_t count = -1) const; - int CompareLeftNoCase(const char *cstr, size_t count = -1) const; - // Compares any part of this string with given C-string - int CompareMid(const char *cstr, size_t from, size_t count = -1) const; - int CompareMidNoCase(const char *cstr, size_t from, size_t count = -1) const; - // Compares the rightmost part of this string with given C-string - int CompareRight(const char *cstr, size_t count = -1) const; - int CompareRightNoCase(const char *cstr, size_t count = -1) const; - - // These functions search for character or substring inside this string - // and return the index of the (first) character, or -1 if nothing found. - size_t FindChar(char c, size_t from = 0) const; - size_t FindCharReverse(char c, size_t from = -1) const; - size_t FindString(const char *cstr, size_t from = 0) const; - - // Section methods treat string as a sequence of 'fields', separated by - // special character. They search for a substring consisting of all such - // 'fields' from the 'first' to the 'last', inclusive; the bounding - // separators are optionally included too. - // Section indexes are zero-based. The first (0th) section is always - // located before the first separator and the last section is always - // located after the last separator, meaning that if the outermost - // character in string is separator char, there's still an empty trailing - // field beyond that. - // This also means that there's always at least one section in any string, - // even if there are no separating chars. - bool FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, - size_t &from, size_t &to) const; - - // Get Nth character with bounds check (as opposed to subscript operator) - inline char GetAt(size_t index) const - { - return (index < _len) ? _cstr[index] : 0; - } - inline char GetLast() const - { - return (_len > 0) ? _cstr[_len - 1] : 0; - } - - //------------------------------------------------------------------------- - // Value cast methods - //------------------------------------------------------------------------- - - int ToInt() const; - - //------------------------------------------------------------------------- - // Factory methods - //------------------------------------------------------------------------- - - // Wraps the given string buffer without owning it, won't count references, - // won't delete it at destruction. Can be used with string literals. - static String Wrapper(const char *cstr); - - static String FromFormat(const char *fcstr, ...); - static String FromFormatV(const char *fcstr, va_list argptr); - // Reads stream until null-terminator or EOS - static String FromStream(Stream *in, size_t max_chars = 5 * 1024 * 1024, bool stop_at_limit = false); - // Reads up to N chars from stream - static String FromStreamCount(Stream *in, size_t count); - - // Creates a lowercased copy of the string - String Lower() const; - // Creates an uppercased copy of the string - String Upper() const; - - // Extract N leftmost characters as a new string - String Left(size_t count) const; - // Extract up to N characters starting from given index - String Mid(size_t from, size_t count = -1) const; - // Extract N rightmost characters - String Right(size_t count) const; - - // Extract leftmost part, separated by the given char; if no separator was - // found returns the whole string - String LeftSection(char separator, bool exclude_separator = true) const; - // Extract rightmost part, separated by the given char; if no separator was - // found returns the whole string - String RightSection(char separator, bool exclude_separator = true) const; - // Extract the range of Xth to Yth fields, separated by the given character - String Section(char separator, size_t first, size_t last, - bool exclude_first_sep = true, bool exclude_last_sep = true) const; - // Splits the string into segments divided by the instances of a given character, - // including empty segments e.g. if separators follow each other; - // returns at least one segment (equal to full string if no separator was found) - std::vector Split(char separator) const; - - //------------------------------------------------------------------------- - // String modification methods - //------------------------------------------------------------------------- - - // Ensure string has at least space to store N chars; - // this does not change string contents, nor length - void Reserve(size_t max_length); - // Ensure string has at least space to store N additional chars - void ReserveMore(size_t more_length); - // Make string's buffer as small as possible to hold current data - void Compact(); - - // Append* methods add content at the string's end, increasing its length - // Add C-string at string's end - void Append(const char *cstr); - // Add single character at string's end - void AppendChar(char c); - // Clip* methods decrease the string, removing defined part - // Cuts off leftmost N characters - void ClipLeft(size_t count); - // Cuts out N characters starting from given index - void ClipMid(size_t from, size_t count = -1); - // Cuts off rightmost N characters - void ClipRight(size_t count); - // Cuts off leftmost part, separated by the given char; if no separator was - // found cuts whole string, leaving empty string - void ClipLeftSection(char separator, bool include_separator = true); - // Cuts off rightmost part, separated by the given char; if no separator - // was found cuts whole string, leaving empty string - void ClipRightSection(char separator, bool include_separator = true); - // Cuts out the range of Xth to Yth fields separated by the given character - void ClipSection(char separator, size_t first, size_t last, - bool include_first_sep = true, bool include_last_sep = true); - // Sets string length to zero - void Empty(); - // Makes a new string by filling N chars with certain value - void FillString(char c, size_t count); - // Makes a new string by putting in parameters according to format string - void Format(const char *fcstr, ...); - void FormatV(const char *fcstr, va_list argptr); - // Decrement ref counter and deallocate data if must. - // Free() should be called only when buffer is not needed anymore; - // if string must be truncated to zero length, but retain the allocated - // memory, call Empty() instead. - void Free(); - // Convert string to lowercase equivalent - void MakeLower(); - // Convert string to uppercase equivalent - void MakeUpper(); - // Prepend* methods add content before the string's head, increasing its length - // Add C-string before string's head - void Prepend(const char *cstr); - // Add single character before string's head - void PrependChar(char c); - // Replaces all occurences of one character with another character - void Replace(char what, char with); - // Replaces particular substring with another substring; new substring - // may have different length - void ReplaceMid(size_t from, size_t count, const char *cstr); - // Reverses the string - void Reverse(); - // Overwrite the Nth character of the string; does not change string's length - void SetAt(size_t index, char c); - // Makes a new string by copying up to N chars from C-string - void SetString(const char *cstr, size_t length = -1); - // For all Trim functions, if given character value is 0, all whitespace - // characters (space, tabs, CRLF) are removed. - // Remove heading and trailing characters from the string - void Trim(char c = 0); - // Remove heading characters from the string; - void TrimLeft(char c = 0); - // Remove trailing characters from the string - void TrimRight(char c = 0); - // Truncate* methods decrease the string to the part of itself - // Truncate the string to the leftmost N characters - void TruncateToLeft(size_t count); - // Truncate the string to the middle N characters - void TruncateToMid(size_t from, size_t count = -1); - // Truncate the string to the rightmost N characters - void TruncateToRight(size_t count); - // Truncate the string to the leftmost part, separated by the given char; - // if no separator was found leaves string unchanged - void TruncateToLeftSection(char separator, bool exclude_separator = true); - // Truncate the string to the rightmost part, separated by the given char; - // if no separator was found leaves string unchanged - void TruncateToRightSection(char separator, bool exclude_separator = true); - // Truncate the string to range of Xth to Yth fields separated by the - // given character - void TruncateToSection(char separator, size_t first, size_t last, - bool exclude_first_sep = true, bool exclude_last_sep = true); - // Wraps the given string buffer without owning it, won't count references, - // won't delete it at destruction. Can be used with string literals. - void Wrap(const char *cstr); - - //------------------------------------------------------------------------- - // Operators - //------------------------------------------------------------------------- - - inline operator const char *() const - { - return GetCStr(); - } - // Assign String by sharing data reference - String &operator=(const String&); - // Assign C-string by copying contents - String &operator=(const char *cstr); - inline char operator[](size_t index) const - { - assert(index < _len); - return _cstr[index]; - } - inline bool operator==(const char *cstr) const - { - return Compare(cstr) == 0; - } - inline bool operator!=(const char *cstr) const - { - return Compare(cstr) != 0; - } - inline bool operator <(const char *cstr) const - { - return Compare(cstr) < 0; - } + // Read() method implies that string length is initially unknown. + // max_chars parameter determine the buffer size limit. + // If stop_at_limit flag is set, it will read only up to the max_chars. + // Otherwise (by default) hitting the limit won't stop stream reading; + // the data will be read until null-terminator or EOS is met, and buffer + // will contain only leftmost part of the longer string that fits in. + // This method is better fit for reading from binary streams. + void Read(Stream *in, size_t max_chars = 5 * 1024 * 1024, bool stop_at_limit = false); + // ReadCount() reads up to N characters from stream, ignoring null- + // terminator. This method is better fit for reading from text + // streams, or when the length of string is known beforehand. + void ReadCount(Stream *in, size_t count); + // Write() puts the null-terminated string into the stream. + void Write(Stream *out) const; + // WriteCount() writes N characters to stream, filling the remaining + // space with null-terminators when needed. + void WriteCount(Stream *out, size_t count) const; + + static void WriteString(const char *cstr, Stream *out); + + //------------------------------------------------------------------------- + // String analysis methods + //------------------------------------------------------------------------- + + // Compares with given C-string + int Compare(const char *cstr) const; + int CompareNoCase(const char *cstr) const; + // Compares the leftmost part of this string with given C-string + int CompareLeft(const char *cstr, size_t count = -1) const; + int CompareLeftNoCase(const char *cstr, size_t count = -1) const; + // Compares any part of this string with given C-string + int CompareMid(const char *cstr, size_t from, size_t count = -1) const; + int CompareMidNoCase(const char *cstr, size_t from, size_t count = -1) const; + // Compares the rightmost part of this string with given C-string + int CompareRight(const char *cstr, size_t count = -1) const; + int CompareRightNoCase(const char *cstr, size_t count = -1) const; + + // These functions search for character or substring inside this string + // and return the index of the (first) character, or -1 if nothing found. + size_t FindChar(char c, size_t from = 0) const; + size_t FindCharReverse(char c, size_t from = -1) const; + size_t FindString(const char *cstr, size_t from = 0) const; + + // Section methods treat string as a sequence of 'fields', separated by + // special character. They search for a substring consisting of all such + // 'fields' from the 'first' to the 'last', inclusive; the bounding + // separators are optionally included too. + // Section indexes are zero-based. The first (0th) section is always + // located before the first separator and the last section is always + // located after the last separator, meaning that if the outermost + // character in string is separator char, there's still an empty trailing + // field beyond that. + // This also means that there's always at least one section in any string, + // even if there are no separating chars. + bool FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, + size_t &from, size_t &to) const; + + // Get Nth character with bounds check (as opposed to subscript operator) + inline char GetAt(size_t index) const { + return (index < _len) ? _cstr[index] : 0; + } + inline char GetLast() const { + return (_len > 0) ? _cstr[_len - 1] : 0; + } + + //------------------------------------------------------------------------- + // Value cast methods + //------------------------------------------------------------------------- + + int ToInt() const; + + //------------------------------------------------------------------------- + // Factory methods + //------------------------------------------------------------------------- + + // Wraps the given string buffer without owning it, won't count references, + // won't delete it at destruction. Can be used with string literals. + static String Wrapper(const char *cstr); + + static String FromFormat(const char *fcstr, ...); + static String FromFormatV(const char *fcstr, va_list argptr); + // Reads stream until null-terminator or EOS + static String FromStream(Stream *in, size_t max_chars = 5 * 1024 * 1024, bool stop_at_limit = false); + // Reads up to N chars from stream + static String FromStreamCount(Stream *in, size_t count); + + // Creates a lowercased copy of the string + String Lower() const; + // Creates an uppercased copy of the string + String Upper() const; + + // Extract N leftmost characters as a new string + String Left(size_t count) const; + // Extract up to N characters starting from given index + String Mid(size_t from, size_t count = -1) const; + // Extract N rightmost characters + String Right(size_t count) const; + + // Extract leftmost part, separated by the given char; if no separator was + // found returns the whole string + String LeftSection(char separator, bool exclude_separator = true) const; + // Extract rightmost part, separated by the given char; if no separator was + // found returns the whole string + String RightSection(char separator, bool exclude_separator = true) const; + // Extract the range of Xth to Yth fields, separated by the given character + String Section(char separator, size_t first, size_t last, + bool exclude_first_sep = true, bool exclude_last_sep = true) const; + // Splits the string into segments divided by the instances of a given character, + // including empty segments e.g. if separators follow each other; + // returns at least one segment (equal to full string if no separator was found) + std::vector Split(char separator) const; + + //------------------------------------------------------------------------- + // String modification methods + //------------------------------------------------------------------------- + + // Ensure string has at least space to store N chars; + // this does not change string contents, nor length + void Reserve(size_t max_length); + // Ensure string has at least space to store N additional chars + void ReserveMore(size_t more_length); + // Make string's buffer as small as possible to hold current data + void Compact(); + + // Append* methods add content at the string's end, increasing its length + // Add C-string at string's end + void Append(const char *cstr); + // Add single character at string's end + void AppendChar(char c); + // Clip* methods decrease the string, removing defined part + // Cuts off leftmost N characters + void ClipLeft(size_t count); + // Cuts out N characters starting from given index + void ClipMid(size_t from, size_t count = -1); + // Cuts off rightmost N characters + void ClipRight(size_t count); + // Cuts off leftmost part, separated by the given char; if no separator was + // found cuts whole string, leaving empty string + void ClipLeftSection(char separator, bool include_separator = true); + // Cuts off rightmost part, separated by the given char; if no separator + // was found cuts whole string, leaving empty string + void ClipRightSection(char separator, bool include_separator = true); + // Cuts out the range of Xth to Yth fields separated by the given character + void ClipSection(char separator, size_t first, size_t last, + bool include_first_sep = true, bool include_last_sep = true); + // Sets string length to zero + void Empty(); + // Makes a new string by filling N chars with certain value + void FillString(char c, size_t count); + // Makes a new string by putting in parameters according to format string + void Format(const char *fcstr, ...); + void FormatV(const char *fcstr, va_list argptr); + // Decrement ref counter and deallocate data if must. + // Free() should be called only when buffer is not needed anymore; + // if string must be truncated to zero length, but retain the allocated + // memory, call Empty() instead. + void Free(); + // Convert string to lowercase equivalent + void MakeLower(); + // Convert string to uppercase equivalent + void MakeUpper(); + // Prepend* methods add content before the string's head, increasing its length + // Add C-string before string's head + void Prepend(const char *cstr); + // Add single character before string's head + void PrependChar(char c); + // Replaces all occurences of one character with another character + void Replace(char what, char with); + // Replaces particular substring with another substring; new substring + // may have different length + void ReplaceMid(size_t from, size_t count, const char *cstr); + // Reverses the string + void Reverse(); + // Overwrite the Nth character of the string; does not change string's length + void SetAt(size_t index, char c); + // Makes a new string by copying up to N chars from C-string + void SetString(const char *cstr, size_t length = -1); + // For all Trim functions, if given character value is 0, all whitespace + // characters (space, tabs, CRLF) are removed. + // Remove heading and trailing characters from the string + void Trim(char c = 0); + // Remove heading characters from the string; + void TrimLeft(char c = 0); + // Remove trailing characters from the string + void TrimRight(char c = 0); + // Truncate* methods decrease the string to the part of itself + // Truncate the string to the leftmost N characters + void TruncateToLeft(size_t count); + // Truncate the string to the middle N characters + void TruncateToMid(size_t from, size_t count = -1); + // Truncate the string to the rightmost N characters + void TruncateToRight(size_t count); + // Truncate the string to the leftmost part, separated by the given char; + // if no separator was found leaves string unchanged + void TruncateToLeftSection(char separator, bool exclude_separator = true); + // Truncate the string to the rightmost part, separated by the given char; + // if no separator was found leaves string unchanged + void TruncateToRightSection(char separator, bool exclude_separator = true); + // Truncate the string to range of Xth to Yth fields separated by the + // given character + void TruncateToSection(char separator, size_t first, size_t last, + bool exclude_first_sep = true, bool exclude_last_sep = true); + // Wraps the given string buffer without owning it, won't count references, + // won't delete it at destruction. Can be used with string literals. + void Wrap(const char *cstr); + + //------------------------------------------------------------------------- + // Operators + //------------------------------------------------------------------------- + + inline operator const char *() const { + return GetCStr(); + } + // Assign String by sharing data reference + String &operator=(const String &); + // Assign C-string by copying contents + String &operator=(const char *cstr); + inline char operator[](size_t index) const { + assert(index < _len); + return _cstr[index]; + } + inline bool operator==(const char *cstr) const { + return Compare(cstr) == 0; + } + inline bool operator!=(const char *cstr) const { + return Compare(cstr) != 0; + } + inline bool operator <(const char *cstr) const { + return Compare(cstr) < 0; + } private: - // Creates new empty string with buffer enough to fit given length - void Create(size_t buffer_length); - // Release string and copy data to the new buffer - void Copy(size_t buffer_length, size_t offset = 0); - // Aligns data at given offset - void Align(size_t offset); - - // Ensure this string is a compact independent copy, with ref counter = 1 - void BecomeUnique(); - // Ensure this string is independent, and there's enough space before - // or after the current string data - void ReserveAndShift(bool left, size_t more_length); - - char *_cstr; // pointer to actual string data - size_t _len; // valid string length, in characters, excluding null-term - - // Header of a reference-counted buffer - struct BufHeader - { - size_t RefCount = 0; // reference count - size_t Capacity = 0; // available space, in characters - }; - - // Union that groups mutually exclusive data (currently only ref counted buffer) - union - { - char *_buf; // reference-counted data (raw ptr) - BufHeader *_bufHead; // the header of a reference-counted data - }; + // Creates new empty string with buffer enough to fit given length + void Create(size_t buffer_length); + // Release string and copy data to the new buffer + void Copy(size_t buffer_length, size_t offset = 0); + // Aligns data at given offset + void Align(size_t offset); + + // Ensure this string is a compact independent copy, with ref counter = 1 + void BecomeUnique(); + // Ensure this string is independent, and there's enough space before + // or after the current string data + void ReserveAndShift(bool left, size_t more_length); + + char *_cstr; // pointer to actual string data + size_t _len; // valid string length, in characters, excluding null-term + + // Header of a reference-counted buffer + struct BufHeader { + size_t RefCount = 0; // reference count + size_t Capacity = 0; // available space, in characters + }; + + // Union that groups mutually exclusive data (currently only ref counted buffer) + union { + char *_buf; // reference-counted data (raw ptr) + BufHeader *_bufHead; // the header of a reference-counted data + }; }; } // namespace Common diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index 62c81dd15706..28989aa44694 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -30,46 +30,39 @@ #include #include "util/string.h" -namespace FNV -{ +namespace FNV { const uint32_t PRIME_NUMBER = 2166136261U; const uint32_t SECONDARY_NUMBER = 16777619U; -inline size_t Hash(const char *data, const size_t len) -{ - uint32_t hash = PRIME_NUMBER; - for (size_t i = 0; i < len; ++i) - hash = (SECONDARY_NUMBER * hash) ^ (uint8_t)(data[i]); - return hash; +inline size_t Hash(const char *data, const size_t len) { + uint32_t hash = PRIME_NUMBER; + for (size_t i = 0; i < len; ++i) + hash = (SECONDARY_NUMBER * hash) ^ (uint8_t)(data[i]); + return hash; } -inline size_t Hash_LowerCase(const char *data, const size_t len) -{ - uint32_t hash = PRIME_NUMBER; - for (size_t i = 0; i < len; ++i) - hash = (SECONDARY_NUMBER * hash) ^ (uint8_t)(tolower(data[i])); - return hash; +inline size_t Hash_LowerCase(const char *data, const size_t len) { + uint32_t hash = PRIME_NUMBER; + for (size_t i = 0; i < len; ++i) + hash = (SECONDARY_NUMBER * hash) ^ (uint8_t)(tolower(data[i])); + return hash; } } // namespace FNV // A std::hash specialization for AGS String -namespace std -{ +namespace std { #ifdef AGS_NEEDS_TR1 -namespace tr1 -{ +namespace tr1 { #endif // std::hash for String object template<> -struct hash : public unary_function -{ - size_t operator ()(const AGS::Common::String &key) const - { - return FNV::Hash(key.GetCStr(), key.GetLength()); - } +struct hash : public unary_function { + size_t operator()(const AGS::Common::String &key) const { + return FNV::Hash(key.GetCStr(), key.GetLength()); + } }; #ifdef AGS_NEEDS_TR1 } @@ -77,40 +70,32 @@ struct hash : public unary_function -{ - bool operator()(const String &s1, const String &s2) const - { - return s1.CompareNoCase(s2) == 0; - } +struct StrEqNoCase : public std::binary_function { + bool operator()(const String &s1, const String &s2) const { + return s1.CompareNoCase(s2) == 0; + } }; // Case-insensitive String less -struct StrLessNoCase : public std::binary_function -{ - bool operator()(const String &s1, const String &s2) const - { - return s1.CompareNoCase(s2) < 0; - } +struct StrLessNoCase : public std::binary_function { + bool operator()(const String &s1, const String &s2) const { + return s1.CompareNoCase(s2) < 0; + } }; // Compute case-insensitive hash for a String object -struct HashStrNoCase : public std::unary_function -{ - size_t operator ()(const String &key) const - { - return FNV::Hash_LowerCase(key.GetCStr(), key.GetLength()); - } +struct HashStrNoCase : public std::unary_function { + size_t operator()(const String &key) const { + return FNV::Hash_LowerCase(key.GetCStr(), key.GetLength()); + } }; typedef std::vector StringV; diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp index 67c22b4556c8..5278966534a1 100644 --- a/engines/ags/shared/util/string_utils.cpp +++ b/engines/ags/shared/util/string_utils.cpp @@ -29,151 +29,131 @@ using namespace AGS::Common; -String cbuf_to_string_and_free(char *char_buf) -{ - String s = char_buf; - free(char_buf); - return s; +String cbuf_to_string_and_free(char *char_buf) { + String s = char_buf; + free(char_buf); + return s; } -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -String StrUtil::IntToString(int d) -{ - return String::FromFormat("%d", d); +String StrUtil::IntToString(int d) { + return String::FromFormat("%d", d); } -int StrUtil::StringToInt(const String &s, int def_val) -{ - if (!s.GetCStr()) - return def_val; - char *stop_ptr; - int val = strtol(s.GetCStr(), &stop_ptr, 0); - return (stop_ptr == s.GetCStr() + s.GetLength()) ? val : def_val; +int StrUtil::StringToInt(const String &s, int def_val) { + if (!s.GetCStr()) + return def_val; + char *stop_ptr; + int val = strtol(s.GetCStr(), &stop_ptr, 0); + return (stop_ptr == s.GetCStr() + s.GetLength()) ? val : def_val; } -StrUtil::ConversionError StrUtil::StringToInt(const String &s, int &val, int def_val) -{ - val = def_val; - if (!s.GetCStr()) - return StrUtil::kFailed; - char *stop_ptr; - errno = 0; - long lval = strtol(s.GetCStr(), &stop_ptr, 0); - if (stop_ptr != s.GetCStr() + s.GetLength()) - return StrUtil::kFailed; - if (lval > INT_MAX || lval < INT_MIN || errno == ERANGE) - return StrUtil::kOutOfRange; - val = (int)lval; - return StrUtil::kNoError; +StrUtil::ConversionError StrUtil::StringToInt(const String &s, int &val, int def_val) { + val = def_val; + if (!s.GetCStr()) + return StrUtil::kFailed; + char *stop_ptr; + errno = 0; + long lval = strtol(s.GetCStr(), &stop_ptr, 0); + if (stop_ptr != s.GetCStr() + s.GetLength()) + return StrUtil::kFailed; + if (lval > INT_MAX || lval < INT_MIN || errno == ERANGE) + return StrUtil::kOutOfRange; + val = (int)lval; + return StrUtil::kNoError; } -String StrUtil::ReadString(Stream *in) -{ - size_t len = in->ReadInt32(); - if (len > 0) - return String::FromStreamCount(in, len); - return String(); +String StrUtil::ReadString(Stream *in) { + size_t len = in->ReadInt32(); + if (len > 0) + return String::FromStreamCount(in, len); + return String(); } -void StrUtil::ReadString(char *cstr, Stream *in, size_t buf_limit) -{ - size_t len = in->ReadInt32(); - if (buf_limit == 0) - { - in->Seek(len); - return; - } - - len = Math::Min(len, buf_limit - 1); - if (len > 0) - in->Read(cstr, len); - cstr[len] = 0; +void StrUtil::ReadString(char *cstr, Stream *in, size_t buf_limit) { + size_t len = in->ReadInt32(); + if (buf_limit == 0) { + in->Seek(len); + return; + } + + len = Math::Min(len, buf_limit - 1); + if (len > 0) + in->Read(cstr, len); + cstr[len] = 0; } -void StrUtil::ReadString(String &s, Stream *in) -{ - size_t len = in->ReadInt32(); - s.ReadCount(in, len); +void StrUtil::ReadString(String &s, Stream *in) { + size_t len = in->ReadInt32(); + s.ReadCount(in, len); } -void StrUtil::ReadString(char **cstr, Stream *in) -{ - size_t len = in->ReadInt32(); - *cstr = new char[len + 1]; - if (len > 0) - in->Read(*cstr, len); - (*cstr)[len] = 0; +void StrUtil::ReadString(char **cstr, Stream *in) { + size_t len = in->ReadInt32(); + *cstr = new char[len + 1]; + if (len > 0) + in->Read(*cstr, len); + (*cstr)[len] = 0; } -void StrUtil::SkipString(Stream *in) -{ - size_t len = in->ReadInt32(); - in->Seek(len); +void StrUtil::SkipString(Stream *in) { + size_t len = in->ReadInt32(); + in->Seek(len); } -void StrUtil::WriteString(const String &s, Stream *out) -{ - size_t len = s.GetLength(); - out->WriteInt32(len); - if (len > 0) - out->Write(s.GetCStr(), len); +void StrUtil::WriteString(const String &s, Stream *out) { + size_t len = s.GetLength(); + out->WriteInt32(len); + if (len > 0) + out->Write(s.GetCStr(), len); } -void StrUtil::WriteString(const char *cstr, Stream *out) -{ - size_t len = strlen(cstr); - out->WriteInt32(len); - if (len > 0) - out->Write(cstr, len); +void StrUtil::WriteString(const char *cstr, Stream *out) { + size_t len = strlen(cstr); + out->WriteInt32(len); + if (len > 0) + out->Write(cstr, len); } -void StrUtil::ReadCStr(char *buf, Stream *in, size_t buf_limit) -{ - if (buf_limit == 0) - { - while (in->ReadByte() > 0); - return; - } - - auto ptr = buf; - auto last = buf + buf_limit - 1; - for (;;) - { - if (ptr >= last) { - *ptr = 0; - while (in->ReadByte() > 0); // must still read until 0 - break; - } - - auto ichar = in->ReadByte(); - if (ichar <= 0) { - *ptr = 0; - break; - } - *ptr = static_cast(ichar); - ptr++; - } +void StrUtil::ReadCStr(char *buf, Stream *in, size_t buf_limit) { + if (buf_limit == 0) { + while (in->ReadByte() > 0); + return; + } + + auto ptr = buf; + auto last = buf + buf_limit - 1; + for (;;) { + if (ptr >= last) { + *ptr = 0; + while (in->ReadByte() > 0); // must still read until 0 + break; + } + + auto ichar = in->ReadByte(); + if (ichar <= 0) { + *ptr = 0; + break; + } + *ptr = static_cast(ichar); + ptr++; + } } -void StrUtil::SkipCStr(Stream *in) -{ - while (in->ReadByte() > 0); +void StrUtil::SkipCStr(Stream *in) { + while (in->ReadByte() > 0); } -void StrUtil::WriteCStr(const char *cstr, Stream *out) -{ - size_t len = strlen(cstr); - out->Write(cstr, len + 1); +void StrUtil::WriteCStr(const char *cstr, Stream *out) { + size_t len = strlen(cstr); + out->Write(cstr, len + 1); } -void StrUtil::WriteCStr(const String &s, Stream *out) -{ - out->Write(s.GetCStr(), s.GetLength() + 1); +void StrUtil::WriteCStr(const String &s, Stream *out) { + out->Write(s.GetCStr(), s.GetLength() + 1); } } // namespace Common diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h index 440d3521612c..305deb523137 100644 --- a/engines/ags/shared/util/string_utils.h +++ b/engines/ags/shared/util/string_utils.h @@ -25,7 +25,11 @@ #include "util/string.h" -namespace AGS { namespace Common { class Stream; } } +namespace AGS { +namespace Common { +class Stream; +} +} using namespace AGS; // FIXME later //============================================================================= @@ -34,45 +38,41 @@ using namespace AGS; // FIXME later // This is used when we get a malloc'd char array from some utility function. Common::String cbuf_to_string_and_free(char *char_buf); -namespace AGS -{ -namespace Common -{ -namespace StrUtil -{ - enum ConversionError - { - kNoError, // conversion successful - kFailed, // conversion failed (e.g. wrong format) - kOutOfRange // the resulting value is out of range - }; +namespace AGS { +namespace Common { +namespace StrUtil { +enum ConversionError { + kNoError, // conversion successful + kFailed, // conversion failed (e.g. wrong format) + kOutOfRange // the resulting value is out of range +}; - // Convert integer to string, by printing its value - String IntToString(int val); - // Tries to convert whole string into integer value; - // returns def_val on failure - int StringToInt(const String &s, int def_val = 0); - // Tries to convert whole string into integer value; - // Returns error code if any non-digit character was met or if value is out - // of range; the 'val' variable will be set with resulting integer, or - // def_val on failure - ConversionError StringToInt(const String &s, int &val, int def_val); +// Convert integer to string, by printing its value +String IntToString(int val); +// Tries to convert whole string into integer value; +// returns def_val on failure +int StringToInt(const String &s, int def_val = 0); +// Tries to convert whole string into integer value; +// Returns error code if any non-digit character was met or if value is out +// of range; the 'val' variable will be set with resulting integer, or +// def_val on failure +ConversionError StringToInt(const String &s, int &val, int def_val); - // Serialize and unserialize unterminated string prefixed with 32-bit length; - // length is presented as 32-bit integer integer - String ReadString(Stream *in); - void ReadString(char *cstr, Stream *in, size_t buf_limit); - void ReadString(char **cstr, Stream *in); - void ReadString(String &s, Stream *in); - void SkipString(Stream *in); - void WriteString(const String &s, Stream *out); - void WriteString(const char *cstr, Stream *out); +// Serialize and unserialize unterminated string prefixed with 32-bit length; +// length is presented as 32-bit integer integer +String ReadString(Stream *in); +void ReadString(char *cstr, Stream *in, size_t buf_limit); +void ReadString(char **cstr, Stream *in); +void ReadString(String &s, Stream *in); +void SkipString(Stream *in); +void WriteString(const String &s, Stream *out); +void WriteString(const char *cstr, Stream *out); - // Serialize and unserialize string as c-string (null-terminated sequence) - void ReadCStr(char *buf, Stream *in, size_t buf_limit); - void SkipCStr(Stream *in); - void WriteCStr(const char *cstr, Stream *out); - void WriteCStr(const String &s, Stream *out); +// Serialize and unserialize string as c-string (null-terminated sequence) +void ReadCStr(char *buf, Stream *in, size_t buf_limit); +void SkipCStr(Stream *in); +void WriteCStr(const char *cstr, Stream *out); +void WriteCStr(const String &s, Stream *out); } } // namespace Common } // namespace AGS diff --git a/engines/ags/shared/util/textreader.h b/engines/ags/shared/util/textreader.h index d5fc20c02619..fb1c7b3eafd1 100644 --- a/engines/ags/shared/util/textreader.h +++ b/engines/ags/shared/util/textreader.h @@ -31,26 +31,23 @@ #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class TextReader -{ +class TextReader { public: - virtual ~TextReader() = default; - - virtual bool IsValid() const = 0; - - // Read single character - virtual char ReadChar() = 0; - // Read defined number of characters - virtual String ReadString(size_t length) = 0; - // Read till line break - virtual String ReadLine() = 0; - // Read till end of available data - virtual String ReadAll() = 0; + virtual ~TextReader() = default; + + virtual bool IsValid() const = 0; + + // Read single character + virtual char ReadChar() = 0; + // Read defined number of characters + virtual String ReadString(size_t length) = 0; + // Read till line break + virtual String ReadLine() = 0; + // Read till end of available data + virtual String ReadAll() = 0; }; } // namespace Common diff --git a/engines/ags/shared/util/textstreamreader.cpp b/engines/ags/shared/util/textstreamreader.cpp index 90e01d84f0e9..5b974e838c51 100644 --- a/engines/ags/shared/util/textstreamreader.cpp +++ b/engines/ags/shared/util/textstreamreader.cpp @@ -24,138 +24,112 @@ #include "util/stream.h" #include "util/textstreamreader.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { TextStreamReader::TextStreamReader(Stream *stream) - : _stream(stream) -{ + : _stream(stream) { } -TextStreamReader::~TextStreamReader() -{ - // TODO: use shared ptr - delete _stream; +TextStreamReader::~TextStreamReader() { + // TODO: use shared ptr + delete _stream; } -bool TextStreamReader::IsValid() const -{ - return _stream && _stream->CanRead(); +bool TextStreamReader::IsValid() const { + return _stream && _stream->CanRead(); } -const Stream *TextStreamReader::GetStream() const -{ - return _stream; +const Stream *TextStreamReader::GetStream() const { + return _stream; } -void TextStreamReader::ReleaseStream() -{ - _stream = nullptr; +void TextStreamReader::ReleaseStream() { + _stream = nullptr; } -bool TextStreamReader::EOS() const -{ - return _stream ? _stream->EOS() : true; +bool TextStreamReader::EOS() const { + return _stream ? _stream->EOS() : true; } -char TextStreamReader::ReadChar() -{ - if (_stream) - { - // Skip carriage-returns - char c; - do - { - c = _stream->ReadByte(); - } - while (!_stream->EOS() && c == '\r'); - return c; - } - return '\0'; +char TextStreamReader::ReadChar() { + if (_stream) { + // Skip carriage-returns + char c; + do { + c = _stream->ReadByte(); + } while (!_stream->EOS() && c == '\r'); + return c; + } + return '\0'; } -String TextStreamReader::ReadString(size_t length) -{ - if (!_stream) - { - return ""; - } - // TODO: remove carriage-return characters - return String::FromStreamCount(_stream, length); +String TextStreamReader::ReadString(size_t length) { + if (!_stream) { + return ""; + } + // TODO: remove carriage-return characters + return String::FromStreamCount(_stream, length); } -String TextStreamReader::ReadLine() -{ - // TODO - // Probably it is possible to group Stream::ReadString with this, - // both use similar algorythm, difference is only in terminator chars - - if (!_stream) - { - return ""; - } - - String str; - int chars_read_last = 0; - int line_break_position = -1; - // Read a chunk of memory to buffer and seek for null-terminator, - // if not found, repeat until EOS - const int single_chunk_length = 3000; - const int max_chars = 5000000; - char char_buffer[single_chunk_length + 1]; - do - { - chars_read_last = _stream->Read(char_buffer, single_chunk_length); - char *seek_ptr = char_buffer; - int c; - for (c = 0; c < chars_read_last && *seek_ptr != '\n'; ++c, ++seek_ptr); - - int append_length = 0; - int str_len = str.GetLength(); - if (c < chars_read_last && *seek_ptr == '\n') - { - line_break_position = seek_ptr - char_buffer; - if (str_len < max_chars) - { - append_length = Math::Min(line_break_position, max_chars - str_len); - } - } - else - { - append_length = Math::Min(chars_read_last, max_chars - str_len); - } - - if (append_length > 0) - { - char_buffer[append_length] = '\0'; - str.Append(char_buffer); - } - } - while (!EOS() && line_break_position < 0); - - // If null-terminator was found make sure stream is positioned at the next - // byte after line end - if (line_break_position >= 0) - { - // CHECKME: what if stream does not support seek? need an algorythm fork for that - // the seek offset should be negative - _stream->Seek(line_break_position - chars_read_last + 1 /* beyond line feed */); - } - - str.TrimRight('\r'); // skip carriage-return, if any - return str; +String TextStreamReader::ReadLine() { + // TODO + // Probably it is possible to group Stream::ReadString with this, + // both use similar algorythm, difference is only in terminator chars + + if (!_stream) { + return ""; + } + + String str; + int chars_read_last = 0; + int line_break_position = -1; + // Read a chunk of memory to buffer and seek for null-terminator, + // if not found, repeat until EOS + const int single_chunk_length = 3000; + const int max_chars = 5000000; + char char_buffer[single_chunk_length + 1]; + do { + chars_read_last = _stream->Read(char_buffer, single_chunk_length); + char *seek_ptr = char_buffer; + int c; + for (c = 0; c < chars_read_last && *seek_ptr != '\n'; ++c, ++seek_ptr); + + int append_length = 0; + int str_len = str.GetLength(); + if (c < chars_read_last && *seek_ptr == '\n') { + line_break_position = seek_ptr - char_buffer; + if (str_len < max_chars) { + append_length = Math::Min(line_break_position, max_chars - str_len); + } + } else { + append_length = Math::Min(chars_read_last, max_chars - str_len); + } + + if (append_length > 0) { + char_buffer[append_length] = '\0'; + str.Append(char_buffer); + } + } while (!EOS() && line_break_position < 0); + + // If null-terminator was found make sure stream is positioned at the next + // byte after line end + if (line_break_position >= 0) { + // CHECKME: what if stream does not support seek? need an algorythm fork for that + // the seek offset should be negative + _stream->Seek(line_break_position - chars_read_last + 1 /* beyond line feed */); + } + + str.TrimRight('\r'); // skip carriage-return, if any + return str; } -String TextStreamReader::ReadAll() -{ - if (_stream) - { - soff_t len = _stream->GetLength() - _stream->GetPosition(); - return ReadString(len > SIZE_MAX ? SIZE_MAX : (size_t)len); - } - return ""; +String TextStreamReader::ReadAll() { + if (_stream) { + soff_t len = _stream->GetLength() - _stream->GetPosition(); + return ReadString(len > SIZE_MAX ? SIZE_MAX : (size_t)len); + } + return ""; } } // namespace Common diff --git a/engines/ags/shared/util/textstreamreader.h b/engines/ags/shared/util/textstreamreader.h index 74859a913b7d..943ccf4d5582 100644 --- a/engines/ags/shared/util/textstreamreader.h +++ b/engines/ags/shared/util/textstreamreader.h @@ -31,38 +31,35 @@ #include "util/textreader.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class Stream; -class TextStreamReader : public TextReader -{ +class TextStreamReader : public TextReader { public: - // TODO: use shared ptr - TextStreamReader(Stream *stream); - ~TextStreamReader() override; + // TODO: use shared ptr + TextStreamReader(Stream *stream); + ~TextStreamReader() override; - bool IsValid() const override; - const Stream *GetStream() const; - // TODO: use shared ptr instead - void ReleaseStream(); + bool IsValid() const override; + const Stream *GetStream() const; + // TODO: use shared ptr instead + void ReleaseStream(); - bool EOS() const; + bool EOS() const; - // Read single character - char ReadChar() override; - // Read defined number of characters - String ReadString(size_t length) override; - // Read till line break - String ReadLine() override; - // Read till end of available data - String ReadAll() override; + // Read single character + char ReadChar() override; + // Read defined number of characters + String ReadString(size_t length) override; + // Read till line break + String ReadLine() override; + // Read till end of available data + String ReadAll() override; private: - Stream *_stream; + Stream *_stream; }; } // namespace Common diff --git a/engines/ags/shared/util/textstreamwriter.cpp b/engines/ags/shared/util/textstreamwriter.cpp index 927788cf9158..edf2f8588e5d 100644 --- a/engines/ags/shared/util/textstreamwriter.cpp +++ b/engines/ags/shared/util/textstreamwriter.cpp @@ -26,10 +26,8 @@ #include "util/textstreamwriter.h" #include "util/stream.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { #if AGS_PLATFORM_OS_WINDOWS static const char Endl[2] = {'\r', '\n'}; @@ -39,90 +37,75 @@ static const char Endl[1] = {'\n'}; TextStreamWriter::TextStreamWriter(Stream *stream) - : _stream(stream) -{ + : _stream(stream) { } -TextStreamWriter::~TextStreamWriter() -{ - // TODO use shared ptr - delete _stream; +TextStreamWriter::~TextStreamWriter() { + // TODO use shared ptr + delete _stream; } -bool TextStreamWriter::IsValid() const -{ - return _stream && _stream->CanWrite(); +bool TextStreamWriter::IsValid() const { + return _stream && _stream->CanWrite(); } -const Stream *TextStreamWriter::GetStream() const -{ - return _stream; +const Stream *TextStreamWriter::GetStream() const { + return _stream; } -void TextStreamWriter::ReleaseStream() -{ - _stream = nullptr; +void TextStreamWriter::ReleaseStream() { + _stream = nullptr; } -bool TextStreamWriter::EOS() const -{ - return _stream ? _stream->EOS() : true; +bool TextStreamWriter::EOS() const { + return _stream ? _stream->EOS() : true; } -void TextStreamWriter::WriteChar(char c) -{ - if (_stream) - { - _stream->WriteByte(c); - } +void TextStreamWriter::WriteChar(char c) { + if (_stream) { + _stream->WriteByte(c); + } } -void TextStreamWriter::WriteString(const String &str) -{ - if (_stream) - { - // TODO: replace line-feed characters in string with platform-specific line break - _stream->Write(str.GetCStr(), str.GetLength()); - } +void TextStreamWriter::WriteString(const String &str) { + if (_stream) { + // TODO: replace line-feed characters in string with platform-specific line break + _stream->Write(str.GetCStr(), str.GetLength()); + } } -void TextStreamWriter::WriteLine(const String &str) -{ - if (!_stream) - { - return; - } +void TextStreamWriter::WriteLine(const String &str) { + if (!_stream) { + return; + } - // TODO: replace line-feed characters in string with platform-specific line break - _stream->Write(str.GetCStr(), str.GetLength()); - _stream->Write(Endl, sizeof(Endl)); + // TODO: replace line-feed characters in string with platform-specific line break + _stream->Write(str.GetCStr(), str.GetLength()); + _stream->Write(Endl, sizeof(Endl)); } -void TextStreamWriter::WriteFormat(const char *fmt, ...) -{ - if (!_stream) - { - return; - } - - // TODO: replace line-feed characters in format string with platform-specific line break - - va_list argptr; - va_start(argptr, fmt); - int need_length = vsnprintf(nullptr, 0, fmt, argptr); - va_start(argptr, fmt); // Reset argptr - char *buffer = new char[need_length + 1]; - vsprintf(buffer, fmt, argptr); - va_end(argptr); - - _stream->Write(buffer, need_length); - delete [] buffer; +void TextStreamWriter::WriteFormat(const char *fmt, ...) { + if (!_stream) { + return; + } + + // TODO: replace line-feed characters in format string with platform-specific line break + + va_list argptr; + va_start(argptr, fmt); + int need_length = vsnprintf(nullptr, 0, fmt, argptr); + va_start(argptr, fmt); // Reset argptr + char *buffer = new char[need_length + 1]; + vsprintf(buffer, fmt, argptr); + va_end(argptr); + + _stream->Write(buffer, need_length); + delete [] buffer; } -void TextStreamWriter::WriteLineBreak() -{ - if (_stream) - _stream->Write(Endl, sizeof(Endl)); +void TextStreamWriter::WriteLineBreak() { + if (_stream) + _stream->Write(Endl, sizeof(Endl)); } } // namespace Common diff --git a/engines/ags/shared/util/textstreamwriter.h b/engines/ags/shared/util/textstreamwriter.h index 58ce4634b883..3ece10881db8 100644 --- a/engines/ags/shared/util/textstreamwriter.h +++ b/engines/ags/shared/util/textstreamwriter.h @@ -31,39 +31,36 @@ #include "util/textwriter.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { class Stream; -class TextStreamWriter : public TextWriter -{ +class TextStreamWriter : public TextWriter { public: - // TODO: use shared ptr - TextStreamWriter(Stream *stream); - ~TextStreamWriter() override; + // TODO: use shared ptr + TextStreamWriter(Stream *stream); + ~TextStreamWriter() override; - bool IsValid() const override; - const Stream *GetStream() const; - // TODO: use shared ptr instead - void ReleaseStream(); + bool IsValid() const override; + const Stream *GetStream() const; + // TODO: use shared ptr instead + void ReleaseStream(); - bool EOS() const; + bool EOS() const; - // Write single character - void WriteChar(char c) override; - // Write string as a plain text (without null-terminator) - void WriteString(const String &str) override; - // Write string and add line break at the end - void WriteLine(const String &str) override; - // Write formatted string (see *printf) - void WriteFormat(const char *fmt, ...) override; - void WriteLineBreak() override; + // Write single character + void WriteChar(char c) override; + // Write string as a plain text (without null-terminator) + void WriteString(const String &str) override; + // Write string and add line break at the end + void WriteLine(const String &str) override; + // Write formatted string (see *printf) + void WriteFormat(const char *fmt, ...) override; + void WriteLineBreak() override; private: - Stream *_stream; + Stream *_stream; }; } // namespace Common diff --git a/engines/ags/shared/util/textwriter.h b/engines/ags/shared/util/textwriter.h index 9f99a8f08e81..64b4f292dfb4 100644 --- a/engines/ags/shared/util/textwriter.h +++ b/engines/ags/shared/util/textwriter.h @@ -31,27 +31,24 @@ #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { -class TextWriter -{ +class TextWriter { public: - virtual ~TextWriter() = default; - - virtual bool IsValid() const = 0; - - // Write single character - virtual void WriteChar(char c) = 0; - // Write string as a plain text (without null-terminator) - virtual void WriteString(const String &str) = 0; - // Write string and add line break at the end - virtual void WriteLine(const String &str) = 0; - // Write formatted string (see *printf) - virtual void WriteFormat(const char *fmt, ...) = 0; - virtual void WriteLineBreak() = 0; + virtual ~TextWriter() = default; + + virtual bool IsValid() const = 0; + + // Write single character + virtual void WriteChar(char c) = 0; + // Write string as a plain text (without null-terminator) + virtual void WriteString(const String &str) = 0; + // Write string and add line break at the end + virtual void WriteLine(const String &str) = 0; + // Write formatted string (see *printf) + virtual void WriteFormat(const char *fmt, ...) = 0; + virtual void WriteLineBreak() = 0; }; } // namespace Common diff --git a/engines/ags/shared/util/version.cpp b/engines/ags/shared/util/version.cpp index ab14ea0c7ab0..613ab12a3a49 100644 --- a/engines/ags/shared/util/version.cpp +++ b/engines/ags/shared/util/version.cpp @@ -23,135 +23,113 @@ #include #include "util/version.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { const Version Version::LastOldFormatVersion(3, 2, 2, 1120); Version::Version() - : Major(0) - , Minor(0) - , Release(0) - , Revision(0) -{ - MakeString(); + : Major(0) + , Minor(0) + , Release(0) + , Revision(0) { + MakeString(); } Version::Version(int32_t major, int32_t minor, int32_t release) - : Major(major) - , Minor(minor) - , Release(release) - , Revision(0) -{ - MakeString(); + : Major(major) + , Minor(minor) + , Release(release) + , Revision(0) { + MakeString(); } Version::Version(int32_t major, int32_t minor, int32_t release, int32_t revision) - : Major(major) - , Minor(minor) - , Release(release) - , Revision(revision) -{ - MakeString(); + : Major(major) + , Minor(minor) + , Release(release) + , Revision(revision) { + MakeString(); } Version::Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special) - : Major(major) - , Minor(minor) - , Release(release) - , Revision(revision) - , Special(special) -{ - MakeString(); + : Major(major) + , Minor(minor) + , Release(release) + , Revision(revision) + , Special(special) { + MakeString(); } Version::Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special, const String &build_info) - : Major(major) - , Minor(minor) - , Release(release) - , Revision(revision) - , Special(special) - , BuildInfo(build_info) -{ - MakeString(); + : Major(major) + , Minor(minor) + , Release(release) + , Revision(revision) + , Special(special) + , BuildInfo(build_info) { + MakeString(); } Version::Version(const String &version_string) - : Major(0) - , Minor(0) - , Release(0) - , Revision(0) -{ - SetFromString(version_string); + : Major(0) + , Minor(0) + , Release(0) + , Revision(0) { + SetFromString(version_string); } -void Version::SetFromString(const String &version_string) -{ - Major = version_string.LeftSection('.').ToInt(); - String second_section = version_string.Section('.', 1, 1); - Minor = second_section.ToInt(); - String third_section = version_string.Section('.', 2, 2); - String fourth_section = version_string.Section('.', 3, 3); - String revision_section; - - bool old_version_format = Major < 3 || fourth_section.IsEmpty(); - if (old_version_format) - { - if (second_section.GetLength() > 1) - { - Release = Minor % 10; - Minor /= 10; - } - else - { - Release = 0; - } - revision_section = third_section; - } - else - { - Release = third_section.ToInt(); - revision_section = fourth_section; - } - - int revision_length = 0; - if (!revision_section.IsEmpty()) - { - const char *seek_ptr = revision_section.GetCStr(); - const char *end_ptr = revision_section.GetCStr() + revision_section.GetLength(); - while (seek_ptr != end_ptr) - { - if (!isdigit(*seek_ptr)) - { - break; - } - revision_length++; - seek_ptr++; - } - } - - Revision = revision_section.Left(revision_length).ToInt(); - // In old version format a special tag was added right after revision digits. - // In new version format a special tag is separated from revision digits with single space char. - Special = revision_section.Mid(revision_length + (old_version_format ? 0 : 1)); - - MakeString(); +void Version::SetFromString(const String &version_string) { + Major = version_string.LeftSection('.').ToInt(); + String second_section = version_string.Section('.', 1, 1); + Minor = second_section.ToInt(); + String third_section = version_string.Section('.', 2, 2); + String fourth_section = version_string.Section('.', 3, 3); + String revision_section; + + bool old_version_format = Major < 3 || fourth_section.IsEmpty(); + if (old_version_format) { + if (second_section.GetLength() > 1) { + Release = Minor % 10; + Minor /= 10; + } else { + Release = 0; + } + revision_section = third_section; + } else { + Release = third_section.ToInt(); + revision_section = fourth_section; + } + + int revision_length = 0; + if (!revision_section.IsEmpty()) { + const char *seek_ptr = revision_section.GetCStr(); + const char *end_ptr = revision_section.GetCStr() + revision_section.GetLength(); + while (seek_ptr != end_ptr) { + if (!isdigit(*seek_ptr)) { + break; + } + revision_length++; + seek_ptr++; + } + } + + Revision = revision_section.Left(revision_length).ToInt(); + // In old version format a special tag was added right after revision digits. + // In new version format a special tag is separated from revision digits with single space char. + Special = revision_section.Mid(revision_length + (old_version_format ? 0 : 1)); + + MakeString(); } -void Version::MakeString() -{ - if (Special.IsEmpty()) - { - LongString.Format("%d.%d.%d.%d", Major, Minor, Release, Revision); - } - else - { - LongString.Format("%d.%d.%d.%d %s", Major, Minor, Release, Revision, Special.GetCStr()); - } - BackwardCompatibleString.Format("%d.%02d.%d%s", Major, Minor * 10 + Release, Revision, Special.GetCStr()); - ShortString.Format("%d.%d", Major, Minor); +void Version::MakeString() { + if (Special.IsEmpty()) { + LongString.Format("%d.%d.%d.%d", Major, Minor, Release, Revision); + } else { + LongString.Format("%d.%d.%d.%d %s", Major, Minor, Release, Revision, Special.GetCStr()); + } + BackwardCompatibleString.Format("%d.%02d.%d%s", Major, Minor * 10 + Release, Revision, Special.GetCStr()); + ShortString.Format("%d.%d", Major, Minor); } } // namespace Common diff --git a/engines/ags/shared/util/version.h b/engines/ags/shared/util/version.h index 09cd6c362457..865280e0fd90 100644 --- a/engines/ags/shared/util/version.h +++ b/engines/ags/shared/util/version.h @@ -31,85 +31,73 @@ #include "util/string.h" -namespace AGS -{ -namespace Common -{ +namespace AGS { +namespace Common { using Common::String; -struct Version -{ - int32_t Major; - int32_t Minor; - int32_t Release; - int32_t Revision; - String Special; - String BuildInfo; - - String LongString; - String ShortString; - String BackwardCompatibleString; - - // Last engine version, using different version format than AGS Editor (3.22.1120 / 3.2.2.1120) - static const Version LastOldFormatVersion; - - Version(); - Version(int32_t major, int32_t minor, int32_t release); - Version(int32_t major, int32_t minor, int32_t release, int32_t revision); - Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special); - Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special, const String &build_info); - Version(const String &version_string); - - inline int32_t AsNumber() const - { - return Major * 10000 + Minor * 100 + Release; - } - - inline int64_t AsLongNumber() const - { - return (int64_t)Major * 100000000L + (int64_t)Minor * 1000000L + (int64_t)Release * 10000L + Revision; - } - - inline int32_t AsSmallNumber() const - { - return Major * 100 + Minor; - } - - void SetFromString(const String &version_string); - - inline bool operator < (const Version &other) const - { - return AsLongNumber() < other.AsLongNumber(); - } - - inline bool operator <= (const Version &other) const - { - return AsLongNumber() <= other.AsLongNumber(); - } - - inline bool operator > (const Version &other) const - { - return AsLongNumber() > other.AsLongNumber(); - } - - inline bool operator >= (const Version &other) const - { - return AsLongNumber() >= other.AsLongNumber(); - } - - inline bool operator == (const Version &other) const - { - return AsLongNumber() == other.AsLongNumber(); - } - - inline bool operator != (const Version &other) const - { - return AsLongNumber() != other.AsLongNumber(); - } +struct Version { + int32_t Major; + int32_t Minor; + int32_t Release; + int32_t Revision; + String Special; + String BuildInfo; + + String LongString; + String ShortString; + String BackwardCompatibleString; + + // Last engine version, using different version format than AGS Editor (3.22.1120 / 3.2.2.1120) + static const Version LastOldFormatVersion; + + Version(); + Version(int32_t major, int32_t minor, int32_t release); + Version(int32_t major, int32_t minor, int32_t release, int32_t revision); + Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special); + Version(int32_t major, int32_t minor, int32_t release, int32_t revision, const String &special, const String &build_info); + Version(const String &version_string); + + inline int32_t AsNumber() const { + return Major * 10000 + Minor * 100 + Release; + } + + inline int64_t AsLongNumber() const { + return (int64_t)Major * 100000000L + (int64_t)Minor * 1000000L + (int64_t)Release * 10000L + Revision; + } + + inline int32_t AsSmallNumber() const { + return Major * 100 + Minor; + } + + void SetFromString(const String &version_string); + + inline bool operator < (const Version &other) const { + return AsLongNumber() < other.AsLongNumber(); + } + + inline bool operator <= (const Version &other) const { + return AsLongNumber() <= other.AsLongNumber(); + } + + inline bool operator > (const Version &other) const { + return AsLongNumber() > other.AsLongNumber(); + } + + inline bool operator >= (const Version &other) const { + return AsLongNumber() >= other.AsLongNumber(); + } + + inline bool operator == (const Version &other) const { + return AsLongNumber() == other.AsLongNumber(); + } + + inline bool operator != (const Version &other) const { + return AsLongNumber() != other.AsLongNumber(); + } private: - void MakeString(); + void MakeString(); }; } // namespace Common diff --git a/engines/ags/shared/util/wgt2allg.cpp b/engines/ags/shared/util/wgt2allg.cpp index 0dff3610a3ff..436481eb394a 100644 --- a/engines/ags/shared/util/wgt2allg.cpp +++ b/engines/ags/shared/util/wgt2allg.cpp @@ -32,191 +32,178 @@ extern "C" { #endif - void wsetrgb(int coll, int r, int g, int b, color * pall) - { - pall[coll].r = r; - pall[coll].g = g; - pall[coll].b = b; - } - - void wcolrotate(unsigned char start, unsigned char finish, int dir, color * pall) - { - int jj; - if (dir == 0) { - // rotate left - color tempp = pall[start]; - - for (jj = start; jj < finish; jj++) - pall[jj] = pall[jj + 1]; - - pall[finish] = tempp; - } - else { - // rotate right - color tempp = pall[finish]; - - for (jj = finish - 1; jj >= start; jj--) - pall[jj + 1] = pall[jj]; - - pall[start] = tempp; - } - } - - Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2) - { - Bitmap *tempbitm; - int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; - - if (twid < 1) - twid = 1; - - if (thit < 1) - thit = 1; - - tempbitm = BitmapHelper::CreateBitmap(twid, thit); - - if (tempbitm == nullptr) - return nullptr; - - tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); - return tempbitm; - } - - int wloadsprites(color * pall, char *filnam, Bitmap ** sarray, int strt, int eend) - { - int vers; - char buff[20]; - int numspri = 0, vv, hh, wdd, htt; - - Stream *in = Common::AssetManager::OpenAsset(filnam); - if (in == nullptr) - return -1; - - vers = in->ReadInt16(); - in->ReadArray(&buff[0], 13, 1); - for (vv = 0; vv < 256; vv++) // there's a filler byte - in->ReadArray(&pall[vv], 3, 1); - - if (vers > 4) - return -1; - - if (vers == 4) - numspri = in->ReadInt16(); - else { - numspri = in->ReadInt16(); - if ((numspri < 2) || (numspri > 200)) - numspri = 200; - } - - for (vv = strt; vv <= eend; vv++) - sarray[vv] = nullptr; - - for (vv = 0; vv <= numspri; vv++) { - int coldep = in->ReadInt16(); - - if (coldep == 0) { - sarray[vv] = nullptr; - if (in->EOS()) - break; - - continue; - } - - if (in->EOS()) - break; - - if (vv > eend) - break; - - wdd = in->ReadInt16(); - htt = in->ReadInt16(); - if (vv < strt) { - in->Seek(wdd * htt); - continue; - } - sarray[vv] = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); - - if (sarray[vv] == nullptr) { - delete in; - return -1; - } - - for (hh = 0; hh < htt; hh++) - in->ReadArray(&sarray[vv]->GetScanLineForWriting(hh)[0], wdd * coldep, 1); - } - delete in; - return 0; - } - - void wputblock(Common::Bitmap *ds, int xx, int yy, Bitmap *bll, int xray) - { - if (xray) - ds->Blit(bll, xx, yy, Common::kBitmap_Transparency); - else - ds->Blit(bll, 0, 0, xx, yy, bll->GetWidth(), bll->GetHeight()); - } - - Bitmap wputblock_wrapper; // [IKM] argh! :[ - void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray) - { +void wsetrgb(int coll, int r, int g, int b, color *pall) { + pall[coll].r = r; + pall[coll].g = g; + pall[coll].b = b; +} + +void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall) { + int jj; + if (dir == 0) { + // rotate left + color tempp = pall[start]; + + for (jj = start; jj < finish; jj++) + pall[jj] = pall[jj + 1]; + + pall[finish] = tempp; + } else { + // rotate right + color tempp = pall[finish]; + + for (jj = finish - 1; jj >= start; jj--) + pall[jj + 1] = pall[jj]; + + pall[start] = tempp; + } +} + +Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2) { + Bitmap *tempbitm; + int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; + + if (twid < 1) + twid = 1; + + if (thit < 1) + thit = 1; + + tempbitm = BitmapHelper::CreateBitmap(twid, thit); + + if (tempbitm == nullptr) + return nullptr; + + tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); + return tempbitm; +} + +int wloadsprites(color *pall, char *filnam, Bitmap **sarray, int strt, int eend) { + int vers; + char buff[20]; + int numspri = 0, vv, hh, wdd, htt; + + Stream *in = Common::AssetManager::OpenAsset(filnam); + if (in == nullptr) + return -1; + + vers = in->ReadInt16(); + in->ReadArray(&buff[0], 13, 1); + for (vv = 0; vv < 256; vv++) // there's a filler byte + in->ReadArray(&pall[vv], 3, 1); + + if (vers > 4) + return -1; + + if (vers == 4) + numspri = in->ReadInt16(); + else { + numspri = in->ReadInt16(); + if ((numspri < 2) || (numspri > 200)) + numspri = 200; + } + + for (vv = strt; vv <= eend; vv++) + sarray[vv] = nullptr; + + for (vv = 0; vv <= numspri; vv++) { + int coldep = in->ReadInt16(); + + if (coldep == 0) { + sarray[vv] = nullptr; + if (in->EOS()) + break; + + continue; + } + + if (in->EOS()) + break; + + if (vv > eend) + break; + + wdd = in->ReadInt16(); + htt = in->ReadInt16(); + if (vv < strt) { + in->Seek(wdd * htt); + continue; + } + sarray[vv] = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); + + if (sarray[vv] == nullptr) { + delete in; + return -1; + } + + for (hh = 0; hh < htt; hh++) + in->ReadArray(&sarray[vv]->GetScanLineForWriting(hh)[0], wdd * coldep, 1); + } + delete in; + return 0; +} + +void wputblock(Common::Bitmap *ds, int xx, int yy, Bitmap *bll, int xray) { + if (xray) + ds->Blit(bll, xx, yy, Common::kBitmap_Transparency); + else + ds->Blit(bll, 0, 0, xx, yy, bll->GetWidth(), bll->GetHeight()); +} + +Bitmap wputblock_wrapper; // [IKM] argh! :[ +void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray) { wputblock_wrapper.WrapAllegroBitmap(bll, true); - if (xray) - ds->Blit(&wputblock_wrapper, xx, yy, Common::kBitmap_Transparency); - else - ds->Blit(&wputblock_wrapper, 0, 0, xx, yy, wputblock_wrapper.GetWidth(), wputblock_wrapper.GetHeight()); - } - - const int col_lookups[32] = { - 0x000000, 0x0000A0, 0x00A000, 0x00A0A0, 0xA00000, // 4 - 0xA000A0, 0xA05000, 0xA0A0A0, 0x505050, 0x5050FF, 0x50FF50, 0x50FFFF, // 11 - 0xFF5050, 0xFF50FF, 0xFFFF50, 0xFFFFFF, 0x000000, 0x101010, 0x202020, // 18 - 0x303030, 0x404040, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, // 25 - 0xA0A0A0, 0xB0B0B0, 0xC0C0C0, 0xD0D0D0, 0xE0E0E0, 0xF0F0F0 - }; - - int __wremap_keep_transparent = 1; - - void wremap(color * pal1, Bitmap *picc, color * pal2) - { - int jj; - unsigned char color_mapped_table[256]; - - for (jj = 0; jj < 256; jj++) - { - if ((pal1[jj].r == 0) && (pal1[jj].g == 0) && (pal1[jj].b == 0)) - { - color_mapped_table[jj] = 0; - } - else - { - color_mapped_table[jj] = bestfit_color(pal2, pal1[jj].r, pal1[jj].g, pal1[jj].b); - } - } - - if (__wremap_keep_transparent > 0) { - // keep transparency - color_mapped_table[0] = 0; - // any other pixels which are being mapped to 0, map to 16 instead - for (jj = 1; jj < 256; jj++) { - if (color_mapped_table[jj] == 0) - color_mapped_table[jj] = 16; - } - } - - int pic_size = picc->GetWidth() * picc->GetHeight(); - for (jj = 0; jj < pic_size; jj++) { - int xxl = jj % (picc->GetWidth()), yyl = jj / (picc->GetWidth()); - int rr = picc->GetPixel(xxl, yyl); - picc->PutPixel(xxl, yyl, color_mapped_table[rr]); - } - } - - void wremapall(color * pal1, Bitmap *picc, color * pal2) - { - __wremap_keep_transparent--; - wremap(pal1, picc, pal2); - __wremap_keep_transparent++; - } + if (xray) + ds->Blit(&wputblock_wrapper, xx, yy, Common::kBitmap_Transparency); + else + ds->Blit(&wputblock_wrapper, 0, 0, xx, yy, wputblock_wrapper.GetWidth(), wputblock_wrapper.GetHeight()); +} + +const int col_lookups[32] = { + 0x000000, 0x0000A0, 0x00A000, 0x00A0A0, 0xA00000, // 4 + 0xA000A0, 0xA05000, 0xA0A0A0, 0x505050, 0x5050FF, 0x50FF50, 0x50FFFF, // 11 + 0xFF5050, 0xFF50FF, 0xFFFF50, 0xFFFFFF, 0x000000, 0x101010, 0x202020, // 18 + 0x303030, 0x404040, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, // 25 + 0xA0A0A0, 0xB0B0B0, 0xC0C0C0, 0xD0D0D0, 0xE0E0E0, 0xF0F0F0 +}; + +int __wremap_keep_transparent = 1; + +void wremap(color *pal1, Bitmap *picc, color *pal2) { + int jj; + unsigned char color_mapped_table[256]; + + for (jj = 0; jj < 256; jj++) { + if ((pal1[jj].r == 0) && (pal1[jj].g == 0) && (pal1[jj].b == 0)) { + color_mapped_table[jj] = 0; + } else { + color_mapped_table[jj] = bestfit_color(pal2, pal1[jj].r, pal1[jj].g, pal1[jj].b); + } + } + + if (__wremap_keep_transparent > 0) { + // keep transparency + color_mapped_table[0] = 0; + // any other pixels which are being mapped to 0, map to 16 instead + for (jj = 1; jj < 256; jj++) { + if (color_mapped_table[jj] == 0) + color_mapped_table[jj] = 16; + } + } + + int pic_size = picc->GetWidth() * picc->GetHeight(); + for (jj = 0; jj < pic_size; jj++) { + int xxl = jj % (picc->GetWidth()), yyl = jj / (picc->GetWidth()); + int rr = picc->GetPixel(xxl, yyl); + picc->PutPixel(xxl, yyl, color_mapped_table[rr]); + } +} + +void wremapall(color *pal1, Bitmap *picc, color *pal2) { + __wremap_keep_transparent--; + wremap(pal1, picc, pal2); + __wremap_keep_transparent++; +} #ifdef __cplusplus diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index ef8a87f62768..22ce298acbab 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -37,7 +37,11 @@ #include "allegro.h" -namespace AGS { namespace Common { class Bitmap; }} +namespace AGS { +namespace Common { +class Bitmap; +} +} using namespace AGS; // FIXME later @@ -56,24 +60,24 @@ extern void __my_setcolor(int *ctset, int newcol, int wantColDep); extern "C" { #endif - - extern void wsetrgb(int coll, int r, int g, int b, color * pall); - extern void wcolrotate(unsigned char start, unsigned char finish, int dir, color * pall); - extern Common::Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2); +extern void wsetrgb(int coll, int r, int g, int b, color *pall); +extern void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall); + +extern Common::Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2); - extern int wloadsprites(color * pall, char *filnam, Common::Bitmap ** sarray, int strt, int eend); +extern int wloadsprites(color *pall, char *filnam, Common::Bitmap **sarray, int strt, int eend); - extern void wputblock(Common::Bitmap *ds, int xx, int yy, Common::Bitmap *bll, int xray); - // CHECKME: temporary solution for plugin system - extern void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray); - extern const int col_lookups[32]; +extern void wputblock(Common::Bitmap *ds, int xx, int yy, Common::Bitmap *bll, int xray); +// CHECKME: temporary solution for plugin system +extern void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray); +extern const int col_lookups[32]; - //extern void wsetcolor(int nval); +//extern void wsetcolor(int nval); - extern int __wremap_keep_transparent; - extern void wremap(color * pal1, Common::Bitmap *picc, color * pal2); - extern void wremapall(color * pal1, Common::Bitmap *picc, color * pal2); +extern int __wremap_keep_transparent; +extern void wremap(color *pal1, Common::Bitmap *picc, color *pal2); +extern void wremapall(color *pal1, Common::Bitmap *picc, color *pal2); #ifdef __cplusplus } diff --git a/engines/ags/std/list.h b/engines/ags/std/list.h index 5694dfc64aa3..a4eacaf8727e 100644 --- a/engines/ags/std/list.h +++ b/engines/ags/std/list.h @@ -58,7 +58,7 @@ class list : public Common::List { }; public: typename Common::List::iterator insert(typename Common::List::iterator pos, - const T &element) { + const T &element) { Common::List::insert(pos, element); return pos; } diff --git a/engines/ags/std/map.h b/engines/ags/std/map.h index 5899948db30f..028cb7b71e3b 100644 --- a/engines/ags/std/map.h +++ b/engines/ags/std/map.h @@ -30,7 +30,7 @@ namespace AGS3 { namespace std { template, -class EqualFunc = Common::EqualTo > + class EqualFunc = Common::EqualTo > class map : public Common::HashMap { public: void insert(pair elem) { @@ -39,7 +39,7 @@ class map : public Common::HashMap { }; template, - class EqualFunc = Common::EqualTo > + class EqualFunc = Common::EqualTo > class unordered_map : public Common::HashMap { public: void insert(pair elem) { diff --git a/engines/ags/std/set.h b/engines/ags/std/set.h index 30b39c0421e6..18d30e2bdb4a 100644 --- a/engines/ags/std/set.h +++ b/engines/ags/std/set.h @@ -49,10 +49,18 @@ class set { typedef T *iterator; typedef const T *const_iterator; - iterator begin() { return _items.begin(); } - iterator end() { return _items.end(); } - const_iterator begin() const { return _items.begin(); } - const_iterator end() const { return _items.end(); } + iterator begin() { + return _items.begin(); + } + iterator end() { + return _items.end(); + } + const_iterator begin() const { + return _items.begin(); + } + const_iterator end() const { + return _items.end(); + } /** * Clear the set diff --git a/engines/ags/std/vector.h b/engines/ags/std/vector.h index 745fb20bd64d..87814229c63a 100644 --- a/engines/ags/std/vector.h +++ b/engines/ags/std/vector.h @@ -102,7 +102,7 @@ class vector : public Common::Array { } typename Common::Array::iterator erase(typename Common::Array::iterator first, - typename Common::Array::iterator last) { + typename Common::Array::iterator last) { Common::copy(last, this->_storage + this->_size, first); int count = (last - first); diff --git a/engines/ags/stubs/allegro/base.h b/engines/ags/stubs/allegro/base.h index cc08b5b518f0..e5cf5bb16876 100644 --- a/engines/ags/stubs/allegro/base.h +++ b/engines/ags/stubs/allegro/base.h @@ -37,8 +37,8 @@ namespace AGS3 { /* Returns the median of x, y, z */ #define MID(x,y,z) ((x) > (y) ? ((y) > (z) ? (y) : ((x) > (z) ? \ - (z) : (x))) : ((y) > (z) ? ((z) > (x) ? (z) : \ - (x)): (y))) + (z) : (x))) : ((y) > (z) ? ((z) > (x) ? (z) : \ + (x)): (y))) #define AL_ID MKTAG diff --git a/engines/ags/stubs/allegro/color.h b/engines/ags/stubs/allegro/color.h index 0785bd23cd83..e4655628508b 100644 --- a/engines/ags/stubs/allegro/color.h +++ b/engines/ags/stubs/allegro/color.h @@ -28,7 +28,7 @@ namespace AGS3 { -#include "common/pack-start.h" // START STRUCT PACKING +#include "common/pack-start.h" // START STRUCT PACKING struct color { byte r, g, b; @@ -37,7 +37,7 @@ struct color { typedef color RGB; typedef color PALETTE[256]; -#include "common/pack-end.h" // END STRUCT PACKING +#include "common/pack-end.h" // END STRUCT PACKING //define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) diff --git a/engines/ags/stubs/allegro/digi.h b/engines/ags/stubs/allegro/digi.h index 78f41cadee99..0dc8d44adee9 100644 --- a/engines/ags/stubs/allegro/digi.h +++ b/engines/ags/stubs/allegro/digi.h @@ -123,12 +123,12 @@ AL_ARRAY(_DRIVER_INFO, _digi_driver_list); /* macros for constructing the driver lists */ #define BEGIN_DIGI_DRIVER_LIST \ - _DRIVER_INFO _digi_driver_list[] = \ - { + _DRIVER_INFO _digi_driver_list[] = \ + { #define END_DIGI_DRIVER_LIST \ - { 0, nullptr, 0 } \ - }; + { 0, nullptr, 0 } \ + }; AL_VAR(DIGI_DRIVER *, digi_driver); diff --git a/engines/ags/stubs/allegro/fixed.cpp b/engines/ags/stubs/allegro/fixed.cpp index a6923e58ec04..09d0343a7d16 100644 --- a/engines/ags/stubs/allegro/fixed.cpp +++ b/engines/ags/stubs/allegro/fixed.cpp @@ -29,63 +29,57 @@ fixed fixtorad_r; fixed radtofix_r; fixed ftofix(double x) { - if (x > 32767.0) { - *allegro_errno = ERANGE; - return 0x7FFFFFFF; - } + if (x > 32767.0) { + *allegro_errno = ERANGE; + return 0x7FFFFFFF; + } - if (x < -32767.0) { - *allegro_errno = ERANGE; - return (fixed)-0x7FFFFFFF; - } + if (x < -32767.0) { + *allegro_errno = ERANGE; + return (fixed) - 0x7FFFFFFF; + } - return (fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); + return (fixed)(x * 65536.0 + (x < 0 ? -0.5 : 0.5)); } double fixtof(fixed x) { - return (double)x / 65536.0; + return (double)x / 65536.0; } fixed fixadd(fixed x, fixed y) { - fixed result = x + y; - - if (result >= 0) { - if ((x < 0) && (y < 0)) { - *allegro_errno = ERANGE; - return (fixed)-0x7FFFFFFF; - } - else - return result; - } - else { - if ((x > 0) && (y > 0)) { - *allegro_errno = ERANGE; - return 0x7FFFFFFF; - } - else - return result; - } + fixed result = x + y; + + if (result >= 0) { + if ((x < 0) && (y < 0)) { + *allegro_errno = ERANGE; + return (fixed) - 0x7FFFFFFF; + } else + return result; + } else { + if ((x > 0) && (y > 0)) { + *allegro_errno = ERANGE; + return 0x7FFFFFFF; + } else + return result; + } } fixed fixsub(fixed x, fixed y) { - fixed result = x - y; - - if (result >= 0) { - if ((x < 0) && (y > 0)) { - *allegro_errno = ERANGE; - return (fixed)-0x7FFFFFFF; - } - else - return result; - } - else { - if ((x > 0) && (y < 0)) { - *allegro_errno = ERANGE; - return 0x7FFFFFFF; - } - else - return result; - } + fixed result = x - y; + + if (result >= 0) { + if ((x < 0) && (y > 0)) { + *allegro_errno = ERANGE; + return (fixed) - 0x7FFFFFFF; + } else + return result; + } else { + if ((x > 0) && (y < 0)) { + *allegro_errno = ERANGE; + return 0x7FFFFFFF; + } else + return result; + } } fixed fixmul(fixed x, fixed y) { diff --git a/engines/ags/stubs/allegro/gfx.h b/engines/ags/stubs/allegro/gfx.h index a3e15eaa8c17..a6e71afccb7f 100644 --- a/engines/ags/stubs/allegro/gfx.h +++ b/engines/ags/stubs/allegro/gfx.h @@ -160,9 +160,9 @@ namespace AGS3 { #define COLORCONV_KEEP_ALPHA (COLORCONV_TOTAL \ & ~(COLORCONV_32A_TO_8 | \ - COLORCONV_32A_TO_15 | \ - COLORCONV_32A_TO_16 | \ - COLORCONV_32A_TO_24)) + COLORCONV_32A_TO_15 | \ + COLORCONV_32A_TO_16 | \ + COLORCONV_32A_TO_24)) class BITMAP : public Graphics::ManagedSurface { }; diff --git a/engines/ags/stubs/allegro/midi.h b/engines/ags/stubs/allegro/midi.h index 8925ac653b6a..e1f5f2071d45 100644 --- a/engines/ags/stubs/allegro/midi.h +++ b/engines/ags/stubs/allegro/midi.h @@ -90,15 +90,15 @@ AL_ARRAY(_DRIVER_INFO, _midi_driver_list); /* macros for constructing the driver lists */ #define BEGIN_MIDI_DRIVER_LIST \ - _DRIVER_INFO _midi_driver_list[] = \ - { + _DRIVER_INFO _midi_driver_list[] = \ + { #define END_MIDI_DRIVER_LIST \ - { 0, NULL, 0 } \ - }; + { 0, NULL, 0 } \ + }; #define MIDI_DRIVER_DIGMID \ - { MIDI_DIGMID, &midi_digmid, TRUE }, + { MIDI_DIGMID, &midi_digmid, TRUE }, AL_VAR(MIDI_DRIVER *, midi_driver); From 6e714a7d9fd858f3c4830d8e145b0dd69b940a58 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 15:22:35 -0800 Subject: [PATCH 008/215] AGS: Wrapping headers in an AGS3 namespace --- engines/ags/engine/ac/asset_helper.h | 4 + engines/ags/engine/ac/audiochannel.h | 4 + engines/ags/engine/ac/audioclip.h | 4 + engines/ags/engine/ac/button.h | 4 + engines/ags/engine/ac/cdaudio.h | 8 +- engines/ags/engine/ac/character.h | 4 + engines/ags/engine/ac/charactercache.h | 4 + engines/ags/engine/ac/characterextras.h | 4 + engines/ags/engine/ac/datetime.h | 4 + engines/ags/engine/ac/dialog.h | 6 +- .../ags/engine/ac/dialogoptionsrendering.h | 4 + engines/ags/engine/ac/display.h | 6 +- engines/ags/engine/ac/draw.h | 8 +- engines/ags/engine/ac/draw_software.h | 4 + engines/ags/engine/ac/drawingsurface.h | 4 + engines/ags/engine/ac/dynamicsprite.h | 4 + .../engine/ac/dynobj/cc_agsdynamicobject.h | 4 + .../ags/engine/ac/dynobj/cc_audiochannel.h | 4 + engines/ags/engine/ac/dynobj/cc_audioclip.h | 4 + engines/ags/engine/ac/dynobj/cc_character.h | 4 + engines/ags/engine/ac/dynobj/cc_dialog.h | 4 + .../ags/engine/ac/dynobj/cc_dynamicarray.h | 4 + .../ags/engine/ac/dynobj/cc_dynamicobject.h | 22 +- .../cc_dynamicobject_addr_and_manager.h | 6 +- engines/ags/engine/ac/dynobj/cc_gui.h | 4 + engines/ags/engine/ac/dynobj/cc_guiobject.h | 4 + engines/ags/engine/ac/dynobj/cc_hotspot.h | 4 + engines/ags/engine/ac/dynobj/cc_inventory.h | 4 + engines/ags/engine/ac/dynobj/cc_object.h | 4 + engines/ags/engine/ac/dynobj/cc_region.h | 5 +- engines/ags/engine/ac/dynobj/cc_serializer.h | 4 + .../ags/engine/ac/dynobj/managedobjectpool.h | 18 +- .../ags/engine/ac/dynobj/scriptaudiochannel.h | 4 + engines/ags/engine/ac/dynobj/scriptcamera.h | 4 + .../ags/engine/ac/dynobj/scriptcontainers.h | 4 + engines/ags/engine/ac/dynobj/scriptdatetime.h | 4 + engines/ags/engine/ac/dynobj/scriptdialog.h | 4 + .../ac/dynobj/scriptdialogoptionsrendering.h | 3 + engines/ags/engine/ac/dynobj/scriptdict.h | 6 +- .../engine/ac/dynobj/scriptdrawingsurface.h | 8 +- .../engine/ac/dynobj/scriptdynamicsprite.h | 6 +- engines/ags/engine/ac/dynobj/scriptfile.h | 4 + engines/ags/engine/ac/dynobj/scriptgui.h | 4 + engines/ags/engine/ac/dynobj/scripthotspot.h | 4 + engines/ags/engine/ac/dynobj/scriptinvitem.h | 4 + engines/ags/engine/ac/dynobj/scriptmouse.h | 4 + engines/ags/engine/ac/dynobj/scriptobject.h | 4 + engines/ags/engine/ac/dynobj/scriptoverlay.h | 4 + engines/ags/engine/ac/dynobj/scriptregion.h | 4 + engines/ags/engine/ac/dynobj/scriptset.h | 4 + engines/ags/engine/ac/dynobj/scriptstring.h | 4 + engines/ags/engine/ac/dynobj/scriptsystem.h | 4 + .../ags/engine/ac/dynobj/scriptuserobject.h | 6 +- .../ags/engine/ac/dynobj/scriptviewframe.h | 4 + engines/ags/engine/ac/dynobj/scriptviewport.h | 4 + engines/ags/engine/ac/event.h | 4 + engines/ags/engine/ac/file.h | 9 +- engines/ags/engine/ac/game.h | 9 +- engines/ags/engine/ac/gamesetup.h | 3 + engines/ags/engine/ac/gamestate.h | 25 +- engines/ags/engine/ac/global_audio.h | 4 + engines/ags/engine/ac/global_button.h | 4 + engines/ags/engine/ac/global_character.h | 4 + engines/ags/engine/ac/global_datetime.h | 6 +- engines/ags/engine/ac/global_debug.h | 4 + engines/ags/engine/ac/global_dialog.h | 4 + engines/ags/engine/ac/global_display.h | 4 + engines/ags/engine/ac/global_drawingsurface.h | 4 + engines/ags/engine/ac/global_dynamicsprite.h | 4 + engines/ags/engine/ac/global_file.h | 8 +- engines/ags/engine/ac/global_game.h | 5 + engines/ags/engine/ac/global_gui.h | 4 + engines/ags/engine/ac/global_hotspot.h | 3 + engines/ags/engine/ac/global_inventoryitem.h | 4 + engines/ags/engine/ac/global_invwindow.h | 4 + engines/ags/engine/ac/global_label.h | 10 +- engines/ags/engine/ac/global_listbox.h | 6 +- engines/ags/engine/ac/global_mouse.h | 4 + engines/ags/engine/ac/global_object.h | 8 +- engines/ags/engine/ac/global_overlay.h | 4 + engines/ags/engine/ac/global_palette.h | 4 + engines/ags/engine/ac/global_parser.h | 4 + engines/ags/engine/ac/global_plugin.h | 4 + engines/ags/engine/ac/global_record.h | 4 + engines/ags/engine/ac/global_region.h | 4 + engines/ags/engine/ac/global_room.h | 6 +- engines/ags/engine/ac/global_screen.h | 4 + engines/ags/engine/ac/global_slider.h | 4 + engines/ags/engine/ac/global_string.h | 4 + engines/ags/engine/ac/global_textbox.h | 4 + engines/ags/engine/ac/global_timer.h | 4 + engines/ags/engine/ac/global_translation.h | 4 + engines/ags/engine/ac/global_video.h | 4 + engines/ags/engine/ac/global_viewframe.h | 4 + engines/ags/engine/ac/global_viewport.h | 4 + engines/ags/engine/ac/global_walkablearea.h | 4 + engines/ags/engine/ac/global_walkbehind.h | 4 + engines/ags/engine/ac/gui.h | 4 + engines/ags/engine/ac/guicontrol.h | 14 +- engines/ags/engine/ac/hotspot.h | 4 + engines/ags/engine/ac/inventoryitem.h | 4 + engines/ags/engine/ac/invwindow.h | 8 +- engines/ags/engine/ac/keycode.h | 4 + engines/ags/engine/ac/label.h | 4 + engines/ags/engine/ac/lipsync.h | 6 +- engines/ags/engine/ac/listbox.h | 6 +- engines/ags/engine/ac/math.h | 4 + engines/ags/engine/ac/mouse.h | 4 + engines/ags/engine/ac/movelist.h | 8 +- engines/ags/engine/ac/object.h | 9 +- engines/ags/engine/ac/objectcache.h | 4 + engines/ags/engine/ac/overlay.h | 9 +- engines/ags/engine/ac/parser.h | 4 + engines/ags/engine/ac/path_helper.h | 4 + engines/ags/engine/ac/properties.h | 4 + engines/ags/engine/ac/region.h | 4 + engines/ags/engine/ac/richgamemedia.h | 9 +- engines/ags/engine/ac/room.h | 4 + engines/ags/engine/ac/roomobject.h | 9 +- engines/ags/engine/ac/roomstatus.h | 13 +- engines/ags/engine/ac/route_finder.h | 9 +- engines/ags/engine/ac/route_finder_impl.h | 8 +- .../ags/engine/ac/route_finder_impl_legacy.h | 8 +- engines/ags/engine/ac/runtime_defines.h | 12 +- engines/ags/engine/ac/screen.h | 13 +- engines/ags/engine/ac/screenoverlay.h | 14 +- engines/ags/engine/ac/slider.h | 4 + engines/ags/engine/ac/speech.h | 24 +- engines/ags/engine/ac/sprite.h | 4 + engines/ags/engine/ac/spritelistentry.h | 4 + .../ags/engine/ac/statobj/agsstaticobject.h | 4 + engines/ags/engine/ac/statobj/staticarray.h | 8 +- engines/ags/engine/ac/statobj/staticobject.h | 22 +- engines/ags/engine/ac/string.h | 4 + engines/ags/engine/ac/sys_events.h | 4 + engines/ags/engine/ac/system.h | 3 + engines/ags/engine/ac/textbox.h | 4 + engines/ags/engine/ac/timer.h | 10 +- engines/ags/engine/ac/topbarsettings.h | 4 + engines/ags/engine/ac/translation.h | 4 + engines/ags/engine/ac/tree_map.h | 4 + engines/ags/engine/ac/viewframe.h | 9 +- engines/ags/engine/ac/walkablearea.h | 4 + engines/ags/engine/ac/walkbehind.h | 4 + .../ags/engine/debugging/agseditordebugger.h | 4 + .../engine/debugging/consoleoutputtarget.h | 6 +- engines/ags/engine/debugging/debug_log.h | 6 +- engines/ags/engine/debugging/debugger.h | 4 + .../ags/engine/debugging/dummyagsdebugger.h | 7 +- .../engine/debugging/filebasedagsdebugger.h | 4 + engines/ags/engine/debugging/logfile.h | 8 +- engines/ags/engine/debugging/messagebuffer.h | 6 +- engines/ags/engine/device/mousew32.h | 8 +- engines/ags/engine/game/game_init.h | 2 + engines/ags/engine/game/savegame.h | 21 +- engines/ags/engine/game/savegame_components.h | 3 +- engines/ags/engine/game/savegame_internal.h | 3 +- engines/ags/engine/game/viewport.h | 6 +- engines/ags/engine/gfx/ali3dexception.h | 2 + engines/ags/engine/gfx/ali3dogl.h | 15 +- engines/ags/engine/gfx/ali3dsw.h | 22 +- engines/ags/engine/gfx/blender.h | 4 + engines/ags/engine/gfx/ddb.h | 2 + engines/ags/engine/gfx/gfx_util.h | 4 +- engines/ags/engine/gfx/gfxdefines.h | 2 + engines/ags/engine/gfx/gfxdriverbase.h | 13 +- engines/ags/engine/gfx/gfxdriverfactory.h | 4 +- engines/ags/engine/gfx/gfxdriverfactorybase.h | 4 +- engines/ags/engine/gfx/gfxfilter.h | 2 + engines/ags/engine/gfx/gfxfilter_aad3d.h | 2 + engines/ags/engine/gfx/gfxfilter_aaogl.h | 2 + engines/ags/engine/gfx/gfxfilter_allegro.h | 2 + engines/ags/engine/gfx/gfxfilter_d3d.h | 2 + engines/ags/engine/gfx/gfxfilter_hqx.h | 2 + engines/ags/engine/gfx/gfxfilter_ogl.h | 2 + engines/ags/engine/gfx/gfxfilter_scaling.h | 2 + engines/ags/engine/gfx/gfxmodelist.h | 2 + engines/ags/engine/gfx/graphicsdriver.h | 12 +- engines/ags/engine/gfx/hq2x3x.h | 13 +- engines/ags/engine/gui/animatingguibutton.h | 4 + engines/ags/engine/gui/cscidialog.h | 4 + engines/ags/engine/gui/guidialog.h | 3 + engines/ags/engine/gui/guidialogdefines.h | 8 +- .../ags/engine/gui/guidialoginternaldefs.h | 4 + engines/ags/engine/gui/mylabel.h | 6 +- engines/ags/engine/gui/mylistbox.h | 6 +- engines/ags/engine/gui/mypushbutton.h | 6 +- engines/ags/engine/gui/mytextbox.h | 6 +- engines/ags/engine/gui/newcontrol.h | 4 + engines/ags/engine/main/config.h | 3 + engines/ags/engine/main/engine.h | 4 + engines/ags/engine/main/engine_setup.h | 4 + engines/ags/engine/main/game_file.h | 4 + engines/ags/engine/main/game_run.h | 9 +- engines/ags/engine/main/game_start.h | 4 + engines/ags/engine/main/graphics_mode.h | 16 +- engines/ags/engine/main/main.h | 4 + engines/ags/engine/main/main_allegro.h | 4 + engines/ags/engine/main/mainheader.h | 5 + engines/ags/engine/main/quit.h | 24 +- engines/ags/engine/main/update.h | 4 + engines/ags/engine/media/audio/ambientsound.h | 4 + engines/ags/engine/media/audio/audio.h | 6 +- .../ags/engine/media/audio/clip_mydumbmod.h | 4 + engines/ags/engine/media/audio/clip_myjgmod.h | 6 +- engines/ags/engine/media/audio/clip_mymidi.h | 6 +- engines/ags/engine/media/audio/clip_mymp3.h | 6 +- engines/ags/engine/media/audio/clip_myogg.h | 6 +- .../ags/engine/media/audio/clip_mystaticmp3.h | 6 +- .../ags/engine/media/audio/clip_mystaticogg.h | 6 +- engines/ags/engine/media/audio/clip_mywave.h | 6 +- .../ags/engine/media/audio/queuedaudioitem.h | 9 +- engines/ags/engine/media/audio/sound.h | 4 + engines/ags/engine/media/audio/soundcache.h | 3 + engines/ags/engine/media/audio/soundclip.h | 8 +- engines/ags/engine/media/video/VMR9Graph.h | 38 +-- engines/ags/engine/media/video/video.h | 4 + .../engine/platform/base/agsplatformdriver.h | 11 +- engines/ags/engine/platform/util/pe.h | 16 +- .../windows/debugging/namedpipesagsdebugger.h | 4 + .../engine/platform/windows/gfx/ali3dd3d.h | 16 +- .../engine/platform/windows/setup/winsetup.h | 5 +- .../engine/platform/windows/win_ex_handling.h | 8 +- .../platform/windows/winapi_exclusive.h | 4 + engines/ags/engine/plugin/agsplugin.h | 22 +- engines/ags/engine/plugin/plugin_builtin.h | 4 + engines/ags/engine/plugin/plugin_engine.h | 9 +- .../ags/engine/plugin/pluginobjectreader.h | 4 + engines/ags/engine/script/cc_instance.h | 12 +- engines/ags/engine/script/executingscript.h | 4 + engines/ags/engine/script/exports.h | 4 + .../engine/script/nonblockingscriptfunction.h | 4 + .../ags/engine/script/runtimescriptvalue.h | 233 +++++++++--------- engines/ags/engine/script/script.h | 10 +- engines/ags/engine/script/script_api.h | 6 +- engines/ags/engine/script/script_runtime.h | 4 + engines/ags/engine/script/systemimports.h | 6 +- engines/ags/engine/util/library.h | 3 +- engines/ags/engine/util/library_dummy.h | 6 +- engines/ags/engine/util/library_posix.h | 11 +- engines/ags/engine/util/library_psp.h | 2 + engines/ags/engine/util/library_windows.h | 11 +- engines/ags/engine/util/mutex.h | 3 +- engines/ags/engine/util/mutex_base.h | 4 +- engines/ags/engine/util/mutex_lock.h | 4 +- engines/ags/engine/util/mutex_psp.h | 5 +- engines/ags/engine/util/mutex_pthread.h | 4 +- engines/ags/engine/util/mutex_std.h | 5 +- engines/ags/engine/util/mutex_wii.h | 5 +- engines/ags/engine/util/mutex_windows.h | 5 +- engines/ags/engine/util/scaling.h | 2 + engines/ags/engine/util/thread.h | 5 +- engines/ags/engine/util/thread_psp.h | 4 +- engines/ags/engine/util/thread_pthread.h | 4 +- engines/ags/engine/util/thread_std.h | 2 + engines/ags/engine/util/thread_wii.h | 3 +- engines/ags/engine/util/thread_windows.h | 7 +- engines/ags/shared/ac/audiocliptype.h | 9 +- engines/ags/shared/ac/characterinfo.h | 9 +- engines/ags/shared/ac/common.h | 4 + engines/ags/shared/ac/common_defines.h | 4 + engines/ags/shared/ac/dialogtopic.h | 8 +- .../ags/shared/ac/dynobj/scriptaudioclip.h | 9 +- engines/ags/shared/ac/game_version.h | 4 + engines/ags/shared/ac/gamesetupstruct.h | 16 +- engines/ags/shared/ac/gamesetupstructbase.h | 9 +- engines/ags/shared/ac/gamestructdefines.h | 38 +-- engines/ags/shared/ac/interfacebutton.h | 4 + engines/ags/shared/ac/interfaceelement.h | 4 + engines/ags/shared/ac/inventoryiteminfo.h | 9 +- engines/ags/shared/ac/mousecursor.h | 9 +- engines/ags/shared/ac/oldgamesetupstruct.h | 12 +- engines/ags/shared/ac/spritecache.h | 9 +- engines/ags/shared/ac/view.h | 9 +- engines/ags/shared/ac/wordsdictionary.h | 9 +- engines/ags/shared/api/stream_api.h | 2 + engines/ags/shared/core/asset.h | 2 + engines/ags/shared/core/assetmanager.h | 24 +- engines/ags/shared/core/platform.h | 4 + engines/ags/shared/core/types.h | 8 +- engines/ags/shared/debugging/debugmanager.h | 15 +- engines/ags/shared/debugging/out.h | 35 +-- engines/ags/shared/debugging/outputhandler.h | 9 +- engines/ags/shared/font/agsfontrenderer.h | 4 + engines/ags/shared/font/fonts.h | 11 +- engines/ags/shared/font/ttffontrenderer.h | 8 +- engines/ags/shared/font/wfnfont.h | 8 +- engines/ags/shared/font/wfnfontrenderer.h | 6 +- engines/ags/shared/game/customproperties.h | 3 + engines/ags/shared/game/interactions.h | 16 +- engines/ags/shared/game/main_game_file.h | 9 +- engines/ags/shared/game/plugininfo.h | 6 +- engines/ags/shared/game/room_file.h | 3 + engines/ags/shared/game/room_version.h | 4 + engines/ags/shared/game/roomstruct.h | 25 +- engines/ags/shared/gfx/allegrobitmap.h | 7 +- engines/ags/shared/gfx/bitmap.h | 2 + engines/ags/shared/gfx/gfx_def.h | 4 +- engines/ags/shared/gui/guibutton.h | 18 +- engines/ags/shared/gui/guidefines.h | 108 ++++---- engines/ags/shared/gui/guiinv.h | 5 +- engines/ags/shared/gui/guilabel.h | 8 +- engines/ags/shared/gui/guilistbox.h | 5 +- engines/ags/shared/gui/guimain.h | 17 +- engines/ags/shared/gui/guiobject.h | 34 ++- engines/ags/shared/gui/guislider.h | 5 +- engines/ags/shared/gui/guitextbox.h | 5 +- engines/ags/shared/script/cc_error.h | 4 + engines/ags/shared/script/cc_options.h | 4 + engines/ags/shared/script/cc_script.h | 9 +- engines/ags/shared/script/script_common.h | 4 + engines/ags/shared/util/alignedstream.h | 6 +- engines/ags/shared/util/bbop.h | 9 +- engines/ags/shared/util/bufferedstream.h | 2 + engines/ags/shared/util/compress.h | 9 +- engines/ags/shared/util/datastream.h | 14 +- engines/ags/shared/util/directory.h | 2 + engines/ags/shared/util/error.h | 26 +- engines/ags/shared/util/file.h | 4 +- engines/ags/shared/util/filestream.h | 6 +- engines/ags/shared/util/geometry.h | 59 ++--- engines/ags/shared/util/ini_util.h | 2 + engines/ags/shared/util/inifile.h | 6 +- engines/ags/shared/util/lzw.h | 9 +- engines/ags/shared/util/math.h | 3 + engines/ags/shared/util/memory.h | 11 +- engines/ags/shared/util/misc.h | 14 +- engines/ags/shared/util/multifilelib.h | 26 +- engines/ags/shared/util/path.h | 2 + engines/ags/shared/util/proxystream.h | 4 +- engines/ags/shared/util/stdio_compat.h | 16 +- engines/ags/shared/util/stream.h | 2 + engines/ags/shared/util/string.h | 14 +- engines/ags/shared/util/string_compat.h | 14 +- engines/ags/shared/util/string_types.h | 2 + engines/ags/shared/util/string_utils.h | 9 +- engines/ags/shared/util/textreader.h | 10 +- engines/ags/shared/util/textstreamreader.h | 4 +- engines/ags/shared/util/textstreamwriter.h | 4 +- engines/ags/shared/util/textwriter.h | 14 +- engines/ags/shared/util/version.h | 2 + engines/ags/shared/util/wgt2allg.h | 33 +-- 342 files changed, 1980 insertions(+), 741 deletions(-) diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index 4efd81efb07c..eb5c0e4ffca5 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -33,6 +33,8 @@ #include #include "util/string.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; @@ -79,4 +81,6 @@ PACKFILE *PackfileFromAsset(const AssetPath &path, size_t &asset_size); DUMBFILE *DUMBfileFromAsset(const AssetPath &path, size_t &asset_size); bool DoesAssetExistInLib(const AssetPath &assetname); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/audiochannel.h b/engines/ags/engine/ac/audiochannel.h index d130cb8a13fd..5cb30e14aac7 100644 --- a/engines/ags/engine/ac/audiochannel.h +++ b/engines/ags/engine/ac/audiochannel.h @@ -26,6 +26,8 @@ #include "ac/dynobj/scriptaudioclip.h" #include "ac/dynobj/scriptaudiochannel.h" +namespace AGS3 { + int AudioChannel_GetID(ScriptAudioChannel *channel); int AudioChannel_GetIsPlaying(ScriptAudioChannel *channel); int AudioChannel_GetPanning(ScriptAudioChannel *channel); @@ -40,4 +42,6 @@ void AudioChannel_Stop(ScriptAudioChannel *channel); void AudioChannel_Seek(ScriptAudioChannel *channel, int newPosition); void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPos); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/audioclip.h b/engines/ags/engine/ac/audioclip.h index 8cd7514045e6..9f8fab806014 100644 --- a/engines/ags/engine/ac/audioclip.h +++ b/engines/ags/engine/ac/audioclip.h @@ -26,6 +26,8 @@ #include "ac/dynobj/scriptaudioclip.h" #include "ac/dynobj/scriptaudiochannel.h" +namespace AGS3 { + int AudioClip_GetFileType(ScriptAudioClip *clip); int AudioClip_GetType(ScriptAudioClip *clip); int AudioClip_GetIsAvailable(ScriptAudioClip *clip); @@ -34,4 +36,6 @@ ScriptAudioChannel *AudioClip_Play(ScriptAudioClip *clip, int priority, int repe ScriptAudioChannel *AudioClip_PlayFrom(ScriptAudioClip *clip, int position, int priority, int repeat); ScriptAudioChannel *AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, int repeat); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h index 7f872fcd19ed..65ef6a42d194 100644 --- a/engines/ags/engine/ac/button.h +++ b/engines/ags/engine/ac/button.h @@ -25,6 +25,8 @@ #include "gui/guibutton.h" +namespace AGS3 { + using AGS::Common::GUIButton; void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat); @@ -49,4 +51,6 @@ int UpdateAnimatingButton(int bu); void StopButtonAnimation(int idxn); void FindAndRemoveButtonAnimation(int guin, int objn); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/cdaudio.h b/engines/ags/engine/ac/cdaudio.h index d3598a390434..ee6763bad496 100644 --- a/engines/ags/engine/ac/cdaudio.h +++ b/engines/ags/engine/ac/cdaudio.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_CDAUDIO_H #define AGS_ENGINE_AC_CDAUDIO_H +namespace AGS3 { + // CD Player functions // flags returned with cd_getstatus #define CDS_DRIVEOPEN 0x0001 // tray is open @@ -30,7 +32,9 @@ #define CDS_AUDIOSUPPORT 0x0010 // supports audio CDs #define CDS_DRIVEEMPTY 0x0800 // no CD in drive -int init_cd_player() ; -int cd_manager(int cmdd, int datt) ; +int init_cd_player(); +int cd_manager(int cmdd, int datt); + +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h index 28a127ad6757..9039aaf9adf2 100644 --- a/engines/ags/engine/ac/character.h +++ b/engines/ags/engine/ac/character.h @@ -31,6 +31,8 @@ #include "game/viewport.h" #include "util/geometry.h" +namespace AGS3 { + // **** CHARACTER: FUNCTIONS **** void Character_AddInventory(CharacterInfo *chaa, ScriptInvItem *invi, int addIndex); @@ -225,4 +227,6 @@ extern int32_t _sc_PlayerCharPtr; // order of loops to turn character in circle from down to down extern int turnlooporder[8]; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/charactercache.h b/engines/ags/engine/ac/charactercache.h index 9032c8302459..ec6564d113c7 100644 --- a/engines/ags/engine/ac/charactercache.h +++ b/engines/ags/engine/ac/charactercache.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_CHARACTERCACHE_H #define AGS_ENGINE_AC_CHARACTERCACHE_H +namespace AGS3 { + namespace AGS { namespace Common { class Bitmap; @@ -41,4 +43,6 @@ struct CharacterCache { // no mirroredWas is required, since the code inverts the sprite number }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h index 526e69037478..3d08847df39a 100644 --- a/engines/ags/engine/ac/characterextras.h +++ b/engines/ags/engine/ac/characterextras.h @@ -25,6 +25,8 @@ #include "ac/runtime_defines.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { @@ -58,4 +60,6 @@ struct CharacterExtras { void WriteToFile(Common::Stream *out); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/datetime.h b/engines/ags/engine/ac/datetime.h index 96b922a306da..6febc33f6a48 100644 --- a/engines/ags/engine/ac/datetime.h +++ b/engines/ags/engine/ac/datetime.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scriptdatetime.h" +namespace AGS3 { + ScriptDateTime *DateTime_Now_Core(); ScriptDateTime *DateTime_Now(); int DateTime_GetYear(ScriptDateTime *sdt); @@ -35,4 +37,6 @@ int DateTime_GetMinute(ScriptDateTime *sdt); int DateTime_GetSecond(ScriptDateTime *sdt); int DateTime_GetRawTime(ScriptDateTime *sdt); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h index 717ac31a2cdc..7436d4146628 100644 --- a/engines/ags/engine/ac/dialog.h +++ b/engines/ags/engine/ac/dialog.h @@ -26,6 +26,8 @@ #include #include "ac/dynobj/scriptdialog.h" +namespace AGS3 { + int Dialog_GetID(ScriptDialog *sd); int Dialog_GetOptionCount(ScriptDialog *sd); int Dialog_GetShowTextParser(ScriptDialog *sd); @@ -37,8 +39,10 @@ void Dialog_SetOptionState(ScriptDialog *sd, int option, int newState); void Dialog_Start(ScriptDialog *sd); void do_conversation(int dlgnum); -int show_dialog_options(int dlgnum, int sayChosenOption, bool runGameLoopsInBackground) ; +int show_dialog_options(int dlgnum, int sayChosenOption, bool runGameLoopsInBackground); extern ScriptDialog *scrDialog; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dialogoptionsrendering.h b/engines/ags/engine/ac/dialogoptionsrendering.h index d1e741c20150..4f8584c2716b 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.h +++ b/engines/ags/engine/ac/dialogoptionsrendering.h @@ -26,6 +26,8 @@ #include "ac/dynobj/scriptdialog.h" #include "ac/dynobj/scriptdialogoptionsrendering.h" +namespace AGS3 { + int DialogOptionsRendering_GetX(ScriptDialogOptionsRendering *dlgOptRender); void DialogOptionsRendering_SetX(ScriptDialogOptionsRendering *dlgOptRender, int newX); int DialogOptionsRendering_GetY(ScriptDialogOptionsRendering *dlgOptRender); @@ -47,4 +49,6 @@ ScriptDrawingSurface *DialogOptionsRendering_GetSurface(ScriptDialogOptionsRende int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender); void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h index 6ea4cd5e6713..35b5f7f13c46 100644 --- a/engines/ags/engine/ac/display.h +++ b/engines/ags/engine/ac/display.h @@ -25,6 +25,8 @@ #include "gui/guimain.h" +namespace AGS3 { + using AGS::Common::GUIMain; // options for 'disp_type' parameter @@ -76,10 +78,12 @@ int get_textwindow_top_border_height(int twgui); // Warning!: draw_text_window() and draw_text_window_and_bar() can create new text_window_ds void draw_text_window(Common::Bitmap **text_window_ds, bool should_free_ds, int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum); void draw_text_window_and_bar(Common::Bitmap **text_window_ds, bool should_free_ds, - int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight = 0, int ifnum = -1); + int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight = 0, int ifnum = -1); int get_textwindow_padding(int ifnum); // The efficient length of the last source text prepared for display extern int source_text_length; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index 922b557e1b86..2613f34357ca 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -29,6 +29,8 @@ #include "gfx/gfx_def.h" #include "util/wgt2allg.h" +namespace AGS3 { + namespace AGS { namespace Common { class Bitmap; @@ -115,9 +117,9 @@ void construct_engine_overlay(); void add_to_sprite_list(Engine::IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind = false); void tint_image(Common::Bitmap *g, Common::Bitmap *source, int red, int grn, int blu, int light_level, int luminance = 255); void draw_sprite_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Common::Bitmap *image, bool src_has_alpha, - Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); + Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); void draw_sprite_slot_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot, - Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); + Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); void draw_gui_sprite(Common::Bitmap *ds, int pic, int x, int y, bool use_alpha, Common::BlendMode blend_mode); void draw_gui_sprite_v330(Common::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Common::BlendMode blend_mode = Common::kBlendMode_Alpha); // Render game on screen @@ -177,4 +179,6 @@ Common::PBitmap PrepareSpriteForUse(Common::PBitmap bitmap, bool has_alpha); // of the requested width and height and game's native color depth. Common::Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res = false); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/draw_software.h b/engines/ags/engine/ac/draw_software.h index b27a8c3412a3..8d8d20fd4bff 100644 --- a/engines/ags/engine/ac/draw_software.h +++ b/engines/ags/engine/ac/draw_software.h @@ -34,6 +34,8 @@ #include "gfx/ddb.h" #include "util/geometry.h" +namespace AGS3 { + // Inits dirty rects array for the given room camera/viewport pair // View_index indicates the room viewport (>= 0) or the main viewport (-1) void init_invalid_regions(int view_index, const Size &surf_size, const Rect &viewport); @@ -54,4 +56,6 @@ void update_black_invreg_and_reset(AGS::Common::Bitmap *ds); // no_transform flag tells the system that the regions should be plain copied to the ds. void update_room_invreg_and_reset(int view_index, AGS::Common::Bitmap *ds, AGS::Common::Bitmap *src, bool no_transform); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/drawingsurface.h b/engines/ags/engine/ac/drawingsurface.h index 5878f2a83775..511b73a98b82 100644 --- a/engines/ags/engine/ac/drawingsurface.h +++ b/engines/ags/engine/ac/drawingsurface.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scriptdrawingsurface.h" +namespace AGS3 { + void DrawingSurface_Release(ScriptDrawingSurface *sds); // convert actual co-ordinate back to what the script is expecting ScriptDrawingSurface *DrawingSurface_CreateCopy(ScriptDrawingSurface *sds); @@ -47,4 +49,6 @@ void DrawingSurface_DrawLine(ScriptDrawingSurface *sds, int fromx, int fromy, void DrawingSurface_DrawPixel(ScriptDrawingSurface *sds, int x, int y); int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynamicsprite.h b/engines/ags/engine/ac/dynamicsprite.h index 14610057a883..a78b50ee1033 100644 --- a/engines/ags/engine/ac/dynamicsprite.h +++ b/engines/ags/engine/ac/dynamicsprite.h @@ -26,6 +26,8 @@ #include "ac/dynobj/scriptdynamicsprite.h" #include "ac/dynobj/scriptdrawingsurface.h" +namespace AGS3 { + void DynamicSprite_Delete(ScriptDynamicSprite *sds); ScriptDrawingSurface *DynamicSprite_GetDrawingSurface(ScriptDynamicSprite *dss); int DynamicSprite_GetGraphic(ScriptDynamicSprite *sds); @@ -53,4 +55,6 @@ ScriptDynamicSprite *DynamicSprite_CreateFromBackground(int frame, int x1, int y void add_dynamic_sprite(int gotSlot, Common::Bitmap *redin, bool hasAlpha = false); void free_dynamic_sprite(int gotSlot); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h index c14103702614..af1263bfb77f 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_dynamicobject.h" +namespace AGS3 { + struct AGSCCDynamicObject : ICCDynamicObject { protected: virtual ~AGSCCDynamicObject() = default; @@ -65,4 +67,6 @@ struct AGSCCDynamicObject : ICCDynamicObject { }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.h b/engines/ags/engine/ac/dynobj/cc_audiochannel.h index e36ff25f36df..caa77fe33116 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.h +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.h @@ -25,10 +25,14 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCAudioChannel final : AGSCCDynamicObject { const char *GetType() override; int Serialize(const char *address, char *buffer, int bufsize) override; void Unserialize(int index, const char *serializedData, int dataSize) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.h b/engines/ags/engine/ac/dynobj/cc_audioclip.h index 3b3f7645315b..2f9b8bd8fe55 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.h +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.h @@ -25,10 +25,14 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCAudioClip final : AGSCCDynamicObject { const char *GetType() override; int Serialize(const char *address, char *buffer, int bufsize) override; void Unserialize(int index, const char *serializedData, int dataSize) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_character.h b/engines/ags/engine/ac/dynobj/cc_character.h index e608c281e071..7acb48709949 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.h +++ b/engines/ags/engine/ac/dynobj/cc_character.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCCharacter final : AGSCCDynamicObject { // return the type name of the object @@ -39,4 +41,6 @@ struct CCCharacter final : AGSCCDynamicObject { void WriteInt16(const char *address, intptr_t offset, int16_t val) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.h b/engines/ags/engine/ac/dynobj/cc_dialog.h index 0ed6030ff7fd..9fbcdbe65458 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.h +++ b/engines/ags/engine/ac/dynobj/cc_dialog.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCDialog final : AGSCCDynamicObject { // return the type name of the object @@ -38,4 +40,6 @@ struct CCDialog final : AGSCCDynamicObject { }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index f5febb7e03ec..e89774ada488 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -26,6 +26,8 @@ #include #include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject +namespace AGS3 { + #define CC_DYNAMIC_ARRAY_TYPE_NAME "CCDynamicArray" #define ARRAY_MANAGED_TYPE_FLAG 0x80000000 @@ -62,4 +64,6 @@ namespace DynamicArrayHelpers { DynObjectRef CreateStringArray(const std::vector); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index 39f7a2ffcf6c..42394dc11c88 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -32,6 +32,8 @@ #include #include "core/types.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { @@ -75,17 +77,17 @@ struct ICCDynamicObject { // necessary, because byte-code does not contain any distinct operation for this case. // The worst thing here is that with the current byte-code structure we can never tell whether // offset 0 means getting pointer to whole object or a pointer to its first field. - virtual const char *GetFieldPtr(const char *address, intptr_t offset) = 0; + virtual const char *GetFieldPtr(const char *address, intptr_t offset) = 0; virtual void Read(const char *address, intptr_t offset, void *dest, int size) = 0; - virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; - virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; - virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; - virtual float ReadFloat(const char *address, intptr_t offset) = 0; + virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; + virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; + virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; + virtual float ReadFloat(const char *address, intptr_t offset) = 0; virtual void Write(const char *address, intptr_t offset, void *src, int size) = 0; - virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; - virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; - virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; - virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; + virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; + virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; + virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; + virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; protected: ICCDynamicObject() = default; @@ -128,4 +130,6 @@ extern int ccReleaseObjectReference(int32_t handle); extern ICCStringClass *stringClassImpl; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h index d3a9e5963a28..9087334e6b0f 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h @@ -26,8 +26,12 @@ #include "script/runtimescriptvalue.h" #include "ac/dynobj/cc_dynamicobject.h" +namespace AGS3 { + extern ScriptValueType ccGetObjectAddressAndManagerFromHandle( - int32_t handle, void *&object, ICCDynamicObject *&manager); + int32_t handle, void *&object, ICCDynamicObject *&manager); + +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/dynobj/cc_gui.h b/engines/ags/engine/ac/dynobj/cc_gui.h index 7a24b76e2304..fb0d6974cbab 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.h +++ b/engines/ags/engine/ac/dynobj/cc_gui.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCGUI final : AGSCCDynamicObject { // return the type name of the object @@ -37,4 +39,6 @@ struct CCGUI final : AGSCCDynamicObject { void Unserialize(int index, const char *serializedData, int dataSize) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.h b/engines/ags/engine/ac/dynobj/cc_guiobject.h index d07e6bd645ce..f56c5589a6a2 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.h +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCGUIObject final : AGSCCDynamicObject { // return the type name of the object @@ -38,4 +40,6 @@ struct CCGUIObject final : AGSCCDynamicObject { }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.h b/engines/ags/engine/ac/dynobj/cc_hotspot.h index 0efb6ed4bd2a..5b93be4a2d03 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.h +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCHotspot final : AGSCCDynamicObject { // return the type name of the object @@ -38,4 +40,6 @@ struct CCHotspot final : AGSCCDynamicObject { }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.h b/engines/ags/engine/ac/dynobj/cc_inventory.h index 450305d69dcd..8287600cccc6 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.h +++ b/engines/ags/engine/ac/dynobj/cc_inventory.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCInventory final : AGSCCDynamicObject { // return the type name of the object @@ -38,4 +40,6 @@ struct CCInventory final : AGSCCDynamicObject { }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_object.h b/engines/ags/engine/ac/dynobj/cc_object.h index d1da2d7a2b6f..b74c6ec2fc20 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.h +++ b/engines/ags/engine/ac/dynobj/cc_object.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCObject final : AGSCCDynamicObject { // return the type name of the object @@ -38,4 +40,6 @@ struct CCObject final : AGSCCDynamicObject { }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_region.h b/engines/ags/engine/ac/dynobj/cc_region.h index 7b52c7ae775c..2251fe3c0562 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.h +++ b/engines/ags/engine/ac/dynobj/cc_region.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct CCRegion final : AGSCCDynamicObject { // return the type name of the object @@ -35,7 +37,8 @@ struct CCRegion final : AGSCCDynamicObject { int Serialize(const char *address, char *buffer, int bufsize) override; void Unserialize(int index, const char *serializedData, int dataSize) override; - }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h index 0253eb94f31d..5b43321ed4af 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.h +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_dynamicobject.h" +namespace AGS3 { + struct AGSDeSerializer : ICCObjectReader { void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) override; @@ -32,4 +34,6 @@ struct AGSDeSerializer : ICCObjectReader { extern AGSDeSerializer ccUnserializer; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index 93cd695b1f18..654dcce97900 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -30,11 +30,13 @@ #include "script/runtimescriptvalue.h" #include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject +namespace AGS3 { namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later struct ManagedObjectPool final { @@ -54,14 +56,16 @@ struct ManagedObjectPool final { } ManagedObject() - : obj_type(kScValUndefined), handle(0), addr(nullptr), callback(nullptr), refCount(0) {} + : obj_type(kScValUndefined), handle(0), addr(nullptr), callback(nullptr), refCount(0) { + } ManagedObject(ScriptValueType obj_type, int32_t handle, const char *addr, ICCDynamicObject *callback) - : obj_type(obj_type), handle(handle), addr(addr), callback(callback), refCount(0) {} + : obj_type(obj_type), handle(handle), addr(addr), callback(callback), refCount(0) { + } }; int objectCreationCounter; // used to do garbage collection every so often - int32_t nextHandle {}; // TODO: manage nextHandle's going over INT32_MAX ! + int32_t nextHandle{}; // TODO: manage nextHandle's going over INT32_MAX ! std::queue available_ids; std::vector objects; std::unordered_map handleByAddress; @@ -88,7 +92,7 @@ struct ManagedObjectPool final { void reset(); ManagedObjectPool(); - const char *disableDisposeForObject {nullptr}; + const char *disableDisposeForObject{ nullptr }; }; extern ManagedObjectPool pool; @@ -99,4 +103,6 @@ extern ManagedObjectPool pool; #define ManagedObjectLog(...) #endif +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h index 2358526b2a98..52cb3c7d5375 100644 --- a/engines/ags/engine/ac/dynobj/scriptaudiochannel.h +++ b/engines/ags/engine/ac/dynobj/scriptaudiochannel.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTAUDIOCHANNEL_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTAUDIOCHANNEL_H +namespace AGS3 { + struct ScriptAudioChannel { int id; int reserved; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.h b/engines/ags/engine/ac/dynobj/scriptcamera.h index c958a78c36a3..d0ff62acfdf9 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.h +++ b/engines/ags/engine/ac/dynobj/scriptcamera.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + // ScriptCamera keeps a reference to actual room Camera in script. struct ScriptCamera final : AGSCCDynamicObject { public: @@ -54,4 +56,6 @@ struct ScriptCamera final : AGSCCDynamicObject { // Unserialize camera from the memory stream ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dataSize); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptcontainers.h b/engines/ags/engine/ac/dynobj/scriptcontainers.h index f735c6514bf2..71d377330501 100644 --- a/engines/ags/engine/ac/dynobj/scriptcontainers.h +++ b/engines/ags/engine/ac/dynobj/scriptcontainers.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTCONTAINERS_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTCONTAINERS_H +namespace AGS3 { + class ScriptDictBase; class ScriptSetBase; @@ -35,4 +37,6 @@ ScriptSetBase *Set_Create(bool sorted, bool case_sensitive); // Unserialize set from the memory stream ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.h b/engines/ags/engine/ac/dynobj/scriptdatetime.h index 79c755149bf9..a714ff2cbe38 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.h +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct ScriptDateTime final : AGSCCDynamicObject { int year, month, day; int hour, minute, second; @@ -38,4 +40,6 @@ struct ScriptDateTime final : AGSCCDynamicObject { ScriptDateTime(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdialog.h b/engines/ags/engine/ac/dynobj/scriptdialog.h index b1bdefd72788..92a5de458128 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialog.h +++ b/engines/ags/engine/ac/dynobj/scriptdialog.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOG_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOG_H +namespace AGS3 { + struct ScriptDialog { int id; int reserved; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h index 88277931ff96..00fb395f8a4b 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scriptdrawingsurface.h" +namespace AGS3 { + struct ScriptDialogOptionsRendering final : AGSCCDynamicObject { int x, y, width, height; bool hasAlphaChannel; @@ -51,5 +53,6 @@ struct ScriptDialogOptionsRendering final : AGSCCDynamicObject { ScriptDialogOptionsRendering(); }; +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index 3dc6b863266b..4677d3382858 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -43,6 +43,8 @@ #include "util/string.h" #include "util/string_types.h" +namespace AGS3 { + using namespace AGS::Common; class ScriptDictBase : public AGSCCDynamicObject { @@ -167,7 +169,7 @@ class ScriptDictImpl final : public ScriptDictBase { int key_pos = bytesSoFar; bytesSoFar += key_len; size_t value_len = UnserializeInt(); - if (value_len == (size_t) - 1) { + if (value_len == (size_t)-1) { TryAddItem(&serializedData[key_pos], key_len, nullptr, 0); } else { int value_pos = bytesSoFar; @@ -185,4 +187,6 @@ typedef ScriptDictImpl< std::map, true, false > S typedef ScriptDictImpl< std::unordered_map, false, true > ScriptHashDict; typedef ScriptDictImpl< std::unordered_map, false, false > ScriptHashDictCI; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h index 5a60c3853f73..c8033101bc6d 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h @@ -26,11 +26,13 @@ #include "ac/dynobj/cc_agsdynamicobject.h" #include "game/roomstruct.h" +namespace AGS3 { + namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS struct ScriptDrawingSurface final : AGSCCDynamicObject { // These numbers and types are used to determine the source of this drawing surface; @@ -64,4 +66,6 @@ struct ScriptDrawingSurface final : AGSCCDynamicObject { ScriptDrawingSurface(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h index a5ed2909d793..252c2fc8b2d9 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h @@ -25,7 +25,9 @@ #include "ac/dynobj/cc_agsdynamicobject.h" -struct ScriptDynamicSprite final : AGSCCDynamicObject { +namespace AGS3 { + +struct ScriptDynamicSprite final : AGSCCDynamicObject { int slot; int Dispose(const char *address, bool force) override; @@ -37,4 +39,6 @@ struct ScriptDynamicSprite final : AGSCCDynamicObject { ScriptDynamicSprite(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptfile.h b/engines/ags/engine/ac/dynobj/scriptfile.h index 4aa2e8ccf7d8..08e636a98b92 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.h +++ b/engines/ags/engine/ac/dynobj/scriptfile.h @@ -26,6 +26,8 @@ #include "ac/dynobj/cc_dynamicobject.h" #include "util/file.h" +namespace AGS3 { + using namespace AGS; // FIXME later #define scFileRead 1 @@ -63,4 +65,6 @@ struct sc_File final : ICCDynamicObject { void WriteFloat(const char *address, intptr_t offset, float val) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptgui.h b/engines/ags/engine/ac/dynobj/scriptgui.h index 3b6326078dd7..8f9294d1c242 100644 --- a/engines/ags/engine/ac/dynobj/scriptgui.h +++ b/engines/ags/engine/ac/dynobj/scriptgui.h @@ -23,10 +23,14 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTGUI_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTGUI_H +namespace AGS3 { + // 64 bit: This struct must be 8 byte long struct ScriptGUI { int id; int __padding; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scripthotspot.h b/engines/ags/engine/ac/dynobj/scripthotspot.h index 6b692c3c7ce3..c11d3828d671 100644 --- a/engines/ags/engine/ac/dynobj/scripthotspot.h +++ b/engines/ags/engine/ac/dynobj/scripthotspot.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTHOTSPOT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTHOTSPOT_H +namespace AGS3 { + struct ScriptHotspot { int id; int reserved; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptinvitem.h b/engines/ags/engine/ac/dynobj/scriptinvitem.h index 2c4b74607392..962bf5941081 100644 --- a/engines/ags/engine/ac/dynobj/scriptinvitem.h +++ b/engines/ags/engine/ac/dynobj/scriptinvitem.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTINVITEM_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTINVITEM_H +namespace AGS3 { + struct ScriptInvItem { int id; int reserved; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptmouse.h b/engines/ags/engine/ac/dynobj/scriptmouse.h index d1a8f566858e..d935dbdbb514 100644 --- a/engines/ags/engine/ac/dynobj/scriptmouse.h +++ b/engines/ags/engine/ac/dynobj/scriptmouse.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTMOUSE_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTMOUSE_H +namespace AGS3 { + // The text script's "mouse" struct struct ScriptMouse { int x, y; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptobject.h b/engines/ags/engine/ac/dynobj/scriptobject.h index b2c06e051cb5..3eb68dddd64e 100644 --- a/engines/ags/engine/ac/dynobj/scriptobject.h +++ b/engines/ags/engine/ac/dynobj/scriptobject.h @@ -25,6 +25,8 @@ #include "ac/roomobject.h" +namespace AGS3 { + // 64 bit: Struct size must be 8 byte for scripts to work struct ScriptObject { int id; @@ -32,4 +34,6 @@ struct ScriptObject { int __padding; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.h b/engines/ags/engine/ac/dynobj/scriptoverlay.h index b407f40191fb..ed1e7d81b2a2 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.h +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct ScriptOverlay final : AGSCCDynamicObject { int overlayId; int borderWidth; @@ -39,4 +41,6 @@ struct ScriptOverlay final : AGSCCDynamicObject { ScriptOverlay(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptregion.h b/engines/ags/engine/ac/dynobj/scriptregion.h index bc5244128224..743477d65fee 100644 --- a/engines/ags/engine/ac/dynobj/scriptregion.h +++ b/engines/ags/engine/ac/dynobj/scriptregion.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTREGION_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTREGION_H +namespace AGS3 { + struct ScriptRegion { int id; int reserved; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index 165425b10479..cdf83af7cc89 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -42,6 +42,8 @@ #include "util/string.h" #include "util/string_types.h" +namespace AGS3 { + using namespace AGS::Common; class ScriptSetBase : public AGSCCDynamicObject { @@ -150,4 +152,6 @@ typedef ScriptSetImpl< std::set, true, false > ScriptSetC typedef ScriptSetImpl< std::unordered_set, false, true > ScriptHashSet; typedef ScriptSetImpl< std::unordered_set, false, false > ScriptHashSetCI; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptstring.h b/engines/ags/engine/ac/dynobj/scriptstring.h index 289b1e6d5c87..84bff3c3226e 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.h +++ b/engines/ags/engine/ac/dynobj/scriptstring.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct ScriptString final : AGSCCDynamicObject, ICCStringClass { char *text; @@ -39,4 +41,6 @@ struct ScriptString final : AGSCCDynamicObject, ICCStringClass { ScriptString(const char *fromText); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptsystem.h b/engines/ags/engine/ac/dynobj/scriptsystem.h index 4d40079dd88b..47b30c4d2342 100644 --- a/engines/ags/engine/ac/dynobj/scriptsystem.h +++ b/engines/ags/engine/ac/dynobj/scriptsystem.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSYSTEM_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTSYSTEM_H +namespace AGS3 { + // The text script's "system" struct struct ScriptSystem { int width, height; @@ -35,4 +37,6 @@ struct ScriptSystem { int reserved[5]; // so that future scripts don't overwrite data }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h index 0e3f0f6b45d0..ee2188013843 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.h +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -31,6 +31,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct ScriptUserObject final : ICCDynamicObject { public: ScriptUserObject(); @@ -71,7 +73,7 @@ struct ScriptUserObject final : ICCDynamicObject { // need more significant change to program before we could use different // approach. int32_t _size; - char *_data; + char *_data; }; @@ -81,4 +83,6 @@ namespace ScriptStructHelpers { ScriptUserObject *CreatePoint(int x, int y); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.h b/engines/ags/engine/ac/dynobj/scriptviewframe.h index 7b0dc386196e..4a4721eb7165 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.h +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + struct ScriptViewFrame final : AGSCCDynamicObject { int view, loop, frame; @@ -37,4 +39,6 @@ struct ScriptViewFrame final : AGSCCDynamicObject { ScriptViewFrame(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.h b/engines/ags/engine/ac/dynobj/scriptviewport.h index a199e6ff388d..61ae777aa970 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.h +++ b/engines/ags/engine/ac/dynobj/scriptviewport.h @@ -25,6 +25,8 @@ #include "ac/dynobj/cc_agsdynamicobject.h" +namespace AGS3 { + // ScriptViewport keeps a reference to actual room Viewport in script. struct ScriptViewport final : AGSCCDynamicObject { public: @@ -53,4 +55,6 @@ struct ScriptViewport final : AGSCCDynamicObject { // Unserialize viewport from the memory stream ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int dataSize); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h index 51307ae394df..21b265f27b7c 100644 --- a/engines/ags/engine/ac/event.h +++ b/engines/ags/engine/ac/event.h @@ -26,6 +26,8 @@ #include "ac/runtime_defines.h" #include "script/runtimescriptvalue.h" +namespace AGS3 { + // parameters to run_on_event #define GE_LEAVE_ROOM 1 #define GE_ENTER_ROOM 2 @@ -84,4 +86,6 @@ extern int eventClaimed; extern const char *tsnames[4]; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/file.h b/engines/ags/engine/ac/file.h index 2ea04e003852..2c3b4feede0c 100644 --- a/engines/ags/engine/ac/file.h +++ b/engines/ags/engine/ac/file.h @@ -31,11 +31,14 @@ #include "ac/dynobj/scriptfile.h" #include "ac/runtime_defines.h" + +namespace AGS3 { + using AGS::Common::Stream; int File_Exists(const char *fnmm); int File_Delete(const char *fnmm); -void *sc_OpenFile(const char *fnmm, int mode); +void *sc_OpenFile(const char *fnmm, int mode); void File_Close(sc_File *fil); void File_WriteString(sc_File *fil, const char *towrite); void File_WriteInt(sc_File *fil, int towrite); @@ -54,7 +57,7 @@ int File_GetError(sc_File *fil); int File_GetPosition(sc_File *fil); struct ScriptFileHandle { - Stream *stream; + Stream *stream; int32_t handle; }; extern ScriptFileHandle valid_handles[MAX_OPEN_SCRIPT_FILES + 1]; @@ -64,4 +67,6 @@ ScriptFileHandle *check_valid_file_handle_ptr(Stream *stream_ptr, const char *op ScriptFileHandle *check_valid_file_handle_int32(int32_t handle, const char *operation_name); Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_name); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h index 5466ead57ac0..a977f74421c1 100644 --- a/engines/ags/engine/ac/game.h +++ b/engines/ags/engine/ac/game.h @@ -33,13 +33,16 @@ #include "main/game_file.h" #include "util/string.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Bitmap; class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define RAGMODE_PRESERVEGLOBALINT 1 @@ -203,4 +206,6 @@ extern unsigned int loopcounter; extern void set_loop_counter(unsigned int new_counter); extern int game_paused; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/gamesetup.h b/engines/ags/engine/ac/gamesetup.h index 9bb46ca09912..45c38211325e 100644 --- a/engines/ags/engine/ac/gamesetup.h +++ b/engines/ags/engine/ac/gamesetup.h @@ -26,6 +26,7 @@ #include "main/graphics_mode.h" #include "util/string.h" +namespace AGS3 { // Mouse control activation type enum MouseControlWhen { @@ -89,4 +90,6 @@ struct GameSetup { // Perhaps it makes sense to separate those two group of vars at some point. extern GameSetup usetup; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h index a594e5391ac5..acf3d4845243 100644 --- a/engines/ags/engine/ac/gamestate.h +++ b/engines/ags/engine/ac/gamestate.h @@ -36,18 +36,22 @@ #include "util/string.h" #include "ac/timer.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Bitmap; class Stream; typedef std::shared_ptr PBitmap; -} +} // namespace Shared + namespace Engine { struct RestoredData; -} -} +} // namespace Engine +} // namespace AGS using namespace AGS; // FIXME later + struct ScriptViewport; struct ScriptCamera; @@ -56,14 +60,13 @@ struct ScriptCamera; // Savegame data format enum GameStateSvgVersion { kGSSvgVersion_OldFormat = -1, // TODO: remove after old save support is dropped - kGSSvgVersion_Initial = 0, - kGSSvgVersion_350 = 1, - kGSSvgVersion_3509 = 2, - kGSSvgVersion_3510 = 3, + kGSSvgVersion_Initial = 0, + kGSSvgVersion_350 = 1, + kGSSvgVersion_3509 = 2, + kGSSvgVersion_3510 = 3, }; - // Adding to this might need to modify AGSDEFNS.SH and AGSPLUGIN.H struct GameState { int score; // player's current score @@ -220,7 +223,7 @@ struct GameState { int gamma_adjustment; short temporarily_turned_off_character; // Hide Player Charactr ticked short inv_backwards_compatibility; - int *gui_draw_order; + int *gui_draw_order; std::vector do_once_tokens; int text_min_display_time_ms; int ignore_user_input_after_text_timeout_ms; @@ -354,7 +357,7 @@ struct GameState { void ReadQueuedAudioItems_Aligned(Common::Stream *in); void ReadCustomProperties_v340(Common::Stream *in); void WriteCustomProperties_v340(Common::Stream *out) const; - void ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, AGS::Engine::RestoredData &r_data); + void ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, AGS::Engine::RestoredData &r_data); void WriteForSavegame(Common::Stream *out) const; void FreeProperties(); void FreeViewportsAndCameras(); @@ -400,4 +403,6 @@ HorAlignment ReadScriptAlignment(int32_t align); extern GameState play; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_audio.h b/engines/ags/engine/ac/global_audio.h index d30be09dbecd..4c14d539f5fd 100644 --- a/engines/ags/engine/ac/global_audio.h +++ b/engines/ags/engine/ac/global_audio.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBALAUDIO_H #define AGS_ENGINE_AC_GLOBALAUDIO_H +namespace AGS3 { + void StopAmbientSound(int channel); void PlayAmbientSound(int channel, int sndnum, int vol, int x, int y); int IsChannelPlaying(int chan); @@ -73,4 +75,6 @@ void stop_voice_speech(); // Stop non-blocking voice-over and revert audio volumes if necessary void stop_voice_nonblocking(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_button.h b/engines/ags/engine/ac/global_button.h index ee7fb5dbb4e3..dbda06206349 100644 --- a/engines/ags/engine/ac/global_button.h +++ b/engines/ags/engine/ac/global_button.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_GLOBALBUTTON_H #define AGS_ENGINE_AC_GLOBALBUTTON_H +namespace AGS3 { + void SetButtonText(int guin, int objn, const char *newtx); void AnimateButton(int guin, int objn, int view, int loop, int speed, int repeat); int GetButtonPic(int guin, int objn, int ptype); void SetButtonPic(int guin, int objn, int ptype, int slotn); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_character.h b/engines/ags/engine/ac/global_character.h index 213df919d261..ac9acb19d5b7 100644 --- a/engines/ags/engine/ac/global_character.h +++ b/engines/ags/engine/ac/global_character.h @@ -25,6 +25,8 @@ #include "ac/characterinfo.h" +namespace AGS3 { + void StopMoving(int chaa); void ReleaseCharacterView(int chat); void MoveToWalkableArea(int charid); @@ -89,4 +91,6 @@ void __sc_displayspeech(int chid, const char *text); void DisplaySpeechAt(int xx, int yy, int wii, int aschar, const char *spch); int DisplaySpeechBackground(int charid, const char *speel); +} // nemspace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_datetime.h b/engines/ags/engine/ac/global_datetime.h index 89970236619e..6edcbe230753 100644 --- a/engines/ags/engine/ac/global_datetime.h +++ b/engines/ags/engine/ac/global_datetime.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBALDATETIME_H #define AGS_ENGINE_AC_GLOBALDATETIME_H -int sc_GetTime(int whatti) ; +namespace AGS3 { + +int sc_GetTime(int whatti); int GetRawTime(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_debug.h b/engines/ags/engine/ac/global_debug.h index 6019593cbd3d..cf2bc81a2faf 100644 --- a/engines/ags/engine/ac/global_debug.h +++ b/engines/ags/engine/ac/global_debug.h @@ -26,7 +26,11 @@ #include #include "util/string.h" +namespace AGS3 { + AGS::Common::String GetRuntimeInfo(); void script_debug(int cmdd, int dataa); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_dialog.h b/engines/ags/engine/ac/global_dialog.h index b9733d41019d..6100bd17f9d4 100644 --- a/engines/ags/engine/ac/global_dialog.h +++ b/engines/ags/engine/ac/global_dialog.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_GLOBALDIALOG_H #define AGS_ENGINE_AC_GLOBALDIALOG_H +namespace AGS3 { + void RunDialog(int tum); int GetDialogOption(int dlg, int opt); void SetDialogOption(int dlg, int opt, int onoroff, bool dlg_script = false); void StopDialog(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_display.h b/engines/ags/engine/ac/global_display.h index 8f6f1397ac2c..29652e893bbd 100644 --- a/engines/ags/engine/ac/global_display.h +++ b/engines/ags/engine/ac/global_display.h @@ -25,6 +25,8 @@ #include "ac/speech.h" +namespace AGS3 { + void Display(const char *texx, ...); // applies translation void DisplaySimple(const char *text); // does not apply translation void DisplayAt(int xxp, int yyp, int widd, const char *text); @@ -39,4 +41,6 @@ void SetSpeechStyle(int newstyle); void SetSkipSpeech(SkipSpeechStyle newval); SkipSpeechStyle GetSkipSpeech(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_drawingsurface.h b/engines/ags/engine/ac/global_drawingsurface.h index e9b2626e86a3..05a1ce714528 100644 --- a/engines/ags/engine/ac/global_drawingsurface.h +++ b/engines/ags/engine/ac/global_drawingsurface.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBALDRAWINGSURFACE_H #define AGS_ENGINE_AC_GLOBALDRAWINGSURFACE_H +namespace AGS3 { + void RawSaveScreen(); // RawRestoreScreen: copy backup bitmap back to screen; we // deliberately don't free the Common::Bitmap *cos they can multiple restore @@ -46,4 +48,6 @@ void RawDrawCircle(int xx, int yy, int rad); void RawDrawRectangle(int x1, int y1, int x2, int y2); void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_dynamicsprite.h b/engines/ags/engine/ac/global_dynamicsprite.h index db6fe2d06dce..a2948049170d 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.h +++ b/engines/ags/engine/ac/global_dynamicsprite.h @@ -23,6 +23,10 @@ #ifndef AGS_ENGINE_AC_GLOBAL_DYNAMICSPRITE_H #define AGS_ENGINE_AC_GLOBAL_DYNAMICSPRITE_H +namespace AGS3 { + int LoadImageFile(const char *filename); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_file.h b/engines/ags/engine/ac/global_file.h index 3e58cfdc1035..78afe03a0d31 100644 --- a/engines/ags/engine/ac/global_file.h +++ b/engines/ags/engine/ac/global_file.h @@ -25,11 +25,13 @@ #include "util/file.h" +namespace AGS3 { namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later int32_t FileOpen(const char *fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); @@ -47,4 +49,6 @@ char FileReadRawChar(int32_t handle); int FileReadRawInt(int32_t handle); void FileWriteRawChar(int32_t handle, int chartoWrite); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h index d777fafef306..d60b9d83295d 100644 --- a/engines/ags/engine/ac/global_game.h +++ b/engines/ags/engine/ac/global_game.h @@ -24,6 +24,9 @@ #define AGS_ENGINE_AC_GLOBAL_GAME_H #include "util/string.h" + +namespace AGS3 { + using namespace AGS; // FIXME later void GiveScore(int amnt); @@ -90,4 +93,6 @@ int WaitMouse(int nloops); int WaitMouseKey(int nloops); void SkipWait(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_gui.h b/engines/ags/engine/ac/global_gui.h index 3539a5cf1df4..f08863caab81 100644 --- a/engines/ags/engine/ac/global_gui.h +++ b/engines/ags/engine/ac/global_gui.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_GUI_H #define AGS_ENGINE_AC_GLOBAL_GUI_H +namespace AGS3 { + // IsGUIOn tells whether GUI is actually displayed on screen right now int IsGUIOn(int guinum); // This is an internal script function, and is undocumented. @@ -56,4 +58,6 @@ int GetGUIObjectAt(int xx, int yy); int GetGUIAt(int xx, int yy); void SetTextWindowGUI(int guinum); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_hotspot.h b/engines/ags/engine/ac/global_hotspot.h index 36eb1846709d..b4b800b758d8 100644 --- a/engines/ags/engine/ac/global_hotspot.h +++ b/engines/ags/engine/ac/global_hotspot.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_HOTSPOT_H #define AGS_ENGINE_AC_GLOBAL_HOTSPOT_H +namespace AGS3 { + void DisableHotspot(int hsnum); void EnableHotspot(int hsnum); int GetHotspotPointX(int hotspot); @@ -36,5 +38,6 @@ void RunHotspotInteraction(int hotspothere, int mood); int GetHotspotProperty(int hss, const char *property); void GetHotspotPropertyText(int item, const char *property, char *bufer); +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/global_inventoryitem.h b/engines/ags/engine/ac/global_inventoryitem.h index 332a59cf06ff..11c6b9ccfacc 100644 --- a/engines/ags/engine/ac/global_inventoryitem.h +++ b/engines/ags/engine/ac/global_inventoryitem.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_INVENTORYITEM_H #define AGS_ENGINE_AC_GLOBAL_INVENTORYITEM_H +namespace AGS3 { + void set_inv_item_pic(int invi, int piccy); void SetInvItemName(int invi, const char *newName); int GetInvAt(int xxx, int yyy); @@ -33,4 +35,6 @@ int IsInventoryInteractionAvailable(int item, int mood); int GetInvProperty(int item, const char *property); void GetInvPropertyText(int item, const char *property, char *bufer); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_invwindow.h b/engines/ags/engine/ac/global_invwindow.h index 7e952fd0e605..ad79a6c6f335 100644 --- a/engines/ags/engine/ac/global_invwindow.h +++ b/engines/ags/engine/ac/global_invwindow.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBAL_INVWINDOW_H #define AGS_ENGINE_AC_GLOBAL_INVWINDOW_H +namespace AGS3 { + void sc_invscreen(); void SetInvDimensions(int ww, int hh); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_label.h b/engines/ags/engine/ac/global_label.h index 5c75f8b08fba..74174785042c 100644 --- a/engines/ags/engine/ac/global_label.h +++ b/engines/ags/engine/ac/global_label.h @@ -23,8 +23,12 @@ #ifndef AGS_ENGINE_AC_GLOBAL_LABEL_H #define AGS_ENGINE_AC_GLOBAL_LABEL_H -void SetLabelColor(int guin, int objn, int colr); -void SetLabelText(int guin, int objn, const char *newtx); -void SetLabelFont(int guin, int objn, int fontnum); +namespace AGS3 { + +void SetLabelColor(int guin, int objn, int colr); +void SetLabelText(int guin, int objn, const char *newtx); +void SetLabelFont(int guin, int objn, int fontnum); + +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/global_listbox.h b/engines/ags/engine/ac/global_listbox.h index 2d781cb425ce..7ca1b79c3645 100644 --- a/engines/ags/engine/ac/global_listbox.h +++ b/engines/ags/engine/ac/global_listbox.h @@ -23,15 +23,19 @@ #ifndef AGS_ENGINE_AC_GLOBAL_LISTBOX_H #define AGS_ENGINE_AC_GLOBAL_LISTBOX_H +namespace AGS3 { + void ListBoxClear(int guin, int objn); void ListBoxAdd(int guin, int objn, const char *newitem); void ListBoxRemove(int guin, int objn, int itemIndex); int ListBoxGetSelected(int guin, int objn); int ListBoxGetNumItems(int guin, int objn); -char *ListBoxGetItemText(int guin, int objn, int item, char *buffer); +char *ListBoxGetItemText(int guin, int objn, int item, char *buffer); void ListBoxSetSelected(int guin, int objn, int newsel); void ListBoxSetTopItem(int guin, int objn, int item); int ListBoxSaveGameList(int guin, int objn); void ListBoxDirList(int guin, int objn, const char *filemask); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_mouse.h b/engines/ags/engine/ac/global_mouse.h index ecf01627430d..6e49d30674e1 100644 --- a/engines/ags/engine/ac/global_mouse.h +++ b/engines/ags/engine/ac/global_mouse.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBAL_MOUSE_H #define AGS_ENGINE_AC_GLOBAL_MOUSE_H +namespace AGS3 { + void HideMouseCursor(); void ShowMouseCursor(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_object.h b/engines/ags/engine/ac/global_object.h index 9e0e94778505..05e521356efe 100644 --- a/engines/ags/engine/ac/global_object.h +++ b/engines/ags/engine/ac/global_object.h @@ -23,11 +23,13 @@ #ifndef AGS_ENGINE_AC_GLOBAL_OBJECT_H #define AGS_ENGINE_AC_GLOBAL_OBJECT_H +namespace AGS3 { namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later // TODO: merge with other Rect declared in bitmap unit @@ -77,4 +79,6 @@ void GetObjectPropertyText(int item, const char *property, char *bufer); Common::Bitmap *GetObjectImage(int obj, int *isFlipped); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_overlay.h b/engines/ags/engine/ac/global_overlay.h index 5b2e9c8439c2..2b11c972cf75 100644 --- a/engines/ags/engine/ac/global_overlay.h +++ b/engines/ags/engine/ac/global_overlay.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBALOVERLAY_H #define AGS_ENGINE_AC_GLOBALOVERLAY_H +namespace AGS3 { + void RemoveOverlay(int ovrid); int CreateGraphicOverlay(int xx, int yy, int slott, int trans); int CreateTextOverlayCore(int xx, int yy, int wii, int fontid, int text_color, const char *text, int disp_type, int allowShrink); @@ -31,4 +33,6 @@ void SetTextOverlay(int ovrid, int xx, int yy, int wii, int fontid, int text_col void MoveOverlay(int ovrid, int newx, int newy); int IsOverlayValid(int ovrid); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_palette.h b/engines/ags/engine/ac/global_palette.h index 13ff58ab570d..dcfb20b34eb9 100644 --- a/engines/ags/engine/ac/global_palette.h +++ b/engines/ags/engine/ac/global_palette.h @@ -23,8 +23,12 @@ #ifndef AGS_ENGINE_AC_GLOBAL_PALETTE_H #define AGS_ENGINE_AC_GLOBAL_PALETTE_H +namespace AGS3 { + void CyclePalette(int strt, int eend); void SetPalRGB(int inndx, int rr, int gg, int bb); void UpdatePalette(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_parser.h b/engines/ags/engine/ac/global_parser.h index b3e99bd5e4f9..522b871dd168 100644 --- a/engines/ags/engine/ac/global_parser.h +++ b/engines/ags/engine/ac/global_parser.h @@ -23,6 +23,10 @@ #ifndef AGS_ENGINE_AC_GLOBAL_PARSER_H #define AGS_ENGINE_AC_GLOBAL_PARSER_H +namespace AGS3 { + int SaidUnknownWord(char *buffer); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_plugin.h b/engines/ags/engine/ac/global_plugin.h index 193c1dc99d45..308f2f148e8e 100644 --- a/engines/ags/engine/ac/global_plugin.h +++ b/engines/ags/engine/ac/global_plugin.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBAL_PLUGIN_H #define AGS_ENGINE_AC_GLOBAL_PLUGIN_H +namespace AGS3 { + void PluginSimulateMouseClick(int pluginButtonID); bool RegisterPluginStubs(const char *name); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_record.h b/engines/ags/engine/ac/global_record.h index b459b0c15e22..eeaa6849b85a 100644 --- a/engines/ags/engine/ac/global_record.h +++ b/engines/ags/engine/ac/global_record.h @@ -23,6 +23,10 @@ #ifndef AGS_ENGINE_AC_GLOBAL_RECORD_H #define AGS_ENGINE_AC_GLOBAL_RECORD_H +namespace AGS3 { + void scStartRecording(int keyToStop); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_region.h b/engines/ags/engine/ac/global_region.h index 205a45f90cd2..93fec2cb0c50 100644 --- a/engines/ags/engine/ac/global_region.h +++ b/engines/ags/engine/ac/global_region.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_REGION_H #define AGS_ENGINE_AC_GLOBAL_REGION_H +namespace AGS3 { + // Gets region ID at the given room coordinates; // if region is disabled or non-existing, returns 0 (no area) int GetRegionIDAtRoom(int xxx, int yyy); @@ -34,4 +36,6 @@ void DisableGroundLevelAreas(int alsoEffects); void EnableGroundLevelAreas(); void RunRegionInteraction(int regnum, int mood); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_room.h b/engines/ags/engine/ac/global_room.h index 7bf95ed306fe..178957a73eba 100644 --- a/engines/ags/engine/ac/global_room.h +++ b/engines/ags/engine/ac/global_room.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_ROOM_H #define AGS_ENGINE_AC_GLOBAL_ROOM_H +namespace AGS3 { + void SetAmbientTint(int red, int green, int blue, int opacity, int luminance); void SetAmbientLightLevel(int light_level); void NewRoom(int nrnum); @@ -35,6 +37,8 @@ int HasBeenToRoom(int roomnum); void GetRoomPropertyText(const char *property, char *bufer); void SetBackgroundFrame(int frnum); -int GetBackgroundFrame() ; +int GetBackgroundFrame(); + +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/global_screen.h b/engines/ags/engine/ac/global_screen.h index 1807e115f157..feeb90dcc5cd 100644 --- a/engines/ags/engine/ac/global_screen.h +++ b/engines/ags/engine/ac/global_screen.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_SCREEN_H #define AGS_ENGINE_AC_GLOBAL_SCREEN_H +namespace AGS3 { + void FlipScreen(int amount); void ShakeScreen(int severe); void ShakeScreenBackground(int delay, int amount, int length); @@ -33,4 +35,6 @@ void SetNextScreenTransition(int newtrans); void SetFadeColor(int red, int green, int blue); void FadeIn(int sppd); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_slider.h b/engines/ags/engine/ac/global_slider.h index bef7247ac0b0..88fa05f26536 100644 --- a/engines/ags/engine/ac/global_slider.h +++ b/engines/ags/engine/ac/global_slider.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBAL_SLIDER_H #define AGS_ENGINE_AC_GLOBAL_SLIDER_H +namespace AGS3 { + void SetSliderValue(int guin, int objn, int valn); int GetSliderValue(int guin, int objn); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_string.h b/engines/ags/engine/ac/global_string.h index 88ce8319f0c5..370acf6c4908 100644 --- a/engines/ags/engine/ac/global_string.h +++ b/engines/ags/engine/ac/global_string.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_STRING_H #define AGS_ENGINE_AC_GLOBAL_STRING_H +namespace AGS3 { + int StrGetCharAt(const char *strin, int posn); void StrSetCharAt(char *strin, int posn, int nchar); void _sc_strcat(char *s1, const char *s2); @@ -30,4 +32,6 @@ void _sc_strlower(char *desbuf); void _sc_strupper(char *desbuf); void _sc_strcpy(char *destt, const char *text); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_textbox.h b/engines/ags/engine/ac/global_textbox.h index bd95b85c4eff..c1ecef739953 100644 --- a/engines/ags/engine/ac/global_textbox.h +++ b/engines/ags/engine/ac/global_textbox.h @@ -23,8 +23,12 @@ #ifndef AGS_ENGINE_AC_GLOBAL_TEXTBOX_H #define AGS_ENGINE_AC_GLOBAL_TEXTBOX_H +namespace AGS3 { + void SetTextBoxFont(int guin, int objn, int fontnum); void GetTextBoxText(int guin, int objn, char *txbuf); void SetTextBoxText(int guin, int objn, const char *txbuf); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_timer.h b/engines/ags/engine/ac/global_timer.h index 17b0b78a0486..380573c72384 100644 --- a/engines/ags/engine/ac/global_timer.h +++ b/engines/ags/engine/ac/global_timer.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBAL_TIMER_H #define AGS_ENGINE_AC_GLOBAL_TIMER_H +namespace AGS3 { + void script_SetTimer(int tnum, int timeout); int IsTimerExpired(int tnum); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_translation.h b/engines/ags/engine/ac/global_translation.h index 4c2d7a54eb49..8d761d80824f 100644 --- a/engines/ags/engine/ac/global_translation.h +++ b/engines/ags/engine/ac/global_translation.h @@ -23,8 +23,12 @@ #ifndef AGS_ENGINE_AC_GLOBAL_TRANSLATION_H #define AGS_ENGINE_AC_GLOBAL_TRANSLATION_H +namespace AGS3 { + const char *get_translation(const char *text); int IsTranslationAvailable(); int GetTranslationName(char *buffer); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_video.h b/engines/ags/engine/ac/global_video.h index 3996ccad9ba8..907252bdb919 100644 --- a/engines/ags/engine/ac/global_video.h +++ b/engines/ags/engine/ac/global_video.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_AC_GLOBAL_VIDEO_H #define AGS_ENGINE_AC_GLOBAL_VIDEO_H +namespace AGS3 { + void scrPlayVideo(const char *name, int skip, int flags); void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_viewframe.h b/engines/ags/engine/ac/global_viewframe.h index f06119ba9e3c..b6b221d4b1b1 100644 --- a/engines/ags/engine/ac/global_viewframe.h +++ b/engines/ags/engine/ac/global_viewframe.h @@ -23,6 +23,10 @@ #ifndef AGS_ENGINE_AC_GLOBAL_VIEWFRAME_H #define AGS_ENGINE_AC_GLOBAL_VIEWFRAME_H +namespace AGS3 { + void SetFrameSound(int vii, int loop, int frame, int sound); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_viewport.h b/engines/ags/engine/ac/global_viewport.h index f8bf12179b6e..1a5f656bda43 100644 --- a/engines/ags/engine/ac/global_viewport.h +++ b/engines/ags/engine/ac/global_viewport.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_AC_GLOBAL_VIEWPORT_H #define AGS_ENGINE_AC_GLOBAL_VIEWPORT_H +namespace AGS3 { + void SetViewport(int offsx, int offsy); void ReleaseViewport(); int GetViewportX(); int GetViewportY(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_walkablearea.h b/engines/ags/engine/ac/global_walkablearea.h index 837f677fccc8..b69cbc1fa662 100644 --- a/engines/ags/engine/ac/global_walkablearea.h +++ b/engines/ags/engine/ac/global_walkablearea.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_GLOBAL_WALKABLEAREA_H #define AGS_ENGINE_AC_GLOBAL_WALKABLEAREA_H +namespace AGS3 { + int GetScalingAt(int x, int y); void SetAreaScaling(int area, int min, int max); void RemoveWalkableArea(int areanum); @@ -34,4 +36,6 @@ int GetWalkableAreaAtRoom(int x, int y); // if area is disabled or non-existing, returns 0 (no area) int GetWalkableAreaAtScreen(int x, int y); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/global_walkbehind.h b/engines/ags/engine/ac/global_walkbehind.h index 0243a3a1ee36..f36404a7c6a6 100644 --- a/engines/ags/engine/ac/global_walkbehind.h +++ b/engines/ags/engine/ac/global_walkbehind.h @@ -23,6 +23,10 @@ #ifndef AGS_ENGINE_AC_GLOBAL_WALKBEHIND_H #define AGS_ENGINE_AC_GLOBAL_WALKBEHIND_H +namespace AGS3 { + void SetWalkBehindBase(int wa, int bl); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/gui.h b/engines/ags/engine/ac/gui.h index 9a2eb055cc39..1cb7629dfde3 100644 --- a/engines/ags/engine/ac/gui.h +++ b/engines/ags/engine/ac/gui.h @@ -26,6 +26,8 @@ #include "ac/dynobj/scriptgui.h" #include "gui/guimain.h" +namespace AGS3 { + using AGS::Common::GUIMain; using AGS::Common::GUIObject; @@ -90,4 +92,6 @@ extern int ifacepopped; extern int ifacepopped; extern int mouse_on_iface; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/guicontrol.h b/engines/ags/engine/ac/guicontrol.h index b0527ebfb5cf..1f8d60ef3da5 100644 --- a/engines/ags/engine/ac/guicontrol.h +++ b/engines/ags/engine/ac/guicontrol.h @@ -32,6 +32,8 @@ #include "gui/guitextbox.h" #include "ac/dynobj/scriptgui.h" +namespace AGS3 { + using AGS::Common::GUIObject; using AGS::Common::GUIButton; using AGS::Common::GUIInvWindow; @@ -40,7 +42,7 @@ using AGS::Common::GUIListBox; using AGS::Common::GUISlider; using AGS::Common::GUITextBox; -GUIObject *GetGUIControlAtLocation(int xx, int yy); +GUIObject *GetGUIControlAtLocation(int xx, int yy); int GUIControl_GetVisible(GUIObject *guio); void GUIControl_SetVisible(GUIObject *guio, int visible); int GUIControl_GetClickable(GUIObject *guio); @@ -48,12 +50,12 @@ void GUIControl_SetClickable(GUIObject *guio, int enabled); int GUIControl_GetEnabled(GUIObject *guio); void GUIControl_SetEnabled(GUIObject *guio, int enabled); int GUIControl_GetID(GUIObject *guio); -ScriptGUI *GUIControl_GetOwningGUI(GUIObject *guio); -GUIButton *GUIControl_GetAsButton(GUIObject *guio); +ScriptGUI *GUIControl_GetOwningGUI(GUIObject *guio); +GUIButton *GUIControl_GetAsButton(GUIObject *guio); GUIInvWindow *GUIControl_GetAsInvWindow(GUIObject *guio); -GUILabel *GUIControl_GetAsLabel(GUIObject *guio); +GUILabel *GUIControl_GetAsLabel(GUIObject *guio); GUIListBox *GUIControl_GetAsListBox(GUIObject *guio); -GUISlider *GUIControl_GetAsSlider(GUIObject *guio); +GUISlider *GUIControl_GetAsSlider(GUIObject *guio); GUITextBox *GUIControl_GetAsTextBox(GUIObject *guio); int GUIControl_GetX(GUIObject *guio); void GUIControl_SetX(GUIObject *guio, int xx); @@ -70,4 +72,6 @@ void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit); void GUIControl_SendToBack(GUIObject *guio); void GUIControl_BringToFront(GUIObject *guio); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h index 226ab4ef6d78..a495b0df2fe7 100644 --- a/engines/ags/engine/ac/hotspot.h +++ b/engines/ags/engine/ac/hotspot.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scripthotspot.h" +namespace AGS3 { + void Hotspot_SetEnabled(ScriptHotspot *hss, int newval); int Hotspot_GetEnabled(ScriptHotspot *hss); int Hotspot_GetID(ScriptHotspot *hss); @@ -44,4 +46,6 @@ const char *Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property); // if hotspot is disabled or non-existing, returns 0 (no area) int get_hotspot_at(int xpp, int ypp); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/inventoryitem.h b/engines/ags/engine/ac/inventoryitem.h index 6159b1e9ddea..991526059df6 100644 --- a/engines/ags/engine/ac/inventoryitem.h +++ b/engines/ags/engine/ac/inventoryitem.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scriptinvitem.h" +namespace AGS3 { + void InventoryItem_SetCursorGraphic(ScriptInvItem *iitem, int newSprite); int InventoryItem_GetCursorGraphic(ScriptInvItem *iitem); void InventoryItem_SetGraphic(ScriptInvItem *iitem, int piccy); @@ -42,4 +44,6 @@ const char *InventoryItem_GetTextProperty(ScriptInvItem *scii, const char *prope void set_inv_item_cursorpic(int invItemId, int piccy); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/invwindow.h b/engines/ags/engine/ac/invwindow.h index 4e46eec4720d..29f9c3ace268 100644 --- a/engines/ags/engine/ac/invwindow.h +++ b/engines/ags/engine/ac/invwindow.h @@ -27,10 +27,12 @@ #include "ac/dynobj/scriptinvitem.h" #include "gui/guiinv.h" +namespace AGS3 { + using AGS::Common::GUIInvWindow; void InvWindow_SetCharacterToUse(GUIInvWindow *guii, CharacterInfo *chaa); -CharacterInfo *InvWindow_GetCharacterToUse(GUIInvWindow *guii); +CharacterInfo *InvWindow_GetCharacterToUse(GUIInvWindow *guii); void InvWindow_SetItemWidth(GUIInvWindow *guii, int newwidth); int InvWindow_GetItemWidth(GUIInvWindow *guii); void InvWindow_SetItemHeight(GUIInvWindow *guii, int newhit); @@ -42,7 +44,7 @@ int InvWindow_GetItemCount(GUIInvWindow *guii); int InvWindow_GetRowCount(GUIInvWindow *guii); void InvWindow_ScrollDown(GUIInvWindow *guii); void InvWindow_ScrollUp(GUIInvWindow *guii); -ScriptInvItem *InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index); +ScriptInvItem *InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index); //============================================================================= @@ -50,4 +52,6 @@ int offset_over_inv(GUIInvWindow *inv); // NOTE: This function is valid for AGS 2.72 and lower int invscreen(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/keycode.h b/engines/ags/engine/ac/keycode.h index 63c944bad889..ddfcf071d6a9 100644 --- a/engines/ags/engine/ac/keycode.h +++ b/engines/ags/engine/ac/keycode.h @@ -25,6 +25,8 @@ #include "core/platform.h" +namespace AGS3 { + #define EXTENDED_KEY_CODE ('\0') #define EXTENDED_KEY_CODE_MACOS ('?') @@ -176,4 +178,6 @@ int GetKeyForKeyPressCb(int keycode); // Returns -1 if not found. int PlatformKeyFromAgsKey(int key); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/label.h b/engines/ags/engine/ac/label.h index 687c77c0f886..a1102b8d0f88 100644 --- a/engines/ags/engine/ac/label.h +++ b/engines/ags/engine/ac/label.h @@ -25,6 +25,8 @@ #include "gui/guilabel.h" +namespace AGS3 { + using AGS::Common::GUILabel; const char *Label_GetText_New(GUILabel *labl); @@ -35,4 +37,6 @@ void Label_SetColor(GUILabel *labl, int colr); int Label_GetFont(GUILabel *labl); void Label_SetFont(GUILabel *guil, int fontnum); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/lipsync.h b/engines/ags/engine/ac/lipsync.h index 6508c6813f6d..d5ef6e2bbf5e 100644 --- a/engines/ags/engine/ac/lipsync.h +++ b/engines/ags/engine/ac/lipsync.h @@ -23,11 +23,15 @@ #ifndef AGS_ENGINE_AC_LIPSYNC_H #define AGS_ENGINE_AC_LIPSYNC_H +namespace AGS3 { + struct SpeechLipSyncLine { char filename[14]; - int *endtimeoffs; + int *endtimeoffs; short *frame; short numPhonemes; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/listbox.h b/engines/ags/engine/ac/listbox.h index c0243a22776a..96267dffd142 100644 --- a/engines/ags/engine/ac/listbox.h +++ b/engines/ags/engine/ac/listbox.h @@ -25,6 +25,8 @@ #include "gui/guilistbox.h" +namespace AGS3 { + using AGS::Common::GUIListBox; int ListBox_AddItem(GUIListBox *lbb, const char *text); @@ -34,7 +36,7 @@ void ListBox_FillDirList(GUIListBox *listbox, const char *filemask); int ListBox_GetSaveGameSlots(GUIListBox *listbox, int index); int ListBox_FillSaveGameList(GUIListBox *listbox); int ListBox_GetItemAtLocation(GUIListBox *listbox, int x, int y); -char *ListBox_GetItemText(GUIListBox *listbox, int index, char *buffer); +char *ListBox_GetItemText(GUIListBox *listbox, int index, char *buffer); const char *ListBox_GetItems(GUIListBox *listbox, int index); void ListBox_SetItemText(GUIListBox *listbox, int index, const char *newtext); void ListBox_RemoveItem(GUIListBox *listbox, int itemIndex); @@ -55,4 +57,6 @@ void ListBox_ScrollUp(GUIListBox *listbox); GUIListBox *is_valid_listbox(int guin, int objn); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/math.h b/engines/ags/engine/ac/math.h index bd3d3f7f1e1a..07e3ae45b108 100644 --- a/engines/ags/engine/ac/math.h +++ b/engines/ags/engine/ac/math.h @@ -25,6 +25,8 @@ #include "core/types.h" +namespace AGS3 { + enum RoundDirections { eRoundDown = 0, eRoundNearest = 1, @@ -57,4 +59,6 @@ float Math_Sqrt(float value); int __Rand(int upto); #define Random __Rand +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/mouse.h b/engines/ags/engine/ac/mouse.h index 02893e2619e0..455df017f443 100644 --- a/engines/ags/engine/ac/mouse.h +++ b/engines/ags/engine/ac/mouse.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scriptmouse.h" +namespace AGS3 { + #define DOMOUSE_UPDATE 0 #define DOMOUSE_ENABLE 1 #define DOMOUSE_DISABLE 2 @@ -78,4 +80,6 @@ extern ScriptMouse scmouse; extern int cur_mode; extern int cur_cursor; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h index 8bde626f1838..45334055180b 100644 --- a/engines/ags/engine/ac/movelist.h +++ b/engines/ags/engine/ac/movelist.h @@ -26,12 +26,14 @@ #include "util/wgt2allg.h" // fixed type #include "game/savegame.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS using namespace AGS; // FIXME later #define MAXNEEDSTAGES 256 @@ -52,4 +54,6 @@ struct MoveList { void WriteToFile(Common::Stream *out); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/object.h b/engines/ags/engine/ac/object.h index 11f5d31b57bd..fc02fafc89f8 100644 --- a/engines/ags/engine/ac/object.h +++ b/engines/ags/engine/ac/object.h @@ -34,11 +34,14 @@ #include "ac/common_defines.h" #include "ac/dynobj/scriptobject.h" +namespace AGS3 { + namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later extern AGS_INLINE int is_valid_object(int obtest); @@ -100,4 +103,6 @@ int is_pos_in_sprite(int xx, int yy, int arx, int ary, Common::Bitmap *sprit // X and Y are ROOM coordinates int check_click_on_object(int roomx, int roomy, int mood); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/objectcache.h b/engines/ags/engine/ac/objectcache.h index ba7a323ebea5..6621698ed27e 100644 --- a/engines/ags/engine/ac/objectcache.h +++ b/engines/ags/engine/ac/objectcache.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_OBJECTCACHE_H #define AGS_ENGINE_AC_OBJECTCACHE_H +namespace AGS3 { + // stores cached object info struct ObjectCache { Common::Bitmap *image; @@ -33,4 +35,6 @@ struct ObjectCache { int xwas, ywas; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h index d5628fcc0e91..958a8b8f3379 100644 --- a/engines/ags/engine/ac/overlay.h +++ b/engines/ags/engine/ac/overlay.h @@ -27,11 +27,14 @@ #include "ac/screenoverlay.h" #include "ac/dynobj/scriptoverlay.h" +namespace AGS3 { + namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later void Overlay_Remove(ScriptOverlay *sco); @@ -58,4 +61,6 @@ extern int is_text_overlay; // blocking text overlay on screen extern std::vector screenover; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/parser.h b/engines/ags/engine/ac/parser.h index 2f7431ac07f2..48b4f77f7b71 100644 --- a/engines/ags/engine/ac/parser.h +++ b/engines/ags/engine/ac/parser.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_PARSER_H #define AGS_ENGINE_AC_PARSER_H +namespace AGS3 { + int Parser_FindWordID(const char *wordToFind); const char *Parser_SaidUnknownWord(); void ParseText(const char *text); @@ -35,4 +37,6 @@ int is_valid_word_char(char theChar); int FindMatchingMultiWordWord(char *thisword, const char **text); int parse_sentence(const char *src_text, int *numwords, short *wordarray, short *compareto, int comparetonum); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h index 3761f15dac54..e8768e936d53 100644 --- a/engines/ags/engine/ac/path_helper.h +++ b/engines/ags/engine/ac/path_helper.h @@ -31,6 +31,8 @@ #include "util/string.h" +namespace AGS3 { + using AGS::Common::String; // Filepath tokens, which are replaced by platform-specific directory names @@ -81,4 +83,6 @@ String get_audio_install_dir(); String get_voice_install_dir(); void get_install_dir_path(char *buffer, const char *fileName); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h index 44bc30ffb368..ba829662a53c 100644 --- a/engines/ags/engine/ac/properties.h +++ b/engines/ags/engine/ac/properties.h @@ -25,6 +25,8 @@ #include "game/customproperties.h" +namespace AGS3 { + using AGS::Common::StringIMap; // Getting a property value requires static and runtime property maps. @@ -39,4 +41,6 @@ const char *get_text_property_dynamic_string(const StringIMap &st_prop, const St bool set_int_property(StringIMap &rt_prop, const char *property, int value); bool set_text_property(StringIMap &rt_prop, const char *property, const char *value); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/region.h b/engines/ags/engine/ac/region.h index 49a9688ed2ee..a5db946f130d 100644 --- a/engines/ags/engine/ac/region.h +++ b/engines/ags/engine/ac/region.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scriptregion.h" +namespace AGS3 { + ScriptRegion *GetRegionAtRoom(int xx, int yy); void Region_SetLightLevel(ScriptRegion *ssr, int brightness); int Region_GetLightLevel(ScriptRegion *ssr); @@ -42,4 +44,6 @@ void Region_RunInteraction(ScriptRegion *ssr, int mood); void generate_light_table(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index faeac1760b44..02bc1b1592c1 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_RICHGAMEMEDIA_H #define AGS_ENGINE_AC_RICHGAMEMEDIA_H +namespace AGS3 { + // Windows Vista Rich Save Games, modified to be platform-agnostic #define RM_MAXLENGTH 1024 @@ -32,8 +34,9 @@ namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #pragma pack(push) @@ -56,4 +59,6 @@ typedef struct _RICH_GAME_MEDIA_HEADER { } RICH_GAME_MEDIA_HEADER; #pragma pack(pop) +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h index 0c3149e574ac..4b3e5789d300 100644 --- a/engines/ags/engine/ac/room.h +++ b/engines/ags/engine/ac/room.h @@ -28,6 +28,8 @@ #include "script/runtimescriptvalue.h" #include "game/roomstruct.h" +namespace AGS3 { + ScriptDrawingSurface *Room_GetDrawingSurfaceForBackground(int backgroundNumber); ScriptDrawingSurface *Room_GetDrawingSurfaceForMask(RoomAreaMask mask); int Room_GetObjectCount(); @@ -76,4 +78,6 @@ void convert_move_path_to_room_resolution(MoveList *ml); extern AGS::Common::RoomStruct thisroom; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/roomobject.h b/engines/ags/engine/ac/roomobject.h index 22dce65a76d8..2d8111b99be9 100644 --- a/engines/ags/engine/ac/roomobject.h +++ b/engines/ags/engine/ac/roomobject.h @@ -25,11 +25,14 @@ #include "ac/common_defines.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later // IMPORTANT: this struct is restricted by plugin API! @@ -72,4 +75,6 @@ struct RoomObject { void WriteToFile(Common::Stream *out) const; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h index 70e4701865fa..a00799e05c41 100644 --- a/engines/ags/engine/ac/roomstatus.h +++ b/engines/ags/engine/ac/roomstatus.h @@ -28,12 +28,15 @@ #include "game/interactions.h" #include "util/string_types.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using AGS::Common::Stream; using AGS::Common::Interaction; @@ -47,8 +50,8 @@ struct RoomStatus { int tsdatasize; char *tsdata; Interaction intrHotspot[MAX_ROOM_HOTSPOTS]; - Interaction intrObject [MAX_ROOM_OBJECTS]; - Interaction intrRegion [MAX_ROOM_REGIONS]; + Interaction intrObject[MAX_ROOM_OBJECTS]; + Interaction intrRegion[MAX_ROOM_REGIONS]; Interaction intrRoom; Common::StringIMap roomProps; @@ -86,4 +89,6 @@ RoomStatus *getRoomStatus(int room); bool isRoomStatusValid(int room); void resetRoomStatuses(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h index 17ee1af0abf7..3cef9962fa53 100644 --- a/engines/ags/engine/ac/route_finder.h +++ b/engines/ags/engine/ac/route_finder.h @@ -25,12 +25,15 @@ #include "ac/game_version.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + struct MoveList; void init_pathfinder(GameDataVersion game_file_version); @@ -46,4 +49,6 @@ void set_route_move_speed(int speed_x, int speed_y); int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); void calculate_move_stage(MoveList *mlsp, int aaa); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/route_finder_impl.h b/engines/ags/engine/ac/route_finder_impl.h index dcc2a984370e..43600c8fe91e 100644 --- a/engines/ags/engine/ac/route_finder_impl.h +++ b/engines/ags/engine/ac/route_finder_impl.h @@ -25,12 +25,15 @@ #include "ac/game_version.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + struct MoveList; namespace AGS { @@ -53,5 +56,6 @@ void calculate_move_stage(MoveList *mlsp, int aaa); } // namespace RouteFinder } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h index 4da9d5017f06..632038d524dc 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.h +++ b/engines/ags/engine/ac/route_finder_impl_legacy.h @@ -23,12 +23,15 @@ #ifndef AGS_ENGINE_AC_ROUTE_FINDER_IMPL_LEGACY #define AGS_ENGINE_AC_ROUTE_FINDER_IMPL_LEGACY +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + struct MoveList; namespace AGS { @@ -51,5 +54,6 @@ void calculate_move_stage(MoveList *mlsp, int aaa); } // namespace RouteFinderLegacy } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h index 806a2f93d95b..7e2e9d544bb5 100644 --- a/engines/ags/engine/ac/runtime_defines.h +++ b/engines/ags/engine/ac/runtime_defines.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_RUNTIMEDEFINES_H #define AGS_ENGINE_AC_RUNTIMEDEFINES_H +namespace AGS3 { + // xalleg.h pulls in an Allegro-internal definition of MAX_TIMERS which // conflicts with the definition in runtime_defines.h. Forget it. #ifdef MAX_TIMERS @@ -54,13 +56,13 @@ // Legacy (pre 3.5.0) alignment types used in the script API enum LegacyScriptAlignment { - kLegacyScAlignLeft = 1, - kLegacyScAlignCentre = 2, - kLegacyScAlignRight = 3 + kLegacyScAlignLeft = 1, + kLegacyScAlignCentre = 2, + kLegacyScAlignRight = 3 }; const int LegacyMusicMasterVolumeAdjustment = 60; -const int LegacyRoomVolumeFactor = 30; +const int LegacyRoomVolumeFactor = 30; // These numbers were chosen arbitrarily -- the idea is // to make sure that the user gets the parameters the right way round @@ -155,6 +157,8 @@ const int LegacyRoomVolumeFactor = 30; #define MAX_OPEN_SCRIPT_FILES 10 +} // namespace AGS3 + #include "ac/common_defines.h" #endif diff --git a/engines/ags/engine/ac/screen.h b/engines/ags/engine/ac/screen.h index 4c95fb8065f0..e38b092050f3 100644 --- a/engines/ags/engine/ac/screen.h +++ b/engines/ags/engine/ac/screen.h @@ -23,16 +23,19 @@ #ifndef AGS_ENGINE_AC_SCREEN_H #define AGS_ENGINE_AC_SCREEN_H +namespace AGS3 { + namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + namespace AGS { namespace Engine { class IDriverDependantBitmap; -} -} +} // namespace Engine +} // namespace AGS void my_fade_in(PALETTE p, int speed); void current_fade_out_effect(); @@ -41,4 +44,6 @@ AGS::Engine::IDriverDependantBitmap *prepare_screen_for_transition_in(); // Screenshot made in the last room, used during some of the transition effects extern AGS::Common::Bitmap *saved_viewport_bitmap; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/screenoverlay.h b/engines/ags/engine/ac/screenoverlay.h index 751077a0a510..59ed04a899e4 100644 --- a/engines/ags/engine/ac/screenoverlay.h +++ b/engines/ags/engine/ac/screenoverlay.h @@ -25,18 +25,22 @@ #include +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Bitmap; class Stream; -} -} +} // namespace Shared +} // namespace AGS + namespace AGS { namespace Engine { class IDriverDependantBitmap; -} -} +} // namespace Engine +} // namespace AGS + using namespace AGS; // FIXME later @@ -55,4 +59,6 @@ struct ScreenOverlay { void WriteToFile(Common::Stream *out) const; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/slider.h b/engines/ags/engine/ac/slider.h index 8d0b21dff552..19858cecd32d 100644 --- a/engines/ags/engine/ac/slider.h +++ b/engines/ags/engine/ac/slider.h @@ -25,6 +25,8 @@ #include "gui/guislider.h" +namespace AGS3 { + using AGS::Common::GUISlider; void Slider_SetMax(GUISlider *guisl, int valn); @@ -40,4 +42,6 @@ void Slider_SetHandleGraphic(GUISlider *guisl, int newImage); int Slider_GetHandleOffset(GUISlider *guisl); void Slider_SetHandleOffset(GUISlider *guisl, int newOffset); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/speech.h b/engines/ags/engine/ac/speech.h index e3eea3c030e3..dd5e3dc1e900 100644 --- a/engines/ags/engine/ac/speech.h +++ b/engines/ags/engine/ac/speech.h @@ -23,21 +23,25 @@ #ifndef AGS_ENGINE_AC_SPEECH_H #define AGS_ENGINE_AC_SPEECH_H +namespace AGS3 { + enum SkipSpeechStyle { - kSkipSpeechUndefined = -1, - kSkipSpeechKeyMouseTime = 0, - kSkipSpeechKeyTime = 1, - kSkipSpeechTime = 2, - kSkipSpeechKeyMouse = 3, - kSkipSpeechMouseTime = 4, - kSkipSpeechKey = 5, - kSkipSpeechMouse = 6, + kSkipSpeechUndefined = -1, + kSkipSpeechKeyMouseTime = 0, + kSkipSpeechKeyTime = 1, + kSkipSpeechTime = 2, + kSkipSpeechKeyMouse = 3, + kSkipSpeechMouseTime = 4, + kSkipSpeechKey = 5, + kSkipSpeechMouse = 6, - kSkipSpeechFirst = kSkipSpeechKeyMouseTime, - kSkipSpeechLast = kSkipSpeechMouse + kSkipSpeechFirst = kSkipSpeechKeyMouseTime, + kSkipSpeechLast = kSkipSpeechMouse }; int user_to_internal_skip_speech(SkipSpeechStyle userval); SkipSpeechStyle internal_skip_speech_to_user(int internal_val); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/sprite.h b/engines/ags/engine/ac/sprite.h index a5d15f35f151..09f841e00517 100644 --- a/engines/ags/engine/ac/sprite.h +++ b/engines/ags/engine/ac/sprite.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_SPRITE_H #define AGS_ENGINE_AC_SPRITE_H +namespace AGS3 { + void get_new_size_for_sprite(int ee, int ww, int hh, int &newwid, int &newhit); // set any alpha-transparent pixels in the image to the appropriate // RGB mask value so that the ->Blit calls work correctly @@ -32,4 +34,6 @@ Common::Bitmap *remove_alpha_channel(Common::Bitmap *from); void pre_save_sprite(int ee); void initialize_sprite(int ee); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/spritelistentry.h b/engines/ags/engine/ac/spritelistentry.h index 735eaf2d10dc..8f932743894b 100644 --- a/engines/ags/engine/ac/spritelistentry.h +++ b/engines/ags/engine/ac/spritelistentry.h @@ -25,6 +25,8 @@ #include "gfx/ddb.h" +namespace AGS3 { + struct SpriteListEntry { AGS::Engine::IDriverDependantBitmap *bmp; AGS::Common::Bitmap *pic; @@ -37,4 +39,6 @@ struct SpriteListEntry { SpriteListEntry(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.h b/engines/ags/engine/ac/statobj/agsstaticobject.h index adcf2411bbf0..adaddac4ab1a 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.h +++ b/engines/ags/engine/ac/statobj/agsstaticobject.h @@ -25,6 +25,8 @@ #include "ac/statobj/staticobject.h" +namespace AGS3 { + struct AGSStaticObject : public ICCStaticObject { ~AGSStaticObject() override = default; @@ -50,4 +52,6 @@ struct StaticGame : public AGSStaticObject { extern AGSStaticObject GlobalStaticManager; extern StaticGame GameStaticManager; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h index 729e7f9bcefa..1941cc603ba1 100644 --- a/engines/ags/engine/ac/statobj/staticarray.h +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -25,6 +25,8 @@ #include "ac/statobj/staticobject.h" +namespace AGS3 { + struct ICCDynamicObject; struct StaticArray : public ICCStaticObject { @@ -57,11 +59,13 @@ struct StaticArray : public ICCStaticObject { void WriteFloat(const char *address, intptr_t offset, float val) override; private: - ICCStaticObject *_staticMgr; - ICCDynamicObject *_dynamicMgr; + ICCStaticObject *_staticMgr; + ICCDynamicObject *_dynamicMgr; int _elemLegacySize; int _elemRealSize; int _elemCount; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/statobj/staticobject.h b/engines/ags/engine/ac/statobj/staticobject.h index 4e424a02b0ee..5653222d774b 100644 --- a/engines/ags/engine/ac/statobj/staticobject.h +++ b/engines/ags/engine/ac/statobj/staticobject.h @@ -33,21 +33,25 @@ #include "core/types.h" +namespace AGS3 { + struct ICCStaticObject { virtual ~ICCStaticObject() = default; // Legacy support for reading and writing object values by their relative offset - virtual const char *GetFieldPtr(const char *address, intptr_t offset) = 0; + virtual const char *GetFieldPtr(const char *address, intptr_t offset) = 0; virtual void Read(const char *address, intptr_t offset, void *dest, int size) = 0; - virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; - virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; - virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; - virtual float ReadFloat(const char *address, intptr_t offset) = 0; + virtual uint8_t ReadInt8(const char *address, intptr_t offset) = 0; + virtual int16_t ReadInt16(const char *address, intptr_t offset) = 0; + virtual int32_t ReadInt32(const char *address, intptr_t offset) = 0; + virtual float ReadFloat(const char *address, intptr_t offset) = 0; virtual void Write(const char *address, intptr_t offset, void *src, int size) = 0; - virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; - virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; - virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; - virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; + virtual void WriteInt8(const char *address, intptr_t offset, uint8_t val) = 0; + virtual void WriteInt16(const char *address, intptr_t offset, int16_t val) = 0; + virtual void WriteInt32(const char *address, intptr_t offset, int32_t val) = 0; + virtual void WriteFloat(const char *address, intptr_t offset, float val) = 0; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h index 43968ed85491..e27bd213a4a8 100644 --- a/engines/ags/engine/ac/string.h +++ b/engines/ags/engine/ac/string.h @@ -26,6 +26,8 @@ #include #include "ac/dynobj/cc_dynamicobject.h" +namespace AGS3 { + // Check that a supplied buffer from a text script function was not null #define VALIDATE_STRING(strin) if ((unsigned long)strin <= 4096) quit("!String argument was null: make sure you pass a string, not an int, as a buffer") @@ -58,4 +60,6 @@ size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, i void check_strlen(char *ptt); void my_strncpy(char *dest, const char *src, int len); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/sys_events.h b/engines/ags/engine/ac/sys_events.h index d2e953193040..af50c7d08829 100644 --- a/engines/ags/engine/ac/sys_events.h +++ b/engines/ags/engine/ac/sys_events.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_SYS_EVENTS_H #define AGS_ENGINE_AC_SYS_EVENTS_H +namespace AGS3 { + int ags_getch(); int ags_kbhit(); int ags_iskeypressed(int keycode); @@ -38,4 +40,6 @@ void ags_clear_input_buffer(); // TODO: seriously not a good design, replace with event listening void ags_wait_until_keypress(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/system.h b/engines/ags/engine/ac/system.h index 7ed12cc875c3..280ec92ec733 100644 --- a/engines/ags/engine/ac/system.h +++ b/engines/ags/engine/ac/system.h @@ -25,6 +25,8 @@ #include "ac/dynobj/scriptaudiochannel.h" +namespace AGS3 { + int System_GetColorDepth(); int System_GetOS(); int System_GetScreenWidth(); @@ -49,5 +51,6 @@ int System_GetVolume(); void System_SetVolume(int newvol); const char *System_GetRuntimeInfo(); +} // namespace AGS3 #endif diff --git a/engines/ags/engine/ac/textbox.h b/engines/ags/engine/ac/textbox.h index 6720f392a77a..8b2a1f23a37d 100644 --- a/engines/ags/engine/ac/textbox.h +++ b/engines/ags/engine/ac/textbox.h @@ -25,6 +25,8 @@ #include "gui/guitextbox.h" +namespace AGS3 { + using AGS::Common::GUITextBox; const char *TextBox_GetText_New(GUITextBox *texbox); @@ -35,4 +37,6 @@ void TextBox_SetTextColor(GUITextBox *guit, int colr); int TextBox_GetFont(GUITextBox *guit); void TextBox_SetFont(GUITextBox *guit, int fontnum); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/timer.h b/engines/ags/engine/ac/timer.h index 66363c8d58a4..fa0ecb88013c 100644 --- a/engines/ags/engine/ac/timer.h +++ b/engines/ags/engine/ac/timer.h @@ -26,12 +26,14 @@ #include #include +namespace AGS3 { + // use high resolution clock only if we know it is monotonic/steady. // refer to https://stackoverflow.com/a/38253266/84262 using AGS_Clock = std::conditional < - std::chrono::high_resolution_clock::is_steady, - std::chrono::high_resolution_clock, std::chrono::steady_clock - >::type; + std::chrono::high_resolution_clock::is_steady, + std::chrono::high_resolution_clock, std::chrono::steady_clock +>::type; extern void WaitForNextFrame(); @@ -42,4 +44,6 @@ extern bool isTimerFpsMaxed(); extern bool waitingForNextTick(); // store last tick time. extern void skipMissedTicks(); // if more than N frames, just skip all, start a fresh. +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/topbarsettings.h b/engines/ags/engine/ac/topbarsettings.h index 4b8e1a660b38..0af28b977b47 100644 --- a/engines/ags/engine/ac/topbarsettings.h +++ b/engines/ags/engine/ac/topbarsettings.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_TOPBARSETTINGS_H #define AGS_ENGINE_AC_TOPBARSETTINGS_H +namespace AGS3 { + struct TopBarSettings { int wantIt; int height; @@ -37,4 +39,6 @@ struct TopBarSettings { } }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/translation.h b/engines/ags/engine/ac/translation.h index 1ee20f9e377b..4e5922b5755e 100644 --- a/engines/ags/engine/ac/translation.h +++ b/engines/ags/engine/ac/translation.h @@ -25,9 +25,13 @@ #include "util/string.h" +namespace AGS3 { + using AGS::Common::String; void close_translation(); bool init_translation(const String &lang, const String &fallback_lang, bool quit_on_error); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/tree_map.h b/engines/ags/engine/ac/tree_map.h index f00bb11f5a3b..6230dd3b9cb6 100644 --- a/engines/ags/engine/ac/tree_map.h +++ b/engines/ags/engine/ac/tree_map.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_TREEMAP_H #define AGS_ENGINE_AC_TREEMAP_H +namespace AGS3 { + // Binary tree structure for holding translations, allows fast // access struct TreeMap { @@ -37,4 +39,6 @@ struct TreeMap { ~TreeMap(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/viewframe.h b/engines/ags/engine/ac/viewframe.h index 171170ab6c62..2bd3049aa940 100644 --- a/engines/ags/engine/ac/viewframe.h +++ b/engines/ags/engine/ac/viewframe.h @@ -29,11 +29,14 @@ #include "ac/dynobj/scriptviewframe.h" #include "gfx/bitmap.h" +namespace AGS3 { + namespace AGS { namespace Common { class Graphics; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later int ViewFrame_GetFlipped(ScriptViewFrame *svf); @@ -53,4 +56,6 @@ void CheckViewFrame(int view, int loop, int frame, int sound_volume = SCR_NO_VAL // draws a view frame, flipped if appropriate void DrawViewFrame(Common::Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend = false); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/walkablearea.h b/engines/ags/engine/ac/walkablearea.h index 5be0c3902ecb..922f90af10de 100644 --- a/engines/ags/engine/ac/walkablearea.h +++ b/engines/ags/engine/ac/walkablearea.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_WALKABLEAREA_H #define AGS_ENGINE_AC_WALKABLEAREA_H +namespace AGS3 { + void redo_walkable_areas(); int get_walkable_area_pixel(int x, int y); int get_area_scaling(int onarea, int xx, int yy); @@ -33,4 +35,6 @@ Common::Bitmap *prepare_walkable_areas(int sourceChar); int get_walkable_area_at_location(int xx, int yy); int get_walkable_area_at_character(int charnum); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/ac/walkbehind.h b/engines/ags/engine/ac/walkbehind.h index 2bb80701a1f0..77bbdfc07271 100644 --- a/engines/ags/engine/ac/walkbehind.h +++ b/engines/ags/engine/ac/walkbehind.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_AC_WALKBEHIND_H #define AGS_ENGINE_AC_WALKBEHIND_H +namespace AGS3 { + enum WalkBehindMethodEnum { DrawOverCharSprite, DrawAsSeparateSprite, @@ -32,4 +34,6 @@ enum WalkBehindMethodEnum { void update_walk_behind_images(); void recache_walk_behinds(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/debugging/agseditordebugger.h b/engines/ags/engine/debugging/agseditordebugger.h index 8871a2f5dd3e..b4bdcfe602e3 100644 --- a/engines/ags/engine/debugging/agseditordebugger.h +++ b/engines/ags/engine/debugging/agseditordebugger.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_DEBUGGING_AGSEDITORDEBUGGER_H #define AGS_ENGINE_DEBUGGING_AGSEDITORDEBUGGER_H +namespace AGS3 { + struct IAGSEditorDebugger { public: virtual ~IAGSEditorDebugger() = default; @@ -35,4 +37,6 @@ struct IAGSEditorDebugger { virtual char *GetNextMessage() = 0; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/debugging/consoleoutputtarget.h b/engines/ags/engine/debugging/consoleoutputtarget.h index 9e12ac973995..f35bec348836 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.h +++ b/engines/ags/engine/debugging/consoleoutputtarget.h @@ -32,6 +32,7 @@ #include "debug/outputhandler.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -46,7 +47,8 @@ class ConsoleOutputTarget : public AGS::Common::IOutputHandler { void PrintMessage(const DebugMessage &msg) override; }; -} // namespace Engine -} // namespace AGS +} // namespace Engine +} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/debugging/debug_log.h b/engines/ags/engine/debugging/debug_log.h index f8d07e03830c..ea0b9554275e 100644 --- a/engines/ags/engine/debugging/debug_log.h +++ b/engines/ags/engine/debugging/debug_log.h @@ -29,6 +29,8 @@ #include "platform/base/agsplatformdriver.h" #include "util/ini_util.h" +namespace AGS3 { + void init_debug(const AGS::Common::ConfigTree &cfg, bool stderr_only); void apply_debug_config(const AGS::Common::ConfigTree &cfg); void shutdown_debug(); @@ -45,7 +47,7 @@ void quitprintf(const char *texx, ...); bool init_editor_debugging(); // allow LShift to single-step, RShift to pause flow -void scriptDebugHook(ccInstance *ccinst, int linenum) ; +void scriptDebugHook(ccInstance *ccinst, int linenum); extern AGS::Common::String debug_line[DEBUG_CONSOLE_NUMLINES]; extern int first_debug_line, last_debug_line, display_console; @@ -53,4 +55,6 @@ extern int first_debug_line, last_debug_line, display_console; extern AGSPlatformDriver *platform; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h index 399952677171..39450e988940 100644 --- a/engines/ags/engine/debugging/debugger.h +++ b/engines/ags/engine/debugging/debugger.h @@ -25,6 +25,8 @@ #include "util/string.h" +namespace AGS3 { + struct IAGSEditorDebugger; struct ScriptPosition; @@ -64,4 +66,6 @@ extern float fps; extern FPSDisplayMode display_fps; extern int debug_flags; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/debugging/dummyagsdebugger.h b/engines/ags/engine/debugging/dummyagsdebugger.h index 8ae955bc5b1c..2845e28a9ed1 100644 --- a/engines/ags/engine/debugging/dummyagsdebugger.h +++ b/engines/ags/engine/debugging/dummyagsdebugger.h @@ -25,13 +25,16 @@ #include "debug/debugger.h" +namespace AGS3 { + struct DummyAGSDebugger : IAGSEditorDebugger { public: virtual bool Initialize() override { return false; } - virtual void Shutdown() override { } + virtual void Shutdown() override { + } virtual bool SendMessageToEditor(const char *message) override { return false; } @@ -43,4 +46,6 @@ struct DummyAGSDebugger : IAGSEditorDebugger { } }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.h b/engines/ags/engine/debugging/filebasedagsdebugger.h index aebfba868fa3..3ba6b4acf7e5 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.h +++ b/engines/ags/engine/debugging/filebasedagsdebugger.h @@ -25,6 +25,8 @@ #include "debug/agseditordebugger.h" +namespace AGS3 { + struct FileBasedAGSDebugger : IAGSEditorDebugger { public: @@ -38,4 +40,6 @@ struct FileBasedAGSDebugger : IAGSEditorDebugger { extern const char *SENT_MESSAGE_FILE_NAME; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h index c0f9a6824578..674a097e8ccf 100644 --- a/engines/ags/engine/debugging/logfile.h +++ b/engines/ags/engine/debugging/logfile.h @@ -38,11 +38,12 @@ #include #include "debug/outputhandler.h" +namespace AGS3 { namespace AGS { namespace Common { class Stream; -} +} // namespace Shared namespace Engine { @@ -81,7 +82,8 @@ class LogFile : public AGS::Common::IOutputHandler { OpenMode _openMode; }; -} // namespace Engine -} // namespace AGS +} // namespace Engine +} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h index 1f80ee5494e3..f704af8fbe95 100644 --- a/engines/ags/engine/debugging/messagebuffer.h +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -34,6 +34,7 @@ #include #include "debug/outputhandler.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -59,7 +60,8 @@ class MessageBuffer : public AGS::Common::IOutputHandler { size_t _msgLost; }; -} // namespace Engine -} // namespace AGS +} // namespace Engine +} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h index 5bd55bdd62e5..d5f852eabcdb 100644 --- a/engines/ags/engine/device/mousew32.h +++ b/engines/ags/engine/device/mousew32.h @@ -37,11 +37,13 @@ #include "util/geometry.h" +namespace AGS3 { namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later void msetgraphpos(int, int); @@ -100,3 +102,5 @@ extern int disable_mgetgraphpos; extern char currentcursor; extern Common::Bitmap *mousecurs[MAXCURSORS]; + +} // namespace AGS3 diff --git a/engines/ags/engine/game/game_init.h b/engines/ags/engine/game/game_init.h index 0ce363d62646..e1921006ef71 100644 --- a/engines/ags/engine/game/game_init.h +++ b/engines/ags/engine/game/game_init.h @@ -33,6 +33,7 @@ #include "game/main_game_file.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -60,5 +61,6 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion da } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h index 838d2122aa99..ac605a3ab134 100644 --- a/engines/ags/engine/game/savegame.h +++ b/engines/ags/engine/game/savegame.h @@ -28,13 +28,13 @@ #include "util/error.h" #include "util/version.h" +namespace AGS3 { namespace AGS { - namespace Common { class Bitmap; class Stream; -} +} // namespace Shared namespace Engine { @@ -55,12 +55,12 @@ typedef std::shared_ptr PStream; //----------------------------------------------------------------------------- enum SavegameVersion { kSvgVersion_Undefined = 0, - kSvgVersion_321 = 8, + kSvgVersion_321 = 8, kSvgVersion_Components = 9, kSvgVersion_Cmp_64bit = 10, kSvgVersion_350_final = 11, kSvgVersion_350_final2 = 12, - kSvgVersion_Current = kSvgVersion_350_final2, + kSvgVersion_Current = kSvgVersion_350_final2, kSvgVersion_LowestSupported = kSvgVersion_321 // change if support dropped }; @@ -117,11 +117,11 @@ struct SavegameSource { // Supported elements of savegame description; // these may be used as flags to define valid fields enum SavegameDescElem { - kSvgDesc_None = 0, - kSvgDesc_EnvInfo = 0x0001, - kSvgDesc_UserText = 0x0002, - kSvgDesc_UserImage = 0x0004, - kSvgDesc_All = kSvgDesc_EnvInfo | kSvgDesc_UserText | kSvgDesc_UserImage + kSvgDesc_None = 0, + kSvgDesc_EnvInfo = 0x0001, + kSvgDesc_UserText = 0x0002, + kSvgDesc_UserImage = 0x0004, + kSvgDesc_All = kSvgDesc_EnvInfo | kSvgDesc_UserText | kSvgDesc_UserImage }; // SavegameDescription describes savegame with information about the enviroment @@ -154,7 +154,7 @@ struct SavegameDescription { // Opens savegame for reading; optionally reads description, if any is provided HSaveError OpenSavegame(const String &filename, SavegameSource &src, - SavegameDescription &desc, SavegameDescElem elems = kSvgDesc_All); + SavegameDescription &desc, SavegameDescElem elems = kSvgDesc_All); // Opens savegame and reads the savegame description HSaveError OpenSavegame(const String &filename, SavegameDescription &desc, SavegameDescElem elems = kSvgDesc_All); @@ -169,5 +169,6 @@ void SaveGameState(PStream out); } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h index 77355ee30433..32797df54df3 100644 --- a/engines/ags/engine/game/savegame_components.h +++ b/engines/ags/engine/game/savegame_components.h @@ -26,11 +26,12 @@ #include "game/savegame.h" #include "util/stream.h" +namespace AGS3 { namespace AGS { namespace Common { struct Interaction; -} +} // namespace Shared namespace Engine { diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index 9970ecd90433..e2dba2fedd38 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -29,7 +29,7 @@ #include "gfx/bitmap.h" #include "media/audio/audiodefines.h" - +namespace AGS3 { namespace AGS { namespace Engine { @@ -137,5 +137,6 @@ struct RestoredData { } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/game/viewport.h b/engines/ags/engine/game/viewport.h index b5b100b5329f..f39040cfdb58 100644 --- a/engines/ags/engine/game/viewport.h +++ b/engines/ags/engine/game/viewport.h @@ -34,6 +34,8 @@ #include "util/geometry.h" #include "util/scaling.h" +namespace AGS3 { + class Camera; class Viewport; @@ -48,7 +50,7 @@ typedef std::weak_ptr ViewportRef; template bool is_uninitialized(std::weak_ptr const &weak) { using wt = std::weak_ptr; - return !weak.owner_before(wt{}) &&!wt{} .owner_before(weak); + return !weak.owner_before(wt{}) && !wt{}.owner_before(weak); } @@ -220,4 +222,6 @@ class Viewport { bool _hasChangedVisible = false; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gfx/ali3dexception.h b/engines/ags/engine/gfx/ali3dexception.h index 92c40a96e60e..48e59a744385 100644 --- a/engines/ags/engine/gfx/ali3dexception.h +++ b/engines/ags/engine/gfx/ali3dexception.h @@ -29,6 +29,7 @@ #ifndef AGS_ENGINE_GFX_ALI3DEXCEPTION_H #define AGS_ENGINE_GFX_ALI3DEXCEPTION_H +namespace AGS3 { namespace AGS { namespace Engine { @@ -49,5 +50,6 @@ class Ali3DFullscreenLostException : public Ali3DException { } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h index 38b2c34f19fe..171817bcdb2c 100644 --- a/engines/ags/engine/gfx/ali3dogl.h +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -39,6 +39,7 @@ #include "ogl_headers.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -79,7 +80,7 @@ class OGLBitmap : public VideoMemDDB { _stretchToHeight = height; _useResampler = useResampler; } - void SetLightLevel(int lightLevel) override { + void SetLightLevel(int lightLevel) override { _lightLevel = lightLevel; } void SetTint(int red, int green, int blue, int tintSaturation) override { @@ -202,7 +203,8 @@ class OGLGraphicsDriver : public VideoMemoryGraphicsDriver { void Render() override; void Render(int xoff, int yoff, GlobalFlipType flip) override; bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; - void EnableVsyncBeforeRender(bool enabled) override { } + void EnableVsyncBeforeRender(bool enabled) override { + } void Vsync() override; void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override; void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; @@ -316,7 +318,7 @@ class OGLGraphicsDriver : public VideoMemoryGraphicsDriver { void CreateTintShader(); void CreateLightShader(); void CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, - const char *sampler_var, const char *color_var, const char *aux_var); + const char *sampler_var, const char *color_var, const char *aux_var); void DeleteShaderProgram(ShaderProgram &prg); void OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader); // Configure backbuffer texture, that is used in render-to-texture mode @@ -359,11 +361,11 @@ class OGLGraphicsFactory : public GfxDriverFactoryBase PGfxFilter; } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.h b/engines/ags/engine/gfx/gfxfilter_aad3d.h index 4f5c7de75ca8..84c376ec07b8 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.h +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.h @@ -31,6 +31,7 @@ #include "gfx/gfxfilter_d3d.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace D3D { @@ -48,5 +49,6 @@ class AAD3DGfxFilter : public D3DGfxFilter { } // namespace D3D } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.h b/engines/ags/engine/gfx/gfxfilter_aaogl.h index 3ed266331b34..3d77922736a1 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.h +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.h @@ -31,6 +31,7 @@ #include "gfx/gfxfilter_ogl.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace OGL { @@ -48,5 +49,6 @@ class AAOGLGfxFilter : public OGLGfxFilter { } // namespace OGL } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h index c2982344f90e..fe2b856c8b4b 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.h +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -33,6 +33,7 @@ #include "gfx/gfxfilter_scaling.h" #include "gfx/gfxdefines.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace ALSW { @@ -73,5 +74,6 @@ class AllegroGfxFilter : public ScalingGfxFilter { } // namespace ALSW } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.h b/engines/ags/engine/gfx/gfxfilter_d3d.h index 2db3af5d328c..ead9ae305e08 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.h +++ b/engines/ags/engine/gfx/gfxfilter_d3d.h @@ -31,6 +31,7 @@ #include "gfx/gfxfilter_scaling.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace D3D { @@ -48,5 +49,6 @@ class D3DGfxFilter : public ScalingGfxFilter { } // namespace D3D } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h index b00323a718ca..232e18052084 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.h +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -31,6 +31,7 @@ #include "gfx/gfxfilter_allegro.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace ALSW { @@ -60,5 +61,6 @@ class HqxGfxFilter : public AllegroGfxFilter { } // namespace ALSW } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.h b/engines/ags/engine/gfx/gfxfilter_ogl.h index 194bf95394ec..863dc0a5e57d 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.h +++ b/engines/ags/engine/gfx/gfxfilter_ogl.h @@ -31,6 +31,7 @@ #include "gfx/gfxfilter_scaling.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace OGL { @@ -48,5 +49,6 @@ class OGLGfxFilter : public ScalingGfxFilter { } // namespace D3D } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.h b/engines/ags/engine/gfx/gfxfilter_scaling.h index 85aeb1b5a1ea..f6be6a172955 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.h +++ b/engines/ags/engine/gfx/gfxfilter_scaling.h @@ -32,6 +32,7 @@ #include "gfx/gfxfilter.h" #include "util/scaling.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -49,5 +50,6 @@ class ScalingGfxFilter : public IGfxFilter { } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/gfxmodelist.h b/engines/ags/engine/gfx/gfxmodelist.h index 0fc28896216a..718ea5ce4fc8 100644 --- a/engines/ags/engine/gfx/gfxmodelist.h +++ b/engines/ags/engine/gfx/gfxmodelist.h @@ -32,6 +32,7 @@ #include "core/types.h" #include "gfx/gfxdefines.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -44,5 +45,6 @@ class IGfxModeList { } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h index 0108fad67077..70c39574fb14 100644 --- a/engines/ags/engine/gfx/graphicsdriver.h +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -34,12 +34,13 @@ #include "gfx/gfxmodelist.h" #include "util/geometry.h" +namespace AGS3 { namespace AGS { namespace Common { class Bitmap; typedef std::shared_ptr PBitmap; -} +} // namespace Common namespace Engine { @@ -70,10 +71,12 @@ struct SpriteTransform { float Rotate; // angle, in radians SpriteTransform() - : X(0), Y(0), ScaleX(1.f), ScaleY(1.f), Rotate(0.f) {} + : X(0), Y(0), ScaleX(1.f), ScaleY(1.f), Rotate(0.f) { + } SpriteTransform(int x, int y, float scalex = 1.0f, float scaley = 1.0f, float rotate = 0.0f) - : X(x), Y(y), ScaleX(scalex), ScaleY(scaley), Rotate(rotate) {} + : X(x), Y(y), ScaleX(scalex), ScaleY(scaley), Rotate(rotate) { + } }; typedef void (*GFXDRV_CLIENTCALLBACK)(); @@ -129,7 +132,7 @@ class IGraphicsDriver { // global model transformation; all subsequent calls to DrawSprite will be adding // sprites to this batch's list. virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, - const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) = 0; + const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) = 0; // Adds sprite to the active batch virtual void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) = 0; // Adds fade overlay fx to the active batch @@ -191,5 +194,6 @@ class IGraphicsDriver { } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/gfx/hq2x3x.h b/engines/ags/engine/gfx/hq2x3x.h index 741c31c0b65b..4d679e86f2dd 100644 --- a/engines/ags/engine/gfx/hq2x3x.h +++ b/engines/ags/engine/gfx/hq2x3x.h @@ -25,14 +25,21 @@ #include "core/platform.h" +namespace AGS3 { + #if AGS_PLATFORM_OS_ANDROID -void InitLUTs() {} -void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) {} -void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) {} +void InitLUTs() { +} +void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) { +} +void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) { +} #else void InitLUTs(); void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL); void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL); #endif +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h index d735d22b0db0..0445f1c63655 100644 --- a/engines/ags/engine/gui/animatingguibutton.h +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -25,6 +25,8 @@ #include "ac/runtime_defines.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { @@ -44,4 +46,6 @@ struct AnimatingGUIButton { void WriteToFile(Common::Stream *out); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h index 0d2930942045..47d5c6327d23 100644 --- a/engines/ags/engine/gui/cscidialog.h +++ b/engines/ags/engine/gui/cscidialog.h @@ -31,6 +31,8 @@ #include "gui/guidialoginternaldefs.h" +namespace AGS3 { + int CSCIGetVersion(); int CSCIDrawWindow(int xx, int yy, int wid, int hit); void CSCIEraseWindow(int handl); @@ -44,4 +46,6 @@ int checkcontrols(); int finddefaultcontrol(int flagmask); int GetBaseWidth(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/guidialog.h b/engines/ags/engine/gui/guidialog.h index 883a68009fb3..16bb1dedff65 100644 --- a/engines/ags/engine/gui/guidialog.h +++ b/engines/ags/engine/gui/guidialog.h @@ -23,6 +23,7 @@ #ifndef AGS_ENGINE_GUI_GUIDIALOG_H #define AGS_ENGINE_GUI_GUIDIALOG_H +namespace AGS3 { namespace AGS { namespace Common { class Bitmap; @@ -50,4 +51,6 @@ int quitdialog(); // last string value in gui dialog. char *get_gui_dialog_buffer(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h index 2cbc25fa0b61..e6054242009f 100644 --- a/engines/ags/engine/gui/guidialogdefines.h +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -23,6 +23,10 @@ #ifndef AGS_ENGINE_GUI_GUIDIALOGDEFINES_H #define AGS_ENGINE_GUI_GUIDIALOGDEFINES_H +#include "ac/gamesetup.h" + +namespace AGS3 { + #define MSG_RESTORE 984 #define MSG_CANCEL 985 // "Cancel" #define MSG_SELECTLOAD 986 // "Select game to restore" @@ -36,8 +40,6 @@ #define MSG_PLAYBUTTON 994 // "Play" #define MSG_QUITDIALOG 995 // "Do you want to quit?" -#include "ac/gamesetup.h" - /*#define COL251 26 #define COL252 28 #define COL253 29 @@ -114,4 +116,6 @@ struct OnScreenWindow { OnScreenWindow(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/guidialoginternaldefs.h b/engines/ags/engine/gui/guidialoginternaldefs.h index cb305e884f1e..fd4e0777f8c3 100644 --- a/engines/ags/engine/gui/guidialoginternaldefs.h +++ b/engines/ags/engine/gui/guidialoginternaldefs.h @@ -25,6 +25,8 @@ #include "gui/guidialogdefines.h" +namespace AGS3 { + #define _export #ifdef WINAPI #undef WINAPI @@ -34,4 +36,6 @@ extern int ags_misbuttondown(int but); #define mbutrelease(X) (!ags_misbuttondown(X)) #define TEXT_HT usetup.textheight +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h index 87ed7cb9f760..cb4905cd0bca 100644 --- a/engines/ags/engine/gui/mylabel.h +++ b/engines/ags/engine/gui/mylabel.h @@ -25,7 +25,9 @@ #include "gui/newcontrol.h" -struct MyLabel: public NewControl { +namespace AGS3 { + +struct MyLabel : public NewControl { char text[150]; MyLabel(int xx, int yy, int wii, const char *tee); @@ -36,4 +38,6 @@ struct MyLabel: public NewControl { int processmessage(int mcode, int wParam, long lParam) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h index b9b599b83994..128447bcc07c 100644 --- a/engines/ags/engine/gui/mylistbox.h +++ b/engines/ags/engine/gui/mylistbox.h @@ -25,10 +25,12 @@ #include "gui/newcontrol.h" +namespace AGS3 { + #define MAXLISTITEM 300 #define ARROWWIDTH 8 -struct MyListBox: public NewControl { +struct MyListBox : public NewControl { int items, topitem, numonscreen, selected; char *itemnames[MAXLISTITEM]; MyListBox(int xx, int yy, int wii, int hii); @@ -41,4 +43,6 @@ struct MyListBox: public NewControl { int processmessage(int mcode, int wParam, long lParam) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h index 92147b484050..a1870bcc223b 100644 --- a/engines/ags/engine/gui/mypushbutton.h +++ b/engines/ags/engine/gui/mypushbutton.h @@ -25,7 +25,9 @@ #include "gui/newcontrol.h" -struct MyPushButton: public NewControl { +namespace AGS3 { + +struct MyPushButton : public NewControl { char text[50]; MyPushButton(int xx, int yy, int wi, int hi, const char *tex); void draw(Common::Bitmap *ds) override; @@ -33,4 +35,6 @@ struct MyPushButton: public NewControl { int processmessage(int mcode, int wParam, long lParam) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h index 97d9b687d02f..3a69094d4a10 100644 --- a/engines/ags/engine/gui/mytextbox.h +++ b/engines/ags/engine/gui/mytextbox.h @@ -25,8 +25,10 @@ #include "gui/newcontrol.h" +namespace AGS3 { + #define TEXTBOX_MAXLEN 49 -struct MyTextBox: public NewControl { +struct MyTextBox : public NewControl { char text[TEXTBOX_MAXLEN + 1]; MyTextBox(int xx, int yy, int wii, const char *tee); void draw(Common::Bitmap *ds) override; @@ -34,4 +36,6 @@ struct MyTextBox: public NewControl { int processmessage(int mcode, int wParam, long lParam) override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/gui/newcontrol.h b/engines/ags/engine/gui/newcontrol.h index e496be3fce4e..690e93a0e95e 100644 --- a/engines/ags/engine/gui/newcontrol.h +++ b/engines/ags/engine/gui/newcontrol.h @@ -25,6 +25,8 @@ #include "gfx/bitmap.h" +namespace AGS3 { + using namespace AGS; // FIXME later struct NewControl { @@ -43,4 +45,6 @@ struct NewControl { void drawandmouse(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/config.h b/engines/ags/engine/main/config.h index 4b0c086533fd..528ce79582b2 100644 --- a/engines/ags/engine/main/config.h +++ b/engines/ags/engine/main/config.h @@ -26,6 +26,8 @@ #include "main/graphics_mode.h" #include "util/ini_util.h" +namespace AGS3 { + using AGS::Common::String; using AGS::Common::ConfigTree; @@ -79,5 +81,6 @@ void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int v void INIwritestring(ConfigTree &cfg, const String §n, const String &item, const String &value); void INIwriteint(ConfigTree &cfg, const String §n, const String &item, int value); +} // namespace AGS3 #endif diff --git a/engines/ags/engine/main/engine.h b/engines/ags/engine/main/engine.h index 030d48c09e22..1efa0ec072c3 100644 --- a/engines/ags/engine/main/engine.h +++ b/engines/ags/engine/main/engine.h @@ -25,6 +25,8 @@ #include "util/ini_util.h" +namespace AGS3 { + const char *get_engine_name(); const char *get_engine_version(); void show_preload(); @@ -62,4 +64,6 @@ extern ResourcePaths ResPaths; typedef void (*t_engine_pre_init_callback)(void); extern void engine_set_pre_init_callback(t_engine_pre_init_callback callback); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/engine_setup.h b/engines/ags/engine/main/engine_setup.h index 9c4a42451727..feca62e0ef03 100644 --- a/engines/ags/engine/main/engine_setup.h +++ b/engines/ags/engine/main/engine_setup.h @@ -26,6 +26,8 @@ #include "util/geometry.h" #include "gfx/gfxdefines.h" +namespace AGS3 { + // Sets up game viewport and object scaling parameters depending on game. // TODO: this is part of the game init, not engine init, move it later void engine_init_resolution_settings(const Size game_size); @@ -38,4 +40,6 @@ void engine_pre_gfxsystem_shutdown(); // Applies necessary changes after screen<->virtual coordinate transformation has changed void on_coordinates_scaling_changed(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/game_file.h b/engines/ags/engine/main/game_file.h index d63929bff52a..f822ed0cfd67 100644 --- a/engines/ags/engine/main/game_file.h +++ b/engines/ags/engine/main/game_file.h @@ -26,6 +26,8 @@ #include "util/error.h" #include "util/string.h" +namespace AGS3 { + using AGS::Common::HError; // Preload particular game-describing parameters from the game data header (title, save game dir name, etc) @@ -34,4 +36,6 @@ HError preload_game_data(); HError load_game_file(); void display_game_file_error(HError err); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/game_run.h b/engines/ags/engine/main/game_run.h index e2d8431e6f37..52653659bcce 100644 --- a/engines/ags/engine/main/game_run.h +++ b/engines/ags/engine/main/game_run.h @@ -23,11 +23,14 @@ #ifndef AGS_ENGINE_MAIN_GAME_RUN_H #define AGS_ENGINE_MAIN_GAME_RUN_H +namespace AGS3 { + namespace AGS { namespace Engine { class IDriverDependantBitmap; -} -} +} // namespace Engine +} // namespace AGS + using namespace AGS::Engine; // FIXME later // Loops game frames until certain event takes place (for blocking actions) @@ -54,4 +57,6 @@ bool run_service_key_controls(int &kgn); // otherwise returns true and provides mouse button code. bool run_service_mb_controls(int &mbut, int &mwheelz); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/game_start.h b/engines/ags/engine/main/game_start.h index d672229c98a7..8ca81c2c602f 100644 --- a/engines/ags/engine/main/game_start.h +++ b/engines/ags/engine/main/game_start.h @@ -23,7 +23,11 @@ #ifndef AGS_ENGINE_MAIN_GAME_START_H #define AGS_ENGINE_MAIN_GAME_START_H +namespace AGS3 { + void start_game(); void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h index a75f85f19b3b..facdea50d827 100644 --- a/engines/ags/engine/main/graphics_mode.h +++ b/engines/ags/engine/main/graphics_mode.h @@ -27,6 +27,8 @@ #include "util/scaling.h" #include "util/string.h" +namespace AGS3 { + using AGS::Common::String; using AGS::Engine::DisplayMode; @@ -39,8 +41,8 @@ class IGfxModeList; } } bool find_nearest_supported_mode(const AGS::Engine::IGfxModeList &modes, const Size &wanted_size, - const int color_depth, const Size *ratio_reference, const Size *upper_bound, - AGS::Engine::DisplayMode &dm, int *mode_index = nullptr); + const int color_depth, const Size *ratio_reference, const Size *upper_bound, + AGS::Engine::DisplayMode &dm, int *mode_index = nullptr); // The game-to-screen transformation @@ -119,8 +121,10 @@ struct ColorDepthOption { int Bits; // color depth value in bits bool Forced; // whether the depth should be forced, or driver's recommendation used - ColorDepthOption() : Bits(0), Forced(false) {} - ColorDepthOption(int bits, bool forced = false) : Bits(bits), Forced(forced) {} + ColorDepthOption() : Bits(0), Forced(false) { + } + ColorDepthOption(int bits, bool forced = false) : Bits(bits), Forced(forced) { + } }; // ActiveDisplaySetting struct merges DisplayMode and GameFrameSetup, @@ -139,7 +143,7 @@ ActiveDisplaySetting graphics_mode_get_last_setting(bool windowed); bool graphics_mode_create_renderer(const String &driver_id); // Try to find and initialize compatible display mode as close to given setup as possible bool graphics_mode_set_dm_any(const Size &game_size, const DisplayModeSetup &dm_setup, - const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup); + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup); // Set the display mode with given parameters bool graphics_mode_set_dm(const AGS::Engine::DisplayMode &dm); // Set the native image size @@ -155,4 +159,6 @@ bool graphics_mode_set_filter(const String &filter_id); // Releases current graphic mode and shuts down renderer void graphics_mode_shutdown(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index cd3a27e9b933..1b15acafc236 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -26,6 +26,8 @@ #include "core/platform.h" #include "util/version.h" +namespace AGS3 { + // Current engine version extern AGS::Common::Version EngineVersion; // Lowest savedgame version, accepted by this engine @@ -67,4 +69,6 @@ void main_print_help(); int ags_entry_point(int argc, char *argv[]); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/main_allegro.h b/engines/ags/engine/main/main_allegro.h index c6f0d3e7dbd2..1d610d12f8a0 100644 --- a/engines/ags/engine/main/main_allegro.h +++ b/engines/ags/engine/main/main_allegro.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_MAIN_MAINALLEGRO_H #define AGS_ENGINE_MAIN_MAINALLEGRO_H +namespace AGS3 { + // Gets allegro_error as a const string. // Please, use this getter to acquire error text, do not use allegro_error // global variable directly. @@ -33,4 +35,6 @@ const char *get_allegro_error(); // truncated. Null terminator is always guaranteed. const char *set_allegro_error(const char *format, ...); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/mainheader.h b/engines/ags/engine/main/mainheader.h index 406e5c0787b8..10064e6425e7 100644 --- a/engines/ags/engine/main/mainheader.h +++ b/engines/ags/engine/main/mainheader.h @@ -45,8 +45,13 @@ #include #include +namespace AGS3 { + extern "C" void selectLatestSavegame(); extern bool psp_load_latest_savegame; + +} // namespace AGS3 + #endif #endif diff --git a/engines/ags/engine/main/quit.h b/engines/ags/engine/main/quit.h index cc1fab41e4a4..849173f81459 100644 --- a/engines/ags/engine/main/quit.h +++ b/engines/ags/engine/main/quit.h @@ -23,27 +23,31 @@ #ifndef AGS_ENGINE_MAIN_QUIT_H #define AGS_ENGINE_MAIN_QUIT_H +namespace AGS3 { + enum QuitReason { - kQuitKind_NormalExit = 0x01, - kQuitKind_DeliberateAbort = 0x02, - kQuitKind_GameException = 0x04, - kQuitKind_EngineException = 0x08, + kQuitKind_NormalExit = 0x01, + kQuitKind_DeliberateAbort = 0x02, + kQuitKind_GameException = 0x04, + kQuitKind_EngineException = 0x08, // user closed the window or script command QuitGame was executed - kQuit_GameRequest = kQuitKind_NormalExit | 0x10, + kQuit_GameRequest = kQuitKind_NormalExit | 0x10, // user pressed abort game key - kQuit_UserAbort = kQuitKind_DeliberateAbort | 0x20, + kQuit_UserAbort = kQuitKind_DeliberateAbort | 0x20, // script command AbortGame was executed - kQuit_ScriptAbort = kQuitKind_GameException | 0x10, + kQuit_ScriptAbort = kQuitKind_GameException | 0x10, // game logic has generated a warning and warnings are treated as error - kQuit_GameWarning = kQuitKind_GameException | 0x20, + kQuit_GameWarning = kQuitKind_GameException | 0x20, // game logic has generated an error (often script error) - kQuit_GameError = kQuitKind_GameException | 0x30, + kQuit_GameError = kQuitKind_GameException | 0x30, // any kind of a fatal engine error - kQuit_FatalError = kQuitKind_EngineException + kQuit_FatalError = kQuitKind_EngineException }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/main/update.h b/engines/ags/engine/main/update.h index 45dd6158b395..8d478685b150 100644 --- a/engines/ags/engine/main/update.h +++ b/engines/ags/engine/main/update.h @@ -23,9 +23,13 @@ #ifndef AGS_ENGINE_MAIN_UPDATE_H #define AGS_ENGINE_MAIN_UPDATE_H +namespace AGS3 { + #define MAX_SHEEP 30 // sheep == follower int do_movelist_move(short *mlnum, int *xx, int *yy); void update_stuff(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h index 3a4fb9dc23ed..c0f06ca689bb 100644 --- a/engines/ags/engine/media/audio/ambientsound.h +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -23,6 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_AMBIENTSOUND_H #define AGS_ENGINE_MEDIA_AUDIO_AMBIENTSOUND_H +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { @@ -46,4 +48,6 @@ struct AmbientSound { void WriteToFile(Common::Stream *out); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index 32079d872265..b518a0b93afa 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -33,6 +33,8 @@ #include "util/thread.h" #include "ac/timer.h" +namespace AGS3 { + struct SOUNDCLIP; //controls access to the channels, since that's the main point of synchronization between the streaming thread and the user code @@ -76,7 +78,7 @@ void calculate_reserved_channel_count(); void update_clip_default_volume(ScriptAudioClip *audioClip); void start_fading_in_new_track_if_applicable(int fadeInChannel, ScriptAudioClip *newSound); void stop_or_fade_out_channel(int fadeOutChannel, int fadeInChannel = -1, ScriptAudioClip *newSound = nullptr); -SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat); +SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat); ScriptAudioChannel *play_audio_clip_on_channel(int channel, ScriptAudioClip *clip, int priority, int repeat, int fromOffset, SOUNDCLIP *cachedClip = nullptr); void remove_clips_of_type_from_queue(int audioType); void update_queued_clips_volume(int audioType, int new_vol); @@ -156,4 +158,6 @@ extern SOUNDCLIP *cachedQueuedMusic; // TODO: double check that ambient sounds array actually needs +1 extern std::array < AmbientSound, MAX_SOUND_CHANNELS + 1 > ambient; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index 55efab4d1c4d..50b3cc3c6a90 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -26,6 +26,8 @@ #include "aldumb.h" #include "media/audio/soundclip.h" +namespace AGS3 { + #define VOLUME_TO_DUMB_VOL(vol) ((float)vol) / 256.0 void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop); @@ -73,4 +75,6 @@ struct MYMOD : public SOUNDCLIP { int get_real_mod_pos(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_myjgmod.h b/engines/ags/engine/media/audio/clip_myjgmod.h index 72e6032230fb..3b6a6f45dcc3 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.h +++ b/engines/ags/engine/media/audio/clip_myjgmod.h @@ -26,8 +26,10 @@ #include "jgmod.h" #include "media/audio/soundclip.h" +namespace AGS3 { + // MOD/XM (JGMOD) -struct MYMOD: public SOUNDCLIP { +struct MYMOD : public SOUNDCLIP { JGMOD *tune; int poll(); @@ -53,4 +55,6 @@ struct MYMOD: public SOUNDCLIP { MYMOD(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index e250c346f8a3..18a2f32046a5 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -25,8 +25,10 @@ #include "media/audio/soundclip.h" +namespace AGS3 { + // MIDI -struct MYMIDI: public SOUNDCLIP { +struct MYMIDI : public SOUNDCLIP { MIDI *tune; int lengthInSeconds; @@ -59,4 +61,6 @@ struct MYMIDI: public SOUNDCLIP { void adjust_volume() override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index d4fafabe9819..f658fd5ce63e 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -26,9 +26,11 @@ #include "almp3.h" #include "media/audio/soundclip.h" +namespace AGS3 { + extern AGS::Engine::Mutex _mp3_mutex; -struct MYMP3: public SOUNDCLIP { +struct MYMP3 : public SOUNDCLIP { ALMP3_MP3STREAM *stream; PACKFILE *in; size_t filesize; @@ -54,4 +56,6 @@ struct MYMP3: public SOUNDCLIP { void adjust_stream(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h index b8fbd0dace0e..05cd7439a034 100644 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -26,7 +26,9 @@ #include "alogg.h" #include "media/audio/soundclip.h" -struct MYOGG: public SOUNDCLIP { +namespace AGS3 { + +struct MYOGG : public SOUNDCLIP { ALOGG_OGGSTREAM *stream; PACKFILE *in; char *buffer; @@ -64,4 +66,6 @@ struct MYOGG: public SOUNDCLIP { void adjust_stream(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index 6492518430cb..291d20f98e16 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -26,10 +26,12 @@ #include "almp3.h" #include "media/audio/soundclip.h" +namespace AGS3 { + extern AGS::Engine::Mutex _mp3_mutex; // pre-loaded (non-streaming) MP3 file -struct MYSTATICMP3: public SOUNDCLIP { +struct MYSTATICMP3 : public SOUNDCLIP { ALMP3_MP3 *tune; char *mp3buffer; @@ -61,4 +63,6 @@ struct MYSTATICMP3: public SOUNDCLIP { void adjust_stream(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h index 18972ce79ba2..bc5f5ea3860e 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -26,8 +26,10 @@ #include "alogg.h" #include "media/audio/soundclip.h" +namespace AGS3 { + // pre-loaded (non-streaming) OGG file -struct MYSTATICOGG: public SOUNDCLIP { +struct MYSTATICOGG : public SOUNDCLIP { ALOGG_OGG *tune; char *mp3buffer; int mp3buffersize; @@ -67,4 +69,6 @@ struct MYSTATICOGG: public SOUNDCLIP { void adjust_stream(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h index 4c479b4cffb3..7173367a122e 100644 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -25,8 +25,10 @@ #include "media/audio/soundclip.h" +namespace AGS3 { + // My new MP3STREAM wrapper -struct MYWAVE: public SOUNDCLIP { +struct MYWAVE : public SOUNDCLIP { SAMPLE *wave; int voice; @@ -54,4 +56,6 @@ struct MYWAVE: public SOUNDCLIP { void adjust_volume() override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/queuedaudioitem.h b/engines/ags/engine/media/audio/queuedaudioitem.h index f73fd0de1439..99a917c99f23 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.h +++ b/engines/ags/engine/media/audio/queuedaudioitem.h @@ -23,13 +23,16 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_QUEUEDAUDIOITEM_H #define AGS_ENGINE_MEDIA_AUDIO_QUEUEDAUDIOITEM_H +namespace AGS3 { + struct SOUNDCLIP; namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later struct QueuedAudioItem { @@ -42,4 +45,6 @@ struct QueuedAudioItem { void WriteToFile(Common::Stream *out) const; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/sound.h b/engines/ags/engine/media/audio/sound.h index 0d51ffbeda99..e98c4a7f5ec2 100644 --- a/engines/ags/engine/media/audio/sound.h +++ b/engines/ags/engine/media/audio/sound.h @@ -32,6 +32,8 @@ #include "ac/asset_helper.h" #include "media/audio/soundclip.h" +namespace AGS3 { + SOUNDCLIP *my_load_wave(const AssetPath &asset_name, int voll, int loop); SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll); SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop); @@ -42,4 +44,6 @@ SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet); extern int use_extra_sound_offset; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h index 09e88138a691..09162ba1f7b1 100644 --- a/engines/ags/engine/media/audio/soundcache.h +++ b/engines/ags/engine/media/audio/soundcache.h @@ -25,6 +25,8 @@ #include "ac/asset_helper.h" +namespace AGS3 { + // PSP: A simple sound cache. The size can be configured in the config file. // The data rate while reading from disk on the PSP is usually between 500 to 900 kiB/s, // caching the last used sound files therefore improves game performance. @@ -51,5 +53,6 @@ void clear_sound_cache(); void sound_cache_free(char *buffer, bool is_wave); char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size); +} // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index 2158dbac22cb..48daf5c92682 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -31,6 +31,8 @@ #include "util/mutex.h" +namespace AGS3 { + // JJS: This is needed for the derieved classes extern volatile int psp_audio_multithreaded; @@ -40,7 +42,9 @@ extern volatile int psp_audio_multithreaded; // Improving this situation is only possible with massive refactory of // sound clip use, taking backwards-compatible audio system in account. -enum SoundClipState { SoundClipInitial, SoundClipPlaying, SoundClipPaused, SoundClipStopped }; +enum SoundClipState { + SoundClipInitial, SoundClipPlaying, SoundClipPaused, SoundClipStopped +}; struct SOUNDCLIP { int priority; @@ -171,4 +175,6 @@ struct SOUNDCLIP { } }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/video/VMR9Graph.h b/engines/ags/engine/media/video/VMR9Graph.h index e850d6b741a5..e6a8713355df 100644 --- a/engines/ags/engine/media/video/VMR9Graph.h +++ b/engines/ags/engine/media/video/VMR9Graph.h @@ -36,6 +36,8 @@ #include #include +namespace AGS3 { + //#pragma comment( lib, "strmiids.lib" ) //#pragma comment( lib, "Quartz.lib" ) //#pragma comment( lib, "d3d9.lib" ) @@ -127,33 +129,35 @@ class CVMR9Graph { DWORD m_dwRotId; char m_pszErrorDescription[1024 + MAX_ERROR_TEXT_LEN]; int m_nNumberOfStream; - const char *m_pszFileName; + const char *m_pszFileName; long m_oldWndProc; // MEDIA WINDOW HWND m_hMediaWindow; // SRC interfaces array - IBaseFilter *m_srcFilterArray[10]; + IBaseFilter *m_srcFilterArray[10]; // SOUND interfaces - IBaseFilter *m_pDirectSoundFilter; + IBaseFilter *m_pDirectSoundFilter; // GRAPH interfaces - IUnknown *m_pGraphUnknown; - IGraphBuilder *m_pGraphBuilder; - IFilterGraph *m_pFilterGraph; - IFilterGraph2 *m_pFilterGraph2; - IMediaControl *m_pMediaControl; - IMediaSeeking *m_pMediaSeeking; + IUnknown *m_pGraphUnknown; + IGraphBuilder *m_pGraphBuilder; + IFilterGraph *m_pFilterGraph; + IFilterGraph2 *m_pFilterGraph2; + IMediaControl *m_pMediaControl; + IMediaSeeking *m_pMediaSeeking; //IMediaEvent* m_pMediaEvent; - IMediaEventEx *m_pMediaEventEx; + IMediaEventEx *m_pMediaEventEx; // VMR9 interfaces - IBaseFilter *m_pVMRBaseFilter; - IVMRFilterConfig9 *m_pVMRFilterConfig; - IVMRMixerBitmap9 *m_pVMRMixerBitmap; - IVMRMixerControl9 *m_pVMRMixerControl; - IVMRMonitorConfig9 *m_pVMRMonitorConfig; - IVMRWindowlessControl9 *m_pVMRWindowlessControl; + IBaseFilter *m_pVMRBaseFilter; + IVMRFilterConfig9 *m_pVMRFilterConfig; + IVMRMixerBitmap9 *m_pVMRMixerBitmap; + IVMRMixerControl9 *m_pVMRMixerControl; + IVMRMonitorConfig9 *m_pVMRMonitorConfig; + IVMRWindowlessControl9 *m_pVMRWindowlessControl; // DIRECT3D interfaces //IDirect3DDevice9* m_pD3DDevice; - IDirect3DSurface9 *m_pD3DSurface; + IDirect3DSurface9 *m_pD3DSurface; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/media/video/video.h b/engines/ags/engine/media/video/video.h index 16c037f7da7d..558189e3f78e 100644 --- a/engines/ags/engine/media/video/video.h +++ b/engines/ags/engine/media/video/video.h @@ -23,10 +23,14 @@ #ifndef AGS_ENGINE_MEDIA_VIDEO_VIDEO_H #define AGS_ENGINE_MEDIA_VIDEO_VIDEO_H +namespace AGS3 { + void play_theora_video(const char *name, int skip, int flags); void play_flc_file(int numb, int playflags); // Update video playback if the display mode has changed void video_on_gfxmode_changed(); +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 03a7a6141605..360d3600df63 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -35,6 +35,8 @@ #include "debug/outputhandler.h" #include "util/ini_util.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; @@ -62,7 +64,7 @@ enum SetupReturnValue { }; struct AGSPlatformDriver -// be used as a output target for logging system + // be used as a output target for logging system : public AGS::Common::IOutputHandler { virtual void AboutToQuitGame(); virtual void Delay(int millis); @@ -84,7 +86,7 @@ struct AGSPlatformDriver return "."; } // Get directory for storing all-games user configuration files - virtual const char *GetUserGlobalConfigDirectory() { + virtual const char *GetUserGlobalConfigDirectory() { return "."; } // Get default directory for program output (logs) @@ -150,7 +152,8 @@ struct AGSPlatformDriver virtual void UnRegisterGameWithGameExplorer(); virtual int ConvertKeycodeToScanCode(int keyCode); // Adjust window size to ensure it is in the supported limits - virtual void ValidateWindowSize(int &x, int &y, bool borderless) const {} + virtual void ValidateWindowSize(int &x, int &y, bool borderless) const { + } virtual int InitializeCDPlayer() = 0; // return 0 on success virtual int CDPlayerCommand(int cmdd, int datt) = 0; @@ -201,4 +204,6 @@ int cd_player_control(int cmdd, int datt); // instance by calling AGSPlatformDriver::GetDriver()? extern AGSPlatformDriver *platform; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/util/pe.h b/engines/ags/engine/platform/util/pe.h index f6ab17c9102c..98bdc2227ac0 100644 --- a/engines/ags/engine/platform/util/pe.h +++ b/engines/ags/engine/platform/util/pe.h @@ -23,20 +23,24 @@ #ifndef AGS_ENGINE_PLATFORM_UTIL_PE_H #define AGS_ENGINE_PLATFORM_UTIL_PE_H +namespace AGS3 { + #ifdef __cplusplus extern "C" { #endif -typedef struct { - char version[15]; - char description[100]; - char internal_name[100]; -} version_info_t; + typedef struct { + char version[15]; + char description[100]; + char internal_name[100]; + } version_info_t; -int getVersionInformation(char *filename, version_info_t *version_info); + int getVersionInformation(char *filename, version_info_t *version_info); #ifdef __cplusplus } #endif +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h index 01a192bdb2ab..597d091125c8 100644 --- a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h @@ -27,6 +27,8 @@ #include #include "debug/agseditordebugger.h" +namespace AGS3 { + struct NamedPipesAGSDebugger : IAGSEditorDebugger { private: HANDLE _hPipeSending; @@ -44,4 +46,6 @@ struct NamedPipesAGSDebugger : IAGSEditorDebugger { virtual char *GetNextMessage() override; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index 622a7f55d24e..4a75d322b4b6 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -46,6 +46,8 @@ #include "util/library.h" #include "util/string.h" +namespace AGS3 { + namespace AGS { namespace Engine { namespace D3D { @@ -201,7 +203,8 @@ class D3DGraphicsDriver : public VideoMemoryGraphicsDriver { void Render() override; void Render(int xoff, int yoff, GlobalFlipType flip) override; bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; - void EnableVsyncBeforeRender(bool enabled) override { } + void EnableVsyncBeforeRender(bool enabled) override { + } void Vsync() override; void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override { _renderSprAtScreenRes = enabled; @@ -311,14 +314,14 @@ class D3DGraphicsFactory : public GfxDriverFactoryBase +namespace AGS3 { + struct NonBlockingScriptFunction { const char *functionName; int numParameters; @@ -48,4 +50,6 @@ struct NonBlockingScriptFunction { } }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/script/runtimescriptvalue.h b/engines/ags/engine/script/runtimescriptvalue.h index 91a02368e2db..f7840fdee3c8 100644 --- a/engines/ags/engine/script/runtimescriptvalue.h +++ b/engines/ags/engine/script/runtimescriptvalue.h @@ -33,6 +33,8 @@ #include "util/memory.h" #include "ac/dynobj/cc_dynamicobject.h" +namespace AGS3 { + struct ICCStaticObject; struct StaticArray; @@ -63,19 +65,19 @@ enum ScriptValueType { struct RuntimeScriptValue { public: RuntimeScriptValue() { - Type = kScValUndefined; - IValue = 0; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 0; + Type = kScValUndefined; + IValue = 0; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 0; } RuntimeScriptValue(int32_t val) { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; } ScriptValueType Type; @@ -88,19 +90,19 @@ struct RuntimeScriptValue { // Pointer is used for storing... pointers - to objects, arrays, // functions and stack entries (other RSV) union { - char *Ptr; // generic data pointer - RuntimeScriptValue *RValue;// access ptr as a pointer to Runtime Value - ScriptAPIFunction *SPfn; // access ptr as a pointer to Script API Static Function + char *Ptr; // generic data pointer + RuntimeScriptValue *RValue;// access ptr as a pointer to Runtime Value + ScriptAPIFunction *SPfn; // access ptr as a pointer to Script API Static Function ScriptAPIObjectFunction *ObjPfn; // access ptr as a pointer to Script API Object Function }; // TODO: separation to Ptr and MgrPtr is only needed so far as there's // a separation between Script*, Dynamic* and game entity classes. // Once those classes are merged, it will no longer be needed. union { - void *MgrPtr;// generic object manager pointer - ICCStaticObject *StcMgr;// static object manager - StaticArray *StcArr;// static array manager - ICCDynamicObject *DynMgr;// dynamic object manager + void *MgrPtr;// generic object manager pointer + ICCStaticObject *StcMgr;// static object manager + StaticArray *StcArr;// static array manager + ICCDynamicObject *DynMgr;// dynamic object manager }; // The "real" size of data, either one stored in I/FValue, // or the one referenced by Ptr. Used for calculating stack @@ -125,43 +127,43 @@ struct RuntimeScriptValue { } inline RuntimeScriptValue &Invalidate() { - Type = kScValUndefined; - IValue = 0; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 0; + Type = kScValUndefined; + IValue = 0; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 0; return *this; } inline RuntimeScriptValue &SetUInt8(uint8_t val) { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 1; + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 1; return *this; } inline RuntimeScriptValue &SetInt16(int16_t val) { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 2; + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 2; return *this; } inline RuntimeScriptValue &SetInt32(int32_t val) { - Type = kScValInteger; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; + Type = kScValInteger; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetFloat(float val) { - Type = kScValFloat; - FValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; + Type = kScValFloat; + FValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetInt32AsBool(bool val) { @@ -171,108 +173,108 @@ struct RuntimeScriptValue { return SetFloat(val ? 1.0F : 0.0F); } inline RuntimeScriptValue &SetPluginArgument(int32_t val) { - Type = kScValPluginArg; - IValue = val; - Ptr = nullptr; - MgrPtr = nullptr; - Size = 4; + Type = kScValPluginArg; + IValue = val; + Ptr = nullptr; + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetStackPtr(RuntimeScriptValue *stack_entry) { - Type = kScValStackPtr; - IValue = 0; - RValue = stack_entry; - MgrPtr = nullptr; - Size = 4; + Type = kScValStackPtr; + IValue = 0; + RValue = stack_entry; + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetData(char *data, int size) { - Type = kScValData; - IValue = 0; - Ptr = data; - MgrPtr = nullptr; - Size = size; + Type = kScValData; + IValue = 0; + Ptr = data; + MgrPtr = nullptr; + Size = size; return *this; } inline RuntimeScriptValue &SetGlobalVar(RuntimeScriptValue *glvar_value) { - Type = kScValGlobalVar; - IValue = 0; - RValue = glvar_value; - MgrPtr = nullptr; - Size = 4; + Type = kScValGlobalVar; + IValue = 0; + RValue = glvar_value; + MgrPtr = nullptr; + Size = 4; return *this; } // TODO: size? inline RuntimeScriptValue &SetStringLiteral(const char *str) { - Type = kScValStringLiteral; - IValue = 0; - Ptr = const_cast(str); - MgrPtr = nullptr; - Size = 4; + Type = kScValStringLiteral; + IValue = 0; + Ptr = const_cast(str); + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetStaticObject(void *object, ICCStaticObject *manager) { - Type = kScValStaticObject; - IValue = 0; - Ptr = (char *)object; - StcMgr = manager; - Size = 4; + Type = kScValStaticObject; + IValue = 0; + Ptr = (char *)object; + StcMgr = manager; + Size = 4; return *this; } inline RuntimeScriptValue &SetStaticArray(void *object, StaticArray *manager) { - Type = kScValStaticArray; - IValue = 0; - Ptr = (char *)object; - StcArr = manager; - Size = 4; + Type = kScValStaticArray; + IValue = 0; + Ptr = (char *)object; + StcArr = manager; + Size = 4; return *this; } inline RuntimeScriptValue &SetDynamicObject(void *object, ICCDynamicObject *manager) { - Type = kScValDynamicObject; - IValue = 0; - Ptr = (char *)object; - DynMgr = manager; - Size = 4; + Type = kScValDynamicObject; + IValue = 0; + Ptr = (char *)object; + DynMgr = manager; + Size = 4; return *this; } inline RuntimeScriptValue &SetPluginObject(void *object, ICCDynamicObject *manager) { - Type = kScValPluginObject; - IValue = 0; - Ptr = (char *)object; - DynMgr = manager; - Size = 4; + Type = kScValPluginObject; + IValue = 0; + Ptr = (char *)object; + DynMgr = manager; + Size = 4; return *this; } inline RuntimeScriptValue &SetStaticFunction(ScriptAPIFunction *pfn) { - Type = kScValStaticFunction; - IValue = 0; - SPfn = pfn; - MgrPtr = nullptr; - Size = 4; + Type = kScValStaticFunction; + IValue = 0; + SPfn = pfn; + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetPluginFunction(void *pfn) { - Type = kScValPluginFunction; - IValue = 0; - Ptr = (char *)pfn; - MgrPtr = nullptr; - Size = 4; + Type = kScValPluginFunction; + IValue = 0; + Ptr = (char *)pfn; + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetObjectFunction(ScriptAPIObjectFunction *pfn) { - Type = kScValObjectFunction; - IValue = 0; - ObjPfn = pfn; - MgrPtr = nullptr; - Size = 4; + Type = kScValObjectFunction; + IValue = 0; + ObjPfn = pfn; + MgrPtr = nullptr; + Size = 4; return *this; } inline RuntimeScriptValue &SetCodePtr(char *ptr) { - Type = kScValCodePtr; - IValue = 0; - Ptr = ptr; - MgrPtr = nullptr; - Size = 4; + Type = kScValCodePtr; + IValue = 0; + Ptr = ptr; + MgrPtr = nullptr; + Size = 4; return *this; } @@ -293,7 +295,8 @@ struct RuntimeScriptValue { inline RuntimeScriptValue ReadValue() { RuntimeScriptValue rval; switch (this->Type) { - case kScValStackPtr: { + case kScValStackPtr: + { if (RValue->Type == kScValData) { rval.SetInt32(*(int32_t *)(RValue->GetPtrWithOffset() + this->IValue)); } else { @@ -301,7 +304,8 @@ struct RuntimeScriptValue { } } break; - case kScValGlobalVar: { + case kScValGlobalVar: + { if (RValue->Type == kScValData) { rval.SetInt32(AGS::Common::Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue)); } else { @@ -310,15 +314,18 @@ struct RuntimeScriptValue { } break; case kScValStaticObject: - case kScValStaticArray: { + case kScValStaticArray: + { rval.SetInt32(this->StcMgr->ReadInt32(this->Ptr, this->IValue)); } break; - case kScValDynamicObject: { + case kScValDynamicObject: + { rval.SetInt32(this->DynMgr->ReadInt32(this->Ptr, this->IValue)); } break; - default: { + default: + { // 64 bit: Memory reads are still 32 bit rval.SetInt32(*(int32_t *)this->GetPtrWithOffset()); } @@ -348,4 +355,6 @@ struct RuntimeScriptValue { intptr_t GetDirectPtr() const; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h index 14d635a2f929..cdcababda4ea 100644 --- a/engines/ags/engine/script/script.h +++ b/engines/ags/engine/script/script.h @@ -33,6 +33,8 @@ #include "game/interactions.h" #include "util/string.h" +namespace AGS3 { + using AGS::Common::Interaction; using AGS::Common::InteractionCommandList; using AGS::Common::InteractionScripts; @@ -52,10 +54,10 @@ void cancel_all_scripts(); ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst); // Queues a script function to be run either called by the engine or from another script void QueueScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0, - const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue()); + const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue()); // Try to run a script function right away void RunScriptFunction(ScriptInstType sc_inst, const char *fn_name, size_t param_count = 0, - const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue()); + const RuntimeScriptValue &p1 = RuntimeScriptValue(), const RuntimeScriptValue &p2 = RuntimeScriptValue()); int RunScriptFunctionIfExists(ccInstance *sci, const char *tsname, int numParam, const RuntimeScriptValue *params); int RunTextScript(ccInstance *sci, const char *tsname); @@ -69,7 +71,7 @@ AGS::Common::String GetScriptName(ccInstance *sci); //============================================================================= -char *make_ts_func_name(const char *base, int iii, int subd); +char *make_ts_func_name(const char *base, int iii, int subd); // Performs various updates to the game after script interpreter returns control to the engine. // Executes actions and does changes that are not executed immediately at script command, for // optimisation and other reasons. @@ -121,4 +123,6 @@ extern std::vector characterScriptObjNames; extern AGS::Common::String objectScriptObjNames[MAX_ROOM_OBJECTS]; extern std::vector guiScriptObjNames; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h index 73eca53983d9..04506a14af95 100644 --- a/engines/ags/engine/script/script_api.h +++ b/engines/ags/engine/script/script_api.h @@ -36,6 +36,8 @@ #include "ac/statobj/agsstaticobject.h" #include "debug/out.h" +namespace AGS3 { + struct RuntimeScriptValue; // TODO: replace void* with base object class when possible; also put array class for parameters @@ -46,7 +48,7 @@ typedef RuntimeScriptValue ScriptAPIObjectFunction(void *self, const RuntimeScri // Uses EITHER sc_args/sc_argc or varg_ptr as parameter list, whichever is not // NULL, with varg_ptr having HIGHER priority. const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, - const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr); + const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr); // Sprintf that takes script values as arguments inline const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, const RuntimeScriptValue *args, int32_t argc) { return ScriptSprintf(buffer, buf_length, format, args, argc, nullptr); @@ -556,4 +558,6 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f RET_CLASS* ret_obj = METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr); \ return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h index 5318859002ed..31e99850a488 100644 --- a/engines/ags/engine/script/script_runtime.h +++ b/engines/ags/engine/script/script_runtime.h @@ -40,6 +40,8 @@ #include "script/cc_script.h" // ccScript #include "script/cc_instance.h" // ccInstance +namespace AGS3 { + struct ICCStaticObject; struct ICCDynamicObject; struct StaticArray; @@ -83,4 +85,6 @@ extern void ccNotifyScriptStillAlive(); extern int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, const RuntimeScriptValue *parms); extern void nullfree(void *data); // in script/script_runtime +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index ba715d7e4b5c..ab3c717ddbcf 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -26,6 +26,8 @@ #include #include "script/cc_instance.h" // ccInstance +namespace AGS3 { + struct ICCDynamicObject; struct ICCStaticObject; @@ -38,7 +40,7 @@ struct ScriptImport { String Name; // import's uid RuntimeScriptValue Value; - ccInstance *InstancePtr; // script instance + ccInstance *InstancePtr; // script instance }; struct SystemImports { @@ -65,4 +67,6 @@ extern SystemImports simp; // perform old style unsafe function calls extern SystemImports simp_for_plugin; +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h index a818248bdbd3..8c726c5571f8 100644 --- a/engines/ags/engine/util/library.h +++ b/engines/ags/engine/util/library.h @@ -26,6 +26,7 @@ #include "core/platform.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -47,7 +48,7 @@ class BaseLibrary { } // namespace Engine } // namespace AGS - +} // namespace AGS3 #if AGS_PLATFORM_OS_WINDOWS #include "library_windows.h" diff --git a/engines/ags/engine/util/library_dummy.h b/engines/ags/engine/util/library_dummy.h index c9ee518e455e..732c474e651b 100644 --- a/engines/ags/engine/util/library_dummy.h +++ b/engines/ags/engine/util/library_dummy.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_UTIL_LIBRARY_DUMMY_H #define AGS_ENGINE_UTIL_LIBRARY_DUMMY_H +namespace AGS3 { namespace AGS { namespace Engine { - class DummyLibrary : BaseLibrary { public: DummyLibrary() { @@ -52,12 +52,10 @@ class DummyLibrary : BaseLibrary { } }; - typedef DummyLibrary Library; - - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index a9eb85019550..89e8e4e1ce5a 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -28,6 +28,8 @@ #include "util/string.h" #include "debug/out.h" +namespace AGS3 { + // FIXME: Replace with a unified way to get the directory which contains the engine binary #if AGS_PLATFORM_OS_ANDROID extern char android_app_directory[256]; @@ -53,11 +55,11 @@ class PosixLibrary : BaseLibrary { AGS::Common::String BuildFilename(AGS::Common::String libraryName) { return String::FromFormat( #if AGS_PLATFORM_OS_MACOS - "lib%s.dylib" + "lib%s.dylib" #else - "lib%s.so" + "lib%s.so" #endif - , libraryName.GetCStr()); + , libraryName.GetCStr()); } AGS::Common::String BuildPath(const char *path, AGS::Common::String libraryName) { @@ -131,9 +133,8 @@ class PosixLibrary : BaseLibrary { typedef PosixLibrary Library; - - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h index 8e5e064042dc..7d40b01d1d11 100644 --- a/engines/ags/engine/util/library_psp.h +++ b/engines/ags/engine/util/library_psp.h @@ -27,6 +27,7 @@ #include "util/string.h" #include "debug/out.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -128,5 +129,6 @@ typedef PSPLibrary Library; } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h index f439f0382860..64882535e901 100644 --- a/engines/ags/engine/util/library_windows.h +++ b/engines/ags/engine/util/library_windows.h @@ -27,15 +27,17 @@ #include "platform/windows/winapi_exclusive.h" #include "util/string.h" +namespace AGS3 { + // Because this class may be exposed to generic code in sake of inlining, // we should avoid including full of macros with common names. #ifdef __cplusplus extern "C" { #endif -WINBASEAPI BOOL WINAPI FreeLibrary(HMODULE hLibModule); -WINBASEAPI FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName); -WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName); + WINBASEAPI BOOL WINAPI FreeLibrary(HMODULE hLibModule); + WINBASEAPI FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName); + WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName); #ifdef __cplusplus } // extern "C" @@ -99,9 +101,8 @@ class WindowsLibrary : BaseLibrary { typedef WindowsLibrary Library; - - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/mutex.h b/engines/ags/engine/util/mutex.h index ea398db9be97..e52534363802 100644 --- a/engines/ags/engine/util/mutex.h +++ b/engines/ags/engine/util/mutex.h @@ -26,6 +26,7 @@ namespace AGS { namespace Engine { +namespace AGS3 { class BaseMutex { public: @@ -44,7 +45,7 @@ class BaseMutex { } // namespace Engine } // namespace AGS - +} // namespace AGS3 #if 0 // insert platforms here diff --git a/engines/ags/engine/util/mutex_base.h b/engines/ags/engine/util/mutex_base.h index 5a0debc9e783..2344dd006d5c 100644 --- a/engines/ags/engine/util/mutex_base.h +++ b/engines/ags/engine/util/mutex_base.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_UTIL_MUTEX_BASE_H #define AGS_ENGINE_UTIL_MUTEX_BASE_H +namespace AGS3 { namespace AGS { namespace Common { - class BaseMutex { public: BaseMutex() = 0; @@ -35,8 +35,8 @@ class BaseMutex { virtual void Unlock() = 0; }; - } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/mutex_lock.h b/engines/ags/engine/util/mutex_lock.h index 6a4524499b31..c772fdb9a508 100644 --- a/engines/ags/engine/util/mutex_lock.h +++ b/engines/ags/engine/util/mutex_lock.h @@ -25,10 +25,10 @@ #include "util/mutex.h" +namespace AGS3 { namespace AGS { namespace Engine { - class MutexLock { private: BaseMutex *_m; @@ -59,8 +59,8 @@ class MutexLock { } }; // class MutexLock - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/mutex_psp.h b/engines/ags/engine/util/mutex_psp.h index 83511ee9c368..15cb079d2e81 100644 --- a/engines/ags/engine/util/mutex_psp.h +++ b/engines/ags/engine/util/mutex_psp.h @@ -27,10 +27,10 @@ #include #include +namespace AGS3 { namespace AGS { namespace Engine { - class PSPMutex : public BaseMutex { public: PSPMutex() { @@ -53,11 +53,10 @@ class PSPMutex : public BaseMutex { SceUID _mutex; }; - typedef PSPMutex Mutex; - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/mutex_pthread.h b/engines/ags/engine/util/mutex_pthread.h index ae81f9e67138..53efb21759d6 100644 --- a/engines/ags/engine/util/mutex_pthread.h +++ b/engines/ags/engine/util/mutex_pthread.h @@ -25,10 +25,10 @@ #include +namespace AGS3 { namespace AGS { namespace Engine { - class PThreadMutex : public BaseMutex { public: inline PThreadMutex() { @@ -53,8 +53,8 @@ class PThreadMutex : public BaseMutex { typedef PThreadMutex Mutex; - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/mutex_std.h b/engines/ags/engine/util/mutex_std.h index 0565db6579f3..abe1f8f2c39d 100644 --- a/engines/ags/engine/util/mutex_std.h +++ b/engines/ags/engine/util/mutex_std.h @@ -25,12 +25,14 @@ #include +namespace AGS3 { namespace AGS { namespace Engine { class StdMutex : public BaseMutex { public: - inline StdMutex() : mutex_() {} + inline StdMutex() : mutex_() { + } inline ~StdMutex() override = default; StdMutex &operator=(const StdMutex &) = delete; @@ -51,5 +53,6 @@ typedef StdMutex Mutex; } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/mutex_wii.h b/engines/ags/engine/util/mutex_wii.h index 45b935e8a23e..1930a32c3c71 100644 --- a/engines/ags/engine/util/mutex_wii.h +++ b/engines/ags/engine/util/mutex_wii.h @@ -25,10 +25,10 @@ #include +namespace AGS3 { namespace AGS { namespace Engine { - class WiiMutex : public BaseMutex { public: inline WiiMutex() { @@ -51,11 +51,10 @@ class WiiMutex : public BaseMutex { mutex_t _mutex; }; - typedef WiiMutex Mutex; - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/mutex_windows.h b/engines/ags/engine/util/mutex_windows.h index 0e27e000bd61..7f697a702bec 100644 --- a/engines/ags/engine/util/mutex_windows.h +++ b/engines/ags/engine/util/mutex_windows.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_UTIL_MUTEXT_WINDOWS_H #define AGS_ENGINE_UTIL_MUTEXT_WINDOWS_H +namespace AGS3 { namespace AGS { namespace Engine { - class WindowsMutex : public BaseMutex { public: WindowsMutex() { @@ -57,11 +57,10 @@ class WindowsMutex : public BaseMutex { HANDLE _mutex; }; - typedef WindowsMutex Mutex; - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/scaling.h b/engines/ags/engine/util/scaling.h index 98881e7b6853..b0f980b14d17 100644 --- a/engines/ags/engine/util/scaling.h +++ b/engines/ags/engine/util/scaling.h @@ -35,6 +35,7 @@ #include "core/types.h" #include "util/geometry.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -156,5 +157,6 @@ struct PlaneScaling { } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/thread.h b/engines/ags/engine/util/thread.h index 482d3de9857b..b69a8b7139a4 100644 --- a/engines/ags/engine/util/thread.h +++ b/engines/ags/engine/util/thread.h @@ -23,13 +23,13 @@ #ifndef AGS_ENGINE_UTIL_THREAD_H #define AGS_ENGINE_UTIL_THREAD_H +namespace AGS3 { namespace AGS { namespace Engine { - class BaseThread { public: - typedef void(* AGSThreadEntry)(); + typedef void(*AGSThreadEntry)(); BaseThread() = default; virtual ~BaseThread() = default; @@ -51,6 +51,7 @@ class BaseThread { } // namespace Engine } // namespace AGS +} // namespace AGS3 #if 0 // insert platforms here diff --git a/engines/ags/engine/util/thread_psp.h b/engines/ags/engine/util/thread_psp.h index eab3e5df018b..6785275b10e2 100644 --- a/engines/ags/engine/util/thread_psp.h +++ b/engines/ags/engine/util/thread_psp.h @@ -27,10 +27,10 @@ #include #include +namespace AGS3 { namespace AGS { namespace Engine { - class PSPThread : public BaseThread { public: PSPThread() { @@ -98,8 +98,8 @@ class PSPThread : public BaseThread { typedef PSPThread Thread; - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/thread_pthread.h b/engines/ags/engine/util/thread_pthread.h index 89e9180f8cba..83108f5c6e63 100644 --- a/engines/ags/engine/util/thread_pthread.h +++ b/engines/ags/engine/util/thread_pthread.h @@ -25,10 +25,10 @@ #include +namespace AGS3 { namespace AGS { namespace Engine { - class PThreadThread : public BaseThread { public: PThreadThread() { @@ -97,8 +97,8 @@ class PThreadThread : public BaseThread { typedef PThreadThread Thread; - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/thread_std.h b/engines/ags/engine/util/thread_std.h index 24b870b28b54..1dcc7432f9e9 100644 --- a/engines/ags/engine/util/thread_std.h +++ b/engines/ags/engine/util/thread_std.h @@ -26,6 +26,7 @@ #include #include +namespace AGS3 { namespace AGS { namespace Engine { @@ -98,5 +99,6 @@ typedef StdThread Thread; } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/thread_wii.h b/engines/ags/engine/util/thread_wii.h index 91a67ef8a42c..5b61d5dec978 100644 --- a/engines/ags/engine/util/thread_wii.h +++ b/engines/ags/engine/util/thread_wii.h @@ -25,10 +25,10 @@ #include +namespace AGS3 { namespace AGS { namespace Engine { - class WiiThread : public BaseThread { public: WiiThread() { @@ -100,5 +100,6 @@ typedef WiiThread Thread; } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/util/thread_windows.h b/engines/ags/engine/util/thread_windows.h index e55b243aa351..77e3622b466f 100644 --- a/engines/ags/engine/util/thread_windows.h +++ b/engines/ags/engine/util/thread_windows.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_UTIL_THREAD_WINDOWS_H #define AGS_ENGINE_UTIL_THREAD_WINDOWS_H +namespace AGS3 { namespace AGS { namespace Engine { - class WindowsThread : public BaseThread { public: WindowsThread() { @@ -52,7 +52,7 @@ class WindowsThread : public BaseThread { if ((_thread != NULL) && (!_running)) { DWORD result = ResumeThread(_thread); - _running = (result != (DWORD) - 1); + _running = (result != (DWORD)-1); return _running; } else { return false; @@ -95,11 +95,10 @@ class WindowsThread : public BaseThread { } }; - typedef WindowsThread Thread; - } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/ac/audiocliptype.h b/engines/ags/shared/ac/audiocliptype.h index 8b36ad01dd45..9123a56c7232 100644 --- a/engines/ags/shared/ac/audiocliptype.h +++ b/engines/ags/shared/ac/audiocliptype.h @@ -23,12 +23,15 @@ #ifndef AGS_SHARED_AC_AUDIOCLIPTYPE_H #define AGS_SHARED_AC_AUDIOCLIPTYPE_H +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define AUDIO_CLIP_TYPE_SOUND 1 @@ -45,4 +48,6 @@ struct AudioClipType { void WriteToSavegame(Common::Stream *out) const; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h index 4f3cad6ebf0b..2649887f8595 100644 --- a/engines/ags/shared/ac/characterinfo.h +++ b/engines/ags/shared/ac/characterinfo.h @@ -25,11 +25,14 @@ #include "ac/common_defines.h" // constants +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define MAX_INV 301 @@ -157,4 +160,6 @@ struct OldCharacterInfo { #define COPY_CHAR_VAR(name) ci->name = oci->name void ConvertOldCharacterToNew(OldCharacterInfo *oci, CharacterInfo *ci); +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/common.h b/engines/ags/shared/ac/common.h index 2d857485f6ac..03ef906265cb 100644 --- a/engines/ags/shared/ac/common.h +++ b/engines/ags/shared/ac/common.h @@ -23,6 +23,8 @@ #ifndef AGS_SHARED_AC_COMMON_H #define AGS_SHARED_AC_COMMON_H +namespace AGS3 { + // These are the project-dependent functions, they are defined both in Engine.App and AGS.Native. void quit(const char *); void quitprintf(const char *fmt, ...); @@ -32,4 +34,6 @@ int get_our_eip(); extern const char *game_file_sig; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/common_defines.h b/engines/ags/shared/ac/common_defines.h index c7b658005eb5..0311a452fe05 100644 --- a/engines/ags/shared/ac/common_defines.h +++ b/engines/ags/shared/ac/common_defines.h @@ -25,6 +25,8 @@ #include "core/platform.h" +namespace AGS3 { + #define EXIT_NORMAL 0 #define EXIT_CRASH 92 #define EXIT_ERROR 93 @@ -128,4 +130,6 @@ #define OBJF_LEGACY_LOCKED 0x40 // object position is locked in the editor (OBSOLETE since 3.5.0) #define OBJF_HASLIGHT 0x80 // the tint_light is valid and treated as brightness +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/dialogtopic.h b/engines/ags/shared/ac/dialogtopic.h index dbffaf2a0bea..87502041be3d 100644 --- a/engines/ags/shared/ac/dialogtopic.h +++ b/engines/ags/shared/ac/dialogtopic.h @@ -23,11 +23,14 @@ #ifndef AGS_SHARED_AC_DIALOGTOPIC_H #define AGS_SHARED_AC_DIALOGTOPIC_H +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later // [IKM] This is *conversation* dialog, not *gui* dialog, mind you! @@ -73,5 +76,6 @@ struct DialogTopic { void WriteToSavegame(Common::Stream *out) const; }; +} // namespace AGS3 #endif diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index c8e18fa50241..be246866fa99 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -25,11 +25,14 @@ #include "util/string.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later enum AudioFileType { @@ -60,4 +63,6 @@ struct ScriptAudioClip { void ReadFromFile(Common::Stream *in); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/game_version.h b/engines/ags/shared/ac/game_version.h index 9a11424b5648..0a0cbca5fd36 100644 --- a/engines/ags/shared/ac/game_version.h +++ b/engines/ags/shared/ac/game_version.h @@ -29,6 +29,8 @@ #ifndef AGS_SHARED_AC_GAMEVERSION_H #define AGS_SHARED_AC_GAMEVERSION_H +namespace AGS3 { + /* Game data versions and changes: @@ -152,4 +154,6 @@ enum GameDataVersion { extern GameDataVersion loaded_game_file_version; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index 43d689602216..21e252c3b4d5 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -33,6 +33,8 @@ #include "game/customproperties.h" #include "game/main_game_file.h" // TODO: constants to separate header or split out reading functions +namespace AGS3 { + namespace AGS { namespace Common { struct AssetLibInfo; @@ -40,8 +42,8 @@ struct Interaction; struct InteractionScripts; typedef std::shared_ptr PInteraction; typedef std::shared_ptr PInteractionScripts; -} -} +} // namespace Shared +} // namespace AGS using AGS::Common::PInteraction; using AGS::Common::PInteractionScripts; @@ -50,7 +52,7 @@ struct OldGameSetupStruct; // TODO: split GameSetupStruct into struct used to hold loaded game data, and actual runtime object -struct GameSetupStruct: public GameSetupStructBase { +struct GameSetupStruct : public GameSetupStructBase { // This array is used only to read data into; // font parameters are then put and queried in the fonts module // TODO: split into installation params (used only when reading) and runtime params @@ -79,8 +81,8 @@ struct GameSetupStruct: public GameSetupStructBase { char saveGameFileExtension[MAX_SG_EXT_LENGTH]; char saveGameFolderName[MAX_SG_FOLDER_LEN]; int roomCount; - int *roomNumbers; - char **roomNames; + int *roomNumbers; + char **roomNames; std::vector audioClips; std::vector audioClipTypes; // A clip to play when player gains score in game @@ -155,7 +157,7 @@ struct GameSetupStruct: public GameSetupStructBase { // Functions for reading and writing appropriate data from/to save game void ReadFromSaveGame_v321(Common::Stream *in, char *gswas, ccScript *compsc, CharacterInfo *chwas, - WordsDictionary *olddict, char **mesbk); + WordsDictionary *olddict, char **mesbk); void ReadFromSavegame(Common::PStream in); void WriteForSavegame(Common::PStream out); @@ -167,4 +169,6 @@ void ConvertOldGameStruct(OldGameSetupStruct *ogss, GameSetupStruct *gss); // Finds an audio clip using legacy convention index ScriptAudioClip *GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_music, int num); +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h index 70b0818ad37f..7edfbbad0134 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.h +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -28,12 +28,15 @@ #include "util/string.h" #include "util/wgt2allg.h" // color (allegro RGB) +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later struct WordsDictionary; @@ -244,4 +247,6 @@ struct GameSetupStructBase { int _screenUpscaleMult; }; +// namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/gamestructdefines.h b/engines/ags/shared/ac/gamestructdefines.h index 705c3bf37a0e..e865bc296b49 100644 --- a/engines/ags/shared/ac/gamestructdefines.h +++ b/engines/ags/shared/ac/gamestructdefines.h @@ -26,6 +26,8 @@ #include "util/geometry.h" #include "core/types.h" +namespace AGS3 { + #define PAL_GAMEWIDE 0 #define PAL_LOCKED 1 #define PAL_BACKGROUND 2 @@ -117,21 +119,21 @@ #define MAX_SG_FOLDER_LEN 50 enum GameResolutionType { - kGameResolution_Undefined = -1, + kGameResolution_Undefined = -1, // definition of 320x200 in very old versions of the engine (somewhere pre-2.56) - kGameResolution_Default = 0, - kGameResolution_320x200 = 1, - kGameResolution_320x240 = 2, - kGameResolution_640x400 = 3, - kGameResolution_640x480 = 4, - kGameResolution_800x600 = 5, - kGameResolution_1024x768 = 6, - kGameResolution_1280x720 = 7, - kGameResolution_Custom = 8, + kGameResolution_Default = 0, + kGameResolution_320x200 = 1, + kGameResolution_320x240 = 2, + kGameResolution_640x400 = 3, + kGameResolution_640x480 = 4, + kGameResolution_800x600 = 5, + kGameResolution_1024x768 = 6, + kGameResolution_1280x720 = 7, + kGameResolution_Custom = 8, kNumGameResolutions, - kGameResolution_LastLoRes = kGameResolution_320x240, - kGameResolution_FirstHiRes = kGameResolution_640x400 + kGameResolution_LastLoRes = kGameResolution_320x240, + kGameResolution_FirstHiRes = kGameResolution_640x400 }; inline bool IsLegacyHiRes(GameResolutionType resolution) { @@ -143,8 +145,8 @@ Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox = false) // Automatic numbering of dialog options (OPT_DIALOGNUMBERED) enum DialogOptionNumbering { kDlgOptNoNumbering = -1, - kDlgOptKeysOnly = 0, // implicit key shortcuts - kDlgOptNumbering = 1 // draw option indices and use key shortcuts + kDlgOptKeysOnly = 0, // implicit key shortcuts + kDlgOptNumbering = 1 // draw option indices and use key shortcuts }; // Version of the script api (OPT_BASESCRIPTAPI and OPT_SCRIPTCOMPATLEV). @@ -170,9 +172,9 @@ enum ScriptAPIVersion { // Determines whether the graphics renderer should scale sprites at the final // screen resolution, as opposed to native resolution enum RenderAtScreenRes { - kRenderAtScreenRes_UserDefined = 0, - kRenderAtScreenRes_Enabled = 1, - kRenderAtScreenRes_Disabled = 2, + kRenderAtScreenRes_UserDefined = 0, + kRenderAtScreenRes_Enabled = 1, + kRenderAtScreenRes_Disabled = 2, }; // Method to use when blending two sprites with alpha channel @@ -252,4 +254,6 @@ struct FontInfo { FontInfo(); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/interfacebutton.h b/engines/ags/shared/ac/interfacebutton.h index 3918b8e17280..ab599b59126e 100644 --- a/engines/ags/shared/ac/interfacebutton.h +++ b/engines/ags/shared/ac/interfacebutton.h @@ -23,6 +23,8 @@ #ifndef AGS_SHARED_AC_INTERFACEBUTTON_H #define AGS_SHARED_AC_INTERFACEBUTTON_H +namespace AGS3 { + #define MAXBUTTON 20 #define IBFLG_ENABLED 1 #define IBFLG_INVBOX 2 @@ -34,4 +36,6 @@ struct InterfaceButton { void set(int xx, int yy, int picc, int overpicc, int actionn); }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/interfaceelement.h b/engines/ags/shared/ac/interfaceelement.h index a81a9d6562bb..1b897de03a57 100644 --- a/engines/ags/shared/ac/interfaceelement.h +++ b/engines/ags/shared/ac/interfaceelement.h @@ -25,6 +25,8 @@ #include "ac/interfacebutton.h" // InterfaceButton +namespace AGS3 { + // this struct should go in a Game struct, not the room structure. struct InterfaceElement { int x, y, x2, y2; @@ -56,4 +58,6 @@ button[0].set(0,13,3,-1,0); } };*/ +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/inventoryiteminfo.h b/engines/ags/shared/ac/inventoryiteminfo.h index dce76e5c10e8..29adfffaffb8 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.h +++ b/engines/ags/shared/ac/inventoryiteminfo.h @@ -23,11 +23,14 @@ #ifndef AGS_SHARED_AC_INVENTORYITEMINFO_H #define AGS_SHARED_AC_INVENTORYITEMINFO_H +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define IFLG_STARTWITH 1 @@ -44,4 +47,6 @@ struct InventoryItemInfo { void WriteToSavegame(Common::Stream *out) const; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/mousecursor.h b/engines/ags/shared/ac/mousecursor.h index 72484896ff9e..2ebaebe9cad6 100644 --- a/engines/ags/shared/ac/mousecursor.h +++ b/engines/ags/shared/ac/mousecursor.h @@ -23,11 +23,14 @@ #ifndef AGS_SHARED_AC_MOUSECURSOR_H #define AGS_SHARED_AC_MOUSECURSOR_H +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define MCF_ANIMMOVE 1 @@ -49,4 +52,6 @@ struct MouseCursor { void WriteToSavegame(Common::Stream *out) const; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/oldgamesetupstruct.h b/engines/ags/shared/ac/oldgamesetupstruct.h index ee9f24b29105..1ceb6b25c923 100644 --- a/engines/ags/shared/ac/oldgamesetupstruct.h +++ b/engines/ags/shared/ac/oldgamesetupstruct.h @@ -33,6 +33,8 @@ #include "ac/wordsdictionary.h" // WordsDictionary #include "script/cc_script.h" // ccScript +namespace AGS3 { + struct OriGameSetupStruct { char gamename[30]; char options[20]; @@ -42,14 +44,14 @@ struct OriGameSetupStruct { int numiface; int numviews; MouseCursor mcurs[10]; - char *globalscript; + char *globalscript; int numcharacters; - OldCharacterInfo *chars; + OldCharacterInfo *chars; #ifdef UNUSED_CODE EventBlock __charcond[50]; // [IKM] 2012-06-22: does not seem to be used anywhere EventBlock __invcond[100]; // same #endif - ccScript *compiled_script; + ccScript *compiled_script; int playercharacter; unsigned char __old_spriteflags[2100]; int totalscore; @@ -65,7 +67,7 @@ struct OriGameSetupStruct { int reserved[2]; short numlang; char langcodes[MAXLANGUAGE][3]; - char *messages[MAXGLOBALMES]; + char *messages[MAXGLOBALMES]; }; struct OriGameSetupStruct2 : public OriGameSetupStruct { @@ -80,4 +82,6 @@ struct OldGameSetupStruct : public OriGameSetupStruct2 { unsigned char spriteflags[LEGACY_MAX_SPRITES_V25]; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index 1f11d9e70e94..2d8a5a5eaa4e 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -50,12 +50,15 @@ #include "core/platform.h" #include "util/error.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later typedef AGS::Common::HError HAGSError; @@ -247,4 +250,6 @@ class SpriteCache { extern SpriteCache spriteset; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index 824c3c8cde30..3fa144444dbe 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -25,11 +25,14 @@ #include +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define VFLG_FLIPSPRITE 1 @@ -87,4 +90,6 @@ struct ViewStruct272 { void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *newv); +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h index 8acf1250f35d..ea2fe999082d 100644 --- a/engines/ags/shared/ac/wordsdictionary.h +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -25,11 +25,14 @@ #include "core/types.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define MAX_PARSER_WORD_LENGTH 30 @@ -64,4 +67,6 @@ extern void encrypt_text(char *toenc); extern void write_string_encrypt(Common::Stream *out, const char *s); extern void write_dictionary(WordsDictionary *dict, Common::Stream *out); +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/api/stream_api.h b/engines/ags/shared/api/stream_api.h index b0b03dc2f361..738765a513d4 100644 --- a/engines/ags/shared/api/stream_api.h +++ b/engines/ags/shared/api/stream_api.h @@ -38,6 +38,7 @@ // plugins, and let plugin developers include them manually in plugin sources. #include "core/types.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -93,5 +94,6 @@ class IAGSStream { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index c5601a266cd0..0a8f7c4c2c9d 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -32,6 +32,7 @@ #include #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -62,5 +63,6 @@ struct AssetLibInfo { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h index 70b1c4c596cc..d2937b661b16 100644 --- a/engines/ags/shared/core/assetmanager.h +++ b/engines/ags/shared/core/assetmanager.h @@ -46,6 +46,7 @@ #include "util/file.h" // TODO: extract filestream mode constants or introduce generic ones +namespace AGS3 { namespace AGS { namespace Common { @@ -62,10 +63,10 @@ enum AssetSearchPriority { }; enum AssetError { - kAssetNoError = 0, - kAssetErrNoLibFile = -1, // library file not found or can't be read - kAssetErrLibParse = -2, // bad library file format or read error - kAssetErrNoManager = -6, // asset manager not initialized + kAssetNoError = 0, + kAssetErrNoLibFile = -1, // library file not found or can't be read + kAssetErrLibParse = -2, // bad library file format or read error + kAssetErrNoManager = -6, // asset manager not initialized }; // Explicit location of asset data @@ -111,9 +112,9 @@ class AssetManager { static bool GetAssetLocation(const String &asset_name, AssetLocation &loc); static bool DoesAssetExist(const String &asset_name); - static Stream *OpenAsset(const String &asset_name, - FileOpenMode open_mode = kFile_Open, - FileWorkMode work_mode = kFile_Read); + static Stream *OpenAsset(const String &asset_name, + FileOpenMode open_mode = kFile_Open, + FileWorkMode work_mode = kFile_Read); private: AssetManager(); @@ -134,18 +135,18 @@ class AssetManager { bool _DoesAssetExist(const String &asset_name); - AssetInfo *FindAssetByFileName(const String &asset_name); + AssetInfo *FindAssetByFileName(const String &asset_name); String MakeLibraryFileNameForAsset(const AssetInfo *asset); bool GetAssetFromLib(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); bool GetAssetFromDir(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); bool GetAssetByPriority(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); - Stream *OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode); + Stream *OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode); - static AssetManager *_theAssetManager; + static AssetManager *_theAssetManager; AssetSearchPriority _searchPriority; - AssetLibInfo &_assetLib; + AssetLibInfo &_assetLib; String _basePath; // library's parent path (directory) soff_t _lastAssetSize; // size of asset that was opened last time }; @@ -155,5 +156,6 @@ String GetAssetErrorText(AssetError err); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h index c97ba949cd5f..40d7cc1754ec 100644 --- a/engines/ags/shared/core/platform.h +++ b/engines/ags/shared/core/platform.h @@ -23,6 +23,8 @@ #ifndef AGS_SHARED_CORE_PLATFORM_H #define AGS_SHARED_CORE_PLATFORM_H +namespace AGS3 { + // platform definitions. Not intended for replacing types or checking for libraries. // check Android first because sometimes it can get confused with host OS @@ -124,4 +126,6 @@ #define AGS_PLATFORM_DEBUG (0) #endif +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index 90cf583270b2..c7d0484462ce 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -34,6 +34,8 @@ #include // for size_t #include // for _WORDSIZE +namespace AGS3 { + #ifndef NULL #define NULL nullptr #endif @@ -64,8 +66,10 @@ typedef int64_t soff_t; // TODO: use distinct fixed point class enum { - kShift = 16, - kUnit = 1 << kShift + kShift = 16, + kUnit = 1 << kShift }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index 696881b65d88..21e733206b15 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -54,6 +54,7 @@ #include "util/string.h" #include "util/string_types.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -64,8 +65,10 @@ struct DebugGroup { DebugGroupID UID; String OutputName; - DebugGroup() {} - DebugGroup(DebugGroupID id, String out_name) : UID(id), OutputName(out_name) {} + DebugGroup() { + } + DebugGroup(DebugGroupID id, String out_name) : UID(id), OutputName(out_name) { + } }; // DebugOutput is a slot for IOutputHandler with its own group filter @@ -141,7 +144,8 @@ class DebugManager { PDebugOutput Target; bool Suppressed; - OutputSlot() : Suppressed(false) {} + OutputSlot() : Suppressed(false) { + } }; typedef std::vector GroupVector; @@ -161,7 +165,8 @@ class DebugManager { // TODO: move this to the dynamically allocated engine object whenever it is implemented extern DebugManager DbgMgr; -} // namespace Common -} // namespace AGS +} // namespace Common +} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h index 9f00c411dcf9..2d7efa27fdfa 100644 --- a/engines/ags/shared/debugging/out.h +++ b/engines/ags/shared/debugging/out.h @@ -79,35 +79,36 @@ #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { // Message types provide distinction for debug messages by their intent. enum MessageType { - kDbgMsg_None = 0, + kDbgMsg_None = 0, // Alerts may be informative messages with topmost level of importance, // such as reporting engine startup and shutdown. - kDbgMsg_Alert , + kDbgMsg_Alert, // Fatal errors are ones that make program abort immediately. - kDbgMsg_Fatal , + kDbgMsg_Fatal, // Error messages are about engine not being able to perform requested // operation in a situation when that will affect game playability and // further execution. - kDbgMsg_Error , + kDbgMsg_Error, // Warnings are made when unexpected or non-standart behavior // is detected in program, which is not immediately critical, // but may be a symptom of a bigger problem. - kDbgMsg_Warn , + kDbgMsg_Warn, // General information messages. - kDbgMsg_Info , + kDbgMsg_Info, // Debug reason is for arbitrary information about events and current // game state. - kDbgMsg_Debug , + kDbgMsg_Debug, // Convenient aliases - kDbgMsg_Default = kDbgMsg_Debug, - kDbgMsg_All = kDbgMsg_Debug + kDbgMsg_Default = kDbgMsg_Debug, + kDbgMsg_All = kDbgMsg_Debug }; // This enumeration is a list of common hard-coded groups, but more could @@ -131,9 +132,12 @@ struct DebugGroupID { uint32_t ID; String SID; - DebugGroupID() : ID(kDbgGroup_None) {} - DebugGroupID(uint32_t id, const String &sid = "") : ID(id), SID(sid) {} - DebugGroupID(const String &sid) : ID(kDbgGroup_None), SID(sid) {} + DebugGroupID() : ID(kDbgGroup_None) { + } + DebugGroupID(uint32_t id, const String &sid = "") : ID(id), SID(sid) { + } + DebugGroupID(const String &sid) : ID(kDbgGroup_None), SID(sid) { + } // Tells if any of the id components is valid bool IsValid() const { return ID != kDbgGroup_None || !SID.IsEmpty(); @@ -155,9 +159,10 @@ void Printf(MessageType mt, const char *fmt, ...); // Output formatted message of given group and type void Printf(DebugGroupID group_id, MessageType mt, const char *fmt, ...); -} // namespace Debug +} // namespace Debug -} // namespace Common -} // namespace AGS +} // namespace Common +} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h index 8fc4a1717177..86ddc57fe606 100644 --- a/engines/ags/shared/debugging/outputhandler.h +++ b/engines/ags/shared/debugging/outputhandler.h @@ -33,6 +33,7 @@ #include "debug/out.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -42,7 +43,8 @@ struct DebugMessage { String GroupName; MessageType MT; - DebugMessage() : GroupID(kDbgGroup_None), MT(kDbgMsg_None) {} + DebugMessage() : GroupID(kDbgGroup_None), MT(kDbgMsg_None) { + } DebugMessage(const String &text, uint32_t group_id, const String &group_name, MessageType mt) : Text(text) , GroupID(group_id) @@ -60,7 +62,8 @@ class IOutputHandler { virtual void PrintMessage(const DebugMessage &msg) = 0; }; -} // namespace Common -} // namespace AGS +} // namespace Common +} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/font/agsfontrenderer.h b/engines/ags/shared/font/agsfontrenderer.h index dad4a7a529a3..be77d8223887 100644 --- a/engines/ags/shared/font/agsfontrenderer.h +++ b/engines/ags/shared/font/agsfontrenderer.h @@ -23,6 +23,8 @@ #ifndef AGS_SHARED_FONT_AGSFONTRENDERER_H #define AGS_SHARED_FONT_AGSFONTRENDERER_H +namespace AGS3 { + struct BITMAP; // WARNING: this interface is exposed for plugins and declared for the second time in agsplugin.h @@ -61,4 +63,6 @@ class IAGSFontRenderer2 { ~IAGSFontRenderer2() = default; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index 81bdc67ef920..37586eba6862 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -29,11 +29,13 @@ // TODO: we need to make some kind of TextManager class of this module +namespace AGS3 { namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; class IAGSFontRenderer; @@ -131,7 +133,8 @@ size_t split_lines(const char *texx, SplitLines &lines, int width, int fontNumbe namespace AGS { namespace Common { extern SplitLines Lines; -} -} +} // namespace Shared +} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 6f29bd2490b6..84326fe49ade 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -26,6 +26,8 @@ #include #include "font/agsfontrenderer.h" +namespace AGS3 { + struct ALFONT_FONT; class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { @@ -38,7 +40,7 @@ class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { } int GetTextWidth(const char *text, int fontNumber) override; int GetTextHeight(const char *text, int fontNumber) override; - void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override ; + void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override; void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override; void EnsureTextValidForFont(char *text, int fontNumber) override; @@ -48,10 +50,12 @@ class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { private: struct FontData { - ALFONT_FONT *AlFont; + ALFONT_FONT *AlFont; FontRenderParams Params; }; std::map _fontData; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index e5020fe76423..ebfb0a4ba03b 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -49,11 +49,13 @@ #include #include "core/types.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS enum WFNError { kWFNErr_NoError, @@ -106,4 +108,6 @@ class WFNFont { static const WFNChar _emptyChar; // a dummy character to substitute bad symbols }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index c2fed5015983..ac816f647f5d 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -26,6 +26,8 @@ #include #include "font/agsfontrenderer.h" +namespace AGS3 { + class WFNFont; class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { @@ -44,10 +46,12 @@ class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { private: struct FontData { - WFNFont *Font; + WFNFont *Font; FontRenderParams Params; }; std::map _fontData; }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index 51d546448112..cd36b985a090 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -40,6 +40,8 @@ #include "util/string.h" #include "util/string_types.h" +namespace AGS3 { + #define LEGACY_MAX_CUSTOM_PROPERTIES 30 // NOTE: for some reason the property name stored in schema object was limited // to only 20 characters, while the custom properties map could hold up to 200. @@ -102,5 +104,6 @@ void WriteValues(const StringIMap &map, Stream *out); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index 61728294cb67..02b440f39366 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -52,6 +52,8 @@ #include #include "util/string_types.h" +namespace AGS3 { + #define LOCAL_VARIABLE_OFFSET 10000 #define MAX_GLOBAL_VARIABLES 100 #define MAX_ACTION_ARGS 5 @@ -63,9 +65,9 @@ namespace Common { enum InterValType { kInterValLiteralInt = 1, - kInterValVariable = 2, - kInterValBoolean = 3, - kInterValCharnum = 4 + kInterValVariable = 2, + kInterValBoolean = 3, + kInterValCharnum = 4 }; enum InteractionVersion { @@ -179,9 +181,9 @@ typedef std::shared_ptr PInteraction; // Legacy pre-3.0 kind of global and local room variables struct InteractionVariable { - String Name {}; - char Type {'\0'}; - int Value {0}; + String Name{}; + char Type{ '\0' }; + int Value{ 0 }; InteractionVariable(); InteractionVariable(const String &name, char type, int val); @@ -209,4 +211,6 @@ typedef std::shared_ptr PInteractionScripts; extern AGS::Common::InteractionVariable globalvars[MAX_GLOBAL_VARIABLES]; extern int numGlobalVars; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 31eb11a56833..86fd9241a97c 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -42,6 +42,8 @@ #include "util/string.h" #include "util/version.h" +namespace AGS3 { + struct GameSetupStruct; struct DialogTopic; struct ViewStruct; @@ -107,9 +109,9 @@ struct MainGameSource { // directly. This is temporary solution that has to be resolved by the future // code refactoring. struct LoadedGameEntities { - GameSetupStruct &Game; - DialogTopic *&Dialogs; - ViewStruct *&Views; + GameSetupStruct &Game; + DialogTopic *&Dialogs; + ViewStruct *&Views; PScript GlobalScript; PScript DialogScript; std::vector ScriptModules; @@ -148,5 +150,6 @@ void FixupSaveDirectory(GameSetupStruct &game); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index 53a922689f5b..a368913e91ca 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -32,6 +32,8 @@ #include #include "util/string.h" +namespace AGS3 { + // TODO: why 10 MB limit? #define PLUGIN_SAVEBUFFERSIZE 10247680 @@ -45,10 +47,12 @@ struct PluginInfo { std::shared_ptr Data; size_t DataLen; - PluginInfo() : DataLen(0) {} + PluginInfo() : DataLen(0) { + } }; } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index 0a08f66597bc..be91dbc51947 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -38,6 +38,8 @@ #include "util/stream.h" #include "util/string.h" +namespace AGS3 { + struct SpriteInfo; namespace AGS { namespace Common { @@ -94,5 +96,6 @@ HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersio } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/game/room_version.h b/engines/ags/shared/game/room_version.h index 5c099110f822..33d04dc39f21 100644 --- a/engines/ags/shared/game/room_version.h +++ b/engines/ags/shared/game/room_version.h @@ -29,6 +29,8 @@ #ifndef AGS_SHARED_GAME_ROOMVERSION_H #define AGS_SHARED_GAME_ROOMVERSION_H +namespace AGS3 { + /* room file versions history 8: final v1.14 release 9: intermediate v2 alpha releases @@ -92,4 +94,6 @@ enum RoomFileVersion { kRoomVersion_Current = kRoomVersion_3508 }; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index 590275c5017a..1895d689c8c4 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -54,6 +54,8 @@ #include "util/geometry.h" #include "util/wgt2allg.h" // color (allegro RGB) +namespace AGS3 { + struct ccScript; struct SpriteInfo; typedef std::shared_ptr PScript; @@ -74,18 +76,18 @@ enum RoomAreaMask { // Room's audio volume modifier enum RoomVolumeMod { kRoomVolumeQuietest = -3, - kRoomVolumeQuieter = -2, - kRoomVolumeQuiet = -1, - kRoomVolumeNormal = 0, - kRoomVolumeLoud = 1, - kRoomVolumeLouder = 2, - kRoomVolumeLoudest = 3, + kRoomVolumeQuieter = -2, + kRoomVolumeQuiet = -1, + kRoomVolumeNormal = 0, + kRoomVolumeLoud = 1, + kRoomVolumeLouder = 2, + kRoomVolumeLoudest = 3, // These two options are only settable at runtime by SetMusicVolume() - kRoomVolumeExtra1 = 4, - kRoomVolumeExtra2 = 5, + kRoomVolumeExtra1 = 4, + kRoomVolumeExtra2 = 5, - kRoomVolumeMin = kRoomVolumeQuietest, - kRoomVolumeMax = kRoomVolumeExtra2, + kRoomVolumeMin = kRoomVolumeQuietest, + kRoomVolumeMax = kRoomVolumeExtra2, }; // Flag tells that walkable area does not have continious zoom @@ -302,7 +304,7 @@ class RoomStruct { // Gets region's tint luminance in 0 to 100 range value; returns 0 if region's light level is set int GetRegionTintLuminance(int id) const; -// TODO: all members are currently public because they are used everywhere; hide them later + // TODO: all members are currently public because they are used everywhere; hide them later public: // Game's unique ID, corresponds to GameSetupStructBase::uniqueid. // If this field has a valid value and does not match actual game's id, @@ -384,5 +386,6 @@ PBitmap FixBitmap(PBitmap bmp, int dst_width, int dst_height); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 98771376e03c..77d0ea83fcde 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -36,6 +36,7 @@ #include "core/types.h" #include "gfx/bitmap.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -218,12 +219,11 @@ class Bitmap { void SetScanLine(int index, unsigned char *data, int data_size = -1); private: - BITMAP *_alBitmap; - bool _isDataOwner; + BITMAP *_alBitmap; + bool _isDataOwner; }; - namespace BitmapHelper { // TODO: revise those functions later (currently needed in a few very specific cases) // NOTE: the resulting object __owns__ bitmap data from now on @@ -234,5 +234,6 @@ Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/gfx/bitmap.h b/engines/ags/shared/gfx/bitmap.h index 3dac81c1e60a..b370c9a004a8 100644 --- a/engines/ags/shared/gfx/bitmap.h +++ b/engines/ags/shared/gfx/bitmap.h @@ -31,6 +31,7 @@ #include "util/geometry.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -87,5 +88,6 @@ void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_ } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/gfx/gfx_def.h b/engines/ags/shared/gfx/gfx_def.h index 787839fd8dae..4e84b51bdd97 100644 --- a/engines/ags/shared/gfx/gfx_def.h +++ b/engines/ags/shared/gfx/gfx_def.h @@ -29,12 +29,13 @@ #ifndef AGS_SHARED_GFX_GFXDEF_H #define AGS_SHARED_GFX_GFXDEF_H +namespace AGS3 { namespace AGS { namespace Common { enum BlendMode { // free blending (ARGB -> ARGB) modes - kBlendMode_NoAlpha = 0, // ignore alpha channel + kBlendMode_NoAlpha = 0, // ignore alpha channel kBlendMode_Alpha, // alpha-blend src to dest, combining src & dest alphas // NOTE: add new modes here @@ -104,5 +105,6 @@ inline int LegacyTrans100ToAlpha255(int legacy_transparency) { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index 72315b66bde0..f89edce6fd48 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -27,21 +27,23 @@ #include "gui/guiobject.h" #include "util/string.h" +namespace AGS3 { + #define GUIBUTTON_LEGACY_TEXTLENGTH 50 namespace AGS { namespace Common { enum MouseButton { - kMouseNone = -1, - kMouseLeft = 0, - kMouseRight = 1, + kMouseNone = -1, + kMouseLeft = 0, + kMouseRight = 1, }; enum GUIClickAction { - kGUIAction_None = 0, - kGUIAction_SetMode = 1, - kGUIAction_RunScript = 2, + kGUIAction_None = 0, + kGUIAction_SetMode = 1, + kGUIAction_RunScript = 2, }; enum LegacyButtonAlignment { @@ -80,7 +82,7 @@ class GUIButton : public GUIObject { void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; void WriteToSavegame(Common::Stream *out) const override; -// TODO: these members are currently public; hide them later + // TODO: these members are currently public; hide them later public: int32_t Image; int32_t MouseOverImage; @@ -134,4 +136,6 @@ extern int numguibuts; int UpdateAnimatingButton(int bu); void StopButtonAnimation(int idxn); +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guidefines.h b/engines/ags/shared/gui/guidefines.h index b2aef37410c1..8f7f04f74f9c 100644 --- a/engines/ags/shared/gui/guidefines.h +++ b/engines/ags/shared/gui/guidefines.h @@ -23,6 +23,8 @@ #ifndef AGS_SHARED_GUI_GUIDEFINES_H #define AGS_SHARED_GUI_GUIDEFINES_H +namespace AGS3 { + #define GUIMAGIC 0xcafebeef #define MAX_GUIOBJ_EVENTS 10 #define TEXTWINDOW_PADDING_DEFAULT 3 @@ -57,29 +59,29 @@ enum GuiVersion { // TODO: find out all corresponding engine version numbers - kGuiVersion_Initial = 0, - kGuiVersion_214 = 100, - kGuiVersion_222 = 101, - kGuiVersion_230 = 102, - kGuiVersion_unkn_103 = 103, - kGuiVersion_unkn_104 = 104, - kGuiVersion_260 = 105, - kGuiVersion_unkn_106 = 106, - kGuiVersion_unkn_107 = 107, - kGuiVersion_unkn_108 = 108, - kGuiVersion_unkn_109 = 109, - kGuiVersion_270 = 110, - kGuiVersion_272a = 111, - kGuiVersion_272b = 112, - kGuiVersion_272c = 113, - kGuiVersion_272d = 114, - kGuiVersion_272e = 115, - - kGuiVersion_330 = 116, - kGuiVersion_331 = 117, - kGuiVersion_340 = 118, - kGuiVersion_350 = 119, - kGuiVersion_Current = kGuiVersion_350, + kGuiVersion_Initial = 0, + kGuiVersion_214 = 100, + kGuiVersion_222 = 101, + kGuiVersion_230 = 102, + kGuiVersion_unkn_103 = 103, + kGuiVersion_unkn_104 = 104, + kGuiVersion_260 = 105, + kGuiVersion_unkn_106 = 106, + kGuiVersion_unkn_107 = 107, + kGuiVersion_unkn_108 = 108, + kGuiVersion_unkn_109 = 109, + kGuiVersion_270 = 110, + kGuiVersion_272a = 111, + kGuiVersion_272b = 112, + kGuiVersion_272c = 113, + kGuiVersion_272d = 114, + kGuiVersion_272e = 115, + + kGuiVersion_330 = 116, + kGuiVersion_331 = 117, + kGuiVersion_340 = 118, + kGuiVersion_350 = 119, + kGuiVersion_Current = kGuiVersion_350, }; namespace AGS { @@ -87,14 +89,14 @@ namespace Common { // GUIMain's style and behavior flags enum GUIMainFlags { - kGUIMain_Clickable = 0x0001, + kGUIMain_Clickable = 0x0001, kGUIMain_TextWindow = 0x0002, - kGUIMain_Visible = 0x0004, - kGUIMain_Concealed = 0x0008, + kGUIMain_Visible = 0x0004, + kGUIMain_Concealed = 0x0008, // NOTE: currently default state is Visible to keep this backwards compatible; // check later if this is still a wanted behavior - kGUIMain_DefFlags = kGUIMain_Clickable | kGUIMain_Visible, + kGUIMain_DefFlags = kGUIMain_Clickable | kGUIMain_Visible, // flags that had inverse meaning in old formats kGUIMain_OldFmtXorMask = kGUIMain_Clickable }; @@ -107,42 +109,42 @@ enum GUIMainLegacyFlags { // GUIMain's style of getting displayed on screen enum GUIPopupStyle { // Normal GUI - kGUIPopupNormal = 0, + kGUIPopupNormal = 0, // Shown when the mouse cursor moves to the top of the screen - kGUIPopupMouseY = 1, + kGUIPopupMouseY = 1, // Same as Normal, but pauses the game when shown - kGUIPopupModal = 2, + kGUIPopupModal = 2, // Same as Normal, but is not removed when interface is off - kGUIPopupNoAutoRemove = 3, + kGUIPopupNoAutoRemove = 3, // (legacy option) Normal GUI, initially off // converts to kGUIPopupNormal with Visible = false - kGUIPopupLegacyNormalOff = 4 + kGUIPopupLegacyNormalOff = 4 }; // The type of GUIControl enum GUIControlType { kGUIControlUndefined = -1, - kGUIButton = 1, - kGUILabel = 2, - kGUIInvWindow = 3, - kGUISlider = 4, - kGUITextBox = 5, - kGUIListBox = 6 + kGUIButton = 1, + kGUILabel = 2, + kGUIInvWindow = 3, + kGUISlider = 4, + kGUITextBox = 5, + kGUIListBox = 6 }; // GUIControl general style and behavior flags enum GUIControlFlags { - kGUICtrl_Default = 0x0001, // only button - kGUICtrl_Cancel = 0x0002, // unused - kGUICtrl_Enabled = 0x0004, - kGUICtrl_TabStop = 0x0008, // unused - kGUICtrl_Visible = 0x0010, - kGUICtrl_Clip = 0x0020, // only button - kGUICtrl_Clickable = 0x0040, + kGUICtrl_Default = 0x0001, // only button + kGUICtrl_Cancel = 0x0002, // unused + kGUICtrl_Enabled = 0x0004, + kGUICtrl_TabStop = 0x0008, // unused + kGUICtrl_Visible = 0x0010, + kGUICtrl_Clip = 0x0020, // only button + kGUICtrl_Clickable = 0x0040, kGUICtrl_Translated = 0x0080, // 3.3.0.1132 - kGUICtrl_Deleted = 0x8000, // unused (probably remains from the old editor?) + kGUICtrl_Deleted = 0x8000, // unused (probably remains from the old editor?) - kGUICtrl_DefFlags = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable, + kGUICtrl_DefFlags = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable, // flags that had inverse meaning in old formats kGUICtrl_OldFmtXorMask = kGUICtrl_Enabled | kGUICtrl_Visible | kGUICtrl_Clickable }; @@ -151,9 +153,9 @@ enum GUIControlFlags { enum GUIListBoxFlags { kListBox_ShowBorder = 0x01, kListBox_ShowArrows = 0x02, - kListBox_SvgIndex = 0x04, + kListBox_SvgIndex = 0x04, - kListBox_DefFlags = kListBox_ShowBorder | kListBox_ShowArrows, + kListBox_DefFlags = kListBox_ShowBorder | kListBox_ShowArrows, // flags that had inverse meaning in old formats kListBox_OldFmtXorMask = kListBox_ShowBorder | kListBox_ShowArrows }; @@ -162,7 +164,7 @@ enum GUIListBoxFlags { enum GUITextBoxFlags { kTextBox_ShowBorder = 0x0001, - kTextBox_DefFlags = kTextBox_ShowBorder, + kTextBox_DefFlags = kTextBox_ShowBorder, // flags that had inverse meaning in old formats kTextBox_OldFmtXorMask = kTextBox_ShowBorder }; @@ -170,8 +172,8 @@ enum GUITextBoxFlags { // Savegame data format // TODO: move to the engine code enum GuiSvgVersion { - kGuiSvgVersion_Initial = 0, - kGuiSvgVersion_350 = 1 + kGuiSvgVersion_Initial = 0, + kGuiSvgVersion_350 = 1 }; } // namespace Common @@ -179,4 +181,6 @@ enum GuiSvgVersion { extern int guis_need_update; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index caf85c703d27..f0e6041fac74 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -26,6 +26,7 @@ #include #include "gui/guiobject.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -52,7 +53,7 @@ class GUIInvWindow : public GUIObject { void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; void WriteToSavegame(Common::Stream *out) const override; -// TODO: these members are currently public; hide them later + // TODO: these members are currently public; hide them later public: bool IsMouseOver; int32_t CharId; // whose inventory (-1 = current player) @@ -72,4 +73,6 @@ class GUIInvWindow : public GUIObject { extern std::vector guiinv; extern int numguiinv; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index 745e6bf019c9..88c2380bcf26 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -27,12 +27,14 @@ #include "gui/guiobject.h" #include "util/string.h" +namespace AGS3 { + class SplitLines; namespace AGS { namespace Common { -class GUILabel: public GUIObject { +class GUILabel : public GUIObject { public: GUILabel(); @@ -48,7 +50,7 @@ class GUILabel: public GUIObject { void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; void WriteToSavegame(Common::Stream *out) const override; -// TODO: these members are currently public; hide them later + // TODO: these members are currently public; hide them later public: String Text; int32_t Font; @@ -69,4 +71,6 @@ class GUILabel: public GUIObject { extern std::vector guilabels; extern int numguilabels; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index 73974415e138..30c55e5e6a42 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -27,6 +27,7 @@ #include "gui/guiobject.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -63,7 +64,7 @@ class GUIListBox : public GUIObject { void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; void WriteToSavegame(Common::Stream *out) const override; -// TODO: these members are currently public; hide them later + // TODO: these members are currently public; hide them later public: int32_t Font; color_t TextColor; @@ -100,4 +101,6 @@ class GUIListBox : public GUIObject { extern std::vector guilist; extern int numguilist; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index b56f8f28ec33..27d7deee5eb8 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -31,12 +31,15 @@ #include "util/geometry.h" #include "util/string.h" +namespace AGS3 { + // Forward declaration namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later // There were issues when including header caused conflicts @@ -55,8 +58,8 @@ namespace Common { // Legacy GUIMain visibility state, which combined Visible property and override factor enum LegacyGUIVisState { kGUIVisibility_Concealed = -1, // gui is hidden by command - kGUIVisibility_Off = 0, // gui is disabled (won't show up by command) - kGUIVisibility_On = 1 // gui is shown by command + kGUIVisibility_Off = 0, // gui is disabled (won't show up by command) + kGUIVisibility_On = 1 // gui is shown by command }; class Bitmap; @@ -226,7 +229,7 @@ extern bool is_sprite_alpha(int spr); // This function has distinct implementations in Engine and Editor extern void draw_gui_sprite(Common::Bitmap *ds, int spr, int x, int y, bool use_alpha = true, - Common::BlendMode blend_mode = Common::kBlendMode_Alpha); + Common::BlendMode blend_mode = Common::kBlendMode_Alpha); extern AGS_INLINE int game_to_data_coord(int coord); extern AGS_INLINE int data_to_game_coord(int coord); @@ -235,7 +238,7 @@ extern AGS_INLINE int get_fixed_pixel_size(int pixels); // Those function have distinct implementations in Engine and Editor extern void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); -extern int wgettextwidth_compensate(Common::Bitmap *ds, const char *tex, int font) ; +extern int wgettextwidth_compensate(Common::Bitmap *ds, const char *tex, int font); extern void check_font(int *fontnum); extern void set_our_eip(int eip); @@ -245,4 +248,6 @@ extern int get_eip_guiobj(); extern bool outlineGuiObjects; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h index 8f2f5e26202f..1dfa51786760 100644 --- a/engines/ags/shared/gui/guiobject.h +++ b/engines/ags/shared/gui/guiobject.h @@ -28,20 +28,19 @@ #include "gui/guidefines.h" #include "util/string.h" +namespace AGS3 { + #define GUIDIS_GREYOUT 1 #define GUIDIS_BLACKOUT 2 #define GUIDIS_UNCHANGED 4 #define GUIDIS_GUIOFF 0x80 - - - namespace AGS { namespace Common { enum LegacyGUIAlignment { - kLegacyGUIAlign_Left = 0, - kLegacyGUIAlign_Right = 1, + kLegacyGUIAlign_Left = 0, + kLegacyGUIAlign_Right = 1, kLegacyGUIAlign_Center = 2 }; @@ -64,7 +63,8 @@ class GUIObject { bool IsClickable() const; // Operations - virtual void Draw(Bitmap *ds) { } + virtual void Draw(Bitmap *ds) { + } void SetClickable(bool on); void SetEnabled(bool on); void SetTranslated(bool on); @@ -72,21 +72,27 @@ class GUIObject { // Events // Key pressed for control - virtual void OnKeyPress(int keycode) { } + virtual void OnKeyPress(int keycode) { + } // Mouse button down - return 'True' to lock focus virtual bool OnMouseDown() { return false; } // Mouse moves onto control - virtual void OnMouseEnter() { } + virtual void OnMouseEnter() { + } // Mouse moves off control - virtual void OnMouseLeave() { } + virtual void OnMouseLeave() { + } // Mouse moves over control - x,y relative to gui - virtual void OnMouseMove(int x, int y) { } + virtual void OnMouseMove(int x, int y) { + } // Mouse button up - virtual void OnMouseUp() { } + virtual void OnMouseUp() { + } // Control was resized - virtual void OnResized() { } + virtual void OnResized() { + } // Serialization virtual void ReadFromFile(Common::Stream *in, GuiVersion gui_version); @@ -94,7 +100,7 @@ class GUIObject { virtual void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver); virtual void WriteToSavegame(Common::Stream *out) const; -// TODO: these members are currently public; hide them later + // TODO: these members are currently public; hide them later public: int32_t Id; // GUI object's identifier int32_t ParentId; // id of parent GUI @@ -131,4 +137,6 @@ inline bool IsGUIEnabled(AGS::Common::GUIObject *g) { return !all_buttons_disabled && g->IsEnabled(); } +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index 95b5721af9e6..2e5696bed2e9 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -26,6 +26,7 @@ #include #include "gui/guiobject.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -51,7 +52,7 @@ class GUISlider : public GUIObject { void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; void WriteToSavegame(Stream *out) const override; -// TODO: these members are currently public; hide them later + // TODO: these members are currently public; hide them later public: int32_t MinValue; int32_t MaxValue; @@ -73,4 +74,6 @@ class GUISlider : public GUIObject { extern std::vector guislider; extern int numguislider; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index d78b44787ca8..79f8ac9be511 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -27,6 +27,7 @@ #include "gui/guiobject.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -49,7 +50,7 @@ class GUITextBox : public GUIObject { void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; void WriteToSavegame(Stream *out) const override; -// TODO: these members are currently public; hide them later + // TODO: these members are currently public; hide them later public: int32_t Font; String Text; @@ -67,4 +68,6 @@ class GUITextBox : public GUIObject { extern std::vector guitext; extern int numguitext; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/script/cc_error.h b/engines/ags/shared/script/cc_error.h index c3d9591b1eb5..7dc8c68df965 100644 --- a/engines/ags/shared/script/cc_error.h +++ b/engines/ags/shared/script/cc_error.h @@ -31,6 +31,8 @@ #include "util/string.h" +namespace AGS3 { + extern void cc_error(const char *, ...); // error reporting @@ -41,4 +43,6 @@ extern AGS::Common::String ccErrorCallStack; // callstack where error happened extern bool ccErrorIsUserError; extern const char *ccCurScriptName; // name of currently compiling script +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/script/cc_options.h b/engines/ags/shared/script/cc_options.h index e2ccbb6b7ca2..095887a9a24c 100644 --- a/engines/ags/shared/script/cc_options.h +++ b/engines/ags/shared/script/cc_options.h @@ -26,6 +26,8 @@ // //============================================================================= +namespace AGS3 { + #ifndef AGS_SHARED_SCRIPT_CC_OPTIONS_H #define AGS_SHARED_SCRIPT_CC_OPTIONS_H @@ -41,4 +43,6 @@ extern void ccSetOption(int, int); extern int ccGetOption(int); +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index 5cbdd14c9405..8821879907dc 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -32,11 +32,14 @@ #include #include "core/types.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later struct ccScript { @@ -85,4 +88,6 @@ struct ccScript { typedef std::shared_ptr PScript; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/script/script_common.h b/engines/ags/shared/script/script_common.h index 42fbf6991e92..3e95067c867f 100644 --- a/engines/ags/shared/script/script_common.h +++ b/engines/ags/shared/script/script_common.h @@ -29,6 +29,8 @@ #ifndef AGS_SHARED_SCRIPT_SCRIPT_COMMON_H #define AGS_SHARED_SCRIPT_SCRIPT_COMMON_H +namespace AGS3 { + #define SCOM_VERSION 90 #define SCOM_VERSIONSTR "0.90" @@ -138,4 +140,6 @@ extern int currentline; extern const char scfilesig[5]; #define ENDFILESIG 0xbeefcafe +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/util/alignedstream.h b/engines/ags/shared/util/alignedstream.h index e74517f24ca4..f91ab58c83b1 100644 --- a/engines/ags/shared/util/alignedstream.h +++ b/engines/ags/shared/util/alignedstream.h @@ -47,6 +47,7 @@ #include "util/proxystream.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -58,8 +59,8 @@ enum AlignedStreamMode { class AlignedStream : public ProxyStream { public: AlignedStream(Stream *stream, AlignedStreamMode mode, - ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse, - size_t base_alignment = sizeof(int16_t)); + ObjectOwnershipPolicy stream_ownership_policy = kReleaseAfterUse, + size_t base_alignment = sizeof(int16_t)); ~AlignedStream() override; // Read/Write cumulated padding and reset block counter @@ -109,5 +110,6 @@ class AlignedStream : public ProxyStream { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h index f56b3ba50a1c..32472fa84a87 100644 --- a/engines/ags/shared/util/bbop.h +++ b/engines/ags/shared/util/bbop.h @@ -36,6 +36,7 @@ #define BITBYTE_BIG_ENDIAN #endif +namespace AGS3 { namespace AGS { namespace Common { @@ -60,8 +61,8 @@ inline int32_t SwapBytesInt32(const int32_t val) { inline int64_t SwapBytesInt64(const int64_t val) { return ((val >> 56) & 0xFF) | ((val >> 40) & 0xFF00) | ((val >> 24) & 0xFF0000) | - ((val >> 8) & 0xFF000000) | ((val << 8) & 0xFF00000000LL) | - ((val << 24) & 0xFF0000000000LL) | ((val << 40) & 0xFF000000000000LL) | ((val << 56) & 0xFF00000000000000LL); + ((val >> 8) & 0xFF000000) | ((val << 8) & 0xFF00000000LL) | + ((val << 24) & 0xFF0000000000LL) | ((val << 40) & 0xFF000000000000LL) | ((val << 56) & 0xFF00000000000000LL); } inline float SwapBytesFloat(const float val) { @@ -143,10 +144,10 @@ inline float FloatFromBE(const float val) { // Aliases for easier calling -namespace BBOp = BitByteOperations; - +namespace BBOp = BitByteOperations; } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h index 27c938d21ea5..4e14beb8c573 100644 --- a/engines/ags/shared/util/bufferedstream.h +++ b/engines/ags/shared/util/bufferedstream.h @@ -27,6 +27,7 @@ #include "util/filestream.h" #include "util/file.h" // TODO: extract filestream mode constants +namespace AGS3 { namespace AGS { namespace Common { @@ -67,5 +68,6 @@ class BufferedStream : public FileStream { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h index 783b4a9bb103..8fd7aa630e06 100644 --- a/engines/ags/shared/util/compress.h +++ b/engines/ags/shared/util/compress.h @@ -25,12 +25,15 @@ #include "util/wgt2allg.h" // color (allegro RGB) +namespace AGS3 { + namespace AGS { namespace Common { class Stream; class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later void csavecompressed(Common::Stream *out, const unsigned char *tobesaved, const color pala[256]); @@ -50,4 +53,6 @@ void load_lzw(Common::Stream *in, Common::Bitmap **bmm, int dst_bpp, color *pall void savecompressed_allegro(Common::Stream *out, const Common::Bitmap *bmpp, const color *pall); void loadcompressed_allegro(Common::Stream *in, Common::Bitmap **bimpp, color *pall); +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/util/datastream.h b/engines/ags/shared/util/datastream.h index 78234a4e1d4f..da47e40cb75a 100644 --- a/engines/ags/shared/util/datastream.h +++ b/engines/ags/shared/util/datastream.h @@ -34,6 +34,7 @@ #include "util/bbop.h" #include "util/stream.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -59,17 +60,17 @@ class DataStream : public Stream { inline size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override { return MustSwapBytes() ? - ReadAndConvertArrayOfInt16(buffer, count) : ReadArray(buffer, sizeof(int16_t), count); + ReadAndConvertArrayOfInt16(buffer, count) : ReadArray(buffer, sizeof(int16_t), count); } inline size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override { return MustSwapBytes() ? - ReadAndConvertArrayOfInt32(buffer, count) : ReadArray(buffer, sizeof(int32_t), count); + ReadAndConvertArrayOfInt32(buffer, count) : ReadArray(buffer, sizeof(int32_t), count); } inline size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override { return MustSwapBytes() ? - ReadAndConvertArrayOfInt64(buffer, count) : ReadArray(buffer, sizeof(int64_t), count); + ReadAndConvertArrayOfInt64(buffer, count) : ReadArray(buffer, sizeof(int64_t), count); } size_t WriteInt16(int16_t val) override; @@ -82,17 +83,17 @@ class DataStream : public Stream { inline size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override { return MustSwapBytes() ? - WriteAndConvertArrayOfInt16(buffer, count) : WriteArray(buffer, sizeof(int16_t), count); + WriteAndConvertArrayOfInt16(buffer, count) : WriteArray(buffer, sizeof(int16_t), count); } inline size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override { return MustSwapBytes() ? - WriteAndConvertArrayOfInt32(buffer, count) : WriteArray(buffer, sizeof(int32_t), count); + WriteAndConvertArrayOfInt32(buffer, count) : WriteArray(buffer, sizeof(int32_t), count); } inline size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override { return MustSwapBytes() ? - WriteAndConvertArrayOfInt64(buffer, count) : WriteArray(buffer, sizeof(int64_t), count); + WriteAndConvertArrayOfInt64(buffer, count) : WriteArray(buffer, sizeof(int64_t), count); } protected: @@ -124,5 +125,6 @@ class DataStream : public Stream { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h index 078f777b760f..55dc4deb0a2a 100644 --- a/engines/ags/shared/util/directory.h +++ b/engines/ags/shared/util/directory.h @@ -32,6 +32,7 @@ #include "core/platform.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -49,5 +50,6 @@ String GetCurrentDirectory(); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h index 09ae192346f1..44874849762a 100644 --- a/engines/ags/shared/util/error.h +++ b/engines/ags/shared/util/error.h @@ -33,6 +33,7 @@ #include #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -45,10 +46,14 @@ typedef std::shared_ptr PError; // class Error { public: - Error(int code, String general, PError inner_error = PError()) : _code(code), _general(general), _innerError(inner_error) {} - Error(int code, String general, String comment, PError inner_error = PError()) : _code(code), _general(general), _comment(comment), _innerError(inner_error) {} - Error(String general, PError inner_error = PError()) : _code(0), _general(general), _innerError(inner_error) {} - Error(String general, String comment, PError inner_error = PError()) : _code(0), _general(general), _comment(comment), _innerError(inner_error) {} + Error(int code, String general, PError inner_error = PError()) : _code(code), _general(general), _innerError(inner_error) { + } + Error(int code, String general, String comment, PError inner_error = PError()) : _code(code), _general(general), _comment(comment), _innerError(inner_error) { + } + Error(String general, PError inner_error = PError()) : _code(0), _general(general), _innerError(inner_error) { + } + Error(String general, String comment, PError inner_error = PError()) : _code(0), _general(general), _comment(comment), _innerError(inner_error) { + } // Error code is a number, defining error subtype. It is not much use to the end-user, @@ -110,8 +115,10 @@ template class ErrorHandle { } ErrorHandle() = default; - ErrorHandle(T *err) : _error(err) {} - ErrorHandle(std::shared_ptr err) : _error(err) {} + ErrorHandle(T *err) : _error(err) { + } + ErrorHandle(std::shared_ptr err) : _error(err) { + } bool HasError() const { return _error.get() != NULL; @@ -144,9 +151,11 @@ typedef ErrorHandle HError; template class TypedCodeError : public Error { public: - TypedCodeError(CodeType code, PError inner_error = PError()) : Error(code, GetErrorText(code), inner_error) {} + TypedCodeError(CodeType code, PError inner_error = PError()) : Error(code, GetErrorText(code), inner_error) { + } TypedCodeError(CodeType code, String comment, PError inner_error = PError()) : - Error(code, GetErrorText(code), comment, inner_error) {} + Error(code, GetErrorText(code), comment, inner_error) { + } CodeType Code() const { return (CodeType)Error::Code(); @@ -155,5 +164,6 @@ class TypedCodeError : public Error { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h index e2a9227557d9..6774a33c07c8 100644 --- a/engines/ags/shared/util/file.h +++ b/engines/ags/shared/util/file.h @@ -32,6 +32,7 @@ #include "core/platform.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -67,7 +68,7 @@ bool GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, // Gets C-style file mode from FileOpenMode and FileWorkMode String GetCMode(FileOpenMode open_mode, FileWorkMode work_mode); -Stream *OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode); +Stream *OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode); // Convenience helpers // Create a totally new file, overwrite existing one inline Stream *CreateFile(const String &filename) { @@ -85,5 +86,6 @@ inline Stream *OpenFileWrite(const String &filename) { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index 231f42ea7ad8..8e222b2a3727 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -28,6 +28,7 @@ #include "util/datastream.h" #include "util/file.h" // TODO: extract filestream mode constants +namespace AGS3 { namespace AGS { namespace Common { @@ -39,7 +40,7 @@ class FileStream : public DataStream { // - there is an issue opening the file (does not exist, locked, permissions, etc) // - the open mode could not be determined FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, - DataEndianess stream_endianess = kLittleEndian); + DataEndianess stream_endianess = kLittleEndian); ~FileStream() override; bool HasErrors() const override; @@ -68,12 +69,13 @@ class FileStream : public DataStream { private: void Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode); - FILE *_file; + FILE *_file; const FileOpenMode _openMode; const FileWorkMode _workMode; }; } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/geometry.h b/engines/ags/shared/util/geometry.h index a40b0b475d4c..058ca377a9c1 100644 --- a/engines/ags/shared/util/geometry.h +++ b/engines/ags/shared/util/geometry.h @@ -31,6 +31,8 @@ #include "util/math.h" +namespace AGS3 { + namespace AGSMath = AGS::Common::Math; //namespace AGS //{ @@ -44,35 +46,35 @@ enum FrameAlignment { // Alignment options are representing 8 sides of a frame (rectangle); // they are implemented as flags that may be combined together if it // is wanted to define alignment to multiple sides at once. - kAlignTopLeft = 0x0001, - kAlignTopCenter = 0x0002, - kAlignTopRight = 0x0004, - kAlignMiddleLeft = 0x0008, - kAlignMiddleCenter = 0x0010, - kAlignMiddleRight = 0x0020, - kAlignBottomLeft = 0x0040, - kAlignBottomCenter = 0x0080, - kAlignBottomRight = 0x0100, + kAlignTopLeft = 0x0001, + kAlignTopCenter = 0x0002, + kAlignTopRight = 0x0004, + kAlignMiddleLeft = 0x0008, + kAlignMiddleCenter = 0x0010, + kAlignMiddleRight = 0x0020, + kAlignBottomLeft = 0x0040, + kAlignBottomCenter = 0x0080, + kAlignBottomRight = 0x0100, // Masks are helping to determine whether alignment parameter contains // particular horizontal or vertical component (for example: left side // or bottom side) - kMAlignLeft = kAlignTopLeft | kAlignMiddleLeft | kAlignBottomLeft, - kMAlignRight = kAlignTopRight | kAlignMiddleRight | kAlignBottomRight, - kMAlignTop = kAlignTopLeft | kAlignTopCenter | kAlignTopRight, - kMAlignBottom = kAlignBottomLeft | kAlignBottomCenter | kAlignBottomRight, - kMAlignHCenter = kAlignTopCenter | kAlignMiddleCenter | kAlignBottomCenter, - kMAlignVCenter = kAlignMiddleLeft | kAlignMiddleCenter | kAlignMiddleRight + kMAlignLeft = kAlignTopLeft | kAlignMiddleLeft | kAlignBottomLeft, + kMAlignRight = kAlignTopRight | kAlignMiddleRight | kAlignBottomRight, + kMAlignTop = kAlignTopLeft | kAlignTopCenter | kAlignTopRight, + kMAlignBottom = kAlignBottomLeft | kAlignBottomCenter | kAlignBottomRight, + kMAlignHCenter = kAlignTopCenter | kAlignMiddleCenter | kAlignBottomCenter, + kMAlignVCenter = kAlignMiddleLeft | kAlignMiddleCenter | kAlignMiddleRight }; // Horizontal alignment; based on FrameAlignment, used to restrict alignment // setting to left/right/center option, while keeping compatibility with any // alignment in case it will be supported in the future. enum HorAlignment { - kHAlignNone = kAlignNone, - kHAlignLeft = kAlignTopLeft, - kHAlignRight = kAlignTopRight, - kHAlignCenter = kAlignTopCenter + kHAlignNone = kAlignNone, + kHAlignLeft = kAlignTopLeft, + kHAlignRight = kAlignTopRight, + kHAlignCenter = kAlignTopCenter }; enum RectPlacement { @@ -160,7 +162,7 @@ struct Size { inline static Size Clamp(const Size &sz, const Size &floor, const Size &ceil) { return Size(AGSMath::Clamp(sz.Width, floor.Width, ceil.Width), - AGSMath::Clamp(sz.Height, floor.Height, ceil.Height)); + AGSMath::Clamp(sz.Height, floor.Height, ceil.Height)); } // Indicates if current size exceeds other size by any metric @@ -211,17 +213,17 @@ struct Rect { int Bottom; Rect() { - Left = 0; - Top = 0; - Right = -1; - Bottom = -1; + Left = 0; + Top = 0; + Right = -1; + Bottom = -1; } Rect(int l, int t, int r, int b) { - Left = l; - Top = t; - Right = r; - Bottom = b; + Left = l; + Top = t; + Right = r; + Bottom = b; } inline Point GetLT() const { @@ -361,5 +363,6 @@ Rect ClampToRect(const Rect &place, const Rect &item); Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement); //} // namespace Common //} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h index 7a837780f47a..7e5906bb5e8c 100644 --- a/engines/ags/shared/util/ini_util.h +++ b/engines/ags/shared/util/ini_util.h @@ -33,6 +33,7 @@ #include #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -70,5 +71,6 @@ bool Merge(const String &file, const ConfigTree &tree); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h index 2064dd827e58..09709dda14d2 100644 --- a/engines/ags/shared/util/inifile.h +++ b/engines/ags/shared/util/inifile.h @@ -36,6 +36,7 @@ #include #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -101,7 +102,7 @@ class IniFile { ItemIterator Begin() { return Items.begin(); } - ItemIterator End() { + ItemIterator End() { return Items.end(); } ConstItemIterator CBegin() const { @@ -136,7 +137,7 @@ class IniFile { SectionIterator Begin() { return _sections.begin(); } - SectionIterator End() { + SectionIterator End() { return _sections.end(); } ConstSectionIterator CBegin() const { @@ -169,5 +170,6 @@ class IniFile { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/lzw.h b/engines/ags/shared/util/lzw.h index c62c2c826517..236343090c0e 100644 --- a/engines/ags/shared/util/lzw.h +++ b/engines/ags/shared/util/lzw.h @@ -23,11 +23,14 @@ #ifndef AGS_SHARED_UTIL_LZW_H #define AGS_SHARED_UTIL_LZW_H +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later void lzwcompress(Common::Stream *lzw_in, Common::Stream *out); @@ -35,4 +38,6 @@ unsigned char *lzwexpand_to_mem(Common::Stream *in); extern long outbytes, maxsize, putbytes; +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/util/math.h b/engines/ags/shared/util/math.h index 52d760a50617..9053565f8be0 100644 --- a/engines/ags/shared/util/math.h +++ b/engines/ags/shared/util/math.h @@ -29,6 +29,8 @@ #ifndef AGS_SHARED_UTIL_MATH_H #define AGS_SHARED_UTIL_MATH_H +namespace AGS3 { + #ifndef M_PI #define M_PI 3.14159265358979323846 #endif @@ -84,5 +86,6 @@ inline float DegreesToRadians(float deg) { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h index 8ab235a3e915..85defb9cbbf0 100644 --- a/engines/ags/shared/util/memory.h +++ b/engines/ags/shared/util/memory.h @@ -33,6 +33,8 @@ #include "util/bbop.h" #include "util/math.h" +namespace AGS3 { + #if defined (AGS_STRICT_ALIGNMENT) || defined (TEST_STRICT_ALIGNMENT) #define MEMORY_STRICT_ALIGNMENT #endif @@ -91,10 +93,10 @@ inline int64_t ReadInt64(const void *ptr) { const uint8_t *b = (const uint8_t *)ptr; #if defined (BITBYTE_BIG_ENDIAN) return ((uint64_t)b[0] << 56) | ((uint64_t)b[1] << 48) | ((uint64_t)b[2] << 40) | ((uint64_t)b[3] << 32) | - (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; + (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; #else return ((uint64_t)b[7] << 56) | ((uint64_t)b[6] << 48) | ((uint64_t)b[5] << 40) | ((uint64_t)b[4] << 32) | - (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; + (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; #endif #else return *(int64_t *)ptr; @@ -218,8 +220,8 @@ inline void WriteInt64BE(void *ptr, int64_t value) { //------------------------------------------------------------------------- // Copies block of 2d data from source into destination. inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_offset, - const uint8_t *src, const size_t src_pitch, const size_t src_offset, - const size_t height) { + const uint8_t *src, const size_t src_pitch, const size_t src_offset, + const size_t height) { for (size_t y = 0; y < height; ++y, src += src_pitch, dst += dst_pitch) memcpy(dst + dst_offset, src + src_offset, Math::Min(dst_pitch - dst_offset, src_pitch - src_offset)); } @@ -228,5 +230,6 @@ inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_off } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h index e658ebf2bd6d..8d798e1e7f5d 100644 --- a/engines/ags/shared/util/misc.h +++ b/engines/ags/shared/util/misc.h @@ -54,11 +54,14 @@ #include "util/file.h" // TODO: extract filestream mode constants +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later // Case-insensitive file lookup functions. On case-insensitive systems @@ -68,10 +71,11 @@ using namespace AGS; // FIXME later // They are used as a system-independent way to open a file when its name // case can be ignored. Common::Stream *ci_fopen(const char *file_name, - Common::FileOpenMode open_mode = Common::kFile_Open, - Common::FileWorkMode work_mode = Common::kFile_Read); + Common::FileOpenMode open_mode = Common::kFile_Open, + Common::FileWorkMode work_mode = Common::kFile_Read); // TODO: return String object char *ci_find_file(const char *dir_name, const char *file_name); +} // namespace AGS3 -#endif // __MISC_H +#endif diff --git a/engines/ags/shared/util/multifilelib.h b/engines/ags/shared/util/multifilelib.h index 5def30343673..d7242b667c66 100644 --- a/engines/ags/shared/util/multifilelib.h +++ b/engines/ags/shared/util/multifilelib.h @@ -37,6 +37,7 @@ #include "core/asset.h" #include "util/stream.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -45,21 +46,21 @@ namespace Common { // namespace MFLUtil { enum MFLError { - kMFLNoError = 0, - kMFLErrNoLibSig = -1, // library signature does not match - kMFLErrLibVersion = -2, // library version unsupported - kMFLErrNoLibBase = -3, // file is not library base (head) - kMFLErrLibAssetCount = -4, // too many assets in library + kMFLNoError = 0, + kMFLErrNoLibSig = -1, // library signature does not match + kMFLErrLibVersion = -2, // library version unsupported + kMFLErrNoLibBase = -3, // file is not library base (head) + kMFLErrLibAssetCount = -4, // too many assets in library }; enum MFLVersion { - kMFLVersion_SingleLib = 6, - kMFLVersion_MultiV10 = 10, - kMFLVersion_MultiV11 = 11, - kMFLVersion_MultiV15 = 15, // unknown differences - kMFLVersion_MultiV20 = 20, - kMFLVersion_MultiV21 = 21, - kMFLVersion_MultiV30 = 30 // 64-bit file support, loose limits + kMFLVersion_SingleLib = 6, + kMFLVersion_MultiV10 = 10, + kMFLVersion_MultiV11 = 11, + kMFLVersion_MultiV15 = 15, // unknown differences + kMFLVersion_MultiV20 = 20, + kMFLVersion_MultiV21 = 21, + kMFLVersion_MultiV30 = 30 // 64-bit file support, loose limits }; // Maximal number of the data files in one library chain (1-byte index) @@ -74,5 +75,6 @@ void WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h index 6b4da1924f54..41a62c406b77 100644 --- a/engines/ags/shared/util/path.h +++ b/engines/ags/shared/util/path.h @@ -31,6 +31,7 @@ #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -86,5 +87,6 @@ String GetCmdLinePathInASCII(const char *arg, int arg_index); } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/proxystream.h b/engines/ags/shared/util/proxystream.h index 70e47617458f..8c0758cd1dbe 100644 --- a/engines/ags/shared/util/proxystream.h +++ b/engines/ags/shared/util/proxystream.h @@ -25,6 +25,7 @@ #include "util/stream.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -78,11 +79,12 @@ class ProxyStream : public Stream { bool Seek(soff_t offset, StreamSeek origin) override; protected: - Stream *_stream; + Stream *_stream; ObjectOwnershipPolicy _streamOwnershipPolicy; }; } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h index 203d600c3c27..289d23b6e3ff 100644 --- a/engines/ags/shared/util/stdio_compat.h +++ b/engines/ags/shared/util/stdio_compat.h @@ -26,22 +26,26 @@ #include #include +namespace AGS3 { + typedef int64_t file_off_t; #ifdef __cplusplus extern "C" { #endif -int ags_fseek(FILE *stream, file_off_t offset, int whence); -file_off_t ags_ftell(FILE *stream); + int ags_fseek(FILE *stream, file_off_t offset, int whence); + file_off_t ags_ftell(FILE *stream); -int ags_file_exists(const char *path); -int ags_directory_exists(const char *path); -int ags_path_exists(const char *path); -file_off_t ags_file_size(const char *path); + int ags_file_exists(const char *path); + int ags_directory_exists(const char *path); + int ags_path_exists(const char *path); + file_off_t ags_file_size(const char *path); #ifdef __cplusplus } #endif +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index d97cd26621df..d9cafba2022e 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -37,6 +37,7 @@ #include "api/stream_api.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -84,5 +85,6 @@ class Stream : public IAGSStream { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index 0272468e0d0f..8d8a02f89394 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -52,6 +52,7 @@ #include "core/types.h" #include "debug/assert.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -158,7 +159,7 @@ class String { // This also means that there's always at least one section in any string, // even if there are no separating chars. bool FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, - size_t &from, size_t &to) const; + size_t &from, size_t &to) const; // Get Nth character with bounds check (as opposed to subscript operator) inline char GetAt(size_t index) const { @@ -209,7 +210,7 @@ class String { String RightSection(char separator, bool exclude_separator = true) const; // Extract the range of Xth to Yth fields, separated by the given character String Section(char separator, size_t first, size_t last, - bool exclude_first_sep = true, bool exclude_last_sep = true) const; + bool exclude_first_sep = true, bool exclude_last_sep = true) const; // Splits the string into segments divided by the instances of a given character, // including empty segments e.g. if separators follow each other; // returns at least one segment (equal to full string if no separator was found) @@ -247,7 +248,7 @@ class String { void ClipRightSection(char separator, bool include_separator = true); // Cuts out the range of Xth to Yth fields separated by the given character void ClipSection(char separator, size_t first, size_t last, - bool include_first_sep = true, bool include_last_sep = true); + bool include_first_sep = true, bool include_last_sep = true); // Sets string length to zero void Empty(); // Makes a new string by filling N chars with certain value @@ -304,7 +305,7 @@ class String { // Truncate the string to range of Xth to Yth fields separated by the // given character void TruncateToSection(char separator, size_t first, size_t last, - bool exclude_first_sep = true, bool exclude_last_sep = true); + bool exclude_first_sep = true, bool exclude_last_sep = true); // Wraps the given string buffer without owning it, won't count references, // won't delete it at destruction. Can be used with string literals. void Wrap(const char *cstr); @@ -348,7 +349,7 @@ class String { // or after the current string data void ReserveAndShift(bool left, size_t more_length); - char *_cstr; // pointer to actual string data + char *_cstr; // pointer to actual string data size_t _len; // valid string length, in characters, excluding null-term // Header of a reference-counted buffer @@ -359,12 +360,13 @@ class String { // Union that groups mutually exclusive data (currently only ref counted buffer) union { - char *_buf; // reference-counted data (raw ptr) + char *_buf; // reference-counted data (raw ptr) BufHeader *_bufHead; // the header of a reference-counted data }; }; } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/string_compat.h b/engines/ags/shared/util/string_compat.h index 631c6c22a0f9..3931eae1f56a 100644 --- a/engines/ags/shared/util/string_compat.h +++ b/engines/ags/shared/util/string_compat.h @@ -25,18 +25,22 @@ #include "core/types.h" +namespace AGS3 { + #ifdef __cplusplus extern "C" { #endif -char *ags_strlwr(char *s); -char *ags_strupr(char *s); -int ags_stricmp(const char *, const char *); -int ags_strnicmp(const char *, const char *, size_t); -char *ags_strdup(const char *s); + char *ags_strlwr(char *s); + char *ags_strupr(char *s); + int ags_stricmp(const char *, const char *); + int ags_strnicmp(const char *, const char *, size_t); + char *ags_strdup(const char *s); #ifdef __cplusplus } #endif +} // namespace AGS3 + #endif diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index 28989aa44694..c0871acc2658 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -30,6 +30,7 @@ #include #include "util/string.h" +namespace AGS3 { namespace FNV { const uint32_t PRIME_NUMBER = 2166136261U; @@ -104,5 +105,6 @@ typedef std::unordered_map StringIMa } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h index 305deb523137..34a33e37bfd5 100644 --- a/engines/ags/shared/util/string_utils.h +++ b/engines/ags/shared/util/string_utils.h @@ -25,11 +25,14 @@ #include "util/string.h" +namespace AGS3 { + namespace AGS { namespace Common { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later //============================================================================= @@ -76,6 +79,6 @@ void WriteCStr(const String &s, Stream *out); } } // namespace Common } // namespace AGS - +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/textreader.h b/engines/ags/shared/util/textreader.h index fb1c7b3eafd1..3cfe2b64639b 100644 --- a/engines/ags/shared/util/textreader.h +++ b/engines/ags/shared/util/textreader.h @@ -31,6 +31,7 @@ #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -38,19 +39,20 @@ class TextReader { public: virtual ~TextReader() = default; - virtual bool IsValid() const = 0; + virtual bool IsValid() const = 0; // Read single character - virtual char ReadChar() = 0; + virtual char ReadChar() = 0; // Read defined number of characters virtual String ReadString(size_t length) = 0; // Read till line break - virtual String ReadLine() = 0; + virtual String ReadLine() = 0; // Read till end of available data - virtual String ReadAll() = 0; + virtual String ReadAll() = 0; }; } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/textstreamreader.h b/engines/ags/shared/util/textstreamreader.h index 943ccf4d5582..50360d619ebf 100644 --- a/engines/ags/shared/util/textstreamreader.h +++ b/engines/ags/shared/util/textstreamreader.h @@ -31,6 +31,7 @@ #include "util/textreader.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -43,7 +44,7 @@ class TextStreamReader : public TextReader { ~TextStreamReader() override; bool IsValid() const override; - const Stream *GetStream() const; + const Stream *GetStream() const; // TODO: use shared ptr instead void ReleaseStream(); @@ -64,5 +65,6 @@ class TextStreamReader : public TextReader { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/textstreamwriter.h b/engines/ags/shared/util/textstreamwriter.h index 3ece10881db8..bf7df0911253 100644 --- a/engines/ags/shared/util/textstreamwriter.h +++ b/engines/ags/shared/util/textstreamwriter.h @@ -31,6 +31,7 @@ #include "util/textwriter.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -43,7 +44,7 @@ class TextStreamWriter : public TextWriter { ~TextStreamWriter() override; bool IsValid() const override; - const Stream *GetStream() const; + const Stream *GetStream() const; // TODO: use shared ptr instead void ReleaseStream(); @@ -65,5 +66,6 @@ class TextStreamWriter : public TextWriter { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/textwriter.h b/engines/ags/shared/util/textwriter.h index 64b4f292dfb4..9140f43832f0 100644 --- a/engines/ags/shared/util/textwriter.h +++ b/engines/ags/shared/util/textwriter.h @@ -31,6 +31,7 @@ #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -38,20 +39,21 @@ class TextWriter { public: virtual ~TextWriter() = default; - virtual bool IsValid() const = 0; + virtual bool IsValid() const = 0; // Write single character - virtual void WriteChar(char c) = 0; + virtual void WriteChar(char c) = 0; // Write string as a plain text (without null-terminator) - virtual void WriteString(const String &str) = 0; + virtual void WriteString(const String &str) = 0; // Write string and add line break at the end - virtual void WriteLine(const String &str) = 0; + virtual void WriteLine(const String &str) = 0; // Write formatted string (see *printf) - virtual void WriteFormat(const char *fmt, ...) = 0; - virtual void WriteLineBreak() = 0; + virtual void WriteFormat(const char *fmt, ...) = 0; + virtual void WriteLineBreak() = 0; }; } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/version.h b/engines/ags/shared/util/version.h index 865280e0fd90..ed91b13323cc 100644 --- a/engines/ags/shared/util/version.h +++ b/engines/ags/shared/util/version.h @@ -31,6 +31,7 @@ #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Common { @@ -102,5 +103,6 @@ struct Version { } // namespace Common } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index 22ce298acbab..3e4f81ca2f0b 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -37,11 +37,14 @@ #include "allegro.h" +namespace AGS3 { + namespace AGS { namespace Common { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later @@ -61,23 +64,23 @@ extern "C" { #endif -extern void wsetrgb(int coll, int r, int g, int b, color *pall); -extern void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall); + extern void wsetrgb(int coll, int r, int g, int b, color *pall); + extern void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall); -extern Common::Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2); + extern Common::Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2); -extern int wloadsprites(color *pall, char *filnam, Common::Bitmap **sarray, int strt, int eend); + extern int wloadsprites(color *pall, char *filnam, Common::Bitmap **sarray, int strt, int eend); -extern void wputblock(Common::Bitmap *ds, int xx, int yy, Common::Bitmap *bll, int xray); -// CHECKME: temporary solution for plugin system -extern void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray); -extern const int col_lookups[32]; + extern void wputblock(Common::Bitmap *ds, int xx, int yy, Common::Bitmap *bll, int xray); + // CHECKME: temporary solution for plugin system + extern void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray); + extern const int col_lookups[32]; -//extern void wsetcolor(int nval); + //extern void wsetcolor(int nval); -extern int __wremap_keep_transparent; -extern void wremap(color *pal1, Common::Bitmap *picc, color *pal2); -extern void wremapall(color *pal1, Common::Bitmap *picc, color *pal2); + extern int __wremap_keep_transparent; + extern void wremap(color *pal1, Common::Bitmap *picc, color *pal2); + extern void wremapall(color *pal1, Common::Bitmap *picc, color *pal2); #ifdef __cplusplus } @@ -89,4 +92,6 @@ extern void wremapall(color *pal1, Common::Bitmap *picc, color *pal2); // archive attributes to search for - al_findfirst breaks with 0 #define FA_SEARCH -1 +} // namespace AGS3 + #endif From 530dd506b645ee82392204a6248affce923bd429 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 16:10:55 -0800 Subject: [PATCH 009/215] AGS: Changing Common namespace to Shared --- engines/ags/engine/ac/asset_helper.h | 6 ++--- engines/ags/engine/ac/audiochannel.cpp | 2 +- engines/ags/engine/ac/button.cpp | 2 +- engines/ags/engine/ac/button.h | 2 +- engines/ags/engine/ac/character.cpp | 2 +- engines/ags/engine/ac/character.h | 2 +- engines/ags/engine/ac/charactercache.h | 2 +- engines/ags/engine/ac/characterextras.cpp | 2 +- engines/ags/engine/ac/characterextras.h | 2 +- .../ags/engine/ac/characterinfo_engine.cpp | 2 +- engines/ags/engine/ac/dialog.cpp | 2 +- engines/ags/engine/ac/display.cpp | 4 ++-- engines/ags/engine/ac/display.h | 2 +- engines/ags/engine/ac/draw.cpp | 2 +- engines/ags/engine/ac/draw.h | 2 +- engines/ags/engine/ac/draw_software.cpp | 2 +- engines/ags/engine/ac/draw_software.h | 4 ++-- engines/ags/engine/ac/drawingsurface.cpp | 2 +- engines/ags/engine/ac/dynamicsprite.cpp | 2 +- .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 2 +- .../ags/engine/ac/dynobj/cc_dynamicobject.cpp | 2 +- .../ags/engine/ac/dynobj/cc_dynamicobject.h | 2 +- engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 2 +- .../engine/ac/dynobj/managedobjectpool.cpp | 2 +- .../ags/engine/ac/dynobj/managedobjectpool.h | 2 +- engines/ags/engine/ac/dynobj/scriptcamera.cpp | 2 +- engines/ags/engine/ac/dynobj/scriptdict.h | 2 +- .../engine/ac/dynobj/scriptdrawingsurface.cpp | 2 +- .../engine/ac/dynobj/scriptdrawingsurface.h | 2 +- engines/ags/engine/ac/dynobj/scriptset.h | 2 +- .../ags/engine/ac/dynobj/scriptviewport.cpp | 2 +- engines/ags/engine/ac/event.cpp | 2 +- engines/ags/engine/ac/file.cpp | 2 +- engines/ags/engine/ac/file.h | 2 +- engines/ags/engine/ac/game.cpp | 2 +- engines/ags/engine/ac/game.h | 2 +- engines/ags/engine/ac/gamesetup.h | 2 +- engines/ags/engine/ac/gamestate.cpp | 2 +- engines/ags/engine/ac/gamestate.h | 8 +++---- engines/ags/engine/ac/global_audio.cpp | 2 +- engines/ags/engine/ac/global_button.cpp | 2 +- engines/ags/engine/ac/global_character.cpp | 2 +- engines/ags/engine/ac/global_debug.cpp | 2 +- engines/ags/engine/ac/global_debug.h | 2 +- engines/ags/engine/ac/global_dialog.cpp | 2 +- engines/ags/engine/ac/global_display.cpp | 2 +- .../ags/engine/ac/global_drawingsurface.cpp | 2 +- .../ags/engine/ac/global_dynamicsprite.cpp | 2 +- engines/ags/engine/ac/global_file.cpp | 2 +- engines/ags/engine/ac/global_file.h | 2 +- engines/ags/engine/ac/global_game.cpp | 2 +- engines/ags/engine/ac/global_gui.cpp | 2 +- engines/ags/engine/ac/global_hotspot.cpp | 2 +- .../ags/engine/ac/global_inventoryitem.cpp | 2 +- engines/ags/engine/ac/global_label.cpp | 2 +- engines/ags/engine/ac/global_object.cpp | 2 +- engines/ags/engine/ac/global_object.h | 2 +- engines/ags/engine/ac/global_overlay.cpp | 2 +- engines/ags/engine/ac/global_region.cpp | 2 +- engines/ags/engine/ac/global_room.cpp | 2 +- engines/ags/engine/ac/global_screen.cpp | 2 +- engines/ags/engine/ac/global_slider.cpp | 2 +- engines/ags/engine/ac/global_textbox.cpp | 2 +- engines/ags/engine/ac/global_translation.cpp | 2 +- engines/ags/engine/ac/global_walkablearea.cpp | 2 +- engines/ags/engine/ac/gui.cpp | 2 +- engines/ags/engine/ac/gui.h | 6 ++--- engines/ags/engine/ac/guicontrol.cpp | 2 +- engines/ags/engine/ac/guicontrol.h | 14 ++++++------ engines/ags/engine/ac/guiinv.cpp | 4 ++-- engines/ags/engine/ac/hotspot.cpp | 2 +- engines/ags/engine/ac/invwindow.cpp | 2 +- engines/ags/engine/ac/invwindow.h | 2 +- engines/ags/engine/ac/label.h | 2 +- engines/ags/engine/ac/listbox.cpp | 2 +- engines/ags/engine/ac/listbox.h | 2 +- engines/ags/engine/ac/mouse.cpp | 2 +- engines/ags/engine/ac/movelist.cpp | 2 +- engines/ags/engine/ac/movelist.h | 2 +- engines/ags/engine/ac/object.cpp | 2 +- engines/ags/engine/ac/object.h | 2 +- engines/ags/engine/ac/overlay.cpp | 2 +- engines/ags/engine/ac/overlay.h | 2 +- engines/ags/engine/ac/parser.cpp | 2 +- engines/ags/engine/ac/path_helper.h | 2 +- engines/ags/engine/ac/properties.cpp | 2 +- engines/ags/engine/ac/properties.h | 2 +- engines/ags/engine/ac/region.cpp | 2 +- engines/ags/engine/ac/richgamemedia.cpp | 2 +- engines/ags/engine/ac/richgamemedia.h | 2 +- engines/ags/engine/ac/room.cpp | 2 +- engines/ags/engine/ac/room.h | 2 +- engines/ags/engine/ac/roomobject.cpp | 2 +- engines/ags/engine/ac/roomobject.h | 2 +- engines/ags/engine/ac/roomstatus.cpp | 2 +- engines/ags/engine/ac/roomstatus.h | 6 ++--- engines/ags/engine/ac/route_finder.cpp | 6 ++--- engines/ags/engine/ac/route_finder.h | 6 ++--- engines/ags/engine/ac/route_finder_impl.cpp | 6 ++--- engines/ags/engine/ac/route_finder_impl.h | 6 ++--- .../engine/ac/route_finder_impl_legacy.cpp | 18 +++++++-------- .../ags/engine/ac/route_finder_impl_legacy.h | 6 ++--- engines/ags/engine/ac/screen.cpp | 2 +- engines/ags/engine/ac/screen.h | 4 ++-- engines/ags/engine/ac/screenoverlay.cpp | 2 +- engines/ags/engine/ac/screenoverlay.h | 2 +- engines/ags/engine/ac/slider.h | 2 +- engines/ags/engine/ac/sprite.cpp | 2 +- engines/ags/engine/ac/spritelistentry.h | 2 +- engines/ags/engine/ac/sys_events.cpp | 2 +- engines/ags/engine/ac/system.cpp | 2 +- engines/ags/engine/ac/textbox.h | 2 +- engines/ags/engine/ac/translation.cpp | 2 +- engines/ags/engine/ac/translation.h | 2 +- engines/ags/engine/ac/viewframe.cpp | 4 ++-- engines/ags/engine/ac/viewframe.h | 2 +- engines/ags/engine/ac/viewport_script.cpp | 2 +- engines/ags/engine/ac/walkablearea.cpp | 2 +- engines/ags/engine/ac/walkbehind.cpp | 2 +- .../engine/debugging/consoleoutputtarget.h | 2 +- engines/ags/engine/debugging/debug.cpp | 2 +- engines/ags/engine/debugging/debug_log.h | 6 ++--- engines/ags/engine/debugging/debugger.h | 2 +- .../engine/debugging/filebasedagsdebugger.cpp | 4 ++-- engines/ags/engine/debugging/logfile.cpp | 2 +- engines/ags/engine/debugging/logfile.h | 4 ++-- .../ags/engine/debugging/messagebuffer.cpp | 2 +- engines/ags/engine/debugging/messagebuffer.h | 2 +- engines/ags/engine/device/mousew32.cpp | 2 +- engines/ags/engine/device/mousew32.h | 2 +- engines/ags/engine/game/game_init.cpp | 2 +- engines/ags/engine/game/game_init.h | 2 +- engines/ags/engine/game/savegame.cpp | 2 +- engines/ags/engine/game/savegame.h | 2 +- .../ags/engine/game/savegame_components.cpp | 2 +- engines/ags/engine/game/savegame_components.h | 2 +- engines/ags/engine/game/savegame_internal.h | 2 +- engines/ags/engine/game/viewport.cpp | 2 +- engines/ags/engine/gfx/ali3dogl.cpp | 2 +- engines/ags/engine/gfx/ali3dsw.cpp | 2 +- engines/ags/engine/gfx/ali3dsw.h | 2 +- engines/ags/engine/gfx/gfx_util.cpp | 2 +- engines/ags/engine/gfx/gfxdriverbase.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_allegro.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_hqx.cpp | 2 +- engines/ags/engine/gfx/graphicsdriver.h | 4 ++-- engines/ags/engine/gui/animatingguibutton.cpp | 2 +- engines/ags/engine/gui/animatingguibutton.h | 2 +- engines/ags/engine/gui/cscidialog.cpp | 4 ++-- engines/ags/engine/gui/gui_engine.cpp | 6 ++--- engines/ags/engine/gui/guidialog.cpp | 2 +- engines/ags/engine/gui/guidialog.h | 6 ++--- engines/ags/engine/gui/guidialogdefines.h | 2 +- engines/ags/engine/gui/mylabel.cpp | 2 +- engines/ags/engine/gui/mylistbox.cpp | 2 +- engines/ags/engine/gui/mypushbutton.cpp | 2 +- engines/ags/engine/gui/mytextbox.cpp | 2 +- engines/ags/engine/main/config.cpp | 4 ++-- engines/ags/engine/main/config.h | 6 ++--- engines/ags/engine/main/engine.cpp | 2 +- engines/ags/engine/main/engine.h | 4 ++-- engines/ags/engine/main/engine_setup.cpp | 2 +- engines/ags/engine/main/game_file.cpp | 2 +- engines/ags/engine/main/game_file.h | 2 +- engines/ags/engine/main/game_run.cpp | 2 +- engines/ags/engine/main/game_start.cpp | 2 +- engines/ags/engine/main/graphics_mode.cpp | 2 +- engines/ags/engine/main/graphics_mode.h | 2 +- engines/ags/engine/main/main.cpp | 8 +++---- engines/ags/engine/main/main.h | 12 +++++----- engines/ags/engine/main/quit.cpp | 2 +- engines/ags/engine/main/update.cpp | 2 +- .../ags/engine/media/audio/ambientsound.cpp | 2 +- engines/ags/engine/media/audio/ambientsound.h | 2 +- engines/ags/engine/media/audio/audio.cpp | 2 +- .../engine/media/audio/queuedaudioitem.cpp | 2 +- .../ags/engine/media/audio/queuedaudioitem.h | 2 +- engines/ags/engine/media/audio/soundcache.cpp | 2 +- engines/ags/engine/media/video/video.cpp | 2 +- .../ags/engine/platform/android/acpland.cpp | 2 +- .../platform/base/agsplatformdriver.cpp | 2 +- .../engine/platform/base/agsplatformdriver.h | 6 ++--- engines/ags/engine/platform/ios/acplios.cpp | 2 +- engines/ags/engine/platform/linux/acpllnx.cpp | 2 +- engines/ags/engine/platform/osx/acplmac.cpp | 2 +- .../ags/engine/platform/windows/acplwin.cpp | 2 +- .../engine/platform/windows/gfx/ali3dd3d.cpp | 4 ++-- .../engine/platform/windows/gfx/ali3dd3d.h | 4 ++-- .../platform/windows/media/video/acwavi.cpp | 2 +- .../platform/windows/setup/winsetup.cpp | 2 +- .../engine/platform/windows/setup/winsetup.h | 2 +- .../platform/windows/win_ex_handling.cpp | 4 ++-- .../engine/platform/windows/win_ex_handling.h | 4 ++-- engines/ags/engine/plugin/agsplugin.cpp | 14 ++++++------ engines/ags/engine/plugin/plugin_engine.h | 4 ++-- engines/ags/engine/script/cc_instance.cpp | 4 ++-- .../ags/engine/script/runtimescriptvalue.cpp | 2 +- .../ags/engine/script/runtimescriptvalue.h | 2 +- engines/ags/engine/script/script.cpp | 2 +- engines/ags/engine/script/script.h | 16 +++++++------- engines/ags/engine/script/script_api.cpp | 2 +- engines/ags/engine/script/script_engine.cpp | 4 ++-- engines/ags/engine/script/script_runtime.h | 4 ++-- engines/ags/engine/script/systemimports.h | 2 +- engines/ags/engine/util/library.h | 6 ++--- engines/ags/engine/util/library_dummy.h | 6 ++--- engines/ags/engine/util/library_posix.h | 22 +++++++++---------- engines/ags/engine/util/library_psp.h | 16 +++++++------- engines/ags/engine/util/library_windows.h | 14 ++++++------ engines/ags/engine/util/mutex_base.h | 4 ++-- engines/ags/shared/ac/audiocliptype.cpp | 2 +- engines/ags/shared/ac/audiocliptype.h | 2 +- engines/ags/shared/ac/characterinfo.cpp | 2 +- engines/ags/shared/ac/characterinfo.h | 2 +- engines/ags/shared/ac/common.cpp | 2 +- engines/ags/shared/ac/dialogtopic.cpp | 2 +- engines/ags/shared/ac/dialogtopic.h | 2 +- .../ags/shared/ac/dynobj/scriptaudioclip.cpp | 2 +- .../ags/shared/ac/dynobj/scriptaudioclip.h | 2 +- engines/ags/shared/ac/gamesetupstruct.cpp | 2 +- engines/ags/shared/ac/gamesetupstruct.h | 14 ++++++------ engines/ags/shared/ac/gamesetupstructbase.cpp | 2 +- engines/ags/shared/ac/gamesetupstructbase.h | 4 ++-- engines/ags/shared/ac/inventoryiteminfo.cpp | 2 +- engines/ags/shared/ac/inventoryiteminfo.h | 2 +- engines/ags/shared/ac/mousecursor.cpp | 2 +- engines/ags/shared/ac/mousecursor.h | 2 +- engines/ags/shared/ac/spritecache.cpp | 4 ++-- engines/ags/shared/ac/spritecache.h | 6 ++--- engines/ags/shared/ac/view.cpp | 4 ++-- engines/ags/shared/ac/view.h | 2 +- engines/ags/shared/ac/wordsdictionary.cpp | 2 +- engines/ags/shared/ac/wordsdictionary.h | 2 +- engines/ags/shared/api/stream_api.h | 4 ++-- engines/ags/shared/core/asset.cpp | 4 ++-- engines/ags/shared/core/asset.h | 4 ++-- engines/ags/shared/core/assetmanager.cpp | 4 ++-- engines/ags/shared/core/assetmanager.h | 4 ++-- engines/ags/shared/debugging/debugmanager.cpp | 4 ++-- engines/ags/shared/debugging/debugmanager.h | 4 ++-- engines/ags/shared/debugging/out.h | 4 ++-- engines/ags/shared/debugging/outputhandler.h | 2 +- engines/ags/shared/font/fonts.cpp | 6 ++--- engines/ags/shared/font/fonts.h | 4 ++-- engines/ags/shared/font/ttffontrenderer.cpp | 2 +- engines/ags/shared/font/wfnfont.cpp | 2 +- engines/ags/shared/font/wfnfont.h | 4 ++-- engines/ags/shared/font/wfnfontrenderer.cpp | 2 +- engines/ags/shared/game/customproperties.cpp | 4 ++-- engines/ags/shared/game/customproperties.h | 4 ++-- engines/ags/shared/game/interactions.cpp | 6 ++--- engines/ags/shared/game/interactions.h | 6 ++--- engines/ags/shared/game/main_game_file.cpp | 4 ++-- engines/ags/shared/game/main_game_file.h | 4 ++-- engines/ags/shared/game/plugininfo.h | 4 ++-- engines/ags/shared/game/room_file.cpp | 4 ++-- engines/ags/shared/game/room_file.h | 4 ++-- .../ags/shared/game/room_file_deprecated.cpp | 4 ++-- engines/ags/shared/game/roomstruct.cpp | 4 ++-- engines/ags/shared/game/roomstruct.h | 6 ++--- engines/ags/shared/gfx/allegrobitmap.cpp | 4 ++-- engines/ags/shared/gfx/allegrobitmap.h | 4 ++-- engines/ags/shared/gfx/bitmap.cpp | 4 ++-- engines/ags/shared/gfx/bitmap.h | 8 +++---- engines/ags/shared/gfx/gfx_def.h | 4 ++-- engines/ags/shared/gui/guibutton.cpp | 6 ++--- engines/ags/shared/gui/guibutton.h | 6 ++--- engines/ags/shared/gui/guidefines.h | 4 ++-- engines/ags/shared/gui/guiinv.cpp | 6 ++--- engines/ags/shared/gui/guiinv.h | 6 ++--- engines/ags/shared/gui/guilabel.cpp | 6 ++--- engines/ags/shared/gui/guilabel.h | 6 ++--- engines/ags/shared/gui/guilistbox.cpp | 6 ++--- engines/ags/shared/gui/guilistbox.h | 6 ++--- engines/ags/shared/gui/guimain.cpp | 6 ++--- engines/ags/shared/gui/guimain.h | 6 ++--- engines/ags/shared/gui/guiobject.cpp | 4 ++-- engines/ags/shared/gui/guiobject.h | 6 ++--- engines/ags/shared/gui/guislider.cpp | 6 ++--- engines/ags/shared/gui/guislider.h | 6 ++--- engines/ags/shared/gui/guitextbox.cpp | 6 ++--- engines/ags/shared/gui/guitextbox.h | 6 ++--- engines/ags/shared/script/cc_error.cpp | 2 +- engines/ags/shared/script/cc_error.h | 4 ++-- engines/ags/shared/script/cc_script.cpp | 2 +- engines/ags/shared/script/cc_script.h | 2 +- engines/ags/shared/util/alignedstream.cpp | 4 ++-- engines/ags/shared/util/alignedstream.h | 4 ++-- engines/ags/shared/util/bbop.h | 4 ++-- engines/ags/shared/util/bufferedstream.cpp | 4 ++-- engines/ags/shared/util/bufferedstream.h | 4 ++-- engines/ags/shared/util/compress.cpp | 2 +- engines/ags/shared/util/compress.h | 2 +- engines/ags/shared/util/datastream.cpp | 4 ++-- engines/ags/shared/util/datastream.h | 4 ++-- engines/ags/shared/util/directory.cpp | 4 ++-- engines/ags/shared/util/directory.h | 4 ++-- engines/ags/shared/util/error.h | 4 ++-- engines/ags/shared/util/file.cpp | 4 ++-- engines/ags/shared/util/file.h | 4 ++-- engines/ags/shared/util/filestream.cpp | 4 ++-- engines/ags/shared/util/filestream.h | 4 ++-- engines/ags/shared/util/geometry.cpp | 4 ++-- engines/ags/shared/util/geometry.h | 6 ++--- engines/ags/shared/util/ini_util.cpp | 4 ++-- engines/ags/shared/util/ini_util.h | 4 ++-- engines/ags/shared/util/inifile.cpp | 4 ++-- engines/ags/shared/util/inifile.h | 4 ++-- engines/ags/shared/util/lzw.cpp | 2 +- engines/ags/shared/util/lzw.h | 2 +- engines/ags/shared/util/math.h | 4 ++-- engines/ags/shared/util/memory.h | 4 ++-- engines/ags/shared/util/misc.cpp | 2 +- engines/ags/shared/util/misc.h | 2 +- engines/ags/shared/util/multifilelib.h | 4 ++-- engines/ags/shared/util/mutifilelib.cpp | 6 ++--- engines/ags/shared/util/path.cpp | 4 ++-- engines/ags/shared/util/path.h | 4 ++-- engines/ags/shared/util/proxystream.cpp | 4 ++-- engines/ags/shared/util/proxystream.h | 4 ++-- engines/ags/shared/util/stream.cpp | 4 ++-- engines/ags/shared/util/stream.h | 4 ++-- engines/ags/shared/util/string.cpp | 4 ++-- engines/ags/shared/util/string.h | 4 ++-- engines/ags/shared/util/string_types.h | 8 +++---- engines/ags/shared/util/string_utils.cpp | 6 ++--- engines/ags/shared/util/string_utils.h | 6 ++--- engines/ags/shared/util/textreader.h | 4 ++-- engines/ags/shared/util/textstreamreader.cpp | 4 ++-- engines/ags/shared/util/textstreamreader.h | 4 ++-- engines/ags/shared/util/textstreamwriter.cpp | 4 ++-- engines/ags/shared/util/textstreamwriter.h | 4 ++-- engines/ags/shared/util/textwriter.h | 4 ++-- engines/ags/shared/util/version.cpp | 4 ++-- engines/ags/shared/util/version.h | 4 ++-- engines/ags/shared/util/wgt2allg.cpp | 2 +- engines/ags/shared/util/wgt2allg.h | 2 +- 337 files changed, 575 insertions(+), 575 deletions(-) diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index eb5c0e4ffca5..f6174449608d 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -36,12 +36,12 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } } -using AGS::Common::Stream; -using AGS::Common::String; +using AGS::Shared::Stream; +using AGS::Shared::String; // Looks for valid asset library everywhere and returns path, or empty string if failed String find_assetlib(const String &filename); diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp index e3898f35a616..e793a87cf61d 100644 --- a/engines/ags/engine/ac/audiochannel.cpp +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -29,7 +29,7 @@ #include "script/runtimescriptvalue.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameState play; extern RoomStruct thisroom; diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp index bf61dd5834e3..91f24fa8c632 100644 --- a/engines/ags/engine/ac/button.cpp +++ b/engines/ags/engine/ac/button.cpp @@ -32,7 +32,7 @@ #include "gui/animatingguibutton.h" #include "gui/guimain.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern ViewStruct *views; diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h index 65ef6a42d194..f8293b405635 100644 --- a/engines/ags/engine/ac/button.h +++ b/engines/ags/engine/ac/button.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::GUIButton; +using AGS::Shared::GUIButton; void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat); const char *Button_GetText_New(GUIButton *butt); diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index 347eb922d278..d1ef4162f673 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -71,7 +71,7 @@ #include "media/audio/audio_system.h" #include "ac/movelist.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern int displayed_room, starting_room; diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h index 9039aaf9adf2..c275cfd2379e 100644 --- a/engines/ags/engine/ac/character.h +++ b/engines/ags/engine/ac/character.h @@ -166,7 +166,7 @@ int Character_GetSpeakingFrame(CharacterInfo *chaa); struct MoveList; namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } } diff --git a/engines/ags/engine/ac/charactercache.h b/engines/ags/engine/ac/charactercache.h index ec6564d113c7..4d44bfeffd4c 100644 --- a/engines/ags/engine/ac/charactercache.h +++ b/engines/ags/engine/ac/charactercache.h @@ -26,7 +26,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } } diff --git a/engines/ags/engine/ac/characterextras.cpp b/engines/ags/engine/ac/characterextras.cpp index c76d794c2661..42c48cb39c9f 100644 --- a/engines/ags/engine/ac/characterextras.cpp +++ b/engines/ags/engine/ac/characterextras.cpp @@ -23,7 +23,7 @@ #include "ac/characterextras.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; void CharacterExtras::ReadFromFile(Stream *in) { in->ReadArrayOfInt16(invorder, MAX_INVORDER); diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h index 3d08847df39a..a94ef18b4396 100644 --- a/engines/ags/engine/ac/characterextras.h +++ b/engines/ags/engine/ac/characterextras.h @@ -29,7 +29,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } } diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp index 44ff6b96969d..d404c382a8d8 100644 --- a/engines/ags/engine/ac/characterinfo_engine.cpp +++ b/engines/ags/engine/ac/characterinfo_engine.cpp @@ -35,7 +35,7 @@ #include "main/update.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern ViewStruct *views; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 5b2a85f67534..c5f60cc601e8 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -60,7 +60,7 @@ #include "ac/mouse.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern GameState play; diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp index ddb918fae745..20255b1e92bb 100644 --- a/engines/ags/engine/ac/display.cpp +++ b/engines/ags/engine/ac/display.cpp @@ -55,8 +55,8 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" -using namespace AGS::Common; -using namespace AGS::Common::BitmapHelper; +using namespace AGS::Shared; +using namespace AGS::Shared::BitmapHelper; extern GameState play; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h index 35b5f7f13c46..44a0df247996 100644 --- a/engines/ags/engine/ac/display.h +++ b/engines/ags/engine/ac/display.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::GUIMain; +using AGS::Shared::GUIMain; // options for 'disp_type' parameter #define DISPLAYTEXT_SPEECH 0 diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index e5e80f3ac595..b6ed493c2da5 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -71,7 +71,7 @@ #include "media/audio/audio_system.h" #include "ac/game.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; #if AGS_PLATFORM_OS_ANDROID diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index 2613f34357ca..e100230c9b40 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -32,7 +32,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; typedef std::shared_ptr PBitmap; } diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index fb62af5e06af..46bb1a129898 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -52,7 +52,7 @@ #include "gfx/bitmap.h" #include "util/scaling.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; // TODO: choose these values depending on game resolution? diff --git a/engines/ags/engine/ac/draw_software.h b/engines/ags/engine/ac/draw_software.h index 8d8d20fd4bff..aee7079dde30 100644 --- a/engines/ags/engine/ac/draw_software.h +++ b/engines/ags/engine/ac/draw_software.h @@ -51,10 +51,10 @@ void invalidate_all_rects(); void invalidate_all_camera_rects(int view_index); void invalidate_rect_ds(int x1, int y1, int x2, int y2, bool in_room); // Paints the black screen background in the regions marked as dirty -void update_black_invreg_and_reset(AGS::Common::Bitmap *ds); +void update_black_invreg_and_reset(AGS::Shared::Bitmap *ds); // Copies the room regions marked as dirty from source (src) to destination (ds) with the given offset (x, y) // no_transform flag tells the system that the regions should be plain copied to the ds. -void update_room_invreg_and_reset(int view_index, AGS::Common::Bitmap *ds, AGS::Common::Bitmap *src, bool no_transform); +void update_room_invreg_and_reset(int view_index, AGS::Shared::Bitmap *ds, AGS::Shared::Bitmap *src, bool no_transform); } // namespace AGS3 diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp index 329e31297460..c6a8cfacd245 100644 --- a/engines/ags/engine/ac/drawingsurface.cpp +++ b/engines/ags/engine/ac/drawingsurface.cpp @@ -42,7 +42,7 @@ #include "gfx/gfx_def.h" #include "gfx/gfx_util.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp index a6143bf6ae1c..ef798801bf67 100644 --- a/engines/ags/engine/ac/dynamicsprite.cpp +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -41,7 +41,7 @@ #include "gfx/graphicsdriver.h" #include "script/runtimescriptvalue.h" -using namespace Common; +using namespace Shared; using namespace Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp index ea692ed53178..bdc815dd96b3 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -26,7 +26,7 @@ #include "ac/common.h" // quit() #include "util/bbop.h" -using namespace AGS::Common; +using namespace AGS::Shared; // *** The script serialization routines for built-in types diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp index 09fb15af7c7d..9794f0264688 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp @@ -45,7 +45,7 @@ #include "script/script_common.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; ICCStringClass *stringClassImpl = nullptr; diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index 42394dc11c88..9fc61a45183c 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -36,7 +36,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } } diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp index df0e23233d7b..6898ffb963b4 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -25,7 +25,7 @@ #include "gui/guimain.h" #include "gui/guiobject.h" -using AGS::Common::GUIObject; +using AGS::Shared::GUIObject; // return the type name of the object const char *CCGUIObject::GetType() { diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index a5ab383717f0..f6e837f52d5c 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -30,7 +30,7 @@ #include "script/script_common.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; const auto OBJECT_CACHE_MAGIC_NUMBER = 0xa30b; const auto SERIALIZE_BUFFER_SIZE = 10240; diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index 654dcce97900..e40ead0ac2b4 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -32,7 +32,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp index 138464e29cf9..e8d434ee68e5 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.cpp +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -24,7 +24,7 @@ #include "ac/gamestate.h" #include "util/bbop.h" -using namespace AGS::Common; +using namespace AGS::Shared; ScriptCamera::ScriptCamera(int id) : _id(id) {} diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index 4677d3382858..ce1fe13b1507 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -45,7 +45,7 @@ namespace AGS3 { -using namespace AGS::Common; +using namespace AGS::Shared; class ScriptDictBase : public AGSCCDynamicObject { public: diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp index 08e1bbc591b6..6b2e240239e7 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -30,7 +30,7 @@ #include "game/roomstruct.h" #include "gfx/bitmap.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern RoomStruct thisroom; extern SpriteCache spriteset; diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h index c8033101bc6d..9d224c0babce 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h @@ -29,7 +29,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index cdf83af7cc89..ca7ecbc154c6 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -44,7 +44,7 @@ namespace AGS3 { -using namespace AGS::Common; +using namespace AGS::Shared; class ScriptSetBase : public AGSCCDynamicObject { public: diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp index 54bb03e849b4..c090db39bd66 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -24,7 +24,7 @@ #include "ac/gamestate.h" #include "util/bbop.h" -using namespace AGS::Common; +using namespace AGS::Shared; ScriptViewport::ScriptViewport(int id) : _id(id) {} diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp index e977adde5495..fec319880e44 100644 --- a/engines/ags/engine/ac/event.cpp +++ b/engines/ags/engine/ac/event.cpp @@ -42,7 +42,7 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index d6ae484206fd..c1128f960fab 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -46,7 +46,7 @@ #include "util/string.h" #include "util/string_utils.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetup usetup; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/file.h b/engines/ags/engine/ac/file.h index 2c3b4feede0c..c3e52dfbef55 100644 --- a/engines/ags/engine/ac/file.h +++ b/engines/ags/engine/ac/file.h @@ -34,7 +34,7 @@ namespace AGS3 { -using AGS::Common::Stream; +using AGS::Shared::Stream; int File_Exists(const char *fnmm); int File_Delete(const char *fnmm); diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 5fc5e57d00c2..f71b1a930968 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -98,7 +98,7 @@ #include "util/string_utils.h" #include "ac/keycode.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h index a977f74421c1..15cb70ffe3dc 100644 --- a/engines/ags/engine/ac/game.h +++ b/engines/ags/engine/ac/game.h @@ -37,7 +37,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Bitmap; class Stream; } // namespace Shared diff --git a/engines/ags/engine/ac/gamesetup.h b/engines/ags/engine/ac/gamesetup.h index 45c38211325e..5f1f48ad7c46 100644 --- a/engines/ags/engine/ac/gamesetup.h +++ b/engines/ags/engine/ac/gamesetup.h @@ -43,7 +43,7 @@ enum MouseSpeedDef { kNumMouseSpeedDefs }; -using AGS::Common::String; +using AGS::Shared::String; // TODO: reconsider the purpose of this struct. // Earlier I was trying to remove the uses of this struct from the engine diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index 2837ec920227..73c0d7cf933e 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -39,7 +39,7 @@ #include "util/alignedstream.h" #include "util/string_utils.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h index acf3d4845243..617153b51bc5 100644 --- a/engines/ags/engine/ac/gamestate.h +++ b/engines/ags/engine/ac/gamestate.h @@ -40,7 +40,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Bitmap; class Stream; typedef std::shared_ptr PBitmap; @@ -224,14 +224,14 @@ struct GameState { short temporarily_turned_off_character; // Hide Player Charactr ticked short inv_backwards_compatibility; int *gui_draw_order; - std::vector do_once_tokens; + std::vector do_once_tokens; int text_min_display_time_ms; int ignore_user_input_after_text_timeout_ms; int default_audio_type_volumes[MAX_AUDIO_TYPES]; // Dynamic custom property values for characters and items - std::vector charProps; - AGS::Common::StringIMap invProps[MAX_INV]; + std::vector charProps; + AGS::Shared::StringIMap invProps[MAX_INV]; // Dynamic speech state // diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp index b9154a968615..5f83560d3082 100644 --- a/engines/ags/engine/ac/global_audio.cpp +++ b/engines/ags/engine/ac/global_audio.cpp @@ -36,7 +36,7 @@ #include "ac/timer.h" #include "util/string_compat.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetup usetup; extern GameState play; diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp index 26a46dad6257..f6aa71a5b2b5 100644 --- a/engines/ags/engine/ac/global_button.cpp +++ b/engines/ags/engine/ac/global_button.cpp @@ -28,7 +28,7 @@ #include "gui/guimain.h" #include "gui/guibutton.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp index 874aa92d24cd..389efea22d35 100644 --- a/engines/ags/engine/ac/global_character.cpp +++ b/engines/ags/engine/ac/global_character.cpp @@ -47,7 +47,7 @@ #include "main/game_run.h" #include "script/script.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp index 4131c1834f29..be28d50e1f53 100644 --- a/engines/ags/engine/ac/global_debug.cpp +++ b/engines/ags/engine/ac/global_debug.cpp @@ -47,7 +47,7 @@ #include "gfx/graphicsdriver.h" #include "main/graphics_mode.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/global_debug.h b/engines/ags/engine/ac/global_debug.h index cf2bc81a2faf..bd60f9340bb7 100644 --- a/engines/ags/engine/ac/global_debug.h +++ b/engines/ags/engine/ac/global_debug.h @@ -28,7 +28,7 @@ namespace AGS3 { -AGS::Common::String GetRuntimeInfo(); +AGS::Shared::String GetRuntimeInfo(); void script_debug(int cmdd, int dataa); } // namespace AGS3 diff --git a/engines/ags/engine/ac/global_dialog.cpp b/engines/ags/engine/ac/global_dialog.cpp index 0acc1f5feee8..ff9240615b46 100644 --- a/engines/ags/engine/ac/global_dialog.cpp +++ b/engines/ags/engine/ac/global_dialog.cpp @@ -31,7 +31,7 @@ #include "debug/out.h" #include "script/script.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern GameState play; diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp index 08b821051a61..1ac54d54ff4d 100644 --- a/engines/ags/engine/ac/global_display.cpp +++ b/engines/ags/engine/ac/global_display.cpp @@ -41,7 +41,7 @@ #include "game/roomstruct.h" #include "main/game_run.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern TopBarSettings topBar; extern GameState play; diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp index 5fe00fdacdc3..f5556e7a0736 100644 --- a/engines/ags/engine/ac/global_drawingsurface.cpp +++ b/engines/ags/engine/ac/global_drawingsurface.cpp @@ -37,7 +37,7 @@ #include "gfx/gfx_def.h" #include "gfx/gfx_util.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern Bitmap *raw_saved_screen; diff --git a/engines/ags/engine/ac/global_dynamicsprite.cpp b/engines/ags/engine/ac/global_dynamicsprite.cpp index 4ecd20bf5d04..d5380a199308 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.cpp +++ b/engines/ags/engine/ac/global_dynamicsprite.cpp @@ -30,7 +30,7 @@ #include "gfx/graphicsdriver.h" #include "gfx/bitmap.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern SpriteCache spriteset; diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index 47670c712a6e..9b29b396d91f 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -32,7 +32,7 @@ #include "util/path.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; int32_t FileOpenCMode(const char *fnmm, const char *cmode) { Common::FileOpenMode open_mode; diff --git a/engines/ags/engine/ac/global_file.h b/engines/ags/engine/ac/global_file.h index 78afe03a0d31..be068bf1cfbb 100644 --- a/engines/ags/engine/ac/global_file.h +++ b/engines/ags/engine/ac/global_file.h @@ -27,7 +27,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index afeea81d3ba0..306a63832a5a 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -69,7 +69,7 @@ #include "util/string_utils.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; #define ALLEGRO_KEYBOARD_HANDLER diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp index 63b659d0ecbb..d8a0cdc010d5 100644 --- a/engines/ags/engine/ac/global_gui.cpp +++ b/engines/ags/engine/ac/global_gui.cpp @@ -36,7 +36,7 @@ #include "script/runtimescriptvalue.h" #include "util/string_compat.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern ScriptGUI *scrGui; diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp index c24917104f1f..a145d74bd85a 100644 --- a/engines/ags/engine/ac/global_hotspot.cpp +++ b/engines/ags/engine/ac/global_hotspot.cpp @@ -37,7 +37,7 @@ #include "game/roomstruct.h" #include "script/script.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern RoomStruct thisroom; extern RoomStatus *croom; diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp index 117a52492aec..7de499ee5bbc 100644 --- a/engines/ags/engine/ac/global_inventoryitem.cpp +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -34,7 +34,7 @@ #include "ac/event.h" #include "ac/gamestate.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern GameState play; diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp index 2943089f9c48..5561a7a63a7b 100644 --- a/engines/ags/engine/ac/global_label.cpp +++ b/engines/ags/engine/ac/global_label.cpp @@ -27,7 +27,7 @@ #include "ac/string.h" #include "gui/guimain.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp index ec7c793e31ca..53cae9bb3d88 100644 --- a/engines/ags/engine/ac/global_object.cpp +++ b/engines/ags/engine/ac/global_object.cpp @@ -45,7 +45,7 @@ #include "gfx/bitmap.h" #include "gfx/gfx_def.h" -using namespace AGS::Common; +using namespace AGS::Shared; #define OVERLAPPING_OBJECT 1000 diff --git a/engines/ags/engine/ac/global_object.h b/engines/ags/engine/ac/global_object.h index 05e521356efe..4d192b82a982 100644 --- a/engines/ags/engine/ac/global_object.h +++ b/engines/ags/engine/ac/global_object.h @@ -25,7 +25,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp index bd10c5e7d400..572a71cba51d 100644 --- a/engines/ags/engine/ac/global_overlay.cpp +++ b/engines/ags/engine/ac/global_overlay.cpp @@ -35,7 +35,7 @@ #include "ac/system.h" #include "gfx/bitmap.h" -using namespace Common; +using namespace Shared; using namespace Engine; extern SpriteCache spriteset; diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp index 46c79ade0036..e02e28e5822f 100644 --- a/engines/ags/engine/ac/global_region.cpp +++ b/engines/ags/engine/ac/global_region.cpp @@ -32,7 +32,7 @@ #include "script/script.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern RoomStruct thisroom; extern RoomStatus *croom; diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp index e07db97dfe2b..1b55d8f42e7e 100644 --- a/engines/ags/engine/ac/global_room.cpp +++ b/engines/ags/engine/ac/global_room.cpp @@ -39,7 +39,7 @@ #include "script/script.h" #include "util/math.h" -using namespace Common; +using namespace Shared; extern GameState play; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp index 5e77dbb647d6..c8cb0f04d90a 100644 --- a/engines/ags/engine/ac/global_screen.cpp +++ b/engines/ags/engine/ac/global_screen.cpp @@ -35,7 +35,7 @@ #include "gfx/graphicsdriver.h" #include "gfx/bitmap.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetup usetup; diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp index 290b864e512f..512af4c99dc4 100644 --- a/engines/ags/engine/ac/global_slider.cpp +++ b/engines/ags/engine/ac/global_slider.cpp @@ -27,7 +27,7 @@ #include "gui/guimain.h" #include "gui/guislider.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp index fec358f98b99..8cdbe69b2e53 100644 --- a/engines/ags/engine/ac/global_textbox.cpp +++ b/engines/ags/engine/ac/global_textbox.cpp @@ -28,7 +28,7 @@ #include "gui/guimain.h" #include "gui/guitextbox.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index 5e6230810be3..d2a7b90d2323 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -33,7 +33,7 @@ #include "util/memory.h" #include "core/types.h" -using namespace AGS::Common::Memory; +using namespace AGS::Shared::Memory; extern GameState play; extern AGSPlatformDriver *platform; diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp index 7dc5c7ec2afa..bd57d417f7d1 100644 --- a/engines/ags/engine/ac/global_walkablearea.cpp +++ b/engines/ags/engine/ac/global_walkablearea.cpp @@ -28,7 +28,7 @@ #include "debug/debug_log.h" #include "game/roomstruct.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern RoomStruct thisroom; diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp index 479060c578c7..060914d46801 100644 --- a/engines/ags/engine/ac/gui.cpp +++ b/engines/ags/engine/ac/gui.cpp @@ -56,7 +56,7 @@ #include "util/string_compat.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; diff --git a/engines/ags/engine/ac/gui.h b/engines/ags/engine/ac/gui.h index 1cb7629dfde3..e8e179f9f2ae 100644 --- a/engines/ags/engine/ac/gui.h +++ b/engines/ags/engine/ac/gui.h @@ -28,8 +28,8 @@ namespace AGS3 { -using AGS::Common::GUIMain; -using AGS::Common::GUIObject; +using AGS::Shared::GUIMain; +using AGS::Shared::GUIObject; ScriptGUI *GUI_AsTextWindow(ScriptGUI *tehgui); int GUI_GetPopupStyle(ScriptGUI *tehgui); @@ -71,7 +71,7 @@ ScriptGUI *GetGUIAtLocation(int xx, int yy); void remove_popup_interface(int ifacenum); void process_interface_click(int ifce, int btn, int mbut); -void replace_macro_tokens(const char *text, AGS::Common::String &fixed_text); +void replace_macro_tokens(const char *text, AGS::Shared::String &fixed_text); void update_gui_zorder(); void export_gui_controls(int ee); void unexport_gui_controls(int ee); diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp index cc182c4db89e..edb96d95cd7d 100644 --- a/engines/ags/engine/ac/guicontrol.cpp +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -35,7 +35,7 @@ #include "ac/dynobj/cc_gui.h" #include "ac/dynobj/cc_guiobject.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern ScriptGUI *scrGui; extern CCGUI ccDynamicGUI; diff --git a/engines/ags/engine/ac/guicontrol.h b/engines/ags/engine/ac/guicontrol.h index 1f8d60ef3da5..1159917394ec 100644 --- a/engines/ags/engine/ac/guicontrol.h +++ b/engines/ags/engine/ac/guicontrol.h @@ -34,13 +34,13 @@ namespace AGS3 { -using AGS::Common::GUIObject; -using AGS::Common::GUIButton; -using AGS::Common::GUIInvWindow; -using AGS::Common::GUILabel; -using AGS::Common::GUIListBox; -using AGS::Common::GUISlider; -using AGS::Common::GUITextBox; +using AGS::Shared::GUIObject; +using AGS::Shared::GUIButton; +using AGS::Shared::GUIInvWindow; +using AGS::Shared::GUILabel; +using AGS::Shared::GUIListBox; +using AGS::Shared::GUISlider; +using AGS::Shared::GUITextBox; GUIObject *GetGUIControlAtLocation(int xx, int yy); int GUIControl_GetVisible(GUIObject *guio); diff --git a/engines/ags/engine/ac/guiinv.cpp b/engines/ags/engine/ac/guiinv.cpp index 7bda0b6a5acd..ef3608d34e09 100644 --- a/engines/ags/engine/ac/guiinv.cpp +++ b/engines/ags/engine/ac/guiinv.cpp @@ -38,7 +38,7 @@ extern SpriteCache spriteset; namespace AGS { -namespace Common { +namespace Shared { int GUIInvWindow::GetCharacterId() const { if (CharId < 0) @@ -91,5 +91,5 @@ void GUIInvWindow::Draw(Bitmap *ds) { } } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp index 01c4d74bcc66..a57a57a45802 100644 --- a/engines/ags/engine/ac/hotspot.cpp +++ b/engines/ags/engine/ac/hotspot.cpp @@ -33,7 +33,7 @@ #include "gfx/bitmap.h" #include "script/runtimescriptvalue.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern RoomStruct thisroom; extern RoomStatus *croom; diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp index eafc35680f48..ed8ba694647e 100644 --- a/engines/ags/engine/ac/invwindow.cpp +++ b/engines/ags/engine/ac/invwindow.cpp @@ -45,7 +45,7 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern GameState play; diff --git a/engines/ags/engine/ac/invwindow.h b/engines/ags/engine/ac/invwindow.h index 29f9c3ace268..ebb7fc8822ac 100644 --- a/engines/ags/engine/ac/invwindow.h +++ b/engines/ags/engine/ac/invwindow.h @@ -29,7 +29,7 @@ namespace AGS3 { -using AGS::Common::GUIInvWindow; +using AGS::Shared::GUIInvWindow; void InvWindow_SetCharacterToUse(GUIInvWindow *guii, CharacterInfo *chaa); CharacterInfo *InvWindow_GetCharacterToUse(GUIInvWindow *guii); diff --git a/engines/ags/engine/ac/label.h b/engines/ags/engine/ac/label.h index a1102b8d0f88..27453a5bcd87 100644 --- a/engines/ags/engine/ac/label.h +++ b/engines/ags/engine/ac/label.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::GUILabel; +using AGS::Shared::GUILabel; const char *Label_GetText_New(GUILabel *labl); void Label_GetText(GUILabel *labl, char *buffer); diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index ca42a539fb8e..57635d104d9d 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -32,7 +32,7 @@ #include "gui/guimain.h" #include "debug/debug_log.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameState play; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/listbox.h b/engines/ags/engine/ac/listbox.h index 96267dffd142..7642a9dfba53 100644 --- a/engines/ags/engine/ac/listbox.h +++ b/engines/ags/engine/ac/listbox.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::GUIListBox; +using AGS::Shared::GUIListBox; int ListBox_AddItem(GUIListBox *lbb, const char *text); int ListBox_InsertItemAt(GUIListBox *lbb, int index, const char *text); diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp index 067571982566..9b6f65c89cf1 100644 --- a/engines/ags/engine/ac/mouse.cpp +++ b/engines/ags/engine/ac/mouse.cpp @@ -42,7 +42,7 @@ #include "gfx/graphicsdriver.h" #include "gfx/gfxfilter.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/movelist.cpp b/engines/ags/engine/ac/movelist.cpp index 8f8d034d7a5a..b2402618b3aa 100644 --- a/engines/ags/engine/ac/movelist.cpp +++ b/engines/ags/engine/ac/movelist.cpp @@ -24,7 +24,7 @@ #include "ac/common.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; void MoveList::ReadFromFile_Legacy(Stream *in) { diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h index 45334055180b..06aa462fc34b 100644 --- a/engines/ags/engine/ac/movelist.h +++ b/engines/ags/engine/ac/movelist.h @@ -30,7 +30,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp index 6cedba484f89..399f4bbbc94a 100644 --- a/engines/ags/engine/ac/object.cpp +++ b/engines/ags/engine/ac/object.cpp @@ -46,7 +46,7 @@ #include "ac/dynobj/cc_object.h" #include "ac/movelist.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; diff --git a/engines/ags/engine/ac/object.h b/engines/ags/engine/ac/object.h index fc02fafc89f8..39b3126ae99c 100644 --- a/engines/ags/engine/ac/object.h +++ b/engines/ags/engine/ac/object.h @@ -37,7 +37,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp index 3d1b5bcc26e6..8f6fe78dc79c 100644 --- a/engines/ags/engine/ac/overlay.cpp +++ b/engines/ags/engine/ac/overlay.cpp @@ -38,7 +38,7 @@ #include "gfx/bitmap.h" #include "script/runtimescriptvalue.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h index 958a8b8f3379..683f9a489e27 100644 --- a/engines/ags/engine/ac/overlay.h +++ b/engines/ags/engine/ac/overlay.h @@ -30,7 +30,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp index 4ec35d8794e3..c966d4d9fd54 100644 --- a/engines/ags/engine/ac/parser.cpp +++ b/engines/ags/engine/ac/parser.cpp @@ -32,7 +32,7 @@ #include "util/string.h" #include "util/string_compat.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern GameState play; diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h index e8768e936d53..8630e8235192 100644 --- a/engines/ags/engine/ac/path_helper.h +++ b/engines/ags/engine/ac/path_helper.h @@ -33,7 +33,7 @@ namespace AGS3 { -using AGS::Common::String; +using AGS::Shared::String; // Filepath tokens, which are replaced by platform-specific directory names extern const String UserSavedgamesRootToken; diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp index aae559baac16..e68c908cbde9 100644 --- a/engines/ags/engine/ac/properties.cpp +++ b/engines/ags/engine/ac/properties.cpp @@ -28,7 +28,7 @@ #include "script/runtimescriptvalue.h" #include "util/string_utils.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetupStruct game; extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h index ba829662a53c..aa877441da67 100644 --- a/engines/ags/engine/ac/properties.h +++ b/engines/ags/engine/ac/properties.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::StringIMap; +using AGS::Shared::StringIMap; // Getting a property value requires static and runtime property maps. // Key is first searched in runtime map, if not found - static map is taken, diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp index a9755ed88de5..27a3d05ea528 100644 --- a/engines/ags/engine/ac/region.cpp +++ b/engines/ags/engine/ac/region.cpp @@ -32,7 +32,7 @@ #include "game/roomstruct.h" #include "script/runtimescriptvalue.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; extern RoomStruct thisroom; diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp index 7e0888c2c034..3bf8e2c68c3e 100644 --- a/engines/ags/engine/ac/richgamemedia.cpp +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -23,7 +23,7 @@ #include "ac/richgamemedia.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; void RICH_GAME_MEDIA_HEADER::ReadFromFile(Stream *in) { dwMagicNumber = in->ReadInt32(); diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index 02bc1b1592c1..420903aacb55 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -32,7 +32,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index e77929b86320..d2055e6049f5 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -77,7 +77,7 @@ #include "util/math.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetup usetup; diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h index 4b3e5789d300..05f36efe87b6 100644 --- a/engines/ags/engine/ac/room.h +++ b/engines/ags/engine/ac/room.h @@ -76,7 +76,7 @@ struct MoveList; // Convert move path from room's mask resolution to room resolution void convert_move_path_to_room_resolution(MoveList *ml); -extern AGS::Common::RoomStruct thisroom; +extern AGS::Shared::RoomStruct thisroom; } // namespace AGS3 diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp index b4a8d4de4f7b..ac9a7b05e45b 100644 --- a/engines/ags/engine/ac/roomobject.cpp +++ b/engines/ags/engine/ac/roomobject.cpp @@ -30,7 +30,7 @@ #include "main/update.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; extern ViewStruct *views; extern GameState play; diff --git a/engines/ags/engine/ac/roomobject.h b/engines/ags/engine/ac/roomobject.h index 2d8111b99be9..b78f9a80d5b5 100644 --- a/engines/ags/engine/ac/roomobject.h +++ b/engines/ags/engine/ac/roomobject.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp index 96e036b72f6e..368875d0bf9b 100644 --- a/engines/ags/engine/ac/roomstatus.cpp +++ b/engines/ags/engine/ac/roomstatus.cpp @@ -29,7 +29,7 @@ #include "game/savegame_components.h" #include "util/alignedstream.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; RoomStatus::RoomStatus() { diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h index a00799e05c41..f23e71dfd8aa 100644 --- a/engines/ags/engine/ac/roomstatus.h +++ b/engines/ags/engine/ac/roomstatus.h @@ -32,13 +32,13 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS -using AGS::Common::Stream; -using AGS::Common::Interaction; +using AGS::Shared::Stream; +using AGS::Shared::Interaction; // This struct is saved in the save games - it contains everything about // a room that could change diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index 60be1c042fb3..5de75a3e049a 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -27,7 +27,7 @@ #include "debug/out.h" -using AGS::Common::Bitmap; +using AGS::Shared::Bitmap; class IRouteFinder { public: @@ -101,10 +101,10 @@ static IRouteFinder *route_finder_impl = nullptr; void init_pathfinder(GameDataVersion game_file_version) { if (game_file_version >= kGameVersion_350) { - AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize path finder library"); + AGS::Shared::Debug::Printf(AGS::Shared::MessageType::kDbgMsg_Info, "Initialize path finder library"); route_finder_impl = new AGSRouteFinder(); } else { - AGS::Common::Debug::Printf(AGS::Common::MessageType::kDbgMsg_Info, "Initialize legacy path finder library"); + AGS::Shared::Debug::Printf(AGS::Shared::MessageType::kDbgMsg_Info, "Initialize legacy path finder library"); route_finder_impl = new AGSLegacyRouteFinder(); } diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h index 3cef9962fa53..575903484323 100644 --- a/engines/ags/engine/ac/route_finder.h +++ b/engines/ags/engine/ac/route_finder.h @@ -29,7 +29,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS @@ -39,14 +39,14 @@ struct MoveList; void init_pathfinder(GameDataVersion game_file_version); void shutdown_pathfinder(); -void set_wallscreen(AGS::Common::Bitmap *wallscreen); +void set_wallscreen(AGS::Shared::Bitmap *wallscreen); int can_see_from(int x1, int y1, int x2, int y2); void get_lastcpos(int &lastcx, int &lastcy); // NOTE: pathfinder implementation mostly needs to know proportion between x and y speed void set_route_move_speed(int speed_x, int speed_y); -int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); +int find_route(short srcx, short srcy, short xx, short yy, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); void calculate_move_stage(MoveList *mlsp, int aaa); } // namespace AGS3 diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp index 24a95870445f..66970fb31fa6 100644 --- a/engines/ags/engine/ac/route_finder_impl.cpp +++ b/engines/ags/engine/ac/route_finder_impl.cpp @@ -41,7 +41,7 @@ extern MoveList *mls; -using AGS::Common::Bitmap; +using AGS::Shared::Bitmap; // #define DEBUG_PATHFINDER @@ -238,14 +238,14 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int assert(num_navpoints <= MAXNAVPOINTS); #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stages", srcx, srcy, xx, yy, num_navpoints); + AGS::Shared::Debug::Printf("Route from %d,%d to %d,%d - %d stages", srcx, srcy, xx, yy, num_navpoints); #endif int mlist = movlst; mls[mlist].numstage = num_navpoints; memcpy(&mls[mlist].pos[0], &navpoints[0], sizeof(int) * num_navpoints); #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stages: %d\n", num_navpoints); + AGS::Shared::Debug::Printf("stages: %d\n", num_navpoints); #endif for (i = 0; i < num_navpoints - 1; i++) diff --git a/engines/ags/engine/ac/route_finder_impl.h b/engines/ags/engine/ac/route_finder_impl.h index 43600c8fe91e..cfd44228e032 100644 --- a/engines/ags/engine/ac/route_finder_impl.h +++ b/engines/ags/engine/ac/route_finder_impl.h @@ -29,7 +29,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS @@ -43,14 +43,14 @@ namespace RouteFinder { void init_pathfinder(); void shutdown_pathfinder(); -void set_wallscreen(AGS::Common::Bitmap *wallscreen); +void set_wallscreen(AGS::Shared::Bitmap *wallscreen); int can_see_from(int x1, int y1, int x2, int y2); void get_lastcpos(int &lastcx, int &lastcy); void set_route_move_speed(int speed_x, int speed_y); -int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); +int find_route(short srcx, short srcy, short xx, short yy, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); void calculate_move_stage(MoveList *mlsp, int aaa); } // namespace RouteFinder diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp index c7cb82fefa53..4bbe4c35e6bd 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp +++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp @@ -43,8 +43,8 @@ extern void update_polled_stuff_if_runtime(); extern MoveList *mls; -using AGS::Common::Bitmap; -namespace BitmapHelper = AGS::Common::BitmapHelper; +using AGS::Shared::Bitmap; +namespace BitmapHelper = AGS::Shared::BitmapHelper; // #define DEBUG_PATHFINDER @@ -231,7 +231,7 @@ static int is_route_possible(int fromx, int fromy, int tox, int toy, Bitmap *wss walk_area_granularity[dd] = MAX_GRANULARITY; #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("area %d: Gran %d", dd, walk_area_granularity[dd]); + AGS::Shared::Debug::Printf("area %d: Gran %d", dd, walk_area_granularity[dd]); #endif } walk_area_granularity[0] = MAX_GRANULARITY; @@ -323,7 +323,7 @@ static int try_this_square(int srcx, int srcy, int tox, int toy) { iterations++; if (iterations > 5) { #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("not found: %d,%d beenhere 0x%X\n", srcx, srcy, beenhere[srcy][srcx]); + AGS::Shared::Debug::Printf("not found: %d,%d beenhere 0x%X\n", srcx, srcy, beenhere[srcy][srcx]); #endif nesting--; return 0; @@ -733,7 +733,7 @@ void calculate_move_stage(MoveList *mlsp, int aaa) { mlsp->ypermove[aaa] = newymove; #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stage %d from %d,%d to %d,%d Xpermove:%X Ypm:%X", aaa, ourx, oury, destx, desty, newxmove, newymove); + AGS::Shared::Debug::Printf("stage %d from %d,%d to %d,%d Xpermove:%X Ypm:%X", aaa, ourx, oury, destx, desty, newxmove, newymove); // wtextcolor(14); // wgtprintf((reallyneed[aaa] >> 16) & 0x000ffff, reallyneed[aaa] & 0x000ffff, cbuttfont, "%d", aaa); #endif @@ -807,7 +807,7 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int // find the furthest point that can be seen from this stage for (aaa = pathbackstage - 1; aaa >= 0; aaa--) { #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stage %2d: %2d,%2d\n", aaa, pathbackx[aaa], pathbacky[aaa]); + AGS::Shared::Debug::Printf("stage %2d: %2d,%2d\n", aaa, pathbackx[aaa], pathbacky[aaa]); #endif if (can_see_from(srcx, srcy, pathbackx[aaa], pathbacky[aaa])) { nearestpos = MAKE_INTCOORD(pathbackx[aaa], pathbacky[aaa]); @@ -831,7 +831,7 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int srcx = (nearestpos >> 16) & 0x000ffff; srcy = nearestpos & 0x000ffff; #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("Added: %d, %d pbs:%d", srcx, srcy, pathbackstage); + AGS::Shared::Debug::Printf("Added: %d, %d pbs:%d", srcx, srcy, pathbackstage); #endif lastpbs = pathbackstage; pathbackstage = nearestindx; @@ -853,13 +853,13 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int return 0; } #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("Route from %d,%d to %d,%d - %d stage, %d stages", orisrcx, orisrcy, xx, yy, pathbackstage, numstages); + AGS::Shared::Debug::Printf("Route from %d,%d to %d,%d - %d stage, %d stages", orisrcx, orisrcy, xx, yy, pathbackstage, numstages); #endif int mlist = movlst; mls[mlist].numstage = numstages; memcpy(&mls[mlist].pos[0], &reallyneed[0], sizeof(int) * numstages); #ifdef DEBUG_PATHFINDER - AGS::Common::Debug::Printf("stages: %d\n", numstages); + AGS::Shared::Debug::Printf("stages: %d\n", numstages); #endif for (aaa = 0; aaa < numstages - 1; aaa++) { diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h index 632038d524dc..d61cf03c74f7 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.h +++ b/engines/ags/engine/ac/route_finder_impl_legacy.h @@ -27,7 +27,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS @@ -41,14 +41,14 @@ namespace RouteFinderLegacy { void init_pathfinder(); void shutdown_pathfinder(); -void set_wallscreen(AGS::Common::Bitmap *wallscreen); +void set_wallscreen(AGS::Shared::Bitmap *wallscreen); int can_see_from(int x1, int y1, int x2, int y2); void get_lastcpos(int &lastcx, int &lastcy); void set_route_move_speed(int speed_x, int speed_y); -int find_route(short srcx, short srcy, short xx, short yy, AGS::Common::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); +int find_route(short srcx, short srcy, short xx, short yy, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0); void calculate_move_stage(MoveList *mlsp, int aaa); } // namespace RouteFinderLegacy diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index 39faca649664..299fb1d63f49 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -36,7 +36,7 @@ #include "gfx/bitmap.h" #include "gfx/graphicsdriver.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/screen.h b/engines/ags/engine/ac/screen.h index e38b092050f3..ef1ecba60cb6 100644 --- a/engines/ags/engine/ac/screen.h +++ b/engines/ags/engine/ac/screen.h @@ -26,7 +26,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS @@ -42,7 +42,7 @@ void current_fade_out_effect(); AGS::Engine::IDriverDependantBitmap *prepare_screen_for_transition_in(); // Screenshot made in the last room, used during some of the transition effects -extern AGS::Common::Bitmap *saved_viewport_bitmap; +extern AGS::Shared::Bitmap *saved_viewport_bitmap; } // namespace AGS3 diff --git a/engines/ags/engine/ac/screenoverlay.cpp b/engines/ags/engine/ac/screenoverlay.cpp index c90e3bc77e88..59926bbc8770 100644 --- a/engines/ags/engine/ac/screenoverlay.cpp +++ b/engines/ags/engine/ac/screenoverlay.cpp @@ -23,7 +23,7 @@ #include "screenoverlay.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; void ScreenOverlay::ReadFromFile(Stream *in, int32_t cmp_ver) { // Skipping bmp and pic pointer values diff --git a/engines/ags/engine/ac/screenoverlay.h b/engines/ags/engine/ac/screenoverlay.h index 59ed04a899e4..64a04906bfe0 100644 --- a/engines/ags/engine/ac/screenoverlay.h +++ b/engines/ags/engine/ac/screenoverlay.h @@ -29,7 +29,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Bitmap; class Stream; } // namespace Shared diff --git a/engines/ags/engine/ac/slider.h b/engines/ags/engine/ac/slider.h index 19858cecd32d..d5d8af96d49e 100644 --- a/engines/ags/engine/ac/slider.h +++ b/engines/ags/engine/ac/slider.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::GUISlider; +using AGS::Shared::GUISlider; void Slider_SetMax(GUISlider *guisl, int valn); int Slider_GetMax(GUISlider *guisl); diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp index c34bc4dfa99a..562b89719e66 100644 --- a/engines/ags/engine/ac/sprite.cpp +++ b/engines/ags/engine/ac/sprite.cpp @@ -32,7 +32,7 @@ #include "gfx/bitmap.h" #include "gfx/graphicsdriver.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/spritelistentry.h b/engines/ags/engine/ac/spritelistentry.h index 8f932743894b..cbf0a049be15 100644 --- a/engines/ags/engine/ac/spritelistentry.h +++ b/engines/ags/engine/ac/spritelistentry.h @@ -29,7 +29,7 @@ namespace AGS3 { struct SpriteListEntry { AGS::Engine::IDriverDependantBitmap *bmp; - AGS::Common::Bitmap *pic; + AGS::Shared::Bitmap *pic; int baseline; int x, y; int transparent; diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index 9c0d029b65f3..37306e004ab8 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -31,7 +31,7 @@ #include "platform/base/agsplatformdriver.h" #include "ac/timer.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index e4936cb9e39f..667c75e6b610 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -41,7 +41,7 @@ #include "media/audio/audio_system.h" #include "util/string_compat.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/textbox.h b/engines/ags/engine/ac/textbox.h index 8b2a1f23a37d..45271c0d6726 100644 --- a/engines/ags/engine/ac/textbox.h +++ b/engines/ags/engine/ac/textbox.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::GUITextBox; +using AGS::Shared::GUITextBox; const char *TextBox_GetText_New(GUITextBox *texbox); void TextBox_GetText(GUITextBox *texbox, char *buffer); diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp index 85e64f45abf8..c7b3df4a2816 100644 --- a/engines/ags/engine/ac/translation.cpp +++ b/engines/ags/engine/ac/translation.cpp @@ -36,7 +36,7 @@ #include "util/stream.h" #include "core/assetmanager.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern GameSetup usetup; extern GameSetupStruct game; diff --git a/engines/ags/engine/ac/translation.h b/engines/ags/engine/ac/translation.h index 4e5922b5755e..30e638befe6d 100644 --- a/engines/ags/engine/ac/translation.h +++ b/engines/ags/engine/ac/translation.h @@ -27,7 +27,7 @@ namespace AGS3 { -using AGS::Common::String; +using AGS::Shared::String; void close_translation(); bool init_translation(const String &lang, const String &fallback_lang, bool quit_on_error); diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp index 81605b5d0200..4d7f0543a294 100644 --- a/engines/ags/engine/ac/viewframe.cpp +++ b/engines/ags/engine/ac/viewframe.cpp @@ -31,8 +31,8 @@ #include "ac/game_version.h" #include "media/audio/audio_system.h" -using AGS::Common::Bitmap; -using AGS::Common::Graphics; +using AGS::Shared::Bitmap; +using AGS::Shared::Graphics; extern GameSetupStruct game; extern ViewStruct *views; diff --git a/engines/ags/engine/ac/viewframe.h b/engines/ags/engine/ac/viewframe.h index 2bd3049aa940..7e2c4edbf53f 100644 --- a/engines/ags/engine/ac/viewframe.h +++ b/engines/ags/engine/ac/viewframe.h @@ -32,7 +32,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Graphics; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp index ae83413e887e..b6fb314f5306 100644 --- a/engines/ags/engine/ac/viewport_script.cpp +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -35,7 +35,7 @@ #include "script/script_api.h" #include "script/script_runtime.h" -using namespace AGS::Common; +using namespace AGS::Shared; //============================================================================= // diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp index 8b16f635b843..d129b3e138f5 100644 --- a/engines/ags/engine/ac/walkablearea.cpp +++ b/engines/ags/engine/ac/walkablearea.cpp @@ -33,7 +33,7 @@ #include "game/roomstruct.h" #include "gfx/bitmap.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern RoomStruct thisroom; extern GameState play; diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp index ab1cc69554b1..7ad1b0e2ed91 100644 --- a/engines/ags/engine/ac/walkbehind.cpp +++ b/engines/ags/engine/ac/walkbehind.cpp @@ -27,7 +27,7 @@ #include "gfx/graphicsdriver.h" #include "gfx/bitmap.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern RoomStruct thisroom; diff --git a/engines/ags/engine/debugging/consoleoutputtarget.h b/engines/ags/engine/debugging/consoleoutputtarget.h index f35bec348836..7772d45de09a 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.h +++ b/engines/ags/engine/debugging/consoleoutputtarget.h @@ -39,7 +39,7 @@ namespace Engine { using Common::String; using Common::DebugMessage; -class ConsoleOutputTarget : public AGS::Common::IOutputHandler { +class ConsoleOutputTarget : public AGS::Shared::IOutputHandler { public: ConsoleOutputTarget(); virtual ~ConsoleOutputTarget(); diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index e180cad5c2ae..997add89efc5 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -48,7 +48,7 @@ #include #endif -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern char check_dynamic_sprites_at_exit; diff --git a/engines/ags/engine/debugging/debug_log.h b/engines/ags/engine/debugging/debug_log.h index ea0b9554275e..729fafabacc8 100644 --- a/engines/ags/engine/debugging/debug_log.h +++ b/engines/ags/engine/debugging/debug_log.h @@ -31,8 +31,8 @@ namespace AGS3 { -void init_debug(const AGS::Common::ConfigTree &cfg, bool stderr_only); -void apply_debug_config(const AGS::Common::ConfigTree &cfg); +void init_debug(const AGS::Shared::ConfigTree &cfg, bool stderr_only); +void apply_debug_config(const AGS::Shared::ConfigTree &cfg); void shutdown_debug(); void debug_set_console(bool enable); @@ -49,7 +49,7 @@ bool init_editor_debugging(); // allow LShift to single-step, RShift to pause flow void scriptDebugHook(ccInstance *ccinst, int linenum); -extern AGS::Common::String debug_line[DEBUG_CONSOLE_NUMLINES]; +extern AGS::Shared::String debug_line[DEBUG_CONSOLE_NUMLINES]; extern int first_debug_line, last_debug_line, display_console; diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h index 39450e988940..5f97124f5e7f 100644 --- a/engines/ags/engine/debugging/debugger.h +++ b/engines/ags/engine/debugging/debugger.h @@ -40,7 +40,7 @@ int check_for_messages_from_editor(); bool send_message_to_editor(const char *msg); bool send_exception_to_editor(const char *qmsg); // Returns current script's location and callstack -AGS::Common::String get_cur_script(int numberOfLinesOfCallStack); +AGS::Shared::String get_cur_script(int numberOfLinesOfCallStack); bool get_script_position(ScriptPosition &script_pos); void check_debug_keys(); diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.cpp b/engines/ags/engine/debugging/filebasedagsdebugger.cpp index 22d2ce218c38..a95700ba4ffb 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.cpp +++ b/engines/ags/engine/debugging/filebasedagsdebugger.cpp @@ -28,8 +28,8 @@ #include "util/wgt2allg.h" // exists() #include "platform/base/agsplatformdriver.h" -using AGS::Common::Stream; -using AGS::Common::TextStreamWriter; +using AGS::Shared::Stream; +using AGS::Shared::TextStreamWriter; const char *SENT_MESSAGE_FILE_NAME = "dbgrecv.tmp"; diff --git a/engines/ags/engine/debugging/logfile.cpp b/engines/ags/engine/debugging/logfile.cpp index 444b880bb3c5..ab1639991afb 100644 --- a/engines/ags/engine/debugging/logfile.cpp +++ b/engines/ags/engine/debugging/logfile.cpp @@ -29,7 +29,7 @@ namespace AGS { namespace Engine { -using namespace Common; +using namespace Shared; LogFile::LogFile() : _openMode(kLogFile_Overwrite) { diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h index 674a097e8ccf..45298067d103 100644 --- a/engines/ags/engine/debugging/logfile.h +++ b/engines/ags/engine/debugging/logfile.h @@ -41,7 +41,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared @@ -51,7 +51,7 @@ using Common::DebugMessage; using Common::Stream; using Common::String; -class LogFile : public AGS::Common::IOutputHandler { +class LogFile : public AGS::Shared::IOutputHandler { public: enum OpenMode { kLogFile_Overwrite, diff --git a/engines/ags/engine/debugging/messagebuffer.cpp b/engines/ags/engine/debugging/messagebuffer.cpp index 3ae8f427992a..3413aa5b261f 100644 --- a/engines/ags/engine/debugging/messagebuffer.cpp +++ b/engines/ags/engine/debugging/messagebuffer.cpp @@ -26,7 +26,7 @@ namespace AGS { namespace Engine { -using namespace Common; +using namespace Shared; MessageBuffer::MessageBuffer(size_t buffer_limit) : _bufferLimit(buffer_limit) diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h index f704af8fbe95..4c5d822e3ebf 100644 --- a/engines/ags/engine/debugging/messagebuffer.h +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -41,7 +41,7 @@ namespace Engine { using Common::String; using Common::DebugMessage; -class MessageBuffer : public AGS::Common::IOutputHandler { +class MessageBuffer : public AGS::Shared::IOutputHandler { public: MessageBuffer(size_t buffer_limit = 1024); diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index 66b0b147c373..d15a1335736a 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -60,7 +60,7 @@ #include "ac/sys_events.h" // j for ags_iskeypressed #endif -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h index d5f852eabcdb..128782ea0441 100644 --- a/engines/ags/engine/device/mousew32.h +++ b/engines/ags/engine/device/mousew32.h @@ -39,7 +39,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp index f2b37d1ac010..8ba060cfa691 100644 --- a/engines/ags/engine/game/game_init.cpp +++ b/engines/ags/engine/game/game_init.cpp @@ -51,7 +51,7 @@ #include "util/string_utils.h" #include "media/audio/audio_system.h" -using namespace Common; +using namespace Shared; using namespace Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/game/game_init.h b/engines/ags/engine/game/game_init.h index e1921006ef71..ec905d981edc 100644 --- a/engines/ags/engine/game/game_init.h +++ b/engines/ags/engine/game/game_init.h @@ -37,7 +37,7 @@ namespace AGS3 { namespace AGS { namespace Engine { -using namespace Common; +using namespace Shared; // Error codes for initializing the game enum GameInitErrorType { diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index fcafebf060df..693794a957a4 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -62,7 +62,7 @@ #include "util/string_utils.h" #include "media/audio/audio_system.h" -using namespace Common; +using namespace Shared; using namespace Engine; // function is currently implemented in game.cpp diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h index ac605a3ab134..1445d07907e2 100644 --- a/engines/ags/engine/game/savegame.h +++ b/engines/ags/engine/game/savegame.h @@ -31,7 +31,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; class Stream; } // namespace Shared diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index 8c69ecb3c8b3..b716e1db4d1c 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -60,7 +60,7 @@ #include "util/filestream.h" // TODO: needed only because plugins expect file handle #include "media/audio/audio_system.h" -using namespace Common; +using namespace Shared; extern GameSetupStruct game; extern color palette[256]; diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h index 32797df54df3..009516e50579 100644 --- a/engines/ags/engine/game/savegame_components.h +++ b/engines/ags/engine/game/savegame_components.h @@ -29,7 +29,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { struct Interaction; } // namespace Shared diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index e2dba2fedd38..11cdd707622b 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { namespace Engine { -using AGS::Common::Bitmap; +using AGS::Shared::Bitmap; typedef std::shared_ptr PBitmap; diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp index 30390da8e79d..6bb62c595231 100644 --- a/engines/ags/engine/game/viewport.cpp +++ b/engines/ags/engine/game/viewport.cpp @@ -26,7 +26,7 @@ #include "game/roomstruct.h" #include "game/viewport.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern RoomStruct thisroom; diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 68102c6b0ba3..406449cc23f4 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -124,7 +124,7 @@ namespace AGS { namespace Engine { namespace OGL { -using namespace AGS::Common; +using namespace AGS::Shared; void ogl_dummy_vsync() { } diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index c0f7836b05e8..3ade7458002c 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -60,7 +60,7 @@ namespace AGS { namespace Engine { namespace ALSW { -using namespace Common; +using namespace Shared; bool ALSoftwareGfxModeList::GetMode(int index, DisplayMode &mode) const { if (_gfxModeList && index >= 0 && index < _gfxModeList->num_modes) { diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index c38291382092..0788549a2d9f 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -52,7 +52,7 @@ namespace Engine { namespace ALSW { class AllegroGfxFilter; -using AGS::Common::Bitmap; +using AGS::Shared::Bitmap; class ALSoftwareBitmap : public IDriverDependantBitmap { public: diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp index 8fc9629b83d3..314c2c6d8a80 100644 --- a/engines/ags/engine/gfx/gfx_util.cpp +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -32,7 +32,7 @@ extern int psp_gfx_renderer; namespace AGS { namespace Engine { -using namespace Common; +using namespace Shared; namespace GfxUtil { diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index 2081c75be90d..1a10be6b83e3 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -27,7 +27,7 @@ #include "gfx/gfxdriverbase.h" #include "gfx/gfx_util.h" -using namespace AGS::Common; +using namespace AGS::Shared; namespace AGS { namespace Engine { diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index 47ac6efb2d20..94177683c219 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -26,7 +26,7 @@ namespace AGS { namespace Engine { namespace ALSW { -using namespace Common; +using namespace Shared; const GfxFilterInfo AllegroGfxFilter::FilterInfo = GfxFilterInfo("StdScale", "Nearest-neighbour"); diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp index 082fc906a7db..9bee9d28af3e 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.cpp +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -28,7 +28,7 @@ namespace AGS { namespace Engine { namespace ALSW { -using namespace Common; +using namespace Shared; const GfxFilterInfo HqxGfxFilter::FilterInfo = GfxFilterInfo("Hqx", "Hqx (High Quality)", 2, 3); diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h index 70c39574fb14..4af864a39bd8 100644 --- a/engines/ags/engine/gfx/graphicsdriver.h +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -37,10 +37,10 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; typedef std::shared_ptr PBitmap; -} // namespace Common +} // namespace Shared namespace Engine { diff --git a/engines/ags/engine/gui/animatingguibutton.cpp b/engines/ags/engine/gui/animatingguibutton.cpp index 68e7ad1f6697..a5fcb1aa0571 100644 --- a/engines/ags/engine/gui/animatingguibutton.cpp +++ b/engines/ags/engine/gui/animatingguibutton.cpp @@ -23,7 +23,7 @@ #include "gui/animatingguibutton.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; void AnimatingGUIButton::ReadFromFile(Stream *in) { buttonid = in->ReadInt16(); diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h index 0445f1c63655..f0610f8d62da 100644 --- a/engines/ags/engine/gui/animatingguibutton.h +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -29,7 +29,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } } diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index 6bd1de88943a..6c6cac7523d4 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -43,8 +43,8 @@ #include "platform/base/agsplatformdriver.h" #include "ac/timer.h" -using AGS::Common::Bitmap; -namespace BitmapHelper = AGS::Common::BitmapHelper; +using AGS::Shared::Bitmap; +namespace BitmapHelper = AGS::Shared::BitmapHelper; extern char ignore_bounds; // from mousew32 extern IGraphicsDriver *gfxDriver; diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp index 154db1160fdf..e19c753eeab8 100644 --- a/engines/ags/engine/gui/gui_engine.cpp +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -44,7 +44,7 @@ #include "gfx/bitmap.h" #include "gfx/blender.h" -using namespace AGS::Common; +using namespace AGS::Shared; // For engine these are defined in ac.cpp extern int eip_guiobj; @@ -109,7 +109,7 @@ int get_eip_guiobj() { bool outlineGuiObjects = false; namespace AGS { -namespace Common { +namespace Shared { bool GUIObject::IsClickable() const { return (Flags & kGUICtrl_Clickable) != 0; @@ -156,5 +156,5 @@ void GUIButton::PrepareTextToDraw() { _textToDraw = _text; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index dde29885dc92..cc9b7c977aae 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -34,7 +34,7 @@ #include "gfx/graphicsdriver.h" #include "debug/debug_log.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern IGraphicsDriver *gfxDriver; diff --git a/engines/ags/engine/gui/guidialog.h b/engines/ags/engine/gui/guidialog.h index 16bb1dedff65..dcca3af214a7 100644 --- a/engines/ags/engine/gui/guidialog.h +++ b/engines/ags/engine/gui/guidialog.h @@ -25,15 +25,15 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } } // Functions for handling hard-coded GUIs // Prepares GUI bitmaps which will be passed to the renderer's draw chain -AGS::Common::Bitmap *prepare_gui_screen(int x, int y, int width, int height, bool opaque); -AGS::Common::Bitmap *get_gui_screen(); +AGS::Shared::Bitmap *prepare_gui_screen(int x, int y, int width, int height, bool opaque); +AGS::Shared::Bitmap *get_gui_screen(); // Deletes GUI bitmaps void clear_gui_screen(); // Draws virtual screen contents on the GUI bitmaps and assignes them to diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h index e6054242009f..3b92cf62e8e9 100644 --- a/engines/ags/engine/gui/guidialogdefines.h +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -88,7 +88,7 @@ namespace AGS3 { #define CTB_KEYPRESS 91 namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } } diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp index 5068358f177c..ce173d589d14 100644 --- a/engines/ags/engine/gui/mylabel.cpp +++ b/engines/ags/engine/gui/mylabel.cpp @@ -29,7 +29,7 @@ #include "gui/mylabel.h" #include "gui/guidialoginternaldefs.h" -using namespace Common; +using namespace Shared; extern GameSetup usetup; diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index cee6e3bf1c12..95a1f2d2ee6a 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -30,7 +30,7 @@ #include "gui/guidialoginternaldefs.h" #include "gui/mylistbox.h" -using AGS::Common::Bitmap; +using AGS::Shared::Bitmap; extern GameSetup usetup; extern int numcurso, hotx, hoty; diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index f9432db1ac10..8aa7ff69db7a 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -33,7 +33,7 @@ #include "platform/base/agsplatformdriver.h" #include "ac/timer.h" -using AGS::Common::Bitmap; +using AGS::Shared::Bitmap; extern int windowbackgroundcolor, pushbuttondarkcolor; extern int pushbuttonlightcolor; diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp index 5f23f9fd54d2..fe545e917a3d 100644 --- a/engines/ags/engine/gui/mytextbox.cpp +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -27,7 +27,7 @@ #include "gui/guidialoginternaldefs.h" #include "gfx/bitmap.h" -using AGS::Common::Bitmap; +using AGS::Shared::Bitmap; extern GameSetup usetup; diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 54b76d84ca43..9a6c5e493697 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -46,7 +46,7 @@ #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; @@ -310,7 +310,7 @@ void read_game_data_location(const ConfigTree &cfg) { if (!usetup.data_files_dir.IsEmpty()) { // strip any trailing slash // TODO: move this to Path namespace later - AGS::Common::Path::FixupPath(usetup.data_files_dir); + AGS::Shared::Path::FixupPath(usetup.data_files_dir); #if AGS_PLATFORM_OS_WINDOWS // if the path is just x:\ don't strip the slash if (!(usetup.data_files_dir.GetLength() == 3 && usetup.data_files_dir[1u] == ':')) { diff --git a/engines/ags/engine/main/config.h b/engines/ags/engine/main/config.h index 528ce79582b2..62ff8c98fb3c 100644 --- a/engines/ags/engine/main/config.h +++ b/engines/ags/engine/main/config.h @@ -28,8 +28,8 @@ namespace AGS3 { -using AGS::Common::String; -using AGS::Common::ConfigTree; +using AGS::Shared::String; +using AGS::Shared::ConfigTree; // Set up default config settings void config_defaults(); @@ -40,7 +40,7 @@ String find_user_global_cfg_file(); // Find and game-specific user configuration file (located into writable user directory) String find_user_cfg_file(); // Read optional data file name and location from config -void read_game_data_location(const AGS::Common::ConfigTree &cfg); +void read_game_data_location(const AGS::Shared::ConfigTree &cfg); // Apply overriding values from the external config (e.g. for mobile ports) void override_config_ext(ConfigTree &cfg); // Setup game using final config tree diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 46ce312bd17f..89f3d3bf5820 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -79,7 +79,7 @@ #include "util/misc.h" #include "util/path.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern char check_dynamic_sprites_at_exit; diff --git a/engines/ags/engine/main/engine.h b/engines/ags/engine/main/engine.h index 1efa0ec072c3..d27e4fe89d02 100644 --- a/engines/ags/engine/main/engine.h +++ b/engines/ags/engine/main/engine.h @@ -31,7 +31,7 @@ const char *get_engine_name(); const char *get_engine_version(); void show_preload(); void engine_init_game_settings(); -int initialize_engine(const AGS::Common::ConfigTree &startup_opts); +int initialize_engine(const AGS::Shared::ConfigTree &startup_opts); struct ScreenSetup; // Try to set new graphics mode deduced from given configuration; @@ -44,7 +44,7 @@ bool engine_try_switch_windowed_gfxmode(); // Shutdown graphics mode (used before shutting down tha application) void engine_shutdown_gfxmode(); -using AGS::Common::String; +using AGS::Shared::String; // Defines a package file location struct PackLocation { String Name; // filename, for the reference or to use as an ID diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp index f29f5bb39965..22ae40663a79 100644 --- a/engines/ags/engine/main/engine_setup.cpp +++ b/engines/ags/engine/main/engine_setup.cpp @@ -44,7 +44,7 @@ #include "media/video/video.h" #include "platform/base/agsplatformdriver.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp index e97e63491066..857f80880a19 100644 --- a/engines/ags/engine/main/game_file.cpp +++ b/engines/ags/engine/main/game_file.cpp @@ -53,7 +53,7 @@ #include "plugin/agsplugin.h" #include "script/script.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern int ifacepopped; diff --git a/engines/ags/engine/main/game_file.h b/engines/ags/engine/main/game_file.h index f822ed0cfd67..d1487c9a648a 100644 --- a/engines/ags/engine/main/game_file.h +++ b/engines/ags/engine/main/game_file.h @@ -28,7 +28,7 @@ namespace AGS3 { -using AGS::Common::HError; +using AGS::Shared::HError; // Preload particular game-describing parameters from the game data header (title, save game dir name, etc) HError preload_game_data(); diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 589a6b78be13..1532bf611f80 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -66,7 +66,7 @@ #include "ac/timer.h" #include "ac/keycode.h" -using namespace AGS::Common; +using namespace AGS::Shared; extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; extern int numAnimButs; diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 0b4c609c6b3c..aad1e4319564 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -44,7 +44,7 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern int our_eip, displayed_room; diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp index c99ac6096ced..986b332414af 100644 --- a/engines/ags/engine/main/graphics_mode.cpp +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -45,7 +45,7 @@ #define USE_SIMPLE_GFX_INIT #endif -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern int proper_exit; diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h index facdea50d827..26c377f04f40 100644 --- a/engines/ags/engine/main/graphics_mode.h +++ b/engines/ags/engine/main/graphics_mode.h @@ -29,7 +29,7 @@ namespace AGS3 { -using AGS::Common::String; +using AGS::Shared::String; using AGS::Engine::DisplayMode; Size get_desktop_size(); diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp index 4ed51f38e02d..d41abba50624 100644 --- a/engines/ags/engine/main/main.cpp +++ b/engines/ags/engine/main/main.cpp @@ -63,7 +63,7 @@ #define USE_CUSTOM_EXCEPTION_HANDLER #endif -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; String appDirectory; // Needed for library loading @@ -140,11 +140,11 @@ void main_create_platform_driver() { #define SVG_VERSION_FWCOMPAT_REVISION 1111 // Current engine version -AGS::Common::Version EngineVersion; +AGS::Shared::Version EngineVersion; // Lowest savedgame version, accepted by this engine -AGS::Common::Version SavedgameLowestBackwardCompatVersion; +AGS::Shared::Version SavedgameLowestBackwardCompatVersion; // Lowest engine version, which would accept current savedgames -AGS::Common::Version SavedgameLowestForwardCompatVersion; +AGS::Shared::Version SavedgameLowestForwardCompatVersion; void main_init(int argc, char *argv[]) { EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index 1b15acafc236..a3da94db6ae1 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -29,22 +29,22 @@ namespace AGS3 { // Current engine version -extern AGS::Common::Version EngineVersion; +extern AGS::Shared::Version EngineVersion; // Lowest savedgame version, accepted by this engine -extern AGS::Common::Version SavedgameLowestBackwardCompatVersion; +extern AGS::Shared::Version SavedgameLowestBackwardCompatVersion; // Lowest engine version, which would accept current savedgames -extern AGS::Common::Version SavedgameLowestForwardCompatVersion; +extern AGS::Shared::Version SavedgameLowestForwardCompatVersion; //============================================================================= extern char **global_argv; // Location of the engine executable -extern AGS::Common::String appDirectory; +extern AGS::Shared::String appDirectory; // Game path from the startup options (before reading config) -extern AGS::Common::String cmdGameDataPath; +extern AGS::Shared::String cmdGameDataPath; -AGS::Common::String GetPathFromCmdArg(int arg_index); +AGS::Shared::String GetPathFromCmdArg(int arg_index); // Startup flags, set from parameters to engine extern int force_window; diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 45f7036d3b8f..5412b7d9a1bd 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -47,7 +47,7 @@ #include "plugin/plugin_engine.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp index 48ad214c2c17..54a54daff2b6 100644 --- a/engines/ags/engine/main/update.cpp +++ b/engines/ags/engine/main/update.cpp @@ -49,7 +49,7 @@ #include "main/game_run.h" #include "ac/movelist.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern MoveList *mls; diff --git a/engines/ags/engine/media/audio/ambientsound.cpp b/engines/ags/engine/media/audio/ambientsound.cpp index a2676a85c7ce..ce89b44cc1e9 100644 --- a/engines/ags/engine/media/audio/ambientsound.cpp +++ b/engines/ags/engine/media/audio/ambientsound.cpp @@ -25,7 +25,7 @@ #include "media/audio/soundclip.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; bool AmbientSound::IsPlaying() { if (channel <= 0) diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h index c0f06ca689bb..5c5d8955a084 100644 --- a/engines/ags/engine/media/audio/ambientsound.h +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -27,7 +27,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } } diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 12f818882451..ffc2ba392d41 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -47,7 +47,7 @@ #include "ac/timer.h" #include "main/game_run.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; //----------------------- diff --git a/engines/ags/engine/media/audio/queuedaudioitem.cpp b/engines/ags/engine/media/audio/queuedaudioitem.cpp index d2b93302406b..66be4bf249d7 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.cpp +++ b/engines/ags/engine/media/audio/queuedaudioitem.cpp @@ -24,7 +24,7 @@ #include "ac/common_defines.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; // [IKM] 2012-07-02: these functions are used during load/save game, // and read/written as-is, hence cachedClip pointer should be serialized diff --git a/engines/ags/engine/media/audio/queuedaudioitem.h b/engines/ags/engine/media/audio/queuedaudioitem.h index 99a917c99f23..14907e6559ae 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.h +++ b/engines/ags/engine/media/audio/queuedaudioitem.h @@ -28,7 +28,7 @@ namespace AGS3 { struct SOUNDCLIP; namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index fed227a0ffde..fdeae5cbded5 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -31,7 +31,7 @@ #include "util/string.h" #include "debug/out.h" -using namespace Common; +using namespace Shared; sound_cache_entry_t *sound_cache_entries = nullptr; unsigned int sound_cache_counter = 0; diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index e1930078d6db..b26b41321c1a 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -50,7 +50,7 @@ #include "util/stream.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp index 640691c5f87e..83d3136bdaae 100644 --- a/engines/ags/engine/platform/android/acpland.cpp +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -41,7 +41,7 @@ #include #include -using namespace AGS::Common; +using namespace AGS::Shared; #define ANDROID_CONFIG_FILENAME "android.cfg" diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index 3c64c6759ae3..79db1193d77c 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -38,7 +38,7 @@ #include "ac/timer.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; #if defined (AGS_HAS_CD_AUDIO) diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 360d3600df63..863af0f525ee 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -38,7 +38,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } namespace Engine { @@ -65,7 +65,7 @@ enum SetupReturnValue { struct AGSPlatformDriver // be used as a output target for logging system - : public AGS::Common::IOutputHandler { + : public AGS::Shared::IOutputHandler { virtual void AboutToQuitGame(); virtual void Delay(int millis); virtual void DisplayAlert(const char *, ...) = 0; @@ -178,7 +178,7 @@ struct AGSPlatformDriver // IOutputHandler implementation //----------------------------------------------- // Writes to the standard platform's output, prepending "AGS: " prefix to the message - void PrintMessage(const AGS::Common::DebugMessage &msg) override; + void PrintMessage(const AGS::Shared::DebugMessage &msg) override; protected: // TODO: this is a quick solution for IOutputHandler implementation diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp index 6d545dc316e7..672a3b1a2099 100644 --- a/engines/ags/engine/platform/ios/acplios.cpp +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -36,7 +36,7 @@ #include "plugin/agsplugin.h" #include "util/string_utils.h" -using namespace AGS::Common; +using namespace AGS::Shared; #define IOS_CONFIG_FILENAME "ios.cfg" diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 06491c2fa349..9c0ce818da8c 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -39,7 +39,7 @@ #include #include -using AGS::Common::String; +using AGS::Shared::String; // Replace the default Allegro icon. The original defintion is in the diff --git a/engines/ags/engine/platform/osx/acplmac.cpp b/engines/ags/engine/platform/osx/acplmac.cpp index 1fb3489c13b0..ef815cb945b1 100644 --- a/engines/ags/engine/platform/osx/acplmac.cpp +++ b/engines/ags/engine/platform/osx/acplmac.cpp @@ -70,7 +70,7 @@ AGSMac::AGSMac() { AGSMacInitPaths(psp_game_file_name, libraryApplicationSupport); snprintf(commonDataPath, PATH_MAX, "%s/uk.co.adventuregamestudio", libraryApplicationSupport); - AGS::Common::Directory::CreateDirectory(commonDataPath); + AGS::Shared::Directory::CreateDirectory(commonDataPath); strcpy(psp_translation, "default"); } diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index 0d330d595993..a0097e2793c2 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -55,7 +55,7 @@ extern void dxmedia_resume_video(); extern char lastError[200]; #endif -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; extern GameSetupStruct game; diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index 70d176d594e8..2cfa9e090906 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -50,7 +50,7 @@ extern int dxmedia_play_video_3d(const char *filename, IDirect3DDevice9 *device, extern void dxmedia_shutdown_3d(); #endif -using namespace AGS::Common; +using namespace AGS::Shared; // Necessary to update textures from 8-bit bitmaps extern RGB palette[256]; @@ -128,7 +128,7 @@ namespace AGS { namespace Engine { namespace D3D { -using namespace Common; +using namespace Shared; void D3DBitmap::Dispose() { if (_tiles != NULL) { diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index 4a75d322b4b6..2833ef7ae87e 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -52,8 +52,8 @@ namespace AGS { namespace Engine { namespace D3D { -using AGS::Common::Bitmap; -using AGS::Common::String; +using AGS::Shared::Bitmap; +using AGS::Shared::String; class D3DGfxFilter; struct D3DTextureTile : public TextureTile { diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp index 56e7f1fc7148..071b942b5f4f 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -47,7 +47,7 @@ #include "main/game_run.h" #include "platform/base/agsplatformdriver.h" -using namespace AGS::Common; +using namespace AGS::Shared; using namespace AGS::Engine; //link with the following libraries under project/settings/link... diff --git a/engines/ags/engine/platform/windows/setup/winsetup.cpp b/engines/ags/engine/platform/windows/setup/winsetup.cpp index bb9b49a4219d..87a434406721 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.cpp +++ b/engines/ags/engine/platform/windows/setup/winsetup.cpp @@ -68,7 +68,7 @@ extern "C" namespace AGS { namespace Engine { -using namespace AGS::Common; +using namespace AGS::Shared; //============================================================================= // diff --git a/engines/ags/engine/platform/windows/setup/winsetup.h b/engines/ags/engine/platform/windows/setup/winsetup.h index 87192595fd41..b07ec14fe799 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.h +++ b/engines/ags/engine/platform/windows/setup/winsetup.h @@ -36,7 +36,7 @@ namespace AGS3 { namespace AGS { namespace Engine { -using namespace Common; +using namespace Shared; void SetWinIcon(); SetupReturnValue WinSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index e27e30aaa037..7cf8f7688916 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -37,7 +37,7 @@ #define USE_CUSTOM_EXCEPTION_HANDLER #endif -using namespace AGS::Common; +using namespace AGS::Shared; extern int our_eip; extern int eip_guinum; @@ -66,7 +66,7 @@ static void DisplayException() { } int initialize_engine_with_exception_handling( - int (initialize_engine)(const AGS::Common::ConfigTree &startup_opts), + int (initialize_engine)(const AGS::Shared::ConfigTree &startup_opts), const ConfigTree &startup_opts) { __try { Debug::Printf(kDbgMsg_Info, "Installing exception handler"); diff --git a/engines/ags/engine/platform/windows/win_ex_handling.h b/engines/ags/engine/platform/windows/win_ex_handling.h index c77d4cbf8361..e1559a0bb6d9 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.h +++ b/engines/ags/engine/platform/windows/win_ex_handling.h @@ -29,8 +29,8 @@ namespace AGS3 { void setup_malloc_handling(); int initialize_engine_with_exception_handling( - int (initialize_engine)(const AGS::Common::ConfigTree &startup_opts), - const AGS::Common::ConfigTree &startup_opts); + int (initialize_engine)(const AGS::Shared::ConfigTree &startup_opts), + const AGS::Shared::ConfigTree &startup_opts); } // namespace AGS3 diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 82bcc771fa10..ee10afb53212 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -74,8 +74,8 @@ #include "util/filestream.h" #include "media/audio/audio_system.h" -using namespace AGS::Common; -using namespace AGS::Common::Memory; +using namespace AGS::Shared; +using namespace AGS::Shared::Memory; using namespace AGS::Engine; @@ -1010,7 +1010,7 @@ Engine::GameInitError pl_register_plugins(const std::vector String expect_filename = apl->library.GetFilenameForLib(apl->filename); if (apl->library.Load(apl->filename)) { - AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' loaded as '%s', resolving imports...", apl->filename, expect_filename.GetCStr()); + AGS::Shared::Debug::Printf(kDbgMsg_Info, "Plugin '%s' loaded as '%s', resolving imports...", apl->filename, expect_filename.GetCStr()); if (apl->library.GetFunctionAddress("AGS_PluginV2") == nullptr) { quitprintf("Plugin '%s' is an old incompatible version.", apl->filename); @@ -1025,16 +1025,16 @@ Engine::GameInitError pl_register_plugins(const std::vector apl->debugHook = (int(*)(const char *, int, int))apl->library.GetFunctionAddress("AGS_EngineDebugHook"); apl->initGfxHook = (void(*)(const char *, void *))apl->library.GetFunctionAddress("AGS_EngineInitGfx"); } else { - AGS::Common::Debug::Printf(kDbgMsg_Info, "Plugin '%s' could not be loaded (expected '%s'), trying built-in plugins...", + AGS::Shared::Debug::Printf(kDbgMsg_Info, "Plugin '%s' could not be loaded (expected '%s'), trying built-in plugins...", apl->filename, expect_filename.GetCStr()); if (pl_use_builtin_plugin(apl)) { - AGS::Common::Debug::Printf(kDbgMsg_Info, "Build-in plugin '%s' found and being used.", apl->filename); + AGS::Shared::Debug::Printf(kDbgMsg_Info, "Build-in plugin '%s' found and being used.", apl->filename); } else { // Plugin loading has failed at this point, try using built-in plugin function stubs if (RegisterPluginStubs((const char *)apl->filename)) - AGS::Common::Debug::Printf(kDbgMsg_Info, "Placeholder functions for the plugin '%s' found.", apl->filename); + AGS::Shared::Debug::Printf(kDbgMsg_Info, "Placeholder functions for the plugin '%s' found.", apl->filename); else - AGS::Common::Debug::Printf(kDbgMsg_Info, "No placeholder functions for the plugin '%s' found. The game might fail to load!", apl->filename); + AGS::Shared::Debug::Printf(kDbgMsg_Info, "No placeholder functions for the plugin '%s' found. The game might fail to load!", apl->filename); continue; } } diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/engine/plugin/plugin_engine.h index b988c7544c52..2c3e52aed4c7 100644 --- a/engines/ags/engine/plugin/plugin_engine.h +++ b/engines/ags/engine/plugin/plugin_engine.h @@ -39,7 +39,7 @@ namespace AGS3 { class IAGSEngine; namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS @@ -58,7 +58,7 @@ bool pl_is_plugin_loaded(const char *pl_name); //returns whether _any_ plugins want a particular event bool pl_any_want_hook(int event); -void pl_set_file_handle(long data, AGS::Common::Stream *stream); +void pl_set_file_handle(long data, AGS::Shared::Stream *stream); void pl_clear_file_handle(); } // namespace AGS3 diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index 9a7055135b10..88038dc3127f 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -46,8 +46,8 @@ #include "util/memory.h" #include "util/string_utils.h" // linux strnicmp definition -using namespace AGS::Common; -using namespace AGS::Common::Memory; +using namespace AGS::Shared; +using namespace AGS::Shared::Memory; extern ccInstance *loadedInstances[MAX_LOADED_INSTANCES]; // in script/script_runtime extern int gameHasBeenRestored; // in ac/game diff --git a/engines/ags/engine/script/runtimescriptvalue.cpp b/engines/ags/engine/script/runtimescriptvalue.cpp index dac99d5a09dc..ebcac94e8fbc 100644 --- a/engines/ags/engine/script/runtimescriptvalue.cpp +++ b/engines/ags/engine/script/runtimescriptvalue.cpp @@ -28,7 +28,7 @@ #include // for memcpy() -using namespace AGS::Common; +using namespace AGS::Shared; // // NOTE to future optimizers: I am using 'this' ptr here to better diff --git a/engines/ags/engine/script/runtimescriptvalue.h b/engines/ags/engine/script/runtimescriptvalue.h index f7840fdee3c8..41ae8a5f4010 100644 --- a/engines/ags/engine/script/runtimescriptvalue.h +++ b/engines/ags/engine/script/runtimescriptvalue.h @@ -307,7 +307,7 @@ struct RuntimeScriptValue { case kScValGlobalVar: { if (RValue->Type == kScValData) { - rval.SetInt32(AGS::Common::Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue)); + rval.SetInt32(AGS::Shared::Memory::ReadInt32LE(RValue->GetPtrWithOffset() + this->IValue)); } else { rval = *RValue; } diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp index 92c4a3a9433a..ec59cc6a778c 100644 --- a/engines/ags/engine/script/script.cpp +++ b/engines/ags/engine/script/script.cpp @@ -608,7 +608,7 @@ void quit_with_script_error(const char *functionName) { } int get_nivalue(InteractionCommandList *nic, int idx, int parm) { - if (nic->Cmds[idx].Data[parm].Type == AGS::Common::kInterValVariable) { + if (nic->Cmds[idx].Data[parm].Type == AGS::Shared::kInterValVariable) { // return the value of the variable return get_interaction_variable(nic->Cmds[idx].Data[parm].Value)->Value; } diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h index cdcababda4ea..c61f3a357dda 100644 --- a/engines/ags/engine/script/script.h +++ b/engines/ags/engine/script/script.h @@ -35,10 +35,10 @@ namespace AGS3 { -using AGS::Common::Interaction; -using AGS::Common::InteractionCommandList; -using AGS::Common::InteractionScripts; -using AGS::Common::InteractionVariable; +using AGS::Shared::Interaction; +using AGS::Shared::InteractionCommandList; +using AGS::Shared::InteractionScripts; +using AGS::Shared::InteractionVariable; #define LATE_REP_EXEC_ALWAYS_NAME "late_repeatedly_execute_always" #define REP_EXEC_ALWAYS_NAME "repeatedly_execute_always" @@ -67,7 +67,7 @@ int RunTextScript2IParam(ccInstance *sci, const char *tsname, const RuntimeS int PrepareTextScript(ccInstance *sci, const char **tsname); bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcToRun, bool hasTheFunc); -AGS::Common::String GetScriptName(ccInstance *sci); +AGS::Shared::String GetScriptName(ccInstance *sci); //============================================================================= @@ -119,9 +119,9 @@ extern int numScriptModules; // TODO: find out if these extra arrays are really necessary. This may be remains from the // time when the symbol import table was holding raw pointers to char array. -extern std::vector characterScriptObjNames; -extern AGS::Common::String objectScriptObjNames[MAX_ROOM_OBJECTS]; -extern std::vector guiScriptObjNames; +extern std::vector characterScriptObjNames; +extern AGS::Shared::String objectScriptObjNames[MAX_ROOM_OBJECTS]; +extern std::vector guiScriptObjNames; } // namespace AGS3 diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp index 99c01cd45a1d..411da69bb3c0 100644 --- a/engines/ags/engine/script/script_api.cpp +++ b/engines/ags/engine/script/script_api.cpp @@ -28,7 +28,7 @@ #include "script/script_api.h" #include "util/math.h" -namespace Math = AGS::Common::Math; +namespace Math = AGS::Shared::Math; enum FormatParseResult { kFormatParseNone, diff --git a/engines/ags/engine/script/script_engine.cpp b/engines/ags/engine/script/script_engine.cpp index c84c9546c042..3d22a27aad83 100644 --- a/engines/ags/engine/script/script_engine.cpp +++ b/engines/ags/engine/script/script_engine.cpp @@ -38,11 +38,11 @@ #include "util/stream.h" namespace AGS { -namespace Common { +namespace Shared { class RoomStruct; } } -using namespace AGS::Common; +using namespace AGS::Shared; extern void quit(const char *); extern int currentline; // in script/script_common diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h index 31e99850a488..059f0dd6c5d6 100644 --- a/engines/ags/engine/script/script_runtime.h +++ b/engines/ags/engine/script/script_runtime.h @@ -46,8 +46,8 @@ struct ICCStaticObject; struct ICCDynamicObject; struct StaticArray; -using AGS::Common::String; -using AGS::Common::String; +using AGS::Shared::String; +using AGS::Shared::String; // ************ SCRIPT LOADING AND RUNNING FUNCTIONS ************ diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index ab3c717ddbcf..aef575091dfb 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -31,7 +31,7 @@ namespace AGS3 { struct ICCDynamicObject; struct ICCStaticObject; -using AGS::Common::String; +using AGS::Shared::String; struct ScriptImport { ScriptImport() { diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h index 8c726c5571f8..4745bf1b43f4 100644 --- a/engines/ags/engine/util/library.h +++ b/engines/ags/engine/util/library.h @@ -36,13 +36,13 @@ class BaseLibrary { virtual ~BaseLibrary() = default; - virtual AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) = 0; + virtual AGS::Shared::String GetFilenameForLib(AGS::Shared::String libraryName) = 0; - virtual bool Load(AGS::Common::String libraryName) = 0; + virtual bool Load(AGS::Shared::String libraryName) = 0; virtual bool Unload() = 0; - virtual void *GetFunctionAddress(AGS::Common::String functionName) = 0; + virtual void *GetFunctionAddress(AGS::Shared::String functionName) = 0; }; diff --git a/engines/ags/engine/util/library_dummy.h b/engines/ags/engine/util/library_dummy.h index 732c474e651b..0972228b304d 100644 --- a/engines/ags/engine/util/library_dummy.h +++ b/engines/ags/engine/util/library_dummy.h @@ -35,11 +35,11 @@ class DummyLibrary : BaseLibrary { ~DummyLibrary() override { }; - AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override { + AGS::Shared::String GetFilenameForLib(AGS::Shared::String libraryName) override { return libraryName; } - bool Load(AGS::Common::String libraryName) override { + bool Load(AGS::Shared::String libraryName) override { return false; } @@ -47,7 +47,7 @@ class DummyLibrary : BaseLibrary { return true; } - void *GetFunctionAddress(AGS::Common::String functionName) override { + void *GetFunctionAddress(AGS::Shared::String functionName) override { return NULL; } }; diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index 89e8e4e1ce5a..40220c6c8f78 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -34,7 +34,7 @@ namespace AGS3 { #if AGS_PLATFORM_OS_ANDROID extern char android_app_directory[256]; #else -extern AGS::Common::String appDirectory; +extern AGS::Shared::String appDirectory; #endif @@ -52,7 +52,7 @@ class PosixLibrary : BaseLibrary { Unload(); }; - AGS::Common::String BuildFilename(AGS::Common::String libraryName) { + AGS::Shared::String BuildFilename(AGS::Shared::String libraryName) { return String::FromFormat( #if AGS_PLATFORM_OS_MACOS "lib%s.dylib" @@ -62,28 +62,28 @@ class PosixLibrary : BaseLibrary { , libraryName.GetCStr()); } - AGS::Common::String BuildPath(const char *path, AGS::Common::String libraryName) { - AGS::Common::String platformLibraryName = ""; + AGS::Shared::String BuildPath(const char *path, AGS::Shared::String libraryName) { + AGS::Shared::String platformLibraryName = ""; if (path) { platformLibraryName = path; platformLibraryName.Append("/"); } platformLibraryName.Append(BuildFilename(libraryName)); - AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + AGS::Shared::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); return platformLibraryName; } - AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override { + AGS::Shared::String GetFilenameForLib(AGS::Shared::String libraryName) override { return BuildFilename(libraryName); } - bool Load(AGS::Common::String libraryName) override { + bool Load(AGS::Shared::String libraryName) override { Unload(); // Try rpath first _library = dlopen(BuildPath(nullptr, libraryName).GetCStr(), RTLD_LAZY); - AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + AGS::Shared::Debug::Printf("dlopen returned: %s", dlerror()); if (_library != nullptr) { return true; } @@ -91,7 +91,7 @@ class PosixLibrary : BaseLibrary { // Try current path _library = dlopen(BuildPath(".", libraryName).GetCStr(), RTLD_LAZY); - AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + AGS::Shared::Debug::Printf("dlopen returned: %s", dlerror()); if (_library == nullptr) { // Try the engine directory @@ -104,7 +104,7 @@ class PosixLibrary : BaseLibrary { _library = dlopen(BuildPath(appDirectory, libraryName).GetCStr(), RTLD_LAZY); #endif - AGS::Common::Debug::Printf("dlopen returned: %s", dlerror()); + AGS::Shared::Debug::Printf("dlopen returned: %s", dlerror()); } return (_library != nullptr); @@ -118,7 +118,7 @@ class PosixLibrary : BaseLibrary { } } - void *GetFunctionAddress(AGS::Common::String functionName) override { + void *GetFunctionAddress(AGS::Shared::String functionName) override { if (_library) { return dlsym(_library, functionName.GetCStr()); } else { diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h index 7d40b01d1d11..b8098bbabc54 100644 --- a/engines/ags/engine/util/library_psp.h +++ b/engines/ags/engine/util/library_psp.h @@ -41,17 +41,17 @@ class PSPLibrary : BaseLibrary { Unload(); }; - AGS::Common::String BuildPath(char *path, AGS::Common::String libraryName) { - AGS::Common::String platformLibraryName = path; + AGS::Shared::String BuildPath(char *path, AGS::Shared::String libraryName) { + AGS::Shared::String platformLibraryName = path; platformLibraryName.Append(libraryName); platformLibraryName.Append(".prx"); - AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + AGS::Shared::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); return platformLibraryName; } - bool Load(AGS::Common::String libraryName) { + bool Load(AGS::Shared::String libraryName) { Unload(); // Try current path @@ -66,7 +66,7 @@ class PSPLibrary : BaseLibrary { _moduleName = libraryName; _moduleName.MakeLower(); - AGS::Common::Debug::Printf("Result is %s %d", _moduleName.GetCStr(), _library); + AGS::Shared::Debug::Printf("Result is %s %d", _moduleName.GetCStr(), _library); return (_library > -1); } @@ -79,7 +79,7 @@ class PSPLibrary : BaseLibrary { } } - void *GetFunctionAddress(AGS::Common::String functionName) { + void *GetFunctionAddress(AGS::Shared::String functionName) { if (_library > -1) { // On the PSP functions are identified by an ID that is the first 4 byte of the SHA1 of the name. int functionId; @@ -99,7 +99,7 @@ class PSPLibrary : BaseLibrary { } else if (functionName == "AGS_EngineInitGfx") { functionId = 0xA428D254; } else { - AGS::Common::Debug::Printf("Function ID not found: %s", functionName.GetCStr()); + AGS::Shared::Debug::Printf("Function ID not found: %s", functionName.GetCStr()); functionId = -1; } #else @@ -121,7 +121,7 @@ class PSPLibrary : BaseLibrary { private: SceUID _library; - AGS::Common::String _moduleName; + AGS::Shared::String _moduleName; }; diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h index 64882535e901..7695c93fd95c 100644 --- a/engines/ags/engine/util/library_windows.h +++ b/engines/ags/engine/util/library_windows.h @@ -58,23 +58,23 @@ class WindowsLibrary : BaseLibrary { Unload(); }; - AGS::Common::String BuildFilename(AGS::Common::String libraryName) { + AGS::Shared::String BuildFilename(AGS::Shared::String libraryName) { return String::FromFormat("%s.dll", libraryName.GetCStr()); } - AGS::Common::String BuildPath(AGS::Common::String libraryName) { - AGS::Common::String platformLibraryName = BuildFilename(libraryName); + AGS::Shared::String BuildPath(AGS::Shared::String libraryName) { + AGS::Shared::String platformLibraryName = BuildFilename(libraryName); - AGS::Common::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); + AGS::Shared::Debug::Printf("Built library path: %s", platformLibraryName.GetCStr()); return platformLibraryName; } - AGS::Common::String GetFilenameForLib(AGS::Common::String libraryName) override { + AGS::Shared::String GetFilenameForLib(AGS::Shared::String libraryName) override { return BuildFilename(libraryName); } - bool Load(AGS::Common::String libraryName) { + bool Load(AGS::Shared::String libraryName) { Unload(); _library = LoadLibraryA(BuildPath(libraryName).GetCStr()); @@ -90,7 +90,7 @@ class WindowsLibrary : BaseLibrary { } } - void *GetFunctionAddress(AGS::Common::String functionName) { + void *GetFunctionAddress(AGS::Shared::String functionName) { return GetProcAddress(_library, functionName.GetCStr()); } diff --git a/engines/ags/engine/util/mutex_base.h b/engines/ags/engine/util/mutex_base.h index 2344dd006d5c..5c5339cf305c 100644 --- a/engines/ags/engine/util/mutex_base.h +++ b/engines/ags/engine/util/mutex_base.h @@ -25,7 +25,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class BaseMutex { public: @@ -35,7 +35,7 @@ class BaseMutex { virtual void Unlock() = 0; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/ac/audiocliptype.cpp b/engines/ags/shared/ac/audiocliptype.cpp index d33ccfad84b5..f668c6b40b37 100644 --- a/engines/ags/shared/ac/audiocliptype.cpp +++ b/engines/ags/shared/ac/audiocliptype.cpp @@ -23,7 +23,7 @@ #include "ac/audiocliptype.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; void AudioClipType::ReadFromFile(Stream *in) { id = in->ReadInt32(); diff --git a/engines/ags/shared/ac/audiocliptype.h b/engines/ags/shared/ac/audiocliptype.h index 9123a56c7232..9871c5e29441 100644 --- a/engines/ags/shared/ac/audiocliptype.h +++ b/engines/ags/shared/ac/audiocliptype.h @@ -27,7 +27,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/ac/characterinfo.cpp b/engines/ags/shared/ac/characterinfo.cpp index 9ec843cf6c75..6a3deb6a73f6 100644 --- a/engines/ags/shared/ac/characterinfo.cpp +++ b/engines/ags/shared/ac/characterinfo.cpp @@ -24,7 +24,7 @@ #include "ac/characterinfo.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; void CharacterInfo::ReadFromFile(Stream *in) { diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h index 2649887f8595..4a448299ff4f 100644 --- a/engines/ags/shared/ac/characterinfo.h +++ b/engines/ags/shared/ac/characterinfo.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index d7a2b148a353..156703bf19c7 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -23,7 +23,7 @@ #include "ac/common.h" #include "util/string.h" -using namespace AGS::Common; +using namespace AGS::Shared; const char *game_file_sig = "Adventure Creator Game File v2"; diff --git a/engines/ags/shared/ac/dialogtopic.cpp b/engines/ags/shared/ac/dialogtopic.cpp index 7ae5189ddf0e..f4ffdc0797ba 100644 --- a/engines/ags/shared/ac/dialogtopic.cpp +++ b/engines/ags/shared/ac/dialogtopic.cpp @@ -23,7 +23,7 @@ #include "ac/dialogtopic.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; void DialogTopic::ReadFromFile(Stream *in) { in->ReadArray(optionnames, 150 * sizeof(char), MAXTOPICOPTIONS); diff --git a/engines/ags/shared/ac/dialogtopic.h b/engines/ags/shared/ac/dialogtopic.h index 87502041be3d..e23d534f0fe2 100644 --- a/engines/ags/shared/ac/dialogtopic.h +++ b/engines/ags/shared/ac/dialogtopic.h @@ -26,7 +26,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp index e858f0d63f43..a2b90d6f7ba5 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp @@ -23,7 +23,7 @@ #include "ac/dynobj/scriptaudioclip.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; void ScriptAudioClip::ReadFromFile(Stream *in) { id = in->ReadInt32(); diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index be246866fa99..7167a38d4fd7 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp index 872c7c933d5c..e94ac5e4164b 100644 --- a/engines/ags/shared/ac/gamesetupstruct.cpp +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -28,7 +28,7 @@ #include "game/interactions.h" #include "util/alignedstream.h" -using namespace AGS::Common; +using namespace AGS::Shared; GameSetupStruct::GameSetupStruct() : filever(0) diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index 21e252c3b4d5..951bcfbf4719 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -39,15 +39,15 @@ namespace AGS { namespace Common { struct AssetLibInfo; struct Interaction; -struct InteractionScripts; +namespace SharedonScripts; typedef std::shared_ptr PInteraction; typedef std::shared_ptr PInteractionScripts; } // namespace Shared } // namespace AGS -using AGS::Common::PInteraction; -using AGS::Common::PInteractionScripts; -using AGS::Common::HGameFileError; +using AGS::Shared::PInteraction; +using AGS::Shared::PInteractionScripts; +using AGS::Shared::HGameFileError; struct OldGameSetupStruct; @@ -68,9 +68,9 @@ struct GameSetupStruct : public GameSetupStructBase { int filever; // just used by editor Common::String compiled_with; // version of AGS this data was created by char lipSyncFrameLetters[MAXLIPSYNCFRAMES][50]; - AGS::Common::PropertySchema propSchema; - std::vector charProps; - AGS::Common::StringIMap invProps[MAX_INV]; + AGS::Shared::PropertySchema propSchema; + std::vector charProps; + AGS::Shared::StringIMap invProps[MAX_INV]; // NOTE: although the view names are stored in game data, they are never // used, nor registered as script exports; numeric IDs are used to // reference views instead. diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp index 810697592d74..cd1caef3605b 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.cpp +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -27,7 +27,7 @@ #include "script/cc_script.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; GameSetupStructBase::GameSetupStructBase() : numviews(0) diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h index 7edfbbad0134..fc9ee3cbfd69 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.h +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -32,7 +32,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS @@ -214,7 +214,7 @@ struct GameSetupStructBase { } // Returns the expected filename of a digital audio package - inline AGS::Common::String GetAudioVOXName() const { + inline AGS::Shared::String GetAudioVOXName() const { return IsLegacyAudioSystem() ? "music.vox" : "audio.vox"; } diff --git a/engines/ags/shared/ac/inventoryiteminfo.cpp b/engines/ags/shared/ac/inventoryiteminfo.cpp index 89f9d1784225..0a34dbaa8fbe 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.cpp +++ b/engines/ags/shared/ac/inventoryiteminfo.cpp @@ -24,7 +24,7 @@ #include "util/stream.h" #include "util/string_utils.h" -using namespace AGS::Common; +using namespace AGS::Shared; void InventoryItemInfo::ReadFromFile(Stream *in) { in->Read(name, 25); diff --git a/engines/ags/shared/ac/inventoryiteminfo.h b/engines/ags/shared/ac/inventoryiteminfo.h index 29adfffaffb8..e3f1ab577965 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.h +++ b/engines/ags/shared/ac/inventoryiteminfo.h @@ -26,7 +26,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/ac/mousecursor.cpp b/engines/ags/shared/ac/mousecursor.cpp index 2f5e4d80d29c..86548b29721c 100644 --- a/engines/ags/shared/ac/mousecursor.cpp +++ b/engines/ags/shared/ac/mousecursor.cpp @@ -23,7 +23,7 @@ #include "ac/mousecursor.h" #include "util/stream.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; MouseCursor::MouseCursor() { pic = 2054; diff --git a/engines/ags/shared/ac/mousecursor.h b/engines/ags/shared/ac/mousecursor.h index 2ebaebe9cad6..7ae0ef406d3b 100644 --- a/engines/ags/shared/ac/mousecursor.h +++ b/engines/ags/shared/ac/mousecursor.h @@ -29,7 +29,7 @@ namespace AGS { namespace Common { class Stream; } // namespace Shared -} // namespace AGS +namespace SharedGS using namespace AGS; // FIXME later diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp index 79d79f713bce..178d9ebf655a 100644 --- a/engines/ags/shared/ac/spritecache.cpp +++ b/engines/ags/shared/ac/spritecache.cpp @@ -42,7 +42,7 @@ #include "util/file.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; // [IKM] We have to forward-declare these because their implementations are in the Engine extern void initialize_sprite(int); @@ -732,7 +732,7 @@ HError SpriteCache::InitFile(const char *filename, const char *sprindex_filename return RebuildSpriteIndex(_stream.get(), topmost, vers); } -HError SpriteCache::RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers) { +HError SpriteCache::RebuildSpriteIndex(AGS::Shared::Stream *in, sprkey_t topmost, SpriteFileVersion vers) { for (sprkey_t i = 0; i <= topmost; ++i) { _spriteData[i].Offset = in->GetPosition(); _spriteData[i].Flags = 0; diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index 2d8a5a5eaa4e..d7a2eb3593be 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -53,14 +53,14 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; class Bitmap; } // namespace Shared } // namespace AGS using namespace AGS; // FIXME later -typedef AGS::Common::HError HAGSError; +typedef AGS::Shared::HError HAGSError; struct SpriteInfo; @@ -238,7 +238,7 @@ class SpriteCache { // Loads sprite index file bool LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost); // Rebuilds sprite index from the main sprite file - HAGSError RebuildSpriteIndex(AGS::Common::Stream *in, sprkey_t topmost, SpriteFileVersion vers); + HAGSError RebuildSpriteIndex(AGS::Shared::Stream *in, sprkey_t topmost, SpriteFileVersion vers); // Writes compressed sprite to the stream void CompressSprite(Common::Bitmap *sprite, Common::Stream *out); // Uncompresses sprite from stream into the given bitmap diff --git a/engines/ags/shared/ac/view.cpp b/engines/ags/shared/ac/view.cpp index c464989f554a..e6299ebf5485 100644 --- a/engines/ags/shared/ac/view.cpp +++ b/engines/ags/shared/ac/view.cpp @@ -24,8 +24,8 @@ #include "ac/view.h" #include "util/alignedstream.h" -using AGS::Common::AlignedStream; -using AGS::Common::Stream; +using AGS::Shared::AlignedStream; +using AGS::Shared::Stream; ViewFrame::ViewFrame() : pic(0) diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index 3fa144444dbe..f8dc1fc0e59d 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp index 362179481962..2cddfd73b54a 100644 --- a/engines/ags/shared/ac/wordsdictionary.cpp +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -26,7 +26,7 @@ #include "util/stream.h" #include "util/string_compat.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; WordsDictionary::WordsDictionary() : num_words(0) diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h index ea2fe999082d..fba3277de8f1 100644 --- a/engines/ags/shared/ac/wordsdictionary.h +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/api/stream_api.h b/engines/ags/shared/api/stream_api.h index 738765a513d4..9bd209b434ff 100644 --- a/engines/ags/shared/api/stream_api.h +++ b/engines/ags/shared/api/stream_api.h @@ -40,7 +40,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { enum StreamSeek { kSeekBegin, @@ -92,7 +92,7 @@ class IAGSStream { virtual bool Seek(soff_t offset, StreamSeek origin = kSeekCurrent) = 0; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/core/asset.cpp b/engines/ags/shared/core/asset.cpp index 24f988be4403..ce99ec561521 100644 --- a/engines/ags/shared/core/asset.cpp +++ b/engines/ags/shared/core/asset.cpp @@ -23,7 +23,7 @@ #include "core/asset.h" namespace AGS { -namespace Common { +namespace Shared { AssetInfo::AssetInfo() : LibUid(0) @@ -37,5 +37,5 @@ void AssetLibInfo::Unload() { AssetInfos.clear(); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index 0a8f7c4c2c9d..a531f8c94ede 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -34,7 +34,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // Information on single asset struct AssetInfo { @@ -61,7 +61,7 @@ struct AssetLibInfo { void Unload(); }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp index de80f63d5ee7..1fe72e47975b 100644 --- a/engines/ags/shared/core/assetmanager.cpp +++ b/engines/ags/shared/core/assetmanager.cpp @@ -28,7 +28,7 @@ namespace AGS { -namespace Common { +namespace Shared { AssetLocation::AssetLocation() : Offset(0) @@ -367,5 +367,5 @@ String GetAssetErrorText(AssetError err) { return "Unknown error."; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h index d2937b661b16..bf942bdfa058 100644 --- a/engines/ags/shared/core/assetmanager.h +++ b/engines/ags/shared/core/assetmanager.h @@ -48,7 +48,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; struct MultiFileLib; @@ -154,7 +154,7 @@ class AssetManager { String GetAssetErrorText(AssetError err); -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp index afddfdee2f8e..180e06c97f68 100644 --- a/engines/ags/shared/debugging/debugmanager.cpp +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -25,7 +25,7 @@ #include "util/string_types.h" namespace AGS { -namespace Common { +namespace Shared { DebugOutput::DebugOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity, bool enabled) : _id(id) @@ -224,5 +224,5 @@ void Printf(DebugGroupID group, MessageType mt, const char *fmt, ...) { } // namespace Debug -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index 21e733206b15..83903112577a 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -56,7 +56,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // DebugGroup is a message sender definition, identified by DebugGroupID // and providing OutputName that could be used when printing its messages. @@ -165,7 +165,7 @@ class DebugManager { // TODO: move this to the dynamically allocated engine object whenever it is implemented extern DebugManager DbgMgr; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h index 2d7efa27fdfa..c25eb655a09b 100644 --- a/engines/ags/shared/debugging/out.h +++ b/engines/ags/shared/debugging/out.h @@ -81,7 +81,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // Message types provide distinction for debug messages by their intent. enum MessageType { @@ -161,7 +161,7 @@ void Printf(DebugGroupID group_id, MessageType mt, const char *fmt, ...); } // namespace Debug -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h index 86ddc57fe606..9d071b175572 100644 --- a/engines/ags/shared/debugging/outputhandler.h +++ b/engines/ags/shared/debugging/outputhandler.h @@ -39,7 +39,7 @@ namespace Common { struct DebugMessage { String Text; - uint32_t GroupID; +namespace SharedoupID; String GroupName; MessageType MT; diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 0763bad8c651..77493dd202d3 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -34,10 +34,10 @@ #define STD_BUFFER_SIZE 3000 -using namespace AGS::Common; +using namespace AGS::Shared; namespace AGS { -namespace Common { +namespace Shared { struct Font { IAGSFontRenderer *Renderer; @@ -189,7 +189,7 @@ bool use_default_linespacing(size_t fontNumber) { extern int wgettextwidth_compensate(const char *tex, int font); namespace AGS { -namespace Common { +namespace Shared { SplitLines Lines; } } diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index 37586eba6862..29a8b35e9494 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { namespace Common { class Bitmap; -} // namespace Shared +namespace Sharedhared } // namespace AGS using namespace AGS; @@ -133,7 +133,7 @@ size_t split_lines(const char *texx, SplitLines &lines, int width, int fontNumbe namespace AGS { namespace Common { extern SplitLines Lines; -} // namespace Shared +namespace Sharedhared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp index 54d32ffb09c9..73ec388d239e 100644 --- a/engines/ags/shared/font/ttffontrenderer.cpp +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -34,7 +34,7 @@ #include "font/fonts.h" #endif -using namespace AGS::Common; +using namespace AGS::Shared; // project-specific implementation extern bool ShouldAntiAliasText(); diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index 6825805b4e11..b891aff8cfc1 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -26,7 +26,7 @@ #include "util/memory.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; static const char *WFN_FILE_SIGNATURE = "WGT Font File "; static const size_t WFN_FILE_SIG_LENGTH = 15; diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index ebfb0a4ba03b..6abe424268c3 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -52,7 +52,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS @@ -98,7 +98,7 @@ class WFNFont { void Clear(); // Reads WFNFont object, using data_size bytes from stream; if data_size = 0, // the available stream's length is used instead. Returns error code. - WFNError ReadFromFile(AGS::Common::Stream *in, const soff_t data_size = 0); + WFNError ReadFromFile(AGS::Shared::Stream *in, const soff_t data_size = 0); protected: std::vector _refs; // reference array, contains pointers to elements of _items diff --git a/engines/ags/shared/font/wfnfontrenderer.cpp b/engines/ags/shared/font/wfnfontrenderer.cpp index 3db79fe0ee31..559e88a2e41b 100644 --- a/engines/ags/shared/font/wfnfontrenderer.cpp +++ b/engines/ags/shared/font/wfnfontrenderer.cpp @@ -28,7 +28,7 @@ #include "gfx/bitmap.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; static unsigned char GetCharCode(unsigned char wanted_code, const WFNFont *font) { return wanted_code < font->GetCharCount() ? wanted_code : '?'; diff --git a/engines/ags/shared/game/customproperties.cpp b/engines/ags/shared/game/customproperties.cpp index 61232af84cea..96440c7739cc 100644 --- a/engines/ags/shared/game/customproperties.cpp +++ b/engines/ags/shared/game/customproperties.cpp @@ -25,7 +25,7 @@ #include "util/string_utils.h" namespace AGS { -namespace Common { +namespace Shared { PropertyDesc::PropertyDesc() { Type = kPropertyBoolean; @@ -117,5 +117,5 @@ void WriteValues(const StringIMap &map, Stream *out) { } // namespace Properties -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index cd36b985a090..7908829e2d2b 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -52,7 +52,7 @@ namespace AGS3 { #define LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH 500 namespace AGS { -namespace Common { +namespace Shared { enum PropertyVersion { kPropertyVersion_Initial = 1, @@ -102,7 +102,7 @@ void WriteValues(const StringIMap &map, Stream *out); } // namespace Properties -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/game/interactions.cpp b/engines/ags/shared/game/interactions.cpp index 7b8c2508c603..6c53f14a00de 100644 --- a/engines/ags/shared/game/interactions.cpp +++ b/engines/ags/shared/game/interactions.cpp @@ -26,13 +26,13 @@ #include "util/alignedstream.h" #include "util/math.h" -using namespace AGS::Common; +using namespace AGS::Shared; InteractionVariable globalvars[MAX_GLOBAL_VARIABLES] = {InteractionVariable("Global 1", 0, 0)}; int numGlobalVars = 1; namespace AGS { -namespace Common { +namespace Shared { InteractionValue::InteractionValue() { Type = kInterValLiteralInt; @@ -372,5 +372,5 @@ InteractionScripts *InteractionScripts::CreateFromStream(Stream *in) { return scripts; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index 02b440f39366..c325ee6ebd08 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -61,7 +61,7 @@ namespace AGS3 { #define MAX_COMMANDS_PER_LIST 40 namespace AGS { -namespace Common { +namespace Shared { enum InterValType { kInterValLiteralInt = 1, @@ -204,11 +204,11 @@ struct InteractionScripts { typedef std::shared_ptr PInteractionScripts; -} // namespace Common +} // namespace Shared } // namespace AGS // Legacy global variables -extern AGS::Common::InteractionVariable globalvars[MAX_GLOBAL_VARIABLES]; +extern AGS::Shared::InteractionVariable globalvars[MAX_GLOBAL_VARIABLES]; extern int numGlobalVars; } // namespace AGS3 diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 48dd4a26c9cc..f02e9c10f17f 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -40,7 +40,7 @@ #include "font/fonts.h" namespace AGS { -namespace Common { +namespace Shared { const String MainGameSource::DefaultFilename_v3 = "game28.dta"; const String MainGameSource::DefaultFilename_v2 = "ac2game.dta"; @@ -733,5 +733,5 @@ HGameFileError UpdateGameData(LoadedGameEntities &ents, GameDataVersion data_ver return HGameFileError::None(); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 86fd9241a97c..8bb36b7ff0d5 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -49,7 +49,7 @@ struct DialogTopic; struct ViewStruct; namespace AGS { -namespace Common { +namespace Shared { // Error codes for main game file reading enum MainGameFileErrorType { @@ -148,7 +148,7 @@ HGameFileError UpdateGameData(LoadedGameEntities &ents, GameDataVersion data // Ensures that the game saves directory path is valid void FixupSaveDirectory(GameSetupStruct &game); -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index a368913e91ca..eac9f6e072d1 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -38,7 +38,7 @@ namespace AGS3 { #define PLUGIN_SAVEBUFFERSIZE 10247680 namespace AGS { -namespace Common { +namespace Shared { struct PluginInfo { // (File)name of plugin @@ -51,7 +51,7 @@ struct PluginInfo { } }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index c2c3996c8bf9..ce69890ed481 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -45,7 +45,7 @@ #define LEGACY_TINT_IS_ENABLED 0x80000000 namespace AGS { -namespace Common { +namespace Shared { RoomDataSource::RoomDataSource() : DataVersion(kRoomVersion_Undefined) { @@ -881,5 +881,5 @@ HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersio return HRoomFileError::None(); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index be91dbc51947..6276cb352afa 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -42,7 +42,7 @@ namespace AGS3 { struct SpriteInfo; namespace AGS { -namespace Common { +namespace Shared { class RoomStruct; @@ -94,7 +94,7 @@ HRoomFileError ExtractScriptText(String &script, Stream *in, RoomFileVersion dat HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersion data_ver); -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/game/room_file_deprecated.cpp b/engines/ags/shared/game/room_file_deprecated.cpp index 7fdae6e1f501..4b0a6457a121 100644 --- a/engines/ags/shared/game/room_file_deprecated.cpp +++ b/engines/ags/shared/game/room_file_deprecated.cpp @@ -33,7 +33,7 @@ #include "ac/common.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; #define AE_WAITFLAG 0x80000000 #define MAXANIMSTAGES 10 @@ -70,7 +70,7 @@ struct PolyPoints { numpoints = 0; } - void Read(AGS::Common::Stream *in); + void Read(AGS::Shared::Stream *in); }; diff --git a/engines/ags/shared/game/roomstruct.cpp b/engines/ags/shared/game/roomstruct.cpp index 91bb1b2e5bd1..4a9ddc26ef12 100644 --- a/engines/ags/shared/game/roomstruct.cpp +++ b/engines/ags/shared/game/roomstruct.cpp @@ -26,7 +26,7 @@ #include "gfx/bitmap.h" namespace AGS { -namespace Common { +namespace Shared { RoomOptions::RoomOptions() : StartupMusic(0) @@ -298,5 +298,5 @@ void FixRoomMasks(RoomStruct *room) { room->WalkAreaMask = FixBitmap(room->WalkAreaMask, low_width, low_height); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index 1895d689c8c4..b9d48742e13c 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -60,7 +60,7 @@ struct ccScript; struct SpriteInfo; typedef std::shared_ptr PScript; -// TODO: move the following enums under AGS::Common namespace +// TODO: move the following enums under AGS::Shared namespace // later, when more engine source is put in AGS namespace and // refactored. @@ -110,7 +110,7 @@ enum RoomVolumeMod { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; class Stream; @@ -384,7 +384,7 @@ void FixRoomMasks(RoomStruct *room); // Adjusts bitmap size if necessary and returns either new or old bitmap. PBitmap FixBitmap(PBitmap bmp, int dst_width, int dst_height); -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index 75284d19b6dc..d84072b90c38 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -27,7 +27,7 @@ extern void __my_setcolor(int *ctset, int newcol, int wantColDep); namespace AGS { -namespace Common { +namespace Shared { Bitmap::Bitmap() : _alBitmap(nullptr) @@ -411,5 +411,5 @@ Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp) { } // namespace BitmapHelper -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 77d0ea83fcde..3a5092cc97c3 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -38,7 +38,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap { public: @@ -232,7 +232,7 @@ Bitmap *CreateRawBitmapOwner(BITMAP *al_bmp); Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp); } // namespace BitmapHelper -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp index 85b22374cacb..98447e2c47fe 100644 --- a/engines/ags/shared/gfx/bitmap.cpp +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -24,7 +24,7 @@ #include "util/memory.h" namespace AGS { -namespace Common { +namespace Shared { // TODO: revise this construction later namespace BitmapHelper { @@ -169,5 +169,5 @@ void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t s } // namespace BitmapHelper -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gfx/bitmap.h b/engines/ags/shared/gfx/bitmap.h index b370c9a004a8..91a4d15b074d 100644 --- a/engines/ags/shared/gfx/bitmap.h +++ b/engines/ags/shared/gfx/bitmap.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // Mask option for blitting one bitmap on another enum BitmapMaskOption { @@ -49,7 +49,7 @@ enum BitmapFlip { kBitmap_HVFlip }; -} // namespace Common +} // namespace Shared } // namespace AGS @@ -57,7 +57,7 @@ enum BitmapFlip { #include "gfx/allegrobitmap.h" namespace AGS { -namespace Common { +namespace Shared { class Bitmap; @@ -86,7 +86,7 @@ void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bo void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t src_pitch, const size_t src_px_offset = 0); } // namespace BitmapHelper -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/gfx/gfx_def.h b/engines/ags/shared/gfx/gfx_def.h index 4e84b51bdd97..51a583e47d88 100644 --- a/engines/ags/shared/gfx/gfx_def.h +++ b/engines/ags/shared/gfx/gfx_def.h @@ -31,7 +31,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { enum BlendMode { // free blending (ARGB -> ARGB) modes @@ -103,7 +103,7 @@ inline int LegacyTrans100ToAlpha255(int legacy_transparency) { } } // namespace GfxDef -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/gui/guibutton.cpp b/engines/ags/shared/gui/guibutton.cpp index 9859e4e312e9..502aeb036746 100644 --- a/engines/ags/shared/gui/guibutton.cpp +++ b/engines/ags/shared/gui/guibutton.cpp @@ -26,11 +26,11 @@ #include "util/stream.h" #include "util/string_utils.h" -std::vector guibuts; +std::vector guibuts; int numguibuts = 0; namespace AGS { -namespace Common { +namespace Shared { FrameAlignment ConvertLegacyButtonAlignment(LegacyButtonAlignment align) { switch (align) { @@ -346,5 +346,5 @@ void GUIButton::DrawTextButton(Bitmap *ds, bool draw_disabled) { DrawText(ds, draw_disabled); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index f89edce6fd48..f5ac628a039b 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -32,7 +32,7 @@ namespace AGS3 { #define GUIBUTTON_LEGACY_TEXTLENGTH 50 namespace AGS { -namespace Common { +namespace Shared { enum MouseButton { kMouseNone = -1, @@ -127,10 +127,10 @@ class GUIButton : public GUIObject { String _textToDraw; }; -} // namespace Common +} // namespace Shared } // namespace AGS -extern std::vector guibuts; +extern std::vector guibuts; extern int numguibuts; int UpdateAnimatingButton(int bu); diff --git a/engines/ags/shared/gui/guidefines.h b/engines/ags/shared/gui/guidefines.h index 8f7f04f74f9c..1086132e9e0a 100644 --- a/engines/ags/shared/gui/guidefines.h +++ b/engines/ags/shared/gui/guidefines.h @@ -85,7 +85,7 @@ enum GuiVersion { }; namespace AGS { -namespace Common { +namespace Shared { // GUIMain's style and behavior flags enum GUIMainFlags { @@ -176,7 +176,7 @@ enum GuiSvgVersion { kGuiSvgVersion_350 = 1 }; -} // namespace Common +} // namespace Shared } // namespace AGS extern int guis_need_update; diff --git a/engines/ags/shared/gui/guiinv.cpp b/engines/ags/shared/gui/guiinv.cpp index 368d0beca390..6feaf6c188d0 100644 --- a/engines/ags/shared/gui/guiinv.cpp +++ b/engines/ags/shared/gui/guiinv.cpp @@ -26,11 +26,11 @@ #include "gui/guimain.h" #include "util/stream.h" -std::vector guiinv; +std::vector guiinv; int numguiinv = 0; namespace AGS { -namespace Common { +namespace Shared { GUIInvWindow::GUIInvWindow() { IsMouseOver = false; @@ -127,5 +127,5 @@ void GUIInvWindow::CalculateNumCells() { } } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index f0e6041fac74..8c358dc0b86e 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class GUIInvWindow : public GUIObject { public: @@ -67,10 +67,10 @@ class GUIInvWindow : public GUIObject { void CalculateNumCells(); }; -} // namespace Common +} // namespace Shared } // namespace AGS -extern std::vector guiinv; +extern std::vector guiinv; extern int numguiinv; } // namespace AGS3 diff --git a/engines/ags/shared/gui/guilabel.cpp b/engines/ags/shared/gui/guilabel.cpp index 480c6acb0859..7891b5d66a94 100644 --- a/engines/ags/shared/gui/guilabel.cpp +++ b/engines/ags/shared/gui/guilabel.cpp @@ -27,13 +27,13 @@ #include "util/stream.h" #include "util/string_utils.h" -std::vector guilabels; +std::vector guilabels; int numguilabels = 0; #define GUILABEL_TEXTLENGTH_PRE272 200 namespace AGS { -namespace Common { +namespace Shared { GUILabel::GUILabel() { Font = 0; @@ -121,5 +121,5 @@ void GUILabel::WriteToSavegame(Stream *out) const { out->WriteInt32(TextAlignment); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index 88c2380bcf26..ff114725712b 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -32,7 +32,7 @@ namespace AGS3 { class SplitLines; namespace AGS { -namespace Common { +namespace Shared { class GUILabel : public GUIObject { public: @@ -65,10 +65,10 @@ class GUILabel : public GUIObject { String _textToDraw; }; -} // namespace Common +} // namespace Shared } // namespace AGS -extern std::vector guilabels; +extern std::vector guilabels; extern int numguilabels; } // namespace AGS3 diff --git a/engines/ags/shared/gui/guilistbox.cpp b/engines/ags/shared/gui/guilistbox.cpp index 5cb14fe264d7..f629615ef2f1 100644 --- a/engines/ags/shared/gui/guilistbox.cpp +++ b/engines/ags/shared/gui/guilistbox.cpp @@ -26,11 +26,11 @@ #include "util/stream.h" #include "util/string_utils.h" -std::vector guilist; +std::vector guilist; int numguilist = 0; namespace AGS { -namespace Common { +namespace Shared { GUIListBox::GUIListBox() { ItemCount = 0; @@ -390,5 +390,5 @@ void GUIListBox::WriteToSavegame(Stream *out) const { out->WriteInt32(SelectedItem); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index 30c55e5e6a42..f3910c1074aa 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -29,7 +29,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class GUIListBox : public GUIObject { public: @@ -95,10 +95,10 @@ class GUIListBox : public GUIObject { String _textToDraw; }; -} // namespace Common +} // namespace Shared } // namespace AGS -extern std::vector guilist; +extern std::vector guilist; extern int numguilist; } // namespace AGS3 diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index d71a9c8e3853..dfade96d2fb9 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -35,7 +35,7 @@ #include "util/stream.h" #include "util/string_utils.h" -using namespace AGS::Common; +using namespace AGS::Shared; #define MOVER_MOUSEDOWNLOCKED -4000 @@ -44,7 +44,7 @@ int all_buttons_disabled = 0, gui_inv_pic = -1; int gui_disabled_style = 0; namespace AGS { -namespace Common { +namespace Shared { /* static */ String GUIMain::FixupGUIName(const String &name) { if (name.GetLength() > 0 && name[0u] != 'g') @@ -816,5 +816,5 @@ void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis) { } // namespace GUI -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index 27d7deee5eb8..004f3b226a3c 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -35,7 +35,7 @@ namespace AGS3 { // Forward declaration namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS @@ -53,7 +53,7 @@ struct GameSetupStruct; #define GUIMAIN_LEGACY_TW_FLAGS_SIZE 4 namespace AGS { -namespace Common { +namespace Shared { // Legacy GUIMain visibility state, which combined Visible property and override factor enum LegacyGUIVisState { @@ -214,7 +214,7 @@ void WriteGUI(const std::vector &guis, Stream *out); void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis); } -} // namespace Common +} // namespace Shared } // namespace AGS extern std::vector guis; diff --git a/engines/ags/shared/gui/guiobject.cpp b/engines/ags/shared/gui/guiobject.cpp index 8f278025f14e..82d5bde79174 100644 --- a/engines/ags/shared/gui/guiobject.cpp +++ b/engines/ags/shared/gui/guiobject.cpp @@ -26,7 +26,7 @@ #include "util/stream.h" namespace AGS { -namespace Common { +namespace Shared { GUIObject::GUIObject() { Id = 0; @@ -194,5 +194,5 @@ HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align) { return kHAlignNone; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h index 1dfa51786760..9dc698050d69 100644 --- a/engines/ags/shared/gui/guiobject.h +++ b/engines/ags/shared/gui/guiobject.h @@ -36,7 +36,7 @@ namespace AGS3 { #define GUIDIS_GUIOFF 0x80 namespace AGS { -namespace Common { +namespace Shared { enum LegacyGUIAlignment { kLegacyGUIAlign_Left = 0, @@ -127,13 +127,13 @@ class GUIObject { // Converts legacy alignment type used in GUI Label/ListBox data (only left/right/center) HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align); -} // namespace Common +} // namespace Shared } // namespace AGS // Tells if all controls are disabled extern int all_buttons_disabled; // Tells if the given control is considered enabled, taking global flag into account -inline bool IsGUIEnabled(AGS::Common::GUIObject *g) { +inline bool IsGUIEnabled(AGS::Shared::GUIObject *g) { return !all_buttons_disabled && g->IsEnabled(); } diff --git a/engines/ags/shared/gui/guislider.cpp b/engines/ags/shared/gui/guislider.cpp index fee93194a268..d58e52a2864e 100644 --- a/engines/ags/shared/gui/guislider.cpp +++ b/engines/ags/shared/gui/guislider.cpp @@ -25,11 +25,11 @@ #include "gui/guislider.h" #include "util/stream.h" -std::vector guislider; +std::vector guislider; int numguislider = 0; namespace AGS { -namespace Common { +namespace Shared { GUISlider::GUISlider() { MinValue = 0; @@ -240,5 +240,5 @@ void GUISlider::WriteToSavegame(Stream *out) const { out->WriteInt32(Value); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index 2e5696bed2e9..338dc7124fe9 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class GUISlider : public GUIObject { public: @@ -68,10 +68,10 @@ class GUISlider : public GUIObject { Rect _cachedHandle; }; -} // namespace Common +} // namespace Shared } // namespace AGS -extern std::vector guislider; +extern std::vector guislider; extern int numguislider; } // namespace AGS3 diff --git a/engines/ags/shared/gui/guitextbox.cpp b/engines/ags/shared/gui/guitextbox.cpp index 307ce31bd94e..9722612a25a7 100644 --- a/engines/ags/shared/gui/guitextbox.cpp +++ b/engines/ags/shared/gui/guitextbox.cpp @@ -28,11 +28,11 @@ #define GUITEXTBOX_LEGACY_TEXTLEN 200 -std::vector guitext; +std::vector guitext; int numguitext = 0; namespace AGS { -namespace Common { +namespace Shared { GUITextBox::GUITextBox() { Font = 0; @@ -135,5 +135,5 @@ void GUITextBox::WriteToSavegame(Stream *out) const { out->WriteInt32(TextBoxFlags); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index 79f8ac9be511..9a69cd4c6232 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -29,7 +29,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class GUITextBox : public GUIObject { public: @@ -62,10 +62,10 @@ class GUITextBox : public GUIObject { void DrawTextBoxContents(Bitmap *ds, color_t text_color); }; -} // namespace Common +} // namespace Shared } // namespace AGS -extern std::vector guitext; +extern std::vector guitext; extern int numguitext; } // namespace AGS3 diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp index 71f328df98cd..a97da16d8bd3 100644 --- a/engines/ags/shared/script/cc_error.cpp +++ b/engines/ags/shared/script/cc_error.cpp @@ -25,7 +25,7 @@ #include "script/script_common.h" // current_line #include "util/string.h" -using namespace AGS::Common; +using namespace AGS::Shared; // Returns full script error message and callstack (if possible) extern std::pair cc_error_at_line(const char *error_msg); diff --git a/engines/ags/shared/script/cc_error.h b/engines/ags/shared/script/cc_error.h index 7dc8c68df965..d211af6fbf88 100644 --- a/engines/ags/shared/script/cc_error.h +++ b/engines/ags/shared/script/cc_error.h @@ -38,8 +38,8 @@ extern void cc_error(const char *, ...); // error reporting extern int ccError; // set to non-zero if error occurs extern int ccErrorLine; // line number of the error -extern AGS::Common::String ccErrorString; // description of the error -extern AGS::Common::String ccErrorCallStack; // callstack where error happened +extern AGS::Shared::String ccErrorString; // description of the error +extern AGS::Shared::String ccErrorCallStack; // callstack where error happened extern bool ccErrorIsUserError; extern const char *ccCurScriptName; // name of currently compiling script diff --git a/engines/ags/shared/script/cc_script.cpp b/engines/ags/shared/script/cc_script.cpp index bd5c5b81f853..2f6a567304f7 100644 --- a/engines/ags/shared/script/cc_script.cpp +++ b/engines/ags/shared/script/cc_script.cpp @@ -28,7 +28,7 @@ #include "util/stream.h" #include "util/string_compat.h" -using AGS::Common::Stream; +using AGS::Shared::Stream; // currently executed line int currentline; diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index 8821879907dc..e1390caa8c9f 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -35,7 +35,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/alignedstream.cpp b/engines/ags/shared/util/alignedstream.cpp index d1a760a593f9..aa0a19096353 100644 --- a/engines/ags/shared/util/alignedstream.cpp +++ b/engines/ags/shared/util/alignedstream.cpp @@ -25,7 +25,7 @@ #include "util/math.h" namespace AGS { -namespace Common { +namespace Shared { AlignedStream::AlignedStream(Stream *stream, AlignedStreamMode mode, ObjectOwnershipPolicy stream_ownership_policy, size_t base_alignment) @@ -328,5 +328,5 @@ void AlignedStream::FinalizeBlock() { _block = 0; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/alignedstream.h b/engines/ags/shared/util/alignedstream.h index f91ab58c83b1..8d9d90a42a13 100644 --- a/engines/ags/shared/util/alignedstream.h +++ b/engines/ags/shared/util/alignedstream.h @@ -49,7 +49,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { enum AlignedStreamMode { kAligned_Read, @@ -108,7 +108,7 @@ class AlignedStream : public ProxyStream { int64_t _block; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h index 32472fa84a87..c8cb850ed824 100644 --- a/engines/ags/shared/util/bbop.h +++ b/engines/ags/shared/util/bbop.h @@ -38,7 +38,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { enum DataEndianess { kBigEndian, @@ -146,7 +146,7 @@ inline float FloatFromBE(const float val) { // Aliases for easier calling namespace BBOp = BitByteOperations; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index a1a8f0dd0654..34a569501ad1 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -28,7 +28,7 @@ #include "util/string.h" namespace AGS { -namespace Common { +namespace Shared { BufferedStream::BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) : FileStream(file_name, open_mode, work_mode, stream_endianess), _buffer(BufferStreamSize), _bufferPosition(0), _position(0) { @@ -137,5 +137,5 @@ bool BufferedStream::Seek(soff_t offset, StreamSeek origin) { return _position == want_pos; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h index 4e14beb8c573..1f4bb3a22fef 100644 --- a/engines/ags/shared/util/bufferedstream.h +++ b/engines/ags/shared/util/bufferedstream.h @@ -29,7 +29,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // Needs tuning depending on the platform. const auto BufferStreamSize = 8 * 1024; @@ -66,7 +66,7 @@ class BufferedStream : public FileStream { void FillBufferFromPosition(soff_t position); }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp index cb0cf21e8cb9..9c5270ee7689 100644 --- a/engines/ags/shared/util/compress.cpp +++ b/engines/ags/shared/util/compress.cpp @@ -37,7 +37,7 @@ #include "util/bbop.h" #endif -using namespace AGS::Common; +using namespace AGS::Shared; void cpackbitl(const uint8_t *line, int size, Stream *out) { int cnt = 0; // bytes encoded diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h index 8fd7aa630e06..0c4b8016a85f 100644 --- a/engines/ags/shared/util/compress.h +++ b/engines/ags/shared/util/compress.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; class Bitmap; } // namespace Shared diff --git a/engines/ags/shared/util/datastream.cpp b/engines/ags/shared/util/datastream.cpp index ff170d184c98..ad41bfe4e25d 100644 --- a/engines/ags/shared/util/datastream.cpp +++ b/engines/ags/shared/util/datastream.cpp @@ -23,7 +23,7 @@ #include "util/datastream.h" namespace AGS { -namespace Common { +namespace Shared { DataStream::DataStream(DataEndianess stream_endianess) : _streamEndianess(stream_endianess) { @@ -151,5 +151,5 @@ size_t DataStream::WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t cou return elem; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/datastream.h b/engines/ags/shared/util/datastream.h index da47e40cb75a..16322fd4aa79 100644 --- a/engines/ags/shared/util/datastream.h +++ b/engines/ags/shared/util/datastream.h @@ -36,7 +36,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class DataStream : public Stream { public: @@ -123,7 +123,7 @@ class DataStream : public Stream { } }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp index fa58dfc3ebea..ba0c39b74024 100644 --- a/engines/ags/shared/util/directory.cpp +++ b/engines/ags/shared/util/directory.cpp @@ -33,7 +33,7 @@ #include "stdio_compat.h" namespace AGS { -namespace Common { +namespace Shared { namespace Directory { @@ -81,5 +81,5 @@ String GetCurrentDirectory() { } // namespace Directory -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h index 55dc4deb0a2a..07f5cac469ce 100644 --- a/engines/ags/shared/util/directory.h +++ b/engines/ags/shared/util/directory.h @@ -34,7 +34,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { namespace Directory { // Creates new directory (if it does not exist) @@ -48,7 +48,7 @@ String SetCurrentDirectory(const String &path); String GetCurrentDirectory(); } // namespace Directory -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h index 44874849762a..f404b44ae3e1 100644 --- a/engines/ags/shared/util/error.h +++ b/engines/ags/shared/util/error.h @@ -35,7 +35,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Error; typedef std::shared_ptr PError; @@ -162,7 +162,7 @@ class TypedCodeError : public Error { } }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp index 3b597748ded8..0b4adcd784ee 100644 --- a/engines/ags/shared/util/file.cpp +++ b/engines/ags/shared/util/file.cpp @@ -30,7 +30,7 @@ #include "util/bufferedstream.h" namespace AGS { -namespace Common { +namespace Shared { soff_t File::GetFileSize(const String &filename) { return ags_file_size(filename.GetCStr()); @@ -151,5 +151,5 @@ Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkM return fs; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h index 6774a33c07c8..73f21201cdb8 100644 --- a/engines/ags/shared/util/file.h +++ b/engines/ags/shared/util/file.h @@ -34,7 +34,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // Forward declarations class Stream; @@ -84,7 +84,7 @@ inline Stream *OpenFileWrite(const String &filename) { } } // namespace File -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index aa08fa407a7b..25956eb400d9 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -27,7 +27,7 @@ #include "util/string.h" namespace AGS { -namespace Common { +namespace Shared { FileStream::FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) @@ -160,5 +160,5 @@ void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkM throw std::runtime_error("Error opening file."); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index 8e222b2a3727..77aae7dac173 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -30,7 +30,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class FileStream : public DataStream { public: @@ -74,7 +74,7 @@ class FileStream : public DataStream { const FileWorkMode _workMode; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/geometry.cpp b/engines/ags/shared/util/geometry.cpp index c4e4c9a8932c..254f2dd30176 100644 --- a/engines/ags/shared/util/geometry.cpp +++ b/engines/ags/shared/util/geometry.cpp @@ -26,7 +26,7 @@ //namespace AGS //{ -//namespace Common +//namespace Shared //{ bool AreRectsIntersecting(const Rect &r1, const Rect &r2) { @@ -125,5 +125,5 @@ Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &place } } -//} // namespace Common +//} // namespace Shared //} // namespace AGS diff --git a/engines/ags/shared/util/geometry.h b/engines/ags/shared/util/geometry.h index 058ca377a9c1..570868df7cbf 100644 --- a/engines/ags/shared/util/geometry.h +++ b/engines/ags/shared/util/geometry.h @@ -33,10 +33,10 @@ namespace AGS3 { -namespace AGSMath = AGS::Common::Math; +namespace AGSMath = AGS::Shared::Math; //namespace AGS //{ -//namespace Common +//namespace Shared //{ // Type of alignment of a geometric item of rectangular boundaries. @@ -361,7 +361,7 @@ Rect OffsetRect(const Rect &r, const Point off); Rect CenterInRect(const Rect &place, const Rect &item); Rect ClampToRect(const Rect &place, const Rect &item); Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement); -//} // namespace Common +//} // namespace Shared //} // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/ini_util.cpp b/engines/ags/shared/util/ini_util.cpp index b18321f256e3..b5b773f9af30 100644 --- a/engines/ags/shared/util/ini_util.cpp +++ b/engines/ags/shared/util/ini_util.cpp @@ -28,7 +28,7 @@ #include "util/textstreamwriter.h" namespace AGS { -namespace Common { +namespace Shared { typedef std::unique_ptr UStream; typedef IniFile::SectionIterator SectionIterator; @@ -179,5 +179,5 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { return true; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h index 7e5906bb5e8c..6a127f3652ee 100644 --- a/engines/ags/shared/util/ini_util.h +++ b/engines/ags/shared/util/ini_util.h @@ -35,7 +35,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { typedef std::map StringOrderMap; typedef StringOrderMap::const_iterator StrStrOIter; @@ -69,7 +69,7 @@ void WriteToString(String &s, const ConfigTree &tree); bool Merge(const String &file, const ConfigTree &tree); }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/inifile.cpp b/engines/ags/shared/util/inifile.cpp index 0e39d9586380..3841e2e3c4a9 100644 --- a/engines/ags/shared/util/inifile.cpp +++ b/engines/ags/shared/util/inifile.cpp @@ -34,7 +34,7 @@ inline int isblank(int ch) { } // std namespace AGS { -namespace Common { +namespace Shared { inline static void ReplaceSubString(String &line, IniFile::StrPos &sub_pos, const String &new_sub) { line.ReplaceMid(sub_pos.first, sub_pos.second - sub_pos.first, new_sub); @@ -266,5 +266,5 @@ void IniFile::Write(Stream *out) const { writer.ReleaseStream(); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h index 09709dda14d2..eaa490c3685e 100644 --- a/engines/ags/shared/util/inifile.h +++ b/engines/ags/shared/util/inifile.h @@ -38,7 +38,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class IniFile { public: @@ -168,7 +168,7 @@ class IniFile { LSections _sections; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/lzw.cpp b/engines/ags/shared/util/lzw.cpp index d6667f1bf5fc..be39388a6e37 100644 --- a/engines/ags/shared/util/lzw.cpp +++ b/engines/ags/shared/util/lzw.cpp @@ -30,7 +30,7 @@ #include "ac/common.h" // quit #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; #ifdef _MANAGED // ensure this doesn't get compiled to .NET IL diff --git a/engines/ags/shared/util/lzw.h b/engines/ags/shared/util/lzw.h index 236343090c0e..25171da1d3e7 100644 --- a/engines/ags/shared/util/lzw.h +++ b/engines/ags/shared/util/lzw.h @@ -26,7 +26,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/math.h b/engines/ags/shared/util/math.h index 9053565f8be0..b7737facc105 100644 --- a/engines/ags/shared/util/math.h +++ b/engines/ags/shared/util/math.h @@ -36,7 +36,7 @@ namespace AGS3 { #endif namespace AGS { -namespace Common { +namespace Shared { namespace Math { template @@ -84,7 +84,7 @@ inline float DegreesToRadians(float deg) { } } // namespace Math -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h index 85defb9cbbf0..3b6a0f3c4e18 100644 --- a/engines/ags/shared/util/memory.h +++ b/engines/ags/shared/util/memory.h @@ -40,7 +40,7 @@ namespace AGS3 { #endif namespace AGS { -namespace Common { +namespace Shared { namespace Memory { //------------------------------------------------------------------------- @@ -228,7 +228,7 @@ inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_off } // namespace Memory -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp index a2210e8ae874..65b730665b14 100644 --- a/engines/ags/shared/util/misc.cpp +++ b/engines/ags/shared/util/misc.cpp @@ -63,7 +63,7 @@ #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; #if !defined (AGS_CASE_SENSITIVE_FILESYSTEM) #include diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h index 8d798e1e7f5d..1cd6e6efc3b5 100644 --- a/engines/ags/shared/util/misc.h +++ b/engines/ags/shared/util/misc.h @@ -57,7 +57,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/multifilelib.h b/engines/ags/shared/util/multifilelib.h index d7242b667c66..49dad28c695d 100644 --- a/engines/ags/shared/util/multifilelib.h +++ b/engines/ags/shared/util/multifilelib.h @@ -39,7 +39,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // // MultiFileLib utilities: (de)serialization of asset library in MFL format @@ -73,7 +73,7 @@ void WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_in void WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out); }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/mutifilelib.cpp b/engines/ags/shared/util/mutifilelib.cpp index 490d3ba1f428..03ff460569f3 100644 --- a/engines/ags/shared/util/mutifilelib.cpp +++ b/engines/ags/shared/util/mutifilelib.cpp @@ -26,7 +26,7 @@ #include "util/string_utils.h" namespace AGS { -namespace Common { +namespace Shared { namespace MFLUtil { const String HeadSig = "CLIB\x1a"; @@ -401,7 +401,7 @@ int32_t MFLUtil::ReadEncInt32(Stream *in, int &rand_val) { int val; ReadEncArray(&val, sizeof(int32_t), 1, in, rand_val); #if AGS_PLATFORM_ENDIAN_BIG - AGS::Common::BitByteOperations::SwapBytesInt32(val); + AGS::Shared::BitByteOperations::SwapBytesInt32(val); #endif return val; } @@ -418,4 +418,4 @@ void MFLUtil::ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_ } } // namespace AGS -} // namespace Common +} // namespace Shared diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp index 2b75fe894337..a3b88923a77d 100644 --- a/engines/ags/shared/util/path.cpp +++ b/engines/ags/shared/util/path.cpp @@ -34,7 +34,7 @@ #endif namespace AGS { -namespace Common { +namespace Shared { namespace Path { @@ -241,5 +241,5 @@ String GetCmdLinePathInASCII(const char *arg, int arg_index) { } // namespace Path -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h index 41a62c406b77..0901c6d57bbc 100644 --- a/engines/ags/shared/util/path.h +++ b/engines/ags/shared/util/path.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { namespace Path { // Tells if the given path is a directory @@ -85,7 +85,7 @@ String GetPathInASCII(const String &path); String GetCmdLinePathInASCII(const char *arg, int arg_index); } // namespace Path -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/proxystream.cpp b/engines/ags/shared/util/proxystream.cpp index cdd979569d04..71fe5a17a501 100644 --- a/engines/ags/shared/util/proxystream.cpp +++ b/engines/ags/shared/util/proxystream.cpp @@ -23,7 +23,7 @@ #include "util/proxystream.h" namespace AGS { -namespace Common { +namespace Shared { ProxyStream::ProxyStream(Stream *stream, ObjectOwnershipPolicy stream_ownership_policy) : _stream(stream) @@ -152,5 +152,5 @@ bool ProxyStream::Seek(soff_t offset, StreamSeek origin) { return _stream ? _stream->Seek(offset, origin) : false; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/proxystream.h b/engines/ags/shared/util/proxystream.h index 8c0758cd1dbe..ef40dd10c462 100644 --- a/engines/ags/shared/util/proxystream.h +++ b/engines/ags/shared/util/proxystream.h @@ -27,7 +27,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { // TODO: replace with std::shared_ptr!!! enum ObjectOwnershipPolicy { @@ -83,7 +83,7 @@ class ProxyStream : public Stream { ObjectOwnershipPolicy _streamOwnershipPolicy; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/stream.cpp b/engines/ags/shared/util/stream.cpp index 737496ec4378..33b71778749a 100644 --- a/engines/ags/shared/util/stream.cpp +++ b/engines/ags/shared/util/stream.cpp @@ -23,7 +23,7 @@ #include "util/stream.h" namespace AGS { -namespace Common { +namespace Shared { size_t Stream::WriteByteCount(uint8_t b, size_t count) { if (!CanWrite()) @@ -36,5 +36,5 @@ size_t Stream::WriteByteCount(uint8_t b, size_t count) { return size; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index d9cafba2022e..90cb0011e542 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -39,7 +39,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream : public IAGSStream { public: @@ -83,7 +83,7 @@ class Stream : public IAGSStream { size_t WriteByteCount(uint8_t b, size_t count); }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp index c6f9eb85d028..21e10d1f2841 100644 --- a/engines/ags/shared/util/string.cpp +++ b/engines/ags/shared/util/string.cpp @@ -29,7 +29,7 @@ #include "util/string_compat.h" namespace AGS { -namespace Common { +namespace Shared { String::String() : _cstr(nullptr) @@ -846,5 +846,5 @@ void String::ReserveAndShift(bool left, size_t more_length) { } } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index 8d8a02f89394..c2ecec93fbb8 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -54,7 +54,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; @@ -365,7 +365,7 @@ class String { }; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index c0871acc2658..60fe83f99186 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -60,8 +60,8 @@ namespace tr1 { #endif // std::hash for String object template<> -struct hash : public unary_function { - size_t operator()(const AGS::Common::String &key) const { +struct hash : public unary_function { + size_t operator()(const AGS::Shared::String &key) const { return FNV::Hash(key.GetCStr(), key.GetLength()); } }; @@ -72,7 +72,7 @@ struct hash : public unary_function StringV; typedef std::unordered_map StringMap; typedef std::unordered_map StringIMap; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp index 5278966534a1..e624738f1a1c 100644 --- a/engines/ags/shared/util/string_utils.cpp +++ b/engines/ags/shared/util/string_utils.cpp @@ -27,7 +27,7 @@ #include "util/string_utils.h" #include "util/stream.h" -using namespace AGS::Common; +using namespace AGS::Shared; String cbuf_to_string_and_free(char *char_buf) { String s = char_buf; @@ -37,7 +37,7 @@ String cbuf_to_string_and_free(char *char_buf) { namespace AGS { -namespace Common { +namespace Shared { String StrUtil::IntToString(int d) { return String::FromFormat("%d", d); @@ -156,5 +156,5 @@ void StrUtil::WriteCStr(const String &s, Stream *out) { out->Write(s.GetCStr(), s.GetLength() + 1); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h index 34a33e37bfd5..fc4ebd8f6bf4 100644 --- a/engines/ags/shared/util/string_utils.h +++ b/engines/ags/shared/util/string_utils.h @@ -28,7 +28,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared } // namespace AGS @@ -42,7 +42,7 @@ using namespace AGS; // FIXME later Common::String cbuf_to_string_and_free(char *char_buf); namespace AGS { -namespace Common { +namespace Shared { namespace StrUtil { enum ConversionError { kNoError, // conversion successful @@ -77,7 +77,7 @@ void SkipCStr(Stream *in); void WriteCStr(const char *cstr, Stream *out); void WriteCStr(const String &s, Stream *out); } -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/textreader.h b/engines/ags/shared/util/textreader.h index 3cfe2b64639b..78a507c5a9e3 100644 --- a/engines/ags/shared/util/textreader.h +++ b/engines/ags/shared/util/textreader.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class TextReader { public: @@ -51,7 +51,7 @@ class TextReader { virtual String ReadAll() = 0; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/textstreamreader.cpp b/engines/ags/shared/util/textstreamreader.cpp index 5b974e838c51..ec619da2061b 100644 --- a/engines/ags/shared/util/textstreamreader.cpp +++ b/engines/ags/shared/util/textstreamreader.cpp @@ -25,7 +25,7 @@ #include "util/textstreamreader.h" namespace AGS { -namespace Common { +namespace Shared { TextStreamReader::TextStreamReader(Stream *stream) : _stream(stream) { @@ -132,5 +132,5 @@ String TextStreamReader::ReadAll() { return ""; } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/textstreamreader.h b/engines/ags/shared/util/textstreamreader.h index 50360d619ebf..9c527dcc237b 100644 --- a/engines/ags/shared/util/textstreamreader.h +++ b/engines/ags/shared/util/textstreamreader.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; @@ -63,7 +63,7 @@ class TextStreamReader : public TextReader { Stream *_stream; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/textstreamwriter.cpp b/engines/ags/shared/util/textstreamwriter.cpp index edf2f8588e5d..2e2eb97301dc 100644 --- a/engines/ags/shared/util/textstreamwriter.cpp +++ b/engines/ags/shared/util/textstreamwriter.cpp @@ -27,7 +27,7 @@ #include "util/stream.h" namespace AGS { -namespace Common { +namespace Shared { #if AGS_PLATFORM_OS_WINDOWS static const char Endl[2] = {'\r', '\n'}; @@ -108,5 +108,5 @@ void TextStreamWriter::WriteLineBreak() { _stream->Write(Endl, sizeof(Endl)); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/textstreamwriter.h b/engines/ags/shared/util/textstreamwriter.h index bf7df0911253..ef15320996db 100644 --- a/engines/ags/shared/util/textstreamwriter.h +++ b/engines/ags/shared/util/textstreamwriter.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; @@ -64,7 +64,7 @@ class TextStreamWriter : public TextWriter { Stream *_stream; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/textwriter.h b/engines/ags/shared/util/textwriter.h index 9140f43832f0..42c735c37186 100644 --- a/engines/ags/shared/util/textwriter.h +++ b/engines/ags/shared/util/textwriter.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class TextWriter { public: @@ -52,7 +52,7 @@ class TextWriter { virtual void WriteLineBreak() = 0; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/version.cpp b/engines/ags/shared/util/version.cpp index 613ab12a3a49..6b1a273f52b8 100644 --- a/engines/ags/shared/util/version.cpp +++ b/engines/ags/shared/util/version.cpp @@ -24,7 +24,7 @@ #include "util/version.h" namespace AGS { -namespace Common { +namespace Shared { const Version Version::LastOldFormatVersion(3, 2, 2, 1120); @@ -132,5 +132,5 @@ void Version::MakeString() { ShortString.Format("%d.%d", Major, Minor); } -} // namespace Common +} // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/version.h b/engines/ags/shared/util/version.h index ed91b13323cc..95dad1377ac8 100644 --- a/engines/ags/shared/util/version.h +++ b/engines/ags/shared/util/version.h @@ -33,7 +33,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { using Common::String; @@ -101,7 +101,7 @@ struct Version { void MakeString(); }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/util/wgt2allg.cpp b/engines/ags/shared/util/wgt2allg.cpp index 436481eb394a..4a37ce5b83f4 100644 --- a/engines/ags/shared/util/wgt2allg.cpp +++ b/engines/ags/shared/util/wgt2allg.cpp @@ -25,7 +25,7 @@ #include "util/stream.h" #include "util/wgt2allg.h" -using namespace AGS::Common; +using namespace AGS::Shared; #ifdef __cplusplus extern "C" diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index 3e4f81ca2f0b..b9624c53bbce 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -40,7 +40,7 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; } // namespace Shared } // namespace AGS From 189d7527f12ad73b7c75f741bfaf9552a31e2b55 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 16:24:18 -0800 Subject: [PATCH 010/215] AGS: Adding AGS3 namespace to cpp files --- engines/ags/engine/ac/audiochannel.cpp | 36 ++- engines/ags/engine/ac/audioclip.cpp | 20 +- engines/ags/engine/ac/button.cpp | 52 ++-- engines/ags/engine/ac/cdaudio.cpp | 4 + engines/ags/engine/ac/character.cpp | 4 + engines/ags/engine/ac/characterextras.cpp | 4 + .../ags/engine/ac/characterinfo_engine.cpp | 56 ++-- engines/ags/engine/ac/datetime.cpp | 18 +- engines/ags/engine/ac/dialog.cpp | 4 + .../ags/engine/ac/dialogoptionsrendering.cpp | 44 +-- engines/ags/engine/ac/display.cpp | 40 +-- engines/ags/engine/ac/draw.cpp | 4 + engines/ags/engine/ac/draw_software.cpp | 4 + engines/ags/engine/ac/drawingsurface.cpp | 70 ++--- engines/ags/engine/ac/dynamicsprite.cpp | 52 ++-- .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 4 + .../ags/engine/ac/dynobj/cc_audiochannel.cpp | 4 + engines/ags/engine/ac/dynobj/cc_audioclip.cpp | 4 + engines/ags/engine/ac/dynobj/cc_character.cpp | 4 + engines/ags/engine/ac/dynobj/cc_dialog.cpp | 4 + .../ags/engine/ac/dynobj/cc_dynamicarray.cpp | 4 + .../ags/engine/ac/dynobj/cc_dynamicobject.cpp | 6 +- engines/ags/engine/ac/dynobj/cc_gui.cpp | 4 + engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 4 + engines/ags/engine/ac/dynobj/cc_hotspot.cpp | 4 + engines/ags/engine/ac/dynobj/cc_inventory.cpp | 4 + engines/ags/engine/ac/dynobj/cc_object.cpp | 4 + engines/ags/engine/ac/dynobj/cc_region.cpp | 4 + .../ags/engine/ac/dynobj/cc_serializer.cpp | 3 + .../engine/ac/dynobj/managedobjectpool.cpp | 14 +- engines/ags/engine/ac/dynobj/scriptcamera.cpp | 7 +- .../ags/engine/ac/dynobj/scriptdatetime.cpp | 4 + .../dynobj/scriptdialogoptionsrendering.cpp | 4 + engines/ags/engine/ac/dynobj/scriptdict.cpp | 6 +- .../engine/ac/dynobj/scriptdrawingsurface.cpp | 4 + .../engine/ac/dynobj/scriptdynamicsprite.cpp | 4 + engines/ags/engine/ac/dynobj/scriptfile.cpp | 8 +- .../ags/engine/ac/dynobj/scriptoverlay.cpp | 4 + engines/ags/engine/ac/dynobj/scriptset.cpp | 6 +- engines/ags/engine/ac/dynobj/scriptstring.cpp | 4 + .../ags/engine/ac/dynobj/scriptuserobject.cpp | 8 +- .../ags/engine/ac/dynobj/scriptviewframe.cpp | 4 + .../ags/engine/ac/dynobj/scriptviewport.cpp | 7 +- engines/ags/engine/ac/event.cpp | 16 +- engines/ags/engine/ac/file.cpp | 62 ++-- engines/ags/engine/ac/game.cpp | 4 + engines/ags/engine/ac/gamesetup.cpp | 4 + engines/ags/engine/ac/gamestate.cpp | 10 +- engines/ags/engine/ac/global_api.cpp | 5 + engines/ags/engine/ac/global_audio.cpp | 10 +- engines/ags/engine/ac/global_button.cpp | 4 + engines/ags/engine/ac/global_character.cpp | 14 +- engines/ags/engine/ac/global_datetime.cpp | 4 + engines/ags/engine/ac/global_debug.cpp | 24 +- engines/ags/engine/ac/global_dialog.cpp | 6 +- engines/ags/engine/ac/global_display.cpp | 14 +- .../ags/engine/ac/global_drawingsurface.cpp | 18 +- .../ags/engine/ac/global_dynamicsprite.cpp | 4 + engines/ags/engine/ac/global_file.cpp | 6 +- engines/ags/engine/ac/global_game.cpp | 41 +-- engines/ags/engine/ac/global_gui.cpp | 6 +- engines/ags/engine/ac/global_hotspot.cpp | 8 +- .../ags/engine/ac/global_inventoryitem.cpp | 4 + engines/ags/engine/ac/global_invwindow.cpp | 4 + engines/ags/engine/ac/global_label.cpp | 4 + engines/ags/engine/ac/global_listbox.cpp | 4 + engines/ags/engine/ac/global_mouse.cpp | 4 + engines/ags/engine/ac/global_object.cpp | 16 +- engines/ags/engine/ac/global_overlay.cpp | 4 + engines/ags/engine/ac/global_palette.cpp | 4 + engines/ags/engine/ac/global_parser.cpp | 4 + engines/ags/engine/ac/global_record.cpp | 4 + engines/ags/engine/ac/global_region.cpp | 13 +- engines/ags/engine/ac/global_room.cpp | 12 +- engines/ags/engine/ac/global_screen.cpp | 6 +- engines/ags/engine/ac/global_slider.cpp | 4 + engines/ags/engine/ac/global_string.cpp | 4 + engines/ags/engine/ac/global_textbox.cpp | 4 + engines/ags/engine/ac/global_timer.cpp | 4 + engines/ags/engine/ac/global_translation.cpp | 4 + engines/ags/engine/ac/global_video.cpp | 6 +- engines/ags/engine/ac/global_viewframe.cpp | 4 + engines/ags/engine/ac/global_viewport.cpp | 4 + engines/ags/engine/ac/global_walkablearea.cpp | 5 +- engines/ags/engine/ac/global_walkbehind.cpp | 4 + engines/ags/engine/ac/gui.cpp | 95 +++--- engines/ags/engine/ac/guicontrol.cpp | 62 ++-- engines/ags/engine/ac/guiinv.cpp | 6 +- engines/ags/engine/ac/hotspot.cpp | 36 ++- engines/ags/engine/ac/interfacebutton.cpp | 4 + engines/ags/engine/ac/interfaceelement.cpp | 4 + engines/ags/engine/ac/inventoryitem.cpp | 37 +-- engines/ags/engine/ac/invwindow.cpp | 38 +-- engines/ags/engine/ac/keycode.cpp | 12 +- engines/ags/engine/ac/label.cpp | 16 +- engines/ags/engine/ac/listbox.cpp | 62 ++-- engines/ags/engine/ac/math.cpp | 40 +-- engines/ags/engine/ac/mouse.cpp | 72 ++--- engines/ags/engine/ac/movelist.cpp | 6 +- engines/ags/engine/ac/object.cpp | 138 ++++----- engines/ags/engine/ac/overlay.cpp | 28 +- engines/ags/engine/ac/parser.cpp | 14 +- engines/ags/engine/ac/properties.cpp | 4 + engines/ags/engine/ac/region.cpp | 38 +-- engines/ags/engine/ac/richgamemedia.cpp | 4 + engines/ags/engine/ac/room.cpp | 4 + engines/ags/engine/ac/roomobject.cpp | 12 +- engines/ags/engine/ac/roomstatus.cpp | 8 +- engines/ags/engine/ac/route_finder.cpp | 4 + engines/ags/engine/ac/route_finder_impl.cpp | 3 + .../engine/ac/route_finder_impl_legacy.cpp | 31 +- engines/ags/engine/ac/screen.cpp | 4 + engines/ags/engine/ac/screenoverlay.cpp | 4 + engines/ags/engine/ac/scriptcontainers.cpp | 4 + engines/ags/engine/ac/slider.cpp | 28 +- engines/ags/engine/ac/speech.cpp | 38 +-- engines/ags/engine/ac/sprite.cpp | 4 + engines/ags/engine/ac/spritecache_engine.cpp | 4 + .../ags/engine/ac/statobj/agsstaticobject.cpp | 4 + engines/ags/engine/ac/statobj/staticarray.cpp | 28 +- engines/ags/engine/ac/string.cpp | 59 ++-- engines/ags/engine/ac/sys_events.cpp | 136 ++++----- engines/ags/engine/ac/system.cpp | 54 ++-- engines/ags/engine/ac/textbox.cpp | 24 +- engines/ags/engine/ac/timer.cpp | 4 + engines/ags/engine/ac/translation.cpp | 8 +- engines/ags/engine/ac/tree_map.cpp | 6 +- engines/ags/engine/ac/viewframe.cpp | 4 + engines/ags/engine/ac/viewport_script.cpp | 4 + engines/ags/engine/ac/walkablearea.cpp | 18 +- engines/ags/engine/ac/walkbehind.cpp | 10 +- .../engine/debugging/consoleoutputtarget.cpp | 2 + engines/ags/engine/debugging/debug.cpp | 59 ++-- .../engine/debugging/filebasedagsdebugger.cpp | 4 + engines/ags/engine/debugging/logfile.cpp | 9 +- .../ags/engine/debugging/messagebuffer.cpp | 4 +- engines/ags/engine/device/mousew32.cpp | 16 +- engines/ags/engine/font/fonts_engine.cpp | 4 + engines/ags/engine/game/game_init.cpp | 15 +- engines/ags/engine/game/savegame.cpp | 27 +- .../ags/engine/game/savegame_components.cpp | 3 + engines/ags/engine/game/viewport.cpp | 4 + engines/ags/engine/gfx/ali3dogl.cpp | 3 + engines/ags/engine/gfx/ali3dsw.cpp | 56 ++-- engines/ags/engine/gfx/blender.cpp | 18 +- engines/ags/engine/gfx/color_engine.cpp | 6 +- engines/ags/engine/gfx/gfx_util.cpp | 23 +- engines/ags/engine/gfx/gfxdriverbase.cpp | 13 +- engines/ags/engine/gfx/gfxdriverfactory.cpp | 2 + engines/ags/engine/gfx/gfxfilter_aad3d.cpp | 2 + engines/ags/engine/gfx/gfxfilter_aaogl.cpp | 2 + engines/ags/engine/gfx/gfxfilter_allegro.cpp | 10 +- engines/ags/engine/gfx/gfxfilter_d3d.cpp | 2 + engines/ags/engine/gfx/gfxfilter_hqx.cpp | 4 +- engines/ags/engine/gfx/gfxfilter_ogl.cpp | 2 + engines/ags/engine/gfx/gfxfilter_scaling.cpp | 2 + engines/ags/engine/gui/animatingguibutton.cpp | 4 + engines/ags/engine/gui/cscidialog.cpp | 6 +- engines/ags/engine/gui/gui_engine.cpp | 11 +- engines/ags/engine/gui/guidialog.cpp | 28 +- engines/ags/engine/gui/mylabel.cpp | 4 + engines/ags/engine/gui/mylistbox.cpp | 8 +- engines/ags/engine/gui/mypushbutton.cpp | 4 + engines/ags/engine/gui/mytextbox.cpp | 4 + engines/ags/engine/gui/newcontrol.cpp | 6 +- engines/ags/engine/main/config.cpp | 19 +- engines/ags/engine/main/engine.cpp | 4 + engines/ags/engine/main/engine_setup.cpp | 10 +- engines/ags/engine/main/game_file.cpp | 14 +- engines/ags/engine/main/game_run.cpp | 76 ++--- engines/ags/engine/main/game_start.cpp | 4 + engines/ags/engine/main/graphics_mode.cpp | 82 +++--- engines/ags/engine/main/main.cpp | 120 ++++---- engines/ags/engine/main/quit.cpp | 20 +- engines/ags/engine/main/update.cpp | 58 ++-- .../ags/engine/media/audio/ambientsound.cpp | 4 + engines/ags/engine/media/audio/audio.cpp | 36 ++- .../ags/engine/media/audio/clip_mydumbmod.cpp | 4 + .../ags/engine/media/audio/clip_myjgmod.cpp | 6 +- .../ags/engine/media/audio/clip_mymidi.cpp | 4 + engines/ags/engine/media/audio/clip_mymp3.cpp | 5 +- engines/ags/engine/media/audio/clip_myogg.cpp | 4 + .../engine/media/audio/clip_mystaticmp3.cpp | 6 +- .../engine/media/audio/clip_mystaticogg.cpp | 4 + .../ags/engine/media/audio/clip_mywave.cpp | 4 + .../engine/media/audio/queuedaudioitem.cpp | 4 + engines/ags/engine/media/audio/sound.cpp | 8 +- engines/ags/engine/media/audio/soundcache.cpp | 4 + engines/ags/engine/media/audio/soundclip.cpp | 4 + engines/ags/engine/media/video/video.cpp | 22 +- .../ags/engine/platform/android/acpland.cpp | 4 + .../platform/base/agsplatformdriver.cpp | 48 ++- engines/ags/engine/platform/ios/acplios.cpp | 4 + engines/ags/engine/platform/linux/acpllnx.cpp | 4 + engines/ags/engine/platform/osx/acplmac.cpp | 4 + .../ags/engine/platform/windows/acplwin.cpp | 4 + .../debugging/namedpipesagsdebugger.cpp | 9 +- .../engine/platform/windows/gfx/ali3dd3d.cpp | 5 +- .../platform/windows/media/video/acwavi.cpp | 6 +- .../platform/windows/media/video/acwavi3d.cpp | 6 +- .../ags/engine/platform/windows/minidump.cpp | 4 + .../platform/windows/setup/winsetup.cpp | 5 +- .../platform/windows/win_ex_handling.cpp | 4 + engines/ags/engine/plugin/agsplugin.cpp | 18 +- engines/ags/engine/plugin/global_plugin.cpp | 174 +++++------ .../ags/engine/plugin/pluginobjectreader.cpp | 4 + engines/ags/engine/script/cc_error_engine.cpp | 0 engines/ags/engine/script/cc_instance.cpp | 4 + engines/ags/engine/script/executingscript.cpp | 10 +- engines/ags/engine/script/exports.cpp | 4 + .../ags/engine/script/runtimescriptvalue.cpp | 8 +- engines/ags/engine/script/script.cpp | 24 +- engines/ags/engine/script/script_api.cpp | 18 +- engines/ags/engine/script/script_engine.cpp | 9 +- engines/ags/engine/script/script_runtime.cpp | 42 ++- engines/ags/engine/script/systemimports.cpp | 9 +- engines/ags/shared/ac/audiocliptype.cpp | 4 + engines/ags/shared/ac/characterinfo.cpp | 4 + engines/ags/shared/ac/common.cpp | 4 + engines/ags/shared/ac/dialogtopic.cpp | 4 + .../ags/shared/ac/dynobj/scriptaudioclip.cpp | 4 + engines/ags/shared/ac/gamesetupstruct.cpp | 12 +- engines/ags/shared/ac/gamesetupstructbase.cpp | 4 + engines/ags/shared/ac/inventoryiteminfo.cpp | 4 + engines/ags/shared/ac/mousecursor.cpp | 4 + engines/ags/shared/ac/spritecache.cpp | 24 +- engines/ags/shared/ac/view.cpp | 6 +- engines/ags/shared/ac/wordsdictionary.cpp | 12 +- engines/ags/shared/core/asset.cpp | 2 + engines/ags/shared/core/assetmanager.cpp | 13 +- engines/ags/shared/debugging/debugmanager.cpp | 8 +- engines/ags/shared/font/fonts.cpp | 12 +- engines/ags/shared/font/ttffontrenderer.cpp | 6 +- engines/ags/shared/font/wfnfont.cpp | 24 +- engines/ags/shared/font/wfnfontrenderer.cpp | 6 +- engines/ags/shared/game/customproperties.cpp | 14 +- engines/ags/shared/game/interactions.cpp | 9 +- engines/ags/shared/game/main_game_file.cpp | 40 +-- engines/ags/shared/game/room_file.cpp | 45 +-- .../ags/shared/game/room_file_deprecated.cpp | 4 + engines/ags/shared/game/roomstruct.cpp | 36 +-- engines/ags/shared/gfx/allegrobitmap.cpp | 30 +- engines/ags/shared/gfx/bitmap.cpp | 18 +- engines/ags/shared/gui/guibutton.cpp | 17 +- engines/ags/shared/gui/guiinv.cpp | 3 + engines/ags/shared/gui/guilabel.cpp | 9 +- engines/ags/shared/gui/guilistbox.cpp | 21 +- engines/ags/shared/gui/guimain.cpp | 99 ++++--- engines/ags/shared/gui/guiobject.cpp | 32 +- engines/ags/shared/gui/guislider.cpp | 3 + engines/ags/shared/gui/guitextbox.cpp | 3 + engines/ags/shared/script/cc_error.cpp | 4 + engines/ags/shared/script/cc_options.cpp | 4 + engines/ags/shared/script/cc_script.cpp | 46 +-- engines/ags/shared/util/alignedstream.cpp | 4 +- engines/ags/shared/util/bufferedstream.cpp | 8 +- engines/ags/shared/util/compress.cpp | 17 +- engines/ags/shared/util/datastream.cpp | 2 + engines/ags/shared/util/directory.cpp | 6 +- engines/ags/shared/util/file.cpp | 2 + engines/ags/shared/util/filestream.cpp | 6 +- engines/ags/shared/util/geometry.cpp | 33 ++- engines/ags/shared/util/ini_util.cpp | 8 +- engines/ags/shared/util/inifile.cpp | 7 +- engines/ags/shared/util/lzw.cpp | 8 +- engines/ags/shared/util/misc.cpp | 27 +- engines/ags/shared/util/mutifilelib.cpp | 24 +- engines/ags/shared/util/path.cpp | 9 +- engines/ags/shared/util/proxystream.cpp | 2 + engines/ags/shared/util/stream.cpp | 2 + engines/ags/shared/util/string.cpp | 30 +- engines/ags/shared/util/string_utils.cpp | 3 + engines/ags/shared/util/textstreamreader.cpp | 2 + engines/ags/shared/util/textstreamwriter.cpp | 10 +- engines/ags/shared/util/version.cpp | 2 + engines/ags/shared/util/wgt2allg.cpp | 278 +++++++++--------- 276 files changed, 2801 insertions(+), 1769 deletions(-) delete mode 100644 engines/ags/engine/script/cc_error_engine.cpp diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp index e793a87cf61d..5d41da434047 100644 --- a/engines/ags/engine/ac/audiochannel.cpp +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -29,6 +29,8 @@ #include "script/runtimescriptvalue.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameState play; @@ -278,23 +280,23 @@ RuntimeScriptValue Sc_AudioChannel_SetSpeed(void *self, const RuntimeScriptValue } void RegisterAudioChannelAPI() { - ccAddExternalObjectFunction("AudioChannel::Seek^1", Sc_AudioChannel_Seek); - ccAddExternalObjectFunction("AudioChannel::SetRoomLocation^2", Sc_AudioChannel_SetRoomLocation); - ccAddExternalObjectFunction("AudioChannel::Stop^0", Sc_AudioChannel_Stop); - ccAddExternalObjectFunction("AudioChannel::get_ID", Sc_AudioChannel_GetID); - ccAddExternalObjectFunction("AudioChannel::get_IsPlaying", Sc_AudioChannel_GetIsPlaying); - ccAddExternalObjectFunction("AudioChannel::get_LengthMs", Sc_AudioChannel_GetLengthMs); - ccAddExternalObjectFunction("AudioChannel::get_Panning", Sc_AudioChannel_GetPanning); - ccAddExternalObjectFunction("AudioChannel::set_Panning", Sc_AudioChannel_SetPanning); - ccAddExternalObjectFunction("AudioChannel::get_PlayingClip", Sc_AudioChannel_GetPlayingClip); - ccAddExternalObjectFunction("AudioChannel::get_Position", Sc_AudioChannel_GetPosition); - ccAddExternalObjectFunction("AudioChannel::get_PositionMs", Sc_AudioChannel_GetPositionMs); - ccAddExternalObjectFunction("AudioChannel::get_Volume", Sc_AudioChannel_GetVolume); - ccAddExternalObjectFunction("AudioChannel::set_Volume", Sc_AudioChannel_SetVolume); - ccAddExternalObjectFunction("AudioChannel::get_Speed", Sc_AudioChannel_GetSpeed); - ccAddExternalObjectFunction("AudioChannel::set_Speed", Sc_AudioChannel_SetSpeed); + ccAddExternalObjectFunction("AudioChannel::Seek^1", Sc_AudioChannel_Seek); + ccAddExternalObjectFunction("AudioChannel::SetRoomLocation^2", Sc_AudioChannel_SetRoomLocation); + ccAddExternalObjectFunction("AudioChannel::Stop^0", Sc_AudioChannel_Stop); + ccAddExternalObjectFunction("AudioChannel::get_ID", Sc_AudioChannel_GetID); + ccAddExternalObjectFunction("AudioChannel::get_IsPlaying", Sc_AudioChannel_GetIsPlaying); + ccAddExternalObjectFunction("AudioChannel::get_LengthMs", Sc_AudioChannel_GetLengthMs); + ccAddExternalObjectFunction("AudioChannel::get_Panning", Sc_AudioChannel_GetPanning); + ccAddExternalObjectFunction("AudioChannel::set_Panning", Sc_AudioChannel_SetPanning); + ccAddExternalObjectFunction("AudioChannel::get_PlayingClip", Sc_AudioChannel_GetPlayingClip); + ccAddExternalObjectFunction("AudioChannel::get_Position", Sc_AudioChannel_GetPosition); + ccAddExternalObjectFunction("AudioChannel::get_PositionMs", Sc_AudioChannel_GetPositionMs); + ccAddExternalObjectFunction("AudioChannel::get_Volume", Sc_AudioChannel_GetVolume); + ccAddExternalObjectFunction("AudioChannel::set_Volume", Sc_AudioChannel_SetVolume); + ccAddExternalObjectFunction("AudioChannel::get_Speed", Sc_AudioChannel_GetSpeed); + ccAddExternalObjectFunction("AudioChannel::set_Speed", Sc_AudioChannel_SetSpeed); // For compatibility with Ahmet Kamil's (aka Gord10) custom engine - ccAddExternalObjectFunction("AudioChannel::SetSpeed^1", Sc_AudioChannel_SetSpeed); + ccAddExternalObjectFunction("AudioChannel::SetSpeed^1", Sc_AudioChannel_SetSpeed); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -312,3 +314,5 @@ void RegisterAudioChannelAPI() { ccAddExternalFunctionForPlugin("AudioChannel::get_Volume", (void *)AudioChannel_GetVolume); ccAddExternalFunctionForPlugin("AudioChannel::set_Volume", (void *)AudioChannel_SetVolume); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp index 2653c3aa26f2..993b72b1c6b8 100644 --- a/engines/ags/engine/ac/audioclip.cpp +++ b/engines/ags/engine/ac/audioclip.cpp @@ -28,6 +28,8 @@ #include "ac/dynobj/cc_audiochannel.h" #include "media/audio/audio_system.h" +namespace AGS3 { + extern GameSetupStruct game; extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; extern CCAudioChannel ccDynamicAudio; @@ -122,14 +124,14 @@ RuntimeScriptValue Sc_AudioClip_PlayQueued(void *self, const RuntimeScriptValue } void RegisterAudioClipAPI() { - ccAddExternalObjectFunction("AudioClip::Play^2", Sc_AudioClip_Play); - ccAddExternalObjectFunction("AudioClip::PlayFrom^3", Sc_AudioClip_PlayFrom); - ccAddExternalObjectFunction("AudioClip::PlayQueued^2", Sc_AudioClip_PlayQueued); - ccAddExternalObjectFunction("AudioClip::Stop^0", Sc_AudioClip_Stop); - ccAddExternalObjectFunction("AudioClip::get_ID", Sc_AudioClip_GetID); - ccAddExternalObjectFunction("AudioClip::get_FileType", Sc_AudioClip_GetFileType); - ccAddExternalObjectFunction("AudioClip::get_IsAvailable", Sc_AudioClip_GetIsAvailable); - ccAddExternalObjectFunction("AudioClip::get_Type", Sc_AudioClip_GetType); + ccAddExternalObjectFunction("AudioClip::Play^2", Sc_AudioClip_Play); + ccAddExternalObjectFunction("AudioClip::PlayFrom^3", Sc_AudioClip_PlayFrom); + ccAddExternalObjectFunction("AudioClip::PlayQueued^2", Sc_AudioClip_PlayQueued); + ccAddExternalObjectFunction("AudioClip::Stop^0", Sc_AudioClip_Stop); + ccAddExternalObjectFunction("AudioClip::get_ID", Sc_AudioClip_GetID); + ccAddExternalObjectFunction("AudioClip::get_FileType", Sc_AudioClip_GetFileType); + ccAddExternalObjectFunction("AudioClip::get_IsAvailable", Sc_AudioClip_GetIsAvailable); + ccAddExternalObjectFunction("AudioClip::get_Type", Sc_AudioClip_GetType); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -141,3 +143,5 @@ void RegisterAudioClipAPI() { ccAddExternalFunctionForPlugin("AudioClip::get_IsAvailable", (void *)AudioClip_GetIsAvailable); ccAddExternalFunctionForPlugin("AudioClip::get_Type", (void *)AudioClip_GetType); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp index 91f24fa8c632..469414fbeb13 100644 --- a/engines/ags/engine/ac/button.cpp +++ b/engines/ags/engine/ac/button.cpp @@ -32,6 +32,8 @@ #include "gui/animatingguibutton.h" #include "gui/guimain.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -213,7 +215,7 @@ int UpdateAnimatingButton(int bu) { animbuts[bu].frame = 0; // multi-loop anim, go back while ((animbuts[bu].loop > 0) && - (tview->loops[animbuts[bu].loop - 1].RunNextLoop())) + (tview->loops[animbuts[bu].loop - 1].RunNextLoop())) animbuts[bu].loop--; } else return 1; @@ -420,31 +422,31 @@ RuntimeScriptValue Sc_Button_GetView(void *self, const RuntimeScriptValue *param } void RegisterButtonAPI() { - ccAddExternalObjectFunction("Button::Animate^4", Sc_Button_Animate); - ccAddExternalObjectFunction("Button::Click^1", Sc_Button_Click); - ccAddExternalObjectFunction("Button::GetText^1", Sc_Button_GetText); - ccAddExternalObjectFunction("Button::SetText^1", Sc_Button_SetText); - ccAddExternalObjectFunction("Button::get_TextAlignment", Sc_Button_GetTextAlignment); - ccAddExternalObjectFunction("Button::set_TextAlignment", Sc_Button_SetTextAlignment); - ccAddExternalObjectFunction("Button::get_Animating", Sc_Button_GetAnimating); - ccAddExternalObjectFunction("Button::get_ClipImage", Sc_Button_GetClipImage); - ccAddExternalObjectFunction("Button::set_ClipImage", Sc_Button_SetClipImage); - ccAddExternalObjectFunction("Button::get_Font", Sc_Button_GetFont); - ccAddExternalObjectFunction("Button::set_Font", Sc_Button_SetFont); - ccAddExternalObjectFunction("Button::get_Frame", Sc_Button_GetFrame); - ccAddExternalObjectFunction("Button::get_Graphic", Sc_Button_GetGraphic); - ccAddExternalObjectFunction("Button::get_Loop", Sc_Button_GetLoop); + ccAddExternalObjectFunction("Button::Animate^4", Sc_Button_Animate); + ccAddExternalObjectFunction("Button::Click^1", Sc_Button_Click); + ccAddExternalObjectFunction("Button::GetText^1", Sc_Button_GetText); + ccAddExternalObjectFunction("Button::SetText^1", Sc_Button_SetText); + ccAddExternalObjectFunction("Button::get_TextAlignment", Sc_Button_GetTextAlignment); + ccAddExternalObjectFunction("Button::set_TextAlignment", Sc_Button_SetTextAlignment); + ccAddExternalObjectFunction("Button::get_Animating", Sc_Button_GetAnimating); + ccAddExternalObjectFunction("Button::get_ClipImage", Sc_Button_GetClipImage); + ccAddExternalObjectFunction("Button::set_ClipImage", Sc_Button_SetClipImage); + ccAddExternalObjectFunction("Button::get_Font", Sc_Button_GetFont); + ccAddExternalObjectFunction("Button::set_Font", Sc_Button_SetFont); + ccAddExternalObjectFunction("Button::get_Frame", Sc_Button_GetFrame); + ccAddExternalObjectFunction("Button::get_Graphic", Sc_Button_GetGraphic); + ccAddExternalObjectFunction("Button::get_Loop", Sc_Button_GetLoop); ccAddExternalObjectFunction("Button::get_MouseOverGraphic", Sc_Button_GetMouseOverGraphic); ccAddExternalObjectFunction("Button::set_MouseOverGraphic", Sc_Button_SetMouseOverGraphic); - ccAddExternalObjectFunction("Button::get_NormalGraphic", Sc_Button_GetNormalGraphic); - ccAddExternalObjectFunction("Button::set_NormalGraphic", Sc_Button_SetNormalGraphic); - ccAddExternalObjectFunction("Button::get_PushedGraphic", Sc_Button_GetPushedGraphic); - ccAddExternalObjectFunction("Button::set_PushedGraphic", Sc_Button_SetPushedGraphic); - ccAddExternalObjectFunction("Button::get_Text", Sc_Button_GetText_New); - ccAddExternalObjectFunction("Button::set_Text", Sc_Button_SetText); - ccAddExternalObjectFunction("Button::get_TextColor", Sc_Button_GetTextColor); - ccAddExternalObjectFunction("Button::set_TextColor", Sc_Button_SetTextColor); - ccAddExternalObjectFunction("Button::get_View", Sc_Button_GetView); + ccAddExternalObjectFunction("Button::get_NormalGraphic", Sc_Button_GetNormalGraphic); + ccAddExternalObjectFunction("Button::set_NormalGraphic", Sc_Button_SetNormalGraphic); + ccAddExternalObjectFunction("Button::get_PushedGraphic", Sc_Button_GetPushedGraphic); + ccAddExternalObjectFunction("Button::set_PushedGraphic", Sc_Button_SetPushedGraphic); + ccAddExternalObjectFunction("Button::get_Text", Sc_Button_GetText_New); + ccAddExternalObjectFunction("Button::set_Text", Sc_Button_SetText); + ccAddExternalObjectFunction("Button::get_TextColor", Sc_Button_GetTextColor); + ccAddExternalObjectFunction("Button::set_TextColor", Sc_Button_SetTextColor); + ccAddExternalObjectFunction("Button::get_View", Sc_Button_GetView); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -467,3 +469,5 @@ void RegisterButtonAPI() { ccAddExternalFunctionForPlugin("Button::get_TextColor", (void *)Button_GetTextColor); ccAddExternalFunctionForPlugin("Button::set_TextColor", (void *)Button_SetTextColor); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/cdaudio.cpp b/engines/ags/engine/ac/cdaudio.cpp index 99294b49a2bf..04feb2c3bc7d 100644 --- a/engines/ags/engine/ac/cdaudio.cpp +++ b/engines/ags/engine/ac/cdaudio.cpp @@ -23,6 +23,8 @@ #include "ac/cdaudio.h" #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + int use_cdplayer = 0; bool triedToUseCdAudioCommand = false; int need_to_stop_cd = 0; @@ -42,3 +44,5 @@ int cd_manager(int cmdd, int datt) { return platform->CDPlayerCommand(cmdd, datt); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index d1ef4162f673..34890ee440d2 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -71,6 +71,8 @@ #include "media/audio/audio_system.h" #include "ac/movelist.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -3867,3 +3869,5 @@ void RegisterCharacterAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api ccAddExternalFunctionForPlugin("Character::get_z", (void *)Character_GetZ); ccAddExternalFunctionForPlugin("Character::set_z", (void *)Character_SetZ); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/characterextras.cpp b/engines/ags/engine/ac/characterextras.cpp index 42c48cb39c9f..6915dca2bca5 100644 --- a/engines/ags/engine/ac/characterextras.cpp +++ b/engines/ags/engine/ac/characterextras.cpp @@ -23,6 +23,8 @@ #include "ac/characterextras.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; void CharacterExtras::ReadFromFile(Stream *in) { @@ -60,3 +62,5 @@ void CharacterExtras::WriteToFile(Stream *out) { out->WriteInt8(slow_move_counter); out->WriteInt16(animwait); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp index d404c382a8d8..e9e2bcff84cf 100644 --- a/engines/ags/engine/ac/characterinfo_engine.cpp +++ b/engines/ags/engine/ac/characterinfo_engine.cpp @@ -35,6 +35,8 @@ #include "main/update.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; extern ViewStruct *views; @@ -81,7 +83,7 @@ void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, in } // Make sure it doesn't flash up a blue cup - if (view < 0) ; + if (view < 0); else if (loop >= views[view].numLoops) loop = 0; @@ -135,8 +137,8 @@ int CharacterInfo::update_character_walking(CharacterExtras *chex) { if (wantloop < 0) wantloop = 7; if ((turnlooporder[wantloop] >= views[view].numLoops) || - (views[view].loops[turnlooporder[wantloop]].numFrames < 1) || - ((turnlooporder[wantloop] >= 4) && ((flags & CHF_NODIAGONAL) != 0))) { + (views[view].loops[turnlooporder[wantloop]].numFrames < 1) || + ((turnlooporder[wantloop] >= 4) && ((flags & CHF_NODIAGONAL) != 0))) { if (walking >= TURNING_BACKWARDS) wantloop--; else @@ -190,8 +192,8 @@ void CharacterInfo::update_character_moving(int &char_index, CharacterExtras *ch // to stop it being jumpy chex->xwas = x; chex->ywas = y; - x = ((x) - oldxp) / 2 + oldxp; - y = ((y) - oldyp) / 2 + oldyp; + x = ((x)-oldxp) / 2 + oldxp; + y = ((y)-oldyp) / 2 + oldyp; } else if (numSteps > 0) chex->xwas = INVALID_X; @@ -256,8 +258,8 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) { // not moving, but animating // idleleft is <0 while idle view is playing (.animating is 0) if (((animating != 0) || (idleleft < 0)) && - ((walking == 0) || ((flags & CHF_MOVENOTWALK) != 0)) && - (room == displayed_room)) { + ((walking == 0) || ((flags & CHF_MOVENOTWALK) != 0)) && + (room == displayed_room)) { doing_nothing = 0; // idle anim doesn't count as doing something if (idleleft < 0) @@ -271,7 +273,7 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) { // closed mouth at end of sentence // NOTE: standard lip-sync is synchronized with text timer, not voice file if (play.speech_in_post_state || - ((play.messagetime >= 0) && (play.messagetime < play.close_mouth_speech_time))) + ((play.messagetime >= 0) && (play.messagetime < play.close_mouth_speech_time))) frame = 0; if (frame != fraa) { @@ -288,9 +290,9 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) { if (frame < 0) { // if the previous loop is a Run Next Loop one, go back to it if ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) { + (views[view].loops[loop - 1].RunNextLoop())) { - loop --; + loop--; frame = views[view].loops[loop].numFrames - 1; } else if (animating & CHANIM_REPEAT) { @@ -309,10 +311,10 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) { frame++; if ((aa == char_speaking) && - (play.speech_in_post_state || - ((!play.speech_has_voice) && - (play.close_mouth_speech_time > 0) && - (play.messagetime < play.close_mouth_speech_time)))) { + (play.speech_in_post_state || + ((!play.speech_has_voice) && + (play.close_mouth_speech_time > 0) && + (play.messagetime < play.close_mouth_speech_time)))) { // finished talking - stop animation animating = 0; frame = 0; @@ -344,7 +346,7 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) { // if it's a multi-loop animation, go back to start if (play.no_multiloop_repeat == 0) { while ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) + (views[view].loops[loop - 1].RunNextLoop())) loop--; } } @@ -376,9 +378,9 @@ void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *follo else if ((following >= 0) && (doing_nothing == 1)) { short distaway = (followinfo >> 8) & 0x00ff; // no character in this room - if ((game.chars[following].on == 0) || (on == 0)) ; + if ((game.chars[following].on == 0) || (on == 0)); else if (room < 0) { - room ++; + room++; if (room == 0) { // appear in the new room room = game.chars[following].room; @@ -387,10 +389,10 @@ void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *follo } } // wait a bit, so we're not constantly walking - else if (Random(100) < (followinfo & 0x00ff)) ; + else if (Random(100) < (followinfo & 0x00ff)); // the followed character has changed room else if ((room != game.chars[following].room) - && (game.chars[following].on == 0)) + && (game.chars[following].on == 0)) ; // do nothing if the player isn't visible else if (room != game.chars[following].room) { prevroom = room; @@ -425,15 +427,15 @@ void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *follo // if the characetr is following another character and // neither is in the current room, don't try to move } else if ((abs(game.chars[following].x - x) > distaway + 30) | - (abs(game.chars[following].y - y) > distaway + 30) | - ((followinfo & 0x00ff) == 0)) { + (abs(game.chars[following].y - y) > distaway + 30) | + ((followinfo & 0x00ff) == 0)) { // in same room int goxoffs = (Random(50) - 25); // make sure he's not standing on top of the other man if (goxoffs < 0) goxoffs -= distaway; else goxoffs += distaway; walk_character(aa, game.chars[following].x + goxoffs, - game.chars[following].y + (Random(50) - 25), 0, true); + game.chars[following].y + (Random(50) - 25), 0, true); doing_nothing = 0; } } @@ -441,11 +443,11 @@ void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *follo void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_nothing) { // no idle animation, so skip this bit - if (idleview < 1) ; + if (idleview < 1); // currently playing idle anim - else if (idleleft < 0) ; + else if (idleleft < 0); // not in the current room - else if (room != displayed_room) ; + else if (room != displayed_room); // they are moving or animating (or the view is locked), so // reset idle timeout else if ((doing_nothing == 0) || ((flags & CHF_FIXVIEW) != 0)) @@ -478,10 +480,12 @@ void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_noth useloop = 0; animate_character(this, useloop, - animspeed + 5, (idletime == 0) ? 1 : 0, 1); + animspeed + 5, (idletime == 0) ? 1 : 0, 1); // don't set Animating while the idle anim plays animating = 0; } } // end do idle animation } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/datetime.cpp b/engines/ags/engine/ac/datetime.cpp index a4874cb45d24..982180272025 100644 --- a/engines/ags/engine/ac/datetime.cpp +++ b/engines/ags/engine/ac/datetime.cpp @@ -25,6 +25,8 @@ #include "platform/base/agsplatformdriver.h" #include "script/runtimescriptvalue.h" +namespace AGS3 { + ScriptDateTime *DateTime_Now_Core() { ScriptDateTime *sdt = new ScriptDateTime(); @@ -118,14 +120,14 @@ RuntimeScriptValue Sc_DateTime_GetRawTime(void *self, const RuntimeScriptValue * } void RegisterDateTimeAPI() { - ccAddExternalStaticFunction("DateTime::get_Now", Sc_DateTime_Now); + ccAddExternalStaticFunction("DateTime::get_Now", Sc_DateTime_Now); ccAddExternalObjectFunction("DateTime::get_DayOfMonth", Sc_DateTime_GetDayOfMonth); - ccAddExternalObjectFunction("DateTime::get_Hour", Sc_DateTime_GetHour); - ccAddExternalObjectFunction("DateTime::get_Minute", Sc_DateTime_GetMinute); - ccAddExternalObjectFunction("DateTime::get_Month", Sc_DateTime_GetMonth); - ccAddExternalObjectFunction("DateTime::get_RawTime", Sc_DateTime_GetRawTime); - ccAddExternalObjectFunction("DateTime::get_Second", Sc_DateTime_GetSecond); - ccAddExternalObjectFunction("DateTime::get_Year", Sc_DateTime_GetYear); + ccAddExternalObjectFunction("DateTime::get_Hour", Sc_DateTime_GetHour); + ccAddExternalObjectFunction("DateTime::get_Minute", Sc_DateTime_GetMinute); + ccAddExternalObjectFunction("DateTime::get_Month", Sc_DateTime_GetMonth); + ccAddExternalObjectFunction("DateTime::get_RawTime", Sc_DateTime_GetRawTime); + ccAddExternalObjectFunction("DateTime::get_Second", Sc_DateTime_GetSecond); + ccAddExternalObjectFunction("DateTime::get_Year", Sc_DateTime_GetYear); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -138,3 +140,5 @@ void RegisterDateTimeAPI() { ccAddExternalFunctionForPlugin("DateTime::get_Second", (void *)DateTime_GetSecond); ccAddExternalFunctionForPlugin("DateTime::get_Year", (void *)DateTime_GetYear); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index c5f60cc601e8..6d1f3e98b07a 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -60,6 +60,8 @@ #include "ac/mouse.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -1226,3 +1228,5 @@ void RegisterDialogAPI() { ccAddExternalFunctionForPlugin("Dialog::SetOptionState^2", (void *)Dialog_SetOptionState); ccAddExternalFunctionForPlugin("Dialog::Start^0", (void *)Dialog_Start); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dialogoptionsrendering.cpp b/engines/ags/engine/ac/dialogoptionsrendering.cpp index 499ed2104f32..39b2b2c46651 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dialogoptionsrendering.cpp @@ -28,6 +28,8 @@ #include "script/runtimescriptvalue.h" #include "ac/dynobj/cc_dialog.h" +namespace AGS3 { + extern DialogTopic *dialog; extern CCDialog ccDynamicDialog; @@ -248,28 +250,28 @@ RuntimeScriptValue Sc_DialogOptionsRendering_SetHasAlphaChannel(void *self, cons void RegisterDialogOptionsRenderingAPI() { - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::Update^0", Sc_DialogOptionsRendering_Update); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::RunActiveOption^0", Sc_DialogOptionsRendering_RunActiveOption); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ActiveOptionID", Sc_DialogOptionsRendering_GetActiveOptionID); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ActiveOptionID", Sc_DialogOptionsRendering_SetActiveOptionID); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_DialogToRender", Sc_DialogOptionsRendering_GetDialogToRender); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Height", Sc_DialogOptionsRendering_GetHeight); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Height", Sc_DialogOptionsRendering_SetHeight); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxX", Sc_DialogOptionsRendering_GetParserTextboxX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxX", Sc_DialogOptionsRendering_SetParserTextboxX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxY", Sc_DialogOptionsRendering_GetParserTextboxY); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxY", Sc_DialogOptionsRendering_SetParserTextboxY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::Update^0", Sc_DialogOptionsRendering_Update); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::RunActiveOption^0", Sc_DialogOptionsRendering_RunActiveOption); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ActiveOptionID", Sc_DialogOptionsRendering_GetActiveOptionID); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ActiveOptionID", Sc_DialogOptionsRendering_SetActiveOptionID); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_DialogToRender", Sc_DialogOptionsRendering_GetDialogToRender); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Height", Sc_DialogOptionsRendering_GetHeight); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Height", Sc_DialogOptionsRendering_SetHeight); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxX", Sc_DialogOptionsRendering_GetParserTextboxX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxX", Sc_DialogOptionsRendering_SetParserTextboxX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxY", Sc_DialogOptionsRendering_GetParserTextboxY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxY", Sc_DialogOptionsRendering_SetParserTextboxY); ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_ParserTextBoxWidth", Sc_DialogOptionsRendering_GetParserTextboxWidth); ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_ParserTextBoxWidth", Sc_DialogOptionsRendering_SetParserTextboxWidth); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Surface", Sc_DialogOptionsRendering_GetSurface); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Width", Sc_DialogOptionsRendering_GetWidth); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Width", Sc_DialogOptionsRendering_SetWidth); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_X", Sc_DialogOptionsRendering_GetX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_X", Sc_DialogOptionsRendering_SetX); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Y", Sc_DialogOptionsRendering_GetY); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Y", Sc_DialogOptionsRendering_SetY); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_HasAlphaChannel", Sc_DialogOptionsRendering_GetHasAlphaChannel); - ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_HasAlphaChannel", Sc_DialogOptionsRendering_SetHasAlphaChannel); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Surface", Sc_DialogOptionsRendering_GetSurface); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Width", Sc_DialogOptionsRendering_GetWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Width", Sc_DialogOptionsRendering_SetWidth); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_X", Sc_DialogOptionsRendering_GetX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_X", Sc_DialogOptionsRendering_SetX); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_Y", Sc_DialogOptionsRendering_GetY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_Y", Sc_DialogOptionsRendering_SetY); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::get_HasAlphaChannel", Sc_DialogOptionsRendering_GetHasAlphaChannel); + ccAddExternalObjectFunction("DialogOptionsRenderingInfo::set_HasAlphaChannel", Sc_DialogOptionsRendering_SetHasAlphaChannel); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -292,3 +294,5 @@ void RegisterDialogOptionsRenderingAPI() { ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::get_Y", (void *)DialogOptionsRendering_GetY); ccAddExternalFunctionForPlugin("DialogOptionsRenderingInfo::set_Y", (void *)DialogOptionsRendering_SetY); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp index 20255b1e92bb..017c573034b1 100644 --- a/engines/ags/engine/ac/display.cpp +++ b/engines/ags/engine/ac/display.cpp @@ -55,6 +55,8 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Shared::BitmapHelper; @@ -134,7 +136,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int } const Rect &ui_view = play.GetUIViewport(); - if (xx == OVR_AUTOPLACE) ; + if (xx == OVR_AUTOPLACE); // centre text in middle of screen else if (yy < 0) yy = ui_view.GetHeight() / 2 - disp.fulltxtheight / 2 - padding; // speech, so it wants to be above the character's head @@ -185,7 +187,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int int adjustedXX = xx; int adjustedYY = yy; - if ((strlen(todis) < 1) || (strcmp(todis, " ") == 0) || (wii == 0)) ; + if ((strlen(todis) < 1) || (strcmp(todis, " ") == 0) || (wii == 0)); // if it's an empty speech line, don't draw anything else if (asspch) { //text_color = ds->GetCompatibleColor(12); int ttxleft = 0, ttxtop = paddingScaled, oriwid = wii - padding * 2; @@ -215,7 +217,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int // centre the text if (asspch < 0) { if ((usingGui >= 0) && - ((game.options[OPT_SPEECHTYPE] >= 2) || (isThought))) + ((game.options[OPT_SPEECHTYPE] >= 2) || (isThought))) text_color = text_window_ds->GetCompatibleColor(guis[usingGui].FgColor); else text_color = text_window_ds->GetCompatibleColor(-asspch); @@ -451,10 +453,10 @@ void wouttextxy_AutoOutline_Semitransparent2Opaque(Bitmap *map) { int const transparency = geta(px); if (0 < transparency && transparency < 255) px = makeacol32( - getr32(px), - getg32(px), - getb32(px), - std::min(85 + transparency * 2, 255)); + getr32(px), + getg32(px), + getb32(px), + std::min(85 + transparency * 2, 255)); } } } @@ -488,7 +490,7 @@ void wouttextxy_AutoOutline(Bitmap *ds, size_t font, int32_t color, const char * wouttextxy_AutoOutline_Semitransparent2Opaque(texx_stencil); #endif - void(Bitmap::*pfn_drawstencil)(Bitmap * src, int dst_x, int dst_y); + void(Bitmap:: * pfn_drawstencil)(Bitmap * src, int dst_x, int dst_y); if (antialias) { // NOTE: we must set out blender AFTER wouttextxy, or it will be overidden set_argb2any_blender(); @@ -512,8 +514,8 @@ void wouttextxy_AutoOutline(Bitmap *ds, size_t font, int32_t color, const char * // extend the outline stencil to the top and bottom for (int y_diff = largest_y_diff_reached_so_far + 1; - y_diff <= thickness && y_diff * y_diff <= y_term_limit; - y_diff++) { + y_diff <= thickness && y_diff * y_diff <= y_term_limit; + y_diff++) { (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness - y_diff); if (y_diff > 0) (outline_stencil.*pfn_drawstencil)(&texx_stencil, 0, thickness + y_diff); @@ -568,8 +570,8 @@ int getfontheight_outlined(int font) { int getfontspacing_outlined(int font) { return use_default_linespacing(font) ? - getfontheight_outlined(font) : - getfontlinespacing(font); + getfontheight_outlined(font) : + getfontlinespacing(font); } int getfontlinegap(int font) { @@ -629,9 +631,9 @@ void draw_button_background(Bitmap *ds, int xx1, int yy1, int xx2, int yy2, GUIM int topBottomHeight = game.SpriteInfos[get_but_pic(iep, 6)].Height; if (iep->BgImage > 0) { if ((loaded_game_file_version <= kGameVersion_272) // 2.xx - && (spriteset[iep->BgImage]->GetWidth() == 1) - && (spriteset[iep->BgImage]->GetHeight() == 1) - && (*((unsigned int *)spriteset[iep->BgImage]->GetData()) == 0x00FF00FF)) { + && (spriteset[iep->BgImage]->GetWidth() == 1) + && (spriteset[iep->BgImage]->GetHeight() == 1) + && (*((unsigned int *)spriteset[iep->BgImage]->GetData()) == 0x00FF00FF)) { // Don't draw fully transparent dummy GUI backgrounds } else { // offset the background image and clip it so that it is drawn @@ -681,7 +683,7 @@ int get_textwindow_border_width(int twgui) { quit("!GUI set as text window but is not actually a text window GUI"); int borwid = game.SpriteInfos[get_but_pic(&guis[twgui], 4)].Width + - game.SpriteInfos[get_but_pic(&guis[twgui], 5)].Width; + game.SpriteInfos[get_but_pic(&guis[twgui], 5)].Width; return borwid; } @@ -713,7 +715,7 @@ int get_textwindow_padding(int ifnum) { } void draw_text_window(Bitmap **text_window_ds, bool should_free_ds, - int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum) { + int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum) { Bitmap *ds = *text_window_ds; if (ifnum < 0) @@ -756,7 +758,7 @@ void draw_text_window(Bitmap **text_window_ds, bool should_free_ds, } void draw_text_window_and_bar(Bitmap **text_window_ds, bool should_free_ds, - int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum) { + int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum) { draw_text_window(text_window_ds, should_free_ds, xins, yins, xx, yy, wii, set_text_color, ovrheight, ifnum); @@ -792,3 +794,5 @@ void draw_text_window_and_bar(Bitmap **text_window_ds, bool should_free_ds, } else if (topBar.wantIt) topBar.wantIt = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index b6ed493c2da5..374c218ba7b2 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -71,6 +71,8 @@ #include "media/audio/audio_system.h" #include "ac/game.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -2333,3 +2335,5 @@ void render_graphics(IDriverDependantBitmap *extraBitmap, int extraX, int extraY screen_is_dirty = false; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index 46bb1a129898..917b4cd0eafa 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -52,6 +52,8 @@ #include "gfx/bitmap.h" #include "util/scaling.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -444,3 +446,5 @@ void update_room_invreg_and_reset(int view_index, Bitmap *ds, Bitmap *src, bool update_invalid_region(ds, src, RoomCamRects[view_index], no_transform); RoomCamRects[view_index].Reset(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp index c6a8cfacd245..d4fb8cd14b3e 100644 --- a/engines/ags/engine/ac/drawingsurface.cpp +++ b/engines/ags/engine/ac/drawingsurface.cpp @@ -42,6 +42,8 @@ #include "gfx/gfx_def.h" #include "gfx/gfx_util.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -90,7 +92,7 @@ void DrawingSurface_Release(ScriptDrawingSurface *sds) { } for (tt = 0; tt < game.numgui; tt++) { if ((guis[tt].BgImage == sds->dynamicSpriteNumber) && - (guis[tt].IsDisplayed())) { + (guis[tt].IsDisplayed())) { guis_need_update = 1; break; } @@ -143,7 +145,7 @@ ScriptDrawingSurface *DrawingSurface_CreateCopy(ScriptDrawingSurface *sds) { } void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src, int dst_x, int dst_y, int trans, int dst_width, int dst_height, - int src_x, int src_y, int src_width, int src_height, int sprite_id, bool src_has_alpha) { + int src_x, int src_y, int src_width, int src_height, int sprite_id, bool src_has_alpha) { Bitmap *ds = sds->GetBitmapSurface(); if (src == ds) quit("!DrawingSurface.DrawImage: cannot draw onto itself"); @@ -186,7 +188,7 @@ void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src, int ds } if (dst_x >= ds->GetWidth() || dst_x + dst_width <= 0 || dst_y >= ds->GetHeight() || dst_y + dst_height <= 0 || - src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0) + src_x >= src->GetWidth() || src_x + src_width <= 0 || src_y >= src->GetHeight() || src_y + src_height <= 0) return; // source or destination rects lie completely off surface // Clamp the source rect to the valid limits to prevent exceptions (ignore dest, bitmap drawing deals with that) Math::ClampLength(src_x, src_width, 0, src->GetWidth()); @@ -196,12 +198,12 @@ void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src, int ds // if simplier blit/draw_sprite could be called (no translucency with alpha channel). bool needToFreeBitmap = false; if (dst_width != src->GetWidth() || dst_height != src->GetHeight() || - src_width != src->GetWidth() || src_height != src->GetHeight()) { + src_width != src->GetWidth() || src_height != src->GetHeight()) { // Resize and/or partial copy specified Bitmap *newPic = BitmapHelper::CreateBitmap(dst_width, dst_height, src->GetColorDepth()); newPic->StretchBlt(src, - RectWH(src_x, src_y, src_width, src_height), - RectWH(0, 0, dst_width, dst_height)); + RectWH(src_x, src_y, src_width, src_height), + RectWH(0, 0, dst_width, dst_height)); src = newPic; needToFreeBitmap = true; @@ -219,7 +221,7 @@ void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src, int ds } draw_sprite_support_alpha(ds, sds->hasAlphaChannel != 0, dst_x, dst_y, src, src_has_alpha, - kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans)); + kBlendMode_Alpha, GfxDef::Trans100ToAlpha255(trans)); sds->FinishedDrawing(); @@ -228,11 +230,11 @@ void DrawingSurface_DrawImageImpl(ScriptDrawingSurface *sds, Bitmap *src, int ds } void DrawingSurface_DrawImageEx(ScriptDrawingSurface *sds, int dst_x, int dst_y, int slot, int trans, int dst_width, int dst_height, - int src_x, int src_y, int src_width, int src_height) { + int src_x, int src_y, int src_width, int src_height) { if ((slot < 0) || (spriteset[slot] == nullptr)) quit("!DrawingSurface.DrawImage: invalid sprite slot number specified"); DrawingSurface_DrawImageImpl(sds, spriteset[slot], dst_x, dst_y, trans, dst_width, dst_height, - src_x, src_y, src_width, src_height, slot, (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); + src_x, src_y, src_width, src_height, slot, (game.SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0); } void DrawingSurface_DrawImage(ScriptDrawingSurface *sds, int xx, int yy, int slot, int trans, int width, int height) { @@ -240,10 +242,10 @@ void DrawingSurface_DrawImage(ScriptDrawingSurface *sds, int xx, int yy, int slo } void DrawingSurface_DrawSurfaceEx(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans, - int dst_x, int dst_y, int dst_width, int dst_height, - int src_x, int src_y, int src_width, int src_height) { + int dst_x, int dst_y, int dst_width, int dst_height, + int src_x, int src_y, int src_width, int src_height) { DrawingSurface_DrawImageImpl(target, source->GetBitmapSurface(), dst_x, dst_y, trans, dst_width, dst_height, - src_x, src_y, src_width, src_height, -1, source->hasAlphaChannel); + src_x, src_y, src_width, src_height, -1, source->hasAlphaChannel); } void DrawingSurface_DrawSurface(ScriptDrawingSurface *target, ScriptDrawingSurface *source, int trans) { @@ -472,7 +474,7 @@ RuntimeScriptValue Sc_DrawingSurface_DrawImage_6(void *self, const RuntimeScript RuntimeScriptValue Sc_DrawingSurface_DrawImage(void *self, const RuntimeScriptValue *params, int32_t param_count) { ASSERT_OBJ_PARAM_COUNT(METHOD, 10); DrawingSurface_DrawImageEx((ScriptDrawingSurface *)self, params[0].IValue, params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, - params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); + params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); return RuntimeScriptValue((int32_t)0); } @@ -520,8 +522,8 @@ RuntimeScriptValue Sc_DrawingSurface_DrawSurface_2(void *self, const RuntimeScri RuntimeScriptValue Sc_DrawingSurface_DrawSurface(void *self, const RuntimeScriptValue *params, int32_t param_count) { ASSERT_OBJ_PARAM_COUNT(METHOD, 10); DrawingSurface_DrawSurfaceEx((ScriptDrawingSurface *)self, (ScriptDrawingSurface *)params[0].Ptr, - params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, - params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); + params[1].IValue, params[2].IValue, params[3].IValue, params[4].IValue, params[5].IValue, + params[6].IValue, params[7].IValue, params[8].IValue, params[9].IValue); return RuntimeScriptValue((int32_t)0); } @@ -583,31 +585,31 @@ void ScPl_DrawingSurface_DrawString(ScriptDrawingSurface *sds, int xx, int yy, i } void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) { - ccAddExternalObjectFunction("DrawingSurface::Clear^1", Sc_DrawingSurface_Clear); - ccAddExternalObjectFunction("DrawingSurface::CreateCopy^0", Sc_DrawingSurface_CreateCopy); - ccAddExternalObjectFunction("DrawingSurface::DrawCircle^3", Sc_DrawingSurface_DrawCircle); - ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage_6); - ccAddExternalObjectFunction("DrawingSurface::DrawImage^10", Sc_DrawingSurface_DrawImage); - ccAddExternalObjectFunction("DrawingSurface::DrawLine^5", Sc_DrawingSurface_DrawLine); + ccAddExternalObjectFunction("DrawingSurface::Clear^1", Sc_DrawingSurface_Clear); + ccAddExternalObjectFunction("DrawingSurface::CreateCopy^0", Sc_DrawingSurface_CreateCopy); + ccAddExternalObjectFunction("DrawingSurface::DrawCircle^3", Sc_DrawingSurface_DrawCircle); + ccAddExternalObjectFunction("DrawingSurface::DrawImage^6", Sc_DrawingSurface_DrawImage_6); + ccAddExternalObjectFunction("DrawingSurface::DrawImage^10", Sc_DrawingSurface_DrawImage); + ccAddExternalObjectFunction("DrawingSurface::DrawLine^5", Sc_DrawingSurface_DrawLine); ccAddExternalObjectFunction("DrawingSurface::DrawMessageWrapped^5", Sc_DrawingSurface_DrawMessageWrapped); - ccAddExternalObjectFunction("DrawingSurface::DrawPixel^2", Sc_DrawingSurface_DrawPixel); - ccAddExternalObjectFunction("DrawingSurface::DrawRectangle^4", Sc_DrawingSurface_DrawRectangle); - ccAddExternalObjectFunction("DrawingSurface::DrawString^104", Sc_DrawingSurface_DrawString); + ccAddExternalObjectFunction("DrawingSurface::DrawPixel^2", Sc_DrawingSurface_DrawPixel); + ccAddExternalObjectFunction("DrawingSurface::DrawRectangle^4", Sc_DrawingSurface_DrawRectangle); + ccAddExternalObjectFunction("DrawingSurface::DrawString^104", Sc_DrawingSurface_DrawString); if (base_api < kScriptAPI_v350) ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped_Old); else ccAddExternalObjectFunction("DrawingSurface::DrawStringWrapped^6", Sc_DrawingSurface_DrawStringWrapped); - ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface_2); - ccAddExternalObjectFunction("DrawingSurface::DrawSurface^10", Sc_DrawingSurface_DrawSurface); - ccAddExternalObjectFunction("DrawingSurface::DrawTriangle^6", Sc_DrawingSurface_DrawTriangle); - ccAddExternalObjectFunction("DrawingSurface::GetPixel^2", Sc_DrawingSurface_GetPixel); - ccAddExternalObjectFunction("DrawingSurface::Release^0", Sc_DrawingSurface_Release); - ccAddExternalObjectFunction("DrawingSurface::get_DrawingColor", Sc_DrawingSurface_GetDrawingColor); - ccAddExternalObjectFunction("DrawingSurface::set_DrawingColor", Sc_DrawingSurface_SetDrawingColor); - ccAddExternalObjectFunction("DrawingSurface::get_Height", Sc_DrawingSurface_GetHeight); + ccAddExternalObjectFunction("DrawingSurface::DrawSurface^2", Sc_DrawingSurface_DrawSurface_2); + ccAddExternalObjectFunction("DrawingSurface::DrawSurface^10", Sc_DrawingSurface_DrawSurface); + ccAddExternalObjectFunction("DrawingSurface::DrawTriangle^6", Sc_DrawingSurface_DrawTriangle); + ccAddExternalObjectFunction("DrawingSurface::GetPixel^2", Sc_DrawingSurface_GetPixel); + ccAddExternalObjectFunction("DrawingSurface::Release^0", Sc_DrawingSurface_Release); + ccAddExternalObjectFunction("DrawingSurface::get_DrawingColor", Sc_DrawingSurface_GetDrawingColor); + ccAddExternalObjectFunction("DrawingSurface::set_DrawingColor", Sc_DrawingSurface_SetDrawingColor); + ccAddExternalObjectFunction("DrawingSurface::get_Height", Sc_DrawingSurface_GetHeight); ccAddExternalObjectFunction("DrawingSurface::get_UseHighResCoordinates", Sc_DrawingSurface_GetUseHighResCoordinates); ccAddExternalObjectFunction("DrawingSurface::set_UseHighResCoordinates", Sc_DrawingSurface_SetUseHighResCoordinates); - ccAddExternalObjectFunction("DrawingSurface::get_Width", Sc_DrawingSurface_GetWidth); + ccAddExternalObjectFunction("DrawingSurface::get_Width", Sc_DrawingSurface_GetWidth); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -635,3 +637,5 @@ void RegisterDrawingSurfaceAPI(ScriptAPIVersion base_api, ScriptAPIVersion compa ccAddExternalFunctionForPlugin("DrawingSurface::set_UseHighResCoordinates", (void *)DrawingSurface_SetUseHighResCoordinates); ccAddExternalFunctionForPlugin("DrawingSurface::get_Width", (void *)DrawingSurface_GetWidth); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp index ef798801bf67..1e1a37db215e 100644 --- a/engines/ags/engine/ac/dynamicsprite.cpp +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -41,6 +41,8 @@ #include "gfx/graphicsdriver.h" #include "script/runtimescriptvalue.h" +namespace AGS3 { + using namespace Shared; using namespace Engine; @@ -114,8 +116,8 @@ void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height) { // resize the sprite to the requested size Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); newPic->StretchBlt(spriteset[sds->slot], - RectWH(0, 0, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height), - RectWH(0, 0, width, height)); + RectWH(0, 0, game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height), + RectWH(0, 0, width, height)); delete spriteset[sds->slot]; @@ -150,7 +152,7 @@ void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSpri quit("!DynamicSprite.CopyTransparencyMask: sprite has been deleted"); if ((game.SpriteInfos[sds->slot].Width != game.SpriteInfos[sourceSprite].Width) || - (game.SpriteInfos[sds->slot].Height != game.SpriteInfos[sourceSprite].Height)) { + (game.SpriteInfos[sds->slot].Height != game.SpriteInfos[sourceSprite].Height)) { quit("!DynamicSprite.CopyTransparencyMask: sprites are not the same size"); } @@ -246,7 +248,7 @@ void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int he // rotate the sprite about its centre // (+ width%2 fixes one pixel offset problem) newPic->RotateBlt(spriteset[sds->slot], width / 2 + width % 2, height / 2, - game.SpriteInfos[sds->slot].Width / 2, game.SpriteInfos[sds->slot].Height / 2, itofix(angle)); + game.SpriteInfos[sds->slot].Width / 2, game.SpriteInfos[sds->slot].Height / 2, itofix(angle)); delete spriteset[sds->slot]; @@ -413,7 +415,7 @@ ScriptDynamicSprite *DynamicSprite_CreateFromBackground(int frame, int x1, int y width = play.room_width; height = play.room_height; } else if ((x1 < 0) || (y1 < 0) || (width < 1) || (height < 1) || - (x1 + width > play.room_width) || (y1 + height > play.room_height)) + (x1 + width > play.room_width) || (y1 + height > play.room_height)) quit("!DynamicSprite.CreateFromBackground: invalid co-ordinates specified"); data_to_game_coords(&x1, &y1); @@ -618,28 +620,28 @@ RuntimeScriptValue Sc_DynamicSprite_CreateFromScreenShot(const RuntimeScriptValu void RegisterDynamicSpriteAPI() { - ccAddExternalObjectFunction("DynamicSprite::ChangeCanvasSize^4", Sc_DynamicSprite_ChangeCanvasSize); - ccAddExternalObjectFunction("DynamicSprite::CopyTransparencyMask^1", Sc_DynamicSprite_CopyTransparencyMask); - ccAddExternalObjectFunction("DynamicSprite::Crop^4", Sc_DynamicSprite_Crop); - ccAddExternalObjectFunction("DynamicSprite::Delete", Sc_DynamicSprite_Delete); - ccAddExternalObjectFunction("DynamicSprite::Flip^1", Sc_DynamicSprite_Flip); - ccAddExternalObjectFunction("DynamicSprite::GetDrawingSurface^0", Sc_DynamicSprite_GetDrawingSurface); - ccAddExternalObjectFunction("DynamicSprite::Resize^2", Sc_DynamicSprite_Resize); - ccAddExternalObjectFunction("DynamicSprite::Rotate^3", Sc_DynamicSprite_Rotate); - ccAddExternalObjectFunction("DynamicSprite::SaveToFile^1", Sc_DynamicSprite_SaveToFile); - ccAddExternalObjectFunction("DynamicSprite::Tint^5", Sc_DynamicSprite_Tint); - ccAddExternalObjectFunction("DynamicSprite::get_ColorDepth", Sc_DynamicSprite_GetColorDepth); - ccAddExternalObjectFunction("DynamicSprite::get_Graphic", Sc_DynamicSprite_GetGraphic); - ccAddExternalObjectFunction("DynamicSprite::get_Height", Sc_DynamicSprite_GetHeight); - ccAddExternalObjectFunction("DynamicSprite::get_Width", Sc_DynamicSprite_GetWidth); - ccAddExternalStaticFunction("DynamicSprite::Create^3", Sc_DynamicSprite_Create); - ccAddExternalStaticFunction("DynamicSprite::CreateFromBackground", Sc_DynamicSprite_CreateFromBackground); + ccAddExternalObjectFunction("DynamicSprite::ChangeCanvasSize^4", Sc_DynamicSprite_ChangeCanvasSize); + ccAddExternalObjectFunction("DynamicSprite::CopyTransparencyMask^1", Sc_DynamicSprite_CopyTransparencyMask); + ccAddExternalObjectFunction("DynamicSprite::Crop^4", Sc_DynamicSprite_Crop); + ccAddExternalObjectFunction("DynamicSprite::Delete", Sc_DynamicSprite_Delete); + ccAddExternalObjectFunction("DynamicSprite::Flip^1", Sc_DynamicSprite_Flip); + ccAddExternalObjectFunction("DynamicSprite::GetDrawingSurface^0", Sc_DynamicSprite_GetDrawingSurface); + ccAddExternalObjectFunction("DynamicSprite::Resize^2", Sc_DynamicSprite_Resize); + ccAddExternalObjectFunction("DynamicSprite::Rotate^3", Sc_DynamicSprite_Rotate); + ccAddExternalObjectFunction("DynamicSprite::SaveToFile^1", Sc_DynamicSprite_SaveToFile); + ccAddExternalObjectFunction("DynamicSprite::Tint^5", Sc_DynamicSprite_Tint); + ccAddExternalObjectFunction("DynamicSprite::get_ColorDepth", Sc_DynamicSprite_GetColorDepth); + ccAddExternalObjectFunction("DynamicSprite::get_Graphic", Sc_DynamicSprite_GetGraphic); + ccAddExternalObjectFunction("DynamicSprite::get_Height", Sc_DynamicSprite_GetHeight); + ccAddExternalObjectFunction("DynamicSprite::get_Width", Sc_DynamicSprite_GetWidth); + ccAddExternalStaticFunction("DynamicSprite::Create^3", Sc_DynamicSprite_Create); + ccAddExternalStaticFunction("DynamicSprite::CreateFromBackground", Sc_DynamicSprite_CreateFromBackground); ccAddExternalStaticFunction("DynamicSprite::CreateFromDrawingSurface^5", Sc_DynamicSprite_CreateFromDrawingSurface); ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^1", Sc_DynamicSprite_CreateFromExistingSprite_Old); ccAddExternalStaticFunction("DynamicSprite::CreateFromExistingSprite^2", Sc_DynamicSprite_CreateFromExistingSprite); - ccAddExternalStaticFunction("DynamicSprite::CreateFromFile", Sc_DynamicSprite_CreateFromFile); - ccAddExternalStaticFunction("DynamicSprite::CreateFromSaveGame", Sc_DynamicSprite_CreateFromSaveGame); - ccAddExternalStaticFunction("DynamicSprite::CreateFromScreenShot", Sc_DynamicSprite_CreateFromScreenShot); + ccAddExternalStaticFunction("DynamicSprite::CreateFromFile", Sc_DynamicSprite_CreateFromFile); + ccAddExternalStaticFunction("DynamicSprite::CreateFromSaveGame", Sc_DynamicSprite_CreateFromSaveGame); + ccAddExternalStaticFunction("DynamicSprite::CreateFromScreenShot", Sc_DynamicSprite_CreateFromScreenShot); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -666,3 +668,5 @@ void RegisterDynamicSpriteAPI() { ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromSaveGame", (void *)DynamicSprite_CreateFromSaveGame); ccAddExternalFunctionForPlugin("DynamicSprite::CreateFromScreenShot", (void *)DynamicSprite_CreateFromScreenShot); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp index bdc815dd96b3..fe3f70cb6d1f 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -26,6 +26,8 @@ #include "ac/common.h" // quit() #include "util/bbop.h" +namespace AGS3 { + using namespace AGS::Shared; // *** The script serialization routines for built-in types @@ -125,3 +127,5 @@ void AGSCCDynamicObject::WriteInt32(const char *address, intptr_t offset, int32_ void AGSCCDynamicObject::WriteFloat(const char *address, intptr_t offset, float val) { *(float *)(address + offset) = val; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp index b8463f2f3348..e5e89d620b6e 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp @@ -24,6 +24,8 @@ #include "ac/dynobj/scriptaudiochannel.h" #include "media/audio/audio_system.h" +namespace AGS3 { + extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1]; const char *CCAudioChannel::GetType() { @@ -42,3 +44,5 @@ void CCAudioChannel::Unserialize(int index, const char *serializedData, int data int id = UnserializeInt(); ccRegisterUnserializedObject(index, &scrAudioChannel[id], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp index 06a70867d3f5..edcde5d34ac0 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp @@ -24,6 +24,8 @@ #include "ac/dynobj/scriptaudioclip.h" #include "ac/gamesetupstruct.h" +namespace AGS3 { + extern GameSetupStruct game; const char *CCAudioClip::GetType() { @@ -42,3 +44,5 @@ void CCAudioClip::Unserialize(int index, const char *serializedData, int dataSiz int id = UnserializeInt(); ccRegisterUnserializedObject(index, &game.audioClips[id], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index 07658e367d77..d00b9cea5aae 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -26,6 +26,8 @@ #include "ac/gamesetupstruct.h" #include "ac/game_version.h" +namespace AGS3 { + extern GameSetupStruct game; // return the type name of the object @@ -61,3 +63,5 @@ void CCCharacter::WriteInt16(const char *address, intptr_t offset, int16_t val) } } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp index 47bcefca7693..bfd8e835fa3f 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp @@ -25,6 +25,8 @@ #include "ac/dialogtopic.h" #include "ac/gamestructdefines.h" +namespace AGS3 { + // return the type name of the object const char *CCDialog::GetType() { return "Dialog"; @@ -44,3 +46,5 @@ void CCDialog::Unserialize(int index, const char *serializedData, int dataSize) int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrDialog[num], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp index 0a66cccc5047..d64343865e03 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp @@ -23,6 +23,8 @@ #include #include "cc_dynamicarray.h" +namespace AGS3 { + // return the type name of the object const char *CCDynamicArray::GetType() { return CC_DYNAMIC_ARRAY_TYPE_NAME; @@ -147,3 +149,5 @@ DynObjectRef DynamicArrayHelpers::CreateStringArray(const std::vectorGetType()), handl, object); + ((callback == NULL) ? "(unknown)" : callback->GetType()), handl, object); return handl; } @@ -158,3 +160,5 @@ int ccReleaseObjectReference(int32_t handle) { return pool.SubRef(handle); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp index 300883cff82a..3ef3e51fe909 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.cpp +++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp @@ -23,6 +23,8 @@ #include "ac/dynobj/cc_gui.h" #include "ac/dynobj/scriptgui.h" +namespace AGS3 { + extern ScriptGUI *scrGui; // return the type name of the object @@ -44,3 +46,5 @@ void CCGUI::Unserialize(int index, const char *serializedData, int dataSize) { int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrGui[num], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp index 6898ffb963b4..8d344c7a7f26 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -25,6 +25,8 @@ #include "gui/guimain.h" #include "gui/guiobject.h" +namespace AGS3 { + using AGS::Shared::GUIObject; // return the type name of the object @@ -48,3 +50,5 @@ void CCGUIObject::Unserialize(int index, const char *serializedData, int dataSiz int objnum = UnserializeInt(); ccRegisterUnserializedObject(index, guis[guinum].GetControl(objnum), this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp index 310a1ad06d51..8425c39eeea7 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp @@ -25,6 +25,8 @@ #include "ac/common_defines.h" #include "game/roomstruct.h" +namespace AGS3 { + extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; // return the type name of the object @@ -46,3 +48,5 @@ void CCHotspot::Unserialize(int index, const char *serializedData, int dataSize) int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrHotspot[num], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp index 1e3045348bfa..732a4da44b51 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.cpp +++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp @@ -24,6 +24,8 @@ #include "ac/dynobj/scriptinvitem.h" #include "ac/characterinfo.h" +namespace AGS3 { + extern ScriptInvItem scrInv[MAX_INV]; // return the type name of the object @@ -45,3 +47,5 @@ void CCInventory::Unserialize(int index, const char *serializedData, int dataSiz int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrInv[num], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp index 1f695146f39d..99c0d6f41bc6 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.cpp +++ b/engines/ags/engine/ac/dynobj/cc_object.cpp @@ -25,6 +25,8 @@ #include "ac/common_defines.h" #include "game/roomstruct.h" +namespace AGS3 { + extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; // return the type name of the object @@ -46,3 +48,5 @@ void CCObject::Unserialize(int index, const char *serializedData, int dataSize) int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrObj[num], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp index a1de49619b2e..fb140013f6d5 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.cpp +++ b/engines/ags/engine/ac/dynobj/cc_region.cpp @@ -25,6 +25,8 @@ #include "ac/common_defines.h" #include "game/roomstruct.h" +namespace AGS3 { + extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; // return the type name of the object @@ -46,3 +48,5 @@ void CCRegion::Unserialize(int index, const char *serializedData, int dataSize) int num = UnserializeInt(); ccRegisterUnserializedObject(index, &scrRegion[num], this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp index 90ae3bad28db..53d6f42f876e 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.cpp +++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp @@ -34,6 +34,8 @@ #include "plugin/agsplugin.h" #include "plugin/pluginobjectreader.h" +namespace AGS3 { + extern CCGUIObject ccDynamicGUIObject; extern CCCharacter ccDynamicCharacter; extern CCHotspot ccDynamicHotspot; @@ -122,3 +124,4 @@ void AGSDeSerializer::Unserialize(int index, const char *objectType, const char AGSDeSerializer ccUnserializer; +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index f6e837f52d5c..be2f46b4d2a0 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -30,6 +30,8 @@ #include "script/script_common.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; const auto OBJECT_CACHE_MAGIC_NUMBER = 0xa30b; @@ -199,7 +201,7 @@ int ManagedObjectPool::AddObject(const char *address, ICCDynamicObject *callback o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); - handleByAddress.insert({address, o.handle}); + handleByAddress.insert({ address, o.handle }); objectCreationCounter++; ManagedObjectLog("Allocated managed object handle=%d, type=%s", handle, callback->GetType()); return o.handle; @@ -223,7 +225,7 @@ int ManagedObjectPool::AddUnserializedObject(const char *address, ICCDynamicObje o = ManagedObject(plugin_object ? kScValPluginObject : kScValDynamicObject, handle, address, callback); - handleByAddress.insert({address, o.handle}); + handleByAddress.insert({ address, o.handle }); ManagedObjectLog("Allocated unserialized managed object handle=%d, type=%s", o.handle, callback->GetType()); return o.handle; } @@ -287,7 +289,8 @@ int ManagedObjectPool::ReadFromDisk(Stream *in, ICCObjectReader *reader) { auto version = in->ReadInt32(); switch (version) { - case 1: { + case 1: + { // IMPORTANT: numObjs is "nextHandleId", which is why we iterate from 1 to numObjs-1 int numObjs = in->ReadInt32(); for (int i = 1; i < numObjs; i++) { @@ -309,7 +312,8 @@ int ManagedObjectPool::ReadFromDisk(Stream *in, ICCObjectReader *reader) { } } break; - case 2: { + case 2: + { // This is actually number of objects written. int objectsSize = in->ReadInt32(); for (int i = 0; i < objectsSize; i++) { @@ -377,3 +381,5 @@ ManagedObjectPool::ManagedObjectPool() : objectCreationCounter(0), nextHandle(1) } ManagedObjectPool pool; + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp index e8d434ee68e5..f5c079d2164a 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.cpp +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -24,9 +24,12 @@ #include "ac/gamestate.h" #include "util/bbop.h" +namespace AGS3 { + using namespace AGS::Shared; -ScriptCamera::ScriptCamera(int id) : _id(id) {} +ScriptCamera::ScriptCamera(int id) : _id(id) { +} const char *ScriptCamera::GetType() { return "Camera2"; @@ -64,3 +67,5 @@ ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dat } return new ScriptCamera(-1); // make invalid reference } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp index 19c0abcd9165..83b71cd88901 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp @@ -22,6 +22,8 @@ #include "ac/dynobj/scriptdatetime.h" +namespace AGS3 { + int ScriptDateTime::Dispose(const char *address, bool force) { // always dispose a DateTime delete this; @@ -61,3 +63,5 @@ ScriptDateTime::ScriptDateTime() { hour = minute = second = 0; rawUnixTime = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp index 7414e3a81c3e..1dcc21a77d35 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp @@ -22,6 +22,8 @@ #include "ac/dynobj/scriptdialogoptionsrendering.h" +namespace AGS3 { + // return the type name of the object const char *ScriptDialogOptionsRendering::GetType() { return "DialogOptionsRendering"; @@ -57,3 +59,5 @@ void ScriptDialogOptionsRendering::Reset() { ScriptDialogOptionsRendering::ScriptDialogOptionsRendering() { Reset(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptdict.cpp b/engines/ags/engine/ac/dynobj/scriptdict.cpp index 8dbb901265e6..94dbb00cf9e0 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdict.cpp @@ -22,6 +22,8 @@ #include "ac/dynobj/scriptdict.h" +namespace AGS3 { + int ScriptDictBase::Dispose(const char *address, bool force) { Clear(); delete this; @@ -34,7 +36,7 @@ const char *ScriptDictBase::GetType() { int ScriptDictBase::Serialize(const char *address, char *buffer, int bufsize) { size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; - if (bufsize < 0 || total_sz > (size_t)bufsize) { + if (bufsize < 0 || total_sz >(size_t)bufsize) { // buffer not big enough, ask for a bigger one return -((int)total_sz); } @@ -52,3 +54,5 @@ void ScriptDictBase::Unserialize(int index, const char *serializedData, int data UnserializeContainer(serializedData); ccRegisterUnserializedObject(index, this, this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp index 6b2e240239e7..703120f83639 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -30,6 +30,8 @@ #include "game/roomstruct.h" #include "gfx/bitmap.h" +namespace AGS3 { + using namespace AGS::Shared; extern RoomStruct thisroom; @@ -129,3 +131,5 @@ ScriptDrawingSurface::ScriptDrawingSurface() { highResCoordinates = 1; } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp index 817d77b6fe1e..69b739054021 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp @@ -23,6 +23,8 @@ #include "ac/dynobj/scriptdynamicsprite.h" #include "ac/dynamicsprite.h" +namespace AGS3 { + int ScriptDynamicSprite::Dispose(const char *address, bool force) { // always dispose if ((slot) && (!force)) @@ -56,3 +58,5 @@ ScriptDynamicSprite::ScriptDynamicSprite(int theSlot) { ScriptDynamicSprite::ScriptDynamicSprite() { slot = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptfile.cpp b/engines/ags/engine/ac/dynobj/scriptfile.cpp index 122ab0a8cfb2..203c94f0b0ac 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.cpp +++ b/engines/ags/engine/ac/dynobj/scriptfile.cpp @@ -23,11 +23,13 @@ #include "ac/dynobj/scriptfile.h" #include "ac/global_file.h" +namespace AGS3 { + // CHECKME: actually NULLs here will be equal to kFile_Open & kFile_Read const Common::FileOpenMode sc_File::fopenModes[] = -{Common::kFile_Open/*CHECKME, was undefined*/, Common::kFile_Open, Common::kFile_CreateAlways, Common::kFile_Create}; +{ Common::kFile_Open/*CHECKME, was undefined*/, Common::kFile_Open, Common::kFile_CreateAlways, Common::kFile_Create }; const Common::FileWorkMode sc_File::fworkModes[] = -{Common::kFile_Read/*CHECKME, was undefined*/, Common::kFile_Read, Common::kFile_Write, Common::kFile_Write}; +{ Common::kFile_Read/*CHECKME, was undefined*/, Common::kFile_Read, Common::kFile_Write, Common::kFile_Write }; int sc_File::Dispose(const char *address, bool force) { Close(); @@ -100,3 +102,5 @@ void sc_File::WriteInt32(const char *address, intptr_t offset, int32_t val) { void sc_File::WriteFloat(const char *address, intptr_t offset, float val) { } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp index ba8954b9482b..3beedc5c3acb 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp @@ -26,6 +26,8 @@ #include "ac/runtime_defines.h" #include "ac/screenoverlay.h" +namespace AGS3 { + int ScriptOverlay::Dispose(const char *address, bool force) { // since the managed object is being deleted, remove the // reference so it doesn't try and dispose something else @@ -84,3 +86,5 @@ ScriptOverlay::ScriptOverlay() { borderHeight = 0; isBackgroundSpeech = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptset.cpp b/engines/ags/engine/ac/dynobj/scriptset.cpp index db1e733f5085..626ce882c7ee 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.cpp +++ b/engines/ags/engine/ac/dynobj/scriptset.cpp @@ -22,6 +22,8 @@ #include "ac/dynobj/scriptset.h" +namespace AGS3 { + int ScriptSetBase::Dispose(const char *address, bool force) { Clear(); delete this; @@ -34,7 +36,7 @@ const char *ScriptSetBase::GetType() { int ScriptSetBase::Serialize(const char *address, char *buffer, int bufsize) { size_t total_sz = CalcSerializeSize() + sizeof(int32_t) * 2; - if (bufsize < 0 || total_sz > (size_t)bufsize) { + if (bufsize < 0 || total_sz >(size_t)bufsize) { // buffer not big enough, ask for a bigger one return -((int)total_sz); } @@ -52,3 +54,5 @@ void ScriptSetBase::Unserialize(int index, const char *serializedData, int dataS UnserializeContainer(serializedData); ccRegisterUnserializedObject(index, this, this); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptstring.cpp b/engines/ags/engine/ac/dynobj/scriptstring.cpp index 637de80e35c8..e752f3e97f37 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.cpp +++ b/engines/ags/engine/ac/dynobj/scriptstring.cpp @@ -25,6 +25,8 @@ #include #include +namespace AGS3 { + DynObjectRef ScriptString::CreateString(const char *fromText) { return CreateNewScriptStringObj(fromText); } @@ -72,3 +74,5 @@ ScriptString::ScriptString(const char *fromText) { text = (char *)malloc(strlen(fromText) + 1); strcpy(text, fromText); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp index b519bb17f850..55e2baa04adb 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp @@ -23,6 +23,8 @@ #include #include "scriptuserobject.h" +namespace AGS3 { + // return the type name of the object const char *ScriptUserObject::GetType() { return "UserObject"; @@ -34,7 +36,7 @@ ScriptUserObject::ScriptUserObject() } ScriptUserObject::~ScriptUserObject() { - delete [] _data; + delete[] _data; } /* static */ ScriptUserObject *ScriptUserObject::CreateManaged(size_t size) { @@ -45,7 +47,7 @@ ScriptUserObject::~ScriptUserObject() { } void ScriptUserObject::Create(const char *data, size_t size) { - delete [] _data; + delete[] _data; _data = nullptr; _size = size; @@ -129,3 +131,5 @@ ScriptUserObject *ScriptStructHelpers::CreatePoint(int x, int y) { suo->WriteInt32((const char *)suo, sizeof(int32_t), y); return suo; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp index d3f6ccd31746..9a727afa6068 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp @@ -22,6 +22,8 @@ #include "ac/dynobj/scriptviewframe.h" +namespace AGS3 { + int ScriptViewFrame::Dispose(const char *address, bool force) { // always dispose a ViewFrame delete this; @@ -59,3 +61,5 @@ ScriptViewFrame::ScriptViewFrame() { loop = -1; frame = -1; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp index c090db39bd66..7bca084f19ce 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -24,9 +24,12 @@ #include "ac/gamestate.h" #include "util/bbop.h" +namespace AGS3 { + using namespace AGS::Shared; -ScriptViewport::ScriptViewport(int id) : _id(id) {} +ScriptViewport::ScriptViewport(int id) : _id(id) { +} const char *ScriptViewport::GetType() { return "Viewport2"; @@ -64,3 +67,5 @@ ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int } return new ScriptViewport(-1); // make invalid reference } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp index fec319880e44..e7415dfe095b 100644 --- a/engines/ags/engine/ac/event.cpp +++ b/engines/ags/engine/ac/event.cpp @@ -42,6 +42,8 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -67,7 +69,7 @@ int evblocknum; int inside_processevent = 0; int eventClaimed = EVENT_NONE; -const char *tsnames[4] = {nullptr, REP_EXEC_NAME, "on_key_press", "on_mouse_click"}; +const char *tsnames[4] = { nullptr, REP_EXEC_NAME, "on_key_press", "on_mouse_click" }; int run_claimable_event(const char *tsname, bool includeRoom, int numParams, const RuntimeScriptValue *params, bool *eventWasClaimed) { @@ -186,7 +188,7 @@ void process_event(EventHappened *evp) { evblockbasename = "room"; if (evp->data3 == 5) { - in_enters_screen ++; + in_enters_screen++; run_on_event(GE_ENTER_ROOM, RuntimeScriptValue().SetInt32(displayed_room)); } @@ -204,7 +206,7 @@ void process_event(EventHappened *evp) { evblocknum = oldblocknum; if ((evp->data3 == 5) && (evp->data1 == EVB_ROOM)) - in_enters_screen --; + in_enters_screen--; } else if (evp->type == EV_FADEIN) { // if they change the transition type before the fadein, make // sure the screen doesn't freeze up @@ -227,7 +229,7 @@ void process_event(EventHappened *evp) { const bool ignore_transition = (play.screen_tint > 0); if (((theTransition == FADE_CROSSFADE) || (theTransition == FADE_DISSOLVE)) && - (saved_viewport_bitmap == nullptr) && !ignore_transition) { + (saved_viewport_bitmap == nullptr) && !ignore_transition) { // transition type was not crossfade/dissolve when the screen faded out, // but it is now when the screen fades in (Eg. a save game was restored // with a different setting). Therefore just fade normally. @@ -272,7 +274,7 @@ void process_event(EventHappened *evp) { int lyp = viewport.GetHeight() / 2 - boxhit / 2; gfxDriver->Vsync(); temp_scr->Blit(saved_backbuf, lxp, lyp, lxp, lyp, - boxwid, boxhit); + boxwid, boxhit); render_to_screen(); update_polled_mp3(); WaitForNextFrame(); @@ -312,7 +314,7 @@ void process_event(EventHappened *evp) { set_palette_range(palette, 0, 255, 0); gfxDriver->DestroyDDB(ddb); } else if (theTransition == FADE_DISSOLVE) { - int pattern[16] = {0, 4, 14, 9, 5, 11, 2, 8, 10, 3, 12, 7, 15, 6, 13, 1}; + int pattern[16] = { 0, 4, 14, 9, 5, 11, 2, 8, 10, 3, 12, 7, 15, 6, 13, 1 }; int aa, bb, cc; color interpal[256]; @@ -401,3 +403,5 @@ void ClaimEvent() { eventClaimed = EVENT_CLAIMED; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index c1128f960fab..459e46dea941 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -46,6 +46,8 @@ #include "util/string.h" #include "util/string_utils.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetup usetup; @@ -210,10 +212,10 @@ int File_GetPosition(sc_File *fil) { //============================================================================= -const String GameInstallRootToken = "$INSTALLDIR$"; +const String GameInstallRootToken = "$INSTALLDIR$"; const String UserSavedgamesRootToken = "$MYDOCS$"; -const String GameSavedgamesDirToken = "$SAVEGAMEDIR$"; -const String GameDataDirToken = "$APPDATADIR$"; +const String GameSavedgamesDirToken = "$SAVEGAMEDIR$"; +const String GameDataDirToken = "$APPDATADIR$"; void FixupFilename(char *filename) { const char *illegal = platform->GetIllegalFileChars(); @@ -234,7 +236,7 @@ void FixupFilename(char *filename) { // Returns TRUE if the new string was created, and FALSE if the path was good. bool FixSlashAfterToken(const String &path, const String &token, String &new_path) { if (path.CompareLeft(token) == 0 && path.GetLength() > token.GetLength() && - path[token.GetLength()] != '/') { + path[token.GetLength()] != '/') { new_path = String::FromFormat("%s/%s", token.GetCStr(), path.Mid(token.GetLength()).GetCStr()); return true; } @@ -244,10 +246,10 @@ bool FixSlashAfterToken(const String &path, const String &token, String &new_pat String FixSlashAfterToken(const String &path) { String fixed_path = path; Path::FixupPath(fixed_path); - if (FixSlashAfterToken(fixed_path, GameInstallRootToken, fixed_path) || - FixSlashAfterToken(fixed_path, UserSavedgamesRootToken, fixed_path) || - FixSlashAfterToken(fixed_path, GameSavedgamesDirToken, fixed_path) || - FixSlashAfterToken(fixed_path, GameDataDirToken, fixed_path)) + if (FixSlashAfterToken(fixed_path, GameInstallRootToken, fixed_path) || + FixSlashAfterToken(fixed_path, UserSavedgamesRootToken, fixed_path) || + FixSlashAfterToken(fixed_path, GameSavedgamesDirToken, fixed_path) || + FixSlashAfterToken(fixed_path, GameDataDirToken, fixed_path)) return fixed_path; return path; } @@ -293,7 +295,7 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath if (sc_path.CompareLeft(GameInstallRootToken, GameInstallRootToken.GetLength()) == 0) { if (!read_only) { debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory)", - sc_path.GetCStr()); + sc_path.GetCStr()); return false; } parent_dir = get_install_dir(); @@ -327,7 +329,7 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath // if the unsafe path is used for write operation if (!read_only && game.options[OPT_SAFEFILEPATHS]) { debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory);\nPath will be remapped to the app data directory: '%s'", - sc_path.GetCStr(), parent_dir.GetCStr()); + sc_path.GetCStr(), parent_dir.GetCStr()); } } @@ -713,25 +715,25 @@ RuntimeScriptValue Sc_File_GetPosition(void *self, const RuntimeScriptValue *par void RegisterFileAPI() { - ccAddExternalStaticFunction("File::Delete^1", Sc_File_Delete); - ccAddExternalStaticFunction("File::Exists^1", Sc_File_Exists); - ccAddExternalStaticFunction("File::Open^2", Sc_sc_OpenFile); - ccAddExternalObjectFunction("File::Close^0", Sc_File_Close); - ccAddExternalObjectFunction("File::ReadInt^0", Sc_File_ReadInt); - ccAddExternalObjectFunction("File::ReadRawChar^0", Sc_File_ReadRawChar); - ccAddExternalObjectFunction("File::ReadRawInt^0", Sc_File_ReadRawInt); - ccAddExternalObjectFunction("File::ReadRawLine^1", Sc_File_ReadRawLine); - ccAddExternalObjectFunction("File::ReadRawLineBack^0", Sc_File_ReadRawLineBack); - ccAddExternalObjectFunction("File::ReadString^1", Sc_File_ReadString); - ccAddExternalObjectFunction("File::ReadStringBack^0", Sc_File_ReadStringBack); - ccAddExternalObjectFunction("File::WriteInt^1", Sc_File_WriteInt); - ccAddExternalObjectFunction("File::WriteRawChar^1", Sc_File_WriteRawChar); - ccAddExternalObjectFunction("File::WriteRawLine^1", Sc_File_WriteRawLine); - ccAddExternalObjectFunction("File::WriteString^1", Sc_File_WriteString); - ccAddExternalObjectFunction("File::Seek^2", Sc_File_Seek); - ccAddExternalObjectFunction("File::get_EOF", Sc_File_GetEOF); - ccAddExternalObjectFunction("File::get_Error", Sc_File_GetError); - ccAddExternalObjectFunction("File::get_Position", Sc_File_GetPosition); + ccAddExternalStaticFunction("File::Delete^1", Sc_File_Delete); + ccAddExternalStaticFunction("File::Exists^1", Sc_File_Exists); + ccAddExternalStaticFunction("File::Open^2", Sc_sc_OpenFile); + ccAddExternalObjectFunction("File::Close^0", Sc_File_Close); + ccAddExternalObjectFunction("File::ReadInt^0", Sc_File_ReadInt); + ccAddExternalObjectFunction("File::ReadRawChar^0", Sc_File_ReadRawChar); + ccAddExternalObjectFunction("File::ReadRawInt^0", Sc_File_ReadRawInt); + ccAddExternalObjectFunction("File::ReadRawLine^1", Sc_File_ReadRawLine); + ccAddExternalObjectFunction("File::ReadRawLineBack^0", Sc_File_ReadRawLineBack); + ccAddExternalObjectFunction("File::ReadString^1", Sc_File_ReadString); + ccAddExternalObjectFunction("File::ReadStringBack^0", Sc_File_ReadStringBack); + ccAddExternalObjectFunction("File::WriteInt^1", Sc_File_WriteInt); + ccAddExternalObjectFunction("File::WriteRawChar^1", Sc_File_WriteRawChar); + ccAddExternalObjectFunction("File::WriteRawLine^1", Sc_File_WriteRawLine); + ccAddExternalObjectFunction("File::WriteString^1", Sc_File_WriteString); + ccAddExternalObjectFunction("File::Seek^2", Sc_File_Seek); + ccAddExternalObjectFunction("File::get_EOF", Sc_File_GetEOF); + ccAddExternalObjectFunction("File::get_Error", Sc_File_GetError); + ccAddExternalObjectFunction("File::get_Position", Sc_File_GetPosition); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -753,3 +755,5 @@ void RegisterFileAPI() { ccAddExternalFunctionForPlugin("File::get_EOF", (void *)File_GetEOF); ccAddExternalFunctionForPlugin("File::get_Error", (void *)File_GetError); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index f71b1a930968..da01664b110c 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -98,6 +98,8 @@ #include "util/string_utils.h" #include "ac/keycode.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -2317,3 +2319,5 @@ void RegisterStaticObjects() { ccAddExternalStaticObject("system", &scsystem, &GlobalStaticManager); ccAddExternalStaticObject("savegameindex", &play.filenumbers[0], &GlobalStaticManager); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/gamesetup.cpp b/engines/ags/engine/ac/gamesetup.cpp index d33d4739e38f..8f197591b55a 100644 --- a/engines/ags/engine/ac/gamesetup.cpp +++ b/engines/ags/engine/ac/gamesetup.cpp @@ -23,6 +23,8 @@ #include "util/wgt2allg.h" // DIGI_AUTODETECT & MIDI_AUTODETECT #include "ac/gamesetup.h" +namespace AGS3 { + GameSetup::GameSetup() { digicard = DIGI_AUTODETECT; midicard = MIDI_AUTODETECT; @@ -50,3 +52,5 @@ GameSetup::GameSetup() { Screen.FsGameFrame = GameFrameSetup(kFrame_MaxProportional); Screen.WinGameFrame = GameFrameSetup(kFrame_MaxRound); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index 73c0d7cf933e..aa1d3749d237 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -39,6 +39,8 @@ #include "util/alignedstream.h" #include "util/string_utils.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -367,7 +369,7 @@ bool GameState::IsNonBlockingVoiceSpeech() const { bool GameState::ShouldPlayVoiceSpeech() const { return !play.fast_forward && - (play.want_speech >= 1) && (!ResPaths.SpeechPak.Name.IsEmpty()); + (play.want_speech >= 1) && (!ResPaths.SpeechPak.Name.IsEmpty()); } void GameState::ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, RestoredData &r_data) { @@ -848,6 +850,8 @@ HorAlignment ConvertLegacyScriptAlignment(LegacyScriptAlignment align) { // Alignment constants in the Script API and still support old version. HorAlignment ReadScriptAlignment(int32_t align) { return game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v350 ? - ConvertLegacyScriptAlignment((LegacyScriptAlignment)align) : - (HorAlignment)align; + ConvertLegacyScriptAlignment((LegacyScriptAlignment)align) : + (HorAlignment)align; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp index 1f6a96790c3b..5a36bf5de664 100644 --- a/engines/ags/engine/ac/global_api.cpp +++ b/engines/ags/engine/ac/global_api.cpp @@ -81,6 +81,9 @@ #include "media/audio/audio_system.h" #include "ac/dynobj/scriptstring.h" + +namespace AGS3 { + extern ScriptString myScriptStringImpl; // void (char*texx, ...) @@ -2691,3 +2694,5 @@ void RegisterGlobalAPI() { ccAddExternalFunctionForPlugin("WaitKey", (void *)WaitKey); ccAddExternalFunctionForPlugin("WaitMouseKey", (void *)WaitMouseKey); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp index 5f83560d3082..06de369d830f 100644 --- a/engines/ags/engine/ac/global_audio.cpp +++ b/engines/ags/engine/ac/global_audio.cpp @@ -36,6 +36,8 @@ #include "ac/timer.h" #include "util/string_compat.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetup usetup; @@ -69,7 +71,7 @@ void PlayAmbientSound(int channel, int sndnum, int vol, int x, int y) { // only play the sound if it's not already playing if ((ambient[channel].channel < 1) || (!channel_is_playing(ambient[channel].channel)) || - (ambient[channel].num != sndnum)) { + (ambient[channel].num != sndnum)) { StopAmbientSound(channel); // in case a normal non-ambient sound was playing, stop it too @@ -241,7 +243,7 @@ int PlayMusicQueued(int musnum) { } if ((play.music_queue_size > 0) && - (play.music_queue[play.music_queue_size - 1] >= QUEUED_MUSIC_REPEAT)) { + (play.music_queue[play.music_queue_size - 1] >= QUEUED_MUSIC_REPEAT)) { debug_script_warn("PlayMusicQueued: cannot queue music after a repeating tune has been queued"); return 0; } @@ -325,7 +327,7 @@ void SetMusicVolume(int newvol) { void SetMusicMasterVolume(int newvol) { const int min_volume = loaded_game_file_version < kGameVersion_330 ? 0 : - -LegacyMusicMasterVolumeAdjustment - (kRoomVolumeMax * LegacyRoomVolumeFactor); + -LegacyMusicMasterVolumeAdjustment - (kRoomVolumeMax * LegacyRoomVolumeFactor); if ((newvol < min_volume) | (newvol > 100)) quitprintf("!SetMusicMasterVolume: invalid volume - must be from %d to %d", min_volume, 100); play.music_master_volume = newvol + LegacyMusicMasterVolumeAdjustment; @@ -667,3 +669,5 @@ void stop_voice_nonblocking() { play.speech_voice_blocking = false; } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp index f6aa71a5b2b5..5e78ed739ae2 100644 --- a/engines/ags/engine/ac/global_button.cpp +++ b/engines/ags/engine/ac/global_button.cpp @@ -28,6 +28,8 @@ #include "gui/guimain.h" #include "gui/guibutton.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -100,3 +102,5 @@ void SetButtonPic(int guin, int objn, int ptype, int slotn) { Button_SetPushedGraphic(guil, slotn); } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp index 389efea22d35..e5098d258e35 100644 --- a/engines/ags/engine/ac/global_character.cpp +++ b/engines/ags/engine/ac/global_character.cpp @@ -47,6 +47,8 @@ #include "main/game_run.h" #include "script/script.h" +namespace AGS3 { + using namespace AGS::Shared; @@ -115,8 +117,8 @@ int GetCharacterWidth(int ww) { if (charextra[ww].width < 1) { if ((char1->view < 0) || - (char1->loop >= views[char1->view].numLoops) || - (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) { + (char1->loop >= views[char1->view].numLoops) || + (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) { debug_script_warn("GetCharacterWidth: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); return data_to_game_coord(4); } @@ -131,8 +133,8 @@ int GetCharacterHeight(int charid) { if (charextra[charid].height < 1) { if ((char1->view < 0) || - (char1->loop >= views[char1->view].numLoops) || - (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) { + (char1->loop >= views[char1->view].numLoops) || + (char1->frame >= views[char1->view].loops[char1->loop].numFrames)) { debug_script_warn("GetCharacterHeight: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame); return data_to_game_coord(2); } @@ -555,10 +557,12 @@ int DisplaySpeechBackground(int charid, const char *speel) { } int ovrl = CreateTextOverlay(OVR_AUTOPLACE, charid, play.GetUIViewport().GetWidth() / 2, FONT_SPEECH, - -game.chars[charid].talkcolor, get_translation(speel), DISPLAYTEXT_NORMALOVERLAY); + -game.chars[charid].talkcolor, get_translation(speel), DISPLAYTEXT_NORMALOVERLAY); int scid = find_overlay_of_type(ovrl); screenover[scid].bgSpeechForChar = charid; screenover[scid].timeout = GetTextDisplayTime(speel, 1); return ovrl; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_datetime.cpp b/engines/ags/engine/ac/global_datetime.cpp index 619e678a4751..11db83ec9444 100644 --- a/engines/ags/engine/ac/global_datetime.cpp +++ b/engines/ags/engine/ac/global_datetime.cpp @@ -25,6 +25,8 @@ #include "ac/datetime.h" #include "ac/common.h" +namespace AGS3 { + int sc_GetTime(int whatti) { ScriptDateTime *sdt = DateTime_Now_Core(); int returnVal = 0; @@ -46,3 +48,5 @@ int GetRawTime() { // TODO: we might need to modify script API to support larger time type return static_cast(time(nullptr)); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp index be28d50e1f53..87f13bddf232 100644 --- a/engines/ags/engine/ac/global_debug.cpp +++ b/engines/ags/engine/ac/global_debug.cpp @@ -47,6 +47,8 @@ #include "gfx/graphicsdriver.h" #include "main/graphics_mode.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -69,16 +71,16 @@ String GetRuntimeInfo() { Rect render_frame = gfxDriver->GetRenderDestination(); PGfxFilter filter = gfxDriver->GetGraphicsFilter(); String runtimeInfo = String::FromFormat( - "Adventure Game Studio run-time engine[ACI version %s" - "[Game resolution %d x %d (%d-bit)" - "[Running %d x %d at %d-bit%s%s[GFX: %s; %s[Draw frame %d x %d[" - "Sprite cache size: %d KB (limit %d KB; %d locked)", - EngineVersion.LongString.GetCStr(), game.GetGameRes().Width, game.GetGameRes().Height, game.GetColorDepth(), - mode.Width, mode.Height, mode.ColorDepth, (convert_16bit_bgr) ? " BGR" : "", - mode.Windowed ? " W" : "", - gfxDriver->GetDriverName(), filter->GetInfo().Name.GetCStr(), - render_frame.GetWidth(), render_frame.GetHeight(), - spriteset.GetCacheSize() / 1024, spriteset.GetMaxCacheSize() / 1024, spriteset.GetLockedSize() / 1024); + "Adventure Game Studio run-time engine[ACI version %s" + "[Game resolution %d x %d (%d-bit)" + "[Running %d x %d at %d-bit%s%s[GFX: %s; %s[Draw frame %d x %d[" + "Sprite cache size: %d KB (limit %d KB; %d locked)", + EngineVersion.LongString.GetCStr(), game.GetGameRes().Width, game.GetGameRes().Height, game.GetColorDepth(), + mode.Width, mode.Height, mode.ColorDepth, (convert_16bit_bgr) ? " BGR" : "", + mode.Windowed ? " W" : "", + gfxDriver->GetDriverName(), filter->GetInfo().Name.GetCStr(), + render_frame.GetWidth(), render_frame.GetHeight(), + spriteset.GetCacheSize() / 1024, spriteset.GetMaxCacheSize() / 1024, spriteset.GetLockedSize() / 1024); if (play.separate_music_lib) runtimeInfo.Append("[AUDIO.VOX enabled"); if (play.want_speech >= 1) @@ -185,3 +187,5 @@ void script_debug(int cmdd, int dataa) { ccSetOption(SCOPT_DEBUGRUN, dataa); else quit("!Debug: unknown command code"); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_dialog.cpp b/engines/ags/engine/ac/global_dialog.cpp index ff9240615b46..b2b95c497ebf 100644 --- a/engines/ags/engine/ac/global_dialog.cpp +++ b/engines/ags/engine/ac/global_dialog.cpp @@ -31,6 +31,8 @@ #include "debug/out.h" #include "script/script.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -49,7 +51,7 @@ void RunDialog(int tum) { play.stop_dialog_at_end = DIALOG_NEWTOPIC + tum; else quitprintf("!RunDialog: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", - last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); + last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); return; } @@ -106,3 +108,5 @@ int GetDialogOption(int dlg, int opt) { return 1; return 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp index 1ac54d54ff4d..7aa5326bc242 100644 --- a/engines/ags/engine/ac/global_display.cpp +++ b/engines/ags/engine/ac/global_display.cpp @@ -41,6 +41,8 @@ #include "game/roomstruct.h" #include "main/game_run.h" +namespace AGS3 { + using namespace AGS::Shared; extern TopBarSettings topBar; @@ -113,8 +115,8 @@ void DisplayMessageAtY(int msnum, int ypos) { if (display_message_aschar > 0) { display_message_aschar = 0; quit("!DisplayMessage: data column specified a character for local\n" - "message; use the message editor to select the character for room\n" - "messages.\n"); + "message; use the message editor to select the character for room\n" + "messages.\n"); } int repeatloop = 1; @@ -174,13 +176,13 @@ void DisplayAtY(int ypos, const char *texx) { if (is_screen_dirty()) { // erase any previous DisplaySpeech - play.disabled_user_interface ++; + play.disabled_user_interface++; UpdateGameOnce(); - play.disabled_user_interface --; + play.disabled_user_interface--; } _display_at(-1, ypos, ui_view.GetWidth() / 2 + ui_view.GetWidth() / 4, - get_translation(texx), DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); + get_translation(texx), DISPLAYTEXT_MESSAGEBOX, 0, 0, 0, false); } } @@ -201,3 +203,5 @@ void SetSkipSpeech(SkipSpeechStyle newval) { SkipSpeechStyle GetSkipSpeech() { return internal_skip_speech_to_user(play.cant_skip_speech); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp index f5556e7a0736..36d19cb0e8c8 100644 --- a/engines/ags/engine/ac/global_drawingsurface.cpp +++ b/engines/ags/engine/ac/global_drawingsurface.cpp @@ -37,6 +37,8 @@ #include "gfx/gfx_def.h" #include "gfx/gfx_util.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -78,8 +80,8 @@ void RawRestoreScreenTinted(int red, int green, int blue, int opacity) { return; } if ((red < 0) || (green < 0) || (blue < 0) || - (red > 255) || (green > 255) || (blue > 255) || - (opacity < 1) || (opacity > 100)) + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 1) || (opacity > 100)) quit("!RawRestoreScreenTinted: invalid parameter. R,G,B must be 0-255, opacity 1-100"); debug_script_log("RawRestoreTinted RGB(%d,%d,%d) %d%%", red, green, blue, opacity); @@ -92,7 +94,7 @@ void RawRestoreScreenTinted(int red, int green, int blue, int opacity) { void RawDrawFrameTransparent(int frame, int translev) { if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount) || - (translev < 0) || (translev > 99)) + (translev < 0) || (translev > 99)) quit("!RawDrawFrameTransparent: invalid parameter (transparency must be 0-99, frame a valid BG frame)"); PBitmap bg = thisroom.BgFrames[frame].Graphic; @@ -109,7 +111,7 @@ void RawDrawFrameTransparent(int frame, int translev) { } else { // Draw it transparently GfxUtil::DrawSpriteWithTransparency(RAW_SURFACE(), bg.get(), 0, 0, - GfxDef::Trans100ToAlpha255(translev)); + GfxDef::Trans100ToAlpha255(translev)); } invalidate_screen(); mark_current_background_dirty(); @@ -129,7 +131,7 @@ void RawSetColor(int clr) { } void RawSetColorRGB(int red, int grn, int blu) { if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) || - (blu < 0) || (blu > 255)) + (blu < 0) || (blu > 255)) quit("!RawSetColorRGB: colour values must be 0-255"); play.raw_color = makecol_depth(thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth(), red, grn, blu); @@ -243,8 +245,8 @@ void RawDrawImageResized(int xx, int yy, int gotSlot, int width, int height) { // resize the sprite to the requested size Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); newPic->StretchBlt(spriteset[gotSlot], - RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), - RectWH(0, 0, width, height)); + RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), + RectWH(0, 0, width, height)); RAW_START(); if (newPic->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) @@ -304,3 +306,5 @@ void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) { invalidate_screen(); mark_current_background_dirty(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_dynamicsprite.cpp b/engines/ags/engine/ac/global_dynamicsprite.cpp index d5380a199308..b4019f1a3559 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.cpp +++ b/engines/ags/engine/ac/global_dynamicsprite.cpp @@ -30,6 +30,8 @@ #include "gfx/graphicsdriver.h" #include "gfx/bitmap.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -55,3 +57,5 @@ int LoadImageFile(const char *filename) { return gotSlot; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index 9b29b396d91f..94b1c7ef46a6 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -32,6 +32,8 @@ #include "util/path.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; int32_t FileOpenCMode(const char *fnmm, const char *cmode) { @@ -57,7 +59,7 @@ int32_t FindFreeFileSlot() { } if (useindx >= num_open_script_files && - num_open_script_files >= MAX_OPEN_SCRIPT_FILES) { + num_open_script_files >= MAX_OPEN_SCRIPT_FILES) { quit("!FileOpen: tried to open more than 10 files simultaneously - close some first"); return -1; } @@ -174,3 +176,5 @@ void FileWriteRawChar(int32_t handle, int chartoWrite) { out->WriteInt8(chartoWrite); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 306a63832a5a..8d2c9a36a5ff 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -69,6 +69,8 @@ #include "util/string_utils.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; #define ALLEGRO_KEYBOARD_HANDLER @@ -187,8 +189,8 @@ int LoadSaveSlotScreenshot(int slnum, int width, int height) { // resize the sprite to the requested size Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth()); newPic->StretchBlt(spriteset[gotSlot], - RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), - RectWH(0, 0, width, height)); + RectWH(0, 0, game.SpriteInfos[gotSlot].Width, game.SpriteInfos[gotSlot].Height), + RectWH(0, 0, width, height)); update_polled_stuff_if_runtime(); @@ -319,7 +321,8 @@ int GetGameParameter(int parm, int data1, int data2, int data3) { case GP_FRAMESPEED: case GP_FRAMEIMAGE: case GP_FRAMESOUND: - case GP_ISFRAMEFLIPPED: { + case GP_ISFRAMEFLIPPED: + { if ((data1 < 1) || (data1 > game.numviews)) { quitprintf("!GetGameParameter: invalid view specified (v: %d, l: %d, f: %d)", data1, data2, data3); } @@ -464,7 +467,7 @@ void StartCutscene(int skipwith) { if (is_in_cutscene()) { quitprintf("!StartCutscene: already in a cutscene; previous started in \"%s\", line %d", - last_cutscene_script_pos.Section.GetCStr(), last_cutscene_script_pos.Line); + last_cutscene_script_pos.Section.GetCStr(), last_cutscene_script_pos.Line); } if ((skipwith < 1) || (skipwith > 6)) @@ -646,7 +649,7 @@ int IsKeyPressed(int keycode) { case eAGSKeyCodeCloseBracket: return ags_iskeypressed(__allegro_KEY_CLOSEBRACE); break; - // NOTE: we're treating EQUALS like PLUS, even though it is only available shifted. + // NOTE: we're treating EQUALS like PLUS, even though it is only available shifted. case eAGSKeyCodePlus: return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_PLUS_PAD); break; @@ -654,7 +657,7 @@ int IsKeyPressed(int keycode) { return ags_iskeypressed(__allegro_KEY_MINUS) || ags_iskeypressed(__allegro_KEY_MINUS_PAD); break; - // non-shifted versions of keys + // non-shifted versions of keys case eAGSKeyCodeColon: return ags_iskeypressed(__allegro_KEY_COLON) || ags_iskeypressed(__allegro_KEY_COLON2); break; @@ -846,8 +849,8 @@ int IsKeyPressed(int keycode) { return ags_iskeypressed(__allegro_KEY_DEL) || ags_iskeypressed(__allegro_KEY_DEL_PAD); break; - // These keys are not defined in the eAGSKey enum but are in the manual - // https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html + // These keys are not defined in the eAGSKey enum but are in the manual + // https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html case 403: return ags_iskeypressed(__allegro_KEY_LSHIFT); @@ -865,9 +868,9 @@ int IsKeyPressed(int keycode) { return ags_iskeypressed(__allegro_KEY_ALT); break; - // (noted here for interest) - // The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes. - // These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints. + // (noted here for interest) + // The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes. + // These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints. case 392: return ags_iskeypressed(__allegro_KEY_PRTSCR); @@ -918,10 +921,10 @@ int IsKeyPressed(int keycode) { return ags_iskeypressed(__allegro_KEY_CAPSLOCK); break; - // Allegro4 keys that were never supported: - // __allegro_KEY_COMMAND - // __allegro_KEY_TILDE - // __allegro_KEY_BACKQUOTE + // Allegro4 keys that were never supported: + // __allegro_KEY_COMMAND + // __allegro_KEY_TILDE + // __allegro_KEY_BACKQUOTE default: // Remaining Allegro4 keycodes are offset by AGS_EXT_KEY_SHIFT @@ -996,9 +999,9 @@ void RoomProcessClick(int xx, int yy, int mood) { if ((mood == MODE_WALK) && (game.options[OPT_NOWALKMODE] == 0)) { int hsnum = get_hotspot_at(xx, yy); - if (hsnum < 1) ; - else if (thisroom.Hotspots[hsnum].WalkTo.X < 1) ; - else if (play.auto_use_walkto_points == 0) ; + if (hsnum < 1); + else if (thisroom.Hotspots[hsnum].WalkTo.X < 1); + else if (play.auto_use_walkto_points == 0); else { xx = thisroom.Hotspots[hsnum].WalkTo.X; yy = thisroom.Hotspots[hsnum].WalkTo.Y; @@ -1142,3 +1145,5 @@ int WaitMouseKey(int nloops) { void SkipWait() { play.wait_counter = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp index d8a0cdc010d5..e5481f541d7d 100644 --- a/engines/ags/engine/ac/global_gui.cpp +++ b/engines/ags/engine/ac/global_gui.cpp @@ -36,6 +36,8 @@ #include "script/runtimescriptvalue.h" #include "util/string_compat.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -252,7 +254,7 @@ void SetTextWindowGUI(int guinum) { if ((guinum < -1) | (guinum >= game.numgui)) quit("!SetTextWindowGUI: invalid GUI number"); - if (guinum < 0) ; // disable it + if (guinum < 0); // disable it else if (!guis[guinum].IsTextWindow()) quit("!SetTextWindowGUI: specified GUI is not a text window"); @@ -260,3 +262,5 @@ void SetTextWindowGUI(int guinum) { play.speech_textwindow_gui = guinum; game.options[OPT_TWCUSTOM] = guinum; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp index a145d74bd85a..747b169670fb 100644 --- a/engines/ags/engine/ac/global_hotspot.cpp +++ b/engines/ags/engine/ac/global_hotspot.cpp @@ -37,6 +37,8 @@ #include "game/roomstruct.h" #include "script/script.h" +namespace AGS3 { + using namespace AGS::Shared; extern RoomStruct thisroom; @@ -109,8 +111,8 @@ void RunHotspotInteraction(int hotspothere, int mood) { play.usedinv = cdata; } - if ((game.options[OPT_WALKONLOOK] == 0) & (mood == MODE_LOOK)) ; - else if (play.auto_use_walkto_points == 0) ; + if ((game.options[OPT_WALKONLOOK] == 0) & (mood == MODE_LOOK)); + else if (play.auto_use_walkto_points == 0); else if ((mood != MODE_WALK) && (play.check_interaction_only == 0)) MoveCharacterToHotspot(game.playercharacter, hotspothere); @@ -149,3 +151,5 @@ int GetHotspotProperty(int hss, const char *property) { void GetHotspotPropertyText(int item, const char *property, char *bufer) { get_text_property(thisroom.Hotspots[item].Properties, croom->hsProps[item], property, bufer); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp index 7de499ee5bbc..45f2b1170d69 100644 --- a/engines/ags/engine/ac/global_inventoryitem.cpp +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -34,6 +34,8 @@ #include "ac/event.h" #include "ac/gamestate.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -148,3 +150,5 @@ int GetInvProperty(int item, const char *property) { void GetInvPropertyText(int item, const char *property, char *bufer) { get_text_property(game.invProps[item], play.invProps[item], property, bufer); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_invwindow.cpp b/engines/ags/engine/ac/global_invwindow.cpp index 4433a1b347ff..64553f430f25 100644 --- a/engines/ags/engine/ac/global_invwindow.cpp +++ b/engines/ags/engine/ac/global_invwindow.cpp @@ -27,6 +27,8 @@ #include "gui/guiinv.h" #include "script/executingscript.h" +namespace AGS3 { + extern ExecutingScript *curscript; extern GameState play; @@ -46,3 +48,5 @@ void SetInvDimensions(int ww, int hh) { } guis_need_update = 1; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp index 5561a7a63a7b..770a1f971d0e 100644 --- a/engines/ags/engine/ac/global_label.cpp +++ b/engines/ags/engine/ac/global_label.cpp @@ -27,6 +27,8 @@ #include "ac/string.h" #include "gui/guimain.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -64,3 +66,5 @@ void SetLabelFont(int guin, int objn, int fontnum) { GUILabel *guil = (GUILabel *)guis[guin].GetControl(objn); Label_SetFont(guil, fontnum); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_listbox.cpp b/engines/ags/engine/ac/global_listbox.cpp index 99c3938dd2ce..935927cbe5e6 100644 --- a/engines/ags/engine/ac/global_listbox.cpp +++ b/engines/ags/engine/ac/global_listbox.cpp @@ -25,6 +25,8 @@ #include "ac/listbox.h" #include "ac/string.h" +namespace AGS3 { + void ListBoxClear(int guin, int objn) { GUIListBox *guisl = is_valid_listbox(guin, objn); ListBox_Clear(guisl); @@ -68,3 +70,5 @@ void ListBoxDirList(int guin, int objn, const char *filemask) { GUIListBox *guisl = is_valid_listbox(guin, objn); ListBox_FillDirList(guisl, filemask); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_mouse.cpp b/engines/ags/engine/ac/global_mouse.cpp index af7534661004..8b0e30bf5312 100644 --- a/engines/ags/engine/ac/global_mouse.cpp +++ b/engines/ags/engine/ac/global_mouse.cpp @@ -23,6 +23,8 @@ #include "ac/global_mouse.h" #include "ac/gamestate.h" +namespace AGS3 { + extern GameState play; void HideMouseCursor() { @@ -32,3 +34,5 @@ void HideMouseCursor() { void ShowMouseCursor() { play.mouse_cursor_hidden = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp index 53cae9bb3d88..4feb25f4fab7 100644 --- a/engines/ags/engine/ac/global_object.cpp +++ b/engines/ags/engine/ac/global_object.cpp @@ -45,6 +45,8 @@ #include "gfx/bitmap.h" #include "gfx/gfx_def.h" +namespace AGS3 { + using namespace AGS::Shared; #define OVERLAPPING_OBJECT 1000 @@ -60,7 +62,7 @@ extern int displayed_room; extern SpriteCache spriteset; extern int actSpsCount; extern Bitmap **actsps; -extern IDriverDependantBitmap * *actspsbmp; +extern IDriverDependantBitmap **actspsbmp; extern IGraphicsDriver *gfxDriver; // Used for deciding whether a char or obj was closer @@ -91,7 +93,7 @@ int GetObjectIDAtRoom(int roomx, int roomy) { Bitmap *theImage = GetObjectImage(aa, &isflipped); if (is_pos_in_sprite(roomx, roomy, xxx, yyy - spHeight, theImage, - spWidth, spHeight, isflipped) == FALSE) + spWidth, spHeight, isflipped) == FALSE) continue; int usebasel = objs[aa].get_baseline(); @@ -106,9 +108,9 @@ int GetObjectIDAtRoom(int roomx, int roomy) { void SetObjectTint(int obj, int red, int green, int blue, int opacity, int luminance) { if ((red < 0) || (green < 0) || (blue < 0) || - (red > 255) || (green > 255) || (blue > 255) || - (opacity < 0) || (opacity > 100) || - (luminance < 0) || (luminance > 100)) + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) quit("!SetObjectTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); if (!is_valid_object(obj)) @@ -473,7 +475,7 @@ int AreThingsOverlapping(int thing1, int thing2) { return 0; if ((r1.x2 > r2.x1) && (r1.x1 < r2.x2) && - (r1.y2 > r2.y1) && (r1.y1 < r2.y2)) { + (r1.y2 > r2.y1) && (r1.y1 < r2.y2)) { // determine how far apart they are // take the smaller of the X distances as the overlapping amount int xdist = abs(r1.x2 - r2.x1); @@ -515,3 +517,5 @@ Bitmap *GetObjectImage(int obj, int *isFlipped) { } return spriteset[objs[obj].num]; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp index 572a71cba51d..ddc79f05546c 100644 --- a/engines/ags/engine/ac/global_overlay.cpp +++ b/engines/ags/engine/ac/global_overlay.cpp @@ -35,6 +35,8 @@ #include "ac/system.h" #include "gfx/bitmap.h" +namespace AGS3 { + using namespace Shared; using namespace Engine; @@ -99,3 +101,5 @@ int IsOverlayValid(int ovrid) { return 1; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_palette.cpp b/engines/ags/engine/ac/global_palette.cpp index 25daf644a979..63a4f741e7cb 100644 --- a/engines/ags/engine/ac/global_palette.cpp +++ b/engines/ags/engine/ac/global_palette.cpp @@ -26,6 +26,8 @@ #include "ac/gamestate.h" #include "ac/global_palette.h" +namespace AGS3 { + extern GameSetupStruct game; extern GameState play; extern color palette[256]; @@ -72,3 +74,5 @@ void UpdatePalette() { if (!play.fast_forward) setpal(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_parser.cpp b/engines/ags/engine/ac/global_parser.cpp index 54bcb0852df2..6ae278cd1833 100644 --- a/engines/ags/engine/ac/global_parser.cpp +++ b/engines/ags/engine/ac/global_parser.cpp @@ -26,6 +26,8 @@ #include "ac/gamestate.h" #include "ac/string.h" +namespace AGS3 { + extern GameState play; int SaidUnknownWord(char *buffer) { @@ -35,3 +37,5 @@ int SaidUnknownWord(char *buffer) { return 0; return 1; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_record.cpp b/engines/ags/engine/ac/global_record.cpp index ef251f9ebf62..9f2358045d80 100644 --- a/engines/ags/engine/ac/global_record.cpp +++ b/engines/ags/engine/ac/global_record.cpp @@ -23,6 +23,10 @@ #include "ac/global_record.h" #include "ac/common.h" +namespace AGS3 { + void scStartRecording(int keyToStop) { quit("!StartRecording: not supported"); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp index e02e28e5822f..e607e353c586 100644 --- a/engines/ags/engine/ac/global_region.cpp +++ b/engines/ags/engine/ac/global_region.cpp @@ -31,6 +31,7 @@ #include "gfx/bitmap.h" #include "script/script.h" +namespace AGS3 { using namespace AGS::Shared; @@ -70,7 +71,7 @@ void SetAreaLightLevel(int area, int brightness) { if (brightness > 100) brightness = 100; thisroom.Regions[area].Light = brightness; // disable RGB tint for this area - thisroom.Regions[area].Tint = 0; + thisroom.Regions[area].Tint = 0; debug_script_log("Region %d light level set to %d", area, brightness); } @@ -79,7 +80,7 @@ void SetRegionTint(int area, int red, int green, int blue, int amount, int lumin quit("!SetRegionTint: invalid region"); if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || - (blue < 0) || (blue > 255)) { + (blue < 0) || (blue > 255)) { quit("!SetRegionTint: RGB values must be 0-255"); } @@ -100,9 +101,9 @@ void SetRegionTint(int area, int red, int green, int blue, int amount, int lumin blue -= 100;*/ thisroom.Regions[area].Tint = (red & 0xFF) | - ((green & 0xFF) << 8) | - ((blue & 0XFF) << 16) | - ((amount & 0xFF) << 24); + ((green & 0xFF) << 8) | + ((blue & 0XFF) << 16) | + ((amount & 0xFF) << 24); thisroom.Regions[area].Light = (luminance * 25) / 10; } @@ -165,3 +166,5 @@ void RunRegionInteraction(int regnum, int mood) { evblockbasename = oldbasename; evblocknum = oldblocknum; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp index 1b55d8f42e7e..7fadb5a72b5c 100644 --- a/engines/ags/engine/ac/global_room.cpp +++ b/engines/ags/engine/ac/global_room.cpp @@ -39,6 +39,8 @@ #include "script/script.h" #include "util/math.h" +namespace AGS3 { + using namespace Shared; extern GameState play; @@ -55,9 +57,9 @@ extern RoomStruct thisroom; void SetAmbientTint(int red, int green, int blue, int opacity, int luminance) { if ((red < 0) || (green < 0) || (blue < 0) || - (red > 255) || (green > 255) || (blue > 255) || - (opacity < 0) || (opacity > 100) || - (luminance < 0) || (luminance > 100)) + (red > 255) || (green > 255) || (blue > 255) || + (opacity < 0) || (opacity > 100) || + (luminance < 0) || (luminance > 100)) quit("!SetTint: invalid parameter. R,G,B must be 0-255, opacity & luminance 0-100"); debug_script_log("Set ambient tint RGB(%d,%d,%d) %d%%", red, green, blue, opacity); @@ -100,7 +102,7 @@ void NewRoom(int nrnum) { play.stop_dialog_at_end = DIALOG_NEWROOM + nrnum; else { quitprintf("!NewRoom: two NewRoom/RunDialog/StopDialog requests within dialog; last was called in \"%s\", line %d", - last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); + last_in_dialog_request_script_pos.Section.GetCStr(), last_in_dialog_request_script_pos.Line); } return; } @@ -220,3 +222,5 @@ void SetBackgroundFrame(int frnum) { int GetBackgroundFrame() { return play.bg_frame; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp index c8cb0f04d90a..8ae85266af07 100644 --- a/engines/ags/engine/ac/global_screen.cpp +++ b/engines/ags/engine/ac/global_screen.cpp @@ -35,6 +35,8 @@ #include "gfx/graphicsdriver.h" #include "gfx/bitmap.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -164,7 +166,7 @@ void SetNextScreenTransition(int newtrans) { void SetFadeColor(int red, int green, int blue) { if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || - (blue < 0) || (blue > 255)) + (blue < 0) || (blue > 255)) quit("!SetFadeColor: Red, Green and Blue must be 0-255"); play.fade_to_red = red; @@ -180,3 +182,5 @@ void FadeIn(int sppd) { my_fade_in(palette, sppd); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp index 512af4c99dc4..b05ddacc0f25 100644 --- a/engines/ags/engine/ac/global_slider.cpp +++ b/engines/ags/engine/ac/global_slider.cpp @@ -27,6 +27,8 @@ #include "gui/guimain.h" #include "gui/guislider.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -48,3 +50,5 @@ int GetSliderValue(int guin, int objn) { GUISlider *guisl = (GUISlider *)guis[guin].GetControl(objn); return Slider_GetValue(guisl); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_string.cpp b/engines/ags/engine/ac/global_string.cpp index 751932012936..974b6cea23d9 100644 --- a/engines/ags/engine/ac/global_string.cpp +++ b/engines/ags/engine/ac/global_string.cpp @@ -28,6 +28,8 @@ #include "ac/string.h" #include "util/string_compat.h" +namespace AGS3 { + extern int MAXSTRLEN; int StrGetCharAt(const char *strin, int posn) { @@ -79,3 +81,5 @@ void _sc_strcpy(char *destt, const char *text) { check_strlen(destt); my_strncpy(destt, text, MAXSTRLEN - 1); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp index 8cdbe69b2e53..2f2bf556a0d5 100644 --- a/engines/ags/engine/ac/global_textbox.cpp +++ b/engines/ags/engine/ac/global_textbox.cpp @@ -28,6 +28,8 @@ #include "gui/guimain.h" #include "gui/guitextbox.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -63,3 +65,5 @@ void SetTextBoxText(int guin, int objn, const char *txbuf) { GUITextBox *guisl = (GUITextBox *)guis[guin].GetControl(objn); TextBox_SetText(guisl, txbuf); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_timer.cpp b/engines/ags/engine/ac/global_timer.cpp index cc4373bcc550..04b325961ecd 100644 --- a/engines/ags/engine/ac/global_timer.cpp +++ b/engines/ags/engine/ac/global_timer.cpp @@ -25,6 +25,8 @@ #include "ac/common.h" #include "ac/gamestate.h" +namespace AGS3 { + extern GameState play; @@ -43,3 +45,5 @@ int IsTimerExpired(int tnum) { } return 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index d2a7b90d2323..e27b75dee67c 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -33,6 +33,8 @@ #include "util/memory.h" #include "core/types.h" +namespace AGS3 { + using namespace AGS::Shared::Memory; extern GameState play; @@ -89,3 +91,5 @@ int GetTranslationName(char *buffer) { return IsTranslationAvailable(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp index 20582e0dcdb7..0aa8b375daf9 100644 --- a/engines/ags/engine/ac/global_video.cpp +++ b/engines/ags/engine/ac/global_video.cpp @@ -33,6 +33,7 @@ #include "platform/base/agsplatformdriver.h" #include "util/string_compat.h" +namespace AGS3 { void scrPlayVideo(const char *name, int skip, int flags) { EndSkippingUntilCharStops(); @@ -83,6 +84,9 @@ void pause_sound_if_necessary_and_play_video(const char *name, int skip, int fla #else -void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags) {} +void pause_sound_if_necessary_and_play_video(const char *name, int skip, int flags) { +} #endif + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_viewframe.cpp b/engines/ags/engine/ac/global_viewframe.cpp index ad5f8da4144a..8a8f2942cfdf 100644 --- a/engines/ags/engine/ac/global_viewframe.cpp +++ b/engines/ags/engine/ac/global_viewframe.cpp @@ -27,6 +27,8 @@ #include "debug/debug_log.h" #include "media/audio/audio_system.h" +namespace AGS3 { + extern GameSetupStruct game; extern ViewStruct *views; @@ -52,3 +54,5 @@ void SetFrameSound(int vii, int loop, int frame, int sound) { views[vii].loops[loop].frames[frame].sound = clip->id + (game.IsLegacyAudioSystem() ? 0x10000000 : 0); } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_viewport.cpp b/engines/ags/engine/ac/global_viewport.cpp index cd64d8117cac..456c5822411f 100644 --- a/engines/ags/engine/ac/global_viewport.cpp +++ b/engines/ags/engine/ac/global_viewport.cpp @@ -24,6 +24,8 @@ #include "ac/draw.h" #include "debug/debug_log.h" +namespace AGS3 { + void SetViewport(int offsx, int offsy) { offsx = data_to_game_coord(offsx); offsy = data_to_game_coord(offsy); @@ -38,3 +40,5 @@ int GetViewportX() { int GetViewportY() { return game_to_data_coord(play.GetRoomCamera(0)->GetRect().Top); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp index bd57d417f7d1..ca23e25a3561 100644 --- a/engines/ags/engine/ac/global_walkablearea.cpp +++ b/engines/ags/engine/ac/global_walkablearea.cpp @@ -28,6 +28,8 @@ #include "debug/debug_log.h" #include "game/roomstruct.h" +namespace AGS3 { + using namespace AGS::Shared; extern RoomStruct thisroom; @@ -94,5 +96,4 @@ int GetWalkableAreaAtRoom(int x, int y) { return area >= 0 && area < (MAX_WALK_AREAS + 1) ? area : 0; } -//============================================================================= - +} // namespace AGS3 diff --git a/engines/ags/engine/ac/global_walkbehind.cpp b/engines/ags/engine/ac/global_walkbehind.cpp index e48d80bd0485..d49685c54b22 100644 --- a/engines/ags/engine/ac/global_walkbehind.cpp +++ b/engines/ags/engine/ac/global_walkbehind.cpp @@ -28,6 +28,8 @@ #include "ac/walkbehind.h" #include "debug/debug_log.h" +namespace AGS3 { + extern RoomStatus *croom; extern int walk_behind_baselines_changed; @@ -42,3 +44,5 @@ void SetWalkBehindBase(int wa, int bl) { debug_script_log("Walk-behind %d baseline changed to %d", wa, bl); } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp index 060914d46801..0d5d481f0fac 100644 --- a/engines/ags/engine/ac/gui.cpp +++ b/engines/ags/engine/ac/gui.cpp @@ -55,6 +55,7 @@ #include "script/runtimescriptvalue.h" #include "util/string_compat.h" +namespace AGS3 { using namespace AGS::Shared; using namespace AGS::Engine; @@ -334,8 +335,8 @@ void process_interface_click(int ifce, int btn, int mbut) { if (btn < 0) { // click on GUI background QueueScriptFunction(kScInstGame, guis[ifce].OnClickHandler, 2, - RuntimeScriptValue().SetDynamicObject(&scrGui[ifce], &ccDynamicGUI), - RuntimeScriptValue().SetInt32(mbut)); + RuntimeScriptValue().SetDynamicObject(&scrGui[ifce], &ccDynamicGUI), + RuntimeScriptValue().SetInt32(mbut)); return; } @@ -349,7 +350,7 @@ void process_interface_click(int ifce, int btn, int mbut) { rtype = kGUIAction_RunScript; else quit("unknown GUI object triggered process_interface"); - if (rtype == kGUIAction_None) ; + if (rtype == kGUIAction_None); else if (rtype == kGUIAction_SetMode) set_cursor_mode(rdata); else if (rtype == kGUIAction_RunScript) { @@ -357,20 +358,20 @@ void process_interface_click(int ifce, int btn, int mbut) { // if the object has a special handler script then run it; // otherwise, run interface_click if ((theObj->GetEventCount() > 0) && - (!theObj->EventHandlers[0].IsEmpty()) && - (!gameinst->GetSymbolAddress(theObj->EventHandlers[0]).IsNull())) { + (!theObj->EventHandlers[0].IsEmpty()) && + (!gameinst->GetSymbolAddress(theObj->EventHandlers[0]).IsNull())) { // control-specific event handler if (strchr(theObj->GetEventArgs(0), ',') != nullptr) QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 2, - RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject), - RuntimeScriptValue().SetInt32(mbut)); + RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject), + RuntimeScriptValue().SetInt32(mbut)); else QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 1, - RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject)); + RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject)); } else QueueScriptFunction(kScInstGame, "interface_click", 2, - RuntimeScriptValue().SetInt32(ifce), - RuntimeScriptValue().SetInt32(btn)); + RuntimeScriptValue().SetInt32(ifce), + RuntimeScriptValue().SetInt32(btn)); } } @@ -586,7 +587,7 @@ int gui_get_interactable(int x, int y) { int gui_on_mouse_move() { int mouse_over_gui = -1; // If all GUIs are off, skip the loop - if ((game.options[OPT_DISABLEOFF] == 3) && (all_buttons_disabled > 0)) ; + if ((game.options[OPT_DISABLEOFF] == 3) && (all_buttons_disabled > 0)); else { // Scan for mouse-y-pos GUIs, and pop one up if appropriate // Also work out the mouse-over GUI while we're at it @@ -870,45 +871,45 @@ RuntimeScriptValue Sc_GUI_ProcessClick(const RuntimeScriptValue *params, int32_t } void RegisterGUIAPI() { - ccAddExternalObjectFunction("GUI::Centre^0", Sc_GUI_Centre); - ccAddExternalObjectFunction("GUI::Click^1", Sc_GUI_Click); - ccAddExternalStaticFunction("GUI::GetAtScreenXY^2", Sc_GetGUIAtLocation); - ccAddExternalStaticFunction("GUI::ProcessClick^3", Sc_GUI_ProcessClick); - ccAddExternalObjectFunction("GUI::SetPosition^2", Sc_GUI_SetPosition); - ccAddExternalObjectFunction("GUI::SetSize^2", Sc_GUI_SetSize); - ccAddExternalObjectFunction("GUI::get_BackgroundGraphic", Sc_GUI_GetBackgroundGraphic); - ccAddExternalObjectFunction("GUI::set_BackgroundGraphic", Sc_GUI_SetBackgroundGraphic); - ccAddExternalObjectFunction("GUI::get_BackgroundColor", Sc_GUI_GetBackgroundColor); - ccAddExternalObjectFunction("GUI::set_BackgroundColor", Sc_GUI_SetBackgroundColor); - ccAddExternalObjectFunction("GUI::get_BorderColor", Sc_GUI_GetBorderColor); - ccAddExternalObjectFunction("GUI::set_BorderColor", Sc_GUI_SetBorderColor); - ccAddExternalObjectFunction("GUI::get_Clickable", Sc_GUI_GetClickable); - ccAddExternalObjectFunction("GUI::set_Clickable", Sc_GUI_SetClickable); - ccAddExternalObjectFunction("GUI::get_ControlCount", Sc_GUI_GetControlCount); - ccAddExternalObjectFunction("GUI::geti_Controls", Sc_GUI_GetiControls); - ccAddExternalObjectFunction("GUI::get_Height", Sc_GUI_GetHeight); - ccAddExternalObjectFunction("GUI::set_Height", Sc_GUI_SetHeight); - ccAddExternalObjectFunction("GUI::get_ID", Sc_GUI_GetID); - ccAddExternalObjectFunction("GUI::get_AsTextWindow", Sc_GUI_AsTextWindow); - ccAddExternalObjectFunction("GUI::get_PopupStyle", Sc_GUI_GetPopupStyle); - ccAddExternalObjectFunction("GUI::get_PopupYPos", Sc_GUI_GetPopupYPos); - ccAddExternalObjectFunction("GUI::set_PopupYPos", Sc_GUI_SetPopupYPos); + ccAddExternalObjectFunction("GUI::Centre^0", Sc_GUI_Centre); + ccAddExternalObjectFunction("GUI::Click^1", Sc_GUI_Click); + ccAddExternalStaticFunction("GUI::GetAtScreenXY^2", Sc_GetGUIAtLocation); + ccAddExternalStaticFunction("GUI::ProcessClick^3", Sc_GUI_ProcessClick); + ccAddExternalObjectFunction("GUI::SetPosition^2", Sc_GUI_SetPosition); + ccAddExternalObjectFunction("GUI::SetSize^2", Sc_GUI_SetSize); + ccAddExternalObjectFunction("GUI::get_BackgroundGraphic", Sc_GUI_GetBackgroundGraphic); + ccAddExternalObjectFunction("GUI::set_BackgroundGraphic", Sc_GUI_SetBackgroundGraphic); + ccAddExternalObjectFunction("GUI::get_BackgroundColor", Sc_GUI_GetBackgroundColor); + ccAddExternalObjectFunction("GUI::set_BackgroundColor", Sc_GUI_SetBackgroundColor); + ccAddExternalObjectFunction("GUI::get_BorderColor", Sc_GUI_GetBorderColor); + ccAddExternalObjectFunction("GUI::set_BorderColor", Sc_GUI_SetBorderColor); + ccAddExternalObjectFunction("GUI::get_Clickable", Sc_GUI_GetClickable); + ccAddExternalObjectFunction("GUI::set_Clickable", Sc_GUI_SetClickable); + ccAddExternalObjectFunction("GUI::get_ControlCount", Sc_GUI_GetControlCount); + ccAddExternalObjectFunction("GUI::geti_Controls", Sc_GUI_GetiControls); + ccAddExternalObjectFunction("GUI::get_Height", Sc_GUI_GetHeight); + ccAddExternalObjectFunction("GUI::set_Height", Sc_GUI_SetHeight); + ccAddExternalObjectFunction("GUI::get_ID", Sc_GUI_GetID); + ccAddExternalObjectFunction("GUI::get_AsTextWindow", Sc_GUI_AsTextWindow); + ccAddExternalObjectFunction("GUI::get_PopupStyle", Sc_GUI_GetPopupStyle); + ccAddExternalObjectFunction("GUI::get_PopupYPos", Sc_GUI_GetPopupYPos); + ccAddExternalObjectFunction("GUI::set_PopupYPos", Sc_GUI_SetPopupYPos); ccAddExternalObjectFunction("TextWindowGUI::get_TextColor", Sc_GUI_GetTextColor); ccAddExternalObjectFunction("TextWindowGUI::set_TextColor", Sc_GUI_SetTextColor); ccAddExternalObjectFunction("TextWindowGUI::get_TextPadding", Sc_GUI_GetTextPadding); ccAddExternalObjectFunction("TextWindowGUI::set_TextPadding", Sc_GUI_SetTextPadding); - ccAddExternalObjectFunction("GUI::get_Transparency", Sc_GUI_GetTransparency); - ccAddExternalObjectFunction("GUI::set_Transparency", Sc_GUI_SetTransparency); - ccAddExternalObjectFunction("GUI::get_Visible", Sc_GUI_GetVisible); - ccAddExternalObjectFunction("GUI::set_Visible", Sc_GUI_SetVisible); - ccAddExternalObjectFunction("GUI::get_Width", Sc_GUI_GetWidth); - ccAddExternalObjectFunction("GUI::set_Width", Sc_GUI_SetWidth); - ccAddExternalObjectFunction("GUI::get_X", Sc_GUI_GetX); - ccAddExternalObjectFunction("GUI::set_X", Sc_GUI_SetX); - ccAddExternalObjectFunction("GUI::get_Y", Sc_GUI_GetY); - ccAddExternalObjectFunction("GUI::set_Y", Sc_GUI_SetY); - ccAddExternalObjectFunction("GUI::get_ZOrder", Sc_GUI_GetZOrder); - ccAddExternalObjectFunction("GUI::set_ZOrder", Sc_GUI_SetZOrder); + ccAddExternalObjectFunction("GUI::get_Transparency", Sc_GUI_GetTransparency); + ccAddExternalObjectFunction("GUI::set_Transparency", Sc_GUI_SetTransparency); + ccAddExternalObjectFunction("GUI::get_Visible", Sc_GUI_GetVisible); + ccAddExternalObjectFunction("GUI::set_Visible", Sc_GUI_SetVisible); + ccAddExternalObjectFunction("GUI::get_Width", Sc_GUI_GetWidth); + ccAddExternalObjectFunction("GUI::set_Width", Sc_GUI_SetWidth); + ccAddExternalObjectFunction("GUI::get_X", Sc_GUI_GetX); + ccAddExternalObjectFunction("GUI::set_X", Sc_GUI_SetX); + ccAddExternalObjectFunction("GUI::get_Y", Sc_GUI_GetY); + ccAddExternalObjectFunction("GUI::set_Y", Sc_GUI_SetY); + ccAddExternalObjectFunction("GUI::get_ZOrder", Sc_GUI_GetZOrder); + ccAddExternalObjectFunction("GUI::set_ZOrder", Sc_GUI_SetZOrder); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -938,3 +939,5 @@ void RegisterGUIAPI() { ccAddExternalFunctionForPlugin("GUI::get_ZOrder", (void *)GUI_GetZOrder); ccAddExternalFunctionForPlugin("GUI::set_ZOrder", (void *)GUI_SetZOrder); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp index edb96d95cd7d..99cde3bd0e62 100644 --- a/engines/ags/engine/ac/guicontrol.cpp +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -35,6 +35,8 @@ #include "ac/dynobj/cc_gui.h" #include "ac/dynobj/cc_guiobject.h" +namespace AGS3 { + using namespace AGS::Shared; extern ScriptGUI *scrGui; @@ -385,35 +387,35 @@ RuntimeScriptValue Sc_GUIControl_SetZOrder(void *self, const RuntimeScriptValue void RegisterGUIControlAPI() { - ccAddExternalObjectFunction("GUIControl::BringToFront^0", Sc_GUIControl_BringToFront); - ccAddExternalStaticFunction("GUIControl::GetAtScreenXY^2", Sc_GetGUIControlAtLocation); - ccAddExternalObjectFunction("GUIControl::SendToBack^0", Sc_GUIControl_SendToBack); - ccAddExternalObjectFunction("GUIControl::SetPosition^2", Sc_GUIControl_SetPosition); - ccAddExternalObjectFunction("GUIControl::SetSize^2", Sc_GUIControl_SetSize); - ccAddExternalObjectFunction("GUIControl::get_AsButton", Sc_GUIControl_GetAsButton); - ccAddExternalObjectFunction("GUIControl::get_AsInvWindow", Sc_GUIControl_GetAsInvWindow); - ccAddExternalObjectFunction("GUIControl::get_AsLabel", Sc_GUIControl_GetAsLabel); - ccAddExternalObjectFunction("GUIControl::get_AsListBox", Sc_GUIControl_GetAsListBox); - ccAddExternalObjectFunction("GUIControl::get_AsSlider", Sc_GUIControl_GetAsSlider); - ccAddExternalObjectFunction("GUIControl::get_AsTextBox", Sc_GUIControl_GetAsTextBox); - ccAddExternalObjectFunction("GUIControl::get_Clickable", Sc_GUIControl_GetClickable); - ccAddExternalObjectFunction("GUIControl::set_Clickable", Sc_GUIControl_SetClickable); - ccAddExternalObjectFunction("GUIControl::get_Enabled", Sc_GUIControl_GetEnabled); - ccAddExternalObjectFunction("GUIControl::set_Enabled", Sc_GUIControl_SetEnabled); - ccAddExternalObjectFunction("GUIControl::get_Height", Sc_GUIControl_GetHeight); - ccAddExternalObjectFunction("GUIControl::set_Height", Sc_GUIControl_SetHeight); - ccAddExternalObjectFunction("GUIControl::get_ID", Sc_GUIControl_GetID); - ccAddExternalObjectFunction("GUIControl::get_OwningGUI", Sc_GUIControl_GetOwningGUI); - ccAddExternalObjectFunction("GUIControl::get_Visible", Sc_GUIControl_GetVisible); - ccAddExternalObjectFunction("GUIControl::set_Visible", Sc_GUIControl_SetVisible); - ccAddExternalObjectFunction("GUIControl::get_Width", Sc_GUIControl_GetWidth); - ccAddExternalObjectFunction("GUIControl::set_Width", Sc_GUIControl_SetWidth); - ccAddExternalObjectFunction("GUIControl::get_X", Sc_GUIControl_GetX); - ccAddExternalObjectFunction("GUIControl::set_X", Sc_GUIControl_SetX); - ccAddExternalObjectFunction("GUIControl::get_Y", Sc_GUIControl_GetY); - ccAddExternalObjectFunction("GUIControl::set_Y", Sc_GUIControl_SetY); - ccAddExternalObjectFunction("GUIControl::get_ZOrder", Sc_GUIControl_GetZOrder); - ccAddExternalObjectFunction("GUIControl::set_ZOrder", Sc_GUIControl_SetZOrder); + ccAddExternalObjectFunction("GUIControl::BringToFront^0", Sc_GUIControl_BringToFront); + ccAddExternalStaticFunction("GUIControl::GetAtScreenXY^2", Sc_GetGUIControlAtLocation); + ccAddExternalObjectFunction("GUIControl::SendToBack^0", Sc_GUIControl_SendToBack); + ccAddExternalObjectFunction("GUIControl::SetPosition^2", Sc_GUIControl_SetPosition); + ccAddExternalObjectFunction("GUIControl::SetSize^2", Sc_GUIControl_SetSize); + ccAddExternalObjectFunction("GUIControl::get_AsButton", Sc_GUIControl_GetAsButton); + ccAddExternalObjectFunction("GUIControl::get_AsInvWindow", Sc_GUIControl_GetAsInvWindow); + ccAddExternalObjectFunction("GUIControl::get_AsLabel", Sc_GUIControl_GetAsLabel); + ccAddExternalObjectFunction("GUIControl::get_AsListBox", Sc_GUIControl_GetAsListBox); + ccAddExternalObjectFunction("GUIControl::get_AsSlider", Sc_GUIControl_GetAsSlider); + ccAddExternalObjectFunction("GUIControl::get_AsTextBox", Sc_GUIControl_GetAsTextBox); + ccAddExternalObjectFunction("GUIControl::get_Clickable", Sc_GUIControl_GetClickable); + ccAddExternalObjectFunction("GUIControl::set_Clickable", Sc_GUIControl_SetClickable); + ccAddExternalObjectFunction("GUIControl::get_Enabled", Sc_GUIControl_GetEnabled); + ccAddExternalObjectFunction("GUIControl::set_Enabled", Sc_GUIControl_SetEnabled); + ccAddExternalObjectFunction("GUIControl::get_Height", Sc_GUIControl_GetHeight); + ccAddExternalObjectFunction("GUIControl::set_Height", Sc_GUIControl_SetHeight); + ccAddExternalObjectFunction("GUIControl::get_ID", Sc_GUIControl_GetID); + ccAddExternalObjectFunction("GUIControl::get_OwningGUI", Sc_GUIControl_GetOwningGUI); + ccAddExternalObjectFunction("GUIControl::get_Visible", Sc_GUIControl_GetVisible); + ccAddExternalObjectFunction("GUIControl::set_Visible", Sc_GUIControl_SetVisible); + ccAddExternalObjectFunction("GUIControl::get_Width", Sc_GUIControl_GetWidth); + ccAddExternalObjectFunction("GUIControl::set_Width", Sc_GUIControl_SetWidth); + ccAddExternalObjectFunction("GUIControl::get_X", Sc_GUIControl_GetX); + ccAddExternalObjectFunction("GUIControl::set_X", Sc_GUIControl_SetX); + ccAddExternalObjectFunction("GUIControl::get_Y", Sc_GUIControl_GetY); + ccAddExternalObjectFunction("GUIControl::set_Y", Sc_GUIControl_SetY); + ccAddExternalObjectFunction("GUIControl::get_ZOrder", Sc_GUIControl_GetZOrder); + ccAddExternalObjectFunction("GUIControl::set_ZOrder", Sc_GUIControl_SetZOrder); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -445,3 +447,5 @@ void RegisterGUIControlAPI() { ccAddExternalFunctionForPlugin("GUIControl::get_Y", (void *)GUIControl_GetY); ccAddExternalFunctionForPlugin("GUIControl::set_Y", (void *)GUIControl_SetY); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/guiinv.cpp b/engines/ags/engine/ac/guiinv.cpp index ef3608d34e09..8110cc71ce86 100644 --- a/engines/ags/engine/ac/guiinv.cpp +++ b/engines/ags/engine/ac/guiinv.cpp @@ -29,6 +29,7 @@ #include "ac/spritecache.h" #include "gfx/bitmap.h" +namespace AGS3 { extern GameSetupStruct game; extern int gui_disabled_style; @@ -84,8 +85,8 @@ void GUIInvWindow::Draw(Bitmap *ds) { } if (!enabled && - gui_disabled_style == GUIDIS_GREYOUT && - play.inventory_greys_out == 1) { + gui_disabled_style == GUIDIS_GREYOUT && + play.inventory_greys_out == 1) { // darken the inventory when disabled GUI::DrawDisabledEffect(ds, RectWH(X, Y, Width, Height)); } @@ -93,3 +94,4 @@ void GUIInvWindow::Draw(Bitmap *ds) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp index a57a57a45802..f839323f7ca0 100644 --- a/engines/ags/engine/ac/hotspot.cpp +++ b/engines/ags/engine/ac/hotspot.cpp @@ -33,6 +33,8 @@ #include "gfx/bitmap.h" #include "script/runtimescriptvalue.h" +namespace AGS3 { + using namespace AGS::Shared; extern RoomStruct thisroom; @@ -217,23 +219,23 @@ RuntimeScriptValue Sc_Hotspot_GetWalkToY(void *self, const RuntimeScriptValue *p void RegisterHotspotAPI() { - ccAddExternalStaticFunction("Hotspot::GetAtRoomXY^2", Sc_GetHotspotAtRoom); - ccAddExternalStaticFunction("Hotspot::GetAtScreenXY^2", Sc_GetHotspotAtScreen); - ccAddExternalStaticFunction("Hotspot::GetDrawingSurface", Sc_Hotspot_GetDrawingSurface); - ccAddExternalObjectFunction("Hotspot::GetName^1", Sc_Hotspot_GetName); - ccAddExternalObjectFunction("Hotspot::GetProperty^1", Sc_Hotspot_GetProperty); - ccAddExternalObjectFunction("Hotspot::GetPropertyText^2", Sc_Hotspot_GetPropertyText); - ccAddExternalObjectFunction("Hotspot::GetTextProperty^1", Sc_Hotspot_GetTextProperty); - ccAddExternalObjectFunction("Hotspot::SetProperty^2", Sc_Hotspot_SetProperty); - ccAddExternalObjectFunction("Hotspot::SetTextProperty^2", Sc_Hotspot_SetTextProperty); + ccAddExternalStaticFunction("Hotspot::GetAtRoomXY^2", Sc_GetHotspotAtRoom); + ccAddExternalStaticFunction("Hotspot::GetAtScreenXY^2", Sc_GetHotspotAtScreen); + ccAddExternalStaticFunction("Hotspot::GetDrawingSurface", Sc_Hotspot_GetDrawingSurface); + ccAddExternalObjectFunction("Hotspot::GetName^1", Sc_Hotspot_GetName); + ccAddExternalObjectFunction("Hotspot::GetProperty^1", Sc_Hotspot_GetProperty); + ccAddExternalObjectFunction("Hotspot::GetPropertyText^2", Sc_Hotspot_GetPropertyText); + ccAddExternalObjectFunction("Hotspot::GetTextProperty^1", Sc_Hotspot_GetTextProperty); + ccAddExternalObjectFunction("Hotspot::SetProperty^2", Sc_Hotspot_SetProperty); + ccAddExternalObjectFunction("Hotspot::SetTextProperty^2", Sc_Hotspot_SetTextProperty); ccAddExternalObjectFunction("Hotspot::IsInteractionAvailable^1", Sc_Hotspot_IsInteractionAvailable); - ccAddExternalObjectFunction("Hotspot::RunInteraction^1", Sc_Hotspot_RunInteraction); - ccAddExternalObjectFunction("Hotspot::get_Enabled", Sc_Hotspot_GetEnabled); - ccAddExternalObjectFunction("Hotspot::set_Enabled", Sc_Hotspot_SetEnabled); - ccAddExternalObjectFunction("Hotspot::get_ID", Sc_Hotspot_GetID); - ccAddExternalObjectFunction("Hotspot::get_Name", Sc_Hotspot_GetName_New); - ccAddExternalObjectFunction("Hotspot::get_WalkToX", Sc_Hotspot_GetWalkToX); - ccAddExternalObjectFunction("Hotspot::get_WalkToY", Sc_Hotspot_GetWalkToY); + ccAddExternalObjectFunction("Hotspot::RunInteraction^1", Sc_Hotspot_RunInteraction); + ccAddExternalObjectFunction("Hotspot::get_Enabled", Sc_Hotspot_GetEnabled); + ccAddExternalObjectFunction("Hotspot::set_Enabled", Sc_Hotspot_SetEnabled); + ccAddExternalObjectFunction("Hotspot::get_ID", Sc_Hotspot_GetID); + ccAddExternalObjectFunction("Hotspot::get_Name", Sc_Hotspot_GetName_New); + ccAddExternalObjectFunction("Hotspot::get_WalkToX", Sc_Hotspot_GetWalkToX); + ccAddExternalObjectFunction("Hotspot::get_WalkToY", Sc_Hotspot_GetWalkToY); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -251,3 +253,5 @@ void RegisterHotspotAPI() { ccAddExternalFunctionForPlugin("Hotspot::get_WalkToX", (void *)Hotspot_GetWalkToX); ccAddExternalFunctionForPlugin("Hotspot::get_WalkToY", (void *)Hotspot_GetWalkToY); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/interfacebutton.cpp b/engines/ags/engine/ac/interfacebutton.cpp index d10d90c8d44f..293870287d46 100644 --- a/engines/ags/engine/ac/interfacebutton.cpp +++ b/engines/ags/engine/ac/interfacebutton.cpp @@ -22,6 +22,8 @@ #include "ac/interfacebutton.h" +namespace AGS3 { + void InterfaceButton::set(int xx, int yy, int picc, int overpicc, int actionn) { x = xx; y = yy; @@ -33,3 +35,5 @@ void InterfaceButton::set(int xx, int yy, int picc, int overpicc, int actionn) { flags = IBFLG_ENABLED; reserved_for_future = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/interfaceelement.cpp b/engines/ags/engine/ac/interfaceelement.cpp index 154ce79e57a1..5da22509f5c7 100644 --- a/engines/ags/engine/ac/interfaceelement.cpp +++ b/engines/ags/engine/ac/interfaceelement.cpp @@ -23,6 +23,8 @@ #include #include "ac/interfaceelement.h" +namespace AGS3 { + InterfaceElement::InterfaceElement() { vtextxp = 0; vtextyp = 1; @@ -34,3 +36,5 @@ InterfaceElement::InterfaceElement() { on = 1; flags = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp index a32161f16b48..e71a20ad60ec 100644 --- a/engines/ags/engine/ac/inventoryitem.cpp +++ b/engines/ags/engine/ac/inventoryitem.cpp @@ -33,6 +33,7 @@ #include "script/runtimescriptvalue.h" #include "ac/dynobj/cc_inventory.h" +namespace AGS3 { extern GameSetupStruct game; extern ScriptInvItem scrInv[MAX_INV]; @@ -213,23 +214,23 @@ RuntimeScriptValue Sc_InventoryItem_GetName_New(void *self, const RuntimeScriptV void RegisterInventoryItemAPI() { - ccAddExternalStaticFunction("InventoryItem::GetAtScreenXY^2", Sc_GetInvAtLocation); - ccAddExternalObjectFunction("InventoryItem::IsInteractionAvailable^1", Sc_InventoryItem_CheckInteractionAvailable); - ccAddExternalObjectFunction("InventoryItem::GetName^1", Sc_InventoryItem_GetName); - ccAddExternalObjectFunction("InventoryItem::GetProperty^1", Sc_InventoryItem_GetProperty); - ccAddExternalObjectFunction("InventoryItem::GetPropertyText^2", Sc_InventoryItem_GetPropertyText); - ccAddExternalObjectFunction("InventoryItem::GetTextProperty^1", Sc_InventoryItem_GetTextProperty); - ccAddExternalObjectFunction("InventoryItem::SetProperty^2", Sc_InventoryItem_SetProperty); - ccAddExternalObjectFunction("InventoryItem::SetTextProperty^2", Sc_InventoryItem_SetTextProperty); - ccAddExternalObjectFunction("InventoryItem::RunInteraction^1", Sc_InventoryItem_RunInteraction); - ccAddExternalObjectFunction("InventoryItem::SetName^1", Sc_InventoryItem_SetName); - ccAddExternalObjectFunction("InventoryItem::get_CursorGraphic", Sc_InventoryItem_GetCursorGraphic); - ccAddExternalObjectFunction("InventoryItem::set_CursorGraphic", Sc_InventoryItem_SetCursorGraphic); - ccAddExternalObjectFunction("InventoryItem::get_Graphic", Sc_InventoryItem_GetGraphic); - ccAddExternalObjectFunction("InventoryItem::set_Graphic", Sc_InventoryItem_SetGraphic); - ccAddExternalObjectFunction("InventoryItem::get_ID", Sc_InventoryItem_GetID); - ccAddExternalObjectFunction("InventoryItem::get_Name", Sc_InventoryItem_GetName_New); - ccAddExternalObjectFunction("InventoryItem::set_Name", Sc_InventoryItem_SetName); + ccAddExternalStaticFunction("InventoryItem::GetAtScreenXY^2", Sc_GetInvAtLocation); + ccAddExternalObjectFunction("InventoryItem::IsInteractionAvailable^1", Sc_InventoryItem_CheckInteractionAvailable); + ccAddExternalObjectFunction("InventoryItem::GetName^1", Sc_InventoryItem_GetName); + ccAddExternalObjectFunction("InventoryItem::GetProperty^1", Sc_InventoryItem_GetProperty); + ccAddExternalObjectFunction("InventoryItem::GetPropertyText^2", Sc_InventoryItem_GetPropertyText); + ccAddExternalObjectFunction("InventoryItem::GetTextProperty^1", Sc_InventoryItem_GetTextProperty); + ccAddExternalObjectFunction("InventoryItem::SetProperty^2", Sc_InventoryItem_SetProperty); + ccAddExternalObjectFunction("InventoryItem::SetTextProperty^2", Sc_InventoryItem_SetTextProperty); + ccAddExternalObjectFunction("InventoryItem::RunInteraction^1", Sc_InventoryItem_RunInteraction); + ccAddExternalObjectFunction("InventoryItem::SetName^1", Sc_InventoryItem_SetName); + ccAddExternalObjectFunction("InventoryItem::get_CursorGraphic", Sc_InventoryItem_GetCursorGraphic); + ccAddExternalObjectFunction("InventoryItem::set_CursorGraphic", Sc_InventoryItem_SetCursorGraphic); + ccAddExternalObjectFunction("InventoryItem::get_Graphic", Sc_InventoryItem_GetGraphic); + ccAddExternalObjectFunction("InventoryItem::set_Graphic", Sc_InventoryItem_SetGraphic); + ccAddExternalObjectFunction("InventoryItem::get_ID", Sc_InventoryItem_GetID); + ccAddExternalObjectFunction("InventoryItem::get_Name", Sc_InventoryItem_GetName_New); + ccAddExternalObjectFunction("InventoryItem::set_Name", Sc_InventoryItem_SetName); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -249,3 +250,5 @@ void RegisterInventoryItemAPI() { ccAddExternalFunctionForPlugin("InventoryItem::get_Name", (void *)InventoryItem_GetName_New); ccAddExternalFunctionForPlugin("InventoryItem::set_Name", (void *)InventoryItem_SetName); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp index ed8ba694647e..1c9b8602553f 100644 --- a/engines/ags/engine/ac/invwindow.cpp +++ b/engines/ags/engine/ac/invwindow.cpp @@ -45,6 +45,8 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -125,7 +127,7 @@ int InvWindow_GetRowCount(GUIInvWindow *guii) { void InvWindow_ScrollDown(GUIInvWindow *guii) { if ((charextra[guii->GetCharacterId()].invorder_count) > - (guii->TopItem + (guii->ColCount * guii->RowCount))) { + (guii->TopItem + (guii->ColCount * guii->RowCount))) { guii->TopItem += guii->ColCount; guis_need_update = 1; } @@ -308,8 +310,8 @@ void InventoryScreen::Draw(Bitmap *ds) { if (i >= top_item + num_visible_items) break; Bitmap *spof = spriteset[dii[i].sprnum]; - wputblock(ds, barxp + 1 + ((i - top_item) % 4)*widest + widest / 2 - spof->GetWidth() / 2, - bartop + 1 + ((i - top_item) / 4)*highest + highest / 2 - spof->GetHeight() / 2, spof, 1); + wputblock(ds, barxp + 1 + ((i - top_item) % 4) * widest + widest / 2 - spof->GetWidth() / 2, + bartop + 1 + ((i - top_item) / 4) * highest + highest / 2 - spof->GetHeight() / 2, spof, 1); } #define BUTTONWID Math::Max(1, game.SpriteInfos[btn_select_sprite].Width) // Draw select, look and OK buttons @@ -601,20 +603,20 @@ RuntimeScriptValue Sc_InvWindow_SetTopItem(void *self, const RuntimeScriptValue void RegisterInventoryWindowAPI() { - ccAddExternalObjectFunction("InvWindow::ScrollDown^0", Sc_InvWindow_ScrollDown); - ccAddExternalObjectFunction("InvWindow::ScrollUp^0", Sc_InvWindow_ScrollUp); - ccAddExternalObjectFunction("InvWindow::get_CharacterToUse", Sc_InvWindow_GetCharacterToUse); - ccAddExternalObjectFunction("InvWindow::set_CharacterToUse", Sc_InvWindow_SetCharacterToUse); - ccAddExternalObjectFunction("InvWindow::geti_ItemAtIndex", Sc_InvWindow_GetItemAtIndex); - ccAddExternalObjectFunction("InvWindow::get_ItemCount", Sc_InvWindow_GetItemCount); - ccAddExternalObjectFunction("InvWindow::get_ItemHeight", Sc_InvWindow_GetItemHeight); - ccAddExternalObjectFunction("InvWindow::set_ItemHeight", Sc_InvWindow_SetItemHeight); - ccAddExternalObjectFunction("InvWindow::get_ItemWidth", Sc_InvWindow_GetItemWidth); - ccAddExternalObjectFunction("InvWindow::set_ItemWidth", Sc_InvWindow_SetItemWidth); - ccAddExternalObjectFunction("InvWindow::get_ItemsPerRow", Sc_InvWindow_GetItemsPerRow); - ccAddExternalObjectFunction("InvWindow::get_RowCount", Sc_InvWindow_GetRowCount); - ccAddExternalObjectFunction("InvWindow::get_TopItem", Sc_InvWindow_GetTopItem); - ccAddExternalObjectFunction("InvWindow::set_TopItem", Sc_InvWindow_SetTopItem); + ccAddExternalObjectFunction("InvWindow::ScrollDown^0", Sc_InvWindow_ScrollDown); + ccAddExternalObjectFunction("InvWindow::ScrollUp^0", Sc_InvWindow_ScrollUp); + ccAddExternalObjectFunction("InvWindow::get_CharacterToUse", Sc_InvWindow_GetCharacterToUse); + ccAddExternalObjectFunction("InvWindow::set_CharacterToUse", Sc_InvWindow_SetCharacterToUse); + ccAddExternalObjectFunction("InvWindow::geti_ItemAtIndex", Sc_InvWindow_GetItemAtIndex); + ccAddExternalObjectFunction("InvWindow::get_ItemCount", Sc_InvWindow_GetItemCount); + ccAddExternalObjectFunction("InvWindow::get_ItemHeight", Sc_InvWindow_GetItemHeight); + ccAddExternalObjectFunction("InvWindow::set_ItemHeight", Sc_InvWindow_SetItemHeight); + ccAddExternalObjectFunction("InvWindow::get_ItemWidth", Sc_InvWindow_GetItemWidth); + ccAddExternalObjectFunction("InvWindow::set_ItemWidth", Sc_InvWindow_SetItemWidth); + ccAddExternalObjectFunction("InvWindow::get_ItemsPerRow", Sc_InvWindow_GetItemsPerRow); + ccAddExternalObjectFunction("InvWindow::get_RowCount", Sc_InvWindow_GetRowCount); + ccAddExternalObjectFunction("InvWindow::get_TopItem", Sc_InvWindow_GetTopItem); + ccAddExternalObjectFunction("InvWindow::set_TopItem", Sc_InvWindow_SetTopItem); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -633,3 +635,5 @@ void RegisterInventoryWindowAPI() { ccAddExternalFunctionForPlugin("InvWindow::get_TopItem", (void *)InvWindow_GetTopItem); ccAddExternalFunctionForPlugin("InvWindow::set_TopItem", (void *)InvWindow_SetTopItem); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp index e16de8b958fa..701790ee2343 100644 --- a/engines/ags/engine/ac/keycode.cpp +++ b/engines/ags/engine/ac/keycode.cpp @@ -24,6 +24,8 @@ #include +namespace AGS3 { + int GetKeyForKeyPressCb(int keycode) { // lower case 'a'..'z' do not exist as keycodes, only ascii. 'A'..'Z' do though! return (keycode >= 'a' && keycode <= 'z') ? keycode - 32 : keycode; @@ -33,7 +35,7 @@ int PlatformKeyFromAgsKey(int key) { int platformKey = -1; switch (key) { - // ctrl-[A-Z] keys are numbered 1-26 for A-Z + // ctrl-[A-Z] keys are numbered 1-26 for A-Z case eAGSKeyCodeCtrlA: platformKey = 1; break; @@ -55,8 +57,8 @@ int PlatformKeyFromAgsKey(int key) { case eAGSKeyCodeCtrlG: platformKey = 7; break; - // case eAGSKeyCodeCtrlH: // overlap with backspace - // case eAGSKeyCodeCtrlI: // overlap with tab + // case eAGSKeyCodeCtrlH: // overlap with backspace + // case eAGSKeyCodeCtrlI: // overlap with tab case eAGSKeyCodeCtrlJ: platformKey = 10; break; @@ -66,7 +68,7 @@ int PlatformKeyFromAgsKey(int key) { case eAGSKeyCodeCtrlL: platformKey = 12; break; - // case eAGSKeyCodeCtrlM: // overlap with return + // case eAGSKeyCodeCtrlM: // overlap with return case eAGSKeyCodeCtrlN: platformKey = 14; break; @@ -385,3 +387,5 @@ int PlatformKeyFromAgsKey(int key) { return platformKey; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp index 077a81b34aa6..8935c71abe19 100644 --- a/engines/ags/engine/ac/label.cpp +++ b/engines/ags/engine/ac/label.cpp @@ -27,6 +27,8 @@ #include "ac/global_translation.h" #include "ac/string.h" +namespace AGS3 { + extern GameSetupStruct game; // ** LABEL FUNCTIONS @@ -144,14 +146,14 @@ RuntimeScriptValue Sc_Label_SetColor(void *self, const RuntimeScriptValue *param void RegisterLabelAPI() { - ccAddExternalObjectFunction("Label::GetText^1", Sc_Label_GetText); - ccAddExternalObjectFunction("Label::SetText^1", Sc_Label_SetText); + ccAddExternalObjectFunction("Label::GetText^1", Sc_Label_GetText); + ccAddExternalObjectFunction("Label::SetText^1", Sc_Label_SetText); ccAddExternalObjectFunction("Label::get_TextAlignment", Sc_Label_GetTextAlignment); ccAddExternalObjectFunction("Label::set_TextAlignment", Sc_Label_SetTextAlignment); - ccAddExternalObjectFunction("Label::get_Font", Sc_Label_GetFont); - ccAddExternalObjectFunction("Label::set_Font", Sc_Label_SetFont); - ccAddExternalObjectFunction("Label::get_Text", Sc_Label_GetText_New); - ccAddExternalObjectFunction("Label::set_Text", Sc_Label_SetText); + ccAddExternalObjectFunction("Label::get_Font", Sc_Label_GetFont); + ccAddExternalObjectFunction("Label::set_Font", Sc_Label_SetFont); + ccAddExternalObjectFunction("Label::get_Text", Sc_Label_GetText_New); + ccAddExternalObjectFunction("Label::set_Text", Sc_Label_SetText); ccAddExternalObjectFunction("Label::get_TextColor", Sc_Label_GetColor); ccAddExternalObjectFunction("Label::set_TextColor", Sc_Label_SetColor); @@ -166,3 +168,5 @@ void RegisterLabelAPI() { ccAddExternalFunctionForPlugin("Label::get_TextColor", (void *)Label_GetColor); ccAddExternalFunctionForPlugin("Label::set_TextColor", (void *)Label_SetColor); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index 57635d104d9d..eec074c65f24 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -32,6 +32,8 @@ #include "gui/guimain.h" #include "debug/debug_log.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameState play; @@ -569,46 +571,46 @@ RuntimeScriptValue Sc_ListBox_SetTopItem(void *self, const RuntimeScriptValue *p void RegisterListBoxAPI() { - ccAddExternalObjectFunction("ListBox::AddItem^1", Sc_ListBox_AddItem); - ccAddExternalObjectFunction("ListBox::Clear^0", Sc_ListBox_Clear); - ccAddExternalObjectFunction("ListBox::FillDirList^1", Sc_ListBox_FillDirList); - ccAddExternalObjectFunction("ListBox::FillSaveGameList^0", Sc_ListBox_FillSaveGameList); + ccAddExternalObjectFunction("ListBox::AddItem^1", Sc_ListBox_AddItem); + ccAddExternalObjectFunction("ListBox::Clear^0", Sc_ListBox_Clear); + ccAddExternalObjectFunction("ListBox::FillDirList^1", Sc_ListBox_FillDirList); + ccAddExternalObjectFunction("ListBox::FillSaveGameList^0", Sc_ListBox_FillSaveGameList); ccAddExternalObjectFunction("ListBox::GetItemAtLocation^2", Sc_ListBox_GetItemAtLocation); - ccAddExternalObjectFunction("ListBox::GetItemText^2", Sc_ListBox_GetItemText); - ccAddExternalObjectFunction("ListBox::InsertItemAt^2", Sc_ListBox_InsertItemAt); - ccAddExternalObjectFunction("ListBox::RemoveItem^1", Sc_ListBox_RemoveItem); - ccAddExternalObjectFunction("ListBox::ScrollDown^0", Sc_ListBox_ScrollDown); - ccAddExternalObjectFunction("ListBox::ScrollUp^0", Sc_ListBox_ScrollUp); - ccAddExternalObjectFunction("ListBox::SetItemText^2", Sc_ListBox_SetItemText); - ccAddExternalObjectFunction("ListBox::get_Font", Sc_ListBox_GetFont); - ccAddExternalObjectFunction("ListBox::set_Font", Sc_ListBox_SetFont); - ccAddExternalObjectFunction("ListBox::get_ShowBorder", Sc_ListBox_GetShowBorder); - ccAddExternalObjectFunction("ListBox::set_ShowBorder", Sc_ListBox_SetShowBorder); + ccAddExternalObjectFunction("ListBox::GetItemText^2", Sc_ListBox_GetItemText); + ccAddExternalObjectFunction("ListBox::InsertItemAt^2", Sc_ListBox_InsertItemAt); + ccAddExternalObjectFunction("ListBox::RemoveItem^1", Sc_ListBox_RemoveItem); + ccAddExternalObjectFunction("ListBox::ScrollDown^0", Sc_ListBox_ScrollDown); + ccAddExternalObjectFunction("ListBox::ScrollUp^0", Sc_ListBox_ScrollUp); + ccAddExternalObjectFunction("ListBox::SetItemText^2", Sc_ListBox_SetItemText); + ccAddExternalObjectFunction("ListBox::get_Font", Sc_ListBox_GetFont); + ccAddExternalObjectFunction("ListBox::set_Font", Sc_ListBox_SetFont); + ccAddExternalObjectFunction("ListBox::get_ShowBorder", Sc_ListBox_GetShowBorder); + ccAddExternalObjectFunction("ListBox::set_ShowBorder", Sc_ListBox_SetShowBorder); ccAddExternalObjectFunction("ListBox::get_ShowScrollArrows", Sc_ListBox_GetShowScrollArrows); ccAddExternalObjectFunction("ListBox::set_ShowScrollArrows", Sc_ListBox_SetShowScrollArrows); // old "inverted" properties - ccAddExternalObjectFunction("ListBox::get_HideBorder", Sc_ListBox_GetHideBorder); - ccAddExternalObjectFunction("ListBox::set_HideBorder", Sc_ListBox_SetHideBorder); + ccAddExternalObjectFunction("ListBox::get_HideBorder", Sc_ListBox_GetHideBorder); + ccAddExternalObjectFunction("ListBox::set_HideBorder", Sc_ListBox_SetHideBorder); ccAddExternalObjectFunction("ListBox::get_HideScrollArrows", Sc_ListBox_GetHideScrollArrows); ccAddExternalObjectFunction("ListBox::set_HideScrollArrows", Sc_ListBox_SetHideScrollArrows); // - ccAddExternalObjectFunction("ListBox::get_ItemCount", Sc_ListBox_GetItemCount); - ccAddExternalObjectFunction("ListBox::geti_Items", Sc_ListBox_GetItems); - ccAddExternalObjectFunction("ListBox::seti_Items", Sc_ListBox_SetItemText); - ccAddExternalObjectFunction("ListBox::get_RowCount", Sc_ListBox_GetRowCount); - ccAddExternalObjectFunction("ListBox::geti_SaveGameSlots", Sc_ListBox_GetSaveGameSlots); + ccAddExternalObjectFunction("ListBox::get_ItemCount", Sc_ListBox_GetItemCount); + ccAddExternalObjectFunction("ListBox::geti_Items", Sc_ListBox_GetItems); + ccAddExternalObjectFunction("ListBox::seti_Items", Sc_ListBox_SetItemText); + ccAddExternalObjectFunction("ListBox::get_RowCount", Sc_ListBox_GetRowCount); + ccAddExternalObjectFunction("ListBox::geti_SaveGameSlots", Sc_ListBox_GetSaveGameSlots); ccAddExternalObjectFunction("ListBox::get_SelectedBackColor", Sc_ListBox_GetSelectedBackColor); ccAddExternalObjectFunction("ListBox::set_SelectedBackColor", Sc_ListBox_SetSelectedBackColor); - ccAddExternalObjectFunction("ListBox::get_SelectedIndex", Sc_ListBox_GetSelectedIndex); - ccAddExternalObjectFunction("ListBox::set_SelectedIndex", Sc_ListBox_SetSelectedIndex); + ccAddExternalObjectFunction("ListBox::get_SelectedIndex", Sc_ListBox_GetSelectedIndex); + ccAddExternalObjectFunction("ListBox::set_SelectedIndex", Sc_ListBox_SetSelectedIndex); ccAddExternalObjectFunction("ListBox::get_SelectedTextColor", Sc_ListBox_GetSelectedTextColor); ccAddExternalObjectFunction("ListBox::set_SelectedTextColor", Sc_ListBox_SetSelectedTextColor); - ccAddExternalObjectFunction("ListBox::get_TextAlignment", Sc_ListBox_GetTextAlignment); - ccAddExternalObjectFunction("ListBox::set_TextAlignment", Sc_ListBox_SetTextAlignment); - ccAddExternalObjectFunction("ListBox::get_TextColor", Sc_ListBox_GetTextColor); - ccAddExternalObjectFunction("ListBox::set_TextColor", Sc_ListBox_SetTextColor); - ccAddExternalObjectFunction("ListBox::get_TopItem", Sc_ListBox_GetTopItem); - ccAddExternalObjectFunction("ListBox::set_TopItem", Sc_ListBox_SetTopItem); + ccAddExternalObjectFunction("ListBox::get_TextAlignment", Sc_ListBox_GetTextAlignment); + ccAddExternalObjectFunction("ListBox::set_TextAlignment", Sc_ListBox_SetTextAlignment); + ccAddExternalObjectFunction("ListBox::get_TextColor", Sc_ListBox_GetTextColor); + ccAddExternalObjectFunction("ListBox::set_TextColor", Sc_ListBox_SetTextColor); + ccAddExternalObjectFunction("ListBox::get_TopItem", Sc_ListBox_GetTopItem); + ccAddExternalObjectFunction("ListBox::set_TopItem", Sc_ListBox_SetTopItem); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -639,3 +641,5 @@ void RegisterListBoxAPI() { ccAddExternalFunctionForPlugin("ListBox::get_TopItem", (void *)ListBox_GetTopItem); ccAddExternalFunctionForPlugin("ListBox::set_TopItem", (void *)ListBox_SetTopItem); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/math.cpp b/engines/ags/engine/ac/math.cpp index 228558fc5261..de2d521978d9 100644 --- a/engines/ags/engine/ac/math.cpp +++ b/engines/ags/engine/ac/math.cpp @@ -25,6 +25,8 @@ #include "ac/common.h" // quit #include "util/math.h" +namespace AGS3 { + int FloatToInt(float value, int roundDirection) { if (value >= 0.0) { if (roundDirection == eRoundDown) @@ -242,24 +244,24 @@ RuntimeScriptValue Sc_Math_GetPi(const RuntimeScriptValue *params, int32_t param void RegisterMathAPI() { - ccAddExternalStaticFunction("Maths::ArcCos^1", Sc_Math_ArcCos); - ccAddExternalStaticFunction("Maths::ArcSin^1", Sc_Math_ArcSin); - ccAddExternalStaticFunction("Maths::ArcTan^1", Sc_Math_ArcTan); - ccAddExternalStaticFunction("Maths::ArcTan2^2", Sc_Math_ArcTan2); - ccAddExternalStaticFunction("Maths::Cos^1", Sc_Math_Cos); - ccAddExternalStaticFunction("Maths::Cosh^1", Sc_Math_Cosh); - ccAddExternalStaticFunction("Maths::DegreesToRadians^1", Sc_Math_DegreesToRadians); - ccAddExternalStaticFunction("Maths::Exp^1", Sc_Math_Exp); - ccAddExternalStaticFunction("Maths::Log^1", Sc_Math_Log); - ccAddExternalStaticFunction("Maths::Log10^1", Sc_Math_Log10); - ccAddExternalStaticFunction("Maths::RadiansToDegrees^1", Sc_Math_RadiansToDegrees); - ccAddExternalStaticFunction("Maths::RaiseToPower^2", Sc_Math_RaiseToPower); - ccAddExternalStaticFunction("Maths::Sin^1", Sc_Math_Sin); - ccAddExternalStaticFunction("Maths::Sinh^1", Sc_Math_Sinh); - ccAddExternalStaticFunction("Maths::Sqrt^1", Sc_Math_Sqrt); - ccAddExternalStaticFunction("Maths::Tan^1", Sc_Math_Tan); - ccAddExternalStaticFunction("Maths::Tanh^1", Sc_Math_Tanh); - ccAddExternalStaticFunction("Maths::get_Pi", Sc_Math_GetPi); + ccAddExternalStaticFunction("Maths::ArcCos^1", Sc_Math_ArcCos); + ccAddExternalStaticFunction("Maths::ArcSin^1", Sc_Math_ArcSin); + ccAddExternalStaticFunction("Maths::ArcTan^1", Sc_Math_ArcTan); + ccAddExternalStaticFunction("Maths::ArcTan2^2", Sc_Math_ArcTan2); + ccAddExternalStaticFunction("Maths::Cos^1", Sc_Math_Cos); + ccAddExternalStaticFunction("Maths::Cosh^1", Sc_Math_Cosh); + ccAddExternalStaticFunction("Maths::DegreesToRadians^1", Sc_Math_DegreesToRadians); + ccAddExternalStaticFunction("Maths::Exp^1", Sc_Math_Exp); + ccAddExternalStaticFunction("Maths::Log^1", Sc_Math_Log); + ccAddExternalStaticFunction("Maths::Log10^1", Sc_Math_Log10); + ccAddExternalStaticFunction("Maths::RadiansToDegrees^1", Sc_Math_RadiansToDegrees); + ccAddExternalStaticFunction("Maths::RaiseToPower^2", Sc_Math_RaiseToPower); + ccAddExternalStaticFunction("Maths::Sin^1", Sc_Math_Sin); + ccAddExternalStaticFunction("Maths::Sinh^1", Sc_Math_Sinh); + ccAddExternalStaticFunction("Maths::Sqrt^1", Sc_Math_Sqrt); + ccAddExternalStaticFunction("Maths::Tan^1", Sc_Math_Tan); + ccAddExternalStaticFunction("Maths::Tanh^1", Sc_Math_Tanh); + ccAddExternalStaticFunction("Maths::get_Pi", Sc_Math_GetPi); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -282,3 +284,5 @@ void RegisterMathAPI() { ccAddExternalFunctionForPlugin("Maths::Tanh^1", (void *)Math_Tanh); ccAddExternalFunctionForPlugin("Maths::get_Pi", (void *)Math_GetPi); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp index 9b6f65c89cf1..8fe271403991 100644 --- a/engines/ags/engine/ac/mouse.cpp +++ b/engines/ags/engine/ac/mouse.cpp @@ -42,6 +42,8 @@ #include "gfx/graphicsdriver.h" #include "gfx/gfxfilter.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -89,7 +91,7 @@ void SetMouseBounds(int x1, int y1, int x2, int y2) { } else { if (x1 < 0 || x1 > xmax || x2 < 0 || x2 > xmax || x1 > x2 || y1 < 0 || y1 > ymax || y2 < 0 || y2 > ymax || y1 > y2) debug_script_warn("SetMouseBounds: arguments are out of range and will be corrected: (%d,%d)-(%d,%d), range is (%d,%d)-(%d,%d)", - x1, y1, x2, y2, 0, 0, xmax, ymax); + x1, y1, x2, y2, 0, 0, xmax, ymax); x1 = Math::Clamp(x1, 0, xmax); x2 = Math::Clamp(x2, x1, xmax); y1 = Math::Clamp(y1, 0, ymax); @@ -115,7 +117,7 @@ void set_mouse_cursor(int newcurs) { // if it's same cursor and there's animation in progress, then don't assign a new pic just yet if (newcurs == cur_cursor && game.mcurs[newcurs].view >= 0 && - (mouse_frame > 0 || mouse_delay > 0)) { + (mouse_frame > 0 || mouse_delay > 0)) { return; } @@ -133,17 +135,17 @@ void set_mouse_cursor(int newcurs) { // If it's inventory cursor, draw hotspot crosshair sprite upon it if ((newcurs == MODE_USE) && (game.mcurs[newcurs].pic > 0) && - ((game.hotdot > 0) || (game.invhotdotsprite > 0))) { + ((game.hotdot > 0) || (game.invhotdotsprite > 0))) { // If necessary, create a copy of the cursor and put the hotspot // dot onto it dotted_mouse_cursor = BitmapHelper::CreateBitmapCopy(mousecurs[0]); if (game.invhotdotsprite > 0) { draw_sprite_slot_support_alpha(dotted_mouse_cursor, - (game.SpriteInfos[game.mcurs[newcurs].pic].Flags & SPF_ALPHACHANNEL) != 0, - hotspotx - game.SpriteInfos[game.invhotdotsprite].Width / 2, - hotspoty - game.SpriteInfos[game.invhotdotsprite].Height / 2, - game.invhotdotsprite); + (game.SpriteInfos[game.mcurs[newcurs].pic].Flags & SPF_ALPHACHANNEL) != 0, + hotspotx - game.SpriteInfos[game.invhotdotsprite].Width / 2, + hotspoty - game.SpriteInfos[game.invhotdotsprite].Height / 2, + game.invhotdotsprite); } else { putpixel_compensate(dotted_mouse_cursor, hotspotx, hotspoty, MakeColor(game.hotdot)); @@ -315,8 +317,8 @@ int IsButtonDown(int which) { int IsModeEnabled(int which) { return (which < 0) || (which >= game.numcursors) ? 0 : - which == MODE_USE ? playerchar->activeinv > 0 : - (game.mcurs[which].flags & MCF_DISABLED) == 0; + which == MODE_USE ? playerchar->activeinv > 0 : + (game.mcurs[which].flags & MCF_DISABLED) == 0; } void Mouse_EnableControl(bool on) { @@ -326,7 +328,7 @@ void Mouse_EnableControl(bool on) { // Whether mouse movement should be controlled by the engine - this is // determined based on related config option. bool should_control_mouse = usetup.mouse_ctrl_when == kMouseCtrl_Always || - (usetup.mouse_ctrl_when == kMouseCtrl_Fullscreen && !is_windowed); + (usetup.mouse_ctrl_when == kMouseCtrl_Fullscreen && !is_windowed); // Whether mouse movement control is supported by the engine - this is // determined on per platform basis. Some builds may not have such // capability, e.g. because of how backend library implements mouse utils. @@ -582,31 +584,31 @@ RuntimeScriptValue Sc_Mouse_SetSpeed(const RuntimeScriptValue *params, int32_t p } void RegisterMouseAPI() { - ccAddExternalStaticFunction("Mouse::ChangeModeGraphic^2", Sc_ChangeCursorGraphic); - ccAddExternalStaticFunction("Mouse::ChangeModeHotspot^3", Sc_ChangeCursorHotspot); - ccAddExternalStaticFunction("Mouse::ChangeModeView^2", Sc_Mouse_ChangeModeView); - ccAddExternalStaticFunction("Mouse::Click^1", Sc_Mouse_Click); - ccAddExternalStaticFunction("Mouse::DisableMode^1", Sc_disable_cursor_mode); - ccAddExternalStaticFunction("Mouse::EnableMode^1", Sc_enable_cursor_mode); - ccAddExternalStaticFunction("Mouse::GetModeGraphic^1", Sc_Mouse_GetModeGraphic); - ccAddExternalStaticFunction("Mouse::IsButtonDown^1", Sc_IsButtonDown); - ccAddExternalStaticFunction("Mouse::IsModeEnabled^1", Sc_IsModeEnabled); + ccAddExternalStaticFunction("Mouse::ChangeModeGraphic^2", Sc_ChangeCursorGraphic); + ccAddExternalStaticFunction("Mouse::ChangeModeHotspot^3", Sc_ChangeCursorHotspot); + ccAddExternalStaticFunction("Mouse::ChangeModeView^2", Sc_Mouse_ChangeModeView); + ccAddExternalStaticFunction("Mouse::Click^1", Sc_Mouse_Click); + ccAddExternalStaticFunction("Mouse::DisableMode^1", Sc_disable_cursor_mode); + ccAddExternalStaticFunction("Mouse::EnableMode^1", Sc_enable_cursor_mode); + ccAddExternalStaticFunction("Mouse::GetModeGraphic^1", Sc_Mouse_GetModeGraphic); + ccAddExternalStaticFunction("Mouse::IsButtonDown^1", Sc_IsButtonDown); + ccAddExternalStaticFunction("Mouse::IsModeEnabled^1", Sc_IsModeEnabled); ccAddExternalStaticFunction("Mouse::SaveCursorUntilItLeaves^0", Sc_SaveCursorForLocationChange); - ccAddExternalStaticFunction("Mouse::SelectNextMode^0", Sc_SetNextCursor); - ccAddExternalStaticFunction("Mouse::SelectPreviousMode^0", Sc_SetPreviousCursor); - ccAddExternalStaticFunction("Mouse::SetBounds^4", Sc_SetMouseBounds); - ccAddExternalStaticFunction("Mouse::SetPosition^2", Sc_SetMousePosition); - ccAddExternalStaticFunction("Mouse::Update^0", Sc_RefreshMouse); - ccAddExternalStaticFunction("Mouse::UseDefaultGraphic^0", Sc_set_default_cursor); - ccAddExternalStaticFunction("Mouse::UseModeGraphic^1", Sc_set_mouse_cursor); - ccAddExternalStaticFunction("Mouse::get_ControlEnabled", Sc_Mouse_GetControlEnabled); - ccAddExternalStaticFunction("Mouse::set_ControlEnabled", Sc_Mouse_SetControlEnabled); - ccAddExternalStaticFunction("Mouse::get_Mode", Sc_GetCursorMode); - ccAddExternalStaticFunction("Mouse::set_Mode", Sc_set_cursor_mode); - ccAddExternalStaticFunction("Mouse::get_Speed", Sc_Mouse_GetSpeed); - ccAddExternalStaticFunction("Mouse::set_Speed", Sc_Mouse_SetSpeed); - ccAddExternalStaticFunction("Mouse::get_Visible", Sc_Mouse_GetVisible); - ccAddExternalStaticFunction("Mouse::set_Visible", Sc_Mouse_SetVisible); + ccAddExternalStaticFunction("Mouse::SelectNextMode^0", Sc_SetNextCursor); + ccAddExternalStaticFunction("Mouse::SelectPreviousMode^0", Sc_SetPreviousCursor); + ccAddExternalStaticFunction("Mouse::SetBounds^4", Sc_SetMouseBounds); + ccAddExternalStaticFunction("Mouse::SetPosition^2", Sc_SetMousePosition); + ccAddExternalStaticFunction("Mouse::Update^0", Sc_RefreshMouse); + ccAddExternalStaticFunction("Mouse::UseDefaultGraphic^0", Sc_set_default_cursor); + ccAddExternalStaticFunction("Mouse::UseModeGraphic^1", Sc_set_mouse_cursor); + ccAddExternalStaticFunction("Mouse::get_ControlEnabled", Sc_Mouse_GetControlEnabled); + ccAddExternalStaticFunction("Mouse::set_ControlEnabled", Sc_Mouse_SetControlEnabled); + ccAddExternalStaticFunction("Mouse::get_Mode", Sc_GetCursorMode); + ccAddExternalStaticFunction("Mouse::set_Mode", Sc_set_cursor_mode); + ccAddExternalStaticFunction("Mouse::get_Speed", Sc_Mouse_GetSpeed); + ccAddExternalStaticFunction("Mouse::set_Speed", Sc_Mouse_SetSpeed); + ccAddExternalStaticFunction("Mouse::get_Visible", Sc_Mouse_GetVisible); + ccAddExternalStaticFunction("Mouse::set_Visible", Sc_Mouse_SetVisible); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -631,3 +633,5 @@ void RegisterMouseAPI() { ccAddExternalFunctionForPlugin("Mouse::get_Visible", (void *)Mouse_GetVisible); ccAddExternalFunctionForPlugin("Mouse::set_Visible", (void *)Mouse_SetVisible); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/movelist.cpp b/engines/ags/engine/ac/movelist.cpp index b2402618b3aa..0b46fbf8fd76 100644 --- a/engines/ags/engine/ac/movelist.cpp +++ b/engines/ags/engine/ac/movelist.cpp @@ -24,6 +24,8 @@ #include "ac/common.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -52,7 +54,7 @@ HSaveError MoveList::ReadFromFile(Stream *in, int32_t cmp_ver) { // TODO: reimplement MoveList stages as vector to avoid these limits if (numstage > MAXNEEDSTAGES) { return new SavegameError(kSvgErr_IncompatibleEngine, - String::FromFormat("Incompatible number of movelist steps (count: %d, max : %d).", numstage, MAXNEEDSTAGES)); + String::FromFormat("Incompatible number of movelist steps (count: %d, max : %d).", numstage, MAXNEEDSTAGES)); } fromx = in->ReadInt32(); @@ -85,3 +87,5 @@ void MoveList::WriteToFile(Stream *out) { out->WriteArrayOfInt32(xpermove, numstage); out->WriteArrayOfInt32(ypermove, numstage); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp index 399f4bbbc94a..3fb358320a3e 100644 --- a/engines/ags/engine/ac/object.cpp +++ b/engines/ags/engine/ac/object.cpp @@ -46,6 +46,8 @@ #include "ac/dynobj/cc_object.h" #include "ac/movelist.h" +namespace AGS3 { + using namespace AGS::Shared; @@ -870,76 +872,76 @@ RuntimeScriptValue Sc_Object_SetY(void *self, const RuntimeScriptValue *params, void RegisterObjectAPI() { - ccAddExternalObjectFunction("Object::Animate^5", Sc_Object_Animate); - ccAddExternalObjectFunction("Object::Animate^6", Sc_Object_AnimateFrom); - ccAddExternalObjectFunction("Object::IsCollidingWithObject^1", Sc_Object_IsCollidingWithObject); - ccAddExternalObjectFunction("Object::GetName^1", Sc_Object_GetName); - ccAddExternalObjectFunction("Object::GetProperty^1", Sc_Object_GetProperty); - ccAddExternalObjectFunction("Object::GetPropertyText^2", Sc_Object_GetPropertyText); - ccAddExternalObjectFunction("Object::GetTextProperty^1", Sc_Object_GetTextProperty); - ccAddExternalObjectFunction("Object::SetProperty^2", Sc_Object_SetProperty); - ccAddExternalObjectFunction("Object::SetTextProperty^2", Sc_Object_SetTextProperty); + ccAddExternalObjectFunction("Object::Animate^5", Sc_Object_Animate); + ccAddExternalObjectFunction("Object::Animate^6", Sc_Object_AnimateFrom); + ccAddExternalObjectFunction("Object::IsCollidingWithObject^1", Sc_Object_IsCollidingWithObject); + ccAddExternalObjectFunction("Object::GetName^1", Sc_Object_GetName); + ccAddExternalObjectFunction("Object::GetProperty^1", Sc_Object_GetProperty); + ccAddExternalObjectFunction("Object::GetPropertyText^2", Sc_Object_GetPropertyText); + ccAddExternalObjectFunction("Object::GetTextProperty^1", Sc_Object_GetTextProperty); + ccAddExternalObjectFunction("Object::SetProperty^2", Sc_Object_SetProperty); + ccAddExternalObjectFunction("Object::SetTextProperty^2", Sc_Object_SetTextProperty); ccAddExternalObjectFunction("Object::IsInteractionAvailable^1", Sc_Object_IsInteractionAvailable); - ccAddExternalObjectFunction("Object::MergeIntoBackground^0", Sc_Object_MergeIntoBackground); - ccAddExternalObjectFunction("Object::Move^5", Sc_Object_Move); - ccAddExternalObjectFunction("Object::RemoveTint^0", Sc_Object_RemoveTint); - ccAddExternalObjectFunction("Object::RunInteraction^1", Sc_Object_RunInteraction); - ccAddExternalObjectFunction("Object::SetLightLevel^1", Sc_Object_SetLightLevel); - ccAddExternalObjectFunction("Object::SetPosition^2", Sc_Object_SetPosition); - ccAddExternalObjectFunction("Object::SetView^3", Sc_Object_SetView); - ccAddExternalObjectFunction("Object::StopAnimating^0", Sc_Object_StopAnimating); - ccAddExternalObjectFunction("Object::StopMoving^0", Sc_Object_StopMoving); - ccAddExternalObjectFunction("Object::Tint^5", Sc_Object_Tint); + ccAddExternalObjectFunction("Object::MergeIntoBackground^0", Sc_Object_MergeIntoBackground); + ccAddExternalObjectFunction("Object::Move^5", Sc_Object_Move); + ccAddExternalObjectFunction("Object::RemoveTint^0", Sc_Object_RemoveTint); + ccAddExternalObjectFunction("Object::RunInteraction^1", Sc_Object_RunInteraction); + ccAddExternalObjectFunction("Object::SetLightLevel^1", Sc_Object_SetLightLevel); + ccAddExternalObjectFunction("Object::SetPosition^2", Sc_Object_SetPosition); + ccAddExternalObjectFunction("Object::SetView^3", Sc_Object_SetView); + ccAddExternalObjectFunction("Object::StopAnimating^0", Sc_Object_StopAnimating); + ccAddExternalObjectFunction("Object::StopMoving^0", Sc_Object_StopMoving); + ccAddExternalObjectFunction("Object::Tint^5", Sc_Object_Tint); // static - ccAddExternalStaticFunction("Object::GetAtRoomXY^2", Sc_GetObjectAtRoom); - ccAddExternalStaticFunction("Object::GetAtScreenXY^2", Sc_GetObjectAtScreen); - - ccAddExternalObjectFunction("Object::get_Animating", Sc_Object_GetAnimating); - ccAddExternalObjectFunction("Object::get_Baseline", Sc_Object_GetBaseline); - ccAddExternalObjectFunction("Object::set_Baseline", Sc_Object_SetBaseline); - ccAddExternalObjectFunction("Object::get_BlockingHeight", Sc_Object_GetBlockingHeight); - ccAddExternalObjectFunction("Object::set_BlockingHeight", Sc_Object_SetBlockingHeight); - ccAddExternalObjectFunction("Object::get_BlockingWidth", Sc_Object_GetBlockingWidth); - ccAddExternalObjectFunction("Object::set_BlockingWidth", Sc_Object_SetBlockingWidth); - ccAddExternalObjectFunction("Object::get_Clickable", Sc_Object_GetClickable); - ccAddExternalObjectFunction("Object::set_Clickable", Sc_Object_SetClickable); - ccAddExternalObjectFunction("Object::get_Frame", Sc_Object_GetFrame); - ccAddExternalObjectFunction("Object::get_Graphic", Sc_Object_GetGraphic); - ccAddExternalObjectFunction("Object::set_Graphic", Sc_Object_SetGraphic); - ccAddExternalObjectFunction("Object::get_ID", Sc_Object_GetID); - ccAddExternalObjectFunction("Object::get_IgnoreScaling", Sc_Object_GetIgnoreScaling); - ccAddExternalObjectFunction("Object::set_IgnoreScaling", Sc_Object_SetIgnoreScaling); - ccAddExternalObjectFunction("Object::get_IgnoreWalkbehinds", Sc_Object_GetIgnoreWalkbehinds); - ccAddExternalObjectFunction("Object::set_IgnoreWalkbehinds", Sc_Object_SetIgnoreWalkbehinds); - ccAddExternalObjectFunction("Object::get_Loop", Sc_Object_GetLoop); - ccAddExternalObjectFunction("Object::get_ManualScaling", Sc_Object_GetIgnoreScaling); - ccAddExternalObjectFunction("Object::set_ManualScaling", Sc_Object_SetManualScaling); - ccAddExternalObjectFunction("Object::get_Moving", Sc_Object_GetMoving); - ccAddExternalObjectFunction("Object::get_Name", Sc_Object_GetName_New); - ccAddExternalObjectFunction("Object::get_Scaling", Sc_Object_GetScaling); - ccAddExternalObjectFunction("Object::set_Scaling", Sc_Object_SetScaling); - ccAddExternalObjectFunction("Object::get_Solid", Sc_Object_GetSolid); - ccAddExternalObjectFunction("Object::set_Solid", Sc_Object_SetSolid); - ccAddExternalObjectFunction("Object::get_Transparency", Sc_Object_GetTransparency); - ccAddExternalObjectFunction("Object::set_Transparency", Sc_Object_SetTransparency); - ccAddExternalObjectFunction("Object::get_View", Sc_Object_GetView); - ccAddExternalObjectFunction("Object::get_Visible", Sc_Object_GetVisible); - ccAddExternalObjectFunction("Object::set_Visible", Sc_Object_SetVisible); - ccAddExternalObjectFunction("Object::get_X", Sc_Object_GetX); - ccAddExternalObjectFunction("Object::set_X", Sc_Object_SetX); - ccAddExternalObjectFunction("Object::get_Y", Sc_Object_GetY); - ccAddExternalObjectFunction("Object::set_Y", Sc_Object_SetY); - - ccAddExternalObjectFunction("Object::get_HasExplicitLight", Sc_Object_HasExplicitLight); - ccAddExternalObjectFunction("Object::get_HasExplicitTint", Sc_Object_HasExplicitTint); - ccAddExternalObjectFunction("Object::get_LightLevel", Sc_Object_GetLightLevel); - ccAddExternalObjectFunction("Object::set_LightLevel", Sc_Object_SetLightLevel); - ccAddExternalObjectFunction("Object::get_TintBlue", Sc_Object_GetTintBlue); - ccAddExternalObjectFunction("Object::get_TintGreen", Sc_Object_GetTintGreen); - ccAddExternalObjectFunction("Object::get_TintRed", Sc_Object_GetTintRed); - ccAddExternalObjectFunction("Object::get_TintSaturation", Sc_Object_GetTintSaturation); - ccAddExternalObjectFunction("Object::get_TintLuminance", Sc_Object_GetTintLuminance); + ccAddExternalStaticFunction("Object::GetAtRoomXY^2", Sc_GetObjectAtRoom); + ccAddExternalStaticFunction("Object::GetAtScreenXY^2", Sc_GetObjectAtScreen); + + ccAddExternalObjectFunction("Object::get_Animating", Sc_Object_GetAnimating); + ccAddExternalObjectFunction("Object::get_Baseline", Sc_Object_GetBaseline); + ccAddExternalObjectFunction("Object::set_Baseline", Sc_Object_SetBaseline); + ccAddExternalObjectFunction("Object::get_BlockingHeight", Sc_Object_GetBlockingHeight); + ccAddExternalObjectFunction("Object::set_BlockingHeight", Sc_Object_SetBlockingHeight); + ccAddExternalObjectFunction("Object::get_BlockingWidth", Sc_Object_GetBlockingWidth); + ccAddExternalObjectFunction("Object::set_BlockingWidth", Sc_Object_SetBlockingWidth); + ccAddExternalObjectFunction("Object::get_Clickable", Sc_Object_GetClickable); + ccAddExternalObjectFunction("Object::set_Clickable", Sc_Object_SetClickable); + ccAddExternalObjectFunction("Object::get_Frame", Sc_Object_GetFrame); + ccAddExternalObjectFunction("Object::get_Graphic", Sc_Object_GetGraphic); + ccAddExternalObjectFunction("Object::set_Graphic", Sc_Object_SetGraphic); + ccAddExternalObjectFunction("Object::get_ID", Sc_Object_GetID); + ccAddExternalObjectFunction("Object::get_IgnoreScaling", Sc_Object_GetIgnoreScaling); + ccAddExternalObjectFunction("Object::set_IgnoreScaling", Sc_Object_SetIgnoreScaling); + ccAddExternalObjectFunction("Object::get_IgnoreWalkbehinds", Sc_Object_GetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Object::set_IgnoreWalkbehinds", Sc_Object_SetIgnoreWalkbehinds); + ccAddExternalObjectFunction("Object::get_Loop", Sc_Object_GetLoop); + ccAddExternalObjectFunction("Object::get_ManualScaling", Sc_Object_GetIgnoreScaling); + ccAddExternalObjectFunction("Object::set_ManualScaling", Sc_Object_SetManualScaling); + ccAddExternalObjectFunction("Object::get_Moving", Sc_Object_GetMoving); + ccAddExternalObjectFunction("Object::get_Name", Sc_Object_GetName_New); + ccAddExternalObjectFunction("Object::get_Scaling", Sc_Object_GetScaling); + ccAddExternalObjectFunction("Object::set_Scaling", Sc_Object_SetScaling); + ccAddExternalObjectFunction("Object::get_Solid", Sc_Object_GetSolid); + ccAddExternalObjectFunction("Object::set_Solid", Sc_Object_SetSolid); + ccAddExternalObjectFunction("Object::get_Transparency", Sc_Object_GetTransparency); + ccAddExternalObjectFunction("Object::set_Transparency", Sc_Object_SetTransparency); + ccAddExternalObjectFunction("Object::get_View", Sc_Object_GetView); + ccAddExternalObjectFunction("Object::get_Visible", Sc_Object_GetVisible); + ccAddExternalObjectFunction("Object::set_Visible", Sc_Object_SetVisible); + ccAddExternalObjectFunction("Object::get_X", Sc_Object_GetX); + ccAddExternalObjectFunction("Object::set_X", Sc_Object_SetX); + ccAddExternalObjectFunction("Object::get_Y", Sc_Object_GetY); + ccAddExternalObjectFunction("Object::set_Y", Sc_Object_SetY); + + ccAddExternalObjectFunction("Object::get_HasExplicitLight", Sc_Object_HasExplicitLight); + ccAddExternalObjectFunction("Object::get_HasExplicitTint", Sc_Object_HasExplicitTint); + ccAddExternalObjectFunction("Object::get_LightLevel", Sc_Object_GetLightLevel); + ccAddExternalObjectFunction("Object::set_LightLevel", Sc_Object_SetLightLevel); + ccAddExternalObjectFunction("Object::get_TintBlue", Sc_Object_GetTintBlue); + ccAddExternalObjectFunction("Object::get_TintGreen", Sc_Object_GetTintGreen); + ccAddExternalObjectFunction("Object::get_TintRed", Sc_Object_GetTintRed); + ccAddExternalObjectFunction("Object::get_TintSaturation", Sc_Object_GetTintSaturation); + ccAddExternalObjectFunction("Object::get_TintLuminance", Sc_Object_GetTintLuminance); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -992,3 +994,5 @@ void RegisterObjectAPI() { ccAddExternalFunctionForPlugin("Object::get_Y", (void *)Object_GetY); ccAddExternalFunctionForPlugin("Object::set_Y", (void *)Object_SetY); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp index 8f6fe78dc79c..f9b40cbec46f 100644 --- a/engines/ags/engine/ac/overlay.cpp +++ b/engines/ags/engine/ac/overlay.cpp @@ -38,6 +38,8 @@ #include "gfx/bitmap.h" #include "script/runtimescriptvalue.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -238,8 +240,8 @@ void get_overlay_position(const ScreenOverlay &over, int *x, int *y) { const int charpic = views[game.chars[charid].view].loops[game.chars[charid].loop].frames[0].pic; const int height = (charextra[charid].height < 1) ? game.SpriteInfos[charpic].Height : charextra[charid].height; Point screenpt = view->RoomToScreen( - data_to_game_coord(game.chars[charid].x), - data_to_game_coord(game.chars[charid].get_effective_y()) - height).first; + data_to_game_coord(game.chars[charid].x), + data_to_game_coord(game.chars[charid].get_effective_y()) - height).first; tdxp = screenpt.X - over.pic->GetWidth() / 2; if (tdxp < 0) tdxp = 0; tdyp = screenpt.Y - get_fixed_pixel_size(5); @@ -298,7 +300,7 @@ RuntimeScriptValue Sc_Overlay_CreateGraphical(const RuntimeScriptValue *params, RuntimeScriptValue Sc_Overlay_CreateTextual(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_SCRIPT_SPRINTF(Overlay_CreateTextual, 6); ScriptOverlay *overlay = Overlay_CreateTextual(params[0].IValue, params[1].IValue, params[2].IValue, - params[3].IValue, params[4].IValue, scsf_buffer); + params[3].IValue, params[4].IValue, scsf_buffer); return RuntimeScriptValue().SetDynamicObject(overlay, overlay); } @@ -359,15 +361,15 @@ void ScPl_Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, c void RegisterOverlayAPI() { - ccAddExternalStaticFunction("Overlay::CreateGraphical^4", Sc_Overlay_CreateGraphical); - ccAddExternalStaticFunction("Overlay::CreateTextual^106", Sc_Overlay_CreateTextual); - ccAddExternalObjectFunction("Overlay::SetText^104", Sc_Overlay_SetText); - ccAddExternalObjectFunction("Overlay::Remove^0", Sc_Overlay_Remove); - ccAddExternalObjectFunction("Overlay::get_Valid", Sc_Overlay_GetValid); - ccAddExternalObjectFunction("Overlay::get_X", Sc_Overlay_GetX); - ccAddExternalObjectFunction("Overlay::set_X", Sc_Overlay_SetX); - ccAddExternalObjectFunction("Overlay::get_Y", Sc_Overlay_GetY); - ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY); + ccAddExternalStaticFunction("Overlay::CreateGraphical^4", Sc_Overlay_CreateGraphical); + ccAddExternalStaticFunction("Overlay::CreateTextual^106", Sc_Overlay_CreateTextual); + ccAddExternalObjectFunction("Overlay::SetText^104", Sc_Overlay_SetText); + ccAddExternalObjectFunction("Overlay::Remove^0", Sc_Overlay_Remove); + ccAddExternalObjectFunction("Overlay::get_Valid", Sc_Overlay_GetValid); + ccAddExternalObjectFunction("Overlay::get_X", Sc_Overlay_GetX); + ccAddExternalObjectFunction("Overlay::set_X", Sc_Overlay_SetX); + ccAddExternalObjectFunction("Overlay::get_Y", Sc_Overlay_GetY); + ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -381,3 +383,5 @@ void RegisterOverlayAPI() { ccAddExternalFunctionForPlugin("Overlay::get_Y", (void *)Overlay_GetY); ccAddExternalFunctionForPlugin("Overlay::set_Y", (void *)Overlay_SetY); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp index c966d4d9fd54..66fc367497e3 100644 --- a/engines/ags/engine/ac/parser.cpp +++ b/engines/ags/engine/ac/parser.cpp @@ -32,6 +32,8 @@ #include "util/string.h" #include "util/string_compat.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -207,8 +209,8 @@ int parse_sentence(const char *src_text, int *numwords, short *wordarray, short } if (word <= 0) quitprintf("!Said: supplied word '%s' is not in dictionary or is an ignored word\nText: %s", thisword, src_text); - if (word == ANYWORD) { } - else if (word != compareto[comparing]) { + if (word == ANYWORD) { + } else if (word != compareto[comparing]) { // words don't match - if a comma then a list of possibles, // so allow retry if (text[0] == ',') @@ -329,10 +331,10 @@ RuntimeScriptValue Sc_Said(const RuntimeScriptValue *params, int32_t param_count void RegisterParserAPI() { - ccAddExternalStaticFunction("Parser::FindWordID^1", Sc_Parser_FindWordID); - ccAddExternalStaticFunction("Parser::ParseText^1", Sc_ParseText); + ccAddExternalStaticFunction("Parser::FindWordID^1", Sc_Parser_FindWordID); + ccAddExternalStaticFunction("Parser::ParseText^1", Sc_ParseText); ccAddExternalStaticFunction("Parser::SaidUnknownWord^0", Sc_Parser_SaidUnknownWord); - ccAddExternalStaticFunction("Parser::Said^1", Sc_Said); + ccAddExternalStaticFunction("Parser::Said^1", Sc_Said); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -341,3 +343,5 @@ void RegisterParserAPI() { ccAddExternalFunctionForPlugin("Parser::SaidUnknownWord^0", (void *)Parser_SaidUnknownWord); ccAddExternalFunctionForPlugin("Parser::Said^1", (void *)Said); } + +} // namespace ASG3 diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp index e68c908cbde9..84082a6e8e07 100644 --- a/engines/ags/engine/ac/properties.cpp +++ b/engines/ags/engine/ac/properties.cpp @@ -28,6 +28,8 @@ #include "script/runtimescriptvalue.h" #include "util/string_utils.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetupStruct game; @@ -104,3 +106,5 @@ bool set_text_property(StringIMap &rt_prop, const char *property, const char *va } return false; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp index 27a3d05ea528..9e12a5b705ee 100644 --- a/engines/ags/engine/ac/region.cpp +++ b/engines/ags/engine/ac/region.cpp @@ -32,6 +32,8 @@ #include "game/roomstruct.h" #include "script/runtimescriptvalue.h" +namespace AGS3 { + using namespace AGS::Shared; extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; @@ -223,23 +225,23 @@ RuntimeScriptValue Sc_Region_GetTintLuminance(void *self, const RuntimeScriptVal void RegisterRegionAPI() { - ccAddExternalStaticFunction("Region::GetAtRoomXY^2", Sc_GetRegionAtRoom); - ccAddExternalStaticFunction("Region::GetAtScreenXY^2", Sc_GetRegionAtScreen); - ccAddExternalStaticFunction("Region::GetDrawingSurface", Sc_Region_GetDrawingSurface); - ccAddExternalObjectFunction("Region::Tint^4", Sc_Region_TintNoLum); - ccAddExternalObjectFunction("Region::Tint^5", Sc_Region_Tint); - ccAddExternalObjectFunction("Region::RunInteraction^1", Sc_Region_RunInteraction); - ccAddExternalObjectFunction("Region::get_Enabled", Sc_Region_GetEnabled); - ccAddExternalObjectFunction("Region::set_Enabled", Sc_Region_SetEnabled); - ccAddExternalObjectFunction("Region::get_ID", Sc_Region_GetID); - ccAddExternalObjectFunction("Region::get_LightLevel", Sc_Region_GetLightLevel); - ccAddExternalObjectFunction("Region::set_LightLevel", Sc_Region_SetLightLevel); - ccAddExternalObjectFunction("Region::get_TintEnabled", Sc_Region_GetTintEnabled); - ccAddExternalObjectFunction("Region::get_TintBlue", Sc_Region_GetTintBlue); - ccAddExternalObjectFunction("Region::get_TintGreen", Sc_Region_GetTintGreen); - ccAddExternalObjectFunction("Region::get_TintRed", Sc_Region_GetTintRed); - ccAddExternalObjectFunction("Region::get_TintSaturation", Sc_Region_GetTintSaturation); - ccAddExternalObjectFunction("Region::get_TintLuminance", Sc_Region_GetTintLuminance); + ccAddExternalStaticFunction("Region::GetAtRoomXY^2", Sc_GetRegionAtRoom); + ccAddExternalStaticFunction("Region::GetAtScreenXY^2", Sc_GetRegionAtScreen); + ccAddExternalStaticFunction("Region::GetDrawingSurface", Sc_Region_GetDrawingSurface); + ccAddExternalObjectFunction("Region::Tint^4", Sc_Region_TintNoLum); + ccAddExternalObjectFunction("Region::Tint^5", Sc_Region_Tint); + ccAddExternalObjectFunction("Region::RunInteraction^1", Sc_Region_RunInteraction); + ccAddExternalObjectFunction("Region::get_Enabled", Sc_Region_GetEnabled); + ccAddExternalObjectFunction("Region::set_Enabled", Sc_Region_SetEnabled); + ccAddExternalObjectFunction("Region::get_ID", Sc_Region_GetID); + ccAddExternalObjectFunction("Region::get_LightLevel", Sc_Region_GetLightLevel); + ccAddExternalObjectFunction("Region::set_LightLevel", Sc_Region_SetLightLevel); + ccAddExternalObjectFunction("Region::get_TintEnabled", Sc_Region_GetTintEnabled); + ccAddExternalObjectFunction("Region::get_TintBlue", Sc_Region_GetTintBlue); + ccAddExternalObjectFunction("Region::get_TintGreen", Sc_Region_GetTintGreen); + ccAddExternalObjectFunction("Region::get_TintRed", Sc_Region_GetTintRed); + ccAddExternalObjectFunction("Region::get_TintSaturation", Sc_Region_GetTintSaturation); + ccAddExternalObjectFunction("Region::get_TintLuminance", Sc_Region_GetTintLuminance); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -258,3 +260,5 @@ void RegisterRegionAPI() { ccAddExternalFunctionForPlugin("Region::get_TintRed", (void *)Region_GetTintRed); ccAddExternalFunctionForPlugin("Region::get_TintSaturation", (void *)Region_GetTintSaturation); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp index 3bf8e2c68c3e..0c15a3f70276 100644 --- a/engines/ags/engine/ac/richgamemedia.cpp +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -23,6 +23,8 @@ #include "ac/richgamemedia.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; void RICH_GAME_MEDIA_HEADER::ReadFromFile(Stream *in) { @@ -52,3 +54,5 @@ void RICH_GAME_MEDIA_HEADER::WriteToFile(Stream *out) { out->WriteArrayOfInt16((int16_t *)szLevelName, RM_MAXLENGTH); out->WriteArrayOfInt16((int16_t *)szComments, RM_MAXLENGTH); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index d2055e6049f5..8b7b4276d0d2 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -77,6 +77,8 @@ #include "util/math.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -1222,3 +1224,5 @@ void RegisterRoomAPI() { ccAddExternalFunctionForPlugin("Room::get_TopEdge", (void *)Room_GetTopEdge); ccAddExternalFunctionForPlugin("Room::get_Width", (void *)Room_GetWidth); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp index ac9a7b05e45b..92947e3db713 100644 --- a/engines/ags/engine/ac/roomobject.cpp +++ b/engines/ags/engine/ac/roomobject.cpp @@ -30,6 +30,8 @@ #include "main/update.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; extern ViewStruct *views; @@ -121,8 +123,8 @@ void RoomObject::update_cycle_view_forwards() { if (play.no_multiloop_repeat == 0) { // multi-loop anims, go back to start of it while ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) - loop --; + (views[view].loops[loop - 1].RunNextLoop())) + loop--; } if (cycling % ANIM_BACKWARDS == ANIM_ONCERESET) cycling = 0; @@ -136,9 +138,9 @@ void RoomObject::update_cycle_view_backwards() { frame--; if (frame < 0) { if ((loop > 0) && - (views[view].loops[loop - 1].RunNextLoop())) { + (views[view].loops[loop - 1].RunNextLoop())) { // If it's a Go-to-next-loop on the previous one, then go back - loop --; + loop--; frame = views[view].loops[loop].numFrames - 1; } else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) { // leave it on the first frame @@ -163,3 +165,5 @@ void RoomObject::WriteToFile(Stream *out) const { out->WriteArrayOfInt8((int8_t *)&cycling, 4); out->WriteArrayOfInt16(&blocking_width, 2); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp index 368875d0bf9b..3687e476b5d0 100644 --- a/engines/ags/engine/ac/roomstatus.cpp +++ b/engines/ags/engine/ac/roomstatus.cpp @@ -29,6 +29,8 @@ #include "game/savegame_components.h" #include "util/alignedstream.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -47,12 +49,12 @@ RoomStatus::RoomStatus() { RoomStatus::~RoomStatus() { if (tsdata) - delete [] tsdata; + delete[] tsdata; } void RoomStatus::FreeScriptData() { if (tsdata) - delete [] tsdata; + delete[] tsdata; tsdata = nullptr; tsdatasize = 0; } @@ -212,3 +214,5 @@ void resetRoomStatuses() { } } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index 5de75a3e049a..44fa3464fd38 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -27,6 +27,8 @@ #include "debug/out.h" +namespace AGS3 { + using AGS::Shared::Bitmap; class IRouteFinder { @@ -138,3 +140,5 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int void calculate_move_stage(MoveList *mlsp, int aaa) { route_finder_impl->calculate_move_stage(mlsp, aaa); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp index 66970fb31fa6..a9d93a6bb55a 100644 --- a/engines/ags/engine/ac/route_finder_impl.cpp +++ b/engines/ags/engine/ac/route_finder_impl.cpp @@ -39,6 +39,8 @@ #include "route_finder_jps.inl" +namespace AGS3 { + extern MoveList *mls; using AGS::Shared::Bitmap; @@ -265,3 +267,4 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int } // namespace RouteFinder } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp index 4bbe4c35e6bd..be4c99a9d17b 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp +++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp @@ -39,6 +39,8 @@ #include "gfx/bitmap.h" #include "debug/out.h" +namespace AGS3 { + extern void update_polled_stuff_if_runtime(); extern MoveList *mls; @@ -85,11 +87,11 @@ static int lastcx, lastcy; static void line_callback(BITMAP *bmpp, int x, int y, int d) { /* if ((x>=320) | (y>=200) | (x<0) | (y<0)) line_failed=1; else */ if (getpixel(bmpp, x, y) < 1) - line_failed = 1; - else if (line_failed == 0) { - lastcx = x; - lastcy = y; - } + line_failed = 1; + else if (line_failed == 0) { + lastcx = x; + lastcy = y; + } } @@ -330,7 +332,7 @@ static int try_this_square(int srcx, int srcy, int tox, int toy) { } if (((nextx < 0) | (nextx >= wallscreen->GetWidth()) | (nexty < 0) | (nexty >= wallscreen->GetHeight())) || - (wallscreen->GetPixel(nextx, nexty) == 0) || ((beenhere[srcy][srcx] & (1 << trydir)) != 0)) { + (wallscreen->GetPixel(nextx, nexty) == 0) || ((beenhere[srcy][srcx] & (1 << trydir)) != 0)) { if (leftorright == 0) { trydir++; @@ -344,7 +346,7 @@ static int try_this_square(int srcx, int srcy, int tox, int toy) { goto try_again; } beenhere[srcy][srcx] |= (1 << trydir); -// srcx=nextx; srcy=nexty; + // srcx=nextx; srcy=nexty; beenhere[srcy][srcx] |= 0x80; // being processed int retcod = try_this_square(nextx, nexty, tox, toy); @@ -435,7 +437,7 @@ static int find_route_dijkstra(int fromx, int fromy, int destx, int desty) { return 1; } - int allocsize = int (wallscreen->GetWidth()) * int (wallscreen->GetHeight()) * sizeof(int); + int allocsize = int(wallscreen->GetWidth()) * int(wallscreen->GetHeight()) * sizeof(int); int *parent = (int *)malloc(allocsize); int min = 999999, cheapest[40], newcell[40], replace[40]; int *visited = (int *)malloc(MAX_TRAIL_LENGTH * sizeof(int)); @@ -511,8 +513,8 @@ static int find_route_dijkstra(int fromx, int fromy, int destx, int desty) { newx = newcell[p] % wallscreen->GetWidth(); newy = newcell[p] / wallscreen->GetWidth(); beenhere[newy][newx] = beenhere[cheapest[p] / wallscreen->GetWidth()][cheapest[p] % wallscreen->GetWidth()] + 1; -// int wal = walk_area_granularity[->GetPixel(wallscreen, newx, newy)]; -// beenhere[newy - newy%wal][newx - newx%wal] = beenhere[newy][newx]; + // int wal = walk_area_granularity[->GetPixel(wallscreen, newx, newy)]; + // beenhere[newy - newy%wal][newx - newx%wal] = beenhere[newy][newx]; parent[newcell[p]] = cheapest[p]; // edges of screen pose a problem, so if current and dest are within @@ -525,7 +527,7 @@ static int find_route_dijkstra(int fromx, int fromy, int destx, int desty) { // Found the desination, abort loop if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) - && (newy <= destyhi)) { + && (newy <= destyhi)) { foundAnswer = newcell[p]; break; } @@ -578,7 +580,7 @@ static int find_route_dijkstra(int fromx, int fromy, int destx, int desty) { newx = on % wallscreen->GetWidth(); newy = on / wallscreen->GetWidth(); if ((newx >= destxlow) && (newx <= destxhi) && (newy >= destylow) - && (newy <= destyhi)) + && (newy <= destyhi)) break; pathbackx[pathbackstage] = on % wallscreen->GetWidth(); @@ -816,7 +818,7 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int } if ((nearestpos == 0) && (can_see_from(srcx, srcy, xx, yy) == 0) && - (srcx >= 0) && (srcy >= 0) && (srcx < wallscreen->GetWidth()) && (srcy < wallscreen->GetHeight()) && (pathbackstage > 0)) { + (srcx >= 0) && (srcy >= 0) && (srcx < wallscreen->GetWidth()) && (srcy < wallscreen->GetHeight()) && (pathbackstage > 0)) { // If we couldn't see anything, we're stuck in a corner so advance // to the next square anyway (but only if they're on the screen) nearestindx = pathbackstage - 1; @@ -906,8 +908,7 @@ void shutdown_pathfinder() { beenhere_array_size = 0; } - - } // namespace RouteFinderLegacy } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index 299fb1d63f49..ccdba1374506 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -36,6 +36,8 @@ #include "gfx/bitmap.h" #include "gfx/graphicsdriver.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -206,3 +208,5 @@ void RegisterScreenAPI() { ccAddExternalStaticFunction("Screen::ScreenToRoomPoint", Sc_Screen_ScreenToRoomPoint); ccAddExternalStaticFunction("Screen::RoomToScreenPoint", Sc_Screen_RoomToScreenPoint); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/screenoverlay.cpp b/engines/ags/engine/ac/screenoverlay.cpp index 59926bbc8770..ed1a886f5218 100644 --- a/engines/ags/engine/ac/screenoverlay.cpp +++ b/engines/ags/engine/ac/screenoverlay.cpp @@ -23,6 +23,8 @@ #include "screenoverlay.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; void ScreenOverlay::ReadFromFile(Stream *in, int32_t cmp_ver) { @@ -62,3 +64,5 @@ void ScreenOverlay::WriteToFile(Stream *out) const { out->WriteInt32(_offsetX); out->WriteInt32(_offsetY); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index 6913fa606b09..5b33fdd3a350 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -37,6 +37,8 @@ #include "script/script_runtime.h" #include "util/bbop.h" +namespace AGS3 { + extern ScriptString myScriptStringImpl; //============================================================================= @@ -316,3 +318,5 @@ void RegisterContainerAPI() { ccAddExternalObjectFunction("Set::get_ItemCount", Sc_Set_GetItemCount); ccAddExternalObjectFunction("Set::GetItemsAsArray", Sc_Set_GetItemAsArray); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/slider.cpp b/engines/ags/engine/ac/slider.cpp index 2cd6b58e4cda..66273367ba7c 100644 --- a/engines/ags/engine/ac/slider.cpp +++ b/engines/ags/engine/ac/slider.cpp @@ -23,6 +23,8 @@ #include "ac/slider.h" #include "ac/common.h" +namespace AGS3 { + // *** SLIDER FUNCTIONS void Slider_SetMax(GUISlider *guisl, int valn) { @@ -182,18 +184,18 @@ RuntimeScriptValue Sc_Slider_SetValue(void *self, const RuntimeScriptValue *para void RegisterSliderAPI() { - ccAddExternalObjectFunction("Slider::get_BackgroundGraphic", Sc_Slider_GetBackgroundGraphic); - ccAddExternalObjectFunction("Slider::set_BackgroundGraphic", Sc_Slider_SetBackgroundGraphic); - ccAddExternalObjectFunction("Slider::get_HandleGraphic", Sc_Slider_GetHandleGraphic); - ccAddExternalObjectFunction("Slider::set_HandleGraphic", Sc_Slider_SetHandleGraphic); - ccAddExternalObjectFunction("Slider::get_HandleOffset", Sc_Slider_GetHandleOffset); - ccAddExternalObjectFunction("Slider::set_HandleOffset", Sc_Slider_SetHandleOffset); - ccAddExternalObjectFunction("Slider::get_Max", Sc_Slider_GetMax); - ccAddExternalObjectFunction("Slider::set_Max", Sc_Slider_SetMax); - ccAddExternalObjectFunction("Slider::get_Min", Sc_Slider_GetMin); - ccAddExternalObjectFunction("Slider::set_Min", Sc_Slider_SetMin); - ccAddExternalObjectFunction("Slider::get_Value", Sc_Slider_GetValue); - ccAddExternalObjectFunction("Slider::set_Value", Sc_Slider_SetValue); + ccAddExternalObjectFunction("Slider::get_BackgroundGraphic", Sc_Slider_GetBackgroundGraphic); + ccAddExternalObjectFunction("Slider::set_BackgroundGraphic", Sc_Slider_SetBackgroundGraphic); + ccAddExternalObjectFunction("Slider::get_HandleGraphic", Sc_Slider_GetHandleGraphic); + ccAddExternalObjectFunction("Slider::set_HandleGraphic", Sc_Slider_SetHandleGraphic); + ccAddExternalObjectFunction("Slider::get_HandleOffset", Sc_Slider_GetHandleOffset); + ccAddExternalObjectFunction("Slider::set_HandleOffset", Sc_Slider_SetHandleOffset); + ccAddExternalObjectFunction("Slider::get_Max", Sc_Slider_GetMax); + ccAddExternalObjectFunction("Slider::set_Max", Sc_Slider_SetMax); + ccAddExternalObjectFunction("Slider::get_Min", Sc_Slider_GetMin); + ccAddExternalObjectFunction("Slider::set_Min", Sc_Slider_SetMin); + ccAddExternalObjectFunction("Slider::get_Value", Sc_Slider_GetValue); + ccAddExternalObjectFunction("Slider::set_Value", Sc_Slider_SetValue); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -210,3 +212,5 @@ void RegisterSliderAPI() { ccAddExternalFunctionForPlugin("Slider::get_Value", (void *)Slider_GetValue); ccAddExternalFunctionForPlugin("Slider::set_Value", (void *)Slider_SetValue); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp index 32c416a7c6ff..e91694c826a0 100644 --- a/engines/ags/engine/ac/speech.cpp +++ b/engines/ags/engine/ac/speech.cpp @@ -25,6 +25,8 @@ #include "ac/speech.h" #include "debug/debug_log.h" +namespace AGS3 { + int user_to_internal_skip_speech(SkipSpeechStyle userval) { switch (userval) { case kSkipSpeechKeyMouseTime: @@ -194,29 +196,31 @@ void RegisterSpeechAPI(ScriptAPIVersion base_api, ScriptAPIVersion compat_api) { ccAddExternalStaticFunction("Speech::set_AnimationStopTimeMargin", Sc_Speech_SetAnimationStopTimeMargin); ccAddExternalStaticFunction("Speech::get_CustomPortraitPlacement", Sc_Speech_GetCustomPortraitPlacement); ccAddExternalStaticFunction("Speech::set_CustomPortraitPlacement", Sc_Speech_SetCustomPortraitPlacement); - ccAddExternalStaticFunction("Speech::get_DisplayPostTimeMs", Sc_Speech_GetDisplayPostTimeMs); - ccAddExternalStaticFunction("Speech::set_DisplayPostTimeMs", Sc_Speech_SetDisplayPostTimeMs); + ccAddExternalStaticFunction("Speech::get_DisplayPostTimeMs", Sc_Speech_GetDisplayPostTimeMs); + ccAddExternalStaticFunction("Speech::set_DisplayPostTimeMs", Sc_Speech_SetDisplayPostTimeMs); ccAddExternalStaticFunction("Speech::get_GlobalSpeechAnimationDelay", Sc_Speech_GetGlobalSpeechAnimationDelay); ccAddExternalStaticFunction("Speech::set_GlobalSpeechAnimationDelay", Sc_Speech_SetGlobalSpeechAnimationDelay); - ccAddExternalStaticFunction("Speech::get_PortraitXOffset", Sc_Speech_GetPortraitXOffset); - ccAddExternalStaticFunction("Speech::set_PortraitXOffset", Sc_Speech_SetPortraitXOffset); - ccAddExternalStaticFunction("Speech::get_PortraitY", Sc_Speech_GetPortraitY); - ccAddExternalStaticFunction("Speech::set_PortraitY", Sc_Speech_SetPortraitY); - ccAddExternalStaticFunction("Speech::get_SkipKey", Sc_Speech_GetSkipKey); - ccAddExternalStaticFunction("Speech::set_SkipKey", Sc_Speech_SetSkipKey); - ccAddExternalStaticFunction("Speech::get_SkipStyle", Sc_Speech_GetSkipStyle); - ccAddExternalStaticFunction("Speech::set_SkipStyle", Sc_SetSkipSpeech); - ccAddExternalStaticFunction("Speech::get_Style", Sc_Speech_GetStyle); - ccAddExternalStaticFunction("Speech::set_Style", Sc_SetSpeechStyle); - ccAddExternalStaticFunction("Speech::get_TextAlignment", Sc_Speech_GetTextAlignment); + ccAddExternalStaticFunction("Speech::get_PortraitXOffset", Sc_Speech_GetPortraitXOffset); + ccAddExternalStaticFunction("Speech::set_PortraitXOffset", Sc_Speech_SetPortraitXOffset); + ccAddExternalStaticFunction("Speech::get_PortraitY", Sc_Speech_GetPortraitY); + ccAddExternalStaticFunction("Speech::set_PortraitY", Sc_Speech_SetPortraitY); + ccAddExternalStaticFunction("Speech::get_SkipKey", Sc_Speech_GetSkipKey); + ccAddExternalStaticFunction("Speech::set_SkipKey", Sc_Speech_SetSkipKey); + ccAddExternalStaticFunction("Speech::get_SkipStyle", Sc_Speech_GetSkipStyle); + ccAddExternalStaticFunction("Speech::set_SkipStyle", Sc_SetSkipSpeech); + ccAddExternalStaticFunction("Speech::get_Style", Sc_Speech_GetStyle); + ccAddExternalStaticFunction("Speech::set_Style", Sc_SetSpeechStyle); + ccAddExternalStaticFunction("Speech::get_TextAlignment", Sc_Speech_GetTextAlignment); if (base_api < kScriptAPI_v350) - ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment_Old); + ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment_Old); else - ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment); + ccAddExternalStaticFunction("Speech::set_TextAlignment", Sc_Speech_SetTextAlignment); ccAddExternalStaticFunction("Speech::get_UseGlobalSpeechAnimationDelay", Sc_Speech_GetUseGlobalSpeechAnimationDelay); ccAddExternalStaticFunction("Speech::set_UseGlobalSpeechAnimationDelay", Sc_Speech_SetUseGlobalSpeechAnimationDelay); - ccAddExternalStaticFunction("Speech::get_VoiceMode", Sc_Speech_GetVoiceMode); - ccAddExternalStaticFunction("Speech::set_VoiceMode", Sc_SetVoiceMode); + ccAddExternalStaticFunction("Speech::get_VoiceMode", Sc_Speech_GetVoiceMode); + ccAddExternalStaticFunction("Speech::set_VoiceMode", Sc_SetVoiceMode); /* -- Don't register more unsafe plugin symbols until new plugin interface is designed --*/ } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp index 562b89719e66..25457a4963cf 100644 --- a/engines/ags/engine/ac/sprite.cpp +++ b/engines/ags/engine/ac/sprite.cpp @@ -32,6 +32,8 @@ #include "gfx/bitmap.h" #include "gfx/graphicsdriver.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -181,3 +183,5 @@ void initialize_sprite(int ee) { our_eip = oldeip; } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/spritecache_engine.cpp b/engines/ags/engine/ac/spritecache_engine.cpp index 5c6533d5dc55..9f5ae3388e4e 100644 --- a/engines/ags/engine/ac/spritecache_engine.cpp +++ b/engines/ags/engine/ac/spritecache_engine.cpp @@ -37,6 +37,8 @@ #include "ac/spritecache.h" #include "util/compress.h" +namespace AGS3 { + //============================================================================= // Engine-specific implementation split out of sprcache.cpp //============================================================================= @@ -50,3 +52,5 @@ void SpriteCache::InitNullSpriteParams(sprkey_t index) { _spriteData[index].Size = _spriteData[0].Size; _spriteData[index].Flags = SPRCACHEFLAG_REMAPPED; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp index 53233da9f813..54f975ee7608 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.cpp +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -25,6 +25,8 @@ #include "ac/game.h" #include "ac/gamestate.h" +namespace AGS3 { + AGSStaticObject GlobalStaticManager; StaticGame GameStaticManager; @@ -84,3 +86,5 @@ void StaticGame::WriteInt32(const char *address, intptr_t offset, int32_t val) { *(int32_t *)(address + offset) = val; } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp index 8b87c74932b2..a55758eac62b 100644 --- a/engines/ags/engine/ac/statobj/staticarray.cpp +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -24,28 +24,30 @@ #include "ac/statobj/staticarray.h" #include "ac/dynobj/cc_dynamicobject.h" +namespace AGS3 { + void StaticArray::Create(int elem_legacy_size, int elem_real_size, int elem_count) { - _staticMgr = nullptr; - _dynamicMgr = nullptr; + _staticMgr = nullptr; + _dynamicMgr = nullptr; _elemLegacySize = elem_legacy_size; - _elemRealSize = elem_real_size; - _elemCount = elem_count; + _elemRealSize = elem_real_size; + _elemCount = elem_count; } void StaticArray::Create(ICCStaticObject *stcmgr, int elem_legacy_size, int elem_real_size, int elem_count) { - _staticMgr = stcmgr; - _dynamicMgr = nullptr; + _staticMgr = stcmgr; + _dynamicMgr = nullptr; _elemLegacySize = elem_legacy_size; - _elemRealSize = elem_real_size; - _elemCount = elem_count; + _elemRealSize = elem_real_size; + _elemCount = elem_count; } void StaticArray::Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int elem_real_size, int elem_count) { - _staticMgr = nullptr; - _dynamicMgr = dynmgr; + _staticMgr = nullptr; + _dynamicMgr = dynmgr; _elemLegacySize = elem_legacy_size; - _elemRealSize = elem_real_size; - _elemCount = elem_count; + _elemRealSize = elem_real_size; + _elemCount = elem_count; } const char *StaticArray::GetElementPtr(const char *address, intptr_t legacy_offset) { @@ -160,3 +162,5 @@ void StaticArray::WriteFloat(const char *address, intptr_t offset, float val) { *(float *)(el_ptr + offset % _elemLegacySize) = val; } } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index 11b27c34e42a..3380f56c7d44 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -34,6 +34,8 @@ #include "script/runtimescriptvalue.h" #include "util/string_compat.h" +namespace AGS3 { + extern GameSetupStruct game; extern GameState play; extern int longestline; @@ -254,14 +256,13 @@ size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, i line_length = wgettextwidth_compensate(lines[rr], fonnt); if (line_length > longestline) longestline = line_length; - } - else - for (size_t rr = 0; rr < lines.Count(); rr++) { - line_length = wgettextwidth_compensate(lines[rr], fonnt); - if (line_length > longestline) - longestline = line_length; - } - return lines.Count(); + } else + for (size_t rr = 0; rr < lines.Count(); rr++) { + line_length = wgettextwidth_compensate(lines[rr], fonnt); + if (line_length > longestline) + longestline = line_length; + } + return lines.Count(); } int MAXSTRLEN = MAX_MAXSTRLEN; @@ -412,26 +413,26 @@ const char *ScPl_String_Format(const char *texx, ...) { void RegisterStringAPI() { - ccAddExternalStaticFunction("String::IsNullOrEmpty^1", Sc_String_IsNullOrEmpty); - ccAddExternalObjectFunction("String::Append^1", Sc_String_Append); - ccAddExternalObjectFunction("String::AppendChar^1", Sc_String_AppendChar); - ccAddExternalObjectFunction("String::CompareTo^2", Sc_String_CompareTo); - ccAddExternalObjectFunction("String::Contains^1", Sc_StrContains); - ccAddExternalObjectFunction("String::Copy^0", Sc_String_Copy); - ccAddExternalObjectFunction("String::EndsWith^2", Sc_String_EndsWith); - ccAddExternalStaticFunction("String::Format^101", Sc_String_Format); - ccAddExternalObjectFunction("String::IndexOf^1", Sc_StrContains); - ccAddExternalObjectFunction("String::LowerCase^0", Sc_String_LowerCase); - ccAddExternalObjectFunction("String::Replace^3", Sc_String_Replace); - ccAddExternalObjectFunction("String::ReplaceCharAt^2", Sc_String_ReplaceCharAt); - ccAddExternalObjectFunction("String::StartsWith^2", Sc_String_StartsWith); - ccAddExternalObjectFunction("String::Substring^2", Sc_String_Substring); - ccAddExternalObjectFunction("String::Truncate^1", Sc_String_Truncate); - ccAddExternalObjectFunction("String::UpperCase^0", Sc_String_UpperCase); - ccAddExternalObjectFunction("String::get_AsFloat", Sc_StringToFloat); - ccAddExternalObjectFunction("String::get_AsInt", Sc_StringToInt); - ccAddExternalObjectFunction("String::geti_Chars", Sc_String_GetChars); - ccAddExternalObjectFunction("String::get_Length", Sc_strlen); + ccAddExternalStaticFunction("String::IsNullOrEmpty^1", Sc_String_IsNullOrEmpty); + ccAddExternalObjectFunction("String::Append^1", Sc_String_Append); + ccAddExternalObjectFunction("String::AppendChar^1", Sc_String_AppendChar); + ccAddExternalObjectFunction("String::CompareTo^2", Sc_String_CompareTo); + ccAddExternalObjectFunction("String::Contains^1", Sc_StrContains); + ccAddExternalObjectFunction("String::Copy^0", Sc_String_Copy); + ccAddExternalObjectFunction("String::EndsWith^2", Sc_String_EndsWith); + ccAddExternalStaticFunction("String::Format^101", Sc_String_Format); + ccAddExternalObjectFunction("String::IndexOf^1", Sc_StrContains); + ccAddExternalObjectFunction("String::LowerCase^0", Sc_String_LowerCase); + ccAddExternalObjectFunction("String::Replace^3", Sc_String_Replace); + ccAddExternalObjectFunction("String::ReplaceCharAt^2", Sc_String_ReplaceCharAt); + ccAddExternalObjectFunction("String::StartsWith^2", Sc_String_StartsWith); + ccAddExternalObjectFunction("String::Substring^2", Sc_String_Substring); + ccAddExternalObjectFunction("String::Truncate^1", Sc_String_Truncate); + ccAddExternalObjectFunction("String::UpperCase^0", Sc_String_UpperCase); + ccAddExternalObjectFunction("String::get_AsFloat", Sc_StringToFloat); + ccAddExternalObjectFunction("String::get_AsInt", Sc_StringToInt); + ccAddExternalObjectFunction("String::geti_Chars", Sc_String_GetChars); + ccAddExternalObjectFunction("String::get_Length", Sc_strlen); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -456,3 +457,5 @@ void RegisterStringAPI() { ccAddExternalFunctionForPlugin("String::geti_Chars", (void *)String_GetChars); ccAddExternalFunctionForPlugin("String::get_Length", (void *)strlen); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index 37306e004ab8..fc20cdbd9811 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -31,6 +31,8 @@ #include "platform/base/agsplatformdriver.h" #include "ac/timer.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -133,106 +135,106 @@ int ags_getch() { // the complete scan code list is not here. switch (scancode) { - case __allegro_KEY_F1 : - gott = eAGSKeyCodeF1 ; + case __allegro_KEY_F1: + gott = eAGSKeyCodeF1; break; - case __allegro_KEY_F2 : - gott = eAGSKeyCodeF2 ; + case __allegro_KEY_F2: + gott = eAGSKeyCodeF2; break; - case __allegro_KEY_F3 : - gott = eAGSKeyCodeF3 ; + case __allegro_KEY_F3: + gott = eAGSKeyCodeF3; break; - case __allegro_KEY_F4 : - gott = eAGSKeyCodeF4 ; + case __allegro_KEY_F4: + gott = eAGSKeyCodeF4; break; - case __allegro_KEY_F5 : - gott = eAGSKeyCodeF5 ; + case __allegro_KEY_F5: + gott = eAGSKeyCodeF5; break; - case __allegro_KEY_F6 : - gott = eAGSKeyCodeF6 ; + case __allegro_KEY_F6: + gott = eAGSKeyCodeF6; break; - case __allegro_KEY_F7 : - gott = eAGSKeyCodeF7 ; + case __allegro_KEY_F7: + gott = eAGSKeyCodeF7; break; - case __allegro_KEY_F8 : - gott = eAGSKeyCodeF8 ; + case __allegro_KEY_F8: + gott = eAGSKeyCodeF8; break; - case __allegro_KEY_F9 : - gott = eAGSKeyCodeF9 ; + case __allegro_KEY_F9: + gott = eAGSKeyCodeF9; break; - case __allegro_KEY_F10 : - gott = eAGSKeyCodeF10 ; + case __allegro_KEY_F10: + gott = eAGSKeyCodeF10; break; - case __allegro_KEY_F11 : - gott = eAGSKeyCodeF11 ; + case __allegro_KEY_F11: + gott = eAGSKeyCodeF11; break; - case __allegro_KEY_F12 : - gott = eAGSKeyCodeF12 ; + case __allegro_KEY_F12: + gott = eAGSKeyCodeF12; break; - case __allegro_KEY_INSERT : - gott = eAGSKeyCodeInsert ; + case __allegro_KEY_INSERT: + gott = eAGSKeyCodeInsert; break; - case __allegro_KEY_DEL : - gott = eAGSKeyCodeDelete ; + case __allegro_KEY_DEL: + gott = eAGSKeyCodeDelete; break; - case __allegro_KEY_HOME : - gott = eAGSKeyCodeHome ; + case __allegro_KEY_HOME: + gott = eAGSKeyCodeHome; break; - case __allegro_KEY_END : - gott = eAGSKeyCodeEnd ; + case __allegro_KEY_END: + gott = eAGSKeyCodeEnd; break; - case __allegro_KEY_PGUP : - gott = eAGSKeyCodePageUp ; + case __allegro_KEY_PGUP: + gott = eAGSKeyCodePageUp; break; - case __allegro_KEY_PGDN : - gott = eAGSKeyCodePageDown ; + case __allegro_KEY_PGDN: + gott = eAGSKeyCodePageDown; break; - case __allegro_KEY_LEFT : - gott = eAGSKeyCodeLeftArrow ; + case __allegro_KEY_LEFT: + gott = eAGSKeyCodeLeftArrow; break; - case __allegro_KEY_RIGHT : - gott = eAGSKeyCodeRightArrow ; + case __allegro_KEY_RIGHT: + gott = eAGSKeyCodeRightArrow; break; - case __allegro_KEY_UP : - gott = eAGSKeyCodeUpArrow ; + case __allegro_KEY_UP: + gott = eAGSKeyCodeUpArrow; break; - case __allegro_KEY_DOWN : - gott = eAGSKeyCodeDownArrow ; + case __allegro_KEY_DOWN: + gott = eAGSKeyCodeDownArrow; break; - case __allegro_KEY_0_PAD : - gott = eAGSKeyCodeInsert ; + case __allegro_KEY_0_PAD: + gott = eAGSKeyCodeInsert; break; - case __allegro_KEY_1_PAD : - gott = eAGSKeyCodeEnd ; + case __allegro_KEY_1_PAD: + gott = eAGSKeyCodeEnd; break; - case __allegro_KEY_2_PAD : - gott = eAGSKeyCodeDownArrow ; + case __allegro_KEY_2_PAD: + gott = eAGSKeyCodeDownArrow; break; - case __allegro_KEY_3_PAD : - gott = eAGSKeyCodePageDown ; + case __allegro_KEY_3_PAD: + gott = eAGSKeyCodePageDown; break; - case __allegro_KEY_4_PAD : - gott = eAGSKeyCodeLeftArrow ; + case __allegro_KEY_4_PAD: + gott = eAGSKeyCodeLeftArrow; break; - case __allegro_KEY_5_PAD : - gott = eAGSKeyCodeNumPad5 ; + case __allegro_KEY_5_PAD: + gott = eAGSKeyCodeNumPad5; break; - case __allegro_KEY_6_PAD : - gott = eAGSKeyCodeRightArrow ; + case __allegro_KEY_6_PAD: + gott = eAGSKeyCodeRightArrow; break; - case __allegro_KEY_7_PAD : - gott = eAGSKeyCodeHome ; + case __allegro_KEY_7_PAD: + gott = eAGSKeyCodeHome; break; - case __allegro_KEY_8_PAD : - gott = eAGSKeyCodeUpArrow ; + case __allegro_KEY_8_PAD: + gott = eAGSKeyCodeUpArrow; break; - case __allegro_KEY_9_PAD : - gott = eAGSKeyCodePageUp ; + case __allegro_KEY_9_PAD: + gott = eAGSKeyCodePageUp; break; - case __allegro_KEY_DEL_PAD : - gott = eAGSKeyCodeDelete ; + case __allegro_KEY_DEL_PAD: + gott = eAGSKeyCodeDelete; break; default: @@ -268,3 +270,5 @@ void ags_wait_until_keypress() { } ags_getch(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index 667c75e6b610..33be22fd38a7 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -41,6 +41,8 @@ #include "media/audio/audio_system.h" #include "util/string_compat.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -371,35 +373,35 @@ RuntimeScriptValue Sc_System_Log(const RuntimeScriptValue *params, int32_t param void RegisterSystemAPI() { - ccAddExternalStaticFunction("System::get_AudioChannelCount", Sc_System_GetAudioChannelCount); - ccAddExternalStaticFunction("System::geti_AudioChannels", Sc_System_GetAudioChannels); - ccAddExternalStaticFunction("System::get_CapsLock", Sc_System_GetCapsLock); - ccAddExternalStaticFunction("System::get_ColorDepth", Sc_System_GetColorDepth); - ccAddExternalStaticFunction("System::get_Gamma", Sc_System_GetGamma); - ccAddExternalStaticFunction("System::set_Gamma", Sc_System_SetGamma); + ccAddExternalStaticFunction("System::get_AudioChannelCount", Sc_System_GetAudioChannelCount); + ccAddExternalStaticFunction("System::geti_AudioChannels", Sc_System_GetAudioChannels); + ccAddExternalStaticFunction("System::get_CapsLock", Sc_System_GetCapsLock); + ccAddExternalStaticFunction("System::get_ColorDepth", Sc_System_GetColorDepth); + ccAddExternalStaticFunction("System::get_Gamma", Sc_System_GetGamma); + ccAddExternalStaticFunction("System::set_Gamma", Sc_System_SetGamma); ccAddExternalStaticFunction("System::get_HardwareAcceleration", Sc_System_GetHardwareAcceleration); - ccAddExternalStaticFunction("System::get_HasInputFocus", Sc_System_GetHasInputFocus); - ccAddExternalStaticFunction("System::get_NumLock", Sc_System_GetNumLock); - ccAddExternalStaticFunction("System::set_NumLock", Sc_System_SetNumLock); - ccAddExternalStaticFunction("System::get_OperatingSystem", Sc_System_GetOS); + ccAddExternalStaticFunction("System::get_HasInputFocus", Sc_System_GetHasInputFocus); + ccAddExternalStaticFunction("System::get_NumLock", Sc_System_GetNumLock); + ccAddExternalStaticFunction("System::set_NumLock", Sc_System_SetNumLock); + ccAddExternalStaticFunction("System::get_OperatingSystem", Sc_System_GetOS); ccAddExternalStaticFunction("System::get_RenderAtScreenResolution", Sc_System_GetRenderAtScreenResolution); ccAddExternalStaticFunction("System::set_RenderAtScreenResolution", Sc_System_SetRenderAtScreenResolution); - ccAddExternalStaticFunction("System::get_RuntimeInfo", Sc_System_GetRuntimeInfo); - ccAddExternalStaticFunction("System::get_ScreenHeight", Sc_System_GetScreenHeight); - ccAddExternalStaticFunction("System::get_ScreenWidth", Sc_System_GetScreenWidth); - ccAddExternalStaticFunction("System::get_ScrollLock", Sc_System_GetScrollLock); + ccAddExternalStaticFunction("System::get_RuntimeInfo", Sc_System_GetRuntimeInfo); + ccAddExternalStaticFunction("System::get_ScreenHeight", Sc_System_GetScreenHeight); + ccAddExternalStaticFunction("System::get_ScreenWidth", Sc_System_GetScreenWidth); + ccAddExternalStaticFunction("System::get_ScrollLock", Sc_System_GetScrollLock); ccAddExternalStaticFunction("System::get_SupportsGammaControl", Sc_System_GetSupportsGammaControl); - ccAddExternalStaticFunction("System::get_Version", Sc_System_GetVersion); - ccAddExternalStaticFunction("SystemInfo::get_Version", Sc_System_GetVersion); - ccAddExternalStaticFunction("System::get_ViewportHeight", Sc_System_GetViewportHeight); - ccAddExternalStaticFunction("System::get_ViewportWidth", Sc_System_GetViewportWidth); - ccAddExternalStaticFunction("System::get_Volume", Sc_System_GetVolume); - ccAddExternalStaticFunction("System::set_Volume", Sc_System_SetVolume); - ccAddExternalStaticFunction("System::get_VSync", Sc_System_GetVsync); - ccAddExternalStaticFunction("System::set_VSync", Sc_System_SetVsync); - ccAddExternalStaticFunction("System::get_Windowed", Sc_System_GetWindowed); - ccAddExternalStaticFunction("System::set_Windowed", Sc_System_SetWindowed); - ccAddExternalStaticFunction("System::Log^102", Sc_System_Log); + ccAddExternalStaticFunction("System::get_Version", Sc_System_GetVersion); + ccAddExternalStaticFunction("SystemInfo::get_Version", Sc_System_GetVersion); + ccAddExternalStaticFunction("System::get_ViewportHeight", Sc_System_GetViewportHeight); + ccAddExternalStaticFunction("System::get_ViewportWidth", Sc_System_GetViewportWidth); + ccAddExternalStaticFunction("System::get_Volume", Sc_System_GetVolume); + ccAddExternalStaticFunction("System::set_Volume", Sc_System_SetVolume); + ccAddExternalStaticFunction("System::get_VSync", Sc_System_GetVsync); + ccAddExternalStaticFunction("System::set_VSync", Sc_System_SetVsync); + ccAddExternalStaticFunction("System::get_Windowed", Sc_System_GetWindowed); + ccAddExternalStaticFunction("System::set_Windowed", Sc_System_SetWindowed); + ccAddExternalStaticFunction("System::Log^102", Sc_System_Log); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -428,3 +430,5 @@ void RegisterSystemAPI() { ccAddExternalFunctionForPlugin("System::set_VSync", (void *)System_SetVsync); ccAddExternalFunctionForPlugin("System::get_Windowed", (void *)System_GetWindowed); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp index 4d8bce4677a6..64f68cc217b0 100644 --- a/engines/ags/engine/ac/textbox.cpp +++ b/engines/ags/engine/ac/textbox.cpp @@ -26,6 +26,8 @@ #include "ac/gamesetupstruct.h" #include "ac/string.h" +namespace AGS3 { + extern GameSetupStruct game; @@ -141,16 +143,16 @@ RuntimeScriptValue Sc_TextBox_SetTextColor(void *self, const RuntimeScriptValue void RegisterTextBoxAPI() { - ccAddExternalObjectFunction("TextBox::GetText^1", Sc_TextBox_GetText); - ccAddExternalObjectFunction("TextBox::SetText^1", Sc_TextBox_SetText); - ccAddExternalObjectFunction("TextBox::get_Font", Sc_TextBox_GetFont); - ccAddExternalObjectFunction("TextBox::set_Font", Sc_TextBox_SetFont); - ccAddExternalObjectFunction("TextBox::get_ShowBorder", Sc_TextBox_GetShowBorder); - ccAddExternalObjectFunction("TextBox::set_ShowBorder", Sc_TextBox_SetShowBorder); - ccAddExternalObjectFunction("TextBox::get_Text", Sc_TextBox_GetText_New); - ccAddExternalObjectFunction("TextBox::set_Text", Sc_TextBox_SetText); - ccAddExternalObjectFunction("TextBox::get_TextColor", Sc_TextBox_GetTextColor); - ccAddExternalObjectFunction("TextBox::set_TextColor", Sc_TextBox_SetTextColor); + ccAddExternalObjectFunction("TextBox::GetText^1", Sc_TextBox_GetText); + ccAddExternalObjectFunction("TextBox::SetText^1", Sc_TextBox_SetText); + ccAddExternalObjectFunction("TextBox::get_Font", Sc_TextBox_GetFont); + ccAddExternalObjectFunction("TextBox::set_Font", Sc_TextBox_SetFont); + ccAddExternalObjectFunction("TextBox::get_ShowBorder", Sc_TextBox_GetShowBorder); + ccAddExternalObjectFunction("TextBox::set_ShowBorder", Sc_TextBox_SetShowBorder); + ccAddExternalObjectFunction("TextBox::get_Text", Sc_TextBox_GetText_New); + ccAddExternalObjectFunction("TextBox::set_Text", Sc_TextBox_SetText); + ccAddExternalObjectFunction("TextBox::get_TextColor", Sc_TextBox_GetTextColor); + ccAddExternalObjectFunction("TextBox::set_TextColor", Sc_TextBox_SetTextColor); /* ----------------------- Registering unsafe exports for plugins -----------------------*/ @@ -163,3 +165,5 @@ void RegisterTextBoxAPI() { ccAddExternalFunctionForPlugin("TextBox::get_TextColor", (void *)TextBox_GetTextColor); ccAddExternalFunctionForPlugin("TextBox::set_TextColor", (void *)TextBox_SetTextColor); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index e94e7b3ed776..2e2f9b472b7e 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -31,6 +31,8 @@ #include #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + namespace { const auto MAXIMUM_FALL_BEHIND = 3; @@ -120,3 +122,5 @@ void skipMissedTicks() { last_tick_time = AGS_Clock::now(); next_frame_timestamp = AGS_Clock::now(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp index c7b3df4a2816..4ca6ac1577ac 100644 --- a/engines/ags/engine/ac/translation.cpp +++ b/engines/ags/engine/ac/translation.cpp @@ -36,6 +36,8 @@ #include "util/stream.h" #include "core/assetmanager.h" +namespace AGS3 { + using namespace AGS::Shared; extern GameSetup usetup; @@ -71,7 +73,7 @@ bool init_translation(const String &lang, const String &fallback_lang, bool quit // in case it's inside a library file, record the offset lang_offs_start = language_file->GetPosition(); - char transsig[16] = {0}; + char transsig[16] = { 0 }; language_file->Read(transsig, 15); if (strcmp(transsig, "AGSTranslation") != 0) { Debug::Printf(kDbgMsg_Error, "Translation signature mismatch: %s", transFileName); @@ -136,7 +138,7 @@ bool parse_translation(Stream *language_file, String &parse_error) { read_string_decrypt(language_file, wasgamename, sizeof(wasgamename)); if ((uidfrom != game.uniqueid) || (strcmp(wasgamename, game.gamename) != 0)) { parse_error.Format("The translation file is not compatible with this game. The translation is designed for '%s'.", - wasgamename); + wasgamename); return false; } } else if (blockType == 3) { @@ -171,3 +173,5 @@ bool parse_translation(Stream *language_file, String &parse_error) { return true; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/tree_map.cpp b/engines/ags/engine/ac/tree_map.cpp index a25ab6dcc5f2..0f8680d14a0d 100644 --- a/engines/ags/engine/ac/tree_map.cpp +++ b/engines/ags/engine/ac/tree_map.cpp @@ -25,6 +25,8 @@ #include "ac/common.h" #include "ac/tree_map.h" +namespace AGS3 { + TreeMap::TreeMap() { left = nullptr; right = nullptr; @@ -53,7 +55,7 @@ char *TreeMap::findValue(const char *key) { void TreeMap::addText(const char *ntx, char *trans) { if ((ntx == nullptr) || (ntx[0] == 0) || - ((text != nullptr) && (strcmp(ntx, text) == 0))) + ((text != nullptr) && (strcmp(ntx, text) == 0))) // don't add if it's an empty string or if it's already here return; @@ -101,3 +103,5 @@ void TreeMap::clear() { TreeMap::~TreeMap() { clear(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp index 4d7f0543a294..6f749c52c200 100644 --- a/engines/ags/engine/ac/viewframe.cpp +++ b/engines/ags/engine/ac/viewframe.cpp @@ -31,6 +31,8 @@ #include "ac/game_version.h" #include "media/audio/audio_system.h" +} // namespace AGS3 + using AGS::Shared::Bitmap; using AGS::Shared::Graphics; @@ -262,3 +264,5 @@ void RegisterViewFrameAPI() { ccAddExternalFunctionForPlugin("ViewFrame::get_Speed", (void *)ViewFrame_GetSpeed); ccAddExternalFunctionForPlugin("ViewFrame::get_View", (void *)ViewFrame_GetView); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp index b6fb314f5306..d4f405ab7628 100644 --- a/engines/ags/engine/ac/viewport_script.cpp +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -35,6 +35,8 @@ #include "script/script_api.h" #include "script/script_runtime.h" +namespace AGS3 { + using namespace AGS::Shared; //============================================================================= @@ -553,3 +555,5 @@ void RegisterViewportAPI() { ccAddExternalObjectFunction("Viewport::ScreenToRoomPoint", Sc_Viewport_ScreenToRoomPoint); ccAddExternalObjectFunction("Viewport::RoomToScreenPoint", Sc_Viewport_RoomToScreenPoint); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp index d129b3e138f5..93d6d5c07f90 100644 --- a/engines/ags/engine/ac/walkablearea.cpp +++ b/engines/ags/engine/ac/walkablearea.cpp @@ -33,6 +33,8 @@ #include "game/roomstruct.h" #include "gfx/bitmap.h" +namespace AGS3 { + using namespace AGS::Shared; extern RoomStruct thisroom; @@ -76,7 +78,7 @@ int get_area_scaling(int onarea, int xx, int yy) { yy = room_to_mask_coord(yy); if ((onarea >= 0) && (onarea <= MAX_WALK_AREAS) && - (thisroom.WalkAreas[onarea].ScalingNear != NOT_VECTOR_SCALED)) { + (thisroom.WalkAreas[onarea].ScalingNear != NOT_VECTOR_SCALED)) { // We have vector scaling! // In case the character is off the screen, limit the Y co-ordinate // to within the area range (otherwise we get silly zoom levels @@ -90,7 +92,7 @@ int get_area_scaling(int onarea, int xx, int yy) { // Zoom level = ((max - min) * Percent) / 100 if (thisroom.WalkAreas[onarea].Bottom != thisroom.WalkAreas[onarea].Top) { int percent = ((yy - thisroom.WalkAreas[onarea].Top) * 100) - / (thisroom.WalkAreas[onarea].Bottom - thisroom.WalkAreas[onarea].Top); + / (thisroom.WalkAreas[onarea].Bottom - thisroom.WalkAreas[onarea].Top); zoom_level = ((thisroom.WalkAreas[onarea].ScalingNear - thisroom.WalkAreas[onarea].ScalingFar) * (percent)) / 100 + thisroom.WalkAreas[onarea].ScalingFar; } else { // Special case for 1px tall walkable area: take bottom line scaling @@ -128,10 +130,10 @@ void remove_walkable_areas_from_temp(int fromx, int cwidth, int starty, int endy if (starty < 0) starty = 0; - for (; cwidth > 0; cwidth --) { + for (; cwidth > 0; cwidth--) { for (yyy = starty; yyy <= endy; yyy++) walkable_areas_temp->PutPixel(fromx, yyy, 0); - fromx ++; + fromx++; } } @@ -146,7 +148,7 @@ Bitmap *prepare_walkable_areas(int sourceChar) { // copy the walkable areas to the temp bitmap walkable_areas_temp->Blit(thisroom.WalkAreaMask.get(), 0, 0, 0, 0, thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight()); // if the character who's moving doesn't Bitmap *, don't bother checking - if (sourceChar < 0) ; + if (sourceChar < 0); else if (game.chars[sourceChar].flags & CHF_NOBLOCKING) return walkable_areas_temp; @@ -189,8 +191,8 @@ Bitmap *prepare_walkable_areas(int sourceChar) { // if the character is currently standing on the object, ignore // it so as to allow him to escape if ((sourceChar >= 0) && - (is_point_in_rect(game.chars[sourceChar].x, game.chars[sourceChar].y, - x1, y1, x1 + width, y2))) + (is_point_in_rect(game.chars[sourceChar].x, game.chars[sourceChar].y, + x1, y1, x1 + width, y2))) continue; remove_walkable_areas_from_temp(x1, width, y1, y2); @@ -239,3 +241,5 @@ int get_walkable_area_at_character(int charnum) { CharacterInfo *chin = &game.chars[charnum]; return get_walkable_area_at_location(chin->x, chin->y); } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp index 7ad1b0e2ed91..90744461858a 100644 --- a/engines/ags/engine/ac/walkbehind.cpp +++ b/engines/ags/engine/ac/walkbehind.cpp @@ -27,6 +27,8 @@ #include "gfx/graphicsdriver.h" #include "gfx/bitmap.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -54,9 +56,9 @@ void update_walk_behind_images() { if (walkBehindRight[ee] > 0) { wbbmp = BitmapHelper::CreateTransparentBitmap( - (walkBehindRight[ee] - walkBehindLeft[ee]) + 1, - (walkBehindBottom[ee] - walkBehindTop[ee]) + 1, - thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth()); + (walkBehindRight[ee] - walkBehindLeft[ee]) + 1, + (walkBehindBottom[ee] - walkBehindTop[ee]) + 1, + thisroom.BgFrames[play.bg_frame].Graphic->GetColorDepth()); int yy, startX = walkBehindLeft[ee], startY = walkBehindTop[ee]; for (rr = startX; rr <= walkBehindRight[ee]; rr++) { for (yy = startY; yy <= walkBehindBottom[ee]; yy++) { @@ -139,3 +141,5 @@ void recache_walk_behinds() { update_walk_behind_images(); } } + +} // namespace AGS3 diff --git a/engines/ags/engine/debugging/consoleoutputtarget.cpp b/engines/ags/engine/debugging/consoleoutputtarget.cpp index 3e90694f39ef..6f638edd7b03 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.cpp +++ b/engines/ags/engine/debugging/consoleoutputtarget.cpp @@ -24,6 +24,7 @@ #include "consoleoutputtarget.h" #include "debug/debug_log.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -44,3 +45,4 @@ void ConsoleOutputTarget::PrintMessage(const DebugMessage &msg) { } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index 997add89efc5..a974ff299539 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -48,6 +48,8 @@ #include #endif +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -165,8 +167,8 @@ MessageType get_messagetype_from_string(const String &mt) { typedef std::pair DbgGroupOption; void apply_log_config(const ConfigTree &cfg, const String &log_id, - bool def_enabled, - std::initializer_list def_opts) { + bool def_enabled, + std::initializer_list def_opts) { String value = INIreadstring(cfg, "log", log_id); if (value.IsEmpty() && !def_enabled) return; @@ -231,32 +233,32 @@ void apply_debug_config(const ConfigTree &cfg) { apply_log_config(cfg, OutputSystemID, /* defaults */ true, { DbgGroupOption(kDbgGroup_Main, kDbgMsg_Info) }); bool legacy_log_enabled = INIreadint(cfg, "misc", "log", 0) != 0; apply_log_config(cfg, OutputFileID, - /* defaults */ - legacy_log_enabled, { - DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), - DbgGroupOption(kDbgGroup_Game, kDbgMsg_Info), - DbgGroupOption(kDbgGroup_Script, kDbgMsg_All), -#ifdef DEBUG_SPRITECACHE - DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_All), -#else - DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_Info), -#endif -#ifdef DEBUG_MANAGED_OBJECTS - DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_All), -#else - DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_Info), -#endif - }); + /* defaults */ + legacy_log_enabled, { + DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Game, kDbgMsg_Info), + DbgGroupOption(kDbgGroup_Script, kDbgMsg_All), + #ifdef DEBUG_SPRITECACHE + DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_All), + #else + DbgGroupOption(kDbgGroup_SprCache, kDbgMsg_Info), + #endif + #ifdef DEBUG_MANAGED_OBJECTS + DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_All), + #else + DbgGroupOption(kDbgGroup_ManObj, kDbgMsg_Info), + #endif + }); // Init game console if the game was compiled in Debug mode if (game.options[OPT_DEBUGMODE] != 0) { apply_log_config(cfg, OutputGameConsoleID, - /* defaults */ - true, { - DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), - DbgGroupOption(kDbgGroup_Game, kDbgMsg_All), - DbgGroupOption(kDbgGroup_Script, kDbgMsg_All) - }); + /* defaults */ + true, { + DbgGroupOption(kDbgGroup_Main, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Game, kDbgMsg_All), + DbgGroupOption(kDbgGroup_Script, kDbgMsg_All) + }); debug_set_console(true); } @@ -430,7 +432,7 @@ int check_for_messages_from_editor() { free(msg); return 2; } else if ((strncmp(msgPtr, "SETBREAK", 8) == 0) || - (strncmp(msgPtr, "DELBREAK", 8) == 0)) { + (strncmp(msgPtr, "DELBREAK", 8) == 0)) { bool isDelete = (msgPtr[0] == 'D'); // Format: SETBREAK $scriptname$lineNumber$ msgPtr += 10; @@ -449,7 +451,7 @@ int check_for_messages_from_editor() { if (isDelete) { for (i = 0; i < numBreakpoints; i++) { if ((breakpoints[i].lineNumber == lineNumber) && - (strcmp(breakpoints[i].scriptName, scriptNameBuf) == 0)) { + (strcmp(breakpoints[i].scriptName, scriptNameBuf) == 0)) { numBreakpoints--; breakpoints.erase(breakpoints.begin() + i); break; @@ -548,7 +550,7 @@ void scriptDebugHook(ccInstance *ccinst, int linenum) { for (int i = 0; i < numBreakpoints; i++) { if ((breakpoints[i].lineNumber == linenum) && - (strcmp(breakpoints[i].scriptName, scriptName) == 0)) { + (strcmp(breakpoints[i].scriptName, scriptName) == 0)) { break_into_debugger(); break; } @@ -570,5 +572,6 @@ void check_debug_keys() { } } - } + +} // namespace AGS3 diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.cpp b/engines/ags/engine/debugging/filebasedagsdebugger.cpp index a95700ba4ffb..891fac1155ce 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.cpp +++ b/engines/ags/engine/debugging/filebasedagsdebugger.cpp @@ -28,6 +28,8 @@ #include "util/wgt2allg.h" // exists() #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + using AGS::Shared::Stream; using AGS::Shared::TextStreamWriter; @@ -75,3 +77,5 @@ char *FileBasedAGSDebugger::GetNextMessage() { msg[fileSize] = 0; return msg; } + +} // namespace AGS3 diff --git a/engines/ags/engine/debugging/logfile.cpp b/engines/ags/engine/debugging/logfile.cpp index ab1639991afb..6e237e6f4847 100644 --- a/engines/ags/engine/debugging/logfile.cpp +++ b/engines/ags/engine/debugging/logfile.cpp @@ -25,7 +25,7 @@ #include "util/file.h" #include "util/stream.h" - +namespace AGS3 { namespace AGS { namespace Engine { @@ -40,7 +40,7 @@ void LogFile::PrintMessage(const DebugMessage &msg) { if (_filePath.IsEmpty()) return; _file.reset(File::OpenFile(_filePath, _openMode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, - Common::kFile_Write)); + Common::kFile_Write)); if (!_file) { Debug::Printf("Unable to write log to '%s'.", _filePath.GetCStr()); _filePath = ""; @@ -69,8 +69,8 @@ bool LogFile::OpenFile(const String &file_path, OpenMode open_mode) { return File::TestWriteFile(_filePath); } else { _file.reset(File::OpenFile(file_path, - open_mode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, - Common::kFile_Write)); + open_mode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, + Common::kFile_Write)); return _file.get() != nullptr; } } @@ -82,3 +82,4 @@ void LogFile::CloseFile() { } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/debugging/messagebuffer.cpp b/engines/ags/engine/debugging/messagebuffer.cpp index 3413aa5b261f..24fe07705d68 100644 --- a/engines/ags/engine/debugging/messagebuffer.cpp +++ b/engines/ags/engine/debugging/messagebuffer.cpp @@ -23,6 +23,7 @@ #include "debug/debugmanager.h" #include "debug/messagebuffer.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -51,7 +52,7 @@ void MessageBuffer::Send(const String &out_id) { if (_msgLost > 0) { DebugGroup gr = DbgMgr.GetGroup(kDbgGroup_Main); DbgMgr.SendMessage(out_id, DebugMessage(String::FromFormat("WARNING: output %s lost exceeding buffer: %u debug messages\n", out_id.GetCStr(), (unsigned)_msgLost), - gr.UID.ID, gr.OutputName, kDbgMsg_All)); + gr.UID.ID, gr.OutputName, kDbgMsg_All)); } for (std::vector::const_iterator it = _buffer.begin(); it != _buffer.end(); ++it) { DbgMgr.SendMessage(out_id, *it); @@ -65,3 +66,4 @@ void MessageBuffer::Flush(const String &out_id) { } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index d15a1335736a..7192299bae80 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -60,6 +60,8 @@ #include "ac/sys_events.h" // j for ags_iskeypressed #endif +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -76,7 +78,7 @@ int real_mouse_x = 0, real_mouse_y = 0; int boundx1 = 0, boundx2 = 99999, boundy1 = 0, boundy2 = 99999; int disable_mgetgraphpos = 0; char ignore_bounds = 0; -extern char alpha_blend_cursor ; +extern char alpha_blend_cursor; Bitmap *mousecurs[MAXCURSORS]; extern color palette[256]; extern volatile bool switched_away; @@ -106,8 +108,8 @@ void mgraphconfine(int x1, int y1, int x2, int y2) { Mouse::ControlRect = Rect(x1, y1, x2, y2); set_mouse_range(Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom); Debug::Printf("Mouse confined: (%d,%d)-(%d,%d) (%dx%d)", - Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom, - Mouse::ControlRect.GetWidth(), Mouse::ControlRect.GetHeight()); + Mouse::ControlRect.Left, Mouse::ControlRect.Top, Mouse::ControlRect.Right, Mouse::ControlRect.Bottom, + Mouse::ControlRect.GetWidth(), Mouse::ControlRect.GetHeight()); } void mgetgraphpos() { @@ -116,7 +118,7 @@ void mgetgraphpos() { // The cursor coordinates are provided from alternate source; // in this case we completely ignore actual cursor movement. if (!ignore_bounds && - (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { + (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { mousex = Math::Clamp(mousex, boundx1, boundx2); mousey = Math::Clamp(mousey, boundy1, boundy2); msetgraphpos(mousex, mousey); @@ -173,7 +175,7 @@ void mgetgraphpos() { mousey = real_mouse_y; if (!ignore_bounds && - (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { + (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { mousex = Math::Clamp(mousex, boundx1, boundx2); mousey = Math::Clamp(mousey, boundy1, boundy2); msetgraphpos(mousex, mousey); @@ -247,7 +249,7 @@ int mgetbutton() { poll_mouse(); int butis = mouse_b; - if ((butis > 0) & (butwas > 0)) + if ((butis > 0) &(butwas > 0)) return NONE; // don't allow holding button down if (butis & 1) { @@ -356,3 +358,5 @@ void Mouse::SetSpeed(float speed) { float Mouse::GetSpeed() { return SpeedVal; } + +} // namespace AGS3 diff --git a/engines/ags/engine/font/fonts_engine.cpp b/engines/ags/engine/font/fonts_engine.cpp index 1f773351cac7..2b77e3d496ab 100644 --- a/engines/ags/engine/font/fonts_engine.cpp +++ b/engines/ags/engine/font/fonts_engine.cpp @@ -29,6 +29,8 @@ #include #include "ac/gamesetupstruct.h" +namespace AGS3 { + extern int our_eip; extern GameSetupStruct game; @@ -43,3 +45,5 @@ void set_our_eip(int eip) { int get_our_eip() { return our_eip; } + +} // namespace AGS3 diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp index 8ba060cfa691..3df894addc59 100644 --- a/engines/ags/engine/game/game_init.cpp +++ b/engines/ags/engine/game/game_init.cpp @@ -51,15 +51,17 @@ #include "util/string_utils.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace Shared; using namespace Engine; extern GameSetupStruct game; extern int actSpsCount; extern Bitmap **actsps; -extern IDriverDependantBitmap * *actspsbmp; +extern IDriverDependantBitmap **actspsbmp; extern Bitmap **actspswb; -extern IDriverDependantBitmap * *actspswbbmp; +extern IDriverDependantBitmap **actspswbbmp; extern CachedActSpsData *actspswbcache; extern CharacterCache *charcache; @@ -75,7 +77,7 @@ extern CCAudioChannel ccDynamicAudio; extern CCAudioClip ccDynamicAudioClip; extern ScriptString myScriptStringImpl; extern ScriptObject scrObj[MAX_ROOM_OBJECTS]; -extern ScriptGUI *scrGui; +extern ScriptGUI *scrGui; extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS]; extern ScriptRegion scrRegion[MAX_ROOM_REGIONS]; extern ScriptInvItem scrInv[MAX_INV]; @@ -334,10 +336,10 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat if (data_ver >= kGameVersion_341) { // TODO: find a way to either automate this list of strings or make it more visible (shared & easier to find in engine code) // TODO: stack-allocated strings, here and in other similar places - const String scapi_names[kScriptAPI_Current + 1] = {"v3.2.1", "v3.3.0", "v3.3.4", "v3.3.5", "v3.4.0", "v3.4.1", "v3.5.0", "v3.5.0.7"}; + const String scapi_names[kScriptAPI_Current + 1] = { "v3.2.1", "v3.3.0", "v3.3.4", "v3.3.5", "v3.4.0", "v3.4.1", "v3.5.0", "v3.5.0.7" }; Debug::Printf(kDbgMsg_Info, "Requested script API: %s (%d), compat level: %s (%d)", - base_api >= 0 && base_api <= kScriptAPI_Current ? scapi_names[base_api].GetCStr() : "unknown", base_api, - compat_api >= 0 && compat_api <= kScriptAPI_Current ? scapi_names[compat_api].GetCStr() : "unknown", compat_api); + base_api >= 0 && base_api <= kScriptAPI_Current ? scapi_names[base_api].GetCStr() : "unknown", base_api, + compat_api >= 0 && compat_api <= kScriptAPI_Current ? scapi_names[compat_api].GetCStr() : "unknown", compat_api); } // If the game was compiled using unsupported version of the script API, // we warn about potential incompatibilities but proceed further. @@ -450,3 +452,4 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index 693794a957a4..1b55a38210d0 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -62,6 +62,8 @@ #include "util/string_utils.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace Shared; using namespace Engine; @@ -82,7 +84,7 @@ namespace AGS { namespace Engine { const String SavegameSource::LegacySignature = "Adventure Game Studio saved game"; -const String SavegameSource::Signature = "Adventure Game Studio saved game v2"; +const String SavegameSource::Signature = "Adventure Game Studio saved game v2"; SavegameSource::SavegameSource() : Version(kSvgVersion_Undefined) { @@ -178,7 +180,7 @@ HSaveError ReadDescription(Stream *in, SavegameVersion &svg_ver, SavegameDescrip svg_ver = (SavegameVersion)in->ReadInt32(); if (svg_ver < kSvgVersion_LowestSupported || svg_ver > kSvgVersion_Current) return new SavegameError(kSvgErr_FormatVersionNotSupported, - String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); + String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); // Enviroment information if (elems & kSvgDesc_EnvInfo) { @@ -223,9 +225,9 @@ HSaveError ReadDescription_v321(Stream *in, SavegameVersion &svg_ver, SavegameDe // Check saved game format version if (svg_ver < kSvgVersion_LowestSupported || - svg_ver > kSvgVersion_Current) { + svg_ver > kSvgVersion_Current) { return new SavegameError(kSvgErr_FormatVersionNotSupported, - String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); + String::FromFormat("Required: %d, supported: %d - %d.", svg_ver, kSvgVersion_LowestSupported, kSvgVersion_Current)); } if (elems & kSvgDesc_UserImage) @@ -236,10 +238,10 @@ HSaveError ReadDescription_v321(Stream *in, SavegameVersion &svg_ver, SavegameDe String version_str = String::FromStream(in); Version eng_version(version_str); if (eng_version > EngineVersion || - eng_version < SavedgameLowestBackwardCompatVersion) { + eng_version < SavedgameLowestBackwardCompatVersion) { // Engine version is either non-forward or non-backward compatible return new SavegameError(kSvgErr_IncompatibleEngine, - String::FromFormat("Required: %s, supported: %s - %s.", eng_version.LongString.GetCStr(), SavedgameLowestBackwardCompatVersion.LongString.GetCStr(), EngineVersion.LongString.GetCStr())); + String::FromFormat("Required: %s, supported: %s - %s.", eng_version.LongString.GetCStr(), SavedgameLowestBackwardCompatVersion.LongString.GetCStr(), EngineVersion.LongString.GetCStr())); } if (elems & kSvgDesc_EnvInfo) { desc.MainDataFilename.Read(in); @@ -457,19 +459,19 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) if (create_global_script()) { return new SavegameError(kSvgErr_GameObjectInitFailed, - String::FromFormat("Unable to recreate global script: %s", ccErrorString.GetCStr())); + String::FromFormat("Unable to recreate global script: %s", ccErrorString.GetCStr())); } // read the global data into the newly created script if (r_data.GlobalScript.Data.get()) memcpy(gameinst->globaldata, r_data.GlobalScript.Data.get(), - Math::Min((size_t)gameinst->globaldatasize, r_data.GlobalScript.Len)); + Math::Min((size_t)gameinst->globaldatasize, r_data.GlobalScript.Len)); // restore the script module data for (int i = 0; i < numScriptModules; ++i) { if (r_data.ScriptModules[i].Data.get()) memcpy(moduleInst[i]->globaldata, r_data.ScriptModules[i].Data.get(), - Math::Min((size_t)moduleInst[i]->globaldatasize, r_data.ScriptModules[i].Len)); + Math::Min((size_t)moduleInst[i]->globaldatasize, r_data.ScriptModules[i].Len)); } setup_player_character(game.playercharacter); @@ -556,10 +558,10 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) continue; if ((size_t)chan_info.ClipID >= game.audioClips.size()) { return new SavegameError(kSvgErr_GameObjectInitFailed, - String::FromFormat("Invalid audio clip index: %d (clip count: %u).", chan_info.ClipID, game.audioClips.size())); + String::FromFormat("Invalid audio clip index: %d (clip count: %u).", chan_info.ClipID, game.audioClips.size())); } play_audio_clip_on_channel(i, &game.audioClips[chan_info.ClipID], - chan_info.Priority, chan_info.Repeat, chan_info.Pos); + chan_info.Priority, chan_info.Repeat, chan_info.Pos); auto *ch = lock.GetChannel(i); if (ch != nullptr) { @@ -629,7 +631,7 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) AudioChannelsLock lock; if ((crossFading > 0 && !lock.GetChannelIfPlaying(crossFading)) || - (crossFading <= 0 && !lock.GetChannelIfPlaying(SCHAN_MUSIC))) { + (crossFading <= 0 && !lock.GetChannelIfPlaying(SCHAN_MUSIC))) { current_music_type = 0; // playback failed, reset flag } } @@ -735,3 +737,4 @@ void SaveGameState(PStream out) { } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index b716e1db4d1c..c0bef7a568f9 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -60,6 +60,8 @@ #include "util/filestream.h" // TODO: needed only because plugins expect file handle #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace Shared; extern GameSetupStruct game; @@ -1261,3 +1263,4 @@ HSaveError WriteAllCommon(PStream out) { } // namespace SavegameBlocks } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp index 6bb62c595231..ddbed3d8be32 100644 --- a/engines/ags/engine/game/viewport.cpp +++ b/engines/ags/engine/game/viewport.cpp @@ -26,6 +26,8 @@ #include "game/roomstruct.h" #include "game/viewport.h" +namespace AGS3 { + using namespace AGS::Shared; extern RoomStruct thisroom; @@ -202,3 +204,5 @@ VpPoint Viewport::ScreenToRoom(int scrx, int scry, bool clip, bool convert_cam_t } return std::make_pair(p, _id); } + +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 406449cc23f4..5b275a592b98 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -35,6 +35,8 @@ #include "util/math.h" #include "ac/timer.h" +namespace AGS3 { + #if AGS_PLATFORM_OS_ANDROID #define glOrtho glOrthof @@ -1871,5 +1873,6 @@ OGLGfxFilter *OGLGraphicsFactory::CreateFilter(const String &id) { } // namespace OGL } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif // only on Windows, Android and iOS diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index 3ade7458002c..85b121ced9e1 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -37,6 +37,8 @@ #include "platform/base/agsplatformdriver.h" #include "ac/timer.h" +namespace AGS3 { + #if AGS_DDRAW_GAMMA_CONTROL // NOTE: this struct and variables are defined internally in Allegro typedef struct DDRAW_SURFACE { @@ -49,7 +51,7 @@ typedef struct DDRAW_SURFACE { } DDRAW_SURFACE; extern "C" extern LPDIRECTDRAW2 directdraw; -extern "C" DDRAW_SURFACE *gfx_directx_primary_surface; +extern "C" DDRAW_SURFACE * gfx_directx_primary_surface; #endif // AGS_DDRAW_GAMMA_CONTROL #ifndef AGS_NO_VIDEO_PLAYER @@ -116,8 +118,8 @@ bool ALSoftwareGraphicsDriver::IsModeSupported(const DisplayMode &mode) { // between loads of unsupported resolutions for (int i = 0; i < _gfxModeList->num_modes; i++) { if ((_gfxModeList->mode[i].width == mode.Width) && - (_gfxModeList->mode[i].height == mode.Height) && - (_gfxModeList->mode[i].bpp == mode.ColorDepth)) { + (_gfxModeList->mode[i].height == mode.Height) && + (_gfxModeList->mode[i].bpp == mode.ColorDepth)) { return true; } } @@ -211,8 +213,8 @@ bool ALSoftwareGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile ddrawCaps.dwSize = sizeof(ddrawCaps); IDirectDraw2_GetCaps(directdraw, &ddrawCaps, NULL); - if ((ddrawCaps.dwCaps2 & DDCAPS2_PRIMARYGAMMA) == 0) { } - else if (IDirectDrawSurface2_QueryInterface(gfx_directx_primary_surface->id, IID_IDirectDrawGammaControl, (void **)&dxGammaControl) == 0) { + if ((ddrawCaps.dwCaps2 & DDCAPS2_PRIMARYGAMMA) == 0) { + } else if (IDirectDrawSurface2_QueryInterface(gfx_directx_primary_surface->id, IID_IDirectDrawGammaControl, (void **)&dxGammaControl) == 0) { dxGammaControl->GetGammaRamp(0, &defaultGammaRamp); } } @@ -438,7 +440,7 @@ void ALSoftwareGraphicsDriver::RenderToBackBuffer() { RenderSpriteBatch(batch, surface, transform.X, transform.Y); if (!batch.IsVirtualScreen) virtualScreen->StretchBlt(surface, RectWH(view_offx, view_offy, viewport.GetWidth(), viewport.GetHeight()), - batch.Opaque ? kBitmap_Copy : kBitmap_Transparency); + batch.Opaque ? kBitmap_Copy : kBitmap_Transparency); } else { RenderSpriteBatch(batch, virtualScreen, view_offx + transform.X, view_offy + transform.Y); } @@ -468,9 +470,10 @@ void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Com int drawAtX = drawlist[i].x + surf_offx; int drawAtY = drawlist[i].y + surf_offy; - if (bitmap->_transparency >= 255) {} // fully transparent, do nothing - else if ((bitmap->_opaque) && (bitmap->_bmp == surface) && (bitmap->_transparency == 0)) {} - else if (bitmap->_opaque) { + if (bitmap->_transparency >= 255) { + } // fully transparent, do nothing + else if ((bitmap->_opaque) && (bitmap->_bmp == surface) && (bitmap->_transparency == 0)) { + } else if (bitmap->_opaque) { surface->Blit(bitmap->_bmp, 0, 0, drawAtX, drawAtY, bitmap->_bmp->GetWidth(), bitmap->_bmp->GetHeight()); // TODO: we need to also support non-masked translucent blend, but... // Allegro 4 **does not have such function ready** :( (only masked blends, where it skips magenta pixels); @@ -486,23 +489,23 @@ void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Com } else { // here _transparency is used as alpha (between 1 and 254), but 0 means opaque! GfxUtil::DrawSpriteWithTransparency(surface, bitmap->_bmp, drawAtX, drawAtY, - bitmap->_transparency ? bitmap->_transparency : 255); + bitmap->_transparency ? bitmap->_transparency : 255); } } // NOTE: following is experimental tint code (currently unused) /* This alternate method gives the correct (D3D-style) result, but is just too slow! - if ((_spareTintingScreen != NULL) && - ((_spareTintingScreen->GetWidth() != surface->GetWidth()) || (_spareTintingScreen->GetHeight() != surface->GetHeight()))) - { - destroy_bitmap(_spareTintingScreen); - _spareTintingScreen = NULL; - } - if (_spareTintingScreen == NULL) - { - _spareTintingScreen = BitmapHelper::CreateBitmap_(GetColorDepth(surface), surface->GetWidth(), surface->GetHeight()); - } - tint_image(surface, _spareTintingScreen, _tint_red, _tint_green, _tint_blue, 100, 255); - Blit(_spareTintingScreen, surface, 0, 0, 0, 0, _spareTintingScreen->GetWidth(), _spareTintingScreen->GetHeight());*/ + if ((_spareTintingScreen != NULL) && + ((_spareTintingScreen->GetWidth() != surface->GetWidth()) || (_spareTintingScreen->GetHeight() != surface->GetHeight()))) + { + destroy_bitmap(_spareTintingScreen); + _spareTintingScreen = NULL; + } + if (_spareTintingScreen == NULL) + { + _spareTintingScreen = BitmapHelper::CreateBitmap_(GetColorDepth(surface), surface->GetWidth(), surface->GetHeight()); + } + tint_image(surface, _spareTintingScreen, _tint_red, _tint_green, _tint_blue, 100, 255); + Blit(_spareTintingScreen, surface, 0, 0, 0, 0, _spareTintingScreen->GetWidth(), _spareTintingScreen->GetHeight());*/ } void ALSoftwareGraphicsDriver::Render(int xoff, int yoff, GlobalFlipType flip) { @@ -561,11 +564,11 @@ bool ALSoftwareGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bo } /** - fade.c - High Color Fading Routines + fade.c - High Color Fading Routines - Last Revision: 21 June, 2002 + Last Revision: 21 June, 2002 - Author: Matthew Leverton + Author: Matthew Leverton **/ void ALSoftwareGraphicsDriver::highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { Bitmap *bmp_orig = vs; @@ -703,7 +706,7 @@ void ALSoftwareGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int del boxhit += yspeed; int vcentre = _srcRect.GetHeight() / 2; bmp_orig->FillRect(Rect(_srcRect.GetWidth() / 2 - boxwid / 2, vcentre - boxhit / 2, - _srcRect.GetWidth() / 2 + boxwid / 2, vcentre + boxhit / 2), 0); + _srcRect.GetWidth() / 2 + boxwid / 2, vcentre + boxhit / 2), 0); bmp_buff->Fill(0); bmp_buff->Blit(bmp_orig); if (_drawPostScreenCallback) { @@ -808,3 +811,4 @@ AllegroGfxFilter *ALSWGraphicsFactory::CreateFilter(const String &id) { } // namespace ALSW } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/blender.cpp b/engines/ags/engine/gfx/blender.cpp index 8d802b5462ef..736768836e37 100644 --- a/engines/ags/engine/gfx/blender.cpp +++ b/engines/ags/engine/gfx/blender.cpp @@ -24,6 +24,8 @@ #include "gfx/blender.h" #include "util/wgt2allg.h" +namespace AGS3 { + extern "C" { // Fallback routine for when we don't have anything better to do. unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n); @@ -186,25 +188,25 @@ FORCEINLINE unsigned long argb2argb_blend_core(unsigned long src_col, unsigned l dst_alpha++; // dst_g now contains the green hue from destination color - dst_g = (dst_col & 0x00FF00) * dst_alpha / 256; + dst_g = (dst_col & 0x00FF00) * dst_alpha / 256; // dst_col now contains the red & blue hues from destination color dst_col = (dst_col & 0xFF00FF) * dst_alpha / 256; // res_g now contains the green hue of the pre-final color - dst_g = (((src_col & 0x00FF00) - (dst_g & 0x00FF00)) * src_alpha / 256 + dst_g) & 0x00FF00; + dst_g = (((src_col & 0x00FF00) - (dst_g & 0x00FF00)) * src_alpha / 256 + dst_g) & 0x00FF00; // res_rb now contains the red & blue hues of the pre-final color dst_col = (((src_col & 0xFF00FF) - (dst_col & 0xFF00FF)) * src_alpha / 256 + dst_col) & 0xFF00FF; // dst_alpha now contains the final alpha // we assume that final alpha will never be zero - dst_alpha = 256 - (256 - src_alpha) * (256 - dst_alpha) / 256; + dst_alpha = 256 - (256 - src_alpha) * (256 - dst_alpha) / 256; // src_alpha is now the final alpha factor made for being multiplied by, // instead of divided by: this makes it possible to use it in faster // calculation below - src_alpha = /* 256 * 256 == */ 0x10000 / dst_alpha; + src_alpha = /* 256 * 256 == */ 0x10000 / dst_alpha; // setting up final color hues - dst_g = (dst_g * src_alpha / 256) & 0x00FF00; + dst_g = (dst_g * src_alpha / 256) & 0x00FF00; dst_col = (dst_col * src_alpha / 256) & 0xFF00FF; return dst_col | dst_g | (--dst_alpha << 24); } @@ -284,6 +286,8 @@ void set_opaque_alpha_blender() { void set_argb2any_blender() { set_blender_mode_ex(_blender_black, _blender_black, _blender_black, _argb2argb_blender, - _blender_alpha15, skiptranspixels_blender_alpha16, _blender_alpha24, - 0, 0, 0, 0xff); // TODO: do we need to support proper 15- and 24-bit here? + _blender_alpha15, skiptranspixels_blender_alpha16, _blender_alpha24, + 0, 0, 0, 0xff); // TODO: do we need to support proper 15- and 24-bit here? } + +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/color_engine.cpp b/engines/ags/engine/gfx/color_engine.cpp index 95f39dd88d2f..ae3ec5e1921c 100644 --- a/engines/ags/engine/gfx/color_engine.cpp +++ b/engines/ags/engine/gfx/color_engine.cpp @@ -31,6 +31,8 @@ #include "util/wgt2allg.h" #include "gfx/bitmap.h" +namespace AGS3 { + void __my_setcolor(int *ctset, int newcol, int wantColDep) { if (wantColDep == 8) ctset[0] = newcol; @@ -52,7 +54,7 @@ void __my_setcolor(int *ctset, int newcol, int wantColDep) { ctset[0] = newcol; } else { ctset[0] = makecol_depth(wantColDep, col_lookups[newcol] >> 16, - (col_lookups[newcol] >> 8) & 0x000ff, col_lookups[newcol] & 0x000ff); + (col_lookups[newcol] >> 8) & 0x000ff, col_lookups[newcol] & 0x000ff); // in case it's used on an alpha-channel sprite, make sure it's visible if (wantColDep > 16) @@ -63,3 +65,5 @@ void __my_setcolor(int *ctset, int newcol, int wantColDep) { //if (wantColDep >= 24) // ctset[0] |= 0x40000000; } + +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp index 314c2c6d8a80..dd309c0cefc4 100644 --- a/engines/ags/engine/gfx/gfx_util.cpp +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -24,6 +24,8 @@ #include "gfx/gfx_util.h" #include "gfx/blender.h" +namespace AGS3 { + // CHECKME: is this hack still relevant? #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID extern int psp_gfx_renderer; @@ -77,7 +79,7 @@ bool SetBlender(BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, in PfnBlenderCb blender; if (dst_has_alpha) blender = src_has_alpha ? set.AllAlpha : - (blend_alpha == 0xFF ? set.OpaqueToAlphaNoTrans : set.OpaqueToAlpha); + (blend_alpha == 0xFF ? set.OpaqueToAlphaNoTrans : set.OpaqueToAlpha); else blender = src_has_alpha ? set.AlphaToOpaque : set.AllOpaque; @@ -89,14 +91,14 @@ bool SetBlender(BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, in } void DrawSpriteBlend(Bitmap *ds, const Point &ds_at, Bitmap *sprite, - BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) { + BlendMode blend_mode, bool dst_has_alpha, bool src_has_alpha, int blend_alpha) { if (blend_alpha <= 0) return; // do not draw 100% transparent image if (// support only 32-bit blending at the moment - ds->GetColorDepth() == 32 && sprite->GetColorDepth() == 32 && - // set blenders if applicable and tell if succeeded - SetBlender(blend_mode, dst_has_alpha, src_has_alpha, blend_alpha)) { + ds->GetColorDepth() == 32 && sprite->GetColorDepth() == 32 && + // set blenders if applicable and tell if succeeded + SetBlender(blend_mode, dst_has_alpha, src_has_alpha, blend_alpha)) { ds->TransBlendBlt(sprite, ds_at.X, ds_at.Y); } else { GfxUtil::DrawSpriteWithTransparency(ds, sprite, ds_at.X, ds_at.Y, blend_alpha); @@ -110,14 +112,14 @@ void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int al } int surface_depth = ds->GetColorDepth(); - int sprite_depth = sprite->GetColorDepth(); + int sprite_depth = sprite->GetColorDepth(); if (sprite_depth < surface_depth - // CHECKME: what is the purpose of this hack and is this still relevant? + // CHECKME: what is the purpose of this hack and is this still relevant? #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID - || (ds->GetBPP() < surface_depth && psp_gfx_renderer > 0) // Fix for corrupted speechbox outlines with the OGL driver + || (ds->GetBPP() < surface_depth && psp_gfx_renderer > 0) // Fix for corrupted speechbox outlines with the OGL driver #endif - ) { + ) { // If sprite is lower color depth than destination surface, e.g. // 8-bit sprites drawn on 16/32-bit surfaces. if (sprite_depth == 8 && surface_depth >= 24) { @@ -138,7 +140,7 @@ void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int al for (int scan_y = 0; scan_y < hctemp.GetHeight(); ++scan_y) { // we know this must be 1 bpp source and 2 bpp pixel destination const uint8_t *src_scanline = sprite->GetScanLine(scan_y); - uint16_t *dst_scanline = (uint16_t *)hctemp.GetScanLineForWriting(scan_y); + uint16_t *dst_scanline = (uint16_t *)hctemp.GetScanLineForWriting(scan_y); for (int scan_x = 0; scan_x < hctemp.GetWidth(); ++scan_x) { if (src_scanline[scan_x] == 0) { dst_scanline[scan_x] = mask_color; @@ -167,3 +169,4 @@ void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int al } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index 1a10be6b83e3..7de8c33ed29e 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -27,6 +27,8 @@ #include "gfx/gfxdriverbase.h" #include "gfx/gfx_util.h" +namespace AGS3 { + using namespace AGS::Shared; namespace AGS { @@ -68,7 +70,7 @@ Rect GraphicsDriverBase::GetRenderDestination() const { } void GraphicsDriverBase::BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, - const Point offset, GlobalFlipType flip, PBitmap surface) { + const Point offset, GlobalFlipType flip, PBitmap surface) { _actSpriteBatch++; _spriteBatchDesc.push_back(SpriteBatchDesc(viewport, transform, offset, flip, surface)); InitSpriteBatch(_actSpriteBatch, _spriteBatchDesc[_actSpriteBatch]); @@ -283,14 +285,14 @@ __inline void get_pixel_if_not_transparent32(unsigned int *pixel, unsigned int * void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, - char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering) { + char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering) { const int src_depth = bitmap->GetColorDepth(); bool lastPixelWasTransparent = false; for (int y = 0; y < tile->height; y++) { lastPixelWasTransparent = false; const uint8_t *scanline_before = bitmap->GetScanLine(y + tile->y - 1); - const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); - const uint8_t *scanline_after = bitmap->GetScanLine(y + tile->y + 1); + const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); + const uint8_t *scanline_after = bitmap->GetScanLine(y + tile->y + 1); unsigned int *memPtrLong = (unsigned int *)dst_ptr; for (int x = 0; x < tile->width; x++) { @@ -401,7 +403,7 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo } void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, - char *dst_ptr, const int dst_pitch) { + char *dst_ptr, const int dst_pitch) { const int src_depth = bitmap->GetColorDepth(); for (int y = 0; y < tile->height; y++) { const uint8_t *scanline_at = bitmap->GetScanLine(y + tile->y); @@ -430,3 +432,4 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, con } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp index 4147c8d9475d..d2469785df1f 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.cpp +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -42,6 +42,7 @@ #include "main/main_allegro.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -72,3 +73,4 @@ IGfxDriverFactory *GetGfxDriverFactory(const String id) { } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp index c09ee706e872..bdbde84b7526 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp @@ -28,6 +28,7 @@ #include #endif +namespace AGS3 { namespace AGS { namespace Engine { namespace D3D { @@ -53,3 +54,4 @@ bool AAD3DGfxFilter::NeedToColourEdgeLines() { } // namespace D3D } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp index cb34a0ae49e3..70d5e869a341 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp @@ -27,6 +27,7 @@ #include "gfx/gfxfilter_aaogl.h" #include "ogl_headers.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace OGL { @@ -49,5 +50,6 @@ const GfxFilterInfo &AAOGLGfxFilter::GetInfo() const { } // namespace OGL } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif // only on Windows, Android and iOS diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index 94177683c219..8385ef783d58 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -22,6 +22,7 @@ #include "gfx/gfxfilter_allegro.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace ALSW { @@ -135,8 +136,8 @@ void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_w // so copy the screen to a buffer first. realScreenSizedBuffer->Blit(realScreen, 0, 0); copyBitmap->StretchBlt(realScreenSizedBuffer, - _dstRect, - RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); + _dstRect, + RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); } } else if (!lastBlitFrom) copyBitmap->Fill(0); @@ -144,8 +145,8 @@ void AllegroGfxFilter::GetCopyOfScreenIntoBitmap(Bitmap *copyBitmap, bool copy_w copyBitmap->Blit(realScreen, lastBlitX, lastBlitY, 0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight()); else { copyBitmap->StretchBlt(lastBlitFrom, - RectWH(0, 0, lastBlitFrom->GetWidth(), lastBlitFrom->GetHeight()), - RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); + RectWH(0, 0, lastBlitFrom->GetWidth(), lastBlitFrom->GetHeight()), + RectWH(0, 0, copyBitmap->GetWidth(), copyBitmap->GetHeight())); } } @@ -157,3 +158,4 @@ Bitmap *AllegroGfxFilter::PreRenderPass(Bitmap *toRender) { } // namespace ALSW } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.cpp b/engines/ags/engine/gfx/gfxfilter_d3d.cpp index 4ed4890b087a..8156af57eefb 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_d3d.cpp @@ -26,6 +26,7 @@ #include #endif +namespace AGS3 { namespace AGS { namespace Engine { namespace D3D { @@ -51,3 +52,4 @@ bool D3DGfxFilter::NeedToColourEdgeLines() { } // namespace D3D } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp index 9bee9d28af3e..1974779a7c94 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.cpp +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -24,6 +24,7 @@ #include "gfx/gfxfilter_hqx.h" #include "gfx/hq2x3x.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace ALSW { @@ -79,7 +80,7 @@ Bitmap *HqxGfxFilter::ShutdownAndReturnRealScreen() { Bitmap *HqxGfxFilter::PreRenderPass(Bitmap *toRender) { _hqxScalingBuffer->Acquire(); _pfnHqx(toRender->GetDataForWriting(), _hqxScalingBuffer->GetDataForWriting(), - toRender->GetWidth(), toRender->GetHeight(), _hqxScalingBuffer->GetLineLength()); + toRender->GetWidth(), toRender->GetHeight(), _hqxScalingBuffer->GetLineLength()); _hqxScalingBuffer->Release(); return _hqxScalingBuffer; } @@ -87,3 +88,4 @@ Bitmap *HqxGfxFilter::PreRenderPass(Bitmap *toRender) { } // namespace ALSW } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.cpp b/engines/ags/engine/gfx/gfxfilter_ogl.cpp index 7ca95acbb9d0..9d480c0de5d3 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_ogl.cpp @@ -27,6 +27,7 @@ #include "gfx/gfxfilter_ogl.h" #include "ogl_headers.h" +namespace AGS3 { namespace AGS { namespace Engine { namespace OGL { @@ -49,5 +50,6 @@ const GfxFilterInfo &OGLGfxFilter::GetInfo() const { } // namespace OGL } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif // only on Windows, Android and iOS diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.cpp b/engines/ags/engine/gfx/gfxfilter_scaling.cpp index 455015105bb9..7b013e1309aa 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.cpp +++ b/engines/ags/engine/gfx/gfxfilter_scaling.cpp @@ -22,6 +22,7 @@ #include "gfx/gfxfilter_scaling.h" +namespace AGS3 { namespace AGS { namespace Engine { @@ -47,3 +48,4 @@ Rect ScalingGfxFilter::GetDestination() const { } // namespace Engine } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gui/animatingguibutton.cpp b/engines/ags/engine/gui/animatingguibutton.cpp index a5fcb1aa0571..bac2621ab418 100644 --- a/engines/ags/engine/gui/animatingguibutton.cpp +++ b/engines/ags/engine/gui/animatingguibutton.cpp @@ -23,6 +23,8 @@ #include "gui/animatingguibutton.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; void AnimatingGUIButton::ReadFromFile(Stream *in) { @@ -48,3 +50,5 @@ void AnimatingGUIButton::WriteToFile(Stream *out) { out->WriteInt16(repeat); out->WriteInt16(wait); } + +} // namespace AGS3 diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index 6c6cac7523d4..9dc7a079d3ea 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -43,6 +43,8 @@ #include "platform/base/agsplatformdriver.h" #include "ac/timer.h" +namespace AGS3 { + using AGS::Shared::Bitmap; namespace BitmapHelper = AGS::Shared::BitmapHelper; @@ -165,7 +167,7 @@ int CSCIWaitMessage(CSCIMessage *cscim) { } else if (keywas == 27) { cscim->id = finddefaultcontrol(CNF_CANCEL); cscim->code = CM_COMMAND; - } else if ((keywas < 32) && (keywas != 8)) ; + } else if ((keywas < 32) && (keywas != 8)); else if ((keywas >= 372) & (keywas <= 381) & (finddefaultcontrol(CNT_LISTBOX) >= 0)) vobjs[finddefaultcontrol(CNT_LISTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0); else if (finddefaultcontrol(CNT_TEXTBOX) >= 0) @@ -306,3 +308,5 @@ int finddefaultcontrol(int flagmask) { int GetBaseWidth() { return play.GetUIViewport().GetWidth(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp index e19c753eeab8..c5a7e1b6509b 100644 --- a/engines/ags/engine/gui/gui_engine.cpp +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -44,6 +44,8 @@ #include "gfx/bitmap.h" #include "gfx/blender.h" +namespace AGS3 { + using namespace AGS::Shared; // For engine these are defined in ac.cpp @@ -68,10 +70,10 @@ bool GUIMain::HasAlphaChannel() const { } // transparent background, enable alpha blending return game.GetColorDepth() >= 24 && - // transparent background have alpha channel only since 3.2.0; - // "classic" gui rendering mode historically had non-alpha transparent backgrounds - // (3.2.0 broke the compatibility, now we restore it) - loaded_game_file_version >= kGameVersion_320 && game.options[OPT_NEWGUIALPHA] != kGuiAlphaRender_Legacy; + // transparent background have alpha channel only since 3.2.0; + // "classic" gui rendering mode historically had non-alpha transparent backgrounds + // (3.2.0 broke the compatibility, now we restore it) + loaded_game_file_version >= kGameVersion_320 && game.options[OPT_NEWGUIALPHA] != kGuiAlphaRender_Legacy; } //============================================================================= @@ -158,3 +160,4 @@ void GUIButton::PrepareTextToDraw() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index cc9b7c977aae..b793a689ca29 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -34,6 +34,8 @@ #include "gfx/graphicsdriver.h" #include "debug/debug_log.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -113,10 +115,10 @@ int loadgamedialog() { int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); int ctrlok = - CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, get_global_message(MSG_RESTORE)); + CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 135, 5, 60, 10, get_global_message(MSG_RESTORE)); int ctrlcancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, - get_global_message(MSG_CANCEL)); + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, + get_global_message(MSG_CANCEL)); int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 30, 120, 80, nullptr); int ctrltex1 = CSCICreateControl(CNT_LABEL, 10, 5, 120, 0, get_global_message(MSG_SELECTLOAD)); CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); @@ -168,8 +170,8 @@ int savegamedialog() { int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); int ctrlcancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, - get_global_message(MSG_CANCEL)); + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 135, 5 + buttonhit, 60, 10, + get_global_message(MSG_CANCEL)); int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 120, 80, nullptr); int ctrltbox = 0; @@ -210,17 +212,17 @@ int savegamedialog() { if (toomanygames) { int nwhand = CSCIDrawWindow(boxleft + 5, boxtop + 20, 190, 65); int lbl1 = - CSCICreateControl(CNT_LABEL, 15, 5, 160, 0, get_global_message(MSG_REPLACEWITH1)); + CSCICreateControl(CNT_LABEL, 15, 5, 160, 0, get_global_message(MSG_REPLACEWITH1)); int lbl2 = CSCICreateControl(CNT_LABEL, 25, 14, 160, 0, bufTemp); int lbl3 = - CSCICreateControl(CNT_LABEL, 15, 25, 160, 0, get_global_message(MSG_REPLACEWITH2)); + CSCICreateControl(CNT_LABEL, 15, 25, 160, 0, get_global_message(MSG_REPLACEWITH2)); int txt1 = CSCICreateControl(CNT_TEXTBOX, 15, 35, 160, 0, bufTemp); int btnOk = - CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 25, 50, 60, 10, - get_global_message(MSG_REPLACE)); + CSCICreateControl(CNT_PUSHBUTTON | CNF_DEFAULT, 25, 50, 60, 10, + get_global_message(MSG_REPLACE)); int btnCancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 95, 50, 60, 10, - get_global_message(MSG_CANCEL)); + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 95, 50, 60, 10, + get_global_message(MSG_CANCEL)); CSCIMessage cmes; do { @@ -413,7 +415,7 @@ int roomSelectorWindow(int currentRoom, int numRooms, int *roomNumbers, char **r int handl = CSCIDrawWindow(boxleft, boxtop, wnd_width, wnd_height); int ctrllist = CSCICreateControl(CNT_LISTBOX, 10, 40, 220, 100, nullptr); int ctrlcancel = - CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 80, 145, 60, 10, "Cancel"); + CSCICreateControl(CNT_PUSHBUTTON | CNF_CANCEL, 80, 145, 60, 10, "Cancel"); CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box for (int aa = 0; aa < numRooms; aa++) { @@ -510,3 +512,5 @@ int quitdialog() { strcpy(playbut, get_global_message(MSG_PLAYBUTTON)); return myscimessagebox(get_global_message(MSG_QUITDIALOG), quitbut, playbut); } + +} // namespace AGS3 diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp index ce173d589d14..74bd80ab2ac4 100644 --- a/engines/ags/engine/gui/mylabel.cpp +++ b/engines/ags/engine/gui/mylabel.cpp @@ -29,6 +29,8 @@ #include "gui/mylabel.h" #include "gui/guidialoginternaldefs.h" +namespace AGS3 { + using namespace Shared; extern GameSetup usetup; @@ -64,3 +66,5 @@ int MyLabel::pressedon(int mousex, int mousey) { int MyLabel::processmessage(int mcode, int wParam, long lParam) { return -1; // doesn't support messages } + +} // namespace AGS3 diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index 95a1f2d2ee6a..37d24a4dbea7 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -30,6 +30,8 @@ #include "gui/guidialoginternaldefs.h" #include "gui/mylistbox.h" +namespace AGS3 { + using AGS::Shared::Bitmap; extern GameSetup usetup; @@ -112,7 +114,7 @@ int MyListBox::pressedon(int mousex, int mousey) { if (mousex > x + wid - ARROWWIDTH) { if ((mousey - y < hit / 2) & (topitem > 0)) topitem--; - else if ((mousey - y > hit / 2) & (topitem + numonscreen < items)) + else if ((mousey - y > hit / 2) &(topitem + numonscreen < items)) topitem++; } else { @@ -122,7 +124,7 @@ int MyListBox::pressedon(int mousex, int mousey) { } -// ags_domouse(DOMOUSE_DISABLE); + // ags_domouse(DOMOUSE_DISABLE); draw(get_gui_screen()); // ags_domouse(DOMOUSE_ENABLE); smcode = CM_SELCHANGE; @@ -195,3 +197,5 @@ int MyListBox::processmessage(int mcode, int wParam, long lParam) { return 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index 8aa7ff69db7a..77e68a829b46 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -33,6 +33,8 @@ #include "platform/base/agsplatformdriver.h" #include "ac/timer.h" +namespace AGS3 { + using AGS::Shared::Bitmap; extern int windowbackgroundcolor, pushbuttondarkcolor; @@ -109,3 +111,5 @@ int MyPushButton::pressedon(int mousex, int mousey) { int MyPushButton::processmessage(int mcode, int wParam, long lParam) { return -1; // doesn't support messages } + +} // namespace AGS3 diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp index fe545e917a3d..74e740bc84bb 100644 --- a/engines/ags/engine/gui/mytextbox.cpp +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -27,6 +27,8 @@ #include "gui/guidialoginternaldefs.h" #include "gfx/bitmap.h" +namespace AGS3 { + using AGS::Shared::Bitmap; extern GameSetup usetup; @@ -90,3 +92,5 @@ int MyTextBox::processmessage(int mcode, int wParam, long lParam) { return 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp index 80516ce6f53c..cdc052d11489 100644 --- a/engines/ags/engine/gui/newcontrol.cpp +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -24,6 +24,8 @@ #include "gui/guidialog.h" #include "gui/guidialoginternaldefs.h" +namespace AGS3 { + extern int topwindowhandle; NewControl::NewControl(int xx, int yy, int wi, int hi) { @@ -51,7 +53,7 @@ int NewControl::mouseisinarea(int mousex, int mousey) { if (topwindowhandle != wlevel) return 0; - if ((mousex > x) & (mousex < x + wid) & (mousey > y) & (mousey < y + hit)) + if ((mousex > x) &(mousex < x + wid) &(mousey > y) &(mousey < y + hit)) return 1; return 0; @@ -69,3 +71,5 @@ void NewControl::drawandmouse() { draw(get_gui_screen()); // ags_domouse(DOMOUSE_ENABLE); } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 9a6c5e493697..58949bf10aad 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -45,6 +45,7 @@ #include "util/string_utils.h" #include "media/audio/audio_system.h" +namespace AGS3 { using namespace AGS::Shared; using namespace AGS::Engine; @@ -159,7 +160,7 @@ bool parse_legacy_frame_config(const String &scaling_option, String &filter_id, filter_id = legacy_filters[i].CurrentName; frame.ScaleDef = legacy_filters[i].Scaling == 0 ? kFrame_MaxRound : kFrame_IntScale; frame.ScaleFactor = legacy_filters[i].Scaling >= 0 ? legacy_filters[i].Scaling : - scaling_option.Mid(legacy_filters[i].LegacyName.GetLength()).ToInt(); + scaling_option.Mid(legacy_filters[i].LegacyName.GetLength()).ToInt(); return true; } } @@ -197,17 +198,17 @@ int convert_fp_to_scaling(uint32_t scaling) { AlIDStr AlIDToChars(int al_id) { if (al_id == 0) - return AlIDStr {{ 'N', 'O', 'N', 'E', '\0' }}; + return AlIDStr{ { 'N', 'O', 'N', 'E', '\0' } }; else if (al_id == -1) - return AlIDStr {{ 'A', 'U', 'T', 'O', '\0' }}; + return AlIDStr{ { 'A', 'U', 'T', 'O', '\0' } }; else - return AlIDStr {{ + return AlIDStr{ { static_cast((al_id >> 24) & 0xFF), static_cast((al_id >> 16) & 0xFF), static_cast((al_id >> 8) & 0xFF), static_cast((al_id) & 0xFF), '\0' - }}; + } }; } AlIDStr AlIDToChars(const String &s) { @@ -364,8 +365,8 @@ void read_legacy_graphics_config(const ConfigTree &cfg) { // AGS 3.2.1 and 3.3.0 aspect ratio preferences if (!usetup.Screen.DisplayMode.Windowed) { usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = - (INIreadint(cfg, "misc", "sideborders") > 0 || INIreadint(cfg, "misc", "forceletterbox") > 0 || - INIreadint(cfg, "misc", "prefer_sideborders") > 0 || INIreadint(cfg, "misc", "prefer_letterbox") > 0); + (INIreadint(cfg, "misc", "sideborders") > 0 || INIreadint(cfg, "misc", "forceletterbox") > 0 || + INIreadint(cfg, "misc", "prefer_sideborders") > 0 || INIreadint(cfg, "misc", "prefer_letterbox") > 0); } } @@ -478,7 +479,7 @@ void apply_config(const ConfigTree &cfg) { } usetup.Screen.DisplayMode.ScreenSize.Size = Size(INIreadint(cfg, "graphics", "screen_width"), - INIreadint(cfg, "graphics", "screen_height")); + INIreadint(cfg, "graphics", "screen_height")); usetup.Screen.DisplayMode.ScreenSize.MatchDeviceRatio = INIreadint(cfg, "graphics", "match_device_ratio", 1) != 0; // TODO: move to config overrides (replace values during config load) #if AGS_PLATFORM_OS_MACOS @@ -609,3 +610,5 @@ void save_config_file() { if (!cfg_file.IsEmpty()) IniUtil::Merge(cfg_file, cfg); } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 89f3d3bf5820..31cf7bca1a45 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -79,6 +79,8 @@ #include "util/misc.h" #include "util/path.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -1541,3 +1543,5 @@ const char *get_engine_version() { void engine_set_pre_init_callback(t_engine_pre_init_callback callback) { engine_pre_init_callback = callback; } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp index 22ae40663a79..9168a24f7dac 100644 --- a/engines/ags/engine/main/engine_setup.cpp +++ b/engines/ags/engine/main/engine_setup.cpp @@ -44,6 +44,8 @@ #include "media/video/video.h" #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -131,7 +133,7 @@ void engine_init_resolution_settings(const Size game_size) { usetup.textheight = getfontheight_outlined(0) + 1; Debug::Printf(kDbgMsg_Info, "Game native resolution: %d x %d (%d bit)%s", game_size.Width, game_size.Height, game.color_depth * 8, - game.IsLegacyLetterbox() ? " letterbox-by-design" : ""); + game.IsLegacyLetterbox() ? " letterbox-by-design" : ""); convert_gui_to_game_resolution(loaded_game_file_version); convert_objects_to_data_resolution(loaded_game_file_version); @@ -268,12 +270,12 @@ void engine_post_gfxmode_mouse_setup(const DisplayMode &dm, const Size &init_des Size cur_desktop; if (get_desktop_resolution(&cur_desktop.Width, &cur_desktop.Height) == 0) Mouse::SetSpeedUnit(Math::Max((float)cur_desktop.Width / (float)init_desktop.Width, - (float)cur_desktop.Height / (float)init_desktop.Height)); + (float)cur_desktop.Height / (float)init_desktop.Height)); } Mouse_EnableControl(usetup.mouse_ctrl_enabled); Debug::Printf(kDbgMsg_Info, "Mouse control: %s, base: %f, speed: %f", Mouse::IsControlEnabled() ? "on" : "off", - Mouse::GetSpeedUnit(), Mouse::GetSpeed()); + Mouse::GetSpeedUnit(), Mouse::GetSpeed()); on_coordinates_scaling_changed(); @@ -340,3 +342,5 @@ void on_coordinates_scaling_changed() { else Mouse::SetMoveLimit(Rect(play.mboundx1, play.mboundy1, play.mboundx2, play.mboundy2)); } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp index 857f80880a19..a1590ca03624 100644 --- a/engines/ags/engine/main/game_file.cpp +++ b/engines/ags/engine/main/game_file.cpp @@ -53,6 +53,8 @@ #include "plugin/agsplugin.h" #include "script/script.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -88,9 +90,9 @@ String get_caps_list(const std::set &caps) { HGameFileError game_file_first_open(MainGameSource &src) { HGameFileError err = OpenMainGameFileFromDefaultAsset(src); if (err || - err->Code() == kMGFErr_SignatureFailed || - err->Code() == kMGFErr_FormatVersionTooOld || - err->Code() == kMGFErr_FormatVersionNotSupported) { + err->Code() == kMGFErr_SignatureFailed || + err->Code() == kMGFErr_FormatVersionTooOld || + err->Code() == kMGFErr_FormatVersionNotSupported) { // Log data description for debugging Debug::Printf(kDbgMsg_Info, "Opened game data file: %s", src.Filename.GetCStr()); Debug::Printf(kDbgMsg_Info, "Game data version: %d", src.DataVersion); @@ -117,7 +119,7 @@ void PreReadSaveFileInfo(Stream *in, GameDataVersion data_ver) { AlignedStream align_s(in, Common::kAligned_Read); game.ReadFromFile(&align_s); // Discard game messages we do not need here - delete [] game.load_messages; + delete[] game.load_messages; game.load_messages = nullptr; game.read_savegame_info(in, data_ver); } @@ -153,5 +155,7 @@ HError load_game_file() { void display_game_file_error(HError err) { platform->DisplayAlert("Loading game failed with error:\n%s.\n\nThe game files may be incomplete, corrupt or from unsupported version of AGS.", - err->FullMessage().GetCStr()); + err->FullMessage().GetCStr()); } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 1532bf611f80..63816c8cbe76 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -66,6 +66,8 @@ #include "ac/timer.h" #include "ac/keycode.h" +namespace AGS3 { + using namespace AGS::Shared; extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS]; @@ -128,7 +130,7 @@ static void ProperExit() { static void game_loop_check_problems_at_start() { if ((in_enters_screen != 0) & (displayed_room == starting_room)) quit("!A text script run in the Player Enters Screen event caused the\n" - "screen to be updated. If you need to use Wait(), do so in After Fadein"); + "screen to be updated. If you need to use Wait(), do so in After Fadein"); if ((in_enters_screen != 0) && (done_es_error == 0)) { debug_script_warn("Wait() was used in Player Enters Screen - use Enters Screen After Fadein instead"); done_es_error = 1; @@ -251,7 +253,7 @@ static void check_mouse_controls() { } else if (is_text_overlay > 0) { if (play.cant_skip_speech & SKIP_MOUSECLICK) remove_screen_overlay(OVER_TEXTMSG); - } else if (!IsInterfaceEnabled()) ; // blocking cutscene, ignore mouse + } else if (!IsInterfaceEnabled()); // blocking cutscene, ignore mouse else if (pl_run_plugin_hooks(AGSE_MOUSECLICK, mbut + 1)) { // plugin took the click debug_script_log("Plugin handled mouse button %d", mbut + 1); @@ -397,8 +399,8 @@ static void check_keyboard_controls() { if (IsGamePaused() == 0) { // check if it requires a specific keypress if ((play.skip_speech_specific_key > 0) && - (kgn != play.skip_speech_specific_key)) { } - else + (kgn != play.skip_speech_specific_key)) { + } else remove_screen_overlay(OVER_TEXTMSG); } @@ -425,22 +427,22 @@ static void check_keyboard_controls() { int ff; // MACPORT FIX 9/6/5: added last %s sprintf(infobuf, "In room %d %s[Player at %d, %d (view %d, loop %d, frame %d)%s%s%s", - displayed_room, (noWalkBehindsAtAll ? "(has no walk-behinds)" : ""), playerchar->x, playerchar->y, - playerchar->view + 1, playerchar->loop, playerchar->frame, - (IsGamePaused() == 0) ? "" : "[Game paused.", - (play.ground_level_areas_disabled == 0) ? "" : "[Ground areas disabled.", - (IsInterfaceEnabled() == 0) ? "[Game in Wait state" : ""); + displayed_room, (noWalkBehindsAtAll ? "(has no walk-behinds)" : ""), playerchar->x, playerchar->y, + playerchar->view + 1, playerchar->loop, playerchar->frame, + (IsGamePaused() == 0) ? "" : "[Game paused.", + (play.ground_level_areas_disabled == 0) ? "" : "[Ground areas disabled.", + (IsInterfaceEnabled() == 0) ? "[Game in Wait state" : ""); for (ff = 0; ff < croom->numobj; ff++) { if (ff >= 8) break; // buffer not big enough for more than 7 sprintf(&infobuf[strlen(infobuf)], - "[Object %d: (%d,%d) size (%d x %d) on:%d moving:%s animating:%d slot:%d trnsp:%d clkble:%d", - ff, objs[ff].x, objs[ff].y, - (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Width : 0, - (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Height : 0, - objs[ff].on, - (objs[ff].moving > 0) ? "yes" : "no", objs[ff].cycling, - objs[ff].num, objs[ff].transparent, - ((objs[ff].flags & OBJF_NOINTERACT) != 0) ? 0 : 1); + "[Object %d: (%d,%d) size (%d x %d) on:%d moving:%s animating:%d slot:%d trnsp:%d clkble:%d", + ff, objs[ff].x, objs[ff].y, + (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Width : 0, + (spriteset[objs[ff].num] != nullptr) ? game.SpriteInfos[objs[ff].num].Height : 0, + objs[ff].on, + (objs[ff].moving > 0) ? "yes" : "no", objs[ff].cycling, + objs[ff].num, objs[ff].transparent, + ((objs[ff].flags & OBJF_NOINTERACT) != 0) ? 0 : 1); } Display(infobuf); int chd = game.playercharacter; @@ -454,12 +456,12 @@ static void check_keyboard_controls() { } chd = ff; sprintf(&bigbuffer[strlen(bigbuffer)], - "%s (view/loop/frm:%d,%d,%d x/y/z:%d,%d,%d idleview:%d,time:%d,left:%d walk:%d anim:%d follow:%d flags:%X wait:%d zoom:%d)[", - game.chars[chd].scrname, game.chars[chd].view + 1, game.chars[chd].loop, game.chars[chd].frame, - game.chars[chd].x, game.chars[chd].y, game.chars[chd].z, - game.chars[chd].idleview, game.chars[chd].idletime, game.chars[chd].idleleft, - game.chars[chd].walking, game.chars[chd].animating, game.chars[chd].following, - game.chars[chd].flags, game.chars[chd].wait, charextra[chd].zoom); + "%s (view/loop/frm:%d,%d,%d x/y/z:%d,%d,%d idleview:%d,time:%d,left:%d walk:%d anim:%d follow:%d flags:%X wait:%d zoom:%d)[", + game.chars[chd].scrname, game.chars[chd].view + 1, game.chars[chd].loop, game.chars[chd].frame, + game.chars[chd].x, game.chars[chd].y, game.chars[chd].z, + game.chars[chd].idleview, game.chars[chd].idletime, game.chars[chd].idleleft, + game.chars[chd].walking, game.chars[chd].animating, game.chars[chd].following, + game.chars[chd].flags, game.chars[chd].wait, charextra[chd].zoom); } Display(bigbuffer); @@ -496,7 +498,7 @@ static void check_keyboard_controls() { // pressed, but exclude control characters (<32) and // extended keys (eg. up/down arrow; 256+) if ((((kgn >= 32) && (kgn <= 255) && (kgn != '[')) || (kgn == eAGSKeyCodeReturn) || (kgn == eAGSKeyCodeBackspace)) - && !all_buttons_disabled) { + && !all_buttons_disabled) { for (int guiIndex = 0; guiIndex < game.numgui; guiIndex++) { auto &gui = guis[guiIndex]; @@ -552,13 +554,13 @@ static void check_controls() { static void check_room_edges(int numevents_was) { if ((IsInterfaceEnabled()) && (IsGamePaused() == 0) && - (in_new_room == 0) && (new_room_was == 0)) { + (in_new_room == 0) && (new_room_was == 0)) { // Only allow walking off edges if not in wait mode, and // if not in Player Enters Screen (allow walking in from off-screen) - int edgesActivated[4] = {0, 0, 0, 0}; + int edgesActivated[4] = { 0, 0, 0, 0 }; // Only do it if nothing else has happened (eg. mouseclick) if ((numevents == numevents_was) && - ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0)) { + ((play.ground_level_areas_disabled & GLED_INTERACTION) == 0)) { if (playerchar->x <= thisroom.Edges.Left) edgesActivated[0] = 1; @@ -602,7 +604,7 @@ static void game_loop_check_controls(bool checkControls) { } static void game_loop_do_update() { - if (debug_flags & DBG_NOUPDATE) ; + if (debug_flags & DBG_NOUPDATE); else if (game_paused == 0) update_stuff(); } @@ -641,7 +643,7 @@ static void game_loop_do_render_and_check_mouse(IDriverDependantBitmap *extraBit int offsety = cam->GetRect().Top; if (((mwasatx != mousex) || (mwasaty != mousey) || - (offsetxWas != offsetx) || (offsetyWas != offsety))) { + (offsetxWas != offsetx) || (offsetyWas != offsety))) { // mouse moves over hotspot if (__GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey), 1) == LOCTYPE_HOTSPOT) { int onhs = getloctype_index; @@ -675,7 +677,7 @@ static void game_loop_update_events() { static void game_loop_update_background_animation() { if (play.bg_anim_delay > 0) play.bg_anim_delay--; - else if (play.bg_frame_locked) ; + else if (play.bg_frame_locked); else { play.bg_anim_delay = play.anim_background_speed; play.bg_frame++; @@ -815,8 +817,8 @@ static void UpdateMouseOverLocation() { GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); if ((play.get_loc_name_save_cursor >= 0) && - (play.get_loc_name_save_cursor != play.get_loc_name_last_time) && - (mouse_on_iface < 0) && (ifacepopped < 0)) { + (play.get_loc_name_save_cursor != play.get_loc_name_last_time) && + (mouse_on_iface < 0) && (ifacepopped < 0)) { // we have saved the cursor, but the mouse location has changed // and it's time to restore it play.get_loc_name_save_cursor = -1; @@ -882,9 +884,9 @@ static int UpdateWaitMode() { user_disabled_for = 0; switch (was_disabled_for) { - // case FOR_ANIMATION: - // run_animation((FullAnimation*)user_disabled_data2,user_disabled_data3); - // break; + // case FOR_ANIMATION: + // run_animation((FullAnimation*)user_disabled_data2,user_disabled_data3); + // break; case FOR_EXITLOOP: return -1; case FOR_SCRIPT: @@ -921,7 +923,7 @@ static void SetupLoopParameters(int untilwhat, const void *udata) { // Only change the mouse cursor if it hasn't been specifically changed first // (or if it's speech, always change it) if (((cur_cursor == cur_mode) || (untilwhat == UNTIL_NOOVERLAY)) && - (cur_mode != CURS_WAIT)) + (cur_mode != CURS_WAIT)) set_mouse_cursor(CURS_WAIT); restrict_until = untilwhat; @@ -1011,3 +1013,5 @@ void update_polled_stuff_if_runtime() { if (editor_debugging_initialized) check_for_messages_from_editor(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index aad1e4319564..244f007a35b4 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -44,6 +44,8 @@ #include "media/audio/audio_system.h" #include "ac/timer.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -155,3 +157,5 @@ void initialize_start_and_play_game(int override_start_room, const char *loadSav quit((char *)gfxException._message); } } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp index 986b332414af..2700ea198654 100644 --- a/engines/ags/engine/main/graphics_mode.cpp +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -40,6 +40,8 @@ #include "main/main_allegro.h" #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + // Don't try to figure out the window size on the mac because the port resizes itself. #if AGS_PLATFORM_OS_MACOS || defined(ALLEGRO_SDL2) || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID #define USE_SIMPLE_GFX_INIT @@ -129,7 +131,7 @@ bool graphics_mode_set_filter_any(const GfxFilterSetup &setup) { if (def_filter.CompareNoCase(setup.ID) == 0) return false; Debug::Printf(kDbgMsg_Error, "Failed to apply gfx filter: %s; will try to use factory default filter '%s' instead", - setup.UserRequest.GetCStr(), def_filter.GetCStr()); + setup.UserRequest.GetCStr(), def_filter.GetCStr()); if (!graphics_mode_set_filter(def_filter)) return false; } @@ -138,7 +140,7 @@ bool graphics_mode_set_filter_any(const GfxFilterSetup &setup) { } bool find_nearest_supported_mode(const IGfxModeList &modes, const Size &wanted_size, const int color_depth, - const Size *ratio_reference, const Size *upper_bound, DisplayMode &dm, int *mode_index) { + const Size *ratio_reference, const Size *upper_bound, DisplayMode &dm, int *mode_index) { uint32_t wanted_ratio = 0; if (ratio_reference && !ratio_reference->IsNull()) { wanted_ratio = (ratio_reference->Height << kShift) / ratio_reference->Width; @@ -181,8 +183,8 @@ bool find_nearest_supported_mode(const IGfxModeList &modes, const Size &wanted_s bool same_diff_h_higher = (diff_h == nearest_height_diff && nearest_height < wanted_size.Height); if (nearest_width == 0 || - ((diff_w < nearest_width_diff || same_diff_w_higher) && diff_h <= nearest_height_diff) || - ((diff_h < nearest_height_diff || same_diff_h_higher) && diff_w <= nearest_width_diff)) { + ((diff_w < nearest_width_diff || same_diff_w_higher) && diff_h <= nearest_height_diff) || + ((diff_h < nearest_height_diff || same_diff_h_higher) && diff_w <= nearest_width_diff)) { nearest_width = mode.Width; nearest_width_diff = diff_w; nearest_height = mode.Height; @@ -212,7 +214,7 @@ Size set_game_frame_after_screen_size(const Size &game_size, const Size screen_s int scale; if (setup.ScaleDef == kFrame_MaxRound) scale = Math::Min((screen_size.Width / game_size.Width) << kShift, - (screen_size.Height / game_size.Height) << kShift); + (screen_size.Height / game_size.Height) << kShift); else scale = convert_scaling_to_fp(setup.ScaleFactor); @@ -267,7 +269,7 @@ bool try_init_compatible_mode(const DisplayMode &dm, const bool match_device_rat const Size &screen_size = Size(dm.Width, dm.Height); // Find nearest compatible mode and init that Debug::Printf("Attempting to find nearest supported resolution for screen size %d x %d (%d-bit) %s", - dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); + dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); const Size device_size = get_max_display_size(dm.Windowed); if (dm.Windowed) Debug::Printf("Maximal allowed window size: %d x %d", device_size.Width, device_size.Height); @@ -314,12 +316,12 @@ bool try_init_compatible_mode(const DisplayMode &dm, const bool match_device_rat // Try to find and initialize compatible display mode as close to given setup as possible bool try_init_mode_using_setup(const Size &game_size, const DisplayModeSetup &dm_setup, - const int col_depth, const GameFrameSetup &frame_setup, - const GfxFilterSetup &filter_setup) { + const int col_depth, const GameFrameSetup &frame_setup, + const GfxFilterSetup &filter_setup) { // We determine the requested size of the screen using setup options const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, col_depth), - dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); if (!try_init_compatible_mode(dm, dm_setup.ScreenSize.SizeDef == kScreenDef_Explicit ? false : dm_setup.ScreenSize.MatchDeviceRatio)) return false; @@ -363,12 +365,12 @@ void log_out_driver_modes(const int color_depth) { // Create requested graphics driver and try to find and initialize compatible display mode as close to user setup as possible; // if the given setup fails, gets default setup for the opposite type of mode (fullscreen/windowed) and tries that instead. bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id, const Size &game_size, const DisplayModeSetup &dm_setup, - const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup, const GfxFilterSetup &filter_setup) { + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup, const GfxFilterSetup &filter_setup) { if (!graphics_mode_create_renderer(gfx_driver_id)) return false; const int use_col_depth = - color_depth.Forced ? color_depth.Bits : gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); + color_depth.Forced ? color_depth.Bits : gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); // Log out supported driver modes log_out_driver_modes(use_col_depth); @@ -386,11 +388,11 @@ bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id, const Size } bool simple_create_gfx_driver_and_init_mode(const String &gfx_driver_id, - const Size &game_size, - const DisplayModeSetup &dm_setup, - const ColorDepthOption &color_depth, - const GameFrameSetup &frame_setup, - const GfxFilterSetup &filter_setup) { + const Size &game_size, + const DisplayModeSetup &dm_setup, + const ColorDepthOption &color_depth, + const GameFrameSetup &frame_setup, + const GfxFilterSetup &filter_setup) { if (!graphics_mode_create_renderer(gfx_driver_id)) { return false; } @@ -398,7 +400,7 @@ bool simple_create_gfx_driver_and_init_mode(const String &gfx_driver_id, const int col_depth = gfxDriver->GetDisplayDepthForNativeDepth(color_depth.Bits); DisplayMode dm(GraphicResolution(game_size.Width, game_size.Height, col_depth), - dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); if (!graphics_mode_set_dm(dm)) { return false; @@ -427,16 +429,16 @@ void display_gfx_mode_error(const Size &game_size, const ScreenSetup &setup, con Size wanted_screen; if (scsz.SizeDef == kScreenDef_Explicit) main_error.Format("There was a problem initializing graphics mode %d x %d (%d-bit), or finding nearest compatible mode, with game size %d x %d and filter '%s'.", - scsz.Size.Width, scsz.Size.Height, color_depth, game_size.Width, game_size.Height, filter ? filter->GetInfo().Id.GetCStr() : "Undefined"); + scsz.Size.Width, scsz.Size.Height, color_depth, game_size.Width, game_size.Height, filter ? filter->GetInfo().Id.GetCStr() : "Undefined"); else main_error.Format("There was a problem finding and/or creating valid graphics mode for game size %d x %d (%d-bit) and requested filter '%s'.", - game_size.Width, game_size.Height, color_depth, setup.Filter.UserRequest.IsEmpty() ? "Undefined" : setup.Filter.UserRequest.GetCStr()); + game_size.Width, game_size.Height, color_depth, setup.Filter.UserRequest.IsEmpty() ? "Undefined" : setup.Filter.UserRequest.GetCStr()); platform->DisplayAlert("%s\n" - "(Problem: '%s')\n" - "Try to correct the problem, or seek help from the AGS homepage." - "%s", - main_error.GetCStr(), get_allegro_error(), platform->GetGraphicsTroubleshootingText()); + "(Problem: '%s')\n" + "Try to correct the problem, or seek help from the AGS homepage." + "%s", + main_error.GetCStr(), get_allegro_error(), platform->GetGraphicsTroubleshootingText()); } bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, const ColorDepthOption &color_depth) { @@ -453,10 +455,10 @@ bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, cons GameFrameSetup gameframe = setup.DisplayMode.Windowed ? setup.WinGameFrame : setup.FsGameFrame; const String scale_option = make_scaling_option(gameframe); Debug::Printf(kDbgMsg_Info, "Graphic settings: driver: %s, windowed: %s, screen def: %s, screen size: %d x %d, match device ratio: %s, game scale: %s", - setup.DriverID.GetCStr(), - setup.DisplayMode.Windowed ? "yes" : "no", screen_sz_def_options[scsz.SizeDef], - scsz.Size.Width, scsz.Size.Height, - ignore_device_ratio ? "ignore" : (scsz.MatchDeviceRatio ? "yes" : "no"), scale_option.GetCStr()); + setup.DriverID.GetCStr(), + setup.DisplayMode.Windowed ? "yes" : "no", screen_sz_def_options[scsz.SizeDef], + scsz.Size.Width, scsz.Size.Height, + ignore_device_ratio ? "ignore" : (scsz.MatchDeviceRatio ? "yes" : "no"), scale_option.GetCStr()); // Prepare the list of available gfx factories, having the one requested by user at first place // TODO: make factory & driver IDs case-insensitive! @@ -476,11 +478,11 @@ bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, cons for (StringV::const_iterator it = ids.begin(); it != ids.end(); ++it) { result = #ifdef USE_SIMPLE_GFX_INIT - simple_create_gfx_driver_and_init_mode + simple_create_gfx_driver_and_init_mode #else - create_gfx_driver_and_init_mode_any + create_gfx_driver_and_init_mode_any #endif - (*it, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter); + (*it, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter); if (result) break; @@ -518,17 +520,17 @@ bool graphics_mode_create_renderer(const String &driver_id) { } bool graphics_mode_set_dm_any(const Size &game_size, const DisplayModeSetup &dm_setup, - const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup) { + const ColorDepthOption &color_depth, const GameFrameSetup &frame_setup) { // We determine the requested size of the screen using setup options const Size screen_size = precalc_screen_size(game_size, dm_setup, frame_setup); DisplayMode dm(GraphicResolution(screen_size.Width, screen_size.Height, color_depth.Bits), - dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); + dm_setup.Windowed, dm_setup.RefreshRate, dm_setup.VSync); return try_init_compatible_mode(dm, dm_setup.ScreenSize.MatchDeviceRatio); } bool graphics_mode_set_dm(const DisplayMode &dm) { Debug::Printf("Attempt to switch gfx mode to %d x %d (%d-bit) %s", - dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); + dm.Width, dm.Height, dm.ColorDepth, dm.Windowed ? "windowed" : "fullscreen"); // Tell Allegro new default bitmap color depth (must be done before set_gfx_mode) // TODO: this is also done inside ALSoftwareGraphicsDriver implementation; can remove one? @@ -549,7 +551,7 @@ bool graphics_mode_set_dm(const DisplayMode &dm) { else SavedFullscreenSetting.Dm = rdm; Debug::Printf("Succeeded. Using gfx mode %d x %d (%d-bit) %s", - rdm.Width, rdm.Height, rdm.ColorDepth, rdm.Windowed ? "windowed" : "fullscreen"); + rdm.Width, rdm.Height, rdm.ColorDepth, rdm.Windowed ? "windowed" : "fullscreen"); return true; } @@ -565,14 +567,14 @@ bool graphics_mode_update_render_frame() { if (!gfxDriver->SetRenderFrame(render_frame)) { Debug::Printf(kDbgMsg_Error, "Failed to set render frame (%d, %d, %d, %d : %d x %d). Error: %s", - render_frame.Left, render_frame.Top, render_frame.Right, render_frame.Bottom, - render_frame.GetWidth(), render_frame.GetHeight(), get_allegro_error()); + render_frame.Left, render_frame.Top, render_frame.Right, render_frame.Bottom, + render_frame.GetWidth(), render_frame.GetHeight(), get_allegro_error()); return false; } Rect dst_rect = gfxDriver->GetRenderDestination(); Debug::Printf("Render frame set, render dest (%d, %d, %d, %d : %d x %d)", - dst_rect.Left, dst_rect.Top, dst_rect.Right, dst_rect.Bottom, dst_rect.GetWidth(), dst_rect.GetHeight()); + dst_rect.Left, dst_rect.Top, dst_rect.Right, dst_rect.Bottom, dst_rect.GetWidth(), dst_rect.GetHeight()); // init game scaling transformation GameScaling.Init(native_size, gfxDriver->GetRenderDestination()); return true; @@ -615,9 +617,9 @@ bool graphics_mode_set_filter(const String &filter_id) { Debug::Printf(kDbgMsg_Error, "Unable to set graphics filter '%s'. Error: %s", filter_id.GetCStr(), filter_error.GetCStr()); return false; } - Rect filter_rect = filter->GetDestination(); + Rect filter_rect = filter->GetDestination(); Debug::Printf("Graphics filter set: '%s', filter dest (%d, %d, %d, %d : %d x %d)", filter->GetInfo().Id.GetCStr(), - filter_rect.Left, filter_rect.Top, filter_rect.Right, filter_rect.Bottom, filter_rect.GetWidth(), filter_rect.GetHeight()); + filter_rect.Left, filter_rect.Top, filter_rect.Right, filter_rect.Bottom, filter_rect.GetWidth(), filter_rect.GetHeight()); return true; } @@ -630,3 +632,5 @@ void graphics_mode_shutdown() { // Tell Allegro that we are no longer in graphics mode set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp index d41abba50624..91f12195fc96 100644 --- a/engines/ags/engine/main/main.cpp +++ b/engines/ags/engine/main/main.cpp @@ -63,6 +63,8 @@ #define USE_CUSTOM_EXCEPTION_HANDLER #endif +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -164,12 +166,12 @@ void main_init(int argc, char *argv[]) { String get_engine_string() { return String::FromFormat("Adventure Game Studio v%s Interpreter\n" - "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" + "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" #ifdef BUILD_STR - "ACI version %s (Build: %s)\n", - EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr(), EngineVersion.BuildInfo.GetCStr()); + "ACI version %s (Build: %s)\n", + EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr(), EngineVersion.BuildInfo.GetCStr()); #else - "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); + "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); #endif } @@ -178,67 +180,67 @@ extern char return_to_room[150]; void main_print_help() { platform->WriteStdOut( - "Usage: ags [OPTIONS] [GAMEFILE or DIRECTORY]\n\n" - //--------------------------------------------------------------------------------| - "Options:\n" + "Usage: ags [OPTIONS] [GAMEFILE or DIRECTORY]\n\n" + //--------------------------------------------------------------------------------| + "Options:\n" #if AGS_PLATFORM_OS_WINDOWS - " --console-attach Write output to the parent process's console\n" + " --console-attach Write output to the parent process's console\n" #endif - " --fps Display fps counter\n" - " --fullscreen Force display mode to fullscreen\n" - " --gfxdriver Request graphics driver. Available options:\n" + " --fps Display fps counter\n" + " --fullscreen Force display mode to fullscreen\n" + " --gfxdriver Request graphics driver. Available options:\n" #if AGS_PLATFORM_OS_WINDOWS - " d3d9, ogl, software\n" + " d3d9, ogl, software\n" #else - " ogl, software\n" + " ogl, software\n" #endif - " --gfxfilter FILTER [SCALING]\n" - " Request graphics filter. Available options:\n" - " hqx, linear, none, stdscale\n" - " (support differs between graphic drivers);\n" - " scaling is specified by integer number\n" - " --help Print this help message and stop\n" - " --log-OUTPUT=GROUP[:LEVEL][,GROUP[:LEVEL]][,...]\n" - " --log-OUTPUT=+GROUPLIST[:LEVEL]\n" - " Setup logging to the chosen OUTPUT with given\n" - " log groups and verbosity levels. Groups may\n" - " be also defined by a LIST of one-letter IDs,\n" - " preceded by '+', e.g. +ABCD:LEVEL. Verbosity may\n" - " be also defined by a numberic ID.\n" - " OUTPUTs are\n" - " stdout, file, console\n" - " (where \"console\" is internal engine's console)\n" - " GROUPs are:\n" - " all, main (m), game (g), manobj (o),\n" - " script (s), sprcache (c)\n" - " LEVELs are:\n" - " all, alert (1), fatal (2), error (3), warn (4),\n" - " info (5), debug (6)\n" - " Examples:\n" - " --log-stdout=+mgs:debug\n" - " --log-file=all:warn\n" - " --log-file-path=PATH Define custom path for the log file\n" - //--------------------------------------------------------------------------------| + " --gfxfilter FILTER [SCALING]\n" + " Request graphics filter. Available options:\n" + " hqx, linear, none, stdscale\n" + " (support differs between graphic drivers);\n" + " scaling is specified by integer number\n" + " --help Print this help message and stop\n" + " --log-OUTPUT=GROUP[:LEVEL][,GROUP[:LEVEL]][,...]\n" + " --log-OUTPUT=+GROUPLIST[:LEVEL]\n" + " Setup logging to the chosen OUTPUT with given\n" + " log groups and verbosity levels. Groups may\n" + " be also defined by a LIST of one-letter IDs,\n" + " preceded by '+', e.g. +ABCD:LEVEL. Verbosity may\n" + " be also defined by a numberic ID.\n" + " OUTPUTs are\n" + " stdout, file, console\n" + " (where \"console\" is internal engine's console)\n" + " GROUPs are:\n" + " all, main (m), game (g), manobj (o),\n" + " script (s), sprcache (c)\n" + " LEVELs are:\n" + " all, alert (1), fatal (2), error (3), warn (4),\n" + " info (5), debug (6)\n" + " Examples:\n" + " --log-stdout=+mgs:debug\n" + " --log-file=all:warn\n" + " --log-file-path=PATH Define custom path for the log file\n" + //--------------------------------------------------------------------------------| #if AGS_PLATFORM_OS_WINDOWS - " --no-message-box Disable reporting of alerts to message boxes\n" - " --setup Run setup application\n" + " --no-message-box Disable reporting of alerts to message boxes\n" + " --setup Run setup application\n" #endif - " --tell Print various information concerning engine\n" - " and the game; for selected output use:\n" - " --tell-config Print contents of merged game config\n" - " --tell-configpath Print paths to available config files\n" - " --tell-data Print information on game data and its location\n" - " --tell-engine Print engine name and version\n" - " --tell-graphicdriver Print list of supported graphic drivers\n" - "\n" - " --version Print engine's version and stop\n" - " --windowed Force display mode to windowed\n" - "\n" - "Gamefile options:\n" - " /dir/path/game/ Launch the game in specified directory\n" - " /dir/path/game/penguin.exe Launch penguin.exe\n" - " [nothing] Launch the game in the current directory\n" - //--------------------------------------------------------------------------------| + " --tell Print various information concerning engine\n" + " and the game; for selected output use:\n" + " --tell-config Print contents of merged game config\n" + " --tell-configpath Print paths to available config files\n" + " --tell-data Print information on game data and its location\n" + " --tell-engine Print engine name and version\n" + " --tell-graphicdriver Print list of supported graphic drivers\n" + "\n" + " --version Print engine's version and stop\n" + " --windowed Force display mode to windowed\n" + "\n" + "Gamefile options:\n" + " /dir/path/game/ Launch the game in specified directory\n" + " /dir/path/game/penguin.exe Launch penguin.exe\n" + " [nothing] Launch the game in the current directory\n" + //--------------------------------------------------------------------------------| ); } @@ -459,3 +461,5 @@ int ags_entry_point(int argc, char *argv[]) { } #endif } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 5412b7d9a1bd..e76439281fa6 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -47,6 +47,8 @@ #include "plugin/plugin_engine.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -87,7 +89,7 @@ void quit_shutdown_scripts() { void quit_check_dynamic_sprites(QuitReason qreason) { if ((qreason & kQuitKind_NormalExit) && (check_dynamic_sprites_at_exit) && - (game.options[OPT_DEBUGMODE] != 0)) { + (game.options[OPT_DEBUGMODE] != 0)) { // game exiting normally -- make sure the dynamic sprites // have been deleted for (int i = 1; i < spriteset.GetSpriteSlotCount(); i++) { @@ -146,8 +148,8 @@ QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) { } else { qreason = kQuit_GameError; alertis.Format("An error has occurred. Please contact the game author for support, as this " - "is likely to be a scripting error and not a bug in AGS.\n" - "(ACI version %s)\n\n", EngineVersion.LongString.GetCStr()); + "is likely to be a scripting error and not a bug in AGS.\n" + "(ACI version %s)\n\n", EngineVersion.LongString.GetCStr()); } alertis.Append(get_cur_script(5)); @@ -160,14 +162,14 @@ QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) { } else if (qmsg[0] == '%') { qmsg++; alertis.Format("A warning has been generated. This is not normally fatal, but you have selected " - "to treat warnings as errors.\n" - "(ACI version %s)\n\n%s\n", EngineVersion.LongString.GetCStr(), get_cur_script(5).GetCStr()); + "to treat warnings as errors.\n" + "(ACI version %s)\n\n%s\n", EngineVersion.LongString.GetCStr(), get_cur_script(5).GetCStr()); return kQuit_GameWarning; } else { alertis.Format("An internal error has occurred. Please note down the following information.\n" - "If the problem persists, post the details on the AGS Technical Forum.\n" - "(ACI version %s)\n" - "\nError: ", EngineVersion.LongString.GetCStr()); + "If the problem persists, post the details on the AGS Technical Forum.\n" + "(ACI version %s)\n" + "\nError: ", EngineVersion.LongString.GetCStr()); return kQuit_FatalError; } } @@ -300,3 +302,5 @@ extern "C" { quit(msg); } } + +} // namespace AGS3 diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp index 54a54daff2b6..f8810acccde0 100644 --- a/engines/ags/engine/main/update.cpp +++ b/engines/ags/engine/main/update.cpp @@ -49,6 +49,8 @@ #include "main/game_run.h" #include "ac/movelist.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -95,16 +97,18 @@ int do_movelist_move(short *mlnum, int *xx, int *yy) { int adjAmnt = 3; // 2.70: if the X permove is also <=1, don't do the skipping if (((xpermove & 0xffff0000) == 0xffff0000) || - ((xpermove & 0xffff0000) == 0x00000000)) + ((xpermove & 0xffff0000) == 0x00000000)) adjAmnt = 2; // 2.61 RC1: correct this to work with > -1 as well as < 1 - if (ypermove == 0) { } + if (ypermove == 0) { + } // Y per move is < 1, so finish the move else if ((ypermove & 0xffff0000) == 0) targety -= adjAmnt; // Y per move is -1 exactly, don't snap to finish - else if (ypermove == 0xffff0000) { } + else if (ypermove == 0xffff0000) { + } // Y per move is > -1, so finish the move else if ((ypermove & 0xffff0000) == 0xffff0000) targety += adjAmnt; @@ -117,26 +121,28 @@ int do_movelist_move(short *mlnum, int *xx, int *yy) { // if the Y permove is also <=1, don't skip as far if (((ypermove & 0xffff0000) == 0xffff0000) || - ((ypermove & 0xffff0000) == 0x00000000)) + ((ypermove & 0xffff0000) == 0x00000000)) adjAmnt = 2; - if (xpermove == 0) { } + if (xpermove == 0) { + } // Y per move is < 1, so finish the move else if ((xpermove & 0xffff0000) == 0) targetx -= adjAmnt; // X per move is -1 exactly, don't snap to finish - else if (xpermove == 0xffff0000) { } + else if (xpermove == 0xffff0000) { + } // X per move is > -1, so finish the move else if ((xpermove & 0xffff0000) == 0xffff0000) targetx += adjAmnt; /* int xpmm=(xpermove >> 16) & 0x0000ffff; // if ((xpmm==0) | (xpmm==0xffff)) cmls->doneflag|=1; - if (xpmm==0) cmls->doneflag|=1;*/ + if (xpmm==0) cmls->doneflag|=1;*/ } else yps = cmls->fromy + (int)(fixtof(ypermove) * (float)cmls->onpart); // check if finished horizontal movement if (((xpermove > 0) && (xps >= targetx)) || - ((xpermove < 0) && (xps <= targetx))) { + ((xpermove < 0) && (xps <= targetx))) { cmls->doneflag |= 1; xps = targetx; // if the Y is almost there too, finish it @@ -147,7 +153,7 @@ int do_movelist_move(short *mlnum, int *xx, int *yy) { } else if (xpermove == 0) cmls->doneflag |= 1; // check if finished vertical movement - if ((ypermove > 0) & (yps >= targety)) { + if ((ypermove > 0) &(yps >= targety)) { cmls->doneflag |= 2; yps = targety; } else if ((ypermove < 0) & (yps <= targety)) { @@ -205,8 +211,8 @@ void update_cycling_views() { void update_shadow_areas() { // shadow areas int onwalkarea = get_walkable_area_at_character(game.playercharacter); - if (onwalkarea < 0) ; - else if (playerchar->flags & CHF_FIXVIEW) ; + if (onwalkarea < 0); + else if (playerchar->flags & CHF_FIXVIEW); else { onwalkarea = thisroom.WalkAreas[onwalkarea].Light; if (onwalkarea > 0) playerchar->view = onwalkarea - 1; @@ -220,7 +226,7 @@ void update_character_move_and_anim(int &numSheep, int *followingAsSheep) { for (int aa = 0; aa < game.numcharacters; aa++) { if (game.chars[aa].on != 1) continue; - CharacterInfo *chi = &game.chars[aa]; + CharacterInfo *chi = &game.chars[aa]; CharacterExtras *chex = &charextra[aa]; chi->UpdateMoveAndAnim(aa, chex, numSheep, followingAsSheep); @@ -270,7 +276,7 @@ void update_speech_and_messages() { } if (play.messagetime < 1 && play.speech_display_post_time_ms > 0 && - play.fast_forward == 0) { + play.fast_forward == 0) { if (!play.speech_in_post_state) { play.messagetime = ::lround(play.speech_display_post_time_ms * get_current_fps() / 1000.0f); } @@ -331,8 +337,8 @@ void update_sierra_speech() { // the lip-sync has finished, so just stay idle } else { while ((curLipLinePhoneme < splipsync[curLipLine].numPhonemes) && - ((curLipLinePhoneme < 0) || (voice_pos_ms >= splipsync[curLipLine].endtimeoffs[curLipLinePhoneme]))) { - curLipLinePhoneme ++; + ((curLipLinePhoneme < 0) || (voice_pos_ms >= splipsync[curLipLine].endtimeoffs[curLipLinePhoneme]))) { + curLipLinePhoneme++; if (curLipLinePhoneme >= splipsync[curLipLine].numPhonemes) facetalkframe = game.default_lipsync_frame; else @@ -347,18 +353,18 @@ void update_sierra_speech() { } else if (facetalkwait > 0) facetalkwait--; // don't animate if the speech has finished else if ((play.messagetime < 1) && (facetalkframe == 0) && - // if play.close_mouth_speech_time = 0, this means animation should play till - // the speech ends; but this should not work in voice mode, and also if the - // speech is in the "post" state - (play.speech_has_voice || play.speech_in_post_state || play.close_mouth_speech_time > 0)) + // if play.close_mouth_speech_time = 0, this means animation should play till + // the speech ends; but this should not work in voice mode, and also if the + // speech is in the "post" state + (play.speech_has_voice || play.speech_in_post_state || play.close_mouth_speech_time > 0)) ; else { // Close mouth at end of sentence: if speech has entered the "post" state, // or if this is a text only mode and close_mouth_speech_time is set if (play.speech_in_post_state || - (!play.speech_has_voice && - (play.messagetime < play.close_mouth_speech_time) && - (play.close_mouth_speech_time > 0))) { + (!play.speech_has_voice && + (play.messagetime < play.close_mouth_speech_time) && + (play.close_mouth_speech_time > 0))) { facetalkframe = 0; facetalkwait = play.messagetime; } else if ((game.options[OPT_LIPSYNCTEXT]) && (facetalkrepeat > 0)) { @@ -366,15 +372,15 @@ void update_sierra_speech() { facetalkwait = update_lip_sync(facetalkview, facetalkloop, &facetalkframe); // It is actually displayed for facetalkwait+1 loops // (because when it's 1, it gets --'d then wait for next time) - facetalkwait --; + facetalkwait--; } else { // normal non-lip-sync facetalkframe++; if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) || - (!play.speech_has_voice && (play.messagetime < 1) && (play.close_mouth_speech_time > 0))) { + (!play.speech_has_voice && (play.messagetime < 1) && (play.close_mouth_speech_time > 0))) { if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) && - (views[facetalkview].loops[facetalkloop].RunNextLoop())) { + (views[facetalkview].loops[facetalkloop].RunNextLoop())) { facetalkloop++; } else { facetalkloop = 0; @@ -468,3 +474,5 @@ void update_stuff() { our_eip = 25; } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/ambientsound.cpp b/engines/ags/engine/media/audio/ambientsound.cpp index ce89b44cc1e9..b7c77972e4d5 100644 --- a/engines/ags/engine/media/audio/ambientsound.cpp +++ b/engines/ags/engine/media/audio/ambientsound.cpp @@ -25,6 +25,8 @@ #include "media/audio/soundclip.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; bool AmbientSound::IsPlaying() { @@ -50,3 +52,5 @@ void AmbientSound::WriteToFile(Stream *out) { out->WriteInt32(num); out->WriteInt32(maxdist); } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index ffc2ba392d41..cdd3339b5f03 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -47,6 +47,8 @@ #include "ac/timer.h" #include "main/game_run.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -200,14 +202,14 @@ static int find_free_audio_channel(ScriptAudioClip *clip, int priority, bool int break; } if ((ch->priority < lowestPrioritySoFar) && - (ch->sourceClipType == clip->type)) { + (ch->sourceClipType == clip->type)) { lowestPrioritySoFar = ch->priority; lowestPriorityID = i; } } if ((channelToUse < 0) && (lowestPriorityID >= 0) && - (lowestPrioritySoFar <= priority)) { + (lowestPrioritySoFar <= priority)) { stop_or_fade_out_channel(lowestPriorityID, lowestPriorityID, clip); channelToUse = lowestPriorityID; } else if ((channelToUse >= 0) && (play.crossfading_in_channel < 1)) { @@ -218,7 +220,7 @@ static int find_free_audio_channel(ScriptAudioClip *clip, int priority, bool int bool is_audiotype_allowed_to_play(AudioFileType type) { return (type == eAudioFileMIDI && usetup.midicard != MIDI_NONE) || - (type != eAudioFileMIDI && usetup.digicard != DIGI_NONE); + (type != eAudioFileMIDI && usetup.digicard != DIGI_NONE); } SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat) { @@ -572,11 +574,11 @@ void update_directional_sound_vol() { auto *ch = lock.GetChannelIfPlaying(chnum); if ((ch != nullptr) && (ch->xSource >= 0)) { ch->apply_directional_modifier( - get_volume_adjusted_for_distance(ch->vol, - ch->xSource, - ch->ySource, - ch->maximumPossibleDistanceAway) - - ch->vol); + get_volume_adjusted_for_distance(ch->vol, + ch->xSource, + ch->ySource, + ch->maximumPossibleDistanceAway) - + ch->vol); } } } @@ -892,7 +894,7 @@ void update_audio_system_on_game_loop() { play.cur_music_number = -1; play_next_queued(); } else if ((game.options[OPT_CROSSFADEMUSIC] > 0) && - (play.music_queue_size > 0) && (!crossFading)) { + (play.music_queue_size > 0) && (!crossFading)) { // want to crossfade, and new tune in the queue auto *ch = lock.GetChannel(SCHAN_MUSIC); if (ch) { @@ -932,10 +934,10 @@ void stopmusic() { update_music_volume(); } } else if ((game.options[OPT_CROSSFADEMUSIC] > 0) - && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) - && (current_music_type != 0) - && (current_music_type != MUS_MIDI) - && (current_music_type != MUS_MOD)) { + && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) + && (current_music_type != 0) + && (current_music_type != MUS_MIDI) + && (current_music_type != MUS_MOD)) { crossFading = -1; crossFadeStep = 0; @@ -1013,9 +1015,9 @@ int prepare_for_new_music() { int useChannel = SCHAN_MUSIC; if ((game.options[OPT_CROSSFADEMUSIC] > 0) - && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) - && (current_music_type != MUS_MIDI) - && (current_music_type != MUS_MOD)) { + && (lock.GetChannelIfPlaying(SCHAN_MUSIC) != nullptr) + && (current_music_type != MUS_MIDI) + && (current_music_type != MUS_MOD)) { if (crossFading > 0) { // It's still crossfading to the previous track @@ -1132,3 +1134,5 @@ static void play_new_music(int mnum, SOUNDCLIP *music) { void newmusic(int mnum) { play_new_music(mnum, nullptr); } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp index ddf8b2e43900..29337fda62c6 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.cpp +++ b/engines/ags/engine/media/audio/clip_mydumbmod.cpp @@ -27,6 +27,8 @@ #include "media/audio/clip_mydumbmod.h" #include "media/audio/audiointernaldefs.h" +namespace AGS3 { + void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop) { DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(dp); DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); @@ -176,4 +178,6 @@ MYMOD::MYMOD() : SOUNDCLIP() { duhPlayer = nullptr; } +} // namespace AGS3 + #endif // DUMB_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/clip_myjgmod.cpp b/engines/ags/engine/media/audio/clip_myjgmod.cpp index 2dbbc01c748e..2225bb636b54 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.cpp +++ b/engines/ags/engine/media/audio/clip_myjgmod.cpp @@ -27,6 +27,8 @@ #include "media/audio/clip_myjgmod.h" #include "media/audio/audiointernaldefs.h" +namespace AGS3 { + int MYMOD::poll() { if (done) return done; @@ -87,4 +89,6 @@ int MYMOD::play() { MYMOD::MYMOD() : SOUNDCLIP() { } -#endif // #ifdef JGMOD_MOD_PLAYER +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index 06f5bf986fd7..389ed3b47576 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -25,6 +25,8 @@ #include "media/audio/clip_mymidi.h" #include "media/audio/audiointernaldefs.h" +namespace AGS3 { + void MYMIDI::poll() { if (state_ != SoundClipPlaying) { return; @@ -122,3 +124,5 @@ MYMIDI::MYMIDI() : SOUNDCLIP() { tune = nullptr; lengthInSeconds = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp index 792c563fb4a7..d90f2cfbfef3 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -32,6 +32,7 @@ #include "platform/base/agsplatformdriver.h" +namespace AGS3 { void MYMP3::poll() { if (state_ != SoundClipPlaying) { @@ -181,4 +182,6 @@ MYMP3::MYMP3() : SOUNDCLIP() { chunksize = 0; } -#endif // !NO_MP3_PLAYER +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp index 98a2d1485b4f..45634550cca1 100644 --- a/engines/ags/engine/media/audio/clip_myogg.cpp +++ b/engines/ags/engine/media/audio/clip_myogg.cpp @@ -29,6 +29,8 @@ #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + extern "C" { extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); @@ -206,3 +208,5 @@ MYOGG::MYOGG() : SOUNDCLIP() { last_but_one = 0; last_ms_offs = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp index 63b760bdaf12..942a5fbe57a9 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -31,6 +31,8 @@ #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + extern int our_eip; // ALMP3 functions are not reentrant! This mutex should be locked before calling any @@ -162,4 +164,6 @@ MYSTATICMP3::MYSTATICMP3() : SOUNDCLIP() { mp3buffer = nullptr; } -#endif // !NO_MP3_PLAYER +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp index 1efb47f45a25..8860ca716082 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticogg.cpp @@ -28,6 +28,8 @@ #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + extern "C" { extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); @@ -213,3 +215,5 @@ MYSTATICOGG::MYSTATICOGG() : SOUNDCLIP() { last_ms_offs = 0; last_but_one_but_one = 0; } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp index 34ab83cc04f8..5efd2fbe3257 100644 --- a/engines/ags/engine/media/audio/clip_mywave.cpp +++ b/engines/ags/engine/media/audio/clip_mywave.cpp @@ -29,6 +29,8 @@ #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + void MYWAVE::poll() { if (state_ != SoundClipPlaying) { return; @@ -128,3 +130,5 @@ MYWAVE::MYWAVE() : SOUNDCLIP() { wave = nullptr; voice = -1; } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/queuedaudioitem.cpp b/engines/ags/engine/media/audio/queuedaudioitem.cpp index 66be4bf249d7..a98f801af2f3 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.cpp +++ b/engines/ags/engine/media/audio/queuedaudioitem.cpp @@ -24,6 +24,8 @@ #include "ac/common_defines.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; // [IKM] 2012-07-02: these functions are used during load/save game, @@ -42,3 +44,5 @@ void QueuedAudioItem::WriteToFile(Stream *out) const { out->WriteBool(repeat); out->WriteInt32(0); // cachedClip } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index 557c066c931a..ac9f3e6d718c 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -51,6 +51,8 @@ #include "media/audio/soundcache.h" #include "util/mutex_lock.h" +namespace AGS3 { + #if defined JGMOD_MOD_PLAYER && defined DUMB_MOD_PLAYER #error JGMOD_MOD_PLAYER and DUMB_MOD_PLAYER macros cannot be defined at the same time. #endif @@ -61,7 +63,7 @@ extern "C" { -// Load MIDI from PACKFILE stream + // Load MIDI from PACKFILE stream MIDI *load_midi_pf(PACKFILE *pf); } @@ -349,4 +351,6 @@ void remove_mod_player() { dumb_exit(); } -#endif // DUMB_MOD_PLAYER +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index fdeae5cbded5..f8bbfa3095fe 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -31,6 +31,8 @@ #include "util/string.h" #include "debug/out.h" +namespace AGS3 { + using namespace Shared; sound_cache_entry_t *sound_cache_entries = nullptr; @@ -210,3 +212,5 @@ char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) } } + +} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index 28298057d4ac..64a2238f3155 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -26,6 +26,8 @@ #include "media/audio/soundclip.h" #include "media/audio/audiointernaldefs.h" +namespace AGS3 { + int SOUNDCLIP::play_from(int position) { int retVal = play(); if ((retVal != 0) && (position > 0)) { @@ -90,3 +92,5 @@ SOUNDCLIP::SOUNDCLIP() { } SOUNDCLIP::~SOUNDCLIP() = default; + +} // namespace AGS3 diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index b26b41321c1a..a34bdf43a9ef 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -50,6 +50,8 @@ #include "util/stream.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -223,7 +225,8 @@ void play_flc_file(int numb, int playflags) { delete hicol_buf; hicol_buf = nullptr; // SetVirtualScreen(screen); wputblock(0,0,backbuffer,0); - while (ags_mgetbutton() != NONE) { } // clear any queued mouse events. + while (ags_mgetbutton() != NONE) { + } // clear any queued mouse events. invalidate_screen(); } @@ -232,7 +235,7 @@ void play_flc_file(int numb, int playflags) { // Theora player begin // TODO: find a way to take Bitmap here? Bitmap gl_TheoraBuffer; -int theora_playing_callback(BITMAP *theoraBuffer) { +int theora_playing_callback(BITMAP * theoraBuffer) { if (theoraBuffer == nullptr) { // No video, only sound return check_if_user_input_should_cancel_video(); @@ -250,7 +253,7 @@ int theora_playing_callback(BITMAP *theoraBuffer) { drawAtY = viewport.GetHeight() / 2 - fliTargetHeight / 2; if (!gfxDriver->HasAcceleratedTransform()) { fli_target->StretchBlt(&gl_TheoraBuffer, RectWH(0, 0, gl_TheoraBuffer.GetWidth(), gl_TheoraBuffer.GetHeight()), - RectWH(drawAtX, drawAtY, fliTargetWidth, fliTargetHeight)); + RectWH(drawAtX, drawAtY, fliTargetWidth, fliTargetHeight)); gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); drawAtX = 0; drawAtY = 0; @@ -290,7 +293,7 @@ void apeg_stream_skip(int bytes, void *ptr) { } // -APEG_STREAM *get_theora_size(Stream *video_stream, int *width, int *height) { +APEG_STREAM *get_theora_size(Stream * video_stream, int *width, int *height) { APEG_STREAM *oggVid = apeg_open_stream_ex(video_stream); if (oggVid != nullptr) { apeg_get_video_size(oggVid, width, height); @@ -393,8 +396,13 @@ void video_on_gfxmode_changed() { #else -void play_theora_video(const char *name, int skip, int flags) {} -void play_flc_file(int numb, int playflags) {} -void video_on_gfxmode_changed() {} +void play_theora_video(const char *name, int skip, int flags) { +} +void play_flc_file(int numb, int playflags) { +} +void video_on_gfxmode_changed() { +} #endif + +} // namespace AGS3 diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp index 83d3136bdaae..7ce56c4d18bc 100644 --- a/engines/ags/engine/platform/android/acpland.cpp +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -41,6 +41,8 @@ #include #include +namespace AGS3 { + using namespace AGS::Shared; #define ANDROID_CONFIG_FILENAME "android.cfg" @@ -725,4 +727,6 @@ AGSPlatformDriver *AGSPlatformDriver::GetDriver() { return instance; } +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index 79db1193d77c..ba78ed5a99ff 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -38,6 +38,8 @@ #include "ac/timer.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -55,25 +57,38 @@ AGSPlatformDriver *platform = nullptr; // ******** DEFAULT IMPLEMENTATIONS ******* -void AGSPlatformDriver::AboutToQuitGame() { } -void AGSPlatformDriver::PostAllegroInit(bool windowed) { } -void AGSPlatformDriver::AttachToParentConsole() { } -void AGSPlatformDriver::DisplaySwitchOut() { } -void AGSPlatformDriver::DisplaySwitchIn() { } -void AGSPlatformDriver::PauseApplication() { } -void AGSPlatformDriver::ResumeApplication() { } -void AGSPlatformDriver::GetSystemDisplayModes(std::vector &dms) { } +void AGSPlatformDriver::AboutToQuitGame() { +} +void AGSPlatformDriver::PostAllegroInit(bool windowed) { +} +void AGSPlatformDriver::AttachToParentConsole() { +} +void AGSPlatformDriver::DisplaySwitchOut() { +} +void AGSPlatformDriver::DisplaySwitchIn() { +} +void AGSPlatformDriver::PauseApplication() { +} +void AGSPlatformDriver::ResumeApplication() { +} +void AGSPlatformDriver::GetSystemDisplayModes(std::vector &dms) { +} bool AGSPlatformDriver::EnterFullscreenMode(const DisplayMode &dm) { return true; } bool AGSPlatformDriver::ExitFullscreenMode() { return true; } -void AGSPlatformDriver::AdjustWindowStyleForFullscreen() { } -void AGSPlatformDriver::AdjustWindowStyleForWindowed() { } -void AGSPlatformDriver::RegisterGameWithGameExplorer() { } -void AGSPlatformDriver::UnRegisterGameWithGameExplorer() { } -void AGSPlatformDriver::PlayVideo(const char *name, int skip, int flags) {} +void AGSPlatformDriver::AdjustWindowStyleForFullscreen() { +} +void AGSPlatformDriver::AdjustWindowStyleForWindowed() { +} +void AGSPlatformDriver::RegisterGameWithGameExplorer() { +} +void AGSPlatformDriver::UnRegisterGameWithGameExplorer() { +} +void AGSPlatformDriver::PlayVideo(const char *name, int skip, int flags) { +} const char *AGSPlatformDriver::GetAllegroFailUserHint() { return "Make sure you have latest version of Allegro 4 libraries installed, and your system is running in graphical mode."; @@ -149,7 +164,8 @@ int AGSPlatformDriver::ConvertKeycodeToScanCode(int keycode) { bool AGSPlatformDriver::LockMouseToWindow() { return false; } -void AGSPlatformDriver::UnlockMouse() { } +void AGSPlatformDriver::UnlockMouse() { +} //----------------------------------------------- // IOutputHandler implementation @@ -209,7 +225,7 @@ int cd_player_control(int cmdd, int datt) { cd_close(); else if (cmdd == 8) return numcddrives; - else if (cmdd == 9) ; + else if (cmdd == 9); else quit("!CDAudio: Unknown command code"); return 0; @@ -240,3 +256,5 @@ void AGSPlatformDriver::Delay(int millis) { now = AGS_Clock::now(); // update now } } + +} // namespace AGS3 diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp index 672a3b1a2099..56e80d2753c3 100644 --- a/engines/ags/engine/platform/ios/acplios.cpp +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -36,6 +36,8 @@ #include "plugin/agsplugin.h" #include "util/string_utils.h" +namespace AGS3 { + using namespace AGS::Shared; #define IOS_CONFIG_FILENAME "ios.cfg" @@ -624,4 +626,6 @@ AGSPlatformDriver *AGSPlatformDriver::GetDriver() { return instance; } +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 9c0ce818da8c..092d67a2e3d8 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -39,6 +39,8 @@ #include #include +namespace AGS3 { + using AGS::Shared::String; @@ -201,4 +203,6 @@ void AGSLinux::GetSystemDisplayModes(std::vector &dms) { destroy_gfx_mode_list(gmlist); } +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/osx/acplmac.cpp b/engines/ags/engine/platform/osx/acplmac.cpp index ef815cb945b1..449464d8bf95 100644 --- a/engines/ags/engine/platform/osx/acplmac.cpp +++ b/engines/ags/engine/platform/osx/acplmac.cpp @@ -39,6 +39,8 @@ #include "ac/common.h" #include "main/main.h" +namespace AGS3 { + void AGSMacInitPaths(char gamename[256], char appdata[PATH_MAX]); void AGSMacGetBundleDir(char gamepath[PATH_MAX]); //bool PlayMovie(char const *name, int skipType); @@ -148,4 +150,6 @@ AGSPlatformDriver *AGSPlatformDriver::GetDriver() { return instance; } +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index a0097e2793c2..00965b04f7c0 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -48,6 +48,8 @@ #include "util/string_compat.h" #include "media/audio/audio_system.h" +namespace AGS3 { + #ifndef AGS_NO_VIDEO_PLAYER extern void dxmedia_abort_video(); extern void dxmedia_pause_video(); @@ -1045,4 +1047,6 @@ LPDIRECTINPUTDEVICE IAGSEngine::GetDirectInputMouse() { return mouse_dinput_device; } +} // namespace AGS3 + #endif diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp index f2b22812bc5a..6985e435ae98 100644 --- a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp @@ -28,6 +28,8 @@ #include // sprintf +namespace AGS3 { + void NamedPipesAGSDebugger::SendAcknowledgement() { DWORD bytesWritten; WriteFile(_hPipeSending, "MSGACK", 6, &bytesWritten, NULL); @@ -50,7 +52,7 @@ bool NamedPipesAGSDebugger::Initialize() { _hPipeReading = CreateFile(pipeNameBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if ((_hPipeReading == INVALID_HANDLE_VALUE) || - (_hPipeSending == INVALID_HANDLE_VALUE)) + (_hPipeSending == INVALID_HANDLE_VALUE)) return false; return true; @@ -91,7 +93,8 @@ char *NamedPipesAGSDebugger::GetNextMessage() { } else { return NULL; } - } -#endif // AGS_PLATFORM_OS_WINDOWS +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index 2cfa9e090906..b7d06c1e358e 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -45,6 +45,8 @@ #include "platform/base/agsplatformdriver.h" #include "util/library.h" +namespace AGS3 { + #ifndef AGS_NO_VIDEO_PLAYER extern int dxmedia_play_video_3d(const char *filename, IDirect3DDevice9 *device, bool useAVISound, int canskip, int stretch); extern void dxmedia_shutdown_3d(); @@ -1866,5 +1868,6 @@ bool D3DGraphicsFactory::Init() { } // namespace D3D } // namespace Engine } // namespace AGS +} // namsepace AGS3 -#endif // AGS_PLATFORM_OS_WINDOWS +#endif diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp index 071b942b5f4f..1e17d09aec50 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -47,6 +47,8 @@ #include "main/game_run.h" #include "platform/base/agsplatformdriver.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Engine; @@ -435,4 +437,6 @@ int WINAPI WinMain( } #endif -#endif // AGS_PLATFORM_OS_WINDOWS +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp index c964e3412713..a22f02848de2 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -50,6 +50,8 @@ typedef float D3DVALUE, *LPD3DVALUE; //#include #include "media/audio/audio_system.h" +namespace AGS3 { + #define USES_CONVERSION int _convert = 0; _convert; UINT _acp = CP_ACP; _acp; LPCWSTR _lpw = NULL; _lpw; LPCSTR _lpa = NULL; _lpa inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp) { @@ -920,4 +922,6 @@ BOOL CVMR9Graph::SetLayerZOrder(int nLayer, DWORD dwZOrder) { return TRUE; } -#endif // AGS_PLATFORM_OS_WINDOWS +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/platform/windows/minidump.cpp b/engines/ags/engine/platform/windows/minidump.cpp index 8f6314817a54..6203f1eadcd1 100644 --- a/engines/ags/engine/platform/windows/minidump.cpp +++ b/engines/ags/engine/platform/windows/minidump.cpp @@ -29,6 +29,8 @@ #include #include "main/main.h" +namespace AGS3 { + CONTEXT cpustate; EXCEPTION_RECORD excinfo; int miniDumpResultCode = 0; @@ -112,4 +114,6 @@ int CustomExceptionHandler(LPEXCEPTION_POINTERS exinfo) { return EXCEPTION_EXECUTE_HANDLER; } +} // namespace AGS3 + #endif // AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG diff --git a/engines/ags/engine/platform/windows/setup/winsetup.cpp b/engines/ags/engine/platform/windows/setup/winsetup.cpp index 87a434406721..0b33435e221e 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.cpp +++ b/engines/ags/engine/platform/windows/setup/winsetup.cpp @@ -48,6 +48,8 @@ #include "util/file.h" #include "util/string_utils.h" +namespace AGS3 { + #define AL_ID(a,b,c,d) (((a)<<24) | ((b)<<16) | ((c)<<8) | (d)) #define DIGI_DIRECTAMX(n) AL_ID('A','X','A'+(n),' ') @@ -1156,5 +1158,6 @@ SetupReturnValue WinSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, } // namespace Engine } // namespace AGS +} // namespace AGS3 -#endif // AGS_PLATFORM_OS_WINDOWS +#endif diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index 7cf8f7688916..3f2e35bfeeb2 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -37,6 +37,8 @@ #define USE_CUSTOM_EXCEPTION_HANDLER #endif +namespace AGS3 { + using namespace AGS::Shared; extern int our_eip; @@ -96,4 +98,6 @@ void setup_malloc_handling() { printfworkingspace = (char *)malloc(7000); } +} // namespace AGS3 + #endif // AGS_PLATFORM_OS_WINDOWS diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index ee10afb53212..83133ab32afa 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -74,6 +74,8 @@ #include "util/filestream.h" #include "media/audio/audio_system.h" +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Shared::Memory; using namespace AGS::Engine; @@ -124,7 +126,7 @@ struct EnginePlugin { char filename[PLUGIN_FILENAME_MAX + 1]; AGS::Engine::Library library; bool available; - char *savedata; + char *savedata; int savedatasize; int wantHook; int invalidatedRegion; @@ -193,7 +195,7 @@ void IAGSEngine::RequestEventHook(int32 event) { quit("!IAGSEngine::RequestEventHook: no callback AGS_EngineOnEvent function exported from plugin"); if ((event & AGSE_SCRIPTDEBUG) && - ((plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG) == 0)) { + ((plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG) == 0)) { pluginsWantingDebugHooks++; ccSetDebugHook(scriptDebugHook); } @@ -211,7 +213,7 @@ void IAGSEngine::UnrequestEventHook(int32 event) { quit("!IAGSEngine::UnrequestEventHook: invalid event requested"); if ((event & AGSE_SCRIPTDEBUG) && - (plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG)) { + (plugins[this->pluginId].wantHook & AGSE_SCRIPTDEBUG)) { pluginsWantingDebugHooks--; if (pluginsWantingDebugHooks < 1) ccSetDebugHook(nullptr); @@ -564,7 +566,7 @@ void IAGSEngine::PlaySoundChannel(int32 channel, int32 soundType, int32 volume, SOUNDCLIP *newcha = nullptr; if (((soundType == PSND_MP3STREAM) || (soundType == PSND_OGGSTREAM)) - && (loop != 0)) + && (loop != 0)) quit("IAGSEngine::PlaySoundChannel: streamed samples cannot loop"); // TODO: find out how engine was supposed to decide on where to load the sound from @@ -725,7 +727,7 @@ void IAGSEngine::QueueGameScriptFunction(const char *name, int32 globalScript, i quit("IAGSEngine::QueueGameScriptFunction: invalid number of arguments"); curscript->run_another(name, globalScript ? kScInstGame : kScInstRoom, numArgs, - RuntimeScriptValue().SetPluginArgument(arg1), RuntimeScriptValue().SetPluginArgument(arg2)); + RuntimeScriptValue().SetPluginArgument(arg1), RuntimeScriptValue().SetPluginArgument(arg2)); } int IAGSEngine::RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback) { @@ -988,7 +990,7 @@ Engine::GameInitError pl_register_plugins(const std::vector // ".dll" extension appended; we need to take care of that const String name_ext = ".dll"; if (name.GetLength() <= name_ext.GetLength() || name.GetLength() > PLUGIN_FILENAME_MAX + name_ext.GetLength() || - name.CompareRightNoCase(name_ext, name_ext.GetLength())) { + name.CompareRightNoCase(name_ext, name_ext.GetLength())) { return kGameInitErr_PluginNameInvalid; } // remove ".dll" from plugin's name @@ -1026,7 +1028,7 @@ Engine::GameInitError pl_register_plugins(const std::vector apl->initGfxHook = (void(*)(const char *, void *))apl->library.GetFunctionAddress("AGS_EngineInitGfx"); } else { AGS::Shared::Debug::Printf(kDbgMsg_Info, "Plugin '%s' could not be loaded (expected '%s'), trying built-in plugins...", - apl->filename, expect_filename.GetCStr()); + apl->filename, expect_filename.GetCStr()); if (pl_use_builtin_plugin(apl)) { AGS::Shared::Debug::Printf(kDbgMsg_Info, "Build-in plugin '%s' found and being used.", apl->filename); } else { @@ -1065,3 +1067,5 @@ bool pl_any_want_hook(int event) { } return false; } + +} // namespace AGS3 diff --git a/engines/ags/engine/plugin/global_plugin.cpp b/engines/ags/engine/plugin/global_plugin.cpp index 0be249c80a66..52e66cd8f88d 100644 --- a/engines/ags/engine/plugin/global_plugin.cpp +++ b/engines/ags/engine/plugin/global_plugin.cpp @@ -31,6 +31,8 @@ #include "ac/mouse.h" #include "util/string_compat.h" +namespace AGS3 { + int pluginSimulatedClick = NONE; void PluginSimulateMouseClick(int pluginButtonID) { @@ -65,114 +67,114 @@ bool RegisterPluginStubs(const char *name) { // Stubs for plugin functions. bool is_agsteam = (ags_stricmp(name, "agsteam") == 0) || (ags_stricmp(name, "agsteam-unified") == 0) || - (ags_stricmp(name, "agsteam-disjoint") == 0); + (ags_stricmp(name, "agsteam-disjoint") == 0); bool is_agsgalaxy = (ags_stricmp(name, "agsgalaxy") == 0) || (ags_stricmp(name, "agsgalaxy-unified") == 0) || - (ags_stricmp(name, "agsgalaxy-disjoint") == 0); + (ags_stricmp(name, "agsgalaxy-disjoint") == 0); if (ags_stricmp(name, "ags_shell") == 0) { // ags_shell.dll - ccAddExternalStaticFunction("ShellExecute", Sc_PluginStub_Void); + ccAddExternalStaticFunction("ShellExecute", Sc_PluginStub_Void); return true; } else if (ags_stricmp(name, "ags_snowrain") == 0) { // ags_snowrain.dll - ccAddExternalStaticFunction("srSetSnowDriftRange", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowDriftSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowFallSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srChangeSnowAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowBaseline", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowTransparency", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowDefaultView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowWindSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetSnowView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srChangeRainAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainDefaultView", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainTransparency", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainWindSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainBaseline", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainAmount", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetRainFallSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetWindSpeed", Sc_PluginStub_Void); - ccAddExternalStaticFunction("srSetBaseline", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowDriftRange", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowDriftSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowFallSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srChangeSnowAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowBaseline", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowTransparency", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowDefaultView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetSnowView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srChangeRainAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainDefaultView", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainTransparency", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainBaseline", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainAmount", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetRainFallSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetWindSpeed", Sc_PluginStub_Void); + ccAddExternalStaticFunction("srSetBaseline", Sc_PluginStub_Void); return true; } else if (ags_stricmp(name, "agsjoy") == 0) { // agsjoy.dll - ccAddExternalStaticFunction("JoystickCount", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("JoystickName", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("JoystickRescan", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Open^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::IsOpen^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Click^1", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::Close^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::Valid^0", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Unplugged^0", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::GetName^0", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::GetAxis^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::IsButtonDown^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::IsJoyBtnDown^1", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Joystick::Update^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::DisableEvents^0", Sc_PluginStub_Void); - ccAddExternalStaticFunction("Joystick::EnableEvents^1", Sc_PluginStub_Void); + ccAddExternalStaticFunction("JoystickCount", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("JoystickName", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("JoystickRescan", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Open^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsOpen^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Click^1", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::Close^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::Valid^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Unplugged^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::GetName^0", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::GetAxis^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsButtonDown^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::IsJoyBtnDown^1", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Joystick::Update^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::DisableEvents^0", Sc_PluginStub_Void); + ccAddExternalStaticFunction("Joystick::EnableEvents^1", Sc_PluginStub_Void); return true; } else if (ags_stricmp(name, "agsblend") == 0) { // agsblend.dll - ccAddExternalStaticFunction("DrawAlpha", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetAlpha", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("PutAlpha", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("Blur", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("HighPass", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("DrawAdd", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("DrawAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("PutAlpha", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("Blur", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("HighPass", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("DrawAdd", Sc_PluginStub_Int0); return true; } else if (ags_stricmp(name, "agsflashlight") == 0) { // agsflashlight.dll - ccAddExternalStaticFunction("SetFlashlightTint", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightTintRed", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightTintGreen", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightTintBlue", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightMinLightLevel", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightMaxLightLevel", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightDarkness", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightDarkness", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightDarknessSize", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightDarknessSize", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightBrightness", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightBrightness", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightBrightnessSize", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightBrightnessSize", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightPosition", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightPositionX", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightPositionY", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightFollowMouse", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightFollowMouse", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightTint", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightTintRed", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightTintGreen", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightTintBlue", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightMinLightLevel", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightMaxLightLevel", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightDarkness", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightDarkness", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightDarknessSize", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightDarknessSize", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightBrightness", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightBrightness", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightBrightnessSize", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightBrightnessSize", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightPosition", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightPositionX", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightPositionY", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightFollowMouse", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightFollowMouse", Sc_PluginStub_Int0); ccAddExternalStaticFunction("SetFlashlightFollowCharacter", Sc_PluginStub_Void); ccAddExternalStaticFunction("GetFlashlightFollowCharacter", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterDX", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterDY", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterHorz", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("GetFlashlightCharacterVert", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("SetFlashlightMask", Sc_PluginStub_Void); - ccAddExternalStaticFunction("GetFlashlightMask", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterDX", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterDY", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterHorz", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("GetFlashlightCharacterVert", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("SetFlashlightMask", Sc_PluginStub_Void); + ccAddExternalStaticFunction("GetFlashlightMask", Sc_PluginStub_Int0); return true; } else if (ags_stricmp(name, "agswadjetutil") == 0) { // agswadjetutil.dll - ccAddExternalStaticFunction("IsOnPhone", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("FakeKeypress", Sc_PluginStub_Void); - ccAddExternalStaticFunction("IosSetAchievementValue", Sc_PluginStub_Void); - ccAddExternalStaticFunction("IosGetAchievementValue", Sc_PluginStub_IntNeg1); - ccAddExternalStaticFunction("IosShowAchievements", Sc_PluginStub_Void); - ccAddExternalStaticFunction("IosResetAchievements", Sc_PluginStub_Void); - ccAddExternalStaticFunction("MobileGetAchievement", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("MobileSetAchievement", Sc_PluginStub_Int0); - ccAddExternalStaticFunction("MobileShowAchievements", Sc_PluginStub_Void); - ccAddExternalStaticFunction("MobileResetAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IsOnPhone", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("FakeKeypress", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosSetAchievementValue", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosGetAchievementValue", Sc_PluginStub_IntNeg1); + ccAddExternalStaticFunction("IosShowAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("IosResetAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("MobileGetAchievement", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("MobileSetAchievement", Sc_PluginStub_Int0); + ccAddExternalStaticFunction("MobileShowAchievements", Sc_PluginStub_Void); + ccAddExternalStaticFunction("MobileResetAchievements", Sc_PluginStub_Void); return true; } else if (ags_stricmp(name, "agsspritefont") == 0) { - ccAddExternalStaticFunction("SetSpriteFont", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetVariableSpriteFont", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetGlyph", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetSpacing", Sc_PluginStub_Void); - ccAddExternalStaticFunction("SetLineHeightAdjust", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetSpriteFont", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetVariableSpriteFont", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetGlyph", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetSpacing", Sc_PluginStub_Void); + ccAddExternalStaticFunction("SetLineHeightAdjust", Sc_PluginStub_Void); return true; } else if (is_agsteam || is_agsgalaxy) { // agsteam.dll or agsgalaxy.dll @@ -245,3 +247,5 @@ bool RegisterPluginStubs(const char *name) { return false; } + +} // namespace AGS3 diff --git a/engines/ags/engine/plugin/pluginobjectreader.cpp b/engines/ags/engine/plugin/pluginobjectreader.cpp index 7cf0d2b8b011..c5d387dd12b2 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.cpp +++ b/engines/ags/engine/plugin/pluginobjectreader.cpp @@ -23,5 +23,9 @@ #include "plugin/pluginobjectreader.h" #include "ac/runtime_defines.h" +namespace AGS3 { + PluginObjectReader pluginReaders[MAX_PLUGIN_OBJECT_READERS]; int numPluginReaders = 0; + +} // namespace AGS3 diff --git a/engines/ags/engine/script/cc_error_engine.cpp b/engines/ags/engine/script/cc_error_engine.cpp deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index 88038dc3127f..ef4b9dd643ca 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -46,6 +46,8 @@ #include "util/memory.h" #include "util/string_utils.h" // linux strnicmp definition +namespace AGS3 { + using namespace AGS::Shared; using namespace AGS::Shared::Memory; @@ -1819,3 +1821,5 @@ void ccInstance::PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t func_callstack.Head += num_entries; func_callstack.Count -= num_entries; } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/executingscript.cpp b/engines/ags/engine/script/executingscript.cpp index 41d8f87a17cc..3b977b517b5d 100644 --- a/engines/ags/engine/script/executingscript.cpp +++ b/engines/ags/engine/script/executingscript.cpp @@ -25,6 +25,8 @@ #include "debug/debug_log.h" #include "debug/debugger.h" +namespace AGS3 { + QueuedScript::QueuedScript() : Instance(kScInstGame) , ParamCount(0) { @@ -44,10 +46,10 @@ int ExecutingScript::queue_action(PostScriptAction act, int data, const char *an case ePSARunAGSGame: case ePSARestartGame: quitprintf("!%s: Cannot run this command, since there was a %s command already queued to run in \"%s\", line %d", - aname, postScriptActionNames[numPostScriptActions - 1], - postScriptActionPositions[numPostScriptActions - 1].Section.GetCStr(), postScriptActionPositions[numPostScriptActions - 1].Line); + aname, postScriptActionNames[numPostScriptActions - 1], + postScriptActionPositions[numPostScriptActions - 1].Section.GetCStr(), postScriptActionPositions[numPostScriptActions - 1].Line); break; - // MACPORT FIX 9/6/5: added default clause to remove warning + // MACPORT FIX 9/6/5: added default clause to remove warning default: break; } @@ -93,3 +95,5 @@ void ExecutingScript::init() { ExecutingScript::ExecutingScript() { init(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/exports.cpp b/engines/ags/engine/script/exports.cpp index ce217931c2d7..3d067b951806 100644 --- a/engines/ags/engine/script/exports.cpp +++ b/engines/ags/engine/script/exports.cpp @@ -28,6 +28,8 @@ #include "ac/gamestructdefines.h" +namespace AGS3 { + extern void RegisterAudioChannelAPI(); extern void RegisterAudioClipAPI(); extern void RegisterButtonAPI(); @@ -105,3 +107,5 @@ void setup_script_exports(ScriptAPIVersion base_api, ScriptAPIVersion compat_api RegisterStaticObjects(); } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/runtimescriptvalue.cpp b/engines/ags/engine/script/runtimescriptvalue.cpp index ebcac94e8fbc..97f208099a38 100644 --- a/engines/ags/engine/script/runtimescriptvalue.cpp +++ b/engines/ags/engine/script/runtimescriptvalue.cpp @@ -28,6 +28,8 @@ #include // for memcpy() +namespace AGS3 { + using namespace AGS::Shared; // @@ -225,8 +227,8 @@ intptr_t RuntimeScriptValue::GetDirectPtr() const { const RuntimeScriptValue *temp_val = this; int ival = temp_val->IValue; if (temp_val->Type == kScValGlobalVar || temp_val->Type == kScValStackPtr) { - temp_val = temp_val->RValue; - ival += temp_val->IValue; + temp_val = temp_val->RValue; + ival += temp_val->IValue; } if (temp_val->Type == kScValDynamicObject) return (intptr_t)temp_val->DynMgr->GetFieldPtr(temp_val->Ptr, ival); @@ -235,3 +237,5 @@ intptr_t RuntimeScriptValue::GetDirectPtr() const { else return (intptr_t)(temp_val->Ptr + ival); } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp index ec59cc6a778c..52ddbdcff3cb 100644 --- a/engines/ags/engine/script/script.cpp +++ b/engines/ags/engine/script/script.cpp @@ -52,6 +52,8 @@ #include "util/string_compat.h" #include "media/audio/audio_system.h" +namespace AGS3 { + extern GameSetupStruct game; extern GameState play; extern int gameHasBeenRestored, displayed_room; @@ -160,13 +162,13 @@ void run_function_on_non_blocking_thread(NonBlockingScriptFunction *funcToRun) { int run_interaction_event(Interaction *nint, int evnt, int chkAny, int isInv) { if (evnt < 0 || (size_t)evnt >= nint->Events.size() || - (nint->Events[evnt].Response.get() == nullptr) || (nint->Events[evnt].Response->Cmds.size() == 0)) { + (nint->Events[evnt].Response.get() == nullptr) || (nint->Events[evnt].Response->Cmds.size() == 0)) { // no response defined for this event // If there is a response for "Any Click", then abort now so as to // run that instead - if (chkAny < 0) ; + if (chkAny < 0); else if ((size_t)chkAny < nint->Events.size() && - (nint->Events[chkAny].Response.get() != nullptr) && (nint->Events[chkAny].Response->Cmds.size() > 0)) + (nint->Events[chkAny].Response.get() != nullptr) && (nint->Events[chkAny].Response->Cmds.size() > 0)) return 0; // Otherwise, run unhandled_event @@ -200,7 +202,7 @@ int run_interaction_script(InteractionScripts *nint, int evnt, int chkAny, int i // no response defined for this event // If there is a response for "Any Click", then abort now so as to // run that instead - if (chkAny < 0) ; + if (chkAny < 0); else if ((nint->ScriptFuncNames[chkAny] != nullptr) && (nint->ScriptFuncNames[chkAny][0u] != 0)) return 0; @@ -438,7 +440,7 @@ int RunTextScript(ccInstance *sci, const char *tsname) { RunScriptFunctionIfExists(moduleInst[kk], tsname, 0, nullptr); if ((room_changes_was != play.room_changes) || - (restore_game_count_was != gameHasBeenRestored)) + (restore_game_count_was != gameHasBeenRestored)) return 0; } } @@ -672,7 +674,8 @@ int run_interaction_commandlist(InteractionCommandList *nicl, int *timesrun, int switch (nicl->Cmds[i].Type) { case 0: // Do nothing break; - case 1: { // Run script + case 1: + { // Run script TempEip tempip(4001); RuntimeScriptValue rval_null; update_polled_mp3(); @@ -713,7 +716,8 @@ int run_interaction_commandlist(InteractionCommandList *nicl, int *timesrun, int case 8: // Play Flic play_flc_file(IPARAM1, IPARAM2); break; - case 9: { // Run Dialog + case 9: + { // Run Dialog int room_was = play.room_changes; RunDialog(IPARAM1); // if they changed room within the dialog script, @@ -903,11 +907,13 @@ void run_unhandled_event(int evnt) { evtype = 4; if ((evtype == 1) & ((evnt == 0) | (evnt == 5) | (evnt == 6))) ; // character stands on hotspot, mouse moves over hotspot, any click - else if ((evtype == 2) & (evnt == 4)) ; // any click on object - else if ((evtype == 3) & (evnt == 4)) ; // any click on character + else if ((evtype == 2) & (evnt == 4)); // any click on object + else if ((evtype == 3) & (evnt == 4)); // any click on character else if (evtype > 0) { can_run_delayed_command(); QueueScriptFunction(kScInstGame, "unhandled_event", 2, RuntimeScriptValue().SetInt32(evtype), RuntimeScriptValue().SetInt32(evnt)); } } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp index 411da69bb3c0..da410e1389eb 100644 --- a/engines/ags/engine/script/script_api.cpp +++ b/engines/ags/engine/script/script_api.cpp @@ -28,6 +28,8 @@ #include "script/script_api.h" #include "util/math.h" +namespace AGS3 { + namespace Math = AGS::Shared::Math; enum FormatParseResult { @@ -71,7 +73,7 @@ inline const char *GetArgPtr(const RuntimeScriptValue *sc_args, va_list *varg_pt // snprintf but formatting values ourselves, or by using some library method // that supports customizing, such as getting arguments in a custom way. const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, - const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr) { + const RuntimeScriptValue *sc_args, int32_t sc_argc, va_list *varg_ptr) { if (!buffer || buf_length == 0) { cc_error("Internal error in ScriptSprintf: buffer is null"); return ""; @@ -99,14 +101,14 @@ const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, // number, such case is theoretically valid. const size_t fmtbuf_size = 27; char fmtbuf[fmtbuf_size]; - char *fmt_bufptr; - char *fmt_bufendptr = &fmtbuf[fmtbuf_size - 1]; + char *fmt_bufptr; + char *fmt_bufendptr = &fmtbuf[fmtbuf_size - 1]; - char *out_ptr = buffer; + char *out_ptr = buffer; // save 1 character for null terminator const char *out_endptr = buffer + buf_length - 1; - const char *fmt_ptr = format; - int32_t arg_idx = 0; + const char *fmt_ptr = format; + int32_t arg_idx = 0; ptrdiff_t avail_outbuf; int snprintf_res; @@ -172,7 +174,7 @@ const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, *(out_ptr++) = '%'; continue; } else if (fmt_done >= kFormatParseArgFirst && fmt_done <= kFormatParseArgLast && - (varg_ptr || arg_idx < sc_argc)) { + (varg_ptr || arg_idx < sc_argc)) { // Print the actual value // NOTE: snprintf is called with avail_outbuf + 1 here, because we let it use our reserved // character for null-terminator, in case we are at the end of the buffer @@ -224,3 +226,5 @@ const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format, *out_ptr = 0; return buffer; } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/script_engine.cpp b/engines/ags/engine/script/script_engine.cpp index 3d22a27aad83..892b957ee07f 100644 --- a/engines/ags/engine/script/script_engine.cpp +++ b/engines/ags/engine/script/script_engine.cpp @@ -37,11 +37,14 @@ #include "util/file.h" #include "util/stream.h" +namespace AGS3 { + namespace AGS { namespace Shared { class RoomStruct; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS::Shared; extern void quit(const char *); @@ -59,3 +62,5 @@ std::pair cc_error_at_line(const char *error_msg) { String cc_error_without_line(const char *error_msg) { return String::FromFormat("Runtime error: %s", error_msg); } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp index 014c86c16cfd..d6eeeb827ad8 100644 --- a/engines/ags/engine/script/script_runtime.cpp +++ b/engines/ags/engine/script/script_runtime.cpp @@ -45,6 +45,8 @@ #include "script/systemimports.h" #include "ac/statobj/staticobject.h" +namespace AGS3 { + extern ccInstance *current_instance; // in script/cc_instance bool ccAddExternalStaticFunction(const String &name, ScriptAPIFunction *pfn) { @@ -83,10 +85,10 @@ void ccRemoveAllSymbols() { simp.clear(); } -ccInstance *loadedInstances[MAX_LOADED_INSTANCES] = {nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr - }; +ccInstance *loadedInstances[MAX_LOADED_INSTANCES] = { nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; void nullfree(void *data) { if (data != nullptr) @@ -209,52 +211,62 @@ int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, // switch (numparm) { - case 0: { + case 0: + { int (*fparam)(); fparam = (int (*)())addr; return fparam(); } - case 1: { + case 1: + { int (*fparam)(intptr_t); fparam = (int (*)(intptr_t))addr; return fparam(parm_value[0]); } - case 2: { + case 2: + { int (*fparam)(intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1]); } - case 3: { + case 3: + { int (*fparam)(intptr_t, intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1], parm_value[2]); } - case 4: { + case 4: + { int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3]); } - case 5: { + case 5: + { int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4]); } - case 6: { + case 6: + { int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5]); } - case 7: { + case 7: + { int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6]); } - case 8: { + case 8: + { int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7]); } - case 9: { + case 9: + { int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7], parm_value[8]); @@ -264,3 +276,5 @@ int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, cc_error("too many arguments in call to function"); return -1; } + +} // namespace AGS3 diff --git a/engines/ags/engine/script/systemimports.cpp b/engines/ags/engine/script/systemimports.cpp index 67a06b78360f..1912f111a86c 100644 --- a/engines/ags/engine/script/systemimports.cpp +++ b/engines/ags/engine/script/systemimports.cpp @@ -24,6 +24,7 @@ #include #include "script/systemimports.h" +namespace AGS3 { extern void quit(const char *); @@ -53,9 +54,9 @@ int SystemImports::add(const String &name, const RuntimeScriptValue &value, ccIn btree[name] = ixof; if (ixof == imports.size()) imports.push_back(ScriptImport()); - imports[ixof].Name = name; // TODO: rather make a string copy here for safety reasons - imports[ixof].Value = value; - imports[ixof].InstancePtr = anotherscr; + imports[ixof].Name = name; // TODO: rather make a string copy here for safety reasons + imports[ixof].Value = value; + imports[ixof].InstancePtr = anotherscr; return 0; } @@ -129,3 +130,5 @@ void SystemImports::clear() { btree.clear(); imports.clear(); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/audiocliptype.cpp b/engines/ags/shared/ac/audiocliptype.cpp index f668c6b40b37..d71acd72c2f8 100644 --- a/engines/ags/shared/ac/audiocliptype.cpp +++ b/engines/ags/shared/ac/audiocliptype.cpp @@ -23,6 +23,8 @@ #include "ac/audiocliptype.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; void AudioClipType::ReadFromFile(Stream *in) { @@ -50,3 +52,5 @@ void AudioClipType::WriteToSavegame(Common::Stream *out) const { out->WriteInt32(volume_reduction_while_speech_playing); out->WriteInt32(crossfadeSpeed); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/characterinfo.cpp b/engines/ags/shared/ac/characterinfo.cpp index 6a3deb6a73f6..a6572e8d020f 100644 --- a/engines/ags/shared/ac/characterinfo.cpp +++ b/engines/ags/shared/ac/characterinfo.cpp @@ -24,6 +24,8 @@ #include "ac/characterinfo.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; @@ -159,3 +161,5 @@ void ConvertOldCharacterToNew(OldCharacterInfo *oci, CharacterInfo *ci) { ci->talkcolor = (oci->flags & OCHF_SPEECHCOL) >> OCHF_SPEECHCOLSHIFT; ci->flags = ci->flags & (~OCHF_SPEECHCOL); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index 156703bf19c7..74a9b6cb9d3b 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -23,6 +23,8 @@ #include "ac/common.h" #include "util/string.h" +namespace AGS3 { + using namespace AGS::Shared; const char *game_file_sig = "Adventure Creator Game File v2"; @@ -34,3 +36,5 @@ void quitprintf(const char *fmt, ...) { va_end(ap); quit(text); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/dialogtopic.cpp b/engines/ags/shared/ac/dialogtopic.cpp index f4ffdc0797ba..ac185000e3e6 100644 --- a/engines/ags/shared/ac/dialogtopic.cpp +++ b/engines/ags/shared/ac/dialogtopic.cpp @@ -23,6 +23,8 @@ #include "ac/dialogtopic.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; void DialogTopic::ReadFromFile(Stream *in) { @@ -45,3 +47,5 @@ void DialogTopic::ReadFromSavegame(Common::Stream *in) { void DialogTopic::WriteToSavegame(Common::Stream *out) const { out->WriteArrayOfInt32(optionflags, MAXTOPICOPTIONS); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp index a2b90d6f7ba5..4bee23fe7cc5 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp @@ -23,6 +23,8 @@ #include "ac/dynobj/scriptaudioclip.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; void ScriptAudioClip::ReadFromFile(Stream *in) { @@ -37,3 +39,5 @@ void ScriptAudioClip::ReadFromFile(Stream *in) { defaultVolume = in->ReadInt16(); in->ReadInt32(); // reserved } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp index e94ac5e4164b..970b8bc99795 100644 --- a/engines/ags/shared/ac/gamesetupstruct.cpp +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -28,6 +28,8 @@ #include "game/interactions.h" #include "util/alignedstream.h" +namespace AGS3 { + using namespace AGS::Shared; GameSetupStruct::GameSetupStruct() @@ -138,7 +140,7 @@ void GameSetupStruct::read_font_infos(Common::Stream *in, GameDataVersion data_v if (data_ver >= kGameVersion_351) { fonts[i].AutoOutlineThickness = in->ReadInt32(); fonts[i].AutoOutlineStyle = - static_cast(in->ReadInt32()); + static_cast(in->ReadInt32()); } } } @@ -247,7 +249,7 @@ void GameSetupStruct::read_messages(Common::Stream *in, GameDataVersion data_ver } else read_string_decrypt(in, messages[ee], GLOBALMESLENGTH); } - delete [] load_messages; + delete[] load_messages; load_messages = nullptr; } @@ -349,7 +351,7 @@ void GameSetupStruct::ReadAudioClips_Aligned(Common::Stream *in, size_t count) { } void GameSetupStruct::ReadFromSaveGame_v321(Stream *in, char *gswas, ccScript *compsc, CharacterInfo *chwas, - WordsDictionary *olddict, char **mesbk) { + WordsDictionary *olddict, char **mesbk) { int bb; ReadInvInfo_Aligned(in); @@ -382,7 +384,7 @@ void ConvertOldGameStruct(OldGameSetupStruct *ogss, GameSetupStruct *gss) { for (int i = 0; i < 20; i++) gss->options[i] = ogss->options[i]; memcpy(&gss->paluses[0], &ogss->paluses[0], 256); - memcpy(&gss->defpal[0], &ogss->defpal[0], 256 * sizeof(color)); + memcpy(&gss->defpal[0], &ogss->defpal[0], 256 * sizeof(color)); gss->numviews = ogss->numviews; gss->numcharacters = ogss->numcharacters; gss->playercharacter = ogss->playercharacter; @@ -443,3 +445,5 @@ void GameSetupStruct::WriteForSavegame(PStream out) { out->WriteInt32(invhotdotsprite); out->WriteInt32(default_lipsync_frame); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp index cd1caef3605b..9781d3a4a55d 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.cpp +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -27,6 +27,8 @@ #include "script/cc_script.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; GameSetupStructBase::GameSetupStructBase() @@ -251,3 +253,5 @@ Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox) { } return Size(); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/inventoryiteminfo.cpp b/engines/ags/shared/ac/inventoryiteminfo.cpp index 0a34dbaa8fbe..3311180c2a8a 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.cpp +++ b/engines/ags/shared/ac/inventoryiteminfo.cpp @@ -24,6 +24,8 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { + using namespace AGS::Shared; void InventoryItemInfo::ReadFromFile(Stream *in) { @@ -57,3 +59,5 @@ void InventoryItemInfo::WriteToSavegame(Stream *out) const { out->WriteInt32(pic); out->WriteInt32(cursorPic); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/mousecursor.cpp b/engines/ags/shared/ac/mousecursor.cpp index 86548b29721c..01f9323b92ef 100644 --- a/engines/ags/shared/ac/mousecursor.cpp +++ b/engines/ags/shared/ac/mousecursor.cpp @@ -23,6 +23,8 @@ #include "ac/mousecursor.h" #include "util/stream.h" +namespace AGS3 { + using AGS::Shared::Stream; MouseCursor::MouseCursor() { @@ -67,3 +69,5 @@ void MouseCursor::WriteToSavegame(Stream *out) const { out->WriteInt32(view); out->WriteInt32(flags); } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp index 178d9ebf655a..592c6665d739 100644 --- a/engines/ags/shared/ac/spritecache.cpp +++ b/engines/ags/shared/ac/spritecache.cpp @@ -42,6 +42,8 @@ #include "util/file.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; // [IKM] We have to forward-declare these because their implementations are in the Engine @@ -219,7 +221,7 @@ sprkey_t SpriteCache::GetFreeIndex() { bool SpriteCache::SpriteData::DoesSpriteExist() const { return (Image != nullptr) || // HAS loaded bitmap - ((Flags & SPRCACHEFLAG_ISASSET) != 0); // OR found in the game resources + ((Flags & SPRCACHEFLAG_ISASSET) != 0); // OR found in the game resources } bool SpriteCache::SpriteData::IsAssetSprite() const { @@ -228,8 +230,8 @@ bool SpriteCache::SpriteData::IsAssetSprite() const { bool SpriteCache::SpriteData::IsExternalSprite() const { return (Image != nullptr) && // HAS loaded bitmap - ((Flags & SPRCACHEFLAG_ISASSET) == 0) && // AND NOT found in game resources - ((Flags & SPRCACHEFLAG_REMAPPED) == 0); // AND was NOT remapped to another sprite + ((Flags & SPRCACHEFLAG_ISASSET) == 0) && // AND NOT found in game resources + ((Flags & SPRCACHEFLAG_REMAPPED) == 0); // AND was NOT remapped to another sprite } bool SpriteCache::SpriteData::IsLocked() const { @@ -323,7 +325,7 @@ void SpriteCache::DisposeOldest() { // There must be a bug somewhere causing this, but for now // let's just reset the cache Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: CACHE INCONSISTENT: RESETTING\n\tAt size %d (of %d), start %d end %d fwdlink=%d", - _cacheSize, _maxCacheSize, oldstart, _listend, _liststart); + _cacheSize, _maxCacheSize, oldstart, _listend, _liststart); DisposeAll(); } } @@ -338,7 +340,7 @@ void SpriteCache::DisposeAll() { _listend = -1; for (size_t i = 0; i < _spriteData.size(); ++i) { if (!_spriteData[i].IsLocked() && // not locked - _spriteData[i].IsAssetSprite()) { // sprite from game resource + _spriteData[i].IsAssetSprite()) { // sprite from game resource delete _spriteData[i].Image; _spriteData[i].Image = nullptr; } @@ -602,7 +604,7 @@ int SpriteCache::SaveToFile(const char *filename, bool compressOutput, SpriteFil if (this->_compressed != compressOutput) { // shouldn't be able to get here - delete [] memBuffer; + delete[] memBuffer; delete output; return -2; } @@ -635,7 +637,7 @@ int SpriteCache::SaveToFile(const char *filename, bool compressOutput, SpriteFil output->WriteArray(memBuffer, sizeToCopy, 1); } - delete [] memBuffer; + delete[] memBuffer; delete output; index.SpriteFileIDCheck = spriteFileIDCheck; @@ -840,9 +842,9 @@ bool SpriteCache::LoadSpriteIndexFile(const char *filename, int expectedFileID, } } - delete [] rspritewidths; - delete [] rspriteheights; - delete [] spriteoffs; + delete[] rspritewidths; + delete[] rspriteheights; + delete[] spriteoffs; delete fidx; return true; } @@ -862,3 +864,5 @@ int SpriteCache::AttachFile(const char *filename) { bool SpriteCache::IsFileCompressed() const { return _compressed; } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/view.cpp b/engines/ags/shared/ac/view.cpp index e6299ebf5485..d9ef44ff663a 100644 --- a/engines/ags/shared/ac/view.cpp +++ b/engines/ags/shared/ac/view.cpp @@ -24,6 +24,8 @@ #include "ac/view.h" #include "util/alignedstream.h" +namespace AGS3 { + using AGS::Shared::AlignedStream; using AGS::Shared::Stream; @@ -177,7 +179,7 @@ void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *ne newv[a].loops[b].Initialize(oldv[a].numframes[b]); if ((oldv[a].numframes[b] > 0) && - (oldv[a].frames[b][oldv[a].numframes[b] - 1].pic == -1)) { + (oldv[a].frames[b][oldv[a].numframes[b] - 1].pic == -1)) { newv[a].loops[b].flags = LOOPFLAG_RUNNEXTLOOP; newv[a].loops[b].numFrames--; } else @@ -188,3 +190,5 @@ void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *ne } } } + +} // namespace AGS3 diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp index 2cddfd73b54a..5f7d1381d518 100644 --- a/engines/ags/shared/ac/wordsdictionary.cpp +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -26,6 +26,8 @@ #include "util/stream.h" #include "util/string_compat.h" +namespace AGS3 { + using AGS::Shared::Stream; WordsDictionary::WordsDictionary() @@ -52,9 +54,9 @@ void WordsDictionary::allocate_memory(int wordCount) { void WordsDictionary::free_memory() { if (num_words > 0) { - delete [] word[0]; - delete [] word; - delete [] wordnum; + delete[] word[0]; + delete[] word; + delete[] wordnum; word = nullptr; wordnum = nullptr; num_words = 0; @@ -66,7 +68,7 @@ void WordsDictionary::sort() { for (aa = 0; aa < num_words; aa++) { for (bb = aa + 1; bb < num_words; bb++) { if (((wordnum[aa] == wordnum[bb]) && (ags_stricmp(word[aa], word[bb]) > 0)) - || (wordnum[aa] > wordnum[bb])) { + || (wordnum[aa] > wordnum[bb])) { short temp = wordnum[aa]; char tempst[30]; @@ -172,3 +174,5 @@ void write_dictionary(WordsDictionary *dict, Stream *out) { out->WriteInt16(dict->wordnum[ii]);//__putshort__lilendian(dict->wordnum[ii], writeto); } } + +} // namespace AGS3 diff --git a/engines/ags/shared/core/asset.cpp b/engines/ags/shared/core/asset.cpp index ce99ec561521..7c34675faf4f 100644 --- a/engines/ags/shared/core/asset.cpp +++ b/engines/ags/shared/core/asset.cpp @@ -22,6 +22,7 @@ #include "core/asset.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -39,3 +40,4 @@ void AssetLibInfo::Unload() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp index 1fe72e47975b..3017592cb10b 100644 --- a/engines/ags/shared/core/assetmanager.cpp +++ b/engines/ags/shared/core/assetmanager.cpp @@ -26,7 +26,7 @@ #include "util/path.h" #include "util/string_utils.h" - +namespace AGS3 { namespace AGS { namespace Shared { @@ -145,8 +145,8 @@ AssetError AssetManager::ReadDataFileTOC(const String &data_file, AssetLibInfo & } /* static */ Stream *AssetManager::OpenAsset(const String &asset_name, - FileOpenMode open_mode, - FileWorkMode work_mode) { + FileOpenMode open_mode, + FileWorkMode work_mode) { assert(_theAssetManager != NULL); if (!_theAssetManager) { return nullptr; @@ -240,7 +240,7 @@ const AssetLibInfo &AssetManager::_GetLibraryTOC() const { bool AssetManager::_DoesAssetExist(const String &asset_name) { return FindAssetByFileName(asset_name) != nullptr || - File::TestReadFile(asset_name); + File::TestReadFile(asset_name); } AssetError AssetManager::RegisterAssetLib(const String &data_file, const String &password) { @@ -330,11 +330,11 @@ bool AssetManager::GetAssetByPriority(const String &asset_name, AssetLocation &l if (_searchPriority == kAssetPriorityDir) { // check for disk, otherwise use datafile return GetAssetFromDir(asset_name, loc, open_mode, work_mode) || - GetAssetFromLib(asset_name, loc, open_mode, work_mode); + GetAssetFromLib(asset_name, loc, open_mode, work_mode); } else if (_searchPriority == kAssetPriorityLib) { // check datafile first, then scan directory return GetAssetFromLib(asset_name, loc, open_mode, work_mode) || - GetAssetFromDir(asset_name, loc, open_mode, work_mode); + GetAssetFromDir(asset_name, loc, open_mode, work_mode); } return false; } @@ -369,3 +369,4 @@ String GetAssetErrorText(AssetError err) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp index 180e06c97f68..69800cc25fd6 100644 --- a/engines/ags/shared/debugging/debugmanager.cpp +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -24,6 +24,7 @@ #include "debug/debugmanager.h" #include "util/string_types.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -88,7 +89,7 @@ void DebugOutput::ResolveGroupID(DebugGroupID id) { } } -bool DebugOutput::TestGroup(DebugGroupID id, MessageType mt) const { +bool DebugOutput::TestGroup(DebugGroupID id, MessageType mt) const { DebugGroupID real_id = DbgMgr.GetGroup(id).UID; if (real_id.ID == kDbgGroup_None || real_id.ID >= _groupFilter.size()) return false; @@ -224,5 +225,6 @@ void Printf(DebugGroupID group, MessageType mt, const char *fmt, ...) { } // namespace Debug -} // namespace Shared -} // namespace AGS +} // namespace Shared +} // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 77493dd202d3..6acbebd152da 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -32,6 +32,8 @@ #include "gui/guidefines.h" // MAXLINE #include "util/string_utils.h" +namespace AGS3 { + #define STD_BUFFER_SIZE 3000 using namespace AGS::Shared; @@ -40,8 +42,8 @@ namespace AGS { namespace Shared { struct Font { - IAGSFontRenderer *Renderer; - IAGSFontRenderer2 *Renderer2; + IAGSFontRenderer *Renderer; + IAGSFontRenderer2 *Renderer2; FontInfo Info; Font(); @@ -327,10 +329,10 @@ bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) { params.SizeMultiplier = font_info.SizeMultiplier; if (ttfRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) { - fonts[fontNumber].Renderer = &ttfRenderer; + fonts[fontNumber].Renderer = &ttfRenderer; fonts[fontNumber].Renderer2 = &ttfRenderer; } else if (wfnRenderer.LoadFromDiskEx(fontNumber, font_info.SizePt, ¶ms)) { - fonts[fontNumber].Renderer = &wfnRenderer; + fonts[fontNumber].Renderer = &wfnRenderer; fonts[fontNumber].Renderer2 = &wfnRenderer; } @@ -371,3 +373,5 @@ void free_all_fonts() { } fonts.clear(); } + +} // namespace AGS3 diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp index 73ec388d239e..6dfc35161cd6 100644 --- a/engines/ags/shared/font/ttffontrenderer.cpp +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -34,6 +34,8 @@ #include "font/fonts.h" #endif +namespace AGS3 { + using namespace AGS::Shared; // project-specific implementation @@ -119,7 +121,7 @@ bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRen // A simple workaround is to disable outline fonts for it and use // automatic outline drawing. if (get_font_outline(fontNumber) >= 0 && - strcmp(alfont_get_name(alfptr), "LucasFan-Font") == 0) + strcmp(alfont_get_name(alfptr), "LucasFan-Font") == 0) set_font_outline(fontNumber, FONT_OUTLINE_AUTO); #endif if (fontSize == 0) @@ -138,3 +140,5 @@ void TTFFontRenderer::FreeMemory(int fontNumber) { alfont_destroy_font(_fontData[fontNumber].AlFont); _fontData.erase(fontNumber); } + +} // namespace AGS3 diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index b891aff8cfc1..da07dead4fe1 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -26,11 +26,13 @@ #include "util/memory.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; -static const char *WFN_FILE_SIGNATURE = "WGT Font File "; +static const char *WFN_FILE_SIGNATURE = "WGT Font File "; static const size_t WFN_FILE_SIG_LENGTH = 15; -static const size_t MinCharDataSize = sizeof(uint16_t) * 2; +static const size_t MinCharDataSize = sizeof(uint16_t) * 2; WFNChar::WFNChar() : Width(0) @@ -99,7 +101,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { const uint16_t off = offset_table[i]; if (off < raw_data_offset || off + MinCharDataSize > table_addr) { Debug::Printf("\tWFN: character %d -- bad item offset: %d (%d - %d, +%d)", - i, off, raw_data_offset, table_addr, MinCharDataSize); + i, off, raw_data_offset, table_addr, MinCharDataSize); err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format continue; // bad character offset } @@ -115,7 +117,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { size_t total_pixel_size = 0; for (size_t i = 0; i < _items.size(); ++i) { const uint8_t *p_data = raw_data + offs[i] - raw_data_offset; - init_ch.Width = Memory::ReadInt16LE(p_data); + init_ch.Width = Memory::ReadInt16LE(p_data); init_ch.Height = Memory::ReadInt16LE(p_data + sizeof(uint16_t)); total_pixel_size += init_ch.GetRequiredPixelSize(); _items[i] = init_ch; @@ -133,12 +135,12 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { err = kWFNErr_HasBadCharacters; continue; // just an empty character } - const uint16_t raw_off = offs[i] - raw_data_offset + MinCharDataSize; // offset in raw array + const uint16_t raw_off = offs[i] - raw_data_offset + MinCharDataSize; // offset in raw array size_t src_size = pixel_data_size; if (i + 1 != _items.size() && raw_off + src_size > offs[i + 1] - raw_data_offset) { // character pixel data overlaps next character Debug::Printf("\tWFN: item at off %d -- pixel data overlaps next known item (at %d, +%d)", - offs[i], offs[i + 1], MinCharDataSize + src_size); + offs[i], offs[i + 1], MinCharDataSize + src_size); err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format src_size = offs[i + 1] - offs[i] - MinCharDataSize; } @@ -146,7 +148,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { if (raw_off + src_size > total_char_data) { // character pixel data overflow buffer Debug::Printf("\tWFN: item at off %d -- pixel data exceeds available data (at %d, +%d)", - offs[i], table_addr, MinCharDataSize + src_size); + offs[i], table_addr, MinCharDataSize + src_size); err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format src_size = total_char_data - raw_off; } @@ -173,13 +175,15 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { // we know beforehand that such item must exist std::vector::const_iterator at = std::lower_bound(offs.begin(), offs.end(), off); assert(at != offs.end() && *at == off && // should not normally fail - at - offs.begin() >= 0 && static_cast(at - offs.begin()) < _items.size()); + at - offs.begin() >= 0 && static_cast(at - offs.begin()) < _items.size()); _refs[i] = &_items[at - offs.begin()]; // set up reference to item } } } - delete [] raw_data; - delete [] offset_table; + delete[] raw_data; + delete[] offset_table; return err; } + +} // namespace AGS3 diff --git a/engines/ags/shared/font/wfnfontrenderer.cpp b/engines/ags/shared/font/wfnfontrenderer.cpp index 559e88a2e41b..336680540890 100644 --- a/engines/ags/shared/font/wfnfontrenderer.cpp +++ b/engines/ags/shared/font/wfnfontrenderer.cpp @@ -28,6 +28,8 @@ #include "gfx/bitmap.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; static unsigned char GetCharCode(unsigned char wanted_code, const WFNFont *font) { @@ -104,7 +106,7 @@ int RenderChar(Bitmap *ds, const int at_x, const int at_y, const WFNChar &wfn_ch if (((actdata[h * bytewid + (w / 8)] & (0x80 >> (w % 8))) != 0)) { if (scale > 1) { ds->FillRect(Rect(x + w, y + h, x + w + (scale - 1), - y + h + (scale - 1)), text_color); + y + h + (scale - 1)), text_color); } else { ds->PutPixel(x + w, y + h, text_color); } @@ -162,3 +164,5 @@ void WFNFontRenderer::FreeMemory(int fontNumber) { bool WFNFontRenderer::SupportsExtendedCharacters(int fontNumber) { return _fontData[fontNumber].Font->GetCharCount() > 128; } + +} // namespace AGS3 diff --git a/engines/ags/shared/game/customproperties.cpp b/engines/ags/shared/game/customproperties.cpp index 96440c7739cc..be148873faba 100644 --- a/engines/ags/shared/game/customproperties.cpp +++ b/engines/ags/shared/game/customproperties.cpp @@ -24,6 +24,7 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -44,7 +45,7 @@ namespace Properties { PropertyError ReadSchema(PropertySchema &schema, Stream *in) { PropertyVersion version = (PropertyVersion)in->ReadInt32(); if (version < kPropertyVersion_Initial || - version > kPropertyVersion_Current) { + version > kPropertyVersion_Current) { return kPropertyErr_UnsupportedFormat; } @@ -74,7 +75,7 @@ void WriteSchema(const PropertySchema &schema, Stream *out) { out->WriteInt32(kPropertyVersion_Current); out->WriteInt32(schema.size()); for (PropertySchema::const_iterator it = schema.begin(); - it != schema.end(); ++it) { + it != schema.end(); ++it) { const PropertyDesc &prop = it->second; StrUtil::WriteString(prop.Name, out); out->WriteInt32(prop.Type); @@ -86,19 +87,19 @@ void WriteSchema(const PropertySchema &schema, Stream *out) { PropertyError ReadValues(StringIMap &map, Stream *in) { PropertyVersion version = (PropertyVersion)in->ReadInt32(); if (version < kPropertyVersion_Initial || - version > kPropertyVersion_Current) { + version > kPropertyVersion_Current) { return kPropertyErr_UnsupportedFormat; } int count = in->ReadInt32(); if (version == kPropertyVersion_Initial) { for (int i = 0; i < count; ++i) { - String name = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_NAME_LENGTH); + String name = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_NAME_LENGTH); map[name] = String::FromStream(in, LEGACY_MAX_CUSTOM_PROP_VALUE_LENGTH); } } else { for (int i = 0; i < count; ++i) { - String name = StrUtil::ReadString(in); + String name = StrUtil::ReadString(in); map[name] = StrUtil::ReadString(in); } } @@ -109,7 +110,7 @@ void WriteValues(const StringIMap &map, Stream *out) { out->WriteInt32(kPropertyVersion_Current); out->WriteInt32(map.size()); for (StringIMap::const_iterator it = map.begin(); - it != map.end(); ++it) { + it != map.end(); ++it) { StrUtil::WriteString(it->first, out); StrUtil::WriteString(it->second, out); } @@ -119,3 +120,4 @@ void WriteValues(const StringIMap &map, Stream *out) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/game/interactions.cpp b/engines/ags/shared/game/interactions.cpp index 6c53f14a00de..69cece596779 100644 --- a/engines/ags/shared/game/interactions.cpp +++ b/engines/ags/shared/game/interactions.cpp @@ -26,9 +26,11 @@ #include "util/alignedstream.h" #include "util/math.h" +namespace AGS3 { + using namespace AGS::Shared; -InteractionVariable globalvars[MAX_GLOBAL_VARIABLES] = {InteractionVariable("Global 1", 0, 0)}; +InteractionVariable globalvars[MAX_GLOBAL_VARIABLES] = { InteractionVariable("Global 1", 0, 0) }; int numGlobalVars = 1; namespace AGS { @@ -41,7 +43,7 @@ InteractionValue::InteractionValue() { } void InteractionValue::Read(Stream *in) { - Type = (InterValType)in->ReadInt8(); + Type = (InterValType)in->ReadInt8(); Value = in->ReadInt32(); Extra = in->ReadInt32(); } @@ -345,7 +347,7 @@ InteractionVariable::InteractionVariable(const String &name, char type, int val) void InteractionVariable::Read(Stream *in) { Name.ReadCount(in, INTER_VAR_NAME_LENGTH); - Type = in->ReadInt8(); + Type = in->ReadInt8(); Value = in->ReadInt32(); } @@ -374,3 +376,4 @@ InteractionScripts *InteractionScripts::CreateFromStream(Stream *in) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index f02e9c10f17f..847f894f6d8f 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -39,6 +39,7 @@ #include "util/string_utils.h" #include "font/fonts.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -111,7 +112,7 @@ bool IsMainGameLibrary(const String &filename) { return false; for (size_t i = 0; i < lib.AssetInfos.size(); ++i) { if (lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v3) == 0 || - lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v2) == 0) { + lib.AssetInfos[i].FileName.CompareNoCase(MainGameSource::DefaultFilename_v2) == 0) { return true; } } @@ -132,7 +133,7 @@ HGameFileError OpenMainGameFileBase(PStream &in, MainGameSource &src) { return new MainGameFileError(kMGFErr_FormatVersionTooOld, String::FromFormat("Required format version: %d, supported %d - %d", src.DataVersion, kGameVersion_250, kGameVersion_Current)); if (src.DataVersion > kGameVersion_Current) return new MainGameFileError(kMGFErr_FormatVersionNotSupported, - String::FromFormat("Game was compiled with %s. Required format version: %d, supported %d - %d", src.CompiledWith.GetCStr(), src.DataVersion, kGameVersion_250, kGameVersion_Current)); + String::FromFormat("Game was compiled with %s. Required format version: %d, supported %d - %d", src.CompiledWith.GetCStr(), src.DataVersion, kGameVersion_250, kGameVersion_Current)); // Read required capabilities if (src.DataVersion >= kGameVersion_341) { size_t count = in->ReadInt32(); @@ -226,10 +227,10 @@ void ReadViews(GameSetupStruct &game, ViewStruct *&views, Stream *in, GameDataVe } void ReadDialogs(DialogTopic *&dialog, - std::vector< std::shared_ptr > &old_dialog_scripts, - std::vector &old_dialog_src, - std::vector &old_speech_lines, - Stream *in, GameDataVersion data_ver, int dlg_count) { + std::vector< std::shared_ptr > &old_dialog_scripts, + std::vector &old_dialog_src, + std::vector &old_speech_lines, + Stream *in, GameDataVersion data_ver, int dlg_count) { // TODO: I suspect +5 was a hacky way to "supress" memory access mistakes; // double check and remove if proved unnecessary dialog = (DialogTopic *)malloc(sizeof(DialogTopic) * dlg_count + 5); @@ -258,7 +259,7 @@ void ReadDialogs(DialogTopic *&dialog, if (data_ver > kGameVersion_260) decrypt_text(buffer); old_dialog_src[i] = buffer; - delete [] buffer; + delete[] buffer; } else { in->Seek(script_text_len); } @@ -268,13 +269,13 @@ void ReadDialogs(DialogTopic *&dialog, // // TODO: investigate this: these strings were read much simplier in the editor, see code: /* - char stringbuffer[1000]; - for (bb=0;bb= 26) && (encrypted)) - read_string_decrypt(iii, stringbuffer); - else - fgetstring(stringbuffer, iii); - } + char stringbuffer[1000]; + for (bb=0;bb= 26) && (encrypted)) + read_string_decrypt(iii, stringbuffer); + else + fgetstring(stringbuffer, iii); + } */ int i = 0; char buffer[1000]; @@ -371,7 +372,7 @@ void BuildAudioClipArray(const std::vector &assets, std::vector 1) ? - get_fixed_pixel_size(1) : 1; + // if it's a scaled up bitmap font, move the outline out more + (is_bitmap_font(font) && get_font_scaling_mul(font) > 1) ? + get_fixed_pixel_size(1) : 1; finfo.AutoOutlineStyle = FontInfo::kSquared; } } @@ -682,7 +683,7 @@ HGameFileError ReadGameData(LoadedGameEntities &ents, Stream *in, GameDataVersio game.read_messages(in, data_ver); ReadDialogs(ents.Dialogs, ents.OldDialogScripts, ents.OldDialogSources, ents.OldSpeechLines, - in, data_ver, game.numdialog); + in, data_ver, game.numdialog); HError err2 = GUI::ReadGUI(guis, in); if (!err2) return new MainGameFileError(kMGFErr_GameEntityFailed, err2); @@ -735,3 +736,4 @@ HGameFileError UpdateGameData(LoadedGameEntities &ents, GameDataVersion data_ver } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index ce69890ed481..7793053e7062 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -35,6 +35,8 @@ #include "util/compress.h" #include "util/string_utils.h" +namespace AGS3 { + // default number of hotspots to read from the room file #define MIN_ROOM_HOTSPOTS 20 #define LEGACY_HOTSPOT_NAME_LEN 30 @@ -102,26 +104,26 @@ HRoomFileError OpenRoomFile(const String &filename, RoomDataSource &src) { enum RoomFileBlock { - kRoomFblk_None = 0, + kRoomFblk_None = 0, // Main room data - kRoomFblk_Main = 1, + kRoomFblk_Main = 1, // Room script text source (was present in older room formats) - kRoomFblk_Script = 2, + kRoomFblk_Script = 2, // Old versions of compiled script (no longer supported) - kRoomFblk_CompScript = 3, - kRoomFblk_CompScript2 = 4, + kRoomFblk_CompScript = 3, + kRoomFblk_CompScript2 = 4, // Names of the room objects - kRoomFblk_ObjectNames = 5, + kRoomFblk_ObjectNames = 5, // Secondary room backgrounds - kRoomFblk_AnimBg = 6, + kRoomFblk_AnimBg = 6, // Contemporary compiled script - kRoomFblk_CompScript3 = 7, + kRoomFblk_CompScript3 = 7, // Custom properties - kRoomFblk_Properties = 8, + kRoomFblk_Properties = 8, // Script names of the room objects - kRoomFblk_ObjectScNames = 9, + kRoomFblk_ObjectScNames = 9, // End of room data tag - kRoomFile_EOF = 0xFF + kRoomFile_EOF = 0xFF }; @@ -199,8 +201,8 @@ HRoomFileError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ if (polypoint_areas > 0) return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Legacy poly-point areas are no longer supported."); /* NOTE: implementation hidden in room_file_deprecated.cpp - for (size_t i = 0; i < polypoint_areas; ++i) - wallpoints[i].Read(in); + for (size_t i = 0; i < polypoint_areas; ++i) + wallpoints[i].Read(in); */ update_polled_stuff_if_runtime(); @@ -331,7 +333,7 @@ HRoomFileError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ if (fullanim_count > 0) return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Room animations are no longer supported."); /* NOTE: implementation hidden in room_file_deprecated.cpp - in->ReadArray(&fullanims[0], sizeof(FullAnimation), fullanim_count); + in->ReadArray(&fullanims[0], sizeof(FullAnimation), fullanim_count); */ } @@ -340,7 +342,7 @@ HRoomFileError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ if ((data_ver >= kRoomVersion_pre114_4) && (data_ver < kRoomVersion_250a)) { return new RoomFileError(kRoomFileErr_IncompatibleEngine, "Pre-2.5 graphical scripts are no longer supported."); /* NOTE: implementation hidden in room_file_deprecated.cpp - ReadPre250Scripts(in); + ReadPre250Scripts(in); */ } @@ -411,7 +413,7 @@ HRoomFileError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion d int name_count = in->ReadByte(); if (name_count != room->ObjectCount) return new RoomFileError(kRoomFileErr_InconsistentData, - String::FromFormat("In the object names block, expected name count: %d, got %d", room->ObjectCount, name_count)); + String::FromFormat("In the object names block, expected name count: %d, got %d", room->ObjectCount, name_count)); for (size_t i = 0; i < room->ObjectCount; ++i) { if (data_ver >= kRoomVersion_3415) @@ -427,7 +429,7 @@ HRoomFileError ReadObjScNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion int name_count = in->ReadByte(); if (name_count != room->ObjectCount) return new RoomFileError(kRoomFileErr_InconsistentData, - String::FromFormat("In the object script names block, expected name count: %d, got %d", room->ObjectCount, name_count)); + String::FromFormat("In the object script names block, expected name count: %d, got %d", room->ObjectCount, name_count)); for (size_t i = 0; i < room->ObjectCount; ++i) { if (data_ver >= kRoomVersion_3415) @@ -507,10 +509,10 @@ HRoomFileError ReadRoomBlock(RoomStruct *room, Stream *in, RoomFileBlock block, case kRoomFblk_CompScript: case kRoomFblk_CompScript2: return new RoomFileError(kRoomFileErr_OldBlockNotSupported, - String::FromFormat("Type: %d.", block)); + String::FromFormat("Type: %d.", block)); default: return new RoomFileError(kRoomFileErr_UnknownBlockType, - String::FromFormat("Type: %d, known range: %d - %d.", block, kRoomFblk_Main, kRoomFblk_ObjectScNames)); + String::FromFormat("Type: %d, known range: %d - %d.", block, kRoomFblk_Main, kRoomFblk_ObjectScNames)); } if (!err) @@ -519,10 +521,10 @@ HRoomFileError ReadRoomBlock(RoomStruct *room, Stream *in, RoomFileBlock block, soff_t cur_pos = in->GetPosition(); if (cur_pos > block_end) { return new RoomFileError(kRoomFileErr_BlockDataOverlapping, - String::FromFormat("Type: %d, expected to end at offset: %u, finished reading at %u.", block, block_end, cur_pos)); + String::FromFormat("Type: %d, expected to end at offset: %u, finished reading at %u.", block, block_end, cur_pos)); } else if (cur_pos < block_end) { Debug::Printf(kDbgMsg_Warn, "WARNING: room data blocks nonsequential, block type %d expected to end at %u, finished reading at %u", - block, block_end, cur_pos); + block, block_end, cur_pos); in->Seek(block_end, Common::kSeekBegin); } return HRoomFileError::None(); @@ -883,3 +885,4 @@ HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersio } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/game/room_file_deprecated.cpp b/engines/ags/shared/game/room_file_deprecated.cpp index 4b0a6457a121..388d9783ceac 100644 --- a/engines/ags/shared/game/room_file_deprecated.cpp +++ b/engines/ags/shared/game/room_file_deprecated.cpp @@ -33,6 +33,8 @@ #include "ac/common.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; #define AE_WAITFLAG 0x80000000 @@ -140,4 +142,6 @@ HRoomFileError ReadPre250Scripts(Stream *in) { return err; } +} // namespace AGS3 + #endif // OBSOLETE diff --git a/engines/ags/shared/game/roomstruct.cpp b/engines/ags/shared/game/roomstruct.cpp index 4a9ddc26ef12..73d399ed0e65 100644 --- a/engines/ags/shared/game/roomstruct.cpp +++ b/engines/ags/shared/game/roomstruct.cpp @@ -25,6 +25,7 @@ #include "game/roomstruct.h" #include "gfx/bitmap.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -145,24 +146,24 @@ void RoomStruct::FreeScripts() { } void RoomStruct::InitDefaults() { - DataVersion = kRoomVersion_Current; - GameID = NO_GAME_ID_IN_ROOM_FILE; - - _resolution = kRoomRealRes; - MaskResolution = 1; - Width = 320; - Height = 200; - - Options = RoomOptions(); - Edges = RoomEdges(0, 317, 40, 199); - - BgFrameCount = 1; - HotspotCount = 0; - ObjectCount = 0; - RegionCount = 0; - WalkAreaCount = 0; + DataVersion = kRoomVersion_Current; + GameID = NO_GAME_ID_IN_ROOM_FILE; + + _resolution = kRoomRealRes; + MaskResolution = 1; + Width = 320; + Height = 200; + + Options = RoomOptions(); + Edges = RoomEdges(0, 317, 40, 199); + + BgFrameCount = 1; + HotspotCount = 0; + ObjectCount = 0; + RegionCount = 0; + WalkAreaCount = 0; WalkBehindCount = 0; - MessageCount = 0; + MessageCount = 0; for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i) { Hotspots[i] = RoomHotspot(); @@ -300,3 +301,4 @@ void FixRoomMasks(RoomStruct *room) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index d84072b90c38..1112dfd32751 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -24,6 +24,8 @@ #include "gfx/allegrobitmap.h" #include "debug/assert.h" +namespace AGS3 { + extern void __my_setcolor(int *ctset, int newcol, int wantColDep); namespace AGS { @@ -188,11 +190,11 @@ void Bitmap::StretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask) // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite if (mask == kBitmap_Transparency) { stretch_sprite(_alBitmap, al_src_bmp, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } else { stretch_blit(al_src_bmp, _alBitmap, - 0, 0, al_src_bmp->w, al_src_bmp->h, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + 0, 0, al_src_bmp->w, al_src_bmp->h, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } @@ -200,12 +202,12 @@ void Bitmap::StretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, Bit BITMAP *al_src_bmp = src->_alBitmap; if (mask == kBitmap_Transparency) { masked_stretch_blit(al_src_bmp, _alBitmap, - src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } else { stretch_blit(al_src_bmp, _alBitmap, - src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } @@ -214,11 +216,11 @@ void Bitmap::AAStretchBlt(Bitmap *src, const Rect &dst_rc, BitmapMaskOption mask // WARNING: For some evil reason Allegro expects dest and src bitmaps in different order for blit and draw_sprite if (mask == kBitmap_Transparency) { aa_stretch_sprite(_alBitmap, al_src_bmp, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } else { aa_stretch_blit(al_src_bmp, _alBitmap, - 0, 0, al_src_bmp->w, al_src_bmp->h, - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + 0, 0, al_src_bmp->w, al_src_bmp->h, + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } @@ -231,8 +233,8 @@ void Bitmap::AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, B throw "aa_masked_blit is not yet supported!"; } else { aa_stretch_blit(al_src_bmp, _alBitmap, - src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), - dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); + src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), + dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); } } @@ -335,7 +337,7 @@ void Bitmap::DrawLine(const Line &ln, color_t color) { void Bitmap::DrawTriangle(const Triangle &tr, color_t color) { triangle(_alBitmap, - tr.X1, tr.Y1, tr.X2, tr.Y2, tr.X3, tr.Y3, color); + tr.X1, tr.Y1, tr.X2, tr.Y2, tr.X3, tr.Y3, color); } void Bitmap::DrawRect(const Rect &rc, color_t color) { @@ -410,6 +412,6 @@ Bitmap *CreateRawBitmapWrapper(BITMAP *al_bmp) { } // namespace BitmapHelper - } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp index 98447e2c47fe..543fecba5d24 100644 --- a/engines/ags/shared/gfx/bitmap.cpp +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -23,6 +23,7 @@ #include "gfx/bitmap.h" #include "util/memory.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -98,7 +99,7 @@ struct PixelNoSkip { } }; -typedef PixelTransCpy PixelTransCpy8; +typedef PixelTransCpy PixelTransCpy8; typedef PixelTransCpy PixelTransCpy16; struct PixelTransCpy24 { @@ -119,7 +120,7 @@ struct PixelTransCpy32 { if (*(const uint32_t *)src == mask_color) *(uint32_t *)dst = mask_color; else if (use_alpha) - dst[3] = src[3]; // copy alpha channel + dst[3] = src[3]; // copy alpha channel else dst[3] = 0xFF; // set the alpha channel byte to opaque } @@ -142,15 +143,15 @@ void ApplyMask(uint8_t *dst, const uint8_t *src, size_t pitch, size_t height, Fn } void CopyTransparency(Bitmap *dst, const Bitmap *mask, bool dst_has_alpha, bool mask_has_alpha) { - color_t mask_color = mask->GetMaskColor(); - uint8_t *dst_ptr = dst->GetDataForWriting(); + color_t mask_color = mask->GetMaskColor(); + uint8_t *dst_ptr = dst->GetDataForWriting(); const uint8_t *src_ptr = mask->GetData(); - const size_t bpp = mask->GetBPP(); - const size_t pitch = mask->GetLineLength(); - const size_t height = mask->GetHeight(); + const size_t bpp = mask->GetBPP(); + const size_t pitch = mask->GetLineLength(); + const size_t height = mask->GetHeight(); if (bpp == 1) - ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy8(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); + ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy8(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); else if (bpp == 2) ApplyMask(dst_ptr, src_ptr, pitch, height, PixelTransCpy16(), PixelNoSkip(), mask_color, dst_has_alpha, mask_has_alpha); else if (bpp == 3) @@ -171,3 +172,4 @@ void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t s } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guibutton.cpp b/engines/ags/shared/gui/guibutton.cpp index 502aeb036746..bcc61f7fa9f0 100644 --- a/engines/ags/shared/gui/guibutton.cpp +++ b/engines/ags/shared/gui/guibutton.cpp @@ -26,6 +26,8 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { + std::vector guibuts; int numguibuts = 0; @@ -94,7 +96,7 @@ void GUIButton::Draw(Bitmap *ds) { check_font(&Font); // if it's "Unchanged when disabled" or "GUI Off", don't grey out if (gui_disabled_style == GUIDIS_UNCHANGED || - gui_disabled_style == GUIDIS_GUIOFF) { + gui_disabled_style == GUIDIS_GUIOFF) { draw_disabled = false; } // TODO: should only change properties in reaction to particular events @@ -269,7 +271,7 @@ void GUIButton::DrawImageButton(Bitmap *ds, bool draw_disabled) { GUIButtonPlaceholder place = _placeholder; if (place == kButtonPlace_InvItemAuto) { if ((get_adjusted_spritewidth(gui_inv_pic) > Width - 6) || - (get_adjusted_spriteheight(gui_inv_pic) > Height - 6)) { + (get_adjusted_spriteheight(gui_inv_pic) > Height - 6)) { place = kButtonPlace_InvItemStretch; } else { place = kButtonPlace_InvItemCenter; @@ -280,17 +282,17 @@ void GUIButton::DrawImageButton(Bitmap *ds, bool draw_disabled) { ds->StretchBlt(spriteset[gui_inv_pic], RectWH(X + 3, Y + 3, Width - 6, Height - 6), Common::kBitmap_Transparency); } else if (place == kButtonPlace_InvItemCenter) { draw_gui_sprite(ds, gui_inv_pic, - X + Width / 2 - get_adjusted_spritewidth(gui_inv_pic) / 2, - Y + Height / 2 - get_adjusted_spriteheight(gui_inv_pic) / 2, - true); + X + Width / 2 - get_adjusted_spritewidth(gui_inv_pic) / 2, + Y + Height / 2 - get_adjusted_spriteheight(gui_inv_pic) / 2, + true); } } if ((draw_disabled) && (gui_disabled_style == GUIDIS_GREYOUT)) { // darken the button when disabled GUI::DrawDisabledEffect(ds, RectWH(X, Y, - spriteset[CurrentImage]->GetWidth(), - spriteset[CurrentImage]->GetHeight())); + spriteset[CurrentImage]->GetWidth(), + spriteset[CurrentImage]->GetHeight())); } ds->SetClip(Rect(0, 0, ds->GetWidth() - 1, ds->GetHeight() - 1)); @@ -348,3 +350,4 @@ void GUIButton::DrawTextButton(Bitmap *ds, bool draw_disabled) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guiinv.cpp b/engines/ags/shared/gui/guiinv.cpp index 6feaf6c188d0..7e71a39234cc 100644 --- a/engines/ags/shared/gui/guiinv.cpp +++ b/engines/ags/shared/gui/guiinv.cpp @@ -26,6 +26,8 @@ #include "gui/guimain.h" #include "util/stream.h" +namespace AGS3 { + std::vector guiinv; int numguiinv = 0; @@ -129,3 +131,4 @@ void GUIInvWindow::CalculateNumCells() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guilabel.cpp b/engines/ags/shared/gui/guilabel.cpp index 7891b5d66a94..cf72d09d9642 100644 --- a/engines/ags/shared/gui/guilabel.cpp +++ b/engines/ags/shared/gui/guilabel.cpp @@ -27,6 +27,8 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { + std::vector guilabels; int numguilabels = 0; @@ -62,10 +64,10 @@ void GUILabel::Draw(Common::Bitmap *ds) { const bool limit_by_label_frame = loaded_game_file_version >= kGameVersion_272; int at_y = Y; for (size_t i = 0; - i < Lines.Count() && (!limit_by_label_frame || at_y <= Y + Height); - ++i, at_y += linespacing) { + i < Lines.Count() && (!limit_by_label_frame || at_y <= Y + Height); + ++i, at_y += linespacing) { GUI::DrawTextAlignedHor(ds, Lines[i], Font, text_color, X, X + Width - 1, at_y, - (FrameAlignment)TextAlignment); + (FrameAlignment)TextAlignment); } } @@ -123,3 +125,4 @@ void GUILabel::WriteToSavegame(Stream *out) const { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guilistbox.cpp b/engines/ags/shared/gui/guilistbox.cpp index f629615ef2f1..4f574a10f8be 100644 --- a/engines/ags/shared/gui/guilistbox.cpp +++ b/engines/ags/shared/gui/guilistbox.cpp @@ -26,6 +26,8 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { + std::vector guilist; int numguilist = 0; @@ -96,7 +98,7 @@ void GUIListBox::Clear() { } void GUIListBox::Draw(Common::Bitmap *ds) { - const int width = Width - 1; + const int width = Width - 1; const int height = Height - 1; const int pixel_size = get_fixed_pixel_size(1); @@ -115,7 +117,7 @@ void GUIListBox::Draw(Common::Bitmap *ds) { SetFont(Font); // draw the scroll bar in if necessary - if (ItemCount > VisibleItemCount && IsBorderShown() && AreArrowsShown()) { + if (ItemCount > VisibleItemCount &&IsBorderShown() && AreArrowsShown()) { int xstrt, ystrt; ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y, (X + (pixel_size - 1) + width) - get_fixed_pixel_size(7), Y + height), draw_color); ds->DrawRect(Rect(X + width - get_fixed_pixel_size(7), Y + height / 2, X + width, Y + height / 2 + (pixel_size - 1)), draw_color); @@ -125,14 +127,14 @@ void GUIListBox::Draw(Common::Bitmap *ds) { draw_color = ds->GetCompatibleColor(TextColor); ds->DrawTriangle(Triangle(xstrt, ystrt, xstrt + get_fixed_pixel_size(4), ystrt, - xstrt + get_fixed_pixel_size(2), - ystrt + get_fixed_pixel_size(5)), draw_color); + xstrt + get_fixed_pixel_size(2), + ystrt + get_fixed_pixel_size(5)), draw_color); ystrt = Y + 3; ds->DrawTriangle(Triangle(xstrt, ystrt + get_fixed_pixel_size(5), - xstrt + get_fixed_pixel_size(4), - ystrt + get_fixed_pixel_size(5), - xstrt + get_fixed_pixel_size(2), ystrt), draw_color); + xstrt + get_fixed_pixel_size(4), + ystrt + get_fixed_pixel_size(5), + xstrt + get_fixed_pixel_size(2), ystrt), draw_color); right_hand_edge -= get_fixed_pixel_size(7); } @@ -162,7 +164,7 @@ void GUIListBox::Draw(Common::Bitmap *ds) { PrepareTextToDraw(Items[item_index]); GUI::DrawTextAlignedHor(ds, _textToDraw, Font, text_color, X + 1 + pixel_size, right_hand_edge, at_y + 1, - (FrameAlignment)TextAlignment); + (FrameAlignment)TextAlignment); } DrawItemsUnfix(); @@ -327,7 +329,7 @@ void GUIListBox::ReadFromFile(Stream *in, GuiVersion gui_version) { } if (gui_version >= kGuiVersion_272d && gui_version < kGuiVersion_350 && - (ListBoxFlags & kListBox_SvgIndex)) { + (ListBoxFlags & kListBox_SvgIndex)) { // NOTE: reading into actual variables only for old savegame support for (int i = 0; i < ItemCount; ++i) SavedGameIndex[i] = in->ReadInt16(); @@ -392,3 +394,4 @@ void GUIListBox::WriteToSavegame(Stream *out) const { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index dfade96d2fb9..9463a712df47 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -35,6 +35,8 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { + using namespace AGS::Shared; #define MOVER_MOUSEDOWNLOCKED -4000 @@ -57,29 +59,29 @@ GUIMain::GUIMain() { } void GUIMain::InitDefaults() { - ID = 0; + ID = 0; Name.Empty(); - _flags = kGUIMain_DefFlags; - - X = 0; - Y = 0; - Width = 0; - Height = 0; - BgColor = 8; - BgImage = 0; - FgColor = 1; - Padding = TEXTWINDOW_PADDING_DEFAULT; - PopupStyle = kGUIPopupNormal; + _flags = kGUIMain_DefFlags; + + X = 0; + Y = 0; + Width = 0; + Height = 0; + BgColor = 8; + BgImage = 0; + FgColor = 1; + Padding = TEXTWINDOW_PADDING_DEFAULT; + PopupStyle = kGUIPopupNormal; PopupAtMouseY = -1; - Transparency = 0; - ZOrder = -1; + Transparency = 0; + ZOrder = -1; - FocusCtrl = 0; + FocusCtrl = 0; HighlightCtrl = -1; MouseOverCtrl = -1; MouseDownCtrl = -1; - MouseWasAt.X = -1; - MouseWasAt.Y = -1; + MouseWasAt.X = -1; + MouseWasAt.Y = -1; OnClickHandler.Empty(); @@ -197,23 +199,23 @@ void GUIMain::Draw(Bitmap *ds) { void GUIMain::DrawAt(Bitmap *ds, int x, int y) { SET_EIP(375) - if ((Width < 1) || (Height < 1)) - return; + if ((Width < 1) || (Height < 1)) + return; Bitmap subbmp; subbmp.CreateSubBitmap(ds, RectWH(x, y, Width, Height)); SET_EIP(376) - // stop border being transparent, if the whole GUI isn't - if ((FgColor == 0) && (BgColor != 0)) - FgColor = 16; + // stop border being transparent, if the whole GUI isn't + if ((FgColor == 0) && (BgColor != 0)) + FgColor = 16; if (BgColor != 0) subbmp.Fill(subbmp.GetCompatibleColor(BgColor)); SET_EIP(377) - color_t draw_color; + color_t draw_color; if (FgColor != BgColor) { draw_color = subbmp.GetCompatibleColor(FgColor); subbmp.DrawRect(Rect(0, 0, subbmp.GetWidth() - 1, subbmp.GetHeight() - 1), draw_color); @@ -223,13 +225,13 @@ void GUIMain::DrawAt(Bitmap *ds, int x, int y) { SET_EIP(378) - if (BgImage > 0 && spriteset[BgImage] != nullptr) - draw_gui_sprite(&subbmp, BgImage, 0, 0, false); + if (BgImage > 0 && spriteset[BgImage] != nullptr) + draw_gui_sprite(&subbmp, BgImage, 0, 0, false); SET_EIP(379) - if (all_buttons_disabled && gui_disabled_style == GUIDIS_BLACKOUT) - return; // don't draw GUI controls + if (all_buttons_disabled && gui_disabled_style == GUIDIS_BLACKOUT) + return; // don't draw GUI controls for (size_t ctrl_index = 0; ctrl_index < _controls.size(); ++ctrl_index) { set_eip_guiobj(_ctrlDrawOrder[ctrl_index]); @@ -253,7 +255,7 @@ void GUIMain::DrawAt(Bitmap *ds, int x, int y) { DrawBlob(&subbmp, objToDraw->X, objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); DrawBlob(&subbmp, objToDraw->X, objToDraw->Y, draw_color); DrawBlob(&subbmp, objToDraw->X + objToDraw->Width - get_fixed_pixel_size(1) - 1, - objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); + objToDraw->Y + objToDraw->Height - get_fixed_pixel_size(1) - 1, draw_color); } if (outlineGuiObjects) { // draw a dotted outline round all objects @@ -391,8 +393,8 @@ bool GUIMain::SetControlZOrder(int index, int zorder) { return false; // no change const bool move_back = zorder < old_zorder; // back is at zero index - const int left = move_back ? zorder : old_zorder; - const int right = move_back ? old_zorder : zorder; + const int left = move_back ? zorder : old_zorder; + const int right = move_back ? old_zorder : zorder; for (size_t i = 0; i < _controls.size(); ++i) { const int i_zorder = _controls[i]->ZOrder; if (i_zorder == old_zorder) @@ -441,7 +443,7 @@ void GUIMain::OnMouseButtonDown() { // don't activate disabled buttons if (!IsGUIEnabled(_controls[MouseOverCtrl]) || !_controls[MouseOverCtrl]->IsVisible() || - !_controls[MouseOverCtrl]->IsClickable()) + !_controls[MouseOverCtrl]->IsClickable()) return; MouseDownCtrl = MouseOverCtrl; @@ -469,7 +471,7 @@ void GUIMain::OnMouseButtonUp() { void GUIMain::ReadFromFile(Stream *in, GuiVersion gui_version) { // Legacy text window tag - char tw_flags[GUIMAIN_LEGACY_TW_FLAGS_SIZE] = {0}; + char tw_flags[GUIMAIN_LEGACY_TW_FLAGS_SIZE] = { 0 }; if (gui_version < kGuiVersion_350) in->Read(tw_flags, sizeof(tw_flags)); @@ -480,33 +482,33 @@ void GUIMain::ReadFromFile(Stream *in, GuiVersion gui_version) { Name = StrUtil::ReadString(in); OnClickHandler = StrUtil::ReadString(in); } - X = in->ReadInt32(); - Y = in->ReadInt32(); - Width = in->ReadInt32(); - Height = in->ReadInt32(); + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); if (gui_version < kGuiVersion_350) { // NOTE: reading into actual variables only for old savegame support FocusCtrl = in->ReadInt32(); } const size_t ctrl_count = in->ReadInt32(); - PopupStyle = (GUIPopupStyle)in->ReadInt32(); + PopupStyle = (GUIPopupStyle)in->ReadInt32(); PopupAtMouseY = in->ReadInt32(); - BgColor = in->ReadInt32(); - BgImage = in->ReadInt32(); - FgColor = in->ReadInt32(); + BgColor = in->ReadInt32(); + BgImage = in->ReadInt32(); + FgColor = in->ReadInt32(); if (gui_version < kGuiVersion_350) { // NOTE: reading into actual variables only for old savegame support MouseOverCtrl = in->ReadInt32(); - MouseWasAt.X = in->ReadInt32(); - MouseWasAt.Y = in->ReadInt32(); + MouseWasAt.X = in->ReadInt32(); + MouseWasAt.Y = in->ReadInt32(); MouseDownCtrl = in->ReadInt32(); HighlightCtrl = in->ReadInt32(); } - _flags = in->ReadInt32(); - Transparency = in->ReadInt32(); - ZOrder = in->ReadInt32(); - ID = in->ReadInt32(); - Padding = in->ReadInt32(); + _flags = in->ReadInt32(); + Transparency = in->ReadInt32(); + ZOrder = in->ReadInt32(); + ID = in->ReadInt32(); + Padding = in->ReadInt32(); if (gui_version < kGuiVersion_350) in->Seek(sizeof(int32_t) * GUIMAIN_LEGACY_RESERVED_INTS); @@ -673,7 +675,7 @@ HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame) { GameGuiVersion = kGuiVersion_Initial; } else if (GameGuiVersion > kGuiVersion_Current) return new Error(String::FromFormat("ReadGUI: format version not supported (required %d, supported %d - %d)", - GameGuiVersion, kGuiVersion_Initial, kGuiVersion_Current)); + GameGuiVersion, kGuiVersion_Initial, kGuiVersion_Current)); else gui_count = in->ReadInt32(); guis.resize(gui_count); @@ -818,3 +820,4 @@ void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guiobject.cpp b/engines/ags/shared/gui/guiobject.cpp index 82d5bde79174..69b44f47b3dc 100644 --- a/engines/ags/shared/gui/guiobject.cpp +++ b/engines/ags/shared/gui/guiobject.cpp @@ -25,19 +25,20 @@ #include "gui/guiobject.h" #include "util/stream.h" +namespace AGS3 { namespace AGS { namespace Shared { GUIObject::GUIObject() { - Id = 0; - ParentId = 0; - Flags = kGUICtrl_DefFlags; - X = 0; - Y = 0; - Width = 0; - Height = 0; - ZOrder = -1; - IsActivated = false; + Id = 0; + ParentId = 0; + Flags = kGUICtrl_DefFlags; + X = 0; + Y = 0; + Width = 0; + Height = 0; + ZOrder = -1; + IsActivated = false; _scEventCount = 0; } @@ -121,15 +122,15 @@ void GUIObject::WriteToFile(Stream *out) const { } void GUIObject::ReadFromFile(Stream *in, GuiVersion gui_version) { - Flags = in->ReadInt32(); + Flags = in->ReadInt32(); // reverse particular flags from older format if (gui_version < kGuiVersion_350) Flags ^= kGUICtrl_OldFmtXorMask; - X = in->ReadInt32(); - Y = in->ReadInt32(); - Width = in->ReadInt32(); - Height = in->ReadInt32(); - ZOrder = in->ReadInt32(); + X = in->ReadInt32(); + Y = in->ReadInt32(); + Width = in->ReadInt32(); + Height = in->ReadInt32(); + ZOrder = in->ReadInt32(); if (gui_version < kGuiVersion_350) { // NOTE: reading into actual variables only for old savegame support IsActivated = in->ReadInt32() != 0; @@ -196,3 +197,4 @@ HorAlignment ConvertLegacyGUIAlignment(LegacyGUIAlignment align) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guislider.cpp b/engines/ags/shared/gui/guislider.cpp index d58e52a2864e..557344bedd66 100644 --- a/engines/ags/shared/gui/guislider.cpp +++ b/engines/ags/shared/gui/guislider.cpp @@ -25,6 +25,8 @@ #include "gui/guislider.h" #include "util/stream.h" +namespace AGS3 { + std::vector guislider; int numguislider = 0; @@ -242,3 +244,4 @@ void GUISlider::WriteToSavegame(Stream *out) const { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/gui/guitextbox.cpp b/engines/ags/shared/gui/guitextbox.cpp index 9722612a25a7..8b9a20a940c5 100644 --- a/engines/ags/shared/gui/guitextbox.cpp +++ b/engines/ags/shared/gui/guitextbox.cpp @@ -26,6 +26,8 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { + #define GUITEXTBOX_LEGACY_TEXTLEN 200 std::vector guitext; @@ -137,3 +139,4 @@ void GUITextBox::WriteToSavegame(Stream *out) const { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp index a97da16d8bd3..b015289c509a 100644 --- a/engines/ags/shared/script/cc_error.cpp +++ b/engines/ags/shared/script/cc_error.cpp @@ -25,6 +25,8 @@ #include "script/script_common.h" // current_line #include "util/string.h" +namespace AGS3 { + using namespace AGS::Shared; // Returns full script error message and callstack (if possible) @@ -64,3 +66,5 @@ void cc_error(const char *descr, ...) { ccError = 1; ccErrorLine = currentline; } + +} // namespace AGS3 diff --git a/engines/ags/shared/script/cc_options.cpp b/engines/ags/shared/script/cc_options.cpp index 6bb3c610e343..9c7821f1beaf 100644 --- a/engines/ags/shared/script/cc_options.cpp +++ b/engines/ags/shared/script/cc_options.cpp @@ -22,6 +22,8 @@ #include "cc_options.h" +namespace AGS3 { + int ccCompOptions = SCOPT_LEFTTORIGHT; void ccSetOption(int optbit, int onoroff) { @@ -37,3 +39,5 @@ int ccGetOption(int optbit) { return 0; } + +} // namespace AGS3 diff --git a/engines/ags/shared/script/cc_script.cpp b/engines/ags/shared/script/cc_script.cpp index 2f6a567304f7..b7a79059cd41 100644 --- a/engines/ags/shared/script/cc_script.cpp +++ b/engines/ags/shared/script/cc_script.cpp @@ -28,6 +28,8 @@ #include "util/stream.h" #include "util/string_compat.h" +namespace AGS3 { + using AGS::Shared::Stream; // currently executed line @@ -70,27 +72,27 @@ ccScript *ccScript::CreateFromStream(Stream *in) { } ccScript::ccScript() { - globaldata = nullptr; - globaldatasize = 0; - code = nullptr; - codesize = 0; - strings = nullptr; - stringssize = 0; - fixuptypes = nullptr; - fixups = nullptr; - numfixups = 0; - importsCapacity = 0; - imports = nullptr; - numimports = 0; - exportsCapacity = 0; - exports = nullptr; - export_addr = nullptr; - numexports = 0; - instances = 0; - sectionNames = nullptr; - sectionOffsets = nullptr; - numSections = 0; - capacitySections = 0; + globaldata = nullptr; + globaldatasize = 0; + code = nullptr; + codesize = 0; + strings = nullptr; + stringssize = 0; + fixuptypes = nullptr; + fixups = nullptr; + numfixups = 0; + importsCapacity = 0; + imports = nullptr; + numimports = 0; + exportsCapacity = 0; + exports = nullptr; + export_addr = nullptr; + numexports = 0; + instances = 0; + sectionNames = nullptr; + sectionOffsets = nullptr; + numSections = 0; + capacitySections = 0; } ccScript::ccScript(const ccScript &src) { @@ -370,3 +372,5 @@ const char *ccScript::GetSectionName(int32_t offs) { return sectionNames[i - 1]; } + +} // namespace AGS3 diff --git a/engines/ags/shared/util/alignedstream.cpp b/engines/ags/shared/util/alignedstream.cpp index aa0a19096353..9601283e6927 100644 --- a/engines/ags/shared/util/alignedstream.cpp +++ b/engines/ags/shared/util/alignedstream.cpp @@ -24,11 +24,12 @@ #include "util/alignedstream.h" #include "util/math.h" +namespace AGS3 { namespace AGS { namespace Shared { AlignedStream::AlignedStream(Stream *stream, AlignedStreamMode mode, ObjectOwnershipPolicy stream_ownership_policy, - size_t base_alignment) + size_t base_alignment) : ProxyStream(stream, stream_ownership_policy) , _mode(mode) , _baseAlignment(base_alignment) @@ -330,3 +331,4 @@ void AlignedStream::FinalizeBlock() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index 34a569501ad1..30d385f0500a 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -27,6 +27,7 @@ #include "util/stdio_compat.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -121,13 +122,13 @@ bool BufferedStream::Seek(soff_t offset, StreamSeek origin) { soff_t want_pos = -1; switch (origin) { case StreamSeek::kSeekCurrent: - want_pos = _position + offset; + want_pos = _position + offset; break; case StreamSeek::kSeekBegin: - want_pos = 0 + offset; + want_pos = 0 + offset; break; case StreamSeek::kSeekEnd: - want_pos = _end + offset; + want_pos = _end + offset; break; break; } @@ -139,3 +140,4 @@ bool BufferedStream::Seek(soff_t offset, StreamSeek origin) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp index 9c5270ee7689..d707ab8b55ad 100644 --- a/engines/ags/shared/util/compress.cpp +++ b/engines/ags/shared/util/compress.cpp @@ -37,6 +37,8 @@ #include "util/bbop.h" #endif +namespace AGS3 { + using namespace AGS::Shared; void cpackbitl(const uint8_t *line, int size, Stream *out) { @@ -322,7 +324,7 @@ void save_lzw(Stream *out, const Bitmap *bmpp, const color *pall) { void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, color *pall) { soff_t uncompsiz; - int *loptr; + int *loptr; unsigned char *membuffer; int arin; @@ -345,11 +347,13 @@ void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, color *pall) { loptr[1] = BBOp::SwapBytesInt32(loptr[1]); int bitmapNumPixels = loptr[0] * loptr[1] / dst_bpp; switch (dst_bpp) { // bytes per pixel! - case 1: { + case 1: + { // all done break; } - case 2: { + case 2: + { short *sp = (short *)membuffer; for (int i = 0; i < bitmapNumPixels; ++i) { sp[i] = BBOp::SwapBytesInt16(sp[i]); @@ -357,7 +361,8 @@ void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, color *pall) { // all done break; } - case 4: { + case 4: + { int *ip = (int *)membuffer; for (int i = 0; i < bitmapNumPixels; ++i) { ip[i] = BBOp::SwapBytesInt32(ip[i]); @@ -397,7 +402,7 @@ void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, color *pall) { void savecompressed_allegro(Stream *out, const Bitmap *bmpp, const color *pall) { unsigned char *wgtbl = (unsigned char *)malloc(bmpp->GetWidth() * bmpp->GetHeight() + 4); - short *sss = (short *)wgtbl; + short *sss = (short *)wgtbl; sss[0] = bmpp->GetWidth(); sss[1] = bmpp->GetHeight(); @@ -427,3 +432,5 @@ void loadcompressed_allegro(Stream *in, Bitmap **bimpp, color *pall) { in->Seek(768); // skip palette *bimpp = bim; } + +} // namespace AGS3 diff --git a/engines/ags/shared/util/datastream.cpp b/engines/ags/shared/util/datastream.cpp index ad41bfe4e25d..1eb27225ae5e 100644 --- a/engines/ags/shared/util/datastream.cpp +++ b/engines/ags/shared/util/datastream.cpp @@ -22,6 +22,7 @@ #include "util/datastream.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -153,3 +154,4 @@ size_t DataStream::WriteAndConvertArrayOfInt64(const int64_t *buffer, size_t cou } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp index ba0c39b74024..e8c790cb603e 100644 --- a/engines/ags/shared/util/directory.cpp +++ b/engines/ags/shared/util/directory.cpp @@ -32,6 +32,7 @@ #include "util/path.h" #include "stdio_compat.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -40,9 +41,9 @@ namespace Directory { bool CreateDirectory(const String &path) { return mkdir(path #if ! AGS_PLATFORM_OS_WINDOWS - , 0755 + , 0755 #endif - ) == 0 || errno == EEXIST; + ) == 0 || errno == EEXIST; } bool CreateAllDirectories(const String &parent, const String &path) { @@ -83,3 +84,4 @@ String GetCurrentDirectory() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp index 0b4adcd784ee..f02286c8cb5e 100644 --- a/engines/ags/shared/util/file.cpp +++ b/engines/ags/shared/util/file.cpp @@ -29,6 +29,7 @@ #include "util/filestream.h" #include "util/bufferedstream.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -153,3 +154,4 @@ Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkM } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index 25956eb400d9..db8978949350 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -26,11 +26,12 @@ #include "util/stdio_compat.h" #include "util/string.h" +namespace AGS3 { namespace AGS { namespace Shared { FileStream::FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, - DataEndianess stream_endianess) + DataEndianess stream_endianess) : DataStream(stream_endianess) , _file(nullptr) , _openMode(open_mode) @@ -82,7 +83,7 @@ soff_t FileStream::GetLength() const { soff_t FileStream::GetPosition() const { if (IsValid()) { - return (soff_t) ags_ftell(_file); + return (soff_t)ags_ftell(_file); } return -1; } @@ -162,3 +163,4 @@ void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkM } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/geometry.cpp b/engines/ags/shared/util/geometry.cpp index 254f2dd30176..770344f3af59 100644 --- a/engines/ags/shared/util/geometry.cpp +++ b/engines/ags/shared/util/geometry.cpp @@ -24,6 +24,8 @@ #include #include +namespace AGS3 { + //namespace AGS //{ //namespace Shared @@ -32,21 +34,21 @@ bool AreRectsIntersecting(const Rect &r1, const Rect &r2) { // NOTE: remember that in AGS Y axis is pointed downwards return r1.Left <= r2.Right && r1.Right >= r2.Left && - r1.Top <= r2.Bottom && r1.Bottom >= r2.Top; + r1.Top <= r2.Bottom && r1.Bottom >= r2.Top; } bool IsRectInsideRect(const Rect &place, const Rect &item) { return item.Left >= place.Left && item.Right <= place.Right && - item.Top >= place.Top && item.Bottom <= place.Bottom; + item.Top >= place.Top && item.Bottom <= place.Bottom; } float DistanceBetween(const Rect &r1, const Rect &r2) { // https://gamedev.stackexchange.com/a/154040 Rect rect_outer( - std::min(r1.Left, r2.Left), - std::min(r1.Top, r2.Top), - std::max(r1.Right, r2.Right), - std::max(r1.Bottom, r2.Bottom) + std::min(r1.Left, r2.Left), + std::min(r1.Top, r2.Top), + std::max(r1.Right, r2.Right), + std::max(r1.Bottom, r2.Bottom) ); int inner_width = std::max(0, rect_outer.GetWidth() - r1.GetWidth() - r2.GetWidth()); int inner_height = std::max(0, rect_outer.GetHeight() - r1.GetHeight() - r2.GetHeight()); @@ -57,7 +59,7 @@ Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h) { int width = item_w ? dest_w : 0; int height = item_w ? (dest_w * item_h / item_w) : 0; if (height > dest_h) { - width = item_h ? (dest_h * item_w / item_h) : 0; + width = item_h ? (dest_h * item_w / item_h) : 0; height = dest_h; } return Size(width, height); @@ -98,17 +100,17 @@ Rect OffsetRect(const Rect &r, const Point off) { Rect CenterInRect(const Rect &place, const Rect &item) { return RectWH((place.GetWidth() >> 1) - (item.GetWidth() >> 1), - (place.GetHeight() >> 1) - (item.GetHeight() >> 1), - item.GetWidth(), item.GetHeight()); + (place.GetHeight() >> 1) - (item.GetHeight() >> 1), + item.GetWidth(), item.GetHeight()); } Rect ClampToRect(const Rect &place, const Rect &item) { return Rect( - AGSMath::Clamp(item.Left, place.Left, place.Right), - AGSMath::Clamp(item.Top, place.Top, place.Bottom), - AGSMath::Clamp(item.Right, place.Left, place.Right), - AGSMath::Clamp(item.Bottom, place.Top, place.Bottom) - ); + AGSMath::Clamp(item.Left, place.Left, place.Right), + AGSMath::Clamp(item.Top, place.Top, place.Bottom), + AGSMath::Clamp(item.Right, place.Left, place.Right), + AGSMath::Clamp(item.Bottom, place.Top, place.Bottom) + ); } Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement) { @@ -119,7 +121,7 @@ Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &place return place; case kPlaceStretchProportional: return CenterInRect(place, - RectWH(ProportionalStretch(place.GetWidth(), place.GetHeight(), item.GetWidth(), item.GetHeight()))); + RectWH(ProportionalStretch(place.GetWidth(), place.GetHeight(), item.GetWidth(), item.GetHeight()))); default: return RectWH(place.Left + item.Left, place.Top + item.Top, item.GetWidth(), item.GetHeight()); } @@ -127,3 +129,4 @@ Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &place //} // namespace Shared //} // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/ini_util.cpp b/engines/ags/shared/util/ini_util.cpp index b5b773f9af30..7c7bb0b1f80a 100644 --- a/engines/ags/shared/util/ini_util.cpp +++ b/engines/ags/shared/util/ini_util.cpp @@ -27,6 +27,7 @@ #include "util/stream.h" #include "util/textstreamwriter.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -70,7 +71,7 @@ void IniUtil::Write(const String &file, const ConfigTree &tree) { TextStreamWriter writer(fs.get()); for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) { - const String &sec_key = it_sec->first; + const String &sec_key = it_sec->first; const StringOrderMap &sec_tree = it_sec->second; if (!sec_tree.size()) @@ -82,7 +83,7 @@ void IniUtil::Write(const String &file, const ConfigTree &tree) { } // write all items for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) { - const String &item_key = keyval->first; + const String &item_key = keyval->first; const String &item_value = keyval->second; writer.WriteFormat("%s = %s", item_key.GetCStr(), item_value.GetCStr()); @@ -137,7 +138,7 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { // Replace matching items for (ItemIterator item = sec->Begin(); item != sec->End(); ++item) { - String key = item->GetKey(); + String key = item->GetKey(); StrStrOIter keyval = subtree.find(key); if (keyval == subtree.end()) continue; // this item is not interesting for us @@ -181,3 +182,4 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/inifile.cpp b/engines/ags/shared/util/inifile.cpp index 3841e2e3c4a9..200fbe21feeb 100644 --- a/engines/ags/shared/util/inifile.cpp +++ b/engines/ags/shared/util/inifile.cpp @@ -26,6 +26,8 @@ #include "util/textstreamreader.h" #include "util/textstreamwriter.h" +namespace AGS3 { + // TODO: replace with C++11 std::isblank library function namespace agsstd { inline int isblank(int ch) { @@ -164,7 +166,7 @@ const char *SkipSpace(const char *line, const char *endl) { // The 'endl' must point beyond the last character of the string // (e.g. terminator). const char *ParsePaddedString(const char *line, const char *endl, - const char *&str_at, const char *&str_end) { + const char *&str_at, const char *&str_end) { // skip left padding for (; line != endl && agsstd::isblank(*line); ++line); str_at = line; @@ -206,7 +208,7 @@ void IniFile::Read(Stream *in) { // Detect the kind of string we found if ((endl - pstr >= 2 && *pstr == '/' && *(pstr + 1) == '/') || - (endl - pstr >= 1 && (*pstr == '#' || *pstr == ';'))) { + (endl - pstr >= 1 && (*pstr == '#' || *pstr == ';'))) { StrPos nullpos(0, 0); cur_section->InsertItem(cur_section->End(), ItemDef(line, nullpos, nullpos, -1)); continue; @@ -268,3 +270,4 @@ void IniFile::Write(Stream *out) const { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/lzw.cpp b/engines/ags/shared/util/lzw.cpp index be39388a6e37..8c78f628e463 100644 --- a/engines/ags/shared/util/lzw.cpp +++ b/engines/ags/shared/util/lzw.cpp @@ -30,6 +30,8 @@ #include "ac/common.h" // quit #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; #ifdef _MANAGED @@ -67,7 +69,7 @@ int insert(int i, int run) { p = &root[(unsigned char)lzbuffer[i]]; lson[i] = rson[i] = NIL; while ((j = *p) != NIL) { - for (n = min(k, l); n < run && (c = (lzbuffer[j + n] - lzbuffer[i + n])) == 0; n++) ; + for (n = min(k, l); n < run && (c = (lzbuffer[j + n] - lzbuffer[i + n])) == 0; n++); if (n > match) { match = n; @@ -219,7 +221,7 @@ void myputc(int ccc, Stream *out) { void lzwexpand(Stream *lzw_in, Stream *out) { int bits, ch, i, j, len, mask; char *lzbuffer; -// printf(" UnShrinking: %s ",filena); + // printf(" UnShrinking: %s ",filena); putbytes = 0; lzbuffer = (char *)malloc(N); @@ -273,3 +275,5 @@ unsigned char *lzwexpand_to_mem(Stream *in) { lzwexpand(in, nullptr); return membuff; } + +} // namespace AGS3 diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp index 65b730665b14..71c6596c3567 100644 --- a/engines/ags/shared/util/misc.cpp +++ b/engines/ags/shared/util/misc.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #if !AGS_PLATFORM_OS_WINDOWS #include #endif @@ -62,14 +63,14 @@ #include "util/file.h" #include "util/stream.h" +namespace AGS3 { using namespace AGS::Shared; #if !defined (AGS_CASE_SENSITIVE_FILESYSTEM) -#include /* File Name Concatenator basically on Windows / DOS */ char *ci_find_file(const char *dir_name, const char *file_name) { - char *diamond = NULL; + char *diamond = NULL; if (dir_name == NULL && file_name == NULL) return NULL; @@ -90,12 +91,12 @@ char *ci_find_file(const char *dir_name, const char *file_name) { /* Case Insensitive File Find */ char *ci_find_file(const char *dir_name, const char *file_name) { struct stat statbuf; - struct dirent *entry = nullptr; - DIR *rough = nullptr; - DIR *prevdir = nullptr; - char *diamond = nullptr; - char *directory = nullptr; - char *filename = nullptr; + struct dirent *entry = nullptr; + DIR *rough = nullptr; + DIR *prevdir = nullptr; + char *diamond = nullptr; + char *directory = nullptr; + char *filename = nullptr; if (dir_name == nullptr && file_name == nullptr) return nullptr; @@ -117,16 +118,16 @@ char *ci_find_file(const char *dir_name, const char *file_name) { } if (directory == nullptr) { - char *match = nullptr; + char *match = nullptr; int match_len = 0; - int dir_len = 0; + int dir_len = 0; match = get_filename(filename); if (match == nullptr) return nullptr; match_len = strlen(match); - dir_len = (match - filename); + dir_len = (match - filename); if (dir_len == 0) { directory = (char *)malloc(2); @@ -192,7 +193,7 @@ Stream *ci_fopen(const char *file_name, FileOpenMode open_mode, FileWorkMode wor char *fullpath = ci_find_file(nullptr, (char *)file_name); /* If I didn't find a file, this could be writing a new file, - so use whatever file_name they passed */ + so use whatever file_name they passed */ if (fullpath == nullptr) { fs = File::OpenFile(file_name, open_mode, work_mode); } else { @@ -203,3 +204,5 @@ Stream *ci_fopen(const char *file_name, FileOpenMode open_mode, FileWorkMode wor return fs; #endif } + +} // namespace AGS3 diff --git a/engines/ags/shared/util/mutifilelib.cpp b/engines/ags/shared/util/mutifilelib.cpp index 03ff460569f3..9d578e01bb0f 100644 --- a/engines/ags/shared/util/mutifilelib.cpp +++ b/engines/ags/shared/util/mutifilelib.cpp @@ -25,6 +25,7 @@ #include "util/stream.h" #include "util/string_utils.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -34,12 +35,12 @@ const String TailSig = "CLIB\x1\x2\x3\x4SIGE"; static const size_t SingleFilePswLen = 13; -static const size_t MaxAssetFileLen = 100; -static const size_t MaxDataFileLen = 50; -static const size_t V10LibFileLen = 20; -static const size_t V10AssetFileLen = 25; +static const size_t MaxAssetFileLen = 100; +static const size_t MaxDataFileLen = 50; +static const size_t V10LibFileLen = 20; +static const size_t V10AssetFileLen = 25; -static const int EncryptionRandSeed = 9338638; +static const int EncryptionRandSeed = 9338638; static const String EncryptionString = "My\x1\xde\x4Jibzle"; MFLError ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_version, soff_t *p_abs_offset); @@ -94,7 +95,7 @@ MFLUtil::MFLError MFLUtil::ReadHeader(AssetLibInfo &lib, Stream *in) { // (since only base data file may be EXE file, other clib parts are always on their own) if (abs_offset > 0) { for (AssetVec::iterator it = lib.AssetInfos.begin(); - it != lib.AssetInfos.end(); ++it) { + it != lib.AssetInfos.end(); ++it) { if (it->LibUid == 0) it->Offset += abs_offset; } @@ -149,9 +150,9 @@ MFLUtil::MFLError MFLUtil::ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_vers // read library header MFLVersion lib_version = (MFLVersion)in->ReadByte(); if ((lib_version != kMFLVersion_SingleLib) && (lib_version != kMFLVersion_MultiV10) && - (lib_version != kMFLVersion_MultiV11) && (lib_version != kMFLVersion_MultiV15) && - (lib_version != kMFLVersion_MultiV20) && (lib_version != kMFLVersion_MultiV21) && - lib_version != kMFLVersion_MultiV30) + (lib_version != kMFLVersion_MultiV11) && (lib_version != kMFLVersion_MultiV15) && + (lib_version != kMFLVersion_MultiV20) && (lib_version != kMFLVersion_MultiV21) && + lib_version != kMFLVersion_MultiV30) return kMFLErrLibVersion; // unsupported version if (p_lib_version) @@ -381,7 +382,7 @@ void MFLUtil::DecryptText(char *text) { int MFLUtil::GetNextPseudoRand(int &rand_val) { return (((rand_val = rand_val * 214013L - + 2531011L) >> 16) & 0x7fff); + + 2531011L) >> 16) & 0x7fff); } void MFLUtil::ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &rand_val) { @@ -417,5 +418,6 @@ void MFLUtil::ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_ } } -} // namespace AGS } // namespace Shared +} // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp index a3b88923a77d..ad47317fe721 100644 --- a/engines/ags/shared/util/path.cpp +++ b/engines/ags/shared/util/path.cpp @@ -28,6 +28,8 @@ #include "util/path.h" #include "util/stdio_compat.h" +namespace AGS3 { + // TODO: implement proper portable path length #ifndef MAX_PATH #define MAX_PATH 512 @@ -64,9 +66,9 @@ int ComparePaths(const String &path1, const String &path2) { int cmp_result = #if defined AGS_CASE_SENSITIVE_FILESYSTEM - fixed_path1.Compare(fixed_path2); + fixed_path1.Compare(fixed_path2); #else - fixed_path1.CompareNoCase(fixed_path2); + fixed_path1.CompareNoCase(fixed_path2); #endif // AGS_CASE_SENSITIVE_FILESYSTEM return cmp_result; } @@ -91,7 +93,7 @@ bool IsSameOrSubDir(const String &parent, const String &path) { char relative[MAX_PATH]; // canonicalize_filename treats "." as "./." (file in working dir) const char *use_parent = parent == "." ? "./" : parent; - const char *use_path = path == "." ? "./" : path; + const char *use_path = path == "." ? "./" : path; canonicalize_filename(can_parent, use_parent, MAX_PATH); canonicalize_filename(can_path, use_path, MAX_PATH); const char *pstr = make_relative_filename(relative, can_parent, can_path, MAX_PATH); @@ -243,3 +245,4 @@ String GetCmdLinePathInASCII(const char *arg, int arg_index) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/proxystream.cpp b/engines/ags/shared/util/proxystream.cpp index 71fe5a17a501..c8c810a7ab73 100644 --- a/engines/ags/shared/util/proxystream.cpp +++ b/engines/ags/shared/util/proxystream.cpp @@ -22,6 +22,7 @@ #include "util/proxystream.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -154,3 +155,4 @@ bool ProxyStream::Seek(soff_t offset, StreamSeek origin) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/stream.cpp b/engines/ags/shared/util/stream.cpp index 33b71778749a..29a46cafb02c 100644 --- a/engines/ags/shared/util/stream.cpp +++ b/engines/ags/shared/util/stream.cpp @@ -22,6 +22,7 @@ #include "util/stream.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -38,3 +39,4 @@ size_t Stream::WriteByteCount(uint8_t b, size_t count) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp index 21e10d1f2841..cff8342c583f 100644 --- a/engines/ags/shared/util/string.cpp +++ b/engines/ags/shared/util/string.cpp @@ -28,6 +28,7 @@ #include "util/string.h" #include "util/string_compat.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -210,7 +211,7 @@ size_t String::FindString(const char *cstr, size_t from) const { } bool String::FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, - size_t &from, size_t &to) const { + size_t &from, size_t &to) const { if (!_cstr || !separator) { return false; } @@ -247,7 +248,7 @@ bool String::FindSection(char separator, size_t first, size_t last, bool exclude // correct the indices to stay in the [0; length] range assert(slice_from <= slice_to); from = Math::Clamp(slice_from, (size_t)0, _len); - to = Math::Clamp(slice_to, (size_t)0, _len); + to = Math::Clamp(slice_to, (size_t)0, _len); return true; } return false; @@ -341,7 +342,7 @@ String String::RightSection(char separator, bool exclude_separator) const { } String String::Section(char separator, size_t first, size_t last, - bool exclude_first_sep, bool exclude_last_sep) const { + bool exclude_first_sep, bool exclude_last_sep) const { if (!_cstr || !separator) { return String(); } @@ -349,7 +350,7 @@ String String::Section(char separator, size_t first, size_t last, size_t slice_from; size_t slice_to; if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, - slice_from, slice_to)) { + slice_from, slice_to)) { return Mid(slice_from, slice_to - slice_from); } return String(); @@ -471,7 +472,7 @@ void String::ClipRightSection(char separator, bool include_separator) { } void String::ClipSection(char separator, size_t first, size_t last, - bool include_first_sep, bool include_last_sep) { + bool include_first_sep, bool include_last_sep) { if (!_cstr || !separator) { return; } @@ -479,7 +480,7 @@ void String::ClipSection(char separator, size_t first, size_t last, size_t slice_from; size_t slice_to; if (FindSection(separator, first, last, !include_first_sep, !include_last_sep, - slice_from, slice_to)) { + slice_from, slice_to)) { ClipMid(slice_from, slice_to - slice_from); } } @@ -526,7 +527,7 @@ void String::Free() { assert(_bufHead->RefCount > 0); _bufHead->RefCount--; if (!_bufHead->RefCount) { - delete [] _buf; + delete[] _buf; } } _buf = nullptr; @@ -597,7 +598,7 @@ void String::Reverse() { if (!_cstr || GetLength() <= 1) return; for (char *fw = _cstr, *bw = _cstr + _len - 1; - *fw; ++fw, --bw) { + *fw; ++fw, --bw) { std::swap(*fw, *bw); } } @@ -737,7 +738,7 @@ void String::TruncateToRightSection(char separator, bool exclude_separator) { } void String::TruncateToSection(char separator, size_t first, size_t last, - bool exclude_first_sep, bool exclude_last_sep) { + bool exclude_first_sep, bool exclude_last_sep) { if (!_cstr || !separator) { return; } @@ -745,7 +746,7 @@ void String::TruncateToSection(char separator, size_t first, size_t last, size_t slice_from; size_t slice_to; if (FindSection(separator, first, last, exclude_first_sep, exclude_last_sep, - slice_from, slice_to)) { + slice_from, slice_to)) { TruncateToMid(slice_from, slice_to - slice_from); } else { Empty(); @@ -833,12 +834,12 @@ void String::ReserveAndShift(bool left, size_t more_length) { // make sure we make use of all of our space const char *cstr_head = _buf + sizeof(String::BufHeader); size_t free_space = left ? - _cstr - cstr_head : - (cstr_head + _bufHead->Capacity) - (_cstr + _len); + _cstr - cstr_head : + (cstr_head + _bufHead->Capacity) - (_cstr + _len); if (free_space < more_length) { Align((left ? - _cstr + (more_length - free_space) : - _cstr - (more_length - free_space)) - cstr_head); + _cstr + (more_length - free_space) : + _cstr - (more_length - free_space)) - cstr_head); } } } else { @@ -848,3 +849,4 @@ void String::ReserveAndShift(bool left, size_t more_length) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp index e624738f1a1c..fe0dbdec08d5 100644 --- a/engines/ags/shared/util/string_utils.cpp +++ b/engines/ags/shared/util/string_utils.cpp @@ -27,6 +27,8 @@ #include "util/string_utils.h" #include "util/stream.h" +namespace AGS3 { + using namespace AGS::Shared; String cbuf_to_string_and_free(char *char_buf) { @@ -158,3 +160,4 @@ void StrUtil::WriteCStr(const String &s, Stream *out) { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/textstreamreader.cpp b/engines/ags/shared/util/textstreamreader.cpp index ec619da2061b..a19169470db1 100644 --- a/engines/ags/shared/util/textstreamreader.cpp +++ b/engines/ags/shared/util/textstreamreader.cpp @@ -24,6 +24,7 @@ #include "util/stream.h" #include "util/textstreamreader.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -134,3 +135,4 @@ String TextStreamReader::ReadAll() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/textstreamwriter.cpp b/engines/ags/shared/util/textstreamwriter.cpp index 2e2eb97301dc..1d72acc24cf2 100644 --- a/engines/ags/shared/util/textstreamwriter.cpp +++ b/engines/ags/shared/util/textstreamwriter.cpp @@ -26,13 +26,14 @@ #include "util/textstreamwriter.h" #include "util/stream.h" +namespace AGS3 { namespace AGS { namespace Shared { #if AGS_PLATFORM_OS_WINDOWS -static const char Endl[2] = {'\r', '\n'}; +static const char Endl[2] = { '\r', '\n' }; #else -static const char Endl[1] = {'\n'}; +static const char Endl[1] = { '\n' }; #endif @@ -95,12 +96,12 @@ void TextStreamWriter::WriteFormat(const char *fmt, ...) { va_start(argptr, fmt); int need_length = vsnprintf(nullptr, 0, fmt, argptr); va_start(argptr, fmt); // Reset argptr - char *buffer = new char[need_length + 1]; + char *buffer = new char[need_length + 1]; vsprintf(buffer, fmt, argptr); va_end(argptr); _stream->Write(buffer, need_length); - delete [] buffer; + delete[] buffer; } void TextStreamWriter::WriteLineBreak() { @@ -110,3 +111,4 @@ void TextStreamWriter::WriteLineBreak() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/version.cpp b/engines/ags/shared/util/version.cpp index 6b1a273f52b8..f3f7ae9ebc8f 100644 --- a/engines/ags/shared/util/version.cpp +++ b/engines/ags/shared/util/version.cpp @@ -23,6 +23,7 @@ #include #include "util/version.h" +namespace AGS3 { namespace AGS { namespace Shared { @@ -134,3 +135,4 @@ void Version::MakeString() { } // namespace Shared } // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/shared/util/wgt2allg.cpp b/engines/ags/shared/util/wgt2allg.cpp index 4a37ce5b83f4..8975fd02f7bd 100644 --- a/engines/ags/shared/util/wgt2allg.cpp +++ b/engines/ags/shared/util/wgt2allg.cpp @@ -25,6 +25,8 @@ #include "util/stream.h" #include "util/wgt2allg.h" +namespace AGS3 { + using namespace AGS::Shared; #ifdef __cplusplus @@ -32,180 +34,182 @@ extern "C" { #endif -void wsetrgb(int coll, int r, int g, int b, color *pall) { - pall[coll].r = r; - pall[coll].g = g; - pall[coll].b = b; -} + void wsetrgb(int coll, int r, int g, int b, color *pall) { + pall[coll].r = r; + pall[coll].g = g; + pall[coll].b = b; + } -void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall) { - int jj; - if (dir == 0) { - // rotate left - color tempp = pall[start]; + void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall) { + int jj; + if (dir == 0) { + // rotate left + color tempp = pall[start]; - for (jj = start; jj < finish; jj++) - pall[jj] = pall[jj + 1]; + for (jj = start; jj < finish; jj++) + pall[jj] = pall[jj + 1]; - pall[finish] = tempp; - } else { - // rotate right - color tempp = pall[finish]; + pall[finish] = tempp; + } else { + // rotate right + color tempp = pall[finish]; - for (jj = finish - 1; jj >= start; jj--) - pall[jj + 1] = pall[jj]; + for (jj = finish - 1; jj >= start; jj--) + pall[jj + 1] = pall[jj]; - pall[start] = tempp; + pall[start] = tempp; + } } -} - -Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2) { - Bitmap *tempbitm; - int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; - if (twid < 1) - twid = 1; + Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2) { + Bitmap *tempbitm; + int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; - if (thit < 1) - thit = 1; + if (twid < 1) + twid = 1; - tempbitm = BitmapHelper::CreateBitmap(twid, thit); + if (thit < 1) + thit = 1; - if (tempbitm == nullptr) - return nullptr; + tempbitm = BitmapHelper::CreateBitmap(twid, thit); - tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); - return tempbitm; -} + if (tempbitm == nullptr) + return nullptr; -int wloadsprites(color *pall, char *filnam, Bitmap **sarray, int strt, int eend) { - int vers; - char buff[20]; - int numspri = 0, vv, hh, wdd, htt; - - Stream *in = Common::AssetManager::OpenAsset(filnam); - if (in == nullptr) - return -1; - - vers = in->ReadInt16(); - in->ReadArray(&buff[0], 13, 1); - for (vv = 0; vv < 256; vv++) // there's a filler byte - in->ReadArray(&pall[vv], 3, 1); - - if (vers > 4) - return -1; - - if (vers == 4) - numspri = in->ReadInt16(); - else { - numspri = in->ReadInt16(); - if ((numspri < 2) || (numspri > 200)) - numspri = 200; + tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); + return tempbitm; } - for (vv = strt; vv <= eend; vv++) - sarray[vv] = nullptr; + int wloadsprites(color *pall, char *filnam, Bitmap **sarray, int strt, int eend) { + int vers; + char buff[20]; + int numspri = 0, vv, hh, wdd, htt; + + Stream *in = Common::AssetManager::OpenAsset(filnam); + if (in == nullptr) + return -1; - for (vv = 0; vv <= numspri; vv++) { - int coldep = in->ReadInt16(); + vers = in->ReadInt16(); + in->ReadArray(&buff[0], 13, 1); + for (vv = 0; vv < 256; vv++) // there's a filler byte + in->ReadArray(&pall[vv], 3, 1); - if (coldep == 0) { - sarray[vv] = nullptr; - if (in->EOS()) - break; + if (vers > 4) + return -1; - continue; + if (vers == 4) + numspri = in->ReadInt16(); + else { + numspri = in->ReadInt16(); + if ((numspri < 2) || (numspri > 200)) + numspri = 200; } - if (in->EOS()) - break; + for (vv = strt; vv <= eend; vv++) + sarray[vv] = nullptr; - if (vv > eend) - break; + for (vv = 0; vv <= numspri; vv++) { + int coldep = in->ReadInt16(); - wdd = in->ReadInt16(); - htt = in->ReadInt16(); - if (vv < strt) { - in->Seek(wdd * htt); - continue; - } - sarray[vv] = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); + if (coldep == 0) { + sarray[vv] = nullptr; + if (in->EOS()) + break; - if (sarray[vv] == nullptr) { - delete in; - return -1; - } + continue; + } - for (hh = 0; hh < htt; hh++) - in->ReadArray(&sarray[vv]->GetScanLineForWriting(hh)[0], wdd * coldep, 1); - } - delete in; - return 0; -} + if (in->EOS()) + break; -void wputblock(Common::Bitmap *ds, int xx, int yy, Bitmap *bll, int xray) { - if (xray) - ds->Blit(bll, xx, yy, Common::kBitmap_Transparency); - else - ds->Blit(bll, 0, 0, xx, yy, bll->GetWidth(), bll->GetHeight()); -} + if (vv > eend) + break; -Bitmap wputblock_wrapper; // [IKM] argh! :[ -void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray) { - wputblock_wrapper.WrapAllegroBitmap(bll, true); - if (xray) - ds->Blit(&wputblock_wrapper, xx, yy, Common::kBitmap_Transparency); - else - ds->Blit(&wputblock_wrapper, 0, 0, xx, yy, wputblock_wrapper.GetWidth(), wputblock_wrapper.GetHeight()); -} + wdd = in->ReadInt16(); + htt = in->ReadInt16(); + if (vv < strt) { + in->Seek(wdd * htt); + continue; + } + sarray[vv] = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); + + if (sarray[vv] == nullptr) { + delete in; + return -1; + } + + for (hh = 0; hh < htt; hh++) + in->ReadArray(&sarray[vv]->GetScanLineForWriting(hh)[0], wdd * coldep, 1); + } + delete in; + return 0; + } -const int col_lookups[32] = { - 0x000000, 0x0000A0, 0x00A000, 0x00A0A0, 0xA00000, // 4 - 0xA000A0, 0xA05000, 0xA0A0A0, 0x505050, 0x5050FF, 0x50FF50, 0x50FFFF, // 11 - 0xFF5050, 0xFF50FF, 0xFFFF50, 0xFFFFFF, 0x000000, 0x101010, 0x202020, // 18 - 0x303030, 0x404040, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, // 25 - 0xA0A0A0, 0xB0B0B0, 0xC0C0C0, 0xD0D0D0, 0xE0E0E0, 0xF0F0F0 -}; + void wputblock(Common::Bitmap *ds, int xx, int yy, Bitmap *bll, int xray) { + if (xray) + ds->Blit(bll, xx, yy, Common::kBitmap_Transparency); + else + ds->Blit(bll, 0, 0, xx, yy, bll->GetWidth(), bll->GetHeight()); + } -int __wremap_keep_transparent = 1; + Bitmap wputblock_wrapper; // [IKM] argh! :[ + void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray) { + wputblock_wrapper.WrapAllegroBitmap(bll, true); + if (xray) + ds->Blit(&wputblock_wrapper, xx, yy, Common::kBitmap_Transparency); + else + ds->Blit(&wputblock_wrapper, 0, 0, xx, yy, wputblock_wrapper.GetWidth(), wputblock_wrapper.GetHeight()); + } -void wremap(color *pal1, Bitmap *picc, color *pal2) { - int jj; - unsigned char color_mapped_table[256]; + const int col_lookups[32] = { + 0x000000, 0x0000A0, 0x00A000, 0x00A0A0, 0xA00000, // 4 + 0xA000A0, 0xA05000, 0xA0A0A0, 0x505050, 0x5050FF, 0x50FF50, 0x50FFFF, // 11 + 0xFF5050, 0xFF50FF, 0xFFFF50, 0xFFFFFF, 0x000000, 0x101010, 0x202020, // 18 + 0x303030, 0x404040, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, // 25 + 0xA0A0A0, 0xB0B0B0, 0xC0C0C0, 0xD0D0D0, 0xE0E0E0, 0xF0F0F0 + }; + + int __wremap_keep_transparent = 1; + + void wremap(color *pal1, Bitmap *picc, color *pal2) { + int jj; + unsigned char color_mapped_table[256]; + + for (jj = 0; jj < 256; jj++) { + if ((pal1[jj].r == 0) && (pal1[jj].g == 0) && (pal1[jj].b == 0)) { + color_mapped_table[jj] = 0; + } else { + color_mapped_table[jj] = bestfit_color(pal2, pal1[jj].r, pal1[jj].g, pal1[jj].b); + } + } - for (jj = 0; jj < 256; jj++) { - if ((pal1[jj].r == 0) && (pal1[jj].g == 0) && (pal1[jj].b == 0)) { - color_mapped_table[jj] = 0; - } else { - color_mapped_table[jj] = bestfit_color(pal2, pal1[jj].r, pal1[jj].g, pal1[jj].b); + if (__wremap_keep_transparent > 0) { + // keep transparency + color_mapped_table[0] = 0; + // any other pixels which are being mapped to 0, map to 16 instead + for (jj = 1; jj < 256; jj++) { + if (color_mapped_table[jj] == 0) + color_mapped_table[jj] = 16; + } } - } - if (__wremap_keep_transparent > 0) { - // keep transparency - color_mapped_table[0] = 0; - // any other pixels which are being mapped to 0, map to 16 instead - for (jj = 1; jj < 256; jj++) { - if (color_mapped_table[jj] == 0) - color_mapped_table[jj] = 16; + int pic_size = picc->GetWidth() * picc->GetHeight(); + for (jj = 0; jj < pic_size; jj++) { + int xxl = jj % (picc->GetWidth()), yyl = jj / (picc->GetWidth()); + int rr = picc->GetPixel(xxl, yyl); + picc->PutPixel(xxl, yyl, color_mapped_table[rr]); } } - int pic_size = picc->GetWidth() * picc->GetHeight(); - for (jj = 0; jj < pic_size; jj++) { - int xxl = jj % (picc->GetWidth()), yyl = jj / (picc->GetWidth()); - int rr = picc->GetPixel(xxl, yyl); - picc->PutPixel(xxl, yyl, color_mapped_table[rr]); + void wremapall(color *pal1, Bitmap *picc, color *pal2) { + __wremap_keep_transparent--; + wremap(pal1, picc, pal2); + __wremap_keep_transparent++; } -} - -void wremapall(color *pal1, Bitmap *picc, color *pal2) { - __wremap_keep_transparent--; - wremap(pal1, picc, pal2); - __wremap_keep_transparent++; -} #ifdef __cplusplus } #endif + +} // namespace AGS3 From 1dba242b0640a4409db09e8aef334ea8f51ff14e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 21 Nov 2020 18:19:22 -0800 Subject: [PATCH 011/215] AGS: Added shared/util/ folder --- engines/ags/engine/ac/global_video.cpp | 2 +- engines/ags/engine/ac/keycode.cpp | 2 +- engines/ags/engine/gfx/ali3dsw.h | 2 +- engines/ags/engine/gfx/ogl_headers.h | 4 +- .../ags/engine/platform/android/acpland.cpp | 2 +- engines/ags/engine/platform/ios/acplios.cpp | 2 +- engines/ags/engine/platform/linux/acpllnx.cpp | 2 +- .../ags/engine/platform/windows/acplwin.cpp | 2 +- .../engine/platform/windows/gfx/ali3dd3d.cpp | 2 +- .../engine/platform/windows/gfx/ali3dd3d.h | 2 +- .../platform/windows/media/video/acwavi.cpp | 2 +- .../platform/windows/media/video/acwavi3d.cpp | 2 +- .../platform/windows/win_ex_handling.cpp | 2 +- engines/ags/module.mk | 25 +- engines/ags/shared/ac/audiocliptype.cpp | 4 +- engines/ags/shared/ac/characterinfo.cpp | 6 +- engines/ags/shared/ac/characterinfo.h | 2 +- engines/ags/shared/ac/common.cpp | 4 +- engines/ags/shared/ac/common_defines.h | 2 +- engines/ags/shared/ac/dialogtopic.cpp | 4 +- .../ags/shared/ac/dynobj/scriptaudioclip.cpp | 4 +- .../ags/shared/ac/dynobj/scriptaudioclip.h | 2 +- engines/ags/shared/ac/gamesetupstruct.cpp | 14 +- engines/ags/shared/ac/gamesetupstruct.h | 18 +- engines/ags/shared/ac/gamesetupstructbase.cpp | 12 +- engines/ags/shared/ac/gamesetupstructbase.h | 8 +- engines/ags/shared/ac/gamestructdefines.h | 4 +- engines/ags/shared/ac/interfaceelement.h | 2 +- engines/ags/shared/ac/inventoryiteminfo.cpp | 6 +- engines/ags/shared/ac/mousecursor.cpp | 4 +- engines/ags/shared/ac/oldgamesetupstruct.h | 14 +- engines/ags/shared/ac/spritecache.cpp | 18 +- engines/ags/shared/ac/spritecache.h | 8 +- engines/ags/shared/ac/view.cpp | 6 +- engines/ags/shared/ac/view.h | 2 +- engines/ags/shared/ac/wordsdictionary.cpp | 10 +- engines/ags/shared/ac/wordsdictionary.h | 2 +- engines/ags/shared/api/stream_api.h | 4 +- engines/ags/shared/core/asset.cpp | 2 +- engines/ags/shared/core/asset.h | 4 +- engines/ags/shared/core/assetmanager.cpp | 10 +- engines/ags/shared/core/assetmanager.h | 10 +- engines/ags/shared/core/platform.h | 12 +- engines/ags/shared/core/types.h | 32 +- engines/ags/shared/debugging/assert.h | 2 +- engines/ags/shared/debugging/debugmanager.cpp | 6 +- engines/ags/shared/debugging/debugmanager.h | 12 +- engines/ags/shared/debugging/out.h | 2 +- engines/ags/shared/debugging/outputhandler.h | 4 +- engines/ags/shared/font/fonts.cpp | 22 +- engines/ags/shared/font/fonts.h | 6 +- engines/ags/shared/font/ttffontrenderer.cpp | 14 +- engines/ags/shared/font/ttffontrenderer.h | 4 +- engines/ags/shared/font/wfnfont.cpp | 10 +- engines/ags/shared/font/wfnfont.h | 4 +- engines/ags/shared/font/wfnfontrenderer.cpp | 14 +- engines/ags/shared/font/wfnfontrenderer.h | 4 +- engines/ags/shared/game/customproperties.cpp | 6 +- engines/ags/shared/game/customproperties.h | 6 +- engines/ags/shared/game/interactions.cpp | 10 +- engines/ags/shared/game/interactions.h | 4 +- engines/ags/shared/game/main_game_file.cpp | 36 +-- engines/ags/shared/game/main_game_file.h | 20 +- engines/ags/shared/game/plugininfo.h | 4 +- engines/ags/shared/game/room_file.cpp | 28 +- engines/ags/shared/game/room_file.h | 12 +- .../ags/shared/game/room_file_deprecated.cpp | 4 +- engines/ags/shared/game/roomstruct.cpp | 8 +- engines/ags/shared/game/roomstruct.h | 10 +- engines/ags/shared/gfx/allegrobitmap.cpp | 6 +- engines/ags/shared/gfx/allegrobitmap.h | 26 +- engines/ags/shared/gfx/bitmap.cpp | 4 +- engines/ags/shared/gfx/bitmap.h | 7 +- engines/ags/shared/gui/guibutton.cpp | 10 +- engines/ags/shared/gui/guibutton.h | 6 +- engines/ags/shared/gui/guiinv.cpp | 10 +- engines/ags/shared/gui/guiinv.h | 4 +- engines/ags/shared/gui/guilabel.cpp | 12 +- engines/ags/shared/gui/guilabel.h | 6 +- engines/ags/shared/gui/guilistbox.cpp | 10 +- engines/ags/shared/gui/guilistbox.h | 6 +- engines/ags/shared/gui/guimain.cpp | 28 +- engines/ags/shared/gui/guimain.h | 14 +- engines/ags/shared/gui/guiobject.cpp | 8 +- engines/ags/shared/gui/guiobject.h | 8 +- engines/ags/shared/gui/guislider.cpp | 8 +- engines/ags/shared/gui/guislider.h | 4 +- engines/ags/shared/gui/guitextbox.cpp | 10 +- engines/ags/shared/gui/guitextbox.h | 6 +- engines/ags/shared/script/cc_error.cpp | 8 +- engines/ags/shared/script/cc_error.h | 2 +- engines/ags/shared/script/cc_options.cpp | 2 +- engines/ags/shared/script/cc_script.cpp | 14 +- engines/ags/shared/script/cc_script.h | 4 +- engines/ags/shared/util/alignedstream.cpp | 6 +- engines/ags/shared/util/alignedstream.h | 2 +- engines/ags/shared/util/bbop.h | 4 +- engines/ags/shared/util/bufferedstream.cpp | 18 +- engines/ags/shared/util/bufferedstream.h | 6 +- engines/ags/shared/util/compress.cpp | 21 +- engines/ags/shared/util/compress.h | 25 +- engines/ags/shared/util/datastream.cpp | 2 +- engines/ags/shared/util/datastream.h | 4 +- engines/ags/shared/util/directory.cpp | 33 +- engines/ags/shared/util/directory.h | 4 +- engines/ags/shared/util/error.h | 4 +- engines/ags/shared/util/file.cpp | 63 ++-- engines/ags/shared/util/file.h | 4 +- engines/ags/shared/util/filestream.cpp | 77 +++-- engines/ags/shared/util/filestream.h | 9 +- engines/ags/shared/util/geometry.cpp | 9 +- engines/ags/shared/util/geometry.h | 2 +- engines/ags/shared/util/ini_util.cpp | 48 +-- engines/ags/shared/util/ini_util.h | 11 +- engines/ags/shared/util/inifile.cpp | 12 +- engines/ags/shared/util/inifile.h | 5 +- engines/ags/shared/util/lzw.cpp | 18 +- engines/ags/shared/util/lzw.h | 4 +- engines/ags/shared/util/memory.h | 6 +- engines/ags/shared/util/misc.cpp | 18 +- engines/ags/shared/util/misc.h | 8 +- engines/ags/shared/util/multifilelib.h | 8 +- engines/ags/shared/util/mutifilelib.cpp | 16 +- engines/ags/shared/util/path.cpp | 13 +- engines/ags/shared/util/path.h | 2 +- engines/ags/shared/util/proxystream.cpp | 2 +- engines/ags/shared/util/proxystream.h | 2 +- engines/ags/shared/util/stdio_compat.c | 95 ------ engines/ags/shared/util/stdio_compat.cpp | 67 ++++ engines/ags/shared/util/stdio_compat.h | 21 +- engines/ags/shared/util/stream.cpp | 2 +- engines/ags/shared/util/stream.h | 2 +- engines/ags/shared/util/string.cpp | 62 ++-- engines/ags/shared/util/string.h | 42 ++- engines/ags/shared/util/string_compat.c | 58 ---- engines/ags/shared/util/string_compat.cpp | 57 ++++ engines/ags/shared/util/string_compat.h | 12 +- engines/ags/shared/util/string_types.h | 69 +++-- engines/ags/shared/util/string_utils.cpp | 17 +- engines/ags/shared/util/string_utils.h | 4 +- engines/ags/shared/util/textreader.h | 2 +- engines/ags/shared/util/textstreamreader.cpp | 6 +- engines/ags/shared/util/textstreamreader.h | 2 +- engines/ags/shared/util/textstreamwriter.cpp | 10 +- engines/ags/shared/util/textstreamwriter.h | 2 +- engines/ags/shared/util/textwriter.h | 2 +- engines/ags/shared/util/version.cpp | 6 +- engines/ags/shared/util/version.h | 4 +- engines/ags/shared/util/wgt2allg.cpp | 290 +++++++++--------- engines/ags/shared/util/wgt2allg.h | 24 +- engines/ags/std/algorithm.h | 42 +++ engines/ags/std/memory.h | 5 + engines/ags/std/vector.h | 2 +- engines/ags/stubs/allegro.cpp | 1 + engines/ags/stubs/allegro/error.cpp | 6 +- engines/ags/stubs/allegro/error.h | 3 +- engines/ags/stubs/allegro/fixed.h | 2 +- engines/ags/stubs/allegro/mouse.cpp | 4 +- 158 files changed, 1131 insertions(+), 1014 deletions(-) delete mode 100644 engines/ags/shared/util/stdio_compat.c create mode 100644 engines/ags/shared/util/stdio_compat.cpp delete mode 100644 engines/ags/shared/util/string_compat.c create mode 100644 engines/ags/shared/util/string_compat.cpp create mode 100644 engines/ags/std/algorithm.h diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp index 0aa8b375daf9..718e91fbde73 100644 --- a/engines/ags/engine/ac/global_video.cpp +++ b/engines/ags/engine/ac/global_video.cpp @@ -20,7 +20,7 @@ * */ -#include +#include "ags/stubs/allegro.h" #include "ac/gamesetup.h" #include "ac/gamestate.h" #include "ac/global_audio.h" diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp index 701790ee2343..6e05ca18539c 100644 --- a/engines/ags/engine/ac/keycode.cpp +++ b/engines/ags/engine/ac/keycode.cpp @@ -22,7 +22,7 @@ #include "ac/keycode.h" -#include +#include "ags/stubs/allegro.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index 0788549a2d9f..e46b5f4cc2fe 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -34,7 +34,7 @@ #include "core/platform.h" #define AGS_DDRAW_GAMMA_CONTROL (AGS_PLATFORM_OS_WINDOWS) -#include +#include "ags/stubs/allegro.h" #if AGS_DDRAW_GAMMA_CONTROL #include diff --git a/engines/ags/engine/gfx/ogl_headers.h b/engines/ags/engine/gfx/ogl_headers.h index 9c41aa6f14f4..595b4647b571 100644 --- a/engines/ags/engine/gfx/ogl_headers.h +++ b/engines/ags/engine/gfx/ogl_headers.h @@ -29,7 +29,7 @@ #include "core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include +#include "ags/stubs/allegro.h" #include #include @@ -37,7 +37,7 @@ #include "glad/glad_wgl.h" #elif AGS_PLATFORM_OS_LINUX -#include +#include "ags/stubs/allegro.h" #include #include diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp index 7ce56c4d18bc..3b191305b56a 100644 --- a/engines/ags/engine/platform/android/acpland.cpp +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -24,7 +24,7 @@ #if AGS_PLATFORM_OS_ANDROID -#include +#include "ags/stubs/allegro.h" #include "platform/base/agsplatformdriver.h" #include "ac/runtime_defines.h" #include "main/config.h" diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp index 56e80d2753c3..a00f5aa2d451 100644 --- a/engines/ags/engine/platform/ios/acplios.cpp +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include "ags/stubs/allegro.h" #include "platform/base/agsplatformdriver.h" #include "ac/runtime_defines.h" #include "main/config.h" diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 092d67a2e3d8..826d0a39d319 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -27,7 +27,7 @@ // ********* LINUX PLACEHOLDER DRIVER ********* #include -#include +#include "ags/stubs/allegro.h" #include #include "ac/runtime_defines.h" #include "gfx/gfxdefines.h" diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index 00965b04f7c0..d585c214bba5 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -27,7 +27,7 @@ // ********* WINDOWS ********* #include -#include +#include "ags/stubs/allegro.h" #include #include "ac/common.h" #include "ac/draw.h" diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index b7d06c1e358e..44cdc82d7d7b 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -32,7 +32,7 @@ #include "platform/windows/gfx/ali3dd3d.h" -#include +#include "ags/stubs/allegro.h" #include #include "ac/timer.h" #include "debug/assert.h" diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index 2833ef7ae87e..ed7fdc392439 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -36,7 +36,7 @@ #endif #include -#include +#include "ags/stubs/allegro.h" #include #include #include "gfx/bitmap.h" diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp index 1e17d09aec50..741ab58b4864 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -33,7 +33,7 @@ #if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) //#define ALLEGRO_STATICLINK // already defined in project settings -#include +#include "ags/stubs/allegro.h" #include #include #include diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp index a22f02848de2..0d6cab1fe1ba 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -32,7 +32,7 @@ #if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) //#define ALLEGRO_STATICLINK // already defined in project settings -#include +#include "ags/stubs/allegro.h" #include #include #include diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index 3f2e35bfeeb2..c8aba200f54c 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -24,7 +24,7 @@ #if AGS_PLATFORM_OS_WINDOWS #include -#include +#include "ags/stubs/allegro.h" #include #include "ac/common.h" #include "ac/common_defines.h" diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 5256e3b69e68..4d51bd9761a4 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -16,7 +16,30 @@ MODULE_OBJS = \ stubs/allegro/mouse.o \ stubs/allegro/sound.o \ stubs/allegro/system.o \ - stubs/allegro/unicode.o + stubs/allegro/unicode.o \ + shared/util/alignedstream.o \ + shared/util/bufferedstream.o \ + shared/util/compress.o \ + shared/util/datastream.o \ + shared/util/directory.o \ + shared/util/file.o \ + shared/util/filestream.o \ + shared/util/geometry.o \ + shared/util/inifile.o \ + shared/util/ini_util.o \ + shared/util/lzw.o \ + shared/util/misc.o \ + shared/util/mutifilelib.o \ + shared/util/path.o \ + shared/util/proxystream.o \ + shared/util/stream.o \ + shared/util/string.o \ + shared/util/string_compat.o \ + shared/util/string_utils.o \ + shared/util/textstreamreader.o \ + shared/util/textstreamwriter.o \ + shared/util/version.o \ + shared/util/wgt2allg.o # This module can be built as a plugin diff --git a/engines/ags/shared/ac/audiocliptype.cpp b/engines/ags/shared/ac/audiocliptype.cpp index d71acd72c2f8..a1de83d396d1 100644 --- a/engines/ags/shared/ac/audiocliptype.cpp +++ b/engines/ags/shared/ac/audiocliptype.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/audiocliptype.h" -#include "util/stream.h" +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/characterinfo.cpp b/engines/ags/shared/ac/characterinfo.cpp index a6572e8d020f..dcc8eeca3e6a 100644 --- a/engines/ags/shared/ac/characterinfo.cpp +++ b/engines/ags/shared/ac/characterinfo.cpp @@ -20,9 +20,9 @@ * */ -#include -#include "ac/characterinfo.h" -#include "util/stream.h" +//include +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h index 4a448299ff4f..287937994ade 100644 --- a/engines/ags/shared/ac/characterinfo.h +++ b/engines/ags/shared/ac/characterinfo.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_CHARACTERINFO_H #define AGS_SHARED_AC_CHARACTERINFO_H -#include "ac/common_defines.h" // constants +#include "ags/shared/ac/common_defines.h" // constants namespace AGS3 { diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index 74a9b6cb9d3b..0990898673c6 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/common.h" -#include "util/string.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/common_defines.h b/engines/ags/shared/ac/common_defines.h index 0311a452fe05..282ad7ea89b3 100644 --- a/engines/ags/shared/ac/common_defines.h +++ b/engines/ags/shared/ac/common_defines.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_DEFINES_H #define AGS_SHARED_AC_DEFINES_H -#include "core/platform.h" +#include "ags/shared/core/platform.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/dialogtopic.cpp b/engines/ags/shared/ac/dialogtopic.cpp index ac185000e3e6..efcbb4f2c16c 100644 --- a/engines/ags/shared/ac/dialogtopic.cpp +++ b/engines/ags/shared/ac/dialogtopic.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/dialogtopic.h" -#include "util/stream.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp index 4bee23fe7cc5..e26d5ace8cea 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/dynobj/scriptaudioclip.h" -#include "util/stream.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index 7167a38d4fd7..de4361bd0408 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_DYNOBJ_SCRIPTAUDIOCLIP_H #define AGS_SHARED_AC_DYNOBJ_SCRIPTAUDIOCLIP_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp index 970b8bc99795..4c4139c82bc0 100644 --- a/engines/ags/shared/ac/gamesetupstruct.cpp +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/audiocliptype.h" -#include "ac/gamesetupstruct.h" -#include "ac/oldgamesetupstruct.h" -#include "ac/wordsdictionary.h" -#include "ac/dynobj/scriptaudioclip.h" -#include "game/interactions.h" -#include "util/alignedstream.h" +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/oldgamesetupstruct.h" +#include "ags/shared/ac/wordsdictionary.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/shared/game/interactions.h" +#include "ags/shared/util/alignedstream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index 951bcfbf4719..76a8be382742 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -23,15 +23,15 @@ #ifndef AGS_SHARED_AC_GAMESETUPSTRUCT_H #define AGS_SHARED_AC_GAMESETUPSTRUCT_H -#include -#include "ac/audiocliptype.h" -#include "ac/characterinfo.h" // TODO: constants to separate header -#include "ac/gamesetupstructbase.h" -#include "ac/inventoryiteminfo.h" -#include "ac/mousecursor.h" -#include "ac/dynobj/scriptaudioclip.h" -#include "game/customproperties.h" -#include "game/main_game_file.h" // TODO: constants to separate header or split out reading functions +//include +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/characterinfo.h" // TODO: constants to separate header +#include "ags/shared/ac/gamesetupstructbase.h" +#include "ags/shared/ac/inventoryiteminfo.h" +#include "ags/shared/ac/mousecursor.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/shared/game/customproperties.h" +#include "ags/shared/game/main_game_file.h" // TODO: constants to separate header or split out reading functions namespace AGS3 { diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp index 9781d3a4a55d..2b03a199b96e 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.cpp +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/characterinfo.h" -#include "ac/gamesetupstructbase.h" -#include "ac/game_version.h" -#include "ac/wordsdictionary.h" -#include "script/cc_script.h" -#include "util/stream.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/gamesetupstructbase.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/wordsdictionary.h" +#include "ags/shared/script/cc_script.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h index fc9ee3cbfd69..045b751634d8 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.h +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -23,10 +23,10 @@ #ifndef AGS_SHARED_AC_GAMESETUPSTRUCTBASE_H #define AGS_SHARED_AC_GAMESETUPSTRUCTBASE_H -#include "ac/game_version.h" -#include "ac/gamestructdefines.h" -#include "util/string.h" -#include "util/wgt2allg.h" // color (allegro RGB) +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/wgt2allg.h" // color (allegro RGB) namespace AGS3 { diff --git a/engines/ags/shared/ac/gamestructdefines.h b/engines/ags/shared/ac/gamestructdefines.h index e865bc296b49..367796aa4333 100644 --- a/engines/ags/shared/ac/gamestructdefines.h +++ b/engines/ags/shared/ac/gamestructdefines.h @@ -23,8 +23,8 @@ #ifndef AGS_SHARED_AC_GAMESTRUCTDEFINES_H #define AGS_SHARED_AC_GAMESTRUCTDEFINES_H -#include "util/geometry.h" -#include "core/types.h" +#include "ags/shared/util/geometry.h" +#include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/interfaceelement.h b/engines/ags/shared/ac/interfaceelement.h index 1b897de03a57..69f8fcaa02f4 100644 --- a/engines/ags/shared/ac/interfaceelement.h +++ b/engines/ags/shared/ac/interfaceelement.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_INTERFACEELEMENT_H #define AGS_SHARED_AC_INTERFACEELEMENT_H -#include "ac/interfacebutton.h" // InterfaceButton +#include "ags/shared/ac/interfacebutton.h" // InterfaceButton namespace AGS3 { diff --git a/engines/ags/shared/ac/inventoryiteminfo.cpp b/engines/ags/shared/ac/inventoryiteminfo.cpp index 3311180c2a8a..148e1362b027 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.cpp +++ b/engines/ags/shared/ac/inventoryiteminfo.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/inventoryiteminfo.h" -#include "util/stream.h" -#include "util/string_utils.h" +#include "ags/shared/ac/inventoryiteminfo.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/mousecursor.cpp b/engines/ags/shared/ac/mousecursor.cpp index 01f9323b92ef..8acbf41b41de 100644 --- a/engines/ags/shared/ac/mousecursor.cpp +++ b/engines/ags/shared/ac/mousecursor.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/mousecursor.h" -#include "util/stream.h" +#include "ags/shared/ac/mousecursor.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/oldgamesetupstruct.h b/engines/ags/shared/ac/oldgamesetupstruct.h index 1ceb6b25c923..cbe8023b2064 100644 --- a/engines/ags/shared/ac/oldgamesetupstruct.h +++ b/engines/ags/shared/ac/oldgamesetupstruct.h @@ -23,15 +23,15 @@ #ifndef AGS_SHARED_AC_OLDGAMESETUPSTRUCT_H #define AGS_SHARED_AC_OLDGAMESETUPSTRUCT_H -#include "ac/characterinfo.h" // OldCharacterInfo, CharacterInfo +#include "ags/shared/ac/characterinfo.h" // OldCharacterInfo, CharacterInfo #ifdef UNUSED_CODE -#include "ac/eventblock.h" // EventBlock +#include "ags/shared/ac/eventblock.h" // EventBlock #endif -#include "ac/interfaceelement.h" // InterfaceElement -#include "ac/inventoryiteminfo.h" // InventoryItemInfo -#include "ac/mousecursor.h" // MouseCursor -#include "ac/wordsdictionary.h" // WordsDictionary -#include "script/cc_script.h" // ccScript +#include "ags/shared/ac/interfaceelement.h" // InterfaceElement +#include "ags/shared/ac/inventoryiteminfo.h" // InventoryItemInfo +#include "ags/shared/ac/mousecursor.h" // MouseCursor +#include "ags/shared/ac/wordsdictionary.h" // WordsDictionary +#include "ags/shared/script/cc_script.h" // ccScript namespace AGS3 { diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp index 592c6665d739..3d850d7fc3e2 100644 --- a/engines/ags/shared/ac/spritecache.cpp +++ b/engines/ags/shared/ac/spritecache.cpp @@ -32,15 +32,15 @@ #pragma warning (disable: 4996 4312) // disable deprecation warnings #endif -#include "ac/common.h" // quit -#include "ac/gamestructdefines.h" -#include "ac/spritecache.h" -#include "core/assetmanager.h" -#include "debug/out.h" -#include "gfx/bitmap.h" -#include "util/compress.h" -#include "util/file.h" -#include "util/stream.h" +#include "ags/shared/ac/common.h" // quit +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/util/compress.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index d7a2eb3593be..a6ed86f3e58f 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -45,10 +45,10 @@ #ifndef AGS_SHARED_AC_SPRITECACHE_H #define AGS_SHARED_AC_SPRITECACHE_H -#include -#include -#include "core/platform.h" -#include "util/error.h" +//include +//include +#include "ags/shared/core/platform.h" +#include "ags/shared/util/error.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/view.cpp b/engines/ags/shared/ac/view.cpp index d9ef44ff663a..614258fb1d26 100644 --- a/engines/ags/shared/ac/view.cpp +++ b/engines/ags/shared/ac/view.cpp @@ -20,9 +20,9 @@ * */ -#include -#include "ac/view.h" -#include "util/alignedstream.h" +//include +#include "ags/shared/ac/view.h" +#include "ags/shared/util/alignedstream.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index f8dc1fc0e59d..41d27ebdd806 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_VIEW_H #define AGS_SHARED_AC_VIEW_H -#include +//include namespace AGS3 { diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp index 5f7d1381d518..9ea0a590ce7a 100644 --- a/engines/ags/shared/ac/wordsdictionary.cpp +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -20,11 +20,11 @@ * */ -#include -#include -#include "ac/wordsdictionary.h" -#include "util/stream.h" -#include "util/string_compat.h" +//include +//include +#include "ags/shared/ac/wordsdictionary.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h index fba3277de8f1..db453aec60db 100644 --- a/engines/ags/shared/ac/wordsdictionary.h +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_WORDSDICTIONARY_H #define AGS_SHARED_AC_WORDSDICTIONARY_H -#include "core/types.h" +#include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/shared/api/stream_api.h b/engines/ags/shared/api/stream_api.h index 9bd209b434ff..682758f1d3e3 100644 --- a/engines/ags/shared/api/stream_api.h +++ b/engines/ags/shared/api/stream_api.h @@ -36,7 +36,7 @@ // TODO: it would probably be better to not include core definition headers // in API class headers, but make separate core headers specifically for // plugins, and let plugin developers include them manually in plugin sources. -#include "core/types.h" +#include "ags/shared/core/types.h" namespace AGS3 { namespace AGS { @@ -78,7 +78,7 @@ class IAGSStream { virtual size_t ReadArrayOfInt32(int32_t *buffer, size_t count) = 0; virtual size_t ReadArrayOfInt64(int64_t *buffer, size_t count) = 0; - virtual size_t WriteInt8(int8_t val) = 0;; + virtual size_t WriteInt8(int8_t val) = 0; virtual size_t WriteInt16(int16_t val) = 0; virtual size_t WriteInt32(int32_t val) = 0; virtual size_t WriteInt64(int64_t val) = 0; diff --git a/engines/ags/shared/core/asset.cpp b/engines/ags/shared/core/asset.cpp index 7c34675faf4f..7cb05ed89de7 100644 --- a/engines/ags/shared/core/asset.cpp +++ b/engines/ags/shared/core/asset.cpp @@ -20,7 +20,7 @@ * */ -#include "core/asset.h" +#include "ags/shared/core/asset.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index a531f8c94ede..34647cc30a8c 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -29,8 +29,8 @@ #ifndef AGS_SHARED_CORE_ASSET_H #define AGS_SHARED_CORE_ASSET_H -#include -#include "util/string.h" +//include +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp index 3017592cb10b..28b8d0a37cb6 100644 --- a/engines/ags/shared/core/assetmanager.cpp +++ b/engines/ags/shared/core/assetmanager.cpp @@ -20,11 +20,11 @@ * */ -#include "core/assetmanager.h" -#include "util/misc.h" // ci_fopen -#include "util/multifilelib.h" -#include "util/path.h" -#include "util/string_utils.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/util/misc.h" // ci_fopen +#include "ags/shared/util/multifilelib.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h index bf942bdfa058..383c61b52dc4 100644 --- a/engines/ags/shared/core/assetmanager.h +++ b/engines/ags/shared/core/assetmanager.h @@ -44,7 +44,7 @@ #ifndef AGS_SHARED_CORE_ASSETMANAGER_H #define AGS_SHARED_CORE_ASSETMANAGER_H -#include "util/file.h" // TODO: extract filestream mode constants or introduce generic ones +#include "ags/shared/util/file.h" // TODO: extract filestream mode constants or introduce generic ones namespace AGS3 { namespace AGS { @@ -138,10 +138,10 @@ class AssetManager { AssetInfo *FindAssetByFileName(const String &asset_name); String MakeLibraryFileNameForAsset(const AssetInfo *asset); - bool GetAssetFromLib(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); - bool GetAssetFromDir(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); - bool GetAssetByPriority(const String &asset_name, AssetLocation &loc, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); - Stream *OpenAssetAsStream(const String &asset_name, FileOpenMode open_mode, FileWorkMode work_mode); + bool GetAssetFromLib(const String &asset_name, AssetLocation &loc, Shared::FileOpenMode open_mode, Shared::FileWorkMode work_mode); + bool GetAssetFromDir(const String &asset_name, AssetLocation &loc, Shared::FileOpenMode open_mode, Shared::FileWorkMode work_mode); + bool GetAssetByPriority(const String &asset_name, AssetLocation &loc, Shared::FileOpenMode open_mode, Shared::FileWorkMode work_mode); + Stream *OpenAssetAsStream(const String &asset_name, Shared::FileOpenMode open_mode, Shared::FileWorkMode work_mode); static AssetManager *_theAssetManager; AssetSearchPriority _searchPriority; diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h index 40d7cc1754ec..67ded4ac4b1a 100644 --- a/engines/ags/shared/core/platform.h +++ b/engines/ags/shared/core/platform.h @@ -27,8 +27,16 @@ namespace AGS3 { // platform definitions. Not intended for replacing types or checking for libraries. +// ScummVM implementation is identifying as Linux for now +#if 1 +#define AGS_PLATFORM_OS_WINDOWS (0) +#define AGS_PLATFORM_OS_LINUX (1) +#define AGS_PLATFORM_OS_MACOS (0) +#define AGS_PLATFORM_OS_ANDROID (1) +#define AGS_PLATFORM_OS_IOS (0) +#define AGS_PLATFORM_OS_PSP (0) // check Android first because sometimes it can get confused with host OS -#if defined(__ANDROID__) || defined(ANDROID) +#elif defined(__ANDROID__) || defined(ANDROID) #define AGS_PLATFORM_OS_WINDOWS (0) #define AGS_PLATFORM_OS_LINUX (0) #define AGS_PLATFORM_OS_MACOS (0) @@ -44,7 +52,7 @@ namespace AGS3 { #define AGS_PLATFORM_OS_IOS (0) #define AGS_PLATFORM_OS_PSP (0) #elif defined(__APPLE__) -#include "TargetConditionals.h" +#include "ags/shared/TargetConditionals.h" #ifndef TARGET_OS_SIMULATOR #define TARGET_OS_SIMULATOR (0) #endif diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index c7d0484462ce..9a9669f2cb47 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -29,10 +29,11 @@ #ifndef AGS_SHARED_CORE_TYPES_H #define AGS_SHARED_CORE_TYPES_H -#include -#include -#include // for size_t -#include // for _WORDSIZE +#include "common/scummsys.h" +//include +//include +//include // for size_t +//include // for _WORDSIZE namespace AGS3 { @@ -58,12 +59,33 @@ namespace AGS3 { #endif #endif +typedef uint8 uint8_t; +typedef uint16 uint16_t; +typedef uint32 uint32_t; +typedef int8 int8_t; +typedef int16 int16_t; +typedef int32 int32_t; +typedef int64 int64_t; + // Stream offset type -typedef int64_t soff_t; +typedef int64 soff_t; #define fixed_t int32_t // fixed point type #define color_t int32_t +#undef INT32_MIN +#undef INT32_MAX +#undef INT_MIN +#undef INT_MAX +#undef UINT_MAX +#undef SIZE_MAX +#define INT32_MIN (-2147483647 - 1) +#define INT32_MAX 2147483647 +#define INT_MIN (-2147483647 - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 0xffffffff +#define SIZE_MAX 0xffffffff + // TODO: use distinct fixed point class enum { kShift = 16, diff --git a/engines/ags/shared/debugging/assert.h b/engines/ags/shared/debugging/assert.h index cb355fa6df78..805ca9082e76 100644 --- a/engines/ags/shared/debugging/assert.h +++ b/engines/ags/shared/debugging/assert.h @@ -29,6 +29,6 @@ #ifndef AGS_SHARED_DEBUGGING_ASSERT_H #define AGS_SHARED_DEBUGGING_ASSERT_H -#include +//include #endif diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp index 69800cc25fd6..d6106531cddc 100644 --- a/engines/ags/shared/debugging/debugmanager.cpp +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -20,9 +20,9 @@ * */ -#include -#include "debug/debugmanager.h" -#include "util/string_types.h" +//include +#include "ags/shared/debugging/debugmanager.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index 83903112577a..97a7d89e6f7a 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -47,12 +47,12 @@ #ifndef AGS_SHARED_DEBUGGING_DEBUGMANAGER_H #define AGS_SHARED_DEBUGGING_DEBUGMANAGER_H -#include -#include -#include "debug/out.h" -#include "debug/outputhandler.h" -#include "util/string.h" -#include "util/string_types.h" +//include +//include +#include "ags/shared/debugging/out.h" +#include "ags/shared/debugging/outputhandler.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h index c25eb655a09b..b68cee3bec09 100644 --- a/engines/ags/shared/debugging/out.h +++ b/engines/ags/shared/debugging/out.h @@ -77,7 +77,7 @@ #ifndef AGS_SHARED_DEBUGGING_OUT_H #define AGS_SHARED_DEBUGGING_OUT_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h index 9d071b175572..635932b7fba5 100644 --- a/engines/ags/shared/debugging/outputhandler.h +++ b/engines/ags/shared/debugging/outputhandler.h @@ -30,8 +30,8 @@ #ifndef AGS_SHARED_DEBUGGING_OUTPUTHANDLER_H #define AGS_SHARED_DEBUGGING_OUTPUTHANDLER_H -#include "debug/out.h" -#include "util/string.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 6acbebd152da..5051c94db59a 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -20,17 +20,17 @@ * */ -#include -#include -#include -#include "ac/common.h" // set_our_eip -#include "ac/gamestructdefines.h" -#include "font/fonts.h" -#include "font/ttffontrenderer.h" -#include "font/wfnfontrenderer.h" -#include "gfx/bitmap.h" -#include "gui/guidefines.h" // MAXLINE -#include "util/string_utils.h" +//include +//include +//include +#include "ags/shared/ac/common.h" // set_our_eip +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/font/ttffontrenderer.h" +#include "ags/shared/font/wfnfontrenderer.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gui/guidefines.h" // MAXLINE +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index 29a8b35e9494..85d69d68c958 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -23,9 +23,9 @@ #ifndef AGS_SHARED_FONT_FONTS_H #define AGS_SHARED_FONT_FONTS_H -#include -#include "core/types.h" -#include "util/string.h" +//include +#include "ags/shared/core/types.h" +#include "ags/shared/util/string.h" // TODO: we need to make some kind of TextManager class of this module diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp index 6dfc35161cd6..dfbf669d2173 100644 --- a/engines/ags/shared/font/ttffontrenderer.cpp +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -20,18 +20,18 @@ * */ -#include -#include "core/platform.h" +//include +#include "ags/shared/core/platform.h" #define AGS_OUTLINE_FONT_FIX (!AGS_PLATFORM_OS_WINDOWS) -#include "core/assetmanager.h" -#include "font/ttffontrenderer.h" -#include "util/stream.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/font/ttffontrenderer.h" +#include "ags/shared/util/stream.h" #if AGS_OUTLINE_FONT_FIX // TODO: factor out the hack in LoadFromDiskEx -#include "ac/gamestructdefines.h" -#include "font/fonts.h" +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/shared/font/fonts.h" #endif namespace AGS3 { diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 84326fe49ade..38e1fab00fae 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -23,8 +23,8 @@ #ifndef AGS_SHARED_FONT_TTFFONTRENDERER_H #define AGS_SHARED_FONT_TTFFONTRENDERER_H -#include -#include "font/agsfontrenderer.h" +//include +#include "ags/shared/font/agsfontrenderer.h" namespace AGS3 { diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index da07dead4fe1..daea4e32858d 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -20,11 +20,11 @@ * */ -#include -#include "font/wfnfont.h" -#include "debug/out.h" -#include "util/memory.h" -#include "util/stream.h" +//include +#include "ags/shared/font/wfnfont.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/util/memory.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index 6abe424268c3..c3212f684c3c 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -46,8 +46,8 @@ #ifndef AGS_SHARED_FONT_WFNFONT_H #define AGS_SHARED_FONT_WFNFONT_H -#include -#include "core/types.h" +//include +#include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/shared/font/wfnfontrenderer.cpp b/engines/ags/shared/font/wfnfontrenderer.cpp index 336680540890..301d4ee281f4 100644 --- a/engines/ags/shared/font/wfnfontrenderer.cpp +++ b/engines/ags/shared/font/wfnfontrenderer.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/common.h" // our_eip -#include "core/assetmanager.h" -#include "debug/out.h" -#include "font/wfnfont.h" -#include "font/wfnfontrenderer.h" -#include "gfx/bitmap.h" -#include "util/stream.h" +#include "ags/shared/ac/common.h" // our_eip +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/font/wfnfont.h" +#include "ags/shared/font/wfnfontrenderer.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index ac816f647f5d..25fe6930d4da 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -23,8 +23,8 @@ #ifndef AGS_SHARED_FONT_WFNFONTRENDERER_H #define AGS_SHARED_FONT_WFNFONTRENDERER_H -#include -#include "font/agsfontrenderer.h" +//include +#include "ags/shared/font/agsfontrenderer.h" namespace AGS3 { diff --git a/engines/ags/shared/game/customproperties.cpp b/engines/ags/shared/game/customproperties.cpp index be148873faba..c56eac64f580 100644 --- a/engines/ags/shared/game/customproperties.cpp +++ b/engines/ags/shared/game/customproperties.cpp @@ -20,9 +20,9 @@ * */ -#include "game/customproperties.h" -#include "util/stream.h" -#include "util/string_utils.h" +#include "ags/shared/game/customproperties.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index 7908829e2d2b..fd7515041aa4 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -36,9 +36,9 @@ #ifndef AGS_SHARED_GAME_CUSTOMPROPERTIES_H #define AGS_SHARED_GAME_CUSTOMPROPERTIES_H -#include -#include "util/string.h" -#include "util/string_types.h" +//include +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { diff --git a/engines/ags/shared/game/interactions.cpp b/engines/ags/shared/game/interactions.cpp index 69cece596779..6996c69dae2f 100644 --- a/engines/ags/shared/game/interactions.cpp +++ b/engines/ags/shared/game/interactions.cpp @@ -20,11 +20,11 @@ * */ -#include -#include "ac/common.h" // quit -#include "game/interactions.h" -#include "util/alignedstream.h" -#include "util/math.h" +//include +#include "ags/shared/ac/common.h" // quit +#include "ags/shared/game/interactions.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/math.h" namespace AGS3 { diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index c325ee6ebd08..ad1278404ca9 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -49,8 +49,8 @@ #ifndef AGS_SHARED_GAME_INTEREACTIONS_H #define AGS_SHARED_GAME_INTEREACTIONS_H -#include -#include "util/string_types.h" +//include +#include "ags/shared/util/string_types.h" namespace AGS3 { diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 847f894f6d8f..436c24ba4140 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -20,24 +20,24 @@ * */ -#include -#include "ac/audiocliptype.h" -#include "ac/dialogtopic.h" -#include "ac/gamesetupstruct.h" -#include "ac/spritecache.h" -#include "ac/view.h" -#include "ac/wordsdictionary.h" -#include "ac/dynobj/scriptaudioclip.h" -#include "core/asset.h" -#include "core/assetmanager.h" -#include "game/main_game_file.h" -#include "gui/guimain.h" -#include "script/cc_error.h" -#include "util/alignedstream.h" -#include "util/path.h" -#include "util/string_compat.h" -#include "util/string_utils.h" -#include "font/fonts.h" +//include +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/wordsdictionary.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/shared/core/asset.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/game/main_game_file.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/string_compat.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/font/fonts.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 8bb36b7ff0d5..93705bbade96 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -31,16 +31,16 @@ #ifndef AGS_SHARED_GAME_MAINGAMEFILE_H #define AGS_SHARED_GAME_MAINGAMEFILE_H -#include -#include -#include -#include "ac/game_version.h" -#include "game/plugininfo.h" -#include "script/cc_script.h" -#include "util/error.h" -#include "util/stream.h" -#include "util/string.h" -#include "util/version.h" +//include +//include +//include +#include "ags/shared/ac/game_version.h" +#include "ags/shared/game/plugininfo.h" +#include "ags/shared/script/cc_script.h" +#include "ags/shared/util/error.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/version.h" namespace AGS3 { diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index eac9f6e072d1..b10962dd5f0b 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -29,8 +29,8 @@ #ifndef AGS_SHARED_GAME_PLUGININFO_H #define AGS_SHARED_GAME_PLUGININFO_H -#include -#include "util/string.h" +//include +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index 7793053e7062..48796e19a64e 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -20,20 +20,20 @@ * */ -#include "ac/common.h" // update_polled_stuff -#include "ac/common_defines.h" -#include "ac/gamestructdefines.h" -#include "ac/wordsdictionary.h" // TODO: extract string decryption -#include "core/assetmanager.h" -#include "debug/out.h" -#include "game/customproperties.h" -#include "game/room_file.h" -#include "game/roomstruct.h" -#include "gfx/bitmap.h" -#include "script/cc_error.h" -#include "script/cc_script.h" -#include "util/compress.h" -#include "util/string_utils.h" +#include "ags/shared/ac/common.h" // update_polled_stuff +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/shared/ac/wordsdictionary.h" // TODO: extract string decryption +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/game/customproperties.h" +#include "ags/shared/game/room_file.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/cc_script.h" +#include "ags/shared/util/compress.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index 6276cb352afa..e191e8547082 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -31,12 +31,12 @@ #ifndef AGS_SHARED_GAME_ROOMFILE_H #define AGS_SHARED_GAME_ROOMFILE_H -#include -#include -#include "game/room_version.h" -#include "util/error.h" -#include "util/stream.h" -#include "util/string.h" +//include +//include +#include "ags/shared/game/room_version.h" +#include "ags/shared/util/error.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/game/room_file_deprecated.cpp b/engines/ags/shared/game/room_file_deprecated.cpp index 388d9783ceac..a540e9dfc4de 100644 --- a/engines/ags/shared/game/room_file_deprecated.cpp +++ b/engines/ags/shared/game/room_file_deprecated.cpp @@ -30,8 +30,8 @@ #if defined (OBSOLETE) -#include "ac/common.h" -#include "util/stream.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/game/roomstruct.cpp b/engines/ags/shared/game/roomstruct.cpp index 73d399ed0e65..3d1759181680 100644 --- a/engines/ags/shared/game/roomstruct.cpp +++ b/engines/ags/shared/game/roomstruct.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/common.h" // update_polled_stuff_if_runtime -#include "game/room_file.h" -#include "game/roomstruct.h" -#include "gfx/bitmap.h" +#include "ags/shared/ac/common.h" // update_polled_stuff_if_runtime +#include "ags/shared/game/room_file.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index b9d48742e13c..59f42ea82951 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -48,11 +48,11 @@ #ifndef AGS_SHARED_GAME_ROOMINFO_H #define AGS_SHARED_GAME_ROOMINFO_H -#include -#include "ac/common_defines.h" -#include "game/interactions.h" -#include "util/geometry.h" -#include "util/wgt2allg.h" // color (allegro RGB) +//include +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/game/interactions.h" +#include "ags/shared/util/geometry.h" +#include "ags/shared/util/wgt2allg.h" // color (allegro RGB) namespace AGS3 { diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index 1112dfd32751..42ed2dfa77ac 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -20,9 +20,9 @@ * */ -#include -#include "gfx/allegrobitmap.h" -#include "debug/assert.h" +//include +#include "ags/shared/gfx/allegrobitmap.h" +#include "ags/shared/debugging/assert.h" namespace AGS3 { diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 3a5092cc97c3..195bc85d4310 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -32,9 +32,11 @@ #ifndef AGS_SHARED_GFX_ALLEGROBITMAP_H #define AGS_SHARED_GFX_ALLEGROBITMAP_H -#include -#include "core/types.h" -#include "gfx/bitmap.h" +#include "ags/stubs/allegro.h" +#include "ags/shared/core/types.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/util/geometry.h" +#include "graphics/screen.h" namespace AGS3 { namespace AGS { @@ -74,15 +76,15 @@ class Bitmap { // Is this a "normal" bitmap created by application which data can be directly accessed for reading and writing inline bool IsMemoryBitmap() const { - return is_memory_bitmap(_alBitmap) != 0; + return true; } // Is this a video bitmap inline bool IsVideoBitmap() const { - return is_video_bitmap(_alBitmap) != 0; + return dynamic_cast(_alBitmap) != nullptr; } // Is this a linear bitmap, the one that can be accessed linearly within each scanline inline bool IsLinearBitmap() const { - return is_linear_bitmap(_alBitmap) != 0; + return true; } // Checks if bitmap cannot be used @@ -103,7 +105,7 @@ class Bitmap { return Size(_alBitmap->w, _alBitmap->h); } inline int GetColorDepth() const { - return bitmap_color_depth(_alBitmap); + return _alBitmap->format.bpp(); } // BPP: bytes per pixel inline int GetBPP() const { @@ -123,17 +125,17 @@ class Bitmap { // Gets a pointer to underlying graphic data // FIXME: actually not a very good idea, since there's no 100% guarantee the scanline positions in memory are sequential inline const unsigned char *GetData() const { - return _alBitmap->line[0]; + return (unsigned char *)_alBitmap->getPixels(); } // Get scanline for direct reading inline const unsigned char *GetScanLine(int index) const { - return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; + return (index >= 0 && index < GetHeight()) ? (unsigned char *)_alBitmap->getBasePtr(0, index) : nullptr; } void SetMaskColor(color_t color); inline color_t GetMaskColor() const { - return bitmap_mask_color(_alBitmap); + return _alBitmap->getTransparentColor(); } // FIXME: allegro manual states these should not be used externally; @@ -210,10 +212,10 @@ class Bitmap { // TODO: think how to increase safety over this (some fixed memory buffer class with iterator?) // Gets scanline for directly writing into it inline unsigned char *GetScanLineForWriting(int index) { - return (index >= 0 && index < GetHeight()) ? _alBitmap->line[index] : nullptr; + return (index >= 0 && index < GetHeight()) ? (unsigned char *)_alBitmap->getBasePtr(0, index) : nullptr; } inline unsigned char *GetDataForWriting() { - return _alBitmap->line[0]; + return (unsigned char *)_alBitmap->getPixels(); } // Copies buffer contents into scanline void SetScanLine(int index, unsigned char *data, int data_size = -1); diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp index 543fecba5d24..9c6f311de609 100644 --- a/engines/ags/shared/gfx/bitmap.cpp +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -20,8 +20,8 @@ * */ -#include "gfx/bitmap.h" -#include "util/memory.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/util/memory.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/gfx/bitmap.h b/engines/ags/shared/gfx/bitmap.h index 91a4d15b074d..3c22d7fbff22 100644 --- a/engines/ags/shared/gfx/bitmap.h +++ b/engines/ags/shared/gfx/bitmap.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_GFX_BITMAP_H #define AGS_SHARED_GFX_BITMAP_H -#include "util/geometry.h" +#include "ags/shared/util/geometry.h" namespace AGS3 { namespace AGS { @@ -51,11 +51,12 @@ enum BitmapFlip { } // namespace Shared } // namespace AGS - +} // namespace AGS3 // Declare the actual bitmap class -#include "gfx/allegrobitmap.h" +#include "ags/shared/gfx/allegrobitmap.h" +namespace AGS3 { namespace AGS { namespace Shared { diff --git a/engines/ags/shared/gui/guibutton.cpp b/engines/ags/shared/gui/guibutton.cpp index bcc61f7fa9f0..03a99749eb9e 100644 --- a/engines/ags/shared/gui/guibutton.cpp +++ b/engines/ags/shared/gui/guibutton.cpp @@ -20,11 +20,11 @@ * */ -#include "ac/spritecache.h" -#include "gui/guibutton.h" -#include "gui/guimain.h" // TODO: extract helper functions -#include "util/stream.h" -#include "util/string_utils.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guimain.h" // TODO: extract helper functions +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index f5ac628a039b..87597ec57f7d 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -23,9 +23,9 @@ #ifndef AGS_SHARED_GUI_GUIBUTTON_H #define AGS_SHARED_GUI_GUIBUTTON_H -#include -#include "gui/guiobject.h" -#include "util/string.h" +//include +#include "ags/shared/gui/guiobject.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guiinv.cpp b/engines/ags/shared/gui/guiinv.cpp index 7e71a39234cc..59c413cba379 100644 --- a/engines/ags/shared/gui/guiinv.cpp +++ b/engines/ags/shared/gui/guiinv.cpp @@ -20,11 +20,11 @@ * */ -#include -#include "ac/game_version.h" -#include "gui/guiinv.h" -#include "gui/guimain.h" -#include "util/stream.h" +//include +#include "ags/shared/ac/game_version.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index 8c358dc0b86e..9debe7dcec4c 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -23,8 +23,8 @@ #ifndef AGS_SHARED_GUI_GUIINV_H #define AGS_SHARED_GUI_GUIINV_H -#include -#include "gui/guiobject.h" +//include +#include "ags/shared/gui/guiobject.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/gui/guilabel.cpp b/engines/ags/shared/gui/guilabel.cpp index cf72d09d9642..ea91eeef0254 100644 --- a/engines/ags/shared/gui/guilabel.cpp +++ b/engines/ags/shared/gui/guilabel.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/game_version.h" -#include "font/fonts.h" -#include "gui/guilabel.h" -#include "gui/guimain.h" -#include "util/stream.h" -#include "util/string_utils.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index ff114725712b..6ad4a883b274 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -23,9 +23,9 @@ #ifndef AGS_SHARED_GUI_GUILABEL_H #define AGS_SHARED_GUI_GUILABEL_H -#include -#include "gui/guiobject.h" -#include "util/string.h" +//include +#include "ags/shared/gui/guiobject.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guilistbox.cpp b/engines/ags/shared/gui/guilistbox.cpp index 4f574a10f8be..b3ee25688bed 100644 --- a/engines/ags/shared/gui/guilistbox.cpp +++ b/engines/ags/shared/gui/guilistbox.cpp @@ -20,11 +20,11 @@ * */ -#include "font/fonts.h" -#include "gui/guilistbox.h" -#include "gui/guimain.h" -#include "util/stream.h" -#include "util/string_utils.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guilistbox.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index f3910c1074aa..61472388b8f3 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -23,9 +23,9 @@ #ifndef AGS_SHARED_GUI_GUILISTBOX_H #define AGS_SHARED_GUI_GUILISTBOX_H -#include -#include "gui/guiobject.h" -#include "util/string.h" +//include +#include "ags/shared/gui/guiobject.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index 9463a712df47..8b1f6e8b7f3d 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -20,20 +20,20 @@ * */ -#include -#include "ac/game_version.h" -#include "ac/spritecache.h" -#include "debug/out.h" -#include "font/fonts.h" -#include "gui/guibutton.h" -#include "gui/guiinv.h" -#include "gui/guilabel.h" -#include "gui/guilistbox.h" -#include "gui/guimain.h" -#include "gui/guislider.h" -#include "gui/guitextbox.h" -#include "util/stream.h" -#include "util/string_utils.h" +//include +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/shared/gui/guilistbox.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guislider.h" +#include "ags/shared/gui/guitextbox.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index 004f3b226a3c..4a930f3b4f26 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -23,13 +23,13 @@ #ifndef AGS_SHARED_GUI_GUIMAIN_H #define AGS_SHARED_GUI_GUIMAIN_H -#include -#include "ac/common_defines.h" // TODO: split out gui drawing helpers -#include "gfx/gfx_def.h" // TODO: split out gui drawing helpers -#include "gui/guidefines.h" -#include "util/error.h" -#include "util/geometry.h" -#include "util/string.h" +//include +#include "ags/shared/ac/common_defines.h" // TODO: split out gui drawing helpers +#include "ags/shared/gfx/gfx_def.h" // TODO: split out gui drawing helpers +#include "ags/shared/gui/guidefines.h" +#include "ags/shared/util/error.h" +#include "ags/shared/util/geometry.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guiobject.cpp b/engines/ags/shared/gui/guiobject.cpp index 69b44f47b3dc..81387b1c2a2c 100644 --- a/engines/ags/shared/gui/guiobject.cpp +++ b/engines/ags/shared/gui/guiobject.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/common.h" // quit -#include "gui/guimain.h" -#include "gui/guiobject.h" -#include "util/stream.h" +#include "ags/shared/ac/common.h" // quit +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guiobject.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h index 9dc698050d69..bf37d9b792d8 100644 --- a/engines/ags/shared/gui/guiobject.h +++ b/engines/ags/shared/gui/guiobject.h @@ -23,10 +23,10 @@ #ifndef AGS_SHARED_GUI_GUIOBJECT_H #define AGS_SHARED_GUI_GUIOBJECT_H -#include "core/types.h" -#include "gfx/bitmap.h" -#include "gui/guidefines.h" -#include "util/string.h" +#include "ags/shared/core/types.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gui/guidefines.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guislider.cpp b/engines/ags/shared/gui/guislider.cpp index 557344bedd66..e356d620e79a 100644 --- a/engines/ags/shared/gui/guislider.cpp +++ b/engines/ags/shared/gui/guislider.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/spritecache.h" -#include "gui/guimain.h" -#include "gui/guislider.h" -#include "util/stream.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guislider.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index 338dc7124fe9..3eea0c3a3992 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -23,8 +23,8 @@ #ifndef AGS_SHARED_GUI_GUISLIDER_H #define AGS_SHARED_GUI_GUISLIDER_H -#include -#include "gui/guiobject.h" +//include +#include "ags/shared/gui/guiobject.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/gui/guitextbox.cpp b/engines/ags/shared/gui/guitextbox.cpp index 8b9a20a940c5..b9b24df44bef 100644 --- a/engines/ags/shared/gui/guitextbox.cpp +++ b/engines/ags/shared/gui/guitextbox.cpp @@ -20,11 +20,11 @@ * */ -#include "font/fonts.h" -#include "gui/guimain.h" -#include "gui/guitextbox.h" -#include "util/stream.h" -#include "util/string_utils.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guitextbox.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index 9a69cd4c6232..b1906cc86100 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -23,9 +23,9 @@ #ifndef AGS_SHARED_GUI_GUITEXTBOX_H #define AGS_SHARED_GUI_GUITEXTBOX_H -#include -#include "gui/guiobject.h" -#include "util/string.h" +//include +#include "ags/shared/gui/guiobject.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp index b015289c509a..8c0712b8cb7d 100644 --- a/engines/ags/shared/script/cc_error.cpp +++ b/engines/ags/shared/script/cc_error.cpp @@ -20,10 +20,10 @@ * */ -#include -#include -#include "script/script_common.h" // current_line -#include "util/string.h" +//include +//include +#include "ags/shared/script/script_common.h" // current_line +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/script/cc_error.h b/engines/ags/shared/script/cc_error.h index d211af6fbf88..1417b137fc72 100644 --- a/engines/ags/shared/script/cc_error.h +++ b/engines/ags/shared/script/cc_error.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_SCRIPT_ERROR_H #define AGS_SHARED_SCRIPT_ERROR_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/script/cc_options.cpp b/engines/ags/shared/script/cc_options.cpp index 9c7821f1beaf..1262d6fa492e 100644 --- a/engines/ags/shared/script/cc_options.cpp +++ b/engines/ags/shared/script/cc_options.cpp @@ -20,7 +20,7 @@ * */ -#include "cc_options.h" +#include "ags/shared/cc_options.h" namespace AGS3 { diff --git a/engines/ags/shared/script/cc_script.cpp b/engines/ags/shared/script/cc_script.cpp index b7a79059cd41..0c9079107c28 100644 --- a/engines/ags/shared/script/cc_script.cpp +++ b/engines/ags/shared/script/cc_script.cpp @@ -20,13 +20,13 @@ * */ -#include -#include -#include "script/cc_error.h" -#include "script/cc_script.h" -#include "script/script_common.h" -#include "util/stream.h" -#include "util/string_compat.h" +//include +//include +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/cc_script.h" +#include "ags/shared/script/script_common.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index e1390caa8c9f..53b3c4a750bb 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -29,8 +29,8 @@ #ifndef AGS_SHARED_SCRIPT_CC_SCRIPT_H #define AGS_SHARED_SCRIPT_CC_SCRIPT_H -#include -#include "core/types.h" +//include +#include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/shared/util/alignedstream.cpp b/engines/ags/shared/util/alignedstream.cpp index 9601283e6927..8a8c24efa874 100644 --- a/engines/ags/shared/util/alignedstream.cpp +++ b/engines/ags/shared/util/alignedstream.cpp @@ -20,9 +20,9 @@ * */ -#include "debug/assert.h" -#include "util/alignedstream.h" -#include "util/math.h" +#include "ags/shared/debugging/assert.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/math.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/alignedstream.h b/engines/ags/shared/util/alignedstream.h index 8d9d90a42a13..494854aaba71 100644 --- a/engines/ags/shared/util/alignedstream.h +++ b/engines/ags/shared/util/alignedstream.h @@ -45,7 +45,7 @@ #ifndef AGS_SHARED_UTIL_ALIGNEDSTREAM_H #define AGS_SHARED_UTIL_ALIGNEDSTREAM_H -#include "util/proxystream.h" +#include "ags/shared/util/proxystream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h index c8cb850ed824..48764722f81f 100644 --- a/engines/ags/shared/util/bbop.h +++ b/engines/ags/shared/util/bbop.h @@ -29,8 +29,8 @@ #ifndef AGS_SHARED_UTIL_BBOP_H #define AGS_SHARED_UTIL_BBOP_H -#include "core/platform.h" -#include "core/types.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/core/types.h" #if AGS_PLATFORM_ENDIAN_BIG || defined (TEST_BIGENDIAN) #define BITBYTE_BIG_ENDIAN diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index 30d385f0500a..69e81b5cbcfc 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -20,12 +20,12 @@ * */ -#include -#include -#include -#include "util/bufferedstream.h" -#include "util/stdio_compat.h" -#include "util/string.h" +#include "ags/std/algorithm.h" +#include "ags/std/memory.h" +#include "ags/shared/util/bufferedstream.h" +#include "ags/shared/util/stdio_compat.h" +#include "ags/shared/util/string.h" +#include "common/textconsole.h" namespace AGS3 { namespace AGS { @@ -34,14 +34,14 @@ namespace Shared { BufferedStream::BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) : FileStream(file_name, open_mode, work_mode, stream_endianess), _buffer(BufferStreamSize), _bufferPosition(0), _position(0) { if (FileStream::Seek(0, kSeekEnd) == false) - throw std::runtime_error("Error determining stream end."); + error("Error determining stream end."); _end = FileStream::GetPosition(); if (_end == -1) - throw std::runtime_error("Error determining stream end."); + error("Error determining stream end."); if (FileStream::Seek(0, kSeekBegin) == false) - throw std::runtime_error("Error determining stream end."); + error("Error determining stream end."); _buffer.resize(0); diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h index 1f4bb3a22fef..ffc16c2de4f8 100644 --- a/engines/ags/shared/util/bufferedstream.h +++ b/engines/ags/shared/util/bufferedstream.h @@ -23,9 +23,9 @@ #ifndef AGS_SHARED_UTIL_BUFFEREDSTREAM_H #define AGS_SHARED_UTIL_BUFFEREDSTREAM_H -#include -#include "util/filestream.h" -#include "util/file.h" // TODO: extract filestream mode constants +#include "ags/std/vector.h" +#include "ags/shared/util/filestream.h" +#include "ags/shared/util/file.h" // TODO: extract filestream mode constants namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp index d707ab8b55ad..0b8a4559667a 100644 --- a/engines/ags/shared/util/compress.cpp +++ b/engines/ags/shared/util/compress.cpp @@ -20,21 +20,14 @@ * */ -#ifdef _MANAGED -// ensure this doesn't get compiled to .NET IL -#pragma unmanaged -#endif - -#include -#include -#include "ac/common.h" // quit, update_polled_stuff -#include "gfx/bitmap.h" -#include "util/compress.h" -#include "util/lzw.h" -#include "util/misc.h" -#include "util/stream.h" +#include "ags/shared/ac/common.h" // quit, update_polled_stuff +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/util/compress.h" +#include "ags/shared/util/lzw.h" +#include "ags/shared/util/misc.h" +#include "ags/shared/util/stream.h" #if AGS_PLATFORM_ENDIAN_BIG -#include "util/bbop.h" +#include "ags/shared/util/bbop.h" #endif namespace AGS3 { diff --git a/engines/ags/shared/util/compress.h b/engines/ags/shared/util/compress.h index 0c4b8016a85f..f8e8d7c83331 100644 --- a/engines/ags/shared/util/compress.h +++ b/engines/ags/shared/util/compress.h @@ -23,7 +23,8 @@ #ifndef AGS_SHARED_UTIL_COMPRESS_H #define AGS_SHARED_UTIL_COMPRESS_H -#include "util/wgt2allg.h" // color (allegro RGB) +#include "ags/shared/core/types.h" +#include "ags/shared/util/wgt2allg.h" // color (allegro RGB) namespace AGS3 { @@ -36,22 +37,22 @@ class Bitmap; using namespace AGS; // FIXME later -void csavecompressed(Common::Stream *out, const unsigned char *tobesaved, const color pala[256]); +void csavecompressed(Shared::Stream *out, const unsigned char *tobesaved, const color pala[256]); // RLE compression -void cpackbitl(const uint8_t *line, int size, Common::Stream *out); -void cpackbitl16(const uint16_t *line, int size, Common::Stream *out); -void cpackbitl32(const uint32_t *line, int size, Common::Stream *out); +void cpackbitl(const uint8_t *line, int size, Shared::Stream *out); +void cpackbitl16(const uint16_t *line, int size, Shared::Stream *out); +void cpackbitl32(const uint32_t *line, int size, Shared::Stream *out); // RLE decompression -int cunpackbitl(uint8_t *line, int size, Common::Stream *in); -int cunpackbitl16(uint16_t *line, int size, Common::Stream *in); -int cunpackbitl32(uint32_t *line, int size, Common::Stream *in); +int cunpackbitl(uint8_t *line, int size, Shared::Stream *in); +int cunpackbitl16(uint16_t *line, int size, Shared::Stream *in); +int cunpackbitl32(uint32_t *line, int size, Shared::Stream *in); //============================================================================= -void save_lzw(Common::Stream *out, const Common::Bitmap *bmpp, const color *pall); -void load_lzw(Common::Stream *in, Common::Bitmap **bmm, int dst_bpp, color *pall); -void savecompressed_allegro(Common::Stream *out, const Common::Bitmap *bmpp, const color *pall); -void loadcompressed_allegro(Common::Stream *in, Common::Bitmap **bimpp, color *pall); +void save_lzw(Shared::Stream *out, const Shared::Bitmap *bmpp, const color *pall); +void load_lzw(Shared::Stream *in, Shared::Bitmap **bmm, int dst_bpp, color *pall); +void savecompressed_allegro(Shared::Stream *out, const Shared::Bitmap *bmpp, const color *pall); +void loadcompressed_allegro(Shared::Stream *in, Shared::Bitmap **bimpp, color *pall); } // namespace AGS3 diff --git a/engines/ags/shared/util/datastream.cpp b/engines/ags/shared/util/datastream.cpp index 1eb27225ae5e..9ec8f39fffed 100644 --- a/engines/ags/shared/util/datastream.cpp +++ b/engines/ags/shared/util/datastream.cpp @@ -20,7 +20,7 @@ * */ -#include "util/datastream.h" +#include "ags/shared/util/datastream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/datastream.h b/engines/ags/shared/util/datastream.h index 16322fd4aa79..4e45ba1c7b33 100644 --- a/engines/ags/shared/util/datastream.h +++ b/engines/ags/shared/util/datastream.h @@ -31,8 +31,8 @@ #ifndef AGS_SHARED_UTIL_DATASTREAM_H #define AGS_SHARED_UTIL_DATASTREAM_H -#include "util/bbop.h" -#include "util/stream.h" +#include "ags/shared/util/bbop.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp index e8c790cb603e..5bbecdb074a6 100644 --- a/engines/ags/shared/util/directory.cpp +++ b/engines/ags/shared/util/directory.cpp @@ -20,17 +20,12 @@ * */ -#include "core/platform.h" -#include -#if AGS_PLATFORM_OS_WINDOWS -#include -#else -#include -#include -#endif -#include "util/directory.h" -#include "util/path.h" -#include "stdio_compat.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/stdio_compat.h" +#include "common/config-manager.h" +#include "common/fs.h" namespace AGS3 { namespace AGS { @@ -39,11 +34,7 @@ namespace Shared { namespace Directory { bool CreateDirectory(const String &path) { - return mkdir(path -#if ! AGS_PLATFORM_OS_WINDOWS - , 0755 -#endif - ) == 0 || errno == EEXIST; + return Common::FSNode(path.GetNullableCStr()).createDirectory(); } bool CreateAllDirectories(const String &parent, const String &path) { @@ -68,16 +59,22 @@ bool CreateAllDirectories(const String &parent, const String &path) { } String SetCurrentDirectory(const String &path) { - chdir(path); - return GetCurrentDirectory(); + warning("TODO: SetCurrentDirectory: %s", path.GetNullableCStr()); +// chdir(path); +// return GetCurrentDirectory(); + return path; } String GetCurrentDirectory() { +#ifdef TODO char buf[512]; getcwd(buf, 512); String str(buf); Path::FixupPath(str); return str; +#else + return ConfMan.get("path"); +#endif } } // namespace Directory diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h index 07f5cac469ce..754e6837bbce 100644 --- a/engines/ags/shared/util/directory.h +++ b/engines/ags/shared/util/directory.h @@ -29,8 +29,8 @@ #ifndef AGS_SHARED_UTIL_DIRECTORY_H #define AGS_SHARED_UTIL_DIRECTORY_H -#include "core/platform.h" -#include "util/string.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h index f404b44ae3e1..4a983dfea4cb 100644 --- a/engines/ags/shared/util/error.h +++ b/engines/ags/shared/util/error.h @@ -30,8 +30,8 @@ #ifndef AGS_SHARED_UTIL_ERROR_H #define AGS_SHARED_UTIL_ERROR_H -#include -#include "util/string.h" +#include "ags/std/memory.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp index f02286c8cb5e..e94d56e9e075 100644 --- a/engines/ags/shared/util/file.cpp +++ b/engines/ags/shared/util/file.cpp @@ -20,14 +20,14 @@ * */ -#include "util/file.h" - -#include -#include "core/platform.h" -#include "util/stdio_compat.h" -#include -#include "util/filestream.h" -#include "util/bufferedstream.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/util/stdio_compat.h" +#include "ags/shared/util/filestream.h" +#include "ags/shared/util/bufferedstream.h" +#include "ags/shared/util/file.h" +#include "common/file.h" +#include "common/savefile.h" +#include "common/system.h" namespace AGS3 { namespace AGS { @@ -38,46 +38,24 @@ soff_t File::GetFileSize(const String &filename) { } bool File::TestReadFile(const String &filename) { - FILE *test_file = fopen(filename, "rb"); - if (test_file) { - fclose(test_file); - return true; - } - return false; + return Common::File::exists(filename.GetNullableCStr()); } bool File::TestWriteFile(const String &filename) { - FILE *test_file = fopen(filename, "r+"); - if (test_file) { - fclose(test_file); - return true; - } return TestCreateFile(filename); } bool File::TestCreateFile(const String &filename) { - FILE *test_file = fopen(filename, "wb"); - if (test_file) { - fclose(test_file); - ::remove(filename); - return true; - } - return false; + Common::DumpFile df; + + bool result = df.open(filename.GetNullableCStr()); + df.close(); + + return result; } bool File::DeleteFile(const String &filename) { - if (::remove(filename) != 0) { - int err; -#if AGS_PLATFORM_OS_WINDOWS - _get_errno(&err); -#else - err = errno; -#endif - if (err == EACCES) { - return false; - } - } - return true; + return g_system->getSavefileManager()->removeSavefile(filename.GetNullableCStr()); } bool File::GetFileModesFromCMode(const String &cmode, FileOpenMode &open_mode, FileWorkMode &work_mode) { @@ -137,7 +115,7 @@ String File::GetCMode(FileOpenMode open_mode, FileWorkMode work_mode) { Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkMode work_mode) { FileStream *fs = nullptr; - try { +// try { if (work_mode == kFile_Read) // NOTE: BufferedStream does not work correctly in the write mode fs = new BufferedStream(filename, open_mode, work_mode); else @@ -146,9 +124,10 @@ Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkM delete fs; fs = nullptr; } - } catch (std::runtime_error) { - fs = nullptr; - } +// } catch (std::runtime_error) { +// fs = nullptr; +// } + return fs; } diff --git a/engines/ags/shared/util/file.h b/engines/ags/shared/util/file.h index 73f21201cdb8..e858b75f7825 100644 --- a/engines/ags/shared/util/file.h +++ b/engines/ags/shared/util/file.h @@ -29,8 +29,8 @@ #ifndef AGS_SHARED_UTIL_FILE_H #define AGS_SHARED_UTIL_FILE_H -#include "core/platform.h" -#include "util/string.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index db8978949350..5134f2e04668 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -20,11 +20,10 @@ * */ -#include "util/filestream.h" - -#include -#include "util/stdio_compat.h" -#include "util/string.h" +#include "ags/shared/util/filestream.h" +#include "ags/shared/util/stdio_compat.h" +#include "ags/shared/util/string.h" +#include "common/file.h" namespace AGS3 { namespace AGS { @@ -44,20 +43,21 @@ FileStream::~FileStream() { } bool FileStream::HasErrors() const { - return IsValid() && ferror(_file) != 0; + return IsValid() && _file->err(); } void FileStream::Close() { if (_file) { - fclose(_file); + delete _file; } _file = nullptr; } bool FileStream::Flush() { - if (_file) { - return fflush(_file) == 0; - } + Common::WriteStream *ws = dynamic_cast(_file); + if (ws) + ws->flush(); + return false; } @@ -66,7 +66,8 @@ bool FileStream::IsValid() const { } bool FileStream::EOS() const { - return !IsValid() || feof(_file) != 0; + Common::ReadStream *rs = dynamic_cast(_file); + return !rs || rs->eos(); } soff_t FileStream::GetLength() const { @@ -101,30 +102,43 @@ bool FileStream::CanSeek() const { } size_t FileStream::Read(void *buffer, size_t size) { - if (_file && buffer) { - return fread(buffer, sizeof(uint8_t), size, _file); + Common::ReadStream *rs = dynamic_cast(_file); + + if (rs && buffer) { + return rs->read(buffer, size); } + return 0; } int32_t FileStream::ReadByte() { - if (_file) { - return fgetc(_file); + Common::ReadStream *rs = dynamic_cast(_file); + + if (rs) { + return rs->eos() ? -1 : (int32_t)rs->readByte(); } + return -1; } size_t FileStream::Write(const void *buffer, size_t size) { - if (_file && buffer) { - return fwrite(buffer, sizeof(uint8_t), size, _file); + Common::WriteStream *ws = dynamic_cast(_file); + + if (ws && buffer) { + return ws->write(buffer, size); } + return 0; } int32_t FileStream::WriteByte(uint8_t val) { - if (_file) { - return fputc(val, _file); + Common::WriteStream *ws = dynamic_cast(_file); + + if (ws) { + ws->writeByte(val); + return 1; } + return -1; } @@ -153,12 +167,27 @@ bool FileStream::Seek(soff_t offset, StreamSeek origin) { } void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode) { - String mode = File::GetCMode(open_mode, work_mode); - if (mode.IsEmpty()) - throw std::runtime_error("Error determining open mode"); - _file = fopen(file_name, mode); + if (open_mode == kFile_Open) { + Common::File *f = new Common::File(); + if (!f->open(file_name.GetNullableCStr())) { + delete f; + _file = nullptr; + } else { + _file = f; + } + + } else { + Common::DumpFile *f = new Common::DumpFile(); + if (!f->open(file_name.GetNullableCStr())) { + delete f; + _file = nullptr; + } else { + _file = f; + } + } + if (_file == nullptr) - throw std::runtime_error("Error opening file."); + error("Error opening file."); } } // namespace Shared diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index 77aae7dac173..69d56f6f9adf 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -23,10 +23,11 @@ #ifndef AGS_SHARED_UTIL_FILESTREAM_H #define AGS_SHARED_UTIL_FILESTREAM_H -#include +//include -#include "util/datastream.h" -#include "util/file.h" // TODO: extract filestream mode constants +#include "ags/shared/util/datastream.h" +#include "ags/shared/util/file.h" // TODO: extract filestream mode constants +#include "common/stream.h" namespace AGS3 { namespace AGS { @@ -69,7 +70,7 @@ class FileStream : public DataStream { private: void Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode); - FILE *_file; + Common::Stream *_file; const FileOpenMode _openMode; const FileWorkMode _workMode; }; diff --git a/engines/ags/shared/util/geometry.cpp b/engines/ags/shared/util/geometry.cpp index 770344f3af59..5da09aabd19a 100644 --- a/engines/ags/shared/util/geometry.cpp +++ b/engines/ags/shared/util/geometry.cpp @@ -20,9 +20,10 @@ * */ -#include "util/geometry.h" -#include -#include +#include "ags/shared/util/geometry.h" +#include "ags/std/algorithm.h" +#include "ags/std/algorithm.h" +//include namespace AGS3 { @@ -52,7 +53,7 @@ float DistanceBetween(const Rect &r1, const Rect &r2) { ); int inner_width = std::max(0, rect_outer.GetWidth() - r1.GetWidth() - r2.GetWidth()); int inner_height = std::max(0, rect_outer.GetHeight() - r1.GetHeight() - r2.GetHeight()); - return std::sqrt(inner_width ^ 2 + inner_height ^ 2); + return std::sqrt((inner_width ^ 2) + (inner_height ^ 2)); } Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h) { diff --git a/engines/ags/shared/util/geometry.h b/engines/ags/shared/util/geometry.h index 570868df7cbf..d24e33ada2d2 100644 --- a/engines/ags/shared/util/geometry.h +++ b/engines/ags/shared/util/geometry.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_UTIL_GEOMETRY_H #define AGS_SHARED_UTIL_GEOMETRY_H -#include "util/math.h" +#include "ags/shared/util/math.h" namespace AGS3 { diff --git a/engines/ags/shared/util/ini_util.cpp b/engines/ags/shared/util/ini_util.cpp index 7c7bb0b1f80a..e4849740d27c 100644 --- a/engines/ags/shared/util/ini_util.cpp +++ b/engines/ags/shared/util/ini_util.cpp @@ -20,12 +20,12 @@ * */ -#include -#include "util/file.h" -#include "util/ini_util.h" -#include "util/inifile.h" -#include "util/stream.h" -#include "util/textstreamwriter.h" +#include "ags/std/memory.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/ini_util.h" +#include "ags/shared/util/inifile.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/textstreamwriter.h" namespace AGS3 { namespace AGS { @@ -71,8 +71,8 @@ void IniUtil::Write(const String &file, const ConfigTree &tree) { TextStreamWriter writer(fs.get()); for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) { - const String &sec_key = it_sec->first; - const StringOrderMap &sec_tree = it_sec->second; + const String &sec_key = it_sec->_key; + const StringOrderMap &sec_tree = it_sec->_value; if (!sec_tree.size()) continue; // skip empty sections @@ -83,8 +83,8 @@ void IniUtil::Write(const String &file, const ConfigTree &tree) { } // write all items for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) { - const String &item_key = keyval->first; - const String &item_value = keyval->second; + const String &item_key = keyval->_key; + const String &item_value = keyval->_value; writer.WriteFormat("%s = %s", item_key.GetCStr(), item_value.GetCStr()); writer.WriteLineBreak(); @@ -96,8 +96,8 @@ void IniUtil::Write(const String &file, const ConfigTree &tree) { void IniUtil::WriteToString(String &s, const ConfigTree &tree) { for (ConfigNode it_sec = tree.begin(); it_sec != tree.end(); ++it_sec) { - const String &sec_key = it_sec->first; - const StringOrderMap &sec_tree = it_sec->second; + const String &sec_key = it_sec->_key; + const StringOrderMap &sec_tree = it_sec->_value; if (!sec_tree.size()) continue; // skip empty sections // write section name @@ -105,7 +105,7 @@ void IniUtil::WriteToString(String &s, const ConfigTree &tree) { s.Append(String::FromFormat("[%s]\n", sec_key.GetCStr())); // write all items for (StrStrOIter keyval = sec_tree.begin(); keyval != sec_tree.end(); ++keyval) - s.Append(String::FromFormat("%s = %s\n", keyval->first.GetCStr(), keyval->second.GetCStr())); + s.Append(String::FromFormat("%s = %s\n", keyval->_key.GetCStr(), keyval->_value.GetCStr())); } } @@ -118,7 +118,7 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { // they will be appended to the end of file. std::map sections_found; for (ConfigNode it = tree.begin(); it != tree.end(); ++it) - sections_found[it->first] = false; + sections_found[it->_key] = false; // Merge existing sections for (SectionIterator sec = ini.Begin(); sec != ini.End(); ++sec) { @@ -131,10 +131,10 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { // Remember the items we find in this section, if some items are not found, // they will be appended to the end of section. - const StringOrderMap &subtree = tree_node->second; + const StringOrderMap &subtree = tree_node->_value; std::map items_found; for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) - items_found[keyval->first] = false; + items_found[keyval->_key] = false; // Replace matching items for (ItemIterator item = sec->Begin(); item != sec->End(); ++item) { @@ -144,7 +144,7 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { continue; // this item is not interesting for us String old_value = item->GetValue(); - String new_value = keyval->second; + String new_value = keyval->_value; if (old_value != new_value) item->SetValue(new_value); items_found[key] = true; @@ -153,10 +153,10 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { // Append new items if (!sections_found[secname]) { for (std::map::const_iterator item_f = items_found.begin(); item_f != items_found.end(); ++item_f) { - if (item_f->second) + if (item_f->_value) continue; // item was already found - StrStrOIter keyval = subtree.find(item_f->first); - ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); + StrStrOIter keyval = subtree.find(item_f->_key); + ini.InsertItem(sec, sec->End(), keyval->_key, keyval->_value); } sections_found[secname] = true; // mark section as known } @@ -164,12 +164,12 @@ bool IniUtil::Merge(const String &file, const ConfigTree &tree) { // Add new sections for (std::map::const_iterator sec_f = sections_found.begin(); sec_f != sections_found.end(); ++sec_f) { - if (sec_f->second) + if (sec_f->_value) continue; - SectionIterator sec = ini.InsertSection(ini.End(), sec_f->first); - const StringOrderMap &subtree = tree.find(sec_f->first)->second; + SectionIterator sec = ini.InsertSection(ini.End(), sec_f->_key); + const StringOrderMap &subtree = tree.find(sec_f->_key)->_value; for (StrStrOIter keyval = subtree.begin(); keyval != subtree.end(); ++keyval) - ini.InsertItem(sec, sec->End(), keyval->first, keyval->second); + ini.InsertItem(sec, sec->End(), keyval->_key, keyval->_value); } // Write the resulting set of lines diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h index 6a127f3652ee..c3fd2276db1d 100644 --- a/engines/ags/shared/util/ini_util.h +++ b/engines/ags/shared/util/ini_util.h @@ -30,20 +30,22 @@ #ifndef AGS_SHARED_UTIL_INIUTIL_H #define AGS_SHARED_UTIL_INIUTIL_H -#include -#include "util/string.h" +#include "ags/std/map.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { namespace AGS { namespace Shared { -typedef std::map StringOrderMap; +typedef std::map StringOrderMap; typedef StringOrderMap::const_iterator StrStrOIter; typedef std::map ConfigTree; typedef ConfigTree::const_iterator ConfigNode; namespace IniUtil { + // Parse the contents of given file as INI format and insert values // into the tree. The pre-existing tree items, if any, are NOT erased. // Returns FALSE if the file could not be opened. @@ -67,7 +69,8 @@ void WriteToString(String &s, const ConfigTree &tree); // or same stream opened for both reading and writing. // Returns FALSE if the file could not be opened for writing. bool Merge(const String &file, const ConfigTree &tree); -}; + +} // namespace IniUtil } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/inifile.cpp b/engines/ags/shared/util/inifile.cpp index 200fbe21feeb..4c75cd8cd0a6 100644 --- a/engines/ags/shared/util/inifile.cpp +++ b/engines/ags/shared/util/inifile.cpp @@ -20,11 +20,11 @@ * */ -#include -#include -#include "util/inifile.h" -#include "util/textstreamreader.h" -#include "util/textstreamwriter.h" +//include +//include +#include "ags/shared/util/inifile.h" +#include "ags/shared/util/textstreamreader.h" +#include "ags/shared/util/textstreamwriter.h" namespace AGS3 { @@ -155,7 +155,7 @@ void IniFile::RemoveSection(SectionIterator sec) { // Moves string pointer forward to the first non-space character const char *SkipSpace(const char *line, const char *endl) { - for (; line != endl && isspace(*line); ++line); + for (; line != endl && Common::isSpace(*line); ++line); return line; } diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h index eaa490c3685e..0008f7b13da9 100644 --- a/engines/ags/shared/util/inifile.h +++ b/engines/ags/shared/util/inifile.h @@ -33,8 +33,9 @@ #ifndef AGS_SHARED_UTIL_INIFILE_H #define AGS_SHARED_UTIL_INIFILE_H -#include -#include "util/string.h" +#include "ags/shared/util/string.h" +#include "ags/std/utility.h" +#include "ags/std/list.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/lzw.cpp b/engines/ags/shared/util/lzw.cpp index 8c78f628e463..b93ec36cb461 100644 --- a/engines/ags/shared/util/lzw.cpp +++ b/engines/ags/shared/util/lzw.cpp @@ -26,9 +26,9 @@ // //============================================================================= -#include -#include "ac/common.h" // quit -#include "util/stream.h" +//include +#include "ags/shared/ac/common.h" // quit +#include "ags/shared/util/stream.h" namespace AGS3 { @@ -220,12 +220,12 @@ void myputc(int ccc, Stream *out) { void lzwexpand(Stream *lzw_in, Stream *out) { int bits, ch, i, j, len, mask; - char *lzbuffer; + char *lzBuffer; // printf(" UnShrinking: %s ",filena); putbytes = 0; - lzbuffer = (char *)malloc(N); - if (lzbuffer == nullptr) { + lzBuffer = (char *)malloc(N); + if (lzBuffer == nullptr) { quit("compress.cpp: unable to decompress: insufficient memory"); } i = N - F; @@ -243,13 +243,13 @@ void lzwexpand(Stream *lzw_in, Stream *out) { j = (i - j - 1) & (N - 1); while (len--) { - myputc(lzbuffer[i] = lzbuffer[j], out); + myputc(lzBuffer[i] = lzBuffer[j], out); j = (j + 1) & (N - 1); i = (i + 1) & (N - 1); } } else { ch = lzw_in->ReadByte(); - myputc(lzbuffer[i] = ch, out); + myputc(lzBuffer[i] = ch, out); i = (i + 1) & (N - 1); } @@ -264,7 +264,7 @@ void lzwexpand(Stream *lzw_in, Stream *out) { break; } - free(lzbuffer); + free(lzBuffer); expand_to_mem = 0; } diff --git a/engines/ags/shared/util/lzw.h b/engines/ags/shared/util/lzw.h index 25171da1d3e7..bbb040464725 100644 --- a/engines/ags/shared/util/lzw.h +++ b/engines/ags/shared/util/lzw.h @@ -33,8 +33,8 @@ class Stream; using namespace AGS; // FIXME later -void lzwcompress(Common::Stream *lzw_in, Common::Stream *out); -unsigned char *lzwexpand_to_mem(Common::Stream *in); +void lzwcompress(Shared::Stream *lzw_in, Shared::Stream *out); +unsigned char *lzwexpand_to_mem(Shared::Stream *in); extern long outbytes, maxsize, putbytes; diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h index 3b6a0f3c4e18..29c6b791b540 100644 --- a/engines/ags/shared/util/memory.h +++ b/engines/ags/shared/util/memory.h @@ -29,9 +29,9 @@ #ifndef AGS_SHARED_UTIL_MEMORY_H #define AGS_SHARED_UTIL_MEMORY_H -#include -#include "util/bbop.h" -#include "util/math.h" +//include +#include "ags/shared/util/bbop.h" +#include "ags/shared/util/math.h" namespace AGS3 { diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp index 71c6596c3567..1bdad6992d9f 100644 --- a/engines/ags/shared/util/misc.cpp +++ b/engines/ags/shared/util/misc.cpp @@ -49,19 +49,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" -#include -#include -#include -#include +//include +//include +//include +//include #if !AGS_PLATFORM_OS_WINDOWS -#include +//include #endif -#include "allegro.h" -#include "util/file.h" -#include "util/stream.h" +#include "ags/stubs/allegro.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/shared/util/misc.h b/engines/ags/shared/util/misc.h index 1cd6e6efc3b5..c84500c92907 100644 --- a/engines/ags/shared/util/misc.h +++ b/engines/ags/shared/util/misc.h @@ -52,7 +52,7 @@ #ifndef AGS_SHARED_UTIL_MISC_H #define AGS_SHARED_UTIL_MISC_H -#include "util/file.h" // TODO: extract filestream mode constants +#include "ags/shared/util/file.h" // TODO: extract filestream mode constants namespace AGS3 { @@ -70,9 +70,9 @@ using namespace AGS; // FIXME later // names in different character case. // They are used as a system-independent way to open a file when its name // case can be ignored. -Common::Stream *ci_fopen(const char *file_name, - Common::FileOpenMode open_mode = Common::kFile_Open, - Common::FileWorkMode work_mode = Common::kFile_Read); +Shared::Stream *ci_fopen(const char *file_name, + Shared::FileOpenMode open_mode = Shared::kFile_Open, + Shared::FileWorkMode work_mode = Shared::kFile_Read); // TODO: return String object char *ci_find_file(const char *dir_name, const char *file_name); diff --git a/engines/ags/shared/util/multifilelib.h b/engines/ags/shared/util/multifilelib.h index 49dad28c695d..e79c4cbe2476 100644 --- a/engines/ags/shared/util/multifilelib.h +++ b/engines/ags/shared/util/multifilelib.h @@ -34,8 +34,8 @@ #ifndef AGS_SHARED_UTIL_MULTIFILELIB_H #define AGS_SHARED_UTIL_MULTIFILELIB_H -#include "core/asset.h" -#include "util/stream.h" +#include "ags/shared/core/asset.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { @@ -45,6 +45,7 @@ namespace Shared { // MultiFileLib utilities: (de)serialization of asset library in MFL format // namespace MFLUtil { + enum MFLError { kMFLNoError = 0, kMFLErrNoLibSig = -1, // library signature does not match @@ -71,7 +72,8 @@ MFLError ReadHeader(AssetLibInfo &lib, Stream *in); void WriteHeader(const AssetLibInfo &lib, MFLVersion lib_version, int lib_index, Stream *out); void WriteEnder(soff_t lib_offset, MFLVersion lib_index, Stream *out); -}; + +} // namespace MFLUtil } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/mutifilelib.cpp b/engines/ags/shared/util/mutifilelib.cpp index 9d578e01bb0f..5d1eac5c5be6 100644 --- a/engines/ags/shared/util/mutifilelib.cpp +++ b/engines/ags/shared/util/mutifilelib.cpp @@ -20,16 +20,17 @@ * */ -#include "util/bbop.h" -#include "util/multifilelib.h" -#include "util/stream.h" -#include "util/string_utils.h" +#include "ags/shared/util/bbop.h" +#include "ags/shared/util/multifilelib.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { namespace AGS { namespace Shared { namespace MFLUtil { + const String HeadSig = "CLIB\x1a"; const String TailSig = "CLIB\x1\x2\x3\x4SIGE"; @@ -60,7 +61,8 @@ void ReadEncArray(void *data, size_t size, size_t count, Stream *in, int &ra int8_t ReadEncInt8(Stream *in, int &rand_val); int32_t ReadEncInt32(Stream *in, int &rand_val); void ReadEncString(char *buffer, size_t max_len, Stream *in, int &rand_val); -}; + +} // namespace MFLUtil MFLUtil::MFLError MFLUtil::TestIsMFL(Stream *in, bool test_is_main) { @@ -127,7 +129,7 @@ MFLUtil::MFLError MFLUtil::ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_vers soff_t abs_offset_32 = in->ReadInt32(); // test for header signature again, with 64-bit and 32-bit offsets if necessary - if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) { + if (abs_offset > 0 && abs_offset < (soff_t)(tail_abs_offset - HeadSig.GetLength())) { in->Seek(abs_offset, kSeekBegin); sig.ReadCount(in, HeadSig.GetLength()); } @@ -135,7 +137,7 @@ MFLUtil::MFLError MFLUtil::ReadSigsAndVersion(Stream *in, MFLVersion *p_lib_vers // try again with 32-bit offset if (HeadSig.Compare(sig) != 0) { abs_offset = abs_offset_32; - if (abs_offset > 0 && abs_offset < (tail_abs_offset - HeadSig.GetLength())) { + if (abs_offset > 0 && abs_offset < (soff_t)(tail_abs_offset - HeadSig.GetLength())) { in->Seek(abs_offset, kSeekBegin); sig.ReadCount(in, HeadSig.GetLength()); } diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp index ad47317fe721..763808bf2b78 100644 --- a/engines/ags/shared/util/path.cpp +++ b/engines/ags/shared/util/path.cpp @@ -20,13 +20,14 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include +//include #endif -#include "allegro/file.h" -#include "util/path.h" -#include "util/stdio_compat.h" + +#include "ags/stubs/allegro/file.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/stdio_compat.h" namespace AGS3 { @@ -80,7 +81,7 @@ String GetDirectoryPath(const String &path) { String dir = path; FixupPath(dir); size_t slash_at = dir.FindCharReverse('/'); - if (slash_at != -1) { + if (slash_at != String::npos) { dir.ClipMid(slash_at + 1); return dir; } diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h index 0901c6d57bbc..a78782e4edd1 100644 --- a/engines/ags/shared/util/path.h +++ b/engines/ags/shared/util/path.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_UTIL_PATH_H #define AGS_SHARED_UTIL_PATH_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/proxystream.cpp b/engines/ags/shared/util/proxystream.cpp index c8c810a7ab73..c763c6fb2ee3 100644 --- a/engines/ags/shared/util/proxystream.cpp +++ b/engines/ags/shared/util/proxystream.cpp @@ -20,7 +20,7 @@ * */ -#include "util/proxystream.h" +#include "ags/shared/util/proxystream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/proxystream.h b/engines/ags/shared/util/proxystream.h index ef40dd10c462..915d3a09939e 100644 --- a/engines/ags/shared/util/proxystream.h +++ b/engines/ags/shared/util/proxystream.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_UTIL_PROXYSTREAM_H #define AGS_SHARED_UTIL_PROXYSTREAM_H -#include "util/stream.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/stdio_compat.c b/engines/ags/shared/util/stdio_compat.c deleted file mode 100644 index d3c7e25e3b70..000000000000 --- a/engines/ags/shared/util/stdio_compat.c +++ /dev/null @@ -1,95 +0,0 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= - -#include "util/stdio_compat.h" - -#include "core/platform.h" -#include -#include -#include - -#if AGS_PLATFORM_OS_WINDOWS -#include -#include -#endif - -int ags_fseek(FILE * stream, file_off_t offset, int whence) -{ -#if defined(HAVE_FSEEKO) // Contemporary POSIX libc - return fseeko(stream, offset, whence); -#elif AGS_PLATFORM_OS_WINDOWS // MSVC - return _fseeki64(stream, offset, whence); -#else // No distinct interface with off_t - return fseek(stream, offset, whence); -#endif -} - -file_off_t ags_ftell(FILE * stream) -{ - #if defined(HAVE_FSEEKO) // Contemporary POSIX libc - return ftello(stream); - #elif AGS_PLATFORM_OS_WINDOWS // MSVC - return _ftelli64(stream); - #else // No distinct interface with off_t - return ftell(stream); - #endif -} - -int ags_file_exists(const char *path) -{ -#if AGS_PLATFORM_OS_WINDOWS - return PathFileExistsA(path) && ! PathIsDirectoryA(path); -#else - struct stat path_stat; - if (stat(path, &path_stat) != 0) { - return 0; - } - return S_ISREG(path_stat.st_mode); -#endif -} - -int ags_directory_exists(const char *path) -{ -#if AGS_PLATFORM_OS_WINDOWS - return PathFileExistsA(path) && PathIsDirectoryA(path); -#else - struct stat path_stat; - if (stat(path, &path_stat) != 0) { - return 0; - } - return S_ISDIR(path_stat.st_mode); -#endif -} - -int ags_path_exists(const char *path) -{ - #if AGS_PLATFORM_OS_WINDOWS - return PathFileExistsA(path); - #else - struct stat path_stat; - if (stat(path, &path_stat) != 0) { - return 0; - } - return S_ISREG(path_stat.st_mode) || S_ISDIR(path_stat.st_mode); - #endif -} - -file_off_t ags_file_size(const char *path) -{ - struct stat path_stat; - if (stat(path, &path_stat) != 0) { - return -1; - } - return path_stat.st_size; -} diff --git a/engines/ags/shared/util/stdio_compat.cpp b/engines/ags/shared/util/stdio_compat.cpp new file mode 100644 index 000000000000..8a0048364dd4 --- /dev/null +++ b/engines/ags/shared/util/stdio_compat.cpp @@ -0,0 +1,67 @@ +/* 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 "ags/shared/util/stdio_compat.h" +#include "ags/shared/core/platform.h" +#include "common/file.h" +#include "common/fs.h" +#include "common/textconsole.h" + +namespace AGS3 { + +int ags_fseek(Common::Stream *stream, file_off_t offset, int whence) { + Common::SeekableReadStream *rs = dynamic_cast(stream); + Common::SeekableWriteStream *ws = dynamic_cast(stream); + + if (rs) + return rs->seek(offset, whence); + else if (ws) + return ws->seek(offset, whence); + else + error("Seek on null stream"); +} + +file_off_t ags_ftell(FILE *stream) { + return stream->pos(); +} + +int ags_file_exists(const char *path) { + Common::FSNode fs(path); + return fs.exists() && !fs.isDirectory() ? 0 : -1; +} + +int ags_directory_exists(const char *path) { + Common::FSNode fs(path); + return fs.exists() && fs.isDirectory() ? 0 : -1; +} + +int ags_path_exists(const char *path) { + return Common::FSNode(path).exists() ? 0 : -1; +} + +file_off_t ags_file_size(const char *path) { + Common::File f; + + return f.open(path) ? f.size() : (file_off_t )-1; +} + +} // namespace AGS3 diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h index 289d23b6e3ff..c930546b0347 100644 --- a/engines/ags/shared/util/stdio_compat.h +++ b/engines/ags/shared/util/stdio_compat.h @@ -20,27 +20,26 @@ * */ -#ifndef AGS_SHARED_UTIL_STDIOCOMPAT_H -#define AGS_SHARED_UTIL_STDIOCOMPAT_H +#ifndef AGS_SHARED_UTIL_STDIO_COMPAT_H +#define AGS_SHARED_UTIL_STDIO_COMPAT_H -#include -#include +#include "common/stream.h" namespace AGS3 { -typedef int64_t file_off_t; +typedef int64 file_off_t; #ifdef __cplusplus extern "C" { #endif - int ags_fseek(FILE *stream, file_off_t offset, int whence); - file_off_t ags_ftell(FILE *stream); +int ags_fseek(Common::Stream *stream, file_off_t offset, int whence); +file_off_t ags_ftell(Common::Stream *stream); - int ags_file_exists(const char *path); - int ags_directory_exists(const char *path); - int ags_path_exists(const char *path); - file_off_t ags_file_size(const char *path); +int ags_file_exists(const char *path); +int ags_directory_exists(const char *path); +int ags_path_exists(const char *path); +file_off_t ags_file_size(const char *path); #ifdef __cplusplus } diff --git a/engines/ags/shared/util/stream.cpp b/engines/ags/shared/util/stream.cpp index 29a46cafb02c..8eed38dd39b9 100644 --- a/engines/ags/shared/util/stream.cpp +++ b/engines/ags/shared/util/stream.cpp @@ -20,7 +20,7 @@ * */ -#include "util/stream.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index 90cb0011e542..9940e9669556 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -35,7 +35,7 @@ #ifndef AGS_SHARED_UTIL_STREAM_H #define AGS_SHARED_UTIL_STREAM_H -#include "api/stream_api.h" +#include "ags/shared/api/stream_api.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp index cff8342c583f..49c5fad5ac4f 100644 --- a/engines/ags/shared/util/string.cpp +++ b/engines/ags/shared/util/string.cpp @@ -20,13 +20,11 @@ * */ -#include -#include -#include -#include "util/math.h" -#include "util/stream.h" -#include "util/string.h" -#include "util/string_compat.h" +#include "ags/shared/util/math.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_compat.h" +#include "ags/std/algorithm.h" namespace AGS3 { namespace AGS { @@ -52,6 +50,10 @@ String::String(const char *cstr) *this = cstr; } +String::String(const Common::String &s) : _cstr(nullptr), _len(0), _buf(nullptr) { + *this = s.c_str(); +} + String::String(const char *cstr, size_t length) : _cstr(nullptr) , _len(0) @@ -144,36 +146,36 @@ int String::CompareNoCase(const char *cstr) const { int String::CompareLeft(const char *cstr, size_t count) const { cstr = cstr ? cstr : ""; - return strncmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); + return strncmp(GetCStr(), cstr, count != npos ? count : strlen(cstr)); } int String::CompareLeftNoCase(const char *cstr, size_t count) const { cstr = cstr ? cstr : ""; - return ags_strnicmp(GetCStr(), cstr, count != -1 ? count : strlen(cstr)); + return ags_strnicmp(GetCStr(), cstr, count != npos ? count : strlen(cstr)); } int String::CompareMid(const char *cstr, size_t from, size_t count) const { cstr = cstr ? cstr : ""; from = Math::Min(from, GetLength()); - return strncmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); + return strncmp(GetCStr() + from, cstr, count != npos ? count : strlen(cstr)); } int String::CompareMidNoCase(const char *cstr, size_t from, size_t count) const { cstr = cstr ? cstr : ""; from = Math::Min(from, GetLength()); - return ags_strnicmp(GetCStr() + from, cstr, count != -1 ? count : strlen(cstr)); + return ags_strnicmp(GetCStr() + from, cstr, count != npos ? count : strlen(cstr)); } int String::CompareRight(const char *cstr, size_t count) const { cstr = cstr ? cstr : ""; - count = count != -1 ? count : strlen(cstr); + count = count != npos ? count : strlen(cstr); size_t off = Math::Min(GetLength(), count); return strncmp(GetCStr() + GetLength() - off, cstr, count); } int String::CompareRightNoCase(const char *cstr, size_t count) const { cstr = cstr ? cstr : ""; - count = count != -1 ? count : strlen(cstr); + count = count != npos ? count : strlen(cstr); size_t off = Math::Min(GetLength(), count); return ags_strnicmp(GetCStr() + GetLength() - off, cstr, count); } @@ -181,14 +183,14 @@ int String::CompareRightNoCase(const char *cstr, size_t count) const { size_t String::FindChar(char c, size_t from) const { if (c && from < _len) { const char *found_cstr = strchr(_cstr + from, c); - return found_cstr ? found_cstr - _cstr : -1; + return found_cstr ? found_cstr - _cstr : npos; } - return -1; + return npos; } size_t String::FindCharReverse(char c, size_t from) const { if (!_cstr || !c) { - return -1; + return npos; } from = Math::Min(from, _len - 1); @@ -199,15 +201,15 @@ size_t String::FindCharReverse(char c, size_t from) const { } seek_ptr--; } - return -1; + return npos; } size_t String::FindString(const char *cstr, size_t from) const { if (cstr && from < _len) { const char *found_cstr = strstr(_cstr + from, cstr); - return found_cstr ? found_cstr - _cstr : -1; + return found_cstr ? found_cstr - _cstr : npos; } - return -1; + return npos; } bool String::FindSection(char separator, size_t first, size_t last, bool exclude_first_sep, bool exclude_last_sep, @@ -222,10 +224,10 @@ bool String::FindSection(char separator, size_t first, size_t last, bool exclude size_t this_field = 0; size_t slice_from = 0; size_t slice_to = _len; - size_t slice_at = -1; + size_t slice_at = npos; do { slice_at = FindChar(separator, slice_at + 1); - if (slice_at == -1) + if (slice_at == npos) slice_at = _len; // found where previous field ends if (this_field == last) { @@ -322,7 +324,7 @@ String String::Right(size_t count) const { String String::LeftSection(char separator, bool exclude_separator) const { if (_cstr && separator) { size_t slice_at = FindChar(separator); - if (slice_at != -1) { + if (slice_at != npos) { slice_at = exclude_separator ? slice_at : slice_at + 1; return Left(slice_at); } @@ -333,7 +335,7 @@ String String::LeftSection(char separator, bool exclude_separator) const { String String::RightSection(char separator, bool exclude_separator) const { if (_cstr && separator) { size_t slice_at = FindCharReverse(separator); - if (slice_at != -1) { + if (slice_at != npos) { size_t count = exclude_separator ? _len - slice_at - 1 : _len - slice_at; return Right(count); } @@ -454,7 +456,7 @@ void String::ClipRight(size_t count) { void String::ClipLeftSection(char separator, bool include_separator) { if (_cstr && separator) { size_t slice_at = FindChar(separator); - if (slice_at != -1) { + if (slice_at != npos) { ClipLeft(include_separator ? slice_at + 1 : slice_at); } else Empty(); @@ -464,7 +466,7 @@ void String::ClipLeftSection(char separator, bool include_separator) { void String::ClipRightSection(char separator, bool include_separator) { if (_cstr && separator) { size_t slice_at = FindCharReverse(separator); - if (slice_at != -1) { + if (slice_at != npos) { ClipRight(include_separator ? _len - slice_at : _len - slice_at - 1); } else Empty(); @@ -645,7 +647,7 @@ void String::TrimLeft(char c) { if (c && t != c) { break; } - if (!c && !isspace(t)) { + if (!c && !Common::isSpace(t)) { break; } trim_ptr++; @@ -672,7 +674,7 @@ void String::TrimRight(char c) { if (c && t != c) { break; } - if (!c && !isspace(t)) { + if (!c && !Common::isSpace(t)) { break; } trim_ptr--; @@ -722,7 +724,7 @@ void String::TruncateToRight(size_t count) { void String::TruncateToLeftSection(char separator, bool exclude_separator) { if (_cstr && separator) { size_t slice_at = FindChar(separator); - if (slice_at != -1) { + if (slice_at != npos) { TruncateToLeft(exclude_separator ? slice_at : slice_at + 1); } } @@ -731,7 +733,7 @@ void String::TruncateToLeftSection(char separator, bool exclude_separator) { void String::TruncateToRightSection(char separator, bool exclude_separator) { if (_cstr && separator) { size_t slice_at = FindCharReverse(separator); - if (slice_at != -1) { + if (slice_at != npos) { TruncateToRight(exclude_separator ? _len - slice_at - 1 : _len - slice_at); } } @@ -816,7 +818,7 @@ void String::Align(size_t offset) { } void String::BecomeUnique() { - if (_cstr && (_bufHead && _bufHead->RefCount > 1 || !_bufHead)) { + if (_cstr && (!_bufHead || (_bufHead && _bufHead->RefCount > 1))) { Copy(_len); } } diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index c2ecec93fbb8..33cfd0ac3c6c 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -46,11 +46,12 @@ #ifndef AGS_SHARED_UTIL_STRING_H #define AGS_SHARED_UTIL_STRING_H -#include -#include -#include "core/platform.h" -#include "core/types.h" -#include "debug/assert.h" +//include +#include "ags/std/vector.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/core/types.h" +#include "ags/shared/debugging/assert.h" +#include "common/str.h" namespace AGS3 { namespace AGS { @@ -60,6 +61,8 @@ class Stream; class String { public: + static const uint32 npos = (uint32)-1; + // Standard constructor: intialize empty string String(); // Copy constructor @@ -70,6 +73,8 @@ class String { String(const char *cstr, size_t length); // Initialize by filling N chars with certain value String(char c, size_t count); + // Initialize with a ScummVM string + String(const Common::String &s); ~String(); // Get underlying C-string for reading; this method guarantees valid C-string @@ -132,19 +137,19 @@ class String { int Compare(const char *cstr) const; int CompareNoCase(const char *cstr) const; // Compares the leftmost part of this string with given C-string - int CompareLeft(const char *cstr, size_t count = -1) const; - int CompareLeftNoCase(const char *cstr, size_t count = -1) const; + int CompareLeft(const char *cstr, size_t count = npos) const; + int CompareLeftNoCase(const char *cstr, size_t count = npos) const; // Compares any part of this string with given C-string - int CompareMid(const char *cstr, size_t from, size_t count = -1) const; - int CompareMidNoCase(const char *cstr, size_t from, size_t count = -1) const; + int CompareMid(const char *cstr, size_t from, size_t count = npos) const; + int CompareMidNoCase(const char *cstr, size_t from, size_t count = npos) const; // Compares the rightmost part of this string with given C-string - int CompareRight(const char *cstr, size_t count = -1) const; - int CompareRightNoCase(const char *cstr, size_t count = -1) const; + int CompareRight(const char *cstr, size_t count = npos) const; + int CompareRightNoCase(const char *cstr, size_t count = npos) const; // These functions search for character or substring inside this string - // and return the index of the (first) character, or -1 if nothing found. + // and return the index of the (first) character, or npos if nothing found. size_t FindChar(char c, size_t from = 0) const; - size_t FindCharReverse(char c, size_t from = -1) const; + size_t FindCharReverse(char c, size_t from = npos) const; size_t FindString(const char *cstr, size_t from = 0) const; // Section methods treat string as a sequence of 'fields', separated by @@ -198,7 +203,7 @@ class String { // Extract N leftmost characters as a new string String Left(size_t count) const; // Extract up to N characters starting from given index - String Mid(size_t from, size_t count = -1) const; + String Mid(size_t from, size_t count = npos) const; // Extract N rightmost characters String Right(size_t count) const; @@ -237,7 +242,7 @@ class String { // Cuts off leftmost N characters void ClipLeft(size_t count); // Cuts out N characters starting from given index - void ClipMid(size_t from, size_t count = -1); + void ClipMid(size_t from, size_t count = npos); // Cuts off rightmost N characters void ClipRight(size_t count); // Cuts off leftmost part, separated by the given char; if no separator was @@ -280,7 +285,7 @@ class String { // Overwrite the Nth character of the string; does not change string's length void SetAt(size_t index, char c); // Makes a new string by copying up to N chars from C-string - void SetString(const char *cstr, size_t length = -1); + void SetString(const char *cstr, size_t length = npos); // For all Trim functions, if given character value is 0, all whitespace // characters (space, tabs, CRLF) are removed. // Remove heading and trailing characters from the string @@ -293,7 +298,7 @@ class String { // Truncate the string to the leftmost N characters void TruncateToLeft(size_t count); // Truncate the string to the middle N characters - void TruncateToMid(size_t from, size_t count = -1); + void TruncateToMid(size_t from, size_t count = npos); // Truncate the string to the rightmost N characters void TruncateToRight(size_t count); // Truncate the string to the leftmost part, separated by the given char; @@ -334,6 +339,9 @@ class String { inline bool operator <(const char *cstr) const { return Compare(cstr) < 0; } + Common::String operator()() const { + return Common::String(GetCStr()); + } private: // Creates new empty string with buffer enough to fit given length diff --git a/engines/ags/shared/util/string_compat.c b/engines/ags/shared/util/string_compat.c deleted file mode 100644 index 0f925e3ce934..000000000000 --- a/engines/ags/shared/util/string_compat.c +++ /dev/null @@ -1,58 +0,0 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -#include "util/string_compat.h" -#include -#include -#include "core/platform.h" - -char *ags_strlwr(char *s) -{ - char *p = s; - for (; *p; p++) - *p = tolower(*p); - return s; -} - -char *ags_strupr(char *s) -{ - char *p = s; - for (; *p; p++) - *p = toupper(*p); - return s; -} - -int ags_stricmp(const char *s1, const char *s2) -{ -#if AGS_PLATFORM_OS_WINDOWS - return stricmp(s1, s2); -#else - return strcasecmp(s1, s2); -#endif -} - -int ags_strnicmp(const char *s1, const char *s2, size_t n) -{ -#if AGS_PLATFORM_OS_WINDOWS - return strnicmp(s1, s2, n); -#else - return strncasecmp(s1, s2, n); -#endif -} - -char *ags_strdup(const char *s) -{ - char *result = (char *)malloc(strlen(s) + 1); - strcpy(result, s); - return result; -} diff --git a/engines/ags/shared/util/string_compat.cpp b/engines/ags/shared/util/string_compat.cpp new file mode 100644 index 000000000000..ec45962c393d --- /dev/null +++ b/engines/ags/shared/util/string_compat.cpp @@ -0,0 +1,57 @@ +/* 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 "ags/shared/util/string_compat.h" +#include "ags/shared/core/platform.h" +#include "common/str.h" + +namespace AGS3 { + +char *ags_strlwr(char *s) { + char *p = s; + for (; *p; p++) + *p = tolower(*p); + return s; +} + +char *ags_strupr(char *s) { + char *p = s; + for (; *p; p++) + *p = toupper(*p); + return s; +} + +int ags_stricmp(const char *s1, const char *s2) { + return scumm_stricmp(s1, s2); +} + +int ags_strnicmp(const char *s1, const char *s2, size_t n) { + return scumm_strnicmp(s1, s2, n); +} + +char *ags_strdup(const char *s) { + char *result = (char *)malloc(strlen(s) + 1); + strcpy(result, s); + return result; +} + +} // namespace AGS3 diff --git a/engines/ags/shared/util/string_compat.h b/engines/ags/shared/util/string_compat.h index 3931eae1f56a..3a8f30dc6e1d 100644 --- a/engines/ags/shared/util/string_compat.h +++ b/engines/ags/shared/util/string_compat.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_UTIL_STRINGCOMPAT_H #define AGS_SHARED_UTIL_STRINGCOMPAT_H -#include "core/types.h" +#include "ags/shared/core/types.h" namespace AGS3 { @@ -31,11 +31,11 @@ namespace AGS3 { extern "C" { #endif - char *ags_strlwr(char *s); - char *ags_strupr(char *s); - int ags_stricmp(const char *, const char *); - int ags_strnicmp(const char *, const char *, size_t); - char *ags_strdup(const char *s); +char *ags_strlwr(char *s); +char *ags_strupr(char *s); +int ags_stricmp(const char *, const char *); +int ags_strnicmp(const char *, const char *, size_t); +char *ags_strdup(const char *s); #ifdef __cplusplus } diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index 60fe83f99186..13b4c4c5f9da 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -23,12 +23,10 @@ #ifndef AGS_SHARED_UTIL_STRINGTYPES_H #define AGS_SHARED_UTIL_STRINGTYPES_H -#include -#include -#include - -#include -#include "util/string.h" +#include "ags/std/map.h" +#include "ags/std/vector.h" +#include "ags/shared/util/string.h" +#include "common/hash-str.h" namespace AGS3 { namespace FNV { @@ -51,29 +49,59 @@ inline size_t Hash_LowerCase(const char *data, const size_t len) { } } // namespace FNV - +} // namespace AGS3 // A std::hash specialization for AGS String -namespace std { -#ifdef AGS_NEEDS_TR1 -namespace tr1 { -#endif -// std::hash for String object +namespace AGS3 { + +struct CaseSensitiveString_EqualTo { + bool operator()(const AGS3::AGS::Shared::String &x, const AGS3::AGS::Shared::String &y) const { + return x.Compare(y) == 0; + } +}; + +struct CaseSensitiveString_Hash { + uint operator()(const AGS3::AGS::Shared::String &x) const { + return Common::hashit(x.GetNullableCStr()); + } +}; + +struct IgnoreCase_EqualTo { + bool operator()(const AGS3::AGS::Shared::String &x, const AGS3::AGS::Shared::String &y) const { + return x.CompareNoCase(y) == 0; + } +}; + +struct IgnoreCase_Hash { + uint operator()(const AGS3::AGS::Shared::String &x) const { + return Common::hashit_lower(x.GetNullableCStr()); + } +}; + +} // namespace AGS3 + +namespace Common { + +// Specalization of the Hash functor for String objects. +// We do case sensitve hashing here, because that is what +// the default EqualTo is compatible with. If one wants to use +// case insensitve hashing, then only because one wants to use +// IgnoreCase_EqualTo, and then one has to specify a custom +// hash anyway. template<> -struct hash : public unary_function { - size_t operator()(const AGS::Shared::String &key) const { - return FNV::Hash(key.GetCStr(), key.GetLength()); +struct Hash { + uint operator()(const AGS3::AGS::Shared::String &s) const { + return Common::hashit(s.GetNullableCStr()); } }; -#ifdef AGS_NEEDS_TR1 -} -#endif -} +} // namespace Common +namespace AGS3 { namespace AGS { namespace Shared { +#if 0 // // Various comparison functors // @@ -98,10 +126,11 @@ struct HashStrNoCase : public std::unary_function { return FNV::Hash_LowerCase(key.GetCStr(), key.GetLength()); } }; +#endif typedef std::vector StringV; typedef std::unordered_map StringMap; -typedef std::unordered_map StringIMap; +typedef std::unordered_map StringIMap; } // namespace Shared } // namespace AGS diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp index fe0dbdec08d5..16eeaccf47c3 100644 --- a/engines/ags/shared/util/string_utils.cpp +++ b/engines/ags/shared/util/string_utils.cpp @@ -20,12 +20,13 @@ * */ -#include -#include -#include "core/platform.h" -#include "util/math.h" -#include "util/string_utils.h" -#include "util/stream.h" +//include +//include +#include "ags/shared/core/platform.h" +#include "ags/shared/util/math.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/util/stream.h" +#include "ags/stubs/allegro/error.h" namespace AGS3 { @@ -58,11 +59,11 @@ StrUtil::ConversionError StrUtil::StringToInt(const String &s, int &val, int def if (!s.GetCStr()) return StrUtil::kFailed; char *stop_ptr; - errno = 0; + errnum = 0; long lval = strtol(s.GetCStr(), &stop_ptr, 0); if (stop_ptr != s.GetCStr() + s.GetLength()) return StrUtil::kFailed; - if (lval > INT_MAX || lval < INT_MIN || errno == ERANGE) + if (lval > INT_MAX || lval < INT_MIN || errnum == ERANGE) return StrUtil::kOutOfRange; val = (int)lval; return StrUtil::kNoError; diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h index fc4ebd8f6bf4..43d6234e7795 100644 --- a/engines/ags/shared/util/string_utils.h +++ b/engines/ags/shared/util/string_utils.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_UTIL_STRING_UTILS_H #define AGS_SHARED_UTIL_STRING_UTILS_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { @@ -39,7 +39,7 @@ using namespace AGS; // FIXME later // Converts char* to string and frees original malloc-ed array; // This is used when we get a malloc'd char array from some utility function. -Common::String cbuf_to_string_and_free(char *char_buf); +Shared::String cbuf_to_string_and_free(char *char_buf); namespace AGS { namespace Shared { diff --git a/engines/ags/shared/util/textreader.h b/engines/ags/shared/util/textreader.h index 78a507c5a9e3..c226805659b4 100644 --- a/engines/ags/shared/util/textreader.h +++ b/engines/ags/shared/util/textreader.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_UTIL_TEXTREADER_H #define AGS_SHARED_UTIL_TEXTREADER_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/textstreamreader.cpp b/engines/ags/shared/util/textstreamreader.cpp index a19169470db1..f066c013667a 100644 --- a/engines/ags/shared/util/textstreamreader.cpp +++ b/engines/ags/shared/util/textstreamreader.cpp @@ -20,9 +20,9 @@ * */ -#include "util/math.h" -#include "util/stream.h" -#include "util/textstreamreader.h" +#include "ags/shared/util/math.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/textstreamreader.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/textstreamreader.h b/engines/ags/shared/util/textstreamreader.h index 9c527dcc237b..79d2e550484a 100644 --- a/engines/ags/shared/util/textstreamreader.h +++ b/engines/ags/shared/util/textstreamreader.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_UTIL_TEXTSTREAMREADER_H #define AGS_SHARED_UTIL_TEXTSTREAMREADER_H -#include "util/textreader.h" +#include "ags/shared/util/textreader.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/textstreamwriter.cpp b/engines/ags/shared/util/textstreamwriter.cpp index 1d72acc24cf2..fe2ffad380cd 100644 --- a/engines/ags/shared/util/textstreamwriter.cpp +++ b/engines/ags/shared/util/textstreamwriter.cpp @@ -20,11 +20,11 @@ * */ -#include -#include // sprintf -#include "core/platform.h" -#include "util/textstreamwriter.h" -#include "util/stream.h" +//include +//include // sprintf +#include "ags/shared/core/platform.h" +#include "ags/shared/util/textstreamwriter.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/textstreamwriter.h b/engines/ags/shared/util/textstreamwriter.h index ef15320996db..932759b029ad 100644 --- a/engines/ags/shared/util/textstreamwriter.h +++ b/engines/ags/shared/util/textstreamwriter.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_UTIL_TEXTSTREAMWRITER_H #define AGS_SHARED_UTIL_TEXTSTREAMWRITER_H -#include "util/textwriter.h" +#include "ags/shared/util/textwriter.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/textwriter.h b/engines/ags/shared/util/textwriter.h index 42c735c37186..87123e5801f4 100644 --- a/engines/ags/shared/util/textwriter.h +++ b/engines/ags/shared/util/textwriter.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_UTIL_TEXTWRITER_H #define AGS_SHARED_UTIL_TEXTWRITER_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/version.cpp b/engines/ags/shared/util/version.cpp index f3f7ae9ebc8f..40ef6bd31322 100644 --- a/engines/ags/shared/util/version.cpp +++ b/engines/ags/shared/util/version.cpp @@ -20,8 +20,8 @@ * */ -#include -#include "util/version.h" +//include +#include "ags/shared/util/version.h" namespace AGS3 { namespace AGS { @@ -107,7 +107,7 @@ void Version::SetFromString(const String &version_string) { const char *seek_ptr = revision_section.GetCStr(); const char *end_ptr = revision_section.GetCStr() + revision_section.GetLength(); while (seek_ptr != end_ptr) { - if (!isdigit(*seek_ptr)) { + if (!Common::isDigit(*seek_ptr)) { break; } revision_length++; diff --git a/engines/ags/shared/util/version.h b/engines/ags/shared/util/version.h index 95dad1377ac8..829540a97cc6 100644 --- a/engines/ags/shared/util/version.h +++ b/engines/ags/shared/util/version.h @@ -29,13 +29,13 @@ #ifndef AGS_SHARED_UTIL_VERSION_H #define AGS_SHARED_UTIL_VERSION_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { namespace Shared { -using Common::String; +using Shared::String; struct Version { int32_t Major; diff --git a/engines/ags/shared/util/wgt2allg.cpp b/engines/ags/shared/util/wgt2allg.cpp index 8975fd02f7bd..ea5067d79aad 100644 --- a/engines/ags/shared/util/wgt2allg.cpp +++ b/engines/ags/shared/util/wgt2allg.cpp @@ -20,196 +20,188 @@ * */ -#include "core/assetmanager.h" -#include "gfx/bitmap.h" -#include "util/stream.h" -#include "util/wgt2allg.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/allegrobitmap.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/stubs/allegro.h" namespace AGS3 { using namespace AGS::Shared; -#ifdef __cplusplus -extern "C" -{ -#endif +void wsetrgb(int coll, int r, int g, int b, color *pall) { + pall[coll].r = r; + pall[coll].g = g; + pall[coll].b = b; +} - void wsetrgb(int coll, int r, int g, int b, color *pall) { - pall[coll].r = r; - pall[coll].g = g; - pall[coll].b = b; - } +void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall) { + int jj; + if (dir == 0) { + // rotate left + color tempp = pall[start]; - void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall) { - int jj; - if (dir == 0) { - // rotate left - color tempp = pall[start]; + for (jj = start; jj < finish; jj++) + pall[jj] = pall[jj + 1]; - for (jj = start; jj < finish; jj++) - pall[jj] = pall[jj + 1]; + pall[finish] = tempp; + } else { + // rotate right + color tempp = pall[finish]; - pall[finish] = tempp; - } else { - // rotate right - color tempp = pall[finish]; + for (jj = finish - 1; jj >= start; jj--) + pall[jj + 1] = pall[jj]; - for (jj = finish - 1; jj >= start; jj--) - pall[jj + 1] = pall[jj]; - - pall[start] = tempp; - } + pall[start] = tempp; } +} + +Bitmap *wnewblock(Shared::Bitmap *src, int x1, int y1, int x2, int y2) { + Bitmap *tempbitm; + int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; - Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2) { - Bitmap *tempbitm; - int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; + if (twid < 1) + twid = 1; - if (twid < 1) - twid = 1; + if (thit < 1) + thit = 1; - if (thit < 1) - thit = 1; + tempbitm = BitmapHelper::CreateBitmap(twid, thit); - tempbitm = BitmapHelper::CreateBitmap(twid, thit); + if (tempbitm == nullptr) + return nullptr; - if (tempbitm == nullptr) - return nullptr; + tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); + return tempbitm; +} - tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); - return tempbitm; +int wloadsprites(color *pall, char *filnam, Bitmap **sarray, int strt, int eend) { + int vers; + char buff[20]; + int numspri = 0, vv, hh, wdd, htt; + + Stream *in = Shared::AssetManager::OpenAsset(filnam); + if (in == nullptr) + return -1; + + vers = in->ReadInt16(); + in->ReadArray(&buff[0], 13, 1); + for (vv = 0; vv < 256; vv++) // there's a filler byte + in->ReadArray(&pall[vv], 3, 1); + + if (vers > 4) + return -1; + + if (vers == 4) + numspri = in->ReadInt16(); + else { + numspri = in->ReadInt16(); + if ((numspri < 2) || (numspri > 200)) + numspri = 200; } - int wloadsprites(color *pall, char *filnam, Bitmap **sarray, int strt, int eend) { - int vers; - char buff[20]; - int numspri = 0, vv, hh, wdd, htt; + for (vv = strt; vv <= eend; vv++) + sarray[vv] = nullptr; - Stream *in = Common::AssetManager::OpenAsset(filnam); - if (in == nullptr) - return -1; + for (vv = 0; vv <= numspri; vv++) { + int coldep = in->ReadInt16(); - vers = in->ReadInt16(); - in->ReadArray(&buff[0], 13, 1); - for (vv = 0; vv < 256; vv++) // there's a filler byte - in->ReadArray(&pall[vv], 3, 1); - - if (vers > 4) - return -1; + if (coldep == 0) { + sarray[vv] = nullptr; + if (in->EOS()) + break; - if (vers == 4) - numspri = in->ReadInt16(); - else { - numspri = in->ReadInt16(); - if ((numspri < 2) || (numspri > 200)) - numspri = 200; + continue; } - for (vv = strt; vv <= eend; vv++) - sarray[vv] = nullptr; + if (in->EOS()) + break; - for (vv = 0; vv <= numspri; vv++) { - int coldep = in->ReadInt16(); + if (vv > eend) + break; - if (coldep == 0) { - sarray[vv] = nullptr; - if (in->EOS()) - break; + wdd = in->ReadInt16(); + htt = in->ReadInt16(); + if (vv < strt) { + in->Seek(wdd * htt); + continue; + } + sarray[vv] = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); - continue; - } + if (sarray[vv] == nullptr) { + delete in; + return -1; + } - if (in->EOS()) - break; + for (hh = 0; hh < htt; hh++) + in->ReadArray(&sarray[vv]->GetScanLineForWriting(hh)[0], wdd * coldep, 1); + } + delete in; + return 0; +} - if (vv > eend) - break; +void wputblock(Shared::Bitmap *ds, int xx, int yy, Bitmap *bll, int xray) { + if (xray) + ds->Blit(bll, xx, yy, Shared::kBitmap_Transparency); + else + ds->Blit(bll, 0, 0, xx, yy, bll->GetWidth(), bll->GetHeight()); +} - wdd = in->ReadInt16(); - htt = in->ReadInt16(); - if (vv < strt) { - in->Seek(wdd * htt); - continue; - } - sarray[vv] = BitmapHelper::CreateBitmap(wdd, htt, coldep * 8); - - if (sarray[vv] == nullptr) { - delete in; - return -1; - } - - for (hh = 0; hh < htt; hh++) - in->ReadArray(&sarray[vv]->GetScanLineForWriting(hh)[0], wdd * coldep, 1); - } - delete in; - return 0; - } +Bitmap wputblock_wrapper; // [IKM] argh! :[ +void wputblock_raw(Shared::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray) { + wputblock_wrapper.WrapAllegroBitmap(bll, true); + if (xray) + ds->Blit(&wputblock_wrapper, xx, yy, Shared::kBitmap_Transparency); + else + ds->Blit(&wputblock_wrapper, 0, 0, xx, yy, wputblock_wrapper.GetWidth(), wputblock_wrapper.GetHeight()); +} - void wputblock(Common::Bitmap *ds, int xx, int yy, Bitmap *bll, int xray) { - if (xray) - ds->Blit(bll, xx, yy, Common::kBitmap_Transparency); - else - ds->Blit(bll, 0, 0, xx, yy, bll->GetWidth(), bll->GetHeight()); - } +const int col_lookups[32] = { + 0x000000, 0x0000A0, 0x00A000, 0x00A0A0, 0xA00000, // 4 + 0xA000A0, 0xA05000, 0xA0A0A0, 0x505050, 0x5050FF, 0x50FF50, 0x50FFFF, // 11 + 0xFF5050, 0xFF50FF, 0xFFFF50, 0xFFFFFF, 0x000000, 0x101010, 0x202020, // 18 + 0x303030, 0x404040, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, // 25 + 0xA0A0A0, 0xB0B0B0, 0xC0C0C0, 0xD0D0D0, 0xE0E0E0, 0xF0F0F0 +}; - Bitmap wputblock_wrapper; // [IKM] argh! :[ - void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray) { - wputblock_wrapper.WrapAllegroBitmap(bll, true); - if (xray) - ds->Blit(&wputblock_wrapper, xx, yy, Common::kBitmap_Transparency); - else - ds->Blit(&wputblock_wrapper, 0, 0, xx, yy, wputblock_wrapper.GetWidth(), wputblock_wrapper.GetHeight()); - } +int __wremap_keep_transparent = 1; - const int col_lookups[32] = { - 0x000000, 0x0000A0, 0x00A000, 0x00A0A0, 0xA00000, // 4 - 0xA000A0, 0xA05000, 0xA0A0A0, 0x505050, 0x5050FF, 0x50FF50, 0x50FFFF, // 11 - 0xFF5050, 0xFF50FF, 0xFFFF50, 0xFFFFFF, 0x000000, 0x101010, 0x202020, // 18 - 0x303030, 0x404040, 0x505050, 0x606060, 0x707070, 0x808080, 0x909090, // 25 - 0xA0A0A0, 0xB0B0B0, 0xC0C0C0, 0xD0D0D0, 0xE0E0E0, 0xF0F0F0 - }; - - int __wremap_keep_transparent = 1; - - void wremap(color *pal1, Bitmap *picc, color *pal2) { - int jj; - unsigned char color_mapped_table[256]; - - for (jj = 0; jj < 256; jj++) { - if ((pal1[jj].r == 0) && (pal1[jj].g == 0) && (pal1[jj].b == 0)) { - color_mapped_table[jj] = 0; - } else { - color_mapped_table[jj] = bestfit_color(pal2, pal1[jj].r, pal1[jj].g, pal1[jj].b); - } - } +void wremap(color *pal1, Bitmap *picc, color *pal2) { + int jj; + unsigned char color_mapped_table[256]; - if (__wremap_keep_transparent > 0) { - // keep transparency - color_mapped_table[0] = 0; - // any other pixels which are being mapped to 0, map to 16 instead - for (jj = 1; jj < 256; jj++) { - if (color_mapped_table[jj] == 0) - color_mapped_table[jj] = 16; - } + for (jj = 0; jj < 256; jj++) { + if ((pal1[jj].r == 0) && (pal1[jj].g == 0) && (pal1[jj].b == 0)) { + color_mapped_table[jj] = 0; + } else { + color_mapped_table[jj] = bestfit_color(pal2, pal1[jj].r, pal1[jj].g, pal1[jj].b); } + } - int pic_size = picc->GetWidth() * picc->GetHeight(); - for (jj = 0; jj < pic_size; jj++) { - int xxl = jj % (picc->GetWidth()), yyl = jj / (picc->GetWidth()); - int rr = picc->GetPixel(xxl, yyl); - picc->PutPixel(xxl, yyl, color_mapped_table[rr]); + if (__wremap_keep_transparent > 0) { + // keep transparency + color_mapped_table[0] = 0; + // any other pixels which are being mapped to 0, map to 16 instead + for (jj = 1; jj < 256; jj++) { + if (color_mapped_table[jj] == 0) + color_mapped_table[jj] = 16; } } - void wremapall(color *pal1, Bitmap *picc, color *pal2) { - __wremap_keep_transparent--; - wremap(pal1, picc, pal2); - __wremap_keep_transparent++; + int pic_size = picc->GetWidth() * picc->GetHeight(); + for (jj = 0; jj < pic_size; jj++) { + int xxl = jj % (picc->GetWidth()), yyl = jj / (picc->GetWidth()); + int rr = picc->GetPixel(xxl, yyl); + picc->PutPixel(xxl, yyl, color_mapped_table[rr]); } +} - -#ifdef __cplusplus +void wremapall(color *pal1, Bitmap *picc, color *pal2) { + __wremap_keep_transparent--; + wremap(pal1, picc, pal2); + __wremap_keep_transparent++; } -#endif } // namespace AGS3 diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index b9624c53bbce..090f51ca4945 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -28,14 +28,13 @@ // //============================================================================= -#include "core/platform.h" +#ifndef AGS_SHARED_UTIL_WGT2ALLG_H +#define AGS_SHARED_UTIL_WGT2ALLG_H #define _WGT45_ -#ifndef AGS_SHARED_UTIL_WGT4_H -#define AGS_SHARED_UTIL_WGT4_H - -#include "allegro.h" +#include "ags/shared/core/platform.h" +#include "ags/stubs/allegro.h" namespace AGS3 { @@ -47,12 +46,11 @@ class Bitmap; using namespace AGS; // FIXME later - #if defined WGT2ALLEGRO_NOFUNCTIONS #error WGT2ALLEGRO_NOFUNCTIONS macro is obsolete and should not be defined anymore. #endif -#define color RGB +//define color RGB //============================================================================= @@ -67,20 +65,20 @@ extern "C" extern void wsetrgb(int coll, int r, int g, int b, color *pall); extern void wcolrotate(unsigned char start, unsigned char finish, int dir, color *pall); - extern Common::Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2); + extern Shared::Bitmap *wnewblock(Shared::Bitmap *src, int x1, int y1, int x2, int y2); - extern int wloadsprites(color *pall, char *filnam, Common::Bitmap **sarray, int strt, int eend); + extern int wloadsprites(color *pall, char *filnam, Shared::Bitmap **sarray, int strt, int eend); - extern void wputblock(Common::Bitmap *ds, int xx, int yy, Common::Bitmap *bll, int xray); + extern void wputblock(Shared::Bitmap *ds, int xx, int yy, Shared::Bitmap *bll, int xray); // CHECKME: temporary solution for plugin system - extern void wputblock_raw(Common::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray); + extern void wputblock_raw(Shared::Bitmap *ds, int xx, int yy, BITMAP *bll, int xray); extern const int col_lookups[32]; //extern void wsetcolor(int nval); extern int __wremap_keep_transparent; - extern void wremap(color *pal1, Common::Bitmap *picc, color *pal2); - extern void wremapall(color *pal1, Common::Bitmap *picc, color *pal2); + extern void wremap(color *pal1, Shared::Bitmap *picc, color *pal2); + extern void wremapall(color *pal1, Shared::Bitmap *picc, color *pal2); #ifdef __cplusplus } diff --git a/engines/ags/std/algorithm.h b/engines/ags/std/algorithm.h new file mode 100644 index 000000000000..504e883a42d8 --- /dev/null +++ b/engines/ags/std/algorithm.h @@ -0,0 +1,42 @@ +/* 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 AGS_STD_ALGORITHM_H +#define AGS_STD_ALGORITHM_H + +#include "common/algorithm.h" +#include "common/util.h" + +namespace AGS3 { +namespace std { + +template inline T abs(T x) { return ABS(x); } +template inline T min(T a, T b) { return MIN(a, b); } +template inline T max(T a, T b) { return MAX(a, b); } +template inline T clip(T v, T amin, T amax) { return CLIP(v, amin, amax); } +template inline T sqrt(T x) { return ::sqrt(x); } +template inline void swap(T a, T b) { SWAP(a, b); } + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/memory.h b/engines/ags/std/memory.h index c33d945d76c8..99c85916a08a 100644 --- a/engines/ags/std/memory.h +++ b/engines/ags/std/memory.h @@ -38,6 +38,11 @@ using weak_ptr = Common::WeakPtr; template > using unique_ptr = Common::ScopedPtr; +template +T *memcpy(T *dest, const T *src, size_t n) { + return (T *)::memcpy(dest, src, n); +} + } // namespace std } // namespace AGS3 diff --git a/engines/ags/std/vector.h b/engines/ags/std/vector.h index 87814229c63a..84a1915d495a 100644 --- a/engines/ags/std/vector.h +++ b/engines/ags/std/vector.h @@ -125,7 +125,7 @@ class vector : public Common::Array { * Rotates the array so that the item pointed to by the iterator becomes * the first item, and the predeceding item becomes the last one */ - void rotate(Common::Array::iterator &it) { + void rotate(typename Common::Array::iterator it) { if (it != Common::Array::end()) { size_t count = it - Common::Array::begin(); for (size_t ctr = 0; ctr < count; ++ctr) { diff --git a/engines/ags/stubs/allegro.cpp b/engines/ags/stubs/allegro.cpp index 44f7099b3017..93a597c56f61 100644 --- a/engines/ags/stubs/allegro.cpp +++ b/engines/ags/stubs/allegro.cpp @@ -25,6 +25,7 @@ namespace AGS3 { int install_allegro() { + errnum = 0; return 0; } diff --git a/engines/ags/stubs/allegro/error.cpp b/engines/ags/stubs/allegro/error.cpp index b25496e834a5..25105d946141 100644 --- a/engines/ags/stubs/allegro/error.cpp +++ b/engines/ags/stubs/allegro/error.cpp @@ -20,9 +20,11 @@ * */ +#include "ags/stubs/allegro/error.h" + namespace AGS3 { -static int allegro_error; -extern int *allegro_errno = &allegro_error; +int errnum; +int *allegro_errno = &errnum; } // namespace AGS3 diff --git a/engines/ags/stubs/allegro/error.h b/engines/ags/stubs/allegro/error.h index 46d3e03fdeaf..7a5aeb627ab5 100644 --- a/engines/ags/stubs/allegro/error.h +++ b/engines/ags/stubs/allegro/error.h @@ -27,8 +27,6 @@ namespace AGS3 { - - // Error codes #define EPERM 1 #define ENOENT 2 @@ -75,6 +73,7 @@ namespace AGS3 { #define STRUNCATE 80 #endif +extern int errnum; extern int *allegro_errno; } // namespace AGS3 diff --git a/engines/ags/stubs/allegro/fixed.h b/engines/ags/stubs/allegro/fixed.h index 45acd42c990b..fa1e456b123e 100644 --- a/engines/ags/stubs/allegro/fixed.h +++ b/engines/ags/stubs/allegro/fixed.h @@ -27,7 +27,7 @@ namespace AGS3 { -typedef uint32 fixed; +typedef long fixed; extern fixed fixtorad_r; extern fixed radtofix_r; diff --git a/engines/ags/stubs/allegro/mouse.cpp b/engines/ags/stubs/allegro/mouse.cpp index c8bad8476f2b..daa0bad28f9f 100644 --- a/engines/ags/stubs/allegro/mouse.cpp +++ b/engines/ags/stubs/allegro/mouse.cpp @@ -27,7 +27,9 @@ namespace AGS3 { MOUSE_DRIVER mousedrv_none; MOUSE_DRIVER *mouse_driver; -_DRIVER_INFO _mouse_driver_list[]; +_DRIVER_INFO _mouse_driver_list[] = { + { 0, nullptr, 0 } +}; BITMAP *mouse_sprite; int mouse_x_focus; From 1fae11dedb1e1e78d734039bda3af7a74542bdf5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 10:20:20 -0800 Subject: [PATCH 012/215] AGS: Added shared/script/ --- engines/ags/module.mk | 3 +++ engines/ags/shared/script/cc_error.cpp | 3 +-- engines/ags/shared/script/cc_error.h | 4 ++-- engines/ags/shared/script/cc_options.cpp | 2 +- engines/ags/shared/script/cc_script.cpp | 8 ++++---- engines/ags/shared/script/cc_script.h | 8 ++++---- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 4d51bd9761a4..ae53b8b55d8c 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -17,6 +17,9 @@ MODULE_OBJS = \ stubs/allegro/sound.o \ stubs/allegro/system.o \ stubs/allegro/unicode.o \ + shared/script/cc_error.o \ + shared/script/cc_options.o \ + shared/script/cc_script.o \ shared/util/alignedstream.o \ shared/util/bufferedstream.o \ shared/util/compress.o \ diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp index 8c0712b8cb7d..9e5736bb81e1 100644 --- a/engines/ags/shared/script/cc_error.cpp +++ b/engines/ags/shared/script/cc_error.cpp @@ -20,10 +20,9 @@ * */ -//include -//include #include "ags/shared/script/script_common.h" // current_line #include "ags/shared/util/string.h" +#include "ags/std/utility.h" namespace AGS3 { diff --git a/engines/ags/shared/script/cc_error.h b/engines/ags/shared/script/cc_error.h index 1417b137fc72..35089ada2340 100644 --- a/engines/ags/shared/script/cc_error.h +++ b/engines/ags/shared/script/cc_error.h @@ -26,8 +26,8 @@ // //============================================================================= -#ifndef AGS_SHARED_SCRIPT_ERROR_H -#define AGS_SHARED_SCRIPT_ERROR_H +#ifndef AGS_SHARED_SCRIPT_CC_ERROR_H +#define AGS_SHARED_SCRIPT_CC_ERROR_H #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/script/cc_options.cpp b/engines/ags/shared/script/cc_options.cpp index 1262d6fa492e..d0b8c1b1e867 100644 --- a/engines/ags/shared/script/cc_options.cpp +++ b/engines/ags/shared/script/cc_options.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/cc_options.h" +#include "ags/shared/script/cc_options.h" namespace AGS3 { diff --git a/engines/ags/shared/script/cc_script.cpp b/engines/ags/shared/script/cc_script.cpp index 0c9079107c28..3e638d3d1516 100644 --- a/engines/ags/shared/script/cc_script.cpp +++ b/engines/ags/shared/script/cc_script.cpp @@ -62,7 +62,7 @@ void fwritestring(const char *strptr, Stream *out) { } } -ccScript *ccScript::CreateFromStream(Stream *in) { +ccScript *ccScript::CreateFromStream(Shared::Stream *in) { ccScript *scri = new ccScript(); if (!scri->Read(in)) { delete scri; @@ -177,7 +177,7 @@ ccScript::~ccScript() { Free(); } -void ccScript::Write(Stream *out) { +void ccScript::Write(Shared::Stream *out) { int n; out->Write(scfilesig, 4); out->WriteInt32(SCOM_VERSION); @@ -211,7 +211,7 @@ void ccScript::Write(Stream *out) { out->WriteInt32(ENDFILESIG); } -bool ccScript::Read(Stream *in) { +bool ccScript::Read(Shared::Stream *in) { instances = 0; int n; char gotsig[5]; @@ -296,7 +296,7 @@ bool ccScript::Read(Stream *in) { sectionOffsets = nullptr; } - if (in->ReadInt32() != ENDFILESIG) { + if (in->ReadInt32() != (int32)ENDFILESIG) { cc_error("internal error rebuilding script"); return false; } diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index 53b3c4a750bb..a0852f5851c6 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -29,8 +29,8 @@ #ifndef AGS_SHARED_SCRIPT_CC_SCRIPT_H #define AGS_SHARED_SCRIPT_CC_SCRIPT_H -//include #include "ags/shared/core/types.h" +#include "ags/std/memory.h" namespace AGS3 { @@ -68,16 +68,16 @@ struct ccScript { int numSections; int capacitySections; - static ccScript *CreateFromStream(Common::Stream *in); + static ccScript *CreateFromStream(Shared::Stream *in); ccScript(); ccScript(const ccScript &src); virtual ~ccScript(); // there are few derived classes, so dtor should be virtual // write the script to disk (after compiling) - void Write(Common::Stream *out); + void Write(Shared::Stream *out); // read back a script written with Write - bool Read(Common::Stream *in); + bool Read(Shared::Stream *in); const char *GetSectionName(int32_t offset); protected: From 276d14bbb594ae20ec2cdd22e7a63c17ba876957 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 10:41:30 -0800 Subject: [PATCH 013/215] AGS: Adding shared/gui/ folder --- engines/ags/module.mk | 8 ++++++++ engines/ags/shared/ac/common_defines.h | 4 ---- engines/ags/shared/ac/spritecache.h | 18 ++++++++--------- engines/ags/shared/debugging/out.h | 8 ++++---- engines/ags/shared/font/fonts.h | 18 ++++++++--------- engines/ags/shared/gui/guibutton.cpp | 2 +- engines/ags/shared/gui/guibutton.h | 4 ++-- engines/ags/shared/gui/guiinv.h | 4 ++-- engines/ags/shared/gui/guilabel.cpp | 2 +- engines/ags/shared/gui/guilabel.h | 4 ++-- engines/ags/shared/gui/guilistbox.cpp | 2 +- engines/ags/shared/gui/guilistbox.h | 4 ++-- engines/ags/shared/gui/guimain.cpp | 28 +++++++++++++------------- engines/ags/shared/gui/guimain.h | 13 ++++++------ engines/ags/shared/gui/guiobject.h | 8 ++++---- engines/ags/shared/gui/guislider.cpp | 8 ++++---- engines/ags/std/algorithm.h | 5 +++++ 17 files changed, 75 insertions(+), 65 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index ae53b8b55d8c..6a5a42c6c742 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -17,6 +17,14 @@ MODULE_OBJS = \ stubs/allegro/sound.o \ stubs/allegro/system.o \ stubs/allegro/unicode.o \ + shared/gui/guibutton.o \ + shared/gui/guiinv.o \ + shared/gui/guilabel.o \ + shared/gui/guilistbox.o \ + shared/gui/guimain.o \ + shared/gui/guiobject.o \ + shared/gui/guislider.o \ + shared/gui/guitextbox.o \ shared/script/cc_error.o \ shared/script/cc_options.o \ shared/script/cc_script.o \ diff --git a/engines/ags/shared/ac/common_defines.h b/engines/ags/shared/ac/common_defines.h index 282ad7ea89b3..c606d6e62716 100644 --- a/engines/ags/shared/ac/common_defines.h +++ b/engines/ags/shared/ac/common_defines.h @@ -106,10 +106,6 @@ namespace AGS3 { #define LEGACY_MAX_SPRITES 30000 #define MAX_CURSOR 20 -#ifndef int32 -#define int32 int -#endif - #if AGS_PLATFORM_OS_WINDOWS #define AGS_INLINE inline #else diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index a6ed86f3e58f..5a0ebf0dffc1 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -117,8 +117,8 @@ class SpriteCache { static const size_t MAX_SPRITE_SLOTS = INT32_MAX; // Standart sprite file and sprite index names - static const Common::String DefaultSpriteFileName; - static const Common::String DefaultSpriteIndexName; + static const Shared::String DefaultSpriteFileName; + static const Shared::String DefaultSpriteIndexName; SpriteCache(std::vector &sprInfos); ~SpriteCache(); @@ -153,12 +153,12 @@ class SpriteCache { // Deletes all data and resets cache to the clear state void Reset(); // Assigns new sprite for the given index; this sprite won't be auto disposed - void SetSprite(sprkey_t index, Common::Bitmap *); + void SetSprite(sprkey_t index, Shared::Bitmap *); // Assigns new sprite for the given index, remapping it to sprite 0; // optionally marks it as an asset placeholder void SetEmptySprite(sprkey_t index, bool as_asset); // Assigns new bitmap for the *registered* sprite without changing its properties - void SubstituteBitmap(sprkey_t index, Common::Bitmap *); + void SubstituteBitmap(sprkey_t index, Shared::Bitmap *); // Sets max cache size in bytes void SetMaxCacheSize(size_t size); @@ -177,7 +177,7 @@ class SpriteCache { int SaveSpriteIndex(const char *filename, const SpriteFileIndex &index); // Loads (if it's not in cache yet) and returns bitmap by the sprite index - Common::Bitmap *operator[](sprkey_t index); + Shared::Bitmap *operator[](sprkey_t index); private: void Init(); @@ -199,7 +199,7 @@ class SpriteCache { uint32_t Flags; // TODO: investigate if we may safely use unique_ptr here // (some of these bitmaps may be assigned from outside of the cache) - Common::Bitmap *Image; // actual bitmap + Shared::Bitmap *Image; // actual bitmap // Tells if there actually is a registered sprite in this slot bool DoesSpriteExist() const; @@ -220,7 +220,7 @@ class SpriteCache { std::vector _spriteData; bool _compressed; // are sprites compressed - std::unique_ptr _stream; // the sprite stream + std::unique_ptr _stream; // the sprite stream sprkey_t _lastLoad; // last loaded sprite index size_t _maxCacheSize; // cache size limit @@ -240,9 +240,9 @@ class SpriteCache { // Rebuilds sprite index from the main sprite file HAGSError RebuildSpriteIndex(AGS::Shared::Stream *in, sprkey_t topmost, SpriteFileVersion vers); // Writes compressed sprite to the stream - void CompressSprite(Common::Bitmap *sprite, Common::Stream *out); + void CompressSprite(Shared::Bitmap *sprite, Shared::Stream *out); // Uncompresses sprite from stream into the given bitmap - void UnCompressSprite(Common::Bitmap *sprite, Common::Stream *in); + void UnCompressSprite(Shared::Bitmap *sprite, Shared::Stream *in); // Initialize the empty sprite slot void InitNullSpriteParams(sprkey_t index); diff --git a/engines/ags/shared/debugging/out.h b/engines/ags/shared/debugging/out.h index b68cee3bec09..74fc343bc888 100644 --- a/engines/ags/shared/debugging/out.h +++ b/engines/ags/shared/debugging/out.h @@ -132,19 +132,19 @@ struct DebugGroupID { uint32_t ID; String SID; - DebugGroupID() : ID(kDbgGroup_None) { + DebugGroupID() : ID((uint32_t)kDbgGroup_None) { } DebugGroupID(uint32_t id, const String &sid = "") : ID(id), SID(sid) { } - DebugGroupID(const String &sid) : ID(kDbgGroup_None), SID(sid) { + DebugGroupID(const String &sid) : ID((uint32_t)kDbgGroup_None), SID(sid) { } // Tells if any of the id components is valid bool IsValid() const { - return ID != kDbgGroup_None || !SID.IsEmpty(); + return ID != (uint32_t)kDbgGroup_None || !SID.IsEmpty(); } // Tells if both id components are properly set bool IsComplete() const { - return ID != kDbgGroup_None && !SID.IsEmpty(); + return ID != (uint32_t)kDbgGroup_None && !SID.IsEmpty(); } }; diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index 85d69d68c958..c3e92655889d 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -31,9 +31,9 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Bitmap; -namespace Sharedhared +} // namespace Shared } // namespace AGS using namespace AGS; @@ -79,12 +79,12 @@ void set_font_outline(size_t font_number, int outline_type); // Outputs a single line of text on the defined position on bitmap, using defined font, color and parameters int getfontlinespacing(size_t fontNumber); // Print text on a surface using a given font -void wouttextxy(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx); +void wouttextxy(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx); // Assigns FontInfo to the font void set_fontinfo(size_t fontNumber, const FontInfo &finfo); // Loads a font from disk bool wloadfont_size(size_t fontNumber, const FontInfo &font_info); -void wgtprintf(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...); +void wgtprintf(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...); // Free particular font's data void wfreefont(size_t fontNumber); // Free all fonts data @@ -100,10 +100,10 @@ class SplitLines { inline size_t Count() const { return _count; } - inline const Common::String &operator[](size_t i) const { + inline const Shared::String &operator[](size_t i) const { return _pool[i]; } - inline Common::String &operator[](size_t i) { + inline Shared::String &operator[](size_t i) { return _pool[i]; } inline void Clear() { @@ -122,7 +122,7 @@ class SplitLines { std::vector LineBuf; private: - std::vector _pool; + std::vector _pool; size_t _count; // actual number of lines in use }; @@ -131,9 +131,9 @@ class SplitLines { size_t split_lines(const char *texx, SplitLines &lines, int width, int fontNumber, size_t max_lines = -1); namespace AGS { -namespace Common { +namespace Shared { extern SplitLines Lines; -namespace Sharedhared +} // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/shared/gui/guibutton.cpp b/engines/ags/shared/gui/guibutton.cpp index 03a99749eb9e..eee618201aa9 100644 --- a/engines/ags/shared/gui/guibutton.cpp +++ b/engines/ags/shared/gui/guibutton.cpp @@ -279,7 +279,7 @@ void GUIButton::DrawImageButton(Bitmap *ds, bool draw_disabled) { } if (place == kButtonPlace_InvItemStretch) { - ds->StretchBlt(spriteset[gui_inv_pic], RectWH(X + 3, Y + 3, Width - 6, Height - 6), Common::kBitmap_Transparency); + ds->StretchBlt(spriteset[gui_inv_pic], RectWH(X + 3, Y + 3, Width - 6, Height - 6), Shared::kBitmap_Transparency); } else if (place == kButtonPlace_InvItemCenter) { draw_gui_sprite(ds, gui_inv_pic, X + Width / 2 - get_adjusted_spritewidth(gui_inv_pic) / 2, diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index 87597ec57f7d..955df3c5c629 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -79,8 +79,8 @@ class GUIButton : public GUIObject { // Serialization void ReadFromFile(Stream *in, GuiVersion gui_version) override; void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; // TODO: these members are currently public; hide them later public: diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index 9debe7dcec4c..ba16d7a59633 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -50,8 +50,8 @@ class GUIInvWindow : public GUIObject { // Serialization void ReadFromFile(Stream *in, GuiVersion gui_version) override; void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; // TODO: these members are currently public; hide them later public: diff --git a/engines/ags/shared/gui/guilabel.cpp b/engines/ags/shared/gui/guilabel.cpp index ea91eeef0254..96b26c1bfeda 100644 --- a/engines/ags/shared/gui/guilabel.cpp +++ b/engines/ags/shared/gui/guilabel.cpp @@ -49,7 +49,7 @@ String GUILabel::GetText() const { return Text; } -void GUILabel::Draw(Common::Bitmap *ds) { +void GUILabel::Draw(Shared::Bitmap *ds) { check_font(&Font); // TODO: need to find a way to cache text prior to drawing; diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index 6ad4a883b274..836b473a4b4e 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -47,8 +47,8 @@ class GUILabel : public GUIObject { // Serialization void ReadFromFile(Stream *in, GuiVersion gui_version) override; void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; // TODO: these members are currently public; hide them later public: diff --git a/engines/ags/shared/gui/guilistbox.cpp b/engines/ags/shared/gui/guilistbox.cpp index b3ee25688bed..f908df0dac08 100644 --- a/engines/ags/shared/gui/guilistbox.cpp +++ b/engines/ags/shared/gui/guilistbox.cpp @@ -97,7 +97,7 @@ void GUIListBox::Clear() { guis_need_update = 1; } -void GUIListBox::Draw(Common::Bitmap *ds) { +void GUIListBox::Draw(Shared::Bitmap *ds) { const int width = Width - 1; const int height = Height - 1; const int pixel_size = get_fixed_pixel_size(1); diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index 61472388b8f3..090184ba04ea 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -61,8 +61,8 @@ class GUIListBox : public GUIObject { // Serialization void ReadFromFile(Stream *in, GuiVersion gui_version) override; void WriteToFile(Stream *out) const override; - void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver) override; - void WriteToSavegame(Common::Stream *out) const override; + void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) override; + void WriteToSavegame(Stream *out) const override; // TODO: these members are currently public; hide them later public: diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index 8b1f6e8b7f3d..1fb82b51758f 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -20,7 +20,6 @@ * */ -//include #include "ags/shared/ac/game_version.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/debugging/out.h" @@ -34,6 +33,7 @@ #include "ags/shared/gui/guitextbox.h" #include "ags/shared/util/stream.h" #include "ags/shared/util/string_utils.h" +#include "ags/std/algorithm.h" namespace AGS3 { @@ -561,7 +561,7 @@ void GUIMain::WriteToFile(Stream *out) const { } } -void GUIMain::ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_version) { +void GUIMain::ReadFromSavegame(Stream *in, GuiSvgVersion svg_version) { // Properties _flags = in->ReadInt32(); X = in->ReadInt32(); @@ -593,7 +593,7 @@ void GUIMain::ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_version) { MouseWasAt.Y = in->ReadInt32(); } -void GUIMain::WriteToSavegame(Common::Stream *out) const { +void GUIMain::WriteToSavegame(Stream *out) const { // Properties out->WriteInt32(_flags); out->WriteInt32(X); @@ -643,10 +643,10 @@ void DrawTextAlignedHor(Bitmap *ds, const char *text, int font, color_t text_col wouttext_outline(ds, x, y, font, text_color, text); } -HError ResortGUI(std::vector &guis, bool bwcompat_ctrl_zorder = false) { +HError ResortGUI(std::vector &theGuis, bool bwcompat_ctrl_zorder = false) { // set up the reverse-lookup array - for (size_t gui_index = 0; gui_index < guis.size(); ++gui_index) { - GUIMain &gui = guis[gui_index]; + for (size_t gui_index = 0; gui_index < theGuis.size(); ++gui_index) { + GUIMain &gui = theGuis[gui_index]; HError err = gui.RebuildArray(); if (!err) return err; @@ -663,7 +663,7 @@ HError ResortGUI(std::vector &guis, bool bwcompat_ctrl_zorder = false) return HError::None(); } -HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame) { +HError ReadGUI(std::vector &theGuis, Stream *in, bool is_savegame) { if (in->ReadInt32() != (int)GUIMAGIC) return new Error("ReadGUI: unknown format or file is corrupt"); @@ -678,11 +678,11 @@ HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame) { GameGuiVersion, kGuiVersion_Initial, kGuiVersion_Current)); else gui_count = in->ReadInt32(); - guis.resize(gui_count); + theGuis.resize(gui_count); // import the main GUI elements for (size_t i = 0; i < gui_count; ++i) { - GUIMain &gui = guis[i]; + GUIMain &gui = theGuis[i]; gui.InitDefaults(); gui.ReadFromFile(in, GameGuiVersion); @@ -764,16 +764,16 @@ HError ReadGUI(std::vector &guis, Stream *in, bool is_savegame) { guilist[i].ReadFromFile(in, GameGuiVersion); } } - return ResortGUI(guis, GameGuiVersion < kGuiVersion_272e); + return ResortGUI(theGuis, GameGuiVersion < kGuiVersion_272e); } -void WriteGUI(const std::vector &guis, Stream *out) { +void WriteGUI(const std::vector &theGuis, Stream *out) { out->WriteInt32(GUIMAGIC); out->WriteInt32(kGuiVersion_Current); - out->WriteInt32(guis.size()); + out->WriteInt32(theGuis.size()); - for (size_t i = 0; i < guis.size(); ++i) { - guis[i].WriteToFile(out); + for (size_t i = 0; i < theGuis.size(); ++i) { + theGuis[i].WriteToFile(out); } out->WriteInt32(numguibuts); for (int i = 0; i < numguibuts; ++i) { diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index 4a930f3b4f26..4c42a25e5907 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -23,13 +23,14 @@ #ifndef AGS_SHARED_GUI_GUIMAIN_H #define AGS_SHARED_GUI_GUIMAIN_H -//include #include "ags/shared/ac/common_defines.h" // TODO: split out gui drawing helpers #include "ags/shared/gfx/gfx_def.h" // TODO: split out gui drawing helpers #include "ags/shared/gui/guidefines.h" #include "ags/shared/util/error.h" #include "ags/shared/util/geometry.h" #include "ags/shared/util/string.h" +#include "ags/std/utility.h" +#include "ags/std/vector.h" namespace AGS3 { @@ -217,7 +218,7 @@ void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis); } // namespace Shared } // namespace AGS -extern std::vector guis; +extern std::vector guis; extern int all_buttons_disabled, gui_inv_pic; extern int gui_disabled_style; @@ -228,8 +229,8 @@ extern int get_adjusted_spriteheight(int spr); extern bool is_sprite_alpha(int spr); // This function has distinct implementations in Engine and Editor -extern void draw_gui_sprite(Common::Bitmap *ds, int spr, int x, int y, bool use_alpha = true, - Common::BlendMode blend_mode = Common::kBlendMode_Alpha); +extern void draw_gui_sprite(Shared::Bitmap *ds, int spr, int x, int y, bool use_alpha = true, + Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha); extern AGS_INLINE int game_to_data_coord(int coord); extern AGS_INLINE int data_to_game_coord(int coord); @@ -237,8 +238,8 @@ extern AGS_INLINE void data_to_game_coords(int *x, int *y); extern AGS_INLINE int get_fixed_pixel_size(int pixels); // Those function have distinct implementations in Engine and Editor -extern void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); -extern int wgettextwidth_compensate(Common::Bitmap *ds, const char *tex, int font); +extern void wouttext_outline(Shared::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); +extern int wgettextwidth_compensate(Shared::Bitmap *ds, const char *tex, int font); extern void check_font(int *fontnum); extern void set_our_eip(int eip); diff --git a/engines/ags/shared/gui/guiobject.h b/engines/ags/shared/gui/guiobject.h index bf37d9b792d8..c0ba3c46307b 100644 --- a/engines/ags/shared/gui/guiobject.h +++ b/engines/ags/shared/gui/guiobject.h @@ -95,10 +95,10 @@ class GUIObject { } // Serialization - virtual void ReadFromFile(Common::Stream *in, GuiVersion gui_version); - virtual void WriteToFile(Common::Stream *out) const; - virtual void ReadFromSavegame(Common::Stream *in, GuiSvgVersion svg_ver); - virtual void WriteToSavegame(Common::Stream *out) const; + virtual void ReadFromFile(Stream *in, GuiVersion gui_version); + virtual void WriteToFile(Stream *out) const; + virtual void ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver); + virtual void WriteToSavegame(Stream *out) const; // TODO: these members are currently public; hide them later public: diff --git a/engines/ags/shared/gui/guislider.cpp b/engines/ags/shared/gui/guislider.cpp index e356d620e79a..fff16de2aa42 100644 --- a/engines/ags/shared/gui/guislider.cpp +++ b/engines/ags/shared/gui/guislider.cpp @@ -51,15 +51,15 @@ bool GUISlider::IsHorizontal() const { return Width > Height; } -bool GUISlider::IsOverControl(int X, int Y, int leeway) const { +bool GUISlider::IsOverControl(int x, int y, int leeway) const { // check the overall boundary - if (GUIObject::IsOverControl(X, Y, leeway)) + if (GUIObject::IsOverControl(x, y, leeway)) return true; // now check the handle too - return _cachedHandle.IsInside(Point(X, Y)); + return _cachedHandle.IsInside(Point(x, y)); } -void GUISlider::Draw(Common::Bitmap *ds) { +void GUISlider::Draw(Bitmap *ds) { Rect bar; Rect handle; int thickness; diff --git a/engines/ags/std/algorithm.h b/engines/ags/std/algorithm.h index 504e883a42d8..8b5f070125bb 100644 --- a/engines/ags/std/algorithm.h +++ b/engines/ags/std/algorithm.h @@ -36,6 +36,11 @@ template inline T clip(T v, T amin, T amax) { return CLIP(v, amin, a template inline T sqrt(T x) { return ::sqrt(x); } template inline void swap(T a, T b) { SWAP(a, b); } +template +void sort(T first, T last, StrictWeakOrdering comp) { + Common::sort(first, last, comp); +} + } // namespace std } // namespace AGS3 From 185baf42affddb66532e6a375a9c88ba83d91c85 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 16:18:27 -0800 Subject: [PATCH 014/215] AGS: Added shared/gfx/ and support code --- engines/ags/lib/aastr-0.1.1/aarot.cpp | 559 +++++++ engines/ags/lib/aastr-0.1.1/aastr.cpp | 224 +++ engines/ags/lib/aastr-0.1.1/aastr.h | 74 + engines/ags/lib/aastr-0.1.1/aautil.cpp | 1836 ++++++++++++++++++++++ engines/ags/lib/aastr-0.1.1/aautil.h | 166 ++ engines/ags/module.mk | 6 + engines/ags/shared/core/types.h | 2 +- engines/ags/shared/gfx/allegrobitmap.cpp | 5 +- engines/ags/shared/gfx/allegrobitmap.h | 8 +- engines/ags/shared/gfx/bitmap.cpp | 4 +- engines/ags/shared/gfx/image.cpp | 77 + engines/ags/shared/gfx/image.h | 43 + engines/ags/shared/util/wgt2allg.h | 2 +- engines/ags/stubs/allegro/color.cpp | 60 +- engines/ags/stubs/allegro/color.h | 23 +- engines/ags/stubs/allegro/gfx.cpp | 346 ++++ engines/ags/stubs/allegro/gfx.h | 92 +- 17 files changed, 3514 insertions(+), 13 deletions(-) create mode 100644 engines/ags/lib/aastr-0.1.1/aarot.cpp create mode 100644 engines/ags/lib/aastr-0.1.1/aastr.cpp create mode 100644 engines/ags/lib/aastr-0.1.1/aastr.h create mode 100644 engines/ags/lib/aastr-0.1.1/aautil.cpp create mode 100644 engines/ags/lib/aastr-0.1.1/aautil.h create mode 100644 engines/ags/shared/gfx/image.cpp create mode 100644 engines/ags/shared/gfx/image.h diff --git a/engines/ags/lib/aastr-0.1.1/aarot.cpp b/engines/ags/lib/aastr-0.1.1/aarot.cpp new file mode 100644 index 000000000000..e2bd4f325b85 --- /dev/null +++ b/engines/ags/lib/aastr-0.1.1/aarot.cpp @@ -0,0 +1,559 @@ +/* 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. + * + */ + +/* + * aarot.c --- anti-aliased rotation for Allegro + * + * This file is gift-ware. This file is given to you freely + * as a gift. You may use, modify, redistribute, and generally hack + * it about in any way you like, and you do not have to give anyone + * anything in return. + * + * I do not accept any responsibility for any effects, adverse or + * otherwise, that this code may have on just about anything that + * you can think of. Use it at your own risk. + * + * Copyright (C) 1998, 1999 Michael Bukin + */ + +#include "ags/lib/aastr-0.1.1/aastr.h" +#include "ags/lib/aastr-0.1.1/aautil.h" + +namespace AGS3 { + +/* + * Engine of anti-aliased rotation. + */ +static void +_aa_rotate_bitmap(BITMAP *_src, BITMAP *_dst, int _x, int _y, fixed _angle, + fixed _scalex, fixed _scaley, int _masked) { + int sw, sh, dw, dh; + fixed fx0, fy0, fux, fuy, fvx, fvy; + fixed fdw, fdh, fsinangle, fcosangle; + struct { + int dx, dy; + int sx, sy; + } point[4], *lpoint1, *lpoint2, *rpoint1, *rpoint2; + int ledge[4], redge[4], lindex, rindex; + int xbeg, xend, ybeg, yend; + int sx, sy, dx, dy, dsx, dsy; + int ldx, lsx, lsy, *lsc; + int rdx, rsx, rsy, *rsc; + int ldxinc, ldxdd, ldxi1, ldxi2; + int rdxinc, rdxdd, rdxi1, rdxi2; + int lscinc, lscdd, lsci1, lsci2; + int rscinc, rscdd, rsci1, rsci2; + int sxinc, sxdd, sxi1, sxi2; + int syinc, sydd, syi1, syi2; + unsigned long num; + void (*add) (BITMAP * _src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); + void (*put) (unsigned long _addr, int _x); + + if (_dst->clip) { + xbeg = _dst->cl; + xend = _dst->cr; + ybeg = _dst->ct; + yend = _dst->cb; + } else { + xbeg = 0; + xend = _dst->w; + ybeg = 0; + yend = _dst->h; + } + + if ((xbeg >= xend) || (ybeg >= yend)) + return; + + /* Convert angle to [0, 256) range. */ + _angle %= itofix(256); + if (_angle < 0) + _angle += itofix(256); + + /* Width and height of source and destination. */ + sw = _src->w; + sh = _src->h; + fdw = fixmul(ABS(_scalex), itofix(sw)); + fdh = fixmul(ABS(_scaley), itofix(sh)); + dw = fixtoi(fdw); + dh = fixtoi(fdh); + if ((dw <= 0) || (dh <= 0)) + return; + + fdw /= 2; + fdh /= 2; + + /* Center of destination. */ + fx0 = itofix(_x); + fy0 = itofix(_y); + + fsinangle = fixsin(_angle); + fcosangle = fixcos(_angle); + + /* Map source (half) edges onto destination. */ + fux = fixmul(fdw, fcosangle); + fuy = fixmul(fdw, fsinangle); + fvx = -fixmul(fdh, fsinangle); + fvy = fixmul(fdh, fcosangle); + + /* Coordinates of corners in destination. */ + point[0].dx = fixtoi(fx0 - fux - fvx); + point[1].dx = fixtoi(fx0 + fux - fvx); + point[2].dx = fixtoi(fx0 - fux + fvx); + point[3].dx = fixtoi(fx0 + fux + fvx); + point[0].dy = fixtoi(fy0 - fuy - fvy); + point[1].dy = fixtoi(fy0 + fuy - fvy); + point[2].dy = fixtoi(fy0 - fuy + fvy); + point[3].dy = fixtoi(fy0 + fuy + fvy); + + sw <<= aa_BITS; + dsx = sw / dw; + if (dsx < aa_SIZE) + dsx = aa_SIZE; + sw -= dsx; + + sh <<= aa_BITS; + dsy = sh / dh; + if (dsy < aa_SIZE) + dsy = aa_SIZE; + sh -= dsy; + + num = dsx * dsy; + + /* Avoid overflow. */ + if (num > aa_MAX_NUM) { + if (dsx > aa_MAX_SIZE) + dsx = aa_MAX_SIZE; + if (dsy > aa_MAX_SIZE) + dsy = aa_MAX_SIZE; + num = dsx * dsy; + } + + /* Coordinates of corners in source. */ + if (_scalex < 0) { + point[0].sx = sw; + point[1].sx = 0; + point[2].sx = sw; + point[3].sx = 0; + } else { + point[0].sx = 0; + point[1].sx = sw; + point[2].sx = 0; + point[3].sx = sw; + } + if (_scaley < 0) { + point[0].sy = sh; + point[1].sy = sh; + point[2].sy = 0; + point[3].sy = 0; + } else { + point[0].sy = 0; + point[1].sy = 0; + point[2].sy = sh; + point[3].sy = sh; + } + + /* Sort left and right edges. */ + if ((_angle < itofix(32)) || (_angle >= itofix(128 + 64 + 32))) { + if (point[0].dy < point[1].dy) { + ledge[0] = 0; + ledge[1] = 2; + ledge[2] = 3; + redge[0] = 0; + redge[1] = 1; + redge[2] = 3; + } else if (point[0].dy > point[1].dy) { + ledge[0] = 1; + ledge[1] = 0; + ledge[2] = 2; + redge[0] = 1; + redge[1] = 3; + redge[2] = 2; + } else { + ledge[0] = 0; + ledge[1] = 2; + ledge[2] = 3; + redge[0] = 1; + redge[1] = 3; + redge[2] = 2; + } + } else if (_angle < itofix(64 + 32)) { + if (point[0].dy < point[2].dy) { + ledge[0] = 0; + ledge[1] = 2; + ledge[2] = 3; + redge[0] = 0; + redge[1] = 1; + redge[2] = 3; + } else if (point[0].dy > point[2].dy) { + ledge[0] = 2; + ledge[1] = 3; + ledge[2] = 1; + redge[0] = 2; + redge[1] = 0; + redge[2] = 1; + } else { + ledge[0] = 2; + ledge[1] = 3; + ledge[2] = 1; + redge[0] = 0; + redge[1] = 1; + redge[2] = 3; + } + } else if (_angle < itofix(128 + 32)) { + if (point[2].dy < point[3].dy) { + ledge[0] = 2; + ledge[1] = 3; + ledge[2] = 1; + redge[0] = 2; + redge[1] = 0; + redge[2] = 1; + } else if (point[2].dy > point[3].dy) { + ledge[0] = 3; + ledge[1] = 1; + ledge[2] = 0; + redge[0] = 3; + redge[1] = 2; + redge[2] = 0; + } else { + ledge[0] = 3; + ledge[1] = 1; + ledge[2] = 0; + redge[0] = 2; + redge[1] = 0; + redge[2] = 1; + } + } else { + if (point[1].dy < point[3].dy) { + ledge[0] = 1; + ledge[1] = 0; + ledge[2] = 2; + redge[0] = 1; + redge[1] = 3; + redge[2] = 2; + } else if (point[1].dy > point[3].dy) { + ledge[0] = 3; + ledge[1] = 1; + ledge[2] = 0; + redge[0] = 3; + redge[1] = 2; + redge[2] = 0; + } else { + ledge[0] = 1; + ledge[1] = 0; + ledge[2] = 2; + redge[0] = 3; + redge[1] = 2; + redge[2] = 0; + } + } + + /* Remove wrong edges on bottom. */ + if (point[ledge[0]].dy == point[ledge[1]].dy) { + ledge[0] = ledge[1]; + ledge[1] = ledge[2]; + } + if (point[ledge[1]].dy >= point[ledge[2]].dy) + ledge[2] = -1; + ledge[3] = -1; + + if (point[redge[0]].dy == point[redge[1]].dy) { + redge[0] = redge[1]; + redge[1] = redge[2]; + } + if (point[redge[1]].dy >= point[redge[2]].dy) + redge[2] = -1; + redge[3] = -1; + + /* Completely clipped by y? */ + if ((point[ledge[0]].dy >= yend) + || ((ledge[2] == -1) && (point[ledge[1]].dy < ybeg)) + || (point[ledge[2]].dy < ybeg)) + return; + + /* Color manipulation routines. */ + if (is_screen_bitmap(_src)) + return; + else { + switch (bitmap_color_depth(_src)) { + case 8: + add = ((_masked != 0) ? _aa_masked_add_rgb8 : _aa_add_rgb8); + break; +#ifdef ALLEGRO_COLOR16 + case 15: + add = ((_masked != 0) ? _aa_masked_add_rgb15 : _aa_add_rgb15); + break; + case 16: + add = ((_masked != 0) ? _aa_masked_add_rgb16 : _aa_add_rgb16); + break; +#endif +#ifdef ALLEGRO_COLOR24 + case 24: + add = ((_masked != 0) ? _aa_masked_add_rgb24 : _aa_add_rgb24); + _aa_prepare_for_24bpp(); + break; +#endif +#ifdef ALLEGRO_COLOR32 + case 32: + add = ((_masked != 0) ? _aa_masked_add_rgb32 : _aa_add_rgb32); + break; +#endif + default: + return; + } + } + + if (is_planar_bitmap(_dst)) + return; + else { + switch (bitmap_color_depth(_dst)) { + case 8: + put = ((_masked != 0) ? _aa_masked_put_rgb8 : _aa_put_rgb8); + break; +#ifdef ALLEGRO_COLOR16 + case 15: + put = ((_masked != 0) ? _aa_masked_put_rgb15 : _aa_put_rgb15); + break; + case 16: + put = ((_masked != 0) ? _aa_masked_put_rgb16 : _aa_put_rgb16); + break; +#endif +#ifdef ALLEGRO_COLOR24 + case 24: + put = ((_masked != 0) ? _aa_masked_put_rgb24 : _aa_put_rgb24); + _aa_prepare_for_24bpp(); + break; +#endif +#ifdef ALLEGRO_COLOR32 + case 32: + put = ((_masked != 0) ? _aa_masked_put_rgb32 : _aa_put_rgb32); + break; +#endif + default: + return; + } + } + + lindex = 1; + rindex = 1; + lpoint1 = &point[ledge[0]]; + lpoint2 = &point[ledge[1]]; + rpoint1 = &point[redge[0]]; + rpoint2 = &point[redge[1]]; + + dy = lpoint1->dy; + if (ledge[2] == -1) { + if (point[ledge[1]].dy < yend) + yend = point[ledge[1]].dy + 1; + } else if (point[ledge[2]].dy < yend) + yend = point[ledge[2]].dy + 1; + + ldx = lpoint1->dx; + aa_PREPARE(ldxinc, ldxdd, ldxi1, ldxi2, + lpoint2->dx - lpoint1->dx, lpoint2->dy - lpoint1->dy); + + lsx = lpoint1->sx; + lsy = lpoint1->sy; + if (lpoint1->sx != lpoint2->sx) { + lsc = &lsx; + aa_PREPARE(lscinc, lscdd, lsci1, lsci2, + lpoint2->sx - lpoint1->sx, lpoint2->dy - lpoint1->dy); + } else { + lsc = &lsy; + aa_PREPARE(lscinc, lscdd, lsci1, lsci2, + lpoint2->sy - lpoint1->sy, lpoint2->dy - lpoint1->dy); + } + + rdx = rpoint1->dx; + aa_PREPARE(rdxinc, rdxdd, rdxi1, rdxi2, + rpoint2->dx - rpoint1->dx, rpoint2->dy - rpoint1->dy); + + rsx = rpoint1->sx; + rsy = rpoint1->sy; + if (rpoint1->sx != rpoint2->sx) { + rsc = &rsx; + aa_PREPARE(rscinc, rscdd, rsci1, rsci2, + rpoint2->sx - rpoint1->sx, rpoint2->dy - rpoint1->dy); + } else { + rsc = &rsy; + aa_PREPARE(rscinc, rscdd, rsci1, rsci2, + rpoint2->sy - rpoint1->sy, rpoint2->dy - rpoint1->dy); + } + + /* Skip region clipped on top. */ + while (dy < ybeg) { + dy++; + + if (dy > lpoint2->dy) { + if (ledge[++lindex] == -1) + return; + lpoint1 = lpoint2; + lpoint2 = &point[ledge[lindex]]; + + if (lpoint1->sx != lpoint2->sx) { + lsc = &lsx; + aa_PREPARE(lscinc, lscdd, lsci1, lsci2, + lpoint2->sx - lpoint1->sx, lpoint2->dy - lpoint1->dy); + } else { + lsc = &lsy; + aa_PREPARE(lscinc, lscdd, lsci1, lsci2, + lpoint2->sy - lpoint1->sy, lpoint2->dy - lpoint1->dy); + } + aa_PREPARE(ldxinc, ldxdd, ldxi1, ldxi2, + lpoint2->dx - lpoint1->dx, lpoint2->dy - lpoint1->dy); + } + aa_ADVANCE(*lsc, lscinc, lscdd, lsci1, lsci2); + aa_ADVANCE(ldx, ldxinc, ldxdd, ldxi1, ldxi2); + + if (dy > rpoint2->dy) { + if (redge[++rindex] == -1) + return; + rpoint1 = rpoint2; + rpoint2 = &point[redge[rindex]]; + + if (rpoint1->sx != rpoint2->sx) { + rsc = &rsx; + aa_PREPARE(rscinc, rscdd, rsci1, rsci2, + rpoint2->sx - rpoint1->sx, rpoint2->dy - rpoint1->dy); + } else { + rsc = &rsy; + aa_PREPARE(rscinc, rscdd, rsci1, rsci2, + rpoint2->sy - rpoint1->sy, rpoint2->dy - rpoint1->dy); + } + aa_PREPARE(rdxinc, rdxdd, rdxi1, rdxi2, + rpoint2->dx - rpoint1->dx, rpoint2->dy - rpoint1->dy); + } + aa_ADVANCE(*rsc, rscinc, rscdd, rsci1, rsci2); + aa_ADVANCE(rdx, rdxinc, rdxdd, rdxi1, rdxi2); + } + + bmp_select(_dst); + + /* Stretch lines. */ + while (dy < yend) { + unsigned long daddr = bmp_write_line(_dst, dy); + + if ((ldx < xend) && (rdx >= xbeg)) { + int curxend; + + aa_PREPARE(sxinc, sxdd, sxi1, sxi2, + rsx - lsx, rdx - ldx); + aa_PREPARE(syinc, sydd, syi1, syi2, + rsy - lsy, rdx - ldx); + + for (sx = lsx, sy = lsy, dx = ldx; dx < xbeg; dx++) { + aa_ADVANCE(sx, sxinc, sxdd, sxi1, sxi2); + aa_ADVANCE(sy, syinc, sydd, syi1, syi2); + } + + curxend = (rdx < xend) ? (rdx + 1) : xend; + for (; dx < curxend; dx++) { + (*add) (_src, sx, sx + dsx, sy, sy + dsy, num); + (*put) (daddr, dx); + + aa_ADVANCE(sx, sxinc, sxdd, sxi1, sxi2); + aa_ADVANCE(sy, syinc, sydd, syi1, syi2); + } + } + + dy++; + + if (dy > lpoint2->dy) { + if (ledge[++lindex] == -1) + return; + lpoint1 = lpoint2; + lpoint2 = &point[ledge[lindex]]; + + if (lpoint1->sx != lpoint2->sx) { + lsc = &lsx; + aa_PREPARE(lscinc, lscdd, lsci1, lsci2, + lpoint2->sx - lpoint1->sx, lpoint2->dy - lpoint1->dy); + } else { + lsc = &lsy; + aa_PREPARE(lscinc, lscdd, lsci1, lsci2, + lpoint2->sy - lpoint1->sy, lpoint2->dy - lpoint1->dy); + } + aa_PREPARE(ldxinc, ldxdd, ldxi1, ldxi2, + lpoint2->dx - lpoint1->dx, lpoint2->dy - lpoint1->dy); + } + aa_ADVANCE(*lsc, lscinc, lscdd, lsci1, lsci2); + aa_ADVANCE(ldx, ldxinc, ldxdd, ldxi1, ldxi2); + + if (dy > rpoint2->dy) { + if (redge[++rindex] == -1) + return; + rpoint1 = rpoint2; + rpoint2 = &point[redge[rindex]]; + + if (rpoint1->sx != rpoint2->sx) { + rsc = &rsx; + aa_PREPARE(rscinc, rscdd, rsci1, rsci2, + rpoint2->sx - rpoint1->sx, rpoint2->dy - rpoint1->dy); + } else { + rsc = &rsy; + aa_PREPARE(rscinc, rscdd, rsci1, rsci2, + rpoint2->sy - rpoint1->sy, rpoint2->dy - rpoint1->dy); + } + aa_PREPARE(rdxinc, rdxdd, rdxi1, rdxi2, + rpoint2->dx - rpoint1->dx, rpoint2->dy - rpoint1->dy); + } + aa_ADVANCE(*rsc, rscinc, rscdd, rsci1, rsci2); + aa_ADVANCE(rdx, rdxinc, rdxdd, rdxi1, rdxi2); + } + + bmp_unwrite_line(_dst); +} + +/* + * Anti-aliased bitmap rotation with scaling. + */ +void +aa_rotate_scaled_bitmap(BITMAP *_src, BITMAP *_dst, int _x, int _y, fixed _angle, + fixed _scalex, fixed _scaley) { + _aa_rotate_bitmap(_src, _dst, _x, _y, _angle, _scalex, _scaley, 0); +} + +/* + * Anti-aliased bitmap rotation with scaling (masked). + */ +void +aa_rotate_scaled_sprite(BITMAP *_dst, BITMAP *_src, int _x, int _y, fixed _angle, + fixed _scalex, fixed _scaley) { + _aa_rotate_bitmap(_src, _dst, _x, _y, _angle, _scalex, _scaley, 1); +} + +/* + * Anti-aliased bitmap rotation. + */ +void +aa_rotate_bitmap(BITMAP *_src, BITMAP *_dst, int _x, int _y, fixed _angle) { + _aa_rotate_bitmap(_src, _dst, _x, _y, _angle, itofix(1), itofix(1), 0); +} + +/* + * Anti-aliased bitmap rotation (masked). + */ +void +aa_rotate_sprite(BITMAP *_dst, BITMAP *_src, int _x, int _y, fixed _angle) { + _aa_rotate_bitmap(_src, _dst, _x, _y, _angle, itofix(1), itofix(1), 1); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/aastr-0.1.1/aastr.cpp b/engines/ags/lib/aastr-0.1.1/aastr.cpp new file mode 100644 index 000000000000..e62bbf7020da --- /dev/null +++ b/engines/ags/lib/aastr-0.1.1/aastr.cpp @@ -0,0 +1,224 @@ +/* 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. + * + */ + +/* + * aastr.c --- anti-aliased stretching for Allegro + * + * This file is gift-ware. This file is given to you freely + * as a gift. You may use, modify, redistribute, and generally hack + * it about in any way you like, and you do not have to give anyone + * anything in return. + * + * I do not accept any responsibility for any effects, adverse or + * otherwise, that this code may have on just about anything that + * you can think of. Use it at your own risk. + * + * Copyright (C) 1998, 1999 Michael Bukin + */ + +#include "ags/lib/aastr-0.1.1/aastr.h" +#include "ags/lib/aastr-0.1.1/aautil.h" + +namespace AGS3 { + +/* + * Engine of anti-aliased stretching. + */ +static void +_aa_stretch_blit(BITMAP *_src, BITMAP *_dst, + int _sx, int _sy, int _sw, int _sh, + int _dx, int _dy, int _dw, int _dh, int _masked) { + int sx, sy, dx, dy, ydx, ysx; + int xinc, yinc, dsx, dsy; + int xi1, xi2, xdd, yxdd; + int yi1, yi2, ydd; + int dxbeg, dxend, dybeg, dyend; + unsigned long num; + void (*add) (BITMAP * _src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); + void (*put) (unsigned long _addr, int _x); + + if ((_dw <= 0) || (_dh <= 0) || (_sw <= 0) || (_sh <= 0)) + return; + + if (_dst->clip) { + dybeg = ((_dy > _dst->ct) ? _dy : _dst->ct); + dyend = (((_dy + _dh) < _dst->cb) ? (_dy + _dh) : _dst->cb); + if (dybeg >= dyend) + return; + + dxbeg = ((_dx > _dst->cl) ? _dx : _dst->cl); + dxend = (((_dx + _dw) < _dst->cr) ? (_dx + _dw) : _dst->cr); + if (dxbeg >= dxend) + return; + } else { + dxbeg = _dx; + dybeg = _dy; + dxend = _dx + _dw; + dyend = _dy + _dh; + } + + _sx <<= aa_BITS; + _sw <<= aa_BITS; + dsx = _sw / _dw; + + if (dsx < aa_SIZE) { + /* Exploding by x. */ + _dw--; + _sw -= aa_SIZE; + dsx = aa_SIZE; + } + + _sy <<= aa_BITS; + _sh <<= aa_BITS; + dsy = _sh / _dh; + + if (dsy < aa_SIZE) { + /* Exploding by y. */ + _dh--; + _sh -= aa_SIZE; + dsy = aa_SIZE; + } + + num = dsx * dsy; + + if (num > aa_MAX_NUM) { + if (dsx > aa_MAX_SIZE) + dsx = aa_MAX_SIZE; + if (dsy > aa_MAX_SIZE) + dsy = aa_MAX_SIZE; + num = dsx * dsy; + } + + /* Walk in x direction up to dxbeg and save Bresenham state there. + * Later, it will be used to restart at any line. */ + aa_PREPARE(xinc, yxdd, xi1, xi2, _sw, _dw); + for (ydx = _dx, ysx = _sx; ydx < dxbeg; ydx++) { + aa_ADVANCE(ysx, xinc, yxdd, xi1, xi2); + } + + /* Color manipulation routines. */ + if (is_screen_bitmap(_src)) + return; + else { + switch (bitmap_color_depth(_src)) { + case 8: + add = ((_masked != 0) ? _aa_masked_add_rgb8 : _aa_add_rgb8); + break; +#ifdef ALLEGRO_COLOR16 + case 15: + add = ((_masked != 0) ? _aa_masked_add_rgb15 : _aa_add_rgb15); + break; + case 16: + add = ((_masked != 0) ? _aa_masked_add_rgb16 : _aa_add_rgb16); + break; +#endif +#ifdef ALLEGRO_COLOR24 + case 24: + add = ((_masked != 0) ? _aa_masked_add_rgb24 : _aa_add_rgb24); + _aa_prepare_for_24bpp(); + break; +#endif +#ifdef ALLEGRO_COLOR32 + case 32: + add = ((_masked != 0) ? _aa_masked_add_rgb32 : _aa_add_rgb32); + break; +#endif + default: + return; + } + } + + if (is_planar_bitmap(_dst)) + return; + else { + switch (bitmap_color_depth(_dst)) { + case 8: + put = ((_masked != 0) ? _aa_masked_put_rgb8 : _aa_put_rgb8); + break; +#ifdef ALLEGRO_COLOR16 + case 15: + put = ((_masked != 0) ? _aa_masked_put_rgb15 : _aa_put_rgb15); + break; + case 16: + put = ((_masked != 0) ? _aa_masked_put_rgb16 : _aa_put_rgb16); + break; +#endif +#ifdef ALLEGRO_COLOR24 + case 24: + put = ((_masked != 0) ? _aa_masked_put_rgb24 : _aa_put_rgb24); + _aa_prepare_for_24bpp(); + break; +#endif +#ifdef ALLEGRO_COLOR32 + case 32: + put = ((_masked != 0) ? _aa_masked_put_rgb32 : _aa_put_rgb32); + break; +#endif + default: + return; + } + } + + /* Walk in y until we reach first non-clipped line. */ + aa_PREPARE(yinc, ydd, yi1, yi2, _sh, _dh); + for (dy = _dy, sy = _sy; dy < dybeg; dy++) { + aa_ADVANCE(sy, yinc, ydd, yi1, yi2); + } + + bmp_select(_dst); + + /* Stretch all non-clipped lines. */ + for (; dy < dyend; dy++) { + unsigned long daddr = bmp_write_line(_dst, dy); + + for (dx = ydx, sx = ysx, xdd = yxdd; dx < dxend; dx++) { + (*add) (_src, sx, sx + dsx, sy, sy + dsy, num); + (*put) (daddr, dx); + + aa_ADVANCE(sx, xinc, xdd, xi1, xi2); + } + + aa_ADVANCE(sy, yinc, ydd, yi1, yi2); + } + + bmp_unwrite_line(_dst); +} + +/* + * Anti-aliased bitmap stretching with blit. + */ +void +aa_stretch_blit(BITMAP *_src, BITMAP *_dst, + int _sx, int _sy, int _sw, int _sh, + int _dx, int _dy, int _dw, int _dh) { + _aa_stretch_blit(_src, _dst, _sx, _sy, _sw, _sh, _dx, _dy, _dw, _dh, 0); +} + +/* + * Anti-aliased bitmap stretching with blit (masked). + */ +void +aa_stretch_sprite(BITMAP *_dst, BITMAP *_src, int _dx, int _dy, int _dw, int _dh) { + _aa_stretch_blit(_src, _dst, 0, 0, _src->w, _src->h, _dx, _dy, _dw, _dh, 1); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/aastr-0.1.1/aastr.h b/engines/ags/lib/aastr-0.1.1/aastr.h new file mode 100644 index 000000000000..3a85ca1a7350 --- /dev/null +++ b/engines/ags/lib/aastr-0.1.1/aastr.h @@ -0,0 +1,74 @@ +/* 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. + * + */ + +/* + * aastr.h --- anti-aliased stretching and rotation for Allegro + * + * This file is gift-ware. This file is given to you freely + * as a gift. You may use, modify, redistribute, and generally hack + * it about in any way you like, and you do not have to give anyone + * anything in return. + * + * I do not accept any responsibility for any effects, adverse or + * otherwise, that this code may have on just about anything that + * you can think of. Use it at your own risk. + * + * Copyright (C) 1998, 1999 Michael Bukin + */ + +#ifndef AGS_LIB_AASTR_AASTR_H +#define AGS_LIB_AASTR_AASTR_H + +#include "ags/stubs/allegro.h" + +namespace AGS3 { + +#ifdef __cplusplus +extern "C" { +#endif + +/* Stretching. */ +void aa_stretch_blit(BITMAP *src, BITMAP *dst, + int sx, int sy, int sw, int sh, + int dx, int dy, int dw, int dh); +void aa_stretch_sprite(BITMAP *dst, BITMAP *src, + int dx, int dy, int dw, int dh); + +/* Rotation. */ +void aa_rotate_scaled_bitmap(BITMAP *src, BITMAP *dst, + int x, int y, fixed angle, + fixed scalex, fixed scaley); +void aa_rotate_scaled_sprite(BITMAP *dst, BITMAP *src, + int x, int y, fixed angle, + fixed scalex, fixed scaley); +void aa_rotate_bitmap(BITMAP *src, BITMAP *dst, + int x, int y, fixed angle); +void aa_rotate_sprite(BITMAP *dst, BITMAP *src, + int x, int y, fixed angle); + +#ifdef __cplusplus +} +#endif + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/aastr-0.1.1/aautil.cpp b/engines/ags/lib/aastr-0.1.1/aautil.cpp new file mode 100644 index 000000000000..25b789c36ffd --- /dev/null +++ b/engines/ags/lib/aastr-0.1.1/aautil.cpp @@ -0,0 +1,1836 @@ +/* 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. + * + */ + +/* + * aautil.c --- helpers for anti-aliasing routines for Allegro + * + * This file is gift-ware. This file is given to you freely + * as a gift. You may use, modify, redistribute, and generally hack + * it about in any way you like, and you do not have to give anyone + * anything in return. + * + * I do not accept any responsibility for any effects, adverse or + * otherwise, that this code may have on just about anything that + * you can think of. Use it at your own risk. + * + * Copyright (C) 1998, 1999 Michael Bukin + */ + +#include "ags/lib/aastr-0.1.1/aautil.h" + +namespace AGS3 { + +/* Multiply b by a (0 <= a <= aa_SIZE). */ +#define MUL(a, b) ((b) * (a)) + +static struct +{ + int transparent; + unsigned int r; + unsigned int g; + unsigned int b; + int roffset24; + int goffset24; + int boffset24; +} _aa; + +/* + * Prepare offsets for direct access to 24bpp bitmap. + */ +void +_aa_prepare_for_24bpp (void) +{ + _aa.roffset24 = _rgb_r_shift_24 / 8; + _aa.goffset24 = _rgb_g_shift_24 / 8; + _aa.boffset24 = _rgb_b_shift_24 / 8; +} + +/* + * Add r, g, b values of pixels. + */ +void +_aa_add_rgb8 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned char *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1; + unsigned int r2, g2, b2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = _src->line[sy] + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + r1 = MUL (getr8 (scolor), sx1f); + g1 = MUL (getg8 (scolor), sx1f); + b1 = MUL (getb8 (scolor), sx1f); + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r1 += getr8 (scolor) << aa_BITS; + g1 += getg8 (scolor) << aa_BITS; + b1 += getb8 (scolor) << aa_BITS; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + r1 += MUL (getr8 (scolor), sx2f); + g1 += MUL (getg8 (scolor), sx2f); + b1 += MUL (getb8 (scolor), sx2f); + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = 0; + do + { + sx = sx1i; + sline = _src->line[sy] + sx; + + scolor = *sline; + r2 += MUL (getr8 (scolor), sx1f); + g2 += MUL (getg8 (scolor), sx1f); + b2 += MUL (getb8 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr8 (scolor) << aa_BITS; + g2 += getg8 (scolor) << aa_BITS; + b2 += getb8 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr8 (scolor), sx2f); + g2 += MUL (getg8 (scolor), sx2f); + b2 += MUL (getb8 (scolor), sx2f); + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = _src->line[sy] + sx; + + scolor = *sline; + r2 = MUL (getr8 (scolor), sx1f); + g2 = MUL (getg8 (scolor), sx1f); + b2 = MUL (getb8 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr8 (scolor) << aa_BITS; + g2 += getg8 (scolor) << aa_BITS; + b2 += getb8 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr8 (scolor), sx2f); + g2 += MUL (getg8 (scolor), sx2f); + b2 += MUL (getb8 (scolor), sx2f); + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + } + + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } +} +#ifdef ALLEGRO_COLOR16 +void +_aa_add_rgb15 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned short *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1; + unsigned int r2, g2, b2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + r1 = MUL (getr15 (scolor), sx1f); + g1 = MUL (getg15 (scolor), sx1f); + b1 = MUL (getb15 (scolor), sx1f); + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r1 += getr15 (scolor) << aa_BITS; + g1 += getg15 (scolor) << aa_BITS; + b1 += getb15 (scolor) << aa_BITS; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + r1 += MUL (getr15 (scolor), sx2f); + g1 += MUL (getg15 (scolor), sx2f); + b1 += MUL (getb15 (scolor), sx2f); + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = 0; + do + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + r2 += MUL (getr15 (scolor), sx1f); + g2 += MUL (getg15 (scolor), sx1f); + b2 += MUL (getb15 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr15 (scolor) << aa_BITS; + g2 += getg15 (scolor) << aa_BITS; + b2 += getb15 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr15 (scolor), sx2f); + g2 += MUL (getg15 (scolor), sx2f); + b2 += MUL (getb15 (scolor), sx2f); + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + r2 = MUL (getr15 (scolor), sx1f); + g2 = MUL (getg15 (scolor), sx1f); + b2 = MUL (getb15 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr15 (scolor) << aa_BITS; + g2 += getg15 (scolor) << aa_BITS; + b2 += getb15 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr15 (scolor), sx2f); + g2 += MUL (getg15 (scolor), sx2f); + b2 += MUL (getb15 (scolor), sx2f); + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + } + + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } +} +void +_aa_add_rgb16 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned short *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1; + unsigned int r2, g2, b2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + r1 = MUL (getr16 (scolor), sx1f); + g1 = MUL (getg16 (scolor), sx1f); + b1 = MUL (getb16 (scolor), sx1f); + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r1 += getr16 (scolor) << aa_BITS; + g1 += getg16 (scolor) << aa_BITS; + b1 += getb16 (scolor) << aa_BITS; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + r1 += MUL (getr16 (scolor), sx2f); + g1 += MUL (getg16 (scolor), sx2f); + b1 += MUL (getb16 (scolor), sx2f); + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = 0; + do + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + r2 += MUL (getr16 (scolor), sx1f); + g2 += MUL (getg16 (scolor), sx1f); + b2 += MUL (getb16 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr16 (scolor) << aa_BITS; + g2 += getg16 (scolor) << aa_BITS; + b2 += getb16 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr16 (scolor), sx2f); + g2 += MUL (getg16 (scolor), sx2f); + b2 += MUL (getb16 (scolor), sx2f); + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + r2 = MUL (getr16 (scolor), sx1f); + g2 = MUL (getg16 (scolor), sx1f); + b2 = MUL (getb16 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr16 (scolor) << aa_BITS; + g2 += getg16 (scolor) << aa_BITS; + b2 += getb16 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr16 (scolor), sx2f); + g2 += MUL (getg16 (scolor), sx2f); + b2 += MUL (getb16 (scolor), sx2f); + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + } + + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } +} +#endif +#ifdef ALLEGRO_COLOR24 +void +_aa_add_rgb24 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned char *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1; + unsigned int r2, g2, b2; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = _src->line[sy] + sx * 3; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + r1 = MUL (sline[_aa.roffset24], sx1f); + g1 = MUL (sline[_aa.goffset24], sx1f); + b1 = MUL (sline[_aa.boffset24], sx1f); + + sx2i = _sx2 >> aa_BITS; + for (sline += 3, sx++; sx < sx2i; sline += 3, sx++) + { + r1 += sline[_aa.roffset24] << aa_BITS; + g1 += sline[_aa.goffset24] << aa_BITS; + b1 += sline[_aa.boffset24] << aa_BITS; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + r1 += MUL (sline[_aa.roffset24], sx2f); + g1 += MUL (sline[_aa.goffset24], sx2f); + b1 += MUL (sline[_aa.boffset24], sx2f); + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = 0; + do + { + sx = sx1i; + sline = _src->line[sy] + sx * 3; + + r2 += MUL (sline[_aa.roffset24], sx1f); + g2 += MUL (sline[_aa.goffset24], sx1f); + b2 += MUL (sline[_aa.boffset24], sx1f); + + for (sline += 3, sx++; sx < sx2i; sline += 3, sx++) + { + r2 += sline[_aa.roffset24] << aa_BITS; + g2 += sline[_aa.goffset24] << aa_BITS; + b2 += sline[_aa.boffset24] << aa_BITS; + } + + if (sx2f != 0) + { + r2 += MUL (sline[_aa.roffset24], sx2f); + g2 += MUL (sline[_aa.goffset24], sx2f); + b2 += MUL (sline[_aa.boffset24], sx2f); + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = _src->line[sy] + sx * 3; + + r2 = MUL (sline[_aa.roffset24], sx1f); + g2 = MUL (sline[_aa.goffset24], sx1f); + b2 = MUL (sline[_aa.boffset24], sx1f); + + for (sline += 3, sx++; sx < sx2i; sline += 3, sx++) + { + r2 += sline[_aa.roffset24] << aa_BITS; + g2 += sline[_aa.goffset24] << aa_BITS; + b2 += sline[_aa.boffset24] << aa_BITS; + } + + if (sx2f != 0) + { + r2 += MUL (sline[_aa.roffset24], sx2f); + g2 += MUL (sline[_aa.goffset24], sx2f); + b2 += MUL (sline[_aa.boffset24], sx2f); + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + } + + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } +} +#endif +#ifdef ALLEGRO_COLOR32 +void +_aa_add_rgb32 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned int *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1; + unsigned int r2, g2, b2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = (unsigned int*) (_src->line[sy]) + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + r1 = MUL (getr32 (scolor), sx1f); + g1 = MUL (getg32 (scolor), sx1f); + b1 = MUL (getb32 (scolor), sx1f); + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r1 += getr32 (scolor) << aa_BITS; + g1 += getg32 (scolor) << aa_BITS; + b1 += getb32 (scolor) << aa_BITS; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + r1 += MUL (getr32 (scolor), sx2f); + g1 += MUL (getg32 (scolor), sx2f); + b1 += MUL (getb32 (scolor), sx2f); + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = 0; + do + { + sx = sx1i; + sline = (unsigned int*) (_src->line[sy]) + sx; + + scolor = *sline; + r2 += MUL (getr32 (scolor), sx1f); + g2 += MUL (getg32 (scolor), sx1f); + b2 += MUL (getb32 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr32 (scolor) << aa_BITS; + g2 += getg32 (scolor) << aa_BITS; + b2 += getb32 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr32 (scolor), sx2f); + g2 += MUL (getg32 (scolor), sx2f); + b2 += MUL (getb32 (scolor), sx2f); + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = (unsigned int*) (_src->line[sy]) + sx; + + scolor = *sline; + r2 = MUL (getr32 (scolor), sx1f); + g2 = MUL (getg32 (scolor), sx1f); + b2 = MUL (getb32 (scolor), sx1f); + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + r2 += getr32 (scolor) << aa_BITS; + g2 += getg32 (scolor) << aa_BITS; + b2 += getb32 (scolor) << aa_BITS; + } + + if (sx2f != 0) + { + scolor = *sline; + r2 += MUL (getr32 (scolor), sx2f); + g2 += MUL (getg32 (scolor), sx2f); + b2 += MUL (getb32 (scolor), sx2f); + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + } + + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } +} +#endif + +/* + * Putting pixel to destination bitmap. + */ +void +_aa_put_rgb8 (unsigned long _addr, int _x) +{ + bmp_write8 (_addr + _x, makecol8 (_aa.r, _aa.g, _aa.b)); +} +#ifdef ALLEGRO_COLOR16 +void +_aa_put_rgb15 (unsigned long _addr, int _x) +{ + bmp_write15 (_addr + sizeof (short) * _x, makecol15 (_aa.r, _aa.g, _aa.b)); +} +void +_aa_put_rgb16 (unsigned long _addr, int _x) +{ + bmp_write16 (_addr + sizeof (short) * _x, makecol16 (_aa.r, _aa.g, _aa.b)); +} +#endif +#ifdef ALLEGRO_COLOR24 +void +_aa_put_rgb24 (unsigned long _addr, int _x) +{ + bmp_write24 (_addr + 3 * _x, makecol24 (_aa.r, _aa.g, _aa.g)); +} +#endif +#ifdef ALLEGRO_COLOR32 +void +_aa_put_rgb32 (unsigned long _addr, int _x) +{ + bmp_write32 (_addr + sizeof (int) * _x, makecol32 (_aa.r, _aa.g, _aa.b)); +} +#endif + +/* + * Add masked r, g, b values of pixels. + */ +void +_aa_masked_add_rgb8 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned char *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned long r1, g1, b1, t1; + unsigned long r2, g2, b2, t2; + unsigned long scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = _src->line[sy] + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r1 = MUL (getr8 (scolor), sx1f); + g1 = MUL (getg8 (scolor), sx1f); + b1 = MUL (getb8 (scolor), sx1f); + t1 = 0; + } + else + { + r1 = g1 = b1 = 0; + t1 = sx1f; + } + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r1 += getr8 (scolor) << aa_BITS; + g1 += getg8 (scolor) << aa_BITS; + b1 += getb8 (scolor) << aa_BITS; + } + else + t1 += aa_SIZE; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r1 += MUL (getr8 (scolor), sx2f); + g1 += MUL (getg8 (scolor), sx2f); + b1 += MUL (getb8 (scolor), sx2f); + } + else + t1 += sx2f; + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + t1 = MUL (t1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = t2 = 0; + do + { + sx = sx1i; + sline = _src->line[sy] + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r2 += MUL (getr8 (scolor), sx1f); + g2 += MUL (getg8 (scolor), sx1f); + b2 += MUL (getb8 (scolor), sx1f); + } + else + t2 += sx1f; + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r2 += getr8 (scolor) << aa_BITS; + g2 += getg8 (scolor) << aa_BITS; + b2 += getb8 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r2 += MUL (getr8 (scolor), sx2f); + g2 += MUL (getg8 (scolor), sx2f); + b2 += MUL (getb8 (scolor), sx2f); + } + else + t2 += sx2f; + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + t1 += t2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = _src->line[sy] + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r2 = MUL (getr8 (scolor), sx1f); + g2 = MUL (getg8 (scolor), sx1f); + b2 = MUL (getb8 (scolor), sx1f); + t2 = 0; + } + else + { + r2 = g2 = b2 = 0; + t2 = sx1f; + } + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r2 += getr8 (scolor) << aa_BITS; + g2 += getg8 (scolor) << aa_BITS; + b2 += getb8 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_8) + { + r2 += MUL (getr8 (scolor), sx2f); + g2 += MUL (getg8 (scolor), sx2f); + b2 += MUL (getb8 (scolor), sx2f); + } + else + t2 += sx2f; + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + t1 += MUL (t2, sy2f); + } + + if (_num >= (2 * t1)) + { + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } + _aa.transparent = 0; + } + else + _aa.transparent = 1; +} +#ifdef ALLEGRO_COLOR16 +void +_aa_masked_add_rgb15 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned short *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1, t1; + unsigned int r2, g2, b2, t2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r1 = MUL (getr15 (scolor), sx1f); + g1 = MUL (getg15 (scolor), sx1f); + b1 = MUL (getb15 (scolor), sx1f); + t1 = 0; + } + else + { + r1 = g1 = b1 = 0; + t1 = sx1f; + } + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r1 += getr15 (scolor) << aa_BITS; + g1 += getg15 (scolor) << aa_BITS; + b1 += getb15 (scolor) << aa_BITS; + } + else + t1 += aa_SIZE; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r1 += MUL (getr15 (scolor), sx2f); + g1 += MUL (getg15 (scolor), sx2f); + b1 += MUL (getb15 (scolor), sx2f); + } + else + t1 += sx2f; + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + t1 = MUL (t1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = t2 = 0; + do + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r2 += MUL (getr15 (scolor), sx1f); + g2 += MUL (getg15 (scolor), sx1f); + b2 += MUL (getb15 (scolor), sx1f); + } + else + t2 += sx1f; + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r2 += getr15 (scolor) << aa_BITS; + g2 += getg15 (scolor) << aa_BITS; + b2 += getb15 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r2 += MUL (getr15 (scolor), sx2f); + g2 += MUL (getg15 (scolor), sx2f); + b2 += MUL (getb15 (scolor), sx2f); + } + else + t2 += sx2f; + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + t1 += t2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r2 = MUL (getr15 (scolor), sx1f); + g2 = MUL (getg15 (scolor), sx1f); + b2 = MUL (getb15 (scolor), sx1f); + t2 = 0; + } + else + { + r2 = g2 = b2 = 0; + t2 = sx1f; + } + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r2 += getr15 (scolor) << aa_BITS; + g2 += getg15 (scolor) << aa_BITS; + b2 += getb15 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_15) + { + r2 += MUL (getr15 (scolor), sx2f); + g2 += MUL (getg15 (scolor), sx2f); + b2 += MUL (getb15 (scolor), sx2f); + } + else + t2 += sx2f; + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + t1 += MUL (t2, sy2f); + } + + if (_num >= (2 * t1)) + { + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } + _aa.transparent = 0; + } + else + _aa.transparent = 1; +} +void +_aa_masked_add_rgb16 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned short *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1, t1; + unsigned int r2, g2, b2, t2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r1 = MUL (getr16 (scolor), sx1f); + g1 = MUL (getg16 (scolor), sx1f); + b1 = MUL (getb16 (scolor), sx1f); + t1 = 0; + } + else + { + r1 = g1 = b1 = 0; + t1 = sx1f; + } + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r1 += getr16 (scolor) << aa_BITS; + g1 += getg16 (scolor) << aa_BITS; + b1 += getb16 (scolor) << aa_BITS; + } + else + t1 += aa_SIZE; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r1 += MUL (getr16 (scolor), sx2f); + g1 += MUL (getg16 (scolor), sx2f); + b1 += MUL (getb16 (scolor), sx2f); + } + else + t1 += sx2f; + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + t1 = MUL (t1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = t2 = 0; + do + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r2 += MUL (getr16 (scolor), sx1f); + g2 += MUL (getg16 (scolor), sx1f); + b2 += MUL (getb16 (scolor), sx1f); + } + else + t2 += sx1f; + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r2 += getr16 (scolor) << aa_BITS; + g2 += getg16 (scolor) << aa_BITS; + b2 += getb16 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r2 += MUL (getr16 (scolor), sx2f); + g2 += MUL (getg16 (scolor), sx2f); + b2 += MUL (getb16 (scolor), sx2f); + } + else + t2 += sx2f; + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + t1 += t2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = (unsigned short*) (_src->line[sy]) + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r2 = MUL (getr16 (scolor), sx1f); + g2 = MUL (getg16 (scolor), sx1f); + b2 = MUL (getb16 (scolor), sx1f); + t2 = 0; + } + else + { + r2 = g2 = b2 = 0; + t2 = sx1f; + } + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r2 += getr16 (scolor) << aa_BITS; + g2 += getg16 (scolor) << aa_BITS; + b2 += getb16 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_16) + { + r2 += MUL (getr16 (scolor), sx2f); + g2 += MUL (getg16 (scolor), sx2f); + b2 += MUL (getb16 (scolor), sx2f); + } + else + t2 += sx2f; + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + t1 += MUL (t2, sy2f); + } + + if (_num >= (2 * t1)) + { + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } + _aa.transparent = 0; + } + else + _aa.transparent = 1; +} +#endif +#ifdef ALLEGRO_COLOR24 +void +_aa_masked_add_rgb24 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned char *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1, t1; + unsigned int r2, g2, b2, t2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = _src->line[sy] + sx * 3; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r1 = MUL (getr24 (scolor), sx1f); + g1 = MUL (getg24 (scolor), sx1f); + b1 = MUL (getb24 (scolor), sx1f); + t1 = 0; + } + else + { + r1 = g1 = b1 = 0; + t1 = sx1f; + } + + sx2i = _sx2 >> aa_BITS; + for (sline += 3, sx++; sx < sx2i; sline += 3, sx++) + { +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r1 += getr24 (scolor) << aa_BITS; + g1 += getg24 (scolor) << aa_BITS; + b1 += getb24 (scolor) << aa_BITS; + } + else + t1 += aa_SIZE; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r1 += MUL (getr24 (scolor), sx2f); + g1 += MUL (getg24 (scolor), sx2f); + b1 += MUL (getb24 (scolor), sx2f); + } + else + t1 += sx2f; + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + t1 = MUL (t1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = t2 = 0; + do + { + sx = sx1i; + sline = _src->line[sy] + sx * 3; + +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r2 += MUL (getr24 (scolor), sx1f); + g2 += MUL (getg24 (scolor), sx1f); + b2 += MUL (getb24 (scolor), sx1f); + } + else + t2 += sx1f; + + for (sline += 3, sx++; sx < sx2i; sline += 3, sx++) + { +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r2 += getr24 (scolor) << aa_BITS; + g2 += getg24 (scolor) << aa_BITS; + b2 += getb24 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r2 += MUL (getr24 (scolor), sx2f); + g2 += MUL (getg24 (scolor), sx2f); + b2 += MUL (getb24 (scolor), sx2f); + } + else + t2 += sx2f; + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + t1 += t2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = _src->line[sy] + sx * 3; + +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r2 = MUL (getr24 (scolor), sx1f); + g2 = MUL (getg24 (scolor), sx1f); + b2 = MUL (getb24 (scolor), sx1f); + t2 = 0; + } + else + { + r2 = g2 = b2 = 0; + t2 = sx1f; + } + + for (sline += 3, sx++; sx < sx2i; sline += 3, sx++) + { +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r2 += getr24 (scolor) << aa_BITS; + g2 += getg24 (scolor) << aa_BITS; + b2 += getb24 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { +#ifdef USE_24BIT_AS_CHARS + scolor = ((unsigned int) (sline[0]) + | ((unsigned int) (sline[1]) << 8) + | ((unsigned int) (sline[2]) << 16)); +#else + scolor = ((unsigned int) (((unsigned short*) sline)[0]) + | ((unsigned int) (sline[2]) << 16)); +#endif + if (scolor != MASK_COLOR_24) + { + r2 += MUL (getr24 (scolor), sx2f); + g2 += MUL (getg24 (scolor), sx2f); + b2 += MUL (getb24 (scolor), sx2f); + } + else + t2 += sx2f; + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + t1 += MUL (t2, sy2f); + } + + if (_num >= (2 * t1)) + { + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } + _aa.transparent = 0; + } + else + _aa.transparent = 1; +} +#endif +#ifdef ALLEGRO_COLOR32 +void +_aa_masked_add_rgb32 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) +{ + unsigned int *sline; + int sx, sx1i, sx1f, sx2i, sx2f; + int sy, sy1i, sy1f, sy2i, sy2f; + unsigned int r1, g1, b1, t1; + unsigned int r2, g2, b2, t2; + unsigned int scolor; + + sy1i = _sy1 >> aa_BITS; + sy = sy1i; + + /* First line. */ + sx1i = _sx1 >> aa_BITS; + sx = sx1i; + sline = (unsigned int*) (_src->line[sy]) + sx; + + sx1f = aa_SIZE - (_sx1 & aa_MASK); + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r1 = MUL (getr32 (scolor), sx1f); + g1 = MUL (getg32 (scolor), sx1f); + b1 = MUL (getb32 (scolor), sx1f); + t1 = 0; + } + else + { + r1 = g1 = b1 = 0; + t1 = sx1f; + } + + sx2i = _sx2 >> aa_BITS; + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r1 += getr32 (scolor) << aa_BITS; + g1 += getg32 (scolor) << aa_BITS; + b1 += getb32 (scolor) << aa_BITS; + } + else + t1 += aa_SIZE; + } + + sx2f = _sx2 & aa_MASK; + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r1 += MUL (getr32 (scolor), sx2f); + g1 += MUL (getg32 (scolor), sx2f); + b1 += MUL (getb32 (scolor), sx2f); + } + else + t1 += sx2f; + } + + sy1f = aa_SIZE - (_sy1 & aa_MASK); + r1 = MUL (r1, sy1f); + g1 = MUL (g1, sy1f); + b1 = MUL (b1, sy1f); + t1 = MUL (t1, sy1f); + + /* Middle lines. */ + sy2i = _sy2 >> aa_BITS; + if (++sy < sy2i) + { + r2 = g2 = b2 = t2 = 0; + do + { + sx = sx1i; + sline = (unsigned int*) (_src->line[sy]) + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r2 += MUL (getr32 (scolor), sx1f); + g2 += MUL (getg32 (scolor), sx1f); + b2 += MUL (getb32 (scolor), sx1f); + } + else + t2 += sx1f; + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r2 += getr32 (scolor) << aa_BITS; + g2 += getg32 (scolor) << aa_BITS; + b2 += getb32 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r2 += MUL (getr32 (scolor), sx2f); + g2 += MUL (getg32 (scolor), sx2f); + b2 += MUL (getb32 (scolor), sx2f); + } + else + t2 += sx2f; + } + } + while (++sy < sy2i); + + r1 += r2 << aa_BITS; + g1 += g2 << aa_BITS; + b1 += b2 << aa_BITS; + t1 += t2 << aa_BITS; + } + + /* Last line. */ + sy2f = _sy2 & aa_MASK; + if (sy2f != 0) + { + sx = sx1i; + sline = (unsigned int*) (_src->line[sy]) + sx; + + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r2 = MUL (getr32 (scolor), sx1f); + g2 = MUL (getg32 (scolor), sx1f); + b2 = MUL (getb32 (scolor), sx1f); + t2 = 0; + } + else + { + r2 = g2 = b2 = 0; + t2 = sx1f; + } + + for (sline++, sx++; sx < sx2i; sline++, sx++) + { + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r2 += getr32 (scolor) << aa_BITS; + g2 += getg32 (scolor) << aa_BITS; + b2 += getb32 (scolor) << aa_BITS; + } + else + t2 += aa_SIZE; + } + + if (sx2f != 0) + { + scolor = *sline; + if (scolor != MASK_COLOR_32) + { + r2 += MUL (getr32 (scolor), sx2f); + g2 += MUL (getg32 (scolor), sx2f); + b2 += MUL (getb32 (scolor), sx2f); + } + else + t2 += sx2f; + } + + r1 += MUL (r2, sy2f); + g1 += MUL (g2, sy2f); + b1 += MUL (b2, sy2f); + t1 += MUL (t2, sy2f); + } + + if (_num >= (2 * t1)) + { + if (_num == (aa_SIZE * aa_SIZE)) + { + _aa.r = r1 >> (2 * aa_BITS); + _aa.g = g1 >> (2 * aa_BITS); + _aa.b = b1 >> (2 * aa_BITS); + } + else + { + _aa.r = r1 / _num; + _aa.g = g1 / _num; + _aa.b = b1 / _num; + } + _aa.transparent = 0; + } + else + _aa.transparent = 1; +} +#endif + +/* + * Putting pixel to destination bitmap. + */ +void +_aa_masked_put_rgb8 (unsigned long _addr, int _x) +{ + if (!_aa.transparent) + bmp_write8 (_addr + _x, makecol8 (_aa.r, _aa.g, _aa.b)); +} +#ifdef ALLEGRO_COLOR16 +void +_aa_masked_put_rgb15 (unsigned long _addr, int _x) +{ + if (!_aa.transparent) + bmp_write15 (_addr + sizeof (short) * _x, makecol15 (_aa.r, _aa.g, _aa.b)); +} +void +_aa_masked_put_rgb16 (unsigned long _addr, int _x) +{ + if (!_aa.transparent) + bmp_write16 (_addr + sizeof (short) * _x, makecol16 (_aa.r, _aa.g, _aa.b)); +} +#endif +#ifdef ALLEGRO_COLOR24 +void +_aa_masked_put_rgb24 (unsigned long _addr, int _x) +{ + if (!_aa.transparent) + bmp_write24 (_addr + 3 * _x, makecol24 (_aa.r, _aa.g, _aa.b)); +} +#endif +#ifdef ALLEGRO_COLOR32 +void +_aa_masked_put_rgb32 (unsigned long _addr, int _x) +{ + if (!_aa.transparent) + bmp_write32 (_addr + sizeof (int) * _x, makecol32 (_aa.r, _aa.g, _aa.b)); +} + +#endif + +} // namespace AGS3 diff --git a/engines/ags/lib/aastr-0.1.1/aautil.h b/engines/ags/lib/aastr-0.1.1/aautil.h new file mode 100644 index 000000000000..81b1f97fec05 --- /dev/null +++ b/engines/ags/lib/aastr-0.1.1/aautil.h @@ -0,0 +1,166 @@ +/* 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. + * + */ + +/* + * aautil.h --- helpers for anti-aliasing routines for Allegro + * + * This file is gift-ware. This file is given to you freely + * as a gift. You may use, modify, redistribute, and generally hack + * it about in any way you like, and you do not have to give anyone + * anything in return. + * + * I do not accept any responsibility for any effects, adverse or + * otherwise, that this code may have on just about anything that + * you can think of. Use it at your own risk. + * + * Copyright (C) 1998, 1999 Michael Bukin + */ + +#ifndef AGS_LIB_AASTR_AAUTIL_H +#define AGS_LIB_AASTR_AAUTIL_H + +#include "ags/stubs/allegro.h" + +namespace AGS3 { + +/* + * Change aa_BITS, and never aa_SIZE or aa_MASK. + * 8 or 4 are probably the fastest for i386+. + * Recompile the package after changing aa_BITS. + */ +#ifdef aa_BITS +#undef aa_BITS +#endif +#define aa_BITS 8 + +#if ((aa_BITS < 0) || (aa_BITS > 12)) +#error aa_BITS must be (0 <= aa_BITS <= 12) +#endif + +#define aa_SIZE (1UL << aa_BITS) +#define aa_MASK (aa_SIZE - 1) + +#define aa_MAX_SIZE (1UL << 12) +#define aa_MAX_NUM (aa_MAX_SIZE * aa_MAX_SIZE) + + + /* Prepare Bresenham line parameters. */ +#define aa_PREPARE(inc,dd,i1,i2,_yw,_xw) \ +{ \ + int xw = (_xw); \ + int yw = (_yw); \ + \ + if ((xw == 0) || ((yw < xw) && (yw > -xw))) { \ + (inc) = 0; \ + } \ + else { \ + (inc) = yw / xw; \ + yw %= xw; \ + } \ + if (yw < 0) { \ + (inc) -= 1; \ + yw += xw; \ + } \ + (i2) = ((dd) = ((i1) = 2 * yw) - xw) - xw; \ +} + +/* Advance to the next point. */ +#define aa_ADVANCE(y,inc,dd,i1,i2) \ +{ \ + if ((dd) >= 0) \ + (y) += (inc) + 1, (dd) += (i2); \ + else \ + (y) += (inc), (dd) += (i1); \ +} + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Prepare offsets for direct access to 24bpp bitmap. */ + void _aa_prepare_for_24bpp(void); + + /* Add r,g,b values from source bitmap. */ + void _aa_add_rgb8(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); +#ifdef ALLEGRO_COLOR16 + void _aa_add_rgb15(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); + void _aa_add_rgb16(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); +#endif +#ifdef ALLEGRO_COLOR24 + void _aa_add_rgb24(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); +#endif +#ifdef ALLEGRO_COLOR32 + void _aa_add_rgb32(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); +#endif + + /* Put pixel to destination bitmap. */ + void _aa_put_rgb8(unsigned long _addr, int _x); +#ifdef ALLEGRO_COLOR16 + void _aa_put_rgb15(unsigned long _addr, int _x); + void _aa_put_rgb16(unsigned long _addr, int _x); +#endif +#ifdef ALLEGRO_COLOR24 + void _aa_put_rgb24(unsigned long _addr, int _x); +#endif +#ifdef ALLEGRO_COLOR32 + void _aa_put_rgb32(unsigned long _addr, int _x); +#endif + + /* Add r,g,b and transparency values from source bitmap. */ + void _aa_masked_add_rgb8(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, + unsigned long _num); +#ifdef ALLEGRO_COLOR16 + void _aa_masked_add_rgb15(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, + unsigned long _num); + void _aa_masked_add_rgb16(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, + unsigned long _num); +#endif +#ifdef ALLEGRO_COLOR24 + void _aa_masked_add_rgb24(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, + unsigned long _num); +#endif +#ifdef ALLEGRO_COLOR32 + void _aa_masked_add_rgb32(BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, + unsigned long _num); +#endif + + /* Put masked pixel to destination bitmap. */ + void _aa_masked_put_rgb8(unsigned long _addr, int _x); +#ifdef ALLEGRO_COLOR16 + void _aa_masked_put_rgb15(unsigned long _addr, int _x); + void _aa_masked_put_rgb16(unsigned long _addr, int _x); +#endif +#ifdef ALLEGRO_COLOR24 + void _aa_masked_put_rgb24(unsigned long _addr, int _x); +#endif +#ifdef ALLEGRO_COLOR32 + void _aa_masked_put_rgb32(unsigned long _addr, int _x); +#endif + +#ifdef __cplusplus +} +#endif + +} // namespace AGS3 + +#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 6a5a42c6c742..148852c3cd1e 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -3,6 +3,9 @@ MODULE := engines/ags MODULE_OBJS = \ ags.o \ metaengine.o \ + lib/aastr-0.1.1/aarot.o \ + lib/aastr-0.1.1/aastr.o \ + lib/aastr-0.1.1/aautil.o \ stubs/allegro.o \ stubs/allegro/color.o \ stubs/allegro/config.o \ @@ -17,6 +20,9 @@ MODULE_OBJS = \ stubs/allegro/sound.o \ stubs/allegro/system.o \ stubs/allegro/unicode.o \ + shared/gfx/allegrobitmap.o \ + shared/gfx/bitmap.o \ + shared/gfx/image.o \ shared/gui/guibutton.o \ shared/gui/guiinv.o \ shared/gui/guilabel.o \ diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index 9a9669f2cb47..7370da5934bf 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -71,7 +71,7 @@ typedef int64 int64_t; typedef int64 soff_t; #define fixed_t int32_t // fixed point type -#define color_t int32_t +#define color_t int #undef INT32_MIN #undef INT32_MAX diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index 42ed2dfa77ac..cb471b43e7f2 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -20,13 +20,14 @@ * */ -//include #include "ags/shared/gfx/allegrobitmap.h" +#include "ags/shared/gfx/image.h" #include "ags/shared/debugging/assert.h" +#include "ags/lib/aastr-0.1.1/aastr.h" namespace AGS3 { -extern void __my_setcolor(int *ctset, int newcol, int wantColDep); +extern void __my_setcolor(color_t *ctset, color_t newcol, int wantColDep); namespace AGS { namespace Shared { diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 195bc85d4310..f59f346daedb 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -125,12 +125,12 @@ class Bitmap { // Gets a pointer to underlying graphic data // FIXME: actually not a very good idea, since there's no 100% guarantee the scanline positions in memory are sequential inline const unsigned char *GetData() const { - return (unsigned char *)_alBitmap->getPixels(); + return _alBitmap->getPixels(); } // Get scanline for direct reading inline const unsigned char *GetScanLine(int index) const { - return (index >= 0 && index < GetHeight()) ? (unsigned char *)_alBitmap->getBasePtr(0, index) : nullptr; + return (index >= 0 && index < GetHeight()) ? _alBitmap->getBasePtr(0, index) : nullptr; } void SetMaskColor(color_t color); @@ -212,10 +212,10 @@ class Bitmap { // TODO: think how to increase safety over this (some fixed memory buffer class with iterator?) // Gets scanline for directly writing into it inline unsigned char *GetScanLineForWriting(int index) { - return (index >= 0 && index < GetHeight()) ? (unsigned char *)_alBitmap->getBasePtr(0, index) : nullptr; + return (index >= 0 && index < GetHeight()) ? _alBitmap->getBasePtr(0, index) : nullptr; } inline unsigned char *GetDataForWriting() { - return (unsigned char *)_alBitmap->getPixels(); + return _alBitmap->getPixels(); } // Copies buffer contents into scanline void SetScanLine(int index, unsigned char *data, int data_size = -1); diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp index 9c6f311de609..01ee210b600c 100644 --- a/engines/ags/shared/gfx/bitmap.cpp +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -117,7 +117,7 @@ struct PixelTransCpy24 { struct PixelTransCpy32 { static const size_t BPP = 4; inline void operator()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const { - if (*(const uint32_t *)src == mask_color) + if (*(const uint32_t *)src == (uint32_t)mask_color) *(uint32_t *)dst = mask_color; else if (use_alpha) dst[3] = src[3]; // copy alpha channel @@ -128,7 +128,7 @@ struct PixelTransCpy32 { struct PixelTransSkip32 { inline bool operator()(uint8_t *data, color_t mask_color, bool use_alpha) const { - return *(uint32_t *)data == mask_color || (use_alpha && data[3] == 0); + return *(uint32_t *)data == (uint32_t)mask_color || (use_alpha && data[3] == 0); } }; diff --git a/engines/ags/shared/gfx/image.cpp b/engines/ags/shared/gfx/image.cpp new file mode 100644 index 000000000000..b77e08286ced --- /dev/null +++ b/engines/ags/shared/gfx/image.cpp @@ -0,0 +1,77 @@ +/* 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 "ags/shared/gfx/image.h" +#include "ags/stubs/allegro.h" +#include "common/str.h" +#include "common/textconsole.h" + +namespace AGS3 { + +BITMAP *load_bmp_pf(PACKFILE *f, color *pal) { + error("TODO: load_bmp_pf"); +} + +BITMAP *load_pcx_pf(PACKFILE *f, color *pal) { + error("TODO: load_pcx_pf"); +} + +BITMAP *load_tga_pf(PACKFILE *f, color *pal) { + error("TODO: load_tga_pf"); +} + +BITMAP *load_bmp(const char *filename, color *pal) { + error("TODO: load_bmp"); +} + +BITMAP *load_lbm(const char *filename, color *pal) { + error("TODO: load_lbm"); +} + +BITMAP *load_pcx(const char *filename, color *pal) { + error("TODO: load_pcx"); +} + +BITMAP *load_tga(const char *filename, color *pal) { + error("TODO: load_tga"); +} + +BITMAP *load_bitmap(const char *filename, color *pal) { + Common::String fname(filename); + + if (fname.hasSuffixIgnoreCase(".bmp")) + return load_bmp(filename, pal); + else if (fname.hasSuffixIgnoreCase(".lbm")) + return load_lbm(filename, pal); + else if (fname.hasSuffixIgnoreCase(".pcx")) + return load_pcx(filename, pal); + else if (fname.hasSuffixIgnoreCase(".tga")) + return load_tga(filename, pal); + else + error("Unknown image file - %s", filename); +} + +int save_bitmap(const char *filename, BITMAP *bmp, const RGB *pal) { + error("TODO: save_bitmap"); +} + +} // namespace AGS diff --git a/engines/ags/shared/gfx/image.h b/engines/ags/shared/gfx/image.h new file mode 100644 index 000000000000..a37358fa25cb --- /dev/null +++ b/engines/ags/shared/gfx/image.h @@ -0,0 +1,43 @@ +/* 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 AGS_SHARED_GFX_IMAGE_H +#define AGS_SHARED_GFX_IMAGE_H + +#include "ags/stubs/allegro.h" + +namespace AGS3 { + +BITMAP *load_bitmap(const char *filename, color *pal); +BITMAP *load_bmp(const char *filename, color *pal); +BITMAP *load_bmp_pf(PACKFILE *f, color *pal); +BITMAP *load_lbm(const char *filename, color *pal); +BITMAP *load_pcx(const char *filename, color *pal); +BITMAP *load_pcx_pf(PACKFILE *f, color *pal); +BITMAP *load_tga(const char *filename, color *pal); +BITMAP *load_tga_pf(PACKFILE *f, color *pal); + +int save_bitmap(const char *filename, BITMAP *bmp, const RGB *pal); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index 090f51ca4945..0302f118b032 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -55,7 +55,7 @@ using namespace AGS; // FIXME later //============================================================================= // [IKM] 2012-09-13: this function is now defined in engine and editor separately -extern void __my_setcolor(int *ctset, int newcol, int wantColDep); +extern void __my_setcolor(color_t *ctset, color_t newcol, int wantColDep); #ifdef __cplusplus extern "C" diff --git a/engines/ags/stubs/allegro/color.cpp b/engines/ags/stubs/allegro/color.cpp index a69500e38717..f096998d4257 100644 --- a/engines/ags/stubs/allegro/color.cpp +++ b/engines/ags/stubs/allegro/color.cpp @@ -41,22 +41,28 @@ int _rgb_g_shift_32 = 0; int _rgb_b_shift_32 = 0; int _rgb_a_shift_32 = 0; +PALETTE _current_palette; + int bestfit_color(const PALETTE pal, int r, int g, int b) { error("TODO: bestfit_color"); } void set_color(int idx, const RGB *p) { + _current_palette[idx] = *p; g_system->getPaletteManager()->setPalette((const byte *)p, idx, 1); } void set_palette(const PALETTE p) { - + for (int idx = 0; idx < PALETTE_COUNT; ++idx) + _current_palette[idx] = p[idx]; + g_system->getPaletteManager()->setPalette((const byte *)p, 0, PALETTE_COUNT); } void set_palette_range(const PALETTE p, int from, int to, int retracesync) { byte palette[256 * 3]; byte *destP = palette; for (int i = 0; i < 256; ++i, destP += 3) { + _current_palette[i] = *p; destP[0] = p->r; destP[1] = p->g; destP[2] = p->b; @@ -65,4 +71,56 @@ void set_palette_range(const PALETTE p, int from, int to, int retracesync) { g_system->getPaletteManager()->setPalette(&palette[from], from, to - from + 1); } + +int makecol15(int r, int g, int b) { + return (((r >> 3) << _rgb_r_shift_15) | + ((g >> 3) << _rgb_g_shift_15) | + ((b >> 3) << _rgb_b_shift_15)); +} + +int makecol16(int r, int g, int b) { + return (((r >> 3) << _rgb_r_shift_16) | + ((g >> 2) << _rgb_g_shift_16) | + ((b >> 3) << _rgb_b_shift_16)); +} + +int makecol24(int r, int g, int b) { + return ((r << _rgb_r_shift_24) | + (g << _rgb_g_shift_24) | + (b << _rgb_b_shift_24)); +} + +int makecol32(int r, int g, int b) { + return ((r << _rgb_r_shift_32) | + (g << _rgb_g_shift_32) | + (b << _rgb_b_shift_32)); +} + +int makeacol32(int r, int g, int b, int a) { + return ((r << _rgb_r_shift_32) | + (g << _rgb_g_shift_32) | + (b << _rgb_b_shift_32) | + (a << _rgb_a_shift_32)); +} + +int getr8(int c) { + return (int)_current_palette[c].r; +} + +int getg8(int c) { + return (int)_current_palette[c].g; +} + +int getb8(int c) { + return (int)_current_palette[c].b; +} + +int makecol(byte r, byte g, byte b) { + return (b) | (g << 8) | (r << 16); +} + +int makecol8(byte r, byte g, byte b) { + return (b) | (g << 8) | (r << 16); +} + } // namespace AGS3 diff --git a/engines/ags/stubs/allegro/color.h b/engines/ags/stubs/allegro/color.h index e4655628508b..de8ab5b14bb2 100644 --- a/engines/ags/stubs/allegro/color.h +++ b/engines/ags/stubs/allegro/color.h @@ -28,6 +28,13 @@ namespace AGS3 { +#define PALETTE_COUNT 256 +#define MASK_COLOR_8 0 +#define MASK_COLOR_15 0x7C1F +#define MASK_COLOR_16 0xF81F +#define MASK_COLOR_24 0xFF00FF +#define MASK_COLOR_32 0xFF00FF + #include "common/pack-start.h" // START STRUCT PACKING struct color { @@ -35,7 +42,9 @@ struct color { } PACKED_STRUCT; typedef color RGB; -typedef color PALETTE[256]; +typedef color PALETTE[PALETTE_COUNT]; + +AL_VAR(PALETTE, _current_palette); #include "common/pack-end.h" // END STRUCT PACKING @@ -61,6 +70,18 @@ AL_FUNC(void, set_color, (int idx, AL_CONST RGB *p)); AL_FUNC(void, set_palette, (AL_CONST PALETTE p)); AL_FUNC(void, set_palette_range, (AL_CONST PALETTE p, int from, int to, int retracesync)); + +extern int makecol15(int r, int g, int b); +extern int makecol16(int r, int g, int b); +extern int makecol24(int r, int g, int b); +extern int makecol32(int r, int g, int b); +extern int makeacol32(int r, int g, int b, int a); +extern int getr8(int c); +extern int getg8(int c); +extern int getb8(int c); +extern int makecol(byte r, byte g, byte b); +extern int makecol8(byte r, byte g, byte b); + } // namespace AGS3 #endif diff --git a/engines/ags/stubs/allegro/gfx.cpp b/engines/ags/stubs/allegro/gfx.cpp index 799e42a07dbc..0aec33c9f9cf 100644 --- a/engines/ags/stubs/allegro/gfx.cpp +++ b/engines/ags/stubs/allegro/gfx.cpp @@ -22,11 +22,54 @@ #include "ags/stubs/allegro/gfx.h" #include "common/textconsole.h" +#include "graphics/screen.h" namespace AGS3 { int color_conversion; +/*-------------------------------------------------------------------*/ + +BITMAP::BITMAP(Graphics::ManagedSurface *owner) : _owner(owner), + w(owner->w), h(owner->h), format(owner->format), + clip(false), ct(0), cb(0), cl(0), cr(0) { + line.resize(h); + for (uint y = 0; y < h; ++y) + line[y] = (byte *)_owner->getBasePtr(0, y); +} + +/*-------------------------------------------------------------------*/ + +/** + * Derived surface class + */ +class Surface : public Graphics::ManagedSurface, public BITMAP { +public: + Surface() : Graphics::ManagedSurface(), BITMAP(this) {} + Surface(const Graphics::ManagedSurface &surf) : Graphics::ManagedSurface(surf), BITMAP(this) {} + Surface(int width, int height) : Graphics::ManagedSurface(width, height), BITMAP(this) {} + Surface(int width, int height, const Graphics::PixelFormat &pixelFormat) : + Graphics::ManagedSurface(width, height, pixelFormat), BITMAP(this) {} + Surface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) : + Graphics::ManagedSurface(surf, bounds), BITMAP(this) {} + ~Surface() override {} +}; + +/** + * Dervied screen surface + */ +class Screen : public Graphics::Screen, public BITMAP { +public: + Screen() : Graphics::Screen(), BITMAP(this) {} + Screen(int width, int height) : Graphics::Screen(width, height), BITMAP(this) {} + Screen(int width, int height, const Graphics::PixelFormat &pixelFormat) : + Graphics::Screen(width, height, pixelFormat), BITMAP(this) {} + ~Screen() override {} +}; + + +/*-------------------------------------------------------------------*/ + void set_color_conversion(int mode) { color_conversion = mode; } @@ -39,5 +82,308 @@ int set_gfx_mode(int card, int w, int h, int v_w, int v_h) { error("TODO: set_gfx_mode"); } +BITMAP *create_bitmap(int width, int height) { + return new Surface(width, height); +} + +BITMAP *create_bitmap_ex(int color_depth, int width, int height) { + Graphics::PixelFormat format; + + switch (color_depth) { + case 16: + format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + case 32: + format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); + default: + error("Invalid color depth"); + } + + return new Surface(width, height, format); +} + +BITMAP *create_sub_bitmap(BITMAP *parent, int x, int y, int width, int height) { + Graphics::ManagedSurface &surf = **parent; + return new Surface(surf, Common::Rect(x, y, x + width, y + height)); +} + +BITMAP *create_video_bitmap(int width, int height) { + return new Screen(width, height); +} + +BITMAP *create_system_bitmap(int width, int height) { + return create_bitmap(width, height); +} + +void destroy_bitmap(BITMAP *bitmap) { + delete bitmap; +} + +void set_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) { + warning("TODO: set_clip_rect"); +} + +void add_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) { + warning("TODO: add_clip_rect"); +} + +void get_clip_rect(BITMAP *bitmap, int *x1, int *y1, int *x2, int *y2) { + warning("TODO: get_clip_rect"); + *x1 = *y1 = *x2 = *y2 = 0; +} + +void acquire_bitmap(BITMAP *bitmap) { + // No implementation needed +} + +void release_bitmap(BITMAP *bitmap) { + // No implementation needed +} + +void clear_to_color(BITMAP *bitmap, int color) { + Graphics::ManagedSurface &surf = **bitmap; + + surf.clear(color); +} + +int bitmap_color_depth(BITMAP *bmp) { + Graphics::ManagedSurface &surf = **bmp; + + return surf.format.bpp(); +} + +int bitmap_mask_color(BITMAP *bmp) { + Graphics::ManagedSurface &surf = **bmp; + return surf.getTransparentColor(); +} + +void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height) { + Graphics::ManagedSurface &srcS = **src; + Graphics::ManagedSurface &destS = **dest; + + destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y)); +} + +void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, + int dest_x, int dest_y, int dest_width, int dest_height) { + Graphics::ManagedSurface &srcS = **src; + Graphics::ManagedSurface &destS = **dest; + + destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), + Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height)); +} + +void masked_blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height) { + Graphics::ManagedSurface &srcS = **src; + Graphics::ManagedSurface &destS = **dest; + + destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y)); +} + +void masked_stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, + int dest_x, int dest_y, int dest_width, int dest_height) { + Graphics::ManagedSurface &srcS = **src; + Graphics::ManagedSurface &destS = **dest; + + destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), + Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height)); +} + +void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { + Graphics::ManagedSurface &bmpS = **bmp; + Graphics::ManagedSurface &spriteS = **sprite; + + bmpS.blitFrom(spriteS, Common::Point(x, y)); +} + +void stretch_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, int w, int h) { + Graphics::ManagedSurface &bmpS = **bmp; + Graphics::ManagedSurface &spriteS = **sprite; + + bmpS.transBlitFrom(spriteS, Common::Rect(0, 0, sprite->w, sprite->h), + Common::Rect(x, y, x + w, y + h)); +} + +void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { + error("TODO: draw_trans_sprite"); +} + +void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color) { + error("TODO: draw_lit_sprite"); +} + +void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { + error("TODO: draw_sprite_h_flip"); +} + +void draw_sprite_v_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { + error("TODO: draw_sprite_v_flip"); +} + +void draw_sprite_vh_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { + error("TODO: draw_sprite_vh_flip"); +} + +void rotate_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, fixed angle) { + error("TODO: rotate_sprite"); +} + +void pivot_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int cx, int cy, fixed angle) { + error("TODO: pivot_sprite"); +} + + +bool is_screen_bitmap(BITMAP *bmp) { + return dynamic_cast(bmp) != nullptr; +} + +bool is_video_bitmap(BITMAP *bmp) { + return dynamic_cast(bmp) != nullptr; +} + +bool is_planar_bitmap(BITMAP *bmp) { + return false; +} + +void bmp_select(BITMAP *bmp) { + // No implementation needed +} + +long bmp_write_line(BITMAP *bmp, int line) { + return (long)bmp->line[line]; +} + +void bmp_unwrite_line(BITMAP *bmp) { + // No implementation needed +} + +void bmp_write8(unsigned long addr, int color) { + *((byte *)addr) = color; +} + +void memory_putpixel(BITMAP *bmp, int x, int y, int color) { + putpixel(bmp, x, y, color); +} + +void putpixel(BITMAP *bmp, int x, int y, int color) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + + switch (surf.format.bytesPerPixel) { + case 1: + *((uint8 *)p) = color; + break; + case 2: + *((uint16 *)p) = color; + break; + case 4: + *((uint32 *)p) = color; + break; + default: + break; + } +} + +void _putpixel(BITMAP *bmp, int x, int y, int color) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + *((uint8 *)p) = color; +} + +void _putpixel15(BITMAP *bmp, int x, int y, int color) { + error("Unsupported bpp"); +} + +void _putpixel16(BITMAP *bmp, int x, int y, int color) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + *((uint16 *)p) = color; +} + +void _putpixel24(BITMAP *bmp, int x, int y, int color) { + error("Unsupported bpp"); +} + +void _putpixel32(BITMAP *bmp, int x, int y, int color) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + *((uint32 *)p) = color; +} + +int getpixel(BITMAP *bmp, int x, int y) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + + switch (surf.format.bytesPerPixel) { + case 1: + return *((uint8 *)p); + break; + case 2: + return *((uint16 *)p); + break; + case 4: + return *((uint32 *)p); + break; + default: + break; + } + + error("Unsupported bpp"); +} + +int _getpixel(BITMAP *bmp, int x, int y) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + return *((uint8 *)p); +} + +int _getpixel15(BITMAP *bmp, int x, int y) { + error("Unsupported bpp"); +} + +int _getpixel16(BITMAP *bmp, int x, int y) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + return *((uint16 *)p); +} + +int _getpixel24(BITMAP *bmp, int x, int y) { + error("Unsupported bpp"); +} + +int _getpixel32(BITMAP *bmp, int x, int y) { + Graphics::ManagedSurface &surf = **bmp; + void *p = surf.getBasePtr(x, y); + return *((uint32 *)p); +} + +void line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) { + Graphics::ManagedSurface &surf = **bmp; + surf.drawLine(x1, y1, x2, y2, color); +} + +void rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) { + Graphics::ManagedSurface &surf = **bmp; + surf.frameRect(Common::Rect(x1, y1, x2, y2), color); +} + +void rectfill(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) { + Graphics::ManagedSurface &surf = **bmp; + surf.fillRect(Common::Rect(x1, y1, x2, y2), color); +} + +void triangle(BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3, int color) { + Graphics::ManagedSurface &surf = **bmp; + surf.drawLine(x1, y1, x2, y2, color); + surf.drawLine(x2, y2, x3, y3, color); + surf.drawLine(x3, y3, x1, y1, color); +} + +void floodfill(BITMAP *bmp, int x, int y, int color) { + error("TODO: floodfill"); +} + +void circlefill(BITMAP *bmp, int x, int y, int radius, int color) { + error("TODO: circlefill"); +} } // namespace AGS3 diff --git a/engines/ags/stubs/allegro/gfx.h b/engines/ags/stubs/allegro/gfx.h index a6e71afccb7f..b6f8c3be3db6 100644 --- a/engines/ags/stubs/allegro/gfx.h +++ b/engines/ags/stubs/allegro/gfx.h @@ -25,6 +25,8 @@ #include "graphics/managed_surface.h" #include "ags/stubs/allegro/base.h" +#include "ags/stubs/allegro/fixed.h" +#include "common/array.h" namespace AGS3 { @@ -164,12 +166,100 @@ namespace AGS3 { COLORCONV_32A_TO_16 | \ COLORCONV_32A_TO_24)) -class BITMAP : public Graphics::ManagedSurface { +class BITMAP { +private: + Graphics::ManagedSurface *_owner; +public: + uint16 &w, &h; + Graphics::PixelFormat &format; + bool clip; + int ct, cb, cl, cr; + Common::Array line; +public: + BITMAP(Graphics::ManagedSurface *owner); + virtual ~BITMAP() {} + + Graphics::ManagedSurface &operator*() const { + return *_owner; + } + + unsigned char *getPixels() const { + return (unsigned char *)_owner->getPixels(); + } + + unsigned char *getBasePtr(uint16 x, uint16 y) const { + return (unsigned char *)_owner->getBasePtr(x, y); + } + + uint getTransparentColor() const { + return _owner->getTransparentColor(); + } }; AL_FUNC(void, set_color_conversion, (int mode)); AL_FUNC(int, get_color_conversion, ()); AL_FUNC(int, set_gfx_mode, (int card, int w, int h, int v_w, int v_h)); +AL_FUNC(BITMAP *, create_bitmap, (int width, int height)); +AL_FUNC(BITMAP *, create_bitmap_ex, (int color_depth, int width, int height)); +AL_FUNC(BITMAP *, create_sub_bitmap, (BITMAP *parent, int x, int y, int width, int height)); +AL_FUNC(BITMAP *, create_video_bitmap, (int width, int height)); +AL_FUNC(BITMAP *, create_system_bitmap, (int width, int height)); + +AL_FUNC(void, destroy_bitmap, (BITMAP *bitmap)); +AL_FUNC(void, set_clip_rect, (BITMAP *bitmap, int x1, int y1, int x2, int y2)); +AL_FUNC(void, add_clip_rect, (BITMAP *bitmap, int x1, int y1, int x2, int y2)); +AL_FUNC(void, get_clip_rect, (BITMAP *bitmap, int *x1, int *y1, int *x2, int *y2)); +AL_FUNC(void, clear_bitmap, (BITMAP *bitmap)); + +AL_FUNC(void, acquire_bitmap, (BITMAP *bitmap)); +AL_FUNC(void, release_bitmap, (BITMAP *bitmap)); +AL_FUNC(void, draw_sprite, (BITMAP *bmp, const BITMAP *sprite, int x, int y)); +AL_FUNC(void, stretch_sprite, (BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h)); + + +extern void clear_to_color(BITMAP *bitmap, int color); +extern int bitmap_color_depth(BITMAP *bmp); +extern int bitmap_mask_color(BITMAP *bmp); +extern void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height); +extern void masked_blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height); +extern void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, + int dest_x, int dest_y, int dest_width, int dest_height); +extern void masked_stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, + int dest_x, int dest_y, int dest_width, int dest_height); +extern void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y); +extern void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color); +extern void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y); +extern void draw_sprite_v_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y); +extern void draw_sprite_vh_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y); +extern void rotate_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, fixed angle); +extern void pivot_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int cx, int cy, fixed angle); + +extern bool is_screen_bitmap(BITMAP *bmp); +extern bool is_video_bitmap(BITMAP *bmp); +extern bool is_planar_bitmap(BITMAP *bmp); +extern void bmp_select(BITMAP *bmp); +extern long bmp_write_line(BITMAP *bmp, int line); +extern void bmp_unwrite_line(BITMAP *bmp); +extern void bmp_write8(unsigned long addr, int color); +extern void memory_putpixel(BITMAP *bmp, int x, int y, int color); +extern void putpixel(BITMAP *bmp, int x, int y, int color); +extern void _putpixel(BITMAP *bmp, int x, int y, int color); +extern void _putpixel15(BITMAP *bmp, int x, int y, int color); +extern void _putpixel16(BITMAP *bmp, int x, int y, int color); +extern void _putpixel24(BITMAP *bmp, int x, int y, int color); +extern void _putpixel32(BITMAP *bmp, int x, int y, int color); +extern int getpixel(BITMAP *bmp, int x, int y); +extern int _getpixel(BITMAP *bmp, int x, int y); +extern int _getpixel15(BITMAP *bmp, int x, int y); +extern int _getpixel16(BITMAP *bmp, int x, int y); +extern int _getpixel24(BITMAP *bmp, int x, int y); +extern int _getpixel32(BITMAP *bmp, int x, int y); +extern void line(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color); +extern void rect(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color); +extern void rectfill(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color); +extern void triangle(BITMAP *bmp, int x1, int y_1, int x2, int y2, int x3, int y3, int color); +extern void floodfill(BITMAP *bmp, int x, int y, int color); +extern void circlefill(BITMAP *bmp, int x, int y, int radius, int color); } // namespace AGS3 From e4aa2654f76f091bdf1451f5388a66f38b900b31 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 17:48:57 -0800 Subject: [PATCH 015/215] AGS: Move allegro from stubs/ to lib/ --- engines/ags/engine/ac/global_video.cpp | 2 +- engines/ags/engine/ac/keycode.cpp | 2 +- engines/ags/engine/gfx/ali3dsw.h | 2 +- engines/ags/engine/gfx/ogl_headers.h | 4 +-- .../ags/engine/platform/android/acpland.cpp | 2 +- engines/ags/engine/platform/ios/acplios.cpp | 2 +- engines/ags/engine/platform/linux/acpllnx.cpp | 2 +- .../ags/engine/platform/windows/acplwin.cpp | 2 +- .../engine/platform/windows/gfx/ali3dd3d.cpp | 2 +- .../engine/platform/windows/gfx/ali3dd3d.h | 2 +- .../platform/windows/media/video/acwavi.cpp | 2 +- .../platform/windows/media/video/acwavi3d.cpp | 2 +- .../platform/windows/win_ex_handling.cpp | 2 +- engines/ags/lib/aastr-0.1.1/aastr.h | 2 +- engines/ags/lib/aastr-0.1.1/aautil.h | 2 +- engines/ags/{stubs => lib}/allegro.cpp | 2 +- engines/ags/{stubs => lib}/allegro.h | 30 +++++++++---------- engines/ags/{stubs => lib}/allegro/alconfig.h | 0 engines/ags/{stubs => lib}/allegro/base.h | 0 engines/ags/{stubs => lib}/allegro/color.cpp | 2 +- engines/ags/{stubs => lib}/allegro/color.h | 2 +- engines/ags/{stubs => lib}/allegro/config.cpp | 2 +- engines/ags/{stubs => lib}/allegro/config.h | 0 engines/ags/{stubs => lib}/allegro/digi.cpp | 2 +- engines/ags/{stubs => lib}/allegro/digi.h | 4 +-- engines/ags/{stubs => lib}/allegro/error.cpp | 2 +- engines/ags/{stubs => lib}/allegro/error.h | 0 engines/ags/{stubs => lib}/allegro/file.cpp | 2 +- engines/ags/{stubs => lib}/allegro/file.h | 0 engines/ags/{stubs => lib}/allegro/fixed.cpp | 4 +-- engines/ags/{stubs => lib}/allegro/fixed.h | 0 engines/ags/{stubs => lib}/allegro/gfx.cpp | 2 +- engines/ags/{stubs => lib}/allegro/gfx.h | 4 +-- .../ags/{stubs => lib}/allegro/keyboard.cpp | 2 +- engines/ags/{stubs => lib}/allegro/keyboard.h | 0 engines/ags/{stubs => lib}/allegro/midi.cpp | 2 +- engines/ags/{stubs => lib}/allegro/midi.h | 4 +-- engines/ags/{stubs => lib}/allegro/mouse.cpp | 2 +- engines/ags/{stubs => lib}/allegro/mouse.h | 6 ++-- engines/ags/{stubs => lib}/allegro/sound.cpp | 2 +- engines/ags/{stubs => lib}/allegro/sound.h | 4 +-- engines/ags/{stubs => lib}/allegro/system.cpp | 2 +- engines/ags/{stubs => lib}/allegro/system.h | 6 ++-- .../ags/{stubs => lib}/allegro/unicode.cpp | 2 +- engines/ags/{stubs => lib}/allegro/unicode.h | 2 +- engines/ags/module.mk | 28 ++++++++--------- engines/ags/shared/gfx/allegrobitmap.h | 2 +- engines/ags/shared/gfx/image.cpp | 2 +- engines/ags/shared/gfx/image.h | 2 +- engines/ags/shared/util/misc.cpp | 2 +- engines/ags/shared/util/path.cpp | 2 +- engines/ags/shared/util/string_utils.cpp | 2 +- engines/ags/shared/util/wgt2allg.cpp | 2 +- engines/ags/shared/util/wgt2allg.h | 2 +- 54 files changed, 84 insertions(+), 84 deletions(-) rename engines/ags/{stubs => lib}/allegro.cpp (97%) rename engines/ags/{stubs => lib}/allegro.h (66%) rename engines/ags/{stubs => lib}/allegro/alconfig.h (100%) rename engines/ags/{stubs => lib}/allegro/base.h (100%) rename engines/ags/{stubs => lib}/allegro/color.cpp (98%) rename engines/ags/{stubs => lib}/allegro/color.h (98%) rename engines/ags/{stubs => lib}/allegro/config.cpp (96%) rename engines/ags/{stubs => lib}/allegro/config.h (100%) rename engines/ags/{stubs => lib}/allegro/digi.cpp (96%) rename engines/ags/{stubs => lib}/allegro/digi.h (98%) rename engines/ags/{stubs => lib}/allegro/error.cpp (96%) rename engines/ags/{stubs => lib}/allegro/error.h (100%) rename engines/ags/{stubs => lib}/allegro/file.cpp (97%) rename engines/ags/{stubs => lib}/allegro/file.h (100%) rename engines/ags/{stubs => lib}/allegro/fixed.cpp (97%) rename engines/ags/{stubs => lib}/allegro/fixed.h (100%) rename engines/ags/{stubs => lib}/allegro/gfx.cpp (99%) rename engines/ags/{stubs => lib}/allegro/gfx.h (99%) rename engines/ags/{stubs => lib}/allegro/keyboard.cpp (96%) rename engines/ags/{stubs => lib}/allegro/keyboard.h (100%) rename engines/ags/{stubs => lib}/allegro/midi.cpp (97%) rename engines/ags/{stubs => lib}/allegro/midi.h (98%) rename engines/ags/{stubs => lib}/allegro/mouse.cpp (98%) rename engines/ags/{stubs => lib}/allegro/mouse.h (97%) rename engines/ags/{stubs => lib}/allegro/sound.cpp (98%) rename engines/ags/{stubs => lib}/allegro/sound.h (96%) rename engines/ags/{stubs => lib}/allegro/system.cpp (97%) rename engines/ags/{stubs => lib}/allegro/system.h (97%) rename engines/ags/{stubs => lib}/allegro/unicode.cpp (96%) rename engines/ags/{stubs => lib}/allegro/unicode.h (97%) diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp index 718e91fbde73..1629b1cf8f97 100644 --- a/engines/ags/engine/ac/global_video.cpp +++ b/engines/ags/engine/ac/global_video.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include "ac/gamesetup.h" #include "ac/gamestate.h" #include "ac/global_audio.h" diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp index 6e05ca18539c..e938b14ef6d4 100644 --- a/engines/ags/engine/ac/keycode.cpp +++ b/engines/ags/engine/ac/keycode.cpp @@ -22,7 +22,7 @@ #include "ac/keycode.h" -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index e46b5f4cc2fe..54bfc93d90f2 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -34,7 +34,7 @@ #include "core/platform.h" #define AGS_DDRAW_GAMMA_CONTROL (AGS_PLATFORM_OS_WINDOWS) -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #if AGS_DDRAW_GAMMA_CONTROL #include diff --git a/engines/ags/engine/gfx/ogl_headers.h b/engines/ags/engine/gfx/ogl_headers.h index 595b4647b571..b4f3c2f2228e 100644 --- a/engines/ags/engine/gfx/ogl_headers.h +++ b/engines/ags/engine/gfx/ogl_headers.h @@ -29,7 +29,7 @@ #include "core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include @@ -37,7 +37,7 @@ #include "glad/glad_wgl.h" #elif AGS_PLATFORM_OS_LINUX -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp index 3b191305b56a..a3f24a8c1f14 100644 --- a/engines/ags/engine/platform/android/acpland.cpp +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -24,7 +24,7 @@ #if AGS_PLATFORM_OS_ANDROID -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include "platform/base/agsplatformdriver.h" #include "ac/runtime_defines.h" #include "main/config.h" diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp index a00f5aa2d451..8134a608ea07 100644 --- a/engines/ags/engine/platform/ios/acplios.cpp +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -29,7 +29,7 @@ #include #include -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include "platform/base/agsplatformdriver.h" #include "ac/runtime_defines.h" #include "main/config.h" diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 826d0a39d319..3adccfd820f3 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -27,7 +27,7 @@ // ********* LINUX PLACEHOLDER DRIVER ********* #include -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include "ac/runtime_defines.h" #include "gfx/gfxdefines.h" diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index d585c214bba5..ccf9dc00c5bd 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -27,7 +27,7 @@ // ********* WINDOWS ********* #include -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include "ac/common.h" #include "ac/draw.h" diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index 44cdc82d7d7b..93c926e8c088 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -32,7 +32,7 @@ #include "platform/windows/gfx/ali3dd3d.h" -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include "ac/timer.h" #include "debug/assert.h" diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index ed7fdc392439..1d5abbebe4e0 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -36,7 +36,7 @@ #endif #include -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include #include "gfx/bitmap.h" diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp index 741ab58b4864..fe9a62160d22 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -33,7 +33,7 @@ #if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) //#define ALLEGRO_STATICLINK // already defined in project settings -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include #include diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp index 0d6cab1fe1ba..e49ef7c05c43 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -32,7 +32,7 @@ #if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) //#define ALLEGRO_STATICLINK // already defined in project settings -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include #include diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index c8aba200f54c..c59d7e3456e7 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -24,7 +24,7 @@ #if AGS_PLATFORM_OS_WINDOWS #include -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include #include "ac/common.h" #include "ac/common_defines.h" diff --git a/engines/ags/lib/aastr-0.1.1/aastr.h b/engines/ags/lib/aastr-0.1.1/aastr.h index 3a85ca1a7350..05a082e40ca9 100644 --- a/engines/ags/lib/aastr-0.1.1/aastr.h +++ b/engines/ags/lib/aastr-0.1.1/aastr.h @@ -38,7 +38,7 @@ #ifndef AGS_LIB_AASTR_AASTR_H #define AGS_LIB_AASTR_AASTR_H -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" namespace AGS3 { diff --git a/engines/ags/lib/aastr-0.1.1/aautil.h b/engines/ags/lib/aastr-0.1.1/aautil.h index 81b1f97fec05..8616f8c286f3 100644 --- a/engines/ags/lib/aastr-0.1.1/aautil.h +++ b/engines/ags/lib/aastr-0.1.1/aautil.h @@ -38,7 +38,7 @@ #ifndef AGS_LIB_AASTR_AAUTIL_H #define AGS_LIB_AASTR_AAUTIL_H -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro.cpp b/engines/ags/lib/allegro.cpp similarity index 97% rename from engines/ags/stubs/allegro.cpp rename to engines/ags/lib/allegro.cpp index 93a597c56f61..90365ef8250a 100644 --- a/engines/ags/stubs/allegro.cpp +++ b/engines/ags/lib/allegro.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro.h b/engines/ags/lib/allegro.h similarity index 66% rename from engines/ags/stubs/allegro.h rename to engines/ags/lib/allegro.h index 6d3aed6b22e4..09d26765d7c5 100644 --- a/engines/ags/stubs/allegro.h +++ b/engines/ags/lib/allegro.h @@ -23,21 +23,21 @@ #ifndef AGS_STUBS_ALLEGRO_H #define AGS_STUBS_ALLEGRO_H -#include "ags/stubs/allegro/alconfig.h" -#include "ags/stubs/allegro/base.h" -#include "ags/stubs/allegro/color.h" -#include "ags/stubs/allegro/config.h" -#include "ags/stubs/allegro/digi.h" -#include "ags/stubs/allegro/error.h" -#include "ags/stubs/allegro/file.h" -#include "ags/stubs/allegro/fixed.h" -#include "ags/stubs/allegro/gfx.h" -#include "ags/stubs/allegro/keyboard.h" -#include "ags/stubs/allegro/midi.h" -#include "ags/stubs/allegro/mouse.h" -#include "ags/stubs/allegro/sound.h" -#include "ags/stubs/allegro/system.h" -#include "ags/stubs/allegro/unicode.h" +#include "ags/lib/allegro/alconfig.h" +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/color.h" +#include "ags/lib/allegro/config.h" +#include "ags/lib/allegro/digi.h" +#include "ags/lib/allegro/error.h" +#include "ags/lib/allegro/file.h" +#include "ags/lib/allegro/fixed.h" +#include "ags/lib/allegro/gfx.h" +#include "ags/lib/allegro/keyboard.h" +#include "ags/lib/allegro/midi.h" +#include "ags/lib/allegro/mouse.h" +#include "ags/lib/allegro/sound.h" +#include "ags/lib/allegro/system.h" +#include "ags/lib/allegro/unicode.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/alconfig.h b/engines/ags/lib/allegro/alconfig.h similarity index 100% rename from engines/ags/stubs/allegro/alconfig.h rename to engines/ags/lib/allegro/alconfig.h diff --git a/engines/ags/stubs/allegro/base.h b/engines/ags/lib/allegro/base.h similarity index 100% rename from engines/ags/stubs/allegro/base.h rename to engines/ags/lib/allegro/base.h diff --git a/engines/ags/stubs/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp similarity index 98% rename from engines/ags/stubs/allegro/color.cpp rename to engines/ags/lib/allegro/color.cpp index f096998d4257..45a994e7f7f1 100644 --- a/engines/ags/stubs/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/color.h" +#include "ags/lib/allegro/color.h" #include "common/textconsole.h" #include "common/system.h" #include "graphics/palette.h" diff --git a/engines/ags/stubs/allegro/color.h b/engines/ags/lib/allegro/color.h similarity index 98% rename from engines/ags/stubs/allegro/color.h rename to engines/ags/lib/allegro/color.h index de8ab5b14bb2..d08762f8de3b 100644 --- a/engines/ags/stubs/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -24,7 +24,7 @@ #define AGS_STUBS_ALLEGRO_COLOR_H #include "common/scummsys.h" -#include "ags/stubs/allegro/alconfig.h" +#include "ags/lib/allegro/alconfig.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/config.cpp b/engines/ags/lib/allegro/config.cpp similarity index 96% rename from engines/ags/stubs/allegro/config.cpp rename to engines/ags/lib/allegro/config.cpp index 537f86e43949..390f17332e37 100644 --- a/engines/ags/stubs/allegro/config.cpp +++ b/engines/ags/lib/allegro/config.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/config.h" +#include "ags/lib/allegro/config.h" #include "common/textconsole.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/config.h b/engines/ags/lib/allegro/config.h similarity index 100% rename from engines/ags/stubs/allegro/config.h rename to engines/ags/lib/allegro/config.h diff --git a/engines/ags/stubs/allegro/digi.cpp b/engines/ags/lib/allegro/digi.cpp similarity index 96% rename from engines/ags/stubs/allegro/digi.cpp rename to engines/ags/lib/allegro/digi.cpp index 07ba5ecfdaa4..c3dbacf4ba83 100644 --- a/engines/ags/stubs/allegro/digi.cpp +++ b/engines/ags/lib/allegro/digi.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/digi.h" +#include "ags/lib/allegro/digi.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/digi.h b/engines/ags/lib/allegro/digi.h similarity index 98% rename from engines/ags/stubs/allegro/digi.h rename to engines/ags/lib/allegro/digi.h index 0dc8d44adee9..7eeaa723828f 100644 --- a/engines/ags/stubs/allegro/digi.h +++ b/engines/ags/lib/allegro/digi.h @@ -24,8 +24,8 @@ #define AGS_STUBS_ALLEGRO_DIGI_H #include "common/scummsys.h" -#include "ags/stubs/allegro/base.h" -#include "ags/stubs/allegro/alconfig.h" +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/alconfig.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/error.cpp b/engines/ags/lib/allegro/error.cpp similarity index 96% rename from engines/ags/stubs/allegro/error.cpp rename to engines/ags/lib/allegro/error.cpp index 25105d946141..4c78014fb337 100644 --- a/engines/ags/stubs/allegro/error.cpp +++ b/engines/ags/lib/allegro/error.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/error.h" +#include "ags/lib/allegro/error.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/error.h b/engines/ags/lib/allegro/error.h similarity index 100% rename from engines/ags/stubs/allegro/error.h rename to engines/ags/lib/allegro/error.h diff --git a/engines/ags/stubs/allegro/file.cpp b/engines/ags/lib/allegro/file.cpp similarity index 97% rename from engines/ags/stubs/allegro/file.cpp rename to engines/ags/lib/allegro/file.cpp index ad121f296b98..8ac3f0579380 100644 --- a/engines/ags/stubs/allegro/file.cpp +++ b/engines/ags/lib/allegro/file.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/file.h" +#include "ags/lib/allegro/file.h" #include "common/str.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/file.h b/engines/ags/lib/allegro/file.h similarity index 100% rename from engines/ags/stubs/allegro/file.h rename to engines/ags/lib/allegro/file.h diff --git a/engines/ags/stubs/allegro/fixed.cpp b/engines/ags/lib/allegro/fixed.cpp similarity index 97% rename from engines/ags/stubs/allegro/fixed.cpp rename to engines/ags/lib/allegro/fixed.cpp index 09d0343a7d16..be16f6ae40c8 100644 --- a/engines/ags/stubs/allegro/fixed.cpp +++ b/engines/ags/lib/allegro/fixed.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/stubs/allegro/fixed.h" -#include "ags/stubs/allegro/error.h" +#include "ags/lib/allegro/fixed.h" +#include "ags/lib/allegro/error.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/fixed.h b/engines/ags/lib/allegro/fixed.h similarity index 100% rename from engines/ags/stubs/allegro/fixed.h rename to engines/ags/lib/allegro/fixed.h diff --git a/engines/ags/stubs/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp similarity index 99% rename from engines/ags/stubs/allegro/gfx.cpp rename to engines/ags/lib/allegro/gfx.cpp index 0aec33c9f9cf..e5ccd68ec874 100644 --- a/engines/ags/stubs/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/gfx.h" +#include "ags/lib/allegro/gfx.h" #include "common/textconsole.h" #include "graphics/screen.h" diff --git a/engines/ags/stubs/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h similarity index 99% rename from engines/ags/stubs/allegro/gfx.h rename to engines/ags/lib/allegro/gfx.h index b6f8c3be3db6..cf2402acb2c6 100644 --- a/engines/ags/stubs/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -24,8 +24,8 @@ #define AGS_STUBS_ALLEGRO_GRAPHICS_H #include "graphics/managed_surface.h" -#include "ags/stubs/allegro/base.h" -#include "ags/stubs/allegro/fixed.h" +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/fixed.h" #include "common/array.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/keyboard.cpp b/engines/ags/lib/allegro/keyboard.cpp similarity index 96% rename from engines/ags/stubs/allegro/keyboard.cpp rename to engines/ags/lib/allegro/keyboard.cpp index ba014a85f521..9e0a0f638ab2 100644 --- a/engines/ags/stubs/allegro/keyboard.cpp +++ b/engines/ags/lib/allegro/keyboard.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/keyboard.h" +#include "ags/lib/allegro/keyboard.h" #include "common/algorithm.h" #include "common/textconsole.h" diff --git a/engines/ags/stubs/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h similarity index 100% rename from engines/ags/stubs/allegro/keyboard.h rename to engines/ags/lib/allegro/keyboard.h diff --git a/engines/ags/stubs/allegro/midi.cpp b/engines/ags/lib/allegro/midi.cpp similarity index 97% rename from engines/ags/stubs/allegro/midi.cpp rename to engines/ags/lib/allegro/midi.cpp index d0bab8025489..7b058574bab0 100644 --- a/engines/ags/stubs/allegro/midi.cpp +++ b/engines/ags/lib/allegro/midi.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/midi.h" +#include "ags/lib/allegro/midi.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/midi.h b/engines/ags/lib/allegro/midi.h similarity index 98% rename from engines/ags/stubs/allegro/midi.h rename to engines/ags/lib/allegro/midi.h index e1f5f2071d45..66a89f0aba78 100644 --- a/engines/ags/stubs/allegro/midi.h +++ b/engines/ags/lib/allegro/midi.h @@ -24,8 +24,8 @@ #define AGS_STUBS_ALLEGRO_MIDI_H #include "common/scummsys.h" -#include "ags/stubs/allegro/base.h" -#include "ags/stubs/allegro/alconfig.h" +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/alconfig.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/mouse.cpp b/engines/ags/lib/allegro/mouse.cpp similarity index 98% rename from engines/ags/stubs/allegro/mouse.cpp rename to engines/ags/lib/allegro/mouse.cpp index daa0bad28f9f..9c719db02f99 100644 --- a/engines/ags/stubs/allegro/mouse.cpp +++ b/engines/ags/lib/allegro/mouse.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/mouse.h" +#include "ags/lib/allegro/mouse.h" #include "common/textconsole.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/mouse.h b/engines/ags/lib/allegro/mouse.h similarity index 97% rename from engines/ags/stubs/allegro/mouse.h rename to engines/ags/lib/allegro/mouse.h index 33538fac929b..3ad8998f773f 100644 --- a/engines/ags/stubs/allegro/mouse.h +++ b/engines/ags/lib/allegro/mouse.h @@ -24,9 +24,9 @@ #define AGS_STUBS_ALLEGRO_MOUSE_H #include "common/events.h" -#include "ags/stubs/allegro/base.h" -#include "ags/stubs/allegro/alconfig.h" -#include "ags/stubs/allegro/gfx.h" +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/alconfig.h" +#include "ags/lib/allegro/gfx.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/sound.cpp b/engines/ags/lib/allegro/sound.cpp similarity index 98% rename from engines/ags/stubs/allegro/sound.cpp rename to engines/ags/lib/allegro/sound.cpp index 5eda1fe992e2..a4acc0565f68 100644 --- a/engines/ags/stubs/allegro/sound.cpp +++ b/engines/ags/lib/allegro/sound.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/sound.h" +#include "ags/lib/allegro/sound.h" #include "common/textconsole.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/sound.h b/engines/ags/lib/allegro/sound.h similarity index 96% rename from engines/ags/stubs/allegro/sound.h rename to engines/ags/lib/allegro/sound.h index fa9f64097e6b..d487041039e9 100644 --- a/engines/ags/stubs/allegro/sound.h +++ b/engines/ags/lib/allegro/sound.h @@ -24,8 +24,8 @@ #define AGS_STUBS_ALLEGRO_SOUND_H #include "common/scummsys.h" -#include "ags/stubs/allegro/base.h" -#include "ags/stubs/allegro/alconfig.h" +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/alconfig.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/system.cpp b/engines/ags/lib/allegro/system.cpp similarity index 97% rename from engines/ags/stubs/allegro/system.cpp rename to engines/ags/lib/allegro/system.cpp index 47675373790b..67a6d806a44e 100644 --- a/engines/ags/stubs/allegro/system.cpp +++ b/engines/ags/lib/allegro/system.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/system.h" +#include "ags/lib/allegro/system.h" #include "common/system.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/system.h b/engines/ags/lib/allegro/system.h similarity index 97% rename from engines/ags/stubs/allegro/system.h rename to engines/ags/lib/allegro/system.h index 0f6724600630..f461d00195f7 100644 --- a/engines/ags/stubs/allegro/system.h +++ b/engines/ags/lib/allegro/system.h @@ -23,9 +23,9 @@ #ifndef AGS_STUBS_ALLEGRO_SYSTEM_H #define AGS_STUBS_ALLEGRO_SYSTEM_H -#include "ags/stubs/allegro/base.h" -#include "ags/stubs/allegro/color.h" -#include "ags/stubs/allegro/gfx.h" +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/color.h" +#include "ags/lib/allegro/gfx.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/unicode.cpp b/engines/ags/lib/allegro/unicode.cpp similarity index 96% rename from engines/ags/stubs/allegro/unicode.cpp rename to engines/ags/lib/allegro/unicode.cpp index 36372960e2a4..073fda45ec71 100644 --- a/engines/ags/stubs/allegro/unicode.cpp +++ b/engines/ags/lib/allegro/unicode.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/stubs/allegro/unicode.h" +#include "ags/lib/allegro/unicode.h" #include "common/textconsole.h" namespace AGS3 { diff --git a/engines/ags/stubs/allegro/unicode.h b/engines/ags/lib/allegro/unicode.h similarity index 97% rename from engines/ags/stubs/allegro/unicode.h rename to engines/ags/lib/allegro/unicode.h index 24e84d913aae..48667d7f8a58 100644 --- a/engines/ags/stubs/allegro/unicode.h +++ b/engines/ags/lib/allegro/unicode.h @@ -23,7 +23,7 @@ #ifndef AGS_STUBS_ALLEGRO_UNICODE_H #define AGS_STUBS_ALLEGRO_UNICODE_H -#include "ags/stubs/allegro/base.h" +#include "ags/lib/allegro/base.h" namespace AGS3 { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 148852c3cd1e..f87f6cbd10bc 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -6,20 +6,20 @@ MODULE_OBJS = \ lib/aastr-0.1.1/aarot.o \ lib/aastr-0.1.1/aastr.o \ lib/aastr-0.1.1/aautil.o \ - stubs/allegro.o \ - stubs/allegro/color.o \ - stubs/allegro/config.o \ - stubs/allegro/digi.o \ - stubs/allegro/error.o \ - stubs/allegro/file.o \ - stubs/allegro/fixed.o \ - stubs/allegro/gfx.o \ - stubs/allegro/keyboard.o \ - stubs/allegro/midi.o \ - stubs/allegro/mouse.o \ - stubs/allegro/sound.o \ - stubs/allegro/system.o \ - stubs/allegro/unicode.o \ + lib/allegro.o \ + lib/allegro/color.o \ + lib/allegro/config.o \ + lib/allegro/digi.o \ + lib/allegro/error.o \ + lib/allegro/file.o \ + lib/allegro/fixed.o \ + lib/allegro/gfx.o \ + lib/allegro/keyboard.o \ + lib/allegro/midi.o \ + lib/allegro/mouse.o \ + lib/allegro/sound.o \ + lib/allegro/system.o \ + lib/allegro/unicode.o \ shared/gfx/allegrobitmap.o \ shared/gfx/bitmap.o \ shared/gfx/image.o \ diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index f59f346daedb..37ba3fcd978d 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -32,7 +32,7 @@ #ifndef AGS_SHARED_GFX_ALLEGROBITMAP_H #define AGS_SHARED_GFX_ALLEGROBITMAP_H -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include "ags/shared/core/types.h" #include "ags/shared/gfx/bitmap.h" #include "ags/shared/util/geometry.h" diff --git a/engines/ags/shared/gfx/image.cpp b/engines/ags/shared/gfx/image.cpp index b77e08286ced..8de490b338f4 100644 --- a/engines/ags/shared/gfx/image.cpp +++ b/engines/ags/shared/gfx/image.cpp @@ -21,7 +21,7 @@ */ #include "ags/shared/gfx/image.h" -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include "common/str.h" #include "common/textconsole.h" diff --git a/engines/ags/shared/gfx/image.h b/engines/ags/shared/gfx/image.h index a37358fa25cb..592009ec016f 100644 --- a/engines/ags/shared/gfx/image.h +++ b/engines/ags/shared/gfx/image.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GFX_IMAGE_H #define AGS_SHARED_GFX_IMAGE_H -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" namespace AGS3 { diff --git a/engines/ags/shared/util/misc.cpp b/engines/ags/shared/util/misc.cpp index 1bdad6992d9f..f499d297947c 100644 --- a/engines/ags/shared/util/misc.cpp +++ b/engines/ags/shared/util/misc.cpp @@ -59,7 +59,7 @@ //include #endif -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" #include "ags/shared/util/file.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/shared/util/path.cpp b/engines/ags/shared/util/path.cpp index 763808bf2b78..495ddb23db44 100644 --- a/engines/ags/shared/util/path.cpp +++ b/engines/ags/shared/util/path.cpp @@ -25,7 +25,7 @@ //include #endif -#include "ags/stubs/allegro/file.h" +#include "ags/lib/allegro/file.h" #include "ags/shared/util/path.h" #include "ags/shared/util/stdio_compat.h" diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp index 16eeaccf47c3..9d3381995681 100644 --- a/engines/ags/shared/util/string_utils.cpp +++ b/engines/ags/shared/util/string_utils.cpp @@ -26,7 +26,7 @@ #include "ags/shared/util/math.h" #include "ags/shared/util/string_utils.h" #include "ags/shared/util/stream.h" -#include "ags/stubs/allegro/error.h" +#include "ags/lib/allegro/error.h" namespace AGS3 { diff --git a/engines/ags/shared/util/wgt2allg.cpp b/engines/ags/shared/util/wgt2allg.cpp index ea5067d79aad..80793adb9c18 100644 --- a/engines/ags/shared/util/wgt2allg.cpp +++ b/engines/ags/shared/util/wgt2allg.cpp @@ -25,7 +25,7 @@ #include "ags/shared/gfx/allegrobitmap.h" #include "ags/shared/util/stream.h" #include "ags/shared/util/wgt2allg.h" -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" namespace AGS3 { diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index 0302f118b032..6126da9591c1 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -34,7 +34,7 @@ #define _WGT45_ #include "ags/shared/core/platform.h" -#include "ags/stubs/allegro.h" +#include "ags/lib/allegro.h" namespace AGS3 { From 63bc6332350b4bf2bb3d0ffc473abb9c151982c7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 17:57:29 -0800 Subject: [PATCH 016/215] AGS: Added shared/ac/ folder --- engines/ags/module.mk | 12 +++++ engines/ags/shared/ac/audiocliptype.cpp | 4 +- engines/ags/shared/ac/audiocliptype.h | 8 +-- engines/ags/shared/ac/characterinfo.h | 4 +- engines/ags/shared/ac/dialogtopic.cpp | 4 +- engines/ags/shared/ac/dialogtopic.h | 6 +-- .../ags/shared/ac/dynobj/scriptaudioclip.h | 6 +-- engines/ags/shared/ac/gamesetupstruct.cpp | 36 ++++++------- engines/ags/shared/ac/gamesetupstruct.h | 51 ++++++++++--------- engines/ags/shared/ac/gamesetupstructbase.h | 20 ++++---- engines/ags/shared/ac/inventoryiteminfo.h | 8 +-- engines/ags/shared/ac/mousecursor.h | 12 ++--- engines/ags/shared/ac/spritecache.cpp | 15 +++--- engines/ags/shared/ac/spritecache.h | 4 +- engines/ags/shared/ac/view.cpp | 4 +- engines/ags/shared/ac/view.h | 20 ++++---- engines/ags/shared/ac/wordsdictionary.cpp | 2 +- engines/ags/shared/ac/wordsdictionary.h | 8 +-- engines/ags/shared/core/asset.h | 2 +- engines/ags/shared/debugging/debugmanager.h | 4 +- engines/ags/shared/font/fonts.cpp | 2 +- engines/ags/shared/font/fonts.h | 2 +- engines/ags/shared/font/wfnfont.cpp | 2 +- engines/ags/shared/font/wfnfont.h | 2 +- engines/ags/shared/game/customproperties.cpp | 6 +-- engines/ags/shared/game/customproperties.h | 4 +- engines/ags/shared/game/interactions.cpp | 10 ++-- engines/ags/shared/game/interactions.h | 6 +-- engines/ags/shared/game/main_game_file.h | 6 +-- engines/ags/shared/game/plugininfo.h | 2 +- engines/ags/shared/game/room_file.cpp | 16 +++--- engines/ags/shared/game/room_file.h | 4 +- engines/ags/shared/game/roomstruct.h | 2 +- engines/ags/shared/gui/guibutton.h | 2 +- engines/ags/shared/gui/guiinv.h | 2 +- engines/ags/shared/gui/guilabel.h | 2 +- engines/ags/shared/gui/guilistbox.h | 2 +- engines/ags/shared/gui/guislider.h | 2 +- engines/ags/shared/gui/guitextbox.h | 2 +- 39 files changed, 160 insertions(+), 146 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index f87f6cbd10bc..f039ffe63f19 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -20,6 +20,18 @@ MODULE_OBJS = \ lib/allegro/sound.o \ lib/allegro/system.o \ lib/allegro/unicode.o \ + shared/ac/dynobj/scriptaudioclip.o \ + shared/ac/audiocliptype.o \ + shared/ac/characterinfo.o \ + shared/ac/common.o \ + shared/ac/dialogtopic.o \ + shared/ac/gamesetupstruct.o \ + shared/ac/gamesetupstructbase.o \ + shared/ac/inventoryiteminfo.o \ + shared/ac/mousecursor.o \ + shared/ac/spritecache.o \ + shared/ac/view.o \ + shared/ac/wordsdictionary.o \ shared/gfx/allegrobitmap.o \ shared/gfx/bitmap.o \ shared/gfx/image.o \ diff --git a/engines/ags/shared/ac/audiocliptype.cpp b/engines/ags/shared/ac/audiocliptype.cpp index a1de83d396d1..4417559e331a 100644 --- a/engines/ags/shared/ac/audiocliptype.cpp +++ b/engines/ags/shared/ac/audiocliptype.cpp @@ -43,12 +43,12 @@ void AudioClipType::WriteToFile(Stream *out) { out->WriteInt32(reservedForFuture); } -void AudioClipType::ReadFromSavegame(Common::Stream *in) { +void AudioClipType::ReadFromSavegame(Stream *in) { volume_reduction_while_speech_playing = in->ReadInt32(); crossfadeSpeed = in->ReadInt32(); } -void AudioClipType::WriteToSavegame(Common::Stream *out) const { +void AudioClipType::WriteToSavegame(Stream *out) const { out->WriteInt32(volume_reduction_while_speech_playing); out->WriteInt32(crossfadeSpeed); } diff --git a/engines/ags/shared/ac/audiocliptype.h b/engines/ags/shared/ac/audiocliptype.h index 9871c5e29441..80ff9a168186 100644 --- a/engines/ags/shared/ac/audiocliptype.h +++ b/engines/ags/shared/ac/audiocliptype.h @@ -42,10 +42,10 @@ struct AudioClipType { int crossfadeSpeed; int reservedForFuture; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); + void ReadFromSavegame(Shared::Stream *in); + void WriteToSavegame(Shared::Stream *out) const; }; } // namespace AGS3 diff --git a/engines/ags/shared/ac/characterinfo.h b/engines/ags/shared/ac/characterinfo.h index 287937994ade..b8175c006256 100644 --- a/engines/ags/shared/ac/characterinfo.h +++ b/engines/ags/shared/ac/characterinfo.h @@ -128,8 +128,8 @@ struct CharacterInfo { void update_character_idle(CharacterExtras *chex, int &doing_nothing); void update_character_follower(int &char_index, int &numSheep, int *followingAsSheep, int &doing_nothing); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); }; diff --git a/engines/ags/shared/ac/dialogtopic.cpp b/engines/ags/shared/ac/dialogtopic.cpp index efcbb4f2c16c..546877bd0c03 100644 --- a/engines/ags/shared/ac/dialogtopic.cpp +++ b/engines/ags/shared/ac/dialogtopic.cpp @@ -40,11 +40,11 @@ void DialogTopic::ReadFromFile(Stream *in) { topicFlags = in->ReadInt32(); } -void DialogTopic::ReadFromSavegame(Common::Stream *in) { +void DialogTopic::ReadFromSavegame(Stream *in) { in->ReadArrayOfInt32(optionflags, MAXTOPICOPTIONS); } -void DialogTopic::WriteToSavegame(Common::Stream *out) const { +void DialogTopic::WriteToSavegame(Stream *out) const { out->WriteArrayOfInt32(optionflags, MAXTOPICOPTIONS); } diff --git a/engines/ags/shared/ac/dialogtopic.h b/engines/ags/shared/ac/dialogtopic.h index e23d534f0fe2..8fb0031e10f4 100644 --- a/engines/ags/shared/ac/dialogtopic.h +++ b/engines/ags/shared/ac/dialogtopic.h @@ -70,10 +70,10 @@ struct DialogTopic { int numoptions; int topicFlags; - void ReadFromFile(Common::Stream *in); + void ReadFromFile(Shared::Stream *in); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromSavegame(Shared::Stream *in); + void WriteToSavegame(Shared::Stream *out) const; }; } // namespace AGS3 diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index de4361bd0408..dfde8e752e37 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -51,8 +51,8 @@ enum AudioFileType { #define SCRIPTAUDIOCLIP_FILENAMELENGTH 15 struct ScriptAudioClip { int id = 0; - Common::String scriptName; - Common::String fileName; + Shared::String scriptName; + Shared::String fileName; char bundlingType = AUCL_BUNDLE_EXE; char type = 0; char fileType = eAudioFileOGG; @@ -60,7 +60,7 @@ struct ScriptAudioClip { short defaultPriority = 50; short defaultVolume = 100; - void ReadFromFile(Common::Stream *in); + void ReadFromFile(Shared::Stream *in); }; } // namespace AGS3 diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp index 4c4139c82bc0..73cb35d8deba 100644 --- a/engines/ags/shared/ac/gamesetupstruct.cpp +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -107,7 +107,7 @@ ScriptAudioClip *GetAudioClipForOldStyleNumber(GameSetupStruct &game, bool is_mu //----------------------------------------------------------------------------- // Reading Part 1 -void GameSetupStruct::read_savegame_info(Common::Stream *in, GameDataVersion data_ver) { +void GameSetupStruct::read_savegame_info(Shared::Stream *in, GameDataVersion data_ver) { if (data_ver > kGameVersion_272) { // only 3.x in->Read(&guid[0], MAX_GUID_LENGTH); in->Read(&saveGameFileExtension[0], MAX_SG_EXT_LENGTH); @@ -115,7 +115,7 @@ void GameSetupStruct::read_savegame_info(Common::Stream *in, GameDataVersion dat } } -void GameSetupStruct::read_font_infos(Common::Stream *in, GameDataVersion data_ver) { +void GameSetupStruct::read_font_infos(Shared::Stream *in, GameDataVersion data_ver) { fonts.resize(numfonts); if (data_ver < kGameVersion_350) { for (int i = 0; i < numfonts; ++i) @@ -147,7 +147,7 @@ void GameSetupStruct::read_font_infos(Common::Stream *in, GameDataVersion data_v } void GameSetupStruct::ReadInvInfo_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) { invinfo[iteratorCount].ReadFromFile(&align_s); align_s.Reset(); @@ -155,14 +155,14 @@ void GameSetupStruct::ReadInvInfo_Aligned(Stream *in) { } void GameSetupStruct::WriteInvInfo_Aligned(Stream *out) { - AlignedStream align_s(out, Common::kAligned_Write); + AlignedStream align_s(out, Shared::kAligned_Write); for (int iteratorCount = 0; iteratorCount < numinvitems; ++iteratorCount) { invinfo[iteratorCount].WriteToFile(&align_s); align_s.Reset(); } } -HGameFileError GameSetupStruct::read_cursors(Common::Stream *in, GameDataVersion data_ver) { +HGameFileError GameSetupStruct::read_cursors(Shared::Stream *in, GameDataVersion data_ver) { if (numcursors > MAX_CURSOR) return new MainGameFileError(kMGFErr_TooManyCursors, String::FromFormat("Count: %d, max: %d", numcursors, MAX_CURSOR)); @@ -170,7 +170,7 @@ HGameFileError GameSetupStruct::read_cursors(Common::Stream *in, GameDataVersion return HGameFileError::None(); } -void GameSetupStruct::read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver) { +void GameSetupStruct::read_interaction_scripts(Shared::Stream *in, GameDataVersion data_ver) { numGlobalVars = 0; if (data_ver > kGameVersion_272) { // 3.x @@ -194,7 +194,7 @@ void GameSetupStruct::read_interaction_scripts(Common::Stream *in, GameDataVersi } } -void GameSetupStruct::read_words_dictionary(Common::Stream *in) { +void GameSetupStruct::read_words_dictionary(Shared::Stream *in) { if (load_dictionary) { dict = new WordsDictionary(); read_dictionary(dict, in); @@ -202,7 +202,7 @@ void GameSetupStruct::read_words_dictionary(Common::Stream *in) { } void GameSetupStruct::ReadMouseCursors_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) { mcurs[iteratorCount].ReadFromFile(&align_s); align_s.Reset(); @@ -210,7 +210,7 @@ void GameSetupStruct::ReadMouseCursors_Aligned(Stream *in) { } void GameSetupStruct::WriteMouseCursors_Aligned(Stream *out) { - AlignedStream align_s(out, Common::kAligned_Write); + AlignedStream align_s(out, Shared::kAligned_Write); for (int iteratorCount = 0; iteratorCount < numcursors; ++iteratorCount) { mcurs[iteratorCount].WriteToFile(&align_s); align_s.Reset(); @@ -220,18 +220,18 @@ void GameSetupStruct::WriteMouseCursors_Aligned(Stream *out) { //----------------------------------------------------------------------------- // Reading Part 2 -void GameSetupStruct::read_characters(Common::Stream *in, GameDataVersion data_ver) { +void GameSetupStruct::read_characters(Shared::Stream *in, GameDataVersion data_ver) { chars = new CharacterInfo[numcharacters + 5]; // TODO: why +5, is this really needed? ReadCharacters_Aligned(in); } -void GameSetupStruct::read_lipsync(Common::Stream *in, GameDataVersion data_ver) { +void GameSetupStruct::read_lipsync(Shared::Stream *in, GameDataVersion data_ver) { if (data_ver >= kGameVersion_254) // lip syncing was introduced in 2.54 in->ReadArray(&lipSyncFrameLetters[0][0], MAXLIPSYNCFRAMES, 50); } -void GameSetupStruct::read_messages(Common::Stream *in, GameDataVersion data_ver) { +void GameSetupStruct::read_messages(Shared::Stream *in, GameDataVersion data_ver) { for (int ee = 0; ee < MAXGLOBALMES; ee++) { if (!load_messages[ee]) continue; messages[ee] = new char[GLOBALMESLENGTH]; @@ -254,7 +254,7 @@ void GameSetupStruct::read_messages(Common::Stream *in, GameDataVersion data_ver } void GameSetupStruct::ReadCharacters_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) { chars[iteratorCount].ReadFromFile(&align_s); align_s.Reset(); @@ -262,7 +262,7 @@ void GameSetupStruct::ReadCharacters_Aligned(Stream *in) { } void GameSetupStruct::WriteCharacters_Aligned(Stream *out) { - AlignedStream align_s(out, Common::kAligned_Write); + AlignedStream align_s(out, Shared::kAligned_Write); for (int iteratorCount = 0; iteratorCount < numcharacters; ++iteratorCount) { chars[iteratorCount].WriteToFile(&align_s); align_s.Reset(); @@ -272,7 +272,7 @@ void GameSetupStruct::WriteCharacters_Aligned(Stream *out) { //----------------------------------------------------------------------------- // Reading Part 3 -HGameFileError GameSetupStruct::read_customprops(Common::Stream *in, GameDataVersion data_ver) { +HGameFileError GameSetupStruct::read_customprops(Shared::Stream *in, GameDataVersion data_ver) { dialogScriptNames.resize(numdialog); viewNames.resize(numviews); if (data_ver >= kGameVersion_260) { // >= 2.60 @@ -304,7 +304,7 @@ HGameFileError GameSetupStruct::read_customprops(Common::Stream *in, GameDataVer return HGameFileError::None(); } -HGameFileError GameSetupStruct::read_audio(Common::Stream *in, GameDataVersion data_ver) { +HGameFileError GameSetupStruct::read_audio(Shared::Stream *in, GameDataVersion data_ver) { if (data_ver >= kGameVersion_320) { size_t audiotype_count = in->ReadInt32(); audioClipTypes.resize(audiotype_count); @@ -342,8 +342,8 @@ void GameSetupStruct::read_room_names(Stream *in, GameDataVersion data_ver) { } } -void GameSetupStruct::ReadAudioClips_Aligned(Common::Stream *in, size_t count) { - AlignedStream align_s(in, Common::kAligned_Read); +void GameSetupStruct::ReadAudioClips_Aligned(Shared::Stream *in, size_t count) { + AlignedStream align_s(in, Shared::kAligned_Read); for (size_t i = 0; i < count; ++i) { audioClips[i].ReadFromFile(&align_s); align_s.Reset(); diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index 76a8be382742..af10c29ccf99 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -23,7 +23,8 @@ #ifndef AGS_SHARED_AC_GAMESETUPSTRUCT_H #define AGS_SHARED_AC_GAMESETUPSTRUCT_H -//include +#include "ags/std/vector.h" +#include "ags/std/memory.h" #include "ags/shared/ac/audiocliptype.h" #include "ags/shared/ac/characterinfo.h" // TODO: constants to separate header #include "ags/shared/ac/gamesetupstructbase.h" @@ -36,10 +37,10 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { struct AssetLibInfo; struct Interaction; -namespace SharedonScripts; +struct InteractionScripts; typedef std::shared_ptr PInteraction; typedef std::shared_ptr PInteractionScripts; } // namespace Shared @@ -128,39 +129,39 @@ struct GameSetupStruct : public GameSetupStructBase { // Do not call these directly //------------------------------ // Part 1 - void read_savegame_info(Common::Stream *in, GameDataVersion data_ver); - void read_font_infos(Common::Stream *in, GameDataVersion data_ver); - HGameFileError read_cursors(Common::Stream *in, GameDataVersion data_ver); - void read_interaction_scripts(Common::Stream *in, GameDataVersion data_ver); - void read_words_dictionary(Common::Stream *in); - - void ReadInvInfo_Aligned(Common::Stream *in); - void WriteInvInfo_Aligned(Common::Stream *out); - void ReadMouseCursors_Aligned(Common::Stream *in); - void WriteMouseCursors_Aligned(Common::Stream *out); + void read_savegame_info(Shared::Stream *in, GameDataVersion data_ver); + void read_font_infos(Shared::Stream *in, GameDataVersion data_ver); + HGameFileError read_cursors(Shared::Stream *in, GameDataVersion data_ver); + void read_interaction_scripts(Shared::Stream *in, GameDataVersion data_ver); + void read_words_dictionary(Shared::Stream *in); + + void ReadInvInfo_Aligned(Shared::Stream *in); + void WriteInvInfo_Aligned(Shared::Stream *out); + void ReadMouseCursors_Aligned(Shared::Stream *in); + void WriteMouseCursors_Aligned(Shared::Stream *out); //------------------------------ // Part 2 - void read_characters(Common::Stream *in, GameDataVersion data_ver); - void read_lipsync(Common::Stream *in, GameDataVersion data_ver); - void read_messages(Common::Stream *in, GameDataVersion data_ver); + void read_characters(Shared::Stream *in, GameDataVersion data_ver); + void read_lipsync(Shared::Stream *in, GameDataVersion data_ver); + void read_messages(Shared::Stream *in, GameDataVersion data_ver); - void ReadCharacters_Aligned(Common::Stream *in); - void WriteCharacters_Aligned(Common::Stream *out); + void ReadCharacters_Aligned(Shared::Stream *in); + void WriteCharacters_Aligned(Shared::Stream *out); //------------------------------ // Part 3 - HGameFileError read_customprops(Common::Stream *in, GameDataVersion data_ver); - HGameFileError read_audio(Common::Stream *in, GameDataVersion data_ver); - void read_room_names(Common::Stream *in, GameDataVersion data_ver); + HGameFileError read_customprops(Shared::Stream *in, GameDataVersion data_ver); + HGameFileError read_audio(Shared::Stream *in, GameDataVersion data_ver); + void read_room_names(Shared::Stream *in, GameDataVersion data_ver); - void ReadAudioClips_Aligned(Common::Stream *in, size_t count); + void ReadAudioClips_Aligned(Shared::Stream *in, size_t count); //-------------------------------------------------------------------- // Functions for reading and writing appropriate data from/to save game - void ReadFromSaveGame_v321(Common::Stream *in, char *gswas, ccScript *compsc, CharacterInfo *chwas, + void ReadFromSaveGame_v321(Shared::Stream *in, char *gswas, ccScript *compsc, CharacterInfo *chwas, WordsDictionary *olddict, char **mesbk); - void ReadFromSavegame(Common::PStream in); - void WriteForSavegame(Common::PStream out); + void ReadFromSavegame(Shared::PStream in); + void WriteForSavegame(Shared::PStream out); }; //============================================================================= diff --git a/engines/ags/shared/ac/gamesetupstructbase.h b/engines/ags/shared/ac/gamesetupstructbase.h index 045b751634d8..41656ed5ee2a 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.h +++ b/engines/ags/shared/ac/gamesetupstructbase.h @@ -70,13 +70,13 @@ struct GameSetupStructBase { int default_lipsync_frame; // used for unknown chars int invhotdotsprite; int reserved[NUM_INTS_RESERVED]; - char *messages[MAXGLOBALMES]; - WordsDictionary *dict; - char *globalscript; - CharacterInfo *chars; - ccScript *compiled_script; + char *messages[MAXGLOBALMES]; + WordsDictionary *dict; + char *globalscript; + CharacterInfo *chars; + ccScript *compiled_script; - int *load_messages; + int *load_messages; bool load_dictionary; bool load_compiled_script; // [IKM] 2013-03-30 @@ -91,8 +91,8 @@ struct GameSetupStructBase { void SetDefaultResolution(Size game_res); void SetGameResolution(GameResolutionType type); void SetGameResolution(Size game_res); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); // @@ -187,7 +187,7 @@ struct GameSetupStructBase { inline bool IsLegacyHiRes() const { if (_resolutionType == kGameResolution_Custom) return (_gameResolution.Width * _gameResolution.Height) > (320 * 240); - return ::IsLegacyHiRes(_resolutionType); + return AGS3::IsLegacyHiRes(_resolutionType); } // Tells if data has coordinates in default game resolution inline bool IsDataInNativeCoordinates() const { @@ -247,6 +247,6 @@ struct GameSetupStructBase { int _screenUpscaleMult; }; -// namespace AGS3 +} // namespace AGS3 #endif diff --git a/engines/ags/shared/ac/inventoryiteminfo.h b/engines/ags/shared/ac/inventoryiteminfo.h index e3f1ab577965..ee4786613b94 100644 --- a/engines/ags/shared/ac/inventoryiteminfo.h +++ b/engines/ags/shared/ac/inventoryiteminfo.h @@ -41,10 +41,10 @@ struct InventoryItemInfo { int reserved[5]; char flags; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); + void ReadFromSavegame(Shared::Stream *in); + void WriteToSavegame(Shared::Stream *out) const; }; } // namespace AGS3 diff --git a/engines/ags/shared/ac/mousecursor.h b/engines/ags/shared/ac/mousecursor.h index 7ae0ef406d3b..9e42fa0ea058 100644 --- a/engines/ags/shared/ac/mousecursor.h +++ b/engines/ags/shared/ac/mousecursor.h @@ -26,10 +26,10 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { class Stream; } // namespace Shared -namespace SharedGS +} // namespace AGS using namespace AGS; // FIXME later @@ -46,10 +46,10 @@ struct MouseCursor { char flags; MouseCursor(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); + void ReadFromSavegame(Shared::Stream *in); + void WriteToSavegame(Shared::Stream *out) const; }; } // namespace AGS3 diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp index 3d850d7fc3e2..496ba10b51da 100644 --- a/engines/ags/shared/ac/spritecache.cpp +++ b/engines/ags/shared/ac/spritecache.cpp @@ -41,6 +41,7 @@ #include "ags/shared/util/compress.h" #include "ags/shared/util/file.h" #include "ags/shared/util/stream.h" +#include "common/system.h" namespace AGS3 { @@ -172,7 +173,7 @@ void SpriteCache::SetEmptySprite(sprkey_t index, bool as_asset) { RemapSpriteToSprite0(index); } -void SpriteCache::SubstituteBitmap(sprkey_t index, Common::Bitmap *sprite) { +void SpriteCache::SubstituteBitmap(sprkey_t index, Shared::Bitmap *sprite) { if (!DoesSpriteExist(index)) { Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SubstituteBitmap: attempt to set for non-existing sprite %d", index); return; @@ -510,19 +511,19 @@ void SpriteCache::UnCompressSprite(Bitmap *sprite, Stream *in) { } int SpriteCache::SaveToFile(const char *filename, bool compressOutput, SpriteFileIndex &index) { - Stream *output = Common::File::CreateFile(filename); + Stream *output = Shared::File::CreateFile(filename); if (output == nullptr) return -1; if (compressOutput) { // re-open the file so that it can be seeked delete output; - output = File::OpenFile(filename, Common::kFile_Open, Common::kFile_ReadWrite); // CHECKME why mode was "r+" here? + output = File::OpenFile(filename, Shared::kFile_Open, Shared::kFile_ReadWrite); // CHECKME why mode was "r+" here? if (output == nullptr) return -1; } - int spriteFileIDCheck = (int)time(nullptr); + int spriteFileIDCheck = g_system->getMillis(); // sprite file version output->WriteInt16(kSprfVersion_Current); @@ -678,7 +679,7 @@ HError SpriteCache::InitFile(const char *filename, const char *sprindex_filename soff_t spr_initial_offs = 0; int spriteFileID = 0; - _stream.reset(Common::AssetManager::OpenAsset(filename)); + _stream.reset(Shared::AssetManager::OpenAsset(filename)); if (_stream == nullptr) return new Error(String::FromFormat("Failed to open spriteset file '%s'.", filename)); @@ -780,7 +781,7 @@ HError SpriteCache::RebuildSpriteIndex(AGS::Shared::Stream *in, sprkey_t topmost } bool SpriteCache::LoadSpriteIndexFile(const char *filename, int expectedFileID, soff_t spr_initial_offs, sprkey_t topmost) { - Stream *fidx = Common::AssetManager::OpenAsset(filename); + Stream *fidx = Shared::AssetManager::OpenAsset(filename); if (fidx == nullptr) { return false; } @@ -855,7 +856,7 @@ void SpriteCache::DetachFile() { } int SpriteCache::AttachFile(const char *filename) { - _stream.reset(Common::AssetManager::OpenAsset((char *)filename)); + _stream.reset(Shared::AssetManager::OpenAsset((char *)filename)); if (_stream == nullptr) return -1; return 0; diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index 5a0ebf0dffc1..4ee33e4f61d4 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -45,8 +45,8 @@ #ifndef AGS_SHARED_AC_SPRITECACHE_H #define AGS_SHARED_AC_SPRITECACHE_H -//include -//include +#include "ags/std/memory.h" +#include "ags/std/vector.h" #include "ags/shared/core/platform.h" #include "ags/shared/util/error.h" diff --git a/engines/ags/shared/ac/view.cpp b/engines/ags/shared/ac/view.cpp index 614258fb1d26..886e4c485972 100644 --- a/engines/ags/shared/ac/view.cpp +++ b/engines/ags/shared/ac/view.cpp @@ -93,7 +93,7 @@ void ViewLoopNew::WriteToFile_v321(Stream *out) { } void ViewLoopNew::WriteFrames_Aligned(Stream *out) { - AlignedStream align_s(out, Common::kAligned_Write); + AlignedStream align_s(out, Shared::kAligned_Write); for (int i = 0; i < numFrames; ++i) { frames[i].WriteToFile(&align_s); align_s.Reset(); @@ -111,7 +111,7 @@ void ViewLoopNew::ReadFromFile_v321(Stream *in) { } void ViewLoopNew::ReadFrames_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int i = 0; i < numFrames; ++i) { frames[i].ReadFromFile(&align_s); align_s.Reset(); diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index 41d27ebdd806..b30b406e585d 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_VIEW_H #define AGS_SHARED_AC_VIEW_H -//include +#include "ags/std/vector.h" namespace AGS3 { @@ -46,8 +46,8 @@ struct ViewFrame { int reserved_for_future[2]; ViewFrame(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); }; #define LOOPFLAG_RUNNEXTLOOP 1 @@ -61,10 +61,10 @@ struct ViewLoopNew { void Initialize(int frameCount); void Dispose(); bool RunNextLoop(); - void WriteToFile_v321(Common::Stream *out); - void ReadFromFile_v321(Common::Stream *in); - void WriteFrames_Aligned(Common::Stream *out); - void ReadFrames_Aligned(Common::Stream *in); + void WriteToFile_v321(Shared::Stream *out); + void ReadFromFile_v321(Shared::Stream *in); + void WriteFrames_Aligned(Shared::Stream *out); + void ReadFrames_Aligned(Shared::Stream *in); }; struct ViewStruct { @@ -74,8 +74,8 @@ struct ViewStruct { ViewStruct(); void Initialize(int loopCount); void Dispose(); - void WriteToFile(Common::Stream *out); - void ReadFromFile(Common::Stream *in); + void WriteToFile(Shared::Stream *out); + void ReadFromFile(Shared::Stream *in); }; struct ViewStruct272 { @@ -85,7 +85,7 @@ struct ViewStruct272 { ViewFrame frames[16][20]; ViewStruct272(); - void ReadFromFile(Common::Stream *in); + void ReadFromFile(Shared::Stream *in); }; void Convert272ViewsToNew(const std::vector &oldv, ViewStruct *newv); diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp index 9ea0a590ce7a..6ec5cfe5719e 100644 --- a/engines/ags/shared/ac/wordsdictionary.cpp +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -20,7 +20,7 @@ * */ -//include +#include "ags/std/algorithm.h" //include #include "ags/shared/ac/wordsdictionary.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/shared/ac/wordsdictionary.h b/engines/ags/shared/ac/wordsdictionary.h index db453aec60db..24ac7efce4a6 100644 --- a/engines/ags/shared/ac/wordsdictionary.h +++ b/engines/ags/shared/ac/wordsdictionary.h @@ -55,8 +55,8 @@ struct WordsDictionary { extern const char *passwencstring; extern void decrypt_text(char *toenc); -extern void read_string_decrypt(Common::Stream *in, char *buf, size_t buf_sz); -extern void read_dictionary(WordsDictionary *dict, Common::Stream *in); +extern void read_string_decrypt(Shared::Stream *in, char *buf, size_t buf_sz); +extern void read_dictionary(WordsDictionary *dict, Shared::Stream *in); #if defined (OBSOLETE) // TODO: not a part of wordsdictionary, move to obsoletes @@ -64,8 +64,8 @@ extern void freadmissout(short *pptr, Common::Stream *in); #endif extern void encrypt_text(char *toenc); -extern void write_string_encrypt(Common::Stream *out, const char *s); -extern void write_dictionary(WordsDictionary *dict, Common::Stream *out); +extern void write_string_encrypt(Shared::Stream *out, const char *s); +extern void write_dictionary(WordsDictionary *dict, Shared::Stream *out); } // namespace AGS3 diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index 34647cc30a8c..bcbed3a231a6 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_CORE_ASSET_H #define AGS_SHARED_CORE_ASSET_H -//include +#include "ags/std/vector.h" #include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index 97a7d89e6f7a..cb8c1257074c 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -47,8 +47,8 @@ #ifndef AGS_SHARED_DEBUGGING_DEBUGMANAGER_H #define AGS_SHARED_DEBUGGING_DEBUGMANAGER_H -//include -//include +#include "ags/std/memory.h" +#include "ags/std/map.h" #include "ags/shared/debugging/out.h" #include "ags/shared/debugging/outputhandler.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 5051c94db59a..0bc9c8505c63 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -21,7 +21,7 @@ */ //include -//include +#include "ags/std/vector.h" //include #include "ags/shared/ac/common.h" // set_our_eip #include "ags/shared/ac/gamestructdefines.h" diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index c3e92655889d..56dcb7d3c091 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_FONT_FONTS_H #define AGS_SHARED_FONT_FONTS_H -//include +#include "ags/std/vector.h" #include "ags/shared/core/types.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index daea4e32858d..ce76cda9e30e 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -20,7 +20,7 @@ * */ -//include +#include "ags/std/algorithm.h" #include "ags/shared/font/wfnfont.h" #include "ags/shared/debugging/out.h" #include "ags/shared/util/memory.h" diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index c3212f684c3c..583d30459877 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -46,7 +46,7 @@ #ifndef AGS_SHARED_FONT_WFNFONT_H #define AGS_SHARED_FONT_WFNFONT_H -//include +#include "ags/std/vector.h" #include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/shared/game/customproperties.cpp b/engines/ags/shared/game/customproperties.cpp index c56eac64f580..aeeffe5c8cbe 100644 --- a/engines/ags/shared/game/customproperties.cpp +++ b/engines/ags/shared/game/customproperties.cpp @@ -76,7 +76,7 @@ void WriteSchema(const PropertySchema &schema, Stream *out) { out->WriteInt32(schema.size()); for (PropertySchema::const_iterator it = schema.begin(); it != schema.end(); ++it) { - const PropertyDesc &prop = it->second; + const PropertyDesc &prop = it->_value; StrUtil::WriteString(prop.Name, out); out->WriteInt32(prop.Type); StrUtil::WriteString(prop.Description, out); @@ -111,8 +111,8 @@ void WriteValues(const StringIMap &map, Stream *out) { out->WriteInt32(map.size()); for (StringIMap::const_iterator it = map.begin(); it != map.end(); ++it) { - StrUtil::WriteString(it->first, out); - StrUtil::WriteString(it->second, out); + StrUtil::WriteString(it->_key, out); + StrUtil::WriteString(it->_value, out); } } diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index fd7515041aa4..7b956e9d792e 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -36,7 +36,7 @@ #ifndef AGS_SHARED_GAME_CUSTOMPROPERTIES_H #define AGS_SHARED_GAME_CUSTOMPROPERTIES_H -//include +#include "ags/std/map.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" @@ -87,7 +87,7 @@ struct PropertyDesc { // NOTE: AGS has case-insensitive property IDs // Schema - a map of property descriptions -typedef std::unordered_map PropertySchema; +typedef std::unordered_map PropertySchema; namespace Properties { diff --git a/engines/ags/shared/game/interactions.cpp b/engines/ags/shared/game/interactions.cpp index 6996c69dae2f..46021eb15094 100644 --- a/engines/ags/shared/game/interactions.cpp +++ b/engines/ags/shared/game/interactions.cpp @@ -80,7 +80,7 @@ void InteractionCommand::Reset() { } void InteractionCommand::ReadValues_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int i = 0; i < MAX_ACTION_ARGS; ++i) { Data[i].Read(&align_s); align_s.Reset(); @@ -96,7 +96,7 @@ void InteractionCommand::Read_v321(Stream *in, bool &has_children) { } void InteractionCommand::WriteValues_Aligned(Stream *out) const { - AlignedStream align_s(out, Common::kAligned_Write); + AlignedStream align_s(out, Shared::kAligned_Write); for (int i = 0; i < MAX_ACTION_ARGS; ++i) { Data[i].Write(&align_s); align_s.Reset(); @@ -139,7 +139,7 @@ void InteractionCommandList::Reset() { } void InteractionCommandList::Read_Aligned(Stream *in, std::vector &cmd_children) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (size_t i = 0; i < Cmds.size(); ++i) { bool has_children; Cmds[i].Read_v321(&align_s, has_children); @@ -167,7 +167,7 @@ void InteractionCommandList::Read_v321(Stream *in) { } void InteractionCommandList::Write_Aligned(Stream *out) const { - AlignedStream align_s(out, Common::kAligned_Write); + AlignedStream align_s(out, Shared::kAligned_Write); for (InterCmdVector::const_iterator it = Cmds.begin(); it != Cmds.end(); ++it) { it->Write_v321(&align_s); align_s.Reset(); @@ -351,7 +351,7 @@ void InteractionVariable::Read(Stream *in) { Value = in->ReadInt32(); } -void InteractionVariable::Write(Common::Stream *out) const { +void InteractionVariable::Write(Shared::Stream *out) const { out->Write(Name, INTER_VAR_NAME_LENGTH); out->WriteInt8(Type); out->WriteInt32(Value); diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index ad1278404ca9..ead5ec7a4856 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -49,8 +49,8 @@ #ifndef AGS_SHARED_GAME_INTEREACTIONS_H #define AGS_SHARED_GAME_INTEREACTIONS_H -//include #include "ags/shared/util/string_types.h" +#include "ags/std/memory.h" namespace AGS3 { @@ -130,8 +130,8 @@ struct InteractionCommandList { void Write_v321(Stream *out) const; protected: - void Read_Aligned(Common::Stream *in, std::vector &cmd_children); - void Write_Aligned(Common::Stream *out) const; + void Read_Aligned(Stream *in, std::vector &cmd_children); + void Write_Aligned(Stream *out) const; }; diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 93705bbade96..3fb86a794c10 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -31,9 +31,9 @@ #ifndef AGS_SHARED_GAME_MAINGAMEFILE_H #define AGS_SHARED_GAME_MAINGAMEFILE_H -//include -//include -//include +#include "ags/std/memory.h" +#include "ags/std/set.h" +#include "ags/std/vector.h" #include "ags/shared/ac/game_version.h" #include "ags/shared/game/plugininfo.h" #include "ags/shared/script/cc_script.h" diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index b10962dd5f0b..025ccd8ce6c9 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_GAME_PLUGININFO_H #define AGS_SHARED_GAME_PLUGININFO_H -//include +#include "ags/std/memory.h" #include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index 48796e19a64e..6ddbf9367079 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -411,7 +411,7 @@ HRoomFileError ReadCompSc3Block(RoomStruct *room, Stream *in, RoomFileVersion da // Room object names HRoomFileError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { int name_count = in->ReadByte(); - if (name_count != room->ObjectCount) + if (name_count != (int)room->ObjectCount) return new RoomFileError(kRoomFileErr_InconsistentData, String::FromFormat("In the object names block, expected name count: %d, got %d", room->ObjectCount, name_count)); @@ -525,7 +525,7 @@ HRoomFileError ReadRoomBlock(RoomStruct *room, Stream *in, RoomFileBlock block, } else if (cur_pos < block_end) { Debug::Printf(kDbgMsg_Warn, "WARNING: room data blocks nonsequential, block type %d expected to end at %u, finished reading at %u", block, block_end, cur_pos); - in->Seek(block_end, Common::kSeekBegin); + in->Seek(block_end, Shared::kSeekBegin); } return HRoomFileError::None(); } @@ -718,10 +718,10 @@ void WriteBlock(const RoomStruct *room, RoomFileBlock block, PfnWriteBlock write soff_t end_at = out->GetPosition(); soff_t block_size = (end_at - sz_at) - sizeof(int64_t); // ...return back and write block's size in the placeholder - out->Seek(sz_at, Common::kSeekBegin); + out->Seek(sz_at, Shared::kSeekBegin); out->WriteInt64(block_size); // ...and get back to the end of the file - out->Seek(0, Common::kSeekEnd); + out->Seek(0, Shared::kSeekEnd); } void WriteInteractionScripts(const InteractionScripts *interactions, Stream *out) { @@ -742,9 +742,9 @@ void WriteMainBlock(const RoomStruct *room, Stream *out) { out->WriteInt16(room->Hotspots[i].WalkTo.Y); } for (size_t i = 0; i < room->HotspotCount; ++i) - Common::StrUtil::WriteString(room->Hotspots[i].Name, out); + Shared::StrUtil::WriteString(room->Hotspots[i].Name, out); for (size_t i = 0; i < room->HotspotCount; ++i) - Common::StrUtil::WriteString(room->Hotspots[i].ScriptName, out); + Shared::StrUtil::WriteString(room->Hotspots[i].ScriptName, out); out->WriteInt32(0); // legacy poly-point areas @@ -828,13 +828,13 @@ void WriteCompSc3Block(const RoomStruct *room, Stream *out) { void WriteObjNamesBlock(const RoomStruct *room, Stream *out) { out->WriteByte((int8_t)room->ObjectCount); for (size_t i = 0; i < room->ObjectCount; ++i) - Common::StrUtil::WriteString(room->Objects[i].Name, out); + Shared::StrUtil::WriteString(room->Objects[i].Name, out); } void WriteObjScNamesBlock(const RoomStruct *room, Stream *out) { out->WriteByte((int8_t)room->ObjectCount); for (size_t i = 0; i < room->ObjectCount; ++i) - Common::StrUtil::WriteString(room->Objects[i].ScriptName, out); + Shared::StrUtil::WriteString(room->Objects[i].ScriptName, out); } void WriteAnimBgBlock(const RoomStruct *room, Stream *out) { diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index e191e8547082..1de92c364b05 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -31,8 +31,8 @@ #ifndef AGS_SHARED_GAME_ROOMFILE_H #define AGS_SHARED_GAME_ROOMFILE_H -//include -//include +#include "ags/std/memory.h" +#include "ags/std/vector.h" #include "ags/shared/game/room_version.h" #include "ags/shared/util/error.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index 59f42ea82951..40bd7dd461b4 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -48,11 +48,11 @@ #ifndef AGS_SHARED_GAME_ROOMINFO_H #define AGS_SHARED_GAME_ROOMINFO_H -//include #include "ags/shared/ac/common_defines.h" #include "ags/shared/game/interactions.h" #include "ags/shared/util/geometry.h" #include "ags/shared/util/wgt2allg.h" // color (allegro RGB) +#include "ags/std/memory.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index 955df3c5c629..ab03e4fd23a2 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUIBUTTON_H #define AGS_SHARED_GUI_GUIBUTTON_H -//include +#include "ags/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index ba16d7a59633..7ab166063ee4 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUIINV_H #define AGS_SHARED_GUI_GUIINV_H -//include +#include "ags/std/vector.h" #include "ags/shared/gui/guiobject.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index 836b473a4b4e..82d7b7538d66 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUILABEL_H #define AGS_SHARED_GUI_GUILABEL_H -//include +#include "ags/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index 090184ba04ea..52193b6af472 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUILISTBOX_H #define AGS_SHARED_GUI_GUILISTBOX_H -//include +#include "ags/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index 3eea0c3a3992..5cbb4fc00d1f 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUISLIDER_H #define AGS_SHARED_GUI_GUISLIDER_H -//include +#include "ags/std/vector.h" #include "ags/shared/gui/guiobject.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index b1906cc86100..53b830590aa6 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUITEXTBOX_H #define AGS_SHARED_GUI_GUITEXTBOX_H -//include +#include "ags/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" From 7f8f3c35905db2610b41d7b122f5f7a8c6f33be7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 18:53:05 -0800 Subject: [PATCH 017/215] AGS: Added shared/core/ folder --- engines/ags/module.mk | 2 ++ engines/ags/shared/core/assetmanager.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index f039ffe63f19..6bc49486b991 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -32,6 +32,8 @@ MODULE_OBJS = \ shared/ac/spritecache.o \ shared/ac/view.o \ shared/ac/wordsdictionary.o \ + shared/core/asset.o \ + shared/core/assetmanager.o \ shared/gfx/allegrobitmap.o \ shared/gfx/bitmap.o \ shared/gfx/image.o \ diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp index 28b8d0a37cb6..e3f62a8f1697 100644 --- a/engines/ags/shared/core/assetmanager.cpp +++ b/engines/ags/shared/core/assetmanager.cpp @@ -67,7 +67,7 @@ AssetManager::~AssetManager() { } /* static */ bool AssetManager::IsDataFile(const String &data_file) { - Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + Stream *in = ci_fopen(data_file, Shared::kFile_Open, Shared::kFile_Read); if (in) { MFLUtil::MFLError err = MFLUtil::TestIsMFL(in, true); delete in; @@ -77,7 +77,7 @@ AssetManager::~AssetManager() { } AssetError AssetManager::ReadDataFileTOC(const String &data_file, AssetLibInfo &lib) { - Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + Stream *in = ci_fopen(data_file, Shared::kFile_Open, Shared::kFile_Read); if (in) { MFLUtil::MFLError err = MFLUtil::ReadHeader(lib, in); delete in; @@ -248,7 +248,7 @@ AssetError AssetManager::RegisterAssetLib(const String &data_file, const String _basePath = "."; // open data library - Stream *in = ci_fopen(data_file, Common::kFile_Open, Common::kFile_Read); + Stream *in = ci_fopen(data_file, Shared::kFile_Open, Shared::kFile_Read); if (!in) return kAssetErrNoLibFile; // can't be opened, return error code @@ -300,7 +300,7 @@ String AssetManager::MakeLibraryFileNameForAsset(const AssetInfo *asset) { } bool AssetManager::GetAssetFromLib(const String &asset_name, AssetLocation &loc, FileOpenMode open_mode, FileWorkMode work_mode) { - if (open_mode != Common::kFile_Open || work_mode != Common::kFile_Read) + if (open_mode != Shared::kFile_Open || work_mode != Shared::kFile_Read) return false; // creating/writing is allowed only for common files on disk AssetInfo *asset = FindAssetByFileName(asset_name); From 3afa102f9abed01e24d1599999cb10dcdc9b6324 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 19:01:09 -0800 Subject: [PATCH 018/215] AGS: Added shared/debugging/ folder --- engines/ags/module.mk | 1 + engines/ags/shared/debugging/debugmanager.cpp | 14 +++++++------- engines/ags/shared/debugging/debugmanager.h | 6 +++--- engines/ags/shared/debugging/outputhandler.h | 8 ++++---- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 6bc49486b991..edb48894ef2c 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -34,6 +34,7 @@ MODULE_OBJS = \ shared/ac/wordsdictionary.o \ shared/core/asset.o \ shared/core/assetmanager.o \ + shared/debugging/debugmanager.o \ shared/gfx/allegrobitmap.o \ shared/gfx/bitmap.o \ shared/gfx/image.o \ diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp index d6106531cddc..f1889e2ab865 100644 --- a/engines/ags/shared/debugging/debugmanager.cpp +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -64,7 +64,7 @@ void DebugOutput::SetAllGroupFilters(MessageType verbosity) { for (auto &group : _groupFilter) group = verbosity; for (auto &group : _unresolvedGroups) - group.second = verbosity; + group._value = verbosity; } void DebugOutput::ClearGroupFilters() { @@ -83,7 +83,7 @@ void DebugOutput::ResolveGroupID(DebugGroupID id) { _groupFilter.resize(id.ID + 1, _defaultVerbosity); GroupNameToMTMap::const_iterator it = _unresolvedGroups.find(real_id.SID); if (it != _unresolvedGroups.end()) { - _groupFilter[real_id.ID] = it->second; + _groupFilter[real_id.ID] = it->_value; _unresolvedGroups.erase(it); } } @@ -112,14 +112,14 @@ DebugGroup DebugManager::GetGroup(DebugGroupID id) { return id.ID < _groups.size() ? _groups[id.ID] : DebugGroup(); } else if (!id.SID.IsEmpty()) { GroupByStringMap::const_iterator it = _groupByStrLookup.find(id.SID); - return it != _groupByStrLookup.end() ? _groups[it->second.ID] : DebugGroup(); + return it != _groupByStrLookup.end() ? _groups[it->_value.ID] : DebugGroup(); } return DebugGroup(); } PDebugOutput DebugManager::GetOutput(const String &id) { OutMap::const_iterator it = _outputs.find(id); - return it != _outputs.end() ? it->second.Target : PDebugOutput(); + return it != _outputs.end() ? it->_value.Target : PDebugOutput(); } DebugGroup DebugManager::RegisterGroup(const String &id, const String &out_name) { @@ -132,7 +132,7 @@ DebugGroup DebugManager::RegisterGroup(const String &id, const String &out_name) // Resolve group reference on every output target for (OutMap::const_iterator it = _outputs.begin(); it != _outputs.end(); ++it) { - it->second.Target->ResolveGroupID(group.UID); + it->_value.Target->ResolveGroupID(group.UID); } return group; } @@ -172,14 +172,14 @@ void DebugManager::Print(DebugGroupID group_id, MessageType mt, const String &te DebugMessage msg(text, group.UID.ID, group.OutputName, mt); for (OutMap::iterator it = _outputs.begin(); it != _outputs.end(); ++it) { - SendMessage(it->second, msg); + SendMessage(it->_value, msg); } } void DebugManager::SendMessage(const String &out_id, const DebugMessage &msg) { OutMap::iterator it = _outputs.find(out_id); if (it != _outputs.end()) - SendMessage(it->second, msg); + SendMessage(it->_value, msg); } void DebugManager::SendMessage(OutputSlot &out, const DebugMessage &msg) { diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index cb8c1257074c..eefa9aac0172 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -100,7 +100,7 @@ class DebugOutput { // Set of permitted groups' numeric IDs std::vector _groupFilter; // Set of unresolved groups, which numeric IDs are not yet known - typedef std::unordered_map GroupNameToMTMap; + typedef std::unordered_map GroupNameToMTMap; GroupNameToMTMap _unresolvedGroups; }; @@ -149,8 +149,8 @@ class DebugManager { }; typedef std::vector GroupVector; - typedef std::unordered_map GroupByStringMap; - typedef std::unordered_map OutMap; + typedef std::unordered_map GroupByStringMap; + typedef std::unordered_map OutMap; void RegisterGroup(const DebugGroup &id); void SendMessage(OutputSlot &out, const DebugMessage &msg); diff --git a/engines/ags/shared/debugging/outputhandler.h b/engines/ags/shared/debugging/outputhandler.h index 635932b7fba5..8e51ab19b3d9 100644 --- a/engines/ags/shared/debugging/outputhandler.h +++ b/engines/ags/shared/debugging/outputhandler.h @@ -35,15 +35,15 @@ namespace AGS3 { namespace AGS { -namespace Common { +namespace Shared { struct DebugMessage { String Text; -namespace SharedoupID; + uint32_t GroupID; String GroupName; MessageType MT; - DebugMessage() : GroupID(kDbgGroup_None), MT(kDbgMsg_None) { + DebugMessage() : GroupID((uint32_t)kDbgGroup_None), MT(kDbgMsg_None) { } DebugMessage(const String &text, uint32_t group_id, const String &group_name, MessageType mt) : Text(text) @@ -62,7 +62,7 @@ class IOutputHandler { virtual void PrintMessage(const DebugMessage &msg) = 0; }; -} // namespace Common +} // namespace Shared } // namespace AGS } // namespace AGS3 From 2aacd282bedcda2af7e7b2c9da877bbe7709e3b4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 19:04:25 -0800 Subject: [PATCH 019/215] AGS: Adding shared/game/ folder --- engines/ags/module.mk | 5 ++++ engines/ags/shared/game/main_game_file.cpp | 29 ++++++++++++---------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index edb48894ef2c..4c650f9b43f3 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -35,6 +35,11 @@ MODULE_OBJS = \ shared/core/asset.o \ shared/core/assetmanager.o \ shared/debugging/debugmanager.o \ + shared/game/customproperties.o \ + shared/game/interactions.o \ + shared/game/room_file.o \ + shared/game/room_file_deprecated.o \ + shared/game/roomstruct.o \ shared/gfx/allegrobitmap.o \ shared/gfx/bitmap.o \ shared/gfx/image.o \ diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 436c24ba4140..276aceb53cc2 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -20,7 +20,6 @@ * */ -//include #include "ags/shared/ac/audiocliptype.h" #include "ags/shared/ac/dialogtopic.h" #include "ags/shared/ac/gamesetupstruct.h" @@ -34,10 +33,12 @@ #include "ags/shared/gui/guimain.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/directory.h" #include "ags/shared/util/path.h" #include "ags/shared/util/string_compat.h" #include "ags/shared/util/string_utils.h" #include "ags/shared/font/fonts.h" +#include "common/fs.h" namespace AGS3 { namespace AGS { @@ -204,7 +205,7 @@ HGameFileError ReadScriptModules(std::vector &sc_mods, Stream *in, Game } void ReadViewStruct272_Aligned(std::vector &oldv, Stream *in, size_t count) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); oldv.resize(count); for (size_t i = 0; i < count; ++i) { oldv[i].ReadFromFile(&align_s); @@ -434,7 +435,7 @@ void UpgradeFonts(GameSetupStruct &game, GameDataVersion data_ver) { } } if (data_ver < kGameVersion_351) { - for (size_t font = 0; font < game.numfonts; font++) { + for (size_t font = 0; font < (size_t)game.numfonts; font++) { FontInfo &finfo = game.fonts[font]; // Thickness that corresponds to 1 game pixel finfo.AutoOutlineThickness = @@ -498,15 +499,16 @@ void UpgradeAudio(GameSetupStruct &game, GameDataVersion data_ver) { } } // Append contents of the game directory - // TODO: use explicit path instead of cwd? keep this consistent with AssetManager! { - al_ffblk ff; - if (al_findfirst("*.*", &ff, FA_ALL & ~(FA_DIREC)) == 0) { - do { - if (ags_strnicmp(ff.name, "music", 5) == 0 || ags_strnicmp(ff.name, "sound", 5) == 0) - assets.push_back(ff.name); - } while (al_findnext(&ff) == 0); - al_findclose(&ff); + Common::FSNode folder(Directory::GetCurrentDirectory().GetNullableCStr()); + Common::FSList files; + folder.getChildren(files, Common::FSNode::kListFilesOnly); + + for (uint idx = 0; idx < files.size(); ++idx) { + Common::String name = files[idx].getName(); + if (name.hasPrefixIgnoreCase("music") || name.hasPrefixIgnoreCase("sound")) { + assets.push_back(name); + } } } BuildAudioClipArray(assets, audioclips); @@ -627,7 +629,8 @@ HGameFileError ReadSpriteFlags(LoadedGameEntities &ents, Stream *in, GameDataVer else sprcount = in->ReadInt32(); if (sprcount > (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1) - return new MainGameFileError(kMGFErr_TooManySprites, String::FromFormat("Count: %u, max: %u", sprcount, (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1)); + return new MainGameFileError(kMGFErr_TooManySprites, String::FromFormat("Count: %u, max: %u", + sprcount, (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1)); ents.SpriteCount = sprcount; ents.SpriteFlags.reset(new char[sprcount]); @@ -639,7 +642,7 @@ HGameFileError ReadGameData(LoadedGameEntities &ents, Stream *in, GameDataVersio GameSetupStruct &game = ents.Game; { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); game.GameSetupStructBase::ReadFromFile(&align_s); } From 1b9ac49fc01d083a28cff22e77f1fb84d1f2d026 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 22 Nov 2020 20:31:43 -0800 Subject: [PATCH 020/215] AGS: Beginnings of engine/ inclusion --- engines/ags/engine/ac/asset_helper.h | 6 +- engines/ags/engine/ac/audiochannel.cpp | 22 +- engines/ags/engine/ac/audiochannel.h | 4 +- engines/ags/engine/ac/audioclip.cpp | 20 +- engines/ags/engine/ac/audioclip.h | 4 +- engines/ags/engine/ac/button.cpp | 32 +-- engines/ags/engine/ac/button.h | 2 +- engines/ags/engine/ac/cdaudio.cpp | 4 +- engines/ags/engine/ac/character.cpp | 96 ++++---- engines/ags/engine/ac/character.h | 18 +- engines/ags/engine/ac/charactercache.h | 7 +- engines/ags/engine/ac/characterextras.cpp | 4 +- engines/ags/engine/ac/characterextras.h | 6 +- .../ags/engine/ac/characterinfo_engine.cpp | 28 +-- engines/ags/engine/ac/datetime.cpp | 14 +- engines/ags/engine/ac/datetime.h | 2 +- engines/ags/engine/ac/dialog.cpp | 86 +++---- engines/ags/engine/ac/dialog.h | 4 +- .../ags/engine/ac/dialogoptionsrendering.cpp | 20 +- .../ags/engine/ac/dialogoptionsrendering.h | 4 +- engines/ags/engine/ac/display.cpp | 70 +++--- engines/ags/engine/ac/display.h | 14 +- engines/ags/engine/ac/draw.cpp | 104 ++++----- engines/ags/engine/ac/draw.h | 42 ++-- engines/ags/engine/ac/draw_software.cpp | 10 +- engines/ags/engine/ac/draw_software.h | 6 +- engines/ags/engine/ac/drawingsurface.cpp | 48 ++-- engines/ags/engine/ac/drawingsurface.h | 2 +- engines/ags/engine/ac/dynamicsprite.cpp | 46 ++-- engines/ags/engine/ac/dynamicsprite.h | 6 +- .../ags/engine/ac/dynobj/all_dynamicclasses.h | 24 +- .../ags/engine/ac/dynobj/all_scriptclasses.h | 30 +-- .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 10 +- .../engine/ac/dynobj/cc_agsdynamicobject.h | 2 +- .../ags/engine/ac/dynobj/cc_audiochannel.cpp | 6 +- .../ags/engine/ac/dynobj/cc_audiochannel.h | 2 +- engines/ags/engine/ac/dynobj/cc_audioclip.cpp | 6 +- engines/ags/engine/ac/dynobj/cc_audioclip.h | 2 +- engines/ags/engine/ac/dynobj/cc_character.cpp | 10 +- engines/ags/engine/ac/dynobj/cc_character.h | 2 +- engines/ags/engine/ac/dynobj/cc_dialog.cpp | 8 +- engines/ags/engine/ac/dynobj/cc_dialog.h | 2 +- .../ags/engine/ac/dynobj/cc_dynamicarray.cpp | 4 +- .../ags/engine/ac/dynobj/cc_dynamicarray.h | 4 +- .../ags/engine/ac/dynobj/cc_dynamicobject.cpp | 16 +- .../ags/engine/ac/dynobj/cc_dynamicobject.h | 8 +- .../cc_dynamicobject_addr_and_manager.h | 4 +- engines/ags/engine/ac/dynobj/cc_gui.cpp | 4 +- engines/ags/engine/ac/dynobj/cc_gui.h | 2 +- engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 8 +- engines/ags/engine/ac/dynobj/cc_guiobject.h | 2 +- engines/ags/engine/ac/dynobj/cc_hotspot.cpp | 8 +- engines/ags/engine/ac/dynobj/cc_hotspot.h | 2 +- engines/ags/engine/ac/dynobj/cc_inventory.cpp | 6 +- engines/ags/engine/ac/dynobj/cc_inventory.h | 2 +- engines/ags/engine/ac/dynobj/cc_object.cpp | 8 +- engines/ags/engine/ac/dynobj/cc_object.h | 2 +- engines/ags/engine/ac/dynobj/cc_region.cpp | 8 +- engines/ags/engine/ac/dynobj/cc_region.h | 2 +- .../ags/engine/ac/dynobj/cc_serializer.cpp | 26 +-- engines/ags/engine/ac/dynobj/cc_serializer.h | 2 +- .../engine/ac/dynobj/managedobjectpool.cpp | 18 +- .../ags/engine/ac/dynobj/managedobjectpool.h | 14 +- engines/ags/engine/ac/dynobj/scriptcamera.cpp | 6 +- engines/ags/engine/ac/dynobj/scriptcamera.h | 2 +- .../ags/engine/ac/dynobj/scriptdatetime.cpp | 2 +- engines/ags/engine/ac/dynobj/scriptdatetime.h | 2 +- .../dynobj/scriptdialogoptionsrendering.cpp | 2 +- .../ac/dynobj/scriptdialogoptionsrendering.h | 2 +- engines/ags/engine/ac/dynobj/scriptdict.cpp | 2 +- engines/ags/engine/ac/dynobj/scriptdict.h | 12 +- .../engine/ac/dynobj/scriptdrawingsurface.cpp | 18 +- .../engine/ac/dynobj/scriptdrawingsurface.h | 12 +- .../engine/ac/dynobj/scriptdynamicsprite.cpp | 4 +- .../engine/ac/dynobj/scriptdynamicsprite.h | 2 +- engines/ags/engine/ac/dynobj/scriptfile.cpp | 4 +- engines/ags/engine/ac/dynobj/scriptfile.h | 8 +- engines/ags/engine/ac/dynobj/scriptobject.h | 2 +- .../ags/engine/ac/dynobj/scriptoverlay.cpp | 10 +- engines/ags/engine/ac/dynobj/scriptoverlay.h | 2 +- engines/ags/engine/ac/dynobj/scriptset.cpp | 2 +- engines/ags/engine/ac/dynobj/scriptset.h | 12 +- engines/ags/engine/ac/dynobj/scriptstring.cpp | 8 +- engines/ags/engine/ac/dynobj/scriptstring.h | 2 +- .../ags/engine/ac/dynobj/scriptuserobject.cpp | 4 +- .../ags/engine/ac/dynobj/scriptuserobject.h | 2 +- .../ags/engine/ac/dynobj/scriptviewframe.cpp | 2 +- .../ags/engine/ac/dynobj/scriptviewframe.h | 2 +- .../ags/engine/ac/dynobj/scriptviewport.cpp | 6 +- engines/ags/engine/ac/dynobj/scriptviewport.h | 2 +- engines/ags/engine/ac/event.cpp | 42 ++-- engines/ags/engine/ac/event.h | 4 +- engines/ags/engine/ac/file.cpp | 58 ++--- engines/ags/engine/ac/file.h | 4 +- engines/ags/engine/ac/game.cpp | 164 +++++++------- engines/ags/engine/ac/game.h | 30 +-- engines/ags/engine/ac/gamesetup.cpp | 4 +- engines/ags/engine/ac/gamesetup.h | 4 +- engines/ags/engine/ac/gamestate.cpp | 46 ++-- engines/ags/engine/ac/gamestate.h | 35 ++- engines/ags/engine/ac/global_api.cpp | 110 ++++----- engines/ags/engine/ac/global_audio.cpp | 30 +-- engines/ags/engine/ac/global_button.cpp | 14 +- engines/ags/engine/ac/global_character.cpp | 40 ++-- engines/ags/engine/ac/global_character.h | 2 +- engines/ags/engine/ac/global_datetime.cpp | 8 +- engines/ags/engine/ac/global_debug.cpp | 52 ++--- engines/ags/engine/ac/global_debug.h | 3 +- engines/ags/engine/ac/global_dialog.cpp | 20 +- engines/ags/engine/ac/global_display.cpp | 40 ++-- engines/ags/engine/ac/global_display.h | 2 +- .../ags/engine/ac/global_drawingsurface.cpp | 32 +-- engines/ags/engine/ac/global_drawingsurface.h | 2 +- .../ags/engine/ac/global_dynamicsprite.cpp | 18 +- engines/ags/engine/ac/global_file.cpp | 22 +- engines/ags/engine/ac/global_file.h | 4 +- engines/ags/engine/ac/global_game.cpp | 96 ++++---- engines/ags/engine/ac/global_game.h | 2 +- engines/ags/engine/ac/global_gui.cpp | 30 +-- engines/ags/engine/ac/global_hotspot.cpp | 32 +-- .../ags/engine/ac/global_inventoryitem.cpp | 26 +-- engines/ags/engine/ac/global_invwindow.cpp | 12 +- engines/ags/engine/ac/global_label.cpp | 12 +- engines/ags/engine/ac/global_listbox.cpp | 8 +- engines/ags/engine/ac/global_mouse.cpp | 4 +- engines/ags/engine/ac/global_object.cpp | 48 ++-- engines/ags/engine/ac/global_object.h | 2 +- engines/ags/engine/ac/global_overlay.cpp | 28 +-- engines/ags/engine/ac/global_palette.cpp | 10 +- engines/ags/engine/ac/global_parser.cpp | 10 +- engines/ags/engine/ac/global_record.cpp | 4 +- engines/ags/engine/ac/global_region.cpp | 20 +- engines/ags/engine/ac/global_room.cpp | 36 +-- engines/ags/engine/ac/global_screen.cpp | 28 +-- engines/ags/engine/ac/global_slider.cpp | 12 +- engines/ags/engine/ac/global_string.cpp | 14 +- engines/ags/engine/ac/global_textbox.cpp | 14 +- engines/ags/engine/ac/global_timer.cpp | 8 +- engines/ags/engine/ac/global_translation.cpp | 24 +- engines/ags/engine/ac/global_video.cpp | 22 +- engines/ags/engine/ac/global_viewframe.cpp | 12 +- engines/ags/engine/ac/global_viewport.cpp | 6 +- engines/ags/engine/ac/global_walkablearea.cpp | 14 +- engines/ags/engine/ac/global_walkbehind.cpp | 14 +- engines/ags/engine/ac/gui.cpp | 74 +++---- engines/ags/engine/ac/gui.h | 4 +- engines/ags/engine/ac/guicontrol.cpp | 34 +-- engines/ags/engine/ac/guicontrol.h | 16 +- engines/ags/engine/ac/guiinv.cpp | 16 +- engines/ags/engine/ac/hotspot.cpp | 32 +-- engines/ags/engine/ac/hotspot.h | 2 +- engines/ags/engine/ac/interfacebutton.cpp | 2 +- engines/ags/engine/ac/interfaceelement.cpp | 4 +- engines/ags/engine/ac/inventoryitem.cpp | 32 +-- engines/ags/engine/ac/inventoryitem.h | 2 +- engines/ags/engine/ac/invwindow.cpp | 54 ++--- engines/ags/engine/ac/invwindow.h | 6 +- engines/ags/engine/ac/keycode.cpp | 2 +- engines/ags/engine/ac/keycode.h | 2 +- engines/ags/engine/ac/label.cpp | 20 +- engines/ags/engine/ac/label.h | 2 +- engines/ags/engine/ac/listbox.cpp | 30 +-- engines/ags/engine/ac/listbox.h | 2 +- engines/ags/engine/ac/math.cpp | 14 +- engines/ags/engine/ac/math.h | 2 +- engines/ags/engine/ac/mouse.cpp | 50 ++--- engines/ags/engine/ac/mouse.h | 2 +- engines/ags/engine/ac/movelist.cpp | 6 +- engines/ags/engine/ac/movelist.h | 10 +- engines/ags/engine/ac/object.cpp | 58 ++--- engines/ags/engine/ac/object.h | 6 +- engines/ags/engine/ac/objectcache.h | 2 +- engines/ags/engine/ac/overlay.cpp | 42 ++-- engines/ags/engine/ac/overlay.h | 10 +- engines/ags/engine/ac/parser.cpp | 30 +-- engines/ags/engine/ac/path_helper.h | 2 +- engines/ags/engine/ac/properties.cpp | 14 +- engines/ags/engine/ac/properties.h | 2 +- engines/ags/engine/ac/region.cpp | 28 +-- engines/ags/engine/ac/region.h | 2 +- engines/ags/engine/ac/richgamemedia.cpp | 4 +- engines/ags/engine/ac/richgamemedia.h | 4 +- engines/ags/engine/ac/room.cpp | 120 +++++----- engines/ags/engine/ac/room.h | 8 +- engines/ags/engine/ac/roomobject.cpp | 18 +- engines/ags/engine/ac/roomobject.h | 6 +- engines/ags/engine/ac/roomstatus.cpp | 18 +- engines/ags/engine/ac/roomstatus.h | 22 +- engines/ags/engine/ac/route_finder.cpp | 8 +- engines/ags/engine/ac/route_finder.h | 2 +- engines/ags/engine/ac/route_finder_impl.cpp | 18 +- engines/ags/engine/ac/route_finder_impl.h | 2 +- .../engine/ac/route_finder_impl_legacy.cpp | 18 +- engines/ags/engine/ac/route_finder_jps.inl | 14 +- engines/ags/engine/ac/runtime_defines.h | 2 +- engines/ags/engine/ac/screen.cpp | 30 +-- engines/ags/engine/ac/screenoverlay.cpp | 4 +- engines/ags/engine/ac/screenoverlay.h | 9 +- engines/ags/engine/ac/scriptcontainers.cpp | 20 +- engines/ags/engine/ac/slider.cpp | 10 +- engines/ags/engine/ac/slider.h | 2 +- engines/ags/engine/ac/speech.cpp | 22 +- engines/ags/engine/ac/sprite.cpp | 22 +- engines/ags/engine/ac/sprite.h | 4 +- engines/ags/engine/ac/spritecache_engine.cpp | 6 +- engines/ags/engine/ac/spritelistentry.h | 2 +- .../ags/engine/ac/statobj/agsstaticobject.cpp | 8 +- .../ags/engine/ac/statobj/agsstaticobject.h | 2 +- engines/ags/engine/ac/statobj/staticarray.cpp | 6 +- engines/ags/engine/ac/statobj/staticarray.h | 2 +- engines/ags/engine/ac/statobj/staticobject.h | 2 +- engines/ags/engine/ac/string.cpp | 34 +-- engines/ags/engine/ac/string.h | 4 +- engines/ags/engine/ac/sys_events.cpp | 20 +- engines/ags/engine/ac/system.cpp | 48 ++-- engines/ags/engine/ac/system.h | 2 +- engines/ags/engine/ac/textbox.cpp | 18 +- engines/ags/engine/ac/textbox.h | 2 +- engines/ags/engine/ac/timer.cpp | 14 +- engines/ags/engine/ac/timer.h | 7 +- engines/ags/engine/ac/translation.cpp | 30 +-- engines/ags/engine/ac/translation.h | 2 +- engines/ags/engine/ac/tree_map.cpp | 8 +- engines/ags/engine/ac/viewframe.cpp | 26 +-- engines/ags/engine/ac/viewframe.h | 12 +- engines/ags/engine/ac/viewport_script.cpp | 16 +- engines/ags/engine/ac/walkablearea.cpp | 24 +- engines/ags/engine/ac/walkablearea.h | 2 +- engines/ags/engine/ac/walkbehind.cpp | 12 +- .../engine/debugging/consoleoutputtarget.cpp | 6 +- .../engine/debugging/consoleoutputtarget.h | 6 +- engines/ags/engine/debugging/debug.cpp | 55 ++--- engines/ags/engine/debugging/debug_log.h | 10 +- engines/ags/engine/debugging/debugger.h | 2 +- .../ags/engine/debugging/dummyagsdebugger.h | 2 +- .../engine/debugging/filebasedagsdebugger.cpp | 34 ++- .../engine/debugging/filebasedagsdebugger.h | 2 +- engines/ags/engine/debugging/logfile.cpp | 16 +- engines/ags/engine/debugging/logfile.h | 12 +- .../ags/engine/debugging/messagebuffer.cpp | 4 +- engines/ags/engine/debugging/messagebuffer.h | 8 +- engines/ags/engine/device/mousew32.cpp | 28 +-- engines/ags/engine/device/mousew32.h | 6 +- engines/ags/engine/font/fonts_engine.cpp | 4 +- engines/ags/engine/game/game_init.cpp | 60 ++--- engines/ags/engine/game/game_init.h | 4 +- engines/ags/engine/game/savegame.cpp | 82 +++---- engines/ags/engine/game/savegame.h | 20 +- .../ags/engine/game/savegame_components.cpp | 78 +++---- engines/ags/engine/game/savegame_components.h | 6 +- engines/ags/engine/game/savegame_internal.h | 10 +- engines/ags/engine/game/viewport.cpp | 10 +- engines/ags/engine/game/viewport.h | 8 +- engines/ags/engine/gfx/ali3dogl.cpp | 22 +- engines/ags/engine/gfx/ali3dogl.h | 20 +- engines/ags/engine/gfx/ali3dsw.cpp | 20 +- engines/ags/engine/gfx/ali3dsw.h | 18 +- engines/ags/engine/gfx/blender.cpp | 6 +- engines/ags/engine/gfx/color_engine.cpp | 6 +- engines/ags/engine/gfx/gfx_util.cpp | 6 +- engines/ags/engine/gfx/gfx_util.h | 6 +- engines/ags/engine/gfx/gfxdefines.h | 2 +- engines/ags/engine/gfx/gfxdriverbase.cpp | 12 +- engines/ags/engine/gfx/gfxdriverbase.h | 10 +- engines/ags/engine/gfx/gfxdriverfactory.cpp | 18 +- engines/ags/engine/gfx/gfxdriverfactory.h | 10 +- engines/ags/engine/gfx/gfxdriverfactorybase.h | 6 +- engines/ags/engine/gfx/gfxfilter.h | 8 +- engines/ags/engine/gfx/gfxfilter_aad3d.cpp | 8 +- engines/ags/engine/gfx/gfxfilter_aad3d.h | 2 +- engines/ags/engine/gfx/gfxfilter_aaogl.cpp | 6 +- engines/ags/engine/gfx/gfxfilter_aaogl.h | 2 +- engines/ags/engine/gfx/gfxfilter_allegro.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_allegro.h | 8 +- engines/ags/engine/gfx/gfxfilter_d3d.cpp | 6 +- engines/ags/engine/gfx/gfxfilter_d3d.h | 2 +- engines/ags/engine/gfx/gfxfilter_hqx.cpp | 6 +- engines/ags/engine/gfx/gfxfilter_hqx.h | 2 +- engines/ags/engine/gfx/gfxfilter_ogl.cpp | 6 +- engines/ags/engine/gfx/gfxfilter_ogl.h | 2 +- engines/ags/engine/gfx/gfxfilter_scaling.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_scaling.h | 4 +- engines/ags/engine/gfx/gfxmodelist.h | 4 +- engines/ags/engine/gfx/graphicsdriver.h | 24 +- engines/ags/engine/gfx/hq2x3x.h | 2 +- engines/ags/engine/gfx/ogl_headers.h | 30 +-- engines/ags/engine/gui/animatingguibutton.cpp | 4 +- engines/ags/engine/gui/animatingguibutton.h | 6 +- engines/ags/engine/gui/cscidialog.cpp | 44 ++-- engines/ags/engine/gui/cscidialog.h | 2 +- engines/ags/engine/gui/gui_engine.cpp | 30 +-- engines/ags/engine/gui/guidialog.cpp | 26 +-- engines/ags/engine/gui/guidialogdefines.h | 2 +- .../ags/engine/gui/guidialoginternaldefs.h | 2 +- engines/ags/engine/gui/mycontrols.h | 8 +- engines/ags/engine/gui/mylabel.cpp | 16 +- engines/ags/engine/gui/mylabel.h | 4 +- engines/ags/engine/gui/mylistbox.cpp | 18 +- engines/ags/engine/gui/mylistbox.h | 4 +- engines/ags/engine/gui/mypushbutton.cpp | 24 +- engines/ags/engine/gui/mypushbutton.h | 4 +- engines/ags/engine/gui/mytextbox.cpp | 12 +- engines/ags/engine/gui/mytextbox.h | 4 +- engines/ags/engine/gui/newcontrol.cpp | 6 +- engines/ags/engine/gui/newcontrol.h | 4 +- engines/ags/engine/main/config.cpp | 50 ++--- engines/ags/engine/main/config.h | 4 +- engines/ags/engine/main/engine.cpp | 209 +++++++++--------- engines/ags/engine/main/engine.h | 2 +- engines/ags/engine/main/engine_setup.cpp | 46 ++-- engines/ags/engine/main/engine_setup.h | 4 +- engines/ags/engine/main/game_file.cpp | 62 +++--- engines/ags/engine/main/game_file.h | 4 +- engines/ags/engine/main/game_run.cpp | 83 +++---- engines/ags/engine/main/game_start.cpp | 43 ++-- engines/ags/engine/main/graphics_mode.cpp | 36 +-- engines/ags/engine/main/graphics_mode.h | 8 +- engines/ags/engine/main/main.cpp | 42 ++-- engines/ags/engine/main/main.h | 4 +- engines/ags/engine/main/mainheader.h | 30 +-- engines/ags/engine/main/quit.cpp | 51 +++-- engines/ags/engine/main/update.cpp | 48 ++-- .../ags/engine/media/audio/ambientsound.cpp | 8 +- engines/ags/engine/media/audio/ambientsound.h | 4 +- engines/ags/engine/media/audio/audio.cpp | 52 ++--- engines/ags/engine/media/audio/audio.h | 20 +- engines/ags/engine/media/audio/audio_system.h | 14 +- .../ags/engine/media/audio/clip_mydumbmod.cpp | 6 +- .../ags/engine/media/audio/clip_mydumbmod.h | 4 +- .../ags/engine/media/audio/clip_myjgmod.cpp | 6 +- engines/ags/engine/media/audio/clip_myjgmod.h | 4 +- .../ags/engine/media/audio/clip_mymidi.cpp | 8 +- engines/ags/engine/media/audio/clip_mymidi.h | 2 +- engines/ags/engine/media/audio/clip_mymp3.cpp | 14 +- engines/ags/engine/media/audio/clip_mymp3.h | 4 +- engines/ags/engine/media/audio/clip_myogg.cpp | 16 +- engines/ags/engine/media/audio/clip_myogg.h | 4 +- .../engine/media/audio/clip_mystaticmp3.cpp | 12 +- .../ags/engine/media/audio/clip_mystaticmp3.h | 4 +- .../engine/media/audio/clip_mystaticogg.cpp | 12 +- .../ags/engine/media/audio/clip_mystaticogg.h | 4 +- .../ags/engine/media/audio/clip_mywave.cpp | 16 +- engines/ags/engine/media/audio/clip_mywave.h | 2 +- .../engine/media/audio/queuedaudioitem.cpp | 6 +- .../ags/engine/media/audio/queuedaudioitem.h | 4 +- engines/ags/engine/media/audio/sound.cpp | 36 +-- engines/ags/engine/media/audio/sound.h | 4 +- engines/ags/engine/media/audio/soundcache.cpp | 20 +- engines/ags/engine/media/audio/soundcache.h | 2 +- engines/ags/engine/media/audio/soundclip.cpp | 10 +- engines/ags/engine/media/audio/soundclip.h | 2 +- engines/ags/engine/media/video/VMR9Graph.h | 4 +- engines/ags/engine/media/video/video.cpp | 46 ++-- .../ags/engine/platform/android/acpland.cpp | 26 +-- .../platform/base/agsplatformdriver.cpp | 26 +-- .../engine/platform/base/agsplatformdriver.h | 12 +- engines/ags/engine/platform/ios/acplios.cpp | 20 +- engines/ags/engine/platform/linux/acpllnx.cpp | 24 +- engines/ags/engine/platform/osx/acplmac.cpp | 26 +-- engines/ags/engine/platform/osx/alplmac.mm | 2 +- engines/ags/engine/platform/util/libc.c | 12 +- engines/ags/engine/platform/util/pe.c | 8 +- .../ags/engine/platform/windows/acplwin.cpp | 56 ++--- .../debugging/namedpipesagsdebugger.cpp | 6 +- .../windows/debugging/namedpipesagsdebugger.h | 6 +- .../engine/platform/windows/gfx/ali3dd3d.cpp | 26 +-- .../engine/platform/windows/gfx/ali3dd3d.h | 20 +- .../platform/windows/media/video/acwavi.cpp | 26 +-- .../platform/windows/media/video/acwavi3d.cpp | 24 +- .../ags/engine/platform/windows/minidump.cpp | 10 +- .../platform/windows/setup/winsetup.cpp | 40 ++-- .../engine/platform/windows/setup/winsetup.h | 2 +- .../platform/windows/win_ex_handling.cpp | 18 +- .../engine/platform/windows/win_ex_handling.h | 2 +- engines/ags/engine/plugin/agsplugin.cpp | 116 +++++----- engines/ags/engine/plugin/global_plugin.cpp | 10 +- engines/ags/engine/plugin/plugin_engine.h | 8 +- .../ags/engine/plugin/pluginobjectreader.cpp | 4 +- engines/ags/engine/resource/version.rc | 10 +- engines/ags/engine/script/cc_instance.cpp | 50 ++--- engines/ags/engine/script/cc_instance.h | 19 +- engines/ags/engine/script/executingscript.cpp | 8 +- engines/ags/engine/script/executingscript.h | 4 +- engines/ags/engine/script/exports.cpp | 2 +- .../engine/script/nonblockingscriptfunction.h | 6 +- .../ags/engine/script/runtimescriptvalue.cpp | 12 +- .../ags/engine/script/runtimescriptvalue.h | 6 +- engines/ags/engine/script/script.cpp | 62 +++--- engines/ags/engine/script/script.h | 18 +- engines/ags/engine/script/script_api.cpp | 14 +- engines/ags/engine/script/script_api.h | 10 +- engines/ags/engine/script/script_engine.cpp | 10 +- engines/ags/engine/script/script_runtime.cpp | 20 +- engines/ags/engine/script/script_runtime.h | 4 +- engines/ags/engine/script/systemimports.cpp | 6 +- engines/ags/engine/script/systemimports.h | 4 +- engines/ags/engine/util/library.h | 10 +- engines/ags/engine/util/library_posix.h | 8 +- engines/ags/engine/util/library_psp.h | 6 +- engines/ags/engine/util/library_windows.h | 6 +- engines/ags/engine/util/mutex.h | 5 +- engines/ags/engine/util/mutex_lock.h | 2 +- engines/ags/engine/util/mutex_psp.h | 6 +- engines/ags/engine/util/mutex_pthread.h | 2 +- engines/ags/engine/util/mutex_std.h | 3 +- engines/ags/engine/util/mutex_wii.h | 2 +- engines/ags/engine/util/scaling.h | 4 +- engines/ags/engine/util/thread.h | 2 +- engines/ags/engine/util/thread_psp.h | 6 +- engines/ags/engine/util/thread_pthread.h | 3 +- engines/ags/engine/util/thread_std.h | 13 +- engines/ags/engine/util/thread_wii.h | 2 +- engines/ags/lib/allegro.h | 4 +- engines/ags/lib/allegro/alconfig.h | 4 +- engines/ags/lib/allegro/base.h | 4 +- engines/ags/lib/allegro/color.h | 4 +- engines/ags/lib/allegro/config.h | 4 +- engines/ags/lib/allegro/digi.h | 4 +- engines/ags/lib/allegro/error.h | 4 +- engines/ags/lib/allegro/file.h | 4 +- engines/ags/lib/allegro/fixed.h | 4 +- engines/ags/lib/allegro/gfx.h | 4 +- engines/ags/lib/allegro/keyboard.h | 11 +- engines/ags/lib/allegro/midi.h | 4 +- engines/ags/lib/allegro/mouse.h | 4 +- engines/ags/lib/allegro/sound.h | 4 +- engines/ags/lib/allegro/system.h | 4 +- engines/ags/lib/allegro/unicode.h | 4 +- engines/ags/module.mk | 12 +- engines/ags/shared/ac/gamesetupstruct.h | 8 +- engines/ags/shared/font/agsfontrenderer.h | 2 +- engines/ags/shared/game/room_file.cpp | 2 +- engines/ags/shared/util/path.h | 6 + engines/ags/shared/util/string.h | 5 +- engines/ags/std/initializer_list.h | 68 ++++++ engines/ags/std/xtr1common.h | 46 ++++ 436 files changed, 3538 insertions(+), 3383 deletions(-) create mode 100644 engines/ags/std/initializer_list.h create mode 100644 engines/ags/std/xtr1common.h diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index f6174449608d..84604052ed40 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -29,9 +29,9 @@ #ifndef AGS_ENGINE_AC_ASSETHELPER_H #define AGS_ENGINE_AC_ASSETHELPER_H -#include -#include -#include "util/string.h" +#include "ags/std/memory.h" +#include "ags/std/utility.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp index 5d41da434047..9773f5f2b03c 100644 --- a/engines/ags/engine/ac/audiochannel.cpp +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -20,14 +20,14 @@ * */ -#include "ac/audiochannel.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/dynobj/cc_audioclip.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "script/runtimescriptvalue.h" -#include "media/audio/audio_system.h" +#include "ags/engine/ac/audiochannel.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/dynobj/cc_audioclip.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { @@ -202,9 +202,9 @@ void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPo // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // int | ScriptAudioChannel *channel RuntimeScriptValue Sc_AudioChannel_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/audiochannel.h b/engines/ags/engine/ac/audiochannel.h index 5cb30e14aac7..da55ffa70242 100644 --- a/engines/ags/engine/ac/audiochannel.h +++ b/engines/ags/engine/ac/audiochannel.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_AUDIOCHANNEL_H #define AGS_ENGINE_AC_AUDIOCHANNEL_H -#include "ac/dynobj/scriptaudioclip.h" -#include "ac/dynobj/scriptaudiochannel.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/engine/ac/dynobj/scriptaudiochannel.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp index 993b72b1c6b8..412072b34643 100644 --- a/engines/ags/engine/ac/audioclip.cpp +++ b/engines/ags/engine/ac/audioclip.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/asset_helper.h" -#include "ac/audioclip.h" -#include "ac/audiochannel.h" -#include "ac/gamesetupstruct.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_audiochannel.h" -#include "media/audio/audio_system.h" +#include "ags/engine/ac/asset_helper.h" +#include "ags/engine/ac/audioclip.h" +#include "ags/engine/ac/audiochannel.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_audiochannel.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { @@ -80,9 +80,9 @@ ScriptAudioChannel *AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, in // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" RuntimeScriptValue Sc_AudioClip_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetID); diff --git a/engines/ags/engine/ac/audioclip.h b/engines/ags/engine/ac/audioclip.h index 9f8fab806014..00d8075b97fc 100644 --- a/engines/ags/engine/ac/audioclip.h +++ b/engines/ags/engine/ac/audioclip.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_AUDIOCLIP_H #define AGS_ENGINE_AC_AUDIOCLIP_H -#include "ac/dynobj/scriptaudioclip.h" -#include "ac/dynobj/scriptaudiochannel.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/engine/ac/dynobj/scriptaudiochannel.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp index 469414fbeb13..e533a6384ba9 100644 --- a/engines/ags/engine/ac/button.cpp +++ b/engines/ags/engine/ac/button.cpp @@ -20,17 +20,22 @@ * */ -#include "ac/button.h" -#include "ac/common.h" -#include "ac/gui.h" -#include "ac/view.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_translation.h" -#include "ac/string.h" -#include "ac/viewframe.h" -#include "debug/debug_log.h" -#include "gui/animatingguibutton.h" -#include "gui/guimain.h" +#include "ags/engine/ac/button.h" +#include "ags/shared/ac/common.h" +#include "ags/engine/ac/gui.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/gui/animatingguibutton.h" +#include "ags/shared/gui/guimain.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -301,11 +306,6 @@ void Button_SetTextAlignment(GUIButton *butt, int align) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // void | GUIButton *butt, int view, int loop, int speed, int repeat diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h index f8293b405635..64215f89fd65 100644 --- a/engines/ags/engine/ac/button.h +++ b/engines/ags/engine/ac/button.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_BUTTON_H #define AGS_ENGINE_AC_BUTTON_H -#include "gui/guibutton.h" +#include "ags/shared/gui/guibutton.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/cdaudio.cpp b/engines/ags/engine/ac/cdaudio.cpp index 04feb2c3bc7d..fc8cbd26c635 100644 --- a/engines/ags/engine/ac/cdaudio.cpp +++ b/engines/ags/engine/ac/cdaudio.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/cdaudio.h" -#include "platform/base/agsplatformdriver.h" +#include "ags/engine/ac/cdaudio.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index 34890ee440d2..ee3ea08a5866 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -26,50 +26,50 @@ // //============================================================================= -#include "ac/character.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/view.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/game.h" -#include "ac/global_audio.h" -#include "ac/global_character.h" -#include "ac/global_game.h" -#include "ac/global_object.h" -#include "ac/global_region.h" -#include "ac/global_room.h" -#include "ac/global_translation.h" -#include "ac/gui.h" -#include "ac/lipsync.h" -#include "ac/mouse.h" -#include "ac/object.h" -#include "ac/overlay.h" -#include "ac/properties.h" -#include "ac/room.h" -#include "ac/screenoverlay.h" -#include "ac/string.h" -#include "ac/system.h" -#include "ac/viewframe.h" -#include "ac/walkablearea.h" -#include "gui/guimain.h" -#include "ac/route_finder.h" -#include "ac/gamestate.h" -#include "debug/debug_log.h" -#include "main/game_run.h" -#include "main/update.h" -#include "ac/spritecache.h" -#include "util/string_compat.h" -#include -#include "gfx/graphicsdriver.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_character.h" -#include "ac/dynobj/cc_inventory.h" -#include "script/script_runtime.h" -#include "gfx/gfx_def.h" -#include "media/audio/audio_system.h" -#include "ac/movelist.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_object.h" +#include "ags/shared/ac/global_region.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/lipsync.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/viewframe.h" +#include "ags/shared/ac/walkablearea.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/ac/route_finder.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/main/update.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/util/string_compat.h" +//include +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_character.h" +#include "ags/shared/ac/dynobj/cc_inventory.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/gfx/gfx_def.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/ac/movelist.h" namespace AGS3 { @@ -2848,10 +2848,10 @@ PViewport FindNearestViewport(int charid) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h index c275cfd2379e..c2ee1c668a29 100644 --- a/engines/ags/engine/ac/character.h +++ b/engines/ags/engine/ac/character.h @@ -23,13 +23,13 @@ #ifndef AGS_ENGINE_AC_CHARACTER_H #define AGS_ENGINE_AC_CHARACTER_H -#include "ac/characterinfo.h" -#include "ac/characterextras.h" -#include "ac/dynobj/scriptobject.h" -#include "ac/dynobj/scriptinvitem.h" -#include "ac/dynobj/scriptoverlay.h" -#include "game/viewport.h" -#include "util/geometry.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/engine/ac/characterextras.h" +#include "ags/engine/ac/dynobj/scriptobject.h" +#include "ags/engine/ac/dynobj/scriptinvitem.h" +#include "ags/engine/ac/dynobj/scriptoverlay.h" +#include "ags/engine/game/viewport.h" +#include "ags/shared/util/geometry.h" namespace AGS3 { @@ -193,14 +193,14 @@ int is_valid_character(int newchar); int wantMoveNow(CharacterInfo *chi, CharacterExtras *chex); void setup_player_character(int charid); void CheckViewFrameForCharacter(CharacterInfo *chi); -Common::Bitmap *GetCharacterImage(int charid, int *isFlipped); +Shared::Bitmap *GetCharacterImage(int charid, int *isFlipped); CharacterInfo *GetCharacterAtScreen(int xx, int yy); // Get character ID at the given room coordinates int is_pos_on_character(int xx, int yy); void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2); // Check whether the source char has walked onto character ww int is_char_on_another(int sourceChar, int ww, int *fromxptr, int *cwidptr); -int my_getpixel(Common::Bitmap *blk, int x, int y); +int my_getpixel(Shared::Bitmap *blk, int x, int y); // X and Y co-ordinates must be in 320x200 format int check_click_on_character(int xx, int yy, int mood); int is_pos_on_character(int xx, int yy); diff --git a/engines/ags/engine/ac/charactercache.h b/engines/ags/engine/ac/charactercache.h index 4d44bfeffd4c..1b1810fb4fe6 100644 --- a/engines/ags/engine/ac/charactercache.h +++ b/engines/ags/engine/ac/charactercache.h @@ -28,13 +28,14 @@ namespace AGS3 { namespace AGS { namespace Shared { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later // stores cached info about the character struct CharacterCache { - Common::Bitmap *image; + Shared::Bitmap *image; int sppic; int scaling; int inUse; diff --git a/engines/ags/engine/ac/characterextras.cpp b/engines/ags/engine/ac/characterextras.cpp index 6915dca2bca5..e0e80a0bc50c 100644 --- a/engines/ags/engine/ac/characterextras.cpp +++ b/engines/ags/engine/ac/characterextras.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/characterextras.h" -#include "util/stream.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h index a94ef18b4396..906282b5f594 100644 --- a/engines/ags/engine/ac/characterextras.h +++ b/engines/ags/engine/ac/characterextras.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_CHARACTEREXTRAS_H #define AGS_ENGINE_AC_CHARACTEREXTRAS_H -#include "ac/runtime_defines.h" +#include "ags/engine/ac/runtime_defines.h" namespace AGS3 { @@ -56,8 +56,8 @@ struct CharacterExtras { char slow_move_counter; short animwait; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); }; } // namespace AGS3 diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp index e9e2bcff84cf..74118dce63bc 100644 --- a/engines/ags/engine/ac/characterinfo_engine.cpp +++ b/engines/ags/engine/ac/characterinfo_engine.cpp @@ -20,20 +20,20 @@ * */ -#include "ac/characterinfo.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/character.h" -#include "ac/characterextras.h" -#include "ac/gamestate.h" -#include "ac/global_character.h" -#include "ac/math.h" -#include "ac/viewframe.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "main/maindefines_ex.h" // RETURN_CONTINUE -#include "main/update.h" -#include "media/audio/audio_system.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/math.h" +#include "ags/shared/ac/viewframe.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/main/maindefines_ex.h" // RETURN_CONTINUE +#include "ags/shared/main/update.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/datetime.cpp b/engines/ags/engine/ac/datetime.cpp index 982180272025..c46c4589950b 100644 --- a/engines/ags/engine/ac/datetime.cpp +++ b/engines/ags/engine/ac/datetime.cpp @@ -20,10 +20,10 @@ * */ -#include -#include "ac/datetime.h" -#include "platform/base/agsplatformdriver.h" -#include "script/runtimescriptvalue.h" +//include +#include "ags/shared/ac/datetime.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/script/runtimescriptvalue.h" namespace AGS3 { @@ -75,9 +75,9 @@ int DateTime_GetRawTime(ScriptDateTime *sdt) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // ScriptDateTime* () RuntimeScriptValue Sc_DateTime_Now(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/datetime.h b/engines/ags/engine/ac/datetime.h index 6febc33f6a48..871173951845 100644 --- a/engines/ags/engine/ac/datetime.h +++ b/engines/ags/engine/ac/datetime.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DATETIME_H #define AGS_ENGINE_AC_DATETIME_H -#include "ac/dynobj/scriptdatetime.h" +#include "ags/engine/ac/dynobj/scriptdatetime.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 6d1f3e98b07a..4f3522da9a05 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -20,45 +20,45 @@ * */ -#include "ac/dialog.h" -#include "ac/common.h" -#include "ac/character.h" -#include "ac/characterinfo.h" -#include "ac/dialogtopic.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/gamestate.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_character.h" -#include "ac/global_dialog.h" -#include "ac/global_display.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/global_room.h" -#include "ac/global_translation.h" -#include "ac/keycode.h" -#include "ac/overlay.h" -#include "ac/mouse.h" -#include "ac/parser.h" -#include "ac/sys_events.h" -#include "ac/string.h" -#include "ac/dynobj/scriptdialogoptionsrendering.h" -#include "ac/dynobj/scriptdrawingsurface.h" -#include "ac/system.h" -#include "debug/debug_log.h" -#include "font/fonts.h" -#include "script/cc_instance.h" -#include "gui/guimain.h" -#include "gui/guitextbox.h" -#include "main/game_run.h" -#include "platform/base/agsplatformdriver.h" -#include "script/script.h" -#include "ac/spritecache.h" -#include "gfx/ddb.h" -#include "gfx/gfx_util.h" -#include "gfx/graphicsdriver.h" -#include "ac/mouse.h" -#include "media/audio/audio_system.h" +#include "ags/shared/ac/dialog.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_dialog.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/keycode.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/parser.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/dynobj/scriptdialogoptionsrendering.h" +#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/script/cc_instance.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guitextbox.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/script/script.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { @@ -1148,10 +1148,10 @@ void do_conversation(int dlgnum) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h index 7436d4146628..696c195b5e65 100644 --- a/engines/ags/engine/ac/dialog.h +++ b/engines/ags/engine/ac/dialog.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DIALOG_H #define AGS_ENGINE_AC_DIALOG_H -#include -#include "ac/dynobj/scriptdialog.h" +#include "ags/std/vector.h" +#include "ags/engine/ac/dynobj/scriptdialog.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dialogoptionsrendering.cpp b/engines/ags/engine/ac/dialogoptionsrendering.cpp index 39b2b2c46651..f7bf6a54530d 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dialogoptionsrendering.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/dialog.h" -#include "ac/dialogtopic.h" -#include "ac/dialogoptionsrendering.h" -#include "ac/gamestructdefines.h" -#include "debug/debug_log.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_dialog.h" +#include "ags/shared/ac/dialog.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/ac/dialogoptionsrendering.h" +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_dialog.h" namespace AGS3 { @@ -138,9 +138,9 @@ void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgO // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" RuntimeScriptValue Sc_DialogOptionsRendering_Update(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_VOID(ScriptDialogOptionsRendering, DialogOptionsRendering_Update); diff --git a/engines/ags/engine/ac/dialogoptionsrendering.h b/engines/ags/engine/ac/dialogoptionsrendering.h index 4f8584c2716b..2ab24033e23d 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.h +++ b/engines/ags/engine/ac/dialogoptionsrendering.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DIALOGOPTIONSRENDERING_H #define AGS_ENGINE_AC_DIALOGOPTIONSRENDERING_H -#include "ac/dynobj/scriptdialog.h" -#include "ac/dynobj/scriptdialogoptionsrendering.h" +#include "ags/engine/ac/dynobj/scriptdialog.h" +#include "ags/engine/ac/dynobj/scriptdialogoptionsrendering.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp index 017c573034b1..cfbc137cdf6f 100644 --- a/engines/ags/engine/ac/display.cpp +++ b/engines/ags/engine/ac/display.cpp @@ -20,40 +20,40 @@ * */ -#include - -#include "ac/display.h" -#include "ac/common.h" -#include "font/agsfontrenderer.h" -#include "font/fonts.h" -#include "ac/character.h" -#include "ac/draw.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/global_game.h" -#include "ac/gui.h" -#include "ac/mouse.h" -#include "ac/overlay.h" -#include "ac/sys_events.h" -#include "ac/screenoverlay.h" -#include "ac/speech.h" -#include "ac/string.h" -#include "ac/system.h" -#include "ac/topbarsettings.h" -#include "debug/debug_log.h" -#include "gfx/blender.h" -#include "gui/guibutton.h" -#include "gui/guimain.h" -#include "main/game_run.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/spritecache.h" -#include "gfx/gfx_util.h" -#include "util/string_utils.h" -#include "ac/mouse.h" -#include "media/audio/audio_system.h" -#include "ac/timer.h" +//include + +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/font/agsfontrenderer.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/speech.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/topbarsettings.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/gfx/blender.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { @@ -530,7 +530,7 @@ void wouttextxy_AutoOutline(Bitmap *ds, size_t font, int32_t color, const char * } // Draw an outline if requested, then draw the text on top -void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int font, color_t text_color, const char *texx) { +void wouttext_outline(Shared::Bitmap *ds, int xxp, int yyp, int font, color_t text_color, const char *texx) { size_t const text_font = static_cast(font); // Draw outline (a backdrop) if requested color_t const outline_color = ds->GetCompatibleColor(play.speech_text_shadow); diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h index 44a0df247996..d202c03fbaf9 100644 --- a/engines/ags/engine/ac/display.h +++ b/engines/ags/engine/ac/display.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DISPLAY_H #define AGS_ENGINE_AC_DISPLAY_H -#include "gui/guimain.h" +#include "ags/shared/gui/guimain.h" namespace AGS3 { @@ -48,8 +48,8 @@ int GetTextDisplayLength(const char *text); // Calculates number of game loops for displaying a text on screen int GetTextDisplayTime(const char *text, int canberel = 0); // Draw an outline if requested, then draw the text on top -void wouttext_outline(Common::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); -void wouttext_aligned(Common::Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align); +void wouttext_outline(Shared::Bitmap *ds, int xxp, int yyp, int usingfont, color_t text_color, const char *texx); +void wouttext_aligned(Shared::Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, color_t text_color, const char *text, HorAlignment align); // TODO: GUI classes located in Common library do not make use of outlining, // need to find a way to make all code use same functions. // Get the maximal height of the given font, with corresponding outlining @@ -62,10 +62,10 @@ int getfontlinegap(int font); int getheightoflines(int font, int numlines); // Get the maximal width of the given font, with corresponding outlining int wgettextwidth_compensate(const char *tex, int font); -void do_corner(Common::Bitmap *ds, int sprn, int xx1, int yy1, int typx, int typy); +void do_corner(Shared::Bitmap *ds, int sprn, int xx1, int yy1, int typx, int typy); // Returns the image of a button control on the GUI under given child index int get_but_pic(GUIMain *guo, int indx); -void draw_button_background(Common::Bitmap *ds, int xx1, int yy1, int xx2, int yy2, GUIMain *iep); +void draw_button_background(Shared::Bitmap *ds, int xx1, int yy1, int xx2, int yy2, GUIMain *iep); // Calculate the width that the left and right border of the textwindow // GUI take up int get_textwindow_border_width(int twgui); @@ -76,8 +76,8 @@ int get_textwindow_top_border_height(int twgui); // point text_window_ds to it // returns text start x & y pos in parameters // Warning!: draw_text_window() and draw_text_window_and_bar() can create new text_window_ds -void draw_text_window(Common::Bitmap **text_window_ds, bool should_free_ds, int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum); -void draw_text_window_and_bar(Common::Bitmap **text_window_ds, bool should_free_ds, +void draw_text_window(Shared::Bitmap **text_window_ds, bool should_free_ds, int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight, int ifnum); +void draw_text_window_and_bar(Shared::Bitmap **text_window_ds, bool should_free_ds, int *xins, int *yins, int *xx, int *yy, int *wii, color_t *set_text_color, int ovrheight = 0, int ifnum = -1); int get_textwindow_padding(int ifnum); diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index 374c218ba7b2..7ac126608e33 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -20,56 +20,56 @@ * */ -#include -#include -#include "aastr.h" -#include "core/platform.h" -#include "ac/common.h" -#include "util/compress.h" -#include "ac/view.h" -#include "ac/charactercache.h" -#include "ac/characterextras.h" -#include "ac/characterinfo.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/draw_software.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/global_region.h" -#include "ac/gui.h" -#include "ac/mouse.h" -#include "ac/objectcache.h" -#include "ac/overlay.h" -#include "ac/sys_events.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "ac/runtime_defines.h" -#include "ac/screenoverlay.h" -#include "ac/sprite.h" -#include "ac/spritelistentry.h" -#include "ac/string.h" -#include "ac/system.h" -#include "ac/viewframe.h" -#include "ac/walkablearea.h" -#include "ac/walkbehind.h" -#include "ac/dynobj/scriptsystem.h" -#include "debug/debugger.h" -#include "debug/debug_log.h" -#include "font/fonts.h" -#include "gui/guimain.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "ac/spritecache.h" -#include "gfx/gfx_util.h" -#include "gfx/graphicsdriver.h" -#include "gfx/ali3dexception.h" -#include "gfx/blender.h" -#include "media/audio/audio_system.h" -#include "ac/game.h" +//include +//include +#include "ags/shared/aastr.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/util/compress.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/charactercache.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/draw_software.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_region.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/sprite.h" +#include "ags/shared/ac/spritelistentry.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/viewframe.h" +#include "ags/shared/ac/walkablearea.h" +#include "ags/shared/ac/walkbehind.h" +#include "ags/shared/ac/dynobj/scriptsystem.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/ali3dexception.h" +#include "ags/shared/gfx/blender.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/ac/game.h" namespace AGS3 { @@ -77,8 +77,8 @@ using namespace AGS::Shared; using namespace AGS::Engine; #if AGS_PLATFORM_OS_ANDROID -#include -#include +//include +//include extern "C" void android_render(); #endif diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index e100230c9b40..42437b6f9de3 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -23,18 +23,18 @@ #ifndef AGS_ENGINE_AC_DRAW_H #define AGS_ENGINE_AC_DRAW_H -#include -#include "core/types.h" -#include "ac/common_defines.h" -#include "gfx/gfx_def.h" -#include "util/wgt2allg.h" +#include "ags/std/memory.h" +#include "ags/shared/core/types.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/gfx/gfx_def.h" +#include "ags/shared/util/wgt2allg.h" namespace AGS3 { namespace AGS { namespace Shared { class Bitmap; -typedef std::shared_ptr PBitmap; +typedef std::shared_ptr PBitmap; } namespace Engine { class IDriverDependantBitmap; @@ -104,8 +104,8 @@ void invalidate_rect(int x1, int y1, int x2, int y2, bool in_room); void mark_current_background_dirty(); void invalidate_cached_walkbehinds(); // Avoid freeing and reallocating the memory if possible -Common::Bitmap *recycle_bitmap(Common::Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent = false); -Engine::IDriverDependantBitmap *recycle_ddb_bitmap(Engine::IDriverDependantBitmap *bimp, Common::Bitmap *source, bool hasAlpha = false, bool opaque = false); +Shared::Bitmap *recycle_bitmap(Shared::Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent = false); +Engine::IDriverDependantBitmap *recycle_ddb_bitmap(Engine::IDriverDependantBitmap *bimp, Shared::Bitmap *source, bool hasAlpha = false, bool opaque = false); // Draw everything void render_graphics(Engine::IDriverDependantBitmap *extraBitmap = nullptr, int extraX = 0, int extraY = 0); // Construct game scene, scheduling drawing list for the renderer @@ -115,27 +115,27 @@ void construct_game_screen_overlay(bool draw_mouse = true); // Construct engine overlay with debugging tools (fps, console) void construct_engine_overlay(); void add_to_sprite_list(Engine::IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind = false); -void tint_image(Common::Bitmap *g, Common::Bitmap *source, int red, int grn, int blu, int light_level, int luminance = 255); -void draw_sprite_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Common::Bitmap *image, bool src_has_alpha, - Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); -void draw_sprite_slot_support_alpha(Common::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot, - Common::BlendMode blend_mode = Common::kBlendMode_Alpha, int alpha = 0xFF); -void draw_gui_sprite(Common::Bitmap *ds, int pic, int x, int y, bool use_alpha, Common::BlendMode blend_mode); -void draw_gui_sprite_v330(Common::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Common::BlendMode blend_mode = Common::kBlendMode_Alpha); +void tint_image(Shared::Bitmap *g, Shared::Bitmap *source, int red, int grn, int blu, int light_level, int luminance = 255); +void draw_sprite_support_alpha(Shared::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Shared::Bitmap *image, bool src_has_alpha, + Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF); +void draw_sprite_slot_support_alpha(Shared::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, int src_slot, + Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF); +void draw_gui_sprite(Shared::Bitmap *ds, int pic, int x, int y, bool use_alpha, Shared::BlendMode blend_mode); +void draw_gui_sprite_v330(Shared::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha); // Render game on screen void render_to_screen(); // Callbacks for the graphics driver void draw_game_screen_callback(); void GfxDriverOnInitCallback(void *data); bool GfxDriverNullSpriteCallback(int x, int y); -void putpixel_compensate(Common::Bitmap *g, int xx, int yy, int col); +void putpixel_compensate(Shared::Bitmap *g, int xx, int yy, int col); // create the actsps[aa] image with the object drawn correctly // returns 1 if nothing at all has changed and actsps is still // intact from last time; 0 otherwise int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysUseSoftware); void clear_letterbox_borders(); -void draw_and_invalidate_text(Common::Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text); +void draw_and_invalidate_text(Shared::Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text); void setpal(); @@ -167,17 +167,17 @@ extern AGS_INLINE void defgame_to_finalgame_coords(int &x, int &y); // TODO: this helper function was meant to remove bitmap deletion from the GraphicsDriver's // implementations while keeping code changes to minimum. The proper solution would probably // be to use shared pointers when storing Bitmaps, or make Bitmap reference-counted object. -Common::Bitmap *ReplaceBitmapWithSupportedFormat(Common::Bitmap *bitmap); +Shared::Bitmap *ReplaceBitmapWithSupportedFormat(Shared::Bitmap *bitmap); // Checks if the bitmap needs any kind of adjustments before it may be used // in AGS sprite operations. Also handles number of certain special cases // (old systems or uncommon gfx modes, and similar stuff). // Original bitmap **gets deleted** if a new bitmap had to be created. -Common::Bitmap *PrepareSpriteForUse(Common::Bitmap *bitmap, bool has_alpha); +Shared::Bitmap *PrepareSpriteForUse(Shared::Bitmap *bitmap, bool has_alpha); // Same as above, but compatible for std::shared_ptr. -Common::PBitmap PrepareSpriteForUse(Common::PBitmap bitmap, bool has_alpha); +Shared::PBitmap PrepareSpriteForUse(Shared::PBitmap bitmap, bool has_alpha); // Makes a screenshot corresponding to the last screen render and returns it as a bitmap // of the requested width and height and game's native color depth. -Common::Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res = false); +Shared::Bitmap *CopyScreenIntoBitmap(int width, int height, bool at_native_res = false); } // namespace AGS3 diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index 917b4cd0eafa..ab4412a4279a 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -46,11 +46,11 @@ // //============================================================================= -#include -#include -#include "ac/draw_software.h" -#include "gfx/bitmap.h" -#include "util/scaling.h" +//include +#include "ags/std/vector.h" +#include "ags/shared/ac/draw_software.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/util/scaling.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/draw_software.h b/engines/ags/engine/ac/draw_software.h index aee7079dde30..7a28ca0d7c50 100644 --- a/engines/ags/engine/ac/draw_software.h +++ b/engines/ags/engine/ac/draw_software.h @@ -30,9 +30,9 @@ #ifndef AGS_ENGINE_AC_DRAWSOFTWARE_H #define AGS_ENGINE_AC_DRAWSOFTWARE_H -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "util/geometry.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/shared/util/geometry.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp index d4fb8cd14b3e..a0a6f494f539 100644 --- a/engines/ags/engine/ac/drawingsurface.cpp +++ b/engines/ags/engine/ac/drawingsurface.cpp @@ -20,27 +20,27 @@ * */ -#include "ac/draw.h" -#include "ac/drawingsurface.h" -#include "ac/common.h" -#include "ac/charactercache.h" -#include "ac/display.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_translation.h" -#include "ac/objectcache.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "ac/string.h" -#include "ac/walkbehind.h" -#include "debug/debug_log.h" -#include "font/fonts.h" -#include "gui/guimain.h" -#include "ac/spritecache.h" -#include "script/runtimescriptvalue.h" -#include "gfx/gfx_def.h" -#include "gfx/gfx_util.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/drawingsurface.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/charactercache.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/walkbehind.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/gfx/gfx_def.h" +#include "ags/shared/gfx/gfx_util.h" namespace AGS3 { @@ -447,9 +447,9 @@ int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // void (ScriptDrawingSurface *sds, int colour) RuntimeScriptValue Sc_DrawingSurface_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/drawingsurface.h b/engines/ags/engine/ac/drawingsurface.h index 511b73a98b82..7ba6a87c5520 100644 --- a/engines/ags/engine/ac/drawingsurface.h +++ b/engines/ags/engine/ac/drawingsurface.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DRAWINGSURFACE_H #define AGS_ENGINE_AC_DRAWINGSURFACE_H -#include "ac/dynobj/scriptdrawingsurface.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp index 1e1a37db215e..d5c635592d3e 100644 --- a/engines/ags/engine/ac/dynamicsprite.cpp +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -20,26 +20,26 @@ * */ -#include -#include "ac/dynamicsprite.h" -#include "ac/common.h" -#include "ac/charactercache.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_dynamicsprite.h" -#include "ac/global_game.h" -#include "ac/math.h" // M_PI -#include "ac/objectcache.h" -#include "ac/path_helper.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "ac/system.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "gui/guibutton.h" -#include "ac/spritecache.h" -#include "gfx/graphicsdriver.h" -#include "script/runtimescriptvalue.h" +//include +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/charactercache.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_dynamicsprite.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/math.h" // M_PI +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/script/runtimescriptvalue.h" namespace AGS3 { @@ -504,9 +504,9 @@ void free_dynamic_sprite(int gotSlot) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // void (ScriptDynamicSprite *sds, int width, int height, int x, int y) RuntimeScriptValue Sc_DynamicSprite_ChangeCanvasSize(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/dynamicsprite.h b/engines/ags/engine/ac/dynamicsprite.h index a78b50ee1033..478407d22ac0 100644 --- a/engines/ags/engine/ac/dynamicsprite.h +++ b/engines/ags/engine/ac/dynamicsprite.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNAMICSPRITE_H #define AGS_ENGINE_AC_DYNAMICSPRITE_H -#include "ac/dynobj/scriptdynamicsprite.h" -#include "ac/dynobj/scriptdrawingsurface.h" +#include "ags/engine/ac/dynobj/scriptdynamicsprite.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" namespace AGS3 { @@ -52,7 +52,7 @@ ScriptDynamicSprite *DynamicSprite_CreateFromExistingSprite_Old(int slot); ScriptDynamicSprite *DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height); -void add_dynamic_sprite(int gotSlot, Common::Bitmap *redin, bool hasAlpha = false); +void add_dynamic_sprite(int gotSlot, Shared::Bitmap *redin, bool hasAlpha = false); void free_dynamic_sprite(int gotSlot); } // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h index e9d32a155703..f597b28a477f 100644 --- a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h +++ b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h @@ -23,18 +23,18 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_ALLDYNAMICCLASSES_H #define AGS_ENGINE_AC_DYNOBJ_ALLDYNAMICCLASSES_H -#include "ac/dynobj/cc_agsdynamicobject.h" -#include "ac/dynobj/cc_audiochannel.h" -#include "ac/dynobj/cc_audioclip.h" -#include "ac/dynobj/cc_character.h" -#include "ac/dynobj/cc_dialog.h" -#include "ac/dynobj/cc_gui.h" -#include "ac/dynobj/cc_guiobject.h" -#include "ac/dynobj/cc_hotspot.h" -#include "ac/dynobj/cc_inventory.h" -#include "ac/dynobj/cc_object.h" -#include "ac/dynobj/cc_region.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_audiochannel.h" +#include "ags/shared/ac/dynobj/cc_audioclip.h" +#include "ags/shared/ac/dynobj/cc_character.h" +#include "ags/shared/ac/dynobj/cc_dialog.h" +#include "ags/shared/ac/dynobj/cc_gui.h" +#include "ags/shared/ac/dynobj/cc_guiobject.h" +#include "ags/shared/ac/dynobj/cc_hotspot.h" +#include "ags/shared/ac/dynobj/cc_inventory.h" +#include "ags/shared/ac/dynobj/cc_object.h" +#include "ags/shared/ac/dynobj/cc_region.h" -#include "ac/dynobj/cc_serializer.h" +#include "ags/shared/ac/dynobj/cc_serializer.h" #endif diff --git a/engines/ags/engine/ac/dynobj/all_scriptclasses.h b/engines/ags/engine/ac/dynobj/all_scriptclasses.h index 7c9776d2cb51..7c3c72b9c5f6 100644 --- a/engines/ags/engine/ac/dynobj/all_scriptclasses.h +++ b/engines/ags/engine/ac/dynobj/all_scriptclasses.h @@ -23,20 +23,20 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_ALLSCRIPTCLASSES_H #define AGS_ENGINE_AC_DYNOBJ_ALLSCRIPTCLASSES_H -#include "ac/dynobj/scriptdatetime.h" -#include "ac/dynobj/scriptdialog.h" -#include "ac/dynobj/scriptdialogoptionsrendering.h" -#include "ac/dynobj/scriptdrawingsurface.h" -#include "ac/dynobj/scriptdynamicsprite.h" -#include "ac/dynobj/scriptgui.h" -#include "ac/dynobj/scripthotspot.h" -#include "ac/dynobj/scriptinvitem.h" -#include "ac/dynobj/scriptmouse.h" -#include "ac/dynobj/scriptobject.h" -#include "ac/dynobj/scriptoverlay.h" -#include "ac/dynobj/scriptregion.h" -#include "ac/dynobj/scriptstring.h" -#include "ac/dynobj/scriptsystem.h" -#include "ac/dynobj/scriptviewframe.h" +#include "ags/shared/ac/dynobj/scriptdatetime.h" +#include "ags/shared/ac/dynobj/scriptdialog.h" +#include "ags/shared/ac/dynobj/scriptdialogoptionsrendering.h" +#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" +#include "ags/shared/ac/dynobj/scriptdynamicsprite.h" +#include "ags/shared/ac/dynobj/scriptgui.h" +#include "ags/shared/ac/dynobj/scripthotspot.h" +#include "ags/shared/ac/dynobj/scriptinvitem.h" +#include "ags/shared/ac/dynobj/scriptmouse.h" +#include "ags/shared/ac/dynobj/scriptobject.h" +#include "ags/shared/ac/dynobj/scriptoverlay.h" +#include "ags/shared/ac/dynobj/scriptregion.h" +#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/shared/ac/dynobj/scriptsystem.h" +#include "ags/shared/ac/dynobj/scriptviewframe.h" #endif diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp index fe3f70cb6d1f..f64397eec1be 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -20,11 +20,11 @@ * */ -#include -#include "core/types.h" -#include "ac/dynobj/cc_agsdynamicobject.h" -#include "ac/common.h" // quit() -#include "util/bbop.h" +//include +#include "ags/shared/core/types.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/common.h" // quit() +#include "ags/shared/util/bbop.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h index af1263bfb77f..da64242dc909 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CC_AGSDYNAMICOBJECT_H #define AGS_ENGINE_AC_DYNOBJ_CC_AGSDYNAMICOBJECT_H -#include "ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp index e5e89d620b6e..280486465f60 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/dynobj/cc_audiochannel.h" -#include "ac/dynobj/scriptaudiochannel.h" -#include "media/audio/audio_system.h" +#include "ags/shared/ac/dynobj/cc_audiochannel.h" +#include "ags/shared/ac/dynobj/scriptaudiochannel.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.h b/engines/ags/engine/ac/dynobj/cc_audiochannel.h index caa77fe33116..0013e8225246 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.h +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CC_AUDIOCHANNEL_H #define AGS_ENGINE_AC_DYNOBJ_CC_AUDIOCHANNEL_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp index edcde5d34ac0..6f63f2fd64b1 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/dynobj/cc_audioclip.h" -#include "ac/dynobj/scriptaudioclip.h" -#include "ac/gamesetupstruct.h" +#include "ags/shared/ac/dynobj/cc_audioclip.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/shared/ac/gamesetupstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.h b/engines/ags/engine/ac/dynobj/cc_audioclip.h index 2f9b8bd8fe55..32d2b8aa4939 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.h +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCAUDIOCLIP_H #define AGS_ENGINE_AC_DYNOBJ_CCAUDIOCLIP_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index d00b9cea5aae..6944fc652d47 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -20,11 +20,11 @@ * */ -#include "ac/dynobj/cc_character.h" -#include "ac/characterinfo.h" -#include "ac/global_character.h" -#include "ac/gamesetupstruct.h" -#include "ac/game_version.h" +#include "ags/shared/ac/dynobj/cc_character.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/game_version.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_character.h b/engines/ags/engine/ac/dynobj/cc_character.h index 7acb48709949..b75cd6a3518d 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.h +++ b/engines/ags/engine/ac/dynobj/cc_character.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCCHARACTER_H #define AGS_ENGINE_AC_DYNOBJ_CCCHARACTER_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp index bfd8e835fa3f..622f6392aca9 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/dynobj/cc_dialog.h" -#include "ac/dialog.h" -#include "ac/dialogtopic.h" -#include "ac/gamestructdefines.h" +#include "ags/shared/ac/dynobj/cc_dialog.h" +#include "ags/shared/ac/dialog.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/ac/gamestructdefines.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.h b/engines/ags/engine/ac/dynobj/cc_dialog.h index 9fbcdbe65458..a7c4954af529 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.h +++ b/engines/ags/engine/ac/dynobj/cc_dialog.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCDIALOG_H #define AGS_ENGINE_AC_DYNOBJ_CCDIALOG_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp index d64343865e03..118eb4e8a73a 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp @@ -20,8 +20,8 @@ * */ -#include -#include "cc_dynamicarray.h" +//include +#include "ags/shared/cc_dynamicarray.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index e89774ada488..327a0b1b78b8 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCDYNAMICARRAY_H #define AGS_ENGINE_AC_DYNOBJ_CCDYNAMICARRAY_H -#include -#include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject +#include "ags/std/vector.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp index 725545ed9feb..7fb7290c0019 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp @@ -36,14 +36,14 @@ //#define DEBUG_MANAGED_OBJECTS -#include -#include -#include "ac/dynobj/cc_dynamicobject.h" -#include "ac/dynobj/managedobjectpool.h" -#include "debug/out.h" -#include "script/cc_error.h" -#include "script/script_common.h" -#include "util/stream.h" +//include +//include +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" +#include "ags/shared/ac/dynobj/managedobjectpool.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/script_common.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index 9fc61a45183c..8e73a593f3a4 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCDYNAMICOBJECT_H #define AGS_ENGINE_AC_DYNOBJ_CCDYNAMICOBJECT_H -#include -#include "core/types.h" +#include "ags/std/utility.h" +#include "ags/shared/core/types.h" namespace AGS3 { @@ -114,9 +114,9 @@ extern int ccUnRegisterManagedObject(const void *object); // remove all registered objects extern void ccUnregisterAllObjects(); // serialize all objects to disk -extern void ccSerializeAllObjects(Common::Stream *out); +extern void ccSerializeAllObjects(Shared::Stream *out); // un-serialise all objects (will remove all currently registered ones) -extern int ccUnserializeAllObjects(Common::Stream *in, ICCObjectReader *callback); +extern int ccUnserializeAllObjects(Shared::Stream *in, ICCObjectReader *callback); // dispose the object if RefCount==0 extern void ccAttemptDisposeObject(int32_t handle); // translate between object handles and memory addresses diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h index 9087334e6b0f..416284c8120b 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_ADDR_AND_MANAGER_H #define AGS_ENGINE_AC_DYNOBJ_ADDR_AND_MANAGER_H -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_dynamicobject.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp index 3ef3e51fe909..9b2d472b5e31 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.cpp +++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/dynobj/cc_gui.h" -#include "ac/dynobj/scriptgui.h" +#include "ags/shared/ac/dynobj/cc_gui.h" +#include "ags/shared/ac/dynobj/scriptgui.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_gui.h b/engines/ags/engine/ac/dynobj/cc_gui.h index fb0d6974cbab..c33862580797 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.h +++ b/engines/ags/engine/ac/dynobj/cc_gui.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCGUI_H #define AGS_ENGINE_AC_DYNOBJ_CCGUI_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp index 8d344c7a7f26..9bbb9352dc73 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/dynobj/cc_guiobject.h" -#include "ac/dynobj/scriptgui.h" -#include "gui/guimain.h" -#include "gui/guiobject.h" +#include "ags/shared/ac/dynobj/cc_guiobject.h" +#include "ags/shared/ac/dynobj/scriptgui.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guiobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.h b/engines/ags/engine/ac/dynobj/cc_guiobject.h index f56c5589a6a2..4da35e13944a 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.h +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCGUI_H #define AGS_ENGINE_AC_DYNOBJ_CCGUI_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp index 8425c39eeea7..0bf87cf47987 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/dynobj/cc_hotspot.h" -#include "ac/dynobj/scripthotspot.h" -#include "ac/common_defines.h" -#include "game/roomstruct.h" +#include "ags/shared/ac/dynobj/cc_hotspot.h" +#include "ags/shared/ac/dynobj/scripthotspot.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/game/roomstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.h b/engines/ags/engine/ac/dynobj/cc_hotspot.h index 5b93be4a2d03..3a1beb8e618c 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.h +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCHOTSPOT_H #define AGS_ENGINE_AC_DYNOBJ_CCHOTSPOT_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp index 732a4da44b51..d213c84c2ee2 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.cpp +++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/dynobj/cc_inventory.h" -#include "ac/dynobj/scriptinvitem.h" -#include "ac/characterinfo.h" +#include "ags/shared/ac/dynobj/cc_inventory.h" +#include "ags/shared/ac/dynobj/scriptinvitem.h" +#include "ags/shared/ac/characterinfo.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.h b/engines/ags/engine/ac/dynobj/cc_inventory.h index 8287600cccc6..10edec6e0ce1 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.h +++ b/engines/ags/engine/ac/dynobj/cc_inventory.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCINVENTORY_H #define AGS_ENGINE_AC_DYNOBJ_CCINVENTORY_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp index 99c0d6f41bc6..092f5123db94 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.cpp +++ b/engines/ags/engine/ac/dynobj/cc_object.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/dynobj/cc_object.h" -#include "ac/dynobj/scriptobject.h" -#include "ac/common_defines.h" -#include "game/roomstruct.h" +#include "ags/shared/ac/dynobj/cc_object.h" +#include "ags/shared/ac/dynobj/scriptobject.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/game/roomstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_object.h b/engines/ags/engine/ac/dynobj/cc_object.h index b74c6ec2fc20..789e8c196f08 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.h +++ b/engines/ags/engine/ac/dynobj/cc_object.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCOBJECT_H #define AGS_ENGINE_AC_DYNOBJ_CCOBJECT_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp index fb140013f6d5..9d804eee84e1 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.cpp +++ b/engines/ags/engine/ac/dynobj/cc_region.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/dynobj/cc_region.h" -#include "ac/dynobj/scriptregion.h" -#include "ac/common_defines.h" -#include "game/roomstruct.h" +#include "ags/shared/ac/dynobj/cc_region.h" +#include "ags/shared/ac/dynobj/scriptregion.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/game/roomstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_region.h b/engines/ags/engine/ac/dynobj/cc_region.h index 2251fe3c0562..c0a21cffd4e0 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.h +++ b/engines/ags/engine/ac/dynobj/cc_region.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCREGION_H #define AGS_ENGINE_AC_DYNOBJ_CCREGION_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp index 53d6f42f876e..fc932e3fcd90 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.cpp +++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp @@ -20,19 +20,19 @@ * */ -#include -#include "ac/dynobj/cc_serializer.h" -#include "ac/dynobj/all_dynamicclasses.h" -#include "ac/dynobj/all_scriptclasses.h" -#include "ac/dynobj/scriptcamera.h" -#include "ac/dynobj/scriptcontainers.h" -#include "ac/dynobj/scriptfile.h" -#include "ac/dynobj/scriptuserobject.h" -#include "ac/dynobj/scriptviewport.h" -#include "ac/game.h" -#include "debug/debug_log.h" -#include "plugin/agsplugin.h" -#include "plugin/pluginobjectreader.h" +//include +#include "ags/shared/ac/dynobj/cc_serializer.h" +#include "ags/shared/ac/dynobj/all_dynamicclasses.h" +#include "ags/shared/ac/dynobj/all_scriptclasses.h" +#include "ags/shared/ac/dynobj/scriptcamera.h" +#include "ags/shared/ac/dynobj/scriptcontainers.h" +#include "ags/shared/ac/dynobj/scriptfile.h" +#include "ags/shared/ac/dynobj/scriptuserobject.h" +#include "ags/shared/ac/dynobj/scriptviewport.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/pluginobjectreader.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h index 5b43321ed4af..2d16667228df 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.h +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCSERIALIZER_H #define AGS_ENGINE_AC_DYNOBJ_CCSERIALIZER_H -#include "ac/dynobj/cc_dynamicobject.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index be2f46b4d2a0..d6a9d5b997c0 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -20,15 +20,15 @@ * */ -#include -#include -#include "ac/dynobj/managedobjectpool.h" -#include "ac/dynobj/cc_dynamicarray.h" // globalDynamicArray, constants -#include "debug/out.h" -#include "util/string_utils.h" // fputstring, etc -#include "script/cc_error.h" -#include "script/script_common.h" -#include "util/stream.h" +#include "ags/std/vector.h" +//include +#include "ags/shared/ac/dynobj/managedobjectpool.h" +#include "ags/shared/ac/dynobj/cc_dynamicarray.h" // globalDynamicArray, constants +#include "ags/shared/debug/out.h" +#include "ags/shared/util/string_utils.h" // fputstring, etc +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/script_common.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index e40ead0ac2b4..118df53d3f19 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -23,12 +23,12 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_MANAGEDOBJECTPOOL_H #define AGS_ENGINE_AC_DYNOBJ_MANAGEDOBJECTPOOL_H -#include -#include -#include +#include "ags/std/vector.h" +//include +//include -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject namespace AGS3 { namespace AGS { @@ -87,8 +87,8 @@ struct ManagedObjectPool final { void RunGarbageCollectionIfAppropriate(); int AddObject(const char *address, ICCDynamicObject *callback, bool plugin_object); int AddUnserializedObject(const char *address, ICCDynamicObject *callback, bool plugin_object, int handle); - void WriteToDisk(Common::Stream *out); - int ReadFromDisk(Common::Stream *in, ICCObjectReader *reader); + void WriteToDisk(Shared::Stream *out); + int ReadFromDisk(Shared::Stream *in, ICCObjectReader *reader); void reset(); ManagedObjectPool(); diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp index f5c079d2164a..0eebc6177f9d 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.cpp +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/dynobj/scriptcamera.h" -#include "ac/gamestate.h" -#include "util/bbop.h" +#include "ags/shared/ac/dynobj/scriptcamera.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/util/bbop.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.h b/engines/ags/engine/ac/dynobj/scriptcamera.h index d0ff62acfdf9..019896fc68e6 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.h +++ b/engines/ags/engine/ac/dynobj/scriptcamera.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTCAMERA_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTCAMERA_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp index 83b71cd88901..459cc717acae 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp @@ -20,7 +20,7 @@ * */ -#include "ac/dynobj/scriptdatetime.h" +#include "ags/shared/ac/dynobj/scriptdatetime.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.h b/engines/ags/engine/ac/dynobj/scriptdatetime.h index a714ff2cbe38..e7a002d504dd 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.h +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDATETIME_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDATETIME_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp index 1dcc21a77d35..017aaf599c58 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp @@ -20,7 +20,7 @@ * */ -#include "ac/dynobj/scriptdialogoptionsrendering.h" +#include "ags/shared/ac/dynobj/scriptdialogoptionsrendering.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h index 00fb395f8a4b..7a6bdf2d8d64 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOGOPTIONSRENDERING_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOGOPTIONSRENDERING_H -#include "ac/dynobj/scriptdrawingsurface.h" +#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdict.cpp b/engines/ags/engine/ac/dynobj/scriptdict.cpp index 94dbb00cf9e0..9260e2033234 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdict.cpp @@ -20,7 +20,7 @@ * */ -#include "ac/dynobj/scriptdict.h" +#include "ags/shared/ac/dynobj/scriptdict.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index ce1fe13b1507..85a0bdc7b3c7 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -36,12 +36,12 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDICT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDICT_H -#include -#include -#include -#include "ac/dynobj/cc_agsdynamicobject.h" -#include "util/string.h" -#include "util/string_types.h" +//include +//include +//include +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp index 703120f83639..24cd01bc94ec 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -20,15 +20,15 @@ * */ -#include "ac/dynobj/scriptdrawingsurface.h" -#include "ac/spritecache.h" -#include "ac/runtime_defines.h" -#include "ac/common.h" -#include "ac/drawingsurface.h" -#include "ac/gamestate.h" -#include "ac/gamesetupstruct.h" -#include "game/roomstruct.h" -#include "gfx/bitmap.h" +#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/drawingsurface.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h index 9d224c0babce..36385aa95a59 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDRAWINGSURFACE_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDRAWINGSURFACE_H -#include "ac/dynobj/cc_agsdynamicobject.h" -#include "game/roomstruct.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/game/roomstruct.h" namespace AGS3 { @@ -42,20 +42,20 @@ struct ScriptDrawingSurface final : AGSCCDynamicObject { int dynamicSpriteNumber; int dynamicSurfaceNumber; bool isLinkedBitmapOnly; - Common::Bitmap *linkedBitmapOnly; + Shared::Bitmap *linkedBitmapOnly; int currentColour; int currentColourScript; int highResCoordinates; int modified; int hasAlphaChannel; - //Common::Bitmap* abufBackup; + //Shared::Bitmap* abufBackup; int Dispose(const char *address, bool force) override; const char *GetType() override; int Serialize(const char *address, char *buffer, int bufsize) override; void Unserialize(int index, const char *serializedData, int dataSize) override; - Common::Bitmap *GetBitmapSurface(); - Common::Bitmap *StartDrawing(); + Shared::Bitmap *GetBitmapSurface(); + Shared::Bitmap *StartDrawing(); void PointToGameResolution(int *xcoord, int *ycoord); void SizeToGameResolution(int *width, int *height); void SizeToGameResolution(int *adjustValue); diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp index 69b739054021..83e94075f366 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/dynobj/scriptdynamicsprite.h" -#include "ac/dynamicsprite.h" +#include "ags/shared/ac/dynobj/scriptdynamicsprite.h" +#include "ags/shared/ac/dynamicsprite.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h index 252c2fc8b2d9..3418840f0508 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDYNAMICSPRITE_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDYNAMICSPRITE_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptfile.cpp b/engines/ags/engine/ac/dynobj/scriptfile.cpp index 203c94f0b0ac..8d75f62462a2 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.cpp +++ b/engines/ags/engine/ac/dynobj/scriptfile.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/dynobj/scriptfile.h" -#include "ac/global_file.h" +#include "ags/shared/ac/dynobj/scriptfile.h" +#include "ags/shared/ac/global_file.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptfile.h b/engines/ags/engine/ac/dynobj/scriptfile.h index 08e636a98b92..b5085c2e5a73 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.h +++ b/engines/ags/engine/ac/dynobj/scriptfile.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTFILE_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTFILE_H -#include "ac/dynobj/cc_dynamicobject.h" -#include "util/file.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" +#include "ags/shared/util/file.h" namespace AGS3 { @@ -37,8 +37,8 @@ using namespace AGS; // FIXME later struct sc_File final : ICCDynamicObject { int32_t handle; - static const Common::FileOpenMode fopenModes[]; - static const Common::FileWorkMode fworkModes[]; + static const Shared::FileOpenMode fopenModes[]; + static const Shared::FileWorkMode fworkModes[]; int Dispose(const char *address, bool force) override; diff --git a/engines/ags/engine/ac/dynobj/scriptobject.h b/engines/ags/engine/ac/dynobj/scriptobject.h index 3eb68dddd64e..6292bbddb4f6 100644 --- a/engines/ags/engine/ac/dynobj/scriptobject.h +++ b/engines/ags/engine/ac/dynobj/scriptobject.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTOBJECT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTOBJECT_H -#include "ac/roomobject.h" +#include "ags/engine/ac/roomobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp index 3beedc5c3acb..0a8f3be6754e 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp @@ -20,11 +20,11 @@ * */ -#include "ac/dynobj/scriptoverlay.h" -#include "ac/common.h" -#include "ac/overlay.h" -#include "ac/runtime_defines.h" -#include "ac/screenoverlay.h" +#include "ags/shared/ac/dynobj/scriptoverlay.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/screenoverlay.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.h b/engines/ags/engine/ac/dynobj/scriptoverlay.h index ed1e7d81b2a2..df73fa8881b9 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.h +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTOVERLAY_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTOVERLAY_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptset.cpp b/engines/ags/engine/ac/dynobj/scriptset.cpp index 626ce882c7ee..c3cc922ef901 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.cpp +++ b/engines/ags/engine/ac/dynobj/scriptset.cpp @@ -20,7 +20,7 @@ * */ -#include "ac/dynobj/scriptset.h" +#include "ags/shared/ac/dynobj/scriptset.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index ca7ecbc154c6..f20a979c8509 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -35,12 +35,12 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H -#include -#include -#include -#include "ac/dynobj/cc_agsdynamicobject.h" -#include "util/string.h" -#include "util/string_types.h" +//include +//include +//include +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptstring.cpp b/engines/ags/engine/ac/dynobj/scriptstring.cpp index e752f3e97f37..9f55a1c8f12e 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.cpp +++ b/engines/ags/engine/ac/dynobj/scriptstring.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/dynobj/scriptstring.h" -#include "ac/string.h" -#include -#include +#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/shared/ac/string.h" +//include +//include namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptstring.h b/engines/ags/engine/ac/dynobj/scriptstring.h index 84bff3c3226e..200eb93b2429 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.h +++ b/engines/ags/engine/ac/dynobj/scriptstring.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSTRING_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTSTRING_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp index 55e2baa04adb..e3d949c4bed0 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp @@ -20,8 +20,8 @@ * */ -#include -#include "scriptuserobject.h" +//include +#include "ags/shared/scriptuserobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h index ee2188013843..d54d32aaa594 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.h +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTUSERSTRUCT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTUSERSTRUCT_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp index 9a727afa6068..d60d45733bc9 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp @@ -20,7 +20,7 @@ * */ -#include "ac/dynobj/scriptviewframe.h" +#include "ags/shared/ac/dynobj/scriptviewframe.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.h b/engines/ags/engine/ac/dynobj/scriptviewframe.h index 4a4721eb7165..29edce6559b4 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.h +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWFRAME_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWFRAME_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp index 7bca084f19ce..8783de73079a 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/dynobj/scriptviewport.h" -#include "ac/gamestate.h" -#include "util/bbop.h" +#include "ags/shared/ac/dynobj/scriptviewport.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/util/bbop.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.h b/engines/ags/engine/ac/dynobj/scriptviewport.h index 61ae777aa970..9075190a09d6 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.h +++ b/engines/ags/engine/ac/dynobj/scriptviewport.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWPORT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWPORT_H -#include "ac/dynobj/cc_agsdynamicobject.h" +#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp index e7415dfe095b..cf8d118ab920 100644 --- a/engines/ags/engine/ac/event.cpp +++ b/engines/ags/engine/ac/event.cpp @@ -20,27 +20,27 @@ * */ -#include "event.h" -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_game.h" -#include "ac/global_room.h" -#include "ac/global_screen.h" -#include "ac/gui.h" -#include "ac/roomstatus.h" -#include "ac/screen.h" -#include "script/cc_error.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "script/script.h" -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "gfx/graphicsdriver.h" -#include "media/audio/audio_system.h" -#include "ac/timer.h" +#include "ags/shared/event.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/global_screen.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/screen.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/script/script.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/event.h b/engines/ags/engine/ac/event.h index 21b265f27b7c..2e1fb955fee2 100644 --- a/engines/ags/engine/ac/event.h +++ b/engines/ags/engine/ac/event.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_EVENT_H #define AGS_ENGINE_AC_EVENT_H -#include "ac/runtime_defines.h" -#include "script/runtimescriptvalue.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/script/runtimescriptvalue.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index 459e46dea941..6a6a30b0a859 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -20,31 +20,31 @@ * */ -#include "aldumb.h" -#include "ac/asset_helper.h" -#include "ac/audiocliptype.h" -#include "ac/file.h" -#include "ac/common.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_file.h" -#include "ac/path_helper.h" -#include "ac/runtime_defines.h" -#include "ac/string.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "util/misc.h" -#include "platform/base/agsplatformdriver.h" -#include "util/stream.h" -#include "core/assetmanager.h" -#include "core/asset.h" -#include "main/engine.h" -#include "main/game_file.h" -#include "util/directory.h" -#include "util/path.h" -#include "util/string.h" -#include "util/string_utils.h" +#include "ags/shared/aldumb.h" +#include "ags/shared/ac/asset_helper.h" +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/file.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_file.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/util/misc.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/core/asset.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/main/game_file.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { @@ -613,10 +613,10 @@ Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_ // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/file.h b/engines/ags/engine/ac/file.h index c3e52dfbef55..fb116d1213da 100644 --- a/engines/ags/engine/ac/file.h +++ b/engines/ags/engine/ac/file.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_AC_FILE_H #define AGS_ENGINE_AC_FILE_H -#include "ac/dynobj/scriptfile.h" -#include "ac/runtime_defines.h" +#include "ags/engine/ac/dynobj/scriptfile.h" +#include "ags/engine/ac/runtime_defines.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index da01664b110c..928974a26e4a 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -20,83 +20,83 @@ * */ -#include "ac/game.h" - -#include "ac/common.h" -#include "ac/view.h" -#include "ac/audiocliptype.h" -#include "ac/audiochannel.h" -#include "ac/character.h" -#include "ac/charactercache.h" -#include "ac/characterextras.h" -#include "ac/dialogtopic.h" -#include "ac/draw.h" -#include "ac/dynamicsprite.h" -#include "ac/event.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/global_character.h" -#include "ac/global_display.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/global_object.h" -#include "ac/global_translation.h" -#include "ac/gui.h" -#include "ac/hotspot.h" -#include "ac/lipsync.h" -#include "ac/mouse.h" -#include "ac/movelist.h" -#include "ac/objectcache.h" -#include "ac/overlay.h" -#include "ac/path_helper.h" -#include "ac/sys_events.h" -#include "ac/region.h" -#include "ac/richgamemedia.h" -#include "ac/room.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "ac/runtime_defines.h" -#include "ac/screenoverlay.h" -#include "ac/spritecache.h" -#include "ac/string.h" -#include "ac/system.h" -#include "ac/timer.h" -#include "ac/translation.h" -#include "ac/dynobj/all_dynamicclasses.h" -#include "ac/dynobj/all_scriptclasses.h" -#include "ac/dynobj/cc_audiochannel.h" -#include "ac/dynobj/cc_audioclip.h" -#include "ac/dynobj/scriptcamera.h" -#include "debug/debug_log.h" -#include "debug/out.h" -#include "device/mousew32.h" -#include "font/fonts.h" -#include "game/savegame.h" -#include "game/savegame_components.h" -#include "game/savegame_internal.h" -#include "gui/animatingguibutton.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" -#include "gfx/gfxfilter.h" -#include "gui/guidialog.h" -#include "main/engine.h" -#include "main/graphics_mode.h" -#include "main/main.h" -#include "media/audio/audio_system.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "script/cc_error.h" -#include "script/runtimescriptvalue.h" -#include "script/script.h" -#include "script/script_runtime.h" -#include "util/alignedstream.h" -#include "util/directory.h" -#include "util/filestream.h" // TODO: needed only because plugins expect file handle -#include "util/path.h" -#include "util/string_utils.h" -#include "ac/keycode.h" +#include "ags/shared/ac/game.h" + +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/audiochannel.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/charactercache.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_object.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/hotspot.h" +#include "ags/shared/ac/lipsync.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/region.h" +#include "ags/shared/ac/richgamemedia.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/timer.h" +#include "ags/shared/ac/translation.h" +#include "ags/shared/ac/dynobj/all_dynamicclasses.h" +#include "ags/shared/ac/dynobj/all_scriptclasses.h" +#include "ags/shared/ac/dynobj/cc_audiochannel.h" +#include "ags/shared/ac/dynobj/cc_audioclip.h" +#include "ags/shared/ac/dynobj/scriptcamera.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/game/savegame.h" +#include "ags/shared/game/savegame_components.h" +#include "ags/shared/game/savegame_internal.h" +#include "ags/shared/gui/animatingguibutton.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/main/graphics_mode.h" +#include "ags/shared/main/main.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/filestream.h" // TODO: needed only because plugins expect file handle +#include "ags/shared/util/path.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/ac/keycode.h" namespace AGS3 { @@ -890,7 +890,7 @@ void Game_SimulateKeyPress(int key) { -void serialize_bitmap(const Common::Bitmap *thispic, Stream *out) { +void serialize_bitmap(const Shared::Bitmap *thispic, Stream *out) { if (thispic != nullptr) { out->WriteInt32(thispic->GetWidth()); out->WriteInt32(thispic->GetHeight()); @@ -1604,7 +1604,7 @@ bool try_restore_save(int slot) { return try_restore_save(get_save_game_path(slot), slot); } -bool try_restore_save(const Common::String &path, int slot) { +bool try_restore_save(const Shared::String &path, int slot) { bool data_overwritten; HSaveError err = load_game(path, slot, data_overwritten); if (!err) { @@ -1937,9 +1937,9 @@ bool unserialize_audio_script_object(int index, const char *objectType, const ch // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // int (int audioType); RuntimeScriptValue Sc_Game_IsAudioPlaying(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h index 15cb70ffe3dc..2d6c81380507 100644 --- a/engines/ags/engine/ac/game.h +++ b/engines/ags/engine/ac/game.h @@ -29,9 +29,9 @@ #ifndef AGS_ENGINE_AC_GAME_H #define AGS_ENGINE_AC_GAME_H -#include "ac/dynobj/scriptviewframe.h" -#include "main/game_file.h" -#include "util/string.h" +#include "ags/engine/ac/dynobj/scriptviewframe.h" +#include "ags/engine/main/game_file.h" +#include "ags/shared/util/string.h" namespace AGS3 { @@ -94,7 +94,7 @@ int Game_GetDialogCount(); // Defines a custom save parent directory, which will replace $MYDOCS$/GameName // when a new save directory is set from the script -bool SetCustomSaveParent(const Common::String &path); +bool SetCustomSaveParent(const Shared::String &path); // If explicit_path flag is false, the actual path will be constructed // as a relative to system's user saves directory bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path = false); @@ -149,28 +149,28 @@ void set_debug_mode(bool on); void set_game_speed(int new_fps); void setup_for_dialog(); void restore_after_dialog(); -Common::String get_save_game_directory(); -Common::String get_save_game_suffix(); -void set_save_game_suffix(const Common::String &suffix); -Common::String get_save_game_path(int slotNum); +Shared::String get_save_game_directory(); +Shared::String get_save_game_suffix(); +void set_save_game_suffix(const Shared::String &suffix); +Shared::String get_save_game_path(int slotNum); void restore_game_dialog(); void save_game_dialog(); void free_do_once_tokens(); // Free all the memory associated with the game void unload_game_file(); void save_game(int slotn, const char *descript); -bool read_savedgame_description(const Common::String &savedgame, Common::String &description); -bool read_savedgame_screenshot(const Common::String &savedgame, int &want_shot); +bool read_savedgame_description(const Shared::String &savedgame, Shared::String &description); +bool read_savedgame_screenshot(const Shared::String &savedgame, int &want_shot); // Tries to restore saved game and displays an error on failure; if the error occured // too late, when the game data was already overwritten, shuts engine down. bool try_restore_save(int slot); -bool try_restore_save(const Common::String &path, int slot); -void serialize_bitmap(const Common::Bitmap *thispic, Common::Stream *out); +bool try_restore_save(const Shared::String &path, int slot); +void serialize_bitmap(const Shared::Bitmap *thispic, Shared::Stream *out); // On Windows we could just use IIDFromString but this is platform-independant void convert_guid_from_text_to_binary(const char *guidText, unsigned char *buffer); -Common::Bitmap *read_serialized_bitmap(Common::Stream *in); -void skip_serialized_bitmap(Common::Stream *in); -long write_screen_shot_for_vista(Common::Stream *out, Common::Bitmap *screenshot); +Shared::Bitmap *read_serialized_bitmap(Shared::Stream *in); +void skip_serialized_bitmap(Shared::Stream *in); +long write_screen_shot_for_vista(Shared::Stream *out, Shared::Bitmap *screenshot); bool is_in_cutscene(); CutsceneSkipStyle get_cutscene_skipstyle(); diff --git a/engines/ags/engine/ac/gamesetup.cpp b/engines/ags/engine/ac/gamesetup.cpp index 8f197591b55a..2bce8af2e1b3 100644 --- a/engines/ags/engine/ac/gamesetup.cpp +++ b/engines/ags/engine/ac/gamesetup.cpp @@ -20,8 +20,8 @@ * */ -#include "util/wgt2allg.h" // DIGI_AUTODETECT & MIDI_AUTODETECT -#include "ac/gamesetup.h" +#include "ags/shared/util/wgt2allg.h" // DIGI_AUTODETECT & MIDI_AUTODETECT +#include "ags/shared/ac/gamesetup.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/gamesetup.h b/engines/ags/engine/ac/gamesetup.h index 5f1f48ad7c46..2b207176b3d5 100644 --- a/engines/ags/engine/ac/gamesetup.h +++ b/engines/ags/engine/ac/gamesetup.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GAMESETUP_H #define AGS_ENGINE_AC_GAMESETUP_H -#include "main/graphics_mode.h" -#include "util/string.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index aa1d3749d237..b6e186b61019 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -20,24 +20,24 @@ * */ -#include -#include "ac/draw.h" -#include "ac/game_version.h" -#include "ac/gamestate.h" -#include "ac/gamesetupstruct.h" -#include "ac/timer.h" -#include "ac/dynobj/scriptcamera.h" -#include "ac/dynobj/scriptsystem.h" -#include "ac/dynobj/scriptviewport.h" -#include "debug/debug_log.h" -#include "device/mousew32.h" -#include "game/customproperties.h" -#include "game/roomstruct.h" -#include "game/savegame_internal.h" -#include "main/engine.h" -#include "media/audio/audio_system.h" -#include "util/alignedstream.h" -#include "util/string_utils.h" +//include +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/timer.h" +#include "ags/shared/ac/dynobj/scriptcamera.h" +#include "ags/shared/ac/dynobj/scriptsystem.h" +#include "ags/shared/ac/dynobj/scriptviewport.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/game/customproperties.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/game/savegame_internal.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { @@ -372,7 +372,7 @@ bool GameState::ShouldPlayVoiceSpeech() const { (play.want_speech >= 1) && (!ResPaths.SpeechPak.Name.IsEmpty()); } -void GameState::ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, RestoredData &r_data) { +void GameState::ReadFromSavegame(Shared::Stream *in, GameStateSvgVersion svg_ver, RestoredData &r_data) { const bool old_save = svg_ver < kGSSvgVersion_Initial; score = in->ReadInt32(); usedmode = in->ReadInt32(); @@ -595,7 +595,7 @@ void GameState::ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver } } -void GameState::WriteForSavegame(Common::Stream *out) const { +void GameState::WriteForSavegame(Shared::Stream *out) const { // NOTE: following parameters are never saved: // recording, playback, gamestep, screen_is_faded_out, room_changes out->WriteInt32(score); @@ -776,7 +776,7 @@ void GameState::WriteForSavegame(Common::Stream *out) const { out->WriteInt32(voice_speech_flags); } -void GameState::ReadQueuedAudioItems_Aligned(Common::Stream *in) { +void GameState::ReadQueuedAudioItems_Aligned(Shared::Stream *in) { AlignedStream align_s(in, Common::kAligned_Read); for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) { new_music_queue[i].ReadFromFile(&align_s); @@ -807,7 +807,7 @@ void GameState::FreeViewportsAndCameras() { _scCameraRefs.clear(); } -void GameState::ReadCustomProperties_v340(Common::Stream *in) { +void GameState::ReadCustomProperties_v340(Shared::Stream *in) { if (loaded_game_file_version >= kGameVersion_340_4) { // After runtime property values were read we also copy missing default, // because we do not keep defaults in the saved game, and also in case @@ -820,7 +820,7 @@ void GameState::ReadCustomProperties_v340(Common::Stream *in) { } } -void GameState::WriteCustomProperties_v340(Common::Stream *out) const { +void GameState::WriteCustomProperties_v340(Shared::Stream *out) const { if (loaded_game_file_version >= kGameVersion_340_4) { // We temporarily remove properties that kept default values // just for the saving data time to avoid getting lots of diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h index 617153b51bc5..cf6102581fb7 100644 --- a/engines/ags/engine/ac/gamestate.h +++ b/engines/ags/engine/ac/gamestate.h @@ -23,18 +23,17 @@ #ifndef AGS_ENGINE_AC_GAMESTATE_H #define AGS_ENGINE_AC_GAMESTATE_H -#include -#include - -#include "ac/characterinfo.h" -#include "ac/runtime_defines.h" -#include "game/roomstruct.h" -#include "game/viewport.h" -#include "media/audio/queuedaudioitem.h" -#include "util/geometry.h" -#include "util/string_types.h" -#include "util/string.h" -#include "ac/timer.h" +#include "ags/std/memory.h" +#include "ags/std/vector.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/engine/game/viewport.h" +#include "ags/engine/media/audio/queuedaudioitem.h" +#include "ags/shared/util/geometry.h" +#include "ags/shared/util/string_types.h" +#include "ags/shared/util/string.h" +#include "ags/engine/ac/timer.h" namespace AGS3 { @@ -185,7 +184,7 @@ struct GameState { char bad_parsed_word[100]; int raw_color; int raw_modified[MAX_ROOM_BGFRAMES]; - Common::PBitmap raw_drawing_surface; + Shared::PBitmap raw_drawing_surface; short filenumbers[MAXSAVEGAMES]; int room_changes; int mouse_cursor_hidden; @@ -354,11 +353,11 @@ struct GameState { // // Serialization // - void ReadQueuedAudioItems_Aligned(Common::Stream *in); - void ReadCustomProperties_v340(Common::Stream *in); - void WriteCustomProperties_v340(Common::Stream *out) const; - void ReadFromSavegame(Common::Stream *in, GameStateSvgVersion svg_ver, AGS::Engine::RestoredData &r_data); - void WriteForSavegame(Common::Stream *out) const; + void ReadQueuedAudioItems_Aligned(Shared::Stream *in); + void ReadCustomProperties_v340(Shared::Stream *in); + void WriteCustomProperties_v340(Shared::Stream *out) const; + void ReadFromSavegame(Shared::Stream *in, GameStateSvgVersion svg_ver, AGS::Engine::RestoredData &r_data); + void WriteForSavegame(Shared::Stream *out) const; void FreeProperties(); void FreeViewportsAndCameras(); diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp index 5a36bf5de664..ce894d675e59 100644 --- a/engines/ags/engine/ac/global_api.cpp +++ b/engines/ags/engine/ac/global_api.cpp @@ -26,61 +26,61 @@ // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" - -#include "ac/cdaudio.h" -#include "ac/display.h" -#include "ac/dynamicsprite.h" -#include "ac/event.h" -#include "ac/game.h" -#include "ac/global_audio.h" -#include "ac/global_button.h" -#include "ac/global_character.h" -#include "ac/global_datetime.h" -#include "ac/global_debug.h" -#include "ac/global_dialog.h" -#include "ac/global_display.h" -#include "ac/global_drawingsurface.h" -#include "ac/global_dynamicsprite.h" -#include "ac/global_file.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/global_hotspot.h" -#include "ac/global_inventoryitem.h" -#include "ac/global_invwindow.h" -#include "ac/global_label.h" -#include "ac/global_listbox.h" -#include "ac/global_mouse.h" -#include "ac/global_object.h" -#include "ac/global_overlay.h" -#include "ac/global_palette.h" -#include "ac/global_parser.h" -#include "ac/global_record.h" -#include "ac/global_region.h" -#include "ac/global_room.h" -#include "ac/global_slider.h" -#include "ac/global_screen.h" -#include "ac/global_string.h" -#include "ac/global_textbox.h" -#include "ac/global_timer.h" -#include "ac/global_translation.h" -#include "ac/global_video.h" -#include "ac/global_viewframe.h" -#include "ac/global_viewport.h" -#include "ac/global_walkablearea.h" -#include "ac/global_walkbehind.h" -#include "ac/math.h" -#include "ac/mouse.h" -#include "ac/parser.h" -#include "ac/string.h" -#include "ac/room.h" -#include "media/video/video.h" -#include "util/string_compat.h" -#include "media/audio/audio_system.h" - -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" + +#include "ags/shared/ac/cdaudio.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_button.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_datetime.h" +#include "ags/shared/ac/global_debug.h" +#include "ags/shared/ac/global_dialog.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/global_drawingsurface.h" +#include "ags/shared/ac/global_dynamicsprite.h" +#include "ags/shared/ac/global_file.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_hotspot.h" +#include "ags/shared/ac/global_inventoryitem.h" +#include "ags/shared/ac/global_invwindow.h" +#include "ags/shared/ac/global_label.h" +#include "ags/shared/ac/global_listbox.h" +#include "ags/shared/ac/global_mouse.h" +#include "ags/shared/ac/global_object.h" +#include "ags/shared/ac/global_overlay.h" +#include "ags/shared/ac/global_palette.h" +#include "ags/shared/ac/global_parser.h" +#include "ags/shared/ac/global_record.h" +#include "ags/shared/ac/global_region.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/global_slider.h" +#include "ags/shared/ac/global_screen.h" +#include "ags/shared/ac/global_string.h" +#include "ags/shared/ac/global_textbox.h" +#include "ags/shared/ac/global_timer.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/global_video.h" +#include "ags/shared/ac/global_viewframe.h" +#include "ags/shared/ac/global_viewport.h" +#include "ags/shared/ac/global_walkablearea.h" +#include "ags/shared/ac/global_walkbehind.h" +#include "ags/shared/ac/math.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/parser.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/media/video/video.h" +#include "ags/shared/util/string_compat.h" +#include "ags/shared/media/audio/audio_system.h" + +#include "ags/shared/ac/dynobj/scriptstring.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp index 06de369d830f..10ae491f76f7 100644 --- a/engines/ags/engine/ac/global_audio.cpp +++ b/engines/ags/engine/ac/global_audio.cpp @@ -20,21 +20,21 @@ * */ -#include "ac/common.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/lipsync.h" -#include "ac/path_helper.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "game/roomstruct.h" -#include "main/engine.h" -#include "media/audio/audio_system.h" -#include "ac/timer.h" -#include "util/string_compat.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/lipsync.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/ac/timer.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp index 5e78ed739ae2..3b6124ed1131 100644 --- a/engines/ags/engine/ac/global_button.cpp +++ b/engines/ags/engine/ac/global_button.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/global_button.h" -#include "ac/common.h" -#include "ac/button.h" -#include "ac/gamesetupstruct.h" -#include "ac/string.h" -#include "gui/guimain.h" -#include "gui/guibutton.h" +#include "ags/shared/ac/global_button.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/button.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guibutton.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp index e5098d258e35..e1ea22755639 100644 --- a/engines/ags/engine/ac/global_character.cpp +++ b/engines/ags/engine/ac/global_character.cpp @@ -26,26 +26,26 @@ // //============================================================================= -#include "ac/global_character.h" -#include "ac/common.h" -#include "ac/view.h" -#include "ac/character.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_overlay.h" -#include "ac/global_translation.h" -#include "ac/object.h" -#include "ac/overlay.h" -#include "ac/properties.h" -#include "ac/screenoverlay.h" -#include "ac/string.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "main/game_run.h" -#include "script/script.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_overlay.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_character.h b/engines/ags/engine/ac/global_character.h index ac9acb19d5b7..6745d410b5e6 100644 --- a/engines/ags/engine/ac/global_character.h +++ b/engines/ags/engine/ac/global_character.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBALCHARACTER_H #define AGS_ENGINE_AC_GLOBALCHARACTER_H -#include "ac/characterinfo.h" +#include "ags/shared/ac/characterinfo.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_datetime.cpp b/engines/ags/engine/ac/global_datetime.cpp index 11db83ec9444..2151e00cc7b7 100644 --- a/engines/ags/engine/ac/global_datetime.cpp +++ b/engines/ags/engine/ac/global_datetime.cpp @@ -20,10 +20,10 @@ * */ -#include -#include "ac/global_datetime.h" -#include "ac/datetime.h" -#include "ac/common.h" +//include +#include "ags/shared/ac/global_datetime.h" +#include "ags/shared/ac/datetime.h" +#include "ags/shared/ac/common.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp index 87f13bddf232..14723841504d 100644 --- a/engines/ags/engine/ac/global_debug.cpp +++ b/engines/ags/engine/ac/global_debug.cpp @@ -20,32 +20,32 @@ * */ -#include "ac/global_debug.h" -#include "ac/common.h" -#include "ac/characterinfo.h" -#include "ac/draw.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_character.h" -#include "ac/global_display.h" -#include "ac/global_room.h" -#include "ac/movelist.h" -#include "ac/properties.h" -#include "ac/sys_events.h" -#include "ac/tree_map.h" -#include "ac/walkablearea.h" -#include "gfx/gfxfilter.h" -#include "gui/guidialog.h" -#include "script/cc_options.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "main/main.h" -#include "ac/spritecache.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" -#include "main/graphics_mode.h" +#include "ags/shared/ac/global_debug.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/tree_map.h" +#include "ags/shared/ac/walkablearea.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/script/cc_options.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/main/main.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/main/graphics_mode.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_debug.h b/engines/ags/engine/ac/global_debug.h index bd60f9340bb7..f104c53fcc0a 100644 --- a/engines/ags/engine/ac/global_debug.h +++ b/engines/ags/engine/ac/global_debug.h @@ -23,8 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBALDEBUG_H #define AGS_ENGINE_AC_GLOBALDEBUG_H -#include -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_dialog.cpp b/engines/ags/engine/ac/global_dialog.cpp index b2b95c497ebf..d5faa9009750 100644 --- a/engines/ags/engine/ac/global_dialog.cpp +++ b/engines/ags/engine/ac/global_dialog.cpp @@ -20,16 +20,16 @@ * */ -#include "ac/global_dialog.h" -#include "ac/common.h" -#include "ac/dialog.h" -#include "ac/dialogtopic.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "debug/out.h" -#include "script/script.h" +#include "ags/shared/ac/global_dialog.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/dialog.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp index 7aa5326bc242..18658b6740b3 100644 --- a/engines/ags/engine/ac/global_display.cpp +++ b/engines/ags/engine/ac/global_display.cpp @@ -20,26 +20,26 @@ * */ -#include -#include -#include "ac/common.h" -#include "ac/character.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_character.h" -#include "ac/global_display.h" -#include "ac/global_screen.h" -#include "ac/global_translation.h" -#include "ac/runtime_defines.h" -#include "ac/speech.h" -#include "ac/string.h" -#include "ac/topbarsettings.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "main/game_run.h" +//include +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/global_screen.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/speech.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/topbarsettings.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/main/game_run.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_display.h b/engines/ags/engine/ac/global_display.h index 29652e893bbd..1a813a9492f1 100644 --- a/engines/ags/engine/ac/global_display.h +++ b/engines/ags/engine/ac/global_display.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBALDISPLAY_H #define AGS_ENGINE_AC_GLOBALDISPLAY_H -#include "ac/speech.h" +#include "ags/engine/ac/speech.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp index 36d19cb0e8c8..acee470f8f4f 100644 --- a/engines/ags/engine/ac/global_drawingsurface.cpp +++ b/engines/ags/engine/ac/global_drawingsurface.cpp @@ -20,22 +20,22 @@ * */ -#include "ac/common.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_drawingsurface.h" -#include "ac/global_translation.h" -#include "ac/string.h" -#include "debug/debug_log.h" -#include "font/fonts.h" -#include "game/roomstruct.h" -#include "gui/guidefines.h" -#include "ac/spritecache.h" -#include "gfx/gfx_def.h" -#include "gfx/gfx_util.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_drawingsurface.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gui/guidefines.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/gfx_def.h" +#include "ags/shared/gfx/gfx_util.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_drawingsurface.h b/engines/ags/engine/ac/global_drawingsurface.h index 05a1ce714528..f6f8b81623ea 100644 --- a/engines/ags/engine/ac/global_drawingsurface.h +++ b/engines/ags/engine/ac/global_drawingsurface.h @@ -27,7 +27,7 @@ namespace AGS3 { void RawSaveScreen(); // RawRestoreScreen: copy backup bitmap back to screen; we -// deliberately don't free the Common::Bitmap *cos they can multiple restore +// deliberately don't free the Shared::Bitmap *cos they can multiple restore // and it gets freed on room exit anyway void RawRestoreScreen(); // Restores the backup bitmap, but tints it to the specified level diff --git a/engines/ags/engine/ac/global_dynamicsprite.cpp b/engines/ags/engine/ac/global_dynamicsprite.cpp index b4019f1a3559..e9cb5979f408 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.cpp +++ b/engines/ags/engine/ac/global_dynamicsprite.cpp @@ -20,15 +20,15 @@ * */ -#include "ac/global_dynamicsprite.h" -#include "util/wgt2allg.h" // Allegro RGB, PALETTE -#include "ac/draw.h" -#include "ac/dynamicsprite.h" -#include "ac/path_helper.h" -#include "ac/spritecache.h" -#include "ac/runtime_defines.h" //MAX_PATH -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" +#include "ags/shared/ac/global_dynamicsprite.h" +#include "ags/shared/util/wgt2allg.h" // Allegro RGB, PALETTE +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/ac/runtime_defines.h" //MAX_PATH +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index 94b1c7ef46a6..0f3708b03f97 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -20,17 +20,17 @@ * */ -#include -#include "ac/global_file.h" -#include "ac/common.h" -#include "ac/file.h" -#include "ac/path_helper.h" -#include "ac/runtime_defines.h" -#include "ac/string.h" -#include "debug/debug_log.h" -#include "util/directory.h" -#include "util/path.h" -#include "util/stream.h" +//include +#include "ags/shared/ac/global_file.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/file.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_file.h b/engines/ags/engine/ac/global_file.h index be068bf1cfbb..1392c5859b56 100644 --- a/engines/ags/engine/ac/global_file.h +++ b/engines/ags/engine/ac/global_file.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBAL_FILE_H #define AGS_ENGINE_AC_GLOBAL_FILE_H -#include "util/file.h" +#include "ags/shared/util/file.h" namespace AGS3 { namespace AGS { @@ -34,7 +34,7 @@ class Stream; using namespace AGS; // FIXME later -int32_t FileOpen(const char *fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode); +int32_t FileOpen(const char *fnmm, Shared::FileOpenMode open_mode, Shared::FileWorkMode work_mode); // NOTE: FileOpenCMode is a backwards-compatible replacement for old-style global script function FileOpen int32_t FileOpenCMode(const char *fnmm, const char *cmode); void FileClose(int32_t handle); diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 8d2c9a36a5ff..b13d206904a6 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -20,54 +20,54 @@ * */ -#include - -#include "core/platform.h" -#include "ac/audiocliptype.h" -#include "ac/global_game.h" -#include "ac/common.h" -#include "ac/view.h" -#include "ac/character.h" -#include "ac/draw.h" -#include "ac/dynamicsprite.h" -#include "ac/event.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_character.h" -#include "ac/global_gui.h" -#include "ac/global_hotspot.h" -#include "ac/global_inventoryitem.h" -#include "ac/global_translation.h" -#include "ac/gui.h" -#include "ac/hotspot.h" -#include "ac/keycode.h" -#include "ac/mouse.h" -#include "ac/object.h" -#include "ac/path_helper.h" -#include "ac/sys_events.h" -#include "ac/room.h" -#include "ac/roomstatus.h" -#include "ac/string.h" -#include "ac/system.h" -#include "debug/debugger.h" -#include "debug/debug_log.h" -#include "gui/guidialog.h" -#include "main/engine.h" -#include "main/game_start.h" -#include "main/game_run.h" -#include "main/graphics_mode.h" -#include "script/script.h" -#include "script/script_runtime.h" -#include "ac/spritecache.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" -#include "core/assetmanager.h" -#include "main/config.h" -#include "main/game_file.h" -#include "util/string_utils.h" -#include "media/audio/audio_system.h" +//include + +#include "ags/shared/core/platform.h" +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_hotspot.h" +#include "ags/shared/ac/global_inventoryitem.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/hotspot.h" +#include "ags/shared/ac/keycode.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/main/game_start.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/main/graphics_mode.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/main/config.h" +#include "ags/shared/main/game_file.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h index d60b9d83295d..8280887aa579 100644 --- a/engines/ags/engine/ac/global_game.h +++ b/engines/ags/engine/ac/global_game.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_GLOBAL_GAME_H #define AGS_ENGINE_AC_GLOBAL_GAME_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp index e5481f541d7d..fcd7223b2718 100644 --- a/engines/ags/engine/ac/global_gui.cpp +++ b/engines/ags/engine/ac/global_gui.cpp @@ -20,21 +20,21 @@ * */ -#include "ac/common.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/gui.h" -#include "ac/guicontrol.h" -#include "ac/mouse.h" -#include "ac/string.h" -#include "debug/debug_log.h" -#include "font/fonts.h" -#include "gui/guimain.h" -#include "script/runtimescriptvalue.h" -#include "util/string_compat.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/guicontrol.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp index 747b169670fb..b6021c650ab1 100644 --- a/engines/ags/engine/ac/global_hotspot.cpp +++ b/engines/ags/engine/ac/global_hotspot.cpp @@ -20,22 +20,22 @@ * */ -#include "ac/global_hotspot.h" -#include "ac/common.h" -#include "ac/common_defines.h" -#include "ac/characterinfo.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_character.h" -#include "ac/global_translation.h" -#include "ac/hotspot.h" -#include "ac/properties.h" -#include "ac/roomstatus.h" -#include "ac/string.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "script/script.h" +#include "ags/shared/ac/global_hotspot.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/hotspot.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp index 45f2b1170d69..7d2f7885d821 100644 --- a/engines/ags/engine/ac/global_inventoryitem.cpp +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -20,19 +20,19 @@ * */ -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_gui.h" -#include "ac/global_inventoryitem.h" -#include "ac/global_translation.h" -#include "ac/inventoryitem.h" -#include "ac/invwindow.h" -#include "ac/properties.h" -#include "ac/string.h" -#include "gui/guimain.h" -#include "gui/guiinv.h" -#include "ac/event.h" -#include "ac/gamestate.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_inventoryitem.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/inventoryitem.h" +#include "ags/shared/ac/invwindow.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_invwindow.cpp b/engines/ags/engine/ac/global_invwindow.cpp index 64553f430f25..cb3ef9ef1e15 100644 --- a/engines/ags/engine/ac/global_invwindow.cpp +++ b/engines/ags/engine/ac/global_invwindow.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/gamestate.h" -#include "ac/global_invwindow.h" -#include "ac/global_translation.h" -#include "ac/properties.h" -#include "gui/guiinv.h" -#include "script/executingscript.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_invwindow.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/script/executingscript.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp index 770a1f971d0e..8c1b404bd475 100644 --- a/engines/ags/engine/ac/global_label.cpp +++ b/engines/ags/engine/ac/global_label.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/global_label.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/label.h" -#include "ac/string.h" -#include "gui/guimain.h" +#include "ags/shared/ac/global_label.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/label.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/gui/guimain.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_listbox.cpp b/engines/ags/engine/ac/global_listbox.cpp index 935927cbe5e6..ef607a52f731 100644 --- a/engines/ags/engine/ac/global_listbox.cpp +++ b/engines/ags/engine/ac/global_listbox.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/global_listbox.h" -#include "ac/common.h" -#include "ac/listbox.h" -#include "ac/string.h" +#include "ags/shared/ac/global_listbox.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/listbox.h" +#include "ags/shared/ac/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_mouse.cpp b/engines/ags/engine/ac/global_mouse.cpp index 8b0e30bf5312..6310da0da325 100644 --- a/engines/ags/engine/ac/global_mouse.cpp +++ b/engines/ags/engine/ac/global_mouse.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/global_mouse.h" -#include "ac/gamestate.h" +#include "ags/shared/ac/global_mouse.h" +#include "ags/shared/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp index 4feb25f4fab7..3be568fa04e0 100644 --- a/engines/ags/engine/ac/global_object.cpp +++ b/engines/ags/engine/ac/global_object.cpp @@ -20,30 +20,30 @@ * */ -#include "ac/global_object.h" -#include "ac/common.h" -#include "ac/object.h" -#include "ac/view.h" -#include "ac/character.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_character.h" -#include "ac/global_translation.h" -#include "ac/object.h" -#include "ac/objectcache.h" -#include "ac/properties.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "ac/string.h" -#include "ac/viewframe.h" -#include "debug/debug_log.h" -#include "main/game_run.h" -#include "script/script.h" -#include "ac/spritecache.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" -#include "gfx/gfx_def.h" +#include "ags/shared/ac/global_object.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/viewframe.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/script/script.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfx_def.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_object.h b/engines/ags/engine/ac/global_object.h index 4d192b82a982..730432266224 100644 --- a/engines/ags/engine/ac/global_object.h +++ b/engines/ags/engine/ac/global_object.h @@ -77,7 +77,7 @@ int AreThingsOverlapping(int thing1, int thing2); int GetObjectProperty(int hss, const char *property); void GetObjectPropertyText(int item, const char *property, char *bufer); -Common::Bitmap *GetObjectImage(int obj, int *isFlipped); +Shared::Bitmap *GetObjectImage(int obj, int *isFlipped); } // namespace AGS3 diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp index ddc79f05546c..3f1c82ec105f 100644 --- a/engines/ags/engine/ac/global_overlay.cpp +++ b/engines/ags/engine/ac/global_overlay.cpp @@ -20,20 +20,20 @@ * */ -#include "ac/global_overlay.h" -#include "ac/common.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_translation.h" -#include "ac/overlay.h" -#include "ac/runtime_defines.h" -#include "ac/screenoverlay.h" -#include "ac/string.h" -#include "ac/spritecache.h" -#include "ac/system.h" -#include "gfx/bitmap.h" +#include "ags/shared/ac/global_overlay.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_palette.cpp b/engines/ags/engine/ac/global_palette.cpp index 63a4f741e7cb..0d8bc049fb6e 100644 --- a/engines/ags/engine/ac/global_palette.cpp +++ b/engines/ags/engine/ac/global_palette.cpp @@ -20,11 +20,11 @@ * */ -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_palette.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_palette.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_parser.cpp b/engines/ags/engine/ac/global_parser.cpp index 6ae278cd1833..68635efc5893 100644 --- a/engines/ags/engine/ac/global_parser.cpp +++ b/engines/ags/engine/ac/global_parser.cpp @@ -20,11 +20,11 @@ * */ -#include //strcpy() -#include "ac/global_parser.h" -#include "ac/common.h" -#include "ac/gamestate.h" -#include "ac/string.h" +//include //strcpy() +#include "ags/shared/ac/global_parser.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_record.cpp b/engines/ags/engine/ac/global_record.cpp index 9f2358045d80..6e6e0c92f808 100644 --- a/engines/ags/engine/ac/global_record.cpp +++ b/engines/ags/engine/ac/global_record.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/global_record.h" -#include "ac/common.h" +#include "ags/shared/ac/global_record.h" +#include "ags/shared/ac/common.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp index e607e353c586..e1307d3941dd 100644 --- a/engines/ags/engine/ac/global_region.cpp +++ b/engines/ags/engine/ac/global_region.cpp @@ -20,16 +20,16 @@ * */ -#include "ac/global_region.h" -#include "ac/common.h" -#include "ac/game_version.h" -#include "ac/region.h" -#include "ac/room.h" -#include "ac/roomstatus.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "gfx/bitmap.h" -#include "script/script.h" +#include "ags/shared/ac/global_region.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/region.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp index 7fadb5a72b5c..ff23f92d91a0 100644 --- a/engines/ags/engine/ac/global_room.cpp +++ b/engines/ags/engine/ac/global_room.cpp @@ -20,24 +20,24 @@ * */ -#include "ac/global_room.h" -#include "ac/common.h" -#include "ac/character.h" -#include "ac/characterinfo.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_character.h" -#include "ac/global_game.h" -#include "ac/movelist.h" -#include "ac/properties.h" -#include "ac/room.h" -#include "ac/roomstatus.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "script/script.h" -#include "util/math.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/script/script.h" +#include "ags/shared/util/math.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp index 8ae85266af07..801402420365 100644 --- a/engines/ags/engine/ac/global_screen.cpp +++ b/engines/ags/engine/ac/global_screen.cpp @@ -20,20 +20,20 @@ * */ -#include "ac/common.h" -#include "ac/gamesetup.h" -#include "ac/draw.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_game.h" -#include "ac/global_screen.h" -#include "ac/runtime_defines.h" -#include "ac/screen.h" -#include "debug/debug_log.h" -#include "platform/base/agsplatformdriver.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_screen.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/screen.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp index b05ddacc0f25..f91e88660da6 100644 --- a/engines/ags/engine/ac/global_slider.cpp +++ b/engines/ags/engine/ac/global_slider.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/global_slider.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/slider.h" -#include "gui/guimain.h" -#include "gui/guislider.h" +#include "ags/shared/ac/global_slider.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/slider.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guislider.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_string.cpp b/engines/ags/engine/ac/global_string.cpp index 974b6cea23d9..d64a4fae9135 100644 --- a/engines/ags/engine/ac/global_string.cpp +++ b/engines/ags/engine/ac/global_string.cpp @@ -20,13 +20,13 @@ * */ -#include -#include "ac/common.h" -#include "ac/global_string.h" -#include "ac/global_translation.h" -#include "ac/runtime_defines.h" -#include "ac/string.h" -#include "util/string_compat.h" +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/global_string.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp index 2f2bf556a0d5..aa78c0632cf7 100644 --- a/engines/ags/engine/ac/global_textbox.cpp +++ b/engines/ags/engine/ac/global_textbox.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/global_textbox.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/string.h" -#include "ac/textbox.h" -#include "gui/guimain.h" -#include "gui/guitextbox.h" +#include "ags/shared/ac/global_textbox.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/textbox.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guitextbox.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_timer.cpp b/engines/ags/engine/ac/global_timer.cpp index 04b325961ecd..d65d2befdf23 100644 --- a/engines/ags/engine/ac/global_timer.cpp +++ b/engines/ags/engine/ac/global_timer.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/global_timer.h" -#include "ac/runtime_defines.h" -#include "ac/common.h" -#include "ac/gamestate.h" +#include "ags/shared/ac/global_timer.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index e27b75dee67c..822ee3a73509 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -20,18 +20,18 @@ * */ -#include -#include "ac/common.h" -#include "ac/display.h" -#include "ac/gamestate.h" -#include "ac/global_translation.h" -#include "ac/string.h" -#include "ac/tree_map.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "util/memory.h" -#include "core/types.h" +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/tree_map.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/util/memory.h" +#include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp index 1629b1cf8f97..a676765874c7 100644 --- a/engines/ags/engine/ac/global_video.cpp +++ b/engines/ags/engine/ac/global_video.cpp @@ -21,17 +21,17 @@ */ #include "ags/lib/allegro.h" -#include "ac/gamesetup.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/global_game.h" -#include "ac/global_video.h" -#include "ac/path_helper.h" -#include "debug/debugger.h" -#include "media/video/video.h" -#include "media/audio/audio_system.h" -#include "platform/base/agsplatformdriver.h" -#include "util/string_compat.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_video.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/media/video/video.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_viewframe.cpp b/engines/ags/engine/ac/global_viewframe.cpp index 8a8f2942cfdf..e57afccfb718 100644 --- a/engines/ags/engine/ac/global_viewframe.cpp +++ b/engines/ags/engine/ac/global_viewframe.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/global_viewframe.h" -#include "ac/common.h" -#include "ac/view.h" -#include "ac/gamesetupstruct.h" -#include "debug/debug_log.h" -#include "media/audio/audio_system.h" +#include "ags/shared/ac/global_viewframe.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_viewport.cpp b/engines/ags/engine/ac/global_viewport.cpp index 456c5822411f..a76a4443fcd1 100644 --- a/engines/ags/engine/ac/global_viewport.cpp +++ b/engines/ags/engine/ac/global_viewport.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/global_viewport.h" -#include "ac/draw.h" -#include "debug/debug_log.h" +#include "ags/shared/ac/global_viewport.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/debug/debug_log.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp index ca23e25a3561..8bf3df756aac 100644 --- a/engines/ags/engine/ac/global_walkablearea.cpp +++ b/engines/ags/engine/ac/global_walkablearea.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/global_walkablearea.h" -#include "ac/common.h" -#include "ac/common_defines.h" -#include "ac/draw.h" -#include "ac/walkablearea.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" +#include "ags/shared/ac/global_walkablearea.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/walkablearea.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_walkbehind.cpp b/engines/ags/engine/ac/global_walkbehind.cpp index d49685c54b22..315c3ac4d955 100644 --- a/engines/ags/engine/ac/global_walkbehind.cpp +++ b/engines/ags/engine/ac/global_walkbehind.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/global_walkbehind.h" -#include "ac/common.h" -#include "ac/common_defines.h" -#include "ac/draw.h" -#include "ac/roomstatus.h" -#include "ac/walkbehind.h" -#include "debug/debug_log.h" +#include "ags/shared/ac/global_walkbehind.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/walkbehind.h" +#include "ags/shared/debug/debug_log.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp index 0d5d481f0fac..fa00a425ff94 100644 --- a/engines/ags/engine/ac/gui.cpp +++ b/engines/ags/engine/ac/gui.cpp @@ -20,40 +20,40 @@ * */ -#include -#include "ac/gui.h" -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_character.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/global_inventoryitem.h" -#include "ac/global_screen.h" -#include "ac/guicontrol.h" -#include "ac/interfacebutton.h" -#include "ac/invwindow.h" -#include "ac/mouse.h" -#include "ac/runtime_defines.h" -#include "ac/system.h" -#include "ac/dynobj/cc_guiobject.h" -#include "ac/dynobj/scriptgui.h" -#include "script/cc_instance.h" -#include "debug/debug_log.h" -#include "device/mousew32.h" -#include "gfx/gfxfilter.h" -#include "gui/guibutton.h" -#include "gui/guimain.h" -#include "script/script.h" -#include "script/script_runtime.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" -#include "ac/dynobj/cc_gui.h" -#include "ac/dynobj/cc_guiobject.h" -#include "script/runtimescriptvalue.h" -#include "util/string_compat.h" +//include +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_inventoryitem.h" +#include "ags/shared/ac/global_screen.h" +#include "ags/shared/ac/guicontrol.h" +#include "ags/shared/ac/interfacebutton.h" +#include "ags/shared/ac/invwindow.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/dynobj/cc_guiobject.h" +#include "ags/shared/ac/dynobj/scriptgui.h" +#include "ags/shared/script/cc_instance.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/ac/dynobj/cc_gui.h" +#include "ags/shared/ac/dynobj/cc_guiobject.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { @@ -685,9 +685,9 @@ void gui_on_mouse_down(const int guin, const int mbut) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // void GUI_Centre(ScriptGUI *sgui) RuntimeScriptValue Sc_GUI_Centre(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/gui.h b/engines/ags/engine/ac/gui.h index e8e179f9f2ae..d871b601a2a5 100644 --- a/engines/ags/engine/ac/gui.h +++ b/engines/ags/engine/ac/gui.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GUI_H #define AGS_ENGINE_AC_GUI_H -#include "ac/dynobj/scriptgui.h" -#include "gui/guimain.h" +#include "ags/engine/ac/dynobj/scriptgui.h" +#include "ags/shared/gui/guimain.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp index 99cde3bd0e62..90907e77485a 100644 --- a/engines/ags/engine/ac/guicontrol.cpp +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -20,20 +20,20 @@ * */ -#include "ac/common.h" -#include "ac/guicontrol.h" -#include "ac/global_gui.h" -#include "debug/debug_log.h" -#include "gui/guibutton.h" -#include "gui/guiinv.h" -#include "gui/guilabel.h" -#include "gui/guilistbox.h" -#include "gui/guimain.h" -#include "gui/guislider.h" -#include "gui/guitextbox.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_gui.h" -#include "ac/dynobj/cc_guiobject.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/guicontrol.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/shared/gui/guilistbox.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guislider.h" +#include "ags/shared/gui/guitextbox.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_gui.h" +#include "ags/shared/ac/dynobj/cc_guiobject.h" namespace AGS3 { @@ -237,9 +237,9 @@ void GUIControl_BringToFront(GUIObject *guio) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // void (GUIObject *guio) RuntimeScriptValue Sc_GUIControl_BringToFront(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/guicontrol.h b/engines/ags/engine/ac/guicontrol.h index 1159917394ec..006c52859bdb 100644 --- a/engines/ags/engine/ac/guicontrol.h +++ b/engines/ags/engine/ac/guicontrol.h @@ -23,14 +23,14 @@ #ifndef AGS_ENGINE_AC_GUICONTROL_H #define AGS_ENGINE_AC_GUICONTROL_H -#include "gui/guiobject.h" -#include "gui/guibutton.h" -#include "gui/guiinv.h" -#include "gui/guilabel.h" -#include "gui/guilistbox.h" -#include "gui/guislider.h" -#include "gui/guitextbox.h" -#include "ac/dynobj/scriptgui.h" +#include "ags/shared/gui/guiobject.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/shared/gui/guilistbox.h" +#include "ags/shared/gui/guislider.h" +#include "ags/shared/gui/guitextbox.h" +#include "ags/engine/ac/dynobj/scriptgui.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/guiinv.cpp b/engines/ags/engine/ac/guiinv.cpp index 8110cc71ce86..18a08c034c7d 100644 --- a/engines/ags/engine/ac/guiinv.cpp +++ b/engines/ags/engine/ac/guiinv.cpp @@ -20,14 +20,14 @@ * */ -#include "gui/guiinv.h" -#include "gui/guimain.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/characterextras.h" -#include "ac/spritecache.h" -#include "gfx/bitmap.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp index f839323f7ca0..ddaee7ce852a 100644 --- a/engines/ags/engine/ac/hotspot.cpp +++ b/engines/ags/engine/ac/hotspot.cpp @@ -20,18 +20,18 @@ * */ -#include "ac/dynobj/cc_hotspot.h" -#include "ac/hotspot.h" -#include "ac/gamestate.h" -#include "ac/global_hotspot.h" -#include "ac/global_translation.h" -#include "ac/properties.h" -#include "ac/room.h" -#include "ac/roomstatus.h" -#include "ac/string.h" -#include "game/roomstruct.h" -#include "gfx/bitmap.h" -#include "script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_hotspot.h" +#include "ags/shared/ac/hotspot.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_hotspot.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/script/runtimescriptvalue.h" namespace AGS3 { @@ -128,10 +128,10 @@ int get_hotspot_at(int xpp, int ypp) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h index a495b0df2fe7..488254309772 100644 --- a/engines/ags/engine/ac/hotspot.h +++ b/engines/ags/engine/ac/hotspot.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_HOTSPOT_H #define AGS_ENGINE_AC_HOTSPOT_H -#include "ac/dynobj/scripthotspot.h" +#include "ags/engine/ac/dynobj/scripthotspot.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/interfacebutton.cpp b/engines/ags/engine/ac/interfacebutton.cpp index 293870287d46..3ec3d848243a 100644 --- a/engines/ags/engine/ac/interfacebutton.cpp +++ b/engines/ags/engine/ac/interfacebutton.cpp @@ -20,7 +20,7 @@ * */ -#include "ac/interfacebutton.h" +#include "ags/shared/ac/interfacebutton.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/interfaceelement.cpp b/engines/ags/engine/ac/interfaceelement.cpp index 5da22509f5c7..ea8f5d483c60 100644 --- a/engines/ags/engine/ac/interfaceelement.cpp +++ b/engines/ags/engine/ac/interfaceelement.cpp @@ -20,8 +20,8 @@ * */ -#include -#include "ac/interfaceelement.h" +//include +#include "ags/shared/ac/interfaceelement.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp index e71a20ad60ec..c04585e3af19 100644 --- a/engines/ags/engine/ac/inventoryitem.cpp +++ b/engines/ags/engine/ac/inventoryitem.cpp @@ -20,18 +20,18 @@ * */ -#include "ac/inventoryitem.h" -#include "ac/characterinfo.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_inventoryitem.h" -#include "ac/global_translation.h" -#include "ac/mouse.h" -#include "ac/properties.h" -#include "ac/runtime_defines.h" -#include "ac/string.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_inventory.h" +#include "ags/shared/ac/inventoryitem.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_inventoryitem.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_inventory.h" namespace AGS3 { @@ -126,10 +126,10 @@ void set_inv_item_cursorpic(int invItemId, int piccy) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/inventoryitem.h b/engines/ags/engine/ac/inventoryitem.h index 991526059df6..58c2d51cef2d 100644 --- a/engines/ags/engine/ac/inventoryitem.h +++ b/engines/ags/engine/ac/inventoryitem.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_INVENTORYITEM_H #define AGS_ENGINE_AC_INVENTORYITEM_H -#include "ac/dynobj/scriptinvitem.h" +#include "ags/engine/ac/dynobj/scriptinvitem.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp index 1c9b8602553f..87b10255e704 100644 --- a/engines/ags/engine/ac/invwindow.cpp +++ b/engines/ags/engine/ac/invwindow.cpp @@ -20,30 +20,30 @@ * */ -#include "ac/invwindow.h" -#include "ac/common.h" -#include "ac/characterextras.h" -#include "ac/characterinfo.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/gamestate.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_character.h" -#include "ac/global_display.h" -#include "ac/global_room.h" -#include "ac/mouse.h" -#include "ac/sys_events.h" -#include "debug/debug_log.h" -#include "gui/guidialog.h" -#include "main/game_run.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/spritecache.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_character.h" -#include "ac/dynobj/cc_inventory.h" -#include "util/math.h" -#include "media/audio/audio_system.h" -#include "ac/timer.h" +#include "ags/shared/ac/invwindow.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_character.h" +#include "ags/shared/ac/dynobj/cc_inventory.h" +#include "ags/shared/util/math.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { @@ -526,9 +526,9 @@ int invscreen() { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // void (GUIInvWindow *guii) RuntimeScriptValue Sc_InvWindow_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/invwindow.h b/engines/ags/engine/ac/invwindow.h index ebb7fc8822ac..6f830a8eb3b6 100644 --- a/engines/ags/engine/ac/invwindow.h +++ b/engines/ags/engine/ac/invwindow.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_AC_INVWINDOW_H #define AGS_ENGINE_AC_INVWINDOW_H -#include "ac/characterinfo.h" -#include "ac/dynobj/scriptinvitem.h" -#include "gui/guiinv.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/engine/ac/dynobj/scriptinvitem.h" +#include "ags/shared/gui/guiinv.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp index e938b14ef6d4..c3a790e9cfca 100644 --- a/engines/ags/engine/ac/keycode.cpp +++ b/engines/ags/engine/ac/keycode.cpp @@ -20,7 +20,7 @@ * */ -#include "ac/keycode.h" +#include "ags/shared/ac/keycode.h" #include "ags/lib/allegro.h" diff --git a/engines/ags/engine/ac/keycode.h b/engines/ags/engine/ac/keycode.h index ddfcf071d6a9..b1086a921491 100644 --- a/engines/ags/engine/ac/keycode.h +++ b/engines/ags/engine/ac/keycode.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_KEYCODE_H #define AGS_ENGINE_AC_KEYCODE_H -#include "core/platform.h" +#include "ags/shared/core/platform.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp index 8935c71abe19..de5c06fa8458 100644 --- a/engines/ags/engine/ac/label.cpp +++ b/engines/ags/engine/ac/label.cpp @@ -20,12 +20,12 @@ * */ -#include -#include "ac/label.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_translation.h" -#include "ac/string.h" +//include +#include "ags/shared/ac/label.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/string.h" namespace AGS3 { @@ -92,10 +92,10 @@ void Label_SetFont(GUILabel *guil, int fontnum) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/label.h b/engines/ags/engine/ac/label.h index 27453a5bcd87..fc43c0d0638d 100644 --- a/engines/ags/engine/ac/label.h +++ b/engines/ags/engine/ac/label.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_LABEL_H #define AGS_ENGINE_AC_LABEL_H -#include "gui/guilabel.h" +#include "ags/shared/gui/guilabel.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index eec074c65f24..4753e933c3a5 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -20,17 +20,17 @@ * */ -#include -#include "ac/listbox.h" -#include "ac/common.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_game.h" -#include "ac/path_helper.h" -#include "ac/string.h" -#include "gui/guimain.h" -#include "debug/debug_log.h" +//include +#include "ags/shared/ac/listbox.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/debug/debug_log.h" namespace AGS3 { @@ -384,10 +384,10 @@ GUIListBox *is_valid_listbox(int guin, int objn) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/listbox.h b/engines/ags/engine/ac/listbox.h index 7642a9dfba53..c2be166f56eb 100644 --- a/engines/ags/engine/ac/listbox.h +++ b/engines/ags/engine/ac/listbox.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_LISTBOX_H #define AGS_ENGINE_AC_LISTBOX_H -#include "gui/guilistbox.h" +#include "ags/shared/gui/guilistbox.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/math.cpp b/engines/ags/engine/ac/math.cpp index de2d521978d9..431e6bddb4f8 100644 --- a/engines/ags/engine/ac/math.cpp +++ b/engines/ags/engine/ac/math.cpp @@ -20,10 +20,10 @@ * */ -#include -#include "ac/math.h" -#include "ac/common.h" // quit -#include "util/math.h" +//include +#include "ags/shared/ac/math.h" +#include "ags/shared/ac/common.h" // quit +#include "ags/shared/util/math.h" namespace AGS3 { @@ -148,9 +148,9 @@ int __Rand(int upto) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // float (float value) RuntimeScriptValue Sc_Math_ArcCos(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/math.h b/engines/ags/engine/ac/math.h index 07e3ae45b108..8ec93ce28a7f 100644 --- a/engines/ags/engine/ac/math.h +++ b/engines/ags/engine/ac/math.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_MATH_H #define AGS_ENGINE_AC_MATH_H -#include "core/types.h" +#include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp index 8fe271403991..fbfa84fa8919 100644 --- a/engines/ags/engine/ac/mouse.cpp +++ b/engines/ags/engine/ac/mouse.cpp @@ -20,27 +20,27 @@ * */ -#include "ac/mouse.h" -#include "ac/common.h" -#include "ac/characterinfo.h" -#include "ac/draw.h" -#include "ac/dynobj/scriptmouse.h" -#include "ac/dynobj/scriptsystem.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_mouse.h" -#include "ac/global_plugin.h" -#include "ac/global_screen.h" -#include "ac/system.h" -#include "ac/viewframe.h" -#include "debug/debug_log.h" -#include "gui/guibutton.h" -#include "gui/guimain.h" -#include "device/mousew32.h" -#include "ac/spritecache.h" -#include "gfx/graphicsdriver.h" -#include "gfx/gfxfilter.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/dynobj/scriptmouse.h" +#include "ags/shared/ac/dynobj/scriptsystem.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_mouse.h" +#include "ags/shared/ac/global_plugin.h" +#include "ags/shared/ac/global_screen.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/viewframe.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/gfxfilter.h" namespace AGS3 { @@ -455,10 +455,10 @@ int find_previous_enabled_cursor(int startwith) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/global_game.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/global_game.h" // void (int curs, int newslot) RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/mouse.h b/engines/ags/engine/ac/mouse.h index 455df017f443..95e455fdf6a5 100644 --- a/engines/ags/engine/ac/mouse.h +++ b/engines/ags/engine/ac/mouse.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_MOUSE_H #define AGS_ENGINE_AC_MOUSE_H -#include "ac/dynobj/scriptmouse.h" +#include "ags/engine/ac/dynobj/scriptmouse.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/movelist.cpp b/engines/ags/engine/ac/movelist.cpp index 0b46fbf8fd76..5b6154fc1551 100644 --- a/engines/ags/engine/ac/movelist.cpp +++ b/engines/ags/engine/ac/movelist.cpp @@ -20,9 +20,9 @@ * */ -#include "ac/movelist.h" -#include "ac/common.h" -#include "util/stream.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h index 06aa462fc34b..b950ffe44b1f 100644 --- a/engines/ags/engine/ac/movelist.h +++ b/engines/ags/engine/ac/movelist.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_MOVE_H #define AGS_ENGINE_AC_MOVE_H -#include "util/wgt2allg.h" // fixed type -#include "game/savegame.h" +#include "ags/shared/util/wgt2allg.h" // fixed type +#include "ags/engine/game/savegame.h" namespace AGS3 { @@ -49,9 +49,9 @@ struct MoveList { char doneflag; char direct; // MoveCharDirect was used or not - void ReadFromFile_Legacy(Common::Stream *in); - AGS::Engine::HSaveError ReadFromFile(Common::Stream *in, int32_t cmp_ver); - void WriteToFile(Common::Stream *out); + void ReadFromFile_Legacy(Shared::Stream *in); + AGS::Engine::HSaveError ReadFromFile(Shared::Stream *in, int32_t cmp_ver); + void WriteToFile(Shared::Stream *out); }; } // namespace AGS3 diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp index 3fb358320a3e..bc982e325f3c 100644 --- a/engines/ags/engine/ac/object.cpp +++ b/engines/ags/engine/ac/object.cpp @@ -20,31 +20,31 @@ * */ -#include "ac/object.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/draw.h" -#include "ac/character.h" -#include "ac/global_object.h" -#include "ac/global_translation.h" -#include "ac/objectcache.h" -#include "ac/properties.h" -#include "ac/room.h" -#include "ac/roomstatus.h" -#include "ac/runtime_defines.h" -#include "ac/string.h" -#include "ac/system.h" -#include "ac/view.h" -#include "ac/walkablearea.h" -#include "debug/debug_log.h" -#include "main/game_run.h" -#include "ac/route_finder.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" -#include "gfx/gfx_def.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_object.h" -#include "ac/movelist.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/global_object.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/walkablearea.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/ac/route_finder.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfx_def.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_object.h" +#include "ags/shared/ac/movelist.h" namespace AGS3 { @@ -558,10 +558,10 @@ int check_click_on_object(int roomx, int roomy, int mood) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/object.h b/engines/ags/engine/ac/object.h index 39b3126ae99c..a376b8f0ba2c 100644 --- a/engines/ags/engine/ac/object.h +++ b/engines/ags/engine/ac/object.h @@ -31,8 +31,8 @@ #ifndef AGS_ENGINE_AC_OBJECT_H #define AGS_ENGINE_AC_OBJECT_H -#include "ac/common_defines.h" -#include "ac/dynobj/scriptobject.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/engine/ac/dynobj/scriptobject.h" namespace AGS3 { @@ -98,7 +98,7 @@ const char *Object_GetTextProperty(ScriptObject *objj, const char *property); void move_object(int objj, int tox, int toy, int spee, int ignwal); void get_object_blocking_rect(int objid, int *x1, int *y1, int *width, int *y2); int isposinbox(int mmx, int mmy, int lf, int tp, int rt, int bt); -int is_pos_in_sprite(int xx, int yy, int arx, int ary, Common::Bitmap *sprit, int spww, int sphh, int flipped = 0); +int is_pos_in_sprite(int xx, int yy, int arx, int ary, Shared::Bitmap *sprit, int spww, int sphh, int flipped = 0); // X and Y co-ordinates must be in native format // X and Y are ROOM coordinates int check_click_on_object(int roomx, int roomy, int mood); diff --git a/engines/ags/engine/ac/objectcache.h b/engines/ags/engine/ac/objectcache.h index 6621698ed27e..7f2d994e156d 100644 --- a/engines/ags/engine/ac/objectcache.h +++ b/engines/ags/engine/ac/objectcache.h @@ -27,7 +27,7 @@ namespace AGS3 { // stores cached object info struct ObjectCache { - Common::Bitmap *image; + Shared::Bitmap *image; int sppic; short tintredwas, tintgrnwas, tintbluwas, tintamntwas, tintlightwas; short lightlevwas, mirroredWas, zoomWas; diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp index f9b40cbec46f..5edd4a255433 100644 --- a/engines/ags/engine/ac/overlay.cpp +++ b/engines/ags/engine/ac/overlay.cpp @@ -20,23 +20,23 @@ * */ -#include "ac/overlay.h" -#include "ac/common.h" -#include "ac/view.h" -#include "ac/character.h" -#include "ac/characterextras.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_overlay.h" -#include "ac/global_translation.h" -#include "ac/runtime_defines.h" -#include "ac/screenoverlay.h" -#include "ac/string.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" -#include "script/runtimescriptvalue.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_overlay.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/script/runtimescriptvalue.h" namespace AGS3 { @@ -197,7 +197,7 @@ size_t add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChann return add_screen_overlay(x, y, type, piccy, 0, 0, alphaChannel); } -size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) { +size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) { if (type == OVER_COMPLETE) is_complete_overlay++; if (type == OVER_TEXTMSG) is_text_overlay++; if (type == OVER_CUSTOM) { @@ -287,9 +287,9 @@ void recreate_overlay_ddbs() { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // ScriptOverlay* (int x, int y, int slot, int transparent) RuntimeScriptValue Sc_Overlay_CreateGraphical(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h index 683f9a489e27..8300596c6f49 100644 --- a/engines/ags/engine/ac/overlay.h +++ b/engines/ags/engine/ac/overlay.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_AC_OVERLAY_H #define AGS_ENGINE_AC_OVERLAY_H -#include -#include "ac/screenoverlay.h" -#include "ac/dynobj/scriptoverlay.h" +#include "ags/std/vector.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/dynobj/scriptoverlay.h" namespace AGS3 { @@ -51,8 +51,8 @@ int find_overlay_of_type(int type); void remove_screen_overlay(int type); // Calculates overlay position in screen coordinates void get_overlay_position(const ScreenOverlay &over, int *x, int *y); -size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, bool alphaChannel = false); -size_t add_screen_overlay(int x, int y, int type, Common::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false); +size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, bool alphaChannel = false); +size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false); void remove_screen_overlay_index(size_t over_idx); void recreate_overlay_ddbs(); diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp index 66fc367497e3..bddd826e706d 100644 --- a/engines/ags/engine/ac/parser.cpp +++ b/engines/ags/engine/ac/parser.cpp @@ -20,17 +20,17 @@ * */ -#include //isalnum() -#include -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/parser.h" -#include "ac/string.h" -#include "ac/wordsdictionary.h" -#include "debug/debug_log.h" -#include "util/string.h" -#include "util/string_compat.h" +//include //isalnum() +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/parser.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/wordsdictionary.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { @@ -301,10 +301,10 @@ int parse_sentence(const char *src_text, int *numwords, short *wordarray, short // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h index 8630e8235192..46349386ac9f 100644 --- a/engines/ags/engine/ac/path_helper.h +++ b/engines/ags/engine/ac/path_helper.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_AC_PATHHELPER_H #define AGS_ENGINE_AC_PATHHELPER_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp index 84082a6e8e07..9e1f22154655 100644 --- a/engines/ags/engine/ac/properties.cpp +++ b/engines/ags/engine/ac/properties.cpp @@ -20,13 +20,13 @@ * */ -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/properties.h" -#include "ac/string.h" -#include "ac/dynobj/scriptstring.h" -#include "script/runtimescriptvalue.h" -#include "util/string_utils.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h index aa877441da67..ac40ab5b2aca 100644 --- a/engines/ags/engine/ac/properties.h +++ b/engines/ags/engine/ac/properties.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_PROPERTIES_H #define AGS_ENGINE_AC_PROPERTIES_H -#include "game/customproperties.h" +#include "ags/engine/game/customproperties.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp index 9e12a5b705ee..0716dd7d5ce6 100644 --- a/engines/ags/engine/ac/region.cpp +++ b/engines/ags/engine/ac/region.cpp @@ -20,17 +20,17 @@ * */ -#include "ac/region.h" -#include "ac/common_defines.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_region.h" -#include "ac/room.h" -#include "ac/roomstatus.h" -#include "ac/dynobj/cc_region.h" -#include "ac/dynobj/scriptdrawingsurface.h" -#include "game/roomstruct.h" -#include "script/runtimescriptvalue.h" +#include "ags/shared/ac/region.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_region.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/dynobj/cc_region.h" +#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/script/runtimescriptvalue.h" namespace AGS3 { @@ -136,9 +136,9 @@ void generate_light_table() { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // ScriptRegion *(int xx, int yy) RuntimeScriptValue Sc_GetRegionAtRoom(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/region.h b/engines/ags/engine/ac/region.h index a5db946f130d..58b3fa4589d7 100644 --- a/engines/ags/engine/ac/region.h +++ b/engines/ags/engine/ac/region.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_REGION_H #define AGS_ENGINE_AC_REGION_H -#include "ac/dynobj/scriptregion.h" +#include "ags/engine/ac/dynobj/scriptregion.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp index 0c15a3f70276..4409f1b855e4 100644 --- a/engines/ags/engine/ac/richgamemedia.cpp +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/richgamemedia.h" -#include "util/stream.h" +#include "ags/shared/ac/richgamemedia.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index 420903aacb55..f28cd454aef3 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -54,8 +54,8 @@ typedef struct _RICH_GAME_MEDIA_HEADER { unsigned short szLevelName[RM_MAXLENGTH]; unsigned short szComments[RM_MAXLENGTH]; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); } RICH_GAME_MEDIA_HEADER; #pragma pack(pop) diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index 8b7b4276d0d2..12ce1ec851f5 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -20,62 +20,62 @@ * */ -#include // for toupper - -#include "core/platform.h" -#include "util/string_utils.h" //strlwr() -#include "ac/common.h" -#include "ac/charactercache.h" -#include "ac/characterextras.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/global_character.h" -#include "ac/global_game.h" -#include "ac/global_object.h" -#include "ac/global_translation.h" -#include "ac/movelist.h" -#include "ac/mouse.h" -#include "ac/objectcache.h" -#include "ac/overlay.h" -#include "ac/properties.h" -#include "ac/region.h" -#include "ac/sys_events.h" -#include "ac/room.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "ac/screen.h" -#include "ac/string.h" -#include "ac/system.h" -#include "ac/walkablearea.h" -#include "ac/walkbehind.h" -#include "ac/dynobj/scriptobject.h" -#include "ac/dynobj/scripthotspot.h" -#include "gui/guidefines.h" -#include "script/cc_instance.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "debug/out.h" -#include "game/room_version.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "script/cc_error.h" -#include "script/script.h" -#include "script/script_runtime.h" -#include "ac/spritecache.h" -#include "util/stream.h" -#include "gfx/graphicsdriver.h" -#include "core/assetmanager.h" -#include "ac/dynobj/all_dynamicclasses.h" -#include "gfx/bitmap.h" -#include "gfx/gfxfilter.h" -#include "util/math.h" -#include "media/audio/audio_system.h" +//include // for toupper + +#include "ags/shared/core/platform.h" +#include "ags/shared/util/string_utils.h" //strlwr() +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/charactercache.h" +#include "ags/shared/ac/characterextras.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_object.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/properties.h" +#include "ags/shared/ac/region.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/screen.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/walkablearea.h" +#include "ags/shared/ac/walkbehind.h" +#include "ags/shared/ac/dynobj/scriptobject.h" +#include "ags/shared/ac/dynobj/scripthotspot.h" +#include "ags/shared/gui/guidefines.h" +#include "ags/shared/script/cc_instance.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/game/room_version.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/ac/dynobj/all_dynamicclasses.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/util/math.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { @@ -1102,10 +1102,10 @@ void convert_move_path_to_room_resolution(MoveList *ml) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h index 05f36efe87b6..e90fda831c40 100644 --- a/engines/ags/engine/ac/room.h +++ b/engines/ags/engine/ac/room.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_AC_ROOM_H #define AGS_ENGINE_AC_ROOM_H -#include "ac/dynobj/scriptdrawingsurface.h" -#include "ac/characterinfo.h" -#include "script/runtimescriptvalue.h" -#include "game/roomstruct.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/shared/game/roomstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp index 92947e3db713..06ae948f4cb2 100644 --- a/engines/ags/engine/ac/roomobject.cpp +++ b/engines/ags/engine/ac/roomobject.cpp @@ -20,15 +20,15 @@ * */ -#include "ac/roomobject.h" -#include "ac/common.h" -#include "ac/common_defines.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/runtime_defines.h" -#include "ac/viewframe.h" -#include "main/update.h" -#include "util/stream.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/viewframe.h" +#include "ags/shared/main/update.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/roomobject.h b/engines/ags/engine/ac/roomobject.h index b78f9a80d5b5..d14c5a33fd37 100644 --- a/engines/ags/engine/ac/roomobject.h +++ b/engines/ags/engine/ac/roomobject.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_ROOMOBJECT_H #define AGS_ENGINE_AC_ROOMOBJECT_H -#include "ac/common_defines.h" +#include "ags/shared/ac/common_defines.h" namespace AGS3 { @@ -71,8 +71,8 @@ struct RoomObject { void update_cycle_view_forwards(); void update_cycle_view_backwards(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out) const; + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out) const; }; } // namespace AGS3 diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp index 3687e476b5d0..d523a8d006c0 100644 --- a/engines/ags/engine/ac/roomstatus.cpp +++ b/engines/ags/engine/ac/roomstatus.cpp @@ -20,14 +20,14 @@ * */ -#include // memset -#include // free -#include "ac/common.h" -#include "ac/game_version.h" -#include "ac/roomstatus.h" -#include "game/customproperties.h" -#include "game/savegame_components.h" -#include "util/alignedstream.h" +//include // memset +//include // free +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/game/customproperties.h" +#include "ags/shared/game/savegame_components.h" +#include "ags/shared/util/alignedstream.h" namespace AGS3 { @@ -102,7 +102,7 @@ void RoomStatus::ReadFromFile_v321(Stream *in) { } } -void RoomStatus::ReadRoomObjects_Aligned(Common::Stream *in) { +void RoomStatus::ReadRoomObjects_Aligned(Shared::Stream *in) { AlignedStream align_s(in, Common::kAligned_Read); for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) { obj[i].ReadFromFile(&align_s); diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h index f23e71dfd8aa..89d982539a71 100644 --- a/engines/ags/engine/ac/roomstatus.h +++ b/engines/ags/engine/ac/roomstatus.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_AC_ROOMSTATUS_H #define AGS_ENGINE_AC_ROOMSTATUS_H -#include "ac/roomobject.h" -#include "game/roomstruct.h" -#include "game/interactions.h" -#include "util/string_types.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/game/interactions.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { @@ -54,9 +54,9 @@ struct RoomStatus { Interaction intrRegion[MAX_ROOM_REGIONS]; Interaction intrRoom; - Common::StringIMap roomProps; - Common::StringIMap hsProps[MAX_ROOM_HOTSPOTS]; - Common::StringIMap objProps[MAX_ROOM_OBJECTS]; + Shared::StringIMap roomProps; + Shared::StringIMap hsProps[MAX_ROOM_HOTSPOTS]; + Shared::StringIMap objProps[MAX_ROOM_OBJECTS]; // [IKM] 2012-06-22: not used anywhere #ifdef UNUSED_CODE EventBlock hscond[MAX_ROOM_HOTSPOTS]; @@ -74,10 +74,10 @@ struct RoomStatus { void FreeScriptData(); void FreeProperties(); - void ReadFromFile_v321(Common::Stream *in); - void ReadRoomObjects_Aligned(Common::Stream *in); - void ReadFromSavegame(Common::Stream *in); - void WriteToSavegame(Common::Stream *out) const; + void ReadFromFile_v321(Shared::Stream *in); + void ReadRoomObjects_Aligned(Shared::Stream *in); + void ReadFromSavegame(Shared::Stream *in); + void WriteToSavegame(Shared::Stream *out) const; }; // Replaces all accesses to the roomstats array diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index 44fa3464fd38..2daaff186f36 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/route_finder.h" +#include "ags/shared/ac/route_finder.h" -#include "ac/route_finder_impl.h" -#include "ac/route_finder_impl_legacy.h" +#include "ags/shared/ac/route_finder_impl.h" +#include "ags/shared/ac/route_finder_impl_legacy.h" -#include "debug/out.h" +#include "ags/shared/debug/out.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h index 575903484323..69f0023ed451 100644 --- a/engines/ags/engine/ac/route_finder.h +++ b/engines/ags/engine/ac/route_finder.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_ROUTEFND_H #define AGS_ENGINE_AC_ROUTEFND_H -#include "ac/game_version.h" +#include "ags/shared/ac/game_version.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp index a9d93a6bb55a..b62bd5cfb8e7 100644 --- a/engines/ags/engine/ac/route_finder_impl.cpp +++ b/engines/ags/engine/ac/route_finder_impl.cpp @@ -26,18 +26,18 @@ // //============================================================================= -#include "ac/route_finder_impl.h" +#include "ags/shared/ac/route_finder_impl.h" -#include -#include +//include +//include -#include "ac/common.h" // quit() -#include "ac/movelist.h" // MoveList -#include "ac/common_defines.h" -#include "gfx/bitmap.h" -#include "debug/out.h" +#include "ags/shared/ac/common.h" // quit() +#include "ags/shared/ac/movelist.h" // MoveList +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/debug/out.h" -#include "route_finder_jps.inl" +#include "ags/shared/route_finder_jps.inl" namespace AGS3 { diff --git a/engines/ags/engine/ac/route_finder_impl.h b/engines/ags/engine/ac/route_finder_impl.h index cfd44228e032..39b78e56ce38 100644 --- a/engines/ags/engine/ac/route_finder_impl.h +++ b/engines/ags/engine/ac/route_finder_impl.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_ROUTE_FINDER_IMPL #define AGS_ENGINE_AC_ROUTE_FINDER_IMPL -#include "ac/game_version.h" +#include "ags/shared/ac/game_version.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp index be4c99a9d17b..88c30f5fd803 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp +++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp @@ -27,17 +27,17 @@ // //============================================================================= -#include "ac/route_finder_impl_legacy.h" +#include "ags/shared/ac/route_finder_impl_legacy.h" -#include -#include +//include +//include -#include "ac/common.h" // quit() -#include "ac/common_defines.h" -#include "game/roomstruct.h" -#include "ac/movelist.h" // MoveList -#include "gfx/bitmap.h" -#include "debug/out.h" +#include "ags/shared/ac/common.h" // quit() +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/ac/movelist.h" // MoveList +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/debug/out.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/route_finder_jps.inl b/engines/ags/engine/ac/route_finder_jps.inl index e78db1b5762e..5172e59538e9 100644 --- a/engines/ags/engine/ac/route_finder_jps.inl +++ b/engines/ags/engine/ac/route_finder_jps.inl @@ -17,13 +17,13 @@ // //============================================================================= -#include -#include -#include -#include -#include -#include -#include +//include +#include "ags/std/vector.h" +//include +//include +//include +//include +//include // TODO: this could be cleaned up/simplified ... diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h index 7e2e9d544bb5..5de5e3454297 100644 --- a/engines/ags/engine/ac/runtime_defines.h +++ b/engines/ags/engine/ac/runtime_defines.h @@ -159,6 +159,6 @@ const int LegacyRoomVolumeFactor = 30; } // namespace AGS3 -#include "ac/common_defines.h" +#include "ags/shared/ac/common_defines.h" #endif diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index ccdba1374506..15ddac6f35fa 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -20,21 +20,21 @@ * */ -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_game.h" -#include "ac/global_screen.h" -#include "ac/screen.h" -#include "ac/dynobj/scriptviewport.h" -#include "ac/dynobj/scriptuserobject.h" -#include "script/script_runtime.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_screen.h" +#include "ags/shared/ac/screen.h" +#include "ags/shared/ac/dynobj/scriptviewport.h" +#include "ags/shared/ac/dynobj/scriptuserobject.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/screenoverlay.cpp b/engines/ags/engine/ac/screenoverlay.cpp index ed1a886f5218..fadd6e6c2e07 100644 --- a/engines/ags/engine/ac/screenoverlay.cpp +++ b/engines/ags/engine/ac/screenoverlay.cpp @@ -20,8 +20,8 @@ * */ -#include "screenoverlay.h" -#include "util/stream.h" +#include "ags/shared/screenoverlay.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/screenoverlay.h b/engines/ags/engine/ac/screenoverlay.h index 64a04906bfe0..97787c34ba6b 100644 --- a/engines/ags/engine/ac/screenoverlay.h +++ b/engines/ags/engine/ac/screenoverlay.h @@ -23,7 +23,8 @@ #ifndef AGS_ENGINE_AC_SCREENOVERLAY_H #define AGS_ENGINE_AC_SCREENOVERLAY_H -#include +//include +#include "ags/shared/core/types.h" namespace AGS3 { @@ -46,7 +47,7 @@ using namespace AGS; // FIXME later struct ScreenOverlay { Engine::IDriverDependantBitmap *bmp = nullptr; - Common::Bitmap *pic = nullptr; + Shared::Bitmap *pic = nullptr; int type = 0, x = 0, y = 0, timeout = 0; int bgSpeechForChar = 0; int associatedOverlayHandle = 0; @@ -55,8 +56,8 @@ struct ScreenOverlay { bool hasSerializedBitmap = false; int _offsetX = 0, _offsetY = 0; - void ReadFromFile(Common::Stream *in, int32_t cmp_ver); - void WriteToFile(Common::Stream *out) const; + void ReadFromFile(Shared::Stream *in, int32_t cmp_ver); + void WriteToFile(Shared::Stream *out) const; }; } // namespace AGS3 diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index 5b33fdd3a350..148832bda5b4 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -26,16 +26,16 @@ // //============================================================================= -#include "ac/common.h" // quit -#include "ac/string.h" -#include "ac/dynobj/cc_dynamicarray.h" -#include "ac/dynobj/cc_dynamicobject.h" -#include "ac/dynobj/scriptdict.h" -#include "ac/dynobj/scriptset.h" -#include "ac/dynobj/scriptstring.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "util/bbop.h" +#include "ags/shared/ac/common.h" // quit +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/dynobj/cc_dynamicarray.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" +#include "ags/shared/ac/dynobj/scriptdict.h" +#include "ags/shared/ac/dynobj/scriptset.h" +#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/util/bbop.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/slider.cpp b/engines/ags/engine/ac/slider.cpp index 66273367ba7c..89589b80e3c8 100644 --- a/engines/ags/engine/ac/slider.cpp +++ b/engines/ags/engine/ac/slider.cpp @@ -20,8 +20,8 @@ * */ -#include "ac/slider.h" -#include "ac/common.h" +#include "ags/shared/ac/slider.h" +#include "ags/shared/ac/common.h" namespace AGS3 { @@ -118,9 +118,9 @@ void Slider_SetHandleOffset(GUISlider *guisl, int newOffset) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // int (GUISlider *guisl) RuntimeScriptValue Sc_Slider_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/slider.h b/engines/ags/engine/ac/slider.h index d5d8af96d49e..3c94e485e2ac 100644 --- a/engines/ags/engine/ac/slider.h +++ b/engines/ags/engine/ac/slider.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_SLIDER_H #define AGS_ENGINE_AC_SLIDER_H -#include "gui/guislider.h" +#include "ags/shared/gui/guislider.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp index e91694c826a0..08b2584ebc3a 100644 --- a/engines/ags/engine/ac/speech.cpp +++ b/engines/ags/engine/ac/speech.cpp @@ -20,10 +20,10 @@ * */ -#include "ac/common.h" -#include "ac/runtime_defines.h" -#include "ac/speech.h" -#include "debug/debug_log.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/speech.h" +#include "ags/shared/debug/debug_log.h" namespace AGS3 { @@ -78,13 +78,13 @@ SkipSpeechStyle internal_skip_speech_to_user(int internal_val) { // //============================================================================= -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/global_display.h" -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" extern GameSetupStruct game; extern GameState play; diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp index 25457a4963cf..4220305ce9e3 100644 --- a/engines/ags/engine/ac/sprite.cpp +++ b/engines/ags/engine/ac/sprite.cpp @@ -20,17 +20,17 @@ * */ -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/gamesetupstruct.h" -#include "ac/sprite.h" -#include "ac/system.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "ac/spritecache.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/sprite.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/sprite.h b/engines/ags/engine/ac/sprite.h index 09f841e00517..8995e76fecce 100644 --- a/engines/ags/engine/ac/sprite.h +++ b/engines/ags/engine/ac/sprite.h @@ -28,9 +28,9 @@ namespace AGS3 { void get_new_size_for_sprite(int ee, int ww, int hh, int &newwid, int &newhit); // set any alpha-transparent pixels in the image to the appropriate // RGB mask value so that the ->Blit calls work correctly -void set_rgb_mask_using_alpha_channel(Common::Bitmap *image); +void set_rgb_mask_using_alpha_channel(Shared::Bitmap *image); // from is a 32-bit RGBA image, to is a 15/16/24-bit destination image -Common::Bitmap *remove_alpha_channel(Common::Bitmap *from); +Shared::Bitmap *remove_alpha_channel(Shared::Bitmap *from); void pre_save_sprite(int ee); void initialize_sprite(int ee); diff --git a/engines/ags/engine/ac/spritecache_engine.cpp b/engines/ags/engine/ac/spritecache_engine.cpp index 9f5ae3388e4e..e31443c64d05 100644 --- a/engines/ags/engine/ac/spritecache_engine.cpp +++ b/engines/ags/engine/ac/spritecache_engine.cpp @@ -33,9 +33,9 @@ #pragma warning (disable: 4996 4312) // disable deprecation warnings #endif -#include "ac/gamestructdefines.h" -#include "ac/spritecache.h" -#include "util/compress.h" +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/util/compress.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/spritelistentry.h b/engines/ags/engine/ac/spritelistentry.h index cbf0a049be15..6db4ca3c3bb4 100644 --- a/engines/ags/engine/ac/spritelistentry.h +++ b/engines/ags/engine/ac/spritelistentry.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_SPRITELISTENTRY_H #define AGS_ENGINE_AC_SPRITELISTENTRY_H -#include "gfx/ddb.h" +#include "ags/engine/gfx/ddb.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp index 54f975ee7608..db55c0bcb35f 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.cpp +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -20,10 +20,10 @@ * */ -#include -#include "ac/statobj/agsstaticobject.h" -#include "ac/game.h" -#include "ac/gamestate.h" +//include +#include "ags/shared/ac/statobj/agsstaticobject.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.h b/engines/ags/engine/ac/statobj/agsstaticobject.h index adaddac4ab1a..6b6a0224e60b 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.h +++ b/engines/ags/engine/ac/statobj/agsstaticobject.h @@ -23,7 +23,7 @@ #ifndef _AGS_ENGINE_AC_STATICOBJ_AGSSTATICOBJECT_H #define _AGS_ENGINE_AC_STATICOBJ_AGSSTATICOBJECT_H -#include "ac/statobj/staticobject.h" +#include "ags/engine/ac/statobj/staticobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp index a55758eac62b..73fd3b27f837 100644 --- a/engines/ags/engine/ac/statobj/staticarray.cpp +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -20,9 +20,9 @@ * */ -#include -#include "ac/statobj/staticarray.h" -#include "ac/dynobj/cc_dynamicobject.h" +//include +#include "ags/shared/ac/statobj/staticarray.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h index 1941cc603ba1..3940708f1083 100644 --- a/engines/ags/engine/ac/statobj/staticarray.h +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -23,7 +23,7 @@ #ifndef _AGS_ENGINE_AC_STATICOBJ_STATICARRAY_H #define _AGS_ENGINE_AC_STATICOBJ_STATICARRAY_H -#include "ac/statobj/staticobject.h" +#include "ags/shared/ac/statobj/staticobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/statobj/staticobject.h b/engines/ags/engine/ac/statobj/staticobject.h index 5653222d774b..a38e521c0085 100644 --- a/engines/ags/engine/ac/statobj/staticobject.h +++ b/engines/ags/engine/ac/statobj/staticobject.h @@ -31,7 +31,7 @@ #ifndef AGS_ENGINE_AC_STATICOBJ_STATICOBJECT_H #define AGS_ENGINE_AC_STATICOBJ_STATICOBJECT_H -#include "core/types.h" +#include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index 3380f56c7d44..60a963a50ad2 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -20,19 +20,19 @@ * */ -#include -#include "ac/string.h" -#include "ac/common.h" -#include "ac/display.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_translation.h" -#include "ac/runtime_defines.h" -#include "ac/dynobj/scriptstring.h" -#include "font/fonts.h" -#include "debug/debug_log.h" -#include "script/runtimescriptvalue.h" -#include "util/string_compat.h" +//include +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { @@ -298,10 +298,10 @@ void my_strncpy(char *dest, const char *src, int len) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/math.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/math.h" // int (const char *thisString) RuntimeScriptValue Sc_String_IsNullOrEmpty(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h index e27bd213a4a8..1d606e9a2df7 100644 --- a/engines/ags/engine/ac/string.h +++ b/engines/ags/engine/ac/string.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_STRING_H #define AGS_ENGINE_AC_STRING_H -#include -#include "ac/dynobj/cc_dynamicobject.h" +//include +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index fc20cdbd9811..467e80a13d4b 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -20,16 +20,16 @@ * */ -#include "core/platform.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/keycode.h" -#include "ac/mouse.h" -#include "ac/sys_events.h" -#include "device/mousew32.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/timer.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/keycode.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index 33be22fd38a7..873b11ee987d 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -20,26 +20,26 @@ * */ -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/mouse.h" -#include "ac/string.h" -#include "ac/system.h" -#include "ac/dynobj/scriptsystem.h" -#include "debug/debug_log.h" -#include "debug/out.h" -#include "main/engine.h" -#include "main/main.h" -#include "gfx/graphicsdriver.h" -#include "ac/dynobj/cc_audiochannel.h" -#include "main/graphics_mode.h" -#include "ac/global_debug.h" -#include "ac/global_translation.h" -#include "media/audio/audio_system.h" -#include "util/string_compat.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/dynobj/scriptsystem.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/main/main.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/ac/dynobj/cc_audiochannel.h" +#include "ags/shared/main/graphics_mode.h" +#include "ags/shared/ac/global_debug.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { @@ -227,10 +227,10 @@ void System_SetRenderAtScreenResolution(int enable) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/system.h b/engines/ags/engine/ac/system.h index 280ec92ec733..0b8708d1a21a 100644 --- a/engines/ags/engine/ac/system.h +++ b/engines/ags/engine/ac/system.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_SYSTEMAUDIO_H #define AGS_ENGINE_AC_SYSTEMAUDIO_H -#include "ac/dynobj/scriptaudiochannel.h" +#include "ags/engine/ac/dynobj/scriptaudiochannel.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp index 64f68cc217b0..f4dfa5809b0e 100644 --- a/engines/ags/engine/ac/textbox.cpp +++ b/engines/ags/engine/ac/textbox.cpp @@ -20,11 +20,11 @@ * */ -#include -#include "ac/textbox.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/string.h" +//include +#include "ags/shared/ac/textbox.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/string.h" namespace AGS3 { @@ -90,10 +90,10 @@ void TextBox_SetShowBorder(GUITextBox *guit, bool on) { // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" -#include "ac/dynobj/scriptstring.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" extern ScriptString myScriptStringImpl; diff --git a/engines/ags/engine/ac/textbox.h b/engines/ags/engine/ac/textbox.h index 45271c0d6726..c1bb80801c25 100644 --- a/engines/ags/engine/ac/textbox.h +++ b/engines/ags/engine/ac/textbox.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_TEXTBOX_H #define AGS_ENGINE_AC_TEXTBOX_H -#include "gui/guitextbox.h" +#include "ags/shared/gui/guitextbox.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index 2e2f9b472b7e..08f475228ff6 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -20,16 +20,16 @@ * */ -#include "ac/timer.h" +#include "ags/shared/ac/timer.h" -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_DEBUG && defined (__GNUC__) -#include -#include -#include +//include +//include +//include #endif -#include -#include "platform/base/agsplatformdriver.h" +//include +#include "ags/shared/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/timer.h b/engines/ags/engine/ac/timer.h index fa0ecb88013c..b737923aee74 100644 --- a/engines/ags/engine/ac/timer.h +++ b/engines/ags/engine/ac/timer.h @@ -23,14 +23,15 @@ #ifndef AGS_ENGINE_AC_TIMER_H #define AGS_ENGINE_AC_TIMER_H -#include -#include +#include "ags/std/type_traits.h" +#include "ags/std/chrono.h" +#include "ags/std/xtr1common.h" namespace AGS3 { // use high resolution clock only if we know it is monotonic/steady. // refer to https://stackoverflow.com/a/38253266/84262 -using AGS_Clock = std::conditional < +using AGS_Clock = std::conditional< std::chrono::high_resolution_clock::is_steady, std::chrono::high_resolution_clock, std::chrono::steady_clock >::type; diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp index 4ca6ac1577ac..3c2892b5830d 100644 --- a/engines/ags/engine/ac/translation.cpp +++ b/engines/ags/engine/ac/translation.cpp @@ -20,21 +20,21 @@ * */ -#include -#include "ac/asset_helper.h" -#include "ac/common.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_game.h" -#include "ac/runtime_defines.h" -#include "ac/translation.h" -#include "ac/tree_map.h" -#include "ac/wordsdictionary.h" -#include "debug/out.h" -#include "util/misc.h" -#include "util/stream.h" -#include "core/assetmanager.h" +//include +#include "ags/shared/ac/asset_helper.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/translation.h" +#include "ags/shared/ac/tree_map.h" +#include "ags/shared/ac/wordsdictionary.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/util/misc.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/core/assetmanager.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/translation.h b/engines/ags/engine/ac/translation.h index 30e638befe6d..1dbc27c3a2af 100644 --- a/engines/ags/engine/ac/translation.h +++ b/engines/ags/engine/ac/translation.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_TRANSLATION_H #define AGS_ENGINE_AC_TRANSLATION_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/tree_map.cpp b/engines/ags/engine/ac/tree_map.cpp index 0f8680d14a0d..d81be33d3b21 100644 --- a/engines/ags/engine/ac/tree_map.cpp +++ b/engines/ags/engine/ac/tree_map.cpp @@ -20,10 +20,10 @@ * */ -#include -#include -#include "ac/common.h" -#include "ac/tree_map.h" +//include +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/tree_map.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp index 6f749c52c200..41ab83b02753 100644 --- a/engines/ags/engine/ac/viewframe.cpp +++ b/engines/ags/engine/ac/viewframe.cpp @@ -20,16 +20,16 @@ * */ -#include "ac/gamesetupstruct.h" -#include "ac/viewframe.h" -#include "debug/debug_log.h" -#include "ac/spritecache.h" -#include "gfx/bitmap.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_audioclip.h" -#include "ac/draw.h" -#include "ac/game_version.h" -#include "media/audio/audio_system.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/viewframe.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_audioclip.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/media/audio/audio_system.h" } // namespace AGS3 @@ -178,9 +178,9 @@ void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha // //============================================================================= -#include "debug/out.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" // int (ScriptViewFrame *svf) RuntimeScriptValue Sc_ViewFrame_GetFlipped(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/viewframe.h b/engines/ags/engine/ac/viewframe.h index 7e2c4edbf53f..d169d83cdc0a 100644 --- a/engines/ags/engine/ac/viewframe.h +++ b/engines/ags/engine/ac/viewframe.h @@ -23,11 +23,11 @@ #ifndef AGS_ENGINE_AC_VIEWFRAME_H #define AGS_ENGINE_AC_VIEWFRAME_H -#include "ac/runtime_defines.h" -#include "ac/view.h" -#include "ac/dynobj/scriptaudioclip.h" -#include "ac/dynobj/scriptviewframe.h" -#include "gfx/bitmap.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/engine/ac/dynobj/scriptviewframe.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { @@ -54,7 +54,7 @@ int ViewFrame_GetFrame(ScriptViewFrame *svf); void precache_view(int view); void CheckViewFrame(int view, int loop, int frame, int sound_volume = SCR_NO_VALUE); // draws a view frame, flipped if appropriate -void DrawViewFrame(Common::Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend = false); +void DrawViewFrame(Shared::Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha_blend = false); } // namespace AGS3 diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp index d4f405ab7628..e145c78d9661 100644 --- a/engines/ags/engine/ac/viewport_script.cpp +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -26,14 +26,14 @@ // //============================================================================= -#include "ac/dynobj/scriptcamera.h" -#include "ac/dynobj/scriptviewport.h" -#include "ac/dynobj/scriptuserobject.h" -#include "ac/draw.h" -#include "ac/gamestate.h" -#include "debug/debug_log.h" -#include "script/script_api.h" -#include "script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptcamera.h" +#include "ags/shared/ac/dynobj/scriptviewport.h" +#include "ags/shared/ac/dynobj/scriptuserobject.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp index 93d6d5c07f90..8d9a62caf20e 100644 --- a/engines/ags/engine/ac/walkablearea.cpp +++ b/engines/ags/engine/ac/walkablearea.cpp @@ -20,18 +20,18 @@ * */ -#include "ac/common.h" -#include "ac/object.h" -#include "ac/character.h" -#include "ac/gamestate.h" -#include "ac/gamesetupstruct.h" -#include "ac/object.h" -#include "ac/room.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "ac/walkablearea.h" -#include "game/roomstruct.h" -#include "gfx/bitmap.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/object.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/walkablearea.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/walkablearea.h b/engines/ags/engine/ac/walkablearea.h index 922f90af10de..68717ddb8d6c 100644 --- a/engines/ags/engine/ac/walkablearea.h +++ b/engines/ags/engine/ac/walkablearea.h @@ -31,7 +31,7 @@ int get_area_scaling(int onarea, int xx, int yy); void scale_sprite_size(int sppic, int zoom_level, int *newwidth, int *newheight); void remove_walkable_areas_from_temp(int fromx, int cwidth, int starty, int endy); int is_point_in_rect(int x, int y, int left, int top, int right, int bottom); -Common::Bitmap *prepare_walkable_areas(int sourceChar); +Shared::Bitmap *prepare_walkable_areas(int sourceChar); int get_walkable_area_at_location(int xx, int yy); int get_walkable_area_at_character(int charnum); diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp index 90744461858a..27b36e1ec4f5 100644 --- a/engines/ags/engine/ac/walkbehind.cpp +++ b/engines/ags/engine/ac/walkbehind.cpp @@ -20,12 +20,12 @@ * */ -#include "ac/walkbehind.h" -#include "ac/common.h" -#include "ac/common_defines.h" -#include "ac/gamestate.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" +#include "ags/shared/ac/walkbehind.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/debugging/consoleoutputtarget.cpp b/engines/ags/engine/debugging/consoleoutputtarget.cpp index 6f638edd7b03..cc9a72e452da 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.cpp +++ b/engines/ags/engine/debugging/consoleoutputtarget.cpp @@ -20,9 +20,9 @@ * */ -#include -#include "consoleoutputtarget.h" -#include "debug/debug_log.h" +//include +#include "ags/engine/debugging/consoleoutputtarget.h" +#include "ags/engine/debugging/debug_log.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/debugging/consoleoutputtarget.h b/engines/ags/engine/debugging/consoleoutputtarget.h index 7772d45de09a..e3caefa6e199 100644 --- a/engines/ags/engine/debugging/consoleoutputtarget.h +++ b/engines/ags/engine/debugging/consoleoutputtarget.h @@ -30,14 +30,14 @@ #ifndef AGS_ENGINE_DEBUGGING_CONSOLEOUTPUTTARGET_H #define AGS_ENGINE_DEBUGGING_CONSOLEOUTPUTTARGET_H -#include "debug/outputhandler.h" +#include "ags/shared/debugging/outputhandler.h" namespace AGS3 { namespace AGS { namespace Engine { -using Common::String; -using Common::DebugMessage; +using Shared::String; +using Shared::DebugMessage; class ConsoleOutputTarget : public AGS::Shared::IOutputHandler { public: diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index a974ff299539..903787665d9d 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -20,32 +20,33 @@ * */ -#include -#include -#include "core/platform.h" -#include "ac/common.h" -#include "ac/gamesetupstruct.h" -#include "ac/runtime_defines.h" -#include "debug/agseditordebugger.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "debug/debugmanager.h" -#include "debug/out.h" -#include "debug/consoleoutputtarget.h" -#include "debug/logfile.h" -#include "debug/messagebuffer.h" -#include "main/config.h" -#include "media/audio/audio_system.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/plugin_engine.h" -#include "script/script.h" -#include "script/script_common.h" -#include "script/cc_error.h" -#include "util/string_utils.h" -#include "util/textstreamwriter.h" +#include "ags/std/initializer_list.h" +#include "ags/std/limits.h" +#include "ags/std/memory.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/debugging/agseditordebugger.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/shared/debugging/debugmanager.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/debugging/consoleoutputtarget.h" +#include "ags/engine/debugging/logfile.h" +#include "ags/engine/debugging/messagebuffer.h" +#include "ags/engine/main/config.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/plugin_engine.h" +#include "ags/engine/script/script.h" +#include "ags/shared/script/script_common.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/util/textstreamwriter.h" #if AGS_PLATFORM_OS_WINDOWS -#include +//include #endif namespace AGS3 { @@ -70,7 +71,7 @@ volatile int game_paused_in_debugger = 0; #if AGS_PLATFORM_OS_WINDOWS -#include "platform/windows/debug/namedpipesagsdebugger.h" +#include "ags/shared/platform/windows/debug/namedpipesagsdebugger.h" HWND editor_window_handle = 0; @@ -167,8 +168,8 @@ MessageType get_messagetype_from_string(const String &mt) { typedef std::pair DbgGroupOption; void apply_log_config(const ConfigTree &cfg, const String &log_id, - bool def_enabled, - std::initializer_list def_opts) { + bool def_enabled, + std::initializer_list def_opts) { String value = INIreadstring(cfg, "log", log_id); if (value.IsEmpty() && !def_enabled) return; diff --git a/engines/ags/engine/debugging/debug_log.h b/engines/ags/engine/debugging/debug_log.h index 729fafabacc8..95250862186f 100644 --- a/engines/ags/engine/debugging/debug_log.h +++ b/engines/ags/engine/debugging/debug_log.h @@ -23,11 +23,11 @@ #ifndef AGS_ENGINE_DEBUGGING_LOG_H #define AGS_ENGINE_DEBUGGING_LOG_H -#include "script/cc_instance.h" -#include "ac/runtime_defines.h" -#include "ac/gamestate.h" -#include "platform/base/agsplatformdriver.h" -#include "util/ini_util.h" +#include "ags/engine/script/cc_instance.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/shared/util/ini_util.h" namespace AGS3 { diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h index 5f97124f5e7f..8e87d71f22d5 100644 --- a/engines/ags/engine/debugging/debugger.h +++ b/engines/ags/engine/debugging/debugger.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_DEBUGGING_DEBUGGER_H #define AGS_ENGINE_DEBUGGING_DEBUGGER_H -#include "util/string.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/debugging/dummyagsdebugger.h b/engines/ags/engine/debugging/dummyagsdebugger.h index 2845e28a9ed1..cc1158755a1a 100644 --- a/engines/ags/engine/debugging/dummyagsdebugger.h +++ b/engines/ags/engine/debugging/dummyagsdebugger.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_DEBUGGING_DUMMYAGSDEBUGGER_H #define AGS_ENGINE_DEBUGGING_DUMMYAGSDEBUGGER_H -#include "debug/debugger.h" +#include "ags/shared/debug/debugger.h" namespace AGS3 { diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.cpp b/engines/ags/engine/debugging/filebasedagsdebugger.cpp index 891fac1155ce..c8e6b420225f 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.cpp +++ b/engines/ags/engine/debugging/filebasedagsdebugger.cpp @@ -20,13 +20,15 @@ * */ -#include -#include "debug/filebasedagsdebugger.h" -#include "ac/file.h" // filelength() -#include "util/stream.h" -#include "util/textstreamwriter.h" -#include "util/wgt2allg.h" // exists() -#include "platform/base/agsplatformdriver.h" +//include +#include "ags/engine/debugging/filebasedagsdebugger.h" +#include "ags/engine/ac/file.h" // filelength() +#include "ags/shared/util/stream.h" +#include "ags/shared/util/textstreamwriter.h" +#include "ags/shared/util/wgt2allg.h" // exists() +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "common/system.h" +#include "common/savefile.h" namespace AGS3 { @@ -35,9 +37,21 @@ using AGS::Shared::TextStreamWriter; const char *SENT_MESSAGE_FILE_NAME = "dbgrecv.tmp"; +static bool exists(const char *filename) { + Common::InSaveFile *save = g_system->getSavefileManager()->openForLoading(filename); + bool result = save != nullptr; + delete save; + + return result; +} + +static bool remove(const char *filename) { + return g_system->getSavefileManager()->removeSavefile(filename); +} + bool FileBasedAGSDebugger::Initialize() { if (exists(SENT_MESSAGE_FILE_NAME)) { - ::remove(SENT_MESSAGE_FILE_NAME); + remove(SENT_MESSAGE_FILE_NAME); } return true; } @@ -50,7 +64,7 @@ bool FileBasedAGSDebugger::SendMessageToEditor(const char *message) { platform->YieldCPU(); } - Stream *out = Common::File::CreateFile(SENT_MESSAGE_FILE_NAME); + Stream *out = Shared::File::CreateFile(SENT_MESSAGE_FILE_NAME); // CHECKME: originally the file was opened as "wb" for some reason, // which means the message should be written as a binary array; // or shouldn't it? @@ -64,7 +78,7 @@ bool FileBasedAGSDebugger::IsMessageAvailable() { } char *FileBasedAGSDebugger::GetNextMessage() { - Stream *in = Common::File::OpenFileRead("dbgsend.tmp"); + Stream *in = Shared::File::OpenFileRead("dbgsend.tmp"); if (in == nullptr) { // check again, because the editor might have deleted the file in the meantime return nullptr; diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.h b/engines/ags/engine/debugging/filebasedagsdebugger.h index 3ba6b4acf7e5..eae9a7aa917a 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.h +++ b/engines/ags/engine/debugging/filebasedagsdebugger.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_DEBUGGING_FILEBASEDAGSDEBUGGER_H #define AGS_ENGINE_DEBUGGING_FILEBASEDAGSDEBUGGER_H -#include "debug/agseditordebugger.h" +#include "ags/engine/debugging/agseditordebugger.h" namespace AGS3 { diff --git a/engines/ags/engine/debugging/logfile.cpp b/engines/ags/engine/debugging/logfile.cpp index 6e237e6f4847..2117fae27c1e 100644 --- a/engines/ags/engine/debugging/logfile.cpp +++ b/engines/ags/engine/debugging/logfile.cpp @@ -20,10 +20,10 @@ * */ -#include -#include "debug/logfile.h" -#include "util/file.h" -#include "util/stream.h" +//include +#include "ags/engine/debugging/logfile.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { @@ -39,8 +39,8 @@ void LogFile::PrintMessage(const DebugMessage &msg) { if (!_file.get()) { if (_filePath.IsEmpty()) return; - _file.reset(File::OpenFile(_filePath, _openMode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, - Common::kFile_Write)); + _file.reset(File::OpenFile(_filePath, _openMode == kLogFile_Append ? Shared::kFile_Create : Shared::kFile_CreateAlways, + Shared::kFile_Write)); if (!_file) { Debug::Printf("Unable to write log to '%s'.", _filePath.GetCStr()); _filePath = ""; @@ -69,8 +69,8 @@ bool LogFile::OpenFile(const String &file_path, OpenMode open_mode) { return File::TestWriteFile(_filePath); } else { _file.reset(File::OpenFile(file_path, - open_mode == kLogFile_Append ? Common::kFile_Create : Common::kFile_CreateAlways, - Common::kFile_Write)); + open_mode == kLogFile_Append ? Shared::kFile_Create : Shared::kFile_CreateAlways, + Shared::kFile_Write)); return _file.get() != nullptr; } } diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h index 45298067d103..18a43563427b 100644 --- a/engines/ags/engine/debugging/logfile.h +++ b/engines/ags/engine/debugging/logfile.h @@ -35,8 +35,8 @@ #ifndef AGS_ENGINE_DEBUGGING_LOGFILE_H #define AGS_ENGINE_DEBUGGING_LOGFILE_H -#include -#include "debug/outputhandler.h" +#include "ags/std/memory.h" +#include "ags/shared/debugging/outputhandler.h" namespace AGS3 { namespace AGS { @@ -47,9 +47,9 @@ class Stream; namespace Engine { -using Common::DebugMessage; -using Common::Stream; -using Common::String; +using Shared::DebugMessage; +using Shared::Stream; +using Shared::String; class LogFile : public AGS::Shared::IOutputHandler { public: @@ -62,7 +62,7 @@ class LogFile : public AGS::Shared::IOutputHandler { public: LogFile(); - void PrintMessage(const Common::DebugMessage &msg) override; + void PrintMessage(const Shared::DebugMessage &msg) override; // Open file using given file path, optionally appending if one exists // diff --git a/engines/ags/engine/debugging/messagebuffer.cpp b/engines/ags/engine/debugging/messagebuffer.cpp index 24fe07705d68..d946c2a2afd1 100644 --- a/engines/ags/engine/debugging/messagebuffer.cpp +++ b/engines/ags/engine/debugging/messagebuffer.cpp @@ -20,8 +20,8 @@ * */ -#include "debug/debugmanager.h" -#include "debug/messagebuffer.h" +#include "ags/shared/debugging/debugmanager.h" +#include "ags/engine/debugging/messagebuffer.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h index 4c5d822e3ebf..57016fe61148 100644 --- a/engines/ags/engine/debugging/messagebuffer.h +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -31,15 +31,15 @@ #ifndef AGS_ENGINE_DEBUGGING_MESSAGEBUFFER_H #define AGS_ENGINE_DEBUGGING_MESSAGEBUFFER_H -#include -#include "debug/outputhandler.h" +#include "ags/std/vector.h" +#include "ags/shared/debugging/outputhandler.h" namespace AGS3 { namespace AGS { namespace Engine { -using Common::String; -using Common::DebugMessage; +using Shared::String; +using Shared::DebugMessage; class MessageBuffer : public AGS::Shared::IOutputHandler { public: diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index 7192299bae80..5544601fd886 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -31,33 +31,33 @@ // //============================================================================= -#include "core/platform.h" +#include "ags/shared/core/platform.h" #define AGS_SIMULATE_RIGHT_CLICK (AGS_PLATFORM_OS_MACOS) #if AGS_PLATFORM_OS_WINDOWS -#include -#include -#include +//include +//include +//include #endif -#include "util/wgt2allg.h" +#include "ags/shared/util/wgt2allg.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif -#include "ac/gamestate.h" -#include "debug/out.h" -#include "device/mousew32.h" -#include "gfx/bitmap.h" -#include "gfx/gfx_util.h" -#include "main/graphics_mode.h" -#include "platform/base/agsplatformdriver.h" -#include "util/math.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/main/graphics_mode.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/util/math.h" #if AGS_SIMULATE_RIGHT_CLICK -#include "ac/sys_events.h" // j for ags_iskeypressed +#include "ags/shared/ac/sys_events.h" // j for ags_iskeypressed #endif namespace AGS3 { diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h index 128782ea0441..6662320676df 100644 --- a/engines/ags/engine/device/mousew32.h +++ b/engines/ags/engine/device/mousew32.h @@ -31,11 +31,11 @@ // //============================================================================= -#include "util/geometry.h" +#include "ags/shared/util/geometry.h" #define MAXCURSORS 20 -#include "util/geometry.h" +#include "ags/shared/util/geometry.h" namespace AGS3 { namespace AGS { @@ -101,6 +101,6 @@ extern int hotx, hoty; extern int disable_mgetgraphpos; extern char currentcursor; -extern Common::Bitmap *mousecurs[MAXCURSORS]; +extern Shared::Bitmap *mousecurs[MAXCURSORS]; } // namespace AGS3 diff --git a/engines/ags/engine/font/fonts_engine.cpp b/engines/ags/engine/font/fonts_engine.cpp index 2b77e3d496ab..b52947b26cda 100644 --- a/engines/ags/engine/font/fonts_engine.cpp +++ b/engines/ags/engine/font/fonts_engine.cpp @@ -26,8 +26,8 @@ // //============================================================================= -#include -#include "ac/gamesetupstruct.h" +//include +#include "ags/shared/ac/gamesetupstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp index 3df894addc59..3836f46af7d1 100644 --- a/engines/ags/engine/game/game_init.cpp +++ b/engines/ags/engine/game/game_init.cpp @@ -20,36 +20,36 @@ * */ -#include "ac/character.h" -#include "ac/charactercache.h" -#include "ac/dialog.h" -#include "ac/draw.h" -#include "ac/file.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/gui.h" -#include "ac/movelist.h" -#include "ac/dynobj/all_dynamicclasses.h" -#include "ac/dynobj/all_scriptclasses.h" -#include "ac/statobj/agsstaticobject.h" -#include "ac/statobj/staticarray.h" -#include "debug/debug_log.h" -#include "debug/out.h" -#include "font/agsfontrenderer.h" -#include "font/fonts.h" -#include "game/game_init.h" -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "gui/guilabel.h" -#include "plugin/plugin_engine.h" -#include "script/cc_error.h" -#include "script/exports.h" -#include "script/script.h" -#include "script/script_runtime.h" -#include "util/string_utils.h" -#include "media/audio/audio_system.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/charactercache.h" +#include "ags/shared/ac/dialog.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/file.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/dynobj/all_dynamicclasses.h" +#include "ags/shared/ac/dynobj/all_scriptclasses.h" +#include "ags/shared/ac/statobj/agsstaticobject.h" +#include "ags/shared/ac/statobj/staticarray.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/font/agsfontrenderer.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/game/game_init.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/exports.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/game/game_init.h b/engines/ags/engine/game/game_init.h index ec905d981edc..0591548fbb3e 100644 --- a/engines/ags/engine/game/game_init.h +++ b/engines/ags/engine/game/game_init.h @@ -30,8 +30,8 @@ #ifndef AGS_ENGINE_GAME_GAMEINIT_H #define AGS_ENGINE_GAME_GAMEINIT_H -#include "game/main_game_file.h" -#include "util/string.h" +#include "ags/shared/game/main_game_file.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index 1b55a38210d0..cc8f5bbd8820 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -20,47 +20,47 @@ * */ -#include "ac/character.h" -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/dynamicsprite.h" -#include "ac/event.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/gamesetup.h" -#include "ac/global_audio.h" -#include "ac/global_character.h" -#include "ac/gui.h" -#include "ac/mouse.h" -#include "ac/overlay.h" -#include "ac/region.h" -#include "ac/richgamemedia.h" -#include "ac/room.h" -#include "ac/roomstatus.h" -#include "ac/spritecache.h" -#include "ac/system.h" -#include "ac/timer.h" -#include "debug/out.h" -#include "device/mousew32.h" -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "gfx/graphicsdriver.h" -#include "game/savegame.h" -#include "game/savegame_components.h" -#include "game/savegame_internal.h" -#include "main/engine.h" -#include "main/main.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "script/script.h" -#include "script/cc_error.h" -#include "util/alignedstream.h" -#include "util/file.h" -#include "util/stream.h" -#include "util/string_utils.h" -#include "media/audio/audio_system.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/region.h" +#include "ags/shared/ac/richgamemedia.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/timer.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/game/savegame.h" +#include "ags/shared/game/savegame_components.h" +#include "ags/shared/game/savegame_internal.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/main/main.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h index 1445d07907e2..53b7d355d276 100644 --- a/engines/ags/engine/game/savegame.h +++ b/engines/ags/engine/game/savegame.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_GAME_SAVEGAME_H #define AGS_ENGINE_GAME_SAVEGAME_H -#include -#include "ac/game_version.h" -#include "util/error.h" -#include "util/version.h" +#include "ags/std/memory.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/util/error.h" +#include "ags/shared/util/version.h" namespace AGS3 { @@ -38,12 +38,12 @@ class Stream; namespace Engine { -using Common::Bitmap; -using Common::ErrorHandle; -using Common::TypedCodeError; -using Common::Stream; -using Common::String; -using Common::Version; +using Shared::Bitmap; +using Shared::ErrorHandle; +using Shared::TypedCodeError; +using Shared::Stream; +using Shared::String; +using Shared::Version; typedef std::shared_ptr PStream; diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index c0bef7a568f9..1e558819f995 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -20,45 +20,45 @@ * */ -#include - -#include "ac/audiocliptype.h" -#include "ac/character.h" -#include "ac/common.h" -#include "ac/dialogtopic.h" -#include "ac/draw.h" -#include "ac/dynamicsprite.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/gui.h" -#include "ac/mouse.h" -#include "ac/movelist.h" -#include "ac/overlay.h" -#include "ac/roomstatus.h" -#include "ac/screenoverlay.h" -#include "ac/spritecache.h" -#include "ac/view.h" -#include "ac/system.h" -#include "ac/dynobj/cc_serializer.h" -#include "debug/out.h" -#include "game/savegame_components.h" -#include "game/savegame_internal.h" -#include "gfx/bitmap.h" -#include "gui/animatingguibutton.h" -#include "gui/guibutton.h" -#include "gui/guiinv.h" -#include "gui/guilabel.h" -#include "gui/guilistbox.h" -#include "gui/guimain.h" -#include "gui/guislider.h" -#include "gui/guitextbox.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "script/cc_error.h" -#include "script/script.h" -#include "util/filestream.h" // TODO: needed only because plugins expect file handle -#include "media/audio/audio_system.h" +//include + +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/overlay.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/screenoverlay.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/ac/dynobj/cc_serializer.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/game/savegame_components.h" +#include "ags/shared/game/savegame_internal.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gui/animatingguibutton.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/shared/gui/guilistbox.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guislider.h" +#include "ags/shared/gui/guitextbox.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/script.h" +#include "ags/shared/util/filestream.h" // TODO: needed only because plugins expect file handle +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h index 009516e50579..18cfb46a6fcc 100644 --- a/engines/ags/engine/game/savegame_components.h +++ b/engines/ags/engine/game/savegame_components.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_GAME_SAVEGAMECOMPONENTS_H #define AGS_ENGINE_GAME_SAVEGAMECOMPONENTS_H -#include "game/savegame.h" -#include "util/stream.h" +#include "ags/shared/game/savegame.h" +#include "ags/shared/util/stream.h" namespace AGS3 { namespace AGS { @@ -35,7 +35,7 @@ struct Interaction; namespace Engine { -using Common::Stream; +using Shared::Stream; typedef std::shared_ptr PStream; struct PreservedParams; diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index 11cdd707622b..713c662d9d64 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -23,11 +23,11 @@ #ifndef AGS_ENGINE_GAME_SAVEGAMEINTERNAL_H #define AGS_ENGINE_GAME_SAVEGAMEINTERNAL_H -#include -#include -#include "ac/common_defines.h" -#include "gfx/bitmap.h" -#include "media/audio/audiodefines.h" +#include "ags/std/memory.h" +#include "ags/std/vector.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/media/audio/audiodefines.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp index ddbed3d8be32..cc5415f8b377 100644 --- a/engines/ags/engine/game/viewport.cpp +++ b/engines/ags/engine/game/viewport.cpp @@ -20,11 +20,11 @@ * */ -#include "ac/draw.h" -#include "ac/gamestate.h" -#include "debug/debug_log.h" -#include "game/roomstruct.h" -#include "game/viewport.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/game/roomstruct.h" +#include "ags/shared/game/viewport.h" namespace AGS3 { diff --git a/engines/ags/engine/game/viewport.h b/engines/ags/engine/game/viewport.h index f39040cfdb58..3834dd9e0a01 100644 --- a/engines/ags/engine/game/viewport.h +++ b/engines/ags/engine/game/viewport.h @@ -29,10 +29,10 @@ #ifndef AGS_ENGINE_GAME_VIEWPORT_H #define AGS_ENGINE_GAME_VIEWPORT_H -#include -#include -#include "util/geometry.h" -#include "util/scaling.h" +#include "ags/std/memory.h" +#include "ags/std/vector.h" +#include "ags/shared/util/geometry.h" +#include "ags/engine/util/scaling.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 5b275a592b98..06355a0fa667 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -20,20 +20,20 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX -#include -#include "gfx/ali3dexception.h" -#include "gfx/ali3dogl.h" -#include "gfx/gfxfilter_ogl.h" -#include "gfx/gfxfilter_aaogl.h" -#include "gfx/gfx_util.h" -#include "main/main_allegro.h" -#include "platform/base/agsplatformdriver.h" -#include "util/math.h" -#include "ac/timer.h" +//include +#include "ags/shared/gfx/ali3dexception.h" +#include "ags/shared/gfx/ali3dogl.h" +#include "ags/shared/gfx/gfxfilter_ogl.h" +#include "ags/shared/gfx/gfxfilter_aaogl.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/main/main_allegro.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/util/math.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h index 171817bcdb2c..fde7c439aab6 100644 --- a/engines/ags/engine/gfx/ali3dogl.h +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -29,15 +29,15 @@ #ifndef AGS_ENGINE_GFX_ALI3DOGL_H #define AGS_ENGINE_GFX_ALI3DOGL_H -#include -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "gfx/gfxdriverfactorybase.h" -#include "gfx/gfxdriverbase.h" -#include "util/string.h" -#include "util/version.h" +#include "ags/std/memory.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/gfxdriverfactorybase.h" +#include "ags/shared/gfx/gfxdriverbase.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/version.h" -#include "ogl_headers.h" +#include "ags/shared/ogl_headers.h" namespace AGS3 { namespace AGS { @@ -45,8 +45,8 @@ namespace Engine { namespace OGL { -using Common::Bitmap; -using Common::String; +using Shared::Bitmap; +using Shared::String; using Common::Version; typedef struct _OGLVECTOR { diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index 85b121ced9e1..ec380f7c1285 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -26,16 +26,16 @@ // //============================================================================= -#include "gfx/ali3dsw.h" +#include "ags/shared/gfx/ali3dsw.h" -#include "core/platform.h" -#include "gfx/ali3dexception.h" -#include "gfx/gfxfilter_allegro.h" -#include "gfx/gfxfilter_hqx.h" -#include "gfx/gfx_util.h" -#include "main/main_allegro.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/timer.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/gfx/ali3dexception.h" +#include "ags/shared/gfx/gfxfilter_allegro.h" +#include "ags/shared/gfx/gfxfilter_hqx.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/main/main_allegro.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { @@ -449,7 +449,7 @@ void ALSoftwareGraphicsDriver::RenderToBackBuffer() { ClearDrawLists(); } -void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy) { +void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Shared::Bitmap *surface, int surf_offx, int surf_offy) { const std::vector &drawlist = batch.List; for (size_t i = 0; i < drawlist.size(); i++) { if (drawlist[i].bitmap == nullptr) { diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index 54bfc93d90f2..91b192782e88 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -29,22 +29,22 @@ #ifndef AGS_ENGINE_GFX_ALI3DSW_H #define AGS_ENGINE_GFX_ALI3DSW_H -#include +#include "ags/std/memory.h" -#include "core/platform.h" +#include "ags/shared/core/platform.h" #define AGS_DDRAW_GAMMA_CONTROL (AGS_PLATFORM_OS_WINDOWS) #include "ags/lib/allegro.h" #if AGS_DDRAW_GAMMA_CONTROL -#include -#include +//include +//include #endif -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "gfx/gfxdriverfactorybase.h" -#include "gfx/gfxdriverbase.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/gfxdriverfactorybase.h" +#include "ags/shared/gfx/gfxdriverbase.h" namespace AGS3 { namespace AGS { @@ -263,7 +263,7 @@ class ALSoftwareGraphicsDriver : public GraphicsDriverBase { // Unset parameters and release resources related to the display mode void ReleaseDisplayMode(); // Renders single sprite batch on the precreated surface - void RenderSpriteBatch(const ALSpriteBatch &batch, Common::Bitmap *surface, int surf_offx, int surf_offy); + void RenderSpriteBatch(const ALSpriteBatch &batch, Shared::Bitmap *surface, int surf_offx, int surf_offy); void highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); void highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); diff --git a/engines/ags/engine/gfx/blender.cpp b/engines/ags/engine/gfx/blender.cpp index 736768836e37..e4eb457e7a3a 100644 --- a/engines/ags/engine/gfx/blender.cpp +++ b/engines/ags/engine/gfx/blender.cpp @@ -20,9 +20,9 @@ * */ -#include "core/types.h" -#include "gfx/blender.h" -#include "util/wgt2allg.h" +#include "ags/shared/core/types.h" +#include "ags/shared/gfx/blender.h" +#include "ags/shared/util/wgt2allg.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/color_engine.cpp b/engines/ags/engine/gfx/color_engine.cpp index ae3ec5e1921c..4726d0f677c9 100644 --- a/engines/ags/engine/gfx/color_engine.cpp +++ b/engines/ags/engine/gfx/color_engine.cpp @@ -26,10 +26,10 @@ // //============================================================================= -#include "core/platform.h" +#include "ags/shared/core/platform.h" -#include "util/wgt2allg.h" -#include "gfx/bitmap.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp index dd309c0cefc4..aadbb940a4dc 100644 --- a/engines/ags/engine/gfx/gfx_util.cpp +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -20,9 +20,9 @@ * */ -#include "core/platform.h" -#include "gfx/gfx_util.h" -#include "gfx/blender.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/gfx/blender.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfx_util.h b/engines/ags/engine/gfx/gfx_util.h index e9b9f17199ad..7e8f1e6f0372 100644 --- a/engines/ags/engine/gfx/gfx_util.h +++ b/engines/ags/engine/gfx/gfx_util.h @@ -35,14 +35,14 @@ #ifndef AGS_ENGINE_GFX_GFXUTIL_H #define AGS_ENGINE_GFX_GFXUTIL_H -#include "gfx/bitmap.h" -#include "gfx/gfx_def.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfx_def.h" namespace AGS3 { namespace AGS { namespace Engine { -using Common::Bitmap; +using Shared::Bitmap; namespace GfxUtil { // Creates a COPY of the source bitmap, converted to the given format. diff --git a/engines/ags/engine/gfx/gfxdefines.h b/engines/ags/engine/gfx/gfxdefines.h index cbb4fab49646..0f2e2cf458b9 100644 --- a/engines/ags/engine/gfx/gfxdefines.h +++ b/engines/ags/engine/gfx/gfxdefines.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GFX_GFXDEFINES_H #define AGS_ENGINE_GFX_GFXDEFINES_H -#include "core/types.h" +#include "ags/shared/core/types.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index 7de8c33ed29e..d1dd038ab8c8 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -20,12 +20,12 @@ * */ -#include "util/wgt2allg.h" -#include "gfx/ali3dexception.h" -#include "gfx/bitmap.h" -#include "gfx/gfxfilter.h" -#include "gfx/gfxdriverbase.h" -#include "gfx/gfx_util.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/gfx/ali3dexception.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/gfx/gfxdriverbase.h" +#include "ags/shared/gfx/gfx_util.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfxdriverbase.h b/engines/ags/engine/gfx/gfxdriverbase.h index 14012a957731..b845de3b4aae 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.h +++ b/engines/ags/engine/gfx/gfxdriverbase.h @@ -29,16 +29,16 @@ #ifndef AGS_ENGINE_GFX_GFXDRIVERBASE_H #define AGS_ENGINE_GFX_GFXDRIVERBASE_H -#include -#include "gfx/ddb.h" -#include "gfx/graphicsdriver.h" -#include "util/scaling.h" +#include "ags/std/vector.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/util/scaling.h" namespace AGS3 { namespace AGS { namespace Engine { -using Common::Bitmap; +using Shared::Bitmap; // Sprite batch, defines viewport and an optional model transformation for the list of sprites struct SpriteBatchDesc { diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp index d2469785df1f..00dcbf52119d 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.cpp +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -20,27 +20,27 @@ * */ -#include "gfx/gfxdriverfactory.h" +#include "ags/shared/gfx/gfxdriverfactory.h" -#include "core/platform.h" +#include "ags/shared/core/platform.h" #define AGS_HAS_DIRECT3D (AGS_PLATFORM_OS_WINDOWS) #define AGS_HAS_OPENGL (AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX) -#include "gfx/ali3dsw.h" -#include "gfx/gfxfilter_allegro.h" +#include "ags/shared/gfx/ali3dsw.h" +#include "ags/shared/gfx/gfxfilter_allegro.h" #if AGS_HAS_OPENGL -#include "gfx/ali3dogl.h" -#include "gfx/gfxfilter_ogl.h" +#include "ags/shared/gfx/ali3dogl.h" +#include "ags/shared/gfx/gfxfilter_ogl.h" #endif #if AGS_HAS_DIRECT3D -#include "platform/windows/gfx/ali3dd3d.h" -#include "gfx/gfxfilter_d3d.h" +#include "ags/shared/platform/windows/gfx/ali3dd3d.h" +#include "ags/shared/gfx/gfxfilter_d3d.h" #endif -#include "main/main_allegro.h" +#include "ags/shared/main/main_allegro.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxdriverfactory.h b/engines/ags/engine/gfx/gfxdriverfactory.h index eb6bae49eed4..b28560d76530 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.h +++ b/engines/ags/engine/gfx/gfxdriverfactory.h @@ -33,16 +33,16 @@ #ifndef AGS_ENGINE_GFX_GFXDRIVERFACTORY_H #define AGS_ENGINE_GFX_GFXDRIVERFACTORY_H -#include -#include "util/string.h" -#include "util/string_types.h" +#include "ags/std/memory.h" +#include "ags/shared/util/string.h" +#include "ags/shared/util/string_types.h" namespace AGS3 { namespace AGS { namespace Engine { -using Common::String; -using Common::StringV; +using Shared::String; +using Shared::StringV; class IGraphicsDriver; class IGfxFilter; struct GfxFilterInfo; diff --git a/engines/ags/engine/gfx/gfxdriverfactorybase.h b/engines/ags/engine/gfx/gfxdriverfactorybase.h index 337901ca80a9..5424ea7c8999 100644 --- a/engines/ags/engine/gfx/gfxdriverfactorybase.h +++ b/engines/ags/engine/gfx/gfxdriverfactorybase.h @@ -33,9 +33,9 @@ #ifndef AGS_ENGINE_GFX_GFXDRIVERFACTORYBASE_H #define AGS_ENGINE_GFX_GFXDRIVERFACTORYBASE_H -#include -#include "gfx/gfxdriverfactory.h" -#include "gfx/gfxfilter.h" +#include "ags/std/vector.h" +#include "ags/shared/gfx/gfxdriverfactory.h" +#include "ags/shared/gfx/gfxfilter.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter.h b/engines/ags/engine/gfx/gfxfilter.h index a8fc9b4da677..7b0f636215a8 100644 --- a/engines/ags/engine/gfx/gfxfilter.h +++ b/engines/ags/engine/gfx/gfxfilter.h @@ -29,15 +29,15 @@ #ifndef AGS_ENGINE_GFX_GFXFILTER_H #define AGS_ENGINE_GFX_GFXFILTER_H -#include -#include "util/geometry.h" -#include "util/string.h" +#include "ags/std/memory.h" +#include "ags/shared/util/geometry.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { namespace Engine { -using Common::String; +using Shared::String; struct GfxFilterInfo { String Id; diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp index bdbde84b7526..eebfbbbed531 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp @@ -20,12 +20,12 @@ * */ -#include "core/platform.h" -#include "stdio.h" -#include "gfx/gfxfilter_aad3d.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/stdio.h" +#include "ags/shared/gfx/gfxfilter_aad3d.h" #if AGS_PLATFORM_OS_WINDOWS -#include +//include #endif namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.h b/engines/ags/engine/gfx/gfxfilter_aad3d.h index 84c376ec07b8..351cfa22b6f7 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.h +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_AAD3DGFXFILTER_H #define AGS_ENGINE_GFX_AAD3DGFXFILTER_H -#include "gfx/gfxfilter_d3d.h" +#include "ags/shared/gfx/gfxfilter_d3d.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp index 70d5e869a341..0bec89329c4c 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp @@ -20,12 +20,12 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX -#include "gfx/gfxfilter_aaogl.h" -#include "ogl_headers.h" +#include "ags/shared/gfx/gfxfilter_aaogl.h" +#include "ags/shared/ogl_headers.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.h b/engines/ags/engine/gfx/gfxfilter_aaogl.h index 3d77922736a1..6c4036549482 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.h +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_AAOGLGFXFILTER_H #define AGS_ENGINE_GFX_AAOGLGFXFILTER_H -#include "gfx/gfxfilter_ogl.h" +#include "ags/shared/gfx/gfxfilter_ogl.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index 8385ef783d58..b1f1a93ed122 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -20,7 +20,7 @@ * */ -#include "gfx/gfxfilter_allegro.h" +#include "ags/shared/gfx/gfxfilter_allegro.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h index fe2b856c8b4b..e0906d41d5f6 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.h +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -29,16 +29,16 @@ #ifndef AGS_ENGINE_GFX_ALLEGROGFXFILTER_H #define AGS_ENGINE_GFX_ALLEGROGFXFILTER_H -#include "gfx/bitmap.h" -#include "gfx/gfxfilter_scaling.h" -#include "gfx/gfxdefines.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfxfilter_scaling.h" +#include "ags/shared/gfx/gfxdefines.h" namespace AGS3 { namespace AGS { namespace Engine { namespace ALSW { -using Common::Bitmap; +using Shared::Bitmap; class AllegroGfxFilter : public ScalingGfxFilter { public: diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.cpp b/engines/ags/engine/gfx/gfxfilter_d3d.cpp index 8156af57eefb..9e4eb302e542 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_d3d.cpp @@ -20,10 +20,10 @@ * */ -#include "core/platform.h" -#include "gfx/gfxfilter_d3d.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/gfx/gfxfilter_d3d.h" #if AGS_PLATFORM_OS_WINDOWS -#include +//include #endif namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.h b/engines/ags/engine/gfx/gfxfilter_d3d.h index ead9ae305e08..e5cd2b239574 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.h +++ b/engines/ags/engine/gfx/gfxfilter_d3d.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_D3DGFXFILTER_H #define AGS_ENGINE_GFX_D3DGFXFILTER_H -#include "gfx/gfxfilter_scaling.h" +#include "ags/shared/gfx/gfxfilter_scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp index 1974779a7c94..2acd26f0d49f 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.cpp +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -20,9 +20,9 @@ * */ -#include "gfx/bitmap.h" -#include "gfx/gfxfilter_hqx.h" -#include "gfx/hq2x3x.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/gfxfilter_hqx.h" +#include "ags/shared/gfx/hq2x3x.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h index 232e18052084..8cc897357f59 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.h +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_HQ2XGFXFILTER_H #define AGS_ENGINE_GFX_HQ2XGFXFILTER_H -#include "gfx/gfxfilter_allegro.h" +#include "ags/shared/gfx/gfxfilter_allegro.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.cpp b/engines/ags/engine/gfx/gfxfilter_ogl.cpp index 9d480c0de5d3..3615d025b18d 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_ogl.cpp @@ -20,12 +20,12 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX -#include "gfx/gfxfilter_ogl.h" -#include "ogl_headers.h" +#include "ags/shared/gfx/gfxfilter_ogl.h" +#include "ags/shared/ogl_headers.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.h b/engines/ags/engine/gfx/gfxfilter_ogl.h index 863dc0a5e57d..786dba62c2ca 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.h +++ b/engines/ags/engine/gfx/gfxfilter_ogl.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_OGLGFXFILTER_H #define AGS_ENGINE_GFX_OGLGFXFILTER_H -#include "gfx/gfxfilter_scaling.h" +#include "ags/shared/gfx/gfxfilter_scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.cpp b/engines/ags/engine/gfx/gfxfilter_scaling.cpp index 7b013e1309aa..71cbb5af3b50 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.cpp +++ b/engines/ags/engine/gfx/gfxfilter_scaling.cpp @@ -20,7 +20,7 @@ * */ -#include "gfx/gfxfilter_scaling.h" +#include "ags/shared/gfx/gfxfilter_scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.h b/engines/ags/engine/gfx/gfxfilter_scaling.h index f6be6a172955..52f420979e6c 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.h +++ b/engines/ags/engine/gfx/gfxfilter_scaling.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_GFX_SCALINGGFXFILTER_H #define AGS_ENGINE_GFX_SCALINGGFXFILTER_H -#include "gfx/gfxfilter.h" -#include "util/scaling.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/util/scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxmodelist.h b/engines/ags/engine/gfx/gfxmodelist.h index 718ea5ce4fc8..c49c1a1e5229 100644 --- a/engines/ags/engine/gfx/gfxmodelist.h +++ b/engines/ags/engine/gfx/gfxmodelist.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_GFX_GFXMODELIST_H #define AGS_ENGINE_GFX_GFXMODELIST_H -#include "core/types.h" -#include "gfx/gfxdefines.h" +#include "ags/shared/core/types.h" +#include "ags/engine/gfx/gfxdefines.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h index 4af864a39bd8..1024addc128f 100644 --- a/engines/ags/engine/gfx/graphicsdriver.h +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -29,17 +29,17 @@ #ifndef AGS_ENGINE_GFX_GRAPHICSDRIVER_H #define AGS_ENGINE_GFX_GRAPHICSDRIVER_H -#include -#include "gfx/gfxdefines.h" -#include "gfx/gfxmodelist.h" -#include "util/geometry.h" +#include "ags/std/memory.h" +#include "ags/engine/gfx/gfxdefines.h" +#include "ags/engine/gfx/gfxmodelist.h" +#include "ags/shared/util/geometry.h" namespace AGS3 { namespace AGS { namespace Shared { class Bitmap; -typedef std::shared_ptr PBitmap; +typedef std::shared_ptr PBitmap; } // namespace Shared namespace Engine { @@ -48,7 +48,7 @@ namespace Engine { class IDriverDependantBitmap; class IGfxFilter; typedef std::shared_ptr PGfxFilter; -using Common::PBitmap; +using Shared::PBitmap; enum TintMethod { TintReColourise = 0, @@ -124,8 +124,8 @@ class IGraphicsDriver { // Gets closest recommended bitmap format (currently - only color depth) for the given original format. // Engine needs to have game bitmaps brought to the certain range of formats, easing conversion into the video bitmaps. virtual int GetCompatibleBitmapFormat(int color_depth) = 0; - virtual IDriverDependantBitmap *CreateDDBFromBitmap(Common::Bitmap *bitmap, bool hasAlpha, bool opaque = false) = 0; - virtual void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Common::Bitmap *bitmap, bool hasAlpha) = 0; + virtual IDriverDependantBitmap *CreateDDBFromBitmap(Shared::Bitmap *bitmap, bool hasAlpha, bool opaque = false) = 0; + virtual void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Shared::Bitmap *bitmap, bool hasAlpha) = 0; virtual void DestroyDDB(IDriverDependantBitmap *bitmap) = 0; // Prepares next sprite batch, a list of sprites with defined viewport and optional @@ -151,7 +151,7 @@ class IGraphicsDriver { // Copies contents of the game screen into bitmap using simple blit or pixel copy. // Bitmap must be of supported size and pixel format. If it's not the method will // fail and optionally write wanted destination format into 'want_fmt' pointer. - virtual bool GetCopyOfScreenIntoBitmap(Common::Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt = nullptr) = 0; + virtual bool GetCopyOfScreenIntoBitmap(Shared::Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt = nullptr) = 0; virtual void EnableVsyncBeforeRender(bool enabled) = 0; virtual void Vsync() = 0; // Enables or disables rendering mode that draws sprite list directly into @@ -178,14 +178,14 @@ class IGraphicsDriver { virtual void SetGamma(int newGamma) = 0; // Returns the virtual screen. Will return NULL if renderer does not support memory backbuffer. // In normal case you should use GetStageBackBuffer() instead. - virtual Common::Bitmap *GetMemoryBackBuffer() = 0; + virtual Shared::Bitmap *GetMemoryBackBuffer() = 0; // Sets custom backbuffer bitmap to render to. // Passing NULL pointer will tell renderer to switch back to its original virtual screen. // Note that only software renderer supports this. - virtual void SetMemoryBackBuffer(Common::Bitmap *backBuffer) = 0; + virtual void SetMemoryBackBuffer(Shared::Bitmap *backBuffer) = 0; // Returns memory backbuffer for the current rendering stage (or base virtual screen if called outside of render pass). // All renderers should support this. - virtual Common::Bitmap *GetStageBackBuffer() = 0; + virtual Shared::Bitmap *GetStageBackBuffer() = 0; virtual bool RequiresFullRedrawEachFrame() = 0; virtual bool HasAcceleratedTransform() = 0; virtual bool UsesMemoryBackBuffer() = 0; diff --git a/engines/ags/engine/gfx/hq2x3x.h b/engines/ags/engine/gfx/hq2x3x.h index 4d679e86f2dd..ff6a962274a7 100644 --- a/engines/ags/engine/gfx/hq2x3x.h +++ b/engines/ags/engine/gfx/hq2x3x.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GFX_HQ2X3X_H #define AGS_ENGINE_GFX_HQ2X3X_H -#include "core/platform.h" +#include "ags/shared/core/platform.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/ogl_headers.h b/engines/ags/engine/gfx/ogl_headers.h index b4f3c2f2228e..6fa7e481b824 100644 --- a/engines/ags/engine/gfx/ogl_headers.h +++ b/engines/ags/engine/gfx/ogl_headers.h @@ -26,35 +26,35 @@ // //============================================================================= -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS #include "ags/lib/allegro.h" -#include -#include +//include +//include -#include "glad/glad.h" -#include "glad/glad_wgl.h" +#include "ags/shared/glad/glad.h" +#include "ags/shared/glad/glad_wgl.h" #elif AGS_PLATFORM_OS_LINUX #include "ags/lib/allegro.h" -#include -#include +//include +//include -#include "glad/glad.h" -#include "glad/glad_glx.h" +#include "ags/shared/glad/glad.h" +#include "ags/shared/glad/glad_glx.h" #elif AGS_PLATFORM_OS_ANDROID -#include -#include +//include +//include #ifndef GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES #endif // TODO: we probably should not use GLExt since we use GLES2 -#include +//include #define HDC void* #define HGLRC void* @@ -63,14 +63,14 @@ #elif AGS_PLATFORM_OS_IOS -#include -#include +//include +//include #ifndef GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES #endif -#include +//include #define HDC void* #define HGLRC void* diff --git a/engines/ags/engine/gui/animatingguibutton.cpp b/engines/ags/engine/gui/animatingguibutton.cpp index bac2621ab418..8534a9ced2cc 100644 --- a/engines/ags/engine/gui/animatingguibutton.cpp +++ b/engines/ags/engine/gui/animatingguibutton.cpp @@ -20,8 +20,8 @@ * */ -#include "gui/animatingguibutton.h" -#include "util/stream.h" +#include "ags/shared/gui/animatingguibutton.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h index f0610f8d62da..4fcaacadd921 100644 --- a/engines/ags/engine/gui/animatingguibutton.h +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_ANIMATINGGUIBUTTON_H #define AGS_ENGINE_GUI_ANIMATINGGUIBUTTON_H -#include "ac/runtime_defines.h" +#include "ags/engine/ac/runtime_defines.h" namespace AGS3 { @@ -42,8 +42,8 @@ struct AnimatingGUIButton { short view, loop, frame; short speed, repeat, wait; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); }; } // namespace AGS3 diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index 9dc7a079d3ea..89929fb4ed93 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -20,28 +20,28 @@ * */ -#include -#include "util/wgt2allg.h" -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/gamesetup.h" -#include "ac/gamestate.h" -#include "ac/gui.h" -#include "ac/keycode.h" -#include "ac/mouse.h" -#include "ac/sys_events.h" -#include "ac/runtime_defines.h" -#include "font/fonts.h" -#include "gui/cscidialog.h" -#include "gui/guidialog.h" -#include "gui/guimain.h" -#include "gui/mycontrols.h" -#include "main/game_run.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" -#include "media/audio/audio_system.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/timer.h" +//include +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/gui.h" +#include "ags/shared/ac/keycode.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/cscidialog.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/mycontrols.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h index 47d5c6327d23..05b5057b9015 100644 --- a/engines/ags/engine/gui/cscidialog.h +++ b/engines/ags/engine/gui/cscidialog.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GUI_CSCIDIALOG_H #define AGS_ENGINE_GUI_CSCIDIALOG_H -#include "gui/guidialoginternaldefs.h" +#include "ags/shared/gui/guidialoginternaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp index c5a7e1b6509b..1644445c469e 100644 --- a/engines/ags/engine/gui/gui_engine.cpp +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -28,21 +28,21 @@ // Headers, as they are in acgui.cpp #pragma unmanaged -#include "ac/game_version.h" -#include "ac/system.h" -#include "font/fonts.h" -#include "gui/guimain.h" -#include "gui/guibutton.h" -#include "gui/guilabel.h" -#include "gui/guilistbox.h" -#include "gui/guitextbox.h" -#include -#include "ac/gamesetupstruct.h" -#include "ac/global_translation.h" -#include "ac/string.h" -#include "ac/spritecache.h" -#include "gfx/bitmap.h" -#include "gfx/blender.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/shared/gui/guilistbox.h" +#include "ags/shared/gui/guitextbox.h" +//include +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_translation.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/blender.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index b793a689ca29..261a43e17de6 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -20,19 +20,19 @@ * */ -#include -#include "gui/guidialog.h" - -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "gui/cscidialog.h" -#include //isdigit() -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" -#include "debug/debug_log.h" +//include +#include "ags/shared/gui/guidialog.h" + +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/gui/cscidialog.h" +//include //isdigit() +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/debug/debug_log.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h index 3b92cf62e8e9..45404757b37a 100644 --- a/engines/ags/engine/gui/guidialogdefines.h +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_GUIDIALOGDEFINES_H #define AGS_ENGINE_GUI_GUIDIALOGDEFINES_H -#include "ac/gamesetup.h" +#include "ags/shared/ac/gamesetup.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/guidialoginternaldefs.h b/engines/ags/engine/gui/guidialoginternaldefs.h index fd4e0777f8c3..22c53733178d 100644 --- a/engines/ags/engine/gui/guidialoginternaldefs.h +++ b/engines/ags/engine/gui/guidialoginternaldefs.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_GUIDIALOGINTERNALDEFS_H #define AGS_ENGINE_GUI_GUIDIALOGINTERNALDEFS_H -#include "gui/guidialogdefines.h" +#include "ags/shared/gui/guidialogdefines.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mycontrols.h b/engines/ags/engine/gui/mycontrols.h index d0fd99a8086b..5a1abee69459 100644 --- a/engines/ags/engine/gui/mycontrols.h +++ b/engines/ags/engine/gui/mycontrols.h @@ -29,9 +29,9 @@ #ifndef AGS_ENGINE_GUI_MYCONTROLS_H #define AGS_ENGINE_GUI_MYCONTROLS_H -#include "gui/mylabel.h" -#include "gui/mylistbox.h" -#include "gui/mypushbutton.h" -#include "gui/mytextbox.h" +#include "ags/shared/gui/mylabel.h" +#include "ags/shared/gui/mylistbox.h" +#include "ags/shared/gui/mypushbutton.h" +#include "ags/shared/gui/mytextbox.h" #endif diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp index 74bd80ab2ac4..8af6ee072986 100644 --- a/engines/ags/engine/gui/mylabel.cpp +++ b/engines/ags/engine/gui/mylabel.cpp @@ -20,14 +20,14 @@ * */ -#include -#include "ac/display.h" -#include "ac/gamesetup.h" -#include "ac/string.h" -#include "font/fonts.h" -#include "gui/guidefines.h" -#include "gui/mylabel.h" -#include "gui/guidialoginternaldefs.h" +//include +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/guidefines.h" +#include "ags/shared/gui/mylabel.h" +#include "ags/shared/gui/guidialoginternaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h index cb4905cd0bca..b0b5ec733e1f 100644 --- a/engines/ags/engine/gui/mylabel.h +++ b/engines/ags/engine/gui/mylabel.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_MYLABEL_H #define AGS_ENGINE_GUI_MYLABEL_H -#include "gui/newcontrol.h" +#include "ags/shared/gui/newcontrol.h" namespace AGS3 { @@ -31,7 +31,7 @@ struct MyLabel : public NewControl { char text[150]; MyLabel(int xx, int yy, int wii, const char *tee); - void draw(Common::Bitmap *ds) override; + void draw(Shared::Bitmap *ds) override; int pressedon(int mousex, int mousey) override; diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index 37d24a4dbea7..07e6ec1951dc 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -20,15 +20,15 @@ * */ -#include -#include "util/wgt2allg.h" -#include "ac/common.h" -#include "ac/gamesetup.h" -#include "font/fonts.h" -#include "gfx/bitmap.h" -#include "gui/guidialog.h" -#include "gui/guidialoginternaldefs.h" -#include "gui/mylistbox.h" +//include +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/gui/guidialoginternaldefs.h" +#include "ags/shared/gui/mylistbox.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h index 128447bcc07c..4c54e317fa7d 100644 --- a/engines/ags/engine/gui/mylistbox.h +++ b/engines/ags/engine/gui/mylistbox.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_MYLISTBOX_H #define AGS_ENGINE_GUI_MYLISTBOX_H -#include "gui/newcontrol.h" +#include "ags/shared/gui/newcontrol.h" namespace AGS3 { @@ -37,7 +37,7 @@ struct MyListBox : public NewControl { void clearlist(); ~MyListBox() override; - void draw(Common::Bitmap *ds) override; + void draw(Shared::Bitmap *ds) override; int pressedon(int mousex, int mousey) override; void additem(char *texx); int processmessage(int mcode, int wParam, long lParam) override; diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index 77e68a829b46..6cdf81386be1 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -20,18 +20,18 @@ * */ -#include -#include "util/wgt2allg.h" -#include "ac/common.h" -#include "ac/mouse.h" -#include "font/fonts.h" -#include "gui/mypushbutton.h" -#include "gui/guidialog.h" -#include "gui/guidialoginternaldefs.h" -#include "main/game_run.h" -#include "gfx/bitmap.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/timer.h" +//include +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/mypushbutton.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/gui/guidialoginternaldefs.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h index a1870bcc223b..55696560211f 100644 --- a/engines/ags/engine/gui/mypushbutton.h +++ b/engines/ags/engine/gui/mypushbutton.h @@ -23,14 +23,14 @@ #ifndef AGS_ENGINE_GUI_PUSHBUTTON_H #define AGS_ENGINE_GUI_PUSHBUTTON_H -#include "gui/newcontrol.h" +#include "ags/shared/gui/newcontrol.h" namespace AGS3 { struct MyPushButton : public NewControl { char text[50]; MyPushButton(int xx, int yy, int wi, int hi, const char *tex); - void draw(Common::Bitmap *ds) override; + void draw(Shared::Bitmap *ds) override; int pressedon(int mousex, int mousey) override; int processmessage(int mcode, int wParam, long lParam) override; }; diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp index 74e740bc84bb..898e8d7432b1 100644 --- a/engines/ags/engine/gui/mytextbox.cpp +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -20,12 +20,12 @@ * */ -#include -#include "util/wgt2allg.h" -#include "font/fonts.h" -#include "gui/mytextbox.h" -#include "gui/guidialoginternaldefs.h" -#include "gfx/bitmap.h" +//include +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/gui/mytextbox.h" +#include "ags/shared/gui/guidialoginternaldefs.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h index 3a69094d4a10..46f9e7728baa 100644 --- a/engines/ags/engine/gui/mytextbox.h +++ b/engines/ags/engine/gui/mytextbox.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_MYTEXTBOX_H #define AGS_ENGINE_GUI_MYTEXTBOX_H -#include "gui/newcontrol.h" +#include "ags/shared/gui/newcontrol.h" namespace AGS3 { @@ -31,7 +31,7 @@ namespace AGS3 { struct MyTextBox : public NewControl { char text[TEXTBOX_MAXLEN + 1]; MyTextBox(int xx, int yy, int wii, const char *tee); - void draw(Common::Bitmap *ds) override; + void draw(Shared::Bitmap *ds) override; int pressedon(int mousex, int mousey) override; int processmessage(int mcode, int wParam, long lParam) override; }; diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp index cdc052d11489..6337fddbce6d 100644 --- a/engines/ags/engine/gui/newcontrol.cpp +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -20,9 +20,9 @@ * */ -#include "gui/newcontrol.h" -#include "gui/guidialog.h" -#include "gui/guidialoginternaldefs.h" +#include "ags/shared/gui/newcontrol.h" +#include "ags/shared/gui/guidialog.h" +#include "ags/shared/gui/guidialoginternaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/newcontrol.h b/engines/ags/engine/gui/newcontrol.h index 690e93a0e95e..cfb19f128c26 100644 --- a/engines/ags/engine/gui/newcontrol.h +++ b/engines/ags/engine/gui/newcontrol.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_NEWCONTROL_H #define AGS_ENGINE_GUI_NEWCONTROL_H -#include "gfx/bitmap.h" +#include "ags/shared/gfx/bitmap.h" namespace AGS3 { @@ -33,7 +33,7 @@ struct NewControl { int x, y, wid, hit, state, typeandflags, wlevel; char visible, enabled; // not implemented char needredraw; - virtual void draw(Common::Bitmap *ds) = 0; + virtual void draw(Shared::Bitmap *ds) = 0; virtual int pressedon(int mousex, int mousey) = 0; virtual int processmessage(int, int, long) = 0; diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 58949bf10aad..d2095f1b290d 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -23,27 +23,27 @@ // // Game configuration // -#include // toupper - -#include "core/platform.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_translation.h" -#include "ac/path_helper.h" -#include "ac/spritecache.h" -#include "ac/system.h" -#include "debug/debugger.h" -#include "debug/debug_log.h" -#include "main/mainheader.h" -#include "main/config.h" -#include "platform/base/agsplatformdriver.h" -#include "util/directory.h" -#include "util/ini_util.h" -#include "util/textstreamreader.h" -#include "util/path.h" -#include "util/string_utils.h" -#include "media/audio/audio_system.h" +//include // toupper + +#include "ags/shared/core/platform.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/main/config.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/ini_util.h" +#include "ags/shared/util/textstreamreader.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/string_utils.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { @@ -85,9 +85,9 @@ void INIgetdirec(char *wasgv, const char *inifil) { bool INIreaditem(const ConfigTree &cfg, const String §n, const String &item, String &value) { ConfigNode sec_it = cfg.find(sectn); if (sec_it != cfg.end()) { - StrStrOIter item_it = sec_it->second.find(item); - if (item_it != sec_it->second.end()) { - value = item_it->second; + StrStrOIter item_it = sec_it->_value.find(item); + if (item_it != sec_it->_value.end()) { + value = item_it->_value; return true; } } @@ -272,7 +272,7 @@ void graphics_mode_get_defaults(bool windowed, ScreenSizeSetup &scsz_setup, Game String find_default_cfg_file(const char *alt_cfg_file) { // Try current directory for config first; else try exe dir String filename = String::FromFormat("%s/%s", Directory::GetCurrentDirectory().GetCStr(), DefaultConfigFileName.GetCStr()); - if (!Common::File::TestReadFile(filename)) { + if (!Shared::File::TestReadFile(filename)) { char conffilebuf[512]; strcpy(conffilebuf, alt_cfg_file); fix_filename_case(conffilebuf); diff --git a/engines/ags/engine/main/config.h b/engines/ags/engine/main/config.h index 62ff8c98fb3c..9c9c10ec6ebf 100644 --- a/engines/ags/engine/main/config.h +++ b/engines/ags/engine/main/config.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MAIN_CONFIG_H #define AGS_ENGINE_MAIN_CONFIG_H -#include "main/graphics_mode.h" -#include "util/ini_util.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/shared/util/ini_util.h" namespace AGS3 { diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 31cf7bca1a45..516483f3baa9 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -24,60 +24,63 @@ // Engine initialization // -#include "core/platform.h" +#include "ags/shared/core/platform.h" -#include +//include #if AGS_PLATFORM_OS_WINDOWS -#include // _spawnl +//include // _spawnl #endif -#include "main/mainheader.h" -#include "ac/asset_helper.h" -#include "ac/common.h" -#include "ac/character.h" -#include "ac/characterextras.h" -#include "ac/characterinfo.h" -#include "ac/draw.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_character.h" -#include "ac/global_game.h" -#include "ac/gui.h" -#include "ac/lipsync.h" -#include "ac/objectcache.h" -#include "ac/path_helper.h" -#include "ac/sys_events.h" -#include "ac/roomstatus.h" -#include "ac/speech.h" -#include "ac/spritecache.h" -#include "ac/translation.h" -#include "ac/viewframe.h" -#include "ac/dynobj/scriptobject.h" -#include "ac/dynobj/scriptsystem.h" -#include "core/assetmanager.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "debug/out.h" -#include "font/agsfontrenderer.h" -#include "font/fonts.h" -#include "gfx/graphicsdriver.h" -#include "gfx/gfxdriverfactory.h" -#include "gfx/ddb.h" -#include "main/config.h" -#include "main/game_file.h" -#include "main/game_start.h" -#include "main/engine.h" -#include "main/engine_setup.h" -#include "main/graphics_mode.h" -#include "main/main.h" -#include "main/main_allegro.h" -#include "media/audio/audio_system.h" -#include "platform/util/pe.h" -#include "util/directory.h" -#include "util/error.h" -#include "util/misc.h" -#include "util/path.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/ac/asset_helper.h" +#include "ags/shared/ac/common.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/characterextras.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/lipsync.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/speech.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/engine/ac/translation.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/ac/dynobj/scriptobject.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/font/agsfontrenderer.h" +#include "ags/shared/font/fonts.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/gfx/gfxdriverfactory.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/main/config.h" +#include "ags/engine/main/game_file.h" +#include "ags/engine/main/game_start.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/engine_setup.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/main/main.h" +#include "ags/engine/main/main_allegro.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/platform/util/pe.h" +#include "ags/shared/gfx/image.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/error.h" +#include "ags/shared/util/misc.h" +#include "ags/shared/util/path.h" +#include "ags/ags.h" +#include "common/fs.h" namespace AGS3 { @@ -122,7 +125,7 @@ bool engine_init_allegro() { our_eip = -199; // Initialize allegro set_uformat(U_ASCII); - if (install_allegro(SYSTEM_AUTODETECT, &errno, atexit)) { + if (install_allegro()) { const char *al_err = get_allegro_error(); const char *user_hint = platform->GetAllegroFailUserHint(); platform->DisplayAlert("Unable to initialize Allegro system driver.\n%s\n\n%s", @@ -150,7 +153,7 @@ void engine_setup_window() { Debug::Printf(kDbgMsg_Info, "Setting up window"); our_eip = -198; - set_window_title("Adventure Game Studio"); + //set_window_title("Adventure Game Studio"); set_close_button_callback(winclosehook); our_eip = -197; @@ -208,44 +211,44 @@ void engine_force_window() { } String find_game_data_in_directory(const String &path) { - al_ffblk ff; - String test_file; + Common::String test_file; String first_nonstd_fn; - String pattern = path; - pattern.Append("/*"); - - if (al_findfirst(pattern, &ff, FA_ALL & ~(FA_DIREC)) != 0) - return ""; - // Select first found data file; files with standart names (*.ags) have - // higher priority over files with custom names. - do { - test_file = ff.name; - // Add a bit of sanity and do not parse contents of the 10k-files-large - // digital sound libraries. - // NOTE: we could certainly benefit from any kind of flag in file lib - // that would tell us this is the main lib without extra parsing. - if (test_file.CompareRightNoCase(".vox") == 0) - continue; - - // *.ags is a standart cross-platform file pattern for AGS games, - // ac2game.dat is a legacy file name for very old games, - // *.exe is a MS Win executable; it is included to this case because - // users often run AGS ports with Windows versions of games. - bool is_std_name = test_file.CompareRightNoCase(".ags") == 0 || - test_file.CompareNoCase("ac2game.dat") == 0 || - test_file.CompareRightNoCase(".exe") == 0; - if (is_std_name || first_nonstd_fn.IsEmpty()) { - test_file.Format("%s/%s", path.GetCStr(), ff.name); - if (IsMainGameLibrary(test_file)) { - if (is_std_name) { - al_findclose(&ff); - return test_file; - } else - first_nonstd_fn = test_file; + + Common::FSNode folder(path); + Common::FSList files; + if (folder.getChildren(files, Common::FSNode::kListFilesOnly)) { + // Select first found data file; files with standart names (*.ags) have + // higher priority over files with custom names. + for (Common::FSList::iterator it = files.begin(); it != files.end(); ++it) { + test_file = it->getName(); + + // Add a bit of sanity and do not parse contents of the 10k-files-large + // digital sound libraries. + // NOTE: we could certainly benefit from any kind of flag in file lib + // that would tell us this is the main lib without extra parsing. + if (test_file.hasSuffixIgnoreCase(".vox")) + continue; + + // *.ags is a standart cross-platform file pattern for AGS games, + // ac2game.dat is a legacy file name for very old games, + // *.exe is a MS Win executable; it is included to this case because + // users often run AGS ports with Windows versions of games. + bool is_std_name = test_file.hasSuffixIgnoreCase(".ags") || + test_file.equalsIgnoreCase("ac2game.dat") || + test_file.hasSuffixIgnoreCase(".exe"); + if (is_std_name || first_nonstd_fn.IsEmpty()) { + test_file = it->getName(); + + if (IsMainGameLibrary(test_file)) { + if (is_std_name) { + return test_file; + } else + first_nonstd_fn = test_file; + } } } - } while (al_findnext(&ff) == 0); - al_findclose(&ff); + } + return first_nonstd_fn; } @@ -271,7 +274,7 @@ bool search_for_game_data_file(String &filename, String &search_path) { // // this will use argument zero, the executable's name filename = GetPathFromCmdArg(0); - if (filename.IsEmpty() || !Common::AssetManager::IsDataFile(filename)) { + if (filename.IsEmpty() || !Shared::AssetManager::IsDataFile(filename)) { // 3.2 Look in current directory search_path = Directory::GetCurrentDirectory(); filename = find_game_data_in_directory(search_path); @@ -329,7 +332,7 @@ void engine_locate_speech_pak() { String speech_filepath = find_assetlib(speech_file); if (!speech_filepath.IsEmpty()) { Debug::Printf("Initializing speech vox"); - if (AssetManager::SetDataFile(speech_filepath) != Common::kAssetNoError) { + if (AssetManager::SetDataFile(speech_filepath) != Shared::kAssetNoError) { platform->DisplayAlert("Unable to read voice pack, file could be corrupted or of unknown format.\nSpeech voice-over will be disabled."); AssetManager::SetDataFile(ResPaths.GamePak.Path); // switch back to the main data pack return; @@ -393,7 +396,7 @@ void engine_init_keyboard() { install_keyboard(); #endif #if AGS_PLATFORM_OS_LINUX - setlocale(LC_NUMERIC, "C"); // needed in X platform because install keyboard affects locale of printfs +// setlocale(LC_NUMERIC, "C"); // needed in X platform because install keyboard affects locale of printfs #endif } @@ -567,8 +570,8 @@ void engine_init_exit_handler() { } void engine_init_rand() { - play.randseed = time(nullptr); - srand(play.randseed); + play.randseed = g_system->getMillis(); + ::AGS::g_vm->setRandomNumberSeed(play.randseed); } void engine_init_pathfinder() { @@ -612,7 +615,7 @@ int engine_check_register_game() { void engine_init_title() { our_eip = -91; - set_window_title(game.gamename); + ::AGS::g_vm->set_window_title(game.gamename); Debug::Printf(kDbgMsg_Info, "Game title: '%s'", game.gamename); } @@ -631,7 +634,7 @@ void engine_init_directories() { ResPaths.DataDir = usetup.data_files_dir; ResPaths.GamePak.Path = usetup.main_data_filepath; - ResPaths.GamePak.Name = get_filename(usetup.main_data_filepath); + ResPaths.GamePak.Name = Shared::Path::get_filename(usetup.main_data_filepath); set_install_dir(usetup.install_dir, usetup.install_audio_dir, usetup.install_voice_dir); if (!usetup.install_dir.IsEmpty()) { @@ -671,14 +674,14 @@ int check_write_access() { // The Save Game Dir is the only place that we should write to String svg_dir = get_save_game_directory(); String tempPath = String::FromFormat("%s""tmptest.tmp", svg_dir.GetCStr()); - Stream *temp_s = Common::File::CreateFile(tempPath); + Stream *temp_s = Shared::File::CreateFile(tempPath); if (!temp_s) // TODO: move this somewhere else (Android platform driver init?) #if AGS_PLATFORM_OS_ANDROID { - put_backslash(android_base_directory); +// put_backslash(android_base_directory); tempPath.Format("%s""tmptest.tmp", android_base_directory); - temp_s = Common::File::CreateFile(tempPath); + temp_s = Shared::File::CreateFile(tempPath); if (temp_s == NULL) return 0; else SetCustomSaveParent(android_base_directory); } @@ -1154,7 +1157,7 @@ bool define_gamedata_location(const String &exe_path) { // On success: set all the necessary path and filename settings, // derive missing ones from available. if (usetup.main_data_filename.IsEmpty()) { - usetup.main_data_filename = get_filename(usetup.main_data_filepath); + usetup.main_data_filename = Shared::Path::get_filename(usetup.main_data_filepath); } else if (usetup.main_data_filepath.IsEmpty()) { if (usetup.data_files_dir.IsEmpty() || !is_relative_filename(usetup.main_data_filename)) usetup.main_data_filepath = usetup.main_data_filename; @@ -1221,8 +1224,8 @@ void engine_prepare_config(ConfigTree &cfg, const String &exe_path, const Config engine_read_config(exe_path, cfg); // Merge startup options in for (const auto §n : startup_opts) - for (const auto &opt : sectn.second) - cfg[sectn.first][opt.first] = opt.second; + for (const auto &opt : sectn._value) + cfg[sectn._key][opt._key] = opt._value; // Add "meta" config settings to let setup application(s) // display correct properties to the user @@ -1278,9 +1281,9 @@ static void engine_print_info(const std::set &keys, const String &exe_pa } if ((all || keys.count("config") > 0) && user_cfg) { for (const auto §n : *user_cfg) { - String cfg_sectn = String::FromFormat("config@%s", sectn.first.GetCStr()); - for (const auto &opt : sectn.second) - data[cfg_sectn][opt.first] = opt.second; + String cfg_sectn = String::FromFormat("config@%s", sectn._key.GetCStr()); + for (const auto &opt : sectn._value) + data[cfg_sectn][opt._key] = opt._value; } } if (all || keys.count("data") > 0) { diff --git a/engines/ags/engine/main/engine.h b/engines/ags/engine/main/engine.h index d27e4fe89d02..f08af9fa999b 100644 --- a/engines/ags/engine/main/engine.h +++ b/engines/ags/engine/main/engine.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MAIN_ENGINE_H #define AGS_ENGINE_MAIN_ENGINE_H -#include "util/ini_util.h" +#include "ags/shared/util/ini_util.h" namespace AGS3 { diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp index 9168a24f7dac..72a46c96c67b 100644 --- a/engines/ags/engine/main/engine_setup.cpp +++ b/engines/ags/engine/main/engine_setup.cpp @@ -20,29 +20,29 @@ * */ -#include "core/platform.h" -#include "ac/common.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/game_version.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/mouse.h" -#include "ac/runtime_defines.h" -#include "ac/walkbehind.h" -#include "ac/dynobj/scriptsystem.h" -#include "debug/out.h" -#include "device/mousew32.h" -#include "font/fonts.h" -#include "gfx/ali3dexception.h" -#include "gfx/graphicsdriver.h" -#include "gui/guimain.h" -#include "gui/guiinv.h" -#include "main/graphics_mode.h" -#include "main/engine_setup.h" -#include "media/video/video.h" -#include "platform/base/agsplatformdriver.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/ac/common.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/shared/ac/game_version.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/walkbehind.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/device/mousew32.h" +#include "ags/shared/font/fonts.h" +#include "ags/engine/gfx/ali3dexception.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/main/engine_setup.h" +#include "ags/engine/media/video/video.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/main/engine_setup.h b/engines/ags/engine/main/engine_setup.h index feca62e0ef03..cc2039811498 100644 --- a/engines/ags/engine/main/engine_setup.h +++ b/engines/ags/engine/main/engine_setup.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MAIN_ENGINESETUP_H #define AGS_ENGINE_MAIN_ENGINESETUP_H -#include "util/geometry.h" -#include "gfx/gfxdefines.h" +#include "ags/shared/util/geometry.h" +#include "ags/engine/gfx/gfxdefines.h" namespace AGS3 { diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp index a1590ca03624..545ef80b75f3 100644 --- a/engines/ags/engine/main/game_file.cpp +++ b/engines/ags/engine/main/game_file.cpp @@ -24,34 +24,34 @@ // Game data file management // -#include "main/mainheader.h" -#include "main/game_file.h" -#include "ac/common.h" -#include "ac/character.h" -#include "ac/charactercache.h" -#include "ac/dialogtopic.h" -#include "ac/draw.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/gamestructdefines.h" -#include "ac/gui.h" -#include "ac/viewframe.h" -#include "debug/debug_log.h" -#include "debug/out.h" -#include "gui/guilabel.h" -#include "main/main.h" -#include "platform/base/agsplatformdriver.h" -#include "util/stream.h" -#include "gfx/bitmap.h" -#include "gfx/blender.h" -#include "core/assetmanager.h" -#include "util/alignedstream.h" -#include "ac/gamesetup.h" -#include "game/main_game_file.h" -#include "game/game_init.h" -#include "plugin/agsplugin.h" -#include "script/script.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/main/game_file.h" +#include "ags/shared/ac/common.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/shared/ac/dialogtopic.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/shared/ac/gamestructdefines.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/gui/guilabel.h" +#include "ags/engine/main/main.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/engine/gfx/blender.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/shared/game/main_game_file.h" +#include "ags/engine/game/game_init.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/script/script.h" namespace AGS3 { @@ -72,7 +72,7 @@ extern int numScriptModules; bool test_game_caps(const std::set &caps, std::set &failed_caps) { // Currently we support nothing special failed_caps = caps; - return caps.size() == 0; + return caps.empty(); } // Forms a simple list of capability names @@ -97,7 +97,7 @@ HGameFileError game_file_first_open(MainGameSource &src) { Debug::Printf(kDbgMsg_Info, "Opened game data file: %s", src.Filename.GetCStr()); Debug::Printf(kDbgMsg_Info, "Game data version: %d", src.DataVersion); Debug::Printf(kDbgMsg_Info, "Compiled with: %s", src.CompiledWith.GetCStr()); - if (src.Caps.size() > 0) { + if (!src.Caps.empty()) { String caps_list = get_caps_list(src.Caps); Debug::Printf(kDbgMsg_Info, "Requested engine caps: %s", caps_list.GetCStr()); } @@ -116,7 +116,7 @@ HGameFileError game_file_first_open(MainGameSource &src) { } void PreReadSaveFileInfo(Stream *in, GameDataVersion data_ver) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); game.ReadFromFile(&align_s); // Discard game messages we do not need here delete[] game.load_messages; diff --git a/engines/ags/engine/main/game_file.h b/engines/ags/engine/main/game_file.h index d1487c9a648a..9a9f81827907 100644 --- a/engines/ags/engine/main/game_file.h +++ b/engines/ags/engine/main/game_file.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MAIN_GAMEFILE_H #define AGS_ENGINE_MAIN_GAMEFILE_H -#include "util/error.h" -#include "util/string.h" +#include "ags/shared/util/error.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 63816c8cbe76..d6ae72515269 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -24,47 +24,48 @@ // Game loop // -#include -#include -#include "ac/common.h" -#include "ac/characterextras.h" -#include "ac/characterinfo.h" -#include "ac/draw.h" -#include "ac/event.h" -#include "ac/game.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_debug.h" -#include "ac/global_display.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/global_region.h" -#include "ac/gui.h" -#include "ac/hotspot.h" -#include "ac/keycode.h" -#include "ac/mouse.h" -#include "ac/overlay.h" -#include "ac/sys_events.h" -#include "ac/room.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "debug/debugger.h" -#include "debug/debug_log.h" -#include "gui/guiinv.h" -#include "gui/guimain.h" -#include "gui/guitextbox.h" -#include "main/mainheader.h" -#include "main/engine.h" -#include "main/game_run.h" -#include "main/update.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "script/script.h" -#include "ac/spritecache.h" -#include "media/audio/audio_system.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/timer.h" -#include "ac/keycode.h" +#include "ags/std/limits.h" +#include "ags/std/chrono.h" +#include "ags/shared/ac/common.h" +#include "ags/engine/ac/characterextras.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/global_debug.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_region.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/hotspot.h" +#include "ags/engine/ac/keycode.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/shared/gui/guiinv.h" +#include "ags/shared/gui/guimain.h" +#include "ags/shared/gui/guitextbox.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/main/update.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" +#include "ags/engine/script/script.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/timer.h" +#include "ags/engine/ac/keycode.h" +#include "ags/lib/allegro/keyboard.h" namespace AGS3 { diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 244f007a35b4..df57f42753ca 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -24,25 +24,26 @@ // Game initialization // -#include "ac/common.h" -#include "ac/characterinfo.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_game.h" -#include "ac/mouse.h" -#include "ac/room.h" -#include "ac/screen.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "debug/out.h" -#include "gfx/ali3dexception.h" -#include "main/mainheader.h" -#include "main/game_run.h" -#include "main/game_start.h" -#include "script/script.h" -#include "media/audio/audio_system.h" -#include "ac/timer.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/characterinfo.h" +#include "ags/engine/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/screen.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/gfx/ali3dexception.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/main/game_start.h" +#include "ags/engine/script/script.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/timer.h" +#include "ags/ags.h" namespace AGS3 { @@ -123,7 +124,7 @@ void do_start_game() { start_game(); } -void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup) { +void initialize_start_and_play_game(int override_start_room, const char *loadSaveOnStartup) { try { // BEGIN try for ALI3DEXception set_cursor_mode(MODE_WALK); @@ -138,7 +139,7 @@ void initialize_start_and_play_game(int override_start_room, const char *loadSav game.options[OPT_ALWAYSSPCH] = oldalways; } - srand(play.randseed); + ::AGS::g_vm->setRandomNumberSeed(play.randseed); if (override_start_room) playerchar->room = override_start_room; diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp index 2700ea198654..7020a0ada670 100644 --- a/engines/ags/engine/main/graphics_mode.cpp +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -24,21 +24,21 @@ // Graphics initialization // -#include -#include "core/platform.h" -#include "ac/draw.h" -#include "debug/debugger.h" -#include "debug/out.h" -#include "gfx/ali3dexception.h" -#include "gfx/bitmap.h" -#include "gfx/gfxdriverfactory.h" -#include "gfx/gfxfilter.h" -#include "gfx/graphicsdriver.h" -#include "main/config.h" -#include "main/engine_setup.h" -#include "main/graphics_mode.h" -#include "main/main_allegro.h" -#include "platform/base/agsplatformdriver.h" +//include +#include "ags/shared/core/platform.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/gfx/ali3dexception.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/engine/gfx/gfxdriverfactory.h" +#include "ags/engine/gfx/gfxfilter.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/main/config.h" +#include "ags/engine/main/engine_setup.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/main/main_allegro.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { @@ -469,20 +469,20 @@ bool graphics_mode_init_any(const Size game_size, const ScreenSetup &setup, cons if (it->CompareNoCase(setup.DriverID) == 0) break; } if (it != ids.end()) - std::rotate(ids.begin(), it, ids.end()); + ids.rotate(it); else Debug::Printf(kDbgMsg_Error, "Requested graphics driver '%s' not found, will try existing drivers instead", setup.DriverID.GetCStr()); // Try to create renderer and init gfx mode, choosing one factory at a time bool result = false; - for (StringV::const_iterator it = ids.begin(); it != ids.end(); ++it) { + for (StringV::const_iterator sit = ids.begin(); sit != ids.end(); ++sit) { result = #ifdef USE_SIMPLE_GFX_INIT simple_create_gfx_driver_and_init_mode #else create_gfx_driver_and_init_mode_any #endif - (*it, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter); + (*sit, game_size, setup.DisplayMode, color_depth, gameframe, setup.Filter); if (result) break; diff --git a/engines/ags/engine/main/graphics_mode.h b/engines/ags/engine/main/graphics_mode.h index 26c377f04f40..0576b90f70b8 100644 --- a/engines/ags/engine/main/graphics_mode.h +++ b/engines/ags/engine/main/graphics_mode.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_MAIN_GRAPHICSMODE_H #define AGS_ENGINE_MAIN_GRAPHICSMODE_H -#include "gfx/gfxdefines.h" -#include "util/scaling.h" -#include "util/string.h" +#include "ags/engine/gfx/gfxdefines.h" +#include "ags/engine/util/scaling.h" +#include "ags/shared/util/string.h" namespace AGS3 { @@ -85,7 +85,7 @@ enum ScreenSizeDefinition { // Configuration that is used to determine the size of the screen struct ScreenSizeSetup { ScreenSizeDefinition SizeDef; // a method used to determine screen size - ::Size Size; // explicitly defined screen metrics + AGS3::Size Size; // explicitly defined screen metrics bool MatchDeviceRatio; // whether to choose resolution matching device aspect ratio ScreenSizeSetup(); diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp index 91f12195fc96..a70fb04f8603 100644 --- a/engines/ags/engine/main/main.cpp +++ b/engines/ags/engine/main/main.cpp @@ -30,33 +30,33 @@ // What about other platforms? // -#include "core/platform.h" +#include "ags/shared/core/platform.h" #define AGS_PLATFORM_DEFINES_PSP_VARS (AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID) -#include -#include "ac/common.h" -#include "ac/gamesetup.h" -#include "ac/gamestate.h" -#include "core/def_version.h" -#include "debug/debugger.h" -#include "debug/debug_log.h" -#include "debug/out.h" -#include "main/config.h" -#include "main/engine.h" -#include "main/mainheader.h" -#include "main/main.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/route_finder.h" -#include "core/assetmanager.h" -#include "util/directory.h" -#include "util/path.h" -#include "util/string_compat.h" +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/core/def_version.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/main/config.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/main/mainheader.h" +#include "ags/shared/main/main.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/route_finder.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/string_compat.h" #if AGS_PLATFORM_OS_WINDOWS -#include "platform/windows/win_ex_handling.h" +#include "ags/shared/platform/windows/win_ex_handling.h" #endif #if AGS_PLATFORM_DEBUG -#include "test/test_all.h" +#include "ags/shared/test/test_all.h" #endif #if AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index a3da94db6ae1..d0efac642533 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MAIN_MAIN_H #define AGS_ENGINE_MAIN_MAIN_H -#include "core/platform.h" -#include "util/version.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/util/version.h" namespace AGS3 { diff --git a/engines/ags/engine/main/mainheader.h b/engines/ags/engine/main/mainheader.h index 10064e6425e7..b2166d287410 100644 --- a/engines/ags/engine/main/mainheader.h +++ b/engines/ags/engine/main/mainheader.h @@ -23,27 +23,27 @@ #ifndef AGS_ENGINE_MAIN_MAINHEADER_H #define AGS_ENGINE_MAIN_MAINHEADER_H -#include "core/platform.h" +#include "ags/shared/core/platform.h" -#include "main/maindefines_ex.h" +#include "ags/engine/main/maindefines_ex.h" -#include "ac/math.h" -#include "script/script_runtime.h" -#include "gui/animatingguibutton.h" -#include "gui/guibutton.h" -#include "gfx/gfxfilter.h" -#include "util/string_utils.h" -#include "device/mousew32.h" -#include "ac/route_finder.h" -#include "util/misc.h" -#include "script/cc_error.h" +#include "ags/engine/ac/math.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/gui/animatingguibutton.h" +#include "ags/shared/gui/guibutton.h" +#include "ags/engine/gfx/gfxfilter.h" +#include "ags/shared/util/string_utils.h" +#include "ags/engine/device/mousew32.h" +#include "ags/engine/ac/route_finder.h" +#include "ags/shared/util/misc.h" +#include "ags/shared/script/cc_error.h" // include last since we affect windows includes -#include "ac/file.h" +#include "ags/engine/ac/file.h" #if AGS_PLATFORM_OS_ANDROID -#include -#include +//include +//include namespace AGS3 { diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index e76439281fa6..9158366712af 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -24,28 +24,29 @@ // Quit game procedure // -#include "core/platform.h" -#include "ac/cdaudio.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/roomstatus.h" -#include "ac/translation.h" -#include "debug/agseditordebugger.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "debug/out.h" -#include "font/fonts.h" -#include "main/config.h" -#include "main/engine.h" -#include "main/main.h" -#include "main/mainheader.h" -#include "main/quit.h" -#include "ac/spritecache.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" -#include "core/assetmanager.h" -#include "plugin/plugin_engine.h" -#include "media/audio/audio_system.h" +#include "ags/shared/core/platform.h" +#include "ags/engine/ac/cdaudio.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/translation.h" +#include "ags/engine/debugging/agseditordebugger.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/font/fonts.h" +#include "ags/engine/main/config.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/main.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/main/quit.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/engine/plugin/plugin_engine.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/ags.h" namespace AGS3 { @@ -194,10 +195,11 @@ void quit_release_data() { _CrtMemCheckpoint(&memstart); _CrtMemDumpStatistics( &memstart );*/ - Common::AssetManager::DestroyInstance(); + Shared::AssetManager::DestroyInstance(); } void quit_delete_temp_files() { +#ifdef TODO al_ffblk dfb; int dun = al_findfirst("~ac*.tmp", &dfb, FA_SEARCH); while (!dun) { @@ -205,6 +207,7 @@ void quit_delete_temp_files() { dun = al_findnext(&dfb); } al_findclose(&dfb); +#endif } // TODO: move to test unit @@ -294,7 +297,7 @@ void quit(const char *quitmsg) { shutdown_debug(); our_eip = 9904; - exit(EXIT_NORMAL); + error("%s", qmsg.GetNullableCStr()); } extern "C" { diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp index f8810acccde0..9ace25d19850 100644 --- a/engines/ags/engine/main/update.cpp +++ b/engines/ags/engine/main/update.cpp @@ -24,30 +24,30 @@ // Game update procedure // -#include -#include "ac/common.h" -#include "ac/character.h" -#include "ac/characterextras.h" -#include "ac/draw.h" -#include "ac/gamestate.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_character.h" -#include "ac/lipsync.h" -#include "ac/overlay.h" -#include "ac/sys_events.h" -#include "ac/roomobject.h" -#include "ac/roomstatus.h" -#include "main/mainheader.h" -#include "main/update.h" -#include "ac/screenoverlay.h" -#include "ac/viewframe.h" -#include "ac/walkablearea.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" -#include "media/audio/audio_system.h" -#include "ac/timer.h" -#include "main/game_run.h" -#include "ac/movelist.h" +//include +#include "ags/shared/ac/common.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/characterextras.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/lipsync.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/main/update.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/ac/walkablearea.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/timer.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/ac/movelist.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/ambientsound.cpp b/engines/ags/engine/media/audio/ambientsound.cpp index b7c77972e4d5..94e1e0cbb60e 100644 --- a/engines/ags/engine/media/audio/ambientsound.cpp +++ b/engines/ags/engine/media/audio/ambientsound.cpp @@ -20,10 +20,10 @@ * */ -#include "media/audio/ambientsound.h" -#include "media/audio/audio.h" -#include "media/audio/soundclip.h" -#include "util/stream.h" +#include "ags/shared/media/audio/ambientsound.h" +#include "ags/shared/media/audio/audio.h" +#include "ags/shared/media/audio/soundclip.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h index 5c5d8955a084..3d042ccb98c6 100644 --- a/engines/ags/engine/media/audio/ambientsound.h +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -44,8 +44,8 @@ struct AmbientSound { bool IsPlaying(); - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out); + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out); }; } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index cdd3339b5f03..f7db003f40ff 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -20,32 +20,32 @@ * */ -#include - -#include "core/platform.h" -#include "util/wgt2allg.h" -#include "media/audio/audio.h" -#include "ac/audiocliptype.h" -#include "ac/gamesetupstruct.h" -#include "ac/dynobj/cc_audioclip.h" -#include "ac/dynobj/cc_audiochannel.h" -#include "ac/gamestate.h" -#include "script/script_runtime.h" -#include "ac/audiochannel.h" -#include "ac/audioclip.h" -#include "ac/gamesetup.h" -#include "ac/path_helper.h" -#include "media/audio/sound.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "ac/common.h" -#include "ac/file.h" -#include "ac/global_audio.h" -#include -#include "util/stream.h" -#include "core/assetmanager.h" -#include "ac/timer.h" -#include "main/game_run.h" +//include + +#include "ags/shared/core/platform.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/media/audio/audio.h" +#include "ags/shared/ac/audiocliptype.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/dynobj/cc_audioclip.h" +#include "ags/shared/ac/dynobj/cc_audiochannel.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/audiochannel.h" +#include "ags/shared/ac/audioclip.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/media/audio/sound.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/file.h" +#include "ags/shared/ac/global_audio.h" +//include +#include "ags/shared/util/stream.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/ac/timer.h" +#include "ags/shared/main/game_run.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index b518a0b93afa..69d4bc71a4fe 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -23,15 +23,15 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_AUDIO_H #define AGS_ENGINE_MEDIA_AUDIO_AUDIO_H -#include -#include "media/audio/audiodefines.h" -#include "ac/dynobj/scriptaudioclip.h" -#include "ac/dynobj/scriptaudiochannel.h" -#include "media/audio/ambientsound.h" -#include "util/mutex.h" -#include "util/mutex_lock.h" -#include "util/thread.h" -#include "ac/timer.h" +#include "ags/std/array.h" +#include "ags/engine/media/audio/audiodefines.h" +#include "ags/shared/ac/dynobj/scriptaudioclip.h" +#include "ags/engine/ac/dynobj/scriptaudiochannel.h" +#include "ags/engine/media/audio/ambientsound.h" +#include "ags/engine/util/mutex.h" +#include "ags/engine/util/mutex_lock.h" +#include "ags/engine/util/thread.h" +#include "ags/engine/ac/timer.h" namespace AGS3 { @@ -156,7 +156,7 @@ extern int crossFadeVolumeAtStart; extern SOUNDCLIP *cachedQueuedMusic; // TODO: double check that ambient sounds array actually needs +1 -extern std::array < AmbientSound, MAX_SOUND_CHANNELS + 1 > ambient; +extern std::array ambient(MAX_SOUND_CHANNELS + 1); } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/audio_system.h b/engines/ags/engine/media/audio/audio_system.h index 202f0238d2ce..b2d086d60d7f 100644 --- a/engines/ags/engine/media/audio/audio_system.h +++ b/engines/ags/engine/media/audio/audio_system.h @@ -23,16 +23,16 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_AUDIO_SYSTEM_H #define AGS_ENGINE_MEDIA_AUDIO_AUDIO_SYSTEM_H -#include "media/audio/audiodefines.h" -#include "media/audio/ambientsound.h" +#include "ags/engine/media/audio/audiodefines.h" +#include "ags/engine/media/audio/ambientsound.h" -#include "media/audio/audio.h" +#include "ags/engine/media/audio/audio.h" -#include "media/audio/soundcache.h" +#include "ags/engine/media/audio/soundcache.h" -#include "media/audio/soundclip.h" -#include "media/audio/sound.h" +#include "ags/engine/media/audio/soundclip.h" +#include "ags/engine/media/audio/sound.h" -#include "media/audio/queuedaudioitem.h" +#include "ags/engine/media/audio/queuedaudioitem.h" #endif diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp index 29337fda62c6..d863bce0dca7 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.cpp +++ b/engines/ags/engine/media/audio/clip_mydumbmod.cpp @@ -20,12 +20,12 @@ * */ -#include "media/audio/audiodefines.h" +#include "ags/shared/media/audio/audiodefines.h" #ifdef DUMB_MOD_PLAYER -#include "media/audio/clip_mydumbmod.h" -#include "media/audio/audiointernaldefs.h" +#include "ags/shared/media/audio/clip_mydumbmod.h" +#include "ags/shared/media/audio/audiointernaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index 50b3cc3c6a90..fcd2f6cb7414 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H -#include "aldumb.h" -#include "media/audio/soundclip.h" +#include "ags/shared/aldumb.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_myjgmod.cpp b/engines/ags/engine/media/audio/clip_myjgmod.cpp index 2225bb636b54..6f1fed049206 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.cpp +++ b/engines/ags/engine/media/audio/clip_myjgmod.cpp @@ -20,12 +20,12 @@ * */ -#include "media/audio/audiodefines.h" +#include "ags/shared/media/audio/audiodefines.h" #ifdef JGMOD_MOD_PLAYER -#include "media/audio/clip_myjgmod.h" -#include "media/audio/audiointernaldefs.h" +#include "ags/shared/media/audio/clip_myjgmod.h" +#include "ags/shared/media/audio/audiointernaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_myjgmod.h b/engines/ags/engine/media/audio/clip_myjgmod.h index 3b6a6f45dcc3..16494928238c 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.h +++ b/engines/ags/engine/media/audio/clip_myjgmod.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYJGMOD_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYJGMOD_H -#include "jgmod.h" -#include "media/audio/soundclip.h" +#include "ags/shared/jgmod.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index 389ed3b47576..ed60c2f25c3b 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -20,10 +20,10 @@ * */ -#include "media/audio/audiodefines.h" -#include "util/wgt2allg.h" -#include "media/audio/clip_mymidi.h" -#include "media/audio/audiointernaldefs.h" +#include "ags/shared/media/audio/audiodefines.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/media/audio/clip_mymidi.h" +#include "ags/shared/media/audio/audiointernaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index 18a2f32046a5..8a802867b399 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMIDI_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMIDI_H -#include "media/audio/soundclip.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp index d90f2cfbfef3..0519eb413d7d 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -20,17 +20,17 @@ * */ -#include "media/audio/audiodefines.h" +#include "ags/shared/media/audio/audiodefines.h" #ifndef NO_MP3_PLAYER -#include "media/audio/clip_mymp3.h" -#include "media/audio/audiointernaldefs.h" -#include "ac/common.h" // quit() -#include "ac/asset_helper.h" -#include "util/mutex_lock.h" +#include "ags/shared/media/audio/clip_mymp3.h" +#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/shared/ac/common.h" // quit() +#include "ags/shared/ac/asset_helper.h" +#include "ags/shared/util/mutex_lock.h" -#include "platform/base/agsplatformdriver.h" +#include "ags/shared/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index f658fd5ce63e..cdd034b9bbd7 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H -#include "almp3.h" -#include "media/audio/soundclip.h" +#include "ags/shared/almp3.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp index 45634550cca1..6c5539d1bffb 100644 --- a/engines/ags/engine/media/audio/clip_myogg.cpp +++ b/engines/ags/engine/media/audio/clip_myogg.cpp @@ -20,14 +20,14 @@ * */ -#include "media/audio/audiodefines.h" -#include "media/audio/clip_myogg.h" -#include "media/audio/audiointernaldefs.h" -#include "ac/common.h" // quit() -#include "ac/asset_helper.h" -#include "util/mutex_lock.h" - -#include "platform/base/agsplatformdriver.h" +#include "ags/shared/media/audio/audiodefines.h" +#include "ags/shared/media/audio/clip_myogg.h" +#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/shared/ac/common.h" // quit() +#include "ags/shared/ac/asset_helper.h" +#include "ags/shared/util/mutex_lock.h" + +#include "ags/shared/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h index 05cd7439a034..0341caec08db 100644 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H -#include "alogg.h" -#include "media/audio/soundclip.h" +#include "ags/shared/alogg.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp index 942a5fbe57a9..f653f3d1b17a 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -20,16 +20,16 @@ * */ -#include "media/audio/audiodefines.h" +#include "ags/shared/media/audio/audiodefines.h" #ifndef NO_MP3_PLAYER -#include "media/audio/clip_mystaticmp3.h" -#include "media/audio/audiointernaldefs.h" -#include "media/audio/soundcache.h" -#include "util/mutex_lock.h" +#include "ags/shared/media/audio/clip_mystaticmp3.h" +#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/shared/media/audio/soundcache.h" +#include "ags/shared/util/mutex_lock.h" -#include "platform/base/agsplatformdriver.h" +#include "ags/shared/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index 291d20f98e16..7f1313d13731 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H -#include "almp3.h" -#include "media/audio/soundclip.h" +#include "ags/shared/almp3.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp index 8860ca716082..5cbbb79a6f44 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticogg.cpp @@ -20,13 +20,13 @@ * */ -#include "media/audio/audiodefines.h" -#include "media/audio/clip_mystaticogg.h" -#include "media/audio/audiointernaldefs.h" -#include "media/audio/soundcache.h" -#include "util/mutex_lock.h" +#include "ags/shared/media/audio/audiodefines.h" +#include "ags/shared/media/audio/clip_mystaticogg.h" +#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/shared/media/audio/soundcache.h" +#include "ags/shared/util/mutex_lock.h" -#include "platform/base/agsplatformdriver.h" +#include "ags/shared/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h index bc5f5ea3860e..4663560961e9 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H -#include "alogg.h" -#include "media/audio/soundclip.h" +#include "ags/shared/alogg.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp index 5efd2fbe3257..875bd3363b5a 100644 --- a/engines/ags/engine/media/audio/clip_mywave.cpp +++ b/engines/ags/engine/media/audio/clip_mywave.cpp @@ -20,14 +20,14 @@ * */ -#include "util/wgt2allg.h" -#include "media/audio/audiodefines.h" -#include "media/audio/clip_mywave.h" -#include "media/audio/audiointernaldefs.h" -#include "media/audio/soundcache.h" -#include "util/mutex_lock.h" - -#include "platform/base/agsplatformdriver.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/media/audio/audiodefines.h" +#include "ags/shared/media/audio/clip_mywave.h" +#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/shared/media/audio/soundcache.h" +#include "ags/shared/util/mutex_lock.h" + +#include "ags/shared/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h index 7173367a122e..24b119a7eb04 100644 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H -#include "media/audio/soundclip.h" +#include "ags/shared/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/queuedaudioitem.cpp b/engines/ags/engine/media/audio/queuedaudioitem.cpp index a98f801af2f3..744e6db89f90 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.cpp +++ b/engines/ags/engine/media/audio/queuedaudioitem.cpp @@ -20,9 +20,9 @@ * */ -#include "media/audio/queuedaudioitem.h" -#include "ac/common_defines.h" -#include "util/stream.h" +#include "ags/shared/media/audio/queuedaudioitem.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/queuedaudioitem.h b/engines/ags/engine/media/audio/queuedaudioitem.h index 14907e6559ae..9c7fa0ffa5cc 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.h +++ b/engines/ags/engine/media/audio/queuedaudioitem.h @@ -41,8 +41,8 @@ struct QueuedAudioItem { bool repeat; SOUNDCLIP *cachedClip; - void ReadFromFile(Common::Stream *in); - void WriteToFile(Common::Stream *out) const; + void ReadFromFile(Shared::Stream *in); + void WriteToFile(Shared::Stream *out) const; }; } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index ac9f3e6d718c..057a498b983a 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -26,30 +26,30 @@ // //============================================================================= -#include // for toupper - -#include "core/platform.h" -#include "util/wgt2allg.h" -#include "ac/file.h" -#include "media/audio/audiodefines.h" -#include "media/audio/sound.h" -#include "media/audio/audiointernaldefs.h" -#include "media/audio/clip_mywave.h" +//include // for toupper + +#include "ags/shared/core/platform.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/ac/file.h" +#include "ags/shared/media/audio/audiodefines.h" +#include "ags/shared/media/audio/sound.h" +#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/shared/media/audio/clip_mywave.h" #ifndef NO_MP3_PLAYER -#include "media/audio/clip_mymp3.h" -#include "media/audio/clip_mystaticmp3.h" +#include "ags/shared/media/audio/clip_mymp3.h" +#include "ags/shared/media/audio/clip_mystaticmp3.h" #endif -#include "media/audio/clip_myogg.h" -#include "media/audio/clip_mystaticogg.h" -#include "media/audio/clip_mymidi.h" +#include "ags/shared/media/audio/clip_myogg.h" +#include "ags/shared/media/audio/clip_mystaticogg.h" +#include "ags/shared/media/audio/clip_mymidi.h" #ifdef JGMOD_MOD_PLAYER -#include "media/audio/clip_myjgmod.h" +#include "ags/shared/media/audio/clip_myjgmod.h" #endif #ifdef DUMB_MOD_PLAYER -#include "media/audio/clip_mydumbmod.h" +#include "ags/shared/media/audio/clip_mydumbmod.h" #endif -#include "media/audio/soundcache.h" -#include "util/mutex_lock.h" +#include "ags/shared/media/audio/soundcache.h" +#include "ags/shared/util/mutex_lock.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/sound.h b/engines/ags/engine/media/audio/sound.h index e98c4a7f5ec2..d5d5ea7e357e 100644 --- a/engines/ags/engine/media/audio/sound.h +++ b/engines/ags/engine/media/audio/sound.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_SOUND_H #define AGS_ENGINE_MEDIA_AUDIO_SOUND_H -#include "ac/asset_helper.h" -#include "media/audio/soundclip.h" +#include "ags/engine/ac/asset_helper.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index f8bbfa3095fe..0ca7dde4a532 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -20,16 +20,16 @@ * */ -#include -#include -#include "ac/file.h" -#include "util/wgt2allg.h" -#include "media/audio/soundcache.h" -#include "media/audio/audiointernaldefs.h" -#include "util/mutex.h" -#include "util/mutex_lock.h" -#include "util/string.h" -#include "debug/out.h" +//include +//include +#include "ags/shared/ac/file.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/media/audio/soundcache.h" +#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/shared/util/mutex.h" +#include "ags/shared/util/mutex_lock.h" +#include "ags/shared/util/string.h" +#include "ags/shared/debug/out.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h index 09162ba1f7b1..932c207b8c8d 100644 --- a/engines/ags/engine/media/audio/soundcache.h +++ b/engines/ags/engine/media/audio/soundcache.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_SOUNDCACHE_H #define AGS_ENGINE_MEDIA_AUDIO_SOUNDCACHE_H -#include "ac/asset_helper.h" +#include "ags/engine/ac/asset_helper.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index 64a2238f3155..68fc57ceec6e 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -20,11 +20,11 @@ * */ -#include "util/wgt2allg.h" -#include "media/audio/audio.h" -#include "media/audio/audiodefines.h" -#include "media/audio/soundclip.h" -#include "media/audio/audiointernaldefs.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/media/audio/audio.h" +#include "ags/shared/media/audio/audiodefines.h" +#include "ags/shared/media/audio/soundclip.h" +#include "ags/shared/media/audio/audiointernaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index 48daf5c92682..d7d89767e7ae 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_SOUNDCLIP_H #define AGS_ENGINE_MEDIA_AUDIO_SOUNDCLIP_H -#include "util/mutex.h" +#include "ags/engine/util/mutex.h" namespace AGS3 { diff --git a/engines/ags/engine/media/video/VMR9Graph.h b/engines/ags/engine/media/video/VMR9Graph.h index e6a8713355df..837d3a5896dd 100644 --- a/engines/ags/engine/media/video/VMR9Graph.h +++ b/engines/ags/engine/media/video/VMR9Graph.h @@ -33,8 +33,8 @@ #pragma once #endif -#include -#include +//include +//include namespace AGS3 { diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index a34bdf43a9ef..930a5bc79759 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -20,35 +20,35 @@ * */ -#include "media/video/video.h" +#include "ags/shared/media/video/video.h" #ifndef AGS_NO_VIDEO_PLAYER -#include "apeg.h" -#include "core/platform.h" +#include "ags/shared/apeg.h" +#include "ags/shared/core/platform.h" #define AGS_FLI_FROM_PACK_FILE ((ALLEGRO_DATE >= 20190303) || \ AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_MACOS) -#include "debug/debug_log.h" -#include "debug/out.h" -#include "ac/asset_helper.h" -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/game_version.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_display.h" -#include "ac/mouse.h" -#include "ac/sys_events.h" -#include "ac/runtime_defines.h" -#include "ac/system.h" -#include "core/assetmanager.h" -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "gfx/graphicsdriver.h" -#include "main/game_run.h" -#include "util/stream.h" -#include "media/audio/audio_system.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/ac/asset_helper.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/game_version.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/sys_events.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/system.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/android/acpland.cpp b/engines/ags/engine/platform/android/acpland.cpp index a3f24a8c1f14..5df561b3e74a 100644 --- a/engines/ags/engine/platform/android/acpland.cpp +++ b/engines/ags/engine/platform/android/acpland.cpp @@ -20,26 +20,26 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_ANDROID #include "ags/lib/allegro.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/runtime_defines.h" -#include "main/config.h" -#include "plugin/agsplugin.h" -#include -#include -#include -#include -#include -#include "util/string_compat.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/main/config.h" +#include "ags/shared/plugin/agsplugin.h" +//include +//include +//include +//include +//include +#include "ags/shared/util/string_compat.h" -#include -#include +//include +//include namespace AGS3 { diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index ba78ed5a99ff..0d0a624ffc8a 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -26,17 +26,17 @@ // //============================================================================= -#include -#include "util/wgt2allg.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/common.h" -#include "ac/runtime_defines.h" -#include "util/string_utils.h" -#include "util/stream.h" -#include "gfx/bitmap.h" -#include "plugin/agsplugin.h" -#include "ac/timer.h" -#include "media/audio/audio_system.h" +//include +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/util/string_utils.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/ac/timer.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { @@ -44,7 +44,7 @@ using namespace AGS::Shared; using namespace AGS::Engine; #if defined (AGS_HAS_CD_AUDIO) -#include "libcda.h" +#include "ags/shared/libcda.h" #endif // We don't have many places where we delay longer than a frame, but where we @@ -170,7 +170,7 @@ void AGSPlatformDriver::UnlockMouse() { //----------------------------------------------- // IOutputHandler implementation //----------------------------------------------- -void AGSPlatformDriver::PrintMessage(const Common::DebugMessage &msg) { +void AGSPlatformDriver::PrintMessage(const Shared::DebugMessage &msg) { if (_logToStdErr) { if (msg.GroupName.IsEmpty()) WriteStdErr("%s", msg.Text.GetCStr()); diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 863af0f525ee..4363cb7fbb7a 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -29,11 +29,11 @@ #ifndef AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H #define AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H -#include -#include -#include "ac/datetime.h" -#include "debug/outputhandler.h" -#include "util/ini_util.h" +//include +#include "ags/std/vector.h" +#include "ags/engine/ac/datetime.h" +#include "ags/shared/debugging/outputhandler.h" +#include "ags/shared/util/ini_util.h" namespace AGS3 { @@ -120,7 +120,7 @@ struct AGSPlatformDriver virtual void PostAllegroInit(bool windowed); virtual void PostAllegroExit() = 0; virtual void FinishedUsingGraphicsMode(); - virtual SetupReturnValue RunSetup(const Common::ConfigTree &cfg_in, Common::ConfigTree &cfg_out); + virtual SetupReturnValue RunSetup(const Shared::ConfigTree &cfg_in, Shared::ConfigTree &cfg_out); virtual void SetGameWindowIcon(); // Formats message and writes to standard platform's output; // Always adds trailing '\n' after formatted string diff --git a/engines/ags/engine/platform/ios/acplios.cpp b/engines/ags/engine/platform/ios/acplios.cpp index 8134a608ea07..4081f8d9f164 100644 --- a/engines/ags/engine/platform/ios/acplios.cpp +++ b/engines/ags/engine/platform/ios/acplios.cpp @@ -20,21 +20,21 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_IOS -#include -#include -#include -#include +//include +//include +//include +//include #include "ags/lib/allegro.h" -#include "platform/base/agsplatformdriver.h" -#include "ac/runtime_defines.h" -#include "main/config.h" -#include "plugin/agsplugin.h" -#include "util/string_utils.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/main/config.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 3adccfd820f3..4c44c0afcff3 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -20,24 +20,24 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_LINUX // ********* LINUX PLACEHOLDER DRIVER ********* -#include +//include #include "ags/lib/allegro.h" -#include -#include "ac/runtime_defines.h" -#include "gfx/gfxdefines.h" -#include "platform/base/agsplatformdriver.h" -#include "plugin/agsplugin.h" -#include "util/string.h" -#include +//include +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/gfx/gfxdefines.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/util/string.h" +//include -#include -#include +//include +//include namespace AGS3 { @@ -46,7 +46,7 @@ using AGS::Shared::String; // Replace the default Allegro icon. The original defintion is in the // Allegro 4.4 source under "src/x/xwin.c". -#include "icon.xpm" +#include "ags/shared/icon.xpm" void *allegro_icon = icon_xpm; String CommonDataDirectory; String UserDataDirectory; diff --git a/engines/ags/engine/platform/osx/acplmac.cpp b/engines/ags/engine/platform/osx/acplmac.cpp index 449464d8bf95..ae49c9d74bb9 100644 --- a/engines/ags/engine/platform/osx/acplmac.cpp +++ b/engines/ags/engine/platform/osx/acplmac.cpp @@ -20,24 +20,24 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_MACOS // ********* MacOS PLACEHOLDER DRIVER ********* -//#include "util/wgt2allg.h" -//#include "gfx/ali3d.h" -//#include "ac/runtime_defines.h" -//#include "main/config.h" -//#include "plugin/agsplugin.h" -//#include -//#include -//#include -#include "platform/base/agsplatformdriver.h" -#include "util/directory.h" -#include "ac/common.h" -#include "main/main.h" +//#include "ags/shared/util/wgt2allg.h" +//#include "ags/shared/gfx/ali3d.h" +//#include "ags/shared/ac/runtime_defines.h" +//#include "ags/shared/main/config.h" +//#include "ags/shared/plugin/agsplugin.h" +////include +////include +////include +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/main/main.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/osx/alplmac.mm b/engines/ags/engine/platform/osx/alplmac.mm index c245aec1b931..965772170539 100644 --- a/engines/ags/engine/platform/osx/alplmac.mm +++ b/engines/ags/engine/platform/osx/alplmac.mm @@ -1,6 +1,6 @@ #import -#include +//include void AGSMacInitPaths(char gamename[256], char appdata[PATH_MAX]) { diff --git a/engines/ags/engine/platform/util/libc.c b/engines/ags/engine/platform/util/libc.c index f88f89cc4bd5..02aacb202e5b 100644 --- a/engines/ags/engine/platform/util/libc.c +++ b/engines/ags/engine/platform/util/libc.c @@ -16,15 +16,15 @@ // //============================================================================= -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if ! AGS_PLATFORM_OS_WINDOWS -#include -#include -#include -#include -#include +//include +//include +//include +//include +//include size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t max) { diff --git a/engines/ags/engine/platform/util/pe.c b/engines/ags/engine/platform/util/pe.c index de7f65287787..2925f7e6d5e7 100644 --- a/engines/ags/engine/platform/util/pe.c +++ b/engines/ags/engine/platform/util/pe.c @@ -18,11 +18,11 @@ #if defined(ANDROID) || defined(PSP) -#include "pe.h" +#include "ags/shared/pe.h" -#include -#include -#include "util/stdio_compat.h" +//include +//include +#include "ags/shared/util/stdio_compat.h" // Simplified structs for PE files diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index ccf9dc00c5bd..9f300fb1e16e 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -20,33 +20,33 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS // ********* WINDOWS ********* -#include +//include #include "ags/lib/allegro.h" -#include -#include "ac/common.h" -#include "ac/draw.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_display.h" -#include "ac/runtime_defines.h" -#include "ac/string.h" -#include "debug/out.h" -#include "gfx/graphicsdriver.h" -#include "gfx/bitmap.h" -#include "main/engine.h" -#include "platform/base/agsplatformdriver.h" -#include "platform/windows/setup/winsetup.h" -#include "plugin/agsplugin.h" -#include "util/file.h" -#include "util/stream.h" -#include "util/string_compat.h" -#include "media/audio/audio_system.h" +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/runtime_defines.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/platform/windows/setup/winsetup.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/string_compat.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { @@ -66,14 +66,14 @@ extern int our_eip; extern IGraphicsDriver *gfxDriver; extern color palette[256]; -#include -#include -#include -#include -#include -#include +//include +//include +//include +//include +//include +//include -#include +//include #ifndef CSIDL_LOCAL_APPDATA diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp index 6985e435ae98..b97ecf460b51 100644 --- a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.cpp @@ -20,13 +20,13 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include "platform/windows/debug/namedpipesagsdebugger.h" +#include "ags/shared/platform/windows/debug/namedpipesagsdebugger.h" -#include // sprintf +//include // sprintf namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h index 597d091125c8..6e7b86d43fa3 100644 --- a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_DEBUGGING_NAMEDPIPESAGSDEBUGGER_H #define AGS_ENGINE_DEBUGGING_NAMEDPIPESAGSDEBUGGER_H -#include -#include -#include "debug/agseditordebugger.h" +//include +//include +#include "ags/shared/debug/agseditordebugger.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index 93c926e8c088..e099493b9fb1 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -26,24 +26,24 @@ // //============================================================================= -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include "platform/windows/gfx/ali3dd3d.h" +#include "ags/shared/platform/windows/gfx/ali3dd3d.h" #include "ags/lib/allegro.h" -#include -#include "ac/timer.h" -#include "debug/assert.h" -#include "debug/out.h" -#include "gfx/ali3dexception.h" -#include "gfx/gfxfilter_d3d.h" -#include "gfx/gfxfilter_aad3d.h" -#include "gfx/gfx_util.h" -#include "main/main_allegro.h" -#include "platform/base/agsplatformdriver.h" -#include "util/library.h" +//include +#include "ags/shared/ac/timer.h" +#include "ags/shared/debug/assert.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/gfx/ali3dexception.h" +#include "ags/shared/gfx/gfxfilter_d3d.h" +#include "ags/shared/gfx/gfxfilter_aad3d.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/main/main_allegro.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/util/library.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index 1d5abbebe4e0..deb25f9d9785 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -29,22 +29,22 @@ #ifndef AGS_ENGINE_PLATFORM_WINDOWS_ALI3DD3D_H #define AGS_ENGINE_PLATFORM_WINDOWS_ALI3DD3D_H -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if ! AGS_PLATFORM_OS_WINDOWS #error This file should only be included on the Windows build #endif -#include +#include "ags/std/memory.h" #include "ags/lib/allegro.h" -#include -#include -#include "gfx/bitmap.h" -#include "gfx/ddb.h" -#include "gfx/gfxdriverfactorybase.h" -#include "gfx/gfxdriverbase.h" -#include "util/library.h" -#include "util/string.h" +//include +//include +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/ddb.h" +#include "ags/shared/gfx/gfxdriverfactorybase.h" +#include "ags/shared/gfx/gfxdriverbase.h" +#include "ags/shared/util/library.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/media/video/acwavi.cpp b/engines/ags/engine/platform/windows/media/video/acwavi.cpp index fe9a62160d22..1266dc8ff3c1 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi.cpp @@ -28,24 +28,24 @@ // //============================================================================= -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) //#define ALLEGRO_STATICLINK // already defined in project settings #include "ags/lib/allegro.h" -#include -#include -#include -#include -#include // Multimedia stream interfaces -#include // DirectDraw multimedia stream interfaces -#include // Defines DEFINE_GUID macro and enables GUID initialization -#include "ac/draw.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" -#include "main/game_run.h" -#include "platform/base/agsplatformdriver.h" +//include +//include +//include +//include +//include // Multimedia stream interfaces +//include // DirectDraw multimedia stream interfaces +//include // Defines DEFINE_GUID macro and enables GUID initialization +#include "ags/shared/ac/draw.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp index e49ef7c05c43..11b24ecb2b52 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -27,28 +27,28 @@ // //============================================================================= -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS && ! defined (AGS_NO_VIDEO_PLAYER) //#define ALLEGRO_STATICLINK // already defined in project settings #include "ags/lib/allegro.h" -#include -#include -#include -#include +//include +//include +//include +//include #define DWORD_PTR DWORD* #define LONG_PTR LONG* #define LPD3DVECTOR D3DVECTOR* #define _D3DTYPES_H_ #define _STRSAFE_H_INCLUDED_ typedef float D3DVALUE, *LPD3DVALUE; -#include "ac/common.h" -#include "main/game_run.h" -#include "media/video/VMR9Graph.h" -#include "platform/base/agsplatformdriver.h" -//#include -#include "media/audio/audio_system.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/media/video/VMR9Graph.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +////include +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { @@ -147,7 +147,7 @@ int dxmedia_play_video_3d(const char *filename, IDirect3DDevice9 *device, bool u ////////////////////////////////////////////////////////////////////// -//#include +////include #if AGS_PLATFORM_DEBUG #undef THIS_FILE diff --git a/engines/ags/engine/platform/windows/minidump.cpp b/engines/ags/engine/platform/windows/minidump.cpp index 6203f1eadcd1..c25b96d3b3fb 100644 --- a/engines/ags/engine/platform/windows/minidump.cpp +++ b/engines/ags/engine/platform/windows/minidump.cpp @@ -20,14 +20,14 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG #define UNICODE -#include // sprintf -#include "windows.h" -#include -#include "main/main.h" +//include // sprintf +#include "ags/shared/windows.h" +//include +#include "ags/shared/main/main.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/setup/winsetup.cpp b/engines/ags/engine/platform/windows/setup/winsetup.cpp index 0b33435e221e..3a3e824f10a3 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.cpp +++ b/engines/ags/engine/platform/windows/setup/winsetup.cpp @@ -20,33 +20,33 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ac/gamestructdefines.h" +//include +//include +//include +//include +//include +#include "ags/std/memory.h" +//include +//include +#include "ags/std/vector.h" +#include "ags/shared/ac/gamestructdefines.h" #undef RGB #undef PALETTE #define RGB void* #define PALETTE void* -#include "gfx/gfxdriverfactory.h" -#include "gfx/gfxfilter.h" -#include "gfx/graphicsdriver.h" -#include "main/config.h" -#include "main/graphics_mode.h" -#include "platform/base/agsplatformdriver.h" -#include "resource/resource.h" -#include "util/file.h" -#include "util/string_utils.h" +#include "ags/shared/gfx/gfxdriverfactory.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/main/config.h" +#include "ags/shared/main/graphics_mode.h" +#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/shared/resource/resource.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/string_utils.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/setup/winsetup.h b/engines/ags/engine/platform/windows/setup/winsetup.h index b07ec14fe799..dc4c9bb8c184 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.h +++ b/engines/ags/engine/platform/windows/setup/winsetup.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_PLATFORM_WINDOWS_SETUP_WINSETUP_H #define AGS_ENGINE_PLATFORM_WINDOWS_SETUP_WINSETUP_H -#include "util/ini_util.h" +#include "ags/shared/util/ini_util.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index c59d7e3456e7..aeffbc23c9d0 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -20,18 +20,18 @@ * */ -#include "core/platform.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include +//include #include "ags/lib/allegro.h" -#include -#include "ac/common.h" -#include "ac/common_defines.h" -#include "debug/debugger.h" -#include "debug/out.h" -#include "main/main.h" -#include "util/ini_util.h" +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/common_defines.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/main/main.h" +#include "ags/shared/util/ini_util.h" #if !AGS_PLATFORM_DEBUG #define USE_CUSTOM_EXCEPTION_HANDLER diff --git a/engines/ags/engine/platform/windows/win_ex_handling.h b/engines/ags/engine/platform/windows/win_ex_handling.h index e1559a0bb6d9..4f2d6d234f4f 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.h +++ b/engines/ags/engine/platform/windows/win_ex_handling.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_PLATFORM_WINDOWS_WIN_EX_HANDLING_H #define AGS_ENGINE_PLATFORM_WINDOWS_WIN_EX_HANDLING_H -#include "util/ini_util.h" +#include "ags/shared/util/ini_util.h" namespace AGS3 { diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 83133ab32afa..5837511a6cb7 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -20,59 +20,59 @@ * */ -#include -#include "core/platform.h" +#include "ags/std/vector.h" +#include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS -#include "platform/windows/winapi_exclusive.h" +#include "ags/shared/platform/windows/winapi_exclusive.h" #endif -#include "util/wgt2allg.h" -#include "ac/common.h" -#include "ac/view.h" -#include "ac/charactercache.h" -#include "ac/display.h" -#include "ac/draw.h" -#include "ac/dynamicsprite.h" -#include "ac/gamesetup.h" -#include "ac/gamesetupstruct.h" -#include "ac/global_audio.h" -#include "ac/global_plugin.h" -#include "ac/global_walkablearea.h" -#include "ac/keycode.h" -#include "ac/mouse.h" -#include "ac/movelist.h" -#include "ac/objectcache.h" -#include "ac/parser.h" -#include "ac/path_helper.h" -#include "ac/roomstatus.h" -#include "ac/string.h" -#include "ac/dynobj/cc_dynamicobject_addr_and_manager.h" -#include "font/fonts.h" -#include "util/string_compat.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" -#include "device/mousew32.h" -#include "gui/guidefines.h" -#include "main/game_run.h" -#include "main/engine.h" -#include "plugin/agsplugin.h" -#include "plugin/plugin_engine.h" -#include "plugin/plugin_builtin.h" -#include "plugin/pluginobjectreader.h" -#include "script/script.h" -#include "script/script_runtime.h" -#include "ac/spritecache.h" -#include "util/stream.h" -#include "gfx/bitmap.h" -#include "gfx/graphicsdriver.h" -#include "gfx/gfxfilter.h" -#include "script/runtimescriptvalue.h" -#include "debug/out.h" -#include "ac/dynobj/scriptstring.h" -#include "main/graphics_mode.h" -#include "gfx/gfx_util.h" -#include "util/memory.h" -#include "util/filestream.h" -#include "media/audio/audio_system.h" +#include "ags/shared/util/wgt2allg.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/view.h" +#include "ags/shared/ac/charactercache.h" +#include "ags/shared/ac/display.h" +#include "ags/shared/ac/draw.h" +#include "ags/shared/ac/dynamicsprite.h" +#include "ags/shared/ac/gamesetup.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_plugin.h" +#include "ags/shared/ac/global_walkablearea.h" +#include "ags/shared/ac/keycode.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/movelist.h" +#include "ags/shared/ac/objectcache.h" +#include "ags/shared/ac/parser.h" +#include "ags/shared/ac/path_helper.h" +#include "ags/shared/ac/roomstatus.h" +#include "ags/shared/ac/string.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject_addr_and_manager.h" +#include "ags/shared/font/fonts.h" +#include "ags/shared/util/string_compat.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/device/mousew32.h" +#include "ags/shared/gui/guidefines.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/main/engine.h" +#include "ags/shared/plugin/agsplugin.h" +#include "ags/shared/plugin/plugin_engine.h" +#include "ags/shared/plugin/plugin_builtin.h" +#include "ags/shared/plugin/pluginobjectreader.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/spritecache.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/shared/gfx/gfxfilter.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/shared/main/graphics_mode.h" +#include "ags/shared/gfx/gfx_util.h" +#include "ags/shared/util/memory.h" +#include "ags/shared/util/filestream.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { @@ -82,13 +82,13 @@ using namespace AGS::Engine; #if defined(BUILTIN_PLUGINS) -#include "../Plugins/AGSflashlight/agsflashlight.h" -#include "../Plugins/agsblend/agsblend.h" -#include "../Plugins/ags_snowrain/ags_snowrain.h" -#include "../Plugins/ags_parallax/ags_parallax.h" -#include "../Plugins/agspalrender/agspalrender.h" +#include "ags/shared/../Plugins/AGSflashlight/agsflashlight.h" +#include "ags/shared/../Plugins/agsblend/agsblend.h" +#include "ags/shared/../Plugins/ags_snowrain/ags_snowrain.h" +#include "ags/shared/../Plugins/ags_parallax/ags_parallax.h" +#include "ags/shared/../Plugins/agspalrender/agspalrender.h" #if AGS_PLATFORM_OS_IOS -#include "../Plugins/agstouch/agstouch.h" +#include "ags/shared/../Plugins/agstouch/agstouch.h" #endif // AGS_PLATFORM_OS_IOS #endif // BUILTIN_PLUGINS @@ -117,7 +117,7 @@ extern ScriptString myScriptStringImpl; // **************** PLUGIN IMPLEMENTATION **************** -#include "util/library.h" +#include "ags/shared/util/library.h" diff --git a/engines/ags/engine/plugin/global_plugin.cpp b/engines/ags/engine/plugin/global_plugin.cpp index 52e66cd8f88d..8ec36dd51d35 100644 --- a/engines/ags/engine/plugin/global_plugin.cpp +++ b/engines/ags/engine/plugin/global_plugin.cpp @@ -26,10 +26,10 @@ // //============================================================================= -#include -#include "ac/global_plugin.h" -#include "ac/mouse.h" -#include "util/string_compat.h" +//include +#include "ags/shared/ac/global_plugin.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/util/string_compat.h" namespace AGS3 { @@ -45,7 +45,7 @@ void PluginSimulateMouseClick(int pluginButtonID) { // //============================================================================= -#include "script/script_runtime.h" +#include "ags/shared/script/script_runtime.h" RuntimeScriptValue Sc_PluginStub_Void(const RuntimeScriptValue *params, int32_t param_count) { return RuntimeScriptValue((int32_t)0); diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/engine/plugin/plugin_engine.h index 2c3e52aed4c7..736f5d5950f9 100644 --- a/engines/ags/engine/plugin/plugin_engine.h +++ b/engines/ags/engine/plugin/plugin_engine.h @@ -29,9 +29,9 @@ #ifndef AGS_ENGINE_PLUGIN_PLUGIN_ENGINE_H #define AGS_ENGINE_PLUGIN_PLUGIN_ENGINE_H -#include -#include "game/game_init.h" -#include "game/plugininfo.h" +#include "ags/std/vector.h" +#include "ags/engine/game/game_init.h" +#include "ags/shared/game/plugininfo.h" namespace AGS3 { @@ -52,7 +52,7 @@ int pl_run_plugin_hooks(int event, int data); void pl_run_plugin_init_gfx_hooks(const char *driverName, void *data); int pl_run_plugin_debug_hooks(const char *scriptfile, int linenum); // Tries to register plugins, either by loading dynamic libraries, or getting any kind of replacement -Engine::GameInitError pl_register_plugins(const std::vector &infos); +Engine::GameInitError pl_register_plugins(const std::vector &infos); bool pl_is_plugin_loaded(const char *pl_name); //returns whether _any_ plugins want a particular event diff --git a/engines/ags/engine/plugin/pluginobjectreader.cpp b/engines/ags/engine/plugin/pluginobjectreader.cpp index c5d387dd12b2..237c7e9370f2 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.cpp +++ b/engines/ags/engine/plugin/pluginobjectreader.cpp @@ -20,8 +20,8 @@ * */ -#include "plugin/pluginobjectreader.h" -#include "ac/runtime_defines.h" +#include "ags/shared/plugin/pluginobjectreader.h" +#include "ags/shared/ac/runtime_defines.h" namespace AGS3 { diff --git a/engines/ags/engine/resource/version.rc b/engines/ags/engine/resource/version.rc index f22cb431833a..0dd4d1c8a5e5 100644 --- a/engines/ags/engine/resource/version.rc +++ b/engines/ags/engine/resource/version.rc @@ -1,15 +1,15 @@ // Microsoft Visual C++ generated resource script. // -#include "resource.h" +#include "ags/shared/resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // -#include +//include #define IDC_STATIC -1 -#include "../../Common/core/def_version.h" +#include "ags/shared/../../Common/core/def_version.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -86,9 +86,9 @@ END 2 TEXTINCLUDE BEGIN - "#include \r\n" + "//include \r\n" "#define IDC_STATIC -1\r\n" - "#include ""../../Common/core/def_version.h""\r\n" + "#include "ags/shared/"../../Common/core/def_version.h""\r\n" "\0" END diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index ef4b9dd643ca..2effb0fd1f51 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -20,31 +20,31 @@ * */ -#include -#include -#include "ac/common.h" -#include "ac/dynobj/cc_dynamicarray.h" -#include "ac/dynobj/managedobjectpool.h" -#include "gui/guidefines.h" -#include "script/cc_error.h" -#include "script/cc_instance.h" -#include "debug/debug_log.h" -#include "debug/out.h" -#include "script/cc_options.h" -#include "script/script.h" -#include "script/script_runtime.h" -#include "script/systemimports.h" -#include "util/bbop.h" -#include "util/stream.h" -#include "util/misc.h" -#include "util/textstreamwriter.h" -#include "ac/dynobj/scriptstring.h" -#include "ac/dynobj/scriptuserobject.h" -#include "ac/statobj/agsstaticobject.h" -#include "ac/statobj/staticarray.h" -#include "ac/dynobj/cc_dynamicobject_addr_and_manager.h" -#include "util/memory.h" -#include "util/string_utils.h" // linux strnicmp definition +//include +//include +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/dynobj/cc_dynamicarray.h" +#include "ags/shared/ac/dynobj/managedobjectpool.h" +#include "ags/shared/gui/guidefines.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/cc_instance.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/script/cc_options.h" +#include "ags/shared/script/script.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/script/systemimports.h" +#include "ags/shared/util/bbop.h" +#include "ags/shared/util/stream.h" +#include "ags/shared/util/misc.h" +#include "ags/shared/util/textstreamwriter.h" +#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/shared/ac/dynobj/scriptuserobject.h" +#include "ags/shared/ac/statobj/agsstaticobject.h" +#include "ags/shared/ac/statobj/staticarray.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject_addr_and_manager.h" +#include "ags/shared/util/memory.h" +#include "ags/shared/util/string_utils.h" // linux strnicmp definition namespace AGS3 { diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h index 5784d0aa4ec2..7b0dd97c2c4f 100644 --- a/engines/ags/engine/script/cc_instance.h +++ b/engines/ags/engine/script/cc_instance.h @@ -29,13 +29,12 @@ #ifndef AGS_ENGINE_SCRIPT_CCINSTANCE_H #define AGS_ENGINE_SCRIPT_CCINSTANCE_H -#include -#include - -#include "script/script_common.h" -#include "script/cc_script.h" // ccScript -#include "script/nonblockingscriptfunction.h" -#include "util/string.h" +#include "ags/std/map.h" +#include "ags/std/memory.h" +#include "ags/shared/script/script_common.h" +#include "ags/shared/script/cc_script.h" // ccScript +#include "ags/engine/script/nonblockingscriptfunction.h" +#include "ags/shared/util/string.h" namespace AGS3 { @@ -96,12 +95,12 @@ struct ScriptPosition { : Line(0) { } - ScriptPosition(const Common::String §ion, int32_t line) + ScriptPosition(const Shared::String §ion, int32_t line) : Section(section) , Line(line) { } - Common::String Section; + Shared::String Section; int32_t Line; }; @@ -173,7 +172,7 @@ struct ccInstance { int Run(int32_t curpc); // Get the script's execution position and callstack as human-readable text - Common::String GetCallStack(int maxLines); + Shared::String GetCallStack(int maxLines); // Get the script's execution position void GetScriptPosition(ScriptPosition &script_pos); // Get the address of an exported symbol (function or variable) in the script diff --git a/engines/ags/engine/script/executingscript.cpp b/engines/ags/engine/script/executingscript.cpp index 3b977b517b5d..190f4464dc1c 100644 --- a/engines/ags/engine/script/executingscript.cpp +++ b/engines/ags/engine/script/executingscript.cpp @@ -20,10 +20,10 @@ * */ -#include -#include "executingscript.h" -#include "debug/debug_log.h" -#include "debug/debugger.h" +//include +#include "ags/shared/executingscript.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debug/debugger.h" namespace AGS3 { diff --git a/engines/ags/engine/script/executingscript.h b/engines/ags/engine/script/executingscript.h index ee4c7dfe656a..abbdab272390 100644 --- a/engines/ags/engine/script/executingscript.h +++ b/engines/ags/engine/script/executingscript.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_SCRIPT_EXECUTINGSCRIPT_H #define AGS_ENGINE_SCRIPT_EXECUTINGSCRIPT_H -#include "script/cc_instance.h" +#include "ags/engine/script/cc_instance.h" namespace AGS3 { @@ -49,7 +49,7 @@ enum ScriptInstType { }; struct QueuedScript { - Common::String FnName; + Shared::String FnName; ScriptInstType Instance; size_t ParamCount; RuntimeScriptValue Param1; diff --git a/engines/ags/engine/script/exports.cpp b/engines/ags/engine/script/exports.cpp index 3d067b951806..ff8d0987e44d 100644 --- a/engines/ags/engine/script/exports.cpp +++ b/engines/ags/engine/script/exports.cpp @@ -26,7 +26,7 @@ // //============================================================================= -#include "ac/gamestructdefines.h" +#include "ags/shared/ac/gamestructdefines.h" namespace AGS3 { diff --git a/engines/ags/engine/script/nonblockingscriptfunction.h b/engines/ags/engine/script/nonblockingscriptfunction.h index ad77689ea5d9..a7e982a1cd0e 100644 --- a/engines/ags/engine/script/nonblockingscriptfunction.h +++ b/engines/ags/engine/script/nonblockingscriptfunction.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_SCRIPT_NONBLOCKINGSCRIPTFUNCTION_H #define AGS_ENGINE_SCRIPT_NONBLOCKINGSCRIPTFUNCTION_H -#include "ac/runtime_defines.h" -#include "script/runtimescriptvalue.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/script/runtimescriptvalue.h" -#include +#include "ags/std/vector.h" namespace AGS3 { diff --git a/engines/ags/engine/script/runtimescriptvalue.cpp b/engines/ags/engine/script/runtimescriptvalue.cpp index 97f208099a38..2ac47d71cf65 100644 --- a/engines/ags/engine/script/runtimescriptvalue.cpp +++ b/engines/ags/engine/script/runtimescriptvalue.cpp @@ -20,13 +20,13 @@ * */ -#include "script/cc_error.h" -#include "script/runtimescriptvalue.h" -#include "ac/dynobj/cc_dynamicobject.h" -#include "ac/statobj/staticobject.h" -#include "util/memory.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/ac/dynobj/cc_dynamicobject.h" +#include "ags/shared/ac/statobj/staticobject.h" +#include "ags/shared/util/memory.h" -#include // for memcpy() +//include // for memcpy() namespace AGS3 { diff --git a/engines/ags/engine/script/runtimescriptvalue.h b/engines/ags/engine/script/runtimescriptvalue.h index 41ae8a5f4010..836290d5697e 100644 --- a/engines/ags/engine/script/runtimescriptvalue.h +++ b/engines/ags/engine/script/runtimescriptvalue.h @@ -29,9 +29,9 @@ #ifndef AGS_ENGINE_SCRIPT_RUNTIMESCRIPTVALUE_H #define AGS_ENGINE_SCRIPT_RUNTIMESCRIPTVALUE_H -#include "script/script_api.h" -#include "util/memory.h" -#include "ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/script/script_api.h" +#include "ags/shared/util/memory.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp index 52ddbdcff3cb..45d52a275402 100644 --- a/engines/ags/engine/script/script.cpp +++ b/engines/ags/engine/script/script.cpp @@ -20,37 +20,37 @@ * */ -#include -#include "script/script.h" -#include "ac/common.h" -#include "ac/character.h" -#include "ac/dialog.h" -#include "ac/event.h" -#include "ac/game.h" -#include "ac/gamesetupstruct.h" -#include "ac/gamestate.h" -#include "ac/global_audio.h" -#include "ac/global_character.h" -#include "ac/global_dialog.h" -#include "ac/global_display.h" -#include "ac/global_game.h" -#include "ac/global_gui.h" -#include "ac/global_hotspot.h" -#include "ac/global_object.h" -#include "ac/global_room.h" -#include "ac/invwindow.h" -#include "ac/mouse.h" -#include "ac/room.h" -#include "ac/roomobject.h" -#include "script/cc_error.h" -#include "script/cc_options.h" -#include "debug/debugger.h" -#include "debug/debug_log.h" -#include "main/game_run.h" -#include "media/video/video.h" -#include "script/script_runtime.h" -#include "util/string_compat.h" -#include "media/audio/audio_system.h" +//include +#include "ags/shared/script/script.h" +#include "ags/shared/ac/common.h" +#include "ags/shared/ac/character.h" +#include "ags/shared/ac/dialog.h" +#include "ags/shared/ac/event.h" +#include "ags/shared/ac/game.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/ac/gamestate.h" +#include "ags/shared/ac/global_audio.h" +#include "ags/shared/ac/global_character.h" +#include "ags/shared/ac/global_dialog.h" +#include "ags/shared/ac/global_display.h" +#include "ags/shared/ac/global_game.h" +#include "ags/shared/ac/global_gui.h" +#include "ags/shared/ac/global_hotspot.h" +#include "ags/shared/ac/global_object.h" +#include "ags/shared/ac/global_room.h" +#include "ags/shared/ac/invwindow.h" +#include "ags/shared/ac/mouse.h" +#include "ags/shared/ac/room.h" +#include "ags/shared/ac/roomobject.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/cc_options.h" +#include "ags/shared/debug/debugger.h" +#include "ags/shared/debug/debug_log.h" +#include "ags/shared/main/game_run.h" +#include "ags/shared/media/video/video.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/util/string_compat.h" +#include "ags/shared/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h index c61f3a357dda..8c797038cdc5 100644 --- a/engines/ags/engine/script/script.h +++ b/engines/ags/engine/script/script.h @@ -23,15 +23,15 @@ #ifndef AGS_ENGINE_SCRIPT_SCRIPT_H #define AGS_ENGINE_SCRIPT_SCRIPT_H -#include - -#include "game/roomstruct.h" // MAX_ROOM_OBJECTS -#include "script/cc_instance.h" -#include "script/executingscript.h" -#include "script/nonblockingscriptfunction.h" -#include "ac/dynobj/scriptsystem.h" -#include "game/interactions.h" -#include "util/string.h" +#include "ags/std/vector.h" + +#include "ags/shared/game/roomstruct.h" // MAX_ROOM_OBJECTS +#include "ags/engine/script/cc_instance.h" +#include "ags/engine/script/executingscript.h" +#include "ags/engine/script/nonblockingscriptfunction.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/shared/game/interactions.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp index da410e1389eb..50f37f883d00 100644 --- a/engines/ags/engine/script/script_api.cpp +++ b/engines/ags/engine/script/script_api.cpp @@ -20,13 +20,13 @@ * */ -#include -#include -#include "ac/game_version.h" -#include "script/cc_error.h" -#include "script/runtimescriptvalue.h" -#include "script/script_api.h" -#include "util/math.h" +//include +//include +#include "ags/shared/ac/game_version.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/util/math.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h index 04506a14af95..6cd64d87a048 100644 --- a/engines/ags/engine/script/script_api.h +++ b/engines/ags/engine/script/script_api.h @@ -30,11 +30,11 @@ #ifndef AGS_ENGINE_SCRIPT_SCRIPTAPI_H #define AGS_ENGINE_SCRIPT_SCRIPTAPI_H -#include -#include "core/types.h" -#include "ac/runtime_defines.h" -#include "ac/statobj/agsstaticobject.h" -#include "debug/out.h" +//include +#include "ags/shared/core/types.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/statobj/agsstaticobject.h" +#include "ags/shared/debugging/out.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script_engine.cpp b/engines/ags/engine/script/script_engine.cpp index 892b957ee07f..234ed39bd491 100644 --- a/engines/ags/engine/script/script_engine.cpp +++ b/engines/ags/engine/script/script_engine.cpp @@ -31,11 +31,11 @@ // //============================================================================= -#include -#include "script/cc_instance.h" -#include "script/cc_error.h" -#include "util/file.h" -#include "util/stream.h" +//include +#include "ags/shared/script/cc_instance.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp index d6eeeb827ad8..117162d359e4 100644 --- a/engines/ags/engine/script/script_runtime.cpp +++ b/engines/ags/engine/script/script_runtime.cpp @@ -34,16 +34,16 @@ // //============================================================================= -#include -#include -#include -#include "script/script_runtime.h" -#include "script/script_common.h" -#include "script/cc_error.h" -#include "script/cc_options.h" -#include "ac/dynobj/cc_dynamicarray.h" -#include "script/systemimports.h" -#include "ac/statobj/staticobject.h" +//include +//include +//include +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/script/script_common.h" +#include "ags/shared/script/cc_error.h" +#include "ags/shared/script/cc_options.h" +#include "ags/shared/ac/dynobj/cc_dynamicarray.h" +#include "ags/shared/script/systemimports.h" +#include "ags/shared/ac/statobj/staticobject.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h index 059f0dd6c5d6..3075282f3c11 100644 --- a/engines/ags/engine/script/script_runtime.h +++ b/engines/ags/engine/script/script_runtime.h @@ -37,8 +37,8 @@ #ifndef AGS_ENGINE_SCRIPT_SCRIPT_RUNTIME_H #define AGS_ENGINE_SCRIPT_SCRIPT_RUNTIME_H -#include "script/cc_script.h" // ccScript -#include "script/cc_instance.h" // ccInstance +#include "ags/shared/script/cc_script.h" // ccScript +#include "ags/engine/script/cc_instance.h" // ccInstance namespace AGS3 { diff --git a/engines/ags/engine/script/systemimports.cpp b/engines/ags/engine/script/systemimports.cpp index 1912f111a86c..850458aa5ae4 100644 --- a/engines/ags/engine/script/systemimports.cpp +++ b/engines/ags/engine/script/systemimports.cpp @@ -20,9 +20,9 @@ * */ -#include -#include -#include "script/systemimports.h" +//include +//include +#include "ags/shared/script/systemimports.h" namespace AGS3 { diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index aef575091dfb..7d8d9cb34c21 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H #define AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H -#include -#include "script/cc_instance.h" // ccInstance +//include +#include "ags/shared/script/cc_instance.h" // ccInstance namespace AGS3 { diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h index 4745bf1b43f4..41d53f5a431a 100644 --- a/engines/ags/engine/util/library.h +++ b/engines/ags/engine/util/library.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_UTIL_LIBRARY_H #define AGS_ENGINE_UTIL_LIBRARY_H -#include "core/platform.h" -#include "util/string.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/util/string.h" namespace AGS3 { namespace AGS { @@ -51,15 +51,15 @@ class BaseLibrary { } // namespace AGS3 #if AGS_PLATFORM_OS_WINDOWS -#include "library_windows.h" +#include "ags/shared/library_windows.h" #elif AGS_PLATFORM_OS_LINUX \ || AGS_PLATFORM_OS_MACOS \ || AGS_PLATFORM_OS_ANDROID -#include "library_posix.h" +#include "ags/shared/library_posix.h" #elif AGS_PLATFORM_OS_IOS -#include "library_dummy.h" +#include "ags/shared/library_dummy.h" #endif diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index 40220c6c8f78..53692c1f332c 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -23,10 +23,10 @@ #ifndef AGS_ENGINE_UTIL_LIBRARY_POSIX_H #define AGS_ENGINE_UTIL_LIBRARY_POSIX_H -#include -#include "core/platform.h" -#include "util/string.h" -#include "debug/out.h" +//include +#include "ags/shared/core/platform.h" +#include "ags/shared/util/string.h" +#include "ags/shared/debug/out.h" namespace AGS3 { diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h index b8098bbabc54..64bbdf1d1d55 100644 --- a/engines/ags/engine/util/library_psp.h +++ b/engines/ags/engine/util/library_psp.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_UTIL_LIBRARY_PSP_H #define AGS_ENGINE_UTIL_LIBRARY_PSP_H -#include -#include "util/string.h" -#include "debug/out.h" +//include +#include "ags/shared/util/string.h" +#include "ags/shared/debug/out.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h index 7695c93fd95c..4ce9b74e4157 100644 --- a/engines/ags/engine/util/library_windows.h +++ b/engines/ags/engine/util/library_windows.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_UTIL_LIBRARY_WINDOWS_H #define AGS_ENGINE_UTIL_LIBRARY_WINDOWS_H -#include "debug/out.h" -#include "platform/windows/winapi_exclusive.h" -#include "util/string.h" +#include "ags/shared/debug/out.h" +#include "ags/shared/platform/windows/winapi_exclusive.h" +#include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/util/mutex.h b/engines/ags/engine/util/mutex.h index e52534363802..0b21a9a6f0d7 100644 --- a/engines/ags/engine/util/mutex.h +++ b/engines/ags/engine/util/mutex.h @@ -23,11 +23,10 @@ #ifndef AGS_ENGINE_UTIL_MUTEX_H #define AGS_ENGINE_UTIL_MUTEX_H +namespace AGS3 { namespace AGS { namespace Engine { -namespace AGS3 { - class BaseMutex { public: BaseMutex() = default; @@ -50,7 +49,7 @@ class BaseMutex { #if 0 // insert platforms here #else -#include "mutex_std.h" +#include "ags/engine/util/mutex_std.h" #endif #endif diff --git a/engines/ags/engine/util/mutex_lock.h b/engines/ags/engine/util/mutex_lock.h index c772fdb9a508..38d3cdd88ec0 100644 --- a/engines/ags/engine/util/mutex_lock.h +++ b/engines/ags/engine/util/mutex_lock.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_UTIL_MUTEX_LOCK_H #define AGS_ENGINE_UTIL_MUTEX_LOCK_H -#include "util/mutex.h" +#include "ags/engine/util/mutex.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/mutex_psp.h b/engines/ags/engine/util/mutex_psp.h index 15cb079d2e81..b8e3187123b3 100644 --- a/engines/ags/engine/util/mutex_psp.h +++ b/engines/ags/engine/util/mutex_psp.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_UTIL_PSP_MUTEX_H #define AGS_ENGINE_UTIL_PSP_MUTEX_H -#include -#include -#include +//include +//include +//include namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/mutex_pthread.h b/engines/ags/engine/util/mutex_pthread.h index 53efb21759d6..afc66f6d6c9f 100644 --- a/engines/ags/engine/util/mutex_pthread.h +++ b/engines/ags/engine/util/mutex_pthread.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_UTIL_MUTEX_PTHREAD_H #define AGS_ENGINE_UTIL_MUTEX_PTHREAD_H -#include +//include namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/mutex_std.h b/engines/ags/engine/util/mutex_std.h index abe1f8f2c39d..41ab31ea262b 100644 --- a/engines/ags/engine/util/mutex_std.h +++ b/engines/ags/engine/util/mutex_std.h @@ -23,7 +23,8 @@ #ifndef AGS_ENGINE_UTIL_MUTEX_STD_H #define AGS_ENGINE_UTIL_MUTEX_STD_H -#include +#include "ags/engine/util/mutex.h" +#include "ags/std/mutex.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/mutex_wii.h b/engines/ags/engine/util/mutex_wii.h index 1930a32c3c71..4073bd8642c8 100644 --- a/engines/ags/engine/util/mutex_wii.h +++ b/engines/ags/engine/util/mutex_wii.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_UTIL_WII_MUTEX_H #define AGS_ENGINE_UTIL_WII_MUTEX_H -#include +//include namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/scaling.h b/engines/ags/engine/util/scaling.h index b0f980b14d17..d79e8a92df3a 100644 --- a/engines/ags/engine/util/scaling.h +++ b/engines/ags/engine/util/scaling.h @@ -32,8 +32,8 @@ #ifndef AGS_ENGINE_UTIL_SCALING_H #define AGS_ENGINE_UTIL_SCALING_H -#include "core/types.h" -#include "util/geometry.h" +#include "ags/shared/core/types.h" +#include "ags/shared/util/geometry.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/thread.h b/engines/ags/engine/util/thread.h index b69a8b7139a4..356122734ee0 100644 --- a/engines/ags/engine/util/thread.h +++ b/engines/ags/engine/util/thread.h @@ -56,7 +56,7 @@ class BaseThread { #if 0 // insert platforms here #else -#include "thread_std.h" +#include "ags/engine/util/thread_std.h" #endif diff --git a/engines/ags/engine/util/thread_psp.h b/engines/ags/engine/util/thread_psp.h index 6785275b10e2..4e2a96747834 100644 --- a/engines/ags/engine/util/thread_psp.h +++ b/engines/ags/engine/util/thread_psp.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_UTIL_PSP_THREAD_H #define AGS_ENGINE_UTIL_PSP_THREAD_H -#include -#include -#include +//include +//include +//include namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/thread_pthread.h b/engines/ags/engine/util/thread_pthread.h index 83108f5c6e63..66b73e80b63e 100644 --- a/engines/ags/engine/util/thread_pthread.h +++ b/engines/ags/engine/util/thread_pthread.h @@ -28,8 +28,7 @@ namespace AGS3 { namespace AGS { namespace Engine { - -class PThreadThread : public BaseThread { +//include -#include +//include +#include "ags/engine/util/thread.h" +#include "ags/std/thread.h" namespace AGS3 { namespace AGS { @@ -60,11 +61,11 @@ class StdThread : public BaseThread { return false; } - try { +// try { thread_ = std::thread(thread_start_, this); - } catch (std::system_error) { - return false; - } +// } catch (std::system_error) { +// return false; +// } return thread_.joinable(); } diff --git a/engines/ags/engine/util/thread_wii.h b/engines/ags/engine/util/thread_wii.h index 5b61d5dec978..633b7a521b51 100644 --- a/engines/ags/engine/util/thread_wii.h +++ b/engines/ags/engine/util/thread_wii.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_UTIL_THREAD_WII_H #define AGS_ENGINE_UTIL_THREAD_WII_H -#include +//include namespace AGS3 { namespace AGS { diff --git a/engines/ags/lib/allegro.h b/engines/ags/lib/allegro.h index 09d26765d7c5..662c67395882 100644 --- a/engines/ags/lib/allegro.h +++ b/engines/ags/lib/allegro.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_H -#define AGS_STUBS_ALLEGRO_H +#ifndef ALLEGRO_H +#define ALLEGRO_H #include "ags/lib/allegro/alconfig.h" #include "ags/lib/allegro/base.h" diff --git a/engines/ags/lib/allegro/alconfig.h b/engines/ags/lib/allegro/alconfig.h index 88a154b8ea7d..c6dc71b84f32 100644 --- a/engines/ags/lib/allegro/alconfig.h +++ b/engines/ags/lib/allegro/alconfig.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_ALCONFIG_H -#define AGS_STUBS_ALLEGRO_ALCONFIG_H +#ifndef AGS_LIB_ALLEGRO_ALCONFIG_H +#define AGS_LIB_ALLEGRO_ALCONFIG_H namespace AGS3 { diff --git a/engines/ags/lib/allegro/base.h b/engines/ags/lib/allegro/base.h index e5cf5bb16876..88a91e082edb 100644 --- a/engines/ags/lib/allegro/base.h +++ b/engines/ags/lib/allegro/base.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_BASE_H -#define AGS_STUBS_ALLEGRO_BASE_H +#ifndef AGS_LIB_ALLEGRO_BASE_H +#define AGS_LIB_ALLEGRO_BASE_H #include "common/scummsys.h" #include "common/algorithm.h" diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index d08762f8de3b..ddb7ae1e8d6e 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_COLOR_H -#define AGS_STUBS_ALLEGRO_COLOR_H +#ifndef AGS_LIB_ALLEGRO_COLOR_H +#define AGS_LIB_ALLEGRO_COLOR_H #include "common/scummsys.h" #include "ags/lib/allegro/alconfig.h" diff --git a/engines/ags/lib/allegro/config.h b/engines/ags/lib/allegro/config.h index 5695ea0eda17..53526c3eb646 100644 --- a/engines/ags/lib/allegro/config.h +++ b/engines/ags/lib/allegro/config.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_CONFIG_H -#define AGS_STUBS_ALLEGRO_CONFIG_H +#ifndef AGS_LIB_ALLEGRO_CONFIG_H +#define AGS_LIB_ALLEGRO_CONFIG_H namespace AGS3 { diff --git a/engines/ags/lib/allegro/digi.h b/engines/ags/lib/allegro/digi.h index 7eeaa723828f..1ffe0bdc2425 100644 --- a/engines/ags/lib/allegro/digi.h +++ b/engines/ags/lib/allegro/digi.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_DIGI_H -#define AGS_STUBS_ALLEGRO_DIGI_H +#ifndef AGS_LIB_ALLEGRO_DIGI_H +#define AGS_LIB_ALLEGRO_DIGI_H #include "common/scummsys.h" #include "ags/lib/allegro/base.h" diff --git a/engines/ags/lib/allegro/error.h b/engines/ags/lib/allegro/error.h index 7a5aeb627ab5..c7942c9eda23 100644 --- a/engines/ags/lib/allegro/error.h +++ b/engines/ags/lib/allegro/error.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_ERROR_H -#define AGS_STUBS_ALLEGRO_ERROR_H +#ifndef AGS_LIB_ALLEGRO_ERROR_H +#define AGS_LIB_ALLEGRO_ERROR_H #include "common/scummsys.h" diff --git a/engines/ags/lib/allegro/file.h b/engines/ags/lib/allegro/file.h index 083e8d1db36d..0e2a490032b4 100644 --- a/engines/ags/lib/allegro/file.h +++ b/engines/ags/lib/allegro/file.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_FILE_H -#define AGS_STUBS_ALLEGRO_FILE_H +#ifndef AGS_LIB_ALLEGRO_FILE_H +#define AGS_LIB_ALLEGRO_FILE_H namespace AGS3 { diff --git a/engines/ags/lib/allegro/fixed.h b/engines/ags/lib/allegro/fixed.h index fa1e456b123e..f8692ee9cfc5 100644 --- a/engines/ags/lib/allegro/fixed.h +++ b/engines/ags/lib/allegro/fixed.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_FIXED_H -#define AGS_STUBS_ALLEGRO_FIXED_H +#ifndef AGS_LIB_ALLEGRO_FIXED_H +#define AGS_LIB_ALLEGRO_FIXED_H #include "common/scummsys.h" diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index cf2402acb2c6..737ddb3802cf 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_GRAPHICS_H -#define AGS_STUBS_ALLEGRO_GRAPHICS_H +#ifndef AGS_LIB_ALLEGRO_GRAPHICS_H +#define AGS_LIB_ALLEGRO_GRAPHICS_H #include "graphics/managed_surface.h" #include "ags/lib/allegro/base.h" diff --git a/engines/ags/lib/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h index 8f8d0da14fb1..cd6d804ec31f 100644 --- a/engines/ags/lib/allegro/keyboard.h +++ b/engines/ags/lib/allegro/keyboard.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_KEYBOARD_H -#define AGS_STUBS_ALLEGRO_KEYBOARD_H +#ifndef AGS_LIB_ALLEGRO_KEYBOARD_H +#define AGS_LIB_ALLEGRO_KEYBOARD_H #include "common/keyboard.h" @@ -31,9 +31,13 @@ namespace AGS3 { #define KB_CTRL_FLAG Common::KBD_CTRL #define KB_ALT_FLAG Common::KBD_ALT -#define KEY_F9 Common::KEYCODE_F9 +#define KEY_LSHIFT Common::KEYCODE_LSHIFT +#define KEY_RSHIFT Common::KEYCODE_RSHIFT +#define KEY_ALT Common::KEYCODE_LALT #define KEY_LCONTROL Common::KEYCODE_LCTRL #define KEY_RCONTROL Common::KEYCODE_RCTRL +#define KEY_ALTGR 0 +#define KEY_F9 Common::KEYCODE_F9 #define __allegro_KEY_LSHIFT Common::KEYCODE_LSHIFT #define __allegro_KEY_RSHIFT Common::KEYCODE_RSHIFT @@ -94,7 +98,6 @@ namespace AGS3 { #define __allegro_KEY_NUMLOCK Common::KEYCODE_NUMLOCK #define __allegro_KEY_CAPSLOCK Common::KEYCODE_CAPSLOCK - extern bool key[Common::KEYCODE_LAST]; extern int install_keyboard(); diff --git a/engines/ags/lib/allegro/midi.h b/engines/ags/lib/allegro/midi.h index 66a89f0aba78..8f474995e169 100644 --- a/engines/ags/lib/allegro/midi.h +++ b/engines/ags/lib/allegro/midi.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_MIDI_H -#define AGS_STUBS_ALLEGRO_MIDI_H +#ifndef AGS_LIB_ALLEGRO_MIDI_H +#define AGS_LIB_ALLEGRO_MIDI_H #include "common/scummsys.h" #include "ags/lib/allegro/base.h" diff --git a/engines/ags/lib/allegro/mouse.h b/engines/ags/lib/allegro/mouse.h index 3ad8998f773f..a063b7e7eabc 100644 --- a/engines/ags/lib/allegro/mouse.h +++ b/engines/ags/lib/allegro/mouse.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_MOUSE_H -#define AGS_STUBS_ALLEGRO_MOUSE_H +#ifndef AGS_LIB_ALLEGRO_MOUSE_H +#define AGS_LIB_ALLEGRO_MOUSE_H #include "common/events.h" #include "ags/lib/allegro/base.h" diff --git a/engines/ags/lib/allegro/sound.h b/engines/ags/lib/allegro/sound.h index d487041039e9..bc4790c9ac78 100644 --- a/engines/ags/lib/allegro/sound.h +++ b/engines/ags/lib/allegro/sound.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_SOUND_H -#define AGS_STUBS_ALLEGRO_SOUND_H +#ifndef AGS_LIB_ALLEGRO_SOUND_H +#define AGS_LIB_ALLEGRO_SOUND_H #include "common/scummsys.h" #include "ags/lib/allegro/base.h" diff --git a/engines/ags/lib/allegro/system.h b/engines/ags/lib/allegro/system.h index f461d00195f7..fbd1f104295a 100644 --- a/engines/ags/lib/allegro/system.h +++ b/engines/ags/lib/allegro/system.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_SYSTEM_H -#define AGS_STUBS_ALLEGRO_SYSTEM_H +#ifndef AGS_LIB_ALLEGRO_SYSTEM_H +#define AGS_LIB_ALLEGRO_SYSTEM_H #include "ags/lib/allegro/base.h" #include "ags/lib/allegro/color.h" diff --git a/engines/ags/lib/allegro/unicode.h b/engines/ags/lib/allegro/unicode.h index 48667d7f8a58..a17ab6d9f7a6 100644 --- a/engines/ags/lib/allegro/unicode.h +++ b/engines/ags/lib/allegro/unicode.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_STUBS_ALLEGRO_UNICODE_H -#define AGS_STUBS_ALLEGRO_UNICODE_H +#ifndef AGS_LIB_ALLEGRO_UNICODE_H +#define AGS_LIB_ALLEGRO_UNICODE_H #include "ags/lib/allegro/base.h" diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 4c650f9b43f3..ad3dda27ddf7 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -76,8 +76,16 @@ MODULE_OBJS = \ shared/util/textstreamreader.o \ shared/util/textstreamwriter.o \ shared/util/version.o \ - shared/util/wgt2allg.o - + shared/util/wgt2allg.o \ + engine/main/config.o \ + engine/main/engine.o \ + engine/main/engine_setup.o \ + engine/main/game_file.o \ + engine/main/game_run.o \ + engine/main/game_start.o \ + engine/main/graphics_mode.o \ + engine/main/quit.o \ + engine/main/update.o # This module can be built as a plugin ifeq ($(ENABLE_AGS), DYNAMIC_PLUGIN) diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index af10c29ccf99..3d47eea2799a 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -67,7 +67,7 @@ struct GameSetupStruct : public GameSetupStructBase { // TODO: why we do not use this in the engine instead of // loaded_game_file_version? int filever; // just used by editor - Common::String compiled_with; // version of AGS this data was created by + Shared::String compiled_with; // version of AGS this data was created by char lipSyncFrameLetters[MAXLIPSYNCFRAMES][50]; AGS::Shared::PropertySchema propSchema; std::vector charProps; @@ -75,9 +75,9 @@ struct GameSetupStruct : public GameSetupStructBase { // NOTE: although the view names are stored in game data, they are never // used, nor registered as script exports; numeric IDs are used to // reference views instead. - std::vector viewNames; - Common::String invScriptNames[MAX_INV]; - std::vector dialogScriptNames; + std::vector viewNames; + Shared::String invScriptNames[MAX_INV]; + std::vector dialogScriptNames; char guid[MAX_GUID_LENGTH]; char saveGameFileExtension[MAX_SG_EXT_LENGTH]; char saveGameFolderName[MAX_SG_FOLDER_LEN]; diff --git a/engines/ags/shared/font/agsfontrenderer.h b/engines/ags/shared/font/agsfontrenderer.h index be77d8223887..03daf322b6a3 100644 --- a/engines/ags/shared/font/agsfontrenderer.h +++ b/engines/ags/shared/font/agsfontrenderer.h @@ -25,7 +25,7 @@ namespace AGS3 { -struct BITMAP; +class BITMAP; // WARNING: this interface is exposed for plugins and declared for the second time in agsplugin.h class IAGSFontRenderer { diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index 6ddbf9367079..7ea092b11a5d 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -431,7 +431,7 @@ HRoomFileError ReadObjScNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion return new RoomFileError(kRoomFileErr_InconsistentData, String::FromFormat("In the object script names block, expected name count: %d, got %d", room->ObjectCount, name_count)); - for (size_t i = 0; i < room->ObjectCount; ++i) { + for (size_t i = 0; i < (size_t)room->ObjectCount; ++i) { if (data_ver >= kRoomVersion_3415) room->Objects[i].ScriptName = StrUtil::ReadString(in); else diff --git a/engines/ags/shared/util/path.h b/engines/ags/shared/util/path.h index a78782e4edd1..9afee49861e9 100644 --- a/engines/ags/shared/util/path.h +++ b/engines/ags/shared/util/path.h @@ -30,6 +30,7 @@ #define AGS_SHARED_UTIL_PATH_H #include "ags/shared/util/string.h" +#include "common/fs.h" namespace AGS3 { namespace AGS { @@ -83,6 +84,11 @@ String FixupSharedFilename(const String &filename); String GetPathInASCII(const String &path); // Converts filepath from command line's argument into ASCII variant String GetCmdLinePathInASCII(const char *arg, int arg_index); + +inline String get_filename(const String &pathAndName) { + return Common::FSNode(pathAndName).getName(); +} + } // namespace Path } // namespace Shared diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index 33cfd0ac3c6c..ae9063c1a375 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -339,8 +339,9 @@ class String { inline bool operator <(const char *cstr) const { return Compare(cstr) < 0; } - Common::String operator()() const { - return Common::String(GetCStr()); + // Converts an AGS string to a ScummVM one + operator Common::String() const { + return Common::String(GetNullableCStr()); } private: diff --git a/engines/ags/std/initializer_list.h b/engines/ags/std/initializer_list.h new file mode 100644 index 000000000000..0b07f56eaa0a --- /dev/null +++ b/engines/ags/std/initializer_list.h @@ -0,0 +1,68 @@ +/* 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 AGS_STD_INITIALIZER_LIST_H +#define AGS_STD_INITIALIZER_LIST_H + +namespace AGS3 { +namespace std { + +// CLASS TEMPLATE initializer_list +template +class initializer_list { +public: + using value_type = _Elem; + using reference = const _Elem &; + using const_reference = const _Elem &; + using size_type = size_t; + + using iterator = const _Elem *; + using const_iterator = const _Elem *; + + constexpr initializer_list() : _First(nullptr), _Last(nullptr) { + } + + constexpr initializer_list(const _Elem *_First_arg, const _Elem *_Last_arg) noexcept + : _First(_First_arg), _Last(_Last_arg) { + } + + constexpr const _Elem *begin() const { + return _First; + } + + constexpr const _Elem *end() const { + return _Last; + } + + constexpr size_t size() const { + return static_cast(_Last - _First); + } + +private: + const _Elem *_First; + const _Elem *_Last; +}; + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/xtr1common.h b/engines/ags/std/xtr1common.h new file mode 100644 index 000000000000..c17c0ba6635d --- /dev/null +++ b/engines/ags/std/xtr1common.h @@ -0,0 +1,46 @@ +/* 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 AGS_STD_XTR1COMMON_H +#define AGS_STD_XTR1COMMON_H + +namespace AGS3 { +namespace std { + +// STRUCT TEMPLATE conditional +template +struct conditional { // Choose _Ty1 if _Test is true, and _Ty2 otherwise + using type = _Ty1; +}; + +template +struct conditional { + using type = _Ty2; +}; + +template +using conditional_t = typename conditional<_Test, _Ty1, _Ty2>::type; + +} // namespace std +} // namespace AGS3 + +#endif From 8c2a877dc56f5abb34e489b03b115b4c896fe5c0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Nov 2020 17:40:04 -0800 Subject: [PATCH 021/215] AGS: Added engine/gui/ folder --- engines/ags/engine/gui/animatingguibutton.cpp | 2 +- engines/ags/engine/gui/animatingguibutton.h | 5 +- engines/ags/engine/gui/cscidialog.cpp | 40 ++++++------- engines/ags/engine/gui/cscidialog.h | 2 +- engines/ags/engine/gui/gui_engine.cpp | 8 +-- engines/ags/engine/gui/guidialog.cpp | 60 +++++++------------ engines/ags/engine/gui/guidialog.h | 4 +- engines/ags/engine/gui/guidialogdefines.h | 2 +- .../ags/engine/gui/guidialoginternaldefs.h | 2 +- engines/ags/engine/gui/mycontrols.h | 8 +-- engines/ags/engine/gui/mylabel.cpp | 12 ++-- engines/ags/engine/gui/mylabel.h | 4 +- engines/ags/engine/gui/mylistbox.cpp | 8 +-- engines/ags/engine/gui/mylistbox.h | 2 +- engines/ags/engine/gui/mypushbutton.cpp | 14 ++--- engines/ags/engine/gui/mypushbutton.h | 2 +- engines/ags/engine/gui/mytextbox.cpp | 4 +- engines/ags/engine/gui/mytextbox.h | 2 +- engines/ags/engine/gui/newcontrol.cpp | 6 +- engines/ags/engine/media/audio/audio.h | 2 +- engines/ags/module.mk | 9 +++ engines/ags/shared/game/room_file.cpp | 2 +- engines/ags/shared/util/wgt2allg.h | 1 + 23 files changed, 96 insertions(+), 105 deletions(-) diff --git a/engines/ags/engine/gui/animatingguibutton.cpp b/engines/ags/engine/gui/animatingguibutton.cpp index 8534a9ced2cc..88d55b0ed022 100644 --- a/engines/ags/engine/gui/animatingguibutton.cpp +++ b/engines/ags/engine/gui/animatingguibutton.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/gui/animatingguibutton.h" +#include "ags/engine/gui/animatingguibutton.h" #include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/animatingguibutton.h b/engines/ags/engine/gui/animatingguibutton.h index 4fcaacadd921..1a0053601a28 100644 --- a/engines/ags/engine/gui/animatingguibutton.h +++ b/engines/ags/engine/gui/animatingguibutton.h @@ -31,8 +31,9 @@ namespace AGS3 { namespace AGS { namespace Shared { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later struct AnimatingGUIButton { diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index 89929fb4ed93..25f4c7db1869 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -23,25 +23,25 @@ //include #include "ags/shared/util/wgt2allg.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/gamesetup.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/keycode.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/runtime_defines.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/keycode.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/runtime_defines.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/gui/cscidialog.h" -#include "ags/shared/gui/guidialog.h" +#include "ags/engine/gui/cscidialog.h" +#include "ags/engine/gui/guidialog.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/gui/mycontrols.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/gui/mycontrols.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/timer.h" namespace AGS3 { @@ -275,15 +275,15 @@ void multiply_up(int *x1, int *y1, int *x2, int *y2) { int checkcontrols() { // NOTE: this is because old code was working with full game screen - const int mousex = ::mousex - win_x; - const int mousey = ::mousey - win_y; + const int mouseX = AGS3::mousex - win_x; + const int mouseY = AGS3::mousey - win_y; smcode = 0; for (int kk = 0; kk < MAXCONTROLS; kk++) { if (vobjs[kk] != nullptr) { - if (vobjs[kk]->mouseisinarea(mousex, mousey)) { + if (vobjs[kk]->mouseisinarea(mouseX, mouseY)) { controlid = kk; - return vobjs[kk]->pressedon(mousex, mousey); + return vobjs[kk]->pressedon(mouseX, mouseY); } } } diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h index 05b5057b9015..5a360b1faaa5 100644 --- a/engines/ags/engine/gui/cscidialog.h +++ b/engines/ags/engine/gui/cscidialog.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GUI_CSCIDIALOG_H #define AGS_ENGINE_GUI_CSCIDIALOG_H -#include "ags/shared/gui/guidialoginternaldefs.h" +#include "ags/engine/gui/guidialoginternaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp index 1644445c469e..97258f53ae1e 100644 --- a/engines/ags/engine/gui/gui_engine.cpp +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -29,7 +29,7 @@ // Headers, as they are in acgui.cpp #pragma unmanaged #include "ags/shared/ac/game_version.h" -#include "ags/shared/ac/system.h" +#include "ags/engine/ac/system.h" #include "ags/shared/font/fonts.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guibutton.h" @@ -38,11 +38,11 @@ #include "ags/shared/gui/guitextbox.h" //include #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/string.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/blender.h" +#include "ags/engine/gfx/blender.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index 261a43e17de6..d2d2b7111134 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -21,18 +21,20 @@ */ //include -#include "ags/shared/gui/guidialog.h" +#include "ags/engine/gui/guidialog.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/gui/cscidialog.h" +#include "ags/engine/gui/cscidialog.h" //include //isdigit() #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/debugging/debug_log.h" +#include "engines/savestate.h" +#include "ags/ags.h" namespace AGS3 { @@ -295,46 +297,24 @@ int savegamedialog() { void preparesavegamelist(int ctrllist) { numsaves = 0; toomanygames = 0; - al_ffblk ffb; - int bufix = 0; - - String svg_dir = get_save_game_directory(); - String svg_suff = get_save_game_suffix(); - String searchPath = String::FromFormat("%s""agssave.*%s", svg_dir.GetCStr(), svg_suff.GetCStr()); - - int don = al_findfirst(searchPath, &ffb, -1); - while (!don) { - bufix = 0; - if (numsaves >= MAXSAVEGAMES) { - toomanygames = 1; - break; - } - // only list games .000 to .099 (to allow higher slots for other purposes) - if (strstr(ffb.name, ".0") == nullptr) { - don = al_findnext(&ffb); - continue; - } + // Get a list of savegames + SaveStateList saveList = ::AGS::g_vm->listSaves(); - const char *numberExtension = strstr(ffb.name, ".0") + 1; - int sgNumber = atoi(numberExtension); + for (SaveStateList::iterator it = saveList.begin(); it != saveList.end(); ++it) { + Common::String desc = it->getDescription(); - String thisGamePath = get_save_game_path(sgNumber); + // TODO: Casting pointer to long is nasty + CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)desc.c_str()); - // get description - String description; - read_savedgame_description(thisGamePath, description); - - CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)description.GetCStr()); // Select the first item CSCISendControlMessage(ctrllist, CLB_SETCURSEL, 0, 0); - filenumbers[numsaves] = sgNumber; - filedates[numsaves] = (long int)ffb.time; - numsaves++; - don = al_findnext(&ffb); + filenumbers[numsaves] = it->getSaveSlot(); + filedates[numsaves] = 0; // TODO: How to handle file dates in ScummVM + + ++numsaves; } - al_findclose(&ffb); if (numsaves >= MAXSAVEGAMES) toomanygames = 1; @@ -442,7 +422,7 @@ int roomSelectorWindow(int currentRoom, int numRooms, int *roomNumbers, char **r if (mes.code == CM_COMMAND) { if (mes.id == ctrlok) { CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); - if (isdigit(buffer2[0])) { + if (Common::isDigit(buffer2[0])) { toret = atoi(buffer2); } } else if (mes.id == ctrlcancel) { diff --git a/engines/ags/engine/gui/guidialog.h b/engines/ags/engine/gui/guidialog.h index dcca3af214a7..32d45ca77efc 100644 --- a/engines/ags/engine/gui/guidialog.h +++ b/engines/ags/engine/gui/guidialog.h @@ -27,8 +27,8 @@ namespace AGS3 { namespace AGS { namespace Shared { class Bitmap; -} -} +} // namespace Shared +} // namespace AGS // Functions for handling hard-coded GUIs // Prepares GUI bitmaps which will be passed to the renderer's draw chain diff --git a/engines/ags/engine/gui/guidialogdefines.h b/engines/ags/engine/gui/guidialogdefines.h index 45404757b37a..851257e110c6 100644 --- a/engines/ags/engine/gui/guidialogdefines.h +++ b/engines/ags/engine/gui/guidialogdefines.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_GUIDIALOGDEFINES_H #define AGS_ENGINE_GUI_GUIDIALOGDEFINES_H -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/gamesetup.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/guidialoginternaldefs.h b/engines/ags/engine/gui/guidialoginternaldefs.h index 22c53733178d..ea363da5d8f5 100644 --- a/engines/ags/engine/gui/guidialoginternaldefs.h +++ b/engines/ags/engine/gui/guidialoginternaldefs.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_GUIDIALOGINTERNALDEFS_H #define AGS_ENGINE_GUI_GUIDIALOGINTERNALDEFS_H -#include "ags/shared/gui/guidialogdefines.h" +#include "ags/engine/gui/guidialogdefines.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mycontrols.h b/engines/ags/engine/gui/mycontrols.h index 5a1abee69459..46b492cb8560 100644 --- a/engines/ags/engine/gui/mycontrols.h +++ b/engines/ags/engine/gui/mycontrols.h @@ -29,9 +29,9 @@ #ifndef AGS_ENGINE_GUI_MYCONTROLS_H #define AGS_ENGINE_GUI_MYCONTROLS_H -#include "ags/shared/gui/mylabel.h" -#include "ags/shared/gui/mylistbox.h" -#include "ags/shared/gui/mypushbutton.h" -#include "ags/shared/gui/mytextbox.h" +#include "ags/engine/gui/mylabel.h" +#include "ags/engine/gui/mylistbox.h" +#include "ags/engine/gui/mypushbutton.h" +#include "ags/engine/gui/mytextbox.h" #endif diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp index 8af6ee072986..69a330b9844d 100644 --- a/engines/ags/engine/gui/mylabel.cpp +++ b/engines/ags/engine/gui/mylabel.cpp @@ -21,13 +21,13 @@ */ //include -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/gamesetup.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/engine/ac/string.h" #include "ags/shared/font/fonts.h" #include "ags/shared/gui/guidefines.h" -#include "ags/shared/gui/mylabel.h" -#include "ags/shared/gui/guidialoginternaldefs.h" +#include "ags/engine/gui/mylabel.h" +#include "ags/engine/gui/guidialoginternaldefs.h" namespace AGS3 { @@ -59,7 +59,7 @@ void MyLabel::draw(Bitmap *ds) { } } -int MyLabel::pressedon(int mousex, int mousey) { +int MyLabel::pressedon(int mouseX, int mouseY) { return 0; } diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h index b0b5ec733e1f..67cdc5508269 100644 --- a/engines/ags/engine/gui/mylabel.h +++ b/engines/ags/engine/gui/mylabel.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_MYLABEL_H #define AGS_ENGINE_GUI_MYLABEL_H -#include "ags/shared/gui/newcontrol.h" +#include "ags/engine/gui/newcontrol.h" namespace AGS3 { @@ -33,7 +33,7 @@ struct MyLabel : public NewControl { void draw(Shared::Bitmap *ds) override; - int pressedon(int mousex, int mousey) override; + int pressedon(int mouseX, int mouseY) override; int processmessage(int mcode, int wParam, long lParam) override; }; diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index 07e6ec1951dc..339cabce1011 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -23,12 +23,12 @@ //include #include "ags/shared/util/wgt2allg.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/font/fonts.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gui/guidialog.h" -#include "ags/shared/gui/guidialoginternaldefs.h" -#include "ags/shared/gui/mylistbox.h" +#include "ags/engine/gui/guidialog.h" +#include "ags/engine/gui/guidialoginternaldefs.h" +#include "ags/engine/gui/mylistbox.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h index 4c54e317fa7d..b70b45ee4f15 100644 --- a/engines/ags/engine/gui/mylistbox.h +++ b/engines/ags/engine/gui/mylistbox.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_MYLISTBOX_H #define AGS_ENGINE_GUI_MYLISTBOX_H -#include "ags/shared/gui/newcontrol.h" +#include "ags/engine/gui/newcontrol.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index 6cdf81386be1..7f462063e676 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -23,15 +23,15 @@ //include #include "ags/shared/util/wgt2allg.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/mouse.h" +#include "ags/engine/ac/mouse.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/gui/mypushbutton.h" -#include "ags/shared/gui/guidialog.h" -#include "ags/shared/gui/guidialoginternaldefs.h" -#include "ags/shared/main/game_run.h" +#include "ags/engine/gui/mypushbutton.h" +#include "ags/engine/gui/guidialog.h" +#include "ags/engine/gui/guidialoginternaldefs.h" +#include "ags/engine/main/game_run.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h index 55696560211f..2ba6ca11ca25 100644 --- a/engines/ags/engine/gui/mypushbutton.h +++ b/engines/ags/engine/gui/mypushbutton.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_PUSHBUTTON_H #define AGS_ENGINE_GUI_PUSHBUTTON_H -#include "ags/shared/gui/newcontrol.h" +#include "ags/engine/gui/newcontrol.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp index 898e8d7432b1..b0d45b02180b 100644 --- a/engines/ags/engine/gui/mytextbox.cpp +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -23,8 +23,8 @@ //include #include "ags/shared/util/wgt2allg.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/gui/mytextbox.h" -#include "ags/shared/gui/guidialoginternaldefs.h" +#include "ags/engine/gui/mytextbox.h" +#include "ags/engine/gui/guidialoginternaldefs.h" #include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h index 46f9e7728baa..a2a3e7d16623 100644 --- a/engines/ags/engine/gui/mytextbox.h +++ b/engines/ags/engine/gui/mytextbox.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GUI_MYTEXTBOX_H #define AGS_ENGINE_GUI_MYTEXTBOX_H -#include "ags/shared/gui/newcontrol.h" +#include "ags/engine/gui/newcontrol.h" namespace AGS3 { diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp index 6337fddbce6d..57f593ec5459 100644 --- a/engines/ags/engine/gui/newcontrol.cpp +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -20,9 +20,9 @@ * */ -#include "ags/shared/gui/newcontrol.h" -#include "ags/shared/gui/guidialog.h" -#include "ags/shared/gui/guidialoginternaldefs.h" +#include "ags/engine/gui/newcontrol.h" +#include "ags/engine/gui/guidialog.h" +#include "ags/engine/gui/guidialoginternaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index 69d4bc71a4fe..42471bfd7608 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -156,7 +156,7 @@ extern int crossFadeVolumeAtStart; extern SOUNDCLIP *cachedQueuedMusic; // TODO: double check that ambient sounds array actually needs +1 -extern std::array ambient(MAX_SOUND_CHANNELS + 1); +extern std::array ambient; } // namespace AGS3 diff --git a/engines/ags/module.mk b/engines/ags/module.mk index ad3dda27ddf7..86ff892941ba 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -77,6 +77,15 @@ MODULE_OBJS = \ shared/util/textstreamwriter.o \ shared/util/version.o \ shared/util/wgt2allg.o \ + engine/gui/animatingguibutton.o \ + engine/gui/cscidialog.o \ + engine/gui/guidialog.o \ + engine/gui/gui_engine.o \ + engine/gui/mylabel.o \ + engine/gui/mylistbox.o \ + engine/gui/mypushbutton.o \ + engine/gui/mytextbox.o \ + engine/gui/newcontrol.o \ engine/main/config.o \ engine/main/engine.o \ engine/main/engine_setup.o \ diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index 7ea092b11a5d..b39bb7059d4b 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -427,7 +427,7 @@ HRoomFileError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion d // Room object script names HRoomFileError ReadObjScNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) { int name_count = in->ReadByte(); - if (name_count != room->ObjectCount) + if (name_count != (int)room->ObjectCount) return new RoomFileError(kRoomFileErr_InconsistentData, String::FromFormat("In the object script names block, expected name count: %d, got %d", room->ObjectCount, name_count)); diff --git a/engines/ags/shared/util/wgt2allg.h b/engines/ags/shared/util/wgt2allg.h index 6126da9591c1..4ac8a969eda7 100644 --- a/engines/ags/shared/util/wgt2allg.h +++ b/engines/ags/shared/util/wgt2allg.h @@ -34,6 +34,7 @@ #define _WGT45_ #include "ags/shared/core/platform.h" +#include "ags/shared/core/types.h" #include "ags/lib/allegro.h" namespace AGS3 { From ee277279e6b450d77186e54ba1d7d304e2fce977 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Nov 2020 18:35:52 -0800 Subject: [PATCH 022/215] AGS: Added engine/game/ folder --- engines/ags/engine/ac/asset_helper.h | 5 +- engines/ags/engine/ac/characterextras.h | 5 +- engines/ags/engine/ac/draw.h | 8 +- .../ags/engine/ac/dynobj/all_dynamicclasses.h | 24 +++--- .../ags/engine/ac/dynobj/all_scriptclasses.h | 30 +++---- engines/ags/engine/ac/dynobj/cc_character.h | 2 +- engines/ags/engine/ac/dynobj/cc_dialog.h | 2 +- .../ags/engine/ac/dynobj/cc_dynamicobject.h | 5 +- engines/ags/engine/ac/dynobj/cc_gui.h | 2 +- engines/ags/engine/ac/dynobj/cc_guiobject.h | 6 +- engines/ags/engine/ac/dynobj/cc_hotspot.h | 2 +- engines/ags/engine/ac/dynobj/cc_inventory.h | 2 +- engines/ags/engine/ac/dynobj/cc_object.h | 2 +- engines/ags/engine/ac/dynobj/cc_region.h | 2 +- engines/ags/engine/ac/dynobj/cc_serializer.h | 2 +- .../ac/dynobj/scriptdialogoptionsrendering.h | 2 +- .../engine/ac/dynobj/scriptdynamicsprite.h | 2 +- engines/ags/engine/ac/movelist.h | 1 + engines/ags/engine/ac/statobj/staticarray.h | 2 +- engines/ags/engine/device/mousew32.h | 8 +- engines/ags/engine/game/game_init.cpp | 46 +++++----- engines/ags/engine/game/savegame.cpp | 84 +++++++++++-------- .../ags/engine/game/savegame_components.cpp | 44 +++++----- engines/ags/engine/game/savegame_components.h | 3 +- engines/ags/engine/game/savegame_internal.h | 4 +- engines/ags/engine/game/viewport.cpp | 8 +- engines/ags/engine/media/audio/ambientsound.h | 5 +- engines/ags/engine/util/thread_pthread.h | 3 +- engines/ags/module.mk | 4 + 29 files changed, 174 insertions(+), 141 deletions(-) diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index 84604052ed40..7c6160af7bd1 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -38,8 +38,9 @@ namespace AGS3 { namespace AGS { namespace Shared { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using AGS::Shared::Stream; using AGS::Shared::String; diff --git a/engines/ags/engine/ac/characterextras.h b/engines/ags/engine/ac/characterextras.h index 906282b5f594..67e6e568c24d 100644 --- a/engines/ags/engine/ac/characterextras.h +++ b/engines/ags/engine/ac/characterextras.h @@ -31,8 +31,9 @@ namespace AGS3 { namespace AGS { namespace Shared { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later struct CharacterExtras { diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index 42437b6f9de3..03901e7884f6 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -35,11 +35,13 @@ namespace AGS { namespace Shared { class Bitmap; typedef std::shared_ptr PBitmap; -} +} // namespace Shared + namespace Engine { class IDriverDependantBitmap; -} -} +} // namespace Engine +} // namespace AGS + using namespace AGS; // FIXME later #define IS_ANTIALIAS_SPRITES usetup.enable_antialiasing && (play.disable_antialiasing == 0) diff --git a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h index f597b28a477f..da01ed1ce190 100644 --- a/engines/ags/engine/ac/dynobj/all_dynamicclasses.h +++ b/engines/ags/engine/ac/dynobj/all_dynamicclasses.h @@ -23,18 +23,18 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_ALLDYNAMICCLASSES_H #define AGS_ENGINE_AC_DYNOBJ_ALLDYNAMICCLASSES_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" -#include "ags/shared/ac/dynobj/cc_audiochannel.h" -#include "ags/shared/ac/dynobj/cc_audioclip.h" -#include "ags/shared/ac/dynobj/cc_character.h" -#include "ags/shared/ac/dynobj/cc_dialog.h" -#include "ags/shared/ac/dynobj/cc_gui.h" -#include "ags/shared/ac/dynobj/cc_guiobject.h" -#include "ags/shared/ac/dynobj/cc_hotspot.h" -#include "ags/shared/ac/dynobj/cc_inventory.h" -#include "ags/shared/ac/dynobj/cc_object.h" -#include "ags/shared/ac/dynobj/cc_region.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_audiochannel.h" +#include "ags/engine/ac/dynobj/cc_audioclip.h" +#include "ags/engine/ac/dynobj/cc_character.h" +#include "ags/engine/ac/dynobj/cc_dialog.h" +#include "ags/engine/ac/dynobj/cc_gui.h" +#include "ags/engine/ac/dynobj/cc_guiobject.h" +#include "ags/engine/ac/dynobj/cc_hotspot.h" +#include "ags/engine/ac/dynobj/cc_inventory.h" +#include "ags/engine/ac/dynobj/cc_object.h" +#include "ags/engine/ac/dynobj/cc_region.h" -#include "ags/shared/ac/dynobj/cc_serializer.h" +#include "ags/engine/ac/dynobj/cc_serializer.h" #endif diff --git a/engines/ags/engine/ac/dynobj/all_scriptclasses.h b/engines/ags/engine/ac/dynobj/all_scriptclasses.h index 7c3c72b9c5f6..5d533fa9b93d 100644 --- a/engines/ags/engine/ac/dynobj/all_scriptclasses.h +++ b/engines/ags/engine/ac/dynobj/all_scriptclasses.h @@ -23,20 +23,20 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_ALLSCRIPTCLASSES_H #define AGS_ENGINE_AC_DYNOBJ_ALLSCRIPTCLASSES_H -#include "ags/shared/ac/dynobj/scriptdatetime.h" -#include "ags/shared/ac/dynobj/scriptdialog.h" -#include "ags/shared/ac/dynobj/scriptdialogoptionsrendering.h" -#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" -#include "ags/shared/ac/dynobj/scriptdynamicsprite.h" -#include "ags/shared/ac/dynobj/scriptgui.h" -#include "ags/shared/ac/dynobj/scripthotspot.h" -#include "ags/shared/ac/dynobj/scriptinvitem.h" -#include "ags/shared/ac/dynobj/scriptmouse.h" -#include "ags/shared/ac/dynobj/scriptobject.h" -#include "ags/shared/ac/dynobj/scriptoverlay.h" -#include "ags/shared/ac/dynobj/scriptregion.h" -#include "ags/shared/ac/dynobj/scriptstring.h" -#include "ags/shared/ac/dynobj/scriptsystem.h" -#include "ags/shared/ac/dynobj/scriptviewframe.h" +#include "ags/engine/ac/dynobj/scriptdatetime.h" +#include "ags/engine/ac/dynobj/scriptdialog.h" +#include "ags/engine/ac/dynobj/scriptdialogoptionsrendering.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" +#include "ags/engine/ac/dynobj/scriptdynamicsprite.h" +#include "ags/engine/ac/dynobj/scriptgui.h" +#include "ags/engine/ac/dynobj/scripthotspot.h" +#include "ags/engine/ac/dynobj/scriptinvitem.h" +#include "ags/engine/ac/dynobj/scriptmouse.h" +#include "ags/engine/ac/dynobj/scriptobject.h" +#include "ags/engine/ac/dynobj/scriptoverlay.h" +#include "ags/engine/ac/dynobj/scriptregion.h" +#include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/engine/ac/dynobj/scriptviewframe.h" #endif diff --git a/engines/ags/engine/ac/dynobj/cc_character.h b/engines/ags/engine/ac/dynobj/cc_character.h index b75cd6a3518d..8c800ec8465e 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.h +++ b/engines/ags/engine/ac/dynobj/cc_character.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCCHARACTER_H #define AGS_ENGINE_AC_DYNOBJ_CCCHARACTER_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.h b/engines/ags/engine/ac/dynobj/cc_dialog.h index a7c4954af529..061892734d57 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.h +++ b/engines/ags/engine/ac/dynobj/cc_dialog.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCDIALOG_H #define AGS_ENGINE_AC_DYNOBJ_CCDIALOG_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index 8e73a593f3a4..469aaa35033c 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -38,8 +38,9 @@ namespace AGS3 { namespace AGS { namespace Shared { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later // A pair of managed handle and abstract object pointer diff --git a/engines/ags/engine/ac/dynobj/cc_gui.h b/engines/ags/engine/ac/dynobj/cc_gui.h index c33862580797..311684d65654 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.h +++ b/engines/ags/engine/ac/dynobj/cc_gui.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCGUI_H #define AGS_ENGINE_AC_DYNOBJ_CCGUI_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.h b/engines/ags/engine/ac/dynobj/cc_guiobject.h index 4da35e13944a..6f1911e867d4 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.h +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.h @@ -20,10 +20,10 @@ * */ -#ifndef AGS_ENGINE_AC_DYNOBJ_CCGUI_H -#define AGS_ENGINE_AC_DYNOBJ_CCGUI_H +#ifndef AGS_ENGINE_AC_DYNOBJ_CCGUIOBJECT_H +#define AGS_ENGINE_AC_DYNOBJ_CCGUIOBJECT_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.h b/engines/ags/engine/ac/dynobj/cc_hotspot.h index 3a1beb8e618c..1677a4929582 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.h +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCHOTSPOT_H #define AGS_ENGINE_AC_DYNOBJ_CCHOTSPOT_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.h b/engines/ags/engine/ac/dynobj/cc_inventory.h index 10edec6e0ce1..0687ebb54ceb 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.h +++ b/engines/ags/engine/ac/dynobj/cc_inventory.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCINVENTORY_H #define AGS_ENGINE_AC_DYNOBJ_CCINVENTORY_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_object.h b/engines/ags/engine/ac/dynobj/cc_object.h index 789e8c196f08..a6d77cc759ce 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.h +++ b/engines/ags/engine/ac/dynobj/cc_object.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCOBJECT_H #define AGS_ENGINE_AC_DYNOBJ_CCOBJECT_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_region.h b/engines/ags/engine/ac/dynobj/cc_region.h index c0a21cffd4e0..927b2e874b40 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.h +++ b/engines/ags/engine/ac/dynobj/cc_region.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCREGION_H #define AGS_ENGINE_AC_DYNOBJ_CCREGION_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h index 2d16667228df..54458ead27c3 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.h +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCSERIALIZER_H #define AGS_ENGINE_AC_DYNOBJ_CCSERIALIZER_H -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h index 7a6bdf2d8d64..43d34d9f2cf9 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOGOPTIONSRENDERING_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDIALOGOPTIONSRENDERING_H -#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h index 3418840f0508..82bb60d7f3bf 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDYNAMICSPRITE_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDYNAMICSPRITE_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/movelist.h b/engines/ags/engine/ac/movelist.h index b950ffe44b1f..d9672b1d80b4 100644 --- a/engines/ags/engine/ac/movelist.h +++ b/engines/ags/engine/ac/movelist.h @@ -34,6 +34,7 @@ namespace Shared { class Stream; } // namespace Shared } // namespace AGS + using namespace AGS; // FIXME later #define MAXNEEDSTAGES 256 diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h index 3940708f1083..6176dc438451 100644 --- a/engines/ags/engine/ac/statobj/staticarray.h +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -23,7 +23,7 @@ #ifndef _AGS_ENGINE_AC_STATICOBJ_STATICARRAY_H #define _AGS_ENGINE_AC_STATICOBJ_STATICARRAY_H -#include "ags/shared/ac/statobj/staticobject.h" +#include "ags/engine/ac/statobj/staticobject.h" namespace AGS3 { diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h index 6662320676df..87185517de44 100644 --- a/engines/ags/engine/device/mousew32.h +++ b/engines/ags/engine/device/mousew32.h @@ -61,6 +61,7 @@ void msethotspot(int xx, int yy); int minstalled(); namespace Mouse { + // Get if mouse is locked to the game window bool IsLockedToWindow(); // Try locking mouse to the game window @@ -82,9 +83,11 @@ float GetSpeedUnit(); void SetSpeed(float speed); // Get speed factor float GetSpeed(); -} + +} // namespace Mouse namespace Mouse { + // Updates limits of the area inside which the standard OS cursor is not shown; // uses game's main viewport (in native coordinates) to calculate real area on screen void SetGraphicArea(); @@ -93,7 +96,8 @@ void SetGraphicArea(); void SetMoveLimit(const Rect &r); // Set actual OS cursor position on screen; parameter must be in native game coordinates void SetPosition(const Point p); -} + +} // namespace Mouse extern int mousex, mousey; diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp index 3836f46af7d1..8de53db9a165 100644 --- a/engines/ags/engine/game/game_init.cpp +++ b/engines/ags/engine/game/game_init.cpp @@ -20,36 +20,36 @@ * */ -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/charactercache.h" -#include "ags/shared/ac/dialog.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/file.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/engine/ac/dialog.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/file.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/movelist.h" -#include "ags/shared/ac/dynobj/all_dynamicclasses.h" -#include "ags/shared/ac/dynobj/all_scriptclasses.h" -#include "ags/shared/ac/statobj/agsstaticobject.h" -#include "ags/shared/ac/statobj/staticarray.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/out.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/movelist.h" +#include "ags/engine/ac/dynobj/all_dynamicclasses.h" +#include "ags/engine/ac/dynobj/all_scriptclasses.h" +#include "ags/engine/ac/statobj/agsstaticobject.h" +#include "ags/engine/ac/statobj/staticarray.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/font/agsfontrenderer.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/game/game_init.h" +#include "ags/engine/game/game_init.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/ddb.h" +#include "ags/engine/gfx/ddb.h" #include "ags/shared/gui/guilabel.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/script/cc_error.h" -#include "ags/shared/script/exports.h" -#include "ags/shared/script/script.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/script/exports.h" +#include "ags/engine/script/script.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/util/string_utils.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index cc8f5bbd8820..b9678c25e6d2 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -20,47 +20,48 @@ * */ -#include "ags/shared/ac/character.h" +#include "ags/engine/ac/character.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/dynamicsprite.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/dynamicsprite.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/gamesetup.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/region.h" -#include "ags/shared/ac/richgamemedia.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomstatus.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/region.h" +#include "ags/engine/ac/richgamemedia.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomstatus.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/timer.h" -#include "ags/shared/debug/out.h" -#include "ags/shared/device/mousew32.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/timer.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/device/mousew32.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/ddb.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/game/savegame.h" -#include "ags/shared/game/savegame_components.h" -#include "ags/shared/game/savegame_internal.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/main/main.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" -#include "ags/shared/script/script.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/game/savegame.h" +#include "ags/engine/game/savegame_components.h" +#include "ags/engine/game/savegame_internal.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/main.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" +#include "ags/engine/script/script.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/util/alignedstream.h" #include "ags/shared/util/file.h" #include "ags/shared/util/stream.h" #include "ags/shared/util/string_utils.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/ags.h" namespace AGS3 { @@ -507,7 +508,7 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) // ensure that the current cursor is locked spriteset.Precache(game.mcurs[r_data.CursorID].pic); - set_window_title(play.game_name); + ::AGS::g_vm->set_window_title(play.game_name); update_polled_stuff_if_runtime(); @@ -680,8 +681,16 @@ void WriteDescription(Stream *out, const String &user_text, const Bitmap *user_i WriteSaveImage(out, user_image); } +static void uconvert(const char *src, unsigned short *dest, int maxSize) { + do { + *dest++ = *src; + } while (*src++ != 0 && --maxSize > 1); + + *dest = '\0'; +} + PStream StartSavegame(const String &filename, const String &user_text, const Bitmap *user_image) { - Stream *out = Common::File::CreateFile(filename); + Stream *out = Shared::File::CreateFile(filename); if (!out) return PStream(); @@ -695,8 +704,15 @@ PStream StartSavegame(const String &filename, const String &user_text, const Bit vistaHeader.dwThumbnailOffsetLowerDword = 0; vistaHeader.dwThumbnailSize = 0; convert_guid_from_text_to_binary(game.guid, &vistaHeader.guidGameId[0]); + +#if 1 + Common::String name = Common::String::format("%s %s", game.gamename, user_text.GetNullableCStr()); + uconvert(name.c_str(), vistaHeader.szSaveName, RM_MAXLENGTH); +#else uconvert(game.gamename, U_ASCII, (char *)&vistaHeader.szGameName[0], U_UNICODE, RM_MAXLENGTH); uconvert(user_text, U_ASCII, (char *)&vistaHeader.szSaveName[0], U_UNICODE, RM_MAXLENGTH); +#endif + vistaHeader.szLevelName[0] = 0; vistaHeader.szComments[0] = 0; // MS Windows Vista rich media header diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index 1e558819f995..55c30b441738 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -23,29 +23,29 @@ //include #include "ags/shared/ac/audiocliptype.h" -#include "ags/shared/ac/character.h" +#include "ags/engine/ac/character.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/dialogtopic.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/dynamicsprite.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/dynamicsprite.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/movelist.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/screenoverlay.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/movelist.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/screenoverlay.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/dynobj/cc_serializer.h" -#include "ags/shared/debug/out.h" -#include "ags/shared/game/savegame_components.h" -#include "ags/shared/game/savegame_internal.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/dynobj/cc_serializer.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/game/savegame_components.h" +#include "ags/engine/game/savegame_internal.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gui/animatingguibutton.h" +#include "ags/engine/gui/animatingguibutton.h" #include "ags/shared/gui/guibutton.h" #include "ags/shared/gui/guiinv.h" #include "ags/shared/gui/guilabel.h" @@ -53,12 +53,12 @@ #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guislider.h" #include "ags/shared/gui/guitextbox.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/script/cc_error.h" -#include "ags/shared/script/script.h" +#include "ags/engine/script/script.h" #include "ags/shared/util/filestream.h" // TODO: needed only because plugins expect file handle -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { @@ -1183,7 +1183,7 @@ HSaveError ReadComponent(PStream in, SvgCmpReadHelper &hlp, ComponentInfo &info) const ComponentHandler *handler = nullptr; std::map::const_iterator it_hdr = hlp.Handlers.find(info.Name); if (it_hdr != hlp.Handlers.end()) - handler = &it_hdr->second; + handler = &it_hdr->_value; if (!handler || !handler->Unserialize) return new SavegameError(kSvgErr_UnsupportedComponent); diff --git a/engines/ags/engine/game/savegame_components.h b/engines/ags/engine/game/savegame_components.h index 18cfb46a6fcc..db3b2b444235 100644 --- a/engines/ags/engine/game/savegame_components.h +++ b/engines/ags/engine/game/savegame_components.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GAME_SAVEGAMECOMPONENTS_H #define AGS_ENGINE_GAME_SAVEGAMECOMPONENTS_H -#include "ags/shared/game/savegame.h" +#include "ags/engine/game/savegame.h" #include "ags/shared/util/stream.h" namespace AGS3 { @@ -60,5 +60,6 @@ void ReadLegacyCameraState(Stream *in, RestoredData &r_data); } // namespace Engine } // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index 713c662d9d64..5db638911e01 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -27,13 +27,13 @@ #include "ags/std/vector.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/media/audio/audiodefines.h" +#include "ags/engine/media/audio/audiodefines.h" namespace AGS3 { namespace AGS { namespace Engine { -using AGS::Shared::Bitmap; +using Shared::Bitmap; typedef std::shared_ptr PBitmap; diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp index cc5415f8b377..c4484dd765d8 100644 --- a/engines/ags/engine/game/viewport.cpp +++ b/engines/ags/engine/game/viewport.cpp @@ -20,11 +20,11 @@ * */ -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/game/viewport.h" +#include "ags/engine/game/viewport.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/ambientsound.h b/engines/ags/engine/media/audio/ambientsound.h index 3d042ccb98c6..fe24a81ce7d7 100644 --- a/engines/ags/engine/media/audio/ambientsound.h +++ b/engines/ags/engine/media/audio/ambientsound.h @@ -29,8 +29,9 @@ namespace AGS3 { namespace AGS { namespace Shared { class Stream; -} -} +} // namespace Shared +} // namespace AGS + using namespace AGS; // FIXME later #define AMBIENCE_FULL_DIST 25 diff --git a/engines/ags/engine/util/thread_pthread.h b/engines/ags/engine/util/thread_pthread.h index 66b73e80b63e..83108f5c6e63 100644 --- a/engines/ags/engine/util/thread_pthread.h +++ b/engines/ags/engine/util/thread_pthread.h @@ -28,7 +28,8 @@ namespace AGS3 { namespace AGS { namespace Engine { -//include Date: Mon, 23 Nov 2020 18:38:42 -0800 Subject: [PATCH 023/215] AGS: Added engine/font/ folder --- engines/ags/module.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index da2c5b061217..e8c6b7639ac2 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -77,6 +77,7 @@ MODULE_OBJS = \ shared/util/textstreamwriter.o \ shared/util/version.o \ shared/util/wgt2allg.o \ + engine/font/fonts_engine.o \ engine/game/game_init.o \ engine/game/savegame.o \ engine/game/savegame_components.o \ From 797404be98d0b72716b6d215d66aff946acdc41c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Nov 2020 19:39:48 -0800 Subject: [PATCH 024/215] AGS: Added engine/platform/ folder --- engines/ags/engine/main/game_start.cpp | 8 +- .../platform/base/agsplatformdriver.cpp | 52 ++++++------ .../engine/platform/base/agsplatformdriver.h | 8 +- engines/ags/lib/allegro.h | 4 +- engines/ags/lib/allegro/keyboard.h | 1 + engines/ags/lib/system/datetime.cpp | 80 +++++++++++++++++++ engines/ags/lib/system/datetime.h | 50 ++++++++++++ engines/ags/module.mk | 8 +- engines/ags/std/thread.h | 7 ++ 9 files changed, 184 insertions(+), 34 deletions(-) create mode 100644 engines/ags/lib/system/datetime.cpp create mode 100644 engines/ags/lib/system/datetime.h diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index df57f42753ca..681ee8f85886 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -125,7 +125,7 @@ void do_start_game() { } void initialize_start_and_play_game(int override_start_room, const char *loadSaveOnStartup) { - try { // BEGIN try for ALI3DEXception +// try { // BEGIN try for ALI3DEXception set_cursor_mode(MODE_WALK); @@ -154,9 +154,9 @@ void initialize_start_and_play_game(int override_start_room, const char *loadSav RunGameUntilAborted(); - } catch (Ali3DException gfxException) { - quit((char *)gfxException._message); - } +// } catch (Ali3DException gfxException) { +// quit((char *)gfxException._message); +// } } } // namespace AGS3 diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index 0d0a624ffc8a..11d4e585eb18 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -26,27 +26,28 @@ // //============================================================================= -//include #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/runtime_defines.h" +#include "ags/engine/ac/runtime_defines.h" #include "ags/shared/util/string_utils.h" #include "ags/shared/util/stream.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/ac/timer.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/ac/timer.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/lib/system/datetime.h" +#include "ags/std/algorithm.h" + +#if defined (AGS_HAS_CD_AUDIO) +#include "libcda.h" +#endif namespace AGS3 { using namespace AGS::Shared; using namespace AGS::Engine; -#if defined (AGS_HAS_CD_AUDIO) -#include "ags/shared/libcda.h" -#endif - // We don't have many places where we delay longer than a frame, but where we // do, we should give the audio layer a chance to update. // 16 milliseconds is rough period for 60fps @@ -99,36 +100,37 @@ const char *AGSPlatformDriver::GetDiskWriteAccessTroubleshootingText() { } void AGSPlatformDriver::GetSystemTime(ScriptDateTime *sdt) { - time_t t = time(nullptr); + time_t t = getUnixTime(); //note: subject to year 2038 problem due to shoving time_t in an integer sdt->rawUnixTime = static_cast(t); - struct tm *newtime = localtime(&t); - sdt->hour = newtime->tm_hour; - sdt->minute = newtime->tm_min; - sdt->second = newtime->tm_sec; - sdt->day = newtime->tm_mday; - sdt->month = newtime->tm_mon + 1; - sdt->year = newtime->tm_year + 1900; + tm newTime; + localTime(&newTime); + sdt->hour = newTime.tm_hour; + sdt->minute = newTime.tm_min; + sdt->second = newTime.tm_sec; + sdt->day = newTime.tm_mday; + sdt->month = newTime.tm_mon + 1; + sdt->year = newTime.tm_year + 1900; } void AGSPlatformDriver::WriteStdOut(const char *fmt, ...) { va_list args; va_start(args, fmt); - vprintf(fmt, args); + Common::String str = Common::String::vformat(fmt, args); va_end(args); - printf("\n"); - fflush(stdout); + + debug("%s\n", str.c_str()); } void AGSPlatformDriver::WriteStdErr(const char *fmt, ...) { va_list args; va_start(args, fmt); - vfprintf(stderr, fmt, args); + Common::String str = Common::String::vformat(fmt, args); va_end(args); - fprintf(stderr, "\n"); - fflush(stdout); + + debug("ERROR: %s\n", str.c_str()); } void AGSPlatformDriver::YieldCPU() { @@ -242,7 +244,7 @@ void AGSPlatformDriver::Delay(int millis) { break; } - auto duration = std::min(delayUntil - now, MaximumDelayBetweenPolling); + auto duration = std::min(delayUntil - now, MaximumDelayBetweenPolling); std::this_thread::sleep_for(duration); now = AGS_Clock::now(); // update now diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 4363cb7fbb7a..5a2023c6cc6d 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -40,11 +40,13 @@ namespace AGS3 { namespace AGS { namespace Shared { class Stream; -} +} // namespace Shared + namespace Engine { struct DisplayMode; -} -} +} // namespace Engine +} // namespace AGS + using namespace AGS; // FIXME later enum eScriptSystemOSID { diff --git a/engines/ags/lib/allegro.h b/engines/ags/lib/allegro.h index 662c67395882..4667540d0f96 100644 --- a/engines/ags/lib/allegro.h +++ b/engines/ags/lib/allegro.h @@ -20,7 +20,9 @@ * */ -#ifndef ALLEGRO_H +#ifndef AGS_LIB_ALLEGRO_H +#define AGS_LIB_ALLEGRO_H + #define ALLEGRO_H #include "ags/lib/allegro/alconfig.h" diff --git a/engines/ags/lib/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h index cd6d804ec31f..06187120f679 100644 --- a/engines/ags/lib/allegro/keyboard.h +++ b/engines/ags/lib/allegro/keyboard.h @@ -38,6 +38,7 @@ namespace AGS3 { #define KEY_RCONTROL Common::KEYCODE_RCTRL #define KEY_ALTGR 0 #define KEY_F9 Common::KEYCODE_F9 +#define KEY_A Common::KEYCODE_a #define __allegro_KEY_LSHIFT Common::KEYCODE_LSHIFT #define __allegro_KEY_RSHIFT Common::KEYCODE_RSHIFT diff --git a/engines/ags/lib/system/datetime.cpp b/engines/ags/lib/system/datetime.cpp new file mode 100644 index 000000000000..e95978d0dd66 --- /dev/null +++ b/engines/ags/lib/system/datetime.cpp @@ -0,0 +1,80 @@ +/* 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 "ags/lib/system/datetime.h" + +namespace AGS3 { + +/* + * Converts a date/time structure to Unix timestamp + * @author Oryx Embedded SARL (www.oryx-embedded.com) + * @version 2.0.0 + */ +time_t convertDateToUnixTime(const TimeDate *date) { + uint y; + uint m; + uint d; + time_t t; + + // Year + y = date->tm_year; + // Month of year + m = date->tm_mon; + // Day of month + d = date->tm_mday; + + // January and February are counted as months 13 and 14 of the previous year + if (m <= 2) { + m += 12; + y -= 1; + } + + // Convert years to days + t = (365 * y) + (y / 4) - (y / 100) + (y / 400); + // Convert months to days + t += (30 * m) + (3 * (m + 1) / 5) + d; + // Unix time starts on January 1st, 1970 + t -= 719561; + // Convert days to seconds + t *= 86400; + // Add hours, minutes and seconds + t += (3600 * date->tm_hour) + (60 * date->tm_min) + date->tm_sec; + + // Return Unix time + return t; +} + +void localTime(tm *time) { + g_system->getTimeAndDate(*time); + + time->tm_yday = 0; + time->tm_isdst = 0; +} + +time_t getUnixTime() { + tm time; + localTime(&time); + + return convertDateToUnixTime(&time); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/system/datetime.h b/engines/ags/lib/system/datetime.h new file mode 100644 index 000000000000..ba2bea9880c7 --- /dev/null +++ b/engines/ags/lib/system/datetime.h @@ -0,0 +1,50 @@ +/* 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 AGS_LIB_SYSTEM_DATETIME_H +#define AGS_LIB_SYSTEM_DATETIME_H + +#include "common/scummsys.h" +#include "common/system.h" + +namespace AGS3 { + +struct tm : public TimeDate { + int tm_yday; // days since January 1 - [0, 365] + int tm_isdst; // daylight savings time flag +}; + +typedef int64 time_t; + +/** + * Returns the current date and time + */ +extern void localTime(tm *time); + +/** + * Returns the Unix 2038-end time + */ +extern time_t getUnixTime(); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk index e8c6b7639ac2..47674e664289 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -20,6 +20,7 @@ MODULE_OBJS = \ lib/allegro/sound.o \ lib/allegro/system.o \ lib/allegro/unicode.o \ + lib/system/datetime.o \ shared/ac/dynobj/scriptaudioclip.o \ shared/ac/audiocliptype.o \ shared/ac/characterinfo.o \ @@ -99,7 +100,12 @@ MODULE_OBJS = \ engine/main/game_start.o \ engine/main/graphics_mode.o \ engine/main/quit.o \ - engine/main/update.o + engine/main/update.o \ + engine/platform/base/agsplatformdriver.o \ + engine/platform/windows/acplwin.o \ + engine/platform/windows/minidump.o \ + engine/platform/windows/win_ex_handling.o + # This module can be built as a plugin ifeq ($(ENABLE_AGS), DYNAMIC_PLUGIN) diff --git a/engines/ags/std/thread.h b/engines/ags/std/thread.h index 46be465c51bb..53455e9dd05f 100644 --- a/engines/ags/std/thread.h +++ b/engines/ags/std/thread.h @@ -23,6 +23,7 @@ #ifndef AGS_STD_THREAD_H #define AGS_STD_THREAD_H +#include "ags/std/chrono.h" #include "common/textconsole.h" namespace AGS3 { @@ -53,6 +54,12 @@ class this_thread { static void yield() { warning("TODO: this_thread::yield"); } + + static void sleep_for(uint32 milli) { + g_system->delayMillis(milli); + } +// template +// static void sleep_for(const chrono::duration &rel_time); }; } // namespace std From e05f33bec2675e9fec269d92c01cf51d80754c18 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Nov 2020 19:58:57 -0800 Subject: [PATCH 025/215] AGS: Added engine/plugin/ folder --- .../cc_dynamicobject_addr_and_manager.h | 4 +- engines/ags/engine/gfx/gfx_util.h | 2 +- engines/ags/engine/gui/gui_engine.cpp | 2 +- engines/ags/engine/plugin/agsplugin.cpp | 104 +++++++++--------- engines/ags/engine/plugin/library.cpp | 44 ++++++++ engines/ags/engine/plugin/library.h | 40 +++++++ engines/ags/engine/plugin/plugin_builtin.h | 2 - .../ags/engine/plugin/pluginobjectreader.cpp | 4 +- engines/ags/engine/util/library.h | 4 +- engines/ags/engine/util/library_posix.h | 3 +- engines/ags/lib/allegro/color.cpp | 23 ++++ engines/ags/lib/allegro/color.h | 7 ++ engines/ags/lib/allegro/gfx.cpp | 4 + engines/ags/lib/allegro/gfx.h | 1 + engines/ags/module.mk | 4 +- 15 files changed, 182 insertions(+), 66 deletions(-) create mode 100644 engines/ags/engine/plugin/library.cpp create mode 100644 engines/ags/engine/plugin/library.h diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h index 416284c8120b..91830bee0e55 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_ADDR_AND_MANAGER_H #define AGS_ENGINE_AC_DYNOBJ_ADDR_AND_MANAGER_H -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfx_util.h b/engines/ags/engine/gfx/gfx_util.h index 7e8f1e6f0372..c0ce244f9088 100644 --- a/engines/ags/engine/gfx/gfx_util.h +++ b/engines/ags/engine/gfx/gfx_util.h @@ -53,7 +53,7 @@ Bitmap *ConvertBitmap(Bitmap *src, int dst_color_depth); // or fallbacks to common "magic pink" transparency mode; // optionally uses blending alpha (overall image transparency). void DrawSpriteBlend(Bitmap *ds, const Point &ds_at, Bitmap *sprite, - Common::BlendMode blend_mode, bool dst_has_alpha = true, bool src_has_alpha = true, int blend_alpha = 0xFF); + Shared::BlendMode blend_mode, bool dst_has_alpha = true, bool src_has_alpha = true, int blend_alpha = 0xFF); // Draws a bitmap over another one with given alpha level (0 - 255), // takes account of the bitmap's mask color, diff --git a/engines/ags/engine/gui/gui_engine.cpp b/engines/ags/engine/gui/gui_engine.cpp index 97258f53ae1e..3a76b334fc26 100644 --- a/engines/ags/engine/gui/gui_engine.cpp +++ b/engines/ags/engine/gui/gui_engine.cpp @@ -27,7 +27,7 @@ //============================================================================= // Headers, as they are in acgui.cpp -#pragma unmanaged +//pragma unmanaged #include "ags/shared/ac/game_version.h" #include "ags/engine/ac/system.h" #include "ags/shared/font/fonts.h" diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 5837511a6cb7..6019f9525de6 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -28,58 +28,52 @@ #include "ags/shared/util/wgt2allg.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/charactercache.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/dynamicsprite.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/dynamicsprite.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_plugin.h" -#include "ags/shared/ac/global_walkablearea.h" -#include "ags/shared/ac/keycode.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/movelist.h" -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/parser.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject_addr_and_manager.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_plugin.h" +#include "ags/engine/ac/global_walkablearea.h" +#include "ags/engine/ac/keycode.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/movelist.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/parser.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h" #include "ags/shared/font/fonts.h" #include "ags/shared/util/string_compat.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/device/mousew32.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/device/mousew32.h" #include "ags/shared/gui/guidefines.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" -#include "ags/shared/plugin/plugin_builtin.h" -#include "ags/shared/plugin/pluginobjectreader.h" -#include "ags/shared/script/script.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" +#include "ags/engine/plugin/plugin_builtin.h" +#include "ags/engine/plugin/pluginobjectreader.h" +#include "ags/engine/script/script.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/util/stream.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/gfx/gfxfilter.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/debug/out.h" -#include "ags/shared/ac/dynobj/scriptstring.h" -#include "ags/shared/main/graphics_mode.h" -#include "ags/shared/gfx/gfx_util.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/gfx/gfxfilter.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/gfx/gfx_util.h" #include "ags/shared/util/memory.h" #include "ags/shared/util/filestream.h" -#include "ags/shared/media/audio/audio_system.h" - -namespace AGS3 { - -using namespace AGS::Shared; -using namespace AGS::Shared::Memory; -using namespace AGS::Engine; - +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/util/library.h" #if defined(BUILTIN_PLUGINS) #include "ags/shared/../Plugins/AGSflashlight/agsflashlight.h" @@ -92,6 +86,11 @@ using namespace AGS::Engine; #endif // AGS_PLATFORM_OS_IOS #endif // BUILTIN_PLUGINS +namespace AGS3 { + +using namespace AGS::Shared; +using namespace AGS::Shared::Memory; +using namespace AGS::Engine; extern IGraphicsDriver *gfxDriver; extern int mousex, mousey; @@ -117,9 +116,6 @@ extern ScriptString myScriptStringImpl; // **************** PLUGIN IMPLEMENTATION **************** -#include "ags/shared/util/library.h" - - struct EnginePlugin { @@ -260,7 +256,7 @@ unsigned char **IAGSEngine::GetRawBitmapSurface(BITMAP *bmp) { if (stage && bmp == stage->GetAllegroBitmap()) plugins[this->pluginId].invalidatedRegion = 0; - return bmp->line; + return (unsigned char **)bmp->getPixels(); } void IAGSEngine::ReleaseBitmapSurface(BITMAP *bmp) { @@ -554,7 +550,7 @@ void IAGSEngine::PrintDebugConsole(const char *text) { platform->WriteStdOut("[PLUGIN] %s", text); } int IAGSEngine::IsChannelPlaying(int32 channel) { - return ::IsChannelPlaying(channel); + return AGS3::IsChannelPlaying(channel); } void IAGSEngine::PlaySoundChannel(int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename) { stop_and_destroy_channel(channel); @@ -752,19 +748,19 @@ void IAGSEngine::AddManagedObjectReader(const char *typeName, IAGSManagedObjectR numPluginReaders++; } -void IAGSEngine::RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback) { +void IAGSEngine::RegisterUnserializedObject(int key_, const void *object, IAGSScriptManagedObject *callback) { GlobalReturnValue.SetPluginObject((void *)object, (ICCDynamicObject *)callback); - ccRegisterUnserializedObject(key, object, (ICCDynamicObject *)callback, true); + ccRegisterUnserializedObject(key_, object, (ICCDynamicObject *)callback, true); } int IAGSEngine::GetManagedObjectKeyByAddress(const char *address) { return ccGetObjectHandleFromAddress(address); } -void *IAGSEngine::GetManagedObjectAddressByKey(int key) { +void *IAGSEngine::GetManagedObjectAddressByKey(int key_) { void *object; ICCDynamicObject *manager; - ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(key, object, manager); + ScriptValueType obj_type = ccGetObjectAddressAndManagerFromHandle(key_, object, manager); if (obj_type == kScValPluginObject) { GlobalReturnValue.SetPluginObject(object, manager); } else { @@ -977,10 +973,10 @@ bool pl_use_builtin_plugin(EnginePlugin *apl) { return false; } -Engine::GameInitError pl_register_plugins(const std::vector &infos) { +Engine::GameInitError pl_register_plugins(const std::vector &infos) { numPlugins = 0; for (size_t inf_index = 0; inf_index < infos.size(); ++inf_index) { - const Common::PluginInfo &info = infos[inf_index]; + const Shared::PluginInfo &info = infos[inf_index]; String name = info.Name; if (name.GetLast() == '!') continue; // editor-only plugin, ignore it diff --git a/engines/ags/engine/plugin/library.cpp b/engines/ags/engine/plugin/library.cpp new file mode 100644 index 000000000000..44c6e1a06a6d --- /dev/null +++ b/engines/ags/engine/plugin/library.cpp @@ -0,0 +1,44 @@ +/* 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 "ags/engine/plugin/library.h" + +namespace AGS3 { + +void *dlopen(const char *filename, bool) { + // TODO: Reimplement plugins as C++ code that's part of the project + return nullptr; +} + +int dlclose(void *) { + return 0; +} + +void *dlsym(void *lib, const char *method) { + return nullptr; +} + +const char *dlerror() { + return nullptr; +} + +} // namespace AGS3 diff --git a/engines/ags/engine/plugin/library.h b/engines/ags/engine/plugin/library.h new file mode 100644 index 000000000000..4679f9c64292 --- /dev/null +++ b/engines/ags/engine/plugin/library.h @@ -0,0 +1,40 @@ +/* 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 AGS_ENGINE_PLUGIN_LIBRARY_H +#define AGS_ENGINE_PLUGIN_LIBRARY_H + +namespace AGS3 { + +#define RTLD_LAZY true + +extern void *dlopen(const char *filename, bool); + +extern int dlclose(void *lib); + +extern void *dlsym(void *lib, const char *method); + +extern const char *dlerror(); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/plugin/plugin_builtin.h b/engines/ags/engine/plugin/plugin_builtin.h index 13538f8a6001..3db0f06e60a8 100644 --- a/engines/ags/engine/plugin/plugin_builtin.h +++ b/engines/ags/engine/plugin/plugin_builtin.h @@ -35,8 +35,6 @@ namespace AGS3 { class IAGSEngine; -using namespace AGS; // FIXME later - // Initial implementation for apps to register their own inbuilt plugins struct InbuiltPluginDetails { diff --git a/engines/ags/engine/plugin/pluginobjectreader.cpp b/engines/ags/engine/plugin/pluginobjectreader.cpp index 237c7e9370f2..c01edae79b35 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.cpp +++ b/engines/ags/engine/plugin/pluginobjectreader.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/plugin/pluginobjectreader.h" -#include "ags/shared/ac/runtime_defines.h" +#include "ags/engine/plugin/pluginobjectreader.h" +#include "ags/engine/ac/runtime_defines.h" namespace AGS3 { diff --git a/engines/ags/engine/util/library.h b/engines/ags/engine/util/library.h index 41d53f5a431a..2fe01f20034d 100644 --- a/engines/ags/engine/util/library.h +++ b/engines/ags/engine/util/library.h @@ -56,10 +56,10 @@ class BaseLibrary { #elif AGS_PLATFORM_OS_LINUX \ || AGS_PLATFORM_OS_MACOS \ || AGS_PLATFORM_OS_ANDROID -#include "ags/shared/library_posix.h" +#include "ags/engine/util/library_posix.h" #elif AGS_PLATFORM_OS_IOS -#include "ags/shared/library_dummy.h" +#include "ags/engine/util/library_dummy.h" #endif diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index 53692c1f332c..ceb39cf21bca 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -26,7 +26,8 @@ //include #include "ags/shared/core/platform.h" #include "ags/shared/util/string.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/plugin/library.h" namespace AGS3 { diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 45a994e7f7f1..6756d1ab2c65 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -71,6 +71,13 @@ void set_palette_range(const PALETTE p, int from, int to, int retracesync) { g_system->getPaletteManager()->setPalette(&palette[from], from, to - from + 1); } +int makeacol(int r, int g, int b, int a) { + error("TODO: makeacol"); +} + +int makeacol_depth(int color_depth, int r, int g, int b, int a) { + error("makeacol_depth"); +} int makecol15(int r, int g, int b) { return (((r >> 3) << _rgb_r_shift_15) | @@ -123,4 +130,20 @@ int makecol8(byte r, byte g, byte b) { return (b) | (g << 8) | (r << 16); } +int getr_depth(int color_depth, int c) { + error("TOD: getr_depth"); +} + +int getg_depth(int color_depth, int c) { + error("TOD: getg_depth"); +} + +int getb_depth(int color_depth, int c) { + error("TOD: getb_depth"); +} + +int geta_depth(int color_depth, int c) { + error("TOD: geta_depth"); +} + } // namespace AGS3 diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index ddb7ae1e8d6e..cc1c86a95e37 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -70,6 +70,8 @@ AL_FUNC(void, set_color, (int idx, AL_CONST RGB *p)); AL_FUNC(void, set_palette, (AL_CONST PALETTE p)); AL_FUNC(void, set_palette_range, (AL_CONST PALETTE p, int from, int to, int retracesync)); +extern int makeacol(int r, int g, int b, int a); +extern int makeacol_depth(int color_depth, int r, int g, int b, int a); extern int makecol15(int r, int g, int b); extern int makecol16(int r, int g, int b); @@ -82,6 +84,11 @@ extern int getb8(int c); extern int makecol(byte r, byte g, byte b); extern int makecol8(byte r, byte g, byte b); +extern int getr_depth(int color_depth, int c); +extern int getg_depth(int color_depth, int c); +extern int getb_depth(int color_depth, int c); +extern int geta_depth(int color_depth, int c); + } // namespace AGS3 #endif diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index e5ccd68ec874..153a00be7285 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -244,6 +244,10 @@ bool is_planar_bitmap(BITMAP *bmp) { return false; } +bool is_linear_bitmap(BITMAP *bmp) { + return true; +} + void bmp_select(BITMAP *bmp) { // No implementation needed } diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index 737ddb3802cf..95cd8104c88f 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -236,6 +236,7 @@ extern void pivot_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int cx extern bool is_screen_bitmap(BITMAP *bmp); extern bool is_video_bitmap(BITMAP *bmp); +extern bool is_linear_bitmap(BITMAP *bmp); extern bool is_planar_bitmap(BITMAP *bmp); extern void bmp_select(BITMAP *bmp); extern long bmp_write_line(BITMAP *bmp, int line); diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 47674e664289..8df0808d72f5 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -104,7 +104,9 @@ MODULE_OBJS = \ engine/platform/base/agsplatformdriver.o \ engine/platform/windows/acplwin.o \ engine/platform/windows/minidump.o \ - engine/platform/windows/win_ex_handling.o + engine/platform/windows/win_ex_handling.o \ + engine/plugin/agsplugin.o \ + engine/plugin/pluginobjectreader.o # This module can be built as a plugin From 6840ccba8d0cf74ef0c041a86977fa62d88a1528 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Nov 2020 21:14:56 -0800 Subject: [PATCH 026/215] AGS: Adding engine/script/ folder --- .../ags/engine/ac/dynobj/cc_dynamicarray.h | 2 +- engines/ags/engine/ac/dynobj/cc_serializer.h | 2 +- .../ags/engine/ac/dynobj/managedobjectpool.h | 10 ++-- .../ags/engine/ac/dynobj/scriptuserobject.h | 2 +- .../engine/platform/base/agsplatformdriver.h | 4 +- engines/ags/engine/script/cc_instance.cpp | 32 +++++------ engines/ags/engine/script/executingscript.cpp | 6 +-- .../ags/engine/script/runtimescriptvalue.cpp | 6 +-- engines/ags/engine/script/script.cpp | 54 +++++++++---------- engines/ags/engine/script/script_api.cpp | 4 +- engines/ags/engine/script/script_engine.cpp | 2 +- engines/ags/engine/script/script_runtime.cpp | 8 +-- engines/ags/engine/script/systemimports.cpp | 10 ++-- engines/ags/engine/script/systemimports.h | 5 +- engines/ags/lib/aastr-0.1.1/aarot.cpp | 8 +-- engines/ags/lib/aastr-0.1.1/aastr.cpp | 8 +-- engines/ags/module.mk | 11 +++- engines/ags/shared/ac/gamesetupstructbase.cpp | 2 + engines/ags/shared/ac/spritecache.cpp | 6 +-- engines/ags/shared/core/types.h | 7 +-- engines/ags/shared/debugging/debugmanager.cpp | 6 +-- engines/ags/shared/game/roomstruct.cpp | 4 ++ engines/ags/shared/gfx/allegrobitmap.cpp | 2 +- engines/ags/shared/util/memory.h | 13 +++-- engines/ags/std/map.h | 13 +++++ engines/ags/std/queue.h | 37 +++++++++++++ 26 files changed, 167 insertions(+), 97 deletions(-) create mode 100644 engines/ags/std/queue.h diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index 327a0b1b78b8..309a8adbcf3d 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -24,7 +24,7 @@ #define AGS_ENGINE_AC_DYNOBJ_CCDYNAMICARRAY_H #include "ags/std/vector.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.h b/engines/ags/engine/ac/dynobj/cc_serializer.h index 54458ead27c3..963c65d1d2c0 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.h +++ b/engines/ags/engine/ac/dynobj/cc_serializer.h @@ -28,7 +28,7 @@ namespace AGS3 { struct AGSDeSerializer : ICCObjectReader { - + virtual ~AGSDeSerializer() {} void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) override; }; diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index 118df53d3f19..31366b02fa18 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -24,11 +24,11 @@ #define AGS_ENGINE_AC_DYNOBJ_MANAGEDOBJECTPOOL_H #include "ags/std/vector.h" -//include -//include - -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject +#include "ags/std/queue.h" +#include "ags/std/map.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject +#include "ags/shared/util/string_types.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h index d54d32aaa594..b4ff5418df2f 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.h +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTUSERSTRUCT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTUSERSTRUCT_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 5a2023c6cc6d..1975d94353ee 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -29,11 +29,11 @@ #ifndef AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H #define AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H -//include #include "ags/std/vector.h" #include "ags/engine/ac/datetime.h" #include "ags/shared/debugging/outputhandler.h" #include "ags/shared/util/ini_util.h" +#include "ags/lib/allegro/error.h" namespace AGS3 { @@ -73,7 +73,7 @@ struct AGSPlatformDriver virtual void DisplayAlert(const char *, ...) = 0; virtual void AttachToParentConsole(); virtual int GetLastSystemError() { - return errno; + return errnum; } // Get root directory for storing per-game shared data virtual const char *GetAllUsersDataDirectory() { diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index 2effb0fd1f51..b76ee2cfdc3d 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -23,26 +23,26 @@ //include //include #include "ags/shared/ac/common.h" -#include "ags/shared/ac/dynobj/cc_dynamicarray.h" -#include "ags/shared/ac/dynobj/managedobjectpool.h" +#include "ags/engine/ac/dynobj/cc_dynamicarray.h" +#include "ags/engine/ac/dynobj/managedobjectpool.h" #include "ags/shared/gui/guidefines.h" #include "ags/shared/script/cc_error.h" -#include "ags/shared/script/cc_instance.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/out.h" +#include "ags/engine/script/cc_instance.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/script/cc_options.h" -#include "ags/shared/script/script.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/script/systemimports.h" +#include "ags/engine/script/script.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/script/systemimports.h" #include "ags/shared/util/bbop.h" #include "ags/shared/util/stream.h" #include "ags/shared/util/misc.h" #include "ags/shared/util/textstreamwriter.h" -#include "ags/shared/ac/dynobj/scriptstring.h" -#include "ags/shared/ac/dynobj/scriptuserobject.h" -#include "ags/shared/ac/statobj/agsstaticobject.h" -#include "ags/shared/ac/statobj/staticarray.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject_addr_and_manager.h" +#include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/ac/dynobj/scriptuserobject.h" +#include "ags/engine/ac/statobj/agsstaticobject.h" +#include "ags/engine/ac/statobj/staticarray.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h" #include "ags/shared/util/memory.h" #include "ags/shared/util/string_utils.h" // linux strnicmp definition @@ -1319,8 +1319,8 @@ bool ccInstance::_Create(PScript scri, ccInstance *joined) { code = (intptr_t *)malloc(codesize * sizeof(intptr_t)); // 64 bit: Read code into 8 byte array, necessary for being able to perform // relocations on the references. - for (int i = 0; i < codesize; ++i) - code[i] = scri->code[i]; + for (int idx = 0; idx < codesize; ++idx) + code[idx] = scri->code[idx]; } } @@ -1558,7 +1558,7 @@ ScriptVariable *ccInstance::FindGlobalVar(int32_t var_addr) { Debug::Printf(kDbgMsg_Warn, "WARNING: looking up for global variable beyond allocated buffer (%d, %d)", var_addr, globaldatasize); } ScVarMap::iterator it = globalvars->find(var_addr); - return it != globalvars->end() ? &it->second : nullptr; + return it != globalvars->end() ? &it->_value : nullptr; } bool ccInstance::CreateRuntimeCodeFixups(PScript scri) { diff --git a/engines/ags/engine/script/executingscript.cpp b/engines/ags/engine/script/executingscript.cpp index 190f4464dc1c..2924a0b8ed4a 100644 --- a/engines/ags/engine/script/executingscript.cpp +++ b/engines/ags/engine/script/executingscript.cpp @@ -21,9 +21,9 @@ */ //include -#include "ags/shared/executingscript.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" +#include "ags/engine/script/executingscript.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" namespace AGS3 { diff --git a/engines/ags/engine/script/runtimescriptvalue.cpp b/engines/ags/engine/script/runtimescriptvalue.cpp index 2ac47d71cf65..5a943734f149 100644 --- a/engines/ags/engine/script/runtimescriptvalue.cpp +++ b/engines/ags/engine/script/runtimescriptvalue.cpp @@ -21,9 +21,9 @@ */ #include "ags/shared/script/cc_error.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" -#include "ags/shared/ac/statobj/staticobject.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/ac/statobj/staticobject.h" #include "ags/shared/util/memory.h" //include // for memcpy() diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp index 45d52a275402..72217c857d70 100644 --- a/engines/ags/engine/script/script.cpp +++ b/engines/ags/engine/script/script.cpp @@ -21,36 +21,36 @@ */ //include -#include "ags/shared/script/script.h" +#include "ags/engine/script/script.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/dialog.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/dialog.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_dialog.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_hotspot.h" -#include "ags/shared/ac/global_object.h" -#include "ags/shared/ac/global_room.h" -#include "ags/shared/ac/invwindow.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomobject.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_dialog.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_hotspot.h" +#include "ags/engine/ac/global_object.h" +#include "ags/engine/ac/global_room.h" +#include "ags/engine/ac/invwindow.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomobject.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/script/cc_options.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/media/video/video.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/media/video/video.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/util/string_compat.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { @@ -718,11 +718,11 @@ int run_interaction_commandlist(InteractionCommandList *nicl, int *timesrun, int break; case 9: { // Run Dialog - int room_was = play.room_changes; + int roomWas = play.room_changes; RunDialog(IPARAM1); // if they changed room within the dialog script, // the interaction command list is no longer valid - if (room_was != play.room_changes) + if (roomWas != play.room_changes) return -1; } break; diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp index 50f37f883d00..ecf8192db5db 100644 --- a/engines/ags/engine/script/script_api.cpp +++ b/engines/ags/engine/script/script_api.cpp @@ -24,8 +24,8 @@ //include #include "ags/shared/ac/game_version.h" #include "ags/shared/script/cc_error.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/script/script_api.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/script/script_api.h" #include "ags/shared/util/math.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script_engine.cpp b/engines/ags/engine/script/script_engine.cpp index 234ed39bd491..fdbe1fc56a2f 100644 --- a/engines/ags/engine/script/script_engine.cpp +++ b/engines/ags/engine/script/script_engine.cpp @@ -32,7 +32,7 @@ //============================================================================= //include -#include "ags/shared/script/cc_instance.h" +#include "ags/engine/script/cc_instance.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/util/file.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp index 117162d359e4..f460eb5807c6 100644 --- a/engines/ags/engine/script/script_runtime.cpp +++ b/engines/ags/engine/script/script_runtime.cpp @@ -37,13 +37,13 @@ //include //include //include -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/script/script_common.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/script/cc_options.h" -#include "ags/shared/ac/dynobj/cc_dynamicarray.h" -#include "ags/shared/script/systemimports.h" -#include "ags/shared/ac/statobj/staticobject.h" +#include "ags/engine/ac/dynobj/cc_dynamicarray.h" +#include "ags/engine/script/systemimports.h" +#include "ags/engine/ac/statobj/staticobject.h" namespace AGS3 { diff --git a/engines/ags/engine/script/systemimports.cpp b/engines/ags/engine/script/systemimports.cpp index 850458aa5ae4..cc94b15d5fca 100644 --- a/engines/ags/engine/script/systemimports.cpp +++ b/engines/ags/engine/script/systemimports.cpp @@ -22,7 +22,7 @@ //include //include -#include "ags/shared/script/systemimports.h" +#include "ags/engine/script/systemimports.h" namespace AGS3 { @@ -52,7 +52,7 @@ int SystemImports::add(const String &name, const RuntimeScriptValue &value, ccIn } btree[name] = ixof; - if (ixof == imports.size()) + if (ixof == (int)imports.size()) imports.push_back(ScriptImport()); imports[ixof].Name = name; // TODO: rather make a string copy here for safety reasons imports[ixof].Value = value; @@ -88,14 +88,14 @@ const ScriptImport *SystemImports::getByIndex(int index) { int SystemImports::get_index_of(const String &name) { IndexMap::const_iterator it = btree.find(name); if (it != btree.end()) - return it->second; + return it->_value; // CHECKME: what are "mangled names" and where do they come from? String mangled_name = String::FromFormat("%s$", name.GetCStr()); // if it's a function with a mangled name, allow it it = btree.lower_bound(mangled_name); - if (it != btree.end() && it->first.CompareLeft(mangled_name) == 0) - return it->second; + if (it != btree.end() && it->_key.CompareLeft(mangled_name) == 0) + return it->_value; if (name.GetLength() > 3) { size_t c = name.FindCharReverse('^'); diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index 7d8d9cb34c21..4bf2238dd9ca 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -23,8 +23,9 @@ #ifndef AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H #define AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H -//include -#include "ags/shared/script/cc_instance.h" // ccInstance +#include "ags/std/map.h" +#include "ags/engine/script/cc_instance.h" // ccInstance +#include "ags/shared/util/string_types.h" namespace AGS3 { diff --git a/engines/ags/lib/aastr-0.1.1/aarot.cpp b/engines/ags/lib/aastr-0.1.1/aarot.cpp index e2bd4f325b85..0c9a364da9a1 100644 --- a/engines/ags/lib/aastr-0.1.1/aarot.cpp +++ b/engines/ags/lib/aastr-0.1.1/aarot.cpp @@ -126,13 +126,13 @@ _aa_rotate_bitmap(BITMAP *_src, BITMAP *_dst, int _x, int _y, fixed _angle, sw <<= aa_BITS; dsx = sw / dw; - if (dsx < aa_SIZE) + if (dsx < (int)aa_SIZE) dsx = aa_SIZE; sw -= dsx; sh <<= aa_BITS; dsy = sh / dh; - if (dsy < aa_SIZE) + if (dsy < (int)aa_SIZE) dsy = aa_SIZE; sh -= dsy; @@ -140,9 +140,9 @@ _aa_rotate_bitmap(BITMAP *_src, BITMAP *_dst, int _x, int _y, fixed _angle, /* Avoid overflow. */ if (num > aa_MAX_NUM) { - if (dsx > aa_MAX_SIZE) + if (dsx > (int)aa_MAX_SIZE) dsx = aa_MAX_SIZE; - if (dsy > aa_MAX_SIZE) + if (dsy > (int)aa_MAX_SIZE) dsy = aa_MAX_SIZE; num = dsx * dsy; } diff --git a/engines/ags/lib/aastr-0.1.1/aastr.cpp b/engines/ags/lib/aastr-0.1.1/aastr.cpp index e62bbf7020da..b753d9e5f2d5 100644 --- a/engines/ags/lib/aastr-0.1.1/aastr.cpp +++ b/engines/ags/lib/aastr-0.1.1/aastr.cpp @@ -80,7 +80,7 @@ _aa_stretch_blit(BITMAP *_src, BITMAP *_dst, _sw <<= aa_BITS; dsx = _sw / _dw; - if (dsx < aa_SIZE) { + if (dsx < (int)aa_SIZE) { /* Exploding by x. */ _dw--; _sw -= aa_SIZE; @@ -91,7 +91,7 @@ _aa_stretch_blit(BITMAP *_src, BITMAP *_dst, _sh <<= aa_BITS; dsy = _sh / _dh; - if (dsy < aa_SIZE) { + if (dsy < (int)aa_SIZE) { /* Exploding by y. */ _dh--; _sh -= aa_SIZE; @@ -101,9 +101,9 @@ _aa_stretch_blit(BITMAP *_src, BITMAP *_dst, num = dsx * dsy; if (num > aa_MAX_NUM) { - if (dsx > aa_MAX_SIZE) + if (dsx > (int)aa_MAX_SIZE) dsx = aa_MAX_SIZE; - if (dsy > aa_MAX_SIZE) + if (dsy > (int)aa_MAX_SIZE) dsy = aa_MAX_SIZE; num = dsx * dsy; } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 8df0808d72f5..793bc264d95d 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -106,7 +106,16 @@ MODULE_OBJS = \ engine/platform/windows/minidump.o \ engine/platform/windows/win_ex_handling.o \ engine/plugin/agsplugin.o \ - engine/plugin/pluginobjectreader.o + engine/plugin/pluginobjectreader.o \ + engine/script/cc_instance.o \ + engine/script/executingscript.o \ + engine/script/exports.o \ + engine/script/runtimescriptvalue.o \ + engine/script/script.o \ + engine/script/script_api.o \ + engine/script/script_engine.o \ + engine/script/script_runtime.o \ + engine/script/systemimports.o # This module can be built as a plugin diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp index 2b03a199b96e..8c665fb5f551 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.cpp +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -250,6 +250,8 @@ Size ResolutionTypeToSize(GameResolutionType resolution, bool letterbox) { return Size(1024, 768); case kGameResolution_1280x720: return Size(1280, 720); + default: + break; } return Size(); } diff --git a/engines/ags/shared/ac/spritecache.cpp b/engines/ags/shared/ac/spritecache.cpp index 496ba10b51da..8258e7902839 100644 --- a/engines/ags/shared/ac/spritecache.cpp +++ b/engines/ags/shared/ac/spritecache.cpp @@ -489,10 +489,10 @@ void SpriteCache::CompressSprite(Bitmap *sprite, Stream *out) { cpackbitl(&sprite->GetScanLineForWriting(y)[0], sprite->GetWidth(), out); } else if (depth == 2) { for (int y = 0; y < sprite->GetHeight(); y++) - cpackbitl16((unsigned short *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); + cpackbitl16((const unsigned short *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); } else { for (int y = 0; y < sprite->GetHeight(); y++) - cpackbitl32((unsigned int *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); + cpackbitl32((const unsigned int *)&sprite->GetScanLine(y)[0], sprite->GetWidth(), out); } } @@ -856,7 +856,7 @@ void SpriteCache::DetachFile() { } int SpriteCache::AttachFile(const char *filename) { - _stream.reset(Shared::AssetManager::OpenAsset((char *)filename)); + _stream.reset(Shared::AssetManager::OpenAsset((const char *)filename)); if (_stream == nullptr) return -1; return 0; diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index 7370da5934bf..3bf23121d98b 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -67,10 +67,11 @@ typedef int16 int16_t; typedef int32 int32_t; typedef int64 int64_t; -// Stream offset type -typedef int64 soff_t; +typedef int64 soff_t; // Stream offset type +typedef int64 intptr_t; -#define fixed_t int32_t // fixed point type +// fixed point type +#define fixed_t int32_t #define color_t int #undef INT32_MIN diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp index f1889e2ab865..f54484a66d20 100644 --- a/engines/ags/shared/debugging/debugmanager.cpp +++ b/engines/ags/shared/debugging/debugmanager.cpp @@ -54,7 +54,7 @@ void DebugOutput::SetEnabled(bool enable) { void DebugOutput::SetGroupFilter(DebugGroupID id, MessageType verbosity) { uint32_t key = DbgMgr.GetGroup(id).UID.ID; - if (key != kDbgGroup_None) + if (key != (uint32_t)kDbgGroup_None) _groupFilter[key] = verbosity; else _unresolvedGroups.insert(std::make_pair(id.SID, verbosity)); @@ -91,7 +91,7 @@ void DebugOutput::ResolveGroupID(DebugGroupID id) { bool DebugOutput::TestGroup(DebugGroupID id, MessageType mt) const { DebugGroupID real_id = DbgMgr.GetGroup(id).UID; - if (real_id.ID == kDbgGroup_None || real_id.ID >= _groupFilter.size()) + if (real_id.ID == (uint32_t)kDbgGroup_None || real_id.ID >= _groupFilter.size()) return false; return (_groupFilter[real_id.ID] >= mt) != 0; } @@ -108,7 +108,7 @@ DebugManager::DebugManager() { } DebugGroup DebugManager::GetGroup(DebugGroupID id) { - if (id.ID != kDbgGroup_None) { + if (id.ID != (uint32_t)kDbgGroup_None) { return id.ID < _groups.size() ? _groups[id.ID] : DebugGroup(); } else if (!id.SID.IsEmpty()) { GroupByStringMap::const_iterator it = _groupByStrLookup.find(id.SID); diff --git a/engines/ags/shared/game/roomstruct.cpp b/engines/ags/shared/game/roomstruct.cpp index 3d1759181680..d467f2a01d30 100644 --- a/engines/ags/shared/game/roomstruct.cpp +++ b/engines/ags/shared/game/roomstruct.cpp @@ -201,6 +201,8 @@ Bitmap *RoomStruct::GetMask(RoomAreaMask mask) const { return WalkAreaMask.get(); case kRoomAreaRegion: return RegionMask.get(); + default: + break; } return nullptr; } @@ -213,6 +215,8 @@ float RoomStruct::GetMaskScale(RoomAreaMask mask) const { case kRoomAreaWalkable: case kRoomAreaRegion: return 1.f / MaskResolution; + default: + break; } return 0.f; } diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index cb471b43e7f2..9071308340fc 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -231,7 +231,7 @@ void Bitmap::AAStretchBlt(Bitmap *src, const Rect &src_rc, const Rect &dst_rc, B // TODO: aastr lib does not expose method for masked stretch blit; should do that at some point since // the source code is a gift-ware anyway // aa_masked_blit(_alBitmap, al_src_bmp, src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), dst_rc.Left, dst_rc.Top, dst_rc.GetWidth(), dst_rc.GetHeight()); - throw "aa_masked_blit is not yet supported!"; + error("aa_masked_blit is not yet supported!"); } else { aa_stretch_blit(al_src_bmp, _alBitmap, src_rc.Left, src_rc.Top, src_rc.GetWidth(), src_rc.GetHeight(), diff --git a/engines/ags/shared/util/memory.h b/engines/ags/shared/util/memory.h index 29c6b791b540..b5cd1c1aed3f 100644 --- a/engines/ags/shared/util/memory.h +++ b/engines/ags/shared/util/memory.h @@ -32,6 +32,7 @@ //include #include "ags/shared/util/bbop.h" #include "ags/shared/util/math.h" +#include "common/textconsole.h" namespace AGS3 { @@ -50,11 +51,13 @@ namespace Memory { //------------------------------------------------------------------------- template inline int32_t PtrToInt32(T *ptr) { - return static_cast(reinterpret_cast(ptr)); + error("TODO: Handle 32-bit pointers in ScummVM if needed"); + //return static_cast(reinterpret_cast(ptr)); } template inline T *Int32ToPtr(int32_t value) { - return reinterpret_cast(static_cast(value)); + error("TODO: Handle 32-bit pointers in ScummVM if needed"); + //return reinterpret_cast(static_cast(value)); } //------------------------------------------------------------------------- @@ -71,7 +74,7 @@ inline int16_t ReadInt16(const void *ptr) { return (b[1] << 8) | b[0]; #endif #else - return *(int16_t *)ptr; + return *(const int16_t *)ptr; #endif } @@ -84,7 +87,7 @@ inline int32_t ReadInt32(const void *ptr) { return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; #endif #else - return *(int32_t *)ptr; + return *(const int32_t *)ptr; #endif } @@ -99,7 +102,7 @@ inline int64_t ReadInt64(const void *ptr) { (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; #endif #else - return *(int64_t *)ptr; + return *(const int64_t *)ptr; #endif } diff --git a/engines/ags/std/map.h b/engines/ags/std/map.h index 028cb7b71e3b..0c015ccaba7f 100644 --- a/engines/ags/std/map.h +++ b/engines/ags/std/map.h @@ -33,9 +33,22 @@ template, class EqualFunc = Common::EqualTo > class map : public Common::HashMap { public: + using iterator = typename Common::HashMap::iterator; + void insert(pair elem) { this->operator[](elem.first) = elem.second; } + + // FUNCTION TEMPLATE lower_bound + iterator lower_bound(Key &val) { + iterator it; + for (it = this->begin(); it != this->end(); ++it) { + if (it->_key >= val) + break; + } + + return it; + } }; template, diff --git a/engines/ags/std/queue.h b/engines/ags/std/queue.h new file mode 100644 index 000000000000..41c0653464bf --- /dev/null +++ b/engines/ags/std/queue.h @@ -0,0 +1,37 @@ +/* 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 AGS_STD_QUEUE_H +#define AGS_STD_QUEUE_H + +#include "common/queue.h" + +namespace AGS3 { +namespace std { + +template +using queue = Common::Queue; + +} // namespace std +} // namespace AGS3 + +#endif From 19832746d4778178c7fa6af606204df405134940 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 23 Nov 2020 21:54:11 -0800 Subject: [PATCH 027/215] AGS: gcc compilation fixes --- engines/ags/engine/ac/dynobj/cc_dynamicarray.h | 4 +++- engines/ags/engine/ac/dynobj/cc_dynamicobject.h | 2 ++ engines/ags/engine/ac/dynobj/managedobjectpool.h | 4 ++-- engines/ags/engine/ac/dynobj/scriptuserobject.h | 4 +++- engines/ags/engine/ac/statobj/staticarray.cpp | 6 +++++- engines/ags/engine/ac/statobj/staticarray.h | 3 ++- engines/ags/engine/game/savegame.cpp | 4 +++- engines/ags/engine/plugin/agsplugin.h | 4 ++++ engines/ags/engine/script/cc_instance.cpp | 6 +++--- engines/ags/engine/script/script.cpp | 6 +++--- engines/ags/engine/script/systemimports.cpp | 2 +- 11 files changed, 31 insertions(+), 14 deletions(-) diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index 309a8adbcf3d..aea7d06935c8 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -60,9 +60,11 @@ extern CCDynamicArray globalDynamicArray; // Helper functions for setting up dynamic arrays. namespace DynamicArrayHelpers { + // Create array of managed strings DynObjectRef CreateStringArray(const std::vector); -}; + +} // namespace DynamicArrayHelpers } // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index 469aaa35033c..93bc6593516f 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -96,10 +96,12 @@ struct ICCDynamicObject { }; struct ICCObjectReader { + virtual ~ICCObjectReader() {} // TODO: pass savegame format version virtual void Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) = 0; }; struct ICCStringClass { + virtual ~ICCStringClass() {} virtual DynObjectRef CreateString(const char *fromText) = 0; }; diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index 31366b02fa18..a66f23c8693f 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -58,8 +58,8 @@ struct ManagedObjectPool final { ManagedObject() : obj_type(kScValUndefined), handle(0), addr(nullptr), callback(nullptr), refCount(0) { } - ManagedObject(ScriptValueType obj_type, int32_t handle, const char *addr, ICCDynamicObject *callback) - : obj_type(obj_type), handle(handle), addr(addr), callback(callback), refCount(0) { + ManagedObject(ScriptValueType obj_type_, int32_t handle_, const char *addr_, ICCDynamicObject *callback_) + : obj_type(obj_type_), handle(handle_), addr(addr_), callback(callback_), refCount(0) { } }; diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.h b/engines/ags/engine/ac/dynobj/scriptuserobject.h index b4ff5418df2f..44ae8bf68ce8 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.h +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.h @@ -79,9 +79,11 @@ struct ScriptUserObject final : ICCDynamicObject { // Helper functions for setting up custom managed structs based on ScriptUserObject. namespace ScriptStructHelpers { + // Creates a managed Point object, represented as a pair of X and Y coordinates. ScriptUserObject *CreatePoint(int x, int y); -}; + +} // namespace ScriptStructHelpers } // namespace AGS3 diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp index 73fd3b27f837..d2fada026d0c 100644 --- a/engines/ags/engine/ac/statobj/staticarray.cpp +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -50,7 +50,11 @@ void StaticArray::Create(ICCDynamicObject *dynmgr, int elem_legacy_size, int ele _elemCount = elem_count; } -const char *StaticArray::GetElementPtr(const char *address, intptr_t legacy_offset) { +const char *StaticArray::GetElementPtr(const char *address, intptr_t legacy_offset) const { + return address + (legacy_offset / _elemLegacySize) * _elemRealSize; +} + +char *StaticArray::GetElementPtr(char *address, intptr_t legacy_offset) { return address + (legacy_offset / _elemLegacySize) * _elemRealSize; } diff --git a/engines/ags/engine/ac/statobj/staticarray.h b/engines/ags/engine/ac/statobj/staticarray.h index 6176dc438451..1c9309c9da3d 100644 --- a/engines/ags/engine/ac/statobj/staticarray.h +++ b/engines/ags/engine/ac/statobj/staticarray.h @@ -44,7 +44,8 @@ struct StaticArray : public ICCStaticObject { return _dynamicMgr; } // Legacy support for reading and writing object values by their relative offset - virtual const char *GetElementPtr(const char *address, intptr_t legacy_offset); + virtual const char *GetElementPtr(const char *address, intptr_t legacy_offset) const; + virtual char *GetElementPtr(char *address, intptr_t legacy_offset); const char *GetFieldPtr(const char *address, intptr_t offset) override; void Read(const char *address, intptr_t offset, void *dest, int size) override; diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index b9678c25e6d2..f9adcdb69fdd 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -162,6 +162,8 @@ String GetSavegameErrorText(SavegameErrorType err) { return "Saved with the engine running at a different colour depth."; case kSvgErr_GameObjectInitFailed: return "Game object initialization failed after save restoration."; + default: + break; } return "Unknown error."; } @@ -449,7 +451,7 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) } // restore these to the ones retrieved from the save game - const size_t dynsurf_num = Math::Min((size_t)MAX_DYNAMIC_SURFACES, r_data.DynamicSurfaces.size()); + const size_t dynsurf_num = Math::Min((uint)MAX_DYNAMIC_SURFACES, r_data.DynamicSurfaces.size()); for (size_t i = 0; i < dynsurf_num; ++i) { dynamicallyCreatedSurfaces[i] = r_data.DynamicSurfaces[i]; } diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/engine/plugin/agsplugin.h index da60dda2848c..6b40b888a4a1 100644 --- a/engines/ags/engine/plugin/agsplugin.h +++ b/engines/ags/engine/plugin/agsplugin.h @@ -218,6 +218,8 @@ class IAGSEditor { int32 pluginId; // used internally, do not touch this public: + virtual ~IAGSEditor() {} + // get the HWND of the main editor frame AGSIFUNC(HWND) GetEditorHandle(); // get the HWND of the current active window @@ -326,6 +328,8 @@ class IAGSEngine { int32 pluginId; // used internally, do not touch public: + virtual ~IAGSEngine() {} + // quit the game AGSIFUNC(void) AbortGame(const char *reason); // get engine version diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index b76ee2cfdc3d..4bc07dde5249 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -832,10 +832,10 @@ int ccInstance::Run(int32_t curpc) { case SCMD_MEMWRITEPTR: { int32_t handle = registers[SREG_MAR].ReadInt32(); - char *address = nullptr; + const char *address = nullptr; if (reg1.Type == kScValStaticArray && reg1.StcArr->GetDynamicManager()) { - address = (char *)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); + address = (const char *)reg1.StcArr->GetElementPtr(reg1.Ptr, reg1.IValue); } else if (reg1.Type == kScValDynamicObject || reg1.Type == kScValPluginObject) { address = reg1.Ptr; @@ -1152,7 +1152,7 @@ int ccInstance::Run(int32_t curpc) { int currentStackSize = registers[SREG_SP].RValue - &stack[0]; int currentDataSize = stackdata_ptr - stackdata; if (currentStackSize + 1 >= CC_STACK_SIZE || - currentDataSize + arg1.IValue >= CC_STACK_DATA_SIZE) { + currentDataSize + arg1.IValue >= (int)CC_STACK_DATA_SIZE) { cc_error("stack overflow, attempted grow to %d bytes", currentDataSize + arg1.IValue); return -1; } diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp index 72217c857d70..999d250427a2 100644 --- a/engines/ags/engine/script/script.cpp +++ b/engines/ags/engine/script/script.cpp @@ -322,7 +322,7 @@ bool DoRunScriptFuncCantBlock(ccInstance *sci, NonBlockingScriptFunction *funcTo int result = 0; if (funcToRun->numParameters < 3) { - result = sci->CallScriptFunction((char *)funcToRun->functionName, funcToRun->numParameters, funcToRun->params); + result = sci->CallScriptFunction((const char *)funcToRun->functionName, funcToRun->numParameters, funcToRun->params); } else quit("DoRunScriptFuncCantBlock called with too many parameters"); @@ -503,10 +503,10 @@ String GetScriptName(ccInstance *sci) { char bname[MAX_FUNCTION_NAME_LEN + 1], bne[MAX_FUNCTION_NAME_LEN + 1]; char *make_ts_func_name(const char *base, int iii, int subd) { int err = snprintf(bname, MAX_FUNCTION_NAME_LEN, base, iii); - if (err >= sizeof(bname)) + if (err >= (int)sizeof(bname)) debug_script_warn("Function name length limit exceeded: %s (%d)", base, iii); err = snprintf(bne, MAX_FUNCTION_NAME_LEN, "%s_%c", bname, subd + 'a'); - if (err >= sizeof(bne)) + if (err >= (int)sizeof(bne)) debug_script_warn("Function name length limit exceeded: %s", bname); return &bne[0]; } diff --git a/engines/ags/engine/script/systemimports.cpp b/engines/ags/engine/script/systemimports.cpp index cc94b15d5fca..843e9f011946 100644 --- a/engines/ags/engine/script/systemimports.cpp +++ b/engines/ags/engine/script/systemimports.cpp @@ -99,7 +99,7 @@ int SystemImports::get_index_of(const String &name) { if (name.GetLength() > 3) { size_t c = name.FindCharReverse('^'); - if (c != -1 && (c == name.GetLength() - 2 || c == name.GetLength() - 3)) { + if (c != String::npos && (c == name.GetLength() - 2 || c == name.GetLength() - 3)) { // Function with number of prametrs on the end // attempt to find it without the param count return get_index_of(name.Left(c)); From 19bc3813a7c8f39d5c8ce003eb1e3e9979206cc0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 24 Nov 2020 22:23:07 -0800 Subject: [PATCH 028/215] AGS: Added engine/gfx/ folder --- engines/ags/ags.cpp | 2 +- engines/ags/ags.h | 8 + engines/ags/engine/gfx/ali3dogl.cpp | 63 +++++-- engines/ags/engine/gfx/ali3dogl.h | 10 +- engines/ags/engine/gfx/ali3dsw.cpp | 21 ++- engines/ags/engine/gfx/ali3dsw.h | 10 +- engines/ags/engine/gfx/blender.cpp | 3 +- engines/ags/engine/gfx/gfx_util.cpp | 4 +- engines/ags/engine/gfx/gfxdriverbase.cpp | 9 +- engines/ags/engine/gfx/gfxdriverbase.h | 6 +- engines/ags/engine/gfx/gfxdriverfactory.cpp | 16 +- engines/ags/engine/gfx/gfxdriverfactorybase.h | 4 +- engines/ags/engine/gfx/gfxfilter_aad3d.cpp | 3 +- engines/ags/engine/gfx/gfxfilter_aad3d.h | 2 +- engines/ags/engine/gfx/gfxfilter_aaogl.h | 2 +- engines/ags/engine/gfx/gfxfilter_allegro.cpp | 8 +- engines/ags/engine/gfx/gfxfilter_allegro.h | 4 +- engines/ags/engine/gfx/gfxfilter_d3d.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_d3d.h | 2 +- engines/ags/engine/gfx/gfxfilter_hqx.cpp | 4 +- engines/ags/engine/gfx/gfxfilter_hqx.h | 2 +- engines/ags/engine/gfx/gfxfilter_ogl.cpp | 4 +- engines/ags/engine/gfx/gfxfilter_ogl.h | 2 +- engines/ags/engine/gfx/gfxfilter_scaling.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_scaling.h | 4 +- engines/ags/engine/gfx/ogl_headers.h | 8 +- engines/ags/lib/aastr-0.1.1/aautil.cpp | 2 +- engines/ags/lib/allegro/alconfig.h | 2 +- engines/ags/lib/allegro/color.cpp | 57 +++++- engines/ags/lib/allegro/color.h | 109 +++++++++++- engines/ags/lib/allegro/system.cpp | 21 ++- engines/ags/lib/allegro/system.h | 45 ++++- engines/ags/lib/opengl/opengl.cpp | 117 ++++++++++++ engines/ags/lib/opengl/opengl.h | 166 ++++++++++++++++++ engines/ags/module.mk | 15 ++ engines/ags/shared/core/platform.h | 6 +- engines/ags/shared/core/types.h | 5 + engines/ags/std/algorithm.h | 5 + engines/ags/std/memory.h | 6 + 39 files changed, 662 insertions(+), 99 deletions(-) create mode 100644 engines/ags/lib/opengl/opengl.cpp create mode 100644 engines/ags/lib/opengl/opengl.h diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index ce3961461ca2..c5dc3afa71eb 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -35,7 +35,7 @@ AGSEngine *g_vm; /*------------------------------------------------------------------*/ AGSEngine::AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc) : Engine(syst), - _gameDescription(gameDesc), _randomSource("AGS") { + _gameDescription(gameDesc), _randomSource("AGS"), _screen(nullptr), _gfxDriver(nullptr) { g_vm = this; DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); diff --git a/engines/ags/ags.h b/engines/ags/ags.h index fce049973e15..6e947b7c635a 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -33,6 +33,9 @@ #include "engines/savestate.h" #include "graphics/surface.h" +#include "ags/shared/gfx/bitmap.h" +#include "ags/lib/allegro/system.h" + namespace AGS { #define SCREEN_WIDTH 320 @@ -49,6 +52,9 @@ class AGSEngine : public Engine { private: const AGSGameDescription *_gameDescription; Common::RandomSource _randomSource; +public: + ::AGS3::BITMAP *_screen; + ::AGS3::GFX_DRIVER *_gfxDriver; protected: // Engine APIs virtual Common::Error run(); @@ -84,6 +90,8 @@ class AGSEngine : public Engine { }; extern AGSEngine *g_vm; +#define screen ::AGS::g_vm->_screen +#define gfx_driver ::AGS::g_vm->_gfxDriver } // namespace AGS diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 06355a0fa667..11e19838f6aa 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -24,16 +24,17 @@ #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX -//include -#include "ags/shared/gfx/ali3dexception.h" -#include "ags/shared/gfx/ali3dogl.h" -#include "ags/shared/gfx/gfxfilter_ogl.h" -#include "ags/shared/gfx/gfxfilter_aaogl.h" -#include "ags/shared/gfx/gfx_util.h" -#include "ags/shared/main/main_allegro.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/std/algorithm.h" +#include "ags/engine/gfx/ali3dexception.h" +#include "ags/engine/gfx/ali3dogl.h" +#include "ags/engine/gfx/gfxfilter_ogl.h" +#include "ags/engine/gfx/gfxfilter_aaogl.h" +#include "ags/engine/gfx/gfx_util.h" +#include "ags/engine/main/main_allegro.h" +#include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/util/math.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/ac/timer.h" +#include "ags/ags.h" namespace AGS3 { @@ -132,6 +133,8 @@ void ogl_dummy_vsync() { } #define GFX_OPENGL AL_ID('O','G','L',' ') +static const char *empty_string = ""; + GFX_DRIVER gfx_opengl = { GFX_OPENGL, empty_string, @@ -335,6 +338,7 @@ void OGLGraphicsDriver::FirstTimeInit() { _firstTimeInit = true; } +#if !AGS_PLATFORM_SCUMMVM #if AGS_PLATFORM_OS_LINUX Atom get_x_atom(const char *atom_name) { Atom atom = XInternAtom(_xwin.display, atom_name, False); @@ -344,6 +348,7 @@ Atom get_x_atom(const char *atom_name) { return atom; } #endif +#endif bool OGLGraphicsDriver::InitGlScreen(const DisplayMode &mode) { #if AGS_PLATFORM_OS_ANDROID @@ -397,6 +402,9 @@ bool OGLGraphicsDriver::InitGlScreen(const DisplayMode &mode) { CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); win_grab_input(); +#elif AGS_PLATFORM_SCUMMVM + warning("TODO: InitGlScreen"); + #elif AGS_PLATFORM_OS_LINUX if (!_have_window) { // Use Allegro to create our window. We don't care what size Allegro uses @@ -516,7 +524,9 @@ void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#if !AGS_PLATFORM_SCUMMVM auto interval = mode.Vsync ? 1 : 0; +#endif bool vsyncEnabled = false; #if AGS_PLATFORM_OS_WINDOWS @@ -525,6 +535,7 @@ void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { } #endif +#if !AGS_PLATFORM_SCUMMVM #if AGS_PLATFORM_OS_LINUX if (GLAD_GLX_EXT_swap_control) { glXSwapIntervalEXT(_xwin.display, _xwin.window, interval); @@ -535,6 +546,7 @@ void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { } else if (GLAD_GLX_SGI_swap_control) { vsyncEnabled = glXSwapIntervalSGI(interval) == 0; } +#endif #endif // TODO: find out how to implement SwapInterval on other platforms, and how to check if it's supported @@ -559,7 +571,9 @@ void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { } bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) { -#if AGS_PLATFORM_OS_WINDOWS +#if AGS_PLATFORM_SCUMMVM + warning("TODO: CreateGlContext"); +#elif AGS_PLATFORM_OS_WINDOWS PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, @@ -594,8 +608,7 @@ bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) { if (!wglMakeCurrent(_hDC, _hRC)) return false; -#endif // AGS_PLATFORM_OS_WINDOWS -#if AGS_PLATFORM_OS_LINUX +#elif AGS_PLATFORM_OS_LINUX int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; XVisualInfo *vi = glXChooseVisual(_xwin.display, DefaultScreen(_xwin.display), attrib); if (!vi) { @@ -617,7 +630,9 @@ bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) { } void OGLGraphicsDriver::DeleteGlContext() { -#if AGS_PLATFORM_OS_WINDOWS +#if AGS_PLATFORM_SCUMMVM + warning("TODO: DeleteGlContext"); +#elif AGS_PLATFORM_OS_WINDOWS if (_hRC) { wglMakeCurrent(NULL, NULL); wglDeleteContext(_hRC); @@ -663,6 +678,7 @@ void OGLGraphicsDriver::TestRenderToTexture() { } void OGLGraphicsDriver::TestSupersampling() { +#if !AGS_PLATFORM_SCUMMVM if (!_can_render_to_texture) return; // Disable super-sampling if it would cause a too large texture size @@ -672,6 +688,7 @@ void OGLGraphicsDriver::TestSupersampling() { if ((max < _srcRect.GetWidth() * _super_sampling) || (max < _srcRect.GetHeight() * _super_sampling)) _super_sampling = 1; } +#endif } void OGLGraphicsDriver::CreateShaders() { @@ -768,6 +785,7 @@ void OGLGraphicsDriver::CreateLightShader() { void OGLGraphicsDriver::CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, const char *sampler_var, const char *color_var, const char *aux_var) { +#if !AGS_PLATFORM_SCUMMVM GLint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr); glCompileShader(fragment_shader); @@ -797,6 +815,7 @@ void OGLGraphicsDriver::CreateShaderProgram(ShaderProgram &prg, const char *name prg.ColorVar = glGetUniformLocation(program, color_var); prg.AuxVar = glGetUniformLocation(program, aux_var); Debug::Printf("OGL: %s shader program created successfully", name); +#endif } void OGLGraphicsDriver::DeleteShaderProgram(ShaderProgram &prg) { @@ -806,6 +825,7 @@ void OGLGraphicsDriver::DeleteShaderProgram(ShaderProgram &prg) { } void OGLGraphicsDriver::OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader) { +#ifdef TODO GLint log_len; if (is_shader) glGetShaderiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); @@ -827,6 +847,9 @@ void OGLGraphicsDriver::OutputShaderError(GLuint obj_id, const String &obj_name, } else { Debug::Printf(kDbgMsg_Error, "Shader info log was empty."); } +#else + error("Obj Id=%u, Name=%s, Is Shader=%d", obj_id, obj_name.GetNullableCStr(), (int)is_shader); +#endif } void OGLGraphicsDriver::SetupBackbufferTexture() { @@ -835,7 +858,7 @@ void OGLGraphicsDriver::SetupBackbufferTexture() { // both native size set and context capabilities test passed. if (!IsNativeSizeValid() || !_can_render_to_texture) return; - +#if !AGS_PLATFORM_SCUMMVM DeleteBackbufferTexture(); // _backbuffer_texture_coordinates defines translation from wanted texture size to actual supported texture size @@ -863,7 +886,7 @@ void OGLGraphicsDriver::SetupBackbufferTexture() { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _backbuffer, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - +#endif // Assign vertices of the backbuffer texture position in the scene _backbuffer_vertices[0] = _backbuffer_vertices[4] = 0; _backbuffer_vertices[2] = _backbuffer_vertices[6] = _srcRect.GetWidth(); @@ -901,17 +924,17 @@ bool OGLGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *lo return false; } - try { +// try { if (!InitGlScreen(mode)) return false; if (!_firstTimeInit) FirstTimeInit(); InitGlParams(mode); - } catch (Ali3DException exception) { +/* } catch (Ali3DException exception) { if (exception._message != get_allegro_error()) set_allegro_error(exception._message); return false; - } + }*/ OnInit(loopTimer); @@ -1307,7 +1330,9 @@ void OGLGraphicsDriver::_render(bool clearDrawListAfterwards) { glFinish(); -#if AGS_PLATFORM_OS_WINDOWS +#if AGS_PLATFORM_SCUMMVM + g_system->updateScreen(); +#elif AGS_PLATFORM_OS_WINDOWS SwapBuffers(_hDC); #elif AGS_PLATFORM_OS_LINUX glXSwapBuffers(_xwin.display, _xwin.window); diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h index fde7c439aab6..c3f944d35836 100644 --- a/engines/ags/engine/gfx/ali3dogl.h +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -31,13 +31,13 @@ #include "ags/std/memory.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/ddb.h" -#include "ags/shared/gfx/gfxdriverfactorybase.h" -#include "ags/shared/gfx/gfxdriverbase.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/gfx/gfxdriverfactorybase.h" +#include "ags/engine/gfx/gfxdriverbase.h" #include "ags/shared/util/string.h" #include "ags/shared/util/version.h" -#include "ags/shared/ogl_headers.h" +#include "ags/engine/gfx/ogl_headers.h" namespace AGS3 { namespace AGS { @@ -47,7 +47,7 @@ namespace OGL { using Shared::Bitmap; using Shared::String; -using Common::Version; +using Shared::Version; typedef struct _OGLVECTOR { float x; diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index ec380f7c1285..e56761a422e8 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -26,16 +26,19 @@ // //============================================================================= -#include "ags/shared/gfx/ali3dsw.h" - +#include "ags/engine/gfx/ali3dsw.h" #include "ags/shared/core/platform.h" -#include "ags/shared/gfx/ali3dexception.h" -#include "ags/shared/gfx/gfxfilter_allegro.h" -#include "ags/shared/gfx/gfxfilter_hqx.h" -#include "ags/shared/gfx/gfx_util.h" -#include "ags/shared/main/main_allegro.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/gfx/ali3dexception.h" +#include "ags/engine/gfx/gfxfilter_allegro.h" +#include "ags/engine/gfx/gfxfilter_hqx.h" +#include "ags/engine/gfx/gfx_util.h" +#include "ags/engine/main/main_allegro.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/timer.h" +#include "ags/lib/allegro/color.h" +#include "ags/lib/opengl/opengl.h" +#include "ags/std/algorithm.h" +#include "ags/ags.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index 91b192782e88..a9e2a4fb2993 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -42,9 +42,9 @@ #endif #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/ddb.h" -#include "ags/shared/gfx/gfxdriverfactorybase.h" -#include "ags/shared/gfx/gfxdriverbase.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/gfx/gfxdriverfactorybase.h" +#include "ags/engine/gfx/gfxdriverbase.h" namespace AGS3 { namespace AGS { @@ -124,7 +124,7 @@ class ALSoftwareBitmap : public IDriverDependantBitmap { class ALSoftwareGfxModeList : public IGfxModeList { public: - ALSoftwareGfxModeList(GFX_MODE_LIST *alsw_gfx_mode_list) + ALSoftwareGfxModeList(const GFX_MODE_LIST *alsw_gfx_mode_list) : _gfxModeList(alsw_gfx_mode_list) { } @@ -135,7 +135,7 @@ class ALSoftwareGfxModeList : public IGfxModeList { bool GetMode(int index, DisplayMode &mode) const override; private: - GFX_MODE_LIST *_gfxModeList; + const GFX_MODE_LIST *_gfxModeList; }; diff --git a/engines/ags/engine/gfx/blender.cpp b/engines/ags/engine/gfx/blender.cpp index e4eb457e7a3a..549c74f53c98 100644 --- a/engines/ags/engine/gfx/blender.cpp +++ b/engines/ags/engine/gfx/blender.cpp @@ -21,8 +21,9 @@ */ #include "ags/shared/core/types.h" -#include "ags/shared/gfx/blender.h" +#include "ags/engine/gfx/blender.h" #include "ags/shared/util/wgt2allg.h" +#include "ags/lib/allegro/color.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp index aadbb940a4dc..d6ff6d19ae78 100644 --- a/engines/ags/engine/gfx/gfx_util.cpp +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -21,8 +21,8 @@ */ #include "ags/shared/core/platform.h" -#include "ags/shared/gfx/gfx_util.h" -#include "ags/shared/gfx/blender.h" +#include "ags/engine/gfx/gfx_util.h" +#include "ags/engine/gfx/blender.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index d1dd038ab8c8..b8947b7617f6 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -21,11 +21,12 @@ */ #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/gfx/ali3dexception.h" +#include "ags/engine/gfx/ali3dexception.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/gfxfilter.h" -#include "ags/shared/gfx/gfxdriverbase.h" -#include "ags/shared/gfx/gfx_util.h" +#include "ags/engine/gfx/gfxfilter.h" +#include "ags/engine/gfx/gfxdriverbase.h" +#include "ags/engine/gfx/gfx_util.h" +#include "ags/engine/ac/draw.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/gfxdriverbase.h b/engines/ags/engine/gfx/gfxdriverbase.h index b845de3b4aae..88f83fa6b076 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.h +++ b/engines/ags/engine/gfx/gfxdriverbase.h @@ -30,9 +30,9 @@ #define AGS_ENGINE_GFX_GFXDRIVERBASE_H #include "ags/std/vector.h" -#include "ags/shared/gfx/ddb.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/util/scaling.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/util/scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp index 00dcbf52119d..61954f52d2cd 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.cpp +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -20,27 +20,27 @@ * */ -#include "ags/shared/gfx/gfxdriverfactory.h" +#include "ags/engine/gfx/gfxdriverfactory.h" #include "ags/shared/core/platform.h" #define AGS_HAS_DIRECT3D (AGS_PLATFORM_OS_WINDOWS) #define AGS_HAS_OPENGL (AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX) -#include "ags/shared/gfx/ali3dsw.h" -#include "ags/shared/gfx/gfxfilter_allegro.h" +#include "ags/engine/gfx/ali3dsw.h" +#include "ags/engine/gfx/gfxfilter_allegro.h" #if AGS_HAS_OPENGL -#include "ags/shared/gfx/ali3dogl.h" -#include "ags/shared/gfx/gfxfilter_ogl.h" +#include "ags/engine/gfx/ali3dogl.h" +#include "ags/engine/gfx/gfxfilter_ogl.h" #endif #if AGS_HAS_DIRECT3D -#include "ags/shared/platform/windows/gfx/ali3dd3d.h" -#include "ags/shared/gfx/gfxfilter_d3d.h" +#include "ags/engine/platform/windows/gfx/ali3dd3d.h" +#include "ags/engine/gfx/gfxfilter_d3d.h" #endif -#include "ags/shared/main/main_allegro.h" +#include "ags/engine/main/main_allegro.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxdriverfactorybase.h b/engines/ags/engine/gfx/gfxdriverfactorybase.h index 5424ea7c8999..8a1d66d5675d 100644 --- a/engines/ags/engine/gfx/gfxdriverfactorybase.h +++ b/engines/ags/engine/gfx/gfxdriverfactorybase.h @@ -34,8 +34,8 @@ #define AGS_ENGINE_GFX_GFXDRIVERFACTORYBASE_H #include "ags/std/vector.h" -#include "ags/shared/gfx/gfxdriverfactory.h" -#include "ags/shared/gfx/gfxfilter.h" +#include "ags/engine/gfx/gfxdriverfactory.h" +#include "ags/engine/gfx/gfxfilter.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp index eebfbbbed531..fd2161174f50 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.cpp @@ -21,8 +21,7 @@ */ #include "ags/shared/core/platform.h" -#include "ags/shared/stdio.h" -#include "ags/shared/gfx/gfxfilter_aad3d.h" +#include "ags/engine/gfx/gfxfilter_aad3d.h" #if AGS_PLATFORM_OS_WINDOWS //include diff --git a/engines/ags/engine/gfx/gfxfilter_aad3d.h b/engines/ags/engine/gfx/gfxfilter_aad3d.h index 351cfa22b6f7..5396e749cca6 100644 --- a/engines/ags/engine/gfx/gfxfilter_aad3d.h +++ b/engines/ags/engine/gfx/gfxfilter_aad3d.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_AAD3DGFXFILTER_H #define AGS_ENGINE_GFX_AAD3DGFXFILTER_H -#include "ags/shared/gfx/gfxfilter_d3d.h" +#include "ags/engine/gfx/gfxfilter_d3d.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.h b/engines/ags/engine/gfx/gfxfilter_aaogl.h index 6c4036549482..071cfc7b91a5 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.h +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_AAOGLGFXFILTER_H #define AGS_ENGINE_GFX_AAOGLGFXFILTER_H -#include "ags/shared/gfx/gfxfilter_ogl.h" +#include "ags/engine/gfx/gfxfilter_ogl.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index b1f1a93ed122..94640f0daefd 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/gfx/gfxfilter_allegro.h" +#include "ags/engine/gfx/gfxfilter_allegro.h" namespace AGS3 { namespace AGS { @@ -98,13 +98,13 @@ void AllegroGfxFilter::RenderScreenFlipped(Bitmap *toRender, int x, int y, Globa switch (flipType) { case kFlip_Horizontal: - virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HFlip); + virtualScreen->FlipBlt(toRender, 0, 0, Shared::kBitmap_HFlip); break; case kFlip_Vertical: - virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_VFlip); + virtualScreen->FlipBlt(toRender, 0, 0, Shared::kBitmap_VFlip); break; case kFlip_Both: - virtualScreen->FlipBlt(toRender, 0, 0, Common::kBitmap_HVFlip); + virtualScreen->FlipBlt(toRender, 0, 0, Shared::kBitmap_HVFlip); break; default: virtualScreen->Blit(toRender, 0, 0); diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h index e0906d41d5f6..d1aba1542134 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.h +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -30,8 +30,8 @@ #define AGS_ENGINE_GFX_ALLEGROGFXFILTER_H #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/gfxfilter_scaling.h" -#include "ags/shared/gfx/gfxdefines.h" +#include "ags/engine/gfx/gfxfilter_scaling.h" +#include "ags/engine/gfx/gfxdefines.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.cpp b/engines/ags/engine/gfx/gfxfilter_d3d.cpp index 9e4eb302e542..ecba7a45c6f9 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.cpp +++ b/engines/ags/engine/gfx/gfxfilter_d3d.cpp @@ -21,7 +21,7 @@ */ #include "ags/shared/core/platform.h" -#include "ags/shared/gfx/gfxfilter_d3d.h" +#include "ags/engine/gfx/gfxfilter_d3d.h" #if AGS_PLATFORM_OS_WINDOWS //include #endif diff --git a/engines/ags/engine/gfx/gfxfilter_d3d.h b/engines/ags/engine/gfx/gfxfilter_d3d.h index e5cd2b239574..c4be89a8cadf 100644 --- a/engines/ags/engine/gfx/gfxfilter_d3d.h +++ b/engines/ags/engine/gfx/gfxfilter_d3d.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_D3DGFXFILTER_H #define AGS_ENGINE_GFX_D3DGFXFILTER_H -#include "ags/shared/gfx/gfxfilter_scaling.h" +#include "ags/engine/gfx/gfxfilter_scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp index 2acd26f0d49f..cd46a97c5036 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.cpp +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -21,8 +21,8 @@ */ #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/gfxfilter_hqx.h" -#include "ags/shared/gfx/hq2x3x.h" +#include "ags/engine/gfx/gfxfilter_hqx.h" +#include "ags/engine/gfx/hq2x3x.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h index 8cc897357f59..06a1e45bfd46 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.h +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_HQ2XGFXFILTER_H #define AGS_ENGINE_GFX_HQ2XGFXFILTER_H -#include "ags/shared/gfx/gfxfilter_allegro.h" +#include "ags/engine/gfx/gfxfilter_allegro.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.cpp b/engines/ags/engine/gfx/gfxfilter_ogl.cpp index 3615d025b18d..44edd0db5fee 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_ogl.cpp @@ -24,8 +24,8 @@ #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX -#include "ags/shared/gfx/gfxfilter_ogl.h" -#include "ags/shared/ogl_headers.h" +#include "ags/engine/gfx/gfxfilter_ogl.h" +#include "ags/engine/gfx/ogl_headers.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_ogl.h b/engines/ags/engine/gfx/gfxfilter_ogl.h index 786dba62c2ca..a6d5b9bbdb15 100644 --- a/engines/ags/engine/gfx/gfxfilter_ogl.h +++ b/engines/ags/engine/gfx/gfxfilter_ogl.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_OGLGFXFILTER_H #define AGS_ENGINE_GFX_OGLGFXFILTER_H -#include "ags/shared/gfx/gfxfilter_scaling.h" +#include "ags/engine/gfx/gfxfilter_scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.cpp b/engines/ags/engine/gfx/gfxfilter_scaling.cpp index 71cbb5af3b50..d57aa8c5ecfe 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.cpp +++ b/engines/ags/engine/gfx/gfxfilter_scaling.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/gfx/gfxfilter_scaling.h" +#include "ags/engine/gfx/gfxfilter_scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/gfxfilter_scaling.h b/engines/ags/engine/gfx/gfxfilter_scaling.h index 52f420979e6c..21020f15cc1c 100644 --- a/engines/ags/engine/gfx/gfxfilter_scaling.h +++ b/engines/ags/engine/gfx/gfxfilter_scaling.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_GFX_SCALINGGFXFILTER_H #define AGS_ENGINE_GFX_SCALINGGFXFILTER_H -#include "ags/shared/gfx/gfxfilter.h" -#include "ags/shared/util/scaling.h" +#include "ags/engine/gfx/gfxfilter.h" +#include "ags/engine/util/scaling.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/gfx/ogl_headers.h b/engines/ags/engine/gfx/ogl_headers.h index 6fa7e481b824..b3591766c3aa 100644 --- a/engines/ags/engine/gfx/ogl_headers.h +++ b/engines/ags/engine/gfx/ogl_headers.h @@ -28,7 +28,9 @@ #include "ags/shared/core/platform.h" -#if AGS_PLATFORM_OS_WINDOWS +#if AGS_PLATFORM_SCUMMVM +#include "ags/lib/opengl/opengl.h" +#elif AGS_PLATFORM_OS_WINDOWS #include "ags/lib/allegro.h" //include //include @@ -41,8 +43,8 @@ //include //include -#include "ags/shared/glad/glad.h" -#include "ags/shared/glad/glad_glx.h" +//include "glad/glad.h" +//include "glad/glad_glx.h" #elif AGS_PLATFORM_OS_ANDROID diff --git a/engines/ags/lib/aastr-0.1.1/aautil.cpp b/engines/ags/lib/aastr-0.1.1/aautil.cpp index 25b789c36ffd..ebd0889cf31f 100644 --- a/engines/ags/lib/aastr-0.1.1/aautil.cpp +++ b/engines/ags/lib/aastr-0.1.1/aautil.cpp @@ -725,7 +725,7 @@ _aa_add_rgb32 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned lo void _aa_put_rgb8 (unsigned long _addr, int _x) { - bmp_write8 (_addr + _x, makecol8 (_aa.r, _aa.g, _aa.b)); + bmp_write8 (_addr + _x, makecol8(_aa.r, _aa.g, _aa.b)); } #ifdef ALLEGRO_COLOR16 void diff --git a/engines/ags/lib/allegro/alconfig.h b/engines/ags/lib/allegro/alconfig.h index c6dc71b84f32..7e390ee09ca1 100644 --- a/engines/ags/lib/allegro/alconfig.h +++ b/engines/ags/lib/allegro/alconfig.h @@ -39,7 +39,7 @@ namespace AGS3 { #endif #ifndef AL_CONST -#define AL_CONST +#define AL_CONST const #endif #ifndef AL_VAR diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 6756d1ab2c65..5126e5c62eaa 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -41,6 +41,9 @@ int _rgb_g_shift_32 = 0; int _rgb_b_shift_32 = 0; int _rgb_a_shift_32 = 0; +AL_ARRAY(int, _rgb_scale_5); +AL_ARRAY(int, _rgb_scale_6); + PALETTE _current_palette; int bestfit_color(const PALETTE pal, int r, int g, int b) { @@ -53,9 +56,9 @@ void set_color(int idx, const RGB *p) { } void set_palette(const PALETTE p) { - for (int idx = 0; idx < PALETTE_COUNT; ++idx) + for (int idx = 0; idx < PAL_SIZE; ++idx) _current_palette[idx] = p[idx]; - g_system->getPaletteManager()->setPalette((const byte *)p, 0, PALETTE_COUNT); + g_system->getPaletteManager()->setPalette((const byte *)p, 0, PAL_SIZE); } void set_palette_range(const PALETTE p, int from, int to, int retracesync) { @@ -76,7 +79,15 @@ int makeacol(int r, int g, int b, int a) { } int makeacol_depth(int color_depth, int r, int g, int b, int a) { - error("makeacol_depth"); + error("TODO: makeacol_depth"); +} + +void hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b) { + error("TODO: hsv_to_rgb"); +} + +void rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v) { + error("TODO: rgb_to_hsv"); } int makecol15(int r, int g, int b) { @@ -122,6 +133,46 @@ int getb8(int c) { return (int)_current_palette[c].b; } +int getr15(int c) { + return _rgb_scale_5[(c >> _rgb_r_shift_15) & 0x1F]; +} + +int getg15(int c) { + return _rgb_scale_5[(c >> _rgb_g_shift_15) & 0x1F]; +} + +int getb15(int c) { + return _rgb_scale_5[(c >> _rgb_b_shift_15) & 0x1F]; +} + +int getr16(int c) { + return _rgb_scale_5[(c >> _rgb_r_shift_16) & 0x1F]; +} + +int getg16(int c) { + return _rgb_scale_6[(c >> _rgb_g_shift_16) & 0x3F]; +} + +int getb16(int c) { + return _rgb_scale_5[(c >> _rgb_b_shift_16) & 0x1F]; +} + +int getr32(int c) { + error("TODO: getr32"); +} + +int getg32(int c) { + error("TODO: getg32"); +} + +int getb32(int c) { + error("TODO: getb32"); +} + +int geta32(int c) { + error("TODO: geta32"); +} + int makecol(byte r, byte g, byte b) { return (b) | (g << 8) | (r << 16); } diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index cc1c86a95e37..c5b92444f4fb 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -28,13 +28,15 @@ namespace AGS3 { -#define PALETTE_COUNT 256 +#define PAL_SIZE 256 #define MASK_COLOR_8 0 #define MASK_COLOR_15 0x7C1F #define MASK_COLOR_16 0xF81F #define MASK_COLOR_24 0xFF00FF #define MASK_COLOR_32 0xFF00FF +class BITMAP; + #include "common/pack-start.h" // START STRUCT PACKING struct color { @@ -42,15 +44,28 @@ struct color { } PACKED_STRUCT; typedef color RGB; -typedef color PALETTE[PALETTE_COUNT]; +typedef RGB PALETTE[PAL_SIZE]; AL_VAR(PALETTE, _current_palette); #include "common/pack-end.h" // END STRUCT PACKING -//define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) +struct RGB_MAP { + byte data[32][32][32]; +}; + +struct COLOR_MAP { + byte data[PAL_SIZE][PAL_SIZE]; +}; + +AL_VAR(PALETTE, black_palette); +AL_VAR(PALETTE, desktop_palette); +AL_VAR(PALETTE, default_palette); -extern int bestfit_color(const PALETTE pal, int r, int g, int b); +AL_VAR(RGB_MAP *, rgb_map); +AL_VAR(COLOR_MAP *, color_map); + +AL_VAR(PALETTE, _current_palette); extern int _rgb_r_shift_15; extern int _rgb_g_shift_15; @@ -66,12 +81,82 @@ extern int _rgb_g_shift_32; extern int _rgb_b_shift_32; extern int _rgb_a_shift_32; +AL_ARRAY(int, _rgb_scale_5); +AL_ARRAY(int, _rgb_scale_6); + AL_FUNC(void, set_color, (int idx, AL_CONST RGB *p)); AL_FUNC(void, set_palette, (AL_CONST PALETTE p)); AL_FUNC(void, set_palette_range, (AL_CONST PALETTE p, int from, int to, int retracesync)); -extern int makeacol(int r, int g, int b, int a); -extern int makeacol_depth(int color_depth, int r, int g, int b, int a); +AL_FUNC(void, get_color, (int idx, RGB *p)); +AL_FUNC(void, get_palette, (PALETTE p)); +AL_FUNC(void, get_palette_range, (PALETTE p, int from, int to)); + +AL_FUNC(void, fade_interpolate, (AL_CONST PALETTE source, AL_CONST PALETTE dest, PALETTE output, int pos, int from, int to)); +AL_FUNC(void, fade_from_range, (AL_CONST PALETTE source, AL_CONST PALETTE dest, int speed, int from, int to)); +AL_FUNC(void, fade_in_range, (AL_CONST PALETTE p, int speed, int from, int to)); +AL_FUNC(void, fade_out_range, (int speed, int from, int to)); +AL_FUNC(void, fade_from, (AL_CONST PALETTE source, AL_CONST PALETTE dest, int speed)); +AL_FUNC(void, fade_in, (AL_CONST PALETTE p, int speed)); +AL_FUNC(void, fade_out, (int speed)); + +AL_FUNC(void, select_palette, (AL_CONST PALETTE p)); +AL_FUNC(void, unselect_palette, (void)); + +AL_FUNC(void, generate_332_palette, (PALETTE pal)); +AL_FUNC(int, generate_optimized_palette, (BITMAP *image, PALETTE pal, AL_CONST signed char rsvdcols[256])); + +AL_FUNC(void, create_rgb_table, (RGB_MAP *table, AL_CONST PALETTE pal, AL_METHOD(void, callback, (int pos)))); +AL_FUNC(void, create_light_table, (COLOR_MAP *table, AL_CONST PALETTE pal, int r, int g, int b, AL_METHOD(void, callback, (int pos)))); +AL_FUNC(void, create_trans_table, (COLOR_MAP *table, AL_CONST PALETTE pal, int r, int g, int b, AL_METHOD(void, callback, (int pos)))); +AL_FUNC(void, create_color_table, (COLOR_MAP *table, AL_CONST PALETTE pal, AL_METHOD(void, blend, (AL_CONST PALETTE pal, int x, int y, RGB *rgb)), AL_METHOD(void, callback, (int pos)))); +AL_FUNC(void, create_blender_table, (COLOR_MAP *table, AL_CONST PALETTE pal, AL_METHOD(void, callback, (int pos)))); + +typedef AL_METHOD(unsigned long, BLENDER_FUNC, (unsigned long x, unsigned long y, unsigned long n)); + +AL_FUNC(void, set_blender_mode, (BLENDER_FUNC b15, BLENDER_FUNC b16, BLENDER_FUNC b24, int r, int g, int b, int a)); +AL_FUNC(void, set_blender_mode_ex, (BLENDER_FUNC b15, BLENDER_FUNC b16, BLENDER_FUNC b24, BLENDER_FUNC b32, BLENDER_FUNC b15x, BLENDER_FUNC b16x, BLENDER_FUNC b24x, int r, int g, int b, int a)); + +AL_FUNC(void, set_alpha_blender, (void)); +AL_FUNC(void, set_write_alpha_blender, (void)); +AL_FUNC(void, set_trans_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_add_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_burn_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_color_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_difference_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_dissolve_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_dodge_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_hue_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_invert_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_luminance_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_multiply_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_saturation_blender, (int r, int g, int b, int a)); +AL_FUNC(void, set_screen_blender, (int r, int g, int b, int a)); + +AL_FUNC(void, hsv_to_rgb, (float h, float s, float v, int *r, int *g, int *b)); +AL_FUNC(void, rgb_to_hsv, (int r, int g, int b, float *h, float *s, float *v)); + +AL_FUNC(int, bestfit_color, (AL_CONST PALETTE pal, int r, int g, int b)); + +AL_FUNC(int, makecol, (int r, int g, int b)); +AL_FUNC(int, makecol8, (int r, int g, int b)); +AL_FUNC(int, makecol_depth, (int color_depth, int r, int g, int b)); + +AL_FUNC(int, makeacol, (int r, int g, int b, int a)); +AL_FUNC(int, makeacol_depth, (int color_depth, int r, int g, int b, int a)); + +AL_FUNC(int, makecol15_dither, (int r, int g, int b, int x, int y)); +AL_FUNC(int, makecol16_dither, (int r, int g, int b, int x, int y)); + +AL_FUNC(int, getr, (int c)); +AL_FUNC(int, getg, (int c)); +AL_FUNC(int, getb, (int c)); +AL_FUNC(int, geta, (int c)); + +AL_FUNC(int, getr_depth, (int color_depth, int c)); +AL_FUNC(int, getg_depth, (int color_depth, int c)); +AL_FUNC(int, getb_depth, (int color_depth, int c)); +AL_FUNC(int, geta_depth, (int color_depth, int c)); extern int makecol15(int r, int g, int b); extern int makecol16(int r, int g, int b); @@ -81,8 +166,16 @@ extern int makeacol32(int r, int g, int b, int a); extern int getr8(int c); extern int getg8(int c); extern int getb8(int c); -extern int makecol(byte r, byte g, byte b); -extern int makecol8(byte r, byte g, byte b); +extern int getr15(int c); +extern int getg15(int c); +extern int getb15(int c); +extern int getr16(int c); +extern int getg16(int c); +extern int getb16(int c); +extern int getr32(int c); +extern int getg32(int c); +extern int getb32(int c); +extern int geta32(int c); extern int getr_depth(int color_depth, int c); extern int getg_depth(int color_depth, int c); diff --git a/engines/ags/lib/allegro/system.cpp b/engines/ags/lib/allegro/system.cpp index 67a6d806a44e..b372b7ebdd83 100644 --- a/engines/ags/lib/allegro/system.cpp +++ b/engines/ags/lib/allegro/system.cpp @@ -31,12 +31,31 @@ SYSTEM_DRIVER system_none; SYSTEM_DRIVER *system_driver; _DRIVER_INFO _system_driver_list[] = { -// { SYSTEM_IOS, &system_none, true }, { SYSTEM_NONE, &system_none, false }, { 0, nullptr , 0 } }; +GFX_MODE_LIST *get_gfx_mode_list(int card) { + assert(card == 0); + + GFX_MODE_LIST *list = new GFX_MODE_LIST(); + list->num_modes = 1; + list->mode = new GFX_MODE[1]; + + GFX_MODE &gm = list->mode[0]; + gm.width = 320; + gm.height = 200; + gm.bpp = 16; + + return list; +} + +void destroy_gfx_mode_list(GFX_MODE_LIST *list) { + delete[] list->mode; + delete list; +} + void set_color_depth(int depth) { color_depth = depth; } diff --git a/engines/ags/lib/allegro/system.h b/engines/ags/lib/allegro/system.h index fbd1f104295a..be5759b02f99 100644 --- a/engines/ags/lib/allegro/system.h +++ b/engines/ags/lib/allegro/system.h @@ -43,7 +43,7 @@ struct GFX_MODE { struct GFX_MODE_LIST { int num_modes; /* number of gfx modes */ - GFX_MODE *mode; /* pointer to the actual mode list array */ + GFX_MODE *mode; /* pointer to the actual mode list array */ }; struct SYSTEM_DRIVER { @@ -88,6 +88,44 @@ struct SYSTEM_DRIVER { AL_METHOD(_DRIVER_INFO *, timer_drivers, (void)); }; +/* creates and manages the screen bitmap */ +struct GFX_DRIVER { + int id; + AL_CONST char *name; + AL_CONST char *desc; + AL_CONST char *ascii_name; + AL_METHOD(BITMAP *, init, (int w, int h, int v_w, int v_h, int color_depth)); + AL_METHOD(void, exit, (BITMAP *b)); + AL_METHOD(int, scroll, (int x, int y)); + AL_METHOD(void, vsync, (void)); + AL_METHOD(void, set_palette, (AL_CONST RGB *p, int from, int to, int retracesync)); + AL_METHOD(int, request_scroll, (int x, int y)); + AL_METHOD(int, poll_scroll, (void)); + AL_METHOD(void, enable_triple_buffer, (void)); + AL_METHOD(BITMAP *, create_video_bitmap, (int width, int height)); + AL_METHOD(void, destroy_video_bitmap, (BITMAP *bitmap)); + AL_METHOD(int, show_video_bitmap, (BITMAP *bitmap)); + AL_METHOD(int, request_video_bitmap, (BITMAP *bitmap)); + AL_METHOD( BITMAP *, create_system_bitmap, (int width, int height)); + AL_METHOD(void, destroy_system_bitmap, (BITMAP *bitmap)); + AL_METHOD(int, set_mouse_sprite, (BITMAP *sprite, int xfocus, int yfocus)); + AL_METHOD(int, show_mouse, (BITMAP *bmp, int x, int y)); + AL_METHOD(void, hide_mouse, (void)); + AL_METHOD(void, move_mouse, (int x, int y)); + AL_METHOD(void, drawing_mode, (void)); + AL_METHOD(void, save_video_state, (void)); + AL_METHOD(void, restore_video_state, (void)); + AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); + AL_METHOD(GFX_MODE_LIST *, fetch_mode_list, (void)); + int w, h; /* physical (not virtual!) screen size */ + int linear; /* true if video memory is linear */ + long bank_size; /* bank size, in bytes */ + long bank_gran; /* bank granularity, in bytes */ + long vid_mem; /* video memory size, in bytes */ + long vid_phys_base; /* physical address of video memory */ + int windowed; /* true if driver runs windowed */ +}; + extern SYSTEM_DRIVER system_none; extern SYSTEM_DRIVER *system_driver; extern _DRIVER_INFO _system_driver_list[]; @@ -98,6 +136,11 @@ extern int get_desktop_resolution(int *width, int *height); extern void request_refresh_rate(int rate); extern void set_close_button_callback(void(*proc)()); +extern GFX_MODE_LIST *get_gfx_mode_list(int card); +extern void destroy_gfx_mode_list(GFX_MODE_LIST *list); + +inline void vsync() {} + } // namespace AGS3 #endif diff --git a/engines/ags/lib/opengl/opengl.cpp b/engines/ags/lib/opengl/opengl.cpp new file mode 100644 index 000000000000..ba367d006745 --- /dev/null +++ b/engines/ags/lib/opengl/opengl.cpp @@ -0,0 +1,117 @@ +/* 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 "ags/lib/opengl/opengl.h" +#include "common/array.h" +#include "graphics/managed_surface.h" +#include "common/system.h" + +namespace AGS3 { + +Common::Array texturesArray; +uint32 currentColor, clearColor; + +const GLubyte *glGetString(GLenum name) { + switch (name) { + case GL_VERSION: + return (const GLubyte *)"ScummVM"; + case GL_EXTENSIONS: + return (const GLubyte *)"ScummVM Extensions"; + default: + return nullptr; + } +} + +void glTexParameteri(GLenum target, GLenum pname, GLint param) { + // No implementation +} + +void glDeleteTextures(GLsizei n, const GLuint *textures) { + for (; n > 0; --n, ++textures) { + texturesArray[*textures].clear(); + } +} + +GLint glGetUniformLocation(GLuint program, const GLchar *name) { + error("TODO: glGetUniformLocation"); +} + +void glShadeModel(GLenum mode) { + error("TODO: glShadeMode"); +} + +void glGetProgramiv(GLuint program, GLenum pname, GLint *params) { + assert(pname == GL_LINK_STATUS); + *params = GL_TRUE; +} + +void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + Graphics::PixelFormat format = g_system->getScreenFormat(); + currentColor = format.RGBToColor((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255)); +} + +void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + Graphics::PixelFormat format = g_system->getScreenFormat(); + clearColor = format.RGBToColor((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255)); +} + +void glClear(GLbitfield mask) { + warning("TODO: glClear"); +} + +void glDrawArrays(GLenum mode, GLint first, GLsizei count) { + warning("TODO: glDrawArrays"); +} + +void glReadBuffer(GLenum mode) { + warning("TODO: glReadBuffer"); +} + +void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data) { + warning("TODO: glReadPixels"); +} + +void glGetIntegerv(GLenum pname, GLint *data) { + // TODO: glGetIntegerv + *data = 0; +} + +void glGetFloatv(GLenum pname, GLfloat *params) { + // TODO: glGetFloatv + *params = 0.0; +} + +void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { + warning("TODO: glTexSubImage2D"); +} + +void glTexImage2D(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *data) { + warning("TODO: glTexImage2D"); +} + +void glGenTextures(GLsizei n, GLuint *textures) { + warning("TODO: glGenTextures"); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/opengl/opengl.h b/engines/ags/lib/opengl/opengl.h new file mode 100644 index 000000000000..3e6ecd89cf23 --- /dev/null +++ b/engines/ags/lib/opengl/opengl.h @@ -0,0 +1,166 @@ +/* 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 AGS_LIB_OPENGL_OPENGL_H +#define AGS_LIB_OPENGL_OPENGL_H + +#include "common/scummsys.h" + +namespace AGS3 { + +#define GL_TRUE 1 +#define GL_FALSE 2 + +#define GFX_XWINDOWS MKTAG('S', 'C', 'V', 'M') +#define GFX_XWINDOWS_FULLSCREEN MKTAG('S', 'C', 'V', 'M') +#define GL_FLOAT 1 + +// glEnable/glDisable +#define GL_BLEND 1 +#define GL_SCISSOR_TEST 2 +#define GL_CULL_FACE 3 +#define GL_DEPTH_TEST 4 +#define GL_LIGHTING 5 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_NEAREST 0x2600 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 + +// glBlendFunc +#define GL_SRC_ALPHA 1 +#define GL_ONE_MINUS_SRC_ALPHA 2 + +// glShadeModel +#define GL_FLAT 1 + +// glGetString +#define GL_VERSION 1 +#define GL_EXTENSIONS 2 + +// glGetProgramiv +#define GL_LINK_STATUS 1 + +// glClear +#define GL_COLOR_BUFFER_BIT 1 + +// glMatrixMode +#define GL_PROJECTION 1 +#define GL_MODELVIEW 2 + +// glEnableClientState/glDisableClientState +#define GL_COLOR_ARRAY 1 +#define GL_NORMAL_ARRAY 2 +#define GL_VERTEX_ARRAY 3 +#define GL_TEXTURE_COORD_ARRAY 4 + +// glTexParameteri +#define GL_LINEAR 1 +#define GL_CLAMP 2 +#define GL_TEXTURE_WRAP_T 3 +#define GL_TEXTURE_WRAP_S 4 + +// glBindFramebufferEXT +#define GL_FRAMEBUFFER_EXT 1 + +// glReadBuffer +#define GL_FRONT 1 + +// glReadPixels +#define GL_RGBA 1 +#define GL_UNSIGNED_BYTE 2 + +// glDrawArrays +#define GL_TRIANGLE_STRIP 1 + +// glGetIntegerv/glGetFloatv +#define GL_MAX_TEXTURE_SIZE 1 +#define GL_MODELVIEW_MATRIX 2 + + +typedef char GLchar; +typedef byte GLubyte; +typedef uint GLenum; +typedef int GLint; +typedef uint32 GLuint; +typedef uint GLbitfield; +typedef float GLfloat; +typedef double GLdouble; +typedef size_t GLsizei; + +struct GLXContextStruct { +}; +typedef GLXContextStruct *GLXContext; + +inline bool gladLoadGL() { return true; } +inline void glFinish() {} + +inline int glCreateProgram() { return 1; } +inline void glDeleteProgram(int prog) {} +inline void glEnable(GLenum cap) {} +inline void glDisable(GLenum cap) {} +inline void glBlendFunc(GLenum sfactor, GLenum dfactor) {} +inline void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {} +inline void glMatrixMode(GLenum mode) {} +inline void glLoadIdentity() {} +inline void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, + GLdouble nearVal, GLdouble farVal); +inline void glEnableClientState(GLenum arr) {} +inline void glDisableClientState(GLenum arr) {} +inline void glUseProgram(GLuint program) {} +inline void glUniform1f(GLint location, GLfloat v0) {} +inline void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {} +inline void glUniform1i(GLint location, GLint v0) {} +inline void glTranslatef(GLfloat x, GLfloat y, GLfloat z) {} +inline void glMultMatrixf(const GLfloat *m) {} +inline void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +inline void glScalef(GLfloat x, GLfloat y, GLfloat z); +inline void glBindTexture(GLenum target, GLuint texture) {} +inline void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); +inline void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {} +inline void glBindFramebufferEXT(GLenum v1, uint v2) {} +inline void glDeleteFramebuffersEXT(int v1, uint *v2) {} +inline void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {} + +extern const GLubyte *glGetString(GLenum name); +extern void glTexParameteri(GLenum target, GLenum pname, GLint param); +extern void glDeleteTextures(GLsizei n, const GLuint *textures); +extern GLint glGetUniformLocation(GLuint program, const GLchar *name); +extern void glShadeModel(GLenum mode); +extern void glGetProgramiv(GLuint program, GLenum pname, GLint *params); + +extern void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +extern void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +extern void glClear(GLbitfield mask); +extern void glDrawArrays(GLenum mode, GLint first, GLsizei count); +extern void glReadBuffer(GLenum mode); +extern void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *data); +extern void glGetIntegerv(GLenum pname, GLint *data); +extern void glGetFloatv(GLenum pname, GLfloat *params); +extern void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +extern void glTexImage2D(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *data); +extern void glGenTextures(GLsizei n, GLuint *textures); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 793bc264d95d..037cda3400c3 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -20,6 +20,7 @@ MODULE_OBJS = \ lib/allegro/sound.o \ lib/allegro/system.o \ lib/allegro/unicode.o \ + lib/opengl/opengl.o \ lib/system/datetime.o \ shared/ac/dynobj/scriptaudioclip.o \ shared/ac/audiocliptype.o \ @@ -83,6 +84,20 @@ MODULE_OBJS = \ engine/game/savegame.o \ engine/game/savegame_components.o \ engine/game/viewport.o \ + engine/gfx/all3dd3d.o \ + engine/gfx/ali3dogl.o \ + engine/gfx/ali3dsw.o \ + engine/gfx/blender.o \ + engine/gfx/color_engine.o \ + engine/gfx/gfx_util.o \ + engine/gfx/gfxdriverbase.o \ + engine/gfx/gfxdriverfactory.o \ + engine/gfx/gfxfilter_aad3d.o \ + engine/gfx/gfxfilter_allegro.o \ + engine/gfx/gfxfilter_d3d.o \ + engine/gfx/gfxfilter_hqx.o \ + engine/gfx/gfxfilter_ogl.o \ + engine/gfx/gfxfilter_scaling.o \ engine/gui/animatingguibutton.o \ engine/gui/cscidialog.o \ engine/gui/guidialog.o \ diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h index 67ded4ac4b1a..bcac2025a1eb 100644 --- a/engines/ags/shared/core/platform.h +++ b/engines/ags/shared/core/platform.h @@ -29,14 +29,16 @@ namespace AGS3 { // ScummVM implementation is identifying as Linux for now #if 1 +#define AGS_PLATFORM_SCUMMVM (1) #define AGS_PLATFORM_OS_WINDOWS (0) #define AGS_PLATFORM_OS_LINUX (1) #define AGS_PLATFORM_OS_MACOS (0) -#define AGS_PLATFORM_OS_ANDROID (1) +#define AGS_PLATFORM_OS_ANDROID (0) #define AGS_PLATFORM_OS_IOS (0) #define AGS_PLATFORM_OS_PSP (0) // check Android first because sometimes it can get confused with host OS #elif defined(__ANDROID__) || defined(ANDROID) +#define AGS_PLATFORM_SCUMMVM (0) #define AGS_PLATFORM_OS_WINDOWS (0) #define AGS_PLATFORM_OS_LINUX (0) #define AGS_PLATFORM_OS_MACOS (0) @@ -45,6 +47,7 @@ namespace AGS3 { #define AGS_PLATFORM_OS_PSP (0) #elif defined(_WIN32) //define something for Windows (32-bit and 64-bit) +#define AGS_PLATFORM_SCUMMVM (0) #define AGS_PLATFORM_OS_WINDOWS (1) #define AGS_PLATFORM_OS_LINUX (0) #define AGS_PLATFORM_OS_MACOS (0) @@ -52,6 +55,7 @@ namespace AGS3 { #define AGS_PLATFORM_OS_IOS (0) #define AGS_PLATFORM_OS_PSP (0) #elif defined(__APPLE__) +#define AGS_PLATFORM_SCUMMVM (0) #include "ags/shared/TargetConditionals.h" #ifndef TARGET_OS_SIMULATOR #define TARGET_OS_SIMULATOR (0) diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index 3bf23121d98b..f1e3dd1b54ad 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -87,6 +87,11 @@ typedef int64 intptr_t; #define UINT_MAX 0xffffffff #define SIZE_MAX 0xffffffff +#undef TRUE +#undef FALSE +#define TRUE true +#define FALSE false + // TODO: use distinct fixed point class enum { kShift = 16, diff --git a/engines/ags/std/algorithm.h b/engines/ags/std/algorithm.h index 8b5f070125bb..8599dc0878f9 100644 --- a/engines/ags/std/algorithm.h +++ b/engines/ags/std/algorithm.h @@ -36,6 +36,11 @@ template inline T clip(T v, T amin, T amax) { return CLIP(v, amin, a template inline T sqrt(T x) { return ::sqrt(x); } template inline void swap(T a, T b) { SWAP(a, b); } +template +In fill(In first, In last, const Value &val) { + return Common::fill(first, last, val); +} + template void sort(T first, T last, StrictWeakOrdering comp) { Common::sort(first, last, comp); diff --git a/engines/ags/std/memory.h b/engines/ags/std/memory.h index 99c85916a08a..7efe2c16f670 100644 --- a/engines/ags/std/memory.h +++ b/engines/ags/std/memory.h @@ -43,6 +43,12 @@ T *memcpy(T *dest, const T *src, size_t n) { return (T *)::memcpy(dest, src, n); } +template +shared_ptr static_pointer_cast(const shared_ptr &src) { + T *ptr = src.get(); + return shared_ptr(ptr); +} + } // namespace std } // namespace AGS3 From 5ee48e1cb8cbb84a7aa0adfda619e20dcceb3312 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 25 Nov 2020 22:18:21 -0800 Subject: [PATCH 029/215] AGS: Warning fixes --- engines/ags/engine/ac/hotspot.h | 2 +- engines/ags/engine/gfx/ali3dogl.cpp | 8 ++-- engines/ags/engine/gfx/ali3dsw.cpp | 4 +- engines/ags/engine/gfx/gfxdriverbase.cpp | 18 +++---- engines/ags/engine/gui/mypushbutton.cpp | 2 +- engines/ags/engine/gui/newcontrol.cpp | 6 ++- engines/ags/engine/main/config.cpp | 2 + engines/ags/engine/main/engine.cpp | 2 +- engines/ags/engine/main/game_run.cpp | 12 ++--- engines/ags/engine/main/graphics_mode.cpp | 2 + .../engine/platform/windows/gfx/ali3dd3d.cpp | 48 +++++++++---------- engines/ags/engine/plugin/agsplugin.cpp | 10 ++-- engines/ags/module.mk | 1 - engines/ags/shared/gfx/bitmap.cpp | 2 +- 14 files changed, 63 insertions(+), 56 deletions(-) diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h index 488254309772..90cf192dffd5 100644 --- a/engines/ags/engine/ac/hotspot.h +++ b/engines/ags/engine/ac/hotspot.h @@ -31,7 +31,7 @@ void Hotspot_SetEnabled(ScriptHotspot *hss, int newval); int Hotspot_GetEnabled(ScriptHotspot *hss); int Hotspot_GetID(ScriptHotspot *hss); ScriptHotspot *GetHotspotAtScreen(int xx, int yy); -int Hotspot_GetWalkToX(ScriptHotspot *hss);; +int Hotspot_GetWalkToX(ScriptHotspot *hss); int Hotspot_GetWalkToY(ScriptHotspot *hss); void Hotspot_GetName(ScriptHotspot *hss, char *buffer); const char *Hotspot_GetName_New(ScriptHotspot *hss); diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 11e19838f6aa..ec1b2825c165 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -1087,7 +1087,7 @@ bool OGLGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_n } void OGLGraphicsDriver::RenderToBackBuffer() { - throw Ali3DException("OGL driver does not have a back buffer"); + error("OGL driver does not have a back buffer"); } void OGLGraphicsDriver::Render() { @@ -1565,10 +1565,10 @@ void OGLGraphicsDriver::UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap void OGLGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { OGLBitmap *target = (OGLBitmap *)bitmapToUpdate; if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) - throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); + error("UpdateDDBFromBitmap: mismatched bitmap size"); const int color_depth = bitmap->GetColorDepth(); if (color_depth != target->_colDepth) - throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); + error("UpdateDDBFromBitmap: mismatched colour depths"); target->_hasAlpha = hasAlpha; if (color_depth == 8) @@ -1620,7 +1620,7 @@ IDriverDependantBitmap *OGLGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, b int allocatedHeight = bitmap->GetHeight(); // NOTE: original bitmap object is not modified in this function if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) - throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); + error("CreateDDBFromBitmap: bitmap colour depth not supported"); int colourDepth = bitmap->GetColorDepth(); OGLBitmap *ddb = new OGLBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index e56761a422e8..9d82d3cb4230 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -459,7 +459,7 @@ void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Sha if (_nullSpriteCallback) _nullSpriteCallback(drawlist[i].x, drawlist[i].y); else - throw Ali3DException("Unhandled attempt to draw null sprite"); + error("Unhandled attempt to draw null sprite"); continue; } else if (drawlist[i].bitmap == (ALSoftwareBitmap *)0x1) { @@ -727,7 +727,7 @@ void ALSoftwareGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int del delete bmp_buff; SetMemoryBackBuffer(bmp_orig); } else { - throw Ali3DException("BoxOut fade-in not implemented in sw gfx driver"); + error("BoxOut fade-in not implemented in sw gfx driver"); } } // end fading routines diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index b8947b7617f6..ce75c9b1ed58 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -189,7 +189,7 @@ void VideoMemoryGraphicsDriver::DestroyAllStageScreens() { bool VideoMemoryGraphicsDriver::DoNullSpriteCallback(int x, int y) { if (!_nullSpriteCallback) - throw Ali3DException("Unhandled attempt to draw null sprite"); + error("Unhandled attempt to draw null sprite"); _stageScreenDirty = false; _stageVirtualScreen->ClearTransparent(); // NOTE: this is not clear whether return value of callback may be @@ -362,11 +362,11 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo } } } else if (src_depth == 32) { - unsigned int *memPtrLong = (unsigned int *)dst_ptr; + unsigned int *ptrLong = (unsigned int *)dst_ptr; unsigned int *srcData = (unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; if (*srcData == MASK_COLOR_32) { if (!usingLinearFiltering) - memPtrLong[x] = 0; + ptrLong[x] = 0; // set to transparent, but use the colour from the neighbouring // pixel to stop the linear filter doing black outlines else { @@ -380,19 +380,19 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo if (y < tile->height - 1) get_pixel_if_not_transparent32((unsigned int *)&scanline_after[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); if (divisor > 0) - memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); + ptrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); else - memPtrLong[x] = 0; + ptrLong[x] = 0; } lastPixelWasTransparent = true; } else if (has_alpha) { - memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); + ptrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); } else { - memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); + ptrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), 0xFF); if (lastPixelWasTransparent) { // update the colour of the previous tranparent pixel, to // stop black outlines when linear filtering - memPtrLong[x - 1] = memPtrLong[x] & 0x00FFFFFF; + ptrLong[x - 1] = ptrLong[x] & 0x00FFFFFF; lastPixelWasTransparent = false; } } @@ -418,7 +418,7 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, con unsigned short *srcData = (unsigned short *)&scanline_at[(x + tile->x) * sizeof(short)]; memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); } else if (src_depth == 32) { - unsigned int *memPtrLong = (unsigned int *)dst_ptr; + //unsigned int *memPtrLong = (unsigned int *)dst_ptr; unsigned int *srcData = (unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; if (has_alpha) memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index 7f462063e676..b5bb5a5da71d 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -50,7 +50,7 @@ MyPushButton::MyPushButton(int xx, int yy, int wi, int hi, const char *tex) { state = 0; strncpy(text, tex, 50); text[49] = 0; -}; +} void MyPushButton::draw(Bitmap *ds) { color_t text_color = ds->GetCompatibleColor(0); diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp index 57f593ec5459..f17d444ed493 100644 --- a/engines/ags/engine/gui/newcontrol.cpp +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -39,7 +39,8 @@ NewControl::NewControl(int xx, int yy, int wi, int hi) { visible = 1; enabled = 1; needredraw = 1; -}; +} + NewControl::NewControl() { x = y = wid = hit = 0; state = 0; @@ -49,6 +50,7 @@ NewControl::NewControl() { enabled = 1; needredraw = 1; } + int NewControl::mouseisinarea(int mousex, int mousey) { if (topwindowhandle != wlevel) return 0; @@ -58,6 +60,7 @@ int NewControl::mouseisinarea(int mousex, int mousey) { return 0; } + void NewControl::drawifneeded() { if (topwindowhandle != wlevel) return; @@ -66,6 +69,7 @@ void NewControl::drawifneeded() { draw(get_gui_screen()); } } + void NewControl::drawandmouse() { // ags_domouse(DOMOUSE_DISABLE); draw(get_gui_screen()); diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index d2095f1b290d..97d54ac784ba 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -175,6 +175,8 @@ String make_scaling_option(FrameScaleDefinition scale_def, int scale_factor) { return "stretch"; case kFrame_MaxProportional: return "proportional"; + default: + break; } return String::FromFormat("%d", scale_factor); } diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 516483f3baa9..a2cf6c6f3d4c 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -488,7 +488,7 @@ void engine_init_audio() { digi_id = digi_drv.first; midi_id = midi_drv.first; const int max_digi_voices = digi_drv.second; - const int max_midi_voices = midi_drv.second; + //const int max_midi_voices = midi_drv.second; if (digi_voices > max_digi_voices) digi_voices = max_digi_voices; // NOTE: we do not specify number of MIDI voices, so don't have to calculate available here diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index d6ae72515269..541b1ab719f9 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -841,24 +841,24 @@ static int ShouldStayInWaitMode() { int retval = restrict_until; if (restrict_until == UNTIL_MOVEEND) { - short *wkptr = (short *)user_disabled_data; + const short *wkptr = (const short *)user_disabled_data; if (wkptr[0] < 1) retval = 0; } else if (restrict_until == UNTIL_CHARIS0) { - char *chptr = (char *)user_disabled_data; + const char *chptr = (const char *)user_disabled_data; if (chptr[0] == 0) retval = 0; } else if (restrict_until == UNTIL_NEGATIVE) { - short *wkptr = (short *)user_disabled_data; + const short *wkptr = (const short *)user_disabled_data; if (wkptr[0] < 0) retval = 0; } else if (restrict_until == UNTIL_INTISNEG) { - int *wkptr = (int *)user_disabled_data; + const int *wkptr = (const int *)user_disabled_data; if (wkptr[0] < 0) retval = 0; } else if (restrict_until == UNTIL_NOOVERLAY) { if (is_text_overlay < 1) retval = 0; } else if (restrict_until == UNTIL_INTIS0) { - int *wkptr = (int *)user_disabled_data; + const int *wkptr = (const int *)user_disabled_data; if (wkptr[0] == 0) retval = 0; } else if (restrict_until == UNTIL_SHORTIS0) { - short *wkptr = (short *)user_disabled_data; + const short *wkptr = (const short *)user_disabled_data; if (wkptr[0] == 0) retval = 0; } else quit("loop_until: unknown until event"); diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp index 7020a0ada670..63490180e9e8 100644 --- a/engines/ags/engine/main/graphics_mode.cpp +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -260,6 +260,8 @@ Size precalc_screen_size(const Size &game_size, const DisplayModeSetup &dm_setup // Set as big as current device size screen_size = device_size; break; + default: + break; } return screen_size; } diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index e099493b9fb1..3a28afb3ba26 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -433,7 +433,7 @@ int D3DGraphicsDriver::FirstTimeInit() { void D3DGraphicsDriver::initD3DDLL(const DisplayMode &mode) { if (!IsModeSupported(mode)) { - throw Ali3DException(get_allegro_error()); + error(get_allegro_error()); } _enter_critical(); @@ -442,7 +442,7 @@ void D3DGraphicsDriver::initD3DDLL(const DisplayMode &mode) { // Set the display mode in the window's thread if (wnd_call_proc(wnd_create_device)) { _exit_critical(); - throw Ali3DException(get_allegro_error()); + error(get_allegro_error()); } availableVideoMemory = direct3ddevice->GetAvailableTextureMem(); @@ -845,10 +845,10 @@ void D3DGraphicsDriver::CreateVirtualScreen() { D3DPOOL_DEFAULT, &pNativeTexture, NULL) != D3D_OK) { - throw Ali3DException("CreateTexture failed"); + error("CreateTexture failed"); } if (pNativeTexture->GetSurfaceLevel(0, &pNativeSurface) != D3D_OK) { - throw Ali3DException("GetSurfaceLevel failed"); + error("GetSurfaceLevel failed"); } direct3ddevice->ColorFill(pNativeSurface, NULL, 0); @@ -1000,16 +1000,16 @@ bool D3DGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_n D3DPOOL_SYSTEMMEM, &surface, NULL) != D3D_OK) { - throw Ali3DException("CreateOffscreenPlainSurface failed"); + error("CreateOffscreenPlainSurface failed"); } if (direct3ddevice->GetRenderTargetData(pNativeSurface, surface) != D3D_OK) { - throw Ali3DException("GetRenderTargetData failed"); + error("GetRenderTargetData failed"); } } // Get the back buffer surface else if (direct3ddevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &surface) != D3D_OK) { - throw Ali3DException("IDirect3DDevice9::GetBackBuffer failed"); + error("IDirect3DDevice9::GetBackBuffer failed"); } if (_pollingCallback) @@ -1017,7 +1017,7 @@ bool D3DGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_n D3DLOCKED_RECT lockedRect; if (surface->LockRect(&lockedRect, (at_native_res ? NULL : &viewport_rect), D3DLOCK_READONLY) != D3D_OK) { - throw Ali3DException("IDirect3DSurface9::LockRect failed"); + error("IDirect3DSurface9::LockRect failed"); } BitmapHelper::ReadPixelsFromMemory(destination, (uint8_t *)lockedRect.pBits, lockedRect.Pitch); @@ -1032,7 +1032,7 @@ bool D3DGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_n } void D3DGraphicsDriver::RenderToBackBuffer() { - throw Ali3DException("D3D driver does not have a back buffer"); + error("D3D driver does not have a back buffer"); } void D3DGraphicsDriver::Render() { @@ -1139,7 +1139,7 @@ void D3DGraphicsDriver::_renderSprite(const D3DDrawListEntry *drawListEntry, con hr = direct3ddevice->SetStreamSource(0, bmpToDraw->_vertex, 0, sizeof(CUSTOMVERTEX)); } if (hr != D3D_OK) { - throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); + error("IDirect3DDevice9::SetStreamSource failed"); } float width = bmpToDraw->GetWidthToRender(); @@ -1195,7 +1195,7 @@ void D3DGraphicsDriver::_renderSprite(const D3DDrawListEntry *drawListEntry, con hr = direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, ti * 4, 2); if (hr != D3D_OK) { - throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); + error("IDirect3DDevice9::DrawPrimitive failed"); } } @@ -1203,7 +1203,7 @@ void D3DGraphicsDriver::_renderSprite(const D3DDrawListEntry *drawListEntry, con void D3DGraphicsDriver::_renderFromTexture() { if (direct3ddevice->SetStreamSource(0, vertexbuffer, 0, sizeof(CUSTOMVERTEX)) != D3D_OK) { - throw Ali3DException("IDirect3DDevice9::SetStreamSource failed"); + error("IDirect3DDevice9::SetStreamSource failed"); } float width = _srcRect.GetWidth(); @@ -1224,7 +1224,7 @@ void D3DGraphicsDriver::_renderFromTexture() { direct3ddevice->SetTexture(0, pNativeTexture); if (direct3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2) != D3D_OK) { - throw Ali3DException("IDirect3DDevice9::DrawPrimitive failed"); + error("IDirect3DDevice9::DrawPrimitive failed"); } } @@ -1237,19 +1237,19 @@ void D3DGraphicsDriver::_render(bool clearDrawListAfterwards) { IDirect3DSurface9 *pBackBuffer = NULL; if (direct3ddevice->GetRenderTarget(0, &pBackBuffer) != D3D_OK) { - throw Ali3DException("IDirect3DSurface9::GetRenderTarget failed"); + error("IDirect3DSurface9::GetRenderTarget failed"); } direct3ddevice->ColorFill(pBackBuffer, nullptr, D3DCOLOR_RGBA(0, 0, 0, 255)); if (!_renderSprAtScreenRes) { if (direct3ddevice->SetRenderTarget(0, pNativeSurface) != D3D_OK) { - throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); + error("IDirect3DSurface9::SetRenderTarget failed"); } } direct3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.5f, 0); if (direct3ddevice->BeginScene() != D3D_OK) - throw Ali3DException("IDirect3DDevice9::BeginScene failed"); + error("IDirect3DDevice9::BeginScene failed"); // if showing at 2x size, the sprite can get distorted otherwise direct3ddevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); @@ -1260,7 +1260,7 @@ void D3DGraphicsDriver::_render(bool clearDrawListAfterwards) { if (!_renderSprAtScreenRes) { if (direct3ddevice->SetRenderTarget(0, pBackBuffer) != D3D_OK) { - throw Ali3DException("IDirect3DSurface9::SetRenderTarget failed"); + error("IDirect3DSurface9::SetRenderTarget failed"); } direct3ddevice->SetViewport(&_d3dViewport); _renderFromTexture(); @@ -1426,7 +1426,7 @@ void D3DGraphicsDriver::UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap D3DLOCKED_RECT lockedRegion; HRESULT hr = newTexture->LockRect(0, &lockedRegion, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD); if (hr != D3D_OK) { - throw Ali3DException("Unable to lock texture"); + error("Unable to lock texture"); } bool usingLinearFiltering = _filter->NeedToColourEdgeLines(); @@ -1443,10 +1443,10 @@ void D3DGraphicsDriver::UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap void D3DGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { D3DBitmap *target = (D3DBitmap *)bitmapToUpdate; if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) - throw Ali3DException("UpdateDDBFromBitmap: mismatched bitmap size"); + error("UpdateDDBFromBitmap: mismatched bitmap size"); const int color_depth = bitmap->GetColorDepth(); if (color_depth != target->_colDepth) - throw Ali3DException("UpdateDDBFromBitmap: mismatched colour depths"); + error("UpdateDDBFromBitmap: mismatched colour depths"); target->_hasAlpha = hasAlpha; if (color_depth == 8) @@ -1516,7 +1516,7 @@ IDriverDependantBitmap *D3DGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, b int allocatedWidth = bitmap->GetWidth(); int allocatedHeight = bitmap->GetHeight(); if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) - throw Ali3DException("CreateDDBFromBitmap: bitmap colour depth not supported"); + error("CreateDDBFromBitmap: bitmap colour depth not supported"); int colourDepth = bitmap->GetColorDepth(); D3DBitmap *ddb = new D3DBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); @@ -1563,12 +1563,12 @@ IDriverDependantBitmap *D3DGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, b free(tiles); char errorMessage[200]; sprintf(errorMessage, "Direct3DDevice9::CreateVertexBuffer(Length=%d) for texture failed: error code %08X", vertexBufferSize, hr); - throw Ali3DException(errorMessage); + error(errorMessage); } if (ddb->_vertex->Lock(0, 0, (void **)&vertices, D3DLOCK_DISCARD) != D3D_OK) { free(tiles); - throw Ali3DException("Failed to lock vertex buffer"); + error("Failed to lock vertex buffer"); } } @@ -1614,7 +1614,7 @@ IDriverDependantBitmap *D3DGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, b if (hr != D3D_OK) { char errorMessage[200]; sprintf(errorMessage, "Direct3DDevice9::CreateTexture(X=%d, Y=%d, FMT=%d) failed: error code %08X", thisAllocatedWidth, thisAllocatedHeight, textureFormat, hr); - throw Ali3DException(errorMessage); + error(errorMessage); } } diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 6019f9525de6..648bf89d5d31 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -154,7 +154,7 @@ int pluginsWantingDebugHooks = 0; std::vector _registered_builtin_plugins; void IAGSEngine::AbortGame(const char *reason) { - quit((char *)reason); + quit((const char *)reason); } const char *IAGSEngine::GetEngineVersion() { return get_engine_version(); @@ -368,7 +368,7 @@ void IAGSEngine::SetVirtualScreen(BITMAP *bmp) { } int IAGSEngine::LookupParserWord(const char *word) { - return find_word_in_dictionary((char *)word); + return find_word_in_dictionary((const char *)word); } void IAGSEngine::BlitBitmap(int32 x, int32 y, BITMAP *bmp, int32 masked) { @@ -515,7 +515,7 @@ int IAGSEngine::GetWalkbehindBaseline(int32 wa) { return croom->walkbehind_base[wa]; } void *IAGSEngine::GetScriptFunctionAddress(const char *funcName) { - return ccGetSymbolAddressForPlugin((char *)funcName); + return ccGetSymbolAddressForPlugin((const char *)funcName); } int IAGSEngine::GetBitmapTransparentColor(BITMAP *bmp) { return bitmap_mask_color(bmp); @@ -543,7 +543,7 @@ void IAGSEngine::GetTextExtent(int32 font, const char *text, int32 *width, int32 if (width != nullptr) width[0] = wgettextwidth_compensate(text, font); if (height != nullptr) - height[0] = wgettextheight((char *)text, font); + height[0] = wgettextheight((const char *)text, font); } void IAGSEngine::PrintDebugConsole(const char *text) { debug_script_log("[PLUGIN] %s", text); @@ -681,7 +681,7 @@ int IAGSEngine::CallGameScriptFunction(const char *name, int32 globalScript, int params[0].SetPluginArgument(arg1); params[1].SetPluginArgument(arg2); params[2].SetPluginArgument(arg3); - int toret = RunScriptFunctionIfExists(toRun, (char *)name, numArgs, params); + int toret = RunScriptFunctionIfExists(toRun, (const char *)name, numArgs, params); return toret; } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 037cda3400c3..1ccbbe317845 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -84,7 +84,6 @@ MODULE_OBJS = \ engine/game/savegame.o \ engine/game/savegame_components.o \ engine/game/viewport.o \ - engine/gfx/all3dd3d.o \ engine/gfx/ali3dogl.o \ engine/gfx/ali3dsw.o \ engine/gfx/blender.o \ diff --git a/engines/ags/shared/gfx/bitmap.cpp b/engines/ags/shared/gfx/bitmap.cpp index 01ee210b600c..332e6528155d 100644 --- a/engines/ags/shared/gfx/bitmap.cpp +++ b/engines/ags/shared/gfx/bitmap.cpp @@ -88,7 +88,7 @@ template struct PixelTransCpy { static const size_t BPP = BPP_; inline void operator()(uint8_t *dst, const uint8_t *src, color_t mask_color, bool use_alpha) const { - if (*(TPx *)src == mask_color) + if (*(const TPx *)src == mask_color) *(TPx *)dst = mask_color; } }; From fd79c78d5c2dc674e369710486c63db468d3fefe Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 08:44:18 -0800 Subject: [PATCH 030/215] AGS: Fix some const loss warnings --- engines/ags/engine/plugin/agsplugin.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 648bf89d5d31..5307263fd939 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -727,7 +727,8 @@ void IAGSEngine::QueueGameScriptFunction(const char *name, int32 globalScript, i } int IAGSEngine::RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback) { - GlobalReturnValue.SetPluginObject((void *)object, (ICCDynamicObject *)callback); + // TODO: handle loss of const better + GlobalReturnValue.SetPluginObject(const_cast(object), (ICCDynamicObject *)callback); return ccRegisterManagedObject(object, (ICCDynamicObject *)callback, true); } @@ -749,7 +750,8 @@ void IAGSEngine::AddManagedObjectReader(const char *typeName, IAGSManagedObjectR } void IAGSEngine::RegisterUnserializedObject(int key_, const void *object, IAGSScriptManagedObject *callback) { - GlobalReturnValue.SetPluginObject((void *)object, (ICCDynamicObject *)callback); + // TODO: handle loss of const better + GlobalReturnValue.SetPluginObject(const_cast(object), (ICCDynamicObject *)callback); ccRegisterUnserializedObject(key_, object, (ICCDynamicObject *)callback, true); } @@ -772,7 +774,8 @@ void *IAGSEngine::GetManagedObjectAddressByKey(int key_) { const char *IAGSEngine::CreateScriptString(const char *fromText) { const char *string = CreateNewScriptString(fromText); // Should be still standard dynamic object, because not managed by plugin - GlobalReturnValue.SetDynamicObject((void *)string, &myScriptStringImpl); + // TODO: handle loss of const better + GlobalReturnValue.SetDynamicObject(const_cast(string), &myScriptStringImpl); return string; } From 551daa20a0355c23ea1583bf6eb2e4ce1074ebf8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 08:48:14 -0800 Subject: [PATCH 031/215] AGS: Added engine/device/ folder --- engines/ags/engine/device/mousew32.cpp | 17 ++++++++--------- engines/ags/module.mk | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index 5544601fd886..05454731bb49 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -48,13 +48,13 @@ #define FALSE 0 #endif -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/debug/out.h" -#include "ags/shared/device/mousew32.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/device/mousew32.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/gfx_util.h" -#include "ags/shared/main/graphics_mode.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/gfx/gfx_util.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/util/math.h" #if AGS_SIMULATE_RIGHT_CLICK #include "ags/shared/ac/sys_events.h" // j for ags_iskeypressed @@ -200,7 +200,7 @@ void domouse(int str) { */ int poow = mousecurs[currentcursor]->GetWidth(); int pooh = mousecurs[currentcursor]->GetHeight(); - int smx = mousex - hotxwas, smy = mousey - hotywas; + //int smx = mousex - hotxwas, smy = mousey - hotywas; const Rect &viewport = play.GetMainViewport(); mgetgraphpos(); @@ -238,8 +238,7 @@ void mfreemem() { void mloadwcursor(char *namm) { color dummypal[256]; if (wloadsprites(&dummypal[0], namm, mousecurs, 0, MAXCURSORS)) { - //printf("C_Load_wCursor: Error reading mouse cursor file\n"); - exit(1); + error("mloadwcursor: Error reading mouse cursor file"); } } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 1ccbbe317845..996f9b6a07ba 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -79,6 +79,7 @@ MODULE_OBJS = \ shared/util/textstreamwriter.o \ shared/util/version.o \ shared/util/wgt2allg.o \ + engine/device/mousew32.o \ engine/font/fonts_engine.o \ engine/game/game_init.o \ engine/game/savegame.o \ From 6ca4c1307ab0eeef99b326fd9b9c5bf5b24aa77b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 08:52:11 -0800 Subject: [PATCH 032/215] AGS: Added engine/debugging/ folder --- engines/ags/lib/allegro/keyboard.h | 1 + engines/ags/module.mk | 6 +++++ engines/ags/std/initializer_list.h | 39 +++--------------------------- 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/engines/ags/lib/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h index 06187120f679..0634eec0abc9 100644 --- a/engines/ags/lib/allegro/keyboard.h +++ b/engines/ags/lib/allegro/keyboard.h @@ -36,6 +36,7 @@ namespace AGS3 { #define KEY_ALT Common::KEYCODE_LALT #define KEY_LCONTROL Common::KEYCODE_LCTRL #define KEY_RCONTROL Common::KEYCODE_RCTRL +#define KEY_SCRLOCK Common::KEYCODE_SCROLLOCK #define KEY_ALTGR 0 #define KEY_F9 Common::KEYCODE_F9 #define KEY_A Common::KEYCODE_a diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 996f9b6a07ba..8d6dda1c6e74 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -79,6 +79,12 @@ MODULE_OBJS = \ shared/util/textstreamwriter.o \ shared/util/version.o \ shared/util/wgt2allg.o \ + engine/debugging/consoleoutputtarget.o \ + engine/debugging/debug.o \ + engine/debugging/filebasedagsdebugger.o \ + engine/debugging/logfile.o \ + engine/debugging/messagebuffer.o \ + engine/debugging/namedpipesagsdebugger.o \ engine/device/mousew32.o \ engine/font/fonts_engine.o \ engine/game/game_init.o \ diff --git a/engines/ags/std/initializer_list.h b/engines/ags/std/initializer_list.h index 0b07f56eaa0a..21e7c2f6433f 100644 --- a/engines/ags/std/initializer_list.h +++ b/engines/ags/std/initializer_list.h @@ -23,44 +23,13 @@ #ifndef AGS_STD_INITIALIZER_LIST_H #define AGS_STD_INITIALIZER_LIST_H +#include + namespace AGS3 { namespace std { -// CLASS TEMPLATE initializer_list -template -class initializer_list { -public: - using value_type = _Elem; - using reference = const _Elem &; - using const_reference = const _Elem &; - using size_type = size_t; - - using iterator = const _Elem *; - using const_iterator = const _Elem *; - - constexpr initializer_list() : _First(nullptr), _Last(nullptr) { - } - - constexpr initializer_list(const _Elem *_First_arg, const _Elem *_Last_arg) noexcept - : _First(_First_arg), _Last(_Last_arg) { - } - - constexpr const _Elem *begin() const { - return _First; - } - - constexpr const _Elem *end() const { - return _Last; - } - - constexpr size_t size() const { - return static_cast(_Last - _First); - } - -private: - const _Elem *_First; - const _Elem *_Last; -}; +template +using initializer_list = ::std::initializer_list; } // namespace std } // namespace AGS3 From b976165c1dab9779dc69ce68d6f32acd1ff41085 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 09:21:09 -0800 Subject: [PATCH 033/215] AGS: gcc warning fixes --- engines/ags/engine/device/mousew32.cpp | 4 ++-- engines/ags/engine/gfx/gfxdriverbase.cpp | 30 ++++++++++++------------ engines/ags/engine/gui/guidialog.cpp | 2 +- engines/ags/module.mk | 1 - 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index 05454731bb49..16e65d813bad 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -198,8 +198,8 @@ void domouse(int str) { TO USE THIS ROUTINE YOU MUST LOAD A MOUSE CURSOR USING mloadcursor. YOU MUST ALSO REMEMBER TO CALL mfreemem AT THE END OF THE PROGRAM. */ - int poow = mousecurs[currentcursor]->GetWidth(); - int pooh = mousecurs[currentcursor]->GetHeight(); + int poow = mousecurs[(int)currentcursor]->GetWidth(); + int pooh = mousecurs[(int)currentcursor]->GetHeight(); //int smx = mousex - hotxwas, smy = mousey - hotywas; const Rect &viewport = play.GetMainViewport(); diff --git a/engines/ags/engine/gfx/gfxdriverbase.cpp b/engines/ags/engine/gfx/gfxdriverbase.cpp index ce75c9b1ed58..4b458a78b681 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.cpp +++ b/engines/ags/engine/gfx/gfxdriverbase.cpp @@ -253,7 +253,7 @@ void VideoMemoryGraphicsDriver::DestroyFxPool() { #define algetb8(c) getb8(c) -__inline void get_pixel_if_not_transparent8(unsigned char *pixel, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *divisor) { +__inline void get_pixel_if_not_transparent8(const unsigned char *pixel, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *divisor) { if (pixel[0] != MASK_COLOR_8) { *red += algetr8(pixel[0]); *green += algetg8(pixel[0]); @@ -262,7 +262,7 @@ __inline void get_pixel_if_not_transparent8(unsigned char *pixel, unsigned char } } -__inline void get_pixel_if_not_transparent16(unsigned short *pixel, unsigned short *red, unsigned short *green, unsigned short *blue, unsigned short *divisor) { +__inline void get_pixel_if_not_transparent16(const unsigned short *pixel, unsigned short *red, unsigned short *green, unsigned short *blue, unsigned short *divisor) { if (pixel[0] != MASK_COLOR_16) { *red += algetr16(pixel[0]); *green += algetg16(pixel[0]); @@ -271,7 +271,7 @@ __inline void get_pixel_if_not_transparent16(unsigned short *pixel, unsigned sho } } -__inline void get_pixel_if_not_transparent32(unsigned int *pixel, unsigned int *red, unsigned int *green, unsigned int *blue, unsigned int *divisor) { +__inline void get_pixel_if_not_transparent32(const unsigned int *pixel, unsigned int *red, unsigned int *green, unsigned int *blue, unsigned int *divisor) { if (pixel[0] != MASK_COLOR_32) { *red += algetr32(pixel[0]); *green += algetg32(pixel[0]); @@ -298,7 +298,7 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo for (int x = 0; x < tile->width; x++) { if (src_depth == 8) { - unsigned char *srcData = (unsigned char *)&scanline_at[(x + tile->x) * sizeof(char)]; + const unsigned char *srcData = (const unsigned char *)&scanline_at[(x + tile->x) * sizeof(char)]; if (*srcData == MASK_COLOR_8) { if (!usingLinearFiltering) memPtrLong[x] = 0; @@ -311,9 +311,9 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo if (x < tile->width - 1) get_pixel_if_not_transparent8(&srcData[1], &red, &green, &blue, &divisor); if (y > 0) - get_pixel_if_not_transparent8((unsigned char *)&scanline_before[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); + get_pixel_if_not_transparent8((const unsigned char *)&scanline_before[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); if (y < tile->height - 1) - get_pixel_if_not_transparent8((unsigned char *)&scanline_after[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); + get_pixel_if_not_transparent8((const unsigned char *)&scanline_after[(x + tile->x) * sizeof(char)], &red, &green, &blue, &divisor); if (divisor > 0) memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); else @@ -330,7 +330,7 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo } } } else if (src_depth == 16) { - unsigned short *srcData = (unsigned short *)&scanline_at[(x + tile->x) * sizeof(short)]; + const unsigned short *srcData = (const unsigned short *)&scanline_at[(x + tile->x) * sizeof(short)]; if (*srcData == MASK_COLOR_16) { if (!usingLinearFiltering) memPtrLong[x] = 0; @@ -343,9 +343,9 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo if (x < tile->width - 1) get_pixel_if_not_transparent16(&srcData[1], &red, &green, &blue, &divisor); if (y > 0) - get_pixel_if_not_transparent16((unsigned short *)&scanline_before[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); + get_pixel_if_not_transparent16((const unsigned short *)&scanline_before[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); if (y < tile->height - 1) - get_pixel_if_not_transparent16((unsigned short *)&scanline_after[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); + get_pixel_if_not_transparent16((const unsigned short *)&scanline_after[(x + tile->x) * sizeof(short)], &red, &green, &blue, &divisor); if (divisor > 0) memPtrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); else @@ -363,7 +363,7 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo } } else if (src_depth == 32) { unsigned int *ptrLong = (unsigned int *)dst_ptr; - unsigned int *srcData = (unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; + const unsigned int *srcData = (const unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; if (*srcData == MASK_COLOR_32) { if (!usingLinearFiltering) ptrLong[x] = 0; @@ -376,9 +376,9 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo if (x < tile->width - 1) get_pixel_if_not_transparent32(&srcData[1], &red, &green, &blue, &divisor); if (y > 0) - get_pixel_if_not_transparent32((unsigned int *)&scanline_before[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); + get_pixel_if_not_transparent32((const unsigned int *)&scanline_before[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); if (y < tile->height - 1) - get_pixel_if_not_transparent32((unsigned int *)&scanline_after[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); + get_pixel_if_not_transparent32((const unsigned int *)&scanline_after[(x + tile->x) * sizeof(int)], &red, &green, &blue, &divisor); if (divisor > 0) ptrLong[x] = VMEMCOLOR_RGBA(red / divisor, green / divisor, blue / divisor, 0); else @@ -412,14 +412,14 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, con for (int x = 0; x < tile->width; x++) { if (src_depth == 8) { - unsigned char *srcData = (unsigned char *)&scanline_at[(x + tile->x) * sizeof(char)]; + const unsigned char *srcData = (const unsigned char *)&scanline_at[(x + tile->x) * sizeof(char)]; memPtrLong[x] = VMEMCOLOR_RGBA(algetr8(*srcData), algetg8(*srcData), algetb8(*srcData), 0xFF); } else if (src_depth == 16) { - unsigned short *srcData = (unsigned short *)&scanline_at[(x + tile->x) * sizeof(short)]; + const unsigned short *srcData = (const unsigned short *)&scanline_at[(x + tile->x) * sizeof(short)]; memPtrLong[x] = VMEMCOLOR_RGBA(algetr16(*srcData), algetg16(*srcData), algetb16(*srcData), 0xFF); } else if (src_depth == 32) { //unsigned int *memPtrLong = (unsigned int *)dst_ptr; - unsigned int *srcData = (unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; + const unsigned int *srcData = (const unsigned int *)&scanline_at[(x + tile->x) * sizeof(int)]; if (has_alpha) memPtrLong[x] = VMEMCOLOR_RGBA(algetr32(*srcData), algetg32(*srcData), algetb32(*srcData), algeta32(*srcData)); else diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index d2d2b7111134..56002f6bb1f7 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -54,7 +54,7 @@ IDriverDependantBitmap *dialogDDB; #undef MAXSAVEGAMES #define MAXSAVEGAMES 20 -DisplayProperties dispp; +//DisplayProperties dispp; char *lpTemp, *lpTemp2; char bufTemp[260], buffer2[260]; int numsaves = 0, toomanygames; diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 8d6dda1c6e74..d3a5f538591d 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -84,7 +84,6 @@ MODULE_OBJS = \ engine/debugging/filebasedagsdebugger.o \ engine/debugging/logfile.o \ engine/debugging/messagebuffer.o \ - engine/debugging/namedpipesagsdebugger.o \ engine/device/mousew32.o \ engine/font/fonts_engine.o \ engine/game/game_init.o \ From 055c9566fffece9bda918f5dd6c871f37b092a7d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 11:47:47 -0800 Subject: [PATCH 034/215] AGS: std::set implementation now derives from Common::SortedArray --- engines/ags/std/set.h | 99 ++++++++----------------------------------- 1 file changed, 18 insertions(+), 81 deletions(-) diff --git a/engines/ags/std/set.h b/engines/ags/std/set.h index 18d30e2bdb4a..5df72295ceaa 100644 --- a/engines/ags/std/set.h +++ b/engines/ags/std/set.h @@ -23,102 +23,39 @@ #ifndef AGS_STD_SET_H #define AGS_STD_SET_H +#include "common/array.h" + namespace AGS3 { namespace std { -template -class set { - struct Comparitor { - bool operator()(const T &a, const T &b) const { - return a == b; - } - }; - - class Items : public Common::Array { - public: - void swap(Items &arr) { - SWAP(this->_capacity, arr._capacity); - SWAP(this->_size, arr._size); - SWAP(this->_storage, arr._storage); - } - }; +/** + * Derives the ScummVM SortedArray to match the std::set class + */ +template > +class set : public Common::SortedArray { private: - Items _items; - Comparitor _comparitor; -public: - typedef T *iterator; - typedef const T *const_iterator; - - iterator begin() { - return _items.begin(); - } - iterator end() { - return _items.end(); - } - const_iterator begin() const { - return _items.begin(); - } - const_iterator end() const { - return _items.end(); - } - - /** - * Clear the set - */ - void clear() { - _items.clear(); - } - - /** - * Inserts a new item - */ - void insert(T val) { - _items.push_back(val); - Common::sort(begin(), end(), _comparitor); - } - - /** - * Inserts a range of items - */ - void insert(iterator first, iterator last) { - for (; first != last; ++first) - _items.push_back(*first); - Common::sort(begin(), end(), _comparitor); - } - - /** - * Swaps a set - */ - void swap(set &arr) { - _items.swap(arr); + static int ComparatorFn(const T &a, const T &b) { + return EqualFunc()(a, b) ? -1 : 0; } +public: + using const_iterator = typename Common::SortedArray::const_iterator; /** - * Find an item + * Constructor */ - iterator find(const T item) { - iterator it = begin(); - for (; it != end() && *it != item; ++it) {} - return it; - } - const_iterator find(const T item) const { - const_iterator it = begin(); - for (; it != end() && *it != item; ++it) { - } - return it; - } - bool empty() const { - return _items.empty(); - } + set() : Common::SortedArray(ComparatorFn) {} /** - * Returns the number of matching entries + * Returns the number of keys that match the specified key */ size_t count(const T item) const { size_t total = 0; - for (const_iterator it = begin(); it != end(); ++it) { + for (const_iterator it = this->begin(); it != this->end(); ++it) { if (*it == item) ++total; + else if (!ComparatorFn(item, *it)) + // Passed beyond possibility of matches + break; } return total; From 0edf5d23c3bb998411afd0fb69299ef5b93ba9bf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 13:13:04 -0800 Subject: [PATCH 035/215] AGS: Added engine/ac/dynobj/ folder --- .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 2 +- .../ags/engine/ac/dynobj/cc_audiochannel.cpp | 6 +-- engines/ags/engine/ac/dynobj/cc_audioclip.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_character.cpp | 4 +- engines/ags/engine/ac/dynobj/cc_dialog.cpp | 4 +- .../ags/engine/ac/dynobj/cc_dynamicarray.cpp | 2 +- .../ags/engine/ac/dynobj/cc_dynamicobject.cpp | 6 +-- engines/ags/engine/ac/dynobj/cc_gui.cpp | 4 +- engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 4 +- engines/ags/engine/ac/dynobj/cc_hotspot.cpp | 4 +- engines/ags/engine/ac/dynobj/cc_inventory.cpp | 4 +- engines/ags/engine/ac/dynobj/cc_object.cpp | 4 +- engines/ags/engine/ac/dynobj/cc_region.cpp | 4 +- .../ags/engine/ac/dynobj/cc_serializer.cpp | 24 +++++----- .../engine/ac/dynobj/managedobjectpool.cpp | 10 ++-- engines/ags/engine/ac/dynobj/scriptcamera.cpp | 4 +- engines/ags/engine/ac/dynobj/scriptcamera.h | 2 +- .../ags/engine/ac/dynobj/scriptdatetime.cpp | 2 +- .../dynobj/scriptdialogoptionsrendering.cpp | 2 +- engines/ags/engine/ac/dynobj/scriptdict.cpp | 2 +- engines/ags/engine/ac/dynobj/scriptdict.h | 9 ++-- .../engine/ac/dynobj/scriptdrawingsurface.cpp | 8 ++-- .../engine/ac/dynobj/scriptdynamicsprite.cpp | 4 +- engines/ags/engine/ac/dynobj/scriptfile.cpp | 12 ++--- .../ags/engine/ac/dynobj/scriptoverlay.cpp | 8 ++-- engines/ags/engine/ac/dynobj/scriptset.cpp | 2 +- engines/ags/engine/ac/dynobj/scriptset.h | 12 ++--- engines/ags/engine/ac/dynobj/scriptstring.cpp | 4 +- .../ags/engine/ac/dynobj/scriptuserobject.cpp | 4 +- .../ags/engine/ac/dynobj/scriptviewframe.cpp | 2 +- .../ags/engine/ac/dynobj/scriptviewport.cpp | 4 +- engines/ags/engine/ac/dynobj/scriptviewport.h | 2 +- engines/ags/module.mk | 28 +++++++++++ engines/ags/shared/util/string_types.h | 33 +++---------- engines/ags/std/map.h | 4 ++ engines/ags/std/set.h | 4 +- engines/ags/std/unordered_set.h | 46 +++++++++++++++++++ 37 files changed, 169 insertions(+), 113 deletions(-) create mode 100644 engines/ags/std/unordered_set.h diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp index f64397eec1be..c0d4d780f0c5 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -22,7 +22,7 @@ //include #include "ags/shared/core/types.h" -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" #include "ags/shared/ac/common.h" // quit() #include "ags/shared/util/bbop.h" diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp index 280486465f60..ae636d4de88a 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp @@ -20,9 +20,9 @@ * */ -#include "ags/shared/ac/dynobj/cc_audiochannel.h" -#include "ags/shared/ac/dynobj/scriptaudiochannel.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/ac/dynobj/cc_audiochannel.h" +#include "ags/engine/ac/dynobj/scriptaudiochannel.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp index 6f63f2fd64b1..cebe70e77933 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/dynobj/cc_audioclip.h" +#include "ags/engine/ac/dynobj/cc_audioclip.h" #include "ags/shared/ac/dynobj/scriptaudioclip.h" #include "ags/shared/ac/gamesetupstruct.h" diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index 6944fc652d47..c114d948011f 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -20,9 +20,9 @@ * */ -#include "ags/shared/ac/dynobj/cc_character.h" +#include "ags/engine/ac/dynobj/cc_character.h" #include "ags/shared/ac/characterinfo.h" -#include "ags/shared/ac/global_character.h" +#include "ags/engine/ac/global_character.h" #include "ags/shared/ac/gamesetupstruct.h" #include "ags/shared/ac/game_version.h" diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp index 622f6392aca9..6be1090eccfd 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/cc_dialog.h" -#include "ags/shared/ac/dialog.h" +#include "ags/engine/ac/dynobj/cc_dialog.h" +#include "ags/engine/ac/dialog.h" #include "ags/shared/ac/dialogtopic.h" #include "ags/shared/ac/gamestructdefines.h" diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp index 118eb4e8a73a..03fe6797072e 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp @@ -21,7 +21,7 @@ */ //include -#include "ags/shared/cc_dynamicarray.h" +#include "ags/engine/ac/dynobj/cc_dynamicarray.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp index 7fb7290c0019..8492137105b1 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.cpp @@ -38,9 +38,9 @@ //include //include -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" -#include "ags/shared/ac/dynobj/managedobjectpool.h" -#include "ags/shared/debug/out.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/ac/dynobj/managedobjectpool.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/script/script_common.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp index 9b2d472b5e31..4c9b46482fd7 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.cpp +++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/cc_gui.h" -#include "ags/shared/ac/dynobj/scriptgui.h" +#include "ags/engine/ac/dynobj/cc_gui.h" +#include "ags/engine/ac/dynobj/scriptgui.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp index 9bbb9352dc73..e8c0e350913f 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/cc_guiobject.h" -#include "ags/shared/ac/dynobj/scriptgui.h" +#include "ags/engine/ac/dynobj/cc_guiobject.h" +#include "ags/engine/ac/dynobj/scriptgui.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guiobject.h" diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp index 0bf87cf47987..8a4677404235 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/cc_hotspot.h" -#include "ags/shared/ac/dynobj/scripthotspot.h" +#include "ags/engine/ac/dynobj/cc_hotspot.h" +#include "ags/engine/ac/dynobj/scripthotspot.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/game/roomstruct.h" diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp index d213c84c2ee2..60cae380be96 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.cpp +++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/cc_inventory.h" -#include "ags/shared/ac/dynobj/scriptinvitem.h" +#include "ags/engine/ac/dynobj/cc_inventory.h" +#include "ags/engine/ac/dynobj/scriptinvitem.h" #include "ags/shared/ac/characterinfo.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp index 092f5123db94..abcd84f8dc3f 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.cpp +++ b/engines/ags/engine/ac/dynobj/cc_object.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/cc_object.h" -#include "ags/shared/ac/dynobj/scriptobject.h" +#include "ags/engine/ac/dynobj/cc_object.h" +#include "ags/engine/ac/dynobj/scriptobject.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/game/roomstruct.h" diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp index 9d804eee84e1..a6fc8910b588 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.cpp +++ b/engines/ags/engine/ac/dynobj/cc_region.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/cc_region.h" -#include "ags/shared/ac/dynobj/scriptregion.h" +#include "ags/engine/ac/dynobj/cc_region.h" +#include "ags/engine/ac/dynobj/scriptregion.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/game/roomstruct.h" diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp index fc932e3fcd90..1e91c8c8e65f 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.cpp +++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp @@ -21,18 +21,18 @@ */ //include -#include "ags/shared/ac/dynobj/cc_serializer.h" -#include "ags/shared/ac/dynobj/all_dynamicclasses.h" -#include "ags/shared/ac/dynobj/all_scriptclasses.h" -#include "ags/shared/ac/dynobj/scriptcamera.h" -#include "ags/shared/ac/dynobj/scriptcontainers.h" -#include "ags/shared/ac/dynobj/scriptfile.h" -#include "ags/shared/ac/dynobj/scriptuserobject.h" -#include "ags/shared/ac/dynobj/scriptviewport.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/pluginobjectreader.h" +#include "ags/engine/ac/dynobj/cc_serializer.h" +#include "ags/engine/ac/dynobj/all_dynamicclasses.h" +#include "ags/engine/ac/dynobj/all_scriptclasses.h" +#include "ags/engine/ac/dynobj/scriptcamera.h" +#include "ags/engine/ac/dynobj/scriptcontainers.h" +#include "ags/engine/ac/dynobj/scriptfile.h" +#include "ags/engine/ac/dynobj/scriptuserobject.h" +#include "ags/engine/ac/dynobj/scriptviewport.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/pluginobjectreader.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index d6a9d5b997c0..d7b30f4ef968 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -22,9 +22,9 @@ #include "ags/std/vector.h" //include -#include "ags/shared/ac/dynobj/managedobjectpool.h" -#include "ags/shared/ac/dynobj/cc_dynamicarray.h" // globalDynamicArray, constants -#include "ags/shared/debug/out.h" +#include "ags/engine/ac/dynobj/managedobjectpool.h" +#include "ags/engine/ac/dynobj/cc_dynamicarray.h" // globalDynamicArray, constants +#include "ags/shared/debugging/out.h" #include "ags/shared/util/string_utils.h" // fputstring, etc #include "ags/shared/script/cc_error.h" #include "ags/shared/script/script_common.h" @@ -116,7 +116,7 @@ int32_t ManagedObjectPool::AddressToHandle(const char *addr) { if (it == handleByAddress.end()) { return 0; } - return it->second; + return it->_value; } // this function is called often (whenever a pointer is used) @@ -155,7 +155,7 @@ int ManagedObjectPool::RemoveObject(const char *address) { return 0; } - auto &o = objects[it->second]; + auto &o = objects[it->_value]; return Remove(o, true); } diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp index 0eebc6177f9d..aa7aa5d8bd73 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.cpp +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/scriptcamera.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/dynobj/scriptcamera.h" +#include "ags/engine/ac/gamestate.h" #include "ags/shared/util/bbop.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.h b/engines/ags/engine/ac/dynobj/scriptcamera.h index 019896fc68e6..8d77f9d2054c 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.h +++ b/engines/ags/engine/ac/dynobj/scriptcamera.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTCAMERA_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTCAMERA_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp index 459cc717acae..b055e380e1a6 100644 --- a/engines/ags/engine/ac/dynobj/scriptdatetime.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdatetime.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/dynobj/scriptdatetime.h" +#include "ags/engine/ac/dynobj/scriptdatetime.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp index 017aaf599c58..d442b16e8f1e 100644 --- a/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdialogoptionsrendering.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/dynobj/scriptdialogoptionsrendering.h" +#include "ags/engine/ac/dynobj/scriptdialogoptionsrendering.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdict.cpp b/engines/ags/engine/ac/dynobj/scriptdict.cpp index 9260e2033234..7991471e11a2 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdict.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/dynobj/scriptdict.h" +#include "ags/engine/ac/dynobj/scriptdict.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index 85a0bdc7b3c7..08740845c62c 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -36,10 +36,9 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTDICT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDICT_H -//include -//include //include -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/std/map.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" @@ -183,9 +182,9 @@ class ScriptDictImpl final : public ScriptDictBase { }; typedef ScriptDictImpl< std::map, true, true > ScriptDict; -typedef ScriptDictImpl< std::map, true, false > ScriptDictCI; +typedef ScriptDictImpl< std::map, true, false > ScriptDictCI; typedef ScriptDictImpl< std::unordered_map, false, true > ScriptHashDict; -typedef ScriptDictImpl< std::unordered_map, false, false > ScriptHashDictCI; +typedef ScriptDictImpl< std::unordered_map, false, false > ScriptHashDictCI; } // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp index 24cd01bc94ec..041a9f7aad4d 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -20,12 +20,12 @@ * */ -#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/ac/runtime_defines.h" +#include "ags/engine/ac/runtime_defines.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/drawingsurface.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/drawingsurface.h" +#include "ags/engine/ac/gamestate.h" #include "ags/shared/ac/gamesetupstruct.h" #include "ags/shared/game/roomstruct.h" #include "ags/shared/gfx/bitmap.h" diff --git a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp index 83e94075f366..d21f430d9b1b 100644 --- a/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdynamicsprite.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/scriptdynamicsprite.h" -#include "ags/shared/ac/dynamicsprite.h" +#include "ags/engine/ac/dynobj/scriptdynamicsprite.h" +#include "ags/engine/ac/dynamicsprite.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptfile.cpp b/engines/ags/engine/ac/dynobj/scriptfile.cpp index 8d75f62462a2..8798d2bb41d1 100644 --- a/engines/ags/engine/ac/dynobj/scriptfile.cpp +++ b/engines/ags/engine/ac/dynobj/scriptfile.cpp @@ -20,16 +20,16 @@ * */ -#include "ags/shared/ac/dynobj/scriptfile.h" -#include "ags/shared/ac/global_file.h" +#include "ags/engine/ac/dynobj/scriptfile.h" +#include "ags/engine/ac/global_file.h" namespace AGS3 { // CHECKME: actually NULLs here will be equal to kFile_Open & kFile_Read -const Common::FileOpenMode sc_File::fopenModes[] = -{ Common::kFile_Open/*CHECKME, was undefined*/, Common::kFile_Open, Common::kFile_CreateAlways, Common::kFile_Create }; -const Common::FileWorkMode sc_File::fworkModes[] = -{ Common::kFile_Read/*CHECKME, was undefined*/, Common::kFile_Read, Common::kFile_Write, Common::kFile_Write }; +const Shared::FileOpenMode sc_File::fopenModes[] = +{ Shared::kFile_Open/*CHECKME, was undefined*/, Shared::kFile_Open, Shared::kFile_CreateAlways, Shared::kFile_Create }; +const Shared::FileWorkMode sc_File::fworkModes[] = +{ Shared::kFile_Read/*CHECKME, was undefined*/, Shared::kFile_Read, Shared::kFile_Write, Shared::kFile_Write }; int sc_File::Dispose(const char *address, bool force) { Close(); diff --git a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp index 0a8f3be6754e..918538a42625 100644 --- a/engines/ags/engine/ac/dynobj/scriptoverlay.cpp +++ b/engines/ags/engine/ac/dynobj/scriptoverlay.cpp @@ -20,11 +20,11 @@ * */ -#include "ags/shared/ac/dynobj/scriptoverlay.h" +#include "ags/engine/ac/dynobj/scriptoverlay.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/screenoverlay.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/screenoverlay.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptset.cpp b/engines/ags/engine/ac/dynobj/scriptset.cpp index c3cc922ef901..8141fc8913c6 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.cpp +++ b/engines/ags/engine/ac/dynobj/scriptset.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/dynobj/scriptset.h" +#include "ags/engine/ac/dynobj/scriptset.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index f20a979c8509..e6ca5068f789 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -35,10 +35,10 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H -//include -//include -//include -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/std/set.h" +#include "ags/std/unordered_set.h" +#include "ags/std/map.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" @@ -148,9 +148,9 @@ class ScriptSetImpl final : public ScriptSetBase { }; typedef ScriptSetImpl< std::set, true, true > ScriptSet; -typedef ScriptSetImpl< std::set, true, false > ScriptSetCI; +typedef ScriptSetImpl< std::set, true, false > ScriptSetCI; typedef ScriptSetImpl< std::unordered_set, false, true > ScriptHashSet; -typedef ScriptSetImpl< std::unordered_set, false, false > ScriptHashSetCI; +typedef ScriptSetImpl< std::unordered_set, false, false > ScriptHashSetCI; } // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/scriptstring.cpp b/engines/ags/engine/ac/dynobj/scriptstring.cpp index 9f55a1c8f12e..695f94bfb60c 100644 --- a/engines/ags/engine/ac/dynobj/scriptstring.cpp +++ b/engines/ags/engine/ac/dynobj/scriptstring.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/scriptstring.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/ac/string.h" //include //include diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp index e3d949c4bed0..ae02f3cb91fb 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp @@ -20,8 +20,8 @@ * */ -//include -#include "ags/shared/scriptuserobject.h" +#include "ags/std/memory.h" +#include "ags/engine/ac/dynobj/scriptuserobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp index d60d45733bc9..44e2d7271c30 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewframe.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewframe.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/dynobj/scriptviewframe.h" +#include "ags/engine/ac/dynobj/scriptviewframe.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp index 8783de73079a..e578dce59421 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/dynobj/scriptviewport.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/dynobj/scriptviewport.h" +#include "ags/engine/ac/gamestate.h" #include "ags/shared/util/bbop.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.h b/engines/ags/engine/ac/dynobj/scriptviewport.h index 9075190a09d6..fc4ea1a258d0 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.h +++ b/engines/ags/engine/ac/dynobj/scriptviewport.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWPORT_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTVIEWPORT_H -#include "ags/shared/ac/dynobj/cc_agsdynamicobject.h" +#include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" namespace AGS3 { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index d3a5f538591d..5598eb3491c6 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -79,6 +79,34 @@ MODULE_OBJS = \ shared/util/textstreamwriter.o \ shared/util/version.o \ shared/util/wgt2allg.o \ + engine/ac/dynobj/cc_agsdynamicobject.o \ + engine/ac/dynobj/cc_audiochannel.o \ + engine/ac/dynobj/cc_audioclip.o \ + engine/ac/dynobj/cc_character.o \ + engine/ac/dynobj/cc_dialog.o \ + engine/ac/dynobj/cc_dynamicarray.o \ + engine/ac/dynobj/cc_dynamicobject.o \ + engine/ac/dynobj/cc_gui.o \ + engine/ac/dynobj/cc_guiobject.o \ + engine/ac/dynobj/cc_hotspot.o \ + engine/ac/dynobj/cc_inventory.o \ + engine/ac/dynobj/cc_object.o \ + engine/ac/dynobj/cc_region.o \ + engine/ac/dynobj/cc_serializer.o \ + engine/ac/dynobj/managedobjectpool.o \ + engine/ac/dynobj/scriptcamera.o \ + engine/ac/dynobj/scriptdatetime.o \ + engine/ac/dynobj/scriptdialogoptionsrendering.o \ + engine/ac/dynobj/scriptdict.o \ + engine/ac/dynobj/scriptdrawingsurface.o \ + engine/ac/dynobj/scriptdynamicsprite.o \ + engine/ac/dynobj/scriptfile.o \ + engine/ac/dynobj/scriptoverlay.o \ + engine/ac/dynobj/scriptstring.o \ + engine/ac/dynobj/scriptuserobject.o \ + engine/ac/dynobj/scriptviewframe.o \ + engine/ac/dynobj/scriptviewport.o \ + engine/ac/dynobj/scriptset.o \ engine/debugging/consoleoutputtarget.o \ engine/debugging/debug.o \ engine/debugging/filebasedagsdebugger.o \ diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index 13b4c4c5f9da..0e65ce084eae 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -78,6 +78,12 @@ struct IgnoreCase_Hash { } }; +struct IgnoreCase_LessThan { + bool operator()(const AGS3::AGS::Shared::String &x, const AGS3::AGS::Shared::String &y) const { + return x.CompareNoCase(y) < 0; + } +}; + } // namespace AGS3 namespace Common { @@ -101,33 +107,6 @@ namespace AGS3 { namespace AGS { namespace Shared { -#if 0 -// -// Various comparison functors -// - -// Test case-insensitive String equality -struct StrEqNoCase : public std::binary_function { - bool operator()(const String &s1, const String &s2) const { - return s1.CompareNoCase(s2) == 0; - } -}; - -// Case-insensitive String less -struct StrLessNoCase : public std::binary_function { - bool operator()(const String &s1, const String &s2) const { - return s1.CompareNoCase(s2) < 0; - } -}; - -// Compute case-insensitive hash for a String object -struct HashStrNoCase : public std::unary_function { - size_t operator()(const String &key) const { - return FNV::Hash_LowerCase(key.GetCStr(), key.GetLength()); - } -}; -#endif - typedef std::vector StringV; typedef std::unordered_map StringMap; typedef std::unordered_map StringIMap; diff --git a/engines/ags/std/map.h b/engines/ags/std/map.h index 0c015ccaba7f..34a27bb7d156 100644 --- a/engines/ags/std/map.h +++ b/engines/ags/std/map.h @@ -58,6 +58,10 @@ class unordered_map : public Common::HashMap { void insert(pair elem) { this->operator[](elem.first) = elem.second; } + + void reserve(size_t size) { + // No implementation + } }; } // namespace std diff --git a/engines/ags/std/set.h b/engines/ags/std/set.h index 5df72295ceaa..f50a8f87e0e5 100644 --- a/engines/ags/std/set.h +++ b/engines/ags/std/set.h @@ -31,11 +31,11 @@ namespace std { /** * Derives the ScummVM SortedArray to match the std::set class */ -template > +template > class set : public Common::SortedArray { private: static int ComparatorFn(const T &a, const T &b) { - return EqualFunc()(a, b) ? -1 : 0; + return Comparitor()(a, b) ? -1 : 0; } public: using const_iterator = typename Common::SortedArray::const_iterator; diff --git a/engines/ags/std/unordered_set.h b/engines/ags/std/unordered_set.h new file mode 100644 index 000000000000..9ef12dd3e53b --- /dev/null +++ b/engines/ags/std/unordered_set.h @@ -0,0 +1,46 @@ +/* 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 AGS_STD_UNORDERED_SET_H +#define AGS_STD_UNORDERED_SET_H + +#include "common/array.h" +//#include + +namespace AGS3 { +namespace std { + +template , class Pred = Common::EqualTo > +class unordered_set { +private: + Hash _hash; + Pred _comparitor; +public: + unordered_set() {} + + // TODO: Implement whatever unordered_set methods are needed +}; + +} // namespace std +} // namespace AGS3 + +#endif From a2c3fffe305c101b3416e36e58227b41516840db Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 13:18:05 -0800 Subject: [PATCH 036/215] AGS: Added engine/ac/statobj/ folder --- engines/ags/engine/ac/statobj/agsstaticobject.cpp | 6 +++--- engines/ags/engine/ac/statobj/staticarray.cpp | 4 ++-- engines/ags/module.mk | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp index db55c0bcb35f..1351b6995228 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.cpp +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -21,9 +21,9 @@ */ //include -#include "ags/shared/ac/statobj/agsstaticobject.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/statobj/agsstaticobject.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp index d2fada026d0c..b70c029d2e39 100644 --- a/engines/ags/engine/ac/statobj/staticarray.cpp +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -21,8 +21,8 @@ */ //include -#include "ags/shared/ac/statobj/staticarray.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/ac/statobj/staticarray.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" namespace AGS3 { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 5598eb3491c6..b455f9916dbc 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -107,6 +107,8 @@ MODULE_OBJS = \ engine/ac/dynobj/scriptviewframe.o \ engine/ac/dynobj/scriptviewport.o \ engine/ac/dynobj/scriptset.o \ + engine/ac/statobj/agsstaticobject.o \ + engine/ac/statobj/staticarray.o \ engine/debugging/consoleoutputtarget.o \ engine/debugging/debug.o \ engine/debugging/filebasedagsdebugger.o \ From c710fdd8d12b48dfcf0f80b65d198571dfb9e855 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 14:34:47 -0800 Subject: [PATCH 037/215] AGS: Added engine/ac/ folder --- engines/ags/engine/ac/audiochannel.cpp | 8 +- engines/ags/engine/ac/audioclip.cpp | 7 +- engines/ags/engine/ac/character.cpp | 84 +-- engines/ags/engine/ac/characterextras.cpp | 2 +- .../ags/engine/ac/characterinfo_engine.cpp | 23 +- engines/ags/engine/ac/datetime.cpp | 14 +- engines/ags/engine/ac/dialog.cpp | 82 +-- .../ags/engine/ac/dialogoptionsrendering.cpp | 17 +- engines/ags/engine/ac/display.cpp | 48 +- engines/ags/engine/ac/draw.cpp | 108 ++-- engines/ags/engine/ac/draw_software.cpp | 8 +- engines/ags/engine/ac/drawingsurface.cpp | 45 +- engines/ags/engine/ac/dynamicsprite.cpp | 42 +- engines/ags/engine/ac/dynobj/scriptdict.h | 31 +- engines/ags/engine/ac/dynobj/scriptset.h | 2 +- engines/ags/engine/ac/event.cpp | 42 +- engines/ags/engine/ac/file.cpp | 42 +- engines/ags/engine/ac/game.cpp | 183 +++--- engines/ags/engine/ac/gamesetup.cpp | 2 +- engines/ags/engine/ac/gamestate.cpp | 28 +- engines/ags/engine/ac/global_api.cpp | 106 ++-- engines/ags/engine/ac/global_audio.cpp | 22 +- engines/ags/engine/ac/global_button.cpp | 6 +- engines/ags/engine/ac/global_character.cpp | 32 +- engines/ags/engine/ac/global_datetime.cpp | 8 +- engines/ags/engine/ac/global_datetime.h | 4 +- engines/ags/engine/ac/global_debug.cpp | 44 +- engines/ags/engine/ac/global_dialog.cpp | 14 +- engines/ags/engine/ac/global_display.cpp | 30 +- .../ags/engine/ac/global_drawingsurface.cpp | 18 +- .../ags/engine/ac/global_dynamicsprite.cpp | 12 +- engines/ags/engine/ac/global_file.cpp | 20 +- engines/ags/engine/ac/global_game.cpp | 83 +-- engines/ags/engine/ac/global_gui.cpp | 20 +- engines/ags/engine/ac/global_hotspot.cpp | 22 +- .../ags/engine/ac/global_inventoryitem.cpp | 18 +- engines/ags/engine/ac/global_invwindow.cpp | 10 +- engines/ags/engine/ac/global_label.cpp | 6 +- engines/ags/engine/ac/global_listbox.cpp | 6 +- engines/ags/engine/ac/global_mouse.cpp | 4 +- engines/ags/engine/ac/global_object.cpp | 36 +- engines/ags/engine/ac/global_overlay.cpp | 20 +- engines/ags/engine/ac/global_palette.cpp | 6 +- engines/ags/engine/ac/global_parser.cpp | 7 +- engines/ags/engine/ac/global_record.cpp | 2 +- engines/ags/engine/ac/global_region.cpp | 12 +- engines/ags/engine/ac/global_room.cpp | 28 +- engines/ags/engine/ac/global_screen.cpp | 22 +- engines/ags/engine/ac/global_slider.cpp | 4 +- engines/ags/engine/ac/global_string.cpp | 8 +- engines/ags/engine/ac/global_textbox.cpp | 6 +- engines/ags/engine/ac/global_timer.cpp | 6 +- engines/ags/engine/ac/global_translation.cpp | 16 +- engines/ags/engine/ac/global_video.cpp | 20 +- engines/ags/engine/ac/global_viewframe.cpp | 6 +- engines/ags/engine/ac/global_viewport.cpp | 6 +- engines/ags/engine/ac/global_walkablearea.cpp | 8 +- engines/ags/engine/ac/global_walkbehind.cpp | 10 +- engines/ags/engine/ac/gui.cpp | 62 +- engines/ags/engine/ac/guicontrol.cpp | 20 +- engines/ags/engine/ac/guiinv.cpp | 6 +- engines/ags/engine/ac/hotspot.cpp | 30 +- engines/ags/engine/ac/interfaceelement.cpp | 2 +- engines/ags/engine/ac/inventoryitem.cpp | 30 +- engines/ags/engine/ac/invwindow.cpp | 68 +- engines/ags/engine/ac/keycode.cpp | 7 +- engines/ags/engine/ac/label.cpp | 16 +- engines/ags/engine/ac/listbox.cpp | 70 +-- engines/ags/engine/ac/math.cpp | 15 +- engines/ags/engine/ac/mouse.cpp | 40 +- engines/ags/engine/ac/movelist.cpp | 2 +- engines/ags/engine/ac/object.cpp | 50 +- engines/ags/engine/ac/overlay.cpp | 36 +- engines/ags/engine/ac/parser.cpp | 22 +- engines/ags/engine/ac/properties.cpp | 14 +- engines/ags/engine/ac/properties.h | 2 +- engines/ags/engine/ac/region.cpp | 24 +- engines/ags/engine/ac/richgamemedia.cpp | 2 +- engines/ags/engine/ac/room.cpp | 98 +-- engines/ags/engine/ac/roomobject.cpp | 10 +- engines/ags/engine/ac/roomstatus.cpp | 6 +- engines/ags/engine/ac/route_finder.cpp | 8 +- engines/ags/engine/ac/route_finder_impl.cpp | 8 +- .../engine/ac/route_finder_impl_legacy.cpp | 8 +- engines/ags/engine/ac/route_finder_jps.inl | 425 ++++++------- engines/ags/engine/ac/screen.cpp | 24 +- engines/ags/engine/ac/screenoverlay.cpp | 2 +- engines/ags/engine/ac/scriptcontainers.cpp | 16 +- engines/ags/engine/ac/slider.cpp | 10 +- engines/ags/engine/ac/speech.cpp | 22 +- engines/ags/engine/ac/sprite.cpp | 16 +- engines/ags/engine/ac/string.cpp | 12 +- engines/ags/engine/ac/sys_events.cpp | 14 +- engines/ags/engine/ac/system.cpp | 14 +- engines/ags/engine/ac/textbox.cpp | 10 +- engines/ags/engine/ac/translation.cpp | 2 +- engines/ags/engine/ac/viewframe.cpp | 16 +- engines/ags/engine/ac/viewport_script.cpp | 2 +- .../ags/engine/debugging/dummyagsdebugger.h | 2 +- engines/ags/engine/main/main.cpp | 6 +- engines/ags/engine/media/audio/audio.cpp | 4 +- engines/ags/engine/media/audio/soundcache.cpp | 2 +- engines/ags/engine/media/video/video.cpp | 4 +- engines/ags/engine/platform/linux/acpllnx.cpp | 4 +- .../ags/engine/platform/windows/acplwin.cpp | 4 +- .../windows/debugging/namedpipesagsdebugger.h | 2 +- .../engine/platform/windows/gfx/ali3dd3d.cpp | 4 +- .../platform/windows/win_ex_handling.cpp | 4 +- engines/ags/engine/util/library_psp.h | 2 +- engines/ags/engine/util/library_windows.h | 2 +- engines/ags/lib/aldumb.h | 118 ++++ engines/ags/lib/allegro.h | 2 + engines/ags/lib/allegro/draw.cpp | 31 + engines/ags/lib/allegro/draw.h | 37 ++ engines/ags/lib/allegro/file.cpp | 101 +++ engines/ags/lib/allegro/file.h | 81 ++- engines/ags/lib/allegro/fixed.h | 9 +- engines/ags/lib/allegro/fmaths.cpp | 101 +++ engines/ags/lib/allegro/fmaths.h | 41 ++ engines/ags/lib/allegro/gfx.cpp | 13 + engines/ags/lib/allegro/gfx.h | 9 + engines/ags/lib/allegro/keyboard.cpp | 40 ++ engines/ags/lib/allegro/keyboard.h | 76 +++ engines/ags/lib/allegro/system.h | 10 + engines/ags/lib/dumb.h | 581 ++++++++++++++++++ engines/ags/module.mk | 92 +++ engines/ags/shared/core/types.h | 2 + engines/ags/std/algorithm.h | 12 +- engines/ags/std/map.h | 6 +- engines/ags/std/math.h | 42 ++ engines/ags/std/queue.h | 22 + engines/ags/std/set.h | 30 +- engines/ags/std/unordered_set.h | 51 +- engines/ags/std/vector.h | 35 +- engines/ags/std/xutility.h | 8 + 135 files changed, 2902 insertions(+), 1455 deletions(-) create mode 100644 engines/ags/lib/aldumb.h create mode 100644 engines/ags/lib/allegro/draw.cpp create mode 100644 engines/ags/lib/allegro/draw.h create mode 100644 engines/ags/lib/allegro/fmaths.cpp create mode 100644 engines/ags/lib/allegro/fmaths.h create mode 100644 engines/ags/lib/dumb.h create mode 100644 engines/ags/std/math.h diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp index 9773f5f2b03c..31bb032c9aca 100644 --- a/engines/ags/engine/ac/audiochannel.cpp +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -29,6 +29,10 @@ #include "ags/engine/script/runtimescriptvalue.h" #include "ags/engine/media/audio/audio_system.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" + namespace AGS3 { using namespace AGS::Shared; @@ -202,10 +206,6 @@ void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPo // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // int | ScriptAudioChannel *channel RuntimeScriptValue Sc_AudioChannel_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_INT(ScriptAudioChannel, AudioChannel_GetID); diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp index 412072b34643..cd4047675276 100644 --- a/engines/ags/engine/ac/audioclip.cpp +++ b/engines/ags/engine/ac/audioclip.cpp @@ -25,6 +25,7 @@ #include "ags/engine/ac/audiochannel.h" #include "ags/shared/ac/gamesetupstruct.h" #include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/script/script_runtime.h" #include "ags/engine/ac/dynobj/cc_audiochannel.h" #include "ags/engine/media/audio/audio_system.h" @@ -80,9 +81,9 @@ ScriptAudioChannel *AudioClip_PlayQueued(ScriptAudioClip *clip, int priority, in // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" RuntimeScriptValue Sc_AudioClip_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_INT(ScriptAudioClip, AudioClip_GetID); diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index ee3ea08a5866..4d0dc7434c5b 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -26,50 +26,55 @@ // //============================================================================= -#include "ags/shared/ac/character.h" +#include "ags/engine/ac/character.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_object.h" -#include "ags/shared/ac/global_region.h" -#include "ags/shared/ac/global_room.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/lipsync.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/object.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/screenoverlay.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/viewframe.h" -#include "ags/shared/ac/walkablearea.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_object.h" +#include "ags/engine/ac/global_region.h" +#include "ags/engine/ac/global_room.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/lipsync.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/object.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/ac/walkablearea.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/ac/route_finder.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/main/update.h" +#include "ags/engine/ac/route_finder.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/main/update.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/util/string_compat.h" //include -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_character.h" -#include "ags/shared/ac/dynobj/cc_inventory.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_character.h" +#include "ags/engine/ac/dynobj/cc_inventory.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/gfx/gfx_def.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/ac/movelist.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/movelist.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -2236,7 +2241,7 @@ int my_getpixel(Bitmap *blk, int x, int y) { // strip the alpha channel // TODO: is there a way to do this vtable thing with Bitmap? BITMAP *al_bmp = (BITMAP *)blk->GetAllegroBitmap(); - return al_bmp->vtable->getpixel(al_bmp, x, y) & 0x00ffffff; + return al_bmp->getpixel(x, y) & 0x00ffffff; } int check_click_on_character(int xx, int yy, int mood) { @@ -2848,11 +2853,6 @@ PViewport FindNearestViewport(int charid) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // void | CharacterInfo *chaa, ScriptInvItem *invi, int addIndex diff --git a/engines/ags/engine/ac/characterextras.cpp b/engines/ags/engine/ac/characterextras.cpp index e0e80a0bc50c..2fec603b6da0 100644 --- a/engines/ags/engine/ac/characterextras.cpp +++ b/engines/ags/engine/ac/characterextras.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/characterextras.h" +#include "ags/engine/ac/characterextras.h" #include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp index 74118dce63bc..9264f21b3833 100644 --- a/engines/ags/engine/ac/characterinfo_engine.cpp +++ b/engines/ags/engine/ac/characterinfo_engine.cpp @@ -23,17 +23,18 @@ #include "ags/shared/ac/characterinfo.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/characterextras.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/math.h" -#include "ags/shared/ac/viewframe.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/characterextras.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/math.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/main/maindefines_ex.h" // RETURN_CONTINUE -#include "ags/shared/main/update.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/main/maindefines_ex.h" // RETURN_CONTINUE +#include "ags/engine/main/update.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/ags.h" namespace AGS3 { @@ -470,7 +471,7 @@ void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_noth // if there arent enough loops to do the current one. if ((idletime > 0) && (useloop >= maxLoops)) { do { - useloop = rand() % maxLoops; + useloop = ::AGS::g_vm->getRandomNumber(maxLoops - 1); // don't select a loop which is a continuation of a previous one } while ((useloop > 0) && (views[idleview].loops[useloop - 1].RunNextLoop())); } diff --git a/engines/ags/engine/ac/datetime.cpp b/engines/ags/engine/ac/datetime.cpp index c46c4589950b..fd07d3050af5 100644 --- a/engines/ags/engine/ac/datetime.cpp +++ b/engines/ags/engine/ac/datetime.cpp @@ -21,9 +21,13 @@ */ //include -#include "ags/shared/ac/datetime.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/ac/datetime.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/script/runtimescriptvalue.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -75,10 +79,6 @@ int DateTime_GetRawTime(ScriptDateTime *sdt) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // ScriptDateTime* () RuntimeScriptValue Sc_DateTime_Now(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_OBJAUTO(ScriptDateTime, DateTime_Now); diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 4f3522da9a05..4ccb896ed42f 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -20,45 +20,50 @@ * */ -#include "ags/shared/ac/dialog.h" +#include "ags/engine/ac/dialog.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/character.h" +#include "ags/engine/ac/character.h" #include "ags/shared/ac/characterinfo.h" #include "ags/shared/ac/dialogtopic.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/gamestate.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_dialog.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_room.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/keycode.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/parser.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/dynobj/scriptdialogoptionsrendering.h" -#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_dialog.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_room.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/keycode.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/parser.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/dynobj/scriptdialogoptionsrendering.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/script/cc_instance.h" +#include "ags/engine/script/cc_instance.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guitextbox.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/script/script.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/script/script.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/gfx/ddb.h" -#include "ags/shared/gfx/gfx_util.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/gfx/gfx_util.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/media/audio/audio_system.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -582,16 +587,16 @@ void DialogOptions::Show() { } } else { //dlgyp=(play.viewport.GetHeight()-numdisp*txthit)-1; - const Rect &ui_view = play.GetUIViewport(); - areawid = ui_view.GetWidth() - 5; + const Rect &uiView = play.GetUIViewport(); + areawid = uiView.GetWidth() - 5; padding = TEXTWINDOW_PADDING_DEFAULT; GET_OPTIONS_HEIGHT - dlgyp = ui_view.GetHeight() - needheight; + dlgyp = uiView.GetHeight() - needheight; dirtyx = 0; dirtyy = dlgyp - 1; - dirtywidth = ui_view.GetWidth(); - dirtyheight = ui_view.GetHeight() - dirtyy; + dirtywidth = uiView.GetWidth(); + dirtyheight = uiView.GetHeight() - dirtyy; dialog_abs_x = 0; } if (!is_textwindow) @@ -1148,11 +1153,6 @@ void do_conversation(int dlgnum) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // int (ScriptDialog *sd) diff --git a/engines/ags/engine/ac/dialogoptionsrendering.cpp b/engines/ags/engine/ac/dialogoptionsrendering.cpp index f7bf6a54530d..059d6aa07ea8 100644 --- a/engines/ags/engine/ac/dialogoptionsrendering.cpp +++ b/engines/ags/engine/ac/dialogoptionsrendering.cpp @@ -20,13 +20,14 @@ * */ -#include "ags/shared/ac/dialog.h" +#include "ags/engine/ac/dialog.h" #include "ags/shared/ac/dialogtopic.h" -#include "ags/shared/ac/dialogoptionsrendering.h" +#include "ags/engine/ac/dialogoptionsrendering.h" #include "ags/shared/ac/gamestructdefines.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_dialog.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/cc_dialog.h" namespace AGS3 { @@ -138,9 +139,9 @@ void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgO // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" RuntimeScriptValue Sc_DialogOptionsRendering_Update(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_VOID(ScriptDialogOptionsRendering, DialogOptionsRendering_Update); diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp index cfbc137cdf6f..7f4574138a21 100644 --- a/engines/ags/engine/ac/display.cpp +++ b/engines/ags/engine/ac/display.cpp @@ -22,38 +22,38 @@ //include -#include "ags/shared/ac/display.h" +#include "ags/engine/ac/display.h" #include "ags/shared/ac/common.h" #include "ags/shared/font/agsfontrenderer.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/screenoverlay.h" -#include "ags/shared/ac/speech.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/topbarsettings.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/gfx/blender.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/speech.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/topbarsettings.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/gfx/blender.h" #include "ags/shared/gui/guibutton.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/gfx/gfx_util.h" +#include "ags/engine/gfx/gfx_util.h" #include "ags/shared/util/string_utils.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index 7ac126608e33..6e451c414d48 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -20,56 +20,56 @@ * */ -//include -//include -#include "ags/shared/aastr.h" +#include "ags/std/algorithm.h" +#include "ags/std/math.h" +#include "ags/lib/aastr-0.1.1/aastr.h" #include "ags/shared/core/platform.h" #include "ags/shared/ac/common.h" #include "ags/shared/util/compress.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/charactercache.h" -#include "ags/shared/ac/characterextras.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/engine/ac/characterextras.h" #include "ags/shared/ac/characterinfo.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/draw_software.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/draw_software.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_region.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/roomobject.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/screenoverlay.h" -#include "ags/shared/ac/sprite.h" -#include "ags/shared/ac/spritelistentry.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/viewframe.h" -#include "ags/shared/ac/walkablearea.h" -#include "ags/shared/ac/walkbehind.h" -#include "ags/shared/ac/dynobj/scriptsystem.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_region.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/sprite.h" +#include "ags/engine/ac/spritelistentry.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/ac/walkablearea.h" +#include "ags/engine/ac/walkbehind.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/font/fonts.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/gfx/gfx_util.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/gfx/ali3dexception.h" -#include "ags/shared/gfx/blender.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/gfx/gfx_util.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/gfx/ali3dexception.h" +#include "ags/engine/gfx/blender.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/game.h" namespace AGS3 { @@ -447,16 +447,16 @@ AGS_INLINE void defgame_to_finalgame_coords(int &x, int &y) { void create_blank_image(int coldepth) { // this is the first time that we try to use the graphics driver, // so it's the most likey place for a crash - try { +// try { Bitmap *blank = BitmapHelper::CreateBitmap(16, 16, coldepth); blank = ReplaceBitmapWithSupportedFormat(blank); blank->Clear(); blankImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); blankSidebarImage = gfxDriver->CreateDDBFromBitmap(blank, false, true); delete blank; - } catch (Ali3DException gfxException) { +/* } catch (Ali3DException gfxException) { quit((char *)gfxException._message); - } + }*/ } void destroy_blank_image() { @@ -703,7 +703,7 @@ void render_to_screen() { bool succeeded = false; while (!succeeded) { - try { +// try { // For software renderer, need to blacken upper part of the game frame when shaking screen moves image down const Rect &viewport = play.GetMainViewport(); if (play.shake_screen_yoff > 0 && !gfxDriver->RequiresFullRedrawEachFrame()) @@ -719,9 +719,9 @@ void render_to_screen() { #endif succeeded = true; - } catch (Ali3DFullscreenLostException) { +/* } catch (Ali3DFullscreenLostException) { platform->Delay(500); - } + }*/ } } @@ -1255,15 +1255,15 @@ int scale_and_flip_sprite(int useindx, int coldept, int zoom_level, Bitmap *tempspr = BitmapHelper::CreateBitmap(newwidth, newheight, coldept); tempspr->Fill(actsps[useindx]->GetMaskColor()); if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) - tempspr->AAStretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + tempspr->AAStretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Shared::kBitmap_Transparency); else - tempspr->StretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); - active_spr->FlipBlt(tempspr, 0, 0, Common::kBitmap_HFlip); + tempspr->StretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Shared::kBitmap_Transparency); + active_spr->FlipBlt(tempspr, 0, 0, Shared::kBitmap_HFlip); delete tempspr; } else if ((IS_ANTIALIAS_SPRITES) && ((game.SpriteInfos[sppic].Flags & SPF_ALPHACHANNEL) == 0)) - active_spr->AAStretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + active_spr->AAStretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Shared::kBitmap_Transparency); else - active_spr->StretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Common::kBitmap_Transparency); + active_spr->StretchBlt(spriteset[sppic], RectWH(0, 0, newwidth, newheight), Shared::kBitmap_Transparency); /* AASTR2 version of code (doesn't work properly, gives black borders) if (IS_ANTIALIAS_SPRITES) { @@ -1280,7 +1280,7 @@ int scale_and_flip_sprite(int useindx, int coldept, int zoom_level, Bitmap *tempspr = BitmapHelper::CreateBitmap_ (coldept, newwidth, newheight); ->Clear (tempspr, ->GetMaskColor(actsps[useindx])); ->StretchBlt (tempspr, spriteset[sppic], 0, 0, newwidth, newheight); - ->FlipBlt(Common::kBitmap_HFlip, (actsps[useindx], tempspr, 0, 0); + ->FlipBlt(Shared::kBitmap_HFlip, (actsps[useindx], tempspr, 0, 0); wfreeblock (tempspr); } else @@ -1295,7 +1295,7 @@ int scale_and_flip_sprite(int useindx, int coldept, int zoom_level, our_eip = 339; if (isMirrored) - active_spr->FlipBlt(spriteset[sppic], 0, 0, Common::kBitmap_HFlip); + active_spr->FlipBlt(spriteset[sppic], 0, 0, Shared::kBitmap_HFlip); else actsps_used = 0; //->Blit (spriteset[sppic], actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight()); diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index ab4412a4279a..999d9b4a7bc3 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -46,11 +46,11 @@ // //============================================================================= -//include +#include "ags/std/utility.h" #include "ags/std/vector.h" -#include "ags/shared/ac/draw_software.h" +#include "ags/engine/ac/draw_software.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/util/scaling.h" +#include "ags/engine/util/scaling.h" namespace AGS3 { @@ -288,7 +288,7 @@ void invalidate_rect_on_surf(int x1, int y1, int x2, int y2, DirtyRects &rects) dirtyRow[a].numSpans++; } else { // didn't fit in an existing span, and there are none spare - int nearestDist = 99999, nearestWas = -1, extendLeft; + int nearestDist = 99999, nearestWas = -1, extendLeft = 0; int tleft, tright; // find the nearest span, and enlarge that to include this rect for (s = 0; s < dirtyRow[a].numSpans; s++) { diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp index a0a6f494f539..13b86da26a56 100644 --- a/engines/ags/engine/ac/drawingsurface.cpp +++ b/engines/ags/engine/ac/drawingsurface.cpp @@ -20,27 +20,32 @@ * */ -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/drawingsurface.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/drawingsurface.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/charactercache.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/roomobject.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/walkbehind.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/walkbehind.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/font/fonts.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/script/runtimescriptvalue.h" #include "ags/shared/gfx/gfx_def.h" -#include "ags/shared/gfx/gfx_util.h" +#include "ags/engine/gfx/gfx_util.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -427,13 +432,13 @@ int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) { int colDepth = ds->GetColorDepth(); if (rawPixel == maskColor) { - rawPixel = SCR_COLOR_TRANSPARENT; + rawPixel = (unsigned int)SCR_COLOR_TRANSPARENT; } else if (colDepth > 8) { int r = getr_depth(colDepth, rawPixel); - int ds = getg_depth(colDepth, rawPixel); + int g = getg_depth(colDepth, rawPixel); int b = getb_depth(colDepth, rawPixel); - rawPixel = Game_GetColorFromRGB(r, ds, b); + rawPixel = Game_GetColorFromRGB(r, g, b); } sds->FinishedDrawingReadOnly(); @@ -447,10 +452,6 @@ int DrawingSurface_GetPixel(ScriptDrawingSurface *sds, int x, int y) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // void (ScriptDrawingSurface *sds, int colour) RuntimeScriptValue Sc_DrawingSurface_Clear(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_VOID_PINT(ScriptDrawingSurface, DrawingSurface_Clear); diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp index d5c635592d3e..2d78b61869dc 100644 --- a/engines/ags/engine/ac/dynamicsprite.cpp +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -21,25 +21,29 @@ */ //include -#include "ags/shared/ac/dynamicsprite.h" +#include "ags/engine/ac/dynamicsprite.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/charactercache.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_dynamicsprite.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/math.h" // M_PI -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/ac/roomobject.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/global_dynamicsprite.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/math.h" // M_PI +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" #include "ags/shared/gui/guibutton.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/script/runtimescriptvalue.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -135,11 +139,11 @@ void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction) { Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(game.SpriteInfos[sds->slot].Width, game.SpriteInfos[sds->slot].Height, spriteset[sds->slot]->GetColorDepth()); if (direction == 1) - newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HFlip); + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Shared::kBitmap_HFlip); else if (direction == 2) - newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_VFlip); + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Shared::kBitmap_VFlip); else if (direction == 3) - newPic->FlipBlt(spriteset[sds->slot], 0, 0, Common::kBitmap_HVFlip); + newPic->FlipBlt(spriteset[sds->slot], 0, 0, Shared::kBitmap_HVFlip); delete spriteset[sds->slot]; @@ -504,10 +508,6 @@ void free_dynamic_sprite(int gotSlot) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // void (ScriptDynamicSprite *sds, int width, int height, int x, int y) RuntimeScriptValue Sc_DynamicSprite_ChangeCanvasSize(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_VOID_PINT4(ScriptDynamicSprite, DynamicSprite_ChangeCanvasSize); diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index 08740845c62c..e560fccf9e02 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -91,12 +91,16 @@ class ScriptDictImpl final : public ScriptDictBase { _dic.clear(); } bool Contains(const char *key) override { +#ifdef AGS_PLATFORM_SCUMMVM + return _dic.find(String::Wrapper(key)) != _dic.end(); +#else return _dic.count(String::Wrapper(key)) != 0; +#endif } const char *Get(const char *key) override { auto it = _dic.find(String::Wrapper(key)); if (it == _dic.end()) return nullptr; - return it->second.GetNullableCStr(); + return it->_value.GetNullableCStr(); } bool Remove(const char *key) override { auto it = _dic.find(String::Wrapper(key)); @@ -116,11 +120,11 @@ class ScriptDictImpl final : public ScriptDictBase { } void GetKeys(std::vector &buf) const override { for (auto it = _dic.begin(); it != _dic.end(); ++it) - buf.push_back(it->first.GetCStr()); // keys cannot be null + buf.push_back(it->_key.GetCStr()); // keys cannot be null } void GetValues(std::vector &buf) const override { for (auto it = _dic.begin(); it != _dic.end(); ++it) - buf.push_back(it->second.GetNullableCStr()); // values may be null + buf.push_back(it->_value.GetNullableCStr()); // values may be null } private: @@ -139,8 +143,8 @@ class ScriptDictImpl final : public ScriptDictBase { size_t CalcSerializeSize() override { size_t total_sz = sizeof(int32_t); for (auto it = _dic.begin(); it != _dic.end(); ++it) { - total_sz += sizeof(int32_t) + it->first.GetLength(); - total_sz += sizeof(int32_t) + it->second.GetLength(); + total_sz += sizeof(int32_t) + it->_key.GetLength(); + total_sz += sizeof(int32_t) + it->_value.GetLength(); } return total_sz; } @@ -148,13 +152,13 @@ class ScriptDictImpl final : public ScriptDictBase { void SerializeContainer() override { SerializeInt((int)_dic.size()); for (auto it = _dic.begin(); it != _dic.end(); ++it) { - SerializeInt((int)it->first.GetLength()); - memcpy(&serbuffer[bytesSoFar], it->first.GetCStr(), it->first.GetLength()); - bytesSoFar += it->first.GetLength(); - if (it->second.GetNullableCStr()) { // values may be null - SerializeInt((int)it->second.GetLength()); - memcpy(&serbuffer[bytesSoFar], it->second.GetCStr(), it->second.GetLength()); - bytesSoFar += it->second.GetLength(); + SerializeInt((int)it->_key.GetLength()); + memcpy(&serbuffer[bytesSoFar], it->_key.GetCStr(), it->_key.GetLength()); + bytesSoFar += it->_key.GetLength(); + if (it->_value.GetNullableCStr()) { // values may be null + SerializeInt((int)it->_value.GetLength()); + memcpy(&serbuffer[bytesSoFar], it->_value.GetCStr(), it->_value.GetLength()); + bytesSoFar += it->_value.GetLength(); } else { SerializeInt(-1); } @@ -182,7 +186,8 @@ class ScriptDictImpl final : public ScriptDictBase { }; typedef ScriptDictImpl< std::map, true, true > ScriptDict; -typedef ScriptDictImpl< std::map, true, false > ScriptDictCI; +// TODO: Not sure if current std::map implement works for LessThan to give a key ordering +typedef ScriptDictImpl< std::map, true, false > ScriptDictCI; typedef ScriptDictImpl< std::unordered_map, false, true > ScriptHashDict; typedef ScriptDictImpl< std::unordered_map, false, false > ScriptHashDictCI; diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index e6ca5068f789..10a00757acac 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -113,7 +113,7 @@ class ScriptSetImpl final : public ScriptSetBase { private: bool TryAddItem(const char *item, size_t len) { - return _set.insert(String(item, len)).second; + return _set.insert(String(item, len))._value; } void DeleteItem(ConstIterator it) { /* do nothing */ diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp index cf8d118ab920..bb7d9b23aa84 100644 --- a/engines/ags/engine/ac/event.cpp +++ b/engines/ags/engine/ac/event.cpp @@ -20,27 +20,27 @@ * */ -#include "ags/shared/event.h" +#include "ags/engine/ac/event.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_room.h" -#include "ags/shared/ac/global_screen.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/screen.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_room.h" +#include "ags/engine/ac/global_screen.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/screen.h" #include "ags/shared/script/cc_error.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" -#include "ags/shared/script/script.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" +#include "ags/engine/script/script.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/ddb.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/timer.h" namespace AGS3 { @@ -121,12 +121,12 @@ void run_room_event(int id) { } } -void run_event_block_inv(int invNum, int event) { +void run_event_block_inv(int invNum, int event_) { evblockbasename = "inventory%d"; if (loaded_game_file_version > kGameVersion_272) { - run_interaction_script(game.invScripts[invNum].get(), event); + run_interaction_script(game.invScripts[invNum].get(), event_); } else { - run_interaction_event(game.intrInv[invNum].get(), event); + run_interaction_event(game.intrInv[invNum].get(), event_); } } @@ -238,7 +238,7 @@ void process_event(EventHappened *evp) { } // TODO: use normal coordinates instead of "native_size" and multiply_up_*? - const Size &data_res = game.GetDataRes(); + //const Size &data_res = game.GetDataRes(); const Rect &viewport = play.GetMainViewport(); if ((theTransition == FADE_INSTANT) || ignore_transition) diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index 6a6a30b0a859..cfee54d31ccc 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -20,32 +20,37 @@ * */ -#include "ags/shared/aldumb.h" -#include "ags/shared/ac/asset_helper.h" +#include "ags/lib/aldumb.h" +#include "ags/engine/ac/asset_helper.h" #include "ags/shared/ac/audiocliptype.h" -#include "ags/shared/ac/file.h" +#include "ags/engine/ac/file.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_file.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" +#include "ags/engine/ac/global_file.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" #include "ags/shared/util/misc.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/util/stream.h" #include "ags/shared/core/assetmanager.h" #include "ags/shared/core/asset.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/main/game_file.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/game_file.h" #include "ags/shared/util/directory.h" #include "ags/shared/util/path.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_utils.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" + namespace AGS3 { using namespace AGS::Shared; @@ -85,7 +90,7 @@ int File_Delete(const char *fnmm) { if (::remove(rp.FullPath) == 0) return 1; - if (errno == ENOENT && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) + if (errnum == ENOENT && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) return ::remove(rp.AltPath) == 0 ? 1 : 0; return 0; } @@ -535,7 +540,7 @@ String get_known_assetlib(const String &filename) { } Stream *find_open_asset(const String &filename) { - Stream *asset_s = Common::AssetManager::OpenAsset(filename); + Stream *asset_s = Shared::AssetManager::OpenAsset(filename); if (!asset_s && Path::ComparePaths(ResPaths.DataDir, installDirectory) != 0) { // Just in case they're running in Debug, try standalone file in compiled folder asset_s = ci_fopen(String::FromFormat("%s/%s", installDirectory.GetCStr(), filename.GetCStr())); @@ -613,11 +618,6 @@ Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_ // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // int (const char *fnmm) diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 928974a26e4a..4b988ef1c300 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -20,83 +20,88 @@ * */ -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/view.h" #include "ags/shared/ac/audiocliptype.h" -#include "ags/shared/ac/audiochannel.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/charactercache.h" -#include "ags/shared/ac/characterextras.h" +#include "ags/engine/ac/audiochannel.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/engine/ac/characterextras.h" #include "ags/shared/ac/dialogtopic.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/dynamicsprite.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/dynamicsprite.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_object.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/hotspot.h" -#include "ags/shared/ac/lipsync.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/movelist.h" -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/region.h" -#include "ags/shared/ac/richgamemedia.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomobject.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/screenoverlay.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_object.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/hotspot.h" +#include "ags/engine/ac/lipsync.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/movelist.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/region.h" +#include "ags/engine/ac/richgamemedia.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/screenoverlay.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/timer.h" -#include "ags/shared/ac/translation.h" -#include "ags/shared/ac/dynobj/all_dynamicclasses.h" -#include "ags/shared/ac/dynobj/all_scriptclasses.h" -#include "ags/shared/ac/dynobj/cc_audiochannel.h" -#include "ags/shared/ac/dynobj/cc_audioclip.h" -#include "ags/shared/ac/dynobj/scriptcamera.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/out.h" -#include "ags/shared/device/mousew32.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/timer.h" +#include "ags/engine/ac/translation.h" +#include "ags/engine/ac/dynobj/all_dynamicclasses.h" +#include "ags/engine/ac/dynobj/all_scriptclasses.h" +#include "ags/engine/ac/dynobj/cc_audiochannel.h" +#include "ags/engine/ac/dynobj/cc_audioclip.h" +#include "ags/engine/ac/dynobj/scriptcamera.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/device/mousew32.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/game/savegame.h" -#include "ags/shared/game/savegame_components.h" -#include "ags/shared/game/savegame_internal.h" -#include "ags/shared/gui/animatingguibutton.h" +#include "ags/engine/game/savegame.h" +#include "ags/engine/game/savegame_components.h" +#include "ags/engine/game/savegame_internal.h" +#include "ags/engine/gui/animatingguibutton.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/gfx/gfxfilter.h" -#include "ags/shared/gui/guidialog.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/main/graphics_mode.h" -#include "ags/shared/main/main.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/gfx/gfxfilter.h" +#include "ags/engine/gui/guidialog.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/main/main.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/script/cc_error.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/script/script.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/script/script.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/util/alignedstream.h" #include "ags/shared/util/directory.h" #include "ags/shared/util/filestream.h" // TODO: needed only because plugins expect file handle #include "ags/shared/util/path.h" #include "ags/shared/util/string_utils.h" -#include "ags/shared/ac/keycode.h" +#include "ags/engine/ac/keycode.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/ags.h" namespace AGS3 { @@ -436,12 +441,12 @@ bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path) { } String newFolderTempFile = String::FromFormat("%s""agstmp.tmp", newSaveGameDir.GetCStr()); - if (!Common::File::TestCreateFile(newFolderTempFile)) + if (!Shared::File::TestCreateFile(newFolderTempFile)) return false; // copy the Restart Game file, if applicable String restartGamePath = String::FromFormat("%s""agssave.%d%s", saveGameDirectory.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); - Stream *restartGameFile = Common::File::OpenFileRead(restartGamePath); + Stream *restartGameFile = Shared::File::OpenFileRead(restartGamePath); if (restartGameFile != nullptr) { long fileSize = restartGameFile->GetLength(); char *mbuffer = (char *)malloc(fileSize); @@ -449,7 +454,7 @@ bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path) { delete restartGameFile; restartGamePath.Format("%s""agssave.%d%s", newSaveGameDir.GetCStr(), RESTART_POINT_SAVE_GAME_NUMBER, saveGameSuffix.GetCStr()); - restartGameFile = Common::File::CreateFile(restartGamePath); + restartGameFile = Shared::File::CreateFile(restartGamePath); restartGameFile->Write(mbuffer, fileSize); delete restartGameFile; free(mbuffer); @@ -771,7 +776,7 @@ const char *Game_GetName() { void Game_SetName(const char *newName) { strncpy(play.game_name, newName, 99); play.game_name[99] = 0; - set_window_title(play.game_name); + ::AGS::g_vm->set_window_title(play.game_name); } int Game_GetSkippingCutscene() { @@ -876,8 +881,8 @@ ScriptCamera *Game_GetAnyCamera(int index) { return play.GetScriptCamera(index); } -void Game_SimulateKeyPress(int key) { - int platformKey = GetKeyForKeyPressCb(key); +void Game_SimulateKeyPress(int key_) { + int platformKey = GetKeyForKeyPressCb(key_); platformKey = PlatformKeyFromAgsKey(platformKey); if (platformKey >= 0) { simulate_keypress(platformKey); @@ -985,6 +990,7 @@ void skip_serialized_bitmap(Stream *in) { } long write_screen_shot_for_vista(Stream *out, Bitmap *screenshot) { +#ifdef TODO long fileSize = 0; String tempFileName = String::FromFormat("%s""_tmpscht.bmp", saveGameDirectory.GetCStr()); @@ -996,7 +1002,7 @@ long write_screen_shot_for_vista(Stream *out, Bitmap *screenshot) { fileSize = file_size_ex(tempFileName); char *buffer = (char *)malloc(fileSize); - Stream *temp_in = Common::File::OpenFileRead(tempFileName); + Stream *temp_in = Shared::File::OpenFileRead(tempFileName); temp_in->Read(buffer, fileSize); delete temp_in; ::remove(tempFileName); @@ -1005,10 +1011,13 @@ long write_screen_shot_for_vista(Stream *out, Bitmap *screenshot) { free(buffer); } return fileSize; +#else + error("TODO: write_screen_shot_for_vista"); +#endif } void WriteGameSetupStructBase_Aligned(Stream *out) { - AlignedStream align_s(out, Common::kAligned_Write); + AlignedStream align_s(out, Shared::kAligned_Write); game.GameSetupStructBase::WriteToFile(&align_s); } @@ -1056,7 +1065,7 @@ void save_game(int slotn, const char *descript) { // Screenshot create_savegame_screenshot(screenShot); - Common::PStream out = StartSavegame(nametouse, descript, screenShot); + Shared::PStream out = StartSavegame(nametouse, descript, screenShot); if (out == nullptr) quit("save_game: unable to open savegame file for writing"); @@ -1071,7 +1080,7 @@ void save_game(int slotn, const char *descript) { update_polled_stuff_if_runtime(); - out.reset(Common::File::OpenFile(nametouse, Common::kFile_Open, Common::kFile_ReadWrite)); + out.reset(Shared::File::OpenFile(nametouse, Shared::kFile_Open, Shared::kFile_ReadWrite)); out->Seek(12, kSeekBegin); out->WriteInt32(screenShotOffset); out->Seek(4); @@ -1121,7 +1130,7 @@ HSaveError restore_game_scripts(Stream *in, const PreservedParams &pp, RestoredD r_data.ScriptModules.resize(numScriptModules); for (int i = 0; i < numScriptModules; ++i) { size_t module_size = in->ReadInt32(); - if (pp.ScMdDataSize[i] != module_size) { + if (pp.ScMdDataSize[i] != (int)module_size) { return new SavegameError(kSvgErr_GameContentAssertion, String::FromFormat("Mismatching size of script module data, module %d.", i)); } r_data.ScriptModules[i].Len = module_size; @@ -1132,7 +1141,7 @@ HSaveError restore_game_scripts(Stream *in, const PreservedParams &pp, RestoredD } void ReadRoomStatus_Aligned(RoomStatus *roomstat, Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); roomstat->ReadFromFile_v321(&align_s); } @@ -1162,7 +1171,7 @@ void restore_game_room_state(Stream *in) { } void ReadGameState_Aligned(Stream *in, RestoredData &r_data) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); play.ReadFromSavegame(&align_s, kGSSvgVersion_OldFormat, r_data); } @@ -1193,7 +1202,7 @@ void restore_game_play(Stream *in, RestoredData &r_data) { } void ReadMoveList_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int i = 0; i < game.numcharacters + MAX_ROOM_OBJECTS + 1; ++i) { mls[i].ReadFromFile_Legacy(&align_s); @@ -1202,12 +1211,12 @@ void ReadMoveList_Aligned(Stream *in) { } void ReadGameSetupStructBase_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); game.GameSetupStructBase::ReadFromFile(&align_s); } void ReadCharacterExtras_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int i = 0; i < game.numcharacters; ++i) { charextra[i].ReadFromFile(&align_s); align_s.Reset(); @@ -1232,7 +1241,7 @@ void restore_game_more_dynamic_values(Stream *in) { } void ReadAnimatedButtons_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int i = 0; i < numAnimButs; ++i) { animbuts[i].ReadFromFile(&align_s); align_s.Reset(); @@ -1255,7 +1264,7 @@ HSaveError restore_game_gui(Stream *in, int numGuisWas) { } HSaveError restore_game_audiocliptypes(Stream *in) { - if (in->ReadInt32() != game.audioClipTypes.size()) { + if (in->ReadInt32() != (int)game.audioClipTypes.size()) { return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clip Types."); } @@ -1288,7 +1297,7 @@ void restore_game_ambientsounds(Stream *in, RestoredData &r_data) { } void ReadOverlays_Aligned(Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (auto &over : screenover) { over.ReadFromFile(&align_s, 0); align_s.Reset(); @@ -1374,7 +1383,7 @@ HSaveError restore_game_views(Stream *in) { } HSaveError restore_game_audioclips_and_crossfade(Stream *in, RestoredData &r_data) { - if (in->ReadInt32() != game.audioClips.size()) { + if (in->ReadInt32() != (int)game.audioClips.size()) { return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of Audio Clips."); } @@ -1383,7 +1392,7 @@ HSaveError restore_game_audioclips_and_crossfade(Stream *in, RestoredData &r_dat chan_info.Pos = 0; chan_info.ClipID = in->ReadInt32(); if (chan_info.ClipID >= 0) { - if ((size_t)chan_info.ClipID >= game.audioClips.size()) { + if ((size_t)chan_info.ClipID >= (int)game.audioClips.size()) { return new SavegameError(kSvgErr_GameObjectInitFailed, "Invalid audio clip index."); } @@ -1576,12 +1585,12 @@ HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten) // Try to find wanted game's executable; if it does not exist, // continue loading savedgame in current game, and pray for the best get_install_dir_path(gamefilenamebuf, desc.MainDataFilename); - if (Common::File::TestReadFile(gamefilenamebuf)) { + if (Shared::File::TestReadFile(gamefilenamebuf)) { RunAGSGame(desc.MainDataFilename, 0, 0); load_new_game_restore = slotNumber; return HSaveError::None(); } - Common::Debug::Printf(kDbgMsg_Warn, "WARNING: the saved game '%s' references game file '%s', but it cannot be found in the current directory. Trying to restore in the running game instead.", + Shared::Debug::Printf(kDbgMsg_Warn, "WARNING: the saved game '%s' references game file '%s', but it cannot be found in the current directory. Trying to restore in the running game instead.", path.GetCStr(), desc.MainDataFilename.GetCStr()); } @@ -1937,10 +1946,6 @@ bool unserialize_audio_script_object(int index, const char *objectType, const ch // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // int (int audioType); RuntimeScriptValue Sc_Game_IsAudioPlaying(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_INT_PINT(Game_IsAudioPlaying); diff --git a/engines/ags/engine/ac/gamesetup.cpp b/engines/ags/engine/ac/gamesetup.cpp index 2bce8af2e1b3..3c7a2b8a7ff8 100644 --- a/engines/ags/engine/ac/gamesetup.cpp +++ b/engines/ags/engine/ac/gamesetup.cpp @@ -21,7 +21,7 @@ */ #include "ags/shared/util/wgt2allg.h" // DIGI_AUTODETECT & MIDI_AUTODETECT -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/gamesetup.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index b6e186b61019..889c3a5d45a0 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -20,22 +20,22 @@ * */ -//include -#include "ags/shared/ac/draw.h" +#include "ags/std/algorithm.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/game_version.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/gamestate.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/timer.h" -#include "ags/shared/ac/dynobj/scriptcamera.h" -#include "ags/shared/ac/dynobj/scriptsystem.h" -#include "ags/shared/ac/dynobj/scriptviewport.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/device/mousew32.h" +#include "ags/engine/ac/timer.h" +#include "ags/engine/ac/dynobj/scriptcamera.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/engine/ac/dynobj/scriptviewport.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/device/mousew32.h" #include "ags/shared/game/customproperties.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/game/savegame_internal.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/game/savegame_internal.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/media/audio/audio_system.h" #include "ags/shared/util/alignedstream.h" #include "ags/shared/util/string_utils.h" @@ -130,7 +130,7 @@ void GameState::UpdateViewports() { } _roomViewportZOrderChanged = false; } - size_t vp_changed = -1; + size_t vp_changed = (size_t)-1; for (size_t i = _roomViewportsSorted.size(); i-- > 0;) { auto vp = _roomViewportsSorted[i]; if (vp->HasChangedSize() || vp->HasChangedPosition() || vp->HasChangedVisible()) { @@ -777,7 +777,7 @@ void GameState::WriteForSavegame(Shared::Stream *out) const { } void GameState::ReadQueuedAudioItems_Aligned(Shared::Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int i = 0; i < MAX_QUEUED_MUSIC; ++i) { new_music_queue[i].ReadFromFile(&align_s); align_s.Reset(); diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp index ce894d675e59..49d411b5e8ec 100644 --- a/engines/ags/engine/ac/global_api.cpp +++ b/engines/ags/engine/ac/global_api.cpp @@ -26,61 +26,61 @@ // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - -#include "ags/shared/ac/cdaudio.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/dynamicsprite.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_button.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_datetime.h" -#include "ags/shared/ac/global_debug.h" -#include "ags/shared/ac/global_dialog.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/global_drawingsurface.h" -#include "ags/shared/ac/global_dynamicsprite.h" -#include "ags/shared/ac/global_file.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_hotspot.h" -#include "ags/shared/ac/global_inventoryitem.h" -#include "ags/shared/ac/global_invwindow.h" -#include "ags/shared/ac/global_label.h" -#include "ags/shared/ac/global_listbox.h" -#include "ags/shared/ac/global_mouse.h" -#include "ags/shared/ac/global_object.h" -#include "ags/shared/ac/global_overlay.h" -#include "ags/shared/ac/global_palette.h" -#include "ags/shared/ac/global_parser.h" -#include "ags/shared/ac/global_record.h" -#include "ags/shared/ac/global_region.h" -#include "ags/shared/ac/global_room.h" -#include "ags/shared/ac/global_slider.h" -#include "ags/shared/ac/global_screen.h" -#include "ags/shared/ac/global_string.h" -#include "ags/shared/ac/global_textbox.h" -#include "ags/shared/ac/global_timer.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/global_video.h" -#include "ags/shared/ac/global_viewframe.h" -#include "ags/shared/ac/global_viewport.h" -#include "ags/shared/ac/global_walkablearea.h" -#include "ags/shared/ac/global_walkbehind.h" -#include "ags/shared/ac/math.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/parser.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/media/video/video.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" + +#include "ags/engine/ac/cdaudio.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/dynamicsprite.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_button.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_datetime.h" +#include "ags/engine/ac/global_debug.h" +#include "ags/engine/ac/global_dialog.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_drawingsurface.h" +#include "ags/engine/ac/global_dynamicsprite.h" +#include "ags/engine/ac/global_file.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_hotspot.h" +#include "ags/engine/ac/global_inventoryitem.h" +#include "ags/engine/ac/global_invwindow.h" +#include "ags/engine/ac/global_label.h" +#include "ags/engine/ac/global_listbox.h" +#include "ags/engine/ac/global_mouse.h" +#include "ags/engine/ac/global_object.h" +#include "ags/engine/ac/global_overlay.h" +#include "ags/engine/ac/global_palette.h" +#include "ags/engine/ac/global_parser.h" +#include "ags/engine/ac/global_record.h" +#include "ags/engine/ac/global_region.h" +#include "ags/engine/ac/global_room.h" +#include "ags/engine/ac/global_slider.h" +#include "ags/engine/ac/global_screen.h" +#include "ags/engine/ac/global_string.h" +#include "ags/engine/ac/global_textbox.h" +#include "ags/engine/ac/global_timer.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/global_video.h" +#include "ags/engine/ac/global_viewframe.h" +#include "ags/engine/ac/global_viewport.h" +#include "ags/engine/ac/global_walkablearea.h" +#include "ags/engine/ac/global_walkbehind.h" +#include "ags/engine/ac/math.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/parser.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/media/video/video.h" #include "ags/shared/util/string_compat.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" -#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp index 10ae491f76f7..1cf2aaf71e1d 100644 --- a/engines/ags/engine/ac/global_audio.cpp +++ b/engines/ags/engine/ac/global_audio.cpp @@ -21,19 +21,19 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/lipsync.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/lipsync.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/timer.h" #include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp index 3b6124ed1131..77508d1f5e09 100644 --- a/engines/ags/engine/ac/global_button.cpp +++ b/engines/ags/engine/ac/global_button.cpp @@ -20,11 +20,11 @@ * */ -#include "ags/shared/ac/global_button.h" +#include "ags/engine/ac/global_button.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/button.h" +#include "ags/engine/ac/button.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/string.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guibutton.h" diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp index e1ea22755639..99e40fd04367 100644 --- a/engines/ags/engine/ac/global_character.cpp +++ b/engines/ags/engine/ac/global_character.cpp @@ -26,26 +26,26 @@ // //============================================================================= -#include "ags/shared/ac/global_character.h" +#include "ags/engine/ac/global_character.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_overlay.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/object.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/screenoverlay.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_overlay.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/object.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/script/script.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_datetime.cpp b/engines/ags/engine/ac/global_datetime.cpp index 2151e00cc7b7..6e45f02f0ec5 100644 --- a/engines/ags/engine/ac/global_datetime.cpp +++ b/engines/ags/engine/ac/global_datetime.cpp @@ -21,9 +21,10 @@ */ //include -#include "ags/shared/ac/global_datetime.h" -#include "ags/shared/ac/datetime.h" +#include "ags/engine/ac/global_datetime.h" +#include "ags/engine/ac/datetime.h" #include "ags/shared/ac/common.h" +#include "common/system.h" namespace AGS3 { @@ -45,8 +46,7 @@ int sc_GetTime(int whatti) { } int GetRawTime() { - // TODO: we might need to modify script API to support larger time type - return static_cast(time(nullptr)); + return g_system->getMillis(); } } // namespace AGS3 diff --git a/engines/ags/engine/ac/global_datetime.h b/engines/ags/engine/ac/global_datetime.h index 6edcbe230753..4fdfce993a16 100644 --- a/engines/ags/engine/ac/global_datetime.h +++ b/engines/ags/engine/ac/global_datetime.h @@ -25,8 +25,8 @@ namespace AGS3 { -int sc_GetTime(int whatti); -int GetRawTime(); +extern int sc_GetTime(int whatti); +extern int GetRawTime(); } // namespace AGS3 diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp index 14723841504d..e1a4aefecef0 100644 --- a/engines/ags/engine/ac/global_debug.cpp +++ b/engines/ags/engine/ac/global_debug.cpp @@ -20,32 +20,32 @@ * */ -#include "ags/shared/ac/global_debug.h" +#include "ags/engine/ac/global_debug.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/characterinfo.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/global_room.h" -#include "ags/shared/ac/movelist.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/tree_map.h" -#include "ags/shared/ac/walkablearea.h" -#include "ags/shared/gfx/gfxfilter.h" -#include "ags/shared/gui/guidialog.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_room.h" +#include "ags/engine/ac/movelist.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/tree_map.h" +#include "ags/engine/ac/walkablearea.h" +#include "ags/engine/gfx/gfxfilter.h" +#include "ags/engine/gui/guidialog.h" #include "ags/shared/script/cc_options.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/main/main.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/main/main.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/main/graphics_mode.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/main/graphics_mode.h" namespace AGS3 { @@ -120,7 +120,7 @@ void script_debug(int cmdd, int dataa) { const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); - view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); + view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Shared::kBitmap_Transparency); IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); render_graphics(ddb, viewport.Left, viewport.Top); @@ -174,7 +174,7 @@ void script_debug(int cmdd, int dataa) { const Rect &camera = play.GetRoomCamera(camera_index)->GetRect(); Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight()); Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution); - view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Common::kBitmap_Transparency); + view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Shared::kBitmap_Transparency); IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true); render_graphics(ddb, viewport.Left, viewport.Top); diff --git a/engines/ags/engine/ac/global_dialog.cpp b/engines/ags/engine/ac/global_dialog.cpp index d5faa9009750..82f46aa948b0 100644 --- a/engines/ags/engine/ac/global_dialog.cpp +++ b/engines/ags/engine/ac/global_dialog.cpp @@ -20,16 +20,16 @@ * */ -#include "ags/shared/ac/global_dialog.h" +#include "ags/engine/ac/global_dialog.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/dialog.h" +#include "ags/engine/ac/dialog.h" #include "ags/shared/ac/dialogtopic.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp index 18658b6740b3..4cbacc467f03 100644 --- a/engines/ags/engine/ac/global_display.cpp +++ b/engines/ags/engine/ac/global_display.cpp @@ -23,23 +23,23 @@ //include //include #include "ags/shared/ac/common.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/global_screen.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/speech.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/topbarsettings.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_screen.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/speech.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/topbarsettings.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/main/game_run.h" +#include "ags/engine/main/game_run.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp index acee470f8f4f..d513678e1d37 100644 --- a/engines/ags/engine/ac/global_drawingsurface.cpp +++ b/engines/ags/engine/ac/global_drawingsurface.cpp @@ -21,21 +21,21 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_drawingsurface.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_drawingsurface.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/font/fonts.h" #include "ags/shared/game/roomstruct.h" #include "ags/shared/gui/guidefines.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/gfx_def.h" -#include "ags/shared/gfx/gfx_util.h" +#include "ags/engine/gfx/gfx_util.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_dynamicsprite.cpp b/engines/ags/engine/ac/global_dynamicsprite.cpp index e9cb5979f408..59a7eb951d45 100644 --- a/engines/ags/engine/ac/global_dynamicsprite.cpp +++ b/engines/ags/engine/ac/global_dynamicsprite.cpp @@ -20,14 +20,14 @@ * */ -#include "ags/shared/ac/global_dynamicsprite.h" +#include "ags/engine/ac/global_dynamicsprite.h" #include "ags/shared/util/wgt2allg.h" // Allegro RGB, PALETTE -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/dynamicsprite.h" -#include "ags/shared/ac/path_helper.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/dynamicsprite.h" +#include "ags/engine/ac/path_helper.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/ac/runtime_defines.h" //MAX_PATH -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/ac/runtime_defines.h" //MAX_PATH +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index 0f3708b03f97..66fb05648e36 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -21,13 +21,13 @@ */ //include -#include "ags/shared/ac/global_file.h" +#include "ags/engine/ac/global_file.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/file.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/file.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/util/directory.h" #include "ags/shared/util/path.h" #include "ags/shared/util/stream.h" @@ -37,14 +37,14 @@ namespace AGS3 { using namespace AGS::Shared; int32_t FileOpenCMode(const char *fnmm, const char *cmode) { - Common::FileOpenMode open_mode; - Common::FileWorkMode work_mode; + Shared::FileOpenMode open_mode; + Shared::FileWorkMode work_mode; // NOTE: here we ignore the text-mode flag. AGS 2.62 did not let // game devs to open files in text mode. The file reading and // writing logic in AGS makes extra control characters added for // security reasons, and FileWriteRawLine adds CR/LF to the end // of string on its own. - if (!Common::File::GetFileModesFromCMode(cmode, open_mode, work_mode)) { + if (!Shared::File::GetFileModesFromCMode(cmode, open_mode, work_mode)) { return 0; } return FileOpen(fnmm, open_mode, work_mode); @@ -66,7 +66,7 @@ int32_t FindFreeFileSlot() { return useindx; } -int32_t FileOpen(const char *fnmm, Common::FileOpenMode open_mode, Common::FileWorkMode work_mode) { +int32_t FileOpen(const char *fnmm, Shared::FileOpenMode open_mode, Shared::FileWorkMode work_mode) { int32_t useindx = FindFreeFileSlot(); if (useindx < 0) return 0; diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index b13d206904a6..11484566304b 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -24,50 +24,51 @@ #include "ags/shared/core/platform.h" #include "ags/shared/ac/audiocliptype.h" -#include "ags/shared/ac/global_game.h" +#include "ags/shared/util/path.h" +#include "ags/engine/ac/global_game.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/dynamicsprite.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/dynamicsprite.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_hotspot.h" -#include "ags/shared/ac/global_inventoryitem.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/hotspot.h" -#include "ags/shared/ac/keycode.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/object.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/gui/guidialog.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/main/game_start.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/main/graphics_mode.h" -#include "ags/shared/script/script.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_hotspot.h" +#include "ags/engine/ac/global_inventoryitem.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/hotspot.h" +#include "ags/engine/ac/keycode.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/object.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/gui/guidialog.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/game_start.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/script/script.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/core/assetmanager.h" -#include "ags/shared/main/config.h" -#include "ags/shared/main/game_file.h" +#include "ags/engine/main/config.h" +#include "ags/engine/main/game_file.h" #include "ags/shared/util/string_utils.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { @@ -136,7 +137,7 @@ void DeleteSaveSlot(int slnum) { String thisname; for (int i = MAXSAVEGAMES; i > slnum; i--) { thisname = get_save_game_path(i); - if (Common::File::TestReadFile(thisname)) { + if (Shared::File::TestReadFile(thisname)) { // Rename the highest save game to fill in the gap rename(thisname, nametouse); break; @@ -252,7 +253,7 @@ int RunAGSGame(const char *newgame, unsigned int mode, int data) { // need to copy, since the script gets destroyed get_install_dir_path(gamefilenamebuf, newgame); ResPaths.GamePak.Path = gamefilenamebuf; - ResPaths.GamePak.Name = get_filename(gamefilenamebuf); + ResPaths.GamePak.Name = Shared::Path::get_filename(gamefilenamebuf); play.takeover_data = data; load_new_game_restore = -1; @@ -276,7 +277,7 @@ int RunAGSGame(const char *newgame, unsigned int mode, int data) { // Adjust config (NOTE: normally, RunAGSGame would need a redesign to allow separate config etc per each game) usetup.translation = ""; // reset to default, prevent from trying translation file of game A in game B - if (Common::AssetManager::SetDataFile(ResPaths.GamePak.Path) != Common::kAssetNoError) + if (Shared::AssetManager::SetDataFile(ResPaths.GamePak.Path) != Shared::kAssetNoError) quitprintf("!RunAGSGame: unable to load new game file '%s'", ResPaths.GamePak.Path.GetCStr()); show_preload(); @@ -1113,7 +1114,7 @@ int WaitImpl(int skip_type, int nloops) { if (game.options[OPT_BASESCRIPTAPI] < kScriptAPI_v351) { // < 3.5.1 return 1 is skipped by user input, otherwise 0 - return (play.wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK) != 0) ? 1 : 0; + return (play.wait_skipped_by & (SKIP_KEYPRESS | SKIP_MOUSECLICK)) != 0 ? 1 : 0; } // >= 3.5.1 return positive keycode, negative mouse button code, or 0 as time-out switch (play.wait_skipped_by) { diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp index fcd7223b2718..6ffeacfdd686 100644 --- a/engines/ags/engine/ac/global_gui.cpp +++ b/engines/ags/engine/ac/global_gui.cpp @@ -21,19 +21,19 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/gui.h" -#include "ags/shared/ac/guicontrol.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/gui.h" +#include "ags/engine/ac/guicontrol.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/font/fonts.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/script/runtimescriptvalue.h" #include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp index b6021c650ab1..6998213c1e1b 100644 --- a/engines/ags/engine/ac/global_hotspot.cpp +++ b/engines/ags/engine/ac/global_hotspot.cpp @@ -20,22 +20,22 @@ * */ -#include "ags/shared/ac/global_hotspot.h" +#include "ags/engine/ac/global_hotspot.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/ac/characterinfo.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/hotspot.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/hotspot.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/script/script.h" +#include "ags/engine/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp index 7d2f7885d821..4bd15c1eee63 100644 --- a/engines/ags/engine/ac/global_inventoryitem.cpp +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -22,17 +22,17 @@ #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_inventoryitem.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/inventoryitem.h" -#include "ags/shared/ac/invwindow.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_inventoryitem.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/inventoryitem.h" +#include "ags/engine/ac/invwindow.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/string.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guiinv.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_invwindow.cpp b/engines/ags/engine/ac/global_invwindow.cpp index cb3ef9ef1e15..ac2a68a8ea18 100644 --- a/engines/ags/engine/ac/global_invwindow.cpp +++ b/engines/ags/engine/ac/global_invwindow.cpp @@ -20,12 +20,12 @@ * */ -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_invwindow.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/properties.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_invwindow.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/properties.h" #include "ags/shared/gui/guiinv.h" -#include "ags/shared/script/executingscript.h" +#include "ags/engine/script/executingscript.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp index 8c1b404bd475..a60e6f23d634 100644 --- a/engines/ags/engine/ac/global_label.cpp +++ b/engines/ags/engine/ac/global_label.cpp @@ -20,11 +20,11 @@ * */ -#include "ags/shared/ac/global_label.h" +#include "ags/engine/ac/global_label.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/label.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/label.h" +#include "ags/engine/ac/string.h" #include "ags/shared/gui/guimain.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_listbox.cpp b/engines/ags/engine/ac/global_listbox.cpp index ef607a52f731..be748096bce5 100644 --- a/engines/ags/engine/ac/global_listbox.cpp +++ b/engines/ags/engine/ac/global_listbox.cpp @@ -20,10 +20,10 @@ * */ -#include "ags/shared/ac/global_listbox.h" +#include "ags/engine/ac/global_listbox.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/listbox.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/listbox.h" +#include "ags/engine/ac/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_mouse.cpp b/engines/ags/engine/ac/global_mouse.cpp index 6310da0da325..7c9471b50111 100644 --- a/engines/ags/engine/ac/global_mouse.cpp +++ b/engines/ags/engine/ac/global_mouse.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/shared/ac/global_mouse.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/global_mouse.h" +#include "ags/engine/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp index 3be568fa04e0..a2b552eba3df 100644 --- a/engines/ags/engine/ac/global_object.cpp +++ b/engines/ags/engine/ac/global_object.cpp @@ -20,28 +20,28 @@ * */ -#include "ags/shared/ac/global_object.h" +#include "ags/engine/ac/global_object.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/object.h" +#include "ags/engine/ac/object.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/object.h" -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/roomobject.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/viewframe.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/script/script.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/object.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/script/script.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" #include "ags/shared/gfx/gfx_def.h" diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp index 3f1c82ec105f..9fe39315a179 100644 --- a/engines/ags/engine/ac/global_overlay.cpp +++ b/engines/ags/engine/ac/global_overlay.cpp @@ -20,19 +20,19 @@ * */ -#include "ags/shared/ac/global_overlay.h" +#include "ags/engine/ac/global_overlay.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/screenoverlay.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/string.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/ac/system.h" +#include "ags/engine/ac/system.h" #include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_palette.cpp b/engines/ags/engine/ac/global_palette.cpp index 0d8bc049fb6e..17961ad2f574 100644 --- a/engines/ags/engine/ac/global_palette.cpp +++ b/engines/ags/engine/ac/global_palette.cpp @@ -21,10 +21,10 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_palette.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_palette.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_parser.cpp b/engines/ags/engine/ac/global_parser.cpp index 68635efc5893..677661989812 100644 --- a/engines/ags/engine/ac/global_parser.cpp +++ b/engines/ags/engine/ac/global_parser.cpp @@ -20,11 +20,10 @@ * */ -//include //strcpy() -#include "ags/shared/ac/global_parser.h" +#include "ags/engine/ac/global_parser.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_record.cpp b/engines/ags/engine/ac/global_record.cpp index 6e6e0c92f808..40c14ecc9e18 100644 --- a/engines/ags/engine/ac/global_record.cpp +++ b/engines/ags/engine/ac/global_record.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/global_record.h" +#include "ags/engine/ac/global_record.h" #include "ags/shared/ac/common.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp index e1307d3941dd..5ef84c06a955 100644 --- a/engines/ags/engine/ac/global_region.cpp +++ b/engines/ags/engine/ac/global_region.cpp @@ -20,16 +20,16 @@ * */ -#include "ags/shared/ac/global_region.h" +#include "ags/engine/ac/global_region.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/game_version.h" -#include "ags/shared/ac/region.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/region.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/script/script.h" +#include "ags/engine/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp index ff23f92d91a0..43ec2bae8d9d 100644 --- a/engines/ags/engine/ac/global_room.cpp +++ b/engines/ags/engine/ac/global_room.cpp @@ -20,23 +20,23 @@ * */ -#include "ags/shared/ac/global_room.h" +#include "ags/engine/ac/global_room.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/character.h" +#include "ags/engine/ac/character.h" #include "ags/shared/ac/characterinfo.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/movelist.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/script/script.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/movelist.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/script/script.h" #include "ags/shared/util/math.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp index 801402420365..52a0c628add5 100644 --- a/engines/ags/engine/ac/global_screen.cpp +++ b/engines/ags/engine/ac/global_screen.cpp @@ -21,18 +21,18 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/gamesetup.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_screen.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/screen.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_screen.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/screen.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp index f91e88660da6..36845f9440e5 100644 --- a/engines/ags/engine/ac/global_slider.cpp +++ b/engines/ags/engine/ac/global_slider.cpp @@ -20,10 +20,10 @@ * */ -#include "ags/shared/ac/global_slider.h" +#include "ags/engine/ac/global_slider.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/slider.h" +#include "ags/engine/ac/slider.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guislider.h" diff --git a/engines/ags/engine/ac/global_string.cpp b/engines/ags/engine/ac/global_string.cpp index d64a4fae9135..38f74bdb938c 100644 --- a/engines/ags/engine/ac/global_string.cpp +++ b/engines/ags/engine/ac/global_string.cpp @@ -22,10 +22,10 @@ //include #include "ags/shared/ac/common.h" -#include "ags/shared/ac/global_string.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/global_string.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/string.h" #include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp index aa78c0632cf7..34a4d1d04a5e 100644 --- a/engines/ags/engine/ac/global_textbox.cpp +++ b/engines/ags/engine/ac/global_textbox.cpp @@ -20,11 +20,11 @@ * */ -#include "ags/shared/ac/global_textbox.h" +#include "ags/engine/ac/global_textbox.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/textbox.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/textbox.h" #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guitextbox.h" diff --git a/engines/ags/engine/ac/global_timer.cpp b/engines/ags/engine/ac/global_timer.cpp index d65d2befdf23..e06a37eb111c 100644 --- a/engines/ags/engine/ac/global_timer.cpp +++ b/engines/ags/engine/ac/global_timer.cpp @@ -20,10 +20,10 @@ * */ -#include "ags/shared/ac/global_timer.h" -#include "ags/shared/ac/runtime_defines.h" +#include "ags/engine/ac/global_timer.h" +#include "ags/engine/ac/runtime_defines.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/gamestate.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index 822ee3a73509..07c277175233 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -22,14 +22,14 @@ //include #include "ags/shared/ac/common.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/tree_map.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/tree_map.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/util/memory.h" #include "ags/shared/core/types.h" diff --git a/engines/ags/engine/ac/global_video.cpp b/engines/ags/engine/ac/global_video.cpp index a676765874c7..e8183a3ec9a1 100644 --- a/engines/ags/engine/ac/global_video.cpp +++ b/engines/ags/engine/ac/global_video.cpp @@ -21,16 +21,16 @@ */ #include "ags/lib/allegro.h" -#include "ags/shared/ac/gamesetup.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_video.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/media/video/video.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_video.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/media/video/video.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/util/string_compat.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_viewframe.cpp b/engines/ags/engine/ac/global_viewframe.cpp index e57afccfb718..8ede6164272d 100644 --- a/engines/ags/engine/ac/global_viewframe.cpp +++ b/engines/ags/engine/ac/global_viewframe.cpp @@ -20,12 +20,12 @@ * */ -#include "ags/shared/ac/global_viewframe.h" +#include "ags/engine/ac/global_viewframe.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/view.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_viewport.cpp b/engines/ags/engine/ac/global_viewport.cpp index a76a4443fcd1..776272d2fdd0 100644 --- a/engines/ags/engine/ac/global_viewport.cpp +++ b/engines/ags/engine/ac/global_viewport.cpp @@ -20,9 +20,9 @@ * */ -#include "ags/shared/ac/global_viewport.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/global_viewport.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/debugging/debug_log.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp index 8bf3df756aac..3a62a1627dec 100644 --- a/engines/ags/engine/ac/global_walkablearea.cpp +++ b/engines/ags/engine/ac/global_walkablearea.cpp @@ -20,12 +20,12 @@ * */ -#include "ags/shared/ac/global_walkablearea.h" +#include "ags/engine/ac/global_walkablearea.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/common_defines.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/walkablearea.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/walkablearea.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/game/roomstruct.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/global_walkbehind.cpp b/engines/ags/engine/ac/global_walkbehind.cpp index 315c3ac4d955..ae1f7cc67f2d 100644 --- a/engines/ags/engine/ac/global_walkbehind.cpp +++ b/engines/ags/engine/ac/global_walkbehind.cpp @@ -20,13 +20,13 @@ * */ -#include "ags/shared/ac/global_walkbehind.h" +#include "ags/engine/ac/global_walkbehind.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/common_defines.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/walkbehind.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/walkbehind.h" +#include "ags/engine/debugging/debug_log.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp index fa00a425ff94..d52d7cbc829e 100644 --- a/engines/ags/engine/ac/gui.cpp +++ b/engines/ags/engine/ac/gui.cpp @@ -21,40 +21,44 @@ */ //include -#include "ags/shared/ac/gui.h" +#include "ags/engine/ac/gui.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/ac/global_inventoryitem.h" -#include "ags/shared/ac/global_screen.h" -#include "ags/shared/ac/guicontrol.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/ac/global_inventoryitem.h" +#include "ags/engine/ac/global_screen.h" +#include "ags/engine/ac/guicontrol.h" #include "ags/shared/ac/interfacebutton.h" -#include "ags/shared/ac/invwindow.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/dynobj/cc_guiobject.h" -#include "ags/shared/ac/dynobj/scriptgui.h" -#include "ags/shared/script/cc_instance.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/device/mousew32.h" -#include "ags/shared/gfx/gfxfilter.h" +#include "ags/engine/ac/invwindow.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/dynobj/cc_guiobject.h" +#include "ags/engine/ac/dynobj/scriptgui.h" +#include "ags/engine/script/cc_instance.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/device/mousew32.h" +#include "ags/engine/gfx/gfxfilter.h" #include "ags/shared/gui/guibutton.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/script/script.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/script/script.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/ac/dynobj/cc_gui.h" -#include "ags/shared/ac/dynobj/cc_guiobject.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_gui.h" +#include "ags/engine/ac/dynobj/cc_guiobject.h" +#include "ags/engine/script/runtimescriptvalue.h" #include "ags/shared/util/string_compat.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" + namespace AGS3 { using namespace AGS::Shared; @@ -341,7 +345,7 @@ void process_interface_click(int ifce, int btn, int mbut) { } int btype = guis[ifce].GetControlType(btn); - int rtype = kGUIAction_None, rdata; + int rtype = kGUIAction_None, rdata = 0; if (btype == kGUIButton) { GUIButton *gbuto = (GUIButton *)guis[ifce].GetControl(btn); rtype = gbuto->ClickAction[kMouseLeft]; @@ -685,10 +689,6 @@ void gui_on_mouse_down(const int guin, const int mbut) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // void GUI_Centre(ScriptGUI *sgui) RuntimeScriptValue Sc_GUI_Centre(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_VOID(ScriptGUI, GUI_Centre); diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp index 90907e77485a..eb089b3de407 100644 --- a/engines/ags/engine/ac/guicontrol.cpp +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -21,9 +21,9 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/guicontrol.h" -#include "ags/shared/ac/global_gui.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/guicontrol.h" +#include "ags/engine/ac/global_gui.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/gui/guibutton.h" #include "ags/shared/gui/guiinv.h" #include "ags/shared/gui/guilabel.h" @@ -31,9 +31,13 @@ #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guislider.h" #include "ags/shared/gui/guitextbox.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_gui.h" -#include "ags/shared/ac/dynobj/cc_guiobject.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_gui.h" +#include "ags/engine/ac/dynobj/cc_guiobject.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -237,10 +241,6 @@ void GUIControl_BringToFront(GUIObject *guio) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // void (GUIObject *guio) RuntimeScriptValue Sc_GUIControl_BringToFront(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_VOID(GUIObject, GUIControl_BringToFront); diff --git a/engines/ags/engine/ac/guiinv.cpp b/engines/ags/engine/ac/guiinv.cpp index 18a08c034c7d..b7a2767e45b5 100644 --- a/engines/ags/engine/ac/guiinv.cpp +++ b/engines/ags/engine/ac/guiinv.cpp @@ -22,10 +22,10 @@ #include "ags/shared/gui/guiinv.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/characterextras.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/characterextras.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp index ddaee7ce852a..09e4948d3303 100644 --- a/engines/ags/engine/ac/hotspot.cpp +++ b/engines/ags/engine/ac/hotspot.cpp @@ -20,18 +20,23 @@ * */ -#include "ags/shared/ac/dynobj/cc_hotspot.h" -#include "ags/shared/ac/hotspot.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_hotspot.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/dynobj/cc_hotspot.h" +#include "ags/engine/ac/hotspot.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_hotspot.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/string.h" #include "ags/shared/game/roomstruct.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/script/runtimescriptvalue.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -128,11 +133,6 @@ int get_hotspot_at(int xpp, int ypp) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; RuntimeScriptValue Sc_GetHotspotAtRoom(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/interfaceelement.cpp b/engines/ags/engine/ac/interfaceelement.cpp index ea8f5d483c60..8f3dc5b529be 100644 --- a/engines/ags/engine/ac/interfaceelement.cpp +++ b/engines/ags/engine/ac/interfaceelement.cpp @@ -20,8 +20,8 @@ * */ -//include #include "ags/shared/ac/interfaceelement.h" +#include "common/str.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp index c04585e3af19..a9b45c23e66d 100644 --- a/engines/ags/engine/ac/inventoryitem.cpp +++ b/engines/ags/engine/ac/inventoryitem.cpp @@ -20,18 +20,23 @@ * */ -#include "ags/shared/ac/inventoryitem.h" +#include "ags/engine/ac/inventoryitem.h" #include "ags/shared/ac/characterinfo.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_inventoryitem.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_inventory.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_inventoryitem.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_inventory.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -126,11 +131,6 @@ void set_inv_item_cursorpic(int invItemId, int piccy) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // ScriptInvItem *(int xx, int yy) diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp index 87b10255e704..208666888dbd 100644 --- a/engines/ags/engine/ac/invwindow.cpp +++ b/engines/ags/engine/ac/invwindow.cpp @@ -20,30 +20,34 @@ * */ -#include "ags/shared/ac/invwindow.h" +#include "ags/engine/ac/invwindow.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/characterextras.h" +#include "ags/engine/ac/characterextras.h" #include "ags/shared/ac/characterinfo.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/gamestate.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/global_room.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/gui/guidialog.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/global_room.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/gui/guidialog.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_character.h" -#include "ags/shared/ac/dynobj/cc_inventory.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_character.h" +#include "ags/engine/ac/dynobj/cc_inventory.h" #include "ags/shared/util/math.h" -#include "ags/shared/media/audio/audio_system.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/ac/timer.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -333,7 +337,7 @@ void InventoryScreen::Draw(Bitmap *ds) { if (top_item > 0) wputblock(ds, windowwid - ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(2), arrowblock, 1); if (top_item + num_visible_items < numitems) - arrowblock->FlipBlt(arrowblock, windowwid - ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID, Common::kBitmap_VFlip); + arrowblock->FlipBlt(arrowblock, windowwid - ARROWBUTTONWID, buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID, Shared::kBitmap_VFlip); delete arrowblock; } @@ -362,11 +366,11 @@ bool InventoryScreen::Run() { refresh_gui_screen(); // NOTE: this is because old code was working with full game screen - const int mousex = ::mousex - windowxp; - const int mousey = ::mousey - windowyp; + const int mouseX = AGS3::mousex - windowxp; + const int mouseY = AGS3::mousey - windowyp; - int isonitem = ((mousey - bartop) / highest) * ICONSPERLINE + (mousex - barxp) / widest; - if (mousey <= bartop) isonitem = -1; + int isonitem = ((mouseY - bartop) / highest) * ICONSPERLINE + (mouseX - barxp) / widest; + if (mouseY <= bartop) isonitem = -1; else if (isonitem >= 0) isonitem += top_item; if ((isonitem < 0) | (isonitem >= numitems) | (isonitem >= top_item + num_visible_items)) isonitem = -1; @@ -377,9 +381,9 @@ bool InventoryScreen::Run() { } if (mclick == LEFT) { - if ((mousey < 0) | (mousey > windowhit) | (mousex < 0) | (mousex > windowwid)) + if ((mouseY < 0) | (mouseY > windowhit) | (mouseX < 0) | (mouseX > windowwid)) return true; // continue inventory screen loop - if (mousey < buttonyp) { + if (mouseY < buttonyp) { int clickedon = isonitem; if (clickedon < 0) return true; // continue inventory screen loop evblocknum = dii[clickedon].num; @@ -430,8 +434,8 @@ bool InventoryScreen::Run() { // break; return true; // continue inventory screen loop } else { - if (mousex >= windowwid - ARROWBUTTONWID) { - if (mousey < buttonyp + get_fixed_pixel_size(2) + ARROWBUTTONWID) { + if (mouseX >= windowwid - ARROWBUTTONWID) { + if (mouseY < buttonyp + get_fixed_pixel_size(2) + ARROWBUTTONWID) { if (top_item > 0) { top_item -= ICONSPERLINE; //ags_domouse(DOMOUSE_DISABLE); @@ -439,7 +443,7 @@ bool InventoryScreen::Run() { break_code = Redraw(); return break_code == 0; } - } else if ((mousey < buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID * 2) && (top_item + num_visible_items < numitems)) { + } else if ((mouseY < buttonyp + get_fixed_pixel_size(4) + ARROWBUTTONWID * 2) && (top_item + num_visible_items < numitems)) { top_item += ICONSPERLINE; //ags_domouse(DOMOUSE_DISABLE); @@ -449,7 +453,7 @@ bool InventoryScreen::Run() { return true; // continue inventory screen loop } - int buton = mousex - 2; + int buton = mouseX - 2; if (buton < 0) return true; // continue inventory screen loop buton /= BUTTONWID; if (buton >= 3) return true; // continue inventory screen loop @@ -526,10 +530,6 @@ int invscreen() { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // void (GUIInvWindow *guii) RuntimeScriptValue Sc_InvWindow_ScrollDown(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_VOID(GUIInvWindow, InvWindow_ScrollDown); diff --git a/engines/ags/engine/ac/keycode.cpp b/engines/ags/engine/ac/keycode.cpp index c3a790e9cfca..b2c1521dff74 100644 --- a/engines/ags/engine/ac/keycode.cpp +++ b/engines/ags/engine/ac/keycode.cpp @@ -20,8 +20,7 @@ * */ -#include "ags/shared/ac/keycode.h" - +#include "ags/engine/ac/keycode.h" #include "ags/lib/allegro.h" namespace AGS3 { @@ -31,10 +30,10 @@ int GetKeyForKeyPressCb(int keycode) { return (keycode >= 'a' && keycode <= 'z') ? keycode - 32 : keycode; } -int PlatformKeyFromAgsKey(int key) { +int PlatformKeyFromAgsKey(int key_) { int platformKey = -1; - switch (key) { + switch (key_) { // ctrl-[A-Z] keys are numbered 1-26 for A-Z case eAGSKeyCodeCtrlA: platformKey = 1; diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp index de5c06fa8458..29249cef0925 100644 --- a/engines/ags/engine/ac/label.cpp +++ b/engines/ags/engine/ac/label.cpp @@ -21,11 +21,16 @@ */ //include -#include "ags/shared/ac/label.h" +#include "ags/engine/ac/label.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/string.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -92,11 +97,6 @@ void Label_SetFont(GUILabel *guil, int fontnum) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // void (GUILabel *labl, char *buffer) diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index 4753e933c3a5..081cc25e27d0 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -20,17 +20,25 @@ * */ -//include -#include "ags/shared/ac/listbox.h" +#include "ags/std/set.h" +#include "ags/engine/ac/listbox.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/game.h" +#include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/ac/string.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/debugging/debug_log.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" +#include "common/fs.h" +#include "common/savefile.h" +#include "ags/ags.h" namespace AGS3 { @@ -63,13 +71,12 @@ void ListBox_Clear(GUIListBox *listbox) { } void FillDirList(std::set &files, const String &path) { - al_ffblk dfb; - int dun = al_findfirst(path, &dfb, FA_SEARCH); - while (!dun) { - files.insert(dfb.name); - dun = al_findnext(&dfb); - } - al_findclose(&dfb); + Common::FSNode folder(path); + Common::FSList fsList; + folder.getChildren(fsList, Common::FSNode::kListAll); + + for (uint idx = 0; idx < fsList.size(); ++idx) + files.insert(fsList[idx].getName()); } void ListBox_FillDirList(GUIListBox *listbox, const char *filemask) { @@ -101,34 +108,22 @@ int ListBox_FillSaveGameList(GUIListBox *listbox) { listbox->Clear(); int numsaves = 0; - int bufix = 0; - al_ffblk ffb; long filedates[MAXSAVEGAMES]; - char buff[200]; - String svg_dir = get_save_game_directory(); - String searchPath = String::FromFormat("%s""agssave.*", svg_dir.GetCStr()); + SaveStateList saveList = ::AGS::g_vm->listSaves(); - int don = al_findfirst(searchPath, &ffb, FA_SEARCH); - while (!don) { - bufix = 0; + for (uint idx = 0; idx < saveList.size(); ++idx) { if (numsaves >= MAXSAVEGAMES) break; - // only list games .000 to .099 (to allow higher slots for other perposes) - if (strstr(ffb.name, ".0") == nullptr) { - don = al_findnext(&ffb); - continue; - } - const char *numberExtension = strstr(ffb.name, ".0") + 1; - int saveGameSlot = atoi(numberExtension); - GetSaveSlotDescription(saveGameSlot, buff); - listbox->AddItem(buff); + + int saveGameSlot = saveList[idx].getSaveSlot(); + Common::String desc = saveList[idx].getDescription(); + + listbox->AddItem(desc); listbox->SavedGameIndex[numsaves] = saveGameSlot; - filedates[numsaves] = (long int)ffb.time; + filedates[numsaves] = 0; numsaves++; - don = al_findnext(&ffb); } - al_findclose(&ffb); int nn; for (nn = 0; nn < numsaves - 1; nn++) { @@ -384,11 +379,6 @@ GUIListBox *is_valid_listbox(int guin, int objn) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // int (GUIListBox *lbb, const char *text) diff --git a/engines/ags/engine/ac/math.cpp b/engines/ags/engine/ac/math.cpp index 431e6bddb4f8..2709b632cd6f 100644 --- a/engines/ags/engine/ac/math.cpp +++ b/engines/ags/engine/ac/math.cpp @@ -21,10 +21,15 @@ */ //include -#include "ags/shared/ac/math.h" +#include "ags/engine/ac/math.h" #include "ags/shared/ac/common.h" // quit #include "ags/shared/util/math.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/ags.h" + namespace AGS3 { int FloatToInt(float value, int roundDirection) { @@ -137,8 +142,8 @@ float Math_Sqrt(float value) { int __Rand(int upto) { upto++; if (upto < 1) - quit("!Random: invalid parameter passed -- must be at least 0."); - return rand() % upto; + quit("!Random: invalid parameter passed -- must be at least 1."); + return ::AGS::g_vm->getRandomNumber(upto - 1); } @@ -148,10 +153,6 @@ int __Rand(int upto) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // float (float value) RuntimeScriptValue Sc_Math_ArcCos(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_FLOAT_PFLOAT(Math_ArcCos); diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp index fbfa84fa8919..c6780c73d39e 100644 --- a/engines/ags/engine/ac/mouse.cpp +++ b/engines/ags/engine/ac/mouse.cpp @@ -20,27 +20,32 @@ * */ -#include "ags/shared/ac/mouse.h" +#include "ags/engine/ac/mouse.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/characterinfo.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/dynobj/scriptmouse.h" -#include "ags/shared/ac/dynobj/scriptsystem.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/dynobj/scriptmouse.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_mouse.h" -#include "ags/shared/ac/global_plugin.h" -#include "ags/shared/ac/global_screen.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/viewframe.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_mouse.h" +#include "ags/engine/ac/global_plugin.h" +#include "ags/engine/ac/global_screen.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/gui/guibutton.h" #include "ags/shared/gui/guimain.h" -#include "ags/shared/device/mousew32.h" +#include "ags/engine/device/mousew32.h" #include "ags/shared/ac/spritecache.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/gfx/gfxfilter.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/gfx/gfxfilter.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/global_game.h" namespace AGS3 { @@ -455,11 +460,6 @@ int find_previous_enabled_cursor(int startwith) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/global_game.h" - // void (int curs, int newslot) RuntimeScriptValue Sc_ChangeCursorGraphic(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_VOID_PINT2(ChangeCursorGraphic); diff --git a/engines/ags/engine/ac/movelist.cpp b/engines/ags/engine/ac/movelist.cpp index 5b6154fc1551..4393bfafbb2f 100644 --- a/engines/ags/engine/ac/movelist.cpp +++ b/engines/ags/engine/ac/movelist.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/movelist.h" +#include "ags/engine/ac/movelist.h" #include "ags/shared/ac/common.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp index bc982e325f3c..58b52be1a14c 100644 --- a/engines/ags/engine/ac/object.cpp +++ b/engines/ags/engine/ac/object.cpp @@ -20,31 +20,36 @@ * */ -#include "ags/shared/ac/object.h" +#include "ags/engine/ac/object.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/global_object.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/global_object.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/walkablearea.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/main/game_run.h" -#include "ags/shared/ac/route_finder.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/ac/walkablearea.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/main/game_run.h" +#include "ags/engine/ac/route_finder.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" #include "ags/shared/gfx/gfx_def.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_object.h" -#include "ags/shared/ac/movelist.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_object.h" +#include "ags/engine/ac/movelist.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -558,11 +563,6 @@ int check_click_on_object(int roomx, int roomy, int mood) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // void (ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction) diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp index 5edd4a255433..269bb5dc74e8 100644 --- a/engines/ags/engine/ac/overlay.cpp +++ b/engines/ags/engine/ac/overlay.cpp @@ -20,23 +20,27 @@ * */ -#include "ags/shared/ac/overlay.h" +#include "ags/engine/ac/overlay.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/view.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/characterextras.h" -#include "ags/shared/ac/display.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/characterextras.h" +#include "ags/engine/ac/display.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_overlay.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/screenoverlay.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_overlay.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/screenoverlay.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/script/runtimescriptvalue.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -202,7 +206,7 @@ size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic if (type == OVER_TEXTMSG) is_text_overlay++; if (type == OVER_CUSTOM) { // find an unused custom ID; TODO: find a better approach! - for (int id = OVER_CUSTOM + 1; id < screenover.size() + OVER_CUSTOM + 1; ++id) { + for (int id = OVER_CUSTOM + 1; id < (int)screenover.size() + OVER_CUSTOM + 1; ++id) { if (find_overlay_of_type(id) == -1) { type = id; break; @@ -287,10 +291,6 @@ void recreate_overlay_ddbs() { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // ScriptOverlay* (int x, int y, int slot, int transparent) RuntimeScriptValue Sc_Overlay_CreateGraphical(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_OBJAUTO_PINT4(ScriptOverlay, Overlay_CreateGraphical); diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp index bddd826e706d..43a3ddc63f21 100644 --- a/engines/ags/engine/ac/parser.cpp +++ b/engines/ags/engine/ac/parser.cpp @@ -24,14 +24,19 @@ //include #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/parser.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/parser.h" +#include "ags/engine/ac/string.h" #include "ags/shared/ac/wordsdictionary.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_compat.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" + namespace AGS3 { using namespace AGS::Shared; @@ -89,7 +94,7 @@ int find_word_in_dictionary(const char *lookfor) { } int is_valid_word_char(char theChar) { - if ((isalnum((unsigned char)theChar)) || (theChar == '\'') || (theChar == '-')) { + if ((Common::isAlnum((unsigned char)theChar)) || (theChar == '\'') || (theChar == '-')) { return 1; } return 0; @@ -239,7 +244,7 @@ int parse_sentence(const char *src_text, int *numwords, short *wordarray, short const char *textStart = &text[1]; - while ((text[0] == ',') || (isalnum((unsigned char)text[0]) != 0)) + while ((text[0] == ',') || (Common::isAlnum((unsigned char)text[0]) != 0)) text++; continueSearching = 0; @@ -301,11 +306,6 @@ int parse_sentence(const char *src_text, int *numwords, short *wordarray, short // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // int (const char *wordToFind) diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp index 9e1f22154655..04988a487e53 100644 --- a/engines/ags/engine/ac/properties.cpp +++ b/engines/ags/engine/ac/properties.cpp @@ -22,10 +22,10 @@ #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/dynobj/scriptstring.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/script/runtimescriptvalue.h" #include "ags/shared/util/string_utils.h" namespace AGS3 { @@ -42,7 +42,7 @@ bool get_property_desc(PropertyDesc &desc, const char *property, PropertyType wa if (sch_it == game.propSchema.end()) quit("!GetProperty: no such property found in schema. Make sure you are using the property's name, and not its description, when calling this command."); - desc = sch_it->second; + desc = sch_it->_value; if (want_type == kPropertyString && desc.Type != kPropertyString) quit("!GetTextProperty: need to use GetProperty for a non-text property"); else if (want_type != kPropertyString && desc.Type == kPropertyString) @@ -55,10 +55,10 @@ String get_property_value(const StringIMap &st_prop, const StringIMap &rt_prop, // if no matching entry was found, use default schema value StringIMap::const_iterator it = rt_prop.find(property); if (it != rt_prop.end()) - return it->second; + return it->_value; it = st_prop.find(property); if (it != st_prop.end()) - return it->second; + return it->_value; return def_val; } diff --git a/engines/ags/engine/ac/properties.h b/engines/ags/engine/ac/properties.h index ac40ab5b2aca..b9873d3c8dd4 100644 --- a/engines/ags/engine/ac/properties.h +++ b/engines/ags/engine/ac/properties.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_PROPERTIES_H #define AGS_ENGINE_AC_PROPERTIES_H -#include "ags/engine/game/customproperties.h" +#include "ags/shared/game/customproperties.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp index 0716dd7d5ce6..22d628828e28 100644 --- a/engines/ags/engine/ac/region.cpp +++ b/engines/ags/engine/ac/region.cpp @@ -20,17 +20,21 @@ * */ -#include "ags/shared/ac/region.h" +#include "ags/engine/ac/region.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_region.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/dynobj/cc_region.h" -#include "ags/shared/ac/dynobj/scriptdrawingsurface.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_region.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/dynobj/cc_region.h" +#include "ags/engine/ac/dynobj/scriptdrawingsurface.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/script/runtimescriptvalue.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -136,10 +140,6 @@ void generate_light_table() { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // ScriptRegion *(int xx, int yy) RuntimeScriptValue Sc_GetRegionAtRoom(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtRoom); diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp index 4409f1b855e4..1c09739ddd8a 100644 --- a/engines/ags/engine/ac/richgamemedia.cpp +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/ac/richgamemedia.h" +#include "ags/engine/ac/richgamemedia.h" #include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index 12ce1ec851f5..1cf81d7c5d5e 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -25,57 +25,62 @@ #include "ags/shared/core/platform.h" #include "ags/shared/util/string_utils.h" //strlwr() #include "ags/shared/ac/common.h" -#include "ags/shared/ac/charactercache.h" -#include "ags/shared/ac/characterextras.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/event.h" -#include "ags/shared/ac/game.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/charactercache.h" +#include "ags/engine/ac/characterextras.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/event.h" +#include "ags/engine/ac/game.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_character.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_object.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/movelist.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/objectcache.h" -#include "ags/shared/ac/overlay.h" -#include "ags/shared/ac/properties.h" -#include "ags/shared/ac/region.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomobject.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/screen.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/walkablearea.h" -#include "ags/shared/ac/walkbehind.h" -#include "ags/shared/ac/dynobj/scriptobject.h" -#include "ags/shared/ac/dynobj/scripthotspot.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_character.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_object.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/movelist.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/objectcache.h" +#include "ags/engine/ac/overlay.h" +#include "ags/engine/ac/properties.h" +#include "ags/engine/ac/region.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/screen.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/walkablearea.h" +#include "ags/engine/ac/walkbehind.h" +#include "ags/engine/ac/dynobj/scriptobject.h" +#include "ags/engine/ac/dynobj/scripthotspot.h" #include "ags/shared/gui/guidefines.h" -#include "ags/shared/script/cc_instance.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/debug/out.h" +#include "ags/engine/script/cc_instance.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/game/room_version.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/script/cc_error.h" -#include "ags/shared/script/script.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/script/script.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/util/stream.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/core/assetmanager.h" -#include "ags/shared/ac/dynobj/all_dynamicclasses.h" +#include "ags/engine/ac/dynobj/all_dynamicclasses.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/gfxfilter.h" +#include "ags/engine/gfx/gfxfilter.h" #include "ags/shared/util/math.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" + +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -462,8 +467,8 @@ void load_new_room(int newnum, CharacterInfo *forchar) { if (newnum == 0) { // support both room0.crm and intro.crm // 2.70: Renamed intro.crm to room0.crm, to stop it causing confusion - if ((loaded_game_file_version < kGameVersion_270 && Common::AssetManager::DoesAssetExist("intro.crm")) || - (loaded_game_file_version >= kGameVersion_270 && !Common::AssetManager::DoesAssetExist(room_filename))) { + if ((loaded_game_file_version < kGameVersion_270 && Shared::AssetManager::DoesAssetExist("intro.crm")) || + (loaded_game_file_version >= kGameVersion_270 && !Shared::AssetManager::DoesAssetExist(room_filename))) { room_filename = "intro.crm"; } } @@ -1102,11 +1107,6 @@ void convert_move_path_to_room_resolution(MoveList *ml) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // ScriptDrawingSurface* (int backgroundNumber) diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp index 06ae948f4cb2..806420119793 100644 --- a/engines/ags/engine/ac/roomobject.cpp +++ b/engines/ags/engine/ac/roomobject.cpp @@ -20,14 +20,14 @@ * */ -#include "ags/shared/ac/roomobject.h" +#include "ags/engine/ac/roomobject.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/viewframe.h" -#include "ags/shared/main/update.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/main/update.h" #include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp index d523a8d006c0..d24aff1fa8d4 100644 --- a/engines/ags/engine/ac/roomstatus.cpp +++ b/engines/ags/engine/ac/roomstatus.cpp @@ -24,9 +24,9 @@ //include // free #include "ags/shared/ac/common.h" #include "ags/shared/ac/game_version.h" -#include "ags/shared/ac/roomstatus.h" +#include "ags/engine/ac/roomstatus.h" #include "ags/shared/game/customproperties.h" -#include "ags/shared/game/savegame_components.h" +#include "ags/engine/game/savegame_components.h" #include "ags/shared/util/alignedstream.h" namespace AGS3 { @@ -103,7 +103,7 @@ void RoomStatus::ReadFromFile_v321(Stream *in) { } void RoomStatus::ReadRoomObjects_Aligned(Shared::Stream *in) { - AlignedStream align_s(in, Common::kAligned_Read); + AlignedStream align_s(in, Shared::kAligned_Read); for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) { obj[i].ReadFromFile(&align_s); align_s.Reset(); diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index 2daaff186f36..b5722d3b1039 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -20,12 +20,12 @@ * */ -#include "ags/shared/ac/route_finder.h" +#include "ags/engine/ac/route_finder.h" -#include "ags/shared/ac/route_finder_impl.h" -#include "ags/shared/ac/route_finder_impl_legacy.h" +#include "ags/engine/ac/route_finder_impl.h" +#include "ags/engine/ac/route_finder_impl_legacy.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp index b62bd5cfb8e7..13ea1c667af9 100644 --- a/engines/ags/engine/ac/route_finder_impl.cpp +++ b/engines/ags/engine/ac/route_finder_impl.cpp @@ -26,18 +26,18 @@ // //============================================================================= -#include "ags/shared/ac/route_finder_impl.h" +#include "ags/engine/ac/route_finder_impl.h" //include //include #include "ags/shared/ac/common.h" // quit() -#include "ags/shared/ac/movelist.h" // MoveList +#include "ags/engine/ac/movelist.h" // MoveList #include "ags/shared/ac/common_defines.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" -#include "ags/shared/route_finder_jps.inl" +#include "ags/engine/ac/route_finder_jps.inl" namespace AGS3 { diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp index 88c30f5fd803..067900745e8c 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp +++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp @@ -27,7 +27,7 @@ // //============================================================================= -#include "ags/shared/ac/route_finder_impl_legacy.h" +#include "ags/engine/ac/route_finder_impl_legacy.h" //include //include @@ -35,9 +35,9 @@ #include "ags/shared/ac/common.h" // quit() #include "ags/shared/ac/common_defines.h" #include "ags/shared/game/roomstruct.h" -#include "ags/shared/ac/movelist.h" // MoveList +#include "ags/engine/ac/movelist.h" // MoveList #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" namespace AGS3 { @@ -123,7 +123,7 @@ void get_lastcpos(int &lastcx_, int &lastcy_) { int find_nearest_walkable_area(Bitmap *tempw, int fromX, int fromY, int toX, int toY, int destX, int destY, int granularity) { assert(tempw != nullptr); - int ex, ey, nearest = 99999, thisis, nearx, neary; + int ex, ey, nearest = 99999, thisis, nearx = 0, neary = 0; if (fromX < 0) fromX = 0; if (fromY < 0) fromY = 0; if (toX >= tempw->GetWidth()) toX = tempw->GetWidth() - 1; diff --git a/engines/ags/engine/ac/route_finder_jps.inl b/engines/ags/engine/ac/route_finder_jps.inl index 5172e59538e9..0f21f05c75a4 100644 --- a/engines/ags/engine/ac/route_finder_jps.inl +++ b/engines/ags/engine/ac/route_finder_jps.inl @@ -1,15 +1,25 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// +/* 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. + * + */ + //============================================================================= // // jump point search grid navigation with navpoint refinement @@ -17,28 +27,29 @@ // //============================================================================= -//include +#include "ags/std/queue.h" #include "ags/std/vector.h" -//include -//include +#include "ags/std/algorithm.h" +#include "ags/std/functional.h" +#include "ags/std/xutility.h" //include //include //include +namespace AGS3 { + // TODO: this could be cleaned up/simplified ... // further optimizations possible: // - forward refinement should use binary search -class Navigation -{ +class Navigation { public: Navigation(); void Resize(int width, int height); - enum NavResult - { + enum NavResult { // unreachable NAV_UNREACHABLE, // straight line exists @@ -57,15 +68,16 @@ public: bool TraceLine(int srcx, int srcy, int targx, int targy, int &lastValidX, int &lastValidY) const; bool TraceLine(int srcx, int srcy, int targx, int targy, std::vector *rpath = nullptr) const; - inline void SetMapRow(int y, const unsigned char *row) {map[y] = row;} + inline void SetMapRow(int y, const unsigned char *row) { + map[y] = row; + } inline static int PackSquare(int x, int y); inline static void UnpackSquare(int sq, int &x, int &y); private: // priority queue entry - struct Entry - { + struct Entry { float cost; int index; @@ -73,17 +85,14 @@ private: inline Entry(float ncost, int nindex) : cost(ncost) - , index(nindex) - { + , index(nindex) { } - inline bool operator <(const Entry &b) const - { + inline bool operator <(const Entry &b) const { return cost < b.cost; } - inline bool operator >(const Entry &b) const - { + inline bool operator >(const Entry &b) const { return cost > b.cost; } }; @@ -95,8 +104,7 @@ private: typedef unsigned short tFrameId; typedef int tPrev; - struct NodeInfo - { + struct NodeInfo { // quantized min distance from origin unsigned short dist; // frame id (counter to detect new search) @@ -107,8 +115,7 @@ private: inline NodeInfo() : dist(0) , frameId(0) - , prev(-1) - { + , prev(-1) { } }; @@ -118,7 +125,7 @@ private: std::vector mapNodes; tFrameId frameId; - std::priority_queue, std::greater > pq; + std::priority_queue, Common::Greater > pq; // temporary buffers: mutable std::vector fpath; @@ -151,24 +158,20 @@ private: // neighbor reachable (nodiag only) bool Reachable(int x0, int y0, int x1, int y1) const; - static inline int sign(int n) - { + static inline int sign(int n) { return n < 0 ? -1 : (n > 0 ? 1 : 0); } - static inline int iabs(int n) - { + static inline int iabs(int n) { return n < 0 ? -n : n; } - static inline int iclamp(int v, int min, int max) - { + static inline int iclamp(int v, int min, int max) { return v < min ? min : (v > max ? max : v); } - static inline int ClosestDist(int dx, int dy) - { - return dx*dx + dy*dy; + static inline int ClosestDist(int dx, int dy) { + return dx * dx + dy * dy; // Manhattan? //return iabs(dx) + iabs(dy); } @@ -189,63 +192,53 @@ Navigation::Navigation() , closest(0) // no diagonal route - this should correspond to what AGS does , nodiag(true) - , navLock(false) -{ + , navLock(false) { } -void Navigation::Resize(int width, int height) -{ +void Navigation::Resize(int width, int height) { mapWidth = width; mapHeight = height; - int size = mapWidth*mapHeight; + int size = mapWidth * mapHeight; map.resize(mapHeight); mapNodes.resize(size); } -void Navigation::IncFrameId() -{ - if (++frameId == 0) - { - for (int i=0; i<(int)mapNodes.size(); i++) +void Navigation::IncFrameId() { + if (++frameId == 0) { + for (int i = 0; i < (int)mapNodes.size(); i++) mapNodes[i].frameId = 0; frameId = 1; } } -inline int Navigation::PackSquare(int x, int y) -{ +inline int Navigation::PackSquare(int x, int y) { return (y << 16) + x; } -inline void Navigation::UnpackSquare(int sq, int &x, int &y) -{ +inline void Navigation::UnpackSquare(int sq, int &x, int &y) { y = sq >> 16; - x = sq & ((1 << 16)-1); + x = sq & ((1 << 16) - 1); } -inline bool Navigation::Outside(int x, int y) const -{ +inline bool Navigation::Outside(int x, int y) const { return (unsigned)x >= (unsigned)mapWidth || (unsigned)y >= (unsigned)mapHeight; } -inline bool Navigation::Walkable(int x, int y) const -{ +inline bool Navigation::Walkable(int x, int y) const { // invert condition because of AGS return map[y][x] != 0; } -bool Navigation::Passable(int x, int y) const -{ +bool Navigation::Passable(int x, int y) const { return !Outside(x, y) && Walkable(x, y); } -bool Navigation::Reachable(int x0, int y0, int x1, int y1) const -{ +bool Navigation::Reachable(int x0, int y0, int x1, int y1) const { assert(nodiag); return Passable(x1, y1) && @@ -254,26 +247,22 @@ bool Navigation::Reachable(int x0, int y0, int x1, int y1) const // A* using jump point search (JPS) // reference: http://users.cecs.anu.edu.au/~dharabor/data/papers/harabor-grastien-aaai11.pdf -void Navigation::AddPruned(int *buf, int &bcount, int x, int y) const -{ +void Navigation::AddPruned(int *buf, int &bcount, int x, int y) const { assert(buf && bcount < 8); if (Passable(x, y)) buf[bcount++] = PackSquare(x, y); } -bool Navigation::HasForcedNeighbor(int x, int y, int dx, int dy) const -{ - if (!dy) - { - return (!Passable(x, y-1) && Passable(x+dx, y-1)) || - (!Passable(x, y+1) && Passable(x+dx, y+1)); +bool Navigation::HasForcedNeighbor(int x, int y, int dx, int dy) const { + if (!dy) { + return (!Passable(x, y - 1) && Passable(x + dx, y - 1)) || + (!Passable(x, y + 1) && Passable(x + dx, y + 1)); } - if (!dx) - { - return (!Passable(x-1, y) && Passable(x-1, y+dy)) || - (!Passable(x+1, y) && Passable(x+1, y+dy)); + if (!dx) { + return (!Passable(x - 1, y) && Passable(x - 1, y + dy)) || + (!Passable(x + 1, y) && Passable(x + 1, y + dy)); } return @@ -281,12 +270,10 @@ bool Navigation::HasForcedNeighbor(int x, int y, int dx, int dy) const (!Passable(x, y - dy) && Passable(x + dx, y - dy)); } -int Navigation::FindOrthoJump(int x, int y, int dx, int dy, int ex, int ey) -{ +int Navigation::FindOrthoJump(int x, int y, int dx, int dy, int ex, int ey) { assert((!dx || !dy) && (dx || dy)); - for (;;) - { + for (;;) { x += dx; y += dy; @@ -297,8 +284,7 @@ int Navigation::FindOrthoJump(int x, int y, int dx, int dy, int ex, int ey) int edy = y - ey; int edist = ClosestDist(edx, edy); - if (edist < closest) - { + if (edist < closest) { closest = edist; cnode = PackSquare(x, y); } @@ -310,12 +296,11 @@ int Navigation::FindOrthoJump(int x, int y, int dx, int dy, int ex, int ey) return -1; } -int Navigation::FindJump(int x, int y, int dx, int dy, int ex, int ey) -{ +int Navigation::FindJump(int x, int y, int dx, int dy, int ex, int ey) { if (!(dx && dy)) return FindOrthoJump(x, y, dx, dy, ex, ey); - if (nodiag && !Reachable(x, y, x+dx, y+dy)) + if (nodiag && !Reachable(x, y, x + dx, y + dy)) return -1; x += dx; @@ -328,8 +313,7 @@ int Navigation::FindJump(int x, int y, int dx, int dy, int ex, int ey) int edy = y - ey; int edist = ClosestDist(edx, edy); - if (edist < closest) - { + if (edist < closest) { closest = edist; cnode = PackSquare(x, y); } @@ -337,8 +321,7 @@ int Navigation::FindJump(int x, int y, int dx, int dy, int ex, int ey) if ((x == ex && y == ey) || HasForcedNeighbor(x, y, dx, dy)) return PackSquare(x, y); - if (dx && dy) - { + if (dx && dy) { if (FindOrthoJump(x, y, dx, 0, ex, ey) || FindOrthoJump(x, y, 0, dy, ex, ey)) return PackSquare(x, y); @@ -347,12 +330,10 @@ int Navigation::FindJump(int x, int y, int dx, int dy, int ex, int ey) return nodiag ? -1 : FindJump(x, y, dx, dy, ex, ey); } -Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std::vector &opath) -{ +Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std::vector &opath) { IncFrameId(); - if (!Passable(sx, sy)) - { + if (!Passable(sx, sy)) { opath.clear(); return NAV_UNREACHABLE; } @@ -361,7 +342,7 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: if (!TraceLine(sx, sy, ex, ey, &opath)) return NAV_STRAIGHT; - NodeInfo &ni = mapNodes[sy*mapWidth+sx]; + NodeInfo &ni = mapNodes[sy * mapWidth + sx]; ni.dist = 0; ni.frameId = frameId; ni.prev = -1; @@ -371,12 +352,11 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: // no clear for priority queue, like, really?! while (!pq.empty()) - pq.pop(); + pq.pop(); pq.push(Entry(0.0, cnode)); - while (!pq.empty()) - { + while (!pq.empty()) { Entry e = pq.top(); pq.pop(); @@ -387,19 +367,17 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: int dy = y - ey; int edist = ClosestDist(dx, dy); - if (edist < closest) - { + if (edist < closest) { closest = edist; cnode = e.index; } - if (x == ex && y == ey) - { + if (x == ex && y == ey) { // done break; } - const NodeInfo &node = mapNodes[y*mapWidth+x]; + const NodeInfo &node = mapNodes[y * mapWidth + x]; float dist = node.dist * DIST_SCALE_UNPACK; @@ -408,15 +386,12 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: int prev = node.prev; - if (prev < 0) - { - for (int ny = y-1; ny <= y+1; ny++) - { + if (prev < 0) { + for (int ny = y - 1; ny <= y + 1; ny++) { if ((unsigned)ny >= (unsigned)mapHeight) continue; - for (int nx = x-1; nx <= x+1; nx++) - { + for (int nx = x - 1; nx <= x + 1; nx++) { if (nx == x && ny == y) continue; @@ -432,93 +407,82 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: pneig[ncount++] = PackSquare(nx, ny); } } - } - else - { + } else { // filter int px, py; UnpackSquare(prev, px, py); - int dx = sign(x - px); - int dy = sign(y - py); - assert(dx || dy); + int dX = sign(x - px); + int dY = sign(y - py); + assert(dX || dY); - if (!dy) - { - AddPruned(pneig, ncount, x+dx, y); + if (!dY) { + AddPruned(pneig, ncount, x + dX, y); // add corners - if (!nodiag || Passable(x+dx, y)) - { - if (!Passable(x, y+1)) - AddPruned(pneig, ncount, x+dx, y+1); + if (!nodiag || Passable(x + dX, y)) { + if (!Passable(x, y + 1)) + AddPruned(pneig, ncount, x + dX, y + 1); - if (!Passable(x, y-1)) - AddPruned(pneig, ncount, x+dx, y-1); + if (!Passable(x, y - 1)) + AddPruned(pneig, ncount, x + dX, y - 1); } - } - else if (!dx) - { + } else if (!dX) { // same as above but transposed - AddPruned(pneig, ncount, x, y+dy); + AddPruned(pneig, ncount, x, y + dY); // add corners - if (!nodiag || Passable(x, y+dy)) - { - if (!Passable(x+1, y)) - AddPruned(pneig, ncount, x+1, y+dy); + if (!nodiag || Passable(x, y + dY)) { + if (!Passable(x + 1, y)) + AddPruned(pneig, ncount, x + 1, y + dY); - if (!Passable(x-1, y)) - AddPruned(pneig, ncount, x-1, y+dy); + if (!Passable(x - 1, y)) + AddPruned(pneig, ncount, x - 1, y + dY); } - } - else - { + } else { // diagonal case - AddPruned(pneig, ncount, x, y+dy); - AddPruned(pneig, ncount, x+dx, y); + AddPruned(pneig, ncount, x, y + dY); + AddPruned(pneig, ncount, x + dX, y); - if (!nodiag || Reachable(x, y, x+dx, y+dy)) - AddPruned(pneig, ncount, x+dx, y+dy); + if (!nodiag || Reachable(x, y, x + dX, y + dY)) + AddPruned(pneig, ncount, x + dX, y + dY); - if (!Passable(x - dx, y) && - (nodiag || Reachable(x, y, x-dx, y+dy))) - AddPruned(pneig, ncount, x-dx, y+dy); + if (!Passable(x - dX, y) && + (nodiag || Reachable(x, y, x - dX, y + dY))) + AddPruned(pneig, ncount, x - dX, y + dY); - if (!Passable(x, y-dy) && - (nodiag || Reachable(x, y, x+dx, y-dy))) - AddPruned(pneig, ncount, x+dx, y-dy); + if (!Passable(x, y - dY) && + (nodiag || Reachable(x, y, x + dX, y - dY))) + AddPruned(pneig, ncount, x + dX, y - dY); } } // sort by heuristics Entry sort[8]; - for (int ni = 0; ni < ncount; ni++) - { + for (int idx = 0; idx < ncount; idx++) { int nx, ny; - UnpackSquare(pneig[ni], nx, ny); + UnpackSquare(pneig[idx], nx, ny); float edx = (float)(nx - ex); float edy = (float)(ny - ey); - sort[ni].cost = sqrt(edx*edx + edy*edy); - sort[ni].index = pneig[ni]; + sort[idx].cost = sqrt(edx * edx + edy * edy); + sort[idx].index = pneig[idx]; } - std::sort(sort, sort+ncount); + std::sort(sort, sort + ncount, Common::Less()); int succ[8]; int nsucc = 0; - for (int ni=0; ni 65535.0f) continue; - node.dist = (unsigned short)(ecost + 0.5f); - node.frameId = frameId; - node.prev = PackSquare(x, y); + nodeInfo.dist = (unsigned short)(ecost + 0.5f); + nodeInfo.frameId = frameId; + nodeInfo.prev = PackSquare(x, y); pq.push(Entry(ecost + heur, PackSquare(nx, ny))); } } @@ -573,8 +535,7 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: int nex, ney; UnpackSquare(cnode, nex, ney); - if ((nex != sx || ney != sy) && (nex != ex || ney != ey)) - { + if ((nex != sx || ney != sy) && (nex != ex || ney != ey)) { // target not directly reachable => move closer to target TraceLine(nex, ney, ex, ey, &opath); UnpackSquare(opath.back(), nex, ney); @@ -585,8 +546,7 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: // infinite recursion should never happen but... better safe than sorry assert(!navLock); - if (!navLock) - { + if (!navLock) { // and re-route opath.clear(); @@ -601,17 +561,15 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: int best = 0x7fffffff; int bestSize = (int)opath.size(); - for (int i=0; i<(int)opath.size(); i++) - { + for (int i = 0; i < (int)opath.size(); i++) { int x, y; UnpackSquare(opath[i], x, y); - int dx = x-ex, dy = y-ey; + int dx = x - ex, dy = y - ey; int cost = ClosestDist(dx, dy); - if (cost < best) - { + if (cost < best) { best = cost; - bestSize = i+1; + bestSize = i + 1; } } @@ -621,8 +579,7 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: } if (ex < 0 || ex >= mapWidth || ey < 0 || ey >= mapHeight || - mapNodes[ey*mapWidth+ex].frameId != frameId) - { + mapNodes[ey * mapWidth + ex].frameId != frameId) { // path not found return NAV_UNREACHABLE; } @@ -632,9 +589,8 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: // add end opath.push_back(PackSquare(tx, ty)); - for (;;) - { - int prev = mapNodes[ty*mapWidth+tx].prev; + for (;;) { + int prev = mapNodes[ty * mapWidth + tx].prev; if (prev < 0) break; @@ -645,8 +601,7 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: int dx = sign(px - tx); int dy = sign(py - ty); - while (tx != px || ty != py) - { + while (tx != px || ty != py) { tx += dx; ty += dy; opath.push_back(PackSquare(tx, ty)); @@ -658,16 +613,13 @@ Navigation::NavResult Navigation::Navigate(int sx, int sy, int ex, int ey, std:: } Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey, - std::vector &opath, std::vector &ncpath) -{ + std::vector &opath, std::vector &ncpath) { ncpath.clear(); NavResult res = Navigate(sx, sy, ex, ey, opath); - if (res != NAV_PATH) - { - if (res == NAV_STRAIGHT) - { + if (res != NAV_PATH) { + if (res == NAV_STRAIGHT) { ncpath.push_back(opath[0]); ncpath.push_back(opath.back()); } @@ -692,16 +644,14 @@ Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey rayPath.reserve(opath.size()); orayPath.reserve(opath.size()); - for (int i=1; i<(int)opath.size(); i++) - { + for (int i = 1; i < (int)opath.size(); i++) { // trying to optimize path int tx, ty; UnpackSquare(opath[i], tx, ty); - bool last = i == (int)opath.size()-1; + bool last = i == (int)opath.size() - 1; - if (!TraceLine(fx, fy, tx, ty, &rayPath)) - { + if (!TraceLine(fx, fy, tx, ty, &rayPath)) { assert(rayPath.back() == opath[i]); std::swap(rayPath, orayPath); @@ -710,17 +660,15 @@ Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey } // copy orayPath - for (int j=1; j<(int)orayPath.size(); j++) + for (int j = 1; j < (int)orayPath.size(); j++) fpath.push_back(orayPath[j]); - if (!orayPath.empty()) - { + if (!orayPath.empty()) { assert(ncpath.back() == orayPath[0]); ncpath.push_back(orayPath.back()); - ncpathIndex.push_back((int)fpath.size()-1); + ncpathIndex.push_back((int)fpath.size() - 1); - if (!last) - { + if (!last) { UnpackSquare(orayPath.back(), fx, fy); orayPath.clear(); i--; @@ -731,10 +679,9 @@ Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey if (fpath.back() != opath[i]) fpath.push_back(opath[i]); - if (ncpath.back() != opath[i]) - { + if (ncpath.back() != opath[i]) { ncpath.push_back(opath[i]); - ncpathIndex.push_back((int)fpath.size()-1); + ncpathIndex.push_back((int)fpath.size() - 1); } fx = tx; @@ -744,11 +691,10 @@ Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey std::swap(opath, fpath); // validate cpath - for (int i=0; i<(int)ncpath.size()-1; i++) - { + for (int i = 0; i < (int)ncpath.size() - 1; i++) { int tx, ty; UnpackSquare(ncpath[i], fx, fy); - UnpackSquare(ncpath[i+1], tx, ty); + UnpackSquare(ncpath[i + 1], tx, ty); assert(!TraceLine(fx, fy, tx, ty, &rayPath)); } @@ -761,19 +707,17 @@ Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey bool adjusted = false; - for (int i=(int)ncpath.size()-2; i>0; i--) - { + for (int i = (int)ncpath.size() - 2; i > 0; i--) { int px, py; int nx, ny; - int pidx = ncpathIndex[i-1]; + int pidx = ncpathIndex[i - 1]; int idx = ncpathIndex[i]; - UnpackSquare(ncpath[i-1], px, py); - UnpackSquare(ncpath[i+1], nx, ny); + UnpackSquare(ncpath[i - 1], px, py); + UnpackSquare(ncpath[i + 1], nx, ny); - for (int j=idx-1; j >= pidx; j--) - { + for (int j = idx - 1; j >= pidx; j--) { int x, y; UnpackSquare(opath[j], x, y); @@ -790,12 +734,11 @@ Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey adjusted = true; } - if (ncpath[i] == ncpath[i-1]) - { + if (ncpath[i] == ncpath[i - 1]) { // if we get here, we need to remove ncpath[i] // because we reached the previous node - ncpath.erase(ncpath.begin()+i); - ncpathIndex.erase(ncpathIndex.begin()+i); + ncpath.erase(ncpath.begin() + i); + ncpathIndex.erase(ncpathIndex.begin() + i); adjusted = true; } } @@ -808,25 +751,23 @@ Navigation::NavResult Navigation::NavigateRefined(int sx, int sy, int ex, int ey opath.clear(); opath.push_back(ncpath[0]); - for (int i=1; i<(int)ncpath.size(); i++) - { - int fx, fy; + for (int i = 1; i < (int)ncpath.size(); i++) { +// int fx, fy; int tx, ty; - UnpackSquare(ncpath[i-1], fx, fy); + UnpackSquare(ncpath[i - 1], fx, fy); UnpackSquare(ncpath[i], tx, ty); TraceLine(fx, fy, tx, ty, &rayPath); - for (int j=1; j<(int)rayPath.size(); j++) + for (int j = 1; j < (int)rayPath.size(); j++) opath.push_back(rayPath[j]); } return NAV_PATH; } -bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, int &lastValidX, int &lastValidY) const -{ +bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, int &lastValidX, int &lastValidY) const { lastValidX = srcx; lastValidY = srcy; @@ -838,8 +779,7 @@ bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, int &lastVa return res; } -bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, std::vector *rpath) const -{ +bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, std::vector *rpath) const { if (rpath) rpath->clear(); @@ -852,8 +792,7 @@ bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, std::vector int dx = x1 - x0; int dy = y1 - y0; - if (!dx && !dy) - { + if (!dx && !dy) { if (!Passable(srcx, srcy)) return true; @@ -865,14 +804,11 @@ bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, std::vector int xinc, yinc; - if (iabs(dx) >= iabs(dy)) - { + if (iabs(dx) >= iabs(dy)) { // step along x xinc = sign(dx) * 65536; yinc = (int)((double)dy * 65536 / iabs(dx)); - } - else - { + } else { // step along y yinc = sign(dy) * 65536; xinc = (int)((double)dx * 65536 / iabs(dy)); @@ -885,8 +821,7 @@ bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, std::vector int ex = x1 >> 16; int ey = y1 >> 16; - while (x != ex || y != ey) - { + while (x != ex || y != ey) { if (!Passable(x, y)) return true; @@ -919,3 +854,5 @@ bool Navigation::TraceLine(int srcx, int srcy, int targx, int targy, std::vector return false; } + +} // namespace AGS3 diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index 15ddac6f35fa..9306c4ac88c4 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -21,20 +21,20 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/global_screen.h" -#include "ags/shared/ac/screen.h" -#include "ags/shared/ac/dynobj/scriptviewport.h" -#include "ags/shared/ac/dynobj/scriptuserobject.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/global_screen.h" +#include "ags/engine/ac/screen.h" +#include "ags/engine/ac/dynobj/scriptviewport.h" +#include "ags/engine/ac/dynobj/scriptuserobject.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/gfx/graphicsdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/screenoverlay.cpp b/engines/ags/engine/ac/screenoverlay.cpp index fadd6e6c2e07..c4c133e67fde 100644 --- a/engines/ags/engine/ac/screenoverlay.cpp +++ b/engines/ags/engine/ac/screenoverlay.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/screenoverlay.h" +#include "ags/engine/ac/screenoverlay.h" #include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index 148832bda5b4..e67e3a1ed346 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -27,14 +27,14 @@ //============================================================================= #include "ags/shared/ac/common.h" // quit -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/dynobj/cc_dynamicarray.h" -#include "ags/shared/ac/dynobj/cc_dynamicobject.h" -#include "ags/shared/ac/dynobj/scriptdict.h" -#include "ags/shared/ac/dynobj/scriptset.h" -#include "ags/shared/ac/dynobj/scriptstring.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/dynobj/cc_dynamicarray.h" +#include "ags/engine/ac/dynobj/cc_dynamicobject.h" +#include "ags/engine/ac/dynobj/scriptdict.h" +#include "ags/engine/ac/dynobj/scriptset.h" +#include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" #include "ags/shared/util/bbop.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/slider.cpp b/engines/ags/engine/ac/slider.cpp index 89589b80e3c8..005570b2e300 100644 --- a/engines/ags/engine/ac/slider.cpp +++ b/engines/ags/engine/ac/slider.cpp @@ -20,9 +20,13 @@ * */ -#include "ags/shared/ac/slider.h" +#include "ags/engine/ac/slider.h" #include "ags/shared/ac/common.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" + namespace AGS3 { // *** SLIDER FUNCTIONS @@ -118,10 +122,6 @@ void Slider_SetHandleOffset(GUISlider *guisl, int newOffset) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // int (GUISlider *guisl) RuntimeScriptValue Sc_Slider_GetBackgroundGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_INT(GUISlider, Slider_GetBackgroundGraphic); diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp index 08b2584ebc3a..8164c123622d 100644 --- a/engines/ags/engine/ac/speech.cpp +++ b/engines/ags/engine/ac/speech.cpp @@ -21,9 +21,17 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/speech.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/speech.h" +#include "ags/engine/debugging/debug_log.h" + +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_audio.h" +#include "ags/engine/ac/global_display.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -78,14 +86,6 @@ SkipSpeechStyle internal_skip_speech_to_user(int internal_val) { // //============================================================================= -#include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_audio.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - extern GameSetupStruct game; extern GameState play; diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp index 4220305ce9e3..e8e1f2eeeebc 100644 --- a/engines/ags/engine/ac/sprite.cpp +++ b/engines/ags/engine/ac/sprite.cpp @@ -21,16 +21,16 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/sprite.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/plugin/plugin_engine.h" +#include "ags/engine/ac/sprite.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/plugin/plugin_engine.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/gfx/graphicsdriver.h" namespace AGS3 { @@ -158,7 +158,7 @@ void initialize_sprite(int ee) { quit("Not enough memory to load sprite graphics"); tmpdbl->Acquire(); curspr->Acquire(); - tmpdbl->StretchBlt(curspr, RectWH(0, 0, tmpdbl->GetWidth(), tmpdbl->GetHeight()), Common::kBitmap_Transparency); + tmpdbl->StretchBlt(curspr, RectWH(0, 0, tmpdbl->GetWidth(), tmpdbl->GetHeight()), Shared::kBitmap_Transparency); curspr->Release(); tmpdbl->Release(); delete curspr; diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index 60a963a50ad2..283be7111fa3 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -30,10 +30,15 @@ #include "ags/shared/ac/runtime_defines.h" #include "ags/shared/ac/dynobj/scriptstring.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debugging/debug_log.h" #include "ags/shared/script/runtimescriptvalue.h" #include "ags/shared/util/string_compat.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/math.h" + namespace AGS3 { extern GameSetupStruct game; @@ -298,11 +303,6 @@ void my_strncpy(char *dest, const char *src, int len) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/math.h" - // int (const char *thisString) RuntimeScriptValue Sc_String_IsNullOrEmpty(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_INT_POBJ(String_IsNullOrEmpty, const char); diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index 467e80a13d4b..7142cb7792ab 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -23,13 +23,13 @@ #include "ags/shared/core/platform.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/keycode.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/device/mousew32.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/ac/timer.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/keycode.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/device/mousew32.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/timer.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index 873b11ee987d..6c52eb2b5194 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -29,8 +29,8 @@ #include "ags/shared/ac/string.h" #include "ags/shared/ac/system.h" #include "ags/shared/ac/dynobj/scriptsystem.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/main/engine.h" #include "ags/shared/main/main.h" #include "ags/shared/gfx/graphicsdriver.h" @@ -41,6 +41,11 @@ #include "ags/shared/media/audio/audio_system.h" #include "ags/shared/util/string_compat.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" + namespace AGS3 { using namespace AGS::Shared; @@ -227,11 +232,6 @@ void System_SetRenderAtScreenResolution(int enable) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // int () diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp index f4dfa5809b0e..9a926db00ce7 100644 --- a/engines/ags/engine/ac/textbox.cpp +++ b/engines/ags/engine/ac/textbox.cpp @@ -26,6 +26,11 @@ #include "ags/shared/ac/gamesetupstruct.h" #include "ags/shared/ac/string.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" +#include "ags/shared/ac/dynobj/scriptstring.h" + namespace AGS3 { extern GameSetupStruct game; @@ -90,11 +95,6 @@ void TextBox_SetShowBorder(GUITextBox *guit, bool on) { // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" - extern ScriptString myScriptStringImpl; // void (GUITextBox *texbox, char *buffer) diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp index 3c2892b5830d..64c065b308d7 100644 --- a/engines/ags/engine/ac/translation.cpp +++ b/engines/ags/engine/ac/translation.cpp @@ -31,7 +31,7 @@ #include "ags/shared/ac/translation.h" #include "ags/shared/ac/tree_map.h" #include "ags/shared/ac/wordsdictionary.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/util/misc.h" #include "ags/shared/util/stream.h" #include "ags/shared/core/assetmanager.h" diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp index 41ab83b02753..5461f4b1f93a 100644 --- a/engines/ags/engine/ac/viewframe.cpp +++ b/engines/ags/engine/ac/viewframe.cpp @@ -22,7 +22,7 @@ #include "ags/shared/ac/gamesetupstruct.h" #include "ags/shared/ac/viewframe.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debugging/debug_log.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" #include "ags/shared/script/runtimescriptvalue.h" @@ -31,6 +31,10 @@ #include "ags/shared/ac/game_version.h" #include "ags/shared/media/audio/audio_system.h" +#include "ags/shared/debugging/out.h" +#include "ags/shared/script/script_api.h" +#include "ags/shared/script/script_runtime.h" + } // namespace AGS3 using AGS::Shared::Bitmap; @@ -159,16 +163,16 @@ void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha Bitmap *src = vf_bmp; if (vframe->flags & VFLG_FLIPSPRITE) { src = new Bitmap(vf_bmp->GetWidth(), vf_bmp->GetHeight(), vf_bmp->GetColorDepth()); - src->FlipBlt(vf_bmp, 0, 0, Common::kBitmap_HFlip); + src->FlipBlt(vf_bmp, 0, 0, Shared::kBitmap_HFlip); } draw_sprite_support_alpha(ds, true, x, y, src, (game.SpriteInfos[vframe->pic].Flags & SPF_ALPHACHANNEL) != 0); if (src != vf_bmp) delete src; } else { if (vframe->flags & VFLG_FLIPSPRITE) - ds->FlipBlt(spriteset[vframe->pic], x, y, Common::kBitmap_HFlip); + ds->FlipBlt(spriteset[vframe->pic], x, y, Shared::kBitmap_HFlip); else - ds->Blit(spriteset[vframe->pic], x, y, Common::kBitmap_Transparency); + ds->Blit(spriteset[vframe->pic], x, y, Shared::kBitmap_Transparency); } } @@ -178,10 +182,6 @@ void DrawViewFrame(Bitmap *ds, const ViewFrame *vframe, int x, int y, bool alpha // //============================================================================= -#include "ags/shared/debug/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" - // int (ScriptViewFrame *svf) RuntimeScriptValue Sc_ViewFrame_GetFlipped(void *self, const RuntimeScriptValue *params, int32_t param_count) { API_OBJCALL_INT(ScriptViewFrame, ViewFrame_GetFlipped); diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp index e145c78d9661..5d0c2672d89e 100644 --- a/engines/ags/engine/ac/viewport_script.cpp +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -31,7 +31,7 @@ #include "ags/shared/ac/dynobj/scriptuserobject.h" #include "ags/shared/ac/draw.h" #include "ags/shared/ac/gamestate.h" -#include "ags/shared/debug/debug_log.h" +#include "ags/shared/debugging/debug_log.h" #include "ags/shared/script/script_api.h" #include "ags/shared/script/script_runtime.h" diff --git a/engines/ags/engine/debugging/dummyagsdebugger.h b/engines/ags/engine/debugging/dummyagsdebugger.h index cc1158755a1a..efbdb3a29567 100644 --- a/engines/ags/engine/debugging/dummyagsdebugger.h +++ b/engines/ags/engine/debugging/dummyagsdebugger.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_DEBUGGING_DUMMYAGSDEBUGGER_H #define AGS_ENGINE_DEBUGGING_DUMMYAGSDEBUGGER_H -#include "ags/shared/debug/debugger.h" +#include "ags/engine/debugging/debugger.h" namespace AGS3 { diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp index a70fb04f8603..de0b2b72ea1f 100644 --- a/engines/ags/engine/main/main.cpp +++ b/engines/ags/engine/main/main.cpp @@ -38,9 +38,9 @@ #include "ags/shared/ac/gamesetup.h" #include "ags/shared/ac/gamestate.h" #include "ags/shared/core/def_version.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/debugger.h" +#include "ags/shared/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/main/config.h" #include "ags/shared/main/engine.h" #include "ags/shared/main/mainheader.h" diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index f7db003f40ff..414db622ae21 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -36,8 +36,8 @@ #include "ags/shared/ac/gamesetup.h" #include "ags/shared/ac/path_helper.h" #include "ags/shared/media/audio/sound.h" -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/debugger.h" +#include "ags/shared/debugging/debug_log.h" +#include "ags/shared/debugging/debugger.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/file.h" #include "ags/shared/ac/global_audio.h" diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index 0ca7dde4a532..dcf4136ac357 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -29,7 +29,7 @@ #include "ags/shared/util/mutex.h" #include "ags/shared/util/mutex_lock.h" #include "ags/shared/util/string.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" namespace AGS3 { diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index 930a5bc79759..9372858dfb63 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -29,8 +29,8 @@ #define AGS_FLI_FROM_PACK_FILE ((ALLEGRO_DATE >= 20190303) || \ AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_MACOS) -#include "ags/shared/debug/debug_log.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/ac/asset_helper.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/draw.h" diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 4c44c0afcff3..f0279b66023e 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -100,10 +100,10 @@ size_t BuildXDGPath(char *destPath, size_t destSize) { // No evironment variable, so we fall back to home dir in /etc/passwd struct passwd *p = getpwuid(getuid()); l = snprintf(destPath, destSize, "%s/.local", p->pw_dir); - if (mkdir(destPath, 0755) != 0 && errno != EEXIST) + if (mkdir(destPath, 0755) != 0 && errnum != EEXIST) return 0; l += snprintf(destPath + l, destSize - l, "/share"); - if (mkdir(destPath, 0755) != 0 && errno != EEXIST) + if (mkdir(destPath, 0755) != 0 && errnum != EEXIST) return 0; } return l; diff --git a/engines/ags/engine/platform/windows/acplwin.cpp b/engines/ags/engine/platform/windows/acplwin.cpp index 9f300fb1e16e..eda5ca2d983f 100644 --- a/engines/ags/engine/platform/windows/acplwin.cpp +++ b/engines/ags/engine/platform/windows/acplwin.cpp @@ -36,7 +36,7 @@ #include "ags/shared/ac/global_display.h" #include "ags/shared/ac/runtime_defines.h" #include "ags/shared/ac/string.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" #include "ags/shared/main/engine.h" @@ -618,7 +618,7 @@ void DetermineAppOutputDirectory() { if (win32SavedGamesDirectory[0]) { win32OutputDirectory = win32SavedGamesDirectory; win32OutputDirectory.Append("\\.ags"); - log_to_saves_dir = mkdir(win32OutputDirectory) == 0 || errno == EEXIST; + log_to_saves_dir = mkdir(win32OutputDirectory) == 0 || errnum == EEXIST; } if (!log_to_saves_dir) { diff --git a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h index 6e7b86d43fa3..879f95faa29c 100644 --- a/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h +++ b/engines/ags/engine/platform/windows/debugging/namedpipesagsdebugger.h @@ -25,7 +25,7 @@ //include //include -#include "ags/shared/debug/agseditordebugger.h" +#include "ags/shared/debugging/agseditordebugger.h" namespace AGS3 { diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp index 3a28afb3ba26..269c5b050770 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.cpp @@ -35,8 +35,8 @@ #include "ags/lib/allegro.h" //include #include "ags/shared/ac/timer.h" -#include "ags/shared/debug/assert.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/assert.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/gfx/ali3dexception.h" #include "ags/shared/gfx/gfxfilter_d3d.h" #include "ags/shared/gfx/gfxfilter_aad3d.h" diff --git a/engines/ags/engine/platform/windows/win_ex_handling.cpp b/engines/ags/engine/platform/windows/win_ex_handling.cpp index aeffbc23c9d0..de3fcd9150c0 100644 --- a/engines/ags/engine/platform/windows/win_ex_handling.cpp +++ b/engines/ags/engine/platform/windows/win_ex_handling.cpp @@ -28,8 +28,8 @@ //include #include "ags/shared/ac/common.h" #include "ags/shared/ac/common_defines.h" -#include "ags/shared/debug/debugger.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/debugger.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/main/main.h" #include "ags/shared/util/ini_util.h" diff --git a/engines/ags/engine/util/library_psp.h b/engines/ags/engine/util/library_psp.h index 64bbdf1d1d55..10b95d243168 100644 --- a/engines/ags/engine/util/library_psp.h +++ b/engines/ags/engine/util/library_psp.h @@ -25,7 +25,7 @@ //include #include "ags/shared/util/string.h" -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/library_windows.h b/engines/ags/engine/util/library_windows.h index 4ce9b74e4157..8f7c2ab8811c 100644 --- a/engines/ags/engine/util/library_windows.h +++ b/engines/ags/engine/util/library_windows.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_UTIL_LIBRARY_WINDOWS_H #define AGS_ENGINE_UTIL_LIBRARY_WINDOWS_H -#include "ags/shared/debug/out.h" +#include "ags/shared/debugging/out.h" #include "ags/shared/platform/windows/winapi_exclusive.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/lib/aldumb.h b/engines/ags/lib/aldumb.h new file mode 100644 index 000000000000..b72dc823d8e3 --- /dev/null +++ b/engines/ags/lib/aldumb.h @@ -0,0 +1,118 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * aldumb.h - The user header file for DUMB with / / \ \ + * Allegro. | < / \_ + * | \/ /\ / + * Include this file if you wish to use DUMB \_ / > / + * with Allegro. It will include dumb.h for you, | \ / / + * and provide extra functionality such as audio | ' / + * stream and datafile integration. \__/ + */ + +#ifndef AGS_LIB_ALDUMB_H +#define AGS_LIB_ALDUMB_H + +#include "ags/lib/allegro.h" +#include "ags/lib/dumb.h" + +namespace AGS3 { + +#ifdef __cplusplus +extern "C" { +#endif + +/* Packfile Support */ + +void dumb_register_packfiles(void); + +DUMBFILE *dumbfile_open_packfile(PACKFILE *p); +DUMBFILE *dumbfile_from_packfile(PACKFILE *p); + + +/* Datafile Registration Functions */ + +#define DUMB_DAT_DUH DAT_ID('D','U','H',' ') +#define DUMB_DAT_IT DAT_ID('I','T',' ',' ') +#define DUMB_DAT_XM DAT_ID('X','M',' ',' ') +#define DUMB_DAT_S3M DAT_ID('S','3','M',' ') +#define DUMB_DAT_MOD DAT_ID('M','O','D',' ') + +void dumb_register_dat_duh(long type); +void dumb_register_dat_it(long type); +void dumb_register_dat_xm(long type); +void dumb_register_dat_s3m(long type); +void dumb_register_dat_mod(long type); +void dumb_register_dat_it_quick(long type); +void dumb_register_dat_xm_quick(long type); +void dumb_register_dat_s3m_quick(long type); +void dumb_register_dat_mod_quick(long type); + + +/* DUH Playing Functions */ + +typedef struct AL_DUH_PLAYER AL_DUH_PLAYER; + +AL_DUH_PLAYER *al_start_duh(DUH *duh, int n_channels, long pos, float volume, long bufsize, int freq); +void al_stop_duh(AL_DUH_PLAYER *dp); +void al_pause_duh(AL_DUH_PLAYER *dp); +void al_resume_duh(AL_DUH_PLAYER *dp); +void al_duh_set_priority(AL_DUH_PLAYER *dp, int priority); +void al_duh_set_volume(AL_DUH_PLAYER *dp, float volume); +float al_duh_get_volume(AL_DUH_PLAYER *dp); +int al_poll_duh(AL_DUH_PLAYER *dp); +long al_duh_get_position(AL_DUH_PLAYER *dp); + +AL_DUH_PLAYER *al_duh_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer, float volume, long bufsize, int freq); +DUH_SIGRENDERER *al_duh_get_sigrenderer(AL_DUH_PLAYER *dp); + +/* IMPORTANT: This function will return NULL if the music has ended. */ +DUH_SIGRENDERER *al_duh_decompose_to_sigrenderer(AL_DUH_PLAYER *dp); + +#ifdef DUMB_DECLARE_DEPRECATED + + AL_DUH_PLAYER *al_duh_encapsulate_renderer(DUH_SIGRENDERER *dr, float volume, long bufsize, int freq) DUMB_DEPRECATED; + DUH_SIGRENDERER *al_duh_get_renderer(AL_DUH_PLAYER *dp) DUMB_DEPRECATED; + DUH_SIGRENDERER *al_duh_decompose_to_renderer(AL_DUH_PLAYER *dp) DUMB_DEPRECATED; + /* Replace 'renderer' with 'sigrenderer' in each case where you called one of + * these functions. + */ + +#endif + +#ifdef __cplusplus +} +#endif + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/allegro.h b/engines/ags/lib/allegro.h index 4667540d0f96..9ecceb509edb 100644 --- a/engines/ags/lib/allegro.h +++ b/engines/ags/lib/allegro.h @@ -30,9 +30,11 @@ #include "ags/lib/allegro/color.h" #include "ags/lib/allegro/config.h" #include "ags/lib/allegro/digi.h" +#include "ags/lib/allegro/draw.h" #include "ags/lib/allegro/error.h" #include "ags/lib/allegro/file.h" #include "ags/lib/allegro/fixed.h" +#include "ags/lib/allegro/fmaths.h" #include "ags/lib/allegro/gfx.h" #include "ags/lib/allegro/keyboard.h" #include "ags/lib/allegro/midi.h" diff --git a/engines/ags/lib/allegro/draw.cpp b/engines/ags/lib/allegro/draw.cpp new file mode 100644 index 000000000000..e6b467557d4e --- /dev/null +++ b/engines/ags/lib/allegro/draw.cpp @@ -0,0 +1,31 @@ +/* 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 "ags/lib/allegro/draw.h" + +namespace AGS3 { + +void do_line(BITMAP *bmp, int x1, int y_1, int x2, int y2, int d, DrawMethod proc) { + warning("TODO: do_line"); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/draw.h b/engines/ags/lib/allegro/draw.h new file mode 100644 index 000000000000..3e16ff8f2e59 --- /dev/null +++ b/engines/ags/lib/allegro/draw.h @@ -0,0 +1,37 @@ +/* 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 "ags/lib/allegro/base.h" +#include "ags/lib/allegro/gfx.h" + +#ifndef AGS_LIB_ALLEGRO_DRAW_H +#define AGS_LIB_ALLEGRO_DRAW_H + +namespace AGS3 { + +typedef void (*DrawMethod)(BITMAP *, int, int, int); + +AL_FUNC(void, do_line, (BITMAP *bmp, int x1, int y_1, int x2, int y2, int d, DrawMethod proc)); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/allegro/file.cpp b/engines/ags/lib/allegro/file.cpp index 8ac3f0579380..1ab7ebacadfd 100644 --- a/engines/ags/lib/allegro/file.cpp +++ b/engines/ags/lib/allegro/file.cpp @@ -22,6 +22,7 @@ #include "ags/lib/allegro/file.h" #include "common/str.h" +#include "common/textconsole.h" namespace AGS3 { @@ -54,4 +55,104 @@ int is_relative_filename(const char *filename) { return !fname.contains('/') && !fname.contains('\\') ? 0 : -1; } +void packfile_password(AL_CONST char *password) { + error("TODO: packfile_password"); +} + +PACKFILE *pack_fopen(AL_CONST char *filename, AL_CONST char *mode) { + error("TODO: pack_fopen"); +} + +PACKFILE *pack_fopen_vtable(AL_CONST PACKFILE_VTABLE *vtable, void *userdata) { + error("TODO: pack_fopen_vtable"); +} + +int pack_fclose(PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_fseek(PACKFILE *f, int offset) { + error("TODO: xxx"); +} + +PACKFILE *pack_fopen_chunk(PACKFILE *f, int pack) { + error("TODO: xxx"); +} + +PACKFILE *pack_fclose_chunk(PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_getc(PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_putc(int c, PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_feof(PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_ferror(PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_igetw(PACKFILE *f) { + error("TODO: xxx"); +} + +long pack_igetl(PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_iputw(int w, PACKFILE *f) { + error("TODO: xxx"); +} + +long pack_iputl(long l, PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_mgetw(PACKFILE *f) { + error("TODO: xxx"); +} + +long pack_mgetl(PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_mputw(int w, PACKFILE *f) { + error("TODO: xxx"); +} + +long pack_mputl(long l, PACKFILE *f) { + error("TODO: xxx"); +} + +long pack_fread(void *p, long n, PACKFILE *f) { + error("TODO: xxx"); +} + +long pack_fwrite(AL_CONST void *p, long n, PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_ungetc(int c, PACKFILE *f) { + error("TODO: xxx"); +} + +char *pack_fgets(char *p, int max, PACKFILE *f) { + error("TODO: xxx"); +} + +int pack_fputs(AL_CONST char *p, PACKFILE *f) { + error("TODO: xxx"); +} + +void *pack_get_userdata(PACKFILE *f) { + error("TODO: xxx"); +} + } // namespace AGS3 diff --git a/engines/ags/lib/allegro/file.h b/engines/ags/lib/allegro/file.h index 0e2a490032b4..abf82d97d595 100644 --- a/engines/ags/lib/allegro/file.h +++ b/engines/ags/lib/allegro/file.h @@ -23,11 +23,62 @@ #ifndef AGS_LIB_ALLEGRO_FILE_H #define AGS_LIB_ALLEGRO_FILE_H +#include "ags/lib/allegro/alconfig.h" + namespace AGS3 { +#define F_READ "r" +#define F_WRITE "w" +#define F_READ_PACKED "rp" +#define F_WRITE_PACKED "wp" +#define F_WRITE_NOPACK "w!" + +#define F_BUF_SIZE 4096 /* 4K buffer for caching data */ +#define F_PACK_MAGIC 0x736C6821L /* magic number for packed files */ +#define F_NOPACK_MAGIC 0x736C682EL /* magic number for autodetect */ +#define F_EXE_MAGIC 0x736C682BL /* magic number for appended data */ + +struct _al_normal_packfile_details { + int hndl; /* DOS file handle */ + int flags; /* PACKFILE_FLAG_* constants */ + unsigned char *buf_pos; /* position in buffer */ + int buf_size; /* number of bytes in the buffer */ + long todo; /* number of bytes still on the disk */ + struct PACKFILE *parent; /* nested, parent file */ + struct LZSS_PACK_DATA *pack_data; /* for LZSS compression */ + struct LZSS_UNPACK_DATA *unpack_data; /* for LZSS decompression */ + char *filename; /* name of the file */ + char *passdata; /* encryption key data */ + char *passpos; /* current key position */ + unsigned char buf[F_BUF_SIZE]; /* the actual data buffer */ +}; + +struct PACKFILE_VTABLE { + AL_METHOD(int, pf_fclose, (void *userdata)); + AL_METHOD(int, pf_getc, (void *userdata)); + AL_METHOD(int, pf_ungetc, (int c, void *userdata)); + AL_METHOD(long, pf_fread, (void *p, long n, void *userdata)); + AL_METHOD(int, pf_putc, (int c, void *userdata)); + AL_METHOD(long, pf_fwrite, (AL_CONST void *p, long n, void *userdata)); + AL_METHOD(int, pf_fseek, (void *userdata, int offset)); + AL_METHOD(int, pf_feof, (void *userdata)); + AL_METHOD(int, pf_ferror, (void *userdata)); +}; + +/** + * Allegro file class + */ struct PACKFILE { - // TODO: PACKFILE handling - int dummy; + AL_CONST PACKFILE_VTABLE *vtable; + void *userdata; + int is_normal_packfile; + + /* The following is only to be used for the "normal" PACKFILE vtable, + * i.e. what is implemented by Allegro itself. If is_normal_packfile is + * false then the following is not even allocated. This must be the last + * member in the structure. + */ + struct _al_normal_packfile_details normal; }; extern char *fix_filename_case(char *path); @@ -37,6 +88,32 @@ extern char *canonicalize_filename(char *dest, const char *filename, int size); extern char *make_relative_filename(char *dest, const char *path, const char *filename, int size); extern int is_relative_filename(const char *filename); +AL_FUNC(void, packfile_password, (AL_CONST char *password)); +AL_FUNC(PACKFILE *, pack_fopen, (AL_CONST char *filename, AL_CONST char *mode)); +AL_FUNC(PACKFILE *, pack_fopen_vtable, (AL_CONST PACKFILE_VTABLE *vtable, void *userdata)); +AL_FUNC(int, pack_fclose, (PACKFILE *f)); +AL_FUNC(int, pack_fseek, (PACKFILE *f, int offset)); +AL_FUNC(PACKFILE *, pack_fopen_chunk, (PACKFILE *f, int pack)); +AL_FUNC(PACKFILE *, pack_fclose_chunk, (PACKFILE *f)); +AL_FUNC(int, pack_getc, (PACKFILE *f)); +AL_FUNC(int, pack_putc, (int c, PACKFILE *f)); +AL_FUNC(int, pack_feof, (PACKFILE *f)); +AL_FUNC(int, pack_ferror, (PACKFILE *f)); +AL_FUNC(int, pack_igetw, (PACKFILE *f)); +AL_FUNC(long, pack_igetl, (PACKFILE *f)); +AL_FUNC(int, pack_iputw, (int w, PACKFILE *f)); +AL_FUNC(long, pack_iputl, (long l, PACKFILE *f)); +AL_FUNC(int, pack_mgetw, (PACKFILE *f)); +AL_FUNC(long, pack_mgetl, (PACKFILE *f)); +AL_FUNC(int, pack_mputw, (int w, PACKFILE *f)); +AL_FUNC(long, pack_mputl, (long l, PACKFILE *f)); +AL_FUNC(long, pack_fread, (void *p, long n, PACKFILE *f)); +AL_FUNC(long, pack_fwrite, (AL_CONST void *p, long n, PACKFILE *f)); +AL_FUNC(int, pack_ungetc, (int c, PACKFILE *f)); +AL_FUNC(char *, pack_fgets, (char *p, int max, PACKFILE *f)); +AL_FUNC(int, pack_fputs, (AL_CONST char *p, PACKFILE *f)); +AL_FUNC(void *, pack_get_userdata, (PACKFILE *f)); + } // namespace AGS3 #endif diff --git a/engines/ags/lib/allegro/fixed.h b/engines/ags/lib/allegro/fixed.h index f8692ee9cfc5..da0a7a5d850a 100644 --- a/engines/ags/lib/allegro/fixed.h +++ b/engines/ags/lib/allegro/fixed.h @@ -27,7 +27,7 @@ namespace AGS3 { -typedef long fixed; +typedef int32 fixed; extern fixed fixtorad_r; extern fixed radtofix_r; @@ -51,13 +51,6 @@ extern fixed fixtan(fixed x); extern fixed fixacos(fixed x); extern fixed fixasin(fixed x); -#if 0 -extern fixed fixsqrt(fixed x); -extern fixed fixhypot(fixed x, fixed y); -extern fixed fixatan(fixed x); -extern fixed fixatan2(fixed y, fixed x); -#endif - } // namespace AGS3 #endif diff --git a/engines/ags/lib/allegro/fmaths.cpp b/engines/ags/lib/allegro/fmaths.cpp new file mode 100644 index 000000000000..fa4461267781 --- /dev/null +++ b/engines/ags/lib/allegro/fmaths.cpp @@ -0,0 +1,101 @@ +/* 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 "ags/lib/allegro/fmaths.h" + +namespace AGS3 { + +fixed fixsqrt(fixed x) { + if (x > 0) + return ftofix(sqrt(fixtof(x))); + + if (x < 0) + *allegro_errno = EDOM; + + return 0; +} + +fixed fixhypot(fixed x, fixed y) { + return ftofix(hypot(fixtof(x), fixtof(y))); +} + +fixed fixatan(fixed x) { + int a, b, c; /* for binary search */ + fixed d; /* difference value for search */ + + if (x >= 0) { /* search the first part of tan table */ + a = 0; + b = 127; + } else { /* search the second half instead */ + a = 128; + b = 255; + } + + do { + c = (a + b) >> 1; + d = x - _tan_tbl[c]; + + if (d > 0) + a = c + 1; + else + if (d < 0) + b = c - 1; + + } while ((a <= b) && (d)); + + if (x >= 0) + return ((long)c) << 15; + + return (-0x00800000L + (((long)c) << 15)); +} + +fixed fixatan2(fixed y, fixed x) { + fixed r; + + if (x == 0) { + if (y == 0) { + *allegro_errno = EDOM; + return 0L; + } else + return ((y < 0) ? -0x00400000L : 0x00400000L); + } + + *allegro_errno = 0; + r = fixdiv(y, x); + + if (*allegro_errno) { + *allegro_errno = 0; + return ((y < 0) ? -0x00400000L : 0x00400000L); + } + + r = fixatan(r); + + if (x >= 0) + return r; + + if (y >= 0) + return 0x00800000L + r; + + return r - 0x00800000L; +} + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/fmaths.h b/engines/ags/lib/allegro/fmaths.h new file mode 100644 index 000000000000..0aad8c5a1cf9 --- /dev/null +++ b/engines/ags/lib/allegro/fmaths.h @@ -0,0 +1,41 @@ +/* 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 AGS_LIB_ALLEGRO_FMATHS_H +#define AGS_LIB_ALLEGRO_FMATHS_H + +#include "ags/lib/allegro/fixed.h" + +namespace AGS3 { + +AL_FUNC(fixed, fixsqrt, (fixed x)); +AL_FUNC(fixed, fixhypot, (fixed x, fixed y)); +AL_FUNC(fixed, fixatan, (fixed x)); +AL_FUNC(fixed, fixatan2, (fixed y, fixed x)); + +AL_ARRAY(fixed, _cos_tbl); +AL_ARRAY(fixed, _tan_tbl); +AL_ARRAY(fixed, _acos_tbl); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 153a00be7285..a14bf1dda89d 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -38,6 +38,19 @@ BITMAP::BITMAP(Graphics::ManagedSurface *owner) : _owner(owner), line[y] = (byte *)_owner->getBasePtr(0, y); } +int BITMAP::getpixel(int x, int y) const { + if (x < 0 || y < 0 || x >= w || y >= h) + return -1; + + const byte *pixel = (const byte *)getBasePtr(x, y); + if (format.bytesPerPixel == 1) + return *pixel; + else if (format.bytesPerPixel == 2) + return *(const uint16 *)pixel; + else + return *(const uint32 *)pixel; +} + /*-------------------------------------------------------------------*/ /** diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index 95cd8104c88f..66dbdc3be31e 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -37,6 +37,13 @@ namespace AGS3 { #define GFX_SAFE AL_ID('S','A','F','E') #define GFX_NONE AL_ID('N','O','N','E') +/* Bitfield for relaying graphics driver type information */ +#define GFX_TYPE_UNKNOWN 0 +#define GFX_TYPE_WINDOWED 1 +#define GFX_TYPE_FULLSCREEN 2 +#define GFX_TYPE_DEFINITE 4 +#define GFX_TYPE_MAGIC 8 + /* drawing modes for draw_sprite_ex() */ #define DRAW_SPRITE_NORMAL 0 #define DRAW_SPRITE_LIT 1 @@ -194,6 +201,8 @@ class BITMAP { uint getTransparentColor() const { return _owner->getTransparentColor(); } + + int getpixel(int x, int y) const; }; AL_FUNC(void, set_color_conversion, (int mode)); diff --git a/engines/ags/lib/allegro/keyboard.cpp b/engines/ags/lib/allegro/keyboard.cpp index 9e0a0f638ab2..38516df5a67c 100644 --- a/engines/ags/lib/allegro/keyboard.cpp +++ b/engines/ags/lib/allegro/keyboard.cpp @@ -23,6 +23,9 @@ #include "ags/lib/allegro/keyboard.h" #include "common/algorithm.h" #include "common/textconsole.h" +#include "common/system.h" +#include "common/events.h" +#include "common/textconsole.h" namespace AGS3 { @@ -36,4 +39,41 @@ int install_keyboard() { void remove_keyboard() { } +bool keyboard_needs_poll() { + // TODO: Check if it's okay to be hardcoded for events, since I'm not sure + // how to check with ScummVM event manager for pending events + return true; +} + +int poll_keyboard() { + warning("TODO: poll_keyboard"); + return false; +} + +void simulate_keypress(int keycode) { + simulate_ukeypress(keycode, keycode); +} + +void simulate_ukeypress(int keycode, int scancode) { + Common::Event event; + + event.type = Common::EVENT_KEYDOWN; + event.kbd.ascii = scancode; + event.kbd.keycode = (Common::KeyCode)keycode; + g_system->getEventManager()->pushEvent(event); + + event.type = Common::EVENT_KEYUP; + g_system->getEventManager()->pushEvent(event); +} + +bool keypressed() { + warning("TODO: keypressed"); + return true; +} + +int readkey(void) { + warning("TODO: readkey"); + return 0; +} + } // namespace AGS3 diff --git a/engines/ags/lib/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h index 0634eec0abc9..15a1ce5512ad 100644 --- a/engines/ags/lib/allegro/keyboard.h +++ b/engines/ags/lib/allegro/keyboard.h @@ -23,10 +23,13 @@ #ifndef AGS_LIB_ALLEGRO_KEYBOARD_H #define AGS_LIB_ALLEGRO_KEYBOARD_H +#include "ags/lib/allegro/alconfig.h" #include "common/keyboard.h" namespace AGS3 { +#define __allegro_KEY_MAX Common::KEYCODE_LAST + #define KB_SHIFT_FLAG Common::KBD_SHIFT #define KB_CTRL_FLAG Common::KBD_CTRL #define KB_ALT_FLAG Common::KBD_ALT @@ -100,10 +103,83 @@ namespace AGS3 { #define __allegro_KEY_NUMLOCK Common::KEYCODE_NUMLOCK #define __allegro_KEY_CAPSLOCK Common::KEYCODE_CAPSLOCK +#define __allegro_KEY_0 Common::KEYCODE_0 +#define __allegro_KEY_1 Common::KEYCODE_1 +#define __allegro_KEY_2 Common::KEYCODE_2 +#define __allegro_KEY_3 Common::KEYCODE_3 +#define __allegro_KEY_4 Common::KEYCODE_4 +#define __allegro_KEY_5 Common::KEYCODE_5 +#define __allegro_KEY_6 Common::KEYCODE_6 +#define __allegro_KEY_7 Common::KEYCODE_7 +#define __allegro_KEY_8 Common::KEYCODE_8 +#define __allegro_KEY_9 Common::KEYCODE_9 + +#define __allegro_KEY_A Common::KEYCODE_a +#define __allegro_KEY_B Common::KEYCODE_b +#define __allegro_KEY_C Common::KEYCODE_c +#define __allegro_KEY_D Common::KEYCODE_d +#define __allegro_KEY_E Common::KEYCODE_e +#define __allegro_KEY_F Common::KEYCODE_f +#define __allegro_KEY_G Common::KEYCODE_g +#define __allegro_KEY_H Common::KEYCODE_h +#define __allegro_KEY_I Common::KEYCODE_i +#define __allegro_KEY_J Common::KEYCODE_j +#define __allegro_KEY_K Common::KEYCODE_k +#define __allegro_KEY_L Common::KEYCODE_l +#define __allegro_KEY_M Common::KEYCODE_m +#define __allegro_KEY_N Common::KEYCODE_n +#define __allegro_KEY_O Common::KEYCODE_o +#define __allegro_KEY_P Common::KEYCODE_p +#define __allegro_KEY_Q Common::KEYCODE_q +#define __allegro_KEY_R Common::KEYCODE_r +#define __allegro_KEY_S Common::KEYCODE_s +#define __allegro_KEY_T Common::KEYCODE_t +#define __allegro_KEY_U Common::KEYCODE_u +#define __allegro_KEY_V Common::KEYCODE_v +#define __allegro_KEY_W Common::KEYCODE_w +#define __allegro_KEY_X Common::KEYCODE_x +#define __allegro_KEY_Y Common::KEYCODE_y +#define __allegro_KEY_Z Common::KEYCODE_z + + +#define __allegro_KEY_BACKSPACE Common::KEYCODE_BACKSPACE +#define __allegro_KEY_TAB Common::KEYCODE_TAB +#define __allegro_KEY_ENTER Common::KEYCODE_RETURN +#define __allegro_KEY_ENTER_PAD Common::KEYCODE_KP_ENTER +#define __allegro_KEY_ESC Common::KEYCODE_ESCAPE +#define __allegro_KEY_SPACE Common::KEYCODE_SPACE +#define __allegro_KEY_QUOTE Common::KEYCODE_QUOTE +#define __allegro_KEY_COMMA Common::KEYCODE_COMMA +#define __allegro_KEY_STOP 0 +#define __allegro_KEY_SLASH Common::KEYCODE_SLASH +#define __allegro_KEY_SLASH_PAD Common::KEYCODE_KP_DIVIDE +#define __allegro_KEY_BACKSLASH Common::KEYCODE_BACKSLASH +#define __allegro_KEY_BACKSLASH2 Common::KEYCODE_BACKSLASH +#define __allegro_KEY_SEMICOLON Common::KEYCODE_SEMICOLON +#define __allegro_KEY_EQUALS Common::KEYCODE_EQUALS +#define __allegro_KEY_EQUALS_PAD Common::KEYCODE_KP_EQUALS +#define __allegro_KEY_OPENBRACE 123 +#define __allegro_KEY_CLOSEBRACE 125 +#define __allegro_KEY_PLUS_PAD Common::KEYCODE_KP_PLUS +#define __allegro_KEY_MINUS Common::KEYCODE_MINUS +#define __allegro_KEY_MINUS_PAD Common::KEYCODE_KP_MINUS +#define __allegro_KEY_COLON Common::KEYCODE_COLON +#define __allegro_KEY_COLON2 Common::KEYCODE_COLON +#define __allegro_KEY_ASTERISK Common::KEYCODE_ASTERISK +#define __allegro_KEY_AT Common::KEYCODE_AT + extern bool key[Common::KEYCODE_LAST]; +AL_FUNC(bool, keyboard_needs_poll, (void)); +AL_FUNC(int, poll_keyboard, (void)); + extern int install_keyboard(); extern void remove_keyboard(); +AL_FUNC(void, simulate_keypress, (int keycode)); +AL_FUNC(void, simulate_ukeypress, (int keycode, int scancode)); + +AL_FUNC(bool, keypressed, (void)); +AL_FUNC(int, readkey, (void)); } // namespace AGS3 diff --git a/engines/ags/lib/allegro/system.h b/engines/ags/lib/allegro/system.h index be5759b02f99..c44eedd84d2f 100644 --- a/engines/ags/lib/allegro/system.h +++ b/engines/ags/lib/allegro/system.h @@ -36,6 +36,14 @@ namespace AGS3 { #define SYSTEM_AUTODETECT 0 #define SYSTEM_NONE AL_ID('N','O','N','E') +#define SWITCH_NONE 0 +#define SWITCH_PAUSE 1 +#define SWITCH_AMNESIA 2 +#define SWITCH_BACKGROUND 3 +#define SWITCH_BACKAMNESIA 4 + +#define SWITCH_IN 0 +#define SWITCH_OUT 1 struct GFX_MODE { int width, height, bpp; @@ -140,6 +148,8 @@ extern GFX_MODE_LIST *get_gfx_mode_list(int card); extern void destroy_gfx_mode_list(GFX_MODE_LIST *list); inline void vsync() {} +inline int set_display_switch_callback(int dir, AL_METHOD(void, cb, (void))) { return 0; } +inline int set_display_switch_mode(int v) { return -1; } } // namespace AGS3 diff --git a/engines/ags/lib/dumb.h b/engines/ags/lib/dumb.h new file mode 100644 index 000000000000..a74ffdf0baae --- /dev/null +++ b/engines/ags/lib/dumb.h @@ -0,0 +1,581 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * dumb.h - The user header file for DUMB. / / \ \ + * | < / \_ + * Include this file in any of your files in | \/ /\ / + * which you wish to use the DUMB functions \_ / > / + * and variables. | \ / / + * | ' / + * \__/ + */ + +#ifndef AGS_LIB_DUMB_H +#define AGS_LIB_DUMB_H + +#include "common/stream.h" + +namespace AGS3 { + +#ifdef __cplusplus +extern "C" { +#endif + + +#define DUMB_MAJOR_VERSION 0 +#define DUMB_MINOR_VERSION 9 +#define DUMB_REVISION_VERSION 2 + +#define DUMB_VERSION (DUMB_MAJOR_VERSION*10000 + DUMB_MINOR_VERSION*100 + DUMB_REVISION_VERSION) + +#define DUMB_VERSION_STR "0.9.2" + +#define DUMB_NAME "DUMB v" DUMB_VERSION_STR + +#define DUMB_YEAR 2003 +#define DUMB_MONTH 4 +#define DUMB_DAY 2 + +#define DUMB_YEAR_STR2 "03" +#define DUMB_YEAR_STR4 "2003" +#define DUMB_MONTH_STR1 "4" +#define DUMB_DAY_STR1 "2" + +#if DUMB_MONTH < 10 +#define DUMB_MONTH_STR2 "0" DUMB_MONTH_STR1 +#else +#define DUMB_MONTH_STR2 DUMB_MONTH_STR1 +#endif + +#if DUMB_DAY < 10 +#define DUMB_DAY_STR2 "0" DUMB_DAY_STR1 +#else +#define DUMB_DAY_STR2 DUMB_DAY_STR1 +#endif + + + /* WARNING: The month and day were inadvertently swapped in the v0.8 release. + * Please do not compare this constant against any date in 2002. In + * any case, DUMB_VERSION is probably more useful for this purpose. + */ +#define DUMB_DATE (DUMB_YEAR*10000 + DUMB_MONTH*100 + DUMB_DAY) + +#define DUMB_DATE_STR DUMB_DAY_STR1 "." DUMB_MONTH_STR1 "." DUMB_YEAR_STR4 + + +#undef MIN +#undef MAX +#undef MID + +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#define MID(x,y,z) MAX((x), MIN((y), (z))) + +#undef ABS +#define ABS(x) (((x) >= 0) ? (x) : (-(x))) + + +#ifdef DEBUGMODE + +#ifndef ASSERT +#include +#define ASSERT(n) assert(n) +#endif +#ifndef TRACE + // it would be nice if this did actually trace ... +#define TRACE 1 ? (void)0 : (void)printf +#endif + +#else + +#ifndef ASSERT +#define ASSERT(n) +#endif +#ifndef TRACE +#define TRACE 1 ? (void)0 : (void)printf +#endif + +#endif + + +#define DUMB_ID(a,b,c,d) (((unsigned int)(a) << 24) | \ + ((unsigned int)(b) << 16) | \ + ((unsigned int)(c) << 8) | \ + ((unsigned int)(d) )) + + + +#ifndef LONG_LONG +#ifdef __GNUC__ +#define LONG_LONG long long +#elif defined _MSC_VER +#define LONG_LONG __int64 +#else +#error 64-bit integer type unknown +#endif +#endif + +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 301 /* GCC 3.1+ */ +#ifndef DUMB_DECLARE_DEPRECATED +#define DUMB_DECLARE_DEPRECATED +#endif +#define DUMB_DEPRECATED __attribute__((__deprecated__)) +#else +#define DUMB_DEPRECATED +#endif + + + /* Basic Sample Type. Normal range is -0x800000 to 0x7FFFFF. */ + + typedef int sample_t; + + + /* Library Clean-up Management */ + + int dumb_atexit(void (*proc)(void)); + + void dumb_exit(void); + + + /* File Input Functions */ + + typedef struct DUMBFILE_SYSTEM { + void *(*open)(const char *filename); + int (*skip)(void *f, long n); + int (*getc)(void *f); + long (*getnc)(char *ptr, long n, void *f); + void (*close)(void *f); + } + DUMBFILE_SYSTEM; + + typedef struct DUMBFILE DUMBFILE; + + void register_dumbfile_system(DUMBFILE_SYSTEM *dfs); + + DUMBFILE *dumbfile_open(const char *filename); + DUMBFILE *dumbfile_open_ex(void *file, DUMBFILE_SYSTEM *dfs); + + long dumbfile_pos(DUMBFILE *f); + int dumbfile_skip(DUMBFILE *f, long n); + + int dumbfile_getc(DUMBFILE *f); + + int dumbfile_igetw(DUMBFILE *f); + int dumbfile_mgetw(DUMBFILE *f); + + long dumbfile_igetl(DUMBFILE *f); + long dumbfile_mgetl(DUMBFILE *f); + + unsigned long dumbfile_cgetul(DUMBFILE *f); + signed long dumbfile_cgetsl(DUMBFILE *f); + + long dumbfile_getnc(char *ptr, long n, DUMBFILE *f); + + int dumbfile_error(DUMBFILE *f); + int dumbfile_close(DUMBFILE *f); + + + /* stdio File Input Module */ + + void dumb_register_stdfiles(void); + + DUMBFILE *dumbfile_open_stdfile(Common::ReadStream *p); + + + /* Memory File Input Module */ + + DUMBFILE *dumbfile_open_memory(const char *data, long size); + + + /* DUH Management */ + + typedef struct DUH DUH; + +#define DUH_SIGNATURE DUMB_ID('D','U','H','!') + + void unload_duh(DUH *duh); + + DUH *load_duh(const char *filename); + DUH *read_duh(DUMBFILE *f); + + long duh_get_length(DUH *duh); + + + /* Signal Rendering Functions */ + + typedef struct DUH_SIGRENDERER DUH_SIGRENDERER; + + DUH_SIGRENDERER *duh_start_sigrenderer(DUH *duh, int sig, int n_channels, long pos); + +#ifdef DUMB_DECLARE_DEPRECATED + typedef void (*DUH_SIGRENDERER_CALLBACK)(void *data, sample_t **samples, int n_channels, long length); + /* This is deprecated, but is not marked as such because GCC tends to + * complain spuriously when the typedef is used later. See comments below. + */ + + void duh_sigrenderer_set_callback( + DUH_SIGRENDERER *sigrenderer, + DUH_SIGRENDERER_CALLBACK callback, void *data + ) DUMB_DEPRECATED; + /* The 'callback' argument's type has changed for const-correctness. See the + * DUH_SIGRENDERER_CALLBACK definition just above. Also note that the samples + * in the buffer are now 256 times as large; the normal range is -0x800000 to + * 0x7FFFFF. The function has been renamed partly because its functionality + * has changed slightly and partly so that its name is more meaningful. The + * new one is duh_sigrenderer_set_analyser_callback(), and the typedef for + * the function pointer has also changed, from DUH_SIGRENDERER_CALLBACK to + * DUH_SIGRENDERER_ANALYSER_CALLBACK. (If you wanted to use this callback to + * apply a DSP effect, don't worry; there is a better way of doing this. It + * is undocumented, so contact me and I shall try to help. Contact details + * are in readme.txt.) + */ +#endif + + typedef void (*DUH_SIGRENDERER_ANALYSER_CALLBACK)(void *data, const sample_t *const *samples, int n_channels, long length); + + void duh_sigrenderer_set_analyser_callback( + DUH_SIGRENDERER *sigrenderer, + DUH_SIGRENDERER_ANALYSER_CALLBACK callback, void *data + ); + + int duh_sigrenderer_get_n_channels(DUH_SIGRENDERER *sigrenderer); + long duh_sigrenderer_get_position(DUH_SIGRENDERER *sigrenderer); + + void duh_sigrenderer_set_sigparam(DUH_SIGRENDERER *sigrenderer, unsigned char id, long value); + + long duh_sigrenderer_get_samples( + DUH_SIGRENDERER *sigrenderer, + float volume, float delta, + long size, sample_t **samples + ); + + void duh_sigrenderer_get_current_sample(DUH_SIGRENDERER *sigrenderer, float volume, sample_t *samples); + + void duh_end_sigrenderer(DUH_SIGRENDERER *sigrenderer); + + + /* DUH Rendering Functions */ + + long duh_render( + DUH_SIGRENDERER *sigrenderer, + int bits, int unsign, + float volume, float delta, + long size, void *sptr + ); + +#ifdef DUMB_DECLARE_DEPRECATED + + long duh_render_signal( + DUH_SIGRENDERER *sigrenderer, + float volume, float delta, + long size, sample_t **samples + ) DUMB_DEPRECATED; + /* Please use duh_sigrenderer_get_samples(). Arguments and functionality are + * identical. + */ + + typedef DUH_SIGRENDERER DUH_RENDERER DUMB_DEPRECATED; + /* Please use DUH_SIGRENDERER instead of DUH_RENDERER. */ + + DUH_SIGRENDERER *duh_start_renderer(DUH *duh, int n_channels, long pos) DUMB_DEPRECATED; + /* Please use duh_start_sigrenderer() instead. Pass 0 for 'sig'. */ + + int duh_renderer_get_n_channels(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; + long duh_renderer_get_position(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; + /* Please use the duh_sigrenderer_*() equivalents of these two functions. */ + + void duh_end_renderer(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; + /* Please use duh_end_sigrenderer() instead. */ + + DUH_SIGRENDERER *duh_renderer_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer) DUMB_DEPRECATED; + DUH_SIGRENDERER *duh_renderer_get_sigrenderer(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; + DUH_SIGRENDERER *duh_renderer_decompose_to_sigrenderer(DUH_SIGRENDERER *dr) DUMB_DEPRECATED; + /* These functions have become no-ops that just return the parameter. + * So, for instance, replace + * duh_renderer_encapsulate_sigrenderer(my_sigrenderer) + * with + * my_sigrenderer + */ + +#endif + + + /* Impulse Tracker Support */ + + extern int dumb_it_max_to_mix; + + typedef struct DUMB_IT_SIGDATA DUMB_IT_SIGDATA; + typedef struct DUMB_IT_SIGRENDERER DUMB_IT_SIGRENDERER; + + DUMB_IT_SIGDATA *duh_get_it_sigdata(DUH *duh); + DUH_SIGRENDERER *duh_encapsulate_it_sigrenderer(DUMB_IT_SIGRENDERER *it_sigrenderer, int n_channels, long pos); + DUMB_IT_SIGRENDERER *duh_get_it_sigrenderer(DUH_SIGRENDERER *sigrenderer); + + DUH_SIGRENDERER *dumb_it_start_at_order(DUH *duh, int n_channels, int startorder); + + void dumb_it_set_loop_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data); + void dumb_it_set_xm_speed_zero_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data); + void dumb_it_set_midi_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data, int channel, unsigned char byte), void *data); + + int dumb_it_callback_terminate(void *data); + int dumb_it_callback_midi_block(void *data, int channel, unsigned char byte); + + DUH *dumb_load_it(const char *filename); + DUH *dumb_load_xm(const char *filename); + DUH *dumb_load_s3m(const char *filename); + DUH *dumb_load_mod(const char *filename); + + DUH *dumb_read_it(DUMBFILE *f); + DUH *dumb_read_xm(DUMBFILE *f); + DUH *dumb_read_s3m(DUMBFILE *f); + DUH *dumb_read_mod(DUMBFILE *f); + + int dumb_it_sd_get_n_orders(DUMB_IT_SIGDATA *sd); + + int dumb_it_sd_get_initial_global_volume(DUMB_IT_SIGDATA *sd); + void dumb_it_sd_set_initial_global_volume(DUMB_IT_SIGDATA *sd, int gv); + + int dumb_it_sd_get_mixing_volume(DUMB_IT_SIGDATA *sd); + void dumb_it_sd_set_mixing_volume(DUMB_IT_SIGDATA *sd, int mv); + + int dumb_it_sd_get_initial_speed(DUMB_IT_SIGDATA *sd); + void dumb_it_sd_set_initial_speed(DUMB_IT_SIGDATA *sd, int speed); + + int dumb_it_sd_get_initial_tempo(DUMB_IT_SIGDATA *sd); + void dumb_it_sd_set_initial_tempo(DUMB_IT_SIGDATA *sd, int tempo); + + int dumb_it_sd_get_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel); + void dumb_it_sd_set_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel, int volume); + + int dumb_it_sr_get_current_order(DUMB_IT_SIGRENDERER *sr); + int dumb_it_sr_get_current_row(DUMB_IT_SIGRENDERER *sr); + + int dumb_it_sr_get_global_volume(DUMB_IT_SIGRENDERER *sr); + void dumb_it_sr_set_global_volume(DUMB_IT_SIGRENDERER *sr, int gv); + + int dumb_it_sr_get_tempo(DUMB_IT_SIGRENDERER *sr); + void dumb_it_sr_set_tempo(DUMB_IT_SIGRENDERER *sr, int tempo); + + int dumb_it_sr_get_speed(DUMB_IT_SIGRENDERER *sr); + void dumb_it_sr_set_speed(DUMB_IT_SIGRENDERER *sr, int speed); + +#define DUMB_IT_N_CHANNELS 64 +#define DUMB_IT_N_NNA_CHANNELS 192 +#define DUMB_IT_TOTAL_CHANNELS (DUMB_IT_N_CHANNELS + DUMB_IT_N_NNA_CHANNELS) + + /* Channels passed to any of these functions are 0-based */ + int dumb_it_sr_get_channel_volume(DUMB_IT_SIGRENDERER *sr, int channel); + void dumb_it_sr_set_channel_volume(DUMB_IT_SIGRENDERER *sr, int channel, int volume); + + typedef struct DUMB_IT_CHANNEL_STATE DUMB_IT_CHANNEL_STATE; + + struct DUMB_IT_CHANNEL_STATE { + int channel; /* 0-based; meaningful for NNA channels */ + int sample; /* 1-based; 0 if nothing playing, then other fields undef */ + int freq; /* in Hz */ + float volume; /* 1.0 maximum; affected by ALL factors, inc. mixing vol */ + unsigned char pan; /* 0-64, 100 for surround */ + signed char subpan; /* use (pan + subpan/256.0f) or ((pan<<8)+subpan) */ + unsigned char filter_cutoff; /* 0-127 cutoff=127 AND resonance=0 */ + unsigned char filter_subcutoff; /* 0-255 -> no filters (subcutoff */ + unsigned char filter_resonance; /* 0-127 always 0 in this case) */ + /* subcutoff only changes from zero if filter envelopes are in use. The + * calculation (filter_cutoff + filter_subcutoff/256.0f) gives a more + * accurate filter cutoff measurement as a float. It would often be more + * useful to use a scaled int such as ((cutoff<<8) + subcutoff). + */ + }; + + /* Values of 64 or more will access NNA channels here. */ + void dumb_it_sr_get_channel_state(DUMB_IT_SIGRENDERER *sr, int channel, DUMB_IT_CHANNEL_STATE *state); + + + /* Signal Design Helper Values */ + + /* Use pow(DUMB_SEMITONE_BASE, n) to get the 'delta' value to transpose up by + * n semitones. To transpose down, use negative n. + */ +#define DUMB_SEMITONE_BASE 1.059463094359295309843105314939748495817 + + /* Use pow(DUMB_QUARTERTONE_BASE, n) to get the 'delta' value to transpose up + * by n quartertones. To transpose down, use negative n. + */ +#define DUMB_QUARTERTONE_BASE 1.029302236643492074463779317738953977823 + + /* Use pow(DUMB_PITCH_BASE, n) to get the 'delta' value to transpose up by n + * units. In this case, 256 units represent one semitone; 3072 units + * represent one octave. These units are used by the sequence signal (SEQU). + */ +#define DUMB_PITCH_BASE 1.000225659305069791926712241547647863626 + + + /* Signal Design Function Types */ + + typedef void sigdata_t; + typedef void sigrenderer_t; + + typedef sigdata_t *(*DUH_LOAD_SIGDATA)(DUH *duh, DUMBFILE *file); + + typedef sigrenderer_t *(*DUH_START_SIGRENDERER)( + DUH *duh, + sigdata_t *sigdata, + int n_channels, + long pos + ); + + typedef void (*DUH_SIGRENDERER_SET_SIGPARAM)( + sigrenderer_t *sigrenderer, + unsigned char id, long value + ); + + typedef long (*DUH_SIGRENDERER_GET_SAMPLES)( + sigrenderer_t *sigrenderer, + float volume, float delta, + long size, sample_t **samples + ); + + typedef void (*DUH_SIGRENDERER_GET_CURRENT_SAMPLE)( + sigrenderer_t *sigrenderer, + float volume, + sample_t *samples + ); + + typedef void (*DUH_END_SIGRENDERER)(sigrenderer_t *sigrenderer); + + typedef void (*DUH_UNLOAD_SIGDATA)(sigdata_t *sigdata); + + + /* Signal Design Function Registration */ + + typedef struct DUH_SIGTYPE_DESC { + long type; + DUH_LOAD_SIGDATA load_sigdata; + DUH_START_SIGRENDERER start_sigrenderer; + DUH_SIGRENDERER_SET_SIGPARAM sigrenderer_set_sigparam; + DUH_SIGRENDERER_GET_SAMPLES sigrenderer_get_samples; + DUH_SIGRENDERER_GET_CURRENT_SAMPLE sigrenderer_get_current_sample; + DUH_END_SIGRENDERER end_sigrenderer; + DUH_UNLOAD_SIGDATA unload_sigdata; + } + DUH_SIGTYPE_DESC; + + void dumb_register_sigtype(DUH_SIGTYPE_DESC *desc); + + + // Decide where to put these functions; new heading? + + sigdata_t *duh_get_raw_sigdata(DUH *duh, int sig, long type); + + DUH_SIGRENDERER *duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer, DUH_SIGTYPE_DESC *desc, int n_channels, long pos); + sigrenderer_t *duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type); + + + /* Sample Buffer Allocation Helpers */ + + sample_t **create_sample_buffer(int n_channels, long length); + void destroy_sample_buffer(sample_t **samples); + + + /* Silencing Helper */ + + void dumb_silence(sample_t *samples, long length); + + + /* Click Removal Helpers */ + + typedef struct DUMB_CLICK_REMOVER DUMB_CLICK_REMOVER; + + DUMB_CLICK_REMOVER *dumb_create_click_remover(void); + void dumb_record_click(DUMB_CLICK_REMOVER *cr, long pos, sample_t step); + void dumb_remove_clicks(DUMB_CLICK_REMOVER *cr, sample_t *samples, long length, float halflife); + sample_t dumb_click_remover_get_offset(DUMB_CLICK_REMOVER *cr); + void dumb_destroy_click_remover(DUMB_CLICK_REMOVER *cr); + + DUMB_CLICK_REMOVER **dumb_create_click_remover_array(int n); + void dumb_record_click_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step); + void dumb_record_click_negative_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step); + void dumb_remove_clicks_array(int n, DUMB_CLICK_REMOVER **cr, sample_t **samples, long length, float halflife); + void dumb_click_remover_get_offset_array(int n, DUMB_CLICK_REMOVER **cr, sample_t *offset); + void dumb_destroy_click_remover_array(int n, DUMB_CLICK_REMOVER **cr); + + + /* Resampling Helpers */ + +#define DUMB_RQ_ALIASING 0 +#define DUMB_RQ_LINEAR 1 +#define DUMB_RQ_CUBIC 2 +#define DUMB_RQ_N_LEVELS 3 + extern int dumb_resampling_quality; + + typedef struct DUMB_RESAMPLER DUMB_RESAMPLER; + + typedef void (*DUMB_RESAMPLE_PICKUP)(DUMB_RESAMPLER *resampler, void *data); + + struct DUMB_RESAMPLER { + sample_t *src; + long pos; + int subpos; + long start, end; + int dir; + DUMB_RESAMPLE_PICKUP pickup; + void *pickup_data; + int min_quality; + int max_quality; + /* Everything below this point is internal: do not use. */ + sample_t x[3]; + int overshot; + }; + + void dumb_reset_resampler(DUMB_RESAMPLER *resampler, sample_t *src, long pos, long start, long end); + DUMB_RESAMPLER *dumb_start_resampler(sample_t *src, long pos, long start, long end); + long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta); + sample_t dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, float volume); + void dumb_end_resampler(DUMB_RESAMPLER *resampler); + + + /* DUH Construction */ + + DUH *make_duh( + long length, + int n_signals, + DUH_SIGTYPE_DESC *desc[], + sigdata_t *sigdata[] + ); + + +#ifdef __cplusplus +} +#endif + +} // namespace AGS3 + +#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk index b455f9916dbc..4806c7b00af1 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -10,6 +10,7 @@ MODULE_OBJS = \ lib/allegro/color.o \ lib/allegro/config.o \ lib/allegro/digi.o \ + lib/allegro/draw.o \ lib/allegro/error.o \ lib/allegro/file.o \ lib/allegro/fixed.o \ @@ -109,6 +110,97 @@ MODULE_OBJS = \ engine/ac/dynobj/scriptset.o \ engine/ac/statobj/agsstaticobject.o \ engine/ac/statobj/staticarray.o \ + engine/ac/audiochannel.o \ + engine/ac/audioclip.o \ + engine/ac/button.o \ + engine/ac/cdaudio.o \ + engine/ac/character.o \ + engine/ac/characterextras.o \ + engine/ac/characterinfo_engine.o \ + engine/ac/datetime.o \ + engine/ac/dialog.o \ + engine/ac/dialogoptionsrendering.o \ + engine/ac/display.o \ + engine/ac/draw.o \ + engine/ac/drawingsurface.o \ + engine/ac/draw_software.o \ + engine/ac/dynamicsprite.o \ + engine/ac/event.o \ + engine/ac/file.o \ + engine/ac/game.o \ + engine/ac/gamesetup.o \ + engine/ac/gamestate.o \ + engine/ac/global_api.o \ + engine/ac/global_audio.o \ + engine/ac/global_button.o \ + engine/ac/global_character.o \ + engine/ac/global_datetime.o \ + engine/ac/global_debug.o \ + engine/ac/global_dialog.o \ + engine/ac/global_display.o \ + engine/ac/global_drawingsurface.o \ + engine/ac/global_dynamicsprite.o \ + engine/ac/global_file.o \ + engine/ac/global_game.o \ + engine/ac/global_gui.o \ + engine/ac/global_hotspot.o \ + engine/ac/global_inventoryitem.o \ + engine/ac/global_invwindow.o \ + engine/ac/global_label.o \ + engine/ac/global_listbox.o \ + engine/ac/global_mouse.o \ + engine/ac/global_object.o \ + engine/ac/global_overlay.o \ + engine/ac/global_palette.o \ + engine/ac/global_parser.o \ + engine/ac/global_record.o \ + engine/ac/global_region.o \ + engine/ac/global_room.o \ + engine/ac/global_screen.o \ + engine/ac/global_slider.o \ + engine/ac/global_string.o \ + engine/ac/global_textbox.o \ + engine/ac/global_timer.o \ + engine/ac/global_translation.o \ + engine/ac/global_video.o \ + engine/ac/global_viewframe.o \ + engine/ac/global_viewport.o \ + engine/ac/global_walkablearea.o \ + engine/ac/global_walkbehind.o \ + engine/ac/gui.o \ + engine/ac/guicontrol.o \ + engine/ac/guiinv.o \ + engine/ac/hotspot.o \ + engine/ac/interfacebutton.o \ + engine/ac/interfaceelement.o \ + engine/ac/inventoryitem.o \ + engine/ac/invwindow.o \ + engine/ac/keycode.o \ + engine/ac/label.o \ + engine/ac/listbox.o \ + engine/ac/math.o \ + engine/ac/mouse.o \ + engine/ac/movelist.o \ + engine/ac/object.o \ + engine/ac/overlay.o \ + engine/ac/parser.o \ + engine/ac/properties.o \ + engine/ac/route_finder_impl.o \ + engine/ac/route_finder_impl_legacy.o \ + engine/ac/scriptcontainers.o \ + engine/ac/sys_events.o \ + engine/ac/region.o \ + engine/ac/richgamemedia.o \ + engine/ac/room.o \ + engine/ac/roomobject.o \ + engine/ac/roomstatus.o \ + engine/ac/route_finder.o \ + engine/ac/screen.o \ + engine/ac/screenoverlay.o \ + engine/ac/slider.o \ + engine/ac/speech.o \ + engine/ac/sprite.o \ + engine/ac/spritecache_engine.o \ engine/debugging/consoleoutputtarget.o \ engine/debugging/debug.o \ engine/debugging/filebasedagsdebugger.o \ diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index f1e3dd1b54ad..b4209972a632 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -74,12 +74,14 @@ typedef int64 intptr_t; #define fixed_t int32_t #define color_t int +#undef INT16_MAX #undef INT32_MIN #undef INT32_MAX #undef INT_MIN #undef INT_MAX #undef UINT_MAX #undef SIZE_MAX +#define INT16_MAX 0x7fff #define INT32_MIN (-2147483647 - 1) #define INT32_MAX 2147483647 #define INT_MIN (-2147483647 - 1) diff --git a/engines/ags/std/algorithm.h b/engines/ags/std/algorithm.h index 8599dc0878f9..6e02eed2c3e0 100644 --- a/engines/ags/std/algorithm.h +++ b/engines/ags/std/algorithm.h @@ -43,7 +43,17 @@ In fill(In first, In last, const Value &val) { template void sort(T first, T last, StrictWeakOrdering comp) { - Common::sort(first, last, comp); + Common::sort(first, last, comp); +} + +template +void sort(T *first, T *last) { + Common::sort(first, last, Common::Less()); +} + +template +void sort(T first, T last) { + Common::sort(first, last); } } // namespace std diff --git a/engines/ags/std/map.h b/engines/ags/std/map.h index 34a27bb7d156..70156b9cb25d 100644 --- a/engines/ags/std/map.h +++ b/engines/ags/std/map.h @@ -35,8 +35,9 @@ class map : public Common::HashMap { public: using iterator = typename Common::HashMap::iterator; - void insert(pair elem) { + pair insert(pair elem) { this->operator[](elem.first) = elem.second; + return elem; } // FUNCTION TEMPLATE lower_bound @@ -55,8 +56,9 @@ template, class EqualFunc = Common::EqualTo > class unordered_map : public Common::HashMap { public: - void insert(pair elem) { + pair insert(pair elem) { this->operator[](elem.first) = elem.second; + return elem; } void reserve(size_t size) { diff --git a/engines/ags/std/math.h b/engines/ags/std/math.h new file mode 100644 index 000000000000..8fa5814ed62a --- /dev/null +++ b/engines/ags/std/math.h @@ -0,0 +1,42 @@ +/* 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 AGS_STD_MATH_H +#define AGS_STD_MATH_H + +#include "common/hashmap.h" +#include "ags/std/utility.h" + +namespace AGS3 { +namespace std { + +#ifndef NAN +#define NAN ((float)(INFINITY * 0.0F)) +#endif + +template +inline bool isnan(T val) { return val == NAN; } + +} // namespace std +} // namespace AGS3 + +#endif diff --git a/engines/ags/std/queue.h b/engines/ags/std/queue.h index 41c0653464bf..52761ec45d9f 100644 --- a/engines/ags/std/queue.h +++ b/engines/ags/std/queue.h @@ -23,6 +23,8 @@ #ifndef AGS_STD_QUEUE_H #define AGS_STD_QUEUE_H +#include "ags/std/algorithm.h" +#include "ags/std/vector.h" #include "common/queue.h" namespace AGS3 { @@ -31,6 +33,26 @@ namespace std { template using queue = Common::Queue; +template, class Comparitor = typename Common::Less > +class priority_queue { +private: + Container _container; + Comparitor _comparitor; +public: + priority_queue(); + + bool empty() const { return _container.empty(); } + + const T &top() const { return _container.front(); } + + void push(const T &item) { + _container.push_back(item); + Common::sort(_container.begin(), _container.end(), _comparitor); + } + + void pop() { _container.remove_at(0); } +}; + } // namespace std } // namespace AGS3 diff --git a/engines/ags/std/set.h b/engines/ags/std/set.h index f50a8f87e0e5..7815a40ed493 100644 --- a/engines/ags/std/set.h +++ b/engines/ags/std/set.h @@ -35,9 +35,16 @@ template > class set : public Common::SortedArray { private: static int ComparatorFn(const T &a, const T &b) { - return Comparitor()(a, b) ? -1 : 0; + return Comparitor().operator()(a, b) ? -1 : 0; } public: + struct Entry { + const T &_value; + Entry(const T &item) : _value(item) { + } + }; +public: + using iterator = typename Common::SortedArray::iterator; using const_iterator = typename Common::SortedArray::const_iterator; /** @@ -45,6 +52,25 @@ class set : public Common::SortedArray { */ set() : Common::SortedArray(ComparatorFn) {} + /** + * Locate an item in the set + */ + iterator find(const T &item) { + iterator it; + for (it = this->begin(); it != this->end() && *it != item; ++it) { + } + + return it; + } + + /** + * Insert an element at the sorted position. + */ + Entry insert(const T &item) { + Common::SortedArray::insert(item); + return Entry(item); + } + /** * Returns the number of keys that match the specified key */ @@ -53,7 +79,7 @@ class set : public Common::SortedArray { for (const_iterator it = this->begin(); it != this->end(); ++it) { if (*it == item) ++total; - else if (!ComparatorFn(item, *it)) + else if (!ComparatorFn (item, *it)) // Passed beyond possibility of matches break; } diff --git a/engines/ags/std/unordered_set.h b/engines/ags/std/unordered_set.h index 9ef12dd3e53b..c9db4ffbde4c 100644 --- a/engines/ags/std/unordered_set.h +++ b/engines/ags/std/unordered_set.h @@ -29,15 +29,60 @@ namespace AGS3 { namespace std { -template , class Pred = Common::EqualTo > -class unordered_set { +/** + * Unordered set + * TODO: If needed, implement containers of items by unique hash of key + */ +template , class Pred = Common::EqualTo > +class unordered_set : public Common::Array { private: Hash _hash; Pred _comparitor; public: + struct Entry { + const T &_value; + Entry(const T &item) : _value(item) {} + }; +public: + using iterator = typename Common::Array::iterator; + using const_iterator = typename Common::Array::const_iterator; + unordered_set() {} - // TODO: Implement whatever unordered_set methods are needed + /** + * Locate an item in the set + */ + iterator find(const T &item) { + iterator it; + for (it = this->begin(); it != this->end() && *it != item; ++it) { + } + + return it; + } + + /** + * Adds an item + */ + Entry insert(const T &item) { + this->push_back(item); + return Entry(item); + } + + /** + * Returns the number of keys that match the specified key + */ + size_t count(const T item) const { + size_t total = 0; + for (const_iterator it = this->begin(); it != this->end(); ++it) { + if (*it == item) + ++total; + else if (!_comparitor(item, *it)) + // Passed beyond possibility of matches + break; + } + + return total; + } }; } // namespace std diff --git a/engines/ags/std/vector.h b/engines/ags/std/vector.h index 84a1915d495a..dffff2aa28ed 100644 --- a/engines/ags/std/vector.h +++ b/engines/ags/std/vector.h @@ -84,6 +84,9 @@ class vector : public Common::Array { return !operator==(rhs); } }; + + using iterator = typename Common::Array::iterator; + using const_iterator = typename Common::Array::const_iterator; public: typedef T reference; typedef const T const_reference; @@ -97,12 +100,12 @@ class vector : public Common::Array { resize(newSize, elem); } - typename Common::Array::iterator erase(typename Common::Array::iterator pos) { + iterator erase(iterator pos) { return Common::Array::erase(pos); } - typename Common::Array::iterator erase(typename Common::Array::iterator first, - typename Common::Array::iterator last) { + iterator erase(iterator first, + iterator last) { Common::copy(last, this->_storage + this->_size, first); int count = (last - first); @@ -125,7 +128,7 @@ class vector : public Common::Array { * Rotates the array so that the item pointed to by the iterator becomes * the first item, and the predeceding item becomes the last one */ - void rotate(typename Common::Array::iterator it) { + void rotate(iterator it) { if (it != Common::Array::end()) { size_t count = it - Common::Array::begin(); for (size_t ctr = 0; ctr < count; ++ctr) { @@ -165,6 +168,30 @@ class vector : public Common::Array { T at(size_t index) const { return (*this)[index]; } + + /** + * Adds an item to the array + */ + void insert(const T &element) { + Common::Array::push_back(element); + } + + /** + * Adds an item to the array at a specified index + */ + void insert(iterator pos, const T &element) { + Common::Array::insert(pos, element); + } + + /** + * Adds a range of items at the specified position in the array + */ + void insert(iterator position, const_iterator first, const_iterator last) { + int destIndex = position - this->begin(); + for (; first != last; ++first) { + this->insert_at(destIndex++, *first); + } + } }; } // namespace std diff --git a/engines/ags/std/xutility.h b/engines/ags/std/xutility.h index ac5627fbdb0b..e207d7fc66b2 100644 --- a/engines/ags/std/xutility.h +++ b/engines/ags/std/xutility.h @@ -24,10 +24,18 @@ #define AGS_STD_XUTILITY_H #include "common/algorithm.h" +#include "common/util.h" namespace AGS3 { namespace std { +template +void reverse(T *First, T *Last) { + for (; First < Last; ++First, --Last) { + SWAP(*First, *Last); + } +} + } // namespace std } // namespace AGS3 From fbba7ea7c306c38defe6d4cbd67f535132e750af Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 26 Nov 2020 22:10:34 -0800 Subject: [PATCH 038/215] AGS: Warning fixes --- engines/ags/engine/ac/character.cpp | 6 +++--- engines/ags/engine/ac/dialog.cpp | 8 ++++---- engines/ags/engine/ac/display.cpp | 4 ++-- engines/ags/engine/ac/draw.cpp | 4 ++-- engines/ags/engine/ac/dynamicsprite.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_guiobject.cpp | 2 +- .../engine/ac/dynobj/scriptdrawingsurface.cpp | 2 +- engines/ags/engine/ac/game.cpp | 8 ++++---- engines/ags/engine/ac/gamestate.cpp | 2 +- engines/ags/engine/ac/roomobject.cpp | 2 +- engines/ags/engine/main/update.cpp | 18 +++++++++--------- engines/ags/lib/opengl/opengl.h | 8 ++++---- engines/ags/shared/gfx/allegrobitmap.h | 3 +++ 13 files changed, 36 insertions(+), 33 deletions(-) diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index 4d0dc7434c5b..cfee01f260db 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -750,7 +750,7 @@ void Character_SayAt(CharacterInfo *chaa, int x, int y, int width, const char *t ScriptOverlay *Character_SayBackground(CharacterInfo *chaa, const char *texx) { - int ovltype = DisplaySpeechBackground(chaa->index_id, (char *)texx); + int ovltype = DisplaySpeechBackground(chaa->index_id, (const char *)texx); int ovri = find_overlay_of_type(ovltype); if (ovri < 0) quit("!SayBackground internal error: no overlay"); @@ -2291,7 +2291,7 @@ void _DisplayThoughtCore(int chid, const char *displbuf) { ypp = -1; } - _displayspeech((char *)displbuf, chid, xpp, ypp, width, 1); + _displayspeech((const char *)displbuf, chid, xpp, ypp, width, 1); } void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int isThought) { @@ -2448,7 +2448,7 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int if (tdyp < 0) { int sppic = views[speakingChar->view].loops[speakingChar->loop].frames[0].pic; - int height = (charextra[aschar].height < 1) ? game.SpriteInfos[sppic].Height : height = charextra[aschar].height; + int height = (charextra[aschar].height < 1) ? game.SpriteInfos[sppic].Height : charextra[aschar].height; tdyp = view->RoomToScreen(0, data_to_game_coord(game.chars[aschar].get_effective_y()) - height).first.Y - get_fixed_pixel_size(5); if (isThought) // if it's a thought, lift it a bit further up diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 4ccb896ed42f..6c7d6d9f1a40 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -337,7 +337,7 @@ int write_dialog_options(Bitmap *ds, bool ds_has_alpha, int dlgxp, int curyp, in color_t text_color; for (ww = 0; ww < numdisp; ww++) { - if ((dtop->optionflags[disporder[ww]] & DFLG_HASBEENCHOSEN) && + if ((dtop->optionflags[(int)disporder[ww]] & DFLG_HASBEENCHOSEN) && (play.read_dialog_option_colour >= 0)) { // 'read' colour text_color = ds->GetCompatibleColor(play.read_dialog_option_colour); @@ -352,7 +352,7 @@ int write_dialog_options(Bitmap *ds, bool ds_has_alpha, int dlgxp, int curyp, in else text_color = ds->GetCompatibleColor(utextcol); } - break_up_text_into_lines(get_translation(dtop->optionnames[disporder[ww]]), Lines, areawid - (2 * padding + 2 + bullet_wid), usingfont); + break_up_text_into_lines(get_translation(dtop->optionnames[(int)disporder[ww]]), Lines, areawid - (2 * padding + 2 + bullet_wid), usingfont); dispyp[ww] = curyp; if (game.dialog_bullet > 0) { draw_gui_sprite_v330(ds, game.dialog_bullet, dlgxp, curyp, ds_has_alpha); @@ -381,7 +381,7 @@ int write_dialog_options(Bitmap *ds, bool ds_has_alpha, int dlgxp, int curyp, in #define GET_OPTIONS_HEIGHT {\ needheight = 0;\ for (int i = 0; i < numdisp; ++i) {\ - break_up_text_into_lines(get_translation(dtop->optionnames[disporder[i]]), Lines, areawid-(2*padding+2+bullet_wid), usingfont);\ + break_up_text_into_lines(get_translation(dtop->optionnames[(int)disporder[i]]), Lines, areawid-(2*padding+2+bullet_wid), usingfont);\ needheight += getheightoflines(usingfont, Lines.Count()) + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ }\ if (parserInput) needheight += parserInput->Height + data_to_game_coord(game.options[OPT_DIALOGGAP]);\ @@ -664,7 +664,7 @@ void DialogOptions::Redraw() { int biggest = 0; padding = guis[game.options[OPT_DIALOGIFACE]].Padding; for (int i = 0; i < numdisp; ++i) { - break_up_text_into_lines(get_translation(dtop->optionnames[disporder[i]]), Lines, areawid - ((2 * padding + 2) + bullet_wid), usingfont); + break_up_text_into_lines(get_translation(dtop->optionnames[(int)disporder[i]]), Lines, areawid - ((2 * padding + 2) + bullet_wid), usingfont); if (longestline > biggest) biggest = longestline; } diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp index 7f4574138a21..9a21e70eae0c 100644 --- a/engines/ags/engine/ac/display.cpp +++ b/engines/ags/engine/ac/display.cpp @@ -553,7 +553,7 @@ void wouttext_aligned(Bitmap *ds, int usexp, int yy, int oriwid, int usingfont, else if (align & kMAlignRight) usexp = usexp + (oriwid - wgettextwidth_compensate(text, usingfont)); - wouttext_outline(ds, usexp, yy, usingfont, text_color, (char *)text); + wouttext_outline(ds, usexp, yy, usingfont, text_color, (const char *)text); } // Get outline's thickness addition to the font's width or height @@ -633,7 +633,7 @@ void draw_button_background(Bitmap *ds, int xx1, int yy1, int xx2, int yy2, GUIM if ((loaded_game_file_version <= kGameVersion_272) // 2.xx && (spriteset[iep->BgImage]->GetWidth() == 1) && (spriteset[iep->BgImage]->GetHeight() == 1) - && (*((unsigned int *)spriteset[iep->BgImage]->GetData()) == 0x00FF00FF)) { + && (*((const unsigned int *)spriteset[iep->BgImage]->GetData()) == 0x00FF00FF)) { // Don't draw fully transparent dummy GUI backgrounds } else { // offset the background image and clip it so that it is drawn diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index 6e451c414d48..8f824f35c796 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -255,7 +255,7 @@ Bitmap *convert_32_to_32bgr(Bitmap *tempbl) { // Bitmap *AdjustBitmapForUseWithDisplayMode(Bitmap *bitmap, bool has_alpha) { const int bmp_col_depth = bitmap->GetColorDepth(); - const int sys_col_depth = System_GetColorDepth(); + //const int sys_col_depth = System_GetColorDepth(); const int game_col_depth = game.GetColorDepth(); Bitmap *new_bitmap = bitmap; @@ -661,7 +661,7 @@ void mark_current_background_dirty() { void draw_and_invalidate_text(Bitmap *ds, int x1, int y1, int font, color_t text_color, const char *text) { - wouttext_outline(ds, x1, y1, font, text_color, (char *)text); + wouttext_outline(ds, x1, y1, font, text_color, (const char *)text); invalidate_rect(x1, y1, x1 + wgettextwidth_compensate(text, font), y1 + getfontheight_outlined(font) + get_fixed_pixel_size(1), false); } diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp index 2d78b61869dc..1cafa991664f 100644 --- a/engines/ags/engine/ac/dynamicsprite.cpp +++ b/engines/ags/engine/ac/dynamicsprite.cpp @@ -276,7 +276,7 @@ int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char *namm) { quit("!DynamicSprite.SaveToFile: sprite has been deleted"); auto filename = String(namm); - if (filename.FindChar('.') == -1) + if (filename.FindChar('.') == String::npos) filename.Append(".bmp"); ResolvedPath rp; diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp index e8c0e350913f..0f0a9a5abc43 100644 --- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp @@ -37,7 +37,7 @@ const char *CCGUIObject::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCGUIObject::Serialize(const char *address, char *buffer, int bufsize) { - GUIObject *guio = (GUIObject *)address; + const GUIObject *guio = (const GUIObject *)address; StartSerialize(buffer); SerializeInt(guio->ParentId); SerializeInt(guio->Id); diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp index 041a9f7aad4d..4c19c95c6745 100644 --- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp +++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp @@ -84,7 +84,7 @@ const char *ScriptDrawingSurface::GetType() { int ScriptDrawingSurface::Serialize(const char *address, char *buffer, int bufsize) { StartSerialize(buffer); - SerializeInt(roomBackgroundNumber & 0xFFFF | (roomMaskType << 16)); + SerializeInt((roomBackgroundNumber & 0xFFFF) | (roomMaskType << 16)); SerializeInt(dynamicSpriteNumber); SerializeInt(dynamicSurfaceNumber); SerializeInt(currentColour); diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 4b988ef1c300..b1f40dc1aa7e 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -931,7 +931,7 @@ void convert_guid_from_text_to_binary(const char *guidText, unsigned char *buffe tempString[1] = guidText[1]; tempString[2] = 0; int thisByte = 0; - sscanf(tempString, "%X", &thisByte); + sscanf(tempString, "%X", (unsigned int *)&thisByte); buffer[bytesDone] = thisByte; guidText += 2; @@ -1392,7 +1392,7 @@ HSaveError restore_game_audioclips_and_crossfade(Stream *in, RestoredData &r_dat chan_info.Pos = 0; chan_info.ClipID = in->ReadInt32(); if (chan_info.ClipID >= 0) { - if ((size_t)chan_info.ClipID >= (int)game.audioClips.size()) { + if (chan_info.ClipID >= (int)game.audioClips.size()) { return new SavegameError(kSvgErr_GameObjectInitFailed, "Invalid audio clip index."); } @@ -1500,7 +1500,7 @@ HSaveError restore_game_data(Stream *in, SavegameVersion svg_version, const Pres if (!err) return err; - if (in->ReadInt32() != MAGICNUMBER + 1) { + if (in->ReadInt32() != (int32)(MAGICNUMBER + 1)) { return new SavegameError(kSvgErr_InconsistentFormat, "MAGICNUMBER not found before Audio Clips."); } @@ -1512,7 +1512,7 @@ HSaveError restore_game_data(Stream *in, SavegameVersion svg_version, const Pres pl_set_file_handle(pluginFileHandle, in); pl_run_plugin_hooks(AGSE_RESTOREGAME, pluginFileHandle); pl_clear_file_handle(); - if (in->ReadInt32() != (unsigned)MAGICNUMBER) + if (in->ReadInt32() != (int32)MAGICNUMBER) return new SavegameError(kSvgErr_InconsistentPlugin); // save the new room music vol for later use diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index 889c3a5d45a0..125f211b533c 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -139,7 +139,7 @@ void GameState::UpdateViewports() { vp->ClearChangedFlags(); } } - if (vp_changed != -1) + if (vp_changed != (size_t)-1) detect_roomviewport_overlaps(vp_changed); for (auto cam : _roomCameras) { if (cam->HasChangedSize() || cam->HasChangedPosition()) { diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp index 806420119793..858ab3737d84 100644 --- a/engines/ags/engine/ac/roomobject.cpp +++ b/engines/ags/engine/ac/roomobject.cpp @@ -162,7 +162,7 @@ void RoomObject::ReadFromFile(Stream *in) { void RoomObject::WriteToFile(Stream *out) const { out->WriteArrayOfInt32(&x, 3); out->WriteArrayOfInt16(&tint_r, 15); - out->WriteArrayOfInt8((int8_t *)&cycling, 4); + out->WriteArrayOfInt8((const int8_t *)&cycling, 4); out->WriteArrayOfInt16(&blocking_width, 2); } diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp index 9ace25d19850..4f8298bc8fca 100644 --- a/engines/ags/engine/main/update.cpp +++ b/engines/ags/engine/main/update.cpp @@ -96,21 +96,21 @@ int do_movelist_move(short *mlnum, int *xx, int *yy) { int adjAmnt = 3; // 2.70: if the X permove is also <=1, don't do the skipping - if (((xpermove & 0xffff0000) == 0xffff0000) || - ((xpermove & 0xffff0000) == 0x00000000)) + if ((((uint32)xpermove & 0xffff0000) == 0xffff0000) || + (((uint32)xpermove & 0xffff0000) == 0x00000000)) adjAmnt = 2; // 2.61 RC1: correct this to work with > -1 as well as < 1 if (ypermove == 0) { } // Y per move is < 1, so finish the move - else if ((ypermove & 0xffff0000) == 0) + else if (((uint32)ypermove & 0xffff0000) == 0) targety -= adjAmnt; // Y per move is -1 exactly, don't snap to finish - else if (ypermove == 0xffff0000) { + else if ((uint32)ypermove == 0xffff0000) { } // Y per move is > -1, so finish the move - else if ((ypermove & 0xffff0000) == 0xffff0000) + else if (((uint32)ypermove & 0xffff0000) == 0xffff0000) targety += adjAmnt; } else xps = cmls->fromx + (int)(fixtof(xpermove) * (float)cmls->onpart); @@ -120,20 +120,20 @@ int do_movelist_move(short *mlnum, int *xx, int *yy) { int adjAmnt = 3; // if the Y permove is also <=1, don't skip as far - if (((ypermove & 0xffff0000) == 0xffff0000) || + if ((((uint32)ypermove & 0xffff0000) == 0xffff0000) || ((ypermove & 0xffff0000) == 0x00000000)) adjAmnt = 2; if (xpermove == 0) { } // Y per move is < 1, so finish the move - else if ((xpermove & 0xffff0000) == 0) + else if (((uint32)xpermove & 0xffff0000) == 0) targetx -= adjAmnt; // X per move is -1 exactly, don't snap to finish - else if (xpermove == 0xffff0000) { + else if ((uint32)xpermove == 0xffff0000) { } // X per move is > -1, so finish the move - else if ((xpermove & 0xffff0000) == 0xffff0000) + else if (((uint32)xpermove & 0xffff0000) == 0xffff0000) targetx += adjAmnt; /* int xpmm=(xpermove >> 16) & 0x0000ffff; diff --git a/engines/ags/lib/opengl/opengl.h b/engines/ags/lib/opengl/opengl.h index 3e6ecd89cf23..2525645547c1 100644 --- a/engines/ags/lib/opengl/opengl.h +++ b/engines/ags/lib/opengl/opengl.h @@ -122,7 +122,7 @@ inline void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {} inline void glMatrixMode(GLenum mode) {} inline void glLoadIdentity() {} inline void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, - GLdouble nearVal, GLdouble farVal); + GLdouble nearVal, GLdouble farVal) {} inline void glEnableClientState(GLenum arr) {} inline void glDisableClientState(GLenum arr) {} inline void glUseProgram(GLuint program) {} @@ -131,10 +131,10 @@ inline void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {} inline void glUniform1i(GLint location, GLint v0) {} inline void glTranslatef(GLfloat x, GLfloat y, GLfloat z) {} inline void glMultMatrixf(const GLfloat *m) {} -inline void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -inline void glScalef(GLfloat x, GLfloat y, GLfloat z); +inline void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {} +inline void glScalef(GLfloat x, GLfloat y, GLfloat z) {} inline void glBindTexture(GLenum target, GLuint texture) {} -inline void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); +inline void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {} inline void glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {} inline void glBindFramebufferEXT(GLenum v1, uint v2) {} inline void glDeleteFramebuffersEXT(int v1, uint *v2) {} diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 37ba3fcd978d..3b04c369eb71 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -132,6 +132,9 @@ class Bitmap { inline const unsigned char *GetScanLine(int index) const { return (index >= 0 && index < GetHeight()) ? _alBitmap->getBasePtr(0, index) : nullptr; } + inline unsigned char *GetScanLine(int index) { + return (index >= 0 && index < GetHeight()) ? (unsigned char *)_alBitmap->getBasePtr(0, index) : nullptr; + } void SetMaskColor(color_t color); inline color_t GetMaskColor() const { From 5b50e2627cd57e528de73b9ca0ea41b588f3eb6c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 11:35:34 -0800 Subject: [PATCH 039/215] AGS: Added shared/font/ folder --- engines/ags/engine/font/fonts_engine.cpp | 2 +- engines/ags/lib/alfont/alfont.cpp | 82 +++++++++++++++++++++ engines/ags/lib/alfont/alfont.h | 65 ++++++++++++++++ engines/ags/lib/allegro/gfx.h | 1 - engines/ags/module.mk | 5 ++ engines/ags/shared/font/fonts.cpp | 11 ++- engines/ags/shared/font/ttffontrenderer.cpp | 18 +---- engines/ags/shared/font/ttffontrenderer.h | 5 +- engines/ags/shared/font/wfnfont.cpp | 7 +- engines/ags/shared/font/wfnfontrenderer.h | 2 +- engines/ags/std/algorithm.h | 31 ++++++++ 11 files changed, 201 insertions(+), 28 deletions(-) create mode 100644 engines/ags/lib/alfont/alfont.cpp create mode 100644 engines/ags/lib/alfont/alfont.h diff --git a/engines/ags/engine/font/fonts_engine.cpp b/engines/ags/engine/font/fonts_engine.cpp index b52947b26cda..cd608b7a97c0 100644 --- a/engines/ags/engine/font/fonts_engine.cpp +++ b/engines/ags/engine/font/fonts_engine.cpp @@ -26,7 +26,7 @@ // //============================================================================= -//include +#include "ags/lib/alfont/alfont.h" #include "ags/shared/ac/gamesetupstruct.h" namespace AGS3 { diff --git a/engines/ags/lib/alfont/alfont.cpp b/engines/ags/lib/alfont/alfont.cpp new file mode 100644 index 000000000000..3a69e8e7b42d --- /dev/null +++ b/engines/ags/lib/alfont/alfont.cpp @@ -0,0 +1,82 @@ +/* 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 "ags/lib/alfont/alfont.h" +#include "common/file.h" +#include "graphics/fonts/ttf.h" + +namespace AGS3 { + +Graphics::Font *ALFONT_FONT::getFont() { + if (!_fonts.contains(_size)) { + Common::File f; + if (!f.open(_filename)) + error("Could not read font - %s", _filename.c_str()); + _fonts[_size] = Graphics::loadTTFFont(f, f.size()); + f.close(); + + assert(_fonts[_size]); + } + + return _fonts[_size]; +} + +/*------------------------------------------------------------------*/ + +ALFONT_FONT *alfont_loadFont(const Common::String &filename) { + ALFONT_FONT *result = new ALFONT_FONT(); + result->_filename = filename; + + return result; +} + +void alfont_destroy_font(ALFONT_FONT *font) { + delete font; +} + +size_t alfont_text_length(ALFONT_FONT *font, const char *text) { + return font->getFont()->getStringWidth(text); +} + +size_t alfont_text_height(ALFONT_FONT *font) { + return font->getFont()->getFontHeight(); +} + +void alfont_textout(BITMAP *bmp, ALFONT_FONT *font, const char *text, int x, int y, uint32 color) { + Graphics::ManagedSurface &surf = **bmp; + font->getFont()->drawString(&surf, Common::U32String(text), x, y, bmp->w - x, color); +} + +void alfont_textout_aa(BITMAP *bmp, ALFONT_FONT *font, const char *text, int x, int y, uint32 color) { + alfont_textout(bmp, font, text, x, y, color); +} + +void alfont_set_font_size(ALFONT_FONT *font, int size) { + font->_size = size; +} + +const char *alfont_get_name(ALFONT_FONT *font) { + // TODO: Return ttf font name + return "Unsupported"; +} + +} // namespace AGS3 diff --git a/engines/ags/lib/alfont/alfont.h b/engines/ags/lib/alfont/alfont.h new file mode 100644 index 000000000000..d3f92e245147 --- /dev/null +++ b/engines/ags/lib/alfont/alfont.h @@ -0,0 +1,65 @@ +/* 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 AGS_LIB_ALFONT_H +#define AGS_LIB_ALFONT_H + +#include "common/hashmap.h" +#include "graphics/font.h" +#include "ags/lib/allegro/gfx.h" + +namespace AGS3 { + +struct ALFONT_FONT { + Common::String _filename; + int _size; + Common::HashMap _fonts; + + ALFONT_FONT() : _size(-1) {} + ALFONT_FONT(const Common::String &filename) : _filename(filename), _size(-1) {} + + ~ALFONT_FONT() { + for (Common::HashMap::iterator it = _fonts.begin(); + it != _fonts.end(); ++it) + delete (*it)._value; + } + + Graphics::Font *getFont(); +}; + +inline void alfont_init() {} +inline void alfont_exit() {} +inline void alfont_text_mode(int val) {} +extern ALFONT_FONT *alfont_loadFont(const Common::String &filename); +extern void alfont_destroy_font(ALFONT_FONT *font); + +extern size_t alfont_text_length(ALFONT_FONT *font, const char *text); +extern size_t alfont_text_height(ALFONT_FONT *font); +extern void alfont_textout(BITMAP *bmp, ALFONT_FONT *font, const char *text, int x, int y, uint32 color); +extern void alfont_textout_aa(BITMAP *bmp, ALFONT_FONT *font, const char *text, int x, int y, uint32 color); +extern const char *alfont_get_name(ALFONT_FONT *font); +extern void alfont_set_font_size(ALFONT_FONT *font, int size); + + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index 66dbdc3be31e..11a1c07a1624 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -225,7 +225,6 @@ AL_FUNC(void, release_bitmap, (BITMAP *bitmap)); AL_FUNC(void, draw_sprite, (BITMAP *bmp, const BITMAP *sprite, int x, int y)); AL_FUNC(void, stretch_sprite, (BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h)); - extern void clear_to_color(BITMAP *bitmap, int color); extern int bitmap_color_depth(BITMAP *bmp); extern int bitmap_mask_color(BITMAP *bmp); diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 4806c7b00af1..f1e905fb1ab8 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS = \ lib/aastr-0.1.1/aarot.o \ lib/aastr-0.1.1/aastr.o \ lib/aastr-0.1.1/aautil.o \ + lib/alfont/alfont.o \ lib/allegro.o \ lib/allegro/color.o \ lib/allegro/config.o \ @@ -38,6 +39,10 @@ MODULE_OBJS = \ shared/core/asset.o \ shared/core/assetmanager.o \ shared/debugging/debugmanager.o \ + shared/font/fonts.o \ + shared/font/ttffontrenderer.o \ + shared/font/wfnfont.o \ + shared/font/wfnfontrenderer.o \ shared/game/customproperties.o \ shared/game/interactions.o \ shared/game/room_file.o \ diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 0bc9c8505c63..ad4c4c5ab2a6 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -20,9 +20,8 @@ * */ -//include #include "ags/std/vector.h" -//include +#include "ags/lib/alfont/alfont.h" #include "ags/shared/ac/common.h" // set_our_eip #include "ags/shared/ac/gamestructdefines.h" #include "ags/shared/font/fonts.h" @@ -241,7 +240,7 @@ size_t split_lines(const char *todis, SplitLines &lines, int wii, int fonnt, siz size_t splitAt; char nextCharWas; while (1) { - splitAt = -1; + splitAt = (size_t)-1; if (theline[i] == 0) { // end of the text, add the last line if necessary @@ -294,7 +293,7 @@ size_t split_lines(const char *todis, SplitLines &lines, int wii, int fonnt, siz // skip the space or new line that caused the line break if ((theline[0] == ' ') || (theline[0] == '\n')) theline++; - i = -1; + i = (size_t)-1; } i++; @@ -302,7 +301,7 @@ size_t split_lines(const char *todis, SplitLines &lines, int wii, int fonnt, siz return lines.Count(); } -void wouttextxy(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx) { +void wouttextxy(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, const char *texx) { if (fontNumber >= fonts.size()) return; yyy += fonts[fontNumber].Info.YOffset; @@ -343,7 +342,7 @@ bool wloadfont_size(size_t fontNumber, const FontInfo &font_info) { return false; } -void wgtprintf(Common::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...) { +void wgtprintf(Shared::Bitmap *ds, int xxx, int yyy, size_t fontNumber, color_t text_color, char *fmt, ...) { if (fontNumber >= fonts.size()) return; diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp index dfbf669d2173..34a5489fa951 100644 --- a/engines/ags/shared/font/ttffontrenderer.cpp +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -20,7 +20,8 @@ * */ -//include +#include "ags/lib/alfont/alfont.h" +#include "ags/lib/allegro/gfx.h" #include "ags/shared/core/platform.h" #define AGS_OUTLINE_FONT_FIX (!AGS_PLATFORM_OS_WINDOWS) @@ -91,21 +92,8 @@ bool TTFFontRenderer::IsBitmapFont() { bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) { String file_name = String::FromFormat("agsfnt%d.ttf", fontNumber); - Stream *reader = AssetManager::OpenAsset(file_name); - char *membuffer; - - if (reader == nullptr) - return false; - - long lenof = AssetManager::GetLastAssetSize(); - - membuffer = (char *)malloc(lenof); - reader->ReadArray(membuffer, lenof, 1); - delete reader; - - ALFONT_FONT *alfptr = alfont_load_font_from_mem(membuffer, lenof); - free(membuffer); + ALFONT_FONT *alfptr = alfont_loadFont(file_name); if (alfptr == nullptr) return false; diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 38e1fab00fae..368dac016ec3 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -23,13 +23,12 @@ #ifndef AGS_SHARED_FONT_TTFFONTRENDERER_H #define AGS_SHARED_FONT_TTFFONTRENDERER_H -//include +#include "ags/std/map.h" +#include "ags/lib/alfont/alfont.h" #include "ags/shared/font/agsfontrenderer.h" namespace AGS3 { -struct ALFONT_FONT; - class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { public: // IAGSFontRenderer implementation diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index ce76cda9e30e..c98d5e3d1ced 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -109,7 +109,12 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { } // sort offsets vector and remove any duplicates std::sort(offs.begin(), offs.end()); +#if AGS_PLATFORM_SCUMMVM + // TODO: See if this works correctly + std::unique(offs.begin(), offs.end()); +#else std::vector(offs.begin(), std::unique(offs.begin(), offs.end())).swap(offs); +#endif // Now that we know number of valid character items, parse and store character data WFNChar init_ch; @@ -155,7 +160,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { _items[i].RestrictToBytes(src_size); assert(pixel_it + pixel_data_size <= _pixelData.end()); // should not normally fail - std::copy(raw_data + raw_off, raw_data + raw_off + src_size, pixel_it); + Common::copy(raw_data + raw_off, raw_data + raw_off + src_size, pixel_it); _items[i].Data = &(*pixel_it); pixel_it += pixel_data_size; } diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index 25fe6930d4da..76d57efe9b5b 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_FONT_WFNFONTRENDERER_H #define AGS_SHARED_FONT_WFNFONTRENDERER_H -//include +#include "ags/std/map.h" #include "ags/shared/font/agsfontrenderer.h" namespace AGS3 { diff --git a/engines/ags/std/algorithm.h b/engines/ags/std/algorithm.h index 6e02eed2c3e0..f95335f35180 100644 --- a/engines/ags/std/algorithm.h +++ b/engines/ags/std/algorithm.h @@ -56,6 +56,37 @@ void sort(T first, T last) { Common::sort(first, last); } +template +T unique(T first, T last) { + T pos; + for (pos = first + 1; pos < last; ++pos) { + // Check for duplicate + for (T existingPos = first; existingPos < last; ++existingPos) { + if (*pos == *existingPos) { + // Found a match, so shift values over the duplicate + while (pos < (last - 1)) { + *pos++ = *(pos + 1); + } + + --last; + break; + } + } + } + + return pos; +} + +template +ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T &value) { + for (ForwardIt it = first; it < last; ++it) { + if (*it >= value) + return it; + } + + return last; +} + } // namespace std } // namespace AGS3 From 06679735e379aa70bb57e57166de7b0078632403 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 16:07:10 -0800 Subject: [PATCH 040/215] AGS: Added engine/media/audio/ folder --- engines/ags/configure.engine | 2 +- .../ags/engine/media/audio/ambientsound.cpp | 6 +- engines/ags/engine/media/audio/audio.cpp | 46 +++--- .../ags/engine/media/audio/clip_mydumbmod.cpp | 6 +- .../ags/engine/media/audio/clip_mydumbmod.h | 4 +- .../ags/engine/media/audio/clip_myjgmod.cpp | 6 +- engines/ags/engine/media/audio/clip_myjgmod.h | 4 +- .../ags/engine/media/audio/clip_mymidi.cpp | 10 +- engines/ags/engine/media/audio/clip_mymidi.h | 2 +- engines/ags/engine/media/audio/clip_mymp3.cpp | 16 +- engines/ags/engine/media/audio/clip_mymp3.h | 5 +- engines/ags/engine/media/audio/clip_myogg.cpp | 24 ++- engines/ags/engine/media/audio/clip_myogg.h | 5 +- .../engine/media/audio/clip_mystaticmp3.cpp | 12 +- .../ags/engine/media/audio/clip_mystaticmp3.h | 4 +- .../engine/media/audio/clip_mystaticogg.cpp | 21 +-- .../ags/engine/media/audio/clip_mystaticogg.h | 4 +- .../ags/engine/media/audio/clip_mywave.cpp | 13 +- engines/ags/engine/media/audio/clip_mywave.h | 2 +- .../engine/media/audio/queuedaudioitem.cpp | 2 +- engines/ags/engine/media/audio/sound.cpp | 33 ++-- engines/ags/engine/media/audio/soundcache.cpp | 10 +- engines/ags/engine/media/audio/soundclip.cpp | 8 +- engines/ags/lib/allegro.h | 7 +- engines/ags/lib/allegro/sound.cpp | 12 +- engines/ags/lib/audio/digi.cpp | 90 +++++++++++ engines/ags/lib/{allegro => audio}/digi.h | 19 ++- engines/ags/lib/{allegro => audio}/midi.cpp | 39 ++++- engines/ags/lib/{allegro => audio}/midi.h | 13 +- engines/ags/lib/audio/mod.cpp | 34 ++++ .../ags/lib/{allegro/digi.cpp => audio/mod.h} | 20 +-- engines/ags/lib/audio/mp3.cpp | 117 ++++++++++++++ engines/ags/lib/audio/mp3.h | 64 ++++++++ engines/ags/lib/audio/ogg.cpp | 146 ++++++++++++++++++ engines/ags/lib/audio/ogg.h | 76 +++++++++ engines/ags/lib/audio/sound.cpp | 108 +++++++++++++ engines/ags/lib/{allegro => audio}/sound.h | 13 ++ engines/ags/lib/audio/wav.cpp | 31 ++++ engines/ags/lib/audio/wav.h | 34 ++++ engines/ags/module.mk | 24 ++- 40 files changed, 939 insertions(+), 153 deletions(-) create mode 100644 engines/ags/lib/audio/digi.cpp rename engines/ags/lib/{allegro => audio}/digi.h (89%) rename engines/ags/lib/{allegro => audio}/midi.cpp (71%) rename engines/ags/lib/{allegro => audio}/midi.h (92%) create mode 100644 engines/ags/lib/audio/mod.cpp rename engines/ags/lib/{allegro/digi.cpp => audio/mod.h} (84%) create mode 100644 engines/ags/lib/audio/mp3.cpp create mode 100644 engines/ags/lib/audio/mp3.h create mode 100644 engines/ags/lib/audio/ogg.cpp create mode 100644 engines/ags/lib/audio/ogg.h create mode 100644 engines/ags/lib/audio/sound.cpp rename engines/ags/lib/{allegro => audio}/sound.h (90%) create mode 100644 engines/ags/lib/audio/wav.cpp create mode 100644 engines/ags/lib/audio/wav.h diff --git a/engines/ags/configure.engine b/engines/ags/configure.engine index 55cba93bb428..6149895b719c 100644 --- a/engines/ags/configure.engine +++ b/engines/ags/configure.engine @@ -1,3 +1,3 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine ags "Adventure Game Studio" no "" "" "cxx11" +add_engine ags "Adventure Game Studio" no "" "" "cxx11 mp3 ogg" diff --git a/engines/ags/engine/media/audio/ambientsound.cpp b/engines/ags/engine/media/audio/ambientsound.cpp index 94e1e0cbb60e..4010abc0dd67 100644 --- a/engines/ags/engine/media/audio/ambientsound.cpp +++ b/engines/ags/engine/media/audio/ambientsound.cpp @@ -20,9 +20,9 @@ * */ -#include "ags/shared/media/audio/ambientsound.h" -#include "ags/shared/media/audio/audio.h" -#include "ags/shared/media/audio/soundclip.h" +#include "ags/engine/media/audio/ambientsound.h" +#include "ags/engine/media/audio/audio.h" +#include "ags/engine/media/audio/soundclip.h" #include "ags/shared/util/stream.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 414db622ae21..0d4ca41d3b2b 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -20,32 +20,30 @@ * */ -//include - #include "ags/shared/core/platform.h" #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/media/audio/audio.h" +#include "ags/engine/media/audio/audio.h" #include "ags/shared/ac/audiocliptype.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/dynobj/cc_audioclip.h" -#include "ags/shared/ac/dynobj/cc_audiochannel.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/audiochannel.h" -#include "ags/shared/ac/audioclip.h" -#include "ags/shared/ac/gamesetup.h" -#include "ags/shared/ac/path_helper.h" -#include "ags/shared/media/audio/sound.h" -#include "ags/shared/debugging/debug_log.h" -#include "ags/shared/debugging/debugger.h" +#include "ags/engine/ac/dynobj/cc_audioclip.h" +#include "ags/engine/ac/dynobj/cc_audiochannel.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/audiochannel.h" +#include "ags/engine/ac/audioclip.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/engine/ac/path_helper.h" +#include "ags/engine/media/audio/sound.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/file.h" -#include "ags/shared/ac/global_audio.h" -//include +#include "ags/engine/ac/file.h" +#include "ags/engine/ac/global_audio.h" #include "ags/shared/util/stream.h" #include "ags/shared/core/assetmanager.h" -#include "ags/shared/ac/timer.h" -#include "ags/shared/main/game_run.h" +#include "ags/engine/ac/timer.h" +#include "ags/engine/main/game_run.h" +#include "ags/lib/audio/sound.h" namespace AGS3 { @@ -55,7 +53,7 @@ using namespace AGS::Engine; //----------------------- //sound channel management; all access goes through here, which can't be done without a lock -static std::array < SOUNDCLIP *, MAX_SOUND_CHANNELS + 1 > _channels; +static std::array _channels(MAX_SOUND_CHANNELS + 1); AGS::Engine::Mutex AudioChannelsLock::s_mutex; SOUNDCLIP *AudioChannelsLock::GetChannel(int index) { @@ -546,7 +544,7 @@ void force_audiostream_include() { } // TODO: double check that ambient sounds array actually needs +1 -std::array < AmbientSound, MAX_SOUND_CHANNELS + 1 > ambient; +std::array ambient(MAX_SOUND_CHANNELS + 1); int get_volume_adjusted_for_distance(int volume, int sndX, int sndY, int sndMaxDist) { int distx = playerchar->x - sndX; @@ -682,9 +680,9 @@ static int play_sound_priority(int val1, int priority) { if (usechan >= 0) { // channel will hold a different clip here assert(usechan == i); - auto *ch = lock.GetChannel(usechan); - if (ch) - ch->priority = priority; + auto *chan = lock.GetChannel(usechan); + if (chan) + chan->priority = priority; } return usechan; } else if (ch->priority < lowest_pri) { diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp index d863bce0dca7..d5c2262379e0 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.cpp +++ b/engines/ags/engine/media/audio/clip_mydumbmod.cpp @@ -20,12 +20,12 @@ * */ -#include "ags/shared/media/audio/audiodefines.h" +#include "ags/engine/media/audio/audiodefines.h" #ifdef DUMB_MOD_PLAYER -#include "ags/shared/media/audio/clip_mydumbmod.h" -#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/clip_mydumbmod.h" +#include "ags/engine/media/audio/audiointernaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index fcd2f6cb7414..927eee6f8991 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H -#include "ags/shared/aldumb.h" -#include "ags/shared/media/audio/soundclip.h" +#include "ags/lib/aldumb.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_myjgmod.cpp b/engines/ags/engine/media/audio/clip_myjgmod.cpp index 6f1fed049206..73fd0004dea9 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.cpp +++ b/engines/ags/engine/media/audio/clip_myjgmod.cpp @@ -20,12 +20,12 @@ * */ -#include "ags/shared/media/audio/audiodefines.h" +#include "ags/engine/media/audio/audiodefines.h" #ifdef JGMOD_MOD_PLAYER -#include "ags/shared/media/audio/clip_myjgmod.h" -#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/clip_myjgmod.h" +#include "ags/engine/media/audio/audiointernaldefs.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_myjgmod.h b/engines/ags/engine/media/audio/clip_myjgmod.h index 16494928238c..ad5058e8d47f 100644 --- a/engines/ags/engine/media/audio/clip_myjgmod.h +++ b/engines/ags/engine/media/audio/clip_myjgmod.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYJGMOD_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYJGMOD_H -#include "ags/shared/jgmod.h" -#include "ags/shared/media/audio/soundclip.h" +#include "ags/lib/audio/mod.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index ed60c2f25c3b..2dfbb7204136 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -20,10 +20,10 @@ * */ -#include "ags/shared/media/audio/audiodefines.h" +#include "ags/engine/media/audio/audiodefines.h" #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/media/audio/clip_mymidi.h" -#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/clip_mymidi.h" +#include "ags/engine/media/audio/audiointernaldefs.h" namespace AGS3 { @@ -40,7 +40,7 @@ void MYMIDI::adjust_volume() { if (!is_playing()) { return; } - ::set_volume(-1, get_final_volume()); + AGS3::set_volume(-1, get_final_volume()); } void MYMIDI::set_volume(int newvol) { @@ -112,7 +112,7 @@ int MYMIDI::play() { } lengthInSeconds = get_midi_length(tune); - if (::play_midi(tune, repeat)) { + if (AGS3::play_midi(tune, repeat)) { return 0; } diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index 8a802867b399..87e21d770409 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMIDI_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMIDI_H -#include "ags/shared/media/audio/soundclip.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp index 0519eb413d7d..66e9674d3d13 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -20,17 +20,17 @@ * */ -#include "ags/shared/media/audio/audiodefines.h" +#include "ags/engine/media/audio/audiodefines.h" #ifndef NO_MP3_PLAYER -#include "ags/shared/media/audio/clip_mymp3.h" -#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/clip_mymp3.h" +#include "ags/engine/media/audio/audiointernaldefs.h" #include "ags/shared/ac/common.h" // quit() -#include "ags/shared/ac/asset_helper.h" -#include "ags/shared/util/mutex_lock.h" +#include "ags/engine/ac/asset_helper.h" +#include "ags/engine/util/mutex_lock.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { @@ -38,7 +38,7 @@ void MYMP3::poll() { if (state_ != SoundClipPlaying) { return; } - +#if !AGS_PLATFORM_SCUMMVM // update the buffer char *tempbuf = nullptr; { @@ -60,7 +60,7 @@ void MYMP3::poll() { almp3_free_mp3stream_buffer(stream, free_val); } } - +#endif { AGS::Engine::MutexLock _lockMp3(_mp3_mutex); if (almp3_poll_mp3stream(stream) == ALMP3_POLL_PLAYJUSTFINISHED) { diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index cdd034b9bbd7..787bd5a3f39a 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -23,8 +23,9 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H -#include "ags/shared/almp3.h" -#include "ags/shared/media/audio/soundclip.h" +#include "ags/lib/audio/mp3.h" +#include "ags/lib/allegro/file.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp index 6c5539d1bffb..c2c16a770de8 100644 --- a/engines/ags/engine/media/audio/clip_myogg.cpp +++ b/engines/ags/engine/media/audio/clip_myogg.cpp @@ -20,29 +20,23 @@ * */ -#include "ags/shared/media/audio/audiodefines.h" -#include "ags/shared/media/audio/clip_myogg.h" -#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/lib/audio/digi.h" +#include "ags/engine/media/audio/audiodefines.h" +#include "ags/engine/media/audio/clip_myogg.h" +#include "ags/engine/media/audio/audiointernaldefs.h" #include "ags/shared/ac/common.h" // quit() -#include "ags/shared/ac/asset_helper.h" -#include "ags/shared/util/mutex_lock.h" +#include "ags/engine/ac/asset_helper.h" +#include "ags/engine/util/mutex_lock.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { -extern "C" { - extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); - extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); - extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); - extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); -} - void MYOGG::poll() { if (state_ != SoundClipPlaying) { return; } - +#if !AGS_PLATFORM_SCUMMVM AGS_PACKFILE_OBJ *obj = (AGS_PACKFILE_OBJ *)in->userdata; if (obj->remains > 0) { // update the buffer @@ -57,7 +51,7 @@ void MYOGG::poll() { alogg_free_oggstream_buffer(stream, free_val); } } - +#endif int ret = alogg_poll_oggstream(stream); if (ret == ALOGG_OK || ret == ALOGG_POLL_BUFFERUNDERRUN) get_pos_ms(); // call this to keep the last_but_one stuff up to date diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h index 0341caec08db..951ae336b3a2 100644 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -23,8 +23,9 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H -#include "ags/shared/alogg.h" -#include "ags/shared/media/audio/soundclip.h" +#include "ags/lib/audio/ogg.h" +#include "ags/lib/allegro/file.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp index f653f3d1b17a..9f27f5546109 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -20,16 +20,16 @@ * */ -#include "ags/shared/media/audio/audiodefines.h" +#include "ags/engine/media/audio/audiodefines.h" #ifndef NO_MP3_PLAYER -#include "ags/shared/media/audio/clip_mystaticmp3.h" -#include "ags/shared/media/audio/audiointernaldefs.h" -#include "ags/shared/media/audio/soundcache.h" -#include "ags/shared/util/mutex_lock.h" +#include "ags/engine/media/audio/clip_mystaticmp3.h" +#include "ags/engine/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/soundcache.h" +#include "ags/engine/util/mutex_lock.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index 7f1313d13731..c849a1803bd8 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H -#include "ags/shared/almp3.h" -#include "ags/shared/media/audio/soundclip.h" +#include "ags/lib/audio/mp3.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp index 5cbbb79a6f44..84654620ce4b 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticogg.cpp @@ -20,23 +20,18 @@ * */ -#include "ags/shared/media/audio/audiodefines.h" -#include "ags/shared/media/audio/clip_mystaticogg.h" -#include "ags/shared/media/audio/audiointernaldefs.h" -#include "ags/shared/media/audio/soundcache.h" -#include "ags/shared/util/mutex_lock.h" +#include "ags/engine/media/audio/audiodefines.h" +#include "ags/engine/media/audio/clip_mystaticogg.h" +#include "ags/engine/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/soundcache.h" +#include "ags/engine/util/mutex_lock.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/lib/audio/digi.h" +#include "ags/lib/audio/ogg.h" namespace AGS3 { -extern "C" { - extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); - extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); - extern int alogg_get_ogg_freq(ALOGG_OGG *ogg); - extern int alogg_get_ogg_stereo(ALOGG_OGG *ogg); -} - extern int use_extra_sound_offset; // defined in ac.cpp void MYSTATICOGG::poll() { diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h index 4663560961e9..cffe99009045 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H -#include "ags/shared/alogg.h" -#include "ags/shared/media/audio/soundclip.h" +#include "ags/lib/audio/ogg.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp index 875bd3363b5a..f11f1b22dd91 100644 --- a/engines/ags/engine/media/audio/clip_mywave.cpp +++ b/engines/ags/engine/media/audio/clip_mywave.cpp @@ -20,14 +20,15 @@ * */ +#include "ags/lib/audio/digi.h" #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/media/audio/audiodefines.h" -#include "ags/shared/media/audio/clip_mywave.h" -#include "ags/shared/media/audio/audiointernaldefs.h" -#include "ags/shared/media/audio/soundcache.h" -#include "ags/shared/util/mutex_lock.h" +#include "ags/engine/media/audio/audiodefines.h" +#include "ags/engine/media/audio/clip_mywave.h" +#include "ags/engine/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/soundcache.h" +#include "ags/engine/util/mutex_lock.h" -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h index 24b119a7eb04..a9f75b8319a1 100644 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H -#include "ags/shared/media/audio/soundclip.h" +#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/engine/media/audio/queuedaudioitem.cpp b/engines/ags/engine/media/audio/queuedaudioitem.cpp index 744e6db89f90..80dbadfe4338 100644 --- a/engines/ags/engine/media/audio/queuedaudioitem.cpp +++ b/engines/ags/engine/media/audio/queuedaudioitem.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/shared/media/audio/queuedaudioitem.h" +#include "ags/engine/media/audio/queuedaudioitem.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index 057a498b983a..5c3a72424f81 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -30,26 +30,26 @@ #include "ags/shared/core/platform.h" #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/ac/file.h" -#include "ags/shared/media/audio/audiodefines.h" -#include "ags/shared/media/audio/sound.h" -#include "ags/shared/media/audio/audiointernaldefs.h" -#include "ags/shared/media/audio/clip_mywave.h" +#include "ags/engine/ac/file.h" +#include "ags/engine/media/audio/audiodefines.h" +#include "ags/engine/media/audio/sound.h" +#include "ags/engine/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/clip_mywave.h" #ifndef NO_MP3_PLAYER -#include "ags/shared/media/audio/clip_mymp3.h" -#include "ags/shared/media/audio/clip_mystaticmp3.h" +#include "ags/engine/media/audio/clip_mymp3.h" +#include "ags/engine/media/audio/clip_mystaticmp3.h" #endif -#include "ags/shared/media/audio/clip_myogg.h" -#include "ags/shared/media/audio/clip_mystaticogg.h" -#include "ags/shared/media/audio/clip_mymidi.h" +#include "ags/engine/media/audio/clip_myogg.h" +#include "ags/engine/media/audio/clip_mystaticogg.h" +#include "ags/engine/media/audio/clip_mymidi.h" #ifdef JGMOD_MOD_PLAYER -#include "ags/shared/media/audio/clip_myjgmod.h" +#include "ags/engine/media/audio/clip_myjgmod.h" #endif #ifdef DUMB_MOD_PLAYER -#include "ags/shared/media/audio/clip_mydumbmod.h" +#include "ags/engine/media/audio/clip_mydumbmod.h" #endif -#include "ags/shared/media/audio/soundcache.h" -#include "ags/shared/util/mutex_lock.h" +#include "ags/engine/media/audio/soundcache.h" +#include "ags/engine/util/mutex_lock.h" namespace AGS3 { @@ -94,6 +94,7 @@ PACKFILE *mp3in; #ifndef NO_MP3_PLAYER MYMP3 *thistune; + SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) { size_t asset_size; mp3in = PackfileFromAsset(asset_name, asset_size); @@ -111,7 +112,7 @@ SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) { thistune->filesize = asset_size; thistune->vol = voll; - if (thistune->chunksize > thistune->filesize) + if (thistune->chunksize > (int)thistune->filesize) thistune->chunksize = thistune->filesize; pack_fread(tmpbuffer, thistune->chunksize, mp3in); @@ -230,7 +231,7 @@ SOUNDCLIP *my_load_ogg(const AssetPath &asset_name, int voll) { thisogg->last_ms_offs = 0; thisogg->last_but_one_but_one = 0; - if (thisogg->chunksize > asset_size) + if (thisogg->chunksize > (int)asset_size) thisogg->chunksize = asset_size; pack_fread(tmpbuffer, thisogg->chunksize, mp3in); diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index dcf4136ac357..81eb9737a73e 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -22,12 +22,12 @@ //include //include -#include "ags/shared/ac/file.h" +#include "ags/engine/ac/file.h" #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/media/audio/soundcache.h" -#include "ags/shared/media/audio/audiointernaldefs.h" -#include "ags/shared/util/mutex.h" -#include "ags/shared/util/mutex_lock.h" +#include "ags/engine/media/audio/soundcache.h" +#include "ags/engine/media/audio/audiointernaldefs.h" +#include "ags/engine/util/mutex.h" +#include "ags/engine/util/mutex_lock.h" #include "ags/shared/util/string.h" #include "ags/shared/debugging/out.h" diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index 68fc57ceec6e..c7b54cc83ab1 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -21,10 +21,10 @@ */ #include "ags/shared/util/wgt2allg.h" -#include "ags/shared/media/audio/audio.h" -#include "ags/shared/media/audio/audiodefines.h" -#include "ags/shared/media/audio/soundclip.h" -#include "ags/shared/media/audio/audiointernaldefs.h" +#include "ags/engine/media/audio/audio.h" +#include "ags/engine/media/audio/audiodefines.h" +#include "ags/engine/media/audio/soundclip.h" +#include "ags/engine/media/audio/audiointernaldefs.h" namespace AGS3 { diff --git a/engines/ags/lib/allegro.h b/engines/ags/lib/allegro.h index 9ecceb509edb..9952637ada82 100644 --- a/engines/ags/lib/allegro.h +++ b/engines/ags/lib/allegro.h @@ -29,7 +29,6 @@ #include "ags/lib/allegro/base.h" #include "ags/lib/allegro/color.h" #include "ags/lib/allegro/config.h" -#include "ags/lib/allegro/digi.h" #include "ags/lib/allegro/draw.h" #include "ags/lib/allegro/error.h" #include "ags/lib/allegro/file.h" @@ -37,12 +36,14 @@ #include "ags/lib/allegro/fmaths.h" #include "ags/lib/allegro/gfx.h" #include "ags/lib/allegro/keyboard.h" -#include "ags/lib/allegro/midi.h" #include "ags/lib/allegro/mouse.h" -#include "ags/lib/allegro/sound.h" #include "ags/lib/allegro/system.h" #include "ags/lib/allegro/unicode.h" +#include "ags/lib/audio/sound.h" +#include "ags/lib/audio/digi.h" +#include "ags/lib/audio/midi.h" + namespace AGS3 { extern int install_allegro(); diff --git a/engines/ags/lib/allegro/sound.cpp b/engines/ags/lib/allegro/sound.cpp index a4acc0565f68..46b9d1b909e8 100644 --- a/engines/ags/lib/allegro/sound.cpp +++ b/engines/ags/lib/allegro/sound.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/lib/allegro/sound.h" +#include "ags/lib/audio/sound.h" #include "common/textconsole.h" namespace AGS3 { @@ -69,7 +69,7 @@ void get_volume(int *digi_volume, int *midi_volume) { } void get_hardware_volume(int *digi_volume, int *midi_volume) { - error("get_hardware_volume"); + error("get_hardware_volume"); } void set_mixer_quality(int quality) { @@ -100,4 +100,12 @@ int get_mixer_buffer_length() { error("get_mixer_buffer_length"); } + +void stop_audio_stream(AUDIOSTREAM *stream) { + warning("TODO: stop_audio_stream"); +} + +void set_volume(int channel, int vol) { + warning("TODO: set_volume(%d, %d)", channel, vol); +} } // namespace AGS3 diff --git a/engines/ags/lib/audio/digi.cpp b/engines/ags/lib/audio/digi.cpp new file mode 100644 index 000000000000..6e34e036e99b --- /dev/null +++ b/engines/ags/lib/audio/digi.cpp @@ -0,0 +1,90 @@ +/* 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 "ags/lib/audio/digi.h" +#include "common/textconsole.h" + +namespace AGS3 { + +DIGI_DRIVER *digi_driver; + +DIGI_DRIVER *digi_input_driver; + +int digi_card; + +int digi_input_card; + + +int detect_digi_driver(int driver_id) { + return 0; +} + +SAMPLE *load_wav_pf(PACKFILE *f) { + warning("TODO: load_wav_pf"); + return nullptr; +} + +void destroy_sample(SAMPLE *spl) { + delete spl; +} + +int play_sample(SAMPLE *spl, int vol, int pan, int freq, int loop) { + warning("TODO: play_sample"); + return 0; +} + +void stop_sample(SAMPLE *spl) { + warning("TODO: stop_sample"); +} + + +void voice_start(int voice) { + warning("TODO: voice_start"); +} + +void voice_stop(int voice) { + warning("TODO: voice_stop"); +} + +int voice_get_position(int voice) { + warning("TODO: voice_get_position"); + return 0; +} + +void voice_set_position(int voice, int position) { + warning("TODO: voice_set_position"); +} + +void voice_set_volume(int voice, int volume) { + warning("TODO: voice_set_volume"); +} + +int voice_get_frequency(int voice) { + warning("TODO: voice_get_frequency"); + return 0; +} + +void voice_set_pan(int voice, int pan) { + warning("TODO: voice_set_pan"); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/digi.h b/engines/ags/lib/audio/digi.h similarity index 89% rename from engines/ags/lib/allegro/digi.h rename to engines/ags/lib/audio/digi.h index 1ffe0bdc2425..904c40fb3ff9 100644 --- a/engines/ags/lib/allegro/digi.h +++ b/engines/ags/lib/audio/digi.h @@ -20,12 +20,13 @@ * */ -#ifndef AGS_LIB_ALLEGRO_DIGI_H -#define AGS_LIB_ALLEGRO_DIGI_H +#ifndef AGS_LIB_AUDIO_DIGI_H +#define AGS_LIB_AUDIO_DIGI_H #include "common/scummsys.h" #include "ags/lib/allegro/base.h" #include "ags/lib/allegro/alconfig.h" +#include "ags/lib/allegro/file.h" namespace AGS3 { @@ -140,6 +141,20 @@ AL_VAR(int, digi_input_card); AL_FUNC(int, detect_digi_driver, (int driver_id)); + +extern SAMPLE *load_wav_pf(PACKFILE *f); +extern void destroy_sample(SAMPLE *spl); +extern int play_sample(SAMPLE *spl, int vol, int pan, int freq, int loop); +extern void stop_sample(SAMPLE *spl); + +extern void voice_start(int voice); +extern void voice_stop(int voice); +extern int voice_get_position(int voice); +extern void voice_set_position(int voice, int position); +extern void voice_set_volume(int voice, int volume); +extern int voice_get_frequency(int voice); +extern void voice_set_pan(int voice, int pan); + } // namespace AGS3 #endif diff --git a/engines/ags/lib/allegro/midi.cpp b/engines/ags/lib/audio/midi.cpp similarity index 71% rename from engines/ags/lib/allegro/midi.cpp rename to engines/ags/lib/audio/midi.cpp index 7b058574bab0..96ed12eb1095 100644 --- a/engines/ags/lib/allegro/midi.cpp +++ b/engines/ags/lib/audio/midi.cpp @@ -20,7 +20,8 @@ * */ -#include "ags/lib/allegro/midi.h" +#include "ags/lib/audio/midi.h" +#include "common/textconsole.h" namespace AGS3 { @@ -43,4 +44,40 @@ int detect_midi_driver(int driver_id) { return 0; } + +void stop_midi() { + warning("TODO: stop_midi"); +} + +void destroy_midi(MIDI *midi) { + delete midi; +} + +int play_midi(MIDI *tune, bool repeat) { + warning("TODO: play_midi"); + return 0; +} + +size_t get_midi_length(MIDI *tune) { + warning("TODO: get_midi_length"); + return 0; +} + +void midi_seek(int target) { + warning("TODO: midi_seek"); +} + +void midi_pause() { + warning("TODO: midi_pause"); +} + +void midi_resume() { + warning("TODO: midi_resume"); +} + +int load_midi_patches() { + warning("TODO: load_midi_patches"); + return 0; +} + } // namespace AGS3 diff --git a/engines/ags/lib/allegro/midi.h b/engines/ags/lib/audio/midi.h similarity index 92% rename from engines/ags/lib/allegro/midi.h rename to engines/ags/lib/audio/midi.h index 8f474995e169..a96048191d5f 100644 --- a/engines/ags/lib/allegro/midi.h +++ b/engines/ags/lib/audio/midi.h @@ -20,8 +20,8 @@ * */ -#ifndef AGS_LIB_ALLEGRO_MIDI_H -#define AGS_LIB_ALLEGRO_MIDI_H +#ifndef AGS_LIB_AUDIO_MIDI_H +#define AGS_LIB_AUDIO_MIDI_H #include "common/scummsys.h" #include "ags/lib/allegro/base.h" @@ -118,6 +118,15 @@ AL_VAR(long, midi_loop_end); /* loop when we hit this position */ AL_FUNC(int, detect_midi_driver, (int driver_id)); +extern void stop_midi(); +extern void destroy_midi(MIDI *tune); +extern int play_midi(MIDI *tune, bool repeat); +extern size_t get_midi_length(MIDI *tune); +extern void midi_seek(int target); +extern void midi_pause(); +extern void midi_resume(); +extern int load_midi_patches(); + } // namespace AGS3 #endif diff --git a/engines/ags/lib/audio/mod.cpp b/engines/ags/lib/audio/mod.cpp new file mode 100644 index 000000000000..29c9acadb73b --- /dev/null +++ b/engines/ags/lib/audio/mod.cpp @@ -0,0 +1,34 @@ +/* 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 "ags/lib/audio/ogg.h" +#include "common/textconsole.h" +#include "ags/ags.h" + +namespace AGS3 { + +int alogg_poll_ogg(ALOGG_OGG *ogg) { + return ::AGS::g_vm->_mixer->isSoundHandleActive(ogg->_handle) ? 0 : ALOGG_POLL_PLAYJUSTFINISHED; +} + + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/digi.cpp b/engines/ags/lib/audio/mod.h similarity index 84% rename from engines/ags/lib/allegro/digi.cpp rename to engines/ags/lib/audio/mod.h index c3dbacf4ba83..5fcf46c3fa4e 100644 --- a/engines/ags/lib/allegro/digi.cpp +++ b/engines/ags/lib/audio/mod.h @@ -20,21 +20,15 @@ * */ -#include "ags/lib/allegro/digi.h" +#ifndef AGS_LIB_AUDIO_MOD_H +#define AGS_LIB_AUDIO_MOD_H -namespace AGS3 { - -DIGI_DRIVER *digi_driver; - -DIGI_DRIVER *digi_input_driver; - -int digi_card; - -int digi_input_card; +#include "audio/audiostream.h" +#include "audio/mixer.h" +namespace AGS3 { -int detect_digi_driver(int driver_id) { - return 0; -} } // namespace AGS3 + +#endif diff --git a/engines/ags/lib/audio/mp3.cpp b/engines/ags/lib/audio/mp3.cpp new file mode 100644 index 000000000000..b948acdbf765 --- /dev/null +++ b/engines/ags/lib/audio/mp3.cpp @@ -0,0 +1,117 @@ +/* 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 "ags/lib/audio/mp3.h" +#include "common/textconsole.h" +#include "ags/ags.h" + +namespace AGS3 { + +ALMP3_MP3 *almp3_create_mp3(void *data, int data_len) { + warning("TODO: almp3_create_mp3"); + return nullptr; +} + +int almp3_play_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan) { + warning("TODO: almp3_play_mp3"); + return 0; +} + +int almp3_play_ex_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan, int speed, int loop) { + warning("TODO: almp3_play_ex_mp3"); + return 0; +} + +void almp3_stop_mp3(ALMP3_MP3 *mp3) { + ::AGS::g_vm->_mixer->stopHandle(mp3->_handle); +} + +void almp3_destroy_mp3(ALMP3_MP3 *mp3) { + delete mp3; +} + +int almp3_poll_mp3(ALMP3_MP3 *mp3) { + return ::AGS::g_vm->_mixer->isSoundHandleActive(mp3->_handle) ? 0 : ALMP3_POLL_PLAYJUSTFINISHED; +} + +void almp3_adjust_mp3(ALMP3_MP3 *mp3, int volume, int panning, int speed, bool repeat) { + warning("TODO: almp3_adjust_mp3"); +} + +void almp3_seek_abs_msecs_mp3(ALMP3_MP3 *mp3, int pos) { + warning("TODO: almp3_seek_abs_msecs_mp3"); +} + +int almp3_get_pos_msecs_mp3(ALMP3_MP3 *mp3) { + warning("TODO: almp3_get_pos_msecs_mp3"); + return 0; +} + +AUDIOSTREAM *almp3_get_audiostream_mp3(ALMP3_MP3 *mp3) { + warning("TODO: almp3_get_audiostream_mp3"); + return nullptr; +} + +int almp3_get_length_msecs_mp3(ALMP3_MP3 *mp3) { + warning("TODO: almp3_get_length_msecs_mp3"); + return 0; +} + + +ALMP3_MP3STREAM *almp3_create_mp3stream(void *first_data_buffer, int data_buffer_len, int last_block) { + warning("TODO: almp3_create_mp3stream"); + return nullptr; +} + +int almp3_play_mp3stream(ALMP3_MP3STREAM *mp3, int buffer_len, int vol, int pan) { + warning("TODO: almp3_play_mp3stream"); + return -1; +} + +int almp3_poll_mp3stream(ALMP3_MP3STREAM *mp3) { + warning("TODO: almp3_poll_mp3stream"); + return 0; +} + +void almp3_adjust_mp3stream(ALMP3_MP3STREAM *mp3, int volume, int panning, int speed) { + warning("TODO: almp3_adjust_mp3stream"); +} + +void almp3_stop_mp3stream(ALMP3_MP3STREAM *mp3) { + warning("TODO: almp3_stop_mp3stream"); +} + +void almp3_destroy_mp3stream(ALMP3_MP3STREAM *mp3) { + warning("TODO: almp3_destroy_mp3stream"); +} + +int almp3_get_pos_msecs_mp3stream(ALMP3_MP3STREAM *mp3) { + warning("TODO: almp3_get_pos_msecs_mp3stream"); + return 0; +} + +AUDIOSTREAM *almp3_get_audiostream_mp3stream(ALMP3_MP3STREAM *mp3) { + warning("TODO: almp3_get_audiostream_mp3stream"); + return nullptr; +} + +} // namespace AGS3 diff --git a/engines/ags/lib/audio/mp3.h b/engines/ags/lib/audio/mp3.h new file mode 100644 index 000000000000..2ac411aa758b --- /dev/null +++ b/engines/ags/lib/audio/mp3.h @@ -0,0 +1,64 @@ +/* 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 AGS_LIB_AUDIO_MP3_H +#define AGS_LIB_AUDIO_MP3_H + +#include "ags/lib/audio/sound.h" +#include "audio/mixer.h" + +namespace AGS3 { + +#define ALMP3_OK 0 +#define ALMP3_POLL_PLAYJUSTFINISHED 1 + +typedef Audio::AudioStream ALMP3_MP3STREAM; +struct ALMP3_MP3 { + ALMP3_MP3STREAM *_stream; + Audio::SoundHandle _handle; +}; + +extern ALMP3_MP3 *almp3_create_mp3(void *data, int data_len); +extern void almp3_destroy_mp3(ALMP3_MP3 *mp3); +extern int almp3_play_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan); +extern int almp3_play_ex_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan, int speed, int loop); +extern void almp3_stop_mp3(ALMP3_MP3 *mp3); +extern int almp3_poll_mp3(ALMP3_MP3 *mp3); +extern void almp3_adjust_mp3(ALMP3_MP3 *mp3, int volume, int panning, int speed, bool repeat); +extern void almp3_seek_abs_msecs_mp3(ALMP3_MP3 *mp3, int pos); +extern int almp3_get_pos_msecs_mp3(ALMP3_MP3 *mp3); +extern AUDIOSTREAM *almp3_get_audiostream_mp3(ALMP3_MP3 *mp3); +extern int almp3_get_length_msecs_mp3(ALMP3_MP3 *mp3); + +extern ALMP3_MP3STREAM *almp3_create_mp3stream(void *first_data_buffer, int data_buffer_len, int last_block); +extern int almp3_play_mp3stream(ALMP3_MP3STREAM *mp3, int buffer_len, int vol, int pan); +extern int almp3_poll_mp3stream(ALMP3_MP3STREAM *mp3); +extern void almp3_adjust_mp3stream(ALMP3_MP3STREAM *mp3, int volume, int panning, int speed); +extern void almp3_stop_mp3stream(ALMP3_MP3STREAM *mp3); +extern void almp3_destroy_mp3stream(ALMP3_MP3STREAM *mp3); +extern int almp3_get_pos_msecs_mp3stream(ALMP3_MP3STREAM *mp3); +extern AUDIOSTREAM *almp3_get_audiostream_mp3stream(ALMP3_MP3STREAM *mp3); +extern int almp3_get_length_msecs_mp3stream(ALMP3_MP3STREAM *mp3, int total_size); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/audio/ogg.cpp b/engines/ags/lib/audio/ogg.cpp new file mode 100644 index 000000000000..60860b3df9a5 --- /dev/null +++ b/engines/ags/lib/audio/ogg.cpp @@ -0,0 +1,146 @@ +/* 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 "ags/lib/audio/ogg.h" +#include "common/textconsole.h" +#include "ags/ags.h" + +namespace AGS3 { + +ALOGG_OGG *alogg_create_ogg_from_buffer(void *data, int data_len) { + warning("TODO: alogg_create_ogg_from_buffer"); + return nullptr; +} + +void alogg_destroy_ogg(ALOGG_OGG *ogg) { + delete ogg; +} + +int alogg_play_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan) { + warning("TODO: alogg_play_ogg"); + return 0; +} + +int alogg_play_ex_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan, int speed, int loop) { + warning("TODO: alogg_play_ex_ogg"); + return 0; +} + +void alogg_stop_ogg(ALOGG_OGG *ogg) { + warning("TODO: alogg_stop_ogg"); +} + +int alogg_poll_ogg(ALOGG_OGG *ogg) { + return ::AGS::g_vm->_mixer->isSoundHandleActive(ogg->_handle) ? 0 : ALOGG_POLL_PLAYJUSTFINISHED; +} + +bool alogg_is_playing_ogg(ALOGG_OGG *ogg) { + warning("TODO: alogg_is_playing_ogg"); + return false; +} + +void alogg_adjust_ogg(ALOGG_OGG *ogg, int volume, int panning, int speed, bool repeat) { + warning("TODO: alogg_adjust_oggstream"); +} + +AUDIOSTREAM *alogg_get_audiostream_ogg(ALOGG_OGG *ogg) { + return ogg->_stream; +} + +int alogg_get_pos_msecs_ogg(ALOGG_OGG *ogg) { + warning("TODO: alogg_get_pos_msecs_ogg"); + return 0; +} + +bool alogg_get_wave_is_stereo_ogg(ALOGG_OGG *ogg) { + warning("TODO: alogg_get_wave_is_stereo_ogg"); + return true; +} + +int alogg_get_length_msecs_ogg(ALOGG_OGG *ogg) { + warning("TODO: alogg_get_length_msecs_ogg"); + return 0; +} + +void alogg_seek_abs_msecs_ogg(ALOGG_OGG *ogg, int msecs) { + warning("TODO: alogg_seek_abs_msecs_ogg"); +} + +int alogg_get_wave_freq_ogg(ALOGG_OGG *ogg) { + warning("TODO: alogg_get_wave_freq_ogg"); + return 0; +} + +int alogg_is_end_of_ogg(ALOGG_OGG *ogg) { + warning("TODO: alogg_is_end_of_oggstream"); + return 0; +} + + +ALOGG_OGGSTREAM *alogg_create_oggstream(void *first_data_buffer, int data_buffer_len, int last_block) { + warning("TODO: alogg_create_oggstream"); + return nullptr; +} + +void alogg_destroy_oggstream(ALOGG_OGGSTREAM *ogg) { + warning("TODO: alogg_destroy_oggstream"); +} + +int alogg_play_oggstream(ALOGG_OGGSTREAM *ogg, int buffer_len, int vol, int pan) { + warning("TODO: alogg_play_oggstream"); + return 0; +} + +void alogg_stop_oggstream(ALOGG_OGGSTREAM *ogg) { + warning("TODO: alogg_stop_oggstream"); +} + +int alogg_poll_oggstream(ALOGG_OGGSTREAM *ogg) { + warning("TODO: alogg_poll_oggstream"); + return 0; +} + +void alogg_adjust_oggstream(ALOGG_OGGSTREAM *ogg, int volume, int panning, int speed) { + warning("TODO: alogg_adjust_oggstream"); +} + +bool alogg_is_playing_oggstream(ALOGG_OGGSTREAM *ogg) { + warning("TODO: alogg_is_playing_oggstream"); + return false; +} + +int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg) { + warning("TODO: alogg_is_end_of_oggstream"); + return 0; +} + +AUDIOSTREAM *alogg_get_audiostream_oggstream(ALOGG_OGGSTREAM *ogg) { + warning("TODO: alogg_get_audiostream_oggstream"); + return nullptr; +} + +int alogg_get_pos_msecs_oggstream(ALOGG_OGGSTREAM *ogg) { + warning("TODO: alogg_get_pos_msecs_oggstream"); + return 0; +} + +} // namespace AGS3 diff --git a/engines/ags/lib/audio/ogg.h b/engines/ags/lib/audio/ogg.h new file mode 100644 index 000000000000..b967cb53f97b --- /dev/null +++ b/engines/ags/lib/audio/ogg.h @@ -0,0 +1,76 @@ +/* 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 AGS_LIB_AUDIO_OGG_H +#define AGS_LIB_AUDIO_OGG_H + +#include "ags/lib/audio/sound.h" +#include "audio/mixer.h" + +namespace AGS3 { + +#define ALOGG_OK 0 + +#define ALOGG_PLAY_BUFFERTOOSMALL -1 + +#define ALOGG_POLL_PLAYJUSTFINISHED 1 +#define ALOGG_POLL_NOTPLAYING -1 +#define ALOGG_POLL_FRAMECORRUPT -2 +#define ALOGG_POLL_BUFFERUNDERRUN -3 +#define ALOGG_POLL_INTERNALERROR -4 + +typedef AUDIOSTREAM ALOGG_OGGSTREAM; +struct ALOGG_OGG { + ALOGG_OGGSTREAM *_stream; + Audio::SoundHandle _handle; +}; + +extern ALOGG_OGG *alogg_create_ogg_from_buffer(void *data, int data_len); +extern void alogg_destroy_ogg(ALOGG_OGG *ogg); +extern int alogg_play_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan); +extern int alogg_play_ex_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan, int speed, int loop); +extern void alogg_stop_ogg(ALOGG_OGG *ogg); +extern int alogg_poll_ogg(ALOGG_OGG *ogg); +extern bool alogg_is_playing_ogg(ALOGG_OGG *ogg); +extern void alogg_adjust_ogg(ALOGG_OGG *ogg, int volume, int panning, int speed, bool repeat); +extern AUDIOSTREAM *alogg_get_audiostream_ogg(ALOGG_OGG *ogg); +extern int alogg_get_pos_msecs_ogg(ALOGG_OGG *ogg); +extern bool alogg_get_wave_is_stereo_ogg(ALOGG_OGG *ogg); +extern int alogg_get_length_msecs_ogg(ALOGG_OGG *ogg); +extern void alogg_seek_abs_msecs_ogg(ALOGG_OGG *ogg, int msecs); +extern int alogg_get_wave_freq_ogg(ALOGG_OGG *ogg); +extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); + +ALOGG_OGGSTREAM *alogg_create_oggstream(void *first_data_buffer, int data_buffer_len, int last_block); +extern int alogg_play_oggstream(ALOGG_OGGSTREAM *ogg, int buffer_len, int vol, int pan); +extern void alogg_stop_oggstream(ALOGG_OGGSTREAM *ogg); +extern void alogg_destroy_oggstream(ALOGG_OGGSTREAM *ogg); +extern int alogg_poll_oggstream(ALOGG_OGGSTREAM *ogg); +extern void alogg_adjust_oggstream(ALOGG_OGGSTREAM *ogg, int volume, int panning, int speed); +extern bool alogg_is_playing_oggstream(ALOGG_OGGSTREAM *ogg); +extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); +extern AUDIOSTREAM *alogg_get_audiostream_oggstream(ALOGG_OGGSTREAM *ogg); +extern int alogg_get_pos_msecs_oggstream(ALOGG_OGGSTREAM *ogg); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/audio/sound.cpp b/engines/ags/lib/audio/sound.cpp new file mode 100644 index 000000000000..e8d197b660f1 --- /dev/null +++ b/engines/ags/lib/audio/sound.cpp @@ -0,0 +1,108 @@ +/* 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 "ags/lib/audio/sound.h" +#include "common/textconsole.h" + +namespace AGS3 { + +_DRIVER_INFO _digi_driver_list[] = { + { 0, nullptr, 0 } +}; + + +int install_sound(int digi, int midi, const char *cfg_path) { + // TODO: install_sound + return 0; +} + +void remove_sound() { + // TODO: remove_sound +} + +void reserve_voices(int digi_voices, int midi_voices) { + error("reserve_voices"); +} + +void set_volume_per_voice(int scale) { + error("set_volume_per_voice"); + +} + +int install_sound_input(int digi, int midi) { + error("install_sound_input"); +} + +void remove_sound_input() { + error("remove_sound_input"); +} + +void set_volume(int digi_volume, int midi_volume) { + error("set_volume"); +} + +void set_hardware_volume(int digi_volume, int midi_volume) { + error("set_hardware_volume"); +} + +void get_volume(int *digi_volume, int *midi_volume) { + error("get_volume"); +} + +void get_hardware_volume(int *digi_volume, int *midi_volume) { + error("get_hardware_volume"); +} + +void set_mixer_quality(int quality) { + error("set_mixer_quality"); +} + +int get_mixer_quality() { + error("get_mixer_quality"); +} + +int get_mixer_frequency() { + error("get_mixer_frequency"); +} + +int get_mixer_bits() { + error("get_mixer_bits"); +} + +int get_mixer_channels() { + error("get_mixer_channels"); +} + +int get_mixer_voices() { + error("get_mixer_voices"); +} + +int get_mixer_buffer_length() { + error("get_mixer_buffer_length"); +} + + +void stop_audio_stream(AUDIOSTREAM *stream) { + warning("TODO: stop_audio_stream"); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/sound.h b/engines/ags/lib/audio/sound.h similarity index 90% rename from engines/ags/lib/allegro/sound.h rename to engines/ags/lib/audio/sound.h index bc4790c9ac78..d8c046de25c6 100644 --- a/engines/ags/lib/allegro/sound.h +++ b/engines/ags/lib/audio/sound.h @@ -29,6 +29,15 @@ namespace AGS3 { +struct SAMPLE; + +struct AUDIOSTREAM { + int voice = -1; + SAMPLE *samp = nullptr; + bool active = false; + void *locked = nullptr; +}; + AL_FUNC(void, reserve_voices, (int digi_voices, int midi_voices)); AL_FUNC(void, set_volume_per_voice, (int scale)); @@ -52,6 +61,10 @@ AL_FUNC(int, get_mixer_channels, (void)); AL_FUNC(int, get_mixer_voices, (void)); AL_FUNC(int, get_mixer_buffer_length, (void)); + +extern void stop_audio_stream(AUDIOSTREAM *stream); +extern void set_volume(int channel, int vol); + } // namespace AGS3 #endif diff --git a/engines/ags/lib/audio/wav.cpp b/engines/ags/lib/audio/wav.cpp new file mode 100644 index 000000000000..851877df4619 --- /dev/null +++ b/engines/ags/lib/audio/wav.cpp @@ -0,0 +1,31 @@ +/* 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 "ags/lib/audio/wav.h" +#include "common/textconsole.h" +#include "ags/ags.h" + +namespace AGS3 { + + + +} // namespace AGS3 diff --git a/engines/ags/lib/audio/wav.h b/engines/ags/lib/audio/wav.h new file mode 100644 index 000000000000..d550c03312da --- /dev/null +++ b/engines/ags/lib/audio/wav.h @@ -0,0 +1,34 @@ +/* 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 AGS_LIB_AUDIO_WAV_H +#define AGS_LIB_AUDIO_WAV_H + +#include "audio/audiostream.h" +#include "audio/mixer.h" + +namespace AGS3 { + + +} // namespace AGS3 + +#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk index f1e905fb1ab8..90af620cbf07 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -10,18 +10,22 @@ MODULE_OBJS = \ lib/allegro.o \ lib/allegro/color.o \ lib/allegro/config.o \ - lib/allegro/digi.o \ lib/allegro/draw.o \ lib/allegro/error.o \ lib/allegro/file.o \ lib/allegro/fixed.o \ lib/allegro/gfx.o \ lib/allegro/keyboard.o \ - lib/allegro/midi.o \ lib/allegro/mouse.o \ - lib/allegro/sound.o \ lib/allegro/system.o \ lib/allegro/unicode.o \ + lib/audio/audio.o \ + lib/audio/digi.o \ + lib/audio/midi.o \ + lib/audio/mp3.o \ + lib/audio/ogg.o \ + lib/audio/sound.o \ + lib/audio/wav.o \ lib/opengl/opengl.o \ lib/system/datetime.o \ shared/ac/dynobj/scriptaudioclip.o \ @@ -248,6 +252,20 @@ MODULE_OBJS = \ engine/main/graphics_mode.o \ engine/main/quit.o \ engine/main/update.o \ + engine/media/audio/ambientsound.o \ + engine/media/audio/audio.o \ + engine/media/audio/clip_mydumbmod.o \ + engine/media/audio/clip_myjgmod.o \ + engine/media/audio/clip_mymidi.o \ + engine/media/audio/clip_mymp3.o \ + engine/media/audio/clip_myogg.o \ + engine/media/audio/clip_mystaticmp3.o \ + engine/media/audio/clip_mystaticogg.o \ + engine/media/audio/clip_mywave.o \ + engine/media/audio/queuedaudioitem.o \ + engine/media/audio/sound.o \ + engine/media/audio/soundcache.o \ + engine/media/audio/soundclip.o \ engine/platform/base/agsplatformdriver.o \ engine/platform/windows/acplwin.o \ engine/platform/windows/minidump.o \ From 1cd7015fb2c5469f1a822332bc12ea3c1806a094 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 20:24:48 -0800 Subject: [PATCH 041/215] AGS: Added engine/media/video/ folder --- engines/ags/engine/media/video/video.cpp | 43 +++++++++++-------- .../media/video/{VMR9Graph.h => vmr9_graph.h} | 10 ++--- .../platform/windows/media/video/acwavi3d.cpp | 2 +- engines/ags/module.mk | 1 + 4 files changed, 30 insertions(+), 26 deletions(-) rename engines/ags/engine/media/video/{VMR9Graph.h => vmr9_graph.h} (94%) diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index 9372858dfb63..d5a14bc821fd 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -20,38 +20,41 @@ * */ -#include "ags/shared/media/video/video.h" +#include "ags/engine/media/video/video.h" -#ifndef AGS_NO_VIDEO_PLAYER - -#include "ags/shared/apeg.h" +//include "apeg.h" #include "ags/shared/core/platform.h" #define AGS_FLI_FROM_PACK_FILE ((ALLEGRO_DATE >= 20190303) || \ - AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_MACOS) + AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_MACOS) -#include "ags/shared/debugging/debug_log.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/debugging/out.h" -#include "ags/shared/ac/asset_helper.h" +#include "ags/engine/ac/asset_helper.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/game_version.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_display.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/sys_events.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/system.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_display.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/sys_events.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/system.h" #include "ags/shared/core/assetmanager.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/gfx/ddb.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/main/game_run.h" +#include "ags/engine/gfx/ddb.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/main/game_run.h" #include "ags/shared/util/stream.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" namespace AGS3 { +// TODO: Enable video playback +#define AGS_NO_VIDEO_PLAYER + +#ifndef AGS_NO_VIDEO_PLAYER + using namespace AGS::Shared; using namespace AGS::Engine; @@ -397,10 +400,14 @@ void video_on_gfxmode_changed() { #else void play_theora_video(const char *name, int skip, int flags) { + warning("TODO: play_theora_video"); } void play_flc_file(int numb, int playflags) { + warning("TODO: play_flc_file"); } + void video_on_gfxmode_changed() { + warning("TODO: video_on_gfxmode_changed"); } #endif diff --git a/engines/ags/engine/media/video/VMR9Graph.h b/engines/ags/engine/media/video/vmr9_graph.h similarity index 94% rename from engines/ags/engine/media/video/VMR9Graph.h rename to engines/ags/engine/media/video/vmr9_graph.h index 837d3a5896dd..d3488fbd9b0c 100644 --- a/engines/ags/engine/media/video/VMR9Graph.h +++ b/engines/ags/engine/media/video/vmr9_graph.h @@ -22,16 +22,12 @@ //============================================================================= // -// VMR9Graph.h: interface for the CVMR9Graph class. +// vmr9_graph.h: interface for the CVMR9Graph class. // //============================================================================= -#if !defined(AFX_VMR9GRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_) -#define AFX_VMR9GRAPH_H__449FDB5B_6719_4134_B5A7_B651C08D109E__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif +#ifndef AGS_ENGINE_MEDIA_VIDEO_VMR9_GRAPH_H +#define AGS_ENGINE_MEDIA_VIDEO_VMR9_GRAPH_H //include //include diff --git a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp index 11b24ecb2b52..0b70185d6515 100644 --- a/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp +++ b/engines/ags/engine/platform/windows/media/video/acwavi3d.cpp @@ -45,7 +45,7 @@ typedef float D3DVALUE, *LPD3DVALUE; #include "ags/shared/ac/common.h" #include "ags/shared/main/game_run.h" -#include "ags/shared/media/video/VMR9Graph.h" +#include "ags/shared/media/video/vmr9_graph.h" #include "ags/shared/platform/base/agsplatformdriver.h" ////include #include "ags/shared/media/audio/audio_system.h" diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 90af620cbf07..fd1677c0591e 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -266,6 +266,7 @@ MODULE_OBJS = \ engine/media/audio/sound.o \ engine/media/audio/soundcache.o \ engine/media/audio/soundclip.o \ + engine/media/video/video.o \ engine/platform/base/agsplatformdriver.o \ engine/platform/windows/acplwin.o \ engine/platform/windows/minidump.o \ From 465680c706a086baa82ff8c1b3e3d8fc756b6541 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 20:33:28 -0800 Subject: [PATCH 042/215] AGS: Move std/ folder into lib/ --- engines/ags/engine/ac/asset_helper.h | 4 +- engines/ags/engine/ac/dialog.h | 2 +- engines/ags/engine/ac/draw.cpp | 4 +- engines/ags/engine/ac/draw.h | 2 +- engines/ags/engine/ac/draw_software.cpp | 4 +- .../ags/engine/ac/dynobj/cc_dynamicarray.h | 2 +- .../ags/engine/ac/dynobj/cc_dynamicobject.h | 2 +- .../engine/ac/dynobj/managedobjectpool.cpp | 2 +- .../ags/engine/ac/dynobj/managedobjectpool.h | 6 +-- engines/ags/engine/ac/dynobj/scriptdict.h | 2 +- engines/ags/engine/ac/dynobj/scriptset.h | 6 +-- .../ags/engine/ac/dynobj/scriptuserobject.cpp | 2 +- engines/ags/engine/ac/gamestate.cpp | 2 +- engines/ags/engine/ac/gamestate.h | 4 +- engines/ags/engine/ac/listbox.cpp | 2 +- engines/ags/engine/ac/overlay.h | 2 +- engines/ags/engine/ac/route_finder_jps.inl | 10 ++--- engines/ags/engine/ac/timer.h | 6 +-- engines/ags/engine/debugging/debug.cpp | 6 +-- engines/ags/engine/debugging/logfile.h | 2 +- engines/ags/engine/debugging/messagebuffer.h | 2 +- engines/ags/engine/game/savegame.h | 2 +- engines/ags/engine/game/savegame_internal.h | 4 +- engines/ags/engine/game/viewport.h | 4 +- engines/ags/engine/gfx/ali3dogl.cpp | 2 +- engines/ags/engine/gfx/ali3dogl.h | 2 +- engines/ags/engine/gfx/ali3dsw.cpp | 2 +- engines/ags/engine/gfx/ali3dsw.h | 2 +- engines/ags/engine/gfx/gfxdriverbase.h | 2 +- engines/ags/engine/gfx/gfxdriverfactory.h | 2 +- engines/ags/engine/gfx/gfxdriverfactorybase.h | 2 +- engines/ags/engine/gfx/gfxfilter.h | 2 +- engines/ags/engine/gfx/graphicsdriver.h | 2 +- engines/ags/engine/main/game_run.cpp | 4 +- engines/ags/engine/media/audio/audio.h | 2 +- .../platform/base/agsplatformdriver.cpp | 2 +- .../engine/platform/base/agsplatformdriver.h | 2 +- .../engine/platform/windows/gfx/ali3dd3d.h | 2 +- .../platform/windows/setup/winsetup.cpp | 4 +- engines/ags/engine/plugin/agsplugin.cpp | 2 +- engines/ags/engine/plugin/plugin_engine.h | 2 +- engines/ags/engine/script/cc_instance.h | 4 +- .../engine/script/nonblockingscriptfunction.h | 2 +- engines/ags/engine/script/script.h | 2 +- engines/ags/engine/script/systemimports.h | 2 +- engines/ags/engine/util/mutex_std.h | 2 +- engines/ags/engine/util/thread_std.h | 2 +- engines/ags/{ => lib}/std/algorithm.h | 0 engines/ags/{ => lib}/std/array.h | 0 engines/ags/{ => lib}/std/chrono.h | 0 engines/ags/{ => lib}/std/functional.h | 0 engines/ags/{ => lib}/std/initializer_list.h | 0 engines/ags/{ => lib}/std/limits.h | 0 engines/ags/{ => lib}/std/list.h | 0 engines/ags/{ => lib}/std/map.h | 2 +- engines/ags/{ => lib}/std/math.h | 2 +- engines/ags/{ => lib}/std/memory.h | 0 engines/ags/{ => lib}/std/mutex.h | 0 engines/ags/{ => lib}/std/queue.h | 4 +- engines/ags/{ => lib}/std/set.h | 0 engines/ags/lib/std/std.cpp | 44 +++++++++++++++++++ engines/ags/{ => lib}/std/thread.h | 2 +- engines/ags/{ => lib}/std/type_traits.h | 0 engines/ags/{ => lib}/std/unordered_set.h | 0 engines/ags/{ => lib}/std/utility.h | 0 engines/ags/{ => lib}/std/vector.h | 0 engines/ags/{ => lib}/std/xtr1common.h | 0 engines/ags/{ => lib}/std/xutility.h | 0 engines/ags/module.mk | 1 + engines/ags/shared/ac/gamesetupstruct.h | 4 +- engines/ags/shared/ac/spritecache.h | 4 +- engines/ags/shared/ac/view.h | 2 +- engines/ags/shared/ac/wordsdictionary.cpp | 2 +- engines/ags/shared/core/asset.h | 2 +- engines/ags/shared/debugging/debugmanager.h | 4 +- engines/ags/shared/font/fonts.cpp | 2 +- engines/ags/shared/font/fonts.h | 2 +- engines/ags/shared/font/ttffontrenderer.h | 2 +- engines/ags/shared/font/wfnfont.cpp | 2 +- engines/ags/shared/font/wfnfont.h | 2 +- engines/ags/shared/font/wfnfontrenderer.h | 2 +- engines/ags/shared/game/customproperties.h | 2 +- engines/ags/shared/game/interactions.h | 2 +- engines/ags/shared/game/main_game_file.h | 6 +-- engines/ags/shared/game/plugininfo.h | 2 +- engines/ags/shared/game/room_file.h | 4 +- engines/ags/shared/game/roomstruct.h | 2 +- engines/ags/shared/gui/guibutton.h | 2 +- engines/ags/shared/gui/guiinv.h | 2 +- engines/ags/shared/gui/guilabel.h | 2 +- engines/ags/shared/gui/guilistbox.h | 2 +- engines/ags/shared/gui/guimain.cpp | 2 +- engines/ags/shared/gui/guimain.h | 4 +- engines/ags/shared/gui/guislider.h | 2 +- engines/ags/shared/gui/guitextbox.h | 2 +- engines/ags/shared/script/cc_error.cpp | 2 +- engines/ags/shared/script/cc_script.h | 2 +- engines/ags/shared/util/bufferedstream.cpp | 4 +- engines/ags/shared/util/bufferedstream.h | 2 +- engines/ags/shared/util/error.h | 2 +- engines/ags/shared/util/geometry.cpp | 4 +- engines/ags/shared/util/ini_util.cpp | 2 +- engines/ags/shared/util/ini_util.h | 2 +- engines/ags/shared/util/inifile.h | 4 +- engines/ags/shared/util/string.cpp | 2 +- engines/ags/shared/util/string.h | 2 +- engines/ags/shared/util/string_types.h | 4 +- 107 files changed, 167 insertions(+), 122 deletions(-) rename engines/ags/{ => lib}/std/algorithm.h (100%) rename engines/ags/{ => lib}/std/array.h (100%) rename engines/ags/{ => lib}/std/chrono.h (100%) rename engines/ags/{ => lib}/std/functional.h (100%) rename engines/ags/{ => lib}/std/initializer_list.h (100%) rename engines/ags/{ => lib}/std/limits.h (100%) rename engines/ags/{ => lib}/std/list.h (100%) rename engines/ags/{ => lib}/std/map.h (98%) rename engines/ags/{ => lib}/std/math.h (97%) rename engines/ags/{ => lib}/std/memory.h (100%) rename engines/ags/{ => lib}/std/mutex.h (100%) rename engines/ags/{ => lib}/std/queue.h (96%) rename engines/ags/{ => lib}/std/set.h (100%) create mode 100644 engines/ags/lib/std/std.cpp rename engines/ags/{ => lib}/std/thread.h (98%) rename engines/ags/{ => lib}/std/type_traits.h (100%) rename engines/ags/{ => lib}/std/unordered_set.h (100%) rename engines/ags/{ => lib}/std/utility.h (100%) rename engines/ags/{ => lib}/std/vector.h (100%) rename engines/ags/{ => lib}/std/xtr1common.h (100%) rename engines/ags/{ => lib}/std/xutility.h (100%) diff --git a/engines/ags/engine/ac/asset_helper.h b/engines/ags/engine/ac/asset_helper.h index 7c6160af7bd1..4ce099cc9bbb 100644 --- a/engines/ags/engine/ac/asset_helper.h +++ b/engines/ags/engine/ac/asset_helper.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_AC_ASSETHELPER_H #define AGS_ENGINE_AC_ASSETHELPER_H -#include "ags/std/memory.h" -#include "ags/std/utility.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/utility.h" #include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h index 696c195b5e65..6621259050b3 100644 --- a/engines/ags/engine/ac/dialog.h +++ b/engines/ags/engine/ac/dialog.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DIALOG_H #define AGS_ENGINE_AC_DIALOG_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/engine/ac/dynobj/scriptdialog.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index 8f824f35c796..d74095bdee3e 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/std/algorithm.h" -#include "ags/std/math.h" +#include "ags/lib/std/algorithm.h" +#include "ags/lib/std/math.h" #include "ags/lib/aastr-0.1.1/aastr.h" #include "ags/shared/core/platform.h" #include "ags/shared/ac/common.h" diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h index 03901e7884f6..481a50270069 100644 --- a/engines/ags/engine/ac/draw.h +++ b/engines/ags/engine/ac/draw.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DRAW_H #define AGS_ENGINE_AC_DRAW_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/core/types.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/gfx/gfx_def.h" diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index 999d9b4a7bc3..e6af2262bcb3 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -46,8 +46,8 @@ // //============================================================================= -#include "ags/std/utility.h" -#include "ags/std/vector.h" +#include "ags/lib/std/utility.h" +#include "ags/lib/std/vector.h" #include "ags/engine/ac/draw_software.h" #include "ags/shared/gfx/bitmap.h" #include "ags/engine/util/scaling.h" diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h index aea7d06935c8..d68244e64c5d 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCDYNAMICARRAY_H #define AGS_ENGINE_AC_DYNOBJ_CCDYNAMICARRAY_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/engine/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h index 93bc6593516f..88e4aa1d5a3e 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicobject.h +++ b/engines/ags/engine/ac/dynobj/cc_dynamicobject.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_CCDYNAMICOBJECT_H #define AGS_ENGINE_AC_DYNOBJ_CCDYNAMICOBJECT_H -#include "ags/std/utility.h" +#include "ags/lib/std/utility.h" #include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index d7b30f4ef968..f89fe386984b 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" //include #include "ags/engine/ac/dynobj/managedobjectpool.h" #include "ags/engine/ac/dynobj/cc_dynamicarray.h" // globalDynamicArray, constants diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.h b/engines/ags/engine/ac/dynobj/managedobjectpool.h index a66f23c8693f..1dee09a0dae6 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.h +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_MANAGEDOBJECTPOOL_H #define AGS_ENGINE_AC_DYNOBJ_MANAGEDOBJECTPOOL_H -#include "ags/std/vector.h" -#include "ags/std/queue.h" -#include "ags/std/map.h" +#include "ags/lib/std/vector.h" +#include "ags/lib/std/queue.h" +#include "ags/lib/std/map.h" #include "ags/engine/script/runtimescriptvalue.h" #include "ags/engine/ac/dynobj/cc_dynamicobject.h" // ICCDynamicObject #include "ags/shared/util/string_types.h" diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index e560fccf9e02..8d6210da2794 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -37,7 +37,7 @@ #define AGS_ENGINE_AC_DYNOBJ_SCRIPTDICT_H //include -#include "ags/std/map.h" +#include "ags/lib/std/map.h" #include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" diff --git a/engines/ags/engine/ac/dynobj/scriptset.h b/engines/ags/engine/ac/dynobj/scriptset.h index 10a00757acac..073390d0dda1 100644 --- a/engines/ags/engine/ac/dynobj/scriptset.h +++ b/engines/ags/engine/ac/dynobj/scriptset.h @@ -35,9 +35,9 @@ #ifndef AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H #define AGS_ENGINE_AC_DYNOBJ_SCRIPTSET_H -#include "ags/std/set.h" -#include "ags/std/unordered_set.h" -#include "ags/std/map.h" +#include "ags/lib/std/set.h" +#include "ags/lib/std/unordered_set.h" +#include "ags/lib/std/map.h" #include "ags/engine/ac/dynobj/cc_agsdynamicobject.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" diff --git a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp index ae02f3cb91fb..81a709540508 100644 --- a/engines/ags/engine/ac/dynobj/scriptuserobject.cpp +++ b/engines/ags/engine/ac/dynobj/scriptuserobject.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/engine/ac/dynobj/scriptuserobject.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp index 125f211b533c..347899db76eb 100644 --- a/engines/ags/engine/ac/gamestate.cpp +++ b/engines/ags/engine/ac/gamestate.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" #include "ags/engine/ac/draw.h" #include "ags/shared/ac/game_version.h" #include "ags/engine/ac/gamestate.h" diff --git a/engines/ags/engine/ac/gamestate.h b/engines/ags/engine/ac/gamestate.h index cf6102581fb7..0285962a5e9c 100644 --- a/engines/ags/engine/ac/gamestate.h +++ b/engines/ags/engine/ac/gamestate.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_AC_GAMESTATE_H #define AGS_ENGINE_AC_GAMESTATE_H -#include "ags/std/memory.h" -#include "ags/std/vector.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/vector.h" #include "ags/shared/ac/characterinfo.h" #include "ags/engine/ac/runtime_defines.h" #include "ags/shared/game/roomstruct.h" diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index 081cc25e27d0..baeeab72222e 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/set.h" +#include "ags/lib/std/set.h" #include "ags/engine/ac/listbox.h" #include "ags/shared/ac/common.h" #include "ags/engine/ac/game.h" diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h index 8300596c6f49..429da7ace82e 100644 --- a/engines/ags/engine/ac/overlay.h +++ b/engines/ags/engine/ac/overlay.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_AC_OVERLAY_H #define AGS_ENGINE_AC_OVERLAY_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/engine/ac/screenoverlay.h" #include "ags/engine/ac/dynobj/scriptoverlay.h" diff --git a/engines/ags/engine/ac/route_finder_jps.inl b/engines/ags/engine/ac/route_finder_jps.inl index 0f21f05c75a4..c977b48f57db 100644 --- a/engines/ags/engine/ac/route_finder_jps.inl +++ b/engines/ags/engine/ac/route_finder_jps.inl @@ -27,11 +27,11 @@ // //============================================================================= -#include "ags/std/queue.h" -#include "ags/std/vector.h" -#include "ags/std/algorithm.h" -#include "ags/std/functional.h" -#include "ags/std/xutility.h" +#include "ags/lib/std/queue.h" +#include "ags/lib/std/vector.h" +#include "ags/lib/std/algorithm.h" +#include "ags/lib/std/functional.h" +#include "ags/lib/std/xutility.h" //include //include //include diff --git a/engines/ags/engine/ac/timer.h b/engines/ags/engine/ac/timer.h index b737923aee74..6470e7ff7b71 100644 --- a/engines/ags/engine/ac/timer.h +++ b/engines/ags/engine/ac/timer.h @@ -23,9 +23,9 @@ #ifndef AGS_ENGINE_AC_TIMER_H #define AGS_ENGINE_AC_TIMER_H -#include "ags/std/type_traits.h" -#include "ags/std/chrono.h" -#include "ags/std/xtr1common.h" +#include "ags/lib/std/type_traits.h" +#include "ags/lib/std/chrono.h" +#include "ags/lib/std/xtr1common.h" namespace AGS3 { diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index 903787665d9d..921108c4b2f9 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -20,9 +20,9 @@ * */ -#include "ags/std/initializer_list.h" -#include "ags/std/limits.h" -#include "ags/std/memory.h" +#include "ags/lib/std/initializer_list.h" +#include "ags/lib/std/limits.h" +#include "ags/lib/std/memory.h" #include "ags/shared/core/platform.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" diff --git a/engines/ags/engine/debugging/logfile.h b/engines/ags/engine/debugging/logfile.h index 18a43563427b..1f93d6499943 100644 --- a/engines/ags/engine/debugging/logfile.h +++ b/engines/ags/engine/debugging/logfile.h @@ -35,7 +35,7 @@ #ifndef AGS_ENGINE_DEBUGGING_LOGFILE_H #define AGS_ENGINE_DEBUGGING_LOGFILE_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/debugging/outputhandler.h" namespace AGS3 { diff --git a/engines/ags/engine/debugging/messagebuffer.h b/engines/ags/engine/debugging/messagebuffer.h index 57016fe61148..34956e8e472b 100644 --- a/engines/ags/engine/debugging/messagebuffer.h +++ b/engines/ags/engine/debugging/messagebuffer.h @@ -31,7 +31,7 @@ #ifndef AGS_ENGINE_DEBUGGING_MESSAGEBUFFER_H #define AGS_ENGINE_DEBUGGING_MESSAGEBUFFER_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/debugging/outputhandler.h" namespace AGS3 { diff --git a/engines/ags/engine/game/savegame.h b/engines/ags/engine/game/savegame.h index 53b7d355d276..ff0804025d57 100644 --- a/engines/ags/engine/game/savegame.h +++ b/engines/ags/engine/game/savegame.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_GAME_SAVEGAME_H #define AGS_ENGINE_GAME_SAVEGAME_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/ac/game_version.h" #include "ags/shared/util/error.h" #include "ags/shared/util/version.h" diff --git a/engines/ags/engine/game/savegame_internal.h b/engines/ags/engine/game/savegame_internal.h index 5db638911e01..29661bdc7c51 100644 --- a/engines/ags/engine/game/savegame_internal.h +++ b/engines/ags/engine/game/savegame_internal.h @@ -23,8 +23,8 @@ #ifndef AGS_ENGINE_GAME_SAVEGAMEINTERNAL_H #define AGS_ENGINE_GAME_SAVEGAMEINTERNAL_H -#include "ags/std/memory.h" -#include "ags/std/vector.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/vector.h" #include "ags/shared/ac/common_defines.h" #include "ags/shared/gfx/bitmap.h" #include "ags/engine/media/audio/audiodefines.h" diff --git a/engines/ags/engine/game/viewport.h b/engines/ags/engine/game/viewport.h index 3834dd9e0a01..3d7964300ab2 100644 --- a/engines/ags/engine/game/viewport.h +++ b/engines/ags/engine/game/viewport.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_GAME_VIEWPORT_H #define AGS_ENGINE_GAME_VIEWPORT_H -#include "ags/std/memory.h" -#include "ags/std/vector.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/vector.h" #include "ags/shared/util/geometry.h" #include "ags/engine/util/scaling.h" diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index ec1b2825c165..6d621b1c0267 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -24,7 +24,7 @@ #if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" #include "ags/engine/gfx/ali3dexception.h" #include "ags/engine/gfx/ali3dogl.h" #include "ags/engine/gfx/gfxfilter_ogl.h" diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h index c3f944d35836..e6dd2e35e84c 100644 --- a/engines/ags/engine/gfx/ali3dogl.h +++ b/engines/ags/engine/gfx/ali3dogl.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_ALI3DOGL_H #define AGS_ENGINE_GFX_ALI3DOGL_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/gfx/bitmap.h" #include "ags/engine/gfx/ddb.h" #include "ags/engine/gfx/gfxdriverfactorybase.h" diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dsw.cpp index 9d82d3cb4230..3e67d3760221 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dsw.cpp @@ -37,7 +37,7 @@ #include "ags/engine/ac/timer.h" #include "ags/lib/allegro/color.h" #include "ags/lib/opengl/opengl.h" -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" #include "ags/ags.h" namespace AGS3 { diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dsw.h index a9e2a4fb2993..c168667c504c 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dsw.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_ALI3DSW_H #define AGS_ENGINE_GFX_ALI3DSW_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/core/platform.h" #define AGS_DDRAW_GAMMA_CONTROL (AGS_PLATFORM_OS_WINDOWS) diff --git a/engines/ags/engine/gfx/gfxdriverbase.h b/engines/ags/engine/gfx/gfxdriverbase.h index 88f83fa6b076..5241a76d3697 100644 --- a/engines/ags/engine/gfx/gfxdriverbase.h +++ b/engines/ags/engine/gfx/gfxdriverbase.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_GFXDRIVERBASE_H #define AGS_ENGINE_GFX_GFXDRIVERBASE_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/engine/gfx/ddb.h" #include "ags/engine/gfx/graphicsdriver.h" #include "ags/engine/util/scaling.h" diff --git a/engines/ags/engine/gfx/gfxdriverfactory.h b/engines/ags/engine/gfx/gfxdriverfactory.h index b28560d76530..2873b345c0b1 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.h +++ b/engines/ags/engine/gfx/gfxdriverfactory.h @@ -33,7 +33,7 @@ #ifndef AGS_ENGINE_GFX_GFXDRIVERFACTORY_H #define AGS_ENGINE_GFX_GFXDRIVERFACTORY_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" diff --git a/engines/ags/engine/gfx/gfxdriverfactorybase.h b/engines/ags/engine/gfx/gfxdriverfactorybase.h index 8a1d66d5675d..911f718d83e4 100644 --- a/engines/ags/engine/gfx/gfxdriverfactorybase.h +++ b/engines/ags/engine/gfx/gfxdriverfactorybase.h @@ -33,7 +33,7 @@ #ifndef AGS_ENGINE_GFX_GFXDRIVERFACTORYBASE_H #define AGS_ENGINE_GFX_GFXDRIVERFACTORYBASE_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/engine/gfx/gfxdriverfactory.h" #include "ags/engine/gfx/gfxfilter.h" diff --git a/engines/ags/engine/gfx/gfxfilter.h b/engines/ags/engine/gfx/gfxfilter.h index 7b0f636215a8..1e03c7719016 100644 --- a/engines/ags/engine/gfx/gfxfilter.h +++ b/engines/ags/engine/gfx/gfxfilter.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_GFXFILTER_H #define AGS_ENGINE_GFX_GFXFILTER_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/util/geometry.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/engine/gfx/graphicsdriver.h b/engines/ags/engine/gfx/graphicsdriver.h index 1024addc128f..9ff9a77c9c58 100644 --- a/engines/ags/engine/gfx/graphicsdriver.h +++ b/engines/ags/engine/gfx/graphicsdriver.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_GFX_GRAPHICSDRIVER_H #define AGS_ENGINE_GFX_GRAPHICSDRIVER_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/engine/gfx/gfxdefines.h" #include "ags/engine/gfx/gfxmodelist.h" #include "ags/shared/util/geometry.h" diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 541b1ab719f9..a695db97ac08 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -24,8 +24,8 @@ // Game loop // -#include "ags/std/limits.h" -#include "ags/std/chrono.h" +#include "ags/lib/std/limits.h" +#include "ags/lib/std/chrono.h" #include "ags/shared/ac/common.h" #include "ags/engine/ac/characterextras.h" #include "ags/shared/ac/characterinfo.h" diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index 42471bfd7608..192de3246e56 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_AUDIO_H #define AGS_ENGINE_MEDIA_AUDIO_AUDIO_H -#include "ags/std/array.h" +#include "ags/lib/std/array.h" #include "ags/engine/media/audio/audiodefines.h" #include "ags/shared/ac/dynobj/scriptaudioclip.h" #include "ags/engine/ac/dynobj/scriptaudiochannel.h" diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index 11d4e585eb18..ea977eb50494 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -37,7 +37,7 @@ #include "ags/engine/ac/timer.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/lib/system/datetime.h" -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" #if defined (AGS_HAS_CD_AUDIO) #include "libcda.h" diff --git a/engines/ags/engine/platform/base/agsplatformdriver.h b/engines/ags/engine/platform/base/agsplatformdriver.h index 1975d94353ee..95c7c68b3d04 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.h +++ b/engines/ags/engine/platform/base/agsplatformdriver.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H #define AGS_ENGINE_PLATFORM_BASE_AGSPLATFORMDRIVER_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/engine/ac/datetime.h" #include "ags/shared/debugging/outputhandler.h" #include "ags/shared/util/ini_util.h" diff --git a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h index deb25f9d9785..62558e34c62f 100644 --- a/engines/ags/engine/platform/windows/gfx/ali3dd3d.h +++ b/engines/ags/engine/platform/windows/gfx/ali3dd3d.h @@ -35,7 +35,7 @@ #error This file should only be included on the Windows build #endif -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/lib/allegro.h" //include //include diff --git a/engines/ags/engine/platform/windows/setup/winsetup.cpp b/engines/ags/engine/platform/windows/setup/winsetup.cpp index 3a3e824f10a3..3ee704f37623 100644 --- a/engines/ags/engine/platform/windows/setup/winsetup.cpp +++ b/engines/ags/engine/platform/windows/setup/winsetup.cpp @@ -29,10 +29,10 @@ //include //include //include -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" //include //include -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/ac/gamestructdefines.h" #undef RGB #undef PALETTE diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 5307263fd939..f128e0c5992f 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/core/platform.h" #if AGS_PLATFORM_OS_WINDOWS #include "ags/shared/platform/windows/winapi_exclusive.h" diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/engine/plugin/plugin_engine.h index 736f5d5950f9..430d3c5d7e74 100644 --- a/engines/ags/engine/plugin/plugin_engine.h +++ b/engines/ags/engine/plugin/plugin_engine.h @@ -29,7 +29,7 @@ #ifndef AGS_ENGINE_PLUGIN_PLUGIN_ENGINE_H #define AGS_ENGINE_PLUGIN_PLUGIN_ENGINE_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/engine/game/game_init.h" #include "ags/shared/game/plugininfo.h" diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h index 7b0dd97c2c4f..efa176d30fbe 100644 --- a/engines/ags/engine/script/cc_instance.h +++ b/engines/ags/engine/script/cc_instance.h @@ -29,8 +29,8 @@ #ifndef AGS_ENGINE_SCRIPT_CCINSTANCE_H #define AGS_ENGINE_SCRIPT_CCINSTANCE_H -#include "ags/std/map.h" -#include "ags/std/memory.h" +#include "ags/lib/std/map.h" +#include "ags/lib/std/memory.h" #include "ags/shared/script/script_common.h" #include "ags/shared/script/cc_script.h" // ccScript #include "ags/engine/script/nonblockingscriptfunction.h" diff --git a/engines/ags/engine/script/nonblockingscriptfunction.h b/engines/ags/engine/script/nonblockingscriptfunction.h index a7e982a1cd0e..b4439ff3a8ae 100644 --- a/engines/ags/engine/script/nonblockingscriptfunction.h +++ b/engines/ags/engine/script/nonblockingscriptfunction.h @@ -26,7 +26,7 @@ #include "ags/engine/ac/runtime_defines.h" #include "ags/engine/script/runtimescriptvalue.h" -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script.h b/engines/ags/engine/script/script.h index 8c797038cdc5..abc5eea914db 100644 --- a/engines/ags/engine/script/script.h +++ b/engines/ags/engine/script/script.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_SCRIPT_SCRIPT_H #define AGS_ENGINE_SCRIPT_SCRIPT_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/game/roomstruct.h" // MAX_ROOM_OBJECTS #include "ags/engine/script/cc_instance.h" diff --git a/engines/ags/engine/script/systemimports.h b/engines/ags/engine/script/systemimports.h index 4bf2238dd9ca..1332252b0681 100644 --- a/engines/ags/engine/script/systemimports.h +++ b/engines/ags/engine/script/systemimports.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H #define AGS_ENGINE_SCRIPT_SYSTEMIMPORTS_H -#include "ags/std/map.h" +#include "ags/lib/std/map.h" #include "ags/engine/script/cc_instance.h" // ccInstance #include "ags/shared/util/string_types.h" diff --git a/engines/ags/engine/util/mutex_std.h b/engines/ags/engine/util/mutex_std.h index 41ab31ea262b..47c62091840d 100644 --- a/engines/ags/engine/util/mutex_std.h +++ b/engines/ags/engine/util/mutex_std.h @@ -24,7 +24,7 @@ #define AGS_ENGINE_UTIL_MUTEX_STD_H #include "ags/engine/util/mutex.h" -#include "ags/std/mutex.h" +#include "ags/lib/std/mutex.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/util/thread_std.h b/engines/ags/engine/util/thread_std.h index 88d6543f6107..1ad4477838df 100644 --- a/engines/ags/engine/util/thread_std.h +++ b/engines/ags/engine/util/thread_std.h @@ -25,7 +25,7 @@ //include #include "ags/engine/util/thread.h" -#include "ags/std/thread.h" +#include "ags/lib/std/thread.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/std/algorithm.h b/engines/ags/lib/std/algorithm.h similarity index 100% rename from engines/ags/std/algorithm.h rename to engines/ags/lib/std/algorithm.h diff --git a/engines/ags/std/array.h b/engines/ags/lib/std/array.h similarity index 100% rename from engines/ags/std/array.h rename to engines/ags/lib/std/array.h diff --git a/engines/ags/std/chrono.h b/engines/ags/lib/std/chrono.h similarity index 100% rename from engines/ags/std/chrono.h rename to engines/ags/lib/std/chrono.h diff --git a/engines/ags/std/functional.h b/engines/ags/lib/std/functional.h similarity index 100% rename from engines/ags/std/functional.h rename to engines/ags/lib/std/functional.h diff --git a/engines/ags/std/initializer_list.h b/engines/ags/lib/std/initializer_list.h similarity index 100% rename from engines/ags/std/initializer_list.h rename to engines/ags/lib/std/initializer_list.h diff --git a/engines/ags/std/limits.h b/engines/ags/lib/std/limits.h similarity index 100% rename from engines/ags/std/limits.h rename to engines/ags/lib/std/limits.h diff --git a/engines/ags/std/list.h b/engines/ags/lib/std/list.h similarity index 100% rename from engines/ags/std/list.h rename to engines/ags/lib/std/list.h diff --git a/engines/ags/std/map.h b/engines/ags/lib/std/map.h similarity index 98% rename from engines/ags/std/map.h rename to engines/ags/lib/std/map.h index 70156b9cb25d..3d596dc0c763 100644 --- a/engines/ags/std/map.h +++ b/engines/ags/lib/std/map.h @@ -24,7 +24,7 @@ #define AGS_STD_MAP_H #include "common/hashmap.h" -#include "ags/std/utility.h" +#include "ags/lib/std/utility.h" namespace AGS3 { namespace std { diff --git a/engines/ags/std/math.h b/engines/ags/lib/std/math.h similarity index 97% rename from engines/ags/std/math.h rename to engines/ags/lib/std/math.h index 8fa5814ed62a..14cc22682212 100644 --- a/engines/ags/std/math.h +++ b/engines/ags/lib/std/math.h @@ -24,7 +24,7 @@ #define AGS_STD_MATH_H #include "common/hashmap.h" -#include "ags/std/utility.h" +#include "ags/lib/std/utility.h" namespace AGS3 { namespace std { diff --git a/engines/ags/std/memory.h b/engines/ags/lib/std/memory.h similarity index 100% rename from engines/ags/std/memory.h rename to engines/ags/lib/std/memory.h diff --git a/engines/ags/std/mutex.h b/engines/ags/lib/std/mutex.h similarity index 100% rename from engines/ags/std/mutex.h rename to engines/ags/lib/std/mutex.h diff --git a/engines/ags/std/queue.h b/engines/ags/lib/std/queue.h similarity index 96% rename from engines/ags/std/queue.h rename to engines/ags/lib/std/queue.h index 52761ec45d9f..b8846fd8c473 100644 --- a/engines/ags/std/queue.h +++ b/engines/ags/lib/std/queue.h @@ -23,8 +23,8 @@ #ifndef AGS_STD_QUEUE_H #define AGS_STD_QUEUE_H -#include "ags/std/algorithm.h" -#include "ags/std/vector.h" +#include "ags/lib/std/algorithm.h" +#include "ags/lib/std/vector.h" #include "common/queue.h" namespace AGS3 { diff --git a/engines/ags/std/set.h b/engines/ags/lib/std/set.h similarity index 100% rename from engines/ags/std/set.h rename to engines/ags/lib/std/set.h diff --git a/engines/ags/lib/std/std.cpp b/engines/ags/lib/std/std.cpp new file mode 100644 index 000000000000..4a737d3cbe73 --- /dev/null +++ b/engines/ags/lib/std/std.cpp @@ -0,0 +1,44 @@ +/* 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. + * + */ + +// Dummy include of STD mockup headers so they'll appear in the Visual Studio project + +#include "ags/lib/std/algorithm.h" +#include "ags/lib/std/array.h" +#include "ags/lib/std/chrono.h" +#include "ags/lib/std/functional.h" +#include "ags/lib/std/initializer_list.h" +#include "ags/lib/std/limits.h" +#include "ags/lib/std/list.h" +#include "ags/lib/std/map.h" +#include "ags/lib/std/math.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/mutex.h" +#include "ags/lib/std/queue.h" +#include "ags/lib/std/set.h" +#include "ags/lib/std/thread.h" +#include "ags/lib/std/type_traits.h" +#include "ags/lib/std/unordered_set.h" +#include "ags/lib/std/utility.h" +#include "ags/lib/std/vector.h" +#include "ags/lib/std/xtr1common.h" +#include "ags/lib/std/xutility.h" diff --git a/engines/ags/std/thread.h b/engines/ags/lib/std/thread.h similarity index 98% rename from engines/ags/std/thread.h rename to engines/ags/lib/std/thread.h index 53455e9dd05f..bdd43e6cf7d3 100644 --- a/engines/ags/std/thread.h +++ b/engines/ags/lib/std/thread.h @@ -23,7 +23,7 @@ #ifndef AGS_STD_THREAD_H #define AGS_STD_THREAD_H -#include "ags/std/chrono.h" +#include "ags/lib/std/chrono.h" #include "common/textconsole.h" namespace AGS3 { diff --git a/engines/ags/std/type_traits.h b/engines/ags/lib/std/type_traits.h similarity index 100% rename from engines/ags/std/type_traits.h rename to engines/ags/lib/std/type_traits.h diff --git a/engines/ags/std/unordered_set.h b/engines/ags/lib/std/unordered_set.h similarity index 100% rename from engines/ags/std/unordered_set.h rename to engines/ags/lib/std/unordered_set.h diff --git a/engines/ags/std/utility.h b/engines/ags/lib/std/utility.h similarity index 100% rename from engines/ags/std/utility.h rename to engines/ags/lib/std/utility.h diff --git a/engines/ags/std/vector.h b/engines/ags/lib/std/vector.h similarity index 100% rename from engines/ags/std/vector.h rename to engines/ags/lib/std/vector.h diff --git a/engines/ags/std/xtr1common.h b/engines/ags/lib/std/xtr1common.h similarity index 100% rename from engines/ags/std/xtr1common.h rename to engines/ags/lib/std/xtr1common.h diff --git a/engines/ags/std/xutility.h b/engines/ags/lib/std/xutility.h similarity index 100% rename from engines/ags/std/xutility.h rename to engines/ags/lib/std/xutility.h diff --git a/engines/ags/module.mk b/engines/ags/module.mk index fd1677c0591e..59e28d33b6bd 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -27,6 +27,7 @@ MODULE_OBJS = \ lib/audio/sound.o \ lib/audio/wav.o \ lib/opengl/opengl.o \ + lib/std/std.o \ lib/system/datetime.o \ shared/ac/dynobj/scriptaudioclip.o \ shared/ac/audiocliptype.o \ diff --git a/engines/ags/shared/ac/gamesetupstruct.h b/engines/ags/shared/ac/gamesetupstruct.h index 3d47eea2799a..7dc8660f03b7 100644 --- a/engines/ags/shared/ac/gamesetupstruct.h +++ b/engines/ags/shared/ac/gamesetupstruct.h @@ -23,8 +23,8 @@ #ifndef AGS_SHARED_AC_GAMESETUPSTRUCT_H #define AGS_SHARED_AC_GAMESETUPSTRUCT_H -#include "ags/std/vector.h" -#include "ags/std/memory.h" +#include "ags/lib/std/vector.h" +#include "ags/lib/std/memory.h" #include "ags/shared/ac/audiocliptype.h" #include "ags/shared/ac/characterinfo.h" // TODO: constants to separate header #include "ags/shared/ac/gamesetupstructbase.h" diff --git a/engines/ags/shared/ac/spritecache.h b/engines/ags/shared/ac/spritecache.h index 4ee33e4f61d4..712985ef2403 100644 --- a/engines/ags/shared/ac/spritecache.h +++ b/engines/ags/shared/ac/spritecache.h @@ -45,8 +45,8 @@ #ifndef AGS_SHARED_AC_SPRITECACHE_H #define AGS_SHARED_AC_SPRITECACHE_H -#include "ags/std/memory.h" -#include "ags/std/vector.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/vector.h" #include "ags/shared/core/platform.h" #include "ags/shared/util/error.h" diff --git a/engines/ags/shared/ac/view.h b/engines/ags/shared/ac/view.h index b30b406e585d..e05863aea337 100644 --- a/engines/ags/shared/ac/view.h +++ b/engines/ags/shared/ac/view.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_AC_VIEW_H #define AGS_SHARED_AC_VIEW_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" namespace AGS3 { diff --git a/engines/ags/shared/ac/wordsdictionary.cpp b/engines/ags/shared/ac/wordsdictionary.cpp index 6ec5cfe5719e..a73f247a93d4 100644 --- a/engines/ags/shared/ac/wordsdictionary.cpp +++ b/engines/ags/shared/ac/wordsdictionary.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" //include #include "ags/shared/ac/wordsdictionary.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/shared/core/asset.h b/engines/ags/shared/core/asset.h index bcbed3a231a6..71081a871632 100644 --- a/engines/ags/shared/core/asset.h +++ b/engines/ags/shared/core/asset.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_CORE_ASSET_H #define AGS_SHARED_CORE_ASSET_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h index eefa9aac0172..a8b92fc52771 100644 --- a/engines/ags/shared/debugging/debugmanager.h +++ b/engines/ags/shared/debugging/debugmanager.h @@ -47,8 +47,8 @@ #ifndef AGS_SHARED_DEBUGGING_DEBUGMANAGER_H #define AGS_SHARED_DEBUGGING_DEBUGMANAGER_H -#include "ags/std/memory.h" -#include "ags/std/map.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/map.h" #include "ags/shared/debugging/out.h" #include "ags/shared/debugging/outputhandler.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index ad4c4c5ab2a6..5ffaf7788f8a 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/lib/alfont/alfont.h" #include "ags/shared/ac/common.h" // set_our_eip #include "ags/shared/ac/gamestructdefines.h" diff --git a/engines/ags/shared/font/fonts.h b/engines/ags/shared/font/fonts.h index 56dcb7d3c091..b9374f49d656 100644 --- a/engines/ags/shared/font/fonts.h +++ b/engines/ags/shared/font/fonts.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_FONT_FONTS_H #define AGS_SHARED_FONT_FONTS_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/core/types.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 368dac016ec3..033425cdc624 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_FONT_TTFFONTRENDERER_H #define AGS_SHARED_FONT_TTFFONTRENDERER_H -#include "ags/std/map.h" +#include "ags/lib/std/map.h" #include "ags/lib/alfont/alfont.h" #include "ags/shared/font/agsfontrenderer.h" diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index c98d5e3d1ced..2e07a5955c05 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" #include "ags/shared/font/wfnfont.h" #include "ags/shared/debugging/out.h" #include "ags/shared/util/memory.h" diff --git a/engines/ags/shared/font/wfnfont.h b/engines/ags/shared/font/wfnfont.h index 583d30459877..c5e23e3956a0 100644 --- a/engines/ags/shared/font/wfnfont.h +++ b/engines/ags/shared/font/wfnfont.h @@ -46,7 +46,7 @@ #ifndef AGS_SHARED_FONT_WFNFONT_H #define AGS_SHARED_FONT_WFNFONT_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/core/types.h" namespace AGS3 { diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index 76d57efe9b5b..47341efe48c2 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_FONT_WFNFONTRENDERER_H #define AGS_SHARED_FONT_WFNFONTRENDERER_H -#include "ags/std/map.h" +#include "ags/lib/std/map.h" #include "ags/shared/font/agsfontrenderer.h" namespace AGS3 { diff --git a/engines/ags/shared/game/customproperties.h b/engines/ags/shared/game/customproperties.h index 7b956e9d792e..14bcd2eba3f6 100644 --- a/engines/ags/shared/game/customproperties.h +++ b/engines/ags/shared/game/customproperties.h @@ -36,7 +36,7 @@ #ifndef AGS_SHARED_GAME_CUSTOMPROPERTIES_H #define AGS_SHARED_GAME_CUSTOMPROPERTIES_H -#include "ags/std/map.h" +#include "ags/lib/std/map.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" diff --git a/engines/ags/shared/game/interactions.h b/engines/ags/shared/game/interactions.h index ead5ec7a4856..dba759886f3f 100644 --- a/engines/ags/shared/game/interactions.h +++ b/engines/ags/shared/game/interactions.h @@ -50,7 +50,7 @@ #define AGS_SHARED_GAME_INTEREACTIONS_H #include "ags/shared/util/string_types.h" -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" namespace AGS3 { diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 3fb86a794c10..0a30f115e0c1 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -31,9 +31,9 @@ #ifndef AGS_SHARED_GAME_MAINGAMEFILE_H #define AGS_SHARED_GAME_MAINGAMEFILE_H -#include "ags/std/memory.h" -#include "ags/std/set.h" -#include "ags/std/vector.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/set.h" +#include "ags/lib/std/vector.h" #include "ags/shared/ac/game_version.h" #include "ags/shared/game/plugininfo.h" #include "ags/shared/script/cc_script.h" diff --git a/engines/ags/shared/game/plugininfo.h b/engines/ags/shared/game/plugininfo.h index 025ccd8ce6c9..1ce6f27c1361 100644 --- a/engines/ags/shared/game/plugininfo.h +++ b/engines/ags/shared/game/plugininfo.h @@ -29,7 +29,7 @@ #ifndef AGS_SHARED_GAME_PLUGININFO_H #define AGS_SHARED_GAME_PLUGININFO_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/game/room_file.h b/engines/ags/shared/game/room_file.h index 1de92c364b05..1874dbeebf05 100644 --- a/engines/ags/shared/game/room_file.h +++ b/engines/ags/shared/game/room_file.h @@ -31,8 +31,8 @@ #ifndef AGS_SHARED_GAME_ROOMFILE_H #define AGS_SHARED_GAME_ROOMFILE_H -#include "ags/std/memory.h" -#include "ags/std/vector.h" +#include "ags/lib/std/memory.h" +#include "ags/lib/std/vector.h" #include "ags/shared/game/room_version.h" #include "ags/shared/util/error.h" #include "ags/shared/util/stream.h" diff --git a/engines/ags/shared/game/roomstruct.h b/engines/ags/shared/game/roomstruct.h index 40bd7dd461b4..45fe84740a4d 100644 --- a/engines/ags/shared/game/roomstruct.h +++ b/engines/ags/shared/game/roomstruct.h @@ -52,7 +52,7 @@ #include "ags/shared/game/interactions.h" #include "ags/shared/util/geometry.h" #include "ags/shared/util/wgt2allg.h" // color (allegro RGB) -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guibutton.h b/engines/ags/shared/gui/guibutton.h index ab03e4fd23a2..1176faacf487 100644 --- a/engines/ags/shared/gui/guibutton.h +++ b/engines/ags/shared/gui/guibutton.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUIBUTTON_H #define AGS_SHARED_GUI_GUIBUTTON_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/gui/guiinv.h b/engines/ags/shared/gui/guiinv.h index 7ab166063ee4..5e585ded792e 100644 --- a/engines/ags/shared/gui/guiinv.h +++ b/engines/ags/shared/gui/guiinv.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUIINV_H #define AGS_SHARED_GUI_GUIINV_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/gui/guiobject.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guilabel.h b/engines/ags/shared/gui/guilabel.h index 82d7b7538d66..22a690b45f4e 100644 --- a/engines/ags/shared/gui/guilabel.h +++ b/engines/ags/shared/gui/guilabel.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUILABEL_H #define AGS_SHARED_GUI_GUILABEL_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/gui/guilistbox.h b/engines/ags/shared/gui/guilistbox.h index 52193b6af472..b754decaab7d 100644 --- a/engines/ags/shared/gui/guilistbox.h +++ b/engines/ags/shared/gui/guilistbox.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUILISTBOX_H #define AGS_SHARED_GUI_GUILISTBOX_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index 1fb82b51758f..889bf289f712 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -33,7 +33,7 @@ #include "ags/shared/gui/guitextbox.h" #include "ags/shared/util/stream.h" #include "ags/shared/util/string_utils.h" -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index 4c42a25e5907..3e72bbae29f2 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -29,8 +29,8 @@ #include "ags/shared/util/error.h" #include "ags/shared/util/geometry.h" #include "ags/shared/util/string.h" -#include "ags/std/utility.h" -#include "ags/std/vector.h" +#include "ags/lib/std/utility.h" +#include "ags/lib/std/vector.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guislider.h b/engines/ags/shared/gui/guislider.h index 5cbb4fc00d1f..b2ac2663d722 100644 --- a/engines/ags/shared/gui/guislider.h +++ b/engines/ags/shared/gui/guislider.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUISLIDER_H #define AGS_SHARED_GUI_GUISLIDER_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/gui/guiobject.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guitextbox.h b/engines/ags/shared/gui/guitextbox.h index 53b830590aa6..840f3f6e2786 100644 --- a/engines/ags/shared/gui/guitextbox.h +++ b/engines/ags/shared/gui/guitextbox.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_GUI_GUITEXTBOX_H #define AGS_SHARED_GUI_GUITEXTBOX_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/gui/guiobject.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/script/cc_error.cpp b/engines/ags/shared/script/cc_error.cpp index 9e5736bb81e1..f404788f6cbb 100644 --- a/engines/ags/shared/script/cc_error.cpp +++ b/engines/ags/shared/script/cc_error.cpp @@ -22,7 +22,7 @@ #include "ags/shared/script/script_common.h" // current_line #include "ags/shared/util/string.h" -#include "ags/std/utility.h" +#include "ags/lib/std/utility.h" namespace AGS3 { diff --git a/engines/ags/shared/script/cc_script.h b/engines/ags/shared/script/cc_script.h index a0852f5851c6..ad9e440cc6c5 100644 --- a/engines/ags/shared/script/cc_script.h +++ b/engines/ags/shared/script/cc_script.h @@ -30,7 +30,7 @@ #define AGS_SHARED_SCRIPT_CC_SCRIPT_H #include "ags/shared/core/types.h" -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" namespace AGS3 { diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index 69e81b5cbcfc..63f2bc099068 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -20,8 +20,8 @@ * */ -#include "ags/std/algorithm.h" -#include "ags/std/memory.h" +#include "ags/lib/std/algorithm.h" +#include "ags/lib/std/memory.h" #include "ags/shared/util/bufferedstream.h" #include "ags/shared/util/stdio_compat.h" #include "ags/shared/util/string.h" diff --git a/engines/ags/shared/util/bufferedstream.h b/engines/ags/shared/util/bufferedstream.h index ffc16c2de4f8..debae2eaab54 100644 --- a/engines/ags/shared/util/bufferedstream.h +++ b/engines/ags/shared/util/bufferedstream.h @@ -23,7 +23,7 @@ #ifndef AGS_SHARED_UTIL_BUFFEREDSTREAM_H #define AGS_SHARED_UTIL_BUFFEREDSTREAM_H -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/util/filestream.h" #include "ags/shared/util/file.h" // TODO: extract filestream mode constants diff --git a/engines/ags/shared/util/error.h b/engines/ags/shared/util/error.h index 4a983dfea4cb..370a1a6c280c 100644 --- a/engines/ags/shared/util/error.h +++ b/engines/ags/shared/util/error.h @@ -30,7 +30,7 @@ #ifndef AGS_SHARED_UTIL_ERROR_H #define AGS_SHARED_UTIL_ERROR_H -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/shared/util/geometry.cpp b/engines/ags/shared/util/geometry.cpp index 5da09aabd19a..8059f9f5bdfb 100644 --- a/engines/ags/shared/util/geometry.cpp +++ b/engines/ags/shared/util/geometry.cpp @@ -21,8 +21,8 @@ */ #include "ags/shared/util/geometry.h" -#include "ags/std/algorithm.h" -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" +#include "ags/lib/std/algorithm.h" //include namespace AGS3 { diff --git a/engines/ags/shared/util/ini_util.cpp b/engines/ags/shared/util/ini_util.cpp index e4849740d27c..d39d7830c97b 100644 --- a/engines/ags/shared/util/ini_util.cpp +++ b/engines/ags/shared/util/ini_util.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/std/memory.h" +#include "ags/lib/std/memory.h" #include "ags/shared/util/file.h" #include "ags/shared/util/ini_util.h" #include "ags/shared/util/inifile.h" diff --git a/engines/ags/shared/util/ini_util.h b/engines/ags/shared/util/ini_util.h index c3fd2276db1d..a5e36e859aa5 100644 --- a/engines/ags/shared/util/ini_util.h +++ b/engines/ags/shared/util/ini_util.h @@ -30,7 +30,7 @@ #ifndef AGS_SHARED_UTIL_INIUTIL_H #define AGS_SHARED_UTIL_INIUTIL_H -#include "ags/std/map.h" +#include "ags/lib/std/map.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_types.h" diff --git a/engines/ags/shared/util/inifile.h b/engines/ags/shared/util/inifile.h index 0008f7b13da9..b4f7afa6aacd 100644 --- a/engines/ags/shared/util/inifile.h +++ b/engines/ags/shared/util/inifile.h @@ -34,8 +34,8 @@ #define AGS_SHARED_UTIL_INIFILE_H #include "ags/shared/util/string.h" -#include "ags/std/utility.h" -#include "ags/std/list.h" +#include "ags/lib/std/utility.h" +#include "ags/lib/std/list.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp index 49c5fad5ac4f..4fa6ea1f6982 100644 --- a/engines/ags/shared/util/string.cpp +++ b/engines/ags/shared/util/string.cpp @@ -24,7 +24,7 @@ #include "ags/shared/util/stream.h" #include "ags/shared/util/string.h" #include "ags/shared/util/string_compat.h" -#include "ags/std/algorithm.h" +#include "ags/lib/std/algorithm.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h index ae9063c1a375..c492112d0068 100644 --- a/engines/ags/shared/util/string.h +++ b/engines/ags/shared/util/string.h @@ -47,7 +47,7 @@ #define AGS_SHARED_UTIL_STRING_H //include -#include "ags/std/vector.h" +#include "ags/lib/std/vector.h" #include "ags/shared/core/platform.h" #include "ags/shared/core/types.h" #include "ags/shared/debugging/assert.h" diff --git a/engines/ags/shared/util/string_types.h b/engines/ags/shared/util/string_types.h index 0e65ce084eae..bde5fd750e85 100644 --- a/engines/ags/shared/util/string_types.h +++ b/engines/ags/shared/util/string_types.h @@ -23,8 +23,8 @@ #ifndef AGS_SHARED_UTIL_STRINGTYPES_H #define AGS_SHARED_UTIL_STRINGTYPES_H -#include "ags/std/map.h" -#include "ags/std/vector.h" +#include "ags/lib/std/map.h" +#include "ags/lib/std/vector.h" #include "ags/shared/util/string.h" #include "common/hash-str.h" From 7360c5c5cab90fc32912d1cf175958c87b248b5b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 20:59:49 -0800 Subject: [PATCH 043/215] AGS: Added platform driver --- engines/ags/engine/platform/linux/acpllnx.cpp | 42 ++++++++++++------- engines/ags/lib/opengl/opengl.h | 1 + engines/ags/module.mk | 4 +- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index f0279b66023e..415dd3dc725c 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -27,17 +27,17 @@ // ********* LINUX PLACEHOLDER DRIVER ********* //include -#include "ags/lib/allegro.h" //include -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/gfx/gfxdefines.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/plugin/agsplugin.h" -#include "ags/shared/util/string.h" //include - //include //include +#include "ags/lib/allegro.h" +#include "ags/lib/opengl/opengl.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/gfx/gfxdefines.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/shared/util/string.h" namespace AGS3 { @@ -46,8 +46,8 @@ using AGS::Shared::String; // Replace the default Allegro icon. The original defintion is in the // Allegro 4.4 source under "src/x/xwin.c". -#include "ags/shared/icon.xpm" -void *allegro_icon = icon_xpm; +//include "ags/shared/icon.xpm" +//void *allegro_icon = icon_xpm; String CommonDataDirectory; String UserDataDirectory; @@ -75,7 +75,9 @@ struct AGSLinux : AGSPlatformDriver { int AGSLinux::CDPlayerCommand(int cmdd, int datt) { - return cd_player_control(cmdd, datt); + warning("CDPlayerCommand(%d,%d)", cmdd, datt); + //return cd_player_control(cmdd, datt); + return 0; } void AGSLinux::DisplayAlert(const char *text, ...) { @@ -85,12 +87,13 @@ void AGSLinux::DisplayAlert(const char *text, ...) { vsprintf(displbuf, text, ap); va_end(ap); if (_logToStdErr) - fprintf(stderr, "%s\n", displbuf); + debug("ERROR: %s\n", displbuf); else - fprintf(stdout, "%s\n", displbuf); + debug("ERROR: %s\n", displbuf); } size_t BuildXDGPath(char *destPath, size_t destSize) { +#ifdef TODO // Check to see if XDG_DATA_HOME is set in the enviroment const char *home_dir = getenv("XDG_DATA_HOME"); size_t l = 0; @@ -107,9 +110,12 @@ size_t BuildXDGPath(char *destPath, size_t destSize) { return 0; } return l; +#endif + return 0; } void DetermineDataDirectories() { +#ifdef TODO if (!UserDataDirectory.IsEmpty()) return; char xdg_path[256]; @@ -119,6 +125,7 @@ void DetermineDataDirectories() { mkdir(UserDataDirectory.GetCStr(), 0755); CommonDataDirectory.Format("%s/ags-common", xdg_path); mkdir(CommonDataDirectory.GetCStr(), 0755); +#endif } const char *AGSLinux::GetAllUsersDataDirectory() { @@ -162,7 +169,8 @@ eScriptSystemOSID AGSLinux::GetSystemOSID() { } int AGSLinux::InitializeCDPlayer() { - return cd_player_init(); + //return cd_player_init(); + return 0; } void AGSLinux::PostAllegroExit() { @@ -174,7 +182,7 @@ void AGSLinux::SetGameWindowIcon() { } void AGSLinux::ShutdownCDPlayer() { - cd_exit(); + //cd_exit(); } AGSPlatformDriver *AGSPlatformDriver::GetDriver() { @@ -184,13 +192,19 @@ AGSPlatformDriver *AGSPlatformDriver::GetDriver() { } bool AGSLinux::LockMouseToWindow() { +#if 0 return XGrabPointer(_xwin.display, _xwin.window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, _xwin.window, None, CurrentTime) == GrabSuccess; +#else + return false; +#endif } void AGSLinux::UnlockMouse() { +#if 0 XUngrabPointer(_xwin.display, CurrentTime); +#endif } void AGSLinux::GetSystemDisplayModes(std::vector &dms) { diff --git a/engines/ags/lib/opengl/opengl.h b/engines/ags/lib/opengl/opengl.h index 2525645547c1..92fb19034f90 100644 --- a/engines/ags/lib/opengl/opengl.h +++ b/engines/ags/lib/opengl/opengl.h @@ -24,6 +24,7 @@ #define AGS_LIB_OPENGL_OPENGL_H #include "common/scummsys.h" +#include "common/endian.h" namespace AGS3 { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 59e28d33b6bd..7a4fbd1a0c71 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -269,9 +269,7 @@ MODULE_OBJS = \ engine/media/audio/soundclip.o \ engine/media/video/video.o \ engine/platform/base/agsplatformdriver.o \ - engine/platform/windows/acplwin.o \ - engine/platform/windows/minidump.o \ - engine/platform/windows/win_ex_handling.o \ + engine/platform/linux/acpllnx.o \ engine/plugin/agsplugin.o \ engine/plugin/pluginobjectreader.o \ engine/script/cc_instance.o \ From fcc7310c2ddbf53192208b925f805be23b0a6591 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 21:41:23 -0800 Subject: [PATCH 044/215] AGS: Added lib/hq2x/ folder --- engines/ags/lib/hq2x/hq2x3x.cpp | 5278 +++++++++++++++++++++++++++++++ engines/ags/lib/hq2x/hq2x3x.h | 45 + engines/ags/module.mk | 1 + 3 files changed, 5324 insertions(+) create mode 100644 engines/ags/lib/hq2x/hq2x3x.cpp create mode 100644 engines/ags/lib/hq2x/hq2x3x.h diff --git a/engines/ags/lib/hq2x/hq2x3x.cpp b/engines/ags/lib/hq2x/hq2x3x.cpp new file mode 100644 index 000000000000..0129ff67eab4 --- /dev/null +++ b/engines/ags/lib/hq2x/hq2x3x.cpp @@ -0,0 +1,5278 @@ +/* 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 "ags/shared/core/types.h" + +namespace AGS3 { + +static int LUT16to32[65536]; +static int RGBtoYUV[65536]; +static int YUV1, YUV2; +const int Ymask = 0x00FF0000; +const int Umask = 0x0000FF00; +const int Vmask = 0x000000FF; +const int trY = 0x00300000; +const int trU = 0x00000700; +const int trV = 0x00000006; + +inline void Interp1(unsigned char *pc, int c1, int c2) { + *((int *)pc) = (c1 * 3 + c2) >> 2; +} + +inline void Interp2(unsigned char *pc, int c1, int c2, int c3) { + *((int *)pc) = (c1 * 2 + c2 + c3) >> 2; +} + +inline void Interp3(unsigned char *pc, int c1, int c2) { + //*((int*)pc) = (c1*7+c2)/8; + + *((int *)pc) = ((((c1 & 0x00FF00) * 7 + (c2 & 0x00FF00)) & 0x0007F800) + + (((c1 & 0xFF00FF) * 7 + (c2 & 0xFF00FF)) & 0x07F807F8)) >> 3; +} + +inline void Interp4(unsigned char *pc, int c1, int c2, int c3) { + //*((int*)pc) = (c1*2+(c2+c3)*7)/16; + + *((int *)pc) = ((((c1 & 0x00FF00) * 2 + ((c2 & 0x00FF00) + (c3 & 0x00FF00)) * 7) & 0x000FF000) + + (((c1 & 0xFF00FF) * 2 + ((c2 & 0xFF00FF) + (c3 & 0xFF00FF)) * 7) & 0x0FF00FF0)) >> 4; +} + +inline void Interp5(unsigned char *pc, int c1, int c2) { + *((int *)pc) = (c1 + c2) >> 1; +} + +inline void Interp6(unsigned char *pc, int c1, int c2, int c3) { + //*((int*)pc) = (c1*5+c2*2+c3)/8; + + *((int *)pc) = ((((c1 & 0x00FF00) * 5 + (c2 & 0x00FF00) * 2 + (c3 & 0x00FF00)) & 0x0007F800) + + (((c1 & 0xFF00FF) * 5 + (c2 & 0xFF00FF) * 2 + (c3 & 0xFF00FF)) & 0x07F807F8)) >> 3; +} + +inline void Interp7(unsigned char *pc, int c1, int c2, int c3) { + //*((int*)pc) = (c1*6+c2+c3)/8; + + *((int *)pc) = ((((c1 & 0x00FF00) * 6 + (c2 & 0x00FF00) + (c3 & 0x00FF00)) & 0x0007F800) + + (((c1 & 0xFF00FF) * 6 + (c2 & 0xFF00FF) + (c3 & 0xFF00FF)) & 0x07F807F8)) >> 3; +} + +inline void Interp9(unsigned char *pc, int c1, int c2, int c3) { + //*((int*)pc) = (c1*2+(c2+c3)*3)/8; + + *((int *)pc) = ((((c1 & 0x00FF00) * 2 + ((c2 & 0x00FF00) + (c3 & 0x00FF00)) * 3) & 0x0007F800) + + (((c1 & 0xFF00FF) * 2 + ((c2 & 0xFF00FF) + (c3 & 0xFF00FF)) * 3) & 0x07F807F8)) >> 3; +} + +inline void Interp10(unsigned char *pc, int c1, int c2, int c3) { + //*((int*)pc) = (c1*14+c2+c3)/16; + + *((int *)pc) = ((((c1 & 0x00FF00) * 14 + (c2 & 0x00FF00) + (c3 & 0x00FF00)) & 0x000FF000) + + (((c1 & 0xFF00FF) * 14 + (c2 & 0xFF00FF) + (c3 & 0xFF00FF)) & 0x0FF00FF0)) >> 4; +} + + +#define PIXEL00_0 *((int*)(pOut)) = c[5]; +#define PIXEL00_10 Interp1(pOut, c[5], c[1]); +#define PIXEL00_11 Interp1(pOut, c[5], c[4]); +#define PIXEL00_12 Interp1(pOut, c[5], c[2]); +#define PIXEL00_20 Interp2(pOut, c[5], c[4], c[2]); +#define PIXEL00_21 Interp2(pOut, c[5], c[1], c[2]); +#define PIXEL00_22 Interp2(pOut, c[5], c[1], c[4]); +#define PIXEL00_60 Interp6(pOut, c[5], c[2], c[4]); +#define PIXEL00_61 Interp6(pOut, c[5], c[4], c[2]); +#define PIXEL00_70 Interp7(pOut, c[5], c[4], c[2]); +#define PIXEL00_90 Interp9(pOut, c[5], c[4], c[2]); +#define PIXEL00_100 Interp10(pOut, c[5], c[4], c[2]); +#define PIXEL01_0 *((int*)(pOut+4)) = c[5]; +#define PIXEL01_10 Interp1(pOut+4, c[5], c[3]); +#define PIXEL01_11 Interp1(pOut+4, c[5], c[2]); +#define PIXEL01_12 Interp1(pOut+4, c[5], c[6]); +#define PIXEL01_20 Interp2(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_21 Interp2(pOut+4, c[5], c[3], c[6]); +#define PIXEL01_22 Interp2(pOut+4, c[5], c[3], c[2]); +#define PIXEL01_60 Interp6(pOut+4, c[5], c[6], c[2]); +#define PIXEL01_61 Interp6(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_70 Interp7(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_90 Interp9(pOut+4, c[5], c[2], c[6]); +#define PIXEL01_100 Interp10(pOut+4, c[5], c[2], c[6]); +#define PIXEL10_0 *((int*)(pOut+BpL)) = c[5]; +#define PIXEL10_10 Interp1(pOut+BpL, c[5], c[7]); +#define PIXEL10_11 Interp1(pOut+BpL, c[5], c[8]); +#define PIXEL10_12 Interp1(pOut+BpL, c[5], c[4]); +#define PIXEL10_20 Interp2(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_21 Interp2(pOut+BpL, c[5], c[7], c[4]); +#define PIXEL10_22 Interp2(pOut+BpL, c[5], c[7], c[8]); +#define PIXEL10_60 Interp6(pOut+BpL, c[5], c[4], c[8]); +#define PIXEL10_61 Interp6(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_70 Interp7(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_90 Interp9(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL10_100 Interp10(pOut+BpL, c[5], c[8], c[4]); +#define PIXEL11_0 *((int*)(pOut+BpL+4)) = c[5]; +#define PIXEL11_10 Interp1(pOut+BpL+4, c[5], c[9]); +#define PIXEL11_11 Interp1(pOut+BpL+4, c[5], c[6]); +#define PIXEL11_12 Interp1(pOut+BpL+4, c[5], c[8]); +#define PIXEL11_20 Interp2(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_21 Interp2(pOut+BpL+4, c[5], c[9], c[8]); +#define PIXEL11_22 Interp2(pOut+BpL+4, c[5], c[9], c[6]); +#define PIXEL11_60 Interp6(pOut+BpL+4, c[5], c[8], c[6]); +#define PIXEL11_61 Interp6(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_70 Interp7(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_90 Interp9(pOut+BpL+4, c[5], c[6], c[8]); +#define PIXEL11_100 Interp10(pOut+BpL+4, c[5], c[6], c[8]); + + + +inline bool Diff(unsigned int w1, unsigned int w2) { + YUV1 = RGBtoYUV[w1]; + YUV2 = RGBtoYUV[w2]; + return ((abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY) || + (abs((YUV1 & Umask) - (YUV2 & Umask)) > trU) || + (abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV)); +} + +#define INPUT_IMAGE_PIXEL_SIZE uint32_t +#define INPUT_IMAGE_PIXEL_SIZE_IN_BYTES sizeof(INPUT_IMAGE_PIXEL_SIZE) + +void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) { + int i, j, k; + int prevline, nextline; + int w[10]; + int c[10]; + + // +----+----+----+ + // | | | | + // | w1 | w2 | w3 | + // +----+----+----+ + // | | | | + // | w4 | w5 | w6 | + // +----+----+----+ + // | | | | + // | w7 | w8 | w9 | + // +----+----+----+ + + for (j = 0; j < Yres; j++) { + if (j > 0) prevline = -Xres * 4; + else prevline = 0; + if (j < Yres - 1) nextline = Xres * 4; + else nextline = 0; + + for (i = 0; i < Xres; i++) { + w[2] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + prevline)); + w[5] = *((INPUT_IMAGE_PIXEL_SIZE *)pIn); + w[8] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + nextline)); + + if (i > 0) { + w[1] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + prevline - INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[4] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn - INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[7] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + nextline - INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + } else { + w[1] = w[2]; + w[4] = w[5]; + w[7] = w[8]; + } + + if (i < Xres - 1) { + w[3] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + prevline + INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[6] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[9] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + nextline + INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + } else { + w[3] = w[2]; + w[6] = w[5]; + w[9] = w[8]; + } + + // convert down to 16-bit + for (k = 1; k <= 9; k++) { + w[k] = (((((w[k] >> 16) & 0x00ff) / 8) << 11) + + ((((w[k] >> 8) & 0x00ff) / 4) << 5) + + ((w[k] & 0x00ff) / 8)) & 0x000ffff; + } + + int pattern = 0; + int flag = 1; + + YUV1 = RGBtoYUV[w[5]]; + + for (k = 1; k <= 9; k++) { + if (k == 5) continue; + + if (w[k] != w[5]) { + YUV2 = RGBtoYUV[w[k]]; + if ((abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY) || + (abs((YUV1 & Umask) - (YUV2 & Umask)) > trU) || + (abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV)) + pattern |= flag; + } + flag <<= 1; + } + + for (k = 1; k <= 9; k++) + c[k] = LUT16to32[w[k]]; + + switch (pattern) { + case 0: + case 1: + case 4: + case 32: + case 128: + case 5: + case 132: + case 160: + case 33: + case 129: + case 36: + case 133: + case 164: + case 161: + case 37: + case 165: { + PIXEL00_20 + PIXEL01_20 + PIXEL10_20 + PIXEL11_20 + break; + } + case 2: + case 34: + case 130: + case 162: { + PIXEL00_22 + PIXEL01_21 + PIXEL10_20 + PIXEL11_20 + break; + } + case 16: + case 17: + case 48: + case 49: { + PIXEL00_20 + PIXEL01_22 + PIXEL10_20 + PIXEL11_21 + break; + } + case 64: + case 65: + case 68: + case 69: { + PIXEL00_20 + PIXEL01_20 + PIXEL10_21 + PIXEL11_22 + break; + } + case 8: + case 12: + case 136: + case 140: { + PIXEL00_21 + PIXEL01_20 + PIXEL10_22 + PIXEL11_20 + break; + } + case 3: + case 35: + case 131: + case 163: { + PIXEL00_11 + PIXEL01_21 + PIXEL10_20 + PIXEL11_20 + break; + } + case 6: + case 38: + case 134: + case 166: { + PIXEL00_22 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + } + case 20: + case 21: + case 52: + case 53: { + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_21 + break; + } + case 144: + case 145: + case 176: + case 177: { + PIXEL00_20 + PIXEL01_22 + PIXEL10_20 + PIXEL11_12 + break; + } + case 192: + case 193: + case 196: + case 197: { + PIXEL00_20 + PIXEL01_20 + PIXEL10_21 + PIXEL11_11 + break; + } + case 96: + case 97: + case 100: + case 101: { + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_22 + break; + } + case 40: + case 44: + case 168: + case 172: { + PIXEL00_21 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + } + case 9: + case 13: + case 137: + case 141: { + PIXEL00_12 + PIXEL01_20 + PIXEL10_22 + PIXEL11_20 + break; + } + case 18: + case 50: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_20 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 80: + case 81: { + PIXEL00_20 + PIXEL01_22 + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_20 + } + break; + } + case 72: + case 76: { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 10: + case 138: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_22 + PIXEL11_20 + break; + } + case 66: { + PIXEL00_22 + PIXEL01_21 + PIXEL10_21 + PIXEL11_22 + break; + } + case 24: { + PIXEL00_21 + PIXEL01_22 + PIXEL10_22 + PIXEL11_21 + break; + } + case 7: + case 39: + case 135: { + PIXEL00_11 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + } + case 148: + case 149: + case 180: { + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_12 + break; + } + case 224: + case 228: + case 225: { + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_11 + break; + } + case 41: + case 169: + case 45: { + PIXEL00_12 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + } + case 22: + case 54: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 208: + case 209: { + PIXEL00_20 + PIXEL01_22 + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 104: + case 108: { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 11: + case 139: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_22 + PIXEL11_20 + break; + } + case 19: + case 51: { + if (Diff(w[2], w[6])) { + PIXEL00_11 + PIXEL01_10 + } else { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 146: + case 178: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_10 + PIXEL11_12 + } else { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_20 + break; + } + case 84: + case 85: { + PIXEL00_20 + if (Diff(w[6], w[8])) { + PIXEL01_11 + PIXEL11_10 + } else { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_21 + break; + } + case 112: + case 113: { + PIXEL00_20 + PIXEL01_22 + if (Diff(w[6], w[8])) { + PIXEL10_12 + PIXEL11_10 + } else { + PIXEL10_61 + PIXEL11_90 + } + break; + } + case 200: + case 204: { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) { + PIXEL10_10 + PIXEL11_11 + } else { + PIXEL10_90 + PIXEL11_60 + } + break; + } + case 73: + case 77: { + if (Diff(w[8], w[4])) { + PIXEL00_12 + PIXEL10_10 + } else { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_20 + PIXEL11_22 + break; + } + case 42: + case 170: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + PIXEL10_11 + } else { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_21 + PIXEL11_20 + break; + } + case 14: + case 142: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + PIXEL01_12 + } else { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_22 + PIXEL11_20 + break; + } + case 67: { + PIXEL00_11 + PIXEL01_21 + PIXEL10_21 + PIXEL11_22 + break; + } + case 70: { + PIXEL00_22 + PIXEL01_12 + PIXEL10_21 + PIXEL11_22 + break; + } + case 28: { + PIXEL00_21 + PIXEL01_11 + PIXEL10_22 + PIXEL11_21 + break; + } + case 152: { + PIXEL00_21 + PIXEL01_22 + PIXEL10_22 + PIXEL11_12 + break; + } + case 194: { + PIXEL00_22 + PIXEL01_21 + PIXEL10_21 + PIXEL11_11 + break; + } + case 98: { + PIXEL00_22 + PIXEL01_21 + PIXEL10_12 + PIXEL11_22 + break; + } + case 56: { + PIXEL00_21 + PIXEL01_22 + PIXEL10_11 + PIXEL11_21 + break; + } + case 25: { + PIXEL00_12 + PIXEL01_22 + PIXEL10_22 + PIXEL11_21 + break; + } + case 26: + case 31: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_21 + break; + } + case 82: + case 214: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 88: + case 248: { + PIXEL00_21 + PIXEL01_22 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 74: + case 107: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 27: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_22 + PIXEL11_21 + break; + } + case 86: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_21 + PIXEL11_10 + break; + } + case 216: { + PIXEL00_21 + PIXEL01_22 + PIXEL10_10 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 106: { + PIXEL00_10 + PIXEL01_21 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 30: { + PIXEL00_10 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_21 + break; + } + case 210: { + PIXEL00_22 + PIXEL01_10 + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 120: { + PIXEL00_21 + PIXEL01_22 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 75: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_10 + PIXEL11_22 + break; + } + case 29: { + PIXEL00_12 + PIXEL01_11 + PIXEL10_22 + PIXEL11_21 + break; + } + case 198: { + PIXEL00_22 + PIXEL01_12 + PIXEL10_21 + PIXEL11_11 + break; + } + case 184: { + PIXEL00_21 + PIXEL01_22 + PIXEL10_11 + PIXEL11_12 + break; + } + case 99: { + PIXEL00_11 + PIXEL01_21 + PIXEL10_12 + PIXEL11_22 + break; + } + case 57: { + PIXEL00_12 + PIXEL01_22 + PIXEL10_11 + PIXEL11_21 + break; + } + case 71: { + PIXEL00_11 + PIXEL01_12 + PIXEL10_21 + PIXEL11_22 + break; + } + case 156: { + PIXEL00_21 + PIXEL01_11 + PIXEL10_22 + PIXEL11_12 + break; + } + case 226: { + PIXEL00_22 + PIXEL01_21 + PIXEL10_12 + PIXEL11_11 + break; + } + case 60: { + PIXEL00_21 + PIXEL01_11 + PIXEL10_11 + PIXEL11_21 + break; + } + case 195: { + PIXEL00_11 + PIXEL01_21 + PIXEL10_21 + PIXEL11_11 + break; + } + case 102: { + PIXEL00_22 + PIXEL01_12 + PIXEL10_12 + PIXEL11_22 + break; + } + case 153: { + PIXEL00_12 + PIXEL01_22 + PIXEL10_22 + PIXEL11_12 + break; + } + case 58: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 83: { + PIXEL00_11 + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 92: { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 202: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_21 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_11 + break; + } + case 78: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_12 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_22 + break; + } + case 154: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_22 + PIXEL11_12 + break; + } + case 114: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_12 + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 89: { + PIXEL00_12 + PIXEL01_22 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 90: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 55: + case 23: { + if (Diff(w[2], w[6])) { + PIXEL00_11 + PIXEL01_0 + } else { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_20 + PIXEL11_21 + break; + } + case 182: + case 150: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_0 + PIXEL11_12 + } else { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_20 + break; + } + case 213: + case 212: { + PIXEL00_20 + if (Diff(w[6], w[8])) { + PIXEL01_11 + PIXEL11_0 + } else { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_21 + break; + } + case 241: + case 240: { + PIXEL00_20 + PIXEL01_22 + if (Diff(w[6], w[8])) { + PIXEL10_12 + PIXEL11_0 + } else { + PIXEL10_61 + PIXEL11_90 + } + break; + } + case 236: + case 232: { + PIXEL00_21 + PIXEL01_20 + if (Diff(w[8], w[4])) { + PIXEL10_0 + PIXEL11_11 + } else { + PIXEL10_90 + PIXEL11_60 + } + break; + } + case 109: + case 105: { + if (Diff(w[8], w[4])) { + PIXEL00_12 + PIXEL10_0 + } else { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_20 + PIXEL11_22 + break; + } + case 171: + case 43: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + PIXEL10_11 + } else { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_21 + PIXEL11_20 + break; + } + case 143: + case 15: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + PIXEL01_12 + } else { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_22 + PIXEL11_20 + break; + } + case 124: { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 203: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + PIXEL10_10 + PIXEL11_11 + break; + } + case 62: { + PIXEL00_10 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 211: { + PIXEL00_11 + PIXEL01_10 + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 118: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_12 + PIXEL11_10 + break; + } + case 217: { + PIXEL00_12 + PIXEL01_22 + PIXEL10_10 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 110: { + PIXEL00_10 + PIXEL01_12 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 155: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_22 + PIXEL11_12 + break; + } + case 188: { + PIXEL00_21 + PIXEL01_11 + PIXEL10_11 + PIXEL11_12 + break; + } + case 185: { + PIXEL00_12 + PIXEL01_22 + PIXEL10_11 + PIXEL11_12 + break; + } + case 61: { + PIXEL00_12 + PIXEL01_11 + PIXEL10_11 + PIXEL11_21 + break; + } + case 157: { + PIXEL00_12 + PIXEL01_11 + PIXEL10_22 + PIXEL11_12 + break; + } + case 103: { + PIXEL00_11 + PIXEL01_12 + PIXEL10_12 + PIXEL11_22 + break; + } + case 227: { + PIXEL00_11 + PIXEL01_21 + PIXEL10_12 + PIXEL11_11 + break; + } + case 230: { + PIXEL00_22 + PIXEL01_12 + PIXEL10_12 + PIXEL11_11 + break; + } + case 199: { + PIXEL00_11 + PIXEL01_12 + PIXEL10_21 + PIXEL11_11 + break; + } + case 220: { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 158: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_22 + PIXEL11_12 + break; + } + case 234: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_21 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_11 + break; + } + case 242: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_12 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 59: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 121: { + PIXEL00_12 + PIXEL01_22 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 87: { + PIXEL00_11 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 79: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_12 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_22 + break; + } + case 122: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 94: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 218: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 91: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 229: { + PIXEL00_20 + PIXEL01_20 + PIXEL10_12 + PIXEL11_11 + break; + } + case 167: { + PIXEL00_11 + PIXEL01_12 + PIXEL10_20 + PIXEL11_20 + break; + } + case 173: { + PIXEL00_12 + PIXEL01_20 + PIXEL10_11 + PIXEL11_20 + break; + } + case 181: { + PIXEL00_20 + PIXEL01_11 + PIXEL10_20 + PIXEL11_12 + break; + } + case 186: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_11 + PIXEL11_12 + break; + } + case 115: { + PIXEL00_11 + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_12 + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 93: { + PIXEL00_12 + PIXEL01_11 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 206: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_12 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_11 + break; + } + case 205: + case 201: { + PIXEL00_12 + PIXEL01_20 + if (Diff(w[8], w[4])) { + PIXEL10_10 + } else { + PIXEL10_70 + } + PIXEL11_11 + break; + } + case 174: + case 46: { + if (Diff(w[4], w[2])) { + PIXEL00_10 + } else { + PIXEL00_70 + } + PIXEL01_12 + PIXEL10_11 + PIXEL11_20 + break; + } + case 179: + case 147: { + PIXEL00_11 + if (Diff(w[2], w[6])) { + PIXEL01_10 + } else { + PIXEL01_70 + } + PIXEL10_20 + PIXEL11_12 + break; + } + case 117: + case 116: { + PIXEL00_20 + PIXEL01_11 + PIXEL10_12 + if (Diff(w[6], w[8])) { + PIXEL11_10 + } else { + PIXEL11_70 + } + break; + } + case 189: { + PIXEL00_12 + PIXEL01_11 + PIXEL10_11 + PIXEL11_12 + break; + } + case 231: { + PIXEL00_11 + PIXEL01_12 + PIXEL10_12 + PIXEL11_11 + break; + } + case 126: { + PIXEL00_10 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 219: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + PIXEL10_10 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 125: { + if (Diff(w[8], w[4])) { + PIXEL00_12 + PIXEL10_0 + } else { + PIXEL00_61 + PIXEL10_90 + } + PIXEL01_11 + PIXEL11_10 + break; + } + case 221: { + PIXEL00_12 + if (Diff(w[6], w[8])) { + PIXEL01_11 + PIXEL11_0 + } else { + PIXEL01_60 + PIXEL11_90 + } + PIXEL10_10 + break; + } + case 207: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + PIXEL01_12 + } else { + PIXEL00_90 + PIXEL01_61 + } + PIXEL10_10 + PIXEL11_11 + break; + } + case 238: { + PIXEL00_10 + PIXEL01_12 + if (Diff(w[8], w[4])) { + PIXEL10_0 + PIXEL11_11 + } else { + PIXEL10_90 + PIXEL11_60 + } + break; + } + case 190: { + PIXEL00_10 + if (Diff(w[2], w[6])) { + PIXEL01_0 + PIXEL11_12 + } else { + PIXEL01_90 + PIXEL11_61 + } + PIXEL10_11 + break; + } + case 187: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + PIXEL10_11 + } else { + PIXEL00_90 + PIXEL10_60 + } + PIXEL01_10 + PIXEL11_12 + break; + } + case 243: { + PIXEL00_11 + PIXEL01_10 + if (Diff(w[6], w[8])) { + PIXEL10_12 + PIXEL11_0 + } else { + PIXEL10_61 + PIXEL11_90 + } + break; + } + case 119: { + if (Diff(w[2], w[6])) { + PIXEL00_11 + PIXEL01_0 + } else { + PIXEL00_60 + PIXEL01_90 + } + PIXEL10_12 + PIXEL11_10 + break; + } + case 237: + case 233: { + PIXEL00_12 + PIXEL01_20 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_100 + } + PIXEL11_11 + break; + } + case 175: + case 47: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_100 + } + PIXEL01_12 + PIXEL10_11 + PIXEL11_20 + break; + } + case 183: + case 151: { + PIXEL00_11 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_20 + PIXEL11_12 + break; + } + case 245: + case 244: { + PIXEL00_20 + PIXEL01_11 + PIXEL10_12 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } + case 250: { + PIXEL00_10 + PIXEL01_10 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 123: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 95: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_10 + PIXEL11_10 + break; + } + case 222: { + PIXEL00_10 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_10 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 252: { + PIXEL00_21 + PIXEL01_11 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } + case 249: { + PIXEL00_12 + PIXEL01_22 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 235: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_21 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_100 + } + PIXEL11_11 + break; + } + case 111: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_100 + } + PIXEL01_12 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_22 + break; + } + case 63: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_11 + PIXEL11_21 + break; + } + case 159: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_22 + PIXEL11_12 + break; + } + case 215: { + PIXEL00_11 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_21 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 246: { + PIXEL00_22 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + PIXEL10_12 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } + case 254: { + PIXEL00_10 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } + case 253: { + PIXEL00_12 + PIXEL01_11 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } + case 251: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + PIXEL01_10 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 239: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_100 + } + PIXEL01_12 + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_100 + } + PIXEL11_11 + break; + } + case 127: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_20 + } + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_20 + } + PIXEL11_10 + break; + } + case 191: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_11 + PIXEL11_12 + break; + } + case 223: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_20 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_10 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_20 + } + break; + } + case 247: { + PIXEL00_11 + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_100 + } + PIXEL10_12 + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } + case 255: { + if (Diff(w[4], w[2])) { + PIXEL00_0 + } else { + PIXEL00_100 + } + if (Diff(w[2], w[6])) { + PIXEL01_0 + } else { + PIXEL01_100 + } + if (Diff(w[8], w[4])) { + PIXEL10_0 + } else { + PIXEL10_100 + } + if (Diff(w[6], w[8])) { + PIXEL11_0 + } else { + PIXEL11_100 + } + break; + } + } + pIn += INPUT_IMAGE_PIXEL_SIZE_IN_BYTES; + pOut += 8; + } + pOut += BpL + (BpL - Xres * 8); + } +} + +void InitLUTs(void) { + int i, j, k, r, g, b, Y, u, v; + + for (i = 0; i < 65536; i++) + LUT16to32[i] = ((i & 0xF800) << 8) + ((i & 0x07E0) << 5) + ((i & 0x001F) << 3); + + for (i = 0; i < 32; i++) + for (j = 0; j < 64; j++) + for (k = 0; k < 32; k++) { + r = i << 3; + g = j << 2; + b = k << 3; + Y = (r + g + b) >> 2; + u = 128 + ((r - b) >> 2); + v = 128 + ((-r + 2 * g - b) >> 3); + RGBtoYUV[(i << 11) + (j << 5) + k ] = (Y << 16) + (u << 8) + v; + } +} + + + +//// **** HQ3X BELOW **** ///// + + +#define PIXEL00_1M Interp1(pOut, c[5], c[1]); +#define PIXEL00_1U Interp1(pOut, c[5], c[2]); +#define PIXEL00_1L Interp1(pOut, c[5], c[4]); +#define PIXEL00_2 Interp2(pOut, c[5], c[4], c[2]); +#define PIXEL00_4 Interp4(pOut, c[5], c[4], c[2]); +#define PIXEL00_5 Interp5(pOut, c[4], c[2]); +#define PIXEL00_C *((int*)(pOut)) = c[5]; + +#define PIXEL01_1 Interp1(pOut+4, c[5], c[2]); +#define PIXEL01_3 Interp3(pOut+4, c[5], c[2]); +#define PIXEL01_6 Interp1(pOut+4, c[2], c[5]); +#define PIXEL01_C *((int*)(pOut+4)) = c[5]; + +#define PIXEL02_1M Interp1(pOut+8, c[5], c[3]); +#define PIXEL02_1U Interp1(pOut+8, c[5], c[2]); +#define PIXEL02_1R Interp1(pOut+8, c[5], c[6]); +#define PIXEL02_2 Interp2(pOut+8, c[5], c[2], c[6]); +#define PIXEL02_4 Interp4(pOut+8, c[5], c[2], c[6]); +#define PIXEL02_5 Interp5(pOut+8, c[2], c[6]); +#define PIXEL02_C *((int*)(pOut+8)) = c[5]; + +#define PIXEL10_1 Interp1(pOut+BpL, c[5], c[4]); +#define PIXEL10_3 Interp3(pOut+BpL, c[5], c[4]); +#define PIXEL10_6 Interp1(pOut+BpL, c[4], c[5]); +#define PIXEL10_C *((int*)(pOut+BpL)) = c[5]; + +#define PIXEL11 *((int*)(pOut+BpL+4)) = c[5]; + +#define PIXEL12_1 Interp1(pOut+BpL+8, c[5], c[6]); +#define PIXEL12_3 Interp3(pOut+BpL+8, c[5], c[6]); +#define PIXEL12_6 Interp1(pOut+BpL+8, c[6], c[5]); +#define PIXEL12_C *((int*)(pOut+BpL+8)) = c[5]; + +#define PIXEL20_1M Interp1(pOut+BpL+BpL, c[5], c[7]); +#define PIXEL20_1D Interp1(pOut+BpL+BpL, c[5], c[8]); +#define PIXEL20_1L Interp1(pOut+BpL+BpL, c[5], c[4]); +#define PIXEL20_2 Interp2(pOut+BpL+BpL, c[5], c[8], c[4]); +#define PIXEL20_4 Interp4(pOut+BpL+BpL, c[5], c[8], c[4]); +#define PIXEL20_5 Interp5(pOut+BpL+BpL, c[8], c[4]); +#define PIXEL20_C *((int*)(pOut+BpL+BpL)) = c[5]; + +#define PIXEL21_1 Interp1(pOut+BpL+BpL+4, c[5], c[8]); +#define PIXEL21_3 Interp3(pOut+BpL+BpL+4, c[5], c[8]); +#define PIXEL21_6 Interp1(pOut+BpL+BpL+4, c[8], c[5]); +#define PIXEL21_C *((int*)(pOut+BpL+BpL+4)) = c[5]; + +#define PIXEL22_1M Interp1(pOut+BpL+BpL+8, c[5], c[9]); +#define PIXEL22_1D Interp1(pOut+BpL+BpL+8, c[5], c[8]); +#define PIXEL22_1R Interp1(pOut+BpL+BpL+8, c[5], c[6]); +#define PIXEL22_2 Interp2(pOut+BpL+BpL+8, c[5], c[6], c[8]); +#define PIXEL22_4 Interp4(pOut+BpL+BpL+8, c[5], c[6], c[8]); +#define PIXEL22_5 Interp5(pOut+BpL+BpL+8, c[6], c[8]); +#define PIXEL22_C *((int*)(pOut+BpL+BpL+8)) = c[5]; + + + +void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) { + int i, j, k; + int prevline, nextline; + int w[10]; + int c[10]; + + // +----+----+----+ + // | | | | + // | w1 | w2 | w3 | + // +----+----+----+ + // | | | | + // | w4 | w5 | w6 | + // +----+----+----+ + // | | | | + // | w7 | w8 | w9 | + // +----+----+----+ + + for (j = 0; j < Yres; j++) { + if (j > 0) prevline = -Xres * 4; + else prevline = 0; + if (j < Yres - 1) nextline = Xres * 4; + else nextline = 0; + + for (i = 0; i < Xres; i++) { + w[2] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + prevline)); + w[5] = *((INPUT_IMAGE_PIXEL_SIZE *)pIn); + w[8] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + nextline)); + + if (i > 0) { + w[1] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + prevline - INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[4] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn - INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[7] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + nextline - INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + } else { + w[1] = w[2]; + w[4] = w[5]; + w[7] = w[8]; + } + + if (i < Xres - 1) { + w[3] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + prevline + INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[6] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + w[9] = *((INPUT_IMAGE_PIXEL_SIZE *)(pIn + nextline + INPUT_IMAGE_PIXEL_SIZE_IN_BYTES)); + } else { + w[3] = w[2]; + w[6] = w[5]; + w[9] = w[8]; + } + + // convert down to 16-bit + for (k = 1; k <= 9; k++) { + w[k] = (((((w[k] >> 16) & 0x00ff) / 8) << 11) + + ((((w[k] >> 8) & 0x00ff) / 4) << 5) + + ((w[k] & 0x00ff) / 8)) & 0x000ffff; + } + + int pattern = 0; + int flag = 1; + + YUV1 = RGBtoYUV[w[5]]; + + for (k = 1; k <= 9; k++) { + if (k == 5) continue; + + if (w[k] != w[5]) { + YUV2 = RGBtoYUV[w[k]]; + if ((abs((YUV1 & Ymask) - (YUV2 & Ymask)) > trY) || + (abs((YUV1 & Umask) - (YUV2 & Umask)) > trU) || + (abs((YUV1 & Vmask) - (YUV2 & Vmask)) > trV)) + pattern |= flag; + } + flag <<= 1; + } + + for (k = 1; k <= 9; k++) + c[k] = LUT16to32[w[k]]; + + switch (pattern) { + case 0: + case 1: + case 4: + case 32: + case 128: + case 5: + case 132: + case 160: + case 33: + case 129: + case 36: + case 133: + case 164: + case 161: + case 37: + case 165: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + } + case 2: + case 34: + case 130: + case 162: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + } + case 16: + case 17: + case 48: + case 49: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + } + case 64: + case 65: + case 68: + case 69: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 8: + case 12: + case 136: + case 140: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + } + case 3: + case 35: + case 131: + case 163: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + } + case 6: + case 38: + case 134: + case 166: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + } + case 20: + case 21: + case 52: + case 53: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + } + case 144: + case 145: + case 176: + case 177: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + } + case 192: + case 193: + case 196: + case 197: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + } + case 96: + case 97: + case 100: + case 101: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + } + case 40: + case 44: + case 168: + case 172: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + } + case 9: + case 13: + case 137: + case 141: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + } + case 18: + case 50: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_1M + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + } + case 80: + case 81: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_1M + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 72: + case 76: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_1M + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 10: + case 138: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + } + case 66: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 24: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + } + case 7: + case 39: + case 135: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + } + case 148: + case 149: + case 180: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + } + case 224: + case 228: + case 225: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + } + case 41: + case 169: + case 45: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + } + case 22: + case 54: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + } + case 208: + case 209: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 104: + case 108: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 11: + case 139: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + } + case 19: + case 51: { + if (Diff(w[2], w[6])) { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL12_C + } else { + PIXEL00_2 + PIXEL01_6 + PIXEL02_5 + PIXEL12_1 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + } + case 146: + case 178: { + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_1M + PIXEL12_C + PIXEL22_1D + } else { + PIXEL01_1 + PIXEL02_5 + PIXEL12_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + break; + } + case 84: + case 85: { + if (Diff(w[6], w[8])) { + PIXEL02_1U + PIXEL12_C + PIXEL21_C + PIXEL22_1M + } else { + PIXEL02_2 + PIXEL12_6 + PIXEL21_1 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL10_1 + PIXEL11 + PIXEL20_1M + break; + } + case 112: + case 113: { + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + } else { + PIXEL12_1 + PIXEL20_2 + PIXEL21_6 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + break; + } + case 200: + case 204: { + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + } else { + PIXEL10_1 + PIXEL20_5 + PIXEL21_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + break; + } + case 73: + case 77: { + if (Diff(w[8], w[4])) { + PIXEL00_1U + PIXEL10_C + PIXEL20_1M + PIXEL21_C + } else { + PIXEL00_2 + PIXEL10_6 + PIXEL20_5 + PIXEL21_1 + } + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + PIXEL22_1M + break; + } + case 42: + case 170: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + PIXEL01_C + PIXEL10_C + PIXEL20_1D + } else { + PIXEL00_5 + PIXEL01_1 + PIXEL10_6 + PIXEL20_2 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL21_1 + PIXEL22_2 + break; + } + case 14: + case 142: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_C + } else { + PIXEL00_5 + PIXEL01_6 + PIXEL02_2 + PIXEL10_1 + } + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + } + case 67: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 70: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 28: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + } + case 152: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 194: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + } + case 98: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + } + case 56: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 25: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + } + case 26: + case 31: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + } + case 82: + case 214: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 88: + case 248: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + } + case 74: + case 107: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 27: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + } + case 86: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 216: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 106: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 30: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + } + case 210: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 120: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 75: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 29: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1M + break; + } + case 198: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + } + case 184: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + } + case 99: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + } + case 57: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 71: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 156: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 226: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + } + case 60: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 195: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + } + case 102: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + } + case 153: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 58: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 83: { + PIXEL00_1L + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 92: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 202: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + } + case 78: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1M + break; + } + case 154: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 114: { + PIXEL00_1M + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 89: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 90: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 55: + case 23: { + if (Diff(w[2], w[6])) { + PIXEL00_1L + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL00_2 + PIXEL01_6 + PIXEL02_5 + PIXEL12_1 + } + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + PIXEL22_1M + break; + } + case 182: + case 150: { + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + PIXEL22_1D + } else { + PIXEL01_1 + PIXEL02_5 + PIXEL12_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL10_1 + PIXEL11 + PIXEL20_2 + PIXEL21_1 + break; + } + case 213: + case 212: { + if (Diff(w[6], w[8])) { + PIXEL02_1U + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL02_2 + PIXEL12_6 + PIXEL21_1 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL10_1 + PIXEL11 + PIXEL20_1M + break; + } + case 241: + case 240: { + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL20_1L + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_1 + PIXEL20_2 + PIXEL21_6 + PIXEL22_5 + } + PIXEL00_2 + PIXEL01_1 + PIXEL02_1M + PIXEL10_1 + PIXEL11 + break; + } + case 236: + case 232: { + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + PIXEL22_1R + } else { + PIXEL10_1 + PIXEL20_5 + PIXEL21_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + break; + } + case 109: + case 105: { + if (Diff(w[8], w[4])) { + PIXEL00_1U + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL00_2 + PIXEL10_6 + PIXEL20_5 + PIXEL21_1 + } + PIXEL01_1 + PIXEL02_2 + PIXEL11 + PIXEL12_1 + PIXEL22_1M + break; + } + case 171: + case 43: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + PIXEL20_1D + } else { + PIXEL00_5 + PIXEL01_1 + PIXEL10_6 + PIXEL20_2 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL21_1 + PIXEL22_2 + break; + } + case 143: + case 15: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL02_1R + PIXEL10_C + } else { + PIXEL00_5 + PIXEL01_6 + PIXEL02_2 + PIXEL10_1 + } + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_1 + PIXEL22_2 + break; + } + case 124: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 203: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + } + case 62: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 211: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 118: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + } + case 217: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 110: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 155: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 188: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + } + case 185: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + } + case 61: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 157: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 103: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + } + case 227: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + } + case 230: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + } + case 199: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + } + case 220: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 158: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 234: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1M + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1R + break; + } + case 242: { + PIXEL00_1M + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1L + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 59: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 121: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 87: { + PIXEL00_1L + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1M + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 79: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1R + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1M + break; + } + case 122: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 94: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 218: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 91: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 229: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_2 + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + } + case 167: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_2 + PIXEL21_1 + PIXEL22_2 + break; + } + case 173: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + } + case 181: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + } + case 186: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + } + case 115: { + PIXEL00_1L + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 93: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 206: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + } + case 205: + case 201: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_1M + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + } + case 174: + case 46: { + if (Diff(w[4], w[2])) { + PIXEL00_1M + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + } + case 179: + case 147: { + PIXEL00_1L + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_1M + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + } + case 117: + case 116: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_1M + } else { + PIXEL22_2 + } + break; + } + case 189: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + } + case 231: { + PIXEL00_1L + PIXEL01_C + PIXEL02_1R + PIXEL10_1 + PIXEL11 + PIXEL12_1 + PIXEL20_1L + PIXEL21_C + PIXEL22_1R + break; + } + case 126: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 219: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL01_3 + PIXEL10_3 + } + PIXEL02_1M + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 125: { + if (Diff(w[8], w[4])) { + PIXEL00_1U + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL00_2 + PIXEL10_6 + PIXEL20_5 + PIXEL21_1 + } + PIXEL01_1 + PIXEL02_1U + PIXEL11 + PIXEL12_C + PIXEL22_1M + break; + } + case 221: { + if (Diff(w[6], w[8])) { + PIXEL02_1U + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL02_2 + PIXEL12_6 + PIXEL21_1 + PIXEL22_5 + } + PIXEL00_1U + PIXEL01_1 + PIXEL10_C + PIXEL11 + PIXEL20_1M + break; + } + case 207: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL02_1R + PIXEL10_C + } else { + PIXEL00_5 + PIXEL01_6 + PIXEL02_2 + PIXEL10_1 + } + PIXEL11 + PIXEL12_1 + PIXEL20_1M + PIXEL21_C + PIXEL22_1R + break; + } + case 238: { + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + PIXEL22_1R + } else { + PIXEL10_1 + PIXEL20_5 + PIXEL21_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL01_C + PIXEL02_1R + PIXEL11 + PIXEL12_1 + break; + } + case 190: { + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + PIXEL22_1D + } else { + PIXEL01_1 + PIXEL02_5 + PIXEL12_6 + PIXEL22_2 + } + PIXEL00_1M + PIXEL10_C + PIXEL11 + PIXEL20_1D + PIXEL21_1 + break; + } + case 187: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + PIXEL20_1D + } else { + PIXEL00_5 + PIXEL01_1 + PIXEL10_6 + PIXEL20_2 + } + PIXEL02_1M + PIXEL11 + PIXEL12_C + PIXEL21_1 + PIXEL22_1D + break; + } + case 243: { + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL20_1L + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_1 + PIXEL20_2 + PIXEL21_6 + PIXEL22_5 + } + PIXEL00_1L + PIXEL01_C + PIXEL02_1M + PIXEL10_1 + PIXEL11 + break; + } + case 119: { + if (Diff(w[2], w[6])) { + PIXEL00_1L + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL00_2 + PIXEL01_6 + PIXEL02_5 + PIXEL12_1 + } + PIXEL10_1 + PIXEL11 + PIXEL20_1L + PIXEL21_C + PIXEL22_1M + break; + } + case 237: + case 233: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_2 + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + } + case 175: + case 47: { + if (Diff(w[4], w[2])) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + PIXEL20_1D + PIXEL21_1 + PIXEL22_2 + break; + } + case 183: + case 151: { + PIXEL00_1L + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_2 + PIXEL21_1 + PIXEL22_1D + break; + } + case 245: + case 244: { + PIXEL00_2 + PIXEL01_1 + PIXEL02_1U + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + } + case 250: { + PIXEL00_1M + PIXEL01_C + PIXEL02_1M + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + } + case 123: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 95: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + PIXEL20_1M + PIXEL21_C + PIXEL22_1M + break; + } + case 222: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 252: { + PIXEL00_1M + PIXEL01_1 + PIXEL02_1U + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + } + case 249: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1M + PIXEL10_C + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + } + case 235: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + } + case 111: { + if (Diff(w[4], w[2])) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 63: { + if (Diff(w[4], w[2])) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL10_C + PIXEL11 + PIXEL20_1D + PIXEL21_1 + PIXEL22_1M + break; + } + case 159: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL11 + PIXEL12_C + PIXEL20_1M + PIXEL21_1 + PIXEL22_1D + break; + } + case 215: { + PIXEL00_1L + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 246: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + } + case 254: { + PIXEL00_1M + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + } else { + PIXEL01_3 + PIXEL02_4 + } + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + } else { + PIXEL10_3 + PIXEL20_4 + } + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL21_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL21_3 + PIXEL22_2 + } + break; + } + case 253: { + PIXEL00_1U + PIXEL01_1 + PIXEL02_1U + PIXEL10_C + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + } + case 251: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + } else { + PIXEL00_4 + PIXEL01_3 + } + PIXEL02_1M + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL10_C + PIXEL20_C + PIXEL21_C + } else { + PIXEL10_3 + PIXEL20_2 + PIXEL21_3 + } + if (Diff(w[6], w[8])) { + PIXEL12_C + PIXEL22_C + } else { + PIXEL12_3 + PIXEL22_4 + } + break; + } + case 239: { + if (Diff(w[4], w[2])) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + PIXEL02_1R + PIXEL10_C + PIXEL11 + PIXEL12_1 + if (Diff(w[8], w[4])) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + PIXEL22_1R + break; + } + case 127: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL01_C + PIXEL10_C + } else { + PIXEL00_2 + PIXEL01_3 + PIXEL10_3 + } + if (Diff(w[2], w[6])) { + PIXEL02_C + PIXEL12_C + } else { + PIXEL02_4 + PIXEL12_3 + } + PIXEL11 + if (Diff(w[8], w[4])) { + PIXEL20_C + PIXEL21_C + } else { + PIXEL20_4 + PIXEL21_3 + } + PIXEL22_1M + break; + } + case 191: { + if (Diff(w[4], w[2])) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + PIXEL20_1D + PIXEL21_1 + PIXEL22_1D + break; + } + case 223: { + if (Diff(w[4], w[2])) { + PIXEL00_C + PIXEL10_C + } else { + PIXEL00_4 + PIXEL10_3 + } + if (Diff(w[2], w[6])) { + PIXEL01_C + PIXEL02_C + PIXEL12_C + } else { + PIXEL01_3 + PIXEL02_2 + PIXEL12_3 + } + PIXEL11 + PIXEL20_1M + if (Diff(w[6], w[8])) { + PIXEL21_C + PIXEL22_C + } else { + PIXEL21_3 + PIXEL22_4 + } + break; + } + case 247: { + PIXEL00_1L + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_1 + PIXEL11 + PIXEL12_C + PIXEL20_1L + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + } + case 255: { + if (Diff(w[4], w[2])) { + PIXEL00_C + } else { + PIXEL00_2 + } + PIXEL01_C + if (Diff(w[2], w[6])) { + PIXEL02_C + } else { + PIXEL02_2 + } + PIXEL10_C + PIXEL11 + PIXEL12_C + if (Diff(w[8], w[4])) { + PIXEL20_C + } else { + PIXEL20_2 + } + PIXEL21_C + if (Diff(w[6], w[8])) { + PIXEL22_C + } else { + PIXEL22_2 + } + break; + } + } + pIn += INPUT_IMAGE_PIXEL_SIZE_IN_BYTES; + pOut += 12; + } + pOut += BpL + (BpL - Xres * 12); + pOut += BpL; + } +} + +} // namespace AGS3 diff --git a/engines/ags/lib/hq2x/hq2x3x.h b/engines/ags/lib/hq2x/hq2x3x.h new file mode 100644 index 000000000000..e3202f738070 --- /dev/null +++ b/engines/ags/lib/hq2x/hq2x3x.h @@ -0,0 +1,45 @@ +/* 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 AGS_LIB_HQ2X_HQ2X3X_H +#define AGS_LIB_HQ2X_HQ2X3X_H + +#include "ags/shared/core/platform.h" + +namespace AGS3 { + +#if AGS_PLATFORM_OS_ANDROID +void InitLUTs() { +} +void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) { +} +void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) { +} +#else +void InitLUTs(); +void hq2x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL); +void hq3x_32(unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL); +#endif + +} // namespace AGS3 + +#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 7a4fbd1a0c71..355c53013308 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -26,6 +26,7 @@ MODULE_OBJS = \ lib/audio/ogg.o \ lib/audio/sound.o \ lib/audio/wav.o \ + lib/hq2x/hq2x3x.o \ lib/opengl/opengl.o \ lib/std/std.o \ lib/system/datetime.o \ From aab28c10c48eb30099e371a094c3d26144203895 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 22:17:15 -0800 Subject: [PATCH 045/215] AGS: Add missing files from engine/ac/ to project --- engines/ags/engine/ac/string.cpp | 22 ++++---- engines/ags/engine/ac/system.cpp | 45 ++++++++--------- engines/ags/engine/ac/textbox.cpp | 10 ++-- engines/ags/engine/ac/timer.cpp | 8 +-- engines/ags/engine/ac/translation.cpp | 14 +++--- engines/ags/engine/ac/tree_map.cpp | 5 +- engines/ags/engine/ac/viewframe.cpp | 18 +++---- engines/ags/engine/ac/viewport_script.cpp | 16 +++--- engines/ags/engine/ac/walkablearea.cpp | 16 +++--- engines/ags/engine/ac/walkbehind.cpp | 6 +-- engines/ags/lib/allegro/keyboard.cpp | 2 + engines/ags/lib/allegro/keyboard.h | 4 ++ engines/ags/lib/std/chrono.h | 61 +++++++++++++++-------- engines/ags/module.mk | 11 ++++ 14 files changed, 133 insertions(+), 105 deletions(-) diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index 283be7111fa3..b1ac38d05c32 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -21,23 +21,23 @@ */ //include -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/string.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/display.h" +#include "ags/engine/ac/display.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/dynobj/scriptstring.h" #include "ags/shared/font/fonts.h" -#include "ags/shared/debugging/debug_log.h" -#include "ags/shared/script/runtimescriptvalue.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/script/runtimescriptvalue.h" #include "ags/shared/util/string_compat.h" #include "ags/shared/debugging/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/math.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/math.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index 6c52eb2b5194..954d8ff9cd73 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -21,30 +21,30 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/mouse.h" -#include "ags/shared/ac/string.h" -#include "ags/shared/ac/system.h" -#include "ags/shared/ac/dynobj/scriptsystem.h" -#include "ags/shared/debugging/debug_log.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/mouse.h" +#include "ags/engine/ac/string.h" +#include "ags/engine/ac/system.h" +#include "ags/engine/ac/dynobj/scriptsystem.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/debugging/out.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/main/main.h" -#include "ags/shared/gfx/graphicsdriver.h" -#include "ags/shared/ac/dynobj/cc_audiochannel.h" -#include "ags/shared/main/graphics_mode.h" -#include "ags/shared/ac/global_debug.h" -#include "ags/shared/ac/global_translation.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/main.h" +#include "ags/engine/gfx/graphicsdriver.h" +#include "ags/engine/ac/dynobj/cc_audiochannel.h" +#include "ags/engine/main/graphics_mode.h" +#include "ags/engine/ac/global_debug.h" +#include "ags/engine/ac/global_translation.h" +#include "ags/engine/media/audio/audio_system.h" #include "ags/shared/util/string_compat.h" #include "ags/shared/debugging/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { @@ -130,12 +130,7 @@ int System_GetScrollLock() { } void System_SetNumLock(int newValue) { - // doesn't work ... maybe allegro doesn't implement this on windows - int ledState = key_shifts & (KB_SCROLOCK_FLAG | KB_CAPSLOCK_FLAG); - if (newValue) { - ledState |= KB_NUMLOCK_FLAG; - } - set_leds(ledState); + // No implementation } int System_GetVsync() { diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp index 9a926db00ce7..31b35d74cb97 100644 --- a/engines/ags/engine/ac/textbox.cpp +++ b/engines/ags/engine/ac/textbox.cpp @@ -21,15 +21,15 @@ */ //include -#include "ags/shared/ac/textbox.h" +#include "ags/engine/ac/textbox.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/string.h" +#include "ags/engine/ac/string.h" #include "ags/shared/debugging/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" -#include "ags/shared/ac/dynobj/scriptstring.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptstring.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index 08f475228ff6..5eb0e31c3f52 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -20,16 +20,16 @@ * */ -#include "ags/shared/ac/timer.h" - +#include "ags/engine/ac/timer.h" #include "ags/shared/core/platform.h" +#include "ags/lib/std/chrono.h" +#include "ags/lib/std/thread.h" #if AGS_PLATFORM_DEBUG && defined (__GNUC__) //include //include //include #endif -//include -#include "ags/shared/platform/base/agsplatformdriver.h" +#include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp index 64c065b308d7..7f4612b7762c 100644 --- a/engines/ags/engine/ac/translation.cpp +++ b/engines/ags/engine/ac/translation.cpp @@ -21,15 +21,15 @@ */ //include -#include "ags/shared/ac/asset_helper.h" +#include "ags/engine/ac/asset_helper.h" #include "ags/shared/ac/common.h" -#include "ags/shared/ac/gamesetup.h" +#include "ags/engine/ac/gamesetup.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/ac/global_game.h" -#include "ags/shared/ac/runtime_defines.h" -#include "ags/shared/ac/translation.h" -#include "ags/shared/ac/tree_map.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/global_game.h" +#include "ags/engine/ac/runtime_defines.h" +#include "ags/engine/ac/translation.h" +#include "ags/engine/ac/tree_map.h" #include "ags/shared/ac/wordsdictionary.h" #include "ags/shared/debugging/out.h" #include "ags/shared/util/misc.h" diff --git a/engines/ags/engine/ac/tree_map.cpp b/engines/ags/engine/ac/tree_map.cpp index d81be33d3b21..008796689c74 100644 --- a/engines/ags/engine/ac/tree_map.cpp +++ b/engines/ags/engine/ac/tree_map.cpp @@ -20,10 +20,9 @@ * */ -//include -//include #include "ags/shared/ac/common.h" -#include "ags/shared/ac/tree_map.h" +#include "ags/engine/ac/tree_map.h" +#include "common/str.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp index 5461f4b1f93a..6faa57beccae 100644 --- a/engines/ags/engine/ac/viewframe.cpp +++ b/engines/ags/engine/ac/viewframe.cpp @@ -21,21 +21,21 @@ */ #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/viewframe.h" -#include "ags/shared/debugging/debug_log.h" +#include "ags/engine/ac/viewframe.h" +#include "ags/engine/debugging/debug_log.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/shared/script/runtimescriptvalue.h" -#include "ags/shared/ac/dynobj/cc_audioclip.h" -#include "ags/shared/ac/draw.h" +#include "ags/engine/script/runtimescriptvalue.h" +#include "ags/engine/ac/dynobj/cc_audioclip.h" +#include "ags/engine/ac/draw.h" #include "ags/shared/ac/game_version.h" -#include "ags/shared/media/audio/audio_system.h" +#include "ags/engine/media/audio/audio_system.h" #include "ags/shared/debugging/out.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" -} // namespace AGS3 +namespace AGS3 { using AGS::Shared::Bitmap; using AGS::Shared::Graphics; diff --git a/engines/ags/engine/ac/viewport_script.cpp b/engines/ags/engine/ac/viewport_script.cpp index 5d0c2672d89e..23edbfa23211 100644 --- a/engines/ags/engine/ac/viewport_script.cpp +++ b/engines/ags/engine/ac/viewport_script.cpp @@ -26,14 +26,14 @@ // //============================================================================= -#include "ags/shared/ac/dynobj/scriptcamera.h" -#include "ags/shared/ac/dynobj/scriptviewport.h" -#include "ags/shared/ac/dynobj/scriptuserobject.h" -#include "ags/shared/ac/draw.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/debugging/debug_log.h" -#include "ags/shared/script/script_api.h" -#include "ags/shared/script/script_runtime.h" +#include "ags/engine/ac/dynobj/scriptcamera.h" +#include "ags/engine/ac/dynobj/scriptviewport.h" +#include "ags/engine/ac/dynobj/scriptuserobject.h" +#include "ags/engine/ac/draw.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp index 8d9a62caf20e..f8a585a9bc66 100644 --- a/engines/ags/engine/ac/walkablearea.cpp +++ b/engines/ags/engine/ac/walkablearea.cpp @@ -21,15 +21,15 @@ */ #include "ags/shared/ac/common.h" -#include "ags/shared/ac/object.h" -#include "ags/shared/ac/character.h" -#include "ags/shared/ac/gamestate.h" +#include "ags/engine/ac/object.h" +#include "ags/engine/ac/character.h" +#include "ags/engine/ac/gamestate.h" #include "ags/shared/ac/gamesetupstruct.h" -#include "ags/shared/ac/object.h" -#include "ags/shared/ac/room.h" -#include "ags/shared/ac/roomobject.h" -#include "ags/shared/ac/roomstatus.h" -#include "ags/shared/ac/walkablearea.h" +#include "ags/engine/ac/object.h" +#include "ags/engine/ac/room.h" +#include "ags/engine/ac/roomobject.h" +#include "ags/engine/ac/roomstatus.h" +#include "ags/engine/ac/walkablearea.h" #include "ags/shared/game/roomstruct.h" #include "ags/shared/gfx/bitmap.h" diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp index 27b36e1ec4f5..2c53228b0d6e 100644 --- a/engines/ags/engine/ac/walkbehind.cpp +++ b/engines/ags/engine/ac/walkbehind.cpp @@ -20,11 +20,11 @@ * */ -#include "ags/shared/ac/walkbehind.h" +#include "ags/engine/ac/walkbehind.h" #include "ags/shared/ac/common.h" #include "ags/shared/ac/common_defines.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/gfx/graphicsdriver.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" namespace AGS3 { diff --git a/engines/ags/lib/allegro/keyboard.cpp b/engines/ags/lib/allegro/keyboard.cpp index 38516df5a67c..652e73815ecf 100644 --- a/engines/ags/lib/allegro/keyboard.cpp +++ b/engines/ags/lib/allegro/keyboard.cpp @@ -30,9 +30,11 @@ namespace AGS3 { bool key[Common::KEYCODE_LAST]; +uint key_shifts; int install_keyboard() { Common::fill(&key[0], &key[Common::KEYCODE_LAST], false); + key_shifts = 0; return 0; } diff --git a/engines/ags/lib/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h index 15a1ce5512ad..01a85e338b18 100644 --- a/engines/ags/lib/allegro/keyboard.h +++ b/engines/ags/lib/allegro/keyboard.h @@ -33,6 +33,9 @@ namespace AGS3 { #define KB_SHIFT_FLAG Common::KBD_SHIFT #define KB_CTRL_FLAG Common::KBD_CTRL #define KB_ALT_FLAG Common::KBD_ALT +#define KB_NUMLOCK_FLAG Common::KBD_NUM +#define KB_CAPSLOCK_FLAG Common::KBD_CAPS +#define KB_SCROLOCK_FLAG Common::KBD_SCRL #define KEY_LSHIFT Common::KEYCODE_LSHIFT #define KEY_RSHIFT Common::KEYCODE_RSHIFT @@ -169,6 +172,7 @@ namespace AGS3 { #define __allegro_KEY_AT Common::KEYCODE_AT extern bool key[Common::KEYCODE_LAST]; +extern uint key_shifts; AL_FUNC(bool, keyboard_needs_poll, (void)); AL_FUNC(int, poll_keyboard, (void)); diff --git a/engines/ags/lib/std/chrono.h b/engines/ags/lib/std/chrono.h index 5bbb2b03fd92..a5728bd8da6e 100644 --- a/engines/ags/lib/std/chrono.h +++ b/engines/ags/lib/std/chrono.h @@ -30,7 +30,43 @@ namespace std { namespace chrono { -typedef uint32 milliseconds; +class duration { +private: + uint32 _value; +public: + duration() : _value(0) { + } + duration(uint32 value) : _value(value) { + } + + size_t count() const { + // durations for ScummVM are hardcoded to be in milliseconds + return 1000; + } + + operator uint32() const { + return _value; + } + + inline bool operator>=(const duration &rhs) const { + return _value >= rhs._value; + } +}; + +class milliseconds : public duration { +public: + milliseconds() : duration(0) {} + milliseconds(uint32 val) : duration(val) {} + + static milliseconds zero() { return milliseconds(); } +}; + +class microseconds : public duration { +public: + microseconds() : duration(0) {} + microseconds(long val) : duration(val / 1000) {} +}; + struct system_clock { }; @@ -50,30 +86,11 @@ struct steady_clock { // wraps QueryPerformanceCounter using high_resolution_clock = steady_clock; -class duration { -private: - uint32 _value; -public: - duration() : _value(0) { - } - duration(uint32 value) : _value(value) { - } - - size_t count() const { - // durations for ScummVM are hardcoded to be in milliseconds - return 1000; - } - - operator milliseconds() const { - return _value; - } -}; - template duration duration_cast(T param); -template -duration duration_cast(milliseconds param) { +template +duration duration_cast(T param) { return duration(param); } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 355c53013308..a5fd0e803f58 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -212,6 +212,17 @@ MODULE_OBJS = \ engine/ac/speech.o \ engine/ac/sprite.o \ engine/ac/spritecache_engine.o \ + engine/ac/string.o \ + engine/ac/sys_events.o \ + engine/ac/system.o \ + engine/ac/textbox.o \ + engine/ac/timer.o \ + engine/ac/translation.o \ + engine/ac/tree_map.o \ + engine/ac/viewframe.o \ + engine/ac/viewport_script.o \ + engine/ac/walkablearea.o \ + engine/ac/walkbehind.o \ engine/debugging/consoleoutputtarget.o \ engine/debugging/debug.o \ engine/debugging/filebasedagsdebugger.o \ From 805bb3014a72eadba98733b9ab63fbea5a8cee77 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 22:26:23 -0800 Subject: [PATCH 046/215] AGS: Added shared/game/main_game_file.cpp to project --- engines/ags/module.mk | 1 + engines/ags/shared/game/main_game_file.cpp | 6 ++++-- engines/ags/shared/game/main_game_file.h | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index a5fd0e803f58..1bca0736cd8d 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -51,6 +51,7 @@ MODULE_OBJS = \ shared/font/wfnfontrenderer.o \ shared/game/customproperties.o \ shared/game/interactions.o \ + shared/game/main_game_file.o \ shared/game/room_file.o \ shared/game/room_file_deprecated.o \ shared/game/roomstruct.o \ diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 276aceb53cc2..48edb9ab8b15 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -633,8 +633,10 @@ HGameFileError ReadSpriteFlags(LoadedGameEntities &ents, Stream *in, GameDataVer sprcount, (uint32_t)SpriteCache::MAX_SPRITE_INDEX + 1)); ents.SpriteCount = sprcount; - ents.SpriteFlags.reset(new char[sprcount]); - in->Read(ents.SpriteFlags.get(), sprcount); + ents.SpriteFlags.clear(); + ents.SpriteFlags.resize(sprcount); + + in->Read(&ents.SpriteFlags[0], sprcount); return HGameFileError::None(); } diff --git a/engines/ags/shared/game/main_game_file.h b/engines/ags/shared/game/main_game_file.h index 0a30f115e0c1..108abf51b11e 100644 --- a/engines/ags/shared/game/main_game_file.h +++ b/engines/ags/shared/game/main_game_file.h @@ -119,7 +119,7 @@ struct LoadedGameEntities { // Original sprite data (when it was read into const-sized arrays) size_t SpriteCount; - std::unique_ptr SpriteFlags; + Common::Array SpriteFlags; // Old dialog support // legacy compiled dialog script of its own format, From e875b1d25ba4d7fbf5f227bd0ad32738b2a84ccb Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 22:30:43 -0800 Subject: [PATCH 047/215] AGS: Added shared/util/stdio_compat.cpp to project --- engines/ags/module.mk | 1 + engines/ags/shared/util/stdio_compat.cpp | 8 +++++--- engines/ags/shared/util/stdio_compat.h | 8 -------- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 1bca0736cd8d..02d2539fda4a 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -84,6 +84,7 @@ MODULE_OBJS = \ shared/util/mutifilelib.o \ shared/util/path.o \ shared/util/proxystream.o \ + shared/util/stdio_compat.o \ shared/util/stream.o \ shared/util/string.o \ shared/util/string_compat.o \ diff --git a/engines/ags/shared/util/stdio_compat.cpp b/engines/ags/shared/util/stdio_compat.cpp index 8a0048364dd4..e5fe999338de 100644 --- a/engines/ags/shared/util/stdio_compat.cpp +++ b/engines/ags/shared/util/stdio_compat.cpp @@ -28,7 +28,7 @@ namespace AGS3 { -int ags_fseek(Common::Stream *stream, file_off_t offset, int whence) { +int ags_fseek(Common::Stream *stream, file_off_t offset, int whence) { Common::SeekableReadStream *rs = dynamic_cast(stream); Common::SeekableWriteStream *ws = dynamic_cast(stream); @@ -40,8 +40,10 @@ int ags_fseek(Common::Stream *stream, file_off_t offset, int whence) { error("Seek on null stream"); } -file_off_t ags_ftell(FILE *stream) { - return stream->pos(); +file_off_t ags_ftell(Common::Stream *stream) { + Common::SeekableReadStream *rs = dynamic_cast(stream); + assert(rs); + return rs->pos(); } int ags_file_exists(const char *path) { diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h index c930546b0347..f3bfc739990a 100644 --- a/engines/ags/shared/util/stdio_compat.h +++ b/engines/ags/shared/util/stdio_compat.h @@ -29,10 +29,6 @@ namespace AGS3 { typedef int64 file_off_t; -#ifdef __cplusplus -extern "C" { -#endif - int ags_fseek(Common::Stream *stream, file_off_t offset, int whence); file_off_t ags_ftell(Common::Stream *stream); @@ -41,10 +37,6 @@ int ags_directory_exists(const char *path); int ags_path_exists(const char *path); file_off_t ags_file_size(const char *path); -#ifdef __cplusplus -} -#endif - } // namespace AGS3 #endif From 9ff37239728af272ec554d13a787695c6f8f4486 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 27 Nov 2020 22:44:00 -0800 Subject: [PATCH 048/215] AGS: Add in missing code to project --- engines/ags/engine/plugin/agsplugin.cpp | 18 ++++++++++++++++++ engines/ags/engine/plugin/agsplugin.h | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index f128e0c5992f..637330b9df6c 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -156,9 +156,27 @@ std::vector _registered_builtin_plugins; void IAGSEngine::AbortGame(const char *reason) { quit((const char *)reason); } + const char *IAGSEngine::GetEngineVersion() { return get_engine_version(); } + +#ifdef WINDOWS_VERSION + +HWND IAGSEngine::GetWindowHandle() { + return (HWND)0; +} + +LPDIRECTDRAW2 IAGSEngine::GetDirectDraw2() { + return nullptr; +} + +LPDIRECTDRAWSURFACE2 IAGSEngine::GetBitmapSurface(BITMAP *) { + return nullptr; +} + +#endif + void IAGSEngine::RegisterScriptFunction(const char *name, void *addy) { ccAddExternalPluginFunction(name, addy); } diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/engine/plugin/agsplugin.h index 6b40b888a4a1..f38aca8c99cc 100644 --- a/engines/ags/engine/plugin/agsplugin.h +++ b/engines/ags/engine/plugin/agsplugin.h @@ -59,7 +59,7 @@ typedef int HWND; // This file is distributed as part of the Plugin API docs, so // ensure that WINDOWS_VERSION is defined (if applicable) -#if defined(_WIN32) +#if AGS_PLATFORM_OS_WINDOWS #undef WINDOWS_VERSION #define WINDOWS_VERSION #endif From 686d763c2f91605f79d045f40837cdc72ecb1e07 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 08:41:36 -0800 Subject: [PATCH 049/215] AGS: Added stubs for DUH player --- engines/ags/engine/ac/file.cpp | 2 +- .../ags/engine/media/audio/clip_mydumbmod.h | 2 +- engines/ags/lib/audio/aldumb.cpp | 133 ++++++++++++++++++ engines/ags/lib/{ => audio}/aldumb.h | 10 +- engines/ags/lib/{ => audio}/dumb.h | 0 engines/ags/module.mk | 2 +- 6 files changed, 137 insertions(+), 12 deletions(-) create mode 100644 engines/ags/lib/audio/aldumb.cpp rename engines/ags/lib/{ => audio}/aldumb.h (97%) rename engines/ags/lib/{ => audio}/dumb.h (100%) diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index cfee54d31ccc..ae826d948928 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/lib/aldumb.h" +#include "ags/lib/audio/aldumb.h" #include "ags/engine/ac/asset_helper.h" #include "ags/shared/ac/audiocliptype.h" #include "ags/engine/ac/file.h" diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index 927eee6f8991..75c0a0433b4c 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -23,7 +23,7 @@ #ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H -#include "ags/lib/aldumb.h" +#include "ags/lib/audio/aldumb.h" #include "ags/engine/media/audio/soundclip.h" namespace AGS3 { diff --git a/engines/ags/lib/audio/aldumb.cpp b/engines/ags/lib/audio/aldumb.cpp new file mode 100644 index 000000000000..b1eeba1b1467 --- /dev/null +++ b/engines/ags/lib/audio/aldumb.cpp @@ -0,0 +1,133 @@ +/* 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 "ags/lib/audio/aldumb.h" + +namespace AGS3 { + +void dumb_register_packfiles() { +} + +DUMBFILE *dumbfile_open_packfile(PACKFILE *p) { + warning("TODO: dumbfile_open_packfile"); + return nullptr; +} + +DUMBFILE *dumbfile_from_packfile(PACKFILE *p) { + warning("TODO: dumbfile_from_packfile"); + return nullptr; +} + +void dumb_register_dat_duh(long type) { + warning("TODO: dumb_register_dat_duh"); +} + +void dumb_register_dat_it(long type) { + warning("TODO: dumb_register_dat_it"); +} + +void dumb_register_dat_xm(long type) { + warning("TODO: dumb_register_dat_xm"); +} + +void dumb_register_dat_s3m(long type) { + warning("TODO: dumb_register_dat_s3m"); +} + +void dumb_register_dat_mod(long type) { + warning("TODO: dumb_register_dat_mod"); +} + +void dumb_register_dat_it_quick(long type) { + warning("TODO: dumb_register_dat_it_quick"); +} + +void dumb_register_dat_xm_quick(long type) { + warning("TODO: dumb_register_dat_xm_quick"); +} + +void dumb_register_dat_s3m_quick(long type) { + warning("TODO: dumb_register_dat_s3m_quick"); +} + +void dumb_register_dat_mod_quick(long type) { + warning("TODO: dumb_register_dat_mod_quick"); +} + +/* DUH Playing Functions */ + +AL_DUH_PLAYER *al_start_duh(DUH *duh, int n_channels, long pos, float volume, long bufsize, int freq) { + warning("TODO: al_start_duh"); + return nullptr; +} + +void al_stop_duh(AL_DUH_PLAYER *dp) { + warning("TODO: al_stop_duh"); +} + +void al_pause_duh(AL_DUH_PLAYER *dp) { + warning("TODO: al_pause_duh"); +} + +void al_resume_duh(AL_DUH_PLAYER *dp) { + warning("TODO: al_resume_duh"); +} + +void al_duh_set_priority(AL_DUH_PLAYER *dp, int priority) { + warning("TODO: al_duh_set_priority"); +} + +void al_duh_set_volume(AL_DUH_PLAYER *dp, float volume) { + warning("TODO: al_duh_set_volume"); +} + +float al_duh_get_volume(AL_DUH_PLAYER *dp) { + warning("TODO: al_duh_get_volume"); + return 0; +} + +int al_poll_duh(AL_DUH_PLAYER *dp) { + warning("TODO: al_poll_duh"); + return 0; +} + +long al_duh_get_position(AL_DUH_PLAYER *dp) { + warning("TODO: al_duh_get_position"); + return 0; +} + +AL_DUH_PLAYER *al_duh_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer, float volume, long bufsize, int freq) { + warning("TODO: al_duh_encapsulate_sigrenderer"); + return nullptr; +} + +DUH_SIGRENDERER *al_duh_get_sigrenderer(AL_DUH_PLAYER *dp) { + warning("TODO: al_duh_get_sigrenderer"); + return nullptr; +} + +DUH_SIGRENDERER *al_duh_decompose_to_sigrenderer(AL_DUH_PLAYER *dp) { + warning("TODO: al_duh_decompose_to_sigrenderer"); + return nullptr; +} + +} // namespace AGS3 diff --git a/engines/ags/lib/aldumb.h b/engines/ags/lib/audio/aldumb.h similarity index 97% rename from engines/ags/lib/aldumb.h rename to engines/ags/lib/audio/aldumb.h index b72dc823d8e3..478760e1bcd7 100644 --- a/engines/ags/lib/aldumb.h +++ b/engines/ags/lib/audio/aldumb.h @@ -43,14 +43,10 @@ #define AGS_LIB_ALDUMB_H #include "ags/lib/allegro.h" -#include "ags/lib/dumb.h" +#include "ags/lib/audio/dumb.h" namespace AGS3 { -#ifdef __cplusplus -extern "C" { -#endif - /* Packfile Support */ void dumb_register_packfiles(void); @@ -109,10 +105,6 @@ DUH_SIGRENDERER *al_duh_decompose_to_sigrenderer(AL_DUH_PLAYER *dp); #endif -#ifdef __cplusplus -} -#endif - } // namespace AGS3 #endif diff --git a/engines/ags/lib/dumb.h b/engines/ags/lib/audio/dumb.h similarity index 100% rename from engines/ags/lib/dumb.h rename to engines/ags/lib/audio/dumb.h diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 02d2539fda4a..d5a605bc366e 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -19,7 +19,7 @@ MODULE_OBJS = \ lib/allegro/mouse.o \ lib/allegro/system.o \ lib/allegro/unicode.o \ - lib/audio/audio.o \ + lib/audio/aldumb.o \ lib/audio/digi.o \ lib/audio/midi.o \ lib/audio/mp3.o \ From 244ec94b7f01e0778041aa89e49dff66a540ab20 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 09:22:56 -0800 Subject: [PATCH 050/215] AGS: Adding DUMBFILE methods to project --- engines/ags/lib/audio/aldumb.h | 2 +- engines/ags/lib/dumb-0.9.2/dumbfile.cpp | 409 ++++++++++++++++++ .../{audio/dumb.h => dumb-0.9.2/dumbfile.h} | 4 +- engines/ags/module.mk | 1 + 4 files changed, 413 insertions(+), 3 deletions(-) create mode 100644 engines/ags/lib/dumb-0.9.2/dumbfile.cpp rename engines/ags/lib/{audio/dumb.h => dumb-0.9.2/dumbfile.h} (99%) diff --git a/engines/ags/lib/audio/aldumb.h b/engines/ags/lib/audio/aldumb.h index 478760e1bcd7..61ede22bd85c 100644 --- a/engines/ags/lib/audio/aldumb.h +++ b/engines/ags/lib/audio/aldumb.h @@ -43,7 +43,7 @@ #define AGS_LIB_ALDUMB_H #include "ags/lib/allegro.h" -#include "ags/lib/audio/dumb.h" +#include "ags/lib/dumb-0.9.2/dumbfile.h" namespace AGS3 { diff --git a/engines/ags/lib/dumb-0.9.2/dumbfile.cpp b/engines/ags/lib/dumb-0.9.2/dumbfile.cpp new file mode 100644 index 000000000000..60d82b5801c6 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/dumbfile.cpp @@ -0,0 +1,409 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * dumbfile.c - Hookable, strictly sequential / / \ \ + * file input functions. | < / \_ + * | \/ /\ / + * By entheh. \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +//include + +#include "ags/lib/dumb-0.9.2/dumbfile.h" + +namespace AGS3 { + +static DUMBFILE_SYSTEM *the_dfs = NULL; + + + +void register_dumbfile_system(DUMBFILE_SYSTEM *dfs) { + ASSERT(dfs); + ASSERT(dfs->open); + ASSERT(dfs->getc); + ASSERT(dfs->close); + the_dfs = dfs; +} + + + +struct DUMBFILE { + DUMBFILE_SYSTEM *dfs; + void *file; + long pos; +}; + + + +DUMBFILE *dumbfile_open(const char *filename) { + DUMBFILE *f; + + ASSERT(the_dfs); + + f = (DUMBFILE *)malloc(sizeof(DUMBFILE)); + + if (!f) + return NULL; + + f->dfs = the_dfs; + + f->file = (*the_dfs->open)(filename); + + if (!f->file) { + free(f); + return NULL; + } + + f->pos = 0; + + return f; +} + + + +DUMBFILE *dumbfile_open_ex(void *file, DUMBFILE_SYSTEM *dfs) { + DUMBFILE *f; + + ASSERT(dfs); + ASSERT(dfs->getc); + ASSERT(file); + + f = (DUMBFILE *)malloc(sizeof(DUMBFILE)); + + if (!f) { + if (dfs->close) + (*dfs->close)(file); + return NULL; + } + + f->dfs = dfs; + f->file = file; + + f->pos = 0; + + return f; +} + + + +long dumbfile_pos(DUMBFILE *f) { + ASSERT(f); + + return f->pos; +} + + + +int dumbfile_skip(DUMBFILE *f, long n) { + int rv; + + ASSERT(f); + ASSERT(n >= 0); + + if (f->pos < 0) + return -1; + + f->pos += n; + + if (f->dfs->skip) { + rv = (*f->dfs->skip)(f->file, n); + if (rv) { + f->pos = -1; + return rv; + } + } else { + while (n) { + rv = (*f->dfs->getc)(f->file); + if (rv < 0) { + f->pos = -1; + return rv; + } + n--; + } + } + + return 0; +} + + + +int dumbfile_getc(DUMBFILE *f) { + int rv; + + ASSERT(f); + + if (f->pos < 0) + return -1; + + rv = (*f->dfs->getc)(f->file); + + if (rv < 0) { + f->pos = -1; + return rv; + } + + f->pos++; + + return rv; +} + + + +int dumbfile_igetw(DUMBFILE *f) { + int l, h; + + ASSERT(f); + + if (f->pos < 0) + return -1; + + l = (*f->dfs->getc)(f->file); + if (l < 0) { + f->pos = -1; + return l; + } + + h = (*f->dfs->getc)(f->file); + if (h < 0) { + f->pos = -1; + return h; + } + + f->pos += 2; + + return l | (h << 8); +} + + + +int dumbfile_mgetw(DUMBFILE *f) { + int l, h; + + ASSERT(f); + + if (f->pos < 0) + return -1; + + h = (*f->dfs->getc)(f->file); + if (h < 0) { + f->pos = -1; + return h; + } + + l = (*f->dfs->getc)(f->file); + if (l < 0) { + f->pos = -1; + return l; + } + + f->pos += 2; + + return l | (h << 8); +} + + + +long dumbfile_igetl(DUMBFILE *f) { + unsigned long rv, b; + + ASSERT(f); + + if (f->pos < 0) + return -1; + + rv = (*f->dfs->getc)(f->file); + if ((signed long)rv < 0) { + f->pos = -1; + return rv; + } + + b = (*f->dfs->getc)(f->file); + if ((signed long)b < 0) { + f->pos = -1; + return b; + } + rv |= b << 8; + + b = (*f->dfs->getc)(f->file); + if ((signed long)b < 0) { + f->pos = -1; + return b; + } + rv |= b << 16; + + b = (*f->dfs->getc)(f->file); + if ((signed long)b < 0) { + f->pos = -1; + return b; + } + rv |= b << 24; + + f->pos += 4; + + return rv; +} + + + +long dumbfile_mgetl(DUMBFILE *f) { + unsigned long rv, b; + + ASSERT(f); + + if (f->pos < 0) + return -1; + + rv = (*f->dfs->getc)(f->file); + if ((signed long)rv < 0) { + f->pos = -1; + return rv; + } + rv <<= 24; + + b = (*f->dfs->getc)(f->file); + if ((signed long)b < 0) { + f->pos = -1; + return b; + } + rv |= b << 16; + + b = (*f->dfs->getc)(f->file); + if ((signed long)b < 0) { + f->pos = -1; + return b; + } + rv |= b << 8; + + b = (*f->dfs->getc)(f->file); + if ((signed long)b < 0) { + f->pos = -1; + return b; + } + rv |= b; + + f->pos += 4; + + return rv; +} + + + +unsigned long dumbfile_cgetul(DUMBFILE *f) { + unsigned long rv = 0; + int v; + + do { + v = dumbfile_getc(f); + + if (v < 0) + return v; + + rv <<= 7; + rv |= v & 0x7F; + } while (v & 0x80); + + return rv; +} + + + +signed long dumbfile_cgetsl(DUMBFILE *f) { + unsigned long rv = dumbfile_cgetul(f); + + if (f->pos < 0) + return rv; + + return (rv >> 1) | (rv << 31); +} + + + +long dumbfile_getnc(char *ptr, long n, DUMBFILE *f) { + long rv; + + ASSERT(f); + ASSERT(n >= 0); + + if (f->pos < 0) + return -1; + + if (f->dfs->getnc) { + rv = (*f->dfs->getnc)(ptr, n, f->file); + if (rv < n) { + f->pos = -1; + return MAX(rv, 0); + } + } else { + for (rv = 0; rv < n; rv++) { + int c = (*f->dfs->getc)(f->file); + if (c < 0) { + f->pos = -1; + return rv; + } + *ptr++ = c; + } + } + + f->pos += rv; + + return rv; +} + + + +int dumbfile_error(DUMBFILE *f) { + ASSERT(f); + + return f->pos < 0; +} + + + +int dumbfile_close(DUMBFILE *f) { + int rv; + + ASSERT(f); + + rv = f->pos < 0; + + if (f->dfs->close) + (*f->dfs->close)(f->file); + + free(f); + + return rv; +} + +} // namespace AGS3 diff --git a/engines/ags/lib/audio/dumb.h b/engines/ags/lib/dumb-0.9.2/dumbfile.h similarity index 99% rename from engines/ags/lib/audio/dumb.h rename to engines/ags/lib/dumb-0.9.2/dumbfile.h index a74ffdf0baae..2099c27b48a2 100644 --- a/engines/ags/lib/audio/dumb.h +++ b/engines/ags/lib/dumb-0.9.2/dumbfile.h @@ -39,8 +39,8 @@ * \__/ */ -#ifndef AGS_LIB_DUMB_H -#define AGS_LIB_DUMB_H +#ifndef AGS_LIB_DUMB_DUMBFILE_H +#define AGS_LIB_DUMB_DUMBFILE_H #include "common/stream.h" diff --git a/engines/ags/module.mk b/engines/ags/module.mk index d5a605bc366e..dd57d91c4c27 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -26,6 +26,7 @@ MODULE_OBJS = \ lib/audio/ogg.o \ lib/audio/sound.o \ lib/audio/wav.o \ + lib/dumb-0.9.2/dumbfile.o \ lib/hq2x/hq2x3x.o \ lib/opengl/opengl.o \ lib/std/std.o \ From b20315f27786f9a1e0bc8c4a57d5c9dc6babe069 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 09:27:41 -0800 Subject: [PATCH 051/215] AGS: Add missing dll stub methods to project --- engines/ags/module.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index dd57d91c4c27..0e97a279be40 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -286,6 +286,7 @@ MODULE_OBJS = \ engine/platform/base/agsplatformdriver.o \ engine/platform/linux/acpllnx.o \ engine/plugin/agsplugin.o \ + engine/plugin/library.o \ engine/plugin/pluginobjectreader.o \ engine/script/cc_instance.o \ engine/script/executingscript.o \ From 98060a74ca6dad006f6aa060a05f6f4c93de3276 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 09:36:59 -0800 Subject: [PATCH 052/215] AGS: Added color blending methods --- engines/ags/engine/gfx/blender.cpp | 13 +-- engines/ags/lib/allegro.h | 1 + engines/ags/lib/allegro/colblend.cpp | 115 +++++++++++++++++++++++++++ engines/ags/lib/allegro/colblend.h | 41 ++++++++++ 4 files changed, 158 insertions(+), 12 deletions(-) create mode 100644 engines/ags/lib/allegro/colblend.cpp create mode 100644 engines/ags/lib/allegro/colblend.h diff --git a/engines/ags/engine/gfx/blender.cpp b/engines/ags/engine/gfx/blender.cpp index 549c74f53c98..b800d9bb5184 100644 --- a/engines/ags/engine/gfx/blender.cpp +++ b/engines/ags/engine/gfx/blender.cpp @@ -24,21 +24,10 @@ #include "ags/engine/gfx/blender.h" #include "ags/shared/util/wgt2allg.h" #include "ags/lib/allegro/color.h" +#include "ags/lib/allegro/colblend.h" namespace AGS3 { -extern "C" { - // Fallback routine for when we don't have anything better to do. - unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n); - // Standard Allegro 4 trans blenders for 16 and 15-bit color modes - unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n); - unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n); - // Standard Allegro 4 alpha blenders for 16 and 15-bit color modes - unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n); - unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n); - unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n); -} - // the allegro "inline" ones are not actually inline, so #define // over them to speed it up #define getr32(xx) ((xx >> _rgb_r_shift_32) & 0xFF) diff --git a/engines/ags/lib/allegro.h b/engines/ags/lib/allegro.h index 9952637ada82..879029da104a 100644 --- a/engines/ags/lib/allegro.h +++ b/engines/ags/lib/allegro.h @@ -27,6 +27,7 @@ #include "ags/lib/allegro/alconfig.h" #include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/colblend.h" #include "ags/lib/allegro/color.h" #include "ags/lib/allegro/config.h" #include "ags/lib/allegro/draw.h" diff --git a/engines/ags/lib/allegro/colblend.cpp b/engines/ags/lib/allegro/colblend.cpp new file mode 100644 index 000000000000..4b623a190d15 --- /dev/null +++ b/engines/ags/lib/allegro/colblend.cpp @@ -0,0 +1,115 @@ +/* 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 "ags/lib/allegro/colblend.h" + +namespace AGS3 { + +unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n) { + return 0; +} + +unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n) { + unsigned long result; + + if (n) + n = (n + 1) / 8; + + x = ((x & 0xFFFF) | (x << 16)) & 0x3E07C1F; + y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F; + + result = ((x - y) * n / 32 + y) & 0x3E07C1F; + + return ((result & 0xFFFF) | (result >> 16)); +} + +unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n) { + unsigned long result; + + if (n) + n = (n + 1) / 8; + + x = ((x & 0xFFFF) | (x << 16)) & 0x7E0F81F; + y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F; + + result = ((x - y) * n / 32 + y) & 0x7E0F81F; + + return ((result & 0xFFFF) | (result >> 16)); +} + +unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n) { + unsigned long result; + + n = geta32(x); + + if (n) + n = (n + 1) / 8; + + x = makecol15(getr32(x), getg32(x), getb32(x)); + + x = (x | (x << 16)) & 0x3E07C1F; + y = ((y & 0xFFFF) | (y << 16)) & 0x3E07C1F; + + result = ((x - y) * n / 32 + y) & 0x3E07C1F; + + return ((result & 0xFFFF) | (result >> 16)); +} + +unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n) { + unsigned long result; + + n = geta32(x); + + if (n) + n = (n + 1) / 8; + + x = makecol16(getr32(x), getg32(x), getb32(x)); + + x = (x | (x << 16)) & 0x7E0F81F; + y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F; + + result = ((x - y) * n / 32 + y) & 0x7E0F81F; + + return ((result & 0xFFFF) | (result >> 16)); +} + +unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n) { + unsigned long xx = makecol24(getr32(x), getg32(x), getb32(x)); + unsigned long res, g; + + n = geta32(x); + + if (n) + n++; + + res = ((xx & 0xFF00FF) - (y & 0xFF00FF)) * n / 256 + y; + y &= 0xFF00; + xx &= 0xFF00; + g = (xx - y) * n / 256 + y; + + res &= 0xFF00FF; + g &= 0xFF00; + + return res | g; +} + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/colblend.h b/engines/ags/lib/allegro/colblend.h new file mode 100644 index 000000000000..60eaea8e32ab --- /dev/null +++ b/engines/ags/lib/allegro/colblend.h @@ -0,0 +1,41 @@ +/* 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 AGS_LIB_ALLEGRO_COLBLEND_H +#define AGS_LIB_ALLEGRO_COLBLEND_H + +#include "ags/lib/allegro/alconfig.h" + +namespace AGS3 { + +extern unsigned long _blender_black(unsigned long x, unsigned long y, unsigned long n); + +extern unsigned long _blender_trans15(unsigned long x, unsigned long y, unsigned long n); +extern unsigned long _blender_trans16(unsigned long x, unsigned long y, unsigned long n); + +extern unsigned long _blender_alpha15(unsigned long x, unsigned long y, unsigned long n); +extern unsigned long _blender_alpha16(unsigned long x, unsigned long y, unsigned long n); +extern unsigned long _blender_alpha24(unsigned long x, unsigned long y, unsigned long n); + +} // namespace AGS3 + +#endif From 82ea9ef502dc9aa169d4727c903f9eebe099bef1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 15:37:54 -0800 Subject: [PATCH 053/215] AGS: Adding missing methods --- engines/ags/engine/gfx/gfxfilter_aaogl.cpp | 2 +- engines/ags/lib/allegro/math.cpp | 286 ++++++ engines/ags/lib/dumb-0.9.2/it.h | 716 ++++++++++++++ engines/ags/lib/dumb-0.9.2/readxm.cpp | 1007 ++++++++++++++++++++ 4 files changed, 2010 insertions(+), 1 deletion(-) create mode 100644 engines/ags/lib/allegro/math.cpp create mode 100644 engines/ags/lib/dumb-0.9.2/it.h create mode 100644 engines/ags/lib/dumb-0.9.2/readxm.cpp diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp index 0bec89329c4c..ac26f2955763 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp @@ -22,7 +22,7 @@ #include "ags/shared/core/platform.h" -#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX +#if 1 #include "ags/shared/gfx/gfxfilter_aaogl.h" #include "ags/shared/ogl_headers.h" diff --git a/engines/ags/lib/allegro/math.cpp b/engines/ags/lib/allegro/math.cpp new file mode 100644 index 000000000000..88c1a5eafaa0 --- /dev/null +++ b/engines/ags/lib/allegro/math.cpp @@ -0,0 +1,286 @@ +/* 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 AGS_LIB_ALLEGRO_MATH_H +#define AGS_LIB_ALLEGRO_MATH_H + +#include "ags/lib/allegro/fixed.h" + +namespace AGS3 { + + +fixed _cos_tbl[512] = +{ + /* precalculated fixed point (16.16) cosines for a full circle (0-255) */ + + 65536L, 65531L, 65516L, 65492L, 65457L, 65413L, 65358L, 65294L, + 65220L, 65137L, 65043L, 64940L, 64827L, 64704L, 64571L, 64429L, + 64277L, 64115L, 63944L, 63763L, 63572L, 63372L, 63162L, 62943L, + 62714L, 62476L, 62228L, 61971L, 61705L, 61429L, 61145L, 60851L, + 60547L, 60235L, 59914L, 59583L, 59244L, 58896L, 58538L, 58172L, + 57798L, 57414L, 57022L, 56621L, 56212L, 55794L, 55368L, 54934L, + 54491L, 54040L, 53581L, 53114L, 52639L, 52156L, 51665L, 51166L, + 50660L, 50146L, 49624L, 49095L, 48559L, 48015L, 47464L, 46906L, + 46341L, 45769L, 45190L, 44604L, 44011L, 43412L, 42806L, 42194L, + 41576L, 40951L, 40320L, 39683L, 39040L, 38391L, 37736L, 37076L, + 36410L, 35738L, 35062L, 34380L, 33692L, 33000L, 32303L, 31600L, + 30893L, 30182L, 29466L, 28745L, 28020L, 27291L, 26558L, 25821L, + 25080L, 24335L, 23586L, 22834L, 22078L, 21320L, 20557L, 19792L, + 19024L, 18253L, 17479L, 16703L, 15924L, 15143L, 14359L, 13573L, + 12785L, 11996L, 11204L, 10411L, 9616L, 8820L, 8022L, 7224L, + 6424L, 5623L, 4821L, 4019L, 3216L, 2412L, 1608L, 804L, + 0L, -804L, -1608L, -2412L, -3216L, -4019L, -4821L, -5623L, + -6424L, -7224L, -8022L, -8820L, -9616L, -10411L, -11204L, -11996L, + -12785L, -13573L, -14359L, -15143L, -15924L, -16703L, -17479L, -18253L, + -19024L, -19792L, -20557L, -21320L, -22078L, -22834L, -23586L, -24335L, + -25080L, -25821L, -26558L, -27291L, -28020L, -28745L, -29466L, -30182L, + -30893L, -31600L, -32303L, -33000L, -33692L, -34380L, -35062L, -35738L, + -36410L, -37076L, -37736L, -38391L, -39040L, -39683L, -40320L, -40951L, + -41576L, -42194L, -42806L, -43412L, -44011L, -44604L, -45190L, -45769L, + -46341L, -46906L, -47464L, -48015L, -48559L, -49095L, -49624L, -50146L, + -50660L, -51166L, -51665L, -52156L, -52639L, -53114L, -53581L, -54040L, + -54491L, -54934L, -55368L, -55794L, -56212L, -56621L, -57022L, -57414L, + -57798L, -58172L, -58538L, -58896L, -59244L, -59583L, -59914L, -60235L, + -60547L, -60851L, -61145L, -61429L, -61705L, -61971L, -62228L, -62476L, + -62714L, -62943L, -63162L, -63372L, -63572L, -63763L, -63944L, -64115L, + -64277L, -64429L, -64571L, -64704L, -64827L, -64940L, -65043L, -65137L, + -65220L, -65294L, -65358L, -65413L, -65457L, -65492L, -65516L, -65531L, + -65536L, -65531L, -65516L, -65492L, -65457L, -65413L, -65358L, -65294L, + -65220L, -65137L, -65043L, -64940L, -64827L, -64704L, -64571L, -64429L, + -64277L, -64115L, -63944L, -63763L, -63572L, -63372L, -63162L, -62943L, + -62714L, -62476L, -62228L, -61971L, -61705L, -61429L, -61145L, -60851L, + -60547L, -60235L, -59914L, -59583L, -59244L, -58896L, -58538L, -58172L, + -57798L, -57414L, -57022L, -56621L, -56212L, -55794L, -55368L, -54934L, + -54491L, -54040L, -53581L, -53114L, -52639L, -52156L, -51665L, -51166L, + -50660L, -50146L, -49624L, -49095L, -48559L, -48015L, -47464L, -46906L, + -46341L, -45769L, -45190L, -44604L, -44011L, -43412L, -42806L, -42194L, + -41576L, -40951L, -40320L, -39683L, -39040L, -38391L, -37736L, -37076L, + -36410L, -35738L, -35062L, -34380L, -33692L, -33000L, -32303L, -31600L, + -30893L, -30182L, -29466L, -28745L, -28020L, -27291L, -26558L, -25821L, + -25080L, -24335L, -23586L, -22834L, -22078L, -21320L, -20557L, -19792L, + -19024L, -18253L, -17479L, -16703L, -15924L, -15143L, -14359L, -13573L, + -12785L, -11996L, -11204L, -10411L, -9616L, -8820L, -8022L, -7224L, + -6424L, -5623L, -4821L, -4019L, -3216L, -2412L, -1608L, -804L, + 0L, 804L, 1608L, 2412L, 3216L, 4019L, 4821L, 5623L, + 6424L, 7224L, 8022L, 8820L, 9616L, 10411L, 11204L, 11996L, + 12785L, 13573L, 14359L, 15143L, 15924L, 16703L, 17479L, 18253L, + 19024L, 19792L, 20557L, 21320L, 22078L, 22834L, 23586L, 24335L, + 25080L, 25821L, 26558L, 27291L, 28020L, 28745L, 29466L, 30182L, + 30893L, 31600L, 32303L, 33000L, 33692L, 34380L, 35062L, 35738L, + 36410L, 37076L, 37736L, 38391L, 39040L, 39683L, 40320L, 40951L, + 41576L, 42194L, 42806L, 43412L, 44011L, 44604L, 45190L, 45769L, + 46341L, 46906L, 47464L, 48015L, 48559L, 49095L, 49624L, 50146L, + 50660L, 51166L, 51665L, 52156L, 52639L, 53114L, 53581L, 54040L, + 54491L, 54934L, 55368L, 55794L, 56212L, 56621L, 57022L, 57414L, + 57798L, 58172L, 58538L, 58896L, 59244L, 59583L, 59914L, 60235L, + 60547L, 60851L, 61145L, 61429L, 61705L, 61971L, 62228L, 62476L, + 62714L, 62943L, 63162L, 63372L, 63572L, 63763L, 63944L, 64115L, + 64277L, 64429L, 64571L, 64704L, 64827L, 64940L, 65043L, 65137L, + 65220L, 65294L, 65358L, 65413L, 65457L, 65492L, 65516L, 65531L +}; + + + +fixed _tan_tbl[256] = +{ + /* precalculated fixed point (16.16) tangents for a half circle (0-127) */ + + 0L, 804L, 1609L, 2414L, 3220L, 4026L, 4834L, 5644L, + 6455L, 7268L, 8083L, 8901L, 9721L, 10545L, 11372L, 12202L, + 13036L, 13874L, 14717L, 15564L, 16416L, 17273L, 18136L, 19005L, + 19880L, 20762L, 21650L, 22546L, 23449L, 24360L, 25280L, 26208L, + 27146L, 28093L, 29050L, 30018L, 30996L, 31986L, 32988L, 34002L, + 35030L, 36071L, 37126L, 38196L, 39281L, 40382L, 41500L, 42636L, + 43790L, 44963L, 46156L, 47369L, 48605L, 49863L, 51145L, 52451L, + 53784L, 55144L, 56532L, 57950L, 59398L, 60880L, 62395L, 63947L, + 65536L, 67165L, 68835L, 70548L, 72308L, 74116L, 75974L, 77887L, + 79856L, 81885L, 83977L, 86135L, 88365L, 90670L, 93054L, 95523L, + 98082L, 100736L, 103493L, 106358L, 109340L, 112447L, 115687L, 119071L, + 122609L, 126314L, 130198L, 134276L, 138564L, 143081L, 147847L, 152884L, + 158218L, 163878L, 169896L, 176309L, 183161L, 190499L, 198380L, 206870L, + 216043L, 225990L, 236817L, 248648L, 261634L, 275959L, 291845L, 309568L, + 329472L, 351993L, 377693L, 407305L, 441808L, 482534L, 531352L, 590958L, + 665398L, 761030L, 888450L, 1066730L,1334016L,1779314L,2669641L,5340086L, + -2147483647L,-5340086L,-2669641L,-1779314L,-1334016L,-1066730L,-888450L,-761030L, + -665398L,-590958L,-531352L,-482534L,-441808L,-407305L,-377693L,-351993L, + -329472L,-309568L,-291845L,-275959L,-261634L,-248648L,-236817L,-225990L, + -216043L,-206870L,-198380L,-190499L,-183161L,-176309L,-169896L,-163878L, + -158218L,-152884L,-147847L,-143081L,-138564L,-134276L,-130198L,-126314L, + -122609L,-119071L,-115687L,-112447L,-109340L,-106358L,-103493L,-100736L, + -98082L, -95523L, -93054L, -90670L, -88365L, -86135L, -83977L, -81885L, + -79856L, -77887L, -75974L, -74116L, -72308L, -70548L, -68835L, -67165L, + -65536L, -63947L, -62395L, -60880L, -59398L, -57950L, -56532L, -55144L, + -53784L, -52451L, -51145L, -49863L, -48605L, -47369L, -46156L, -44963L, + -43790L, -42636L, -41500L, -40382L, -39281L, -38196L, -37126L, -36071L, + -35030L, -34002L, -32988L, -31986L, -30996L, -30018L, -29050L, -28093L, + -27146L, -26208L, -25280L, -24360L, -23449L, -22546L, -21650L, -20762L, + -19880L, -19005L, -18136L, -17273L, -16416L, -15564L, -14717L, -13874L, + -13036L, -12202L, -11372L, -10545L, -9721L, -8901L, -8083L, -7268L, + -6455L, -5644L, -4834L, -4026L, -3220L, -2414L, -1609L, -804L +}; + + + +fixed _acos_tbl[513] = +{ + /* precalculated fixed point (16.16) inverse cosines (-1 to 1) */ + + 0x800000L, 0x7C65C7L, 0x7AE75AL, 0x79C19EL, 0x78C9BEL, 0x77EF25L, 0x772953L, 0x76733AL, + 0x75C991L, 0x752A10L, 0x74930CL, 0x740345L, 0x7379C1L, 0x72F5BAL, 0x72768FL, 0x71FBBCL, + 0x7184D3L, 0x711174L, 0x70A152L, 0x703426L, 0x6FC9B5L, 0x6F61C9L, 0x6EFC36L, 0x6E98D1L, + 0x6E3777L, 0x6DD805L, 0x6D7A5EL, 0x6D1E68L, 0x6CC40BL, 0x6C6B2FL, 0x6C13C1L, 0x6BBDAFL, + 0x6B68E6L, 0x6B1558L, 0x6AC2F5L, 0x6A71B1L, 0x6A217EL, 0x69D251L, 0x698420L, 0x6936DFL, + 0x68EA85L, 0x689F0AL, 0x685465L, 0x680A8DL, 0x67C17DL, 0x67792CL, 0x673194L, 0x66EAAFL, + 0x66A476L, 0x665EE5L, 0x6619F5L, 0x65D5A2L, 0x6591E7L, 0x654EBFL, 0x650C26L, 0x64CA18L, + 0x648890L, 0x64478CL, 0x640706L, 0x63C6FCL, 0x63876BL, 0x63484FL, 0x6309A5L, 0x62CB6AL, + 0x628D9CL, 0x625037L, 0x621339L, 0x61D69FL, 0x619A68L, 0x615E90L, 0x612316L, 0x60E7F7L, + 0x60AD31L, 0x6072C3L, 0x6038A9L, 0x5FFEE3L, 0x5FC56EL, 0x5F8C49L, 0x5F5372L, 0x5F1AE7L, + 0x5EE2A7L, 0x5EAAB0L, 0x5E7301L, 0x5E3B98L, 0x5E0473L, 0x5DCD92L, 0x5D96F3L, 0x5D6095L, + 0x5D2A76L, 0x5CF496L, 0x5CBEF2L, 0x5C898BL, 0x5C545EL, 0x5C1F6BL, 0x5BEAB0L, 0x5BB62DL, + 0x5B81E1L, 0x5B4DCAL, 0x5B19E7L, 0x5AE638L, 0x5AB2BCL, 0x5A7F72L, 0x5A4C59L, 0x5A1970L, + 0x59E6B6L, 0x59B42AL, 0x5981CCL, 0x594F9BL, 0x591D96L, 0x58EBBDL, 0x58BA0EL, 0x588889L, + 0x58572DL, 0x5825FAL, 0x57F4EEL, 0x57C40AL, 0x57934DL, 0x5762B5L, 0x573243L, 0x5701F5L, + 0x56D1CCL, 0x56A1C6L, 0x5671E4L, 0x564224L, 0x561285L, 0x55E309L, 0x55B3ADL, 0x558471L, + 0x555555L, 0x552659L, 0x54F77BL, 0x54C8BCL, 0x549A1BL, 0x546B98L, 0x543D31L, 0x540EE7L, + 0x53E0B9L, 0x53B2A7L, 0x5384B0L, 0x5356D4L, 0x532912L, 0x52FB6BL, 0x52CDDDL, 0x52A068L, + 0x52730CL, 0x5245C9L, 0x52189EL, 0x51EB8BL, 0x51BE8FL, 0x5191AAL, 0x5164DCL, 0x513825L, + 0x510B83L, 0x50DEF7L, 0x50B280L, 0x50861FL, 0x5059D2L, 0x502D99L, 0x500175L, 0x4FD564L, + 0x4FA967L, 0x4F7D7DL, 0x4F51A6L, 0x4F25E2L, 0x4EFA30L, 0x4ECE90L, 0x4EA301L, 0x4E7784L, + 0x4E4C19L, 0x4E20BEL, 0x4DF574L, 0x4DCA3AL, 0x4D9F10L, 0x4D73F6L, 0x4D48ECL, 0x4D1DF1L, + 0x4CF305L, 0x4CC829L, 0x4C9D5AL, 0x4C729AL, 0x4C47E9L, 0x4C1D45L, 0x4BF2AEL, 0x4BC826L, + 0x4B9DAAL, 0x4B733BL, 0x4B48D9L, 0x4B1E84L, 0x4AF43BL, 0x4AC9FEL, 0x4A9FCDL, 0x4A75A7L, + 0x4A4B8DL, 0x4A217EL, 0x49F77AL, 0x49CD81L, 0x49A393L, 0x4979AFL, 0x494FD5L, 0x492605L, + 0x48FC3FL, 0x48D282L, 0x48A8CFL, 0x487F25L, 0x485584L, 0x482BECL, 0x48025DL, 0x47D8D6L, + 0x47AF57L, 0x4785E0L, 0x475C72L, 0x47330AL, 0x4709ABL, 0x46E052L, 0x46B701L, 0x468DB7L, + 0x466474L, 0x463B37L, 0x461201L, 0x45E8D0L, 0x45BFA6L, 0x459682L, 0x456D64L, 0x45444BL, + 0x451B37L, 0x44F229L, 0x44C920L, 0x44A01CL, 0x44771CL, 0x444E21L, 0x44252AL, 0x43FC38L, + 0x43D349L, 0x43AA5FL, 0x438178L, 0x435894L, 0x432FB4L, 0x4306D8L, 0x42DDFEL, 0x42B527L, + 0x428C53L, 0x426381L, 0x423AB2L, 0x4211E5L, 0x41E91AL, 0x41C051L, 0x41978AL, 0x416EC5L, + 0x414601L, 0x411D3EL, 0x40F47CL, 0x40CBBBL, 0x40A2FBL, 0x407A3CL, 0x40517DL, 0x4028BEL, + 0x400000L, 0x3FD742L, 0x3FAE83L, 0x3F85C4L, 0x3F5D05L, 0x3F3445L, 0x3F0B84L, 0x3EE2C2L, + 0x3EB9FFL, 0x3E913BL, 0x3E6876L, 0x3E3FAFL, 0x3E16E6L, 0x3DEE1BL, 0x3DC54EL, 0x3D9C7FL, + 0x3D73ADL, 0x3D4AD9L, 0x3D2202L, 0x3CF928L, 0x3CD04CL, 0x3CA76CL, 0x3C7E88L, 0x3C55A1L, + 0x3C2CB7L, 0x3C03C8L, 0x3BDAD6L, 0x3BB1DFL, 0x3B88E4L, 0x3B5FE4L, 0x3B36E0L, 0x3B0DD7L, + 0x3AE4C9L, 0x3ABBB5L, 0x3A929CL, 0x3A697EL, 0x3A405AL, 0x3A1730L, 0x39EDFFL, 0x39C4C9L, + 0x399B8CL, 0x397249L, 0x3948FFL, 0x391FAEL, 0x38F655L, 0x38CCF6L, 0x38A38EL, 0x387A20L, + 0x3850A9L, 0x38272AL, 0x37FDA3L, 0x37D414L, 0x37AA7CL, 0x3780DBL, 0x375731L, 0x372D7EL, + 0x3703C1L, 0x36D9FBL, 0x36B02BL, 0x368651L, 0x365C6DL, 0x36327FL, 0x360886L, 0x35DE82L, + 0x35B473L, 0x358A59L, 0x356033L, 0x353602L, 0x350BC5L, 0x34E17CL, 0x34B727L, 0x348CC5L, + 0x346256L, 0x3437DAL, 0x340D52L, 0x33E2BBL, 0x33B817L, 0x338D66L, 0x3362A6L, 0x3337D7L, + 0x330CFBL, 0x32E20FL, 0x32B714L, 0x328C0AL, 0x3260F0L, 0x3235C6L, 0x320A8CL, 0x31DF42L, + 0x31B3E7L, 0x31887CL, 0x315CFFL, 0x313170L, 0x3105D0L, 0x30DA1EL, 0x30AE5AL, 0x308283L, + 0x305699L, 0x302A9CL, 0x2FFE8BL, 0x2FD267L, 0x2FA62EL, 0x2F79E1L, 0x2F4D80L, 0x2F2109L, + 0x2EF47DL, 0x2EC7DBL, 0x2E9B24L, 0x2E6E56L, 0x2E4171L, 0x2E1475L, 0x2DE762L, 0x2DBA37L, + 0x2D8CF4L, 0x2D5F98L, 0x2D3223L, 0x2D0495L, 0x2CD6EEL, 0x2CA92CL, 0x2C7B50L, 0x2C4D59L, + 0x2C1F47L, 0x2BF119L, 0x2BC2CFL, 0x2B9468L, 0x2B65E5L, 0x2B3744L, 0x2B0885L, 0x2AD9A7L, + 0x2AAAABL, 0x2A7B8FL, 0x2A4C53L, 0x2A1CF7L, 0x29ED7BL, 0x29BDDCL, 0x298E1CL, 0x295E3AL, + 0x292E34L, 0x28FE0BL, 0x28CDBDL, 0x289D4BL, 0x286CB3L, 0x283BF6L, 0x280B12L, 0x27DA06L, + 0x27A8D3L, 0x277777L, 0x2745F2L, 0x271443L, 0x26E26AL, 0x26B065L, 0x267E34L, 0x264BD6L, + 0x26194AL, 0x25E690L, 0x25B3A7L, 0x25808EL, 0x254D44L, 0x2519C8L, 0x24E619L, 0x24B236L, + 0x247E1FL, 0x2449D3L, 0x241550L, 0x23E095L, 0x23ABA2L, 0x237675L, 0x23410EL, 0x230B6AL, + 0x22D58AL, 0x229F6BL, 0x22690DL, 0x22326EL, 0x21FB8DL, 0x21C468L, 0x218CFFL, 0x215550L, + 0x211D59L, 0x20E519L, 0x20AC8EL, 0x2073B7L, 0x203A92L, 0x20011DL, 0x1FC757L, 0x1F8D3DL, + 0x1F52CFL, 0x1F1809L, 0x1EDCEAL, 0x1EA170L, 0x1E6598L, 0x1E2961L, 0x1DECC7L, 0x1DAFC9L, + 0x1D7264L, 0x1D3496L, 0x1CF65BL, 0x1CB7B1L, 0x1C7895L, 0x1C3904L, 0x1BF8FAL, 0x1BB874L, + 0x1B7770L, 0x1B35E8L, 0x1AF3DAL, 0x1AB141L, 0x1A6E19L, 0x1A2A5EL, 0x19E60BL, 0x19A11BL, + 0x195B8AL, 0x191551L, 0x18CE6CL, 0x1886D4L, 0x183E83L, 0x17F573L, 0x17AB9BL, 0x1760F6L, + 0x17157BL, 0x16C921L, 0x167BE0L, 0x162DAFL, 0x15DE82L, 0x158E4FL, 0x153D0BL, 0x14EAA8L, + 0x14971AL, 0x144251L, 0x13EC3FL, 0x1394D1L, 0x133BF5L, 0x12E198L, 0x1285A2L, 0x1227FBL, + 0x11C889L, 0x11672FL, 0x1103CAL, 0x109E37L, 0x10364BL, 0xFCBDAL, 0xF5EAEL, 0xEEE8CL, + 0xE7B2DL, 0xE0444L, 0xD8971L, 0xD0A46L, 0xC863FL, 0xBFCBBL, 0xB6CF4L, 0xAD5F0L, + 0xA366FL, 0x98CC6L, 0x8D6ADL, 0x810DBL, 0x73642L, 0x63E62L, 0x518A6L, 0x39A39L, + 0x0L +}; + + + +/* fixatan: + * Fixed point inverse tangent. Does a binary search on the tan table. + */ +fixed fixatan(fixed x) { + int a, b, c; /* for binary search */ + fixed d; /* difference value for search */ + + if (x >= 0) { /* search the first part of tan table */ + a = 0; + b = 127; + } else { /* search the second half instead */ + a = 128; + b = 255; + } + + do { + c = (a + b) >> 1; + d = x - _tan_tbl[c]; + + if (d > 0) + a = c + 1; + else + if (d < 0) + b = c - 1; + + } while ((a <= b) && (d)); + + if (x >= 0) + return ((long)c) << 15; + + return (-0x00800000L + (((long)c) << 15)); +} + + + +/* fixatan2: + * Like the libc atan2, but for fixed point numbers. + */ +fixed fixatan2(fixed y, fixed x) { + fixed r; + + if (x == 0) { + if (y == 0) { + *allegro_errno = EDOM; + return 0L; + } else + return ((y < 0) ? -0x00400000L : 0x00400000L); + } + + *allegro_errno = 0; + r = fixdiv(y, x); + + if (*allegro_errno) { + *allegro_errno = 0; + return ((y < 0) ? -0x00400000L : 0x00400000L); + } + + r = fixatan(r); + + if (x >= 0) + return r; + + if (y >= 0) + return 0x00800000L + r; + + return r - 0x00800000L; +} + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/dumb-0.9.2/it.h b/engines/ags/lib/dumb-0.9.2/it.h new file mode 100644 index 000000000000..40678b95023b --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/it.h @@ -0,0 +1,716 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * internal/it.h - Internal stuff for IT playback / / \ \ + * and MOD/XM/S3M conversion. | < / \_ + * | \/ /\ / + * \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#ifndef INTERNAL_IT_H +#define INTERNAL_IT_H + +#include "common/scummsys.h" + +namespace AGS3 { + +/** TO DO: THINK ABOUT THE FOLLOWING: + +sigdata->flags & IT_COMPATIBLE_GXX + + Bit 5: On = Link Effect G's memory with Effect E/F. Also + Gxx with an instrument present will cause the + envelopes to be retriggered. If you change a + sample on a row with Gxx, it'll adjust the + frequency of the current note according to: + + NewFrequency = OldFrequency * NewC5 / OldC5; +*/ + + + +/* These #defines are TEMPORARY. They are used to write alternative code to + * handle ambiguities in the format specification. The correct code in each + * case will be determined most likely by experimentation. + */ +#define STEREO_SAMPLES_COUNT_AS_TWO +#define INVALID_ORDERS_END_SONG +#define INVALID_NOTES_CAUSE_NOTE_CUT +#define SUSTAIN_LOOP_OVERRIDES_NORMAL_LOOP +#define VOLUME_OUT_OF_RANGE_SETS_MAXIMUM + + + +#define SIGTYPE_IT DUMB_ID('I', 'T', ' ', ' ') + +#define IT_SIGNATURE DUMB_ID('I', 'M', 'P', 'M') +#define IT_INSTRUMENT_SIGNATURE DUMB_ID('I', 'M', 'P', 'I') +#define IT_SAMPLE_SIGNATURE DUMB_ID('I', 'M', 'P', 'S') + + + + /* 1 minute per 4 rows, each row 6 ticks; this is divided by the tempo to get + * the interval between ticks. + */ +#define TICK_TIME_DIVIDEND ((65536 * 60) / (4 * 6)) + + + + /* I'm not going to try to explain this, because I didn't derive it very + * formally ;) + */ + /* #define AMIGA_DIVISOR ((float)(4.0 * 14317056.0)) */ + /* I believe the following one to be more accurate. */ +#define AMIGA_DIVISOR ((float)(8.0 * 7159090.5)) + + + +typedef struct IT_MIDI IT_MIDI; +typedef struct IT_FILTER_STATE IT_FILTER_STATE; +typedef struct IT_ENVELOPE IT_ENVELOPE; +typedef struct IT_INSTRUMENT IT_INSTRUMENT; +typedef struct IT_SAMPLE IT_SAMPLE; +typedef struct IT_ENTRY IT_ENTRY; +typedef struct IT_PATTERN IT_PATTERN; +typedef struct IT_PLAYING_ENVELOPE IT_PLAYING_ENVELOPE; +typedef struct IT_PLAYING IT_PLAYING; +typedef struct IT_CHANNEL IT_CHANNEL; +typedef struct IT_CHECKPOINT IT_CHECKPOINT; +typedef struct IT_CALLBACKS IT_CALLBACKS; + + + +struct IT_MIDI { + unsigned char SFmacro[16][16]; // read these from 0x120 + unsigned char SFmacrolen[16]; + unsigned short SFmacroz[16]; /* Bitfield; bit 0 set = z in first position */ + unsigned char Zmacro[128][16]; // read these from 0x320 + unsigned char Zmacrolen[128]; +}; + + + +struct IT_FILTER_STATE { + float currsample, prevsample; +}; + + + +#define IT_ENVELOPE_ON 1 +#define IT_ENVELOPE_LOOP_ON 2 +#define IT_ENVELOPE_SUSTAIN_LOOP 4 +#define IT_ENVELOPE_PITCH_IS_FILTER 128 + +struct IT_ENVELOPE { + unsigned char flags; + unsigned char n_nodes; + unsigned char loop_start; + unsigned char loop_end; + unsigned char sus_loop_start; + unsigned char sus_loop_end; + signed char node_y[25]; + unsigned short node_t[25]; +}; + + + +#define NNA_NOTE_CUT 0 +#define NNA_NOTE_CONTINUE 1 +#define NNA_NOTE_OFF 2 +#define NNA_NOTE_FADE 3 + +#define DCT_OFF 0 +#define DCT_NOTE 1 +#define DCT_SAMPLE 2 +#define DCT_INSTRUMENT 3 + +#define DCA_NOTE_CUT 0 +#define DCA_NOTE_OFF 1 +#define DCA_NOTE_FADE 2 + +struct IT_INSTRUMENT { + int fadeout; + + IT_ENVELOPE volume_envelope; + IT_ENVELOPE pan_envelope; + IT_ENVELOPE pitch_envelope; + + unsigned char new_note_action; + unsigned char dup_check_type; + unsigned char dup_check_action; + unsigned char pp_separation; + unsigned char pp_centre; + unsigned char global_volume; + unsigned char default_pan; + unsigned char random_volume; + unsigned char random_pan; + + unsigned char filter_cutoff; + unsigned char filter_resonance; + + unsigned char map_note[120]; + unsigned short map_sample[120]; +}; + + + +#define IT_SAMPLE_EXISTS 1 +#define IT_SAMPLE_16BIT 2 +#define IT_SAMPLE_STEREO 4 +#define IT_SAMPLE_LOOP 16 +#define IT_SAMPLE_SUS_LOOP 32 +#define IT_SAMPLE_PINGPONG_LOOP 64 +#define IT_SAMPLE_PINGPONG_SUS_LOOP 128 + +#define IT_VIBRATO_SINE 0 +#define IT_VIBRATO_SAWTOOTH 1 /* Ramp down */ +#define IT_VIBRATO_SQUARE 2 +#define IT_VIBRATO_RANDOM 3 + +struct IT_SAMPLE { + unsigned char flags; + unsigned char global_volume; + unsigned char default_volume; + unsigned char default_pan; + + long length; + long loop_start; + long loop_end; + long C5_speed; + long sus_loop_start; + long sus_loop_end; + + unsigned char vibrato_speed; + unsigned char vibrato_depth; + unsigned char vibrato_rate; + unsigned char vibrato_waveform; + + sample_t *left; + sample_t *right; +}; + + + +#define IT_ENTRY_NOTE 1 +#define IT_ENTRY_INSTRUMENT 2 +#define IT_ENTRY_VOLPAN 4 +#define IT_ENTRY_EFFECT 8 + +#define IT_SET_END_ROW(entry) ((entry)->channel = 255) +#define IT_IS_END_ROW(entry) ((entry)->channel >= DUMB_IT_N_CHANNELS) + +#define IT_NOTE_OFF 255 +#define IT_NOTE_CUT 254 + +#define IT_ENVELOPE_SHIFT 8 + +#define IT_SURROUND 100 +#define IT_IS_SURROUND(pan) ((pan) > 64) +#define IT_IS_SURROUND_SHIFTED(pan) ((pan) > 64 << IT_ENVELOPE_SHIFT) + +#define IT_SET_SPEED 1 +#define IT_JUMP_TO_ORDER 2 +#define IT_BREAK_TO_ROW 3 +#define IT_VOLUME_SLIDE 4 +#define IT_PORTAMENTO_DOWN 5 +#define IT_PORTAMENTO_UP 6 +#define IT_TONE_PORTAMENTO 7 +#define IT_VIBRATO 8 +#define IT_TREMOR 9 +#define IT_ARPEGGIO 10 +#define IT_VOLSLIDE_VIBRATO 11 +#define IT_VOLSLIDE_TONEPORTA 12 +#define IT_SET_CHANNEL_VOLUME 13 +#define IT_CHANNEL_VOLUME_SLIDE 14 +#define IT_SET_SAMPLE_OFFSET 15 +#define IT_PANNING_SLIDE 16 +#define IT_RETRIGGER_NOTE 17 +#define IT_TREMOLO 18 +#define IT_S 19 +#define IT_SET_SONG_TEMPO 20 +#define IT_FINE_VIBRATO 21 +#define IT_SET_GLOBAL_VOLUME 22 +#define IT_GLOBAL_VOLUME_SLIDE 23 +#define IT_SET_PANNING 24 +#define IT_PANBRELLO 25 +#define IT_MIDI_MACRO 26 //see MIDI.TXT + +/* Some effects needed for XM compatibility */ +#define IT_XM_PORTAMENTO_DOWN 27 +#define IT_XM_PORTAMENTO_UP 28 +#define IT_XM_FINE_VOLSLIDE_DOWN 29 +#define IT_XM_FINE_VOLSLIDE_UP 30 +#define IT_XM_RETRIGGER_NOTE 31 + +#define IT_N_EFFECTS 32 + +/* These represent the top nibble of the command value. */ +#define IT_S_SET_FILTER 0 /* Greyed out in IT... */ +#define IT_S_SET_GLISSANDO_CONTROL 1 /* Greyed out in IT... */ +#define IT_S_FINETUNE 2 /* Greyed out in IT... */ +#define IT_S_SET_VIBRATO_WAVEFORM 3 +#define IT_S_SET_TREMOLO_WAVEFORM 4 +#define IT_S_SET_PANBRELLO_WAVEFORM 5 +#define IT_S_FINE_PATTERN_DELAY 6 +#define IT_S7 7 +#define IT_S_SET_PAN 8 +#define IT_S_SET_SURROUND_SOUND 9 +#define IT_S_SET_HIGH_OFFSET 10 +#define IT_S_PATTERN_LOOP 11 +#define IT_S_DELAYED_NOTE_CUT 12 +#define IT_S_NOTE_DELAY 13 +#define IT_S_PATTERN_DELAY 14 +#define IT_S_SET_MIDI_MACRO 15 + +/* +S0x Set filter +S1x Set glissando control +S2x Set finetune + + +S3x Set vibrato waveform to type x +S4x Set tremelo waveform to type x +S5x Set panbrello waveform to type x + Waveforms for commands S3x, S4x and S5x: + 0: Sine wave + 1: Ramp down + 2: Square wave + 3: Random wave +S6x Pattern delay for x ticks +S70 Past note cut +S71 Past note off +S72 Past note fade +S73 Set NNA to note cut +S74 Set NNA to continue +S75 Set NNA to note off +S76 Set NNA to note fade +S77 Turn off volume envelope +S78 Turn on volume envelope +S79 Turn off panning envelope +S7A Turn on panning envelope +S7B Turn off pitch envelope +S7C Turn on pitch envelope +S8x Set panning position +S91 Set surround sound +SAy Set high value of sample offset yxx00h +SB0 Set loopback point +SBx Loop x times to loopback point +SCx Note cut after x ticks +SDx Note delay for x ticks +SEx Pattern delay for x rows +SFx Set parameterised MIDI Macro +*/ + +struct IT_ENTRY { + unsigned char channel; /* End of row if channel >= DUMB_IT_N_CHANNELS */ + unsigned char mask; + unsigned char note; + unsigned char instrument; + unsigned char volpan; + unsigned char effect; + unsigned char effectvalue; +}; + + + +struct IT_PATTERN { + int n_rows; + int n_entries; + IT_ENTRY *entry; +}; + + + +#define IT_STEREO 1 +#define IT_USE_INSTRUMENTS 4 +#define IT_LINEAR_SLIDES 8 /* If not set, use Amiga slides */ +#define IT_OLD_EFFECTS 16 +#define IT_COMPATIBLE_GXX 32 + +/* Make sure IT_WAS_AN_XM and IT_WAS_A_MOD aren't set accidentally */ +#define IT_REAL_FLAGS 63 + +#define IT_WAS_AN_XM 64 /* Set for both XMs and MODs */ +#define IT_WAS_A_MOD 128 + +#define IT_ORDER_END 255 +#define IT_ORDER_SKIP 254 + +struct DUMB_IT_SIGDATA { + int n_orders; + int n_instruments; + int n_samples; + int n_patterns; + + int flags; + + int global_volume; + int mixing_volume; + int speed; + int tempo; + int pan_separation; + + unsigned char channel_pan[DUMB_IT_N_CHANNELS]; + unsigned char channel_volume[DUMB_IT_N_CHANNELS]; + + unsigned char *order; + unsigned char restart_position; /* for XM compatiblity */ + + IT_INSTRUMENT *instrument; + IT_SAMPLE *sample; + IT_PATTERN *pattern; + + IT_MIDI *midi; + + IT_CHECKPOINT *checkpoint; +}; + + + +struct IT_PLAYING_ENVELOPE { + int next_node; + int tick; +}; + + + +#define IT_PLAYING_BACKGROUND 1 +#define IT_PLAYING_SUSTAINOFF 2 +#define IT_PLAYING_FADING 4 +#define IT_PLAYING_DEAD 8 + +struct IT_PLAYING { + int flags; + + IT_CHANNEL *channel; + IT_SAMPLE *sample; + IT_INSTRUMENT *instrument; + IT_INSTRUMENT *env_instrument; + + unsigned short sampnum; + unsigned char instnum; + + unsigned char channel_volume; + + unsigned char volume; + unsigned short pan; + + unsigned char note; + + unsigned char filter_cutoff; + unsigned char filter_resonance; + + unsigned short true_filter_cutoff; /* These incorporate the filter envelope, and will not */ + unsigned char true_filter_resonance; /* be changed if they would be set to 127<<8 and 0. */ + + unsigned char vibrato_speed; + unsigned char vibrato_depth; + unsigned char vibrato_n; /* May be specified twice: volpan & effect. */ + unsigned char vibrato_time; + + unsigned char tremolo_speed; + unsigned char tremolo_depth; + unsigned char tremolo_time; + + unsigned char sample_vibrato_time; + int sample_vibrato_depth; /* Starts at rate?0:depth, increases by rate */ + + int slide; + float delta; + + IT_PLAYING_ENVELOPE volume_envelope; + IT_PLAYING_ENVELOPE pan_envelope; + IT_PLAYING_ENVELOPE pitch_envelope; + + int fadeoutcount; + + IT_FILTER_STATE filter_state[2]; /* Left and right */ + + DUMB_RESAMPLER resampler[2]; + + /* time_lost is used to emulate Impulse Tracker's sample looping + * characteristics. When time_lost is added to pos, the result represents + * the position in the theoretical version of the sample where all loops + * have been expanded. If this is stored, the resampling helpers will + * safely convert it for use with new loop boundaries. The situation is + * slightly more complicated if dir == -1 when the change takes place; we + * must reflect pos off the loop end point and set dir to 1 before + * proceeding. + */ + long time_lost; +}; + + + +#define IT_CHANNEL_MUTED 1 + +struct IT_CHANNEL { + int flags; + + unsigned char volume; + signed char volslide; + signed char xm_volslide; + + /* xm_volslide is used for volume slides done in the volume column in an + * XM file, since it seems the volume column slide is applied first, + * followed by clamping, followed by the effects column slide. IT does + * not exhibit this behaviour, so xm_volslide is maintained at zero. + */ + + unsigned char pan; + unsigned short truepan; + + unsigned char channelvolume; + signed char channelvolslide; + + unsigned char instrument; + unsigned char note; + + unsigned char SFmacro; + + unsigned char filter_cutoff; + unsigned char filter_resonance; + + unsigned char note_cut_count; + unsigned char note_delay_count; + IT_ENTRY *note_delay_entry; + + int arpeggio; + unsigned char retrig; + unsigned char xm_retrig; + int retrig_tick; + + unsigned char tremor; + unsigned char tremor_time; /* Bit 6 set if note on; bit 7 set if tremor active. */ + + int portamento; + int toneporta; + unsigned char destnote; + + /** WARNING - for neatness, should one or both of these be in the IT_PLAYING struct? */ + unsigned short sample; + unsigned char truenote; + + unsigned char midi_state; + + signed char lastvolslide; + unsigned char lastDKL; + unsigned char lastEF; /* Doubles as last portamento up for XM files */ + unsigned char lastG; + unsigned char lastHspeed; + unsigned char lastHdepth; + unsigned char lastRspeed; + unsigned char lastRdepth; + unsigned char lastI; + unsigned char lastJ; /* Doubles as last portamento down for XM files */ + unsigned char lastN; + unsigned char lastO; + unsigned char high_offset; + unsigned char lastQ; + unsigned char lastS; + unsigned char pat_loop_row; + unsigned char pat_loop_count; + unsigned char lastW; + + unsigned char xm_lastE1; + unsigned char xm_lastE2; + unsigned char xm_lastEA; + unsigned char xm_lastEB; + unsigned char xm_lastX1; + unsigned char xm_lastX2; + + IT_PLAYING *playing; +}; + + + +struct DUMB_IT_SIGRENDERER { + DUMB_IT_SIGDATA *sigdata; + + int n_channels; + + unsigned char globalvolume; + signed char globalvolslide; + + unsigned char tempo; + signed char temposlide; + + IT_CHANNEL channel[DUMB_IT_N_CHANNELS]; + + IT_PLAYING *playing[DUMB_IT_N_NNA_CHANNELS]; + + int tick; + int speed; + int rowcount; + + int order; /* Set to -1 if the song is terminated by a callback. */ + int row; + int processorder; + int processrow; + int breakrow; + int pat_loop_row; + + int n_rows; + + IT_ENTRY *entry_start; + IT_ENTRY *entry; + IT_ENTRY *entry_end; + + long time_left; /* Time before the next tick is processed */ + int sub_time_left; + + DUMB_CLICK_REMOVER **click_remover; + + IT_CALLBACKS *callbacks; +}; + + + +struct IT_CHECKPOINT { + IT_CHECKPOINT *next; + long time; + DUMB_IT_SIGRENDERER *sigrenderer; +}; + + + +struct IT_CALLBACKS { + int (*loop)(void *data); + void *loop_data; + /* Return 1 to prevent looping; the music will terminate abruptly. If you + * want to make the music stop but allow samples to fade (beware, as they + * might not fade at all!), use dumb_it_sr_set_speed() and set the speed + * to 0. Note that xm_speed_zero() will not be called if you set the + * speed manually, and also that this will work for IT and S3M files even + * though the music can't stop in this way by itself. + */ + + int (*xm_speed_zero)(void *data); + void *xm_speed_zero_data; + /* Return 1 to terminate the mod, without letting samples fade. */ + + int (*midi)(void *data, int channel, unsigned char byte); + void *midi_data; + /* Return 1 to prevent DUMB from subsequently interpreting the MIDI bytes + * itself. In other words, return 1 if the Zxx macros in an IT file are + * controlling filters and shouldn't be. + */ +}; + + + +void _dumb_it_end_sigrenderer(sigrenderer_t *sigrenderer); +void _dumb_it_unload_sigdata(sigdata_t *vsigdata); + +extern DUH_SIGTYPE_DESC _dumb_sigtype_it; + + + +long _dumb_it_build_checkpoints(DUMB_IT_SIGDATA *sigdata); + + + +#define XM_APPREGIO 0 +#define XM_PORTAMENTO_UP 1 +#define XM_PORTAMENTO_DOWN 2 +#define XM_TONE_PORTAMENTO 3 +#define XM_VIBRATO 4 +#define XM_VOLSLIDE_TONEPORTA 5 +#define XM_VOLSLIDE_VIBRATO 6 +#define XM_TREMOLO 7 +#define XM_SET_PANNING 8 +#define XM_SAMPLE_OFFSET 9 +#define XM_VOLUME_SLIDE 10 /* A */ +#define XM_POSITION_JUMP 11 /* B */ +#define XM_SET_CHANNEL_VOLUME 12 /* C */ +#define XM_PATTERN_BREAK 13 /* D */ +#define XM_E 14 /* E */ +#define XM_SET_TEMPO_BPM 15 /* F */ +#define XM_SET_GLOBAL_VOLUME 16 /* G */ +#define XM_GLOBAL_VOLUME_SLIDE 17 /* H */ +#define XM_KEY_OFF 20 /* K (undocumented) */ +#define XM_SET_ENVELOPE_POSITION 21 /* L */ +#define XM_PANNING_SLIDE 25 /* P */ +#define XM_MULTI_RETRIG 27 /* R */ +#define XM_TREMOR 29 /* T */ +#define XM_X 33 /* X */ +#define XM_N_EFFECTS (10+26) + +#define XM_E_SET_FILTER 0x0 +#define XM_E_FINE_PORTA_UP 0x1 +#define XM_E_FINE_PORTA_DOWN 0x2 +#define XM_E_SET_GLISSANDO_CONTROL 0x3 +#define XM_E_SET_VIBRATO_CONTROL 0x4 +#define XM_E_SET_FINETUNE 0x5 +#define XM_E_SET_LOOP 0x6 +#define XM_E_SET_TREMOLO_CONTROL 0x7 +#define XM_E_RETRIG_NOTE 0x9 +#define XM_E_FINE_VOLSLIDE_UP 0xA +#define XM_E_FINE_VOLSLIDE_DOWN 0xB +#define XM_E_NOTE_CUT 0xC +#define XM_E_NOTE_DELAY 0xD +#define XM_E_PATTERN_DELAY 0xE + +#define XM_X_EXTRAFINE_PORTA_UP 1 +#define XM_X_EXTRAFINE_PORTA_DOWN 2 + +/* To make my life a bit simpler during conversion, effect E:xy is converted + * to effect number EBASE+x:y. The same applies to effect X, and IT's S. That + * way, these effects can be manipulated like regular effects. + */ +#define EBASE (XM_N_EFFECTS) +#define XBASE (EBASE+16) +#define SBASE (IT_N_EFFECTS) + +#define EFFECT_VALUE(x, y) (((x)<<4)|(y)) +#define HIGH(v) ((v)>>4) +#define LOW(v) ((v)&0x0F) +#define SET_HIGH(v, x) v = (((x)<<4)|((v)&0x0F)) +#define SET_LOW(v, y) v = (((v)&0xF0)|(y)) +#define BCD_TO_NORMAL(v) (HIGH(v)*10+LOW(v)) + + + +#if 0 +unsigned char **_dumb_malloc2(int w, int h); +void _dumb_free2(unsigned char **line); +#endif + +void _dumb_it_xm_convert_effect(int effect, int value, IT_ENTRY *entry); +int _dumb_it_fix_invalid_orders(DUMB_IT_SIGDATA *sigdata); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/dumb-0.9.2/readxm.cpp b/engines/ags/lib/dumb-0.9.2/readxm.cpp new file mode 100644 index 000000000000..775620e8c574 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/readxm.cpp @@ -0,0 +1,1007 @@ +/* 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. + * + */ + + /* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * readxm.c - Code to read a Fast Tracker II / / \ \ + * module from an open file. | < / \_ + * | \/ /\ / + * By Julien Cugniere. Some bits of code taken \_ / > / + * from reads3m.c. | \ / / + * | ' / + * \__/ + */ + +#include "ags/lib/dumb-0.9.2/dumb.h" +#include "ags/lib/dumb-0.9.2/it.h" + +namespace AGS3 { + +/** TODO: + + * XM_TREMOLO doesn't sound quite right... + * XM_E_SET_FINETUNE todo. + * XM_SET_ENVELOPE_POSITION todo. + + * VIBRATO conversion needs to be checked (sample/effect/volume). Plus check + that effect memory is correct when using XM_VOLSLIDE_VIBRATO. + - sample vibrato (instrument vibrato) is now handled correctly. - entheh + + * XM_E_SET_VIBRATO/TREMOLO_CONTROL: effectvalue&4 -> don't retrig wave when + a new instrument is played. In retrigger_note()?. Is it worth implementing? + + * Lossy fadeout approximation. 0..31 converted to 0 --> won't fade at all. + + * Replace DUMB's sawtooth by ramp_down/ramp_up. Update XM loader. + + * A lot of things need to be reset when the end of the song is reached. + + * It seems that IT and XM don't behave the same way when dealing with + mixed loops. When IT encounters multiple SBx (x>0) commands on the same + row, it decrements the loop count for all, but only execute the loop of + the last one (highest channel). FT2 only decrements the loop count of the + last one. Not that I know of any modules using so convoluted combinations! + + * Maybe we could remove patterns that don't appear in the order table ? Or + provide a function to "optimize" a DUMB_IT_SIGDATA ? + +*/ + + + +#define XM_LINEAR_FREQUENCY 1 /* otherwise, use amiga slides */ + +#define XM_ENTRY_PACKED 128 +#define XM_ENTRY_NOTE 1 +#define XM_ENTRY_INSTRUMENT 2 +#define XM_ENTRY_VOLUME 4 +#define XM_ENTRY_EFFECT 8 +#define XM_ENTRY_EFFECTVALUE 16 + +#define XM_NOTE_OFF 97 + +#define XM_ENVELOPE_ON 1 +#define XM_ENVELOPE_SUSTAIN 2 +#define XM_ENVELOPE_LOOP 4 + +#define XM_SAMPLE_NO_LOOP 0 +#define XM_SAMPLE_FORWARD_LOOP 1 +#define XM_SAMPLE_PINGPONG_LOOP 2 +#define XM_SAMPLE_16BIT 16 +#define XM_SAMPLE_STEREO 32 + +#define XM_VIBRATO_SINE 0 +#define XM_VIBRATO_SQUARE 1 +#define XM_VIBRATO_RAMP_DOWN 2 +#define XM_VIBRATO_RAMP_UP 3 + + + +/* Probably useless :) */ +static const char xm_convert_vibrato[] = { + IT_VIBRATO_SINE, + IT_VIBRATO_SQUARE, + IT_VIBRATO_SAWTOOTH, + IT_VIBRATO_SAWTOOTH +}; + + + +#define XM_MAX_SAMPLES_PER_INSTRUMENT 16 + + + +/* Extra data that doesn't fit inside IT_INSTRUMENT */ +typedef struct XM_INSTRUMENT_EXTRA { + int n_samples; + int vibrato_type; + int vibrato_sweep; /* 0-0xFF */ + int vibrato_depth; /* 0-0x0F */ + int vibrato_speed; /* 0-0x3F */ +} +XM_INSTRUMENT_EXTRA; + + + +/* Frees the original block if it can't resize it or if size is 0, and acts + * as malloc if ptr is NULL. + */ +static void *safe_realloc(void *ptr, size_t size) { + if (ptr == NULL) + return malloc(size); + + if (size == 0) { + free(ptr); + return NULL; + } else { + void *new_block = realloc(ptr, size); + if (!new_block) + free(ptr); + return new_block; + } +} + + + +/* The interpretation of the XM volume column is left to the player. Here, we + * just filter bad values. + */ + // This function is so tiny now, should we inline it? +static void it_xm_convert_volume(int volume, IT_ENTRY *entry) { + entry->mask |= IT_ENTRY_VOLPAN; + entry->volpan = volume; + + switch (volume >> 4) { + case 0xA: /* set vibrato speed */ + case 0xB: /* vibrato */ + case 0xF: /* tone porta */ + case 0x6: /* vol slide up */ + case 0x7: /* vol slide down */ + case 0x8: /* fine vol slide up */ + case 0x9: /* fine vol slide down */ + case 0xC: /* set panning */ + case 0xD: /* pan slide left */ + case 0xE: /* pan slide right */ + case 0x1: /* set volume */ + case 0x2: /* set volume */ + case 0x3: /* set volume */ + case 0x4: /* set volume */ + break; + + case 0x5: + if (volume == 0x50) + break; /* set volume */ + /* else fall through */ + + default: + entry->mask &= ~IT_ENTRY_VOLPAN; + break; + } +} + + + +static int it_xm_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, int n_channels, unsigned char *buffer) { + int size; + int pos; + int channel; + int row; + int effect, effectvalue; + IT_ENTRY *entry; + + /* pattern header size */ + if (dumbfile_igetl(f) != 0x09) { + TRACE("XM error: unexpected pattern header size\n"); + return -1; + } + + /* pattern data packing type */ + if (dumbfile_getc(f) != 0) { + TRACE("XM error: unexpected pattern packing type\n"); + return -1; + } + + pattern->n_rows = dumbfile_igetw(f); /* 1..256 */ + size = dumbfile_igetw(f); + pattern->n_entries = 0; + + if (dumbfile_error(f)) + return -1; + + if (size == 0) + return 0; + + if (size > 1280 * n_channels) { + TRACE("XM error: pattern data size > %d bytes\n", 1280 * n_channels); + return -1; + } + + if (dumbfile_getnc(buffer, size, f) < size) + return -1; + + /* compute number of entries */ + pattern->n_entries = 0; + pos = channel = row = 0; + while (pos < size) { + if (!(buffer[pos] & XM_ENTRY_PACKED) || (buffer[pos] & 31)) + pattern->n_entries++; + + channel++; + if (channel >= n_channels) { + channel = 0; + row++; + pattern->n_entries++; + } + + if (buffer[pos] & XM_ENTRY_PACKED) { + static const char offset[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5 }; + pos += 1 + offset[buffer[pos] & 31]; + } else { + pos += 5; + } + } + + if (row != pattern->n_rows) { + TRACE("XM error: wrong number of rows in pattern data\n"); + return -1; + } + + pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry)); + if (!pattern->entry) + return -1; + + /* read the entries */ + entry = pattern->entry; + pos = channel = row = 0; + while (pos < size) { + unsigned char mask; + + if (buffer[pos] & XM_ENTRY_PACKED) + mask = buffer[pos++] & 31; + else + mask = 31; + + if (mask) { + ASSERT(entry < pattern->entry + pattern->n_entries); + + entry->channel = channel; + entry->mask = 0; + + if (mask & XM_ENTRY_NOTE) { + int note = buffer[pos++]; /* 1-96 <=> C0-B7 */ + entry->note = (note == XM_NOTE_OFF) ? (IT_NOTE_OFF) : (note - 1); + entry->mask |= IT_ENTRY_NOTE; + } + + if (mask & XM_ENTRY_INSTRUMENT) { + entry->instrument = buffer[pos++]; /* 1-128 */ + entry->mask |= IT_ENTRY_INSTRUMENT; + } + + if (mask & XM_ENTRY_VOLUME) + it_xm_convert_volume(buffer[pos++], entry); + + effect = effectvalue = 0; + if (mask & XM_ENTRY_EFFECT) effect = buffer[pos++]; + if (mask & XM_ENTRY_EFFECTVALUE) effectvalue = buffer[pos++]; + _dumb_it_xm_convert_effect(effect, effectvalue, entry); + + entry++; + } + + channel++; + if (channel >= n_channels) { + channel = 0; + row++; + IT_SET_END_ROW(entry); + entry++; + } + } + + return 0; +} + + + +static int it_xm_make_envelope(IT_ENVELOPE *envelope, const unsigned short *data, int y_offset) { + int i, pos; + + if (envelope->n_nodes > 12) { + TRACE("XM error: wrong number of envelope nodes (%d)\n", envelope->n_nodes); + envelope->n_nodes = 0; + return -1; + } + + pos = 0; + for (i = 0; i < envelope->n_nodes; i++) { + envelope->node_t[i] = data[pos++]; + if (data[pos] > 64) { + TRACE("XM error: out-of-range envelope node (node_y[%d]=%d)\n", i, data[pos]); + envelope->n_nodes = 0; + return -1; + } + envelope->node_y[i] = (signed char)(data[pos++] + y_offset); + } + + return 0; +} + + + +static int it_xm_read_instrument(IT_INSTRUMENT *instrument, XM_INSTRUMENT_EXTRA *extra, DUMBFILE *f) { + unsigned long size, bytes_read; + unsigned short vol_points[24]; + unsigned short pan_points[24]; + int i, type; + + /* Header size. Tends to be more than the actual size of the structure. + * So unread bytes must be skipped before reading the first sample + * header. + */ + size = dumbfile_igetl(f); + + //memset(instrument, 0, sizeof(*instrument)); + dumbfile_skip(f, 22); /* Instrument name */ + dumbfile_skip(f, 1); /* Instrument type. Should be 0, but seems random. */ + extra->n_samples = dumbfile_igetw(f); + + if (dumbfile_error(f) || (unsigned int)extra->n_samples > XM_MAX_SAMPLES_PER_INSTRUMENT) + return -1; + + bytes_read = 4 + 22 + 1 + 2; + + if (extra->n_samples) { + /* sample header size */ + if (dumbfile_igetl(f) != 0x28) { + TRACE("XM error: unexpected sample header size\n"); + return -1; + } + + /* sample map */ + for (i = 0; i < 96; i++) { + instrument->map_sample[i] = dumbfile_getc(f) + 1; + instrument->map_note[i] = i; + } + + if (dumbfile_error(f)) + return 1; + + /* volume/panning envelopes */ + for (i = 0; i < 24; i++) + vol_points[i] = dumbfile_igetw(f); + for (i = 0; i < 24; i++) + pan_points[i] = dumbfile_igetw(f); + + instrument->volume_envelope.n_nodes = dumbfile_getc(f); + instrument->pan_envelope.n_nodes = dumbfile_getc(f); + + if (dumbfile_error(f)) + return -1; + + instrument->volume_envelope.sus_loop_start = dumbfile_getc(f); + instrument->volume_envelope.loop_start = dumbfile_getc(f); + instrument->volume_envelope.loop_end = dumbfile_getc(f); + + instrument->pan_envelope.sus_loop_start = dumbfile_getc(f); + instrument->pan_envelope.loop_start = dumbfile_getc(f); + instrument->pan_envelope.loop_end = dumbfile_getc(f); + + /* The envelope handler for XM files won't use sus_loop_end. */ + + type = dumbfile_getc(f); + instrument->volume_envelope.flags = 0; + if ((type & XM_ENVELOPE_ON) && instrument->volume_envelope.n_nodes) + instrument->volume_envelope.flags |= IT_ENVELOPE_ON; + if (type & XM_ENVELOPE_LOOP) instrument->volume_envelope.flags |= IT_ENVELOPE_LOOP_ON; +#if 1 + if (type & XM_ENVELOPE_SUSTAIN) instrument->volume_envelope.flags |= IT_ENVELOPE_SUSTAIN_LOOP; +#else // This is now handled in itrender.c + /* let's avoid fading out when reaching the last envelope node */ + if (!(type & XM_ENVELOPE_LOOP)) { + instrument->volume_envelope.loop_start = instrument->volume_envelope.n_nodes - 1; + instrument->volume_envelope.loop_end = instrument->volume_envelope.n_nodes - 1; + } + instrument->volume_envelope.flags |= IT_ENVELOPE_LOOP_ON; +#endif + + type = dumbfile_getc(f); + instrument->pan_envelope.flags = 0; + if ((type & XM_ENVELOPE_ON) && instrument->pan_envelope.n_nodes) + instrument->pan_envelope.flags |= IT_ENVELOPE_ON; + if (type & XM_ENVELOPE_LOOP) instrument->pan_envelope.flags |= IT_ENVELOPE_LOOP_ON; // should this be here? + if (type & XM_ENVELOPE_SUSTAIN) instrument->pan_envelope.flags |= IT_ENVELOPE_SUSTAIN_LOOP; + + if (it_xm_make_envelope(&instrument->volume_envelope, vol_points, 0) != 0) { + TRACE("XM error: volume envelope\n"); + if (instrument->volume_envelope.flags & IT_ENVELOPE_ON) return -1; + } + + if (it_xm_make_envelope(&instrument->pan_envelope, pan_points, -32) != 0) { + TRACE("XM error: pan envelope\n"); + if (instrument->pan_envelope.flags & IT_ENVELOPE_ON) return -1; + } + + instrument->pitch_envelope.flags = 0; + + extra->vibrato_type = dumbfile_getc(f); + extra->vibrato_sweep = dumbfile_getc(f); + extra->vibrato_depth = dumbfile_getc(f); + extra->vibrato_speed = dumbfile_getc(f); + + if (dumbfile_error(f) || extra->vibrato_type >= 4) + return -1; + + /** WARNING: lossy approximation */ + instrument->fadeout = (dumbfile_igetw(f) * 128 + 64) / 0xFFF; + + dumbfile_skip(f, 2); /* reserved */ + + bytes_read += 4 + 96 + 48 + 48 + 14 * 1 + 2 + 2; + } + + if (dumbfile_skip(f, size - bytes_read)) + return -1; + + instrument->new_note_action = NNA_NOTE_CUT; + instrument->dup_check_type = DCT_OFF; + instrument->dup_check_action = DCA_NOTE_CUT; + instrument->pp_separation = 0; + instrument->pp_centre = 60; /* C-5 */ + instrument->global_volume = 128; + instrument->default_pan = 32; + instrument->random_volume = 0; + instrument->random_pan = 0; + instrument->filter_cutoff = 0; + instrument->filter_resonance = 0; + + return 0; +} + + + +/* I (entheh) have two XM files saved by a very naughty program. After a + * 16-bit sample, it saved a rogue byte. The length of the sample was indeed + * an odd number, incremented to include the rogue byte. + * + * In this function we are converting sample lengths and loop points so they + * are measured in samples. This means we forget about the extra bytes, and + * they don't get skipped. So we fail trying to read the next instrument. + * + * To get around this, this function returns the number of rogue bytes that + * won't be accounted for by reading sample->length samples. It returns a + * negative number on failure. + */ +static int it_xm_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f) { + int type; + int relative_note_number; /* relative to C4 */ + int finetune; + int roguebytes; + int roguebytesmask; + + sample->length = dumbfile_igetl(f); + sample->loop_start = dumbfile_igetl(f); + sample->loop_end = sample->loop_start + dumbfile_igetl(f); + sample->global_volume = 64; + sample->default_volume = dumbfile_getc(f); + finetune = (signed char)dumbfile_getc(f); /* -128..127 <=> -1 semitone .. +127/128 of a semitone */ + type = dumbfile_getc(f); + sample->default_pan = (dumbfile_getc(f) * 64) / 255 | 128; /* 0-255 */ + relative_note_number = (signed char)dumbfile_getc(f); + + dumbfile_skip(f, 1); /* reserved */ + dumbfile_skip(f, 22); /* sample name */ + + if (dumbfile_error(f)) + return -1; + + sample->C5_speed = (long)(16726.0 * pow(DUMB_SEMITONE_BASE, relative_note_number) * pow(DUMB_PITCH_BASE, finetune * 2)); + + sample->flags = IT_SAMPLE_EXISTS; + + roguebytes = (int)sample->length; + roguebytesmask = 3; + + if (type & XM_SAMPLE_16BIT) { + sample->flags |= IT_SAMPLE_16BIT; + sample->length >>= 1; + sample->loop_start >>= 1; + sample->loop_end >>= 1; + } else + roguebytesmask >>= 1; + + if (type & XM_SAMPLE_STEREO) { + sample->flags |= IT_SAMPLE_STEREO; + sample->length >>= 1; + sample->loop_start >>= 1; + sample->loop_end >>= 1; + } else + roguebytesmask >>= 1; + + roguebytes &= roguebytesmask; + + if ((unsigned int)sample->loop_start < (unsigned int)sample->loop_end) { + if (type & XM_SAMPLE_FORWARD_LOOP) sample->flags |= IT_SAMPLE_LOOP; + if (type & XM_SAMPLE_PINGPONG_LOOP) sample->flags |= IT_SAMPLE_LOOP | IT_SAMPLE_PINGPONG_LOOP; + } + + if (sample->length <= 0) + sample->flags &= ~IT_SAMPLE_EXISTS; + else if ((unsigned int)sample->loop_end > (unsigned int)sample->length) + sample->flags &= ~IT_SAMPLE_LOOP; + else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end) + sample->flags &= ~IT_SAMPLE_LOOP; + + return roguebytes; +} + + + +static int it_xm_read_sample_data(IT_SAMPLE *sample, unsigned char roguebytes, DUMBFILE *f) { + int old; + long i; + long truncated_size; + + if (!(sample->flags & IT_SAMPLE_EXISTS)) + return dumbfile_skip(f, roguebytes); + + /* let's get rid of the sample data coming after the end of the loop */ + if ((sample->flags & IT_SAMPLE_LOOP) && sample->loop_end < sample->length) { + truncated_size = sample->length - sample->loop_end; + sample->length = sample->loop_end; + } else { + truncated_size = 0; + } + + sample->left = malloc(sample->length * sizeof(*sample->left)); + if (!sample->left) + return -1; + + if (sample->flags & IT_SAMPLE_STEREO) { + sample->right = malloc(sample->length * sizeof(*sample->right)); + if (!sample->right) + return -1; + } + + /* sample data is stored as signed delta values */ + old = 0; + if (sample->flags & IT_SAMPLE_16BIT) { + for (i = 0; i < sample->length; i++) { + old = sample->left[i] = (int)(signed short)(old + dumbfile_igetw(f)); + sample->left[i] <<= 8; + } + } else { + for (i = 0; i < sample->length; i++) { + old = sample->left[i] = (int)(signed char)(old + dumbfile_getc(f)); + sample->left[i] <<= 16; + } + } + + /* skip truncated data */ + dumbfile_skip(f, (sample->flags & IT_SAMPLE_16BIT) ? (2 * truncated_size) : (truncated_size)); + + if (sample->flags & IT_SAMPLE_STEREO) { + old = 0; + if (sample->flags & IT_SAMPLE_16BIT) { + for (i = 0; i < sample->length; i++) { + old = sample->right[i] = (int)(signed short)(old + dumbfile_igetw(f)); + sample->right[i] <<= 8; + } + } else { + for (i = 0; i < sample->length; i++) { + old = sample->right[i] = (int)(signed char)(old + dumbfile_getc(f)); + sample->right[i] <<= 16; + } + } + /* skip truncated data */ + dumbfile_skip(f, (sample->flags & IT_SAMPLE_16BIT) ? (2 * truncated_size) : (truncated_size)); + } + + dumbfile_skip(f, roguebytes); + + if (dumbfile_error(f)) + return -1; + + return 0; +} + + + +/* "Real programmers don't document. If it was hard to write, + * it should be hard to understand." + * + * (Never trust the documentation provided with a tracker. + * Real files are the only truth...) + */ +static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f) { + DUMB_IT_SIGDATA *sigdata; + char id_text[18]; + + int flags; + int n_channels; + int total_samples; + int i, j; + + /* check ID text */ + if (dumbfile_getnc(id_text, 17, f) < 17) + return NULL; + id_text[17] = 0; + if (strcmp(id_text, "Extended Module: ") != 0) { + TRACE("XM error: Not an Extended Module\n"); + return NULL; + } + + /* song name */ + if (dumbfile_skip(f, 20)) + return NULL; + + if (dumbfile_getc(f) != 0x1A) { + TRACE("XM error: 0x1A not found\n"); + return NULL; + } + + /* tracker name */ + if (dumbfile_skip(f, 20)) + return NULL; + + /* version number */ + if (dumbfile_igetw(f) != 0x0104) { + TRACE("XM error: wrong format version\n"); + return NULL; + } + + /* + ------------------ + --- Header --- + ------------------ + */ + + /* header size */ + if (dumbfile_igetl(f) != 0x0114) { + TRACE("XM error: unexpected header size\n"); + return NULL; + } + + sigdata = malloc(sizeof(*sigdata)); + if (!sigdata) + return NULL; + + sigdata->order = NULL; + sigdata->instrument = NULL; + sigdata->sample = NULL; + sigdata->pattern = NULL; + sigdata->midi = NULL; + sigdata->checkpoint = NULL; + + sigdata->n_samples = 0; + sigdata->n_orders = dumbfile_igetw(f); + sigdata->restart_position = dumbfile_igetw(f); + n_channels = dumbfile_igetw(f); /* max 32 but we'll be lenient */ + sigdata->n_patterns = dumbfile_igetw(f); + sigdata->n_instruments = dumbfile_igetw(f); /* max 128 */ + flags = dumbfile_igetw(f); + sigdata->speed = dumbfile_igetw(f); + sigdata->tempo = dumbfile_igetw(f); + + /* sanity checks */ + if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_orders > 256 || sigdata->n_patterns > 256 || sigdata->n_instruments > 128 || n_channels > DUMB_IT_N_CHANNELS) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + + //if (sigdata->restart_position >= sigdata->n_orders) + //sigdata->restart_position = 0; + + /* order table */ + sigdata->order = malloc(sigdata->n_orders * sizeof(*sigdata->order)); + if (!sigdata->order) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + dumbfile_getnc(sigdata->order, sigdata->n_orders, f); + dumbfile_skip(f, 256 - sigdata->n_orders); + + if (dumbfile_error(f)) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + + /* + -------------------- + --- Patterns --- + -------------------- + */ + + sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern)); + if (!sigdata->pattern) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + for (i = 0; i < sigdata->n_patterns; i++) + sigdata->pattern[i].entry = NULL; + + { + unsigned char *buffer = malloc(1280 * n_channels); /* 256 rows * 5 bytes */ + if (!buffer) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + for (i = 0; i < sigdata->n_patterns; i++) { + if (it_xm_read_pattern(&sigdata->pattern[i], f, n_channels, buffer) != 0) { + free(buffer); + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + } + free(buffer); + } + + /* + ----------------------------------- + --- Instruments and Samples --- + ----------------------------------- + */ + + sigdata->instrument = malloc(sigdata->n_instruments * sizeof(*sigdata->instrument)); + if (!sigdata->instrument) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + + /* With XM, samples are not global, they're part of an instrument. In a + * file, each instrument is stored with its samples. Because of this, I + * don't know how to find how many samples are present in the file. Thus + * I have to do n_instruments reallocation on sigdata->sample. + * Looking at FT2, it doesn't seem possible to have more than 16 samples + * per instrument (even though n_samples is stored as 2 bytes). So maybe + * we could allocate a 128*16 array of samples, and shrink it back to the + * correct size when we know it? + * Alternatively, I could allocate samples by blocks of N (still O(n)), + * or double the number of allocated samples when I need more (O(log n)). + */ + total_samples = 0; + sigdata->sample = NULL; + + for (i = 0; i < sigdata->n_instruments; i++) { + XM_INSTRUMENT_EXTRA extra; + + if (it_xm_read_instrument(&sigdata->instrument[i], &extra, f) < 0) { + TRACE("XM error: instrument %d\n", i + 1); + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + + if (extra.n_samples) { + unsigned char roguebytes[XM_MAX_SAMPLES_PER_INSTRUMENT]; + + /* adjust instrument sample map (make indices absolute) */ + for (j = 0; j < 96; j++) + sigdata->instrument[i].map_sample[j] += total_samples; + + sigdata->sample = safe_realloc(sigdata->sample, sizeof(*sigdata->sample) * (total_samples + extra.n_samples)); + if (!sigdata->sample) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + for (j = total_samples; j < total_samples + extra.n_samples; j++) + sigdata->sample[j].right = sigdata->sample[j].left = NULL; + + /* read instrument's samples */ + for (j = 0; j < extra.n_samples; j++) { + IT_SAMPLE *sample = &sigdata->sample[total_samples + j]; + int b = it_xm_read_sample_header(sample, f); + if (b < 0) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + roguebytes[j] = b; + // Any reason why these can't be set inside it_xm_read_sample_header()? + sample->vibrato_speed = extra.vibrato_speed; + sample->vibrato_depth = extra.vibrato_depth; + sample->vibrato_rate = extra.vibrato_sweep; + /* Rate and sweep don't match, but the difference is + * accounted for in itrender.c. + */ + sample->vibrato_waveform = xm_convert_vibrato[extra.vibrato_type]; + } + for (j = 0; j < extra.n_samples; j++) { + if (it_xm_read_sample_data(&sigdata->sample[total_samples + j], roguebytes[j], f) != 0) { + _dumb_it_unload_sigdata(sigdata); + return NULL; + } + } + total_samples += extra.n_samples; + } + } + + sigdata->n_samples = total_samples; + + sigdata->flags = IT_WAS_AN_XM | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_STEREO | IT_USE_INSTRUMENTS; + // Are we OK with IT_COMPATIBLE_GXX off? + // + // When specifying note + instr + tone portamento, and an old note is still playing (even after note off): + // - If Compatible Gxx is on, the new note will be triggered only if the instrument _changes_. + // - If Compatible Gxx is off, the new note will always be triggered, provided the instrument is specified. + // - FT2 seems to do the latter (unconfirmed). + + // Err, wait. XM playback has its own code. The change made to the IT + // playbackc code didn't affect XM playback. Forget this then. There's + // still a bug in XM playback though, and it'll need some investigation... + // tomorrow... + + // UPDATE: IT_COMPATIBLE_GXX is required to be on, so that tone porta has + // separate memory from portamento. + + if (flags & XM_LINEAR_FREQUENCY) + sigdata->flags |= IT_LINEAR_SLIDES; + + sigdata->global_volume = 128; + sigdata->mixing_volume = 48; + sigdata->pan_separation = 128; + + memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS); + memset(sigdata->channel_pan, 32, DUMB_IT_N_CHANNELS); + + _dumb_it_fix_invalid_orders(sigdata); + + return sigdata; +} + + + +#if 0 // no fucking way, dude! + +/* The length returned is the time required to play from the beginning of the + * file to the last row of the last order (which is when the player will + * loop). Depending on the song, the sound might stop sooner. + * Due to fixed point roundoffs, I think this is only reliable to the second. + * Full precision could be achieved by using a double during the computation, + * or maybe a LONG_LONG. + */ +long it_compute_length(const DUMB_IT_SIGDATA *sigdata) { + IT_PATTERN *pattern; + int tempo, speed; + int loop_start[IT_N_CHANNELS]; + char loop_count[IT_N_CHANNELS]; + int order, entry; + int row_first_entry = 0; + int jump, jump_dest; + int delay, fine_delay; + int i; + long t; + + if (!sigdata) + return 0; + + tempo = sigdata->tempo; + speed = sigdata->speed; + order = entry = 0; + jump = jump_dest = 0; + t = 0; + + /* for each PATTERN */ + for (order = 0; order < sigdata->n_orders; order++) { + + if (sigdata->order[order] == IT_ORDER_END) break; + if (sigdata->order[order] == IT_ORDER_SKIP) continue; + + for (i = 0; i < IT_N_CHANNELS; i++) + loop_count[i] = -1; + + pattern = &sigdata->pattern[sigdata->order[order]]; + entry = 0; + if (jump == IT_BREAK_TO_ROW) { + int row = 0; + while (row < jump_dest) + if (pattern->entry[entry++].channel >= IT_N_CHANNELS) + row++; + } + + /* for each ROW */ + while (entry < pattern->n_entries) { + row_first_entry = entry; + delay = fine_delay = 0; + jump = 0; + + /* for each note NOTE */ + while (entry < pattern->n_entries && pattern->entry[entry].channel < IT_N_CHANNELS) { + int value = pattern->entry[entry].effectvalue; + int channel = pattern->entry[entry].channel; + + switch (pattern->entry[entry].effect) { + + case IT_SET_SPEED: speed = value; break; + + case IT_JUMP_TO_ORDER: + if (value <= order) /* infinite loop */ + return 0; + jump = IT_JUMP_TO_ORDER; + jump_dest = value; + break; + + case IT_BREAK_TO_ROW: + jump = IT_BREAK_TO_ROW; + jump_dest = value; + break; + + case IT_S: + switch (HIGH(value)) { + case IT_S_PATTERN_DELAY: delay = LOW(value); break; + case IT_S_FINE_PATTERN_DELAY: fine_delay = LOW(value); break; + case IT_S_PATTERN_LOOP: + if (LOW(value) == 0) { + loop_start[channel] = row_first_entry; + } else { + if (loop_count[channel] == -1) + loop_count[channel] = LOW(value); + + if (loop_count[channel]) { + jump = IT_S_PATTERN_LOOP; + jump_dest = loop_start[channel]; + } + loop_count[channel]--; + } + break; + } + break; + + case IT_SET_SONG_TEMPO: + switch (HIGH(value)) { /* slides happen every non-row frames */ + case 0: tempo = tempo - LOW(value) * (speed - 1); break; + case 1: tempo = tempo + LOW(value) * (speed - 1); break; + default: tempo = value; + } + tempo = MID(32, tempo, 255); + break; + } + + entry++; + } + + /* end of ROW */ + entry++; + t += TICK_TIME_DIVIDEND * (speed * (1 + delay) + fine_delay) / tempo; + + if (jump == IT_JUMP_TO_ORDER) { + order = jump_dest - 1; + break; + } else if (jump == IT_BREAK_TO_ROW) + break; + else if (jump == IT_S_PATTERN_LOOP) + entry = jump_dest - 1; + } + + /* end of PATTERN */ + } + + return t; +} + +#endif /* 0 */ + + + +DUH *dumb_read_xm(DUMBFILE *f) { + sigdata_t *sigdata; + long length; + + DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it; + + sigdata = it_xm_load_sigdata(f); + + if (!sigdata) + return NULL; + + length = _dumb_it_build_checkpoints(sigdata); + + return make_duh(length, 1, &descptr, &sigdata); +} + +} // namespace AGS3 From b7e23390b2caf80b104ded5795abf5563f03f4d4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 15:38:18 -0800 Subject: [PATCH 054/215] AGS: Added missing allegro gfx methods --- engines/ags/lib/allegro/aintern.h | 43 ++ engines/ags/lib/allegro/color.cpp | 979 ++++++++++++++++++++++++++- engines/ags/lib/allegro/color.h | 1 + engines/ags/lib/allegro/graphics.cpp | 37 + engines/ags/lib/allegro/system.cpp | 7 +- engines/ags/module.mk | 1 + 6 files changed, 1040 insertions(+), 28 deletions(-) create mode 100644 engines/ags/lib/allegro/aintern.h create mode 100644 engines/ags/lib/allegro/graphics.cpp diff --git a/engines/ags/lib/allegro/aintern.h b/engines/ags/lib/allegro/aintern.h new file mode 100644 index 000000000000..37ac742507ae --- /dev/null +++ b/engines/ags/lib/allegro/aintern.h @@ -0,0 +1,43 @@ +/* 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 AGS_LIB_ALLEGRO_AINTERN_H +#define AGS_LIB_ALLEGRO_AINTERN_H + +#include "ags/lib/allegro/base.h" +#include "ags/lib/allegro/color.h" + +namespace AGS3 { + +extern int _color_depth; + +/* truecolor blending functions */ +AL_VAR(BLENDER_FUNC, _blender_func15); +AL_VAR(BLENDER_FUNC, _blender_func16); +AL_VAR(BLENDER_FUNC, _blender_func24); +AL_VAR(BLENDER_FUNC, _blender_func32); + +AL_VAR(int, _blender_alpha); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 5126e5c62eaa..41eed400009f 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -21,6 +21,8 @@ */ #include "ags/lib/allegro/color.h" +#include "ags/lib/allegro/system.h" +#include "ags/lib/allegro/aintern.h" #include "common/textconsole.h" #include "common/system.h" #include "graphics/palette.h" @@ -46,10 +48,6 @@ AL_ARRAY(int, _rgb_scale_6); PALETTE _current_palette; -int bestfit_color(const PALETTE pal, int r, int g, int b) { - error("TODO: bestfit_color"); -} - void set_color(int idx, const RGB *p) { _current_palette[idx] = *p; g_system->getPaletteManager()->setPalette((const byte *)p, idx, 1); @@ -74,22 +72,6 @@ void set_palette_range(const PALETTE p, int from, int to, int retracesync) { g_system->getPaletteManager()->setPalette(&palette[from], from, to - from + 1); } -int makeacol(int r, int g, int b, int a) { - error("TODO: makeacol"); -} - -int makeacol_depth(int color_depth, int r, int g, int b, int a) { - error("TODO: makeacol_depth"); -} - -void hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b) { - error("TODO: hsv_to_rgb"); -} - -void rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v) { - error("TODO: rgb_to_hsv"); -} - int makecol15(int r, int g, int b) { return (((r >> 3) << _rgb_r_shift_15) | ((g >> 3) << _rgb_g_shift_15) | @@ -157,6 +139,22 @@ int getb16(int c) { return _rgb_scale_5[(c >> _rgb_b_shift_16) & 0x1F]; } +int getr24(int c) { + error("TODO: getr24"); +} + +int getg24(int c) { + error("TODO: getg24"); +} + +int getb24(int c) { + error("TODO: getb24"); +} + +int geta24(int c) { + error("TODO: geta24"); +} + int getr32(int c) { error("TODO: getr32"); } @@ -181,20 +179,953 @@ int makecol8(byte r, byte g, byte b) { return (b) | (g << 8) | (r << 16); } +void get_color(int idx, RGB *p) { + warning("TODO: get_color"); +} + +void get_palette(PALETTE p) { + warning("TODO: get_palette"); +} + +void get_palette_range(PALETTE p, int from, int to) { + warning("TODO: get_palette_range"); +} + +void fade_interpolate(AL_CONST PALETTE source, AL_CONST PALETTE dest, PALETTE output, int pos, int from, int to) { + warning("TODO: fade_interpolate"); +} + +void fade_from_range(AL_CONST PALETTE source, AL_CONST PALETTE dest, int speed, int from, int to) { + warning("TODO: fade_from_range"); +} + +void fade_in_range(AL_CONST PALETTE p, int speed, int from, int to) { + warning("TODO: fade_in_range"); +} + +void fade_out_range(int speed, int from, int to) { + warning("TODO: fade_out_range"); +} + +void fade_from(AL_CONST PALETTE source, AL_CONST PALETTE dest, int speed) { + warning("TODO: fade_from"); +} + +void fade_in(AL_CONST PALETTE p, int speed) { + warning("TODO: fade_in"); +} + +void fade_out(int speed) { + warning("TODO: fade_out"); +} + +void select_palette(AL_CONST PALETTE p) { + warning("TODO: select_palette"); +} + +void unselect_palette(void) { + warning("TODO: unselect_palette"); +} + +void generate_332_palette(PALETTE pal) { + warning("TODO: generate_332_palette"); +} + +int generate_optimized_palette(BITMAP *image, PALETTE pal, AL_CONST signed char rsvdcols[256]) { + warning("TODO: generate_optimized_palette"); + return 0; +} + +void set_blender_mode(BLENDER_FUNC b15, BLENDER_FUNC b16, BLENDER_FUNC b24, int r, int g, int b, int a) { + warning("TODO: set_blender_mode"); +} + +void set_blender_mode_ex(BLENDER_FUNC b15, BLENDER_FUNC b16, BLENDER_FUNC b24, BLENDER_FUNC b32, BLENDER_FUNC b15x, BLENDER_FUNC b16x, BLENDER_FUNC b24x, int r, int g, int b, int a) { + warning("TODO: set_blender_mode_ex"); +} + +void set_alpha_blender(void) { + warning("TODO: set_alpha_blender"); +} + +void set_write_alpha_blender(void) { + warning("TODO: set_write_alpha_blender"); +} + +void set_trans_blender(int r, int g, int b, int a) { + warning("TODO: set_trans_blender"); +} + +void set_add_blender(int r, int g, int b, int a) { + warning("TODO: set_add_blender"); +} + +void set_burn_blender(int r, int g, int b, int a) { + warning("TODO: set_burn_blender"); +} + +void set_color_blender(int r, int g, int b, int a) { + warning("TODO: set_color_blender"); +} + +void set_difference_blender(int r, int g, int b, int a) { + warning("TODO: set_difference_blender"); +} + +void set_dissolve_blender(int r, int g, int b, int a) { + warning("TODO: set_dissolve_blender"); +} + +void set_dodge_blender(int r, int g, int b, int a) { + warning("TODO: set_dodge_blender"); +} + +void set_hue_blender(int r, int g, int b, int a) { + warning("TODO: set_hue_blender"); +} + +void set_invert_blender(int r, int g, int b, int a) { + warning("TODO: set_invert_blender"); +} + +void set_luminance_blender(int r, int g, int b, int a) { + warning("TODO: set_luminance_blender"); +} + +void set_multiply_blender(int r, int g, int b, int a) { + warning("TODO: set_multiply_blender"); +} + +void set_saturation_blender(int r, int g, int b, int a) { + warning("TODO: set_saturation_blender"); +} + +void set_screen_blender(int r, int g, int b, int a) { + warning("TODO: set_screen_blender"); +} + + +/* makecol_depth: + * Converts R, G, and B values (ranging 0-255) to whatever pixel format + * is required by the specified color depth. + */ +int makecol_depth(int color_depth, int r, int g, int b) { + switch (color_depth) { + + case 8: + return makecol8(r, g, b); + + case 15: + return makecol15(r, g, b); + + case 16: + return makecol16(r, g, b); + + case 24: + return makecol24(r, g, b); + + case 32: + return makecol32(r, g, b); + } + + return 0; +} + + + +/* makeacol_depth: + * Converts R, G, B, and A values (ranging 0-255) to whatever pixel format + * is required by the specified color depth. + */ +int makeacol_depth(int color_depth, int r, int g, int b, int a) { + switch (color_depth) { + + case 8: + return makecol8(r, g, b); + + case 15: + return makecol15(r, g, b); + + case 16: + return makecol16(r, g, b); + + case 24: + return makecol24(r, g, b); + + case 32: + return makeacol32(r, g, b, a); + } + + return 0; +} + + + +/* makecol: + * Converts R, G, and B values (ranging 0-255) to whatever pixel format + * is required by the current video mode. + */ +int makecol(int r, int g, int b) { + return makecol_depth(_color_depth, r, g, b); +} + + + +/* makeacol: + * Converts R, G, B, and A values (ranging 0-255) to whatever pixel format + * is required by the current video mode. + */ +int makeacol(int r, int g, int b, int a) { + return makeacol_depth(_color_depth, r, g, b, a); +} + + + +/* getr_depth: + * Extracts the red component (ranging 0-255) from a pixel in the format + * being used by the specified color depth. + */ int getr_depth(int color_depth, int c) { - error("TOD: getr_depth"); + switch (color_depth) { + + case 8: + return getr8(c); + + case 15: + return getr15(c); + + case 16: + return getr16(c); + + case 24: + return getr24(c); + + case 32: + return getr32(c); + } + + return 0; } + + +/* getg_depth: + * Extracts the green component (ranging 0-255) from a pixel in the format + * being used by the specified color depth. + */ int getg_depth(int color_depth, int c) { - error("TOD: getg_depth"); + switch (color_depth) { + + case 8: + return getg8(c); + + case 15: + return getg15(c); + + case 16: + return getg16(c); + + case 24: + return getg24(c); + + case 32: + return getg32(c); + } + + return 0; } + + +/* getb_depth: + * Extracts the blue component (ranging 0-255) from a pixel in the format + * being used by the specified color depth. + */ int getb_depth(int color_depth, int c) { - error("TOD: getb_depth"); + switch (color_depth) { + + case 8: + return getb8(c); + + case 15: + return getb15(c); + + case 16: + return getb16(c); + + case 24: + return getb24(c); + + case 32: + return getb32(c); + } + + return 0; } + + +/* geta_depth: + * Extracts the alpha component (ranging 0-255) from a pixel in the format + * being used by the specified color depth. + */ int geta_depth(int color_depth, int c) { - error("TOD: geta_depth"); + if (color_depth == 32) + return geta32(c); + + return 0; +} + + + +/* getr: + * Extracts the red component (ranging 0-255) from a pixel in the format + * being used by the current video mode. + */ +int getr(int c) { + return getr_depth(_color_depth, c); +} + + + +/* getg: + * Extracts the green component (ranging 0-255) from a pixel in the format + * being used by the current video mode. + */ +int getg(int c) { + return getg_depth(_color_depth, c); +} + + + +/* getb: + * Extracts the blue component (ranging 0-255) from a pixel in the format + * being used by the current video mode. + */ +int getb(int c) { + return getb_depth(_color_depth, c); +} + + + +/* geta: + * Extracts the alpha component (ranging 0-255) from a pixel in the format + * being used by the current video mode. + */ +int geta(int c) { + return geta_depth(_color_depth, c); +} + + + +/* 1.5k lookup table for color matching */ +static unsigned int col_diff[3 * 128]; + + + +/* bestfit_init: + * Color matching is done with weighted squares, which are much faster + * if we pregenerate a little lookup table... + */ +static void bestfit_init(void) { + int i; + + for (i = 1; i < 64; i++) { + int k = i * i; + col_diff[0 + i] = col_diff[0 + 128 - i] = k * (59 * 59); + col_diff[128 + i] = col_diff[128 + 128 - i] = k * (30 * 30); + col_diff[256 + i] = col_diff[256 + 128 - i] = k * (11 * 11); + } +} + + + +/* bestfit_color: + * Searches a palette for the color closest to the requested R, G, B value. + */ +int bestfit_color(AL_CONST PALETTE pal, int r, int g, int b) { + int i, coldiff, lowest, bestfit; + + assert(r >= 0 && r <= 63); + assert(g >= 0 && g <= 63); + assert(b >= 0 && b <= 63); + + if (col_diff[1] == 0) + bestfit_init(); + + bestfit = 0; + lowest = INT_MAX; + + /* only the transparent (pink) color can be mapped to index 0 */ + if ((r == 63) && (g == 0) && (b == 63)) + i = 0; + else + i = 1; + + while (i < PAL_SIZE) { + AL_CONST RGB *rgb = &pal[i]; + coldiff = (col_diff + 0)[(rgb->g - g) & 0x7F]; + if (coldiff < lowest) { + coldiff += (col_diff + 128)[(rgb->r - r) & 0x7F]; + if (coldiff < lowest) { + coldiff += (col_diff + 256)[(rgb->b - b) & 0x7F]; + if (coldiff < lowest) { + bestfit = rgb - pal; /* faster than `bestfit = i;' */ + if (coldiff == 0) + return bestfit; + lowest = coldiff; + } + } + } + i++; + } + + return bestfit; +} + + + +/* makecol8: + * Converts R, G, and B values (ranging 0-255) to an 8 bit paletted color. + * If the global rgb_map table is initialised, it uses that, otherwise + * it searches through the current palette to find the best match. + */ +int makecol8(int r, int g, int b) { + if (rgb_map) + return rgb_map->data[r >> 3][g >> 3][b >> 3]; + else + return bestfit_color(_current_palette, r >> 2, g >> 2, b >> 2); +} + + + +/* hsv_to_rgb: + * Converts from HSV colorspace to RGB values. + */ +void hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b) { + float f, x, y, z; + int i; + + assert(s >= 0 && s <= 1); + assert(v >= 0 && v <= 1); + + v *= 255.0f; + + if (s == 0.0f) { /* ok since we don't divide by s, and faster */ + *r = *g = *b = v + 0.5f; + } else { + h = fmod(h, 360.0f) / 60.0f; + if (h < 0.0f) + h += 6.0f; + + i = (int)h; + f = h - i; + x = v * s; + y = x * f; + v += 0.5f; /* round to the nearest integer below */ + z = v - x; + + switch (i) { + + case 6: + case 0: + *r = v; + *g = z + y; + *b = z; + break; + + case 1: + *r = v - y; + *g = v; + *b = z; + break; + + case 2: + *r = z; + *g = v; + *b = z + y; + break; + + case 3: + *r = z; + *g = v - y; + *b = v; + break; + + case 4: + *r = z + y; + *g = z; + *b = v; + break; + + case 5: + *r = v; + *g = z; + *b = v - y; + break; + } + } +} + + + +/* rgb_to_hsv: + * Converts an RGB value into the HSV colorspace. + */ +void rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v) { + int delta; + + assert(r >= 0 && r <= 255); + assert(g >= 0 && g <= 255); + assert(b >= 0 && b <= 255); + + if (r > g) { + if (b > r) { + /* b>r>g */ + delta = b - g; + *h = 240.0f + ((r - g) * 60) / (float)delta; + *s = (float)delta / (float)b; + *v = (float)b * (1.0f / 255.0f); + } else { + /* r>g and r>b */ + delta = r - MIN(g, b); + *h = ((g - b) * 60) / (float)delta; + if (*h < 0.0f) + *h += 360.0f; + *s = (float)delta / (float)r; + *v = (float)r * (1.0f / 255.0f); + } + } else { + if (b > g) { + /* b>g>=r */ + delta = b - r; + *h = 240.0f + ((r - g) * 60) / (float)delta; + *s = (float)delta / (float)b; + *v = (float)b * (1.0f / 255.0f); + } else { + /* g>=b and g>=r */ + delta = g - MIN(r, b); + if (delta == 0) { + *h = 0.0f; + if (g == 0) + *s = *v = 0.0f; + else { + *s = (float)delta / (float)g; + *v = (float)g * (1.0f / 255.0f); + } + } else { + *h = 120.0f + ((b - r) * 60) / (float)delta; + *s = (float)delta / (float)g; + *v = (float)g * (1.0f / 255.0f); + } + } + } +} + + + +/* create_rgb_table: + * Fills an RGB_MAP lookup table with conversion data for the specified + * palette. This is the faster version by Jan Hubicka. + * + * Uses alg. similar to floodfill - it adds one seed per every color in + * palette to its best position. Then areas around seed are filled by + * same color because it is best approximation for them, and then areas + * about them etc... + * + * It does just about 80000 tests for distances and this is about 100 + * times better than normal 256*32000 tests so the calculation time + * is now less than one second at all computers I tested. + */ +void create_rgb_table(RGB_MAP *table, AL_CONST PALETTE pal, void (*callback)(int pos)) { +#define UNUSED 65535 +#define LAST 65532 + + /* macro add adds to single linked list */ +#define add(i) (next[(i)] == UNUSED ? (next[(i)] = LAST, \ + (first != LAST ? (next[last] = (i)) : (first = (i))), \ + (last = (i))) : 0) + + /* same but w/o checking for first element */ +#define add1(i) (next[(i)] == UNUSED ? (next[(i)] = LAST, \ + next[last] = (i), \ + (last = (i))) : 0) + + /* calculates distance between two colors */ +#define dist(a1, a2, a3, b1, b2, b3) \ + (col_diff[ ((a2) - (b2)) & 0x7F] + \ + (col_diff + 128)[((a1) - (b1)) & 0x7F] + \ + (col_diff + 256)[((a3) - (b3)) & 0x7F]) + + /* converts r,g,b to position in array and back */ +#define pos(r, g, b) \ + (((r) / 2) * 32 * 32 + ((g) / 2) * 32 + ((b) / 2)) + +#define depos(pal, r, g, b) \ + ((b) = ((pal) & 31) * 2, \ + (g) = (((pal) >> 5) & 31) * 2, \ + (r) = (((pal) >> 10) & 31) * 2) + + /* is current color better than pal1? */ +#define better(r1, g1, b1, pal1) \ + (((int)dist((r1), (g1), (b1), \ + (pal1).r, (pal1).g, (pal1).b)) > (int)dist2) + + /* checking of position */ +#define dopos(rp, gp, bp, ts) \ + if ((rp > -1 || r > 0) && (rp < 1 || r < 61) && \ + (gp > -1 || g > 0) && (gp < 1 || g < 61) && \ + (bp > -1 || b > 0) && (bp < 1 || b < 61)) { \ + i = first + rp * 32 * 32 + gp * 32 + bp; \ + if (!data[i]) { \ + data[i] = val; \ + add1(i); \ + } \ + else if ((ts) && (data[i] != val)) { \ + dist2 = (rp ? (col_diff+128)[(r+2*rp-pal[val].r) & 0x7F] : r2) + \ + (gp ? (col_diff )[(g+2*gp-pal[val].g) & 0x7F] : g2) + \ + (bp ? (col_diff+256)[(b+2*bp-pal[val].b) & 0x7F] : b2); \ + if (better((r+2*rp), (g+2*gp), (b+2*bp), pal[data[i]])) { \ + data[i] = val; \ + add1(i); \ + } \ + } \ + } + + int i, curr, r, g, b, val, dist2; + unsigned int r2, g2, b2; + unsigned short next[32 * 32 * 32]; + unsigned char *data; + int first = LAST; + int last = LAST; + int count = 0; + int cbcount = 0; + +#define AVERAGE_COUNT 18000 + + if (col_diff[1] == 0) + bestfit_init(); + + memset(next, 255, sizeof(next)); + memset(table->data, 0, sizeof(char) * 32 * 32 * 32); + + data = (unsigned char *)table->data; + + /* add starting seeds for floodfill */ + for (i = 1; i < PAL_SIZE; i++) { + curr = pos(pal[i].r, pal[i].g, pal[i].b); + if (next[curr] == UNUSED) { + data[curr] = i; + add(curr); + } + } + + /* main floodfill: two versions of loop for faster growing in blue axis */ + while (first != LAST) { + depos(first, r, g, b); + + /* calculate distance of current color */ + val = data[first]; + r2 = (col_diff + 128)[((pal[val].r) - (r)) & 0x7F]; + g2 = (col_diff)[((pal[val].g) - (g)) & 0x7F]; + b2 = (col_diff + 256)[((pal[val].b) - (b)) & 0x7F]; + + /* try to grow to all directions */ + dopos(0, 0, 1, 1); + dopos(0, 0, -1, 1); + dopos(1, 0, 0, 1); + dopos(-1, 0, 0, 1); + dopos(0, 1, 0, 1); + dopos(0, -1, 0, 1); + + /* faster growing of blue direction */ + if ((b > 0) && (data[first - 1] == val)) { + b -= 2; + first--; + b2 = (col_diff + 256)[((pal[val].b) - (b)) & 0x7F]; + + dopos(-1, 0, 0, 0); + dopos(1, 0, 0, 0); + dopos(0, -1, 0, 0); + dopos(0, 1, 0, 0); + + first++; + } + + /* get next from list */ + i = first; + first = next[first]; + next[i] = UNUSED; + + /* second version of loop */ + if (first != LAST) { + depos(first, r, g, b); + + val = data[first]; + r2 = (col_diff + 128)[((pal[val].r) - (r)) & 0x7F]; + g2 = (col_diff)[((pal[val].g) - (g)) & 0x7F]; + b2 = (col_diff + 256)[((pal[val].b) - (b)) & 0x7F]; + + dopos(0, 0, 1, 1); + dopos(0, 0, -1, 1); + dopos(1, 0, 0, 1); + dopos(-1, 0, 0, 1); + dopos(0, 1, 0, 1); + dopos(0, -1, 0, 1); + + if ((b < 61) && (data[first + 1] == val)) { + b += 2; + first++; + b2 = (col_diff + 256)[((pal[val].b) - (b)) & 0x7f]; + + dopos(-1, 0, 0, 0); + dopos(1, 0, 0, 0); + dopos(0, -1, 0, 0); + dopos(0, 1, 0, 0); + + first--; + } + + i = first; + first = next[first]; + next[i] = UNUSED; + } + + count++; + if (count == (cbcount + 1) * AVERAGE_COUNT / 256) { + if (cbcount < 256) { + if (callback) + callback(cbcount); + cbcount++; + } + } + } + + /* only the transparent (pink) color can be mapped to index 0 */ + if ((pal[0].r == 63) && (pal[0].g == 0) && (pal[0].b == 63)) + table->data[31][0][31] = 0; + + if (callback) + while (cbcount < 256) + callback(cbcount++); +} + + + +/* create_light_table: + * Constructs a lighting color table for the specified palette. At light + * intensity 255 the table will produce the palette colors directly, and + * at level 0 it will produce the specified R, G, B value for all colors + * (this is specified in 0-63 VGA format). If the callback function is + * not NULL, it will be called 256 times during the calculation, allowing + * you to display a progress indicator. + */ +void create_light_table(COLOR_MAP *table, AL_CONST PALETTE pal, int r, int g, int b, void (*callback)(int pos)) { + int r1, g1, b1, r2, g2, b2, x, y; + unsigned int t1, t2; + + assert(table); + assert(r >= 0 && r <= 63); + assert(g >= 0 && g <= 63); + assert(b >= 0 && b <= 63); + + if (rgb_map) { + for (x = 0; x < PAL_SIZE - 1; x++) { + t1 = x * 0x010101; + t2 = 0xFFFFFF - t1; + + r1 = (1 << 24) + r * t2; + g1 = (1 << 24) + g * t2; + b1 = (1 << 24) + b * t2; + + for (y = 0; y < PAL_SIZE; y++) { + r2 = (r1 + pal[y].r * t1) >> 25; + g2 = (g1 + pal[y].g * t1) >> 25; + b2 = (b1 + pal[y].b * t1) >> 25; + + table->data[x][y] = rgb_map->data[r2][g2][b2]; + } + } + if (callback) + (*callback)(x); + } else { + for (x = 0; x < PAL_SIZE - 1; x++) { + t1 = x * 0x010101; + t2 = 0xFFFFFF - t1; + + r1 = (1 << 23) + r * t2; + g1 = (1 << 23) + g * t2; + b1 = (1 << 23) + b * t2; + + for (y = 0; y < PAL_SIZE; y++) { + r2 = (r1 + pal[y].r * t1) >> 24; + g2 = (g1 + pal[y].g * t1) >> 24; + b2 = (b1 + pal[y].b * t1) >> 24; + + table->data[x][y] = bestfit_color(pal, r2, g2, b2); + } + } + + if (callback) + (*callback)(x); + } + + for (y = 0; y < PAL_SIZE; y++) + table->data[255][y] = y; +} + + + +/* create_trans_table: + * Constructs a translucency color table for the specified palette. The + * r, g, and b parameters specifiy the solidity of each color component, + * ranging from 0 (totally transparent) to 255 (totally solid). Source + * color #0 is a special case, and is set to leave the destination + * unchanged, so that masked sprites will draw correctly. If the callback + * function is not NULL, it will be called 256 times during the calculation, + * allowing you to display a progress indicator. + */ +void create_trans_table(COLOR_MAP *table, AL_CONST PALETTE pal, int r, int g, int b, void (*callback)(int pos)) { + int tmp[768], *q; + int x, y, i, j, k; + unsigned char *p; + int tr, tg, tb; + int add; + + assert(table); + assert(r >= 0 && r <= 255); + assert(g >= 0 && g <= 255); + assert(b >= 0 && b <= 255); + + /* This is a bit ugly, but accounts for the solidity parameters + being in the range 0-255 rather than 0-256. Given that the + precision of r,g,b components is only 6 bits it shouldn't do any + harm. */ + if (r > 128) + r++; + if (g > 128) + g++; + if (b > 128) + b++; + + if (rgb_map) + add = 255; + else + add = 127; + + for (x = 0; x < 256; x++) { + tmp[x * 3] = pal[x].r * (256 - r) + add; + tmp[x * 3 + 1] = pal[x].g * (256 - g) + add; + tmp[x * 3 + 2] = pal[x].b * (256 - b) + add; + } + + for (x = 1; x < PAL_SIZE; x++) { + i = pal[x].r * r; + j = pal[x].g * g; + k = pal[x].b * b; + + p = table->data[x]; + q = tmp; + + if (rgb_map) { + for (y = 0; y < PAL_SIZE; y++) { + tr = (i + *(q++)) >> 9; + tg = (j + *(q++)) >> 9; + tb = (k + *(q++)) >> 9; + p[y] = rgb_map->data[tr][tg][tb]; + } + } else { + for (y = 0; y < PAL_SIZE; y++) { + tr = (i + *(q++)) >> 8; + tg = (j + *(q++)) >> 8; + tb = (k + *(q++)) >> 8; + p[y] = bestfit_color(pal, tr, tg, tb); + } + } + + if (callback) + (*callback)(x - 1); + } + + for (y = 0; y < PAL_SIZE; y++) { + table->data[0][y] = y; + table->data[y][y] = y; + } + + if (callback) + (*callback)(255); +} + + + +/* create_color_table: + * Creates a color mapping table, using a user-supplied callback to blend + * each pair of colors. Your blend routine will be passed a pointer to the + * palette and the two colors to be blended (x is the source color, y is + * the destination), and should return the desired output RGB for this + * combination. If the callback function is not NULL, it will be called + * 256 times during the calculation, allowing you to display a progress + * indicator. + */ +void create_color_table(COLOR_MAP *table, AL_CONST PALETTE pal, void (*blend)(AL_CONST PALETTE pal, int x, int y, RGB *rgb), void (*callback)(int pos)) { + int x, y; + RGB c; + + for (x = 0; x < PAL_SIZE; x++) { + for (y = 0; y < PAL_SIZE; y++) { + blend(pal, x, y, &c); + + if (rgb_map) + table->data[x][y] = rgb_map->data[c.r >> 1][c.g >> 1][c.b >> 1]; + else + table->data[x][y] = bestfit_color(pal, c.r, c.g, c.b); + } + + if (callback) + (*callback)(x); + } +} + + + +/* create_blender_table: + * Fills the specified color mapping table with lookup data for doing a + * paletted equivalent of whatever truecolor blender mode is currently + * selected. + */ +void create_blender_table(COLOR_MAP *table, AL_CONST PALETTE pal, void (*callback)(int pos)) { + int x, y, c; + int r, g, b; + int r1, g1, b1; + int r2, g2, b2; + + assert(_blender_func24); + + for (x = 0; x < PAL_SIZE; x++) { + for (y = 0; y < PAL_SIZE; y++) { + r1 = (pal[x].r << 2) | ((pal[x].r & 0x30) >> 4); + g1 = (pal[x].g << 2) | ((pal[x].g & 0x30) >> 4); + b1 = (pal[x].b << 2) | ((pal[x].b & 0x30) >> 4); + + r2 = (pal[y].r << 2) | ((pal[y].r & 0x30) >> 4); + g2 = (pal[y].g << 2) | ((pal[y].g & 0x30) >> 4); + b2 = (pal[y].b << 2) | ((pal[y].b & 0x30) >> 4); + + c = _blender_func24(makecol24(r1, g1, b1), makecol24(r2, g2, b2), _blender_alpha); + + r = getr24(c); + g = getg24(c); + b = getb24(c); + + if (rgb_map) + table->data[x][y] = rgb_map->data[r >> 3][g >> 3][b >> 3]; + else + table->data[x][y] = bestfit_color(pal, r >> 2, g >> 2, b >> 2); + } + + if (callback) + (*callback)(x); + } } } // namespace AGS3 diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index c5b92444f4fb..2ab216255df6 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -24,6 +24,7 @@ #define AGS_LIB_ALLEGRO_COLOR_H #include "common/scummsys.h" +#include "ags/lib/allegro/base.h" #include "ags/lib/allegro/alconfig.h" namespace AGS3 { diff --git a/engines/ags/lib/allegro/graphics.cpp b/engines/ags/lib/allegro/graphics.cpp new file mode 100644 index 000000000000..cc435162eaed --- /dev/null +++ b/engines/ags/lib/allegro/graphics.cpp @@ -0,0 +1,37 @@ +/* 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 "ags/lib/allegro/gfx.h" +#include "ags/lib/allegro/color.h" + +namespace AGS3 { + +int _color_depth; + +BLENDER_FUNC _blender_func15 = NULL; /* truecolor pixel blender routines */ +BLENDER_FUNC _blender_func16 = NULL; +BLENDER_FUNC _blender_func24 = NULL; +BLENDER_FUNC _blender_func32 = NULL; + +int _blender_alpha; + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/system.cpp b/engines/ags/lib/allegro/system.cpp index b372b7ebdd83..a27cb655b329 100644 --- a/engines/ags/lib/allegro/system.cpp +++ b/engines/ags/lib/allegro/system.cpp @@ -21,12 +21,11 @@ */ #include "ags/lib/allegro/system.h" +#include "ags/lib/allegro/aintern.h" #include "common/system.h" namespace AGS3 { -int color_depth; - SYSTEM_DRIVER system_none; SYSTEM_DRIVER *system_driver; @@ -57,11 +56,11 @@ void destroy_gfx_mode_list(GFX_MODE_LIST *list) { } void set_color_depth(int depth) { - color_depth = depth; + _color_depth = depth; } int get_color_depth() { - return color_depth; + return _color_depth; } int get_desktop_resolution(int *width, int *height) { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 0e97a279be40..27941c9d8210 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -15,6 +15,7 @@ MODULE_OBJS = \ lib/allegro/file.o \ lib/allegro/fixed.o \ lib/allegro/gfx.o \ + lib/allegro/graphics.o \ lib/allegro/keyboard.o \ lib/allegro/mouse.o \ lib/allegro/system.o \ From 88411519b9693083c444407e8f4b998b78b8a0d2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 15:40:55 -0800 Subject: [PATCH 055/215] AGS: Further adding missing code --- engines/ags/engine/plugin/global_plugin.cpp | 7 +++---- engines/ags/module.mk | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engines/ags/engine/plugin/global_plugin.cpp b/engines/ags/engine/plugin/global_plugin.cpp index 8ec36dd51d35..cc84eca6823c 100644 --- a/engines/ags/engine/plugin/global_plugin.cpp +++ b/engines/ags/engine/plugin/global_plugin.cpp @@ -27,9 +27,10 @@ //============================================================================= //include -#include "ags/shared/ac/global_plugin.h" -#include "ags/shared/ac/mouse.h" +#include "ags/engine/ac/global_plugin.h" +#include "ags/engine/ac/mouse.h" #include "ags/shared/util/string_compat.h" +#include "ags/engine/script/script_runtime.h" namespace AGS3 { @@ -45,8 +46,6 @@ void PluginSimulateMouseClick(int pluginButtonID) { // //============================================================================= -#include "ags/shared/script/script_runtime.h" - RuntimeScriptValue Sc_PluginStub_Void(const RuntimeScriptValue *params, int32_t param_count) { return RuntimeScriptValue((int32_t)0); } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 27941c9d8210..8c278fbe876c 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -287,6 +287,7 @@ MODULE_OBJS = \ engine/platform/base/agsplatformdriver.o \ engine/platform/linux/acpllnx.o \ engine/plugin/agsplugin.o \ + engine/plugin/global_plugin.o \ engine/plugin/library.o \ engine/plugin/pluginobjectreader.o \ engine/script/cc_instance.o \ From 34a9dbc2c70d5460b02ff084c284ebf929222681 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 16:56:31 -0800 Subject: [PATCH 056/215] AGS: Add further missing lib/ code --- engines/ags/engine/gfx/gfxfilter_aaogl.cpp | 6 +- .../ags/engine/media/audio/clip_mydumbmod.h | 2 +- engines/ags/engine/media/audio/sound.cpp | 7 +- engines/ags/lib/allegro.cpp | 83 + engines/ags/lib/allegro/colblend.cpp | 1 + engines/ags/lib/allegro/color.cpp | 5 +- engines/ags/lib/allegro/color.h | 1 + engines/ags/lib/allegro/gfx.cpp | 7 +- engines/ags/lib/allegro/graphics.cpp | 21 + engines/ags/lib/allegro/math.cpp | 16 +- engines/ags/lib/audio/aldumb.h | 2 +- engines/ags/lib/audio/midi.cpp | 8 + engines/ags/lib/audio/mp3.cpp | 5 + engines/ags/lib/dumb-0.9.2/dumb.cpp | 182 + .../ags/lib/dumb-0.9.2/{dumbfile.h => dumb.h} | 0 engines/ags/lib/dumb-0.9.2/dumbfile.cpp | 2 +- .../ags/lib/dumb-0.9.2/helpers/clickrem.cpp | 278 ++ engines/ags/lib/dumb-0.9.2/helpers/memfile.c | 96 + engines/ags/lib/dumb-0.9.2/helpers/resample.c | 1177 ++++++ engines/ags/lib/dumb-0.9.2/helpers/sampbuf.c | 47 + engines/ags/lib/dumb-0.9.2/helpers/silence.c | 29 + engines/ags/lib/dumb-0.9.2/helpers/stdfile.c | 93 + engines/ags/lib/dumb-0.9.2/it/it.h | 714 ++++ engines/ags/lib/dumb-0.9.2/it/itmisc.cpp | 70 + engines/ags/lib/dumb-0.9.2/it/itrender.cpp | 3533 +++++++++++++++++ engines/ags/lib/dumb-0.9.2/it/itunload.cpp | 92 + engines/ags/lib/std/queue.h | 2 +- engines/ags/module.mk | 8 + 28 files changed, 6459 insertions(+), 28 deletions(-) create mode 100644 engines/ags/lib/dumb-0.9.2/dumb.cpp rename engines/ags/lib/dumb-0.9.2/{dumbfile.h => dumb.h} (100%) create mode 100644 engines/ags/lib/dumb-0.9.2/helpers/clickrem.cpp create mode 100644 engines/ags/lib/dumb-0.9.2/helpers/memfile.c create mode 100644 engines/ags/lib/dumb-0.9.2/helpers/resample.c create mode 100644 engines/ags/lib/dumb-0.9.2/helpers/sampbuf.c create mode 100644 engines/ags/lib/dumb-0.9.2/helpers/silence.c create mode 100644 engines/ags/lib/dumb-0.9.2/helpers/stdfile.c create mode 100644 engines/ags/lib/dumb-0.9.2/it/it.h create mode 100644 engines/ags/lib/dumb-0.9.2/it/itmisc.cpp create mode 100644 engines/ags/lib/dumb-0.9.2/it/itrender.cpp create mode 100644 engines/ags/lib/dumb-0.9.2/it/itunload.cpp diff --git a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp index ac26f2955763..f809d9331079 100644 --- a/engines/ags/engine/gfx/gfxfilter_aaogl.cpp +++ b/engines/ags/engine/gfx/gfxfilter_aaogl.cpp @@ -22,10 +22,10 @@ #include "ags/shared/core/platform.h" -#if 1 +#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX -#include "ags/shared/gfx/gfxfilter_aaogl.h" -#include "ags/shared/ogl_headers.h" +#include "ags/engine/gfx/gfxfilter_aaogl.h" +#include "ags/engine/gfx/ogl_headers.h" namespace AGS3 { namespace AGS { diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index 75c0a0433b4c..370de3f344c8 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -30,7 +30,7 @@ namespace AGS3 { #define VOLUME_TO_DUMB_VOL(vol) ((float)vol) / 256.0 -void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop); +extern void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop); // MOD/XM (DUMB) struct MYMOD : public SOUNDCLIP { diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index 5c3a72424f81..f92ab6683d29 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -61,11 +61,8 @@ namespace AGS3 { #error Either JGMOD_MOD_PLAYER or DUMB_MOD_PLAYER should be defined. #endif -extern "C" -{ - // Load MIDI from PACKFILE stream - MIDI *load_midi_pf(PACKFILE *pf); -} +// Load MIDI from PACKFILE stream +extern MIDI *load_midi_pf(PACKFILE *pf); int use_extra_sound_offset = 0; diff --git a/engines/ags/lib/allegro.cpp b/engines/ags/lib/allegro.cpp index 90365ef8250a..bc1f5d24f23d 100644 --- a/engines/ags/lib/allegro.cpp +++ b/engines/ags/lib/allegro.cpp @@ -24,6 +24,89 @@ namespace AGS3 { +/* default palette structures */ +PALETTE black_palette; +PALETTE _current_palette; + +int _current_palette_changed = 0xFFFFFFFF; + + +PALETTE desktop_palette = { + { 63, 63, 63, 0 }, { 63, 0, 0, 0 }, { 0, 63, 0, 0 }, { 63, 63, 0, 0 }, + { 0, 0, 63, 0 }, { 63, 0, 63, 0 }, { 0, 63, 63, 0 }, { 16, 16, 16, 0 }, + { 31, 31, 31, 0 }, { 63, 31, 31, 0 }, { 31, 63, 31, 0 }, { 63, 63, 31, 0 }, + { 31, 31, 63, 0 }, { 63, 31, 63, 0 }, { 31, 63, 63, 0 }, { 0, 0, 0, 0 } +}; + + +PALETTE default_palette = { + { 0, 0, 0, 0 }, { 0, 0, 42, 0 }, { 0, 42, 0, 0 }, { 0, 42, 42, 0 }, + { 42, 0, 0, 0 }, { 42, 0, 42, 0 }, { 42, 21, 0, 0 }, { 42, 42, 42, 0 }, + { 21, 21, 21, 0 }, { 21, 21, 63, 0 }, { 21, 63, 21, 0 }, { 21, 63, 63, 0 }, + { 63, 21, 21, 0 }, { 63, 21, 63, 0 }, { 63, 63, 21, 0 }, { 63, 63, 63, 0 }, + { 0, 0, 0, 0 }, { 5, 5, 5, 0 }, { 8, 8, 8, 0 }, { 11, 11, 11, 0 }, + { 14, 14, 14, 0 }, { 17, 17, 17, 0 }, { 20, 20, 20, 0 }, { 24, 24, 24, 0 }, + { 28, 28, 28, 0 }, { 32, 32, 32, 0 }, { 36, 36, 36, 0 }, { 40, 40, 40, 0 }, + { 45, 45, 45, 0 }, { 50, 50, 50, 0 }, { 56, 56, 56, 0 }, { 63, 63, 63, 0 }, + { 0, 0, 63, 0 }, { 16, 0, 63, 0 }, { 31, 0, 63, 0 }, { 47, 0, 63, 0 }, + { 63, 0, 63, 0 }, { 63, 0, 47, 0 }, { 63, 0, 31, 0 }, { 63, 0, 16, 0 }, + { 63, 0, 0, 0 }, { 63, 16, 0, 0 }, { 63, 31, 0, 0 }, { 63, 47, 0, 0 }, + { 63, 63, 0, 0 }, { 47, 63, 0, 0 }, { 31, 63, 0, 0 }, { 16, 63, 0, 0 }, + { 0, 63, 0, 0 }, { 0, 63, 16, 0 }, { 0, 63, 31, 0 }, { 0, 63, 47, 0 }, + { 0, 63, 63, 0 }, { 0, 47, 63, 0 }, { 0, 31, 63, 0 }, { 0, 16, 63, 0 }, + { 31, 31, 63, 0 }, { 39, 31, 63, 0 }, { 47, 31, 63, 0 }, { 55, 31, 63, 0 }, + { 63, 31, 63, 0 }, { 63, 31, 55, 0 }, { 63, 31, 47, 0 }, { 63, 31, 39, 0 }, + { 63, 31, 31, 0 }, { 63, 39, 31, 0 }, { 63, 47, 31, 0 }, { 63, 55, 31, 0 }, + { 63, 63, 31, 0 }, { 55, 63, 31, 0 }, { 47, 63, 31, 0 }, { 39, 63, 31, 0 }, + { 31, 63, 31, 0 }, { 31, 63, 39, 0 }, { 31, 63, 47, 0 }, { 31, 63, 55, 0 }, + { 31, 63, 63, 0 }, { 31, 55, 63, 0 }, { 31, 47, 63, 0 }, { 31, 39, 63, 0 }, + { 45, 45, 63, 0 }, { 49, 45, 63, 0 }, { 54, 45, 63, 0 }, { 58, 45, 63, 0 }, + { 63, 45, 63, 0 }, { 63, 45, 58, 0 }, { 63, 45, 54, 0 }, { 63, 45, 49, 0 }, + { 63, 45, 45, 0 }, { 63, 49, 45, 0 }, { 63, 54, 45, 0 }, { 63, 58, 45, 0 }, + { 63, 63, 45, 0 }, { 58, 63, 45, 0 }, { 54, 63, 45, 0 }, { 49, 63, 45, 0 }, + { 45, 63, 45, 0 }, { 45, 63, 49, 0 }, { 45, 63, 54, 0 }, { 45, 63, 58, 0 }, + { 45, 63, 63, 0 }, { 45, 58, 63, 0 }, { 45, 54, 63, 0 }, { 45, 49, 63, 0 }, + { 0, 0, 28, 0 }, { 7, 0, 28, 0 }, { 14, 0, 28, 0 }, { 21, 0, 28, 0 }, + { 28, 0, 28, 0 }, { 28, 0, 21, 0 }, { 28, 0, 14, 0 }, { 28, 0, 7, 0 }, + { 28, 0, 0, 0 }, { 28, 7, 0, 0 }, { 28, 14, 0, 0 }, { 28, 21, 0, 0 }, + { 28, 28, 0, 0 }, { 21, 28, 0, 0 }, { 14, 28, 0, 0 }, { 7, 28, 0, 0 }, + { 0, 28, 0, 0 }, { 0, 28, 7, 0 }, { 0, 28, 14, 0 }, { 0, 28, 21, 0 }, + { 0, 28, 28, 0 }, { 0, 21, 28, 0 }, { 0, 14, 28, 0 }, { 0, 7, 28, 0 }, + { 14, 14, 28, 0 }, { 17, 14, 28, 0 }, { 21, 14, 28, 0 }, { 24, 14, 28, 0 }, + { 28, 14, 28, 0 }, { 28, 14, 24, 0 }, { 28, 14, 21, 0 }, { 28, 14, 17, 0 }, + { 28, 14, 14, 0 }, { 28, 17, 14, 0 }, { 28, 21, 14, 0 }, { 28, 24, 14, 0 }, + { 28, 28, 14, 0 }, { 24, 28, 14, 0 }, { 21, 28, 14, 0 }, { 17, 28, 14, 0 }, + { 14, 28, 14, 0 }, { 14, 28, 17, 0 }, { 14, 28, 21, 0 }, { 14, 28, 24, 0 }, + { 14, 28, 28, 0 }, { 14, 24, 28, 0 }, { 14, 21, 28, 0 }, { 14, 17, 28, 0 }, + { 20, 20, 28, 0 }, { 22, 20, 28, 0 }, { 24, 20, 28, 0 }, { 26, 20, 28, 0 }, + { 28, 20, 28, 0 }, { 28, 20, 26, 0 }, { 28, 20, 24, 0 }, { 28, 20, 22, 0 }, + { 28, 20, 20, 0 }, { 28, 22, 20, 0 }, { 28, 24, 20, 0 }, { 28, 26, 20, 0 }, + { 28, 28, 20, 0 }, { 26, 28, 20, 0 }, { 24, 28, 20, 0 }, { 22, 28, 20, 0 }, + { 20, 28, 20, 0 }, { 20, 28, 22, 0 }, { 20, 28, 24, 0 }, { 20, 28, 26, 0 }, + { 20, 28, 28, 0 }, { 20, 26, 28, 0 }, { 20, 24, 28, 0 }, { 20, 22, 28, 0 }, + { 0, 0, 16, 0 }, { 4, 0, 16, 0 }, { 8, 0, 16, 0 }, { 12, 0, 16, 0 }, + { 16, 0, 16, 0 }, { 16, 0, 12, 0 }, { 16, 0, 8, 0 }, { 16, 0, 4, 0 }, + { 16, 0, 0, 0 }, { 16, 4, 0, 0 }, { 16, 8, 0, 0 }, { 16, 12, 0, 0 }, + { 16, 16, 0, 0 }, { 12, 16, 0, 0 }, { 8, 16, 0, 0 }, { 4, 16, 0, 0 }, + { 0, 16, 0, 0 }, { 0, 16, 4, 0 }, { 0, 16, 8, 0 }, { 0, 16, 12, 0 }, + { 0, 16, 16, 0 }, { 0, 12, 16, 0 }, { 0, 8, 16, 0 }, { 0, 4, 16, 0 }, + { 8, 8, 16, 0 }, { 10, 8, 16, 0 }, { 12, 8, 16, 0 }, { 14, 8, 16, 0 }, + { 16, 8, 16, 0 }, { 16, 8, 14, 0 }, { 16, 8, 12, 0 }, { 16, 8, 10, 0 }, + { 16, 8, 8, 0 }, { 16, 10, 8, 0 }, { 16, 12, 8, 0 }, { 16, 14, 8, 0 }, + { 16, 16, 8, 0 }, { 14, 16, 8, 0 }, { 12, 16, 8, 0 }, { 10, 16, 8, 0 }, + { 8, 16, 8, 0 }, { 8, 16, 10, 0 }, { 8, 16, 12, 0 }, { 8, 16, 14, 0 }, + { 8, 16, 16, 0 }, { 8, 14, 16, 0 }, { 8, 12, 16, 0 }, { 8, 10, 16, 0 }, + { 11, 11, 16, 0 }, { 12, 11, 16, 0 }, { 13, 11, 16, 0 }, { 15, 11, 16, 0 }, + { 16, 11, 16, 0 }, { 16, 11, 15, 0 }, { 16, 11, 13, 0 }, { 16, 11, 12, 0 }, + { 16, 11, 11, 0 }, { 16, 12, 11, 0 }, { 16, 13, 11, 0 }, { 16, 15, 11, 0 }, + { 16, 16, 11, 0 }, { 15, 16, 11, 0 }, { 13, 16, 11, 0 }, { 12, 16, 11, 0 }, + { 11, 16, 11, 0 }, { 11, 16, 12, 0 }, { 11, 16, 13, 0 }, { 11, 16, 15, 0 }, + { 11, 16, 16, 0 }, { 11, 15, 16, 0 }, { 11, 13, 16, 0 }, { 11, 12, 16, 0 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 63, 63, 63, 0 } +}; + + int install_allegro() { errnum = 0; return 0; diff --git a/engines/ags/lib/allegro/colblend.cpp b/engines/ags/lib/allegro/colblend.cpp index 4b623a190d15..20581c2f21cf 100644 --- a/engines/ags/lib/allegro/colblend.cpp +++ b/engines/ags/lib/allegro/colblend.cpp @@ -21,6 +21,7 @@ */ #include "ags/lib/allegro/colblend.h" +#include "ags/lib/allegro/color.h" namespace AGS3 { diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 41eed400009f..14243c765674 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -43,10 +43,9 @@ int _rgb_g_shift_32 = 0; int _rgb_b_shift_32 = 0; int _rgb_a_shift_32 = 0; -AL_ARRAY(int, _rgb_scale_5); -AL_ARRAY(int, _rgb_scale_6); +RGB_MAP *rgb_map; +COLOR_MAP *color_map; -PALETTE _current_palette; void set_color(int idx, const RGB *p) { _current_palette[idx] = *p; diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index 2ab216255df6..8dc105c49139 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -42,6 +42,7 @@ class BITMAP; struct color { byte r, g, b; + byte filler; } PACKED_STRUCT; typedef color RGB; diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index a14bf1dda89d..9111935848e6 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -208,7 +208,7 @@ void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { bmpS.blitFrom(spriteS, Common::Point(x, y)); } -void stretch_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, int w, int h) { +void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h) { Graphics::ManagedSurface &bmpS = **bmp; Graphics::ManagedSurface &spriteS = **sprite; @@ -403,4 +403,9 @@ void circlefill(BITMAP *bmp, int x, int y, int radius, int color) { error("TODO: circlefill"); } +void clear_bitmap(BITMAP *bmp) { + error("TODO: clear_bitmap"); +} + + } // namespace AGS3 diff --git a/engines/ags/lib/allegro/graphics.cpp b/engines/ags/lib/allegro/graphics.cpp index cc435162eaed..f7b717f69cef 100644 --- a/engines/ags/lib/allegro/graphics.cpp +++ b/engines/ags/lib/allegro/graphics.cpp @@ -34,4 +34,25 @@ BLENDER_FUNC _blender_func32 = NULL; int _blender_alpha; +/* lookup table for scaling 5 bit colors up to 8 bits */ +int _rgb_scale_5[32] = { + 0, 8, 16, 24, 33, 41, 49, 57, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 198, 206, 214, 222, 231, 239, 247, 255 +}; + + +/* lookup table for scaling 6 bit colors up to 8 bits */ +int _rgb_scale_6[64] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + 65, 69, 73, 77, 81, 85, 89, 93, + 97, 101, 105, 109, 113, 117, 121, 125, + 130, 134, 138, 142, 146, 150, 154, 158, + 162, 166, 170, 174, 178, 182, 186, 190, + 195, 199, 203, 207, 211, 215, 219, 223, + 227, 231, 235, 239, 243, 247, 251, 255 +}; + } // namespace AGS3 diff --git a/engines/ags/lib/allegro/math.cpp b/engines/ags/lib/allegro/math.cpp index 88c1a5eafaa0..19413b2cf6ec 100644 --- a/engines/ags/lib/allegro/math.cpp +++ b/engines/ags/lib/allegro/math.cpp @@ -23,13 +23,12 @@ #ifndef AGS_LIB_ALLEGRO_MATH_H #define AGS_LIB_ALLEGRO_MATH_H +#include "ags/lib/allegro/error.h" #include "ags/lib/allegro/fixed.h" namespace AGS3 { - -fixed _cos_tbl[512] = -{ +fixed _cos_tbl[512] = { /* precalculated fixed point (16.16) cosines for a full circle (0-255) */ 65536L, 65531L, 65516L, 65492L, 65457L, 65413L, 65358L, 65294L, @@ -98,10 +97,7 @@ fixed _cos_tbl[512] = 65220L, 65294L, 65358L, 65413L, 65457L, 65492L, 65516L, 65531L }; - - -fixed _tan_tbl[256] = -{ +fixed _tan_tbl[256] = { /* precalculated fixed point (16.16) tangents for a half circle (0-127) */ 0L, 804L, 1609L, 2414L, 3220L, 4026L, 4834L, 5644L, @@ -138,10 +134,7 @@ fixed _tan_tbl[256] = -6455L, -5644L, -4834L, -4026L, -3220L, -2414L, -1609L, -804L }; - - -fixed _acos_tbl[513] = -{ +fixed _acos_tbl[513] = { /* precalculated fixed point (16.16) inverse cosines (-1 to 1) */ 0x800000L, 0x7C65C7L, 0x7AE75AL, 0x79C19EL, 0x78C9BEL, 0x77EF25L, 0x772953L, 0x76733AL, @@ -212,7 +205,6 @@ fixed _acos_tbl[513] = }; - /* fixatan: * Fixed point inverse tangent. Does a binary search on the tan table. */ diff --git a/engines/ags/lib/audio/aldumb.h b/engines/ags/lib/audio/aldumb.h index 61ede22bd85c..32270f78e092 100644 --- a/engines/ags/lib/audio/aldumb.h +++ b/engines/ags/lib/audio/aldumb.h @@ -43,7 +43,7 @@ #define AGS_LIB_ALDUMB_H #include "ags/lib/allegro.h" -#include "ags/lib/dumb-0.9.2/dumbfile.h" +#include "ags/lib/dumb-0.9.2/dumb.h" namespace AGS3 { diff --git a/engines/ags/lib/audio/midi.cpp b/engines/ags/lib/audio/midi.cpp index 96ed12eb1095..5be76b146862 100644 --- a/engines/ags/lib/audio/midi.cpp +++ b/engines/ags/lib/audio/midi.cpp @@ -21,10 +21,14 @@ */ #include "ags/lib/audio/midi.h" +#include "ags/lib/allegro/file.h" #include "common/textconsole.h" namespace AGS3 { +BEGIN_MIDI_DRIVER_LIST +END_MIDI_DRIVER_LIST + MIDI_DRIVER *midi_driver; MIDI_DRIVER *midi_input_driver; @@ -80,4 +84,8 @@ int load_midi_patches() { return 0; } +MIDI *load_midi_pf(PACKFILE *fp) { + error("TODO: load_midi_pf"); +} + } // namespace AGS3 diff --git a/engines/ags/lib/audio/mp3.cpp b/engines/ags/lib/audio/mp3.cpp index b948acdbf765..d6fd91ecfef6 100644 --- a/engines/ags/lib/audio/mp3.cpp +++ b/engines/ags/lib/audio/mp3.cpp @@ -114,4 +114,9 @@ AUDIOSTREAM *almp3_get_audiostream_mp3stream(ALMP3_MP3STREAM *mp3) { return nullptr; } +int almp3_get_length_msecs_mp3stream(ALMP3_MP3STREAM *mp3, int total_size) { + warning("TODO: almp3_get_length_msecs_mp3stream"); + return 0; +} + } // namespace AGS3 diff --git a/engines/ags/lib/dumb-0.9.2/dumb.cpp b/engines/ags/lib/dumb-0.9.2/dumb.cpp new file mode 100644 index 000000000000..215fb76828a5 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/dumb.cpp @@ -0,0 +1,182 @@ +/* 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 "ags/lib/dumb-0.9.2/dumb.h" +#include "common/textconsole.h" + +namespace AGS3 { + +void dumb_exit() { + // No implementation +} + +DUH *dumb_load_it(const char *filename) { + warning("TODO: dumb_load_it"); + return nullptr; +} + +DUH *dumb_load_xm(const char *filename) { + warning("TODO: dumb_load_xm"); + return nullptr; +} + +DUH *dumb_load_s3m(const char *filename) { + warning("TODO: dumb_load_s3m"); + return nullptr; +} + +DUH *dumb_load_mod(const char *filename) { + warning("TODO: dumb_load_mod"); + return nullptr; +} + +DUH *dumb_read_it(DUMBFILE *f) { + warning("TODO: dumb_read_it"); + return nullptr; +} +DUH *dumb_read_xm(DUMBFILE *f) { + warning("TODO: dumb_read_xm"); + return nullptr; +} + +DUH *dumb_read_s3m(DUMBFILE *f) { + warning("TODO: dumb_read_s3m"); + return nullptr; +} + +DUH *dumb_read_mod(DUMBFILE *f) { + warning("TODO: dumb_read_mod"); + return nullptr; +} + +int dumb_it_sd_get_n_orders(DUMB_IT_SIGDATA *sd) { + warning("TODO: dumb_it_sd_get_n_orders"); + return 0; +} + +int dumb_it_sd_get_initial_global_volume(DUMB_IT_SIGDATA *sd) { + warning("TODO: dumb_it_sd_get_initial_global_volume"); + return 0; +} + +void dumb_it_sd_set_initial_global_volume(DUMB_IT_SIGDATA *sd, int gv) { + warning("TODO: dumb_it_sd_set_initial_global_volume"); +} + +int dumb_it_sd_get_mixing_volume(DUMB_IT_SIGDATA *sd) { + warning("TODO: dumb_it_sd_get_mixing_volume"); + return 0; +} + +void dumb_it_sd_set_mixing_volume(DUMB_IT_SIGDATA *sd, int mv) { + warning("TODO: dumb_it_sd_set_mixing_volume"); +} + +int dumb_it_sd_get_initial_speed(DUMB_IT_SIGDATA *sd) { + warning("TODO: dumb_it_sd_get_initial_speed"); + return 0; +} + +void dumb_it_sd_set_initial_speed(DUMB_IT_SIGDATA *sd, int speed) { + warning("TODO: dumb_it_sd_set_initial_speed"); +} + +int dumb_it_sd_get_initial_tempo(DUMB_IT_SIGDATA *sd) { + warning("TODO: dumb_it_sd_get_initial_tempo"); + return 0; +} + +void dumb_it_sd_set_initial_tempo(DUMB_IT_SIGDATA *sd, int tempo) { + warning("TODO: dumb_it_sd_set_initial_tempo"); +} + +int dumb_it_sd_get_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel) { + warning("TODO: dumb_it_sd_get_initial_channel_volume"); + return 0; +} + +void dumb_it_sd_set_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel, int volume) { + warning("TODO: dumb_it_sd_set_initial_channel_volume"); +} + +int dumb_it_sr_get_current_order(DUMB_IT_SIGRENDERER *sr) { + warning("TODO: dumb_it_sr_get_current_order"); + return 0; +} + +int dumb_it_sr_get_current_row(DUMB_IT_SIGRENDERER *sr) { + warning("TODO: dumb_it_sr_get_current_row"); + return 0; +} + +int dumb_it_sr_get_global_volume(DUMB_IT_SIGRENDERER *sr) { + warning("TODO: dumb_it_sr_get_global_volume"); + return 0; +} + +void dumb_it_sr_set_global_volume(DUMB_IT_SIGRENDERER *sr, int gv) { + warning("TODO: dumb_it_sr_set_global_volume"); +} + +int dumb_it_sr_get_tempo(DUMB_IT_SIGRENDERER *sr) { + warning("TODO: dumb_it_sr_get_tempo"); + return 0; +} + +void dumb_it_sr_set_tempo(DUMB_IT_SIGRENDERER *sr, int tempo) { + warning("TODO: dumb_it_sr_set_tempo"); +} + +int dumb_it_sr_get_speed(DUMB_IT_SIGRENDERER *sr) { + warning("TODO: dumb_it_sr_get_speed"); + return 0; +} + +void dumb_it_sr_set_speed(DUMB_IT_SIGRENDERER *sr, int speed) { + warning("TODO: dumb_it_sr_set_speed"); +} + +void unload_duh(DUH *duh) { + warning("TODO: unload_duh"); +} + +DUH *load_duh(const char *filename) { + warning("TODO: load_duh"); + return nullptr; +} + +DUH *read_duh(DUMBFILE *f) { + warning("TODO: load_duh"); + return nullptr; +} + +long duh_get_length(DUH *duh) { + warning("TODO: duh_get_length"); + return 0; +} + +void duh_end_sigrenderer(DUH_SIGRENDERER *sigrenderer) { + warning("TODO: duh_end_sigrenderer"); +} + + +} // namespace AGS3 diff --git a/engines/ags/lib/dumb-0.9.2/dumbfile.h b/engines/ags/lib/dumb-0.9.2/dumb.h similarity index 100% rename from engines/ags/lib/dumb-0.9.2/dumbfile.h rename to engines/ags/lib/dumb-0.9.2/dumb.h diff --git a/engines/ags/lib/dumb-0.9.2/dumbfile.cpp b/engines/ags/lib/dumb-0.9.2/dumbfile.cpp index 60d82b5801c6..496d26935d3c 100644 --- a/engines/ags/lib/dumb-0.9.2/dumbfile.cpp +++ b/engines/ags/lib/dumb-0.9.2/dumbfile.cpp @@ -41,7 +41,7 @@ //include -#include "ags/lib/dumb-0.9.2/dumbfile.h" +#include "ags/lib/dumb-0.9.2/dumb.h" namespace AGS3 { diff --git a/engines/ags/lib/dumb-0.9.2/helpers/clickrem.cpp b/engines/ags/lib/dumb-0.9.2/helpers/clickrem.cpp new file mode 100644 index 000000000000..11bb8814f827 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/helpers/clickrem.cpp @@ -0,0 +1,278 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * clickrem.c - Click removal helpers. / / \ \ + * | < / \_ + * By entheh. | \/ /\ / + * \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include "ags/lib/dumb-0.9.2/dumb.h" + +namespace AGS3 { + +typedef struct DUMB_CLICK DUMB_CLICK; + + +struct DUMB_CLICK_REMOVER { + DUMB_CLICK *click; + int n_clicks; + + int offset; +}; + + +struct DUMB_CLICK { + DUMB_CLICK *next; + long pos; + sample_t step; +}; + + + +DUMB_CLICK_REMOVER *dumb_create_click_remover(void) { + DUMB_CLICK_REMOVER *cr = (DUMB_CLICK_REMOVER *)malloc(sizeof(*cr)); + if (!cr) return NULL; + + cr->click = NULL; + cr->n_clicks = 0; + + cr->offset = 0; + + return cr; +} + + + +void dumb_record_click(DUMB_CLICK_REMOVER *cr, long pos, sample_t step) { + DUMB_CLICK *click; + + ASSERT(pos >= 0); + + if (!cr || !step) return; + + if (pos == 0) { + cr->offset -= step; + return; + } + + click = (DUMB_CLICK *)malloc(sizeof(*click)); + if (!click) return; + + click->pos = pos; + click->step = step; + + click->next = cr->click; + cr->click = click; + cr->n_clicks++; +} + + + +static DUMB_CLICK *dumb_click_mergesort(DUMB_CLICK *click, int n_clicks) { + int i; + DUMB_CLICK *c1, *c2, **cp; + + if (n_clicks <= 1) return click; + + /* Split the list into two */ + c1 = click; + cp = &c1; + for (i = 0; i < n_clicks; i += 2) cp = &(*cp)->next; + c2 = *cp; + *cp = NULL; + + /* Sort the sublists */ + c1 = dumb_click_mergesort(c1, (n_clicks + 1) >> 1); + c2 = dumb_click_mergesort(c2, n_clicks >> 1); + + /* Merge them */ + cp = &click; + while (c1 && c2) { + if (c1->pos > c2->pos) { + *cp = c2; + c2 = c2->next; + } else { + *cp = c1; + c1 = c1->next; + } + cp = &(*cp)->next; + } + if (c2) + *cp = c2; + else + *cp = c1; + + return click; +} + + + +void dumb_remove_clicks(DUMB_CLICK_REMOVER *cr, sample_t *samples, long length, float halflife) { + DUMB_CLICK *click; + long pos = 0; + int offset; + int factor; + + if (!cr) return; + + factor = (int)floor(pow(0.5, 1.0 / halflife) * (1U << 31)); + + click = dumb_click_mergesort(cr->click, cr->n_clicks); + cr->click = NULL; + cr->n_clicks = 0; + + while (click) { + DUMB_CLICK *next = click->next; + ASSERT(click->pos <= length); + offset = cr->offset; + if (offset < 0) { + offset = -offset; + while (pos < click->pos) { + samples[pos++] -= offset; + offset = (int)((LONG_LONG)(offset << 1) * factor >> 32); + } + offset = -offset; + } else { + while (pos < click->pos) { + samples[pos++] += offset; + offset = (int)((LONG_LONG)(offset << 1) * factor >> 32); + } + } + cr->offset = offset - click->step; + free(click); + click = next; + } + + offset = cr->offset; + if (offset < 0) { + offset = -offset; + while (pos < length) { + samples[pos++] -= offset; + offset = (int)((LONG_LONG)(offset << 1) * factor >> 32); + } + offset = -offset; + } else { + while (pos < length) { + samples[pos++] += offset; + offset = (int)((LONG_LONG)(offset << 1) * factor >> 32); + } + } + cr->offset = offset; +} + + + +sample_t dumb_click_remover_get_offset(DUMB_CLICK_REMOVER *cr) { + return cr ? cr->offset : 0; +} + + + +void dumb_destroy_click_remover(DUMB_CLICK_REMOVER *cr) { + if (cr) { + DUMB_CLICK *click = cr->click; + while (click) { + DUMB_CLICK *next = click->next; + free(click); + click = next; + } + free(cr); + } +} + + + +DUMB_CLICK_REMOVER **dumb_create_click_remover_array(int n) { + int i; + DUMB_CLICK_REMOVER **cr; + if (n <= 0) return NULL; + cr = (DUMB_CLICK_REMOVER **)malloc(n * sizeof(*cr)); + if (!cr) return NULL; + for (i = 0; i < n; i++) cr[i] = dumb_create_click_remover(); + return cr; +} + + + +void dumb_record_click_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step) { + if (cr) { + int i; + for (i = 0; i < n; i++) + dumb_record_click(cr[i], pos, step[i]); + } +} + + + +void dumb_record_click_negative_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step) { + if (cr) { + int i; + for (i = 0; i < n; i++) + dumb_record_click(cr[i], pos, -step[i]); + } +} + + + +void dumb_remove_clicks_array(int n, DUMB_CLICK_REMOVER **cr, sample_t **samples, long length, float halflife) { + if (cr) { + int i; + for (i = 0; i < n; i++) + dumb_remove_clicks(cr[i], samples[i], length, halflife); + } +} + + + +void dumb_click_remover_get_offset_array(int n, DUMB_CLICK_REMOVER **cr, sample_t *offset) { + if (cr) { + int i; + for (i = 0; i < n; i++) + if (cr[i]) offset[i] += cr[i]->offset; + } +} + + + +void dumb_destroy_click_remover_array(int n, DUMB_CLICK_REMOVER **cr) { + if (cr) { + int i; + for (i = 0; i < n; i++) dumb_destroy_click_remover(cr[i]); + free(cr); + } +} + +} // namespace AGS3 diff --git a/engines/ags/lib/dumb-0.9.2/helpers/memfile.c b/engines/ags/lib/dumb-0.9.2/helpers/memfile.c new file mode 100644 index 000000000000..b65ab5f78dc9 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/helpers/memfile.c @@ -0,0 +1,96 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * memfile.c - Module for reading data from / / \ \ + * memory using a DUMBFILE. | < / \_ + * | \/ /\ / + * By entheh. \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include +#include + +#include "dumb.h" + + + +typedef struct MEMFILE MEMFILE; + +struct MEMFILE +{ + const char *ptr; + long left; +}; + + + +static int dumb_memfile_skip(void *f, long n) +{ + MEMFILE *m = f; + if (n > m->left) return -1; + m->ptr += n; + m->left -= n; + return 0; +} + + + +static int dumb_memfile_getc(void *f) +{ + MEMFILE *m = f; + if (m->left <= 0) return -1; + m->left--; + return *(const unsigned char *)m->ptr++; +} + + + +static long dumb_memfile_getnc(char *ptr, long n, void *f) +{ + MEMFILE *m = f; + if (n > m->left) n = m->left; + memcpy(ptr, m->ptr, n); + m->ptr += n; + m->left -= n; + return n; +} + + + +static void dumb_memfile_close(void *f) +{ + free(f); +} + + + +static DUMBFILE_SYSTEM memfile_dfs = { + NULL, + &dumb_memfile_skip, + &dumb_memfile_getc, + &dumb_memfile_getnc, + &dumb_memfile_close +}; + + + +DUMBFILE *dumbfile_open_memory(const char *data, long size) +{ + MEMFILE *m = malloc(sizeof(*m)); + if (!m) return NULL; + + m->ptr = data; + m->left = size; + + return dumbfile_open_ex(m, &memfile_dfs); +} diff --git a/engines/ags/lib/dumb-0.9.2/helpers/resample.c b/engines/ags/lib/dumb-0.9.2/helpers/resample.c new file mode 100644 index 000000000000..d8b238fc718e --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/helpers/resample.c @@ -0,0 +1,1177 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * resample.c - Resampling helper. / / \ \ + * | < / \_ + * By Bob and entheh. | \/ /\ / + * \_ / > / + * In order to find a good trade-off between | \ / / + * speed and accuracy in this code, some tests | ' / + * were carried out regarding the behaviour of \__/ + * long long ints with gcc. The following code + * was tested: + * + * int a, b, c; + * c = ((long long)a * b) >> 16; + * + * DJGPP GCC Version 3.0.3 generated the following assembly language code for + * the multiplication and scaling, leaving the 32-bit result in EAX. + * + * movl -8(%ebp), %eax ; read one int into EAX + * imull -4(%ebp) ; multiply by the other; result goes in EDX:EAX + * shrdl $16, %edx, %eax ; shift EAX right 16, shifting bits in from EDX + * + * Note that a 32*32->64 multiplication is performed, allowing for high + * accuracy. On the Pentium 2 and above, shrdl takes two cycles (generally), + * so it is a minor concern when four multiplications are being performed + * (the cubic resampler). On the Pentium MMX and earlier, it takes four or + * more cycles, so this method is unsuitable for use in the low-quality + * resamplers. + * + * Since "long long" is a gcc-specific extension, we use LONG_LONG instead, + * defined in dumb.h. We may investigate later what code MSVC generates, but + * if it seems too slow then we suggest you use a good compiler. + * + * FIXME: these comments are somewhat out of date now. + */ + +#include +#include "dumb.h" + + + +/* Compile with -DHEAVYDEBUG if you want to make sure the pick-up function is + * called when it should be. There will be a considerable performance hit, + * since at least one condition has to be tested for every sample generated. + */ +#ifdef HEAVYDEBUG +#define HEAVYASSERT(cond) ASSERT(cond) +#else +#define HEAVYASSERT(cond) +#endif + + + +//#define MULSC(a, b) ((int)((LONG_LONG)(a) * (b) >> 16)) +//#define MULSC(a, b) ((a) * ((b) >> 2) >> 14) +#define MULSC(a, b) ((int)((LONG_LONG)((a) << 4) * ((b) << 12) >> 32)) + + + +/* A global variable for controlling resampling quality wherever a local + * specification doesn't override it. The following values are valid: + * + * 0 - DUMB_RQ_ALIASING - fastest + * 1 - DUMB_RQ_LINEAR + * 2 - DUMB_RQ_CUBIC - nicest + * + * Values outside the range 0-2 will behave the same as the nearest + * value within the range. + */ +int dumb_resampling_quality = 2; + + + +void dumb_reset_resampler(DUMB_RESAMPLER *resampler, sample_t *src, long pos, long start, long end) +{ + resampler->src = src; + resampler->pos = pos; + resampler->subpos = 0; + resampler->start = start; + resampler->end = end; + resampler->dir = 1; + resampler->pickup = NULL; + resampler->pickup_data = NULL; + resampler->min_quality = 0; + resampler->max_quality = DUMB_RQ_N_LEVELS - 1; + resampler->x[2] = resampler->x[1] = resampler->x[0] = 0; + resampler->overshot = -1; +} + + + +DUMB_RESAMPLER *dumb_start_resampler(sample_t *src, long pos, long start, long end) +{ + DUMB_RESAMPLER *resampler = malloc(sizeof(*resampler)); + if (!resampler) return NULL; + dumb_reset_resampler(resampler, src, pos, start, end); + return resampler; +} + + + +/* For convenience, returns nonzero on stop. */ +static int process_pickup(DUMB_RESAMPLER *resampler) +{ + if (resampler->overshot < 0) { + resampler->overshot = 0; + dumb_resample(resampler, NULL, 2, 0, 1.0f); + resampler->x[0] = resampler->x[1]; + } + + for (;;) { + if (resampler->dir < 0) { + if (resampler->overshot >= 3 && resampler->pos+3 >= resampler->start) resampler->x[0] = resampler->src[resampler->pos+3]; + if (resampler->overshot >= 2 && resampler->pos+2 >= resampler->start) resampler->x[1] = resampler->src[resampler->pos+2]; + if (resampler->overshot >= 1 && resampler->pos+1 >= resampler->start) resampler->x[2] = resampler->src[resampler->pos+1]; + resampler->overshot = resampler->start - resampler->pos - 1; + } else { + if (resampler->overshot >= 3 && resampler->pos-3 < resampler->end) resampler->x[0] = resampler->src[resampler->pos-3]; + if (resampler->overshot >= 2 && resampler->pos-2 < resampler->end) resampler->x[1] = resampler->src[resampler->pos-2]; + if (resampler->overshot >= 1 && resampler->pos-1 < resampler->end) resampler->x[2] = resampler->src[resampler->pos-1]; + resampler->overshot = resampler->pos - resampler->end; + } + + if (resampler->overshot < 0) { + resampler->overshot = 0; + return 0; + } + + if (!resampler->pickup) { + resampler->dir = 0; + return 1; + } + (*resampler->pickup)(resampler, resampler->pickup_data); + if (resampler->dir == 0) return 1; + ASSERT(resampler->dir == -1 || resampler->dir == 1); + } +} + + + +/* Executes the content 'iterator' times. + * Clobbers the 'iterator' variable. + * The loop is unrolled by four. + */ +#define LOOP4(iterator, CONTENT) \ +{ \ + if ((iterator) & 2) { \ + CONTENT; \ + CONTENT; \ + } \ + if ((iterator) & 1) { \ + CONTENT; \ + } \ + (iterator) >>= 2; \ + while (iterator) { \ + CONTENT; \ + CONTENT; \ + CONTENT; \ + CONTENT; \ + (iterator)--; \ + } \ +} + + + +long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta) +{ + int dt; + int vol; + long done; + long todo; + int quality; + + if (!resampler || resampler->dir == 0) return 0; + ASSERT(resampler->dir == -1 || resampler->dir == 1); + + done = 0; + dt = (int)(delta * 65536.0 + 0.5); + vol = (int)floor(volume * 65536.0 + 0.5); + + if (vol == 0) dst = NULL; + + quality = dumb_resampling_quality; + if (quality > resampler->max_quality) quality = resampler->max_quality; + else if (quality < resampler->min_quality) quality = resampler->min_quality; + + while (done < dst_size) { + if (process_pickup(resampler)) return done; + + if ((resampler->dir ^ dt) < 0) + dt = -dt; + + if (resampler->dir < 0) + todo = (long)((((LONG_LONG)(resampler->pos - resampler->start) << 16) + resampler->subpos - dt) / -dt); + else + todo = (long)((((LONG_LONG)(resampler->end - resampler->pos) << 16) - resampler->subpos - 1 + dt) / dt); + + if (todo < 0) + todo = 0; + else if (todo > dst_size - done) + todo = dst_size - done; + + done += todo; + + { + sample_t *src = resampler->src; + long pos = resampler->pos; + int subpos = resampler->subpos; + long diff = pos; + long overshot; + if (resampler->dir < 0) { + if (!dst) { + /* Silence or simulation */ + LONG_LONG new_subpos = subpos + dt * todo; + pos += (long)(new_subpos >> 16); + subpos = (long)new_subpos & 65535; + } else if (quality <= DUMB_RQ_ALIASING) { + /* Aliasing, backwards */ + sample_t xbuf[2]; + sample_t *x = &xbuf[0]; + sample_t *xstart; + xbuf[0] = resampler->x[1]; + xbuf[1] = resampler->x[2]; + while (todo && x < &xbuf[2]) { + HEAVYASSERT(pos >= resampler->start); + *dst++ += MULSC(x[0], vol); + subpos += dt; + pos += subpos >> 16; + x -= subpos >> 16; + subpos &= 65535; + todo--; + } + x = xstart = &src[pos]; + LOOP4(todo, + *dst++ += MULSC(x[2], vol); + subpos += dt; + x += subpos >> 16; + subpos &= 65535; + ); + pos += x - xstart; + } else if (quality <= DUMB_RQ_LINEAR) { + /* Linear interpolation, backwards */ + sample_t xbuf[3]; + sample_t *x = &xbuf[1]; + xbuf[0] = resampler->x[1]; + xbuf[1] = resampler->x[2]; + xbuf[2] = src[pos]; + while (todo && x < &xbuf[3]) { + HEAVYASSERT(pos >= resampler->start); + *dst++ += MULSC(x[0] + MULSC(x[-1] - x[0], subpos), vol); + subpos += dt; + pos += subpos >> 16; + x -= subpos >> 16; + subpos &= 65535; + todo--; + } + x = &src[pos]; + LOOP4(todo, + HEAVYASSERT(pos >= resampler->start); + *dst++ += MULSC(x[1] + MULSC(x[2] - x[1], subpos), vol); + subpos += dt; + pos += subpos >> 16; + x += subpos >> 16; + subpos &= 65535; + ); + } else { + /* Cubic interpolation, backwards */ + sample_t xbuf[6]; + sample_t *x = &xbuf[3]; + sample_t *lastx = NULL; + int a = 0, b = 0, c = 0; + xbuf[0] = resampler->x[0]; + xbuf[1] = resampler->x[1]; + xbuf[2] = resampler->x[2]; + xbuf[3] = src[pos]; + if (pos-1 >= resampler->start) xbuf[4] = src[pos-1]; + if (pos-2 >= resampler->start) xbuf[5] = src[pos-2]; + while (todo && x < &xbuf[6]) { + HEAVYASSERT(pos >= resampler->start); + if (lastx != x) { + lastx = x; + a = (((x[-1] - x[-2]) << 1) + (x[-1] - x[-2]) + (x[-3] - x[0])) >> 1; + b = (x[-2] << 1) + x[0] - ((5 * x[-1] + x[-3]) >> 1); + c = (x[-2] - x[0]) >> 1; + } + *dst++ += MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + x[-1], vol); + subpos += dt; + pos += subpos >> 16; + x -= subpos >> 16; + subpos &= 65535; + todo--; + } + x = &src[pos]; + lastx = NULL; + LOOP4(todo, + HEAVYASSERT(pos >= resampler->start); + if (lastx != x) { + lastx = x; + a = (((x[1] - x[2]) << 1) + (x[1] - x[2]) + (x[3] - x[0])) >> 1; + b = (x[2] << 1) + x[0] - ((5 * x[1] + x[3]) >> 1); + c = (x[2] - x[0]) >> 1; + } + *dst++ += MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + x[1], vol); + subpos += dt; + pos += subpos >> 16; + x += subpos >> 16; + subpos &= 65535; + ); + } + diff = diff - pos; + overshot = resampler->start - pos - 1; + if (diff >= 3) { + resampler->x[0] = overshot >= 3 ? 0 : src[pos+3]; + resampler->x[1] = overshot >= 2 ? 0 : src[pos+2]; + resampler->x[2] = overshot >= 1 ? 0 : src[pos+1]; + } else if (diff >= 2) { + resampler->x[0] = resampler->x[2]; + resampler->x[1] = overshot >= 2 ? 0 : src[pos+2]; + resampler->x[2] = overshot >= 1 ? 0 : src[pos+1]; + } else if (diff >= 1) { + resampler->x[0] = resampler->x[1]; + resampler->x[1] = resampler->x[2]; + resampler->x[2] = overshot >= 1 ? 0 : src[pos+1]; + } + } else { + if (!dst) { + /* Silence or simulation */ + LONG_LONG new_subpos = subpos + dt * todo; + pos += (long)(new_subpos >> 16); + subpos = (long)new_subpos & 65535; + } else if (dumb_resampling_quality <= DUMB_RQ_ALIASING) { + /* Aliasing, forwards */ + sample_t xbuf[2]; + sample_t *x = &xbuf[0]; + sample_t *xstart; + xbuf[0] = resampler->x[1]; + xbuf[1] = resampler->x[2]; + while (todo && x < &xbuf[2]) { + HEAVYASSERT(pos < resampler->end); + *dst++ += MULSC(x[0], vol); + subpos += dt; + pos += subpos >> 16; + x += subpos >> 16; + subpos &= 65535; + todo--; + } + x = xstart = &src[pos]; + LOOP4(todo, + *dst++ += MULSC(x[-2], vol); + subpos += dt; + x += subpos >> 16; + subpos &= 65535; + ); + pos += x - xstart; + } else if (dumb_resampling_quality <= DUMB_RQ_LINEAR) { + /* Linear interpolation, forwards */ + sample_t xbuf[3]; + sample_t *x = &xbuf[1]; + xbuf[0] = resampler->x[1]; + xbuf[1] = resampler->x[2]; + xbuf[2] = src[pos]; + while (todo && x < &xbuf[3]) { + HEAVYASSERT(pos < resampler->end); + *dst++ += MULSC(x[-1] + MULSC(x[0] - x[-1], subpos), vol); + subpos += dt; + pos += subpos >> 16; + x += subpos >> 16; + subpos &= 65535; + todo--; + } + x = &src[pos]; + LOOP4(todo, + HEAVYASSERT(pos < resampler->end); + *dst++ += MULSC(x[-2] + MULSC(x[-1] - x[-2], subpos), vol); + subpos += dt; + pos += subpos >> 16; + x += subpos >> 16; + subpos &= 65535; + ); + } else { + /* Cubic interpolation, forwards */ + sample_t xbuf[6]; + sample_t *x = &xbuf[3]; + sample_t *lastx = NULL; + int a = 0, b = 0, c = 0; + xbuf[0] = resampler->x[0]; + xbuf[1] = resampler->x[1]; + xbuf[2] = resampler->x[2]; + xbuf[3] = src[pos]; + if (pos+1 < resampler->end) xbuf[4] = src[pos+1]; + if (pos+2 < resampler->end) xbuf[5] = src[pos+2]; + while (todo && x < &xbuf[6]) { + HEAVYASSERT(pos < resampler->end); + if (lastx != x) { + lastx = x; + a = (((x[-2] - x[-1]) << 1) + (x[-2] - x[-1]) + (x[0] - x[-3])) >> 1; + b = (x[-1] << 1) + x[-3] - ((5 * x[-2] + x[0]) >> 1); + c = (x[-1] - x[-3]) >> 1; + } + *dst++ += MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + x[-2], vol); + subpos += dt; + pos += subpos >> 16; + x += subpos >> 16; + subpos &= 65535; + todo--; + } + x = &src[pos]; + lastx = NULL; + LOOP4(todo, + HEAVYASSERT(pos < resampler->end); + if (lastx != x) { + lastx = x; + a = (((x[-2] - x[-1]) << 1) + (x[-2] - x[-1]) + (x[0] - x[-3])) >> 1; + b = (x[-1] << 1) + x[-3] - ((5 * x[-2] + x[0]) >> 1); + c = (x[-1] - x[-3]) >> 1; + } + *dst++ += MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + x[-2], vol); + subpos += dt; + pos += subpos >> 16; + x += subpos >> 16; + subpos &= 65535; + ); + } + diff = pos - diff; + overshot = pos - resampler->end; + if (diff >= 3) { + resampler->x[0] = overshot >= 3 ? 0 : src[pos-3]; + resampler->x[1] = overshot >= 2 ? 0 : src[pos-2]; + resampler->x[2] = overshot >= 1 ? 0 : src[pos-1]; + } else if (diff >= 2) { + resampler->x[0] = resampler->x[2]; + resampler->x[1] = overshot >= 2 ? 0 : src[pos-2]; + resampler->x[2] = overshot >= 1 ? 0 : src[pos-1]; + } else if (diff >= 1) { + resampler->x[0] = resampler->x[1]; + resampler->x[1] = resampler->x[2]; + resampler->x[2] = overshot >= 1 ? 0 : src[pos-1]; + } + } + resampler->pos = pos; + resampler->subpos = subpos; + } + } + + return done; +} + + + +sample_t dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, float volume) +{ + int vol; + sample_t *src; + long pos; + int subpos; + int quality; + + if (!resampler || resampler->dir == 0) return 0; + ASSERT(resampler->dir == -1 || resampler->dir == 1); + + if (process_pickup(resampler)) return 0; + + vol = (int)floor(volume * 65536.0 + 0.5); + if (vol == 0) return 0; + + quality = dumb_resampling_quality; + if (quality > resampler->max_quality) quality = resampler->max_quality; + else if (quality < resampler->min_quality) quality = resampler->min_quality; + + src = resampler->src; + pos = resampler->pos; + subpos = resampler->subpos; + + if (resampler->dir < 0) { + HEAVYASSERT(pos >= resampler->start); + if (dumb_resampling_quality <= 0) { + /* Aliasing, backwards */ + return MULSC(src[pos], vol); + } else if (quality <= DUMB_RQ_LINEAR) { + /* Linear interpolation, backwards */ + return MULSC(resampler->x[2] + MULSC(resampler->x[1] - resampler->x[2], subpos), vol); + } else { + /* Cubic interpolation, backwards */ + sample_t *x = resampler->x; + int a, b, c; + a = (((x[2] - x[1]) << 1) + (x[2] - x[1]) + (x[0] - src[pos])) >> 1; + b = (x[1] << 1) + src[pos] - ((5 * x[2] + x[0]) >> 1); + c = (x[1] - src[pos]) >> 1; + return MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + x[2], vol); + } + } else { + HEAVYASSERT(pos < resampler->end); + if (dumb_resampling_quality <= 0) { + /* Aliasing */ + return MULSC(src[pos], vol); + } else if (dumb_resampling_quality <= DUMB_RQ_LINEAR) { + /* Linear interpolation, forwards */ + return MULSC(resampler->x[1] + MULSC(resampler->x[2] - resampler->x[1], subpos), vol); + } else { + /* Cubic interpolation, forwards */ + sample_t *x = resampler->x; + int a, b, c; + a = (((x[1] - x[2]) << 1) + (x[1] - x[2]) + (src[pos] - x[0])) >> 1; + b = (x[2] << 1) + x[0] - ((5 * x[1] + src[pos]) >> 1); + c = (x[2] - x[0]) >> 1; + return MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + x[1], vol); + } + } +} + + + +void dumb_end_resampler(DUMB_RESAMPLER *resampler) +{ + if (resampler) + free(resampler); +} + + + +#if 0 +/* The following macro is used to overcome the fact that most C + * compilers (including gcc and MSVC) can't correctly multiply signed + * integers outside the range -32768 to 32767. i86 assembler versions + * don't need to use this method, since the processor does in fact + * have instructions to multiply large numbers correctly - which + * means using assembly language could make a significant difference + * to the speed. + * + * The basic method is as follows. We halve the subposition (how far + * we are between samples), so it never exceeds 32767. We also halve + * the delta, which is the amount to be added to the subposition each + * time. Then we unroll the loop twofold, so that we can add the lost + * one every other time if necessary (since the halving may have + * resulted in rounding down). + * + * This method doesn't incur any cumulative inaccuracies. There is a + * very slight loss of quality, which I challenge anyone to notice - + * but the position will advance at *exactly* the same rate as it + * would if we didn't use this method. This also means the pitch is + * exactly the same, which may even make a difference to trained + * musicians when resampling down a lot :) + * + * Each time this macro is invoked, DO_RESAMPLE(inc) must be defined + * to calculate the samples by the appropriate equation (linear, + * cubic, etc.). See the individual cases for examples of how this is + * done. + */ +#define MAKE_RESAMPLER() \ +{ \ + if (dt & 1) { \ + long todo2; \ + \ + dt >>= 1; \ + \ + if (src_subpos & 1) { \ + src_subpos >>= 1; \ + DO_RESAMPLE(1); \ + todo--; \ + } else \ + src_subpos >>= 1; \ + \ + todo2 = todo >> 1; \ + \ + while (todo2) { \ + DO_RESAMPLE(0); \ + DO_RESAMPLE(1); \ + todo2--; \ + } \ + \ + if (todo & 1) { \ + DO_RESAMPLE(0); \ + src_subpos = (src_subpos << 1) | 1; \ + } else \ + src_subpos <<= 1; \ + \ + todo = 0; \ + dt = (dt << 1) | 1; \ + } else { \ + long subposbit = src_subpos & 1; \ + dt >>= 1; \ + src_subpos >>= 1; \ + \ + if (todo & 1) { \ + DO_RESAMPLE(0); \ + } \ + \ + todo >>= 1; \ + \ + while (todo) { \ + DO_RESAMPLE(0); \ + DO_RESAMPLE(0); \ + todo--; \ + } \ + \ + src_subpos = (src_subpos << 1) | subposbit; \ + dt <<= 1; \ + } \ +} + + + +sample_t dumb_resample_get_current_sample( + sample_t *src, long *_src_pos, int *_src_subpos, + long src_start, long src_end, + float volume, int *_dir, + DUMB_RESAMPLE_PICKUP pickup, void *pickup_data +) +{ + long src_pos = *_src_pos; + int src_subpos = *_src_subpos; + int dir = _dir ? *_dir : 1; + + sample_t value = 0; + + if (dir == 0) + return 0; + + ASSERT(dir == 1 || dir == -1); + + if (dir < 0 ? (src_pos < src_start) : (src_pos >= src_end)) { + + /* If there's no pick-up function, we stop. */ + if (!pickup) { + dir = 0; + goto end; + } + + /* Process the pick-up. It may need invoking more than once. */ + do { + dir = (*pickup)(src, &src_pos, &src_subpos, &src_start, &src_end, dir, pickup_data); + + if (dir == 0) + goto end; + + ASSERT(dir == 1 || dir == -1); + } while (dir < 0 ? (src_pos < src_start) : (src_pos >= src_end)); + } + + HEAVYASSERT(dir < 0 ? (src_pos >= src_start) : (src_pos < src_end)); + + if (dumb_resampling_quality == 0) { + /* Aliasing (coarse) */ + int volume_fact = (int)(volume * 16384.0); + value = (src[src_pos] * volume_fact) >> 14; + } else if (dumb_resampling_quality <= 2) { + /* Linear interpolation */ + int volume_fact = (int)(volume * 16384.0); + int subpos = src_subpos >> 1; + value = ((src[src_pos] + ((((src[src_pos + 1] - src[src_pos]) >> 1) * subpos) >> 14)) * volume_fact) >> 14; + } else if (dumb_resampling_quality == 3) { + /* Quadratic interpolation */ + int volume_fact = (int)(volume * 16384.0); + int a, b; + sample_t *x; + int subpos = src_subpos >> 1; + x = &src[src_pos]; + a = ((x[0] + x[2]) >> 1) - x[1]; + b = ((x[2] - x[0]) >> 1) - (a << 1); + value = (((((((a * subpos) >> 15) + b) * subpos) >> 15) + x[0]) * volume_fact) >> 14; + } else { + /* Cubic interpolation */ + int volume_fact = (int)(volume * 16384.0); + int a, b, c; + sample_t *x; + int subpos = src_subpos >> 1; + x = &src[src_pos]; + a = (((x[1] - x[2]) << 1) + (x[1] - x[2]) + (x[3] - x[0])) >> 1; + b = (x[2] << 1) + x[0] - ((5 * x[1] + x[3]) >> 1); + c = (x[2] - x[0]) >> 1; + value = (((int)(((LONG_LONG)((int)(((LONG_LONG)((int)(((LONG_LONG)a * subpos) >> 15) + b) * subpos) >> 15) + c) * subpos) >> 15) + x[1]) * volume_fact) >> 14; + } + + end: + + *_src_pos = src_pos; + *_src_subpos = src_subpos; + if (_dir) *_dir = dir; + + return value; +} + + + +long dumb_resample( + sample_t *src, long *_src_pos, int *_src_subpos, + long src_start, long src_end, + sample_t *dst, long dst_size, + float volume, float delta, int *_dir, + DUMB_RESAMPLE_PICKUP pickup, void *pickup_data +) +{ + int dt = (int)(delta * 65536.0 + 0.5); + long s = 0; /* Current position in the destination buffer */ + + long src_pos = *_src_pos; + int src_subpos = *_src_subpos; + int dir = _dir ? *_dir : 1; + + int linear_average; + + if (dir == 0) + return 0; + + ASSERT(dir == 1 || dir == -1); + + linear_average = dst && dumb_resampling_quality >= 2 && dt > 65536; + + if (dir < 0) dt = -dt; + + if (linear_average) + volume /= delta; + + while (s < dst_size) { + + long todo; + + /* Process pick-ups first, just in case. */ + + if (linear_average) { + + /* For linear average, the pick-up point could split a sum into + * two parts. We handle this by putting the pick-up code inside + * the summing loop. Note that this code is only executed when we + * know that a pick-up is necessary somewhere during this sum + * (although it is always executed once for the first sample). + * We use a separate loop further down when we know we won't have + * to do a pick-up, so the condition does not need testing inside + * the loop. + */ + + float sum; + long i; + int advance; + int x[3]; + + advance = src_subpos + dt; + + /* Make these negative. Then they stay within the necessary + * range for integer multiplication, -32768 to 32767 ;) + */ + x[0] = ~(src_subpos >> 1); /* = -1 - (src_subpos >> 1) */ + x[2] = x[0] ^ 0x7FFF; /* = -32768 + (src_subpos >> 1) */ + + sum = (float)(-((src[src_pos] * (x+1)[dir]) >> 15)); + + i = src_pos + (advance >> 16); + src_pos += dir; + src_subpos = (dir >> 1) & 65535; /* changes 1,-1 to 0,65535 */ + + advance &= 65535; + + /* i is the index of the first sample NOT to sum fully, + * regardless of the direction of resampling. + */ + + while (dir < 0 ? (i < src_start) : (i >= src_end)) { + if (dir < 0) { + while (src_pos >= src_start) + sum += src[src_pos--]; + } else { + while (src_pos < src_end) + sum += src[src_pos++]; + } + + i -= src_pos; + /* i is now the number of samples left to sum fully, except + * it's negative if we're going backwards. + */ + + if (!pickup) { + dir = 0; + goto endsum; + } + + dir = (*pickup)(src, &src_pos, &src_subpos, &src_start, &src_end, dir, pickup_data); + + if (dir == 0) + goto endsum; + + ASSERT(dir == 1 || dir == -1); + + if ((dir ^ dt) < 0) { + dt = -dt; + advance ^= 65535; + i = -i; + } + + i += src_pos; + /* There, i is back to normal. */ + } + + for (; src_pos != i; src_pos += dir) + sum += src[src_pos]; + + src_subpos = advance; + + x[2] = src_subpos >> 1; + x[0] = x[2] ^ 0x7FFF; /* = 32767 - (src_subpos >> 1) */ + + sum += (src[src_pos] * (x+1)[dir]) >> 15; + + endsum: + + sum *= volume; + dst[s] += (int)sum; + + s++; + + if (dir == 0) + break; + + } else if (dir < 0 ? (src_pos < src_start) : (src_pos >= src_end)) { + + /* If there's no pick-up function, we stop. */ + if (!pickup) { + dir = 0; + break; + } + + /* Process the pick-up. It may need invoking more than once. */ + do { + dir = (*pickup)(src, &src_pos, &src_subpos, &src_start, &src_end, dir, pickup_data); + + if (dir == 0) + goto end; + + ASSERT(dir == 1 || dir == -1); + } while (dir < 0 ? (src_pos < src_start) : (src_pos >= src_end)); + + /* Update sign of dt to match that of dir. */ + if ((dir ^ dt) < 0) + dt = -dt; + } + + /* Work out how many contiguous samples we can now render. */ + if (dir < 0) + todo = (long)((((LONG_LONG)(src_pos - src_start) << 16) + src_subpos) / -dt); + else + todo = (long)((((LONG_LONG)(src_end - src_pos) << 16) - src_subpos - 1) / dt); + + /* The above equations work out how many complete dt-sized + * intervals there are between the current position and the loop + * point (provided there is a little fractional extra). The linear + * average function needs complete intervals - but the other + * resamplers only read a sample from the beginning of each interval, + * so they can process one extra sample in their main loops (so we + * increment todo in a moment). + * + * The linear average function makes up the extra sample using the + * specialised pick-up code above. + * + * Note that our above pick-up process should have absolutely ensured + * that the result of this function will be nonnegative. + */ + + ASSERT(todo >= 0); + + if (!linear_average) + todo++; + + /* Of course we don't want to overrun the output buffer! */ + if (todo > dst_size - s) + todo = dst_size - s; + + if (!dst) { + + LONG_LONG t = src_subpos + (LONG_LONG)dt * todo; + src_pos += (long)(t >> 16); + src_subpos = (int)t & 0xFFFFl; + + s += todo; + + } else if (linear_average) { + + float sum; + long i; + int advance; + int x[3]; + + while (todo) { + + advance = src_subpos + dt; + + /* Make these negative. Then they stay within the necessary + * range for integer multiplication, -32768 to 32767 ;) + */ + x[0] = ~(src_subpos >> 1); /* = -1 - (src_subpos >> 1) */ + x[2] = x[0] ^ 0x7FFF; /* = -32768 + (src_subpos >> 1) */ + + sum = (float)(-((src[src_pos] * (x+1)[dir]) >> 15)); + + i = src_pos + (advance >> 16); + src_pos += dir; + src_subpos = (dir >> 1) & 65535; /* changes 1,-1 to 0,65535 */ + + advance &= 65535; + + /* i is the index of the first sample NOT to sum fully, + * regardless of the direction of resampling. + */ + + HEAVYASSERT(dir < 0 ? (i >= src_start) : (i < src_end)); + + for (; src_pos != i; src_pos += dir) + sum += src[src_pos]; + + src_subpos = advance; + + x[2] = src_subpos >> 1; + x[0] = x[2] ^ 0x7FFF; /* = 32767 - (src_subpos >> 1) */ + + sum += (src[src_pos] * (x+1)[dir]) >> 15; + + sum *= volume; + dst[s] += (int)sum; + + s++; + todo--; + } + + } else if (dumb_resampling_quality == 0 || (dumb_resampling_quality == 1 && delta >= 1.0)) { + + /* Aliasing (coarse) */ + int volume_fact = (int)(volume * 16384.0); + + do { + HEAVYASSERT(dir < 0 ? (src_pos >= src_start) : (src_pos < src_end)); + dst[s] += ((src[src_pos] * volume_fact) >> 14); + src_subpos += dt; + src_pos += src_subpos >> 16; + src_subpos &= 0xFFFFl; + s++; + } while (--todo); + + } else if (dumb_resampling_quality <= 2) { + + /* Linear interpolation */ + int volume_fact = (int)(volume * 16384.0); + + #define DO_RESAMPLE(inc) \ + { \ + HEAVYASSERT(dir < 0 ? (src_pos >= src_start) : (src_pos < src_end)); \ + \ + dst[s] += (((src[src_pos] + ((((src[src_pos + 1] - src[src_pos]) >> 1) * src_subpos) >> 14)) * volume_fact) >> 14); \ + \ + src_subpos += dt + inc; \ + src_pos += src_subpos >> 15; \ + src_subpos &= 0x7FFFl; \ + s++; \ + } + + MAKE_RESAMPLER(); + + #undef DO_RESAMPLE + + } else if (dumb_resampling_quality == 3) { + + /* Quadratic interpolation */ + + int volume_fact = (int)(volume * 16384.0); + int a = 0, b = 0; + sample_t *x = NULL; + int last_src_pos = -1; + + /* AIM: no integer multiplicands must transcend the range -32768 to 32767. + * This limitation is imposed by most compilers, including gcc and MSVC. + * + * a = 0.5 * (s0 + s2) - s1 + * b = -1.5 * s0 + 2 * s1 - 0.5 * s2 + * c = s0 + * + * s = (a * t + b) * t + c + * + * In fixed-point: + * + * a = ((s0 + s2) >> 1) - s1 + * b = ((-3 * s0 - s2) >> 1) + (s1 << 1) + * + * s = (((((a * t) >> 16) + b) * t) >> 16) + s0 + * + * With t halved (since t can reach 65535): + * + * s = (((((a * t) >> 15) + b) * t) >> 15) + s0 + * + * a currently reaches 65536 + * b currently reaches 131072 + * + * So we must use aon2 + * + * s = (((((aon2 * t) >> 14) + b) * t) >> 15) + s0 + * + * ((aon2 * t) >> 14) + b is 5 times too big + * so we must divide by 8 + * + * s = (((((aon2 * t) >> 17) + bon8) * t) >> 12) + s0 + * + * aon2 = ((s0 + s2) >> 2) - (s1 >> 1) + * bon8 = ((-3 * s0 - s2) >> 4) + (s1 >> 2) + * or: + * bon8 = ((s2 - s0) >> 4) - (aon2 >> 1) + */ + + /* Unh4x0r3d version: + #define DO_RESAMPLE(inc) \ + { \ + HEAVYASSERT(dir < 0 ? (src_pos >= src_start) : (src_pos < src_end)); \ + \ + if (src_pos != last_src_pos) { \ + last_src_pos = src_pos; \ + x = &src[src_pos]; \ + a = ((x[0] + x[2]) >> 2) - (x[1] >> 1); \ + b = ((x[2] - x[0]) >> 4) - (a >> 1); \ + } \ + \ + dst[s] += ((((((((a * src_subpos) >> 17) + b) * src_subpos) >> 12) + x[0]) * volume_fact) >> 14); \ + \ + src_subpos += dt + inc; \ + src_pos += src_subpos >> 15; \ + src_subpos &= 0x7FFFl; \ + s++; \ + } + */ + + /* H4x0r3d version: */ + #define DO_RESAMPLE(inc) \ + { \ + HEAVYASSERT(dir < 0 ? (src_pos >= src_start) : (src_pos < src_end)); \ + \ + if (src_pos != last_src_pos) { \ + last_src_pos = src_pos; \ + x = &src[src_pos]; \ + a = ((x[0] + x[2]) >> 1) - x[1]; \ + b = ((x[2] - x[0]) >> 1) - (a << 1); \ + } \ + \ + dst[s] += ((((((((a * src_subpos) >> 15) + b) * src_subpos) >> 15) + x[0]) * volume_fact) >> 14); \ + \ + src_subpos += dt + inc; \ + src_pos += src_subpos >> 15; \ + src_subpos &= 0x7FFFl; \ + s++; \ + } + + MAKE_RESAMPLER(); + + #undef DO_RESAMPLE + + } else { + + /* Cubic interpolation */ + + int volume_fact = (int)(volume * 16384.0); + int a = 0, b = 0, c = 0; + sample_t *x = NULL; + int last_src_pos = -1; + + /* AIM: never multiply integers outside the range -32768 to 32767. + * + * a = 1.5f * (x[1] - x[2]) + (x[3] - x[0]) * 0.5f; + * b = 2.0f * x[2] + x[0] - 2.5f * x[1] - x[3] * 0.5f; + * c = (x[2] - x[0]) * 0.5f; + * + * s = ((a * t + b) * t + c) * t + x[1]; + * + * Fixed-point version: + * + * a = (((x[1] - x[2]) << 1) + (x[1] - x[2]) + (x[3] - x[0])) >> 1; + * b = (x[2] << 1) + x[0] - ((5 * x[1] + x[3]) >> 1); + * c = (x[2] - x[0]) >> 1; + * + * s = ((((((((a * t) >> 15) + b) * t) >> 15) + c) * t) >> 15) + x[1]; + * (with t already halved, maximum 32767) + * + * a is in (((1+1)*2)+(1+1)+(1+1))/2 = 8 times the required range + * b is in (1*2)+1+((5*1+1)/2) = 6 times + * c is in the required range + * + * We must use aon8 + * + * s = ((((((((aon8 * t) >> 12) + b) * t) >> 15) + c) * t) >> 15) + x[1]; + * + * But ((aon8 * t) >> 12) is in 2^(15+15-12) = 2^18 = 8 times + * b is in 6 times + * so we divide both ((aon8 * t) >> 12) and b by 16 + * + * s = ((((((((aon8 * t) >> 16) + bon16) * t) >> 11) + c) * t) >> 15) + x[1]; + * + * ((... + bon16) * t) >> 11 is 16 times too big + * c is in the correct range + * we must divide both by 32 + * + * s = ((((((((aon8 * t) >> 16) + bon16) * t) >> 16) + con32) * t) >> 10) + x[1]; + * + * aon8 = (((x[1] - x[2]) << 1) + (x[1] - x[2]) + (x[3] - x[0])) >> 4; + * bon16 = ((x[2] << 2) + (x[0] << 1) - (5 * x[1] + x[3])) >> 5; + * con32 = (x[2] - x[0]) >> 6; + * + * A lot of accuracy is lost here. It is quite likely that some + * of the above would cancel anyway, so the scaling down wouldn't + * have to be so severe. However, I'm not in the mood to work it + * out now :P + * + * It may also be worth investigating whether doing this stuff + * in floats would be faster. + */ + + /* Unh4x0r3d version: + #define DO_RESAMPLE(inc) \ + { \ + HEAVYASSERT(dir < 0 ? (src_pos >= src_start) : (src_pos < src_end)); \ + \ + if (src_pos != last_src_pos) { \ + last_src_pos = src_pos; \ + x = &src[src_pos]; \ + a = (((x[1] - x[2]) << 1) + (x[1] - x[2]) + (x[3] - x[0])) >> 4; \ + b = ((x[2] << 2) + (x[0] << 1) - (5 * x[1] + x[3])) >> 5; \ + c = (x[2] - x[0]) >> 6; \ + } \ + \ + dst[s] += ((((((((((a * src_subpos) >> 16) + b) * src_subpos) >> 16) + c) * src_subpos) >> 10) + x[1]) * volume_fact) >> 14; \ + \ + src_subpos += dt + inc; \ + src_pos += src_subpos >> 15; \ + src_subpos &= 0x7FFFl; \ + s++; \ + } + */ + + /* H4x0r3d version: */ + #define DO_RESAMPLE(inc) \ + { \ + HEAVYASSERT(dir < 0 ? (src_pos >= src_start) : (src_pos < src_end)); \ + \ + if (src_pos != last_src_pos) { \ + last_src_pos = src_pos; \ + x = &src[src_pos]; \ + a = (((x[1] - x[2]) << 1) + (x[1] - x[2]) + (x[3] - x[0])) >> 1; \ + b = (x[2] << 1) + x[0] - ((5 * x[1] + x[3]) >> 1); \ + c = (x[2] - x[0]) >> 1; \ + } \ + \ + dst[s] += (((int)(((LONG_LONG)((int)(((LONG_LONG)((int)(((LONG_LONG)a * src_subpos) >> 15) + b) * src_subpos) >> 15) + c) * src_subpos) >> 15) + x[1]) * volume_fact) >> 14; \ + \ + src_subpos += dt + inc; \ + src_pos += src_subpos >> 15; \ + src_subpos &= 0x7FFFl; \ + s++; \ + } + + MAKE_RESAMPLER(); + + #undef DO_RESAMPLE + + } + + } + + end: + + ASSERT(s <= dst_size); + + *_src_pos = src_pos; + *_src_subpos = src_subpos; + if (_dir) *_dir = dir; + + return s; +} +#endif diff --git a/engines/ags/lib/dumb-0.9.2/helpers/sampbuf.c b/engines/ags/lib/dumb-0.9.2/helpers/sampbuf.c new file mode 100644 index 000000000000..75510c729ac3 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/helpers/sampbuf.c @@ -0,0 +1,47 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * sampbuf.c - Helper for allocating sample / / \ \ + * buffers. | < / \_ + * | \/ /\ / + * By entheh. \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include +#include "dumb.h" + + + +sample_t **create_sample_buffer(int n_channels, long length) +{ + int i; + sample_t **samples = malloc(n_channels * sizeof(*samples)); + if (!samples) return NULL; + samples[0] = malloc(n_channels * length * sizeof(*samples[0])); + if (!samples[0]) { + free(samples); + return NULL; + } + for (i = 1; i < n_channels; i++) samples[i] = samples[i-1] + length; + return samples; +} + + + +void destroy_sample_buffer(sample_t **samples) +{ + if (samples) { + free(samples[0]); + free(samples); + } +} diff --git a/engines/ags/lib/dumb-0.9.2/helpers/silence.c b/engines/ags/lib/dumb-0.9.2/helpers/silence.c new file mode 100644 index 000000000000..4d5fdcf4daa6 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/helpers/silence.c @@ -0,0 +1,29 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * silence.c - Silencing helper. / / \ \ + * | < / \_ + * By entheh. | \/ /\ / + * \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include +#include "dumb.h" + + + +void dumb_silence(sample_t *samples, long length) +{ + memset(samples, 0, length * sizeof(*samples)); +} + diff --git a/engines/ags/lib/dumb-0.9.2/helpers/stdfile.c b/engines/ags/lib/dumb-0.9.2/helpers/stdfile.c new file mode 100644 index 000000000000..2f02539a92ac --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/helpers/stdfile.c @@ -0,0 +1,93 @@ +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * stdfile.c - stdio file input module. / / \ \ + * | < / \_ + * By entheh. | \/ /\ / + * \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include + +#include "dumb.h" + + + +static void *dumb_stdfile_open(const char *filename) +{ + return fopen(filename, "rb"); +} + + + +static int dumb_stdfile_skip(void *f, long n) +{ + return fseek(f, n, SEEK_CUR); +} + + + +static int dumb_stdfile_getc(void *f) +{ + return fgetc(f); +} + + + +static long dumb_stdfile_getnc(char *ptr, long n, void *f) +{ + return fread(ptr, 1, n, f); +} + + + +static void dumb_stdfile_close(void *f) +{ + fclose(f); +} + + + +static DUMBFILE_SYSTEM stdfile_dfs = { + &dumb_stdfile_open, + &dumb_stdfile_skip, + &dumb_stdfile_getc, + &dumb_stdfile_getnc, + &dumb_stdfile_close +}; + + + +void dumb_register_stdfiles(void) +{ + register_dumbfile_system(&stdfile_dfs); +} + + + +static DUMBFILE_SYSTEM stdfile_dfs_leave_open = { + NULL, + &dumb_stdfile_skip, + &dumb_stdfile_getc, + &dumb_stdfile_getnc, + NULL +}; + + + +DUMBFILE *dumbfile_open_stdfile(FILE *p) +{ + DUMBFILE *d = dumbfile_open_ex(p, &stdfile_dfs_leave_open); + + return d; +} diff --git a/engines/ags/lib/dumb-0.9.2/it/it.h b/engines/ags/lib/dumb-0.9.2/it/it.h new file mode 100644 index 000000000000..bf19d3703b6e --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/it/it.h @@ -0,0 +1,714 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * internal/it.h - Internal stuff for IT playback / / \ \ + * and MOD/XM/S3M conversion. | < / \_ + * | \/ /\ / + * \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#ifndef AGS_LIB_DUMB_INTERNAL_IT_H +#define AGS_LIB_DUMB_INTERNAL_IT_H + +namespace AGS3 { + +/** TO DO: THINK ABOUT THE FOLLOWING: + +sigdata->flags & IT_COMPATIBLE_GXX + + Bit 5: On = Link Effect G's memory with Effect E/F. Also + Gxx with an instrument present will cause the + envelopes to be retriggered. If you change a + sample on a row with Gxx, it'll adjust the + frequency of the current note according to: + + NewFrequency = OldFrequency * NewC5 / OldC5; +*/ + + + +/* These #defines are TEMPORARY. They are used to write alternative code to + * handle ambiguities in the format specification. The correct code in each + * case will be determined most likely by experimentation. + */ +#define STEREO_SAMPLES_COUNT_AS_TWO +#define INVALID_ORDERS_END_SONG +#define INVALID_NOTES_CAUSE_NOTE_CUT +#define SUSTAIN_LOOP_OVERRIDES_NORMAL_LOOP +#define VOLUME_OUT_OF_RANGE_SETS_MAXIMUM + + + +#define SIGTYPE_IT DUMB_ID('I', 'T', ' ', ' ') + +#define IT_SIGNATURE DUMB_ID('I', 'M', 'P', 'M') +#define IT_INSTRUMENT_SIGNATURE DUMB_ID('I', 'M', 'P', 'I') +#define IT_SAMPLE_SIGNATURE DUMB_ID('I', 'M', 'P', 'S') + + + + /* 1 minute per 4 rows, each row 6 ticks; this is divided by the tempo to get + * the interval between ticks. + */ +#define TICK_TIME_DIVIDEND ((65536 * 60) / (4 * 6)) + + + + /* I'm not going to try to explain this, because I didn't derive it very + * formally ;) + */ + /* #define AMIGA_DIVISOR ((float)(4.0 * 14317056.0)) */ + /* I believe the following one to be more accurate. */ +#define AMIGA_DIVISOR ((float)(8.0 * 7159090.5)) + + + +typedef struct IT_MIDI IT_MIDI; +typedef struct IT_FILTER_STATE IT_FILTER_STATE; +typedef struct IT_ENVELOPE IT_ENVELOPE; +typedef struct IT_INSTRUMENT IT_INSTRUMENT; +typedef struct IT_SAMPLE IT_SAMPLE; +typedef struct IT_ENTRY IT_ENTRY; +typedef struct IT_PATTERN IT_PATTERN; +typedef struct IT_PLAYING_ENVELOPE IT_PLAYING_ENVELOPE; +typedef struct IT_PLAYING IT_PLAYING; +typedef struct IT_CHANNEL IT_CHANNEL; +typedef struct IT_CHECKPOINT IT_CHECKPOINT; +typedef struct IT_CALLBACKS IT_CALLBACKS; + + + +struct IT_MIDI { + unsigned char SFmacro[16][16]; // read these from 0x120 + unsigned char SFmacrolen[16]; + unsigned short SFmacroz[16]; /* Bitfield; bit 0 set = z in first position */ + unsigned char Zmacro[128][16]; // read these from 0x320 + unsigned char Zmacrolen[128]; +}; + + + +struct IT_FILTER_STATE { + float currsample, prevsample; +}; + + + +#define IT_ENVELOPE_ON 1 +#define IT_ENVELOPE_LOOP_ON 2 +#define IT_ENVELOPE_SUSTAIN_LOOP 4 +#define IT_ENVELOPE_PITCH_IS_FILTER 128 + +struct IT_ENVELOPE { + unsigned char flags; + unsigned char n_nodes; + unsigned char loop_start; + unsigned char loop_end; + unsigned char sus_loop_start; + unsigned char sus_loop_end; + signed char node_y[25]; + unsigned short node_t[25]; +}; + + + +#define NNA_NOTE_CUT 0 +#define NNA_NOTE_CONTINUE 1 +#define NNA_NOTE_OFF 2 +#define NNA_NOTE_FADE 3 + +#define DCT_OFF 0 +#define DCT_NOTE 1 +#define DCT_SAMPLE 2 +#define DCT_INSTRUMENT 3 + +#define DCA_NOTE_CUT 0 +#define DCA_NOTE_OFF 1 +#define DCA_NOTE_FADE 2 + +struct IT_INSTRUMENT { + int fadeout; + + IT_ENVELOPE volume_envelope; + IT_ENVELOPE pan_envelope; + IT_ENVELOPE pitch_envelope; + + unsigned char new_note_action; + unsigned char dup_check_type; + unsigned char dup_check_action; + unsigned char pp_separation; + unsigned char pp_centre; + unsigned char global_volume; + unsigned char default_pan; + unsigned char random_volume; + unsigned char random_pan; + + unsigned char filter_cutoff; + unsigned char filter_resonance; + + unsigned char map_note[120]; + unsigned short map_sample[120]; +}; + + + +#define IT_SAMPLE_EXISTS 1 +#define IT_SAMPLE_16BIT 2 +#define IT_SAMPLE_STEREO 4 +#define IT_SAMPLE_LOOP 16 +#define IT_SAMPLE_SUS_LOOP 32 +#define IT_SAMPLE_PINGPONG_LOOP 64 +#define IT_SAMPLE_PINGPONG_SUS_LOOP 128 + +#define IT_VIBRATO_SINE 0 +#define IT_VIBRATO_SAWTOOTH 1 /* Ramp down */ +#define IT_VIBRATO_SQUARE 2 +#define IT_VIBRATO_RANDOM 3 + +struct IT_SAMPLE { + unsigned char flags; + unsigned char global_volume; + unsigned char default_volume; + unsigned char default_pan; + + long length; + long loop_start; + long loop_end; + long C5_speed; + long sus_loop_start; + long sus_loop_end; + + unsigned char vibrato_speed; + unsigned char vibrato_depth; + unsigned char vibrato_rate; + unsigned char vibrato_waveform; + + sample_t *left; + sample_t *right; +}; + + + +#define IT_ENTRY_NOTE 1 +#define IT_ENTRY_INSTRUMENT 2 +#define IT_ENTRY_VOLPAN 4 +#define IT_ENTRY_EFFECT 8 + +#define IT_SET_END_ROW(entry) ((entry)->channel = 255) +#define IT_IS_END_ROW(entry) ((entry)->channel >= DUMB_IT_N_CHANNELS) + +#define IT_NOTE_OFF 255 +#define IT_NOTE_CUT 254 + +#define IT_ENVELOPE_SHIFT 8 + +#define IT_SURROUND 100 +#define IT_IS_SURROUND(pan) ((pan) > 64) +#define IT_IS_SURROUND_SHIFTED(pan) ((pan) > 64 << IT_ENVELOPE_SHIFT) + +#define IT_SET_SPEED 1 +#define IT_JUMP_TO_ORDER 2 +#define IT_BREAK_TO_ROW 3 +#define IT_VOLUME_SLIDE 4 +#define IT_PORTAMENTO_DOWN 5 +#define IT_PORTAMENTO_UP 6 +#define IT_TONE_PORTAMENTO 7 +#define IT_VIBRATO 8 +#define IT_TREMOR 9 +#define IT_ARPEGGIO 10 +#define IT_VOLSLIDE_VIBRATO 11 +#define IT_VOLSLIDE_TONEPORTA 12 +#define IT_SET_CHANNEL_VOLUME 13 +#define IT_CHANNEL_VOLUME_SLIDE 14 +#define IT_SET_SAMPLE_OFFSET 15 +#define IT_PANNING_SLIDE 16 +#define IT_RETRIGGER_NOTE 17 +#define IT_TREMOLO 18 +#define IT_S 19 +#define IT_SET_SONG_TEMPO 20 +#define IT_FINE_VIBRATO 21 +#define IT_SET_GLOBAL_VOLUME 22 +#define IT_GLOBAL_VOLUME_SLIDE 23 +#define IT_SET_PANNING 24 +#define IT_PANBRELLO 25 +#define IT_MIDI_MACRO 26 //see MIDI.TXT + +/* Some effects needed for XM compatibility */ +#define IT_XM_PORTAMENTO_DOWN 27 +#define IT_XM_PORTAMENTO_UP 28 +#define IT_XM_FINE_VOLSLIDE_DOWN 29 +#define IT_XM_FINE_VOLSLIDE_UP 30 +#define IT_XM_RETRIGGER_NOTE 31 + +#define IT_N_EFFECTS 32 + +/* These represent the top nibble of the command value. */ +#define IT_S_SET_FILTER 0 /* Greyed out in IT... */ +#define IT_S_SET_GLISSANDO_CONTROL 1 /* Greyed out in IT... */ +#define IT_S_FINETUNE 2 /* Greyed out in IT... */ +#define IT_S_SET_VIBRATO_WAVEFORM 3 +#define IT_S_SET_TREMOLO_WAVEFORM 4 +#define IT_S_SET_PANBRELLO_WAVEFORM 5 +#define IT_S_FINE_PATTERN_DELAY 6 +#define IT_S7 7 +#define IT_S_SET_PAN 8 +#define IT_S_SET_SURROUND_SOUND 9 +#define IT_S_SET_HIGH_OFFSET 10 +#define IT_S_PATTERN_LOOP 11 +#define IT_S_DELAYED_NOTE_CUT 12 +#define IT_S_NOTE_DELAY 13 +#define IT_S_PATTERN_DELAY 14 +#define IT_S_SET_MIDI_MACRO 15 + +/* +S0x Set filter +S1x Set glissando control +S2x Set finetune + + +S3x Set vibrato waveform to type x +S4x Set tremelo waveform to type x +S5x Set panbrello waveform to type x + Waveforms for commands S3x, S4x and S5x: + 0: Sine wave + 1: Ramp down + 2: Square wave + 3: Random wave +S6x Pattern delay for x ticks +S70 Past note cut +S71 Past note off +S72 Past note fade +S73 Set NNA to note cut +S74 Set NNA to continue +S75 Set NNA to note off +S76 Set NNA to note fade +S77 Turn off volume envelope +S78 Turn on volume envelope +S79 Turn off panning envelope +S7A Turn on panning envelope +S7B Turn off pitch envelope +S7C Turn on pitch envelope +S8x Set panning position +S91 Set surround sound +SAy Set high value of sample offset yxx00h +SB0 Set loopback point +SBx Loop x times to loopback point +SCx Note cut after x ticks +SDx Note delay for x ticks +SEx Pattern delay for x rows +SFx Set parameterised MIDI Macro +*/ + +struct IT_ENTRY { + unsigned char channel; /* End of row if channel >= DUMB_IT_N_CHANNELS */ + unsigned char mask; + unsigned char note; + unsigned char instrument; + unsigned char volpan; + unsigned char effect; + unsigned char effectvalue; +}; + + + +struct IT_PATTERN { + int n_rows; + int n_entries; + IT_ENTRY *entry; +}; + + + +#define IT_STEREO 1 +#define IT_USE_INSTRUMENTS 4 +#define IT_LINEAR_SLIDES 8 /* If not set, use Amiga slides */ +#define IT_OLD_EFFECTS 16 +#define IT_COMPATIBLE_GXX 32 + +/* Make sure IT_WAS_AN_XM and IT_WAS_A_MOD aren't set accidentally */ +#define IT_REAL_FLAGS 63 + +#define IT_WAS_AN_XM 64 /* Set for both XMs and MODs */ +#define IT_WAS_A_MOD 128 + +#define IT_ORDER_END 255 +#define IT_ORDER_SKIP 254 + +struct DUMB_IT_SIGDATA { + int n_orders; + int n_instruments; + int n_samples; + int n_patterns; + + int flags; + + int global_volume; + int mixing_volume; + int speed; + int tempo; + int pan_separation; + + unsigned char channel_pan[DUMB_IT_N_CHANNELS]; + unsigned char channel_volume[DUMB_IT_N_CHANNELS]; + + unsigned char *order; + unsigned char restart_position; /* for XM compatiblity */ + + IT_INSTRUMENT *instrument; + IT_SAMPLE *sample; + IT_PATTERN *pattern; + + IT_MIDI *midi; + + IT_CHECKPOINT *checkpoint; +}; + + + +struct IT_PLAYING_ENVELOPE { + int next_node; + int tick; +}; + + + +#define IT_PLAYING_BACKGROUND 1 +#define IT_PLAYING_SUSTAINOFF 2 +#define IT_PLAYING_FADING 4 +#define IT_PLAYING_DEAD 8 + +struct IT_PLAYING { + int flags; + + IT_CHANNEL *channel; + IT_SAMPLE *sample; + IT_INSTRUMENT *instrument; + IT_INSTRUMENT *env_instrument; + + unsigned short sampnum; + unsigned char instnum; + + unsigned char channel_volume; + + unsigned char volume; + unsigned short pan; + + unsigned char note; + + unsigned char filter_cutoff; + unsigned char filter_resonance; + + unsigned short true_filter_cutoff; /* These incorporate the filter envelope, and will not */ + unsigned char true_filter_resonance; /* be changed if they would be set to 127<<8 and 0. */ + + unsigned char vibrato_speed; + unsigned char vibrato_depth; + unsigned char vibrato_n; /* May be specified twice: volpan & effect. */ + unsigned char vibrato_time; + + unsigned char tremolo_speed; + unsigned char tremolo_depth; + unsigned char tremolo_time; + + unsigned char sample_vibrato_time; + int sample_vibrato_depth; /* Starts at rate?0:depth, increases by rate */ + + int slide; + float delta; + + IT_PLAYING_ENVELOPE volume_envelope; + IT_PLAYING_ENVELOPE pan_envelope; + IT_PLAYING_ENVELOPE pitch_envelope; + + int fadeoutcount; + + IT_FILTER_STATE filter_state[2]; /* Left and right */ + + DUMB_RESAMPLER resampler[2]; + + /* time_lost is used to emulate Impulse Tracker's sample looping + * characteristics. When time_lost is added to pos, the result represents + * the position in the theoretical version of the sample where all loops + * have been expanded. If this is stored, the resampling helpers will + * safely convert it for use with new loop boundaries. The situation is + * slightly more complicated if dir == -1 when the change takes place; we + * must reflect pos off the loop end point and set dir to 1 before + * proceeding. + */ + long time_lost; +}; + + + +#define IT_CHANNEL_MUTED 1 + +struct IT_CHANNEL { + int flags; + + unsigned char volume; + signed char volslide; + signed char xm_volslide; + + /* xm_volslide is used for volume slides done in the volume column in an + * XM file, since it seems the volume column slide is applied first, + * followed by clamping, followed by the effects column slide. IT does + * not exhibit this behaviour, so xm_volslide is maintained at zero. + */ + + unsigned char pan; + unsigned short truepan; + + unsigned char channelvolume; + signed char channelvolslide; + + unsigned char instrument; + unsigned char note; + + unsigned char SFmacro; + + unsigned char filter_cutoff; + unsigned char filter_resonance; + + unsigned char note_cut_count; + unsigned char note_delay_count; + IT_ENTRY *note_delay_entry; + + int arpeggio; + unsigned char retrig; + unsigned char xm_retrig; + int retrig_tick; + + unsigned char tremor; + unsigned char tremor_time; /* Bit 6 set if note on; bit 7 set if tremor active. */ + + int portamento; + int toneporta; + unsigned char destnote; + + /** WARNING - for neatness, should one or both of these be in the IT_PLAYING struct? */ + unsigned short sample; + unsigned char truenote; + + unsigned char midi_state; + + signed char lastvolslide; + unsigned char lastDKL; + unsigned char lastEF; /* Doubles as last portamento up for XM files */ + unsigned char lastG; + unsigned char lastHspeed; + unsigned char lastHdepth; + unsigned char lastRspeed; + unsigned char lastRdepth; + unsigned char lastI; + unsigned char lastJ; /* Doubles as last portamento down for XM files */ + unsigned char lastN; + unsigned char lastO; + unsigned char high_offset; + unsigned char lastQ; + unsigned char lastS; + unsigned char pat_loop_row; + unsigned char pat_loop_count; + unsigned char lastW; + + unsigned char xm_lastE1; + unsigned char xm_lastE2; + unsigned char xm_lastEA; + unsigned char xm_lastEB; + unsigned char xm_lastX1; + unsigned char xm_lastX2; + + IT_PLAYING *playing; +}; + + + +struct DUMB_IT_SIGRENDERER { + DUMB_IT_SIGDATA *sigdata; + + int n_channels; + + unsigned char globalvolume; + signed char globalvolslide; + + unsigned char tempo; + signed char temposlide; + + IT_CHANNEL channel[DUMB_IT_N_CHANNELS]; + + IT_PLAYING *playing[DUMB_IT_N_NNA_CHANNELS]; + + int tick; + int speed; + int rowcount; + + int order; /* Set to -1 if the song is terminated by a callback. */ + int row; + int processorder; + int processrow; + int breakrow; + int pat_loop_row; + + int n_rows; + + IT_ENTRY *entry_start; + IT_ENTRY *entry; + IT_ENTRY *entry_end; + + long time_left; /* Time before the next tick is processed */ + int sub_time_left; + + DUMB_CLICK_REMOVER **click_remover; + + IT_CALLBACKS *callbacks; +}; + + + +struct IT_CHECKPOINT { + IT_CHECKPOINT *next; + long time; + DUMB_IT_SIGRENDERER *sigrenderer; +}; + + + +struct IT_CALLBACKS { + int (*loop)(void *data); + void *loop_data; + /* Return 1 to prevent looping; the music will terminate abruptly. If you + * want to make the music stop but allow samples to fade (beware, as they + * might not fade at all!), use dumb_it_sr_set_speed() and set the speed + * to 0. Note that xm_speed_zero() will not be called if you set the + * speed manually, and also that this will work for IT and S3M files even + * though the music can't stop in this way by itself. + */ + + int (*xm_speed_zero)(void *data); + void *xm_speed_zero_data; + /* Return 1 to terminate the mod, without letting samples fade. */ + + int (*midi)(void *data, int channel, unsigned char byte); + void *midi_data; + /* Return 1 to prevent DUMB from subsequently interpreting the MIDI bytes + * itself. In other words, return 1 if the Zxx macros in an IT file are + * controlling filters and shouldn't be. + */ +}; + + + +void _dumb_it_end_sigrenderer(sigrenderer_t *sigrenderer); +void _dumb_it_unload_sigdata(sigdata_t *vsigdata); + +extern DUH_SIGTYPE_DESC _dumb_sigtype_it; + + + +long _dumb_it_build_checkpoints(DUMB_IT_SIGDATA *sigdata); + + + +#define XM_APPREGIO 0 +#define XM_PORTAMENTO_UP 1 +#define XM_PORTAMENTO_DOWN 2 +#define XM_TONE_PORTAMENTO 3 +#define XM_VIBRATO 4 +#define XM_VOLSLIDE_TONEPORTA 5 +#define XM_VOLSLIDE_VIBRATO 6 +#define XM_TREMOLO 7 +#define XM_SET_PANNING 8 +#define XM_SAMPLE_OFFSET 9 +#define XM_VOLUME_SLIDE 10 /* A */ +#define XM_POSITION_JUMP 11 /* B */ +#define XM_SET_CHANNEL_VOLUME 12 /* C */ +#define XM_PATTERN_BREAK 13 /* D */ +#define XM_E 14 /* E */ +#define XM_SET_TEMPO_BPM 15 /* F */ +#define XM_SET_GLOBAL_VOLUME 16 /* G */ +#define XM_GLOBAL_VOLUME_SLIDE 17 /* H */ +#define XM_KEY_OFF 20 /* K (undocumented) */ +#define XM_SET_ENVELOPE_POSITION 21 /* L */ +#define XM_PANNING_SLIDE 25 /* P */ +#define XM_MULTI_RETRIG 27 /* R */ +#define XM_TREMOR 29 /* T */ +#define XM_X 33 /* X */ +#define XM_N_EFFECTS (10+26) + +#define XM_E_SET_FILTER 0x0 +#define XM_E_FINE_PORTA_UP 0x1 +#define XM_E_FINE_PORTA_DOWN 0x2 +#define XM_E_SET_GLISSANDO_CONTROL 0x3 +#define XM_E_SET_VIBRATO_CONTROL 0x4 +#define XM_E_SET_FINETUNE 0x5 +#define XM_E_SET_LOOP 0x6 +#define XM_E_SET_TREMOLO_CONTROL 0x7 +#define XM_E_RETRIG_NOTE 0x9 +#define XM_E_FINE_VOLSLIDE_UP 0xA +#define XM_E_FINE_VOLSLIDE_DOWN 0xB +#define XM_E_NOTE_CUT 0xC +#define XM_E_NOTE_DELAY 0xD +#define XM_E_PATTERN_DELAY 0xE + +#define XM_X_EXTRAFINE_PORTA_UP 1 +#define XM_X_EXTRAFINE_PORTA_DOWN 2 + +/* To make my life a bit simpler during conversion, effect E:xy is converted + * to effect number EBASE+x:y. The same applies to effect X, and IT's S. That + * way, these effects can be manipulated like regular effects. + */ +#define EBASE (XM_N_EFFECTS) +#define XBASE (EBASE+16) +#define SBASE (IT_N_EFFECTS) + +#define EFFECT_VALUE(x, y) (((x)<<4)|(y)) +#define HIGH(v) ((v)>>4) +#define LOW(v) ((v)&0x0F) +#define SET_HIGH(v, x) v = (((x)<<4)|((v)&0x0F)) +#define SET_LOW(v, y) v = (((v)&0xF0)|(y)) +#define BCD_TO_NORMAL(v) (HIGH(v)*10+LOW(v)) + + + +#if 0 +unsigned char **_dumb_malloc2(int w, int h); +void _dumb_free2(unsigned char **line); +#endif + +void _dumb_it_xm_convert_effect(int effect, int value, IT_ENTRY *entry); +int _dumb_it_fix_invalid_orders(DUMB_IT_SIGDATA *sigdata); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/dumb-0.9.2/it/itmisc.cpp b/engines/ags/lib/dumb-0.9.2/it/itmisc.cpp new file mode 100644 index 000000000000..2971366034a9 --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/it/itmisc.cpp @@ -0,0 +1,70 @@ +/* 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 "ags/lib/dumb-0.9.2/dumb.h" +#include "common/textconsole.h" + +namespace AGS3 { + +DUMB_IT_SIGDATA *duh_get_it_sigdata(DUH *duh) { + warning("TODO: duh_get_it_sigdata"); + return nullptr; +} + +DUH_SIGRENDERER *duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer, DUH_SIGTYPE_DESC *desc, int n_channels, long pos) { + warning("TODO: duh_encapsulate_raw_sigrenderer"); + return nullptr; +} + +sigrenderer_t *duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type) { + warning("TODO: duh_get_raw_sigrenderer"); + return nullptr; +} + +void dumb_silence(sample_t *samples, long length) { + warning("TODO: dumb_silence"); +} + +long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta) { + warning("TODO: dumb_resample"); + return 0; +} + +void dumb_reset_resampler(DUMB_RESAMPLER *resampler, sample_t *src, long pos, long start, long end) { + warning("TODO: dumb_reset_resampler"); +} + +sample_t dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, float volume) { + warning("TODO: dumb_resample_get_current_sample"); + return (sample_t)0; +} + +sample_t **create_sample_buffer(int n_channels, long length) { + warning("TODO: create_sample_buffer"); + return nullptr; +} + +void destroy_sample_buffer(sample_t **samples) { + warning("TODO: destroy_sample_buffer"); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/dumb-0.9.2/it/itrender.cpp b/engines/ags/lib/dumb-0.9.2/it/itrender.cpp new file mode 100644 index 000000000000..31be41914c4e --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/it/itrender.cpp @@ -0,0 +1,3533 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * itrender.c - Code to render an Impulse Tracker / / \ \ + * module. | < / \_ + * | \/ /\ / + * Written - painstakingly - by entheh. \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include "ags/lib/dumb-0.9.2/dumb.h" +#include "ags/lib/dumb-0.9.2/it/it.h" + +namespace AGS3 { + +static IT_PLAYING *dup_playing(IT_PLAYING *src, IT_CHANNEL *dstchannel, IT_CHANNEL *srcchannel) +{ + IT_PLAYING *dst; + + if (!src) return NULL; + + dst = (IT_PLAYING *)malloc(sizeof(*dst)); + if (!dst) return NULL; + + dst->flags = src->flags; + + ASSERT(src->channel); + dst->channel = &dstchannel[src->channel - srcchannel]; + dst->sample = src->sample; + dst->instrument = src->instrument; + dst->env_instrument = src->env_instrument; + + dst->sampnum = src->sampnum; + dst->instnum = src->instnum; + + dst->channel_volume = src->channel_volume; + + dst->volume = src->volume; + dst->pan = src->pan; + + dst->note = src->note; + + dst->filter_cutoff = src->filter_cutoff; + dst->filter_resonance = src->filter_resonance; + + dst->true_filter_cutoff = src->true_filter_cutoff; + dst->true_filter_resonance = src->true_filter_resonance; + + dst->vibrato_speed = src->vibrato_speed; + dst->vibrato_depth = src->vibrato_depth; + dst->vibrato_n = src->vibrato_n; + dst->vibrato_time = src->vibrato_time; + + dst->tremolo_speed = src->tremolo_speed; + dst->tremolo_depth = src->tremolo_depth; + dst->tremolo_time = src->tremolo_time; + + dst->sample_vibrato_time = src->sample_vibrato_time; + dst->sample_vibrato_depth = src->sample_vibrato_depth; + + dst->slide = src->slide; + dst->delta = src->delta; + + dst->volume_envelope = src->volume_envelope; + dst->pan_envelope = src->pan_envelope; + dst->pitch_envelope = src->pitch_envelope; + + dst->fadeoutcount = src->fadeoutcount; + + dst->filter_state[0] = src->filter_state[0]; + dst->filter_state[1] = src->filter_state[1]; + + dst->resampler[0] = src->resampler[0]; + dst->resampler[1] = src->resampler[1]; + dst->resampler[1].pickup_data = dst->resampler[0].pickup_data = dst; + dst->time_lost = src->time_lost; + + return dst; +} + + + +static void dup_channel(IT_CHANNEL *dst, IT_CHANNEL *src) +{ + dst->flags = src->flags; + + dst->volume = src->volume; + dst->volslide = src->volslide; + dst->xm_volslide = src->xm_volslide; + + dst->pan = src->pan; + dst->truepan = src->truepan; + + dst->channelvolume = src->channelvolume; + dst->channelvolslide = src->channelvolslide; + + dst->instrument = src->instrument; + dst->note = src->note; + + dst->SFmacro = src->SFmacro; + + dst->filter_cutoff = src->filter_cutoff; + dst->filter_resonance = src->filter_resonance; + + dst->note_cut_count = src->note_cut_count; + dst->note_delay_count = src->note_delay_count; + dst->note_delay_entry = src->note_delay_entry; + + dst->arpeggio = src->arpeggio; + dst->retrig = src->retrig; + dst->xm_retrig = src->xm_retrig; + dst->retrig_tick = src->retrig_tick; + + dst->tremor_time = src->tremor_time; + + dst->portamento = src->portamento; + dst->toneporta = src->toneporta; + dst->destnote = src->destnote; + + dst->sample = src->sample; + dst->truenote = src->truenote; + + dst->midi_state = src->midi_state; + + dst->lastvolslide = src->lastvolslide; + dst->lastDKL = src->lastDKL; + dst->lastEF = src->lastEF; + dst->lastG = src->lastG; + dst->lastHspeed = src->lastHspeed; + dst->lastHdepth = src->lastHdepth; + dst->lastRspeed = src->lastRspeed; + dst->lastRdepth = src->lastRdepth; + dst->lastI = src->lastI; + dst->lastJ = src->lastJ; + dst->lastN = src->lastN; + dst->lastO = src->lastO; + dst->high_offset = src->high_offset; + dst->lastQ = src->lastQ; + dst->lastS = src->lastS; + dst->pat_loop_row = src->pat_loop_row; + dst->pat_loop_count = src->pat_loop_count; + dst->lastW = src->lastW; + + dst->xm_lastE1 = src->xm_lastE1; + dst->xm_lastE2 = src->xm_lastE2; + dst->xm_lastEA = src->xm_lastEA; + dst->xm_lastEB = src->xm_lastEB; + dst->xm_lastX1 = src->xm_lastX1; + dst->xm_lastX2 = src->xm_lastX2; + + dst->playing = dup_playing(src->playing, dst, src); +} + + + +/* Allocate the new callbacks first, then pass them to this function! + * It will free them on failure. + */ +static DUMB_IT_SIGRENDERER *dup_sigrenderer(DUMB_IT_SIGRENDERER *src, int n_channels, IT_CALLBACKS *callbacks) +{ + DUMB_IT_SIGRENDERER *dst; + int i; + + if (!src) { + if (callbacks) free(callbacks); + return NULL; + } + + dst = (DUMB_IT_SIGRENDERER *)malloc(sizeof(*dst)); + if (!dst) { + if (callbacks) free(callbacks); + return NULL; + } + + dst->sigdata = src->sigdata; + + dst->n_channels = n_channels; + + dst->globalvolume = src->globalvolume; + dst->globalvolslide = src->globalvolslide; + + dst->tempo = src->tempo; + dst->temposlide = src->temposlide; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) + dup_channel(&dst->channel[i], &src->channel[i]); + + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) + dst->playing[i] = dup_playing(src->playing[i], dst->channel, src->channel); + + dst->tick = src->tick; + dst->speed = src->speed; + dst->rowcount = src->rowcount; + + dst->order = src->order; + dst->row = src->row; + dst->processorder = src->processorder; + dst->processrow = src->processrow; + dst->breakrow = src->breakrow; + dst->pat_loop_row = src->pat_loop_row; + + dst->n_rows = src->n_rows; + + dst->entry_start = src->entry_start; + dst->entry = src->entry; + dst->entry_end = src->entry_end; + + dst->time_left = src->time_left; + dst->sub_time_left = src->sub_time_left; + + dst->click_remover = NULL; + + dst->callbacks = callbacks; + + return dst; +} + + + +static IT_MIDI default_midi = { + /* unsigned char SFmacro[16][16]; */ + { + {0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, + /* unsigned char SFmacrolen[16]; */ + {4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + /* unsigned short SFmacroz[16]; */ + /* Bitfield; bit 0 set = z in first position */ + { + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + /* unsigned char Zmacro[128][16]; */ + { + {0xF0, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xF0, 0xF0, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + }, + /* unsigned char Zmacrolen[128]; */ + { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + + + +static void it_reset_filter_state(IT_FILTER_STATE *state) +{ + state->currsample = 0; + state->prevsample = 0; +} + + + +#define LOG10 2.30258509299 + +/* IMPORTANT: This function expects one extra sample in 'src' so it can apply + * click removal. It reads size samples, starting from src[0], and writes its + * output starting at dst[pos]. The pos parameter is required for getting + * click removal right. + */ +static void it_filter(DUMB_CLICK_REMOVER *cr, IT_FILTER_STATE *state, sample_t *dst, long pos, sample_t *src, long size, int sampfreq, int cutoff, int resonance) +{ + float currsample = state->currsample; + float prevsample = state->prevsample; + + float a, b, c; + + { + float inv_angle = (float)(sampfreq * pow(0.5, 0.25 + cutoff*(1.0/(24< 2.0f) d = 2.0f; + d = (loss - d) * inv_angle; + e = inv_angle * inv_angle; + a = 1.0f / (1.0f + d + e); + c = -e * a; + b = 1.0f - a - c; +#else + a = 1.0f / (inv_angle*inv_angle + inv_angle*loss + loss); + c = -(inv_angle*inv_angle) * a; + b = 1.0f - a - c; +#endif + } + + dst += pos; + + if (cr) { + float startstep = src[0]*a + currsample*b + prevsample*c; + dumb_record_click(cr, pos, (sample_t)startstep); + } + +#define INT_FILTERS +#ifdef INT_FILTERS +#define MULSCA(a, b) ((int)((LONG_LONG)((a) << 4) * (b) >> 32)) +#define SCALEB 12 + { + int ai = (int)(a * (1 << (16+SCALEB))); + int bi = (int)(b * (1 << (16+SCALEB))); + int ci = (int)(c * (1 << (16+SCALEB))); + sample_t csi = (sample_t)currsample; + sample_t psi = (sample_t)prevsample; + sample_t *dst_end = dst + size; + while (dst < dst_end) { + { + sample_t nsi = MULSCA(*src++, ai) + MULSCA(csi, bi) + MULSCA(psi, ci); + psi = csi; + csi = nsi; + } + *dst++ += csi; + } + currsample = csi; + prevsample = psi; + } +#else + { + int i = size % 3; + while (i > 0) { + { + float newsample = *src++*a + currsample*b + prevsample*c; + prevsample = currsample; + currsample = newsample; + } + *dst++ += (sample_t)currsample; + i--; + } + i = size / 3; + while (i > 0) { + float newsample; + /* Gotta love unrolled loops! */ + *dst++ += (sample_t)(newsample = *src++*a + currsample*b + prevsample*c); + *dst++ += (sample_t)(prevsample = *src++*a + newsample*b + currsample*c); + *dst++ += (sample_t)(currsample = *src++*a + prevsample*b + newsample*c); + i--; + } + } +#endif + + if (cr) { + float endstep = *src*a + currsample*b + prevsample*c; + dumb_record_click(cr, pos + size, -(sample_t)endstep); + } + + state->currsample = currsample; + state->prevsample = prevsample; +} + +#undef LOG10 + + + +static signed char it_sine[256] = { + 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, + 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, + 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60, + 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26, + 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2, + 0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23, + -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44, + -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59, + -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64, + -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60, + -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46, + -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26, + -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2 +}; + + + +#if 0 +/** WARNING: use these! */ +/** JULIEN: Plus for XM compatibility it could be interesting to rename + * it_sawtooth[] to it_rampdown[], and add an it_rampup[]. + * Also, still for XM compat', twood be good if it was possible to tell the + * the player not to retrig' the waveform on a new instrument. + * Both of these are only for completness though, as I don't think it would + * be very noticeable ;) + */ +/** ENTHEH: IT also has the 'don't retrig' thingy :) */ + +static signed char it_sawtooth[256] = { + 64, 63, 63, 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56, + 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, + 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40, + 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32, + 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, + 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, + 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, + 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, + 0, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, + -8, -9, -9,-10,-10,-11,-11,-12,-12,-13,-13,-14,-14,-15,-15,-16, + -16,-17,-17,-18,-18,-19,-19,-20,-20,-21,-21,-22,-22,-23,-23,-24, + -24,-25,-25,-26,-26,-27,-27,-28,-28,-29,-29,-30,-30,-31,-31,-32, + -32,-33,-33,-34,-34,-35,-35,-36,-36,-37,-37,-38,-38,-39,-39,-40, + -40,-41,-41,-42,-42,-43,-43,-44,-44,-45,-45,-46,-46,-47,-47,-48, + -48,-49,-49,-50,-50,-51,-51,-52,-52,-53,-53,-54,-54,-55,-55,-56, + -56,-57,-57,-58,-58,-59,-59,-60,-60,-61,-61,-62,-62,-63,-63,-64 +}; + + + +static signed char it_squarewave[256] = { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#endif + + + +static void reset_tick_counts(DUMB_IT_SIGRENDERER *sigrenderer) +{ + int i; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + IT_CHANNEL *channel = &sigrenderer->channel[i]; + channel->note_cut_count = 0; + channel->note_delay_count = 0; + } +} + + + +static void reset_effects(DUMB_IT_SIGRENDERER *sigrenderer) +{ + int i; + + sigrenderer->globalvolslide = 0; + sigrenderer->temposlide = 0; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + IT_CHANNEL *channel = &sigrenderer->channel[i]; + channel->volslide = 0; + channel->xm_volslide = 0; + channel->channelvolslide = 0; + channel->arpeggio = 0; + channel->retrig = 0; + if (channel->xm_retrig) { + channel->xm_retrig = 0; + channel->retrig_tick = 0; + } + channel->tremor_time &= 127; + channel->portamento = 0; + channel->toneporta = 0; + if (channel->playing) { + channel->playing->vibrato_n = 0; + channel->playing->tremolo_speed = 0; + channel->playing->tremolo_depth = 0; + } + } +} + + + +static void update_tremor(IT_CHANNEL *channel) +{ + if ((channel->tremor_time & 128) && channel->playing) { + if (channel->tremor_time == 128) + channel->tremor_time = (channel->lastI >> 4) | 192; + else if (channel->tremor_time == 192) + channel->tremor_time = (channel->lastI & 15) | 128; + else + channel->tremor_time--; + } +} + + + +static void it_pickup_loop(DUMB_RESAMPLER *resampler, void *data) +{ + resampler->pos -= resampler->end - resampler->start; + ((IT_PLAYING *)data)->time_lost += resampler->end - resampler->start; +} + + + +static void it_pickup_pingpong_loop(DUMB_RESAMPLER *resampler, void *data) +{ + if (resampler->dir < 0) { + resampler->pos = (resampler->start << 1) - 1 - resampler->pos; + resampler->subpos ^= 65535; + resampler->dir = 1; + ((IT_PLAYING *)data)->time_lost += (resampler->end - resampler->start) << 1; + } else { + resampler->pos = (resampler->end << 1) - 1 - resampler->pos; + resampler->subpos ^= 65535; + resampler->dir = -1; + } +} + + + +static void it_pickup_stop_at_end(DUMB_RESAMPLER *resampler, void *data) +{ + (void)data; + + if (resampler->dir < 0) { + resampler->pos = (resampler->start << 1) - 1 - resampler->pos; + resampler->subpos ^= 65535; + /* By rights, time_lost would be updated here. However, there is no + * need at this point; it will not be used. + * + * ((IT_PLAYING *)data)->time_lost += (resampler->src_end - resampler->src_start) << 1; + */ + resampler->dir = 1; + } else + resampler->dir = 0; +} + + + +static void it_playing_update_resamplers(IT_PLAYING *playing) +{ + if ((playing->sample->flags & IT_SAMPLE_SUS_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF)) { + playing->resampler[0].start = playing->sample->sus_loop_start; + playing->resampler[0].end = playing->sample->sus_loop_end; + if (playing->sample->flags & IT_SAMPLE_PINGPONG_SUS_LOOP) + playing->resampler[0].pickup = &it_pickup_pingpong_loop; + else + playing->resampler[0].pickup = &it_pickup_loop; + } else if (playing->sample->flags & IT_SAMPLE_LOOP) { + playing->resampler[0].start = playing->sample->loop_start; + playing->resampler[0].end = playing->sample->loop_end; + if (playing->sample->flags & IT_SAMPLE_PINGPONG_LOOP) + playing->resampler[0].pickup = &it_pickup_pingpong_loop; + else + playing->resampler[0].pickup = &it_pickup_loop; + } else { + if (playing->sample->flags & IT_SAMPLE_SUS_LOOP) + playing->resampler[0].start = playing->sample->sus_loop_start; + else + playing->resampler[0].start = 0; + playing->resampler[0].end = playing->sample->length; + playing->resampler[0].pickup = &it_pickup_stop_at_end; + } + playing->resampler[1].start = playing->resampler[0].start; + playing->resampler[1].end = playing->resampler[0].end; + playing->resampler[1].pickup = playing->resampler[0].pickup; + ASSERT(playing->resampler[0].pickup_data == playing); + ASSERT(playing->resampler[1].pickup_data == playing); +} + + + +/* This should be called whenever the sample or sample position changes. */ +static void it_playing_reset_resamplers(IT_PLAYING *playing, long pos) +{ + dumb_reset_resampler(&playing->resampler[0], playing->sample->left, pos, 0, 0); + dumb_reset_resampler(&playing->resampler[1], playing->sample->right, pos, 0, 0); + playing->resampler[1].pickup_data = playing->resampler[0].pickup_data = playing; + playing->time_lost = 0; + playing->flags &= ~IT_PLAYING_DEAD; + it_playing_update_resamplers(playing); +} + + + +static void update_retrig(IT_CHANNEL *channel) +{ + if (channel->xm_retrig) { + channel->retrig_tick--; + if (channel->retrig_tick <= 0) { + if (channel->playing) it_playing_reset_resamplers(channel->playing, 0); + channel->retrig_tick = channel->xm_retrig; + } + } else if (channel->retrig & 0x0F) { + channel->retrig_tick--; + if (channel->retrig_tick <= 0) { + if (channel->retrig < 0x10) { + } else if (channel->retrig < 0x20) { + channel->volume--; + if (channel->volume > 64) channel->volume = 0; + } else if (channel->retrig < 0x30) { + channel->volume -= 2; + if (channel->volume > 64) channel->volume = 0; + } else if (channel->retrig < 0x40) { + channel->volume -= 4; + if (channel->volume > 64) channel->volume = 0; + } else if (channel->retrig < 0x50) { + channel->volume -= 8; + if (channel->volume > 64) channel->volume = 0; + } else if (channel->retrig < 0x60) { + channel->volume -= 16; + if (channel->volume > 64) channel->volume = 0; + } else if (channel->retrig < 0x70) { + channel->volume <<= 1; + channel->volume /= 3; + } else if (channel->retrig < 0x80) { + channel->volume >>= 1; + } else if (channel->retrig < 0x90) { + } else if (channel->retrig < 0xA0) { + channel->volume++; + if (channel->volume > 64) channel->volume = 64; + } else if (channel->retrig < 0xB0) { + channel->volume += 2; + if (channel->volume > 64) channel->volume = 64; + } else if (channel->retrig < 0xC0) { + channel->volume += 4; + if (channel->volume > 64) channel->volume = 64; + } else if (channel->retrig < 0xD0) { + channel->volume += 8; + if (channel->volume > 64) channel->volume = 64; + } else if (channel->retrig < 0xE0) { + channel->volume += 16; + if (channel->volume > 64) channel->volume = 64; + } else if (channel->retrig < 0xF0) { + channel->volume *= 3; + channel->volume >>= 1; + if (channel->volume > 64) channel->volume = 64; + } else { + channel->volume <<= 1; + if (channel->volume > 64) channel->volume = 64; + } + if (channel->playing) it_playing_reset_resamplers(channel->playing, 0); + channel->retrig_tick = channel->retrig & 0x0F; + } + } +} + + + +static void update_smooth_effects(DUMB_IT_SIGRENDERER *sigrenderer) +{ + int i; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + IT_CHANNEL *channel = &sigrenderer->channel[i]; + IT_PLAYING *playing = channel->playing; + + if (playing) { + playing->vibrato_time += playing->vibrato_n * + (playing->vibrato_speed << 2); + playing->tremolo_time += playing->tremolo_speed << 2; + } + } +} + + + +static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer) +{ + int i; + + if (sigrenderer->globalvolslide) { + sigrenderer->globalvolume += sigrenderer->globalvolslide; + if (sigrenderer->globalvolume > 128) { + if (sigrenderer->globalvolslide >= 0) + sigrenderer->globalvolume = 128; + else + sigrenderer->globalvolume = 0; + } + } + + if (sigrenderer->temposlide) { + sigrenderer->tempo += sigrenderer->temposlide; + if (sigrenderer->tempo < 32) { + if (sigrenderer->temposlide >= 0) + sigrenderer->tempo = 255; + else + sigrenderer->tempo = 32; + } + } + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + IT_CHANNEL *channel = &sigrenderer->channel[i]; + IT_PLAYING *playing = channel->playing; + + if (channel->xm_volslide) { + channel->volume += channel->xm_volslide; + if (channel->volume > 64) { + if (channel->xm_volslide >= 0) + channel->volume = 64; + else + channel->volume = 0; + } + } + + if (channel->volslide) { + channel->volume += channel->volslide; + if (channel->volume > 64) { + if (channel->volslide >= 0) + channel->volume = 64; + else + channel->volume = 0; + } + } + + if (channel->channelvolslide) { + channel->channelvolume += channel->channelvolslide; + if (channel->channelvolume > 64) { + if (channel->channelvolslide >= 0) + channel->channelvolume = 64; + else + channel->channelvolume = 0; + } + if (channel->playing) + channel->playing->channel_volume = channel->channelvolume; + } + + update_tremor(channel); + + channel->arpeggio = (channel->arpeggio << 4) | (channel->arpeggio >> 8); + channel->arpeggio &= 0xFFF; + + update_retrig(channel); + + if (playing) { + playing->slide += channel->portamento; + + if (sigrenderer->sigdata->flags & IT_LINEAR_SLIDES) { + if (channel->toneporta && channel->destnote < 120) { + int currpitch = ((playing->note - 60) << 8) + playing->slide; + int destpitch = (channel->destnote - 60) << 8; + if (currpitch > destpitch) { + currpitch -= channel->toneporta; + if (currpitch < destpitch) { + currpitch = destpitch; + channel->destnote = IT_NOTE_OFF; + } + } else if (currpitch < destpitch) { + currpitch += channel->toneporta; + if (currpitch > destpitch) { + currpitch = destpitch; + channel->destnote = IT_NOTE_OFF; + } + } + playing->slide = currpitch - ((playing->note - 60) << 8); + } + } else { + if (channel->toneporta && channel->destnote < 120) { + float amiga_multiplier = playing->sample->C5_speed * (1.0f / AMIGA_DIVISOR); + + float deltanote = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note); + /* deltanote is 1.0 for C-5, 0.5 for C-6, etc. */ + + float deltaslid = deltanote - playing->slide * amiga_multiplier; + + float destdelta = (float)pow(DUMB_SEMITONE_BASE, 60 - channel->destnote); + if (deltaslid < destdelta) { + playing->slide -= channel->toneporta; + deltaslid = deltanote - playing->slide * amiga_multiplier; + if (deltaslid > destdelta) { + playing->note = channel->destnote; + playing->slide = 0; + channel->destnote = IT_NOTE_OFF; + } + } else { + playing->slide += channel->toneporta; + deltaslid = deltanote - playing->slide * amiga_multiplier; + if (deltaslid < destdelta) { + playing->note = channel->destnote; + playing->slide = 0; + channel->destnote = IT_NOTE_OFF; + } + } + } + } + } + } + + update_smooth_effects(sigrenderer); +} + + + +static void update_pattern_variables(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry) +{ + IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel]; + + if (entry->mask & IT_ENTRY_EFFECT) { + if (entry->effect == IT_S) { + unsigned char effectvalue = entry->effectvalue; + if (effectvalue == 0) + effectvalue = channel->lastS; + channel->lastS = effectvalue; + switch (effectvalue >> 4) { + //case IT_S7: + case IT_S_PATTERN_LOOP: + { + unsigned char v = effectvalue & 15; + if (v == 0) + channel->pat_loop_row = sigrenderer->processrow; + else { + if (channel->pat_loop_count == 0) { + channel->pat_loop_count = v; + sigrenderer->pat_loop_row = channel->pat_loop_row; + } else { + if (--channel->pat_loop_count) + sigrenderer->pat_loop_row = channel->pat_loop_row; + else if (!(sigrenderer->sigdata->flags & IT_WAS_AN_XM)) + channel->pat_loop_row = sigrenderer->processrow + 1; + } + } + } + break; + case IT_S_PATTERN_DELAY: + sigrenderer->rowcount = 1 + (effectvalue & 15); + break; + } + } + } +} + + + +/* This function guarantees that channel->sample will always be valid if it + * is nonzero. In other words, to check if it is valid, simply check if it is + * nonzero. + */ +static void instrument_to_sample(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel) +{ + if (sigdata->flags & IT_USE_INSTRUMENTS) { + if (channel->instrument >= 1 && channel->instrument <= sigdata->n_instruments) { + if (channel->note < 120) { + channel->sample = sigdata->instrument[channel->instrument-1].map_sample[channel->note]; + channel->truenote = sigdata->instrument[channel->instrument-1].map_note[channel->note]; + } else + channel->sample = 0; + } else + channel->sample = 0; + } else { + channel->sample = channel->instrument; + channel->truenote = channel->note; + } + if (!(channel->sample >= 1 && channel->sample <= sigdata->n_samples && (sigdata->sample[channel->sample-1].flags & IT_SAMPLE_EXISTS))) + channel->sample = 0; +} + + + +static void fix_sample_looping(IT_PLAYING *playing) +{ + if ((playing->sample->flags & (IT_SAMPLE_LOOP | IT_SAMPLE_SUS_LOOP)) == + (IT_SAMPLE_LOOP | IT_SAMPLE_SUS_LOOP)) { + if (playing->resampler[0].dir < 0) { + playing->resampler[1].pos = playing->resampler[0].pos = (playing->sample->sus_loop_end << 1) - 1 - playing->resampler[0].pos; + playing->resampler[1].subpos = playing->resampler[0].subpos ^= 65535; + playing->resampler[1].dir = playing->resampler[0].dir = 1; + } + + playing->resampler[1].pos = playing->resampler[0].pos += playing->time_lost; + } +} + + + +static void retrigger_it_envelopes(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel) +{ + channel->playing->volume_envelope.next_node = 0; + channel->playing->volume_envelope.tick = -1; + channel->playing->pan_envelope.next_node = 0; + channel->playing->pan_envelope.tick = -1; + channel->playing->pitch_envelope.next_node = 0; + channel->playing->pitch_envelope.tick = -1; + channel->playing->fadeoutcount = 1024; + // Should we remove IT_PLAYING_BACKGROUND? Test with sample with sustain loop... + channel->playing->flags &= ~(IT_PLAYING_BACKGROUND | IT_PLAYING_SUSTAINOFF | IT_PLAYING_FADING | IT_PLAYING_DEAD); + it_playing_update_resamplers(channel->playing); + + if (channel->sample) + if (sigdata->flags & IT_USE_INSTRUMENTS) + channel->playing->env_instrument = &sigdata->instrument[channel->instrument-1]; +} + + + +static void it_retrigger_note(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *channel) +{ + DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; + unsigned char nna; + int i; + + if (channel->playing) { +#ifdef INVALID_NOTES_CAUSE_NOTE_CUT + if (channel->note == IT_NOTE_OFF) + nna = NNA_NOTE_OFF; + else if (channel->note >= 120 || !channel->playing->instrument || (channel->playing->flags & IT_PLAYING_DEAD)) + nna = NNA_NOTE_CUT; + else + nna = channel->playing->instrument->new_note_action; +#else + if (channel->note == IT_NOTE_CUT) + nna = NNA_NOTE_CUT; + if (channel->note >= 120) + nna = NNA_NOTE_OFF; + else if (!channel->playing->instrument || (channel->playing->flags & IT_PLAYING_DEAD)) + nna = NNA_NOTE_CUT; + else + nna = channel->playing->instrument->new_note_action; +#endif + + switch (nna) { + case NNA_NOTE_CUT: + free(channel->playing); + channel->playing = NULL; + break; + case NNA_NOTE_OFF: + channel->playing->flags |= IT_PLAYING_BACKGROUND | IT_PLAYING_SUSTAINOFF; + fix_sample_looping(channel->playing); + it_playing_update_resamplers(channel->playing); + if (channel->playing->instrument) + if ((channel->playing->instrument->volume_envelope.flags & (IT_ENVELOPE_ON | IT_ENVELOPE_LOOP_ON)) != IT_ENVELOPE_ON) + channel->playing->flags |= IT_PLAYING_FADING; + break; + case NNA_NOTE_FADE: + channel->playing->flags |= IT_PLAYING_BACKGROUND | IT_PLAYING_FADING; + break; + } + } + + if (channel->sample == 0 || channel->note >= 120) + return; + + channel->destnote = IT_NOTE_OFF; + + if (channel->playing) { + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) { + if (!sigrenderer->playing[i]) { + sigrenderer->playing[i] = channel->playing; + channel->playing = NULL; + break; + } + } +/** WARNING - come up with some more heuristics for replacing old notes */ +#if 0 + if (channel->playing) { + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) { + if (sigrenderer->playing[i]->flags & IT_PLAYING_BACKGROUND) { + write_seqtime(); + sequence_c(SEQUENCE_STOP_SIGNAL); + sequence_c(i); + channel->VChannel = &module->VChannel[i]; + break; + } + } + } +#endif + } + + if (channel->playing) + free(channel->playing); + + channel->playing = (IT_PLAYING *)malloc(sizeof(*channel->playing)); + + if (!channel->playing) + return; + + channel->playing->flags = 0; + channel->playing->channel = channel; + channel->playing->sample = &sigdata->sample[channel->sample-1]; + if (sigdata->flags & IT_USE_INSTRUMENTS) + channel->playing->instrument = &sigdata->instrument[channel->instrument-1]; + else + channel->playing->instrument = NULL; + channel->playing->env_instrument = channel->playing->instrument; + channel->playing->sampnum = channel->sample; + channel->playing->instnum = channel->instrument; + channel->playing->channel_volume = channel->channelvolume; + channel->playing->note = channel->truenote; + channel->playing->filter_cutoff = 127; + channel->playing->filter_resonance = 0; + channel->playing->true_filter_cutoff = 127 << 8; + channel->playing->true_filter_resonance = 0; + channel->playing->vibrato_speed = 0; + channel->playing->vibrato_depth = 0; + channel->playing->vibrato_n = 0; + channel->playing->vibrato_time = 0; + channel->playing->tremolo_speed = 0; + channel->playing->tremolo_depth = 0; + channel->playing->tremolo_time = 0; + channel->playing->sample_vibrato_time = 0; + channel->playing->sample_vibrato_depth = 0; + channel->playing->slide = 0; + channel->playing->volume_envelope.next_node = 0; + channel->playing->volume_envelope.tick = -1; + channel->playing->pan_envelope.next_node = 0; + channel->playing->pan_envelope.tick = -1; + channel->playing->pitch_envelope.next_node = 0; + channel->playing->pitch_envelope.tick = -1; + channel->playing->fadeoutcount = 1024; + it_reset_filter_state(&channel->playing->filter_state[0]); + it_reset_filter_state(&channel->playing->filter_state[1]); + it_playing_reset_resamplers(channel->playing, 0); + + /** WARNING - is everything initialised? */ +} + + + +static void get_default_volpan(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel) +{ + if (channel->sample == 0) + return; + + channel->volume = sigdata->sample[channel->sample-1].default_volume; + + { + int pan = sigdata->sample[channel->sample-1].default_pan; + if (pan >= 128 && pan <= 192) { + channel->pan = pan - 128; + return; + } + } + + if (sigdata->flags & IT_USE_INSTRUMENTS) { + IT_INSTRUMENT *instrument = &sigdata->instrument[channel->instrument-1]; + if (instrument->default_pan <= 64) + channel->pan = instrument->default_pan; + if (instrument->filter_cutoff >= 128) + channel->filter_cutoff = instrument->filter_cutoff - 128; + if (instrument->filter_resonance >= 128) + channel->filter_resonance = instrument->filter_resonance - 128; + } +} + + + +static void get_true_pan(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel) +{ + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + + if (!IT_IS_SURROUND_SHIFTED(channel->truepan) && (sigdata->flags & IT_USE_INSTRUMENTS)) { + IT_INSTRUMENT *instrument = &sigdata->instrument[channel->instrument-1]; + int truepan = channel->truepan; + truepan += (channel->note - instrument->pp_centre) * instrument->pp_separation << (IT_ENVELOPE_SHIFT - 3); + channel->truepan = MID(0, truepan, 64 << IT_ENVELOPE_SHIFT); + } +} + + + +static void post_process_it_volpan(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry) +{ + IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel]; + + if (entry->mask & IT_ENTRY_VOLPAN) { + if (entry->volpan <= 84) { + /* Volume */ + /* Fine volume slide up */ + /* Fine volume slide down */ + } else if (entry->volpan <= 94) { + /* Volume slide up */ + unsigned char v = entry->volpan - 85; + if (v == 0) + v = channel->lastvolslide; + channel->lastvolslide = v; + /* = effect Dx0 where x == entry->volpan - 85 */ + channel->volslide = v; + } else if (entry->volpan <= 104) { + /* Volume slide down */ + unsigned char v = entry->volpan - 95; + if (v == 0) + v = channel->lastvolslide; + channel->lastvolslide = v; + /* = effect D0x where x == entry->volpan - 95 */ + channel->volslide = -v; + } else if (entry->volpan <= 114) { + /* Portamento down */ + unsigned char v = (entry->volpan - 105) << 2; + if (v == 0) + v = channel->lastEF; + channel->lastEF = v; + channel->portamento -= v << 4; + } else if (entry->volpan <= 124) { + /* Portamento up */ + unsigned char v = (entry->volpan - 115) << 2; + if (v == 0) + v = channel->lastEF; + channel->lastEF = v; + channel->portamento += v << 4; + } else if (entry->volpan <= 202) { + /* Pan */ + /* Tone Portamento */ + } else if (entry->volpan <= 212) { + /* Vibrato */ + unsigned char v = entry->volpan - 203; + if (v == 0) + v = channel->lastHdepth; + else { + v <<= 2; + channel->lastHdepth = v; + } + if (channel->playing) { + channel->playing->vibrato_speed = channel->lastHspeed; + channel->playing->vibrato_depth = v; + channel->playing->vibrato_n++; + } + } + } +} + + + +static void it_send_midi(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *channel, unsigned char byte) +{ + if (sigrenderer->callbacks->midi) + if ((*sigrenderer->callbacks->midi)(sigrenderer->callbacks->midi_data, channel - sigrenderer->channel, byte)) + return; + + switch (channel->midi_state) { + case 4: /* Ready to receive resonance parameter */ + if (byte < 0x80) channel->filter_resonance = byte; + channel->midi_state = 0; + break; + case 3: /* Ready to receive cutoff parameter */ + if (byte < 0x80) channel->filter_cutoff = byte; + channel->midi_state = 0; + break; + case 2: /* Ready for byte specifying which parameter will follow */ + if (byte == 0) /* Cutoff */ + channel->midi_state = 3; + else if (byte == 1) /* Resonance */ + channel->midi_state = 4; + else + channel->midi_state = 0; + break; + default: /* Counting initial F0 bytes */ + switch (byte) { + case 0xF0: + channel->midi_state++; + break; + case 0xFA: + case 0xFC: + case 0xFF: + /* Reset filter parameters for all channels */ + { + int i; + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + sigrenderer->channel[i].filter_cutoff = 127; + sigrenderer->channel[i].filter_resonance = 0; + //// should we be resetting channel[i].playing->filter_* here? + } + } + /* Fall through */ + default: + channel->midi_state = 0; + break; + } + } +} + + + +/* Returns 1 if a callback caused termination of playback. */ +static int process_effects(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry) +{ + DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; + + IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel]; + + if (entry->mask & IT_ENTRY_EFFECT) { + switch (entry->effect) { +/* +Notes about effects (as compared to other module formats) + +C This is now in *HEX*. (Used to be in decimal in ST3) +E/F/G/H/U You need to check whether the song uses Amiga/Linear slides. +H/U Vibrato in Impulse Tracker is two times finer than in + any other tracker and is updated EVERY tick. + If "Old Effects" is *ON*, then the vibrato is played in the + normal manner (every non-row tick and normal depth) +E/F/G These commands ALL share the same memory. +Oxx Offsets to samples are to the 'xx00th' SAMPLE. (ie. for + 16 bit samples, the offset is xx00h*2) + Oxx past the sample end will be ignored, unless "Old Effects" + is ON, in which case the Oxx will play from the end of the + sample. +Yxy This uses a table 4 times larger (hence 4 times slower) than + vibrato or tremelo. If the waveform is set to random, then + the 'speed' part of the command is interpreted as a delay. +*/ + case IT_SET_SPEED: + if (entry->effectvalue) + sigrenderer->tick = sigrenderer->speed = entry->effectvalue; + else if (sigdata->flags & IT_WAS_AN_XM) { + sigrenderer->speed = 0; + if (sigrenderer->callbacks->xm_speed_zero && (*sigrenderer->callbacks->xm_speed_zero)(sigrenderer->callbacks->xm_speed_zero_data)) + return 1; + } + break; + + case IT_JUMP_TO_ORDER: sigrenderer->processorder = entry->effectvalue - 1; sigrenderer->processrow = 0xFFFE; break; + case IT_BREAK_TO_ROW: sigrenderer->breakrow = entry->effectvalue; sigrenderer->processrow = 0xFFFE; break; + + case IT_VOLSLIDE_VIBRATO: + if (channel->playing) { + channel->playing->vibrato_speed = channel->lastHspeed; + channel->playing->vibrato_depth = channel->lastHdepth; + channel->playing->vibrato_n++; + } + /* Fall through and process volume slide. */ + case IT_VOLUME_SLIDE: + case IT_VOLSLIDE_TONEPORTA: + /* The tone portamento component is handled elsewhere. */ + { + unsigned char v = entry->effectvalue; + if (!(sigdata->flags & IT_WAS_A_MOD)) { + if (v == 0) + v = channel->lastDKL; + channel->lastDKL = v; + } + if ((v & 0x0F) == 0) { /* Dx0 */ + channel->volslide = v >> 4; + if (channel->volslide == 15 && !(sigdata->flags & IT_WAS_AN_XM)) { + channel->volume += 15; + if (channel->volume > 64) channel->volume = 64; + } + } else if ((v & 0xF0) == 0) { /* D0x */ + channel->volslide = -v; + if (channel->volslide == -15 && !(sigdata->flags & IT_WAS_AN_XM)) { + channel->volume -= 15; + if (channel->volume > 64) channel->volume = 0; + } + } else if ((v & 0x0F) == 0x0F) { /* DxF */ + channel->volume += v >> 4; + if (channel->volume > 64) channel->volume = 64; + } else if ((v & 0xF0) == 0xF0) { /* DFx */ + channel->volume -= v & 15; + if (channel->volume > 64) channel->volume = 0; + } + } + break; + case IT_XM_FINE_VOLSLIDE_DOWN: + { + unsigned char v = entry->effectvalue; + if (v == 0) + v = channel->xm_lastEB; + channel->xm_lastEB = v; + channel->volume -= v; + if (channel->volume > 64) channel->volume = 0; + } + break; + case IT_XM_FINE_VOLSLIDE_UP: + { + unsigned char v = entry->effectvalue; + if (v == 0) + v = channel->xm_lastEA; + channel->xm_lastEA = v; + channel->volume += v; + if (channel->volume > 64) channel->volume = 64; + } + break; + case IT_PORTAMENTO_DOWN: + { + unsigned char v = entry->effectvalue; + if (sigdata->flags & IT_WAS_AN_XM) { + if (!(sigdata->flags & IT_WAS_A_MOD)) { + if (v == 0xF0) + v |= channel->xm_lastE2; + else if (v >= 0xF0) + channel->xm_lastE2 = v & 15; + else if (v == 0xE0) + v |= channel->xm_lastX2; + else + channel->xm_lastX2 = v & 15; + } + } else { + if (v == 0) + v = channel->lastEF; + channel->lastEF = v; + } + if (channel->playing) { + if ((v & 0xF0) == 0xF0) + channel->playing->slide -= (v & 15) << 4; + else if ((v & 0xF0) == 0xE0) + channel->playing->slide -= (v & 15) << 2; + else + channel->portamento -= v << 4; + } + } + break; + case IT_PORTAMENTO_UP: + { + unsigned char v = entry->effectvalue; + if (sigdata->flags & IT_WAS_AN_XM) { + if (!(sigdata->flags & IT_WAS_A_MOD)) { + if (v == 0xF0) + v |= channel->xm_lastE1; + else if (v >= 0xF0) + channel->xm_lastE1 = v & 15; + else if (v == 0xE0) + v |= channel->xm_lastX1; + else + channel->xm_lastX1 = v & 15; + } + } else { + if (v == 0) + v = channel->lastEF; + channel->lastEF = v; + } + if (channel->playing) { + if ((v & 0xF0) == 0xF0) + channel->playing->slide += (v & 15) << 4; + else if ((v & 0xF0) == 0xE0) + channel->playing->slide += (v & 15) << 2; + else + channel->portamento += v << 4; + } + } + break; + case IT_XM_PORTAMENTO_DOWN: + { + unsigned char v = entry->effectvalue; + if (!(sigdata->flags & IT_WAS_A_MOD)) { + if (v == 0) + v = channel->lastJ; + channel->lastJ = v; + } + if (channel->playing) + channel->portamento -= v << 4; + } + break; + case IT_XM_PORTAMENTO_UP: + { + unsigned char v = entry->effectvalue; + if (!(sigdata->flags & IT_WAS_A_MOD)) { + if (v == 0) + v = channel->lastEF; + channel->lastEF = v; + } + if (channel->playing) + channel->portamento += v << 4; + } + break; + case IT_VIBRATO: + { + unsigned char speed = entry->effectvalue >> 4; + unsigned char depth = entry->effectvalue & 15; + if (speed == 0) + speed = channel->lastHspeed; + channel->lastHspeed = speed; + if (depth == 0) + depth = channel->lastHdepth; + else { + if (sigdata->flags & IT_OLD_EFFECTS) + depth <<= 3; + else + depth <<= 2; + channel->lastHdepth = depth; + } + if (channel->playing) { + channel->playing->vibrato_speed = speed; + channel->playing->vibrato_depth = depth; + channel->playing->vibrato_n++; + } + } + break; + case IT_TREMOR: + { + unsigned char v = entry->effectvalue; + if (v == 0) + v = channel->lastI; + else if (!(sigdata->flags & IT_OLD_EFFECTS)) { + if (v & 0xF0) v -= 0x10; + if (v & 0x0F) v -= 0x01; + } + channel->lastI = v; + channel->tremor_time |= 128; + } + update_tremor(channel); + break; + case IT_ARPEGGIO: + { + unsigned char v = entry->effectvalue; + /* XM files have no memory for arpeggio (000 = no effect) + * and we use lastJ for portamento down instead. + */ + if (!(sigdata->flags & IT_WAS_AN_XM)) { + if (v == 0) + v = channel->lastJ; + channel->lastJ = v; + } + channel->arpeggio = v; + } + break; + case IT_SET_CHANNEL_VOLUME: + if (sigdata->flags & IT_WAS_AN_XM) + channel->volume = MIN(entry->effectvalue, 64); + else if (entry->effectvalue <= 64) + channel->channelvolume = entry->effectvalue; +#ifdef VOLUME_OUT_OF_RANGE_SETS_MAXIMUM + else + channel->channelvolume = 64; +#endif + if (channel->playing) + channel->playing->channel_volume = channel->channelvolume; + break; + case IT_CHANNEL_VOLUME_SLIDE: + { + unsigned char v = entry->effectvalue; + if (v == 0) + v = channel->lastN; + channel->lastN = v; + if ((v & 0x0F) == 0) { /* Nx0 */ + channel->channelvolslide = v >> 4; + } else if ((v & 0xF0) == 0) { /* N0x */ + channel->channelvolslide = -v; + } else { + if ((v & 0x0F) == 0x0F) { /* NxF */ + channel->channelvolume += v >> 4; + if (channel->channelvolume > 64) channel->channelvolume = 64; + } else if ((v & 0xF0) == 0xF0) { /* NFx */ + channel->channelvolume -= v & 15; + if (channel->channelvolume > 64) channel->channelvolume = 0; + } else + break; + if (channel->playing) + channel->playing->channel_volume = channel->channelvolume; + } + } + break; + case IT_SET_SAMPLE_OFFSET: + { + unsigned char v = entry->effectvalue; + if (sigdata->flags & IT_WAS_A_MOD) { + if (v == 0) break; + } else { + if (v == 0) + v = channel->lastO; + channel->lastO = v; + } + /* Note: we set the offset even if tone portamento is + * specified. Impulse Tracker does the same. + */ + if (entry->mask & IT_ENTRY_NOTE) { + if (channel->playing) { + int offset = ((int)channel->high_offset << 16) | ((int)v << 8); + IT_PLAYING *playing = channel->playing; + IT_SAMPLE *sample = playing->sample; + int end; + if ((sample->flags & IT_SAMPLE_SUS_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF)) + end = sample->sus_loop_end; + else if (sample->flags & IT_SAMPLE_LOOP) + end = sample->loop_end; + else + end = sample->length; + if (offset < end) + it_playing_reset_resamplers(playing, offset); + else if (sigdata->flags & IT_OLD_EFFECTS) + it_playing_reset_resamplers(playing, end); + } + } + } + break; + //case IT_PANNING_SLIDE: + /** JULIEN: guess what? the docs are wrong! (how unusual ;) + * Pxy seems to memorize its previous value... and there + * might be other mistakes like that... (sigh!) + */ + /** ENTHEH: umm... but... the docs say that Pxy memorises its + * value... don't they? :o + */ + case IT_RETRIGGER_NOTE: + { + unsigned char v = entry->effectvalue; + if (sigdata->flags & IT_WAS_AN_XM) { + if ((v & 0x0F) == 0) v |= channel->lastQ & 0x0F; + if ((v & 0xF0) == 0) v |= channel->lastQ & 0xF0; + } else { + if (v == 0) + v = channel->lastQ; + } + channel->lastQ = v; + if ((v & 0x0F) == 0) v |= 0x01; + channel->retrig = v; + if (entry->mask & IT_ENTRY_NOTE) { + channel->retrig_tick = v & 0x0F; + /* Emulate a bug */ + if (sigdata->flags & IT_WAS_AN_XM) + update_retrig(channel); + } else + update_retrig(channel); + } + break; + case IT_XM_RETRIGGER_NOTE: + channel->retrig_tick = channel->xm_retrig = entry->effectvalue; + if (entry->effectvalue == 0) + if (channel->playing) it_playing_reset_resamplers(channel->playing, 0); + break; + case IT_TREMOLO: + { + unsigned char speed = entry->effectvalue >> 4; + unsigned char depth = entry->effectvalue & 15; + if (speed == 0) + speed = channel->lastRspeed; + channel->lastRspeed = speed; + if (depth == 0) + depth = channel->lastRdepth; + channel->lastRdepth = depth; + if (channel->playing) { + channel->playing->tremolo_speed = speed; + channel->playing->tremolo_depth = depth; + } + } + break; + case IT_S: + { + /* channel->lastS was set in update_pattern_variables(). */ + unsigned char effectvalue = channel->lastS; + switch (effectvalue >> 4) { + //case IT_S_SET_FILTER: + //case IT_S_SET_GLISSANDO_CONTROL: + //case IT_S_FINETUNE: + //case IT_S_SET_VIBRATO_WAVEFORM: + //case IT_S_SET_TREMOLO_WAVEFORM: + //case IT_S_SET_PANBRELLO_WAVEFORM: + /* Waveforms for commands S3x, S4x and S5x: + * 0: Sine wave + * 1: Ramp down + * 2: Square wave + * 3: Random wave + */ + case IT_S_FINE_PATTERN_DELAY: + sigrenderer->tick += effectvalue & 15; + break; + //case IT_S7: + case IT_S_SET_PAN: + channel->pan = + ((effectvalue & 15) << 2) | + ((effectvalue & 15) >> 2); + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + break; + case IT_S_SET_SURROUND_SOUND: + if ((effectvalue & 15) == 1) + channel->pan = IT_SURROUND; + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + break; + case IT_S_SET_HIGH_OFFSET: + channel->high_offset = effectvalue & 15; + break; + //case IT_S_PATTERN_LOOP: + case IT_S_DELAYED_NOTE_CUT: + channel->note_cut_count = effectvalue & 15; + if (!channel->note_cut_count) { + if (sigdata->flags & IT_WAS_AN_XM) + channel->volume = 0; + else + channel->note_cut_count = 1; + } + break; + case IT_S_SET_MIDI_MACRO: + channel->SFmacro = effectvalue & 15; + break; + } + } + break; + case IT_SET_SONG_TEMPO: + { + unsigned char v = entry->effectvalue; + if (v == 0) + v = channel->lastW; + channel->lastW = v; + if (v < 0x10) + sigrenderer->temposlide = -v; + else if (v < 0x20) + sigrenderer->temposlide = v & 15; + else + sigrenderer->tempo = v; + } + break; + case IT_FINE_VIBRATO: + { + unsigned char speed = entry->effectvalue >> 4; + unsigned char depth = entry->effectvalue & 15; + if (speed == 0) + speed = channel->lastHspeed; + channel->lastHspeed = speed; + if (depth == 0) + depth = channel->lastHdepth; + else { + if (sigdata->flags & IT_OLD_EFFECTS) + depth <<= 1; + channel->lastHdepth = depth; + } + if (channel->playing) { + channel->playing->vibrato_speed = speed; + channel->playing->vibrato_depth = depth; + channel->playing->vibrato_n++; + } + } + break; + case IT_SET_GLOBAL_VOLUME: + if (entry->effectvalue <= 128) + sigrenderer->globalvolume = entry->effectvalue; +#ifdef VOLUME_OUT_OF_RANGE_SETS_MAXIMUM + else + sigrenderer->globalvolume = 128; +#endif + break; + case IT_GLOBAL_VOLUME_SLIDE: + { + unsigned char v = entry->effectvalue; + if (v == 0) + v = channel->lastW; + channel->lastW = v; + if ((v & 0x0F) == 0) { /* Wx0 */ + sigrenderer->globalvolslide = + (sigdata->flags & IT_WAS_AN_XM) ? (v >> 4)*2 : (v >> 4); + } else if ((v & 0xF0) == 0) { /* W0x */ + sigrenderer->globalvolslide = + (sigdata->flags & IT_WAS_AN_XM) ? (-v)*2 : (-v); + } else if ((v & 0x0F) == 0x0F) { /* WxF */ + sigrenderer->globalvolume += v >> 4; + if (sigrenderer->globalvolume > 128) sigrenderer->globalvolume = 128; + } else if ((v & 0xF0) == 0xF0) { /* WFx */ + sigrenderer->globalvolume -= v & 15; + if (sigrenderer->globalvolume > 128) sigrenderer->globalvolume = 0; + } + } + break; + case IT_SET_PANNING: + channel->pan = (entry->effectvalue + 2) >> 2; + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + break; + //case IT_PANBRELLO: + case IT_MIDI_MACRO: + { + IT_MIDI *midi = sigdata->midi ? sigdata->midi : &default_midi; + if (entry->effectvalue >= 0x80) { + int n = midi->Zmacrolen[entry->effectvalue-0x80]; + int i; + for (i = 0; i < n; i++) + it_send_midi(sigrenderer, channel, midi->Zmacro[entry->effectvalue-0x80][i]); + } else { + int n = midi->SFmacrolen[channel->SFmacro]; + int i, j; + for (i = 0, j = 1; i < n; i++, j <<= 1) + it_send_midi(sigrenderer, channel, + midi->SFmacroz[channel->SFmacro] & j ? + entry->effectvalue : midi->SFmacro[channel->SFmacro][i]); + } + } + break; + } + } + + if (!(sigdata->flags & IT_WAS_AN_XM)) + post_process_it_volpan(sigrenderer, entry); + + return 0; +} + + + +static int process_it_note_data(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry) +{ + DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; + IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel]; + + // When tone portamento and instrument are specified: + // If Gxx is off: + // - same sample, do nothing but portamento + // - diff sample, retrigger all but keep current note+slide + do porta + // - if instrument is invalid, nothing; if sample is invalid, cut + // If Gxx is on: + // - same sample or new sample invalid, retrigger envelopes + // - diff sample/inst, start using new envelopes + // When tone portamento is specified alone, sample won't change. + // TODO: consider what happens with instrument alone after all this... + + if (entry->mask & (IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT)) { + if (entry->mask & IT_ENTRY_INSTRUMENT) + channel->instrument = entry->instrument; + instrument_to_sample(sigdata, channel); + if (channel->note < 120) { + if ((sigdata->flags & IT_USE_INSTRUMENTS) && channel->sample == 0) + return 1; + if (entry->mask & IT_ENTRY_INSTRUMENT) + get_default_volpan(sigdata, channel); + } else + it_retrigger_note(sigrenderer, channel); + } + + /** WARNING: This is not ideal, since channel->playing might not get allocated owing to lack of memory... */ + if (channel->playing && + (((entry->mask & IT_ENTRY_VOLPAN) && entry->volpan >= 193 && entry->volpan <= 202) || + ((entry->mask & IT_ENTRY_EFFECT) && (entry->effect == IT_TONE_PORTAMENTO || entry->effect == IT_VOLSLIDE_TONEPORTA)))) + { + if (entry->mask & IT_ENTRY_INSTRUMENT) { + if (sigdata->flags & IT_COMPATIBLE_GXX) + retrigger_it_envelopes(sigdata, channel); + else if ((!(sigdata->flags & IT_USE_INSTRUMENTS) || + (channel->instrument >= 1 && channel->instrument <= sigdata->n_instruments)) && + channel->sample != channel->playing->sampnum) + { + unsigned char note = channel->playing->note; + int slide = channel->playing->slide; + it_retrigger_note(sigrenderer, channel); + if (channel->playing) { + channel->playing->note = note; + channel->playing->slide = slide; + // Should we be preserving sample_vibrato_time? depth? + } + } + } + + if ((entry->mask & IT_ENTRY_VOLPAN) && entry->volpan >= 193 && entry->volpan <= 202) { + /* Tone Portamento in the volume column */ + static const unsigned char slidetable[] = {0, 1, 4, 8, 16, 32, 64, 96, 128, 255}; + unsigned char v = slidetable[entry->volpan - 193]; + if (sigdata->flags & IT_COMPATIBLE_GXX) { + if (v == 0) + v = channel->lastG; + channel->lastG = v; + } else { + if (v == 0) + v = channel->lastEF; + channel->lastEF = v; + } + if (entry->mask & IT_ENTRY_NOTE) + if (channel->sample) + channel->destnote = channel->truenote; + channel->toneporta = v << 4; + } else { + /* Tone Portamento in the effect column */ + unsigned char v; + if (entry->effect == IT_TONE_PORTAMENTO) + v = entry->effectvalue; + else + v = 0; + if (sigdata->flags & IT_COMPATIBLE_GXX) { + if (v == 0) + v = channel->lastG; + channel->lastG = v; + } else { + if (v == 0) + v = channel->lastEF; + channel->lastEF = v; + } + if (entry->mask & IT_ENTRY_NOTE) + if (channel->sample) + channel->destnote = channel->truenote; + channel->toneporta = v << 4; + } + } else if ((entry->mask & IT_ENTRY_NOTE) || + ((entry->mask & IT_ENTRY_INSTRUMENT) && (!channel->playing || entry->instrument != channel->playing->instnum))) + { + if (channel->note < 120) { + get_true_pan(sigdata, channel); + it_retrigger_note(sigrenderer, channel); + } + } + + if (entry->mask & IT_ENTRY_VOLPAN) { + if (entry->volpan <= 64) { + /* Volume */ + channel->volume = entry->volpan; + } else if (entry->volpan <= 74) { + /* Fine volume slide up */ + unsigned char v = entry->volpan - 65; + if (v == 0) + v = channel->lastvolslide; + channel->lastvolslide = v; + /* = effect DxF where x == entry->volpan - 65 */ + channel->volume += v; + if (channel->volume > 64) channel->volume = 64; + } else if (entry->volpan <= 84) { + /* Fine volume slide down */ + unsigned char v = entry->volpan - 75; + if (v == 0) + v = channel->lastvolslide; + channel->lastvolslide = v; + /* = effect DFx where x == entry->volpan - 75 */ + channel->volume -= v; + if (channel->volume > 64) channel->volume = 0; + } else if (entry->volpan < 128) { + /* Volume slide up */ + /* Volume slide down */ + /* Portamento down */ + /* Portamento up */ + } else if (entry->volpan <= 192) { + /* Pan */ + channel->pan = entry->volpan - 128; + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + } + /* else */ + /* Tone Portamento */ + /* Vibrato */ + } + return 0; +} + + + +static void retrigger_xm_envelopes(IT_PLAYING *playing) +{ + playing->volume_envelope.next_node = 0; + playing->volume_envelope.tick = -1; + playing->pan_envelope.next_node = 0; + playing->pan_envelope.tick = -1; + playing->fadeoutcount = 1024; +} + + + +static void process_xm_note_data(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry) +{ + DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; + IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel]; + + if (entry->mask & IT_ENTRY_INSTRUMENT) { + channel->instrument = entry->instrument; + instrument_to_sample(sigdata, channel); + if (channel->playing) { + /* Retrigger vol/pan envelopes if enabled, and cancel fadeout. + * Also reset vol/pan to that of _original_ instrument. + */ + channel->playing->flags &= ~(IT_PLAYING_SUSTAINOFF | IT_PLAYING_FADING); + it_playing_update_resamplers(channel->playing); + + channel->volume = channel->playing->sample->default_volume; + if (channel->pan >= 128 && channel->pan <= 192) + channel->pan = channel->playing->sample->default_pan - 128; + + retrigger_xm_envelopes(channel->playing); + } + } + + if (entry->mask & IT_ENTRY_NOTE) { + if (!(entry->mask & IT_ENTRY_INSTRUMENT)) + instrument_to_sample(sigdata, channel); + + if (channel->note >= 120) { + if (channel->playing) { + if (!(sigdata->instrument[channel->instrument-1].volume_envelope.flags & IT_ENVELOPE_ON)) + if (!(entry->mask & IT_ENTRY_INSTRUMENT)) + channel->volume = 0; + channel->playing->flags |= IT_PLAYING_SUSTAINOFF | IT_PLAYING_FADING; + it_playing_update_resamplers(channel->playing); + } + } else if (channel->sample == 0) { + /** If we get here, one of the following is the case: + ** 1. The instrument has never been specified on this channel. + ** 2. The specified instrument is invalid. + ** 3. The instrument has no sample mapped to the selected note. + ** What should happen? + ** + ** Experimentation shows that any existing note stops and cannot + ** be brought back. A subsequent instrument change fixes that. + **/ + if (channel->playing) { + free(channel->playing); + channel->playing = NULL; + } + return; + } else if (channel->playing && (entry->mask & IT_ENTRY_VOLPAN) && ((entry->volpan>>4) == 0xF)) { + /* Don't retrigger note; portamento in the volume column. */ + } else if (channel->playing && + (entry->mask & IT_ENTRY_EFFECT) && + (entry->effect == IT_TONE_PORTAMENTO || + entry->effect == IT_VOLSLIDE_TONEPORTA)) { + /* Don't retrigger note; portamento in the effects column. */ + } else { + channel->destnote = IT_NOTE_OFF; + + if (!channel->playing) { + channel->playing = (IT_PLAYING *)malloc(sizeof(*channel->playing)); + if (!channel->playing) + return; + // Adding the following seems to do the trick for the case where a piece starts with an instrument alone and then some notes alone. + retrigger_xm_envelopes(channel->playing); + } + + channel->playing->flags = 0; + channel->playing->channel = channel; + channel->playing->sample = &sigdata->sample[channel->sample-1]; + if (sigdata->flags & IT_USE_INSTRUMENTS) + channel->playing->instrument = &sigdata->instrument[channel->instrument-1]; + else + channel->playing->instrument = NULL; + channel->playing->env_instrument = channel->playing->instrument; + channel->playing->sampnum = channel->sample; + channel->playing->instnum = channel->instrument; + channel->playing->channel_volume = channel->channelvolume; + channel->playing->note = channel->truenote; + channel->playing->filter_cutoff = 127; + channel->playing->filter_resonance = 0; + channel->playing->true_filter_cutoff = 127 << 8; + channel->playing->true_filter_resonance = 0; + channel->playing->vibrato_speed = 0; + channel->playing->vibrato_depth = 0; + channel->playing->vibrato_n = 0; + channel->playing->vibrato_time = 0; + channel->playing->tremolo_speed = 0; + channel->playing->tremolo_depth = 0; + channel->playing->tremolo_time = 0; + channel->playing->sample_vibrato_time = 0; + channel->playing->sample_vibrato_depth = 0; + channel->playing->slide = 0; + it_reset_filter_state(&channel->playing->filter_state[0]); // Are these + it_reset_filter_state(&channel->playing->filter_state[1]); // necessary? + it_playing_reset_resamplers(channel->playing, 0); + + /** WARNING - is everything initialised? */ + } + } + + if ((entry->mask & (IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT)) == (IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT)) { + if (channel->playing) retrigger_xm_envelopes(channel->playing); + get_default_volpan(sigdata, channel); + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + } + + if ((entry->mask & IT_ENTRY_VOLPAN) && ((entry->volpan>>4) == 0xF)) { + /* Tone Portamento */ + unsigned char v = (entry->volpan & 15) << 4; + if (v == 0) + v = channel->lastG; + channel->lastG = v; + if (entry->mask & IT_ENTRY_NOTE) + if (channel->sample) + channel->destnote = channel->truenote; + channel->toneporta = v << 4; + } else if ((entry->mask & IT_ENTRY_EFFECT) && + (entry->effect == IT_TONE_PORTAMENTO || + entry->effect == IT_VOLSLIDE_TONEPORTA)) { + unsigned char v; + if (entry->effect == IT_TONE_PORTAMENTO) + v = entry->effectvalue; + else + v = 0; + if (v == 0) + v = channel->lastG; + channel->lastG = v; + if (entry->mask & IT_ENTRY_NOTE) + if (channel->sample) + channel->destnote = channel->truenote; + channel->toneporta = v << 4; + } + + if (entry->mask & IT_ENTRY_VOLPAN) { + int effect = entry->volpan >> 4; + int value = entry->volpan & 15; + switch (effect) { + case 0x6: /* Volume slide down */ + channel->xm_volslide = -value; + break; + case 0x7: /* Volume slide up */ + channel->xm_volslide = value; + break; + case 0x8: /* Fine volume slide down */ + channel->volume -= value; + if (channel->volume > 64) channel->volume = 0; + break; + case 0x9: /* Fine volume slide up */ + channel->volume += value; + if (channel->volume > 64) channel->volume = 64; + break; + case 0xA: /* Set vibrato speed */ + if (value) + channel->lastHspeed = value; + if (channel->playing) + channel->playing->vibrato_speed = channel->lastHspeed; + break; + case 0xB: /* Vibrato */ + if (value) + channel->lastHdepth = value << 2; /** WARNING: correct ? */ + if (channel->playing) { + channel->playing->vibrato_depth = channel->lastHdepth; + channel->playing->vibrato_speed = channel->lastHspeed; + channel->playing->vibrato_n++; + } + break; + case 0xC: /* Set panning */ + channel->pan = (value*64)/15; + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + break; + case 0xD: /* Pan slide left */ + // TODO + // channel->xm_panslide = -value; + break; + case 0xE: /* Pan slide Right */ + // TODO + // channel->xm_panslide = value; + break; + case 0xF: /* Tone porta */ + break; + default: /* Volume */ + channel->volume = entry->volpan - 0x10; + break; + } + } +} + + + +/* This function assumes !IT_IS_END_ROW(entry). */ +static int process_note_data(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry) +{ + DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; + + if (sigdata->flags & IT_WAS_AN_XM) + process_xm_note_data(sigrenderer, entry); + else + if (process_it_note_data(sigrenderer, entry)) return 0; + + return process_effects(sigrenderer, entry); +} + + + +static int process_entry(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry) +{ + IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel]; + + if (entry->mask & IT_ENTRY_NOTE) + channel->note = entry->note; + + if ((entry->mask & IT_ENTRY_EFFECT) && entry->effect == IT_S) { + /* channel->lastS was set in update_pattern_variables(). */ + unsigned char effectvalue = channel->lastS; + if (effectvalue >> 4 == IT_S_NOTE_DELAY) { + channel->note_delay_count = effectvalue & 15; + if (channel->note_delay_count == 0) + channel->note_delay_count = 1; + channel->note_delay_entry = entry; + return 0; + } + } + + return process_note_data(sigrenderer, entry); +} + + + +static void update_tick_counts(DUMB_IT_SIGRENDERER *sigrenderer) +{ + int i; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + IT_CHANNEL *channel = &sigrenderer->channel[i]; + + if (channel->note_cut_count) { + channel->note_cut_count--; + if (channel->note_cut_count == 0) { + if (sigrenderer->sigdata->flags & IT_WAS_AN_XM) + channel->volume = 0; + else if (channel->playing) { + free(channel->playing); + channel->playing = NULL; + } + } + } else if (channel->note_delay_count) { + channel->note_delay_count--; + if (channel->note_delay_count == 0) + process_note_data(sigrenderer, channel->note_delay_entry); + /* Don't bother checking the return value; if the note + * was delayed, there can't have been a speed=0. + */ + } + } +} + + + +static int envelope_get_y(IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe) +{ + int ys, ye; + int ts, te; + int t; + + if (pe->next_node <= 0) + return envelope->node_y[0] << IT_ENVELOPE_SHIFT; + + if (pe->next_node >= envelope->n_nodes) + return envelope->node_y[envelope->n_nodes-1] << IT_ENVELOPE_SHIFT; + + ys = envelope->node_y[pe->next_node-1] << IT_ENVELOPE_SHIFT; + ts = envelope->node_t[pe->next_node-1]; + te = envelope->node_t[pe->next_node]; + + if (ts == te) + return ys; + + ye = envelope->node_y[pe->next_node] << IT_ENVELOPE_SHIFT; + + t = pe->tick; + + return ys + (ye - ys) * (t - ts) / (te - ts); +} + + + +static int it_envelope_end(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe) +{ + if (pe->next_node >= envelope->n_nodes) + return 1; + + if (pe->tick < envelope->node_t[pe->next_node]) return 0; + + if ((envelope->flags & IT_ENVELOPE_LOOP_ON) && + envelope->loop_end >= pe->next_node && + envelope->node_t[envelope->loop_end] <= pe->tick) return 0; + + if ((envelope->flags & IT_ENVELOPE_SUSTAIN_LOOP) && + !(playing->flags & IT_PLAYING_SUSTAINOFF) && + envelope->sus_loop_end >= pe->next_node && + envelope->node_t[envelope->sus_loop_end] <= pe->tick) return 0; + + if (envelope->node_t[envelope->n_nodes-1] <= pe->tick) return 1; + + return 0; +} + + + +/* This returns 1 if the envelope finishes. */ +static int update_it_envelope(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe) +{ + if (!(envelope->flags & IT_ENVELOPE_ON)) + return 0; + + if (pe->next_node >= envelope->n_nodes) + return 1; + + while (pe->tick >= envelope->node_t[pe->next_node]) { + if ((envelope->flags & IT_ENVELOPE_LOOP_ON) && pe->next_node == envelope->loop_end) { + pe->next_node = envelope->loop_start; + pe->tick = envelope->node_t[envelope->loop_start]; + return it_envelope_end(playing, envelope, pe); + } + if ((envelope->flags & IT_ENVELOPE_SUSTAIN_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF) && pe->next_node == envelope->sus_loop_end) { + pe->next_node = envelope->sus_loop_start; + pe->tick = envelope->node_t[envelope->sus_loop_start]; + return it_envelope_end(playing, envelope, pe); + } + + pe->next_node++; + + if (pe->next_node >= envelope->n_nodes) + return 1; + } + + pe->tick++; + + return it_envelope_end(playing, envelope, pe); +} + + + +static void update_it_envelopes(IT_PLAYING *playing) +{ + IT_ENVELOPE *envelope = &playing->env_instrument->volume_envelope; + + if (update_it_envelope(playing, envelope, &playing->volume_envelope)) { + playing->flags |= IT_PLAYING_FADING; + if (envelope->n_nodes && envelope->node_y[envelope->n_nodes-1] == 0) + playing->flags |= IT_PLAYING_DEAD; + } + + update_it_envelope(playing, &playing->env_instrument->pan_envelope, &playing->pan_envelope); + update_it_envelope(playing, &playing->env_instrument->pitch_envelope, &playing->pitch_envelope); +} + + + +static int xm_envelope_is_sustaining(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe) +{ + if ((envelope->flags & IT_ENVELOPE_SUSTAIN_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF)) + if (envelope->sus_loop_start < envelope->n_nodes) + if (pe->tick == envelope->node_t[envelope->sus_loop_start]) + return 1; + return 0; +} + + + +static void update_xm_envelope(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe) +{ + if (!(envelope->flags & IT_ENVELOPE_ON)) + return; + + if (xm_envelope_is_sustaining(playing, envelope, pe)) + return; + + if (pe->tick >= envelope->node_t[envelope->n_nodes-1]) + return; + + pe->tick++; + + /* pe->next_node must be kept up to date for envelope_get_y(). */ + while (pe->tick > envelope->node_t[pe->next_node]) + pe->next_node++; + + if ((envelope->flags & IT_ENVELOPE_LOOP_ON) && envelope->loop_end < envelope->n_nodes) { + if (pe->tick == envelope->node_t[envelope->loop_end]) { + pe->next_node = MID(0, envelope->loop_start, envelope->n_nodes - 1); + pe->tick = envelope->node_t[pe->next_node]; + } + } + + if (xm_envelope_is_sustaining(playing, envelope, pe)) + return; + + if (pe->tick >= envelope->node_t[envelope->n_nodes-1]) + return; +} + + + +static void update_xm_envelopes(IT_PLAYING *playing) +{ + update_xm_envelope(playing, &playing->env_instrument->volume_envelope, &playing->volume_envelope); + update_xm_envelope(playing, &playing->env_instrument->pan_envelope, &playing->pan_envelope); +} + + + +static void update_fadeout(DUMB_IT_SIGDATA *sigdata, IT_PLAYING *playing) +{ + if (playing->flags & IT_PLAYING_FADING) { + playing->fadeoutcount -= playing->env_instrument->fadeout; + if (playing->fadeoutcount <= 0) { + playing->fadeoutcount = 0; + if (!(sigdata->flags & IT_WAS_AN_XM)) + playing->flags |= IT_PLAYING_DEAD; + } + } +} + + + +static void process_playing(DUMB_IT_SIGDATA *sigdata, IT_PLAYING *playing) +{ + if (playing->instrument) { + if (sigdata->flags & IT_WAS_AN_XM) + update_xm_envelopes(playing); + else + update_it_envelopes(playing); + update_fadeout(sigdata, playing); + } + + //Calculate final volume if required + //Calculate final pan if required + + if (sigdata->flags & IT_WAS_AN_XM) { + /* 'depth' is used to store the tick number for XM files. */ + if (playing->sample_vibrato_depth < playing->sample->vibrato_rate) + playing->sample_vibrato_depth++; + } else { + playing->sample_vibrato_depth += playing->sample->vibrato_rate; + if (playing->sample_vibrato_depth > playing->sample->vibrato_depth << 8) + playing->sample_vibrato_depth = playing->sample->vibrato_depth << 8; + } + + playing->sample_vibrato_time += playing->sample->vibrato_speed; +} + + + +static void process_all_playing(DUMB_IT_SIGRENDERER *sigrenderer) +{ + DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; + int i; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + IT_CHANNEL *channel = &sigrenderer->channel[i]; + IT_PLAYING *playing = channel->playing; + + if (playing) { + int vibrato_shift = it_sine[playing->vibrato_time]; + vibrato_shift *= playing->vibrato_n; + vibrato_shift *= playing->vibrato_depth; + vibrato_shift >>= 4; + + if (sigdata->flags & IT_OLD_EFFECTS) + vibrato_shift = -vibrato_shift; + + playing->volume = channel->volume; + playing->pan = channel->truepan; + + if (sigdata->flags & IT_LINEAR_SLIDES) { + int currpitch = ((playing->note - 60) << 8) + playing->slide + + vibrato_shift; + + /* We add a feature here, which is that of keeping the pitch + * within range. Otherwise it crashes. Trust me. It happened. + * The limit 32768 gives almost 11 octaves either way. + */ + if (currpitch < -32768) + currpitch = -32768; + else if (currpitch > 32767) + currpitch = 32767; + + playing->delta = (float)pow(DUMB_PITCH_BASE, currpitch); + playing->delta *= playing->sample->C5_speed / 65536.0f; + } else { + int slide = playing->slide + vibrato_shift; + + playing->delta = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note); + /* playing->delta is 1.0 for C-5, 0.5 for C-6, etc. */ + + playing->delta *= 1.0f / playing->sample->C5_speed; + + playing->delta -= slide / AMIGA_DIVISOR; + + if (playing->delta < (1.0f / 65536.0f) / 32768.0f) { + // Should XM notes die if Amiga slides go out of range? + playing->flags |= IT_PLAYING_DEAD; + continue; + } + + playing->delta = (1.0f / 65536.0f) / playing->delta; + } + + playing->delta *= (float)pow(DUMB_SEMITONE_BASE, channel->arpeggio >> 8); + + playing->filter_cutoff = channel->filter_cutoff; + playing->filter_resonance = channel->filter_resonance; + } + } + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + if (sigrenderer->channel[i].playing) { + process_playing(sigdata, sigrenderer->channel[i].playing); + if (!(sigdata->flags & IT_WAS_AN_XM)) { + if ((sigrenderer->channel[i].playing->flags & (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) == (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) { + free(sigrenderer->channel[i].playing); + sigrenderer->channel[i].playing = NULL; + } + } + } + } + + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) { + if (sigrenderer->playing[i]) { + process_playing(sigdata, sigrenderer->playing[i]); + if (sigrenderer->playing[i]->flags & IT_PLAYING_DEAD) { + free(sigrenderer->playing[i]); + sigrenderer->playing[i] = NULL; + } + } + } +} + + + +static int process_tick(DUMB_IT_SIGRENDERER *sigrenderer) +{ + DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata; + + // Set note vol/freq to vol/freq set for each channel + + if (sigrenderer->speed && --sigrenderer->tick == 0) { + reset_tick_counts(sigrenderer); + sigrenderer->tick = sigrenderer->speed; + sigrenderer->rowcount--; + if (sigrenderer->rowcount == 0) { + sigrenderer->rowcount = 1; + if (sigrenderer->pat_loop_row >= 0) { + int n = sigrenderer->pat_loop_row - 1; + sigrenderer->row = sigrenderer->processrow = n; + sigrenderer->pat_loop_row = -1; + if (n < 0) + sigrenderer->entry = NULL; + else { + sigrenderer->entry = sigrenderer->entry_start; + while (n) { + while (sigrenderer->entry < sigrenderer->entry_end) { + if (IT_IS_END_ROW(sigrenderer->entry)) { + sigrenderer->entry++; + break; + } + sigrenderer->entry++; + } + n--; + } + } + } + + sigrenderer->processrow++; + + if (sigrenderer->processrow >= sigrenderer->n_rows) { + IT_PATTERN *pattern; + int n; + + sigrenderer->processrow = sigrenderer->breakrow; + sigrenderer->breakrow = 0; + + for (;;) { + sigrenderer->processorder++; + + if (sigrenderer->processorder >= sigdata->n_orders) { + sigrenderer->processorder = sigdata->restart_position; + if (sigrenderer->processorder >= sigdata->n_orders) { + /* Restarting beyond end. We'll loop for now. */ + sigrenderer->processorder = -1; + continue; + } + } + + n = sigdata->order[sigrenderer->processorder]; + + if (n < sigdata->n_patterns) + break; + +#ifdef INVALID_ORDERS_END_SONG + if (n != IT_ORDER_SKIP) + sigrenderer->processorder = -1; +#else + if (n == IT_ORDER_END) + sigrenderer->processorder = -1; +#endif + } + + pattern = &sigdata->pattern[n]; + + sigrenderer->n_rows = pattern->n_rows; + + if (sigrenderer->processrow >= sigrenderer->n_rows) + sigrenderer->processrow = 0; + +/** WARNING - everything pertaining to a new pattern initialised? */ + + sigrenderer->entry = sigrenderer->entry_start = pattern->entry; + sigrenderer->entry_end = sigrenderer->entry + pattern->n_entries; + + if (sigrenderer->order >= sigrenderer->processorder) { + if (sigrenderer->callbacks->loop) { + if ((*sigrenderer->callbacks->loop)(sigrenderer->callbacks->loop_data)) + return 1; + if (sigrenderer->speed == 0) + goto speed0; /* I love goto */ + } + } + sigrenderer->order = sigrenderer->processorder; + + n = sigrenderer->processrow; + while (n) { + while (sigrenderer->entry < sigrenderer->entry_end) { + if (IT_IS_END_ROW(sigrenderer->entry)) { + sigrenderer->entry++; + break; + } + sigrenderer->entry++; + } + n--; + } + sigrenderer->row = sigrenderer->processrow; + } else { + if (sigrenderer->entry) { + while (sigrenderer->entry < sigrenderer->entry_end) { + if (IT_IS_END_ROW(sigrenderer->entry)) { + sigrenderer->entry++; + break; + } + sigrenderer->entry++; + } + sigrenderer->row++; + } else { + sigrenderer->entry = sigrenderer->entry_start; + sigrenderer->row = 0; + } + } + + reset_effects(sigrenderer); + + { + IT_ENTRY *entry = sigrenderer->entry; + + while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry)) + update_pattern_variables(sigrenderer, entry++); + } + + { + IT_ENTRY *entry = sigrenderer->entry; + + while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry)) + if (process_entry(sigrenderer, entry++)) + return 1; + } + + if (!(sigdata->flags & IT_OLD_EFFECTS)) + update_smooth_effects(sigrenderer); + } else { + { + IT_ENTRY *entry = sigrenderer->entry; + + while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry)) + process_effects(sigrenderer, entry++); + /* Don't bother checking the return value; if there + * was a pattern delay, there can't be a speed=0. + */ + } + + update_effects(sigrenderer); + } + } else { + speed0: + update_effects(sigrenderer); + update_tick_counts(sigrenderer); + } + + process_all_playing(sigrenderer); + + sigrenderer->time_left += TICK_TIME_DIVIDEND / sigrenderer->tempo; + + return 0; +} + + + +int dumb_it_max_to_mix = 64; + + + +static float calculate_volume(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *playing, float volume) +{ + if (volume != 0) { + int vol; + + if (playing->channel->flags & IT_CHANNEL_MUTED) + return 0; + + if ((playing->channel->tremor_time & 192) == 128) + return 0; + + vol = it_sine[playing->tremolo_time]; + vol *= playing->tremolo_depth; + + vol = (playing->volume << 5) + vol; + + if (vol <= 0) + return 0; + + if (vol > 64 << 5) + vol = 64 << 5; + + volume *= vol; /* 64 << 5 */ + volume *= playing->sample->global_volume; /* 64 */ + volume *= playing->channel_volume; /* 64 */ + volume *= sigrenderer->globalvolume; /* 128 */ + volume *= sigrenderer->sigdata->mixing_volume; /* 128 */ + volume *= 1.0f / ((64 << 5) * 64.0f * 64.0f * 128.0f * 128.0f); + + if (volume && playing->instrument) { + if (playing->env_instrument->volume_envelope.flags & IT_ENVELOPE_ON) { + volume *= envelope_get_y(&playing->env_instrument->volume_envelope, &playing->volume_envelope); + volume *= 1.0f / (64 << IT_ENVELOPE_SHIFT); + } + volume *= playing->instrument->global_volume; /* 128 */ + volume *= playing->fadeoutcount; /* 1024 */ + volume *= 1.0f / (128.0f * 1024.0f); + } + } + + return volume; +} + + + +static int apply_pan_envelope(IT_PLAYING *playing) +{ + int pan = playing->pan; + if (pan <= 64 << IT_ENVELOPE_SHIFT && playing->env_instrument && (playing->env_instrument->pan_envelope.flags & IT_ENVELOPE_ON)) { + int p = envelope_get_y(&playing->env_instrument->pan_envelope, &playing->pan_envelope); + if (pan > 32 << IT_ENVELOPE_SHIFT) + p *= (64 << IT_ENVELOPE_SHIFT) - pan; + else + p *= pan; + pan += p >> (5 + IT_ENVELOPE_SHIFT); + } + return pan; +} + + + +/* Note: if a click remover is provided, and store_end_sample is set, then + * the end point will be computed twice. This situation should not arise. + */ +static long render_playing(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *playing, float volume, float delta, long pos, long size, sample_t **samples, int store_end_sample, int *left_to_mix) +{ + int pan; + + long size_rendered; + + if (playing->flags & IT_PLAYING_DEAD) + return 0; + + if (*left_to_mix <= 0) + volume = 0; + + pan = apply_pan_envelope(playing); + +#define RESAMPLERV(rv, resampler, dst, volume) \ +{ \ + rv = dumb_resample(resampler, dst, size, volume, delta); \ + if (store_end_sample) \ + (dst)[rv] = RESAMPLE_VALUE(resampler, volume); \ +} + +#define RESAMPLE(resampler, dst, volume) \ +{ \ + int i; \ + RESAMPLERV(i, resampler, dst, volume); \ +} + +#define RESAMPLE_VALUE(resampler, volume) \ + dumb_resample_get_current_sample(resampler, volume) + + if (volume == 0) { + size_rendered = dumb_resample(&playing->resampler[0], NULL, size, 0, delta); + if (playing->sample->flags & IT_SAMPLE_STEREO) + dumb_resample(&playing->resampler[1], NULL, size, 0, delta); + } else { + if (sigrenderer->n_channels == 2) { + float vol = volume; + DUMB_RESAMPLER start = playing->resampler[0]; + if (!IT_IS_SURROUND_SHIFTED(pan)) vol *= 2.0f - pan * (1.0f / (32 << IT_ENVELOPE_SHIFT)); + if (sigrenderer->click_remover && sigrenderer->click_remover[0]) + dumb_record_click(sigrenderer->click_remover[0], pos, RESAMPLE_VALUE(&playing->resampler[0], vol)); + RESAMPLERV(size_rendered, &playing->resampler[0], samples[0] + pos, vol); + if (sigrenderer->click_remover && sigrenderer->click_remover[0]) + dumb_record_click(sigrenderer->click_remover[0], pos + size_rendered, -RESAMPLE_VALUE(&playing->resampler[0], vol)); + vol = -vol; + if (!IT_IS_SURROUND_SHIFTED(pan)) vol += 2.0f * volume; + if (playing->sample->flags & IT_SAMPLE_STEREO) { + if (sigrenderer->click_remover && sigrenderer->click_remover[1]) + dumb_record_click(sigrenderer->click_remover[1], pos, RESAMPLE_VALUE(&playing->resampler[1], vol)); + RESAMPLE(&playing->resampler[1], samples[1] + pos, vol); + if (sigrenderer->click_remover && sigrenderer->click_remover[1]) + dumb_record_click(sigrenderer->click_remover[1], pos + size_rendered, -RESAMPLE_VALUE(&playing->resampler[1], vol)); + } else { + playing->resampler[0] = start; + if (sigrenderer->click_remover && sigrenderer->click_remover[1]) + dumb_record_click(sigrenderer->click_remover[1], pos, RESAMPLE_VALUE(&playing->resampler[0], vol)); + RESAMPLE(&playing->resampler[0], samples[1] + pos, vol); + if (sigrenderer->click_remover && sigrenderer->click_remover[1]) + dumb_record_click(sigrenderer->click_remover[1], pos + size_rendered, -RESAMPLE_VALUE(&playing->resampler[0], vol)); + } + } else { + if (playing->sample->flags & IT_SAMPLE_STEREO) { + float vol = 0.5f * volume; + if (!IT_IS_SURROUND_SHIFTED(pan)) vol *= 2.0f - pan * (1.0f / (32 << IT_ENVELOPE_SHIFT)); + if (sigrenderer->click_remover && sigrenderer->click_remover[0]) { + sample_t startstep, endstep; + startstep = RESAMPLE_VALUE(&playing->resampler[0], vol); + RESAMPLE(&playing->resampler[0], samples[0] + pos, vol); + endstep = RESAMPLE_VALUE(&playing->resampler[0], vol); + if (!IT_IS_SURROUND_SHIFTED(pan)) vol = 2.0f * volume - vol; + startstep += RESAMPLE_VALUE(&playing->resampler[1], vol); + RESAMPLERV(size_rendered, &playing->resampler[1], samples[0] + pos, vol); + endstep += RESAMPLE_VALUE(&playing->resampler[1], vol); + dumb_record_click(sigrenderer->click_remover[0], pos, startstep); + dumb_record_click(sigrenderer->click_remover[0], pos + size_rendered, -endstep); + } else { + RESAMPLE(&playing->resampler[0], samples[0] + pos, vol); + if (!IT_IS_SURROUND_SHIFTED(pan)) vol = 2.0f * volume - vol; + RESAMPLERV(size_rendered, &playing->resampler[1], samples[0] + pos, vol); + } + } else { + if (sigrenderer->click_remover && sigrenderer->click_remover[0]) + dumb_record_click(sigrenderer->click_remover[0], pos, RESAMPLE_VALUE(&playing->resampler[0], volume)); + RESAMPLERV(size_rendered, &playing->resampler[0], samples[0] + pos, volume); + if (sigrenderer->click_remover && sigrenderer->click_remover[0]) + dumb_record_click(sigrenderer->click_remover[0], pos + size_rendered, -RESAMPLE_VALUE(&playing->resampler[0], volume)); + } + } + (*left_to_mix)--; + } + + if (playing->resampler[0].dir == 0) + playing->flags |= IT_PLAYING_DEAD; + + return size_rendered; +} + + + +typedef struct IT_TO_MIX +{ + IT_PLAYING *playing; + float volume; +} +IT_TO_MIX; + + + +static int it_to_mix_compare(const void *e1, const void *e2) +{ + if (((const IT_TO_MIX *)e1)->volume > ((const IT_TO_MIX *)e2)->volume) + return -1; + + if (((const IT_TO_MIX *)e1)->volume < ((const IT_TO_MIX *)e2)->volume) + return 1; + + return 0; +} + + + +static void apply_pitch_modifications(DUMB_IT_SIGDATA *sigdata, IT_PLAYING *playing, float *delta, int *cutoff) +{ + { + int sample_vibrato_shift = it_sine[playing->sample_vibrato_time]; + + if (sigdata->flags & IT_WAS_AN_XM) { + int depth = playing->sample->vibrato_depth; /* True depth */ + if (playing->sample->vibrato_rate) { + depth *= playing->sample_vibrato_depth; /* Tick number */ + depth /= playing->sample->vibrato_rate; /* XM sweep */ + } + sample_vibrato_shift *= depth; + } else + sample_vibrato_shift *= playing->sample_vibrato_depth >> 8; + + sample_vibrato_shift >>= 4; + + *delta *= (float)pow(DUMB_PITCH_BASE, sample_vibrato_shift); + } + + if (playing->env_instrument && + (playing->env_instrument->pitch_envelope.flags & IT_ENVELOPE_ON)) + { + int p = envelope_get_y(&playing->env_instrument->pitch_envelope, &playing->pitch_envelope); + if (playing->env_instrument->pitch_envelope.flags & IT_ENVELOPE_PITCH_IS_FILTER) + *cutoff = (*cutoff * (p+(32<> (6 + IT_ENVELOPE_SHIFT); + else + *delta *= (float)pow(DUMB_PITCH_BASE, p >> (IT_ENVELOPE_SHIFT - 7)); + } +} + + + +static void render(DUMB_IT_SIGRENDERER *sigrenderer, float volume, float delta, long pos, long size, sample_t **samples) +{ + int i; + + int n_to_mix = 0; + IT_TO_MIX to_mix[DUMB_IT_TOTAL_CHANNELS]; + int left_to_mix = dumb_it_max_to_mix; + + sample_t **samples_to_filter = NULL; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + if (sigrenderer->channel[i].playing && !(sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD)) { + to_mix[n_to_mix].playing = sigrenderer->channel[i].playing; + to_mix[n_to_mix].volume = volume == 0 ? 0 : calculate_volume(sigrenderer, sigrenderer->channel[i].playing, volume); + n_to_mix++; + } + } + + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) { + if (sigrenderer->playing[i]) { /* Won't be dead; it would have been freed. */ + to_mix[n_to_mix].playing = sigrenderer->playing[i]; + to_mix[n_to_mix].volume = volume == 0 ? 0 : calculate_volume(sigrenderer, sigrenderer->playing[i], volume); + n_to_mix++; + } + } + + if (volume != 0) + qsort(to_mix, n_to_mix, sizeof(IT_TO_MIX), &it_to_mix_compare); + + for (i = 0; i < n_to_mix; i++) { + IT_PLAYING *playing = to_mix[i].playing; + float note_delta = delta * playing->delta; + int cutoff = playing->filter_cutoff << IT_ENVELOPE_SHIFT; + + apply_pitch_modifications(sigrenderer->sigdata, playing, ¬e_delta, &cutoff); + + if (cutoff != 127 << IT_ENVELOPE_SHIFT || playing->filter_resonance != 0) { + playing->true_filter_cutoff = cutoff; + playing->true_filter_resonance = playing->filter_resonance; + } + + if (to_mix[i].volume && (playing->true_filter_cutoff != 127 << IT_ENVELOPE_SHIFT || playing->true_filter_resonance != 0)) { + if (!samples_to_filter) { + samples_to_filter = create_sample_buffer(sigrenderer->n_channels, size + 1); + if (!samples_to_filter) { + render_playing(sigrenderer, playing, 0, note_delta, pos, size, NULL, 0, &left_to_mix); + continue; + } + } + { + long size_rendered; + DUMB_CLICK_REMOVER **cr = sigrenderer->click_remover; + dumb_silence(samples_to_filter[0], sigrenderer->n_channels * (size + 1)); + sigrenderer->click_remover = NULL; + size_rendered = render_playing(sigrenderer, playing, to_mix[i].volume, note_delta, 0, size, samples_to_filter, 1, &left_to_mix); + sigrenderer->click_remover = cr; + it_filter(cr ? cr[0] : NULL, &playing->filter_state[0], samples[0], pos, samples_to_filter[0], size_rendered, + 65536.0f/delta, playing->true_filter_cutoff, playing->true_filter_resonance); + if (sigrenderer->n_channels == 2) + it_filter(cr ? cr[1] : NULL, &playing->filter_state[1], samples[1], pos, samples_to_filter[1], size_rendered, + 65536.0f/delta, playing->true_filter_cutoff, playing->true_filter_resonance); + // warning: filtering is not prevented by low left_to_mix! + } + } else { + it_reset_filter_state(&playing->filter_state[0]); + it_reset_filter_state(&playing->filter_state[1]); + render_playing(sigrenderer, playing, to_mix[i].volume, note_delta, pos, size, samples, 0, &left_to_mix); + } + } + + destroy_sample_buffer(samples_to_filter); + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + if (sigrenderer->channel[i].playing) { + if ((sigrenderer->channel[i].playing->flags & (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) == (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) { + free(sigrenderer->channel[i].playing); + sigrenderer->channel[i].playing = NULL; + } + } + } + + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) { + if (sigrenderer->playing[i]) { + if (sigrenderer->playing[i]->flags & IT_PLAYING_DEAD) { + free(sigrenderer->playing[i]); + sigrenderer->playing[i] = NULL; + } + } + } +} + + + +static DUMB_IT_SIGRENDERER *init_sigrenderer(DUMB_IT_SIGDATA *sigdata, int n_channels, int startorder, IT_CALLBACKS *callbacks, DUMB_CLICK_REMOVER **cr) +{ + DUMB_IT_SIGRENDERER *sigrenderer; + int i; + + if (startorder > sigdata->n_orders) { + free(callbacks); + dumb_destroy_click_remover_array(n_channels, cr); + return NULL; + } + + sigrenderer = (DUMB_IT_SIGRENDERER *)malloc(sizeof(*sigrenderer)); + if (!sigrenderer) { + free(callbacks); + dumb_destroy_click_remover_array(n_channels, cr); + return NULL; + } + + sigrenderer->callbacks = callbacks; + sigrenderer->click_remover = cr; + + sigrenderer->sigdata = sigdata; + sigrenderer->n_channels = n_channels; + sigrenderer->globalvolume = sigdata->global_volume; + sigrenderer->tempo = sigdata->tempo; + + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) { + IT_CHANNEL *channel = &sigrenderer->channel[i]; +#if IT_CHANNEL_MUTED != 1 +#error this is wrong +#endif + channel->flags = sigdata->channel_pan[i] >> 7; + channel->volume = (sigdata->flags & IT_WAS_AN_XM) ? 0 : 64; + channel->pan = sigdata->channel_pan[i] & 0x7F; + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + channel->channelvolume = sigdata->channel_volume[i]; + channel->instrument = 0; + channel->note = 0; + channel->SFmacro = 0; + channel->filter_cutoff = 127; + channel->filter_resonance = 0; + channel->xm_retrig = 0; + channel->retrig_tick = 0; + channel->tremor_time = 0; + channel->midi_state = 0; + channel->lastvolslide = 0; + channel->lastDKL = 0; + channel->lastEF = 0; + channel->lastG = 0; + channel->lastHspeed = 0; + channel->lastHdepth = 0; + channel->lastRspeed = 0; + channel->lastRdepth = 0; + channel->lastI = 0; + channel->lastJ = 0; + channel->lastN = 0; + channel->lastO = 0; + channel->high_offset = 0; + channel->lastQ = 0; + channel->lastS = 0; + channel->pat_loop_row = 0; + channel->pat_loop_count = 0; + channel->lastW = 0; + channel->xm_lastE1 = 0; + channel->xm_lastE2 = 0; + channel->xm_lastEA = 0; + channel->xm_lastEB = 0; + channel->xm_lastX1 = 0; + channel->xm_lastX2 = 0; + channel->playing = NULL; + } + + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) + sigrenderer->playing[i] = NULL; + + sigrenderer->speed = sigdata->speed; + + sigrenderer->processrow = 0; + sigrenderer->breakrow = 0; + sigrenderer->pat_loop_row = -1; + sigrenderer->rowcount = 1; + + reset_tick_counts(sigrenderer); + + sigrenderer->tick = sigrenderer->speed; + + { + IT_PATTERN *pattern; + int n; + + sigrenderer->processorder = startorder; + for (;;) { + n = sigdata->order[sigrenderer->processorder]; + + if (n < sigdata->n_patterns) + break; + +#ifdef INVALID_ORDERS_END_SONG + if (n != IT_ORDER_SKIP) +#else + if (n == IT_ORDER_END) +#endif + { + _dumb_it_end_sigrenderer(sigrenderer); + return NULL; + } + + sigrenderer->processorder++; + if (sigrenderer->processorder >= sigdata->n_orders) + sigrenderer->processorder = 0; + if (sigrenderer->processorder == startorder) { + _dumb_it_end_sigrenderer(sigrenderer); + return NULL; + } + } + + pattern = &sigdata->pattern[n]; + + sigrenderer->n_rows = pattern->n_rows; + +/** WARNING - everything pertaining to a new pattern initialised? */ + + sigrenderer->entry = sigrenderer->entry_start = pattern->entry; + sigrenderer->entry_end = sigrenderer->entry + pattern->n_entries; + + sigrenderer->order = sigrenderer->processorder; + sigrenderer->row = 0; + } + + reset_effects(sigrenderer); + + { + IT_ENTRY *entry = sigrenderer->entry; + + while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry)) + update_pattern_variables(sigrenderer, entry++); + } + + { + IT_ENTRY *entry = sigrenderer->entry; + + while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry)) { + if (process_entry(sigrenderer, entry++)) { + /* Oops, that song ended quickly! */ + _dumb_it_end_sigrenderer(sigrenderer); + return NULL; + } + } + } + + if (!(sigdata->flags & IT_OLD_EFFECTS)) + update_smooth_effects(sigrenderer); + + process_all_playing(sigrenderer); + + sigrenderer->time_left = TICK_TIME_DIVIDEND / sigrenderer->tempo; + sigrenderer->sub_time_left = 0; + + return sigrenderer; +} + + + +void dumb_it_set_loop_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data) +{ + if (sigrenderer) { + sigrenderer->callbacks->loop = callback; + sigrenderer->callbacks->loop_data = data; + } +} + + + +void dumb_it_set_xm_speed_zero_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data) +{ + if (sigrenderer) { + sigrenderer->callbacks->xm_speed_zero = callback; + sigrenderer->callbacks->xm_speed_zero_data = data; + } +} + + + +void dumb_it_set_midi_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data, int channel, unsigned char byte), void *data) +{ + if (sigrenderer) { + sigrenderer->callbacks->midi = callback; + sigrenderer->callbacks->midi_data = data; + } +} + + + +static IT_CALLBACKS *create_callbacks(void) +{ + IT_CALLBACKS *callbacks = (IT_CALLBACKS *)malloc(sizeof(*callbacks)); + if (!callbacks) return NULL; + callbacks->loop = NULL; + callbacks->xm_speed_zero = NULL; + callbacks->midi = NULL; + return callbacks; +} + + + +static DUMB_IT_SIGRENDERER *dumb_it_init_sigrenderer(DUMB_IT_SIGDATA *sigdata, int n_channels, int startorder) +{ + IT_CALLBACKS *callbacks; + + if (!sigdata) return NULL; + + callbacks = create_callbacks(); + if (!callbacks) return NULL; + + return init_sigrenderer(sigdata, n_channels, startorder, callbacks, + dumb_create_click_remover_array(n_channels)); +} + + + +DUH_SIGRENDERER *dumb_it_start_at_order(DUH *duh, int n_channels, int startorder) +{ + DUMB_IT_SIGDATA *itsd = duh_get_it_sigdata(duh); + DUMB_IT_SIGRENDERER *itsr = dumb_it_init_sigrenderer(itsd, n_channels, startorder); + return duh_encapsulate_it_sigrenderer(itsr, n_channels, 0); +} + + + +static sigrenderer_t *it_start_sigrenderer(DUH *duh, sigdata_t *vsigdata, int n_channels, long pos) +{ + DUMB_IT_SIGDATA *sigdata = (DUMB_IT_SIGDATA *)vsigdata; + DUMB_IT_SIGRENDERER *sigrenderer; + + (void)duh; + + { + IT_CALLBACKS *callbacks = create_callbacks(); + if (!callbacks) return NULL; + + if (sigdata->checkpoint) { + IT_CHECKPOINT *checkpoint = sigdata->checkpoint; + while (checkpoint->next && checkpoint->next->time < pos) + checkpoint = checkpoint->next; + sigrenderer = dup_sigrenderer(checkpoint->sigrenderer, n_channels, callbacks); + if (!sigrenderer) return NULL; + sigrenderer->click_remover = dumb_create_click_remover_array(n_channels); + pos -= checkpoint->time; + } else { + sigrenderer = init_sigrenderer(sigdata, n_channels, 0, callbacks, + dumb_create_click_remover_array(n_channels)); + if (!sigrenderer) return NULL; + } + } + + for (;;) { + if (sigrenderer->time_left >= pos) + break; + + render(sigrenderer, 0, 1.0f, 0, sigrenderer->time_left, NULL); + + pos -= sigrenderer->time_left; + sigrenderer->time_left = 0; + + if (process_tick(sigrenderer)) { + _dumb_it_end_sigrenderer(sigrenderer); + return NULL; + } + } + + render(sigrenderer, 0, 1.0f, 0, pos, NULL); + sigrenderer->time_left -= pos; + + /** WARNING - everything initialised? */ + + return sigrenderer; +} + + + +static long it_sigrenderer_get_samples( + sigrenderer_t *vsigrenderer, + float volume, float delta, + long size, sample_t **samples +) +{ + DUMB_IT_SIGRENDERER *sigrenderer = (DUMB_IT_SIGRENDERER *)vsigrenderer; + long pos; + int dt; + long todo; + LONG_LONG t; + + if (sigrenderer->order < 0) return 0; + + pos = 0; + dt = (int)(delta * 65536.0f + 0.5f); + + /* When samples is finally used in render_playing(), it won't be used if + * volume is 0. + */ + if (!samples) volume = 0; + + for (;;) { + todo = (long)((((LONG_LONG)sigrenderer->time_left << 16) | sigrenderer->sub_time_left) / dt); + + if (todo >= size) + break; + + render(sigrenderer, volume, delta, pos, todo, samples); + + pos += todo; + size -= todo; + + t = sigrenderer->sub_time_left - (LONG_LONG)todo * dt; + sigrenderer->sub_time_left = (long)t & 65535; + sigrenderer->time_left += (long)(t >> 16); + + if (process_tick(sigrenderer)) { + sigrenderer->order = -1; + sigrenderer->row = -1; + return pos; + } + } + + render(sigrenderer, volume, delta, pos, size, samples); + + pos += size; + + t = sigrenderer->sub_time_left - (LONG_LONG)size * dt; + sigrenderer->sub_time_left = (long)t & 65535; + sigrenderer->time_left += (long)(t >> 16); + + dumb_remove_clicks_array(sigrenderer->n_channels, sigrenderer->click_remover, samples, pos, 512.0f / delta); + + return pos; +} + + + +static void it_sigrenderer_get_current_sample(sigrenderer_t *vsigrenderer, float volume, sample_t *samples) +{ + DUMB_IT_SIGRENDERER *sigrenderer = (DUMB_IT_SIGRENDERER *)vsigrenderer; + (void)volume; // for consideration: in any of these such functions, is 'volume' going to be required? + dumb_click_remover_get_offset_array(sigrenderer->n_channels, sigrenderer->click_remover, samples); +} + + + +void _dumb_it_end_sigrenderer(sigrenderer_t *vsigrenderer) +{ + DUMB_IT_SIGRENDERER *sigrenderer = (DUMB_IT_SIGRENDERER *)vsigrenderer; + + int i; + + if (sigrenderer) { + for (i = 0; i < DUMB_IT_N_CHANNELS; i++) + if (sigrenderer->channel[i].playing) + free(sigrenderer->channel[i].playing); + + for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) + if (sigrenderer->playing[i]) + free(sigrenderer->playing[i]); + + dumb_destroy_click_remover_array(sigrenderer->n_channels, sigrenderer->click_remover); + + if (sigrenderer->callbacks) + free(sigrenderer->callbacks); + + free(vsigrenderer); + } +} + + + +DUH_SIGTYPE_DESC _dumb_sigtype_it = { + SIGTYPE_IT, + NULL, + &it_start_sigrenderer, + NULL, + &it_sigrenderer_get_samples, + &it_sigrenderer_get_current_sample, + &_dumb_it_end_sigrenderer, + &_dumb_it_unload_sigdata +}; + + + +DUH_SIGRENDERER *duh_encapsulate_it_sigrenderer(DUMB_IT_SIGRENDERER *it_sigrenderer, int n_channels, long pos) +{ + return duh_encapsulate_raw_sigrenderer(it_sigrenderer, &_dumb_sigtype_it, n_channels, pos); +} + + + +DUMB_IT_SIGRENDERER *duh_get_it_sigrenderer(DUH_SIGRENDERER *sigrenderer) +{ + return (DUMB_IT_SIGRENDERER *)duh_get_raw_sigrenderer(sigrenderer, SIGTYPE_IT); +} + + + +/* Values of 64 or more will access NNA channels here. */ +void dumb_it_sr_get_channel_state(DUMB_IT_SIGRENDERER *sr, int channel, DUMB_IT_CHANNEL_STATE *state) +{ + IT_PLAYING *playing; + int t; /* temporary var for holding accurate pan and filter cutoff */ + float delta; + ASSERT(channel < DUMB_IT_TOTAL_CHANNELS); + if (!sr) { state->sample = 0; return; } + if (channel >= DUMB_IT_N_CHANNELS) { + playing = sr->playing[channel - DUMB_IT_N_CHANNELS]; + if (!playing) { state->sample = 0; return; } + } else { + playing = sr->channel[channel].playing; + if (!playing) { state->sample = 0; return; } + } + + if (playing->flags & IT_PLAYING_DEAD) { state->sample = 0; return; } + + state->channel = playing->channel - sr->channel; + state->sample = playing->sampnum; + state->volume = calculate_volume(sr, playing, 1.0f); + + t = apply_pan_envelope(playing); + state->pan = (unsigned char)((t + 128) >> IT_ENVELOPE_SHIFT); + state->subpan = (signed char)t; + + delta = playing->delta * 65536.0f; + t = playing->filter_cutoff << IT_ENVELOPE_SHIFT; + apply_pitch_modifications(sr->sigdata, playing, &delta, &t); + state->freq = (int)delta; + if (t == 127 << IT_ENVELOPE_SHIFT && playing->filter_resonance == 0) { + state->filter_resonance = playing->true_filter_resonance; + t = playing->true_filter_cutoff; + } else + state->filter_resonance = playing->filter_resonance; + state->filter_cutoff = (unsigned char)(t >> 8); + state->filter_subcutoff = (unsigned char)t; +} + + + +int dumb_it_callback_terminate(void *data) +{ + (void)data; + return 1; +} + + + +int dumb_it_callback_midi_block(void *data, int channel, unsigned char byte) +{ + (void)data; + (void)channel; + (void)byte; + return 1; +} + + + +#define IT_CHECKPOINT_INTERVAL (30 * 65536) /* Half a minute */ + + + +/* Returns the length of the module, up until it first loops. */ +long _dumb_it_build_checkpoints(DUMB_IT_SIGDATA *sigdata) +{ + IT_CHECKPOINT *checkpoint = (IT_CHECKPOINT *)malloc(sizeof(*checkpoint)); + if (!checkpoint) return 0; + checkpoint->time = 0; + checkpoint->sigrenderer = dumb_it_init_sigrenderer(sigdata, 0, 0); + if (!checkpoint->sigrenderer) { + free(checkpoint); + return 0; + } + checkpoint->sigrenderer->callbacks->loop = &dumb_it_callback_terminate; + checkpoint->sigrenderer->callbacks->xm_speed_zero = &dumb_it_callback_terminate; + sigdata->checkpoint = checkpoint; + + for (;;) { + long l; + DUMB_IT_SIGRENDERER *sigrenderer = dup_sigrenderer(checkpoint->sigrenderer, 0, checkpoint->sigrenderer->callbacks); + checkpoint->sigrenderer->callbacks = NULL; + if (!sigrenderer) { + checkpoint->next = NULL; + return checkpoint->time; + } + + l = it_sigrenderer_get_samples(sigrenderer, 0, 1.0f, IT_CHECKPOINT_INTERVAL, NULL); + if (l < IT_CHECKPOINT_INTERVAL) { + _dumb_it_end_sigrenderer(sigrenderer); + checkpoint->next = NULL; + return checkpoint->time + l; + } + + checkpoint->next = (IT_CHECKPOINT *)malloc(sizeof(*checkpoint->next)); + if (!checkpoint->next) { + _dumb_it_end_sigrenderer(sigrenderer); + return checkpoint->time + IT_CHECKPOINT_INTERVAL; + } + + checkpoint->next->time = checkpoint->time + IT_CHECKPOINT_INTERVAL; + checkpoint = checkpoint->next; + checkpoint->sigrenderer = sigrenderer; + } +} + +} // namespace AGS3 diff --git a/engines/ags/lib/dumb-0.9.2/it/itunload.cpp b/engines/ags/lib/dumb-0.9.2/it/itunload.cpp new file mode 100644 index 000000000000..d94a9ecac96c --- /dev/null +++ b/engines/ags/lib/dumb-0.9.2/it/itunload.cpp @@ -0,0 +1,92 @@ +/* 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. + * + */ + +/* _______ ____ __ ___ ___ + * \ _ \ \ / \ / \ \ / / ' ' ' + * | | \ \ | | || | \/ | . . + * | | | | | | || ||\ /| | + * | | | | | | || || \/ | | ' ' ' + * | | | | | | || || | | . . + * | |_/ / \ \__// || | | + * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque + * / \ + * / . \ + * itunload.c - Code to free an Impulse Tracker / / \ \ + * module from memory. | < / \_ + * | \/ /\ / + * By entheh. \_ / > / + * | \ / / + * | ' / + * \__/ + */ + +#include "ags/lib/dumb-0.9.2/dumb.h" +#include "ags/lib/dumb-0.9.2/it/it.h" + +namespace AGS3 { + +void _dumb_it_unload_sigdata(sigdata_t *vsigdata) { + if (vsigdata) { + DUMB_IT_SIGDATA *sigdata = (DUMB_IT_SIGDATA *)vsigdata; + int n; + + if (sigdata->order) + free(sigdata->order); + + if (sigdata->instrument) + free(sigdata->instrument); + + if (sigdata->sample) { + for (n = 0; n < sigdata->n_samples; n++) { + if (sigdata->sample[n].left) + free(sigdata->sample[n].left); + if (sigdata->sample[n].right) + free(sigdata->sample[n].right); + } + free(sigdata->sample); + } + + if (sigdata->pattern) { + for (n = 0; n < sigdata->n_patterns; n++) + if (sigdata->pattern[n].entry) + free(sigdata->pattern[n].entry); + free(sigdata->pattern); + } + + if (sigdata->midi) + free(sigdata->midi); + + { + IT_CHECKPOINT *checkpoint = sigdata->checkpoint; + while (checkpoint) { + IT_CHECKPOINT *next = checkpoint->next; + _dumb_it_end_sigrenderer(checkpoint->sigrenderer); + free(checkpoint); + checkpoint = next; + } + } + + free(vsigdata); + } +} + +} // namespace AGS3 diff --git a/engines/ags/lib/std/queue.h b/engines/ags/lib/std/queue.h index b8846fd8c473..3026295ee5d8 100644 --- a/engines/ags/lib/std/queue.h +++ b/engines/ags/lib/std/queue.h @@ -39,7 +39,7 @@ class priority_queue { Container _container; Comparitor _comparitor; public: - priority_queue(); + priority_queue() {} bool empty() const { return _container.empty(); } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 8c278fbe876c..af96975957c9 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -8,6 +8,7 @@ MODULE_OBJS = \ lib/aastr-0.1.1/aautil.o \ lib/alfont/alfont.o \ lib/allegro.o \ + lib/allegro/colblend.o \ lib/allegro/color.o \ lib/allegro/config.o \ lib/allegro/draw.o \ @@ -17,6 +18,7 @@ MODULE_OBJS = \ lib/allegro/gfx.o \ lib/allegro/graphics.o \ lib/allegro/keyboard.o \ + lib/allegro/math.o \ lib/allegro/mouse.o \ lib/allegro/system.o \ lib/allegro/unicode.o \ @@ -27,7 +29,12 @@ MODULE_OBJS = \ lib/audio/ogg.o \ lib/audio/sound.o \ lib/audio/wav.o \ + lib/dumb-0.9.2/dumb.o \ lib/dumb-0.9.2/dumbfile.o \ + lib/dumb-0.9.2/helpers/clickrem.o \ + lib/dumb-0.9.2/it/itmisc.o \ + lib/dumb-0.9.2/it/itrender.o \ + lib/dumb-0.9.2/it/itunload.o \ lib/hq2x/hq2x3x.o \ lib/opengl/opengl.o \ lib/std/std.o \ @@ -246,6 +253,7 @@ MODULE_OBJS = \ engine/gfx/gfxdriverbase.o \ engine/gfx/gfxdriverfactory.o \ engine/gfx/gfxfilter_aad3d.o \ + engine/gfx/gfxfilter_aaogl.o \ engine/gfx/gfxfilter_allegro.o \ engine/gfx/gfxfilter_d3d.o \ engine/gfx/gfxfilter_hqx.o \ From 03dc7ded6d879f7f54a6dff143022af58114bf4c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 18:55:06 -0800 Subject: [PATCH 057/215] AGS: Add overall main code --- engines/ags/ags.cpp | 347 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index c5dc3afa71eb..ad075c586542 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -28,6 +28,296 @@ #include "common/events.h" #include "common/file.h" +#include "ags/shared/core/platform.h" +#define AGS_PLATFORM_DEFINES_PSP_VARS (AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID) + +#include "ags/lib/std/set.h" +#include "ags/shared/ac/common.h" +#include "ags/engine/ac/gamesetup.h" +#include "ags/engine/ac/gamestate.h" +#include "ags/shared/core/def_version.h" +#include "ags/engine/debugging/debugger.h" +#include "ags/engine/debugging/debug_log.h" +#include "ags/shared/debugging/out.h" +#include "ags/engine/main/config.h" +#include "ags/engine/main/engine.h" +#include "ags/engine/main/mainheader.h" +#include "ags/engine/main/main.h" +#include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/ac/route_finder.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/util/directory.h" +#include "ags/shared/util/path.h" + + +namespace AGS3 { + +extern char return_to_roomedit[30]; +extern char return_to_room[150]; + +using namespace Shared; +using namespace Engine; + +String appDirectory; // Needed for library loading +String cmdGameDataPath; + +char **global_argv = nullptr; +int global_argc = 0; + +extern GameSetup usetup; +extern GameState play; +extern int our_eip; +extern AGSPlatformDriver *platform; +extern int convert_16bit_bgr; +extern int editor_debugging_enabled; +extern int editor_debugging_initialized; +extern char editor_debugger_instance_token[100]; + + +// Startup flags, set from parameters to engine +int force_window = 0; +int override_start_room = 0; +bool justDisplayHelp = false; +bool justDisplayVersion = false; +bool justRunSetup = false; +bool justRegisterGame = false; +bool justUnRegisterGame = false; +bool justTellInfo = false; +std::set tellInfoKeys; +const char *loadSaveGameOnStartup = nullptr; + +#if ! AGS_PLATFORM_DEFINES_PSP_VARS +int psp_video_framedrop = 1; +int psp_audio_enabled = 1; +int psp_midi_enabled = 1; +int psp_ignore_acsetup_cfg_file = 0; +int psp_clear_cache_on_room_change = 0; + +int psp_midi_preload_patches = 0; +int psp_audio_cachesize = 10; +char psp_game_file_name[] = ""; +char psp_translation[] = "default"; + +int psp_gfx_renderer = 0; +int psp_gfx_scaling = 1; +int psp_gfx_smoothing = 0; +int psp_gfx_super_sampling = 1; +int psp_gfx_smooth_sprites = 0; +#endif + +// this needs to be updated if the "play" struct changes +#define SVG_VERSION_BWCOMPAT_MAJOR 3 +#define SVG_VERSION_BWCOMPAT_MINOR 2 +#define SVG_VERSION_BWCOMPAT_RELEASE 0 +#define SVG_VERSION_BWCOMPAT_REVISION 1103 +// CHECKME: we may lower this down, if we find that earlier versions may still +// load new savedgames +#define SVG_VERSION_FWCOMPAT_MAJOR 3 +#define SVG_VERSION_FWCOMPAT_MINOR 2 +#define SVG_VERSION_FWCOMPAT_RELEASE 1 +#define SVG_VERSION_FWCOMPAT_REVISION 1111 + +// Current engine version +Version EngineVersion; +// Lowest savedgame version, accepted by this engine +Version SavedgameLowestBackwardCompatVersion; +// Lowest engine version, which would accept current savedgames +Version SavedgameLowestForwardCompatVersion; + + +void main_pre_init() { + our_eip = -999; + Shared::AssetManager::SetSearchPriority(Shared::kAssetPriorityDir); + play.takeover_data = 0; +} + +void main_create_platform_driver() { + platform = AGSPlatformDriver::GetDriver(); +} + +void main_init(int argc, char *argv[]) { + EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); + + SavedgameLowestBackwardCompatVersion = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); + SavedgameLowestForwardCompatVersion = Version(SVG_VERSION_FWCOMPAT_MAJOR, SVG_VERSION_FWCOMPAT_MINOR, SVG_VERSION_FWCOMPAT_RELEASE, SVG_VERSION_FWCOMPAT_REVISION); + + Shared::AssetManager::CreateInstance(); + main_pre_init(); + main_create_platform_driver(); + + global_argv = argv; + global_argc = argc; +} + +String get_engine_string() { + return String::FromFormat("Adventure Game Studio v%s Interpreter\n" + "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" + "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); +} + +void main_print_help() { + // No implementation +} + +static int main_process_cmdline(ConfigTree &cfg, int argc, char *argv[]) { + int datafile_argv = 0; + for (int ee = 1; ee < argc; ++ee) { + const char *arg = argv[ee]; + // + // Startup options + // + if (scumm_stricmp(arg, "--help") == 0 || scumm_stricmp(arg, "/?") == 0 || scumm_stricmp(arg, "-?") == 0) { + justDisplayHelp = true; + return 0; + } + if (scumm_stricmp(arg, "-v") == 0 || scumm_stricmp(arg, "--version") == 0) { + justDisplayVersion = true; + return 0; + } else if (scumm_stricmp(arg, "-updatereg") == 0) + debug_flags |= DBG_REGONLY; +#if AGS_PLATFORM_DEBUG + else if ((scumm_stricmp(arg, "--startr") == 0) && (ee < argc - 1)) { + override_start_room = atoi(argv[ee + 1]); + ee++; + } +#endif + else if ((scumm_stricmp(arg, "--testre") == 0) && (ee < argc - 2)) { + strcpy(return_to_roomedit, argv[ee + 1]); + strcpy(return_to_room, argv[ee + 2]); + ee += 2; + } else if (scumm_stricmp(arg, "-noexceptionhandler") == 0) usetup.disable_exception_handling = true; + else if (scumm_stricmp(arg, "--setup") == 0) { + justRunSetup = true; + } else if (scumm_stricmp(arg, "-registergame") == 0) { + justRegisterGame = true; + } else if (scumm_stricmp(arg, "-unregistergame") == 0) { + justUnRegisterGame = true; + } else if ((scumm_stricmp(arg, "-loadsavedgame") == 0) && (argc > ee + 1)) { + loadSaveGameOnStartup = argv[ee + 1]; + ee++; + } else if ((scumm_stricmp(arg, "--enabledebugger") == 0) && (argc > ee + 1)) { + strcpy(editor_debugger_instance_token, argv[ee + 1]); + editor_debugging_enabled = 1; + force_window = 1; + ee++; + } else if (scumm_stricmp(arg, "--runfromide") == 0 && (argc > ee + 3)) { + usetup.install_dir = argv[ee + 1]; + usetup.install_audio_dir = argv[ee + 2]; + usetup.install_voice_dir = argv[ee + 3]; + ee += 3; + } else if (scumm_stricmp(arg, "--takeover") == 0) { + if (argc < ee + 2) + break; + play.takeover_data = atoi(argv[ee + 1]); + strncpy(play.takeover_from, argv[ee + 2], 49); + play.takeover_from[49] = 0; + ee += 2; + } else if (scumm_strnicmp(arg, "--tell", 6) == 0) { + if (arg[6] == 0) + tellInfoKeys.insert(String("all")); + else if (arg[6] == '-' && arg[7] != 0) + tellInfoKeys.insert(String(arg + 7)); + } + // + // Config overrides + // + else if (scumm_stricmp(arg, "-windowed") == 0 || scumm_stricmp(arg, "--windowed") == 0) + force_window = 1; + else if (scumm_stricmp(arg, "-fullscreen") == 0 || scumm_stricmp(arg, "--fullscreen") == 0) + force_window = 2; + else if ((scumm_stricmp(arg, "-gfxdriver") == 0 || scumm_stricmp(arg, "--gfxdriver") == 0) && (argc > ee + 1)) { + INIwritestring(cfg, "graphics", "driver", argv[++ee]); + } else if ((scumm_stricmp(arg, "-gfxfilter") == 0 || scumm_stricmp(arg, "--gfxfilter") == 0) && (argc > ee + 1)) { + // NOTE: we make an assumption here that if user provides scaling factor, + // this factor means to be applied to windowed mode only. + INIwritestring(cfg, "graphics", "filter", argv[++ee]); + if (argc > ee + 1 && argv[ee + 1][0] != '-') + INIwritestring(cfg, "graphics", "game_scale_win", argv[++ee]); + else + INIwritestring(cfg, "graphics", "game_scale_win", "max_round"); + } else if (scumm_stricmp(arg, "--fps") == 0) display_fps = kFPS_Forced; + else if (scumm_stricmp(arg, "--test") == 0) debug_flags |= DBG_DEBUGMODE; + else if (scumm_stricmp(arg, "-noiface") == 0) debug_flags |= DBG_NOIFACE; + else if (scumm_stricmp(arg, "-nosprdisp") == 0) debug_flags |= DBG_NODRAWSPRITES; + else if (scumm_stricmp(arg, "-nospr") == 0) debug_flags |= DBG_NOOBJECTS; + else if (scumm_stricmp(arg, "-noupdate") == 0) debug_flags |= DBG_NOUPDATE; + else if (scumm_stricmp(arg, "-nosound") == 0) debug_flags |= DBG_NOSFX; + else if (scumm_stricmp(arg, "-nomusic") == 0) debug_flags |= DBG_NOMUSIC; + else if (scumm_stricmp(arg, "-noscript") == 0) debug_flags |= DBG_NOSCRIPT; + else if (scumm_stricmp(arg, "-novideo") == 0) debug_flags |= DBG_NOVIDEO; + else if (scumm_stricmp(arg, "-dbgscript") == 0) debug_flags |= DBG_DBGSCRIPT; + else if (scumm_stricmp(arg, "--log") == 0) INIwriteint(cfg, "misc", "log", 1); + else if (scumm_stricmp(arg, "--no-log") == 0) INIwriteint(cfg, "misc", "log", 0); + // + // Special case: data file location + // + else if (arg[0] != '-') datafile_argv = ee; + } + + if (datafile_argv > 0) { + cmdGameDataPath = GetPathFromCmdArg(datafile_argv); + } else { + // assign standard path for mobile/consoles (defined in their own platform implementation) + cmdGameDataPath = psp_game_file_name; + } + + if (!tellInfoKeys.empty()) + justTellInfo = true; + + return 0; +} + +void main_set_gamedir(int argc, char *argv[]) { + appDirectory = Path::GetDirectoryPath(GetPathFromCmdArg(0)); + + if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) { + // When launched by double-clicking a save game file, the curdir will + // be the save game folder unless we correct it + Directory::SetCurrentDirectory(appDirectory); + } else { + // It looks like Allegro library does not like ANSI (ACP) paths. + // When *not* working in U_UNICODE filepath mode, whenever it gets + // current directory for its own operations, it "fixes" it by + // substituting non-ASCII symbols with '^'. + // Here we explicitly set current directory to ASCII path. + String cur_dir = Directory::GetCurrentDirectory(); + String path = Path::GetPathInASCII(cur_dir); + if (!path.IsEmpty()) + Directory::SetCurrentDirectory(Path::MakeAbsolutePath(path)); + else + Debug::Printf(kDbgMsg_Error, "Unable to determine current directory: GetPathInASCII failed.\nArg: %s", cur_dir.GetCStr()); + } +} + +String GetPathFromCmdArg(int arg_index) { + if (arg_index < 0 || arg_index >= global_argc) + return ""; + String path = Path::GetCmdLinePathInASCII(global_argv[arg_index], arg_index); + if (!path.IsEmpty()) + return Path::MakeAbsolutePath(path); + Debug::Printf(kDbgMsg_Error, "Unable to determine path: GetCmdLinePathInASCII failed.\nCommand line argument %i: %s", arg_index, global_argv[arg_index]); + return global_argv[arg_index]; +} + +const char *get_allegro_error() { + return "ERROR"; // allegro_error; +} + +#define ALLEGRO_ERROR_SIZE 256 +char allegro_error[ALLEGRO_ERROR_SIZE]; + +const char *set_allegro_error(const char *format, ...) { + va_list argptr; + va_start(argptr, format); + Common::String msg = Common::String::format(format, argptr); + strncpy(allegro_error, msg.c_str(), ALLEGRO_ERROR_SIZE); + + va_end(argptr); + return allegro_error; +} + +} // namespace AGS3 + namespace AGS { AGSEngine *g_vm; @@ -49,6 +339,63 @@ uint32 AGSEngine::getFeatures() const { } Common::Error AGSEngine::run() { + char exeName[16], gameName[16]; + strcpy(exeName, "scummvm.exe"); + strcpy(gameName, "bc.exe"); + int argc = 3; + char *argv[] = { exeName, gameName }; + +#ifdef AGS_RUN_TESTS + Test_DoAllTests(); +#endif + AGS3::main_init(argc, argv); + +#if AGS_PLATFORM_OS_WINDOWS + setup_malloc_handling(); +#endif + AGS3::debug_flags = 0; + + AGS3::ConfigTree startup_opts; + int res = AGS3::main_process_cmdline(startup_opts, argc, argv); + if (res != 0) + return Common::kUnknownError; + + if (AGS3::justDisplayVersion) { + AGS3::platform->WriteStdOut(AGS3::get_engine_string()); + return Common::kNoError; + } + + if (AGS3::justDisplayHelp) { + AGS3::main_print_help(); + return Common::kNoError; + } + + if (!AGS3::justTellInfo) + AGS3::platform->SetGUIMode(true); + AGS3::init_debug(startup_opts, AGS3::justTellInfo); + AGS3::Debug::Printf("%s", AGS3::get_engine_string().GetNullableCStr()); + + AGS3::main_set_gamedir(argc, argv); + + // Update shell associations and exit + if (AGS3::debug_flags & DBG_REGONLY) + return Common::kNoError; + +#ifdef USE_CUSTOM_EXCEPTION_HANDLER + if (usetup.disable_exception_handling) +#endif + { + int result = AGS3::initialize_engine(startup_opts); + // TODO: refactor engine shutdown routine (must shutdown and delete everything started and created) + AGS3::platform->PostAllegroExit(); + return result ? Common::kUnknownError : Common::kNoError; + } +#ifdef USE_CUSTOM_EXCEPTION_HANDLER + else { + return initialize_engine_with_exception_handling(initialize_engine, startup_opts); + } +#endif + return Common::kNoError; } From 71076e21977261fb3ce5d2bd62e7472c06bb3ccf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 19:11:09 -0800 Subject: [PATCH 058/215] AGS: Fix global objects crashing ScummVM on startup --- engines/ags/ags.h | 4 ++++ engines/ags/engine/ac/timer.cpp | 4 ++-- engines/ags/engine/main/game_run.cpp | 2 +- engines/ags/engine/media/audio/audio.cpp | 7 ++++-- engines/ags/engine/media/audio/audio.h | 5 +---- engines/ags/engine/media/audio/clip_mymp3.cpp | 20 ++++++++--------- engines/ags/engine/media/audio/clip_mymp3.h | 2 -- .../engine/media/audio/clip_mystaticmp3.cpp | 22 ++++++++----------- .../ags/engine/media/audio/clip_mystaticmp3.h | 2 -- engines/ags/engine/media/audio/sound.cpp | 5 +++-- engines/ags/engine/media/audio/soundcache.cpp | 10 ++++----- engines/ags/lib/std/thread.h | 4 ++-- 12 files changed, 41 insertions(+), 46 deletions(-) diff --git a/engines/ags/ags.h b/engines/ags/ags.h index 6e947b7c635a..5099d68c8345 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -35,6 +35,7 @@ #include "ags/shared/gfx/bitmap.h" #include "ags/lib/allegro/system.h" +#include "ags/engine/util/mutex_std.h" namespace AGS { @@ -55,6 +56,9 @@ class AGSEngine : public Engine { public: ::AGS3::BITMAP *_screen; ::AGS3::GFX_DRIVER *_gfxDriver; + ::AGS3::AGS::Engine::Mutex _sMutex; + ::AGS3::AGS::Engine::Mutex _soundCacheMutex; + ::AGS3::AGS::Engine::Mutex _mp3Mutex; protected: // Engine APIs virtual Common::Error run(); diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index 5eb0e31c3f52..5f26a9c5affb 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -40,8 +40,8 @@ const auto MAXIMUM_FALL_BEHIND = 3; auto tick_duration = std::chrono::microseconds(1000000LL / 40); auto framerate_maxed = false; -auto last_tick_time = AGS_Clock::now(); -auto next_frame_timestamp = AGS_Clock::now(); +uint32 last_tick_time = 0; // AGS_Clock::now(); +uint32 next_frame_timestamp = 0; // AGS_Clock::now(); } diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index a695db97ac08..1e82cc471420 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -102,7 +102,7 @@ extern int cur_mode, cur_cursor; static int ShouldStayInWaitMode(); static int numEventsAtStartOfFunction; -static auto t1 = AGS_Clock::now(); // timer for FPS // ... 't1'... how very appropriate.. :) +static uint32 t1 = 0; // AGS_Clock::now(); // timer for FPS // ... 't1'... how very appropriate.. :) #define UNTIL_ANIMEND 1 #define UNTIL_MOVEEND 2 diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 0d4ca41d3b2b..954f229278a6 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -44,6 +44,7 @@ #include "ags/engine/ac/timer.h" #include "ags/engine/main/game_run.h" #include "ags/lib/audio/sound.h" +#include "ags/ags.h" namespace AGS3 { @@ -54,7 +55,9 @@ using namespace AGS::Engine; //sound channel management; all access goes through here, which can't be done without a lock static std::array _channels(MAX_SOUND_CHANNELS + 1); -AGS::Engine::Mutex AudioChannelsLock::s_mutex; + +AudioChannelsLock::AudioChannelsLock() : MutexLock(::AGS::g_vm->_sMutex) { +} SOUNDCLIP *AudioChannelsLock::GetChannel(int index) { return _channels[index]; @@ -731,7 +734,7 @@ SOUNDCLIP *cachedQueuedMusic = nullptr; // Music update is scheduled when the voice speech stops; // we do a small delay before reverting any volume adjustments static bool music_update_scheduled = false; -static auto music_update_at = AGS_Clock::now(); +static uint32 music_update_at = 0; // AGS_Clock::now(); void cancel_scheduled_music_update() { music_update_scheduled = false; diff --git a/engines/ags/engine/media/audio/audio.h b/engines/ags/engine/media/audio/audio.h index 192de3246e56..ec12575e5ec7 100644 --- a/engines/ags/engine/media/audio/audio.h +++ b/engines/ags/engine/media/audio/audio.h @@ -48,10 +48,7 @@ class AudioChannelsLock : public AGS::Engine::MutexLock { AudioChannelsLock &operator=(AudioChannelsLock const &); // not copy-assignable public: - static AGS::Engine::Mutex s_mutex; - AudioChannelsLock() - : MutexLock(s_mutex) { - } + AudioChannelsLock(); // Gets a clip from the channel SOUNDCLIP *GetChannel(int index); diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp index 66e9674d3d13..ce87812b46d2 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -29,8 +29,8 @@ #include "ags/shared/ac/common.h" // quit() #include "ags/engine/ac/asset_helper.h" #include "ags/engine/util/mutex_lock.h" - #include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/ags.h" namespace AGS3 { @@ -42,7 +42,7 @@ void MYMP3::poll() { // update the buffer char *tempbuf = nullptr; { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); tempbuf = (char *)almp3_get_mp3stream_buffer(stream); } @@ -56,13 +56,13 @@ void MYMP3::poll() { pack_fread(tempbuf, chunksize, in); { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); almp3_free_mp3stream_buffer(stream, free_val); } } #endif { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); if (almp3_poll_mp3stream(stream) == ALMP3_POLL_PLAYJUSTFINISHED) { state_ = SoundClipStopped; } @@ -73,7 +73,7 @@ void MYMP3::adjust_stream() { if (!is_playing()) { return; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); almp3_adjust_mp3stream(stream, get_final_volume(), panning, speed); } @@ -98,7 +98,7 @@ void MYMP3::set_speed(int new_speed) { void MYMP3::destroy() { if (stream) { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); almp3_stop_mp3stream(stream); almp3_destroy_mp3stream(stream); } @@ -129,7 +129,7 @@ int MYMP3::get_pos_ms() { if (!is_playing()) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); return almp3_get_pos_msecs_mp3stream(stream); } @@ -137,7 +137,7 @@ int MYMP3::get_length_ms() { if (!is_playing()) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); return almp3_get_length_msecs_mp3stream(stream, filesize); } @@ -145,7 +145,7 @@ int MYMP3::get_voice() { if (!is_playing()) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); AUDIOSTREAM *ast = almp3_get_audiostream_mp3stream(stream); return (ast != nullptr ? ast->voice : -1); } @@ -160,7 +160,7 @@ int MYMP3::play() { } { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); if (almp3_play_mp3stream(stream, chunksize, (vol > 230) ? vol : vol + 20, panning) != ALMP3_OK) { return 0; } diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index 787bd5a3f39a..148799b0152b 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -29,8 +29,6 @@ namespace AGS3 { -extern AGS::Engine::Mutex _mp3_mutex; - struct MYMP3 : public SOUNDCLIP { ALMP3_MP3STREAM *stream; PACKFILE *in; diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp index 9f27f5546109..65ae8b3ef62d 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -28,17 +28,13 @@ #include "ags/engine/media/audio/audiointernaldefs.h" #include "ags/engine/media/audio/soundcache.h" #include "ags/engine/util/mutex_lock.h" - #include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/ags.h" namespace AGS3 { extern int our_eip; -// ALMP3 functions are not reentrant! This mutex should be locked before calling any -// of the mp3 functions and unlocked afterwards. -AGS::Engine::Mutex _mp3_mutex; - void MYSTATICMP3::poll() { if (state_ != SoundClipPlaying) { return; @@ -47,7 +43,7 @@ void MYSTATICMP3::poll() { int oldeip = our_eip; our_eip = 5997; - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); int result = almp3_poll_mp3(tune); if (result == ALMP3_POLL_PLAYJUSTFINISHED) { @@ -62,7 +58,7 @@ void MYSTATICMP3::adjust_stream() { if (!is_playing()) { return; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); almp3_adjust_mp3(tune, get_final_volume(), panning, speed, repeat); } @@ -82,7 +78,7 @@ void MYSTATICMP3::set_speed(int new_speed) { void MYSTATICMP3::destroy() { if (tune) { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); almp3_stop_mp3(tune); almp3_destroy_mp3(tune); } @@ -100,7 +96,7 @@ void MYSTATICMP3::seek(int pos) { if (!is_playing()) { return; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); almp3_seek_abs_msecs_mp3(tune, pos); } @@ -108,7 +104,7 @@ int MYSTATICMP3::get_pos() { if (!is_playing()) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); return almp3_get_pos_msecs_mp3(tune); } @@ -121,7 +117,7 @@ int MYSTATICMP3::get_length_ms() { if (tune == nullptr) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); return almp3_get_length_msecs_mp3(tune); } @@ -129,7 +125,7 @@ int MYSTATICMP3::get_voice() { if (!is_playing()) { return -1; } - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); AUDIOSTREAM *ast = almp3_get_audiostream_mp3(tune); return (ast != nullptr ? ast->voice : -1); } @@ -144,7 +140,7 @@ int MYSTATICMP3::play() { } { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); int result = almp3_play_ex_mp3(tune, 16384, vol, panning, 1000, repeat); if (result != ALMP3_OK) { return 0; diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index c849a1803bd8..575df1583b54 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -28,8 +28,6 @@ namespace AGS3 { -extern AGS::Engine::Mutex _mp3_mutex; - // pre-loaded (non-streaming) MP3 file struct MYSTATICMP3 : public SOUNDCLIP { ALMP3_MP3 *tune; diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index f92ab6683d29..98134b945637 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -50,6 +50,7 @@ #endif #include "ags/engine/media/audio/soundcache.h" #include "ags/engine/util/mutex_lock.h" +#include "ags/ags.h" namespace AGS3 { @@ -117,7 +118,7 @@ SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) { thistune->buffer = (char *)tmpbuffer; { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); thistune->stream = almp3_create_mp3stream(tmpbuffer, thistune->chunksize, (thistune->filesize < 1)); } @@ -152,7 +153,7 @@ SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) thismp3->repeat = loop; { - AGS::Engine::MutexLock _lockMp3(_mp3_mutex); + AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); thismp3->tune = almp3_create_mp3(mp3buffer, muslen); } diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index 81eb9737a73e..84865d61a3eb 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -30,6 +30,7 @@ #include "ags/engine/util/mutex_lock.h" #include "ags/shared/util/string.h" #include "ags/shared/debugging/out.h" +#include "ags/ags.h" namespace AGS3 { @@ -38,11 +39,8 @@ using namespace Shared; sound_cache_entry_t *sound_cache_entries = nullptr; unsigned int sound_cache_counter = 0; -AGS::Engine::Mutex _sound_cache_mutex; - - void clear_sound_cache() { - AGS::Engine::MutexLock _lock(_sound_cache_mutex); + AGS::Engine::MutexLock _lock(::AGS::g_vm->_soundCacheMutex); if (sound_cache_entries) { int i; @@ -62,7 +60,7 @@ void clear_sound_cache() { } void sound_cache_free(char *buffer, bool is_wave) { - AGS::Engine::MutexLock _lock(_sound_cache_mutex); + AGS::Engine::MutexLock _lock(::AGS::g_vm->_soundCacheMutex); #ifdef SOUND_CACHE_DEBUG Debug::Printf("sound_cache_free(%p %d)\n", buffer, (unsigned int)is_wave); @@ -95,7 +93,7 @@ void sound_cache_free(char *buffer, bool is_wave) { char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) { - AGS::Engine::MutexLock _lock(_sound_cache_mutex); + AGS::Engine::MutexLock _lock(::AGS::g_vm->_soundCacheMutex); #ifdef SOUND_CACHE_DEBUG Debug::Printf("get_cached_sound(%s %d)\n", asset_name.first.GetCStr(), (unsigned int)is_wave); diff --git a/engines/ags/lib/std/thread.h b/engines/ags/lib/std/thread.h index bdd43e6cf7d3..3577b7747df6 100644 --- a/engines/ags/lib/std/thread.h +++ b/engines/ags/lib/std/thread.h @@ -44,8 +44,8 @@ class thread { warning("TODO: thread::join"); } bool joinable() const { - warning("TODO: thread::joinable"); - return true; + // TODO: thread::joinable + return false; } }; From b12b2e39df3973cb2364c13a4bbed01243cc8553 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 19:18:00 -0800 Subject: [PATCH 059/215] AGS: Remove mistake settings from configure.engine --- engines/ags/configure.engine | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/configure.engine b/engines/ags/configure.engine index 6149895b719c..55cba93bb428 100644 --- a/engines/ags/configure.engine +++ b/engines/ags/configure.engine @@ -1,3 +1,3 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine ags "Adventure Game Studio" no "" "" "cxx11 mp3 ogg" +add_engine ags "Adventure Game Studio" no "" "" "cxx11" From 5deca146b84479ed0517985f87a89690124a5433 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 19:30:20 -0800 Subject: [PATCH 060/215] AGS: gcc compilation fixes --- engines/ags/engine/ac/dynobj/cc_character.cpp | 2 +- engines/ags/engine/ac/route_finder_impl_legacy.cpp | 4 ++-- engines/ags/engine/ac/scriptcontainers.cpp | 2 +- engines/ags/engine/ac/timer.cpp | 7 ++++--- engines/ags/lib/allegro/color.cpp | 1 + engines/ags/lib/dumb-0.9.2/it/itrender.cpp | 2 +- engines/ags/lib/std/type_traits.h | 2 ++ engines/ags/shared/ac/dynobj/scriptaudioclip.h | 2 +- engines/ags/shared/font/fonts.cpp | 2 +- engines/ags/shared/font/ttffontrenderer.h | 2 ++ engines/ags/shared/font/wfnfont.cpp | 8 ++++---- engines/ags/shared/font/wfnfontrenderer.h | 2 ++ 12 files changed, 22 insertions(+), 14 deletions(-) diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index c114d948011f..3aacebafaef3 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -58,7 +58,7 @@ void CCCharacter::WriteInt16(const char *address, intptr_t offset, int16_t val) // inventory for older games that reply on the previous behaviour. if (loaded_game_file_version < kGameVersion_270) { const int invoffset = 112; - if (offset >= invoffset && offset < (invoffset + MAX_INV * sizeof(short))) { + if (offset >= invoffset && (int)offset < (invoffset + MAX_INV * sizeof(short))) { update_invorder(); } } diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp index 067900745e8c..b0d6782ffd95 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp +++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp @@ -801,7 +801,7 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int numstages++; nearestindx = -1; - int lastpbs = pathbackstage; +// int lastpbs = pathbackstage; stage_again: nearestpos = 0; @@ -835,7 +835,7 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int #ifdef DEBUG_PATHFINDER AGS::Shared::Debug::Printf("Added: %d, %d pbs:%d", srcx, srcy, pathbackstage); #endif - lastpbs = pathbackstage; +// lastpbs = pathbackstage; pathbackstage = nearestindx; goto stage_again; } diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index e67e3a1ed346..d079ec312e10 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -71,7 +71,7 @@ ScriptDictBase *Dict_Create(bool sorted, bool case_sensitive) { // TODO: we need memory streams ScriptDictBase *Dict_Unserialize(int index, const char *serializedData, int dataSize) { - if (dataSize < sizeof(int32_t) * 2) + if (dataSize < (int)sizeof(int32_t) * 2) quit("Dict_Unserialize: not enough data."); const char *ptr = serializedData; const int sorted = BBOp::Int32FromLE(*((int *)ptr)); diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index 5f26a9c5affb..891471d03f1a 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -99,11 +99,12 @@ bool waitingForNextTick() { if (is_lagging) { #if AGS_PLATFORM_DEBUG && defined (__GNUC__) auto missed_ticks = ((now - last_tick_time) / tick_duration); - printf("Lagging! Missed %lld ticks!\n", (long long)missed_ticks); - void *array[10]; + warning("Lagging! Missed %lld ticks!\n", (long long)missed_ticks); +/* void *array[10]; auto size = backtrace(array, 10); backtrace_symbols_fd(array, size, STDOUT_FILENO); - printf("\n"); +*/ + warning("\n"); #endif last_tick_time = now; return false; diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 14243c765674..bc1bdc25eaf0 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -23,6 +23,7 @@ #include "ags/lib/allegro/color.h" #include "ags/lib/allegro/system.h" #include "ags/lib/allegro/aintern.h" +#include "ags/shared/core/types.h" #include "common/textconsole.h" #include "common/system.h" #include "graphics/palette.h" diff --git a/engines/ags/lib/dumb-0.9.2/it/itrender.cpp b/engines/ags/lib/dumb-0.9.2/it/itrender.cpp index 31be41914c4e..aaed5e799e43 100644 --- a/engines/ags/lib/dumb-0.9.2/it/itrender.cpp +++ b/engines/ags/lib/dumb-0.9.2/it/itrender.cpp @@ -1731,7 +1731,7 @@ Yxy This uses a table 4 times larger (hence 4 times slower) than case IT_S_SET_SURROUND_SOUND: if ((effectvalue & 15) == 1) channel->pan = IT_SURROUND; - channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; + channel->truepan = channel->pan << IT_ENVELOPE_SHIFT; break; case IT_S_SET_HIGH_OFFSET: channel->high_offset = effectvalue & 15; diff --git a/engines/ags/lib/std/type_traits.h b/engines/ags/lib/std/type_traits.h index 564a663ce684..cc33200a8235 100644 --- a/engines/ags/lib/std/type_traits.h +++ b/engines/ags/lib/std/type_traits.h @@ -23,6 +23,8 @@ #ifndef AGS_STD_TYPE_TRAITS_H #define AGS_STD_TYPE_TRAITS_H +#include "common/scummsys.h" + namespace AGS3 { namespace std { diff --git a/engines/ags/shared/ac/dynobj/scriptaudioclip.h b/engines/ags/shared/ac/dynobj/scriptaudioclip.h index dfde8e752e37..317ce5d64c57 100644 --- a/engines/ags/shared/ac/dynobj/scriptaudioclip.h +++ b/engines/ags/shared/ac/dynobj/scriptaudioclip.h @@ -54,7 +54,7 @@ struct ScriptAudioClip { Shared::String scriptName; Shared::String fileName; char bundlingType = AUCL_BUNDLE_EXE; - char type = 0; + int8 type = 0; char fileType = eAudioFileOGG; char defaultRepeat = 0; short defaultPriority = 50; diff --git a/engines/ags/shared/font/fonts.cpp b/engines/ags/shared/font/fonts.cpp index 5ffaf7788f8a..fda7bfbbf9ad 100644 --- a/engines/ags/shared/font/fonts.cpp +++ b/engines/ags/shared/font/fonts.cpp @@ -273,7 +273,7 @@ size_t split_lines(const char *todis, SplitLines &lines, int wii, int fonnt, siz // restore the character that was there before theline[i + 1] = nextCharWas; - if (splitAt != -1) { + if (splitAt != (size_t)-1) { if (splitAt == 0 && !((theline[0] == ' ') || (theline[0] == '\n'))) { // cannot split with current width restriction lines.Reset(); diff --git a/engines/ags/shared/font/ttffontrenderer.h b/engines/ags/shared/font/ttffontrenderer.h index 033425cdc624..3a49157fc4a4 100644 --- a/engines/ags/shared/font/ttffontrenderer.h +++ b/engines/ags/shared/font/ttffontrenderer.h @@ -31,6 +31,8 @@ namespace AGS3 { class TTFFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { public: + virtual ~TTFFontRenderer() {} + // IAGSFontRenderer implementation bool LoadFromDisk(int fontNumber, int fontSize) override; void FreeMemory(int fontNumber) override; diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index 2e07a5955c05..5b7ce146547c 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -67,7 +67,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { } const soff_t table_addr = static_cast(in->ReadInt16()); // offset table relative address - if (table_addr < WFN_FILE_SIG_LENGTH + sizeof(uint16_t) || table_addr >= used_data_size) { + if ((int)table_addr < WFN_FILE_SIG_LENGTH + sizeof(uint16_t) || table_addr >= used_data_size) { Debug::Printf(kDbgMsg_Error, "\tWFN: bad table address: %lld (%d - %d)", table_addr, WFN_FILE_SIG_LENGTH + sizeof(uint16_t), used_data_size); return kWFNErr_BadTableAddress; // bad table address } @@ -99,7 +99,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { offs.reserve(char_count); // reserve max possible offsets for (size_t i = 0; i < char_count; ++i) { const uint16_t off = offset_table[i]; - if (off < raw_data_offset || off + MinCharDataSize > table_addr) { + if (off < raw_data_offset || (int)(off + MinCharDataSize) > table_addr) { Debug::Printf("\tWFN: character %d -- bad item offset: %d (%d - %d, +%d)", i, off, raw_data_offset, table_addr, MinCharDataSize); err = kWFNErr_HasBadCharacters; // warn about potentially corrupt format @@ -142,7 +142,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { } const uint16_t raw_off = offs[i] - raw_data_offset + MinCharDataSize; // offset in raw array size_t src_size = pixel_data_size; - if (i + 1 != _items.size() && raw_off + src_size > offs[i + 1] - raw_data_offset) { + if (i + 1 != _items.size() && (int)(raw_off + src_size) > (offs[i + 1] - raw_data_offset)) { // character pixel data overlaps next character Debug::Printf("\tWFN: item at off %d -- pixel data overlaps next known item (at %d, +%d)", offs[i], offs[i + 1], MinCharDataSize + src_size); @@ -170,7 +170,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { for (size_t i = 0; i < char_count; ++i) { const uint16_t off = offset_table[i]; // if bad character offset - reference empty character - if (off < raw_data_offset || off + MinCharDataSize > table_addr) { + if (off < raw_data_offset || (int)(off + MinCharDataSize) > table_addr) { _refs[i] = &_emptyChar; } else { // in usual case the offset table references items in strict order diff --git a/engines/ags/shared/font/wfnfontrenderer.h b/engines/ags/shared/font/wfnfontrenderer.h index 47341efe48c2..6b06dfdf3be6 100644 --- a/engines/ags/shared/font/wfnfontrenderer.h +++ b/engines/ags/shared/font/wfnfontrenderer.h @@ -32,6 +32,8 @@ class WFNFont; class WFNFontRenderer : public IAGSFontRenderer, public IAGSFontRenderer2 { public: + virtual ~WFNFontRenderer() {} + bool LoadFromDisk(int fontNumber, int fontSize) override; void FreeMemory(int fontNumber) override; bool SupportsExtendedCharacters(int fontNumber) override; From a0f5cef1e53ff7459d7068591fff96f9882476b9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 21:31:43 -0800 Subject: [PATCH 061/215] AGS: Fix a bunch of warnings about const loss Some of these are legitimate, because the AGS source did some nasty code sharing a char * buffer for both reading and writing stuff to savegames. Will need to refactor it at some point to use the Common::Serializer --- .../ags/engine/ac/dynobj/cc_audiochannel.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_audioclip.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_character.cpp | 4 ++-- engines/ags/engine/ac/dynobj/scriptcamera.cpp | 2 +- .../ags/engine/ac/dynobj/scriptviewport.cpp | 2 +- engines/ags/engine/ac/scriptcontainers.cpp | 10 +++++----- .../ags/engine/ac/statobj/agsstaticobject.cpp | 20 +++++++++---------- engines/ags/engine/ac/string.cpp | 2 +- engines/ags/shared/font/wfnfont.cpp | 2 +- engines/ags/shared/game/main_game_file.cpp | 4 ++-- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp index ae636d4de88a..1edc98acab92 100644 --- a/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audiochannel.cpp @@ -33,7 +33,7 @@ const char *CCAudioChannel::GetType() { } int CCAudioChannel::Serialize(const char *address, char *buffer, int bufsize) { - ScriptAudioChannel *ach = (ScriptAudioChannel *)address; + ScriptAudioChannel *ach = (ScriptAudioChannel *)const_cast(address); StartSerialize(buffer); SerializeInt(ach->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp index cebe70e77933..01351f4eefe1 100644 --- a/engines/ags/engine/ac/dynobj/cc_audioclip.cpp +++ b/engines/ags/engine/ac/dynobj/cc_audioclip.cpp @@ -33,7 +33,7 @@ const char *CCAudioClip::GetType() { } int CCAudioClip::Serialize(const char *address, char *buffer, int bufsize) { - ScriptAudioClip *ach = (ScriptAudioClip *)address; + ScriptAudioClip *ach = (ScriptAudioClip *)const_cast(address); StartSerialize(buffer); SerializeInt(ach->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index 3aacebafaef3..6d8d28314219 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -38,7 +38,7 @@ const char *CCCharacter::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCCharacter::Serialize(const char *address, char *buffer, int bufsize) { - CharacterInfo *chaa = (CharacterInfo *)address; + CharacterInfo *chaa = (CharacterInfo *)const_cast(address); StartSerialize(buffer); SerializeInt(chaa->index_id); return EndSerialize(); @@ -51,7 +51,7 @@ void CCCharacter::Unserialize(int index, const char *serializedData, int dataSiz } void CCCharacter::WriteInt16(const char *address, intptr_t offset, int16_t val) { - *(int16_t *)(address + offset) = val; + *(int16_t *)(const_cast(address) + offset) = val; // Detect when a game directly modifies the inventory, which causes the displayed // and actual inventory to diverge since 2.70. Force an update of the displayed diff --git a/engines/ags/engine/ac/dynobj/scriptcamera.cpp b/engines/ags/engine/ac/dynobj/scriptcamera.cpp index aa7aa5d8bd73..be9f7bacd601 100644 --- a/engines/ags/engine/ac/dynobj/scriptcamera.cpp +++ b/engines/ags/engine/ac/dynobj/scriptcamera.cpp @@ -59,7 +59,7 @@ ScriptCamera *Camera_Unserialize(int handle, const char *serializedData, int dat // but acquire one from the GameState, which keeps the first reference. // This is essential because GameState should be able to invalidate any // script references when Camera gets removed. - const int id = BBOp::Int32FromLE(*((int *)serializedData)); + const int id = BBOp::Int32FromLE(*((const int *)serializedData)); if (id >= 0) { auto scam = play.RegisterRoomCamera(id, handle); if (scam) diff --git a/engines/ags/engine/ac/dynobj/scriptviewport.cpp b/engines/ags/engine/ac/dynobj/scriptviewport.cpp index e578dce59421..99c3eae0e31d 100644 --- a/engines/ags/engine/ac/dynobj/scriptviewport.cpp +++ b/engines/ags/engine/ac/dynobj/scriptviewport.cpp @@ -59,7 +59,7 @@ ScriptViewport *Viewport_Unserialize(int handle, const char *serializedData, int // but acquire one from the GameState, which keeps the first reference. // This is essential because GameState should be able to invalidate any // script references when Viewport gets removed. - const int id = BBOp::Int32FromLE(*((int *)serializedData)); + const int id = BBOp::Int32FromLE(*((const int *)serializedData)); if (id >= 0) { auto scview = play.RegisterRoomViewport(id, handle); if (scview) diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index d079ec312e10..4bf42ca47484 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -74,9 +74,9 @@ ScriptDictBase *Dict_Unserialize(int index, const char *serializedData, int data if (dataSize < (int)sizeof(int32_t) * 2) quit("Dict_Unserialize: not enough data."); const char *ptr = serializedData; - const int sorted = BBOp::Int32FromLE(*((int *)ptr)); + const int sorted = BBOp::Int32FromLE(*((const int *)ptr)); ptr += sizeof(int32_t); - const int cs = BBOp::Int32FromLE(*((int *)ptr)); + const int cs = BBOp::Int32FromLE(*((const int *)ptr)); ptr += sizeof(int32_t); ScriptDictBase *dic = Dict_CreateImpl(sorted != 0, cs != 0); dic->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); @@ -208,12 +208,12 @@ ScriptSetBase *Set_Create(bool sorted, bool case_sensitive) { // TODO: we need memory streams ScriptSetBase *Set_Unserialize(int index, const char *serializedData, int dataSize) { - if (dataSize < sizeof(int32_t) * 2) + if (dataSize < (int)sizeof(int32_t) * 2) quit("Set_Unserialize: not enough data."); const char *ptr = serializedData; - const int sorted = BBOp::Int32FromLE(*((int *)ptr)); + const int sorted = BBOp::Int32FromLE(*((const int *)ptr)); ptr += sizeof(int32_t); - const int cs = BBOp::Int32FromLE(*((int *)ptr)); + const int cs = BBOp::Int32FromLE(*((const int *)ptr)); ptr += sizeof(int32_t); ScriptSetBase *set = Set_CreateImpl(sorted != 0, cs != 0); set->Unserialize(index, ptr, dataSize -= sizeof(int32_t) * 2); diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp index 1351b6995228..e76e5c014933 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.cpp +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -39,39 +39,39 @@ void AGSStaticObject::Read(const char *address, intptr_t offset, void *dest, int } uint8_t AGSStaticObject::ReadInt8(const char *address, intptr_t offset) { - return *(uint8_t *)(address + offset); + return *(const uint8_t *)(address + offset); } int16_t AGSStaticObject::ReadInt16(const char *address, intptr_t offset) { - return *(int16_t *)(address + offset); + return *(const int16_t *)(address + offset); } int32_t AGSStaticObject::ReadInt32(const char *address, intptr_t offset) { - return *(int32_t *)(address + offset); + return *(const int32_t *)(address + offset); } float AGSStaticObject::ReadFloat(const char *address, intptr_t offset) { - return *(float *)(address + offset); + return *(const float *)(address + offset); } void AGSStaticObject::Write(const char *address, intptr_t offset, void *src, int size) { - memcpy((void *)(address + offset), src, size); + memcpy((void *)(const_cast(address) + offset), src, size); } void AGSStaticObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) { - *(uint8_t *)(address + offset) = val; + *(uint8_t *)(const_cast(address) + offset) = val; } void AGSStaticObject::WriteInt16(const char *address, intptr_t offset, int16_t val) { - *(int16_t *)(address + offset) = val; + *(int16_t *)(const_cast(address) + offset) = val; } void AGSStaticObject::WriteInt32(const char *address, intptr_t offset, int32_t val) { - *(int32_t *)(address + offset) = val; + *(int32_t *)(const_cast(address) + offset) = val; } void AGSStaticObject::WriteFloat(const char *address, intptr_t offset, float val) { - *(float *)(address + offset) = val; + *(float *)(const_cast(address) + offset) = val; } @@ -83,7 +83,7 @@ void StaticGame::WriteInt32(const char *address, intptr_t offset, int32_t val) { // game.text_align, game.speech_text_align *(int32_t *)(address + offset) = ReadScriptAlignment(val); } else { - *(int32_t *)(address + offset) = val; + *(int32_t *)(const_cast(address) + offset) = val; } } diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index b1ac38d05c32..b33ee59eb438 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -222,7 +222,7 @@ DynObjectRef CreateNewScriptStringObj(const char *fromText, bool reAllocate) { str = new ScriptString(fromText); } else { str = new ScriptString(); - str->text = (char *)fromText; + str->text = const_cast(fromText); } void *obj_ptr = str->text; int32_t handle = ccRegisterManagedObject(obj_ptr, str); diff --git a/engines/ags/shared/font/wfnfont.cpp b/engines/ags/shared/font/wfnfont.cpp index 5b7ce146547c..d4a8b96c8bb4 100644 --- a/engines/ags/shared/font/wfnfont.cpp +++ b/engines/ags/shared/font/wfnfont.cpp @@ -67,7 +67,7 @@ WFNError WFNFont::ReadFromFile(Stream *in, const soff_t data_size) { } const soff_t table_addr = static_cast(in->ReadInt16()); // offset table relative address - if ((int)table_addr < WFN_FILE_SIG_LENGTH + sizeof(uint16_t) || table_addr >= used_data_size) { + if (table_addr < (int)(WFN_FILE_SIG_LENGTH + sizeof(uint16_t)) || table_addr >= used_data_size) { Debug::Printf(kDbgMsg_Error, "\tWFN: bad table address: %lld (%d - %d)", table_addr, WFN_FILE_SIG_LENGTH + sizeof(uint16_t), used_data_size); return kWFNErr_BadTableAddress; // bad table address } diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 48edb9ab8b15..8f6c7f008420 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -310,8 +310,8 @@ void ReadDialogs(DialogTopic *&dialog, } else { // Encrypted text on > 2.60 while (1) { - size_t newlen = in->ReadInt32(); - if (static_cast(newlen) == 0xCAFEBEEF) { // GUI magic + size_t newlen = (size_t)in->ReadInt32(); + if (newlen == 0xCAFEBEEF) { // GUI magic in->Seek(-4); break; } From d9e394541858d4ae2d096c4abf0954df6fc21274 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 21:36:59 -0800 Subject: [PATCH 062/215] AGS: Further gcc warning fixes --- engines/ags/engine/ac/dynobj/managedobjectpool.cpp | 6 ++++-- engines/ags/lib/std/algorithm.h | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp index f89fe386984b..1b6b6f08dc46 100644 --- a/engines/ags/engine/ac/dynobj/managedobjectpool.cpp +++ b/engines/ags/engine/ac/dynobj/managedobjectpool.cpp @@ -49,7 +49,9 @@ int ManagedObjectPool::Remove(ManagedObject &o, bool force) { return 0; } +#ifdef DEBUG_MANAGED_OBJECTS auto handle = o.handle; +#endif available_ids.push(o.handle); handleByAddress.erase(o.addr); @@ -141,7 +143,7 @@ ScriptValueType ManagedObjectPool::HandleToAddressAndManager(int32_t handle, voi return kScValUndefined; } - object = (void *)o.addr; // WARNING: This strips the const from the char* pointer. + object = const_cast(o.addr); // WARNING: This strips the const from the char* pointer. manager = o.callback; return o.obj_type; } @@ -259,7 +261,7 @@ void ManagedObjectPool::WriteToDisk(Stream *out) { // handle out->WriteInt32(o.handle); // write the type of the object - StrUtil::WriteCStr((char *)o.callback->GetType(), out); + StrUtil::WriteCStr(const_cast(o.callback->GetType()), out); // now write the object data int bytesWritten = o.callback->Serialize(o.addr, &serializeBuffer.front(), serializeBuffer.size()); if ((bytesWritten < 0) && ((size_t)(-bytesWritten) > serializeBuffer.size())) { diff --git a/engines/ags/lib/std/algorithm.h b/engines/ags/lib/std/algorithm.h index f95335f35180..427779ca842e 100644 --- a/engines/ags/lib/std/algorithm.h +++ b/engines/ags/lib/std/algorithm.h @@ -65,7 +65,9 @@ T unique(T first, T last) { if (*pos == *existingPos) { // Found a match, so shift values over the duplicate while (pos < (last - 1)) { - *pos++ = *(pos + 1); + T &prior = pos; + ++pos; + prior = pos; } --last; From 7dadc02947ce7521387f0e738030c6103e0d9a2f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 Nov 2020 21:49:31 -0800 Subject: [PATCH 063/215] AGS: Add detection for Black Cauldron Remake --- engines/ags/detection_tables.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 29a04e180b94..d7c4411af872 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -24,10 +24,25 @@ namespace AGS { static const PlainGameDescriptor AGS_GAMES[] = { { "ags", "Adventure Game Studio Game" }, + + { "bcremake", "Black Cauldron Remake" }, { 0, 0 } }; + static const AGSGameDescription GAME_DESCRIPTIONS[] = { + { + { + "bcremake", + nullptr, + AD_ENTRY1s("bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOSPEECH) + } + }, + { AD_TABLE_END_MARKER } }; From cdbc1152e152edd8f7a67d0f75b66e6cc8c5b6f1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 29 Nov 2020 09:01:37 -0800 Subject: [PATCH 064/215] AGS: Further const loss warning fixes --- engines/ags/engine/ac/character.cpp | 2 +- .../engine/ac/dynobj/cc_agsdynamicobject.cpp | 28 +++++++++---------- engines/ags/engine/ac/dynobj/cc_character.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_dialog.cpp | 2 +- .../ags/engine/ac/dynobj/cc_dynamicarray.cpp | 22 +++++++-------- engines/ags/engine/ac/dynobj/cc_gui.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_hotspot.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_inventory.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_object.cpp | 2 +- engines/ags/engine/ac/dynobj/cc_region.cpp | 2 +- .../ags/engine/ac/statobj/agsstaticobject.cpp | 2 +- engines/ags/engine/ac/statobj/staticarray.cpp | 18 ++++++------ 12 files changed, 43 insertions(+), 43 deletions(-) diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index cfee01f260db..3bb7e6c7401f 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -745,7 +745,7 @@ void Character_Say(CharacterInfo *chaa, const char *text) { void Character_SayAt(CharacterInfo *chaa, int x, int y, int width, const char *texx) { - DisplaySpeechAt(x, y, width, chaa->index_id, (char *)texx); + DisplaySpeechAt(x, y, width, chaa->index_id, texx); } ScriptOverlay *Character_SayBackground(CharacterInfo *chaa, const char *texx) { diff --git a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp index c0d4d780f0c5..e711ba39634b 100644 --- a/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp +++ b/engines/ags/engine/ac/dynobj/cc_agsdynamicobject.cpp @@ -63,25 +63,25 @@ int AGSCCDynamicObject::EndSerialize() { void AGSCCDynamicObject::StartUnserialize(const char *sbuffer, int pTotalBytes) { bytesSoFar = 0; totalBytes = pTotalBytes; - serbuffer = (char *)sbuffer; + serbuffer = const_cast(sbuffer); } int AGSCCDynamicObject::UnserializeInt() { if (bytesSoFar >= totalBytes) quit("Unserialise: internal error: read past EOF"); - char *chptr = &serbuffer[bytesSoFar]; + const char *chptr = &serbuffer[bytesSoFar]; bytesSoFar += 4; - return BBOp::Int32FromLE(*((int *)chptr)); + return BBOp::Int32FromLE(*((const int *)chptr)); } float AGSCCDynamicObject::UnserializeFloat() { if (bytesSoFar >= totalBytes) quit("Unserialise: internal error: read past EOF"); - char *chptr = &serbuffer[bytesSoFar]; + const char *chptr = &serbuffer[bytesSoFar]; bytesSoFar += 4; - return BBOp::FloatFromLE(*((float *)chptr)); + return BBOp::FloatFromLE(*((const float *)chptr)); } const char *AGSCCDynamicObject::GetFieldPtr(const char *address, intptr_t offset) { @@ -93,39 +93,39 @@ void AGSCCDynamicObject::Read(const char *address, intptr_t offset, void *dest, } uint8_t AGSCCDynamicObject::ReadInt8(const char *address, intptr_t offset) { - return *(uint8_t *)(address + offset); + return *(const uint8_t *)(address + offset); } int16_t AGSCCDynamicObject::ReadInt16(const char *address, intptr_t offset) { - return *(int16_t *)(address + offset); + return *(const int16_t *)(address + offset); } int32_t AGSCCDynamicObject::ReadInt32(const char *address, intptr_t offset) { - return *(int32_t *)(address + offset); + return *(const int32_t *)(address + offset); } float AGSCCDynamicObject::ReadFloat(const char *address, intptr_t offset) { - return *(float *)(address + offset); + return *(const float *)(address + offset); } void AGSCCDynamicObject::Write(const char *address, intptr_t offset, void *src, int size) { - memcpy((void *)(address + offset), src, size); + memcpy((void *)(const_cast(address) + offset), src, size); } void AGSCCDynamicObject::WriteInt8(const char *address, intptr_t offset, uint8_t val) { - *(uint8_t *)(address + offset) = val; + *(uint8_t *)(const_cast(address) + offset) = val; } void AGSCCDynamicObject::WriteInt16(const char *address, intptr_t offset, int16_t val) { - *(int16_t *)(address + offset) = val; + *(int16_t *)(const_cast(address) + offset) = val; } void AGSCCDynamicObject::WriteInt32(const char *address, intptr_t offset, int32_t val) { - *(int32_t *)(address + offset) = val; + *(int32_t *)(const_cast(address) + offset) = val; } void AGSCCDynamicObject::WriteFloat(const char *address, intptr_t offset, float val) { - *(float *)(address + offset) = val; + *(float *)(const_cast(address) + offset) = val; } } // namespace AGS3 diff --git a/engines/ags/engine/ac/dynobj/cc_character.cpp b/engines/ags/engine/ac/dynobj/cc_character.cpp index 6d8d28314219..a4a03ad253fa 100644 --- a/engines/ags/engine/ac/dynobj/cc_character.cpp +++ b/engines/ags/engine/ac/dynobj/cc_character.cpp @@ -58,7 +58,7 @@ void CCCharacter::WriteInt16(const char *address, intptr_t offset, int16_t val) // inventory for older games that reply on the previous behaviour. if (loaded_game_file_version < kGameVersion_270) { const int invoffset = 112; - if (offset >= invoffset && (int)offset < (invoffset + MAX_INV * sizeof(short))) { + if (offset >= invoffset && offset < (int)(invoffset + MAX_INV * sizeof(short))) { update_invorder(); } } diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp index 6be1090eccfd..e6283dec2a4c 100644 --- a/engines/ags/engine/ac/dynobj/cc_dialog.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp @@ -35,7 +35,7 @@ const char *CCDialog::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCDialog::Serialize(const char *address, char *buffer, int bufsize) { - ScriptDialog *shh = (ScriptDialog *)address; + ScriptDialog *shh = (ScriptDialog *)const_cast(address); StartSerialize(buffer); SerializeInt(shh->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp index 03fe6797072e..0d12ddb439e3 100644 --- a/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp +++ b/engines/ags/engine/ac/dynobj/cc_dynamicarray.cpp @@ -37,7 +37,7 @@ int CCDynamicArray::Dispose(const char *address, bool force) { // except if this array is forcefully removed from the managed pool, // in which case just ignore these. if (!force) { - int *elementCount = (int *)address; + int *elementCount = (int *)const_cast(address); if (elementCount[0] & ARRAY_MANAGED_TYPE_FLAG) { elementCount[0] &= ~ARRAY_MANAGED_TYPE_FLAG; for (int i = 0; i < elementCount[0]; i++) { @@ -55,7 +55,7 @@ int CCDynamicArray::Dispose(const char *address, bool force) { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCDynamicArray::Serialize(const char *address, char *buffer, int bufsize) { - int *sizeInBytes = &((int *)address)[-1]; + const int *sizeInBytes = &((const int *)address)[-1]; int sizeToWrite = *sizeInBytes + 8; if (sizeToWrite > bufsize) { // buffer not big enough, ask for a bigger one @@ -98,39 +98,39 @@ void CCDynamicArray::Read(const char *address, intptr_t offset, void *dest, int } uint8_t CCDynamicArray::ReadInt8(const char *address, intptr_t offset) { - return *(uint8_t *)(address + offset); + return *(const uint8_t *)(address + offset); } int16_t CCDynamicArray::ReadInt16(const char *address, intptr_t offset) { - return *(int16_t *)(address + offset); + return *(const int16_t *)(address + offset); } int32_t CCDynamicArray::ReadInt32(const char *address, intptr_t offset) { - return *(int32_t *)(address + offset); + return *(const int32_t *)(address + offset); } float CCDynamicArray::ReadFloat(const char *address, intptr_t offset) { - return *(float *)(address + offset); + return *(const float *)(address + offset); } void CCDynamicArray::Write(const char *address, intptr_t offset, void *src, int size) { - memcpy((void *)(address + offset), src, size); + memcpy((void *)(const_cast(address) + offset), src, size); } void CCDynamicArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) { - *(uint8_t *)(address + offset) = val; + *(uint8_t *)(const_cast(address) + offset) = val; } void CCDynamicArray::WriteInt16(const char *address, intptr_t offset, int16_t val) { - *(int16_t *)(address + offset) = val; + *(int16_t *)(const_cast(address) + offset) = val; } void CCDynamicArray::WriteInt32(const char *address, intptr_t offset, int32_t val) { - *(int32_t *)(address + offset) = val; + *(int32_t *)(const_cast(address) + offset) = val; } void CCDynamicArray::WriteFloat(const char *address, intptr_t offset, float val) { - *(float *)(address + offset) = val; + *(float *)(const_cast(address) + offset) = val; } CCDynamicArray globalDynamicArray; diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp index 4c9b46482fd7..cdc7c871b683 100644 --- a/engines/ags/engine/ac/dynobj/cc_gui.cpp +++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp @@ -35,7 +35,7 @@ const char *CCGUI::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCGUI::Serialize(const char *address, char *buffer, int bufsize) { - ScriptGUI *shh = (ScriptGUI *)address; + ScriptGUI *shh = (ScriptGUI *)const_cast(address); StartSerialize(buffer); SerializeInt(shh->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp index 8a4677404235..33fe02d8234c 100644 --- a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp +++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp @@ -37,7 +37,7 @@ const char *CCHotspot::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCHotspot::Serialize(const char *address, char *buffer, int bufsize) { - ScriptHotspot *shh = (ScriptHotspot *)address; + ScriptHotspot *shh = (ScriptHotspot *)const_cast(address); StartSerialize(buffer); SerializeInt(shh->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp index 60cae380be96..f453395f7ad7 100644 --- a/engines/ags/engine/ac/dynobj/cc_inventory.cpp +++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp @@ -36,7 +36,7 @@ const char *CCInventory::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCInventory::Serialize(const char *address, char *buffer, int bufsize) { - ScriptInvItem *shh = (ScriptInvItem *)address; + ScriptInvItem *shh = (ScriptInvItem *)const_cast(address); StartSerialize(buffer); SerializeInt(shh->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp index abcd84f8dc3f..35b61676e7f3 100644 --- a/engines/ags/engine/ac/dynobj/cc_object.cpp +++ b/engines/ags/engine/ac/dynobj/cc_object.cpp @@ -37,7 +37,7 @@ const char *CCObject::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCObject::Serialize(const char *address, char *buffer, int bufsize) { - ScriptObject *shh = (ScriptObject *)address; + ScriptObject *shh = (ScriptObject *)const_cast(address); StartSerialize(buffer); SerializeInt(shh->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp index a6fc8910b588..56d099b1c42b 100644 --- a/engines/ags/engine/ac/dynobj/cc_region.cpp +++ b/engines/ags/engine/ac/dynobj/cc_region.cpp @@ -37,7 +37,7 @@ const char *CCRegion::GetType() { // serialize the object into BUFFER (which is BUFSIZE bytes) // return number of bytes used int CCRegion::Serialize(const char *address, char *buffer, int bufsize) { - ScriptRegion *shh = (ScriptRegion *)address; + ScriptRegion *shh = (ScriptRegion *)const_cast(address); StartSerialize(buffer); SerializeInt(shh->id); return EndSerialize(); diff --git a/engines/ags/engine/ac/statobj/agsstaticobject.cpp b/engines/ags/engine/ac/statobj/agsstaticobject.cpp index e76e5c014933..4cc1f476cc51 100644 --- a/engines/ags/engine/ac/statobj/agsstaticobject.cpp +++ b/engines/ags/engine/ac/statobj/agsstaticobject.cpp @@ -81,7 +81,7 @@ void StaticGame::WriteInt32(const char *address, intptr_t offset, int32_t val) { set_debug_mode(val != 0); } else if (offset == 99 * sizeof(int32_t) || offset == 112 * sizeof(int32_t)) { // game.text_align, game.speech_text_align - *(int32_t *)(address + offset) = ReadScriptAlignment(val); + *(int32_t *)(const_cast(address) + offset) = ReadScriptAlignment(val); } else { *(int32_t *)(const_cast(address) + offset) = val; } diff --git a/engines/ags/engine/ac/statobj/staticarray.cpp b/engines/ags/engine/ac/statobj/staticarray.cpp index b70c029d2e39..dd02d047cfa9 100644 --- a/engines/ags/engine/ac/statobj/staticarray.cpp +++ b/engines/ags/engine/ac/statobj/staticarray.cpp @@ -79,7 +79,7 @@ uint8_t StaticArray::ReadInt8(const char *address, intptr_t offset) { } else if (_dynamicMgr) { return _dynamicMgr->ReadInt8(el_ptr, offset % _elemLegacySize); } - return *(uint8_t *)(el_ptr + offset % _elemLegacySize); + return *(const uint8_t *)(el_ptr + offset % _elemLegacySize); } int16_t StaticArray::ReadInt16(const char *address, intptr_t offset) { @@ -89,7 +89,7 @@ int16_t StaticArray::ReadInt16(const char *address, intptr_t offset) { } else if (_dynamicMgr) { return _dynamicMgr->ReadInt16(el_ptr, offset % _elemLegacySize); } - return *(uint16_t *)(el_ptr + offset % _elemLegacySize); + return *(const uint16_t *)(el_ptr + offset % _elemLegacySize); } int32_t StaticArray::ReadInt32(const char *address, intptr_t offset) { @@ -99,7 +99,7 @@ int32_t StaticArray::ReadInt32(const char *address, intptr_t offset) { } else if (_dynamicMgr) { return _dynamicMgr->ReadInt32(el_ptr, offset % _elemLegacySize); } - return *(uint32_t *)(el_ptr + offset % _elemLegacySize); + return *(const uint32_t *)(el_ptr + offset % _elemLegacySize); } float StaticArray::ReadFloat(const char *address, intptr_t offset) { @@ -109,7 +109,7 @@ float StaticArray::ReadFloat(const char *address, intptr_t offset) { } else if (_dynamicMgr) { return _dynamicMgr->ReadFloat(el_ptr, offset % _elemLegacySize); } - return *(float *)(el_ptr + offset % _elemLegacySize); + return *(const float *)(el_ptr + offset % _elemLegacySize); } void StaticArray::Write(const char *address, intptr_t offset, void *src, int size) { @@ -119,7 +119,7 @@ void StaticArray::Write(const char *address, intptr_t offset, void *src, int siz } else if (_dynamicMgr) { return _dynamicMgr->Write(el_ptr, offset % _elemLegacySize, src, size); } else { - memcpy((void *)(el_ptr + offset % _elemLegacySize), src, size); + memcpy((void *)(const_cast(el_ptr) + offset % _elemLegacySize), src, size); } } @@ -130,7 +130,7 @@ void StaticArray::WriteInt8(const char *address, intptr_t offset, uint8_t val) { } else if (_dynamicMgr) { return _dynamicMgr->WriteInt8(el_ptr, offset % _elemLegacySize, val); } else { - *(uint8_t *)(el_ptr + offset % _elemLegacySize) = val; + *(uint8_t *)(const_cast(el_ptr) + offset % _elemLegacySize) = val; } } @@ -141,7 +141,7 @@ void StaticArray::WriteInt16(const char *address, intptr_t offset, int16_t val) } else if (_dynamicMgr) { return _dynamicMgr->WriteInt16(el_ptr, offset % _elemLegacySize, val); } else { - *(uint16_t *)(el_ptr + offset % _elemLegacySize) = val; + *(uint16_t *)(const_cast(el_ptr) + offset % _elemLegacySize) = val; } } @@ -152,7 +152,7 @@ void StaticArray::WriteInt32(const char *address, intptr_t offset, int32_t val) } else if (_dynamicMgr) { return _dynamicMgr->WriteInt32(el_ptr, offset % _elemLegacySize, val); } else { - *(uint32_t *)(el_ptr + offset % _elemLegacySize) = val; + *(uint32_t *)(const_cast(el_ptr) + offset % _elemLegacySize) = val; } } @@ -163,7 +163,7 @@ void StaticArray::WriteFloat(const char *address, intptr_t offset, float val) { } else if (_dynamicMgr) { return _dynamicMgr->WriteFloat(el_ptr, offset % _elemLegacySize, val); } else { - *(float *)(el_ptr + offset % _elemLegacySize) = val; + *(float *)(const_cast(el_ptr) + offset % _elemLegacySize) = val; } } From 98134642b95cb4f46d585282c59acd9cc0a2a486 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 29 Nov 2020 14:07:17 -0800 Subject: [PATCH 065/215] AGS: Fix const warnings in macro expansions --- engines/ags/engine/ac/button.cpp | 2 +- engines/ags/engine/ac/character.cpp | 4 +-- engines/ags/engine/ac/dialog.cpp | 2 +- engines/ags/engine/ac/file.cpp | 4 +-- engines/ags/engine/ac/game.cpp | 16 +++++----- engines/ags/engine/ac/global_api.cpp | 2 +- engines/ags/engine/ac/hotspot.cpp | 4 +-- engines/ags/engine/ac/inventoryitem.cpp | 4 +-- engines/ags/engine/ac/label.cpp | 2 +- engines/ags/engine/ac/listbox.cpp | 2 +- engines/ags/engine/ac/object.cpp | 4 +-- engines/ags/engine/ac/parser.cpp | 2 +- engines/ags/engine/ac/room.cpp | 4 +-- engines/ags/engine/ac/route_finder.cpp | 5 ++++ engines/ags/engine/ac/scriptcontainers.cpp | 2 +- engines/ags/engine/ac/string.cpp | 20 ++++++------- engines/ags/engine/ac/system.cpp | 4 +-- engines/ags/engine/ac/textbox.cpp | 2 +- engines/ags/engine/script/script_api.h | 35 ++++++++++++++++++++++ 19 files changed, 80 insertions(+), 40 deletions(-) diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp index e533a6384ba9..e6e1267e9585 100644 --- a/engines/ags/engine/ac/button.cpp +++ b/engines/ags/engine/ac/button.cpp @@ -315,7 +315,7 @@ RuntimeScriptValue Sc_Button_Animate(void *self, const RuntimeScriptValue *param // const char* | GUIButton *butt RuntimeScriptValue Sc_Button_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(GUIButton, const char, myScriptStringImpl, Button_GetText_New); + API_CONST_OBJCALL_OBJ(GUIButton, const char, myScriptStringImpl, Button_GetText_New); } // void | GUIButton *butt, char *buffer diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp index 3bb7e6c7401f..5e7623a7aadf 100644 --- a/engines/ags/engine/ac/character.cpp +++ b/engines/ags/engine/ac/character.cpp @@ -2930,7 +2930,7 @@ RuntimeScriptValue Sc_Character_GetPropertyText(void *self, const RuntimeScriptV // const char* (CharacterInfo *chaa, const char *property) RuntimeScriptValue Sc_Character_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_POBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetTextProperty, const char); + API_CONST_OBJCALL_OBJ_POBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetTextProperty, const char); } RuntimeScriptValue Sc_Character_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { @@ -3364,7 +3364,7 @@ RuntimeScriptValue Sc_Character_GetDestinationY(void *self, const RuntimeScriptV // const char* (CharacterInfo *chaa) RuntimeScriptValue Sc_Character_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetName); + API_CONST_OBJCALL_OBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetName); } // void (CharacterInfo *chaa, const char *newName) diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 6c7d6d9f1a40..92c3e0fb4543 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -1182,7 +1182,7 @@ RuntimeScriptValue Sc_Dialog_GetOptionState(void *self, const RuntimeScriptValue // const char* (ScriptDialog *sd, int option) RuntimeScriptValue Sc_Dialog_GetOptionText(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_PINT(ScriptDialog, const char, myScriptStringImpl, Dialog_GetOptionText); + API_CONST_OBJCALL_OBJ_PINT(ScriptDialog, const char, myScriptStringImpl, Dialog_GetOptionText); } // int (ScriptDialog *sd, int option) diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index ae826d948928..d20793aaea2b 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -662,7 +662,7 @@ RuntimeScriptValue Sc_File_ReadRawLine(void *self, const RuntimeScriptValue *par // const char* (sc_File *fil) RuntimeScriptValue Sc_File_ReadRawLineBack(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadRawLineBack); + API_CONST_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadRawLineBack); } // void (sc_File *fil, char *toread) @@ -672,7 +672,7 @@ RuntimeScriptValue Sc_File_ReadString(void *self, const RuntimeScriptValue *para // const char* (sc_File *fil) RuntimeScriptValue Sc_File_ReadStringBack(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadStringBack); + API_CONST_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadStringBack); } // void (sc_File *fil, int towrite) diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index b1f40dc1aa7e..561a0d0c8f58 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -1988,7 +1988,7 @@ RuntimeScriptValue Sc_Game_GetFrameCountForLoop(const RuntimeScriptValue *params // const char* (int x, int y) RuntimeScriptValue Sc_Game_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_PINT2(const char, myScriptStringImpl, Game_GetLocationName); + API_CONST_SCALL_OBJ_PINT2(const char, myScriptStringImpl, Game_GetLocationName); } // int (int viewNumber) @@ -2008,7 +2008,7 @@ RuntimeScriptValue Sc_Game_GetRunNextSettingForLoop(const RuntimeScriptValue *pa // const char* (int slnum) RuntimeScriptValue Sc_Game_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetSaveSlotDescription); + API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetSaveSlotDescription); } // ScriptViewFrame* (int viewNumber, int loopNumber, int frame) @@ -2018,7 +2018,7 @@ RuntimeScriptValue Sc_Game_GetViewFrame(const RuntimeScriptValue *params, int32_ // const char* (const char *msg) RuntimeScriptValue Sc_Game_InputBox(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Game_InputBox, const char); + API_CONST_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Game_InputBox, const char); } // int (const char *newFolder) @@ -2043,7 +2043,7 @@ RuntimeScriptValue Sc_Game_GetDialogCount(const RuntimeScriptValue *params, int3 // const char *() RuntimeScriptValue Sc_Game_GetFileName(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetFileName); + API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Game_GetFileName); } // int () @@ -2053,12 +2053,12 @@ RuntimeScriptValue Sc_Game_GetFontCount(const RuntimeScriptValue *params, int32_ // const char* (int index) RuntimeScriptValue Sc_Game_GetGlobalMessages(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalMessages); + API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalMessages); } // const char* (int index) RuntimeScriptValue Sc_Game_GetGlobalStrings(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalStrings); + API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalStrings); } // void (int index, char *newval); @@ -2108,7 +2108,7 @@ RuntimeScriptValue Sc_Game_GetMouseCursorCount(const RuntimeScriptValue *params, // const char *() RuntimeScriptValue Sc_Game_GetName(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetName); + API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Game_GetName); } // void (const char *newName) @@ -2163,7 +2163,7 @@ RuntimeScriptValue Sc_Game_SetTextReadingSpeed(const RuntimeScriptValue *params, // const char* () RuntimeScriptValue Sc_Game_GetTranslationFilename(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ(const char, myScriptStringImpl, Game_GetTranslationFilename); + API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Game_GetTranslationFilename); } // int () diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp index 49d411b5e8ec..20fd5507a484 100644 --- a/engines/ags/engine/ac/global_api.cpp +++ b/engines/ags/engine/ac/global_api.cpp @@ -691,7 +691,7 @@ RuntimeScriptValue Sc_sc_GetTime(const RuntimeScriptValue *params, int32_t param // char * (const char *text) RuntimeScriptValue Sc_get_translation(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_POBJ(char, myScriptStringImpl, get_translation, const char); + API_CONST_SCALL_OBJ_POBJ(const char, myScriptStringImpl, get_translation, const char); } // int (char* buffer) diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp index 09e4948d3303..02f918915862 100644 --- a/engines/ags/engine/ac/hotspot.cpp +++ b/engines/ags/engine/ac/hotspot.cpp @@ -166,7 +166,7 @@ RuntimeScriptValue Sc_Hotspot_GetPropertyText(void *self, const RuntimeScriptVal // const char* (ScriptHotspot *hss, const char *property) RuntimeScriptValue Sc_Hotspot_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_POBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetTextProperty, const char); + API_CONST_OBJCALL_OBJ_POBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetTextProperty, const char); } RuntimeScriptValue Sc_Hotspot_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { @@ -203,7 +203,7 @@ RuntimeScriptValue Sc_Hotspot_GetID(void *self, const RuntimeScriptValue *params // const char* (ScriptHotspot *hss) RuntimeScriptValue Sc_Hotspot_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetName_New); + API_CONST_OBJCALL_OBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetName_New); } // int (ScriptHotspot *hss) diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp index a9b45c23e66d..8701a874d2ab 100644 --- a/engines/ags/engine/ac/inventoryitem.cpp +++ b/engines/ags/engine/ac/inventoryitem.cpp @@ -160,7 +160,7 @@ RuntimeScriptValue Sc_InventoryItem_GetPropertyText(void *self, const RuntimeScr // const char* (ScriptInvItem *scii, const char *property) RuntimeScriptValue Sc_InventoryItem_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_POBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetTextProperty, const char); + API_CONST_OBJCALL_OBJ_POBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetTextProperty, const char); } RuntimeScriptValue Sc_InventoryItem_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { @@ -208,7 +208,7 @@ RuntimeScriptValue Sc_InventoryItem_GetID(void *self, const RuntimeScriptValue * // const char* (ScriptInvItem *invitem) RuntimeScriptValue Sc_InventoryItem_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetName_New); + API_CONST_OBJCALL_OBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetName_New); } diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp index 29249cef0925..92876a318804 100644 --- a/engines/ags/engine/ac/label.cpp +++ b/engines/ags/engine/ac/label.cpp @@ -130,7 +130,7 @@ RuntimeScriptValue Sc_Label_SetFont(void *self, const RuntimeScriptValue *params // const char* (GUILabel *labl) RuntimeScriptValue Sc_Label_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(GUILabel, const char, myScriptStringImpl, Label_GetText_New); + API_CONST_OBJCALL_OBJ(GUILabel, const char, myScriptStringImpl, Label_GetText_New); } // int (GUILabel *labl) diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp index baeeab72222e..c24a6a2db458 100644 --- a/engines/ags/engine/ac/listbox.cpp +++ b/engines/ags/engine/ac/listbox.cpp @@ -489,7 +489,7 @@ RuntimeScriptValue Sc_ListBox_GetItemCount(void *self, const RuntimeScriptValue // const char* (GUIListBox *listbox, int index) RuntimeScriptValue Sc_ListBox_GetItems(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_PINT(GUIListBox, const char, myScriptStringImpl, ListBox_GetItems); + API_CONST_OBJCALL_OBJ_PINT(GUIListBox, const char, myScriptStringImpl, ListBox_GetItems); } // int (GUIListBox *listbox) diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp index 58b52be1a14c..64871509e848 100644 --- a/engines/ags/engine/ac/object.cpp +++ b/engines/ags/engine/ac/object.cpp @@ -596,7 +596,7 @@ RuntimeScriptValue Sc_Object_GetPropertyText(void *self, const RuntimeScriptValu //const char* (ScriptObject *objj, const char *property) RuntimeScriptValue Sc_Object_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_POBJ(ScriptObject, const char, myScriptStringImpl, Object_GetTextProperty, const char); + API_CONST_OBJCALL_OBJ_POBJ(ScriptObject, const char, myScriptStringImpl, Object_GetTextProperty, const char); } RuntimeScriptValue Sc_Object_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) { @@ -802,7 +802,7 @@ RuntimeScriptValue Sc_Object_GetMoving(void *self, const RuntimeScriptValue *par // const char* (ScriptObject *objj) RuntimeScriptValue Sc_Object_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(ScriptObject, const char, myScriptStringImpl, Object_GetName_New); + API_CONST_OBJCALL_OBJ(ScriptObject, const char, myScriptStringImpl, Object_GetName_New); } RuntimeScriptValue Sc_Object_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp index 43a3ddc63f21..ec949675ad2a 100644 --- a/engines/ags/engine/ac/parser.cpp +++ b/engines/ags/engine/ac/parser.cpp @@ -320,7 +320,7 @@ RuntimeScriptValue Sc_ParseText(const RuntimeScriptValue *params, int32_t param_ // const char* () RuntimeScriptValue Sc_Parser_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ(const char, myScriptStringImpl, Parser_SaidUnknownWord); + API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Parser_SaidUnknownWord); } // int (char*checkwords) diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index 1cf81d7c5d5e..6fa660d39336 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -1121,7 +1121,7 @@ RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t // const char* (const char *property) RuntimeScriptValue Sc_Room_GetTextProperty(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Room_GetTextProperty, const char); + API_CONST_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Room_GetTextProperty, const char); } RuntimeScriptValue Sc_Room_SetProperty(const RuntimeScriptValue *params, int32_t param_count) { @@ -1155,7 +1155,7 @@ RuntimeScriptValue Sc_Room_GetLeftEdge(const RuntimeScriptValue *params, int32_t // const char* (int index) RuntimeScriptValue Sc_Room_GetMessages(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Room_GetMessages); + API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Room_GetMessages); } // int () diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index b5722d3b1039..421f08cb5474 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -33,6 +33,7 @@ using AGS::Shared::Bitmap; class IRouteFinder { public: + virtual ~IRouteFinder() {} virtual void init_pathfinder() = 0; virtual void shutdown_pathfinder() = 0; virtual void set_wallscreen(Bitmap *wallscreen) = 0; @@ -45,6 +46,8 @@ class IRouteFinder { class AGSRouteFinder : public IRouteFinder { public: + virtual ~AGSRouteFinder() {} + void init_pathfinder() override { AGS::Engine::RouteFinder::init_pathfinder(); } @@ -73,6 +76,8 @@ class AGSRouteFinder : public IRouteFinder { class AGSLegacyRouteFinder : public IRouteFinder { public: + virtual ~AGSLegacyRouteFinder() {} + void init_pathfinder() override { AGS::Engine::RouteFinderLegacy::init_pathfinder(); } diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index 4bf42ca47484..10700dca701b 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -147,7 +147,7 @@ RuntimeScriptValue Sc_Dict_Contains(void *self, const RuntimeScriptValue *params } RuntimeScriptValue Sc_Dict_Get(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, myScriptStringImpl, Dict_Get, const char); + API_CONST_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, myScriptStringImpl, Dict_Get, const char); } RuntimeScriptValue Sc_Dict_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index b33ee59eb438..305629a49797 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -310,12 +310,12 @@ RuntimeScriptValue Sc_String_IsNullOrEmpty(const RuntimeScriptValue *params, int // const char* (const char *thisString, const char *extrabit) RuntimeScriptValue Sc_String_Append(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_POBJ(const char, const char, myScriptStringImpl, String_Append, const char); + API_CONST_OBJCALL_OBJ_POBJ(const char, const char, myScriptStringImpl, String_Append, const char); } // const char* (const char *thisString, char extraOne) RuntimeScriptValue Sc_String_AppendChar(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_AppendChar); + API_CONST_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_AppendChar); } // int (const char *thisString, const char *otherString, bool caseSensitive) @@ -330,7 +330,7 @@ RuntimeScriptValue Sc_StrContains(void *self, const RuntimeScriptValue *params, // const char* (const char *srcString) RuntimeScriptValue Sc_String_Copy(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_Copy); + API_CONST_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_Copy); } // int (const char *thisString, const char *checkForString, bool caseSensitive) @@ -341,22 +341,22 @@ RuntimeScriptValue Sc_String_EndsWith(void *self, const RuntimeScriptValue *para // const char* (const char *texx, ...) RuntimeScriptValue Sc_String_Format(const RuntimeScriptValue *params, int32_t param_count) { API_SCALL_SCRIPT_SPRINTF(String_Format, 1); - return RuntimeScriptValue().SetDynamicObject((void *)CreateNewScriptString(scsf_buffer), &myScriptStringImpl); + return RuntimeScriptValue().SetDynamicObject(const_cast(CreateNewScriptString(scsf_buffer)), &myScriptStringImpl); } // const char* (const char *thisString) RuntimeScriptValue Sc_String_LowerCase(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_LowerCase); + API_CONST_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_LowerCase); } // const char* (const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive) RuntimeScriptValue Sc_String_Replace(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_POBJ2_PBOOL(const char, const char, myScriptStringImpl, String_Replace, const char, const char); + API_CONST_OBJCALL_OBJ_POBJ2_PBOOL(const char, const char, myScriptStringImpl, String_Replace, const char, const char); } // const char* (const char *thisString, int index, char newChar) RuntimeScriptValue Sc_String_ReplaceCharAt(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_ReplaceCharAt); + API_CONST_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_ReplaceCharAt); } // int (const char *thisString, const char *checkForString, bool caseSensitive) @@ -366,17 +366,17 @@ RuntimeScriptValue Sc_String_StartsWith(void *self, const RuntimeScriptValue *pa // const char* (const char *thisString, int index, int length) RuntimeScriptValue Sc_String_Substring(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_Substring); + API_CONST_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_Substring); } // const char* (const char *thisString, int length) RuntimeScriptValue Sc_String_Truncate(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_Truncate); + API_CONST_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_Truncate); } // const char* (const char *thisString) RuntimeScriptValue Sc_String_UpperCase(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_UpperCase); + API_CONST_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_UpperCase); } // FLOAT_RETURN_TYPE (const char *theString); diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index 954d8ff9cd73..02d4c0a2d78e 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -305,7 +305,7 @@ RuntimeScriptValue Sc_System_GetSupportsGammaControl(const RuntimeScriptValue *p // const char *() RuntimeScriptValue Sc_System_GetVersion(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ(const char, myScriptStringImpl, System_GetVersion); + API_CONST_SCALL_OBJ(const char, myScriptStringImpl, System_GetVersion); } // int () @@ -348,7 +348,7 @@ RuntimeScriptValue Sc_System_SetWindowed(const RuntimeScriptValue *params, int32 // const char *() RuntimeScriptValue Sc_System_GetRuntimeInfo(const RuntimeScriptValue *params, int32_t param_count) { - API_SCALL_OBJ(const char, myScriptStringImpl, System_GetRuntimeInfo); + API_CONST_SCALL_OBJ(const char, myScriptStringImpl, System_GetRuntimeInfo); } RuntimeScriptValue Sc_System_GetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) { diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp index 31b35d74cb97..c8cea8558e09 100644 --- a/engines/ags/engine/ac/textbox.cpp +++ b/engines/ags/engine/ac/textbox.cpp @@ -128,7 +128,7 @@ RuntimeScriptValue Sc_TextBox_SetShowBorder(void *self, const RuntimeScriptValue // const char* (GUITextBox *texbox) RuntimeScriptValue Sc_TextBox_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) { - API_OBJCALL_OBJ(GUITextBox, const char *, myScriptStringImpl, TextBox_GetText_New); + API_CONST_OBJCALL_OBJ(GUITextBox, const char, myScriptStringImpl, TextBox_GetText_New); } // int (GUITextBox *guit) diff --git a/engines/ags/engine/script/script_api.h b/engines/ags/engine/script/script_api.h index 6cd64d87a048..15c129c88955 100644 --- a/engines/ags/engine/script/script_api.h +++ b/engines/ags/engine/script/script_api.h @@ -287,10 +287,17 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f #define API_SCALL_OBJ(RET_CLASS, RET_MGR, FUNCTION) \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(), &RET_MGR) +#define API_CONST_SCALL_OBJ(RET_CLASS, RET_MGR, FUNCTION) \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)FUNCTION()), &RET_MGR) + #define API_SCALL_OBJ_PINT(RET_CLASS, RET_MGR, FUNCTION) \ ASSERT_PARAM_COUNT(FUNCTION, 1); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue), &RET_MGR) +#define API_CONST_SCALL_OBJ_PINT(RET_CLASS, RET_MGR, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)FUNCTION(params[0].IValue)), &RET_MGR) + #define API_SCALL_OBJ_POBJ_PINT_PBOOL(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ ASSERT_PARAM_COUNT(FUNCTION, 3); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr, params[1].IValue, params[2].GetAsBool()), &RET_MGR) @@ -299,6 +306,10 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f ASSERT_PARAM_COUNT(FUNCTION, 2); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue), &RET_MGR) +#define API_CONST_SCALL_OBJ_PINT2(RET_CLASS, RET_MGR, FUNCTION) \ + ASSERT_PARAM_COUNT(FUNCTION, 2); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue)), &RET_MGR) + #define API_SCALL_OBJ_PINT3_POBJ(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ ASSERT_PARAM_COUNT(FUNCTION, 4); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION(params[0].IValue, params[1].IValue, params[2].IValue, (P1CLASS*)params[3].Ptr), &RET_MGR) @@ -307,6 +318,10 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f ASSERT_PARAM_COUNT(FUNCTION, 1); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr), &RET_MGR) +#define API_CONST_SCALL_OBJ_POBJ(RET_CLASS, RET_MGR, FUNCTION, P1CLASS) \ + ASSERT_PARAM_COUNT(FUNCTION, 1); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)FUNCTION((P1CLASS*)params[0].Ptr)), &RET_MGR) + #define API_SCALL_OBJAUTO(RET_CLASS, FUNCTION) \ RET_CLASS* ret_obj = FUNCTION(); \ return RuntimeScriptValue().SetDynamicObject(ret_obj, ret_obj) @@ -523,18 +538,34 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ return RuntimeScriptValue().SetDynamicObject((void*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].GetAsBool()), &RET_MGR) +#define API_CONST_OBJCALL_OBJ_POBJ2_PBOOL(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS, P2CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr, (P2CLASS*)params[1].Ptr, params[2].GetAsBool())), &RET_MGR) + #define API_OBJCALL_OBJ(CLASS, RET_CLASS, RET_MGR, METHOD) \ ASSERT_SELF(METHOD); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self), &RET_MGR) +#define API_CONST_OBJCALL_OBJ(CLASS, RET_CLASS, RET_MGR, METHOD) \ + ASSERT_SELF(METHOD); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)METHOD((CLASS*)self)), &RET_MGR) + #define API_OBJCALL_OBJ_PINT(CLASS, RET_CLASS, RET_MGR, METHOD) \ ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue), &RET_MGR) +#define API_CONST_OBJCALL_OBJ_PINT(CLASS, RET_CLASS, RET_MGR, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue)), &RET_MGR) + #define API_OBJCALL_OBJ_PINT2(CLASS, RET_CLASS, RET_MGR, METHOD) \ ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue), &RET_MGR) +#define API_CONST_OBJCALL_OBJ_PINT2(CLASS, RET_CLASS, RET_MGR, METHOD) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 2); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue)), &RET_MGR) + #define API_OBJCALL_OBJ_PINT3(CLASS, RET_CLASS, RET_MGR, METHOD) \ ASSERT_OBJ_PARAM_COUNT(METHOD, 3); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, params[0].IValue, params[1].IValue, params[2].IValue), &RET_MGR) @@ -543,6 +574,10 @@ inline const char *ScriptVSprintf(char *buffer, size_t buf_length, const char *f ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ return RuntimeScriptValue().SetDynamicObject((void*)(RET_CLASS*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr), &RET_MGR) +#define API_CONST_OBJCALL_OBJ_POBJ(CLASS, RET_CLASS, RET_MGR, METHOD, P1CLASS) \ + ASSERT_OBJ_PARAM_COUNT(METHOD, 1); \ + return RuntimeScriptValue().SetDynamicObject(const_cast((const void *)(RET_CLASS*)METHOD((CLASS*)self, (P1CLASS*)params[0].Ptr)), &RET_MGR) + #define API_OBJCALL_OBJAUTO(CLASS, RET_CLASS, METHOD) \ ASSERT_SELF(METHOD); \ RET_CLASS* ret_obj = METHOD((CLASS*)self); \ From 705dc17a056ea9bd747925cf40c3fd4a18517eca Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 29 Nov 2020 16:44:56 -0800 Subject: [PATCH 066/215] AGS: Get game filename from detection entry --- engines/ags/ags.cpp | 22 ++++++++++------------ engines/ags/engine/main/main.h | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index ad075c586542..79f95a127860 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -61,7 +61,7 @@ using namespace Engine; String appDirectory; // Needed for library loading String cmdGameDataPath; -char **global_argv = nullptr; +const char **global_argv = nullptr; int global_argc = 0; extern GameSetup usetup; @@ -135,7 +135,7 @@ void main_create_platform_driver() { platform = AGSPlatformDriver::GetDriver(); } -void main_init(int argc, char *argv[]) { +void main_init(int argc, const char *argv[]) { EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); SavedgameLowestBackwardCompatVersion = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); @@ -159,7 +159,7 @@ void main_print_help() { // No implementation } -static int main_process_cmdline(ConfigTree &cfg, int argc, char *argv[]) { +static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { int datafile_argv = 0; for (int ee = 1; ee < argc; ++ee) { const char *arg = argv[ee]; @@ -267,7 +267,7 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, char *argv[]) { return 0; } -void main_set_gamedir(int argc, char *argv[]) { +void main_set_gamedir(int argc, const char *argv[]) { appDirectory = Path::GetDirectoryPath(GetPathFromCmdArg(0)); if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) { @@ -339,16 +339,14 @@ uint32 AGSEngine::getFeatures() const { } Common::Error AGSEngine::run() { - char exeName[16], gameName[16]; - strcpy(exeName, "scummvm.exe"); - strcpy(gameName, "bc.exe"); - int argc = 3; - char *argv[] = { exeName, gameName }; + const char *filename = _gameDescription->desc.filesDescriptions[0].fileName; + const char *ARGV[] = { nullptr, filename }; + const int ARGC = 2; #ifdef AGS_RUN_TESTS Test_DoAllTests(); #endif - AGS3::main_init(argc, argv); + AGS3::main_init(ARGC, ARGV); #if AGS_PLATFORM_OS_WINDOWS setup_malloc_handling(); @@ -356,7 +354,7 @@ Common::Error AGSEngine::run() { AGS3::debug_flags = 0; AGS3::ConfigTree startup_opts; - int res = AGS3::main_process_cmdline(startup_opts, argc, argv); + int res = AGS3::main_process_cmdline(startup_opts, ARGC, ARGV); if (res != 0) return Common::kUnknownError; @@ -375,7 +373,7 @@ Common::Error AGSEngine::run() { AGS3::init_debug(startup_opts, AGS3::justTellInfo); AGS3::Debug::Printf("%s", AGS3::get_engine_string().GetNullableCStr()); - AGS3::main_set_gamedir(argc, argv); + AGS3::main_set_gamedir(ARGC, ARGV); // Update shell associations and exit if (AGS3::debug_flags & DBG_REGONLY) diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index d0efac642533..235c6e7c1458 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -37,7 +37,7 @@ extern AGS::Shared::Version SavedgameLowestForwardCompatVersion; //============================================================================= -extern char **global_argv; +extern const char **global_argv; // Location of the engine executable extern AGS::Shared::String appDirectory; From 596147f256b8c4ec245c232b383175444a2a8e27 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 29 Nov 2020 17:44:37 -0800 Subject: [PATCH 067/215] AGS: Add tests as an optional sub-engine --- engines/ags/ags.cpp | 8 +- engines/ags/configure.engine | 3 +- engines/ags/lib/std/map.h | 14 + engines/ags/module.mk | 12 + engines/ags/tests/test_all.cpp | 41 +++ engines/ags/tests/test_all.h | 48 +++ engines/ags/tests/test_file.cpp | 196 +++++++++++ engines/ags/tests/test_gfx.cpp | 47 +++ engines/ags/tests/test_inifile.cpp | 304 +++++++++++++++++ engines/ags/tests/test_math.cpp | 69 ++++ engines/ags/tests/test_memory.cpp | 90 +++++ engines/ags/tests/test_sprintf.cpp | 133 ++++++++ engines/ags/tests/test_string.cpp | 506 +++++++++++++++++++++++++++++ engines/ags/tests/test_version.cpp | 117 +++++++ 14 files changed, 1585 insertions(+), 3 deletions(-) create mode 100644 engines/ags/tests/test_all.cpp create mode 100644 engines/ags/tests/test_all.h create mode 100644 engines/ags/tests/test_file.cpp create mode 100644 engines/ags/tests/test_gfx.cpp create mode 100644 engines/ags/tests/test_inifile.cpp create mode 100644 engines/ags/tests/test_math.cpp create mode 100644 engines/ags/tests/test_memory.cpp create mode 100644 engines/ags/tests/test_sprintf.cpp create mode 100644 engines/ags/tests/test_string.cpp create mode 100644 engines/ags/tests/test_version.cpp diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 79f95a127860..83b599dfd76a 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -49,6 +49,9 @@ #include "ags/shared/util/directory.h" #include "ags/shared/util/path.h" +#ifdef ENABLE_AGS_TESTS +#include "ags/tests/test_all.h" +#endif namespace AGS3 { @@ -343,8 +346,9 @@ Common::Error AGSEngine::run() { const char *ARGV[] = { nullptr, filename }; const int ARGC = 2; -#ifdef AGS_RUN_TESTS - Test_DoAllTests(); +#ifdef ENABLE_AGS_TESTS + AGS3::Test_DoAllTests(); + return Common::kNoError; #endif AGS3::main_init(ARGC, ARGV); diff --git a/engines/ags/configure.engine b/engines/ags/configure.engine index 55cba93bb428..0fb88d9de149 100644 --- a/engines/ags/configure.engine +++ b/engines/ags/configure.engine @@ -1,3 +1,4 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine ags "Adventure Game Studio" no "" "" "cxx11" +add_engine ags "Adventure Game Studio" no "ags_tests" "" "cxx11" +add_engine ags_tests "AGS Tests" no "" "" "" diff --git a/engines/ags/lib/std/map.h b/engines/ags/lib/std/map.h index 3d596dc0c763..a5f080952bd6 100644 --- a/engines/ags/lib/std/map.h +++ b/engines/ags/lib/std/map.h @@ -50,6 +50,20 @@ class map : public Common::HashMap { return it; } + + /** + * Checks if the maps have identical contents + */ + bool operator==(const map &rhs) { + if (this->size() != rhs.size()) + return false; + for (iterator it = this->begin(); it != this->end(); ++it) { + if (!(it->_value == rhs[it->_key])) + return false; + } + + return true; + } }; template, diff --git a/engines/ags/module.mk b/engines/ags/module.mk index af96975957c9..07c1145c9c1b 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -308,6 +308,18 @@ MODULE_OBJS = \ engine/script/script_runtime.o \ engine/script/systemimports.o +ifdef ENABLE_AGS_TESTS +MODULE_OBJS += \ + tests/test_all.o \ + tests/test_file.o \ + tests/test_gfx.o \ + tests/test_inifile.o \ + tests/test_math.o \ + tests/test_memory.o \ + tests/test_sprintf.o \ + tests/test_string.o \ + tests/test_version.o +endif # This module can be built as a plugin ifeq ($(ENABLE_AGS), DYNAMIC_PLUGIN) diff --git a/engines/ags/tests/test_all.cpp b/engines/ags/tests/test_all.cpp new file mode 100644 index 000000000000..08cfce5c48c0 --- /dev/null +++ b/engines/ags/tests/test_all.cpp @@ -0,0 +1,41 @@ +/* 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 "ags/shared/core/platform.h" +#include "ags/tests/test_all.h" + +namespace AGS3 { + +void Test_DoAllTests() { + Test_Math(); + Test_Memory(); + Test_Path(); + Test_ScriptSprintf(); + Test_String(); + Test_Version(); + Test_File(); + Test_IniFile(); + + Test_Gfx(); +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_all.h b/engines/ags/tests/test_all.h new file mode 100644 index 000000000000..f05f3a5c7a8d --- /dev/null +++ b/engines/ags/tests/test_all.h @@ -0,0 +1,48 @@ +/* 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 "ags/shared/core/platform.h" + +namespace AGS3 { + +extern void Test_DoAllTests(); + +// Math tests +extern void Test_Math(); + +// File tests +extern void Test_File(); +extern void Test_IniFile(); + +// Graphics tests +extern void Test_Gfx(); + +// Memory / bit-byte operations +extern void Test_Memory(); + +// String tests +extern void Test_ScriptSprintf(); +extern void Test_String(); +extern void Test_Path(); +extern void Test_Version(); + +} // namespace AGS3 diff --git a/engines/ags/tests/test_file.cpp b/engines/ags/tests/test_file.cpp new file mode 100644 index 000000000000..b3ed8f0b5904 --- /dev/null +++ b/engines/ags/tests/test_file.cpp @@ -0,0 +1,196 @@ +/* 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 "ags/shared/core/platform.h" +#include +#include "ags/shared/debugging/assert.h" +#include "ags/shared/util/alignedstream.h" +#include "ags/shared/util/file.h" + +namespace AGS3 { + +using namespace AGS::Shared; + +struct TTrickyAlignedData { + char a; + int b; + int c; + short d[3]; + int e; + char f[17]; + int g[4]; + short h[13]; + char i[3]; + short j; + int k; + short l; + short m; + int n; + int64_t i64a; + char o; + int64_t i64b; + short p; + int64_t i64c; + short q; + short r; + int64_t i64d; + char final; +}; + +void Test_File() { + //----------------------------------------------------- + // Operations + Stream *out = File::OpenFile("test.tmp", AGS::Shared::kFile_CreateAlways, AGS::Shared::kFile_Write); + + out->WriteInt16(10); + out->WriteInt64(-20202); + String::WriteString("test.tmp", out); + String very_long_string; + very_long_string.FillString('a', 10000); + very_long_string.Write(out); + + TTrickyAlignedData tricky_data_out; + memset(&tricky_data_out, 0xAA, sizeof(tricky_data_out)); + { + tricky_data_out.a = 11; + tricky_data_out.b = 12; + tricky_data_out.c = 13; + tricky_data_out.d[0] = 14; + tricky_data_out.d[1] = 15; + tricky_data_out.d[2] = 16; + tricky_data_out.e = 17; + memset(tricky_data_out.f, 0, 17); + tricky_data_out.g[0] = 18; + tricky_data_out.g[1] = 19; + tricky_data_out.g[2] = 20; + tricky_data_out.g[3] = 21; + memset(tricky_data_out.h, 0, 13 * sizeof(short)); + tricky_data_out.i[0] = 22; + tricky_data_out.i[1] = 23; + tricky_data_out.i[2] = 24; + tricky_data_out.j = 25; + tricky_data_out.k = 26; + tricky_data_out.l = 27; + tricky_data_out.m = 28; + tricky_data_out.n = 29; + tricky_data_out.i64a = 30; + tricky_data_out.o = 31; + tricky_data_out.i64b = 32; + tricky_data_out.p = 33; + tricky_data_out.i64c = 34; + tricky_data_out.q = 35; + tricky_data_out.r = 36; + tricky_data_out.i64d = 37; + tricky_data_out.final = 38; +#if defined (TEST_BIGENDIAN) + TTrickyAlignedData bigend_data = tricky_data_out; + bigend_data.b = BBOp::SwapBytesInt32(bigend_data.b); + bigend_data.c = BBOp::SwapBytesInt32(bigend_data.c); + for (int i = 0; i < 3; ++i) { + bigend_data.d[i] = BBOp::SwapBytesInt16(bigend_data.d[i]); + } + bigend_data.e = BBOp::SwapBytesInt32(bigend_data.e); + for (int i = 0; i < 4; ++i) { + bigend_data.g[i] = BBOp::SwapBytesInt32(bigend_data.g[i]); + } + for (int i = 0; i < 13; ++i) { + bigend_data.h[i] = BBOp::SwapBytesInt16(bigend_data.h[i]); + } + bigend_data.j = BBOp::SwapBytesInt16(bigend_data.j); + bigend_data.k = BBOp::SwapBytesInt32(bigend_data.k); + bigend_data.l = BBOp::SwapBytesInt16(bigend_data.l); + bigend_data.m = BBOp::SwapBytesInt16(bigend_data.m); + bigend_data.n = BBOp::SwapBytesInt32(bigend_data.n); + bigend_data.i64a = BBOp::SwapBytesInt64(bigend_data.i64a); + bigend_data.i64b = BBOp::SwapBytesInt64(bigend_data.i64b); + bigend_data.p = BBOp::SwapBytesInt16(bigend_data.p); + bigend_data.i64c = BBOp::SwapBytesInt64(bigend_data.i64c); + bigend_data.q = BBOp::SwapBytesInt16(bigend_data.q); + bigend_data.r = BBOp::SwapBytesInt16(bigend_data.r); + bigend_data.i64d = BBOp::SwapBytesInt64(bigend_data.i64d); + out->Write(&bigend_data, sizeof(TTrickyAlignedData)); +#else + out->Write(&tricky_data_out, sizeof(TTrickyAlignedData)); +#endif + } + + out->WriteInt32(20); + + delete out; + + //------------------------------------------------------------------------- + + Stream *in = File::OpenFile("test.tmp", AGS::Shared::kFile_Open, AGS::Shared::kFile_Read); + + int16_t int16val = in->ReadInt16(); + int64_t int64val = in->ReadInt64(); + String str1 = String::FromStream(in); + String str2 = String::FromStream(in); + + TTrickyAlignedData tricky_data_in; + memset(&tricky_data_in, 0xAA, sizeof(tricky_data_in)); + { + AlignedStream as(in, AGS::Shared::kAligned_Read); + tricky_data_in.a = as.ReadInt8(); + tricky_data_in.b = as.ReadInt32(); + tricky_data_in.c = as.ReadInt32(); + as.ReadArrayOfInt16(tricky_data_in.d, 3); + tricky_data_in.e = as.ReadInt32(); + as.Read(tricky_data_in.f, 17); + as.ReadArrayOfInt32(tricky_data_in.g, 4); + as.ReadArrayOfInt16(tricky_data_in.h, 13); + as.Read(tricky_data_in.i, 3); + tricky_data_in.j = as.ReadInt16(); + tricky_data_in.k = as.ReadInt32(); + tricky_data_in.l = as.ReadInt16(); + tricky_data_in.m = as.ReadInt16(); + tricky_data_in.n = as.ReadInt32(); + tricky_data_in.i64a = as.ReadInt64(); + tricky_data_in.o = as.ReadInt8(); + tricky_data_in.i64b = as.ReadInt64(); + tricky_data_in.p = as.ReadInt16(); + tricky_data_in.i64c = as.ReadInt64(); + tricky_data_in.q = as.ReadInt16(); + tricky_data_in.r = as.ReadInt16(); + tricky_data_in.i64d = as.ReadInt64(); + tricky_data_in.final = as.ReadInt8(); + } + + int32_t int32val = in->ReadInt32(); + + delete in; + + File::DeleteFile("test.tmp"); + + //----------------------------------------------------- + // Assertions + assert(int16val == 10); + assert(int64val == -20202); + assert(strcmp(str1, "test.tmp") == 0); + assert(strcmp(str2, very_long_string) == 0); + assert(memcmp(&tricky_data_in, &tricky_data_out, sizeof(TTrickyAlignedData)) == 0); + assert(int32val == 20); + + assert(!File::TestReadFile("test.tmp")); +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_gfx.cpp b/engines/ags/tests/test_gfx.cpp new file mode 100644 index 000000000000..04072ae09d97 --- /dev/null +++ b/engines/ags/tests/test_gfx.cpp @@ -0,0 +1,47 @@ +/* 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 "common/scummsys.h" +#include "ags/shared/core/platform.h" +#include "ags/shared/gfx/gfx_def.h" +#include "ags/shared/debugging/assert.h" + +namespace AGS3 { + +namespace GfxDef = AGS::Shared::GfxDef; + +void Test_Gfx() { + // Test that every transparency which is a multiple of 10 is converted + // forth and back without loosing precision + const size_t arr_sz = 11; + const int trans100[arr_sz] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; + int trans255[arr_sz] = { 0 }; + int trans100_back[arr_sz] = { 0 }; + + for (int i = 0; i < arr_sz; ++i) { + trans255[i] = GfxDef::Trans100ToLegacyTrans255(trans100[i]); + trans100_back[i] = GfxDef::LegacyTrans255ToTrans100(trans255[i]); + assert(trans100[i] == trans100_back[i]); + } +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_inifile.cpp b/engines/ags/tests/test_inifile.cpp new file mode 100644 index 000000000000..75781c427a3e --- /dev/null +++ b/engines/ags/tests/test_inifile.cpp @@ -0,0 +1,304 @@ +/* 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 "ags/shared/core/platform.h" +#include "ags/lib/std/algorithm.h" +#include "ags/shared/debugging/assert.h" +#include "ags/shared/util/file.h" +#include "ags/shared/util/ini_util.h" +#include "ags/shared/util/inifile.h" +#include "ags/shared/util/stream.h" + +namespace AGS3 { + +using namespace AGS::Shared; + +#if AGS_PLATFORM_OS_WINDOWS +#define ENDL "\r\n" +#else +#define ENDL "\n" +#endif + +const char *IniFileText = "" +"global_item=global_value" ENDL +"[section1]" ENDL +"item1" ENDL +"//this is comment" ENDL +"item2=" ENDL +"item3=value" ENDL +"item4=another value" ENDL +"[this_section_should_be_deleted]" ENDL +"item1=value1" ENDL +"item2=value2" ENDL +";this is comment" ENDL +"[section3]" ENDL +"item_to_be_deleted=value" ENDL +"item_to_be_kept=another value" ENDL +" [ section4 ] " ENDL +" item1 = value " ENDL; + +const char *IniFileText2 = "" +"global_item=global_value" ENDL +"[section1]" ENDL +"item1=value1" ENDL +"//this is comment" ENDL +"item2=value2" ENDL +"item3=value3" ENDL +"new_item=new_value" ENDL +"[section3]" ENDL +"item_to_be_kept=another value" ENDL +" [ section4 ] " ENDL +"new_item1=new_value1" ENDL +" item1 = value " ENDL +"new_item2=new_value2" ENDL +"[section5]" ENDL +"item5_1=value5_1" ENDL +"item5_2=value5_2" ENDL +"item5_3=value5_3" ENDL; + + +void Test_IniFile() { + Stream *fs = File::CreateFile("test.ini"); + fs->Write(IniFileText, strlen(IniFileText)); + delete fs; + + IniFile ini; + fs = File::OpenFileRead("test.ini"); + ini.Read(fs); + delete fs; + + // there are explicit sections and 1 implicit global one + const int section_count = 5; + // Test reading from the custom ini file + { + assert(ini.GetSectionCount() == section_count); + IniFile::ConstSectionIterator sec = ini.CBegin(); + + assert(sec->GetItemCount() == 1); + IniFile::ConstItemIterator item = sec->CBegin(); + assert(item->GetKey() == "global_item"); + assert(item->GetValue() == "global_value"); + + ++sec; + assert(sec->GetName() == "section1"); + assert(sec->GetItemCount() == 5); + item = sec->CBegin(); + assert(item->GetKey() == "item1"); + assert(item->GetValue() == ""); + ++item; + assert(item->GetLine() == "//this is comment"); + ++item; + assert(item->GetKey() == "item2"); + assert(item->GetValue() == ""); + ++item; + assert(item->GetKey() == "item3"); + assert(item->GetValue() == "value"); + ++item; + assert(item->GetKey() == "item4"); + assert(item->GetValue() == "another value"); + + ++sec; + assert(sec->GetName() == "this_section_should_be_deleted"); + assert(sec->GetItemCount() == 3); + item = sec->CBegin(); + assert(item->GetKey() == "item1"); + assert(item->GetValue() == "value1"); + ++item; + assert(item->GetKey() == "item2"); + assert(item->GetValue() == "value2"); + ++item; + assert(item->GetLine() == ";this is comment"); + + ++sec; + assert(sec->GetName() == "section3"); + assert(sec->GetItemCount() == 2); + item = sec->CBegin(); + assert(item->GetKey() == "item_to_be_deleted"); + assert(item->GetValue() == "value"); + ++item; + assert(item->GetKey() == "item_to_be_kept"); + assert(item->GetValue() == "another value"); + + ++sec; + assert(sec->GetName() == "section4"); + assert(sec->GetItemCount() == 1); + item = sec->CBegin(); + assert(item->GetKey() == "item1"); + assert(item->GetValue() == "value"); + } + + // Test altering INI data and saving to file + { + // Modiying item values + IniFile::SectionIterator sec = ini.Begin(); + ++sec; + IniFile::ItemIterator item = sec->Begin(); + item->SetValue("value1"); + ++item; ++item; + item->SetValue("value2"); + ++item; + item->SetValue("value3"); + ++item; + item->SetKey("new_item"); + item->SetValue("new_value"); + + // Removing a section + sec = ini.Begin(); ++sec; ++sec; + ini.RemoveSection(sec); + assert(ini.GetSectionCount() == section_count - 1); + + // Removing an item + sec = ini.Begin(); ++sec; ++sec; + assert(sec->GetName() == "section3"); + item = sec->Begin(); + assert(item->GetKey() == "item_to_be_deleted"); + sec->EraseItem(item); + + // Inserting new items + ++sec; + assert(sec->GetName() == "section4"); + ini.InsertItem(sec, sec->Begin(), "new_item1", "new_value1"); + ini.InsertItem(sec, sec->End(), "new_item2", "new_value2"); + + // Append new section + sec = ini.InsertSection(ini.End(), "section5"); + ini.InsertItem(sec, sec->End(), "item5_1", "value5_1"); + ini.InsertItem(sec, sec->End(), "item5_2", "value5_2"); + ini.InsertItem(sec, sec->End(), "item5_3", "value5_3"); + + fs = File::CreateFile("test.ini"); + ini.Write(fs); + delete fs; + + fs = File::OpenFileRead("test.ini"); + String ini_content; + ini_content.ReadCount(fs, static_cast(fs->GetLength())); + + assert(ini_content == IniFileText2); + } + + // Test creating KeyValueTree from existing ini file + { + ConfigTree tree; + IniUtil::Read("test.ini", tree); + + assert(tree.size() == 5); + assert(tree.find("") != tree.end()); // global section + assert(tree.find("section1") != tree.end()); + assert(tree.find("section3") != tree.end()); + assert(tree.find("section4") != tree.end()); + assert(tree.find("section5") != tree.end()); + StringOrderMap &sub_tree = tree[""]; + assert(sub_tree.size() == 1); + assert(sub_tree.find("global_item") != sub_tree.end()); + assert(sub_tree["global_item"] == "global_value"); + sub_tree = tree["section1"]; + assert(sub_tree.size() == 4); + assert(sub_tree.find("item1") != sub_tree.end()); + assert(sub_tree.find("item2") != sub_tree.end()); + assert(sub_tree.find("item3") != sub_tree.end()); + assert(sub_tree.find("new_item") != sub_tree.end()); + assert(sub_tree["item1"] == "value1"); + assert(sub_tree["item2"] == "value2"); + assert(sub_tree["item3"] == "value3"); + assert(sub_tree["new_item"] == "new_value"); + sub_tree = tree["section3"]; + assert(sub_tree.size() == 1); + assert(sub_tree.find("item_to_be_kept") != sub_tree.end()); + assert(sub_tree["item_to_be_kept"] == "another value"); + sub_tree = tree["section4"]; + assert(sub_tree.size() == 3); + assert(sub_tree.find("new_item1") != sub_tree.end()); + assert(sub_tree.find("item1") != sub_tree.end()); + assert(sub_tree.find("new_item2") != sub_tree.end()); + assert(sub_tree["new_item1"] == "new_value1"); + assert(sub_tree["item1"] == "value"); + assert(sub_tree["new_item2"] == "new_value2"); + sub_tree = tree["section5"]; + assert(sub_tree.size() == 3); + assert(sub_tree.find("item5_1") != sub_tree.end()); + assert(sub_tree.find("item5_2") != sub_tree.end()); + assert(sub_tree.find("item5_3") != sub_tree.end()); + assert(sub_tree["item5_1"] == "value5_1"); + assert(sub_tree["item5_2"] == "value5_2"); + assert(sub_tree["item5_3"] == "value5_3"); + } + + // Test self-serialization + ConfigTree tree1; + { + ConfigTree tree2; + + // construct the tree + { + StringOrderMap &audio_tree = tree1["audio"]; + audio_tree["volume"] = "100.0"; + audio_tree["driver"] = "midi"; + StringOrderMap &video_tree = tree1["video"]; + video_tree["gfx_mode"] = "standard mode"; + video_tree["gamma"] = "1.0"; + video_tree["vsync"] = "false"; + } + + IniUtil::Write("test.ini", tree1); + IniUtil::Read("test.ini", tree2); + + // Assert, that tree2 has exactly same items as tree1 + assert(tree1 == tree2); + } + + // Test merging + { + ConfigTree tree3; + ConfigTree tree4; + + // Try merging altered tree into existing file + tree3 = tree1; + { + StringOrderMap &audio_tree = tree3["audio"]; + audio_tree["extra_option1"] = "extra value 1"; + audio_tree["extra_option2"] = "extra value 2"; + audio_tree["extra_option3"] = "extra value 3"; + StringOrderMap &video_tree = tree3["video"]; + video_tree["gfx_mode"] = "alternate mode"; + video_tree["gamma"] = "2.0"; + StringOrderMap &new_tree = tree3["other1"]; + new_tree["item1_1"] = "value1_1"; + new_tree["item1_2"] = "value1_2"; + new_tree["item1_3"] = "value1_3"; + StringOrderMap &new_tree2 = tree3["other2"]; + new_tree2["item2_1"] = "value2_1"; + new_tree2["item2_2"] = "value2_2"; + new_tree2["item2_3"] = "value2_3"; + } + + IniUtil::Merge("test.ini", tree3); + IniUtil::Read("test.ini", tree4); + + // Assert, that tree4 has all the items from tree3 + assert(tree3 == tree4); + } + + File::DeleteFile("test.ini"); +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_math.cpp b/engines/ags/tests/test_math.cpp new file mode 100644 index 000000000000..3d752d03ba9b --- /dev/null +++ b/engines/ags/tests/test_math.cpp @@ -0,0 +1,69 @@ +/* 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 "ags/shared/core/platform.h" +#include "ags/shared/debugging/assert.h" +#include "ags/engine/util/scaling.h" + +namespace AGS3 { + +using namespace AGS::Shared; +using namespace AGS::Engine; + +void Test_Scaling(int src, int dst) { + int x; + AxisScaling sc; + sc.Init(src, dst); + x = sc.ScalePt(0); + assert(x == 0); + x = sc.ScalePt(src); + assert(x == dst); + x = sc.UnScalePt(dst); + assert(x == src); +} + +void Test_Math() { + Test_Scaling(100, 100); + + Test_Scaling(100, 1000); + Test_Scaling(320, 1280); + Test_Scaling(200, 400); + + Test_Scaling(1000, 100); + Test_Scaling(1280, 320); + Test_Scaling(400, 200); + + Test_Scaling(300, 900); + Test_Scaling(100, 700); + Test_Scaling(200, 2200); + + Test_Scaling(900, 300); + Test_Scaling(700, 100); + Test_Scaling(2200, 200); + + for (int i = 250; i < 2000; i += 25) { + Test_Scaling(200, i); + Test_Scaling(i, 200); + } +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_memory.cpp b/engines/ags/tests/test_memory.cpp new file mode 100644 index 000000000000..950978d72434 --- /dev/null +++ b/engines/ags/tests/test_memory.cpp @@ -0,0 +1,90 @@ +/* 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 "ags/shared/core/platform.h" +#include "ags/shared/util/memory.h" +#include "ags/shared/debugging/assert.h" + +namespace AGS3 { + +using namespace AGS::Shared; + +void Test_Memory() { + int16_t i16 = (int16_t)0xABCD; + int32_t i32 = (int32_t)0xABCDEF12; + int64_t i64 = (int64_t)0xABCDEF1234567890; + + assert(BBOp::SwapBytesInt16(i16) == (int16_t)0xCDAB); + assert(BBOp::SwapBytesInt32(i32) == (int32_t)0x12EFCDABu); + assert(BBOp::SwapBytesInt64(i64) == (int64_t)0x9078563412EFCDABul); + +#if defined (BITBYTE_BIG_ENDIAN) + assert(BBOp::Int16FromLE(i16) == (int16_t)0xCDAB); + assert(BBOp::Int32FromLE(i32) == (int32_t)0x12EFCDABu); + assert(BBOp::Int64FromLE(i64) == (int64_t)0x9078563412EFCDABul); + + assert(BBOp::Int16FromBE(i16) == (int16_t)0xABCD); + assert(BBOp::Int32FromBE(i32) == (int32_t)0xABCDEF12); + assert(BBOp::Int64FromBE(i64) == (int64_t)0xABCDEF1234567890); +#else + assert(BBOp::Int16FromLE(i16) == (int16_t)0xABCD); + assert(BBOp::Int32FromLE(i32) == (int32_t)0xABCDEF12); + assert(BBOp::Int64FromLE(i64) == (int64_t)0xABCDEF1234567890); + + assert(BBOp::Int16FromBE(i16) == (int16_t)0xCDAB); + assert(BBOp::Int32FromBE(i32) == (int32_t)0x12EFCDABu); + assert(BBOp::Int64FromBE(i64) == (int64_t)0x9078563412EFCDABul); +#endif + + int16_t dst_i16 = (int16_t)0xABCD; + int32_t dst_i32 = (int32_t)0xABCDEF12; + int64_t dst_i64 = (int64_t)0xABCDEF1234567890; + void *p_i16 = &dst_i16; + void *p_i32 = &dst_i32; + void *p_i64 = &dst_i64; + +#if defined (TEST_BIGENDIAN) + dst_i16 = BBOp::SwapBytesInt16(dst_i16); + dst_i32 = BBOp::SwapBytesInt32(dst_i32); + dst_i64 = BBOp::SwapBytesInt64(dst_i64); +#endif + + assert(Memory::ReadInt16(p_i16) == (int16_t)0xABCD); + assert(Memory::ReadInt32(p_i32) == (int32_t)0xABCDEF12); + assert(Memory::ReadInt64(p_i64) == (int64_t)0xABCDEF1234567890); + + Memory::WriteInt16(p_i16, (int16_t)0xCDAB); + Memory::WriteInt32(p_i32, (int32_t)0x12EFCDAB); + Memory::WriteInt64(p_i64, (int64_t)0x9078563412EFCDAB); + +#if defined (TEST_BIGENDIAN) + dst_i16 = BBOp::SwapBytesInt16(dst_i16); + dst_i32 = BBOp::SwapBytesInt32(dst_i32); + dst_i64 = BBOp::SwapBytesInt64(dst_i64); +#endif + + assert(dst_i16 == (int16_t)0xCDAB); + assert(dst_i32 == (int32_t)0x12EFCDAB); + assert(dst_i64 == (int64_t)0x9078563412EFCDAB); +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_sprintf.cpp b/engines/ags/tests/test_sprintf.cpp new file mode 100644 index 000000000000..5ad2fb80a88b --- /dev/null +++ b/engines/ags/tests/test_sprintf.cpp @@ -0,0 +1,133 @@ +/* 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 "ags/shared/core/platform.h" +#include +#include "ags/shared/ac/game_version.h" +#include "ags/shared/debugging/assert.h" +#include "ags/engine/script/script_api.h" +#include "ags/engine/script/runtimescriptvalue.h" + +namespace AGS3 { + +const char *ScriptVSprintf__(char *buffer, size_t buf_length, const char *format, ...) { + va_list args; + va_start(args, format); + const char *res_buffer = ScriptVSprintf(buffer, buf_length, format, args); + va_end(args); + return res_buffer; +} + +void Test_ScriptSprintf() { + const int argi = 123; + const float argf = 0.456F; + const char *argcc = "string literal"; + RuntimeScriptValue params[10]; + params[0].SetInt32(argi); + params[1].SetFloat(argf); + params[2].SetStringLiteral(argcc); + + char ScSfBuffer[STD_BUFFER_SIZE]; + // + // Called-from-script variant + // + // Correct format, extra placeholder + const char *result = + ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, + "testing ScriptSprintf:\nThis is int: %10d\nThis is float: %.4f\nThis is string: '%s'\nThis placeholder will be ignored: %d", + params, 3); + assert(strcmp(result, "testing ScriptSprintf:\nThis is int: 123\nThis is float: 0.4560\nThis is string: 'string literal'\nThis placeholder will be ignored: %d") == 0); + // Literal percent sign + result = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, "%d%%", params, 3); + assert(strcmp(result, "123%") == 0); + result = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, "123%%", NULL, 0); + assert(strcmp(result, "123%") == 0); + result = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, "%%5d%%0.5f%%s", params, 3); + assert(strcmp(result, "%5d%0.5f%s") == 0); + + // Invalid format + result = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, "%zzzzzz", params, 3); + assert(strcmp(result, "%zzzzzz") == 0); + result = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, "%12.34%d", params, 3); + assert(strcmp(result, "%12.34123") == 0); + + // Not enough arguments + result = ScriptSprintf(ScSfBuffer, STD_BUFFER_SIZE, "%5d%0.5f%s", params, 0); + assert(strcmp(result, "%5d%0.5f%s") == 0); + + // Not enough buffer space + result = ScriptSprintf(ScSfBuffer, 9, "12345678%d", params, 3); + assert(strcmp(result, "12345678") == 0); + result = ScriptSprintf(ScSfBuffer, 11, "12345678%d", params, 3); + assert(strcmp(result, "1234567812") == 0); + // Not enough buffer space and not enough params + result = ScriptSprintf(ScSfBuffer, 10, "12345678%d", params, 0); + assert(strcmp(result, "12345678%") == 0); + result = ScriptSprintf(ScSfBuffer, 11, "12345678%d", params, 0); + assert(strcmp(result, "12345678%d") == 0); + + // Test null string pointer in backward-compatibility mode + loaded_game_file_version = kGameVersion_312; + params[0].SetStringLiteral(NULL); + result = ScriptSprintf(ScSfBuffer, 10, "A%sB", params, 1); + assert(strcmp(result, "A(null)B") == 0); + loaded_game_file_version = kGameVersion_Undefined; + + // + // Called-from-plugin variant + // Note that since this is variadic function, number of parameters must + // always be equal or higher than number of placeholders in buffer string. + // + // Correct format, matching number of arguments + result = + ScriptVSprintf__(ScSfBuffer, STD_BUFFER_SIZE, + "testing ScriptVSprintf:\nThis is int: %10d\nThis is float: %.4f\nThis is string: '%s'\n", + argi, argf, argcc); + assert(strcmp(result, "testing ScriptVSprintf:\nThis is int: 123\nThis is float: 0.4560\nThis is string: 'string literal'\n") == 0); + // Literal percent sign + result = ScriptVSprintf__(ScSfBuffer, STD_BUFFER_SIZE, "%d%%", argi); + assert(strcmp(result, "123%") == 0); + result = ScriptVSprintf__(ScSfBuffer, STD_BUFFER_SIZE, "123%%"); + assert(strcmp(result, "123%") == 0); + result = ScriptVSprintf__(ScSfBuffer, STD_BUFFER_SIZE, "%%5d%%0.5f%%s"); + assert(strcmp(result, "%5d%0.5f%s") == 0); + + // Invalid format + result = ScriptVSprintf__(ScSfBuffer, STD_BUFFER_SIZE, "%zzzzzz", argi, argf, argcc); + assert(strcmp(result, "%zzzzzz") == 0); + result = ScriptVSprintf__(ScSfBuffer, STD_BUFFER_SIZE, "%12.34%d", argi, argf, argcc); + assert(strcmp(result, "%12.34123") == 0); + + // Not enough buffer space + result = ScriptVSprintf__(ScSfBuffer, 9, "12345678%d", argi, argf, argcc); + assert(strcmp(result, "12345678") == 0); + result = ScriptVSprintf__(ScSfBuffer, 11, "12345678%d", argi, argf, argcc); + assert(strcmp(result, "1234567812") == 0); + + // Test null string pointer in backward-compatibility mode + loaded_game_file_version = kGameVersion_312; + result = ScriptVSprintf__(ScSfBuffer, 10, "A%sB", NULL); + assert(strcmp(result, "A(null)B") == 0); + loaded_game_file_version = kGameVersion_Undefined; +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_string.cpp b/engines/ags/tests/test_string.cpp new file mode 100644 index 000000000000..edaeca6fdce0 --- /dev/null +++ b/engines/ags/tests/test_string.cpp @@ -0,0 +1,506 @@ +/* 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 "ags/shared/core/platform.h" +#include "ags/lib/std/vector.h" +#include "ags/shared/util/path.h" +#include "ags/shared/util/string.h" +#include "ags/shared/debugging/assert.h" + +namespace AGS3 { + +using namespace AGS::Shared; + +void Test_Path() { + assert(Path::IsSameOrSubDir(".", "dir1/") == true); + assert(Path::IsSameOrSubDir(".", "dir1/dir2/dir3/") == true); + assert(Path::IsSameOrSubDir(".", "dir1/../") == true); + assert(Path::IsSameOrSubDir(".", "dir1/dir2/../../") == true); + assert(Path::IsSameOrSubDir(".", "dir1/../dir2/../dir3/") == true); + assert(Path::IsSameOrSubDir(".", "..dir/") == true); + + assert(Path::IsSameOrSubDir(".", "../") == false); + assert(Path::IsSameOrSubDir(".", "../") == false); + assert(Path::IsSameOrSubDir(".", "/dir1/") == false); + assert(Path::IsSameOrSubDir(".", "dir1/../../") == false); + assert(Path::IsSameOrSubDir(".", "dir1/../dir2/../../dir3/") == false); +} + +void Test_String() { + // Test string's internal work + { + String s1 = "abcdefghijklmnop"; + String s2 = s1; + String s3 = s1; + assert(s1.GetRefCount() == 3); + assert(s1.GetBuffer() == s2.GetBuffer()); + assert(s2.GetBuffer() == s3.GetBuffer()); + + size_t cap1 = s1.GetCapacity(); + assert(cap1 == s1.GetLength()); + + s2.TruncateToLeft(10); + assert(cap1 == s2.GetCapacity()); + s3.TruncateToRight(10); + assert(cap1 == s3.GetCapacity()); + assert(s1.GetRefCount() == 1); + + s2.AppendChar('z'); + assert(cap1 == s2.GetCapacity()); + + s3.Append("1234"); + assert(cap1 == s3.GetCapacity()); + s3.Append("1234567890123"); + assert(27 == s3.GetCapacity()); + s3.Append("1234567890123"); + assert(40 == s3.GetCapacity()); + s3.Append("1234567890123"); + assert(60 == s3.GetCapacity()); + + String s4 = "12345678901234567890"; + const char *cstr = s4.GetCStr(); + s4.ClipLeft(10); + assert(s4.GetCStr() == cstr + 10); + s4.Prepend("12345"); + assert(s4.GetCStr() == cstr + 5); + s4.Append("12345"); + assert(s4.GetCStr() == cstr); + assert(strcmp(s4, "12345123456789012345") == 0); + } + + // Test Compare + { + String s1 = "abcdabcdabcd"; + String s2 = "abcdbfghijklmn"; + int cmp1 = s1.Compare(s2); + int cmp2 = s1.CompareLeft("abcd"); + int cmp3 = s1.CompareLeft("abcdxxx"); + int cmp4 = s1.CompareLeft("abcdxxx", 4); + int cmp5 = s1.CompareMid(s2, 2, 4); + int cmp6 = s1.CompareMid(s2, 8, 4); + int cmp7 = s1.CompareMid(s2, 8, 9); + int cmp8 = s1.CompareLeft("abcdabcdabcdxxxx"); + int cmp9 = s1.CompareMid("ab", 8); + int cmp10 = s1.CompareMid("ab", 8, 4); + int cmp11 = s1.CompareRight("abcd"); + int cmp12 = s1.CompareRight("bcdxxx", 3); + int cmp13 = s1.CompareRight("abc", 4); + int cmp14 = s1.CompareRight("abcdxxxx"); + assert(cmp1 < 0); + assert(cmp2 == 0); + assert(cmp3 < 0); + assert(cmp4 == 0); + assert(cmp5 > 0); + assert(cmp6 == 0); + assert(cmp7 < 0); + assert(cmp8 < 0); + assert(cmp9 == 0); + assert(cmp10 > 0); + assert(cmp11 == 0); + assert(cmp12 == 0); + assert(cmp13 > 0); + assert(cmp14 < 0); + } + + // Test FindChar + { + String s1 = "findsomethinginhere"; + String s2 = "stringtofindsomethinginside"; + String s3 = "findsomethinginherex"; + String s4 = "xstringtofindsomethinginside"; + String s5; + size_t find1 = s1.FindChar('o'); + size_t find2 = s2.FindCharReverse('o'); + size_t find3 = s1.FindChar('x'); + size_t find4 = s2.FindCharReverse('x'); + size_t find5 = s3.FindChar('x'); + size_t find6 = s4.FindCharReverse('x'); + size_t find7 = s5.FindChar('x'); + size_t find8 = s5.FindCharReverse('x'); + size_t find9 = s1.FindChar('i', 2); + size_t find10 = s1.FindCharReverse('i', 12); + assert(find1 == 5); + assert(find2 == 13); + assert(find3 == -1); + assert(find4 == -1); + assert(find5 == 19); + assert(find6 == 0); + assert(find7 == -1); + assert(find8 == -1); + assert(find9 == 10); + assert(find10 == 10); + } + + // Test GetAt + { + String s1 = "abcdefghijklmnop"; + String s2; + char c1 = s1.GetAt(0); + char c2 = s1.GetAt(15); + char c3 = s1.GetAt(16); + char c4 = s2.GetAt(0); + assert(c1 == 'a'); + assert(c2 == 'p'); + assert(c3 == 0); + assert(c4 == 0); + } + + // Test ToInt + { + String s1; + String s2 = "100"; + String s3 = "202aaa"; + String s4 = "aaa333"; + int i1 = s1.ToInt(); + int i2 = s2.ToInt(); + int i3 = s3.ToInt(); + int i4 = s4.ToInt(); + assert(i1 == 0); + assert(i2 == 100); + assert(i3 == 202); + assert(i4 == 0); + } + + // Test Left/Right/Mid + { + String s1 = "this is a string to be split"; + String s2 = s1.Left(4); + String s3 = s1.Left(100); + String s4 = s1.Mid(10); + String s5 = s1.Mid(10, 6); + String s6 = s1.Mid(0, 200); + String s7 = s1.Right(5); + String s8 = s1.Right(100); + String s9 = s1.Left(0); + String s10 = s1.Mid((size_t)-1, 0); + String s11 = s1.Right(0); + + assert(strcmp(s2, "this") == 0); + assert(strcmp(s3, "this is a string to be split") == 0); + assert(strcmp(s4, "string to be split") == 0); + assert(strcmp(s5, "string") == 0); + assert(strcmp(s6, "this is a string to be split") == 0); + assert(strcmp(s7, "split") == 0); + assert(strcmp(s8, "this is a string to be split") == 0); + assert(strcmp(s9, "") == 0); + assert(strcmp(s10, "") == 0); + assert(strcmp(s11, "") == 0); + } + + // Test Section + { + String s = "_123_567_"; + size_t from; + size_t to; + assert(s.FindSection('_', 0, 0, true, true, from, to)); + assert(from == 0 && to == 0); + assert(s.FindSection('_', 0, 0, false, true, from, to)); + assert(from == 0 && to == 0); + assert(s.FindSection('_', 0, 0, true, false, from, to)); + assert(from == 0 && to == 1); + assert(s.FindSection('_', 0, 0, false, false, from, to)); + assert(from == 0 && to == 1); + assert(s.FindSection('_', 3, 3, true, true, from, to)); + assert(from == 9 && to == 9); + assert(s.FindSection('_', 3, 3, false, true, from, to)); + assert(from == 8 && to == 9); + assert(s.FindSection('_', 3, 3, true, false, from, to)); + assert(from == 9 && to == 9); + assert(s.FindSection('_', 3, 3, false, false, from, to)); + assert(from == 8 && to == 9); + assert(s.FindSection('_', 1, 1, true, true, from, to)); + assert(from == 1 && to == 4); + assert(s.FindSection('_', 1, 1, false, true, from, to)); + assert(from == 0 && to == 4); + assert(s.FindSection('_', 1, 1, true, false, from, to)); + assert(from == 1 && to == 5); + assert(s.FindSection('_', 1, 1, false, false, from, to)); + assert(from == 0 && to == 5); + } + + // Test Append + { + String s1 = "a string to enlarge - "; + s1.Append("make it bigger"); + assert(strcmp(s1, "a string to enlarge - make it bigger") == 0); + s1.AppendChar('!'); + assert(strcmp(s1, "a string to enlarge - make it bigger!") == 0); + s1.AppendChar(' '); + assert(strcmp(s1, "a string to enlarge - make it bigger! ") == 0); + s1.Append("much much bigger!"); + assert(strcmp(s1, "a string to enlarge - make it bigger! much much bigger!") == 0); + } + + // Test Clip + { + String str1 = "long truncateable string"; + String str2 = str1; + String str3 = str1; + String str4 = str1; + String str5 = str1; + + str1.ClipLeft(4); + str2.ClipRight(6); + str3.ClipMid(5, 12); + str4.ClipMid(5, 0); + str5.ClipMid(0); + assert(strcmp(str1, " truncateable string") == 0); + assert(strcmp(str2, "long truncateable ") == 0); + assert(strcmp(str3, "long string") == 0); + assert(strcmp(str4, "long truncateable string") == 0); + assert(strcmp(str5, "") == 0); + } + + // Test ClipSection + { + String str1 = "C:\\Games\\AGS\\MyNewGame"; + String str2 = str1; + String str3 = str1; + String str4 = str1; + String str5 = str1; + String str6 = str1; + String str7 = str1; + String str8 = str1; + String str9 = str1; + String str10 = str1; + String str11 = str1; + + str1.ClipLeftSection('\\'); + str2.ClipLeftSection('\\', false); + str3.ClipRightSection('\\'); + str4.ClipRightSection('\\', false); + str5.ClipSection('\\', 1, 2); + str6.ClipSection('\\', 1, 2, false, false); + str7.ClipSection('|', 1, 2); + str8.ClipSection('\\', 0, 2); + str9.ClipSection('\\', 1, 3); + str10.ClipSection('\\', 3, 1); + str11.ClipSection('\\', 0, 4); + assert(strcmp(str1, "Games\\AGS\\MyNewGame") == 0); + assert(strcmp(str2, "\\Games\\AGS\\MyNewGame") == 0); + assert(strcmp(str3, "C:\\Games\\AGS") == 0); + assert(strcmp(str4, "C:\\Games\\AGS\\") == 0); + assert(strcmp(str5, "C:MyNewGame") == 0); + assert(strcmp(str6, "C:\\\\MyNewGame") == 0); + assert(strcmp(str7, "C:\\Games\\AGS\\MyNewGame") == 0); + assert(strcmp(str8, "MyNewGame") == 0); + assert(strcmp(str9, "C:") == 0); + assert(strcmp(str10, "C:\\Games\\AGS\\MyNewGame") == 0); + assert(strcmp(str11, "") == 0); + } + + // Test making new string + { + String s1 = "we have some string here"; + assert(strcmp(s1, "we have some string here") == 0); + s1.Empty(); + assert(strcmp(s1, "") == 0); + s1.FillString('z', 10); + assert(strcmp(s1, "zzzzzzzzzz") == 0); + s1.FillString('a', 0); + assert(strcmp(s1, "") == 0); + s1.Format("this %d is %9ld a %x formatted %0.2f string %s", 1, 2, 100, 22.55F, "abcd"); + assert(strcmp(s1, "this 1 is 2 a 64 formatted 22.55 string abcd") == 0); + s1.SetString("some string"); + assert(strcmp(s1, "some string") == 0); + s1.SetString("some string", 4); + assert(strcmp(s1, "some") == 0); + } + + // Test Upper/Lower case + { + String s1 = "ThIs StRiNg Is TwIsTeD"; + String s2 = s1; + String s3 = s1; + s2.MakeLower(); + s3.MakeUpper(); + assert(strcmp(s2, "this string is twisted") == 0); + assert(strcmp(s3, "THIS STRING IS TWISTED") == 0); + } + + // Test Prepend + { + String s1 = "- a string to enlarge"; + s1.Prepend("make it bigger "); + assert(strcmp(s1, "make it bigger - a string to enlarge") == 0); + s1.PrependChar('!'); + assert(strcmp(s1, "!make it bigger - a string to enlarge") == 0); + s1.PrependChar(' '); + assert(strcmp(s1, " !make it bigger - a string to enlarge") == 0); + s1.Prepend("much much bigger!"); + assert(strcmp(s1, "much much bigger! !make it bigger - a string to enlarge") == 0); + } + + // Test ReplaceMid + { + String s1 = "we need to replace PRECISELY THIS PART in this string"; + String s2 = s1; + String new_long = "WITH A NEW TAD LONGER SUBSTRING"; + String new_short = "SMALL STRING"; + s1.ReplaceMid(19, 19, new_long); + assert(strcmp(s1, "we need to replace WITH A NEW TAD LONGER SUBSTRING in this string") == 0); + s2.ReplaceMid(19, 19, new_short); + assert(strcmp(s2, "we need to replace SMALL STRING in this string") == 0); + String s3 = "insert new string here: "; + s3.ReplaceMid(s3.GetLength(), 0, "NEW STRING"); + assert(strcmp(s3, "insert new string here: NEW STRING") == 0); + } + + // Test SetAt + { + String s1 = "strimg wiyh typos"; + s1.SetAt((size_t)-1, 'a'); + assert(strcmp(s1, "strimg wiyh typos") == 0); + s1.SetAt(100, 'a'); + assert(strcmp(s1, "strimg wiyh typos") == 0); + s1.SetAt(1, 0); + assert(strcmp(s1, "strimg wiyh typos") == 0); + s1.SetAt(4, 'n'); + s1.SetAt(9, 't'); + assert(strcmp(s1, "string with typos") == 0); + } + + // Test Trim + { + String str1 = "\t This string is quite long and should be cut a little bit\r\n "; + String str2 = str1; + String str3 = str1; + String str4 = str1; + String str5 = "There's nothing to trim here"; + + str1.TrimLeft(); + str2.TrimRight(); + str3.Trim(); + str4.Trim('|'); + str5.Trim(); + + assert(strcmp(str1, "This string is quite long and should be cut a little bit\r\n ") == 0); + assert(strcmp(str2, "\t This string is quite long and should be cut a little bit") == 0); + assert(strcmp(str3, "This string is quite long and should be cut a little bit") == 0); + assert(strcmp(str4, "\t This string is quite long and should be cut a little bit\r\n ") == 0); + assert(strcmp(str5, "There's nothing to trim here") == 0); + } + + // Test Truncate + { + String str1 = "long truncateable string"; + String str2 = str1; + String str3 = str1; + String str4 = str1; + String str5 = str1; + + str1.TruncateToLeft(4); + str2.TruncateToRight(6); + str3.TruncateToMid(5, 12); + str4.TruncateToMid(5, 0); + str5.TruncateToMid(0); + assert(strcmp(str1, "long") == 0); + assert(strcmp(str2, "string") == 0); + assert(strcmp(str3, "truncateable") == 0); + assert(strcmp(str4, "") == 0); + assert(strcmp(str5, "long truncateable string") == 0); + } + + // Test TruncateToSection + { + String str1 = "C:\\Games\\AGS\\MyNewGame"; + String str2 = str1; + String str3 = str1; + String str4 = str1; + String str5 = str1; + String str6 = str1; + String str7 = str1; + String str8 = str1; + String str9 = str1; + String str10 = str1; + String str11 = str1; + String str12 = str1; + + str1.TruncateToLeftSection('\\'); + str2.TruncateToLeftSection('\\', false); + str3.TruncateToRightSection('\\'); + str4.TruncateToRightSection('\\', false); + str5.TruncateToSection('\\', 1, 2); + str6.TruncateToSection('\\', 1, 2, false, false); + str7.TruncateToSection('|', 1, 3); + str8.TruncateToSection('\\', 0, 2); + str9.TruncateToSection('\\', 1, 3); + str10.TruncateToSection('\\', 3, 1); + str11.TruncateToSection('\\', 3, 3); + str12.TruncateToSection('\\', 3, 3, false, false); + assert(strcmp(str1, "C:") == 0); + assert(strcmp(str2, "C:\\") == 0); + assert(strcmp(str3, "MyNewGame") == 0); + assert(strcmp(str4, "\\MyNewGame") == 0); + assert(strcmp(str5, "Games\\AGS") == 0); + assert(strcmp(str6, "\\Games\\AGS\\") == 0); + assert(strcmp(str7, "") == 0); + assert(strcmp(str8, "C:\\Games\\AGS") == 0); + assert(strcmp(str9, "Games\\AGS\\MyNewGame") == 0); + assert(strcmp(str10, "") == 0); + assert(strcmp(str11, "MyNewGame") == 0); + assert(strcmp(str12, "\\MyNewGame") == 0); + } + + // Test Split + { + String str1 = "C:\\Games\\AGS\\MyNewGame\\"; + std::vector result = str1.Split('\\'); + assert(result.size() == 5); + assert(strcmp(result[0], "C:") == 0); + assert(strcmp(result[1], "Games") == 0); + assert(strcmp(result[2], "AGS") == 0); + assert(strcmp(result[3], "MyNewGame") == 0); + assert(strcmp(result[4], "") == 0); + String str2 = "test,,,test"; + result = str2.Split(','); + assert(result.size() == 4); + assert(strcmp(result[0], "test") == 0); + assert(strcmp(result[1], "") == 0); + assert(strcmp(result[2], "") == 0); + assert(strcmp(result[3], "test") == 0); + String str3 = ",,test,,"; + result = str3.Split(','); + assert(result.size() == 5); + assert(strcmp(result[0], "") == 0); + assert(strcmp(result[1], "") == 0); + assert(strcmp(result[2], "test") == 0); + assert(strcmp(result[3], "") == 0); + assert(strcmp(result[4], "") == 0); + } + + // Test Wrap + { + const char *cstr = "This is a string literal"; + String str1 = String::Wrapper(cstr); + String str2 = str1; + assert(str1.GetCStr() == cstr); + assert(str2.GetCStr() == cstr); + assert(str1.GetRefCount() == 0); + assert(str2.GetRefCount() == 0); + str2.SetAt(0, 'A'); + assert(str2.GetCStr() != cstr); + assert(str2.GetRefCount() == 1); + } +} + +} // namespace AGS3 diff --git a/engines/ags/tests/test_version.cpp b/engines/ags/tests/test_version.cpp new file mode 100644 index 000000000000..81d67aec2c6e --- /dev/null +++ b/engines/ags/tests/test_version.cpp @@ -0,0 +1,117 @@ +/* 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 "ags/shared/core/platform.h" +#include "ags/shared/debugging/assert.h" +#include "ags/shared/util/version.h" + +namespace AGS3 { + +using AGS::Shared::Version; + +void Test_Version() { + // Old version format + Version test_ver1 = Version("2.06.101"); + Version test_ver2 = Version("2.56.654"); + Version test_ver3 = Version("2.7.722"); + Version test_ver4 = Version("2.72.872NMP"); + Version test_ver5 = Version("3.2.0"); + Version test_ver6 = Version("3.21.1115"); + Version test_ver7 = Version("3.21.1115NMP"); + // New version format + Version test_ver8 = Version("3.3.0.1130"); + Version test_ver9 = Version("3.3.0.1130 BETA"); + + assert(test_ver1.Major == 2); + assert(test_ver1.Minor == 0); + assert(test_ver1.Release == 6); + assert(test_ver1.Revision == 101); + assert(strcmp(test_ver1.LongString.GetCStr(), "2.0.6.101") == 0); + assert(strcmp(test_ver1.BackwardCompatibleString.GetCStr(), "2.06.101") == 0); + assert(strcmp(test_ver1.ShortString.GetCStr(), "2.0") == 0); + + assert(test_ver2.Major == 2); + assert(test_ver2.Minor == 5); + assert(test_ver2.Release == 6); + assert(test_ver2.Revision == 654); + assert(strcmp(test_ver2.LongString.GetCStr(), "2.5.6.654") == 0); + assert(strcmp(test_ver2.BackwardCompatibleString.GetCStr(), "2.56.654") == 0); + assert(strcmp(test_ver2.ShortString.GetCStr(), "2.5") == 0); + + assert(test_ver3.Major == 2); + assert(test_ver3.Minor == 7); + assert(test_ver3.Release == 0); + assert(test_ver3.Revision == 722); + assert(strcmp(test_ver3.LongString.GetCStr(), "2.7.0.722") == 0); + assert(strcmp(test_ver3.BackwardCompatibleString.GetCStr(), "2.70.722") == 0); + assert(strcmp(test_ver3.ShortString.GetCStr(), "2.7") == 0); + + assert(test_ver4.Major == 2); + assert(test_ver4.Minor == 7); + assert(test_ver4.Release == 2); + assert(test_ver4.Revision == 872); + assert(strcmp(test_ver4.LongString.GetCStr(), "2.7.2.872 NMP") == 0); + assert(strcmp(test_ver4.BackwardCompatibleString.GetCStr(), "2.72.872NMP") == 0); + assert(strcmp(test_ver4.ShortString.GetCStr(), "2.7") == 0); + + assert(test_ver5.Major == 3); + assert(test_ver5.Minor == 2); + assert(test_ver5.Release == 0); + assert(test_ver5.Revision == 0); + assert(strcmp(test_ver5.LongString.GetCStr(), "3.2.0.0") == 0); + assert(strcmp(test_ver5.BackwardCompatibleString.GetCStr(), "3.20.0") == 0); + assert(strcmp(test_ver5.ShortString.GetCStr(), "3.2") == 0); + + assert(test_ver6.Major == 3); + assert(test_ver6.Minor == 2); + assert(test_ver6.Release == 1); + assert(test_ver6.Revision == 1115); + assert(strcmp(test_ver6.LongString.GetCStr(), "3.2.1.1115") == 0); + assert(strcmp(test_ver6.BackwardCompatibleString.GetCStr(), "3.21.1115") == 0); + assert(strcmp(test_ver6.ShortString.GetCStr(), "3.2") == 0); + + assert(test_ver7.Major == 3); + assert(test_ver7.Minor == 2); + assert(test_ver7.Release == 1); + assert(test_ver7.Revision == 1115); + assert(strcmp(test_ver7.LongString.GetCStr(), "3.2.1.1115 NMP") == 0); + assert(strcmp(test_ver7.BackwardCompatibleString.GetCStr(), "3.21.1115NMP") == 0); + assert(strcmp(test_ver7.ShortString.GetCStr(), "3.2") == 0); + + assert(test_ver8.Major == 3); + assert(test_ver8.Minor == 3); + assert(test_ver8.Release == 0); + assert(test_ver8.Revision == 1130); + assert(strcmp(test_ver8.LongString.GetCStr(), "3.3.0.1130") == 0); + assert(strcmp(test_ver8.BackwardCompatibleString.GetCStr(), "3.30.1130") == 0); + assert(strcmp(test_ver8.ShortString.GetCStr(), "3.3") == 0); + + assert(test_ver9.Major == 3); + assert(test_ver9.Minor == 3); + assert(test_ver9.Release == 0); + assert(test_ver9.Revision == 1130); + assert(strcmp(test_ver9.LongString.GetCStr(), "3.3.0.1130 BETA") == 0); + assert(strcmp(test_ver9.BackwardCompatibleString.GetCStr(), "3.30.1130BETA") == 0); + assert(strcmp(test_ver9.ShortString.GetCStr(), "3.3") == 0); +} + +} // namespace AGS3 From 6ab5c61db5efd0d8fed71e0f13323ed4a7580b3a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 2 Dec 2020 21:32:50 -0800 Subject: [PATCH 068/215] AGS: Remove directory logic from startup --- engines/ags/ags.cpp | 19 +++++-------------- engines/ags/engine/main/engine.cpp | 2 ++ engines/ags/engine/main/main.h | 2 -- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 83b599dfd76a..9b018673b100 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -258,7 +258,7 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { } if (datafile_argv > 0) { - cmdGameDataPath = GetPathFromCmdArg(datafile_argv); + cmdGameDataPath = "./"; } else { // assign standard path for mobile/consoles (defined in their own platform implementation) cmdGameDataPath = psp_game_file_name; @@ -271,8 +271,8 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { } void main_set_gamedir(int argc, const char *argv[]) { - appDirectory = Path::GetDirectoryPath(GetPathFromCmdArg(0)); - + appDirectory = Path::GetDirectoryPath("./"); +#ifdef DEPRECATED if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) { // When launched by double-clicking a save game file, the curdir will // be the save game folder unless we correct it @@ -290,16 +290,7 @@ void main_set_gamedir(int argc, const char *argv[]) { else Debug::Printf(kDbgMsg_Error, "Unable to determine current directory: GetPathInASCII failed.\nArg: %s", cur_dir.GetCStr()); } -} - -String GetPathFromCmdArg(int arg_index) { - if (arg_index < 0 || arg_index >= global_argc) - return ""; - String path = Path::GetCmdLinePathInASCII(global_argv[arg_index], arg_index); - if (!path.IsEmpty()) - return Path::MakeAbsolutePath(path); - Debug::Printf(kDbgMsg_Error, "Unable to determine path: GetCmdLinePathInASCII failed.\nCommand line argument %i: %s", arg_index, global_argv[arg_index]); - return global_argv[arg_index]; +#endif } const char *get_allegro_error() { @@ -343,7 +334,7 @@ uint32 AGSEngine::getFeatures() const { Common::Error AGSEngine::run() { const char *filename = _gameDescription->desc.filesDescriptions[0].fileName; - const char *ARGV[] = { nullptr, filename }; + const char *ARGV[] = { "scummvm.exe", filename }; const int ARGC = 2; #ifdef ENABLE_AGS_TESTS diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index a2cf6c6f3d4c..48a33cd00204 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -270,6 +270,7 @@ bool search_for_game_data_file(String &filename, String &search_path) { } // 3. Look in known locations else { +#ifdef DEPRECATED // 3.1. Look for attachment in the running executable // // this will use argument zero, the executable's name @@ -286,6 +287,7 @@ bool search_for_game_data_file(String &filename, String &search_path) { } } } +#endif } // Finally, store game file's absolute path, or report error diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index 235c6e7c1458..fdc9da0b6a61 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -44,8 +44,6 @@ extern AGS::Shared::String appDirectory; // Game path from the startup options (before reading config) extern AGS::Shared::String cmdGameDataPath; -AGS::Shared::String GetPathFromCmdArg(int arg_index); - // Startup flags, set from parameters to engine extern int force_window; extern int override_start_room; From cd863d037089e663d4991ccd1e348cf338664687 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Dec 2020 13:45:06 -1000 Subject: [PATCH 069/215] AGS: Fix directory/file exists methods --- engines/ags/shared/util/stdio_compat.cpp | 39 ++++++++++++++++++++---- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/engines/ags/shared/util/stdio_compat.cpp b/engines/ags/shared/util/stdio_compat.cpp index e5fe999338de..3a4c32b01875 100644 --- a/engines/ags/shared/util/stdio_compat.cpp +++ b/engines/ags/shared/util/stdio_compat.cpp @@ -22,6 +22,7 @@ #include "ags/shared/util/stdio_compat.h" #include "ags/shared/core/platform.h" +#include "common/config-manager.h" #include "common/file.h" #include "common/fs.h" #include "common/textconsole.h" @@ -46,24 +47,50 @@ file_off_t ags_ftell(Common::Stream *stream) { return rs->pos(); } +Common::FSNode getFSNOde(const char *path) { + Common::FSNode node(ConfMan.get("path")); + Common::String filePath(path); + + // If it's the root game folder, return the node for it + if (filePath.empty() || filePath == "." || filePath == "./") + return node; + + assert(filePath.hasPrefix("./")); + filePath = Common::String(filePath.c_str() + 2); + + // Iterate through any further subfolders or filename + size_t separator; + while ((separator = filePath.find('/')) != Common::String::npos) { + node = node.getChild(filePath.substr(0, separator)); + filePath = Common::String(filePath.c_str() + separator + 1); + } + + if (!filePath.empty()) + node = node.getChild(filePath); + + return node; +} + int ags_file_exists(const char *path) { - Common::FSNode fs(path); - return fs.exists() && !fs.isDirectory() ? 0 : -1; + Common::FSNode node = getFSNOde(path); + return node.exists() && !node.isDirectory() ? 1 : 0; } int ags_directory_exists(const char *path) { - Common::FSNode fs(path); - return fs.exists() && fs.isDirectory() ? 0 : -1; + Common::FSNode node = getFSNOde(path); + return node.exists() && node.isDirectory() ? 1 : 0; } int ags_path_exists(const char *path) { - return Common::FSNode(path).exists() ? 0 : -1; + Common::FSNode node = getFSNOde(path); + return node.exists() && node.isDirectory() ? 1 : 0; } file_off_t ags_file_size(const char *path) { + Common::FSNode node = getFSNOde(path); Common::File f; - return f.open(path) ? f.size() : (file_off_t )-1; + return f.open(node) ? f.size() : (file_off_t )-1; } } // namespace AGS3 From fbd4f7beb258422c13da5a6ce42d474647309f6e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Dec 2020 13:55:31 -1000 Subject: [PATCH 070/215] AGS: Fix specifying game filename --- engines/ags/ags.cpp | 2 +- engines/ags/shared/util/stdio_compat.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 9b018673b100..a872f7d09b58 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -258,7 +258,7 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { } if (datafile_argv > 0) { - cmdGameDataPath = "./"; + cmdGameDataPath = argv[datafile_argv]; } else { // assign standard path for mobile/consoles (defined in their own platform implementation) cmdGameDataPath = psp_game_file_name; diff --git a/engines/ags/shared/util/stdio_compat.cpp b/engines/ags/shared/util/stdio_compat.cpp index 3a4c32b01875..595a858ce6f5 100644 --- a/engines/ags/shared/util/stdio_compat.cpp +++ b/engines/ags/shared/util/stdio_compat.cpp @@ -55,8 +55,8 @@ Common::FSNode getFSNOde(const char *path) { if (filePath.empty() || filePath == "." || filePath == "./") return node; - assert(filePath.hasPrefix("./")); - filePath = Common::String(filePath.c_str() + 2); + if (filePath.hasPrefix("./")) + filePath = Common::String(filePath.c_str() + 2); // Iterate through any further subfolders or filename size_t separator; @@ -83,7 +83,7 @@ int ags_directory_exists(const char *path) { int ags_path_exists(const char *path) { Common::FSNode node = getFSNOde(path); - return node.exists() && node.isDirectory() ? 1 : 0; + return node.exists() ? 1 : 0; } file_off_t ags_file_size(const char *path) { From d502830e01a491df4542dd58a090c461627c17d0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Dec 2020 14:37:57 -1000 Subject: [PATCH 071/215] AGS: Fix opening game filename --- engines/ags/shared/util/bufferedstream.cpp | 1 - engines/ags/shared/util/filestream.cpp | 2 +- engines/ags/shared/util/stdio_compat.cpp | 14 +++++++------- engines/ags/shared/util/stdio_compat.h | 15 +++++++++------ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index 63f2bc099068..f94cc6a3ab0c 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -44,7 +44,6 @@ BufferedStream::BufferedStream(const String &file_name, FileOpenMode open_mode, error("Error determining stream end."); _buffer.resize(0); - } void BufferedStream::FillBufferFromPosition(soff_t position) { diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index 5134f2e04668..ca762af07df2 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -169,7 +169,7 @@ bool FileStream::Seek(soff_t offset, StreamSeek origin) { void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode) { if (open_mode == kFile_Open) { Common::File *f = new Common::File(); - if (!f->open(file_name.GetNullableCStr())) { + if (!f->open(getFSNode(file_name.GetNullableCStr()))) { delete f; _file = nullptr; } else { diff --git a/engines/ags/shared/util/stdio_compat.cpp b/engines/ags/shared/util/stdio_compat.cpp index 595a858ce6f5..2bdd48ea293e 100644 --- a/engines/ags/shared/util/stdio_compat.cpp +++ b/engines/ags/shared/util/stdio_compat.cpp @@ -34,9 +34,9 @@ int ags_fseek(Common::Stream *stream, file_off_t offset, int whence) { Common::SeekableWriteStream *ws = dynamic_cast(stream); if (rs) - return rs->seek(offset, whence); + return rs->seek(offset, whence) ? 0 : 1; else if (ws) - return ws->seek(offset, whence); + return ws->seek(offset, whence) ? 0 : 1; else error("Seek on null stream"); } @@ -47,7 +47,7 @@ file_off_t ags_ftell(Common::Stream *stream) { return rs->pos(); } -Common::FSNode getFSNOde(const char *path) { +Common::FSNode getFSNode(const char *path) { Common::FSNode node(ConfMan.get("path")); Common::String filePath(path); @@ -72,22 +72,22 @@ Common::FSNode getFSNOde(const char *path) { } int ags_file_exists(const char *path) { - Common::FSNode node = getFSNOde(path); + Common::FSNode node = getFSNode(path); return node.exists() && !node.isDirectory() ? 1 : 0; } int ags_directory_exists(const char *path) { - Common::FSNode node = getFSNOde(path); + Common::FSNode node = getFSNode(path); return node.exists() && node.isDirectory() ? 1 : 0; } int ags_path_exists(const char *path) { - Common::FSNode node = getFSNOde(path); + Common::FSNode node = getFSNode(path); return node.exists() ? 1 : 0; } file_off_t ags_file_size(const char *path) { - Common::FSNode node = getFSNOde(path); + Common::FSNode node = getFSNode(path); Common::File f; return f.open(node) ? f.size() : (file_off_t )-1; diff --git a/engines/ags/shared/util/stdio_compat.h b/engines/ags/shared/util/stdio_compat.h index f3bfc739990a..65e83711071b 100644 --- a/engines/ags/shared/util/stdio_compat.h +++ b/engines/ags/shared/util/stdio_compat.h @@ -24,18 +24,21 @@ #define AGS_SHARED_UTIL_STDIO_COMPAT_H #include "common/stream.h" +#include "common/fs.h" namespace AGS3 { typedef int64 file_off_t; -int ags_fseek(Common::Stream *stream, file_off_t offset, int whence); -file_off_t ags_ftell(Common::Stream *stream); +extern Common::FSNode getFSNode(const char *path); -int ags_file_exists(const char *path); -int ags_directory_exists(const char *path); -int ags_path_exists(const char *path); -file_off_t ags_file_size(const char *path); +extern int ags_fseek(Common::Stream *stream, file_off_t offset, int whence); +extern file_off_t ags_ftell(Common::Stream *stream); + +extern int ags_file_exists(const char *path); +extern int ags_directory_exists(const char *path); +extern int ags_path_exists(const char *path); +extern file_off_t ags_file_size(const char *path); } // namespace AGS3 From 32828d31d20d7934c915f68cde77322108aeeabc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Dec 2020 15:52:00 -1000 Subject: [PATCH 072/215] AGS: Fix tyring to read config file when not present --- engines/ags/engine/main/engine.cpp | 4 +++- engines/ags/shared/game/main_game_file.cpp | 4 ++++ engines/ags/shared/util/bufferedstream.cpp | 13 ++----------- engines/ags/shared/util/file.cpp | 2 +- engines/ags/shared/util/filestream.cpp | 3 --- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 48a33cd00204..f0e03a60ac6d 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -1199,7 +1199,8 @@ void engine_read_config(const String &exe_path, ConfigTree &cfg) { // Disabled on Windows because people were afraid that this config could be mistakenly // created by some installer and screw up their games. Until any kind of solution is found. String user_global_cfg_file; -#if ! AGS_PLATFORM_OS_WINDOWS +#if !AGS_PLATFORM_SCUMMVM +#if !AGS_PLATFORM_OS_WINDOWS // Read user global configuration file user_global_cfg_file = find_user_global_cfg_file(); if (Path::ComparePaths(user_global_cfg_file, def_cfg_file) != 0) @@ -1211,6 +1212,7 @@ void engine_read_config(const String &exe_path, ConfigTree &cfg) { if (Path::ComparePaths(user_cfg_file, def_cfg_file) != 0 && Path::ComparePaths(user_cfg_file, user_global_cfg_file) != 0) IniUtil::Read(user_cfg_file, cfg); +#endif // Apply overriding options from mobile port settings // TODO: normally, those should be instead stored in the same config file in a uniform way diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 8f6c7f008420..ad424347590e 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -607,6 +607,7 @@ void SetDefaultGlobalMessages(GameSetupStruct &game) { } void FixupSaveDirectory(GameSetupStruct &game) { +#ifdef DEPRECATED // If the save game folder was not specified by game author, create one of // the game name, game GUID, or uniqueid, as a last resort if (!game.saveGameFolderName[0]) { @@ -620,6 +621,9 @@ void FixupSaveDirectory(GameSetupStruct &game) { // Lastly, fixup folder name by removing any illegal characters String s = Path::FixupSharedFilename(game.saveGameFolderName); snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", s.GetCStr()); +#else + sprintf(game.saveGameFolderName, ""); +#endif } HGameFileError ReadSpriteFlags(LoadedGameEntities &ents, Stream *in, GameDataVersion data_ver) { diff --git a/engines/ags/shared/util/bufferedstream.cpp b/engines/ags/shared/util/bufferedstream.cpp index f94cc6a3ab0c..973f3d693af8 100644 --- a/engines/ags/shared/util/bufferedstream.cpp +++ b/engines/ags/shared/util/bufferedstream.cpp @@ -32,17 +32,8 @@ namespace AGS { namespace Shared { BufferedStream::BufferedStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) - : FileStream(file_name, open_mode, work_mode, stream_endianess), _buffer(BufferStreamSize), _bufferPosition(0), _position(0) { - if (FileStream::Seek(0, kSeekEnd) == false) - error("Error determining stream end."); - - _end = FileStream::GetPosition(); - if (_end == -1) - error("Error determining stream end."); - - if (FileStream::Seek(0, kSeekBegin) == false) - error("Error determining stream end."); - + : FileStream(file_name, open_mode, work_mode, stream_endianess), _buffer(BufferStreamSize), _bufferPosition(0), _position(0) { + _end = GetLength(); _buffer.resize(0); } diff --git a/engines/ags/shared/util/file.cpp b/engines/ags/shared/util/file.cpp index e94d56e9e075..8324e363de1a 100644 --- a/engines/ags/shared/util/file.cpp +++ b/engines/ags/shared/util/file.cpp @@ -120,7 +120,7 @@ Stream *File::OpenFile(const String &filename, FileOpenMode open_mode, FileWorkM fs = new BufferedStream(filename, open_mode, work_mode); else fs = new FileStream(filename, open_mode, work_mode); - if (fs != nullptr && !fs->IsValid()) { + if (fs != nullptr && !fs->IsValid()) { delete fs; fs = nullptr; } diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index ca762af07df2..b512fc45058e 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -185,9 +185,6 @@ void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkM _file = f; } } - - if (_file == nullptr) - error("Error opening file."); } } // namespace Shared From 93ad5ada355097d75639f376d624396458cdd649 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Dec 2020 16:24:14 -1000 Subject: [PATCH 073/215] AGS: Fix ustrsize stub --- engines/ags/lib/allegro/unicode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/unicode.cpp b/engines/ags/lib/allegro/unicode.cpp index 073fda45ec71..4c70f2fc6e87 100644 --- a/engines/ags/lib/allegro/unicode.cpp +++ b/engines/ags/lib/allegro/unicode.cpp @@ -30,7 +30,7 @@ void set_uformat(int format) { } size_t ustrsize(const char *s) { - error("TODO: ustrsize"); + return strlen(s); } From a7ef1507734aa80ccbf15714a89735b88f6b524d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Dec 2020 17:04:03 -1000 Subject: [PATCH 074/215] AGS: Create ScummVM SYSTEM_DRIVER --- engines/ags/lib/allegro/system.cpp | 46 +++++++++++++++++++++++++++++- engines/ags/lib/allegro/system.h | 7 +++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/engines/ags/lib/allegro/system.cpp b/engines/ags/lib/allegro/system.cpp index a27cb655b329..31f858b4a6ad 100644 --- a/engines/ags/lib/allegro/system.cpp +++ b/engines/ags/lib/allegro/system.cpp @@ -27,13 +27,57 @@ namespace AGS3 { SYSTEM_DRIVER system_none; -SYSTEM_DRIVER *system_driver; + +SYSTEM_DRIVER system_scummvm = { + SYSTEM_SCUMMVM, + nullptr, + nullptr, + "ScummVM Device", + nullptr, // TODO: ios_sys_init, + nullptr, // TODO: ios_sys_exit, + nullptr, /* AL_METHOD(void, get_executable_name, (char *output, int size)); */ + nullptr, /* AL_METHOD(int, find_resource, (char *dest, AL_CONST char *resource, int size)); */ + nullptr, /* AL_METHOD(void, set_window_title, (AL_CONST char *name)); */ + nullptr, /* AL_METHOD(int, set_close_button_callback, (AL_METHOD(void, proc, (void)))); */ + nullptr, /* AL_METHOD(void, message, (AL_CONST char *msg)); */ + nullptr, /* AL_METHOD(void, assert, (AL_CONST char *msg)); */ + nullptr, /* AL_METHOD(void, save_console_state, (void)); */ + nullptr, /* AL_METHOD(void, restore_console_state, (void)); */ + nullptr, /* AL_METHOD(struct BITMAP *, create_bitmap, (int color_depth, int width, int height)); */ + nullptr, /* AL_METHOD(void, created_bitmap, (struct BITMAP *bmp)); */ + nullptr, /* AL_METHOD(struct BITMAP *, create_sub_bitmap, (struct BITMAP *parent, int x, int y, int width, int height)); */ + nullptr, /* AL_METHOD(void, created_sub_bitmap, (struct BITMAP *bmp, struct BITMAP *parent)); */ + nullptr, /* AL_METHOD(int, destroy_bitmap, (struct BITMAP *bitmap)); */ + nullptr, /* AL_METHOD(void, read_hardware_palette, (void)); */ + nullptr, /* AL_METHOD(void, set_palette_range, (AL_CONST struct RGB *p, int from, int to, int retracesync)); */ + nullptr, /* AL_METHOD(struct GFX_VTABLE *, get_vtable, (int color_depth)); */ + nullptr, /* AL_METHOD(int, set_display_switch_mode, (int mode)); */ + nullptr, /* AL_METHOD(void, display_switch_lock, (int lock, int foreground)); */ + nullptr, /* AL_METHOD(int, desktop_color_depth, (void)); */ + nullptr, /* AL_METHOD(int, get_desktop_resolution, (int *width, int *height)); */ + nullptr, // TODO: ios_get_gfx_safe_mode, /*AL_METHOD(void, get_gfx_safe_mode, (int *driver, struct GFX_MODE *mode));*/ + nullptr, /* AL_METHOD(void, yield_timeslice, (void)); */ + nullptr, // TODO: _ios_create_mutex, /* AL_METHOD(void *, create_mutex, (void)); */ + nullptr, // TODO: _ios_destroy_mutex, /* AL_METHOD(void, destroy_mutex, (void *handle)); */ + nullptr, // TODO: _ios_lock_mutex, /* AL_METHOD(void, lock_mutex, (void *handle)); */ + nullptr, // TODO: _ios_unlock_mutex, /* AL_METHOD(void, unlock_mutex, (void *handle)); */ + nullptr, /* AL_METHOD(_DRIVER_INFO *, gfx_drivers, (void)); */ + nullptr, /* AL_METHOD(_DRIVER_INFO *, digi_drivers, (void)); */ + nullptr, /* AL_METHOD(_DRIVER_INFO *, midi_drivers, (void)); */ + nullptr, /* AL_METHOD(_DRIVER_INFO *, keyboard_drivers, (void)); */ + nullptr, /* AL_METHOD(_DRIVER_INFO *, mouse_drivers, (void)); */ + nullptr, /* AL_METHOD(_DRIVER_INFO *, joystick_drivers, (void)); */ + nullptr /* AL_METHOD(_DRIVER_INFO *, timer_drivers, (void)); */ +}; _DRIVER_INFO _system_driver_list[] = { + { SYSTEM_SCUMMVM, &system_scummvm, true }, { SYSTEM_NONE, &system_none, false }, { 0, nullptr , 0 } }; +SYSTEM_DRIVER *system_driver = &system_scummvm; + GFX_MODE_LIST *get_gfx_mode_list(int card) { assert(card == 0); diff --git a/engines/ags/lib/allegro/system.h b/engines/ags/lib/allegro/system.h index c44eedd84d2f..aef878d8edf9 100644 --- a/engines/ags/lib/allegro/system.h +++ b/engines/ags/lib/allegro/system.h @@ -34,6 +34,7 @@ namespace AGS3 { #endif #define SYSTEM_AUTODETECT 0 +#define SYSTEM_SCUMMVM AL_ID('S','C','V','M') #define SYSTEM_NONE AL_ID('N','O','N','E') #define SWITCH_NONE 0 @@ -56,9 +57,9 @@ struct GFX_MODE_LIST { struct SYSTEM_DRIVER { int id; - char *name; - char *desc; - char *ascii_name; + const char *name; + const char *desc; + const char *ascii_name; AL_METHOD(int, init, (void)); AL_METHOD(void, exit, (void)); AL_METHOD(void, get_executable_name, (char *output, int size)); From 3c67c209d055cab0d14fd92542514f450c2e9d5a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 31 Dec 2020 14:27:16 -1000 Subject: [PATCH 075/215] AGS: Change sound method stubs from errors to warnings --- engines/ags/lib/audio/sound.cpp | 41 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/engines/ags/lib/audio/sound.cpp b/engines/ags/lib/audio/sound.cpp index e8d197b660f1..db82aa061ba5 100644 --- a/engines/ags/lib/audio/sound.cpp +++ b/engines/ags/lib/audio/sound.cpp @@ -22,6 +22,8 @@ #include "ags/lib/audio/sound.h" #include "common/textconsole.h" +#include "ags/ags.h" +#include "audio/mixer.h" namespace AGS3 { @@ -40,67 +42,72 @@ void remove_sound() { } void reserve_voices(int digi_voices, int midi_voices) { - error("reserve_voices"); + // TODO: reserve_voices } void set_volume_per_voice(int scale) { - error("set_volume_per_voice"); - + // TODO: set_volume_per_voice } int install_sound_input(int digi, int midi) { - error("install_sound_input"); + // TODO: install_sound_input + return 0; } void remove_sound_input() { - error("remove_sound_input"); + // TODO: remove_sound_input } void set_volume(int digi_volume, int midi_volume) { - error("set_volume"); + // TODO: set_volume } void set_hardware_volume(int digi_volume, int midi_volume) { - error("set_hardware_volume"); + // TODO: set_hardware_volume } void get_volume(int *digi_volume, int *midi_volume) { - error("get_volume"); + // TODO: get_volume + *digi_volume = 255; + *midi_volume = 255; } void get_hardware_volume(int *digi_volume, int *midi_volume) { - error("get_hardware_volume"); + // TODO: get_hardware_volume } void set_mixer_quality(int quality) { - error("set_mixer_quality"); + // TODO: set_mixer_quality } int get_mixer_quality() { - error("get_mixer_quality"); + warning("TODO: get_mixer_quality"); + return 0; } int get_mixer_frequency() { - error("get_mixer_frequency"); + return ::AGS::g_vm->_mixer->getOutputRate(); } int get_mixer_bits() { - error("get_mixer_bits"); + return 16; } int get_mixer_channels() { - error("get_mixer_channels"); + warning("TODO: get_mixer_channels"); + return 10; } int get_mixer_voices() { - error("get_mixer_voices"); + warning("TODO: get_mixer_voices"); + return 1; } int get_mixer_buffer_length() { - error("get_mixer_buffer_length"); + warning("TODO: get_mixer_buffer_length"); + return 22040; } - void stop_audio_stream(AUDIOSTREAM *stream) { warning("TODO: stop_audio_stream"); } From 8d36018eb130a6d1e227193535a30a5c1a32f670 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 31 Dec 2020 16:02:27 -1000 Subject: [PATCH 076/215] AGS: Set up digi driver detection --- engines/ags/lib/allegro/base.h | 3 +++ engines/ags/lib/audio/digi.cpp | 8 +++++++- engines/ags/lib/audio/sound.cpp | 5 ----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engines/ags/lib/allegro/base.h b/engines/ags/lib/allegro/base.h index 88a91e082edb..01eb8d0a32de 100644 --- a/engines/ags/lib/allegro/base.h +++ b/engines/ags/lib/allegro/base.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/algorithm.h" +#include "common/endian.h" namespace AGS3 { @@ -55,6 +56,8 @@ struct _DRIVER_INFO { #define AL_FUNC(type, name, args) type name args +#define SCUMMVM_ID MKTAG('S', 'C', 'V', 'M') + } // namespace AGS3 #endif diff --git a/engines/ags/lib/audio/digi.cpp b/engines/ags/lib/audio/digi.cpp index 6e34e036e99b..03efcaaae99f 100644 --- a/engines/ags/lib/audio/digi.cpp +++ b/engines/ags/lib/audio/digi.cpp @@ -33,9 +33,15 @@ int digi_card; int digi_input_card; +static byte dummy_driver_data[1] = { 0 }; + +BEGIN_DIGI_DRIVER_LIST + { SCUMMVM_ID, &dummy_driver_data, true }, +END_DIGI_DRIVER_LIST + int detect_digi_driver(int driver_id) { - return 0; + return 1; } SAMPLE *load_wav_pf(PACKFILE *f) { diff --git a/engines/ags/lib/audio/sound.cpp b/engines/ags/lib/audio/sound.cpp index db82aa061ba5..f87fdef38987 100644 --- a/engines/ags/lib/audio/sound.cpp +++ b/engines/ags/lib/audio/sound.cpp @@ -27,11 +27,6 @@ namespace AGS3 { -_DRIVER_INFO _digi_driver_list[] = { - { 0, nullptr, 0 } -}; - - int install_sound(int digi, int midi, const char *cfg_path) { // TODO: install_sound return 0; From 4d737fdea9a5de03c12c59d68d6a63d0f1b481ed Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 31 Dec 2020 22:00:33 -1000 Subject: [PATCH 077/215] AGS: Further fixes for audio init --- engines/ags/engine/main/engine.cpp | 12 ++++-- engines/ags/lib/audio/digi.cpp | 61 +++++++++++++++++++++++++++++- engines/ags/lib/audio/digi.h | 4 +- engines/ags/lib/audio/midi.cpp | 5 ++- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index f0e03a60ac6d..b90cee75c141 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -451,18 +451,24 @@ std::pair autodetect_driver(_DRIVER_INFO *driver_list, int (*detect_au // Returns a pair of audio card ID and max available voices. std::pair decide_audiodriver(int try_id, _DRIVER_INFO *driver_list, int(*detect_audio_driver)(int), int &al_drv_id, const char *type) { - if (try_id == 0) // no driver + if (try_id == 0) + // No driver return std::make_pair(0, 0); - al_drv_id = 0; // the driver id will be set by library if one was found + al_drv_id = 0; + if (try_id > 0) { int voices = detect_audio_driver(try_id); - if (al_drv_id == try_id && voices != 0) // found and detected + if (al_drv_id == try_id && voices != 0) { + // found and detected return std::make_pair(try_id, voices); + } if (voices == 0) // found in list but detect failed Debug::Printf(kDbgMsg_Error, "Failed to detect %s driver %s; Error: '%s'.", type, AlIDToChars(try_id).s, get_allegro_error()); else // not found at all Debug::Printf(kDbgMsg_Error, "Unknown %s driver: %s, will try to find suitable one.", type, AlIDToChars(try_id).s); } + + al_drv_id = 1; return autodetect_driver(driver_list, detect_audio_driver, type); } diff --git a/engines/ags/lib/audio/digi.cpp b/engines/ags/lib/audio/digi.cpp index 03efcaaae99f..c28fe3eb7329 100644 --- a/engines/ags/lib/audio/digi.cpp +++ b/engines/ags/lib/audio/digi.cpp @@ -25,6 +25,63 @@ namespace AGS3 { +/*------------------------------------------------------------------*/ + +DIGI_DRIVER::DIGI_DRIVER() : + id(0), name(nullptr), + desc(nullptr), + ascii_name(nullptr), + voices(0), + basevoice(0), + max_voices(0), + def_voices(0), + detect(nullptr), + init(nullptr), + exit_(nullptr), + set_mixer_volume(nullptr), + get_mixer_volume(nullptr), + lock_voice(nullptr), + unlock_voice(nullptr), + buffer_size(nullptr), + init_voice(nullptr), + release_voice(nullptr), + start_voice(nullptr), + stop_voice(nullptr), + loop_voice(nullptr), + get_position(nullptr), + set_position(nullptr), + get_volume(nullptr), + set_volume(nullptr), + ramp_volume(nullptr), + stop_volume_ramp(nullptr), + get_frequency(nullptr), + set_frequency(nullptr), + sweep_frequency(nullptr), + stop_frequency_sweep(nullptr), + get_pan(nullptr), + set_pan(nullptr), + sweep_pan(nullptr), + stop_pan_sweep(nullptr), + set_echo(nullptr), + set_tremolo(nullptr), + set_vibrato(nullptr), + rec_cap_bits(0), + rec_cap_stereo(0), + rec_cap_rate(nullptr), + rec_cap_parm(nullptr), + rec_source(nullptr), + rec_start(nullptr), + rec_stop(nullptr), + rec_read(nullptr) { +} + +/*------------------------------------------------------------------*/ + +class ScummVMDigiDriver : public DIGI_DRIVER { +}; + +/*------------------------------------------------------------------*/ + DIGI_DRIVER *digi_driver; DIGI_DRIVER *digi_input_driver; @@ -41,7 +98,9 @@ END_DIGI_DRIVER_LIST int detect_digi_driver(int driver_id) { - return 1; + assert(driver_id == SCUMMVM_ID); + digi_driver = new ScummVMDigiDriver(); + return 16; } SAMPLE *load_wav_pf(PACKFILE *f) { diff --git a/engines/ags/lib/audio/digi.h b/engines/ags/lib/audio/digi.h index 904c40fb3ff9..da058b11df6e 100644 --- a/engines/ags/lib/audio/digi.h +++ b/engines/ags/lib/audio/digi.h @@ -66,7 +66,7 @@ struct DIGI_DRIVER { /* setup routines */ AL_METHOD(int, detect, (int input)); AL_METHOD(int, init, (int input, int voices)); - AL_METHOD(void, exit, (int input)); + AL_METHOD(void, exit_, (int input)); AL_METHOD(int, set_mixer_volume, (int volume)); AL_METHOD(int, get_mixer_volume, (void)); @@ -118,6 +118,8 @@ struct DIGI_DRIVER { AL_METHOD(int, rec_start, (int rate, int bits, int stereo)); AL_METHOD(void, rec_stop, (void)); AL_METHOD(int, rec_read, (void *buf)); + + DIGI_DRIVER(); }; AL_ARRAY(_DRIVER_INFO, _digi_driver_list); diff --git a/engines/ags/lib/audio/midi.cpp b/engines/ags/lib/audio/midi.cpp index 5be76b146862..96de121a66f6 100644 --- a/engines/ags/lib/audio/midi.cpp +++ b/engines/ags/lib/audio/midi.cpp @@ -26,7 +26,10 @@ namespace AGS3 { +static byte dummy_driver_data[1] = { 0 }; + BEGIN_MIDI_DRIVER_LIST +{ SCUMMVM_ID, &dummy_driver_data, true }, END_MIDI_DRIVER_LIST MIDI_DRIVER *midi_driver; @@ -45,7 +48,7 @@ long midi_loop_end; /* loop when we hit this position */ int detect_midi_driver(int driver_id) { - return 0; + return 16; } From 2786d14ee0bba67316c34b7209ed2ed5f273b247 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jan 2021 16:56:12 -0800 Subject: [PATCH 078/215] AGS: Properly load fonts via asset manager --- engines/ags/lib/alfont/alfont.cpp | 15 +++------- engines/ags/lib/alfont/alfont.h | 9 +++--- engines/ags/shared/font/ttffontrenderer.cpp | 33 ++++++++++++++------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/engines/ags/lib/alfont/alfont.cpp b/engines/ags/lib/alfont/alfont.cpp index 3a69e8e7b42d..e538baf6014d 100644 --- a/engines/ags/lib/alfont/alfont.cpp +++ b/engines/ags/lib/alfont/alfont.cpp @@ -28,12 +28,8 @@ namespace AGS3 { Graphics::Font *ALFONT_FONT::getFont() { if (!_fonts.contains(_size)) { - Common::File f; - if (!f.open(_filename)) - error("Could not read font - %s", _filename.c_str()); - _fonts[_size] = Graphics::loadTTFFont(f, f.size()); - f.close(); - + // Instantiate the raw TTF data into a font of the given size + _fonts[_size] = Graphics::loadTTFFont(_ttfData, _size); assert(_fonts[_size]); } @@ -42,11 +38,8 @@ Graphics::Font *ALFONT_FONT::getFont() { /*------------------------------------------------------------------*/ -ALFONT_FONT *alfont_loadFont(const Common::String &filename) { - ALFONT_FONT *result = new ALFONT_FONT(); - result->_filename = filename; - - return result; +ALFONT_FONT *alfont_load_font_from_mem(const byte *data, int data_len) { + return new ALFONT_FONT(data, data_len); } void alfont_destroy_font(ALFONT_FONT *font) { diff --git a/engines/ags/lib/alfont/alfont.h b/engines/ags/lib/alfont/alfont.h index d3f92e245147..5cf57a407c9f 100644 --- a/engines/ags/lib/alfont/alfont.h +++ b/engines/ags/lib/alfont/alfont.h @@ -24,18 +24,19 @@ #define AGS_LIB_ALFONT_H #include "common/hashmap.h" +#include "common/memstream.h" #include "graphics/font.h" #include "ags/lib/allegro/gfx.h" namespace AGS3 { struct ALFONT_FONT { - Common::String _filename; + Common::MemoryReadStream _ttfData; int _size; Common::HashMap _fonts; - ALFONT_FONT() : _size(-1) {} - ALFONT_FONT(const Common::String &filename) : _filename(filename), _size(-1) {} + ALFONT_FONT() : _size(-1), _ttfData(nullptr, 0) {} + ALFONT_FONT(const byte *data, size_t size) : _size(-1), _ttfData(data, size, DisposeAfterUse::YES) {} ~ALFONT_FONT() { for (Common::HashMap::iterator it = _fonts.begin(); @@ -49,7 +50,7 @@ struct ALFONT_FONT { inline void alfont_init() {} inline void alfont_exit() {} inline void alfont_text_mode(int val) {} -extern ALFONT_FONT *alfont_loadFont(const Common::String &filename); +extern ALFONT_FONT *alfont_load_font_from_mem(const byte *data, int data_len); extern void alfont_destroy_font(ALFONT_FONT *font); extern size_t alfont_text_length(ALFONT_FONT *font, const char *text); diff --git a/engines/ags/shared/font/ttffontrenderer.cpp b/engines/ags/shared/font/ttffontrenderer.cpp index 34a5489fa951..bf675a62f8af 100644 --- a/engines/ags/shared/font/ttffontrenderer.cpp +++ b/engines/ags/shared/font/ttffontrenderer.cpp @@ -92,22 +92,35 @@ bool TTFFontRenderer::IsBitmapFont() { bool TTFFontRenderer::LoadFromDiskEx(int fontNumber, int fontSize, const FontRenderParams *params) { String file_name = String::FromFormat("agsfnt%d.ttf", fontNumber); + Stream *reader = AssetManager::OpenAsset(file_name); + byte *membuffer; + + if (reader == nullptr) + return false; + + long lenof = AssetManager::GetLastAssetSize(); + + membuffer = (byte *)malloc(lenof); + reader->ReadArray(membuffer, lenof, 1); + delete reader; + + ALFONT_FONT *alfptr = alfont_load_font_from_mem(membuffer, lenof); + free(membuffer); - ALFONT_FONT *alfptr = alfont_loadFont(file_name); if (alfptr == nullptr) return false; // TODO: move this somewhere, should not be right here #if AGS_OUTLINE_FONT_FIX - // FIXME: (!!!) this fix should be done differently: - // 1. Find out which OUTLINE font was causing troubles; - // 2. Replace outline method ONLY if that troublesome font is used as outline. - // 3. Move this fix somewhere else!! (right after game load routine?) - // - // Check for the LucasFan font since it comes with an outline font that - // is drawn incorrectly with Freetype versions > 2.1.3. - // A simple workaround is to disable outline fonts for it and use - // automatic outline drawing. + // FIXME: (!!!) this fix should be done differently: + // 1. Find out which OUTLINE font was causing troubles; + // 2. Replace outline method ONLY if that troublesome font is used as outline. + // 3. Move this fix somewhere else!! (right after game load routine?) + // + // Check for the LucasFan font since it comes with an outline font that + // is drawn incorrectly with Freetype versions > 2.1.3. + // A simple workaround is to disable outline fonts for it and use + // automatic outline drawing. if (get_font_outline(fontNumber) >= 0 && strcmp(alfont_get_name(alfptr), "LucasFan-Font") == 0) set_font_outline(fontNumber, FONT_OUTLINE_AUTO); From ffc5a8cf13c5f2bab5897bcc57598334f90717c3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jan 2021 18:25:20 -0800 Subject: [PATCH 079/215] AGS: Fixes for setup of screen resolutions --- engines/ags/lib/allegro/system.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/engines/ags/lib/allegro/system.cpp b/engines/ags/lib/allegro/system.cpp index 31f858b4a6ad..765fdee3c4d6 100644 --- a/engines/ags/lib/allegro/system.cpp +++ b/engines/ags/lib/allegro/system.cpp @@ -80,8 +80,6 @@ SYSTEM_DRIVER *system_driver = &system_scummvm; GFX_MODE_LIST *get_gfx_mode_list(int card) { - assert(card == 0); - GFX_MODE_LIST *list = new GFX_MODE_LIST(); list->num_modes = 1; list->mode = new GFX_MODE[1]; @@ -89,7 +87,7 @@ GFX_MODE_LIST *get_gfx_mode_list(int card) { GFX_MODE &gm = list->mode[0]; gm.width = 320; gm.height = 200; - gm.bpp = 16; + gm.bpp = 32; return list; } @@ -108,10 +106,12 @@ int get_color_depth() { } int get_desktop_resolution(int *width, int *height) { - if (*width) - *width = g_system->getWidth(); - if (*height) - *height = g_system->getHeight(); + // TODO: ScummVM has a hardcoded dummy desktop resolution. See if there's any + // need to change the values, given we're hardcoded for pretend full-screen + if (width) + *width = 640; + if (height) + *height = 480; return 0; } From c747d7963c99c5d29f95a416c18dfa4f68c50fb1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jan 2021 19:37:45 -0800 Subject: [PATCH 080/215] AGS: Fix creating and clearing bitmaps --- engines/ags/engine/gfx/ali3dogl.cpp | 7 ++++++- engines/ags/lib/allegro/gfx.cpp | 4 +++- engines/ags/lib/allegro/gfx.h | 4 ++++ engines/ags/lib/opengl/opengl.cpp | 2 -- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 6d621b1c0267..6c74ecc51829 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -192,7 +192,12 @@ OGLGraphicsDriver::ShaderProgram::ShaderProgram() : Program(0), SamplerVar(0), C OGLGraphicsDriver::OGLGraphicsDriver() { -#if AGS_PLATFORM_OS_WINDOWS +#if AGS_PLATFORM_SCUMMVM + device_screen_physical_width = 640; + device_screen_physical_height = 480; + _glxContext = nullptr; + _have_window = false; +#elif AGS_PLATFORM_OS_WINDOWS _hDC = NULL; _hRC = NULL; _hWnd = NULL; diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 9111935848e6..3dcec8f2df47 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -105,8 +105,10 @@ BITMAP *create_bitmap_ex(int color_depth, int width, int height) { switch (color_depth) { case 16: format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + break; case 32: format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); + break; default: error("Invalid color depth"); } @@ -404,7 +406,7 @@ void circlefill(BITMAP *bmp, int x, int y, int radius, int color) { } void clear_bitmap(BITMAP *bmp) { - error("TODO: clear_bitmap"); + bmp->clear(); } diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index 11a1c07a1624..ea415a05f980 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -203,6 +203,10 @@ class BITMAP { } int getpixel(int x, int y) const; + + void clear() { + _owner->clear(); + } }; AL_FUNC(void, set_color_conversion, (int mode)); diff --git a/engines/ags/lib/opengl/opengl.cpp b/engines/ags/lib/opengl/opengl.cpp index ba367d006745..b60f9f768d5a 100644 --- a/engines/ags/lib/opengl/opengl.cpp +++ b/engines/ags/lib/opengl/opengl.cpp @@ -56,7 +56,6 @@ GLint glGetUniformLocation(GLuint program, const GLchar *name) { } void glShadeModel(GLenum mode) { - error("TODO: glShadeMode"); } void glGetProgramiv(GLuint program, GLenum pname, GLint *params) { @@ -75,7 +74,6 @@ void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { } void glClear(GLbitfield mask) { - warning("TODO: glClear"); } void glDrawArrays(GLenum mode, GLint first, GLsizei count) { From 70dcabd6411ad5061e2cc4fbd151d2868347a2d6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jan 2021 20:01:45 -0800 Subject: [PATCH 081/215] AGS: Implement glGetIntegerv method --- engines/ags/lib/opengl/opengl.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/engines/ags/lib/opengl/opengl.cpp b/engines/ags/lib/opengl/opengl.cpp index b60f9f768d5a..d2d098d17c83 100644 --- a/engines/ags/lib/opengl/opengl.cpp +++ b/engines/ags/lib/opengl/opengl.cpp @@ -89,8 +89,14 @@ void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format } void glGetIntegerv(GLenum pname, GLint *data) { - // TODO: glGetIntegerv - *data = 0; + switch (pname) { + case GL_MAX_TEXTURE_SIZE: + *data = 512; + break; + default: + *data = 0; + break; + } } void glGetFloatv(GLenum pname, GLfloat *params) { From 9d36ccb9c697960c0bfa3b1120a1aa7a1b351b19 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jan 2021 20:52:43 -0800 Subject: [PATCH 082/215] AGS: Implement load_pcx method --- engines/ags/lib/allegro/gfx.cpp | 15 -------------- engines/ags/lib/allegro/gfx.h | 22 ++++++++++++++++++++ engines/ags/shared/gfx/image.cpp | 35 +++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 3dcec8f2df47..672b3b4fa12f 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -53,21 +53,6 @@ int BITMAP::getpixel(int x, int y) const { /*-------------------------------------------------------------------*/ -/** - * Derived surface class - */ -class Surface : public Graphics::ManagedSurface, public BITMAP { -public: - Surface() : Graphics::ManagedSurface(), BITMAP(this) {} - Surface(const Graphics::ManagedSurface &surf) : Graphics::ManagedSurface(surf), BITMAP(this) {} - Surface(int width, int height) : Graphics::ManagedSurface(width, height), BITMAP(this) {} - Surface(int width, int height, const Graphics::PixelFormat &pixelFormat) : - Graphics::ManagedSurface(width, height, pixelFormat), BITMAP(this) {} - Surface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) : - Graphics::ManagedSurface(surf, bounds), BITMAP(this) {} - ~Surface() override {} -}; - /** * Dervied screen surface */ diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index ea415a05f980..ee2189429c09 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -209,6 +209,28 @@ class BITMAP { } }; +/** + * Derived surface class + */ +class Surface : public Graphics::ManagedSurface, public BITMAP { +public: + Surface() : Graphics::ManagedSurface(), BITMAP(this) { + } + Surface(const Graphics::ManagedSurface &surf) : Graphics::ManagedSurface(surf), BITMAP(this) { + } + Surface(int width, int height) : Graphics::ManagedSurface(width, height), BITMAP(this) { + } + Surface(int width, int height, const Graphics::PixelFormat &pixelFormat) : + Graphics::ManagedSurface(width, height, pixelFormat), BITMAP(this) { + } + Surface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) : + Graphics::ManagedSurface(surf, bounds), BITMAP(this) { + } + ~Surface() override { + } +}; + + AL_FUNC(void, set_color_conversion, (int mode)); AL_FUNC(int, get_color_conversion, ()); AL_FUNC(int, set_gfx_mode, (int card, int w, int h, int v_w, int v_h)); diff --git a/engines/ags/shared/gfx/image.cpp b/engines/ags/shared/gfx/image.cpp index 8de490b338f4..914c4d84bf8a 100644 --- a/engines/ags/shared/gfx/image.cpp +++ b/engines/ags/shared/gfx/image.cpp @@ -22,11 +22,44 @@ #include "ags/shared/gfx/image.h" #include "ags/lib/allegro.h" +#include "common/file.h" #include "common/str.h" #include "common/textconsole.h" +#include "image/pcx.h" namespace AGS3 { +template +BITMAP *decodeImage(const char *filename, color *pal) { + DECODER decoder; + Common::File f; + + if (f.open(filename) && decoder.loadStream(f)) { + // Create the output surface + const Graphics::Surface *src = decoder.getSurface(); + + // Copy the decoded surface + Surface *dest = new Surface(); + dest->create(src->w, src->h, src->format); + dest->blitFrom(*src); + + // Copy the palette + const byte *palP = decoder.getPalette(); + if (palP) { + for (int idx = 0; idx < 256; ++idx, palP += 3) { + pal[idx].r = palP[0]; + pal[idx].g = palP[1]; + pal[idx].b = palP[2]; + pal[idx].filler = 0xff; + } + } + + return dest; + } else { + return nullptr; + } +} + BITMAP *load_bmp_pf(PACKFILE *f, color *pal) { error("TODO: load_bmp_pf"); } @@ -48,7 +81,7 @@ BITMAP *load_lbm(const char *filename, color *pal) { } BITMAP *load_pcx(const char *filename, color *pal) { - error("TODO: load_pcx"); + return decodeImage(filename, pal); } BITMAP *load_tga(const char *filename, color *pal) { From 072ed144f708a4da38f9e2cb7abbac65b9522c8f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jan 2021 20:54:39 -0800 Subject: [PATCH 083/215] AGS: Allow paletted bitmaps in create_bitmap_ex method --- engines/ags/lib/allegro/gfx.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 672b3b4fa12f..5e09aba5f3da 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -88,6 +88,9 @@ BITMAP *create_bitmap_ex(int color_depth, int width, int height) { Graphics::PixelFormat format; switch (color_depth) { + case 8: + format = Graphics::PixelFormat::createFormatCLUT8(); + break; case 16: format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); break; From 0b9e7f6fc49a743a78074a591c506e654186fb82 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 5 Jan 2021 18:51:28 -0800 Subject: [PATCH 084/215] AGS: Initialize screen with the needed resolution --- engines/ags/engine/gfx/ali3dogl.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp index 6c74ecc51829..9ea547a8e709 100644 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ b/engines/ags/engine/gfx/ali3dogl.cpp @@ -35,6 +35,7 @@ #include "ags/shared/util/math.h" #include "ags/engine/ac/timer.h" #include "ags/ags.h" +#include "engines/util.h" namespace AGS3 { @@ -540,7 +541,11 @@ void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { } #endif -#if !AGS_PLATFORM_SCUMMVM +#if AGS_PLATFORM_SCUMMVM + assert(mode.ColorDepth == 32); + const Graphics::PixelFormat PIXEL_FORMAT(4, 8, 8, 8, 8, 24, 16, 8, 0); + initGraphics(mode.Width, mode.Height, &PIXEL_FORMAT); +#else #if AGS_PLATFORM_OS_LINUX if (GLAD_GLX_EXT_swap_control) { glXSwapIntervalEXT(_xwin.display, _xwin.window, interval); @@ -577,7 +582,7 @@ void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) { #if AGS_PLATFORM_SCUMMVM - warning("TODO: CreateGlContext"); + // TODO: Do we need to do anything here #elif AGS_PLATFORM_OS_WINDOWS PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), From f029e6ffe181003a29c81831045e77fc20d1eb96 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Jan 2021 17:51:45 -0800 Subject: [PATCH 085/215] AGS: Fix returning GetColorDepth for paletted surfaces --- engines/ags/shared/gfx/allegrobitmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 3b04c369eb71..76ba4ec5960e 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -105,7 +105,7 @@ class Bitmap { return Size(_alBitmap->w, _alBitmap->h); } inline int GetColorDepth() const { - return _alBitmap->format.bpp(); + return (_alBitmap->format.bytesPerPixel == 1) ? 8 : _alBitmap->format.bpp(); } // BPP: bytes per pixel inline int GetBPP() const { From 72500fe5470da2f5efd75078630f8ee05f87499e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Jan 2021 19:50:44 -0800 Subject: [PATCH 086/215] AGS: Switch to using software graphics driver --- engines/ags/engine/gfx/ali3dogl.cpp | 1913 ------------------- engines/ags/engine/gfx/ali3dogl.h | 378 ---- engines/ags/engine/gfx/gfxdriverfactory.cpp | 9 +- engines/ags/module.mk | 1 - 4 files changed, 1 insertion(+), 2300 deletions(-) delete mode 100644 engines/ags/engine/gfx/ali3dogl.cpp delete mode 100644 engines/ags/engine/gfx/ali3dogl.h diff --git a/engines/ags/engine/gfx/ali3dogl.cpp b/engines/ags/engine/gfx/ali3dogl.cpp deleted file mode 100644 index 9ea547a8e709..000000000000 --- a/engines/ags/engine/gfx/ali3dogl.cpp +++ /dev/null @@ -1,1913 +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. - * - */ - -#include "ags/shared/core/platform.h" - -#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX - -#include "ags/lib/std/algorithm.h" -#include "ags/engine/gfx/ali3dexception.h" -#include "ags/engine/gfx/ali3dogl.h" -#include "ags/engine/gfx/gfxfilter_ogl.h" -#include "ags/engine/gfx/gfxfilter_aaogl.h" -#include "ags/engine/gfx/gfx_util.h" -#include "ags/engine/main/main_allegro.h" -#include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/shared/util/math.h" -#include "ags/engine/ac/timer.h" -#include "ags/ags.h" -#include "engines/util.h" - -namespace AGS3 { - -#if AGS_PLATFORM_OS_ANDROID - -#define glOrtho glOrthof -#define GL_CLAMP GL_CLAMP_TO_EDGE - -// Defined in Allegro -extern "C" -{ - void android_swap_buffers(); - void android_create_screen(int width, int height, int color_depth); - void android_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); -} - -extern "C" void android_debug_printf(char *format, ...); - -extern unsigned int android_screen_physical_width; -extern unsigned int android_screen_physical_height; -extern int android_screen_initialized; - -#define device_screen_initialized android_screen_initialized -#define device_mouse_setup android_mouse_setup -#define device_swap_buffers android_swap_buffers - -const char *fbo_extension_string = "GL_OES_framebuffer_object"; - -#define glGenFramebuffersEXT glGenFramebuffersOES -#define glDeleteFramebuffersEXT glDeleteFramebuffersOES -#define glBindFramebufferEXT glBindFramebufferOES -#define glCheckFramebufferStatusEXT glCheckFramebufferStatusOES -#define glGetFramebufferAttachmentParameterivEXT glGetFramebufferAttachmentParameterivOES -#define glGenerateMipmapEXT glGenerateMipmapOES -#define glFramebufferTexture2DEXT glFramebufferTexture2DOES -#define glFramebufferRenderbufferEXT glFramebufferRenderbufferOES -// TODO: probably should use EGL and function eglSwapInterval on Android to support setting swap interval -// For now this is a dummy function pointer which is only used to test that function is not supported -const void (*glSwapIntervalEXT)(int) = NULL; - -#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES -#define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES - -#elif AGS_PLATFORM_OS_IOS - -extern "C" -{ - void ios_swap_buffers(); - void ios_select_buffer(); - void ios_create_screen(); - float get_device_scale(); - void ios_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y); -} - -#define glOrtho glOrthof -#define GL_CLAMP GL_CLAMP_TO_EDGE - -extern unsigned int ios_screen_physical_width; -extern unsigned int ios_screen_physical_height; -extern int ios_screen_initialized; - -#define device_screen_initialized ios_screen_initialized -#define device_mouse_setup ios_mouse_setup -#define device_swap_buffers ios_swap_buffers - -const char *fbo_extension_string = "GL_OES_framebuffer_object"; - -#define glGenFramebuffersEXT glGenFramebuffersOES -#define glDeleteFramebuffersEXT glDeleteFramebuffersOES -#define glBindFramebufferEXT glBindFramebufferOES -#define glCheckFramebufferStatusEXT glCheckFramebufferStatusOES -#define glGetFramebufferAttachmentParameterivEXT glGetFramebufferAttachmentParameterivOES -#define glGenerateMipmapEXT glGenerateMipmapOES -#define glFramebufferTexture2DEXT glFramebufferTexture2DOES -#define glFramebufferRenderbufferEXT glFramebufferRenderbufferOES -// TODO: find out how to support swap interval setting on iOS -// For now this is a dummy function pointer which is only used to test that function is not supported -const void (*glSwapIntervalEXT)(int) = NULL; - -#define GL_FRAMEBUFFER_EXT GL_FRAMEBUFFER_OES -#define GL_COLOR_ATTACHMENT0_EXT GL_COLOR_ATTACHMENT0_OES - -#endif - -// Necessary to update textures from 8-bit bitmaps -extern RGB palette[256]; - - -namespace AGS { -namespace Engine { -namespace OGL { - -using namespace AGS::Shared; - -void ogl_dummy_vsync() { } - -#define GFX_OPENGL AL_ID('O','G','L',' ') - -static const char *empty_string = ""; - -GFX_DRIVER gfx_opengl = { - GFX_OPENGL, - empty_string, - empty_string, - "OpenGL", - nullptr, // init - nullptr, // exit - nullptr, // AL_METHOD(int, scroll, (int x, int y)); - ogl_dummy_vsync, // vsync - nullptr, // setpalette - nullptr, // AL_METHOD(int, request_scroll, (int x, int y)); - nullptr, // AL_METHOD(int, poll_scroll, (void)); - nullptr, // AL_METHOD(void, enable_triple_buffer, (void)); - nullptr, //create_video_bitmap - nullptr, //destroy_video_bitmap - nullptr, //show_video_bitmap - nullptr, - nullptr, //gfx_directx_create_system_bitmap, - nullptr, //gfx_directx_destroy_system_bitmap, - nullptr, //gfx_directx_set_mouse_sprite, - nullptr, //gfx_directx_show_mouse, - nullptr, //gfx_directx_hide_mouse, - nullptr, //gfx_directx_move_mouse, - nullptr, // AL_METHOD(void, drawing_mode, (void)); - nullptr, // AL_METHOD(void, save_video_state, (void*)); - nullptr, // AL_METHOD(void, restore_video_state, (void*)); - nullptr, // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); - nullptr, // AL_METHOD(int, fetch_mode_list, (void)); - 0, 0, // int w, h; - FALSE, // int linear; - 0, // long bank_size; - 0, // long bank_gran; - 0, // long vid_mem; - 0, // long vid_phys_base; - TRUE // int windowed; -}; - -void OGLBitmap::Dispose() { - if (_tiles != nullptr) { - for (int i = 0; i < _numTiles; i++) - glDeleteTextures(1, &(_tiles[i].texture)); - - free(_tiles); - _tiles = nullptr; - _numTiles = 0; - } - if (_vertex != nullptr) { - free(_vertex); - _vertex = nullptr; - } -} - - -OGLGraphicsDriver::ShaderProgram::ShaderProgram() : Program(0), SamplerVar(0), ColorVar(0), AuxVar(0) {} - - -OGLGraphicsDriver::OGLGraphicsDriver() { -#if AGS_PLATFORM_SCUMMVM - device_screen_physical_width = 640; - device_screen_physical_height = 480; - _glxContext = nullptr; - _have_window = false; -#elif AGS_PLATFORM_OS_WINDOWS - _hDC = NULL; - _hRC = NULL; - _hWnd = NULL; - _hInstance = NULL; - device_screen_physical_width = 0; - device_screen_physical_height = 0; -#elif AGS_PLATFORM_OS_LINUX - device_screen_physical_width = 0; - device_screen_physical_height = 0; - _glxContext = nullptr; - _have_window = false; -#elif AGS_PLATFORM_OS_ANDROID - device_screen_physical_width = android_screen_physical_width; - device_screen_physical_height = android_screen_physical_height; -#elif AGS_PLATFORM_OS_IOS - device_screen_physical_width = ios_screen_physical_width; - device_screen_physical_height = ios_screen_physical_height; -#endif - - _firstTimeInit = false; - _backbuffer = 0; - _fbo = 0; - _legacyPixelShader = false; - _can_render_to_texture = false; - _do_render_to_texture = false; - _super_sampling = 1; - SetupDefaultVertices(); - - // Shifts comply to GL_RGBA - _vmem_r_shift_32 = 0; - _vmem_g_shift_32 = 8; - _vmem_b_shift_32 = 16; - _vmem_a_shift_32 = 24; -} - - -void OGLGraphicsDriver::SetupDefaultVertices() { - std::fill(_backbuffer_vertices, _backbuffer_vertices + sizeof(_backbuffer_vertices) / sizeof(GLfloat), 0.0f); - std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); - - defaultVertices[0].position.x = 0.0f; - defaultVertices[0].position.y = 0.0f; - defaultVertices[0].tu = 0.0; - defaultVertices[0].tv = 0.0; - - defaultVertices[1].position.x = 1.0f; - defaultVertices[1].position.y = 0.0f; - defaultVertices[1].tu = 1.0; - defaultVertices[1].tv = 0.0; - - defaultVertices[2].position.x = 0.0f; - defaultVertices[2].position.y = -1.0f; - defaultVertices[2].tu = 0.0; - defaultVertices[2].tv = 1.0; - - defaultVertices[3].position.x = 1.0f; - defaultVertices[3].position.y = -1.0f; - defaultVertices[3].tu = 1.0; - defaultVertices[3].tv = 1.0; -} - -#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX - -void OGLGraphicsDriver::CreateDesktopScreen(int width, int height, int depth) { - device_screen_physical_width = width; - device_screen_physical_height = height; -} - -#elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - -void OGLGraphicsDriver::UpdateDeviceScreen() { -#if AGS_PLATFORM_OS_ANDROID - device_screen_physical_width = android_screen_physical_width; - device_screen_physical_height = android_screen_physical_height; -#elif AGS_PLATFORM_OS_IOS - device_screen_physical_width = ios_screen_physical_width; - device_screen_physical_height = ios_screen_physical_height; -#endif - - Debug::Printf("OGL: notified of device screen updated to %d x %d, resizing viewport", device_screen_physical_width, device_screen_physical_height); - _mode.Width = device_screen_physical_width; - _mode.Height = device_screen_physical_height; - InitGlParams(_mode); - if (_initSurfaceUpdateCallback) - _initSurfaceUpdateCallback(); -} - -#endif - -void OGLGraphicsDriver::Vsync() { - // do nothing on OpenGL -} - -void OGLGraphicsDriver::RenderSpritesAtScreenResolution(bool enabled, int supersampling) { - if (_can_render_to_texture) { - _do_render_to_texture = !enabled; - _super_sampling = supersampling; - TestSupersampling(); - } - - if (_do_render_to_texture) - glDisable(GL_SCISSOR_TEST); -} - -bool OGLGraphicsDriver::IsModeSupported(const DisplayMode &mode) { - if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) { - set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); - return false; - } - return true; -} - -bool OGLGraphicsDriver::SupportsGammaControl() { - return false; -} - -void OGLGraphicsDriver::SetGamma(int newGamma) { -} - -void OGLGraphicsDriver::SetGraphicsFilter(POGLFilter filter) { - _filter = filter; - OnSetFilter(); -} - -void OGLGraphicsDriver::SetTintMethod(TintMethod method) { - _legacyPixelShader = (method == TintReColourise); -} - -void OGLGraphicsDriver::FirstTimeInit() { - String ogl_v_str; -#ifdef GLAPI - ogl_v_str.Format("%d.%d", GLVersion.major, GLVersion.minor); -#else - ogl_v_str = (const char *)glGetString(GL_VERSION); -#endif - Debug::Printf(kDbgMsg_Info, "Running OpenGL: %s", ogl_v_str.GetCStr()); - - // Initialize default sprite batch, it will be used when no other batch was activated - OGLGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); - - TestRenderToTexture(); - CreateShaders(); - _firstTimeInit = true; -} - -#if !AGS_PLATFORM_SCUMMVM -#if AGS_PLATFORM_OS_LINUX -Atom get_x_atom(const char *atom_name) { - Atom atom = XInternAtom(_xwin.display, atom_name, False); - if (atom == None) { - Debug::Printf(kDbgMsg_Error, "ERROR: X11 atom \"%s\" not found.\n", atom_name); - } - return atom; -} -#endif -#endif - -bool OGLGraphicsDriver::InitGlScreen(const DisplayMode &mode) { -#if AGS_PLATFORM_OS_ANDROID - android_create_screen(mode.Width, mode.Height, mode.ColorDepth); -#elif AGS_PLATFORM_OS_IOS - ios_create_screen(); - ios_select_buffer(); -#elif AGS_PLATFORM_OS_WINDOWS - if (mode.Windowed) { - platform->AdjustWindowStyleForWindowed(); - } else { - if (platform->EnterFullscreenMode(mode)) - platform->AdjustWindowStyleForFullscreen(); - } - - // NOTE: adjust_window may leave task bar visible, so we do not use it for fullscreen mode - if (mode.Windowed && adjust_window(mode.Width, mode.Height) != 0) { - set_allegro_error("Window size not supported"); - return false; - } - - _hWnd = win_get_window(); - if (!(_hDC = GetDC(_hWnd))) - return false; - - // First check if we need to recreate GL context, this will only be - // required if different color depth is requested. - if (_hRC) { - GLuint pixel_fmt = GetPixelFormat(_hDC); - PIXELFORMATDESCRIPTOR pfd; - DescribePixelFormat(_hDC, pixel_fmt, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - if (pfd.cColorBits != mode.ColorDepth) { - DeleteGlContext(); - } - } - - if (!_hRC) { - if (!CreateGlContext(mode)) - return false; - } - - if (!gladLoadWGL(_hDC)) { - Debug::Printf(kDbgMsg_Error, "Failed to load WGL."); - return false; - } - - if (!gladLoadGL()) { - Debug::Printf(kDbgMsg_Error, "Failed to load GL."); - return false; - } - - CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); - win_grab_input(); -#elif AGS_PLATFORM_SCUMMVM - warning("TODO: InitGlScreen"); - -#elif AGS_PLATFORM_OS_LINUX - if (!_have_window) { - // Use Allegro to create our window. We don't care what size Allegro uses - // here, we will set that ourselves below by manipulating members of - // Allegro's_xwin structure. We need to use the Allegro routine here (rather - // than create our own X window) to remain compatible with Allegro's mouse & - // keyboard handling. - // - // Note that although _xwin contains a special "fullscreen" Window member - // (_xwin.fs_window), we do not use it for going fullscreen. Instead we ask - // the window manager to take the "managed" Window (_xwin.wm_window) - // fullscreen for us. All drawing goes to the "real" Window (_xwin.window). - if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 0, 0, 0, 0) != 0) - return false; - _have_window = true; - } - - if (!gladLoadGLX(_xwin.display, DefaultScreen(_xwin.display))) { - Debug::Printf(kDbgMsg_Error, "Failed to load GLX."); - return false; - } - - if (!_glxContext && !CreateGlContext(mode)) - return false; - - if (!gladLoadGL()) { - Debug::Printf(kDbgMsg_Error, "Failed to load GL."); - return false; - } - - { - // Set the size of our "managed" window. - XSizeHints *hints = XAllocSizeHints(); - - if (hints) { - if (mode.Windowed) { - // Set a fixed-size window. This is copied from Allegro 4's - // _xwin_private_create_screen(). - hints->flags = PMinSize | PMaxSize | PBaseSize; - hints->min_width = hints->max_width = hints->base_width = mode.Width; - hints->min_height = hints->max_height = hints->base_height = mode.Height; - } else { - // Clear any previously set demand for a fixed-size window, otherwise - // the window manager will ignore our request to go full-screen. - hints->flags = 0; - } - - XSetWMNormalHints(_xwin.display, _xwin.wm_window, hints); - } - - XFree(hints); - } - - // Set the window we are actually drawing into to the desired size. - XResizeWindow(_xwin.display, _xwin.window, mode.Width, mode.Height); - - // Make Allegro aware of the new window size, otherwise the mouse cursor - // movement may be erratic. - _xwin.window_width = mode.Width; - _xwin.window_height = mode.Height; - - { - // Ask the window manager to add (or remove) the "fullscreen" property on - // our top-level window. - const Atom wm_state = get_x_atom("_NET_WM_STATE"); - const Atom fullscreen = get_x_atom("_NET_WM_STATE_FULLSCREEN"); - const long remove_property = 0; - const long add_property = 1; - - XEvent xev; - memset(&xev, 0, sizeof(xev)); - xev.type = ClientMessage; - xev.xclient.window = _xwin.wm_window; - xev.xclient.message_type = wm_state; - xev.xclient.format = 32; - xev.xclient.data.l[0] = mode.Windowed ? remove_property : add_property; - xev.xclient.data.l[1] = fullscreen; - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 1; // Message source is a regular application. - Status status = XSendEvent(_xwin.display, DefaultRootWindow(_xwin.display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); - if (status == 0) { - Debug::Printf(kDbgMsg_Error, "ERROR: Failed to encode window state message.\n"); - } - } - - CreateDesktopScreen(mode.Width, mode.Height, mode.ColorDepth); -#endif - - gfx_driver = &gfx_opengl; - return true; -} - -void OGLGraphicsDriver::InitGlParams(const DisplayMode &mode) { - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glShadeModel(GL_FLAT); - - glEnable(GL_TEXTURE_2D); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, device_screen_physical_width, device_screen_physical_height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, device_screen_physical_width, 0, device_screen_physical_height, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - -#if !AGS_PLATFORM_SCUMMVM - auto interval = mode.Vsync ? 1 : 0; -#endif - bool vsyncEnabled = false; - -#if AGS_PLATFORM_OS_WINDOWS - if (GLAD_WGL_EXT_swap_control) { - vsyncEnabled = wglSwapIntervalEXT(interval) != FALSE; - } -#endif - -#if AGS_PLATFORM_SCUMMVM - assert(mode.ColorDepth == 32); - const Graphics::PixelFormat PIXEL_FORMAT(4, 8, 8, 8, 8, 24, 16, 8, 0); - initGraphics(mode.Width, mode.Height, &PIXEL_FORMAT); -#else -#if AGS_PLATFORM_OS_LINUX - if (GLAD_GLX_EXT_swap_control) { - glXSwapIntervalEXT(_xwin.display, _xwin.window, interval); - // glx requires hooking into XSetErrorHandler to test for BadWindow or BadValue - vsyncEnabled = true; - } else if (GLAD_GLX_MESA_swap_control) { - vsyncEnabled = glXSwapIntervalMESA(interval) == 0; - } else if (GLAD_GLX_SGI_swap_control) { - vsyncEnabled = glXSwapIntervalSGI(interval) == 0; - } -#endif -#endif - - // TODO: find out how to implement SwapInterval on other platforms, and how to check if it's supported - - if (mode.Vsync && !vsyncEnabled) { - Debug::Printf(kDbgMsg_Warn, "WARNING: Vertical sync could not be enabled. Setting will be kept at driver default."); - } - -#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - // Setup library mouse to have 1:1 coordinate transformation. - // NOTE: cannot move this call to general mouse handling mode. Unfortunately, much of the setup and rendering - // is duplicated in the Android/iOS ports' Allegro library patches, and is run when the Software renderer - // is selected in AGS. This ugly situation causes trouble... - float device_scale = 1.0f; - -#if AGS_PLATFORM_OS_IOS - device_scale = get_device_scale(); -#endif - - device_mouse_setup(0, device_screen_physical_width - 1, 0, device_screen_physical_height - 1, device_scale, device_scale); -#endif -} - -bool OGLGraphicsDriver::CreateGlContext(const DisplayMode &mode) { -#if AGS_PLATFORM_SCUMMVM - // TODO: Do we need to do anything here -#elif AGS_PLATFORM_OS_WINDOWS - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, - (BYTE)mode.ColorDepth, - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 0, - 0, - 0, - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - _oldPixelFormat = GetPixelFormat(_hDC); - DescribePixelFormat(_hDC, _oldPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &_oldPixelFormatDesc); - - GLuint pixel_fmt; - if (!(pixel_fmt = ChoosePixelFormat(_hDC, &pfd))) - return false; - - if (!SetPixelFormat(_hDC, pixel_fmt, &pfd)) - return false; - - if (!(_hRC = wglCreateContext(_hDC))) - return false; - - if (!wglMakeCurrent(_hDC, _hRC)) - return false; -#elif AGS_PLATFORM_OS_LINUX - int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; - XVisualInfo *vi = glXChooseVisual(_xwin.display, DefaultScreen(_xwin.display), attrib); - if (!vi) { - Debug::Printf(kDbgMsg_Error, "ERROR: glXChooseVisual() failed.\n"); - return false; - } - - if (!(_glxContext = glXCreateContext(_xwin.display, vi, None, True))) { - Debug::Printf(kDbgMsg_Error, "ERROR: glXCreateContext() failed.\n"); - return false; - } - - if (!glXMakeCurrent(_xwin.display, _xwin.window, _glxContext)) { - Debug::Printf(kDbgMsg_Error, "ERROR: glXMakeCurrent() failed.\n"); - return false; - } -#endif - return true; -} - -void OGLGraphicsDriver::DeleteGlContext() { -#if AGS_PLATFORM_SCUMMVM - warning("TODO: DeleteGlContext"); -#elif AGS_PLATFORM_OS_WINDOWS - if (_hRC) { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(_hRC); - _hRC = NULL; - } - - if (_oldPixelFormat > 0) - SetPixelFormat(_hDC, _oldPixelFormat, &_oldPixelFormatDesc); -#elif AGS_PLATFORM_OS_LINUX - if (_glxContext) { - glXMakeCurrent(_xwin.display, None, nullptr); - glXDestroyContext(_xwin.display, _glxContext); - _glxContext = nullptr; - } -#endif -} - -inline bool CanDoFrameBuffer() { -#ifdef GLAPI - return GLAD_GL_EXT_framebuffer_object != 0; -#else -#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - const char *fbo_extension_string = "GL_OES_framebuffer_object"; -#else - const char *fbo_extension_string = "GL_EXT_framebuffer_object"; -#endif - const char *extensions = (const char *)glGetString(GL_EXTENSIONS); - return extensions && strstr(extensions, fbo_extension_string) != NULL; -#endif -} - -void OGLGraphicsDriver::TestRenderToTexture() { - if (CanDoFrameBuffer()) { - _can_render_to_texture = true; - TestSupersampling(); - } else { - _can_render_to_texture = false; - Debug::Printf(kDbgMsg_Warn, "WARNING: OpenGL extension 'GL_EXT_framebuffer_object' not supported, rendering to texture mode will be disabled."); - } - - if (!_can_render_to_texture) - _do_render_to_texture = false; -} - -void OGLGraphicsDriver::TestSupersampling() { -#if !AGS_PLATFORM_SCUMMVM - if (!_can_render_to_texture) - return; - // Disable super-sampling if it would cause a too large texture size - if (_super_sampling > 1) { - int max = 1024; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); - if ((max < _srcRect.GetWidth() * _super_sampling) || (max < _srcRect.GetHeight() * _super_sampling)) - _super_sampling = 1; - } -#endif -} - -void OGLGraphicsDriver::CreateShaders() { - if (!GLAD_GL_VERSION_2_0) { - Debug::Printf(kDbgMsg_Error, "ERROR: Shaders require a minimum of OpenGL 2.0 support."); - return; - } - CreateTintShader(); - CreateLightShader(); -} - -void OGLGraphicsDriver::CreateTintShader() { - const char *fragment_shader_src = - // NOTE: this shader emulates "historical" AGS software tinting; it is not - // necessarily "proper" tinting in modern terms. - // The RGB-HSV-RGB conversion found in the Internet (copyright unknown); - // Color processing is replicated from Direct3D shader by Chris Jones - // (Engine/resource/tintshaderLegacy.fx). - // Uniforms: - // textID - texture index (usually 0), - // tintHSV - tint color in HSV, - // tintAmnTrsLum - tint parameters: amount, translucence (alpha), luminance. - "\ - #version 120\n\ - uniform sampler2D textID;\n\ - uniform vec3 tintHSV;\n\ - uniform vec3 tintAmnTrsLum;\n\ - \ - vec3 rgb2hsv(vec3 c)\n\ - {\n\ - vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n\ - vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n\ - vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n\ - \ - float d = q.x - min(q.w, q.y);\n\ - const float e = 1.0e-10;\n\ - return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n\ - }\n\ - \ - vec3 hsv2rgb(vec3 c)\n\ - {\n\ - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n\ - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n\ - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n\ - }\n\ - \ - float getValue(vec3 color)\n\ - {\n\ - float colorMax = max (color[0], color[1]);\n\ - colorMax = max (colorMax, color[2]);\n\ - return colorMax;\n\ - }\n\ - \ - void main()\n\ - {\n\ - vec4 src_col = texture2D(textID, gl_TexCoord[0].xy);\n\ - float amount = tintAmnTrsLum[0];\n\ - float lum = getValue(src_col.xyz);\n\ - lum = max(lum - (1.0 - tintAmnTrsLum[2]), 0.0);\n\ - vec3 new_col = (hsv2rgb(vec3(tintHSV[0], tintHSV[1], lum)) * amount + src_col.xyz * (1.0 - amount));\n\ - gl_FragColor = vec4(new_col, src_col.w * tintAmnTrsLum[1]);\n\ - }\n\ - "; - CreateShaderProgram(_tintShader, "Tinting", fragment_shader_src, "textID", "tintHSV", "tintAmnTrsLum"); -} - -void OGLGraphicsDriver::CreateLightShader() { - const char *fragment_shader_src = - // NOTE: due to how the lighting works in AGS, this is combined MODULATE / ADD shader. - // if the light is < 0, then MODULATE operation is used, otherwise ADD is used. - // NOTE: it's been said that using branching in shaders produces inefficient code. - // If that will ever become a real problem, we can easily split this shader in two. - // Uniforms: - // textID - texture index (usually 0), - // light - light level, - // alpha - color alpha value. - "\ - #version 120\n\ - uniform sampler2D textID;\n\ - uniform float light;\n\ - uniform float alpha;\n\ - \ - void main()\n\ - {\n\ - vec4 src_col = texture2D(textID, gl_TexCoord[0].xy);\n\ - if (light >= 0.0)\n\ - gl_FragColor = vec4(src_col.xyz + vec3(light, light, light), src_col.w * alpha);\n\ - else\n\ - gl_FragColor = vec4(src_col.xyz * abs(light), src_col.w * alpha);\n\ - }\n\ - "; - CreateShaderProgram(_lightShader, "Lighting", fragment_shader_src, "textID", "light", "alpha"); -} - -void OGLGraphicsDriver::CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, - const char *sampler_var, const char *color_var, const char *aux_var) { -#if !AGS_PLATFORM_SCUMMVM - GLint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment_shader, 1, &fragment_shader_src, nullptr); - glCompileShader(fragment_shader); - GLint result; - glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &result); - if (result == GL_FALSE) { - OutputShaderError(fragment_shader, String::FromFormat("%s program's fragment shader", name), true); - glDeleteShader(fragment_shader); - return; - } - - GLuint program = glCreateProgram(); - glAttachShader(program, fragment_shader); - glLinkProgram(program); - glGetProgramiv(program, GL_LINK_STATUS, &result); - if (result == GL_FALSE) { - OutputShaderError(program, String::FromFormat("%s program", name), false); - glDeleteProgram(program); - glDeleteShader(fragment_shader); - return; - } - glDetachShader(program, fragment_shader); - glDeleteShader(fragment_shader); - - prg.Program = program; - prg.SamplerVar = glGetUniformLocation(program, sampler_var); - prg.ColorVar = glGetUniformLocation(program, color_var); - prg.AuxVar = glGetUniformLocation(program, aux_var); - Debug::Printf("OGL: %s shader program created successfully", name); -#endif -} - -void OGLGraphicsDriver::DeleteShaderProgram(ShaderProgram &prg) { - if (prg.Program) - glDeleteProgram(prg.Program); - prg.Program = 0; -} - -void OGLGraphicsDriver::OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader) { -#ifdef TODO - GLint log_len; - if (is_shader) - glGetShaderiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); - else - glGetProgramiv(obj_id, GL_INFO_LOG_LENGTH, &log_len); - std::vector errorLog(log_len); - if (log_len > 0) { - if (is_shader) - glGetShaderInfoLog(obj_id, log_len, &log_len, &errorLog[0]); - else - glGetProgramInfoLog(obj_id, log_len, &log_len, &errorLog[0]); - } - - Debug::Printf(kDbgMsg_Error, "ERROR: OpenGL: %s %s:", obj_name.GetCStr(), is_shader ? "failed to compile" : "failed to link"); - if (errorLog.size() > 0) { - Debug::Printf(kDbgMsg_Error, "----------------------------------------"); - Debug::Printf(kDbgMsg_Error, "%s", &errorLog[0]); - Debug::Printf(kDbgMsg_Error, "----------------------------------------"); - } else { - Debug::Printf(kDbgMsg_Error, "Shader info log was empty."); - } -#else - error("Obj Id=%u, Name=%s, Is Shader=%d", obj_id, obj_name.GetNullableCStr(), (int)is_shader); -#endif -} - -void OGLGraphicsDriver::SetupBackbufferTexture() { - // NOTE: ability to render to texture depends on OGL context, which is - // created in SetDisplayMode, therefore creation of textures require - // both native size set and context capabilities test passed. - if (!IsNativeSizeValid() || !_can_render_to_texture) - return; -#if !AGS_PLATFORM_SCUMMVM - DeleteBackbufferTexture(); - - // _backbuffer_texture_coordinates defines translation from wanted texture size to actual supported texture size - _backRenderSize = _srcRect.GetSize() * _super_sampling; - _backTextureSize = _backRenderSize; - AdjustSizeToNearestSupportedByCard(&_backTextureSize.Width, &_backTextureSize.Height); - const float back_ratio_w = (float)_backRenderSize.Width / (float)_backTextureSize.Width; - const float back_ratio_h = (float)_backRenderSize.Height / (float)_backTextureSize.Height; - std::fill(_backbuffer_texture_coordinates, _backbuffer_texture_coordinates + sizeof(_backbuffer_texture_coordinates) / sizeof(GLfloat), 0.0f); - _backbuffer_texture_coordinates[2] = _backbuffer_texture_coordinates[6] = back_ratio_w; - _backbuffer_texture_coordinates[5] = _backbuffer_texture_coordinates[7] = back_ratio_h; - - glGenTextures(1, &_backbuffer); - glBindTexture(GL_TEXTURE_2D, _backbuffer); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backTextureSize.Width, _backTextureSize.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glBindTexture(GL_TEXTURE_2D, 0); - - glGenFramebuffersEXT(1, &_fbo); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _backbuffer, 0); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -#endif - // Assign vertices of the backbuffer texture position in the scene - _backbuffer_vertices[0] = _backbuffer_vertices[4] = 0; - _backbuffer_vertices[2] = _backbuffer_vertices[6] = _srcRect.GetWidth(); - _backbuffer_vertices[5] = _backbuffer_vertices[7] = _srcRect.GetHeight(); - _backbuffer_vertices[1] = _backbuffer_vertices[3] = 0; -} - -void OGLGraphicsDriver::DeleteBackbufferTexture() { - if (_backbuffer) - glDeleteTextures(1, &_backbuffer); - if (_fbo) - glDeleteFramebuffersEXT(1, &_fbo); - _backbuffer = 0; - _fbo = 0; -} - -void OGLGraphicsDriver::SetupViewport() { - if (!IsModeSet() || !IsRenderFrameValid()) - return; - - // Setup viewport rect and scissor - _viewportRect = ConvertTopDownRect(_dstRect, device_screen_physical_height); - glScissor(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); -} - -Rect OGLGraphicsDriver::ConvertTopDownRect(const Rect &rect, int surface_height) { - return RectWH(rect.Left, surface_height - 1 - rect.Bottom, rect.GetWidth(), rect.GetHeight()); -} - -bool OGLGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) { - ReleaseDisplayMode(); - - if (mode.ColorDepth < 15) { - set_allegro_error("OpenGL driver does not support 256-color display mode"); - return false; - } - -// try { - if (!InitGlScreen(mode)) - return false; - if (!_firstTimeInit) - FirstTimeInit(); - InitGlParams(mode); -/* } catch (Ali3DException exception) { - if (exception._message != get_allegro_error()) - set_allegro_error(exception._message); - return false; - }*/ - - OnInit(loopTimer); - - // On certain platforms OpenGL renderer ignores requested screen sizes - // and uses values imposed by the operating system (device). - DisplayMode final_mode = mode; - final_mode.Width = device_screen_physical_width; - final_mode.Height = device_screen_physical_height; - OnModeSet(final_mode); - - // If we already have a native size set, then update virtual screen and setup backbuffer texture immediately - CreateVirtualScreen(); - SetupBackbufferTexture(); - // If we already have a render frame configured, then setup viewport and backbuffer mappings immediately - SetupViewport(); - return true; -} - -void OGLGraphicsDriver::CreateVirtualScreen() { - if (!IsModeSet() || !IsNativeSizeValid()) - return; - // create initial stage screen for plugin raw drawing - _stageVirtualScreen = CreateStageScreen(0, _srcRect.GetSize()); - // we must set Allegro's screen pointer to **something** - screen = (BITMAP *)_stageVirtualScreen->GetAllegroBitmap(); -} - -bool OGLGraphicsDriver::SetNativeSize(const Size &src_size) { - OnSetNativeSize(src_size); - SetupBackbufferTexture(); - // If we already have a gfx mode set, then update virtual screen immediately - CreateVirtualScreen(); - TestSupersampling(); - return !_srcRect.IsEmpty(); -} - -bool OGLGraphicsDriver::SetRenderFrame(const Rect &dst_rect) { - if (!IsNativeSizeValid()) - return false; - OnSetRenderFrame(dst_rect); - // Also make sure viewport and backbuffer mappings are updated using new native & destination rectangles - SetupViewport(); - return !_dstRect.IsEmpty(); -} - -int OGLGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const { - // TODO: check for device caps to know which depth is supported? - return 32; -} - -IGfxModeList *OGLGraphicsDriver::GetSupportedModeList(int color_depth) { - std::vector modes; - platform->GetSystemDisplayModes(modes); - return new OGLDisplayModeList(modes); -} - -PGfxFilter OGLGraphicsDriver::GetGraphicsFilter() const { - return _filter; -} - -void OGLGraphicsDriver::ReleaseDisplayMode() { - if (!IsModeSet()) - return; - - OnModeReleased(); - ClearDrawLists(); - ClearDrawBackups(); - DeleteBackbufferTexture(); - DestroyFxPool(); - DestroyAllStageScreens(); - - gfx_driver = nullptr; - - platform->ExitFullscreenMode(); -} - -void OGLGraphicsDriver::UnInit() { - OnUnInit(); - ReleaseDisplayMode(); - - DeleteGlContext(); -#if AGS_PLATFORM_OS_WINDOWS - _hWnd = NULL; - _hDC = NULL; -#endif - - DeleteShaderProgram(_tintShader); - DeleteShaderProgram(_lightShader); -} - -OGLGraphicsDriver::~OGLGraphicsDriver() { - OGLGraphicsDriver::UnInit(); -} - -void OGLGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) { - // NOTE: this function is practically useless at the moment, because OGL redraws whole game frame each time -} - -bool OGLGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) { - (void)at_native_res; // TODO: support this at some point - - // TODO: following implementation currently only reads GL pixels in 32-bit RGBA. - // this **should** work regardless of actual display mode because OpenGL is - // responsible to convert and fill pixel buffer correctly. - // If you like to support writing directly into 16-bit bitmap, please take - // care of ammending the pixel reading code below. - const int read_in_colordepth = 32; - Size need_size = _do_render_to_texture ? _backRenderSize : _dstRect.GetSize(); - if (destination->GetColorDepth() != read_in_colordepth || destination->GetSize() != need_size) { - if (want_fmt) - *want_fmt = GraphicResolution(need_size.Width, need_size.Height, read_in_colordepth); - return false; - } - - Rect retr_rect; - if (_do_render_to_texture) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); - retr_rect = RectWH(0, 0, _backRenderSize.Width, _backRenderSize.Height); - } else { -#if AGS_PLATFORM_OS_IOS - ios_select_buffer(); -#elif AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX - glReadBuffer(GL_FRONT); -#endif - retr_rect = _dstRect; - } - - int bpp = read_in_colordepth / 8; - int bufferSize = retr_rect.GetWidth() * retr_rect.GetHeight() * bpp; - - unsigned char *buffer = new unsigned char[bufferSize]; - if (buffer) { - glReadPixels(retr_rect.Left, retr_rect.Top, retr_rect.GetWidth(), retr_rect.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buffer); - - unsigned char *sourcePtr = buffer; - for (int y = destination->GetHeight() - 1; y >= 0; y--) { - unsigned int *destPtr = reinterpret_cast(&destination->GetScanLineForWriting(y)[0]); - for (int dx = 0, sx = 0; dx < destination->GetWidth(); ++dx, sx = dx * bpp) { - destPtr[dx] = makeacol32(sourcePtr[sx + 0], sourcePtr[sx + 1], sourcePtr[sx + 2], sourcePtr[sx + 3]); - } - sourcePtr += retr_rect.GetWidth() * bpp; - } - - if (_pollingCallback) - _pollingCallback(); - - delete [] buffer; - } - return true; -} - -void OGLGraphicsDriver::RenderToBackBuffer() { - error("OGL driver does not have a back buffer"); -} - -void OGLGraphicsDriver::Render() { - Render(0, 0, kFlip_None); -} - -void OGLGraphicsDriver::Render(int /*xoff*/, int /*yoff*/, GlobalFlipType /*flip*/) { - _render(true); -} - -void OGLGraphicsDriver::_reDrawLastFrame() { - RestoreDrawLists(); -} - -void OGLGraphicsDriver::_renderSprite(const OGLDrawListEntry *drawListEntry, const GLMATRIX &matGlobal) { - OGLBitmap *bmpToDraw = drawListEntry->bitmap; - - if (bmpToDraw->_transparency >= 255) - return; - - const bool do_tint = bmpToDraw->_tintSaturation > 0 && _tintShader.Program > 0; - const bool do_light = bmpToDraw->_tintSaturation == 0 && bmpToDraw->_lightLevel > 0 && _lightShader.Program > 0; - if (do_tint) { - // Use tinting shader - glUseProgram(_tintShader.Program); - float rgb[3]; - float sat_trs_lum[3]; // saturation / transparency / luminance - if (_legacyPixelShader) { - rgb_to_hsv(bmpToDraw->_red, bmpToDraw->_green, bmpToDraw->_blue, &rgb[0], &rgb[1], &rgb[2]); - rgb[0] /= 360.0; // In HSV, Hue is 0-360 - } else { - rgb[0] = (float)bmpToDraw->_red / 255.0; - rgb[1] = (float)bmpToDraw->_green / 255.0; - rgb[2] = (float)bmpToDraw->_blue / 255.0; - } - - sat_trs_lum[0] = (float)bmpToDraw->_tintSaturation / 255.0; - - if (bmpToDraw->_transparency > 0) - sat_trs_lum[1] = (float)bmpToDraw->_transparency / 255.0; - else - sat_trs_lum[1] = 1.0f; - - if (bmpToDraw->_lightLevel > 0) - sat_trs_lum[2] = (float)bmpToDraw->_lightLevel / 255.0; - else - sat_trs_lum[2] = 1.0f; - - glUniform1i(_tintShader.SamplerVar, 0); - glUniform3f(_tintShader.ColorVar, rgb[0], rgb[1], rgb[2]); - glUniform3f(_tintShader.AuxVar, sat_trs_lum[0], sat_trs_lum[1], sat_trs_lum[2]); - } else if (do_light) { - // Use light shader - glUseProgram(_lightShader.Program); - float light_lev = 1.0f; - float alpha = 1.0f; - - // Light level parameter in DDB is weird, it is measured in units of - // 1/255 (although effectively 1/250, see draw.cpp), but contains two - // ranges: 1-255 is darker range and 256-511 is brighter range. - // (light level of 0 means "default color") - if ((bmpToDraw->_lightLevel > 0) && (bmpToDraw->_lightLevel < 256)) { - // darkening the sprite... this stupid calculation is for - // consistency with the allegro software-mode code that does - // a trans blend with a (8,8,8) sprite - light_lev = -((bmpToDraw->_lightLevel * 192) / 256 + 64) / 255.f; // darker, uses MODULATE op - } else if (bmpToDraw->_lightLevel > 256) { - light_lev = ((bmpToDraw->_lightLevel - 256) / 2) / 255.f; // brighter, uses ADD op - } - - if (bmpToDraw->_transparency > 0) - alpha = bmpToDraw->_transparency / 255.f; - - glUniform1i(_lightShader.SamplerVar, 0); - glUniform1f(_lightShader.ColorVar, light_lev); - glUniform1f(_lightShader.AuxVar, alpha); - } else { - // Use default processing - if (bmpToDraw->_transparency == 0) - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - else - glColor4f(1.0f, 1.0f, 1.0f, bmpToDraw->_transparency / 255.0f); - } - - float width = bmpToDraw->GetWidthToRender(); - float height = bmpToDraw->GetHeightToRender(); - float xProportion = (float)width / (float)bmpToDraw->_width; - float yProportion = (float)height / (float)bmpToDraw->_height; - int drawAtX = drawListEntry->x; - int drawAtY = drawListEntry->y; - - for (int ti = 0; ti < bmpToDraw->_numTiles; ti++) { - width = bmpToDraw->_tiles[ti].width * xProportion; - height = bmpToDraw->_tiles[ti].height * yProportion; - float xOffs; - float yOffs = bmpToDraw->_tiles[ti].y * yProportion; - if (bmpToDraw->_flipped) - xOffs = (bmpToDraw->_width - (bmpToDraw->_tiles[ti].x + bmpToDraw->_tiles[ti].width)) * xProportion; - else - xOffs = bmpToDraw->_tiles[ti].x * xProportion; - int thisX = drawAtX + xOffs; - int thisY = drawAtY + yOffs; - thisX = (-(_srcRect.GetWidth() / 2)) + thisX; - thisY = (_srcRect.GetHeight() / 2) - thisY; - - //Setup translation and scaling matrices - float widthToScale = (float)width; - float heightToScale = (float)height; - if (bmpToDraw->_flipped) { - // The usual transform changes 0..1 into 0..width - // So first negate it (which changes 0..w into -w..0) - widthToScale = -widthToScale; - // and now shift it over to make it 0..w again - thisX += width; - } - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // - // IMPORTANT: in OpenGL order of transformation is REVERSE to the order of commands! - // - // Origin is at the middle of the surface - if (_do_render_to_texture) - glTranslatef(_backRenderSize.Width / 2.0f, _backRenderSize.Height / 2.0f, 0.0f); - else - glTranslatef(_srcRect.GetWidth() / 2.0f, _srcRect.GetHeight() / 2.0f, 0.0f); - - // Global batch transform - glMultMatrixf(matGlobal.m); - // Self sprite transform (first scale, then rotate and then translate, reversed) - glTranslatef((float)thisX, (float)thisY, 0.0f); - glRotatef(0.f, 0.f, 0.f, 1.f); - glScalef(widthToScale, heightToScale, 1.0f); - - glBindTexture(GL_TEXTURE_2D, bmpToDraw->_tiles[ti].texture); - - if ((_smoothScaling) && bmpToDraw->_useResampler && (bmpToDraw->_stretchToHeight > 0) && - ((bmpToDraw->_stretchToHeight != bmpToDraw->_height) || - (bmpToDraw->_stretchToWidth != bmpToDraw->_width))) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else if (_do_render_to_texture) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } else { - _filter->SetFilteringForStandardSprite(); - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - if (bmpToDraw->_vertex != nullptr) { - glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].tu)); - glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &(bmpToDraw->_vertex[ti * 4].position)); - } else { - glTexCoordPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].tu); - glVertexPointer(2, GL_FLOAT, sizeof(OGLCUSTOMVERTEX), &defaultVertices[0].position); - } - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - } - glUseProgram(0); -} - -void OGLGraphicsDriver::_render(bool clearDrawListAfterwards) { -#if AGS_PLATFORM_OS_IOS - ios_select_buffer(); -#endif - -#if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - // TODO: - // For some reason, mobile ports initialize actual display size after a short delay. - // This is why we update display mode and related parameters (projection, viewport) - // at the first render pass. - // Ofcourse this is not a good thing, ideally the display size should be made - // known before graphic mode is initialized. This would require analysis and rewrite - // of the platform-specific part of the code (Java app for Android / XCode for iOS). - if (!device_screen_initialized) { - UpdateDeviceScreen(); - device_screen_initialized = 1; - } -#endif - - if (_do_render_to_texture) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo); - - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, _backRenderSize.Width, _backRenderSize.Height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, _backRenderSize.Width, 0, _backRenderSize.Height, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - } else { - glDisable(GL_SCISSOR_TEST); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); - - glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - } - - RenderSpriteBatches(); - - if (_do_render_to_texture) { - // Texture is ready, now create rectangle in the world space and draw texture upon it -#if AGS_PLATFORM_OS_IOS - ios_select_buffer(); -#else - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -#endif - - glViewport(_viewportRect.Left, _viewportRect.Top, _viewportRect.GetWidth(), _viewportRect.GetHeight()); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, _srcRect.GetWidth(), 0, _srcRect.GetHeight(), 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glDisable(GL_BLEND); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - // use correct sampling method when stretching buffer to the final rect - _filter->SetFilteringForStandardSprite(); - - glBindTexture(GL_TEXTURE_2D, _backbuffer); - - glTexCoordPointer(2, GL_FLOAT, 0, _backbuffer_texture_coordinates); - glVertexPointer(2, GL_FLOAT, 0, _backbuffer_vertices); - glClear(GL_COLOR_BUFFER_BIT); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glEnable(GL_BLEND); - } - - glFinish(); - -#if AGS_PLATFORM_SCUMMVM - g_system->updateScreen(); -#elif AGS_PLATFORM_OS_WINDOWS - SwapBuffers(_hDC); -#elif AGS_PLATFORM_OS_LINUX - glXSwapBuffers(_xwin.display, _xwin.window); -#elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - device_swap_buffers(); -#endif - - if (clearDrawListAfterwards) { - BackupDrawLists(); - ClearDrawLists(); - } - ResetFxPool(); -} - -void OGLGraphicsDriver::RenderSpriteBatches() { - // Render all the sprite batches with necessary transformations - Rect main_viewport = _do_render_to_texture ? _srcRect : _viewportRect; - int surface_height = _do_render_to_texture ? _srcRect.GetHeight() : device_screen_physical_height; - // TODO: see if it's possible to refactor and not enable/disable scissor test - // TODO: also maybe sync scissor code logic with D3D renderer - if (_do_render_to_texture) - glEnable(GL_SCISSOR_TEST); - - for (size_t i = 0; i <= _actSpriteBatch; ++i) { - const Rect &viewport = _spriteBatches[i].Viewport; - const OGLSpriteBatch &batch = _spriteBatches[i]; - if (!viewport.IsEmpty()) { - Rect scissor = _do_render_to_texture ? viewport : _scaling.ScaleRange(viewport); - scissor = ConvertTopDownRect(scissor, surface_height); - glScissor(scissor.Left, scissor.Top, scissor.GetWidth(), scissor.GetHeight()); - } else { - glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); - } - _stageVirtualScreen = GetStageScreen(i); - RenderSpriteBatch(batch); - } - - _stageVirtualScreen = GetStageScreen(0); - glScissor(main_viewport.Left, main_viewport.Top, main_viewport.GetWidth(), main_viewport.GetHeight()); - if (_do_render_to_texture) - glDisable(GL_SCISSOR_TEST); -} - -void OGLGraphicsDriver::RenderSpriteBatch(const OGLSpriteBatch &batch) { - OGLDrawListEntry stageEntry; // raw-draw plugin support - - const std::vector &listToDraw = batch.List; - for (size_t i = 0; i < listToDraw.size(); i++) { - if (listToDraw[i].skip) - continue; - - const OGLDrawListEntry *sprite = &listToDraw[i]; - if (listToDraw[i].bitmap == nullptr) { - if (DoNullSpriteCallback(listToDraw[i].x, listToDraw[i].y)) - stageEntry = OGLDrawListEntry((OGLBitmap *)_stageVirtualScreenDDB); - else - continue; - sprite = &stageEntry; - } - - this->_renderSprite(sprite, batch.Matrix); - } -} - -void OGLGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) { - if (_spriteBatches.size() <= index) - _spriteBatches.resize(index + 1); - _spriteBatches[index].List.clear(); - - Rect orig_viewport = desc.Viewport; - Rect node_viewport = desc.Viewport; - // Combine both world transform and viewport transform into one matrix for faster perfomance - // NOTE: in OpenGL order of transformation is REVERSE to the order of commands! - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - // Global node transformation (flip and offset) - int node_tx = desc.Offset.X, node_ty = desc.Offset.Y; - float node_sx = 1.f, node_sy = 1.f; - if ((desc.Flip == kFlip_Vertical) || (desc.Flip == kFlip_Both)) { - int left = _srcRect.GetWidth() - (orig_viewport.Right + 1); - node_viewport.MoveToX(left); - node_sx = -1.f; - } - if ((desc.Flip == kFlip_Horizontal) || (desc.Flip == kFlip_Both)) { - int top = _srcRect.GetHeight() - (orig_viewport.Bottom + 1); - node_viewport.MoveToY(top); - node_sy = -1.f; - } - _spriteBatches[index].Viewport = Rect::MoveBy(node_viewport, node_tx, node_ty); - glTranslatef(node_tx, -(node_ty), 0.0f); - glScalef(node_sx, node_sy, 1.f); - // NOTE: before node, translate to viewport position; remove this if this - // is changed to a separate operation at some point - // TODO: find out if this is an optimal way to translate scaled room into Top-Left screen coordinates - float scaled_offx = (_srcRect.GetWidth() - desc.Transform.ScaleX * (float)_srcRect.GetWidth()) / 2.f; - float scaled_offy = (_srcRect.GetHeight() - desc.Transform.ScaleY * (float)_srcRect.GetHeight()) / 2.f; - glTranslatef((float)(orig_viewport.Left - scaled_offx), (float) - (orig_viewport.Top - scaled_offy), 0.0f); - // IMPORTANT: while the sprites are usually transformed in the order of Scale-Rotate-Translate, - // the camera's transformation is essentially reverse world transformation. And the operations - // are inverse: Translate-Rotate-Scale (here they are double inverse because OpenGL). - glScalef(desc.Transform.ScaleX, desc.Transform.ScaleY, 1.f); // scale camera - glRotatef(Math::RadiansToDegrees(desc.Transform.Rotate), 0.f, 0.f, 1.f); // rotate camera - glTranslatef((float)desc.Transform.X, (float) - desc.Transform.Y, 0.0f); // translate camera - glGetFloatv(GL_MODELVIEW_MATRIX, _spriteBatches[index].Matrix.m); - glLoadIdentity(); - - // create stage screen for plugin raw drawing - int src_w = orig_viewport.GetWidth() / desc.Transform.ScaleX; - int src_h = orig_viewport.GetHeight() / desc.Transform.ScaleY; - CreateStageScreen(index, Size(src_w, src_h)); -} - -void OGLGraphicsDriver::ResetAllBatches() { - for (size_t i = 0; i < _spriteBatches.size(); ++i) - _spriteBatches[i].List.clear(); -} - -void OGLGraphicsDriver::ClearDrawBackups() { - _backupBatchDescs.clear(); - _backupBatches.clear(); -} - -void OGLGraphicsDriver::BackupDrawLists() { - ClearDrawBackups(); - for (size_t i = 0; i <= _actSpriteBatch; ++i) { - _backupBatchDescs.push_back(_spriteBatchDesc[i]); - _backupBatches.push_back(_spriteBatches[i]); - } -} - -void OGLGraphicsDriver::RestoreDrawLists() { - if (_backupBatchDescs.size() == 0) { - ClearDrawLists(); - return; - } - _spriteBatchDesc = _backupBatchDescs; - _spriteBatches = _backupBatches; - _actSpriteBatch = _backupBatchDescs.size() - 1; -} - -void OGLGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) { - _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry((OGLBitmap *)bitmap, x, y)); -} - -void OGLGraphicsDriver::DestroyDDB(IDriverDependantBitmap *bitmap) { - // Remove deleted DDB from backups - for (OGLSpriteBatches::iterator it = _backupBatches.begin(); it != _backupBatches.end(); ++it) { - std::vector &drawlist = it->List; - for (size_t i = 0; i < drawlist.size(); i++) { - if (drawlist[i].bitmap == bitmap) - drawlist[i].skip = true; - } - } - delete bitmap; -} - - -void OGLGraphicsDriver::UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha) { - int textureHeight = tile->height; - int textureWidth = tile->width; - - // TODO: this seem to be tad overcomplicated, these conversions were made - // when texture is just created. Check later if this operation here may be removed. - AdjustSizeToNearestSupportedByCard(&textureWidth, &textureHeight); - - int tilex = 0, tiley = 0, tileWidth = tile->width, tileHeight = tile->height; - if (textureWidth > tile->width) { - int texxoff = Math::Min(textureWidth - tile->width - 1, 1); - tilex = texxoff; - tileWidth += 1 + texxoff; - } - if (textureHeight > tile->height) { - int texyoff = Math::Min(textureHeight - tile->height - 1, 1); - tiley = texyoff; - tileHeight += 1 + texyoff; - } - - const bool usingLinearFiltering = _filter->UseLinearFiltering(); - char *origPtr = (char *)malloc(sizeof(int) * tileWidth * tileHeight); - const int pitch = tileWidth * sizeof(int); - char *memPtr = origPtr + pitch * tiley + tilex * sizeof(int); - - TextureTile fixedTile; - fixedTile.x = tile->x; - fixedTile.y = tile->y; - fixedTile.width = Math::Min(tile->width, tileWidth); - fixedTile.height = Math::Min(tile->height, tileHeight); - if (target->_opaque) - BitmapToVideoMemOpaque(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch); - else - BitmapToVideoMem(bitmap, hasAlpha, &fixedTile, target, memPtr, pitch, usingLinearFiltering); - - // Mimic the behaviour of GL_CLAMP_EDGE for the tile edges - // NOTE: on some platforms GL_CLAMP_EDGE does not work with the version of OpenGL we're using. - if (tile->width < tileWidth) { - if (tilex > 0) { - for (int y = 0; y < tileHeight; y++) { - unsigned int *edge_left_col = (unsigned int *)(origPtr + y * pitch + (tilex - 1) * sizeof(int)); - unsigned int *bm_left_col = (unsigned int *)(origPtr + y * pitch + (tilex) * sizeof(int)); - *edge_left_col = *bm_left_col & 0x00FFFFFF; - } - } - for (int y = 0; y < tileHeight; y++) { - unsigned int *edge_right_col = (unsigned int *)(origPtr + y * pitch + (tilex + tile->width) * sizeof(int)); - unsigned int *bm_right_col = edge_right_col - 1; - *edge_right_col = *bm_right_col & 0x00FFFFFF; - } - } - if (tile->height < tileHeight) { - if (tiley > 0) { - unsigned int *edge_top_row = (unsigned int *)(origPtr + pitch * (tiley - 1)); - unsigned int *bm_top_row = (unsigned int *)(origPtr + pitch * (tiley)); - for (int x = 0; x < tileWidth; x++) { - edge_top_row[x] = bm_top_row[x] & 0x00FFFFFF; - } - } - unsigned int *edge_bottom_row = (unsigned int *)(origPtr + pitch * (tiley + tile->height)); - unsigned int *bm_bottom_row = (unsigned int *)(origPtr + pitch * (tiley + tile->height - 1)); - for (int x = 0; x < tileWidth; x++) { - edge_bottom_row[x] = bm_bottom_row[x] & 0x00FFFFFF; - } - } - - glBindTexture(GL_TEXTURE_2D, tile->texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tileWidth, tileHeight, GL_RGBA, GL_UNSIGNED_BYTE, origPtr); - - free(origPtr); -} - -void OGLGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { - OGLBitmap *target = (OGLBitmap *)bitmapToUpdate; - if (target->_width != bitmap->GetWidth() || target->_height != bitmap->GetHeight()) - error("UpdateDDBFromBitmap: mismatched bitmap size"); - const int color_depth = bitmap->GetColorDepth(); - if (color_depth != target->_colDepth) - error("UpdateDDBFromBitmap: mismatched colour depths"); - - target->_hasAlpha = hasAlpha; - if (color_depth == 8) - select_palette(palette); - - for (int i = 0; i < target->_numTiles; i++) { - UpdateTextureRegion(&target->_tiles[i], bitmap, target, hasAlpha); - } - - if (color_depth == 8) - unselect_palette(); -} - -int OGLGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) { - if (color_depth == 8) - return 8; - if (color_depth > 8 && color_depth <= 16) - return 16; - return 32; -} - -void OGLGraphicsDriver::AdjustSizeToNearestSupportedByCard(int *width, int *height) { - int allocatedWidth = *width, allocatedHeight = *height; - - bool foundWidth = false, foundHeight = false; - int tryThis = 2; - while ((!foundWidth) || (!foundHeight)) { - if ((tryThis >= allocatedWidth) && (!foundWidth)) { - allocatedWidth = tryThis; - foundWidth = true; - } - - if ((tryThis >= allocatedHeight) && (!foundHeight)) { - allocatedHeight = tryThis; - foundHeight = true; - } - - tryThis = tryThis << 1; - } - - *width = allocatedWidth; - *height = allocatedHeight; -} - - - -IDriverDependantBitmap *OGLGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) { - int allocatedWidth = bitmap->GetWidth(); - int allocatedHeight = bitmap->GetHeight(); - // NOTE: original bitmap object is not modified in this function - if (bitmap->GetColorDepth() != GetCompatibleBitmapFormat(bitmap->GetColorDepth())) - error("CreateDDBFromBitmap: bitmap colour depth not supported"); - int colourDepth = bitmap->GetColorDepth(); - - OGLBitmap *ddb = new OGLBitmap(bitmap->GetWidth(), bitmap->GetHeight(), colourDepth, opaque); - - AdjustSizeToNearestSupportedByCard(&allocatedWidth, &allocatedHeight); - int tilesAcross = 1, tilesDown = 1; - - // Calculate how many textures will be necessary to - // store this image - - int MaxTextureWidth = 512; - int MaxTextureHeight = 512; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTextureWidth); - MaxTextureHeight = MaxTextureWidth; - - tilesAcross = (allocatedWidth + MaxTextureWidth - 1) / MaxTextureWidth; - tilesDown = (allocatedHeight + MaxTextureHeight - 1) / MaxTextureHeight; - int tileWidth = bitmap->GetWidth() / tilesAcross; - int lastTileExtraWidth = bitmap->GetWidth() % tilesAcross; - int tileHeight = bitmap->GetHeight() / tilesDown; - int lastTileExtraHeight = bitmap->GetHeight() % tilesDown; - int tileAllocatedWidth = tileWidth; - int tileAllocatedHeight = tileHeight; - - AdjustSizeToNearestSupportedByCard(&tileAllocatedWidth, &tileAllocatedHeight); - - int numTiles = tilesAcross * tilesDown; - OGLTextureTile *tiles = (OGLTextureTile *)malloc(sizeof(OGLTextureTile) * numTiles); - memset(tiles, 0, sizeof(OGLTextureTile) * numTiles); - - OGLCUSTOMVERTEX *vertices = nullptr; - - if ((numTiles == 1) && - (allocatedWidth == bitmap->GetWidth()) && - (allocatedHeight == bitmap->GetHeight())) { - // use default whole-image vertices - } else { - // The texture is not the same as the bitmap, so create some custom vertices - // so that only the relevant portion of the texture is rendered - int vertexBufferSize = numTiles * 4 * sizeof(OGLCUSTOMVERTEX); - - ddb->_vertex = vertices = (OGLCUSTOMVERTEX *)malloc(vertexBufferSize); - } - - for (int x = 0; x < tilesAcross; x++) { - for (int y = 0; y < tilesDown; y++) { - OGLTextureTile *thisTile = &tiles[y * tilesAcross + x]; - int thisAllocatedWidth = tileAllocatedWidth; - int thisAllocatedHeight = tileAllocatedHeight; - thisTile->x = x * tileWidth; - thisTile->y = y * tileHeight; - thisTile->width = tileWidth; - thisTile->height = tileHeight; - if (x == tilesAcross - 1) { - thisTile->width += lastTileExtraWidth; - thisAllocatedWidth = thisTile->width; - AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); - } - if (y == tilesDown - 1) { - thisTile->height += lastTileExtraHeight; - thisAllocatedHeight = thisTile->height; - AdjustSizeToNearestSupportedByCard(&thisAllocatedWidth, &thisAllocatedHeight); - } - - if (vertices != nullptr) { - const int texxoff = (thisAllocatedWidth - thisTile->width) > 1 ? 1 : 0; - const int texyoff = (thisAllocatedHeight - thisTile->height) > 1 ? 1 : 0; - for (int vidx = 0; vidx < 4; vidx++) { - int i = (y * tilesAcross + x) * 4 + vidx; - vertices[i] = defaultVertices[vidx]; - if (vertices[i].tu > 0.0) { - vertices[i].tu = (float)(texxoff + thisTile->width) / (float)thisAllocatedWidth; - } else { - vertices[i].tu = (float)(texxoff) / (float)thisAllocatedWidth; - } - if (vertices[i].tv > 0.0) { - vertices[i].tv = (float)(texyoff + thisTile->height) / (float)thisAllocatedHeight; - } else { - vertices[i].tv = (float)(texyoff) / (float)thisAllocatedHeight; - } - } - } - - glGenTextures(1, &thisTile->texture); - glBindTexture(GL_TEXTURE_2D, thisTile->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - // NOTE: pay attention that the texture format depends on the **display mode**'s format, - // rather than source bitmap's color depth! - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, thisAllocatedWidth, thisAllocatedHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - } - } - - ddb->_numTiles = numTiles; - ddb->_tiles = tiles; - - UpdateDDBFromBitmap(ddb, bitmap, hasAlpha); - - return ddb; -} - -void OGLGraphicsDriver::do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { - // Construct scene in order: game screen, fade fx, post game overlay - // NOTE: please keep in mind: redrawing last saved frame here instead of constructing new one - // is done because of backwards-compatibility issue: originally AGS faded out using frame - // drawn before the script that triggers blocking fade (e.g. instigated by ChangeRoom). - // Unfortunately some existing games were changing looks of the screen during same function, - // but these were not supposed to get on screen until before fade-in. - if (fadingOut) - this->_reDrawLastFrame(); - else if (_drawScreenCallback != nullptr) - _drawScreenCallback(); - Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); - blackSquare->Clear(makecol32(targetColourRed, targetColourGreen, targetColourBlue)); - IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); - delete blackSquare; - BeginSpriteBatch(_srcRect, SpriteTransform()); - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - this->DrawSprite(0, 0, d3db); - if (_drawPostScreenCallback != NULL) - _drawPostScreenCallback(); - - if (speed <= 0) speed = 16; - speed *= 2; // harmonise speeds with software driver which is faster - for (int a = 1; a < 255; a += speed) { - d3db->SetTransparency(fadingOut ? a : (255 - a)); - this->_render(false); - - if (_pollingCallback) - _pollingCallback(); - WaitForNextFrame(); - } - - if (fadingOut) { - d3db->SetTransparency(0); - this->_render(false); - } - - this->DestroyDDB(d3db); - this->ClearDrawLists(); - ResetFxPool(); -} - -void OGLGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { - do_fade(true, speed, targetColourRed, targetColourGreen, targetColourBlue); -} - -void OGLGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) { - do_fade(false, speed, targetColourRed, targetColourGreen, targetColourBlue); -} - -void OGLGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) { - // Construct scene in order: game screen, fade fx, post game overlay - if (blackingOut) - this->_reDrawLastFrame(); - else if (_drawScreenCallback != nullptr) - _drawScreenCallback(); - Bitmap *blackSquare = BitmapHelper::CreateBitmap(16, 16, 32); - blackSquare->Clear(); - IDriverDependantBitmap *d3db = this->CreateDDBFromBitmap(blackSquare, false, true); - delete blackSquare; - BeginSpriteBatch(_srcRect, SpriteTransform()); - size_t fx_batch = _actSpriteBatch; - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - this->DrawSprite(0, 0, d3db); - if (!blackingOut) { - // when fading in, draw four black boxes, one - // across each side of the screen - this->DrawSprite(0, 0, d3db); - this->DrawSprite(0, 0, d3db); - this->DrawSprite(0, 0, d3db); - } - if (_drawPostScreenCallback != NULL) - _drawPostScreenCallback(); - - int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); - int boxWidth = speed; - int boxHeight = yspeed; - - while (boxWidth < _srcRect.GetWidth()) { - boxWidth += speed; - boxHeight += yspeed; - OGLSpriteBatch &batch = _spriteBatches[fx_batch]; - std::vector &drawList = batch.List; - size_t last = drawList.size() - 1; - if (blackingOut) { - drawList[last].x = _srcRect.GetWidth() / 2 - boxWidth / 2; - drawList[last].y = _srcRect.GetHeight() / 2 - boxHeight / 2; - d3db->SetStretch(boxWidth, boxHeight, false); - } else { - drawList[last - 3].x = _srcRect.GetWidth() / 2 - boxWidth / 2 - _srcRect.GetWidth(); - drawList[last - 2].y = _srcRect.GetHeight() / 2 - boxHeight / 2 - _srcRect.GetHeight(); - drawList[last - 1].x = _srcRect.GetWidth() / 2 + boxWidth / 2; - drawList[last ].y = _srcRect.GetHeight() / 2 + boxHeight / 2; - d3db->SetStretch(_srcRect.GetWidth(), _srcRect.GetHeight(), false); - } - - this->_render(false); - - if (_pollingCallback) - _pollingCallback(); - platform->Delay(delay); - } - - this->DestroyDDB(d3db); - this->ClearDrawLists(); - ResetFxPool(); -} - -void OGLGraphicsDriver::SetScreenFade(int red, int green, int blue) { - OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); - ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), - _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); - ddb->SetTransparency(0); - _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); -} - -void OGLGraphicsDriver::SetScreenTint(int red, int green, int blue) { - if (red == 0 && green == 0 && blue == 0) return; - OGLBitmap *ddb = static_cast(MakeFx(red, green, blue)); - ddb->SetStretch(_spriteBatches[_actSpriteBatch].Viewport.GetWidth(), - _spriteBatches[_actSpriteBatch].Viewport.GetHeight(), false); - ddb->SetTransparency(128); - _spriteBatches[_actSpriteBatch].List.push_back(OGLDrawListEntry(ddb)); -} - - -OGLGraphicsFactory *OGLGraphicsFactory::_factory = nullptr; - -OGLGraphicsFactory::~OGLGraphicsFactory() { - _factory = nullptr; -} - -size_t OGLGraphicsFactory::GetFilterCount() const { - return 2; -} - -const GfxFilterInfo *OGLGraphicsFactory::GetFilterInfo(size_t index) const { - switch (index) { - case 0: - return &OGLGfxFilter::FilterInfo; - case 1: - return &AAOGLGfxFilter::FilterInfo; - default: - return nullptr; - } -} - -String OGLGraphicsFactory::GetDefaultFilterID() const { - return OGLGfxFilter::FilterInfo.Id; -} - -/* static */ OGLGraphicsFactory *OGLGraphicsFactory::GetFactory() { - if (!_factory) - _factory = new OGLGraphicsFactory(); - return _factory; -} - -OGLGraphicsDriver *OGLGraphicsFactory::EnsureDriverCreated() { - if (!_driver) - _driver = new OGLGraphicsDriver(); - return _driver; -} - -OGLGfxFilter *OGLGraphicsFactory::CreateFilter(const String &id) { - if (OGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new OGLGfxFilter(); - else if (AAOGLGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) - return new AAOGLGfxFilter(); - return nullptr; -} - -} // namespace OGL -} // namespace Engine -} // namespace AGS -} // namespace AGS3 - -#endif // only on Windows, Android and iOS diff --git a/engines/ags/engine/gfx/ali3dogl.h b/engines/ags/engine/gfx/ali3dogl.h deleted file mode 100644 index e6dd2e35e84c..000000000000 --- a/engines/ags/engine/gfx/ali3dogl.h +++ /dev/null @@ -1,378 +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. - * - */ - -//============================================================================= -// -// OpenGL graphics factory -// -//============================================================================= - -#ifndef AGS_ENGINE_GFX_ALI3DOGL_H -#define AGS_ENGINE_GFX_ALI3DOGL_H - -#include "ags/lib/std/memory.h" -#include "ags/shared/gfx/bitmap.h" -#include "ags/engine/gfx/ddb.h" -#include "ags/engine/gfx/gfxdriverfactorybase.h" -#include "ags/engine/gfx/gfxdriverbase.h" -#include "ags/shared/util/string.h" -#include "ags/shared/util/version.h" - -#include "ags/engine/gfx/ogl_headers.h" - -namespace AGS3 { -namespace AGS { -namespace Engine { - -namespace OGL { - -using Shared::Bitmap; -using Shared::String; -using Shared::Version; - -typedef struct _OGLVECTOR { - float x; - float y; -} OGLVECTOR2D; - - -struct OGLCUSTOMVERTEX { - OGLVECTOR2D position; - float tu; - float tv; -}; - -struct OGLTextureTile : public TextureTile { - unsigned int texture; -}; - -class OGLBitmap : public VideoMemDDB { -public: - // Transparency is a bit counter-intuitive - // 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible - void SetTransparency(int transparency) override { - _transparency = transparency; - } - void SetFlippedLeftRight(bool isFlipped) override { - _flipped = isFlipped; - } - void SetStretch(int width, int height, bool useResampler = true) override { - _stretchToWidth = width; - _stretchToHeight = height; - _useResampler = useResampler; - } - void SetLightLevel(int lightLevel) override { - _lightLevel = lightLevel; - } - void SetTint(int red, int green, int blue, int tintSaturation) override { - _red = red; - _green = green; - _blue = blue; - _tintSaturation = tintSaturation; - } - - bool _flipped; - int _stretchToWidth, _stretchToHeight; - bool _useResampler; - int _red, _green, _blue; - int _tintSaturation; - int _lightLevel; - bool _hasAlpha; - int _transparency; - OGLCUSTOMVERTEX *_vertex; - OGLTextureTile *_tiles; - int _numTiles; - - OGLBitmap(int width, int height, int colDepth, bool opaque) { - _width = width; - _height = height; - _colDepth = colDepth; - _flipped = false; - _hasAlpha = false; - _stretchToWidth = 0; - _stretchToHeight = 0; - _useResampler = false; - _red = _green = _blue = 0; - _tintSaturation = 0; - _lightLevel = 0; - _transparency = 0; - _opaque = opaque; - _vertex = nullptr; - _tiles = nullptr; - _numTiles = 0; - } - - int GetWidthToRender() const { - return (_stretchToWidth > 0) ? _stretchToWidth : _width; - } - int GetHeightToRender() const { - return (_stretchToHeight > 0) ? _stretchToHeight : _height; - } - - void Dispose(); - - ~OGLBitmap() override { - Dispose(); - } -}; - -typedef SpriteDrawListEntry OGLDrawListEntry; -typedef struct GLMATRIX { - GLfloat m[16]; -} GLMATRIX; -struct OGLSpriteBatch { - // List of sprites to render - std::vector List; - // Clipping viewport - Rect Viewport; - // Transformation matrix, built from the batch description - GLMATRIX Matrix; -}; -typedef std::vector OGLSpriteBatches; - - -class OGLDisplayModeList : public IGfxModeList { -public: - OGLDisplayModeList(const std::vector &modes) - : _modes(modes) { - } - - int GetModeCount() const override { - return _modes.size(); - } - - bool GetMode(int index, DisplayMode &mode) const override { - if (index >= 0 && (size_t)index < _modes.size()) { - mode = _modes[index]; - return true; - } - return false; - } - -private: - std::vector _modes; -}; - - -class OGLGfxFilter; - -class OGLGraphicsDriver : public VideoMemoryGraphicsDriver { -public: - const char *GetDriverName() override { - return "OpenGL"; - } - const char *GetDriverID() override { - return "OGL"; - } - void SetTintMethod(TintMethod method) override; - bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override; - bool SetNativeSize(const Size &src_size) override; - bool SetRenderFrame(const Rect &dst_rect) override; - int GetDisplayDepthForNativeDepth(int native_color_depth) const override; - IGfxModeList *GetSupportedModeList(int color_depth) override; - bool IsModeSupported(const DisplayMode &mode) override; - PGfxFilter GetGraphicsFilter() const override; - void UnInit(); - // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. - void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override; - int GetCompatibleBitmapFormat(int color_depth) override; - IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override; - void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override; - void DestroyDDB(IDriverDependantBitmap *bitmap) override; - void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) override; - void RenderToBackBuffer() override; - void Render() override; - void Render(int xoff, int yoff, GlobalFlipType flip) override; - bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override; - void EnableVsyncBeforeRender(bool enabled) override { - } - void Vsync() override; - void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override; - void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override; - void BoxOutEffect(bool blackingOut, int speed, int delay) override; - bool SupportsGammaControl() override; - void SetGamma(int newGamma) override; - void UseSmoothScaling(bool enabled) override { - _smoothScaling = enabled; - } - bool RequiresFullRedrawEachFrame() override { - return true; - } - bool HasAcceleratedTransform() override { - return true; - } - void SetScreenFade(int red, int green, int blue) override; - void SetScreenTint(int red, int green, int blue) override; - - typedef std::shared_ptr POGLFilter; - - void SetGraphicsFilter(POGLFilter filter); - - OGLGraphicsDriver(); - ~OGLGraphicsDriver() override; - -private: - POGLFilter _filter; - -#if AGS_PLATFORM_OS_WINDOWS - HDC _hDC; - HGLRC _hRC; - HWND _hWnd; - HINSTANCE _hInstance; - GLuint _oldPixelFormat; - PIXELFORMATDESCRIPTOR _oldPixelFormatDesc; -#endif -#if AGS_PLATFORM_OS_LINUX - bool _have_window; - GLXContext _glxContext; -#endif - bool _firstTimeInit; - // Position of backbuffer texture in world space - GLfloat _backbuffer_vertices[8]; - // Relative position of source image on the backbuffer texture, - // in local coordinates - GLfloat _backbuffer_texture_coordinates[8]; - OGLCUSTOMVERTEX defaultVertices[4]; - String previousError; - bool _smoothScaling; - bool _legacyPixelShader; - // Shader program and its variable references; - // the variables are rather specific for AGS use (sprite tinting). - struct ShaderProgram { - GLuint Program; - GLuint SamplerVar; // texture ID - GLuint ColorVar; // primary operation variable - GLuint AuxVar; // auxiliary variable - - ShaderProgram(); - }; - ShaderProgram _tintShader; - ShaderProgram _lightShader; - - int device_screen_physical_width; - int device_screen_physical_height; - - // Viewport and scissor rect, in OpenGL screen coordinates (0,0 is at left-bottom) - Rect _viewportRect; - - // These two flags define whether driver can, and should (respectively) - // render sprites to texture, and then texture to screen, as opposed to - // rendering to screen directly. This is known as supersampling mode - bool _can_render_to_texture; - bool _do_render_to_texture; - // Backbuffer texture multiplier, used to determine a size of texture - // relative to the native game size. - int _super_sampling; - unsigned int _backbuffer; - unsigned int _fbo; - // Size of the backbuffer drawing area, equals to native size - // multiplied by _super_sampling - Size _backRenderSize; - // Actual size of the backbuffer texture, created by OpenGL - Size _backTextureSize; - - OGLSpriteBatches _spriteBatches; - // TODO: these draw list backups are needed only for the fade-in/out effects - // find out if it's possible to reimplement these effects in main drawing routine. - SpriteBatchDescs _backupBatchDescs; - OGLSpriteBatches _backupBatches; - - void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override; - void ResetAllBatches() override; - - // Sets up GL objects not related to particular display mode - void FirstTimeInit(); - // Initializes Gl rendering context - bool InitGlScreen(const DisplayMode &mode); - bool CreateGlContext(const DisplayMode &mode); - void DeleteGlContext(); - // Sets up general rendering parameters - void InitGlParams(const DisplayMode &mode); - void SetupDefaultVertices(); - // Test if rendering to texture is supported - void TestRenderToTexture(); - // Test if supersampling should be allowed with the current setup - void TestSupersampling(); - // Create shader programs for sprite tinting and changing light level - void CreateShaders(); - void CreateTintShader(); - void CreateLightShader(); - void CreateShaderProgram(ShaderProgram &prg, const char *name, const char *fragment_shader_src, - const char *sampler_var, const char *color_var, const char *aux_var); - void DeleteShaderProgram(ShaderProgram &prg); - void OutputShaderError(GLuint obj_id, const String &obj_name, bool is_shader); - // Configure backbuffer texture, that is used in render-to-texture mode - void SetupBackbufferTexture(); - void DeleteBackbufferTexture(); -#if AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_LINUX - void CreateDesktopScreen(int width, int height, int depth); -#elif AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS - void UpdateDeviceScreen(); -#endif - // Unset parameters and release resources related to the display mode - void ReleaseDisplayMode(); - void AdjustSizeToNearestSupportedByCard(int *width, int *height); - void UpdateTextureRegion(OGLTextureTile *tile, Bitmap *bitmap, OGLBitmap *target, bool hasAlpha); - void CreateVirtualScreen(); - void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue); - void _renderSprite(const OGLDrawListEntry *entry, const GLMATRIX &matGlobal); - void SetupViewport(); - // Converts rectangle in top->down coordinates into OpenGL's native bottom->up coordinates - Rect ConvertTopDownRect(const Rect &top_down_rect, int surface_height); - - // Backup all draw lists in the temp storage - void BackupDrawLists(); - // Restore draw lists from the temp storage - void RestoreDrawLists(); - // Deletes draw list backups - void ClearDrawBackups(); - void _render(bool clearDrawListAfterwards); - void RenderSpriteBatches(); - void RenderSpriteBatch(const OGLSpriteBatch &batch); - void _reDrawLastFrame(); -}; - - -class OGLGraphicsFactory : public GfxDriverFactoryBase { -public: - ~OGLGraphicsFactory() override; - - size_t GetFilterCount() const override; - const GfxFilterInfo *GetFilterInfo(size_t index) const override; - String GetDefaultFilterID() const override; - - static OGLGraphicsFactory *GetFactory(); - -private: - OGLGraphicsDriver *EnsureDriverCreated() override; - OGLGfxFilter *CreateFilter(const String &id) override; - - static OGLGraphicsFactory *_factory; -}; - -} // namespace OGL -} // namespace Engine -} // namespace AGS -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp index 61954f52d2cd..8ef707e14fd2 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.cpp +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -57,16 +57,9 @@ void GetGfxDriverFactoryNames(StringV &ids) { } IGfxDriverFactory *GetGfxDriverFactory(const String id) { -#if AGS_HAS_DIRECT3D - if (id.CompareNoCase("D3D9") == 0) - return D3D::D3DGraphicsFactory::GetFactory(); -#endif -#if AGS_HAS_OPENGL - if (id.CompareNoCase("OGL") == 0) - return OGL::OGLGraphicsFactory::GetFactory(); -#endif if (id.CompareNoCase("Software") == 0) return ALSW::ALSWGraphicsFactory::GetFactory(); + set_allegro_error("No graphics factory with such id: %s", id.GetCStr()); return nullptr; } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 07c1145c9c1b..2e50b7b5209a 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -245,7 +245,6 @@ MODULE_OBJS = \ engine/game/savegame.o \ engine/game/savegame_components.o \ engine/game/viewport.o \ - engine/gfx/ali3dogl.o \ engine/gfx/ali3dsw.o \ engine/gfx/blender.o \ engine/gfx/color_engine.o \ From 680016caeae5342c7e3e1de235fab7e19cbf65bb Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Jan 2021 19:58:37 -0800 Subject: [PATCH 087/215] AGS: Rename software graphics driver to ScummVM This will be the basis of the ScummVM implementation --- .../gfx/{ali3dsw.cpp => ali3dscummvm.cpp} | 140 +++++++++--------- .../engine/gfx/{ali3dsw.h => ali3dscummvm.h} | 38 ++--- engines/ags/engine/gfx/gfxdriverfactory.cpp | 25 +--- engines/ags/engine/gfx/gfxfilter_allegro.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_allegro.h | 2 +- engines/ags/engine/gfx/gfxfilter_hqx.cpp | 2 +- engines/ags/engine/gfx/gfxfilter_hqx.h | 2 +- engines/ags/engine/main/config.cpp | 15 +- engines/ags/module.mk | 2 +- 9 files changed, 101 insertions(+), 127 deletions(-) rename engines/ags/engine/gfx/{ali3dsw.cpp => ali3dscummvm.cpp} (81%) rename engines/ags/engine/gfx/{ali3dsw.h => ali3dscummvm.h} (90%) diff --git a/engines/ags/engine/gfx/ali3dsw.cpp b/engines/ags/engine/gfx/ali3dscummvm.cpp similarity index 81% rename from engines/ags/engine/gfx/ali3dsw.cpp rename to engines/ags/engine/gfx/ali3dscummvm.cpp index 3e67d3760221..b588693eb409 100644 --- a/engines/ags/engine/gfx/ali3dsw.cpp +++ b/engines/ags/engine/gfx/ali3dscummvm.cpp @@ -26,7 +26,7 @@ // //============================================================================= -#include "ags/engine/gfx/ali3dsw.h" +#include "ags/engine/gfx/ali3dscummvm.h" #include "ags/shared/core/platform.h" #include "ags/engine/gfx/ali3dexception.h" #include "ags/engine/gfx/gfxfilter_allegro.h" @@ -63,11 +63,11 @@ extern int dxmedia_play_video(const char *, bool, int, int); namespace AGS { namespace Engine { -namespace ALSW { +namespace ALGfx { using namespace Shared; -bool ALSoftwareGfxModeList::GetMode(int index, DisplayMode &mode) const { +bool ALScummVMGfxModeList::GetMode(int index, DisplayMode &mode) const { if (_gfxModeList && index >= 0 && index < _gfxModeList->num_modes) { mode.Width = _gfxModeList->mode[index].width; mode.Height = _gfxModeList->mode[index].height; @@ -81,7 +81,7 @@ unsigned long _trans_alpha_blender32(unsigned long x, unsigned long y, unsigned RGB faded_out_palette[256]; -ALSoftwareGraphicsDriver::ALSoftwareGraphicsDriver() { +ALScummVMGraphicsDriver::ALScummVMGraphicsDriver() { _tint_red = 0; _tint_green = 0; _tint_blue = 0; @@ -97,10 +97,10 @@ ALSoftwareGraphicsDriver::ALSoftwareGraphicsDriver() { _stageVirtualScreen = nullptr; // Initialize default sprite batch, it will be used when no other batch was activated - ALSoftwareGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); + ALScummVMGraphicsDriver::InitSpriteBatch(0, _spriteBatchDesc[0]); } -bool ALSoftwareGraphicsDriver::IsModeSupported(const DisplayMode &mode) { +bool ALScummVMGraphicsDriver::IsModeSupported(const DisplayMode &mode) { if (mode.Width <= 0 || mode.Height <= 0 || mode.ColorDepth <= 0) { set_allegro_error("Invalid resolution parameters: %d x %d x %d", mode.Width, mode.Height, mode.ColorDepth); return false; @@ -132,28 +132,28 @@ bool ALSoftwareGraphicsDriver::IsModeSupported(const DisplayMode &mode) { return true; } -int ALSoftwareGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const { +int ALScummVMGraphicsDriver::GetDisplayDepthForNativeDepth(int native_color_depth) const { // TODO: check for device caps to know which depth is supported? if (native_color_depth > 8) return 32; return native_color_depth; } -IGfxModeList *ALSoftwareGraphicsDriver::GetSupportedModeList(int color_depth) { +IGfxModeList *ALScummVMGraphicsDriver::GetSupportedModeList(int color_depth) { if (_gfxModeList == nullptr) { _gfxModeList = get_gfx_mode_list(GetAllegroGfxDriverID(false)); } if (_gfxModeList == nullptr) { return nullptr; } - return new ALSoftwareGfxModeList(_gfxModeList); + return new ALScummVMGfxModeList(_gfxModeList); } -PGfxFilter ALSoftwareGraphicsDriver::GetGraphicsFilter() const { +PGfxFilter ALScummVMGraphicsDriver::GetGraphicsFilter() const { return _filter; } -int ALSoftwareGraphicsDriver::GetAllegroGfxDriverID(bool windowed) { +int ALScummVMGraphicsDriver::GetAllegroGfxDriverID(bool windowed) { #if AGS_PLATFORM_OS_WINDOWS if (windowed) return GFX_DIRECTX_WIN; @@ -174,7 +174,7 @@ int ALSoftwareGraphicsDriver::GetAllegroGfxDriverID(bool windowed) { #endif } -void ALSoftwareGraphicsDriver::SetGraphicsFilter(PALSWFilter filter) { +void ALScummVMGraphicsDriver::SetGraphicsFilter(PALScummVMFilter filter) { _filter = filter; OnSetFilter(); @@ -182,11 +182,11 @@ void ALSoftwareGraphicsDriver::SetGraphicsFilter(PALSWFilter filter) { CreateVirtualScreen(); } -void ALSoftwareGraphicsDriver::SetTintMethod(TintMethod method) { +void ALScummVMGraphicsDriver::SetTintMethod(TintMethod method) { // TODO: support new D3D-style tint method } -bool ALSoftwareGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) { +bool ALScummVMGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) { ReleaseDisplayMode(); const int driver = GetAllegroGfxDriverID(mode.Windowed); @@ -226,7 +226,7 @@ bool ALSoftwareGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile return true; } -void ALSoftwareGraphicsDriver::CreateVirtualScreen() { +void ALScummVMGraphicsDriver::CreateVirtualScreen() { if (!IsModeSet() || !IsRenderFrameValid() || !IsNativeSizeValid() || !_filter) return; DestroyVirtualScreen(); @@ -246,7 +246,7 @@ void ALSoftwareGraphicsDriver::CreateVirtualScreen() { screen = (BITMAP *)_origVirtualScreen->GetAllegroBitmap(); } -void ALSoftwareGraphicsDriver::DestroyVirtualScreen() { +void ALScummVMGraphicsDriver::DestroyVirtualScreen() { if (_filter && _origVirtualScreen) { screen = (BITMAP *)_filter->ShutdownAndReturnRealScreen()->GetAllegroBitmap(); } @@ -255,7 +255,7 @@ void ALSoftwareGraphicsDriver::DestroyVirtualScreen() { _stageVirtualScreen = nullptr; } -void ALSoftwareGraphicsDriver::ReleaseDisplayMode() { +void ALScummVMGraphicsDriver::ReleaseDisplayMode() { OnModeReleased(); ClearDrawLists(); @@ -273,21 +273,21 @@ void ALSoftwareGraphicsDriver::ReleaseDisplayMode() { _allegroScreenWrapper = nullptr; } -bool ALSoftwareGraphicsDriver::SetNativeSize(const Size &src_size) { +bool ALScummVMGraphicsDriver::SetNativeSize(const Size &src_size) { OnSetNativeSize(src_size); // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately CreateVirtualScreen(); return !_srcRect.IsEmpty(); } -bool ALSoftwareGraphicsDriver::SetRenderFrame(const Rect &dst_rect) { +bool ALScummVMGraphicsDriver::SetRenderFrame(const Rect &dst_rect) { OnSetRenderFrame(dst_rect); // If we already have a gfx mode and gfx filter set, then use it to update virtual screen immediately CreateVirtualScreen(); return !_dstRect.IsEmpty(); } -void ALSoftwareGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) { +void ALScummVMGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) { if (!_filter) return; int color = 0; if (colorToUse != nullptr) @@ -296,11 +296,11 @@ void ALSoftwareGraphicsDriver::ClearRectangle(int x1, int y1, int x2, int y2, RG _filter->ClearRect(x1, y1, x2, y2, color); } -ALSoftwareGraphicsDriver::~ALSoftwareGraphicsDriver() { - ALSoftwareGraphicsDriver::UnInit(); +ALScummVMGraphicsDriver::~ALScummVMGraphicsDriver() { + ALScummVMGraphicsDriver::UnInit(); } -void ALSoftwareGraphicsDriver::UnInit() { +void ALScummVMGraphicsDriver::UnInit() { OnUnInit(); ReleaseDisplayMode(); @@ -310,7 +310,7 @@ void ALSoftwareGraphicsDriver::UnInit() { } } -bool ALSoftwareGraphicsDriver::SupportsGammaControl() { +bool ALScummVMGraphicsDriver::SupportsGammaControl() { #if AGS_DDRAW_GAMMA_CONTROL if (dxGammaControl != NULL) { @@ -322,7 +322,7 @@ bool ALSoftwareGraphicsDriver::SupportsGammaControl() { return 0; } -void ALSoftwareGraphicsDriver::SetGamma(int newGamma) { +void ALScummVMGraphicsDriver::SetGamma(int newGamma) { #if AGS_DDRAW_GAMMA_CONTROL for (int i = 0; i < 256; i++) { int newValue = ((int)defaultGammaRamp.red[i] * newGamma) / 100; @@ -337,26 +337,26 @@ void ALSoftwareGraphicsDriver::SetGamma(int newGamma) { #endif } -int ALSoftwareGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) { +int ALScummVMGraphicsDriver::GetCompatibleBitmapFormat(int color_depth) { return color_depth; } -IDriverDependantBitmap *ALSoftwareGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) { - ALSoftwareBitmap *newBitmap = new ALSoftwareBitmap(bitmap, opaque, hasAlpha); +IDriverDependantBitmap *ALScummVMGraphicsDriver::CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) { + ALScummVMBitmap *newBitmap = new ALScummVMBitmap(bitmap, opaque, hasAlpha); return newBitmap; } -void ALSoftwareGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { - ALSoftwareBitmap *alSwBmp = (ALSoftwareBitmap *)bitmapToUpdate; - alSwBmp->_bmp = bitmap; - alSwBmp->_hasAlpha = hasAlpha; +void ALScummVMGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) { + ALScummVMBitmap *ALScummVMBmp = (ALScummVMBitmap *)bitmapToUpdate; + ALScummVMBmp->_bmp = bitmap; + ALScummVMBmp->_hasAlpha = hasAlpha; } -void ALSoftwareGraphicsDriver::DestroyDDB(IDriverDependantBitmap *bitmap) { +void ALScummVMGraphicsDriver::DestroyDDB(IDriverDependantBitmap *bitmap) { delete bitmap; } -void ALSoftwareGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) { +void ALScummVMGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) { if (_spriteBatches.size() <= index) _spriteBatches.resize(index + 1); ALSpriteBatch &batch = _spriteBatches[index]; @@ -393,29 +393,29 @@ void ALSoftwareGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDe } } -void ALSoftwareGraphicsDriver::ResetAllBatches() { +void ALScummVMGraphicsDriver::ResetAllBatches() { for (ALSpriteBatches::iterator it = _spriteBatches.begin(); it != _spriteBatches.end(); ++it) it->List.clear(); } -void ALSoftwareGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) { - _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap *)bitmap, x, y)); +void ALScummVMGraphicsDriver::DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) { + _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALScummVMBitmap *)bitmap, x, y)); } -void ALSoftwareGraphicsDriver::SetScreenFade(int red, int green, int blue) { +void ALScummVMGraphicsDriver::SetScreenFade(int red, int green, int blue) { // TODO: was not necessary atm } -void ALSoftwareGraphicsDriver::SetScreenTint(int red, int green, int blue) { +void ALScummVMGraphicsDriver::SetScreenTint(int red, int green, int blue) { _tint_red = red; _tint_green = green; _tint_blue = blue; if (((_tint_red > 0) || (_tint_green > 0) || (_tint_blue > 0)) && (_mode.ColorDepth > 8)) { - _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALSoftwareBitmap *)0x1, 0, 0)); + _spriteBatches[_actSpriteBatch].List.push_back(ALDrawListEntry((ALScummVMBitmap *)0x1, 0, 0)); } } -void ALSoftwareGraphicsDriver::RenderToBackBuffer() { +void ALScummVMGraphicsDriver::RenderToBackBuffer() { // Render all the sprite batches with necessary transformations // // NOTE: that's not immediately clear whether it would be faster to first draw upon a camera-sized @@ -452,7 +452,7 @@ void ALSoftwareGraphicsDriver::RenderToBackBuffer() { ClearDrawLists(); } -void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Shared::Bitmap *surface, int surf_offx, int surf_offy) { +void ALScummVMGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Shared::Bitmap *surface, int surf_offx, int surf_offy) { const std::vector &drawlist = batch.List; for (size_t i = 0; i < drawlist.size(); i++) { if (drawlist[i].bitmap == nullptr) { @@ -462,14 +462,14 @@ void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Sha error("Unhandled attempt to draw null sprite"); continue; - } else if (drawlist[i].bitmap == (ALSoftwareBitmap *)0x1) { + } else if (drawlist[i].bitmap == (ALScummVMBitmap *)0x1) { // draw screen tint fx set_trans_blender(_tint_red, _tint_green, _tint_blue, 0); surface->LitBlendBlt(surface, 0, 0, 128); continue; } - ALSoftwareBitmap *bitmap = drawlist[i].bitmap; + ALScummVMBitmap *bitmap = drawlist[i].bitmap; int drawAtX = drawlist[i].x + surf_offx; int drawAtY = drawlist[i].y + surf_offy; @@ -511,7 +511,7 @@ void ALSoftwareGraphicsDriver::RenderSpriteBatch(const ALSpriteBatch &batch, Sha Blit(_spareTintingScreen, surface, 0, 0, 0, 0, _spareTintingScreen->GetWidth(), _spareTintingScreen->GetHeight());*/ } -void ALSoftwareGraphicsDriver::Render(int xoff, int yoff, GlobalFlipType flip) { +void ALScummVMGraphicsDriver::Render(int xoff, int yoff, GlobalFlipType flip) { RenderToBackBuffer(); if (_autoVsync) @@ -523,19 +523,19 @@ void ALSoftwareGraphicsDriver::Render(int xoff, int yoff, GlobalFlipType flip) { _filter->RenderScreenFlipped(virtualScreen, xoff, yoff, flip); } -void ALSoftwareGraphicsDriver::Render() { +void ALScummVMGraphicsDriver::Render() { Render(0, 0, kFlip_None); } -void ALSoftwareGraphicsDriver::Vsync() { +void ALScummVMGraphicsDriver::Vsync() { vsync(); } -Bitmap *ALSoftwareGraphicsDriver::GetMemoryBackBuffer() { +Bitmap *ALScummVMGraphicsDriver::GetMemoryBackBuffer() { return virtualScreen; } -void ALSoftwareGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) { +void ALScummVMGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) { if (backBuffer) { virtualScreen = backBuffer; } else { @@ -550,11 +550,11 @@ void ALSoftwareGraphicsDriver::SetMemoryBackBuffer(Bitmap *backBuffer) { } } -Bitmap *ALSoftwareGraphicsDriver::GetStageBackBuffer() { +Bitmap *ALScummVMGraphicsDriver::GetStageBackBuffer() { return _stageVirtualScreen; } -bool ALSoftwareGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) { +bool ALScummVMGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) { (void)at_native_res; // software driver always renders at native resolution at the moment // software filter is taught to copy to any size if (destination->GetColorDepth() != _mode.ColorDepth) { @@ -573,7 +573,7 @@ bool ALSoftwareGraphicsDriver::GetCopyOfScreenIntoBitmap(Bitmap *destination, bo Author: Matthew Leverton **/ -void ALSoftwareGraphicsDriver::highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { +void ALScummVMGraphicsDriver::highcolor_fade_in(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { Bitmap *bmp_orig = vs; const int col_depth = bmp_orig->GetColorDepth(); const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); @@ -605,7 +605,7 @@ void ALSoftwareGraphicsDriver::highcolor_fade_in(Bitmap *vs, void(*draw_callback _filter->RenderScreen(vs, offx, offy); } -void ALSoftwareGraphicsDriver::highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { +void ALScummVMGraphicsDriver::highcolor_fade_out(Bitmap *vs, void(*draw_callback)(), int offx, int offy, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { Bitmap *bmp_orig = vs; const int col_depth = vs->GetColorDepth(); const int clearColor = makecol_depth(col_depth, targetColourRed, targetColourGreen, targetColourBlue); @@ -650,7 +650,7 @@ void initialize_fade_256(int r, int g, int b) { } } -void ALSoftwareGraphicsDriver::__fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) { +void ALScummVMGraphicsDriver::__fade_from_range(PALETTE source, PALETTE dest, int speed, int from, int to) { PALETTE temp; int c; @@ -667,7 +667,7 @@ void ALSoftwareGraphicsDriver::__fade_from_range(PALETTE source, PALETTE dest, i set_palette_range(dest, from, to, TRUE); } -void ALSoftwareGraphicsDriver::__fade_out_range(int speed, int from, int to, int targetColourRed, int targetColourGreen, int targetColourBlue) { +void ALScummVMGraphicsDriver::__fade_out_range(int speed, int from, int to, int targetColourRed, int targetColourGreen, int targetColourBlue) { PALETTE temp; initialize_fade_256(targetColourRed, targetColourGreen, targetColourBlue); @@ -675,7 +675,7 @@ void ALSoftwareGraphicsDriver::__fade_out_range(int speed, int from, int to, int __fade_from_range(temp, faded_out_palette, speed, from, to); } -void ALSoftwareGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { +void ALScummVMGraphicsDriver::FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) { if (_mode.ColorDepth > 8) { highcolor_fade_out(virtualScreen, _drawPostScreenCallback, 0, 0, speed * 4, targetColourRed, targetColourGreen, targetColourBlue); } else { @@ -683,7 +683,7 @@ void ALSoftwareGraphicsDriver::FadeOut(int speed, int targetColourRed, int targe } } -void ALSoftwareGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) { +void ALScummVMGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) { if (_drawScreenCallback) { _drawScreenCallback(); RenderToBackBuffer(); @@ -696,7 +696,7 @@ void ALSoftwareGraphicsDriver::FadeIn(int speed, PALETTE p, int targetColourRed, } } -void ALSoftwareGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) { +void ALScummVMGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int delay) { if (blackingOut) { int yspeed = _srcRect.GetHeight() / (_srcRect.GetWidth() / speed); int boxwid = speed, boxhit = yspeed; @@ -734,7 +734,7 @@ void ALSoftwareGraphicsDriver::BoxOutEffect(bool blackingOut, int speed, int del #ifndef AGS_NO_VIDEO_PLAYER -bool ALSoftwareGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) { +bool ALScummVMGraphicsDriver::PlayVideo(const char *filename, bool useAVISound, VideoSkipType skipType, bool stretchToFullScreen) { #if AGS_PLATFORM_OS_WINDOWS int result = dxmedia_play_video(filename, useAVISound, skipType, stretchToFullScreen ? 1 : 0); return (result == 0); @@ -766,17 +766,17 @@ unsigned long _trans_alpha_blender32(unsigned long x, unsigned long y, unsigned } -ALSWGraphicsFactory *ALSWGraphicsFactory::_factory = nullptr; +ALScummVMGraphicsFactory *ALScummVMGraphicsFactory::_factory = nullptr; -ALSWGraphicsFactory::~ALSWGraphicsFactory() { +ALScummVMGraphicsFactory::~ALScummVMGraphicsFactory() { _factory = nullptr; } -size_t ALSWGraphicsFactory::GetFilterCount() const { +size_t ALScummVMGraphicsFactory::GetFilterCount() const { return 2; } -const GfxFilterInfo *ALSWGraphicsFactory::GetFilterInfo(size_t index) const { +const GfxFilterInfo *ALScummVMGraphicsFactory::GetFilterInfo(size_t index) const { switch (index) { case 0: return &AllegroGfxFilter::FilterInfo; @@ -787,23 +787,23 @@ const GfxFilterInfo *ALSWGraphicsFactory::GetFilterInfo(size_t index) const { } } -String ALSWGraphicsFactory::GetDefaultFilterID() const { +String ALScummVMGraphicsFactory::GetDefaultFilterID() const { return AllegroGfxFilter::FilterInfo.Id; } -/* static */ ALSWGraphicsFactory *ALSWGraphicsFactory::GetFactory() { +/* static */ ALScummVMGraphicsFactory *ALScummVMGraphicsFactory::GetFactory() { if (!_factory) - _factory = new ALSWGraphicsFactory(); + _factory = new ALScummVMGraphicsFactory(); return _factory; } -ALSoftwareGraphicsDriver *ALSWGraphicsFactory::EnsureDriverCreated() { +ALScummVMGraphicsDriver *ALScummVMGraphicsFactory::EnsureDriverCreated() { if (!_driver) - _driver = new ALSoftwareGraphicsDriver(); + _driver = new ALScummVMGraphicsDriver(); return _driver; } -AllegroGfxFilter *ALSWGraphicsFactory::CreateFilter(const String &id) { +AllegroGfxFilter *ALScummVMGraphicsFactory::CreateFilter(const String &id) { if (AllegroGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) return new AllegroGfxFilter(); else if (HqxGfxFilter::FilterInfo.Id.CompareNoCase(id) == 0) @@ -811,7 +811,7 @@ AllegroGfxFilter *ALSWGraphicsFactory::CreateFilter(const String &id) { return nullptr; } -} // namespace ALSW +} // namespace ALScummVM } // namespace Engine } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/engine/gfx/ali3dsw.h b/engines/ags/engine/gfx/ali3dscummvm.h similarity index 90% rename from engines/ags/engine/gfx/ali3dsw.h rename to engines/ags/engine/gfx/ali3dscummvm.h index c168667c504c..4628a4cf9adb 100644 --- a/engines/ags/engine/gfx/ali3dsw.h +++ b/engines/ags/engine/gfx/ali3dscummvm.h @@ -49,12 +49,12 @@ namespace AGS3 { namespace AGS { namespace Engine { -namespace ALSW { +namespace ALGfx { class AllegroGfxFilter; using AGS::Shared::Bitmap; -class ALSoftwareBitmap : public IDriverDependantBitmap { +class ALScummVMBitmap : public IDriverDependantBitmap { public: // NOTE by CJ: // Transparency is a bit counter-intuitive @@ -92,7 +92,7 @@ class ALSoftwareBitmap : public IDriverDependantBitmap { bool _hasAlpha; int _transparency; - ALSoftwareBitmap(Bitmap *bmp, bool opaque, bool hasAlpha) { + ALScummVMBitmap(Bitmap *bmp, bool opaque, bool hasAlpha) { _bmp = bmp; _width = bmp->GetWidth(); _height = bmp->GetHeight(); @@ -116,15 +116,15 @@ class ALSoftwareBitmap : public IDriverDependantBitmap { // do we want to free the bitmap? } - ~ALSoftwareBitmap() override { + ~ALScummVMBitmap() override { Dispose(); } }; -class ALSoftwareGfxModeList : public IGfxModeList { +class ALScummVMGfxModeList : public IGfxModeList { public: - ALSoftwareGfxModeList(const GFX_MODE_LIST *alsw_gfx_mode_list) + ALScummVMGfxModeList(const GFX_MODE_LIST *alsw_gfx_mode_list) : _gfxModeList(alsw_gfx_mode_list) { } @@ -139,7 +139,7 @@ class ALSoftwareGfxModeList : public IGfxModeList { }; -typedef SpriteDrawListEntry ALDrawListEntry; +typedef SpriteDrawListEntry ALDrawListEntry; // Software renderer's sprite batch struct ALSpriteBatch { // List of sprites to render @@ -154,9 +154,9 @@ struct ALSpriteBatch { typedef std::vector ALSpriteBatches; -class ALSoftwareGraphicsDriver : public GraphicsDriverBase { +class ALScummVMGraphicsDriver : public GraphicsDriverBase { public: - ALSoftwareGraphicsDriver(); + ALScummVMGraphicsDriver(); const char *GetDriverName() override { return "Software renderer"; @@ -216,14 +216,14 @@ class ALSoftwareGraphicsDriver : public GraphicsDriverBase { Bitmap *GetMemoryBackBuffer() override; void SetMemoryBackBuffer(Bitmap *backBuffer) override; Bitmap *GetStageBackBuffer() override; - ~ALSoftwareGraphicsDriver() override; + ~ALScummVMGraphicsDriver() override; - typedef std::shared_ptr PALSWFilter; + typedef std::shared_ptr PALScummVMFilter; - void SetGraphicsFilter(PALSWFilter filter); + void SetGraphicsFilter(PALScummVMFilter filter); private: - PALSWFilter _filter; + PALScummVMFilter _filter; bool _autoVsync; Bitmap *_allegroScreenWrapper; @@ -273,24 +273,24 @@ class ALSoftwareGraphicsDriver : public GraphicsDriverBase { }; -class ALSWGraphicsFactory : public GfxDriverFactoryBase { +class ALScummVMGraphicsFactory : public GfxDriverFactoryBase { public: - ~ALSWGraphicsFactory() override; + ~ALScummVMGraphicsFactory() override; size_t GetFilterCount() const override; const GfxFilterInfo *GetFilterInfo(size_t index) const override; String GetDefaultFilterID() const override; - static ALSWGraphicsFactory *GetFactory(); + static ALScummVMGraphicsFactory *GetFactory(); private: - ALSoftwareGraphicsDriver *EnsureDriverCreated() override; + ALScummVMGraphicsDriver *EnsureDriverCreated() override; AllegroGfxFilter *CreateFilter(const String &id) override; - static ALSWGraphicsFactory *_factory; + static ALScummVMGraphicsFactory *_factory; }; -} // namespace ALSW +} // namespace ALGfx } // namespace Engine } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/engine/gfx/gfxdriverfactory.cpp b/engines/ags/engine/gfx/gfxdriverfactory.cpp index 8ef707e14fd2..e08ab1ddfebb 100644 --- a/engines/ags/engine/gfx/gfxdriverfactory.cpp +++ b/engines/ags/engine/gfx/gfxdriverfactory.cpp @@ -27,19 +27,8 @@ #define AGS_HAS_DIRECT3D (AGS_PLATFORM_OS_WINDOWS) #define AGS_HAS_OPENGL (AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_LINUX) -#include "ags/engine/gfx/ali3dsw.h" +#include "ags/engine/gfx/ali3dscummvm.h" #include "ags/engine/gfx/gfxfilter_allegro.h" - -#if AGS_HAS_OPENGL -#include "ags/engine/gfx/ali3dogl.h" -#include "ags/engine/gfx/gfxfilter_ogl.h" -#endif - -#if AGS_HAS_DIRECT3D -#include "ags/engine/platform/windows/gfx/ali3dd3d.h" -#include "ags/engine/gfx/gfxfilter_d3d.h" -#endif - #include "ags/engine/main/main_allegro.h" namespace AGS3 { @@ -47,18 +36,12 @@ namespace AGS { namespace Engine { void GetGfxDriverFactoryNames(StringV &ids) { -#if AGS_HAS_DIRECT3D - ids.push_back("D3D9"); -#endif -#if AGS_HAS_OPENGL - ids.push_back("OGL"); -#endif - ids.push_back("Software"); + ids.push_back("ScummVM"); } IGfxDriverFactory *GetGfxDriverFactory(const String id) { - if (id.CompareNoCase("Software") == 0) - return ALSW::ALSWGraphicsFactory::GetFactory(); + if (id.CompareNoCase("ScummVM") == 0) + return ALGfx::ALScummVMGraphicsFactory::GetFactory(); set_allegro_error("No graphics factory with such id: %s", id.GetCStr()); return nullptr; diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index 94640f0daefd..aa24f8c3b4d2 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -25,7 +25,7 @@ namespace AGS3 { namespace AGS { namespace Engine { -namespace ALSW { +namespace ALGfx { using namespace Shared; diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.h b/engines/ags/engine/gfx/gfxfilter_allegro.h index d1aba1542134..0a1f953c6697 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.h +++ b/engines/ags/engine/gfx/gfxfilter_allegro.h @@ -36,7 +36,7 @@ namespace AGS3 { namespace AGS { namespace Engine { -namespace ALSW { +namespace ALGfx { using Shared::Bitmap; diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.cpp b/engines/ags/engine/gfx/gfxfilter_hqx.cpp index cd46a97c5036..54ee188ee83b 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.cpp +++ b/engines/ags/engine/gfx/gfxfilter_hqx.cpp @@ -27,7 +27,7 @@ namespace AGS3 { namespace AGS { namespace Engine { -namespace ALSW { +namespace ALGfx { using namespace Shared; diff --git a/engines/ags/engine/gfx/gfxfilter_hqx.h b/engines/ags/engine/gfx/gfxfilter_hqx.h index 06a1e45bfd46..2a1bfe8455d6 100644 --- a/engines/ags/engine/gfx/gfxfilter_hqx.h +++ b/engines/ags/engine/gfx/gfxfilter_hqx.h @@ -34,7 +34,7 @@ namespace AGS3 { namespace AGS { namespace Engine { -namespace ALSW { +namespace ALGfx { class HqxGfxFilter : public AllegroGfxFilter { public: diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 97d54ac784ba..52a6dee9c48d 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -299,7 +299,7 @@ void config_defaults() { #if AGS_PLATFORM_OS_WINDOWS usetup.Screen.DriverID = "D3D9"; #else - usetup.Screen.DriverID = "OGL"; + usetup.Screen.DriverID = "ScummVM"; #endif #if AGS_PLATFORM_OS_WINDOWS usetup.digicard = DIGI_DIRECTAMX(0); @@ -401,17 +401,8 @@ void override_config_ext(ConfigTree &cfg) { INIwriteint(cfg, "graphics", "windowed", 0); #endif - // psp_gfx_renderer - rendering mode - // * 0 - software renderer - // * 1 - hardware, render to screen - // * 2 - hardware, render to texture - if (psp_gfx_renderer == 0) { - INIwritestring(cfg, "graphics", "driver", "Software"); - INIwriteint(cfg, "graphics", "render_at_screenres", 1); - } else { - INIwritestring(cfg, "graphics", "driver", "OGL"); - INIwriteint(cfg, "graphics", "render_at_screenres", psp_gfx_renderer == 1); - } + INIwritestring(cfg, "graphics", "driver", "ScummVM"); + INIwriteint(cfg, "graphics", "render_at_screenres", 1); // psp_gfx_scaling - scaling style: // * 0 - no scaling diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 2e50b7b5209a..f6f087df0a81 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -245,7 +245,7 @@ MODULE_OBJS = \ engine/game/savegame.o \ engine/game/savegame_components.o \ engine/game/viewport.o \ - engine/gfx/ali3dsw.o \ + engine/gfx/ali3dscummvm.o \ engine/gfx/blender.o \ engine/gfx/color_engine.o \ engine/gfx/gfx_util.o \ From 7136301819312c1bcff69762ae019ccf4cc919b9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 10:30:47 -0800 Subject: [PATCH 088/215] AGS: Adding ScummVM graphics init code --- engines/ags/ags.cpp | 14 +++++++++++++- engines/ags/ags.h | 6 ++++++ engines/ags/engine/gfx/ali3dscummvm.cpp | 1 + engines/ags/lib/allegro/gfx.cpp | 5 ++++- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index a872f7d09b58..f9481277af06 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -27,6 +27,7 @@ #include "common/debug-channels.h" #include "common/events.h" #include "common/file.h" +#include "engines/util.h" #include "ags/shared/core/platform.h" #define AGS_PLATFORM_DEFINES_PSP_VARS (AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID) @@ -319,13 +320,16 @@ AGSEngine *g_vm; /*------------------------------------------------------------------*/ AGSEngine::AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc) : Engine(syst), - _gameDescription(gameDesc), _randomSource("AGS"), _screen(nullptr), _gfxDriver(nullptr) { + _gameDescription(gameDesc), _randomSource("AGS"), _rawScreen(nullptr), + _screen(nullptr), _gfxDriver(nullptr) { g_vm = this; DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); } AGSEngine::~AGSEngine() { + delete _screen; + delete _rawScreen; } uint32 AGSEngine::getFeatures() const { @@ -396,4 +400,12 @@ SaveStateList AGSEngine::listSaves() const { return getMetaEngine().listSaves(_targetName.c_str()); } +void AGSEngine::setGraphicsMode(size_t w, size_t h) { + Graphics::PixelFormat FORMAT(4, 8, 8, 8, 8, 24, 16, 8, 0); + initGraphics(w, h, &FORMAT); + + _rawScreen = new Graphics::Screen(); + _screen = new ::AGS3::BITMAP(_rawScreen); +} + } // namespace AGS diff --git a/engines/ags/ags.h b/engines/ags/ags.h index 5099d68c8345..911197309711 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -54,6 +54,7 @@ class AGSEngine : public Engine { const AGSGameDescription *_gameDescription; Common::RandomSource _randomSource; public: + Graphics::Screen *_rawScreen; ::AGS3::BITMAP *_screen; ::AGS3::GFX_DRIVER *_gfxDriver; ::AGS3::AGS::Engine::Mutex _sMutex; @@ -91,6 +92,11 @@ class AGSEngine : public Engine { void setRandomNumberSeed(uint32 seed) { _randomSource.setSeed(seed); } + + /** + * Setse up the graphics mode + */ + void setGraphicsMode(size_t w, size_t h); }; extern AGSEngine *g_vm; diff --git a/engines/ags/engine/gfx/ali3dscummvm.cpp b/engines/ags/engine/gfx/ali3dscummvm.cpp index b588693eb409..27cd4a7099bc 100644 --- a/engines/ags/engine/gfx/ali3dscummvm.cpp +++ b/engines/ags/engine/gfx/ali3dscummvm.cpp @@ -201,6 +201,7 @@ bool ALScummVMGraphicsDriver::SetDisplayMode(const DisplayMode &mode, volatile i OnInit(loopTimer); OnModeSet(mode); + // set_gfx_mode is an allegro function that creates screen bitmap; // following code assumes the screen is already created, therefore we should // ensure global bitmap wraps over existing allegro screen bitmap. diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 5e09aba5f3da..cf7c1564745b 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -21,6 +21,7 @@ */ #include "ags/lib/allegro/gfx.h" +#include "ags/ags.h" #include "common/textconsole.h" #include "graphics/screen.h" @@ -77,7 +78,9 @@ int get_color_conversion() { } int set_gfx_mode(int card, int w, int h, int v_w, int v_h) { - error("TODO: set_gfx_mode"); + assert(card == SCUMMVM_ID); + ::AGS::g_vm->setGraphicsMode(w, h); + return 0; } BITMAP *create_bitmap(int width, int height) { From fa09f4fdd730004b204a157d59b411c128224823 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 10:33:49 -0800 Subject: [PATCH 089/215] AGS: Fix writing initial save state --- engines/ags/shared/util/stdio_compat.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engines/ags/shared/util/stdio_compat.cpp b/engines/ags/shared/util/stdio_compat.cpp index 2bdd48ea293e..449aa39eb7f9 100644 --- a/engines/ags/shared/util/stdio_compat.cpp +++ b/engines/ags/shared/util/stdio_compat.cpp @@ -43,8 +43,9 @@ int ags_fseek(Common::Stream *stream, file_off_t offset, int whence) { file_off_t ags_ftell(Common::Stream *stream) { Common::SeekableReadStream *rs = dynamic_cast(stream); - assert(rs); - return rs->pos(); + Common::SeekableWriteStream *ws = dynamic_cast(stream); + assert(rs || ws); + return rs ? rs->pos() : ws->pos(); } Common::FSNode getFSNode(const char *path) { From 577d434ce78cbb7440e98705d66b2773be5a600c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 11:27:45 -0800 Subject: [PATCH 090/215] AGS: Implement draw_trans_sprite method --- engines/ags/lib/allegro/gfx.cpp | 2 +- engines/ags/lib/allegro/gfx.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index cf7c1564745b..19ec95583d2e 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -210,7 +210,7 @@ void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int } void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { - error("TODO: draw_trans_sprite"); + bmp->getSurface().blitFrom(sprite->getSurface(), Common::Point(x, y)); } void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color) { diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index ee2189429c09..7d83d2b8edc3 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -189,6 +189,12 @@ class BITMAP { Graphics::ManagedSurface &operator*() const { return *_owner; } + Graphics::ManagedSurface &getSurface() { + return *_owner; + } + const Graphics::ManagedSurface &getSurface() const { + return *_owner; + } unsigned char *getPixels() const { return (unsigned char *)_owner->getPixels(); From 08637072ca2442b150100ac44764c82b8babc900 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 12:50:56 -0800 Subject: [PATCH 091/215] AGS: Fixes to WaitForNextFrame --- engines/ags/engine/ac/timer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp index 891471d03f1a..e958287ffdd9 100644 --- a/engines/ags/engine/ac/timer.cpp +++ b/engines/ags/engine/ac/timer.cpp @@ -30,6 +30,7 @@ //include #endif #include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/ags.h" namespace AGS3 { @@ -79,12 +80,14 @@ void WaitForNextFrame() { next_frame_timestamp = now; } - auto frame_time_remaining = next_frame_timestamp - now; - if (frame_time_remaining > std::chrono::milliseconds::zero()) { + if (next_frame_timestamp > now) { + auto frame_time_remaining = next_frame_timestamp - now; std::this_thread::sleep_for(frame_time_remaining); } next_frame_timestamp += frameDuration; + + ::AGS::g_vm->_rawScreen->update(); } bool waitingForNextTick() { From 9a109d73486d9638bd8eafdf5db92a8ac06dba56 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 15:53:06 -0800 Subject: [PATCH 092/215] AGS: Implemented keyboard/mouse event handlers --- engines/ags/ags.cpp | 4 + engines/ags/ags.h | 3 + engines/ags/engine/ac/sys_events.cpp | 11 ++- .../platform/base/agsplatformdriver.cpp | 2 +- engines/ags/events.cpp | 77 ++++++++++++++++ engines/ags/events.h | 69 +++++++++++++++ engines/ags/lib/allegro/keyboard.cpp | 16 ++-- engines/ags/lib/allegro/mouse.cpp | 87 +++++++++++++++++-- engines/ags/module.mk | 1 + 9 files changed, 250 insertions(+), 20 deletions(-) create mode 100644 engines/ags/events.cpp create mode 100644 engines/ags/events.h diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index f9481277af06..6189777dec79 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -22,6 +22,7 @@ #include "ags/ags.h" #include "ags/detection.h" +#include "ags/events.h" #include "common/scummsys.h" #include "common/config-manager.h" #include "common/debug-channels.h" @@ -325,11 +326,14 @@ AGSEngine::AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc) : Engine g_vm = this; DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); + + _events = new EventsManager(); } AGSEngine::~AGSEngine() { delete _screen; delete _rawScreen; + delete _events; } uint32 AGSEngine::getFeatures() const { diff --git a/engines/ags/ags.h b/engines/ags/ags.h index 911197309711..ae6400c2840f 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -48,12 +48,14 @@ enum AGSDebugChannels { }; struct AGSGameDescription; +class EventsManager; class AGSEngine : public Engine { private: const AGSGameDescription *_gameDescription; Common::RandomSource _randomSource; public: + EventsManager *_events; Graphics::Screen *_rawScreen; ::AGS3::BITMAP *_screen; ::AGS3::GFX_DRIVER *_gfxDriver; @@ -102,6 +104,7 @@ class AGSEngine : public Engine { extern AGSEngine *g_vm; #define screen ::AGS::g_vm->_screen #define gfx_driver ::AGS::g_vm->_gfxDriver +#define SHOULD_QUIT ::AGS::g_vm->shouldQuit() } // namespace AGS diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index 7142cb7792ab..53bf7375f5df 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -30,6 +30,7 @@ #include "ags/engine/device/mousew32.h" #include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/engine/ac/timer.h" +#include "ags/ags.h" namespace AGS3 { @@ -260,14 +261,18 @@ int ags_getch() { } void ags_clear_input_buffer() { - while (ags_kbhit()) ags_getch(); - while (mgetbutton() != NONE); + while (!SHOULD_QUIT && ags_kbhit()) + ags_getch(); + + while (!SHOULD_QUIT && mgetbutton() != NONE) { + } } void ags_wait_until_keypress() { - while (!ags_kbhit()) { + while (!SHOULD_QUIT && !ags_kbhit()) { platform->YieldCPU(); } + ags_getch(); } diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index ea977eb50494..cfd02ea60244 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -136,7 +136,7 @@ void AGSPlatformDriver::WriteStdErr(const char *fmt, ...) { void AGSPlatformDriver::YieldCPU() { // NOTE: this is called yield, but if we actually yield instead of delay, // we get a massive increase in CPU usage. - this->Delay(1); + this->Delay(10); //std::this_thread::yield(); } diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp new file mode 100644 index 000000000000..be261c0d132f --- /dev/null +++ b/engines/ags/events.cpp @@ -0,0 +1,77 @@ +/* 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 "ags/events.h" +#include "common/system.h" + +namespace AGS { + +EventsManager *g_events; + +EventsManager::EventsManager() { + g_events = this; +} + +EventsManager::~EventsManager() { + g_events = nullptr; +} + +void EventsManager::pollEvents() { + Common::Event e; + + while (g_system->getEventManager()->pollEvent(e)) { + if (e.type == Common::EVENT_KEYDOWN) { + // Add keypresses to the pending key list + _pendingKeys.push(e.kbd.keycode); + } else { + // Add other event types to the pending events queue. If the event is a + // mouse move and the prior one was also, then discard the prior one. + // This'll help prevent too many mouse move events accumulating + if (e.type == Common::EVENT_MOUSEMOVE && !_pendingEvents.empty() && + _pendingEvents.back().type == Common::EVENT_MOUSEMOVE) + _pendingEvents.back() = e; + else + _pendingEvents.push(e); + } + } +} + +bool EventsManager::keypressed() { + pollEvents(); + return !_pendingKeys.empty(); +} + +int EventsManager::readKey() { + pollEvents(); + return _pendingKeys.empty() ? 0 : _pendingKeys.pop(); +} + +Common::Event EventsManager::readEvent() { + pollEvents(); + return _pendingEvents.empty() ? Common::Event() : _pendingEvents.pop(); +} + +void EventsManager::warpMouse(const Common::Point &newPos) { + g_system->warpMouse(newPos.x, newPos.y); +} + +} // namespace AGS diff --git a/engines/ags/events.h b/engines/ags/events.h new file mode 100644 index 000000000000..71126eee9a54 --- /dev/null +++ b/engines/ags/events.h @@ -0,0 +1,69 @@ +/* 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 AGS_EVENTS_H +#define AGS_EVENTS_H + +#include "common/queue.h" +#include "common/events.h" + +namespace AGS { + +class EventsManager { +private: + Common::Queue _pendingEvents; + Common::Queue _pendingKeys; +public: + EventsManager(); + ~EventsManager(); + + /** + * Poll any pending events + */ + void pollEvents(); + + /** + * Returns true if a keypress is pending + */ + bool keypressed(); + + /** + * Returns the next keypress, if any is pending + */ + int readKey(); + + /** + * Returns the next event, if any + */ + Common::Event readEvent(); + + /** + * Sets the mouse position + */ + void warpMouse(const Common::Point &newPos); +}; + +extern EventsManager *g_events; + +} // namespace AGS + +#endif diff --git a/engines/ags/lib/allegro/keyboard.cpp b/engines/ags/lib/allegro/keyboard.cpp index 652e73815ecf..869ca1655a9e 100644 --- a/engines/ags/lib/allegro/keyboard.cpp +++ b/engines/ags/lib/allegro/keyboard.cpp @@ -26,6 +26,7 @@ #include "common/system.h" #include "common/events.h" #include "common/textconsole.h" +#include "ags/events.h" namespace AGS3 { @@ -42,14 +43,13 @@ void remove_keyboard() { } bool keyboard_needs_poll() { - // TODO: Check if it's okay to be hardcoded for events, since I'm not sure - // how to check with ScummVM event manager for pending events + // We allow allow keyboard polling in ScummVM return true; } int poll_keyboard() { - warning("TODO: poll_keyboard"); - return false; + ::AGS::g_events->pollEvents(); + return 0; } void simulate_keypress(int keycode) { @@ -69,13 +69,11 @@ void simulate_ukeypress(int keycode, int scancode) { } bool keypressed() { - warning("TODO: keypressed"); - return true; + return ::AGS::g_events->keypressed(); } -int readkey(void) { - warning("TODO: readkey"); - return 0; +int readkey() { + return ::AGS::g_events->readKey(); } } // namespace AGS3 diff --git a/engines/ags/lib/allegro/mouse.cpp b/engines/ags/lib/allegro/mouse.cpp index 9c719db02f99..b5cc5ab7ee62 100644 --- a/engines/ags/lib/allegro/mouse.cpp +++ b/engines/ags/lib/allegro/mouse.cpp @@ -21,6 +21,7 @@ */ #include "ags/lib/allegro/mouse.h" +#include "ags/events.h" #include "common/textconsole.h" namespace AGS3 { @@ -35,16 +36,40 @@ BITMAP *mouse_sprite; int mouse_x_focus; int mouse_y_focus; -volatile int mouse_x; -volatile int mouse_y; -volatile int mouse_z; -volatile int mouse_w; -volatile int mouse_b; -volatile int mouse_pos; +volatile int mouse_x; // X position +volatile int mouse_y; // Y position +volatile int mouse_z; // Mouse wheel vertical +volatile int mouse_w; // Mouse wheel horizontal +volatile int mouse_b; // Mouse buttons bitflags +volatile int mouse_pos; // X position in upper 16 bits, Y in lower 16 volatile int freeze_mouse_flag; +static bool isMouseButtonDown(Common::EventType type) { + return type == Common::EVENT_LBUTTONDOWN || type == Common::EVENT_MBUTTONDOWN || + type == Common::EVENT_RBUTTONDOWN; +} + +static bool isMouseButtonUp(Common::EventType type) { + return type == Common::EVENT_LBUTTONUP || type == Common::EVENT_MBUTTONUP || + type == Common::EVENT_RBUTTONUP; +} + +static bool isMouseWheel(Common::EventType type) { + return type == Common::EVENT_WHEELDOWN || type == Common::EVENT_WHEELUP; +} + +static bool isMouseEvent(Common::EventType type) { + return type == Common::EVENT_MOUSEMOVE || isMouseButtonDown(type) || + isMouseButtonUp(type) || isMouseWheel(type); +} + + int install_mouse() { + mouse_x = mouse_y = mouse_z = 0; + mouse_w = mouse_b = 0; + mouse_pos = 0; + return 0; } @@ -52,11 +77,52 @@ void remove_mouse() { } int poll_mouse() { + ::AGS::g_events->pollEvents(); + + Common::Event e; + while ((e = ::AGS::g_events->readEvent()).type != Common::EVENT_INVALID) { + if (isMouseEvent(e.type)) { + mouse_x = e.mouse.x; + mouse_y = e.mouse.y; + mouse_pos = (e.mouse.x << 16) | e.mouse.y; + } + + switch (e.type) { + case Common::EVENT_LBUTTONDOWN: + mouse_b |= 1; + break; + case Common::EVENT_LBUTTONUP: + mouse_b &= ~1; + break; + case Common::EVENT_RBUTTONDOWN: + mouse_b |= 2; + break; + case Common::EVENT_RBUTTONUP: + mouse_b &= ~2; + break; + case Common::EVENT_MBUTTONDOWN: + mouse_b |= 4; + break; + case Common::EVENT_MBUTTONUP: + mouse_b &= ~4; + break; + case Common::EVENT_WHEELDOWN: + ++mouse_z; + break; + case Common::EVENT_WHEELUP: + --mouse_z; + break; + default: + break; + } + } + return 0; } int mouse_needs_poll() { - return 0; + // We can always poll mouse in ScummVM + return true; } void enable_hardware_cursor() { @@ -66,6 +132,7 @@ void disable_hardware_cursor() { } void show_mouse(BITMAP *bmp) { + warning("TODO: show_mouse"); } void scare_mouse() { @@ -78,12 +145,18 @@ void unscare_mouse() { } void position_mouse(int x, int y) { + mouse_x = x; + mouse_y = y; + mouse_pos = (x << 16) | y; + ::AGS::g_events->warpMouse(Common::Point(x, y)); } void position_mouse_z(int z) { + mouse_z = z; } void position_mouse_w(int w) { + mouse_w = w; } void set_mouse_range(int x1, int y_1, int x2, int y2) { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index f6f087df0a81..24a508e4466c 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -2,6 +2,7 @@ MODULE := engines/ags MODULE_OBJS = \ ags.o \ + events.o \ metaengine.o \ lib/aastr-0.1.1/aarot.o \ lib/aastr-0.1.1/aastr.o \ From cea0cf3561601560073e688fa1d62e5b5ef1802c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 16:07:54 -0800 Subject: [PATCH 093/215] AGS: Palette fixes --- engines/ags/lib/allegro/color.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index bc1bdc25eaf0..5bd931a7e700 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -50,26 +50,17 @@ COLOR_MAP *color_map; void set_color(int idx, const RGB *p) { _current_palette[idx] = *p; - g_system->getPaletteManager()->setPalette((const byte *)p, idx, 1); } void set_palette(const PALETTE p) { for (int idx = 0; idx < PAL_SIZE; ++idx) _current_palette[idx] = p[idx]; - g_system->getPaletteManager()->setPalette((const byte *)p, 0, PAL_SIZE); } void set_palette_range(const PALETTE p, int from, int to, int retracesync) { - byte palette[256 * 3]; - byte *destP = palette; - for (int i = 0; i < 256; ++i, destP += 3) { - _current_palette[i] = *p; - destP[0] = p->r; - destP[1] = p->g; - destP[2] = p->b; + for (int i = from; i < to; ++i) { + _current_palette[i] = p[i]; } - - g_system->getPaletteManager()->setPalette(&palette[from], from, to - from + 1); } int makecol15(int r, int g, int b) { From 1392cb572728c9ca54480be89b0c1578f64f69b7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 16:10:30 -0800 Subject: [PATCH 094/215] AGS: Another fix for getting bitmap color depths --- engines/ags/lib/allegro/gfx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 19ec95583d2e..3d7ae5cd172c 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -154,7 +154,7 @@ void clear_to_color(BITMAP *bitmap, int color) { int bitmap_color_depth(BITMAP *bmp) { Graphics::ManagedSurface &surf = **bmp; - return surf.format.bpp(); + return (surf.format.bytesPerPixel == 1) ? 8 : surf.format.bpp(); } int bitmap_mask_color(BITMAP *bmp) { From c073e9390e31686f284eba8cc0fc6ba807d2973a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 18:29:56 -0800 Subject: [PATCH 095/215] AGS: Implemented Allegro PACKFILE --- engines/ags/lib/allegro/file.cpp | 135 +++++++++++++++++++++++++------ engines/ags/lib/allegro/file.h | 135 ++++++++++++++++++++++++++++--- 2 files changed, 237 insertions(+), 33 deletions(-) diff --git a/engines/ags/lib/allegro/file.cpp b/engines/ags/lib/allegro/file.cpp index 1ab7ebacadfd..75f32935f694 100644 --- a/engines/ags/lib/allegro/file.cpp +++ b/engines/ags/lib/allegro/file.cpp @@ -21,11 +21,87 @@ */ #include "ags/lib/allegro/file.h" +#include "common/file.h" #include "common/str.h" #include "common/textconsole.h" namespace AGS3 { +PACKFILE *PACKFILE::pack_fopen_chunk(int pack) { + error("TODO: pack_fopen_chunk is not yet supported"); +} + +PACKFILE *PACKFILE::pack_fclose_chunk() { + error("TODO: pack_fclose_chunk is not yet supported"); +} + +int PACKFILE::pack_igetw() { + byte buf[2]; + return pack_fread(buf, 2) == 2 ? READ_LE_UINT16(buf) : 0; +} + +long PACKFILE::pack_igetl() { + byte buf[4]; + return pack_fread(buf, 4) == 4 ? READ_LE_UINT32(buf) : 0; +} + +int PACKFILE::pack_iputw(int w) { + byte buf[2]; + WRITE_LE_UINT16(buf, w); + pack_fwrite(buf, 2); + return 0; +} + +long PACKFILE::pack_iputl(long l) { + byte buf[4]; + WRITE_LE_UINT32(buf, l); + pack_fwrite(buf, 4); + return 0; +} + +int PACKFILE::pack_mgetw() { + byte buf[2]; + return pack_fread(buf, 2) == 2 ? READ_BE_UINT16(buf) : 0; +} + +long PACKFILE::pack_mgetl() { + byte buf[4]; + return pack_fread(buf, 4) == 4 ? READ_BE_UINT32(buf) : 0; +} + +int PACKFILE::pack_mputw(int w) { + byte buf[2]; + WRITE_BE_UINT16(buf, 2); + pack_fwrite(buf, 2); + return 0; +} + +long PACKFILE::pack_mputl(long l) { + byte buf[4]; + WRITE_BE_UINT16(buf, 4); + pack_fwrite(buf, 4); + return 0; +} + +char *PACKFILE::pack_fgets(char *p, int max) { + int c; + char *dest = p; + + while ((c = pack_getc()) != 0 && !pack_feof() && max-- > 0) { + *dest++ = c; + } + + return p; +} + +int PACKFILE::pack_fputs(AL_CONST char *p) { + pack_fwrite(p, strlen(p)); + pack_putc(0); + return 0; +} + +/*------------------------------------------------------------------*/ + char *fix_filename_case(char *path) { return path; } @@ -55,48 +131,61 @@ int is_relative_filename(const char *filename) { return !fname.contains('/') && !fname.contains('\\') ? 0 : -1; } +/*------------------------------------------------------------------*/ + void packfile_password(AL_CONST char *password) { error("TODO: packfile_password"); } PACKFILE *pack_fopen(AL_CONST char *filename, AL_CONST char *mode) { - error("TODO: pack_fopen"); + assert(!strcmp(mode, "r") || !strcmp(mode, "rb")); + + Common::File *f = new Common::File(); + if (f->open(filename)) { + return new ScummVMPackFile(f); + + } else { + delete f; + return nullptr; + } } PACKFILE *pack_fopen_vtable(AL_CONST PACKFILE_VTABLE *vtable, void *userdata) { - error("TODO: pack_fopen_vtable"); + return new VTablePackFile(vtable, userdata); } int pack_fclose(PACKFILE *f) { - error("TODO: xxx"); + f->close(); + delete f; + return 0; } int pack_fseek(PACKFILE *f, int offset) { - error("TODO: xxx"); + return f->pack_fseek(offset); } PACKFILE *pack_fopen_chunk(PACKFILE *f, int pack) { - error("TODO: xxx"); + return f->pack_fopen_chunk(pack); } PACKFILE *pack_fclose_chunk(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_fclose_chunk(); } int pack_getc(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_getc(); } int pack_putc(int c, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_putc(c); } int pack_feof(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_feof(); } int pack_ferror(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_ferror(); } int pack_igetw(PACKFILE *f) { @@ -104,55 +193,55 @@ int pack_igetw(PACKFILE *f) { } long pack_igetl(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_igetl(); } int pack_iputw(int w, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_iputw(w); } long pack_iputl(long l, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_iputl(l); } int pack_mgetw(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_mgetw(); } long pack_mgetl(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_mgetl(); } int pack_mputw(int w, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_mputw(w); } long pack_mputl(long l, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_mputl(l); } long pack_fread(void *p, long n, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_fread(p, n); } long pack_fwrite(AL_CONST void *p, long n, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_fwrite(p, n); } int pack_ungetc(int c, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_ungetc(c); } char *pack_fgets(char *p, int max, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_fgets(p, max); } int pack_fputs(AL_CONST char *p, PACKFILE *f) { - error("TODO: xxx"); + return f->pack_fputs(p); } void *pack_get_userdata(PACKFILE *f) { - error("TODO: xxx"); + return f->pack_get_userdata(); } } // namespace AGS3 diff --git a/engines/ags/lib/allegro/file.h b/engines/ags/lib/allegro/file.h index abf82d97d595..a551b334b177 100644 --- a/engines/ags/lib/allegro/file.h +++ b/engines/ags/lib/allegro/file.h @@ -24,6 +24,7 @@ #define AGS_LIB_ALLEGRO_FILE_H #include "ags/lib/allegro/alconfig.h" +#include "common/file.h" namespace AGS3 { @@ -69,16 +70,130 @@ struct PACKFILE_VTABLE { * Allegro file class */ struct PACKFILE { - AL_CONST PACKFILE_VTABLE *vtable; - void *userdata; - int is_normal_packfile; - - /* The following is only to be used for the "normal" PACKFILE vtable, - * i.e. what is implemented by Allegro itself. If is_normal_packfile is - * false then the following is not even allocated. This must be the last - * member in the structure. - */ - struct _al_normal_packfile_details normal; + virtual ~PACKFILE() { + close(); + } + + virtual void close() {} + virtual int pack_fseek(int offset) = 0; + virtual int pack_getc() = 0; + virtual int pack_putc(int c) = 0; + virtual int pack_ungetc(int c) = 0; + virtual long pack_fread(void *p, long n) = 0; + virtual long pack_fwrite(AL_CONST void *p, long n) = 0; + virtual int pack_feof() = 0; + virtual int pack_ferror() = 0; + virtual void *pack_get_userdata() const { return nullptr; } + + PACKFILE *pack_fopen_chunk(int pack); + PACKFILE *pack_fclose_chunk(); + int pack_igetw(); + long pack_igetl(); + int pack_iputw(int w); + long pack_iputl(long l); + int pack_mgetw(); + long pack_mgetl(); + int pack_mputw(int w); + long pack_mputl(long l); + char *pack_fgets(char *p, int max); + int pack_fputs(AL_CONST char *p); +}; + +struct ScummVMPackFile : public PACKFILE { +public: + Common::SeekableReadStream *_stream; + + ScummVMPackFile(Common::SeekableReadStream *rs) : PACKFILE(), _stream(rs) { + } + + virtual ~ScummVMPackFile() {} + + void close() override { + delete _stream; + _stream = nullptr; + } + + int pack_fseek(int offset) override { + return _stream->seek(offset); + } + + int pack_getc() override { + return _stream->readByte(); + } + + int pack_putc(int c) override { + error("pack_putc is not yet supported"); + } + + int pack_ungetc(int c) override { + _stream->seek(-1, SEEK_CUR); + return 0; + } + + long pack_fread(void *p, long n) override { + return _stream->read(p, n); + } + + long pack_fwrite(AL_CONST void *p, long n) override { + error("pack_fwrite is not yet supported"); + } + + int pack_feof() override { + return _stream->eos(); + } + + int pack_ferror() override { + return _stream->err(); + } +}; + +struct VTablePackFile : public PACKFILE { + AL_CONST PACKFILE_VTABLE *_vTable; + void *_userData; + + VTablePackFile(AL_CONST PACKFILE_VTABLE *vTable, void *userData) : + _vTable(vTable), _userData(userData) { + } + + void close() override { + _vTable->pf_fclose(_userData); + } + + int pack_fseek(int offset) override { + return _vTable->pf_fseek(_userData, offset); + } + + int pack_getc() override { + return _vTable->pf_getc(_userData); + } + + int pack_putc(int c) override { + return _vTable->pf_putc(c, _userData); + } + + int pack_ungetc(int c) override { + return _vTable->pf_ungetc(c, _userData); + } + + long pack_fread(void *p, long n) override { + return _vTable->pf_fread(p, n, _userData); + } + + long pack_fwrite(AL_CONST void *p, long n) override { + return _vTable->pf_fwrite(p, n, _userData); + } + + int pack_feof() override { + return _vTable->pf_feof(_userData); + } + + int pack_ferror() override { + return _vTable->pf_ferror(_userData); + } + + virtual void *pack_get_userdata() const override { + return _userData; + } }; extern char *fix_filename_case(char *path); From 1726bc0cc28c08e5338f58be7c2d696f52e66325 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 19:51:50 -0800 Subject: [PATCH 096/215] AGS: Remove deprecated MIDI_DRIVER --- engines/ags/lib/audio/midi.cpp | 4 --- engines/ags/lib/audio/midi.h | 55 ++-------------------------------- 2 files changed, 2 insertions(+), 57 deletions(-) diff --git a/engines/ags/lib/audio/midi.cpp b/engines/ags/lib/audio/midi.cpp index 96de121a66f6..ace78dccc16b 100644 --- a/engines/ags/lib/audio/midi.cpp +++ b/engines/ags/lib/audio/midi.cpp @@ -32,10 +32,6 @@ BEGIN_MIDI_DRIVER_LIST { SCUMMVM_ID, &dummy_driver_data, true }, END_MIDI_DRIVER_LIST -MIDI_DRIVER *midi_driver; - -MIDI_DRIVER *midi_input_driver; - int midi_card; int midi_input_card; diff --git a/engines/ags/lib/audio/midi.h b/engines/ags/lib/audio/midi.h index a96048191d5f..37ebf6be81e0 100644 --- a/engines/ags/lib/audio/midi.h +++ b/engines/ags/lib/audio/midi.h @@ -24,67 +24,20 @@ #define AGS_LIB_AUDIO_MIDI_H #include "common/scummsys.h" +#include "common/array.h" #include "ags/lib/allegro/base.h" #include "ags/lib/allegro/alconfig.h" namespace AGS3 { -/* Theoretical maximums: */ -#define MIDI_VOICES 64 /* actual drivers may not be */ -#define MIDI_TRACKS 32 /* able to handle this many */ - /* a midi file */ -struct MIDI { - int divisions; /* number of ticks per quarter note */ - struct { - unsigned char *data; /* MIDI message stream */ - int len; /* length of the track data */ - } track[MIDI_TRACKS]; -}; +typedef Common::Array MIDI; #define MIDI_AUTODETECT -1 #define MIDI_NONE 0 #define MIDI_DIGMID AL_ID('D','I','G','I') -/* driver for playing midi music */ -struct MIDI_DRIVER { - int id; /* driver ID code */ - AL_CONST char *name; /* driver name */ - AL_CONST char *desc; /* description string */ - AL_CONST char *ascii_name; /* ASCII format name string */ - int voices; /* available voices */ - int basevoice; /* voice number offset */ - int max_voices; /* maximum voices we can support */ - int def_voices; /* default number of voices to use */ - int xmin, xmax; /* reserved voice range */ - - /* setup routines */ - AL_METHOD(int, detect, (int input)); - AL_METHOD(int, init, (int input, int voices)); - AL_METHOD(void, exit, (int input)); - AL_METHOD(int, set_mixer_volume, (int volume)); - AL_METHOD(int, get_mixer_volume, (void)); - - /* raw MIDI output to MPU-401, etc. */ - AL_METHOD(void, raw_midi, (int data)); - - /* dynamic patch loading routines */ - AL_METHOD(int, load_patches, (AL_CONST char *patches, AL_CONST char *drums)); - AL_METHOD(void, adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); - - /* note control functions */ - AL_METHOD(void, key_on, (int inst, int note, int bend, int vol, int pan)); - AL_METHOD(void, key_off, (int voice)); - AL_METHOD(void, set_volume, (int voice, int vol)); - AL_METHOD(void, set_pitch, (int voice, int note, int bend)); - AL_METHOD(void, set_pan, (int voice, int pan)); - AL_METHOD(void, set_vibrato, (int voice, int amount)); -}; - - -AL_VAR(MIDI_DRIVER, midi_digmid); - AL_ARRAY(_DRIVER_INFO, _midi_driver_list); @@ -101,10 +54,6 @@ AL_ARRAY(_DRIVER_INFO, _midi_driver_list); { MIDI_DIGMID, &midi_digmid, TRUE }, -AL_VAR(MIDI_DRIVER *, midi_driver); - -AL_VAR(MIDI_DRIVER *, midi_input_driver); - AL_VAR(int, midi_card); AL_VAR(int, midi_input_card); From 3a52732eb0c127de9c03494d4bfb91c8aa990fe8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 20:16:16 -0800 Subject: [PATCH 097/215] AGS: Implemented ScummVM MIDI music player --- engines/ags/ags.cpp | 7 +- engines/ags/ags.h | 2 + .../ags/engine/media/audio/clip_mymidi.cpp | 1 + engines/ags/lib/allegro/file.h | 2 +- engines/ags/lib/audio/midi.cpp | 30 ++++-- engines/ags/lib/audio/midi.h | 6 +- engines/ags/module.mk | 1 + engines/ags/music.cpp | 95 +++++++++++++++++++ engines/ags/music.h | 63 ++++++++++++ 9 files changed, 194 insertions(+), 13 deletions(-) create mode 100644 engines/ags/music.cpp create mode 100644 engines/ags/music.h diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 6189777dec79..a7289c88be60 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -23,6 +23,7 @@ #include "ags/ags.h" #include "ags/detection.h" #include "ags/events.h" +#include "ags/music.h" #include "common/scummsys.h" #include "common/config-manager.h" #include "common/debug-channels.h" @@ -321,19 +322,21 @@ AGSEngine *g_vm; /*------------------------------------------------------------------*/ AGSEngine::AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc) : Engine(syst), - _gameDescription(gameDesc), _randomSource("AGS"), _rawScreen(nullptr), - _screen(nullptr), _gfxDriver(nullptr) { + _gameDescription(gameDesc), _randomSource("AGS"), _events(nullptr), _music(nullptr), + _rawScreen(nullptr), _screen(nullptr), _gfxDriver(nullptr) { g_vm = this; DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); _events = new EventsManager(); + _music = new Music(_mixer); } AGSEngine::~AGSEngine() { delete _screen; delete _rawScreen; delete _events; + delete _music; } uint32 AGSEngine::getFeatures() const { diff --git a/engines/ags/ags.h b/engines/ags/ags.h index ae6400c2840f..f8d0f7e4552f 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -49,6 +49,7 @@ enum AGSDebugChannels { struct AGSGameDescription; class EventsManager; +class Music; class AGSEngine : public Engine { private: @@ -56,6 +57,7 @@ class AGSEngine : public Engine { Common::RandomSource _randomSource; public: EventsManager *_events; + Music *_music; Graphics::Screen *_rawScreen; ::AGS3::BITMAP *_screen; ::AGS3::GFX_DRIVER *_gfxDriver; diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index 2dfbb7204136..ff0a1fd481fe 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -113,6 +113,7 @@ int MYMIDI::play() { lengthInSeconds = get_midi_length(tune); if (AGS3::play_midi(tune, repeat)) { + lengthInSeconds = 0; return 0; } diff --git a/engines/ags/lib/allegro/file.h b/engines/ags/lib/allegro/file.h index a551b334b177..976cbfc94195 100644 --- a/engines/ags/lib/allegro/file.h +++ b/engines/ags/lib/allegro/file.h @@ -114,7 +114,7 @@ struct ScummVMPackFile : public PACKFILE { } int pack_fseek(int offset) override { - return _stream->seek(offset); + return _stream->seek(offset, SEEK_CUR); } int pack_getc() override { diff --git a/engines/ags/lib/audio/midi.cpp b/engines/ags/lib/audio/midi.cpp index ace78dccc16b..503b3b14b7ec 100644 --- a/engines/ags/lib/audio/midi.cpp +++ b/engines/ags/lib/audio/midi.cpp @@ -22,6 +22,7 @@ #include "ags/lib/audio/midi.h" #include "ags/lib/allegro/file.h" +#include "ags/music.h" #include "common/textconsole.h" namespace AGS3 { @@ -49,7 +50,7 @@ int detect_midi_driver(int driver_id) { void stop_midi() { - warning("TODO: stop_midi"); + ::AGS::g_music->stop(); } void destroy_midi(MIDI *midi) { @@ -57,7 +58,7 @@ void destroy_midi(MIDI *midi) { } int play_midi(MIDI *tune, bool repeat) { - warning("TODO: play_midi"); + ::AGS::g_music->playMusic(tune, repeat); return 0; } @@ -67,15 +68,15 @@ size_t get_midi_length(MIDI *tune) { } void midi_seek(int target) { - warning("TODO: midi_seek"); + ::AGS::g_music->seek(target); } void midi_pause() { - warning("TODO: midi_pause"); + ::AGS::g_music->pause(); } void midi_resume() { - warning("TODO: midi_resume"); + ::AGS::g_music->resume(); } int load_midi_patches() { @@ -83,8 +84,25 @@ int load_midi_patches() { return 0; } +#define MIDI_BLOCK_SIZE 32768 + MIDI *load_midi_pf(PACKFILE *fp) { - error("TODO: load_midi_pf"); + MIDI *midi = new MIDI(); + int bytesRead; + + // Iterate through loading blocks of MIDI data + for (;;) { + size_t priorSize = midi->size(); + midi->resize(priorSize + MIDI_BLOCK_SIZE); + bytesRead = pack_fread(&(*midi)[priorSize], MIDI_BLOCK_SIZE, fp); + + if (bytesRead < MIDI_BLOCK_SIZE) { + midi->resize(priorSize + bytesRead); + break; + } + } + + return midi; } } // namespace AGS3 diff --git a/engines/ags/lib/audio/midi.h b/engines/ags/lib/audio/midi.h index 37ebf6be81e0..376f8b919c20 100644 --- a/engines/ags/lib/audio/midi.h +++ b/engines/ags/lib/audio/midi.h @@ -27,19 +27,17 @@ #include "common/array.h" #include "ags/lib/allegro/base.h" #include "ags/lib/allegro/alconfig.h" +#include "ags/music.h" namespace AGS3 { -/* a midi file */ -typedef Common::Array MIDI; - - #define MIDI_AUTODETECT -1 #define MIDI_NONE 0 #define MIDI_DIGMID AL_ID('D','I','G','I') AL_ARRAY(_DRIVER_INFO, _midi_driver_list); +using MIDI = ::AGS::MIDI; /* macros for constructing the driver lists */ #define BEGIN_MIDI_DRIVER_LIST \ diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 24a508e4466c..89c56efde0ea 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -4,6 +4,7 @@ MODULE_OBJS = \ ags.o \ events.o \ metaengine.o \ + music.o \ lib/aastr-0.1.1/aarot.o \ lib/aastr-0.1.1/aastr.o \ lib/aastr-0.1.1/aautil.o \ diff --git a/engines/ags/music.cpp b/engines/ags/music.cpp new file mode 100644 index 000000000000..191335d1e730 --- /dev/null +++ b/engines/ags/music.cpp @@ -0,0 +1,95 @@ +/* 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 "ags/music.h" +#include "audio/midiparser.h" + +namespace AGS { + +Music *g_music; + +Music::Music(Audio::Mixer *mixer) : + Audio::MidiPlayer(), _mixer(mixer) { + g_music = this; + Audio::MidiPlayer::createDriver(); + + int ret = _driver->open(); + if (ret == 0) { + if (_nativeMT32) + _driver->sendMT32Reset(); + else + _driver->sendGMReset(); + + _driver->setTimerCallback(this, &timerCallback); + } +} + +Music::~Music() { + stop(); + g_music = nullptr; +} + +void Music::sendToChannel(byte channel, uint32 b) { + if (!_channelsTable[channel]) { + _channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); + // If a new channel is allocated during the playback, make sure + // its volume is correctly initialized. + if (_channelsTable[channel]) + _channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255); + } + + if (_channelsTable[channel]) + _channelsTable[channel]->send(b); +} + +void Music::playMusic(const MIDI *midi, bool repeat) { + stop(); + + // Load MIDI resource data + int midiMusicSize = midi->size(); + + _midiData.resize(midi->size()); + Common::copy(&(*midi)[0], &(*midi)[0] + midi->size(), &_midiData[0]); + + MidiParser *parser = MidiParser::createParser_SMF(); + if (parser->loadMusic(&_midiData[0], midiMusicSize)) { + parser->setTrack(0); + parser->setMidiDriver(this); + parser->setTimerRate(_driver->getBaseTempo()); + parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1); + + _parser = parser; + + syncVolume(); + + _isLooping = repeat; + _isPlaying = true; + } else { + delete parser; + } +} + +void Music::seek(size_t offset) { + warning("TODO: Music::seek to offset %u", offset); +} + +} // End of namespace AGS diff --git a/engines/ags/music.h b/engines/ags/music.h new file mode 100644 index 000000000000..6b6f09b569d3 --- /dev/null +++ b/engines/ags/music.h @@ -0,0 +1,63 @@ +/* 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 AGS_MUSIC_H +#define AGS_MUSIC_H + +#include "audio/audiostream.h" +#include "audio/midiplayer.h" +#include "audio/mixer.h" +#include "common/array.h" + +namespace AGS { + +// A MIDI file +typedef Common::Array MIDI; + +class Music : public Audio::MidiPlayer { +private: + Audio::Mixer *_mixer; + Audio::SoundHandle _soundHandle; + Common::Array _midiData; +protected: + // Overload Audio::MidiPlayer method + void sendToChannel(byte channel, uint32 b) override; +public: + Music(Audio::Mixer *mixer); + ~Music() override; + + /** + * Play music + */ + void playMusic(const MIDI *midi, bool repeat = false); + + /** + * Seek within the MIDI + */ + void seek(size_t offset); +}; + +extern Music *g_music; + +} // End of namespace AGS + +#endif From af50a85b881ec7758f91bc2c6a350ffd34ae9956 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 20:18:56 -0800 Subject: [PATCH 098/215] AGS: Fix shutdown crash in set_gfx_mode --- engines/ags/lib/allegro/gfx.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 3d7ae5cd172c..fe8f3e6d9cda 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -78,8 +78,11 @@ int get_color_conversion() { } int set_gfx_mode(int card, int w, int h, int v_w, int v_h) { - assert(card == SCUMMVM_ID); - ::AGS::g_vm->setGraphicsMode(w, h); + // Graphics shutdown can be ignored + if (card != -1) { + assert(card == SCUMMVM_ID); + ::AGS::g_vm->setGraphicsMode(w, h); + } return 0; } From 44faee520f3ad606290e1b2128e77fe25c44f266 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 20:34:51 -0800 Subject: [PATCH 099/215] AGS: Added detection for AGDI KQ2 --- engines/ags/detection.cpp | 5 +---- engines/ags/detection_tables.h | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/engines/ags/detection.cpp b/engines/ags/detection.cpp index 7956183a508c..204906a2d5c9 100644 --- a/engines/ags/detection.cpp +++ b/engines/ags/detection.cpp @@ -25,10 +25,7 @@ #include "ags/detection_tables.h" AGSMetaEngineDetection::AGSMetaEngineDetection() : AdvancedMetaEngineDetection(AGS::GAME_DESCRIPTIONS, - sizeof(AGS::AGSGameDescription), AGS::AGS_GAMES) { - static const char *const DIRECTORY_GLOBS[2] = { "usecode", 0 }; - _maxScanDepth = 2; - _directoryGlobs = DIRECTORY_GLOBS; + sizeof(AGS::AGSGameDescription), AGS::GAME_NAMES) { } REGISTER_PLUGIN_STATIC(AGS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, AGSMetaEngineDetection); diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index d7c4411af872..07fcfd54d676 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -22,26 +22,30 @@ namespace AGS { -static const PlainGameDescriptor AGS_GAMES[] = { +static const PlainGameDescriptor GAME_NAMES[] = { { "ags", "Adventure Game Studio Game" }, { "bcremake", "Black Cauldron Remake" }, + { "kq2agdi", "Kings Quest II - Romancing The Stones" }, + { 0, 0 } }; +#define ENGLISH_ENTRY(ID, FILENAME, MD5, SIZE) { \ + { \ + ID, \ + nullptr, \ + AD_ENTRY1s(FILENAME, MD5, SIZE), \ + Common::EN_ANY, \ + Common::kPlatformUnknown, \ + ADGF_NO_FLAGS, \ + GUIO1(GUIO_NOSPEECH) \ + } \ + } static const AGSGameDescription GAME_DESCRIPTIONS[] = { - { - { - "bcremake", - nullptr, - AD_ENTRY1s("bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), - Common::EN_ANY, - Common::kPlatformDOS, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOSPEECH) - } - }, + ENGLISH_ENTRY("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), + ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), { AD_TABLE_END_MARKER } }; From e29846eb705c39ef9ef603065decf12fe0740717 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 20:39:39 -0800 Subject: [PATCH 100/215] AGS: Added detection for A Tale of Two Kingdoms --- engines/ags/detection_tables.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 07fcfd54d676..ec98ce52e46e 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -25,6 +25,7 @@ namespace AGS { static const PlainGameDescriptor GAME_NAMES[] = { { "ags", "Adventure Game Studio Game" }, + { "atotk", "A Tale Of Two Kingdoms" }, { "bcremake", "Black Cauldron Remake" }, { "kq2agdi", "Kings Quest II - Romancing The Stones" }, @@ -45,6 +46,7 @@ static const PlainGameDescriptor GAME_NAMES[] = { static const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), + ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), { AD_TABLE_END_MARKER } From 9c7f7a3194390574c5f4a1c9bcda1ab5b4da0e76 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 21:56:42 -0800 Subject: [PATCH 101/215] AGS: Added framework for implementing AGS plugin DLLs in code --- engines/ags/engine/plugin/library.cpp | 12 +- engines/ags/module.mk | 4 +- engines/ags/plugins/agscreditz/agscreditz.cpp | 39 +++++++ engines/ags/plugins/agscreditz/agscreditz.h | 43 +++++++ engines/ags/plugins/dll.cpp | 105 ++++++++++++++++++ engines/ags/plugins/dll.h | 75 +++++++++++++ 6 files changed, 271 insertions(+), 7 deletions(-) create mode 100644 engines/ags/plugins/agscreditz/agscreditz.cpp create mode 100644 engines/ags/plugins/agscreditz/agscreditz.h create mode 100644 engines/ags/plugins/dll.cpp create mode 100644 engines/ags/plugins/dll.h diff --git a/engines/ags/engine/plugin/library.cpp b/engines/ags/engine/plugin/library.cpp index 44c6e1a06a6d..7b64088194eb 100644 --- a/engines/ags/engine/plugin/library.cpp +++ b/engines/ags/engine/plugin/library.cpp @@ -21,24 +21,24 @@ */ #include "ags/engine/plugin/library.h" +#include "ags/plugins/dll.h" namespace AGS3 { void *dlopen(const char *filename, bool) { - // TODO: Reimplement plugins as C++ code that's part of the project - return nullptr; + return ::AGS::Plugins::dlopen(filename); } -int dlclose(void *) { - return 0; +int dlclose(void *lib) { + return ::AGS::Plugins::dlclose(lib); } void *dlsym(void *lib, const char *method) { - return nullptr; + return ::AGS::Plugins::dlsym(lib, method); } const char *dlerror() { - return nullptr; + return ::AGS::Plugins::dlerror(); } } // namespace AGS3 diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 89c56efde0ea..eeda8d7f1556 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -307,7 +307,9 @@ MODULE_OBJS = \ engine/script/script_api.o \ engine/script/script_engine.o \ engine/script/script_runtime.o \ - engine/script/systemimports.o + engine/script/systemimports.o \ + plugins/dll.o \ + plugins/agscreditz\agscreditz.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/plugins/agscreditz/agscreditz.cpp b/engines/ags/plugins/agscreditz/agscreditz.cpp new file mode 100644 index 000000000000..2c53d438fab5 --- /dev/null +++ b/engines/ags/plugins/agscreditz/agscreditz.cpp @@ -0,0 +1,39 @@ +/* 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 "ags/plugins/agscreditz/agscreditz.h" + +namespace AGS { +namespace Plugins { +namespace AgsCreditz { + +AgsCreditz::AgsCreditz() { + ADD_METHOD(AGS_GetPluginName); +} + +const char *AgsCreditz::AGS_GetPluginName() { + return "agsCreditz v1.1 by AJA"; +} + +} // namespace AgsCreditz +} // namespace Plugins +} // namespace AGS diff --git a/engines/ags/plugins/agscreditz/agscreditz.h b/engines/ags/plugins/agscreditz/agscreditz.h new file mode 100644 index 000000000000..25b5da8b0a7d --- /dev/null +++ b/engines/ags/plugins/agscreditz/agscreditz.h @@ -0,0 +1,43 @@ +/* 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 AGS_PLUGINS_AGSCREDITZ_AGSCREDITZ_H +#define AGS_PLUGINS_AGSCREDITZ_AGSCREDITZ_H + +#include "ags/plugins/dll.h" + +namespace AGS { +namespace Plugins { +namespace AgsCreditz { + +class AgsCreditz : public DLL { +private: + static const char *AGS_GetPluginName(); +public: + AgsCreditz(); +}; + +} // namespace AgsCreditz +} // namespace Plugins +} // namespace AGS + +#endif diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp new file mode 100644 index 000000000000..65d6d13f6c2d --- /dev/null +++ b/engines/ags/plugins/dll.cpp @@ -0,0 +1,105 @@ +/* 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 "ags/plugins/dll.h" +#include "ags/plugins/agscreditz/agscreditz.h" +#include "common/str.h" + +namespace AGS { +namespace Plugins { + +void *dlopen(const char *filename) { + Common::String fname(filename); + + if (fname.equalsIgnoreCase("libagsCreditz.so")) + return new AgsCreditz::AgsCreditz(); + + return nullptr; +} + +int dlclose(void *lib) { + delete lib; + return 0; +} + +void *dlsym(void *lib, const char *method) { + DLL *dll = static_cast(lib); + return (*dll)[method]; +} + +const char *dlerror() { + return nullptr; +} + +/*------------------------------------------------------------------*/ + +DLL::DLL() { + ADD_METHOD(AGS_PluginV2); + ADD_METHOD(AGS_EditorStartup); + ADD_METHOD(AGS_EditorShutdown); + ADD_METHOD(AGS_EditorProperties); + ADD_METHOD(AGS_EditorSaveGame); + ADD_METHOD(AGS_EditorLoadGame); + ADD_METHOD(AGS_EngineStartup); + ADD_METHOD(AGS_EngineShutdown); + ADD_METHOD(AGS_EngineOnEvent); + ADD_METHOD(AGS_EngineDebugHook); + ADD_METHOD(AGS_EngineInitGfx); +} + +int DLL::AGS_EditorStartup(IAGSEditor *) { + return 0; +} + +void DLL::AGS_EditorShutdown() { +} + +void DLL::AGS_EditorProperties(HWND) { +} + +int DLL::AGS_EditorSaveGame(char *, int) { + return 0; +} + +void DLL::AGS_EditorLoadGame(char *, int) { +} + +void DLL::AGS_EngineStartup(IAGSEngine *) { +} + +void DLL::AGS_EngineShutdown() { +} + +int DLL::AGS_EngineOnEvent(int, int) { + return 0; +} + +int DLL::AGS_EngineDebugHook(const char *, int, int) { + return 0; +} + +void DLL::AGS_EngineInitGfx(const char *driverID, void *data) { + assert(!strcmp(driverID, "Software")); +} + +} // namespace Plugins +} // namespace AGS diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h new file mode 100644 index 000000000000..abe2edd14bd7 --- /dev/null +++ b/engines/ags/plugins/dll.h @@ -0,0 +1,75 @@ +/* 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 AGS_PLUGINS_DLL_H +#define AGS_PLUGINS_DLL_H + +#include "common/hashmap.h" +#include "common/hash-str.h" + +namespace AGS { +namespace Plugins { + +#define ADD_METHOD(NAME) _methods[#NAME] = (void *)&NAME + +typedef void *IAGSEditor; +typedef void *IAGSEngine; +typedef uint32 HWND; + +/** + * Base class for the implementation of AGS plugin DLLs + */ +class DLL { +protected: + Common::HashMap _methods; + + static int AGS_PluginV2() { return 1; } + static int AGS_EditorStartup(IAGSEditor *); + static void AGS_EditorShutdown(); + static void AGS_EditorProperties(HWND); + static int AGS_EditorSaveGame(char *, int); + static void AGS_EditorLoadGame(char *, int); + static void AGS_EngineStartup(IAGSEngine *); + static void AGS_EngineShutdown(); + static int AGS_EngineOnEvent(int, int); + static int AGS_EngineDebugHook(const char *, int, int); + static void AGS_EngineInitGfx(const char *driverID, void *data); +public: + DLL(); + + void *operator[](const Common::String &methodName) const { + return _methods[methodName]; + } +}; + +extern void *dlopen(const char *filename); + +extern int dlclose(void *lib); + +extern void *dlsym(void *lib, const char *method); + +extern const char *dlerror(); + +} // namespace Plugins +} // namespace AGS + +#endif From dcc0077cd9e28d135d3c76ac8d118b091c241bcd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jan 2021 22:37:39 -0800 Subject: [PATCH 102/215] AGS: Add script method stubs for AgsCreditZ --- engines/ags/plugins/agscreditz/agscreditz.cpp | 98 ++++++++++++++++++- engines/ags/plugins/agscreditz/agscreditz.h | 25 ++++- engines/ags/plugins/dll.cpp | 22 ++--- engines/ags/plugins/dll.h | 12 ++- 4 files changed, 141 insertions(+), 16 deletions(-) diff --git a/engines/ags/plugins/agscreditz/agscreditz.cpp b/engines/ags/plugins/agscreditz/agscreditz.cpp index 2c53d438fab5..bae5322bc043 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.cpp +++ b/engines/ags/plugins/agscreditz/agscreditz.cpp @@ -27,13 +27,109 @@ namespace Plugins { namespace AgsCreditz { AgsCreditz::AgsCreditz() { - ADD_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); } const char *AgsCreditz::AGS_GetPluginName() { return "agsCreditz v1.1 by AJA"; } +void AgsCreditz::AGS_EngineStartup(IAGSEngine *engine) { + SCRIPT_METHOD(SetCredit); + SCRIPT_METHOD(ScrollCredits); + SCRIPT_METHOD(GetCredit); + SCRIPT_METHOD(IsCreditScrollingFinished); + SCRIPT_METHOD(SetCreditImage); + SCRIPT_METHOD(PauseScroll); + SCRIPT_METHOD(ScrollReset); + SCRIPT_METHOD(SetEmptyLineHeight); + SCRIPT_METHOD(GetEmptyLineHeight); + SCRIPT_METHOD(SetStaticCredit); + SCRIPT_METHOD(GetStaticCredit); + SCRIPT_METHOD(StartEndStaticCredits); + SCRIPT_METHOD(GetCurrentStaticCredit); + SCRIPT_METHOD(SetDefaultStaticDelay); + SCRIPT_METHOD(SetStaticPause); + SCRIPT_METHOD(SetStaticCreditTitle); + SCRIPT_METHOD(ShowStaticCredit); + SCRIPT_METHOD(StaticReset); + SCRIPT_METHOD(GetStaticCreditTitle); + SCRIPT_METHOD(SetStaticCreditImage); + SCRIPT_METHOD(IsStaticCreditsFinished); +} + +void AgsCreditz::SetCredit(int ID, string credit, int colour, int font, int center, int xpos, int generateoutline) { +} + +void AgsCreditz::ScrollCredits(int onoff, int speed, int fromY, int toY, int isautom, int wait, int res) { +} + +string AgsCreditz::GetCredit(int ID) { + return string(); +} + +int AgsCreditz::IsCreditScrollingFinished() { + return true; +} + +void AgsCreditz::SetCreditImage(int ID, int Slot, int center, int xpos, int pixtonext) { +} + +void AgsCreditz::PauseScroll(int onoff) { +} + +void AgsCreditz::ScrollReset() { +} + +void AgsCreditz::SetEmptyLineHeight(int Height) { +} + +int AgsCreditz::GetEmptyLineHeight() { + return 0; +} + +void AgsCreditz::SetStaticCredit(int ID, int x, int y, int creditfont, int creditcolour, int centered, int generateoutline, string credit) { + +} + +string AgsCreditz::GetStaticCredit(int ID) { + return string(); +} + +void AgsCreditz::StartEndStaticCredits(int onoff, int res) { +} + +int AgsCreditz::GetCurrentStaticCredit() { + return 0; +} + +void AgsCreditz::SetDefaultStaticDelay(int Cyclesperchar) { +} + +void AgsCreditz::SetStaticPause(int ID, int length) { +} + +void AgsCreditz::SetStaticCreditTitle(int ID, int x, int y, int titlefont, int titlecolour, int centered, int generateoutline, string title) { +} + +void AgsCreditz::ShowStaticCredit(int ID, int time, int style, int transtime, int sound, int resolution) { +} + +void AgsCreditz::StaticReset() { +} + +string AgsCreditz::GetStaticCreditTitle(int ID) { + return string(); +} + +void AgsCreditz::SetStaticCreditImage(int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time) { +} + +int AgsCreditz::IsStaticCreditsFinished() { + return true; +} + } // namespace AgsCreditz } // namespace Plugins } // namespace AGS diff --git a/engines/ags/plugins/agscreditz/agscreditz.h b/engines/ags/plugins/agscreditz/agscreditz.h index 25b5da8b0a7d..60962602187d 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.h +++ b/engines/ags/plugins/agscreditz/agscreditz.h @@ -7,7 +7,7 @@ * 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. + * 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 @@ -32,6 +32,29 @@ namespace AgsCreditz { class AgsCreditz : public DLL { private: static const char *AGS_GetPluginName(); + static void AGS_EngineStartup(IAGSEngine *engine); + + static void SetCredit(int ID, string credit, int colour, int font, int center, int xpos, int generateoutline); + static void ScrollCredits(int onoff, int speed, int fromY, int toY, int isautom, int wait, int res); + static string GetCredit(int ID); + static int IsCreditScrollingFinished(); + static void SetCreditImage(int ID, int Slot, int center, int xpos, int pixtonext); + static void PauseScroll(int onoff); + static void ScrollReset(); + static void SetEmptyLineHeight(int Height); + static int GetEmptyLineHeight(); + static void SetStaticCredit(int ID, int x, int y, int creditfont, int creditcolour, int centered, int generateoutline, string credit); + static string GetStaticCredit(int ID); + static void StartEndStaticCredits(int onoff, int res); + static int GetCurrentStaticCredit(); + static void SetDefaultStaticDelay(int Cyclesperchar); + static void SetStaticPause(int ID, int length); + static void SetStaticCreditTitle(int ID, int x, int y, int titlefont, int titlecolour, int centered, int generateoutline, string title); + static void ShowStaticCredit(int ID, int time, int style, int transtime, int sound, int resolution); + static void StaticReset(); + static string GetStaticCreditTitle(int ID); + static void SetStaticCreditImage(int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time); + static int IsStaticCreditsFinished(); public: AgsCreditz(); }; diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index 65d6d13f6c2d..405cecee6be6 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -53,17 +53,17 @@ const char *dlerror() { /*------------------------------------------------------------------*/ DLL::DLL() { - ADD_METHOD(AGS_PluginV2); - ADD_METHOD(AGS_EditorStartup); - ADD_METHOD(AGS_EditorShutdown); - ADD_METHOD(AGS_EditorProperties); - ADD_METHOD(AGS_EditorSaveGame); - ADD_METHOD(AGS_EditorLoadGame); - ADD_METHOD(AGS_EngineStartup); - ADD_METHOD(AGS_EngineShutdown); - ADD_METHOD(AGS_EngineOnEvent); - ADD_METHOD(AGS_EngineDebugHook); - ADD_METHOD(AGS_EngineInitGfx); + DLL_METHOD(AGS_PluginV2); + DLL_METHOD(AGS_EditorStartup); + DLL_METHOD(AGS_EditorShutdown); + DLL_METHOD(AGS_EditorProperties); + DLL_METHOD(AGS_EditorSaveGame); + DLL_METHOD(AGS_EditorLoadGame); + DLL_METHOD(AGS_EngineStartup); + DLL_METHOD(AGS_EngineShutdown); + DLL_METHOD(AGS_EngineOnEvent); + DLL_METHOD(AGS_EngineDebugHook); + DLL_METHOD(AGS_EngineInitGfx); } int DLL::AGS_EditorStartup(IAGSEditor *) { diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h index abe2edd14bd7..e3fedacf8850 100644 --- a/engines/ags/plugins/dll.h +++ b/engines/ags/plugins/dll.h @@ -23,16 +23,22 @@ #ifndef AGS_PLUGINS_DLL_H #define AGS_PLUGINS_DLL_H +#include "ags/shared/util/string.h" +#include "ags/engine/plugin/agsplugin.h" #include "common/hashmap.h" #include "common/hash-str.h" namespace AGS { namespace Plugins { -#define ADD_METHOD(NAME) _methods[#NAME] = (void *)&NAME +#define DLL_METHOD(NAME) _methods[#NAME] = (void *)&NAME +#define SCRIPT_METHOD(NAME) engine->RegisterScriptFunction(#NAME, (void *)&NAME) -typedef void *IAGSEditor; -typedef void *IAGSEngine; +// TODO: Refactor string into core AGS namespace +using string = ::AGS3::AGS::Shared::String; + +using IAGSEngine = ::AGS3::IAGSEngine; +using IAGSEditor = ::AGS3::IAGSEditor; typedef uint32 HWND; /** From 79cb66ef1da5c4062534880691848d9a01e72c8c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 11 Jan 2021 18:31:23 -0800 Subject: [PATCH 103/215] AGS: Set ManagedSurface palette when blitting to screen --- engines/ags/lib/allegro/color.cpp | 10 ++++++++++ engines/ags/lib/allegro/color.h | 2 ++ engines/ags/lib/allegro/gfx.cpp | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 5bd931a7e700..9bbe56d2ec82 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -63,6 +63,16 @@ void set_palette_range(const PALETTE p, int from, int to, int retracesync) { } } +void palette_to_rgb8(const PALETTE src, byte dest[PALETTE_SIZE]) { + byte *pDest = dest; + for (int i = 0; i < 256; ++i, pDest += 3) { + pDest[0] = src[i].r; + pDest[1] = src[i].g; + pDest[2] = src[i].b; + } +} + + int makecol15(int r, int g, int b) { return (((r >> 3) << _rgb_r_shift_15) | ((g >> 3) << _rgb_g_shift_15) | diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index 8dc105c49139..f0a25c06006e 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -24,6 +24,7 @@ #define AGS_LIB_ALLEGRO_COLOR_H #include "common/scummsys.h" +#include "graphics/screen.h" #include "ags/lib/allegro/base.h" #include "ags/lib/allegro/alconfig.h" @@ -89,6 +90,7 @@ AL_ARRAY(int, _rgb_scale_6); AL_FUNC(void, set_color, (int idx, AL_CONST RGB *p)); AL_FUNC(void, set_palette, (AL_CONST PALETTE p)); AL_FUNC(void, set_palette_range, (AL_CONST PALETTE p, int from, int to, int retracesync)); +AL_FUNC(void, palette_to_rgb8, (AL_CONST PALETTE src, byte dest[PALETTE_SIZE])); AL_FUNC(void, get_color, (int idx, RGB *p)); AL_FUNC(void, get_palette, (PALETTE p)); diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index fe8f3e6d9cda..492bae84fc9e 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -169,6 +169,12 @@ void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; + if (srcS.format.bytesPerPixel == 1 && dest->format.bytesPerPixel > 1) { + byte pal[PALETTE_SIZE]; + palette_to_rgb8(_current_palette, pal); + srcS.setPalette(pal, 0, PALETTE_COUNT); + } + destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y)); } From 96b1b4393eb395343a1c44f4aa3bdd42a9ffb7e8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 11 Jan 2021 21:30:05 -0800 Subject: [PATCH 104/215] AGS: Reimplement std::map from scratch Previously it was an alias for Common::HashMap, but map needs to have an array of key/value items ordered by the key. As such, I changed it to internally use a Common::Array --- engines/ags/engine/ac/dynobj/scriptdict.h | 2 +- engines/ags/lib/std/map.h | 155 +++++++++++++++++++--- 2 files changed, 135 insertions(+), 22 deletions(-) diff --git a/engines/ags/engine/ac/dynobj/scriptdict.h b/engines/ags/engine/ac/dynobj/scriptdict.h index 8d6210da2794..89a8cb76e5e7 100644 --- a/engines/ags/engine/ac/dynobj/scriptdict.h +++ b/engines/ags/engine/ac/dynobj/scriptdict.h @@ -187,7 +187,7 @@ class ScriptDictImpl final : public ScriptDictBase { typedef ScriptDictImpl< std::map, true, true > ScriptDict; // TODO: Not sure if current std::map implement works for LessThan to give a key ordering -typedef ScriptDictImpl< std::map, true, false > ScriptDictCI; +typedef ScriptDictImpl< std::map, true, false > ScriptDictCI; typedef ScriptDictImpl< std::unordered_map, false, true > ScriptHashDict; typedef ScriptDictImpl< std::unordered_map, false, false > ScriptHashDictCI; diff --git a/engines/ags/lib/std/map.h b/engines/ags/lib/std/map.h index a5f080952bd6..d4d2b87da5fd 100644 --- a/engines/ags/lib/std/map.h +++ b/engines/ags/lib/std/map.h @@ -29,40 +29,153 @@ namespace AGS3 { namespace std { -template, - class EqualFunc = Common::EqualTo > -class map : public Common::HashMap { +template > +class map { + struct KeyValue { + Key _key; + Val _value; + }; +private: + Common::Array _items; + CompFunc _comp; public: - using iterator = typename Common::HashMap::iterator; + using iterator = typename Common::Array::iterator; + using const_iterator = typename Common::Array::const_iterator; - pair insert(pair elem) { - this->operator[](elem.first) = elem.second; - return elem; + /** + * Clears the map + */ + void clear() { + _items.clear(); + } + + /** + * Gets the iterator start + */ + iterator begin() { + return _items.begin(); + } + + /** + * Get the iterator end + */ + iterator end() { + return _items.end(); + } + + /** + * Get the const iterator start + */ + const_iterator begin() const { + return _items.begin(); + } + + /** + * Get the const iterator end + */ + const_iterator end() const { + return _items.end(); + } + + /** + * Returns an iterator for the first element of the map that is + * not less than the given key + */ + const_iterator lower_bound(const Key &theKey) const { + const_iterator first = this->begin(); + const_iterator it; + int count = _items.size(), step; + + while (count > 0) { + it = first; + step = count / 2; + it += step; + + if (_comp(it->_key, theKey)) { + first = ++it; + count -= step + 1; + } else { + count = step; + } + } + + return first; } - // FUNCTION TEMPLATE lower_bound - iterator lower_bound(Key &val) { + iterator lower_bound(const Key &theKey) { + iterator first = this->begin(); iterator it; - for (it = this->begin(); it != this->end(); ++it) { - if (it->_key >= val) - break; + int count = _items.size(), step; + + while (count > 0) { + it = first; + step = count / 2; + it += step; + + if (_comp(it->_key, theKey)) { + first = ++it; + count -= step + 1; + } else { + count = step; + } } - return it; + return first; } /** - * Checks if the maps have identical contents + * Find the entry with the given key */ - bool operator==(const map &rhs) { - if (this->size() != rhs.size()) - return false; - for (iterator it = this->begin(); it != this->end(); ++it) { - if (!(it->_value == rhs[it->_key])) - return false; + iterator find(const Key &theKey) { + iterator it = this->lower_bound(theKey); + + if (it != this->end() && it->_key == theKey) + return it; + return this->end(); + } + + const_iterator find(const Key &theKey) const { + const_iterator it = this->lower_bound(theKey); + + if (it != this->end() && it->_key == theKey) + return it; + return this->end(); + } + + /** + * Square brackets operator accesses items by key, creating if necessary + */ + Val &operator[](const Key &theKey) { + iterator it = this->lower_bound(theKey); + if (it == this->end() || it->_key != theKey) { + size_t idx = it - this->begin(); + _items.insert_at(idx, KeyValue()); + _items[idx]._key = theKey; + return _items[idx]._value; + } else { + return _items[it - this->begin()]._value; } + } + + /** + * Erases an entry in the map + */ + iterator erase(iterator it) { + iterator next = it; + ++next; + _items.remove_at(it - begin()); + return next; + } + + iterator erase(const Key &theKey) { + return erase(find(theKey)); + } - return true; + /** + * Returns the size of the map + */ + size_t size() const { + return _items.size(); } }; From 4f4c43e5c477ec690233307440262accfa38f222 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 11 Jan 2021 21:38:02 -0800 Subject: [PATCH 105/215] AGS: Set palette if needed for other blitting methods --- engines/ags/lib/allegro/gfx.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 492bae84fc9e..21a8cdce1721 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -165,15 +165,19 @@ int bitmap_mask_color(BITMAP *bmp) { return surf.getTransparentColor(); } +void add_palette_if_needed(Graphics::ManagedSurface &src, Graphics::ManagedSurface &dest) { + if (src.format.bytesPerPixel == 1 && dest.format.bytesPerPixel > 1) { + byte pal[PALETTE_SIZE]; + palette_to_rgb8(_current_palette, pal); + src.setPalette(pal, 0, PALETTE_COUNT); + } +} + void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height) { Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; - if (srcS.format.bytesPerPixel == 1 && dest->format.bytesPerPixel > 1) { - byte pal[PALETTE_SIZE]; - palette_to_rgb8(_current_palette, pal); - srcS.setPalette(pal, 0, PALETTE_COUNT); - } + add_palette_if_needed(srcS, destS); destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y)); } @@ -183,6 +187,8 @@ void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, i Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; + add_palette_if_needed(srcS, destS); + destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height)); } @@ -191,6 +197,8 @@ void masked_blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_ Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; + add_palette_if_needed(srcS, destS); + destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y)); } @@ -199,6 +207,8 @@ void masked_stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int sour Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; + add_palette_if_needed(srcS, destS); + destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height)); } @@ -207,6 +217,8 @@ void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { Graphics::ManagedSurface &bmpS = **bmp; Graphics::ManagedSurface &spriteS = **sprite; + add_palette_if_needed(spriteS, bmpS); + bmpS.blitFrom(spriteS, Common::Point(x, y)); } @@ -214,6 +226,8 @@ void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int Graphics::ManagedSurface &bmpS = **bmp; Graphics::ManagedSurface &spriteS = **sprite; + add_palette_if_needed(spriteS, bmpS); + bmpS.transBlitFrom(spriteS, Common::Rect(0, 0, sprite->w, sprite->h), Common::Rect(x, y, x + w, y + h)); } From 33c9c5ff835fc323e3e160b4b3602d49b8d1a950 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 11 Jan 2021 22:07:56 -0800 Subject: [PATCH 106/215] AGS: Implement clipping methods, fixing rendering of text dialogs --- engines/ags/lib/allegro/gfx.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 21a8cdce1721..e25484370eb2 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -33,7 +33,7 @@ int color_conversion; BITMAP::BITMAP(Graphics::ManagedSurface *owner) : _owner(owner), w(owner->w), h(owner->h), format(owner->format), - clip(false), ct(0), cb(0), cl(0), cr(0) { + clip(false), ct(0), cl(0), cr(owner->w), cb(owner->h) { line.resize(h); for (uint y = 0; y < h; ++y) line[y] = (byte *)_owner->getBasePtr(0, y); @@ -128,16 +128,25 @@ void destroy_bitmap(BITMAP *bitmap) { } void set_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) { - warning("TODO: set_clip_rect"); + bitmap->cl = x1; + bitmap->ct = y1; + bitmap->cr = x2; + bitmap->cb = y2; } -void add_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) { - warning("TODO: add_clip_rect"); +void get_clip_rect(BITMAP *bitmap, int *x1, int *y1, int *x2, int *y2) { + if (x1) + *x1 = bitmap->cl; + if (y1) + *y1 = bitmap->ct; + if (x2) + *x2 = bitmap->cr; + if (y2) + *y2 = bitmap->cb; } -void get_clip_rect(BITMAP *bitmap, int *x1, int *y1, int *x2, int *y2) { - warning("TODO: get_clip_rect"); - *x1 = *y1 = *x2 = *y2 = 0; +void add_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) { + warning("TODO: add_clip_rect"); } void acquire_bitmap(BITMAP *bitmap) { From 67ca16ce11317eb472046a922c11e5209796a2ae Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 11 Jan 2021 22:29:04 -0800 Subject: [PATCH 107/215] AGS: Hook up ScummVM window close to exit game --- engines/ags/engine/main/engine.cpp | 7 ------- engines/ags/events.cpp | 12 +++++++++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index b90cee75c141..626e7ce4dc95 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -143,18 +143,11 @@ void engine_setup_allegro() { override_config_data(al_config_data, ustrsize(al_config_data)); } -void winclosehook() { - want_exit = 1; - abort_engine = 1; - check_dynamic_sprites_at_exit = 0; -} - void engine_setup_window() { Debug::Printf(kDbgMsg_Info, "Setting up window"); our_eip = -198; //set_window_title("Adventure Game Studio"); - set_close_button_callback(winclosehook); our_eip = -197; platform->SetGameWindowIcon(); diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp index be261c0d132f..c96279ad888c 100644 --- a/engines/ags/events.cpp +++ b/engines/ags/events.cpp @@ -23,6 +23,11 @@ #include "ags/events.h" #include "common/system.h" +namespace AGS3 { +extern volatile char want_exit, abort_engine; +extern char check_dynamic_sprites_at_exit; +} + namespace AGS { EventsManager *g_events; @@ -39,7 +44,12 @@ void EventsManager::pollEvents() { Common::Event e; while (g_system->getEventManager()->pollEvent(e)) { - if (e.type == Common::EVENT_KEYDOWN) { + if (e.type == Common::EVENT_QUIT) { + ::AGS3::want_exit = 1; + ::AGS3::abort_engine = 1; + ::AGS3::check_dynamic_sprites_at_exit = 0; + + } else if (e.type == Common::EVENT_KEYDOWN) { // Add keypresses to the pending key list _pendingKeys.push(e.kbd.keycode); } else { From d28e3e3b1b49ac46fa647a35559810b18452e8b3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jan 2021 18:01:35 -0800 Subject: [PATCH 108/215] AGS: Fix free after delete in PosixLibrary unload --- engines/ags/engine/util/library_posix.h | 5 ++++- engines/ags/plugins/dll.cpp | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index ceb39cf21bca..a966281fa98d 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -113,7 +113,10 @@ class PosixLibrary : BaseLibrary { bool Unload() override { if (_library) { - return (dlclose(_library) == 0); + void *lib = _library; + _library = nullptr; + + return (dlclose(lib) == 0); } else { return true; } diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index 405cecee6be6..a96494902730 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -37,7 +37,8 @@ void *dlopen(const char *filename) { } int dlclose(void *lib) { - delete lib; + DLL *dll = static_cast(lib); + delete dll; return 0; } From 107d3f95d29a9b1dac1bff26c35a579cf316220a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jan 2021 18:59:26 -0800 Subject: [PATCH 109/215] AGS: Disable save_config_file --- engines/ags/engine/main/config.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 52a6dee9c48d..7f5d52e193dc 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -568,6 +568,8 @@ void post_config() { } void save_config_file() { +// Change to use ScummVM configuration +#ifdef TODO ConfigTree cfg; // Last display mode @@ -602,6 +604,7 @@ void save_config_file() { String cfg_file = find_user_cfg_file(); if (!cfg_file.IsEmpty()) IniUtil::Merge(cfg_file, cfg); +#endif } } // namespace AGS3 From 1071c77253a48092bed4f4374da470138a54ca28 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jan 2021 19:00:57 -0800 Subject: [PATCH 110/215] AGS: Allow graceful exit after call to quit --- engines/ags/ags.cpp | 7 +++++-- engines/ags/engine/main/engine.cpp | 1 - engines/ags/engine/main/quit.cpp | 20 ++++++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index a7289c88be60..f52f74ef7607 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -130,6 +130,7 @@ Version SavedgameLowestBackwardCompatVersion; // Lowest engine version, which would accept current savedgames Version SavedgameLowestForwardCompatVersion; +extern void quit_free(); void main_pre_init() { our_eip = -999; @@ -390,8 +391,10 @@ Common::Error AGSEngine::run() { #endif { int result = AGS3::initialize_engine(startup_opts); - // TODO: refactor engine shutdown routine (must shutdown and delete everything started and created) - AGS3::platform->PostAllegroExit(); + + // Do shutdown stuff + ::AGS3::quit_free(); + return result ? Common::kUnknownError : Common::kNoError; } #ifdef USE_CUSTOM_EXCEPTION_HANDLER diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 626e7ce4dc95..3aff7ea660a7 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -1464,7 +1464,6 @@ int initialize_engine(const ConfigTree &startup_opts) { initialize_start_and_play_game(override_start_room, loadSaveGameOnStartup); - quit("|bye!"); return EXIT_NORMAL; } diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 9158366712af..f8fa75c2159f 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -67,6 +67,7 @@ extern IAGSEditorDebugger *editor_debugger; extern int need_to_stop_cd; extern int use_cdplayer; extern IGraphicsDriver *gfxDriver; +extern volatile char abort_engine; bool handledErrorInEditor; @@ -221,6 +222,8 @@ void allegro_bitmap_test_release() { char return_to_roomedit[30] = "\0"; char return_to_room[150] = "\0"; +char quit_message[256] = "\0"; + // quit - exits the engine, shutting down everything gracefully // The parameter is the message to print. If this message begins with // an '!' character, then it is printed as a "contact game author" error. @@ -229,11 +232,17 @@ char return_to_room[150] = "\0"; // error. // "!|" is a special code used to mean that the player has aborted (Alt+X) void quit(const char *quitmsg) { + strncpy(quit_message, quitmsg, 256); + abort_engine = true; +} + +void quit_free() { String alertis; + if (strlen(quit_message) == 0) + strcpy(quit_message, "|bye!"); + + const char *quitmsg = quit_message; QuitReason qreason = quit_check_for_error_state(quitmsg, alertis); - // Need to copy it in case it's from a plugin (since we're - // about to free plugins) - String qmsg = quitmsg; if (qreason & kQuitKind_NormalExit) save_config_file(); @@ -242,7 +251,7 @@ void quit(const char *quitmsg) { handledErrorInEditor = false; - quit_tell_editor_debugger(qmsg, qreason); + quit_tell_editor_debugger(quit_message, qreason); our_eip = 9900; @@ -275,7 +284,7 @@ void quit(const char *quitmsg) { engine_shutdown_gfxmode(); - quit_message_on_exit(qmsg, alertis, qreason); + quit_message_on_exit(quitmsg, alertis, qreason); quit_release_data(); @@ -297,7 +306,6 @@ void quit(const char *quitmsg) { shutdown_debug(); our_eip = 9904; - error("%s", qmsg.GetNullableCStr()); } extern "C" { From c204d1340046321c3b6f0c9f3dbc54e9a7ffea23 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jan 2021 20:31:32 -0800 Subject: [PATCH 111/215] AGS: Set the transparent color on all created surfaces --- engines/ags/lib/allegro/gfx.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index 7d83d2b8edc3..e0428d0aa5aa 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -227,10 +227,16 @@ class Surface : public Graphics::ManagedSurface, public BITMAP { Surface(int width, int height) : Graphics::ManagedSurface(width, height), BITMAP(this) { } Surface(int width, int height, const Graphics::PixelFormat &pixelFormat) : - Graphics::ManagedSurface(width, height, pixelFormat), BITMAP(this) { + Graphics::ManagedSurface(width, height, pixelFormat), BITMAP(this) { + // Allegro uses 255, 0, 255 RGB as the transparent color + if (pixelFormat.bytesPerPixel == 4) + setTransparentColor(pixelFormat.RGBToColor(255, 0, 255)); } Surface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) : - Graphics::ManagedSurface(surf, bounds), BITMAP(this) { + Graphics::ManagedSurface(surf, bounds), BITMAP(this) { + // Allegro uses 255, 0, 255 RGB as the transparent color + if (surf.format.bytesPerPixel == 4) + setTransparentColor(surf.format.RGBToColor(255, 0, 255)); } ~Surface() override { } From c873761f8feef3e28355c9657ebef4f15921ed59 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jan 2021 20:40:14 -0800 Subject: [PATCH 112/215] AGS: Handle sprite transparency for cursors --- engines/ags/lib/allegro/gfx.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index e25484370eb2..43eaf29d788a 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -228,7 +228,10 @@ void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { add_palette_if_needed(spriteS, bmpS); - bmpS.blitFrom(spriteS, Common::Point(x, y)); + // For Allegro, paletted sprites always use index 0 as the transparent color, + // and for higher resolution formats uses bright pink RGB 255, 0, 255 + bmpS.transBlitFrom(spriteS, Common::Point(x, y), + (spriteS.format.bytesPerPixel == 1) ? 0 : spriteS.format.RGBToColor(255, 0, 255)); } void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h) { From ab7674868db0269f42dc4e221e6d271a5a052eab Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jan 2021 21:21:07 -0800 Subject: [PATCH 113/215] AGS: Implementing drawing code used by pathfinder --- engines/ags/lib/allegro/draw.cpp | 77 +++++++- engines/ags/lib/allegro/draw.h | 2 +- engines/ags/lib/allegro/flood.cpp | 227 +++++++++++++++++++++++ engines/ags/lib/allegro/flood.h | 37 ++++ engines/ags/lib/allegro/gfx.cpp | 48 ++++- engines/ags/lib/allegro/gfx.h | 28 ++- engines/ags/module.mk | 1 + engines/ags/shared/gfx/allegrobitmap.cpp | 2 +- 8 files changed, 410 insertions(+), 12 deletions(-) create mode 100644 engines/ags/lib/allegro/flood.cpp create mode 100644 engines/ags/lib/allegro/flood.h diff --git a/engines/ags/lib/allegro/draw.cpp b/engines/ags/lib/allegro/draw.cpp index e6b467557d4e..fba3b446a221 100644 --- a/engines/ags/lib/allegro/draw.cpp +++ b/engines/ags/lib/allegro/draw.cpp @@ -24,8 +24,81 @@ namespace AGS3 { -void do_line(BITMAP *bmp, int x1, int y_1, int x2, int y2, int d, DrawMethod proc) { - warning("TODO: do_line"); +void do_line(BITMAP *bmp, int x1, int y1, int x2, int y2, int d, DrawMethod proc) { + int dx = x2 - x1; + int dy = y2 - y1; + int i1, i2; + int x, y; + int dd; + + /* worker macro */ + #define DO_LINE(pri_sign, pri_c, pri_cond, sec_sign, sec_c, sec_cond) \ + { \ + if (d##pri_c == 0) { \ + proc(bmp, x1, y1, d); \ + return; \ + } \ + \ + i1 = 2 * d##sec_c; \ + dd = i1 - (sec_sign (pri_sign d##pri_c)); \ + i2 = dd - (sec_sign (pri_sign d##pri_c)); \ + \ + x = x1; \ + y = y1; \ + \ + while (pri_c pri_cond pri_c##2) { \ + proc(bmp, x, y, d); \ + \ + if (dd sec_cond 0) { \ + sec_c = sec_c sec_sign 1; \ + dd += i2; \ + } \ + else \ + dd += i1; \ + \ + pri_c = pri_c pri_sign 1; \ + } \ + } + + if (dx >= 0) { + if (dy >= 0) { + if (dx >= dy) { + /* (x1 <= x2) && (y1 <= y2) && (dx >= dy) */ + DO_LINE(+, x, <= , +, y, >= ); + } else { + /* (x1 <= x2) && (y1 <= y2) && (dx < dy) */ + DO_LINE(+, y, <= , +, x, >= ); + } + } else { + if (dx >= -dy) { + /* (x1 <= x2) && (y1 > y2) && (dx >= dy) */ + DO_LINE(+, x, <= , -, y, <= ); + } else { + /* (x1 <= x2) && (y1 > y2) && (dx < dy) */ + DO_LINE(-, y, >= , +, x, >= ); + } + } + } else { + if (dy >= 0) { + if (-dx >= dy) { + /* (x1 > x2) && (y1 <= y2) && (dx >= dy) */ + DO_LINE(-, x, >= , +, y, >= ); + } else { + /* (x1 > x2) && (y1 <= y2) && (dx < dy) */ + DO_LINE(+, y, <= , -, x, <= ); + } + } else { + if (-dx >= -dy) { + /* (x1 > x2) && (y1 > y2) && (dx >= dy) */ + DO_LINE(-, x, >= , -, y, <= ); + } else { + /* (x1 > x2) && (y1 > y2) && (dx < dy) */ + DO_LINE(-, y, >= , -, x, <= ); + } + } + } + +#undef DO_LINE } } // namespace AGS3 diff --git a/engines/ags/lib/allegro/draw.h b/engines/ags/lib/allegro/draw.h index 3e16ff8f2e59..5c3497a0744a 100644 --- a/engines/ags/lib/allegro/draw.h +++ b/engines/ags/lib/allegro/draw.h @@ -30,7 +30,7 @@ namespace AGS3 { typedef void (*DrawMethod)(BITMAP *, int, int, int); -AL_FUNC(void, do_line, (BITMAP *bmp, int x1, int y_1, int x2, int y2, int d, DrawMethod proc)); +extern void do_line(BITMAP *bmp, int x1, int y1, int x2, int y2, int d, DrawMethod proc); } // namespace AGS3 diff --git a/engines/ags/lib/allegro/flood.cpp b/engines/ags/lib/allegro/flood.cpp new file mode 100644 index 000000000000..e5794ce29cee --- /dev/null +++ b/engines/ags/lib/allegro/flood.cpp @@ -0,0 +1,227 @@ +/* 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 "ags/lib/allegro/flood.h" +#include "ags/lib/allegro/gfx.h" +#include "common/array.h" + +namespace AGS3 { + +struct FLOODED_LINE { + short flags; /* status of the segment */ + short lpos, rpos; /* left and right ends of segment */ + short y; /* y coordinate of the segment */ + int next; /* linked list if several per line */ +}; + +#define FLOOD_IN_USE 1 +#define FLOOD_TODO_ABOVE 2 +#define FLOOD_TODO_BELOW 4 + +#define FLOOD_LINE(c) (&scratchMem[c]) + +template +static bool scanLine(BITMAP *bmp, int x, int y, int src_color, int &left, int &right) { + // check start pixel + const SIZE *pixel = (const SIZE *)bmp->getBasePtr(x, y); + if (*pixel != src_color) + return false; + + // Work left from starting point + const SIZE *pixelLeft = pixel - 1; + for (left = x - 1; left >= bmp->cl; left--, pixelLeft--) { + if (*pixelLeft != src_color) + break; + } + + // Work right from starting point + const SIZE *pixelRight = pixel + 1; + for (right = x + 1; right < bmp->cr; right++, pixelRight++) { + if (*pixelRight != src_color) + break; + } + + return true; +} + +/** + * Fills a horizontal line around the specified position, and adds it + * to the list of drawn segments. Returns the first x coordinate after + * the part of the line which it has dealt with. + */ +static int flooder(BITMAP *bmp, int x, int y, int src_color, int dest_color, + Common::Array &scratchMem) { + FLOODED_LINE *p; + int left = 0, right = 0; + int c; + + assert(bmp); + + bool ret; + switch (bmp->format.bytesPerPixel) { + case 1: ret = scanLine(bmp, x, y, src_color, left, right); break; + case 2: ret = scanLine(bmp, x, y, src_color, left, right); break; + case 4: ret = scanLine(bmp, x, y, src_color, left, right); break; + default: + error("Unknown format"); + } + if (!ret) + return x + 1; + + left++; + right--; + + /* draw the line */ + bmp->hLine(left, y, right, dest_color); + + /* store it in the list of flooded segments */ + c = y; + p = FLOOD_LINE(c); + + if (p->flags) { + while (p->next) { + c = p->next; + p = FLOOD_LINE(c); + } + + p->next = c = scratchMem.size(); + scratchMem.resize(scratchMem.size() + 1); + p = FLOOD_LINE(c); + } + + p->flags = FLOOD_IN_USE; + p->lpos = left; + p->rpos = right; + p->y = y; + p->next = 0; + + if (y > bmp->ct) + p->flags |= FLOOD_TODO_ABOVE; + + if (y + 1 < bmp->cb) + p->flags |= FLOOD_TODO_BELOW; + + return right + 2; +} + + + +/** + * Checks a line segment, using the scratch buffer is to store a list of + * segments which have already been drawn in order to minimise the required + * number of tests. + */ +static bool check_flood_line(BITMAP *bmp, int y, int left, int right, int src_color, int dest_color, + Common::Array &scratchMem) { + int c; + FLOODED_LINE *p; + bool ret = false; + + while (left <= right) { + c = y; + + for (;;) { + p = FLOOD_LINE(c); + + if ((left >= p->lpos) && (left <= p->rpos)) { + left = p->rpos + 2; + break; + } + + c = p->next; + + if (!c) { + left = flooder(bmp, left, y, src_color, dest_color, scratchMem); + ret = true; + break; + } + } + } + + return ret; +} + +void floodfill(BITMAP *bmp, int x, int y, int color) { + int src_color; + int c; + bool done; + FLOODED_LINE *p; + Common::Array scratchMem; + + /* make sure we have a valid starting point */ + if ((x < bmp->cl) || (x >= bmp->cr) || (y < bmp->ct) || (y >= bmp->cb)) + return; + + /* what color to replace? */ + src_color = getpixel(bmp, x, y); + if (src_color == color) { + return; + } + + /* set up the list of flooded segments */ + scratchMem.resize(bmp->cb); + + p = FLOOD_LINE(0); + for (c = 0; c < (int)scratchMem.size(); c++) { + p[c].flags = 0; + p[c].lpos = SHRT_MAX; + p[c].rpos = SHRT_MIN; + p[c].y = y; + p[c].next = 0; + } + + /* start up the flood algorithm */ + flooder(bmp, x, y, src_color, color, scratchMem); + + /* continue as long as there are some segments still to test */ + do { + done = true; + + /* for each line on the screen */ + for (c = 0; c < (int)scratchMem.size(); c++) { + p = FLOOD_LINE(c); + + /* check below the segment? */ + if (p->flags & FLOOD_TODO_BELOW) { + p->flags &= ~FLOOD_TODO_BELOW; + if (check_flood_line(bmp, p->y + 1, p->lpos, p->rpos, src_color, color, scratchMem)) { + done = false; + p = FLOOD_LINE(c); + } + } + + /* check above the segment? */ + if (p->flags & FLOOD_TODO_ABOVE) { + p->flags &= ~FLOOD_TODO_ABOVE; + if (check_flood_line(bmp, p->y - 1, p->lpos, p->rpos, src_color, color, scratchMem)) { + done = false; + /* special case shortcut for going backwards */ + if ((c < bmp->cb) && (c > 0)) + c -= 2; + } + } + } + + } while (!done); +} + +} // namespace AGS3 diff --git a/engines/ags/lib/allegro/flood.h b/engines/ags/lib/allegro/flood.h new file mode 100644 index 000000000000..0aa087483167 --- /dev/null +++ b/engines/ags/lib/allegro/flood.h @@ -0,0 +1,37 @@ +/* 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 AGS_LIB_ALLEGRO_FLOOD_H +#define AGS_LIB_ALLEGRO_FLOOD_H + +#include "graphics/managed_surface.h" +#include "ags/lib/allegro/base.h" + +namespace AGS3 { + +class BITMAP; + +extern void floodfill(BITMAP *bmp, int x, int y, int color); + +} // namespace AGS3 + +#endif diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 43eaf29d788a..a98541c2bfb6 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -21,6 +21,7 @@ */ #include "ags/lib/allegro/gfx.h" +#include "ags/lib/allegro/flood.h" #include "ags/ags.h" #include "common/textconsole.h" #include "graphics/screen.h" @@ -52,6 +53,46 @@ int BITMAP::getpixel(int x, int y) const { return *(const uint32 *)pixel; } +void BITMAP::circlefill(int x, int y, int radius, int color) { + int cx = 0; + int cy = radius; + int df = 1 - radius; + int d_e = 3; + int d_se = -2 * radius + 5; + + do { + _owner->hLine(x - cy, y - cx, x + cy, color); + + if (cx) + _owner->hLine(x - cy, y + cx, x + cy, color); + + if (df < 0) { + df += d_e; + d_e += 2; + d_se += 2; + } else { + if (cx != cy) { + _owner->hLine(x - cx, y - cy, x + cx, color); + + if (cy) + _owner->hLine(x - cx, y + cy, x + cx, color); + } + + df += d_se; + d_e += 2; + d_se += 4; + cy--; + } + + cx++; + + } while (cx <= cy); +} + +void BITMAP::floodfill(int x, int y, int color) { + AGS3::floodfill(this, x, y, color); +} + /*-------------------------------------------------------------------*/ /** @@ -423,17 +464,12 @@ void triangle(BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3, int c surf.drawLine(x3, y3, x1, y1, color); } -void floodfill(BITMAP *bmp, int x, int y, int color) { - error("TODO: floodfill"); -} - void circlefill(BITMAP *bmp, int x, int y, int radius, int color) { - error("TODO: circlefill"); + bmp->circlefill(x, y, radius, color); } void clear_bitmap(BITMAP *bmp) { bmp->clear(); } - } // namespace AGS3 diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index e0428d0aa5aa..2af30ede9f49 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -184,7 +184,8 @@ class BITMAP { Common::Array line; public: BITMAP(Graphics::ManagedSurface *owner); - virtual ~BITMAP() {} + virtual ~BITMAP() { + } Graphics::ManagedSurface &operator*() const { return *_owner; @@ -213,6 +214,30 @@ class BITMAP { void clear() { _owner->clear(); } + + /** + * Draws a solid filled in circle + */ + void circlefill(int x, int y, int radius, int color); + + /** + * Fills an enclosed area starting at a given point + */ + void floodfill(int x, int y, int color); + + /** + * Draw a horizontal line + */ + void hLine(int x, int y, int x2, uint32 color) { + _owner->hLine(x, y, x2, color); + } + + /** + * Draw a vertical line. + */ + void vLine(int x, int y, int y2, uint32 color) { + _owner->vLine(x, y, y2, color); + } }; /** @@ -305,7 +330,6 @@ extern void line(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color); extern void rect(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color); extern void rectfill(BITMAP *bmp, int x1, int y_1, int x2, int y2, int color); extern void triangle(BITMAP *bmp, int x1, int y_1, int x2, int y2, int x3, int y3, int color); -extern void floodfill(BITMAP *bmp, int x, int y, int color); extern void circlefill(BITMAP *bmp, int x, int y, int radius, int color); } // namespace AGS3 diff --git a/engines/ags/module.mk b/engines/ags/module.mk index eeda8d7f1556..e19feb3a3cba 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -17,6 +17,7 @@ MODULE_OBJS = \ lib/allegro/error.o \ lib/allegro/file.o \ lib/allegro/fixed.o \ + lib/allegro/flood.o \ lib/allegro/gfx.o \ lib/allegro/graphics.o \ lib/allegro/keyboard.o \ diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index 9071308340fc..f627868d7eb9 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -366,7 +366,7 @@ void Bitmap::FillTransparent() { } void Bitmap::FloodFill(int x, int y, color_t color) { - floodfill(_alBitmap, x, y, color); + _alBitmap->floodfill(x, y, color); } //============================================================================= From 1aa01a471074e00a011bb2bf0b2464a55e2222b7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jan 2021 22:26:29 -0800 Subject: [PATCH 114/215] AGS: Fix closing ScummVM window on title screen --- engines/ags/engine/main/game_run.cpp | 3 ++- engines/ags/engine/script/cc_instance.cpp | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 1e82cc471420..c331315f414c 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -946,7 +946,8 @@ static void GameLoopUntilEvent(int untilwhat, const void *daaa) { auto cached_user_disabled_for = user_disabled_for; SetupLoopParameters(untilwhat, daaa); - while (GameTick() == 0); + while (GameTick() == 0 && !abort_engine) { + } our_eip = 78; diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index 4bc07dde5249..5a4fd59f3165 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -58,6 +58,7 @@ extern int maxWhileLoops; extern new_line_hook_type new_line_hook; extern ScriptString myScriptStringImpl; +extern volatile char abort_engine; enum ScriptOpArgIsReg { kScOpNoArgIsReg = 0, @@ -434,6 +435,8 @@ int ccInstance::Run(int32_t curpc) { FunctionCallStack func_callstack; while (1) { + if (abort_engine) + return -1; /* if (!codeInst->ReadOperation(codeOp, pc)) From d891e634285324542bf4fcb414dc98a54019864f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 Jan 2021 06:35:16 -0800 Subject: [PATCH 115/215] AGS: Fix cursor palette intensity --- engines/ags/lib/allegro/color.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 9bbe56d2ec82..f66c1d19d739 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -30,6 +30,8 @@ namespace AGS3 { +#define VGA_COLOR_TRANS(x) ((x) * 255 / 63) + int _rgb_r_shift_15 = 0; int _rgb_g_shift_15 = 0; int _rgb_b_shift_15 = 0; @@ -66,9 +68,9 @@ void set_palette_range(const PALETTE p, int from, int to, int retracesync) { void palette_to_rgb8(const PALETTE src, byte dest[PALETTE_SIZE]) { byte *pDest = dest; for (int i = 0; i < 256; ++i, pDest += 3) { - pDest[0] = src[i].r; - pDest[1] = src[i].g; - pDest[2] = src[i].b; + pDest[0] = VGA_COLOR_TRANS(src[i].r); + pDest[1] = VGA_COLOR_TRANS(src[i].g); + pDest[2] = VGA_COLOR_TRANS(src[i].b); } } From 9747bd4df964f4ed6eb5e690ffb70fffc7534395 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 Jan 2021 18:35:12 -0800 Subject: [PATCH 116/215] AGS: Added engine methods for load/save game --- engines/ags/ags.cpp | 15 +++++++++++++++ engines/ags/ags.h | 10 ++++++++++ engines/ags/engine/ac/game.cpp | 6 ++++-- engines/ags/engine/main/engine.cpp | 4 ++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index f52f74ef7607..374d67cf6ba3 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -36,12 +36,14 @@ #include "ags/lib/std/set.h" #include "ags/shared/ac/common.h" +#include "ags/engine/ac/game.h" #include "ags/engine/ac/gamesetup.h" #include "ags/engine/ac/gamestate.h" #include "ags/shared/core/def_version.h" #include "ags/engine/debugging/debugger.h" #include "ags/engine/debugging/debug_log.h" #include "ags/shared/debugging/out.h" +#include "ags/engine/game/savegame.h" #include "ags/engine/main/config.h" #include "ags/engine/main/engine.h" #include "ags/engine/main/mainheader.h" @@ -64,6 +66,8 @@ extern char return_to_room[150]; using namespace Shared; using namespace Engine; +extern HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten); + String appDirectory; // Needed for library loading String cmdGameDataPath; @@ -418,4 +422,15 @@ void AGSEngine::setGraphicsMode(size_t w, size_t h) { _screen = new ::AGS3::BITMAP(_rawScreen); } +Common::Error AGSEngine::loadGameState(int slot) { + bool dataOverwritten; + (void)AGS3::load_game("", slot, dataOverwritten); + return Common::kNoError; +} + +Common::Error AGSEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) { + (void)AGS3::save_game(slot, desc.c_str()); + return Common::kNoError; +} + } // namespace AGS diff --git a/engines/ags/ags.h b/engines/ags/ags.h index f8d0f7e4552f..982bf66d54ce 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -101,6 +101,16 @@ class AGSEngine : public Engine { * Setse up the graphics mode */ void setGraphicsMode(size_t w, size_t h); + + /** + * Load a savegame + */ + Common::Error loadGameState(int slot) override; + + /** + * Save a savegame + */ + Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override; }; extern AGSEngine *g_vm; diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 561a0d0c8f58..ec1f05252093 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -209,7 +209,6 @@ String saveGameDirectory = "./"; // Custom save game parent directory String saveGameParent; -const char *sgnametemplate = "agssave.%03d"; String saveGameSuffix; int game_paused = 0; @@ -361,12 +360,16 @@ void set_save_game_suffix(const String &suffix) { } String get_save_game_path(int slotNum) { +#if AGS_PLATFORM_SCUMMVM + return ::AGS::g_vm->getSaveStateName(slotNum); +#else String filename; filename.Format(sgnametemplate, slotNum); String path = saveGameDirectory; path.Append(filename); path.Append(saveGameSuffix); return path; +#endif } // Convert a path possibly containing path tags into acceptable save path @@ -1041,7 +1044,6 @@ void create_savegame_screenshot(Bitmap *&screenShot) { } void save_game(int slotn, const char *descript) { - // dont allow save in rep_exec_always, because we dont save // the state of blocked scripts can_run_delayed_command(); diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 3aff7ea660a7..7d128c19a12d 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -666,6 +666,9 @@ extern char android_base_directory[256]; #endif // AGS_PLATFORM_OS_ANDROID int check_write_access() { +#if AGS_PLATFORM_SCUMMVM + return true; +#else if (platform->GetDiskFreeSpaceMB() < 2) return 0; @@ -701,6 +704,7 @@ int check_write_access() { return 0; return 1; +#endif } int engine_check_disk_space() { From 33040caca5801b03ac598a75f9f1dfa56153d32f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 Jan 2021 19:47:51 -0800 Subject: [PATCH 117/215] AGS: Adding saveilfe support to FileStream --- engines/ags/engine/ac/game.cpp | 4 +++ engines/ags/shared/util/filestream.cpp | 41 ++++++++++++++++++-------- engines/ags/shared/util/filestream.h | 6 ++-- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index ec1f05252093..1332850a67fd 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -425,6 +425,9 @@ bool SetCustomSaveParent(const String &path) { } bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path) { +#if AGS_PLATFORM_SCUMMVM + return false; +#else if (!newFolder || newFolder[0] == 0) newFolder = "."; String newSaveGameDir; @@ -465,6 +468,7 @@ bool SetSaveGameDirectoryPath(const char *newFolder, bool explicit_path) { saveGameDirectory = newSaveGameDir; return true; +#endif } int Game_SetSaveGameDirectory(const char *newFolder) { diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index b512fc45058e..44988fd5fc47 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -23,7 +23,9 @@ #include "ags/shared/util/filestream.h" #include "ags/shared/util/stdio_compat.h" #include "ags/shared/util/string.h" +#include "ags/ags.h" #include "common/file.h" +#include "common/system.h" namespace AGS3 { namespace AGS { @@ -31,10 +33,8 @@ namespace Shared { FileStream::FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) - : DataStream(stream_endianess) - , _file(nullptr) - , _openMode(open_mode) - , _workMode(work_mode) { + : DataStream(stream_endianess), _writeBuffer(DisposeAfterUse::YES), + _openMode(open_mode), _workMode(work_mode), _file(nullptr), _outSave(nullptr) { Open(file_name, open_mode, work_mode); } @@ -47,9 +47,15 @@ bool FileStream::HasErrors() const { } void FileStream::Close() { - if (_file) { + if (_outSave) { + _outSave->write(_writeBuffer.getData(), _writeBuffer.size()); + _outSave->finalize(); + delete _outSave; + + } else if (_file) { delete _file; } + _file = nullptr; } @@ -168,21 +174,30 @@ bool FileStream::Seek(soff_t offset, StreamSeek origin) { void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode) { if (open_mode == kFile_Open) { + // First try to open file in game folder Common::File *f = new Common::File(); - if (!f->open(getFSNode(file_name.GetNullableCStr()))) { + if (!file_name.CompareLeftNoCase("agssave.") || !f->open(getFSNode(file_name.GetNullableCStr()))) { delete f; - _file = nullptr; + + // Fall back on any save file with the given name + String saveName = file_name; + if (!file_name.CompareLeftNoCase("agssave.")) { + int saveSlot = atoi(file_name.GetNullableCStr() + 8); + saveName = ::AGS::g_vm->getSaveStateName(saveSlot); + } + + _file = g_system->getSavefileManager()->openForLoading(saveName); } else { _file = f; } } else { - Common::DumpFile *f = new Common::DumpFile(); - if (!f->open(file_name.GetNullableCStr())) { - delete f; - _file = nullptr; - } else { - _file = f; + // All newly created files are created as save files + _outSave = g_system->getSavefileManager()->openForSaving(file_name, false); + if (_outSave) { + // Any data written has to first go through the memory stream buffer, + // since the savegame code uses Seeks, which OutSaveFile doesn't support + _file = &_writeBuffer; } } } diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index 69d56f6f9adf..ff9994c11108 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -23,11 +23,11 @@ #ifndef AGS_SHARED_UTIL_FILESTREAM_H #define AGS_SHARED_UTIL_FILESTREAM_H -//include - #include "ags/shared/util/datastream.h" #include "ags/shared/util/file.h" // TODO: extract filestream mode constants #include "common/stream.h" +#include "common/memstream.h" +#include "common/savefile.h" namespace AGS3 { namespace AGS { @@ -73,6 +73,8 @@ class FileStream : public DataStream { Common::Stream *_file; const FileOpenMode _openMode; const FileWorkMode _workMode; + Common::MemoryWriteStreamDynamic _writeBuffer; + Common::OutSaveFile *_outSave; }; } // namespace Shared From 55abddfa7c92f21a72376f216d4d203555323d41 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 Jan 2021 21:39:45 -0800 Subject: [PATCH 118/215] AGS: Fixing keys - upper/lowercase, function keys, etc --- engines/ags/engine/ac/sys_events.cpp | 239 +++++++++++---------------- engines/ags/events.cpp | 19 ++- engines/ags/events.h | 6 +- engines/ags/lib/allegro/keyboard.cpp | 2 +- engines/ags/lib/allegro/keyboard.h | 2 +- 5 files changed, 114 insertions(+), 154 deletions(-) diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index 53bf7375f5df..16acd3c0e818 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -56,7 +56,7 @@ int ags_kbhit() { } int ags_iskeypressed(int keycode) { - if (keycode >= 0 && keycode < __allegro_KEY_MAX) { + if (keycode >= 0 && keycode < Common::KEYCODE_LAST) { return key[keycode] != 0; } return 0; @@ -99,153 +99,100 @@ int ags_check_mouse_wheel() { } int ags_getch() { - const int read_key_value = readkey(); - int gott = read_key_value; - const int scancode = ((gott >> 8) & 0x00ff); - const int ascii = (gott & 0x00ff); - - bool is_extended = (ascii == EXTENDED_KEY_CODE); - // On macos, the extended keycode is the ascii character '?' or '\0' if alt-key - // so check it's not actually the character '?' -#if AGS_PLATFORM_OS_MACOS && ! AGS_PLATFORM_OS_IOS - is_extended = is_extended || ((ascii == EXTENDED_KEY_CODE_MACOS) && (scancode != __allegro_KEY_SLASH)); -#endif - - /* char message[200]; - sprintf(message, "Scancode: %04X", gott); - Debug::Printf(message);*/ - - /*if ((scancode >= KEY_0_PAD) && (scancode <= KEY_9_PAD)) { - // fix numeric pad keys if numlock is off (allegro 4.2 changed this behaviour) - if ((key_shifts & KB_NUMLOCK_FLAG) == 0) - gott = (gott & 0xff00) | EXTENDED_KEY_CODE; - }*/ - - if (gott == READKEY_CODE_ALT_TAB) { - // Alt+Tab, it gets stuck down unless we do this - gott = AGS_KEYCODE_ALT_TAB; - } -#if AGS_PLATFORM_OS_MACOS - else if (scancode == __allegro_KEY_BACKSPACE) { - gott = eAGSKeyCodeBackspace; - } -#endif - else if (is_extended) { - - // I believe we rely on a lot of keys being converted to ASCII, which is why - // the complete scan code list is not here. - - switch (scancode) { - case __allegro_KEY_F1: - gott = eAGSKeyCodeF1; - break; - case __allegro_KEY_F2: - gott = eAGSKeyCodeF2; - break; - case __allegro_KEY_F3: - gott = eAGSKeyCodeF3; - break; - case __allegro_KEY_F4: - gott = eAGSKeyCodeF4; - break; - case __allegro_KEY_F5: - gott = eAGSKeyCodeF5; - break; - case __allegro_KEY_F6: - gott = eAGSKeyCodeF6; - break; - case __allegro_KEY_F7: - gott = eAGSKeyCodeF7; - break; - case __allegro_KEY_F8: - gott = eAGSKeyCodeF8; - break; - case __allegro_KEY_F9: - gott = eAGSKeyCodeF9; - break; - case __allegro_KEY_F10: - gott = eAGSKeyCodeF10; - break; - case __allegro_KEY_F11: - gott = eAGSKeyCodeF11; - break; - case __allegro_KEY_F12: - gott = eAGSKeyCodeF12; - break; - - case __allegro_KEY_INSERT: - gott = eAGSKeyCodeInsert; - break; - case __allegro_KEY_DEL: - gott = eAGSKeyCodeDelete; - break; - case __allegro_KEY_HOME: - gott = eAGSKeyCodeHome; - break; - case __allegro_KEY_END: - gott = eAGSKeyCodeEnd; - break; - case __allegro_KEY_PGUP: - gott = eAGSKeyCodePageUp; - break; - case __allegro_KEY_PGDN: - gott = eAGSKeyCodePageDown; - break; - case __allegro_KEY_LEFT: - gott = eAGSKeyCodeLeftArrow; - break; - case __allegro_KEY_RIGHT: - gott = eAGSKeyCodeRightArrow; - break; - case __allegro_KEY_UP: - gott = eAGSKeyCodeUpArrow; - break; - case __allegro_KEY_DOWN: - gott = eAGSKeyCodeDownArrow; - break; - - case __allegro_KEY_0_PAD: - gott = eAGSKeyCodeInsert; - break; - case __allegro_KEY_1_PAD: - gott = eAGSKeyCodeEnd; - break; - case __allegro_KEY_2_PAD: - gott = eAGSKeyCodeDownArrow; - break; - case __allegro_KEY_3_PAD: - gott = eAGSKeyCodePageDown; - break; - case __allegro_KEY_4_PAD: - gott = eAGSKeyCodeLeftArrow; - break; - case __allegro_KEY_5_PAD: - gott = eAGSKeyCodeNumPad5; - break; - case __allegro_KEY_6_PAD: - gott = eAGSKeyCodeRightArrow; - break; - case __allegro_KEY_7_PAD: - gott = eAGSKeyCodeHome; - break; - case __allegro_KEY_8_PAD: - gott = eAGSKeyCodeUpArrow; - break; - case __allegro_KEY_9_PAD: - gott = eAGSKeyCodePageUp; - break; - case __allegro_KEY_DEL_PAD: - gott = eAGSKeyCodeDelete; - break; - - default: + const Common::KeyState keyState = readkey(); + int gott; + + // I believe we rely on a lot of keys being converted to ASCII, which is why + // the complete scan code list is not here. + + switch (keyState.keycode) { + case Common::KEYCODE_F1: + gott = eAGSKeyCodeF1; + break; + case Common::KEYCODE_F2: + gott = eAGSKeyCodeF2; + break; + case Common::KEYCODE_F3: + gott = eAGSKeyCodeF3; + break; + case Common::KEYCODE_F4: + gott = eAGSKeyCodeF4; + break; + case Common::KEYCODE_F5: + gott = eAGSKeyCodeF5; + break; + case Common::KEYCODE_F6: + gott = eAGSKeyCodeF6; + break; + case Common::KEYCODE_F7: + gott = eAGSKeyCodeF7; + break; + case Common::KEYCODE_F8: + gott = eAGSKeyCodeF8; + break; + case Common::KEYCODE_F9: + gott = eAGSKeyCodeF9; + break; + case Common::KEYCODE_F10: + gott = eAGSKeyCodeF10; + break; + case Common::KEYCODE_F11: + gott = eAGSKeyCodeF11; + break; + case Common::KEYCODE_F12: + gott = eAGSKeyCodeF12; + break; + + case Common::KEYCODE_INSERT: + case Common::KEYCODE_KP0: + gott = eAGSKeyCodeInsert; + break; + case Common::KEYCODE_DELETE: + case Common::KEYCODE_KP_PERIOD: + gott = eAGSKeyCodeDelete; + break; + case Common::KEYCODE_HOME: + case Common::KEYCODE_KP7: + gott = eAGSKeyCodeHome; + break; + case Common::KEYCODE_END: + case Common::KEYCODE_KP1: + gott = eAGSKeyCodeEnd; + break; + case Common::KEYCODE_PAGEUP: + case Common::KEYCODE_KP9: + gott = eAGSKeyCodePageUp; + break; + case Common::KEYCODE_PAGEDOWN: + case Common::KEYCODE_KP3: + gott = eAGSKeyCodePageDown; + break; + case Common::KEYCODE_LEFT: + case Common::KEYCODE_KP4: + gott = eAGSKeyCodeLeftArrow; + break; + case Common::KEYCODE_RIGHT: + case Common::KEYCODE_KP6: + gott = eAGSKeyCodeRightArrow; + break; + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: + gott = eAGSKeyCodeUpArrow; + break; + case Common::KEYCODE_DOWN: + case Common::KEYCODE_KP2: + gott = eAGSKeyCodeDownArrow; + break; + + default: + if (keyState.flags & (Common::KBD_ALT | Common::KBD_CTRL) && + keyState.keycode >= Common::KEYCODE_a && keyState.keycode <= Common::KEYCODE_z) // no meaningful mappings // this is how we accidentally got the alt-key mappings - gott = scancode + AGS_EXT_KEY_SHIFT; - } - } else { - // this includes ascii characters and ctrl-A-Z - gott = ascii; + gott = AGS_EXT_KEY_SHIFT + (keyState.keycode - Common::KEYCODE_a) + 1; + else + gott = keyState.ascii; + break; } // Alt+X, abort (but only once game is loaded) diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp index c96279ad888c..983dcee60f13 100644 --- a/engines/ags/events.cpp +++ b/engines/ags/events.cpp @@ -50,8 +50,10 @@ void EventsManager::pollEvents() { ::AGS3::check_dynamic_sprites_at_exit = 0; } else if (e.type == Common::EVENT_KEYDOWN) { - // Add keypresses to the pending key list - _pendingKeys.push(e.kbd.keycode); + if (!isModifierKey(e.kbd.keycode)) { + // Add keypresses to the pending key list + _pendingKeys.push(e.kbd); + } } else { // Add other event types to the pending events queue. If the event is a // mouse move and the prior one was also, then discard the prior one. @@ -65,14 +67,23 @@ void EventsManager::pollEvents() { } } +bool EventsManager::isModifierKey(const Common::KeyCode &keycode) const { + return keycode == Common::KEYCODE_LCTRL || keycode == Common::KEYCODE_LALT + || keycode == Common::KEYCODE_RCTRL || keycode == Common::KEYCODE_RALT + || keycode == Common::KEYCODE_LSHIFT || keycode == Common::KEYCODE_RSHIFT + || keycode == Common::KEYCODE_LSUPER || keycode == Common::KEYCODE_RSUPER + || keycode == Common::KEYCODE_CAPSLOCK || keycode == Common::KEYCODE_NUMLOCK + || keycode == Common::KEYCODE_SCROLLOCK; +} + bool EventsManager::keypressed() { pollEvents(); return !_pendingKeys.empty(); } -int EventsManager::readKey() { +Common::KeyState EventsManager::readKey() { pollEvents(); - return _pendingKeys.empty() ? 0 : _pendingKeys.pop(); + return _pendingKeys.empty() ? Common::KeyState() : _pendingKeys.pop(); } Common::Event EventsManager::readEvent() { diff --git a/engines/ags/events.h b/engines/ags/events.h index 71126eee9a54..5842bd9548d2 100644 --- a/engines/ags/events.h +++ b/engines/ags/events.h @@ -31,7 +31,9 @@ namespace AGS { class EventsManager { private: Common::Queue _pendingEvents; - Common::Queue _pendingKeys; + Common::Queue _pendingKeys; + + bool isModifierKey(const Common::KeyCode &keycode) const; public: EventsManager(); ~EventsManager(); @@ -49,7 +51,7 @@ class EventsManager { /** * Returns the next keypress, if any is pending */ - int readKey(); + Common::KeyState readKey(); /** * Returns the next event, if any diff --git a/engines/ags/lib/allegro/keyboard.cpp b/engines/ags/lib/allegro/keyboard.cpp index 869ca1655a9e..7629e364e7a4 100644 --- a/engines/ags/lib/allegro/keyboard.cpp +++ b/engines/ags/lib/allegro/keyboard.cpp @@ -72,7 +72,7 @@ bool keypressed() { return ::AGS::g_events->keypressed(); } -int readkey() { +Common::KeyState readkey() { return ::AGS::g_events->readKey(); } diff --git a/engines/ags/lib/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h index 01a85e338b18..5f5b4ccc1f84 100644 --- a/engines/ags/lib/allegro/keyboard.h +++ b/engines/ags/lib/allegro/keyboard.h @@ -183,7 +183,7 @@ AL_FUNC(void, simulate_keypress, (int keycode)); AL_FUNC(void, simulate_ukeypress, (int keycode, int scancode)); AL_FUNC(bool, keypressed, (void)); -AL_FUNC(int, readkey, (void)); +AL_FUNC(Common::KeyState, readkey, (void)); } // namespace AGS3 From 096fdc29fa1d90fa4f62156a0411057fa26d97da Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 13 Jan 2021 23:06:37 -0800 Subject: [PATCH 119/215] AGS: Simplifying passing of script method params to DLL class The original had issues with the types of the method params being 32 bits for ints, but 32 or 64 bits for string pointers. This could easily result in a mismatch of passed params to method definitions. To avoid this, I now pass the parameters as a Common::Array, and a set of macros to simplify getting the parameter values within the script method --- engines/ags/engine/plugin/agsplugin.h | 4 + engines/ags/engine/script/script_runtime.cpp | 125 +++--------------- engines/ags/plugins/agscreditz/agscreditz.cpp | 63 +++++---- engines/ags/plugins/agscreditz/agscreditz.h | 43 +++--- engines/ags/plugins/dll.h | 49 ++++++- 5 files changed, 133 insertions(+), 151 deletions(-) diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/engine/plugin/agsplugin.h index f38aca8c99cc..3f564c214cf6 100644 --- a/engines/ags/engine/plugin/agsplugin.h +++ b/engines/ags/engine/plugin/agsplugin.h @@ -31,8 +31,12 @@ #ifndef AGS_ENGINE_PLUGIN_AGSPLUGIN_H #define AGS_ENGINE_PLUGIN_AGSPLUGIN_H +#include "common/array.h" + namespace AGS3 { +typedef Common::Array ScriptMethodParams; + // If the plugin isn't using DDraw, don't require the headers #ifndef DIRECTDRAW_VERSION typedef void *LPDIRECTDRAW2; diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp index f460eb5807c6..2c4a1e756907 100644 --- a/engines/ags/engine/script/script_runtime.cpp +++ b/engines/ags/engine/script/script_runtime.cpp @@ -34,15 +34,13 @@ // //============================================================================= -//include -//include -//include #include "ags/engine/script/script_runtime.h" #include "ags/shared/script/script_common.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/script/cc_options.h" -#include "ags/engine/ac/dynobj/cc_dynamicarray.h" #include "ags/engine/script/systemimports.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/engine/ac/dynobj/cc_dynamicarray.h" #include "ags/engine/ac/statobj/staticobject.h" namespace AGS3 { @@ -172,109 +170,26 @@ int call_function(intptr_t addr, const RuntimeScriptValue *object, int numparm, } } - // - // AN IMPORTANT NOTE ON PARAM TYPE - // of 2012-11-10 - // - //// NOTE of 2012-12-20: - //// Everything said below is applicable only for calling - //// exported plugin functions. - // - // Here we are sending parameters of type intptr_t to registered - // function of unknown kind. Intptr_t is 32-bit for x32 build and - // 64-bit for x64 build. - // The exported functions usually have two types of parameters: - // pointer and 'int' (32-bit). For x32 build those two have the - // same size, but for x64 build first has 64-bit size while the - // second remains 32-bit. - // In formal case that would cause 'overflow' - function will - // receive more data than needed (written to stack), with some - // values shifted further by 32 bits. - // - // Upon testing, however, it was revealed that AMD64 processor, - // the only platform we support x64 Linux AGS build on right now, - // treats all the function parameters pushed to stack as 64-bit - // values (few first parameters are sent via registers, and hence - // are least concern anyway). Therefore, no 'overflow' occurs, - // and 64-bit values are being effectively truncated to 32-bit - // integers in the callee. - // - // Since this is still quite unreliable, this should be - // reimplemented when there's enough free time available for - // developers both for coding & testing. - // - // Most basic idea is to pass array of RuntimeScriptValue - // objects (that hold type description) and get same RSV as a - // return result. Keep in mind, though, that this solution will - // require fixing ALL exported functions, so a good amount of - // time and energy should be allocated for this task. - // + // AN IMPORTANT NOTE ON PARAMS + // The original AGS interpreter did a bunch of dodgy function pointers with + // varying numbers of parameters, which were all int64_t. To simply matters + // now that we only supported plugins implemented in code, and not DLLs, + // we use a simplified Common::Array containing the parameters - switch (numparm) { - case 0: - { - int (*fparam)(); - fparam = (int (*)())addr; - return fparam(); - } - case 1: - { - int (*fparam)(intptr_t); - fparam = (int (*)(intptr_t))addr; - return fparam(parm_value[0]); - } - case 2: - { - int (*fparam)(intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1]); - } - case 3: - { - int (*fparam)(intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2]); - } - case 4: - { - int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3]); - } - case 5: - { - int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4]); - } - case 6: - { - int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5]); - } - case 7: - { - int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6]); - } - case 8: - { - int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7]); - } - case 9: - { - int (*fparam)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t); - fparam = (int (*)(intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t, intptr_t))addr; - return fparam(parm_value[0], parm_value[1], parm_value[2], parm_value[3], parm_value[4], parm_value[5], parm_value[6], parm_value[7], parm_value[8]); - } - } + if (numparm > 9) { + cc_error("too many arguments in call to function"); + return -1; + } else { + // Build the parameters + ScriptMethodParams params; + for (int i = 0; i < numparm; ++i) + params.push_back(parm_value[i]); - cc_error("too many arguments in call to function"); - return -1; + // Call the method + typedef int (*ScriptMethod)(const ScriptMethodParams ¶ms); + ScriptMethod fparam = (ScriptMethod)addr; + return fparam(params); + } } } // namespace AGS3 diff --git a/engines/ags/plugins/agscreditz/agscreditz.cpp b/engines/ags/plugins/agscreditz/agscreditz.cpp index bae5322bc043..8f30b69f0fcf 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.cpp +++ b/engines/ags/plugins/agscreditz/agscreditz.cpp @@ -59,74 +59,89 @@ void AgsCreditz::AGS_EngineStartup(IAGSEngine *engine) { SCRIPT_METHOD(IsStaticCreditsFinished); } -void AgsCreditz::SetCredit(int ID, string credit, int colour, int font, int center, int xpos, int generateoutline) { +void AgsCreditz::SetCredit(const ScriptMethodParams ¶ms) { + PARAMS7(int, ID, string, credit, int, colour, int, font, int, center, int, xpos, int, generateoutline); } -void AgsCreditz::ScrollCredits(int onoff, int speed, int fromY, int toY, int isautom, int wait, int res) { +void AgsCreditz::ScrollCredits(const ScriptMethodParams ¶ms) { + PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, res); } -string AgsCreditz::GetCredit(int ID) { - return string(); +string AgsCreditz::GetCredit(const ScriptMethodParams ¶ms) { + PARAMS1(int, ID); + return nullptr; } -int AgsCreditz::IsCreditScrollingFinished() { +int AgsCreditz::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { return true; } -void AgsCreditz::SetCreditImage(int ID, int Slot, int center, int xpos, int pixtonext) { +void AgsCreditz::SetCreditImage(const ScriptMethodParams ¶ms) { + PARAMS5(int, ID, int, Slot, int, center, int, xpos, int, pixtonext); } -void AgsCreditz::PauseScroll(int onoff) { +void AgsCreditz::PauseScroll(const ScriptMethodParams ¶ms) { + PARAMS1(int, onoff); } -void AgsCreditz::ScrollReset() { +void AgsCreditz::ScrollReset(const ScriptMethodParams ¶ms) { } -void AgsCreditz::SetEmptyLineHeight(int Height) { +void AgsCreditz::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { + PARAMS1(int, Height); } -int AgsCreditz::GetEmptyLineHeight() { +int AgsCreditz::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { return 0; } -void AgsCreditz::SetStaticCredit(int ID, int x, int y, int creditfont, int creditcolour, int centered, int generateoutline, string credit) { +void AgsCreditz::SetStaticCredit(const ScriptMethodParams ¶ms) { + PARAMS8(int, ID, int, x, int, y, int, creditfont, int, creditcolour, int, centered, int, generateoutline, string, credit); } -string AgsCreditz::GetStaticCredit(int ID) { - return string(); +string AgsCreditz::GetStaticCredit(const ScriptMethodParams ¶ms) { + PARAMS1(int, ID); + return nullptr; } -void AgsCreditz::StartEndStaticCredits(int onoff, int res) { +void AgsCreditz::StartEndStaticCredits(const ScriptMethodParams ¶ms) { + PARAMS2(int, onoff, int, res); } -int AgsCreditz::GetCurrentStaticCredit() { +int AgsCreditz::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { return 0; } -void AgsCreditz::SetDefaultStaticDelay(int Cyclesperchar) { +void AgsCreditz::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { + PARAMS1(int, Cyclesperchar); } -void AgsCreditz::SetStaticPause(int ID, int length) { +void AgsCreditz::SetStaticPause(const ScriptMethodParams ¶ms) { + PARAMS2(int, ID, int, length); } -void AgsCreditz::SetStaticCreditTitle(int ID, int x, int y, int titlefont, int titlecolour, int centered, int generateoutline, string title) { +void AgsCreditz::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { + PARAMS8(int, ID, int, x, int, y, int, titlefont, int, titlecolour, int, centered, int, generateoutline, string, title); } -void AgsCreditz::ShowStaticCredit(int ID, int time, int style, int transtime, int sound, int resolution) { +void AgsCreditz::ShowStaticCredit(const ScriptMethodParams ¶ms) { + PARAMS6(int, ID, int, time, int, style, int, transtime, int, sound, int, resolution); } -void AgsCreditz::StaticReset() { +void AgsCreditz::StaticReset(const ScriptMethodParams ¶ms) { } -string AgsCreditz::GetStaticCreditTitle(int ID) { - return string(); +string AgsCreditz::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { + PARAMS1(int, ID); + return nullptr; } -void AgsCreditz::SetStaticCreditImage(int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time) { +void AgsCreditz::SetStaticCreditImage(const ScriptMethodParams ¶ms) { +//int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time) { } -int AgsCreditz::IsStaticCreditsFinished() { +int AgsCreditz::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { return true; } diff --git a/engines/ags/plugins/agscreditz/agscreditz.h b/engines/ags/plugins/agscreditz/agscreditz.h index 60962602187d..d10c1a889322 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.h +++ b/engines/ags/plugins/agscreditz/agscreditz.h @@ -34,27 +34,28 @@ class AgsCreditz : public DLL { static const char *AGS_GetPluginName(); static void AGS_EngineStartup(IAGSEngine *engine); - static void SetCredit(int ID, string credit, int colour, int font, int center, int xpos, int generateoutline); - static void ScrollCredits(int onoff, int speed, int fromY, int toY, int isautom, int wait, int res); - static string GetCredit(int ID); - static int IsCreditScrollingFinished(); - static void SetCreditImage(int ID, int Slot, int center, int xpos, int pixtonext); - static void PauseScroll(int onoff); - static void ScrollReset(); - static void SetEmptyLineHeight(int Height); - static int GetEmptyLineHeight(); - static void SetStaticCredit(int ID, int x, int y, int creditfont, int creditcolour, int centered, int generateoutline, string credit); - static string GetStaticCredit(int ID); - static void StartEndStaticCredits(int onoff, int res); - static int GetCurrentStaticCredit(); - static void SetDefaultStaticDelay(int Cyclesperchar); - static void SetStaticPause(int ID, int length); - static void SetStaticCreditTitle(int ID, int x, int y, int titlefont, int titlecolour, int centered, int generateoutline, string title); - static void ShowStaticCredit(int ID, int time, int style, int transtime, int sound, int resolution); - static void StaticReset(); - static string GetStaticCreditTitle(int ID); - static void SetStaticCreditImage(int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time); - static int IsStaticCreditsFinished(); + // Script methods + static void SetCredit(const ScriptMethodParams ¶ms); + static void ScrollCredits(const ScriptMethodParams ¶ms); + static string GetCredit(const ScriptMethodParams ¶ms); + static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); + static void SetCreditImage(const ScriptMethodParams ¶ms); + static void PauseScroll(const ScriptMethodParams ¶ms); + static void ScrollReset(const ScriptMethodParams ¶ms); + static void SetEmptyLineHeight(const ScriptMethodParams ¶ms); + static int GetEmptyLineHeight(const ScriptMethodParams ¶ms); + static void SetStaticCredit(const ScriptMethodParams ¶ms); + static string GetStaticCredit(const ScriptMethodParams ¶ms); + static void StartEndStaticCredits(const ScriptMethodParams ¶ms); + static int GetCurrentStaticCredit(const ScriptMethodParams ¶ms); + static void SetDefaultStaticDelay(const ScriptMethodParams ¶ms); + static void SetStaticPause(const ScriptMethodParams ¶ms); + static void SetStaticCreditTitle(const ScriptMethodParams ¶ms); + static void ShowStaticCredit(const ScriptMethodParams ¶ms); + static void StaticReset(const ScriptMethodParams ¶ms); + static string GetStaticCreditTitle(const ScriptMethodParams ¶ms); + static void SetStaticCreditImage(const ScriptMethodParams ¶ms); + static int IsStaticCreditsFinished(const ScriptMethodParams ¶ms); public: AgsCreditz(); }; diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h index e3fedacf8850..2d653a4edc9e 100644 --- a/engines/ags/plugins/dll.h +++ b/engines/ags/plugins/dll.h @@ -34,8 +34,55 @@ namespace Plugins { #define DLL_METHOD(NAME) _methods[#NAME] = (void *)&NAME #define SCRIPT_METHOD(NAME) engine->RegisterScriptFunction(#NAME, (void *)&NAME) +#define PARAMS1(T1, N1) \ + T1 N1 = (T1)params[0] +#define PARAMS2(T1, N1, T2, N2) \ + T1 N1 = (T1)params[0]; \ + T2 N2 = (T2)params[1] +#define PARAMS3(T1, N1, T2, N2, T3, N3) \ + T1 N1 = (T1)params[0]; \ + T2 N2 = (T2)params[1]; \ + T3 N3 = (T3)params[2] +#define PARAMS4(T1, N1, T2, N2, T3, N3, T4, N4) \ + T1 N1 = (T1)params[0]; \ + T2 N2 = (T2)params[1]; \ + T3 N3 = (T3)params[2]; \ + T4 N4 = (T4)params[3] +#define PARAMS5(T1, N1, T2, N2, T3, N3, T4, N4, T5, N5) \ + T1 N1 = (T1)params[0]; \ + T2 N2 = (T2)params[1]; \ + T3 N3 = (T3)params[2]; \ + T4 N4 = (T4)params[3]; \ + T5 N5 = (T5)params[4] +#define PARAMS6(T1, N1, T2, N2, T3, N3, T4, N4, T5, N5, T6, N6) \ + T1 N1 = (T1)params[0]; \ + T2 N2 = (T2)params[1]; \ + T3 N3 = (T3)params[2]; \ + T4 N4 = (T4)params[3]; \ + T5 N5 = (T5)params[4]; \ + T6 N6 = (T6)params[5] +#define PARAMS7(T1, N1, T2, N2, T3, N3, T4, N4, T5, N5, T6, N6, T7, N7) \ + T1 N1 = (T1)params[0]; \ + T2 N2 = (T2)params[1]; \ + T3 N3 = (T3)params[2]; \ + T4 N4 = (T4)params[3]; \ + T5 N5 = (T5)params[4]; \ + T6 N6 = (T6)params[5]; \ + T7 N7 = (T7)params[6] +#define PARAMS8(T1, N1, T2, N2, T3, N3, T4, N4, T5, N5, T6, N6, T7, N7, T8, N8) \ + T1 N1 = (T1)params[0]; \ + T2 N2 = (T2)params[1]; \ + T3 N3 = (T3)params[2]; \ + T4 N4 = (T4)params[3]; \ + T5 N5 = (T5)params[4]; \ + T6 N6 = (T6)params[5]; \ + T7 N7 = (T7)params[6]; \ + T8 N8 = (T8)params[7] + + // TODO: Refactor string into core AGS namespace -using string = ::AGS3::AGS::Shared::String; +using string = const char *; +using ScriptMethodParams = ::AGS3::ScriptMethodParams; using IAGSEngine = ::AGS3::IAGSEngine; using IAGSEditor = ::AGS3::IAGSEditor; From 46f050312a19f57a5ce8eb01691c7ec24e979be0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 14 Jan 2021 20:12:13 -0800 Subject: [PATCH 120/215] AGS: Saves now has dummy path for clarity, added MetaEngine listSaves --- engines/ags/engine/ac/game.cpp | 3 +- engines/ags/engine/ac/richgamemedia.cpp | 11 +++++++ engines/ags/engine/ac/richgamemedia.h | 34 ++++++++++++++------ engines/ags/engine/game/savegame.cpp | 13 ++------ engines/ags/metaengine.cpp | 42 +++++++++++++++++++++++++ engines/ags/metaengine.h | 9 +++++- engines/ags/shared/util/filestream.cpp | 40 +++++++++++++---------- engines/ags/shared/util/filestream.h | 2 ++ 8 files changed, 115 insertions(+), 39 deletions(-) diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 1332850a67fd..26f275be2636 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -361,7 +361,8 @@ void set_save_game_suffix(const String &suffix) { String get_save_game_path(int slotNum) { #if AGS_PLATFORM_SCUMMVM - return ::AGS::g_vm->getSaveStateName(slotNum); + return Common::String::format("%s%s", SAVE_FOLDER_PREFIX, + ::AGS::g_vm->getSaveStateName(slotNum).c_str()); #else String filename; filename.Format(sgnametemplate, slotNum); diff --git a/engines/ags/engine/ac/richgamemedia.cpp b/engines/ags/engine/ac/richgamemedia.cpp index 1c09739ddd8a..ae6852d3a3b6 100644 --- a/engines/ags/engine/ac/richgamemedia.cpp +++ b/engines/ags/engine/ac/richgamemedia.cpp @@ -55,4 +55,15 @@ void RICH_GAME_MEDIA_HEADER::WriteToFile(Stream *out) { out->WriteArrayOfInt16((int16_t *)szComments, RM_MAXLENGTH); } +void RICH_GAME_MEDIA_HEADER::setSaveName(const Common::String &saveName) { + uconvert(saveName.c_str(), szSaveName, RM_MAXLENGTH); +} + +Common::String RICH_GAME_MEDIA_HEADER::getSaveName() const { + char buf[RM_MAXLENGTH]; + uconvert(szSaveName, buf, RM_MAXLENGTH); + + return Common::String(buf); +} + } // namespace AGS3 diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index f28cd454aef3..c66a46d8353d 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -23,12 +23,15 @@ #ifndef AGS_ENGINE_AC_RICHGAMEMEDIA_H #define AGS_ENGINE_AC_RICHGAMEMEDIA_H +#include "common/algorithm.h" +#include "common/str.h" + namespace AGS3 { // Windows Vista Rich Save Games, modified to be platform-agnostic #define RM_MAXLENGTH 1024 -#define RM_MAGICNUMBER "RGMH" +#define RM_MAGICNUMBER MKTAG('R', 'G', 'M', 'H') // Forward declaration namespace AGS { @@ -41,22 +44,35 @@ using namespace AGS; // FIXME later #pragma pack(push) #pragma pack(1) -typedef struct _RICH_GAME_MEDIA_HEADER { - int dwMagicNumber; +struct RICH_GAME_MEDIA_HEADER { +private: + template + static void uconvert(const SRC *src, DEST *dest, size_t maxSize) { + do { + *dest++ = *src; + } while (*src++ != 0 && --maxSize > 1); + + *dest = '\0'; + } +public: + uint32 dwMagicNumber; int dwHeaderVersion; int dwHeaderSize; int dwThumbnailOffsetLowerDword; int dwThumbnailOffsetHigherDword; int dwThumbnailSize; - unsigned char guidGameId[16]; - unsigned short szGameName[RM_MAXLENGTH]; - unsigned short szSaveName[RM_MAXLENGTH]; - unsigned short szLevelName[RM_MAXLENGTH]; - unsigned short szComments[RM_MAXLENGTH]; + byte guidGameId[16]; + uint16 szGameName[RM_MAXLENGTH]; + uint16 szSaveName[RM_MAXLENGTH]; + uint16 szLevelName[RM_MAXLENGTH]; + uint16 szComments[RM_MAXLENGTH]; void ReadFromFile(Shared::Stream *in); void WriteToFile(Shared::Stream *out); -} RICH_GAME_MEDIA_HEADER; + + void setSaveName(const Common::String &saveName); + Common::String getSaveName() const; +}; #pragma pack(pop) } // namespace AGS3 diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index f9adcdb69fdd..89d746abdb0a 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -683,14 +683,6 @@ void WriteDescription(Stream *out, const String &user_text, const Bitmap *user_i WriteSaveImage(out, user_image); } -static void uconvert(const char *src, unsigned short *dest, int maxSize) { - do { - *dest++ = *src; - } while (*src++ != 0 && --maxSize > 1); - - *dest = '\0'; -} - PStream StartSavegame(const String &filename, const String &user_text, const Bitmap *user_image) { Stream *out = Shared::File::CreateFile(filename); if (!out) @@ -699,7 +691,7 @@ PStream StartSavegame(const String &filename, const String &user_text, const Bit // Initialize and write Vista header RICH_GAME_MEDIA_HEADER vistaHeader; memset(&vistaHeader, 0, sizeof(RICH_GAME_MEDIA_HEADER)); - memcpy(&vistaHeader.dwMagicNumber, RM_MAGICNUMBER, sizeof(int)); + vistaHeader.dwMagicNumber = RM_MAGICNUMBER; vistaHeader.dwHeaderVersion = 1; vistaHeader.dwHeaderSize = sizeof(RICH_GAME_MEDIA_HEADER); vistaHeader.dwThumbnailOffsetHigherDword = 0; @@ -708,8 +700,7 @@ PStream StartSavegame(const String &filename, const String &user_text, const Bit convert_guid_from_text_to_binary(game.guid, &vistaHeader.guidGameId[0]); #if 1 - Common::String name = Common::String::format("%s %s", game.gamename, user_text.GetNullableCStr()); - uconvert(name.c_str(), vistaHeader.szSaveName, RM_MAXLENGTH); + vistaHeader.setSaveName(user_text); #else uconvert(game.gamename, U_ASCII, (char *)&vistaHeader.szGameName[0], U_UNICODE, RM_MAXLENGTH); uconvert(user_text, U_ASCII, (char *)&vistaHeader.szSaveName[0], U_UNICODE, RM_MAXLENGTH); diff --git a/engines/ags/metaengine.cpp b/engines/ags/metaengine.cpp index bb737c24f0b9..e210080f4179 100644 --- a/engines/ags/metaengine.cpp +++ b/engines/ags/metaengine.cpp @@ -23,6 +23,10 @@ #include "ags/metaengine.h" #include "ags/detection.h" #include "ags/ags.h" +#include "ags/shared/util/filestream.h" +#include "ags/engine/ac/richgamemedia.h" +#include "ags/engine/game/savegame.h" +#include "common/savefile.h" const char *AGSMetaEngine::getName() const { return "ags"; @@ -35,6 +39,44 @@ Common::Error AGSMetaEngine::createInstance(OSystem *syst, Engine **engine, cons return Common::kNoError; } +SaveStateList AGSMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String pattern(getSavegameFilePattern(target)); + + filenames = saveFileMan->listSavefiles(pattern); + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + Common::String filename = Common::String::format("%s%s", + ::AGS3::AGS::Shared::SAVE_FOLDER_PREFIX, file->c_str()); + + ::AGS3::AGS::Shared::FileStream saveFile(filename, ::AGS3::AGS::Shared::kFile_Open, + ::AGS3::AGS::Shared::kFile_Read); + if (saveFile.IsValid()) { + AGS3::RICH_GAME_MEDIA_HEADER rich_media_header; + rich_media_header.ReadFromFile(&saveFile); + + if (rich_media_header.dwMagicNumber == RM_MAGICNUMBER) { + int slotNum = atoi(file->c_str() + file->size() - 3); + + SaveStateDescriptor desc; + desc.setSaveSlot(slotNum); + desc.setDescription(rich_media_header.getSaveName()); + + if (slotNum == getAutosaveSlot()) + desc.setWriteProtectedFlag(true); + + saveList.push_back(desc); + } + } + } + + // Sort saves based on slot number. + Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator()); + return saveList; +} + #if PLUGIN_ENABLED_DYNAMIC(AGS) REGISTER_PLUGIN_DYNAMIC(AGS, PLUGIN_TYPE_ENGINE, AGSMetaEngine); #else diff --git a/engines/ags/metaengine.h b/engines/ags/metaengine.h index b8a6cd8c84f9..aeccb8f44751 100644 --- a/engines/ags/metaengine.h +++ b/engines/ags/metaengine.h @@ -31,7 +31,14 @@ class AGSMetaEngine : public AdvancedMetaEngine { public: const char *getName() const override; - virtual Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override; + + SaveStateList listSaves(const char *target) const override; + + int getAutosaveSlot() const override { + return 999; + } + }; #endif diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index 44988fd5fc47..620124a42f82 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -31,6 +31,8 @@ namespace AGS3 { namespace AGS { namespace Shared { +const char *SAVE_FOLDER_PREFIX = "/saves/"; + FileStream::FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) : DataStream(stream_endianess), _writeBuffer(DisposeAfterUse::YES), @@ -174,31 +176,35 @@ bool FileStream::Seek(soff_t offset, StreamSeek origin) { void FileStream::Open(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode) { if (open_mode == kFile_Open) { - // First try to open file in game folder - Common::File *f = new Common::File(); - if (!file_name.CompareLeftNoCase("agssave.") || !f->open(getFSNode(file_name.GetNullableCStr()))) { - delete f; - - // Fall back on any save file with the given name - String saveName = file_name; - if (!file_name.CompareLeftNoCase("agssave.")) { - int saveSlot = atoi(file_name.GetNullableCStr() + 8); - saveName = ::AGS::g_vm->getSaveStateName(saveSlot); - } + if (!file_name.CompareLeftNoCase(SAVE_FOLDER_PREFIX)) { + _file = g_system->getSavefileManager()->openForLoading( + file_name.GetNullableCStr() + strlen(SAVE_FOLDER_PREFIX)); - _file = g_system->getSavefileManager()->openForLoading(saveName); } else { - _file = f; + // First try to open file in game folder + Common::File *f = new Common::File(); + if (!f->open(getFSNode(file_name.GetNullableCStr()))) { + delete f; + _file = nullptr; + } else { + _file = f; + } } } else { - // All newly created files are created as save files - _outSave = g_system->getSavefileManager()->openForSaving(file_name, false); - if (_outSave) { + if (!file_name.CompareLeftNoCase(SAVE_FOLDER_PREFIX)) { + _outSave = g_system->getSavefileManager()->openForSaving( + file_name + strlen(SAVE_FOLDER_PREFIX), false); + } else if (file_name == "warnings.log") { + _outSave = g_system->getSavefileManager()->openForSaving(file_name, false); + } else { + error("Creating files is only supported for savegames"); + } + + if (_outSave) // Any data written has to first go through the memory stream buffer, // since the savegame code uses Seeks, which OutSaveFile doesn't support _file = &_writeBuffer; - } } } diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index ff9994c11108..491e552fadd2 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -33,6 +33,8 @@ namespace AGS3 { namespace AGS { namespace Shared { +extern const char *SAVE_FOLDER_PREFIX; + class FileStream : public DataStream { public: From cbd2b3611137d80efda077e432b66fc381013c37 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 Jan 2021 18:12:54 -0800 Subject: [PATCH 121/215] AGS: Sound cleanup and hookup to ScummVM decoders It isn't perfect.. some of the SOUNDCLIP variables don't do anything yet. But it at least properly implements playback of sound now --- engines/ags/engine/ac/audiochannel.cpp | 12 +- engines/ags/engine/ac/audioclip.cpp | 2 +- engines/ags/engine/ac/global_audio.cpp | 6 +- engines/ags/engine/game/savegame.cpp | 8 +- .../ags/engine/game/savegame_components.cpp | 18 +- engines/ags/engine/media/audio/audio.cpp | 36 +-- .../ags/engine/media/audio/clip_mydumbmod.cpp | 2 + .../ags/engine/media/audio/clip_mydumbmod.h | 3 +- .../ags/engine/media/audio/clip_mymidi.cpp | 108 +++---- engines/ags/engine/media/audio/clip_mymidi.h | 23 +- engines/ags/engine/media/audio/clip_mymp3.cpp | 2 + engines/ags/engine/media/audio/clip_mymp3.h | 3 +- engines/ags/engine/media/audio/clip_myogg.cpp | 4 +- engines/ags/engine/media/audio/clip_myogg.h | 3 +- .../engine/media/audio/clip_mystaticmp3.cpp | 3 +- .../ags/engine/media/audio/clip_mystaticmp3.h | 3 +- .../engine/media/audio/clip_mystaticogg.cpp | 187 +---------- .../ags/engine/media/audio/clip_mystaticogg.h | 51 +-- .../ags/engine/media/audio/clip_mywave.cpp | 3 +- engines/ags/engine/media/audio/clip_mywave.h | 3 +- engines/ags/engine/media/audio/sound.cpp | 302 ++---------------- engines/ags/engine/media/audio/sound.h | 4 +- engines/ags/engine/media/audio/soundcache.cpp | 12 +- engines/ags/engine/media/audio/soundcache.h | 2 + engines/ags/engine/media/audio/soundclip.cpp | 152 +++++---- engines/ags/engine/media/audio/soundclip.h | 175 +++++----- engines/ags/lib/audio/midi.cpp | 52 --- engines/ags/lib/audio/midi.h | 12 +- engines/ags/lib/audio/ogg.cpp | 4 +- engines/ags/lib/audio/ogg.h | 4 +- engines/ags/music.cpp | 14 +- engines/ags/music.h | 6 +- 32 files changed, 393 insertions(+), 826 deletions(-) diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp index 31bb032c9aca..5659ead8d6b2 100644 --- a/engines/ags/engine/ac/audiochannel.cpp +++ b/engines/ags/engine/ac/audiochannel.cpp @@ -58,7 +58,7 @@ int AudioChannel_GetPanning(ScriptAudioChannel *channel) { auto *ch = lock.GetChannelIfPlaying(channel->id); if (ch) { - return ch->panningAsPercentage; + return ch->_panningAsPercentage; } return 0; } @@ -72,7 +72,7 @@ void AudioChannel_SetPanning(ScriptAudioChannel *channel, int newPanning) { if (ch) { ch->set_panning(((newPanning + 100) * 255) / 200); - ch->panningAsPercentage = newPanning; + ch->_panningAsPercentage = newPanning; } } @@ -81,7 +81,7 @@ ScriptAudioClip *AudioChannel_GetPlayingClip(ScriptAudioChannel *channel) { auto *ch = lock.GetChannelIfPlaying(channel->id); if (ch) { - return (ScriptAudioClip *)ch->sourceClip; + return (ScriptAudioClip *)ch->_sourceClip; } return nullptr; } @@ -189,9 +189,9 @@ void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPo if (ch) { int maxDist = ((xPos > thisroom.Width / 2) ? xPos : (thisroom.Width - xPos)) - AMBIENCE_FULL_DIST; - ch->xSource = (xPos > 0) ? xPos : -1; - ch->ySource = yPos; - ch->maximumPossibleDistanceAway = maxDist; + ch->_xSource = (xPos > 0) ? xPos : -1; + ch->_ySource = yPos; + ch->_maximumPossibleDistanceAway = maxDist; if (xPos > 0) { update_directional_sound_vol(); } else { diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp index cd4047675276..19b4c41630b7 100644 --- a/engines/ags/engine/ac/audioclip.cpp +++ b/engines/ags/engine/ac/audioclip.cpp @@ -54,7 +54,7 @@ void AudioClip_Stop(ScriptAudioClip *clip) { AudioChannelsLock lock; for (int i = 0; i < MAX_SOUND_CHANNELS; i++) { auto *ch = lock.GetChannelIfPlaying(i); - if ((ch != nullptr) && (ch->sourceClip == clip)) { + if ((ch != nullptr) && (ch->_sourceClip == clip)) { AudioChannel_Stop(&scrAudioChannel[i]); } } diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp index 1cf2aaf71e1d..78c535537da5 100644 --- a/engines/ags/engine/ac/global_audio.cpp +++ b/engines/ags/engine/ac/global_audio.cpp @@ -86,7 +86,7 @@ void PlayAmbientSound(int channel, int sndnum, int vol, int x, int y) { debug_script_log("Playing ambient sound %d on channel %d", sndnum, channel); ambient[channel].channel = channel; - asound->priority = 15; // ambient sound higher priority than normal sfx + asound->_priority = 15; // ambient sound higher priority than normal sfx set_clip_to_channel(channel, asound); } // calculate the maximum distance away the player can be, using X @@ -161,7 +161,7 @@ int PlaySoundEx(int val1, int channel) { return -1; } - soundfx->priority = 10; + soundfx->_priority = 10; soundfx->set_volume(play.sound_volume); set_clip_to_channel(channel, soundfx); return channel; @@ -547,7 +547,7 @@ static bool play_voice_clip_on_channel(const String &voice_name) { if (speechmp3 != nullptr) { if (!speechmp3->play()) { // not assigned to a channel, so clean up manually. - speechmp3->destroy(); + //speechmp3->destroy(); delete speechmp3; speechmp3 = nullptr; } diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index 89d746abdb0a..a5823f295643 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -571,10 +571,10 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data) ch->set_volume_direct(chan_info.VolAsPercent, chan_info.Vol); ch->set_speed(chan_info.Speed); ch->set_panning(chan_info.Pan); - ch->panningAsPercentage = chan_info.PanAsPercent; - ch->xSource = chan_info.XSource; - ch->ySource = chan_info.YSource; - ch->maximumPossibleDistanceAway = chan_info.MaxDist; + ch->_panningAsPercentage = chan_info.PanAsPercent; + ch->_xSource = chan_info.XSource; + ch->_ySource = chan_info.YSource; + ch->_maximumPossibleDistanceAway = chan_info.MaxDist; } } if ((cf_in_chan > 0) && (lock.GetChannel(cf_in_chan) != nullptr)) diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index 55c30b441738..f5fb62c0b46d 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -361,20 +361,16 @@ HSaveError WriteAudio(PStream out) { // Audio clips and crossfade for (int i = 0; i <= MAX_SOUND_CHANNELS; i++) { auto *ch = lock.GetChannelIfPlaying(i); - if ((ch != nullptr) && (ch->sourceClip != nullptr)) { - out->WriteInt32(((ScriptAudioClip *)ch->sourceClip)->id); + if ((ch != nullptr) && (ch->_sourceClip != nullptr)) { + out->WriteInt32(((ScriptAudioClip *)ch->_sourceClip)->id); out->WriteInt32(ch->get_pos()); - out->WriteInt32(ch->priority); - out->WriteInt32(ch->repeat ? 1 : 0); - out->WriteInt32(ch->vol); - out->WriteInt32(ch->panning); - out->WriteInt32(ch->volAsPercentage); - out->WriteInt32(ch->panningAsPercentage); + out->WriteInt32(ch->_priority); + out->WriteInt32(ch->_panningAsPercentage); out->WriteInt32(ch->get_speed()); // since version 1 - out->WriteInt32(ch->xSource); - out->WriteInt32(ch->ySource); - out->WriteInt32(ch->maximumPossibleDistanceAway); + out->WriteInt32(ch->_xSource); + out->WriteInt32(ch->_ySource); + out->WriteInt32(ch->_maximumPossibleDistanceAway); } else { out->WriteInt32(-1); } diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 954f229278a6..21e7aef89170 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -202,9 +202,9 @@ static int find_free_audio_channel(ScriptAudioClip *clip, int priority, bool int stop_and_destroy_channel(i); break; } - if ((ch->priority < lowestPrioritySoFar) && - (ch->sourceClipType == clip->type)) { - lowestPrioritySoFar = ch->priority; + if ((ch->_priority < lowestPrioritySoFar) && + (ch->_sourceClipType == clip->type)) { + lowestPrioritySoFar = ch->_priority; lowestPriorityID = i; } } @@ -259,8 +259,8 @@ SOUNDCLIP *load_sound_clip(ScriptAudioClip *audioClip, bool repeat) { } if (soundClip != nullptr) { soundClip->set_volume_percent(audioClip->defaultVolume); - soundClip->sourceClip = audioClip; - soundClip->sourceClipType = audioClip->type; + soundClip->_sourceClip = audioClip; + soundClip->_sourceClipType = audioClip->type; } return soundClip; } @@ -337,7 +337,7 @@ static void audio_update_polled_stuff() { // Applies a volume drop modifier to the clip, in accordance to its audio type static void apply_volume_drop_to_clip(SOUNDCLIP *clip) { - int audiotype = clip->sourceClipType; + int audiotype = clip->_sourceClipType; clip->apply_volume_modifier(-(game.audioClipTypes[audiotype].volume_reduction_while_speech_playing * 255 / 100)); } @@ -370,7 +370,7 @@ ScriptAudioChannel *play_audio_clip_on_channel(int channel, ScriptAudioClip *cli } return nullptr; } - soundfx->priority = priority; + soundfx->_priority = priority; if (play.crossfading_in_channel == channel) { soundfx->set_volume_percent(0); @@ -573,13 +573,13 @@ void update_directional_sound_vol() { for (int chnum = 1; chnum < MAX_SOUND_CHANNELS; chnum++) { auto *ch = lock.GetChannelIfPlaying(chnum); - if ((ch != nullptr) && (ch->xSource >= 0)) { + if ((ch != nullptr) && (ch->_xSource >= 0)) { ch->apply_directional_modifier( - get_volume_adjusted_for_distance(ch->vol, - ch->xSource, - ch->ySource, - ch->maximumPossibleDistanceAway) - - ch->vol); + get_volume_adjusted_for_distance(ch->_vol, + ch->_xSource, + ch->_ySource, + ch->_maximumPossibleDistanceAway) - + ch->_vol); } } } @@ -685,11 +685,11 @@ static int play_sound_priority(int val1, int priority) { assert(usechan == i); auto *chan = lock.GetChannel(usechan); if (chan) - chan->priority = priority; + chan->_priority = priority; } return usechan; - } else if (ch->priority < lowest_pri) { - lowest_pri = ch->priority; + } else if (ch->_priority < lowest_pri) { + lowest_pri = ch->_priority; lowest_pri_id = i; } @@ -705,7 +705,7 @@ static int play_sound_priority(int val1, int priority) { assert(usechan == lowest_pri_id); auto *ch = lock.GetChannel(usechan); if (ch) - ch->priority = priority; + ch->_priority = priority; return usechan; } } @@ -830,7 +830,7 @@ void apply_volume_drop_modifier(bool applyModifier) { for (int i = 0; i < MAX_SOUND_CHANNELS; i++) { auto *ch = lock.GetChannelIfPlaying(i); - if (ch && ch->sourceClip != nullptr) { + if (ch && ch->_sourceClip != nullptr) { if (applyModifier) apply_volume_drop_to_clip(ch); else diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp index d5c2262379e0..ae0921b1fa29 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.cpp +++ b/engines/ags/engine/media/audio/clip_mydumbmod.cpp @@ -28,6 +28,7 @@ #include "ags/engine/media/audio/audiointernaldefs.h" namespace AGS3 { +#ifdef DEPRECATED void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop) { DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(dp); @@ -178,6 +179,7 @@ MYMOD::MYMOD() : SOUNDCLIP() { duhPlayer = nullptr; } +#endif } // namespace AGS3 #endif // DUMB_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h index 370de3f344c8..ad98d49c2fb8 100644 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ b/engines/ags/engine/media/audio/clip_mydumbmod.h @@ -27,6 +27,7 @@ #include "ags/engine/media/audio/soundclip.h" namespace AGS3 { +#ifdef DEPRECATED #define VOLUME_TO_DUMB_VOL(vol) ((float)vol) / 256.0 @@ -74,7 +75,7 @@ struct MYMOD : public SOUNDCLIP { // Returns real MOD/XM playing position int get_real_mod_pos(); }; - +#endif } // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index ff0a1fd481fe..01e0e3b4bcb7 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -27,103 +27,79 @@ namespace AGS3 { -void MYMIDI::poll() { - if (state_ != SoundClipPlaying) { - return; - } - - if (midi_pos < 0) - state_ = SoundClipStopped; -} - -void MYMIDI::adjust_volume() { - if (!is_playing()) { - return; - } - AGS3::set_volume(-1, get_final_volume()); -} - -void MYMIDI::set_volume(int newvol) { - vol = newvol; - adjust_volume(); +MYMIDI::MYMIDI(Common::SeekableReadStream *data, bool repeat) : + _data(data), _repeat(repeat), lengthInSeconds(0) { } void MYMIDI::destroy() { - stop_midi(); - - if (tune) { - destroy_midi(tune); - } - tune = nullptr; - - state_ = SoundClipStopped; + stop(); + delete _data; + _data = nullptr; } void MYMIDI::seek(int pos) { - if (!is_playing()) { - return; - } - midi_seek(pos); + warning("TODO: MYMIDI::seek"); } int MYMIDI::get_pos() { - if (!is_playing()) { - return -1; - } - return midi_pos; + // We don't know ms with midi + return 0; } int MYMIDI::get_pos_ms() { - return 0; // we don't know ms with midi + // We don't know ms with midi + return 0; } int MYMIDI::get_length_ms() { + warning("TODO: MYMIDI::get_length_ms"); return lengthInSeconds * 1000; } -int MYMIDI::get_voice() { - // voice is N/A for midi - return -1; -} - void MYMIDI::pause() { - if (state_ != SoundClipPlaying) { - return; - } - midi_pause(); - state_ = SoundClipPaused; + ::AGS::g_music->pause(); + _state = SoundClipPaused; } void MYMIDI::resume() { - if (state_ != SoundClipPaused) { + if (_state != SoundClipPaused) return; - } - midi_resume(); - state_ = SoundClipPlaying; -} -int MYMIDI::get_sound_type() { - return MUS_MIDI; + ::AGS::g_music->resume(); + _state = SoundClipPlaying; } int MYMIDI::play() { - if (tune == nullptr) { - return 0; - } + ::AGS::g_music->playMusic(_data, _repeat); + _state = SoundClipPlaying; + return 1; +} - lengthInSeconds = get_midi_length(tune); - if (AGS3::play_midi(tune, repeat)) { - lengthInSeconds = 0; - return 0; - } +void MYMIDI::stop() { + ::AGS::g_music->stop(); +} - state_ = SoundClipPlaying; - return 1; +bool MYMIDI::is_playing() const { + return ::AGS::g_music->isPlaying(); +} + +int MYMIDI::get_volume() const { + return _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType); } -MYMIDI::MYMIDI() : SOUNDCLIP() { - tune = nullptr; - lengthInSeconds = 0; +void MYMIDI::set_volume(int volume) { + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume); +} + +void MYMIDI::set_panning(int newPanning) { + // No implementation for MIDI +} + +/* +int MYMIDI::get_voice() { + // voice is N/A for midi + return -1; } +*/ } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index 87e21d770409..78c7b4fea1e9 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -29,12 +29,12 @@ namespace AGS3 { // MIDI struct MYMIDI : public SOUNDCLIP { - MIDI *tune; + Common::SeekableReadStream *_data; + bool _repeat; int lengthInSeconds; - void poll() override; - - void set_volume(int newvol) override; + MYMIDI(Common::SeekableReadStream *data, bool repeat); + ~MYMIDI() override {} void destroy() override; @@ -50,15 +50,16 @@ struct MYMIDI : public SOUNDCLIP { void resume() override; - int get_sound_type() override; + int get_sound_type() const override { + return MUS_MIDI; + } int play() override; - - MYMIDI(); - -protected: - int get_voice() override; - void adjust_volume() override; + void stop() override; + bool is_playing() const override; + int get_volume() const override; + void set_volume(int volume) override; + void set_panning(int newPanning) override; }; } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp index ce87812b46d2..28d1e0e70a97 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ b/engines/ags/engine/media/audio/clip_mymp3.cpp @@ -33,6 +33,7 @@ #include "ags/ags.h" namespace AGS3 { +#ifdef DEPRECATED void MYMP3::poll() { if (state_ != SoundClipPlaying) { @@ -182,6 +183,7 @@ MYMP3::MYMP3() : SOUNDCLIP() { chunksize = 0; } +#endif } // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h index 148799b0152b..a8c283454edf 100644 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ b/engines/ags/engine/media/audio/clip_mymp3.h @@ -28,6 +28,7 @@ #include "ags/engine/media/audio/soundclip.h" namespace AGS3 { +#ifdef DEPRECATED struct MYMP3 : public SOUNDCLIP { ALMP3_MP3STREAM *stream; @@ -54,7 +55,7 @@ struct MYMP3 : public SOUNDCLIP { private: void adjust_stream(); }; - +#endif } // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp index c2c16a770de8..cc52a6e223f0 100644 --- a/engines/ags/engine/media/audio/clip_myogg.cpp +++ b/engines/ags/engine/media/audio/clip_myogg.cpp @@ -31,7 +31,7 @@ #include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { - +#ifdef DEPRECATED void MYOGG::poll() { if (state_ != SoundClipPlaying) { return; @@ -202,5 +202,5 @@ MYOGG::MYOGG() : SOUNDCLIP() { last_but_one = 0; last_ms_offs = 0; } - +#endif } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h index 951ae336b3a2..f619ec5a90fc 100644 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ b/engines/ags/engine/media/audio/clip_myogg.h @@ -28,7 +28,7 @@ #include "ags/engine/media/audio/soundclip.h" namespace AGS3 { - +#ifdef DEPRECATED struct MYOGG : public SOUNDCLIP { ALOGG_OGGSTREAM *stream; PACKFILE *in; @@ -67,6 +67,7 @@ struct MYOGG : public SOUNDCLIP { void adjust_stream(); }; +#endif } // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp index 65ae8b3ef62d..43c336d71348 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp @@ -32,6 +32,7 @@ #include "ags/ags.h" namespace AGS3 { +#ifdef DEPRECATED extern int our_eip; @@ -159,7 +160,7 @@ MYSTATICMP3::MYSTATICMP3() : SOUNDCLIP() { tune = nullptr; mp3buffer = nullptr; } - +#endif } // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h index 575df1583b54..6592ae8c1933 100644 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ b/engines/ags/engine/media/audio/clip_mystaticmp3.h @@ -27,7 +27,7 @@ #include "ags/engine/media/audio/soundclip.h" namespace AGS3 { - +#ifdef DEPRECATED // pre-loaded (non-streaming) MP3 file struct MYSTATICMP3 : public SOUNDCLIP { ALMP3_MP3 *tune; @@ -60,6 +60,7 @@ struct MYSTATICMP3 : public SOUNDCLIP { private: void adjust_stream(); }; +#endif } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp index 84654620ce4b..363bfa561775 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.cpp +++ b/engines/ags/engine/media/audio/clip_mystaticogg.cpp @@ -20,195 +20,12 @@ * */ -#include "ags/engine/media/audio/audiodefines.h" #include "ags/engine/media/audio/clip_mystaticogg.h" -#include "ags/engine/media/audio/audiointernaldefs.h" -#include "ags/engine/media/audio/soundcache.h" -#include "ags/engine/util/mutex_lock.h" - -#include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/lib/audio/digi.h" -#include "ags/lib/audio/ogg.h" +#include "audio/decoders/vorbis.h" +#include "common/memstream.h" namespace AGS3 { extern int use_extra_sound_offset; // defined in ac.cpp -void MYSTATICOGG::poll() { - if (state_ != SoundClipPlaying) { - return; - } - - if (alogg_poll_ogg(tune) == ALOGG_POLL_PLAYJUSTFINISHED) { - if (!repeat) { - state_ = SoundClipStopped; - } - } else get_pos(); // call this to keep the last_but_one stuff up to date -} - -void MYSTATICOGG::adjust_stream() { - if (!is_playing()) { - return; - } - alogg_adjust_ogg(tune, get_final_volume(), panning, speed, repeat); -} - -void MYSTATICOGG::adjust_volume() { - adjust_stream(); -} - -void MYSTATICOGG::set_volume(int newvol) { - vol = newvol; - adjust_stream(); -} - -void MYSTATICOGG::set_speed(int new_speed) { - speed = new_speed; - adjust_stream(); -} - -void MYSTATICOGG::destroy() { - if (tune) { - alogg_stop_ogg(tune); - alogg_destroy_ogg(tune); - } - tune = nullptr; - - if (mp3buffer) { - sound_cache_free(mp3buffer, false); - } - mp3buffer = nullptr; - - state_ = SoundClipStopped; -} - -void MYSTATICOGG::seek(int pos) { - if (!is_playing()) { - return; - } - - // we stop and restart it because otherwise the buffer finishes - // playing first and the seek isn't quite accurate - alogg_stop_ogg(tune); - state_ = SoundClipInitial; - play_from(pos); -} - -int MYSTATICOGG::get_pos() { - if (!is_playing()) { - return -1; - } - return get_pos_ms(); -} - -int MYSTATICOGG::get_pos_ms() { - if (!is_playing()) { - return -1; - } - - // Unfortunately the alogg_get_pos_msecs function - // returns the ms offset that was last decoded, so it's always - // ahead of the actual playback. Therefore we have this - // hideous hack below to sort it out. - if (!alogg_is_playing_ogg(tune)) - return 0; - - AUDIOSTREAM *str = alogg_get_audiostream_ogg(tune); - long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; - - if (last_ms_offs != alogg_get_pos_msecs_ogg(tune)) { - last_but_one_but_one = last_but_one; - last_but_one = last_ms_offs; - last_ms_offs = alogg_get_pos_msecs_ogg(tune); - } - - // just about to switch buffers - if (offs < 0) - return last_but_one; - - int end_of_stream = alogg_is_end_of_ogg(tune); - - if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { - switch (end_of_stream) { - case 0: - case 2: - offs -= (last_but_one - last_but_one_but_one); - break; - case 1: - offs -= (last_but_one - last_but_one_but_one); - break; - } - } - - if (end_of_stream == 1) { - return offs + last_but_one + extraOffset; - } - - return offs + last_but_one_but_one + extraOffset; -} - -int MYSTATICOGG::get_length_ms() { - if (tune == nullptr) { - return -1; - } - return alogg_get_length_msecs_ogg(tune); -} - -int MYSTATICOGG::get_voice() { - if (!is_playing()) { - return -1; - } - AUDIOSTREAM *ast = alogg_get_audiostream_ogg(tune); - if (ast) - return ast->voice; - return -1; -} - -int MYSTATICOGG::get_sound_type() { - return MUS_OGG; -} - -int MYSTATICOGG::play_from(int position) { - if (tune == nullptr) { - return 0; - } - - if (use_extra_sound_offset) - extraOffset = ((16384 / (alogg_get_wave_is_stereo_ogg(tune) ? 2 : 1)) * 1000) / alogg_get_wave_freq_ogg(tune); - else - extraOffset = 0; - - if (alogg_play_ex_ogg(tune, 16384, vol, panning, 1000, repeat) != ALOGG_OK) { - return 0; - } - - last_ms_offs = position; - last_but_one = position; - last_but_one_but_one = position; - - if (position > 0) - alogg_seek_abs_msecs_ogg(tune, position); - - state_ = SoundClipPlaying; - - if (!psp_audio_multithreaded) - poll(); - - return 1; -} - -int MYSTATICOGG::play() { - return play_from(0); -} - -MYSTATICOGG::MYSTATICOGG() : SOUNDCLIP() { - tune = nullptr; - mp3buffer = nullptr; - mp3buffersize = 0; - extraOffset = 0; - last_but_one = 0; - last_ms_offs = 0; - last_but_one_but_one = 0; -} - } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h index cffe99009045..56b2bb00d260 100644 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ b/engines/ags/engine/media/audio/clip_mystaticogg.h @@ -24,51 +24,20 @@ #define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H #include "ags/lib/audio/ogg.h" -#include "ags/engine/media/audio/soundclip.h" namespace AGS3 { +#ifdef DEPRECATED +/** + * Pre-loaded (non-streaming) OGG file + */ +struct MYSTATICOGG : public AUDIO_STREAM { + MYSTATICOGG(const byte *data, size_t len, bool repeat); -// pre-loaded (non-streaming) OGG file -struct MYSTATICOGG : public SOUNDCLIP { - ALOGG_OGG *tune; - char *mp3buffer; - int mp3buffersize; - int extraOffset; - - int last_but_one_but_one; - int last_but_one; - int last_ms_offs; - - void poll() override; - - void set_volume(int newvol) override; - void set_speed(int new_speed) override; - - void destroy() override; - - void seek(int pos) override; - - int get_pos() override; - - int get_pos_ms() override; - - int get_length_ms() override; - - int get_sound_type() override; - - int play_from(int position) override; - - int play() override; - - MYSTATICOGG(); - -protected: - int get_voice() override; - void adjust_volume() override; -private: - void adjust_stream(); + int get_sound_type() override { + return MUS_OGG; + } }; - +#endif } // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp index f11f1b22dd91..6a6d02b6babd 100644 --- a/engines/ags/engine/media/audio/clip_mywave.cpp +++ b/engines/ags/engine/media/audio/clip_mywave.cpp @@ -31,6 +31,7 @@ #include "ags/engine/platform/base/agsplatformdriver.h" namespace AGS3 { +#ifdef DEPRECATED void MYWAVE::poll() { if (state_ != SoundClipPlaying) { @@ -131,5 +132,5 @@ MYWAVE::MYWAVE() : SOUNDCLIP() { wave = nullptr; voice = -1; } - +#endif } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h index a9f75b8319a1..2e665d088da8 100644 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ b/engines/ags/engine/media/audio/clip_mywave.h @@ -26,6 +26,7 @@ #include "ags/engine/media/audio/soundclip.h" namespace AGS3 { +#ifdef DEPRECATED // My new MP3STREAM wrapper struct MYWAVE : public SOUNDCLIP { @@ -55,7 +56,7 @@ struct MYWAVE : public SOUNDCLIP { int get_voice() override; void adjust_volume() override; }; - +#endif } // namespace AGS3 #endif diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index 98134b945637..25dd52a42845 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -26,8 +26,6 @@ // //============================================================================= -//include // for toupper - #include "ags/shared/core/platform.h" #include "ags/shared/util/wgt2allg.h" #include "ags/engine/ac/file.h" @@ -35,22 +33,15 @@ #include "ags/engine/media/audio/sound.h" #include "ags/engine/media/audio/audiointernaldefs.h" #include "ags/engine/media/audio/clip_mywave.h" -#ifndef NO_MP3_PLAYER -#include "ags/engine/media/audio/clip_mymp3.h" -#include "ags/engine/media/audio/clip_mystaticmp3.h" -#endif -#include "ags/engine/media/audio/clip_myogg.h" -#include "ags/engine/media/audio/clip_mystaticogg.h" -#include "ags/engine/media/audio/clip_mymidi.h" -#ifdef JGMOD_MOD_PLAYER -#include "ags/engine/media/audio/clip_myjgmod.h" -#endif -#ifdef DUMB_MOD_PLAYER -#include "ags/engine/media/audio/clip_mydumbmod.h" -#endif #include "ags/engine/media/audio/soundcache.h" +#include "ags/engine/media/audio/clip_mymidi.h" #include "ags/engine/util/mutex_lock.h" #include "ags/ags.h" +#include "common/memstream.h" +#include "audio/mods/mod_xm_s3m.h" +#include "audio/decoders/mp3.h" +#include "audio/decoders/vorbis.h" +#include "audio/decoders/wave.h" namespace AGS3 { @@ -62,294 +53,71 @@ namespace AGS3 { #error Either JGMOD_MOD_PLAYER or DUMB_MOD_PLAYER should be defined. #endif -// Load MIDI from PACKFILE stream -extern MIDI *load_midi_pf(PACKFILE *pf); - - int use_extra_sound_offset = 0; - -MYWAVE *thiswave; SOUNDCLIP *my_load_wave(const AssetPath &asset_name, int voll, int loop) { - // Load via soundcache. - size_t dummy; - SAMPLE *new_sample = (SAMPLE *)get_cached_sound(asset_name, true, dummy); - - if (new_sample == nullptr) - return nullptr; - - thiswave = new MYWAVE(); - thiswave->wave = new_sample; - thiswave->vol = voll; - thiswave->repeat = (loop != 0); - - return thiswave; -} - -PACKFILE *mp3in; - -#ifndef NO_MP3_PLAYER - -MYMP3 *thistune; - -SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) { - size_t asset_size; - mp3in = PackfileFromAsset(asset_name, asset_size); - if (mp3in == nullptr) - return nullptr; - - char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); - if (tmpbuffer == nullptr) { - pack_fclose(mp3in); + Common::SeekableReadStream *data = get_cached_sound(asset_name); + if (data) { + Audio::AudioStream *audioStream = Audio::makeWAVStream(data, DisposeAfterUse::YES); + return new SoundClipWave(audioStream, voll, loop); + } else { return nullptr; } - thistune = new MYMP3(); - thistune->in = mp3in; - thistune->chunksize = MP3CHUNKSIZE; - thistune->filesize = asset_size; - thistune->vol = voll; - - if (thistune->chunksize > (int)thistune->filesize) - thistune->chunksize = thistune->filesize; - - pack_fread(tmpbuffer, thistune->chunksize, mp3in); - - thistune->buffer = (char *)tmpbuffer; - - { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - thistune->stream = almp3_create_mp3stream(tmpbuffer, thistune->chunksize, (thistune->filesize < 1)); - } - - if (thistune->stream == nullptr) { - free(tmpbuffer); - pack_fclose(mp3in); - delete thistune; - return nullptr; - } - - return thistune; } - - -MYSTATICMP3 *thismp3; SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) { - // Load via soundcache. - size_t muslen = 0; - char *mp3buffer = get_cached_sound(asset_name, false, muslen); - if (mp3buffer == nullptr) - return nullptr; - - // now, create an MP3 structure for it - thismp3 = new MYSTATICMP3(); - if (thismp3 == nullptr) { - free(mp3buffer); - return nullptr; - } - thismp3->vol = voll; - thismp3->mp3buffer = nullptr; - thismp3->repeat = loop; - - { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - thismp3->tune = almp3_create_mp3(mp3buffer, muslen); - } - - if (thismp3->tune == nullptr) { - free(mp3buffer); - delete thismp3; + Common::SeekableReadStream *data = get_cached_sound(asset_name); + if (data) { + Audio::AudioStream *audioStream = Audio::makeMP3Stream(data, DisposeAfterUse::YES); + return new SoundClipWave(audioStream, voll, false); + } else { return nullptr; } - - thismp3->mp3buffer = mp3buffer; - - return thismp3; } -#else // NO_MP3_PLAYER - SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll) { - return NULL; -} - -SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop) { - return NULL; + return my_load_static_mp3(asset_name, voll, false); } -#endif // NO_MP3_PLAYER - - - -MYSTATICOGG *thissogg; SOUNDCLIP *my_load_static_ogg(const AssetPath &asset_name, int voll, bool loop) { - // Load via soundcache. - size_t muslen = 0; - char *mp3buffer = get_cached_sound(asset_name, false, muslen); - if (mp3buffer == nullptr) - return nullptr; - - // now, create an OGG structure for it - thissogg = new MYSTATICOGG(); - thissogg->vol = voll; - thissogg->repeat = loop; - thissogg->mp3buffer = mp3buffer; - thissogg->mp3buffersize = muslen; - - thissogg->tune = alogg_create_ogg_from_buffer(mp3buffer, muslen); - - if (thissogg->tune == nullptr) { - thissogg->destroy(); - delete thissogg; + Common::SeekableReadStream *data = get_cached_sound(asset_name); + if (data) { + Audio::AudioStream *audioStream = Audio::makeVorbisStream(data, DisposeAfterUse::YES); + return new SoundClipWave(audioStream, voll, loop); + } else { return nullptr; } - - return thissogg; } -MYOGG *thisogg; SOUNDCLIP *my_load_ogg(const AssetPath &asset_name, int voll) { - size_t asset_size; - mp3in = PackfileFromAsset(asset_name, asset_size); - if (mp3in == nullptr) - return nullptr; - - char *tmpbuffer = (char *)malloc(MP3CHUNKSIZE); - if (tmpbuffer == nullptr) { - pack_fclose(mp3in); - return nullptr; - } - - thisogg = new MYOGG(); - thisogg->in = mp3in; - thisogg->vol = voll; - thisogg->chunksize = MP3CHUNKSIZE; - thisogg->last_but_one = 0; - thisogg->last_ms_offs = 0; - thisogg->last_but_one_but_one = 0; - - if (thisogg->chunksize > (int)asset_size) - thisogg->chunksize = asset_size; - - pack_fread(tmpbuffer, thisogg->chunksize, mp3in); - - thisogg->buffer = (char *)tmpbuffer; - thisogg->stream = alogg_create_oggstream(tmpbuffer, thisogg->chunksize, (asset_size < 1)); - - if (thisogg->stream == nullptr) { - free(tmpbuffer); - pack_fclose(mp3in); - delete thisogg; - return nullptr; - } - - return thisogg; + return my_load_static_ogg(asset_name, voll, false); } - - -MYMIDI *thismidi; -SOUNDCLIP *my_load_midi(const AssetPath &asset_name, int repet) { - // The first a midi is played, preload all patches. - if (!thismidi && psp_midi_preload_patches) - load_midi_patches(); - - size_t asset_size; - PACKFILE *pf = PackfileFromAsset(asset_name, asset_size); - if (!pf) +SOUNDCLIP *my_load_midi(const AssetPath &asset_name, bool repeat) { + Common::SeekableReadStream *data = get_cached_sound(asset_name); + if (data) { + return new MYMIDI(data, repeat); + } else { return nullptr; - - MIDI *midiPtr = load_midi_pf(pf); - pack_fclose(pf); - - if (midiPtr == nullptr) - return nullptr; - - thismidi = new MYMIDI(); - thismidi->tune = midiPtr; - thismidi->repeat = (repet != 0); - - return thismidi; -} - - -#ifdef JGMOD_MOD_PLAYER - -MYMOD *thismod = NULL; -SOUNDCLIP *my_load_mod(const char *filname, int repet) { - - JGMOD *modPtr = load_mod((char *)filname); - if (modPtr == NULL) - return NULL; - - thismod = new MYMOD(); - thismod->tune = modPtr; - thismod->repeat = (repet != 0); - - return thismod; -} - -int init_mod_player(int numVoices) { - return install_mod(numVoices); -} - -void remove_mod_player() { - remove_mod(); + } } -//#endif // JGMOD_MOD_PLAYER -#elif defined DUMB_MOD_PLAYER - -MYMOD *thismod = nullptr; -SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet) { - size_t asset_size; - DUMBFILE *df = DUMBfileFromAsset(asset_name, asset_size); - if (!df) - return nullptr; - - DUH *modPtr = nullptr; - // determine the file extension - const char *lastDot = strrchr(asset_name.second, '.'); - if (lastDot == nullptr) { - dumbfile_close(df); +SOUNDCLIP *my_load_mod(const AssetPath &asset_name, bool repeat) { + Common::SeekableReadStream *data = get_cached_sound(asset_name); + if (data) { + Audio::AudioStream *audioStream = Audio::makeModXmS3mStream(data, DisposeAfterUse::YES); + return new SoundClipWave(audioStream, 255, repeat); + } else { return nullptr; } - // get the first char of the extensin - int charAfterDot = toupper(lastDot[1]); - - // use the appropriate loader - if (charAfterDot == 'I') { - modPtr = dumb_read_it(df); - } else if (charAfterDot == 'X') { - modPtr = dumb_read_xm(df); - } else if (charAfterDot == 'S') { - modPtr = dumb_read_s3m(df); - } else if (charAfterDot == 'M') { - modPtr = dumb_read_mod(df); - } - - dumbfile_close(df); - if (modPtr == nullptr) - return nullptr; - - thismod = new MYMOD(); - thismod->tune = modPtr; - thismod->vol = 255; - thismod->repeat = (repet != 0); - - return thismod; } int init_mod_player(int numVoices) { - dumb_register_packfiles(); return 0; } void remove_mod_player() { - dumb_exit(); } } // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/sound.h b/engines/ags/engine/media/audio/sound.h index d5d5ea7e357e..c8ccdde425f0 100644 --- a/engines/ags/engine/media/audio/sound.h +++ b/engines/ags/engine/media/audio/sound.h @@ -39,8 +39,8 @@ SOUNDCLIP *my_load_mp3(const AssetPath &asset_name, int voll); SOUNDCLIP *my_load_static_mp3(const AssetPath &asset_name, int voll, bool loop); SOUNDCLIP *my_load_static_ogg(const AssetPath &asset_name, int voll, bool loop); SOUNDCLIP *my_load_ogg(const AssetPath &asset_name, int voll); -SOUNDCLIP *my_load_midi(const AssetPath &asset_name, int repet); -SOUNDCLIP *my_load_mod(const AssetPath &asset_name, int repet); +SOUNDCLIP *my_load_midi(const AssetPath &asset_name, bool repeat); +SOUNDCLIP *my_load_mod(const AssetPath &asset_name, bool repeat); extern int use_extra_sound_offset; diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index 84865d61a3eb..45fce16f10dd 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -20,8 +20,6 @@ * */ -//include -//include #include "ags/engine/ac/file.h" #include "ags/shared/util/wgt2allg.h" #include "ags/engine/media/audio/soundcache.h" @@ -31,6 +29,7 @@ #include "ags/shared/util/string.h" #include "ags/shared/debugging/out.h" #include "ags/ags.h" +#include "common/memstream.h" namespace AGS3 { @@ -208,7 +207,16 @@ char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) return sound_cache_entries[i].data; } +} + +Common::SeekableReadStream *get_cached_sound(const AssetPath &asset_name) { + size_t muslen = 0; + const byte *data = (byte *)get_cached_sound(asset_name, false, muslen); + if (data == nullptr) + return nullptr; + // Create a read stream for the sound + return new Common::MemoryReadStream(data, muslen, DisposeAfterUse::YES); } } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h index 932c207b8c8d..fa872e3b6560 100644 --- a/engines/ags/engine/media/audio/soundcache.h +++ b/engines/ags/engine/media/audio/soundcache.h @@ -24,6 +24,7 @@ #define AGS_ENGINE_MEDIA_AUDIO_SOUNDCACHE_H #include "ags/engine/ac/asset_helper.h" +#include "common/stream.h" namespace AGS3 { @@ -52,6 +53,7 @@ extern int psp_midi_preload_patches; void clear_sound_cache(); void sound_cache_free(char *buffer, bool is_wave); char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size); +Common::SeekableReadStream *get_cached_sound(const AssetPath &asset_name); } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index c7b54cc83ab1..40a7b741f5ca 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -20,77 +20,121 @@ * */ -#include "ags/shared/util/wgt2allg.h" -#include "ags/engine/media/audio/audio.h" -#include "ags/engine/media/audio/audiodefines.h" #include "ags/engine/media/audio/soundclip.h" -#include "ags/engine/media/audio/audiointernaldefs.h" +#include "ags/ags.h" namespace AGS3 { +SOUNDCLIP::SOUNDCLIP() : _state(SoundClipInitial), _panning(128), _panningAsPercentage(0), + _sourceClip(nullptr), _sourceClipType(0), _speed(1000), _priority(50), + _xSource(-1), _ySource(-1), _maximumPossibleDistanceAway(0), + _volAsPercentage(100), _vol(0), _volModifier(0) { + _mixer = ::AGS::g_vm->_mixer; +} + +void SOUNDCLIP::poll() { + bool playing = is_playing(); + if (playing) + _state = SoundClipPlaying; + else if (_state == SoundClipPlaying) + _state = SoundClipStopped; +} + +SOUNDCLIP::~SOUNDCLIP() { + destroy(); +} + +void SOUNDCLIP::set_speed(int new_speed) { + warning("TODO: SOUNDCLIP::set_speed"); + _speed = new_speed; +} + +void SOUNDCLIP::adjust_volume() { + // TODO: See if this method is needed +} + int SOUNDCLIP::play_from(int position) { - int retVal = play(); - if ((retVal != 0) && (position > 0)) { - seek(position); + // TODO: Implement playing from arbitrary positions + if (position == 0) { + play(); + return 1; + } else { + return 0; } - return retVal; } -void SOUNDCLIP::set_panning(int newPanning) { - if (!is_playing()) { - return; - } - int voice = get_voice(); - if (voice >= 0) { - voice_set_pan(voice, newPanning); - panning = newPanning; +/*------------------------------------------------------------------*/ + +SoundClipWaveBase::SoundClipWaveBase(Audio::AudioStream *stream, int volume, bool repeat) : + SOUNDCLIP(), _stream(stream) { + _mixer = ::AGS::g_vm->_mixer; + + if (repeat) { + Audio::SeekableAudioStream *str = dynamic_cast(stream); + assert(str); + _stream = new Audio::LoopingAudioStream(str, 0); } } -void SOUNDCLIP::pause() { - if (state_ != SoundClipPlaying) { - return; - } +void SoundClipWaveBase::destroy() { + stop(); + delete _stream; + _stream = nullptr; +} - int voice = get_voice(); - if (voice >= 0) { - voice_stop(voice); - state_ = SoundClipPaused; - } +int SoundClipWaveBase::play() { + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _stream, + -1, 255, 0, DisposeAfterUse::NO); + return 1; } -void SOUNDCLIP::resume() { - if (state_ != SoundClipPaused) { - return; - } +void SoundClipWaveBase::stop() { + _mixer->stopHandle(_soundHandle); +} - int voice = get_voice(); - if (voice >= 0) { - voice_start(voice); - state_ = SoundClipPlaying; - } +void SoundClipWaveBase::pause() { + _mixer->pauseHandle(_soundHandle, false); + _state = SoundClipPaused; +} + +void SoundClipWaveBase::resume() { + _mixer->pauseHandle(_soundHandle, false); + _state = SoundClipPlaying; + poll(); +} + +bool SoundClipWaveBase::is_playing() const { + return _mixer->isSoundHandleActive(_soundHandle); +} + +void SoundClipWaveBase::seek(int offset) { + warning("TODO: SoundClipWaveBase::seek"); +} + +int SoundClipWaveBase::get_pos() { + return _mixer->getSoundElapsedTime(_soundHandle) / 1000; } -SOUNDCLIP::SOUNDCLIP() { - state_ = SoundClipInitial; - priority = 50; - panning = 128; - panningAsPercentage = 0; - speed = 1000; - sourceClipType = 0; - sourceClip = nullptr; - vol = 0; - volAsPercentage = 0; - volModifier = 0; - muted = false; - repeat = false; - xSource = -1; - ySource = -1; - maximumPossibleDistanceAway = 0; - directionalVolModifier = 0; -} - -SOUNDCLIP::~SOUNDCLIP() = default; +int SoundClipWaveBase::get_pos_ms() { + return _mixer->getSoundElapsedTime(_soundHandle); +} + +int SoundClipWaveBase::get_length_ms() { + warning("TODO: SoundClipWaveBase::get_length_ms"); + return 0; +} + +int SoundClipWaveBase::get_volume() const { + return _mixer->getChannelVolume(_soundHandle); +} + +void SoundClipWaveBase::set_volume(int volume) { + _mixer->setChannelVolume(_soundHandle, volume); +} + +void SoundClipWaveBase::set_panning(int newPanning) { + _mixer->setChannelBalance(_soundHandle, newPanning); +} } // namespace AGS3 diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index d7d89767e7ae..3476a248c07b 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -30,6 +30,9 @@ #define AGS_ENGINE_MEDIA_AUDIO_SOUNDCLIP_H #include "ags/engine/util/mutex.h" +#include "audio/mixer.h" +#include "audio/audiostream.h" +#include "common/stream.h" namespace AGS3 { @@ -47,76 +50,66 @@ enum SoundClipState { }; struct SOUNDCLIP { - int priority; - int sourceClipType; - // absolute volume, set by implementations only! - int vol; - // current relative volume, in percents - int volAsPercentage; - // volModifier is used when there's a need to temporarily change and - // the restore the clip's absolute volume (vol) - int volModifier; - int panning; - int panningAsPercentage; - int xSource, ySource; - int maximumPossibleDistanceAway; - int directionalVolModifier; - bool repeat; - void *sourceClip; - - virtual void poll() = 0; - virtual void destroy() = 0; - // apply volume directly to playback; volume is given in units of 255 - // NOTE: this completely ignores volAsPercentage and muted property - virtual void set_volume(int) = 0; - virtual void seek(int) = 0; - virtual int get_pos() = 0; // return 0 to indicate seek not supported - virtual int get_pos_ms() = 0; // this must always return valid value if poss - virtual int get_length_ms() = 0; // return total track length in ms (or 0) - virtual int get_sound_type() = 0; - virtual int play() = 0; - - virtual int play_from(int position); - - virtual void set_panning(int newPanning); - virtual void set_speed(int new_speed) { - speed = new_speed; - } - - virtual void pause(); - virtual void resume(); - - inline bool is_playing() const { - return state_ == SoundClipPlaying || state_ == SoundClipPaused; - } - - inline int get_speed() const { - return speed; - } + Audio::Mixer *_mixer; + SoundClipState _state; + int _panning; + int _panningAsPercentage; + void *_sourceClip; // Pointer to source object that spawned the clip + int _sourceClipType; + int _speed; + int _xSource, _ySource; // Used for positioning sounds in game rooms + int _maximumPossibleDistanceAway; + int _priority; + bool _muted; + int _volAsPercentage; + int _vol; + int _volModifier; - // Gets clip's volume property, as percentage (0 - 100); - // note this may not be the real volume of playback (which could e.g. be muted) - inline int get_volume() const { - return volAsPercentage; - } - - inline bool is_muted() const { - return muted; - } + SOUNDCLIP(); + virtual ~SOUNDCLIP(); + virtual void destroy() {} + virtual int play() = 0; + virtual void stop() = 0; + virtual void pause() = 0; + virtual void resume() = 0; + virtual bool is_playing() const = 0; + virtual void seek(int offset) = 0; + virtual int get_pos() = 0; + virtual int get_pos_ms() = 0; + virtual int get_length_ms() = 0; // return total track length in ms (or 0) + virtual int get_sound_type() const = 0; + virtual int get_volume() const = 0; + virtual void set_volume(int volume) = 0; + virtual void set_panning(int newPanning) = 0; + inline int get_speed() const { return _speed; } + virtual void set_speed(int new_speed); + + void poll(); // Sets the current volume property, as percentage (0 - 100). inline void set_volume_percent(int volume) { - volAsPercentage = volume; - if (!muted) - set_volume((volume * 255) / 100); + set_volume((volume * 255) / 100); + } + void adjust_volume(); + int play_from(int position); + + /** + * Apply permanent directional volume modifier, in absolute units (0 - 255) + * this is distinct value that is used in conjunction with current volume + * (can be both positive and negative). + */ + inline void apply_directional_modifier(int mod) { + warning("TODO: SOUNDCLIP::apply_directional_modifier"); } - // Explicitly defines both percentage and absolute volume value, - // without calculating it from given percentage. - // NOTE: this overrides the mute + /** + * Explicitly defines both percentage and absolute volume value, + * without calculating it from given percentage. + * NOTE: this overrides the mute + */ inline void set_volume_direct(int vol_percent, int vol_absolute) { - muted = false; - volAsPercentage = vol_percent; + _muted = false; + _volAsPercentage = vol_percent; set_volume(vol_absolute); } @@ -124,27 +117,35 @@ struct SOUNDCLIP { // for the future reference; when unmuted, that property is // used to restart previous volume. inline void set_mute(bool enable) { - muted = enable; + _muted = enable; if (enable) set_volume(0); else - set_volume((volAsPercentage * 255) / 100); + set_volume((_volAsPercentage * 255) / 100); } // Apply arbitrary permanent volume modifier, in absolute units (0 - 255); // this is distinct value that is used in conjunction with current volume // (can be both positive and negative). inline void apply_volume_modifier(int mod) { - volModifier = mod; + _volModifier = mod; adjust_volume(); } - // Apply permanent directional volume modifier, in absolute units (0 - 255) - // this is distinct value that is used in conjunction with current volume - // (can be both positive and negative). - inline void apply_directional_modifier(int mod) { - directionalVolModifier = mod; - adjust_volume(); + /* + inline bool is_playing() const { + return state_ == SoundClipPlaying || state_ == SoundClipPaused; + } + + + // Gets clip's volume property, as percentage (0 - 100); + // note this may not be the real volume of playback (which could e.g. be muted) + inline int get_volume() const { + return volAsPercentage; + } + + inline bool is_muted() const { + return muted; } virtual void adjust_volume() = 0; @@ -173,6 +174,36 @@ struct SOUNDCLIP { int final_vol = vol + volModifier + directionalVolModifier; return final_vol >= 0 ? final_vol : 0; } + */ +}; + +struct SoundClipWaveBase : public SOUNDCLIP { + Audio::AudioStream *_stream; + Audio::SoundHandle _soundHandle; + + SoundClipWaveBase(Audio::AudioStream *stream, int volume, bool repeat = false); + ~SoundClipWaveBase() override {} + + void destroy() override; + int play() override; + void stop() override; + void pause() override; + void resume() override; + bool is_playing() const override; + void seek(int offset) override; + int get_pos() override; + int get_pos_ms() override; + int get_length_ms() override; + int get_volume() const override; + void set_volume(int volume) override; + void set_panning(int newPanning) override; +}; + +template +struct SoundClipWave : public SoundClipWaveBase { + SoundClipWave(Audio::AudioStream *stream, int volume, bool repeat = false) : + SoundClipWaveBase(stream, volume, repeat) {} + int get_sound_type() const { return SOUND_TYPE; } }; } // namespace AGS3 diff --git a/engines/ags/lib/audio/midi.cpp b/engines/ags/lib/audio/midi.cpp index 503b3b14b7ec..ca475da20a82 100644 --- a/engines/ags/lib/audio/midi.cpp +++ b/engines/ags/lib/audio/midi.cpp @@ -48,61 +48,9 @@ int detect_midi_driver(int driver_id) { return 16; } - -void stop_midi() { - ::AGS::g_music->stop(); -} - -void destroy_midi(MIDI *midi) { - delete midi; -} - -int play_midi(MIDI *tune, bool repeat) { - ::AGS::g_music->playMusic(tune, repeat); - return 0; -} - -size_t get_midi_length(MIDI *tune) { - warning("TODO: get_midi_length"); - return 0; -} - -void midi_seek(int target) { - ::AGS::g_music->seek(target); -} - -void midi_pause() { - ::AGS::g_music->pause(); -} - -void midi_resume() { - ::AGS::g_music->resume(); -} - int load_midi_patches() { warning("TODO: load_midi_patches"); return 0; } -#define MIDI_BLOCK_SIZE 32768 - -MIDI *load_midi_pf(PACKFILE *fp) { - MIDI *midi = new MIDI(); - int bytesRead; - - // Iterate through loading blocks of MIDI data - for (;;) { - size_t priorSize = midi->size(); - midi->resize(priorSize + MIDI_BLOCK_SIZE); - bytesRead = pack_fread(&(*midi)[priorSize], MIDI_BLOCK_SIZE, fp); - - if (bytesRead < MIDI_BLOCK_SIZE) { - midi->resize(priorSize + bytesRead); - break; - } - } - - return midi; -} - } // namespace AGS3 diff --git a/engines/ags/lib/audio/midi.h b/engines/ags/lib/audio/midi.h index 376f8b919c20..6bf59bedd0bf 100644 --- a/engines/ags/lib/audio/midi.h +++ b/engines/ags/lib/audio/midi.h @@ -37,8 +37,6 @@ namespace AGS3 { AL_ARRAY(_DRIVER_INFO, _midi_driver_list); -using MIDI = ::AGS::MIDI; - /* macros for constructing the driver lists */ #define BEGIN_MIDI_DRIVER_LIST \ _DRIVER_INFO _midi_driver_list[] = \ @@ -64,15 +62,7 @@ AL_VAR(long, midi_loop_end); /* loop when we hit this position */ AL_FUNC(int, detect_midi_driver, (int driver_id)); - -extern void stop_midi(); -extern void destroy_midi(MIDI *tune); -extern int play_midi(MIDI *tune, bool repeat); -extern size_t get_midi_length(MIDI *tune); -extern void midi_seek(int target); -extern void midi_pause(); -extern void midi_resume(); -extern int load_midi_patches(); +AL_FUNC(int, load_midi_patches, ()); } // namespace AGS3 diff --git a/engines/ags/lib/audio/ogg.cpp b/engines/ags/lib/audio/ogg.cpp index 60860b3df9a5..3fd8dd0b38f8 100644 --- a/engines/ags/lib/audio/ogg.cpp +++ b/engines/ags/lib/audio/ogg.cpp @@ -25,7 +25,7 @@ #include "ags/ags.h" namespace AGS3 { - +#ifdef DEPRECATED ALOGG_OGG *alogg_create_ogg_from_buffer(void *data, int data_len) { warning("TODO: alogg_create_ogg_from_buffer"); return nullptr; @@ -142,5 +142,5 @@ int alogg_get_pos_msecs_oggstream(ALOGG_OGGSTREAM *ogg) { warning("TODO: alogg_get_pos_msecs_oggstream"); return 0; } - +#endif } // namespace AGS3 diff --git a/engines/ags/lib/audio/ogg.h b/engines/ags/lib/audio/ogg.h index b967cb53f97b..79142086ce1e 100644 --- a/engines/ags/lib/audio/ogg.h +++ b/engines/ags/lib/audio/ogg.h @@ -27,7 +27,7 @@ #include "audio/mixer.h" namespace AGS3 { - +#ifdef DEPRECATED #define ALOGG_OK 0 #define ALOGG_PLAY_BUFFERTOOSMALL -1 @@ -70,7 +70,7 @@ extern bool alogg_is_playing_oggstream(ALOGG_OGGSTREAM *ogg); extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); extern AUDIOSTREAM *alogg_get_audiostream_oggstream(ALOGG_OGGSTREAM *ogg); extern int alogg_get_pos_msecs_oggstream(ALOGG_OGGSTREAM *ogg); - +#endif } // namespace AGS3 #endif diff --git a/engines/ags/music.cpp b/engines/ags/music.cpp index 191335d1e730..c0f49644cf97 100644 --- a/engines/ags/music.cpp +++ b/engines/ags/music.cpp @@ -21,6 +21,8 @@ */ #include "ags/music.h" +#include "ags/engine/main/main.h" +#include "ags/lib/audio/midi.h" #include "audio/midiparser.h" namespace AGS { @@ -28,7 +30,7 @@ namespace AGS { Music *g_music; Music::Music(Audio::Mixer *mixer) : - Audio::MidiPlayer(), _mixer(mixer) { + Audio::MidiPlayer(), _mixer(mixer), _isFirstTime(true) { g_music = this; Audio::MidiPlayer::createDriver(); @@ -61,14 +63,20 @@ void Music::sendToChannel(byte channel, uint32 b) { _channelsTable[channel]->send(b); } -void Music::playMusic(const MIDI *midi, bool repeat) { +void Music::playMusic(Common::SeekableReadStream *midi, bool repeat) { + if (_isFirstTime) { + if (::AGS3::psp_midi_preload_patches) + ::AGS3::load_midi_patches(); + _isFirstTime = false; + } + stop(); // Load MIDI resource data int midiMusicSize = midi->size(); _midiData.resize(midi->size()); - Common::copy(&(*midi)[0], &(*midi)[0] + midi->size(), &_midiData[0]); + midi->read(&_midiData[0], midi->size()); MidiParser *parser = MidiParser::createParser_SMF(); if (parser->loadMusic(&_midiData[0], midiMusicSize)) { diff --git a/engines/ags/music.h b/engines/ags/music.h index 6b6f09b569d3..2ea8f8166292 100644 --- a/engines/ags/music.h +++ b/engines/ags/music.h @@ -30,14 +30,12 @@ namespace AGS { -// A MIDI file -typedef Common::Array MIDI; - class Music : public Audio::MidiPlayer { private: Audio::Mixer *_mixer; Audio::SoundHandle _soundHandle; Common::Array _midiData; + bool _isFirstTime; protected: // Overload Audio::MidiPlayer method void sendToChannel(byte channel, uint32 b) override; @@ -48,7 +46,7 @@ class Music : public Audio::MidiPlayer { /** * Play music */ - void playMusic(const MIDI *midi, bool repeat = false); + void playMusic(Common::SeekableReadStream *midi, bool repeat = false); /** * Seek within the MIDI From d67e09791c1ea347a11c0082aa23be1ef2af282c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 Jan 2021 19:52:24 -0800 Subject: [PATCH 122/215] AGS: Remove deprecated audio classes --- .../ags/engine/media/audio/clip_mydumbmod.cpp | 185 ---------------- .../ags/engine/media/audio/clip_mydumbmod.h | 81 ------- engines/ags/engine/media/audio/clip_mymp3.cpp | 189 ---------------- engines/ags/engine/media/audio/clip_mymp3.h | 61 ------ engines/ags/engine/media/audio/clip_myogg.cpp | 206 ------------------ engines/ags/engine/media/audio/clip_myogg.h | 73 ------- .../engine/media/audio/clip_mystaticmp3.cpp | 166 -------------- .../ags/engine/media/audio/clip_mystaticmp3.h | 67 ------ .../engine/media/audio/clip_mystaticogg.cpp | 31 --- .../ags/engine/media/audio/clip_mystaticogg.h | 43 ---- .../ags/engine/media/audio/clip_mywave.cpp | 136 ------------ engines/ags/engine/media/audio/clip_mywave.h | 62 ------ engines/ags/engine/media/audio/sound.cpp | 1 - engines/ags/engine/plugin/agsplugin.cpp | 2 +- engines/ags/lib/audio/midi.cpp | 8 - engines/ags/lib/audio/midi.h | 3 - engines/ags/lib/audio/mp3.cpp | 122 ----------- engines/ags/lib/audio/mp3.h | 64 ------ engines/ags/lib/audio/ogg.cpp | 146 ------------- engines/ags/lib/audio/ogg.h | 76 ------- engines/ags/lib/audio/wav.cpp | 31 --- engines/ags/lib/audio/wav.h | 34 --- engines/ags/module.mk | 10 - 23 files changed, 1 insertion(+), 1796 deletions(-) delete mode 100644 engines/ags/engine/media/audio/clip_mydumbmod.cpp delete mode 100644 engines/ags/engine/media/audio/clip_mydumbmod.h delete mode 100644 engines/ags/engine/media/audio/clip_mymp3.cpp delete mode 100644 engines/ags/engine/media/audio/clip_mymp3.h delete mode 100644 engines/ags/engine/media/audio/clip_myogg.cpp delete mode 100644 engines/ags/engine/media/audio/clip_myogg.h delete mode 100644 engines/ags/engine/media/audio/clip_mystaticmp3.cpp delete mode 100644 engines/ags/engine/media/audio/clip_mystaticmp3.h delete mode 100644 engines/ags/engine/media/audio/clip_mystaticogg.cpp delete mode 100644 engines/ags/engine/media/audio/clip_mystaticogg.h delete mode 100644 engines/ags/engine/media/audio/clip_mywave.cpp delete mode 100644 engines/ags/engine/media/audio/clip_mywave.h delete mode 100644 engines/ags/lib/audio/mp3.cpp delete mode 100644 engines/ags/lib/audio/mp3.h delete mode 100644 engines/ags/lib/audio/ogg.cpp delete mode 100644 engines/ags/lib/audio/ogg.h delete mode 100644 engines/ags/lib/audio/wav.cpp delete mode 100644 engines/ags/lib/audio/wav.h diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.cpp b/engines/ags/engine/media/audio/clip_mydumbmod.cpp deleted file mode 100644 index ae0921b1fa29..000000000000 --- a/engines/ags/engine/media/audio/clip_mydumbmod.cpp +++ /dev/null @@ -1,185 +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. - * - */ - -#include "ags/engine/media/audio/audiodefines.h" - -#ifdef DUMB_MOD_PLAYER - -#include "ags/engine/media/audio/clip_mydumbmod.h" -#include "ags/engine/media/audio/audiointernaldefs.h" - -namespace AGS3 { -#ifdef DEPRECATED - -void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop) { - DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(dp); - DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); - if (itsr == nullptr) - return; - - if (loop) - dumb_it_set_loop_callback(itsr, nullptr, nullptr); - else - dumb_it_set_loop_callback(itsr, dumb_it_callback_terminate, itsr); -} - -void MYMOD::poll() { - if (state_ != SoundClipPlaying) { - return; - } - - if (al_poll_duh(duhPlayer)) { - state_ = SoundClipStopped; - } -} - -void MYMOD::adjust_volume() { - if (!is_playing()) { - return; - } - al_duh_set_volume(duhPlayer, VOLUME_TO_DUMB_VOL(get_final_volume())); -} - -void MYMOD::set_volume(int newvol) { - vol = newvol; - adjust_volume(); -} - -void MYMOD::destroy() { - if (duhPlayer) { - al_stop_duh(duhPlayer); - } - duhPlayer = nullptr; - - if (tune) { - unload_duh(tune); - } - tune = nullptr; - - state_ = SoundClipStopped; -} - -void MYMOD::seek(int patnum) { - if (!is_playing()) { - return; - } - - al_stop_duh(duhPlayer); - state_ = SoundClipInitial; - - DUH_SIGRENDERER *sr = dumb_it_start_at_order(tune, 2, patnum); - duhPlayer = al_duh_encapsulate_sigrenderer(sr, VOLUME_TO_DUMB_VOL(vol), 8192, 22050); - if (!duhPlayer) { - duh_end_sigrenderer(sr); - return; - } - - al_duh_set_loop(duhPlayer, repeat); - state_ = SoundClipPlaying; -} - -int MYMOD::get_pos() { - if (!is_playing()) { - return -1; - } - - // determine the current track number (DUMB calls them 'orders') - DUH_SIGRENDERER *sr = al_duh_get_sigrenderer(duhPlayer); - DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(sr); - if (itsr == nullptr) - return -1; - - return dumb_it_sr_get_current_order(itsr); -} - -int MYMOD::get_real_mod_pos() { - if (!is_playing()) { - return -1; - } - return al_duh_get_position(duhPlayer); -} - -int MYMOD::get_pos_ms() { - if (!is_playing()) { - return -1; - } - return (get_real_mod_pos() * 10) / 655; -} - -int MYMOD::get_length_ms() { - if (tune == nullptr) - return 0; - - // duh_get_length represents time as 65536ths of a second - return (duh_get_length(tune) * 10) / 655; -} - -int MYMOD::get_voice() { - // MOD uses so many different voices it's not practical to keep track - return -1; -} - -void MYMOD::pause() { - if (state_ != SoundClipPlaying) { - return; - } - al_pause_duh(duhPlayer); - state_ = SoundClipPaused; -} - -void MYMOD::resume() { - if (state_ != SoundClipPaused) { - return; - } - al_resume_duh(duhPlayer); - state_ = SoundClipPlaying; -} - -int MYMOD::get_sound_type() { - return MUS_MOD; -} - -int MYMOD::play() { - if (tune == nullptr) { - return 0; - } - - duhPlayer = al_start_duh(tune, 2, 0, 1.0, 8192, 22050); - if (!duhPlayer) { - return 0; - } - al_duh_set_loop(duhPlayer, repeat); - set_volume(vol); - - state_ = SoundClipPlaying; - return 1; -} - -MYMOD::MYMOD() : SOUNDCLIP() { - tune = nullptr; - duhPlayer = nullptr; -} - -#endif -} // namespace AGS3 - -#endif // DUMB_MOD_PLAYER diff --git a/engines/ags/engine/media/audio/clip_mydumbmod.h b/engines/ags/engine/media/audio/clip_mydumbmod.h deleted file mode 100644 index ad98d49c2fb8..000000000000 --- a/engines/ags/engine/media/audio/clip_mydumbmod.h +++ /dev/null @@ -1,81 +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. - * - */ - -#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H -#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYDUMBMOD_H - -#include "ags/lib/audio/aldumb.h" -#include "ags/engine/media/audio/soundclip.h" - -namespace AGS3 { -#ifdef DEPRECATED - -#define VOLUME_TO_DUMB_VOL(vol) ((float)vol) / 256.0 - -extern void al_duh_set_loop(AL_DUH_PLAYER *dp, int loop); - -// MOD/XM (DUMB) -struct MYMOD : public SOUNDCLIP { - DUH *tune; - AL_DUH_PLAYER *duhPlayer; - - void poll() override; - - void set_volume(int newvol) override; - - void destroy() override; - - void seek(int patnum) override; - - // NOTE: this implementation of the virtual function returns a MOD/XM - // "order" index, not actual playing position; - // this does not make much sense in the context of the interface itself, - // and, as it seems, was implemented so solely for the purpose of emulating - // deprecated "GetMODPattern" script function. - // (see Game_GetMODPattern(), and documentation for AudioChannel.Position property) - // TODO: find a way to redesign this behavior - int get_pos() override; - - int get_pos_ms() override; - - int get_length_ms() override; - - void pause() override; - - void resume() override; - - int get_sound_type() override; - - int play() override; - - MYMOD(); - -protected: - int get_voice() override; - void adjust_volume() override; - // Returns real MOD/XM playing position - int get_real_mod_pos(); -}; -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/clip_mymp3.cpp b/engines/ags/engine/media/audio/clip_mymp3.cpp deleted file mode 100644 index 28d1e0e70a97..000000000000 --- a/engines/ags/engine/media/audio/clip_mymp3.cpp +++ /dev/null @@ -1,189 +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. - * - */ - -#include "ags/engine/media/audio/audiodefines.h" - -#ifndef NO_MP3_PLAYER - -#include "ags/engine/media/audio/clip_mymp3.h" -#include "ags/engine/media/audio/audiointernaldefs.h" -#include "ags/shared/ac/common.h" // quit() -#include "ags/engine/ac/asset_helper.h" -#include "ags/engine/util/mutex_lock.h" -#include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/ags.h" - -namespace AGS3 { -#ifdef DEPRECATED - -void MYMP3::poll() { - if (state_ != SoundClipPlaying) { - return; - } -#if !AGS_PLATFORM_SCUMMVM - // update the buffer - char *tempbuf = nullptr; - { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - tempbuf = (char *)almp3_get_mp3stream_buffer(stream); - } - - if (tempbuf != nullptr) { - AGS_PACKFILE_OBJ *obj = (AGS_PACKFILE_OBJ *)in->userdata; - int free_val = -1; - if (chunksize >= obj->remains) { - chunksize = obj->remains; - free_val = chunksize; - } - pack_fread(tempbuf, chunksize, in); - - { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - almp3_free_mp3stream_buffer(stream, free_val); - } - } -#endif - { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - if (almp3_poll_mp3stream(stream) == ALMP3_POLL_PLAYJUSTFINISHED) { - state_ = SoundClipStopped; - } - } -} - -void MYMP3::adjust_stream() { - if (!is_playing()) { - return; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - almp3_adjust_mp3stream(stream, get_final_volume(), panning, speed); -} - -void MYMP3::adjust_volume() { - adjust_stream(); -} - -void MYMP3::set_volume(int newvol) { - // boost MP3 volume - newvol += 20; - if (newvol > 255) - newvol = 255; - - vol = newvol; - adjust_stream(); -} - -void MYMP3::set_speed(int new_speed) { - speed = new_speed; - adjust_stream(); -} - -void MYMP3::destroy() { - if (stream) { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - almp3_stop_mp3stream(stream); - almp3_destroy_mp3stream(stream); - } - stream = nullptr; - - if (buffer) - free(buffer); - buffer = nullptr; - - pack_fclose(in); - - state_ = SoundClipStopped; -} - -void MYMP3::seek(int pos) { - if (!is_playing()) { - return; - } - quit("Tried to seek an mp3stream"); -} - -int MYMP3::get_pos() { - return 0; // Return 0 to signify that Seek is not supported - // return almp3_get_pos_msecs_mp3stream (stream); -} - -int MYMP3::get_pos_ms() { - if (!is_playing()) { - return -1; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - return almp3_get_pos_msecs_mp3stream(stream); -} - -int MYMP3::get_length_ms() { - if (!is_playing()) { - return -1; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - return almp3_get_length_msecs_mp3stream(stream, filesize); -} - -int MYMP3::get_voice() { - if (!is_playing()) { - return -1; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - AUDIOSTREAM *ast = almp3_get_audiostream_mp3stream(stream); - return (ast != nullptr ? ast->voice : -1); -} - -int MYMP3::get_sound_type() { - return MUS_MP3; -} - -int MYMP3::play() { - if (in == nullptr) { - return 0; - } - - { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - if (almp3_play_mp3stream(stream, chunksize, (vol > 230) ? vol : vol + 20, panning) != ALMP3_OK) { - return 0; - } - } - - state_ = SoundClipPlaying; - - if (!psp_audio_multithreaded) - poll(); - - return 1; -} - -MYMP3::MYMP3() : SOUNDCLIP() { - stream = nullptr; - in = nullptr; - filesize = 0; - buffer = nullptr; - chunksize = 0; -} - -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/clip_mymp3.h b/engines/ags/engine/media/audio/clip_mymp3.h deleted file mode 100644 index a8c283454edf..000000000000 --- a/engines/ags/engine/media/audio/clip_mymp3.h +++ /dev/null @@ -1,61 +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. - * - */ - -#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H -#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYMP3_H - -#include "ags/lib/audio/mp3.h" -#include "ags/lib/allegro/file.h" -#include "ags/engine/media/audio/soundclip.h" - -namespace AGS3 { -#ifdef DEPRECATED - -struct MYMP3 : public SOUNDCLIP { - ALMP3_MP3STREAM *stream; - PACKFILE *in; - size_t filesize; - char *buffer; - int chunksize; - - void poll() override; - void set_volume(int newvol) override; - void set_speed(int new_speed) override; - void destroy() override; - void seek(int pos) override; - int get_pos() override; - int get_pos_ms() override; - int get_length_ms() override; - int get_sound_type() override; - int play() override; - MYMP3(); - -protected: - int get_voice() override; - void adjust_volume() override; -private: - void adjust_stream(); -}; -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/clip_myogg.cpp b/engines/ags/engine/media/audio/clip_myogg.cpp deleted file mode 100644 index cc52a6e223f0..000000000000 --- a/engines/ags/engine/media/audio/clip_myogg.cpp +++ /dev/null @@ -1,206 +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. - * - */ - -#include "ags/lib/audio/digi.h" -#include "ags/engine/media/audio/audiodefines.h" -#include "ags/engine/media/audio/clip_myogg.h" -#include "ags/engine/media/audio/audiointernaldefs.h" -#include "ags/shared/ac/common.h" // quit() -#include "ags/engine/ac/asset_helper.h" -#include "ags/engine/util/mutex_lock.h" - -#include "ags/engine/platform/base/agsplatformdriver.h" - -namespace AGS3 { -#ifdef DEPRECATED -void MYOGG::poll() { - if (state_ != SoundClipPlaying) { - return; - } -#if !AGS_PLATFORM_SCUMMVM - AGS_PACKFILE_OBJ *obj = (AGS_PACKFILE_OBJ *)in->userdata; - if (obj->remains > 0) { - // update the buffer - char *tempbuf = (char *)alogg_get_oggstream_buffer(stream); - if (tempbuf != nullptr) { - int free_val = -1; - if (chunksize >= obj->remains) { - chunksize = obj->remains; - free_val = chunksize; - } - pack_fread(tempbuf, chunksize, in); - alogg_free_oggstream_buffer(stream, free_val); - } - } -#endif - int ret = alogg_poll_oggstream(stream); - if (ret == ALOGG_OK || ret == ALOGG_POLL_BUFFERUNDERRUN) - get_pos_ms(); // call this to keep the last_but_one stuff up to date - else { - // finished playing or error - state_ = SoundClipStopped; - } -} - -void MYOGG::adjust_stream() { - if (!is_playing()) { - return; - } - alogg_adjust_oggstream(stream, get_final_volume(), panning, speed); -} - -void MYOGG::adjust_volume() { - adjust_stream(); -} - -void MYOGG::set_volume(int newvol) { - // boost MP3 volume - newvol += 20; - if (newvol > 255) - newvol = 255; - vol = newvol; - adjust_stream(); -} - -void MYOGG::set_speed(int new_speed) { - speed = new_speed; - adjust_stream(); -} - -void MYOGG::destroy() { - if (stream) { - alogg_stop_oggstream(stream); - alogg_destroy_oggstream(stream); - } - stream = nullptr; - - if (buffer) - free(buffer); - buffer = nullptr; - - pack_fclose(in); - - state_ = SoundClipStopped; -} - -void MYOGG::seek(int pos) { - if (!is_playing()) { - return; - } - quit("Attempted to seek an oggstream; operation not permitted"); -} - -int MYOGG::get_pos() { - return 0; -} - -int MYOGG::get_pos_ms() { - // Unfortunately the alogg_get_pos_msecs_oggstream function - // returns the ms offset that was last decoded, so it's always - // ahead of the actual playback. Therefore we have this - // hideous hack below to sort it out. - if ((!is_playing()) || (!alogg_is_playing_oggstream(stream))) - return 0; - - AUDIOSTREAM *str = alogg_get_audiostream_oggstream(stream); - long offs = (voice_get_position(str->voice) * 1000) / str->samp->freq; - - if (last_ms_offs != alogg_get_pos_msecs_oggstream(stream)) { - last_but_one_but_one = last_but_one; - last_but_one = last_ms_offs; - last_ms_offs = alogg_get_pos_msecs_oggstream(stream); - } - - // just about to switch buffers - if (offs < 0) - return last_but_one; - - int end_of_stream = alogg_is_end_of_oggstream(stream); - - if ((str->active == 1) && (last_but_one_but_one > 0) && (str->locked == nullptr)) { - switch (end_of_stream) { - case 0: - case 2: - offs -= (last_but_one - last_but_one_but_one); - break; - case 1: - offs -= (last_but_one - last_but_one_but_one); - break; - } - } - - if (end_of_stream == 1) { - - return offs + last_but_one; - } - - return offs + last_but_one_but_one; -} - -int MYOGG::get_length_ms() { - // streamed OGG is variable bitrate so we don't know - return 0; -} - -int MYOGG::get_voice() { - if (!is_playing()) { - return -1; - } - - AUDIOSTREAM *ast = alogg_get_audiostream_oggstream(stream); - if (ast) - return ast->voice; - return -1; -} - -int MYOGG::get_sound_type() { - return MUS_OGG; -} - -int MYOGG::play() { - if (in == nullptr) { - return 0; - } - - if (alogg_play_oggstream(stream, MP3CHUNKSIZE, (vol > 230) ? vol : vol + 20, panning) != ALOGG_OK) { - return 0; - } - - state_ = SoundClipPlaying; - - if (!psp_audio_multithreaded) - poll(); - - return 1; -} - -MYOGG::MYOGG() : SOUNDCLIP() { - stream = nullptr; - in = nullptr; - buffer = nullptr; - chunksize = 0; - last_but_one_but_one = 0; - last_but_one = 0; - last_ms_offs = 0; -} -#endif -} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_myogg.h b/engines/ags/engine/media/audio/clip_myogg.h deleted file mode 100644 index f619ec5a90fc..000000000000 --- a/engines/ags/engine/media/audio/clip_myogg.h +++ /dev/null @@ -1,73 +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. - * - */ - -#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H -#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYOGG_H - -#include "ags/lib/audio/ogg.h" -#include "ags/lib/allegro/file.h" -#include "ags/engine/media/audio/soundclip.h" - -namespace AGS3 { -#ifdef DEPRECATED -struct MYOGG : public SOUNDCLIP { - ALOGG_OGGSTREAM *stream; - PACKFILE *in; - char *buffer; - int chunksize; - - int last_but_one_but_one; - int last_but_one; - int last_ms_offs; - - void poll() override; - - void set_volume(int newvol) override; - void set_speed(int new_speed) override; - - void destroy() override; - - void seek(int pos) override; - - int get_pos() override; - - int get_pos_ms() override; - - int get_length_ms() override; - - int get_sound_type() override; - - int play() override; - - MYOGG(); - -protected: - int get_voice() override; - void adjust_volume() override; -private: - void adjust_stream(); -}; - -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp b/engines/ags/engine/media/audio/clip_mystaticmp3.cpp deleted file mode 100644 index 43c336d71348..000000000000 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.cpp +++ /dev/null @@ -1,166 +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. - * - */ - -#include "ags/engine/media/audio/audiodefines.h" - -#ifndef NO_MP3_PLAYER - -#include "ags/engine/media/audio/clip_mystaticmp3.h" -#include "ags/engine/media/audio/audiointernaldefs.h" -#include "ags/engine/media/audio/soundcache.h" -#include "ags/engine/util/mutex_lock.h" -#include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/ags.h" - -namespace AGS3 { -#ifdef DEPRECATED - -extern int our_eip; - -void MYSTATICMP3::poll() { - if (state_ != SoundClipPlaying) { - return; - } - - int oldeip = our_eip; - our_eip = 5997; - - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - int result = almp3_poll_mp3(tune); - - if (result == ALMP3_POLL_PLAYJUSTFINISHED) { - if (!repeat) { - state_ = SoundClipStopped; - } - } - our_eip = oldeip; -} - -void MYSTATICMP3::adjust_stream() { - if (!is_playing()) { - return; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - almp3_adjust_mp3(tune, get_final_volume(), panning, speed, repeat); -} - -void MYSTATICMP3::adjust_volume() { - adjust_stream(); -} - -void MYSTATICMP3::set_volume(int newvol) { - vol = newvol; - adjust_stream(); -} - -void MYSTATICMP3::set_speed(int new_speed) { - speed = new_speed; - adjust_stream(); -} - -void MYSTATICMP3::destroy() { - if (tune) { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - almp3_stop_mp3(tune); - almp3_destroy_mp3(tune); - } - tune = nullptr; - - if (mp3buffer) { - sound_cache_free(mp3buffer, false); - } - mp3buffer = nullptr; - - state_ = SoundClipStopped; -} - -void MYSTATICMP3::seek(int pos) { - if (!is_playing()) { - return; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - almp3_seek_abs_msecs_mp3(tune, pos); -} - -int MYSTATICMP3::get_pos() { - if (!is_playing()) { - return -1; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - return almp3_get_pos_msecs_mp3(tune); -} - -int MYSTATICMP3::get_pos_ms() { - int result = get_pos(); - return result; -} - -int MYSTATICMP3::get_length_ms() { - if (tune == nullptr) { - return -1; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - return almp3_get_length_msecs_mp3(tune); -} - -int MYSTATICMP3::get_voice() { - if (!is_playing()) { - return -1; - } - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - AUDIOSTREAM *ast = almp3_get_audiostream_mp3(tune); - return (ast != nullptr ? ast->voice : -1); -} - -int MYSTATICMP3::get_sound_type() { - return MUS_MP3; -} - -int MYSTATICMP3::play() { - if (tune == nullptr) { - return 0; - } - - { - AGS::Engine::MutexLock _lockMp3(::AGS::g_vm->_mp3Mutex); - int result = almp3_play_ex_mp3(tune, 16384, vol, panning, 1000, repeat); - if (result != ALMP3_OK) { - return 0; - } - } - - state_ = SoundClipPlaying; - - if (!psp_audio_multithreaded) - poll(); - - return 1; -} - -MYSTATICMP3::MYSTATICMP3() : SOUNDCLIP() { - tune = nullptr; - mp3buffer = nullptr; -} -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/clip_mystaticmp3.h b/engines/ags/engine/media/audio/clip_mystaticmp3.h deleted file mode 100644 index 6592ae8c1933..000000000000 --- a/engines/ags/engine/media/audio/clip_mystaticmp3.h +++ /dev/null @@ -1,67 +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. - * - */ - -#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H -#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICMP3_H - -#include "ags/lib/audio/mp3.h" -#include "ags/engine/media/audio/soundclip.h" - -namespace AGS3 { -#ifdef DEPRECATED -// pre-loaded (non-streaming) MP3 file -struct MYSTATICMP3 : public SOUNDCLIP { - ALMP3_MP3 *tune; - char *mp3buffer; - - void poll() override; - - void set_volume(int newvol) override; - void set_speed(int new_speed) override; - - void destroy() override; - - void seek(int pos) override; - - int get_pos() override; - - int get_pos_ms() override; - - int get_length_ms() override; - - int get_sound_type() override; - - int play() override; - - MYSTATICMP3(); - -protected: - int get_voice() override; - void adjust_volume() override; -private: - void adjust_stream(); -}; -#endif - -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.cpp b/engines/ags/engine/media/audio/clip_mystaticogg.cpp deleted file mode 100644 index 363bfa561775..000000000000 --- a/engines/ags/engine/media/audio/clip_mystaticogg.cpp +++ /dev/null @@ -1,31 +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. - * - */ - -#include "ags/engine/media/audio/clip_mystaticogg.h" -#include "audio/decoders/vorbis.h" -#include "common/memstream.h" - -namespace AGS3 { - -extern int use_extra_sound_offset; // defined in ac.cpp - -} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mystaticogg.h b/engines/ags/engine/media/audio/clip_mystaticogg.h deleted file mode 100644 index 56b2bb00d260..000000000000 --- a/engines/ags/engine/media/audio/clip_mystaticogg.h +++ /dev/null @@ -1,43 +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. - * - */ - -#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H -#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYSTATICOGG_H - -#include "ags/lib/audio/ogg.h" - -namespace AGS3 { -#ifdef DEPRECATED -/** - * Pre-loaded (non-streaming) OGG file - */ -struct MYSTATICOGG : public AUDIO_STREAM { - MYSTATICOGG(const byte *data, size_t len, bool repeat); - - int get_sound_type() override { - return MUS_OGG; - } -}; -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/clip_mywave.cpp b/engines/ags/engine/media/audio/clip_mywave.cpp deleted file mode 100644 index 6a6d02b6babd..000000000000 --- a/engines/ags/engine/media/audio/clip_mywave.cpp +++ /dev/null @@ -1,136 +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. - * - */ - -#include "ags/lib/audio/digi.h" -#include "ags/shared/util/wgt2allg.h" -#include "ags/engine/media/audio/audiodefines.h" -#include "ags/engine/media/audio/clip_mywave.h" -#include "ags/engine/media/audio/audiointernaldefs.h" -#include "ags/engine/media/audio/soundcache.h" -#include "ags/engine/util/mutex_lock.h" - -#include "ags/engine/platform/base/agsplatformdriver.h" - -namespace AGS3 { -#ifdef DEPRECATED - -void MYWAVE::poll() { - if (state_ != SoundClipPlaying) { - return; - } - - if (voice_get_position(voice) < 0) { - state_ = SoundClipStopped; - } -} - -void MYWAVE::adjust_volume() { - if (!is_playing()) { - return; - } - if (voice < 0) { - return; - } - voice_set_volume(voice, get_final_volume()); -} - -void MYWAVE::set_volume(int newvol) { - vol = newvol; - adjust_volume(); -} - -void MYWAVE::destroy() { - // Stop sound and decrease reference count. - if (wave) { - stop_sample(wave); - sound_cache_free((char *)wave, true); - } - wave = nullptr; - - state_ = SoundClipStopped; -} - -void MYWAVE::seek(int pos) { - if (!is_playing()) { - return; - } - voice_set_position(voice, pos); -} - -int MYWAVE::get_pos() { - if (!is_playing()) { - return -1; - } - return voice_get_position(voice); -} - -int MYWAVE::get_pos_ms() { - // convert the offset in samples into the offset in ms - //return ((1000000 / voice_get_frequency(voice)) * voice_get_position(voice)) / 1000; - - if (voice_get_frequency(voice) < 100) - return 0; - // (number of samples / (samples per second / 100)) * 10 = ms - return (voice_get_position(voice) / (voice_get_frequency(voice) / 100)) * 10; -} - -int MYWAVE::get_length_ms() { - if (wave == nullptr) { - return -1; - } - if (wave->freq < 100) - return 0; - return (wave->len / (wave->freq / 100)) * 10; -} - -int MYWAVE::get_voice() { - if (!is_playing()) { - return -1; - } - return voice; -} - -int MYWAVE::get_sound_type() { - return MUS_WAVE; -} - -int MYWAVE::play() { - if (wave == nullptr) { - return 0; - } - - voice = play_sample(wave, vol, panning, 1000, repeat); - if (voice < 0) { - return 0; - } - - state_ = SoundClipPlaying; - - return 1; -} - -MYWAVE::MYWAVE() : SOUNDCLIP() { - wave = nullptr; - voice = -1; -} -#endif -} // namespace AGS3 diff --git a/engines/ags/engine/media/audio/clip_mywave.h b/engines/ags/engine/media/audio/clip_mywave.h deleted file mode 100644 index 2e665d088da8..000000000000 --- a/engines/ags/engine/media/audio/clip_mywave.h +++ /dev/null @@ -1,62 +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. - * - */ - -#ifndef AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H -#define AGS_ENGINE_MEDIA_AUDIO_CLIP_MYWAVE_H - -#include "ags/engine/media/audio/soundclip.h" - -namespace AGS3 { -#ifdef DEPRECATED - -// My new MP3STREAM wrapper -struct MYWAVE : public SOUNDCLIP { - SAMPLE *wave; - int voice; - - void poll() override; - - void set_volume(int new_speed) override; - - void destroy() override; - - void seek(int pos) override; - - int get_pos() override; - int get_pos_ms() override; - - int get_length_ms() override; - - int get_sound_type() override; - - int play() override; - - MYWAVE(); - -protected: - int get_voice() override; - void adjust_volume() override; -}; -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/engine/media/audio/sound.cpp b/engines/ags/engine/media/audio/sound.cpp index 25dd52a42845..5051321ee1f7 100644 --- a/engines/ags/engine/media/audio/sound.cpp +++ b/engines/ags/engine/media/audio/sound.cpp @@ -32,7 +32,6 @@ #include "ags/engine/media/audio/audiodefines.h" #include "ags/engine/media/audio/sound.h" #include "ags/engine/media/audio/audiointernaldefs.h" -#include "ags/engine/media/audio/clip_mywave.h" #include "ags/engine/media/audio/soundcache.h" #include "ags/engine/media/audio/clip_mymidi.h" #include "ags/engine/util/mutex_lock.h" diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 637330b9df6c..7844c2e24c0f 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -597,7 +597,7 @@ void IAGSEngine::PlaySoundChannel(int32 channel, int32 soundType, int32 volume, else if (soundType == PSND_OGGSTATIC) newcha = my_load_static_ogg(asset_name, volume, (loop != 0)); else if (soundType == PSND_MIDI) { - if (midi_pos >= 0) + if (::AGS::g_music->isPlaying()) quit("!IAGSEngine::PlaySoundChannel: MIDI already in use"); newcha = my_load_midi(asset_name, loop); newcha->set_volume(volume); diff --git a/engines/ags/lib/audio/midi.cpp b/engines/ags/lib/audio/midi.cpp index ca475da20a82..2b8056554dcf 100644 --- a/engines/ags/lib/audio/midi.cpp +++ b/engines/ags/lib/audio/midi.cpp @@ -34,16 +34,8 @@ BEGIN_MIDI_DRIVER_LIST END_MIDI_DRIVER_LIST int midi_card; - int midi_input_card; -volatile long midi_pos; /* current position in the midi file, in beats */ -volatile long midi_time; /* current position in the midi file, in seconds */ - -long midi_loop_start; /* where to loop back to at EOF */ -long midi_loop_end; /* loop when we hit this position */ - - int detect_midi_driver(int driver_id) { return 16; } diff --git a/engines/ags/lib/audio/midi.h b/engines/ags/lib/audio/midi.h index 6bf59bedd0bf..ae24b041ceef 100644 --- a/engines/ags/lib/audio/midi.h +++ b/engines/ags/lib/audio/midi.h @@ -54,9 +54,6 @@ AL_VAR(int, midi_card); AL_VAR(int, midi_input_card); -AL_VAR(volatile long, midi_pos); /* current position in the midi file, in beats */ -AL_VAR(volatile long, midi_time); /* current position in the midi file, in seconds */ - AL_VAR(long, midi_loop_start); /* where to loop back to at EOF */ AL_VAR(long, midi_loop_end); /* loop when we hit this position */ diff --git a/engines/ags/lib/audio/mp3.cpp b/engines/ags/lib/audio/mp3.cpp deleted file mode 100644 index d6fd91ecfef6..000000000000 --- a/engines/ags/lib/audio/mp3.cpp +++ /dev/null @@ -1,122 +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. - * - */ - -#include "ags/lib/audio/mp3.h" -#include "common/textconsole.h" -#include "ags/ags.h" - -namespace AGS3 { - -ALMP3_MP3 *almp3_create_mp3(void *data, int data_len) { - warning("TODO: almp3_create_mp3"); - return nullptr; -} - -int almp3_play_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan) { - warning("TODO: almp3_play_mp3"); - return 0; -} - -int almp3_play_ex_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan, int speed, int loop) { - warning("TODO: almp3_play_ex_mp3"); - return 0; -} - -void almp3_stop_mp3(ALMP3_MP3 *mp3) { - ::AGS::g_vm->_mixer->stopHandle(mp3->_handle); -} - -void almp3_destroy_mp3(ALMP3_MP3 *mp3) { - delete mp3; -} - -int almp3_poll_mp3(ALMP3_MP3 *mp3) { - return ::AGS::g_vm->_mixer->isSoundHandleActive(mp3->_handle) ? 0 : ALMP3_POLL_PLAYJUSTFINISHED; -} - -void almp3_adjust_mp3(ALMP3_MP3 *mp3, int volume, int panning, int speed, bool repeat) { - warning("TODO: almp3_adjust_mp3"); -} - -void almp3_seek_abs_msecs_mp3(ALMP3_MP3 *mp3, int pos) { - warning("TODO: almp3_seek_abs_msecs_mp3"); -} - -int almp3_get_pos_msecs_mp3(ALMP3_MP3 *mp3) { - warning("TODO: almp3_get_pos_msecs_mp3"); - return 0; -} - -AUDIOSTREAM *almp3_get_audiostream_mp3(ALMP3_MP3 *mp3) { - warning("TODO: almp3_get_audiostream_mp3"); - return nullptr; -} - -int almp3_get_length_msecs_mp3(ALMP3_MP3 *mp3) { - warning("TODO: almp3_get_length_msecs_mp3"); - return 0; -} - - -ALMP3_MP3STREAM *almp3_create_mp3stream(void *first_data_buffer, int data_buffer_len, int last_block) { - warning("TODO: almp3_create_mp3stream"); - return nullptr; -} - -int almp3_play_mp3stream(ALMP3_MP3STREAM *mp3, int buffer_len, int vol, int pan) { - warning("TODO: almp3_play_mp3stream"); - return -1; -} - -int almp3_poll_mp3stream(ALMP3_MP3STREAM *mp3) { - warning("TODO: almp3_poll_mp3stream"); - return 0; -} - -void almp3_adjust_mp3stream(ALMP3_MP3STREAM *mp3, int volume, int panning, int speed) { - warning("TODO: almp3_adjust_mp3stream"); -} - -void almp3_stop_mp3stream(ALMP3_MP3STREAM *mp3) { - warning("TODO: almp3_stop_mp3stream"); -} - -void almp3_destroy_mp3stream(ALMP3_MP3STREAM *mp3) { - warning("TODO: almp3_destroy_mp3stream"); -} - -int almp3_get_pos_msecs_mp3stream(ALMP3_MP3STREAM *mp3) { - warning("TODO: almp3_get_pos_msecs_mp3stream"); - return 0; -} - -AUDIOSTREAM *almp3_get_audiostream_mp3stream(ALMP3_MP3STREAM *mp3) { - warning("TODO: almp3_get_audiostream_mp3stream"); - return nullptr; -} - -int almp3_get_length_msecs_mp3stream(ALMP3_MP3STREAM *mp3, int total_size) { - warning("TODO: almp3_get_length_msecs_mp3stream"); - return 0; -} - -} // namespace AGS3 diff --git a/engines/ags/lib/audio/mp3.h b/engines/ags/lib/audio/mp3.h deleted file mode 100644 index 2ac411aa758b..000000000000 --- a/engines/ags/lib/audio/mp3.h +++ /dev/null @@ -1,64 +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. - * - */ - -#ifndef AGS_LIB_AUDIO_MP3_H -#define AGS_LIB_AUDIO_MP3_H - -#include "ags/lib/audio/sound.h" -#include "audio/mixer.h" - -namespace AGS3 { - -#define ALMP3_OK 0 -#define ALMP3_POLL_PLAYJUSTFINISHED 1 - -typedef Audio::AudioStream ALMP3_MP3STREAM; -struct ALMP3_MP3 { - ALMP3_MP3STREAM *_stream; - Audio::SoundHandle _handle; -}; - -extern ALMP3_MP3 *almp3_create_mp3(void *data, int data_len); -extern void almp3_destroy_mp3(ALMP3_MP3 *mp3); -extern int almp3_play_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan); -extern int almp3_play_ex_mp3(ALMP3_MP3 *mp3, int buffer_len, int vol, int pan, int speed, int loop); -extern void almp3_stop_mp3(ALMP3_MP3 *mp3); -extern int almp3_poll_mp3(ALMP3_MP3 *mp3); -extern void almp3_adjust_mp3(ALMP3_MP3 *mp3, int volume, int panning, int speed, bool repeat); -extern void almp3_seek_abs_msecs_mp3(ALMP3_MP3 *mp3, int pos); -extern int almp3_get_pos_msecs_mp3(ALMP3_MP3 *mp3); -extern AUDIOSTREAM *almp3_get_audiostream_mp3(ALMP3_MP3 *mp3); -extern int almp3_get_length_msecs_mp3(ALMP3_MP3 *mp3); - -extern ALMP3_MP3STREAM *almp3_create_mp3stream(void *first_data_buffer, int data_buffer_len, int last_block); -extern int almp3_play_mp3stream(ALMP3_MP3STREAM *mp3, int buffer_len, int vol, int pan); -extern int almp3_poll_mp3stream(ALMP3_MP3STREAM *mp3); -extern void almp3_adjust_mp3stream(ALMP3_MP3STREAM *mp3, int volume, int panning, int speed); -extern void almp3_stop_mp3stream(ALMP3_MP3STREAM *mp3); -extern void almp3_destroy_mp3stream(ALMP3_MP3STREAM *mp3); -extern int almp3_get_pos_msecs_mp3stream(ALMP3_MP3STREAM *mp3); -extern AUDIOSTREAM *almp3_get_audiostream_mp3stream(ALMP3_MP3STREAM *mp3); -extern int almp3_get_length_msecs_mp3stream(ALMP3_MP3STREAM *mp3, int total_size); - -} // namespace AGS3 - -#endif diff --git a/engines/ags/lib/audio/ogg.cpp b/engines/ags/lib/audio/ogg.cpp deleted file mode 100644 index 3fd8dd0b38f8..000000000000 --- a/engines/ags/lib/audio/ogg.cpp +++ /dev/null @@ -1,146 +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. - * - */ - -#include "ags/lib/audio/ogg.h" -#include "common/textconsole.h" -#include "ags/ags.h" - -namespace AGS3 { -#ifdef DEPRECATED -ALOGG_OGG *alogg_create_ogg_from_buffer(void *data, int data_len) { - warning("TODO: alogg_create_ogg_from_buffer"); - return nullptr; -} - -void alogg_destroy_ogg(ALOGG_OGG *ogg) { - delete ogg; -} - -int alogg_play_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan) { - warning("TODO: alogg_play_ogg"); - return 0; -} - -int alogg_play_ex_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan, int speed, int loop) { - warning("TODO: alogg_play_ex_ogg"); - return 0; -} - -void alogg_stop_ogg(ALOGG_OGG *ogg) { - warning("TODO: alogg_stop_ogg"); -} - -int alogg_poll_ogg(ALOGG_OGG *ogg) { - return ::AGS::g_vm->_mixer->isSoundHandleActive(ogg->_handle) ? 0 : ALOGG_POLL_PLAYJUSTFINISHED; -} - -bool alogg_is_playing_ogg(ALOGG_OGG *ogg) { - warning("TODO: alogg_is_playing_ogg"); - return false; -} - -void alogg_adjust_ogg(ALOGG_OGG *ogg, int volume, int panning, int speed, bool repeat) { - warning("TODO: alogg_adjust_oggstream"); -} - -AUDIOSTREAM *alogg_get_audiostream_ogg(ALOGG_OGG *ogg) { - return ogg->_stream; -} - -int alogg_get_pos_msecs_ogg(ALOGG_OGG *ogg) { - warning("TODO: alogg_get_pos_msecs_ogg"); - return 0; -} - -bool alogg_get_wave_is_stereo_ogg(ALOGG_OGG *ogg) { - warning("TODO: alogg_get_wave_is_stereo_ogg"); - return true; -} - -int alogg_get_length_msecs_ogg(ALOGG_OGG *ogg) { - warning("TODO: alogg_get_length_msecs_ogg"); - return 0; -} - -void alogg_seek_abs_msecs_ogg(ALOGG_OGG *ogg, int msecs) { - warning("TODO: alogg_seek_abs_msecs_ogg"); -} - -int alogg_get_wave_freq_ogg(ALOGG_OGG *ogg) { - warning("TODO: alogg_get_wave_freq_ogg"); - return 0; -} - -int alogg_is_end_of_ogg(ALOGG_OGG *ogg) { - warning("TODO: alogg_is_end_of_oggstream"); - return 0; -} - - -ALOGG_OGGSTREAM *alogg_create_oggstream(void *first_data_buffer, int data_buffer_len, int last_block) { - warning("TODO: alogg_create_oggstream"); - return nullptr; -} - -void alogg_destroy_oggstream(ALOGG_OGGSTREAM *ogg) { - warning("TODO: alogg_destroy_oggstream"); -} - -int alogg_play_oggstream(ALOGG_OGGSTREAM *ogg, int buffer_len, int vol, int pan) { - warning("TODO: alogg_play_oggstream"); - return 0; -} - -void alogg_stop_oggstream(ALOGG_OGGSTREAM *ogg) { - warning("TODO: alogg_stop_oggstream"); -} - -int alogg_poll_oggstream(ALOGG_OGGSTREAM *ogg) { - warning("TODO: alogg_poll_oggstream"); - return 0; -} - -void alogg_adjust_oggstream(ALOGG_OGGSTREAM *ogg, int volume, int panning, int speed) { - warning("TODO: alogg_adjust_oggstream"); -} - -bool alogg_is_playing_oggstream(ALOGG_OGGSTREAM *ogg) { - warning("TODO: alogg_is_playing_oggstream"); - return false; -} - -int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg) { - warning("TODO: alogg_is_end_of_oggstream"); - return 0; -} - -AUDIOSTREAM *alogg_get_audiostream_oggstream(ALOGG_OGGSTREAM *ogg) { - warning("TODO: alogg_get_audiostream_oggstream"); - return nullptr; -} - -int alogg_get_pos_msecs_oggstream(ALOGG_OGGSTREAM *ogg) { - warning("TODO: alogg_get_pos_msecs_oggstream"); - return 0; -} -#endif -} // namespace AGS3 diff --git a/engines/ags/lib/audio/ogg.h b/engines/ags/lib/audio/ogg.h deleted file mode 100644 index 79142086ce1e..000000000000 --- a/engines/ags/lib/audio/ogg.h +++ /dev/null @@ -1,76 +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. - * - */ - -#ifndef AGS_LIB_AUDIO_OGG_H -#define AGS_LIB_AUDIO_OGG_H - -#include "ags/lib/audio/sound.h" -#include "audio/mixer.h" - -namespace AGS3 { -#ifdef DEPRECATED -#define ALOGG_OK 0 - -#define ALOGG_PLAY_BUFFERTOOSMALL -1 - -#define ALOGG_POLL_PLAYJUSTFINISHED 1 -#define ALOGG_POLL_NOTPLAYING -1 -#define ALOGG_POLL_FRAMECORRUPT -2 -#define ALOGG_POLL_BUFFERUNDERRUN -3 -#define ALOGG_POLL_INTERNALERROR -4 - -typedef AUDIOSTREAM ALOGG_OGGSTREAM; -struct ALOGG_OGG { - ALOGG_OGGSTREAM *_stream; - Audio::SoundHandle _handle; -}; - -extern ALOGG_OGG *alogg_create_ogg_from_buffer(void *data, int data_len); -extern void alogg_destroy_ogg(ALOGG_OGG *ogg); -extern int alogg_play_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan); -extern int alogg_play_ex_ogg(ALOGG_OGG *ogg, int buffer_len, int vol, int pan, int speed, int loop); -extern void alogg_stop_ogg(ALOGG_OGG *ogg); -extern int alogg_poll_ogg(ALOGG_OGG *ogg); -extern bool alogg_is_playing_ogg(ALOGG_OGG *ogg); -extern void alogg_adjust_ogg(ALOGG_OGG *ogg, int volume, int panning, int speed, bool repeat); -extern AUDIOSTREAM *alogg_get_audiostream_ogg(ALOGG_OGG *ogg); -extern int alogg_get_pos_msecs_ogg(ALOGG_OGG *ogg); -extern bool alogg_get_wave_is_stereo_ogg(ALOGG_OGG *ogg); -extern int alogg_get_length_msecs_ogg(ALOGG_OGG *ogg); -extern void alogg_seek_abs_msecs_ogg(ALOGG_OGG *ogg, int msecs); -extern int alogg_get_wave_freq_ogg(ALOGG_OGG *ogg); -extern int alogg_is_end_of_ogg(ALOGG_OGG *ogg); - -ALOGG_OGGSTREAM *alogg_create_oggstream(void *first_data_buffer, int data_buffer_len, int last_block); -extern int alogg_play_oggstream(ALOGG_OGGSTREAM *ogg, int buffer_len, int vol, int pan); -extern void alogg_stop_oggstream(ALOGG_OGGSTREAM *ogg); -extern void alogg_destroy_oggstream(ALOGG_OGGSTREAM *ogg); -extern int alogg_poll_oggstream(ALOGG_OGGSTREAM *ogg); -extern void alogg_adjust_oggstream(ALOGG_OGGSTREAM *ogg, int volume, int panning, int speed); -extern bool alogg_is_playing_oggstream(ALOGG_OGGSTREAM *ogg); -extern int alogg_is_end_of_oggstream(ALOGG_OGGSTREAM *ogg); -extern AUDIOSTREAM *alogg_get_audiostream_oggstream(ALOGG_OGGSTREAM *ogg); -extern int alogg_get_pos_msecs_oggstream(ALOGG_OGGSTREAM *ogg); -#endif -} // namespace AGS3 - -#endif diff --git a/engines/ags/lib/audio/wav.cpp b/engines/ags/lib/audio/wav.cpp deleted file mode 100644 index 851877df4619..000000000000 --- a/engines/ags/lib/audio/wav.cpp +++ /dev/null @@ -1,31 +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. - * - */ - -#include "ags/lib/audio/wav.h" -#include "common/textconsole.h" -#include "ags/ags.h" - -namespace AGS3 { - - - -} // namespace AGS3 diff --git a/engines/ags/lib/audio/wav.h b/engines/ags/lib/audio/wav.h deleted file mode 100644 index d550c03312da..000000000000 --- a/engines/ags/lib/audio/wav.h +++ /dev/null @@ -1,34 +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. - * - */ - -#ifndef AGS_LIB_AUDIO_WAV_H -#define AGS_LIB_AUDIO_WAV_H - -#include "audio/audiostream.h" -#include "audio/mixer.h" - -namespace AGS3 { - - -} // namespace AGS3 - -#endif diff --git a/engines/ags/module.mk b/engines/ags/module.mk index e19feb3a3cba..703367d4a211 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -28,10 +28,7 @@ MODULE_OBJS = \ lib/audio/aldumb.o \ lib/audio/digi.o \ lib/audio/midi.o \ - lib/audio/mp3.o \ - lib/audio/ogg.o \ lib/audio/sound.o \ - lib/audio/wav.o \ lib/dumb-0.9.2/dumb.o \ lib/dumb-0.9.2/dumbfile.o \ lib/dumb-0.9.2/helpers/clickrem.o \ @@ -281,14 +278,7 @@ MODULE_OBJS = \ engine/main/update.o \ engine/media/audio/ambientsound.o \ engine/media/audio/audio.o \ - engine/media/audio/clip_mydumbmod.o \ - engine/media/audio/clip_myjgmod.o \ engine/media/audio/clip_mymidi.o \ - engine/media/audio/clip_mymp3.o \ - engine/media/audio/clip_myogg.o \ - engine/media/audio/clip_mystaticmp3.o \ - engine/media/audio/clip_mystaticogg.o \ - engine/media/audio/clip_mywave.o \ engine/media/audio/queuedaudioitem.o \ engine/media/audio/sound.o \ engine/media/audio/soundcache.o \ From 13d61c1118b9dc1543d2112e3b9d101712b83c9f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 Jan 2021 20:18:31 -0800 Subject: [PATCH 123/215] AGS: Change some TODO warnings to comments --- engines/ags/lib/allegro/color.cpp | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index f66c1d19d739..eda663a68093 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -240,71 +240,71 @@ int generate_optimized_palette(BITMAP *image, PALETTE pal, AL_CONST signed char } void set_blender_mode(BLENDER_FUNC b15, BLENDER_FUNC b16, BLENDER_FUNC b24, int r, int g, int b, int a) { - warning("TODO: set_blender_mode"); + // TODO: set_blender_mode } void set_blender_mode_ex(BLENDER_FUNC b15, BLENDER_FUNC b16, BLENDER_FUNC b24, BLENDER_FUNC b32, BLENDER_FUNC b15x, BLENDER_FUNC b16x, BLENDER_FUNC b24x, int r, int g, int b, int a) { - warning("TODO: set_blender_mode_ex"); + // TODO: set_blender_mode_ex } void set_alpha_blender(void) { - warning("TODO: set_alpha_blender"); + // TODO: set_alpha_blender } void set_write_alpha_blender(void) { - warning("TODO: set_write_alpha_blender"); + // TODO: set_write_alpha_blender } void set_trans_blender(int r, int g, int b, int a) { - warning("TODO: set_trans_blender"); + // TODO: set_trans_blender } void set_add_blender(int r, int g, int b, int a) { - warning("TODO: set_add_blender"); + // TODO: set_add_blender } void set_burn_blender(int r, int g, int b, int a) { - warning("TODO: set_burn_blender"); + // TODO: set_burn_blender } void set_color_blender(int r, int g, int b, int a) { - warning("TODO: set_color_blender"); + // TODO: set_color_blender } void set_difference_blender(int r, int g, int b, int a) { - warning("TODO: set_difference_blender"); + // TODO: set_difference_blender } void set_dissolve_blender(int r, int g, int b, int a) { - warning("TODO: set_dissolve_blender"); + // TODO: set_dissolve_blender } void set_dodge_blender(int r, int g, int b, int a) { - warning("TODO: set_dodge_blender"); + // TODO: set_dodge_blender } void set_hue_blender(int r, int g, int b, int a) { - warning("TODO: set_hue_blender"); + // TODO: set_hue_blender } void set_invert_blender(int r, int g, int b, int a) { - warning("TODO: set_invert_blender"); + // TODO: set_invert_blender } void set_luminance_blender(int r, int g, int b, int a) { - warning("TODO: set_luminance_blender"); + // TODO: set_luminance_blender } void set_multiply_blender(int r, int g, int b, int a) { - warning("TODO: set_multiply_blender"); + // TODO: set_multiply_blender } void set_saturation_blender(int r, int g, int b, int a) { - warning("TODO: set_saturation_blender"); + // TODO: set_saturation_blender } void set_screen_blender(int r, int g, int b, int a) { - warning("TODO: set_screen_blender"); + // TODO: set_screen_blender } From d28f68cfb9394fddb6a95fd747a17ebfe86da76c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 Jan 2021 20:27:57 -0800 Subject: [PATCH 124/215] AGS: Implement select_palette & unselect_palette --- engines/ags/lib/allegro.cpp | 1 + engines/ags/lib/allegro/color.cpp | 14 ++++++++++++-- engines/ags/lib/allegro/color.h | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/engines/ags/lib/allegro.cpp b/engines/ags/lib/allegro.cpp index bc1f5d24f23d..ec92eb3f2439 100644 --- a/engines/ags/lib/allegro.cpp +++ b/engines/ags/lib/allegro.cpp @@ -27,6 +27,7 @@ namespace AGS3 { /* default palette structures */ PALETTE black_palette; PALETTE _current_palette; +PALETTE _prev_current_palette; int _current_palette_changed = 0xFFFFFFFF; diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index eda663a68093..0ae8c76b3fdd 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -223,11 +223,21 @@ void fade_out(int speed) { } void select_palette(AL_CONST PALETTE p) { - warning("TODO: select_palette"); + int c; + + for (c = 0; c < PAL_SIZE; c++) { + _prev_current_palette[c] = _current_palette[c]; + _current_palette[c] = p[c]; + } + + // TODO: See if the remainder of Allegro's select_palette method is needed for AGS } void unselect_palette(void) { - warning("TODO: unselect_palette"); + int c; + + for (c = 0; c < PAL_SIZE; c++) + _current_palette[c] = _prev_current_palette[c]; } void generate_332_palette(PALETTE pal) { diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index f0a25c06006e..db793f2fade7 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -50,6 +50,7 @@ typedef color RGB; typedef RGB PALETTE[PAL_SIZE]; AL_VAR(PALETTE, _current_palette); +AL_VAR(PALETTE, _prev_current_palette); #include "common/pack-end.h" // END STRUCT PACKING From c79ba8d2b8b40c1a6e94e29492b2bbda2e68765c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 08:59:58 -0800 Subject: [PATCH 125/215] AGS: Corrections to saving games --- engines/ags/engine/ac/file.cpp | 8 ++------ engines/ags/engine/ac/global_file.cpp | 9 +++++++-- engines/ags/engine/script/cc_instance.cpp | 3 ++- engines/ags/lib/allegro/file.cpp | 2 +- engines/ags/metaengine.cpp | 1 + engines/ags/shared/util/directory.cpp | 6 ++++++ engines/ags/shared/util/directory.h | 2 ++ engines/ags/shared/util/filestream.cpp | 3 +-- engines/ags/shared/util/filestream.h | 2 -- 9 files changed, 22 insertions(+), 14 deletions(-) diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index d20793aaea2b..263885359c16 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -37,6 +37,7 @@ #include "ags/shared/util/misc.h" #include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/util/stream.h" +#include "ags/shared/util/filestream.h" #include "ags/shared/core/assetmanager.h" #include "ags/shared/core/asset.h" #include "ags/engine/main/engine.h" @@ -271,12 +272,7 @@ String MakeSpecialSubDir(const String &sp_dir) { } String MakeAppDataPath() { - String app_data_path = usetup.shared_data_dir; - if (app_data_path.IsEmpty()) - app_data_path = MakeSpecialSubDir(PathOrCurDir(platform->GetAllUsersDataDirectory())); - Directory::CreateDirectory(app_data_path); - app_data_path.AppendChar('/'); - return app_data_path; + return AGS::Shared::SAVE_FOLDER_PREFIX; } bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath &rp) { diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index 66fb05648e36..0edc340598bf 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -29,6 +29,7 @@ #include "ags/engine/ac/string.h" #include "ags/engine/debugging/debug_log.h" #include "ags/shared/util/directory.h" +#include "ags/shared/util/filestream.h" #include "ags/shared/util/path.h" #include "ags/shared/util/stream.h" @@ -81,8 +82,12 @@ int32_t FileOpen(const char *fnmm, Shared::FileOpenMode open_mode, Shared::FileW } Stream *s = File::OpenFile(rp.FullPath, open_mode, work_mode); - if (!s && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) - s = File::OpenFile(rp.AltPath, open_mode, work_mode); + if (!s && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) { + if (rp.FullPath.CompareLeft(AGS::Shared::SAVE_FOLDER_PREFIX)) + // When file not found in main path, only check in AltPath if it's not a + // savegame file. Because ScummVM doesn't have any alt for saves + s = File::OpenFile(rp.AltPath, open_mode, work_mode); + } valid_handles[useindx].stream = s; if (valid_handles[useindx].stream == nullptr) diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index 5a4fd59f3165..f239f121736e 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -1024,7 +1024,8 @@ int ccInstance::Run(int32_t curpc) { cc_error("invalid pointer type for object function call: %d", reg1.Type); } } else if (reg1.Type == kScValStaticFunction) { - return_value = reg1.SPfn(func_callstack.GetHead() + 1, num_args_to_func); + RuntimeScriptValue *head = func_callstack.GetHead(); + return_value = reg1.SPfn(head + 1, num_args_to_func); } else if (reg1.Type == kScValObjectFunction) { cc_error("unexpected object function pointer on SCMD_CALLEXT"); } else { diff --git a/engines/ags/lib/allegro/file.cpp b/engines/ags/lib/allegro/file.cpp index 75f32935f694..e4dd65417956 100644 --- a/engines/ags/lib/allegro/file.cpp +++ b/engines/ags/lib/allegro/file.cpp @@ -128,7 +128,7 @@ char *make_relative_filename(char *dest, const char *path, const char *filename, int is_relative_filename(const char *filename) { Common::String fname(filename); - return !fname.contains('/') && !fname.contains('\\') ? 0 : -1; + return !fname.contains('/') && !fname.contains('\\') ? 1 : 0; } /*------------------------------------------------------------------*/ diff --git a/engines/ags/metaengine.cpp b/engines/ags/metaengine.cpp index e210080f4179..977c87d3e1e3 100644 --- a/engines/ags/metaengine.cpp +++ b/engines/ags/metaengine.cpp @@ -23,6 +23,7 @@ #include "ags/metaengine.h" #include "ags/detection.h" #include "ags/ags.h" +#include "ags/shared/util/directory.h" #include "ags/shared/util/filestream.h" #include "ags/engine/ac/richgamemedia.h" #include "ags/engine/game/savegame.h" diff --git a/engines/ags/shared/util/directory.cpp b/engines/ags/shared/util/directory.cpp index 5bbecdb074a6..798dd454dfb1 100644 --- a/engines/ags/shared/util/directory.cpp +++ b/engines/ags/shared/util/directory.cpp @@ -31,6 +31,8 @@ namespace AGS3 { namespace AGS { namespace Shared { +const char *SAVE_FOLDER_PREFIX = "/saves/"; + namespace Directory { bool CreateDirectory(const String &path) { @@ -38,6 +40,10 @@ bool CreateDirectory(const String &path) { } bool CreateAllDirectories(const String &parent, const String &path) { + if (path == SAVE_FOLDER_PREFIX) + // ScummVM save folder doesn't need creating + return true; + if (!ags_directory_exists(parent.GetCStr())) return false; if (path.IsEmpty()) diff --git a/engines/ags/shared/util/directory.h b/engines/ags/shared/util/directory.h index 754e6837bbce..16a2e760b87f 100644 --- a/engines/ags/shared/util/directory.h +++ b/engines/ags/shared/util/directory.h @@ -36,6 +36,8 @@ namespace AGS3 { namespace AGS { namespace Shared { +extern const char *SAVE_FOLDER_PREFIX; + namespace Directory { // Creates new directory (if it does not exist) bool CreateDirectory(const String &path); diff --git a/engines/ags/shared/util/filestream.cpp b/engines/ags/shared/util/filestream.cpp index 620124a42f82..d90c228a4091 100644 --- a/engines/ags/shared/util/filestream.cpp +++ b/engines/ags/shared/util/filestream.cpp @@ -23,6 +23,7 @@ #include "ags/shared/util/filestream.h" #include "ags/shared/util/stdio_compat.h" #include "ags/shared/util/string.h" +#include "ags/shared/util/directory.h" #include "ags/ags.h" #include "common/file.h" #include "common/system.h" @@ -31,8 +32,6 @@ namespace AGS3 { namespace AGS { namespace Shared { -const char *SAVE_FOLDER_PREFIX = "/saves/"; - FileStream::FileStream(const String &file_name, FileOpenMode open_mode, FileWorkMode work_mode, DataEndianess stream_endianess) : DataStream(stream_endianess), _writeBuffer(DisposeAfterUse::YES), diff --git a/engines/ags/shared/util/filestream.h b/engines/ags/shared/util/filestream.h index 491e552fadd2..ff9994c11108 100644 --- a/engines/ags/shared/util/filestream.h +++ b/engines/ags/shared/util/filestream.h @@ -33,8 +33,6 @@ namespace AGS3 { namespace AGS { namespace Shared { -extern const char *SAVE_FOLDER_PREFIX; - class FileStream : public DataStream { public: From 208503c082323a97cf72dc127861b71ee1a4c3df Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 09:54:41 -0800 Subject: [PATCH 126/215] AGS: Show fatal errors in a GUI message dialog --- engines/ags/ags.cpp | 4 ++++ engines/ags/detection_tables.h | 2 +- engines/ags/shared/ac/common.cpp | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 374d67cf6ba3..822737d3b2b7 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -433,4 +433,8 @@ Common::Error AGSEngine::saveGameState(int slot, const Common::String &desc, boo return Common::kNoError; } +void AGSEngine::GUIError(const Common::String &msg) { + GUIErrorMessage(msg); +} + } // namespace AGS diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index ec98ce52e46e..bf615503a4bf 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -47,7 +47,7 @@ static const PlainGameDescriptor GAME_NAMES[] = { static const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), - ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), + ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), // 3.1 { AD_TABLE_END_MARKER } }; diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index 0990898673c6..d7dfc36b6216 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -22,6 +22,7 @@ #include "ags/shared/ac/common.h" #include "ags/shared/util/string.h" +#include "ags/ags.h" namespace AGS3 { @@ -34,6 +35,8 @@ void quitprintf(const char *fmt, ...) { va_start(ap, fmt); String text = String::FromFormatV(fmt, ap); va_end(ap); + + ::AGS::g_vm->GUIError(text); quit(text); } From 68835f3077684b73182b26023e4a03e6a532f9f7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 13:00:35 -0800 Subject: [PATCH 127/215] AGS: Fix for writing audio to savegames --- engines/ags/engine/game/savegame_components.cpp | 13 ++++++++++--- engines/ags/engine/media/audio/clip_mymidi.cpp | 3 ++- engines/ags/engine/media/audio/clip_mymidi.h | 1 - engines/ags/engine/media/audio/soundclip.cpp | 4 +++- engines/ags/engine/media/audio/soundclip.h | 1 + 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index f5fb62c0b46d..4475b1fdb64c 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -352,6 +352,7 @@ HSaveError WriteAudio(PStream out) { // Game content assertion out->WriteInt32(game.audioClipTypes.size()); out->WriteInt32(game.audioClips.size()); // [ivan-mogilko] not necessary, kept only to avoid changing save format + // Audio types for (size_t i = 0; i < game.audioClipTypes.size(); ++i) { game.audioClipTypes[i].WriteToSavegame(out.get()); @@ -365,6 +366,10 @@ HSaveError WriteAudio(PStream out) { out->WriteInt32(((ScriptAudioClip *)ch->_sourceClip)->id); out->WriteInt32(ch->get_pos()); out->WriteInt32(ch->_priority); + out->WriteInt32(ch->_repeat ? 1 : 0); + out->WriteInt32(ch->_vol); + out->WriteInt32(ch->_panning); + out->WriteInt32(ch->_volAsPercentage); out->WriteInt32(ch->_panningAsPercentage); out->WriteInt32(ch->get_speed()); // since version 1 @@ -375,6 +380,7 @@ HSaveError WriteAudio(PStream out) { out->WriteInt32(-1); } } + out->WriteInt32(crossFading); out->WriteInt32(crossFadeVolumePerStep); out->WriteInt32(crossFadeStep); @@ -385,18 +391,17 @@ HSaveError WriteAudio(PStream out) { // Ambient sound for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) ambient[i].WriteToFile(out.get()); + return HSaveError::None(); } HSaveError ReadAudio(PStream in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) { HSaveError err; + // Game content assertion if (!AssertGameContent(err, in->ReadInt32(), game.audioClipTypes.size(), "Audio Clip Types")) return err; in->ReadInt32(); // audio clip count - /* [ivan-mogilko] looks like it's not necessary to assert, as there's no data serialized for clips - if (!AssertGameContent(err, in->ReadInt32(), game.audioClips.size(), "Audio Clips")) - return err;*/ // Audio types for (size_t i = 0; i < game.audioClipTypes.size(); ++i) { @@ -428,6 +433,7 @@ HSaveError ReadAudio(PStream in, int32_t cmp_ver, const PreservedParams &pp, Res } } } + crossFading = in->ReadInt32(); crossFadeVolumePerStep = in->ReadInt32(); crossFadeStep = in->ReadInt32(); @@ -438,6 +444,7 @@ HSaveError ReadAudio(PStream in, int32_t cmp_ver, const PreservedParams &pp, Res // Ambient sound for (int i = 0; i < MAX_SOUND_CHANNELS; ++i) ambient[i].ReadFromFile(in.get()); + for (int i = 1; i < MAX_SOUND_CHANNELS; ++i) { if (ambient[i].channel == 0) { r_data.DoAmbient[i] = 0; diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index 01e0e3b4bcb7..fc05ad53d6ef 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -28,7 +28,8 @@ namespace AGS3 { MYMIDI::MYMIDI(Common::SeekableReadStream *data, bool repeat) : - _data(data), _repeat(repeat), lengthInSeconds(0) { + _data(data), lengthInSeconds(0) { + _repeat = repeat; } void MYMIDI::destroy() { diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index 78c7b4fea1e9..0fa224390e9f 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -30,7 +30,6 @@ namespace AGS3 { // MIDI struct MYMIDI : public SOUNDCLIP { Common::SeekableReadStream *_data; - bool _repeat; int lengthInSeconds; MYMIDI(Common::SeekableReadStream *data, bool repeat); diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index 40a7b741f5ca..2c88f0b9aa0d 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -28,7 +28,7 @@ namespace AGS3 { SOUNDCLIP::SOUNDCLIP() : _state(SoundClipInitial), _panning(128), _panningAsPercentage(0), _sourceClip(nullptr), _sourceClipType(0), _speed(1000), _priority(50), _xSource(-1), _ySource(-1), _maximumPossibleDistanceAway(0), - _volAsPercentage(100), _vol(0), _volModifier(0) { + _volAsPercentage(100), _vol(0), _volModifier(0), _repeat(false) { _mixer = ::AGS::g_vm->_mixer; } @@ -69,6 +69,8 @@ int SOUNDCLIP::play_from(int position) { SoundClipWaveBase::SoundClipWaveBase(Audio::AudioStream *stream, int volume, bool repeat) : SOUNDCLIP(), _stream(stream) { _mixer = ::AGS::g_vm->_mixer; + _repeat = repeat; + _vol = volume; if (repeat) { Audio::SeekableAudioStream *str = dynamic_cast(stream); diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index 3476a248c07b..6d520bfba109 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -64,6 +64,7 @@ struct SOUNDCLIP { int _volAsPercentage; int _vol; int _volModifier; + bool _repeat; SOUNDCLIP(); virtual ~SOUNDCLIP(); From 84258bc06d7e05e49c17a61be5772459b78fb004 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 13:15:17 -0800 Subject: [PATCH 128/215] AGS: Don't allow audio streams to free cached sound data --- engines/ags/engine/media/audio/soundcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index 45fce16f10dd..37e07e1c504a 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -216,7 +216,7 @@ Common::SeekableReadStream *get_cached_sound(const AssetPath &asset_name) { return nullptr; // Create a read stream for the sound - return new Common::MemoryReadStream(data, muslen, DisposeAfterUse::YES); + return new Common::MemoryReadStream(data, muslen, DisposeAfterUse::NO); } } // namespace AGS3 From 824e20a08af55a61dc3505e378aef98acb383a61 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 14:18:48 -0800 Subject: [PATCH 129/215] AGS: gcc compilation fixes --- engines/ags/lib/allegro/flood.cpp | 5 +++-- engines/ags/module.mk | 2 +- engines/ags/music.cpp | 2 +- engines/ags/shared/core/types.h | 2 ++ engines/ags/shared/game/main_game_file.cpp | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/engines/ags/lib/allegro/flood.cpp b/engines/ags/lib/allegro/flood.cpp index e5794ce29cee..a618525f0c31 100644 --- a/engines/ags/lib/allegro/flood.cpp +++ b/engines/ags/lib/allegro/flood.cpp @@ -22,6 +22,7 @@ #include "ags/lib/allegro/flood.h" #include "ags/lib/allegro/gfx.h" +#include "ags/shared/core/types.h" #include "common/array.h" namespace AGS3 { @@ -183,8 +184,8 @@ void floodfill(BITMAP *bmp, int x, int y, int color) { p = FLOOD_LINE(0); for (c = 0; c < (int)scratchMem.size(); c++) { p[c].flags = 0; - p[c].lpos = SHRT_MAX; - p[c].rpos = SHRT_MIN; + p[c].lpos = INT16_MAX; + p[c].rpos = INT16_MIN; p[c].y = y; p[c].next = 0; } diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 703367d4a211..2520fbb6f1b7 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -300,7 +300,7 @@ MODULE_OBJS = \ engine/script/script_runtime.o \ engine/script/systemimports.o \ plugins/dll.o \ - plugins/agscreditz\agscreditz.o + plugins/agscreditz/agscreditz.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/music.cpp b/engines/ags/music.cpp index c0f49644cf97..5b78a24e7bb7 100644 --- a/engines/ags/music.cpp +++ b/engines/ags/music.cpp @@ -97,7 +97,7 @@ void Music::playMusic(Common::SeekableReadStream *midi, bool repeat) { } void Music::seek(size_t offset) { - warning("TODO: Music::seek to offset %u", offset); + warning("TODO: Music::seek to offset %u", (uint32)offset); } } // End of namespace AGS diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index b4209972a632..c77a9e6e2090 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -74,6 +74,7 @@ typedef int64 intptr_t; #define fixed_t int32_t #define color_t int +#undef INT16_MIN #undef INT16_MAX #undef INT32_MIN #undef INT32_MAX @@ -81,6 +82,7 @@ typedef int64 intptr_t; #undef INT_MAX #undef UINT_MAX #undef SIZE_MAX +#define INT16_MIN -32768 #define INT16_MAX 0x7fff #define INT32_MIN (-2147483647 - 1) #define INT32_MAX 2147483647 diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index ad424347590e..6a41aa838035 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -622,7 +622,7 @@ void FixupSaveDirectory(GameSetupStruct &game) { String s = Path::FixupSharedFilename(game.saveGameFolderName); snprintf(game.saveGameFolderName, MAX_SG_FOLDER_LEN, "%s", s.GetCStr()); #else - sprintf(game.saveGameFolderName, ""); + strcpy(game.saveGameFolderName, SAVE_FOLDER_PREFIX); #endif } From 23d1c9474819229a59402cbf67029f6c27c867f4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 16:16:53 -0800 Subject: [PATCH 130/215] AGS: Properly handle transparent pixels in item z order Previously, in cases where multiple items were layered on top of each other, it wasn't properly tecognizing transparent pixels as such to be ignored --- engines/ags/lib/allegro/gfx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index 2af30ede9f49..5075bd9a9a27 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -206,7 +206,7 @@ class BITMAP { } uint getTransparentColor() const { - return _owner->getTransparentColor(); + return format.RGBToColor(255, 0, 255); } int getpixel(int x, int y) const; From 8849e2982c783839432469ec022ce51b3051d046 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 16:29:14 -0800 Subject: [PATCH 131/215] AGS: Add AGS credits section --- devtools/credits.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/devtools/credits.pl b/devtools/credits.pl index d7b844991202..880113f08acc 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -556,6 +556,11 @@ sub add_paragraph { add_person("Ludvig Strigeus", "ludde", "(retired)"); end_section(); + begin_section("AGS"); + add_person("Paul Gilbert", "dreammaster", ""); + add_person("", "AGA", "AgsCreditz"); + end_section(); + begin_section("Avalanche"); add_person("Peter Bozsó", "uruk", ""); add_person("Arnaud Boutonné", "Strangerke", ""); From 9d496da2f9e8505dc3caab574dc3bcabbe6ed902 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 16:47:50 -0800 Subject: [PATCH 132/215] AGS: Don't show GUI message on exit --- engines/ags/shared/ac/common.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index d7dfc36b6216..57caf4820efd 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -29,6 +29,7 @@ namespace AGS3 { using namespace AGS::Shared; const char *game_file_sig = "Adventure Creator Game File v2"; +extern volatile char abort_engine; void quitprintf(const char *fmt, ...) { va_list ap; @@ -36,7 +37,8 @@ void quitprintf(const char *fmt, ...) { String text = String::FromFormatV(fmt, ap); va_end(ap); - ::AGS::g_vm->GUIError(text); + if (!abort_engine) + ::AGS::g_vm->GUIError(text); quit(text); } From fe6784e3eb26802c322f28e6e093d7fcbdea2713 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 18:20:11 -0800 Subject: [PATCH 133/215] AGS: Implement horizontally flipped sprite draw --- engines/ags/lib/allegro/gfx.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index a98541c2bfb6..c35184d27be6 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -294,7 +294,11 @@ void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color) } void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { - error("TODO: draw_sprite_h_flip"); + Graphics::ManagedSurface &bmpS = **bmp; + Graphics::ManagedSurface &spriteS = **sprite; + + add_palette_if_needed(spriteS, bmpS); + bmpS.transBlitFrom(spriteS, Common::Point(x, y), (uint)-1, true); } void draw_sprite_v_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { From c51d95807993fd7a1a44d5458361544882c3d26e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 20:42:51 -0800 Subject: [PATCH 134/215] AGS: Matching keycodes to Allegro in original --- engines/ags/engine/ac/sys_events.cpp | 176 ++++--- engines/ags/engine/ac/system.cpp | 8 +- engines/ags/engine/debugging/debug.cpp | 7 +- engines/ags/engine/main/game_run.cpp | 18 +- .../platform/base/agsplatformdriver.cpp | 2 +- engines/ags/events.cpp | 126 ++++- engines/ags/events.h | 22 +- engines/ags/lib/allegro/keyboard.cpp | 2 +- engines/ags/lib/allegro/keyboard.h | 446 ++++++++++++------ 9 files changed, 534 insertions(+), 273 deletions(-) diff --git a/engines/ags/engine/ac/sys_events.cpp b/engines/ags/engine/ac/sys_events.cpp index 16acd3c0e818..2f8b9c9795e7 100644 --- a/engines/ags/engine/ac/sys_events.cpp +++ b/engines/ags/engine/ac/sys_events.cpp @@ -31,6 +31,7 @@ #include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/engine/ac/timer.h" #include "ags/ags.h" +#include "ags/events.h" namespace AGS3 { @@ -56,8 +57,8 @@ int ags_kbhit() { } int ags_iskeypressed(int keycode) { - if (keycode >= 0 && keycode < Common::KEYCODE_LAST) { - return key[keycode] != 0; + if (keycode >= 0 && keycode < __allegro_KEY_MAX) { + return ::AGS::g_events->isKeyPressed((AllegroKbdKeycode)keycode); } return 0; } @@ -99,100 +100,87 @@ int ags_check_mouse_wheel() { } int ags_getch() { - const Common::KeyState keyState = readkey(); - int gott; - - // I believe we rely on a lot of keys being converted to ASCII, which is why - // the complete scan code list is not here. - - switch (keyState.keycode) { - case Common::KEYCODE_F1: - gott = eAGSKeyCodeF1; - break; - case Common::KEYCODE_F2: - gott = eAGSKeyCodeF2; - break; - case Common::KEYCODE_F3: - gott = eAGSKeyCodeF3; - break; - case Common::KEYCODE_F4: - gott = eAGSKeyCodeF4; - break; - case Common::KEYCODE_F5: - gott = eAGSKeyCodeF5; - break; - case Common::KEYCODE_F6: - gott = eAGSKeyCodeF6; - break; - case Common::KEYCODE_F7: - gott = eAGSKeyCodeF7; - break; - case Common::KEYCODE_F8: - gott = eAGSKeyCodeF8; - break; - case Common::KEYCODE_F9: - gott = eAGSKeyCodeF9; - break; - case Common::KEYCODE_F10: - gott = eAGSKeyCodeF10; - break; - case Common::KEYCODE_F11: - gott = eAGSKeyCodeF11; - break; - case Common::KEYCODE_F12: - gott = eAGSKeyCodeF12; - break; - - case Common::KEYCODE_INSERT: - case Common::KEYCODE_KP0: - gott = eAGSKeyCodeInsert; - break; - case Common::KEYCODE_DELETE: - case Common::KEYCODE_KP_PERIOD: - gott = eAGSKeyCodeDelete; - break; - case Common::KEYCODE_HOME: - case Common::KEYCODE_KP7: - gott = eAGSKeyCodeHome; - break; - case Common::KEYCODE_END: - case Common::KEYCODE_KP1: - gott = eAGSKeyCodeEnd; - break; - case Common::KEYCODE_PAGEUP: - case Common::KEYCODE_KP9: - gott = eAGSKeyCodePageUp; - break; - case Common::KEYCODE_PAGEDOWN: - case Common::KEYCODE_KP3: - gott = eAGSKeyCodePageDown; - break; - case Common::KEYCODE_LEFT: - case Common::KEYCODE_KP4: - gott = eAGSKeyCodeLeftArrow; - break; - case Common::KEYCODE_RIGHT: - case Common::KEYCODE_KP6: - gott = eAGSKeyCodeRightArrow; - break; - case Common::KEYCODE_UP: - case Common::KEYCODE_KP8: - gott = eAGSKeyCodeUpArrow; - break; - case Common::KEYCODE_DOWN: - case Common::KEYCODE_KP2: - gott = eAGSKeyCodeDownArrow; - break; - - default: - if (keyState.flags & (Common::KBD_ALT | Common::KBD_CTRL) && - keyState.keycode >= Common::KEYCODE_a && keyState.keycode <= Common::KEYCODE_z) + const int read_key_value = readkey(); + int gott = read_key_value; + const int scancode = ((gott >> 8) & 0x00ff); + const int ascii = (gott & 0x00ff); + + bool is_extended = (ascii == EXTENDED_KEY_CODE); + // On macos, the extended keycode is the ascii character '?' or '\0' if alt-key + // so check it's not actually the character '?' +#if AGS_PLATFORM_OS_MACOS && ! AGS_PLATFORM_OS_IOS + is_extended = is_extended || ((ascii == EXTENDED_KEY_CODE_MACOS) && (scancode != __allegro_KEY_SLASH)); +#endif + + /* char message[200]; + sprintf(message, "Scancode: %04X", gott); + Debug::Printf(message);*/ + + /*if ((scancode >= KEY_0_PAD) && (scancode <= KEY_9_PAD)) { + // fix numeric pad keys if numlock is off (allegro 4.2 changed this behaviour) + if ((key_shifts & KB_NUMLOCK_FLAG) == 0) + gott = (gott & 0xff00) | EXTENDED_KEY_CODE; + }*/ + + if (gott == READKEY_CODE_ALT_TAB) { + // Alt+Tab, it gets stuck down unless we do this + gott = AGS_KEYCODE_ALT_TAB; + } +#if AGS_PLATFORM_OS_MACOS + else if (scancode == __allegro_KEY_BACKSPACE) { + gott = eAGSKeyCodeBackspace; + } +#endif + else if (is_extended) { + + // I believe we rely on a lot of keys being converted to ASCII, which is why + // the complete scan code list is not here. + + switch (scancode) { + case __allegro_KEY_F1: gott = eAGSKeyCodeF1; break; + case __allegro_KEY_F2: gott = eAGSKeyCodeF2; break; + case __allegro_KEY_F3: gott = eAGSKeyCodeF3; break; + case __allegro_KEY_F4: gott = eAGSKeyCodeF4; break; + case __allegro_KEY_F5: gott = eAGSKeyCodeF5; break; + case __allegro_KEY_F6: gott = eAGSKeyCodeF6; break; + case __allegro_KEY_F7: gott = eAGSKeyCodeF7; break; + case __allegro_KEY_F8: gott = eAGSKeyCodeF8; break; + case __allegro_KEY_F9: gott = eAGSKeyCodeF9; break; + case __allegro_KEY_F10: gott = eAGSKeyCodeF10; break; + case __allegro_KEY_F11: gott = eAGSKeyCodeF11; break; + case __allegro_KEY_F12: gott = eAGSKeyCodeF12; break; + + case __allegro_KEY_INSERT: gott = eAGSKeyCodeInsert; break; + case __allegro_KEY_DEL: gott = eAGSKeyCodeDelete; break; + case __allegro_KEY_HOME: gott = eAGSKeyCodeHome; break; + case __allegro_KEY_END: gott = eAGSKeyCodeEnd; break; + case __allegro_KEY_PGUP: gott = eAGSKeyCodePageUp; break; + case __allegro_KEY_PGDN: gott = eAGSKeyCodePageDown; break; + case __allegro_KEY_LEFT: gott = eAGSKeyCodeLeftArrow; break; + case __allegro_KEY_RIGHT: gott = eAGSKeyCodeRightArrow; break; + case __allegro_KEY_UP: gott = eAGSKeyCodeUpArrow; break; + case __allegro_KEY_DOWN: gott = eAGSKeyCodeDownArrow; break; + + case __allegro_KEY_0_PAD: gott = eAGSKeyCodeInsert; break; + case __allegro_KEY_1_PAD: gott = eAGSKeyCodeEnd; break; + case __allegro_KEY_2_PAD: gott = eAGSKeyCodeDownArrow; break; + case __allegro_KEY_3_PAD: gott = eAGSKeyCodePageDown; break; + case __allegro_KEY_4_PAD: gott = eAGSKeyCodeLeftArrow; break; + case __allegro_KEY_5_PAD: gott = eAGSKeyCodeNumPad5; break; + case __allegro_KEY_6_PAD: gott = eAGSKeyCodeRightArrow; break; + case __allegro_KEY_7_PAD: gott = eAGSKeyCodeHome; break; + case __allegro_KEY_8_PAD: gott = eAGSKeyCodeUpArrow; break; + case __allegro_KEY_9_PAD: gott = eAGSKeyCodePageUp; break; + case __allegro_KEY_DEL_PAD: gott = eAGSKeyCodeDelete; break; + + default: // no meaningful mappings // this is how we accidentally got the alt-key mappings - gott = AGS_EXT_KEY_SHIFT + (keyState.keycode - Common::KEYCODE_a) + 1; - else - gott = keyState.ascii; - break; + gott = scancode + AGS_EXT_KEY_SHIFT; + } + } else { + // this includes ascii characters and ctrl-A-Z + gott = ascii; } // Alt+X, abort (but only once game is loaded) diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index 02d4c0a2d78e..0275ec1b6a5e 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -40,11 +40,11 @@ #include "ags/engine/ac/global_translation.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/shared/util/string_compat.h" - #include "ags/shared/debugging/out.h" #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" #include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/events.h" namespace AGS3 { @@ -118,15 +118,15 @@ int System_GetHardwareAcceleration() { } int System_GetNumLock() { - return (key_shifts & KB_NUMLOCK_FLAG) ? 1 : 0; + return (::AGS::g_events->getModifierFlags() & __allegro_KB_NUMLOCK_FLAG) ? 1 : 0; } int System_GetCapsLock() { - return (key_shifts & KB_CAPSLOCK_FLAG) ? 1 : 0; + return (::AGS::g_events->getModifierFlags() & __allegro_KB_CAPSLOCK_FLAG) ? 1 : 0; } int System_GetScrollLock() { - return (key_shifts & KB_SCROLOCK_FLAG) ? 1 : 0; + return (::AGS::g_events->getModifierFlags() & __allegro_KB_SCROLOCK_FLAG) ? 1 : 0; } void System_SetNumLock(int newValue) { diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index 921108c4b2f9..9fc93fbf7eb6 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -44,6 +44,7 @@ #include "ags/shared/script/cc_error.h" #include "ags/shared/util/string_utils.h" #include "ags/shared/util/textstreamwriter.h" +#include "ags/events.h" #if AGS_PLATFORM_OS_WINDOWS //include @@ -564,14 +565,12 @@ void check_debug_keys() { if (play.debug_mode) { // do the run-time script debugging - if ((!key[KEY_SCRLOCK]) && (scrlockWasDown)) + if (!::AGS::g_events->isKeyPressed(KEY_SCRLOCK) && scrlockWasDown) scrlockWasDown = 0; - else if ((key[KEY_SCRLOCK]) && (!scrlockWasDown)) { - + else if (::AGS::g_events->isKeyPressed(KEY_SCRLOCK) && !scrlockWasDown) { break_on_next_script_step = 1; scrlockWasDown = 1; } - } } diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index c331315f414c..4870b1c27540 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -66,6 +66,7 @@ #include "ags/engine/ac/timer.h" #include "ags/engine/ac/keycode.h" #include "ags/lib/allegro/keyboard.h" +#include "ags/events.h" namespace AGS3 { @@ -280,14 +281,7 @@ static void check_mouse_controls() { // situation: if first modifier gets pressed, 'key_shifts' will be zero, // when second modifier gets pressed it will only contain first one, and so on. static int get_active_shifts() { - int shifts = 0; - if (key[KEY_LSHIFT] || key[KEY_RSHIFT]) - shifts |= KB_SHIFT_FLAG; - if (key[KEY_LCONTROL] || key[KEY_RCONTROL]) - shifts |= KB_CTRL_FLAG; - if (key[KEY_ALT] || key[KEY_ALTGR]) - shifts |= KB_ALT_FLAG; - return shifts; + return ::AGS::g_events->getModifierFlags(); } // Special flags to OR saved shift flags with: @@ -345,7 +339,10 @@ bool run_service_key_controls(int &kgn) { // LAlt or RAlt + Enter // NOTE: for some reason LAlt + Enter produces same code as F9 - if (act_shifts == KB_ALT_FLAG && ((keycode == eAGSKeyCodeF9 && !key[KEY_F9]) || keycode == eAGSKeyCodeReturn)) { + if (act_shifts == KB_ALT_FLAG && ( + (keycode == eAGSKeyCodeF9 && !::AGS::g_events->isKeyPressed(KEY_F9)) || + keycode == eAGSKeyCodeReturn) + ) { engine_try_switch_windowed_gfxmode(); return false; } @@ -476,7 +473,8 @@ static void check_keyboard_controls() { // return; // } - if ((kgn == eAGSKeyCodeAltV) && (key[KEY_LCONTROL] || key[KEY_RCONTROL]) && (play.wait_counter < 1) && (is_text_overlay == 0) && (restrict_until == 0)) { + if (kgn == eAGSKeyCodeAltV && (::AGS::g_events->getModifierFlags() & KB_CTRL_FLAG) + && (play.wait_counter < 1) && (is_text_overlay == 0) && (restrict_until == 0)) { // make sure we can't interrupt a Wait() // and desync the music to cutscene play.debug_mode++; diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index cfd02ea60244..150a7f64189b 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -159,7 +159,7 @@ void AGSPlatformDriver::SetGameWindowIcon() { } int AGSPlatformDriver::ConvertKeycodeToScanCode(int keycode) { - keycode -= ('A' - KEY_A); + keycode -= ('A' - Common::KEYCODE_a); return keycode; } diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp index 983dcee60f13..8a6c7a2a6141 100644 --- a/engines/ags/events.cpp +++ b/engines/ags/events.cpp @@ -32,8 +32,9 @@ namespace AGS { EventsManager *g_events; -EventsManager::EventsManager() { +EventsManager::EventsManager() : _keyFlags(0) { g_events = this; + _keys.resize(AGS3::__allegro_KEY_MAX); } EventsManager::~EventsManager() { @@ -50,10 +51,15 @@ void EventsManager::pollEvents() { ::AGS3::check_dynamic_sprites_at_exit = 0; } else if (e.type == Common::EVENT_KEYDOWN) { + updateKeys(e.kbd.keycode, true); + if (!isModifierKey(e.kbd.keycode)) { // Add keypresses to the pending key list _pendingKeys.push(e.kbd); } + } else if (e.type == Common::EVENT_KEYUP) { + updateKeys(e.kbd.keycode, false); + } else { // Add other event types to the pending events queue. If the event is a // mouse move and the prior one was also, then discard the prior one. @@ -67,23 +73,23 @@ void EventsManager::pollEvents() { } } -bool EventsManager::isModifierKey(const Common::KeyCode &keycode) const { - return keycode == Common::KEYCODE_LCTRL || keycode == Common::KEYCODE_LALT - || keycode == Common::KEYCODE_RCTRL || keycode == Common::KEYCODE_RALT - || keycode == Common::KEYCODE_LSHIFT || keycode == Common::KEYCODE_RSHIFT - || keycode == Common::KEYCODE_LSUPER || keycode == Common::KEYCODE_RSUPER - || keycode == Common::KEYCODE_CAPSLOCK || keycode == Common::KEYCODE_NUMLOCK - || keycode == Common::KEYCODE_SCROLLOCK; -} - bool EventsManager::keypressed() { pollEvents(); return !_pendingKeys.empty(); } -Common::KeyState EventsManager::readKey() { +int EventsManager::readKey() { pollEvents(); - return _pendingKeys.empty() ? Common::KeyState() : _pendingKeys.pop(); + if (_pendingKeys.empty()) + return 0; + + Common::KeyState keyState = _pendingKeys.pop(); + + int code = getScancode(keyState.keycode) << 8; + if (keyState.ascii >= 0 && keyState.ascii <= 127) + code = keyState.ascii; + + return code; } Common::Event EventsManager::readEvent() { @@ -95,4 +101,100 @@ void EventsManager::warpMouse(const Common::Point &newPos) { g_system->warpMouse(newPos.x, newPos.y); } +bool EventsManager::isModifierKey(const Common::KeyCode &keycode) const { + return keycode == Common::KEYCODE_LCTRL || keycode == Common::KEYCODE_LALT + || keycode == Common::KEYCODE_RCTRL || keycode == Common::KEYCODE_RALT + || keycode == Common::KEYCODE_LSHIFT || keycode == Common::KEYCODE_RSHIFT + || keycode == Common::KEYCODE_LSUPER || keycode == Common::KEYCODE_RSUPER + || keycode == Common::KEYCODE_CAPSLOCK || keycode == Common::KEYCODE_NUMLOCK + || keycode == Common::KEYCODE_SCROLLOCK; +} + +int EventsManager::getScancode(Common::KeyCode keycode) const { + if (keycode >= Common::KEYCODE_a && keycode <= Common::KEYCODE_z) + return (int)keycode - Common::KEYCODE_a + AGS3::__allegro_KEY_A; + if (keycode >= Common::KEYCODE_0 && keycode <= Common::KEYCODE_9) + return (int)keycode - Common::KEYCODE_0 + AGS3::__allegro_KEY_0; + if (keycode >= Common::KEYCODE_KP0 && keycode <= Common::KEYCODE_KP9) + return (int)keycode - Common::KEYCODE_KP0 + AGS3::__allegro_KEY_0_PAD; + if (keycode >= Common::KEYCODE_F1 && keycode <= Common::KEYCODE_F12) + return (int)keycode - Common::KEYCODE_F1 + AGS3::__allegro_KEY_F1; + + switch (keycode) { + case Common::KEYCODE_ESCAPE: return AGS3::__allegro_KEY_ESC; + case Common::KEYCODE_TILDE: return AGS3::__allegro_KEY_TILDE; + case Common::KEYCODE_MINUS: return AGS3::__allegro_KEY_MINUS; + case Common::KEYCODE_EQUALS: return AGS3::__allegro_KEY_EQUALS; + case Common::KEYCODE_BACKSPACE: return AGS3::__allegro_KEY_BACKSPACE; + case Common::KEYCODE_TAB: return AGS3::__allegro_KEY_TAB; + case Common::KEYCODE_LEFTBRACKET: return AGS3::__allegro_KEY_OPENBRACE; + case Common::KEYCODE_RIGHTBRACKET: return AGS3::__allegro_KEY_CLOSEBRACE; + case Common::KEYCODE_RETURN: return AGS3::__allegro_KEY_ENTER; + case Common::KEYCODE_COLON: return AGS3::__allegro_KEY_COLON; + case Common::KEYCODE_QUOTE: return AGS3::__allegro_KEY_QUOTE; + case Common::KEYCODE_BACKSLASH: return AGS3::__allegro_KEY_BACKSLASH; + case Common::KEYCODE_COMMA: return AGS3::__allegro_KEY_COMMA; + case Common::KEYCODE_SLASH: return AGS3::__allegro_KEY_SLASH; + case Common::KEYCODE_SPACE: return AGS3::__allegro_KEY_SPACE; + case Common::KEYCODE_INSERT: return AGS3::__allegro_KEY_INSERT; + case Common::KEYCODE_DELETE: return AGS3::__allegro_KEY_DEL; + case Common::KEYCODE_HOME: return AGS3::__allegro_KEY_HOME; + case Common::KEYCODE_END: return AGS3::__allegro_KEY_END; + case Common::KEYCODE_PAGEUP: return AGS3::__allegro_KEY_PGUP; + case Common::KEYCODE_PAGEDOWN: return AGS3::__allegro_KEY_PGDN; + case Common::KEYCODE_LEFT: return AGS3::__allegro_KEY_LEFT; + case Common::KEYCODE_RIGHT: return AGS3::__allegro_KEY_RIGHT; + case Common::KEYCODE_UP: return AGS3::__allegro_KEY_UP; + case Common::KEYCODE_DOWN: return AGS3::__allegro_KEY_DOWN; + case Common::KEYCODE_KP_DIVIDE: return AGS3::__allegro_KEY_SLASH_PAD; + case Common::KEYCODE_ASTERISK: return AGS3::__allegro_KEY_ASTERISK; + case Common::KEYCODE_KP_MINUS: return AGS3::__allegro_KEY_MINUS_PAD; + case Common::KEYCODE_KP_PLUS: return AGS3::__allegro_KEY_PLUS_PAD; + case Common::KEYCODE_KP_PERIOD: return AGS3::__allegro_KEY_DEL_PAD; + case Common::KEYCODE_KP_ENTER: return AGS3::__allegro_KEY_ENTER_PAD; + case Common::KEYCODE_PRINT: return AGS3::__allegro_KEY_PRTSCR; + case Common::KEYCODE_PAUSE: return AGS3::__allegro_KEY_PAUSE; + case Common::KEYCODE_SEMICOLON: return AGS3::__allegro_KEY_SEMICOLON; + + case Common::KEYCODE_LSHIFT: return AGS3::__allegro_KEY_LSHIFT; + case Common::KEYCODE_RSHIFT: return AGS3::__allegro_KEY_RSHIFT; + case Common::KEYCODE_LCTRL: return AGS3::__allegro_KEY_LCONTROL; + case Common::KEYCODE_RCTRL: return AGS3::__allegro_KEY_RCONTROL; + case Common::KEYCODE_LALT: return AGS3::__allegro_KEY_ALT; + case Common::KEYCODE_RALT: return AGS3::__allegro_KEY_ALT; + case Common::KEYCODE_SCROLLOCK: return AGS3::__allegro_KEY_SCRLOCK; + case Common::KEYCODE_NUMLOCK: return AGS3::__allegro_KEY_NUMLOCK; + case Common::KEYCODE_CAPSLOCK: return AGS3::__allegro_KEY_CAPSLOCK; + default: return 0; + } +} + +void EventsManager::updateKeys(const Common::KeyState &keyState, bool isDown) { + // Update the keys array with whether the key is pressed + int scancode = getScancode(keyState.keycode); + if (scancode != 0) + _keys[scancode] = isDown; + + // Update shift flags + _keyFlags = 0; + if (keyState.flags & Common::KBD_SHIFT) + _keyFlags |= AGS3::__allegro_KB_SHIFT_FLAG; + if (keyState.flags & Common::KBD_CTRL) + _keyFlags |= AGS3::__allegro_KB_CTRL_FLAG; + if (keyState.flags & Common::KBD_ALT) + _keyFlags |= AGS3::__allegro_KB_ALT_FLAG; + if (keyState.flags & Common::KBD_META) + _keyFlags |= AGS3::__allegro_KB_COMMAND_FLAG; + if (keyState.flags & Common::KBD_SCRL) + _keyFlags |= AGS3::__allegro_KB_SCROLOCK_FLAG; + if (keyState.flags & Common::KBD_NUM) + _keyFlags |= AGS3::__allegro_KB_NUMLOCK_FLAG; + if (keyState.flags & Common::KBD_CAPS) + _keyFlags |= AGS3::__allegro_KB_CAPSLOCK_FLAG; +} + +bool EventsManager::isKeyPressed(AGS3::AllegroKbdKeycode keycode) const { + return _keys[keycode]; +} + } // namespace AGS diff --git a/engines/ags/events.h b/engines/ags/events.h index 5842bd9548d2..f291136c07a8 100644 --- a/engines/ags/events.h +++ b/engines/ags/events.h @@ -23,6 +23,8 @@ #ifndef AGS_EVENTS_H #define AGS_EVENTS_H +#include "lib/allegro/keyboard.h" +#include "common/array.h" #include "common/queue.h" #include "common/events.h" @@ -32,8 +34,14 @@ class EventsManager { private: Common::Queue _pendingEvents; Common::Queue _pendingKeys; + Common::Array _keys; + uint _keyFlags; bool isModifierKey(const Common::KeyCode &keycode) const; + + int getScancode(Common::KeyCode keycode) const; + + void updateKeys(const Common::KeyState &keyState, bool isDown); public: EventsManager(); ~EventsManager(); @@ -51,7 +59,7 @@ class EventsManager { /** * Returns the next keypress, if any is pending */ - Common::KeyState readKey(); + int readKey(); /** * Returns the next event, if any @@ -62,6 +70,18 @@ class EventsManager { * Sets the mouse position */ void warpMouse(const Common::Point &newPos); + + /** + * Returns true if a given key is pressed + */ + bool isKeyPressed(AGS3::AllegroKbdKeycode keycode) const; + + /** + * Returns the bitset of currently pressed modifier keys + */ + uint getModifierFlags() const { + return _keyFlags; + } }; extern EventsManager *g_events; diff --git a/engines/ags/lib/allegro/keyboard.cpp b/engines/ags/lib/allegro/keyboard.cpp index 7629e364e7a4..869ca1655a9e 100644 --- a/engines/ags/lib/allegro/keyboard.cpp +++ b/engines/ags/lib/allegro/keyboard.cpp @@ -72,7 +72,7 @@ bool keypressed() { return ::AGS::g_events->keypressed(); } -Common::KeyState readkey() { +int readkey() { return ::AGS::g_events->readKey(); } diff --git a/engines/ags/lib/allegro/keyboard.h b/engines/ags/lib/allegro/keyboard.h index 5f5b4ccc1f84..873737e163ee 100644 --- a/engines/ags/lib/allegro/keyboard.h +++ b/engines/ags/lib/allegro/keyboard.h @@ -28,151 +28,305 @@ namespace AGS3 { -#define __allegro_KEY_MAX Common::KEYCODE_LAST - -#define KB_SHIFT_FLAG Common::KBD_SHIFT -#define KB_CTRL_FLAG Common::KBD_CTRL -#define KB_ALT_FLAG Common::KBD_ALT -#define KB_NUMLOCK_FLAG Common::KBD_NUM -#define KB_CAPSLOCK_FLAG Common::KBD_CAPS -#define KB_SCROLOCK_FLAG Common::KBD_SCRL - -#define KEY_LSHIFT Common::KEYCODE_LSHIFT -#define KEY_RSHIFT Common::KEYCODE_RSHIFT -#define KEY_ALT Common::KEYCODE_LALT -#define KEY_LCONTROL Common::KEYCODE_LCTRL -#define KEY_RCONTROL Common::KEYCODE_RCTRL -#define KEY_SCRLOCK Common::KEYCODE_SCROLLOCK -#define KEY_ALTGR 0 -#define KEY_F9 Common::KEYCODE_F9 -#define KEY_A Common::KEYCODE_a - -#define __allegro_KEY_LSHIFT Common::KEYCODE_LSHIFT -#define __allegro_KEY_RSHIFT Common::KEYCODE_RSHIFT -#define __allegro_KEY_LCONTROL Common::KEYCODE_LCTRL -#define __allegro_KEY_RCONTROL Common::KEYCODE_RCTRL -#define __allegro_KEY_ALT Common::KEYCODE_LALT - -#define __allegro_KEY_F1 Common::KEYCODE_F1 -#define __allegro_KEY_F2 Common::KEYCODE_F2 -#define __allegro_KEY_F3 Common::KEYCODE_F3 -#define __allegro_KEY_F4 Common::KEYCODE_F4 -#define __allegro_KEY_F5 Common::KEYCODE_F5 -#define __allegro_KEY_F6 Common::KEYCODE_F6 -#define __allegro_KEY_F7 Common::KEYCODE_F7 -#define __allegro_KEY_F8 Common::KEYCODE_F8 -#define __allegro_KEY_F9 Common::KEYCODE_F9 -#define __allegro_KEY_F10 Common::KEYCODE_F10 -#define __allegro_KEY_F11 Common::KEYCODE_F11 -#define __allegro_KEY_F12 Common::KEYCODE_F12 - -#define __allegro_KEY_HOME Common::KEYCODE_HOME -#define __allegro_KEY_UP Common::KEYCODE_UP -#define __allegro_KEY_PGUP Common::KEYCODE_PAGEUP -#define __allegro_KEY_LEFT Common::KEYCODE_LEFT -#define __allegro_KEY_RIGHT Common::KEYCODE_RIGHT -#define __allegro_KEY_END Common::KEYCODE_END -#define __allegro_KEY_DOWN Common::KEYCODE_DOWN -#define __allegro_KEY_PGDN Common::KEYCODE_PAGEDOWN -#define __allegro_KEY_INSERT Common::KEYCODE_INSERT -#define __allegro_KEY_DEL Common::KEYCODE_DELETE - -#define __allegro_KEY_0_PAD Common::KEYCODE_KP0 -#define __allegro_KEY_1_PAD Common::KEYCODE_KP1 -#define __allegro_KEY_2_PAD Common::KEYCODE_KP2 -#define __allegro_KEY_3_PAD Common::KEYCODE_KP3 -#define __allegro_KEY_4_PAD Common::KEYCODE_KP4 -#define __allegro_KEY_5_PAD Common::KEYCODE_KP5 -#define __allegro_KEY_6_PAD Common::KEYCODE_KP6 -#define __allegro_KEY_7_PAD Common::KEYCODE_KP7 -#define __allegro_KEY_8_PAD Common::KEYCODE_KP8 -#define __allegro_KEY_9_PAD Common::KEYCODE_KP9 -#define __allegro_KEY_DEL_PAD Common::KEYCODE_KP_PERIOD - -#define __allegro_KEY_PRTSCR Common::KEYCODE_PRINT -#define __allegro_KEY_PAUSE Common::KEYCODE_PAUSE -#define __allegro_KEY_ABNT_C1 94 -#define __allegro_KEY_YEN 95 -#define __allegro_KEY_KANA 96 -#define __allegro_KEY_CONVERT 97 -#define __allegro_KEY_NOCONVERT 98 -#define __allegro_KEY_CIRCUMFLEX 100 -#define __allegro_KEY_KANJI 102 -#define __allegro_KEY_ALTGR 120 -#define __allegro_KEY_LWIN Common::KEYCODE_LMETA -#define __allegro_KEY_RWIN Common::KEYCODE_RMETA -#define __allegro_KEY_MENU 123 -#define __allegro_KEY_SCRLOCK Common::KEYCODE_SCROLLOCK -#define __allegro_KEY_NUMLOCK Common::KEYCODE_NUMLOCK -#define __allegro_KEY_CAPSLOCK Common::KEYCODE_CAPSLOCK - -#define __allegro_KEY_0 Common::KEYCODE_0 -#define __allegro_KEY_1 Common::KEYCODE_1 -#define __allegro_KEY_2 Common::KEYCODE_2 -#define __allegro_KEY_3 Common::KEYCODE_3 -#define __allegro_KEY_4 Common::KEYCODE_4 -#define __allegro_KEY_5 Common::KEYCODE_5 -#define __allegro_KEY_6 Common::KEYCODE_6 -#define __allegro_KEY_7 Common::KEYCODE_7 -#define __allegro_KEY_8 Common::KEYCODE_8 -#define __allegro_KEY_9 Common::KEYCODE_9 - -#define __allegro_KEY_A Common::KEYCODE_a -#define __allegro_KEY_B Common::KEYCODE_b -#define __allegro_KEY_C Common::KEYCODE_c -#define __allegro_KEY_D Common::KEYCODE_d -#define __allegro_KEY_E Common::KEYCODE_e -#define __allegro_KEY_F Common::KEYCODE_f -#define __allegro_KEY_G Common::KEYCODE_g -#define __allegro_KEY_H Common::KEYCODE_h -#define __allegro_KEY_I Common::KEYCODE_i -#define __allegro_KEY_J Common::KEYCODE_j -#define __allegro_KEY_K Common::KEYCODE_k -#define __allegro_KEY_L Common::KEYCODE_l -#define __allegro_KEY_M Common::KEYCODE_m -#define __allegro_KEY_N Common::KEYCODE_n -#define __allegro_KEY_O Common::KEYCODE_o -#define __allegro_KEY_P Common::KEYCODE_p -#define __allegro_KEY_Q Common::KEYCODE_q -#define __allegro_KEY_R Common::KEYCODE_r -#define __allegro_KEY_S Common::KEYCODE_s -#define __allegro_KEY_T Common::KEYCODE_t -#define __allegro_KEY_U Common::KEYCODE_u -#define __allegro_KEY_V Common::KEYCODE_v -#define __allegro_KEY_W Common::KEYCODE_w -#define __allegro_KEY_X Common::KEYCODE_x -#define __allegro_KEY_Y Common::KEYCODE_y -#define __allegro_KEY_Z Common::KEYCODE_z - - -#define __allegro_KEY_BACKSPACE Common::KEYCODE_BACKSPACE -#define __allegro_KEY_TAB Common::KEYCODE_TAB -#define __allegro_KEY_ENTER Common::KEYCODE_RETURN -#define __allegro_KEY_ENTER_PAD Common::KEYCODE_KP_ENTER -#define __allegro_KEY_ESC Common::KEYCODE_ESCAPE -#define __allegro_KEY_SPACE Common::KEYCODE_SPACE -#define __allegro_KEY_QUOTE Common::KEYCODE_QUOTE -#define __allegro_KEY_COMMA Common::KEYCODE_COMMA -#define __allegro_KEY_STOP 0 -#define __allegro_KEY_SLASH Common::KEYCODE_SLASH -#define __allegro_KEY_SLASH_PAD Common::KEYCODE_KP_DIVIDE -#define __allegro_KEY_BACKSLASH Common::KEYCODE_BACKSLASH -#define __allegro_KEY_BACKSLASH2 Common::KEYCODE_BACKSLASH -#define __allegro_KEY_SEMICOLON Common::KEYCODE_SEMICOLON -#define __allegro_KEY_EQUALS Common::KEYCODE_EQUALS -#define __allegro_KEY_EQUALS_PAD Common::KEYCODE_KP_EQUALS -#define __allegro_KEY_OPENBRACE 123 -#define __allegro_KEY_CLOSEBRACE 125 -#define __allegro_KEY_PLUS_PAD Common::KEYCODE_KP_PLUS -#define __allegro_KEY_MINUS Common::KEYCODE_MINUS -#define __allegro_KEY_MINUS_PAD Common::KEYCODE_KP_MINUS -#define __allegro_KEY_COLON Common::KEYCODE_COLON -#define __allegro_KEY_COLON2 Common::KEYCODE_COLON -#define __allegro_KEY_ASTERISK Common::KEYCODE_ASTERISK -#define __allegro_KEY_AT Common::KEYCODE_AT - -extern bool key[Common::KEYCODE_LAST]; -extern uint key_shifts; +enum AllegroKbdFlag { + __allegro_KB_SHIFT_FLAG = 0x0001, + __allegro_KB_CTRL_FLAG = 0x0002, + __allegro_KB_ALT_FLAG = 0x0004, + __allegro_KB_LWIN_FLAG = 0x0008, + __allegro_KB_RWIN_FLAG = 0x0010, + __allegro_KB_MENU_FLAG = 0x0020, + __allegro_KB_COMMAND_FLAG = 0x0040, + __allegro_KB_SCROLOCK_FLAG = 0x0100, + __allegro_KB_NUMLOCK_FLAG = 0x0200, + __allegro_KB_CAPSLOCK_FLAG = 0x0400, + __allegro_KB_INALTSEQ_FLAG = 0x0800, + __allegro_KB_ACCENT1_FLAG = 0x1000, + __allegro_KB_ACCENT2_FLAG = 0x2000, + __allegro_KB_ACCENT3_FLAG = 0x4000, + __allegro_KB_ACCENT4_FLAG = 0x8000 +}; + +enum AllegroKbdKeycode { + __allegro_KEY_A = 1, + __allegro_KEY_B = 2, + __allegro_KEY_C = 3, + __allegro_KEY_D = 4, + __allegro_KEY_E = 5, + __allegro_KEY_F = 6, + __allegro_KEY_G = 7, + __allegro_KEY_H = 8, + __allegro_KEY_I = 9, + __allegro_KEY_J = 10, + __allegro_KEY_K = 11, + __allegro_KEY_L = 12, + __allegro_KEY_M = 13, + __allegro_KEY_N = 14, + __allegro_KEY_O = 15, + __allegro_KEY_P = 16, + __allegro_KEY_Q = 17, + __allegro_KEY_R = 18, + __allegro_KEY_S = 19, + __allegro_KEY_T = 20, + __allegro_KEY_U = 21, + __allegro_KEY_V = 22, + __allegro_KEY_W = 23, + __allegro_KEY_X = 24, + __allegro_KEY_Y = 25, + __allegro_KEY_Z = 26, + __allegro_KEY_0 = 27, + __allegro_KEY_1 = 28, + __allegro_KEY_2 = 29, + __allegro_KEY_3 = 30, + __allegro_KEY_4 = 31, + __allegro_KEY_5 = 32, + __allegro_KEY_6 = 33, + __allegro_KEY_7 = 34, + __allegro_KEY_8 = 35, + __allegro_KEY_9 = 36, + __allegro_KEY_0_PAD = 37, + __allegro_KEY_1_PAD = 38, + __allegro_KEY_2_PAD = 39, + __allegro_KEY_3_PAD = 40, + __allegro_KEY_4_PAD = 41, + __allegro_KEY_5_PAD = 42, + __allegro_KEY_6_PAD = 43, + __allegro_KEY_7_PAD = 44, + __allegro_KEY_8_PAD = 45, + __allegro_KEY_9_PAD = 46, + __allegro_KEY_F1 = 47, + __allegro_KEY_F2 = 48, + __allegro_KEY_F3 = 49, + __allegro_KEY_F4 = 50, + __allegro_KEY_F5 = 51, + __allegro_KEY_F6 = 52, + __allegro_KEY_F7 = 53, + __allegro_KEY_F8 = 54, + __allegro_KEY_F9 = 55, + __allegro_KEY_F10 = 56, + __allegro_KEY_F11 = 57, + __allegro_KEY_F12 = 58, + __allegro_KEY_ESC = 59, + __allegro_KEY_TILDE = 60, + __allegro_KEY_MINUS = 61, + __allegro_KEY_EQUALS = 62, + __allegro_KEY_BACKSPACE = 63, + __allegro_KEY_TAB = 64, + __allegro_KEY_OPENBRACE = 65, + __allegro_KEY_CLOSEBRACE = 66, + __allegro_KEY_ENTER = 67, + __allegro_KEY_COLON = 68, + __allegro_KEY_QUOTE = 69, + __allegro_KEY_BACKSLASH = 70, + __allegro_KEY_BACKSLASH2 = 71, + __allegro_KEY_COMMA = 72, + __allegro_KEY_STOP = 73, + __allegro_KEY_SLASH = 74, + __allegro_KEY_SPACE = 75, + __allegro_KEY_INSERT = 76, + __allegro_KEY_DEL = 77, + __allegro_KEY_HOME = 78, + __allegro_KEY_END = 79, + __allegro_KEY_PGUP = 80, + __allegro_KEY_PGDN = 81, + __allegro_KEY_LEFT = 82, + __allegro_KEY_RIGHT = 83, + __allegro_KEY_UP = 84, + __allegro_KEY_DOWN = 85, + __allegro_KEY_SLASH_PAD = 86, + __allegro_KEY_ASTERISK = 87, + __allegro_KEY_MINUS_PAD = 88, + __allegro_KEY_PLUS_PAD = 89, + __allegro_KEY_DEL_PAD = 90, + __allegro_KEY_ENTER_PAD = 91, + __allegro_KEY_PRTSCR = 92, + __allegro_KEY_PAUSE = 93, + __allegro_KEY_ABNT_C1 = 94, + __allegro_KEY_YEN = 95, + __allegro_KEY_KANA = 96, + __allegro_KEY_CONVERT = 97, + __allegro_KEY_NOCONVERT = 98, + __allegro_KEY_AT = 99, + __allegro_KEY_CIRCUMFLEX = 100, + __allegro_KEY_COLON2 = 101, + __allegro_KEY_KANJI = 102, + __allegro_KEY_EQUALS_PAD = 103, /* MacOS X */ + __allegro_KEY_BACKQUOTE = 104, /* MacOS X */ + __allegro_KEY_SEMICOLON = 105, /* MacOS X */ + __allegro_KEY_COMMAND = 106, /* MacOS X */ + __allegro_KEY_UNKNOWN1 = 107, + __allegro_KEY_UNKNOWN2 = 108, + __allegro_KEY_UNKNOWN3 = 109, + __allegro_KEY_UNKNOWN4 = 110, + __allegro_KEY_UNKNOWN5 = 111, + __allegro_KEY_UNKNOWN6 = 112, + __allegro_KEY_UNKNOWN7 = 113, + __allegro_KEY_UNKNOWN8 = 114, + + __allegro_KEY_MODIFIERS = 115, + + __allegro_KEY_LSHIFT = 115, + __allegro_KEY_RSHIFT = 116, + __allegro_KEY_LCONTROL = 117, + __allegro_KEY_RCONTROL = 118, + __allegro_KEY_ALT = 119, + __allegro_KEY_ALTGR = 120, + __allegro_KEY_LWIN = 121, + __allegro_KEY_RWIN = 122, + __allegro_KEY_MENU = 123, + __allegro_KEY_SCRLOCK = 124, + __allegro_KEY_NUMLOCK = 125, + __allegro_KEY_CAPSLOCK = 126, + + __allegro_KEY_MAX = 127 +}; + +#define KB_SHIFT_FLAG __allegro_KB_SHIFT_FLAG +#define KB_CTRL_FLAG __allegro_KB_CTRL_FLAG +#define KB_ALT_FLAG __allegro_KB_ALT_FLAG +#define KB_LWIN_FLAG __allegro_KB_LWIN_FLAG +#define KB_RWIN_FLAG __allegro_KB_RWIN_FLAG +#define KB_MENU_FLAG __allegro_KB_MENU_FLAG +#define KB_COMMAND_FLAG __allegro_KB_COMMAND_FLAG +#define KB_SCROLOCK_FLAG __allegro_KB_SCROLOCK_FLAG +#define KB_NUMLOCK_FLAG __allegro_KB_NUMLOCK_FLAG +#define KB_CAPSLOCK_FLAG __allegro_KB_CAPSLOCK_FLAG +#define KB_INALTSEQ_FLAG __allegro_KB_INALTSEQ_FLAG +#define KB_ACCENT1_FLAG __allegro_KB_ACCENT1_FLAG +#define KB_ACCENT2_FLAG __allegro_KB_ACCENT2_FLAG +#define KB_ACCENT3_FLAG __allegro_KB_ACCENT3_FLAG +#define KB_ACCENT4_FLAG __allegro_KB_ACCENT4_FLAG + +#define KEY_A __allegro_KEY_A +#define KEY_B __allegro_KEY_B +#define KEY_C __allegro_KEY_C +#define KEY_D __allegro_KEY_D +#define KEY_E __allegro_KEY_E +#define KEY_F __allegro_KEY_F +#define KEY_G __allegro_KEY_G +#define KEY_H __allegro_KEY_H +#define KEY_I __allegro_KEY_I +#define KEY_J __allegro_KEY_J +#define KEY_K __allegro_KEY_K +#define KEY_L __allegro_KEY_L +#define KEY_M __allegro_KEY_M +#define KEY_N __allegro_KEY_N +#define KEY_O __allegro_KEY_O +#define KEY_P __allegro_KEY_P +#define KEY_Q __allegro_KEY_Q +#define KEY_R __allegro_KEY_R +#define KEY_S __allegro_KEY_S +#define KEY_T __allegro_KEY_T +#define KEY_U __allegro_KEY_U +#define KEY_V __allegro_KEY_V +#define KEY_W __allegro_KEY_W +#define KEY_X __allegro_KEY_X +#define KEY_Y __allegro_KEY_Y +#define KEY_Z __allegro_KEY_Z +#define KEY_0 __allegro_KEY_0 +#define KEY_1 __allegro_KEY_1 +#define KEY_2 __allegro_KEY_2 +#define KEY_3 __allegro_KEY_3 +#define KEY_4 __allegro_KEY_4 +#define KEY_5 __allegro_KEY_5 +#define KEY_6 __allegro_KEY_6 +#define KEY_7 __allegro_KEY_7 +#define KEY_8 __allegro_KEY_8 +#define KEY_9 __allegro_KEY_9 +#define KEY_0_PAD __allegro_KEY_0_PAD +#define KEY_1_PAD __allegro_KEY_1_PAD +#define KEY_2_PAD __allegro_KEY_2_PAD +#define KEY_3_PAD __allegro_KEY_3_PAD +#define KEY_4_PAD __allegro_KEY_4_PAD +#define KEY_5_PAD __allegro_KEY_5_PAD +#define KEY_6_PAD __allegro_KEY_6_PAD +#define KEY_7_PAD __allegro_KEY_7_PAD +#define KEY_8_PAD __allegro_KEY_8_PAD +#define KEY_9_PAD __allegro_KEY_9_PAD +#define KEY_F1 __allegro_KEY_F1 +#define KEY_F2 __allegro_KEY_F2 +#define KEY_F3 __allegro_KEY_F3 +#define KEY_F4 __allegro_KEY_F4 +#define KEY_F5 __allegro_KEY_F5 +#define KEY_F6 __allegro_KEY_F6 +#define KEY_F7 __allegro_KEY_F7 +#define KEY_F8 __allegro_KEY_F8 +#define KEY_F9 __allegro_KEY_F9 +#define KEY_F10 __allegro_KEY_F10 +#define KEY_F11 __allegro_KEY_F11 +#define KEY_F12 __allegro_KEY_F12 +#define KEY_ESC __allegro_KEY_ESC +#define KEY_TILDE __allegro_KEY_TILDE +#define KEY_MINUS __allegro_KEY_MINUS +#define KEY_EQUALS __allegro_KEY_EQUALS +#define KEY_BACKSPACE __allegro_KEY_BACKSPACE +#define KEY_TAB __allegro_KEY_TAB +#define KEY_OPENBRACE __allegro_KEY_OPENBRACE +#define KEY_CLOSEBRACE __allegro_KEY_CLOSEBRACE +#define KEY_ENTER __allegro_KEY_ENTER +#define KEY_COLON __allegro_KEY_COLON +#define KEY_QUOTE __allegro_KEY_QUOTE +#define KEY_BACKSLASH __allegro_KEY_BACKSLASH +#define KEY_BACKSLASH2 __allegro_KEY_BACKSLASH2 +#define KEY_COMMA __allegro_KEY_COMMA +#define KEY_STOP __allegro_KEY_STOP +#define KEY_SLASH __allegro_KEY_SLASH +#define KEY_SPACE __allegro_KEY_SPACE +#define KEY_INSERT __allegro_KEY_INSERT +#define KEY_DEL __allegro_KEY_DEL +#define KEY_HOME __allegro_KEY_HOME +#define KEY_END __allegro_KEY_END +#define KEY_PGUP __allegro_KEY_PGUP +#define KEY_PGDN __allegro_KEY_PGDN +#define KEY_LEFT __allegro_KEY_LEFT +#define KEY_RIGHT __allegro_KEY_RIGHT +#define KEY_UP __allegro_KEY_UP +#define KEY_DOWN __allegro_KEY_DOWN +#define KEY_SLASH_PAD __allegro_KEY_SLASH_PAD +#define KEY_ASTERISK __allegro_KEY_ASTERISK +#define KEY_MINUS_PAD __allegro_KEY_MINUS_PAD +#define KEY_PLUS_PAD __allegro_KEY_PLUS_PAD +#define KEY_DEL_PAD __allegro_KEY_DEL_PAD +#define KEY_ENTER_PAD __allegro_KEY_ENTER_PAD +#define KEY_PRTSCR __allegro_KEY_PRTSCR +#define KEY_PAUSE __allegro_KEY_PAUSE +#define KEY_ABNT_C1 __allegro_KEY_ABNT_C1 +#define KEY_YEN __allegro_KEY_YEN +#define KEY_KANA __allegro_KEY_KANA +#define KEY_CONVERT __allegro_KEY_CONVERT +#define KEY_NOCONVERT __allegro_KEY_NOCONVERT +#define KEY_AT __allegro_KEY_AT +#define KEY_CIRCUMFLEX __allegro_KEY_CIRCUMFLEX +#define KEY_COLON2 __allegro_KEY_COLON2 +#define KEY_KANJI __allegro_KEY_KANJI +#define KEY_EQUALS_PAD __allegro_KEY_EQUALS_PAD +#define KEY_BACKQUOTE __allegro_KEY_BACKQUOTE +#define KEY_SEMICOLON __allegro_KEY_SEMICOLON +#define KEY_COMMAND __allegro_KEY_COMMAND +#define KEY_UNKNOWN1 __allegro_KEY_UNKNOWN1 +#define KEY_UNKNOWN2 __allegro_KEY_UNKNOWN2 +#define KEY_UNKNOWN3 __allegro_KEY_UNKNOWN3 +#define KEY_UNKNOWN4 __allegro_KEY_UNKNOWN4 +#define KEY_UNKNOWN5 __allegro_KEY_UNKNOWN5 +#define KEY_UNKNOWN6 __allegro_KEY_UNKNOWN6 +#define KEY_UNKNOWN7 __allegro_KEY_UNKNOWN7 +#define KEY_UNKNOWN8 __allegro_KEY_UNKNOWN8 + +#define KEY_MODIFIERS __allegro_KEY_MODIFIERS + +#define KEY_LSHIFT __allegro_KEY_LSHIFT +#define KEY_RSHIFT __allegro_KEY_RSHIFT +#define KEY_LCONTROL __allegro_KEY_LCONTROL +#define KEY_RCONTROL __allegro_KEY_RCONTROL +#define KEY_ALT __allegro_KEY_ALT +#define KEY_ALTGR __allegro_KEY_ALTGR +#define KEY_LWIN __allegro_KEY_LWIN +#define KEY_RWIN __allegro_KEY_RWIN +#define KEY_MENU __allegro_KEY_MENU +#define KEY_SCRLOCK __allegro_KEY_SCRLOCK +#define KEY_NUMLOCK __allegro_KEY_NUMLOCK +#define KEY_CAPSLOCK __allegro_KEY_CAPSLOCK + +#define KEY_MAX __allegro_KEY_MAX AL_FUNC(bool, keyboard_needs_poll, (void)); AL_FUNC(int, poll_keyboard, (void)); @@ -183,7 +337,7 @@ AL_FUNC(void, simulate_keypress, (int keycode)); AL_FUNC(void, simulate_ukeypress, (int keycode, int scancode)); AL_FUNC(bool, keypressed, (void)); -AL_FUNC(Common::KeyState, readkey, (void)); +AL_FUNC(int, readkey, (void)); } // namespace AGS3 From e70cd3b62628ba5f21961e138da44cfb219855ad Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 17 Jan 2021 21:47:35 -0800 Subject: [PATCH 135/215] AGS: Fix assert on ClearRect with invalid coordinates --- engines/ags/engine/gfx/gfxfilter_allegro.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/ags/engine/gfx/gfxfilter_allegro.cpp b/engines/ags/engine/gfx/gfxfilter_allegro.cpp index aa24f8c3b4d2..0392f173fe89 100644 --- a/engines/ags/engine/gfx/gfxfilter_allegro.cpp +++ b/engines/ags/engine/gfx/gfxfilter_allegro.cpp @@ -115,7 +115,8 @@ void AllegroGfxFilter::RenderScreenFlipped(Bitmap *toRender, int x, int y, Globa } void AllegroGfxFilter::ClearRect(int x1, int y1, int x2, int y2, int color) { - if (!realScreen) return; + if (!realScreen || x2 < x1 || y2 < y1) + return; Rect r = _scaling.ScaleRange(Rect(x1, y1, x2, y2)); realScreen->FillRect(r, color); } From 8977ad44f67bc4b07d5a3e4ee30d322c4dbdf571 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 10:10:51 -0800 Subject: [PATCH 136/215] AGS: Fix unreachable code warnings --- engines/ags/engine/ac/global_button.cpp | 2 -- engines/ags/lib/allegro/gfx.cpp | 3 --- 2 files changed, 5 deletions(-) diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp index 77508d1f5e09..db72fbebb2a3 100644 --- a/engines/ags/engine/ac/global_button.cpp +++ b/engines/ags/engine/ac/global_button.cpp @@ -81,8 +81,6 @@ int GetButtonPic(int guin, int objn, int ptype) { } else { // pushed pic return guil->PushedImage; } - - quit("internal error in getbuttonpic"); } void SetButtonPic(int guin, int objn, int ptype, int slotn) { diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index c35184d27be6..df0f0ea2e855 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -406,13 +406,10 @@ int getpixel(BITMAP *bmp, int x, int y) { switch (surf.format.bytesPerPixel) { case 1: return *((uint8 *)p); - break; case 2: return *((uint16 *)p); - break; case 4: return *((uint32 *)p); - break; default: break; } From 82c458a0f6c30c49910fb68f47905ec31f24b9c6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 10:14:08 -0800 Subject: [PATCH 137/215] AGS: Fix some overflow warnings --- engines/ags/ags.cpp | 4 ++-- engines/ags/engine/script/cc_instance.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 822737d3b2b7..1a0805f45d70 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -193,8 +193,8 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { } #endif else if ((scumm_stricmp(arg, "--testre") == 0) && (ee < argc - 2)) { - strcpy(return_to_roomedit, argv[ee + 1]); - strcpy(return_to_room, argv[ee + 2]); + strncpy(return_to_roomedit, argv[ee + 1], 30); + strncpy(return_to_room, argv[ee + 2], 150); ee += 2; } else if (scumm_stricmp(arg, "-noexceptionhandler") == 0) usetup.disable_exception_handling = true; else if (scumm_stricmp(arg, "--setup") == 0) { diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index f239f121736e..3bf2d855690e 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -301,7 +301,7 @@ int ccInstance::CallScriptFunction(const char *funcname, int32_t numargs, const int32_t startat = -1; int k; char mangledName[200]; - sprintf(mangledName, "%s$", funcname); + snprintf(mangledName, 200, "%s$", funcname); for (k = 0; k < instanceof->numexports; k++) { char *thisExportName = instanceof->exports[k]; @@ -1239,7 +1239,7 @@ void ccInstance::GetScriptPosition(ScriptPosition &script_pos) { RuntimeScriptValue ccInstance::GetSymbolAddress(const char *symname) { int k; char altName[200]; - sprintf(altName, "%s$", symname); + snprintf(altName, 200, "%s$", symname); RuntimeScriptValue rval_null; for (k = 0; k < instanceof->numexports; k++) { From 375a6a9920328b450b95e67c0283e2d46af1e91f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 10:45:39 -0800 Subject: [PATCH 138/215] AGS: Fix more unreachable code warnings --- engines/ags/ags.cpp | 2 - engines/ags/engine/ac/global_game.cpp | 126 +++----------------------- 2 files changed, 11 insertions(+), 117 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 1a0805f45d70..439e42e5a931 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -406,8 +406,6 @@ Common::Error AGSEngine::run() { return initialize_engine_with_exception_handling(initialize_engine, startup_opts); } #endif - - return Common::kNoError; } SaveStateList AGSEngine::listSaves() const { diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 11484566304b..9235c76b697b 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -603,329 +603,229 @@ void GetLocationName(int xxx, int yyy, char *tempo) { } int IsKeyPressed(int keycode) { -#ifdef ALLEGRO_KEYBOARD_HANDLER if (keyboard_needs_poll()) poll_keyboard(); switch (keycode) { case eAGSKeyCodeBackspace: return ags_iskeypressed(__allegro_KEY_BACKSPACE); - break; case eAGSKeyCodeTab: return ags_iskeypressed(__allegro_KEY_TAB); - break; case eAGSKeyCodeReturn: return ags_iskeypressed(__allegro_KEY_ENTER) || ags_iskeypressed(__allegro_KEY_ENTER_PAD); - break; case eAGSKeyCodeEscape: return ags_iskeypressed(__allegro_KEY_ESC); - break; case eAGSKeyCodeSpace: return ags_iskeypressed(__allegro_KEY_SPACE); - break; case eAGSKeyCodeSingleQuote: return ags_iskeypressed(__allegro_KEY_QUOTE); - break; case eAGSKeyCodeComma: return ags_iskeypressed(__allegro_KEY_COMMA); - break; case eAGSKeyCodePeriod: return ags_iskeypressed(__allegro_KEY_STOP); - break; case eAGSKeyCodeForwardSlash: return ags_iskeypressed(__allegro_KEY_SLASH) || ags_iskeypressed(__allegro_KEY_SLASH_PAD); - break; case eAGSKeyCodeBackSlash: return ags_iskeypressed(__allegro_KEY_BACKSLASH) || ags_iskeypressed(__allegro_KEY_BACKSLASH2); - break; case eAGSKeyCodeSemiColon: return ags_iskeypressed(__allegro_KEY_SEMICOLON); - break; case eAGSKeyCodeEquals: return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_EQUALS_PAD); - break; case eAGSKeyCodeOpenBracket: return ags_iskeypressed(__allegro_KEY_OPENBRACE); - break; case eAGSKeyCodeCloseBracket: return ags_iskeypressed(__allegro_KEY_CLOSEBRACE); - break; - // NOTE: we're treating EQUALS like PLUS, even though it is only available shifted. + // NOTE: we're treating EQUALS like PLUS, even though it is only available shifted. case eAGSKeyCodePlus: return ags_iskeypressed(__allegro_KEY_EQUALS) || ags_iskeypressed(__allegro_KEY_PLUS_PAD); - break; case eAGSKeyCodeHyphen: return ags_iskeypressed(__allegro_KEY_MINUS) || ags_iskeypressed(__allegro_KEY_MINUS_PAD); - break; - // non-shifted versions of keys + // non-shifted versions of keys case eAGSKeyCodeColon: return ags_iskeypressed(__allegro_KEY_COLON) || ags_iskeypressed(__allegro_KEY_COLON2); - break; case eAGSKeyCodeAsterisk: return ags_iskeypressed(__allegro_KEY_ASTERISK); - break; case eAGSKeyCodeAt: return ags_iskeypressed(__allegro_KEY_AT); - break; case eAGSKeyCode0: return ags_iskeypressed(__allegro_KEY_0); - break; case eAGSKeyCode1: return ags_iskeypressed(__allegro_KEY_1); - break; case eAGSKeyCode2: return ags_iskeypressed(__allegro_KEY_2); - break; case eAGSKeyCode3: return ags_iskeypressed(__allegro_KEY_3); - break; case eAGSKeyCode4: return ags_iskeypressed(__allegro_KEY_4); - break; case eAGSKeyCode5: return ags_iskeypressed(__allegro_KEY_5); - break; case eAGSKeyCode6: return ags_iskeypressed(__allegro_KEY_6); - break; case eAGSKeyCode7: return ags_iskeypressed(__allegro_KEY_7); - break; case eAGSKeyCode8: return ags_iskeypressed(__allegro_KEY_8); - break; case eAGSKeyCode9: return ags_iskeypressed(__allegro_KEY_9); - break; case eAGSKeyCodeA: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('A')); - break; case eAGSKeyCodeB: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('B')); - break; case eAGSKeyCodeC: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('C')); - break; case eAGSKeyCodeD: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('D')); - break; case eAGSKeyCodeE: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('E')); - break; case eAGSKeyCodeF: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('F')); - break; case eAGSKeyCodeG: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('G')); - break; case eAGSKeyCodeH: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('H')); - break; case eAGSKeyCodeI: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('I')); - break; case eAGSKeyCodeJ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('J')); - break; case eAGSKeyCodeK: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('K')); - break; case eAGSKeyCodeL: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('L')); - break; case eAGSKeyCodeM: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('M')); - break; case eAGSKeyCodeN: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('N')); - break; case eAGSKeyCodeO: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('O')); - break; case eAGSKeyCodeP: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('P')); - break; case eAGSKeyCodeQ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Q')); - break; case eAGSKeyCodeR: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('R')); - break; case eAGSKeyCodeS: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('S')); - break; case eAGSKeyCodeT: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('T')); - break; case eAGSKeyCodeU: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('U')); - break; case eAGSKeyCodeV: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('V')); - break; case eAGSKeyCodeW: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('W')); - break; case eAGSKeyCodeX: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('X')); - break; case eAGSKeyCodeY: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Y')); - break; case eAGSKeyCodeZ: return ags_iskeypressed(platform->ConvertKeycodeToScanCode('Z')); - break; case eAGSKeyCodeF1: return ags_iskeypressed(__allegro_KEY_F1); - break; case eAGSKeyCodeF2: return ags_iskeypressed(__allegro_KEY_F2); - break; case eAGSKeyCodeF3: return ags_iskeypressed(__allegro_KEY_F3); - break; case eAGSKeyCodeF4: return ags_iskeypressed(__allegro_KEY_F4); - break; case eAGSKeyCodeF5: return ags_iskeypressed(__allegro_KEY_F5); - break; case eAGSKeyCodeF6: return ags_iskeypressed(__allegro_KEY_F6); - break; case eAGSKeyCodeF7: return ags_iskeypressed(__allegro_KEY_F7); - break; case eAGSKeyCodeF8: return ags_iskeypressed(__allegro_KEY_F8); - break; case eAGSKeyCodeF9: return ags_iskeypressed(__allegro_KEY_F9); - break; case eAGSKeyCodeF10: return ags_iskeypressed(__allegro_KEY_F10); - break; case eAGSKeyCodeF11: return ags_iskeypressed(__allegro_KEY_F11); - break; case eAGSKeyCodeF12: return ags_iskeypressed(__allegro_KEY_F12); - break; case eAGSKeyCodeHome: return ags_iskeypressed(__allegro_KEY_HOME) || ags_iskeypressed(__allegro_KEY_7_PAD); - break; case eAGSKeyCodeUpArrow: return ags_iskeypressed(__allegro_KEY_UP) || ags_iskeypressed(__allegro_KEY_8_PAD); - break; case eAGSKeyCodePageUp: return ags_iskeypressed(__allegro_KEY_PGUP) || ags_iskeypressed(__allegro_KEY_9_PAD); - break; case eAGSKeyCodeLeftArrow: return ags_iskeypressed(__allegro_KEY_LEFT) || ags_iskeypressed(__allegro_KEY_4_PAD); - break; case eAGSKeyCodeNumPad5: return ags_iskeypressed(__allegro_KEY_5_PAD); - break; case eAGSKeyCodeRightArrow: return ags_iskeypressed(__allegro_KEY_RIGHT) || ags_iskeypressed(__allegro_KEY_6_PAD); - break; case eAGSKeyCodeEnd: return ags_iskeypressed(__allegro_KEY_END) || ags_iskeypressed(__allegro_KEY_1_PAD); - break; case eAGSKeyCodeDownArrow: return ags_iskeypressed(__allegro_KEY_DOWN) || ags_iskeypressed(__allegro_KEY_2_PAD); - break; case eAGSKeyCodePageDown: return ags_iskeypressed(__allegro_KEY_PGDN) || ags_iskeypressed(__allegro_KEY_3_PAD); - break; case eAGSKeyCodeInsert: return ags_iskeypressed(__allegro_KEY_INSERT) || ags_iskeypressed(__allegro_KEY_0_PAD); - break; case eAGSKeyCodeDelete: return ags_iskeypressed(__allegro_KEY_DEL) || ags_iskeypressed(__allegro_KEY_DEL_PAD); - break; - // These keys are not defined in the eAGSKey enum but are in the manual - // https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html + // These keys are not defined in the eAGSKey enum but are in the manual + // https://adventuregamestudio.github.io/ags-manual/ASCIIcodes.html case 403: return ags_iskeypressed(__allegro_KEY_LSHIFT); - break; case 404: return ags_iskeypressed(__allegro_KEY_RSHIFT); - break; case 405: return ags_iskeypressed(__allegro_KEY_LCONTROL); - break; case 406: return ags_iskeypressed(__allegro_KEY_RCONTROL); - break; case 407: return ags_iskeypressed(__allegro_KEY_ALT); - break; - // (noted here for interest) - // The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes. - // These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints. + // (noted here for interest) + // The following are the AGS_EXT_KEY_SHIFT, derived from applying arithmetic to the original keycodes. + // These do not have a corresponding ags key enum, do not appear in the manual and may not be accessible because of OS contraints. case 392: return ags_iskeypressed(__allegro_KEY_PRTSCR); - break; case 393: return ags_iskeypressed(__allegro_KEY_PAUSE); - break; case 394: return ags_iskeypressed(__allegro_KEY_ABNT_C1); - break; // The ABNT_C1 (Brazilian) key case 395: return ags_iskeypressed(__allegro_KEY_YEN); - break; case 396: return ags_iskeypressed(__allegro_KEY_KANA); - break; case 397: return ags_iskeypressed(__allegro_KEY_CONVERT); - break; case 398: return ags_iskeypressed(__allegro_KEY_NOCONVERT); - break; case 400: return ags_iskeypressed(__allegro_KEY_CIRCUMFLEX); - break; case 402: return ags_iskeypressed(__allegro_KEY_KANJI); - break; case 420: return ags_iskeypressed(__allegro_KEY_ALTGR); - break; case 421: return ags_iskeypressed(__allegro_KEY_LWIN); - break; case 422: return ags_iskeypressed(__allegro_KEY_RWIN); - break; case 423: return ags_iskeypressed(__allegro_KEY_MENU); - break; case 424: return ags_iskeypressed(__allegro_KEY_SCRLOCK); - break; case 425: return ags_iskeypressed(__allegro_KEY_NUMLOCK); - break; case 426: return ags_iskeypressed(__allegro_KEY_CAPSLOCK); - break; - // Allegro4 keys that were never supported: - // __allegro_KEY_COMMAND - // __allegro_KEY_TILDE - // __allegro_KEY_BACKQUOTE + // Allegro4 keys that were never supported: + // __allegro_KEY_COMMAND + // __allegro_KEY_TILDE + // __allegro_KEY_BACKQUOTE default: // Remaining Allegro4 keycodes are offset by AGS_EXT_KEY_SHIFT @@ -937,10 +837,6 @@ int IsKeyPressed(int keycode) { debug_script_log("IsKeyPressed: unsupported keycode %d", keycode); return 0; } -#else - // old allegro version - quit("allegro keyboard handler not in use??"); -#endif } int SaveScreenShot(const char *namm) { From 361a91d84b9863cec5f39071b423372441fe3ba6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 11:14:56 -0800 Subject: [PATCH 139/215] AGS: Beginnings of new Globals class --- engines/ags/ags.cpp | 6 +++- engines/ags/ags.h | 5 +++ engines/ags/engine/ac/game.cpp | 1 - engines/ags/engine/debugging/debug.cpp | 10 +++--- engines/ags/engine/globals.cpp | 37 +++++++++++++++++++ engines/ags/engine/globals.h | 44 +++++++++++++++++++++++ engines/ags/engine/main/engine.cpp | 1 - engines/ags/engine/main/game_run.cpp | 14 ++++---- engines/ags/engine/main/game_start.cpp | 1 - engines/ags/engine/main/quit.cpp | 4 +-- engines/ags/engine/media/audio/audio.cpp | 2 -- engines/ags/engine/script/cc_instance.cpp | 6 ++-- engines/ags/events.cpp | 6 ++-- engines/ags/module.mk | 1 + engines/ags/shared/ac/common.cpp | 4 +-- 15 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 engines/ags/engine/globals.cpp create mode 100644 engines/ags/engine/globals.h diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 439e42e5a931..f0f01d6fd3e8 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -37,6 +37,7 @@ #include "ags/lib/std/set.h" #include "ags/shared/ac/common.h" #include "ags/engine/ac/game.h" +#include "ags/engine/globals.h" #include "ags/engine/ac/gamesetup.h" #include "ags/engine/ac/gamestate.h" #include "ags/shared/core/def_version.h" @@ -328,13 +329,15 @@ AGSEngine *g_vm; AGSEngine::AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _randomSource("AGS"), _events(nullptr), _music(nullptr), - _rawScreen(nullptr), _screen(nullptr), _gfxDriver(nullptr) { + _rawScreen(nullptr), _screen(nullptr), _gfxDriver(nullptr), + _globals(nullptr) { g_vm = this; DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); DebugMan.addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level"); _events = new EventsManager(); _music = new Music(_mixer); + _globals = new ::AGS3::Globals(); } AGSEngine::~AGSEngine() { @@ -342,6 +345,7 @@ AGSEngine::~AGSEngine() { delete _rawScreen; delete _events; delete _music; + delete _globals; } uint32 AGSEngine::getFeatures() const { diff --git a/engines/ags/ags.h b/engines/ags/ags.h index 982bf66d54ce..2c6b3b1ffd0e 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -37,6 +37,10 @@ #include "ags/lib/allegro/system.h" #include "ags/engine/util/mutex_std.h" +namespace AGS3 { +class Globals; +} + namespace AGS { #define SCREEN_WIDTH 320 @@ -64,6 +68,7 @@ class AGSEngine : public Engine { ::AGS3::AGS::Engine::Mutex _sMutex; ::AGS3::AGS::Engine::Mutex _soundCacheMutex; ::AGS3::AGS::Engine::Mutex _mp3Mutex; + ::AGS3::Globals *_globals; protected: // Engine APIs virtual Common::Error run(); diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 26f275be2636..9b61c47468c3 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -158,7 +158,6 @@ RoomStruct thisroom; volatile int switching_away_from_game = 0; volatile bool switched_away = false; -volatile char want_exit = 0, abort_engine = 0; GameDataVersion loaded_game_file_version = kGameVersion_Undefined; int frames_per_second = 40; int displayed_room = -10, starting_room = -1; diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index 9fc93fbf7eb6..c2454a27fd0c 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -44,6 +44,7 @@ #include "ags/shared/script/cc_error.h" #include "ags/shared/util/string_utils.h" #include "ags/shared/util/textstreamwriter.h" +#include "ags/engine/globals.h" #include "ags/events.h" #if AGS_PLATFORM_OS_WINDOWS @@ -59,7 +60,6 @@ extern char check_dynamic_sprites_at_exit; extern int displayed_room; extern RoomStruct thisroom; extern char pexbuf[STD_BUFFER_SIZE]; -extern volatile char want_exit, abort_engine; extern GameSetupStruct game; @@ -471,8 +471,8 @@ int check_for_messages_from_editor() { game_paused_in_debugger = 0; break_on_next_script_step = 1; } else if (strncmp(msgPtr, "EXIT", 4) == 0) { - want_exit = 1; - abort_engine = 1; + _G(want_exit) = 1; + _G(abort_engine) = 1; check_dynamic_sprites_at_exit = 0; } @@ -488,7 +488,7 @@ int check_for_messages_from_editor() { bool send_exception_to_editor(const char *qmsg) { #if AGS_PLATFORM_OS_WINDOWS - want_exit = 0; + _G(want_exit) = 0; // allow the editor to break with the error message if (editor_window_handle != NULL) SetForegroundWindow(editor_window_handle); @@ -496,7 +496,7 @@ bool send_exception_to_editor(const char *qmsg) { if (!send_message_to_editor("ERROR", qmsg)) return false; - while ((check_for_messages_from_editor() == 0) && (want_exit == 0)) { + while ((check_for_messages_from_editor() == 0) && (_G(want_exit) == 0)) { update_polled_mp3(); platform->Delay(10); } diff --git a/engines/ags/engine/globals.cpp b/engines/ags/engine/globals.cpp new file mode 100644 index 000000000000..af4b56a69d52 --- /dev/null +++ b/engines/ags/engine/globals.cpp @@ -0,0 +1,37 @@ +/* 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 "ags/engine/globals.h" + +namespace AGS3 { + +Globals *g_globals; + +Globals::Globals() : _want_exit(false), _abort_engine(false) { + g_globals = this; +} + +Globals::~Globals() { + g_globals = nullptr; +} + +} // namespace AGS3 diff --git a/engines/ags/engine/globals.h b/engines/ags/engine/globals.h new file mode 100644 index 000000000000..6de237a01cf0 --- /dev/null +++ b/engines/ags/engine/globals.h @@ -0,0 +1,44 @@ +/* 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 AGS_ENGINE_GLOBALS_H +#define AGS_ENGINE_GLOBALS_H + +namespace AGS3 { + +class Globals { +public: + bool _want_exit; + bool _abort_engine; + +public: + Globals(); + ~Globals(); +}; + +extern Globals *g_globals; + +#define _G(FIELD) (::AGS3::g_globals->_##FIELD) + +} // namespace AGS3 + +#endif diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 7d128c19a12d..41192bc72fbb 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -89,7 +89,6 @@ using namespace AGS::Engine; extern char check_dynamic_sprites_at_exit; extern int our_eip; -extern volatile char want_exit, abort_engine; extern bool justRunSetup; extern GameSetup usetup; extern GameSetupStruct game; diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 4870b1c27540..173e3dd998f1 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -66,6 +66,7 @@ #include "ags/engine/ac/timer.h" #include "ags/engine/ac/keycode.h" #include "ags/lib/allegro/keyboard.h" +#include "ags/engine/globals.h" #include "ags/events.h" namespace AGS3 { @@ -77,7 +78,6 @@ extern int numAnimButs; extern int mouse_on_iface; // mouse cursor is over this interface extern int ifacepopped; extern int is_text_overlay; -extern volatile char want_exit, abort_engine; extern int proper_exit, our_eip; extern int displayed_room, starting_room, in_new_room, new_room_was; extern GameSetupStruct game; @@ -124,7 +124,7 @@ unsigned int loopcounter = 0; static unsigned int lastcounter = 0; static void ProperExit() { - want_exit = 0; + _G(want_exit) = 0; proper_exit = 1; quit("||exit!"); } @@ -737,7 +737,7 @@ void UpdateGameOnce(bool checkControls, IDriverDependantBitmap *extraBitmap, int numEventsAtStartOfFunction = numevents; - if (want_exit) { + if (_G(want_exit)) { ProperExit(); } @@ -944,7 +944,7 @@ static void GameLoopUntilEvent(int untilwhat, const void *daaa) { auto cached_user_disabled_for = user_disabled_for; SetupLoopParameters(untilwhat, daaa); - while (GameTick() == 0 && !abort_engine) { + while (GameTick() == 0 && !_G(abort_engine)) { } our_eip = 78; @@ -992,7 +992,7 @@ void RunGameUntilAborted() { // skip ticks to account for time spent starting game. skipMissedTicks(); - while (!abort_engine) { + while (!_G(abort_engine)) { GameTick(); if (load_new_game) { @@ -1003,8 +1003,8 @@ void RunGameUntilAborted() { } void update_polled_stuff_if_runtime() { - if (want_exit) { - want_exit = 0; + if (_G(want_exit)) { + _G(want_exit) = 0; quit("||exit!"); } diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 681ee8f85886..47fe112aac8f 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -51,7 +51,6 @@ using namespace AGS::Shared; using namespace AGS::Engine; extern int our_eip, displayed_room; -extern volatile char want_exit, abort_engine; extern GameSetupStruct game; extern GameState play; extern const char *loadSaveGameOnStartup; diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index f8fa75c2159f..45a1edcc8698 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -46,6 +46,7 @@ #include "ags/shared/core/assetmanager.h" #include "ags/engine/plugin/plugin_engine.h" #include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/globals.h" #include "ags/ags.h" namespace AGS3 { @@ -67,7 +68,6 @@ extern IAGSEditorDebugger *editor_debugger; extern int need_to_stop_cd; extern int use_cdplayer; extern IGraphicsDriver *gfxDriver; -extern volatile char abort_engine; bool handledErrorInEditor; @@ -233,7 +233,7 @@ char quit_message[256] = "\0"; // "!|" is a special code used to mean that the player has aborted (Alt+X) void quit(const char *quitmsg) { strncpy(quit_message, quitmsg, 256); - abort_engine = true; + _G(abort_engine) = true; } void quit_free() { diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 21e7aef89170..90b4a96829a0 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -844,8 +844,6 @@ void update_volume_drop_if_voiceover() { apply_volume_drop_modifier(play.speech_has_voice); } -extern volatile char want_exit; - void update_mp3_thread() { if (switching_away_from_game) { return; diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp index 3bf2d855690e..53ea6aa4f7ef 100644 --- a/engines/ags/engine/script/cc_instance.cpp +++ b/engines/ags/engine/script/cc_instance.cpp @@ -20,8 +20,6 @@ * */ -//include -//include #include "ags/shared/ac/common.h" #include "ags/engine/ac/dynobj/cc_dynamicarray.h" #include "ags/engine/ac/dynobj/managedobjectpool.h" @@ -45,6 +43,7 @@ #include "ags/engine/ac/dynobj/cc_dynamicobject_addr_and_manager.h" #include "ags/shared/util/memory.h" #include "ags/shared/util/string_utils.h" // linux strnicmp definition +#include "ags/engine/globals.h" namespace AGS3 { @@ -58,7 +57,6 @@ extern int maxWhileLoops; extern new_line_hook_type new_line_hook; extern ScriptString myScriptStringImpl; -extern volatile char abort_engine; enum ScriptOpArgIsReg { kScOpNoArgIsReg = 0, @@ -435,7 +433,7 @@ int ccInstance::Run(int32_t curpc) { FunctionCallStack func_callstack; while (1) { - if (abort_engine) + if (_G(abort_engine)) return -1; /* diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp index 8a6c7a2a6141..3bff16c29672 100644 --- a/engines/ags/events.cpp +++ b/engines/ags/events.cpp @@ -22,9 +22,9 @@ #include "ags/events.h" #include "common/system.h" +#include "ags/engine/globals.h" namespace AGS3 { -extern volatile char want_exit, abort_engine; extern char check_dynamic_sprites_at_exit; } @@ -46,8 +46,8 @@ void EventsManager::pollEvents() { while (g_system->getEventManager()->pollEvent(e)) { if (e.type == Common::EVENT_QUIT) { - ::AGS3::want_exit = 1; - ::AGS3::abort_engine = 1; + _G(want_exit) = true; + _G(abort_engine) = true; ::AGS3::check_dynamic_sprites_at_exit = 0; } else if (e.type == Common::EVENT_KEYDOWN) { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 2520fbb6f1b7..e31bfb893827 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -102,6 +102,7 @@ MODULE_OBJS = \ shared/util/textstreamwriter.o \ shared/util/version.o \ shared/util/wgt2allg.o \ + engine/globals.o \ engine/ac/dynobj/cc_agsdynamicobject.o \ engine/ac/dynobj/cc_audiochannel.o \ engine/ac/dynobj/cc_audioclip.o \ diff --git a/engines/ags/shared/ac/common.cpp b/engines/ags/shared/ac/common.cpp index 57caf4820efd..310fe5202852 100644 --- a/engines/ags/shared/ac/common.cpp +++ b/engines/ags/shared/ac/common.cpp @@ -22,6 +22,7 @@ #include "ags/shared/ac/common.h" #include "ags/shared/util/string.h" +#include "ags/engine/globals.h" #include "ags/ags.h" namespace AGS3 { @@ -29,7 +30,6 @@ namespace AGS3 { using namespace AGS::Shared; const char *game_file_sig = "Adventure Creator Game File v2"; -extern volatile char abort_engine; void quitprintf(const char *fmt, ...) { va_list ap; @@ -37,7 +37,7 @@ void quitprintf(const char *fmt, ...) { String text = String::FromFormatV(fmt, ap); va_end(ap); - if (!abort_engine) + if (!_G(abort_engine)) ::AGS::g_vm->GUIError(text); quit(text); } From b7ffc3b6a602037627140ce9308732eef0b225d8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 11:57:15 -0800 Subject: [PATCH 140/215] AGS: Mark engine with 16bit requirement --- engines/ags/configure.engine | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/configure.engine b/engines/ags/configure.engine index 0fb88d9de149..18e126e1677b 100644 --- a/engines/ags/configure.engine +++ b/engines/ags/configure.engine @@ -1,4 +1,4 @@ # This file is included from the main "configure" script # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] -add_engine ags "Adventure Game Studio" no "ags_tests" "" "cxx11" +add_engine ags "Adventure Game Studio" no "ags_tests" "" "cxx11 16bit" add_engine ags_tests "AGS Tests" no "" "" "" From b673255bc9e09c6a6e6f45762adef43a9d3b4c0d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 13:34:01 -0800 Subject: [PATCH 141/215] AGS: Move globals from ags.cpp to Globals --- engines/ags/ags.cpp | 103 ++-- engines/ags/engine/ac/game.cpp | 2 +- engines/ags/engine/ac/global_debug.cpp | 3 +- engines/ags/engine/ac/global_game.cpp | 2 +- engines/ags/engine/ac/room.cpp | 7 +- engines/ags/engine/ac/system.cpp | 3 +- engines/ags/engine/game/savegame.cpp | 9 +- engines/ags/engine/gfx/gfx_util.cpp | 4 +- engines/ags/engine/globals.cpp | 2 +- engines/ags/engine/globals.h | 70 ++- engines/ags/engine/main/config.cpp | 41 +- engines/ags/engine/main/engine.cpp | 54 +- engines/ags/engine/main/game_start.cpp | 8 +- engines/ags/engine/main/main.cpp | 465 ------------------ engines/ags/engine/main/main.h | 33 -- engines/ags/engine/main/quit.cpp | 6 +- engines/ags/engine/media/audio/soundcache.cpp | 19 +- engines/ags/engine/media/audio/soundcache.h | 5 - engines/ags/engine/util/library_posix.h | 5 +- engines/ags/music.cpp | 3 +- 20 files changed, 176 insertions(+), 668 deletions(-) delete mode 100644 engines/ags/engine/main/main.cpp diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index f0f01d6fd3e8..aca6d6e16525 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -69,12 +69,6 @@ using namespace Engine; extern HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten); -String appDirectory; // Needed for library loading -String cmdGameDataPath; - -const char **global_argv = nullptr; -int global_argc = 0; - extern GameSetup usetup; extern GameState play; extern int our_eip; @@ -84,38 +78,6 @@ extern int editor_debugging_enabled; extern int editor_debugging_initialized; extern char editor_debugger_instance_token[100]; - -// Startup flags, set from parameters to engine -int force_window = 0; -int override_start_room = 0; -bool justDisplayHelp = false; -bool justDisplayVersion = false; -bool justRunSetup = false; -bool justRegisterGame = false; -bool justUnRegisterGame = false; -bool justTellInfo = false; -std::set tellInfoKeys; -const char *loadSaveGameOnStartup = nullptr; - -#if ! AGS_PLATFORM_DEFINES_PSP_VARS -int psp_video_framedrop = 1; -int psp_audio_enabled = 1; -int psp_midi_enabled = 1; -int psp_ignore_acsetup_cfg_file = 0; -int psp_clear_cache_on_room_change = 0; - -int psp_midi_preload_patches = 0; -int psp_audio_cachesize = 10; -char psp_game_file_name[] = ""; -char psp_translation[] = "default"; - -int psp_gfx_renderer = 0; -int psp_gfx_scaling = 1; -int psp_gfx_smoothing = 0; -int psp_gfx_super_sampling = 1; -int psp_gfx_smooth_sprites = 0; -#endif - // this needs to be updated if the "play" struct changes #define SVG_VERSION_BWCOMPAT_MAJOR 3 #define SVG_VERSION_BWCOMPAT_MINOR 2 @@ -128,13 +90,6 @@ int psp_gfx_smooth_sprites = 0; #define SVG_VERSION_FWCOMPAT_RELEASE 1 #define SVG_VERSION_FWCOMPAT_REVISION 1111 -// Current engine version -Version EngineVersion; -// Lowest savedgame version, accepted by this engine -Version SavedgameLowestBackwardCompatVersion; -// Lowest engine version, which would accept current savedgames -Version SavedgameLowestForwardCompatVersion; - extern void quit_free(); void main_pre_init() { @@ -148,23 +103,23 @@ void main_create_platform_driver() { } void main_init(int argc, const char *argv[]) { - EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); + _G(EngineVersion) = Version(ACI_VERSION_STR " " SPECIAL_VERSION); - SavedgameLowestBackwardCompatVersion = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); - SavedgameLowestForwardCompatVersion = Version(SVG_VERSION_FWCOMPAT_MAJOR, SVG_VERSION_FWCOMPAT_MINOR, SVG_VERSION_FWCOMPAT_RELEASE, SVG_VERSION_FWCOMPAT_REVISION); + _G(SavedgameLowestBackwardCompatVersion) = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); + _G(SavedgameLowestForwardCompatVersion) = Version(SVG_VERSION_FWCOMPAT_MAJOR, SVG_VERSION_FWCOMPAT_MINOR, SVG_VERSION_FWCOMPAT_RELEASE, SVG_VERSION_FWCOMPAT_REVISION); Shared::AssetManager::CreateInstance(); main_pre_init(); main_create_platform_driver(); - global_argv = argv; - global_argc = argc; + _G(global_argv) = argv; + _G(global_argc) = argc; } String get_engine_string() { return String::FromFormat("Adventure Game Studio v%s Interpreter\n" "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" - "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); + "ACI version %s\n", _G(EngineVersion).ShortString.GetCStr(), _G(EngineVersion).LongString.GetCStr()); } void main_print_help() { @@ -179,17 +134,17 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { // Startup options // if (scumm_stricmp(arg, "--help") == 0 || scumm_stricmp(arg, "/?") == 0 || scumm_stricmp(arg, "-?") == 0) { - justDisplayHelp = true; + _G(justDisplayHelp) = true; return 0; } if (scumm_stricmp(arg, "-v") == 0 || scumm_stricmp(arg, "--version") == 0) { - justDisplayVersion = true; + _G(justDisplayVersion) = true; return 0; } else if (scumm_stricmp(arg, "-updatereg") == 0) debug_flags |= DBG_REGONLY; #if AGS_PLATFORM_DEBUG else if ((scumm_stricmp(arg, "--startr") == 0) && (ee < argc - 1)) { - override_start_room = atoi(argv[ee + 1]); + _G(override_start_room) = atoi(argv[ee + 1]); ee++; } #endif @@ -199,18 +154,18 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { ee += 2; } else if (scumm_stricmp(arg, "-noexceptionhandler") == 0) usetup.disable_exception_handling = true; else if (scumm_stricmp(arg, "--setup") == 0) { - justRunSetup = true; + _G(justRunSetup) = true; } else if (scumm_stricmp(arg, "-registergame") == 0) { - justRegisterGame = true; + _G(justRegisterGame) = true; } else if (scumm_stricmp(arg, "-unregistergame") == 0) { - justUnRegisterGame = true; + _G(justUnRegisterGame) = true; } else if ((scumm_stricmp(arg, "-loadsavedgame") == 0) && (argc > ee + 1)) { - loadSaveGameOnStartup = argv[ee + 1]; + _G(loadSaveGameOnStartup) = argv[ee + 1]; ee++; } else if ((scumm_stricmp(arg, "--enabledebugger") == 0) && (argc > ee + 1)) { strcpy(editor_debugger_instance_token, argv[ee + 1]); editor_debugging_enabled = 1; - force_window = 1; + _G(force_window) = 1; ee++; } else if (scumm_stricmp(arg, "--runfromide") == 0 && (argc > ee + 3)) { usetup.install_dir = argv[ee + 1]; @@ -226,17 +181,17 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { ee += 2; } else if (scumm_strnicmp(arg, "--tell", 6) == 0) { if (arg[6] == 0) - tellInfoKeys.insert(String("all")); + _G(tellInfoKeys).insert(String("all")); else if (arg[6] == '-' && arg[7] != 0) - tellInfoKeys.insert(String(arg + 7)); + _G(tellInfoKeys).insert(String(arg + 7)); } // // Config overrides // else if (scumm_stricmp(arg, "-windowed") == 0 || scumm_stricmp(arg, "--windowed") == 0) - force_window = 1; + _G(force_window) = 1; else if (scumm_stricmp(arg, "-fullscreen") == 0 || scumm_stricmp(arg, "--fullscreen") == 0) - force_window = 2; + _G(force_window) = 2; else if ((scumm_stricmp(arg, "-gfxdriver") == 0 || scumm_stricmp(arg, "--gfxdriver") == 0) && (argc > ee + 1)) { INIwritestring(cfg, "graphics", "driver", argv[++ee]); } else if ((scumm_stricmp(arg, "-gfxfilter") == 0 || scumm_stricmp(arg, "--gfxfilter") == 0) && (argc > ee + 1)) { @@ -267,25 +222,25 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { } if (datafile_argv > 0) { - cmdGameDataPath = argv[datafile_argv]; + _G(cmdGameDataPath) = argv[datafile_argv]; } else { // assign standard path for mobile/consoles (defined in their own platform implementation) - cmdGameDataPath = psp_game_file_name; + _G(cmdGameDataPath) = _G(psp_game_file_name); } - if (!tellInfoKeys.empty()) - justTellInfo = true; + if (!_G(tellInfoKeys).empty()) + _G(justTellInfo) = true; return 0; } void main_set_gamedir(int argc, const char *argv[]) { - appDirectory = Path::GetDirectoryPath("./"); + _G(appDirectory) = Path::GetDirectoryPath("./"); #ifdef DEPRECATED - if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) { + if ((_G(loadSaveGameOnStartup) != nullptr) && (argv[0] != nullptr)) { // When launched by double-clicking a save game file, the curdir will // be the save game folder unless we correct it - Directory::SetCurrentDirectory(appDirectory); + Directory::SetCurrentDirectory(_G(appDirectory)); } else { // It looks like Allegro library does not like ANSI (ACP) paths. // When *not* working in U_UNICODE filepath mode, whenever it gets @@ -373,19 +328,19 @@ Common::Error AGSEngine::run() { if (res != 0) return Common::kUnknownError; - if (AGS3::justDisplayVersion) { + if (_G(justDisplayVersion)) { AGS3::platform->WriteStdOut(AGS3::get_engine_string()); return Common::kNoError; } - if (AGS3::justDisplayHelp) { + if (_G(justDisplayHelp)) { AGS3::main_print_help(); return Common::kNoError; } - if (!AGS3::justTellInfo) + if (!_G(justTellInfo)) AGS3::platform->SetGUIMode(true); - AGS3::init_debug(startup_opts, AGS3::justTellInfo); + AGS3::init_debug(startup_opts, _G(justTellInfo)); AGS3::Debug::Printf("%s", AGS3::get_engine_string().GetNullableCStr()); AGS3::main_set_gamedir(ARGC, ARGV); diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 9b61c47468c3..4526adb9ab89 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -126,7 +126,7 @@ extern int numAnimButs; extern int is_complete_overlay, is_text_overlay; #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID -extern int psp_gfx_renderer; +extern int _G(psp_gfx_renderer); #endif extern int obj_lowest_yp, char_lowest_yp; diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp index e1a4aefecef0..35ae916ad84f 100644 --- a/engines/ags/engine/ac/global_debug.cpp +++ b/engines/ags/engine/ac/global_debug.cpp @@ -46,6 +46,7 @@ #include "ags/shared/gfx/bitmap.h" #include "ags/engine/gfx/graphicsdriver.h" #include "ags/engine/main/graphics_mode.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -75,7 +76,7 @@ String GetRuntimeInfo() { "[Game resolution %d x %d (%d-bit)" "[Running %d x %d at %d-bit%s%s[GFX: %s; %s[Draw frame %d x %d[" "Sprite cache size: %d KB (limit %d KB; %d locked)", - EngineVersion.LongString.GetCStr(), game.GetGameRes().Width, game.GetGameRes().Height, game.GetColorDepth(), + _G(EngineVersion).LongString.GetCStr(), game.GetGameRes().Width, game.GetGameRes().Height, game.GetColorDepth(), mode.Width, mode.Height, mode.ColorDepth, (convert_16bit_bgr) ? " BGR" : "", mode.Windowed ? " W" : "", gfxDriver->GetDriverName(), filter->GetInfo().Name.GetCStr(), diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 9235c76b697b..dd195561d80a 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -95,7 +95,7 @@ extern IGraphicsDriver *gfxDriver; extern color palette[256]; #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID -extern int psp_gfx_renderer; +extern int _G(psp_gfx_renderer); #endif void GiveScore(int amnt) { diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index 6fa660d39336..d6c04b6a02bd 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -20,8 +20,6 @@ * */ -//include // for toupper - #include "ags/shared/core/platform.h" #include "ags/shared/util/string_utils.h" //strlwr() #include "ags/shared/ac/common.h" @@ -81,6 +79,7 @@ #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" #include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -914,8 +913,6 @@ void load_new_room(int newnum, CharacterInfo *forchar) { // MSS_CHECK_ALL_BLOCKS; } -extern int psp_clear_cache_on_room_change; - // new_room: changes the current room number, and loads the new room from disk void new_room(int newnum, CharacterInfo *forchar) { EndSkippingUntilCharStops(); @@ -949,7 +946,7 @@ void new_room(int newnum, CharacterInfo *forchar) { // change rooms unload_old_room(); - if (psp_clear_cache_on_room_change) { + if (_G(psp_clear_cache_on_room_change)) { // Delete all cached sprites spriteset.DisposeAll(); diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp index 0275ec1b6a5e..abeb62a4ddb8 100644 --- a/engines/ags/engine/ac/system.cpp +++ b/engines/ags/engine/ac/system.cpp @@ -44,6 +44,7 @@ #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" #include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/globals.h" #include "ags/events.h" namespace AGS3 { @@ -110,7 +111,7 @@ int System_GetViewportWidth() { } const char *System_GetVersion() { - return CreateNewScriptString(EngineVersion.LongString); + return CreateNewScriptString(_G(EngineVersion).LongString); } int System_GetHardwareAcceleration() { diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index a5823f295643..d2deb79b9d7d 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -61,6 +61,7 @@ #include "ags/shared/util/stream.h" #include "ags/shared/util/string_utils.h" #include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/globals.h" #include "ags/ags.h" namespace AGS3 { @@ -240,11 +241,11 @@ HSaveError ReadDescription_v321(Stream *in, SavegameVersion &svg_ver, SavegameDe String version_str = String::FromStream(in); Version eng_version(version_str); - if (eng_version > EngineVersion || - eng_version < SavedgameLowestBackwardCompatVersion) { + if (eng_version > _G(EngineVersion) || + eng_version < _G(SavedgameLowestBackwardCompatVersion)) { // Engine version is either non-forward or non-backward compatible return new SavegameError(kSvgErr_IncompatibleEngine, - String::FromFormat("Required: %s, supported: %s - %s.", eng_version.LongString.GetCStr(), SavedgameLowestBackwardCompatVersion.LongString.GetCStr(), EngineVersion.LongString.GetCStr())); + String::FromFormat("Required: %s, supported: %s - %s.", eng_version.LongString.GetCStr(), _G(SavedgameLowestBackwardCompatVersion).LongString.GetCStr(), _G(EngineVersion).LongString.GetCStr())); } if (elems & kSvgDesc_EnvInfo) { desc.MainDataFilename.Read(in); @@ -672,7 +673,7 @@ void WriteDescription(Stream *out, const String &user_text, const Bitmap *user_i out->WriteInt32(kSvgVersion_Current); // Enviroment information StrUtil::WriteString("Adventure Game Studio run-time engine", out); - StrUtil::WriteString(EngineVersion.LongString, out); + StrUtil::WriteString(_G(EngineVersion).LongString, out); StrUtil::WriteString(game.guid, out); StrUtil::WriteString(game.gamename, out); StrUtil::WriteString(ResPaths.GamePak.Name, out); diff --git a/engines/ags/engine/gfx/gfx_util.cpp b/engines/ags/engine/gfx/gfx_util.cpp index d6ff6d19ae78..b1ad9e20d2fb 100644 --- a/engines/ags/engine/gfx/gfx_util.cpp +++ b/engines/ags/engine/gfx/gfx_util.cpp @@ -28,7 +28,7 @@ namespace AGS3 { // CHECKME: is this hack still relevant? #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID -extern int psp_gfx_renderer; +extern int _G(psp_gfx_renderer); #endif namespace AGS { @@ -117,7 +117,7 @@ void DrawSpriteWithTransparency(Bitmap *ds, Bitmap *sprite, int x, int y, int al if (sprite_depth < surface_depth // CHECKME: what is the purpose of this hack and is this still relevant? #if AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID - || (ds->GetBPP() < surface_depth && psp_gfx_renderer > 0) // Fix for corrupted speechbox outlines with the OGL driver + || (ds->GetBPP() < surface_depth && _G(psp_gfx_renderer) > 0) // Fix for corrupted speechbox outlines with the OGL driver #endif ) { // If sprite is lower color depth than destination surface, e.g. diff --git a/engines/ags/engine/globals.cpp b/engines/ags/engine/globals.cpp index af4b56a69d52..cd161a794e51 100644 --- a/engines/ags/engine/globals.cpp +++ b/engines/ags/engine/globals.cpp @@ -26,7 +26,7 @@ namespace AGS3 { Globals *g_globals; -Globals::Globals() : _want_exit(false), _abort_engine(false) { +Globals::Globals() { g_globals = this; } diff --git a/engines/ags/engine/globals.h b/engines/ags/engine/globals.h index 6de237a01cf0..b31251904960 100644 --- a/engines/ags/engine/globals.h +++ b/engines/ags/engine/globals.h @@ -23,12 +23,78 @@ #ifndef AGS_ENGINE_GLOBALS_H #define AGS_ENGINE_GLOBALS_H +#include "ags/shared/util/string.h" +#include "ags/shared/util/version.h" +#include "ags/lib/std/set.h" + namespace AGS3 { +using String = AGS::Shared::String; +using Version = AGS::Shared::Version; + class Globals { public: - bool _want_exit; - bool _abort_engine; + /** + * \defgroup Overall flags + * @{ + */ + + // Major overall flags + bool _want_exit = false; + bool _abort_engine = false; + + /**@}*/ + + /** + * \defgroup main globals + * @{ + */ + + String _appDirectory; // Needed for library loading + String _cmdGameDataPath; + + const char **_global_argv = nullptr; + int _global_argc = 0; + + // Startup flags, set from parameters to engine + int _force_window = 0; + int _override_start_room = 0; + bool _justDisplayHelp = false; + bool _justDisplayVersion = false; + bool _justRunSetup = false; + bool _justRegisterGame = false; + bool _justUnRegisterGame = false; + bool _justTellInfo = false; + std::set _tellInfoKeys; + const char *_loadSaveGameOnStartup = nullptr; + +#if ! AGS_PLATFORM_DEFINES_PSP_VARS + int _psp_video_framedrop = 1; + int _psp_audio_enabled = 1; + int _psp_midi_enabled = 1; + int _psp_ignore_acsetup_cfg_file = 0; + int _psp_clear_cache_on_room_change = 0; + + int _psp_midi_preload_patches = 0; + int _psp_audio_cachesize = 10; + const char *_psp_game_file_name = ""; + const char *_psp_translation = "default"; + + int _psp_gfx_renderer = 0; + int _psp_gfx_scaling = 1; + int _psp_gfx_smoothing = 0; + int _psp_gfx_super_sampling = 1; + int _psp_gfx_smooth_sprites = 0; +#endif + + // Current engine version + Version _EngineVersion; + // Lowest savedgame version, accepted by this engine + Version _SavedgameLowestBackwardCompatVersion; + // Lowest engine version, which would accept current savedgames + Version _SavedgameLowestForwardCompatVersion; + + /**@}*/ public: Globals(); diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp index 7f5d52e193dc..93b11d64e194 100644 --- a/engines/ags/engine/main/config.cpp +++ b/engines/ags/engine/main/config.cpp @@ -23,7 +23,6 @@ // // Game configuration // -//include // toupper #include "ags/shared/core/platform.h" #include "ags/engine/ac/gamesetup.h" @@ -44,6 +43,7 @@ #include "ags/shared/util/path.h" #include "ags/shared/util/string_utils.h" #include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -53,7 +53,6 @@ using namespace AGS::Engine; extern GameSetupStruct game; extern GameSetup usetup; extern SpriteCache spriteset; -extern int force_window; extern GameState play; // Filename of the default config file, the one found in the game installation @@ -385,16 +384,6 @@ void read_legacy_graphics_config(const ConfigTree &cfg) { usetup.Screen.DisplayMode.RefreshRate = INIreadint(cfg, "misc", "refresh"); } -// Variables used for mobile port configs -extern int psp_gfx_renderer; -extern int psp_gfx_scaling; -extern int psp_gfx_super_sampling; -extern int psp_gfx_smoothing; -extern int psp_gfx_smooth_sprites; -extern int psp_audio_enabled; -extern int psp_midi_enabled; -extern char psp_translation[]; - void override_config_ext(ConfigTree &cfg) { // Mobile ports always run in fullscreen mode #if AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_IOS @@ -404,35 +393,35 @@ void override_config_ext(ConfigTree &cfg) { INIwritestring(cfg, "graphics", "driver", "ScummVM"); INIwriteint(cfg, "graphics", "render_at_screenres", 1); - // psp_gfx_scaling - scaling style: + // _G(psp_gfx_scaling) - scaling style: // * 0 - no scaling // * 1 - stretch and preserve aspect ratio // * 2 - stretch to whole screen - if (psp_gfx_scaling == 0) + if (_G(psp_gfx_scaling) == 0) INIwritestring(cfg, "graphics", "game_scale_fs", "1"); - else if (psp_gfx_scaling == 1) + else if (_G(psp_gfx_scaling) == 1) INIwritestring(cfg, "graphics", "game_scale_fs", "proportional"); else INIwritestring(cfg, "graphics", "game_scale_fs", "stretch"); - // psp_gfx_smoothing - scaling filter: + // _G(psp_gfx_smoothing) - scaling filter: // * 0 - nearest-neighbour // * 1 - linear - if (psp_gfx_smoothing == 0) + if (_G(psp_gfx_smoothing) == 0) INIwritestring(cfg, "graphics", "filter", "StdScale"); else INIwritestring(cfg, "graphics", "filter", "Linear"); - // psp_gfx_super_sampling - enable super sampling + // _G(psp_gfx_super_sampling) - enable super sampling // * 0 - x1 // * 1 - x2 - if (psp_gfx_renderer == 2) - INIwriteint(cfg, "graphics", "supersampling", psp_gfx_super_sampling + 1); + if (_G(psp_gfx_renderer) == 2) + INIwriteint(cfg, "graphics", "supersampling", _G(psp_gfx_super_sampling) + 1); else INIwriteint(cfg, "graphics", "supersampling", 0); - INIwriteint(cfg, "misc", "antialias", psp_gfx_smooth_sprites != 0); - INIwritestring(cfg, "language", "translation", psp_translation); + INIwriteint(cfg, "misc", "antialias", _G(psp_gfx_smooth_sprites) != 0); + INIwritestring(cfg, "language", "translation", _G(psp_translation)); } void apply_config(const ConfigTree &cfg) { @@ -440,9 +429,9 @@ void apply_config(const ConfigTree &cfg) { // Legacy settings has to be translated into new options; // they must be read first, to let newer options override them, if ones are present read_legacy_audio_config(cfg); - if (psp_audio_enabled) { + if (_G(psp_audio_enabled)) { usetup.digicard = read_driverid(cfg, "sound", "digiid", usetup.digicard); - if (psp_midi_enabled) + if (_G(psp_midi_enabled)) usetup.midicard = read_driverid(cfg, "sound", "midiid", usetup.midicard); else usetup.midicard = MIDI_NONE; @@ -573,8 +562,8 @@ void save_config_file() { ConfigTree cfg; // Last display mode - // TODO: force_window check is a temporary workaround (see comment below) - if (force_window == 0) { + // TODO: _G(force_window) check is a temporary workaround (see comment below) + if (_G(force_window) == 0) { bool is_windowed = System_GetWindowed() != 0; cfg["graphics"]["windowed"] = String::FromFormat("%d", is_windowed ? 1 : 0); // TODO: this is a hack, necessary because the original config system was designed when diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 41192bc72fbb..7e0df18447bf 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -25,6 +25,7 @@ // #include "ags/shared/core/platform.h" +#include "ags/engine/globals.h" //include #if AGS_PLATFORM_OS_WINDOWS @@ -89,7 +90,6 @@ using namespace AGS::Engine; extern char check_dynamic_sprites_at_exit; extern int our_eip; -extern bool justRunSetup; extern GameSetup usetup; extern GameSetupStruct game; extern int proper_exit; @@ -193,10 +193,10 @@ bool engine_run_setup(const String &exe_path, ConfigTree &cfg, int &app_res) { void engine_force_window() { // Force to run in a window, override the config file // TODO: actually overwrite config tree instead - if (force_window == 1) { + if (_G(force_window) == 1) { usetup.Screen.DisplayMode.Windowed = true; usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_ByGameScaling; - } else if (force_window == 2) { + } else if (_G(force_window) == 2) { usetup.Screen.DisplayMode.Windowed = false; usetup.Screen.DisplayMode.ScreenSize.SizeDef = kScreenDef_MaxDisplay; } @@ -247,9 +247,9 @@ String find_game_data_in_directory(const String &path) { bool search_for_game_data_file(String &filename, String &search_path) { Debug::Printf("Looking for the game data file"); // 1. From command line argument, treated as a directory - if (!cmdGameDataPath.IsEmpty()) { + if (!_G(cmdGameDataPath).IsEmpty()) { // set from cmd arg (do any conversions if needed) - filename = cmdGameDataPath; + filename = _G(cmdGameDataPath); if (!filename.IsEmpty() && Path::IsDirectory(filename)) { search_path = filename; filename = find_game_data_in_directory(search_path); @@ -273,8 +273,8 @@ bool search_for_game_data_file(String &filename, String &search_path) { filename = find_game_data_in_directory(search_path); if (filename.IsEmpty()) { // 3.3 Look in executable's directory (if it's different from current dir) - if (Path::ComparePaths(appDirectory, search_path)) { - search_path = appDirectory; + if (Path::ComparePaths(_G(appDirectory), search_path)) { + search_path = _G(appDirectory); filename = find_game_data_in_directory(search_path); } } @@ -559,7 +559,7 @@ void atexit_handler() { "Program pointer: %+03d (write this number down), ACI version %s\n" "If you see a list of numbers above, please write them down and contact\n" "developers. Otherwise, note down any other information displayed.", - our_eip, EngineVersion.LongString.GetCStr()); + our_eip, _G(EngineVersion).LongString.GetCStr()); } } @@ -598,13 +598,13 @@ int engine_load_game_data() { } int engine_check_register_game() { - if (justRegisterGame) { + if (_G(justRegisterGame)) { platform->RegisterGameWithGameExplorer(); proper_exit = 1; return EXIT_NORMAL; } - if (justUnRegisterGame) { + if (_G(justUnRegisterGame)) { platform->UnRegisterGameWithGameExplorer(); proper_exit = 1; return EXIT_NORMAL; @@ -1052,7 +1052,7 @@ void engine_init_game_settings() { void engine_setup_scsystem_auxiliary() { // ScriptSystem::aci_version is only 10 chars long - strncpy(scsystem.aci_version, EngineVersion.LongString, 10); + strncpy(scsystem.aci_version, _G(EngineVersion).LongString, 10); if (usetup.override_script_os >= 0) { scsystem.os = usetup.override_script_os; } else { @@ -1114,15 +1114,15 @@ void allegro_bitmap_test_init() { // for the available resource packs in common locations HError define_gamedata_location_checkall(const String &exe_path) { // First try if they provided a startup option - if (!cmdGameDataPath.IsEmpty()) { + if (!_G(cmdGameDataPath).IsEmpty()) { // If not a valid path - bail out - if (!Path::IsFileOrDir(cmdGameDataPath)) - return new Error(String::FromFormat("Defined game location is not a valid path.\nPath: '%s'", cmdGameDataPath.GetCStr())); + if (!Path::IsFileOrDir(_G(cmdGameDataPath))) + return new Error(String::FromFormat("Defined game location is not a valid path.\nPath: '%s'", _G(cmdGameDataPath).GetCStr())); // Switch working dir to this path to be able to look for config and other assets there - Directory::SetCurrentDirectory(Path::GetDirectoryPath(cmdGameDataPath)); + Directory::SetCurrentDirectory(Path::GetDirectoryPath(_G(cmdGameDataPath))); // If it's a file, then keep it and proceed - if (Path::IsFile(cmdGameDataPath)) { - usetup.main_data_filepath = cmdGameDataPath; + if (Path::IsFile(_G(cmdGameDataPath))) { + usetup.main_data_filepath = _G(cmdGameDataPath); return HError::None(); } } @@ -1219,7 +1219,7 @@ void engine_read_config(const String &exe_path, ConfigTree &cfg) { // Apply overriding options from mobile port settings // TODO: normally, those should be instead stored in the same config file in a uniform way // NOTE: the variable is historically called "ignore" but we use it in "override" meaning here - if (psp_ignore_acsetup_cfg_file) + if (_G(psp_ignore_acsetup_cfg_file)) override_config_ext(cfg); } @@ -1257,7 +1257,7 @@ void engine_set_config(const ConfigTree cfg) { // // --tell command support: printing engine/game info by request // -extern std::set tellInfoKeys; + static bool print_info_needs_game(const std::set &keys) { return keys.count("all") > 0 || keys.count("config") > 0 || keys.count("configpath") > 0 || keys.count("data") > 0; @@ -1329,9 +1329,9 @@ int initialize_engine(const ConfigTree &startup_opts) { //----------------------------------------------------- // Locate game data and assemble game config - const String exe_path = global_argv[0]; - if (justTellInfo && !print_info_needs_game(tellInfoKeys)) { - engine_print_info(tellInfoKeys, exe_path, nullptr); + const String exe_path = _G(global_argv)[0]; + if (_G(justTellInfo) && !print_info_needs_game(_G(tellInfoKeys))) { + engine_print_info(_G(tellInfoKeys), exe_path, nullptr); return EXIT_NORMAL; } @@ -1339,12 +1339,12 @@ int initialize_engine(const ConfigTree &startup_opts) { return EXIT_ERROR; ConfigTree cfg; engine_prepare_config(cfg, exe_path, startup_opts); - if (justTellInfo) { - engine_print_info(tellInfoKeys, exe_path, &cfg); + if (_G(justTellInfo)) { + engine_print_info(_G(tellInfoKeys), exe_path, &cfg); return EXIT_NORMAL; } // Test if need to run built-in setup program (where available) - if (justRunSetup) { + if (_G(justRunSetup)) { int res; if (!engine_run_setup(exe_path, cfg, res)) return res; @@ -1465,7 +1465,7 @@ int initialize_engine(const ConfigTree &startup_opts) { allegro_bitmap_test_init(); - initialize_start_and_play_game(override_start_room, loadSaveGameOnStartup); + initialize_start_and_play_game(_G(override_start_room), _G(loadSaveGameOnStartup)); return EXIT_NORMAL; } @@ -1545,7 +1545,7 @@ const char *get_engine_name() { } const char *get_engine_version() { - return EngineVersion.LongString.GetCStr(); + return _G(EngineVersion).LongString.GetCStr(); } void engine_set_pre_init_callback(t_engine_pre_init_callback callback) { diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 47fe112aac8f..11143a035ff5 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -43,6 +43,7 @@ #include "ags/engine/script/script.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/engine/ac/timer.h" +#include "ags/engine/globals.h" #include "ags/ags.h" namespace AGS3 { @@ -53,7 +54,6 @@ using namespace AGS::Engine; extern int our_eip, displayed_room; extern GameSetupStruct game; extern GameState play; -extern const char *loadSaveGameOnStartup; extern std::vector moduleInst; extern int numScriptModules; extern CharacterInfo *playerchar; @@ -75,14 +75,14 @@ void start_game_init_editor_debugging() { } void start_game_load_savegame_on_startup() { - if (loadSaveGameOnStartup != nullptr) { + if (_G(loadSaveGameOnStartup) != nullptr) { int saveGameNumber = 1000; - const char *sgName = strstr(loadSaveGameOnStartup, "agssave."); + const char *sgName = strstr(_G(loadSaveGameOnStartup), "agssave."); if (sgName != nullptr) { sscanf(sgName, "agssave.%03d", &saveGameNumber); } current_fade_out_effect(); - try_restore_save(loadSaveGameOnStartup, saveGameNumber); + try_restore_save(_G(loadSaveGameOnStartup), saveGameNumber); } } diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp deleted file mode 100644 index de0b2b72ea1f..000000000000 --- a/engines/ags/engine/main/main.cpp +++ /dev/null @@ -1,465 +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. - * - */ - -// -// Entry point of the application here. -// -// -// For Windows main() function is really called _mangled_main and is called -// not by system, but from insides of allegro library. -// (See allegro\platform\alwin.h) -// What about other platforms? -// - -#include "ags/shared/core/platform.h" -#define AGS_PLATFORM_DEFINES_PSP_VARS (AGS_PLATFORM_OS_IOS || AGS_PLATFORM_OS_ANDROID) - -//include -#include "ags/shared/ac/common.h" -#include "ags/shared/ac/gamesetup.h" -#include "ags/shared/ac/gamestate.h" -#include "ags/shared/core/def_version.h" -#include "ags/shared/debugging/debugger.h" -#include "ags/shared/debugging/debug_log.h" -#include "ags/shared/debugging/out.h" -#include "ags/shared/main/config.h" -#include "ags/shared/main/engine.h" -#include "ags/shared/main/mainheader.h" -#include "ags/shared/main/main.h" -#include "ags/shared/platform/base/agsplatformdriver.h" -#include "ags/shared/ac/route_finder.h" -#include "ags/shared/core/assetmanager.h" -#include "ags/shared/util/directory.h" -#include "ags/shared/util/path.h" -#include "ags/shared/util/string_compat.h" - -#if AGS_PLATFORM_OS_WINDOWS -#include "ags/shared/platform/windows/win_ex_handling.h" -#endif -#if AGS_PLATFORM_DEBUG -#include "ags/shared/test/test_all.h" -#endif - -#if AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG -#define USE_CUSTOM_EXCEPTION_HANDLER -#endif - -namespace AGS3 { - -using namespace AGS::Shared; -using namespace AGS::Engine; - -String appDirectory; // Needed for library loading -String cmdGameDataPath; - -char **global_argv = nullptr; -int global_argc = 0; - - -extern GameSetup usetup; -extern GameState play; -extern int our_eip; -extern AGSPlatformDriver *platform; -extern int convert_16bit_bgr; -extern int editor_debugging_enabled; -extern int editor_debugging_initialized; -extern char editor_debugger_instance_token[100]; - - -// Startup flags, set from parameters to engine -int force_window = 0; -int override_start_room = 0; -bool justDisplayHelp = false; -bool justDisplayVersion = false; -bool justRunSetup = false; -bool justRegisterGame = false; -bool justUnRegisterGame = false; -bool justTellInfo = false; -bool attachToParentConsole = false; -bool hideMessageBoxes = false; -std::set tellInfoKeys; -const char *loadSaveGameOnStartup = nullptr; - -#if ! AGS_PLATFORM_DEFINES_PSP_VARS -int psp_video_framedrop = 1; -int psp_audio_enabled = 1; -int psp_midi_enabled = 1; -int psp_ignore_acsetup_cfg_file = 0; -int psp_clear_cache_on_room_change = 0; - -int psp_midi_preload_patches = 0; -int psp_audio_cachesize = 10; -char psp_game_file_name[] = ""; -char psp_translation[] = "default"; - -int psp_gfx_renderer = 0; -int psp_gfx_scaling = 1; -int psp_gfx_smoothing = 0; -int psp_gfx_super_sampling = 1; -int psp_gfx_smooth_sprites = 0; -#endif - - -void main_pre_init() { - our_eip = -999; - Common::AssetManager::SetSearchPriority(Common::kAssetPriorityDir); - play.takeover_data = 0; -} - -void main_create_platform_driver() { - platform = AGSPlatformDriver::GetDriver(); -} - -// this needs to be updated if the "play" struct changes -#define SVG_VERSION_BWCOMPAT_MAJOR 3 -#define SVG_VERSION_BWCOMPAT_MINOR 2 -#define SVG_VERSION_BWCOMPAT_RELEASE 0 -#define SVG_VERSION_BWCOMPAT_REVISION 1103 -// CHECKME: we may lower this down, if we find that earlier versions may still -// load new savedgames -#define SVG_VERSION_FWCOMPAT_MAJOR 3 -#define SVG_VERSION_FWCOMPAT_MINOR 2 -#define SVG_VERSION_FWCOMPAT_RELEASE 1 -#define SVG_VERSION_FWCOMPAT_REVISION 1111 - -// Current engine version -AGS::Shared::Version EngineVersion; -// Lowest savedgame version, accepted by this engine -AGS::Shared::Version SavedgameLowestBackwardCompatVersion; -// Lowest engine version, which would accept current savedgames -AGS::Shared::Version SavedgameLowestForwardCompatVersion; - -void main_init(int argc, char *argv[]) { - EngineVersion = Version(ACI_VERSION_STR " " SPECIAL_VERSION); -#if defined (BUILD_STR) - EngineVersion.BuildInfo = BUILD_STR; -#endif - SavedgameLowestBackwardCompatVersion = Version(SVG_VERSION_BWCOMPAT_MAJOR, SVG_VERSION_BWCOMPAT_MINOR, SVG_VERSION_BWCOMPAT_RELEASE, SVG_VERSION_BWCOMPAT_REVISION); - SavedgameLowestForwardCompatVersion = Version(SVG_VERSION_FWCOMPAT_MAJOR, SVG_VERSION_FWCOMPAT_MINOR, SVG_VERSION_FWCOMPAT_RELEASE, SVG_VERSION_FWCOMPAT_REVISION); - - Common::AssetManager::CreateInstance(); - main_pre_init(); - main_create_platform_driver(); - - global_argv = argv; - global_argc = argc; -} - -String get_engine_string() { - return String::FromFormat("Adventure Game Studio v%s Interpreter\n" - "Copyright (c) 1999-2011 Chris Jones and " ACI_COPYRIGHT_YEARS " others\n" -#ifdef BUILD_STR - "ACI version %s (Build: %s)\n", - EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr(), EngineVersion.BuildInfo.GetCStr()); -#else - "ACI version %s\n", EngineVersion.ShortString.GetCStr(), EngineVersion.LongString.GetCStr()); -#endif -} - -extern char return_to_roomedit[30]; -extern char return_to_room[150]; - -void main_print_help() { - platform->WriteStdOut( - "Usage: ags [OPTIONS] [GAMEFILE or DIRECTORY]\n\n" - //--------------------------------------------------------------------------------| - "Options:\n" -#if AGS_PLATFORM_OS_WINDOWS - " --console-attach Write output to the parent process's console\n" -#endif - " --fps Display fps counter\n" - " --fullscreen Force display mode to fullscreen\n" - " --gfxdriver Request graphics driver. Available options:\n" -#if AGS_PLATFORM_OS_WINDOWS - " d3d9, ogl, software\n" -#else - " ogl, software\n" -#endif - " --gfxfilter FILTER [SCALING]\n" - " Request graphics filter. Available options:\n" - " hqx, linear, none, stdscale\n" - " (support differs between graphic drivers);\n" - " scaling is specified by integer number\n" - " --help Print this help message and stop\n" - " --log-OUTPUT=GROUP[:LEVEL][,GROUP[:LEVEL]][,...]\n" - " --log-OUTPUT=+GROUPLIST[:LEVEL]\n" - " Setup logging to the chosen OUTPUT with given\n" - " log groups and verbosity levels. Groups may\n" - " be also defined by a LIST of one-letter IDs,\n" - " preceded by '+', e.g. +ABCD:LEVEL. Verbosity may\n" - " be also defined by a numberic ID.\n" - " OUTPUTs are\n" - " stdout, file, console\n" - " (where \"console\" is internal engine's console)\n" - " GROUPs are:\n" - " all, main (m), game (g), manobj (o),\n" - " script (s), sprcache (c)\n" - " LEVELs are:\n" - " all, alert (1), fatal (2), error (3), warn (4),\n" - " info (5), debug (6)\n" - " Examples:\n" - " --log-stdout=+mgs:debug\n" - " --log-file=all:warn\n" - " --log-file-path=PATH Define custom path for the log file\n" - //--------------------------------------------------------------------------------| -#if AGS_PLATFORM_OS_WINDOWS - " --no-message-box Disable reporting of alerts to message boxes\n" - " --setup Run setup application\n" -#endif - " --tell Print various information concerning engine\n" - " and the game; for selected output use:\n" - " --tell-config Print contents of merged game config\n" - " --tell-configpath Print paths to available config files\n" - " --tell-data Print information on game data and its location\n" - " --tell-engine Print engine name and version\n" - " --tell-graphicdriver Print list of supported graphic drivers\n" - "\n" - " --version Print engine's version and stop\n" - " --windowed Force display mode to windowed\n" - "\n" - "Gamefile options:\n" - " /dir/path/game/ Launch the game in specified directory\n" - " /dir/path/game/penguin.exe Launch penguin.exe\n" - " [nothing] Launch the game in the current directory\n" - //--------------------------------------------------------------------------------| - ); -} - -static int main_process_cmdline(ConfigTree &cfg, int argc, char *argv[]) { - int datafile_argv = 0; - for (int ee = 1; ee < argc; ++ee) { - const char *arg = argv[ee]; - // - // Startup options - // - if (ags_stricmp(arg, "--help") == 0 || ags_stricmp(arg, "/?") == 0 || ags_stricmp(arg, "-?") == 0) { - justDisplayHelp = true; - return 0; - } - if (ags_stricmp(arg, "-v") == 0 || ags_stricmp(arg, "--version") == 0) { - justDisplayVersion = true; - return 0; - } else if (ags_stricmp(arg, "-updatereg") == 0) - debug_flags |= DBG_REGONLY; -#if AGS_PLATFORM_DEBUG - else if ((ags_stricmp(arg, "--startr") == 0) && (ee < argc - 1)) { - override_start_room = atoi(argv[ee + 1]); - ee++; - } -#endif - else if ((ags_stricmp(arg, "--testre") == 0) && (ee < argc - 2)) { - strcpy(return_to_roomedit, argv[ee + 1]); - strcpy(return_to_room, argv[ee + 2]); - ee += 2; - } else if (ags_stricmp(arg, "-noexceptionhandler") == 0) usetup.disable_exception_handling = true; - else if (ags_stricmp(arg, "--setup") == 0) { - justRunSetup = true; - } else if (ags_stricmp(arg, "-registergame") == 0) { - justRegisterGame = true; - } else if (ags_stricmp(arg, "-unregistergame") == 0) { - justUnRegisterGame = true; - } else if ((ags_stricmp(arg, "-loadsavedgame") == 0) && (argc > ee + 1)) { - loadSaveGameOnStartup = argv[ee + 1]; - ee++; - } else if ((ags_stricmp(arg, "--enabledebugger") == 0) && (argc > ee + 1)) { - strcpy(editor_debugger_instance_token, argv[ee + 1]); - editor_debugging_enabled = 1; - force_window = 1; - ee++; - } else if (ags_stricmp(arg, "--runfromide") == 0 && (argc > ee + 3)) { - usetup.install_dir = argv[ee + 1]; - usetup.install_audio_dir = argv[ee + 2]; - usetup.install_voice_dir = argv[ee + 3]; - ee += 3; - } else if (ags_stricmp(arg, "--takeover") == 0) { - if (argc < ee + 2) - break; - play.takeover_data = atoi(argv[ee + 1]); - strncpy(play.takeover_from, argv[ee + 2], 49); - play.takeover_from[49] = 0; - ee += 2; - } else if (ags_strnicmp(arg, "--tell", 6) == 0) { - if (arg[6] == 0) - tellInfoKeys.insert(String("all")); - else if (arg[6] == '-' && arg[7] != 0) - tellInfoKeys.insert(String(arg + 7)); - } - // - // Config overrides - // - else if (ags_stricmp(arg, "-windowed") == 0 || ags_stricmp(arg, "--windowed") == 0) - force_window = 1; - else if (ags_stricmp(arg, "-fullscreen") == 0 || ags_stricmp(arg, "--fullscreen") == 0) - force_window = 2; - else if ((ags_stricmp(arg, "-gfxdriver") == 0 || ags_stricmp(arg, "--gfxdriver") == 0) && (argc > ee + 1)) { - INIwritestring(cfg, "graphics", "driver", argv[++ee]); - } else if ((ags_stricmp(arg, "-gfxfilter") == 0 || ags_stricmp(arg, "--gfxfilter") == 0) && (argc > ee + 1)) { - // NOTE: we make an assumption here that if user provides scaling factor, - // this factor means to be applied to windowed mode only. - INIwritestring(cfg, "graphics", "filter", argv[++ee]); - if (argc > ee + 1 && argv[ee + 1][0] != '-') - INIwritestring(cfg, "graphics", "game_scale_win", argv[++ee]); - else - INIwritestring(cfg, "graphics", "game_scale_win", "max_round"); - } else if (ags_stricmp(arg, "--fps") == 0) display_fps = kFPS_Forced; - else if (ags_stricmp(arg, "--test") == 0) debug_flags |= DBG_DEBUGMODE; - else if (ags_stricmp(arg, "-noiface") == 0) debug_flags |= DBG_NOIFACE; - else if (ags_stricmp(arg, "-nosprdisp") == 0) debug_flags |= DBG_NODRAWSPRITES; - else if (ags_stricmp(arg, "-nospr") == 0) debug_flags |= DBG_NOOBJECTS; - else if (ags_stricmp(arg, "-noupdate") == 0) debug_flags |= DBG_NOUPDATE; - else if (ags_stricmp(arg, "-nosound") == 0) debug_flags |= DBG_NOSFX; - else if (ags_stricmp(arg, "-nomusic") == 0) debug_flags |= DBG_NOMUSIC; - else if (ags_stricmp(arg, "-noscript") == 0) debug_flags |= DBG_NOSCRIPT; - else if (ags_stricmp(arg, "-novideo") == 0) debug_flags |= DBG_NOVIDEO; - else if (ags_stricmp(arg, "-dbgscript") == 0) debug_flags |= DBG_DBGSCRIPT; - else if (ags_strnicmp(arg, "--log-", 6) == 0 && arg[6] != 0) { - String logarg = arg + 6; - size_t split_at = logarg.FindChar('='); - if (split_at >= 0) - cfg["log"][logarg.Left(split_at)] = logarg.Mid(split_at + 1); - else - cfg["log"][logarg] = ""; - } else if (ags_stricmp(arg, "--console-attach") == 0) attachToParentConsole = true; - else if (ags_stricmp(arg, "--no-message-box") == 0) hideMessageBoxes = true; - // - // Special case: data file location - // - else if (arg[0] != '-') datafile_argv = ee; - } - - if (datafile_argv > 0) { - cmdGameDataPath = GetPathFromCmdArg(datafile_argv); - } else { - // assign standard path for mobile/consoles (defined in their own platform implementation) - cmdGameDataPath = psp_game_file_name; - } - - if (tellInfoKeys.size() > 0) - justTellInfo = true; - - return 0; -} - -void main_set_gamedir(int argc, char *argv[]) { - appDirectory = Path::GetDirectoryPath(GetPathFromCmdArg(0)); - - if ((loadSaveGameOnStartup != nullptr) && (argv[0] != nullptr)) { - // When launched by double-clicking a save game file, the curdir will - // be the save game folder unless we correct it - Directory::SetCurrentDirectory(appDirectory); - } else { - // It looks like Allegro library does not like ANSI (ACP) paths. - // When *not* working in U_UNICODE filepath mode, whenever it gets - // current directory for its own operations, it "fixes" it by - // substituting non-ASCII symbols with '^'. - // Here we explicitly set current directory to ASCII path. - String cur_dir = Directory::GetCurrentDirectory(); - String path = Path::GetPathInASCII(cur_dir); - if (!path.IsEmpty()) - Directory::SetCurrentDirectory(Path::MakeAbsolutePath(path)); - else - Debug::Printf(kDbgMsg_Error, "Unable to determine current directory: GetPathInASCII failed.\nArg: %s", cur_dir.GetCStr()); - } -} - -String GetPathFromCmdArg(int arg_index) { - if (arg_index < 0 || arg_index >= global_argc) - return ""; - String path = Path::GetCmdLinePathInASCII(global_argv[arg_index], arg_index); - if (!path.IsEmpty()) - return Path::MakeAbsolutePath(path); - Debug::Printf(kDbgMsg_Error, "Unable to determine path: GetCmdLinePathInASCII failed.\nCommand line argument %i: %s", arg_index, global_argv[arg_index]); - return global_argv[arg_index]; -} - -const char *get_allegro_error() { - return allegro_error; -} - -const char *set_allegro_error(const char *format, ...) { - va_list argptr; - va_start(argptr, format); - uvszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(format), argptr); - va_end(argptr); - return allegro_error; -} - -int ags_entry_point(int argc, char *argv[]) { - -#ifdef AGS_RUN_TESTS - Test_DoAllTests(); -#endif - main_init(argc, argv); - -#if AGS_PLATFORM_OS_WINDOWS - setup_malloc_handling(); -#endif - debug_flags = 0; - - ConfigTree startup_opts; - int res = main_process_cmdline(startup_opts, argc, argv); - if (res != 0) - return res; - - if (attachToParentConsole) - platform->AttachToParentConsole(); - - if (justDisplayVersion) { - platform->WriteStdOut(get_engine_string()); - return EXIT_NORMAL; - } - - if (justDisplayHelp) { - main_print_help(); - return EXIT_NORMAL; - } - - if (!justTellInfo && !hideMessageBoxes) - platform->SetGUIMode(true); - - init_debug(startup_opts, justTellInfo); - Debug::Printf(kDbgMsg_Alert, get_engine_string()); - - main_set_gamedir(argc, argv); - - // Update shell associations and exit - if (debug_flags & DBG_REGONLY) - exit(EXIT_NORMAL); - -#ifdef USE_CUSTOM_EXCEPTION_HANDLER - if (usetup.disable_exception_handling) -#endif - { - int result = initialize_engine(startup_opts); - // TODO: refactor engine shutdown routine (must shutdown and delete everything started and created) - allegro_exit(); - platform->PostAllegroExit(); - return result; - } -#ifdef USE_CUSTOM_EXCEPTION_HANDLER - else { - return initialize_engine_with_exception_handling(initialize_engine, startup_opts); - } -#endif -} - -} // namespace AGS3 diff --git a/engines/ags/engine/main/main.h b/engines/ags/engine/main/main.h index fdc9da0b6a61..29e4e4476510 100644 --- a/engines/ags/engine/main/main.h +++ b/engines/ags/engine/main/main.h @@ -28,41 +28,8 @@ namespace AGS3 { -// Current engine version -extern AGS::Shared::Version EngineVersion; -// Lowest savedgame version, accepted by this engine -extern AGS::Shared::Version SavedgameLowestBackwardCompatVersion; -// Lowest engine version, which would accept current savedgames -extern AGS::Shared::Version SavedgameLowestForwardCompatVersion; - //============================================================================= -extern const char **global_argv; - -// Location of the engine executable -extern AGS::Shared::String appDirectory; -// Game path from the startup options (before reading config) -extern AGS::Shared::String cmdGameDataPath; - -// Startup flags, set from parameters to engine -extern int force_window; -extern int override_start_room; -extern bool justRegisterGame; -extern bool justUnRegisterGame; -extern bool justTellInfo; -extern const char *loadSaveGameOnStartup; - -extern int psp_video_framedrop; -extern int psp_audio_enabled; -extern int psp_midi_enabled; -extern int psp_ignore_acsetup_cfg_file; -extern int psp_clear_cache_on_room_change; - -extern int psp_midi_preload_patches; -extern int psp_audio_cachesize; -extern char psp_game_file_name[]; -extern char psp_translation[]; - void main_print_help(); int ags_entry_point(int argc, char *argv[]); diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 45a1edcc8698..12660e525dde 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -151,7 +151,7 @@ QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) { qreason = kQuit_GameError; alertis.Format("An error has occurred. Please contact the game author for support, as this " "is likely to be a scripting error and not a bug in AGS.\n" - "(ACI version %s)\n\n", EngineVersion.LongString.GetCStr()); + "(ACI version %s)\n\n", _G(EngineVersion).LongString.GetCStr()); } alertis.Append(get_cur_script(5)); @@ -165,13 +165,13 @@ QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) { qmsg++; alertis.Format("A warning has been generated. This is not normally fatal, but you have selected " "to treat warnings as errors.\n" - "(ACI version %s)\n\n%s\n", EngineVersion.LongString.GetCStr(), get_cur_script(5).GetCStr()); + "(ACI version %s)\n\n%s\n", _G(EngineVersion).LongString.GetCStr(), get_cur_script(5).GetCStr()); return kQuit_GameWarning; } else { alertis.Format("An internal error has occurred. Please note down the following information.\n" "If the problem persists, post the details on the AGS Technical Forum.\n" "(ACI version %s)\n" - "\nError: ", EngineVersion.LongString.GetCStr()); + "\nError: ", _G(EngineVersion).LongString.GetCStr()); return kQuit_FatalError; } } diff --git a/engines/ags/engine/media/audio/soundcache.cpp b/engines/ags/engine/media/audio/soundcache.cpp index 37e07e1c504a..adf41fa9cd35 100644 --- a/engines/ags/engine/media/audio/soundcache.cpp +++ b/engines/ags/engine/media/audio/soundcache.cpp @@ -28,6 +28,7 @@ #include "ags/engine/util/mutex_lock.h" #include "ags/shared/util/string.h" #include "ags/shared/debugging/out.h" +#include "ags/engine/globals.h" #include "ags/ags.h" #include "common/memstream.h" @@ -43,7 +44,7 @@ void clear_sound_cache() { if (sound_cache_entries) { int i; - for (i = 0; i < psp_audio_cachesize; i++) { + for (i = 0; i < _G(psp_audio_cachesize); i++) { if (sound_cache_entries[i].data) { free(sound_cache_entries[i].data); sound_cache_entries[i].data = nullptr; @@ -53,8 +54,8 @@ void clear_sound_cache() { } } } else { - sound_cache_entries = (sound_cache_entry_t *)malloc(psp_audio_cachesize * sizeof(sound_cache_entry_t)); - memset(sound_cache_entries, 0, psp_audio_cachesize * sizeof(sound_cache_entry_t)); + sound_cache_entries = (sound_cache_entry_t *)malloc(_G(psp_audio_cachesize) * sizeof(sound_cache_entry_t)); + memset(sound_cache_entries, 0, _G(psp_audio_cachesize) * sizeof(sound_cache_entry_t)); } } @@ -65,7 +66,7 @@ void sound_cache_free(char *buffer, bool is_wave) { Debug::Printf("sound_cache_free(%p %d)\n", buffer, (unsigned int)is_wave); #endif int i; - for (i = 0; i < psp_audio_cachesize; i++) { + for (i = 0; i < _G(psp_audio_cachesize); i++) { if (sound_cache_entries[i].data == buffer) { if (sound_cache_entries[i].reference > 0) sound_cache_entries[i].reference--; @@ -82,7 +83,7 @@ void sound_cache_free(char *buffer, bool is_wave) { #endif // Sound is uncached - if (i == psp_audio_cachesize) { + if (i == _G(psp_audio_cachesize)) { if (is_wave) destroy_sample((SAMPLE *)buffer); else @@ -101,7 +102,7 @@ char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) size = 0; int i; - for (i = 0; i < psp_audio_cachesize; i++) { + for (i = 0; i < _G(psp_audio_cachesize); i++) { if (sound_cache_entries[i].data == nullptr) continue; @@ -135,17 +136,17 @@ char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size) } // Find free slot - for (i = 0; i < psp_audio_cachesize; i++) { + for (i = 0; i < _G(psp_audio_cachesize); i++) { if (sound_cache_entries[i].data == nullptr) break; } // No free slot? - if (i == psp_audio_cachesize) { + if (i == _G(psp_audio_cachesize)) { unsigned int oldest = sound_cache_counter; int index = -1; - for (i = 0; i < psp_audio_cachesize; i++) { + for (i = 0; i < _G(psp_audio_cachesize); i++) { if (sound_cache_entries[i].reference == 0) { if (sound_cache_entries[i].last_used < oldest) { oldest = sound_cache_entries[i].last_used; diff --git a/engines/ags/engine/media/audio/soundcache.h b/engines/ags/engine/media/audio/soundcache.h index fa872e3b6560..8020d417ce1c 100644 --- a/engines/ags/engine/media/audio/soundcache.h +++ b/engines/ags/engine/media/audio/soundcache.h @@ -45,11 +45,6 @@ typedef struct { bool is_wave; } sound_cache_entry_t; -extern int psp_use_sound_cache; -extern int psp_sound_cache_max_size; -extern int psp_audio_cachesize; -extern int psp_midi_preload_patches; - void clear_sound_cache(); void sound_cache_free(char *buffer, bool is_wave); char *get_cached_sound(const AssetPath &asset_name, bool is_wave, size_t &size); diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index a966281fa98d..04ab9523401c 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -28,14 +28,13 @@ #include "ags/shared/util/string.h" #include "ags/shared/debugging/out.h" #include "ags/engine/plugin/library.h" +#include "ags/engine/globals.h" namespace AGS3 { // FIXME: Replace with a unified way to get the directory which contains the engine binary #if AGS_PLATFORM_OS_ANDROID extern char android_app_directory[256]; -#else -extern AGS::Shared::String appDirectory; #endif @@ -102,7 +101,7 @@ class PosixLibrary : BaseLibrary { sprintf(buffer, "%s%s", android_app_directory, "/lib"); _library = dlopen(BuildPath(buffer, libraryName).GetCStr(), RTLD_LAZY); #else - _library = dlopen(BuildPath(appDirectory, libraryName).GetCStr(), RTLD_LAZY); + _library = dlopen(BuildPath(_G(appDirectory), libraryName).GetCStr(), RTLD_LAZY); #endif AGS::Shared::Debug::Printf("dlopen returned: %s", dlerror()); diff --git a/engines/ags/music.cpp b/engines/ags/music.cpp index 5b78a24e7bb7..a3142d8023bb 100644 --- a/engines/ags/music.cpp +++ b/engines/ags/music.cpp @@ -23,6 +23,7 @@ #include "ags/music.h" #include "ags/engine/main/main.h" #include "ags/lib/audio/midi.h" +#include "ags/engine/globals.h" #include "audio/midiparser.h" namespace AGS { @@ -65,7 +66,7 @@ void Music::sendToChannel(byte channel, uint32 b) { void Music::playMusic(Common::SeekableReadStream *midi, bool repeat) { if (_isFirstTime) { - if (::AGS3::psp_midi_preload_patches) + if (_G(psp_midi_preload_patches)) ::AGS3::load_midi_patches(); _isFirstTime = false; } From a2614ff20a25805294d61b1a928ea67b52ec6e61 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 13:42:05 -0800 Subject: [PATCH 142/215] AGS: Move quit globals into Globals --- engines/ags/ags.cpp | 8 +++----- engines/ags/engine/globals.h | 17 +++++++++++++++++ engines/ags/engine/main/quit.cpp | 26 +++++++++++--------------- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index aca6d6e16525..e282601452f3 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -55,15 +55,13 @@ #include "ags/shared/util/directory.h" #include "ags/shared/util/path.h" + #ifdef ENABLE_AGS_TESTS #include "ags/tests/test_all.h" #endif namespace AGS3 { -extern char return_to_roomedit[30]; -extern char return_to_room[150]; - using namespace Shared; using namespace Engine; @@ -149,8 +147,8 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { } #endif else if ((scumm_stricmp(arg, "--testre") == 0) && (ee < argc - 2)) { - strncpy(return_to_roomedit, argv[ee + 1], 30); - strncpy(return_to_room, argv[ee + 2], 150); + strncpy(_G(return_to_roomedit), argv[ee + 1], 30); + strncpy(_G(return_to_room), argv[ee + 2], 150); ee += 2; } else if (scumm_stricmp(arg, "-noexceptionhandler") == 0) usetup.disable_exception_handling = true; else if (scumm_stricmp(arg, "--setup") == 0) { diff --git a/engines/ags/engine/globals.h b/engines/ags/engine/globals.h index b31251904960..e8b8b908ead3 100644 --- a/engines/ags/engine/globals.h +++ b/engines/ags/engine/globals.h @@ -96,6 +96,18 @@ class Globals { /**@}*/ + /** + * \defgroup quit globals + * @{ + */ + + bool _handledErrorInEditor = false; + char _return_to_roomedit[30] = "\0"; + char _return_to_room[150] = "\0"; + char _quit_message[256] = "\0"; + + /**@}*/ + public: Globals(); ~Globals(); @@ -103,7 +115,12 @@ class Globals { extern Globals *g_globals; +// Macro for accessing a globals member #define _G(FIELD) (::AGS3::g_globals->_##FIELD) +// Macro for accessing a globals member that was an object in the original, +// but is a pointer to the object in ScummVM, so that we don't need to +// provide the full class/struct definition here in the header file +#define _GP(FIELD) (*::AGS3::g_globals->_##FIELD) } // namespace AGS3 diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 12660e525dde..9b33146a00c2 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -69,12 +69,14 @@ extern int need_to_stop_cd; extern int use_cdplayer; extern IGraphicsDriver *gfxDriver; -bool handledErrorInEditor; +// TODO: move to test unit +extern Bitmap *test_allegro_bitmap; +extern IDriverDependantBitmap *test_allegro_ddb; void quit_tell_editor_debugger(const String &qmsg, QuitReason qreason) { if (editor_debugging_initialized) { if (qreason & kQuitKind_GameException) - handledErrorInEditor = send_exception_to_editor(qmsg); + _G(handledErrorInEditor) = send_exception_to_editor(qmsg); send_message_to_editor("EXIT"); editor_debugger->Shutdown(); } @@ -179,7 +181,7 @@ QuitReason quit_check_for_error_state(const char *&qmsg, String &alertis) { void quit_message_on_exit(const char *qmsg, String &alertis, QuitReason qreason) { // successful exit displays no messages (because Windoze closes the dos-box // if it is empty). - if ((qreason & kQuitKind_NormalExit) == 0 && !handledErrorInEditor) { + if ((qreason & kQuitKind_NormalExit) == 0 && !_G(handledErrorInEditor)) { // Display the message (at this point the window still exists) sprintf(pexbuf, "%s\n", qmsg); alertis.Append(pexbuf); @@ -212,18 +214,12 @@ void quit_delete_temp_files() { } // TODO: move to test unit -extern Bitmap *test_allegro_bitmap; -extern IDriverDependantBitmap *test_allegro_ddb; void allegro_bitmap_test_release() { delete test_allegro_bitmap; if (test_allegro_ddb) gfxDriver->DestroyDDB(test_allegro_ddb); } -char return_to_roomedit[30] = "\0"; -char return_to_room[150] = "\0"; -char quit_message[256] = "\0"; - // quit - exits the engine, shutting down everything gracefully // The parameter is the message to print. If this message begins with // an '!' character, then it is printed as a "contact game author" error. @@ -232,16 +228,16 @@ char quit_message[256] = "\0"; // error. // "!|" is a special code used to mean that the player has aborted (Alt+X) void quit(const char *quitmsg) { - strncpy(quit_message, quitmsg, 256); + strncpy(_G(quit_message), quitmsg, 256); _G(abort_engine) = true; } void quit_free() { String alertis; - if (strlen(quit_message) == 0) - strcpy(quit_message, "|bye!"); + if (strlen(_G(quit_message)) == 0) + strcpy(_G(quit_message), "|bye!"); - const char *quitmsg = quit_message; + const char *quitmsg = _G(quit_message); QuitReason qreason = quit_check_for_error_state(quitmsg, alertis); if (qreason & kQuitKind_NormalExit) @@ -249,9 +245,9 @@ void quit_free() { allegro_bitmap_test_release(); - handledErrorInEditor = false; + _G(handledErrorInEditor) = false; - quit_tell_editor_debugger(quit_message, qreason); + quit_tell_editor_debugger(_G(quit_message), qreason); our_eip = 9900; From 6bb7ba492e1cc4b59884e98ea64c1173c0cbd926 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 20:10:44 -0800 Subject: [PATCH 143/215] AGS: Move mouse globals to Globals --- engines/ags/engine/ac/dialog.cpp | 16 +-- engines/ags/engine/ac/draw.cpp | 14 +- engines/ags/engine/ac/global_game.cpp | 3 +- .../ags/engine/ac/global_inventoryitem.cpp | 16 +-- engines/ags/engine/ac/gui.cpp | 28 ++-- engines/ags/engine/ac/guicontrol.cpp | 12 +- engines/ags/engine/ac/invwindow.cpp | 7 +- engines/ags/engine/ac/mouse.cpp | 23 ++-- .../engine/ac/route_finder_impl_legacy.cpp | 4 +- engines/ags/engine/device/mousew32.cpp | 121 ++++++++---------- engines/ags/engine/device/mousew32.h | 12 -- engines/ags/engine/globals.cpp | 2 + engines/ags/engine/globals.h | 25 ++++ engines/ags/engine/gui/cscidialog.cpp | 10 +- engines/ags/engine/gui/mylistbox.cpp | 11 +- engines/ags/engine/gui/mypushbutton.cpp | 3 +- engines/ags/engine/gui/newcontrol.cpp | 3 +- engines/ags/engine/main/engine.cpp | 6 +- engines/ags/engine/main/game_run.cpp | 12 +- engines/ags/engine/plugin/agsplugin.cpp | 6 +- engines/ags/shared/ac/interfaceelement.h | 2 +- engines/ags/shared/ac/mousecursor.cpp | 1 + engines/ags/shared/gui/guimain.cpp | 29 +++-- engines/ags/shared/gui/guimain.h | 4 +- 24 files changed, 188 insertions(+), 182 deletions(-) diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 92c3e0fb4543..1bf4e468e94c 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -59,11 +59,11 @@ #include "ags/engine/gfx/graphicsdriver.h" #include "ags/engine/ac/mouse.h" #include "ags/engine/media/audio/audio_system.h" - #include "ags/shared/debugging/out.h" #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" #include "ags/engine/ac/dynobj/scriptstring.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -872,9 +872,9 @@ bool DialogOptions::Run() { mouseison = -1; if (new_custom_render); // do not automatically detect option under mouse else if (usingCustomRendering) { - if ((mousex >= dirtyx) && (mousey >= dirtyy) && - (mousex < dirtyx + tempScrn->GetWidth()) && - (mousey < dirtyy + tempScrn->GetHeight())) { + if ((_G(mousex) >= dirtyx) && (_G(mousey) >= dirtyy) && + (_G(mousex) < dirtyx + tempScrn->GetWidth()) && + (_G(mousey) < dirtyy + tempScrn->GetHeight())) { getDialogOptionUnderCursorFunc.params[0].SetDynamicObject(&ccDialogOptionsRendering, &ccDialogOptionsRendering); run_function_on_non_blocking_thread(&getDialogOptionUnderCursorFunc); @@ -885,11 +885,11 @@ bool DialogOptions::Run() { } else { ccDialogOptionsRendering.activeOptionID = -1; } - } else if (mousex >= dialog_abs_x && mousex < (dialog_abs_x + areawid) && - mousey >= dlgyp && mousey < curyp) { + } else if (_G(mousex) >= dialog_abs_x && _G(mousex) < (dialog_abs_x + areawid) && + _G(mousey) >= dlgyp && _G(mousey) < curyp) { mouseison = numdisp - 1; for (int i = 0; i < numdisp; ++i) { - if (mousey < dispyp[i]) { + if (_G(mousey) < dispyp[i]) { mouseison = i - 1; break; } @@ -898,7 +898,7 @@ bool DialogOptions::Run() { } if (parserInput != nullptr) { - int relativeMousey = mousey; + int relativeMousey = _G(mousey); if (usingCustomRendering) relativeMousey -= dirtyy; diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index d74095bdee3e..c559768d7366 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -70,6 +70,7 @@ #include "ags/engine/gfx/blender.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/engine/ac/game.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -121,7 +122,6 @@ extern int cur_mode, cur_cursor; extern int mouse_frame, mouse_delay; extern int lastmx, lastmy; extern IDriverDependantBitmap *mouseCursor; -extern int hotx, hoty; extern int bg_just_changed; color palette[256]; @@ -2207,10 +2207,10 @@ void construct_game_screen_overlay(bool draw_mouse) { ags_domouse(DOMOUSE_NOCURSOR); // only on mousemove, and it's not moving if (((game.mcurs[cur_cursor].flags & MCF_ANIMMOVE) != 0) && - (mousex == lastmx) && (mousey == lastmy)); + (_G(mousex) == lastmx) && (_G(mousey) == lastmy)); // only on hotspot, and it's not on one else if (((game.mcurs[cur_cursor].flags & MCF_HOTSPOT) != 0) && - (GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey)) == 0)) + (GetLocationType(game_to_data_coord(_G(mousex)), game_to_data_coord(_G(mousey))) == 0)) set_new_cursor_graphic(game.mcurs[cur_cursor].pic); else if (mouse_delay > 0) mouse_delay--; else { @@ -2228,16 +2228,16 @@ void construct_game_screen_overlay(bool draw_mouse) { mouse_delay = views[viewnum].loops[loopnum].frames[mouse_frame].speed + 5; CheckViewFrame(viewnum, loopnum, mouse_frame); } - lastmx = mousex; - lastmy = mousey; + lastmx = _G(mousex); + lastmy = _G(mousey); } ags_domouse(DOMOUSE_NOCURSOR); // Stage: mouse cursor if (draw_mouse && !play.mouse_cursor_hidden && play.screen_is_faded_out == 0) { - gfxDriver->DrawSprite(mousex - hotx, mousey - hoty, mouseCursor); - invalidate_sprite(mousex - hotx, mousey - hoty, mouseCursor, false); + gfxDriver->DrawSprite(_G(mousex) - _G(hotx), _G(mousey) - _G(hoty), mouseCursor); + invalidate_sprite(_G(mousex) - _G(hotx), _G(mousey) - _G(hoty), mouseCursor, false); } if (play.screen_is_faded_out == 0) { diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index dd195561d80a..d1c2fbeb83b2 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -69,6 +69,7 @@ #include "ags/engine/main/game_file.h" #include "ags/shared/util/string_utils.h" #include "ags/engine/media/audio/audio_system.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -520,7 +521,7 @@ int GetLocationType(int xxx, int yyy) { void SaveCursorForLocationChange() { // update the current location name char tempo[100]; - GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + GetLocationName(game_to_data_coord(_G(mousex)), game_to_data_coord(_G(mousey)), tempo); if (play.get_loc_name_save_cursor != play.get_loc_name_last_time) { play.get_loc_name_save_cursor = play.get_loc_name_last_time; diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp index 4bd15c1eee63..baf99555e139 100644 --- a/engines/ags/engine/ac/global_inventoryitem.cpp +++ b/engines/ags/engine/ac/global_inventoryitem.cpp @@ -33,6 +33,7 @@ #include "ags/shared/gui/guiinv.h" #include "ags/engine/ac/event.h" #include "ags/engine/ac/gamestate.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -40,7 +41,6 @@ using namespace AGS::Shared; extern GameSetupStruct game; extern GameState play; -extern int mousex, mousey; extern int mouse_ifacebut_xoffs, mouse_ifacebut_yoffs; extern const char *evblockbasename; extern int evblocknum; @@ -79,17 +79,17 @@ void SetInvItemName(int invi, const char *newName) { int GetInvAt(int xxx, int yyy) { int ongui = GetGUIAt(xxx, yyy); if (ongui >= 0) { - int mxwas = mousex, mywas = mousey; - mousex = data_to_game_coord(xxx) - guis[ongui].X; - mousey = data_to_game_coord(yyy) - guis[ongui].Y; + int mxwas = _G(mousex), mywas = _G(mousey); + _G(mousex) = data_to_game_coord(xxx) - guis[ongui].X; + _G(mousey) = data_to_game_coord(yyy) - guis[ongui].Y; int onobj = guis[ongui].FindControlUnderMouse(); GUIObject *guio = guis[ongui].GetControl(onobj); if (guio) { - mouse_ifacebut_xoffs = mousex - (guio->X); - mouse_ifacebut_yoffs = mousey - (guio->Y); + mouse_ifacebut_xoffs = _G(mousex) - (guio->X); + mouse_ifacebut_yoffs = _G(mousey) - (guio->Y); } - mousex = mxwas; - mousey = mywas; + _G(mousex) = mxwas; + _G(mousey) = mywas; if (guio && (guis[ongui].GetControlType(onobj) == kGUIInvWindow)) return offset_over_inv((GUIInvWindow *)guio); } diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp index d52d7cbc829e..d76d399ca6c2 100644 --- a/engines/ags/engine/ac/gui.cpp +++ b/engines/ags/engine/ac/gui.cpp @@ -54,10 +54,10 @@ #include "ags/engine/ac/dynobj/cc_guiobject.h" #include "ags/engine/script/runtimescriptvalue.h" #include "ags/shared/util/string_compat.h" - #include "ags/shared/debugging/out.h" #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -304,15 +304,15 @@ void GUI_Click(ScriptGUI *scgui, int mbut) { void GUI_ProcessClick(int x, int y, int mbut) { int guiid = gui_get_interactable(x, y); if (guiid >= 0) { - const int real_mousex = mousex; - const int real_mousey = mousey; - mousex = x; - mousey = y; + const int real_mousex = _G(mousex); + const int real_mousey = _G(mousey); + _G(mousex) = x; + _G(mousey) = y; guis[guiid].Poll(); gui_on_mouse_down(guiid, mbut); gui_on_mouse_up(guiid, mbut); - mousex = real_mousex; - mousey = real_mousey; + _G(mousex) = real_mousex; + _G(mousey) = real_mousey; } } @@ -323,8 +323,8 @@ void remove_popup_interface(int ifacenum) { ifacepopped = -1; UnPauseGame(); guis[ifacenum].SetConceal(true); - if (mousey <= guis[ifacenum].PopupAtMouseY) - Mouse::SetPosition(Point(mousex, guis[ifacenum].PopupAtMouseY + 2)); + if (_G(mousey) <= guis[ifacenum].PopupAtMouseY) + Mouse::SetPosition(Point(_G(mousex), guis[ifacenum].PopupAtMouseY + 2)); if ((!IsInterfaceEnabled()) && (cur_cursor == cur_mode)) // Only change the mouse cursor if it hasn't been specifically changed first set_mouse_cursor(CURS_WAIT); @@ -422,7 +422,7 @@ void replace_macro_tokens(const char *text, String &fixed_text) { if (!IsInterfaceEnabled()) tempo[0] = 0; else - GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + GetLocationName(game_to_data_coord(_G(mousex)), game_to_data_coord(_G(mousey)), tempo); } else { // not a macro, there's just a @ in the message curptr = curptrWasAt + 1; strcpy(tempo, "@"); @@ -598,7 +598,7 @@ int gui_on_mouse_move() { int ll; for (ll = 0; ll < game.numgui; ll++) { const int guin = play.gui_draw_order[ll]; - if (guis[guin].IsInteractableAt(mousex, mousey)) mouse_over_gui = guin; + if (guis[guin].IsInteractableAt(_G(mousex), _G(mousey))) mouse_over_gui = guin; if (guis[guin].PopupStyle != kGUIPopupMouseY) continue; if (is_complete_overlay > 0) break; // interfaces disabled @@ -608,7 +608,7 @@ int gui_on_mouse_move() { // Don't allow it to be popped up while skipping cutscene if (play.fast_forward) continue; - if (mousey < guis[guin].PopupAtMouseY) { + if (_G(mousey) < guis[guin].PopupAtMouseY) { set_mouse_cursor(CURS_ARROW); guis[guin].SetConceal(false); guis_need_update = 1; @@ -646,8 +646,8 @@ void gui_on_mouse_up(const int wasongui, const int wasbutdown) { if ((cttype == kGUIButton) || (cttype == kGUISlider) || (cttype == kGUIListBox)) { force_event(EV_IFACECLICK, wasongui, i, wasbutdown); } else if (cttype == kGUIInvWindow) { - mouse_ifacebut_xoffs = mousex - (guio->X) - guis[wasongui].X; - mouse_ifacebut_yoffs = mousey - (guio->Y) - guis[wasongui].Y; + mouse_ifacebut_xoffs = _G(mousex) - (guio->X) - guis[wasongui].X; + mouse_ifacebut_yoffs = _G(mousey) - (guio->Y) - guis[wasongui].Y; int iit = offset_over_inv((GUIInvWindow *)guio); if (iit >= 0) { evblocknum = iit; diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp index eb089b3de407..e198f72c7d39 100644 --- a/engines/ags/engine/ac/guicontrol.cpp +++ b/engines/ags/engine/ac/guicontrol.cpp @@ -34,10 +34,10 @@ #include "ags/engine/script/runtimescriptvalue.h" #include "ags/engine/ac/dynobj/cc_gui.h" #include "ags/engine/ac/dynobj/cc_guiobject.h" - #include "ags/shared/debugging/out.h" #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -54,12 +54,12 @@ GUIObject *GetGUIControlAtLocation(int xx, int yy) { data_to_game_coords(&xx, &yy); - int oldmousex = mousex, oldmousey = mousey; - mousex = xx - guis[guinum].X; - mousey = yy - guis[guinum].Y; + int oldmousex = _G(mousex), oldmousey = _G(mousey); + _G(mousex) = xx - guis[guinum].X; + _G(mousey) = yy - guis[guinum].Y; int toret = guis[guinum].FindControlUnderMouse(0, false); - mousex = oldmousex; - mousey = oldmousey; + _G(mousex) = oldmousex; + _G(mousey) = oldmousey; if (toret < 0) return nullptr; diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp index 208666888dbd..a0a336d2e3e8 100644 --- a/engines/ags/engine/ac/invwindow.cpp +++ b/engines/ags/engine/ac/invwindow.cpp @@ -44,10 +44,10 @@ #include "ags/shared/util/math.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/engine/ac/timer.h" - #include "ags/shared/debugging/out.h" #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -59,7 +59,6 @@ extern CharacterExtras *charextra; extern ScriptInvItem scrInv[MAX_INV]; extern int mouse_ifacebut_xoffs, mouse_ifacebut_yoffs; extern SpriteCache spriteset; -extern int mousex, mousey; extern int evblocknum; extern CharacterInfo *playerchar; extern AGSPlatformDriver *platform; @@ -366,8 +365,8 @@ bool InventoryScreen::Run() { refresh_gui_screen(); // NOTE: this is because old code was working with full game screen - const int mouseX = AGS3::mousex - windowxp; - const int mouseY = AGS3::mousey - windowyp; + const int mouseX = _G(mousex) - windowxp; + const int mouseY = _G(mousey) - windowyp; int isonitem = ((mouseY - bartop) / highest) * ICONSPERLINE + (mouseX - barxp) / widest; if (mouseY <= bartop) isonitem = -1; diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp index c6780c73d39e..8d12af0650e5 100644 --- a/engines/ags/engine/ac/mouse.cpp +++ b/engines/ags/engine/ac/mouse.cpp @@ -41,11 +41,11 @@ #include "ags/shared/ac/spritecache.h" #include "ags/engine/gfx/graphicsdriver.h" #include "ags/engine/gfx/gfxfilter.h" - #include "ags/shared/debugging/out.h" #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" #include "ags/engine/ac/global_game.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -55,7 +55,6 @@ using namespace AGS::Engine; extern GameSetupStruct game; extern GameState play; extern ScriptSystem scsystem; -extern Bitmap *mousecurs[MAXCURSORS]; extern SpriteCache spriteset; extern CharacterInfo *playerchar; extern IGraphicsDriver *gfxDriver; @@ -143,7 +142,7 @@ void set_mouse_cursor(int newcurs) { ((game.hotdot > 0) || (game.invhotdotsprite > 0))) { // If necessary, create a copy of the cursor and put the hotspot // dot onto it - dotted_mouse_cursor = BitmapHelper::CreateBitmapCopy(mousecurs[0]); + dotted_mouse_cursor = BitmapHelper::CreateBitmapCopy(_G(mousecurs)[0]); if (game.invhotdotsprite > 0) { draw_sprite_slot_support_alpha(dotted_mouse_cursor, @@ -163,7 +162,7 @@ void set_mouse_cursor(int newcurs) { putpixel_compensate(dotted_mouse_cursor, hotspotx, hotspoty - get_fixed_pixel_size(1), outercol); } } - mousecurs[0] = dotted_mouse_cursor; + _G(mousecurs)[0] = dotted_mouse_cursor; update_cached_mouse_cursor(); } } @@ -287,8 +286,8 @@ void disable_cursor_mode(int modd) { void RefreshMouse() { ags_domouse(DOMOUSE_NOCURSOR); - scmouse.x = game_to_data_coord(mousex); - scmouse.y = game_to_data_coord(mousey); + scmouse.x = game_to_data_coord(_G(mousex)); + scmouse.y = game_to_data_coord(_G(mousey)); } void SetMousePosition(int newx, int newy) { @@ -353,8 +352,8 @@ int GetMouseCursor() { } void update_script_mouse_coords() { - scmouse.x = game_to_data_coord(mousex); - scmouse.y = game_to_data_coord(mousey); + scmouse.x = game_to_data_coord(_G(mousex)); + scmouse.y = game_to_data_coord(_G(mousey)); } void update_inv_cursor(int invnum) { @@ -384,19 +383,19 @@ void update_inv_cursor(int invnum) { void update_cached_mouse_cursor() { if (mouseCursor != nullptr) gfxDriver->DestroyDDB(mouseCursor); - mouseCursor = gfxDriver->CreateDDBFromBitmap(mousecurs[0], alpha_blend_cursor != 0); + mouseCursor = gfxDriver->CreateDDBFromBitmap(_G(mousecurs)[0], alpha_blend_cursor != 0); } void set_new_cursor_graphic(int spriteslot) { - mousecurs[0] = spriteset[spriteslot]; + _G(mousecurs)[0] = spriteset[spriteslot]; // It looks like spriteslot 0 can be used in games with version 2.72 and lower. // The NULL check should ensure that the sprite is valid anyway. - if (((spriteslot < 1) && (loaded_game_file_version > kGameVersion_272)) || (mousecurs[0] == nullptr)) { + if (((spriteslot < 1) && (loaded_game_file_version > kGameVersion_272)) || (_G(mousecurs)[0] == nullptr)) { if (blank_mouse_cursor == nullptr) { blank_mouse_cursor = BitmapHelper::CreateTransparentBitmap(1, 1, game.GetColorDepth()); } - mousecurs[0] = blank_mouse_cursor; + _G(mousecurs)[0] = blank_mouse_cursor; } if (game.SpriteInfos[spriteslot].Flags & SPF_ALPHACHANNEL) diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp index b0d6782ffd95..9b662526e354 100644 --- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp +++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp @@ -51,7 +51,7 @@ namespace BitmapHelper = AGS::Shared::BitmapHelper; // #define DEBUG_PATHFINDER #ifdef DEBUG_PATHFINDER -// extern Bitmap *mousecurs[10]; +// extern Bitmap *_G(mousecurs)[10]; #endif namespace AGS { @@ -294,7 +294,7 @@ static int try_this_square(int srcx, int srcy, int tox, int toy) { } #ifdef DEBUG_PATHFINDER - // wputblock(lastcx, lastcy, mousecurs[C_CROSS], 1); + // wputblock(lastcx, lastcy, _G(mousecurs)[C_CROSS], 1); #endif int trydir = DIR_UP; diff --git a/engines/ags/engine/device/mousew32.cpp b/engines/ags/engine/device/mousew32.cpp index 16e65d813bad..ed4497d51d90 100644 --- a/engines/ags/engine/device/mousew32.cpp +++ b/engines/ags/engine/device/mousew32.cpp @@ -56,6 +56,7 @@ #include "ags/engine/main/graphics_mode.h" #include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/shared/util/math.h" +#include "ags/engine/globals.h" #if AGS_SIMULATE_RIGHT_CLICK #include "ags/shared/ac/sys_events.h" // j for ags_iskeypressed #endif @@ -65,25 +66,15 @@ namespace AGS3 { using namespace AGS::Shared; using namespace AGS::Engine; +const int NONE = -1, LEFT = 0, RIGHT = 1, MIDDLE = 2; extern char lib_file_name[13]; - -const char *mouselibcopyr = "MouseLib32 (c) 1994, 1998 Chris Jones"; -const int NONE = -1, LEFT = 0, RIGHT = 1, MIDDLE = 2; -char currentcursor = 0; -// virtual mouse cursor coordinates -int mousex = 0, mousey = 0, numcurso = -1, hotx = 0, hoty = 0; -// real mouse coordinates and bounds -int real_mouse_x = 0, real_mouse_y = 0; -int boundx1 = 0, boundx2 = 99999, boundy1 = 0, boundy2 = 99999; -int disable_mgetgraphpos = 0; -char ignore_bounds = 0; extern char alpha_blend_cursor; -Bitmap *mousecurs[MAXCURSORS]; extern color palette[256]; extern volatile bool switched_away; namespace Mouse { + // Tells whether mouse was locked to the game window bool LockedToWindow = false; @@ -114,14 +105,14 @@ void mgraphconfine(int x1, int y1, int x2, int y2) { void mgetgraphpos() { poll_mouse(); - if (disable_mgetgraphpos) { + if (_G(disable_mgetgraphpos)) { // The cursor coordinates are provided from alternate source; // in this case we completely ignore actual cursor movement. - if (!ignore_bounds && - (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { - mousex = Math::Clamp(mousex, boundx1, boundx2); - mousey = Math::Clamp(mousey, boundy1, boundy2); - msetgraphpos(mousex, mousey); + if (!_G(ignore_bounds) && + (_G(mousex) < _G(boundx1) || _G(mousey) < _G(boundy1) || _G(mousex) > _G(boundx2) || _G(mousey) > _G(boundy2))) { + _G(mousex) = Math::Clamp(_G(mousex), _G(boundx1), _G(boundx2)); + _G(mousey) = Math::Clamp(_G(mousey), _G(boundy1), _G(boundy2)); + msetgraphpos(_G(mousex), _G(mousey)); } return; } @@ -141,55 +132,55 @@ void mgetgraphpos() { //--------------------------------------------------------------------- // If the real cursor is inside the control rectangle (read - game window), // then apply sensitivity factors and adjust real cursor position - if (Mouse::ControlRect.IsInside(real_mouse_x + dx, real_mouse_y + dy)) { - real_mouse_x += dx; - real_mouse_y += dy; - position_mouse(real_mouse_x, real_mouse_y); + if (Mouse::ControlRect.IsInside(_G(real_mouse_x) + dx, _G(real_mouse_y) + dy)) { + _G(real_mouse_x) += dx; + _G(real_mouse_y) += dy; + position_mouse(_G(real_mouse_x), _G(real_mouse_y)); } // Otherwise, if real cursor was moved outside the control rect, yet we // are required to confine cursor inside one, then adjust cursor position // to stay inside the rect's bounds. else if (Mouse::ConfineInCtrlRect) { - real_mouse_x = Math::Clamp(real_mouse_x + dx, Mouse::ControlRect.Left, Mouse::ControlRect.Right); - real_mouse_y = Math::Clamp(real_mouse_y + dy, Mouse::ControlRect.Top, Mouse::ControlRect.Bottom); - position_mouse(real_mouse_x, real_mouse_y); + _G(real_mouse_x) = Math::Clamp(_G(real_mouse_x) + dx, Mouse::ControlRect.Left, Mouse::ControlRect.Right); + _G(real_mouse_y) = Math::Clamp(_G(real_mouse_y) + dy, Mouse::ControlRect.Top, Mouse::ControlRect.Bottom); + position_mouse(_G(real_mouse_x), _G(real_mouse_y)); } // Lastly, if the real cursor is out of the control rect, simply add // actual movement to keep up with the system cursor coordinates. else { - real_mouse_x += mickey_x; - real_mouse_y += mickey_y; + _G(real_mouse_x) += mickey_x; + _G(real_mouse_y) += mickey_y; } // Do not update the game cursor if the real cursor is beyond the control rect - if (!Mouse::ControlRect.IsInside(real_mouse_x, real_mouse_y)) + if (!Mouse::ControlRect.IsInside(_G(real_mouse_x), _G(real_mouse_y))) return; } else { // Save real cursor coordinates provided by system - real_mouse_x = mouse_x; - real_mouse_y = mouse_y; + _G(real_mouse_x) = mouse_x; + _G(real_mouse_y) = mouse_y; } // Set new in-game cursor position - mousex = real_mouse_x; - mousey = real_mouse_y; - - if (!ignore_bounds && - (mousex < boundx1 || mousey < boundy1 || mousex > boundx2 || mousey > boundy2)) { - mousex = Math::Clamp(mousex, boundx1, boundx2); - mousey = Math::Clamp(mousey, boundy1, boundy2); - msetgraphpos(mousex, mousey); + _G(mousex) = _G(real_mouse_x); + _G(mousey) = _G(real_mouse_y); + + if (!_G(ignore_bounds) && + (_G(mousex) < _G(boundx1) || _G(mousey) < _G(boundy1) || _G(mousex) > _G(boundx2) || _G(mousey) > _G(boundy2))) { + _G(mousex) = Math::Clamp(_G(mousex), _G(boundx1), _G(boundx2)); + _G(mousey) = Math::Clamp(_G(mousey), _G(boundy1), _G(boundy2)); + msetgraphpos(_G(mousex), _G(mousey)); } // Convert to virtual coordinates - Mouse::AdjustPosition(mousex, mousey); + Mouse::AdjustPosition(_G(mousex), _G(mousey)); } void msetcursorlimit(int x1, int y1, int x2, int y2) { - boundx1 = x1; - boundy1 = y1; - boundx2 = x2; - boundy2 = y2; + _G(boundx1) = x1; + _G(boundy1) = y1; + _G(boundx2) = x2; + _G(boundy2) = y2; } int hotxwas = 0, hotywas = 0; @@ -198,37 +189,37 @@ void domouse(int str) { TO USE THIS ROUTINE YOU MUST LOAD A MOUSE CURSOR USING mloadcursor. YOU MUST ALSO REMEMBER TO CALL mfreemem AT THE END OF THE PROGRAM. */ - int poow = mousecurs[(int)currentcursor]->GetWidth(); - int pooh = mousecurs[(int)currentcursor]->GetHeight(); - //int smx = mousex - hotxwas, smy = mousey - hotywas; + int poow = _G(mousecurs)[(int)_G(currentcursor)]->GetWidth(); + int pooh = _G(mousecurs)[(int)_G(currentcursor)]->GetHeight(); + //int smx = _G(mousex) - hotxwas, smy = _G(mousey) - hotywas; const Rect &viewport = play.GetMainViewport(); mgetgraphpos(); - mousex -= hotx; - mousey -= hoty; + _G(mousex) -= _G(hotx); + _G(mousey) -= _G(hoty); - if (mousex + poow >= viewport.GetWidth()) - poow = viewport.GetWidth() - mousex; + if (_G(mousex) + poow >= viewport.GetWidth()) + poow = viewport.GetWidth() - _G(mousex); - if (mousey + pooh >= viewport.GetHeight()) - pooh = viewport.GetHeight() - mousey; + if (_G(mousey) + pooh >= viewport.GetHeight()) + pooh = viewport.GetHeight() - _G(mousey); - mousex += hotx; - mousey += hoty; - hotxwas = hotx; - hotywas = hoty; + _G(mousex) += _G(hotx); + _G(mousey) += _G(hoty); + hotxwas = _G(hotx); + hotywas = _G(hoty); } int ismouseinbox(int lf, int tp, int rt, int bt) { - if ((mousex >= lf) & (mousex <= rt) & (mousey >= tp) & (mousey <= bt)) + if ((_G(mousex) >= lf) & (_G(mousex) <= rt) & (_G(mousey) >= tp) & (_G(mousey) <= bt)) return TRUE; else return FALSE; } void mfreemem() { - for (int re = 0; re < numcurso; re++) { - delete mousecurs[re]; + for (int re = 0; re < _G(numcurso); re++) { + delete _G(mousecurs)[re]; } } @@ -237,7 +228,7 @@ void mfreemem() { void mloadwcursor(char *namm) { color dummypal[256]; - if (wloadsprites(&dummypal[0], namm, mousecurs, 0, MAXCURSORS)) { + if (wloadsprites(&dummypal[0], namm, _G(mousecurs), 0, MAXCURSORS)) { error("mloadwcursor: Error reading mouse cursor file"); } } @@ -277,14 +268,14 @@ int misbuttondown(int buno) { } void msetgraphpos(int xa, int ya) { - real_mouse_x = xa; - real_mouse_y = ya; - position_mouse(real_mouse_x, real_mouse_y); + _G(real_mouse_x) = xa; + _G(real_mouse_y) = ya; + position_mouse(_G(real_mouse_x), _G(real_mouse_y)); } void msethotspot(int xx, int yy) { - hotx = xx; // mousex -= hotx; mousey -= hoty; - hoty = yy; // mousex += hotx; mousey += hoty; + _G(hotx) = xx; // _G(mousex) -= _G(hotx); _G(mousey) -= _G(hoty); + _G(hoty) = yy; // _G(mousex) += _G(hotx); _G(mousey) += _G(hoty); } int minstalled() { diff --git a/engines/ags/engine/device/mousew32.h b/engines/ags/engine/device/mousew32.h index 87185517de44..4cee33c6fb37 100644 --- a/engines/ags/engine/device/mousew32.h +++ b/engines/ags/engine/device/mousew32.h @@ -32,9 +32,6 @@ //============================================================================= #include "ags/shared/util/geometry.h" - -#define MAXCURSORS 20 - #include "ags/shared/util/geometry.h" namespace AGS3 { @@ -98,13 +95,4 @@ void SetMoveLimit(const Rect &r); void SetPosition(const Point p); } // namespace Mouse - - -extern int mousex, mousey; -extern int hotx, hoty; -extern int disable_mgetgraphpos; -extern char currentcursor; - -extern Shared::Bitmap *mousecurs[MAXCURSORS]; - } // namespace AGS3 diff --git a/engines/ags/engine/globals.cpp b/engines/ags/engine/globals.cpp index cd161a794e51..88b516c91a3b 100644 --- a/engines/ags/engine/globals.cpp +++ b/engines/ags/engine/globals.cpp @@ -28,6 +28,8 @@ Globals *g_globals; Globals::Globals() { g_globals = this; + + Common::fill(&_mousecurs[0], &_mousecurs[MAXCURSORS], nullptr); } Globals::~Globals() { diff --git a/engines/ags/engine/globals.h b/engines/ags/engine/globals.h index e8b8b908ead3..b13038e84f9d 100644 --- a/engines/ags/engine/globals.h +++ b/engines/ags/engine/globals.h @@ -29,9 +29,17 @@ namespace AGS3 { +#define MAXCURSORS 20 + using String = AGS::Shared::String; using Version = AGS::Shared::Version; +namespace AGS { +namespace Shared { +class Bitmap; +} // namespace Shared +} // namespace AGS + class Globals { public: /** @@ -96,6 +104,23 @@ class Globals { /**@}*/ + /** + * \defgroup mouse globals + * @{ + */ + + char _currentcursor = 0; + // virtual mouse cursor coordinates + int _mousex = 0, _mousey = 0, _numcurso = -1, _hotx = 0, _hoty = 0; + // real mouse coordinates and bounds + int _real_mouse_x = 0, _real_mouse_y = 0; + int _boundx1 = 0, _boundx2 = 99999, _boundy1 = 0, _boundy2 = 99999; + int _disable_mgetgraphpos = 0; + char _ignore_bounds = 0; + AGS::Shared::Bitmap *_mousecurs[MAXCURSORS]; + + /**@}*/ + /** * \defgroup quit globals * @{ diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index 25f4c7db1869..5f26837c58b7 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -42,13 +42,13 @@ #include "ags/engine/media/audio/audio_system.h" #include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/engine/ac/timer.h" +#include "ags/engine/globals.h" namespace AGS3 { using AGS::Shared::Bitmap; namespace BitmapHelper = AGS::Shared::BitmapHelper; -extern char ignore_bounds; // from mousew32 extern IGraphicsDriver *gfxDriver; extern GameSetup usetup; @@ -97,7 +97,7 @@ int CSCIGetVersion() { int windowcount = 0, curswas = 0; int win_x = 0, win_y = 0, win_width = 0, win_height = 0; int CSCIDrawWindow(int xx, int yy, int wid, int hit) { - ignore_bounds++; + _G(ignore_bounds)++; multiply_up(&xx, &yy, &wid, &hit); int drawit = -1; for (int aa = 0; aa < MAXSCREENWINDOWS; aa++) { @@ -133,7 +133,7 @@ int CSCIDrawWindow(int xx, int yy, int wid, int hit) { void CSCIEraseWindow(int handl) { // ags_domouse(DOMOUSE_DISABLE); - ignore_bounds--; + _G(ignore_bounds)--; topwindowhandle = oswi[handl].oldtop; oswi[handl].handle = -1; // ags_domouse(DOMOUSE_ENABLE); @@ -275,8 +275,8 @@ void multiply_up(int *x1, int *y1, int *x2, int *y2) { int checkcontrols() { // NOTE: this is because old code was working with full game screen - const int mouseX = AGS3::mousex - win_x; - const int mouseY = AGS3::mousey - win_y; + const int mouseX = _G(mousex) - win_x; + const int mouseY = _G(mousey) - win_y; smcode = 0; for (int kk = 0; kk < MAXCONTROLS; kk++) { diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index 339cabce1011..c0e77e92da02 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -29,14 +29,13 @@ #include "ags/engine/gui/guidialog.h" #include "ags/engine/gui/guidialoginternaldefs.h" #include "ags/engine/gui/mylistbox.h" +#include "ags/engine/globals.h" namespace AGS3 { using AGS::Shared::Bitmap; extern GameSetup usetup; -extern int numcurso, hotx, hoty; - extern int windowbackgroundcolor; extern int cbuttfont; extern int smcode; @@ -111,14 +110,14 @@ void MyListBox::draw(Bitmap *ds) { } int MyListBox::pressedon(int mousex, int mousey) { - if (mousex > x + wid - ARROWWIDTH) { - if ((mousey - y < hit / 2) & (topitem > 0)) + if (_G(mousex) > x + wid - ARROWWIDTH) { + if ((_G(mousey) - y < hit / 2) & (topitem > 0)) topitem--; - else if ((mousey - y > hit / 2) &(topitem + numonscreen < items)) + else if ((_G(mousey) - y > hit / 2) &(topitem + numonscreen < items)) topitem++; } else { - selected = ((mousey - y) - 2) / TEXT_HT + topitem; + selected = ((_G(mousey) - y) - 2) / TEXT_HT + topitem; if (selected >= items) selected = items - 1; diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index b5bb5a5da71d..f4dcc4c86b5f 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -32,6 +32,7 @@ #include "ags/shared/gfx/bitmap.h" #include "ags/engine/platform/base/agsplatformdriver.h" #include "ags/engine/ac/timer.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -85,7 +86,7 @@ int MyPushButton::pressedon(int mousex, int mousey) { while (mbutrelease(LEFT) == 0) { wasstat = state; - state = mouseisinarea(mousex, mousey); + state = mouseisinarea(_G(mousex), _G(mousey)); // stop mp3 skipping if button held down update_polled_stuff_if_runtime(); if (wasstat != state) { diff --git a/engines/ags/engine/gui/newcontrol.cpp b/engines/ags/engine/gui/newcontrol.cpp index f17d444ed493..d709adf82bca 100644 --- a/engines/ags/engine/gui/newcontrol.cpp +++ b/engines/ags/engine/gui/newcontrol.cpp @@ -23,6 +23,7 @@ #include "ags/engine/gui/newcontrol.h" #include "ags/engine/gui/guidialog.h" #include "ags/engine/gui/guidialoginternaldefs.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -55,7 +56,7 @@ int NewControl::mouseisinarea(int mousex, int mousey) { if (topwindowhandle != wlevel) return 0; - if ((mousex > x) &(mousex < x + wid) &(mousey > y) &(mousey < y + hit)) + if ((_G(mousex) > x) &(_G(mousex) < x + wid) &(_G(mousey) > y) &(_G(mousey) < y + hit)) return 1; return 0; diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index 7e0df18447bf..fb157b5fa4d0 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -810,7 +810,7 @@ void engine_init_game_settings() { } for (ee = 0; ee < game.numcursors; ee++) { - // The cursor graphics are assigned to mousecurs[] and so cannot + // The cursor graphics are assigned to _G(mousecurs)[] and so cannot // be removed from memory if (game.mcurs[ee].pic >= 0) spriteset.Precache(game.mcurs[ee].pic); @@ -1039,9 +1039,9 @@ void engine_init_game_settings() { update_invorder(); displayed_room = -10; - currentcursor = 0; + _G(currentcursor) = 0; our_eip = -4; - mousey = 100; // stop icon bar popping up + _G(mousey) = 100; // stop icon bar popping up // We use same variable to read config and be used at runtime for now, // so update it here with regards to game design option diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 173e3dd998f1..3441ed99d1eb 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -227,7 +227,7 @@ static void check_mouse_controls() { mongu = gui_on_mouse_move(); mouse_on_iface = mongu; - if ((ifacepopped >= 0) && (mousey >= guis[ifacepopped].Y + guis[ifacepopped].Height)) + if ((ifacepopped >= 0) && (_G(mousey) >= guis[ifacepopped].Y + guis[ifacepopped].Height)) remove_popup_interface(ifacepopped); // check mouse clicks on GUIs @@ -621,7 +621,7 @@ static void game_loop_update_animated_buttons() { static void game_loop_do_render_and_check_mouse(IDriverDependantBitmap *extraBitmap, int extraX, int extraY) { if (!play.fast_forward) { - int mwasatx = mousex, mwasaty = mousey; + int mwasatx = _G(mousex), mwasaty = _G(mousey); // Only do this if we are not skipping a cutscene render_graphics(extraBitmap, extraX, extraY); @@ -632,7 +632,7 @@ static void game_loop_do_render_and_check_mouse(IDriverDependantBitmap *extraBit // TODO: if we support rotation then we also need to compare full transform! if (displayed_room < 0) return; - auto view = play.GetRoomViewportAt(mousex, mousey); + auto view = play.GetRoomViewportAt(_G(mousex), _G(mousey)); auto cam = view ? view->GetCamera() : nullptr; if (cam) { // NOTE: all cameras are in same room right now, so their positions are in same coordinate system; @@ -641,10 +641,10 @@ static void game_loop_do_render_and_check_mouse(IDriverDependantBitmap *extraBit int offsetx = cam->GetRect().Left; int offsety = cam->GetRect().Top; - if (((mwasatx != mousex) || (mwasaty != mousey) || + if (((mwasatx != _G(mousex)) || (mwasaty != _G(mousey)) || (offsetxWas != offsetx) || (offsetyWas != offsety))) { // mouse moves over hotspot - if (__GetLocationType(game_to_data_coord(mousex), game_to_data_coord(mousey), 1) == LOCTYPE_HOTSPOT) { + if (__GetLocationType(game_to_data_coord(_G(mousex)), game_to_data_coord(_G(mousey)), 1) == LOCTYPE_HOTSPOT) { int onhs = getloctype_index; setevent(EV_RUNEVBLOCK, EVB_HOTSPOT, onhs, 6); @@ -813,7 +813,7 @@ static void UpdateMouseOverLocation() { // Call GetLocationName - it will internally force a GUI refresh // if the result it returns has changed from last time char tempo[STD_BUFFER_SIZE]; - GetLocationName(game_to_data_coord(mousex), game_to_data_coord(mousey), tempo); + GetLocationName(game_to_data_coord(_G(mousex)), game_to_data_coord(_G(mousey)), tempo); if ((play.get_loc_name_save_cursor >= 0) && (play.get_loc_name_save_cursor != play.get_loc_name_last_time) && diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 7844c2e24c0f..9ef1f677cce9 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -74,6 +74,7 @@ #include "ags/shared/util/filestream.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/engine/util/library.h" +#include "ags/engine/globals.h" #if defined(BUILTIN_PLUGINS) #include "ags/shared/../Plugins/AGSflashlight/agsflashlight.h" @@ -93,7 +94,6 @@ using namespace AGS::Shared::Memory; using namespace AGS::Engine; extern IGraphicsDriver *gfxDriver; -extern int mousex, mousey; extern int displayed_room; extern RoomStruct thisroom; extern GameSetupStruct game; @@ -290,8 +290,8 @@ void IAGSEngine::ReleaseBitmapSurface(BITMAP *bmp) { } void IAGSEngine::GetMousePosition(int32 *x, int32 *y) { - if (x) x[0] = mousex; - if (y) y[0] = mousey; + if (x) x[0] = _G(mousex); + if (y) y[0] = _G(mousey); } int IAGSEngine::GetCurrentRoom() { return displayed_room; diff --git a/engines/ags/shared/ac/interfaceelement.h b/engines/ags/shared/ac/interfaceelement.h index 69f8fcaa02f4..a07a316cbf77 100644 --- a/engines/ags/shared/ac/interfaceelement.h +++ b/engines/ags/shared/ac/interfaceelement.h @@ -37,7 +37,7 @@ struct InterfaceElement { InterfaceButton button[MAXBUTTON]; int flags; int reserved_for_future; - int popupyp; // pops up when mousey < this + int popupyp; // pops up when _G(mousey) < this char popup; // does it pop up? (like sierra icon bar) char on; InterfaceElement(); diff --git a/engines/ags/shared/ac/mousecursor.cpp b/engines/ags/shared/ac/mousecursor.cpp index 8acbf41b41de..cde072b2076c 100644 --- a/engines/ags/shared/ac/mousecursor.cpp +++ b/engines/ags/shared/ac/mousecursor.cpp @@ -22,6 +22,7 @@ #include "ags/shared/ac/mousecursor.h" #include "ags/shared/util/stream.h" +#include "ags/engine/globals.h" namespace AGS3 { diff --git a/engines/ags/shared/gui/guimain.cpp b/engines/ags/shared/gui/guimain.cpp index 889bf289f712..9481df5d6a72 100644 --- a/engines/ags/shared/gui/guimain.cpp +++ b/engines/ags/shared/gui/guimain.cpp @@ -34,6 +34,7 @@ #include "ags/shared/util/stream.h" #include "ags/shared/util/string_utils.h" #include "ags/lib/std/algorithm.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -98,7 +99,7 @@ int GUIMain::FindControlUnderMouse(int leeway, bool must_be_clickable) const { continue; if (!_controls[i]->IsClickable() && must_be_clickable) continue; - if (_controls[i]->IsOverControl(mousex, mousey, leeway)) + if (_controls[i]->IsOverControl(_G(mousex), _G(mousey), leeway)) return i; } } else { @@ -108,7 +109,7 @@ int GUIMain::FindControlUnderMouse(int leeway, bool must_be_clickable) const { continue; if (!_controls[ctrl_index]->IsClickable() && must_be_clickable) continue; - if (_controls[ctrl_index]->IsOverControl(mousex, mousey, leeway)) + if (_controls[ctrl_index]->IsOverControl(_G(mousex), _G(mousey), leeway)) return ctrl_index; } } @@ -279,15 +280,15 @@ void GUIMain::DrawBlob(Bitmap *ds, int x, int y, color_t draw_color) { } void GUIMain::Poll() { - int mxwas = mousex, mywas = mousey; + int mxwas = _G(mousex), mywas = _G(mousey); - mousex -= X; - mousey -= Y; - if (mousex != MouseWasAt.X || mousey != MouseWasAt.Y) { + _G(mousex) -= X; + _G(mousey) -= Y; + if (_G(mousex) != MouseWasAt.X || _G(mousey) != MouseWasAt.Y) { int ctrl_index = FindControlUnderMouse(); if (MouseOverCtrl == MOVER_MOUSEDOWNLOCKED) - _controls[MouseDownCtrl]->OnMouseMove(mousex, mousey); + _controls[MouseDownCtrl]->OnMouseMove(_G(mousex), _G(mousey)); else if (ctrl_index != MouseOverCtrl) { if (MouseOverCtrl >= 0) _controls[MouseOverCtrl]->OnMouseLeave(); @@ -303,18 +304,18 @@ void GUIMain::Poll() { MouseOverCtrl = ctrl_index; if (MouseOverCtrl >= 0) { _controls[MouseOverCtrl]->OnMouseEnter(); - _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); + _controls[MouseOverCtrl]->OnMouseMove(_G(mousex), _G(mousey)); } } guis_need_update = 1; } else if (MouseOverCtrl >= 0) - _controls[MouseOverCtrl]->OnMouseMove(mousex, mousey); + _controls[MouseOverCtrl]->OnMouseMove(_G(mousex), _G(mousey)); } - MouseWasAt.X = mousex; - MouseWasAt.Y = mousey; - mousex = mxwas; - mousey = mywas; + MouseWasAt.X = _G(mousex); + MouseWasAt.Y = _G(mousey); + _G(mousex) = mxwas; + _G(mousey) = mywas; } HError GUIMain::RebuildArray() { @@ -449,7 +450,7 @@ void GUIMain::OnMouseButtonDown() { MouseDownCtrl = MouseOverCtrl; if (_controls[MouseOverCtrl]->OnMouseDown()) MouseOverCtrl = MOVER_MOUSEDOWNLOCKED; - _controls[MouseDownCtrl]->OnMouseMove(mousex - X, mousey - Y); + _controls[MouseDownCtrl]->OnMouseMove(_G(mousex) - X, _G(mousey) - Y); guis_need_update = 1; } diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h index 3e72bbae29f2..670f52a9806e 100644 --- a/engines/ags/shared/gui/guimain.h +++ b/engines/ags/shared/gui/guimain.h @@ -171,7 +171,7 @@ class GUIMain { // and text color in text windows) int32_t Padding; // padding surrounding a GUI text window GUIPopupStyle PopupStyle; // GUI popup behavior - int32_t PopupAtMouseY; // popup when mousey < this + int32_t PopupAtMouseY; // popup when _G(mousey) < this int32_t Transparency; // "incorrect" alpha (in legacy 255-range units) int32_t ZOrder; @@ -222,8 +222,6 @@ extern std::vector guis; extern int all_buttons_disabled, gui_inv_pic; extern int gui_disabled_style; -extern int mousex, mousey; - extern int get_adjusted_spritewidth(int spr); extern int get_adjusted_spriteheight(int spr); extern bool is_sprite_alpha(int spr); From 1a9e9b6de0d5c8c686309edab8662da7504c8b8b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jan 2021 21:53:32 -0800 Subject: [PATCH 144/215] AGS: Move debugger globals to Globals --- engines/ags/ags.cpp | 7 ++-- engines/ags/engine/ac/global_game.cpp | 2 +- engines/ags/engine/debugging/debug.cpp | 42 +++++++++-------------- engines/ags/engine/debugging/debugger.h | 6 ---- engines/ags/engine/globals.h | 16 +++++++++ engines/ags/engine/main/game_run.cpp | 2 +- engines/ags/engine/main/game_start.cpp | 2 +- engines/ags/engine/main/graphics_mode.cpp | 4 +-- engines/ags/engine/main/quit.cpp | 6 ++-- engines/ags/engine/plugin/agsplugin.cpp | 4 +-- 10 files changed, 44 insertions(+), 47 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index e282601452f3..09a58e539df9 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -72,9 +72,6 @@ extern GameState play; extern int our_eip; extern AGSPlatformDriver *platform; extern int convert_16bit_bgr; -extern int editor_debugging_enabled; -extern int editor_debugging_initialized; -extern char editor_debugger_instance_token[100]; // this needs to be updated if the "play" struct changes #define SVG_VERSION_BWCOMPAT_MAJOR 3 @@ -161,8 +158,8 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { _G(loadSaveGameOnStartup) = argv[ee + 1]; ee++; } else if ((scumm_stricmp(arg, "--enabledebugger") == 0) && (argc > ee + 1)) { - strcpy(editor_debugger_instance_token, argv[ee + 1]); - editor_debugging_enabled = 1; + strcpy(_G(editor_debugger_instance_token), argv[ee + 1]); + _G(editor_debugging_enabled) = 1; _G(force_window) = 1; ee++; } else if (scumm_stricmp(arg, "--runfromide") == 0 && (argc > ee + 3)) { diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index d1c2fbeb83b2..37684f36b809 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -246,7 +246,7 @@ int RunAGSGame(const char *newgame, unsigned int mode, int data) { if ((mode & (~AllowedModes)) != 0) quit("!RunAGSGame: mode value unknown"); - if (editor_debugging_enabled) { + if (_G(editor_debugging_enabled)) { quit("!RunAGSGame cannot be used while running the game from within the AGS Editor. You must build the game EXE and run it from there to use this function."); } diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index c2454a27fd0c..016f2b471c29 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -62,14 +62,6 @@ extern RoomStruct thisroom; extern char pexbuf[STD_BUFFER_SIZE]; extern GameSetupStruct game; - -int editor_debugging_enabled = 0; -int editor_debugging_initialized = 0; -char editor_debugger_instance_token[100]; -IAGSEditorDebugger *editor_debugger = nullptr; -int break_on_next_script_step = 0; -volatile int game_paused_in_debugger = 0; - #if AGS_PLATFORM_OS_WINDOWS #include "ags/shared/platform/windows/debug/namedpipesagsdebugger.h" @@ -373,7 +365,7 @@ bool send_message_to_editor(const char *msg, const char *errorMsg) { } strcat(messageToSend, ""); - editor_debugger->SendMessageToEditor(messageToSend); + _G(editor_debugger)->SendMessageToEditor(messageToSend); return true; } @@ -384,17 +376,17 @@ bool send_message_to_editor(const char *msg) { bool init_editor_debugging() { #if AGS_PLATFORM_OS_WINDOWS - editor_debugger = GetEditorDebugger(editor_debugger_instance_token); + _G(editor_debugger) = GetEditorDebugger(_G(editor_debugger_instance_token)); #else // Editor isn't ported yet - editor_debugger = nullptr; + _G(editor_debugger) = nullptr; #endif - if (editor_debugger == nullptr) - quit("editor_debugger is NULL but debugger enabled"); + if (_G(editor_debugger) == nullptr) + quit("_G(editor_debugger) is NULL but debugger enabled"); - if (editor_debugger->Initialize()) { - editor_debugging_initialized = 1; + if (_G(editor_debugger)->Initialize()) { + _G(editor_debugging_initialized) = 1; // Wait for the editor to send the initial breakpoints // and then its READY message @@ -410,8 +402,8 @@ bool init_editor_debugging() { } int check_for_messages_from_editor() { - if (editor_debugger->IsMessageAvailable()) { - char *msg = editor_debugger->GetNextMessage(); + if (_G(editor_debugger)->IsMessageAvailable()) { + char *msg = _G(editor_debugger)->GetNextMessage(); if (msg == nullptr) { return 0; } @@ -466,10 +458,10 @@ int check_for_messages_from_editor() { numBreakpoints++; } } else if (strncmp(msgPtr, "RESUME", 6) == 0) { - game_paused_in_debugger = 0; + _G(game_paused_in_debugger) = 0; } else if (strncmp(msgPtr, "STEP", 4) == 0) { - game_paused_in_debugger = 0; - break_on_next_script_step = 1; + _G(game_paused_in_debugger) = 0; + _G(break_on_next_script_step) = 1; } else if (strncmp(msgPtr, "EXIT", 4) == 0) { _G(want_exit) = 1; _G(abort_engine) = 1; @@ -512,9 +504,9 @@ void break_into_debugger() { SetForegroundWindow(editor_window_handle); send_message_to_editor("BREAK"); - game_paused_in_debugger = 1; + _G(game_paused_in_debugger) = 1; - while (game_paused_in_debugger) { + while (_G(game_paused_in_debugger)) { update_polled_stuff_if_runtime(); platform->YieldCPU(); } @@ -542,8 +534,8 @@ void scriptDebugHook(ccInstance *ccinst, int linenum) { return; } - if (break_on_next_script_step) { - break_on_next_script_step = 0; + if (_G(break_on_next_script_step)) { + _G(break_on_next_script_step) = 0; break_into_debugger(); return; } @@ -568,7 +560,7 @@ void check_debug_keys() { if (!::AGS::g_events->isKeyPressed(KEY_SCRLOCK) && scrlockWasDown) scrlockWasDown = 0; else if (::AGS::g_events->isKeyPressed(KEY_SCRLOCK) && !scrlockWasDown) { - break_on_next_script_step = 1; + _G(break_on_next_script_step) = 1; scrlockWasDown = 1; } } diff --git a/engines/ags/engine/debugging/debugger.h b/engines/ags/engine/debugging/debugger.h index 8e87d71f22d5..7e4b07041339 100644 --- a/engines/ags/engine/debugging/debugger.h +++ b/engines/ags/engine/debugging/debugger.h @@ -30,12 +30,6 @@ namespace AGS3 { struct IAGSEditorDebugger; struct ScriptPosition; -extern int editor_debugging_enabled; -extern int editor_debugging_initialized; -extern char editor_debugger_instance_token[100]; -extern IAGSEditorDebugger *editor_debugger; -extern int break_on_next_script_step; - int check_for_messages_from_editor(); bool send_message_to_editor(const char *msg); bool send_exception_to_editor(const char *qmsg); diff --git a/engines/ags/engine/globals.h b/engines/ags/engine/globals.h index b13038e84f9d..6cca2e29d39f 100644 --- a/engines/ags/engine/globals.h +++ b/engines/ags/engine/globals.h @@ -40,6 +40,8 @@ class Bitmap; } // namespace Shared } // namespace AGS +struct IAGSEditorDebugger; + class Globals { public: /** @@ -53,6 +55,20 @@ class Globals { /**@}*/ + /** + * \defgroup debug globals + * @{ + */ + + int _editor_debugging_enabled = 0; + int _editor_debugging_initialized = 0; + char _editor_debugger_instance_token[100]; + IAGSEditorDebugger *_editor_debugger = nullptr; + int _break_on_next_script_step = 0; + volatile int _game_paused_in_debugger = 0; + + /**@}*/ + /** * \defgroup main globals * @{ diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 3441ed99d1eb..68a830ee8315 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -1010,7 +1010,7 @@ void update_polled_stuff_if_runtime() { update_polled_mp3(); - if (editor_debugging_initialized) + if (_G(editor_debugging_initialized)) check_for_messages_from_editor(); } diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 11143a035ff5..5ea5356fe384 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -60,7 +60,7 @@ extern CharacterInfo *playerchar; extern int convert_16bit_bgr; void start_game_init_editor_debugging() { - if (editor_debugging_enabled) { + if (_G(editor_debugging_enabled)) { SetMultitasking(1); if (init_editor_debugging()) { auto waitUntil = AGS_Clock::now() + std::chrono::milliseconds(500); diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp index 63490180e9e8..9fbdb6aa6bee 100644 --- a/engines/ags/engine/main/graphics_mode.cpp +++ b/engines/ags/engine/main/graphics_mode.cpp @@ -24,7 +24,6 @@ // Graphics initialization // -//include #include "ags/shared/core/platform.h" #include "ags/engine/ac/draw.h" #include "ags/engine/debugging/debugger.h" @@ -39,6 +38,7 @@ #include "ags/engine/main/graphics_mode.h" #include "ags/engine/main/main_allegro.h" #include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/globals.h" namespace AGS3 { @@ -378,7 +378,7 @@ bool create_gfx_driver_and_init_mode_any(const String &gfx_driver_id, const Size bool result = try_init_mode_using_setup(game_size, dm_setup, use_col_depth, frame_setup, filter_setup); // Try windowed mode if fullscreen failed, and vice versa - if (!result && editor_debugging_enabled == 0) { + if (!result && _G(editor_debugging_enabled) == 0) { // we need to clone from initial config, because not every parameter is set by graphics_mode_get_defaults() DisplayModeSetup dm_setup_alt = dm_setup; dm_setup_alt.Windowed = !dm_setup.Windowed; diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 9b33146a00c2..822b2737175f 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -63,8 +63,6 @@ extern GameSetup usetup; extern char pexbuf[STD_BUFFER_SIZE]; extern int proper_exit; extern char check_dynamic_sprites_at_exit; -extern int editor_debugging_initialized; -extern IAGSEditorDebugger *editor_debugger; extern int need_to_stop_cd; extern int use_cdplayer; extern IGraphicsDriver *gfxDriver; @@ -74,11 +72,11 @@ extern Bitmap *test_allegro_bitmap; extern IDriverDependantBitmap *test_allegro_ddb; void quit_tell_editor_debugger(const String &qmsg, QuitReason qreason) { - if (editor_debugging_initialized) { + if (_G(editor_debugging_initialized)) { if (qreason & kQuitKind_GameException) _G(handledErrorInEditor) = send_exception_to_editor(qmsg); send_message_to_editor("EXIT"); - editor_debugger->Shutdown(); + _G(editor_debugger)->Shutdown(); } } diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 9ef1f677cce9..626ced045aa2 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -833,7 +833,7 @@ void IAGSEngine::GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int3 } int IAGSEngine::IsRunningUnderDebugger() { - return (editor_debugging_enabled != 0) ? 1 : 0; + return (_G(editor_debugging_enabled) != 0) ? 1 : 0; } void IAGSEngine::GetPathToFileInCompiledFolder(const char *fileName, char *buffer) { @@ -841,7 +841,7 @@ void IAGSEngine::GetPathToFileInCompiledFolder(const char *fileName, char *buffe } void IAGSEngine::BreakIntoDebugger() { - break_on_next_script_step = 1; + _G(break_on_next_script_step) = 1; } IAGSFontRenderer *IAGSEngine::ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer) { From 549294d5e4857f8f34377e2b5c3c71cd97e2ac5e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 Jan 2021 19:25:10 -0800 Subject: [PATCH 145/215] AGS: Fix spurious bool comparisons --- engines/ags/engine/ac/dialog.cpp | 2 +- engines/ags/engine/ac/global_game.cpp | 2 +- engines/ags/engine/debugging/filebasedagsdebugger.cpp | 2 +- engines/ags/shared/gui/guiobject.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp index 1bf4e468e94c..cd7f1b294e2d 100644 --- a/engines/ags/engine/ac/dialog.cpp +++ b/engines/ags/engine/ac/dialog.cpp @@ -959,7 +959,7 @@ bool DialogOptions::Run() { if (parserActivated) { // They have selected a custom parser-based option - if (!parserInput->Text.IsEmpty() != 0) { + if (!parserInput->Text.IsEmpty()) { chose = DLG_OPTION_PARSER; return false; // end dialog options running loop } else { diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 37684f36b809..64603bafa340 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -850,7 +850,7 @@ int SaveScreenShot(const char *namm) { fileName.Format("%s%s", svg_dir.GetCStr(), namm); Bitmap *buffer = CopyScreenIntoBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight()); - if (!buffer->SaveToFile(fileName, palette) != 0) { + if (!buffer->SaveToFile(fileName, palette)) { delete buffer; return 0; } diff --git a/engines/ags/engine/debugging/filebasedagsdebugger.cpp b/engines/ags/engine/debugging/filebasedagsdebugger.cpp index c8e6b420225f..3975ffd3abd4 100644 --- a/engines/ags/engine/debugging/filebasedagsdebugger.cpp +++ b/engines/ags/engine/debugging/filebasedagsdebugger.cpp @@ -74,7 +74,7 @@ bool FileBasedAGSDebugger::SendMessageToEditor(const char *message) { } bool FileBasedAGSDebugger::IsMessageAvailable() { - return (exists("dbgsend.tmp") != 0); + return exists("dbgsend.tmp"); } char *FileBasedAGSDebugger::GetNextMessage() { diff --git a/engines/ags/shared/gui/guiobject.cpp b/engines/ags/shared/gui/guiobject.cpp index 81387b1c2a2c..6ba23826e596 100644 --- a/engines/ags/shared/gui/guiobject.cpp +++ b/engines/ags/shared/gui/guiobject.cpp @@ -167,7 +167,7 @@ void GUIObject::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver) { Height = in->ReadInt32(); ZOrder = in->ReadInt32(); // Dynamic state - IsActivated = in->ReadBool() ? 1 : 0; + IsActivated = in->ReadBool(); } void GUIObject::WriteToSavegame(Stream *out) const { @@ -179,7 +179,7 @@ void GUIObject::WriteToSavegame(Stream *out) const { out->WriteInt32(Height); out->WriteInt32(ZOrder); // Dynamic state - out->WriteBool(IsActivated != 0); + out->WriteBool(IsActivated); } From 6852be9bd9ce9b0ae995654fe23cfd4c82b3bcf6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 Jan 2021 19:28:16 -0800 Subject: [PATCH 146/215] AGS: Use empty() rather than size() == 0 --- engines/ags/engine/ac/draw_software.cpp | 2 +- engines/ags/engine/ac/scriptcontainers.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/ags/engine/ac/draw_software.cpp b/engines/ags/engine/ac/draw_software.cpp index e6af2262bcb3..67eb7450db1c 100644 --- a/engines/ags/engine/ac/draw_software.cpp +++ b/engines/ags/engine/ac/draw_software.cpp @@ -440,7 +440,7 @@ void update_black_invreg_and_reset(Bitmap *ds) { } void update_room_invreg_and_reset(int view_index, Bitmap *ds, Bitmap *src, bool no_transform) { - if (view_index < 0 || RoomCamRects.size() == 0) + if (view_index < 0 || RoomCamRects.empty()) return; update_invalid_region(ds, src, RoomCamRects[view_index], no_transform); diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp index 10700dca701b..0baa5ea9715f 100644 --- a/engines/ags/engine/ac/scriptcontainers.cpp +++ b/engines/ags/engine/ac/scriptcontainers.cpp @@ -119,7 +119,7 @@ int Dict_GetItemCount(ScriptDictBase *dic) { void *Dict_GetKeysAsArray(ScriptDictBase *dic) { std::vector items; dic->GetKeys(items); - if (items.size() == 0) + if (items.empty()) return nullptr; DynObjectRef arr = DynamicArrayHelpers::CreateStringArray(items); return arr.second; From c9aab47a8300b3487dd802c3113153f858c428b0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 19 Jan 2021 20:34:10 -0800 Subject: [PATCH 147/215] AGS: Compilation fix when tests are enabled --- engines/ags/tests/test_inifile.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/engines/ags/tests/test_inifile.cpp b/engines/ags/tests/test_inifile.cpp index 75781c427a3e..ec0399e83f78 100644 --- a/engines/ags/tests/test_inifile.cpp +++ b/engines/ags/tests/test_inifile.cpp @@ -75,6 +75,35 @@ const char *IniFileText2 = "" "item5_2=value5_2" ENDL "item5_3=value5_3" ENDL; +bool operator==(const StringOrderMap &lhs, const StringOrderMap &rhs) { + if (lhs.size() != rhs.size()) + return false; + + StringOrderMap::const_iterator it1 = lhs.begin(); + StringOrderMap::const_iterator it2 = rhs.begin(); + + for (; it1 != lhs.end(); ++it1, ++it2) { + if (it1->_key || it2->_key || it1->_value != it2->_value) + return false; + } + + return true; +} + +bool operator==(const ConfigTree &lhs, const ConfigTree &rhs) { + if (lhs.size() != rhs.size()) + return false; + + ConfigTree::const_iterator it1 = lhs.begin(); + ConfigTree::const_iterator it2 = rhs.begin(); + + for (; it1 != lhs.end(); ++it1, ++it2) { + if (it1->_key || it2->_key || !(it1->_value == it2->_value)) + return false; + } + + return true; +} void Test_IniFile() { Stream *fs = File::CreateFile("test.ini"); From 3b8911abf0a18cb3d5b0baad6a1191e688525b8b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 Jan 2021 21:12:38 -0800 Subject: [PATCH 148/215] AGS: Fix games that write to files in the game folder This fixes a crash at the very startup of The Blackwell Legacy, which reads from a file prog.bwl in the game folder, and then writes out a new version. In the new scheme, all data files will try to be accessed from the save folder first, and then fall back on the game folder. So this allows Blackwell to first read from the game folder prog.bwl, then create it's own --- engines/ags/detection_tables.h | 2 ++ engines/ags/engine/ac/file.cpp | 20 +++++++++++++++++++- engines/ags/engine/ac/global_file.cpp | 5 +---- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index bf615503a4bf..af315a8bdb04 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -27,6 +27,7 @@ static const PlainGameDescriptor GAME_NAMES[] = { { "atotk", "A Tale Of Two Kingdoms" }, { "bcremake", "Black Cauldron Remake" }, + { "blackwelllegacy", "The Blackwell Legacy" }, { "kq2agdi", "Kings Quest II - Romancing The Stones" }, { 0, 0 } @@ -47,6 +48,7 @@ static const PlainGameDescriptor GAME_NAMES[] = { static const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), + ENGLISH_ENTRY("blackwelllegacy", "blackwell1.exe", "605e124cb7e0b56841c471e2d641c224", 18822697), ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), // 3.1 { AD_TABLE_END_MARKER } diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index 263885359c16..a0b5f7cc4d6e 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -272,7 +272,7 @@ String MakeSpecialSubDir(const String &sp_dir) { } String MakeAppDataPath() { - return AGS::Shared::SAVE_FOLDER_PREFIX; + return "./"; } bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath &rp) { @@ -289,6 +289,23 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath return true; } +#if AGS_PLATFORM_SCUMMVM + if (read_only) { + // For reading files, first try as a save file, then fall back + // in the game folder. This handles cases where some games like + // The Blackwell Legacy write to files in the game folder + rp.BaseDir = SAVE_FOLDER_PREFIX; + rp.FullPath = String::FromFormat("%s%s", SAVE_FOLDER_PREFIX, + orig_sc_path.GetNullableCStr()); + rp.AltPath = orig_sc_path; + } else { + // For writing files, always use as save files + rp.BaseDir = SAVE_FOLDER_PREFIX; + rp.FullPath = String::FromFormat("%s%s", SAVE_FOLDER_PREFIX, + orig_sc_path.GetNullableCStr()); + } + +#else String sc_path = FixSlashAfterToken(orig_sc_path); String parent_dir; String child_path; @@ -348,6 +365,7 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath rp.BaseDir = parent_dir; rp.FullPath = full_path; rp.AltPath = alt_path; +#endif return true; } diff --git a/engines/ags/engine/ac/global_file.cpp b/engines/ags/engine/ac/global_file.cpp index 0edc340598bf..56eb016c0251 100644 --- a/engines/ags/engine/ac/global_file.cpp +++ b/engines/ags/engine/ac/global_file.cpp @@ -83,10 +83,7 @@ int32_t FileOpen(const char *fnmm, Shared::FileOpenMode open_mode, Shared::FileW Stream *s = File::OpenFile(rp.FullPath, open_mode, work_mode); if (!s && !rp.AltPath.IsEmpty() && rp.AltPath.Compare(rp.FullPath) != 0) { - if (rp.FullPath.CompareLeft(AGS::Shared::SAVE_FOLDER_PREFIX)) - // When file not found in main path, only check in AltPath if it's not a - // savegame file. Because ScummVM doesn't have any alt for saves - s = File::OpenFile(rp.AltPath, open_mode, work_mode); + s = File::OpenFile(rp.AltPath, open_mode, work_mode); } valid_handles[useindx].stream = s; From c1ebd589e89c99cfb8295feb7c0aae245cd73816 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 Jan 2021 22:39:49 -0800 Subject: [PATCH 149/215] AGS: Implement bitmap saving code needed by KQ2 --- engines/ags/engine/ac/game.cpp | 28 ++++--------- engines/ags/shared/gfx/allegrobitmap.cpp | 14 ++++++- engines/ags/shared/gfx/allegrobitmap.h | 1 + engines/ags/shared/gfx/image.cpp | 53 +++++++++++++++++++++++- engines/ags/shared/gfx/image.h | 2 +- 5 files changed, 73 insertions(+), 25 deletions(-) diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 4526adb9ab89..9899af897376 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -97,11 +97,11 @@ #include "ags/shared/util/path.h" #include "ags/shared/util/string_utils.h" #include "ags/engine/ac/keycode.h" - #include "ags/shared/debugging/out.h" #include "ags/engine/script/script_api.h" #include "ags/engine/script/script_runtime.h" #include "ags/ags.h" +#include "common/memstream.h" namespace AGS3 { @@ -997,30 +997,16 @@ void skip_serialized_bitmap(Stream *in) { } long write_screen_shot_for_vista(Stream *out, Bitmap *screenshot) { -#ifdef TODO - long fileSize = 0; - String tempFileName = String::FromFormat("%s""_tmpscht.bmp", saveGameDirectory.GetCStr()); - - screenshot->SaveToFile(tempFileName, palette); + // Save the screenshot to a memory stream so we can access the raw data + Common::MemoryWriteStreamDynamic bitmap(DisposeAfterUse::YES); + screenshot->SaveToFile(bitmap, palette); update_polled_stuff_if_runtime(); - if (exists(tempFileName)) { - fileSize = file_size_ex(tempFileName); - char *buffer = (char *)malloc(fileSize); - - Stream *temp_in = Shared::File::OpenFileRead(tempFileName); - temp_in->Read(buffer, fileSize); - delete temp_in; - ::remove(tempFileName); + // Write the bitmap to the output stream + out->Write(bitmap.getData(), bitmap.size()); - out->Write(buffer, fileSize); - free(buffer); - } - return fileSize; -#else - error("TODO: write_screen_shot_for_vista"); -#endif + return bitmap.size(); } void WriteGameSetupStructBase_Aligned(Stream *out) { diff --git a/engines/ags/shared/gfx/allegrobitmap.cpp b/engines/ags/shared/gfx/allegrobitmap.cpp index f627868d7eb9..6f1dc56fc4cd 100644 --- a/engines/ags/shared/gfx/allegrobitmap.cpp +++ b/engines/ags/shared/gfx/allegrobitmap.cpp @@ -24,6 +24,8 @@ #include "ags/shared/gfx/image.h" #include "ags/shared/debugging/assert.h" #include "ags/lib/aastr-0.1.1/aastr.h" +#include "common/savefile.h" +#include "common/system.h" namespace AGS3 { @@ -123,8 +125,18 @@ bool Bitmap::LoadFromFile(const char *filename) { return _alBitmap != nullptr; } +bool Bitmap::SaveToFile(Common::WriteStream &out, const void *palette) { + return save_bitmap(out, _alBitmap, (const RGB *)palette) == 0; +} + bool Bitmap::SaveToFile(const char *filename, const void *palette) { - return save_bitmap(filename, _alBitmap, (const RGB *)palette) == 0; + Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving(filename, false); + assert(out); + bool result = SaveToFile(*out, palette); + out->finalize(); + delete out; + + return result; } void Bitmap::SetMaskColor(color_t color) { diff --git a/engines/ags/shared/gfx/allegrobitmap.h b/engines/ags/shared/gfx/allegrobitmap.h index 76ba4ec5960e..4e70adf1f67d 100644 --- a/engines/ags/shared/gfx/allegrobitmap.h +++ b/engines/ags/shared/gfx/allegrobitmap.h @@ -66,6 +66,7 @@ class Bitmap { void Destroy(); bool LoadFromFile(const char *filename); + bool SaveToFile(Common::WriteStream &out, const void *palette); bool SaveToFile(const char *filename, const void *palette); // TODO: This is temporary solution for cases when we cannot replace diff --git a/engines/ags/shared/gfx/image.cpp b/engines/ags/shared/gfx/image.cpp index 914c4d84bf8a..055dcba4e051 100644 --- a/engines/ags/shared/gfx/image.cpp +++ b/engines/ags/shared/gfx/image.cpp @@ -24,6 +24,7 @@ #include "ags/lib/allegro.h" #include "common/file.h" #include "common/str.h" +#include "common/stream.h" #include "common/textconsole.h" #include "image/pcx.h" @@ -103,8 +104,56 @@ BITMAP *load_bitmap(const char *filename, color *pal) { error("Unknown image file - %s", filename); } -int save_bitmap(const char *filename, BITMAP *bmp, const RGB *pal) { - error("TODO: save_bitmap"); +int save_bitmap(Common::WriteStream &out, BITMAP *bmp, const RGB *pal) { +#ifdef SCUMM_LITTLE_ENDIAN + const Graphics::PixelFormat requiredFormat_3byte(3, 8, 8, 8, 0, 16, 8, 0, 0); +#else + const Graphics::PixelFormat requiredFormat_3byte(3, 8, 8, 8, 0, 0, 8, 16, 0); +#endif + + Graphics::ManagedSurface &src = bmp->getSurface(); + Graphics::Surface *tmp = nullptr; + const Graphics::Surface *surface; + + if (bmp->format == requiredFormat_3byte) { + surface = &src.rawSurface(); + } else { + surface = tmp = src.rawSurface().convertTo(requiredFormat_3byte); + } + + int dstPitch = surface->w * 3; + int extraDataLength = (dstPitch % 4) ? 4 - (dstPitch % 4) : 0; + int padding = 0; + + out.writeByte('B'); + out.writeByte('M'); + out.writeUint32LE(surface->h * dstPitch + 54); + out.writeUint32LE(0); + out.writeUint32LE(54); + out.writeUint32LE(40); + out.writeUint32LE(surface->w); + out.writeUint32LE(surface->h); + out.writeUint16LE(1); + out.writeUint16LE(24); + out.writeUint32LE(0); + out.writeUint32LE(0); + out.writeUint32LE(0); + out.writeUint32LE(0); + out.writeUint32LE(0); + out.writeUint32LE(0); + + for (uint y = surface->h; y-- > 0;) { + out.write((const void *)surface->getBasePtr(0, y), dstPitch); + out.write(&padding, extraDataLength); + } + + // free tmp surface + if (tmp) { + tmp->free(); + delete tmp; + } + + return true; } } // namespace AGS diff --git a/engines/ags/shared/gfx/image.h b/engines/ags/shared/gfx/image.h index 592009ec016f..8af013a19da0 100644 --- a/engines/ags/shared/gfx/image.h +++ b/engines/ags/shared/gfx/image.h @@ -36,7 +36,7 @@ BITMAP *load_pcx_pf(PACKFILE *f, color *pal); BITMAP *load_tga(const char *filename, color *pal); BITMAP *load_tga_pf(PACKFILE *f, color *pal); -int save_bitmap(const char *filename, BITMAP *bmp, const RGB *pal); +int save_bitmap(Common::WriteStream &out, BITMAP *bmp, const RGB *pal); } // namespace AGS3 From dcd9cefbcb1c57dbc10667836afd4ec2e661f20d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 21 Jan 2021 19:55:14 -0800 Subject: [PATCH 150/215] AGS: Fix black box & gfx issues in ATOTK --- engines/ags/lib/allegro/gfx.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index df0f0ea2e855..6b973c993c4e 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -211,8 +211,8 @@ int bitmap_color_depth(BITMAP *bmp) { } int bitmap_mask_color(BITMAP *bmp) { - Graphics::ManagedSurface &surf = **bmp; - return surf.getTransparentColor(); + assert(bmp->format.bytesPerPixel > 1); + return bmp->format.RGBToColor(255, 0, 255); } void add_palette_if_needed(Graphics::ManagedSurface &src, Graphics::ManagedSurface &dest) { From c0f5a39fca05a75aa3c476356e7e9e02e46b0d20 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jan 2021 08:16:05 -0800 Subject: [PATCH 151/215] AGS: Implemented Theora video player --- engines/ags/engine/media/video/video.cpp | 397 ++++------------------- engines/ags/shared/util/stream.h | 42 +++ 2 files changed, 99 insertions(+), 340 deletions(-) diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index d5a14bc821fd..998b29fee083 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -20,13 +20,9 @@ * */ -#include "ags/engine/media/video/video.h" - -//include "apeg.h" +#include "video/theora_decoder.h" #include "ags/shared/core/platform.h" -#define AGS_FLI_FROM_PACK_FILE ((ALLEGRO_DATE >= 20190303) || \ - AGS_PLATFORM_OS_WINDOWS || AGS_PLATFORM_OS_ANDROID || AGS_PLATFORM_OS_MACOS) - +#include "ags/shared/core/types.h" #include "ags/engine/debugging/debug_log.h" #include "ags/shared/debugging/out.h" #include "ags/engine/ac/asset_helper.h" @@ -47,361 +43,84 @@ #include "ags/engine/main/game_run.h" #include "ags/shared/util/stream.h" #include "ags/engine/media/audio/audio_system.h" +#include "ags/ags.h" +#include "ags/events.h" +#include "ags/engine/media/video/video.h" namespace AGS3 { -// TODO: Enable video playback -#define AGS_NO_VIDEO_PLAYER - -#ifndef AGS_NO_VIDEO_PLAYER - -using namespace AGS::Shared; -using namespace AGS::Engine; - - -extern GameSetupStruct game; -extern IGraphicsDriver *gfxDriver; -extern int psp_video_framedrop; - -enum VideoPlaybackType { - kVideoNone, - kVideoFlic, - kVideoTheora -}; - -VideoPlaybackType video_type = kVideoNone; - -// FLIC player start -Bitmap *fli_buffer = nullptr; -short fliwidth, fliheight; -int canabort = 0, stretch_flc = 1; -Bitmap *hicol_buf = nullptr; -IDriverDependantBitmap *fli_ddb = nullptr; -Bitmap *fli_target = nullptr; -int fliTargetWidth, fliTargetHeight; -int check_if_user_input_should_cancel_video() { - int key, mbut, mwheelz; - if (run_service_key_controls(key)) { - if ((key == 27) && (canabort == 1)) - return 1; - if (canabort >= 2) - return 1; // skip on any key - } - if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && canabort == 3) { - return 1; // skip on mouse click - } - return 0; -} - -#if AGS_PLATFORM_OS_WINDOWS -int __cdecl fli_callback() { -#else -extern "C" int fli_callback() { -#endif - Bitmap *usebuf = fli_buffer; - - update_audio_system_on_game_loop(); - - if (game.color_depth > 1) { - hicol_buf->Blit(fli_buffer, 0, 0, 0, 0, fliwidth, fliheight); - usebuf = hicol_buf; - } - - const Rect &view = play.GetMainViewport(); - if (stretch_flc == 0) - fli_target->Blit(usebuf, 0, 0, view.GetWidth() / 2 - fliwidth / 2, view.GetHeight() / 2 - fliheight / 2, view.GetWidth(), view.GetHeight()); - else - fli_target->StretchBlt(usebuf, RectWH(0, 0, fliwidth, fliheight), RectWH(0, 0, view.GetWidth(), view.GetHeight())); - - gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); - gfxDriver->DrawSprite(0, 0, fli_ddb); - render_to_screen(); - - return check_if_user_input_should_cancel_video(); -} - -void play_flc_file(int numb, int playflags) { - color oldpal[256]; - - // AGS 2.x: If the screen is faded out, fade in again when playing a movie. - if (loaded_game_file_version <= kGameVersion_272) - play.screen_is_faded_out = 0; - - if (play.fast_forward) - return; - - get_palette_range(oldpal, 0, 255); - - int clearScreenAtStart = 1; - canabort = playflags % 10; - playflags -= canabort; - - if (canabort == 2) // convert to PlayVideo-compatible setting - canabort = 3; - - if (playflags % 100 == 0) - stretch_flc = 1; - else - stretch_flc = 0; - - if (playflags / 100) - clearScreenAtStart = 0; - - String flicname = String::FromFormat("flic%d.flc", numb); - Stream *in = AssetManager::OpenAsset(flicname); - if (!in) { - flicname.Format("flic%d.fli", numb); - in = AssetManager::OpenAsset(flicname); - } - if (!in) { - debug_script_warn("FLIC animation flic%d.flc nor flic%d.fli not found", numb, numb); - return; - } - - in->Seek(8); - fliwidth = in->ReadInt16(); - fliheight = in->ReadInt16(); - delete in; - - if (game.color_depth > 1) { - hicol_buf = BitmapHelper::CreateBitmap(fliwidth, fliheight, game.GetColorDepth()); - hicol_buf->Clear(); - } - // override the stretch option if necessary - const Rect &view = play.GetMainViewport(); - if ((fliwidth == view.GetWidth()) && (fliheight == view.GetHeight())) - stretch_flc = 0; - else if ((fliwidth > view.GetWidth()) || (fliheight > view.GetHeight())) - stretch_flc = 1; - fli_buffer = BitmapHelper::CreateBitmap(fliwidth, fliheight, 8); - if (fli_buffer == nullptr) quit("Not enough memory to play animation"); - fli_buffer->Clear(); - - if (clearScreenAtStart) { - if (gfxDriver->UsesMemoryBackBuffer()) { - Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); - screen_bmp->Clear(); - } - render_to_screen(); - } - - video_type = kVideoFlic; - fli_target = BitmapHelper::CreateBitmap(view.GetWidth(), view.GetHeight(), game.GetColorDepth()); - fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); - - // TODO: find a better solution. - // Make only certain versions of the engineuse play_fli_pf from the patched version of Allegro for now. - // Add more versions as their Allegro lib becomes patched too, or they use newer version of Allegro 4. - // Ports can still play FLI if separate file is put into game's directory. -#if AGS_FLI_FROM_PACK_FILE - size_t asset_size; - PACKFILE *pf = PackfileFromAsset(AssetPath("", flicname), asset_size); - if (play_fli_pf(pf, (BITMAP *)fli_buffer->GetAllegroBitmap(), fli_callback) == FLI_ERROR) -#else - if (play_fli(flicname, (BITMAP *)fli_buffer->GetAllegroBitmap(), 0, fli_callback) == FLI_ERROR) -#endif - { - // This is not a fatal error that should prevent the game from continuing - Debug::Printf("FLI/FLC animation play error"); - } -#if AGS_FLI_FROM_PACK_FILE - pack_fclose(pf); -#endif - - video_type = kVideoNone; - delete fli_buffer; - fli_buffer = nullptr; - // NOTE: the screen bitmap could change in the meanwhile, if the display mode has changed - if (gfxDriver->UsesMemoryBackBuffer()) { - Bitmap *screen_bmp = gfxDriver->GetMemoryBackBuffer(); - screen_bmp->Clear(); - } - set_palette_range(oldpal, 0, 255, 0); - render_to_screen(); - - delete fli_target; - gfxDriver->DestroyDDB(fli_ddb); - fli_target = nullptr; - fli_ddb = nullptr; - - - delete hicol_buf; - hicol_buf = nullptr; - // SetVirtualScreen(screen); wputblock(0,0,backbuffer,0); - while (ags_mgetbutton() != NONE) { - } // clear any queued mouse events. - invalidate_screen(); -} - -// FLIC player end - -// Theora player begin -// TODO: find a way to take Bitmap here? -Bitmap gl_TheoraBuffer; -int theora_playing_callback(BITMAP * theoraBuffer) { - if (theoraBuffer == nullptr) { - // No video, only sound - return check_if_user_input_should_cancel_video(); - } - - gl_TheoraBuffer.WrapAllegroBitmap(theoraBuffer, true); - - int drawAtX = 0, drawAtY = 0; - const Rect &viewport = play.GetMainViewport(); - if (fli_ddb == nullptr) { - fli_ddb = gfxDriver->CreateDDBFromBitmap(&gl_TheoraBuffer, false, true); - } - if (stretch_flc) { - drawAtX = viewport.GetWidth() / 2 - fliTargetWidth / 2; - drawAtY = viewport.GetHeight() / 2 - fliTargetHeight / 2; - if (!gfxDriver->HasAcceleratedTransform()) { - fli_target->StretchBlt(&gl_TheoraBuffer, RectWH(0, 0, gl_TheoraBuffer.GetWidth(), gl_TheoraBuffer.GetHeight()), - RectWH(drawAtX, drawAtY, fliTargetWidth, fliTargetHeight)); - gfxDriver->UpdateDDBFromBitmap(fli_ddb, fli_target, false); - drawAtX = 0; - drawAtY = 0; - } else { - gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); - fli_ddb->SetStretch(fliTargetWidth, fliTargetHeight, false); - } - } else { - gfxDriver->UpdateDDBFromBitmap(fli_ddb, &gl_TheoraBuffer, false); - drawAtX = viewport.GetWidth() / 2 - gl_TheoraBuffer.GetWidth() / 2; - drawAtY = viewport.GetHeight() / 2 - gl_TheoraBuffer.GetHeight() / 2; - } - - gfxDriver->DrawSprite(drawAtX, drawAtY, fli_ddb); - update_audio_system_on_game_loop(); - render_to_screen(); - - return check_if_user_input_should_cancel_video(); -} - -// -// Theora stream reader callbacks. We need these because APEG library does not -// provide means to supply user's PACKFILE directly. -// -// Open stream for reading (return suggested cache buffer size). -int apeg_stream_init(void *ptr) { - return ptr != nullptr ? F_BUF_SIZE : 0; -} -// Read requested number of bytes into provided buffer, -// return actual number of bytes managed to read. -int apeg_stream_read(void *buffer, int bytes, void *ptr) { - return ((Stream *)ptr)->Read(buffer, bytes); -} -// Skip requested number of bytes -void apeg_stream_skip(int bytes, void *ptr) { - ((Stream *)ptr)->Seek(bytes); -} -// - -APEG_STREAM *get_theora_size(Stream * video_stream, int *width, int *height) { - APEG_STREAM *oggVid = apeg_open_stream_ex(video_stream); - if (oggVid != nullptr) { - apeg_get_video_size(oggVid, width, height); - } else { - *width = 0; - *height = 0; - } - return oggVid; -} - -// TODO: use shared utility function for placing rect in rect -void calculate_destination_size_maintain_aspect_ratio(int vidWidth, int vidHeight, int *targetWidth, int *targetHeight) { - const Rect &viewport = play.GetMainViewport(); - float aspectRatioVideo = (float)vidWidth / (float)vidHeight; - float aspectRatioScreen = (float)viewport.GetWidth() / (float)viewport.GetHeight(); - - if (aspectRatioVideo == aspectRatioScreen) { - *targetWidth = viewport.GetWidth(); - *targetHeight = viewport.GetHeight(); - } else if (aspectRatioVideo > aspectRatioScreen) { - *targetWidth = viewport.GetWidth(); - *targetHeight = (int)(((float)viewport.GetWidth() / aspectRatioVideo) + 0.5f); - } else { - *targetHeight = viewport.GetHeight(); - *targetWidth = (float)viewport.GetHeight() * aspectRatioVideo; - } - -} +using AGS::Shared::AssetManager; void play_theora_video(const char *name, int skip, int flags) { std::unique_ptr video_stream(AssetManager::OpenAsset(name)); - apeg_set_stream_reader(apeg_stream_init, apeg_stream_read, apeg_stream_skip); - apeg_set_display_depth(game.GetColorDepth()); - // we must disable length detection, otherwise it takes ages to start - // playing if the file is large because it seeks through the whole thing - apeg_disable_length_detection(TRUE); - // Disable framedrop because it can lead to the PSP not playing the video at all. - apeg_enable_framedrop(psp_video_framedrop); - update_polled_stuff_if_runtime(); - - stretch_flc = (flags % 10); - canabort = skip; - apeg_ignore_audio((flags >= 10) ? 1 : 0); - - int videoWidth, videoHeight; - APEG_STREAM *oggVid = get_theora_size(video_stream.get(), &videoWidth, &videoHeight); - - if (videoWidth == 0) { + if (!video_stream) { Display("Unable to load theora video '%s'", name); return; } - if (flags < 10) { - stop_all_sound_and_music(); - } + update_polled_stuff_if_runtime(); - //fli_buffer = BitmapHelper::CreateBitmap_(scsystem.coldepth, videoWidth, videoHeight); - calculate_destination_size_maintain_aspect_ratio(videoWidth, videoHeight, &fliTargetWidth, &fliTargetHeight); + Graphics::Screen &scr = *::AGS::g_vm->_rawScreen; + bool stretchVideo = (flags % 10) != 0; + int canAbort = skip; + bool ignoreAudio = (flags >= 10); - if ((fliTargetWidth == videoWidth) && (fliTargetHeight == videoHeight) && (stretch_flc)) { - // don't need to stretch after all - stretch_flc = 0; + if (!ignoreAudio) { + stop_all_sound_and_music(); } - if ((stretch_flc) && (!gfxDriver->HasAcceleratedTransform())) { - fli_target = BitmapHelper::CreateBitmap(play.GetMainViewport().GetWidth(), play.GetMainViewport().GetHeight(), game.GetColorDepth()); - fli_target->Clear(); - fli_ddb = gfxDriver->CreateDDBFromBitmap(fli_target, false, true); - } else { - fli_ddb = nullptr; + Video::TheoraDecoder decoder; + AGS::Shared::ScummVMReadStream *stream = new AGS::Shared::ScummVMReadStream(video_stream.get(), DisposeAfterUse::NO); + + if (!decoder.loadStream(stream)) { + delete stream; + Display("Unable to decode theora video '%s'", name); + return; } update_polled_stuff_if_runtime(); - if (gfxDriver->UsesMemoryBackBuffer()) - gfxDriver->GetMemoryBackBuffer()->Clear(); + decoder.start(); + while (!SHOULD_QUIT && !decoder.endOfVideo()) { + if (decoder.needsUpdate()) { + // Get the next video frame and draw onto the screen + const Graphics::Surface *frame = decoder.decodeNextFrame(); + + if (stretchVideo && frame->w == scr.w && frame->h == scr.h) + // Don't need to stretch video after all + stretchVideo = false; + + if (stretchVideo) { + scr.transBlitFrom(*frame, Common::Rect(0, 0, frame->w, frame->h), + Common::Rect(0, 0, scr.w, scr.h)); + } else { + scr.blitFrom(*frame, Common::Point((scr.w - frame->w) / 2, + (scr.h - frame->h) / 2)); + } + + scr.update(); + } - video_type = kVideoTheora; - if (apeg_play_apeg_stream(oggVid, nullptr, 0, theora_playing_callback) == APEG_ERROR) { - Display("Error playing theora video '%s'", name); + g_system->delayMillis(10); + ::AGS::g_events->pollEvents(); + + if (canAbort) { + // Check for whether user aborted video + int key, mbut, mwheelz; + if (run_service_key_controls(key)) { + if (key == 27 && canAbort) + return; + if (canAbort >= 2) + return; // skip on any key + } + if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && canAbort == 3) { + return; // skip on mouse click + } + } } - apeg_close_stream(oggVid); - video_type = kVideoNone; - //destroy_bitmap(fli_buffer); - delete fli_target; - gfxDriver->DestroyDDB(fli_ddb); - fli_target = nullptr; - fli_ddb = nullptr; invalidate_screen(); } -// Theora player end - -void video_on_gfxmode_changed() { - if (video_type == kVideoFlic) { - // If the FLIC video is playing, restore its palette - set_palette_range(fli_palette, 0, 255, 0); - } -} - -#else - -void play_theora_video(const char *name, int skip, int flags) { - warning("TODO: play_theora_video"); -} void play_flc_file(int numb, int playflags) { warning("TODO: play_flc_file"); } @@ -410,6 +129,4 @@ void video_on_gfxmode_changed() { warning("TODO: video_on_gfxmode_changed"); } -#endif - } // namespace AGS3 diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index 9940e9669556..4b42de45e756 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -36,6 +36,8 @@ #define AGS_SHARED_UTIL_STREAM_H #include "ags/shared/api/stream_api.h" +#include "common/stream.h" +#include "common/types.h" namespace AGS3 { namespace AGS { @@ -83,6 +85,46 @@ class Stream : public IAGSStream { size_t WriteByteCount(uint8_t b, size_t count); }; +class ScummVMReadStream : public Common::SeekableReadStream { +private: + IAGSStream *_stream; + DisposeAfterUse::Flag _disposeAfterUse; +public: + ScummVMReadStream(IAGSStream *src, DisposeAfterUse::Flag disposeAfterUse = + DisposeAfterUse::YES) : _stream(src), _disposeAfterUse(disposeAfterUse) { + } + ~ScummVMReadStream() override { + if (_disposeAfterUse == DisposeAfterUse::YES) + delete _stream; + } + + bool eos() const override { + return _stream->EOS(); + } + + uint32 read(void *dataPtr, uint32 dataSize) override { + return _stream->Read(dataPtr, dataSize); + } + + int32 pos() const override { + return _stream->GetPosition(); + } + + int32 size() const override { + return _stream->GetLength(); + } + + bool seek(int32 offset, int whence = SEEK_SET) override { + StreamSeek origin = kSeekBegin; + if (whence == SEEK_CUR) + origin = kSeekCurrent; + if (whence == SEEK_END) + origin = kSeekEnd; + + return _stream->Seek(offset, origin); + } +}; + } // namespace Shared } // namespace AGS } // namespace AGS3 From 1d40f5e4c81658b79d08874058565df871c34103 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Fri, 22 Jan 2021 22:23:46 +0000 Subject: [PATCH 152/215] AGS: Add some more detection entries --- engines/ags/detection_tables.h | 38 ++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index af315a8bdb04..45c4e1634a5d 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -27,8 +27,24 @@ static const PlainGameDescriptor GAME_NAMES[] = { { "atotk", "A Tale Of Two Kingdoms" }, { "bcremake", "Black Cauldron Remake" }, - { "blackwelllegacy", "The Blackwell Legacy" }, + { "blackwell1", "The Blackwell Legacy"}, + { "blackwell2", "Blackwell Unbound"}, + { "blackwell3", "The Blackwell Convergence"}, + { "blackwell4", "The Blackwell Deception"}, + { "blackwell5", "The Blackwell Epiphany"}, { "kq2agdi", "Kings Quest II - Romancing The Stones" }, + { "kq1agdi", "King's Quest I: Quest for the Crown Remake" }, + { "kq2agdi", "King's Quest II: Romancing The Stones" }, + { "kq3agdi", "King's Quest III Redux: To Heir is Human" }, + { "geminirue", "Gemini Rue"}, + { "goldenwake", "A Golden Wake"}, + { "kathyrain", "Kathy Rain"}, + { "qfi", "Quest for Infamy"}, + { "oott", "Order of the Thorne: The King's Challenge"}, + { "primordia", "Primordia"}, + { "resonance", "Resonance"}, + { "mage", "Mage's Initiation: Reign of the Elements"}, + { "unavowed", "Unavowed"}, { 0, 0 } }; @@ -48,8 +64,26 @@ static const PlainGameDescriptor GAME_NAMES[] = { static const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), - ENGLISH_ENTRY("blackwelllegacy", "blackwell1.exe", "605e124cb7e0b56841c471e2d641c224", 18822697), + ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42740200), + ENGLISH_ENTRY("blackwell1", "blackwell1.exe", "605e124cb7e0b56841c471e2d641c224", 18822697), // GOG + ENGLISH_ENTRY("blackwell2", "unbound.exe", "5c3a940514d91431e8e1c372018851ca", 14493753), // GOG + ENGLISH_ENTRY("blackwell3", "convergence.exe", "2260c1a21aba7ac00baf0100d4ca54f1", 172575801), // GOG + ENGLISH_ENTRY("blackwell4", "deception.exe", "b3b192cf20a2f7666ddea3410dbd87cc", 303459336), // GOG + ENGLISH_ENTRY("blackwell5", "epiphany.exe", "c1cddd6fcdbcd030beda9f10d4e4270a", 281849897), // GOG + ENGLISH_ENTRY("kq1agdi", "kq1vga.exe", "688f1807c9d8df26fc0f174dc756054e", 8278611), // 4.1c ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), // 3.1 + ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12574643), // 3.1c + ENGLISH_ENTRY("kq3agdi", "kq3redux.exe", "e569fb2ceabdc4a1609348c23ebc0821", 11986266), // 1.1 + ENGLISH_ENTRY("geminirue", "gemini rue.exe", "f3c0c7d3892bdd8963e8ce017f73de08", 61986506), // GOG + ENGLISH_ENTRY("goldenwake", "a-golden-wake.exe", "dbe281d93c914899886e77c09c3c65ec", 130844360), // Steam + ENGLISH_ENTRY("kathyrain", "kathyrain.exe", "434e24a12ba3cfb07d7b4b2f0e0bb1bf", 197487159), // Steam + ENGLISH_ENTRY("qfi", "qfi.exe", "0702df6e67ef87fd3c51d09303803126", 534847265), // GOG + ENGLISH_ENTRY("oott", "OotT-TKC.exe", "11c2421258465cba4bd773c49d918ee3", 467834855), // GOG + ENGLISH_ENTRY("primordia", "primordia.exe", "22313e59c3233001488c26f18c80cc08", 973495830), // GOG + ENGLISH_ENTRY("resonance", "resonance.exe", "2e635c22bcbf0ed3d46f1bcde71812d4", 849404957), // GOG + // For some macOS and iOS releases the executable was renamed to ac2game.dat + ENGLISH_ENTRY("mage", "ac2game.dat", "2e822f554994f36e0c62da2acda874da", 30492258), // GOG, Mac + ENGLISH_ENTRY("unavowed", "ac2game.dat", "b1ff7d96667707daf4266975cea2bf90", 1755457364), // Steam, Mac { AD_TABLE_END_MARKER } }; From 898f3f20bca410d57f43dd423700270f616514e9 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Fri, 22 Jan 2021 22:24:41 +0000 Subject: [PATCH 153/215] AGS: Add override keyword --- engines/ags/ags.h | 4 ++-- engines/ags/detection.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/ags/ags.h b/engines/ags/ags.h index 2c6b3b1ffd0e..3c3d8d2e82cd 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -71,10 +71,10 @@ class AGSEngine : public Engine { ::AGS3::Globals *_globals; protected: // Engine APIs - virtual Common::Error run(); + virtual Common::Error run() override; public: AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc); - virtual ~AGSEngine(); + virtual ~AGSEngine() override; void GUIError(const Common::String &msg); void set_window_title(const char *str) { diff --git a/engines/ags/detection.h b/engines/ags/detection.h index f916f2f2a19d..e58dffd202b8 100644 --- a/engines/ags/detection.h +++ b/engines/ags/detection.h @@ -38,15 +38,15 @@ class AGSMetaEngineDetection : public AdvancedMetaEngineDetection { AGSMetaEngineDetection(); ~AGSMetaEngineDetection() override {} - virtual const char *getEngineId() const { + virtual const char *getEngineId() const override { return "ags"; } - virtual const char *getName() const { + virtual const char *getName() const override { return "Adventure Game Studio"; } - virtual const char *getOriginalCopyright() const { + virtual const char *getOriginalCopyright() const override { return ""; } }; From 9736e2898560c7181cb0d39d8b34ccea5caccafb Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Fri, 22 Jan 2021 22:25:45 +0000 Subject: [PATCH 154/215] AGS: Use ScummVM endian macros --- engines/ags/shared/core/platform.h | 11 ++++---- engines/ags/shared/util/bbop.h | 45 +++++++----------------------- 2 files changed, 15 insertions(+), 41 deletions(-) diff --git a/engines/ags/shared/core/platform.h b/engines/ags/shared/core/platform.h index bcac2025a1eb..93479a49d5fc 100644 --- a/engines/ags/shared/core/platform.h +++ b/engines/ags/shared/core/platform.h @@ -23,6 +23,8 @@ #ifndef AGS_SHARED_CORE_PLATFORM_H #define AGS_SHARED_CORE_PLATFORM_H +#include + namespace AGS3 { // platform definitions. Not intended for replacing types or checking for libraries. @@ -117,17 +119,14 @@ namespace AGS3 { #define AGS_PLATFORM_64BIT (0) #endif -#if defined(_WIN32) -#define AGS_PLATFORM_ENDIAN_LITTLE (1) -#define AGS_PLATFORM_ENDIAN_BIG (0) -#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#if defined(SCUMM_LITTLE_ENDIAN) #define AGS_PLATFORM_ENDIAN_LITTLE (1) #define AGS_PLATFORM_ENDIAN_BIG (0) -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#elif defined(SCUMM_BIG_ENDIAN) #define AGS_PLATFORM_ENDIAN_LITTLE (0) #define AGS_PLATFORM_ENDIAN_BIG (1) #else -#error "Unknown platform" +#error "No endianness defined" #endif #if defined(_DEBUG) diff --git a/engines/ags/shared/util/bbop.h b/engines/ags/shared/util/bbop.h index 48764722f81f..0eb32a13a608 100644 --- a/engines/ags/shared/util/bbop.h +++ b/engines/ags/shared/util/bbop.h @@ -29,6 +29,7 @@ #ifndef AGS_SHARED_UTIL_BBOP_H #define AGS_SHARED_UTIL_BBOP_H +#include #include "ags/shared/core/platform.h" #include "ags/shared/core/types.h" @@ -52,17 +53,15 @@ enum DataEndianess { namespace BitByteOperations { inline int16_t SwapBytesInt16(const int16_t val) { - return ((val >> 8) & 0xFF) | ((val << 8) & 0xFF00); + return (int16_t)SWAP_CONSTANT_16(val); } inline int32_t SwapBytesInt32(const int32_t val) { - return ((val >> 24) & 0xFF) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | ((val << 24) & 0xFF000000); + return (int32_t)SWAP_CONSTANT_32(val); } inline int64_t SwapBytesInt64(const int64_t val) { - return ((val >> 56) & 0xFF) | ((val >> 40) & 0xFF00) | ((val >> 24) & 0xFF0000) | - ((val >> 8) & 0xFF000000) | ((val << 8) & 0xFF00000000LL) | - ((val << 24) & 0xFF0000000000LL) | ((val << 40) & 0xFF000000000000LL) | ((val << 56) & 0xFF00000000000000LL); + return (int64_t)SWAP_CONSTANT_64(val); } inline float SwapBytesFloat(const float val) { @@ -77,27 +76,15 @@ inline float SwapBytesFloat(const float val) { } inline int16_t Int16FromLE(const int16_t val) { -#if defined (BITBYTE_BIG_ENDIAN) - return SwapBytesInt16(val); -#else - return val; -#endif + return (int16_t)FROM_LE_16(val); } inline int32_t Int32FromLE(const int32_t val) { -#if defined (BITBYTE_BIG_ENDIAN) - return SwapBytesInt32(val); -#else - return val; -#endif + return (int32_t)FROM_LE_32(val); } inline int64_t Int64FromLE(const int64_t val) { -#if defined (BITBYTE_BIG_ENDIAN) - return SwapBytesInt64(val); -#else - return val; -#endif + return (int64_t)FROM_LE_64(val); } inline float FloatFromLE(const float val) { @@ -109,27 +96,15 @@ inline float FloatFromLE(const float val) { } inline int16_t Int16FromBE(const int16_t val) { -#if defined (BITBYTE_BIG_ENDIAN) - return val; -#else - return SwapBytesInt16(val); -#endif + return (int16_t)FROM_BE_16(val); } inline int32_t Int32FromBE(const int32_t val) { -#if defined (BITBYTE_BIG_ENDIAN) - return val; -#else - return SwapBytesInt32(val); -#endif + return (int32_t)FROM_BE_32(val); } inline int64_t Int64FromBE(const int64_t val) { -#if defined (BITBYTE_BIG_ENDIAN) - return val; -#else - return SwapBytesInt64(val); -#endif + return (int64_t)FROM_BE_64(val); } inline float FloatFromBE(const float val) { From 83d36e57d91776e3d5f8896f0a6375081c71a297 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sat, 23 Jan 2021 00:45:37 +0000 Subject: [PATCH 155/215] AGS: Fix ReadDialogs for some AGS versions on 64 bit systems --- engines/ags/shared/game/main_game_file.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp index 6a41aa838035..08d55da666e2 100644 --- a/engines/ags/shared/game/main_game_file.cpp +++ b/engines/ags/shared/game/main_game_file.cpp @@ -310,13 +310,13 @@ void ReadDialogs(DialogTopic *&dialog, } else { // Encrypted text on > 2.60 while (1) { - size_t newlen = (size_t)in->ReadInt32(); + uint32_t newlen = (uint32_t)in->ReadInt32(); if (newlen == 0xCAFEBEEF) { // GUI magic in->Seek(-4); break; } - newlen = Math::Min(newlen, sizeof(buffer) - 1); + newlen = Math::Min(newlen, (uint32_t)sizeof(buffer) - 1); in->Read(buffer, newlen); buffer[newlen] = 0; decrypt_text(buffer); From ef1533a4a43dc51c132b7d7211685ff8de49921f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jan 2021 18:49:55 -0800 Subject: [PATCH 156/215] AGS: Remove redundant virtual keywords when override is present --- engines/ags/ags.h | 4 ++-- engines/ags/detection.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engines/ags/ags.h b/engines/ags/ags.h index 3c3d8d2e82cd..10bcf431fbae 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -71,10 +71,10 @@ class AGSEngine : public Engine { ::AGS3::Globals *_globals; protected: // Engine APIs - virtual Common::Error run() override; + Common::Error run() override; public: AGSEngine(OSystem *syst, const AGSGameDescription *gameDesc); - virtual ~AGSEngine() override; + ~AGSEngine() override; void GUIError(const Common::String &msg); void set_window_title(const char *str) { diff --git a/engines/ags/detection.h b/engines/ags/detection.h index e58dffd202b8..366758251656 100644 --- a/engines/ags/detection.h +++ b/engines/ags/detection.h @@ -38,15 +38,15 @@ class AGSMetaEngineDetection : public AdvancedMetaEngineDetection { AGSMetaEngineDetection(); ~AGSMetaEngineDetection() override {} - virtual const char *getEngineId() const override { + const char *getEngineId() const override { return "ags"; } - virtual const char *getName() const override { + const char *getName() const override { return "Adventure Game Studio"; } - virtual const char *getOriginalCopyright() const override { + const char *getOriginalCopyright() const override { return ""; } }; From 26bb2dad08c70764e6dca4b9eda63c2355332b53 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jan 2021 18:58:41 -0800 Subject: [PATCH 157/215] AGS: Match the 32-bit PixelFormat to decoded bitmaps The 32-bit bitmap resources encoded by AGS had ARGB rather than RGBA (or is it the other way around?). Anyway, this was what was causing the KQ2 title screen to be all red. --- engines/ags/ags.cpp | 2 +- engines/ags/lib/allegro/gfx.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 09a58e539df9..d3a54972d5c5 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -367,7 +367,7 @@ SaveStateList AGSEngine::listSaves() const { } void AGSEngine::setGraphicsMode(size_t w, size_t h) { - Graphics::PixelFormat FORMAT(4, 8, 8, 8, 8, 24, 16, 8, 0); + Graphics::PixelFormat FORMAT(4, 8, 8, 8, 8, 0, 8, 16, 24); initGraphics(w, h, &FORMAT); _rawScreen = new Graphics::Screen(); diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 6b973c993c4e..fc855550b268 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -142,7 +142,7 @@ BITMAP *create_bitmap_ex(int color_depth, int width, int height) { format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); break; case 32: - format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); + format = Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24); break; default: error("Invalid color depth"); From eb09c316740fd4133c429d2945ca543aed66acd0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jan 2021 19:21:17 -0800 Subject: [PATCH 158/215] AGS: Move plugins/ folder into AGS3 namespace --- engines/ags/engine/plugin/library.cpp | 8 ++++---- engines/ags/plugins/agscreditz/agscreditz.cpp | 4 ++-- engines/ags/plugins/agscreditz/agscreditz.h | 4 ++-- engines/ags/plugins/dll.cpp | 4 ++-- engines/ags/plugins/dll.h | 9 ++------- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/engines/ags/engine/plugin/library.cpp b/engines/ags/engine/plugin/library.cpp index 7b64088194eb..814fab68dcf9 100644 --- a/engines/ags/engine/plugin/library.cpp +++ b/engines/ags/engine/plugin/library.cpp @@ -26,19 +26,19 @@ namespace AGS3 { void *dlopen(const char *filename, bool) { - return ::AGS::Plugins::dlopen(filename); + return Plugins::dlopen(filename); } int dlclose(void *lib) { - return ::AGS::Plugins::dlclose(lib); + return Plugins::dlclose(lib); } void *dlsym(void *lib, const char *method) { - return ::AGS::Plugins::dlsym(lib, method); + return Plugins::dlsym(lib, method); } const char *dlerror() { - return ::AGS::Plugins::dlerror(); + return Plugins::dlerror(); } } // namespace AGS3 diff --git a/engines/ags/plugins/agscreditz/agscreditz.cpp b/engines/ags/plugins/agscreditz/agscreditz.cpp index 8f30b69f0fcf..21a0ce3ecb55 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.cpp +++ b/engines/ags/plugins/agscreditz/agscreditz.cpp @@ -22,7 +22,7 @@ #include "ags/plugins/agscreditz/agscreditz.h" -namespace AGS { +namespace AGS3 { namespace Plugins { namespace AgsCreditz { @@ -147,4 +147,4 @@ int AgsCreditz::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { } // namespace AgsCreditz } // namespace Plugins -} // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/plugins/agscreditz/agscreditz.h b/engines/ags/plugins/agscreditz/agscreditz.h index d10c1a889322..a19a867035ad 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.h +++ b/engines/ags/plugins/agscreditz/agscreditz.h @@ -25,7 +25,7 @@ #include "ags/plugins/dll.h" -namespace AGS { +namespace AGS3 { namespace Plugins { namespace AgsCreditz { @@ -62,6 +62,6 @@ class AgsCreditz : public DLL { } // namespace AgsCreditz } // namespace Plugins -} // namespace AGS +} // namespace AGS3 #endif diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index a96494902730..c9a1d9e91527 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -24,7 +24,7 @@ #include "ags/plugins/agscreditz/agscreditz.h" #include "common/str.h" -namespace AGS { +namespace AGS3 { namespace Plugins { void *dlopen(const char *filename) { @@ -103,4 +103,4 @@ void DLL::AGS_EngineInitGfx(const char *driverID, void *data) { } } // namespace Plugins -} // namespace AGS +} // namespace AGS3 diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h index 2d653a4edc9e..c198add1f60b 100644 --- a/engines/ags/plugins/dll.h +++ b/engines/ags/plugins/dll.h @@ -28,7 +28,7 @@ #include "common/hashmap.h" #include "common/hash-str.h" -namespace AGS { +namespace AGS3 { namespace Plugins { #define DLL_METHOD(NAME) _methods[#NAME] = (void *)&NAME @@ -80,12 +80,7 @@ namespace Plugins { T8 N8 = (T8)params[7] -// TODO: Refactor string into core AGS namespace using string = const char *; -using ScriptMethodParams = ::AGS3::ScriptMethodParams; - -using IAGSEngine = ::AGS3::IAGSEngine; -using IAGSEditor = ::AGS3::IAGSEditor; typedef uint32 HWND; /** @@ -123,6 +118,6 @@ extern void *dlsym(void *lib, const char *method); extern const char *dlerror(); } // namespace Plugins -} // namespace AGS +} // namespace AGS3 #endif From fc00837830676b280b62a1cae6105aa7251a46de Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jan 2021 20:30:02 -0800 Subject: [PATCH 159/215] AGS: Fix compilation of VS 64-bit builds --- engines/ags/engine/ac/string.cpp | 6 +-- engines/ags/engine/ac/string.h | 2 +- engines/ags/engine/gui/cscidialog.cpp | 2 +- engines/ags/engine/gui/cscidialog.h | 2 +- engines/ags/engine/gui/guidialog.cpp | 35 ++++++++-------- engines/ags/engine/gui/mylabel.cpp | 2 +- engines/ags/engine/gui/mylabel.h | 2 +- engines/ags/engine/gui/mylistbox.cpp | 8 ++-- engines/ags/engine/gui/mylistbox.h | 2 +- engines/ags/engine/gui/mypushbutton.cpp | 2 +- engines/ags/engine/gui/mypushbutton.h | 2 +- engines/ags/engine/gui/mytextbox.cpp | 6 +-- engines/ags/engine/gui/mytextbox.h | 2 +- engines/ags/engine/gui/newcontrol.h | 2 +- engines/ags/lib/aastr-0.1.1/aarot.cpp | 4 +- engines/ags/lib/aastr-0.1.1/aastr.cpp | 6 +-- engines/ags/lib/aastr-0.1.1/aautil.cpp | 55 ++++++++++--------------- engines/ags/lib/aastr-0.1.1/aautil.h | 20 ++++----- engines/ags/lib/allegro/gfx.cpp | 8 ++-- engines/ags/lib/allegro/gfx.h | 4 +- engines/ags/shared/core/types.h | 13 ++++++ 21 files changed, 94 insertions(+), 91 deletions(-) diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp index 305629a49797..d679db77add8 100644 --- a/engines/ags/engine/ac/string.cpp +++ b/engines/ags/engine/ac/string.cpp @@ -273,9 +273,9 @@ size_t break_up_text_into_lines(const char *todis, SplitLines &lines, int wii, i int MAXSTRLEN = MAX_MAXSTRLEN; void check_strlen(char *ptt) { MAXSTRLEN = MAX_MAXSTRLEN; - long charstart = (long)&game.chars[0]; - long charend = charstart + sizeof(CharacterInfo) * game.numcharacters; - if (((long)&ptt[0] >= charstart) && ((long)&ptt[0] <= charend)) + const byte *charstart = (const byte *)&game.chars[0]; + const byte *charend = charstart + sizeof(CharacterInfo) * game.numcharacters; + if (((const byte *)&ptt[0] >= charstart) && ((const byte *)&ptt[0] <= charend)) MAXSTRLEN = 30; } diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h index 1d606e9a2df7..df911864a16a 100644 --- a/engines/ags/engine/ac/string.h +++ b/engines/ags/engine/ac/string.h @@ -29,7 +29,7 @@ namespace AGS3 { // Check that a supplied buffer from a text script function was not null -#define VALIDATE_STRING(strin) if ((unsigned long)strin <= 4096) quit("!String argument was null: make sure you pass a string, not an int, as a buffer") +#define VALIDATE_STRING(strin) if (reinterpret_cast(strin) <= 4096) quit("!String argument was null: make sure you pass a string, not an int, as a buffer") int String_IsNullOrEmpty(const char *thisString); const char *String_Copy(const char *srcString); diff --git a/engines/ags/engine/gui/cscidialog.cpp b/engines/ags/engine/gui/cscidialog.cpp index 5f26837c58b7..48da261d1fca 100644 --- a/engines/ags/engine/gui/cscidialog.cpp +++ b/engines/ags/engine/gui/cscidialog.cpp @@ -243,7 +243,7 @@ void CSCIDeleteControl(int haa) { vobjs[haa] = nullptr; } -int CSCISendControlMessage(int haa, int mess, int wPar, long lPar) { +int CSCISendControlMessage(int haa, int mess, int wPar, NumberPtr lPar) { if (vobjs[haa] == nullptr) return -1; return vobjs[haa]->processmessage(mess, wPar, lPar); diff --git a/engines/ags/engine/gui/cscidialog.h b/engines/ags/engine/gui/cscidialog.h index 5a360b1faaa5..5afe6ca286ff 100644 --- a/engines/ags/engine/gui/cscidialog.h +++ b/engines/ags/engine/gui/cscidialog.h @@ -39,7 +39,7 @@ void CSCIEraseWindow(int handl); int CSCIWaitMessage(CSCIMessage *cscim); int CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title); void CSCIDeleteControl(int haa); -int CSCISendControlMessage(int haa, int mess, int wPar, long lPar); +int CSCISendControlMessage(int haa, int mess, int wPar, NumberPtr lPar); void multiply_up_to_game_res(int *x, int *y); void multiply_up(int *x1, int *y1, int *x2, int *y2); int checkcontrols(); diff --git a/engines/ags/engine/gui/guidialog.cpp b/engines/ags/engine/gui/guidialog.cpp index 56002f6bb1f7..d80f2429b34b 100644 --- a/engines/ags/engine/gui/guidialog.cpp +++ b/engines/ags/engine/gui/guidialog.cpp @@ -192,11 +192,11 @@ int savegamedialog() { lpTemp = nullptr; if (numsaves > 0) - CSCISendControlMessage(ctrllist, CLB_GETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrllist, CLB_GETTEXT, 0, &buffer2[0]); else buffer2[0] = 0; - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, &buffer2[0]); int toret = -1; while (1) { @@ -204,10 +204,10 @@ int savegamedialog() { if (mes.code == CM_COMMAND) { if (mes.id == ctrlok) { int cursell = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); - CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, &buffer2[0]); if (numsaves > 0) - CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursell, (long)&bufTemp[0]); + CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursell, &bufTemp[0]); else strcpy(bufTemp, "_NOSAVEGAMENAME"); @@ -231,7 +231,7 @@ int savegamedialog() { CSCIWaitMessage(&cmes); } while (cmes.code != CM_COMMAND); - CSCISendControlMessage(txt1, CTB_GETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(txt1, CTB_GETTEXT, 0, &buffer2[0]); CSCIDeleteControl(btnCancel); CSCIDeleteControl(btnOk); CSCIDeleteControl(txt1); @@ -279,8 +279,8 @@ int savegamedialog() { } else if (mes.code == CM_SELCHANGE) { int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); if (cursel >= 0) { - CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursel, (long)&buffer2[0]); - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrllist, CLB_GETTEXT, cursel, &buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, &buffer2[0]); } } } @@ -305,7 +305,8 @@ void preparesavegamelist(int ctrllist) { Common::String desc = it->getDescription(); // TODO: Casting pointer to long is nasty - CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)desc.c_str()); + CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, + const_cast(desc.c_str())); // Select the first item CSCISendControlMessage(ctrllist, CLB_SETCURSEL, 0, 0); @@ -321,10 +322,10 @@ void preparesavegamelist(int ctrllist) { for (int nn = 0; nn < numsaves - 1; nn++) { for (int kk = 0; kk < numsaves - 1; kk++) { // Date order the games if (filedates[kk] < filedates[kk + 1]) { // swap them round - CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk, (long)&buff[0]); - CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk + 1, (long)&buffer2[0]); - CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk + 1, (long)&buff[0]); - CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk, (long)&buffer2[0]); + CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk, &buff[0]); + CSCISendControlMessage(ctrllist, CLB_GETTEXT, kk + 1, &buffer2[0]); + CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk + 1, &buff[0]); + CSCISendControlMessage(ctrllist, CLB_SETTEXT, kk, &buffer2[0]); int numtem = filenumbers[kk]; filenumbers[kk] = filenumbers[kk + 1]; filenumbers[kk + 1] = numtem; @@ -361,7 +362,7 @@ void enterstringwindow(const char *prompttext, char *stouse) { if (mes.id == ctrlcancel) buffer2[0] = 0; else - CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, &buffer2[0]); break; } } @@ -400,7 +401,7 @@ int roomSelectorWindow(int currentRoom, int numRooms, int *roomNumbers, char **r CSCISendControlMessage(ctrllist, CLB_CLEAR, 0, 0); // clear the list box for (int aa = 0; aa < numRooms; aa++) { sprintf(buff, "%3d %s", roomNumbers[aa], roomNames[aa]); - CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, (long)&buff[0]); + CSCISendControlMessage(ctrllist, CLB_ADDITEM, 0, &buff[0]); if (roomNumbers[aa] == currentRoom) { CSCISendControlMessage(ctrllist, CLB_SETCURSEL, aa, 0); } @@ -414,14 +415,14 @@ int roomSelectorWindow(int currentRoom, int numRooms, int *roomNumbers, char **r buffer2[0] = 0; int ctrltbox = CSCICreateControl(CNT_TEXTBOX, 10, 29, 120, 0, nullptr); - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, &buffer2[0]); int toret = -1; while (1) { CSCIWaitMessage(&mes); //printf("mess: %d, id %d ",mes.code,mes.id); if (mes.code == CM_COMMAND) { if (mes.id == ctrlok) { - CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_GETTEXT, 0, &buffer2[0]); if (Common::isDigit(buffer2[0])) { toret = atoi(buffer2); } @@ -432,7 +433,7 @@ int roomSelectorWindow(int currentRoom, int numRooms, int *roomNumbers, char **r int cursel = CSCISendControlMessage(ctrllist, CLB_GETCURSEL, 0, 0); if (cursel >= 0) { sprintf(buffer2, "%d", roomNumbers[cursel]); - CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, (long)&buffer2[0]); + CSCISendControlMessage(ctrltbox, CTB_SETTEXT, 0, &buffer2[0]); } } } diff --git a/engines/ags/engine/gui/mylabel.cpp b/engines/ags/engine/gui/mylabel.cpp index 69a330b9844d..817d643d7606 100644 --- a/engines/ags/engine/gui/mylabel.cpp +++ b/engines/ags/engine/gui/mylabel.cpp @@ -63,7 +63,7 @@ int MyLabel::pressedon(int mouseX, int mouseY) { return 0; } -int MyLabel::processmessage(int mcode, int wParam, long lParam) { +int MyLabel::processmessage(int mcode, int wParam, NumberPtr lParam) { return -1; // doesn't support messages } diff --git a/engines/ags/engine/gui/mylabel.h b/engines/ags/engine/gui/mylabel.h index 67cdc5508269..43722cfee95c 100644 --- a/engines/ags/engine/gui/mylabel.h +++ b/engines/ags/engine/gui/mylabel.h @@ -35,7 +35,7 @@ struct MyLabel : public NewControl { int pressedon(int mouseX, int mouseY) override; - int processmessage(int mcode, int wParam, long lParam) override; + int processmessage(int mcode, int wParam, NumberPtr lParam) override; }; } // namespace AGS3 diff --git a/engines/ags/engine/gui/mylistbox.cpp b/engines/ags/engine/gui/mylistbox.cpp index c0e77e92da02..2579767a1e43 100644 --- a/engines/ags/engine/gui/mylistbox.cpp +++ b/engines/ags/engine/gui/mylistbox.cpp @@ -139,9 +139,9 @@ void MyListBox::additem(char *texx) { needredraw = 1; } -int MyListBox::processmessage(int mcode, int wParam, long lParam) { +int MyListBox::processmessage(int mcode, int wParam, NumberPtr lParam) { if (mcode == CLB_ADDITEM) { - additem((char *)lParam); + additem((char *)lParam._ptr); } else if (mcode == CLB_CLEAR) clearlist(); else if (mcode == CLB_GETCURSEL) @@ -155,12 +155,12 @@ int MyListBox::processmessage(int mcode, int wParam, long lParam) { if (topitem + numonscreen <= selected) topitem = (selected + 1) - numonscreen; } else if (mcode == CLB_GETTEXT) - strcpy((char *)lParam, itemnames[wParam]); + strcpy((char *)lParam._ptr, itemnames[wParam]); else if (mcode == CLB_SETTEXT) { if (wParam < items) free(itemnames[wParam]); - char *newstri = (char *)lParam; + char *newstri = (char *)lParam._ptr; itemnames[wParam] = (char *)malloc(strlen(newstri) + 2); strcpy(itemnames[wParam], newstri); diff --git a/engines/ags/engine/gui/mylistbox.h b/engines/ags/engine/gui/mylistbox.h index b70b45ee4f15..a817029d8a9b 100644 --- a/engines/ags/engine/gui/mylistbox.h +++ b/engines/ags/engine/gui/mylistbox.h @@ -40,7 +40,7 @@ struct MyListBox : public NewControl { void draw(Shared::Bitmap *ds) override; int pressedon(int mousex, int mousey) override; void additem(char *texx); - int processmessage(int mcode, int wParam, long lParam) override; + int processmessage(int mcode, int wParam, NumberPtr lParam) override; }; } // namespace AGS3 diff --git a/engines/ags/engine/gui/mypushbutton.cpp b/engines/ags/engine/gui/mypushbutton.cpp index f4dcc4c86b5f..7fbc5c7f10c3 100644 --- a/engines/ags/engine/gui/mypushbutton.cpp +++ b/engines/ags/engine/gui/mypushbutton.cpp @@ -109,7 +109,7 @@ int MyPushButton::pressedon(int mousex, int mousey) { return wasstat; } -int MyPushButton::processmessage(int mcode, int wParam, long lParam) { +int MyPushButton::processmessage(int mcode, int wParam, NumberPtr lParam) { return -1; // doesn't support messages } diff --git a/engines/ags/engine/gui/mypushbutton.h b/engines/ags/engine/gui/mypushbutton.h index 2ba6ca11ca25..3fc69782fde7 100644 --- a/engines/ags/engine/gui/mypushbutton.h +++ b/engines/ags/engine/gui/mypushbutton.h @@ -32,7 +32,7 @@ struct MyPushButton : public NewControl { MyPushButton(int xx, int yy, int wi, int hi, const char *tex); void draw(Shared::Bitmap *ds) override; int pressedon(int mousex, int mousey) override; - int processmessage(int mcode, int wParam, long lParam) override; + int processmessage(int mcode, int wParam, NumberPtr lParam) override; }; } // namespace AGS3 diff --git a/engines/ags/engine/gui/mytextbox.cpp b/engines/ags/engine/gui/mytextbox.cpp index b0d45b02180b..48507fb7de30 100644 --- a/engines/ags/engine/gui/mytextbox.cpp +++ b/engines/ags/engine/gui/mytextbox.cpp @@ -64,12 +64,12 @@ int MyTextBox::pressedon(int mousex, int mousey) { return 0; } -int MyTextBox::processmessage(int mcode, int wParam, long lParam) { +int MyTextBox::processmessage(int mcode, int wParam, NumberPtr lParam) { if (mcode == CTB_SETTEXT) { - strcpy(text, (char *)lParam); + strcpy(text, (char *)lParam._ptr); needredraw = 1; } else if (mcode == CTB_GETTEXT) - strcpy((char *)lParam, text); + strcpy((char *)lParam._ptr, text); else if (mcode == CTB_KEYPRESS) { if (wParam == 8) { if (text[0] != 0) diff --git a/engines/ags/engine/gui/mytextbox.h b/engines/ags/engine/gui/mytextbox.h index a2a3e7d16623..db7602c1eb50 100644 --- a/engines/ags/engine/gui/mytextbox.h +++ b/engines/ags/engine/gui/mytextbox.h @@ -33,7 +33,7 @@ struct MyTextBox : public NewControl { MyTextBox(int xx, int yy, int wii, const char *tee); void draw(Shared::Bitmap *ds) override; int pressedon(int mousex, int mousey) override; - int processmessage(int mcode, int wParam, long lParam) override; + int processmessage(int mcode, int wParam, NumberPtr lParam) override; }; } // namespace AGS3 diff --git a/engines/ags/engine/gui/newcontrol.h b/engines/ags/engine/gui/newcontrol.h index cfb19f128c26..43232819fd43 100644 --- a/engines/ags/engine/gui/newcontrol.h +++ b/engines/ags/engine/gui/newcontrol.h @@ -35,7 +35,7 @@ struct NewControl { char needredraw; virtual void draw(Shared::Bitmap *ds) = 0; virtual int pressedon(int mousex, int mousey) = 0; - virtual int processmessage(int, int, long) = 0; + virtual int processmessage(int, int, NumberPtr) = 0; NewControl(int xx, int yy, int wi, int hi); NewControl(); diff --git a/engines/ags/lib/aastr-0.1.1/aarot.cpp b/engines/ags/lib/aastr-0.1.1/aarot.cpp index 0c9a364da9a1..2f4b65a7de89 100644 --- a/engines/ags/lib/aastr-0.1.1/aarot.cpp +++ b/engines/ags/lib/aastr-0.1.1/aarot.cpp @@ -66,7 +66,7 @@ _aa_rotate_bitmap(BITMAP *_src, BITMAP *_dst, int _x, int _y, fixed _angle, int syinc, sydd, syi1, syi2; unsigned long num; void (*add) (BITMAP * _src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); - void (*put) (unsigned long _addr, int _x); + void (*put) (byte *_addr, int _x); if (_dst->clip) { xbeg = _dst->cl; @@ -449,7 +449,7 @@ _aa_rotate_bitmap(BITMAP *_src, BITMAP *_dst, int _x, int _y, fixed _angle, /* Stretch lines. */ while (dy < yend) { - unsigned long daddr = bmp_write_line(_dst, dy); + byte *daddr = bmp_write_line(_dst, dy); if ((ldx < xend) && (rdx >= xbeg)) { int curxend; diff --git a/engines/ags/lib/aastr-0.1.1/aastr.cpp b/engines/ags/lib/aastr-0.1.1/aastr.cpp index b753d9e5f2d5..3cc53b647aa3 100644 --- a/engines/ags/lib/aastr-0.1.1/aastr.cpp +++ b/engines/ags/lib/aastr-0.1.1/aastr.cpp @@ -53,8 +53,8 @@ _aa_stretch_blit(BITMAP *_src, BITMAP *_dst, int yi1, yi2, ydd; int dxbeg, dxend, dybeg, dyend; unsigned long num; - void (*add) (BITMAP * _src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); - void (*put) (unsigned long _addr, int _x); + void (*add)(BITMAP * _src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num); + void (*put)(byte *_addr, int _x); if ((_dw <= 0) || (_dh <= 0) || (_sw <= 0) || (_sh <= 0)) return; @@ -188,7 +188,7 @@ _aa_stretch_blit(BITMAP *_src, BITMAP *_dst, /* Stretch all non-clipped lines. */ for (; dy < dyend; dy++) { - unsigned long daddr = bmp_write_line(_dst, dy); + byte *daddr = bmp_write_line(_dst, dy); for (dx = ydx, sx = ysx, xdd = yxdd; dx < dxend; dx++) { (*add) (_src, sx, sx + dsx, sy, sy + dsy, num); diff --git a/engines/ags/lib/aastr-0.1.1/aautil.cpp b/engines/ags/lib/aastr-0.1.1/aautil.cpp index ebd0889cf31f..98e50e988217 100644 --- a/engines/ags/lib/aastr-0.1.1/aautil.cpp +++ b/engines/ags/lib/aastr-0.1.1/aautil.cpp @@ -722,44 +722,33 @@ _aa_add_rgb32 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned lo /* * Putting pixel to destination bitmap. */ -void -_aa_put_rgb8 (unsigned long _addr, int _x) -{ - bmp_write8 (_addr + _x, makecol8(_aa.r, _aa.g, _aa.b)); +void _aa_put_rgb8(byte *addr, int _x) { + bmp_write8(addr + _x, makecol8(_aa.r, _aa.g, _aa.b)); } #ifdef ALLEGRO_COLOR16 -void -_aa_put_rgb15 (unsigned long _addr, int _x) -{ - bmp_write15 (_addr + sizeof (short) * _x, makecol15 (_aa.r, _aa.g, _aa.b)); +void _aa_put_rgb15 (byte *addr, int _x) { + bmp_write15 (addr + sizeof (short) * _x, makecol15 (_aa.r, _aa.g, _aa.b)); } -void -_aa_put_rgb16 (unsigned long _addr, int _x) -{ - bmp_write16 (_addr + sizeof (short) * _x, makecol16 (_aa.r, _aa.g, _aa.b)); + +void _aa_put_rgb16 (byte *addr, int _x) { + bmp_write16 (addr + sizeof (short) * _x, makecol16 (_aa.r, _aa.g, _aa.b)); } #endif #ifdef ALLEGRO_COLOR24 -void -_aa_put_rgb24 (unsigned long _addr, int _x) -{ - bmp_write24 (_addr + 3 * _x, makecol24 (_aa.r, _aa.g, _aa.g)); +void _aa_put_rgb24 (byte *addr, int _x) { + bmp_write24 (addr + 3 * _x, makecol24 (_aa.r, _aa.g, _aa.g)); } #endif #ifdef ALLEGRO_COLOR32 -void -_aa_put_rgb32 (unsigned long _addr, int _x) -{ - bmp_write32 (_addr + sizeof (int) * _x, makecol32 (_aa.r, _aa.g, _aa.b)); +void _aa_put_rgb32 (byte *addr, int _x) { + bmp_write32 (addr + sizeof (int) * _x, makecol32 (_aa.r, _aa.g, _aa.b)); } #endif /* * Add masked r, g, b values of pixels. */ -void -_aa_masked_add_rgb8 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) -{ +void _aa_masked_add_rgb8 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsigned long _num) { unsigned char *sline; int sx, sx1i, sx1f, sx2i, sx2f; int sy, sy1i, sy1f, sy2i, sy2f; @@ -1796,39 +1785,39 @@ _aa_masked_add_rgb32 (BITMAP *_src, int _sx1, int _sx2, int _sy1, int _sy2, unsi * Putting pixel to destination bitmap. */ void -_aa_masked_put_rgb8 (unsigned long _addr, int _x) +_aa_masked_put_rgb8(byte *addr, int _x) { if (!_aa.transparent) - bmp_write8 (_addr + _x, makecol8 (_aa.r, _aa.g, _aa.b)); + bmp_write8(addr + _x, makecol8 (_aa.r, _aa.g, _aa.b)); } #ifdef ALLEGRO_COLOR16 void -_aa_masked_put_rgb15 (unsigned long _addr, int _x) +_aa_masked_put_rgb15 (byte *addr, int _x) { if (!_aa.transparent) - bmp_write15 (_addr + sizeof (short) * _x, makecol15 (_aa.r, _aa.g, _aa.b)); + bmp_write15 (addr + sizeof (short) * _x, makecol15 (_aa.r, _aa.g, _aa.b)); } void -_aa_masked_put_rgb16 (unsigned long _addr, int _x) +_aa_masked_put_rgb16 (byte *addr, int _x) { if (!_aa.transparent) - bmp_write16 (_addr + sizeof (short) * _x, makecol16 (_aa.r, _aa.g, _aa.b)); + bmp_write16 (addr + sizeof (short) * _x, makecol16 (_aa.r, _aa.g, _aa.b)); } #endif #ifdef ALLEGRO_COLOR24 void -_aa_masked_put_rgb24 (unsigned long _addr, int _x) +_aa_masked_put_rgb24 (byte *addr, int _x) { if (!_aa.transparent) - bmp_write24 (_addr + 3 * _x, makecol24 (_aa.r, _aa.g, _aa.b)); + bmp_write24 (addr + 3 * _x, makecol24 (_aa.r, _aa.g, _aa.b)); } #endif #ifdef ALLEGRO_COLOR32 void -_aa_masked_put_rgb32 (unsigned long _addr, int _x) +_aa_masked_put_rgb32 (byte *addr, int _x) { if (!_aa.transparent) - bmp_write32 (_addr + sizeof (int) * _x, makecol32 (_aa.r, _aa.g, _aa.b)); + bmp_write32 (addr + sizeof (int) * _x, makecol32 (_aa.r, _aa.g, _aa.b)); } #endif diff --git a/engines/ags/lib/aastr-0.1.1/aautil.h b/engines/ags/lib/aastr-0.1.1/aautil.h index 8616f8c286f3..7dce41fe1400 100644 --- a/engines/ags/lib/aastr-0.1.1/aautil.h +++ b/engines/ags/lib/aastr-0.1.1/aautil.h @@ -114,16 +114,16 @@ extern "C" { #endif /* Put pixel to destination bitmap. */ - void _aa_put_rgb8(unsigned long _addr, int _x); + void _aa_put_rgb8(byte *addr, int _x); #ifdef ALLEGRO_COLOR16 - void _aa_put_rgb15(unsigned long _addr, int _x); - void _aa_put_rgb16(unsigned long _addr, int _x); + void _aa_put_rgb15(byte *addr, int _x); + void _aa_put_rgb16(byte *addr, int _x); #endif #ifdef ALLEGRO_COLOR24 - void _aa_put_rgb24(unsigned long _addr, int _x); + void _aa_put_rgb24(byte *addr, int _x); #endif #ifdef ALLEGRO_COLOR32 - void _aa_put_rgb32(unsigned long _addr, int _x); + void _aa_put_rgb32(byte *addr, int _x); #endif /* Add r,g,b and transparency values from source bitmap. */ @@ -145,16 +145,16 @@ extern "C" { #endif /* Put masked pixel to destination bitmap. */ - void _aa_masked_put_rgb8(unsigned long _addr, int _x); + void _aa_masked_put_rgb8(byte *addr, int _x); #ifdef ALLEGRO_COLOR16 - void _aa_masked_put_rgb15(unsigned long _addr, int _x); - void _aa_masked_put_rgb16(unsigned long _addr, int _x); + void _aa_masked_put_rgb15(byte *addr, int _x); + void _aa_masked_put_rgb16(byte *addr, int _x); #endif #ifdef ALLEGRO_COLOR24 - void _aa_masked_put_rgb24(unsigned long _addr, int _x); + void _aa_masked_put_rgb24(byte *addr, int _x); #endif #ifdef ALLEGRO_COLOR32 - void _aa_masked_put_rgb32(unsigned long _addr, int _x); + void _aa_masked_put_rgb32(byte *addr, int _x); #endif #ifdef __cplusplus diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index fc855550b268..065e5738faf8 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -338,16 +338,16 @@ void bmp_select(BITMAP *bmp) { // No implementation needed } -long bmp_write_line(BITMAP *bmp, int line) { - return (long)bmp->line[line]; +byte *bmp_write_line(BITMAP *bmp, int line) { + return bmp->line[line]; } void bmp_unwrite_line(BITMAP *bmp) { // No implementation needed } -void bmp_write8(unsigned long addr, int color) { - *((byte *)addr) = color; +void bmp_write8(byte *addr, int color) { + *addr = color; } void memory_putpixel(BITMAP *bmp, int x, int y, int color) { diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index 5075bd9a9a27..b5006e55af55 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -310,9 +310,9 @@ extern bool is_video_bitmap(BITMAP *bmp); extern bool is_linear_bitmap(BITMAP *bmp); extern bool is_planar_bitmap(BITMAP *bmp); extern void bmp_select(BITMAP *bmp); -extern long bmp_write_line(BITMAP *bmp, int line); +extern byte *bmp_write_line(BITMAP *bmp, int line); extern void bmp_unwrite_line(BITMAP *bmp); -extern void bmp_write8(unsigned long addr, int color); +extern void bmp_write8(byte *addr, int color); extern void memory_putpixel(BITMAP *bmp, int x, int y, int color); extern void putpixel(BITMAP *bmp, int x, int y, int color); extern void _putpixel(BITMAP *bmp, int x, int y, int color); diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index c77a9e6e2090..0aa1fd3e6384 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -102,6 +102,19 @@ enum { kUnit = 1 << kShift }; +/** + * Basic union that can be either a number or a pointer. Helps avoid some + * of the more nasty casts the codebase does, which was causing issues + * on 64-bit systems + */ +union NumberPtr { + int32 _value; + void *_ptr; + + NumberPtr(int value) : _value(value) {} + NumberPtr(void *ptr) : _ptr(ptr) {} +}; + } // namespace AGS3 #endif From dd69a28de6ddd933e332a4b186f38e39e2732a93 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jan 2021 21:07:19 -0800 Subject: [PATCH 160/215] AGS: Allow plugins onEvent 64-bit pointers --- engines/ags/engine/ac/global_game.cpp | 3 ++- engines/ags/engine/ac/global_translation.cpp | 4 ++-- engines/ags/engine/plugin/agsplugin.cpp | 9 +++++---- engines/ags/engine/plugin/plugin_builtin.h | 2 +- engines/ags/engine/plugin/plugin_engine.h | 2 +- engines/ags/plugins/dll.cpp | 2 +- engines/ags/plugins/dll.h | 2 +- engines/ags/shared/core/types.h | 3 ++- 8 files changed, 15 insertions(+), 12 deletions(-) diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp index 64603bafa340..14f70c0faac0 100644 --- a/engines/ags/engine/ac/global_game.cpp +++ b/engines/ags/engine/ac/global_game.cpp @@ -597,7 +597,8 @@ void GetLocationName(int xxx, int yyy, char *tempo) { return; } onhs = getloctype_index; - if (onhs > 0) strcpy(tempo, get_translation(thisroom.Hotspots[onhs].Name)); + if (onhs > 0) + strcpy(tempo, get_translation(thisroom.Hotspots[onhs].Name)); if (play.get_loc_name_last_time != onhs) guis_need_update = 1; play.get_loc_name_last_time = onhs; diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index 07c277175233..6ee31b312e77 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -50,8 +50,8 @@ const char *get_translation(const char *text) { #if AGS_PLATFORM_64BIT // check if a plugin wants to translate it - if so, return that - // TODO: plugin API is currently strictly 32-bit, so this may break on 64-bit systems - char *plResult = Int32ToPtr(pl_run_plugin_hooks(AGSE_TRANSLATETEXT, PtrToInt32(text))); + char *plResult = (char *)(pl_run_plugin_hooks(AGSE_TRANSLATETEXT, + const_cast(text)))._ptr; if (plResult) { return plResult; } diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/engine/plugin/agsplugin.cpp index 626ced045aa2..7c18d3f358df 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/engine/plugin/agsplugin.cpp @@ -128,7 +128,7 @@ struct EnginePlugin { int invalidatedRegion; void (*engineStartup)(IAGSEngine *) = nullptr; void (*engineShutdown)() = nullptr; - int (*onEvent)(int, int) = nullptr; + NumberPtr (*onEvent)(int, NumberPtr) = nullptr; void (*initGfxHook)(const char *driverName, void *data) = nullptr; int (*debugHook)(const char *whichscript, int lineNumber, int reserved) = nullptr; IAGSEngine eiface; @@ -880,8 +880,9 @@ void pl_startup_plugins() { } } -int pl_run_plugin_hooks(int event, int data) { - int i, retval = 0; +NumberPtr pl_run_plugin_hooks(int event, NumberPtr data) { + int i; + NumberPtr retval = 0; for (i = 0; i < numPlugins; i++) { if (plugins[i].wantHook & event) { retval = plugins[i].onEvent(event, data); @@ -1040,7 +1041,7 @@ Engine::GameInitError pl_register_plugins(const std::vector if (apl->engineStartup == nullptr) { quitprintf("Plugin '%s' is not a valid AGS plugin (no engine startup entry point)", apl->filename); } - apl->onEvent = (int(*)(int, int))apl->library.GetFunctionAddress("AGS_EngineOnEvent"); + apl->onEvent = (NumberPtr(*)(int, NumberPtr))apl->library.GetFunctionAddress("AGS_EngineOnEvent"); apl->debugHook = (int(*)(const char *, int, int))apl->library.GetFunctionAddress("AGS_EngineDebugHook"); apl->initGfxHook = (void(*)(const char *, void *))apl->library.GetFunctionAddress("AGS_EngineInitGfx"); } else { diff --git a/engines/ags/engine/plugin/plugin_builtin.h b/engines/ags/engine/plugin/plugin_builtin.h index 3db0f06e60a8..ed698989a7f0 100644 --- a/engines/ags/engine/plugin/plugin_builtin.h +++ b/engines/ags/engine/plugin/plugin_builtin.h @@ -41,7 +41,7 @@ struct InbuiltPluginDetails { char filename[PLUGIN_FILENAME_MAX + 1]; void (*engineStartup)(IAGSEngine *); void (*engineShutdown)(); - int (*onEvent)(int, int); + NumberPtr (*onEvent)(int, NumberPtr); void (*initGfxHook)(const char *driverName, void *data); int (*debugHook)(const char *whichscript, int lineNumber, int reserved); }; diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/engine/plugin/plugin_engine.h index 430d3c5d7e74..7ae9343c6504 100644 --- a/engines/ags/engine/plugin/plugin_engine.h +++ b/engines/ags/engine/plugin/plugin_engine.h @@ -48,7 +48,7 @@ using namespace AGS; // FIXME later void pl_stop_plugins(); void pl_startup_plugins(); -int pl_run_plugin_hooks(int event, int data); +NumberPtr pl_run_plugin_hooks(int event, NumberPtr data); void pl_run_plugin_init_gfx_hooks(const char *driverName, void *data); int pl_run_plugin_debug_hooks(const char *scriptfile, int linenum); // Tries to register plugins, either by loading dynamic libraries, or getting any kind of replacement diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index c9a1d9e91527..a4d0b100284b 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -90,7 +90,7 @@ void DLL::AGS_EngineStartup(IAGSEngine *) { void DLL::AGS_EngineShutdown() { } -int DLL::AGS_EngineOnEvent(int, int) { +NumberPtr DLL::AGS_EngineOnEvent(int, NumberPtr) { return 0; } diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h index c198add1f60b..8aa7f9049934 100644 --- a/engines/ags/plugins/dll.h +++ b/engines/ags/plugins/dll.h @@ -98,7 +98,7 @@ class DLL { static void AGS_EditorLoadGame(char *, int); static void AGS_EngineStartup(IAGSEngine *); static void AGS_EngineShutdown(); - static int AGS_EngineOnEvent(int, int); + static NumberPtr AGS_EngineOnEvent(int, NumberPtr); static int AGS_EngineDebugHook(const char *, int, int); static void AGS_EngineInitGfx(const char *driverID, void *data); public: diff --git a/engines/ags/shared/core/types.h b/engines/ags/shared/core/types.h index 0aa1fd3e6384..35f839fb37b6 100644 --- a/engines/ags/shared/core/types.h +++ b/engines/ags/shared/core/types.h @@ -111,8 +111,9 @@ union NumberPtr { int32 _value; void *_ptr; - NumberPtr(int value) : _value(value) {} + NumberPtr(int value) { _ptr = nullptr; _value = value; } NumberPtr(void *ptr) : _ptr(ptr) {} + operator bool() const { return _ptr != nullptr; } }; } // namespace AGS3 From ce1901784a49ea378214d96d7775dbb349268565 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jan 2021 22:32:42 -0800 Subject: [PATCH 161/215] AGS: Tentative draw_lit_sprite implementation --- engines/ags/lib/allegro/gfx.cpp | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 065e5738faf8..8353437a6165 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -290,7 +290,39 @@ void draw_trans_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { } void draw_lit_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int color) { - error("TODO: draw_lit_sprite"); + // TODO: For now, only 32-bit bitmaps + assert(sprite->format.bytesPerPixel == 4 && bmp->format.bytesPerPixel == 4); + byte rSrc, gSrc, bSrc, aSrc; + byte rDest, gDest, bDest; + double alpha = (double)color / 255.0; + + for (int yCtr = 0, yp = y; yCtr < sprite->h && yp < bmp->h; ++yCtr, ++yp) { + if (yp < 0) + continue; + + const uint32 *srcP = (const uint32 *)sprite->getBasePtr(0, yCtr); + uint32 *destP = (uint32 *)bmp->getBasePtr(x, yp); + + for (int xCtr = 0, xp = x; xCtr < sprite->w && xp < bmp->w; ++xCtr, ++xp, ++destP) { + if (x < 0 || x >= bmp->w) + continue; + + // Get the source and dest pixels + sprite->format.colorToARGB(*srcP, aSrc, rSrc, gSrc, bSrc); + bmp->format.colorToRGB(*destP, rDest, gDest, bDest); + + if (rSrc == 255 && gSrc == 0 && bSrc == 255) + // Skip transparent pixels + continue; + + // Blend the two + rDest = static_cast((rSrc * alpha) + (rDest * (1.0 - alpha))); + gDest = static_cast((gSrc * alpha) + (gDest * (1.0 - alpha))); + bDest = static_cast((bSrc * alpha) + (bDest * (1.0 - alpha))); + + *destP = bmp->format.RGBToColor(rDest, gDest, bDest); + } + } } void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { From 58265972a6f31b292ec222f91e8a73612c14350a Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sat, 23 Jan 2021 18:07:28 +0000 Subject: [PATCH 162/215] AGS: Fix compilation when theoradec is disabled --- engines/ags/engine/media/video/video.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engines/ags/engine/media/video/video.cpp b/engines/ags/engine/media/video/video.cpp index 998b29fee083..b4c385a68e1a 100644 --- a/engines/ags/engine/media/video/video.cpp +++ b/engines/ags/engine/media/video/video.cpp @@ -52,6 +52,9 @@ namespace AGS3 { using AGS::Shared::AssetManager; void play_theora_video(const char *name, int skip, int flags) { +#if !defined (USE_THEORADEC) + Display("This games uses Theora videos but ScummVM has been compiled without Theora support"); +#else std::unique_ptr video_stream(AssetManager::OpenAsset(name)); if (!video_stream) { Display("Unable to load theora video '%s'", name); @@ -120,7 +123,9 @@ void play_theora_video(const char *name, int skip, int flags) { } invalidate_screen(); +#endif } + void play_flc_file(int numb, int playflags) { warning("TODO: play_flc_file"); } From 6c2afc42792bbc27f069a4b62759e44488a89e24 Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sat, 23 Jan 2021 18:21:59 +0000 Subject: [PATCH 163/215] AGS: Fix out of bound crossfade volume The code was trying to pass a volume defined between 0 and 255 to a function expecting a volume between 0 and 100, causing an assert. --- engines/ags/engine/media/audio/audio.cpp | 4 ++-- engines/ags/engine/media/audio/soundclip.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 90b4a96829a0..342fc3aac739 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -277,7 +277,7 @@ static void audio_update_polled_stuff() { if (play.crossfading_out_channel > 0) { SOUNDCLIP *ch = lock.GetChannel(play.crossfading_out_channel); - int newVolume = ch ? ch->get_volume() - play.crossfade_out_volume_per_step : 0; + int newVolume = ch ? ch->get_volume_percent() - play.crossfade_out_volume_per_step : 0; if (newVolume > 0) { AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_out_channel], newVolume); } else { @@ -291,7 +291,7 @@ static void audio_update_polled_stuff() { if (play.crossfading_in_channel > 0) { SOUNDCLIP *ch = lock.GetChannel(play.crossfading_in_channel); - int newVolume = ch ? ch->get_volume() + play.crossfade_in_volume_per_step : 0; + int newVolume = ch ? ch->get_volume_percent() + play.crossfade_in_volume_per_step : 0; if (newVolume > play.crossfade_final_volume_in) { newVolume = play.crossfade_final_volume_in; } diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index 6d520bfba109..ccd071cd21cd 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -91,6 +91,9 @@ struct SOUNDCLIP { inline void set_volume_percent(int volume) { set_volume((volume * 255) / 100); } + inline int get_volume_percent() const { + return get_volume() * 100 / 255; + } void adjust_volume(); int play_from(int position); From c6ae319c973c4f07c4f5f2fb2f3e201ccaa041b3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jan 2021 19:04:21 -0800 Subject: [PATCH 164/215] AGS: Change game folder consts from String to const char * --- engines/ags/engine/ac/file.cpp | 8 ++++---- engines/ags/engine/ac/game.cpp | 4 ++-- engines/ags/engine/ac/path_helper.h | 6 +++--- engines/ags/engine/main/engine.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index a0b5f7cc4d6e..06110570ab58 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -218,10 +218,10 @@ int File_GetPosition(sc_File *fil) { //============================================================================= -const String GameInstallRootToken = "$INSTALLDIR$"; -const String UserSavedgamesRootToken = "$MYDOCS$"; -const String GameSavedgamesDirToken = "$SAVEGAMEDIR$"; -const String GameDataDirToken = "$APPDATADIR$"; +const char *GameInstallRootToken = "$INSTALLDIR$"; +const char *UserSavedgamesRootToken = "$MYDOCS$"; +const char *GameSavedgamesDirToken = "$SAVEGAMEDIR$"; +const char *GameDataDirToken = "$APPDATADIR$"; void FixupFilename(char *filename) { const char *illegal = platform->GetIllegalFileChars(); diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 9899af897376..0cba7e1f1e05 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -382,10 +382,10 @@ bool MakeSaveGameDir(const String &newFolder, ResolvedPath &rp) { String base_dir; String newSaveGameDir = FixSlashAfterToken(newFolder); - if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) { + if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, strlen(UserSavedgamesRootToken)) == 0) { if (saveGameParent.IsEmpty()) { base_dir = PathOrCurDir(platform->GetUserSavedgamesDirectory()); - newSaveGameDir.ReplaceMid(0, UserSavedgamesRootToken.GetLength(), base_dir); + newSaveGameDir.ReplaceMid(0, strlen(UserSavedgamesRootToken), base_dir); } else { // If there is a custom save parent directory, then replace // not only root token, but also first subdirectory diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h index 46349386ac9f..41d12fc570c5 100644 --- a/engines/ags/engine/ac/path_helper.h +++ b/engines/ags/engine/ac/path_helper.h @@ -36,9 +36,9 @@ namespace AGS3 { using AGS::Shared::String; // Filepath tokens, which are replaced by platform-specific directory names -extern const String UserSavedgamesRootToken; -extern const String GameSavedgamesDirToken; -extern const String GameDataDirToken; +extern const char *UserSavedgamesRootToken; +extern const char *GameSavedgamesDirToken; +extern const char *GameDataDirToken; inline const char *PathOrCurDir(const char *path) { return path ? path : "."; diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp index fb157b5fa4d0..cd1940f0463a 100644 --- a/engines/ags/engine/main/engine.cpp +++ b/engines/ags/engine/main/engine.cpp @@ -655,7 +655,7 @@ void engine_init_directories() { // if there is no custom path, or if custom path failed, use default system path if (!res) { char newDirBuffer[MAX_PATH]; - sprintf(newDirBuffer, "%s/%s", UserSavedgamesRootToken.GetCStr(), game.saveGameFolderName); + sprintf(newDirBuffer, "%s/%s", UserSavedgamesRootToken, game.saveGameFolderName); SetSaveGameDirectoryPath(newDirBuffer); } } From 854eda2aed64cc793ac3bb0214689347498015e5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jan 2021 21:22:56 -0800 Subject: [PATCH 165/215] AGS: Fix mapping folder macros like $ --- engines/ags/detection_tables.h | 1 + engines/ags/engine/ac/file.cpp | 50 ++++++++++++-------------------- engines/ags/engine/ac/game.cpp | 2 +- engines/ags/lib/allegro/file.cpp | 4 +-- 4 files changed, 23 insertions(+), 34 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 45c4e1634a5d..e0f1149b1ccf 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -80,6 +80,7 @@ static const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("qfi", "qfi.exe", "0702df6e67ef87fd3c51d09303803126", 534847265), // GOG ENGLISH_ENTRY("oott", "OotT-TKC.exe", "11c2421258465cba4bd773c49d918ee3", 467834855), // GOG ENGLISH_ENTRY("primordia", "primordia.exe", "22313e59c3233001488c26f18c80cc08", 973495830), // GOG + ENGLISH_ENTRY("primordia", "primordia.exe", "f2edc9c3161f1f538df9b4c59fc89e24", 978377890), // GOG ENGLISH_ENTRY("resonance", "resonance.exe", "2e635c22bcbf0ed3d46f1bcde71812d4", 849404957), // GOG // For some macOS and iOS releases the executable was renamed to ac2game.dat ENGLISH_ENTRY("mage", "ac2game.dat", "2e822f554994f36e0c62da2acda874da", 30492258), // GOG, Mac diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp index 06110570ab58..28b0814d61eb 100644 --- a/engines/ags/engine/ac/file.cpp +++ b/engines/ags/engine/ac/file.cpp @@ -288,8 +288,7 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath rp.FullPath = orig_sc_path; return true; } - -#if AGS_PLATFORM_SCUMMVM + /* if (read_only) { // For reading files, first try as a save file, then fall back // in the game folder. This handles cases where some games like @@ -304,13 +303,12 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath rp.FullPath = String::FromFormat("%s%s", SAVE_FOLDER_PREFIX, orig_sc_path.GetNullableCStr()); } - -#else + */ String sc_path = FixSlashAfterToken(orig_sc_path); String parent_dir; String child_path; String alt_path; - if (sc_path.CompareLeft(GameInstallRootToken, GameInstallRootToken.GetLength()) == 0) { + if (sc_path.CompareLeft(GameInstallRootToken) == 0) { if (!read_only) { debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory)", sc_path.GetCStr()); @@ -318,36 +316,26 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath } parent_dir = get_install_dir(); parent_dir.AppendChar('/'); - child_path = sc_path.Mid(GameInstallRootToken.GetLength()); - } else if (sc_path.CompareLeft(GameSavedgamesDirToken, GameSavedgamesDirToken.GetLength()) == 0) { + child_path = sc_path.Mid(strlen(GameInstallRootToken)); + } else if (sc_path.CompareLeft(GameSavedgamesDirToken) == 0) { parent_dir = get_save_game_directory(); - child_path = sc_path.Mid(GameSavedgamesDirToken.GetLength()); - } else if (sc_path.CompareLeft(GameDataDirToken, GameDataDirToken.GetLength()) == 0) { + child_path = sc_path.Mid(strlen(GameSavedgamesDirToken)); + } else if (sc_path.CompareLeft(GameDataDirToken) == 0) { parent_dir = MakeAppDataPath(); - child_path = sc_path.Mid(GameDataDirToken.GetLength()); + child_path = sc_path.Mid(strlen(GameDataDirToken)); } else { child_path = sc_path; - // For games which were made without having safe paths in mind, - // provide two paths: a path to the local directory and a path to - // AppData directory. - // This is done in case game writes a file by local path, and would - // like to read it back later. Since AppData path has higher priority, - // game will first check the AppData location and find a previously - // written file. - // If no file was written yet, but game is trying to read a pre-created - // file in the installation directory, then such file will be found - // following the 'alt_path'. - parent_dir = MakeAppDataPath(); - // Set alternate non-remapped "unsafe" path for read-only operations - if (read_only) - alt_path = String::FromFormat("%s/%s", get_install_dir().GetCStr(), sc_path.GetCStr()); - - // For games made in the safe-path-aware versions of AGS, report a warning - // if the unsafe path is used for write operation - if (!read_only && game.options[OPT_SAFEFILEPATHS]) { - debug_script_warn("Attempt to access file '%s' denied (cannot write to game installation directory);\nPath will be remapped to the app data directory: '%s'", - sc_path.GetCStr(), parent_dir.GetCStr()); + // For cases where a file is trying to write to a game path, always remap + // it to write to a savefile. For normal reading, we thus need to give + // preference to any save file with a given name before looking in the + // game folder. This for example fixes an issue with The Blackwell Legacy, + // which wants to create a new prog.bwl in the game folder + parent_dir = SAVE_FOLDER_PREFIX; + + if (read_only) { + alt_path = String::FromFormat("%s/%s", get_install_dir().GetCStr(), + sc_path.GetCStr()); } } @@ -365,7 +353,7 @@ bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath rp.BaseDir = parent_dir; rp.FullPath = full_path; rp.AltPath = alt_path; -#endif + return true; } diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 0cba7e1f1e05..f7788186da87 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -204,7 +204,7 @@ MoveList *mls = nullptr; //============================================================================= -String saveGameDirectory = "./"; +String saveGameDirectory = SAVE_FOLDER_PREFIX; // Custom save game parent directory String saveGameParent; diff --git a/engines/ags/lib/allegro/file.cpp b/engines/ags/lib/allegro/file.cpp index e4dd65417956..b8c02fba7671 100644 --- a/engines/ags/lib/allegro/file.cpp +++ b/engines/ags/lib/allegro/file.cpp @@ -127,8 +127,8 @@ char *make_relative_filename(char *dest, const char *path, const char *filename, } int is_relative_filename(const char *filename) { - Common::String fname(filename); - return !fname.contains('/') && !fname.contains('\\') ? 1 : 0; + // ScummVM doesn't have absolute paths + return true; } /*------------------------------------------------------------------*/ From 0796484d0abeb3690daba26a70e891b0c6a06f6d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 10:08:42 -0800 Subject: [PATCH 166/215] AGS: Framework for specifying a specific plugin version a game needs Black Cauldron uses the AGSCreditz 1.1 plugin, but in the 2.0 version I was given the source for, there are differences in the method declarations. So this new framework allows me to explicitly specify that the game needs 1.1 --- engines/ags/ags.cpp | 4 + engines/ags/ags.h | 3 + engines/ags/detection.h | 6 + engines/ags/detection_tables.h | 22 +++- engines/ags/plugins/agscreditz/agscreditz.cpp | 123 +++++++++++++----- engines/ags/plugins/agscreditz/agscreditz.h | 117 ++++++++++++++++- engines/ags/plugins/dll.cpp | 21 ++- engines/ags/plugins/dll.h | 1 + 8 files changed, 252 insertions(+), 45 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index d3a54972d5c5..bf61c62120ed 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -302,6 +302,10 @@ uint32 AGSEngine::getFeatures() const { return _gameDescription->desc.flags; } +const PluginVersion *AGSEngine::getNeededPlugins() const { + return _gameDescription->_plugins; +} + Common::Error AGSEngine::run() { const char *filename = _gameDescription->desc.filesDescriptions[0].fileName; const char *ARGV[] = { "scummvm.exe", filename }; diff --git a/engines/ags/ags.h b/engines/ags/ags.h index 10bcf431fbae..f1004110f150 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -52,6 +52,7 @@ enum AGSDebugChannels { }; struct AGSGameDescription; +struct PluginVersion; class EventsManager; class Music; @@ -83,6 +84,8 @@ class AGSEngine : public Engine { uint32 getFeatures() const; + const PluginVersion *getNeededPlugins() const; + /** * Returns the current list of savegames */ diff --git a/engines/ags/detection.h b/engines/ags/detection.h index 366758251656..9ac3d6ae35db 100644 --- a/engines/ags/detection.h +++ b/engines/ags/detection.h @@ -27,8 +27,14 @@ namespace AGS { +struct PluginVersion { + const char *_plugin; + int _version; +}; + struct AGSGameDescription { ADGameDescription desc; + const PluginVersion *_plugins; }; } // namespace AGS diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index e0f1149b1ccf..267f99bf6158 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -56,13 +56,29 @@ static const PlainGameDescriptor GAME_NAMES[] = { AD_ENTRY1s(FILENAME, MD5, SIZE), \ Common::EN_ANY, \ Common::kPlatformUnknown, \ - ADGF_NO_FLAGS, \ + ADGF_UNSTABLE, \ GUIO1(GUIO_NOSPEECH) \ - } \ + }, \ + nullptr \ } +#define ENGLISH_PLUGIN(ID, FILENAME, MD5, SIZE, PLUGIN_ARR) { \ + { \ + ID, \ + nullptr, \ + AD_ENTRY1s(FILENAME, MD5, SIZE), \ + Common::EN_ANY, \ + Common::kPlatformUnknown, \ + ADGF_UNSTABLE, \ + GUIO1(GUIO_NOSPEECH) \ + }, \ + PLUGIN_ARR \ + } + +static const PluginVersion AGSCREDITZ_11[] = { { "agscreditz", 11 }, { nullptr, 0 } }; + static const AGSGameDescription GAME_DESCRIPTIONS[] = { - ENGLISH_ENTRY("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255), + ENGLISH_PLUGIN("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255, AGSCREDITZ_11), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42740200), ENGLISH_ENTRY("blackwell1", "blackwell1.exe", "605e124cb7e0b56841c471e2d641c224", 18822697), // GOG diff --git a/engines/ags/plugins/agscreditz/agscreditz.cpp b/engines/ags/plugins/agscreditz/agscreditz.cpp index 21a0ce3ecb55..d77763ae801e 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.cpp +++ b/engines/ags/plugins/agscreditz/agscreditz.cpp @@ -20,23 +20,34 @@ * */ -#include "ags/plugins/agscreditz/agscreditz.h" +#include "ags/plugins/AGSCreditz/AGSCreditz.h" namespace AGS3 { namespace Plugins { -namespace AgsCreditz { +namespace AGSCreditz { + +AGSCreditz::Version AGSCreditz::_version; +State *AGSCreditz::_state; + +AGSCreditz::AGSCreditz() { + _state = new State(); -AgsCreditz::AgsCreditz() { DLL_METHOD(AGS_GetPluginName); - DLL_METHOD(AGS_EngineStartup); } -const char *AgsCreditz::AGS_GetPluginName() { - return "agsCreditz v1.1 by AJA"; +AGSCreditz::~AGSCreditz() { + delete _state; } -void AgsCreditz::AGS_EngineStartup(IAGSEngine *engine) { - SCRIPT_METHOD(SetCredit); + +const char *AGSCreditz::AGS_GetPluginName() { + if (_version == VERSION_11) + return "AGSCreditz v1.1 by AJA"; + else + return "AGSCreditz 2.0 (by Dima Software: AJA)"; +} + +void AGSCreditz::AGS_EngineStartup(IAGSEngine *engine) { SCRIPT_METHOD(ScrollCredits); SCRIPT_METHOD(GetCredit); SCRIPT_METHOD(IsCreditScrollingFinished); @@ -59,92 +70,138 @@ void AgsCreditz::AGS_EngineStartup(IAGSEngine *engine) { SCRIPT_METHOD(IsStaticCreditsFinished); } -void AgsCreditz::SetCredit(const ScriptMethodParams ¶ms) { - PARAMS7(int, ID, string, credit, int, colour, int, font, int, center, int, xpos, int, generateoutline); -} - -void AgsCreditz::ScrollCredits(const ScriptMethodParams ¶ms) { +void AGSCreditz::ScrollCredits(const ScriptMethodParams ¶ms) { PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, res); } -string AgsCreditz::GetCredit(const ScriptMethodParams ¶ms) { +string AGSCreditz::GetCredit(const ScriptMethodParams ¶ms) { PARAMS1(int, ID); return nullptr; } -int AgsCreditz::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { +int AGSCreditz::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { return true; } -void AgsCreditz::SetCreditImage(const ScriptMethodParams ¶ms) { +void AGSCreditz::SetCreditImage(const ScriptMethodParams ¶ms) { PARAMS5(int, ID, int, Slot, int, center, int, xpos, int, pixtonext); } -void AgsCreditz::PauseScroll(const ScriptMethodParams ¶ms) { +void AGSCreditz::PauseScroll(const ScriptMethodParams ¶ms) { PARAMS1(int, onoff); } -void AgsCreditz::ScrollReset(const ScriptMethodParams ¶ms) { +void AGSCreditz::ScrollReset(const ScriptMethodParams ¶ms) { } -void AgsCreditz::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { +void AGSCreditz::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { PARAMS1(int, Height); } -int AgsCreditz::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { +int AGSCreditz::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { return 0; } -void AgsCreditz::SetStaticCredit(const ScriptMethodParams ¶ms) { +void AGSCreditz::SetStaticCredit(const ScriptMethodParams ¶ms) { PARAMS8(int, ID, int, x, int, y, int, creditfont, int, creditcolour, int, centered, int, generateoutline, string, credit); } -string AgsCreditz::GetStaticCredit(const ScriptMethodParams ¶ms) { +string AGSCreditz::GetStaticCredit(const ScriptMethodParams ¶ms) { PARAMS1(int, ID); return nullptr; } -void AgsCreditz::StartEndStaticCredits(const ScriptMethodParams ¶ms) { +void AGSCreditz::StartEndStaticCredits(const ScriptMethodParams ¶ms) { PARAMS2(int, onoff, int, res); } -int AgsCreditz::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { +int AGSCreditz::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { return 0; } -void AgsCreditz::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { +void AGSCreditz::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { PARAMS1(int, Cyclesperchar); } -void AgsCreditz::SetStaticPause(const ScriptMethodParams ¶ms) { +void AGSCreditz::SetStaticPause(const ScriptMethodParams ¶ms) { PARAMS2(int, ID, int, length); } -void AgsCreditz::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { +void AGSCreditz::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { PARAMS8(int, ID, int, x, int, y, int, titlefont, int, titlecolour, int, centered, int, generateoutline, string, title); } -void AgsCreditz::ShowStaticCredit(const ScriptMethodParams ¶ms) { +void AGSCreditz::ShowStaticCredit(const ScriptMethodParams ¶ms) { PARAMS6(int, ID, int, time, int, style, int, transtime, int, sound, int, resolution); } -void AgsCreditz::StaticReset(const ScriptMethodParams ¶ms) { +void AGSCreditz::StaticReset(const ScriptMethodParams ¶ms) { } -string AgsCreditz::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { +string AGSCreditz::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { PARAMS1(int, ID); return nullptr; } -void AgsCreditz::SetStaticCreditImage(const ScriptMethodParams ¶ms) { +void AGSCreditz::SetStaticCreditImage(const ScriptMethodParams ¶ms) { //int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time) { } -int AgsCreditz::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { +int AGSCreditz::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { return true; } -} // namespace AgsCreditz +/*------------------------------------------------------------------*/ + +AGSCreditz11::AGSCreditz11() { + _version = VERSION_11; + + DLL_METHOD(AGS_EngineStartup); +} + +void AGSCreditz11::AGS_EngineStartup(IAGSEngine *engine) { + AGSCreditz::AGS_EngineStartup(engine); + SCRIPT_METHOD(SetCredit); +} + +void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { + PARAMS7(int, ID, string, credit, int, colour, int, font, int, center, int, xpos, int, generateoutline); + +} + +/*------------------------------------------------------------------*/ + +AGSCreditz20::AGSCreditz20() { + _version = VERSION_20; + + DLL_METHOD(AGS_EngineStartup); +} + +void AGSCreditz20::AGS_EngineStartup(IAGSEngine *engine) { + AGSCreditz::AGS_EngineStartup(engine); + SCRIPT_METHOD(SetCredit); +} + +void AGSCreditz20::SetCredit(const ScriptMethodParams ¶ms) { + PARAMS7(int, sequence, int, line, string, credit, int, x_pos, int, font, int, color, int, gen_outline); + + assert(sequence >= 0 && sequence <= 10); + if (line >= (int)_state->_credits[sequence].size()) + _state->_credits[sequence].resize(line + 1); + + Credit &c = _state->_credits[sequence][line]; + c._credit = credit; + c._fontSlot = font; + c._colorHeight = color; + c._x = x_pos; + c._isSet = true; + if (gen_outline > 0) + c._outline = true; +} + + + +} // namespace AGSCreditz } // namespace Plugins } // namespace AGS3 diff --git a/engines/ags/plugins/agscreditz/agscreditz.h b/engines/ags/plugins/agscreditz/agscreditz.h index a19a867035ad..ab93f88a13eb 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.h +++ b/engines/ags/plugins/agscreditz/agscreditz.h @@ -24,18 +24,102 @@ #define AGS_PLUGINS_AGSCREDITZ_AGSCREDITZ_H #include "ags/plugins/dll.h" +#include "common/array.h" +#include "common/rect.h" +#include "common/str.h" namespace AGS3 { namespace Plugins { -namespace AgsCreditz { +namespace AGSCreditz { -class AgsCreditz : public DLL { -private: +struct Credit { + Common::String _credit; + int _x = 0; + int _y = 0; + int _fontSlot = 0; + int _colorHeight = 0; + bool _isSet = false; + bool _image = false; + bool _outline = false; +}; + +struct SequenceSettings { + int startpoint = 0; + int endpoint = 0; + int speed = 0; + bool finished = false; + int automatic = 0; + int endwait = 0; + int topmask = 0; + int bottommask = 0; +}; + +struct StCredit { + Common::String credit; + Common::String title; + int x = 0; + int y = 0; + int font = 0; + int color = 0; + int title_x = 0; + int title_y = 0; + int title_font = 0; + int title_color = 0; + int pause = 0; + bool image = false; + int image_slot = 0; + int image_time = 0; + bool outline = false; + bool title_outline = false; +}; + +struct StSequenceSettings { + int speed = 0; + bool finished = false; +}; + +struct SingleStatic { + int id = 0; + int time = 0; + int style = 0; + int settings = 01; + int settings2 = 0; + bool bool_ = false; +}; + +typedef Common::Array CreditArray; +typedef Common::Array StCreditArray; + +struct State { + CreditArray _credits[10]; + StCreditArray _stCredits[10]; + bool _creditsRunning = 0, _paused = 0, _staticCredits = 0; + int _creditSequence = 0, _yPos = 0, _sequenceHeight = 0, _speedPoint = 0; + int _calculatedSequenceHeight = 0, _timer = 0, _currentStatic = 0; + int _numChars = 0, _timer2 = 0; + int _emptyLineHeight = 10; + int _strCredit[10]; + SequenceSettings _seqSettings[10]; + StSequenceSettings _stSeqSettings[10]; + SingleStatic _singleStatic; + void *_maskScreen = nullptr; + void *_maski = nullptr; + void *_creditScreen = nullptr; +}; + +class AGSCreditz : public DLL { +protected: + enum Version { + VERSION_11 = 11, VERSION_20 = 20 + }; + + static Version _version; + static State *_state; +protected: static const char *AGS_GetPluginName(); static void AGS_EngineStartup(IAGSEngine *engine); - // Script methods - static void SetCredit(const ScriptMethodParams ¶ms); + // Shared Script methods static void ScrollCredits(const ScriptMethodParams ¶ms); static string GetCredit(const ScriptMethodParams ¶ms); static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); @@ -57,10 +141,29 @@ class AgsCreditz : public DLL { static void SetStaticCreditImage(const ScriptMethodParams ¶ms); static int IsStaticCreditsFinished(const ScriptMethodParams ¶ms); public: - AgsCreditz(); + AGSCreditz(); + ~AGSCreditz(); +}; + +class AGSCreditz11 : public AGSCreditz { +private: + static void AGS_EngineStartup(IAGSEngine *engine); + + static void SetCredit(const ScriptMethodParams ¶ms); +public: + AGSCreditz11(); +}; + +class AGSCreditz20 : public AGSCreditz { +private: + static void AGS_EngineStartup(IAGSEngine *engine); + + static void SetCredit(const ScriptMethodParams ¶ms); +public: + AGSCreditz20(); }; -} // namespace AgsCreditz +} // namespace AGSCreditz } // namespace Plugins } // namespace AGS3 diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index a4d0b100284b..76dcb86a23c5 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -20,8 +20,11 @@ * */ +#include "ags/lib/allegro.h" #include "ags/plugins/dll.h" #include "ags/plugins/agscreditz/agscreditz.h" +#include "ags/ags.h" +#include "ags/detection.h" #include "common/str.h" namespace AGS3 { @@ -30,8 +33,22 @@ namespace Plugins { void *dlopen(const char *filename) { Common::String fname(filename); - if (fname.equalsIgnoreCase("libagsCreditz.so")) - return new AgsCreditz::AgsCreditz(); + // Check for if the game specifies a specific plugin version for this game + int version = 0; + for (const ::AGS::PluginVersion *v = ::AGS::g_vm->getNeededPlugins(); + v->_plugin; ++v) { + if (Common::String::format("lib%s.so", v->_plugin).equalsIgnoreCase(filename)) { + version = v->_version; + break; + } + } + + if (fname.equalsIgnoreCase("libagsCreditz.so")) { + if (version == 20) + return new AGSCreditz::AGSCreditz20(); + else + return new AGSCreditz::AGSCreditz11(); + } return nullptr; } diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h index 8aa7f9049934..d1e9c768a307 100644 --- a/engines/ags/plugins/dll.h +++ b/engines/ags/plugins/dll.h @@ -33,6 +33,7 @@ namespace Plugins { #define DLL_METHOD(NAME) _methods[#NAME] = (void *)&NAME #define SCRIPT_METHOD(NAME) engine->RegisterScriptFunction(#NAME, (void *)&NAME) +#define SCRIPT_METHOD_EXT(NAME, PROC) engine->RegisterScriptFunction(#NAME, (void *)&(PROC)) #define PARAMS1(T1, N1) \ T1 N1 = (T1)params[0] From 14cb959f1d547f95cd195ae4efd114e0da256667 Mon Sep 17 00:00:00 2001 From: dreammaster Date: Sun, 24 Jan 2021 19:04:42 +0000 Subject: [PATCH 167/215] AGS: Initial import of unmodified other plugins source the AGS codebase comes with the option to build with several built-in plugins that code is provided for. These will still need to be cleaned up for the ScummVM DLL implementation --- engines/ags/module.mk | 2 +- engines/ags/plugins/ags_blend/ags_blend.cpp | 1042 ++++++++ engines/ags/plugins/ags_blend/ags_blend.h | 14 + .../ags_creditz.cpp} | 2 +- .../ags_creditz.h} | 2 +- .../plugins/ags_flashlight/ags_flashlight.cpp | 829 +++++++ .../plugins/ags_flashlight/ags_flashlight.h | 14 + .../plugins/ags_pal_render/ags_pal_render.cpp | 2164 +++++++++++++++++ .../plugins/ags_pal_render/ags_pal_render.h | 14 + .../ags/plugins/ags_pal_render/agsplugin.h | 564 +++++ .../ags/plugins/ags_pal_render/pal_render.h | 185 ++ .../ags/plugins/ags_pal_render/raycast.cpp | 1498 ++++++++++++ engines/ags/plugins/ags_pal_render/raycast.h | 189 ++ .../ags/plugins/ags_parallax/ags_parallax.cpp | 287 +++ .../ags/plugins/ags_parallax/ags_parallax.h | 14 + .../plugins/ags_snow_rain/ags_snow_rain.cpp | 841 +++++++ .../ags/plugins/ags_snow_rain/ags_snow_rain.h | 14 + .../ags_sprite_font/ags_sprite_font.cpp | 279 +++ .../ags_sprite_font/character_entry.cpp | 13 + .../plugins/ags_sprite_font/character_entry.h | 12 + engines/ags/plugins/ags_sprite_font/color.cpp | 28 + engines/ags/plugins/ags_sprite_font/color.h | 21 + .../plugins/ags_sprite_font/sprite_font.cpp | 7 + .../ags/plugins/ags_sprite_font/sprite_font.h | 16 + .../ags_sprite_font/sprite_font_renderer.cpp | 171 ++ .../ags_sprite_font/sprite_font_renderer.h | 29 + .../ags_sprite_font/variable_width_font.cpp | 19 + .../ags_sprite_font/variable_width_font.h | 18 + .../variable_width_sprite_font.cpp | 182 ++ .../variable_width_sprite_font.h | 30 + engines/ags/plugins/dll.cpp | 4 +- engines/ags/plugins/dll.h | 4 +- 32 files changed, 8502 insertions(+), 6 deletions(-) create mode 100644 engines/ags/plugins/ags_blend/ags_blend.cpp create mode 100644 engines/ags/plugins/ags_blend/ags_blend.h rename engines/ags/plugins/{agscreditz/agscreditz.cpp => ags_creditz/ags_creditz.cpp} (99%) rename engines/ags/plugins/{agscreditz/agscreditz.h => ags_creditz/ags_creditz.h} (99%) create mode 100644 engines/ags/plugins/ags_flashlight/ags_flashlight.cpp create mode 100644 engines/ags/plugins/ags_flashlight/ags_flashlight.h create mode 100644 engines/ags/plugins/ags_pal_render/ags_pal_render.cpp create mode 100644 engines/ags/plugins/ags_pal_render/ags_pal_render.h create mode 100644 engines/ags/plugins/ags_pal_render/agsplugin.h create mode 100644 engines/ags/plugins/ags_pal_render/pal_render.h create mode 100644 engines/ags/plugins/ags_pal_render/raycast.cpp create mode 100644 engines/ags/plugins/ags_pal_render/raycast.h create mode 100644 engines/ags/plugins/ags_parallax/ags_parallax.cpp create mode 100644 engines/ags/plugins/ags_parallax/ags_parallax.h create mode 100644 engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp create mode 100644 engines/ags/plugins/ags_snow_rain/ags_snow_rain.h create mode 100644 engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp create mode 100644 engines/ags/plugins/ags_sprite_font/character_entry.cpp create mode 100644 engines/ags/plugins/ags_sprite_font/character_entry.h create mode 100644 engines/ags/plugins/ags_sprite_font/color.cpp create mode 100644 engines/ags/plugins/ags_sprite_font/color.h create mode 100644 engines/ags/plugins/ags_sprite_font/sprite_font.cpp create mode 100644 engines/ags/plugins/ags_sprite_font/sprite_font.h create mode 100644 engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp create mode 100644 engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h create mode 100644 engines/ags/plugins/ags_sprite_font/variable_width_font.cpp create mode 100644 engines/ags/plugins/ags_sprite_font/variable_width_font.h create mode 100644 engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp create mode 100644 engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h diff --git a/engines/ags/module.mk b/engines/ags/module.mk index e31bfb893827..ad2657cdcd40 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -301,7 +301,7 @@ MODULE_OBJS = \ engine/script/script_runtime.o \ engine/script/systemimports.o \ plugins/dll.o \ - plugins/agscreditz/agscreditz.o + plugins/ags_creditz/ags_creditz.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/plugins/ags_blend/ags_blend.cpp b/engines/ags/plugins/ags_blend/ags_blend.cpp new file mode 100644 index 000000000000..eeb3584a5046 --- /dev/null +++ b/engines/ags/plugins/ags_blend/ags_blend.cpp @@ -0,0 +1,1042 @@ +/*********************************************************** + * AGSBlend * + * * + * Author: Steven Poulton * + * * + * Date: 09/01/2011 * + * * + * Description: An AGS Plugin to allow true Alpha Blending * + * * + ***********************************************************/ + +#pragma region Defines_and_Includes + +#include "core/platform.h" + +#define MIN_EDITOR_VERSION 1 +#define MIN_ENGINE_VERSION 3 + +#if AGS_PLATFORM_OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include +#include +#include + +#if !defined(BUILTIN_PLUGINS) +#define THIS_IS_THE_PLUGIN +#endif + +#include "plugin/agsplugin.h" + +#if defined(BUILTIN_PLUGINS) +namespace agsblend { +#endif + +typedef unsigned char uint8; + +#define DEFAULT_RGB_R_SHIFT_32 16 +#define DEFAULT_RGB_G_SHIFT_32 8 +#define DEFAULT_RGB_B_SHIFT_32 0 +#define DEFAULT_RGB_A_SHIFT_32 24 + +#if !AGS_PLATFORM_OS_WINDOWS +#define min(x,y) (((x) < (y)) ? (x) : (y)) +#define max(x,y) (((x) > (y)) ? (x) : (y)) +#endif + +#define abs(a) ((a)<0 ? -(a) : (a)) +#define ChannelBlend_Normal(B,L) ((uint8)(B)) +#define ChannelBlend_Lighten(B,L) ((uint8)((L > B) ? L:B)) +#define ChannelBlend_Darken(B,L) ((uint8)((L > B) ? B:L)) +#define ChannelBlend_Multiply(B,L) ((uint8)((B * L) / 255)) +#define ChannelBlend_Average(B,L) ((uint8)((B + L) / 2)) +#define ChannelBlend_Add(B,L) ((uint8)(min(255, (B + L)))) +#define ChannelBlend_Subtract(B,L) ((uint8)((B + L < 255) ? 0:(B + L - 255))) +#define ChannelBlend_Difference(B,L) ((uint8)(abs(B - L))) +#define ChannelBlend_Negation(B,L) ((uint8)(255 - abs(255 - B - L))) +#define ChannelBlend_Screen(B,L) ((uint8)(255 - (((255 - B) * (255 - L)) >> 8))) +#define ChannelBlend_Exclusion(B,L) ((uint8)(B + L - 2 * B * L / 255)) +#define ChannelBlend_Overlay(B,L) ((uint8)((L < 128) ? (2 * B * L / 255):(255 - 2 * (255 - B) * (255 - L) / 255))) +#define ChannelBlend_SoftLight(B,L) ((uint8)((L < 128)?(2*((B>>1)+64))*((float)L/255):(255-(2*(255-((B>>1)+64))*(float)(255-L)/255)))) +#define ChannelBlend_HardLight(B,L) (ChannelBlend_Overlay(L,B)) +#define ChannelBlend_ColorDodge(B,L) ((uint8)((L == 255) ? L:min(255, ((B << 8 ) / (255 - L))))) +#define ChannelBlend_ColorBurn(B,L) ((uint8)((L == 0) ? L:max(0, (255 - ((255 - B) << 8 ) / L)))) +#define ChannelBlend_LinearDodge(B,L)(ChannelBlend_Add(B,L)) +#define ChannelBlend_LinearBurn(B,L) (ChannelBlend_Subtract(B,L)) +#define ChannelBlend_LinearLight(B,L)((uint8)(L < 128)?ChannelBlend_LinearBurn(B,(2 * L)):ChannelBlend_LinearDodge(B,(2 * (L - 128)))) +#define ChannelBlend_VividLight(B,L) ((uint8)(L < 128)?ChannelBlend_ColorBurn(B,(2 * L)):ChannelBlend_ColorDodge(B,(2 * (L - 128)))) +#define ChannelBlend_PinLight(B,L) ((uint8)(L < 128)?ChannelBlend_Darken(B,(2 * L)):ChannelBlend_Lighten(B,(2 * (L - 128)))) +#define ChannelBlend_HardMix(B,L) ((uint8)((ChannelBlend_VividLight(B,L) < 128) ? 0:255)) +#define ChannelBlend_Reflect(B,L) ((uint8)((L == 255) ? L:min(255, (B * B / (255 - L))))) +#define ChannelBlend_Glow(B,L) (ChannelBlend_Reflect(L,B)) +#define ChannelBlend_Phoenix(B,L) ((uint8)(min(B,L) - max(B,L) + 255)) +#define ChannelBlend_Alpha(B,L,O) ((uint8)(O * B + (1 - O) * L)) +#define ChannelBlend_AlphaF(B,L,F,O) (ChannelBlend_Alpha(F(B,L),B,O)) + + +#pragma endregion + +#if AGS_PLATFORM_OS_WINDOWS +// The standard Windows DLL entry point + +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) { + + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +//define engine + +IAGSEngine *engine; + + +#pragma region Color_Functions + + +int getr32(int c) { + return ((c >> DEFAULT_RGB_R_SHIFT_32) & 0xFF); +} + + +int getg32(int c) { + return ((c >> DEFAULT_RGB_G_SHIFT_32) & 0xFF); +} + + +int getb32(int c) { + return ((c >> DEFAULT_RGB_B_SHIFT_32) & 0xFF); +} + + +int geta32(int c) { + return ((c >> DEFAULT_RGB_A_SHIFT_32) & 0xFF); +} + + +int makeacol32(int r, int g, int b, int a) { + return ((r << DEFAULT_RGB_R_SHIFT_32) | + (g << DEFAULT_RGB_G_SHIFT_32) | + (b << DEFAULT_RGB_B_SHIFT_32) | + (a << DEFAULT_RGB_A_SHIFT_32)); +} + +#pragma endregion + +#pragma region Pixel32_Definition + +struct Pixel32 { + +public: + Pixel32(); + ~Pixel32() = default; + int GetColorAsInt(); + int Red; + int Green; + int Blue; + int Alpha; + +}; + +Pixel32::Pixel32() { + Red = 0; + Blue = 0; + Green = 0; + Alpha = 0; +} + +int Pixel32::GetColorAsInt() { + + return makeacol32(Red, Green, Blue, Alpha); + +} + +#pragma endregion + +/// +/// Gets the alpha value at coords x,y +/// +int GetAlpha(int sprite, int x, int y) { + + + BITMAP *engineSprite = engine->GetSpriteGraphic(sprite); + + unsigned char **charbuffer = engine->GetRawBitmapSurface(engineSprite); + unsigned int **longbuffer = (unsigned int **)charbuffer; + + int alpha = geta32(longbuffer[y][x]); + + engine->ReleaseBitmapSurface(engineSprite); + + return alpha; + +} + +/// +/// Sets the alpha value at coords x,y +/// +int PutAlpha(int sprite, int x, int y, int alpha) { + + BITMAP *engineSprite = engine->GetSpriteGraphic(sprite); + + unsigned char **charbuffer = engine->GetRawBitmapSurface(engineSprite); + unsigned int **longbuffer = (unsigned int **)charbuffer; + + + int r = getr32(longbuffer[y][x]); + int g = getg32(longbuffer[y][x]); + int b = getb32(longbuffer[y][x]); + longbuffer[y][x] = makeacol32(r, g, b, alpha); + + engine->ReleaseBitmapSurface(engineSprite); + + return alpha; + +} + + +/// +/// Translates index from a 2D array to a 1D array +/// +int xytolocale(int x, int y, int width) { + + return (y * width + x); + + +} + +int HighPass(int sprite, int threshold) { + + BITMAP *src = engine->GetSpriteGraphic(sprite); + int srcWidth, srcHeight; + + engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + + unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; + + for (int y = 0; y < srcHeight; y++) { + + for (int x = 0; x < srcWidth; x++) { + + int srcr = getb32(srclongbuffer[y][x]); + int srcg = getg32(srclongbuffer[y][x]); + int srcb = getr32(srclongbuffer[y][x]); + int tempmaxim = max(srcr, srcg); + int maxim = max(tempmaxim, srcb); + int tempmin = min(srcr, srcg); + int minim = min(srcb, tempmin); + int light = (maxim + minim) / 2 ; + if (light < threshold) srclongbuffer[y][x] = makeacol32(0, 0, 0, 0); + + } + + } + + return 0; + +} + + +int Blur(int sprite, int radius) { + + BITMAP *src = engine->GetSpriteGraphic(sprite); + + int srcWidth, srcHeight; + engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + + unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; + int negrad = -1 * radius; + + //use a 1Dimensional array since the array is on the free store, not the stack + Pixel32 *Pixels = new Pixel32[(srcWidth + (radius * 2)) * (srcHeight + (radius * 2))]; // this defines a copy of the individual channels in class form. + Pixel32 *Dest = new Pixel32[(srcWidth + (radius * 2)) * (srcHeight + (radius * 2))]; // this is the destination sprite. both have a border all the way round equal to the radius for the blurring. + Pixel32 *Temp = new Pixel32[(srcWidth + (radius * 2)) * (srcHeight + (radius * 2))]; + + + int arraywidth = srcWidth + (radius * 2); //define the array width since its used many times in the algorithm + + + for (int y = 0; y < srcHeight; y++) { //copy the sprite to the Pixels class array + + for (int x = 0; x < srcWidth; x++) { + + int locale = xytolocale(x + radius, y + radius, arraywidth); + + Pixels[locale].Red = getr32(srclongbuffer[y][x]); + Pixels[locale].Green = getg32(srclongbuffer[y][x]); + Pixels[locale].Blue = getb32(srclongbuffer[y][x]); + Pixels[locale].Alpha = geta32(srclongbuffer[y][x]); + + + + } + + } + + + int numofpixels = (radius * 2 + 1); + for (int y = 0; y < srcHeight; y++) { + + int totalr = 0; + int totalg = 0; + int totalb = 0; + int totala = 0; + + // Process entire window for first pixel + for (int kx = negrad; kx <= radius; kx++) { + int locale = xytolocale(kx + radius, y + radius, arraywidth); + totala += Pixels[locale].Alpha; + totalr += (Pixels[locale].Red * Pixels[locale].Alpha) / 255; + totalg += (Pixels[locale].Green * Pixels[locale].Alpha) / 255; + totalb += (Pixels[locale].Blue * Pixels[locale].Alpha) / 255; + } + + int locale = xytolocale(radius, y + radius, arraywidth); + Temp[locale].Red = totalr / numofpixels; // take an average and assign it to the destination array + Temp[locale].Green = totalg / numofpixels; + Temp[locale].Blue = totalb / numofpixels; + Temp[locale].Alpha = totala / numofpixels; + + + // Subsequent pixels just update window total + for (int x = 1; x < srcWidth; x++) { + // Subtract pixel leaving window + int locale = xytolocale(x - 1, y + radius, arraywidth); + totala -= Pixels[locale].Alpha; + totalr -= (Pixels[locale].Red * Pixels[locale].Alpha) / 255; + totalg -= (Pixels[locale].Green * Pixels[locale].Alpha) / 255; + totalb -= (Pixels[locale].Blue * Pixels[locale].Alpha) / 255; + + + // Add pixel entering window + + locale = xytolocale(x + radius + radius, y + radius, arraywidth); + totala += Pixels[locale].Alpha; + totalr += (Pixels[locale].Red * Pixels[locale].Alpha) / 255; + totalg += (Pixels[locale].Green * Pixels[locale].Alpha) / 255; + totalb += (Pixels[locale].Blue * Pixels[locale].Alpha) / 255; + + + locale = xytolocale(x + radius, y + radius, arraywidth); + Temp[locale].Red = totalr / numofpixels; // take an average and assign it to the destination array + Temp[locale].Green = totalg / numofpixels; + Temp[locale].Blue = totalb / numofpixels; + Temp[locale].Alpha = totala / numofpixels; + + } + } + + + + + for (int x = 0; x < srcWidth; x++) { + + int totalr = 0; + int totalg = 0; + int totalb = 0; + int totala = 0; + + // Process entire window for first pixel + for (int ky = negrad; ky <= radius; ky++) { + int locale = xytolocale(x + radius, ky + radius, arraywidth); + totala += Temp[locale].Alpha; + totalr += (Temp[locale].Red * Temp[locale].Alpha) / 255; + totalg += (Temp[locale].Green * Temp[locale].Alpha) / 255; + totalb += (Temp[locale].Blue * Temp[locale].Alpha) / 255; + } + + int locale = xytolocale(x + radius, radius, arraywidth); + Dest[locale].Red = totalr / numofpixels; // take an average and assign it to the destination array + Dest[locale].Green = totalg / numofpixels; + Dest[locale].Blue = totalb / numofpixels; + Dest[locale].Alpha = totala / numofpixels; + + + // Subsequent pixels just update window total + for (int y = 1; y < srcHeight; y++) { + // Subtract pixel leaving window + int locale = xytolocale(x + radius, y - 1, arraywidth); + totala -= Temp[locale].Alpha; + totalr -= (Temp[locale].Red * Temp[locale].Alpha) / 255; + totalg -= (Temp[locale].Green * Temp[locale].Alpha) / 255; + totalb -= (Temp[locale].Blue * Temp[locale].Alpha) / 255; + + + // Add pixel entering window + + locale = xytolocale(x + radius, y + radius + radius, arraywidth); + totala += Temp[locale].Alpha; + totalr += (Temp[locale].Red * Temp[locale].Alpha) / 255; + totalg += (Temp[locale].Green * Temp[locale].Alpha) / 255; + totalb += (Temp[locale].Blue * Temp[locale].Alpha) / 255; + + + locale = xytolocale(x + radius, y + radius, arraywidth); + Dest[locale].Red = totalr / numofpixels; // take an average and assign it to the destination array + Dest[locale].Green = totalg / numofpixels; + Dest[locale].Blue = totalb / numofpixels; + Dest[locale].Alpha = totala / numofpixels; + + } + } + + + + for (int y = 0; y < srcHeight; y++) { + + for (int x = 0; x < srcWidth; x++) { + int locale = xytolocale(x + radius, y + radius, arraywidth); + srclongbuffer[y][x] = Dest[locale].GetColorAsInt(); //write the destination array to the main buffer + + } + + } + delete [] Pixels; + delete [] Dest; + delete [] Temp; + engine->ReleaseBitmapSurface(src); + delete srclongbuffer; + delete srccharbuffer; + return 0; +} + +int Clamp(int val, int min, int max) { + + if (val < min) return min; + else if (val > max) return max; + else return val; + +} + +int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int trans) { + + trans = 100 - trans; + int srcWidth, srcHeight, destWidth, destHeight; + + BITMAP *src = engine->GetSpriteGraphic(sprite); + BITMAP *dest = engine->GetSpriteGraphic(destination); + + engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); + + if (x > destWidth || y > destHeight || x + srcWidth < 0 || y + srcHeight < 0) return 1; // offscreen + + unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; + + unsigned char **destcharbuffer = engine->GetRawBitmapSurface(dest); + unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; + + + + if (srcWidth + x > destWidth) srcWidth = destWidth - x - 1; + if (srcHeight + y > destHeight) srcHeight = destHeight - y - 1; + + int destx, desty; + int srcr, srcg, srcb, srca, destr, destg, destb, desta, finalr, finalg, finalb, finala; + unsigned int col; + int starty = 0; + int startx = 0; + + if (x < 0) startx = -1 * x; + if (y < 0) starty = -1 * y; + + int ycount = 0; + int xcount = 0; + for (ycount = starty; ycount < srcHeight; ycount ++) { + + for (xcount = startx; xcount < srcWidth; xcount ++) { + + destx = xcount + x; + desty = ycount + y; + + srca = (geta32(srclongbuffer[ycount][xcount])); + + if (srca != 0) { + srca = srca * trans / 100; + srcr = getr32(srclongbuffer[ycount][xcount]); + srcg = getg32(srclongbuffer[ycount][xcount]); + srcb = getb32(srclongbuffer[ycount][xcount]); + + destr = getr32(destlongbuffer[desty][destx]); + destg = getg32(destlongbuffer[desty][destx]); + destb = getb32(destlongbuffer[desty][destx]); + desta = geta32(destlongbuffer[desty][destx]); + + + + + switch (DrawMode) { + + case 0: + + finalr = srcr; + finalg = srcg; + finalb = srcb; + break; + + case 1: + + finalr = ChannelBlend_Lighten(srcr, destr); + finalg = ChannelBlend_Lighten(srcg, destg); + finalb = ChannelBlend_Lighten(srcb, destb); + break; + + case 2: + + + finalr = ChannelBlend_Darken(srcr, destr); + finalg = ChannelBlend_Darken(srcg, destg); + finalb = ChannelBlend_Darken(srcb, destb); + break; + + case 3: + + + finalr = ChannelBlend_Multiply(srcr, destr); + finalg = ChannelBlend_Multiply(srcg, destg); + finalb = ChannelBlend_Multiply(srcb, destb); + break; + + case 4: + + + finalr = ChannelBlend_Add(srcr, destr); + finalg = ChannelBlend_Add(srcg, destg); + finalb = ChannelBlend_Add(srcb, destb); + break; + + case 5: + + + finalr = ChannelBlend_Subtract(srcr, destr); + finalg = ChannelBlend_Subtract(srcg, destg); + finalb = ChannelBlend_Subtract(srcb, destb); + break; + + case 6: + + + finalr = ChannelBlend_Difference(srcr, destr); + finalg = ChannelBlend_Difference(srcg, destg); + finalb = ChannelBlend_Difference(srcb, destb); + break; + + case 7: + + + finalr = ChannelBlend_Negation(srcr, destr); + finalg = ChannelBlend_Negation(srcg, destg); + finalb = ChannelBlend_Negation(srcb, destb); + break; + + case 8: + + + finalr = ChannelBlend_Screen(srcr, destr); + finalg = ChannelBlend_Screen(srcg, destg); + finalb = ChannelBlend_Screen(srcb, destb); + break; + + + case 9: + + + finalr = ChannelBlend_Exclusion(srcr, destr); + finalg = ChannelBlend_Exclusion(srcg, destg); + finalb = ChannelBlend_Exclusion(srcb, destb); + break; + + + case 10: + + + finalr = ChannelBlend_Overlay(srcr, destr); + finalg = ChannelBlend_Overlay(srcg, destg); + finalb = ChannelBlend_Overlay(srcb, destb); + break; + + + case 11: + + + finalr = ChannelBlend_SoftLight(srcr, destr); + finalg = ChannelBlend_SoftLight(srcg, destg); + finalb = ChannelBlend_SoftLight(srcb, destb); + break; + + case 12: + + + finalr = ChannelBlend_HardLight(srcr, destr); + finalg = ChannelBlend_HardLight(srcg, destg); + finalb = ChannelBlend_HardLight(srcb, destb); + break; + + case 13: + + + finalr = ChannelBlend_ColorDodge(srcr, destr); + finalg = ChannelBlend_ColorDodge(srcg, destg); + finalb = ChannelBlend_ColorDodge(srcb, destb); + break; + + case 14: + + + finalr = ChannelBlend_ColorBurn(srcr, destr); + finalg = ChannelBlend_ColorBurn(srcg, destg); + finalb = ChannelBlend_ColorBurn(srcb, destb); + break; + + case 15: + + + finalr = ChannelBlend_LinearDodge(srcr, destr); + finalg = ChannelBlend_LinearDodge(srcg, destg); + finalb = ChannelBlend_LinearDodge(srcb, destb); + break; + + case 16: + + + finalr = ChannelBlend_LinearBurn(srcr, destr); + finalg = ChannelBlend_LinearBurn(srcg, destg); + finalb = ChannelBlend_LinearBurn(srcb, destb); + break; + + + + case 17: + + + finalr = ChannelBlend_LinearLight(srcr, destr); + finalg = ChannelBlend_LinearLight(srcg, destg); + finalb = ChannelBlend_LinearLight(srcb, destb); + break; + + + + case 18: + + + finalr = ChannelBlend_VividLight(srcr, destr); + finalg = ChannelBlend_VividLight(srcg, destg); + finalb = ChannelBlend_VividLight(srcb, destb); + break; + + case 19: + + + finalr = ChannelBlend_PinLight(srcr, destr); + finalg = ChannelBlend_PinLight(srcg, destg); + finalb = ChannelBlend_PinLight(srcb, destb); + break; + + case 20: + + + finalr = ChannelBlend_HardMix(srcr, destr); + finalg = ChannelBlend_HardMix(srcg, destg); + finalb = ChannelBlend_HardMix(srcb, destb); + break; + + case 21: + + + finalr = ChannelBlend_Reflect(srcr, destr); + finalg = ChannelBlend_Reflect(srcg, destg); + finalb = ChannelBlend_Reflect(srcb, destb); + break; + + case 22: + + + finalr = ChannelBlend_Glow(srcr, destr); + finalg = ChannelBlend_Glow(srcg, destg); + finalb = ChannelBlend_Glow(srcb, destb); + break; + + case 23: + + + finalr = ChannelBlend_Phoenix(srcr, destr); + finalg = ChannelBlend_Phoenix(srcg, destg); + finalb = ChannelBlend_Phoenix(srcb, destb); + break; + + } + + finala = 255 - (255 - srca) * (255 - desta) / 255; + finalr = srca * finalr / finala + desta * destr * (255 - srca) / finala / 255; + finalg = srca * finalg / finala + desta * destg * (255 - srca) / finala / 255; + finalb = srca * finalb / finala + desta * destb * (255 - srca) / finala / 255; + col = makeacol32(finalr, finalg, finalb, finala); + destlongbuffer[desty][destx] = col; + + } + + + } + + } + + engine->ReleaseBitmapSurface(src); + engine->ReleaseBitmapSurface(dest); + engine->NotifySpriteUpdated(destination); + return 0; + +} + + +int DrawAdd(int destination, int sprite, int x, int y, float scale) { + + + int srcWidth, srcHeight, destWidth, destHeight; + + BITMAP *src = engine->GetSpriteGraphic(sprite); + BITMAP *dest = engine->GetSpriteGraphic(destination); + + engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); + + if (x > destWidth || y > destHeight) return 1; // offscreen + + unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; + + unsigned char **destcharbuffer = engine->GetRawBitmapSurface(dest); + unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; + + if (srcWidth + x > destWidth) srcWidth = destWidth - x - 1; + if (srcHeight + y > destHeight) srcHeight = destHeight - y - 1; + + int destx, desty; + int srcr, srcg, srcb, srca, destr, destg, destb, desta, finalr, finalg, finalb, finala; + unsigned int col; + int ycount = 0; + int xcount = 0; + + int starty = 0; + int startx = 0; + + if (x < 0) startx = -1 * x; + if (y < 0) starty = -1 * y; + + + + for (ycount = starty; ycount < srcHeight; ycount ++) { + + for (xcount = startx; xcount < srcWidth; xcount ++) { + + destx = xcount + x; + desty = ycount + y; + + srca = (geta32(srclongbuffer[ycount][xcount])); + + if (srca != 0) { + + + srcr = getr32(srclongbuffer[ycount][xcount]) * srca / 255 * scale; + srcg = getg32(srclongbuffer[ycount][xcount]) * srca / 255 * scale; + srcb = getb32(srclongbuffer[ycount][xcount]) * srca / 255 * scale; + desta = geta32(destlongbuffer[desty][destx]); + + if (desta == 0) { + destr = 0; + destg = 0; + destb = 0; + + } else { + destr = getr32(destlongbuffer[desty][destx]); + destg = getg32(destlongbuffer[desty][destx]); + destb = getb32(destlongbuffer[desty][destx]); + } + + finala = 255 - (255 - srca) * (255 - desta) / 255; + finalr = Clamp(srcr + destr, 0, 255); + finalg = Clamp(srcg + destg, 0, 255); + finalb = Clamp(srcb + destb, 0, 255); + col = makeacol32(finalr, finalg, finalb, finala); + destlongbuffer[desty][destx] = col; + + } + + } + + } + + engine->ReleaseBitmapSurface(src); + engine->ReleaseBitmapSurface(dest); + engine->NotifySpriteUpdated(destination); + return 0; + + + +} + + + +int DrawAlpha(int destination, int sprite, int x, int y, int trans) { + + trans = 100 - trans; + + int srcWidth, srcHeight, destWidth, destHeight; + + BITMAP *src = engine->GetSpriteGraphic(sprite); + BITMAP *dest = engine->GetSpriteGraphic(destination); + + engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); + + if (x > destWidth || y > destHeight) return 1; // offscreen + + unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; + + unsigned char **destcharbuffer = engine->GetRawBitmapSurface(dest); + unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; + + if (srcWidth + x > destWidth) srcWidth = destWidth - x - 1; + if (srcHeight + y > destHeight) srcHeight = destHeight - y - 1; + + int destx, desty; + int srcr, srcg, srcb, srca, destr, destg, destb, desta, finalr, finalg, finalb, finala; + + int ycount = 0; + int xcount = 0; + + int starty = 0; + int startx = 0; + + if (x < 0) startx = -1 * x; + if (y < 0) starty = -1 * y; + + + for (ycount = starty; ycount < srcHeight; ycount ++) { + + for (xcount = startx; xcount < srcWidth; xcount ++) { + + destx = xcount + x; + desty = ycount + y; + + srca = (geta32(srclongbuffer[ycount][xcount])) * trans / 100; + + if (srca != 0) { + + srcr = getr32(srclongbuffer[ycount][xcount]); + srcg = getg32(srclongbuffer[ycount][xcount]); + srcb = getb32(srclongbuffer[ycount][xcount]); + + destr = getr32(destlongbuffer[desty][destx]); + destg = getg32(destlongbuffer[desty][destx]); + destb = getb32(destlongbuffer[desty][destx]); + desta = geta32(destlongbuffer[desty][destx]); + + finala = 255 - (255 - srca) * (255 - desta) / 255; + finalr = srca * srcr / finala + desta * destr * (255 - srca) / finala / 255; + finalg = srca * srcg / finala + desta * destg * (255 - srca) / finala / 255; + finalb = srca * srcb / finala + desta * destb * (255 - srca) / finala / 255; + + destlongbuffer[desty][destx] = makeacol32(finalr, finalg, finalb, finala); + + } + + } + + } + + engine->ReleaseBitmapSurface(src); + engine->ReleaseBitmapSurface(dest); + engine->NotifySpriteUpdated(destination); + + return 0; +} + + +#if AGS_PLATFORM_OS_WINDOWS + +//============================================================================== + +// ***** Design time ***** + +IAGSEditor *editor; // Editor interface + +const char *ourScriptHeader = + "import int DrawAlpha(int destination, int sprite, int x, int y, int transparency);\r\n" + "import int GetAlpha(int sprite, int x, int y);\r\n" + "import int PutAlpha(int sprite, int x, int y, int alpha);\r\n" + "import int Blur(int sprite, int radius);\r\n" + "import int HighPass(int sprite, int threshold);\r\n" + "import int DrawAdd(int destination, int sprite, int x, int y, float scale);\r\n" + "import int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int trans);"; + + + + +//------------------------------------------------------------------------------ + +LPCSTR AGS_GetPluginName() { + return ("AGSBlend"); +} + +//------------------------------------------------------------------------------ + +int AGS_EditorStartup(IAGSEditor *lpEditor) { + // User has checked the plugin to use it in their game + + // If it's an earlier version than what we need, abort. + if (lpEditor->version < MIN_EDITOR_VERSION) + return (-1); + + editor = lpEditor; + editor->RegisterScriptHeader(ourScriptHeader); + + // Return 0 to indicate success + return (0); +} + +//------------------------------------------------------------------------------ + +void AGS_EditorShutdown() { + // User has un-checked the plugin from their game + editor->UnregisterScriptHeader(ourScriptHeader); +} + +//------------------------------------------------------------------------------ + +void AGS_EditorProperties(HWND parent) { //*** optional *** + // User has chosen to view the Properties of the plugin + // We could load up an options dialog or something here instead + /* MessageBox(parent, + L"AGSBlend v1.0 By Calin Leafshade", + L"About", + MB_OK | MB_ICONINFORMATION); + */ +} + +//------------------------------------------------------------------------------ + +int AGS_EditorSaveGame(char *buffer, int bufsize) { //*** optional *** + // Called by the editor when the current game is saved to disk. + // Plugin configuration can be stored in [buffer] (max [bufsize] bytes) + // Return the amount of bytes written in the buffer + return (0); +} + +//------------------------------------------------------------------------------ + +void AGS_EditorLoadGame(char *buffer, int bufsize) { //*** optional *** + // Called by the editor when a game is loaded from disk + // Previous written data can be read from [buffer] (size [bufsize]). + // Make a copy of the data, the buffer is freed after this function call. +} + +//============================================================================== + +#endif + +// ***** Run time ***** + +// Engine interface + +//------------------------------------------------------------------------------ + +#define REGISTER(x) engine->RegisterScriptFunction(#x, (void *) (x)); +#define STRINGIFY(s) STRINGIFY_X(s) +#define STRINGIFY_X(s) #s + +void AGS_EngineStartup(IAGSEngine *lpEngine) { + engine = lpEngine; + + // Make sure it's got the version with the features we need + if (engine->version < MIN_ENGINE_VERSION) + engine->AbortGame("Plugin needs engine version " STRINGIFY(MIN_ENGINE_VERSION) " or newer."); + + //register functions + + REGISTER(GetAlpha) + REGISTER(PutAlpha) + REGISTER(DrawAlpha) + REGISTER(Blur) + REGISTER(HighPass) + REGISTER(DrawAdd) + REGISTER(DrawSprite) + + +} + +//------------------------------------------------------------------------------ + +void AGS_EngineShutdown() { + // Called by the game engine just before it exits. + // This gives you a chance to free any memory and do any cleanup + // that you need to do before the engine shuts down. +} + +//------------------------------------------------------------------------------ + +int AGS_EngineOnEvent(int event, int data) { //*** optional *** + switch (event) { + /* + case AGSE_KEYPRESS: + case AGSE_MOUSECLICK: + case AGSE_POSTSCREENDRAW: + case AGSE_PRESCREENDRAW: + case AGSE_SAVEGAME: + case AGSE_RESTOREGAME: + case AGSE_PREGUIDRAW: + case AGSE_LEAVEROOM: + case AGSE_ENTERROOM: + case AGSE_TRANSITIONIN: + case AGSE_TRANSITIONOUT: + case AGSE_FINALSCREENDRAW: + case AGSE_TRANSLATETEXT: + case AGSE_SCRIPTDEBUG: + case AGSE_SPRITELOAD: + case AGSE_PRERENDER: + case AGSE_PRESAVEGAME: + case AGSE_POSTRESTOREGAME: + */ + default: + break; + } + + // Return 1 to stop event from processing further (when needed) + return (0); +} + +//------------------------------------------------------------------------------ + +int AGS_EngineDebugHook(const char *scriptName, + int lineNum, int reserved) { //*** optional *** + // Can be used to debug scripts, see documentation + return 0; +} + +//------------------------------------------------------------------------------ + +void AGS_EngineInitGfx(const char *driverID, void *data) { //*** optional *** + // This allows you to make changes to how the graphics driver starts up. + // See documentation +} + +//.............................................................................. + + +#if defined(BUILTIN_PLUGINS) +} +#endif diff --git a/engines/ags/plugins/ags_blend/ags_blend.h b/engines/ags/plugins/ags_blend/ags_blend.h new file mode 100644 index 000000000000..c09349c9f11d --- /dev/null +++ b/engines/ags/plugins/ags_blend/ags_blend.h @@ -0,0 +1,14 @@ +#ifndef AGS_BLEND_H +#define AGS_BLEND_H + +#include "plugin/agsplugin.h" + +namespace agsblend { +void AGS_EngineStartup(IAGSEngine *lpEngine); +void AGS_EngineShutdown(); +int AGS_EngineOnEvent(int event, int data); +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); +void AGS_EngineInitGfx(const char *driverID, void *data); +} + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/agscreditz/agscreditz.cpp b/engines/ags/plugins/ags_creditz/ags_creditz.cpp similarity index 99% rename from engines/ags/plugins/agscreditz/agscreditz.cpp rename to engines/ags/plugins/ags_creditz/ags_creditz.cpp index d77763ae801e..3e350d820b53 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.cpp +++ b/engines/ags/plugins/ags_creditz/ags_creditz.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/plugins/AGSCreditz/AGSCreditz.h" +#include "ags/plugins/ags_creditz/ags_creditz.h" namespace AGS3 { namespace Plugins { diff --git a/engines/ags/plugins/agscreditz/agscreditz.h b/engines/ags/plugins/ags_creditz/ags_creditz.h similarity index 99% rename from engines/ags/plugins/agscreditz/agscreditz.h rename to engines/ags/plugins/ags_creditz/ags_creditz.h index ab93f88a13eb..14f7ed67badf 100644 --- a/engines/ags/plugins/agscreditz/agscreditz.h +++ b/engines/ags/plugins/ags_creditz/ags_creditz.h @@ -119,7 +119,7 @@ class AGSCreditz : public DLL { static const char *AGS_GetPluginName(); static void AGS_EngineStartup(IAGSEngine *engine); - // Shared Script methods + // Shared Script methods static void ScrollCredits(const ScriptMethodParams ¶ms); static string GetCredit(const ScriptMethodParams ¶ms); static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp new file mode 100644 index 000000000000..663e81c1b180 --- /dev/null +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp @@ -0,0 +1,829 @@ +/* + +This is not the AGS Flashlight plugin, +but a workalike plugin created by JJS for the AGS engine PSP port. + +*/ + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#pragma warning(disable : 4244) +#endif + +#if !defined(BUILTIN_PLUGINS) +#define THIS_IS_THE_PLUGIN +#endif + +#include +#include +#include +#include + +#if defined(PSP_VERSION) +#include +#include +#include +#define sin(x) vfpu_sinf(x) +#endif + +#include "plugin/agsplugin.h" + +#if defined(BUILTIN_PLUGINS) +namespace agsflashlight { +#endif + +#if defined(__GNUC__) +inline unsigned long _blender_alpha16_bgr(unsigned long y) __attribute__((always_inline)); +inline void calc_x_n(unsigned long bla) __attribute__((always_inline)); +#endif + +const unsigned int Magic = 0xBABE0000; +const unsigned int Version = 2; +const unsigned int SaveMagic = Magic + Version; +const float PI = 3.14159265f; + +int screen_width = 320; +int screen_height = 200; +int screen_color_depth = 16; + +IAGSEngine *engine; + +bool g_BitmapMustBeUpdated = true; + +int g_RedTint = 0; +int g_GreenTint = 0; +int g_BlueTint = 0; + +int g_DarknessLightLevel = 100; +int g_BrightnessLightLevel = 100; +int g_DarknessSize = 0; +int g_DarknessDiameter = 0; +int g_BrightnessSize = 0; + +int g_FlashlightX = 0; +int g_FlashlightY = 0; +int g_FlashlightDrawAtX = 0; +int g_FlashlightDrawAtY = 0; + +bool g_FlashlightFollowMouse = false; + +int g_FollowCharacterId = 0; +int g_FollowCharacterDx = 0; +int g_FollowCharacterDy = 0; +int g_FollowCharacterHorz = 0; +int g_FollowCharacterVert = 0; + +AGSCharacter *g_FollowCharacter = nullptr; + +BITMAP *g_LightBitmap = nullptr; + + +// This function is from Allegro, split for more performance. + +/* _blender_alpha16_bgr + * Combines a 32 bit RGBA sprite with a 16 bit RGB destination, optimised + * for when one pixel is in an RGB layout and the other is BGR. + */ + +unsigned long x, n; + +inline void calc_x_n(unsigned long _x) { + x = _x; + + n = x >> 24; + + if (n) + n = (n + 1) / 8; + + x = ((x >> 19) & 0x001F) | ((x >> 5) & 0x07E0) | ((x << 8) & 0xF800); + + x = (x | (x << 16)) & 0x7E0F81F; +} + + +inline unsigned long _blender_alpha16_bgr(unsigned long y) { + unsigned long result; + + y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F; + + result = ((x - y) * n / 32 + y) & 0x7E0F81F; + + return ((result & 0xFFFF) | (result >> 16)); +} + + + +inline void setPixel(int x, int y, int color, unsigned int *pixel) { + if ((x >= g_DarknessDiameter) || (y >= g_DarknessDiameter) || (x < 0) || (y < 0)) + return; + + *(pixel + (y * g_DarknessDiameter) + x) = color; +} + + +void plotCircle(int xm, int ym, int r, unsigned int color) { + unsigned int *pixel = *(unsigned int **)engine->GetRawBitmapSurface(g_LightBitmap); + + int x = -r; + int y = 0; + int err = 2 - 2 * r; + + do { + setPixel(xm - x, ym + y, color, pixel); // I. Quadrant + setPixel(xm - x - 1, ym + y, color, pixel); + + setPixel(xm - y, ym - x, color, pixel); // II. Quadrant + setPixel(xm - y, ym - x - 1, color, pixel); + + setPixel(xm + x, ym - y, color, pixel); // III. Quadrant + setPixel(xm + x + 1, ym - y, color, pixel); + + setPixel(xm + y, ym + x, color, pixel); // IV. Quadrant + setPixel(xm + y, ym + x + 1, color, pixel); + + r = err; + if (r > x) + err += ++x * 2 + 1; + + if (r <= y) + err += ++y * 2 + 1; + } while (x < 0); + + engine->ReleaseBitmapSurface(g_LightBitmap); +} + + +void ClipToRange(int &variable, int min, int max) { + if (variable < min) + variable = min; + + if (variable > max) + variable = max; +} + + +void AlphaBlendBitmap() { + unsigned short *destpixel = *(unsigned short **)engine->GetRawBitmapSurface(engine->GetVirtualScreen()); + unsigned int *sourcepixel = *(unsigned int **)engine->GetRawBitmapSurface(g_LightBitmap); + + unsigned short *currentdestpixel = destpixel; + unsigned int *currentsourcepixel = sourcepixel; + + int x, y; + + int targetX = (g_FlashlightDrawAtX > -1) ? g_FlashlightDrawAtX : 0; + int targetY = (g_FlashlightDrawAtY > -1) ? g_FlashlightDrawAtY : 0; + + int startX = (g_FlashlightDrawAtX < 0) ? -1 * g_FlashlightDrawAtX : 0; + int endX = (g_FlashlightDrawAtX + g_DarknessDiameter < screen_width) ? g_DarknessDiameter : g_DarknessDiameter - ((g_FlashlightDrawAtX + g_DarknessDiameter) - screen_width); + + int startY = (g_FlashlightDrawAtY < 0) ? -1 * g_FlashlightDrawAtY : 0; + int endY = (g_FlashlightDrawAtY + g_DarknessDiameter < screen_height) ? g_DarknessDiameter : g_DarknessDiameter - ((g_FlashlightDrawAtY + g_DarknessDiameter) - screen_height); + + for (y = 0; y < endY - startY; y++) { + currentdestpixel = destpixel + (y + targetY) * screen_width + targetX; + currentsourcepixel = sourcepixel + (y + startY) * g_DarknessDiameter + startX; + + for (x = 0; x < endX - startX; x++) { + calc_x_n(*currentsourcepixel); + *currentdestpixel = (unsigned short)_blender_alpha16_bgr(*currentdestpixel); + + currentdestpixel++; + currentsourcepixel++; + } + } + + engine->ReleaseBitmapSurface(engine->GetVirtualScreen()); + engine->ReleaseBitmapSurface(g_LightBitmap); +} + + +void DrawTint() { + int x, y; + BITMAP *screen = engine->GetVirtualScreen(); + unsigned short *destpixel = *(unsigned short **)engine->GetRawBitmapSurface(screen); + + int32 red, blue, green, alpha; + + for (y = 0; y < screen_height; y++) { + for (x = 0; x < screen_width; x++) { + engine->GetRawColorComponents(16, *destpixel, &red, &green, &blue, &alpha); + + if (g_RedTint != 0) { + red += g_RedTint * 8; + if (red > 255) + red = 255; + else if (red < 0) + red = 0; + } + + if (g_BlueTint != 0) { + blue += g_BlueTint * 8; + if (blue > 255) + blue = 255; + else if (blue < 0) + blue = 0; + } + + if (g_GreenTint != 0) { + green += g_GreenTint * 8; + if (green > 255) + green = 255; + else if (green < 0) + green = 0; + } + + *destpixel = engine->MakeRawColorPixel(16, red, green, blue, alpha); + destpixel++; + } + } + + engine->ReleaseBitmapSurface(screen); +} + + +void DrawDarkness() { + int x, y; + unsigned int color = (255 - (int)((float)g_DarknessLightLevel * 2.55f)) << 24; + BITMAP *screen = engine->GetVirtualScreen(); + unsigned short *destpixel = *(unsigned short **)engine->GetRawBitmapSurface(screen); + unsigned short *currentpixel; + + calc_x_n(color); + + if (g_DarknessSize == 0) { + // Whole screen. + for (x = 0; x < screen_width * screen_height; x++) { + *destpixel = (unsigned short)_blender_alpha16_bgr(*destpixel); + destpixel++; + } + } else { + // Top. + if (g_FlashlightDrawAtY > -1) { + currentpixel = destpixel; + for (y = 0; y < g_FlashlightDrawAtY; y++) { + for (x = 0; x < screen_width; x++) { + *currentpixel = (unsigned short)_blender_alpha16_bgr(*currentpixel); + currentpixel++; + } + } + } + + // Bottom. + if (g_FlashlightDrawAtY + g_DarknessDiameter < screen_height) { + currentpixel = destpixel + (g_FlashlightDrawAtY + g_DarknessDiameter) * screen_width; + for (y = g_FlashlightDrawAtY + g_DarknessDiameter; y < screen_height; y++) { + for (x = 0; x < screen_width; x++) { + *currentpixel = (unsigned short)_blender_alpha16_bgr(*currentpixel); + currentpixel++; + } + } + } + + // Left. + if (g_FlashlightDrawAtX > 0) { + currentpixel = destpixel; + int startpoint = (g_FlashlightDrawAtY > 0) ? g_FlashlightDrawAtY : 0; + int endpoint = (g_FlashlightDrawAtY + g_DarknessDiameter >= screen_height) ? screen_height + 1 : g_FlashlightDrawAtY + g_DarknessDiameter + 1; + for (y = startpoint; y < endpoint; y++) { + for (x = 0; x < g_FlashlightDrawAtX; x++) { + *currentpixel = (unsigned short)_blender_alpha16_bgr(*currentpixel); + currentpixel++; + } + + currentpixel = destpixel + screen_width * y; + } + } + + // Right. + if (g_FlashlightDrawAtX + g_DarknessDiameter < screen_width) { + currentpixel = destpixel + (g_FlashlightDrawAtX + g_DarknessDiameter); + int startpoint = (g_FlashlightDrawAtY > 0) ? g_FlashlightDrawAtY : 0; + int endpoint = (g_FlashlightDrawAtY + g_DarknessDiameter >= screen_height) ? screen_height + 1 : g_FlashlightDrawAtY + g_DarknessDiameter + 1; + for (y = startpoint; y < endpoint; y++) { + for (x = g_FlashlightDrawAtX + g_DarknessDiameter; x < screen_width; x++) { + *currentpixel = (unsigned short)_blender_alpha16_bgr(*currentpixel); + currentpixel++; + } + + currentpixel = destpixel + screen_width * y + (g_FlashlightDrawAtX + g_DarknessDiameter); + } + } + } + + engine->ReleaseBitmapSurface(screen); +} + + +void CreateLightBitmap() { + if (g_DarknessSize == 0) + return; + + if (g_LightBitmap) + engine->FreeBitmap(g_LightBitmap); + + g_LightBitmap = engine->CreateBlankBitmap(g_DarknessDiameter, g_DarknessDiameter, 32); + + // Fill with darkness color. + unsigned int color = (255 - (int)((float)g_DarknessLightLevel * 2.55f)) << 24; + unsigned int *pixel = *(unsigned int **)engine->GetRawBitmapSurface(g_LightBitmap); + + int i; + for (i = 0; i < g_DarknessDiameter * g_DarknessDiameter; i++) + *pixel++ = (unsigned int)color; + + // Draw light circle if wanted. + if (g_DarknessSize > 0) { + int current_value = 0; + color = (255 - (int)((float)g_BrightnessLightLevel * 2.55f)); + unsigned int targetcolor = ((255 - (int)((float)g_DarknessLightLevel * 2.55f))); + + int increment = (targetcolor - color) / (g_DarknessSize - g_BrightnessSize); + float perfect_increment = (float)(targetcolor - color) / (float)(g_DarknessSize - g_BrightnessSize); + + float error_term; + + for (i = g_BrightnessSize; i < g_DarknessSize; i++) { + error_term = (perfect_increment * (i - g_BrightnessSize)) - current_value; + + if (error_term >= 1.0f) + increment++; + else if (error_term <= -1.0f) + increment--; + + current_value += increment; + + if (current_value > targetcolor) + current_value = targetcolor; + + plotCircle(g_DarknessSize, g_DarknessSize, i, (current_value << 24) + color); + } + } + + // Draw inner fully lit circle. + if (g_BrightnessSize > 0) { + color = (255 - (int)((float)g_BrightnessLightLevel * 2.55f)) << 24; + + for (i = 0; i < g_BrightnessSize; i++) + plotCircle(g_DarknessSize, g_DarknessSize, i, color); + } + + engine->ReleaseBitmapSurface(g_LightBitmap); +} + + +void Update() { + if (g_BitmapMustBeUpdated) { + CreateLightBitmap(); + g_BitmapMustBeUpdated = false; + } + + if (g_FlashlightFollowMouse) { + engine->GetMousePosition(&g_FlashlightX, &g_FlashlightY); + } else if (g_FollowCharacter != nullptr) { + g_FlashlightX = g_FollowCharacter->x + g_FollowCharacterDx; + g_FlashlightY = g_FollowCharacter->y + g_FollowCharacterDy; + + if ((g_FollowCharacterHorz != 0) || (g_FollowCharacterVert != 0)) { + switch (g_FollowCharacter->loop) { + // Down + case 0: + case 4: + case 6: + g_FlashlightY += g_FollowCharacterVert; + break; + + // Up + case 3: + case 5: + case 7: + g_FlashlightY -= g_FollowCharacterVert; + break; + + // Left + case 1: + g_FlashlightX -= g_FollowCharacterHorz; + break; + + // Right: + case 2: + g_FlashlightX += g_FollowCharacterHorz; + break; + } + } + } + + g_FlashlightDrawAtX = g_FlashlightX - g_DarknessSize; + g_FlashlightDrawAtY = g_FlashlightY - g_DarknessSize; + + + if ((g_GreenTint != 0) || (g_RedTint != 0) || (g_BlueTint != 0)) + DrawTint(); + + if (g_DarknessSize > 0) + AlphaBlendBitmap(); + + if (g_DarknessLightLevel != 100) + DrawDarkness(); + + engine->MarkRegionDirty(0, 0, screen_width, screen_height); +} + +static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = engine->FRead(ptr, size * count, fileHandle); + return totalBytes / size; +} + +static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = engine->FWrite(const_cast(ptr), size * count, fileHandle); + return totalBytes / size; +} + +void RestoreGame(long file) { + unsigned int SaveVersion = 0; + engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, file); + + if (SaveVersion != SaveMagic) { + engine->AbortGame("agsflashlight: bad save."); + } + + // Current version + engineFileRead(&g_RedTint, 4, 1, file); + engineFileRead(&g_GreenTint, 4, 1, file); + engineFileRead(&g_BlueTint, 4, 1, file); + + engineFileRead(&g_DarknessLightLevel, 4, 1, file); + engineFileRead(&g_BrightnessLightLevel, 4, 1, file); + engineFileRead(&g_DarknessSize, 4, 1, file); + engineFileRead(&g_DarknessDiameter, 4, 1, file); + engineFileRead(&g_BrightnessSize, 4, 1, file); + + engineFileRead(&g_FlashlightX, 4, 1, file); + engineFileRead(&g_FlashlightY, 4, 1, file); + + engineFileRead(&g_FlashlightFollowMouse, 4, 1, file); + + engineFileRead(&g_FollowCharacterId, 4, 1, file); + engineFileRead(&g_FollowCharacterDx, 4, 1, file); + engineFileRead(&g_FollowCharacterDy, 4, 1, file); + engineFileRead(&g_FollowCharacterHorz, 4, 1, file); + engineFileRead(&g_FollowCharacterVert, 4, 1, file); + + if (g_FollowCharacterId != 0) + g_FollowCharacter = engine->GetCharacter(g_FollowCharacterId); + + g_BitmapMustBeUpdated = true; +} + + +void SaveGame(long file) { + engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); + + engineFileWrite(&g_RedTint, 4, 1, file); + engineFileWrite(&g_GreenTint, 4, 1, file); + engineFileWrite(&g_BlueTint, 4, 1, file); + + engineFileWrite(&g_DarknessLightLevel, 4, 1, file); + engineFileWrite(&g_BrightnessLightLevel, 4, 1, file); + engineFileWrite(&g_DarknessSize, 4, 1, file); + engineFileWrite(&g_DarknessDiameter, 4, 1, file); + engineFileWrite(&g_BrightnessSize, 4, 1, file); + + engineFileWrite(&g_FlashlightX, 4, 1, file); + engineFileWrite(&g_FlashlightY, 4, 1, file); + + engineFileWrite(&g_FlashlightFollowMouse, 4, 1, file); + + engineFileWrite(&g_FollowCharacterId, 4, 1, file); + engineFileWrite(&g_FollowCharacterDx, 4, 1, file); + engineFileWrite(&g_FollowCharacterDy, 4, 1, file); + engineFileWrite(&g_FollowCharacterHorz, 4, 1, file); + engineFileWrite(&g_FollowCharacterVert, 4, 1, file); +} + + +// ******************************************** +// ************ AGS Interface *************** +// ******************************************** + + + +// tint screen +void SetFlashlightTint(int RedTint, int GreenTint, int BlueTint) { + ClipToRange(RedTint, -31, 31); + ClipToRange(GreenTint, -31, 31); + ClipToRange(BlueTint, -31, 31); + + if ((RedTint != g_RedTint) || (GreenTint != g_GreenTint) || (BlueTint != g_BlueTint)) + g_BitmapMustBeUpdated = true; + + g_RedTint = RedTint; + g_GreenTint = GreenTint; + g_BlueTint = BlueTint; +} + +int GetFlashlightTintRed() { + return g_RedTint; +} + +int GetFlashlightTintGreen() { + return g_GreenTint; +} + +int GetFlashlightTintBlue() { + return g_BlueTint; +} + +int GetFlashlightMinLightLevel() { + return 0; +} + +int GetFlashlightMaxLightLevel() { + return 100; +} + +void SetFlashlightDarkness(int LightLevel) { + ClipToRange(LightLevel, 0, 100); + + if (LightLevel != g_DarknessLightLevel) { + g_BitmapMustBeUpdated = true; + g_DarknessLightLevel = LightLevel; + + if (g_DarknessLightLevel > g_BrightnessLightLevel) + g_BrightnessLightLevel = g_DarknessLightLevel; + } +} + +int GetFlashlightDarkness() { + return g_DarknessLightLevel; +} + +void SetFlashlightDarknessSize(int Size) { + if (Size != g_DarknessSize) { + g_BitmapMustBeUpdated = true; + g_DarknessSize = Size; + g_DarknessDiameter = g_DarknessSize * 2; + } +} + +int GetFlashlightDarknessSize() { + return g_DarknessSize; +} + + +void SetFlashlightBrightness(int LightLevel) { + ClipToRange(LightLevel, 0, 100); + + if (LightLevel != g_BrightnessLightLevel) { + g_BitmapMustBeUpdated = true; + g_BrightnessLightLevel = LightLevel; + + if (g_BrightnessLightLevel < g_DarknessLightLevel) + g_DarknessLightLevel = g_BrightnessLightLevel; + } +} + +int GetFlashlightBrightness() { + return g_BrightnessLightLevel; +} + +void SetFlashlightBrightnessSize(int Size) { + if (Size != g_BrightnessSize) { + g_BitmapMustBeUpdated = true; + g_BrightnessSize = Size; + } +} + +int GetFlashlightBrightnessSize() { + return g_BrightnessSize; +} + +void SetFlashlightPosition(int X, int Y) { + g_FlashlightX = X; + g_FlashlightY = Y; +} + +int GetFlashlightPositionX() { + return g_FlashlightX; +} + +int GetFlashlightPositionY() { + return g_FlashlightY; +} + +void SetFlashlightFollowMouse(int OnOff) { + g_FlashlightFollowMouse = (OnOff != 0); +} + +int GetFlashlightFollowMouse() { + return g_FlashlightFollowMouse ? 1 : 0; +} + +void SetFlashlightFollowCharacter(int CharacterId, int dx, int dy, int horz, int vert) { + g_FollowCharacterId = CharacterId; + g_FollowCharacterDx = dx; + g_FollowCharacterDy = dy; + g_FollowCharacterHorz = horz; + g_FollowCharacterVert = vert; + + g_FollowCharacter = engine->GetCharacter(CharacterId); +} + +int GetFlashlightFollowCharacter() { + return g_FollowCharacterId; +} + +int GetFlashlightCharacterDX() { + return g_FollowCharacterDx; +} + +int GetFlashlightCharacterDY() { + return g_FollowCharacterDy; +} + +int GetFlashlightCharacterHorz() { + return g_FollowCharacterHorz; +} + +int GetFlashlightCharacterVert() { + return g_FollowCharacterVert; +} + +void SetFlashlightMask(int SpriteSlot) { + // Not implemented. +} + +int GetFlashlightMask() { + return 0; +} + +void AGS_EngineStartup(IAGSEngine *lpEngine) { + engine = lpEngine; + + if (engine->version < 13) + engine->AbortGame("Engine interface is too old, need newer version of AGS."); + + engine->RegisterScriptFunction("SetFlashlightTint", (void *)&SetFlashlightTint); + engine->RegisterScriptFunction("GetFlashlightTintRed", (void *)&GetFlashlightTintRed); + engine->RegisterScriptFunction("GetFlashlightTintGreen", (void *)&GetFlashlightTintGreen); + engine->RegisterScriptFunction("GetFlashlightTintBlue", (void *)&GetFlashlightTintBlue); + + engine->RegisterScriptFunction("GetFlashlightMinLightLevel", (void *)&GetFlashlightMinLightLevel); + engine->RegisterScriptFunction("GetFlashlightMaxLightLevel", (void *)&GetFlashlightMaxLightLevel); + + engine->RegisterScriptFunction("SetFlashlightDarkness", (void *)&SetFlashlightDarkness); + engine->RegisterScriptFunction("GetFlashlightDarkness", (void *)&GetFlashlightDarkness); + engine->RegisterScriptFunction("SetFlashlightDarknessSize", (void *)&SetFlashlightDarknessSize); + engine->RegisterScriptFunction("GetFlashlightDarknessSize", (void *)&GetFlashlightDarknessSize); + + engine->RegisterScriptFunction("SetFlashlightBrightness", (void *)&SetFlashlightBrightness); + engine->RegisterScriptFunction("GetFlashlightBrightness", (void *)&GetFlashlightBrightness); + engine->RegisterScriptFunction("SetFlashlightBrightnessSize", (void *)&SetFlashlightBrightnessSize); + engine->RegisterScriptFunction("GetFlashlightBrightnessSize", (void *)&GetFlashlightBrightnessSize); + + engine->RegisterScriptFunction("SetFlashlightPosition", (void *)&SetFlashlightPosition); + engine->RegisterScriptFunction("GetFlashlightPositionX", (void *)&GetFlashlightPositionX); + engine->RegisterScriptFunction("GetFlashlightPositionY", (void *)&GetFlashlightPositionY); + + + engine->RegisterScriptFunction("SetFlashlightFollowMouse", (void *)&SetFlashlightFollowMouse); + engine->RegisterScriptFunction("GetFlashlightFollowMouse", (void *)&GetFlashlightFollowMouse); + + engine->RegisterScriptFunction("SetFlashlightFollowCharacter", (void *)&SetFlashlightFollowCharacter); + engine->RegisterScriptFunction("GetFlashlightFollowCharacter", (void *)&GetFlashlightFollowCharacter); + engine->RegisterScriptFunction("GetFlashlightCharacterDX", (void *)&GetFlashlightCharacterDX); + engine->RegisterScriptFunction("GetFlashlightCharacterDY", (void *)&GetFlashlightCharacterDY); + engine->RegisterScriptFunction("GetFlashlightCharacterHorz", (void *)&GetFlashlightCharacterHorz); + engine->RegisterScriptFunction("GetFlashlightCharacterVert", (void *)&GetFlashlightCharacterVert); + + engine->RegisterScriptFunction("SetFlashlightMask", (void *)&SetFlashlightMask); + engine->RegisterScriptFunction("GetFlashlightMask", (void *)&GetFlashlightMask); + + engine->RequestEventHook(AGSE_PREGUIDRAW); + engine->RequestEventHook(AGSE_PRESCREENDRAW); + engine->RequestEventHook(AGSE_SAVEGAME); + engine->RequestEventHook(AGSE_RESTOREGAME); +} + +void AGS_EngineShutdown() { + +} + +int AGS_EngineOnEvent(int event, int data) { + if (event == AGSE_PREGUIDRAW) { + Update(); + } else if (event == AGSE_RESTOREGAME) { + RestoreGame(data); + } else if (event == AGSE_SAVEGAME) { + SaveGame(data); + } else if (event == AGSE_PRESCREENDRAW) { + // Get screen size once here. + engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); + engine->UnrequestEventHook(AGSE_PRESCREENDRAW); + + // Only 16 bit color depth is supported. + if (screen_color_depth != 16) { + engine->UnrequestEventHook(AGSE_PREGUIDRAW); + engine->UnrequestEventHook(AGSE_PRESCREENDRAW); + engine->UnrequestEventHook(AGSE_SAVEGAME); + engine->UnrequestEventHook(AGSE_RESTOREGAME); + } + } + + return 0; +} + +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { + return 0; +} + +void AGS_EngineInitGfx(const char *driverID, void *data) { +} + + + +#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) + +// ******************************************** +// *********** Editor Interface ************* +// ******************************************** + +const char *scriptHeader = + "import void SetFlashlightTint(int RedTint, int GreenTint, int BlueTint);\r\n" + "import int GetFlashlightTintRed();\r\n" + "import int GetFlashlightTintGreen();\r\n" + "import int GetFlashlightTintBlue();\r\n" + "import int GetFlashlightMinLightLevel();\r\n" + "import int GetFlashlightMaxLightLevel();\r\n" + "import void SetFlashlightDarkness(int LightLevel);\r\n" + "import int GetFlashlightDarkness();\r\n" + "import void SetFlashlightDarknessSize(int Size);\r\n" + "import int GetFlashlightDarknessSize();\r\n" + "import void SetFlashlightBrightness(int LightLevel);\r\n" + "import int GetFlashlightBrightness();\r\n" + "import void SetFlashlightBrightnessSize(int Size);\r\n" + "import int GetFlashlightBrightnessSize();\r\n" + "import void SetFlashlightPosition(int X, int Y);\r\n" + "import int GetFlashlightPositionX();\r\n" + "import int GetFlashlightPositionY();\r\n" + "import void SetFlashlightFollowMouse(int OnOff);\r\n" + "import int GetFlashlightFollowMouse ();\r\n" + "import void SetFlashlightFollowCharacter(int CharacterId, int dx, int dy, int horz, int vert);\r\n" + "import int GetFlashlightFollowCharacter();\r\n" + "import int GetFlashlightCharacterDX();\r\n" + "import int GetFlashlightCharacterDY();\r\n" + "import int GetFlashlightCharacterHorz();\r\n" + "import int GetFlashlightCharacterVert();\r\n"; + + +IAGSEditor *editor; + + +LPCSTR AGS_GetPluginName(void) { + // Return the plugin description + return "Flashlight plugin recreation"; +} + +int AGS_EditorStartup(IAGSEditor *lpEditor) { + // User has checked the plugin to use it in their game + + // If it's an earlier version than what we need, abort. + if (lpEditor->version < 1) + return -1; + + editor = lpEditor; + editor->RegisterScriptHeader(scriptHeader); + + // Return 0 to indicate success + return 0; +} + +void AGS_EditorShutdown() { + // User has un-checked the plugin from their game + editor->UnregisterScriptHeader(scriptHeader); +} + +void AGS_EditorProperties(HWND parent) { + // User has chosen to view the Properties of the plugin + // We could load up an options dialog or something here instead + MessageBoxA(parent, "Flashlight plugin recreation by JJS", "About", MB_OK | MB_ICONINFORMATION); +} + +int AGS_EditorSaveGame(char *buffer, int bufsize) { + // We don't want to save any persistent data + return 0; +} + +void AGS_EditorLoadGame(char *buffer, int bufsize) { + // Nothing to load for this plugin +} + +#endif + + +#if defined(BUILTIN_PLUGINS) +} // namespace agsflashlight +#endif diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.h b/engines/ags/plugins/ags_flashlight/ags_flashlight.h new file mode 100644 index 000000000000..cd01110630a1 --- /dev/null +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.h @@ -0,0 +1,14 @@ +#ifndef AGS_FLASHLIGHT_H +#define AGS_FLASHLIGHT_H + +#include "plugin/agsplugin.h" + +namespace agsflashlight { +void AGS_EngineStartup(IAGSEngine *lpEngine); +void AGS_EngineShutdown(); +int AGS_EngineOnEvent(int event, int data); +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); +void AGS_EngineInitGfx(const char *driverID, void *data); +} + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp new file mode 100644 index 000000000000..7275320213d7 --- /dev/null +++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp @@ -0,0 +1,2164 @@ +// +// ags_template.cpp : Example AGS plugin file +// See the online API reference for details of how this works. +// Copyright (c) 2002 Chris Jones +// + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#if !defined(BUILTIN_PLUGINS) +#define THIS_IS_THE_PLUGIN +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "plugin/agsplugin.h" +#include "palrender.h" +#include "raycast.h" + +#define MAX_OVERLAYS 128 +#define MAX_STARS 1024 +#define MAX_DEPTH 64 + +#define PI (3.1415926535f) +#define HALF_PI (0.5f * PI) +#define TWO_PI (2.0f * PI) +#define TWO_PI_INV (1.0f / TWO_PI) +// DllMain - standard Windows DLL entry point. +// The AGS editor will cause this to get called when the editor first +// starts up, and when it shuts down at the end. + +#if AGS_PLATFORM_OS_WINDOWS +bool APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) { + + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + + + +#if defined(BUILTIN_PLUGINS) +namespace agspalrender { +#endif + +const float halfpi = (0.5f * PI); +const float twopi = (2.0f * PI); +const float twopi_inv = (1.0f / TWO_PI); +const float pisquared = PI * PI; +const float picubed = PI * PI * PI; + +//unsigned char clut[256][256]; +unsigned char clut[65536]; + +struct transoverlaytype { + int sprite; + int spritemask; + int blendtype; + int x; + int y; + int trans; + int level; + bool enabled; +} overlay[MAX_OVERLAYS]; + +int clutslot; +int drawreflections; +unsigned char cycle_remap [256]; + +struct starstype { + float x; + float y; + float z; + unsigned char color; + long sprite; + int maxrad; + int scaleboost; +}; +starstype *stars; + +struct starsoptions { + float speed; + int maxstars; + int depthmultiplier; + int originx; + int originy; + int overscan; +} Starfield; +long *reflectionmap; +BITMAP *rcolormap; +BITMAP *ralphamap; + +struct charrefopt { + char reflect; + int replaceview; +}; + +struct objrefopt { + char reflect; + char ignorescaling; +}; + +struct reflectionopt { + charrefopt *Characters; + objrefopt *Objects; + int blendslot; + int blendamount; +} Reflection; + +int dummy; + +#define LENS_WIDTH 150 + +struct LensDistort { + int xoffset; + int yoffset; +}; + +LensDistort *lens; +struct LensOpt { + bool draw; + int lenswidth; + int lenszoom; + int level; + int x; + int y; + int clampoffset; +} LensOption; + +const int alphamultiply [4096] = { +//#include "alphamultiply.txt" +}; +float rot_sine_LUT[360]; +float rot_cos_LUT[360]; + +BITMAP *backgroundimage; + +PALSTRUCT objectivepal[256]; +int bgimgspr; + +// ***** DESIGN TIME CALLS ******* +#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) + +IAGSEditor *editor; +const char *ourScriptHeader = + "enum BlendingMode { \r\n" + "eBlendAlpha = 0, \r\n" + "eBlendAdditive = 1 \r\n" + "}; \r\n" + "enum ObjectiveMode { \r\n" + "eUseStandardPal = 0, \r\n" + "eUseObjectivePal = 1 \r\n" + "}; \r\n" + "enum PlasmaMixMode { \r\n" + "ePlasmaNone = 0, \r\n" + "ePlasmaHorzBars = 1, \r\n" + "ePlasmaVertBars = 2, \r\n" + "ePlasmaCircle = 3, \r\n" + "ePlasmaDiagBars = 4 \r\n" + "}; \r\n" + "enum PlasmaRootType { \r\n" + "ePlasmaSlowRoot = 1, \r\n" + "ePlasmaFastRoot = 0 \r\n" + "}; \r\n" + "enum TransOverlayLevel { \r\n" + "eTOBackground = 0, \r\n" + "eTOPreGUI = 1, \r\n" + "eTOPostGUI = 2 \r\n" + "}; \r\n" + "enum LensLevel { \r\n" + "eLensBackgroundPreTO = 0, \r\n" + "eLensBackgroundPostTO = 1, \r\n" + "eLensPreGUIPreTO = 2, \r\n" + "eLensPreGUIPostTO = 3, \r\n" + "eLensPostGUIPreTO = 4, \r\n" + "eLensPostGUIPostTO = 5 \r\n" + "}; \r\n" + + "struct Raycast { \r\n" + "import static void Render (int slot); \r\n" + "import static void UnloadEngine (); //$AUTOCOMPLETEIGNORE$ \r\n" + "import static void MoveForward (); \r\n" + "import static void MoveBackward (); \r\n" + "import static void RotateLeft (); \r\n" + "import static void RotateRight (); \r\n" + "import static void MakeTextures (int slot); \r\n" + "import static void Initialize (); \r\n" + "import static void LoadMap (int worldmapSlot,int lightmapSlot,int ceilingmapSlot,int floormapSlot); \r\n" + "import static void SetCameraPosition (float x,float y); \r\n" + "import static float GetCameraX (); \r\n" + "import static float GetCameraY (); \r\n" + "import static int GetCameraAngle (); \r\n" + "import static void SetCameraAngle (int angle); \r\n" + "import static void InitSprite (int id, float x, float y, int slot, char alpha=255, BlendingMode blendmode=0, float scale_x=0, float scale_y=0, float vMove=0);\r\n" + "import static int GetHotspotAtXY (int x,int y); \r\n" + "import static int GetObjectAtXY (int x,int y); \r\n" + + "import static void SetSpriteInteractObj (int id,int obj); \r\n" + "import static int GetSpriteInteractObj (int id); \r\n" + "import static void SetSpritePosition (int id, float x, float y); \r\n" + "import static void SetSpriteVertOffset (int id, float vMove); \r\n" + "import static float GetSpriteVertOffset (int id); \r\n" + "import static float GetSpriteX (int id); \r\n" + "import static float GetSpriteY (int id); \r\n" + "import static int GetSpriteAngle (int id); \r\n" + "import static void SetSpriteAngle (int id,int angle); \r\n" + "import static void SetSpriteView (int id,int view); \r\n" + "import static int GetSpriteView (int id); \r\n" + "import static void SetSpriteFrame (int id,int frame); \r\n" + "import static int GetSpriteFrame (int id); \r\n" + "import static float GetSpriteScaleX (int id); \r\n" + "import static void SetSpriteScaleX (int id,float scale); \r\n" + "import static float GetSpriteScaleY (int id); \r\n" + "import static void SetSpriteScaleY (int id,float scale); \r\n" + + + "import static void SetWallHotspot (int id,char hotsp); \r\n" + "import static void SetWallTextures (int id,int n,int s,int w,int e); \r\n" + "import static void SetWallSolid (int id,int n,int s,int w,int e); \r\n" + "import static void SetWallIgnoreLighting (int id,int n,int s,int w,int e); \r\n" + "import static void SetWallAlpha (int id,int n,int s,int w,int e); \r\n" + "import static void SetWallBlendType (int id,BlendingMode n,BlendingMode s,BlendingMode w,BlendingMode e);\r\n" + + "import static float GetMoveSpeed (); \r\n" + "import static void SetMoveSpeed (float speed); \r\n" + "import static float GetRotSpeed (); \r\n" + "import static void SetRotSpeed (float speed); \r\n" + "import static int GetWallAt (int x,int y); \r\n" + "import static int GetLightAt (int x,int y); \r\n" + "import static void SetLightAt (int x,int y, int light); \r\n" + "import static void SetWallAt (int x,int y,int id); \r\n" + "import static void SetPlaneY (float y); \r\n" + "import static float GetDistanceAt (int x,int y); \r\n" + "import static void SetSkyBox (int slot); \r\n" + "import static int GetSkyBox (int slot); \r\n" + "import static void SetAmbientLight (int value); \r\n" + "import static int GetAmbientLight (); \r\n" + "import static void SetFloorAt (int x,int y,int tex); \r\n" + "import static void SetCeilingAt (int x,int y,int tex); \r\n" + "import static int GetCeilingAt (int x,int y); \r\n" + "import static int GetFloorAt (int x,int y); \r\n" + "import static int GetLightingAt (int x,int y); \r\n" + "import static void SetLightingAt (int x,int y,char lighting); \r\n" + "import static int GetAmbientWeight (); \r\n" + "import static int GetTileX_At (int x,int y); \r\n" + "import static int GetTileY_At (int x,int y); \r\n" + "///Draws a loaded tile onto a sprite (make sure it's 64x64 pixels). \r\n" + "import static void DrawTile (int spr,int tile); \r\n" + "///Draws a sprite onto a tile (make sure it's 64x64 pixels). \r\n" + "import static void DrawOntoTile (int spr,int tile); \r\n" + "import static int GetWallHotspot (int id); \r\n" + "import static int GetWallTexture (int id,int dir); \r\n" + "import static int GetWallSolid (int id,int dir); \r\n" + "import static int GetWallIgnoreLighting (int id,int dir); \r\n" + "import static int GetWallAlpha (int id, int dir); \r\n" + "import static int GetWallBlendType (int id,int dir); \r\n" + "import static void SelectTile (int x,int y, char color); \r\n" + "import static void SetNoClip (int value); \r\n" + "import static int GetNoClip (); \r\n" + "import static int HasSeenTile (int x,int y); \r\n" + "import static int GetSpriteAlpha (int id); \r\n" + "import static void SetSpriteAlpha (int id,int alpha); \r\n" + "import static int GetSpritePic (int id); \r\n" + "import static void SetSpritePic (int id,int slot); \r\n" + "import static void SetSpriteBlendType (int id,BlendingMode type); \r\n" + "import static int GetSpriteBlendType (int id); \r\n" + "import static void SetAmbientColor (int color,int amount); \r\n" + "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" + "}; \r\n" + + "struct PALInternal { \r\n" + "///Loads the colour lookup table for translucency effects. Used by module. \r\n" + "import static int LoadCLUT (int slot);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Cycles the internal palette structure of the plugin. Internal use only. \r\n" + "import static void CycleRemap (int start, int end);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Resets the remap array. \r\n" + "import static void ResetRemapping (); // $AUTOCOMPLETESTATICONLY$ \r\n" + "///Gets the closest palette slot from 16 bit colour space. \r\n" + "import static char GetColor565 (char r,char g,char b);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Returns the true location of a remapped colour. \r\n" + "import static char GetRemappedSlot (char slot);//$AUTOCOMPLETESTATICONLY$ \r\n" + "///Gets the luminosity of the palette slot. \r\n" + "import static int GetLuminosityFromPalette (int slot);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Polynomial Sine Approximation. \r\n" + "import static float FastSin (float x);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Polynomial Cosine Approximation. \r\n" + "import static float FastCos (float x);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Ludicrously Fast Integer Root (0-0xFFFF) \r\n" + "import static int FastRoot(int x); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static int GetModifiedBackgroundImage (); //$AUTOCOMPLETEIGNORE$ \r\n" + "import static void WriteObjectivePalette (char index,char r,char b, char g); \r\n" + "import static int ReadObjectivePaletteR (char index); \r\n" + "import static int ReadObjectivePaletteB (char index); \r\n" + "import static int ReadObjectivePaletteG (char index); \r\n" + "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" + "}; \r\n" + + "struct Translucence { \r\n" + "///Creates a translucent overlay. level=0: Background,level=1: Below GUIs,level=2:Above GUIs. blendmode=0: Alpha, blendmode=1: Additive \r\n" + "import static int CreateOverlay (int id, int sprite, int alpha, int level, int ox, int oy,int mask=0,BlendingMode blendmode=0);// $AUTOCOMPLETESTATICONLY$\r\n" + "///Deletes translucent overlay. \r\n" + "import static int DeleteOverlay (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Moves Translucent Overlay to OX,OY. \r\n" + "import static int Move (int id, int ox, int oy);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Get X coordinate of translucent overlay. \r\n" + "import static int GetOverlayX (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Get Y coordinate of translucent overlay. \r\n" + "import static int GetOverlayY (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Get the sprite slot for translucent overlay id \r\n" + "import static int GetOverlaySprite (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Get the level the overlay is drawn on currently. \r\n" + "import static int GetOverlayLevel (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Get whether Translucent Overlay is currently being drawn. \r\n" + "import static int GetOverlayEnabled (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Get the alpha channel for translucent overlay id. (0-255) \r\n" + "import static int GetOverlayAlpha (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Set translucent overlay id's alpha. (0-255) \r\n" + "import static int SetOverlayAlpha (int id, int alpha);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Turn overlay on or off. \r\n" + "import static int SetOverlayEnabled (int id, int toggle);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Blend bg with fg (fg is changed) together at alpha translevel. \r\n" + "import static int DrawTransSprite (int sprite, int bg, int translevel,int mask=0,BlendingMode blendmode=0,ObjectiveMode use_objpal=0);// $AUTOCOMPLETESTATICONLY$ \r\n" + "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" + "}; \r\n" + + "struct Reflections { \r\n" + "///Turn reflective floors off or on. \r\n" + "import static int Set (int toggle);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Check if reflections are turned on. \r\n" + "import static int IsReflecting ();// $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void SetCharacterReflected (int id,int refl);// $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void SetObjectReflected (int id,int refl);// $AUTOCOMPLETESTATICONLY$ \r\n" + "import static int GetCharacterReflected (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "import static int GetObjectReflected (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void ReplaceCharacterReflectionView (int id,int view);// $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void SetObjectReflectionIgnoreScaling (int id,int wb);// $AUTOCOMPLETESTATICONLY$ \r\n" + "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" + "}; \r\n" + + + "struct LensDistort { \r\n" + "import static void SetPos (int x,int y); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static int GetX (); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static int GetY (); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void Set (int toggle); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static int IsDrawn (); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void SetOffsetClamp (int clamp); //$AUTOCOMPLETEIGNORE$ \r\n" + "import static int GetOffsetClamp (); //$AUTOCOMPLETEIGNORE$ \r\n" + "import static int GetLevel (); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void SetLevel (int level); // $AUTOCOMPLETESTATICONLY$ \r\n" + "import static void Initialize (int width, int zoom, int lensx,int lensy,LensLevel level,int clamp=-1); // $AUTOCOMPLETESTATICONLY$ \r\n" + "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" + "}; \r\n" + + "struct Plasma { \r\n" + "///Set options for plasma generation. 0 = None. 1 = Horizontal Bars (data=width). 2 = Vertical Bars (data=width). 3 = Circle (data=x,data2=y,data3=width). 4 = Diagonal Bars (data=width) \r\n" + "import static void SetPlasmaType (int component, PlasmaMixMode type, int data=0, int data2=0, int data3=0);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Set all plasma settings to 0. \r\n" + "import static void ResetPlasmaSettings ();// $AUTOCOMPLETESTATICONLY$\r\n" + "///Draw Plasma into dynamic sprite slot using range palstart-palend. Remember to use SetPlasmaType first! \r\n" + "import static void DrawPlasma (int slot, int palstart, int palend);// $AUTOCOMPLETESTATICONLY$ \r\n" + "///Draw fire effect into sprite, and alpha channel into masksprite. \r\n" + "import static void DoFire (int sprite, int masksprite, int palstart,int palend, int strength, int seed=0,int cutoff=0,int windspeed=0);// $AUTOCOMPLETESTATICONLY$\r\n" + "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" + "import static void SetRootType (PlasmaRootType real);// $AUTOCOMPLETESTATICONLY$ \r\n" + "import static int GetRootType ();// $AUTOCOMPLETESTATICONLY$ \r\n" + "}; \r\n" + + "struct Starfield { \r\n" + "import static void Draw (int slot, int maskslot); \r\n" + "import static void RotateStar (int star, int angle,int px,int py); \r\n" + "import static void Iterate (int slot); \r\n" + "import static void Initialize (int slot,int maxstars); \r\n" + "import static void SetOriginPoint (int x,int y); \r\n" + "import static float GetStarX (int i); \r\n" + "import static float GetStarY (int i); \r\n" + "import static float GetStarZ (int i); \r\n" + "import static void SetStarPosition (int star,float x,float y,float z); \r\n" + "import static void SetStarColor (int star, char color); \r\n" + "import static char GetStarColor (int star); \r\n" + "import static void SetStarSprite (int star, int slot); \r\n" + "import static int GetStarSprite (int star); \r\n" + "import static void SetStarSpriteRange (int start, int end, int slot); \r\n" + "import static int GetOverscan (); \r\n" + "import static void SetOverscan (int overscan); \r\n" + "import static int GetOriginX (); \r\n" + "import static int GetOriginY (); \r\n" + "import static void SetDepthMultiplier (int multi); \r\n" + "import static int GetDepthMultiplier (); \r\n" + "import static int GetMaxStars (); \r\n" + "import static void SetStarSpriteScaleBoost (int star,int boost); \r\n" + "import static int GetStarSpriteScaleBoost (int star); \r\n" + "import static void SetStarMaxRadius (int star,int radius); \r\n" + "import static int GetStarMaxRadius (int star); \r\n" + "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" + "}; \r\n"; + +const char *AGS_GetPluginName(void) { + // Return the plugin description + return "PALgorithms Translucent Overlay Renderer"; +} + +int AGS_EditorStartup(IAGSEditor *lpEditor) { + // User has checked the plugin to use it in their game + + // If it's an earlier version than what we need, abort. + if (lpEditor->version < 1) + return -1; + + editor = lpEditor; + editor->RegisterScriptHeader(ourScriptHeader); + + // Return 0 to indicate success + return 0; +} + +void AGS_EditorShutdown() { + // User has un-checked the plugin from their game + editor->UnregisterScriptHeader(ourScriptHeader); +} + +#if AGS_PLATFORM_OS_WINDOWS +void AGS_EditorProperties(HWND parent) { + // User has chosen to view the Properties of the plugin + // We could load up an options dialog or something here instead + MessageBox(parent, "PALgorithms Translucent Overlay Renderer & Other Demo Effects (c) 2015 Scavenger", "About", MB_OK | MB_ICONINFORMATION); +} + +#endif + +int AGS_EditorSaveGame(char *buffer, int bufsize) { + // We don't want to save any persistent data + return 0; +} + +void AGS_EditorLoadGame(char *buffer, int bufsize) { + // Nothing to load for this dummy plugin +} + +#endif // #if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) +// ******* END DESIGN TIME ******* + + +// ****** RUN TIME ******** + +IAGSEngine *engine; + +void WriteObjectivePalette(unsigned char index, unsigned char r, unsigned char b, unsigned char g) { + objectivepal[index].r = r; + objectivepal[index].b = b; + objectivepal[index].g = g; +} + +int ReadObjectivePaletteR(unsigned char index) { + return objectivepal[index].r; +} + +int ReadObjectivePaletteB(unsigned char index) { + return objectivepal[index].b; +} +int ReadObjectivePaletteG(unsigned char index) { + return objectivepal[index].g; +} + + +#define SQRT_MAGIC_F 0x5f3759df +float q3sqrt(const float x) { + const float xhalf = 0.5f * x; + + union { // get bits for floating value + float x; + int i; + } u; + u.x = x; + u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0 + return x * u.x * (1.5f - xhalf * u.x * u.x); // Newton step, repeating increases accuracy +} + +void Make_Sin_Lut() { + for (int angle = 0; angle < 360; angle++) { + double rad = (angle * PI) / 180.0; + rot_sine_LUT [angle] = static_cast(sin(rad)); + rot_cos_LUT [angle] = static_cast(cos(rad)); + } +} + +/* +void PreMultiply_Alphas () //Ha ha, this isn't the kind of premultiplcation you're thinking of. +{ + for (int y=0;y<64;y++) + for (int x=0;x<64;x++) + alphamultiply [y*64+x] = y*x; +} +*/ + +int GetModifiedBackgroundImage() { + return bgimgspr; +} + +unsigned short root(unsigned short x) { + unsigned short a, b; + b = x; + a = x = 0x3f; + x = b / x; + a = x = (x + a) >> 1; + x = b / x; + a = x = (x + a) >> 1; + x = b / x; + x = (x + a) >> 1; + return (x); +} + + +inline float Hill(float x) { + const float a0 = 1.0f; + const float a2 = 2.0f / PI - 12.0f / (pisquared); + const float a3 = 16.0f / (picubed) - 4.0f / (pisquared); + const float xx = x * x; + const float xxx = xx * x; + + return a0 + a2 * xx + a3 * xxx; +} + +float FastSin(float x) { + // wrap x within [0, TWO_PI) + const float a = x * twopi_inv; + x -= static_cast(a) * twopi; + if (x < 0.0f) + x += twopi; + + // 4 pieces of hills + if (x < halfpi) + return Hill(halfpi - x); + else if (x < PI) + return Hill(x - halfpi); + else if (x < 3.0f * halfpi) + return -Hill(3.0f * halfpi - x); + else + return -Hill(x - 3.0f * halfpi); +} + +float FastCos(float x) { + return FastSin(x + halfpi); +} + +FLOAT_RETURN_TYPE AGSFastSin(SCRIPT_FLOAT(x)) { + INIT_SCRIPT_FLOAT(x); + x = FastSin(x); + RETURN_FLOAT(x); +} + +FLOAT_RETURN_TYPE AGSFastCos(SCRIPT_FLOAT(x)) { + INIT_SCRIPT_FLOAT(x); + x = FastSin(x + halfpi); + RETURN_FLOAT(x); +} + + +void DrawLens(int ox, int oy) { + int32 sh, sw = 0; + engine->GetScreenDimensions(&sw, &sh, nullptr); + BITMAP *virtsc = engine->GetVirtualScreen(); + if (!virtsc) engine->AbortGame("DrawLens: Cannot get virtual screen."); + BITMAP *lenswrite = engine->CreateBlankBitmap(LensOption.lenswidth, LensOption.lenswidth, 8); + unsigned char **screen = engine->GetRawBitmapSurface(virtsc); + unsigned char **lensarray = engine->GetRawBitmapSurface(lenswrite); + int radius = LensOption.lenswidth >> 1; + for (int y = 0; y < LensOption.lenswidth; y++) { + int ypos = y * LensOption.lenswidth; + for (int x = 0; x < LensOption.lenswidth; x++) { + int lenspos = ypos + x; + int coffx = lens[lenspos].xoffset; + int coffy = lens[lenspos].yoffset; + if (oy + coffy > 0 && oy + coffy < sh && ox + coffx > 0 && ox + coffx < sw) { + lensarray[y][x] = screen[oy + coffy][ox + coffx]; + //screen[oy+coffy][ox+coffx] = abs(coffy); + } + } + } + /* + for (int y=0;y 0 && oy+y < sh && ox+x > 0 && ox+x < sw) + { + screen[oy+y][ox+x] = lensarray[y][x]; + } + } + } + */ + int radsq = radius * radius; + for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask. + int cysq = cy * cy; + for (int cx = -radius; cx <= radius; cx++) { + int cxsq = cx * cx; + int dx = cx + ox; + int dy = cy + oy; + if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0 && cy + radius < LensOption.lenswidth - 1 && cx + radius < LensOption.lenswidth - 1) { + //if (cy+radius < 0 || cx+radius < 0) engine->AbortGame ("I did something wrong"); + screen[dy][dx] = lensarray[cy + radius][cx + radius]; + } + } + } + + engine->ReleaseBitmapSurface(lenswrite); + engine->ReleaseBitmapSurface(virtsc); + engine->FreeBitmap(lenswrite); +} + +void SetLensPos(int x, int y) { + LensOption.x = x; + LensOption.y = y; +} + +int GetLensX() { + return LensOption.x; +} + +int GetLensY() { + return LensOption.y; +} + +void SetLensDrawn(int toggle) { + if (toggle > 0) LensOption.draw = 1; + else LensOption.draw = 0; +} + +int GetLensDrawn() { + return LensOption.draw; +} + +void SetLensOffsetClamp(int clamp) { + if (clamp < 0) LensOption.clampoffset = LensOption.lenswidth; + else LensOption.clampoffset = clamp; +} + +int GetLensOffsetClamp() { + return LensOption.clampoffset; +} + +int GetLensLevel() { + return LensOption.level; +} + +void SetLensLevel(int level) { + if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level."); + else LensOption.level = level; +} + +void LensInitialize(int width, int zoom, int lensx, int lensy, int level, int clamp = -1) { + int32 sw, sh, radius; + if (width < 1) engine->AbortGame("Invalid lens dimension!"); + radius = width >> 1; + lens = new LensDistort [width * width](); + engine->GetScreenDimensions(&sw, &sh, nullptr); + int radsq = radius * radius; + int zoomsq = zoom * zoom; + for (int y = 0; y < radius; y++) { + int ysq = y * y; + for (int x = 0; x < radius; x++) { + int lx, ly; + int xsq = x * x; + if ((xsq + ysq) < (radsq)) { + float shift = zoom / sqrt((float)(zoomsq - (xsq + ysq - radsq))); + lx = (int)(x * shift - x); + ly = (int)(y * shift - y); + } else { + lx = 0; + ly = 0; + } + lens[(radius - y)*width + (radius - x)].xoffset = lx; + lens[(radius - y)*width + (radius - x)].yoffset = ly; + lens[(radius + y)*width + (radius + x)].xoffset = -lx; + lens[(radius + y)*width + (radius + x)].yoffset = -ly; + lens[(radius + y)*width + (radius - x)].xoffset = lx; + lens[(radius + y)*width + (radius - x)].yoffset = -ly; + lens[(radius - y)*width + (radius + x)].xoffset = -lx; + lens[(radius - y)*width + (radius + x)].yoffset = ly; + } + } + LensOption.lenswidth = width; + LensOption.lenszoom = zoom; + if (clamp < 0) LensOption.clampoffset = width; + else LensOption.clampoffset = clamp; + LensOption.x = lensx; + LensOption.y = lensy; + if (level < 0 || level > 4) engine->AbortGame("SetLensLevel: Invalid level."); + else LensOption.level = level; +} + +void ResetRemapping() { + for (int j = 0; j < 256; ++j) { + cycle_remap [j] = j; + } +} + +#define MAX_PLASMA_COMPLEXITY 4 +int plasmatype[MAX_PLASMA_COMPLEXITY]; +int plasmadata [MAX_PLASMA_COMPLEXITY]; +int plasmadata2 [MAX_PLASMA_COMPLEXITY]; +int plasmadata3 [MAX_PLASMA_COMPLEXITY]; +int plasmaroottype; + + +void SetPlasmaRootType(int real) { + if (real) plasmaroottype = 1; + else plasmaroottype = 0; +} + +int GetPlasmaRootType() { + return plasmaroottype; +} + +void SetPlasmaType(int component, int type, int data, int data2, int data3) { + if (component >= MAX_PLASMA_COMPLEXITY) engine->AbortGame("Plasma too complex!"); + else { + plasmatype [component] = type; + plasmadata [component] = data; + plasmadata2[component] = data2; + plasmadata3[component] = data3; + } + + //0 = None. + //1 = Horizontal Bars (data=width) + //2 = Vertical Bars (data=width) + //3 = Circle (data=x,data2=y,data3=width) + //4 = Diagonal Bars (data=width) +} + +void ResetPlasmaSettings() { + int i = 0; + while (i < MAX_PLASMA_COMPLEXITY) { + plasmatype [i] = 0; + plasmadata [i] = 0; + plasmadata2[i] = 0; + plasmadata3[i] = 0; + i++; + } +} + +void DrawPlasma(int slot, int palstart, int palend) { + BITMAP *plasmaspr = engine->GetSpriteGraphic(slot); + if (!plasmaspr) engine->AbortGame("Plasma: Not a sprite I can load."); + int32 w, h, basecol, range = 0; + if (palend > palstart) { + range = palend - palstart; + basecol = palstart; + } else { + range = palstart - palend; + basecol = palend; + } + engine->GetBitmapDimensions(plasmaspr, &w, &h, nullptr); + unsigned char **plasmarray = engine->GetRawBitmapSurface(plasmaspr); + double frange = range / 2.0; + int complex = 0; + int color = 0; + int i = 0; + while (i < MAX_PLASMA_COMPLEXITY) { + if (plasmatype[i] > 0) complex++; + i++; + } + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + color = 0; + for (int p = 0; p < MAX_PLASMA_COMPLEXITY; p++) { + if (plasmatype[p] == 1) { //1 = Horizontal Bars (data=width) + color += int(frange + (frange * FastSin(y / (float)plasmadata[p]))); + } else if (plasmatype[p] == 2) { //2 = Vertical Bars (data=width) + color += int(frange + (frange * FastSin(x / (float)plasmadata[p]))); + } else if (plasmatype[p] == 3) { //3 = Circle (data=x,data2=y,data3=width) + int cx, cy = 0; + cx = plasmadata [p]; + cy = plasmadata2 [p]; + if (plasmaroottype == 1) color += int(frange + (frange * FastSin(q3sqrt((float)((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p])))); + else color += int(frange + (frange * FastSin(root(((x - cx) * (x - cx) + (y - cy) * (y - cy)) / plasmadata3[p])))); + } else if (plasmatype[p] == 4) { //4 = Diagonal Bars (data=width) + color += int(frange + (frange * FastSin((x + y) / (float)plasmadata[p]))); + } + } + if (color > 0 && complex > 0) color = color / complex; + plasmarray[y][x] = static_cast(basecol + color); + } + } + engine->ReleaseBitmapSurface(plasmaspr); + engine->NotifySpriteUpdated(slot); +} + +void DoFire(int sprite, int masksprite, int palstart, int palend, int strength, int seed, int cutoff, int windspeed) { + BITMAP *firespr = engine->GetSpriteGraphic(masksprite); + BITMAP *firecolorspr = engine->GetSpriteGraphic(sprite); + BITMAP *seedspr; + int32 w, h = 0; + int range, basecol, dir = 0; + if (palend > palstart) { + range = palend - palstart; + basecol = palstart; + dir = 1; + } else { + range = palstart - palend; + basecol = palend; + dir = -1; + } + int divider = 256 / range; + engine->GetBitmapDimensions(firespr, &w, &h, nullptr); + unsigned char **fire = engine->GetRawBitmapSurface(firespr); + unsigned char **color = engine->GetRawBitmapSurface(firecolorspr); + int sparky = 0; + //srand(time(NULL)); + for (int y = 0; y < h - 1; y++) { + if (rand() % 10 > 7 - windspeed) { //Wind right + for (int x = w - 1; x > 1; x--) { + fire[y][x] = fire[y][x - 1]; + } + } else if (rand() % 10 > 7 + windspeed) { // wind left + for (int x = 0; x < w - 1; x++) { + fire[y][x] = fire[y][x + 1]; + } + } + } + for (int x = 0; x < w; x++) { + sparky = abs(rand() % (h - 2)); + if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff && abs(rand() % 10) > 7) fire[h - sparky][x] = 255; + sparky = abs(rand() % (h - 2)); + if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff && abs(rand() % 10) > 7) fire[h - sparky][x] = 0; + } + if (seed == 0) { + for (int x = 0; x < w; x++) fire[h - 1][x] = 255; + for (int x = 0; x < w; x++) fire[h - 2][x] = abs(32768 + rand()) % 256; + } else if (seed > 0) { + seedspr = engine->GetSpriteGraphic(seed); + BITMAP *virtsc = engine->GetVirtualScreen(); + engine->SetVirtualScreen(firespr); + engine->BlitBitmap(0, 0, seedspr, 1); + engine->SetVirtualScreen(virtsc); + engine->ReleaseBitmapSurface(virtsc); + engine->ReleaseBitmapSurface(seedspr); + engine->NotifySpriteUpdated(sprite); + engine->NotifySpriteUpdated(masksprite); + } + + for (int y = 0; y < h - 1; y++) { + for (int x = 0; x < w; x++) { + fire[y][x] = + ((fire[(y + 1) % h][(x - 1 + w) % w] + + fire[(y + 1) % h][(x) % w] + + fire[(y + 1) % h][(x + 1) % w] + + fire[(y + 2) % h][(x) % w]) + * 100) / (400 + (100 - strength)); + if (fire[y][x] < cutoff) fire[y][x] = 0; + //if (fire[y][x] ==255) color [y][x] = palend; + else color [y][x] = static_cast(basecol + (fire[y][x] / divider) * dir); + } + } + engine->ReleaseBitmapSurface(firespr); + engine->ReleaseBitmapSurface(firecolorspr); + engine->NotifySpriteUpdated(sprite); + engine->NotifySpriteUpdated(masksprite); +} + +/* +unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha) +{ + //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. + //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. + //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); + //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory."); + //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr); + AGSColor *palette = engine->GetPalette (); + int i=0; + int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha); + int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha); + int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha); + //unsigned char ralpha = alpha>>2; + //unsigned char invralpha = 64-ralpha; + //if (ralpha > alpha) engine->AbortGame ("wtf"); + //int out_r = alphamultiply[(palette[fg].r>>1)][ralpha] + alphamultiply[(palette[bg].r>>1)][(invralpha)]; + //int out_g = alphamultiply[(palette[fg].g)][ralpha] + alphamultiply[(palette[bg].g)][(invralpha)]; + //int out_b = alphamultiply[(palette[fg].b>>1)][ralpha] + alphamultiply[(palette[bg].b>>1)][(invralpha)]; + out_r = (out_r + 1 + (out_r >> 8)) >> 8; + out_g = (out_g + 1 + (out_g >> 8)) >> 8; + out_b = (out_b + 1 + (out_b >> 8)) >> 8; + i = ((out_r << 11) | (out_g << 5) | out_b); + unsigned char (*clutp) = clut; + //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one. + unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one. + //engine->ReleaseBitmapSurface (clutspr); + return result; +} + +unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha) +{ + //unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. + //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. + //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); + //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory."); + //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr); + AGSColor *palette = engine->GetPalette (); + int i=0; + int add_r,add_b,add_g = 0; + char ralpha = alpha>>2; + //if (ralpha > alpha) engine->AbortGame ("wtf"); + //add_r = (((palette[fg].r>>1) * (alpha))>>8); + //add_b = (((palette[fg].b>>1) * (alpha))>>8); + //add_g = (((palette[fg].g) * (alpha))>>8); + add_r = ((alphamultiply[(palette[fg].r>>1)*64+ralpha])>>6); + add_b = ((alphamultiply[(palette[fg].b>>1)*64+ralpha])>>6); + add_g = ((alphamultiply[(palette[fg].g )*64+ralpha])>>6); + int out_r = min(31,(palette[bg].r>>1) + add_r); + int out_g = min(63, palette[bg].g + add_g); + int out_b = min(31,(palette[bg].b>>1) + add_b); + i = ((out_r << 11) | (out_g << 5) | out_b); + unsigned char (*clutp) = clut; + unsigned char result = cycle_remap [*(clutp+i)]; //Once again, to make sure that the palette slot used is the right one. + //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one. + //engine->ReleaseBitmapSurface (clutspr); + return result; +} +*/ +unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b) { + //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); + //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory."); + //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr); + int i = ((r << 11) | (g << 5) | b); + unsigned char (*clutp) = clut; + unsigned char result = *(clutp + i); + result = cycle_remap [result]; //Once again, to make sure that the palette slot used is the right one. + //engine->ReleaseBitmapSurface (clutspr); + return result; +} + +void CycleRemap(int start, int end) { + if (end > start) { + // Rotate left + int wraparound = cycle_remap [start]; + for (; start < end; ++start) { + cycle_remap [start] = cycle_remap [start + 1]; + } + cycle_remap [end] = wraparound; + } else if (end < start) { + // Rotate right + int wraparound = cycle_remap [start]; + for (; start > end; --start) { + cycle_remap [start] = cycle_remap [start - 1]; + } + cycle_remap [end] = wraparound; + + } +} + +unsigned char GetRemappedSlot(unsigned char slot) { + return cycle_remap [slot]; +} + +int LoadCLUT(int slot) { + if (engine->GetSpriteWidth(slot) != 256 || engine->GetSpriteHeight(slot) != 256) return 1; + BITMAP *clutimage = engine->GetSpriteGraphic(slot); + unsigned char **clutarray = engine->GetRawBitmapSurface(clutimage); + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + clut[y * 256 + x] = clutarray[y][x]; + } + } + clutslot = slot; + engine->ReleaseBitmapSurface(clutimage); + return 0; +} + +void SetReflections(int toggle) { + drawreflections = toggle; +} + +int IsReflectionsOn() { + return drawreflections; +} + +int GetLuminosityFromPalette(int slot) { + AGSColor *pal = engine->GetPalette(); + int lum = (pal[slot].r + + pal[slot].r + + pal[slot].r + + pal[slot].g + + pal[slot].g + + pal[slot].g + + pal[slot].g + + pal[slot].b) >> 3; + return lum; +} + + + +void SetStarsOriginPoint(int x, int y) { + Starfield.originx = x; + Starfield.originy = y; +} +void InitializeStars(int slot, int maxstars) { + int32 sw, sh = 0; + BITMAP *canvas = engine->GetSpriteGraphic(slot); + engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr); + Starfield.maxstars = maxstars; + Starfield.overscan = 20; + stars = new starstype [Starfield.maxstars]; + for (int i = 0; i < Starfield.maxstars; i++) { + stars[i].x = (float)((rand() % sw) << 1) - sw; + if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw; + stars[i].y = (float)((rand() % sh) << 1) - sh; + if (stars[i].y < 1.0 && stars[i].y > -1.0) stars[i].y = (float)sh; + stars[i].z = (float)(MAX_DEPTH); + stars[i].color = (rand() % 240); + stars[i].sprite = 0; + stars[i].maxrad = (rand() % 5); + } +} + +void IterateStars(int slot) { + long sw, sh = 0; + sw = engine->GetSpriteWidth(slot); + sh = engine->GetSpriteHeight(slot); + for (int i = 0; i < Starfield.maxstars; i++) { + stars[i].z -= Starfield.speed; + //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH; + float k = Starfield.depthmultiplier / stars[i].z; + int px = static_cast(stars[i].x * k + Starfield.originx); + int py = static_cast(stars[i].y * k + Starfield.originy); + if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) { + stars[i].x = (float)((rand() % sw) << 1) - sw; + if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw; + stars[i].y = (float)((rand() % sh) << 1) - sh; + if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh; + stars[i].z = (float)MAX_DEPTH; + //stars[i].color = (rand () %240); + } + } +} +int GetStarfieldOverscan() { + return Starfield.overscan; +} +void SetStarfieldOverscan(int overscan) { + Starfield.overscan = overscan; +} + +int GetStarfieldOriginX() { + return Starfield.originx; +} + +int GetStarfieldOriginY() { + return Starfield.originy; +} + +void SetStarfieldDepthMultiplier(int multi) { + Starfield.depthmultiplier = multi; +} + +int GetStarfieldDepthMultiplier() { + return Starfield.depthmultiplier; +} + +int GetStarfieldMaxStars() { + return Starfield.maxstars; +} + +void SetStarSpriteScaleBoost(int star, int boost) { + stars[star].scaleboost = boost; +} + +int GetStarSpriteScaleBoost(int star) { + return stars[star].scaleboost; +} + +void SetStarMaxRadius(int star, int radius) { + stars[star].maxrad = radius; +} + +int GetStarMaxRadius(int star) { + return stars[star].maxrad; +} + +void RotateStar(int star, int angle, int px, int py) { + float rsin = rot_sine_LUT[angle]; + float rcos = rot_cos_LUT[angle]; + float fPx = (float)px; + float fPy = (float)py; + float x1 = 0, y1 = 0, xRot = 0, yRot = 0; + int i = star; + x1 = stars[i].x; + y1 = stars[i].y; + xRot = fPx + rcos * (x1 - fPx) - rsin * (y1 - fPy); + yRot = fPy + rsin * (x1 - fPx) + rcos * (y1 - fPy); + stars[i].x = xRot; + stars[i].y = yRot; + i++; +} + +FLOAT_RETURN_TYPE GetStarX(int i) { + float starx = (float)stars[i].x; + RETURN_FLOAT(starx); +} + +FLOAT_RETURN_TYPE GetStarY(int i) { + float stary = (float)stars[i].y; + RETURN_FLOAT(stary); +} + +FLOAT_RETURN_TYPE GetStarZ(int i) { + float starz = (float)stars[i].z; + RETURN_FLOAT(starz); +} + +void SetStarPosition(int star, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), SCRIPT_FLOAT(z)) { + INIT_SCRIPT_FLOAT(x); + INIT_SCRIPT_FLOAT(y); + INIT_SCRIPT_FLOAT(z); + stars[star].x = x; + stars[star].y = y; + stars[star].z = z; +} + +void SetStarColor(int star, unsigned char color) { + stars[star].color = color; +} + +unsigned char GetStarColor(int star) { + return stars[star].color; +} + +void SetStarSprite(int star, int slot) { + stars[star].sprite = slot; +} + +int GetStarSprite(int star) { + return stars[star].sprite; +} + +void SetStarSpriteRange(int start, int end, int slot) { + int sfix = start; + int efix = end; + if (start > Starfield.maxstars) sfix = Starfield.maxstars - 1; + if (end > Starfield.maxstars) efix = Starfield.maxstars; + for (int i = sfix; i < efix; i++) + stars[i].sprite = slot; +} + +void DrawStars(int slot, int maskslot) { + int32 sw, sh = 0; + BITMAP *canvas = engine->GetSpriteGraphic(slot); + if (!canvas) engine->AbortGame("DrawStars: Can't load sprite slot."); + BITMAP *maskcanvas = engine->GetSpriteGraphic(maskslot); + if (!maskcanvas) engine->AbortGame("DrawStars: Can't load mask slot."); + engine->GetBitmapDimensions(canvas, &sw, &sh, nullptr); + unsigned char **screenarray = engine->GetRawBitmapSurface(canvas); + unsigned char **maskarray = engine->GetRawBitmapSurface(maskcanvas); + for (int i = 0; i < Starfield.maxstars; i++) { + //stars[i].z-= 0.5; + //if (stars[i].z < 1.0) stars[i].z = (double)MAX_DEPTH; + float k = (float)Starfield.depthmultiplier / stars[i].z; + int px = static_cast(stars[i].x * k + Starfield.originx); + int py = static_cast(stars[i].y * k + Starfield.originy); + if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) { + stars[i].x = (float)((rand() % sw) << 1) - sw; + if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw; + stars[i].y = (float)((rand() % sh) << 1) - sh; + if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh; + stars[i].z = (float)MAX_DEPTH; + //stars[i].color = (rand () %240); + } else if (stars[i].z > 0) { + int ivalue = (63 - (int)stars[i].z); + if (ivalue > 63) ivalue = 63; + else if (ivalue < 0) ivalue = 0; + unsigned char value = (unsigned char)(ivalue); + unsigned char maskcolor = value << 2; + if (stars[i].sprite > 0) { + BITMAP *origspr = engine->GetSpriteGraphic(stars[i].sprite); + int scale = (ivalue + 1) * 100 >> 6; + //int scale = 50; + if (scale < 1) scale = 1; + /* + if (scale != 100) + { + unsigned char** orig = engine->GetRawBitmapSurface (origspr); + int32 h1,h2,w1,w2=0; + double fw2,fh2; + engine->GetBitmapDimensions (origspr,&w1,&h1,NULL); + fh2 = h1 * (scale / 100.0); + fw2 = w1 * (scale / 100.0); + h2 = static_cast(fh2); + w2 = static_cast(fw2); + if (w2 < 1) w2 = 1; + if (h2 < 1) h2 = 1; + resizspr = engine->CreateBlankBitmap (w2,h2,8); + unsigned char** resized = engine->GetRawBitmapSurface (resizspr); + int x_ratio = (int)((w1<<16)/w2) +1; + int y_ratio = (int)((h1<<16)/h2) +1; + int x2, y2 ; + for (int i=0;i>16) ; + y2 = ((i*y_ratio)>>16) ; + resized [i][j] = orig [y2][x2]; + } + } + engine->ReleaseBitmapSurface (resizspr); + } + //resizspr = origspr; + int32 w,h=0; + engine->GetBitmapDimensions (resizspr,&w,&h,NULL); + unsigned char **imagemap = engine->GetRawBitmapSurface (resizspr); + int ox = px - (w>>1); + int oy = py - (h>>1); + for (int dy=0;dy= 0 && ey < sh && ey >= 0) + { + if (maskcolor > maskarray [ey][ex] && imagemap[dy][dx] > 0) + { + maskarray [ey][ex] = maskcolor; + screenarray [ey][ex] = imagemap[dy][dx]; + } + } + } + } + */ + + unsigned char **orig = engine->GetRawBitmapSurface(origspr); + int32 h1, h2, w1, w2 = 0; + double fw2, fh2; + engine->GetBitmapDimensions(origspr, &w1, &h1, nullptr); + fh2 = h1 * (scale / 100.0); + fw2 = w1 * (scale / 100.0); + h2 = static_cast(fh2); + w2 = static_cast(fw2); + if (w2 < 1) w2 = 1; + if (h2 < 1) h2 = 1; + int x_ratio = (int)((w1 << 16) / w2) + 1; + int y_ratio = (int)((h1 << 16) / h2) + 1; + int x2, y2 ; + int ox = px - (w2 >> 1); + int oy = py - (h2 >> 1); + for (int i = 0; i < h2; i++) { + int temprzy = i * y_ratio; + int ey = oy + i; + for (int j = 0; j < w2; j++) { + x2 = ((j * x_ratio) >> 16); + y2 = ((temprzy) >> 16); + int ex = ox + j; + if (ex < sw && ex >= 0 && ey < sh && ey >= 0) { + if (maskcolor > maskarray [ey][ex] && orig[y2][x2] > 0) { + maskarray [ey][ex] = maskcolor; + screenarray [ey][ex] = orig[y2][x2]; + } + } + //resized [i][j] = orig [y2][x2]; + } + } + engine->ReleaseBitmapSurface(origspr); + } else if (stars[i].sprite == 0) { + if (stars[i].maxrad == 1) { + if (px < sw && px >= 0 && py < sh && py >= 0) { + if (maskcolor > maskarray[py][px]) { + maskarray[py][px] = maskcolor; + screenarray[py][px] = stars[i].color; + } + } + } else { + int scale = ((((int)stars[i].z) * 100) / 63); + if (scale < 1) scale = 1; + int radius = (stars[i].maxrad * (100 - scale) / 100); + int radsq = radius * radius; + //unsigned char color = GetColor565 (value>>1,value,value>>1); + unsigned char color = stars[i].color; + for (int cy = -radius; cy <= radius; cy++) { //Draw a circle around the point, for the mask. + int cysq = cy * cy; + for (int cx = -radius; cx <= radius; cx++) { + int cxsq = cx * cx; + int dx = cx + px; + int dy = cy + py; + if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0) { + if (maskcolor > maskarray [dy][dx]) { + maskarray [dy][dx] = maskcolor; + screenarray [dy][dx] = color; + } + } + } + } + /* + for(int cy=-radius; cy<=radius; cy++) //Draw a circle around the point, for the color. + { + int cysq = cy*cy; + for(int cx=-radius; cx<=radius; cx++) + { + int cxsq = cx*cx; + int dx = cx+px; + int dy = cy+py; + if((cxsq+cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0) + { + if (maskarray [dy][dx] == maskcolor)screenarray [dy][dx] = color; + } + } + } + */ + } + } + } + } + engine->ReleaseBitmapSurface(canvas); + engine->ReleaseBitmapSurface(maskcanvas); + engine->NotifySpriteUpdated(slot); + engine->NotifySpriteUpdated(maskslot); +} + + +int CreateTranslucentOverlay(int id, int sprite, int alpha, int level, int ox, int oy, int mask = 0, int blendmode = 0) { + + BITMAP *testspr = engine->GetSpriteGraphic(sprite); + if (testspr) overlay[id].sprite = sprite; + else engine->AbortGame("CreateTranslucentOverlay: Invalid sprite."); + engine->ReleaseBitmapSurface(testspr); + overlay[id].level = std::max(0, std::min(level, 4)); + overlay[id].trans = std::max(0, std::min(alpha, 255)); + overlay[id].spritemask = mask; + overlay[id].x = ox; + overlay[id].y = oy; + overlay[id].enabled = true; + overlay[id].blendtype = blendmode; + return 0; +} + +int DeleteTranslucentOverlay(int id) { + overlay[id].enabled = false; + overlay[id].sprite = 0; + overlay[id].x = 0; + overlay[id].y = 0; + overlay[id].level = 0; + overlay[id].trans = 0; + return 0; +} + +int MoveTranslucentOverlay(int id, int ox, int oy) { + overlay[id].x = ox; + overlay[id].y = oy; + return 0; +} + +int GetTranslucentOverlayX(int id) { + return overlay[id].x; +} + +int GetTranslucentOverlayY(int id) { + return overlay[id].y; +} + +int GetTranslucentOverlaySprite(int id) { + return overlay[id].sprite; +} + +int GetTranslucentOverlayLevel(int id) { + return overlay[id].level; +} + +int GetTranslucentOverlayEnabled(int id) { + return overlay[id].enabled; +} + +int GetTranslucentOverlayAlpha(int id) { + return overlay[id].trans; +} + +int SetTranslucentOverlayAlpha(int id, int alpha) { + if (alpha >= 0 && alpha < 256) overlay[id].trans = alpha; + else engine->AbortGame("CreateTranslucentOverlay: Invalid alpha selected."); + return 0; +} + +int SetTranslucentOverlayEnabled(int id, int toggle) { + if (toggle > 0) overlay[id].enabled = true; + else overlay[id].enabled = false; + return 0; +} + +void SetCharacterReflected(int id, int refl) { + if (refl > 0) Reflection.Characters[id].reflect = 1; + else Reflection.Characters[id].reflect = 0; +} + +void SetObjectReflected(int id, int refl) { + if (refl > 0) Reflection.Objects[id].reflect = 1; + else Reflection.Objects[id].reflect = 0; +} + +int GetCharacterReflected(int id) { + return Reflection.Characters[id].reflect; +} + +void GetObjectReflected(int id) { + Reflection.Objects[id].reflect; +} + +void ReplaceCharacterReflectionView(int id, int view) { + Reflection.Characters[id].replaceview = view - 1; +} + +void SetObjectReflectionIgnoreScaling(int id, int wb) { + if (wb) Reflection.Objects[id].ignorescaling = 1; + else Reflection.Objects[id].ignorescaling = 0; +} + +int DrawReflections(int id, int charobj = 0) { + int32 screenw, screenh; + int32 bgw, bgh; + engine->GetScreenDimensions(&screenw, &screenh, nullptr); + BITMAP *bgmask = engine->GetBackgroundScene(1); + if (bgmask == nullptr) return 1; + //BITMAP *virtsc = engine->GetVirtualScreen(); + BITMAP *walkbehind = engine->GetRoomMask(MASK_WALKBEHIND); + //if (!virtsc) engine->AbortGame ("Can't load virtual screen."); + if (!walkbehind) engine->AbortGame("DrawRelfections: Can't load Walkbehind into memory."); + engine->GetBitmapDimensions(walkbehind, &bgw, &bgh, nullptr); + if (!bgmask) engine->AbortGame("DrawReflections: Can't load reflection mask."); + //unsigned char **charbuffer = engine->GetRawBitmapSurface (virtsc); + unsigned char **wbarray = engine->GetRawBitmapSurface(walkbehind); + unsigned char **maskarray = engine->GetRawBitmapSurface(bgmask); + //Initialize stuff + BITMAP *charsprite = nullptr; + BITMAP *charsprite2 = nullptr; + AGSCharacter *currchar; + AGSObject *currobj; + int cox, coy, coz = 0; + int scale = 0; + //Get character, and their sprite. + if (charobj == 0) { + currchar = engine->GetCharacter(id); + int view = 0; + if (Reflection.Characters[id].replaceview == 0) view = currchar->view + 1; + else view = Reflection.Characters[id].replaceview; + AGSViewFrame *vf = engine->GetViewFrame(currchar->view + 1, currchar->loop, currchar->frame); + charsprite = engine->GetSpriteGraphic(vf->pic); + long scaling = currchar->flags & CHF_NOSCALING; + if (!scaling)scale = engine->GetAreaScaling(currchar->x, currchar->y); + else scale = 100; + cox = currchar->x; + coy = currchar->y; + coz = currchar->z; + } else if (charobj == 1) { + currobj = engine->GetObject(id); + + charsprite = engine->GetSpriteGraphic(currobj->num); + if (Reflection.Objects[id].ignorescaling) scale = 100; + else scale = engine->GetAreaScaling(currobj->x, currobj->y); + cox = currobj->x; + if (currobj->baseline < 0) coy = currobj->y; + else coy = currobj->baseline; + coz = 0; + } + bool scaled = false; + int32 w, h; + engine->GetBitmapDimensions(charsprite, &w, &h, nullptr); + if (scale != 100) { + unsigned char **orig = engine->GetRawBitmapSurface(charsprite); + int h1, h2, w1, w2; + double fw2, fh2; + h1 = h; + w1 = w; + fh2 = h1 * ((double)scale / 100.0); + fw2 = w1 * ((double)scale / 100.0); + h2 = static_cast(fh2); + w2 = static_cast(fw2); + charsprite2 = engine->CreateBlankBitmap(w2, h2, 8); + unsigned char **resized = engine->GetRawBitmapSurface(charsprite2); + int x_ratio = (int)((w1 << 16) / w2) + 1; + int y_ratio = (int)((h1 << 16) / h2) + 1; + int x2, y2 ; + for (int i = 0; i < h2; i++) { + for (int j = 0; j < w2; j++) { + x2 = ((j * x_ratio) >> 16) ; + y2 = ((i * y_ratio) >> 16) ; + resized [i][j] = orig [y2][x2]; + } + } + engine->ReleaseBitmapSurface(charsprite2); + scaled = true; + w = w2; + h = h2; + } else { + charsprite2 = charsprite; + } + int transamount = 0; + unsigned char **spritearray = engine->GetRawBitmapSurface(charsprite2); + unsigned char **charbuffer = engine->GetRawBitmapSurface(rcolormap); + unsigned char **alphaarray = engine->GetRawBitmapSurface(ralphamap); + int i = h - 1, j = 0; + int32 ox = cox; + if (charobj == 0) ox = ox - (w / 2); + int32 oy = coy + coz - 1; + engine->RoomToViewport(&ox, &oy); + int yoffset = 0; + int translevel = 7; + bool dither = false; + bool dodither = false; + int counter = 0; + int rowcount = 101 - (int)(50.0 * ((double)(scale) / 100.0)); + int delay = screenh / rowcount; + int *obst; + int flipped = 0; + if (charobj == 0) { + int (*sfGetGameParameter)(int, int, int, int); + sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter")); + flipped = sfGetGameParameter(13, currchar->view + 1, currchar->loop, currchar->frame); + } else flipped = 0; + obst = new int [w]; + for (int k = 0; k < w; k++) { + obst[k] = 0; + } + while (i > 0) { + //if ((counter == delay/2-1 || counter == delay-1) && yoffset < 36) dodither = (!dodither); + if (counter == delay) { + counter = 0; + if (translevel > 0) translevel--; + } else counter++; + yoffset++; + while (j < w) { + int xoffset; + if (flipped == 1) xoffset = w - j - 1; + else xoffset = j; + int32 rx = ox + xoffset, ry = oy + yoffset; + int wbb = 0; + engine->ViewportToRoom(&rx, &ry); + if (ry > 0 && ry < bgh && rx > 0 && rx < bgw) { + if (wbarray [ry][rx] > 0) { + wbb = engine->GetWalkbehindBaseline(wbarray[ry][rx]); + } + if (maskarray[ry][rx] == 21) obst[j] = 1; + } + + //dither = (!dither); + transamount = 32 * translevel; + if (spritearray [i][j] != 0 && oy + yoffset < screenh && ox + xoffset < screenw && oy + yoffset >= 0 && ox + xoffset >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the bg. + if (wbb < ry && obst[j] == 0 && (oy > reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))])) { + //charbuffer[oy+yoffset][ox+xoffset] = MixColorAlpha (spritearray [i][j],charbuffer[oy+yoffset][ox+xoffset],transamount); + charbuffer [oy + yoffset][ox + xoffset] = spritearray [i][j]; + alphaarray [oy + yoffset][ox + xoffset] = transamount; + reflectionmap[(ox + xoffset) + (screenw * (oy + yoffset))] = oy; + } + } + j++; + } + //if (w % 2 == 0) dither = (!dither); + i--; + j = 0; + } + + delete [] obst; + if (scaled == true)engine->FreeBitmap(charsprite2); + engine->ReleaseBitmapSurface(charsprite); + //engine->ReleaseBitmapSurface (virtsc); + //engine->ReleaseBitmapSurface (clutspr); + engine->ReleaseBitmapSurface(bgmask); + engine->ReleaseBitmapSurface(walkbehind); + engine->ReleaseBitmapSurface(rcolormap); + engine->ReleaseBitmapSurface(ralphamap); + engine->MarkRegionDirty(ox, oy, ox + w, oy + h); + return 0; +} + + +int DrawTransSprite(int sprite, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) { + BITMAP *maskspr = nullptr; + unsigned char **maskarray; + if (mask > 0) maskspr = engine->GetSpriteGraphic(mask); + if (!maskspr && mask > 0) { + char maskerr [100]; + int cx; + cx = snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask); + engine->AbortGame(maskerr); + } + // Get a reference to the screen we'll draw onto + BITMAP *bgspr = engine->GetSpriteGraphic(bg); + //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); + BITMAP *spritespr = engine->GetSpriteGraphic(sprite); + if (!bgspr) engine->AbortGame("DrawTransSprite: Can't load background"); + //if (!clutspr) engine->AbortGame ("Can't load CLUT sprite into memory."); + if (!spritespr) engine->AbortGame("DrawTransSprite: Can't load overlay sprite into memory."); + // Get its surface + int32 sprw, sprh, coldepth; + int32 bgw, bgh; + engine->GetBitmapDimensions(bgspr, &bgw, &bgh, &coldepth); + engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth); + + unsigned char **bgarray = engine->GetRawBitmapSurface(bgspr); + //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr); + unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr); + if (mask > 0) maskarray = engine->GetRawBitmapSurface(maskspr); + int tloffset = 255 - translevel; + int x = 0; + int y = 0; + //int transamount = 256 * translevel; //old + while (y < sprh) { + while (x < sprw) { + if (spritearray [y][x] != 0 && y < bgh && x < bgw && y >= 0 && x >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the bg. + if (mask > 0) { + translevel = std::max(maskarray [y][x] - tloffset, 0); + } + //spritearray[y][x] = cycle_remap[clutarray [cycle_remap[bgarray[y][x]]+transamount][cycle_remap[spritearray [y][x]]]]; //old + if (blendmode == 0) spritearray[y][x] = Mix::MixColorAlpha(spritearray [y][x], bgarray[y][x], translevel, use_objpal); + else if (blendmode == 1) spritearray[y][x] = Mix::MixColorAdditive(spritearray [y][x], bgarray[y][x], translevel, use_objpal); + } + x++; + } + x = 0; + y++; + } + + // Release the screen so that the engine can continue + engine->ReleaseBitmapSurface(bgspr); + //engine->ReleaseBitmapSurface (clutspr); + engine->ReleaseBitmapSurface(spritespr); + engine->NotifySpriteUpdated(sprite); + return 0; +} + +int DrawTranslucentOverlay(int sprite, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) { + if (translevel == 0) return 0; + BITMAP *maskspr; + unsigned char **maskarray; + // Get a reference to the screen we'll draw onto + BITMAP *virtsc = engine->GetVirtualScreen(); + //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); + BITMAP *spritespr = engine->GetSpriteGraphic(sprite); + if (mask > 0) maskspr = engine->GetSpriteGraphic(mask); + if (!virtsc) engine->AbortGame("DrawTranslucentOverlay: Can't load virtual screen."); + //if (!clutspr) engine->AbortGame ("Can't load CLUT sprite into memory."); + if (!spritespr) engine->AbortGame("DrawTranslucentOverlay: Can't load overlay sprite into memory."); + // Get its surface + int32 sprw, sprh, coldepth; + int32 screenw, screenh; + engine->GetScreenDimensions(&screenw, &screenh, &coldepth); + engine->GetBitmapDimensions(spritespr, &sprw, &sprh, &coldepth); + unsigned char **charbuffer = engine->GetRawBitmapSurface(virtsc); + unsigned char **spritearray = engine->GetRawBitmapSurface(spritespr); + if (mask > 0) { + if (!maskspr && mask > 0) { + char maskerr [100]; + snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask); + engine->AbortGame(maskerr); + } + maskarray = engine->GetRawBitmapSurface(maskspr); + } + int tloffset = 255 - translevel; + int x = 0; + int y = 0; + //int transamount = 256 * translevel; //old + while (y < sprh) { + while (x < sprw) { + if (spritearray [y][x] != 0 && y + oy < screenh && x + ox < screenw && y + oy >= 0 && x + ox >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the screen. + //charbuffer[y+oy][x+ox] = cycle_remap[clutarray [cycle_remap[charbuffer[y+oy][x+ox]]+transamount][cycle_remap[spritearray [y][x]]]]; //old + if (mask > 0) { + translevel = std::max(maskarray [y][x] - tloffset, 0); + } + if (blendmode == 0) { + if (translevel == 255) { + charbuffer[y + oy][x + ox] = spritearray [y][x]; + } else charbuffer[y + oy][x + ox] = Mix::MixColorAlpha(spritearray [y][x], charbuffer[y + oy][x + ox], translevel); + } else if (blendmode == 1) charbuffer[y + oy][x + ox] = Mix::MixColorAdditive(spritearray [y][x], charbuffer[y + oy][x + ox], translevel); + } + x++; + } + x = 0; + y++; + } + + // Release the screen so that the engine can continue + long dirtywidth = ox + sprw; + if (dirtywidth > screenw) dirtywidth = screenw - 1; + long dirtyheight = oy + sprh; + if (dirtyheight > screenh) dirtywidth = screenh - 1; + engine->ReleaseBitmapSurface(virtsc); + //engine->ReleaseBitmapSurface (clutspr); + engine->ReleaseBitmapSurface(spritespr); + if (mask > 0) engine->ReleaseBitmapSurface(maskspr); + engine->MarkRegionDirty(ox, oy, dirtywidth, dirtyheight); + return 0; +} + +void AGS_EngineStartup(IAGSEngine *lpEngine) { + engine = lpEngine; + + // Make sure it's got the version with the features we need + if (engine->version < 3) { + engine->AbortGame("Engine interface is too old, need newer version of AGS."); + } + engine->RegisterScriptFunction("PALInternal::LoadCLUT^1", (void *)LoadCLUT); + engine->RegisterScriptFunction("PALInternal::CycleRemap^2", (void *)CycleRemap); + engine->RegisterScriptFunction("PALInternal::GetColor565^3", (void *)GetColor565); + engine->RegisterScriptFunction("PALInternal::GetLuminosityFromPalette^1", (void *)GetLuminosityFromPalette); + engine->RegisterScriptFunction("PALInternal::FastSin^1", (void *)AGSFastSin); + engine->RegisterScriptFunction("PALInternal::FastCos^1", (void *)AGSFastCos); + engine->RegisterScriptFunction("PALInternal::FastRoot^1", (void *)root); + engine->RegisterScriptFunction("PALInternal::GetRemappedSlot^1", (void *)GetRemappedSlot); + engine->RegisterScriptFunction("PALInternal::ResetRemapping^0", (void *)ResetRemapping); + engine->RegisterScriptFunction("PALInternal::GetModifiedBackgroundImage", (void *)GetModifiedBackgroundImage); + engine->RegisterScriptFunction("PALInternal::WriteObjectivePalette^4", (void *)WriteObjectivePalette); + engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteR^1", (void *)ReadObjectivePaletteR); + engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteB^1", (void *)ReadObjectivePaletteB); + engine->RegisterScriptFunction("PALInternal::ReadObjectivePaletteG^1", (void *)ReadObjectivePaletteG); + + engine->RegisterScriptFunction("Raycast::Render^1", (void *)Raycast_Render); + engine->RegisterScriptFunction("Raycast::LoadMap^4", (void *)LoadMap); + engine->RegisterScriptFunction("Raycast::Initialize", (void *)Init_Raycaster); + engine->RegisterScriptFunction("Raycast::MakeTextures^1", (void *)MakeTextures); + engine->RegisterScriptFunction("Raycast::MoveForward^0", (void *)MoveForward); + engine->RegisterScriptFunction("Raycast::MoveBackward^0", (void *)MoveBackward); + engine->RegisterScriptFunction("Raycast::RotateLeft^0", (void *)RotateLeft); + engine->RegisterScriptFunction("Raycast::RotateRight^0", (void *)RotateRight); + engine->RegisterScriptFunction("Raycast::SetCameraPosition^2", (void *)Ray_SetPlayerPosition); + engine->RegisterScriptFunction("Raycast::GetCameraX^0", (void *)Ray_GetPlayerX); + engine->RegisterScriptFunction("Raycast::GetCameraY^0", (void *)Ray_GetPlayerY); + engine->RegisterScriptFunction("Raycast::GetCameraAngle^0", (void *)Ray_GetPlayerAngle); + engine->RegisterScriptFunction("Raycast::SetCameraAngle^1", (void *)Ray_SetPlayerAngle); + engine->RegisterScriptFunction("Raycast::InitSprite^9", (void *)Ray_InitSprite); + engine->RegisterScriptFunction("Raycast::UnloadEngine^0", (void *)QuitCleanup); + engine->RegisterScriptFunction("Raycast::GetHotspotAtXY^2", (void *)Ray_GetHotspotAt); + engine->RegisterScriptFunction("Raycast::GetObjectAtXY^2", (void *)Ray_GetObjectAt); + engine->RegisterScriptFunction("Raycast::SetSpriteInteractObj^2", (void *)Ray_SetSpriteInteractObj); + engine->RegisterScriptFunction("Raycast::GetSpriteInteractObj^1", (void *)Ray_GetSpriteInteractObj); + engine->RegisterScriptFunction("Raycast::SetSpritePosition^3", (void *)Ray_SetSpritePosition); + engine->RegisterScriptFunction("Raycast::SetSpriteVertOffset^2", (void *)Ray_SetSpriteVertOffset); + engine->RegisterScriptFunction("Raycast::GetSpriteVertOffset^1", (void *)Ray_GetSpriteVertOffset); + engine->RegisterScriptFunction("Raycast::GetSpriteX^1", (void *)Ray_GetSpriteX); + engine->RegisterScriptFunction("Raycast::GetSpriteY^1", (void *)Ray_GetSpriteY); + engine->RegisterScriptFunction("Raycast::SetWallHotspot^2", (void *)Ray_SetWallHotspot); + engine->RegisterScriptFunction("Raycast::SetWallTextures^5", (void *)Ray_SetWallTextures); + engine->RegisterScriptFunction("Raycast::SetWallSolid^5", (void *)Ray_SetWallSolid); + engine->RegisterScriptFunction("Raycast::SetWallIgnoreLighting^5", (void *)Ray_SetWallIgnoreLighting); + engine->RegisterScriptFunction("Raycast::SetWallAlpha^5", (void *)Ray_SetWallAlpha); + engine->RegisterScriptFunction("Raycast::SetWallBlendType^5", (void *)Ray_SetWallBlendType); + engine->RegisterScriptFunction("Raycast::GetMoveSpeed^0", (void *)Ray_GetMoveSpeed); + engine->RegisterScriptFunction("Raycast::SetMoveSpeed^1", (void *)Ray_SetMoveSpeed); + engine->RegisterScriptFunction("Raycast::GetRotSpeed^0", (void *)Ray_GetRotSpeed); + engine->RegisterScriptFunction("Raycast::SetRotSpeed^1", (void *)Ray_SetRotSpeed); + engine->RegisterScriptFunction("Raycast::GetWallAt^2", (void *)Ray_GetWallAt); + engine->RegisterScriptFunction("Raycast::GetLightAt^2", (void *)Ray_GetLightAt); + engine->RegisterScriptFunction("Raycast::SetLightAt^3", (void *)Ray_SetLightAt); + engine->RegisterScriptFunction("Raycast::SetWallAt^3", (void *)Ray_SetWallAt); + engine->RegisterScriptFunction("Raycast::SetPlaneY^1", (void *)Ray_SetPlaneY); + engine->RegisterScriptFunction("Raycast::GetDistanceAt^2", (void *)Ray_GetDistanceAt); + engine->RegisterScriptFunction("Raycast::GetSpriteAngle^1", (void *)Ray_GetSpriteAngle); + engine->RegisterScriptFunction("Raycast::SetSpriteAngle^2", (void *)Ray_SetSpriteAngle); + engine->RegisterScriptFunction("Raycast::SetSpriteView^2", (void *)Ray_SetSpriteView); + engine->RegisterScriptFunction("Raycast::GetSpriteView^1", (void *)Ray_GetSpriteView); + engine->RegisterScriptFunction("Raycast::SetSpriteFrame^2", (void *)Ray_SetSpriteFrame); + engine->RegisterScriptFunction("Raycast::GetSpriteFrame^1", (void *)Ray_GetSpriteFrame); + engine->RegisterScriptFunction("Raycast::SetSpritePic^2", (void *)Ray_SetSpritePic); + engine->RegisterScriptFunction("Raycast::GetSpritePic^1", (void *)Ray_GetSpritePic); + engine->RegisterScriptFunction("Raycast::SetSkyBox^1", (void *)Ray_SetSkyBox); + engine->RegisterScriptFunction("Raycast::SetSpriteAlpha^2", (void *)Ray_SetSpriteAlpha); + engine->RegisterScriptFunction("Raycast::GetSpriteAlpha^1", (void *)Ray_GetSpriteAlpha); + engine->RegisterScriptFunction("Raycast::GetSkyBox^1", (void *)Ray_GetSkyBox); + engine->RegisterScriptFunction("Raycast::SetAmbientLight^1", (void *)Ray_SetAmbientLight); + engine->RegisterScriptFunction("Raycast::SetAmbientColor^2", (void *)Ray_SetAmbientColor); + engine->RegisterScriptFunction("Raycast::GetAmbientLight^0", (void *)Ray_GetAmbientLight); + engine->RegisterScriptFunction("Raycast::GetAmbientWeight^0", (void *)Ray_GetAmbientWeight); + engine->RegisterScriptFunction("Raycast::GetTileX_At^2", (void *)Ray_GetTileX_At); + engine->RegisterScriptFunction("Raycast::GetTileY_At^2", (void *)Ray_GetTileY_At); + engine->RegisterScriptFunction("Raycast::DrawTile^2", (void *)Ray_DrawTile); + engine->RegisterScriptFunction("Raycast::DrawOntoTile^2", (void *)Ray_DrawOntoTile); + engine->RegisterScriptFunction("Raycast::SetNoClip^1", (void *)Ray_SetNoClip); + engine->RegisterScriptFunction("Raycast::GetNoClip^0", (void *)Ray_GetNoClip); + engine->RegisterScriptFunction("Raycast::GetSpriteScaleX^1", (void *)Ray_GetSpriteScaleX); + engine->RegisterScriptFunction("Raycast::SetSpriteScaleX^2", (void *)Ray_SetSpriteScaleX); + engine->RegisterScriptFunction("Raycast::GetSpriteScaleY^1", (void *)Ray_GetSpriteScaleY); + engine->RegisterScriptFunction("Raycast::SetSpriteScaleY^2", (void *)Ray_SetSpriteScaleY); + engine->RegisterScriptFunction("Raycast::GetSpriteBlendType^1", (void *)Ray_GetSpriteBlendType); + engine->RegisterScriptFunction("Raycast::SetSpriteBlendType^2", (void *)Ray_SetSpriteBlendType); + + + engine->RegisterScriptFunction("Raycast::SetFloorAt^3", (void *)Ray_SetFloorAt); + engine->RegisterScriptFunction("Raycast::SetCeilingAt^3", (void *)Ray_SetCeilingAt); + engine->RegisterScriptFunction("Raycast::GetCeilingAt^2", (void *)Ray_GetCeilingAt); + engine->RegisterScriptFunction("Raycast::GetFloorAt^2", (void *)Ray_GetFloorAt); + engine->RegisterScriptFunction("Raycast::GetLightingAt^2", (void *)Ray_GetLightingAt); + engine->RegisterScriptFunction("Raycast::SetLightingAt^3", (void *)Ray_SetLightingAt); + engine->RegisterScriptFunction("Raycast::GetWallHotspot^1", (void *)Ray_GetWallHotspot); + engine->RegisterScriptFunction("Raycast::GetWallTexture^2", (void *)Ray_GetWallTexture); + engine->RegisterScriptFunction("Raycast::GetWallSolid^2", (void *)Ray_GetWallSolid); + engine->RegisterScriptFunction("Raycast::GetWallIgnoreLighting^2", (void *)Ray_GetWallIgnoreLighting); + engine->RegisterScriptFunction("Raycast::GetWallAlpha^2", (void *)Ray_GetWallAlpha); + engine->RegisterScriptFunction("Raycast::GetWallBlendType^2", (void *)Ray_GetWallBlendType); + engine->RegisterScriptFunction("Raycast::SelectTile^3", (void *)Ray_SelectTile); + engine->RegisterScriptFunction("Raycast::HasSeenTile^2", (void *)Ray_HasSeenTile); + + engine->RegisterScriptFunction("LensDistort::SetPos^2", (void *)SetLensPos); + engine->RegisterScriptFunction("LensDistort::GetX^0", (void *)GetLensX); + engine->RegisterScriptFunction("LensDistort::GetY^0", (void *)GetLensY); + engine->RegisterScriptFunction("LensDistort::Set^1", (void *)SetLensDrawn); + engine->RegisterScriptFunction("LensDistort::IsDrawn^0", (void *)GetLensDrawn); + engine->RegisterScriptFunction("LensDistort::SetOffsetClamp^1", (void *)SetLensOffsetClamp); + engine->RegisterScriptFunction("LensDistort::GetOffsetClamp^0", (void *)GetLensOffsetClamp); + engine->RegisterScriptFunction("LensDistort::GetLevel^0", (void *)GetLensLevel); + engine->RegisterScriptFunction("LensDistort::SetLevel^1", (void *)GetLensLevel); + engine->RegisterScriptFunction("LensDistort::Initialize^6", (void *)LensInitialize); + + engine->RegisterScriptFunction("Translucence::CreateOverlay^8", (void *)CreateTranslucentOverlay); + engine->RegisterScriptFunction("Translucence::DeleteOverlay^1", (void *)DeleteTranslucentOverlay); + engine->RegisterScriptFunction("Translucence::Move^3", (void *)MoveTranslucentOverlay); + engine->RegisterScriptFunction("Translucence::GetOverlayX^1", (void *)GetTranslucentOverlayX); + engine->RegisterScriptFunction("Translucence::GetOverlayY^1", (void *)GetTranslucentOverlayY); + engine->RegisterScriptFunction("Translucence::GetOverlaySprite^1", (void *)GetTranslucentOverlaySprite); + engine->RegisterScriptFunction("Translucence::GetOverlayLevel^1", (void *)GetTranslucentOverlayLevel); + engine->RegisterScriptFunction("Translucence::GetOverlayEnabled^1", (void *)GetTranslucentOverlayEnabled); + engine->RegisterScriptFunction("Translucence::GetOverlayAlpha^1", (void *)GetTranslucentOverlayAlpha); + engine->RegisterScriptFunction("Translucence::SetOverlayAlpha^2", (void *)SetTranslucentOverlayAlpha); + engine->RegisterScriptFunction("Translucence::SetOverlayEnabled^2", (void *)SetTranslucentOverlayEnabled); + engine->RegisterScriptFunction("Translucence::DrawTransSprite^6", (void *)DrawTransSprite); + + engine->RegisterScriptFunction("Starfield::GetOverscan^0", (void *)GetStarfieldOverscan); + engine->RegisterScriptFunction("Starfield::SetOverscan^1", (void *)SetStarfieldOverscan); + engine->RegisterScriptFunction("Starfield::GetOriginX^0", (void *)GetStarfieldOriginX); + engine->RegisterScriptFunction("Starfield::GetOriginY^0", (void *)GetStarfieldOriginY); + engine->RegisterScriptFunction("Starfield::SetDepthMultiplier^1", (void *)SetStarfieldDepthMultiplier); + engine->RegisterScriptFunction("Starfield::GetDepthMultiplier^0", (void *)GetStarfieldDepthMultiplier); + engine->RegisterScriptFunction("Starfield::GetMaxStars^0", (void *)GetStarfieldMaxStars); + engine->RegisterScriptFunction("Starfield::SetStarSpriteScaleBoost^1", (void *)SetStarSpriteScaleBoost); + engine->RegisterScriptFunction("Starfield::GetStarSpriteScaleBoost^0", (void *)GetStarSpriteScaleBoost); + engine->RegisterScriptFunction("Starfield::SetStarMaxRadius^2", (void *)SetStarMaxRadius); + engine->RegisterScriptFunction("Starfield::GetStarMaxRadius^0", (void *)GetStarMaxRadius); + engine->RegisterScriptFunction("Starfield::GetStarX^1", (void *)GetStarX); + engine->RegisterScriptFunction("Starfield::GetStarY^1", (void *)GetStarY); + engine->RegisterScriptFunction("Starfield::GetStarZ^1", (void *)GetStarZ); + engine->RegisterScriptFunction("Starfield::SetStarPosition^4", (void *)SetStarPosition); + engine->RegisterScriptFunction("Starfield::RotateStar^4", (void *)RotateStar); + engine->RegisterScriptFunction("Starfield::SetStarColor^2", (void *)SetStarColor); + engine->RegisterScriptFunction("Starfield::GetStarColor^1", (void *)GetStarColor); + engine->RegisterScriptFunction("Starfield::SetStarSprite^2", (void *)SetStarSprite); + engine->RegisterScriptFunction("Starfield::GetStarSprite^1", (void *)GetStarSprite); + engine->RegisterScriptFunction("Starfield::SetStarSpriteRange^3", (void *)SetStarSpriteRange); + engine->RegisterScriptFunction("Starfield::Initialize^2", (void *)InitializeStars); + engine->RegisterScriptFunction("Starfield::Iterate^1", (void *)IterateStars); + engine->RegisterScriptFunction("Starfield::Draw^2", (void *)DrawStars); + engine->RegisterScriptFunction("Starfield::SetOriginPoint^2", (void *)SetStarsOriginPoint); + + engine->RegisterScriptFunction("Plasma::DoFire^8", (void *)DoFire); + engine->RegisterScriptFunction("Plasma::SetPlasmaType^5", (void *)SetPlasmaType); + engine->RegisterScriptFunction("Plasma::ResetPlasmaSettings^0", (void *)ResetPlasmaSettings); + engine->RegisterScriptFunction("Plasma::DrawPlasma^3", (void *)DrawPlasma); + engine->RegisterScriptFunction("Plasma::SetRootType^1", (void *)SetPlasmaRootType); + engine->RegisterScriptFunction("Plasma::GetRootType^0", (void *)GetPlasmaRootType); + + engine->RegisterScriptFunction("Reflections::Set^1", (void *)SetReflections); + engine->RegisterScriptFunction("Reflections::IsReflecting^0", (void *)IsReflectionsOn); + engine->RegisterScriptFunction("Reflections::SetCharacterReflected^2", (void *)SetCharacterReflected); + engine->RegisterScriptFunction("Reflections::GetCharacterReflected^1", (void *)GetCharacterReflected); + engine->RegisterScriptFunction("Reflections::SetObjectReflected^2", (void *)SetObjectReflected); + engine->RegisterScriptFunction("Reflections::GetObjectReflected^1", (void *)GetObjectReflected); + engine->RegisterScriptFunction("Reflections::ReplaceCharacterReflectionView^2", (void *)ReplaceCharacterReflectionView); + engine->RegisterScriptFunction("Reflections::SetObjectReflectionIgnoreScaling^2", (void *)SetObjectReflectionIgnoreScaling); + engine->RequestEventHook(AGSE_PRESCREENDRAW); + engine->RequestEventHook(AGSE_PREGUIDRAW); + engine->RequestEventHook(AGSE_POSTSCREENDRAW); + engine->RequestEventHook(AGSE_SAVEGAME); + engine->RequestEventHook(AGSE_RESTOREGAME); + engine->RequestEventHook(AGSE_ENTERROOM); + stars = new starstype [MAX_STARS]; + Starfield.maxstars = MAX_STARS; + Starfield.depthmultiplier = 256; + Starfield.speed = 0.5; + Starfield.originx = 160; + Starfield.originy = 100; + Reflection.Characters = new charrefopt [engine->GetNumCharacters()](); + lens = new LensDistort [LENS_WIDTH * LENS_WIDTH](); + //PreMultiply_Alphas (); + plasmaroottype = 0; + Make_Sin_Lut(); + Init_Raycaster(); +} + +void AGS_EngineShutdown() { + // no work to do here - but if we had created any dynamic sprites, + // we should delete them here + delete [] Reflection.Characters; + delete [] Reflection.Objects; + //QuitCleanup (); +} + + +int AGS_EngineOnEvent(int event, int data) { + if (event == AGSE_PRESCREENDRAW && clutslot > 0) { + if (drawreflections) { + int32 sh, sw = 0; + engine->GetScreenDimensions(&sw, &sh, nullptr); + reflectionmap = new long[sw * sh](); + rcolormap = engine->CreateBlankBitmap(sw, sh, 8); + ralphamap = engine->CreateBlankBitmap(sw, sh, 8); + for (int i = 0; i < engine->GetNumCharacters(); i++) { + if (Reflection.Characters[i].reflect == 0) continue; + AGSCharacter *tempchar = engine->GetCharacter(i); + if (tempchar->room != engine->GetCurrentRoom()) continue; //if character isn't even in the room, go to next iteration. + int32 vx = tempchar->x; + int32 vy = tempchar->y; + engine->RoomToViewport(&vx, &vy); + AGSViewFrame *vf = engine->GetViewFrame(tempchar->view + 1, tempchar->loop, tempchar->frame); + int w = engine->GetSpriteWidth(vf->pic); + int h = engine->GetSpriteHeight(vf->pic); + vx = vx - (w / 2); + int32 vxmax = vx + w; + int32 vymax = vy + h; + if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration + DrawReflections(i, 0); + } + for (int i = 0; i < engine->GetNumObjects(); i++) { + if (Reflection.Objects[i].reflect == 0) continue; + AGSObject *tempobj = engine->GetObject(i); + if (!tempobj->on) continue; + int32 vx = tempobj->x; + int32 vy = tempobj->baseline - tempobj->y; + engine->RoomToViewport(&vx, &vy); + int32 w = engine->GetSpriteWidth(tempobj->num); + int32 h = engine->GetSpriteHeight(tempobj->num); + int32 vxmax = vx + w; + int32 vymax = vy + h; + if (vxmax < 0 || vy > sh || vx > sw || vymax < 0) continue; //if all of the sprite is off screen in any direction, go to next iteration + DrawReflections(i, 1); + } + BITMAP *virtsc = engine->GetVirtualScreen(); + unsigned char **screenbuffer = engine->GetRawBitmapSurface(virtsc); + unsigned char **colorbuffer = engine->GetRawBitmapSurface(rcolormap); + unsigned char **alphabuffer = engine->GetRawBitmapSurface(ralphamap); + for (int y = 0; y < sh; y++) + for (int x = 0; x < sw; x++) + screenbuffer[y][x] = Mix::MixColorAlpha(colorbuffer[y][x], screenbuffer[y][x], alphabuffer[y][x]); + engine->ReleaseBitmapSurface(rcolormap); + engine->ReleaseBitmapSurface(ralphamap); + engine->ReleaseBitmapSurface(virtsc); + engine->FreeBitmap(rcolormap); + engine->FreeBitmap(ralphamap); + delete [] reflectionmap; + } + int i = 0; + if (LensOption.draw == 1 && LensOption.level == 0) DrawLens(LensOption.x, LensOption.y); + while (i < MAX_OVERLAYS) { + if (overlay[i].enabled && overlay[i].level == 0) { + DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype); + } + i++; + } + if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y); + } + if (event == AGSE_PREGUIDRAW && clutslot > 0) { + int i = 0; + if (LensOption.draw == 1 && LensOption.level == 1) DrawLens(LensOption.x, LensOption.y); + while (i < MAX_OVERLAYS) { + if (overlay[i].enabled && overlay[i].level == 1) { + DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype); + } + i++; + } + if (LensOption.draw == 1 && LensOption.level == 2) DrawLens(LensOption.x, LensOption.y); + } + if (event == AGSE_POSTSCREENDRAW && clutslot > 0) { + int i = 0; + if (LensOption.draw == 1 && LensOption.level == 3) DrawLens(LensOption.x, LensOption.y); + while (i < MAX_OVERLAYS) { + if (overlay[i].enabled && overlay[i].level == 2) { + DrawTranslucentOverlay(overlay[i].sprite, overlay[i].trans, overlay[i].x, overlay[i].y, overlay[i].spritemask, overlay[i].blendtype); + } + i++; + } + if (LensOption.draw == 1 && LensOption.level == 4) DrawLens(LensOption.x, LensOption.y); + } + if (event == AGSE_SAVEGAME) { + for (int i = 0; i < MAX_OVERLAYS; ++i) { + engine->FWrite(&overlay[i].sprite, sizeof(int), data); + engine->FWrite(&overlay[i].spritemask, sizeof(int), data); + engine->FWrite(&overlay[i].x, sizeof(int), data); + engine->FWrite(&overlay[i].y, sizeof(int), data); + engine->FWrite(&overlay[i].level, sizeof(int), data); + engine->FWrite(&overlay[i].trans, sizeof(int), data); + engine->FWrite(&overlay[i].blendtype, sizeof(int), data); + engine->FWrite(&overlay[i].enabled, sizeof(bool), data); + } + engine->FWrite(&clutslot, sizeof(int), data); + engine->FWrite(&drawreflections, sizeof(int), data); + for (int j = 0; j < 256; ++j) { + engine->FWrite(&cycle_remap[j], sizeof(unsigned char), data); + } + for (int j = 0; j < 256; ++j) { + engine->FWrite(&objectivepal[j].r, sizeof(unsigned char), data); + engine->FWrite(&objectivepal[j].b, sizeof(unsigned char), data); + engine->FWrite(&objectivepal[j].g, sizeof(unsigned char), data); + } + for (int j = 0; j < 256; ++j) { + engine->FWrite(&sprite[j].x, sizeof(double), data); + engine->FWrite(&sprite[j].y, sizeof(double), data); + engine->FWrite(&sprite[j].texture, sizeof(int), data); + engine->FWrite(&sprite[j].alpha, sizeof(unsigned char), data); + engine->FWrite(&sprite[j].uDivW, sizeof(double), data); + engine->FWrite(&sprite[j].uDivH, sizeof(double), data); + engine->FWrite(&sprite[j].vMove, sizeof(double), data); + engine->FWrite(&sprite[j].hMove, sizeof(double), data); + engine->FWrite(&sprite[j].objectinteract, sizeof(char), data); + engine->FWrite(&sprite[j].view, sizeof(int), data); + engine->FWrite(&sprite[j].frame, sizeof(int), data); + engine->FWrite(&sprite[j].angle, sizeof(int), data); + } + for (int j = 0; j < 256; ++j) { + for (int k = 0; k < 4; ++k) { + engine->FWrite(&wallData[j].texture[k], sizeof(int), data); + engine->FWrite(&wallData[j].solid[k], sizeof(int), data); + engine->FWrite(&wallData[j].ignorelighting[k], sizeof(int), data); + engine->FWrite(&wallData[j].alpha[k], sizeof(int), data); + engine->FWrite(&wallData[j].blendtype[k], sizeof(int), data); + engine->FWrite(&wallData[j].mask[k], sizeof(int), data); + } + engine->FWrite(&wallData[j].hotspotinteract, sizeof(char), data); + } + engine->FWrite(&raycastOn, sizeof(bool), data); + engine->FWrite(&heightmapOn, sizeof(bool), data); + engine->FWrite(&posX, sizeof(double), data); + engine->FWrite(&posY, sizeof(double), data); + engine->FWrite(&dirX, sizeof(double), data); + engine->FWrite(&dirY, sizeof(double), data); + engine->FWrite(&planeX, sizeof(double), data); + engine->FWrite(&planeY, sizeof(double), data); + engine->FWrite(&moveSpeed, sizeof(double), data); + engine->FWrite(&rotSpeed, sizeof(double), data); + if (raycastOn) { //If the raycaster is active, we have additional data to save. + for (int i = 0; i < mapWidth; ++i) + for (int j = 0; j < mapHeight; ++j) { + engine->FWrite(&worldMap [i][j], sizeof(unsigned char), data); + engine->FWrite(&lightMap [i][j], sizeof(unsigned char), data); + engine->FWrite(&ceilingMap [i][j], sizeof(int), data); + engine->FWrite(&floorMap [i][j], sizeof(int), data); + engine->FWrite(&heightMap [i][j], sizeof(int), data); + } + } + engine->FWrite(&textureSlot, sizeof(int), data); + engine->FWrite(&skybox, sizeof(int), data); + engine->FWrite(&ambientlight, sizeof(int), data); + } + if (event == AGSE_RESTOREGAME) { + + + for (int i = 0; i < MAX_OVERLAYS; ++i) { + engine->FRead(&overlay[i].sprite, sizeof(int), data); + engine->FRead(&overlay[i].spritemask, sizeof(int), data); + engine->FRead(&overlay[i].x, sizeof(int), data); + engine->FRead(&overlay[i].y, sizeof(int), data); + engine->FRead(&overlay[i].level, sizeof(int), data); + engine->FRead(&overlay[i].trans, sizeof(int), data); + engine->FRead(&overlay[i].blendtype, sizeof(int), data); + engine->FRead(&overlay[i].enabled, sizeof(bool), data); + } + engine->FRead(&clutslot, sizeof(int), data); + engine->FRead(&drawreflections, sizeof(int), data); + for (int j = 0; j < 256; ++j) { + engine->FRead(&cycle_remap[j], sizeof(unsigned char), data); + } + for (int j = 0; j < 256; ++j) { //Save Objective Palette, for palette mixing. + engine->FRead(&objectivepal[j].r, sizeof(unsigned char), data); + engine->FRead(&objectivepal[j].b, sizeof(unsigned char), data); + engine->FRead(&objectivepal[j].g, sizeof(unsigned char), data); + } + for (int j = 0; j < 256; ++j) { //Save Raycaster Sprite struct, 256 instances. + engine->FRead(&sprite[j].x, sizeof(double), data); + engine->FRead(&sprite[j].y, sizeof(double), data); + engine->FRead(&sprite[j].texture, sizeof(int), data); + engine->FRead(&sprite[j].alpha, sizeof(unsigned char), data); + engine->FRead(&sprite[j].uDivW, sizeof(double), data); + engine->FRead(&sprite[j].uDivH, sizeof(double), data); + engine->FRead(&sprite[j].vMove, sizeof(double), data); + engine->FRead(&sprite[j].hMove, sizeof(double), data); + engine->FRead(&sprite[j].objectinteract, sizeof(char), data); + engine->FRead(&sprite[j].view, sizeof(int), data); + engine->FRead(&sprite[j].frame, sizeof(int), data); + engine->FRead(&sprite[j].angle, sizeof(int), data); + } + for (int j = 0; j < 256; ++j) { //Save Raycaster wall type data. + for (int k = 0; k < 4; ++k) { + engine->FRead(&wallData[j].texture[k], sizeof(int), data); + engine->FRead(&wallData[j].solid[k], sizeof(int), data); + engine->FRead(&wallData[j].ignorelighting[k], sizeof(int), data); + engine->FRead(&wallData[j].alpha[k], sizeof(int), data); + engine->FRead(&wallData[j].blendtype[k], sizeof(int), data); + engine->FRead(&wallData[j].mask[k], sizeof(int), data); + } + engine->FRead(&wallData[j].hotspotinteract, sizeof(char), data); + } + //Delete worldmap data if it exists. + engine->FRead(&raycastOn, sizeof(bool), data); + engine->FRead(&heightmapOn, sizeof(bool), data); + engine->FRead(&posX, sizeof(double), data); + engine->FRead(&posY, sizeof(double), data); + engine->FRead(&dirX, sizeof(double), data); + engine->FRead(&dirY, sizeof(double), data); + engine->FRead(&planeX, sizeof(double), data); + engine->FRead(&planeY, sizeof(double), data); + engine->FRead(&moveSpeed, sizeof(double), data); + engine->FRead(&rotSpeed, sizeof(double), data); + if (raycastOn) { //If the raycaster is currently running, we have additional data to load. + for (int i = 0; i < mapWidth; ++i) { + for (int j = 0; j < mapHeight; ++j) { + engine->FRead(&worldMap [i][j], sizeof(unsigned char), data); + engine->FRead(&lightMap [i][j], sizeof(unsigned char), data); + engine->FRead(&ceilingMap [i][j], sizeof(int), data); + engine->FRead(&floorMap [i][j], sizeof(int), data); + engine->FRead(&heightMap [i][j], sizeof(int), data); + seenMap [i][j] = 0; + } + } + + //Reinitialize all the buffers and stuff. + + } + engine->FRead(&textureSlot, sizeof(int), data); + if (textureSlot) MakeTextures(textureSlot); + engine->FRead(&skybox, sizeof(int), data); + engine->FRead(&ambientlight, sizeof(int), data); + LoadCLUT(clutslot); + } + if (event == AGSE_ENTERROOM) { + ResetRemapping(); + delete[] Reflection.Objects; + Reflection.Objects = new objrefopt [engine->GetNumObjects()](); + } + return 0; +} + +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { + return 0; +} +void AGS_EngineInitGfx(const char *driverID, void *data) {} + +// *** END RUN TIME **** + +#if defined(BUILTIN_PLUGINS) +} // namespace agspalrender +#endif diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.h b/engines/ags/plugins/ags_pal_render/ags_pal_render.h new file mode 100644 index 000000000000..61063daf9019 --- /dev/null +++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.h @@ -0,0 +1,14 @@ +#ifndef AGS_TOUCH_H +#define AGS_TOUCH_H + +#include "plugin/agsplugin.h" + +namespace agspalrender { +void AGS_EngineStartup(IAGSEngine *lpEngine); +void AGS_EngineShutdown(); +int AGS_EngineOnEvent(int event, int data); +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); +void AGS_EngineInitGfx(const char *driverID, void *data); +} + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/ags_pal_render/agsplugin.h b/engines/ags/plugins/ags_pal_render/agsplugin.h new file mode 100644 index 000000000000..f9fd46e6edc7 --- /dev/null +++ b/engines/ags/plugins/ags_pal_render/agsplugin.h @@ -0,0 +1,564 @@ +//============================================================================= +// +// Adventure Game Studio (AGS) +// +// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others +// The full list of copyright holders can be found in the Copyright.txt +// file, which is part of this source code distribution. +// +// The AGS source code is provided under the Artistic License 2.0. +// A copy of this license can be found in the file License.txt and at +// http://www.opensource.org/licenses/artistic-license-2.0.php +// +//============================================================================= +// +// AGS Plugin interface header file +// +// #define THIS_IS_THE_PLUGIN beforehand if including from the plugin +// +//============================================================================= + +#ifndef _AGS_PLUGIN_H +#define _AGS_PLUGIN_H + +// If the plugin isn't using DDraw, don't require the headers +#ifndef DIRECTDRAW_VERSION +typedef void *LPDIRECTDRAW2; +typedef void *LPDIRECTDRAWSURFACE2; +#endif + +#ifndef DIRECTSOUND_VERSION +typedef void *LPDIRECTSOUND; +#endif + +#ifndef DIRECTINPUT_VERSION +typedef void *LPDIRECTINPUTDEVICE; +#endif + +// If the user isn't using Allegro or WinGDI, define the BITMAP into something +#if !defined(ALLEGRO_H) && !defined(_WINGDI_) && !defined(BITMAP_DEFINED) +typedef char BITMAP; +#endif + +// If not using windows.h, define HWND +#if !defined(_WINDOWS_) && !defined(HWND) +typedef int HWND; +#endif + +// This file is distributed as part of the Plugin API docs, so +// ensure that WINDOWS_VERSION is defined (if applicable) +#if defined(_WINDOWS_) || defined(_WIN32) +#ifndef WINDOWS_VERSION +#define WINDOWS_VERSION +#endif +#endif + +// DOS engine doesn't know about stdcall / neither does Linux version +#if !defined (WINDOWS_VERSION) +#define __stdcall +#endif + +#ifndef int32 +#define int32 int +#endif + +#define AGSIFUNC(type) virtual type __stdcall + +#define MASK_WALKABLE 1 +#define MASK_WALKBEHIND 2 +#define MASK_HOTSPOT 3 +// MASK_REGIONS is interface version 11 and above only +#define MASK_REGIONS 4 + +// **** WARNING: DO NOT ALTER THESE CLASSES IN ANY WAY! +// **** CHANGING THE ORDER OF THE FUNCTIONS OR ADDING ANY VARIABLES +// **** WILL CRASH THE SYSTEM. + +struct AGSColor { + unsigned char r, g, b; + unsigned char padding; +}; + +struct AGSGameOptions { + int32 score; // player's current score + int32 usedmode; // set by ProcessClick to last cursor mode used + int32 disabled_user_interface; // >0 while in cutscene/etc + int32 gscript_timer; // obsolete + int32 debug_mode; // whether we're in debug mode + int32 globalvars[50]; // obsolete + int32 messagetime; // time left for auto-remove messages + int32 usedinv; // inventory item last used + int32 inv_top, inv_numdisp, inv_numorder, inv_numinline; + int32 text_speed; // how quickly text is removed + int32 sierra_inv_color; // background used to paint defualt inv window + int32 talkanim_speed; // animation speed of talking anims + int32 inv_item_wid, inv_item_hit; // set by SetInvDimensions + int32 speech_text_shadow; // colour of outline fonts (default black) + int32 swap_portrait_side; // sierra-style speech swap sides + int32 speech_textwindow_gui; // textwindow used for sierra-style speech + int32 follow_change_room_timer; // delay before moving following characters into new room + int32 totalscore; // maximum possible score + int32 skip_display; // how the user can skip normal Display windows + int32 no_multiloop_repeat; // for backwards compatibility + int32 roomscript_finished; // on_call finished in room + int32 used_inv_on; // inv item they clicked on + int32 no_textbg_when_voice; // no textwindow bgrnd when voice speech is used + int32 max_dialogoption_width; // max width of dialog options text window + int32 no_hicolor_fadein; // fade out but instant in for hi-color + int32 bgspeech_game_speed; // is background speech relative to game speed + int32 bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used + int32 unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay + int32 mp3_loop_before_end; // loop this time before end of track (ms) + int32 speech_music_drop; // how much to drop music volume by when speech is played + int32 in_cutscene; // we are between a StartCutscene and EndCutscene + int32 fast_forward; // player has elected to skip cutscene + int32 room_width; // width of current room (320-res co-ordinates) + int32 room_height; // height of current room (320-res co-ordinates) +}; + +// AGSCharacter.flags +#define CHF_NOSCALING 1 +#define CHF_FIXVIEW 2 // between SetCharView and ReleaseCharView +#define CHF_NOINTERACT 4 +#define CHF_NODIAGONAL 8 +#define CHF_ALWAYSIDLE 0x10 +#define CHF_NOLIGHTING 0x20 +#define CHF_NOTURNING 0x40 +#define CHF_NOWALKBEHINDS 0x80 + +struct AGSCharacter { + int32 defview; + int32 talkview; + int32 view; + int32 room, prevroom; + int32 x, y, wait; + int32 flags; + short following; + short followinfo; + int32 idleview; // the loop will be randomly picked + short idletime, idleleft; // num seconds idle before playing anim + short transparency; // if character is transparent + short baseline; + int32 activeinv; + int32 talkcolor; + int32 thinkview; + int32 reserved[2]; + short walkspeed_y, pic_yoffs; + int32 z; + int32 reserved2[5]; + short loop, frame; + short walking, animating; + short walkspeed, animspeed; + short inv[301]; + short actx, acty; + char name[40]; + char scrname[20]; + char on; +}; + +// AGSObject.flags +#define OBJF_NOINTERACT 1 // not clickable +#define OBJF_NOWALKBEHINDS 2 // ignore walk-behinds + +struct AGSObject { + int32 x, y; + int32 transparent; // current transparency setting + int32 reserved[4]; + short num; // sprite slot number + short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline + short view, loop, frame; // only used to track animation - 'num' holds the current sprite + short wait, moving; + char cycling; // is it currently animating? + char overall_speed; + char on; + char flags; +}; + +// AGSViewFrame.flags +#define FRAF_MIRRORED 1 // flipped left to right + +struct AGSViewFrame { + int32 pic; // sprite slot number + short xoffs, yoffs; + short speed; + int32 flags; + int32 sound; // play sound when this frame comes round + int32 reserved_for_future[2]; +}; + +// AGSMouseCursor.flags +#define MCF_ANIMATEMOVE 1 +#define MCF_DISABLED 2 +#define MCF_STANDARD 4 +#define MCF_ONLYANIMOVERHOTSPOT 8 + +struct AGSMouseCursor { + int32 pic; // sprite slot number + short hotx, hoty; // x,y hotspot co-ordinates + short view; // view (for animating cursors) or -1 + char name[10]; // name of cursor mode + char flags; // MCF_flags above +}; + +// The editor-to-plugin interface +class IAGSEditor { +public: + int32 version; + int32 pluginId; // used internally, do not touch this + +public: + // get the HWND of the main editor frame + AGSIFUNC(HWND) GetEditorHandle(); + // get the HWND of the current active window + AGSIFUNC(HWND) GetWindowHandle(); + // add some script to the default header + AGSIFUNC(void) RegisterScriptHeader(const char *header); + // de-register a script header (pass same pointer as when added) + AGSIFUNC(void) UnregisterScriptHeader(const char *header); + +}; + + +// Below are interface 3 and later +#define AGSE_KEYPRESS 1 +#define AGSE_MOUSECLICK 2 +#define AGSE_POSTSCREENDRAW 4 +// Below are interface 4 and later +#define AGSE_PRESCREENDRAW 8 +// Below are interface 5 and later +#define AGSE_SAVEGAME 0x10 +#define AGSE_RESTOREGAME 0x20 +// Below are interface 6 and later +#define AGSE_PREGUIDRAW 0x40 +#define AGSE_LEAVEROOM 0x80 +#define AGSE_ENTERROOM 0x100 +#define AGSE_TRANSITIONIN 0x200 +#define AGSE_TRANSITIONOUT 0x400 +// Below are interface 12 and later +#define AGSE_FINALSCREENDRAW 0x800 +#define AGSE_TRANSLATETEXT 0x1000 +// Below are interface 13 and later +#define AGSE_SCRIPTDEBUG 0x2000 +#define AGSE_AUDIODECODE 0x4000 // obsolete, no longer supported +// Below are interface 18 and later +#define AGSE_SPRITELOAD 0x8000 +// Below are interface 21 and later +#define AGSE_PRERENDER 0x10000 +// Below are interface 24 and later +#define AGSE_PRESAVEGAME 0x20000 +#define AGSE_POSTRESTOREGAME 0x40000 +#define AGSE_TOOHIGH 0x80000 + +// GetFontType font types +#define FNT_INVALID 0 +#define FNT_SCI 1 +#define FNT_TTF 2 + +// PlaySoundChannel sound types +#define PSND_WAVE 1 +#define PSND_MP3STREAM 2 +#define PSND_MP3STATIC 3 +#define PSND_OGGSTREAM 4 +#define PSND_OGGSTATIC 5 +#define PSND_MIDI 6 +#define PSND_MOD 7 + +class IAGSScriptManagedObject { +public: + // when a ref count reaches 0, this is called with the address + // of the object. Return 1 to remove the object from memory, 0 to + // leave it + virtual int Dispose(const char *address, bool force) = 0; + // return the type name of the object + virtual const char *GetType() = 0; + // serialize the object into BUFFER (which is BUFSIZE bytes) + // return number of bytes used + virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; +}; + +class IAGSManagedObjectReader { +public: + virtual void Unserialize(int key, const char *serializedData, int dataSize) = 0; +}; + +class IAGSFontRenderer { +public: + virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; + virtual void FreeMemory(int fontNumber) = 0; + virtual bool SupportsExtendedCharacters(int fontNumber) = 0; + virtual int GetTextWidth(const char *text, int fontNumber) = 0; + virtual int GetTextHeight(const char *text, int fontNumber) = 0; + virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; + virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; + virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; +}; + +// The plugin-to-engine interface +class IAGSEngine { +public: + int32 version; + int32 pluginId; // used internally, do not touch + +public: + // quit the game + AGSIFUNC(void) AbortGame(const char *reason); + // get engine version + AGSIFUNC(const char *) GetEngineVersion(); + // register a script function with the system + AGSIFUNC(void) RegisterScriptFunction(const char *name, void *address); +#ifdef WINDOWS_VERSION + // get game window handle + AGSIFUNC(HWND) GetWindowHandle(); + // get reference to main DirectDraw interface + AGSIFUNC(LPDIRECTDRAW2) GetDirectDraw2(); + // get the DDraw surface associated with a bitmap + AGSIFUNC(LPDIRECTDRAWSURFACE2) GetBitmapSurface(BITMAP *); +#endif + // get a reference to the screen bitmap + AGSIFUNC(BITMAP *) GetScreen(); + + // *** BELOW ARE INTERFACE VERSION 2 AND ABOVE ONLY + // ask the engine to call back when a certain event happens + AGSIFUNC(void) RequestEventHook(int32 event); + // get the options data saved in the editor + AGSIFUNC(int) GetSavedData(char *buffer, int32 bufsize); + + // *** BELOW ARE INTERFACE VERSION 3 AND ABOVE ONLY + // get the virtual screen + AGSIFUNC(BITMAP *) GetVirtualScreen(); + // write text to the screen in the specified font and colour + AGSIFUNC(void) DrawText(int32 x, int32 y, int32 font, int32 color, char *text); + // get screen dimensions + AGSIFUNC(void) GetScreenDimensions(int32 *width, int32 *height, int32 *coldepth); + // get screen surface to draw on + AGSIFUNC(unsigned char **) GetRawBitmapSurface(BITMAP *); + // release the surface + AGSIFUNC(void) ReleaseBitmapSurface(BITMAP *); + // get the current mouse co-ordinates + AGSIFUNC(void) GetMousePosition(int32 *x, int32 *y); + + // *** BELOW ARE INTERFACE VERSION 4 AND ABOVE ONLY + // get the current room number + AGSIFUNC(int) GetCurrentRoom(); + // get the number of background scenes in this room + AGSIFUNC(int) GetNumBackgrounds(); + // get the current background frame + AGSIFUNC(int) GetCurrentBackground(); + // get a background scene bitmap + AGSIFUNC(BITMAP *) GetBackgroundScene(int32); + // get dimensions of a bitmap + AGSIFUNC(void) GetBitmapDimensions(BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth); + + // *** BELOW ARE INTERFACE VERSION 5 AND ABOVE ONLY + // similar to fwrite - buffer, size, filehandle + AGSIFUNC(int) FWrite(void *, int32, int32); + // similar to fread - buffer, size, filehandle + AGSIFUNC(int) FRead(void *, int32, int32); + // print text, wrapping as usual + AGSIFUNC(void) DrawTextWrapped(int32 x, int32 y, int32 width, int32 font, int32 color, const char *text); + // set the current active 'screen' + AGSIFUNC(void) SetVirtualScreen(BITMAP *); + // look up a word in the parser dictionary + AGSIFUNC(int) LookupParserWord(const char *word); + // draw a bitmap to the active screen + AGSIFUNC(void) BlitBitmap(int32 x, int32 y, BITMAP *, int32 masked); + // update the mouse and music + AGSIFUNC(void) PollSystem(); + + // *** BELOW ARE INTERFACE VERSION 6 AND ABOVE ONLY + // get number of characters in game + AGSIFUNC(int) GetNumCharacters(); + // get reference to specified character struct + AGSIFUNC(AGSCharacter *) GetCharacter(int32); + // get reference to game struct + AGSIFUNC(AGSGameOptions *) GetGameOptions(); + // get reference to current palette + AGSIFUNC(AGSColor *) GetPalette(); + // update palette + AGSIFUNC(void) SetPalette(int32 start, int32 finish, AGSColor *); + + // *** BELOW ARE INTERFACE VERSION 7 AND ABOVE ONLY + // get the current player character + AGSIFUNC(int) GetPlayerCharacter(); + // adjust to viewport co-ordinates + AGSIFUNC(void) RoomToViewport(int32 *x, int32 *y); + // adjust from viewport co-ordinates + AGSIFUNC(void) ViewportToRoom(int32 *x, int32 *y); + // number of objects in current room + AGSIFUNC(int) GetNumObjects(); + // get reference to specified object + AGSIFUNC(AGSObject *) GetObject(int32); + // get sprite graphic + AGSIFUNC(BITMAP *) GetSpriteGraphic(int32); + // create a new blank bitmap + AGSIFUNC(BITMAP *) CreateBlankBitmap(int32 width, int32 height, int32 coldep); + // free a created bitamp + AGSIFUNC(void) FreeBitmap(BITMAP *); + + // *** BELOW ARE INTERFACE VERSION 8 AND ABOVE ONLY + // get one of the room area masks + AGSIFUNC(BITMAP *) GetRoomMask(int32); + + // *** BELOW ARE INTERFACE VERSION 9 AND ABOVE ONLY + // get a particular view frame + AGSIFUNC(AGSViewFrame *) GetViewFrame(int32 view, int32 loop, int32 frame); + // get the walk-behind baseline of a specific WB area + AGSIFUNC(int) GetWalkbehindBaseline(int32 walkbehind); + // get the address of a script function + AGSIFUNC(void *) GetScriptFunctionAddress(const char *funcName); + // get the transparent colour of a bitmap + AGSIFUNC(int) GetBitmapTransparentColor(BITMAP *); + // get the character scaling level at a particular point + AGSIFUNC(int) GetAreaScaling(int32 x, int32 y); + // equivalent to the text script function + AGSIFUNC(int) IsGamePaused(); + + // *** BELOW ARE INTERFACE VERSION 10 AND ABOVE ONLY + // get the raw pixel value to use for the specified AGS colour + AGSIFUNC(int) GetRawPixelColor(int32 color); + + // *** BELOW ARE INTERFACE VERSION 11 AND ABOVE ONLY + // get the width / height of the specified sprite + AGSIFUNC(int) GetSpriteWidth(int32); + AGSIFUNC(int) GetSpriteHeight(int32); + // get the dimensions of the specified string in the specified font + AGSIFUNC(void) GetTextExtent(int32 font, const char *text, int32 *width, int32 *height); + // print a message to the debug console + AGSIFUNC(void) PrintDebugConsole(const char *text); + // play a sound on the specified channel + AGSIFUNC(void) PlaySoundChannel(int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename); + // same as text script function + AGSIFUNC(int) IsChannelPlaying(int32 channel); + + // *** BELOW ARE INTERFACE VERSION 12 AND ABOVE ONLY + // invalidate a region of the virtual screen + AGSIFUNC(void) MarkRegionDirty(int32 left, int32 top, int32 right, int32 bottom); + // get mouse cursor details + AGSIFUNC(AGSMouseCursor *) GetMouseCursor(int32 cursor); + // get the various components of a pixel + AGSIFUNC(void) GetRawColorComponents(int32 coldepth, int32 color, int32 *red, int32 *green, int32 *blue, int32 *alpha); + // make a pixel colour from the supplied components + AGSIFUNC(int) MakeRawColorPixel(int32 coldepth, int32 red, int32 green, int32 blue, int32 alpha); + // get whether the font is TTF or SCI + AGSIFUNC(int) GetFontType(int32 fontNum); + // create a new dynamic sprite slot + AGSIFUNC(int) CreateDynamicSprite(int32 coldepth, int32 width, int32 height); + // free a created dynamic sprite + AGSIFUNC(void) DeleteDynamicSprite(int32 slot); + // check if a sprite has an alpha channel + AGSIFUNC(int) IsSpriteAlphaBlended(int32 slot); + + // *** BELOW ARE INTERFACE VERSION 13 AND ABOVE ONLY + // un-request an event, requested earlier with RequestEventHook + AGSIFUNC(void) UnrequestEventHook(int32 event); + // draw a translucent bitmap to the active screen + AGSIFUNC(void) BlitSpriteTranslucent(int32 x, int32 y, BITMAP *, int32 trans); + // draw a sprite to the screen, but rotated around its centre + AGSIFUNC(void) BlitSpriteRotated(int32 x, int32 y, BITMAP *, int32 angle); + + // *** BELOW ARE INTERFACE VERSION 14 AND ABOVE ONLY +#ifdef WINDOWS_VERSION + // get reference to main DirectSound interface + AGSIFUNC(LPDIRECTSOUND) GetDirectSound(); +#endif + // disable AGS sound engine + AGSIFUNC(void) DisableSound(); + // check whether a script function can be run now + AGSIFUNC(int) CanRunScriptFunctionNow(); + // call a user-defined script function + AGSIFUNC(int) CallGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0, long arg3 = 0); + + // *** BELOW ARE INTERFACE VERSION 15 AND ABOVE ONLY + // force any sprites on-screen using the slot to be updated + AGSIFUNC(void) NotifySpriteUpdated(int32 slot); + // change whether the specified sprite is a 32-bit alpha blended image + AGSIFUNC(void) SetSpriteAlphaBlended(int32 slot, int32 isAlphaBlended); + // run the specified script function whenever script engine is available + AGSIFUNC(void) QueueGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0); + // register a new dynamic managed script object + AGSIFUNC(int) RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback); + // add an object reader for the specified object type + AGSIFUNC(void) AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader); + // register an un-serialized managed script object + AGSIFUNC(void) RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback); + + // *** BELOW ARE INTERFACE VERSION 16 AND ABOVE ONLY + // get the address of a managed object based on its key + AGSIFUNC(void *) GetManagedObjectAddressByKey(int key); + // get managed object's key from its address + AGSIFUNC(int) GetManagedObjectKeyByAddress(const char *address); + + // *** BELOW ARE INTERFACE VERSION 17 AND ABOVE ONLY + // create a new script string + AGSIFUNC(const char *) CreateScriptString(const char *fromText); + + // *** BELOW ARE INTERFACE VERSION 18 AND ABOVE ONLY + // increment reference count + AGSIFUNC(int) IncrementManagedObjectRefCount(const char *address); + // decrement reference count + AGSIFUNC(int) DecrementManagedObjectRefCount(const char *address); + // set mouse position + AGSIFUNC(void) SetMousePosition(int32 x, int32 y); + // simulate the mouse being clicked + AGSIFUNC(void) SimulateMouseClick(int32 button); + // get number of waypoints on this movement path + AGSIFUNC(int) GetMovementPathWaypointCount(int32 pathId); + // get the last waypoint that the char/obj passed + AGSIFUNC(int) GetMovementPathLastWaypoint(int32 pathId); + // get the co-ordinates of the specified waypoint + AGSIFUNC(void) GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y); + // get the speeds of the specified waypoint + AGSIFUNC(void) GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed); + + // *** BELOW ARE INTERFACE VERSION 19 AND ABOVE ONLY + // get the current graphics driver ID + AGSIFUNC(const char *) GetGraphicsDriverID(); + + // *** BELOW ARE INTERFACE VERSION 22 AND ABOVE ONLY + // get whether we are running under the editor's debugger + AGSIFUNC(int) IsRunningUnderDebugger(); + // tells the engine to break into the debugger when the next line of script is run + AGSIFUNC(void) BreakIntoDebugger(); + // fills buffer with \fileName, as appropriate + AGSIFUNC(void) GetPathToFileInCompiledFolder(const char *fileName, char *buffer); + + // *** BELOW ARE INTERFACE VERSION 23 AND ABOVE ONLY +#ifdef WINDOWS_VERSION + // get reference to keyboard Direct Input device + AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputKeyboard(); + // get reference to mouse Direct Input device + AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputMouse(); +#endif + // install a replacement renderer for the specified font number + AGSIFUNC(IAGSFontRenderer *) ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer); +}; + +#ifdef THIS_IS_THE_PLUGIN + +#ifdef WINDOWS_VERSION +#define DLLEXPORT extern "C" __declspec(dllexport) +#else +// MAC VERSION: compile with -fvisibility=hidden +// gcc -dynamiclib -std=gnu99 agsplugin.c -fvisibility=hidden -o agsplugin.dylib +#define DLLEXPORT extern "C" __attribute__((visibility("default"))) +#endif + +DLLEXPORT const char *AGS_GetPluginName(void); +DLLEXPORT int AGS_EditorStartup(IAGSEditor *); +DLLEXPORT void AGS_EditorShutdown(void); +DLLEXPORT void AGS_EditorProperties(HWND); +DLLEXPORT int AGS_EditorSaveGame(char *, int); +DLLEXPORT void AGS_EditorLoadGame(char *, int); +DLLEXPORT void AGS_EngineStartup(IAGSEngine *); +DLLEXPORT void AGS_EngineShutdown(void); +DLLEXPORT int AGS_EngineOnEvent(int, int); +DLLEXPORT int AGS_EngineDebugHook(const char *, int, int); +DLLEXPORT void AGS_EngineInitGfx(const char *driverID, void *data); +// We export this to verify that we are an AGS Plugin +DLLEXPORT int AGS_PluginV2() { + return 1; +} + +#endif // THIS_IS_THE_PLUGIN + +#endif diff --git a/engines/ags/plugins/ags_pal_render/pal_render.h b/engines/ags/plugins/ags_pal_render/pal_render.h new file mode 100644 index 000000000000..09c2e6b5a5ab --- /dev/null +++ b/engines/ags/plugins/ags_pal_render/pal_render.h @@ -0,0 +1,185 @@ +#ifndef __PALGORITHMS_PALRENDER_H +#define __PALGORITHMS_PALRENDER_H + +#include "agsplugin.h" +#include // for int32_t types, __int32 is just Windows +#include // for std::max and std::min +#include // for memcpy + +#undef min +#undef max + +#ifndef _WIN32 +#define __forceinline __attribute__((always_inline)) + +#define SCRIPT_FLOAT(x) int32_t __script_float##x +#define INIT_SCRIPT_FLOAT(x) float x; std::memcpy(&x, &__script_float##x, sizeof(float)) +#define FLOAT_RETURN_TYPE int32_t +#define RETURN_FLOAT(x) int32_t __ret##x; std::memcpy(&__ret##x, &x, sizeof(float)); return __ret##x +#else +#define SCRIPT_FLOAT(x) __int32 __script_float##x +#define INIT_SCRIPT_FLOAT(x) float x; memcpy(&x, &__script_float##x, sizeof(float)) +#define FLOAT_RETURN_TYPE __int32 +#define RETURN_FLOAT(x) __int32 __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x +#endif + +#if defined(BUILTIN_PLUGINS) +namespace agspalrender { +#endif + +struct PALSTRUCT { + int r; + int b; + int g; +}; + +extern IAGSEngine *engine; +extern unsigned char clut[65536]; +extern unsigned char cycle_remap [256]; +extern const int alphamultiply [4096]; +extern PALSTRUCT objectivepal[256]; + +// this class exists solely to take advantage of g++'s +// -fvisibility-inlines-hidden option, so that these +// methods can be inlined without any trace or complaint +class Mix { +public: + +//unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha); +//unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha); + __forceinline static unsigned char MixColorAlpha(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { + unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. + //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. + AGSColor *palette = engine->GetPalette(); + int i = 0; + //int out_r = (palette[fg].r>>1) * alpha + (palette[bg].r>>1) * (255 - alpha); + //int out_g = palette[fg].g * alpha + palette[bg].g * (255 - alpha); + //int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha); + int out_r, out_g, out_b; + if (use_objpal == 0) { + out_r = (objectivepal[rfg].r >> 1) * alpha + (palette[bg].r >> 1) * (255 - alpha); + out_g = objectivepal[rfg].g * alpha + palette[bg].g * (255 - alpha); + out_b = (objectivepal[rfg].b >> 1) * alpha + (palette[bg].b >> 1) * (255 - alpha); + } else { + out_r = (objectivepal[rfg].r >> 1) * alpha + (objectivepal[bg].r >> 1) * (255 - alpha); + out_g = objectivepal[rfg].g * alpha + objectivepal[bg].g * (255 - alpha); + out_b = (objectivepal[rfg].b >> 1) * alpha + (objectivepal[bg].b >> 1) * (255 - alpha); + } + //char ralpha = std::max(0,std::min(63,alpha>>2)); + //unsigned char invralpha = 64-ralpha; + //if (ralpha > alpha) engine->AbortGame ("wtf"); + //int out_r = alphamultiply[((palette[fg].r>>1)<<6) +ralpha] + alphamultiply[((palette[bg].r>>1)<<6) +(invralpha)]; + //int out_g = alphamultiply[((palette[fg].g) <<6) +ralpha] + alphamultiply[((palette[bg].g) <<6) +(invralpha)]; + //int out_b = alphamultiply[((palette[fg].b>>1)<<6) +ralpha] + alphamultiply[((palette[bg].b>>1)<<6) +(invralpha)]; + out_r = (out_r + 1 + (out_r >> 8)) >> 8; + out_g = (out_g + 1 + (out_g >> 8)) >> 8; + out_b = (out_b + 1 + (out_b >> 8)) >> 8; + //out_r = (out_r + 1 + (out_r >> 6)) >> 6; + //out_g = (out_g + 1 + (out_g >> 6)) >> 6; + //out_b = (out_b + 1 + (out_b >> 6)) >> 6; + i = ((out_r << 11) | (out_g << 5) | out_b); + unsigned char (*clutp) = clut; + //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one. + return cycle_remap[*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one. + //engine->ReleaseBitmapSurface (clutspr); + } + + __forceinline static unsigned char MixColorLightLevel(unsigned char fg, unsigned char intensity) { + unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. + int i = 0; + //int dark_r = (((palette[fg].r>>1) * (intensity))>>8); + //int dark_b = (((palette[fg].b>>1) * (intensity))>>8); + //int dark_g = (((palette[fg].g) * (intensity))>>8); + int dark_r = (((objectivepal[rfg].r >> 1) * (intensity)) >> 8); + int dark_b = (((objectivepal[rfg].b >> 1) * (intensity)) >> 8); + int dark_g = (((objectivepal[rfg].g) * (intensity)) >> 8); + i = ((dark_r << 11) | (dark_g << 5) | dark_b); + unsigned char (*clutp) = clut; + return cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one. + } + + __forceinline static unsigned char MixColorAdditive(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { + unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. + unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. + //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); + //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory."); + //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr); + AGSColor *palette = engine->GetPalette(); + int i = 0; + int add_r, add_b, add_g = 0; + //char ralpha = std::max(0,std::min(63,alpha>>2)); + //add_r = (((palette[fg].r>>1) * (alpha))>>8); + //add_b = (((palette[fg].b>>1) * (alpha))>>8); + //add_g = (((palette[fg].g) * (alpha))>>8); + add_r = (((objectivepal[rfg].r >> 1) * (alpha)) >> 8); + add_b = (((objectivepal[rfg].b >> 1) * (alpha)) >> 8); + add_g = (((objectivepal[rfg].g) * (alpha)) >> 8); + //int a_g = std::max(0,std::min(63,alpha>>2)); + //add_r = ((alphamultiply[(palette[fg].r>>1)<<6)+ralpha])>>6); + //add_b = ((alphamultiply[(palette[fg].b>>1)<<6)+ralpha])>>6); + //add_g = ((alphamultiply[(palette[fg].g) <<6)+ralpha])>>6); + //int out_r = std::min(31,(palette[bg].r>>1) + add_r); + //int out_g = std::min(63, palette[bg].g + add_g); + //int out_b = std::min(31,(palette[bg].b>>1) + add_b); + int out_r, out_g, out_b; + if (use_objpal == 0) { + out_r = std::min(31, (palette[bg].r >> 1) + add_r); + out_g = std::min(63, palette[bg].g + add_g); + out_b = std::min(31, (palette[bg].b >> 1) + add_b); + } else { + out_r = std::min(31, (objectivepal [bg].r >> 1) + add_r); + out_g = std::min(63, objectivepal [bg].g + add_g); + out_b = std::min(31, (objectivepal [bg].b >> 1) + add_b); + } + i = ((out_r << 11) | (out_g << 5) | out_b); + unsigned char (*clutp) = clut; + unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one. + //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one. + //engine->ReleaseBitmapSurface (clutspr); + return result; + } + + __forceinline static unsigned char MixColorMultiply(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { + unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. + unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. + AGSColor *palette = engine->GetPalette(); + int i = 0; + int mul_r, mul_b, mul_g = 0; + int out_r, out_g, out_b = 0; + if (use_objpal == 0) { + mul_r = ((objectivepal[rfg].r >> 1) * (palette[rbg].r >> 1)) / 64; + mul_b = ((objectivepal[rfg].b >> 1) * (palette[rbg].b >> 1)) / 64; + mul_g = ((objectivepal[rfg].g * palette[rbg].g) / 64); + out_r = ((palette[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63; + out_g = (palette[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63; + out_b = ((palette[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63; + } else { + mul_r = ((objectivepal[rfg].r >> 1) * (objectivepal[rbg].r >> 1)) / 64; + mul_b = ((objectivepal[rfg].b >> 1) * (objectivepal[rbg].b >> 1)) / 64; + mul_g = ((objectivepal[rfg].g * objectivepal[rbg].g) / 64); + + out_r = ((objectivepal[rbg].r >> 1) * (63 - (alpha / 4)) + (mul_r * (alpha / 4))) / 63; + out_g = (objectivepal[rbg].g * (63 - (alpha / 4)) + (mul_g * (alpha / 4))) / 63; + out_b = ((objectivepal[rbg].b >> 1) * (63 - (alpha / 4)) + (mul_b * (alpha / 4))) / 63; + } + i = ((out_r << 11) | (out_g << 5) | out_b); + unsigned char (*clutp) = clut; + unsigned char result = cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one. + //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one. + //engine->ReleaseBitmapSurface (clutspr); + return result; + } + +}; + +unsigned char GetColor565(unsigned char r, unsigned char g, unsigned char b); + +unsigned short root(unsigned short x); +float FastSin(float x); +float FastCos(float x); + +#if defined(BUILTIN_PLUGINS) +} // namespace agspalrender +#endif + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/ags_pal_render/raycast.cpp b/engines/ags/plugins/ags_pal_render/raycast.cpp new file mode 100644 index 000000000000..9ce5d5c3434e --- /dev/null +++ b/engines/ags/plugins/ags_pal_render/raycast.cpp @@ -0,0 +1,1498 @@ +/* +Copyright (c) 2004-2007, Lode Vandevenne + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "raycast.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(BUILTIN_PLUGINS) +namespace agspalrender { +#endif + +#define PI (3.1415926535f) + +//Variable Declaration +bool raycastOn; +double posX = 22.0, posY = 11.5; //x and y start position +double dirX = -1.0, dirY = 0.0; //initial direction vector +double planeX = 0.0, planeY = 0.77; //the 2d raycaster version of camera plane +double moveSpeed = (1.0 / 60.0) * 3.0; //the constant value is in squares/second +double rotSpeed = (1.0 / 60.0) * 2.0; //the constant value is in radians/second +unsigned char worldMap[64][64]; +unsigned char lightMap[64][64]; +int ceilingMap[64][64]; +int floorMap[64][64]; +int heightMap[64][64]; +unsigned char seenMap[64][64]; +//int mapWidth; +//int mapHeight; +#define mapWidth 64 +#define mapHeight 64 +int textureSlot; +int ambientlight; +int ambientweight = 0; +int ambientcolor = 0; +int ambientcolorAmount = 0; + +Sprite sprite[numSprites] = {}; + + +#define sWidth 320 +#define sHeight 160 + +int editorMap [sWidth][sHeight] = {}; + +unsigned char texture[MAX_TEXTURES][texWidth * texHeight]; + +wallType wallData[256] = {}; + +//arrays used to sort the sprites +int spriteOrder[numSprites]; +double spriteTransformX[numSprites]; +double spriteTransformY[numSprites]; + +unsigned char **transcolorbuffer; +unsigned char **transalphabuffer; +double **transzbuffer; +bool *transslicedrawn; +int *transwallblendmode; +double **ZBuffer; +double *distTable; +short *interactionmap; +int skybox = 0; +bool heightmapOn; + +int noclip = 0; + +int selectedX; +int selectedY; +unsigned char selectedColor; + +void Ray_SelectTile(int x, int y, unsigned char color) { + if (x < 0 || x > mapWidth) selectedX = -1; + else if (y < 0 || y > mapWidth) selectedY = -1; + else { + selectedX = x; + selectedY = y; + selectedColor = color; + } +} + +int Ray_HasSeenTile(int x, int y) { + if (x < 0 || x > mapWidth) return -1; + else if (y < 0 || y > mapWidth) return -1; + return seenMap [x][y]; +} + +void Ray_SetNoClip(int value) { + noclip = value; +} + +int Ray_GetNoClip() { + return noclip; +} + +void Ray_DrawTile(int spr, int tile) { + BITMAP *sprite = engine->GetSpriteGraphic(spr); + unsigned char **sprarray = engine->GetRawBitmapSurface(sprite); + for (int y = 0; y < 64; ++y) + for (int x = 0; x < 64; ++x) + sprarray [y][x] = texture [tile][(texWidth * y) + x]; + engine->ReleaseBitmapSurface(sprite); +} + +void Ray_DrawOntoTile(int spr, int tile) { + BITMAP *sprite = engine->GetSpriteGraphic(spr); + unsigned char **sprarray = engine->GetRawBitmapSurface(sprite); + for (int y = 0; y < 64; ++y) + for (int x = 0; x < 64; ++x) + texture [tile][(texWidth * y) + x] = sprarray [y][x]; + engine->ReleaseBitmapSurface(sprite); +} + +int Ray_GetTileX_At(int x, int y) { + if (x < 0 || x > 319 || y < 0 || y > 159) return -1; + else return editorMap [x][y] >> 16; +} + +int Ray_GetTileY_At(int x, int y) { + if (x < 0 || x > 319 || y < 0 || y > 159) return -1; + else return editorMap [x][y] & 0x0000FFFF; +} + +void Ray_SetWallAt(int x, int y, int id) { + if (x < 0 || x >= mapWidth) return; + if (y < 0 || y >= mapHeight) return; + worldMap [x][y] = id; +} + +int Ray_GetWallAt(int x, int y) { + if (x < 0 || x >= mapWidth) return -1; + if (y < 0 || y >= mapHeight) return -1; + return worldMap [x][y]; +} + +int Ray_GetAmbientWeight() { + return ambientweight; +} + +void Ray_SetAmbientLight(int value) { + ambientlight = std::min(255, std::max(0, value)); +} + +void Ray_SetAmbientColor(int color, int amount) { + ambientcolor = color; + ambientcolorAmount = amount; +} + +int Ray_GetAmbientLight() { + return ambientlight; +} +double fsqrt(double y) { + double x, z, tempf; + unsigned long *tfptr = ((unsigned long *)&tempf) + 1; + + tempf = y; + *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */ + x = tempf; + z = y * 0.5; /* hoist out the �/2� */ + x = (1.5 * x) - (x * x) * (x * z); /* iteration formula */ + x = (1.5 * x) - (x * x) * (x * z); + x = (1.5 * x) - (x * x) * (x * z); + x = (1.5 * x) - (x * x) * (x * z); + x = (1.5 * x) - (x * x) * (x * z); + return x * y; +} + +void Ray_SetWallHotspot(int id, char hotsp) { + wallData[id].hotspotinteract = hotsp; +} + +void Ray_SetWallTextures(int id, int n, int s, int w, int e) { + wallData[id].texture[0] = n; + wallData[id].texture[1] = s; + wallData[id].texture[2] = w; + wallData[id].texture[3] = e; +} + +void Ray_SetWallSolid(int id, int n, int s, int w, int e) { + wallData[id].solid [0] = std::max(0, std::min(n, 1)); + wallData[id].solid [1] = std::max(0, std::min(s, 1)); + wallData[id].solid [2] = std::max(0, std::min(w, 1)); + wallData[id].solid [3] = std::max(0, std::min(e, 1)); +} + +void Ray_SetWallIgnoreLighting(int id, int n, int s, int w, int e) { + wallData[id].ignorelighting [0] = std::max(0, std::min(n, 1)); + wallData[id].ignorelighting [1] = std::max(0, std::min(s, 1)); + wallData[id].ignorelighting [2] = std::max(0, std::min(w, 1)); + wallData[id].ignorelighting [3] = std::max(0, std::min(e, 1)); +} + +void Ray_SetWallAlpha(int id, int n, int s, int w, int e) { + wallData[id].alpha [0] = std::max(0, std::min(n, 255)); + wallData[id].alpha [1] = std::max(0, std::min(s, 255)); + wallData[id].alpha [2] = std::max(0, std::min(w, 255)); + wallData[id].alpha [3] = std::max(0, std::min(e, 255)); +} + +void Ray_SetWallBlendType(int id, int n, int s, int w, int e) { + wallData[id].blendtype [0] = std::max(0, std::min(n, 10)); + wallData[id].blendtype [1] = std::max(0, std::min(s, 10)); + wallData[id].blendtype [2] = std::max(0, std::min(w, 10)); + wallData[id].blendtype [3] = std::max(0, std::min(e, 10)); +} + + + + +int Ray_GetWallHotspot(int id) { + return wallData[id].hotspotinteract; +} + +int Ray_GetWallTexture(int id, int dir) { + return wallData[id].texture[dir]; +} + +int Ray_GetWallSolid(int id, int dir) { + return wallData[id].solid [dir]; +} + +int Ray_GetWallIgnoreLighting(int id, int dir) { + return wallData[id].ignorelighting [dir]; +} + +int Ray_GetWallAlpha(int id, int dir) { + return wallData[id].alpha [dir]; +} + +int Ray_GetWallBlendType(int id, int dir) { + return wallData[id].blendtype [dir]; +} + + + + + +FLOAT_RETURN_TYPE Ray_GetMoveSpeed() { + float mSpeed = (float)moveSpeed; + RETURN_FLOAT(mSpeed); +} + + +void Ray_SetMoveSpeed(SCRIPT_FLOAT(speed)) { + INIT_SCRIPT_FLOAT(speed); + moveSpeed = (double)speed; +} + +FLOAT_RETURN_TYPE Ray_GetRotSpeed() { + float rSpeed = (float)rotSpeed; + RETURN_FLOAT(rSpeed); +} + +void Ray_SetRotSpeed(SCRIPT_FLOAT(speed)) { + INIT_SCRIPT_FLOAT(speed); + rotSpeed = (double)speed; +} + + +int Ray_GetLightAt(int x, int y) { + return lightMap [x][y]; +} + +void Ray_SetLightAt(int x, int y, int light) { + lightMap [x][y] = light; +} + +void Ray_SetPlaneY(SCRIPT_FLOAT(y)) { + INIT_SCRIPT_FLOAT(y); + planeY = (double)y; +} + +FLOAT_RETURN_TYPE Ray_GetPlaneY() { + float pY = (float)planeY; + RETURN_FLOAT(pY); +} + +void Ray_SetPlayerPosition(SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)) { + INIT_SCRIPT_FLOAT(x); + INIT_SCRIPT_FLOAT(y); + posX = (double)x; + posY = (double)y; +} + +FLOAT_RETURN_TYPE Ray_GetPlayerX() { + + float x = (float)posX; + RETURN_FLOAT(x); +} + +FLOAT_RETURN_TYPE Ray_GetPlayerY() { + float y = (float)posY; + RETURN_FLOAT(y); +} + +int Ray_GetPlayerAngle() { + double bgrad = atan2(dirY, dirX); + int bgdeg = (int)(bgrad / PI * 180.0) + 180; + return bgdeg % 360; +} + +void Ray_SetPlayerAngle(int angle) { + int realangle = angle % 360; + if (realangle < 0) realangle += 360; + + int anglediff = realangle - Ray_GetPlayerAngle(); + double radians = 0.0174533 * anglediff; + double oldDirX = dirX; + dirX = dirX * cos(radians) - dirY * sin(radians); + dirY = oldDirX * sin(radians) + dirY * cos(radians); + double oldPlaneX = planeX; + planeX = planeX * cos(radians) - planeY * sin(radians); + planeY = oldPlaneX * sin(radians) + planeY * cos(radians); +} + + +void LoadHeightMap(int heightmapSlot) { + int tempw = engine->GetSpriteWidth(heightmapSlot); + int temph = engine->GetSpriteHeight(heightmapSlot); + if (tempw != mapWidth || temph != mapHeight) engine->AbortGame("LoadHeightMap: Map sizes are mismatched!"); + BITMAP *heightmapBm = engine->GetSpriteGraphic(heightmapSlot); + if (!heightmapBm) engine->AbortGame("LoadHeightMap: Cannot load sprite into memory."); + unsigned char **hmArray = engine->GetRawBitmapSurface(heightmapBm); + + for (int i = 0; i < tempw; i++) { + for (int j = 0; j < temph; j++) { + heightMap[i][j] = hmArray[i][j]; + } + } + engine->ReleaseBitmapSurface(heightmapBm); + heightmapOn = true; +} + +void LoadMap(int worldmapSlot, int lightmapSlot, int ceilingmapSlot, int floormapSlot) { + int tempw = engine->GetSpriteWidth(worldmapSlot); + int temph = engine->GetSpriteHeight(worldmapSlot); + BITMAP *worldmapBm; + BITMAP *lightmapBm; + BITMAP *floormapBm; + BITMAP *ceilingmapBm; + unsigned char **wmArray; + unsigned char **lmArray; + unsigned char **fmArray; + unsigned char **cmArray; + worldmapBm = engine->GetSpriteGraphic(worldmapSlot); + if (!worldmapBm) engine->AbortGame("LoadMap: Couldn't load worldmap sprite into memory."); + wmArray = engine->GetRawBitmapSurface(worldmapBm); + if (engine->GetSpriteWidth(lightmapSlot) != tempw || engine->GetSpriteHeight(lightmapSlot) != temph) engine->AbortGame("LoadMap: Lightmap has different dimensions to worldmap."); + else { + lightmapBm = engine->GetSpriteGraphic(lightmapSlot); + if (!lightmapBm) engine->AbortGame("LoadMap: Couldn't load lightmap sprite into memory."); + lmArray = engine->GetRawBitmapSurface(lightmapBm); + } + if (engine->GetSpriteWidth(ceilingmapSlot) != tempw || engine->GetSpriteHeight(ceilingmapSlot) != temph) engine->AbortGame("LoadMap: Ceilingmap has different dimensions to worldmap."); + else { + ceilingmapBm = engine->GetSpriteGraphic(ceilingmapSlot); + if (!ceilingmapBm) engine->AbortGame("LoadMap: Couldn't load ceilingmap sprite into memory."); + cmArray = engine->GetRawBitmapSurface(ceilingmapBm); + } + if (engine->GetSpriteWidth(floormapSlot) != tempw || engine->GetSpriteHeight(floormapSlot) != temph) engine->AbortGame("LoadMap: Floormap has different dimensions to worldmap."); + else { + floormapBm = engine->GetSpriteGraphic(floormapSlot); + if (!floormapBm) engine->AbortGame("LoadMap: Couldn't load floormap sprite into memory."); + fmArray = engine->GetRawBitmapSurface(floormapBm); + } + for (int i = 0; i < tempw; i++) { + for (int j = 0; j < temph; j++) { + worldMap[i][j] = wmArray[i][j]; + lightMap[i][j] = lmArray[i][j]; + floorMap[i][j] = fmArray[i][j]; + ceilingMap[i][j] = cmArray[i][j]; + heightMap[i][j] = 0; + seenMap[i][j] = 0; + } + } + engine->ReleaseBitmapSurface(worldmapBm); + engine->ReleaseBitmapSurface(lightmapBm); + engine->ReleaseBitmapSurface(ceilingmapBm); + engine->ReleaseBitmapSurface(floormapBm); + //LoadHeightMap (31); //debug only +} + +FLOAT_RETURN_TYPE Ray_GetSpriteScaleX(int id) { + float scale = (float)sprite[id].uDivW; + RETURN_FLOAT(scale); +} + +void Ray_SetSpriteScaleX(int id, SCRIPT_FLOAT(scale)) { + INIT_SCRIPT_FLOAT(scale); + sprite[id].uDivW = scale; +} + +FLOAT_RETURN_TYPE Ray_GetSpriteScaleY(int id) { + float scale = (float)sprite[id].uDivH; + RETURN_FLOAT(scale); +} + +void Ray_SetSpriteScaleY(int id, SCRIPT_FLOAT(scale)) { + INIT_SCRIPT_FLOAT(scale); + sprite[id].uDivH = scale; +} + +int Ray_GetSpriteAlpha(int id) { + return sprite[id].alpha; +} + +void Ray_SetSpriteAlpha(int id, int alpha) { + sprite[id].alpha = alpha; +} + +int Ray_GetSpritePic(int id) { + return sprite[id].texture; +} + +void Ray_SetSpritePic(int id, int slot) { + sprite[id].texture = slot; +} + + + +int Ray_GetSpriteAngle(int id) { + return sprite[id].angle; +} + +void Ray_SetSpriteAngle(int id, int angle) { + sprite[id].angle = angle % 360; +} + +int Ray_GetSpriteInteractObj(int id) { + return sprite[id].objectinteract; +} + +void Ray_SetSpriteView(int id, int view) { + sprite[id].view = view; +} + +void Ray_SetSpriteBlendType(int id, int type) { + sprite[id].blendmode = type; +} + +int Ray_GetSpriteBlendType(int id) { + return sprite[id].blendmode; +} + + +int Ray_GetSpriteView(int id) { + return sprite[id].view; +} + +void Ray_SetSpriteFrame(int id, int frame) { + sprite[id].frame = frame; +} + +int Ray_GetSpriteFrame(int id) { + return sprite[id].frame; +} + +void Ray_SetSpriteInteractObj(int id, int obj) { + sprite[id].objectinteract = obj; +} + +void Ray_SetSpritePosition(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)) { + INIT_SCRIPT_FLOAT(x); + INIT_SCRIPT_FLOAT(y); + sprite[id].x = x; + sprite[id].y = y; +} + +void Ray_SetSpriteVertOffset(int id, SCRIPT_FLOAT(vMove)) { + INIT_SCRIPT_FLOAT(vMove); + sprite[id].vMove = vMove; +} + + +FLOAT_RETURN_TYPE Ray_GetSpriteVertOffset(int id) { + float x = (float)sprite[id].vMove; + RETURN_FLOAT(x); +} + +FLOAT_RETURN_TYPE Ray_GetSpriteX(int id) { + float x = (float)sprite[id].x; + RETURN_FLOAT(x); +} + +FLOAT_RETURN_TYPE Ray_GetSpriteY(int id) { + float y = (float)sprite[id].y; + RETURN_FLOAT(y); +} + +void Ray_InitSprite(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), int slot, unsigned char alpha, int blendmode, SCRIPT_FLOAT(scale_x), SCRIPT_FLOAT(scale_y), SCRIPT_FLOAT(vMove)) { + INIT_SCRIPT_FLOAT(x); + INIT_SCRIPT_FLOAT(y); + INIT_SCRIPT_FLOAT(scale_x); + INIT_SCRIPT_FLOAT(scale_y); + INIT_SCRIPT_FLOAT(vMove); + sprite[id].x = x; + sprite[id].y = y; + sprite[id].texture = slot; + sprite[id].alpha = alpha; + sprite[id].blendmode = blendmode; + sprite[id].uDivW = scale_x; + sprite[id].uDivH = scale_y; + sprite[id].vMove = vMove; +} + +//function used to sort the sprites +void combSort(int *order, double *dist, int amount); + +void MakeTextures(int slot) { + textureSlot = slot; + int sourceWidth = engine->GetSpriteWidth(slot); + int sourceHeight = engine->GetSpriteHeight(slot); + int max = (sourceWidth / texWidth) * (sourceHeight / texHeight); + if (max > MAX_TEXTURES) engine->AbortGame("MakeTextures: Source file has too many tiles to load."); + BITMAP *texspr = engine->GetSpriteGraphic(slot); + unsigned char **texbuffer = engine->GetRawBitmapSurface(texspr); + int numTilesX = sourceWidth / texWidth; + int numTilesY = sourceHeight / texHeight; + int totaltiles = numTilesX * numTilesY; + for (int numX = 0; numX < numTilesX; ++numX) { + for (int numY = 0; numY < numTilesY; ++numY) { + for (int x = 0; x < texWidth; ++x) + for (int y = 0; y < texHeight; ++y) { + texture[(numY * numTilesX) + numX][(texWidth * y) + x] = texbuffer [y + (texHeight * numY)][x + (texWidth * numX)]; + } + } + } + engine->ReleaseBitmapSurface(texspr); + + for (int i = 0; i < 11; i++) { + for (int j = 0; j < 4; j++) { + wallData[i].texture[j] = i; + if (i == 10) wallData[i].texture[j] = 11; + if (i > 0) wallData[i].solid[j] = 1; + else wallData[i].solid[j] = 0; + if (i != 10) wallData[i].alpha[j] = 255; + else { + wallData[i].alpha[j] = 128; + wallData[i].blendtype[j] = 0; + wallData[i].solid[j] = 0; + } + } + } + wallData[1].texture[0] = 1; + wallData[1].texture[1] = 2; + wallData[1].texture[2] = 3; + wallData[1].texture[3] = 4; + wallData[1].solid[0] = 0; + + + +} + +//double ZBuffer[screenWidth][screenHeight]; + +void Ray_SetFloorAt(int x, int y, int tex) { + if (x < 0 || x > mapWidth || y < 0 || y > mapHeight || tex > 511) return; + else floorMap[x][y] = tex; +} + +void Ray_SetCeilingAt(int x, int y, int tex) { + if (x < 0 || x > mapWidth || y < 0 || y > mapHeight || tex > 511) return; + else ceilingMap[x][y] = tex; +} + +int Ray_GetCeilingAt(int x, int y) { + if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1; + else return ceilingMap [x][y]; +} + + +int Ray_GetFloorAt(int x, int y) { + if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1; + else return floorMap [x][y]; +} + + +int Ray_GetLightingAt(int x, int y) { + if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return -1; + else { + int lighting = 0; + if (ceilingMap[x][y] == 0) { + lighting = ambientlight; + if (ambientlight < lightMap [x][y]) lighting = lightMap[x][y]; + } + return lighting; + } +} + +void Ray_SetLightingAt(int x, int y, unsigned char lighting) { + if (x < 0 || x > mapWidth || y < 0 || y > mapHeight) return; + else { + lightMap [x][y] = lighting; + } +} + +void Ray_SetSkyBox(int slot) { + BITMAP *test = engine->GetSpriteGraphic(slot); + if (test) { + skybox = slot; + } else engine->AbortGame("Ray_SetSkybox: No such sprite!"); +} + +int Ray_GetSkyBox(int slot) { + return skybox; +} + +int Ray_GetHotspotAt(int x, int y) { + if (!interactionmap) return -1; + else if (x > sWidth || x < 0 || y > sHeight || y < 0) return -1; + else return interactionmap [x * sWidth + y] & 0x00FF; +} + +int Ray_GetObjectAt(int x, int y) { + if (!interactionmap) return -1; + else if (x > sWidth || x < 0 || y > sHeight || y < 0) return -1; + else return interactionmap [x * sWidth + y] >> 8; +} + +FLOAT_RETURN_TYPE Ray_GetDistanceAt(int x, int y) { + float falsereturn = -1.0f; + if (!ZBuffer) { + RETURN_FLOAT(falsereturn); + } else if (x > sWidth || x < 0 || y > sHeight || y < 0) { + RETURN_FLOAT(falsereturn); + } else { + + float zbuf = (float)ZBuffer[x][y]; + RETURN_FLOAT(zbuf); + } +} + +void Init_Raycaster() { + if (ZBuffer) return; + if (!worldMap) return; + transcolorbuffer = new unsigned char *[sWidth]; + transalphabuffer = new unsigned char *[sWidth]; + transslicedrawn = new bool[sWidth](); + transzbuffer = new double*[sWidth]; + transwallblendmode = new int [mapWidth](); + ZBuffer = new double*[sWidth]; + distTable = new double[sHeight + (sHeight >> 1)]; + interactionmap = new short[sWidth * sHeight](); + for (int y = 0; y < sHeight + (sHeight >> 1); y++) { + distTable [y] = sHeight / (2.0 * y - sHeight); + } + for (int x = 0; x < sWidth; x++) { + transcolorbuffer[x] = new unsigned char [sHeight * (mapWidth)](); + transalphabuffer[x] = new unsigned char [sHeight * (mapWidth)](); + transzbuffer[x] = new double [sHeight * (mapWidth)](); + ZBuffer[x] = new double [sHeight](); + transslicedrawn [x] = false; + } +} + +bool rendering; +void Raycast_Render(int slot) { + ambientweight = 0; + raycastOn = true; + double playerrad = atan2(dirY, dirX) + (2.0 * PI); + rendering = true; + int32 w = sWidth, h = sHeight; + BITMAP *screen = engine->GetSpriteGraphic(slot); + if (!screen) engine->AbortGame("Raycast_Render: No valid sprite to draw on."); + engine->GetBitmapDimensions(screen, &w, &h, nullptr); + BITMAP *sbBm = engine->GetSpriteGraphic(skybox); + if (!sbBm) engine->AbortGame("Raycast_Render: No valid skybox sprite."); + if (skybox > 0) { + int bgdeg = (int)((playerrad / PI) * 180.0) + 180; + int xoffset = (int)(playerrad * 320.0); + BITMAP *virtsc = engine->GetVirtualScreen(); + engine->SetVirtualScreen(screen); + xoffset = abs(xoffset % w); + if (xoffset > 0) { + engine->BlitBitmap(xoffset - 320, 1, sbBm, false); + } + engine->BlitBitmap(xoffset, 1, sbBm, false); + engine->SetVirtualScreen(virtsc); + } + int transwallcount = 0; + unsigned char **buffer = engine->GetRawBitmapSurface(screen); + for (int x = 0; x < w; x++) { + transslicedrawn [x] = false; + for (int y = 0; y < h; y++) { + ZBuffer[x][y] = 0; + } + } + int multiplier = mapWidth; + memset(interactionmap, 0, sizeof(short) * (sHeight * sWidth)); + //start the main loop + for (int x = 0; x < w; x++) { + transwallcount = 0; + //calculate ray position and direction + double cameraX = 2 * x / double(w) - 1; //x-coordinate in camera space + double rayPosX = posX; + double rayPosY = posY; + double rayDirX = dirX + planeX * cameraX; + double rayDirY = dirY + planeY * cameraX; + + //which box of the map we're in + int mapX = int(rayPosX); + int mapY = int(rayPosY); + + //length of ray from current position to next x or y-side + double sideDistX; + double sideDistY; + + //length of ray from one x or y-side to next x or y-side + double deltaDistX = fsqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX)); + double deltaDistY = fsqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY)); + double perpWallDist; + + //what direction to step in x or y-direction (either +1 or -1) + int stepX; + int stepY; + int prevmapX = 0; + int prevmapY = 0; + int hit = 0; //was there a wall hit? + int side; //was a NS or a EW wall hit? + + //calculate step and initial sideDist + if (rayDirX < 0) { + stepX = -1; + sideDistX = (rayPosX - mapX) * deltaDistX; + } else { + stepX = 1; + sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX; + } + if (rayDirY < 0) { + stepY = -1; + sideDistY = (rayPosY - mapY) * deltaDistY; + } else { + stepY = 1; + sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY; + } + //perform DDA + bool deeper = true; + bool opposite = true; + bool oppositedrawn = false; + double wallX; //where exactly the wall was hit + int drawStart; + int drawEnd; + while (hit == 0 && deeper == true) { + if (opposite) { + rayDirX = -rayDirX; + rayDirY = -rayDirY; + stepX = -stepX; + stepY = -stepY; + if (sideDistX < sideDistY) side = 0; + else side = 1; + } else if (sideDistX < sideDistY) { //jump to next map square, OR in x-direction, OR in y-direction + sideDistX += deltaDistX; + mapX += stepX; + mapX = abs(mapX) % mapHeight; + side = 0; + if (oppositedrawn && worldMap[mapX][mapY] > 8) { + opposite = true; + oppositedrawn = false; + rayDirX = -rayDirX; + rayDirY = -rayDirY; + stepX = -stepX; + stepY = -stepY; + if (sideDistX < sideDistY) side = 0; + else side = 1; + } else { + oppositedrawn = false; + opposite = false; + } + } else { + sideDistY += deltaDistY; + mapY += stepY; + mapY = abs(mapY) % mapHeight; + side = 1; + if (oppositedrawn && worldMap[mapX][mapY] > 8) { + opposite = true; + oppositedrawn = false; + rayDirX = -rayDirX; + rayDirY = -rayDirY; + stepX = -stepX; + stepY = -stepY; + if (sideDistX < sideDistY) side = 0; + else side = 1; + } else { + oppositedrawn = false; + opposite = false; + } + } + int texside; + if (rayDirX > 0 && side == 0) texside = 0; + if (rayDirX < 0 && side == 0) texside = 1; + if (rayDirY > 0 && side == 1) texside = 2; + if (rayDirY < 0 && side == 1) texside = 3; + + //set this tile as seen. + seenMap[mapX][mapY] = 1; + //Check if ray has hit a wall + if (wallData[worldMap[mapX][mapY]].texture[texside]) { + bool ambientpixels = false; + hit = 1; //Set this to true so that by default, it's impossible to hang the engine. + deeper = false; //Set this to false so that we don't go deeper than we need to. + + //Calculate distance of perpendicular ray (oblique distance will give fisheye effect!) + if (side == 0) perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX); + else perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY); + //Calculate height of line to draw on screen + int lineHeight = abs(int(h / perpWallDist)); + + //calculate lowest and highest pixel to fill in current stripe + drawStart = -lineHeight / 2 + h / 2; + if (drawStart < 0) drawStart = 0; + drawEnd = lineHeight / 2 + h / 2; + if (drawEnd >= h) drawEnd = h; + //texturing calculations + int texNum = wallData[worldMap[mapX][mapY]].texture[texside] - 1; //1 subtracted from it so that texture 0 can be used! + if (!opposite) { + //calculate value of wallX + if (side == 1) wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX; + else wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY; + } else { + if (side == 1) wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / -rayDirY) * -rayDirX; + else wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / -rayDirX) * -rayDirY; + } + wallX -= floor((wallX)); + + //x coordinate on the texture + int wall_light = 255; + int texX = int(wallX * double(texWidth)); + if (side == 0 && rayDirX > 0) texX = texWidth - texX - 1; + if (side == 1 && rayDirY < 0) texX = texWidth - texX - 1; + bool do_ambient = false; + if (!opposite) { + if (rayDirX > 0 && side == 0) { + wall_light = lightMap [(int)mapX - 1 % mapWidth][(int)mapY] << 5; + if (ceilingMap [(int)mapX - 1 % mapWidth][(int)mapY] <= 1) do_ambient = true; + else if (texture[ceilingMap [(int)mapX - 1 % mapWidth][(int)mapY] - 1][(texWidth * (63 - texX)) + 63] == 0) do_ambient = true; + } + if (rayDirX < 0 && side == 0) { + wall_light = lightMap [(int)mapX + 1 % mapWidth][(int)mapY] << 5; + if (ceilingMap [(int)mapX + 1 % mapWidth][(int)mapY] <= 1) do_ambient = true; + else if (texture[ceilingMap [(int)mapX + 1 % mapWidth][(int)mapY] - 1][(texWidth * texX) + 0] == 0) do_ambient = true; + + } + if (rayDirY > 0 && side == 1) { + wall_light = lightMap [(int)mapX][(int)mapY - 1 % mapHeight] << 5; + if (ceilingMap [(int)mapX][(int)mapY - 1 % mapHeight] <= 1) do_ambient = true; + else if (texture[ceilingMap [(int)mapX][(int)mapY - 1 % mapHeight] - 1][(texWidth * 63) + texX] == 0) do_ambient = true; + } + if (rayDirY < 0 && side == 1) { + wall_light = lightMap [(int)mapX][(int)mapY + 1 % mapHeight] << 5; + if (ceilingMap [(int)mapX][(int)mapY + 1 % mapHeight] <= 1) do_ambient = true; + else if (texture[ceilingMap [(int)mapX][(int)mapY + 1 % mapHeight] - 1][(texWidth * 0) + 63 - texX] == 0) do_ambient = true; + } + } else if (opposite) { + wall_light = lightMap [(int)mapX][(int)mapY] << 5; + if (ceilingMap [(int)mapX][(int)mapY] <= 1) do_ambient = true; + if (rayDirX > 0 && side == 0) { + if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * (63 - texX)) + 63] == 0) do_ambient = true; + } + if (rayDirX < 0 && side == 0) { + if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * texX) + 63] == 0) do_ambient = true; + } + if (rayDirY > 0 && side == 1) { + if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * 0) + (63 - texX)] == 0) do_ambient = true; + } + if (rayDirY < 0 && side == 1) { + if (texture[ceilingMap [(int)mapX][(int)mapY] - 1][(texWidth * 63) + texX] == 0) do_ambient = true; + } + } + if (do_ambient) { + ambientpixels = true; + wall_light = std::max(wall_light, ambientlight); + } + wall_light = std::min(255, std::max(0, wall_light)); + bool alphastripe = false; + for (int y = drawStart; y < drawEnd; y++) { + if (ZBuffer[x][y] > perpWallDist || ZBuffer[x][y] == 0) { //We can draw. + int d = y * 256 - h * 128 + lineHeight * 128; //256 and 128 factors to avoid floats + int texY = ((d * texHeight) / lineHeight) / 256; + int color = texture[texNum][texWidth * texY + texX]; + if (color > 0) { + if (ambientpixels && ambientcolor) color = Mix::MixColorMultiply(ambientcolor, color, ambientcolorAmount, 1); + if (!wallData[worldMap[mapX][mapY]].ignorelighting[texside] && wall_light < 255) color = Mix::MixColorLightLevel(color, wall_light); + if (wallData[worldMap[mapX][mapY]].alpha[texside] == 255 && wallData[worldMap[mapX][mapY]].mask[texside] == 0) { + buffer[y][x] = color; + if (ambientpixels) ambientweight++; + //SET THE ZBUFFER FOR THE SPRITE CASTING + ZBuffer[x][y] = perpWallDist; //perpendicular distance is used + interactionmap [x * sWidth + y] = wallData[worldMap[mapX][mapY]].hotspotinteract; + editorMap [x][y] = ((short)mapX) << 16 | ((short)mapY); + } else { + if (transslicedrawn[x] == false) { + memset(transcolorbuffer[x], 0, sizeof(unsigned char) * (sHeight * mapWidth)); + memset(transalphabuffer[x], 0, sizeof(unsigned char) * (sHeight * mapWidth)); + //memset (transzbuffer[x],0,sizeof(double)*(sHeight*mapWidth)); + transslicedrawn[x] = true; + } + transwallblendmode[transwallcount] = wallData[worldMap[mapX][mapY]].blendtype[texside]; + int transwalloffset = transwallcount * h; + transcolorbuffer[x][transwalloffset + y] = color; + if (ambientpixels) ambientweight++; + if (wallData[worldMap[mapX][mapY]].mask[texside] == 0) transalphabuffer[x][transwalloffset + y] = wallData[worldMap[mapX][mapY]].alpha[texside]; + else { + transalphabuffer[x][transwalloffset + y] = (wallData[worldMap[mapX][mapY]].alpha[texside] + texture[wallData[worldMap[mapX][mapY]].mask[texside]][texWidth * texY + texX]) >> 1; + } + transzbuffer[x][transwalloffset + y] = perpWallDist; + hit = 0; + deeper = true; + alphastripe = true; + } + } else { + //We found transparency, we have to draw deeper. + deeper = true; + hit = 0; + } + if ((int)mapX == selectedX && (int)mapY == selectedY) { + if (texX == 0 || texX == 63 || texY == 0 || texY == 63) { + buffer[y][x] = selectedColor; + ZBuffer [x][y] = perpWallDist; + } + } + + } + } + if (alphastripe) { + if (transwallcount < mapWidth) { + transwallcount++; + } + alphastripe = false; + } + if (opposite) { + if (mapX == 0 || mapX == mapWidth || mapY == 0 || mapY == mapHeight) { + deeper = false; + hit = 0; + } + oppositedrawn = true; + if (deeper) opposite = false; + rayDirX = -rayDirX; + rayDirY = -rayDirY; + stepX = -stepX; + stepY = -stepY; + } else if (!opposite && deeper) { + opposite = true; + prevmapX = mapX; + prevmapY = mapY; + } + //End of wall drawing functions. + } else if (opposite) { + opposite = false; + //oppositedrawn = false; + rayDirX = -rayDirX; + rayDirY = -rayDirY; + stepX = -stepX; + stepY = -stepY; + } else if (!opposite && deeper) { + opposite = true; + prevmapX = mapX; + prevmapY = mapY; + } + //End of loop. + } + + //FLOOR CASTING + + double floorXWall, floorYWall; //x, y position of the floor texel at the bottom of the wall + //4 different wall directions possible + if (side == 0 && rayDirX > 0) { + floorXWall = mapX; + floorYWall = mapY + wallX; + if (opposite) floorXWall = floorXWall + 1.0; + } else if (side == 0 && rayDirX < 0) { + floorXWall = mapX + 1.0; + floorYWall = mapY + wallX; + if (opposite) floorXWall = floorXWall - 1.0; + } else if (side == 1 && rayDirY > 0) { + floorXWall = mapX + wallX; + floorYWall = mapY; + if (opposite) floorYWall = floorYWall + 1.0; + } else { + floorXWall = mapX + wallX; + floorYWall = mapY + 1.0; + if (opposite) floorYWall = floorYWall - 1.0; + } + + double distWall, distPlayer, currentDist; + + distWall = perpWallDist; + distPlayer = 0.0; + if (drawEnd < 0) drawEnd = h - 1; //becomes < 0 when the integer overflows + //draw the floor from drawEnd to the bottom of the screen + int drawdist = h; + int expandeddraw = h >> 1; + for (int y = drawEnd; y < drawdist + expandeddraw; y++) { + //currentDist = h / (2.0 * y - h); //you could make a small lookup table for this instead + currentDist = distTable[y]; + if (y > h - 1) { + if (!heightMap) break; + double weight = (currentDist - distPlayer) / (distWall - distPlayer); + + double currentFloorX = weight * floorXWall + (1.0 - weight) * posX; + double currentFloorY = weight * floorYWall + (1.0 - weight) * posY; + + int floorTexX, floorTexY; + int cmapX = (int)currentFloorX; + if (cmapX > mapWidth - 1) cmapX = mapWidth - 1; + if (cmapX < 0) cmapX = 0; + int cmapY = (int)currentFloorY; + if (cmapY > mapHeight - 1) cmapY = mapHeight - 1; + if (cmapY < 0) cmapY = 0; + if (heightMap[cmapX][cmapY] - 1 < 1) continue; + int lighting = lightMap [cmapX][cmapY] << 5; + lighting = std::min(255, std::max(0, lighting)); + floorTexX = int(currentFloorX * texWidth) % texWidth; + floorTexY = int(currentFloorY * texHeight) % texHeight; + int floorcolor = 0; + int ceilingcolor = 0; + int texpos = texWidth * floorTexY + floorTexX; + if (ceilingMap[cmapX][cmapY] - 1 > 0) { + ceilingcolor = texture[ceilingMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX]; + } + if (floorMap[cmapX][cmapY] - 1 > 0) { + floorcolor = texture[floorMap[cmapX][cmapY] - 1][texpos]; + } else continue; + if (ceilingcolor == 0) { + lighting = std::max(lighting, ambientlight); + ambientweight ++; + } + if (lighting < 255) { + if (floorcolor) floorcolor = Mix::MixColorLightLevel(floorcolor, lighting); + } + + if (heightMap && floorcolor > 0) { + if (heightMap[cmapX][cmapY] - 1 > 0) { + int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texpos] / currentDist); + if (raisedfloorstart > h - 1) continue; + if (raisedfloorstart < 0) raisedfloorstart = 0; + for (int ny = raisedfloorstart; ny < y; ny++) { + if (ny < h && (ZBuffer[x][ny] > currentDist || ZBuffer[x][ny] == 0)) { + ZBuffer[x][ny] = currentDist; //perpendicular distance is used + buffer[ny][x] = floorcolor; + interactionmap [x * sWidth + ny] = 0; + editorMap [x][ny] = ((short)mapX) << 16 | ((short)mapY); + } + } + if (raisedfloorstart < y && y == h - 1 && y == h + expandeddraw) expandeddraw ++; + } + } + } else { + double weight = (currentDist - distPlayer) / (distWall - distPlayer); + + double currentFloorX = weight * floorXWall + (1.0 - weight) * posX; + double currentFloorY = weight * floorYWall + (1.0 - weight) * posY; + + int floorTexX, floorTexY; + int cmapX = (int)currentFloorX % mapWidth; + if (cmapX < 0) cmapX = 0; + int cmapY = (int)currentFloorY % mapHeight; + if (cmapY < 0) cmapY = 0; + int lighting = lightMap [cmapX][cmapY] << 5; + lighting = std::min(255, std::max(0, lighting)); + floorTexX = int(currentFloorX * texWidth) % texWidth; + floorTexY = int(currentFloorY * texHeight) % texHeight; + int floorcolor = 0; + int ceilingcolor = 0; + if (floorMap[cmapX][cmapY] - 1 > 0) { + floorcolor = texture[floorMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX]; + } + if (ceilingMap[cmapX][cmapY] - 1 > 0) { + ceilingcolor = texture[ceilingMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX]; + } + if (ceilingcolor == 0) { + lighting = std::max(lighting, ambientlight); + ambientweight++; + } + if (lighting < 255) { + if (floorcolor) floorcolor = Mix::MixColorLightLevel(floorcolor, lighting); + if (ceilingcolor) ceilingcolor = Mix::MixColorLightLevel(ceilingcolor, lighting); + } + + if (heightMap && floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) { + if (heightMap[cmapX][cmapY] - 1 > 0) { + int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX] / currentDist); + if (raisedfloorstart > h - 1) continue; + if (raisedfloorstart < 0) raisedfloorstart = 0; + for (int ny = raisedfloorstart; ny < y; ny++) { + if (ZBuffer[x][ny] > currentDist || ZBuffer[x][ny] == 0) { + ZBuffer[x][ny] = currentDist; //perpendicular distance is used + buffer[ny][x] = floorcolor; + interactionmap [x * sWidth + ny] = 0; + editorMap [x][ny] = ((short)cmapX) << 16 | ((short)cmapY); + } + } + if (raisedfloorstart < y && y == h - 1 && y == h + expandeddraw) expandeddraw ++; + } + } + //floor + //ceiling (symmetrical!) + //SET THE ZBUFFER FOR THE SPRITE CASTING + if (floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) { + ZBuffer[x][y] = currentDist; //perpendicular distance is used + buffer[y][x] = floorcolor; + editorMap [x][y] = ((short)cmapX) << 16 | ((short)cmapY); + } else ZBuffer[x][y] = 9999999999999.0; + if (currentDist < ZBuffer[x][h - y] || ZBuffer[x][h - y] == 0) { + if (ceilingcolor > 0) { + ZBuffer[x][h - y] = currentDist; //perpendicular distance is used + buffer[h - y][x] = ceilingcolor; + } else ZBuffer[x][h - y] = 999999999999.0; + editorMap [x][h - y] = ((short)cmapX) << 16 | ((short)cmapY); + } + interactionmap [x * sWidth + y] = 0; + interactionmap [x * sWidth + (h - y)] = 0; + if ((int)cmapX == selectedX && (int)cmapY == selectedY) { + if (floorTexX == 0 || floorTexX == 63 || floorTexY == 0 || floorTexY == 63) { + buffer[y][x] = selectedColor; + ZBuffer [x][y] = perpWallDist; + buffer[h - y][x] = selectedColor; + ZBuffer [x][h - y] = perpWallDist; + } + } + + + } + } + //TRANSLUCENT WALL RENDERING + if (transslicedrawn[x] == true) { + for (int y = 0; y < h; y++) { + for (int transwalldrawn = 0; transwalldrawn < transwallcount; transwalldrawn++) { + int transwalloffset = transwalldrawn * h; + int color = transcolorbuffer[x][transwalloffset + y]; + if (color != 0) { + if (transwallblendmode[transwalldrawn] == 0) buffer[y][x] = Mix::MixColorAlpha(color, buffer[y][x], transalphabuffer[x][transwalloffset + y]); //paint pixel if it isn't black, black is the invisible color + else if (transwallblendmode[transwalldrawn] == 1) buffer[y][x] = Mix::MixColorAdditive(color, buffer[y][x], transalphabuffer[x][transwalloffset + y]); + //if (ZBuffer[x][y] > transzbuffer[transwalldrawn*h+y]) ZBuffer[x][y] = transzbuffer[transwalldrawn*h+y]; //put the sprite on the zbuffer so we can draw around it. + } + } + } + } + //End of wall loop. + } + + + //SPRITE CASTING + //sort sprites from far to close + + //Initialize Sprites for casting. + double invDet = 1.0 / (planeX * dirY - dirX * planeY); + for (int i = 0; i < numSprites; i++) { + spriteOrder[i] = i; + spriteTransformY[i] = ((posX - sprite[i].x) * (posX - sprite[i].x) + (posY - sprite[i].y) * (posY - sprite[i].y)); + } + combSort(spriteOrder, spriteTransformY, numSprites); + for (int i = 0; i < numSprites; i++) { + double spriteX = sprite[spriteOrder[i]].x - posX; + double spriteY = sprite[spriteOrder[i]].y - posY; + spriteTransformX[i] = invDet * (dirY * spriteX - dirX * spriteY); + spriteTransformY[i] = invDet * (-planeY * spriteX + planeX * spriteY); + } + + int transwalldraw = 0; + //after sorting the sprites, do the projection and draw them + for (int i = 0; i < numSprites; i++) { + int flipped = 0; + if (sprite[spriteOrder[i]].view != 0) { + + double sprrad = atan2(sprite[spriteOrder[i]].y - posY, sprite[spriteOrder[i]].x - posX); + int sprdeg = (int)(sprrad / 3.1415 * 180.0); + sprdeg = ((sprdeg + 180) + sprite[spriteOrder[i]].angle) % 360; + int loop = 0; + if (sprdeg > 336 || sprdeg < 23) loop = 0; + else if (sprdeg > 22 && sprdeg < 68) loop = 6; + else if (sprdeg > 67 && sprdeg < 113) loop = 1; + else if (sprdeg > 112 && sprdeg < 158) loop = 7; + else if (sprdeg > 157 && sprdeg < 203) loop = 3; + else if (sprdeg > 202 && sprdeg < 248) loop = 5; + else if (sprdeg > 247 && sprdeg < 293) loop = 2; + else if (sprdeg > 292 && sprdeg < 337) loop = 4; + AGSViewFrame *vf = engine->GetViewFrame(sprite[spriteOrder[i]].view, loop, sprite[spriteOrder[i]].frame); + if (vf == nullptr) engine->AbortGame("Raycast_Render: Unable to load viewframe of sprite."); + else { + sprite[spriteOrder[i]].texture = vf->pic; + int (*sfGetGameParameter)(int, int, int, int); + sfGetGameParameter = ((int(*)(int, int, int, int)) engine->GetScriptFunctionAddress("GetGameParameter")); + flipped = sfGetGameParameter(13, sprite[spriteOrder[i]].view, loop, sprite[spriteOrder[i]].frame); + } + } + //translate sprite position to relative to camera + //double spriteX = sprite[spriteOrder[i]].x - posX; + //double spriteY = sprite[spriteOrder[i]].y - posY; + + //transform sprite with the inverse camera matrix + // [ planeX dirX ] -1 [ dirY -dirX ] + // [ ] = 1/(planeX*dirY-dirX*planeY) * [ ] + // [ planeY dirY ] [ -planeY planeX ] + + //double invDet = 1.0 / (planeX * dirY - dirX * planeY); //required for correct matrix multiplication + double spriteX = sprite[spriteOrder[i]].x - posX; + double spriteY = sprite[spriteOrder[i]].y - posY; + //double transformX = invDet * (dirY * spriteX - dirX * spriteY); + //double transformY = invDet * (-planeY * spriteX + planeX * spriteY); //this is actually the depth inside the screen, that what Z is in 3D + + int spriteScreenX = int((w / 2) * (1 + spriteTransformX[i] / spriteTransformY[i])); + + //parameters for scaling and moving the sprites + BITMAP *spritetexbm = engine->GetSpriteGraphic(sprite[spriteOrder[i]].texture); + unsigned char **spritetex = engine->GetRawBitmapSurface(spritetexbm); + int sprw = engine->GetSpriteWidth(sprite[spriteOrder[i]].texture); + int sprh = engine->GetSpriteHeight(sprite[spriteOrder[i]].texture); + + double uDiv = ((double)sprw / (double)texWidth) + sprite[spriteOrder[i]].uDivW; + double vDiv = ((double)sprh / (double)texHeight) + sprite[spriteOrder[i]].uDivH; + double vMove = sprite[spriteOrder[i]].vMove + ((double)texHeight - (double)sprh) * 1.6; + double hMove = sprite[spriteOrder[i]].hMove; + int vMoveScreen = int(vMove / spriteTransformY[i]); + int hMoveScreen = int(hMove / spriteTransformY[i]); + //calculate height of the sprite on screen + int spriteHeight = abs(int(h / (spriteTransformY[i]) * vDiv)) ; //using "transformY" instead of the real distance prevents fisheye + //calculate lowest and highest pixel to fill in current stripe + int drawStartY = -spriteHeight / 2 + h / 2 + vMoveScreen; + if (drawStartY < 0) drawStartY = 0; + int drawEndY = spriteHeight / 2 + h / 2 + vMoveScreen; + if (drawEndY >= h) drawEndY = h - 1; + + //calculate width of the sprite + int spriteWidth = abs(int (h / (spriteTransformY[i]) * uDiv)) ; + int drawStartX = -spriteWidth / 2 + spriteScreenX + hMoveScreen; + if (drawStartX < 0) drawStartX = 0; + int drawEndX = spriteWidth / 2 + spriteScreenX + hMoveScreen; + if (drawEndX >= w) drawEndX = w - 1; + int spr_light = lightMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] << 5; + spr_light = std::min(255, std::max(0, spr_light)); + int floorTexX = int(sprite[spriteOrder[i]].x * texWidth) % texWidth; + int floorTexY = int(sprite[spriteOrder[i]].y * texHeight) % texHeight; + if (ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] == 0) { + spr_light = std::max(spr_light, ambientlight); + } else if (texture[ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] - 1][texWidth * floorTexY + floorTexX] == 0) spr_light = std::max(spr_light, ambientlight); + //loop through every vertical stripe of the sprite on screen + + + for (int stripe = drawStartX; stripe < drawEndX; stripe++) { + transwalldraw = 0; + //int texX = int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * texWidth / spriteWidth) / 256; + int texX = int(256 * (stripe - (-spriteWidth / 2 + spriteScreenX)) * sprw / spriteWidth) / 256; + if (texX >= sprw || texX < 0) continue; + if (flipped) texX = sprw - texX; + //the conditions in the if are: + //1) it's in front of camera plane so you don't see things behind you + //2) it's on the screen (left) + //3) it's on the screen (right) + //4) ZBuffer, with perpendicular distance + if (spriteTransformY[i] > 0 && stripe > 0 && stripe < w) + for (int y = drawStartY; y < drawEndY; y++) { //for every pixel of the current stripe + if (spriteTransformY[i] < ZBuffer[stripe][y]) { + if (transslicedrawn[stripe]) while ((transzbuffer[stripe][transwalldraw * h + y] > spriteTransformY[i] && transzbuffer[stripe][transwalldraw * h + y] != 0) && (transwalldraw < transwallcount)) transwalldraw++; + int d = (y - vMoveScreen) * 256 - h * 128 + spriteHeight * 128; //256 and 128 factors to avoid floats + //int texY = ((d * texHeight) / spriteHeight) / 256; + int texY = ((d * sprh) / spriteHeight) / 256; + if (texY >= sprh || texY < 0) continue; + //unsigned char color = texture[sprite[spriteOrder[i]].texture][texWidth * texY + texX]; //get current color from the texture + unsigned char color = spritetex[texY][texX]; //get current color from the texture + if (color != 0) { + if (sprite[spriteOrder[i]].alpha < 255) { + if (sprite[spriteOrder[i]].blendmode == 0) color = Mix::MixColorAlpha(color, buffer[y][stripe], sprite[spriteOrder[i]].alpha); + if (sprite[spriteOrder[i]].blendmode == 1) color = Mix::MixColorAdditive(color, buffer[y][stripe], sprite[spriteOrder[i]].alpha); + } + color = Mix::MixColorLightLevel(color, spr_light); + if (transzbuffer[stripe][transwalldraw * h + y] < spriteTransformY[i] && transzbuffer[stripe][transwalldraw * h + y] != 0 && transslicedrawn[stripe] && transcolorbuffer[stripe][transwalldraw * h + y] > 0 && transalphabuffer[stripe][transwalldraw * h + y] > 0) { + if (transwallblendmode[transwalldraw] == 0) color = Mix::MixColorAlpha(color, transcolorbuffer[stripe][transwalldraw * h + y], transalphabuffer[stripe][transwalldraw * h + y]); + else if (transwallblendmode[transwalldraw] == 1) color = Mix::MixColorAdditive(color, transcolorbuffer[stripe][transwalldraw * h + y], transalphabuffer[stripe][transwalldraw * h + y]); + buffer[y][stripe] = color; + ZBuffer[stripe][y] = transzbuffer[stripe][transwalldraw * h + y]; + } else { + buffer[y][stripe] = color; //paint pixel if it isn't black, black is the invisible color + ZBuffer[stripe][y] = spriteTransformY[i]; //put the sprite on the zbuffer so we can draw around it. + } + interactionmap [stripe * sWidth + y] = sprite[spriteOrder[i]].objectinteract << 8; + } + } + } + } + engine->ReleaseBitmapSurface(spritetexbm); + } + engine->ReleaseBitmapSurface(screen); + engine->NotifySpriteUpdated(slot); + rendering = false; + +} + +void QuitCleanup() { + if (!rendering) { + for (int i = 0; i < sWidth; ++i) { + if (transcolorbuffer[i])delete [] transcolorbuffer[i]; + if (transalphabuffer[i])delete [] transalphabuffer[i]; + if (transzbuffer[i])delete [] transzbuffer[i]; + if (ZBuffer[i]) delete [] ZBuffer[i]; + } + if (transcolorbuffer) delete [] transcolorbuffer; + if (transalphabuffer) delete [] transalphabuffer; + if (transzbuffer) delete [] transzbuffer; + if (ZBuffer) delete [] ZBuffer; + if (transwallblendmode) delete [] transwallblendmode; + if (interactionmap) delete [] interactionmap; + } +} + +void MoveForward() { + double newposx = 0; + if (dirX > 0) newposx = 0.1 + posX + dirX * moveSpeed; + else newposx = -0.1 + posX + dirX * moveSpeed; + int texsidex = 0; + int inside_texsidex = 0; + double newposy = 0; + if (dirY > 0) newposy = 0.1 + posY + dirY * moveSpeed; + else newposy = -0.1 + posY + dirY * moveSpeed; + int texsidey = 0; + int inside_texsidey = 0; + bool inside = false; + if ((int)newposx == (int)posX && (int)newposy == (int)posY) inside = true; + if (dirX > 0 && !inside) { + texsidex = 0; + inside_texsidex = 1; + } else if (dirX > 0) { + texsidex = 1; + inside_texsidex = 0; + } + if (dirX < 0 && !inside) { + texsidex = 1; + inside_texsidex = 0; + } else if (dirX < 0) { + texsidex = 0; + inside_texsidex = 1; + } + + if (dirY > 0 && !inside) { + texsidey = 2; + inside_texsidey = 3; + } else if (dirY > 0) { + texsidey = 3; + inside_texsidey = 2; + } + if (dirY < 0 && !inside) { + texsidey = 3; + inside_texsidey = 2; + } else if (dirY < 0) { + texsidey = 2; + inside_texsidey = 3; + } + + if (!noclip && !inside) { + if (wallData[worldMap[int(newposx)][int(posY)]].solid[texsidex] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidex] == false && int(newposx) > -1 && int(newposx) < mapWidth) posX += dirX * moveSpeed; + if (wallData[worldMap[int(posX)][int(newposy)]].solid[texsidey] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidey] == false && int(newposy) > -1 && int(newposy) < mapHeight) posY += dirY * moveSpeed; + } else if (!noclip && inside) { + posX += dirX * moveSpeed; + posY += dirY * moveSpeed; + } else { + if (int(newposx) > -1 && int(newposx) < mapWidth) posX += dirX * moveSpeed; + if (int(newposy) > -1 && int(newposy) < mapHeight) posY += dirY * moveSpeed; + } +} + +void MoveBackward() { + double newposx = 0; + if (dirX > 0) newposx = -0.1 + posX - dirX * moveSpeed; + else newposx = 0.1 + posX - dirX * moveSpeed; + int texsidex = 0; + int inside_texsidex = 0; + double newposy = 0; + if (dirY > 0) newposy = -0.1 + posY - dirY * moveSpeed; + else newposy = 0.1 + posY - dirY * moveSpeed; + int texsidey = 0; + int inside_texsidey = 0; + bool inside = false; + if ((int)newposx == (int)posX && (int)newposy == (int)posY) inside = true; + if (dirX > 0 && !inside) { + texsidex = 1; + inside_texsidex = 0; + } else if (dirX > 0) { + texsidex = 0; + inside_texsidex = 1; + } + if (dirX < 0 && !inside) { + texsidex = 0; + inside_texsidex = 1; + } else if (dirX < 0) { + texsidex = 1; + inside_texsidex = 0; + } + + if (dirY > 0 && !inside) { + texsidey = 3; + inside_texsidey = 2; + } else if (dirY > 0) { + texsidey = 2; + inside_texsidey = 3; + } + if (dirY < 0 && !inside) { + texsidey = 2; + inside_texsidey = 3; + } else if (dirY < 0) { + texsidey = 3; + inside_texsidey = 2; + } + + if ((int)posX == (int)newposy && (int)posY == (int)newposy) inside = true; + if (!noclip && !inside) { + if (wallData[worldMap[int(newposx)][int(posY)]].solid[texsidex] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidex] == false && int(newposx) > -1 && int(newposx) < mapWidth) posX -= dirX * moveSpeed; + if (wallData[worldMap[int(posX)][int(newposy)]].solid[texsidey] == false && wallData[worldMap[int(posX)][int(posY)]].solid[inside_texsidey] == false && int(newposy) > -1 && int(newposy) < mapHeight) posY -= dirY * moveSpeed; + } else if (!noclip && inside) { + posX -= dirX * moveSpeed; + posY -= dirY * moveSpeed; + } else { + if (int(newposx) > -1 && int(newposx) < mapWidth) posX -= dirX * moveSpeed; + if (int(newposy) > -1 && int(newposy) < mapHeight) posY -= dirY * moveSpeed; + } +} + + + +/* +void MoveBackward () +{ + double newposx; + if (dirX > 0) newposx = -0.2 + posX - dirX * moveSpeed; + else newposx = 0.2 + posX - dirX * moveSpeed; + double newposy; + if (dirY > 0) newposy = -0.2 + posY - dirY * moveSpeed; + else newposy = 0.2 + posY - dirY * moveSpeed; + if(worldMap[int(newposx)][int(posY)] == false || worldMap[int(newposx)][int(posY)] > 8) posX -= dirX * moveSpeed; + if(worldMap[int(posX)][int(newposy)] == false || worldMap[int(posX)][int(newposy)] > 8) posY -= dirY * moveSpeed; +} +*/ + +void RotateLeft() { + double oldDirX = dirX; + dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed); + dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed); + double oldPlaneX = planeX; + planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed); + planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed); +} + +void RotateRight() { + double oldDirX = dirX; + dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed); + dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed); + double oldPlaneX = planeX; + planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed); + planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed); +} + +//sort algorithm +void combSort(int *order, double *dist, int amount) { + int gap = amount; + bool swapped = false; + while (gap > 1 || swapped) { + //shrink factor 1.3 + gap = (gap * 10) / 13; + if (gap == 9 || gap == 10) gap = 11; + if (gap < 1) gap = 1; + swapped = false; + for (int i = 0; i < amount - gap; i++) { + int j = i + gap; + if (dist[i] < dist[j]) { + std::swap(dist[i], dist[j]); + std::swap(order[i], order[j]); + swapped = true; + } + } + } +} + +#if defined(BUILTIN_PLUGINS) +} // namespace agspalrender +#endif diff --git a/engines/ags/plugins/ags_pal_render/raycast.h b/engines/ags/plugins/ags_pal_render/raycast.h new file mode 100644 index 000000000000..87f4c1ed6f6b --- /dev/null +++ b/engines/ags/plugins/ags_pal_render/raycast.h @@ -0,0 +1,189 @@ +#ifndef __PALGORITHMS_RAYCAST_H +#define __PALGORITHMS_RAYCAST_H + +#include "palrender.h" + +#define mapWidth 64 +#define mapHeight 64 + +#if defined(BUILTIN_PLUGINS) +namespace agspalrender { +#endif + +struct Sprite { + double x; + double y; + int texture; + unsigned char alpha; + int blendmode; + double uDivW; + double uDivH; + double vMove; + double hMove; + char objectinteract; + int view; + int frame; + int angle; +}; + +struct wallType { + int texture[4]; + int solid[4]; + int ignorelighting[4]; + int alpha[4]; + int blendtype[4]; + int mask[4]; + unsigned char hotspotinteract; +}; + + +extern bool raycastOn; +extern double posX; +extern double posY; //x and y start position +extern double dirX; +extern double dirY; //initial direction vector +extern double planeX; +extern double planeY; //the 2d raycaster version of camera plane +extern double moveSpeed; //the constant value is in squares/second +extern double rotSpeed; //the constant value is in radians/second +extern unsigned char worldMap[64][64]; +extern unsigned char lightMap[64][64]; +extern int ceilingMap[64][64]; +extern int floorMap[64][64]; +extern int heightMap[64][64]; +extern unsigned char seenMap[64][64]; +//extern int mapWidth; +//extern int mapHeight; +extern int textureSlot; +extern int ambientlight; + +#define numSprites 256 +extern Sprite sprite[numSprites]; + + +#define texWidth 64 +#define texHeight 64 +#define MAX_TEXTURES 512 +extern unsigned char texture[][texWidth * texHeight]; + +extern bool heightmapOn; + + +extern wallType wallData[256]; + +//arrays used to sort the sprites +extern unsigned char **transcolorbuffer; +extern unsigned char **transalphabuffer; +extern double **transzbuffer; +extern bool *transslicedrawn; +extern int *transwallblendmode; +extern double **ZBuffer; +extern double *distTable; +extern short *interactionmap; +extern int skybox; + + + +void MakeTextures(int slot); +void Raycast_Render(int slot); +void MoveForward(); +void MoveBackward(); +void RotateLeft(); +void RotateRight(); +void Init_Raycaster(); +void QuitCleanup(); +void LoadMap(int worldmapSlot, int lightmapSlot, int ceilingmapSlot, int floormapSlot); +void Ray_InitSprite(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y), int slot, unsigned char alpha, int blendmode, SCRIPT_FLOAT(scale_x), SCRIPT_FLOAT(scale_y), SCRIPT_FLOAT(vMove)); +void Ray_SetPlayerPosition(SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)); +FLOAT_RETURN_TYPE Ray_GetPlayerX(); +FLOAT_RETURN_TYPE Ray_GetPlayerY(); +int Ray_GetPlayerAngle(); +void Ray_SetPlayerAngle(int angle); + +int Ray_GetWallHotspot(int id); +int Ray_GetWallTexture(int id, int dir); +int Ray_GetWallSolid(int id, int dir); +int Ray_GetWallIgnoreLighting(int id, int dir); +int Ray_GetWallAlpha(int id, int dir); +int Ray_GetWallBlendType(int id, int dir); + +void Ray_SelectTile(int x, int y, unsigned char color); + +int Ray_GetHotspotAt(int x, int y); +int Ray_GetObjectAt(int x, int y); + +void Ray_DrawTile(int spr, int tile); +void Ray_DrawOntoTile(int spr, int tile); +void Ray_SetNoClip(int value); +int Ray_GetNoClip(); +void Ray_SetSpriteInteractObj(int id, int obj); +int Ray_GetSpriteInteractObj(int id); +void Ray_SetSpritePosition(int id, SCRIPT_FLOAT(x), SCRIPT_FLOAT(y)); +void Ray_SetSpriteVertOffset(int id, SCRIPT_FLOAT(vMove)); +FLOAT_RETURN_TYPE Ray_GetSpriteVertOffset(int id); +FLOAT_RETURN_TYPE Ray_GetSpriteX(int id); +FLOAT_RETURN_TYPE Ray_GetSpriteY(int id); + +void Ray_SetWallHotspot(int id, char hotsp); +void Ray_SetWallTextures(int id, int n, int s, int w, int e); +void Ray_SetWallSolid(int id, int n, int s, int w, int e); +void Ray_SetWallIgnoreLighting(int id, int n, int s, int w, int e); +void Ray_SetWallAlpha(int id, int n, int s, int w, int e); +void Ray_SetWallBlendType(int id, int n, int s, int w, int e); + +FLOAT_RETURN_TYPE Ray_GetMoveSpeed(); +void Ray_SetMoveSpeed(SCRIPT_FLOAT(speed)); +FLOAT_RETURN_TYPE Ray_GetRotSpeed(); +void Ray_SetRotSpeed(SCRIPT_FLOAT(speed)); +int Ray_GetWallAt(int x, int y); +int Ray_GetLightAt(int x, int y); +void Ray_SetLightAt(int x, int y, int light); +void Ray_SetWallAt(int x, int y, int id); +void Ray_SetPlaneY(SCRIPT_FLOAT(y)); +FLOAT_RETURN_TYPE Ray_GetDistanceAt(int x, int y); +int Ray_GetSpriteAngle(int id); +void Ray_SetSpriteAngle(int id, int angle); +void Ray_SetSpriteView(int id, int view); +int Ray_GetSpriteView(int id); +void Ray_SetSpriteFrame(int id, int frame); +int Ray_GetSpriteFrame(int id); + +int Ray_GetTileX_At(int x, int y); +int Ray_GetTileY_At(int x, int y); + +void Ray_SetSkyBox(int slot); +int Ray_GetSkyBox(int slot); + +void Ray_SetAmbientLight(int value); +int Ray_GetAmbientLight(); +void Ray_SetAmbientColor(int color, int amount); + + +int Ray_GetSpriteAlpha(int id); +void Ray_SetSpriteAlpha(int id, int alpha); +int Ray_GetSpritePic(int id); +void Ray_SetSpritePic(int id, int slot); + +FLOAT_RETURN_TYPE Ray_GetSpriteScaleX(int id); +void Ray_SetSpriteScaleX(int id, SCRIPT_FLOAT(scale)); +FLOAT_RETURN_TYPE Ray_GetSpriteScaleY(int id); +void Ray_SetSpriteScaleY(int id, SCRIPT_FLOAT(scale)); + +void Ray_SetSpriteBlendType(int id, int type); +int Ray_GetSpriteBlendType(int id); + +void Ray_SetFloorAt(int x, int y, int tex); +void Ray_SetCeilingAt(int x, int y, int tex); +int Ray_GetCeilingAt(int x, int y); +int Ray_GetFloorAt(int x, int y); +int Ray_GetLightingAt(int x, int y); +void Ray_SetLightingAt(int x, int y, unsigned char lighting); +int Ray_GetAmbientWeight(); + +int Ray_HasSeenTile(int x, int y); + +#if defined(BUILTIN_PLUGINS) +} // namespace agspalrender +#endif + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.cpp b/engines/ags/plugins/ags_parallax/ags_parallax.cpp new file mode 100644 index 000000000000..05c32b94ddfc --- /dev/null +++ b/engines/ags/plugins/ags_parallax/ags_parallax.cpp @@ -0,0 +1,287 @@ +/* + +This is not the AGS Parallax plugin by Scorpiorus +but a workalike plugin created by JJS for the AGS engine ports. + +*/ + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#pragma warning(disable : 4244) +#endif + +#if !defined(BUILTIN_PLUGINS) +#define THIS_IS_THE_PLUGIN +#endif + +#include +#include +#include +#include + +#include "plugin/agsplugin.h" + +#if defined(BUILTIN_PLUGINS) +namespace ags_parallax { +#endif + +//#define DEBUG + +const unsigned int Magic = 0xCAFE0000; +const unsigned int Version = 2; +const unsigned int SaveMagic = Magic + Version; + +int screen_width = 320; +int screen_height = 200; +int screen_color_depth = 32; + +IAGSEngine *engine; + +bool enabled = false; + + +typedef struct { + int x; + int y; + int slot; + int speed; +} sprite_t; + +#define MAX_SPEED 1000 +#define MAX_SPRITES 100 +sprite_t sprites[MAX_SPRITES]; + +// workaround to fix this error: +// psp-fixup-imports ags_parallax.elf +// Error, no .lib.stub section found +void dummy() { + void *tmp = new int; +} + +static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = engine->FRead(ptr, size * count, fileHandle); + return totalBytes / size; +} + +static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = engine->FWrite(const_cast(ptr), size * count, fileHandle); + return totalBytes / size; +} + +void RestoreGame(long fileHandle) { + unsigned int SaveVersion = 0; + engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, fileHandle); + + if (SaveVersion != SaveMagic) { + engine->AbortGame("ags_parallax: bad save."); + } + + engineFileRead(sprites, sizeof(sprite_t), MAX_SPRITES, fileHandle); + engineFileRead(&enabled, sizeof(bool), 1, fileHandle); +} + +void SaveGame(long file) { + engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); + engineFileWrite(sprites, sizeof(sprite_t), MAX_SPRITES, file); + engineFileWrite(&enabled, sizeof(bool), 1, file); +} + + +void Initialize() { + memset(sprites, 0, sizeof(sprite_t) * MAX_SPRITES); + + int i; + for (i = 0; i < MAX_SPRITES; i++) + sprites[i].slot = -1; + + enabled = false; +} + + +void Draw(bool foreground) { + if (!enabled) + return; + + BITMAP *bmp; + int i; + + int offsetX = 0; + int offsetY = 0; + engine->ViewportToRoom(&offsetX, &offsetY); + + for (i = 0; i < MAX_SPRITES; i++) { + if (sprites[i].slot > -1) { + if (foreground) { + if (sprites[i].speed > 0) { + bmp = engine->GetSpriteGraphic(sprites[i].slot); + if (bmp) + engine->BlitBitmap(sprites[i].x - offsetX - (sprites[i].speed * offsetX / 100), sprites[i].y, bmp, 1); + } + } else { + if (sprites[i].speed <= 0) { + bmp = engine->GetSpriteGraphic(sprites[i].slot); + if (bmp) + engine->BlitBitmap(sprites[i].x - offsetX - (sprites[i].speed * offsetX / 1000), sprites[i].y, bmp, 1); + } + } + } + } +} + + + + + +// ******************************************** +// ************ AGS Interface *************** +// ******************************************** + +void pxDrawSprite(int id, int x, int y, int slot, int speed) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%s %d %d %d %d %d\n", "pxDrawSprite", id, x, y, slot, speed); + engine->PrintDebugConsole(buffer); +#endif + + if ((id < 0) || (id >= MAX_SPRITES)) + return; + + if ((speed < -MAX_SPEED) || (speed > MAX_SPEED)) + speed = 0; + + sprites[id].x = x; + sprites[id].y = y; + sprites[id].slot = slot; + sprites[id].speed = speed; + + engine->RoomToViewport(&sprites[id].x, &sprites[id].y); + + enabled = true; +} + + +void pxDeleteSprite(int id) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%s %d\n", "pxDeleteSprite", id); + engine->PrintDebugConsole(buffer); +#endif + + if ((id < 0) || (id >= MAX_SPRITES)) + return; + + sprites[id].slot = -1; +} + +void AGS_EngineStartup(IAGSEngine *lpEngine) { + engine = lpEngine; + + if (engine->version < 13) + engine->AbortGame("Engine interface is too old, need newer version of AGS."); + + engine->RegisterScriptFunction("pxDrawSprite", (void *)&pxDrawSprite); + engine->RegisterScriptFunction("pxDeleteSprite", (void *)&pxDeleteSprite); + + engine->RequestEventHook(AGSE_PREGUIDRAW); + engine->RequestEventHook(AGSE_PRESCREENDRAW); + engine->RequestEventHook(AGSE_ENTERROOM); + engine->RequestEventHook(AGSE_SAVEGAME); + engine->RequestEventHook(AGSE_RESTOREGAME); + + Initialize(); +} + +void AGS_EngineShutdown() { +} + +int AGS_EngineOnEvent(int event, int data) { + if (event == AGSE_PREGUIDRAW) { + Draw(true); + } else if (event == AGSE_PRESCREENDRAW) { + Draw(false); + } else if (event == AGSE_ENTERROOM) { + // Reset all sprites + Initialize(); + } else if (event == AGSE_PRESCREENDRAW) { + // Get screen size once here + engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); + engine->UnrequestEventHook(AGSE_PRESCREENDRAW); + } else if (event == AGSE_RESTOREGAME) { + RestoreGame(data); + } else if (event == AGSE_SAVEGAME) { + SaveGame(data); + } + + return 0; +} + +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { + return 0; +} + +void AGS_EngineInitGfx(const char *driverID, void *data) { +} + + + +#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) + +// ******************************************** +// *********** Editor Interface ************* +// ******************************************** + +const char *scriptHeader = + "import void pxDrawSprite(int ID, int X, int Y, int SlotNum, int Speed);\r\n" + "import void pxDeleteSprite(int ID);\r\n"; + +IAGSEditor *editor; + + +LPCSTR AGS_GetPluginName(void) { + // Return the plugin description + return "Parallax plugin recreation"; +} + +int AGS_EditorStartup(IAGSEditor *lpEditor) { + // User has checked the plugin to use it in their game + + // If it's an earlier version than what we need, abort. + if (lpEditor->version < 1) + return -1; + + editor = lpEditor; + editor->RegisterScriptHeader(scriptHeader); + + // Return 0 to indicate success + return 0; +} + +void AGS_EditorShutdown() { + // User has un-checked the plugin from their game + editor->UnregisterScriptHeader(scriptHeader); +} + +void AGS_EditorProperties(HWND parent) { + // User has chosen to view the Properties of the plugin + // We could load up an options dialog or something here instead + MessageBoxA(parent, "Parallax plugin recreation by JJS", "About", MB_OK | MB_ICONINFORMATION); +} + +int AGS_EditorSaveGame(char *buffer, int bufsize) { + // We don't want to save any persistent data + return 0; +} + +void AGS_EditorLoadGame(char *buffer, int bufsize) { + // Nothing to load for this plugin +} + +#endif + + +#if defined(BUILTIN_PLUGINS) +} // namespace ags_parallax +#endif diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.h b/engines/ags/plugins/ags_parallax/ags_parallax.h new file mode 100644 index 000000000000..c58126f149dc --- /dev/null +++ b/engines/ags/plugins/ags_parallax/ags_parallax.h @@ -0,0 +1,14 @@ +#ifndef AGS_PARALLAX_H +#define AGS_PARALLAX_H + +#include "plugin/agsplugin.h" + +namespace ags_parallax { +void AGS_EngineStartup(IAGSEngine *lpEngine); +void AGS_EngineShutdown(); +int AGS_EngineOnEvent(int event, int data); +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); +void AGS_EngineInitGfx(const char *driverID, void *data); +} + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp new file mode 100644 index 000000000000..bc61dc26be25 --- /dev/null +++ b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp @@ -0,0 +1,841 @@ +/* + +This is not the AGS SnowRain plugin by Scorpiorus (http://www.bigbluecup.com/yabb/index.php?topic=25665.0), +but a workalike plugin created by JJS for the AGS engine PSP port. + +*/ + +#include "core/platform.h" + +#if AGS_PLATFORM_OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#pragma warning(disable : 4244) +#endif + +#if !defined(BUILTIN_PLUGINS) +#define THIS_IS_THE_PLUGIN +#endif + +#include +#include +#include +#include + +#ifdef PSP_VERSION +#include +#include +#define sin(x) vfpu_sinf(x) +#endif + +#include "plugin/agsplugin.h" + +#if defined(BUILTIN_PLUGINS) +namespace ags_snowrain { +#endif + +//#define DEBUG +//#define AGS_SNOWRAIN_DLL_SAVEGAME_COMPATIBILITY + +#define signum(x) ((x > 0) ? 1 : -1) + +const unsigned int Magic = 0xCAFE0000; +const unsigned int Version = 2; +const unsigned int SaveMagic = Magic + Version; +const float PI = 3.14159265f; + +int screen_width = 320; +int screen_height = 200; +int screen_color_depth = 32; + +IAGSEngine *engine; + + +typedef struct { + int view; + int loop; + bool is_default; + BITMAP *bitmap; +} view_t; + + +typedef struct { + float x; + float y; + int alpha; + float speed; + int max_y; + int kind_id; + int drift; + float drift_speed; + float drift_offset; +} drop_t; + + +class Weather { +public: + Weather(); + Weather(bool IsSnow); + ~Weather(); + + void Initialize(); + void InitializeParticles(); + + void RestoreGame(long file); + void SaveGame(long file); + bool ReinitializeViews(); + + bool IsActive(); + void Update(); + void UpdateWithDrift(); + void EnterRoom(); + + void SetDriftRange(int min_value, int max_value); + void SetDriftSpeed(int min_value, int max_value); + void ChangeAmount(int amount); + void SetView(int kind_id, int event, int view, int loop); + void SetDefaultView(int view, int loop); + void SetTransparency(int min_value, int max_value); + void SetWindSpeed(int value); + void SetBaseline(int top, int bottom); + void SetAmount(int amount); + void SetFallSpeed(int min_value, int max_value); + +private: + void ClipToRange(int &variable, int min, int max); + + bool mIsSnow; + + int mMinDrift; + int mMaxDrift; + int mDeltaDrift; + + int mMinDriftSpeed; + int mMaxDriftSpeed; + int mDeltaDriftSpeed; + + int mAmount; + int mTargetAmount; + + int mMinAlpha; + int mMaxAlpha; + int mDeltaAlpha; + + float mWindSpeed; + + int mTopBaseline; + int mBottomBaseline; + int mDeltaBaseline; + + int mMinFallSpeed; + int mMaxFallSpeed; + int mDeltaFallSpeed; + + drop_t mParticles[2000]; + view_t mViews[5]; + + bool mViewsInitialized; +}; + + +Weather::Weather() { + mIsSnow = false; + Initialize(); +} + + +Weather::Weather(bool IsSnow) { + mIsSnow = IsSnow; + Initialize(); +} + + +Weather::~Weather() = default; + + +void Weather::Update() { + if (mTargetAmount > mAmount) + mAmount++; + else if (mTargetAmount < mAmount) + mAmount--; + + if (!ReinitializeViews()) + return; + + int i; + for (i = 0; i < mAmount * 2; i++) { + mParticles[i].y += mParticles[i].speed; + mParticles[i].x += mWindSpeed; + + if (mParticles[i].x < 0) + mParticles[i].x += screen_width; + + if (mParticles[i].x > screen_width - 1) + mParticles[i].x -= screen_width; + + if (mParticles[i].y > mParticles[i].max_y) { + mParticles[i].y = -1 * (rand() % screen_height); + mParticles[i].x = rand() % screen_width; + mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; + mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; + mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline; + } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) + engine->BlitSpriteTranslucent(mParticles[i].x, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); + } + + engine->MarkRegionDirty(0, 0, screen_width, screen_height); +} + + +void Weather::UpdateWithDrift() { + if (mTargetAmount > mAmount) + mAmount++; + else if (mTargetAmount < mAmount) + mAmount--; + + if (!ReinitializeViews()) + return; + + int i, drift; + for (i = 0; i < mAmount * 2; i++) { + mParticles[i].y += mParticles[i].speed; + drift = mParticles[i].drift * sin((float)(mParticles[i].y + mParticles[i].drift_offset) * mParticles[i].drift_speed * 2.0f * PI / 360.0f); + + if (signum(mWindSpeed) == signum(drift)) + mParticles[i].x += mWindSpeed; + else + mParticles[i].x += mWindSpeed / 4; + + if (mParticles[i].x < 0) + mParticles[i].x += screen_width; + + if (mParticles[i].x > screen_width - 1) + mParticles[i].x -= screen_width; + + if (mParticles[i].y > mParticles[i].max_y) { + mParticles[i].y = -1 * (rand() % screen_height); + mParticles[i].x = rand() % screen_width; + mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; + mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; + mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline; + mParticles[i].drift = rand() % mDeltaDrift + mMinDrift; + mParticles[i].drift_speed = (rand() % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; + } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) + engine->BlitSpriteTranslucent(mParticles[i].x + drift, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); + } + + engine->MarkRegionDirty(0, 0, screen_width, screen_height); +} + +static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = engine->FRead(ptr, size * count, fileHandle); + return totalBytes / size; +} + +static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = engine->FWrite(const_cast(ptr), size * count, fileHandle); + return totalBytes / size; +} + +void Weather::RestoreGame(long file) { + unsigned int SaveVersion = 0; + engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, file); + + if (SaveVersion != SaveMagic) { + engine->AbortGame("ags_snowrain: bad save."); + } + + // Current version + engineFileRead(&mIsSnow, 4, 1, file); + engineFileRead(&mMinDrift, 4, 1, file); + engineFileRead(&mMaxDrift, 4, 1, file); + engineFileRead(&mDeltaDrift, 4, 1, file); + engineFileRead(&mMinDriftSpeed, 4, 1, file); + engineFileRead(&mMaxDriftSpeed, 4, 1, file); + engineFileRead(&mDeltaDriftSpeed, 4, 1, file); + engineFileRead(&mAmount, 4, 1, file); + engineFileRead(&mTargetAmount, 4, 1, file); + engineFileRead(&mMinAlpha, 4, 1, file); + engineFileRead(&mMaxAlpha, 4, 1, file); + engineFileRead(&mDeltaAlpha, 4, 1, file); + engineFileRead(&mWindSpeed, 4, 1, file); + engineFileRead(&mTopBaseline, 4, 1, file); + engineFileRead(&mBottomBaseline, 4, 1, file); + engineFileRead(&mDeltaBaseline, 4, 1, file); + engineFileRead(&mMinFallSpeed, 4, 1, file); + engineFileRead(&mMaxFallSpeed, 4, 1, file); + engineFileRead(&mDeltaFallSpeed, 4, 1, file); + engineFileRead(mViews, sizeof(view_t) * 5, 1, file); + + InitializeParticles(); +} + + +void Weather::SaveGame(long file) { + engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); + + engineFileWrite(&mIsSnow, 4, 1, file); + engineFileWrite(&mMinDrift, 4, 1, file); + engineFileWrite(&mMaxDrift, 4, 1, file); + engineFileWrite(&mDeltaDrift, 4, 1, file); + engineFileWrite(&mMinDriftSpeed, 4, 1, file); + engineFileWrite(&mMaxDriftSpeed, 4, 1, file); + engineFileWrite(&mDeltaDriftSpeed, 4, 1, file); + engineFileWrite(&mAmount, 4, 1, file); + engineFileWrite(&mTargetAmount, 4, 1, file); + engineFileWrite(&mMinAlpha, 4, 1, file); + engineFileWrite(&mMaxAlpha, 4, 1, file); + engineFileWrite(&mDeltaAlpha, 4, 1, file); + engineFileWrite(&mWindSpeed, 4, 1, file); + engineFileWrite(&mTopBaseline, 4, 1, file); + engineFileWrite(&mBottomBaseline, 4, 1, file); + engineFileWrite(&mDeltaBaseline, 4, 1, file); + engineFileWrite(&mMinFallSpeed, 4, 1, file); + engineFileWrite(&mMaxFallSpeed, 4, 1, file); + engineFileWrite(&mDeltaFallSpeed, 4, 1, file); + engineFileWrite(mViews, sizeof(view_t) * 5, 1, file); +} + + +bool Weather::ReinitializeViews() { + if ((mViews[4].view == -1) || (mViews[4].loop == -1)) + return false; + + AGSViewFrame *view_frame = engine->GetViewFrame(mViews[4].view, mViews[4].loop, 0); + BITMAP *default_bitmap = engine->GetSpriteGraphic(view_frame->pic); + + int i; + for (i = 0; i < 5; i++) { + if (mViews[i].bitmap != nullptr) { + if (mViews[i].is_default) + mViews[i].bitmap = default_bitmap; + else { + view_frame = engine->GetViewFrame(mViews[i].view, mViews[i].loop, 0); + mViews[i].bitmap = engine->GetSpriteGraphic(view_frame->pic); + } + } + } + + return true; +} + + +bool Weather::IsActive() { + return (mAmount > 0) || (mTargetAmount != mAmount); +} + + +void Weather::EnterRoom() { + mAmount = mTargetAmount; +} + + +void Weather::ClipToRange(int &variable, int min, int max) { + if (variable < min) + variable = min; + + if (variable > max) + variable = max; +} + + +void Weather::Initialize() { + SetDriftRange(10, 100); + SetDriftSpeed(10, 120); + + SetTransparency(0, 0); + SetWindSpeed(0); + SetBaseline(0, 200); + + if (mIsSnow) + SetFallSpeed(10, 70); + else + SetFallSpeed(100, 300); + + mViewsInitialized = false; + + int i; + for (i = 0; i < 5; i++) { + mViews[i].is_default = true; + mViews[i].view = -1; + mViews[i].loop = -1; + mViews[i].bitmap = nullptr; + } + + SetAmount(0); +} + + +void Weather::InitializeParticles() { + memset(mParticles, 0, sizeof(drop_t) * 2000); + int i; + for (i = 0; i < 2000; i++) { + mParticles[i].kind_id = rand() % 5; + mParticles[i].y = rand() % (screen_height * 2) - screen_height; + mParticles[i].x = rand() % screen_width; + mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; + mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; + mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline; + mParticles[i].drift = rand() % mDeltaDrift + mMinDrift; + mParticles[i].drift_speed = (rand() % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; + mParticles[i].drift_offset = rand() % 100; + } +} + + +void Weather::SetDriftRange(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftRange", min_value, max_value); + engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 100); + ClipToRange(max_value, 0, 100); + + if (min_value > max_value) + min_value = max_value; + + mMinDrift = min_value / 2; + mMaxDrift = max_value / 2; + mDeltaDrift = mMaxDrift - mMinDrift; + + if (mDeltaDrift == 0) + mDeltaDrift = 1; +} + + +void Weather::SetDriftSpeed(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftSpeed", min_value, max_value); + engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 200); + ClipToRange(max_value, 0, 200); + + if (min_value > max_value) + min_value = max_value; + + mMinDriftSpeed = min_value; + mMaxDriftSpeed = max_value; + mDeltaDriftSpeed = mMaxDriftSpeed - mMinDriftSpeed; + + if (mDeltaDriftSpeed == 0) + mDeltaDriftSpeed = 1; +} + + +void Weather::ChangeAmount(int amount) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "ChangeAmount", amount); + engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(amount, 0, 1000); + + mTargetAmount = amount; +} + + +void Weather::SetView(int kind_id, int event, int view, int loop) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d %d %d\n", (int)mIsSnow, "SetView", kind_id, event, view, loop); + engine->PrintDebugConsole(buffer); +#endif + + AGSViewFrame *view_frame = engine->GetViewFrame(view, loop, 0); + mViews[kind_id].bitmap = engine->GetSpriteGraphic(view_frame->pic); + mViews[kind_id].is_default = false; + mViews[kind_id].view = view; + mViews[kind_id].loop = loop; + + if (!mViewsInitialized) + SetDefaultView(view, loop); +} + + +void Weather::SetDefaultView(int view, int loop) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDefaultView", view, loop); + engine->PrintDebugConsole(buffer); +#endif + + AGSViewFrame *view_frame = engine->GetViewFrame(view, loop, 0); + BITMAP *bitmap = engine->GetSpriteGraphic(view_frame->pic); + + mViewsInitialized = true; + + int i; + for (i = 0; i < 5; i++) { + if (mViews[i].is_default) { + mViews[i].view = view; + mViews[i].loop = loop; + mViews[i].bitmap = bitmap; + } + } +} + + +void Weather::SetTransparency(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetTransparency", min_value, max_value); + engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 100); + ClipToRange(max_value, 0, 100); + + if (min_value > max_value) + min_value = max_value; + + mMinAlpha = 255 - floor((float)max_value * 2.55f + 0.5f); + mMaxAlpha = 255 - floor((float)min_value * 2.55f + 0.5f); + mDeltaAlpha = mMaxAlpha - mMinAlpha; + + if (mDeltaAlpha == 0) + mDeltaAlpha = 1; + + int i; + for (i = 0; i < 2000; i++) + mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; +} + + +void Weather::SetWindSpeed(int value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetWindSpeed", value); + engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(value, -200, 200); + + mWindSpeed = (float)value / 20.0f; +} + + +void Weather::SetBaseline(int top, int bottom) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetBaseline", top, bottom); + engine->PrintDebugConsole(buffer); +#endif + + if (screen_height > 0) { + ClipToRange(top, 0, screen_height); + ClipToRange(bottom, 0, screen_height); + } + + if (top > bottom) + top = bottom; + + mTopBaseline = top; + mBottomBaseline = bottom; + mDeltaBaseline = mBottomBaseline - mTopBaseline; + + if (mDeltaBaseline == 0) + mDeltaBaseline = 1; +} + + +void Weather::SetAmount(int amount) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetAmount", amount); + engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(amount, 0, 1000); + + mAmount = mTargetAmount = amount; + + InitializeParticles(); +} + + +void Weather::SetFallSpeed(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetFallSpeed", min_value, max_value); + engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 1000); + ClipToRange(max_value, 0, 1000); + + if (min_value > max_value) + min_value = max_value; + + mMinFallSpeed = min_value; + mMaxFallSpeed = max_value; + mDeltaFallSpeed = mMaxFallSpeed - mMinFallSpeed; + + if (mDeltaFallSpeed == 0) + mDeltaFallSpeed = 1; +} + + + +Weather *rain; +Weather *snow; + + + + +// ******************************************** +// ************ AGS Interface *************** +// ******************************************** + +void srSetWindSpeed(int value) { + snow->SetWindSpeed(value); + rain->SetWindSpeed(value); +} + +void srSetBaseline(int top, int bottom) { + snow->SetBaseline(top, bottom); + rain->SetBaseline(top, bottom); +} + +void srSetSnowDriftRange(int min_value, int max_value) { + snow->SetDriftRange(min_value, max_value); +} + +void srSetSnowDriftSpeed(int min_value, int max_value) { + snow->SetDriftSpeed(min_value, max_value); +} + +void srChangeSnowAmount(int amount) { + snow->ChangeAmount(amount); +} + +void srSetSnowView(int kind_id, int event, int view, int loop) { + snow->SetView(kind_id, event, view, loop); +} + +void srSetSnowDefaultView(int view, int loop) { + snow->SetDefaultView(view, loop); +} + +void srSetSnowTransparency(int min_value, int max_value) { + snow->SetTransparency(min_value, max_value); +} + +void srSetSnowWindSpeed(int value) { + snow->SetWindSpeed(value); +} + +void srSetSnowBaseline(int top, int bottom) { + snow->SetBaseline(top, bottom); +} + +void srSetSnowAmount(int amount) { + snow->SetAmount(amount); +} + +void srSetSnowFallSpeed(int min_value, int max_value) { + snow->SetFallSpeed(min_value, max_value); +} + +void srSetRainDriftRange(int min_value, int max_value) { + rain->SetDriftRange(min_value, max_value); +} + +void srSetRainDriftSpeed(int min_value, int max_value) { + rain->SetDriftSpeed(min_value, max_value); +} + +void srChangeRainAmount(int amount) { + rain->ChangeAmount(amount); +} + +void srSetRainView(int kind_id, int event, int view, int loop) { + rain->SetView(kind_id, event, view, loop); +} + +void srSetRainDefaultView(int view, int loop) { + rain->SetDefaultView(view, loop); +} + +void srSetRainTransparency(int min_value, int max_value) { + rain->SetTransparency(min_value, max_value); +} + +void srSetRainWindSpeed(int value) { + rain->SetWindSpeed(value); +} + +void srSetRainBaseline(int top, int bottom) { + rain->SetBaseline(top, bottom); +} + +void srSetRainAmount(int amount) { + rain->SetAmount(amount); +} + +void srSetRainFallSpeed(int min_value, int max_value) { + rain->SetFallSpeed(min_value, max_value); +} + +void AGS_EngineStartup(IAGSEngine *lpEngine) { + engine = lpEngine; + + if (engine->version < 13) + engine->AbortGame("Engine interface is too old, need newer version of AGS."); + + engine->RegisterScriptFunction("srSetSnowDriftRange", (void *)&srSetSnowDriftRange); + engine->RegisterScriptFunction("srSetSnowDriftSpeed", (void *)&srSetSnowDriftSpeed); + engine->RegisterScriptFunction("srSetSnowFallSpeed", (void *)&srSetSnowFallSpeed); + engine->RegisterScriptFunction("srChangeSnowAmount", (void *)&srChangeSnowAmount); + engine->RegisterScriptFunction("srSetSnowBaseline", (void *)&srSetSnowBaseline); + engine->RegisterScriptFunction("srSetSnowTransparency", (void *)&srSetSnowTransparency); + engine->RegisterScriptFunction("srSetSnowDefaultView", (void *)&srSetSnowDefaultView); + engine->RegisterScriptFunction("srSetSnowWindSpeed", (void *)&srSetSnowWindSpeed); + engine->RegisterScriptFunction("srSetSnowAmount", (void *)&srSetSnowAmount); + engine->RegisterScriptFunction("srSetSnowView", (void *)&srSetSnowView); + + engine->RegisterScriptFunction("srSetRainDriftRange", (void *)&srSetRainDriftRange); + engine->RegisterScriptFunction("srSetRainDriftSpeed", (void *)&srSetRainDriftSpeed); + engine->RegisterScriptFunction("srSetRainFallSpeed", (void *)&srSetRainFallSpeed); + engine->RegisterScriptFunction("srChangeRainAmount", (void *)&srChangeRainAmount); + engine->RegisterScriptFunction("srSetRainBaseline", (void *)&srSetRainBaseline); + engine->RegisterScriptFunction("srSetRainTransparency", (void *)&srSetRainTransparency); + engine->RegisterScriptFunction("srSetRainDefaultView", (void *)&srSetRainDefaultView); + engine->RegisterScriptFunction("srSetRainWindSpeed", (void *)&srSetRainWindSpeed); + engine->RegisterScriptFunction("srSetRainAmount", (void *)&srSetRainAmount); + engine->RegisterScriptFunction("srSetRainView", (void *)&srSetRainView); + + engine->RegisterScriptFunction("srSetWindSpeed", (void *)&srSetWindSpeed); + engine->RegisterScriptFunction("srSetBaseline", (void *)&srSetBaseline); + + engine->RequestEventHook(AGSE_PREGUIDRAW); + engine->RequestEventHook(AGSE_PRESCREENDRAW); + engine->RequestEventHook(AGSE_ENTERROOM); + engine->RequestEventHook(AGSE_SAVEGAME); + engine->RequestEventHook(AGSE_RESTOREGAME); + + rain = new Weather; + snow = new Weather(true); +} + +void AGS_EngineShutdown() { + delete rain; + delete snow; +} + +int AGS_EngineOnEvent(int event, int data) { + if (event == AGSE_PREGUIDRAW) { + if (rain->IsActive()) + rain->Update(); + + if (snow->IsActive()) + snow->UpdateWithDrift(); + } else if (event == AGSE_ENTERROOM) { + rain->EnterRoom(); + snow->EnterRoom(); + } else if (event == AGSE_RESTOREGAME) { + rain->RestoreGame(data); + snow->RestoreGame(data); + } else if (event == AGSE_SAVEGAME) { + rain->SaveGame(data); + snow->SaveGame(data); + } else if (event == AGSE_PRESCREENDRAW) { + // Get screen size once here + engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); + engine->UnrequestEventHook(AGSE_PRESCREENDRAW); + } + + return 0; +} + +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { + return 0; +} + +void AGS_EngineInitGfx(const char *driverID, void *data) { +} + + + +#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) + +// ******************************************** +// *********** Editor Interface ************* +// ******************************************** + +const char *scriptHeader = + "import void srSetSnowDriftSpeed(int, int);\r\n" + "import void srSetSnowDriftRange(int, int);\r\n" + "import void srSetSnowFallSpeed(int, int);\r\n" + "import void srChangeSnowAmount(int);\r\n" + "import void srSetSnowBaseline(int, int);\r\n" + "import void srChangeRainAmount(int);\r\n" + "import void srSetRainView(int, int, int, int);\r\n" + "import void srSetRainTransparency(int, int);\r\n" + "import void srSetSnowTransparency(int, int);\r\n" + "import void srSetSnowDefaultView(int, int);\r\n" + "import void srSetRainDefaultView(int, int);\r\n" + "import void srSetRainWindSpeed(int);\r\n" + "import void srSetSnowWindSpeed(int);\r\n" + "import void srSetWindSpeed(int);\r\n" + "import void srSetRainBaseline(int, int);\r\n" + "import void srSetBaseline(int, int);\r\n" + "import void srSetSnowAmount(int);\r\n" + "import void srSetRainAmount(int);\r\n" + "import void srSetRainFallSpeed(int, int);\r\n" + "import void srSetSnowView(int, int, int, int);\r\n"; + + +IAGSEditor *editor; + + +LPCSTR AGS_GetPluginName(void) { + // Return the plugin description + return "Snow/Rain plugin recreation"; +} + +int AGS_EditorStartup(IAGSEditor *lpEditor) { + // User has checked the plugin to use it in their game + + // If it's an earlier version than what we need, abort. + if (lpEditor->version < 1) + return -1; + + editor = lpEditor; + editor->RegisterScriptHeader(scriptHeader); + + // Return 0 to indicate success + return 0; +} + +void AGS_EditorShutdown() { + // User has un-checked the plugin from their game + editor->UnregisterScriptHeader(scriptHeader); +} + +void AGS_EditorProperties(HWND parent) { + // User has chosen to view the Properties of the plugin + // We could load up an options dialog or something here instead + MessageBoxA(parent, "Snow/Rain plugin recreation by JJS", "About", MB_OK | MB_ICONINFORMATION); +} + +int AGS_EditorSaveGame(char *buffer, int bufsize) { + // We don't want to save any persistent data + return 0; +} + +void AGS_EditorLoadGame(char *buffer, int bufsize) { + // Nothing to load for this plugin +} + +#endif + + +#if defined(BUILTIN_PLUGINS) +} // namespace ags_snowrain +#endif diff --git a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.h b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.h new file mode 100644 index 000000000000..1d198af90bb1 --- /dev/null +++ b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.h @@ -0,0 +1,14 @@ +#ifndef AGS_SNOWRAIN_H +#define AGS_SNOWRAIN_H + +#include "plugin/agsplugin.h" + +namespace ags_snowrain { +void AGS_EngineStartup(IAGSEngine *lpEngine); +void AGS_EngineShutdown(); +int AGS_EngineOnEvent(int event, int data); +int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); +void AGS_EngineInitGfx(const char *driverID, void *data); +} + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp b/engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp new file mode 100644 index 000000000000..acbc19801d6d --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp @@ -0,0 +1,279 @@ +/*********************************************************** + * AGSBlend * + * * + * Author: Steven Poulton * + * * + * Date: 09/01/2011 * + * * + * Description: An AGS Plugin to allow true Alpha Blending * + * * + ***********************************************************/ + +#pragma region Defines_and_Includes + +#include "core/platform.h" + +#define MIN_EDITOR_VERSION 1 +#define MIN_ENGINE_VERSION 3 + +#if AGS_PLATFORM_OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#include +#endif + +#define THIS_IS_THE_PLUGIN +#include "plugin/agsplugin.h" +#include "SpriteFontRenderer.h" +#include "VariableWidthSpriteFont.h" + + +#define DEFAULT_RGB_R_SHIFT_32 16 +#define DEFAULT_RGB_G_SHIFT_32 8 +#define DEFAULT_RGB_B_SHIFT_32 0 +#define DEFAULT_RGB_A_SHIFT_32 24 + +#define abs(a) ((a)<0 ? -(a) : (a)) +#define ChannelBlend_Normal(B,L) ((uint8)(B)) +#define ChannelBlend_Lighten(B,L) ((uint8)((L > B) ? L:B)) +#define ChannelBlend_Darken(B,L) ((uint8)((L > B) ? B:L)) +#define ChannelBlend_Multiply(B,L) ((uint8)((B * L) / 255)) +#define ChannelBlend_Average(B,L) ((uint8)((B + L) / 2)) +#define ChannelBlend_Add(B,L) ((uint8)(min(255, (B + L)))) +#define ChannelBlend_Subtract(B,L) ((uint8)((B + L < 255) ? 0:(B + L - 255))) +#define ChannelBlend_Difference(B,L) ((uint8)(abs(B - L))) +#define ChannelBlend_Negation(B,L) ((uint8)(255 - abs(255 - B - L))) +#define ChannelBlend_Screen(B,L) ((uint8)(255 - (((255 - B) * (255 - L)) >> 8))) +#define ChannelBlend_Exclusion(B,L) ((uint8)(B + L - 2 * B * L / 255)) +#define ChannelBlend_Overlay(B,L) ((uint8)((L < 128) ? (2 * B * L / 255):(255 - 2 * (255 - B) * (255 - L) / 255))) +#define ChannelBlend_SoftLight(B,L) ((uint8)((L < 128)?(2*((B>>1)+64))*((float)L/255):(255-(2*(255-((B>>1)+64))*(float)(255-L)/255)))) +#define ChannelBlend_HardLight(B,L) (ChannelBlend_Overlay(L,B)) +#define ChannelBlend_ColorDodge(B,L) ((uint8)((L == 255) ? L:min(255, ((B << 8 ) / (255 - L))))) +#define ChannelBlend_ColorBurn(B,L) ((uint8)((L == 0) ? L:max(0, (255 - ((255 - B) << 8 ) / L)))) +#define ChannelBlend_LinearDodge(B,L)(ChannelBlend_Add(B,L)) +#define ChannelBlend_LinearBurn(B,L) (ChannelBlend_Subtract(B,L)) +#define ChannelBlend_LinearLight(B,L)((uint8)(L < 128)?ChannelBlend_LinearBurn(B,(2 * L)):ChannelBlend_LinearDodge(B,(2 * (L - 128)))) +#define ChannelBlend_VividLight(B,L) ((uint8)(L < 128)?ChannelBlend_ColorBurn(B,(2 * L)):ChannelBlend_ColorDodge(B,(2 * (L - 128)))) +#define ChannelBlend_PinLight(B,L) ((uint8)(L < 128)?ChannelBlend_Darken(B,(2 * L)):ChannelBlend_Lighten(B,(2 * (L - 128)))) +#define ChannelBlend_HardMix(B,L) ((uint8)((ChannelBlend_VividLight(B,L) < 128) ? 0:255)) +#define ChannelBlend_Reflect(B,L) ((uint8)((L == 255) ? L:min(255, (B * B / (255 - L))))) +#define ChannelBlend_Glow(B,L) (ChannelBlend_Reflect(L,B)) +#define ChannelBlend_Phoenix(B,L) ((uint8)(min(B,L) - max(B,L) + 255)) +#define ChannelBlend_Alpha(B,L,O) ((uint8)(O * B + (1 - O) * L)) +#define ChannelBlend_AlphaF(B,L,F,O) (ChannelBlend_Alpha(F(B,L),B,O)) + + +#pragma endregion + + +#if AGS_PLATFORM_OS_WINDOWS +// The standard Windows DLL entry point + +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) { + + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + + +//define engine + +IAGSEngine *engine = nullptr; +SpriteFontRenderer *fontRenderer = nullptr; +VariableWidthSpriteFontRenderer *vWidthRenderer = nullptr; + + + +void SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit) { + engine->PrintDebugConsole("AGSSpriteFont: SetSpriteFont"); + fontRenderer->SetSpriteFont(fontNum, sprite, rows, columns, charWidth, charHeight, charMin, charMax, use32bit); + engine->ReplaceFontRenderer(fontNum, fontRenderer); + +} + +void SetVariableSpriteFont(int fontNum, int sprite) { + engine->PrintDebugConsole("AGSSpriteFont: SetVariableFont"); + vWidthRenderer->SetSprite(fontNum, sprite); + engine->ReplaceFontRenderer(fontNum, vWidthRenderer); +} + +void SetGlyph(int fontNum, int charNum, int x, int y, int width, int height) { + engine->PrintDebugConsole("AGSSpriteFont: SetGlyph"); + vWidthRenderer->SetGlyph(fontNum, charNum, x, y, width, height); +} + +void SetSpacing(int fontNum, int spacing) { + engine->PrintDebugConsole("AGSSpriteFont: SetSpacing"); + vWidthRenderer->SetSpacing(fontNum, spacing); +} +//============================================================================== + +#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) +// ***** Design time ***** + +IAGSEditor *editor; // Editor interface + +const char *ourScriptHeader = + "import void SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit);\r\n" + "import void SetVariableSpriteFont(int fontNum, int sprite);\r\n" + "import void SetGlyph(int fontNum, int charNum, int x, int y, int width, int height);\r\n" + "import void SetSpacing(int fontNum, int spacing);\r\n" + ; + +//------------------------------------------------------------------------------ + +LPCSTR AGS_GetPluginName() { + return ("AGSSpriteFont"); +} + +//------------------------------------------------------------------------------ + +int AGS_EditorStartup(IAGSEditor *lpEditor) { + // User has checked the plugin to use it in their game + + // If it's an earlier version than what we need, abort. + if (lpEditor->version < MIN_EDITOR_VERSION) + return (-1); + + editor = lpEditor; + editor->RegisterScriptHeader(ourScriptHeader); + + // Return 0 to indicate success + return (0); +} + +//------------------------------------------------------------------------------ + +void AGS_EditorShutdown() { + // User has un-checked the plugin from their game + editor->UnregisterScriptHeader(ourScriptHeader); +} + +//------------------------------------------------------------------------------ + +void AGS_EditorProperties(HWND parent) { //*** optional *** + // User has chosen to view the Properties of the plugin + // We could load up an options dialog or something here instead + MessageBox(parent, + L"AGSSpriteFont v1.0 By Calin Leafshade", + L"About", + MB_OK | MB_ICONINFORMATION); +} + +//------------------------------------------------------------------------------ + +int AGS_EditorSaveGame(char *buffer, int bufsize) { //*** optional *** + // Called by the editor when the current game is saved to disk. + // Plugin configuration can be stored in [buffer] (max [bufsize] bytes) + // Return the amount of bytes written in the buffer + return (0); +} + +//------------------------------------------------------------------------------ + +void AGS_EditorLoadGame(char *buffer, int bufsize) { //*** optional *** + // Called by the editor when a game is loaded from disk + // Previous written data can be read from [buffer] (size [bufsize]). + // Make a copy of the data, the buffer is freed after this function call. +} + +//============================================================================== +#endif + + +// ***** Run time ***** + +// Engine interface + +//------------------------------------------------------------------------------ + +#define REGISTER(x) engine->RegisterScriptFunction(#x, (void *) (x)); +#define STRINGIFY(s) STRINGIFY_X(s) +#define STRINGIFY_X(s) #s + + + +void AGS_EngineStartup(IAGSEngine *lpEngine) { + engine = lpEngine; + engine->PrintDebugConsole("AGSSpriteFont: Init fixed width renderer"); + fontRenderer = new SpriteFontRenderer(engine); + engine->PrintDebugConsole("AGSSpriteFont: Init vari width renderer"); + vWidthRenderer = new VariableWidthSpriteFontRenderer(engine); + // Make sure it's got the version with the features we need + if (engine->version < MIN_ENGINE_VERSION) + engine->AbortGame("Plugin needs engine version " STRINGIFY(MIN_ENGINE_VERSION) " or newer."); + + //register functions + engine->PrintDebugConsole("AGSSpriteFont: Register functions"); + REGISTER(SetSpriteFont) + REGISTER(SetVariableSpriteFont) + REGISTER(SetGlyph) + REGISTER(SetSpacing) +} + +//------------------------------------------------------------------------------ + +void AGS_EngineShutdown() { + // Called by the game engine just before it exits. + // This gives you a chance to free any memory and do any cleanup + // that you need to do before the engine shuts down. +} + +//------------------------------------------------------------------------------ + +int AGS_EngineOnEvent(int event, int data) { //*** optional *** + switch (event) { + /* + case AGSE_KEYPRESS: + case AGSE_MOUSECLICK: + case AGSE_POSTSCREENDRAW: + case AGSE_PRESCREENDRAW: + case AGSE_SAVEGAME: + case AGSE_RESTOREGAME: + case AGSE_PREGUIDRAW: + case AGSE_LEAVEROOM: + case AGSE_ENTERROOM: + case AGSE_TRANSITIONIN: + case AGSE_TRANSITIONOUT: + case AGSE_FINALSCREENDRAW: + case AGSE_TRANSLATETEXT: + case AGSE_SCRIPTDEBUG: + case AGSE_SPRITELOAD: + case AGSE_PRERENDER: + case AGSE_PRESAVEGAME: + case AGSE_POSTRESTOREGAME: + */ + default: + break; + } + + // Return 1 to stop event from processing further (when needed) + return (0); +} + +//------------------------------------------------------------------------------ +/* +int AGS_EngineDebugHook(const char *scriptName, + int lineNum, int reserved) //*** optional *** +{ + // Can be used to debug scripts, see documentation +} +*/ +//------------------------------------------------------------------------------ +/* +void AGS_EngineInitGfx(const char *driverID, void *data) //*** optional *** +{ + // This allows you to make changes to how the graphics driver starts up. + // See documentation +} +*/ +//.............................................................................. diff --git a/engines/ags/plugins/ags_sprite_font/character_entry.cpp b/engines/ags/plugins/ags_sprite_font/character_entry.cpp new file mode 100644 index 000000000000..fa0575da7f96 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/character_entry.cpp @@ -0,0 +1,13 @@ +#include "CharacterEntry.h" + + +CharacterEntry::CharacterEntry(void) { + X = 0; + Y = 0; + Width = 0; + Height = 0; + Character = 0; +} + + +CharacterEntry::~CharacterEntry(void) = default; diff --git a/engines/ags/plugins/ags_sprite_font/character_entry.h b/engines/ags/plugins/ags_sprite_font/character_entry.h new file mode 100644 index 000000000000..2d2a23f1748c --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/character_entry.h @@ -0,0 +1,12 @@ +#pragma once +class CharacterEntry { +public: + CharacterEntry(void); + ~CharacterEntry(void); + int X; + int Y; + int Width; + int Height; + char Character; +}; + diff --git a/engines/ags/plugins/ags_sprite_font/color.cpp b/engines/ags/plugins/ags_sprite_font/color.cpp new file mode 100644 index 000000000000..9e9c13b957fd --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/color.cpp @@ -0,0 +1,28 @@ +#include "color.h" + +int getr32(int c) { + return ((c >> DEFAULT_RGB_R_SHIFT_32) & 0xFF); +} + + +int getg32(int c) { + return ((c >> DEFAULT_RGB_G_SHIFT_32) & 0xFF); +} + + +int getb32(int c) { + return ((c >> DEFAULT_RGB_B_SHIFT_32) & 0xFF); +} + + +int geta32(int c) { + return ((c >> DEFAULT_RGB_A_SHIFT_32) & 0xFF); +} + + +int makeacol32(int r, int g, int b, int a) { + return ((r << DEFAULT_RGB_R_SHIFT_32) | + (g << DEFAULT_RGB_G_SHIFT_32) | + (b << DEFAULT_RGB_B_SHIFT_32) | + (a << DEFAULT_RGB_A_SHIFT_32)); +} \ No newline at end of file diff --git a/engines/ags/plugins/ags_sprite_font/color.h b/engines/ags/plugins/ags_sprite_font/color.h new file mode 100644 index 000000000000..314f02a50d2b --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/color.h @@ -0,0 +1,21 @@ +#ifndef __COLORH +#define __COLORH + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define DEFAULT_RGB_R_SHIFT_32 16 +#define DEFAULT_RGB_G_SHIFT_32 8 +#define DEFAULT_RGB_B_SHIFT_32 0 +#define DEFAULT_RGB_A_SHIFT_32 24 + +#pragma region Color_Functions + + +int getr32(int c); +int getg32(int c); +int getb32(int c); +int geta32(int c); +int makeacol32(int r, int g, int b, int a); + +#pragma endregion + +#endif \ No newline at end of file diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font.cpp b/engines/ags/plugins/ags_sprite_font/sprite_font.cpp new file mode 100644 index 000000000000..19e4ea1997af --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/sprite_font.cpp @@ -0,0 +1,7 @@ +#include "SpriteFont.h" + + +SpriteFont::SpriteFont(void) = default; + + +SpriteFont::~SpriteFont(void) = default; diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font.h b/engines/ags/plugins/ags_sprite_font/sprite_font.h new file mode 100644 index 000000000000..860aaddeae96 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/sprite_font.h @@ -0,0 +1,16 @@ +#pragma once +class SpriteFont { +public: + SpriteFont(void); + ~SpriteFont(void); + int SpriteNumber; + int MinChar; + int MaxChar; + int Rows; + int Columns; + int FontReplaced; + int CharHeight; + int CharWidth; + bool Use32bit; +}; + diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp new file mode 100644 index 000000000000..c12fca038260 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp @@ -0,0 +1,171 @@ +#include "SpriteFontRenderer.h" +#include +#include +#include "color.h" + + + +SpriteFontRenderer::SpriteFontRenderer(IAGSEngine *engine) { + _engine = engine; +} + + +SpriteFontRenderer::~SpriteFontRenderer(void) = default; + +void SpriteFontRenderer::SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit) { + SpriteFont *font = getFontFor(fontNum); + font->SpriteNumber = sprite; + font->Rows = rows; + font->Columns = columns; + font->MinChar = charMin; + font->MaxChar = charMax; + font->Use32bit = use32bit; + font->CharHeight = charHeight; + font->CharWidth = charWidth; + +} + +void SpriteFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) { + SpriteFont *font = getFontFor(fontNumber); + for (int i = 0; i < strlen(text); i++) { + if (text[i] < font->MinChar || text[i] > font->MaxChar) { + if (font->MinChar < 63 || font->MaxChar > 63) text[i] = 63; + else text[i] = font->MinChar; + + } + + } +} + +bool SpriteFontRenderer::SupportsExtendedCharacters(int fontNumber) { + return false; +} + +int SpriteFontRenderer::GetTextWidth(const char *text, int fontNumber) { + SpriteFont *font = getFontFor(fontNumber); + int len = strlen(text); + return font->CharWidth * len; + +} + +int SpriteFontRenderer::GetTextHeight(const char *text, int fontNumber) { + SpriteFont *font = getFontFor(fontNumber); + return font->CharHeight; +} + +SpriteFont *SpriteFontRenderer::getFontFor(int fontNum) { + SpriteFont *font; + for (int i = 0; i < _fonts.size(); i ++) { + font = _fonts.at(i); + if (font->FontReplaced == fontNum) return font; + } + //not found + font = new SpriteFont(); + font->FontReplaced = fontNum; + _fonts.push_back(font); + return font; +} + + + +void SpriteFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) { + + SpriteFont *font = getFontFor(fontNumber); + BITMAP *vScreen = _engine->GetVirtualScreen(); + + //_engine->SetVirtualScreen(destination); + + for (int i = 0; i < strlen(text); i++) { + char c = text[i]; + c -= font->MinChar; + int row = c / font->Columns; + int column = c % font->Columns; + BITMAP *src = _engine->GetSpriteGraphic(font->SpriteNumber); + Draw(src, destination, x + (i * font->CharWidth), y, column * font->CharWidth, row * font->CharHeight, font->CharWidth, font->CharHeight); + } + + //_engine->SetVirtualScreen(vScreen); +} + + + + +void SpriteFontRenderer::Draw(BITMAP *src, BITMAP *dest, int destx, int desty, int srcx, int srcy, int width, int height) { + + int srcWidth, srcHeight, destWidth, destHeight, srcColDepth, destColDepth; + + unsigned char **srccharbuffer = _engine->GetRawBitmapSurface(src); //8bit + unsigned short **srcshortbuffer = (unsigned short **)srccharbuffer; //16bit; + unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; //32bit + + unsigned char **destcharbuffer = _engine->GetRawBitmapSurface(dest); //8bit + unsigned short **destshortbuffer = (unsigned short **)destcharbuffer; //16bit; + unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; //32bit + + int transColor = _engine->GetBitmapTransparentColor(src); + + _engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, &srcColDepth); + _engine->GetBitmapDimensions(dest, &destWidth, &destHeight, &destColDepth); + + if (srcy + height > srcHeight || srcx + width > srcWidth || srcx < 0 || srcy < 0) return; + + if (width + destx > destWidth) width = destWidth - destx; + if (height + desty > destHeight) height = destHeight - desty; + + int startx = MAX(0, (-1 * destx)); + int starty = MAX(0, (-1 * desty)); + + + int srca, srcr, srcg, srcb, desta, destr, destg, destb, finalr, finalg, finalb, finala, col; + + for (int x = startx; x < width; x ++) { + + for (int y = starty; y < height; y ++) { + int srcyy = y + srcy; + int srcxx = x + srcx; + int destyy = y + desty; + int destxx = x + destx; + if (destColDepth == 8) { + if (srccharbuffer[srcyy][srcxx] != transColor) destcharbuffer[destyy][destxx] = srccharbuffer[srcyy][srcxx]; + } else if (destColDepth == 16) { + if (srcshortbuffer[srcyy][srcxx] != transColor) destshortbuffer[destyy][destxx] = srcshortbuffer[srcyy][srcxx]; + } else if (destColDepth == 32) { + //if (srclongbuffer[srcyy][srcxx] != transColor) destlongbuffer[destyy][destxx] = srclongbuffer[srcyy][srcxx]; + + srca = (geta32(srclongbuffer[srcyy][srcxx])); + + if (srca != 0) { + + srcr = getr32(srclongbuffer[srcyy][srcxx]); + srcg = getg32(srclongbuffer[srcyy][srcxx]); + srcb = getb32(srclongbuffer[srcyy][srcxx]); + + destr = getr32(destlongbuffer[destyy][destxx]); + destg = getg32(destlongbuffer[destyy][destxx]); + destb = getb32(destlongbuffer[destyy][destxx]); + desta = geta32(destlongbuffer[destyy][destxx]); + + + finalr = srcr; + finalg = srcg; + finalb = srcb; + + + finala = 255 - (255 - srca) * (255 - desta) / 255; + finalr = srca * finalr / finala + desta * destr * (255 - srca) / finala / 255; + finalg = srca * finalg / finala + desta * destg * (255 - srca) / finala / 255; + finalb = srca * finalb / finala + desta * destb * (255 - srca) / finala / 255; + col = makeacol32(finalr, finalg, finalb, finala); + destlongbuffer[destyy][destxx] = col; + } + + } + } + } + + _engine->ReleaseBitmapSurface(src); + _engine->ReleaseBitmapSurface(dest); + + + +} \ No newline at end of file diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h new file mode 100644 index 000000000000..0fcd57684f83 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h @@ -0,0 +1,29 @@ +#pragma once +#include "plugin/agsplugin.h" +#include "SpriteFont.h" +#include +class SpriteFontRenderer : + public IAGSFontRenderer { +public: + SpriteFontRenderer(IAGSEngine *engine); + ~SpriteFontRenderer(void); + bool LoadFromDisk(int fontNumber, int fontSize) override { + return true; + } + void FreeMemory(int fontNumber) override { } + bool SupportsExtendedCharacters(int fontNumber) override; + int GetTextWidth(const char *text, int fontNumber) override; + int GetTextHeight(const char *text, int fontNumber) override; + void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override; + void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override { } + void EnsureTextValidForFont(char *text, int fontNumber) override; + void SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit); + + +private: + SpriteFont *getFontFor(int fontNum); + void Draw(BITMAP *src, BITMAP *dest, int destx, int desty, int srcx, int srcy, int width, int height); + std::vector _fonts; + IAGSEngine *_engine; +}; + diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_font.cpp b/engines/ags/plugins/ags_sprite_font/variable_width_font.cpp new file mode 100644 index 000000000000..41baaac170ce --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/variable_width_font.cpp @@ -0,0 +1,19 @@ +#include "VariableWidthFont.h" + + +VariableWidthFont::VariableWidthFont(void) { + Spacing = 0; + FontReplaced = 0; + SpriteNumber = 0; +} + + +VariableWidthFont::~VariableWidthFont(void) = default; + +void VariableWidthFont::SetGlyph(int character, int x, int y, int width, int height) { + characters[character].X = x; + characters[character].Y = y; + characters[character].Width = width; + characters[character].Height = height; + characters[character].Character = character; +} diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_font.h b/engines/ags/plugins/ags_sprite_font/variable_width_font.h new file mode 100644 index 000000000000..8eda7123cff0 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/variable_width_font.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include "CharacterEntry.h" +#include "plugin/agsplugin.h" +class VariableWidthFont { +public: + VariableWidthFont(void); + ~VariableWidthFont(void); + void SetGlyph(int character, int x, int y, int width, int height); + int SpriteNumber; + int FontReplaced; + int Spacing; + std::map characters; + +private: + +}; + diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp new file mode 100644 index 000000000000..b6015ef8e1e7 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp @@ -0,0 +1,182 @@ +#include "VariableWidthSpriteFont.h" +#include +#include +#include "color.h" + + + +VariableWidthSpriteFontRenderer::VariableWidthSpriteFontRenderer(IAGSEngine *engine) { + _engine = engine; +} + + +VariableWidthSpriteFontRenderer::~VariableWidthSpriteFontRenderer(void) = default; + + + + +bool VariableWidthSpriteFontRenderer::SupportsExtendedCharacters(int fontNumber) { + return false; +} + +int VariableWidthSpriteFontRenderer::GetTextWidth(const char *text, int fontNumber) { + int total = 0; + VariableWidthFont *font = getFontFor(fontNumber); + for (int i = 0; i < strlen(text); i++) { + if (font->characters.count(text[i]) > 0) { + total += font->characters[text[i]].Width; + if (text[i] != ' ') total += font->Spacing; + } + } + return total; +} + +int VariableWidthSpriteFontRenderer::GetTextHeight(const char *text, int fontNumber) { + VariableWidthFont *font = getFontFor(fontNumber); + for (int i = 0; i < strlen(text); i++) { + if (font->characters.count(text[i]) > 0) { + return font->characters[text[i]].Height; + } + } + return 0; +} + +void VariableWidthSpriteFontRenderer::SetSpacing(int fontNum, int spacing) { + VariableWidthFont *font = getFontFor(fontNum); + font->Spacing = spacing; + + +} + +void VariableWidthSpriteFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) { + VariableWidthFont *font = getFontFor(fontNumber); + std::string s(text); + + for (int i = s.length() - 1; i >= 0 ; i--) { + if (font->characters.count(s[i]) == 0) { + s.erase(i, 1); + } + } + text = strcpy(text, s.c_str()); + +} + +void VariableWidthSpriteFontRenderer::SetGlyph(int fontNum, int charNum, int x, int y, int width, int height) { + VariableWidthFont *font = getFontFor(fontNum); + font->SetGlyph(charNum, x, y, width, height); +} + + +void VariableWidthSpriteFontRenderer::SetSprite(int fontNum, int spriteNum) { + VariableWidthFont *font = getFontFor(fontNum); + font->SpriteNumber = spriteNum; +} + +VariableWidthFont *VariableWidthSpriteFontRenderer::getFontFor(int fontNum) { + VariableWidthFont *font; + for (int i = 0; i < _fonts.size(); i ++) { + font = _fonts.at(i); + if (font->FontReplaced == fontNum) return font; + } + //not found + font = new VariableWidthFont; + font->FontReplaced = fontNum; + _fonts.push_back(font); + return font; +} + +void VariableWidthSpriteFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) { + VariableWidthFont *font = getFontFor(fontNumber); + int totalWidth = 0; + for (int i = 0; i < strlen(text); i++) { + char c = text[i]; + + BITMAP *src = _engine->GetSpriteGraphic(font->SpriteNumber); + Draw(src, destination, x + totalWidth, y, font->characters[c].X, font->characters[c].Y, font->characters[c].Width, font->characters[c].Height); + totalWidth += font->characters[c].Width; + if (text[i] != ' ') totalWidth += font->Spacing; + } + +} + + +void VariableWidthSpriteFontRenderer::Draw(BITMAP *src, BITMAP *dest, int destx, int desty, int srcx, int srcy, int width, int height) { + + int srcWidth, srcHeight, destWidth, destHeight, srcColDepth, destColDepth; + + unsigned char **srccharbuffer = _engine->GetRawBitmapSurface(src); //8bit + unsigned short **srcshortbuffer = (unsigned short **)srccharbuffer; //16bit; + unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; //32bit + + unsigned char **destcharbuffer = _engine->GetRawBitmapSurface(dest); //8bit + unsigned short **destshortbuffer = (unsigned short **)destcharbuffer; //16bit; + unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; //32bit + + int transColor = _engine->GetBitmapTransparentColor(src); + + _engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, &srcColDepth); + _engine->GetBitmapDimensions(dest, &destWidth, &destHeight, &destColDepth); + + if (srcy + height > srcHeight || srcx + width > srcWidth || srcx < 0 || srcy < 0) return; + + if (width + destx > destWidth) width = destWidth - destx; + if (height + desty > destHeight) height = destHeight - desty; + + int startx = MAX(0, (-1 * destx)); + int starty = MAX(0, (-1 * desty)); + + + int srca, srcr, srcg, srcb, desta, destr, destg, destb, finalr, finalg, finalb, finala, col; + + for (int x = startx; x < width; x ++) { + + for (int y = starty; y < height; y ++) { + int srcyy = y + srcy; + int srcxx = x + srcx; + int destyy = y + desty; + int destxx = x + destx; + if (destColDepth == 8) { + if (srccharbuffer[srcyy][srcxx] != transColor) destcharbuffer[destyy][destxx] = srccharbuffer[srcyy][srcxx]; + } else if (destColDepth == 16) { + if (srcshortbuffer[srcyy][srcxx] != transColor) destshortbuffer[destyy][destxx] = srcshortbuffer[srcyy][srcxx]; + } else if (destColDepth == 32) { + //if (srclongbuffer[srcyy][srcxx] != transColor) destlongbuffer[destyy][destxx] = srclongbuffer[srcyy][srcxx]; + + srca = (geta32(srclongbuffer[srcyy][srcxx])); + + if (srca != 0) { + + srcr = getr32(srclongbuffer[srcyy][srcxx]); + srcg = getg32(srclongbuffer[srcyy][srcxx]); + srcb = getb32(srclongbuffer[srcyy][srcxx]); + + destr = getr32(destlongbuffer[destyy][destxx]); + destg = getg32(destlongbuffer[destyy][destxx]); + destb = getb32(destlongbuffer[destyy][destxx]); + desta = geta32(destlongbuffer[destyy][destxx]); + + + finalr = srcr; + finalg = srcg; + finalb = srcb; + + + finala = 255 - (255 - srca) * (255 - desta) / 255; + finalr = srca * finalr / finala + desta * destr * (255 - srca) / finala / 255; + finalg = srca * finalg / finala + desta * destg * (255 - srca) / finala / 255; + finalb = srca * finalb / finala + desta * destb * (255 - srca) / finala / 255; + col = makeacol32(finalr, finalg, finalb, finala); + destlongbuffer[destyy][destxx] = col; + } + + } + } + } + + _engine->ReleaseBitmapSurface(src); + _engine->ReleaseBitmapSurface(dest); + + + +} + diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h new file mode 100644 index 000000000000..30b5211ca387 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h @@ -0,0 +1,30 @@ +#pragma once +#include "plugin/agsplugin.h" +#include "VariableWidthFont.h" +#include +class VariableWidthSpriteFontRenderer : + public IAGSFontRenderer { +public: + VariableWidthSpriteFontRenderer(IAGSEngine *engine); + ~VariableWidthSpriteFontRenderer(void); + bool LoadFromDisk(int fontNumber, int fontSize) override { + return true; + } + void FreeMemory(int fontNumber) override { } + bool SupportsExtendedCharacters(int fontNumber) override; + int GetTextWidth(const char *text, int fontNumber) override; + int GetTextHeight(const char *text, int fontNumber) override; + void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) override; + void AdjustYCoordinateForFont(int *ycoord, int fontNumber) override { } + void EnsureTextValidForFont(char *text, int fontNumber) override; + void SetGlyph(int fontNum, int charNum, int x, int y, int width, int height); + void SetSprite(int fontNum, int spriteNum); + void SetSpacing(int fontNum, int spacing); + +private: + IAGSEngine *_engine; + std::vector _fonts; + VariableWidthFont *getFontFor(int fontNum); + void Draw(BITMAP *src, BITMAP *dest, int destx, int desty, int srcx, int srcy, int width, int height); +}; + diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index 76dcb86a23c5..1662de7958f0 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -22,7 +22,7 @@ #include "ags/lib/allegro.h" #include "ags/plugins/dll.h" -#include "ags/plugins/agscreditz/agscreditz.h" +#include "ags/plugins/ags_creditz/ags_creditz.h" #include "ags/ags.h" #include "ags/detection.h" #include "common/str.h" @@ -36,7 +36,7 @@ void *dlopen(const char *filename) { // Check for if the game specifies a specific plugin version for this game int version = 0; for (const ::AGS::PluginVersion *v = ::AGS::g_vm->getNeededPlugins(); - v->_plugin; ++v) { + v->_plugin; ++v) { if (Common::String::format("lib%s.so", v->_plugin).equalsIgnoreCase(filename)) { version = v->_version; break; diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h index d1e9c768a307..5b797a3d4977 100644 --- a/engines/ags/plugins/dll.h +++ b/engines/ags/plugins/dll.h @@ -91,7 +91,9 @@ class DLL { protected: Common::HashMap _methods; - static int AGS_PluginV2() { return 1; } + static int AGS_PluginV2() { + return 1; + } static int AGS_EditorStartup(IAGSEditor *); static void AGS_EditorShutdown(); static void AGS_EditorProperties(HWND); From 017ca18d81ab279b60e99da45ef19fe60f40c567 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 11:52:50 -0800 Subject: [PATCH 168/215] AGS: Added AGSFlashlight plugin --- engines/ags/module.mk | 3 +- .../plugins/ags_flashlight/ags_flashlight.cpp | 576 ++++++++---------- .../plugins/ags_flashlight/ags_flashlight.h | 140 ++++- engines/ags/plugins/dll.cpp | 3 + 4 files changed, 390 insertions(+), 332 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index ad2657cdcd40..75c55be1144d 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -301,7 +301,8 @@ MODULE_OBJS = \ engine/script/script_runtime.o \ engine/script/systemimports.o \ plugins/dll.o \ - plugins/ags_creditz/ags_creditz.o + plugins/ags_creditz/ags_creditz.o \ + plugins/ags_flashlight/ags_flashlight.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp index 663e81c1b180..c36e7ec40100 100644 --- a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp @@ -1,131 +1,241 @@ -/* +/* 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 is not the AGS Flashlight plugin, -but a workalike plugin created by JJS for the AGS engine PSP port. +#include "ags/lib/allegro.h" +#include "ags/plugins/ags_flashlight/ags_flashlight.h" +#include "ags/shared/core/platform.h" +#include "common/str.h" -*/ +namespace AGS3 { +namespace Plugins { +namespace AGSFlashlight { -#include "core/platform.h" +const unsigned int Magic = 0xBABE0000; +const unsigned int Version = 2; +const unsigned int SaveMagic = Magic + Version; +const float PI = 3.14159265f; -#if AGS_PLATFORM_OS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#pragma warning(disable : 4244) -#endif +int AGSFlashlight::AGSFlashlight::screen_width = 320; +int AGSFlashlight::screen_height = 200; +int AGSFlashlight::screen_color_depth = 16; -#if !defined(BUILTIN_PLUGINS) -#define THIS_IS_THE_PLUGIN -#endif +bool AGSFlashlight::g_BitmapMustBeUpdated = true; -#include -#include -#include -#include +int AGSFlashlight::g_RedTint = 0; +int AGSFlashlight::g_GreenTint = 0; +int AGSFlashlight::g_BlueTint = 0; -#if defined(PSP_VERSION) -#include -#include -#include -#define sin(x) vfpu_sinf(x) -#endif +int AGSFlashlight::g_DarknessLightLevel = 100; +int AGSFlashlight::g_BrightnessLightLevel = 100; +int AGSFlashlight::g_DarknessSize = 0; +int AGSFlashlight::g_DarknessDiameter = 0; +int AGSFlashlight::g_BrightnessSize = 0; -#include "plugin/agsplugin.h" +int AGSFlashlight::g_FlashlightX = 0; +int AGSFlashlight::g_FlashlightY = 0; +int AGSFlashlight::g_FlashlightDrawAtX = 0; +int AGSFlashlight::g_FlashlightDrawAtY = 0; -#if defined(BUILTIN_PLUGINS) -namespace agsflashlight { -#endif +bool AGSFlashlight::g_FlashlightFollowMouse = false; -#if defined(__GNUC__) -inline unsigned long _blender_alpha16_bgr(unsigned long y) __attribute__((always_inline)); -inline void calc_x_n(unsigned long bla) __attribute__((always_inline)); -#endif +int AGSFlashlight::g_FollowCharacterId = 0; +int AGSFlashlight::g_FollowCharacterDx = 0; +int AGSFlashlight::g_FollowCharacterDy = 0; +int AGSFlashlight::g_FollowCharacterHorz = 0; +int AGSFlashlight::g_FollowCharacterVert = 0; -const unsigned int Magic = 0xBABE0000; -const unsigned int Version = 2; -const unsigned int SaveMagic = Magic + Version; -const float PI = 3.14159265f; +AGSCharacter *AGSFlashlight::g_FollowCharacter = nullptr; + +BITMAP *AGSFlashlight::g_LightBitmap = nullptr; -int screen_width = 320; -int screen_height = 200; -int screen_color_depth = 16; +unsigned long AGSFlashlight::flashlight_x; +unsigned long AGSFlashlight::flashlight_n; -IAGSEngine *engine; -bool g_BitmapMustBeUpdated = true; +IAGSEngine *AGSFlashlight::_engine; -int g_RedTint = 0; -int g_GreenTint = 0; -int g_BlueTint = 0; +AGSFlashlight::AGSFlashlight() { + _engine = nullptr; + screen_width = 320; + screen_height = 200; + screen_color_depth = 16; -int g_DarknessLightLevel = 100; -int g_BrightnessLightLevel = 100; -int g_DarknessSize = 0; -int g_DarknessDiameter = 0; -int g_BrightnessSize = 0; + g_BitmapMustBeUpdated = true; -int g_FlashlightX = 0; -int g_FlashlightY = 0; -int g_FlashlightDrawAtX = 0; -int g_FlashlightDrawAtY = 0; + g_RedTint = 0; + g_GreenTint = 0; + g_BlueTint = 0; -bool g_FlashlightFollowMouse = false; + g_DarknessLightLevel = 100; + g_BrightnessLightLevel = 100; + g_DarknessSize = 0; + g_DarknessDiameter = 0; + g_BrightnessSize = 0; -int g_FollowCharacterId = 0; -int g_FollowCharacterDx = 0; -int g_FollowCharacterDy = 0; -int g_FollowCharacterHorz = 0; -int g_FollowCharacterVert = 0; + g_FlashlightX = 0; + g_FlashlightY = 0; + g_FlashlightDrawAtX = 0; + g_FlashlightDrawAtY = 0; -AGSCharacter *g_FollowCharacter = nullptr; + g_FlashlightFollowMouse = false; -BITMAP *g_LightBitmap = nullptr; + g_FollowCharacterId = 0; + g_FollowCharacterDx = 0; + g_FollowCharacterDy = 0; + g_FollowCharacterHorz = 0; + g_FollowCharacterVert = 0; + g_FollowCharacter = nullptr; + g_LightBitmap = nullptr; + flashlight_x = 0; + flashlight_n = 0; -// This function is from Allegro, split for more performance. -/* _blender_alpha16_bgr - * Combines a 32 bit RGBA sprite with a 16 bit RGB destination, optimised - * for when one pixel is in an RGB layout and the other is BGR. - */ + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineShutdown); + DLL_METHOD(AGS_EngineOnEvent); + DLL_METHOD(AGS_EngineDebugHook); + DLL_METHOD(AGS_EngineInitGfx); +} + +const char *AGSFlashlight::AGS_GetPluginName() { + return "Flashlight plugin recreation"; +} -unsigned long x, n; +void AGSFlashlight::AGS_EngineStartup(IAGSEngine *engine) { + _engine = engine; -inline void calc_x_n(unsigned long _x) { - x = _x; + if (_engine->version < 13) + _engine->AbortGame("Engine interface is too old, need newer version of AGS."); + + SCRIPT_METHOD("SetFlashlightTint"); + SCRIPT_METHOD("GetFlashlightTintRed"); + SCRIPT_METHOD("GetFlashlightTintGreen"); + SCRIPT_METHOD("GetFlashlightTintBlue"); + + SCRIPT_METHOD("GetFlashlightMinLightLevel"); + SCRIPT_METHOD("GetFlashlightMaxLightLevel"); + + SCRIPT_METHOD("SetFlashlightDarkness"); + SCRIPT_METHOD("GetFlashlightDarkness"); + SCRIPT_METHOD("SetFlashlightDarknessSize"); + SCRIPT_METHOD("GetFlashlightDarknessSize"); + + SCRIPT_METHOD("SetFlashlightBrightness"); + SCRIPT_METHOD("GetFlashlightBrightness"); + SCRIPT_METHOD("SetFlashlightBrightnessSize"); + SCRIPT_METHOD("GetFlashlightBrightnessSize"); + + SCRIPT_METHOD("SetFlashlightPosition"); + SCRIPT_METHOD("GetFlashlightPositionX"); + SCRIPT_METHOD("GetFlashlightPositionY"); + + + SCRIPT_METHOD("SetFlashlightFollowMouse"); + SCRIPT_METHOD("GetFlashlightFollowMouse"); + + SCRIPT_METHOD("SetFlashlightFollowCharacter"); + SCRIPT_METHOD("GetFlashlightFollowCharacter"); + SCRIPT_METHOD("GetFlashlightCharacterDX"); + SCRIPT_METHOD("GetFlashlightCharacterDY"); + SCRIPT_METHOD("GetFlashlightCharacterHorz"); + SCRIPT_METHOD("GetFlashlightCharacterVert"); + + SCRIPT_METHOD("SetFlashlightMask"); + SCRIPT_METHOD("GetFlashlightMask"); + + _engine->RequestEventHook(AGSE_PREGUIDRAW); + _engine->RequestEventHook(AGSE_PRESCREENDRAW); + _engine->RequestEventHook(AGSE_SAVEGAME); + _engine->RequestEventHook(AGSE_RESTOREGAME); +} + +void AGSFlashlight::AGS_EngineShutdown() { +} + +int AGSFlashlight::AGS_EngineOnEvent(int event, int data) { + if (event == AGSE_PREGUIDRAW) { + Update(); + } else if (event == AGSE_RESTOREGAME) { + RestoreGame(data); + } else if (event == AGSE_SAVEGAME) { + SaveGame(data); + } else if (event == AGSE_PRESCREENDRAW) { + // Get screen size once here. + _engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); + _engine->UnrequestEventHook(AGSE_PRESCREENDRAW); - n = x >> 24; + // Only 16 bit color depth is supported. + if (screen_color_depth != 16) { + _engine->UnrequestEventHook(AGSE_PREGUIDRAW); + _engine->UnrequestEventHook(AGSE_PRESCREENDRAW); + _engine->UnrequestEventHook(AGSE_SAVEGAME); + _engine->UnrequestEventHook(AGSE_RESTOREGAME); + } + } - if (n) - n = (n + 1) / 8; + return 0; +} - x = ((x >> 19) & 0x001F) | ((x >> 5) & 0x07E0) | ((x << 8) & 0xF800); +int AGSFlashlight::AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { + return 0; +} - x = (x | (x << 16)) & 0x7E0F81F; +void AGSFlashlight::AGS_EngineInitGfx(const char *driverID, void *data) { } -inline unsigned long _blender_alpha16_bgr(unsigned long y) { +void AGSFlashlight::calc_x_n(unsigned long x) { + flashlight_x = x; + + flashlight_n = flashlight_x >> 24; + + if (flashlight_n) + flashlight_n = (flashlight_n + 1) / 8; + + flashlight_x = ((flashlight_x >> 19) & 0x001F) | ((flashlight_x >> 5) & 0x07E0) | ((flashlight_x << 8) & 0xF800); + + flashlight_x = (flashlight_x | (flashlight_x << 16)) & 0x7E0F81F; +} + +inline unsigned long AGSFlashlight::_blender_alpha16_bgr(unsigned long y) { unsigned long result; y = ((y & 0xFFFF) | (y << 16)) & 0x7E0F81F; - result = ((x - y) * n / 32 + y) & 0x7E0F81F; + result = ((flashlight_x - y) * flashlight_n / 32 + y) & 0x7E0F81F; return ((result & 0xFFFF) | (result >> 16)); } - - -inline void setPixel(int x, int y, int color, unsigned int *pixel) { +inline void AGSFlashlight::setPixel(int x, int y, int color, unsigned int *pixel) { if ((x >= g_DarknessDiameter) || (y >= g_DarknessDiameter) || (x < 0) || (y < 0)) return; *(pixel + (y * g_DarknessDiameter) + x) = color; } - -void plotCircle(int xm, int ym, int r, unsigned int color) { - unsigned int *pixel = *(unsigned int **)engine->GetRawBitmapSurface(g_LightBitmap); +void AGSFlashlight::plotCircle(int xm, int ym, int r, unsigned int color) { + unsigned int *pixel = *(unsigned int **)_engine->GetRawBitmapSurface(g_LightBitmap); int x = -r; int y = 0; @@ -152,11 +262,10 @@ void plotCircle(int xm, int ym, int r, unsigned int color) { err += ++y * 2 + 1; } while (x < 0); - engine->ReleaseBitmapSurface(g_LightBitmap); + _engine->ReleaseBitmapSurface(g_LightBitmap); } - -void ClipToRange(int &variable, int min, int max) { +void AGSFlashlight::ClipToRange(int &variable, int min, int max) { if (variable < min) variable = min; @@ -164,10 +273,9 @@ void ClipToRange(int &variable, int min, int max) { variable = max; } - -void AlphaBlendBitmap() { - unsigned short *destpixel = *(unsigned short **)engine->GetRawBitmapSurface(engine->GetVirtualScreen()); - unsigned int *sourcepixel = *(unsigned int **)engine->GetRawBitmapSurface(g_LightBitmap); +void AGSFlashlight::AlphaBlendBitmap() { + unsigned short *destpixel = *(unsigned short **)_engine->GetRawBitmapSurface(_engine->GetVirtualScreen()); + unsigned int *sourcepixel = *(unsigned int **)_engine->GetRawBitmapSurface(g_LightBitmap); unsigned short *currentdestpixel = destpixel; unsigned int *currentsourcepixel = sourcepixel; @@ -196,21 +304,20 @@ void AlphaBlendBitmap() { } } - engine->ReleaseBitmapSurface(engine->GetVirtualScreen()); - engine->ReleaseBitmapSurface(g_LightBitmap); + _engine->ReleaseBitmapSurface(_engine->GetVirtualScreen()); + _engine->ReleaseBitmapSurface(g_LightBitmap); } - -void DrawTint() { +void AGSFlashlight::DrawTint() { int x, y; - BITMAP *screen = engine->GetVirtualScreen(); - unsigned short *destpixel = *(unsigned short **)engine->GetRawBitmapSurface(screen); + BITMAP *screen = _engine->GetVirtualScreen(); + unsigned short *destpixel = *(unsigned short **)_engine->GetRawBitmapSurface(screen); int32 red, blue, green, alpha; for (y = 0; y < screen_height; y++) { for (x = 0; x < screen_width; x++) { - engine->GetRawColorComponents(16, *destpixel, &red, &green, &blue, &alpha); + _engine->GetRawColorComponents(16, *destpixel, &red, &green, &blue, &alpha); if (g_RedTint != 0) { red += g_RedTint * 8; @@ -236,20 +343,19 @@ void DrawTint() { green = 0; } - *destpixel = engine->MakeRawColorPixel(16, red, green, blue, alpha); + *destpixel = _engine->MakeRawColorPixel(16, red, green, blue, alpha); destpixel++; } } - engine->ReleaseBitmapSurface(screen); + _engine->ReleaseBitmapSurface(screen); } - -void DrawDarkness() { +void AGSFlashlight::DrawDarkness() { int x, y; unsigned int color = (255 - (int)((float)g_DarknessLightLevel * 2.55f)) << 24; - BITMAP *screen = engine->GetVirtualScreen(); - unsigned short *destpixel = *(unsigned short **)engine->GetRawBitmapSurface(screen); + BITMAP *screen = _engine->GetVirtualScreen(); + unsigned short *destpixel = *(unsigned short **)_engine->GetRawBitmapSurface(screen); unsigned short *currentpixel; calc_x_n(color); @@ -314,22 +420,21 @@ void DrawDarkness() { } } - engine->ReleaseBitmapSurface(screen); + _engine->ReleaseBitmapSurface(screen); } - -void CreateLightBitmap() { +void AGSFlashlight::CreateLightBitmap() { if (g_DarknessSize == 0) return; if (g_LightBitmap) - engine->FreeBitmap(g_LightBitmap); + _engine->FreeBitmap(g_LightBitmap); - g_LightBitmap = engine->CreateBlankBitmap(g_DarknessDiameter, g_DarknessDiameter, 32); + g_LightBitmap = _engine->CreateBlankBitmap(g_DarknessDiameter, g_DarknessDiameter, 32); // Fill with darkness color. unsigned int color = (255 - (int)((float)g_DarknessLightLevel * 2.55f)) << 24; - unsigned int *pixel = *(unsigned int **)engine->GetRawBitmapSurface(g_LightBitmap); + unsigned int *pixel = *(unsigned int **)_engine->GetRawBitmapSurface(g_LightBitmap); int i; for (i = 0; i < g_DarknessDiameter * g_DarknessDiameter; i++) @@ -356,7 +461,7 @@ void CreateLightBitmap() { current_value += increment; - if (current_value > targetcolor) + if ((uint)current_value > targetcolor) current_value = targetcolor; plotCircle(g_DarknessSize, g_DarknessSize, i, (current_value << 24) + color); @@ -371,18 +476,17 @@ void CreateLightBitmap() { plotCircle(g_DarknessSize, g_DarknessSize, i, color); } - engine->ReleaseBitmapSurface(g_LightBitmap); + _engine->ReleaseBitmapSurface(g_LightBitmap); } - -void Update() { +void AGSFlashlight::Update() { if (g_BitmapMustBeUpdated) { CreateLightBitmap(); g_BitmapMustBeUpdated = false; } if (g_FlashlightFollowMouse) { - engine->GetMousePosition(&g_FlashlightX, &g_FlashlightY); + _engine->GetMousePosition(&g_FlashlightX, &g_FlashlightY); } else if (g_FollowCharacter != nullptr) { g_FlashlightX = g_FollowCharacter->x + g_FollowCharacterDx; g_FlashlightY = g_FollowCharacter->y + g_FollowCharacterDy; @@ -429,25 +533,25 @@ void Update() { if (g_DarknessLightLevel != 100) DrawDarkness(); - engine->MarkRegionDirty(0, 0, screen_width, screen_height); + _engine->MarkRegionDirty(0, 0, screen_width, screen_height); } -static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = engine->FRead(ptr, size * count, fileHandle); +size_t AGSFlashlight::engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = _engine->FRead(ptr, size * count, fileHandle); return totalBytes / size; } -static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = engine->FWrite(const_cast(ptr), size * count, fileHandle); +size_t AGSFlashlight::engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = _engine->FWrite(const_cast(ptr), size * count, fileHandle); return totalBytes / size; } -void RestoreGame(long file) { +void AGSFlashlight::RestoreGame(long file) { unsigned int SaveVersion = 0; engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, file); if (SaveVersion != SaveMagic) { - engine->AbortGame("agsflashlight: bad save."); + _engine->AbortGame("agsflashlight: bad save."); } // Current version @@ -473,13 +577,12 @@ void RestoreGame(long file) { engineFileRead(&g_FollowCharacterVert, 4, 1, file); if (g_FollowCharacterId != 0) - g_FollowCharacter = engine->GetCharacter(g_FollowCharacterId); + g_FollowCharacter = _engine->GetCharacter(g_FollowCharacterId); g_BitmapMustBeUpdated = true; } - -void SaveGame(long file) { +void AGSFlashlight::SaveGame(long file) { engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); engineFileWrite(&g_RedTint, 4, 1, file); @@ -509,10 +612,7 @@ void SaveGame(long file) { // ************ AGS Interface *************** // ******************************************** - - -// tint screen -void SetFlashlightTint(int RedTint, int GreenTint, int BlueTint) { +void AGSFlashlight::SetFlashlightTint(int RedTint, int GreenTint, int BlueTint) { ClipToRange(RedTint, -31, 31); ClipToRange(GreenTint, -31, 31); ClipToRange(BlueTint, -31, 31); @@ -525,27 +625,27 @@ void SetFlashlightTint(int RedTint, int GreenTint, int BlueTint) { g_BlueTint = BlueTint; } -int GetFlashlightTintRed() { +int AGSFlashlight::GetFlashlightTintRed() { return g_RedTint; } -int GetFlashlightTintGreen() { +int AGSFlashlight::GetFlashlightTintGreen() { return g_GreenTint; } -int GetFlashlightTintBlue() { +int AGSFlashlight::GetFlashlightTintBlue() { return g_BlueTint; } -int GetFlashlightMinLightLevel() { +int AGSFlashlight::GetFlashlightMinLightLevel() { return 0; } -int GetFlashlightMaxLightLevel() { +int AGSFlashlight::GetFlashlightMaxLightLevel() { return 100; } -void SetFlashlightDarkness(int LightLevel) { +void AGSFlashlight::SetFlashlightDarkness(int LightLevel) { ClipToRange(LightLevel, 0, 100); if (LightLevel != g_DarknessLightLevel) { @@ -557,11 +657,11 @@ void SetFlashlightDarkness(int LightLevel) { } } -int GetFlashlightDarkness() { +int AGSFlashlight::GetFlashlightDarkness() { return g_DarknessLightLevel; } -void SetFlashlightDarknessSize(int Size) { +void AGSFlashlight::SetFlashlightDarknessSize(int Size) { if (Size != g_DarknessSize) { g_BitmapMustBeUpdated = true; g_DarknessSize = Size; @@ -569,12 +669,12 @@ void SetFlashlightDarknessSize(int Size) { } } -int GetFlashlightDarknessSize() { +int AGSFlashlight::GetFlashlightDarknessSize() { return g_DarknessSize; } -void SetFlashlightBrightness(int LightLevel) { +void AGSFlashlight::SetFlashlightBrightness(int LightLevel) { ClipToRange(LightLevel, 0, 100); if (LightLevel != g_BrightnessLightLevel) { @@ -586,244 +686,80 @@ void SetFlashlightBrightness(int LightLevel) { } } -int GetFlashlightBrightness() { +int AGSFlashlight::GetFlashlightBrightness() { return g_BrightnessLightLevel; } -void SetFlashlightBrightnessSize(int Size) { +void AGSFlashlight::SetFlashlightBrightnessSize(int Size) { if (Size != g_BrightnessSize) { g_BitmapMustBeUpdated = true; g_BrightnessSize = Size; } } -int GetFlashlightBrightnessSize() { +int AGSFlashlight::GetFlashlightBrightnessSize() { return g_BrightnessSize; } -void SetFlashlightPosition(int X, int Y) { +void AGSFlashlight::SetFlashlightPosition(int X, int Y) { g_FlashlightX = X; g_FlashlightY = Y; } -int GetFlashlightPositionX() { +int AGSFlashlight::GetFlashlightPositionX() { return g_FlashlightX; } -int GetFlashlightPositionY() { +int AGSFlashlight::GetFlashlightPositionY() { return g_FlashlightY; } -void SetFlashlightFollowMouse(int OnOff) { +void AGSFlashlight::SetFlashlightFollowMouse(int OnOff) { g_FlashlightFollowMouse = (OnOff != 0); } -int GetFlashlightFollowMouse() { +int AGSFlashlight::GetFlashlightFollowMouse() { return g_FlashlightFollowMouse ? 1 : 0; } -void SetFlashlightFollowCharacter(int CharacterId, int dx, int dy, int horz, int vert) { +void AGSFlashlight::SetFlashlightFollowCharacter(int CharacterId, int dx, int dy, int horz, int vert) { g_FollowCharacterId = CharacterId; g_FollowCharacterDx = dx; g_FollowCharacterDy = dy; g_FollowCharacterHorz = horz; g_FollowCharacterVert = vert; - g_FollowCharacter = engine->GetCharacter(CharacterId); + g_FollowCharacter = _engine->GetCharacter(CharacterId); } -int GetFlashlightFollowCharacter() { +int AGSFlashlight::GetFlashlightFollowCharacter() { return g_FollowCharacterId; } -int GetFlashlightCharacterDX() { +int AGSFlashlight::GetFlashlightCharacterDX() { return g_FollowCharacterDx; } -int GetFlashlightCharacterDY() { +int AGSFlashlight::GetFlashlightCharacterDY() { return g_FollowCharacterDy; } -int GetFlashlightCharacterHorz() { +int AGSFlashlight::GetFlashlightCharacterHorz() { return g_FollowCharacterHorz; } -int GetFlashlightCharacterVert() { +int AGSFlashlight::GetFlashlightCharacterVert() { return g_FollowCharacterVert; } -void SetFlashlightMask(int SpriteSlot) { +void AGSFlashlight::SetFlashlightMask(int SpriteSlot) { // Not implemented. } -int GetFlashlightMask() { +int AGSFlashlight::GetFlashlightMask() { return 0; } -void AGS_EngineStartup(IAGSEngine *lpEngine) { - engine = lpEngine; - - if (engine->version < 13) - engine->AbortGame("Engine interface is too old, need newer version of AGS."); - - engine->RegisterScriptFunction("SetFlashlightTint", (void *)&SetFlashlightTint); - engine->RegisterScriptFunction("GetFlashlightTintRed", (void *)&GetFlashlightTintRed); - engine->RegisterScriptFunction("GetFlashlightTintGreen", (void *)&GetFlashlightTintGreen); - engine->RegisterScriptFunction("GetFlashlightTintBlue", (void *)&GetFlashlightTintBlue); - - engine->RegisterScriptFunction("GetFlashlightMinLightLevel", (void *)&GetFlashlightMinLightLevel); - engine->RegisterScriptFunction("GetFlashlightMaxLightLevel", (void *)&GetFlashlightMaxLightLevel); - - engine->RegisterScriptFunction("SetFlashlightDarkness", (void *)&SetFlashlightDarkness); - engine->RegisterScriptFunction("GetFlashlightDarkness", (void *)&GetFlashlightDarkness); - engine->RegisterScriptFunction("SetFlashlightDarknessSize", (void *)&SetFlashlightDarknessSize); - engine->RegisterScriptFunction("GetFlashlightDarknessSize", (void *)&GetFlashlightDarknessSize); - - engine->RegisterScriptFunction("SetFlashlightBrightness", (void *)&SetFlashlightBrightness); - engine->RegisterScriptFunction("GetFlashlightBrightness", (void *)&GetFlashlightBrightness); - engine->RegisterScriptFunction("SetFlashlightBrightnessSize", (void *)&SetFlashlightBrightnessSize); - engine->RegisterScriptFunction("GetFlashlightBrightnessSize", (void *)&GetFlashlightBrightnessSize); - - engine->RegisterScriptFunction("SetFlashlightPosition", (void *)&SetFlashlightPosition); - engine->RegisterScriptFunction("GetFlashlightPositionX", (void *)&GetFlashlightPositionX); - engine->RegisterScriptFunction("GetFlashlightPositionY", (void *)&GetFlashlightPositionY); - - - engine->RegisterScriptFunction("SetFlashlightFollowMouse", (void *)&SetFlashlightFollowMouse); - engine->RegisterScriptFunction("GetFlashlightFollowMouse", (void *)&GetFlashlightFollowMouse); - - engine->RegisterScriptFunction("SetFlashlightFollowCharacter", (void *)&SetFlashlightFollowCharacter); - engine->RegisterScriptFunction("GetFlashlightFollowCharacter", (void *)&GetFlashlightFollowCharacter); - engine->RegisterScriptFunction("GetFlashlightCharacterDX", (void *)&GetFlashlightCharacterDX); - engine->RegisterScriptFunction("GetFlashlightCharacterDY", (void *)&GetFlashlightCharacterDY); - engine->RegisterScriptFunction("GetFlashlightCharacterHorz", (void *)&GetFlashlightCharacterHorz); - engine->RegisterScriptFunction("GetFlashlightCharacterVert", (void *)&GetFlashlightCharacterVert); - - engine->RegisterScriptFunction("SetFlashlightMask", (void *)&SetFlashlightMask); - engine->RegisterScriptFunction("GetFlashlightMask", (void *)&GetFlashlightMask); - - engine->RequestEventHook(AGSE_PREGUIDRAW); - engine->RequestEventHook(AGSE_PRESCREENDRAW); - engine->RequestEventHook(AGSE_SAVEGAME); - engine->RequestEventHook(AGSE_RESTOREGAME); -} - -void AGS_EngineShutdown() { - -} - -int AGS_EngineOnEvent(int event, int data) { - if (event == AGSE_PREGUIDRAW) { - Update(); - } else if (event == AGSE_RESTOREGAME) { - RestoreGame(data); - } else if (event == AGSE_SAVEGAME) { - SaveGame(data); - } else if (event == AGSE_PRESCREENDRAW) { - // Get screen size once here. - engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); - engine->UnrequestEventHook(AGSE_PRESCREENDRAW); - - // Only 16 bit color depth is supported. - if (screen_color_depth != 16) { - engine->UnrequestEventHook(AGSE_PREGUIDRAW); - engine->UnrequestEventHook(AGSE_PRESCREENDRAW); - engine->UnrequestEventHook(AGSE_SAVEGAME); - engine->UnrequestEventHook(AGSE_RESTOREGAME); - } - } - - return 0; -} - -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { - return 0; -} - -void AGS_EngineInitGfx(const char *driverID, void *data) { -} - - - -#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) - -// ******************************************** -// *********** Editor Interface ************* -// ******************************************** - -const char *scriptHeader = - "import void SetFlashlightTint(int RedTint, int GreenTint, int BlueTint);\r\n" - "import int GetFlashlightTintRed();\r\n" - "import int GetFlashlightTintGreen();\r\n" - "import int GetFlashlightTintBlue();\r\n" - "import int GetFlashlightMinLightLevel();\r\n" - "import int GetFlashlightMaxLightLevel();\r\n" - "import void SetFlashlightDarkness(int LightLevel);\r\n" - "import int GetFlashlightDarkness();\r\n" - "import void SetFlashlightDarknessSize(int Size);\r\n" - "import int GetFlashlightDarknessSize();\r\n" - "import void SetFlashlightBrightness(int LightLevel);\r\n" - "import int GetFlashlightBrightness();\r\n" - "import void SetFlashlightBrightnessSize(int Size);\r\n" - "import int GetFlashlightBrightnessSize();\r\n" - "import void SetFlashlightPosition(int X, int Y);\r\n" - "import int GetFlashlightPositionX();\r\n" - "import int GetFlashlightPositionY();\r\n" - "import void SetFlashlightFollowMouse(int OnOff);\r\n" - "import int GetFlashlightFollowMouse ();\r\n" - "import void SetFlashlightFollowCharacter(int CharacterId, int dx, int dy, int horz, int vert);\r\n" - "import int GetFlashlightFollowCharacter();\r\n" - "import int GetFlashlightCharacterDX();\r\n" - "import int GetFlashlightCharacterDY();\r\n" - "import int GetFlashlightCharacterHorz();\r\n" - "import int GetFlashlightCharacterVert();\r\n"; - - -IAGSEditor *editor; - - -LPCSTR AGS_GetPluginName(void) { - // Return the plugin description - return "Flashlight plugin recreation"; -} - -int AGS_EditorStartup(IAGSEditor *lpEditor) { - // User has checked the plugin to use it in their game - - // If it's an earlier version than what we need, abort. - if (lpEditor->version < 1) - return -1; - - editor = lpEditor; - editor->RegisterScriptHeader(scriptHeader); - - // Return 0 to indicate success - return 0; -} - -void AGS_EditorShutdown() { - // User has un-checked the plugin from their game - editor->UnregisterScriptHeader(scriptHeader); -} - -void AGS_EditorProperties(HWND parent) { - // User has chosen to view the Properties of the plugin - // We could load up an options dialog or something here instead - MessageBoxA(parent, "Flashlight plugin recreation by JJS", "About", MB_OK | MB_ICONINFORMATION); -} - -int AGS_EditorSaveGame(char *buffer, int bufsize) { - // We don't want to save any persistent data - return 0; -} - -void AGS_EditorLoadGame(char *buffer, int bufsize) { - // Nothing to load for this plugin -} - -#endif - - -#if defined(BUILTIN_PLUGINS) -} // namespace agsflashlight -#endif +} // namespace AGSFlashlight +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.h b/engines/ags/plugins/ags_flashlight/ags_flashlight.h index cd01110630a1..d225d7e50109 100644 --- a/engines/ags/plugins/ags_flashlight/ags_flashlight.h +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.h @@ -1,14 +1,132 @@ -#ifndef AGS_FLASHLIGHT_H -#define AGS_FLASHLIGHT_H +/* 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 "plugin/agsplugin.h" +#ifndef AGS_PLUGINS_AGSFLASHLIGHT_AGSFLASHLIGHT_H +#define AGS_PLUGINS_AGSFLASHLIGHT_AGSFLASHLIGHT_H -namespace agsflashlight { -void AGS_EngineStartup(IAGSEngine *lpEngine); -void AGS_EngineShutdown(); -int AGS_EngineOnEvent(int event, int data); -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); -void AGS_EngineInitGfx(const char *driverID, void *data); -} +#include "ags/plugins/dll.h" +#include "ags/lib/allegro.h" +#include "common/array.h" +#include "common/rect.h" +#include "common/str.h" -#endif \ No newline at end of file +namespace AGS3 { +namespace Plugins { +namespace AGSFlashlight { + +/** + * This is not the AGS Flashlight plugin, + * but a workalike plugin originally created for the AGS engine PSP port. + */ +class AGSFlashlight : public DLL { +private: + static IAGSEngine *_engine; + static int screen_width; + static int screen_height; + static int screen_color_depth; + static bool g_BitmapMustBeUpdated; + static int g_RedTint; + static int g_GreenTint; + static int g_BlueTint; + static int g_DarknessLightLevel; + static int g_BrightnessLightLevel; + static int g_DarknessSize; + static int g_DarknessDiameter; + static int g_BrightnessSize; + static int g_FlashlightX; + static int g_FlashlightY; + static int g_FlashlightDrawAtX; + static int g_FlashlightDrawAtY; + static bool g_FlashlightFollowMouse; + static int g_FollowCharacterId; + static int g_FollowCharacterDx; + static int g_FollowCharacterDy; + static int g_FollowCharacterHorz; + static int g_FollowCharacterVert; + static AGSCharacter *g_FollowCharacter; + static BITMAP *g_LightBitmap; + static unsigned long flashlight_x, flashlight_n; + +private: + static const char *AGS_GetPluginName(); + static void AGS_EngineStartup(IAGSEngine *engine); + static void AGS_EngineShutdown(); + static int AGS_EngineOnEvent(int event, int data); + static int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); + static void AGS_EngineInitGfx(const char *driverID, void *data); + +private: + /** + * This function is from Allegro, split for more performance. + * Combines a 32 bit RGBA sprite with a 16 bit RGB destination, optimised + * for when one pixel is in an RGB layout and the other is BGR. + */ + static inline unsigned long _blender_alpha16_bgr(unsigned long y); + static inline void calc_x_n(unsigned long x); + static inline void setPixel(int x, int y, int color, unsigned int *pixel); + static void plotCircle(int xm, int ym, int r, unsigned int color); + static void ClipToRange(int &variable, int min, int max); + static void AlphaBlendBitmap(); + static void DrawTint(); + static void DrawDarkness(); + static void CreateLightBitmap(); + static void Update(); + static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle); + static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle); + static void RestoreGame(long file); + static void SaveGame(long file); + static void SetFlashlightTint(int RedTint, int GreenTint, int BlueTint); + static int GetFlashlightTintRed(); + static int GetFlashlightTintGreen(); + static int GetFlashlightTintBlue(); + static int GetFlashlightMinLightLevel(); + static int GetFlashlightMaxLightLevel(); + static void SetFlashlightDarkness(int LightLevel); + static int GetFlashlightDarkness(); + static void SetFlashlightDarknessSize(int Size); + static int GetFlashlightDarknessSize(); + static void SetFlashlightBrightness(int LightLevel); + static int GetFlashlightBrightness(); + static void SetFlashlightBrightnessSize(int Size); + static int GetFlashlightBrightnessSize(); + static void SetFlashlightPosition(int X, int Y); + static int GetFlashlightPositionX(); + static int GetFlashlightPositionY(); + static void SetFlashlightFollowMouse(int OnOff); + static int GetFlashlightFollowMouse(); + static void SetFlashlightFollowCharacter(int CharacterId, int dx, int dy, int horz, int vert); + static int GetFlashlightFollowCharacter(); + static int GetFlashlightCharacterDX(); + static int GetFlashlightCharacterDY(); + static int GetFlashlightCharacterHorz(); + static int GetFlashlightCharacterVert(); + static void SetFlashlightMask(int SpriteSlot); + static int GetFlashlightMask(); +public: + AGSFlashlight(); +}; + +} // namespace AGSFlashlight +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index 1662de7958f0..c1fd382345af 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -23,6 +23,7 @@ #include "ags/lib/allegro.h" #include "ags/plugins/dll.h" #include "ags/plugins/ags_creditz/ags_creditz.h" +#include "ags/plugins/ags_flashlight/ags_flashlight.h" #include "ags/ags.h" #include "ags/detection.h" #include "common/str.h" @@ -49,6 +50,8 @@ void *dlopen(const char *filename) { else return new AGSCreditz::AGSCreditz11(); } + if (fname.equalsIgnoreCase("libAGSFlashlight.so")) + return new AGSFlashlight::AGSFlashlight(); return nullptr; } From fdb07840da7fe9572a7c7472c39df63f27a0a89a Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sun, 24 Jan 2021 01:21:39 +0000 Subject: [PATCH 169/215] AGS: Fix volume range in SOUNDCLIP::get_volume The original has an inline function that returns the volume as a percentage. In ScummVM this was made pure virtual and derived classes returned the volume from the mixer between 0 and 255. The different range caused various asserts. This commit restore the code to how it is in the original AGS. If we find issues with synchronization that require using the volume from the mixer, we can't change the code back to using a virtual function but we will need to scale the mixer volume to be in the [0, 100] range. --- engines/ags/engine/media/audio/audio.cpp | 4 ++-- .../ags/engine/media/audio/clip_mymidi.cpp | 4 ---- engines/ags/engine/media/audio/clip_mymidi.h | 1 - engines/ags/engine/media/audio/soundclip.cpp | 8 ++----- engines/ags/engine/media/audio/soundclip.h | 23 ++++++++----------- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp index 342fc3aac739..90b4a96829a0 100644 --- a/engines/ags/engine/media/audio/audio.cpp +++ b/engines/ags/engine/media/audio/audio.cpp @@ -277,7 +277,7 @@ static void audio_update_polled_stuff() { if (play.crossfading_out_channel > 0) { SOUNDCLIP *ch = lock.GetChannel(play.crossfading_out_channel); - int newVolume = ch ? ch->get_volume_percent() - play.crossfade_out_volume_per_step : 0; + int newVolume = ch ? ch->get_volume() - play.crossfade_out_volume_per_step : 0; if (newVolume > 0) { AudioChannel_SetVolume(&scrAudioChannel[play.crossfading_out_channel], newVolume); } else { @@ -291,7 +291,7 @@ static void audio_update_polled_stuff() { if (play.crossfading_in_channel > 0) { SOUNDCLIP *ch = lock.GetChannel(play.crossfading_in_channel); - int newVolume = ch ? ch->get_volume_percent() + play.crossfade_in_volume_per_step : 0; + int newVolume = ch ? ch->get_volume() + play.crossfade_in_volume_per_step : 0; if (newVolume > play.crossfade_final_volume_in) { newVolume = play.crossfade_final_volume_in; } diff --git a/engines/ags/engine/media/audio/clip_mymidi.cpp b/engines/ags/engine/media/audio/clip_mymidi.cpp index fc05ad53d6ef..84b7b8029864 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.cpp +++ b/engines/ags/engine/media/audio/clip_mymidi.cpp @@ -84,10 +84,6 @@ bool MYMIDI::is_playing() const { return ::AGS::g_music->isPlaying(); } -int MYMIDI::get_volume() const { - return _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType); -} - void MYMIDI::set_volume(int volume) { _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume); } diff --git a/engines/ags/engine/media/audio/clip_mymidi.h b/engines/ags/engine/media/audio/clip_mymidi.h index 0fa224390e9f..3e1d22e786b7 100644 --- a/engines/ags/engine/media/audio/clip_mymidi.h +++ b/engines/ags/engine/media/audio/clip_mymidi.h @@ -56,7 +56,6 @@ struct MYMIDI : public SOUNDCLIP { int play() override; void stop() override; bool is_playing() const override; - int get_volume() const override; void set_volume(int volume) override; void set_panning(int newPanning) override; }; diff --git a/engines/ags/engine/media/audio/soundclip.cpp b/engines/ags/engine/media/audio/soundclip.cpp index 2c88f0b9aa0d..f48ae074af16 100644 --- a/engines/ags/engine/media/audio/soundclip.cpp +++ b/engines/ags/engine/media/audio/soundclip.cpp @@ -27,8 +27,8 @@ namespace AGS3 { SOUNDCLIP::SOUNDCLIP() : _state(SoundClipInitial), _panning(128), _panningAsPercentage(0), _sourceClip(nullptr), _sourceClipType(0), _speed(1000), _priority(50), - _xSource(-1), _ySource(-1), _maximumPossibleDistanceAway(0), - _volAsPercentage(100), _vol(0), _volModifier(0), _repeat(false) { + _xSource(-1), _ySource(-1), _maximumPossibleDistanceAway(0), _muted(false), + _volAsPercentage(0), _vol(0), _volModifier(0), _repeat(false) { _mixer = ::AGS::g_vm->_mixer; } @@ -127,10 +127,6 @@ int SoundClipWaveBase::get_length_ms() { return 0; } -int SoundClipWaveBase::get_volume() const { - return _mixer->getChannelVolume(_soundHandle); -} - void SoundClipWaveBase::set_volume(int volume) { _mixer->setChannelVolume(_soundHandle, volume); } diff --git a/engines/ags/engine/media/audio/soundclip.h b/engines/ags/engine/media/audio/soundclip.h index ccd071cd21cd..3580f72def5e 100644 --- a/engines/ags/engine/media/audio/soundclip.h +++ b/engines/ags/engine/media/audio/soundclip.h @@ -80,19 +80,24 @@ struct SOUNDCLIP { virtual int get_pos_ms() = 0; virtual int get_length_ms() = 0; // return total track length in ms (or 0) virtual int get_sound_type() const = 0; - virtual int get_volume() const = 0; virtual void set_volume(int volume) = 0; virtual void set_panning(int newPanning) = 0; inline int get_speed() const { return _speed; } virtual void set_speed(int new_speed); void poll(); + + // Gets clip's volume property, as percentage (0 - 100); + // note this may not be the real volume of playback (which could e.g. be muted) + inline int get_volume() const { + return _volAsPercentage; + } + // Sets the current volume property, as percentage (0 - 100). inline void set_volume_percent(int volume) { - set_volume((volume * 255) / 100); - } - inline int get_volume_percent() const { - return get_volume() * 100 / 255; + _volAsPercentage = volume; + if (!_muted) + set_volume((volume * 255) / 100); } void adjust_volume(); int play_from(int position); @@ -141,13 +146,6 @@ struct SOUNDCLIP { return state_ == SoundClipPlaying || state_ == SoundClipPaused; } - - // Gets clip's volume property, as percentage (0 - 100); - // note this may not be the real volume of playback (which could e.g. be muted) - inline int get_volume() const { - return volAsPercentage; - } - inline bool is_muted() const { return muted; } @@ -198,7 +196,6 @@ struct SoundClipWaveBase : public SOUNDCLIP { int get_pos() override; int get_pos_ms() override; int get_length_ms() override; - int get_volume() const override; void set_volume(int volume) override; void set_panning(int newPanning) override; }; From 370fc7d80807192b37a5c08c9848dd9ddcc4b6fd Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Sun, 24 Jan 2021 01:58:08 +0000 Subject: [PATCH 170/215] AGS: Fix game data parser for versions between 2.6 and 2.7.1 This is backported from the main AGS repo where this fixe was made a few days ago. --- engines/ags/shared/ac/gamesetupstruct.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/engines/ags/shared/ac/gamesetupstruct.cpp b/engines/ags/shared/ac/gamesetupstruct.cpp index 73cb35d8deba..91d6e53e834d 100644 --- a/engines/ags/shared/ac/gamesetupstruct.cpp +++ b/engines/ags/shared/ac/gamesetupstruct.cpp @@ -295,11 +295,15 @@ HGameFileError GameSetupStruct::read_customprops(Shared::Stream *in, GameDataVer for (int i = 0; i < numviews; ++i) viewNames[i] = String::FromStream(in); - for (int i = 0; i < numinvitems; ++i) - invScriptNames[i] = String::FromStream(in); + if (data_ver >= kGameVersion_270) { + for (int i = 0; i < numinvitems; ++i) + invScriptNames[i] = String::FromStream(in); - for (int i = 0; i < numdialog; ++i) - dialogScriptNames[i] = String::FromStream(in); + if (data_ver >= kGameVersion_272) { + for (int i = 0; i < numdialog; ++i) + dialogScriptNames[i] = String::FromStream(in); + } + } } return HGameFileError::None(); } From 0cf456e09caac9001190c40a2f5e2e702331ba58 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 14:05:08 -0800 Subject: [PATCH 171/215] AGS: Added AGSBlend plugin --- engines/ags/module.mk | 1 + engines/ags/plugins/ags_blend/ags_blend.cpp | 577 ++++-------------- engines/ags/plugins/ags_blend/ags_blend.h | 81 ++- .../plugins/ags_flashlight/ags_flashlight.cpp | 2 +- .../plugins/ags_flashlight/ags_flashlight.h | 3 - engines/ags/plugins/dll.cpp | 5 + 6 files changed, 206 insertions(+), 463 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 75c55be1144d..f9c053ed345b 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -301,6 +301,7 @@ MODULE_OBJS = \ engine/script/script_runtime.o \ engine/script/systemimports.o \ plugins/dll.o \ + plugins/ags_blend/ags_blend.o \ plugins/ags_creditz/ags_creditz.o \ plugins/ags_flashlight/ags_flashlight.o diff --git a/engines/ags/plugins/ags_blend/ags_blend.cpp b/engines/ags/plugins/ags_blend/ags_blend.cpp index eeb3584a5046..f32f79dec62f 100644 --- a/engines/ags/plugins/ags_blend/ags_blend.cpp +++ b/engines/ags/plugins/ags_blend/ags_blend.cpp @@ -1,42 +1,38 @@ -/*********************************************************** - * AGSBlend * - * * - * Author: Steven Poulton * - * * - * Date: 09/01/2011 * - * * - * Description: An AGS Plugin to allow true Alpha Blending * - * * - ***********************************************************/ +/* 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 "ags/plugins/ags_blend/ags_blend.h" +#include "ags/shared/core/platform.h" +#include "common/algorithm.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSBlend { #pragma region Defines_and_Includes -#include "core/platform.h" - #define MIN_EDITOR_VERSION 1 #define MIN_ENGINE_VERSION 3 -#if AGS_PLATFORM_OS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#include -#include -#include - -#if !defined(BUILTIN_PLUGINS) -#define THIS_IS_THE_PLUGIN -#endif - -#include "plugin/agsplugin.h" - -#if defined(BUILTIN_PLUGINS) -namespace agsblend { -#endif - -typedef unsigned char uint8; - #define DEFAULT_RGB_R_SHIFT_32 16 #define DEFAULT_RGB_G_SHIFT_32 8 #define DEFAULT_RGB_B_SHIFT_32 0 @@ -76,56 +72,60 @@ typedef unsigned char uint8; #define ChannelBlend_Alpha(B,L,O) ((uint8)(O * B + (1 - O) * L)) #define ChannelBlend_AlphaF(B,L,F,O) (ChannelBlend_Alpha(F(B,L),B,O)) +#define STRINGIFY(s) STRINGIFY_X(s) +#define STRINGIFY_X(s) #s #pragma endregion -#if AGS_PLATFORM_OS_WINDOWS -// The standard Windows DLL entry point +IAGSEngine *AGSBlend::_engine; -BOOL APIENTRY DllMain(HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved) { +AGSBlend::AGSBlend() : DLL() { + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); +} - switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; +const char *AGSBlend::AGS_GetPluginName() { + return "AGSBlend"; } -#endif -//define engine +void AGSBlend::AGS_EngineStartup(IAGSEngine *engine) { + _engine = engine; -IAGSEngine *engine; + // Make sure it's got the version with the features we need + if (_engine->version < MIN_ENGINE_VERSION) + _engine->AbortGame("Plugin needs engine version " STRINGIFY(MIN_ENGINE_VERSION) " or newer."); + + // Register functions + SCRIPT_METHOD(GetAlpha); + SCRIPT_METHOD(PutAlpha); + SCRIPT_METHOD(DrawAlpha); + SCRIPT_METHOD(Blur); + SCRIPT_METHOD(HighPass); + SCRIPT_METHOD(DrawAdd); + SCRIPT_METHOD(DrawSprite); +} +//------------------------------------------------------------------------------ #pragma region Color_Functions - -int getr32(int c) { +static int getr32(int c) { return ((c >> DEFAULT_RGB_R_SHIFT_32) & 0xFF); } - -int getg32(int c) { +static int getg32(int c) { return ((c >> DEFAULT_RGB_G_SHIFT_32) & 0xFF); } - -int getb32(int c) { +static int getb32(int c) { return ((c >> DEFAULT_RGB_B_SHIFT_32) & 0xFF); } - -int geta32(int c) { +static int geta32(int c) { return ((c >> DEFAULT_RGB_A_SHIFT_32) & 0xFF); } - -int makeacol32(int r, int g, int b, int a) { +static int makeacol32(int r, int g, int b, int a) { return ((r << DEFAULT_RGB_R_SHIFT_32) | (g << DEFAULT_RGB_G_SHIFT_32) | (b << DEFAULT_RGB_B_SHIFT_32) | @@ -137,60 +137,36 @@ int makeacol32(int r, int g, int b, int a) { #pragma region Pixel32_Definition struct Pixel32 { - public: - Pixel32(); - ~Pixel32() = default; - int GetColorAsInt(); - int Red; - int Green; - int Blue; - int Alpha; + int Red = 0; + int Green = 0; + int Blue = 0; + int Alpha = 0; + int GetColorAsInt() const { + return makeacol32(Red, Green, Blue, Alpha); + } }; -Pixel32::Pixel32() { - Red = 0; - Blue = 0; - Green = 0; - Alpha = 0; -} - -int Pixel32::GetColorAsInt() { - - return makeacol32(Red, Green, Blue, Alpha); - -} - #pragma endregion -/// -/// Gets the alpha value at coords x,y -/// -int GetAlpha(int sprite, int x, int y) { - +int AGSBlend::GetAlpha(int sprite, int x, int y) { + BITMAP *engineSprite = _engine->GetSpriteGraphic(sprite); - BITMAP *engineSprite = engine->GetSpriteGraphic(sprite); - - unsigned char **charbuffer = engine->GetRawBitmapSurface(engineSprite); + unsigned char **charbuffer = _engine->GetRawBitmapSurface(engineSprite); unsigned int **longbuffer = (unsigned int **)charbuffer; int alpha = geta32(longbuffer[y][x]); - engine->ReleaseBitmapSurface(engineSprite); + _engine->ReleaseBitmapSurface(engineSprite); return alpha; - } -/// -/// Sets the alpha value at coords x,y -/// -int PutAlpha(int sprite, int x, int y, int alpha) { +int AGSBlend::PutAlpha(int sprite, int x, int y, int alpha) { + BITMAP *engineSprite = _engine->GetSpriteGraphic(sprite); - BITMAP *engineSprite = engine->GetSpriteGraphic(sprite); - - unsigned char **charbuffer = engine->GetRawBitmapSurface(engineSprite); + unsigned char **charbuffer = _engine->GetRawBitmapSurface(engineSprite); unsigned int **longbuffer = (unsigned int **)charbuffer; @@ -199,31 +175,22 @@ int PutAlpha(int sprite, int x, int y, int alpha) { int b = getb32(longbuffer[y][x]); longbuffer[y][x] = makeacol32(r, g, b, alpha); - engine->ReleaseBitmapSurface(engineSprite); + _engine->ReleaseBitmapSurface(engineSprite); return alpha; - } - -/// -/// Translates index from a 2D array to a 1D array -/// -int xytolocale(int x, int y, int width) { - +int AGSBlend::xytolocale(int x, int y, int width) { return (y * width + x); - - } -int HighPass(int sprite, int threshold) { - - BITMAP *src = engine->GetSpriteGraphic(sprite); +int AGSBlend::HighPass(int sprite, int threshold) { + BITMAP *src = _engine->GetSpriteGraphic(sprite); int srcWidth, srcHeight; - engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + _engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); - unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned char **srccharbuffer = _engine->GetRawBitmapSurface(src); unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; for (int y = 0; y < srcHeight; y++) { @@ -248,15 +215,13 @@ int HighPass(int sprite, int threshold) { } - -int Blur(int sprite, int radius) { - - BITMAP *src = engine->GetSpriteGraphic(sprite); +int AGSBlend::Blur(int sprite, int radius) { + BITMAP *src = _engine->GetSpriteGraphic(sprite); int srcWidth, srcHeight; - engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + _engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); - unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned char **srccharbuffer = _engine->GetRawBitmapSurface(src); unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; int negrad = -1 * radius; @@ -265,31 +230,21 @@ int Blur(int sprite, int radius) { Pixel32 *Dest = new Pixel32[(srcWidth + (radius * 2)) * (srcHeight + (radius * 2))]; // this is the destination sprite. both have a border all the way round equal to the radius for the blurring. Pixel32 *Temp = new Pixel32[(srcWidth + (radius * 2)) * (srcHeight + (radius * 2))]; - int arraywidth = srcWidth + (radius * 2); //define the array width since its used many times in the algorithm - for (int y = 0; y < srcHeight; y++) { //copy the sprite to the Pixels class array - for (int x = 0; x < srcWidth; x++) { - int locale = xytolocale(x + radius, y + radius, arraywidth); Pixels[locale].Red = getr32(srclongbuffer[y][x]); Pixels[locale].Green = getg32(srclongbuffer[y][x]); Pixels[locale].Blue = getb32(srclongbuffer[y][x]); Pixels[locale].Alpha = geta32(srclongbuffer[y][x]); - - - } - } - int numofpixels = (radius * 2 + 1); for (int y = 0; y < srcHeight; y++) { - int totalr = 0; int totalg = 0; int totalb = 0; @@ -310,19 +265,16 @@ int Blur(int sprite, int radius) { Temp[locale].Blue = totalb / numofpixels; Temp[locale].Alpha = totala / numofpixels; - // Subsequent pixels just update window total for (int x = 1; x < srcWidth; x++) { // Subtract pixel leaving window - int locale = xytolocale(x - 1, y + radius, arraywidth); + locale = xytolocale(x - 1, y + radius, arraywidth); totala -= Pixels[locale].Alpha; totalr -= (Pixels[locale].Red * Pixels[locale].Alpha) / 255; totalg -= (Pixels[locale].Green * Pixels[locale].Alpha) / 255; totalb -= (Pixels[locale].Blue * Pixels[locale].Alpha) / 255; - // Add pixel entering window - locale = xytolocale(x + radius + radius, y + radius, arraywidth); totala += Pixels[locale].Alpha; totalr += (Pixels[locale].Red * Pixels[locale].Alpha) / 255; @@ -335,15 +287,10 @@ int Blur(int sprite, int radius) { Temp[locale].Green = totalg / numofpixels; Temp[locale].Blue = totalb / numofpixels; Temp[locale].Alpha = totala / numofpixels; - } } - - - for (int x = 0; x < srcWidth; x++) { - int totalr = 0; int totalg = 0; int totalb = 0; @@ -364,11 +311,10 @@ int Blur(int sprite, int radius) { Dest[locale].Blue = totalb / numofpixels; Dest[locale].Alpha = totala / numofpixels; - // Subsequent pixels just update window total for (int y = 1; y < srcHeight; y++) { // Subtract pixel leaving window - int locale = xytolocale(x + radius, y - 1, arraywidth); + locale = xytolocale(x + radius, y - 1, arraywidth); totala -= Temp[locale].Alpha; totalr -= (Temp[locale].Red * Temp[locale].Alpha) / 255; totalg -= (Temp[locale].Green * Temp[locale].Alpha) / 255; @@ -389,64 +335,51 @@ int Blur(int sprite, int radius) { Dest[locale].Green = totalg / numofpixels; Dest[locale].Blue = totalb / numofpixels; Dest[locale].Alpha = totala / numofpixels; - } } - - for (int y = 0; y < srcHeight; y++) { for (int x = 0; x < srcWidth; x++) { int locale = xytolocale(x + radius, y + radius, arraywidth); srclongbuffer[y][x] = Dest[locale].GetColorAsInt(); //write the destination array to the main buffer - } - } + delete [] Pixels; delete [] Dest; delete [] Temp; - engine->ReleaseBitmapSurface(src); + _engine->ReleaseBitmapSurface(src); delete srclongbuffer; delete srccharbuffer; - return 0; -} - -int Clamp(int val, int min, int max) { - - if (val < min) return min; - else if (val > max) return max; - else return val; + return 0; } -int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int trans) { - +int AGSBlend::DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int trans) { trans = 100 - trans; int srcWidth, srcHeight, destWidth, destHeight; - BITMAP *src = engine->GetSpriteGraphic(sprite); - BITMAP *dest = engine->GetSpriteGraphic(destination); + BITMAP *src = _engine->GetSpriteGraphic(sprite); + BITMAP *dest = _engine->GetSpriteGraphic(destination); - engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); - engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); + _engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + _engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); if (x > destWidth || y > destHeight || x + srcWidth < 0 || y + srcHeight < 0) return 1; // offscreen - unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned char **srccharbuffer = _engine->GetRawBitmapSurface(src); unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; - unsigned char **destcharbuffer = engine->GetRawBitmapSurface(dest); + unsigned char **destcharbuffer = _engine->GetRawBitmapSurface(dest); unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; - - if (srcWidth + x > destWidth) srcWidth = destWidth - x - 1; if (srcHeight + y > destHeight) srcHeight = destHeight - y - 1; int destx, desty; - int srcr, srcg, srcb, srca, destr, destg, destb, desta, finalr, finalg, finalb, finala; + int srcr, srcg, srcb, srca, destr, destg, destb, desta; + int finalr = 0, finalg = 0, finalb = 0, finala = 0; unsigned int col; int starty = 0; int startx = 0; @@ -457,9 +390,7 @@ int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int tran int ycount = 0; int xcount = 0; for (ycount = starty; ycount < srcHeight; ycount ++) { - for (xcount = startx; xcount < srcWidth; xcount ++) { - destx = xcount + x; desty = ycount + y; @@ -476,208 +407,153 @@ int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int tran destb = getb32(destlongbuffer[desty][destx]); desta = geta32(destlongbuffer[desty][destx]); - - - switch (DrawMode) { - case 0: - finalr = srcr; finalg = srcg; finalb = srcb; break; case 1: - finalr = ChannelBlend_Lighten(srcr, destr); finalg = ChannelBlend_Lighten(srcg, destg); finalb = ChannelBlend_Lighten(srcb, destb); break; case 2: - - finalr = ChannelBlend_Darken(srcr, destr); finalg = ChannelBlend_Darken(srcg, destg); finalb = ChannelBlend_Darken(srcb, destb); break; case 3: - - finalr = ChannelBlend_Multiply(srcr, destr); finalg = ChannelBlend_Multiply(srcg, destg); finalb = ChannelBlend_Multiply(srcb, destb); break; case 4: - - finalr = ChannelBlend_Add(srcr, destr); finalg = ChannelBlend_Add(srcg, destg); finalb = ChannelBlend_Add(srcb, destb); break; case 5: - - finalr = ChannelBlend_Subtract(srcr, destr); finalg = ChannelBlend_Subtract(srcg, destg); finalb = ChannelBlend_Subtract(srcb, destb); break; case 6: - - finalr = ChannelBlend_Difference(srcr, destr); finalg = ChannelBlend_Difference(srcg, destg); finalb = ChannelBlend_Difference(srcb, destb); break; case 7: - - finalr = ChannelBlend_Negation(srcr, destr); finalg = ChannelBlend_Negation(srcg, destg); finalb = ChannelBlend_Negation(srcb, destb); break; case 8: - - finalr = ChannelBlend_Screen(srcr, destr); finalg = ChannelBlend_Screen(srcg, destg); finalb = ChannelBlend_Screen(srcb, destb); break; - case 9: - - finalr = ChannelBlend_Exclusion(srcr, destr); finalg = ChannelBlend_Exclusion(srcg, destg); finalb = ChannelBlend_Exclusion(srcb, destb); break; - case 10: - - finalr = ChannelBlend_Overlay(srcr, destr); finalg = ChannelBlend_Overlay(srcg, destg); finalb = ChannelBlend_Overlay(srcb, destb); break; - case 11: - - finalr = ChannelBlend_SoftLight(srcr, destr); finalg = ChannelBlend_SoftLight(srcg, destg); finalb = ChannelBlend_SoftLight(srcb, destb); break; case 12: - - finalr = ChannelBlend_HardLight(srcr, destr); finalg = ChannelBlend_HardLight(srcg, destg); finalb = ChannelBlend_HardLight(srcb, destb); break; case 13: - - finalr = ChannelBlend_ColorDodge(srcr, destr); finalg = ChannelBlend_ColorDodge(srcg, destg); finalb = ChannelBlend_ColorDodge(srcb, destb); break; case 14: - - finalr = ChannelBlend_ColorBurn(srcr, destr); finalg = ChannelBlend_ColorBurn(srcg, destg); finalb = ChannelBlend_ColorBurn(srcb, destb); break; case 15: - - finalr = ChannelBlend_LinearDodge(srcr, destr); finalg = ChannelBlend_LinearDodge(srcg, destg); finalb = ChannelBlend_LinearDodge(srcb, destb); break; case 16: - - finalr = ChannelBlend_LinearBurn(srcr, destr); finalg = ChannelBlend_LinearBurn(srcg, destg); finalb = ChannelBlend_LinearBurn(srcb, destb); break; - - case 17: - - finalr = ChannelBlend_LinearLight(srcr, destr); finalg = ChannelBlend_LinearLight(srcg, destg); finalb = ChannelBlend_LinearLight(srcb, destb); break; - - case 18: - - finalr = ChannelBlend_VividLight(srcr, destr); finalg = ChannelBlend_VividLight(srcg, destg); finalb = ChannelBlend_VividLight(srcb, destb); break; case 19: - - finalr = ChannelBlend_PinLight(srcr, destr); finalg = ChannelBlend_PinLight(srcg, destg); finalb = ChannelBlend_PinLight(srcb, destb); break; case 20: - - finalr = ChannelBlend_HardMix(srcr, destr); finalg = ChannelBlend_HardMix(srcg, destg); finalb = ChannelBlend_HardMix(srcb, destb); break; case 21: - - finalr = ChannelBlend_Reflect(srcr, destr); finalg = ChannelBlend_Reflect(srcg, destg); finalb = ChannelBlend_Reflect(srcb, destb); break; case 22: - - finalr = ChannelBlend_Glow(srcr, destr); finalg = ChannelBlend_Glow(srcg, destg); finalb = ChannelBlend_Glow(srcb, destb); break; case 23: - - finalr = ChannelBlend_Phoenix(srcr, destr); finalg = ChannelBlend_Phoenix(srcg, destg); finalb = ChannelBlend_Phoenix(srcb, destb); break; + default: + break; } finala = 255 - (255 - srca) * (255 - desta) / 255; @@ -694,31 +570,28 @@ int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int tran } - engine->ReleaseBitmapSurface(src); - engine->ReleaseBitmapSurface(dest); - engine->NotifySpriteUpdated(destination); + _engine->ReleaseBitmapSurface(src); + _engine->ReleaseBitmapSurface(dest); + _engine->NotifySpriteUpdated(destination); return 0; } - -int DrawAdd(int destination, int sprite, int x, int y, float scale) { - - +int AGSBlend::DrawAdd(int destination, int sprite, int x, int y, float scale) { int srcWidth, srcHeight, destWidth, destHeight; - BITMAP *src = engine->GetSpriteGraphic(sprite); - BITMAP *dest = engine->GetSpriteGraphic(destination); + BITMAP *src = _engine->GetSpriteGraphic(sprite); + BITMAP *dest = _engine->GetSpriteGraphic(destination); - engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); - engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); + _engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + _engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); if (x > destWidth || y > destHeight) return 1; // offscreen - unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned char **srccharbuffer = _engine->GetRawBitmapSurface(src); unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; - unsigned char **destcharbuffer = engine->GetRawBitmapSurface(dest); + unsigned char **destcharbuffer = _engine->GetRawBitmapSurface(dest); unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; if (srcWidth + x > destWidth) srcWidth = destWidth - x - 1; @@ -736,20 +609,14 @@ int DrawAdd(int destination, int sprite, int x, int y, float scale) { if (x < 0) startx = -1 * x; if (y < 0) starty = -1 * y; - - for (ycount = starty; ycount < srcHeight; ycount ++) { - for (xcount = startx; xcount < srcWidth; xcount ++) { - destx = xcount + x; desty = ycount + y; srca = (geta32(srclongbuffer[ycount][xcount])); if (srca != 0) { - - srcr = getr32(srclongbuffer[ycount][xcount]) * srca / 255 * scale; srcg = getg32(srclongbuffer[ycount][xcount]) * srca / 255 * scale; srcb = getb32(srclongbuffer[ycount][xcount]) * srca / 255 * scale; @@ -767,47 +634,39 @@ int DrawAdd(int destination, int sprite, int x, int y, float scale) { } finala = 255 - (255 - srca) * (255 - desta) / 255; - finalr = Clamp(srcr + destr, 0, 255); - finalg = Clamp(srcg + destg, 0, 255); - finalb = Clamp(srcb + destb, 0, 255); + finalr = CLIP(srcr + destr, 0, 255); + finalg = CLIP(srcg + destg, 0, 255); + finalb = CLIP(srcb + destb, 0, 255); col = makeacol32(finalr, finalg, finalb, finala); destlongbuffer[desty][destx] = col; - } - } - } - engine->ReleaseBitmapSurface(src); - engine->ReleaseBitmapSurface(dest); - engine->NotifySpriteUpdated(destination); - return 0; - - + _engine->ReleaseBitmapSurface(src); + _engine->ReleaseBitmapSurface(dest); + _engine->NotifySpriteUpdated(destination); + return 0; } - - -int DrawAlpha(int destination, int sprite, int x, int y, int trans) { - +int AGSBlend::DrawAlpha(int destination, int sprite, int x, int y, int trans) { trans = 100 - trans; int srcWidth, srcHeight, destWidth, destHeight; - BITMAP *src = engine->GetSpriteGraphic(sprite); - BITMAP *dest = engine->GetSpriteGraphic(destination); + BITMAP *src = _engine->GetSpriteGraphic(sprite); + BITMAP *dest = _engine->GetSpriteGraphic(destination); - engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); - engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); + _engine->GetBitmapDimensions(src, &srcWidth, &srcHeight, nullptr); + _engine->GetBitmapDimensions(dest, &destWidth, &destHeight, nullptr); if (x > destWidth || y > destHeight) return 1; // offscreen - unsigned char **srccharbuffer = engine->GetRawBitmapSurface(src); + unsigned char **srccharbuffer = _engine->GetRawBitmapSurface(src); unsigned int **srclongbuffer = (unsigned int **)srccharbuffer; - unsigned char **destcharbuffer = engine->GetRawBitmapSurface(dest); + unsigned char **destcharbuffer = _engine->GetRawBitmapSurface(dest); unsigned int **destlongbuffer = (unsigned int **)destcharbuffer; if (srcWidth + x > destWidth) srcWidth = destWidth - x - 1; @@ -825,18 +684,14 @@ int DrawAlpha(int destination, int sprite, int x, int y, int trans) { if (x < 0) startx = -1 * x; if (y < 0) starty = -1 * y; - for (ycount = starty; ycount < srcHeight; ycount ++) { - for (xcount = startx; xcount < srcWidth; xcount ++) { - destx = xcount + x; desty = ycount + y; srca = (geta32(srclongbuffer[ycount][xcount])) * trans / 100; if (srca != 0) { - srcr = getr32(srclongbuffer[ycount][xcount]); srcg = getg32(srclongbuffer[ycount][xcount]); srcb = getb32(srclongbuffer[ycount][xcount]); @@ -852,191 +707,17 @@ int DrawAlpha(int destination, int sprite, int x, int y, int trans) { finalb = srca * srcb / finala + desta * destb * (255 - srca) / finala / 255; destlongbuffer[desty][destx] = makeacol32(finalr, finalg, finalb, finala); - } - } - - } - - engine->ReleaseBitmapSurface(src); - engine->ReleaseBitmapSurface(dest); - engine->NotifySpriteUpdated(destination); - - return 0; -} - - -#if AGS_PLATFORM_OS_WINDOWS - -//============================================================================== - -// ***** Design time ***** - -IAGSEditor *editor; // Editor interface - -const char *ourScriptHeader = - "import int DrawAlpha(int destination, int sprite, int x, int y, int transparency);\r\n" - "import int GetAlpha(int sprite, int x, int y);\r\n" - "import int PutAlpha(int sprite, int x, int y, int alpha);\r\n" - "import int Blur(int sprite, int radius);\r\n" - "import int HighPass(int sprite, int threshold);\r\n" - "import int DrawAdd(int destination, int sprite, int x, int y, float scale);\r\n" - "import int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int trans);"; - - - - -//------------------------------------------------------------------------------ - -LPCSTR AGS_GetPluginName() { - return ("AGSBlend"); -} - -//------------------------------------------------------------------------------ - -int AGS_EditorStartup(IAGSEditor *lpEditor) { - // User has checked the plugin to use it in their game - - // If it's an earlier version than what we need, abort. - if (lpEditor->version < MIN_EDITOR_VERSION) - return (-1); - - editor = lpEditor; - editor->RegisterScriptHeader(ourScriptHeader); - - // Return 0 to indicate success - return (0); -} - -//------------------------------------------------------------------------------ - -void AGS_EditorShutdown() { - // User has un-checked the plugin from their game - editor->UnregisterScriptHeader(ourScriptHeader); -} - -//------------------------------------------------------------------------------ - -void AGS_EditorProperties(HWND parent) { //*** optional *** - // User has chosen to view the Properties of the plugin - // We could load up an options dialog or something here instead - /* MessageBox(parent, - L"AGSBlend v1.0 By Calin Leafshade", - L"About", - MB_OK | MB_ICONINFORMATION); - */ -} - -//------------------------------------------------------------------------------ - -int AGS_EditorSaveGame(char *buffer, int bufsize) { //*** optional *** - // Called by the editor when the current game is saved to disk. - // Plugin configuration can be stored in [buffer] (max [bufsize] bytes) - // Return the amount of bytes written in the buffer - return (0); -} - -//------------------------------------------------------------------------------ - -void AGS_EditorLoadGame(char *buffer, int bufsize) { //*** optional *** - // Called by the editor when a game is loaded from disk - // Previous written data can be read from [buffer] (size [bufsize]). - // Make a copy of the data, the buffer is freed after this function call. -} - -//============================================================================== - -#endif - -// ***** Run time ***** - -// Engine interface - -//------------------------------------------------------------------------------ - -#define REGISTER(x) engine->RegisterScriptFunction(#x, (void *) (x)); -#define STRINGIFY(s) STRINGIFY_X(s) -#define STRINGIFY_X(s) #s - -void AGS_EngineStartup(IAGSEngine *lpEngine) { - engine = lpEngine; - - // Make sure it's got the version with the features we need - if (engine->version < MIN_ENGINE_VERSION) - engine->AbortGame("Plugin needs engine version " STRINGIFY(MIN_ENGINE_VERSION) " or newer."); - - //register functions - - REGISTER(GetAlpha) - REGISTER(PutAlpha) - REGISTER(DrawAlpha) - REGISTER(Blur) - REGISTER(HighPass) - REGISTER(DrawAdd) - REGISTER(DrawSprite) - - -} - -//------------------------------------------------------------------------------ - -void AGS_EngineShutdown() { - // Called by the game engine just before it exits. - // This gives you a chance to free any memory and do any cleanup - // that you need to do before the engine shuts down. -} - -//------------------------------------------------------------------------------ - -int AGS_EngineOnEvent(int event, int data) { //*** optional *** - switch (event) { - /* - case AGSE_KEYPRESS: - case AGSE_MOUSECLICK: - case AGSE_POSTSCREENDRAW: - case AGSE_PRESCREENDRAW: - case AGSE_SAVEGAME: - case AGSE_RESTOREGAME: - case AGSE_PREGUIDRAW: - case AGSE_LEAVEROOM: - case AGSE_ENTERROOM: - case AGSE_TRANSITIONIN: - case AGSE_TRANSITIONOUT: - case AGSE_FINALSCREENDRAW: - case AGSE_TRANSLATETEXT: - case AGSE_SCRIPTDEBUG: - case AGSE_SPRITELOAD: - case AGSE_PRERENDER: - case AGSE_PRESAVEGAME: - case AGSE_POSTRESTOREGAME: - */ - default: - break; } - // Return 1 to stop event from processing further (when needed) - return (0); -} - -//------------------------------------------------------------------------------ + _engine->ReleaseBitmapSurface(src); + _engine->ReleaseBitmapSurface(dest); + _engine->NotifySpriteUpdated(destination); -int AGS_EngineDebugHook(const char *scriptName, - int lineNum, int reserved) { //*** optional *** - // Can be used to debug scripts, see documentation return 0; } -//------------------------------------------------------------------------------ - -void AGS_EngineInitGfx(const char *driverID, void *data) { //*** optional *** - // This allows you to make changes to how the graphics driver starts up. - // See documentation -} - -//.............................................................................. - - -#if defined(BUILTIN_PLUGINS) -} -#endif +} // namespace AGSBlend +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_blend/ags_blend.h b/engines/ags/plugins/ags_blend/ags_blend.h index c09349c9f11d..5e6d8c1669d1 100644 --- a/engines/ags/plugins/ags_blend/ags_blend.h +++ b/engines/ags/plugins/ags_blend/ags_blend.h @@ -1,14 +1,73 @@ -#ifndef AGS_BLEND_H -#define AGS_BLEND_H +/* 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 "plugin/agsplugin.h" +#ifndef AGS_PLUGINS_AGS_BLEND_AGS_BLEND_H +#define AGS_PLUGINS_AGS_BLEND_AGS_BLEND_H -namespace agsblend { -void AGS_EngineStartup(IAGSEngine *lpEngine); -void AGS_EngineShutdown(); -int AGS_EngineOnEvent(int event, int data); -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); -void AGS_EngineInitGfx(const char *driverID, void *data); -} +#include "ags/plugins/dll.h" -#endif \ No newline at end of file +namespace AGS3 { +namespace Plugins { +namespace AGSBlend { + +/** + * Author: Steven Poulton + * Description: An AGS Plugin to allow true Alpha Blending + */ +class AGSBlend : public DLL { +private: + static IAGSEngine *_engine; +private: + static const char *AGS_GetPluginName(); + static void AGS_EngineStartup(IAGSEngine *lpEngine); + +private: + /** + * Gets the alpha value at coords x,y + */ + static int GetAlpha(int sprite, int x, int y); + + /** + * Sets the alpha value at coords x,y + */ + static int PutAlpha(int sprite, int x, int y, int alpha); + + /** + * Translates index from a 2D array to a 1D array + */ + static int xytolocale(int x, int y, int width); + + static int HighPass(int sprite, int threshold); + static int Blur(int sprite, int radius); + static int DrawSprite(int destination, int sprite, int x, int y, int DrawMode, int trans); + static int DrawAdd(int destination, int sprite, int x, int y, float scale); + static int DrawAlpha(int destination, int sprite, int x, int y, int trans); + +public: + AGSBlend(); +}; + +} // namespace AGSBlend +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp index c36e7ec40100..0e2353a23fcc 100644 --- a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp @@ -73,7 +73,7 @@ unsigned long AGSFlashlight::flashlight_n; IAGSEngine *AGSFlashlight::_engine; -AGSFlashlight::AGSFlashlight() { +AGSFlashlight::AGSFlashlight() : DLL() { _engine = nullptr; screen_width = 320; screen_height = 200; diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.h b/engines/ags/plugins/ags_flashlight/ags_flashlight.h index d225d7e50109..2c24fde7c060 100644 --- a/engines/ags/plugins/ags_flashlight/ags_flashlight.h +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.h @@ -25,9 +25,6 @@ #include "ags/plugins/dll.h" #include "ags/lib/allegro.h" -#include "common/array.h" -#include "common/rect.h" -#include "common/str.h" namespace AGS3 { namespace Plugins { diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index c1fd382345af..f08ce59b96e0 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -22,6 +22,7 @@ #include "ags/lib/allegro.h" #include "ags/plugins/dll.h" +#include "ags/plugins/ags_blend/ags_blend.h" #include "ags/plugins/ags_creditz/ags_creditz.h" #include "ags/plugins/ags_flashlight/ags_flashlight.h" #include "ags/ags.h" @@ -44,12 +45,16 @@ void *dlopen(const char *filename) { } } + if (fname.equalsIgnoreCase("libAGSBlend.so")) + return new AGSBlend::AGSBlend(); + if (fname.equalsIgnoreCase("libagsCreditz.so")) { if (version == 20) return new AGSCreditz::AGSCreditz20(); else return new AGSCreditz::AGSCreditz11(); } + if (fname.equalsIgnoreCase("libAGSFlashlight.so")) return new AGSFlashlight::AGSFlashlight(); From 627e8b5f7e6d4993000688546376126a70ecac9c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 17:26:08 -0800 Subject: [PATCH 172/215] AGS: Added AGSPalRender plugin --- engines/ags/module.mk | 4 +- .../plugins/ags_flashlight/ags_flashlight.cpp | 11 +- .../plugins/ags_flashlight/ags_flashlight.h | 2 - .../plugins/ags_pal_render/ags_pal_render.cpp | 547 ++++------------- .../plugins/ags_pal_render/ags_pal_render.h | 55 +- .../ags/plugins/ags_pal_render/agsplugin.h | 564 ------------------ .../ags/plugins/ags_pal_render/pal_render.h | 120 ++-- .../ags/plugins/ags_pal_render/raycast.cpp | 127 ++-- engines/ags/plugins/ags_pal_render/raycast.h | 46 +- engines/ags/plugins/dll.cpp | 4 + 10 files changed, 323 insertions(+), 1157 deletions(-) delete mode 100644 engines/ags/plugins/ags_pal_render/agsplugin.h diff --git a/engines/ags/module.mk b/engines/ags/module.mk index f9c053ed345b..fbfc1d23952e 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -303,7 +303,9 @@ MODULE_OBJS = \ plugins/dll.o \ plugins/ags_blend/ags_blend.o \ plugins/ags_creditz/ags_creditz.o \ - plugins/ags_flashlight/ags_flashlight.o + plugins/ags_flashlight/ags_flashlight.o \ + plugins/ags_pal_render/ags_pal_render.o \ + plugins/ags_pal_render/raycast.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp index 0e2353a23fcc..116c4a044953 100644 --- a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp @@ -111,10 +111,9 @@ AGSFlashlight::AGSFlashlight() : DLL() { DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); DLL_METHOD(AGS_EngineShutdown); DLL_METHOD(AGS_EngineOnEvent); - DLL_METHOD(AGS_EngineDebugHook); - DLL_METHOD(AGS_EngineInitGfx); } const char *AGSFlashlight::AGS_GetPluginName() { @@ -196,14 +195,6 @@ int AGSFlashlight::AGS_EngineOnEvent(int event, int data) { return 0; } -int AGSFlashlight::AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { - return 0; -} - -void AGSFlashlight::AGS_EngineInitGfx(const char *driverID, void *data) { -} - - void AGSFlashlight::calc_x_n(unsigned long x) { flashlight_x = x; diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.h b/engines/ags/plugins/ags_flashlight/ags_flashlight.h index 2c24fde7c060..182b3dfb2c91 100644 --- a/engines/ags/plugins/ags_flashlight/ags_flashlight.h +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.h @@ -68,8 +68,6 @@ class AGSFlashlight : public DLL { static void AGS_EngineStartup(IAGSEngine *engine); static void AGS_EngineShutdown(); static int AGS_EngineOnEvent(int event, int data); - static int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); - static void AGS_EngineInitGfx(const char *driverID, void *data); private: /** diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp index 7275320213d7..b7467a09f5a4 100644 --- a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp +++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp @@ -1,36 +1,34 @@ -// -// ags_template.cpp : Example AGS plugin file -// See the online API reference for details of how this works. -// Copyright (c) 2002 Chris Jones -// - -#include "core/platform.h" - -#if AGS_PLATFORM_OS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if !defined(BUILTIN_PLUGINS) -#define THIS_IS_THE_PLUGIN -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#include "plugin/agsplugin.h" -#include "palrender.h" -#include "raycast.h" +/* 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 "ags/lib/allegro.h" +#include "ags/plugins/ags_pal_render/ags_pal_render.h" +#include "ags/plugins/ags_pal_render/pal_render.h" +#include "ags/plugins/ags_pal_render/raycast.h" +#include "ags/ags.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSPalRender { #define MAX_OVERLAYS 128 #define MAX_STARS 1024 @@ -40,31 +38,6 @@ #define HALF_PI (0.5f * PI) #define TWO_PI (2.0f * PI) #define TWO_PI_INV (1.0f / TWO_PI) -// DllMain - standard Windows DLL entry point. -// The AGS editor will cause this to get called when the editor first -// starts up, and when it shuts down at the end. - -#if AGS_PLATFORM_OS_WINDOWS -bool APIENTRY DllMain(HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved) { - - switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} -#endif - - - -#if defined(BUILTIN_PLUGINS) -namespace agspalrender { -#endif const float halfpi = (0.5f * PI); const float twopi = (2.0f * PI); @@ -72,6 +45,8 @@ const float twopi_inv = (1.0f / TWO_PI); const float pisquared = PI * PI; const float picubed = PI * PI * PI; +IAGSEngine *engine; + //unsigned char clut[256][256]; unsigned char clut[65536]; @@ -161,313 +136,6 @@ BITMAP *backgroundimage; PALSTRUCT objectivepal[256]; int bgimgspr; -// ***** DESIGN TIME CALLS ******* -#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) - -IAGSEditor *editor; -const char *ourScriptHeader = - "enum BlendingMode { \r\n" - "eBlendAlpha = 0, \r\n" - "eBlendAdditive = 1 \r\n" - "}; \r\n" - "enum ObjectiveMode { \r\n" - "eUseStandardPal = 0, \r\n" - "eUseObjectivePal = 1 \r\n" - "}; \r\n" - "enum PlasmaMixMode { \r\n" - "ePlasmaNone = 0, \r\n" - "ePlasmaHorzBars = 1, \r\n" - "ePlasmaVertBars = 2, \r\n" - "ePlasmaCircle = 3, \r\n" - "ePlasmaDiagBars = 4 \r\n" - "}; \r\n" - "enum PlasmaRootType { \r\n" - "ePlasmaSlowRoot = 1, \r\n" - "ePlasmaFastRoot = 0 \r\n" - "}; \r\n" - "enum TransOverlayLevel { \r\n" - "eTOBackground = 0, \r\n" - "eTOPreGUI = 1, \r\n" - "eTOPostGUI = 2 \r\n" - "}; \r\n" - "enum LensLevel { \r\n" - "eLensBackgroundPreTO = 0, \r\n" - "eLensBackgroundPostTO = 1, \r\n" - "eLensPreGUIPreTO = 2, \r\n" - "eLensPreGUIPostTO = 3, \r\n" - "eLensPostGUIPreTO = 4, \r\n" - "eLensPostGUIPostTO = 5 \r\n" - "}; \r\n" - - "struct Raycast { \r\n" - "import static void Render (int slot); \r\n" - "import static void UnloadEngine (); //$AUTOCOMPLETEIGNORE$ \r\n" - "import static void MoveForward (); \r\n" - "import static void MoveBackward (); \r\n" - "import static void RotateLeft (); \r\n" - "import static void RotateRight (); \r\n" - "import static void MakeTextures (int slot); \r\n" - "import static void Initialize (); \r\n" - "import static void LoadMap (int worldmapSlot,int lightmapSlot,int ceilingmapSlot,int floormapSlot); \r\n" - "import static void SetCameraPosition (float x,float y); \r\n" - "import static float GetCameraX (); \r\n" - "import static float GetCameraY (); \r\n" - "import static int GetCameraAngle (); \r\n" - "import static void SetCameraAngle (int angle); \r\n" - "import static void InitSprite (int id, float x, float y, int slot, char alpha=255, BlendingMode blendmode=0, float scale_x=0, float scale_y=0, float vMove=0);\r\n" - "import static int GetHotspotAtXY (int x,int y); \r\n" - "import static int GetObjectAtXY (int x,int y); \r\n" - - "import static void SetSpriteInteractObj (int id,int obj); \r\n" - "import static int GetSpriteInteractObj (int id); \r\n" - "import static void SetSpritePosition (int id, float x, float y); \r\n" - "import static void SetSpriteVertOffset (int id, float vMove); \r\n" - "import static float GetSpriteVertOffset (int id); \r\n" - "import static float GetSpriteX (int id); \r\n" - "import static float GetSpriteY (int id); \r\n" - "import static int GetSpriteAngle (int id); \r\n" - "import static void SetSpriteAngle (int id,int angle); \r\n" - "import static void SetSpriteView (int id,int view); \r\n" - "import static int GetSpriteView (int id); \r\n" - "import static void SetSpriteFrame (int id,int frame); \r\n" - "import static int GetSpriteFrame (int id); \r\n" - "import static float GetSpriteScaleX (int id); \r\n" - "import static void SetSpriteScaleX (int id,float scale); \r\n" - "import static float GetSpriteScaleY (int id); \r\n" - "import static void SetSpriteScaleY (int id,float scale); \r\n" - - - "import static void SetWallHotspot (int id,char hotsp); \r\n" - "import static void SetWallTextures (int id,int n,int s,int w,int e); \r\n" - "import static void SetWallSolid (int id,int n,int s,int w,int e); \r\n" - "import static void SetWallIgnoreLighting (int id,int n,int s,int w,int e); \r\n" - "import static void SetWallAlpha (int id,int n,int s,int w,int e); \r\n" - "import static void SetWallBlendType (int id,BlendingMode n,BlendingMode s,BlendingMode w,BlendingMode e);\r\n" - - "import static float GetMoveSpeed (); \r\n" - "import static void SetMoveSpeed (float speed); \r\n" - "import static float GetRotSpeed (); \r\n" - "import static void SetRotSpeed (float speed); \r\n" - "import static int GetWallAt (int x,int y); \r\n" - "import static int GetLightAt (int x,int y); \r\n" - "import static void SetLightAt (int x,int y, int light); \r\n" - "import static void SetWallAt (int x,int y,int id); \r\n" - "import static void SetPlaneY (float y); \r\n" - "import static float GetDistanceAt (int x,int y); \r\n" - "import static void SetSkyBox (int slot); \r\n" - "import static int GetSkyBox (int slot); \r\n" - "import static void SetAmbientLight (int value); \r\n" - "import static int GetAmbientLight (); \r\n" - "import static void SetFloorAt (int x,int y,int tex); \r\n" - "import static void SetCeilingAt (int x,int y,int tex); \r\n" - "import static int GetCeilingAt (int x,int y); \r\n" - "import static int GetFloorAt (int x,int y); \r\n" - "import static int GetLightingAt (int x,int y); \r\n" - "import static void SetLightingAt (int x,int y,char lighting); \r\n" - "import static int GetAmbientWeight (); \r\n" - "import static int GetTileX_At (int x,int y); \r\n" - "import static int GetTileY_At (int x,int y); \r\n" - "///Draws a loaded tile onto a sprite (make sure it's 64x64 pixels). \r\n" - "import static void DrawTile (int spr,int tile); \r\n" - "///Draws a sprite onto a tile (make sure it's 64x64 pixels). \r\n" - "import static void DrawOntoTile (int spr,int tile); \r\n" - "import static int GetWallHotspot (int id); \r\n" - "import static int GetWallTexture (int id,int dir); \r\n" - "import static int GetWallSolid (int id,int dir); \r\n" - "import static int GetWallIgnoreLighting (int id,int dir); \r\n" - "import static int GetWallAlpha (int id, int dir); \r\n" - "import static int GetWallBlendType (int id,int dir); \r\n" - "import static void SelectTile (int x,int y, char color); \r\n" - "import static void SetNoClip (int value); \r\n" - "import static int GetNoClip (); \r\n" - "import static int HasSeenTile (int x,int y); \r\n" - "import static int GetSpriteAlpha (int id); \r\n" - "import static void SetSpriteAlpha (int id,int alpha); \r\n" - "import static int GetSpritePic (int id); \r\n" - "import static void SetSpritePic (int id,int slot); \r\n" - "import static void SetSpriteBlendType (int id,BlendingMode type); \r\n" - "import static int GetSpriteBlendType (int id); \r\n" - "import static void SetAmbientColor (int color,int amount); \r\n" - "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" - "}; \r\n" - - "struct PALInternal { \r\n" - "///Loads the colour lookup table for translucency effects. Used by module. \r\n" - "import static int LoadCLUT (int slot);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Cycles the internal palette structure of the plugin. Internal use only. \r\n" - "import static void CycleRemap (int start, int end);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Resets the remap array. \r\n" - "import static void ResetRemapping (); // $AUTOCOMPLETESTATICONLY$ \r\n" - "///Gets the closest palette slot from 16 bit colour space. \r\n" - "import static char GetColor565 (char r,char g,char b);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Returns the true location of a remapped colour. \r\n" - "import static char GetRemappedSlot (char slot);//$AUTOCOMPLETESTATICONLY$ \r\n" - "///Gets the luminosity of the palette slot. \r\n" - "import static int GetLuminosityFromPalette (int slot);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Polynomial Sine Approximation. \r\n" - "import static float FastSin (float x);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Polynomial Cosine Approximation. \r\n" - "import static float FastCos (float x);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Ludicrously Fast Integer Root (0-0xFFFF) \r\n" - "import static int FastRoot(int x); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static int GetModifiedBackgroundImage (); //$AUTOCOMPLETEIGNORE$ \r\n" - "import static void WriteObjectivePalette (char index,char r,char b, char g); \r\n" - "import static int ReadObjectivePaletteR (char index); \r\n" - "import static int ReadObjectivePaletteB (char index); \r\n" - "import static int ReadObjectivePaletteG (char index); \r\n" - "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" - "}; \r\n" - - "struct Translucence { \r\n" - "///Creates a translucent overlay. level=0: Background,level=1: Below GUIs,level=2:Above GUIs. blendmode=0: Alpha, blendmode=1: Additive \r\n" - "import static int CreateOverlay (int id, int sprite, int alpha, int level, int ox, int oy,int mask=0,BlendingMode blendmode=0);// $AUTOCOMPLETESTATICONLY$\r\n" - "///Deletes translucent overlay. \r\n" - "import static int DeleteOverlay (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Moves Translucent Overlay to OX,OY. \r\n" - "import static int Move (int id, int ox, int oy);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Get X coordinate of translucent overlay. \r\n" - "import static int GetOverlayX (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Get Y coordinate of translucent overlay. \r\n" - "import static int GetOverlayY (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Get the sprite slot for translucent overlay id \r\n" - "import static int GetOverlaySprite (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Get the level the overlay is drawn on currently. \r\n" - "import static int GetOverlayLevel (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Get whether Translucent Overlay is currently being drawn. \r\n" - "import static int GetOverlayEnabled (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Get the alpha channel for translucent overlay id. (0-255) \r\n" - "import static int GetOverlayAlpha (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Set translucent overlay id's alpha. (0-255) \r\n" - "import static int SetOverlayAlpha (int id, int alpha);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Turn overlay on or off. \r\n" - "import static int SetOverlayEnabled (int id, int toggle);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Blend bg with fg (fg is changed) together at alpha translevel. \r\n" - "import static int DrawTransSprite (int sprite, int bg, int translevel,int mask=0,BlendingMode blendmode=0,ObjectiveMode use_objpal=0);// $AUTOCOMPLETESTATICONLY$ \r\n" - "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" - "}; \r\n" - - "struct Reflections { \r\n" - "///Turn reflective floors off or on. \r\n" - "import static int Set (int toggle);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Check if reflections are turned on. \r\n" - "import static int IsReflecting ();// $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void SetCharacterReflected (int id,int refl);// $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void SetObjectReflected (int id,int refl);// $AUTOCOMPLETESTATICONLY$ \r\n" - "import static int GetCharacterReflected (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "import static int GetObjectReflected (int id);// $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void ReplaceCharacterReflectionView (int id,int view);// $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void SetObjectReflectionIgnoreScaling (int id,int wb);// $AUTOCOMPLETESTATICONLY$ \r\n" - "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" - "}; \r\n" - - - "struct LensDistort { \r\n" - "import static void SetPos (int x,int y); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static int GetX (); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static int GetY (); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void Set (int toggle); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static int IsDrawn (); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void SetOffsetClamp (int clamp); //$AUTOCOMPLETEIGNORE$ \r\n" - "import static int GetOffsetClamp (); //$AUTOCOMPLETEIGNORE$ \r\n" - "import static int GetLevel (); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void SetLevel (int level); // $AUTOCOMPLETESTATICONLY$ \r\n" - "import static void Initialize (int width, int zoom, int lensx,int lensy,LensLevel level,int clamp=-1); // $AUTOCOMPLETESTATICONLY$ \r\n" - "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" - "}; \r\n" - - "struct Plasma { \r\n" - "///Set options for plasma generation. 0 = None. 1 = Horizontal Bars (data=width). 2 = Vertical Bars (data=width). 3 = Circle (data=x,data2=y,data3=width). 4 = Diagonal Bars (data=width) \r\n" - "import static void SetPlasmaType (int component, PlasmaMixMode type, int data=0, int data2=0, int data3=0);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Set all plasma settings to 0. \r\n" - "import static void ResetPlasmaSettings ();// $AUTOCOMPLETESTATICONLY$\r\n" - "///Draw Plasma into dynamic sprite slot using range palstart-palend. Remember to use SetPlasmaType first! \r\n" - "import static void DrawPlasma (int slot, int palstart, int palend);// $AUTOCOMPLETESTATICONLY$ \r\n" - "///Draw fire effect into sprite, and alpha channel into masksprite. \r\n" - "import static void DoFire (int sprite, int masksprite, int palstart,int palend, int strength, int seed=0,int cutoff=0,int windspeed=0);// $AUTOCOMPLETESTATICONLY$\r\n" - "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" - "import static void SetRootType (PlasmaRootType real);// $AUTOCOMPLETESTATICONLY$ \r\n" - "import static int GetRootType ();// $AUTOCOMPLETESTATICONLY$ \r\n" - "}; \r\n" - - "struct Starfield { \r\n" - "import static void Draw (int slot, int maskslot); \r\n" - "import static void RotateStar (int star, int angle,int px,int py); \r\n" - "import static void Iterate (int slot); \r\n" - "import static void Initialize (int slot,int maxstars); \r\n" - "import static void SetOriginPoint (int x,int y); \r\n" - "import static float GetStarX (int i); \r\n" - "import static float GetStarY (int i); \r\n" - "import static float GetStarZ (int i); \r\n" - "import static void SetStarPosition (int star,float x,float y,float z); \r\n" - "import static void SetStarColor (int star, char color); \r\n" - "import static char GetStarColor (int star); \r\n" - "import static void SetStarSprite (int star, int slot); \r\n" - "import static int GetStarSprite (int star); \r\n" - "import static void SetStarSpriteRange (int start, int end, int slot); \r\n" - "import static int GetOverscan (); \r\n" - "import static void SetOverscan (int overscan); \r\n" - "import static int GetOriginX (); \r\n" - "import static int GetOriginY (); \r\n" - "import static void SetDepthMultiplier (int multi); \r\n" - "import static int GetDepthMultiplier (); \r\n" - "import static int GetMaxStars (); \r\n" - "import static void SetStarSpriteScaleBoost (int star,int boost); \r\n" - "import static int GetStarSpriteScaleBoost (int star); \r\n" - "import static void SetStarMaxRadius (int star,int radius); \r\n" - "import static int GetStarMaxRadius (int star); \r\n" - "int dummy; //$AUTOCOMPLETEIGNORE$ \r\n" - "}; \r\n"; - -const char *AGS_GetPluginName(void) { - // Return the plugin description - return "PALgorithms Translucent Overlay Renderer"; -} - -int AGS_EditorStartup(IAGSEditor *lpEditor) { - // User has checked the plugin to use it in their game - - // If it's an earlier version than what we need, abort. - if (lpEditor->version < 1) - return -1; - - editor = lpEditor; - editor->RegisterScriptHeader(ourScriptHeader); - - // Return 0 to indicate success - return 0; -} - -void AGS_EditorShutdown() { - // User has un-checked the plugin from their game - editor->UnregisterScriptHeader(ourScriptHeader); -} - -#if AGS_PLATFORM_OS_WINDOWS -void AGS_EditorProperties(HWND parent) { - // User has chosen to view the Properties of the plugin - // We could load up an options dialog or something here instead - MessageBox(parent, "PALgorithms Translucent Overlay Renderer & Other Demo Effects (c) 2015 Scavenger", "About", MB_OK | MB_ICONINFORMATION); -} - -#endif - -int AGS_EditorSaveGame(char *buffer, int bufsize) { - // We don't want to save any persistent data - return 0; -} - -void AGS_EditorLoadGame(char *buffer, int bufsize) { - // Nothing to load for this dummy plugin -} - -#endif // #if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) -// ******* END DESIGN TIME ******* - - -// ****** RUN TIME ******** - -IAGSEngine *engine; - void WriteObjectivePalette(unsigned char index, unsigned char r, unsigned char b, unsigned char g) { objectivepal[index].r = r; objectivepal[index].b = b; @@ -534,7 +202,7 @@ unsigned short root(unsigned short x) { } -inline float Hill(float x) { +float Hill(float x) { const float a0 = 1.0f; const float a2 = 2.0f / PI - 12.0f / (pisquared); const float a3 = 16.0f / (picubed) - 4.0f / (pisquared); @@ -585,7 +253,7 @@ void DrawLens(int ox, int oy) { BITMAP *virtsc = engine->GetVirtualScreen(); if (!virtsc) engine->AbortGame("DrawLens: Cannot get virtual screen."); BITMAP *lenswrite = engine->CreateBlankBitmap(LensOption.lenswidth, LensOption.lenswidth, 8); - unsigned char **screen = engine->GetRawBitmapSurface(virtsc); + unsigned char **vScreen = engine->GetRawBitmapSurface(virtsc); unsigned char **lensarray = engine->GetRawBitmapSurface(lenswrite); int radius = LensOption.lenswidth >> 1; for (int y = 0; y < LensOption.lenswidth; y++) { @@ -595,8 +263,8 @@ void DrawLens(int ox, int oy) { int coffx = lens[lenspos].xoffset; int coffy = lens[lenspos].yoffset; if (oy + coffy > 0 && oy + coffy < sh && ox + coffx > 0 && ox + coffx < sw) { - lensarray[y][x] = screen[oy + coffy][ox + coffx]; - //screen[oy+coffy][ox+coffx] = abs(coffy); + lensarray[y][x] = vScreen[oy + coffy][ox + coffx]; + //vScreen[oy+coffy][ox+coffx] = ABS(coffy); } } } @@ -608,7 +276,7 @@ void DrawLens(int ox, int oy) { { if (oy+y > 0 && oy+y < sh && ox+x > 0 && ox+x < sw) { - screen[oy+y][ox+x] = lensarray[y][x]; + vScreen[oy+y][ox+x] = lensarray[y][x]; } } } @@ -622,7 +290,7 @@ void DrawLens(int ox, int oy) { int dy = cy + oy; if ((cxsq + cysq <= radsq) && dx < sw && dx >= 0 && dy < sh && dy >= 0 && cy + radius < LensOption.lenswidth - 1 && cx + radius < LensOption.lenswidth - 1) { //if (cy+radius < 0 || cx+radius < 0) engine->AbortGame ("I did something wrong"); - screen[dy][dx] = lensarray[cy + radius][cx + radius]; + vScreen[dy][dx] = lensarray[cy + radius][cx + radius]; } } } @@ -810,9 +478,9 @@ void DrawPlasma(int slot, int palstart, int palend) { engine->NotifySpriteUpdated(slot); } -void DoFire(int sprite, int masksprite, int palstart, int palend, int strength, int seed, int cutoff, int windspeed) { +void DoFire(int spriteId, int masksprite, int palstart, int palend, int strength, int seed, int cutoff, int windspeed) { BITMAP *firespr = engine->GetSpriteGraphic(masksprite); - BITMAP *firecolorspr = engine->GetSpriteGraphic(sprite); + BITMAP *firecolorspr = engine->GetSpriteGraphic(spriteId); BITMAP *seedspr; int32 w, h = 0; int range, basecol, dir = 0; @@ -832,25 +500,31 @@ void DoFire(int sprite, int masksprite, int palstart, int palend, int strength, int sparky = 0; //srand(time(NULL)); for (int y = 0; y < h - 1; y++) { - if (rand() % 10 > 7 - windspeed) { //Wind right + if ((int)::AGS::g_vm->getRandomNumber(9) > 7 - windspeed) { //Wind right for (int x = w - 1; x > 1; x--) { fire[y][x] = fire[y][x - 1]; } - } else if (rand() % 10 > 7 + windspeed) { // wind left + } else if ((int)::AGS::g_vm->getRandomNumber(9) > 7 + windspeed) { // wind left for (int x = 0; x < w - 1; x++) { fire[y][x] = fire[y][x + 1]; } } } for (int x = 0; x < w; x++) { - sparky = abs(rand() % (h - 2)); - if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff && abs(rand() % 10) > 7) fire[h - sparky][x] = 255; - sparky = abs(rand() % (h - 2)); - if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff && abs(rand() % 10) > 7) fire[h - sparky][x] = 0; + sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2)); + if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff && + ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7) + fire[h - sparky][x] = 255; + sparky = ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % (h - 2)); + if (sparky < h && sparky > 0 && fire[h - sparky][x] > cutoff && + ABS((int)::AGS::g_vm->getRandomNumber(0x7fffffff) % 10) > 7) + fire[h - sparky][x] = 0; } if (seed == 0) { - for (int x = 0; x < w; x++) fire[h - 1][x] = 255; - for (int x = 0; x < w; x++) fire[h - 2][x] = abs(32768 + rand()) % 256; + for (int x = 0; x < w; x++) + fire[h - 1][x] = 255; + for (int x = 0; x < w; x++) + fire[h - 2][x] = ::AGS::g_vm->getRandomNumber(255); } else if (seed > 0) { seedspr = engine->GetSpriteGraphic(seed); BITMAP *virtsc = engine->GetVirtualScreen(); @@ -859,7 +533,7 @@ void DoFire(int sprite, int masksprite, int palstart, int palend, int strength, engine->SetVirtualScreen(virtsc); engine->ReleaseBitmapSurface(virtsc); engine->ReleaseBitmapSurface(seedspr); - engine->NotifySpriteUpdated(sprite); + engine->NotifySpriteUpdated(spriteId); engine->NotifySpriteUpdated(masksprite); } @@ -878,7 +552,7 @@ void DoFire(int sprite, int masksprite, int palstart, int palend, int strength, } engine->ReleaseBitmapSurface(firespr); engine->ReleaseBitmapSurface(firecolorspr); - engine->NotifySpriteUpdated(sprite); + engine->NotifySpriteUpdated(spriteId); engine->NotifySpriteUpdated(masksprite); } @@ -1025,14 +699,14 @@ void InitializeStars(int slot, int maxstars) { Starfield.overscan = 20; stars = new starstype [Starfield.maxstars]; for (int i = 0; i < Starfield.maxstars; i++) { - stars[i].x = (float)((rand() % sw) << 1) - sw; + stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw; if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw; - stars[i].y = (float)((rand() % sh) << 1) - sh; + stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh; if (stars[i].y < 1.0 && stars[i].y > -1.0) stars[i].y = (float)sh; stars[i].z = (float)(MAX_DEPTH); - stars[i].color = (rand() % 240); + stars[i].color = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 240); stars[i].sprite = 0; - stars[i].maxrad = (rand() % 5); + stars[i].maxrad = (::AGS::g_vm->getRandomNumber(0x7fffffff) % 5); } } @@ -1047,9 +721,9 @@ void IterateStars(int slot) { int px = static_cast(stars[i].x * k + Starfield.originx); int py = static_cast(stars[i].y * k + Starfield.originy); if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) { - stars[i].x = (float)((rand() % sw) << 1) - sw; + stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw; if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw; - stars[i].y = (float)((rand() % sh) << 1) - sh; + stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh; if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh; stars[i].z = (float)MAX_DEPTH; //stars[i].color = (rand () %240); @@ -1180,9 +854,9 @@ void DrawStars(int slot, int maskslot) { int px = static_cast(stars[i].x * k + Starfield.originx); int py = static_cast(stars[i].y * k + Starfield.originy); if (px >= sw + Starfield.overscan || px < 0 - Starfield.overscan || py >= sh + Starfield.overscan || py < 0 - Starfield.overscan) { - stars[i].x = (float)((rand() % sw) << 1) - sw; + stars[i].x = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sw) << 1) - sw; if (stars[i].x < 1.0 && stars[i].x > -1.0) stars[i].x = (float)sw; - stars[i].y = (float)((rand() % sh) << 1) - sh; + stars[i].y = (float)((::AGS::g_vm->getRandomNumber(0x7fffffff) % sh) << 1) - sh; if (stars[i].y < 1.0 && stars[i].y > 1.0) stars[i].y = (float)sh; stars[i].z = (float)MAX_DEPTH; //stars[i].color = (rand () %240); @@ -1265,9 +939,9 @@ void DrawStars(int slot, int maskslot) { int x2, y2 ; int ox = px - (w2 >> 1); int oy = py - (h2 >> 1); - for (int i = 0; i < h2; i++) { - int temprzy = i * y_ratio; - int ey = oy + i; + for (int ii = 0; ii < h2; ii++) { + int temprzy = ii * y_ratio; + int ey = oy + ii; for (int j = 0; j < w2; j++) { x2 = ((j * x_ratio) >> 16); y2 = ((temprzy) >> 16); @@ -1278,7 +952,7 @@ void DrawStars(int slot, int maskslot) { screenarray [ey][ex] = orig[y2][x2]; } } - //resized [i][j] = orig [y2][x2]; + //resized [ii][j] = orig [y2][x2]; } } engine->ReleaseBitmapSurface(origspr); @@ -1338,14 +1012,13 @@ void DrawStars(int slot, int maskslot) { } -int CreateTranslucentOverlay(int id, int sprite, int alpha, int level, int ox, int oy, int mask = 0, int blendmode = 0) { - - BITMAP *testspr = engine->GetSpriteGraphic(sprite); - if (testspr) overlay[id].sprite = sprite; - else engine->AbortGame("CreateTranslucentOverlay: Invalid sprite."); +int CreateTranslucentOverlay(int id, int spriteId, int alpha, int level, int ox, int oy, int mask = 0, int blendmode = 0) { + BITMAP *testspr = engine->GetSpriteGraphic(spriteId); + if (testspr) overlay[id].sprite = spriteId; + else engine->AbortGame("CreateTranslucentOverlay: Invalid spriteId."); engine->ReleaseBitmapSurface(testspr); - overlay[id].level = std::max(0, std::min(level, 4)); - overlay[id].trans = std::max(0, std::min(alpha, 255)); + overlay[id].level = MAX(0, MIN(level, 4)); + overlay[id].trans = MAX(0, MIN(alpha, 255)); overlay[id].spritemask = mask; overlay[id].x = ox; overlay[id].y = oy; @@ -1523,8 +1196,8 @@ int DrawReflections(int id, int charobj = 0) { engine->RoomToViewport(&ox, &oy); int yoffset = 0; int translevel = 7; - bool dither = false; - bool dodither = false; + //bool dither = false; + //bool dodither = false; int counter = 0; int rowcount = 101 - (int)(50.0 * ((double)(scale) / 100.0)); int delay = screenh / rowcount; @@ -1591,7 +1264,7 @@ int DrawReflections(int id, int charobj = 0) { } -int DrawTransSprite(int sprite, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) { +int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) { BITMAP *maskspr = nullptr; unsigned char **maskarray; if (mask > 0) maskspr = engine->GetSpriteGraphic(mask); @@ -1604,10 +1277,10 @@ int DrawTransSprite(int sprite, int bg, int translevel, int mask = 0, int blendm // Get a reference to the screen we'll draw onto BITMAP *bgspr = engine->GetSpriteGraphic(bg); //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); - BITMAP *spritespr = engine->GetSpriteGraphic(sprite); + BITMAP *spritespr = engine->GetSpriteGraphic(spriteId); if (!bgspr) engine->AbortGame("DrawTransSprite: Can't load background"); - //if (!clutspr) engine->AbortGame ("Can't load CLUT sprite into memory."); - if (!spritespr) engine->AbortGame("DrawTransSprite: Can't load overlay sprite into memory."); + //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory."); + if (!spritespr) engine->AbortGame("DrawTransSprite: Can't load overlay spriteId into memory."); // Get its surface int32 sprw, sprh, coldepth; int32 bgw, bgh; @@ -1624,9 +1297,9 @@ int DrawTransSprite(int sprite, int bg, int translevel, int mask = 0, int blendm //int transamount = 256 * translevel; //old while (y < sprh) { while (x < sprw) { - if (spritearray [y][x] != 0 && y < bgh && x < bgw && y >= 0 && x >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the bg. + if (spritearray [y][x] != 0 && y < bgh && x < bgw && y >= 0 && x >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the bg. if (mask > 0) { - translevel = std::max(maskarray [y][x] - tloffset, 0); + translevel = MAX(maskarray [y][x] - tloffset, 0); } //spritearray[y][x] = cycle_remap[clutarray [cycle_remap[bgarray[y][x]]+transamount][cycle_remap[spritearray [y][x]]]]; //old if (blendmode == 0) spritearray[y][x] = Mix::MixColorAlpha(spritearray [y][x], bgarray[y][x], translevel, use_objpal); @@ -1642,22 +1315,22 @@ int DrawTransSprite(int sprite, int bg, int translevel, int mask = 0, int blendm engine->ReleaseBitmapSurface(bgspr); //engine->ReleaseBitmapSurface (clutspr); engine->ReleaseBitmapSurface(spritespr); - engine->NotifySpriteUpdated(sprite); + engine->NotifySpriteUpdated(spriteId); return 0; } -int DrawTranslucentOverlay(int sprite, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) { +int DrawTranslucentOverlay(int spriteId, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) { if (translevel == 0) return 0; BITMAP *maskspr; unsigned char **maskarray; // Get a reference to the screen we'll draw onto BITMAP *virtsc = engine->GetVirtualScreen(); //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); - BITMAP *spritespr = engine->GetSpriteGraphic(sprite); + BITMAP *spritespr = engine->GetSpriteGraphic(spriteId); if (mask > 0) maskspr = engine->GetSpriteGraphic(mask); if (!virtsc) engine->AbortGame("DrawTranslucentOverlay: Can't load virtual screen."); - //if (!clutspr) engine->AbortGame ("Can't load CLUT sprite into memory."); - if (!spritespr) engine->AbortGame("DrawTranslucentOverlay: Can't load overlay sprite into memory."); + //if (!clutspr) engine->AbortGame ("Can't load CLUT spriteId into memory."); + if (!spritespr) engine->AbortGame("DrawTranslucentOverlay: Can't load overlay spriteId into memory."); // Get its surface int32 sprw, sprh, coldepth; int32 screenw, screenh; @@ -1679,10 +1352,10 @@ int DrawTranslucentOverlay(int sprite, int translevel, int ox, int oy, int mask //int transamount = 256 * translevel; //old while (y < sprh) { while (x < sprw) { - if (spritearray [y][x] != 0 && y + oy < screenh && x + ox < screenw && y + oy >= 0 && x + ox >= 0) { // If the sprite isn't transparent, and isn't drawn off the edge of the screen. + if (spritearray [y][x] != 0 && y + oy < screenh && x + ox < screenw && y + oy >= 0 && x + ox >= 0) { // If the spriteId isn't transparent, and isn't drawn off the edge of the screen. //charbuffer[y+oy][x+ox] = cycle_remap[clutarray [cycle_remap[charbuffer[y+oy][x+ox]]+transamount][cycle_remap[spritearray [y][x]]]]; //old if (mask > 0) { - translevel = std::max(maskarray [y][x] - tloffset, 0); + translevel = MAX(maskarray [y][x] - tloffset, 0); } if (blendmode == 0) { if (translevel == 255) { @@ -1706,10 +1379,24 @@ int DrawTranslucentOverlay(int sprite, int translevel, int ox, int oy, int mask engine->ReleaseBitmapSurface(spritespr); if (mask > 0) engine->ReleaseBitmapSurface(maskspr); engine->MarkRegionDirty(ox, oy, dirtywidth, dirtyheight); + return 0; } -void AGS_EngineStartup(IAGSEngine *lpEngine) { +/*------------------------------------------------------------------*/ + +AGSPalRender::AGSPalRender() : DLL() { + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); + DLL_METHOD(AGS_EngineShutdown); + DLL_METHOD(AGS_EngineOnEvent); +} + +const char *AGSPalRender::AGS_GetPluginName() { + return "PALgorithms Translucent Overlay Renderer"; +} + +void AGSPalRender::AGS_EngineStartup(IAGSEngine *lpEngine) { engine = lpEngine; // Make sure it's got the version with the features we need @@ -1901,16 +1588,15 @@ void AGS_EngineStartup(IAGSEngine *lpEngine) { Init_Raycaster(); } -void AGS_EngineShutdown() { +void AGSPalRender::AGS_EngineShutdown() { // no work to do here - but if we had created any dynamic sprites, // we should delete them here - delete [] Reflection.Characters; - delete [] Reflection.Objects; - //QuitCleanup (); + delete[] Reflection.Characters; + delete[] Reflection.Objects; + //QuitCleanup(); } - -int AGS_EngineOnEvent(int event, int data) { +int AGSPalRender::AGS_EngineOnEvent(int event, int data) { if (event == AGSE_PRESCREENDRAW && clutslot > 0) { if (drawreflections) { int32 sh, sw = 0; @@ -2152,13 +1838,6 @@ int AGS_EngineOnEvent(int event, int data) { return 0; } -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { - return 0; -} -void AGS_EngineInitGfx(const char *driverID, void *data) {} - -// *** END RUN TIME **** - -#if defined(BUILTIN_PLUGINS) -} // namespace agspalrender -#endif +} // namespace AGSPalRender +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.h b/engines/ags/plugins/ags_pal_render/ags_pal_render.h index 61063daf9019..bf3247852af4 100644 --- a/engines/ags/plugins/ags_pal_render/ags_pal_render.h +++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.h @@ -1,14 +1,47 @@ -#ifndef AGS_TOUCH_H -#define AGS_TOUCH_H +/* 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 "plugin/agsplugin.h" +#ifndef AGS_PLUGINS_AGS_PAL_RENDER_AGS_PAL_RENDER_H +#define AGS_PLUGINS_AGS_PAL_RENDER_AGS_PAL_RENDER_H -namespace agspalrender { -void AGS_EngineStartup(IAGSEngine *lpEngine); -void AGS_EngineShutdown(); -int AGS_EngineOnEvent(int event, int data); -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); -void AGS_EngineInitGfx(const char *driverID, void *data); -} +#include "ags/plugins/dll.h" -#endif \ No newline at end of file +namespace AGS3 { +namespace Plugins { +namespace AGSPalRender { + +class AGSPalRender : public DLL { +private: + static const char *AGS_GetPluginName(); + static void AGS_EngineStartup(IAGSEngine *lpEngine); + static void AGS_EngineShutdown(); + static int AGS_EngineOnEvent(int event, int data); + +public: + AGSPalRender(); +}; + +} // namespace AGSPalRender +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_pal_render/agsplugin.h b/engines/ags/plugins/ags_pal_render/agsplugin.h deleted file mode 100644 index f9fd46e6edc7..000000000000 --- a/engines/ags/plugins/ags_pal_render/agsplugin.h +++ /dev/null @@ -1,564 +0,0 @@ -//============================================================================= -// -// Adventure Game Studio (AGS) -// -// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others -// The full list of copyright holders can be found in the Copyright.txt -// file, which is part of this source code distribution. -// -// The AGS source code is provided under the Artistic License 2.0. -// A copy of this license can be found in the file License.txt and at -// http://www.opensource.org/licenses/artistic-license-2.0.php -// -//============================================================================= -// -// AGS Plugin interface header file -// -// #define THIS_IS_THE_PLUGIN beforehand if including from the plugin -// -//============================================================================= - -#ifndef _AGS_PLUGIN_H -#define _AGS_PLUGIN_H - -// If the plugin isn't using DDraw, don't require the headers -#ifndef DIRECTDRAW_VERSION -typedef void *LPDIRECTDRAW2; -typedef void *LPDIRECTDRAWSURFACE2; -#endif - -#ifndef DIRECTSOUND_VERSION -typedef void *LPDIRECTSOUND; -#endif - -#ifndef DIRECTINPUT_VERSION -typedef void *LPDIRECTINPUTDEVICE; -#endif - -// If the user isn't using Allegro or WinGDI, define the BITMAP into something -#if !defined(ALLEGRO_H) && !defined(_WINGDI_) && !defined(BITMAP_DEFINED) -typedef char BITMAP; -#endif - -// If not using windows.h, define HWND -#if !defined(_WINDOWS_) && !defined(HWND) -typedef int HWND; -#endif - -// This file is distributed as part of the Plugin API docs, so -// ensure that WINDOWS_VERSION is defined (if applicable) -#if defined(_WINDOWS_) || defined(_WIN32) -#ifndef WINDOWS_VERSION -#define WINDOWS_VERSION -#endif -#endif - -// DOS engine doesn't know about stdcall / neither does Linux version -#if !defined (WINDOWS_VERSION) -#define __stdcall -#endif - -#ifndef int32 -#define int32 int -#endif - -#define AGSIFUNC(type) virtual type __stdcall - -#define MASK_WALKABLE 1 -#define MASK_WALKBEHIND 2 -#define MASK_HOTSPOT 3 -// MASK_REGIONS is interface version 11 and above only -#define MASK_REGIONS 4 - -// **** WARNING: DO NOT ALTER THESE CLASSES IN ANY WAY! -// **** CHANGING THE ORDER OF THE FUNCTIONS OR ADDING ANY VARIABLES -// **** WILL CRASH THE SYSTEM. - -struct AGSColor { - unsigned char r, g, b; - unsigned char padding; -}; - -struct AGSGameOptions { - int32 score; // player's current score - int32 usedmode; // set by ProcessClick to last cursor mode used - int32 disabled_user_interface; // >0 while in cutscene/etc - int32 gscript_timer; // obsolete - int32 debug_mode; // whether we're in debug mode - int32 globalvars[50]; // obsolete - int32 messagetime; // time left for auto-remove messages - int32 usedinv; // inventory item last used - int32 inv_top, inv_numdisp, inv_numorder, inv_numinline; - int32 text_speed; // how quickly text is removed - int32 sierra_inv_color; // background used to paint defualt inv window - int32 talkanim_speed; // animation speed of talking anims - int32 inv_item_wid, inv_item_hit; // set by SetInvDimensions - int32 speech_text_shadow; // colour of outline fonts (default black) - int32 swap_portrait_side; // sierra-style speech swap sides - int32 speech_textwindow_gui; // textwindow used for sierra-style speech - int32 follow_change_room_timer; // delay before moving following characters into new room - int32 totalscore; // maximum possible score - int32 skip_display; // how the user can skip normal Display windows - int32 no_multiloop_repeat; // for backwards compatibility - int32 roomscript_finished; // on_call finished in room - int32 used_inv_on; // inv item they clicked on - int32 no_textbg_when_voice; // no textwindow bgrnd when voice speech is used - int32 max_dialogoption_width; // max width of dialog options text window - int32 no_hicolor_fadein; // fade out but instant in for hi-color - int32 bgspeech_game_speed; // is background speech relative to game speed - int32 bgspeech_stay_on_display; // whether to remove bg speech when DisplaySpeech is used - int32 unfactor_speech_from_textlength; // remove "&10" when calculating time for text to stay - int32 mp3_loop_before_end; // loop this time before end of track (ms) - int32 speech_music_drop; // how much to drop music volume by when speech is played - int32 in_cutscene; // we are between a StartCutscene and EndCutscene - int32 fast_forward; // player has elected to skip cutscene - int32 room_width; // width of current room (320-res co-ordinates) - int32 room_height; // height of current room (320-res co-ordinates) -}; - -// AGSCharacter.flags -#define CHF_NOSCALING 1 -#define CHF_FIXVIEW 2 // between SetCharView and ReleaseCharView -#define CHF_NOINTERACT 4 -#define CHF_NODIAGONAL 8 -#define CHF_ALWAYSIDLE 0x10 -#define CHF_NOLIGHTING 0x20 -#define CHF_NOTURNING 0x40 -#define CHF_NOWALKBEHINDS 0x80 - -struct AGSCharacter { - int32 defview; - int32 talkview; - int32 view; - int32 room, prevroom; - int32 x, y, wait; - int32 flags; - short following; - short followinfo; - int32 idleview; // the loop will be randomly picked - short idletime, idleleft; // num seconds idle before playing anim - short transparency; // if character is transparent - short baseline; - int32 activeinv; - int32 talkcolor; - int32 thinkview; - int32 reserved[2]; - short walkspeed_y, pic_yoffs; - int32 z; - int32 reserved2[5]; - short loop, frame; - short walking, animating; - short walkspeed, animspeed; - short inv[301]; - short actx, acty; - char name[40]; - char scrname[20]; - char on; -}; - -// AGSObject.flags -#define OBJF_NOINTERACT 1 // not clickable -#define OBJF_NOWALKBEHINDS 2 // ignore walk-behinds - -struct AGSObject { - int32 x, y; - int32 transparent; // current transparency setting - int32 reserved[4]; - short num; // sprite slot number - short baseline; // <=0 to use Y co-ordinate; >0 for specific baseline - short view, loop, frame; // only used to track animation - 'num' holds the current sprite - short wait, moving; - char cycling; // is it currently animating? - char overall_speed; - char on; - char flags; -}; - -// AGSViewFrame.flags -#define FRAF_MIRRORED 1 // flipped left to right - -struct AGSViewFrame { - int32 pic; // sprite slot number - short xoffs, yoffs; - short speed; - int32 flags; - int32 sound; // play sound when this frame comes round - int32 reserved_for_future[2]; -}; - -// AGSMouseCursor.flags -#define MCF_ANIMATEMOVE 1 -#define MCF_DISABLED 2 -#define MCF_STANDARD 4 -#define MCF_ONLYANIMOVERHOTSPOT 8 - -struct AGSMouseCursor { - int32 pic; // sprite slot number - short hotx, hoty; // x,y hotspot co-ordinates - short view; // view (for animating cursors) or -1 - char name[10]; // name of cursor mode - char flags; // MCF_flags above -}; - -// The editor-to-plugin interface -class IAGSEditor { -public: - int32 version; - int32 pluginId; // used internally, do not touch this - -public: - // get the HWND of the main editor frame - AGSIFUNC(HWND) GetEditorHandle(); - // get the HWND of the current active window - AGSIFUNC(HWND) GetWindowHandle(); - // add some script to the default header - AGSIFUNC(void) RegisterScriptHeader(const char *header); - // de-register a script header (pass same pointer as when added) - AGSIFUNC(void) UnregisterScriptHeader(const char *header); - -}; - - -// Below are interface 3 and later -#define AGSE_KEYPRESS 1 -#define AGSE_MOUSECLICK 2 -#define AGSE_POSTSCREENDRAW 4 -// Below are interface 4 and later -#define AGSE_PRESCREENDRAW 8 -// Below are interface 5 and later -#define AGSE_SAVEGAME 0x10 -#define AGSE_RESTOREGAME 0x20 -// Below are interface 6 and later -#define AGSE_PREGUIDRAW 0x40 -#define AGSE_LEAVEROOM 0x80 -#define AGSE_ENTERROOM 0x100 -#define AGSE_TRANSITIONIN 0x200 -#define AGSE_TRANSITIONOUT 0x400 -// Below are interface 12 and later -#define AGSE_FINALSCREENDRAW 0x800 -#define AGSE_TRANSLATETEXT 0x1000 -// Below are interface 13 and later -#define AGSE_SCRIPTDEBUG 0x2000 -#define AGSE_AUDIODECODE 0x4000 // obsolete, no longer supported -// Below are interface 18 and later -#define AGSE_SPRITELOAD 0x8000 -// Below are interface 21 and later -#define AGSE_PRERENDER 0x10000 -// Below are interface 24 and later -#define AGSE_PRESAVEGAME 0x20000 -#define AGSE_POSTRESTOREGAME 0x40000 -#define AGSE_TOOHIGH 0x80000 - -// GetFontType font types -#define FNT_INVALID 0 -#define FNT_SCI 1 -#define FNT_TTF 2 - -// PlaySoundChannel sound types -#define PSND_WAVE 1 -#define PSND_MP3STREAM 2 -#define PSND_MP3STATIC 3 -#define PSND_OGGSTREAM 4 -#define PSND_OGGSTATIC 5 -#define PSND_MIDI 6 -#define PSND_MOD 7 - -class IAGSScriptManagedObject { -public: - // when a ref count reaches 0, this is called with the address - // of the object. Return 1 to remove the object from memory, 0 to - // leave it - virtual int Dispose(const char *address, bool force) = 0; - // return the type name of the object - virtual const char *GetType() = 0; - // serialize the object into BUFFER (which is BUFSIZE bytes) - // return number of bytes used - virtual int Serialize(const char *address, char *buffer, int bufsize) = 0; -}; - -class IAGSManagedObjectReader { -public: - virtual void Unserialize(int key, const char *serializedData, int dataSize) = 0; -}; - -class IAGSFontRenderer { -public: - virtual bool LoadFromDisk(int fontNumber, int fontSize) = 0; - virtual void FreeMemory(int fontNumber) = 0; - virtual bool SupportsExtendedCharacters(int fontNumber) = 0; - virtual int GetTextWidth(const char *text, int fontNumber) = 0; - virtual int GetTextHeight(const char *text, int fontNumber) = 0; - virtual void RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) = 0; - virtual void AdjustYCoordinateForFont(int *ycoord, int fontNumber) = 0; - virtual void EnsureTextValidForFont(char *text, int fontNumber) = 0; -}; - -// The plugin-to-engine interface -class IAGSEngine { -public: - int32 version; - int32 pluginId; // used internally, do not touch - -public: - // quit the game - AGSIFUNC(void) AbortGame(const char *reason); - // get engine version - AGSIFUNC(const char *) GetEngineVersion(); - // register a script function with the system - AGSIFUNC(void) RegisterScriptFunction(const char *name, void *address); -#ifdef WINDOWS_VERSION - // get game window handle - AGSIFUNC(HWND) GetWindowHandle(); - // get reference to main DirectDraw interface - AGSIFUNC(LPDIRECTDRAW2) GetDirectDraw2(); - // get the DDraw surface associated with a bitmap - AGSIFUNC(LPDIRECTDRAWSURFACE2) GetBitmapSurface(BITMAP *); -#endif - // get a reference to the screen bitmap - AGSIFUNC(BITMAP *) GetScreen(); - - // *** BELOW ARE INTERFACE VERSION 2 AND ABOVE ONLY - // ask the engine to call back when a certain event happens - AGSIFUNC(void) RequestEventHook(int32 event); - // get the options data saved in the editor - AGSIFUNC(int) GetSavedData(char *buffer, int32 bufsize); - - // *** BELOW ARE INTERFACE VERSION 3 AND ABOVE ONLY - // get the virtual screen - AGSIFUNC(BITMAP *) GetVirtualScreen(); - // write text to the screen in the specified font and colour - AGSIFUNC(void) DrawText(int32 x, int32 y, int32 font, int32 color, char *text); - // get screen dimensions - AGSIFUNC(void) GetScreenDimensions(int32 *width, int32 *height, int32 *coldepth); - // get screen surface to draw on - AGSIFUNC(unsigned char **) GetRawBitmapSurface(BITMAP *); - // release the surface - AGSIFUNC(void) ReleaseBitmapSurface(BITMAP *); - // get the current mouse co-ordinates - AGSIFUNC(void) GetMousePosition(int32 *x, int32 *y); - - // *** BELOW ARE INTERFACE VERSION 4 AND ABOVE ONLY - // get the current room number - AGSIFUNC(int) GetCurrentRoom(); - // get the number of background scenes in this room - AGSIFUNC(int) GetNumBackgrounds(); - // get the current background frame - AGSIFUNC(int) GetCurrentBackground(); - // get a background scene bitmap - AGSIFUNC(BITMAP *) GetBackgroundScene(int32); - // get dimensions of a bitmap - AGSIFUNC(void) GetBitmapDimensions(BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth); - - // *** BELOW ARE INTERFACE VERSION 5 AND ABOVE ONLY - // similar to fwrite - buffer, size, filehandle - AGSIFUNC(int) FWrite(void *, int32, int32); - // similar to fread - buffer, size, filehandle - AGSIFUNC(int) FRead(void *, int32, int32); - // print text, wrapping as usual - AGSIFUNC(void) DrawTextWrapped(int32 x, int32 y, int32 width, int32 font, int32 color, const char *text); - // set the current active 'screen' - AGSIFUNC(void) SetVirtualScreen(BITMAP *); - // look up a word in the parser dictionary - AGSIFUNC(int) LookupParserWord(const char *word); - // draw a bitmap to the active screen - AGSIFUNC(void) BlitBitmap(int32 x, int32 y, BITMAP *, int32 masked); - // update the mouse and music - AGSIFUNC(void) PollSystem(); - - // *** BELOW ARE INTERFACE VERSION 6 AND ABOVE ONLY - // get number of characters in game - AGSIFUNC(int) GetNumCharacters(); - // get reference to specified character struct - AGSIFUNC(AGSCharacter *) GetCharacter(int32); - // get reference to game struct - AGSIFUNC(AGSGameOptions *) GetGameOptions(); - // get reference to current palette - AGSIFUNC(AGSColor *) GetPalette(); - // update palette - AGSIFUNC(void) SetPalette(int32 start, int32 finish, AGSColor *); - - // *** BELOW ARE INTERFACE VERSION 7 AND ABOVE ONLY - // get the current player character - AGSIFUNC(int) GetPlayerCharacter(); - // adjust to viewport co-ordinates - AGSIFUNC(void) RoomToViewport(int32 *x, int32 *y); - // adjust from viewport co-ordinates - AGSIFUNC(void) ViewportToRoom(int32 *x, int32 *y); - // number of objects in current room - AGSIFUNC(int) GetNumObjects(); - // get reference to specified object - AGSIFUNC(AGSObject *) GetObject(int32); - // get sprite graphic - AGSIFUNC(BITMAP *) GetSpriteGraphic(int32); - // create a new blank bitmap - AGSIFUNC(BITMAP *) CreateBlankBitmap(int32 width, int32 height, int32 coldep); - // free a created bitamp - AGSIFUNC(void) FreeBitmap(BITMAP *); - - // *** BELOW ARE INTERFACE VERSION 8 AND ABOVE ONLY - // get one of the room area masks - AGSIFUNC(BITMAP *) GetRoomMask(int32); - - // *** BELOW ARE INTERFACE VERSION 9 AND ABOVE ONLY - // get a particular view frame - AGSIFUNC(AGSViewFrame *) GetViewFrame(int32 view, int32 loop, int32 frame); - // get the walk-behind baseline of a specific WB area - AGSIFUNC(int) GetWalkbehindBaseline(int32 walkbehind); - // get the address of a script function - AGSIFUNC(void *) GetScriptFunctionAddress(const char *funcName); - // get the transparent colour of a bitmap - AGSIFUNC(int) GetBitmapTransparentColor(BITMAP *); - // get the character scaling level at a particular point - AGSIFUNC(int) GetAreaScaling(int32 x, int32 y); - // equivalent to the text script function - AGSIFUNC(int) IsGamePaused(); - - // *** BELOW ARE INTERFACE VERSION 10 AND ABOVE ONLY - // get the raw pixel value to use for the specified AGS colour - AGSIFUNC(int) GetRawPixelColor(int32 color); - - // *** BELOW ARE INTERFACE VERSION 11 AND ABOVE ONLY - // get the width / height of the specified sprite - AGSIFUNC(int) GetSpriteWidth(int32); - AGSIFUNC(int) GetSpriteHeight(int32); - // get the dimensions of the specified string in the specified font - AGSIFUNC(void) GetTextExtent(int32 font, const char *text, int32 *width, int32 *height); - // print a message to the debug console - AGSIFUNC(void) PrintDebugConsole(const char *text); - // play a sound on the specified channel - AGSIFUNC(void) PlaySoundChannel(int32 channel, int32 soundType, int32 volume, int32 loop, const char *filename); - // same as text script function - AGSIFUNC(int) IsChannelPlaying(int32 channel); - - // *** BELOW ARE INTERFACE VERSION 12 AND ABOVE ONLY - // invalidate a region of the virtual screen - AGSIFUNC(void) MarkRegionDirty(int32 left, int32 top, int32 right, int32 bottom); - // get mouse cursor details - AGSIFUNC(AGSMouseCursor *) GetMouseCursor(int32 cursor); - // get the various components of a pixel - AGSIFUNC(void) GetRawColorComponents(int32 coldepth, int32 color, int32 *red, int32 *green, int32 *blue, int32 *alpha); - // make a pixel colour from the supplied components - AGSIFUNC(int) MakeRawColorPixel(int32 coldepth, int32 red, int32 green, int32 blue, int32 alpha); - // get whether the font is TTF or SCI - AGSIFUNC(int) GetFontType(int32 fontNum); - // create a new dynamic sprite slot - AGSIFUNC(int) CreateDynamicSprite(int32 coldepth, int32 width, int32 height); - // free a created dynamic sprite - AGSIFUNC(void) DeleteDynamicSprite(int32 slot); - // check if a sprite has an alpha channel - AGSIFUNC(int) IsSpriteAlphaBlended(int32 slot); - - // *** BELOW ARE INTERFACE VERSION 13 AND ABOVE ONLY - // un-request an event, requested earlier with RequestEventHook - AGSIFUNC(void) UnrequestEventHook(int32 event); - // draw a translucent bitmap to the active screen - AGSIFUNC(void) BlitSpriteTranslucent(int32 x, int32 y, BITMAP *, int32 trans); - // draw a sprite to the screen, but rotated around its centre - AGSIFUNC(void) BlitSpriteRotated(int32 x, int32 y, BITMAP *, int32 angle); - - // *** BELOW ARE INTERFACE VERSION 14 AND ABOVE ONLY -#ifdef WINDOWS_VERSION - // get reference to main DirectSound interface - AGSIFUNC(LPDIRECTSOUND) GetDirectSound(); -#endif - // disable AGS sound engine - AGSIFUNC(void) DisableSound(); - // check whether a script function can be run now - AGSIFUNC(int) CanRunScriptFunctionNow(); - // call a user-defined script function - AGSIFUNC(int) CallGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0, long arg3 = 0); - - // *** BELOW ARE INTERFACE VERSION 15 AND ABOVE ONLY - // force any sprites on-screen using the slot to be updated - AGSIFUNC(void) NotifySpriteUpdated(int32 slot); - // change whether the specified sprite is a 32-bit alpha blended image - AGSIFUNC(void) SetSpriteAlphaBlended(int32 slot, int32 isAlphaBlended); - // run the specified script function whenever script engine is available - AGSIFUNC(void) QueueGameScriptFunction(const char *name, int32 globalScript, int32 numArgs, long arg1 = 0, long arg2 = 0); - // register a new dynamic managed script object - AGSIFUNC(int) RegisterManagedObject(const void *object, IAGSScriptManagedObject *callback); - // add an object reader for the specified object type - AGSIFUNC(void) AddManagedObjectReader(const char *typeName, IAGSManagedObjectReader *reader); - // register an un-serialized managed script object - AGSIFUNC(void) RegisterUnserializedObject(int key, const void *object, IAGSScriptManagedObject *callback); - - // *** BELOW ARE INTERFACE VERSION 16 AND ABOVE ONLY - // get the address of a managed object based on its key - AGSIFUNC(void *) GetManagedObjectAddressByKey(int key); - // get managed object's key from its address - AGSIFUNC(int) GetManagedObjectKeyByAddress(const char *address); - - // *** BELOW ARE INTERFACE VERSION 17 AND ABOVE ONLY - // create a new script string - AGSIFUNC(const char *) CreateScriptString(const char *fromText); - - // *** BELOW ARE INTERFACE VERSION 18 AND ABOVE ONLY - // increment reference count - AGSIFUNC(int) IncrementManagedObjectRefCount(const char *address); - // decrement reference count - AGSIFUNC(int) DecrementManagedObjectRefCount(const char *address); - // set mouse position - AGSIFUNC(void) SetMousePosition(int32 x, int32 y); - // simulate the mouse being clicked - AGSIFUNC(void) SimulateMouseClick(int32 button); - // get number of waypoints on this movement path - AGSIFUNC(int) GetMovementPathWaypointCount(int32 pathId); - // get the last waypoint that the char/obj passed - AGSIFUNC(int) GetMovementPathLastWaypoint(int32 pathId); - // get the co-ordinates of the specified waypoint - AGSIFUNC(void) GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y); - // get the speeds of the specified waypoint - AGSIFUNC(void) GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed); - - // *** BELOW ARE INTERFACE VERSION 19 AND ABOVE ONLY - // get the current graphics driver ID - AGSIFUNC(const char *) GetGraphicsDriverID(); - - // *** BELOW ARE INTERFACE VERSION 22 AND ABOVE ONLY - // get whether we are running under the editor's debugger - AGSIFUNC(int) IsRunningUnderDebugger(); - // tells the engine to break into the debugger when the next line of script is run - AGSIFUNC(void) BreakIntoDebugger(); - // fills buffer with \fileName, as appropriate - AGSIFUNC(void) GetPathToFileInCompiledFolder(const char *fileName, char *buffer); - - // *** BELOW ARE INTERFACE VERSION 23 AND ABOVE ONLY -#ifdef WINDOWS_VERSION - // get reference to keyboard Direct Input device - AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputKeyboard(); - // get reference to mouse Direct Input device - AGSIFUNC(LPDIRECTINPUTDEVICE) GetDirectInputMouse(); -#endif - // install a replacement renderer for the specified font number - AGSIFUNC(IAGSFontRenderer *) ReplaceFontRenderer(int fontNumber, IAGSFontRenderer *newRenderer); -}; - -#ifdef THIS_IS_THE_PLUGIN - -#ifdef WINDOWS_VERSION -#define DLLEXPORT extern "C" __declspec(dllexport) -#else -// MAC VERSION: compile with -fvisibility=hidden -// gcc -dynamiclib -std=gnu99 agsplugin.c -fvisibility=hidden -o agsplugin.dylib -#define DLLEXPORT extern "C" __attribute__((visibility("default"))) -#endif - -DLLEXPORT const char *AGS_GetPluginName(void); -DLLEXPORT int AGS_EditorStartup(IAGSEditor *); -DLLEXPORT void AGS_EditorShutdown(void); -DLLEXPORT void AGS_EditorProperties(HWND); -DLLEXPORT int AGS_EditorSaveGame(char *, int); -DLLEXPORT void AGS_EditorLoadGame(char *, int); -DLLEXPORT void AGS_EngineStartup(IAGSEngine *); -DLLEXPORT void AGS_EngineShutdown(void); -DLLEXPORT int AGS_EngineOnEvent(int, int); -DLLEXPORT int AGS_EngineDebugHook(const char *, int, int); -DLLEXPORT void AGS_EngineInitGfx(const char *driverID, void *data); -// We export this to verify that we are an AGS Plugin -DLLEXPORT int AGS_PluginV2() { - return 1; -} - -#endif // THIS_IS_THE_PLUGIN - -#endif diff --git a/engines/ags/plugins/ags_pal_render/pal_render.h b/engines/ags/plugins/ags_pal_render/pal_render.h index 09c2e6b5a5ab..1f448174e3d9 100644 --- a/engines/ags/plugins/ags_pal_render/pal_render.h +++ b/engines/ags/plugins/ags_pal_render/pal_render.h @@ -1,31 +1,40 @@ -#ifndef __PALGORITHMS_PALRENDER_H -#define __PALGORITHMS_PALRENDER_H - -#include "agsplugin.h" -#include // for int32_t types, __int32 is just Windows -#include // for std::max and std::min -#include // for memcpy - -#undef min -#undef max - -#ifndef _WIN32 -#define __forceinline __attribute__((always_inline)) - -#define SCRIPT_FLOAT(x) int32_t __script_float##x -#define INIT_SCRIPT_FLOAT(x) float x; std::memcpy(&x, &__script_float##x, sizeof(float)) -#define FLOAT_RETURN_TYPE int32_t -#define RETURN_FLOAT(x) int32_t __ret##x; std::memcpy(&__ret##x, &x, sizeof(float)); return __ret##x -#else -#define SCRIPT_FLOAT(x) __int32 __script_float##x +/* 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 AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H +#define AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H + +#include "ags/lib/allegro.h" +#include "ags/engine/plugin/agsplugin.h" +#include "common/algorithm.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSPalRender { + +#define SCRIPT_FLOAT(x) int32 __script_float##x #define INIT_SCRIPT_FLOAT(x) float x; memcpy(&x, &__script_float##x, sizeof(float)) -#define FLOAT_RETURN_TYPE __int32 -#define RETURN_FLOAT(x) __int32 __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x -#endif - -#if defined(BUILTIN_PLUGINS) -namespace agspalrender { -#endif +#define FLOAT_RETURN_TYPE int32 +#define RETURN_FLOAT(x) int32 __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x struct PALSTRUCT { int r; @@ -44,11 +53,10 @@ extern PALSTRUCT objectivepal[256]; // methods can be inlined without any trace or complaint class Mix { public: - //unsigned char MixColorAlpha (unsigned char fg,unsigned char bg,unsigned char alpha); //unsigned char MixColorAdditive (unsigned char fg,unsigned char bg,unsigned char alpha); - __forceinline static unsigned char MixColorAlpha(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { - unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. + static unsigned char MixColorAlpha(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { + unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots. //unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. AGSColor *palette = engine->GetPalette(); int i = 0; @@ -57,15 +65,15 @@ class Mix { //int out_b = (palette[fg].b>>1) * alpha + (palette[bg].b>>1) * (255 - alpha); int out_r, out_g, out_b; if (use_objpal == 0) { - out_r = (objectivepal[rfg].r >> 1) * alpha + (palette[bg].r >> 1) * (255 - alpha); + out_r = (objectivepal[rfg].r >> 1) *alpha + (palette[bg].r >> 1) *(255 - alpha); out_g = objectivepal[rfg].g * alpha + palette[bg].g * (255 - alpha); - out_b = (objectivepal[rfg].b >> 1) * alpha + (palette[bg].b >> 1) * (255 - alpha); + out_b = (objectivepal[rfg].b >> 1) *alpha + (palette[bg].b >> 1) *(255 - alpha); } else { - out_r = (objectivepal[rfg].r >> 1) * alpha + (objectivepal[bg].r >> 1) * (255 - alpha); + out_r = (objectivepal[rfg].r >> 1) *alpha + (objectivepal[bg].r >> 1) *(255 - alpha); out_g = objectivepal[rfg].g * alpha + objectivepal[bg].g * (255 - alpha); - out_b = (objectivepal[rfg].b >> 1) * alpha + (objectivepal[bg].b >> 1) * (255 - alpha); + out_b = (objectivepal[rfg].b >> 1) *alpha + (objectivepal[bg].b >> 1) *(255 - alpha); } - //char ralpha = std::max(0,std::min(63,alpha>>2)); + //char ralpha = MAX(0,MIN(63,alpha>>2)); //unsigned char invralpha = 64-ralpha; //if (ralpha > alpha) engine->AbortGame ("wtf"); //int out_r = alphamultiply[((palette[fg].r>>1)<<6) +ralpha] + alphamultiply[((palette[bg].r>>1)<<6) +(invralpha)]; @@ -78,13 +86,13 @@ class Mix { //out_g = (out_g + 1 + (out_g >> 6)) >> 6; //out_b = (out_b + 1 + (out_b >> 6)) >> 6; i = ((out_r << 11) | (out_g << 5) | out_b); - unsigned char (*clutp) = clut; + unsigned char(*clutp) = clut; //unsigned char result = cycle_remap [clut[i>>8][i%256]]; //Once again, to make sure that the palette slot used is the right one. return cycle_remap[*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one. //engine->ReleaseBitmapSurface (clutspr); } - __forceinline static unsigned char MixColorLightLevel(unsigned char fg, unsigned char intensity) { + static unsigned char MixColorLightLevel(unsigned char fg, unsigned char intensity) { unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. int i = 0; //int dark_r = (((palette[fg].r>>1) * (intensity))>>8); @@ -98,38 +106,38 @@ class Mix { return cycle_remap [*(clutp + i)]; //Once again, to make sure that the palette slot used is the right one. } - __forceinline static unsigned char MixColorAdditive(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { - unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. - unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. + static unsigned char MixColorAdditive(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { + unsigned char rfg = cycle_remap[fg]; //Automatic remapping of palette slots. + //unsigned char rbg = cycle_remap[bg]; //Saves on typing elsewhere. //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); //if (!clutspr) engine->AbortGame ("MixColorAlpha: Can't load CLUT sprite into memory."); //unsigned char **clutarray = engine->GetRawBitmapSurface (clutspr); AGSColor *palette = engine->GetPalette(); int i = 0; int add_r, add_b, add_g = 0; - //char ralpha = std::max(0,std::min(63,alpha>>2)); + //char ralpha = MAX(0,MIN(63,alpha>>2)); //add_r = (((palette[fg].r>>1) * (alpha))>>8); //add_b = (((palette[fg].b>>1) * (alpha))>>8); //add_g = (((palette[fg].g) * (alpha))>>8); add_r = (((objectivepal[rfg].r >> 1) * (alpha)) >> 8); add_b = (((objectivepal[rfg].b >> 1) * (alpha)) >> 8); add_g = (((objectivepal[rfg].g) * (alpha)) >> 8); - //int a_g = std::max(0,std::min(63,alpha>>2)); + //int a_g = MAX(0,MIN(63,alpha>>2)); //add_r = ((alphamultiply[(palette[fg].r>>1)<<6)+ralpha])>>6); //add_b = ((alphamultiply[(palette[fg].b>>1)<<6)+ralpha])>>6); //add_g = ((alphamultiply[(palette[fg].g) <<6)+ralpha])>>6); - //int out_r = std::min(31,(palette[bg].r>>1) + add_r); - //int out_g = std::min(63, palette[bg].g + add_g); - //int out_b = std::min(31,(palette[bg].b>>1) + add_b); + //int out_r = MIN(31,(palette[bg].r>>1) + add_r); + //int out_g = MIN(63, palette[bg].g + add_g); + //int out_b = MIN(31,(palette[bg].b>>1) + add_b); int out_r, out_g, out_b; if (use_objpal == 0) { - out_r = std::min(31, (palette[bg].r >> 1) + add_r); - out_g = std::min(63, palette[bg].g + add_g); - out_b = std::min(31, (palette[bg].b >> 1) + add_b); + out_r = MIN(31, (palette[bg].r >> 1) + add_r); + out_g = MIN(63, palette[bg].g + add_g); + out_b = MIN(31, (palette[bg].b >> 1) + add_b); } else { - out_r = std::min(31, (objectivepal [bg].r >> 1) + add_r); - out_g = std::min(63, objectivepal [bg].g + add_g); - out_b = std::min(31, (objectivepal [bg].b >> 1) + add_b); + out_r = MIN(31, (objectivepal [bg].r >> 1) + add_r); + out_g = MIN(63, objectivepal [bg].g + add_g); + out_b = MIN(31, (objectivepal [bg].b >> 1) + add_b); } i = ((out_r << 11) | (out_g << 5) | out_b); unsigned char (*clutp) = clut; @@ -139,7 +147,7 @@ class Mix { return result; } - __forceinline static unsigned char MixColorMultiply(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { + static unsigned char MixColorMultiply(unsigned char fg, unsigned char bg, unsigned char alpha, int use_objpal = 0) { unsigned char rfg = cycle_remap [fg]; //Automatic remapping of palette slots. unsigned char rbg = cycle_remap [bg]; //Saves on typing elsewhere. AGSColor *palette = engine->GetPalette(); @@ -178,8 +186,8 @@ unsigned short root(unsigned short x); float FastSin(float x); float FastCos(float x); -#if defined(BUILTIN_PLUGINS) -} // namespace agspalrender -#endif +} // namespace AGSPalRender +} // namespace Plugins +} // namespace AGS3 -#endif \ No newline at end of file +#endif diff --git a/engines/ags/plugins/ags_pal_render/raycast.cpp b/engines/ags/plugins/ags_pal_render/raycast.cpp index 9ce5d5c3434e..8309081ee350 100644 --- a/engines/ags/plugins/ags_pal_render/raycast.cpp +++ b/engines/ags/plugins/ags_pal_render/raycast.cpp @@ -1,39 +1,31 @@ -/* -Copyright (c) 2004-2007, Lode Vandevenne - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "raycast.h" - -#include -#include -#include -#include -#include -#include -#include - -#if defined(BUILTIN_PLUGINS) -namespace agspalrender { -#endif +/* 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 "ags/lib/allegro.h" +#include "ags/plugins/ags_pal_render/raycast.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSPalRender { #define PI (3.1415926535f) @@ -163,7 +155,7 @@ int Ray_GetAmbientWeight() { } void Ray_SetAmbientLight(int value) { - ambientlight = std::min(255, std::max(0, value)); + ambientlight = MIN(255, MAX(0, value)); } void Ray_SetAmbientColor(int color, int amount) { @@ -202,31 +194,31 @@ void Ray_SetWallTextures(int id, int n, int s, int w, int e) { } void Ray_SetWallSolid(int id, int n, int s, int w, int e) { - wallData[id].solid [0] = std::max(0, std::min(n, 1)); - wallData[id].solid [1] = std::max(0, std::min(s, 1)); - wallData[id].solid [2] = std::max(0, std::min(w, 1)); - wallData[id].solid [3] = std::max(0, std::min(e, 1)); + wallData[id].solid [0] = MAX(0, MIN(n, 1)); + wallData[id].solid [1] = MAX(0, MIN(s, 1)); + wallData[id].solid [2] = MAX(0, MIN(w, 1)); + wallData[id].solid [3] = MAX(0, MIN(e, 1)); } void Ray_SetWallIgnoreLighting(int id, int n, int s, int w, int e) { - wallData[id].ignorelighting [0] = std::max(0, std::min(n, 1)); - wallData[id].ignorelighting [1] = std::max(0, std::min(s, 1)); - wallData[id].ignorelighting [2] = std::max(0, std::min(w, 1)); - wallData[id].ignorelighting [3] = std::max(0, std::min(e, 1)); + wallData[id].ignorelighting [0] = MAX(0, MIN(n, 1)); + wallData[id].ignorelighting [1] = MAX(0, MIN(s, 1)); + wallData[id].ignorelighting [2] = MAX(0, MIN(w, 1)); + wallData[id].ignorelighting [3] = MAX(0, MIN(e, 1)); } void Ray_SetWallAlpha(int id, int n, int s, int w, int e) { - wallData[id].alpha [0] = std::max(0, std::min(n, 255)); - wallData[id].alpha [1] = std::max(0, std::min(s, 255)); - wallData[id].alpha [2] = std::max(0, std::min(w, 255)); - wallData[id].alpha [3] = std::max(0, std::min(e, 255)); + wallData[id].alpha [0] = MAX(0, MIN(n, 255)); + wallData[id].alpha [1] = MAX(0, MIN(s, 255)); + wallData[id].alpha [2] = MAX(0, MIN(w, 255)); + wallData[id].alpha [3] = MAX(0, MIN(e, 255)); } void Ray_SetWallBlendType(int id, int n, int s, int w, int e) { - wallData[id].blendtype [0] = std::max(0, std::min(n, 10)); - wallData[id].blendtype [1] = std::max(0, std::min(s, 10)); - wallData[id].blendtype [2] = std::max(0, std::min(w, 10)); - wallData[id].blendtype [3] = std::max(0, std::min(e, 10)); + wallData[id].blendtype [0] = MAX(0, MIN(n, 10)); + wallData[id].blendtype [1] = MAX(0, MIN(s, 10)); + wallData[id].blendtype [2] = MAX(0, MIN(w, 10)); + wallData[id].blendtype [3] = MAX(0, MIN(e, 10)); } @@ -893,9 +885,9 @@ void Raycast_Render(int slot) { } if (do_ambient) { ambientpixels = true; - wall_light = std::max(wall_light, ambientlight); + wall_light = MAX(wall_light, ambientlight); } - wall_light = std::min(255, std::max(0, wall_light)); + wall_light = MIN(255, MAX(0, wall_light)); bool alphastripe = false; for (int y = drawStart; y < drawEnd; y++) { if (ZBuffer[x][y] > perpWallDist || ZBuffer[x][y] == 0) { //We can draw. @@ -1033,7 +1025,7 @@ void Raycast_Render(int slot) { if (cmapY < 0) cmapY = 0; if (heightMap[cmapX][cmapY] - 1 < 1) continue; int lighting = lightMap [cmapX][cmapY] << 5; - lighting = std::min(255, std::max(0, lighting)); + lighting = MIN(255, MAX(0, lighting)); floorTexX = int(currentFloorX * texWidth) % texWidth; floorTexY = int(currentFloorY * texHeight) % texHeight; int floorcolor = 0; @@ -1046,7 +1038,7 @@ void Raycast_Render(int slot) { floorcolor = texture[floorMap[cmapX][cmapY] - 1][texpos]; } else continue; if (ceilingcolor == 0) { - lighting = std::max(lighting, ambientlight); + lighting = MAX(lighting, ambientlight); ambientweight ++; } if (lighting < 255) { @@ -1081,7 +1073,7 @@ void Raycast_Render(int slot) { int cmapY = (int)currentFloorY % mapHeight; if (cmapY < 0) cmapY = 0; int lighting = lightMap [cmapX][cmapY] << 5; - lighting = std::min(255, std::max(0, lighting)); + lighting = MIN(255, MAX(0, lighting)); floorTexX = int(currentFloorX * texWidth) % texWidth; floorTexY = int(currentFloorY * texHeight) % texHeight; int floorcolor = 0; @@ -1093,7 +1085,7 @@ void Raycast_Render(int slot) { ceilingcolor = texture[ceilingMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX]; } if (ceilingcolor == 0) { - lighting = std::max(lighting, ambientlight); + lighting = MAX(lighting, ambientlight); ambientweight++; } if (lighting < 255) { @@ -1252,12 +1244,12 @@ void Raycast_Render(int slot) { int drawEndX = spriteWidth / 2 + spriteScreenX + hMoveScreen; if (drawEndX >= w) drawEndX = w - 1; int spr_light = lightMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] << 5; - spr_light = std::min(255, std::max(0, spr_light)); + spr_light = MIN(255, MAX(0, spr_light)); int floorTexX = int(sprite[spriteOrder[i]].x * texWidth) % texWidth; int floorTexY = int(sprite[spriteOrder[i]].y * texHeight) % texHeight; if (ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] == 0) { - spr_light = std::max(spr_light, ambientlight); - } else if (texture[ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] - 1][texWidth * floorTexY + floorTexX] == 0) spr_light = std::max(spr_light, ambientlight); + spr_light = MAX(spr_light, ambientlight); + } else if (texture[ceilingMap [(int)sprite[spriteOrder[i]].x][(int)sprite[spriteOrder[i]].y] - 1][texWidth * floorTexY + floorTexX] == 0) spr_light = MAX(spr_light, ambientlight); //loop through every vertical stripe of the sprite on screen @@ -1485,14 +1477,15 @@ void combSort(int *order, double *dist, int amount) { for (int i = 0; i < amount - gap; i++) { int j = i + gap; if (dist[i] < dist[j]) { - std::swap(dist[i], dist[j]); - std::swap(order[i], order[j]); + SWAP(dist[i], dist[j]); + SWAP(order[i], order[j]); swapped = true; } } } } -#if defined(BUILTIN_PLUGINS) -} // namespace agspalrender -#endif +} // namespace AGSBlend +} // namespace Plugins +} // namespace AGS3 + diff --git a/engines/ags/plugins/ags_pal_render/raycast.h b/engines/ags/plugins/ags_pal_render/raycast.h index 87f4c1ed6f6b..3e797a37e341 100644 --- a/engines/ags/plugins/ags_pal_render/raycast.h +++ b/engines/ags/plugins/ags_pal_render/raycast.h @@ -1,15 +1,37 @@ -#ifndef __PALGORITHMS_RAYCAST_H -#define __PALGORITHMS_RAYCAST_H - -#include "palrender.h" +/* 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 AGS_PLUGINS_AGS_PAL_RENDER_RAYCAST_H +#define AGS_PLUGINS_AGS_PAL_RENDER_RAYCAST_H + +#include "ags/plugins/ags_pal_render/pal_render.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSPalRender { #define mapWidth 64 #define mapHeight 64 -#if defined(BUILTIN_PLUGINS) -namespace agspalrender { -#endif - struct Sprite { double x; double y; @@ -182,8 +204,8 @@ int Ray_GetAmbientWeight(); int Ray_HasSeenTile(int x, int y); -#if defined(BUILTIN_PLUGINS) -} // namespace agspalrender -#endif +} // namespace AGSPalRender +} // namespace Plugins +} // namespace AGS3 -#endif \ No newline at end of file +#endif diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index f08ce59b96e0..74217cd2ee21 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -25,6 +25,7 @@ #include "ags/plugins/ags_blend/ags_blend.h" #include "ags/plugins/ags_creditz/ags_creditz.h" #include "ags/plugins/ags_flashlight/ags_flashlight.h" +#include "ags/plugins/ags_pal_render/ags_pal_render.h" #include "ags/ags.h" #include "ags/detection.h" #include "common/str.h" @@ -58,6 +59,9 @@ void *dlopen(const char *filename) { if (fname.equalsIgnoreCase("libAGSFlashlight.so")) return new AGSFlashlight::AGSFlashlight(); + if (fname.equalsIgnoreCase("libAGSPalRender.so")) + return new AGSPalRender::AGSPalRender(); + return nullptr; } From f944d6077dbf7d14378dba4ddaf47fd194a2a2e0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 17:53:40 -0800 Subject: [PATCH 173/215] AGS: Added AGSParallax plugin --- engines/ags/module.mk | 3 +- .../ags/plugins/ags_pal_render/raycast.cpp | 2 +- .../ags/plugins/ags_parallax/ags_parallax.cpp | 322 +++++++----------- .../ags/plugins/ags_parallax/ags_parallax.h | 87 ++++- 4 files changed, 201 insertions(+), 213 deletions(-) diff --git a/engines/ags/module.mk b/engines/ags/module.mk index fbfc1d23952e..295eab39011c 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -305,7 +305,8 @@ MODULE_OBJS = \ plugins/ags_creditz/ags_creditz.o \ plugins/ags_flashlight/ags_flashlight.o \ plugins/ags_pal_render/ags_pal_render.o \ - plugins/ags_pal_render/raycast.o + plugins/ags_pal_render/raycast.o \ + plugins/ags_parallax/ags_parallax.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/plugins/ags_pal_render/raycast.cpp b/engines/ags/plugins/ags_pal_render/raycast.cpp index 8309081ee350..fe26cfb8bbe7 100644 --- a/engines/ags/plugins/ags_pal_render/raycast.cpp +++ b/engines/ags/plugins/ags_pal_render/raycast.cpp @@ -1485,7 +1485,7 @@ void combSort(int *order, double *dist, int amount) { } } -} // namespace AGSBlend +} // namespace AGSPalRender } // namespace Plugins } // namespace AGS3 diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.cpp b/engines/ags/plugins/ags_parallax/ags_parallax.cpp index 05c32b94ddfc..c4575bf1cd91 100644 --- a/engines/ags/plugins/ags_parallax/ags_parallax.cpp +++ b/engines/ags/plugins/ags_parallax/ags_parallax.cpp @@ -1,108 +1,143 @@ -/* +/* 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 "ags/plugins/ags_parallax/ags_parallax.h" +#include "ags/shared/core/platform.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSParallax { -This is not the AGS Parallax plugin by Scorpiorus -but a workalike plugin created by JJS for the AGS engine ports. - -*/ - -#include "core/platform.h" - -#if AGS_PLATFORM_OS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#pragma warning(disable : 4244) -#endif - -#if !defined(BUILTIN_PLUGINS) -#define THIS_IS_THE_PLUGIN -#endif +const unsigned int Magic = 0xCAFE0000; +const unsigned int Version = 2; +const unsigned int SaveMagic = Magic + Version; -#include -#include -#include -#include +IAGSEngine *AGSParallax::_engine; +int AGSParallax::_screenWidth; +int AGSParallax::_screenHeight; +int AGSParallax::_screenColorDepth; +bool AGSParallax::_enabled; +Sprite AGSParallax::_sprites[MAX_SPRITES]; -#include "plugin/agsplugin.h" -#if defined(BUILTIN_PLUGINS) -namespace ags_parallax { -#endif +AGSParallax::AGSParallax() : DLL() { + _engine = nullptr; + _screenWidth = 320; + _screenHeight = 200; + _screenColorDepth = 32; + _enabled = false; -//#define DEBUG + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); + DLL_METHOD(AGS_EngineOnEvent); +} -const unsigned int Magic = 0xCAFE0000; -const unsigned int Version = 2; -const unsigned int SaveMagic = Magic + Version; +const char *AGSParallax::AGS_GetPluginName() { + return "Parallax plugin recreation"; +} -int screen_width = 320; -int screen_height = 200; -int screen_color_depth = 32; +void AGSParallax::AGS_EngineStartup(IAGSEngine *engine) { + _engine = engine; -IAGSEngine *engine; + if (_engine->version < 13) + _engine->AbortGame("Engine interface is too old, need newer version of AGS."); -bool enabled = false; + SCRIPT_METHOD("pxDrawSprite"); + SCRIPT_METHOD("pxDeleteSprite"); + _engine->RequestEventHook(AGSE_PREGUIDRAW); + _engine->RequestEventHook(AGSE_PRESCREENDRAW); + _engine->RequestEventHook(AGSE_ENTERROOM); + _engine->RequestEventHook(AGSE_SAVEGAME); + _engine->RequestEventHook(AGSE_RESTOREGAME); -typedef struct { - int x; - int y; - int slot; - int speed; -} sprite_t; + Initialize(); +} -#define MAX_SPEED 1000 -#define MAX_SPRITES 100 -sprite_t sprites[MAX_SPRITES]; +int AGSParallax::AGS_EngineOnEvent(int event, int data) { + if (event == AGSE_PREGUIDRAW) { + Draw(true); + } else if (event == AGSE_PRESCREENDRAW) { + Draw(false); + } else if (event == AGSE_ENTERROOM) { + // Reset all _sprites + Initialize(); + } else if (event == AGSE_PRESCREENDRAW) { + // Get screen size once here + _engine->GetScreenDimensions(&_screenWidth, &_screenHeight, &_screenColorDepth); + _engine->UnrequestEventHook(AGSE_PRESCREENDRAW); + } else if (event == AGSE_RESTOREGAME) { + RestoreGame(data); + } else if (event == AGSE_SAVEGAME) { + SaveGame(data); + } -// workaround to fix this error: -// psp-fixup-imports ags_parallax.elf -// Error, no .lib.stub section found -void dummy() { - void *tmp = new int; + return 0; } -static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = engine->FRead(ptr, size * count, fileHandle); +size_t AGSParallax::engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = _engine->FRead(ptr, size * count, fileHandle); return totalBytes / size; } -static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = engine->FWrite(const_cast(ptr), size * count, fileHandle); +size_t AGSParallax::engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = _engine->FWrite(const_cast(ptr), size * count, fileHandle); return totalBytes / size; } -void RestoreGame(long fileHandle) { +void AGSParallax::RestoreGame(long fileHandle) { unsigned int SaveVersion = 0; engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, fileHandle); if (SaveVersion != SaveMagic) { - engine->AbortGame("ags_parallax: bad save."); + _engine->AbortGame("ags_parallax: bad save."); } - engineFileRead(sprites, sizeof(sprite_t), MAX_SPRITES, fileHandle); - engineFileRead(&enabled, sizeof(bool), 1, fileHandle); + // TODO: This seems endian/packing unsafe + engineFileRead(_sprites, sizeof(Sprite), MAX_SPRITES, fileHandle); + engineFileRead(&_enabled, sizeof(bool), 1, fileHandle); } -void SaveGame(long file) { +void AGSParallax::SaveGame(long file) { + warning("TODO: AGSParallax::SaveGame is endian unsafe"); engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); - engineFileWrite(sprites, sizeof(sprite_t), MAX_SPRITES, file); - engineFileWrite(&enabled, sizeof(bool), 1, file); + engineFileWrite(_sprites, sizeof(Sprite), MAX_SPRITES, file); + engineFileWrite(&_enabled, sizeof(bool), 1, file); } -void Initialize() { - memset(sprites, 0, sizeof(sprite_t) * MAX_SPRITES); +void AGSParallax::Initialize() { + memset(_sprites, 0, sizeof(Sprite) * MAX_SPRITES); int i; for (i = 0; i < MAX_SPRITES; i++) - sprites[i].slot = -1; + _sprites[i].slot = -1; - enabled = false; + _enabled = false; } -void Draw(bool foreground) { - if (!enabled) +void AGSParallax::Draw(bool foreground) { + if (!_enabled) return; BITMAP *bmp; @@ -110,21 +145,21 @@ void Draw(bool foreground) { int offsetX = 0; int offsetY = 0; - engine->ViewportToRoom(&offsetX, &offsetY); + _engine->ViewportToRoom(&offsetX, &offsetY); for (i = 0; i < MAX_SPRITES; i++) { - if (sprites[i].slot > -1) { + if (_sprites[i].slot > -1) { if (foreground) { - if (sprites[i].speed > 0) { - bmp = engine->GetSpriteGraphic(sprites[i].slot); + if (_sprites[i].speed > 0) { + bmp = _engine->GetSpriteGraphic(_sprites[i].slot); if (bmp) - engine->BlitBitmap(sprites[i].x - offsetX - (sprites[i].speed * offsetX / 100), sprites[i].y, bmp, 1); + _engine->BlitBitmap(_sprites[i].x - offsetX - (_sprites[i].speed * offsetX / 100), _sprites[i].y, bmp, 1); } } else { - if (sprites[i].speed <= 0) { - bmp = engine->GetSpriteGraphic(sprites[i].slot); + if (_sprites[i].speed <= 0) { + bmp = _engine->GetSpriteGraphic(_sprites[i].slot); if (bmp) - engine->BlitBitmap(sprites[i].x - offsetX - (sprites[i].speed * offsetX / 1000), sprites[i].y, bmp, 1); + _engine->BlitBitmap(_sprites[i].x - offsetX - (_sprites[i].speed * offsetX / 1000), _sprites[i].y, bmp, 1); } } } @@ -132,18 +167,11 @@ void Draw(bool foreground) { } - - - -// ******************************************** -// ************ AGS Interface *************** -// ******************************************** - -void pxDrawSprite(int id, int x, int y, int slot, int speed) { +void AGSParallax::pxDrawSprite(int id, int x, int y, int slot, int speed) { #ifdef DEBUG char buffer[200]; sprintf(buffer, "%s %d %d %d %d %d\n", "pxDrawSprite", id, x, y, slot, speed); - engine->PrintDebugConsole(buffer); + _engine->PrintDebugConsole(buffer); #endif if ((id < 0) || (id >= MAX_SPRITES)) @@ -152,136 +180,30 @@ void pxDrawSprite(int id, int x, int y, int slot, int speed) { if ((speed < -MAX_SPEED) || (speed > MAX_SPEED)) speed = 0; - sprites[id].x = x; - sprites[id].y = y; - sprites[id].slot = slot; - sprites[id].speed = speed; + _sprites[id].x = x; + _sprites[id].y = y; + _sprites[id].slot = slot; + _sprites[id].speed = speed; - engine->RoomToViewport(&sprites[id].x, &sprites[id].y); + _engine->RoomToViewport(&_sprites[id].x, &_sprites[id].y); - enabled = true; + _enabled = true; } -void pxDeleteSprite(int id) { +void AGSParallax::pxDeleteSprite(int id) { #ifdef DEBUG char buffer[200]; sprintf(buffer, "%s %d\n", "pxDeleteSprite", id); - engine->PrintDebugConsole(buffer); + _engine->PrintDebugConsole(buffer); #endif if ((id < 0) || (id >= MAX_SPRITES)) return; - sprites[id].slot = -1; -} - -void AGS_EngineStartup(IAGSEngine *lpEngine) { - engine = lpEngine; - - if (engine->version < 13) - engine->AbortGame("Engine interface is too old, need newer version of AGS."); - - engine->RegisterScriptFunction("pxDrawSprite", (void *)&pxDrawSprite); - engine->RegisterScriptFunction("pxDeleteSprite", (void *)&pxDeleteSprite); - - engine->RequestEventHook(AGSE_PREGUIDRAW); - engine->RequestEventHook(AGSE_PRESCREENDRAW); - engine->RequestEventHook(AGSE_ENTERROOM); - engine->RequestEventHook(AGSE_SAVEGAME); - engine->RequestEventHook(AGSE_RESTOREGAME); - - Initialize(); -} - -void AGS_EngineShutdown() { -} - -int AGS_EngineOnEvent(int event, int data) { - if (event == AGSE_PREGUIDRAW) { - Draw(true); - } else if (event == AGSE_PRESCREENDRAW) { - Draw(false); - } else if (event == AGSE_ENTERROOM) { - // Reset all sprites - Initialize(); - } else if (event == AGSE_PRESCREENDRAW) { - // Get screen size once here - engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); - engine->UnrequestEventHook(AGSE_PRESCREENDRAW); - } else if (event == AGSE_RESTOREGAME) { - RestoreGame(data); - } else if (event == AGSE_SAVEGAME) { - SaveGame(data); - } - - return 0; -} - -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { - return 0; -} - -void AGS_EngineInitGfx(const char *driverID, void *data) { -} - - - -#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) - -// ******************************************** -// *********** Editor Interface ************* -// ******************************************** - -const char *scriptHeader = - "import void pxDrawSprite(int ID, int X, int Y, int SlotNum, int Speed);\r\n" - "import void pxDeleteSprite(int ID);\r\n"; - -IAGSEditor *editor; - - -LPCSTR AGS_GetPluginName(void) { - // Return the plugin description - return "Parallax plugin recreation"; -} - -int AGS_EditorStartup(IAGSEditor *lpEditor) { - // User has checked the plugin to use it in their game - - // If it's an earlier version than what we need, abort. - if (lpEditor->version < 1) - return -1; - - editor = lpEditor; - editor->RegisterScriptHeader(scriptHeader); - - // Return 0 to indicate success - return 0; -} - -void AGS_EditorShutdown() { - // User has un-checked the plugin from their game - editor->UnregisterScriptHeader(scriptHeader); -} - -void AGS_EditorProperties(HWND parent) { - // User has chosen to view the Properties of the plugin - // We could load up an options dialog or something here instead - MessageBoxA(parent, "Parallax plugin recreation by JJS", "About", MB_OK | MB_ICONINFORMATION); -} - -int AGS_EditorSaveGame(char *buffer, int bufsize) { - // We don't want to save any persistent data - return 0; + _sprites[id].slot = -1; } -void AGS_EditorLoadGame(char *buffer, int bufsize) { - // Nothing to load for this plugin -} - -#endif - - -#if defined(BUILTIN_PLUGINS) -} // namespace ags_parallax -#endif +} // namespace AGSParallax +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.h b/engines/ags/plugins/ags_parallax/ags_parallax.h index c58126f149dc..74d17089cec3 100644 --- a/engines/ags/plugins/ags_parallax/ags_parallax.h +++ b/engines/ags/plugins/ags_parallax/ags_parallax.h @@ -1,14 +1,79 @@ -#ifndef AGS_PARALLAX_H -#define AGS_PARALLAX_H +/* 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 "plugin/agsplugin.h" +#ifndef AGS_PLUGINS_AGS_PARALLAX_AGS_PARALLAX_H +#define AGS_PLUGINS_AGS_PARALLAX_AGS_PARALLAX_H -namespace ags_parallax { -void AGS_EngineStartup(IAGSEngine *lpEngine); -void AGS_EngineShutdown(); -int AGS_EngineOnEvent(int event, int data); -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); -void AGS_EngineInitGfx(const char *driverID, void *data); -} +#include "ags/plugins/dll.h" -#endif \ No newline at end of file +namespace AGS3 { +namespace Plugins { +namespace AGSParallax { + +struct Sprite { + int x; + int y; + int slot; + int speed; +}; + +#define MAX_SPEED 1000 +#define MAX_SPRITES 100 + +/** + * This is not the AGS Parallax plugin by Scorpiorus + * but a workalike plugin created for the AGS engine ports. + */ +class AGSParallax : public DLL { +private: + static IAGSEngine *_engine; + static int _screenWidth; + static int _screenHeight; + static int _screenColorDepth; + + static bool _enabled; + static Sprite _sprites[MAX_SPRITES]; +private: + static const char *AGS_GetPluginName(); + static void AGS_EngineStartup(IAGSEngine *lpEngine); + static int AGS_EngineOnEvent(int event, int data); + + static void pxDrawSprite(int id, int x, int y, int slot, int speed); + static void pxDeleteSprite(int id); + +private: + static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle); + static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle); + static void RestoreGame(long fileHandle); + static void SaveGame(long file); + static void Initialize(); + static void Draw(bool foreground); + +public: + AGSParallax(); +}; + +} // namespace AGSParallax +} // namespace Plugins +} // namespace AGS3 + +#endif From df8ef24b0bd6c25c9c1474c71fc5d19d1c41f763 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 18:19:36 -0800 Subject: [PATCH 174/215] AGS: Make AGSParallax plugin endian safe --- .../ags/plugins/ags_parallax/ags_parallax.cpp | 78 ++++++++++++------- .../ags/plugins/ags_parallax/ags_parallax.h | 17 ++-- 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.cpp b/engines/ags/plugins/ags_parallax/ags_parallax.cpp index c4575bf1cd91..a07e7382fe27 100644 --- a/engines/ags/plugins/ags_parallax/ags_parallax.cpp +++ b/engines/ags/plugins/ags_parallax/ags_parallax.cpp @@ -22,6 +22,7 @@ #include "ags/plugins/ags_parallax/ags_parallax.h" #include "ags/shared/core/platform.h" +#include "common/endian.h" namespace AGS3 { namespace Plugins { @@ -69,8 +70,6 @@ void AGSParallax::AGS_EngineStartup(IAGSEngine *engine) { _engine->RequestEventHook(AGSE_ENTERROOM); _engine->RequestEventHook(AGSE_SAVEGAME); _engine->RequestEventHook(AGSE_RESTOREGAME); - - Initialize(); } int AGSParallax::AGS_EngineOnEvent(int event, int data) { @@ -80,7 +79,7 @@ int AGSParallax::AGS_EngineOnEvent(int event, int data) { Draw(false); } else if (event == AGSE_ENTERROOM) { // Reset all _sprites - Initialize(); + clear(); } else if (event == AGSE_PRESCREENDRAW) { // Get screen size once here _engine->GetScreenDimensions(&_screenWidth, &_screenHeight, &_screenColorDepth); @@ -94,6 +93,15 @@ int AGSParallax::AGS_EngineOnEvent(int event, int data) { return 0; } +void AGSParallax::clear() { + for (int i = 0; i < MAX_SPRITES; i++) { + _sprites[i] = Sprite(); + _sprites[i].slot = -1; + } + + _enabled = false; +} + size_t AGSParallax::engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { auto totalBytes = _engine->FRead(ptr, size * count, fileHandle); return totalBytes / size; @@ -104,38 +112,29 @@ size_t AGSParallax::engineFileWrite(const void *ptr, size_t size, size_t count, return totalBytes / size; } -void AGSParallax::RestoreGame(long fileHandle) { - unsigned int SaveVersion = 0; - engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, fileHandle); +void AGSParallax::RestoreGame(long file) { + byte saveVersion[4]; + engineFileRead(&saveVersion, 4, 1, file); - if (SaveVersion != SaveMagic) { + if (READ_LE_UINT32(saveVersion) != SaveMagic) { _engine->AbortGame("ags_parallax: bad save."); } - // TODO: This seems endian/packing unsafe - engineFileRead(_sprites, sizeof(Sprite), MAX_SPRITES, fileHandle); - engineFileRead(&_enabled, sizeof(bool), 1, fileHandle); + for (int i = 0; i < MAX_SPRITES; ++i) + _sprites[i].load(_engine, file); + engineFileRead(&_enabled, sizeof(bool), 1, file); } void AGSParallax::SaveGame(long file) { - warning("TODO: AGSParallax::SaveGame is endian unsafe"); - engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); - engineFileWrite(_sprites, sizeof(Sprite), MAX_SPRITES, file); - engineFileWrite(&_enabled, sizeof(bool), 1, file); -} - - -void AGSParallax::Initialize() { - memset(_sprites, 0, sizeof(Sprite) * MAX_SPRITES); - - int i; - for (i = 0; i < MAX_SPRITES; i++) - _sprites[i].slot = -1; + byte saveVersion[4]; + WRITE_LE_UINT32(saveVersion, SaveMagic); + engineFileWrite(&SaveMagic, 4, 1, file); - _enabled = false; + for (int i = 0; i < MAX_SPRITES; ++i) + _sprites[i].save(_engine, file); + engineFileWrite(&_enabled, 1, 1, file); } - void AGSParallax::Draw(bool foreground) { if (!_enabled) return; @@ -166,7 +165,6 @@ void AGSParallax::Draw(bool foreground) { } } - void AGSParallax::pxDrawSprite(int id, int x, int y, int slot, int speed) { #ifdef DEBUG char buffer[200]; @@ -204,6 +202,34 @@ void AGSParallax::pxDeleteSprite(int id) { _sprites[id].slot = -1; } +/*------------------------------------------------------------------*/ + +void Sprite::save(IAGSEngine *engine, long file) { + saveInt(engine, file, x); + saveInt(engine, file, y); + saveInt(engine, file, slot); + saveInt(engine, file, speed); +} + +void Sprite::load(IAGSEngine *engine, long file) { + x = loadInt(engine, file); + y = loadInt(engine, file); + slot = loadInt(engine, file); + speed = loadInt(engine, file); +} + +void saveInt(IAGSEngine *engine, long file, int value) { + byte buf[4]; + WRITE_LE_INT32(buf, value); + engine->FWrite(buf, 4, file); +} + +int loadInt(IAGSEngine *engine, long file) { + byte buf[4]; + engine->FRead(buf, 4, file); + return READ_LE_INT32(buf); +} + } // namespace AGSParallax } // namespace Plugins } // namespace AGS3 diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.h b/engines/ags/plugins/ags_parallax/ags_parallax.h index 74d17089cec3..2d441e38e07a 100644 --- a/engines/ags/plugins/ags_parallax/ags_parallax.h +++ b/engines/ags/plugins/ags_parallax/ags_parallax.h @@ -30,10 +30,15 @@ namespace Plugins { namespace AGSParallax { struct Sprite { - int x; - int y; - int slot; - int speed; + int x = 0; + int y = 0; + int slot = -1; + int speed = 0; + + void save(IAGSEngine *engine, long file); + void load(IAGSEngine *engine, long file); + void saveInt(IAGSEngine *engine, long file, int value); + int loadInt(IAGSEngine *engine, long file); }; #define MAX_SPEED 1000 @@ -63,10 +68,10 @@ class AGSParallax : public DLL { private: static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle); static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle); - static void RestoreGame(long fileHandle); + static void RestoreGame(long file); static void SaveGame(long file); - static void Initialize(); static void Draw(bool foreground); + static void clear(); public: AGSParallax(); From 0cf6825262fa97f44d8258a13418b75122fdfdd8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 18:51:21 -0800 Subject: [PATCH 175/215] AGS: Added AGSSnowRain plugin --- engines/ags/module.mk | 4 +- .../plugins/ags_snow_rain/ags_snow_rain.cpp | 935 +++--------------- .../ags/plugins/ags_snow_rain/ags_snow_rain.h | 91 +- engines/ags/plugins/ags_snow_rain/weather.cpp | 463 +++++++++ engines/ags/plugins/ags_snow_rain/weather.h | 120 +++ engines/ags/plugins/dll.cpp | 4 + 6 files changed, 826 insertions(+), 791 deletions(-) create mode 100644 engines/ags/plugins/ags_snow_rain/weather.cpp create mode 100644 engines/ags/plugins/ags_snow_rain/weather.h diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 295eab39011c..72899f2818fc 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -306,7 +306,9 @@ MODULE_OBJS = \ plugins/ags_flashlight/ags_flashlight.o \ plugins/ags_pal_render/ags_pal_render.o \ plugins/ags_pal_render/raycast.o \ - plugins/ags_parallax/ags_parallax.o + plugins/ags_parallax/ags_parallax.o \ + plugins/ags_snow_rain/ags_snow_rain.o \ + plugins/ags_snow_rain/weather.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp index bc61dc26be25..051a0ed63b13 100644 --- a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp +++ b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp @@ -1,841 +1,218 @@ -/* - -This is not the AGS SnowRain plugin by Scorpiorus (http://www.bigbluecup.com/yabb/index.php?topic=25665.0), -but a workalike plugin created by JJS for the AGS engine PSP port. - -*/ - -#include "core/platform.h" - -#if AGS_PLATFORM_OS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#pragma warning(disable : 4244) -#endif - -#if !defined(BUILTIN_PLUGINS) -#define THIS_IS_THE_PLUGIN -#endif - -#include -#include -#include -#include - -#ifdef PSP_VERSION -#include -#include -#define sin(x) vfpu_sinf(x) -#endif - -#include "plugin/agsplugin.h" - -#if defined(BUILTIN_PLUGINS) -namespace ags_snowrain { -#endif - -//#define DEBUG -//#define AGS_SNOWRAIN_DLL_SAVEGAME_COMPATIBILITY - -#define signum(x) ((x > 0) ? 1 : -1) - -const unsigned int Magic = 0xCAFE0000; -const unsigned int Version = 2; -const unsigned int SaveMagic = Magic + Version; -const float PI = 3.14159265f; - -int screen_width = 320; -int screen_height = 200; -int screen_color_depth = 32; - -IAGSEngine *engine; - - -typedef struct { - int view; - int loop; - bool is_default; - BITMAP *bitmap; -} view_t; - - -typedef struct { - float x; - float y; - int alpha; - float speed; - int max_y; - int kind_id; - int drift; - float drift_speed; - float drift_offset; -} drop_t; - - -class Weather { -public: - Weather(); - Weather(bool IsSnow); - ~Weather(); - - void Initialize(); - void InitializeParticles(); - - void RestoreGame(long file); - void SaveGame(long file); - bool ReinitializeViews(); - - bool IsActive(); - void Update(); - void UpdateWithDrift(); - void EnterRoom(); - - void SetDriftRange(int min_value, int max_value); - void SetDriftSpeed(int min_value, int max_value); - void ChangeAmount(int amount); - void SetView(int kind_id, int event, int view, int loop); - void SetDefaultView(int view, int loop); - void SetTransparency(int min_value, int max_value); - void SetWindSpeed(int value); - void SetBaseline(int top, int bottom); - void SetAmount(int amount); - void SetFallSpeed(int min_value, int max_value); - -private: - void ClipToRange(int &variable, int min, int max); - - bool mIsSnow; - - int mMinDrift; - int mMaxDrift; - int mDeltaDrift; - - int mMinDriftSpeed; - int mMaxDriftSpeed; - int mDeltaDriftSpeed; - - int mAmount; - int mTargetAmount; - - int mMinAlpha; - int mMaxAlpha; - int mDeltaAlpha; - - float mWindSpeed; - - int mTopBaseline; - int mBottomBaseline; - int mDeltaBaseline; - - int mMinFallSpeed; - int mMaxFallSpeed; - int mDeltaFallSpeed; - - drop_t mParticles[2000]; - view_t mViews[5]; - - bool mViewsInitialized; -}; - - -Weather::Weather() { - mIsSnow = false; - Initialize(); -} - - -Weather::Weather(bool IsSnow) { - mIsSnow = IsSnow; - Initialize(); -} - - -Weather::~Weather() = default; - - -void Weather::Update() { - if (mTargetAmount > mAmount) - mAmount++; - else if (mTargetAmount < mAmount) - mAmount--; - - if (!ReinitializeViews()) - return; - - int i; - for (i = 0; i < mAmount * 2; i++) { - mParticles[i].y += mParticles[i].speed; - mParticles[i].x += mWindSpeed; - - if (mParticles[i].x < 0) - mParticles[i].x += screen_width; - - if (mParticles[i].x > screen_width - 1) - mParticles[i].x -= screen_width; - - if (mParticles[i].y > mParticles[i].max_y) { - mParticles[i].y = -1 * (rand() % screen_height); - mParticles[i].x = rand() % screen_width; - mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; - mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; - mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline; - } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) - engine->BlitSpriteTranslucent(mParticles[i].x, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); - } - - engine->MarkRegionDirty(0, 0, screen_width, screen_height); -} - - -void Weather::UpdateWithDrift() { - if (mTargetAmount > mAmount) - mAmount++; - else if (mTargetAmount < mAmount) - mAmount--; - - if (!ReinitializeViews()) - return; - - int i, drift; - for (i = 0; i < mAmount * 2; i++) { - mParticles[i].y += mParticles[i].speed; - drift = mParticles[i].drift * sin((float)(mParticles[i].y + mParticles[i].drift_offset) * mParticles[i].drift_speed * 2.0f * PI / 360.0f); - - if (signum(mWindSpeed) == signum(drift)) - mParticles[i].x += mWindSpeed; - else - mParticles[i].x += mWindSpeed / 4; - - if (mParticles[i].x < 0) - mParticles[i].x += screen_width; - - if (mParticles[i].x > screen_width - 1) - mParticles[i].x -= screen_width; - - if (mParticles[i].y > mParticles[i].max_y) { - mParticles[i].y = -1 * (rand() % screen_height); - mParticles[i].x = rand() % screen_width; - mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; - mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; - mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline; - mParticles[i].drift = rand() % mDeltaDrift + mMinDrift; - mParticles[i].drift_speed = (rand() % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; - } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) - engine->BlitSpriteTranslucent(mParticles[i].x + drift, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); - } - - engine->MarkRegionDirty(0, 0, screen_width, screen_height); -} - -static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = engine->FRead(ptr, size * count, fileHandle); - return totalBytes / size; -} - -static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = engine->FWrite(const_cast(ptr), size * count, fileHandle); - return totalBytes / size; -} - -void Weather::RestoreGame(long file) { - unsigned int SaveVersion = 0; - engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, file); - - if (SaveVersion != SaveMagic) { - engine->AbortGame("ags_snowrain: bad save."); - } - - // Current version - engineFileRead(&mIsSnow, 4, 1, file); - engineFileRead(&mMinDrift, 4, 1, file); - engineFileRead(&mMaxDrift, 4, 1, file); - engineFileRead(&mDeltaDrift, 4, 1, file); - engineFileRead(&mMinDriftSpeed, 4, 1, file); - engineFileRead(&mMaxDriftSpeed, 4, 1, file); - engineFileRead(&mDeltaDriftSpeed, 4, 1, file); - engineFileRead(&mAmount, 4, 1, file); - engineFileRead(&mTargetAmount, 4, 1, file); - engineFileRead(&mMinAlpha, 4, 1, file); - engineFileRead(&mMaxAlpha, 4, 1, file); - engineFileRead(&mDeltaAlpha, 4, 1, file); - engineFileRead(&mWindSpeed, 4, 1, file); - engineFileRead(&mTopBaseline, 4, 1, file); - engineFileRead(&mBottomBaseline, 4, 1, file); - engineFileRead(&mDeltaBaseline, 4, 1, file); - engineFileRead(&mMinFallSpeed, 4, 1, file); - engineFileRead(&mMaxFallSpeed, 4, 1, file); - engineFileRead(&mDeltaFallSpeed, 4, 1, file); - engineFileRead(mViews, sizeof(view_t) * 5, 1, file); - - InitializeParticles(); -} - - -void Weather::SaveGame(long file) { - engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); - - engineFileWrite(&mIsSnow, 4, 1, file); - engineFileWrite(&mMinDrift, 4, 1, file); - engineFileWrite(&mMaxDrift, 4, 1, file); - engineFileWrite(&mDeltaDrift, 4, 1, file); - engineFileWrite(&mMinDriftSpeed, 4, 1, file); - engineFileWrite(&mMaxDriftSpeed, 4, 1, file); - engineFileWrite(&mDeltaDriftSpeed, 4, 1, file); - engineFileWrite(&mAmount, 4, 1, file); - engineFileWrite(&mTargetAmount, 4, 1, file); - engineFileWrite(&mMinAlpha, 4, 1, file); - engineFileWrite(&mMaxAlpha, 4, 1, file); - engineFileWrite(&mDeltaAlpha, 4, 1, file); - engineFileWrite(&mWindSpeed, 4, 1, file); - engineFileWrite(&mTopBaseline, 4, 1, file); - engineFileWrite(&mBottomBaseline, 4, 1, file); - engineFileWrite(&mDeltaBaseline, 4, 1, file); - engineFileWrite(&mMinFallSpeed, 4, 1, file); - engineFileWrite(&mMaxFallSpeed, 4, 1, file); - engineFileWrite(&mDeltaFallSpeed, 4, 1, file); - engineFileWrite(mViews, sizeof(view_t) * 5, 1, file); -} - - -bool Weather::ReinitializeViews() { - if ((mViews[4].view == -1) || (mViews[4].loop == -1)) - return false; - - AGSViewFrame *view_frame = engine->GetViewFrame(mViews[4].view, mViews[4].loop, 0); - BITMAP *default_bitmap = engine->GetSpriteGraphic(view_frame->pic); - - int i; - for (i = 0; i < 5; i++) { - if (mViews[i].bitmap != nullptr) { - if (mViews[i].is_default) - mViews[i].bitmap = default_bitmap; - else { - view_frame = engine->GetViewFrame(mViews[i].view, mViews[i].loop, 0); - mViews[i].bitmap = engine->GetSpriteGraphic(view_frame->pic); - } - } - } - - return true; -} - - -bool Weather::IsActive() { - return (mAmount > 0) || (mTargetAmount != mAmount); -} - - -void Weather::EnterRoom() { - mAmount = mTargetAmount; -} - - -void Weather::ClipToRange(int &variable, int min, int max) { - if (variable < min) - variable = min; - - if (variable > max) - variable = max; -} - - -void Weather::Initialize() { - SetDriftRange(10, 100); - SetDriftSpeed(10, 120); - - SetTransparency(0, 0); - SetWindSpeed(0); - SetBaseline(0, 200); - - if (mIsSnow) - SetFallSpeed(10, 70); - else - SetFallSpeed(100, 300); - - mViewsInitialized = false; - - int i; - for (i = 0; i < 5; i++) { - mViews[i].is_default = true; - mViews[i].view = -1; - mViews[i].loop = -1; - mViews[i].bitmap = nullptr; - } - - SetAmount(0); -} - - -void Weather::InitializeParticles() { - memset(mParticles, 0, sizeof(drop_t) * 2000); - int i; - for (i = 0; i < 2000; i++) { - mParticles[i].kind_id = rand() % 5; - mParticles[i].y = rand() % (screen_height * 2) - screen_height; - mParticles[i].x = rand() % screen_width; - mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; - mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; - mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline; - mParticles[i].drift = rand() % mDeltaDrift + mMinDrift; - mParticles[i].drift_speed = (rand() % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; - mParticles[i].drift_offset = rand() % 100; - } -} - - -void Weather::SetDriftRange(int min_value, int max_value) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftRange", min_value, max_value); - engine->PrintDebugConsole(buffer); -#endif - - ClipToRange(min_value, 0, 100); - ClipToRange(max_value, 0, 100); - - if (min_value > max_value) - min_value = max_value; - - mMinDrift = min_value / 2; - mMaxDrift = max_value / 2; - mDeltaDrift = mMaxDrift - mMinDrift; - - if (mDeltaDrift == 0) - mDeltaDrift = 1; -} - - -void Weather::SetDriftSpeed(int min_value, int max_value) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftSpeed", min_value, max_value); - engine->PrintDebugConsole(buffer); -#endif - - ClipToRange(min_value, 0, 200); - ClipToRange(max_value, 0, 200); - - if (min_value > max_value) - min_value = max_value; - - mMinDriftSpeed = min_value; - mMaxDriftSpeed = max_value; - mDeltaDriftSpeed = mMaxDriftSpeed - mMinDriftSpeed; - - if (mDeltaDriftSpeed == 0) - mDeltaDriftSpeed = 1; -} - - -void Weather::ChangeAmount(int amount) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "ChangeAmount", amount); - engine->PrintDebugConsole(buffer); -#endif - - ClipToRange(amount, 0, 1000); - - mTargetAmount = amount; -} - - -void Weather::SetView(int kind_id, int event, int view, int loop) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d %d %d %d\n", (int)mIsSnow, "SetView", kind_id, event, view, loop); - engine->PrintDebugConsole(buffer); -#endif - - AGSViewFrame *view_frame = engine->GetViewFrame(view, loop, 0); - mViews[kind_id].bitmap = engine->GetSpriteGraphic(view_frame->pic); - mViews[kind_id].is_default = false; - mViews[kind_id].view = view; - mViews[kind_id].loop = loop; - - if (!mViewsInitialized) - SetDefaultView(view, loop); -} - - -void Weather::SetDefaultView(int view, int loop) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDefaultView", view, loop); - engine->PrintDebugConsole(buffer); -#endif - - AGSViewFrame *view_frame = engine->GetViewFrame(view, loop, 0); - BITMAP *bitmap = engine->GetSpriteGraphic(view_frame->pic); - - mViewsInitialized = true; - - int i; - for (i = 0; i < 5; i++) { - if (mViews[i].is_default) { - mViews[i].view = view; - mViews[i].loop = loop; - mViews[i].bitmap = bitmap; - } - } +/* 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 "ags/plugins/ags_snow_rain/ags_snow_rain.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSnowRain { + +IAGSEngine *_engine; +int _screenWidth; +int _screenHeight; +int _screenColorDepth; + +Weather *AGSSnowRain::_rain; +Weather *AGSSnowRain::_snow; + +AGSSnowRain::AGSSnowRain() : DLL() { + _engine = nullptr; + _screenWidth = 320; + _screenHeight = 200; + _screenColorDepth = 32; + + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); + DLL_METHOD(AGS_EngineShutdown); + DLL_METHOD(AGS_EngineOnEvent); +} + +const char *AGSSnowRain::AGS_GetPluginName() { + // Return the plugin description + return "Snow/Rain plugin recreation"; } +void AGSSnowRain::AGS_EngineStartup(IAGSEngine *engine) { + _engine = engine; -void Weather::SetTransparency(int min_value, int max_value) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetTransparency", min_value, max_value); - engine->PrintDebugConsole(buffer); -#endif + if (_engine->version < 13) + _engine->AbortGame("Engine interface is too old, need newer version of AGS."); - ClipToRange(min_value, 0, 100); - ClipToRange(max_value, 0, 100); + SCRIPT_METHOD("srSetSnowDriftRange"); + SCRIPT_METHOD("srSetSnowDriftSpeed"); + SCRIPT_METHOD("srSetSnowFallSpeed"); + SCRIPT_METHOD("srChangeSnowAmount"); + SCRIPT_METHOD("srSetSnowBaseline"); + SCRIPT_METHOD("srSetSnowTransparency"); + SCRIPT_METHOD("srSetSnowDefaultView"); + SCRIPT_METHOD("srSetSnowWindSpeed"); + SCRIPT_METHOD("srSetSnowAmount"); + SCRIPT_METHOD("srSetSnowView"); - if (min_value > max_value) - min_value = max_value; + SCRIPT_METHOD("srSetRainDriftRange"); + SCRIPT_METHOD("srSetRainDriftSpeed"); + SCRIPT_METHOD("srSetRainFallSpeed"); + SCRIPT_METHOD("srChangeRainAmount"); + SCRIPT_METHOD("srSetRainBaseline"); + SCRIPT_METHOD("srSetRainTransparency"); + SCRIPT_METHOD("srSetRainDefaultView"); + SCRIPT_METHOD("srSetRainWindSpeed"); + SCRIPT_METHOD("srSetRainAmount"); + SCRIPT_METHOD("srSetRainView"); - mMinAlpha = 255 - floor((float)max_value * 2.55f + 0.5f); - mMaxAlpha = 255 - floor((float)min_value * 2.55f + 0.5f); - mDeltaAlpha = mMaxAlpha - mMinAlpha; + SCRIPT_METHOD("srSetWindSpeed"); + SCRIPT_METHOD("srSetBaseline"); - if (mDeltaAlpha == 0) - mDeltaAlpha = 1; + _engine->RequestEventHook(AGSE_PREGUIDRAW); + _engine->RequestEventHook(AGSE_PRESCREENDRAW); + _engine->RequestEventHook(AGSE_ENTERROOM); + _engine->RequestEventHook(AGSE_SAVEGAME); + _engine->RequestEventHook(AGSE_RESTOREGAME); - int i; - for (i = 0; i < 2000; i++) - mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha; + _rain = new Weather(); + _snow = new Weather(true); } - -void Weather::SetWindSpeed(int value) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetWindSpeed", value); - engine->PrintDebugConsole(buffer); -#endif - - ClipToRange(value, -200, 200); - - mWindSpeed = (float)value / 20.0f; +void AGSSnowRain::AGS_EngineShutdown() { + delete _rain; + delete _snow; } +int AGSSnowRain::AGS_EngineOnEvent(int event, int data) { + if (event == AGSE_PREGUIDRAW) { + if (_rain->IsActive()) + _rain->Update(); -void Weather::SetBaseline(int top, int bottom) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetBaseline", top, bottom); - engine->PrintDebugConsole(buffer); -#endif - - if (screen_height > 0) { - ClipToRange(top, 0, screen_height); - ClipToRange(bottom, 0, screen_height); + if (_snow->IsActive()) + _snow->UpdateWithDrift(); + } else if (event == AGSE_ENTERROOM) { + _rain->EnterRoom(); + _snow->EnterRoom(); + } else if (event == AGSE_RESTOREGAME) { + _rain->RestoreGame(data); + _snow->RestoreGame(data); + } else if (event == AGSE_SAVEGAME) { + _rain->SaveGame(data); + _snow->SaveGame(data); + } else if (event == AGSE_PRESCREENDRAW) { + // Get screen size once here + _engine->GetScreenDimensions(&_screenWidth, &_screenHeight , &_screenColorDepth); + _engine->UnrequestEventHook(AGSE_PRESCREENDRAW); } - if (top > bottom) - top = bottom; - - mTopBaseline = top; - mBottomBaseline = bottom; - mDeltaBaseline = mBottomBaseline - mTopBaseline; - - if (mDeltaBaseline == 0) - mDeltaBaseline = 1; -} - - -void Weather::SetAmount(int amount) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetAmount", amount); - engine->PrintDebugConsole(buffer); -#endif - - ClipToRange(amount, 0, 1000); - - mAmount = mTargetAmount = amount; - - InitializeParticles(); -} - - -void Weather::SetFallSpeed(int min_value, int max_value) { -#ifdef DEBUG - char buffer[200]; - sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetFallSpeed", min_value, max_value); - engine->PrintDebugConsole(buffer); -#endif - - ClipToRange(min_value, 0, 1000); - ClipToRange(max_value, 0, 1000); - - if (min_value > max_value) - min_value = max_value; - - mMinFallSpeed = min_value; - mMaxFallSpeed = max_value; - mDeltaFallSpeed = mMaxFallSpeed - mMinFallSpeed; - - if (mDeltaFallSpeed == 0) - mDeltaFallSpeed = 1; -} - - - -Weather *rain; -Weather *snow; - - - - -// ******************************************** -// ************ AGS Interface *************** -// ******************************************** - -void srSetWindSpeed(int value) { - snow->SetWindSpeed(value); - rain->SetWindSpeed(value); + return 0; } -void srSetBaseline(int top, int bottom) { - snow->SetBaseline(top, bottom); - rain->SetBaseline(top, bottom); -} -void srSetSnowDriftRange(int min_value, int max_value) { - snow->SetDriftRange(min_value, max_value); +void AGSSnowRain::srSetWindSpeed(int value) { + _snow->SetWindSpeed(value); + _rain->SetWindSpeed(value); } -void srSetSnowDriftSpeed(int min_value, int max_value) { - snow->SetDriftSpeed(min_value, max_value); +void AGSSnowRain::srSetBaseline(int top, int bottom) { + _snow->SetBaseline(top, bottom); + _rain->SetBaseline(top, bottom); } -void srChangeSnowAmount(int amount) { - snow->ChangeAmount(amount); +void AGSSnowRain::srSetSnowDriftRange(int min_value, int max_value) { + _snow->SetDriftRange(min_value, max_value); } -void srSetSnowView(int kind_id, int event, int view, int loop) { - snow->SetView(kind_id, event, view, loop); +void AGSSnowRain::srSetSnowDriftSpeed(int min_value, int max_value) { + _snow->SetDriftSpeed(min_value, max_value); } -void srSetSnowDefaultView(int view, int loop) { - snow->SetDefaultView(view, loop); +void AGSSnowRain::srChangeSnowAmount(int amount) { + _snow->ChangeAmount(amount); } -void srSetSnowTransparency(int min_value, int max_value) { - snow->SetTransparency(min_value, max_value); +void AGSSnowRain::srSetSnowView(int kind_id, int event, int view, int loop) { + _snow->SetView(kind_id, event, view, loop); } -void srSetSnowWindSpeed(int value) { - snow->SetWindSpeed(value); +void AGSSnowRain::srSetSnowDefaultView(int view, int loop) { + _snow->SetDefaultView(view, loop); } -void srSetSnowBaseline(int top, int bottom) { - snow->SetBaseline(top, bottom); +void AGSSnowRain::srSetSnowTransparency(int min_value, int max_value) { + _snow->SetTransparency(min_value, max_value); } -void srSetSnowAmount(int amount) { - snow->SetAmount(amount); +void AGSSnowRain::srSetSnowWindSpeed(int value) { + _snow->SetWindSpeed(value); } -void srSetSnowFallSpeed(int min_value, int max_value) { - snow->SetFallSpeed(min_value, max_value); +void AGSSnowRain::srSetSnowBaseline(int top, int bottom) { + _snow->SetBaseline(top, bottom); } -void srSetRainDriftRange(int min_value, int max_value) { - rain->SetDriftRange(min_value, max_value); +void AGSSnowRain::srSetSnowAmount(int amount) { + _snow->SetAmount(amount); } -void srSetRainDriftSpeed(int min_value, int max_value) { - rain->SetDriftSpeed(min_value, max_value); +void AGSSnowRain::srSetSnowFallSpeed(int min_value, int max_value) { + _snow->SetFallSpeed(min_value, max_value); } -void srChangeRainAmount(int amount) { - rain->ChangeAmount(amount); +void AGSSnowRain::srSetRainDriftRange(int min_value, int max_value) { + _rain->SetDriftRange(min_value, max_value); } -void srSetRainView(int kind_id, int event, int view, int loop) { - rain->SetView(kind_id, event, view, loop); +void AGSSnowRain::srSetRainDriftSpeed(int min_value, int max_value) { + _rain->SetDriftSpeed(min_value, max_value); } -void srSetRainDefaultView(int view, int loop) { - rain->SetDefaultView(view, loop); +void AGSSnowRain::srChangeRainAmount(int amount) { + _rain->ChangeAmount(amount); } -void srSetRainTransparency(int min_value, int max_value) { - rain->SetTransparency(min_value, max_value); +void AGSSnowRain::srSetRainView(int kind_id, int event, int view, int loop) { + _rain->SetView(kind_id, event, view, loop); } -void srSetRainWindSpeed(int value) { - rain->SetWindSpeed(value); +void AGSSnowRain::srSetRainDefaultView(int view, int loop) { + _rain->SetDefaultView(view, loop); } -void srSetRainBaseline(int top, int bottom) { - rain->SetBaseline(top, bottom); +void AGSSnowRain::srSetRainTransparency(int min_value, int max_value) { + _rain->SetTransparency(min_value, max_value); } -void srSetRainAmount(int amount) { - rain->SetAmount(amount); +void AGSSnowRain::srSetRainWindSpeed(int value) { + _rain->SetWindSpeed(value); } -void srSetRainFallSpeed(int min_value, int max_value) { - rain->SetFallSpeed(min_value, max_value); +void AGSSnowRain::srSetRainBaseline(int top, int bottom) { + _rain->SetBaseline(top, bottom); } -void AGS_EngineStartup(IAGSEngine *lpEngine) { - engine = lpEngine; - - if (engine->version < 13) - engine->AbortGame("Engine interface is too old, need newer version of AGS."); - - engine->RegisterScriptFunction("srSetSnowDriftRange", (void *)&srSetSnowDriftRange); - engine->RegisterScriptFunction("srSetSnowDriftSpeed", (void *)&srSetSnowDriftSpeed); - engine->RegisterScriptFunction("srSetSnowFallSpeed", (void *)&srSetSnowFallSpeed); - engine->RegisterScriptFunction("srChangeSnowAmount", (void *)&srChangeSnowAmount); - engine->RegisterScriptFunction("srSetSnowBaseline", (void *)&srSetSnowBaseline); - engine->RegisterScriptFunction("srSetSnowTransparency", (void *)&srSetSnowTransparency); - engine->RegisterScriptFunction("srSetSnowDefaultView", (void *)&srSetSnowDefaultView); - engine->RegisterScriptFunction("srSetSnowWindSpeed", (void *)&srSetSnowWindSpeed); - engine->RegisterScriptFunction("srSetSnowAmount", (void *)&srSetSnowAmount); - engine->RegisterScriptFunction("srSetSnowView", (void *)&srSetSnowView); - - engine->RegisterScriptFunction("srSetRainDriftRange", (void *)&srSetRainDriftRange); - engine->RegisterScriptFunction("srSetRainDriftSpeed", (void *)&srSetRainDriftSpeed); - engine->RegisterScriptFunction("srSetRainFallSpeed", (void *)&srSetRainFallSpeed); - engine->RegisterScriptFunction("srChangeRainAmount", (void *)&srChangeRainAmount); - engine->RegisterScriptFunction("srSetRainBaseline", (void *)&srSetRainBaseline); - engine->RegisterScriptFunction("srSetRainTransparency", (void *)&srSetRainTransparency); - engine->RegisterScriptFunction("srSetRainDefaultView", (void *)&srSetRainDefaultView); - engine->RegisterScriptFunction("srSetRainWindSpeed", (void *)&srSetRainWindSpeed); - engine->RegisterScriptFunction("srSetRainAmount", (void *)&srSetRainAmount); - engine->RegisterScriptFunction("srSetRainView", (void *)&srSetRainView); - - engine->RegisterScriptFunction("srSetWindSpeed", (void *)&srSetWindSpeed); - engine->RegisterScriptFunction("srSetBaseline", (void *)&srSetBaseline); - - engine->RequestEventHook(AGSE_PREGUIDRAW); - engine->RequestEventHook(AGSE_PRESCREENDRAW); - engine->RequestEventHook(AGSE_ENTERROOM); - engine->RequestEventHook(AGSE_SAVEGAME); - engine->RequestEventHook(AGSE_RESTOREGAME); - - rain = new Weather; - snow = new Weather(true); +void AGSSnowRain::srSetRainAmount(int amount) { + _rain->SetAmount(amount); } -void AGS_EngineShutdown() { - delete rain; - delete snow; +void AGSSnowRain::srSetRainFallSpeed(int min_value, int max_value) { + _rain->SetFallSpeed(min_value, max_value); } -int AGS_EngineOnEvent(int event, int data) { - if (event == AGSE_PREGUIDRAW) { - if (rain->IsActive()) - rain->Update(); - - if (snow->IsActive()) - snow->UpdateWithDrift(); - } else if (event == AGSE_ENTERROOM) { - rain->EnterRoom(); - snow->EnterRoom(); - } else if (event == AGSE_RESTOREGAME) { - rain->RestoreGame(data); - snow->RestoreGame(data); - } else if (event == AGSE_SAVEGAME) { - rain->SaveGame(data); - snow->SaveGame(data); - } else if (event == AGSE_PRESCREENDRAW) { - // Get screen size once here - engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth); - engine->UnrequestEventHook(AGSE_PRESCREENDRAW); - } - - return 0; -} - -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved) { - return 0; -} - -void AGS_EngineInitGfx(const char *driverID, void *data) { -} - - - -#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) - -// ******************************************** -// *********** Editor Interface ************* -// ******************************************** - -const char *scriptHeader = - "import void srSetSnowDriftSpeed(int, int);\r\n" - "import void srSetSnowDriftRange(int, int);\r\n" - "import void srSetSnowFallSpeed(int, int);\r\n" - "import void srChangeSnowAmount(int);\r\n" - "import void srSetSnowBaseline(int, int);\r\n" - "import void srChangeRainAmount(int);\r\n" - "import void srSetRainView(int, int, int, int);\r\n" - "import void srSetRainTransparency(int, int);\r\n" - "import void srSetSnowTransparency(int, int);\r\n" - "import void srSetSnowDefaultView(int, int);\r\n" - "import void srSetRainDefaultView(int, int);\r\n" - "import void srSetRainWindSpeed(int);\r\n" - "import void srSetSnowWindSpeed(int);\r\n" - "import void srSetWindSpeed(int);\r\n" - "import void srSetRainBaseline(int, int);\r\n" - "import void srSetBaseline(int, int);\r\n" - "import void srSetSnowAmount(int);\r\n" - "import void srSetRainAmount(int);\r\n" - "import void srSetRainFallSpeed(int, int);\r\n" - "import void srSetSnowView(int, int, int, int);\r\n"; - - -IAGSEditor *editor; - - -LPCSTR AGS_GetPluginName(void) { - // Return the plugin description - return "Snow/Rain plugin recreation"; -} - -int AGS_EditorStartup(IAGSEditor *lpEditor) { - // User has checked the plugin to use it in their game - - // If it's an earlier version than what we need, abort. - if (lpEditor->version < 1) - return -1; - - editor = lpEditor; - editor->RegisterScriptHeader(scriptHeader); - - // Return 0 to indicate success - return 0; -} - -void AGS_EditorShutdown() { - // User has un-checked the plugin from their game - editor->UnregisterScriptHeader(scriptHeader); -} - -void AGS_EditorProperties(HWND parent) { - // User has chosen to view the Properties of the plugin - // We could load up an options dialog or something here instead - MessageBoxA(parent, "Snow/Rain plugin recreation by JJS", "About", MB_OK | MB_ICONINFORMATION); -} - -int AGS_EditorSaveGame(char *buffer, int bufsize) { - // We don't want to save any persistent data - return 0; -} - -void AGS_EditorLoadGame(char *buffer, int bufsize) { - // Nothing to load for this plugin -} - -#endif - - -#if defined(BUILTIN_PLUGINS) -} // namespace ags_snowrain -#endif +} // namespace AGSSnowRain +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.h b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.h index 1d198af90bb1..148e865af750 100644 --- a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.h +++ b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.h @@ -1,14 +1,83 @@ -#ifndef AGS_SNOWRAIN_H -#define AGS_SNOWRAIN_H +/* 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 "plugin/agsplugin.h" +#ifndef AGS_PLUGINS_AGS_SNOW_RAIN_AGS_SNOW_RAIN_H +#define AGS_PLUGINS_AGS_SNOW_RAIN_AGS_SNOW_RAIN_H -namespace ags_snowrain { -void AGS_EngineStartup(IAGSEngine *lpEngine); -void AGS_EngineShutdown(); -int AGS_EngineOnEvent(int event, int data); -int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved); -void AGS_EngineInitGfx(const char *driverID, void *data); -} +#include "ags/plugins/dll.h" +#include "ags/plugins/ags_snow_rain/weather.h" -#endif \ No newline at end of file +namespace AGS3 { +namespace Plugins { +namespace AGSSnowRain { + +extern IAGSEngine *_engine; +extern int _screenWidth; +extern int _screenHeight; +extern int _screenColorDepth; + +/** + * This is not the original AGS SnowRain plugin, but a workalike + * plugin created for the AGS engine PSP port. + */ +class AGSSnowRain : public DLL { +private: + static Weather *_rain; + static Weather *_snow; +private: + static const char *AGS_GetPluginName(); + static void AGS_EngineStartup(IAGSEngine *lpEngine); + static void AGS_EngineShutdown(); + static int AGS_EngineOnEvent(int event, int data); + +private: + static void srSetWindSpeed(int value); + static void srSetBaseline(int top, int bottom); + static void srSetSnowDriftRange(int min_value, int max_value); + static void srSetSnowDriftSpeed(int min_value, int max_value); + static void srChangeSnowAmount(int amount); + static void srSetSnowView(int kind_id, int event, int view, int loop); + static void srSetSnowDefaultView(int view, int loop); + static void srSetSnowTransparency(int min_value, int max_value); + static void srSetSnowWindSpeed(int value); + static void srSetSnowBaseline(int top, int bottom); + static void srSetSnowAmount(int amount); + static void srSetSnowFallSpeed(int min_value, int max_value); + static void srSetRainDriftRange(int min_value, int max_value); + static void srSetRainDriftSpeed(int min_value, int max_value); + static void srChangeRainAmount(int amount); + static void srSetRainView(int kind_id, int event, int view, int loop); + static void srSetRainDefaultView(int view, int loop); + static void srSetRainTransparency(int min_value, int max_value); + static void srSetRainWindSpeed(int value); + static void srSetRainBaseline(int top, int bottom); + static void srSetRainAmount(int amount); + static void srSetRainFallSpeed(int min_value, int max_value); +public: + AGSSnowRain(); +}; + +} // namespace AGSSnowRain +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_snow_rain/weather.cpp b/engines/ags/plugins/ags_snow_rain/weather.cpp new file mode 100644 index 000000000000..6771162cf96a --- /dev/null +++ b/engines/ags/plugins/ags_snow_rain/weather.cpp @@ -0,0 +1,463 @@ +/* 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 "ags/lib/allegro.h" +#include "ags/plugins/ags_snow_rain/weather.h" +#include "ags/plugins/ags_snow_rain/ags_snow_rain.h" +#include "ags/ags.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSnowRain { + +#define signum(x) ((x > 0) ? 1 : -1) + +const unsigned int Magic = 0xCAFE0000; +const unsigned int Version = 2; +const unsigned int SaveMagic = Magic + Version; +const float PI = 3.14159265f; + +Weather::Weather() { + mIsSnow = false; + Initialize(); +} + +Weather::Weather(bool IsSnow) { + mIsSnow = IsSnow; + Initialize(); +} + +Weather::~Weather() = default; + +void Weather::Update() { + if (mTargetAmount > mAmount) + mAmount++; + else if (mTargetAmount < mAmount) + mAmount--; + + if (!ReinitializeViews()) + return; + + int i; + for (i = 0; i < mAmount * 2; i++) { + mParticles[i].y += mParticles[i].speed; + mParticles[i].x += mWindSpeed; + + if (mParticles[i].x < 0) + mParticles[i].x += _screenWidth; + + if (mParticles[i].x > _screenWidth - 1) + mParticles[i].x -= _screenWidth; + + if (mParticles[i].y > mParticles[i].max_y) { + mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight); + mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; + mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; + mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; + mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaBaseline + mTopBaseline; + } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) + _engine->BlitSpriteTranslucent(mParticles[i].x, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); + } + + _engine->MarkRegionDirty(0, 0, _screenWidth, _screenHeight); +} + +void Weather::UpdateWithDrift() { + if (mTargetAmount > mAmount) + mAmount++; + else if (mTargetAmount < mAmount) + mAmount--; + + if (!ReinitializeViews()) + return; + + int i, drift; + for (i = 0; i < mAmount * 2; i++) { + mParticles[i].y += mParticles[i].speed; + drift = mParticles[i].drift * sin((float)(mParticles[i].y + + mParticles[i].drift_offset) * mParticles[i].drift_speed * 2.0f * PI / 360.0f); + + if (signum(mWindSpeed) == signum(drift)) + mParticles[i].x += mWindSpeed; + else + mParticles[i].x += mWindSpeed / 4; + + if (mParticles[i].x < 0) + mParticles[i].x += _screenWidth; + + if (mParticles[i].x > _screenWidth - 1) + mParticles[i].x -= _screenWidth; + + if (mParticles[i].y > mParticles[i].max_y) { + mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight); + mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; + mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; + mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; + mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaBaseline + mTopBaseline; + mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDrift + mMinDrift; + mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; + } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) + _engine->BlitSpriteTranslucent(mParticles[i].x + drift, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); + } + + _engine->MarkRegionDirty(0, 0, _screenWidth, _screenHeight); +} + +static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = _engine->FRead(ptr, size * count, fileHandle); + return totalBytes / size; +} + +static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { + auto totalBytes = _engine->FWrite(const_cast(ptr), size * count, fileHandle); + return totalBytes / size; +} + +void Weather::RestoreGame(long file) { + unsigned int SaveVersion = 0; + engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, file); + + if (SaveVersion != SaveMagic) { + _engine->AbortGame("ags_snowrain: bad save."); + } + + // Current version + engineFileRead(&mIsSnow, 4, 1, file); + engineFileRead(&mMinDrift, 4, 1, file); + engineFileRead(&mMaxDrift, 4, 1, file); + engineFileRead(&mDeltaDrift, 4, 1, file); + engineFileRead(&mMinDriftSpeed, 4, 1, file); + engineFileRead(&mMaxDriftSpeed, 4, 1, file); + engineFileRead(&mDeltaDriftSpeed, 4, 1, file); + engineFileRead(&mAmount, 4, 1, file); + engineFileRead(&mTargetAmount, 4, 1, file); + engineFileRead(&mMinAlpha, 4, 1, file); + engineFileRead(&mMaxAlpha, 4, 1, file); + engineFileRead(&mDeltaAlpha, 4, 1, file); + engineFileRead(&mWindSpeed, 4, 1, file); + engineFileRead(&mTopBaseline, 4, 1, file); + engineFileRead(&mBottomBaseline, 4, 1, file); + engineFileRead(&mDeltaBaseline, 4, 1, file); + engineFileRead(&mMinFallSpeed, 4, 1, file); + engineFileRead(&mMaxFallSpeed, 4, 1, file); + engineFileRead(&mDeltaFallSpeed, 4, 1, file); + engineFileRead(mViews, sizeof(View) * 5, 1, file); + + InitializeParticles(); +} + +void Weather::SaveGame(long file) { + engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); + + engineFileWrite(&mIsSnow, 4, 1, file); + engineFileWrite(&mMinDrift, 4, 1, file); + engineFileWrite(&mMaxDrift, 4, 1, file); + engineFileWrite(&mDeltaDrift, 4, 1, file); + engineFileWrite(&mMinDriftSpeed, 4, 1, file); + engineFileWrite(&mMaxDriftSpeed, 4, 1, file); + engineFileWrite(&mDeltaDriftSpeed, 4, 1, file); + engineFileWrite(&mAmount, 4, 1, file); + engineFileWrite(&mTargetAmount, 4, 1, file); + engineFileWrite(&mMinAlpha, 4, 1, file); + engineFileWrite(&mMaxAlpha, 4, 1, file); + engineFileWrite(&mDeltaAlpha, 4, 1, file); + engineFileWrite(&mWindSpeed, 4, 1, file); + engineFileWrite(&mTopBaseline, 4, 1, file); + engineFileWrite(&mBottomBaseline, 4, 1, file); + engineFileWrite(&mDeltaBaseline, 4, 1, file); + engineFileWrite(&mMinFallSpeed, 4, 1, file); + engineFileWrite(&mMaxFallSpeed, 4, 1, file); + engineFileWrite(&mDeltaFallSpeed, 4, 1, file); + engineFileWrite(mViews, sizeof(View) * 5, 1, file); +} + +bool Weather::ReinitializeViews() { + if ((mViews[4].view == -1) || (mViews[4].loop == -1)) + return false; + + AGSViewFrame *view_frame = _engine->GetViewFrame(mViews[4].view, mViews[4].loop, 0); + BITMAP *default_bitmap = _engine->GetSpriteGraphic(view_frame->pic); + + int i; + for (i = 0; i < 5; i++) { + if (mViews[i].bitmap != nullptr) { + if (mViews[i].is_default) + mViews[i].bitmap = default_bitmap; + else { + view_frame = _engine->GetViewFrame(mViews[i].view, mViews[i].loop, 0); + mViews[i].bitmap = _engine->GetSpriteGraphic(view_frame->pic); + } + } + } + + return true; +} + +bool Weather::IsActive() { + return (mAmount > 0) || (mTargetAmount != mAmount); +} + +void Weather::EnterRoom() { + mAmount = mTargetAmount; +} + +void Weather::ClipToRange(int &variable, int min, int max) { + if (variable < min) + variable = min; + + if (variable > max) + variable = max; +} + +void Weather::Initialize() { + SetDriftRange(10, 100); + SetDriftSpeed(10, 120); + + SetTransparency(0, 0); + SetWindSpeed(0); + SetBaseline(0, 200); + + if (mIsSnow) + SetFallSpeed(10, 70); + else + SetFallSpeed(100, 300); + + mViewsInitialized = false; + + int i; + for (i = 0; i < 5; i++) { + mViews[i].is_default = true; + mViews[i].view = -1; + mViews[i].loop = -1; + mViews[i].bitmap = nullptr; + } + + SetAmount(0); +} + +void Weather::InitializeParticles() { + memset(mParticles, 0, sizeof(Drop) * 2000); + int i; + for (i = 0; i < 2000; i++) { + mParticles[i].kind_id = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 5; + mParticles[i].y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % (_screenHeight * 2) - _screenHeight; + mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; + mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; + mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; + mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaBaseline + mTopBaseline; + mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDrift + mMinDrift; + mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; + mParticles[i].drift_offset = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 100; + } +} + +void Weather::SetDriftRange(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftRange", min_value, max_value); + _engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 100); + ClipToRange(max_value, 0, 100); + + if (min_value > max_value) + min_value = max_value; + + mMinDrift = min_value / 2; + mMaxDrift = max_value / 2; + mDeltaDrift = mMaxDrift - mMinDrift; + + if (mDeltaDrift == 0) + mDeltaDrift = 1; +} + +void Weather::SetDriftSpeed(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftSpeed", min_value, max_value); + _engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 200); + ClipToRange(max_value, 0, 200); + + if (min_value > max_value) + min_value = max_value; + + mMinDriftSpeed = min_value; + mMaxDriftSpeed = max_value; + mDeltaDriftSpeed = mMaxDriftSpeed - mMinDriftSpeed; + + if (mDeltaDriftSpeed == 0) + mDeltaDriftSpeed = 1; +} + +void Weather::ChangeAmount(int amount) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "ChangeAmount", amount); + _engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(amount, 0, 1000); + + mTargetAmount = amount; +} + +void Weather::SetView(int kind_id, int event, int view, int loop) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d %d %d\n", (int)mIsSnow, "SetView", kind_id, event, view, loop); + _engine->PrintDebugConsole(buffer); +#endif + + AGSViewFrame *view_frame = _engine->GetViewFrame(view, loop, 0); + mViews[kind_id].bitmap = _engine->GetSpriteGraphic(view_frame->pic); + mViews[kind_id].is_default = false; + mViews[kind_id].view = view; + mViews[kind_id].loop = loop; + + if (!mViewsInitialized) + SetDefaultView(view, loop); +} + +void Weather::SetDefaultView(int view, int loop) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDefaultView", view, loop); + _engine->PrintDebugConsole(buffer); +#endif + + AGSViewFrame *view_frame = _engine->GetViewFrame(view, loop, 0); + BITMAP *bitmap = _engine->GetSpriteGraphic(view_frame->pic); + + mViewsInitialized = true; + + int i; + for (i = 0; i < 5; i++) { + if (mViews[i].is_default) { + mViews[i].view = view; + mViews[i].loop = loop; + mViews[i].bitmap = bitmap; + } + } +} + +void Weather::SetTransparency(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetTransparency", min_value, max_value); + _engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 100); + ClipToRange(max_value, 0, 100); + + if (min_value > max_value) + min_value = max_value; + + mMinAlpha = 255 - floor((float)max_value * 2.55f + 0.5f); + mMaxAlpha = 255 - floor((float)min_value * 2.55f + 0.5f); + mDeltaAlpha = mMaxAlpha - mMinAlpha; + + if (mDeltaAlpha == 0) + mDeltaAlpha = 1; + + int i; + for (i = 0; i < 2000; i++) + mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; +} + +void Weather::SetWindSpeed(int value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetWindSpeed", value); + _engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(value, -200, 200); + + mWindSpeed = (float)value / 20.0f; +} + +void Weather::SetBaseline(int top, int bottom) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetBaseline", top, bottom); + _engine->PrintDebugConsole(buffer); +#endif + + if (_screenHeight > 0) { + ClipToRange(top, 0, _screenHeight); + ClipToRange(bottom, 0, _screenHeight); + } + + if (top > bottom) + top = bottom; + + mTopBaseline = top; + mBottomBaseline = bottom; + mDeltaBaseline = mBottomBaseline - mTopBaseline; + + if (mDeltaBaseline == 0) + mDeltaBaseline = 1; +} + +void Weather::SetAmount(int amount) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetAmount", amount); + _engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(amount, 0, 1000); + + mAmount = mTargetAmount = amount; + + InitializeParticles(); +} + +void Weather::SetFallSpeed(int min_value, int max_value) { +#ifdef DEBUG + char buffer[200]; + sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetFallSpeed", min_value, max_value); + _engine->PrintDebugConsole(buffer); +#endif + + ClipToRange(min_value, 0, 1000); + ClipToRange(max_value, 0, 1000); + + if (min_value > max_value) + min_value = max_value; + + mMinFallSpeed = min_value; + mMaxFallSpeed = max_value; + mDeltaFallSpeed = mMaxFallSpeed - mMinFallSpeed; + + if (mDeltaFallSpeed == 0) + mDeltaFallSpeed = 1; +} + +} // namespace AGSSnowRain +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_snow_rain/weather.h b/engines/ags/plugins/ags_snow_rain/weather.h new file mode 100644 index 000000000000..c05879e2ce56 --- /dev/null +++ b/engines/ags/plugins/ags_snow_rain/weather.h @@ -0,0 +1,120 @@ +/* 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 AGS_PLUGINS_AGS_SNOW_RAIN_WEATHER_H +#define AGS_PLUGINS_AGS_SNOW_RAIN_WEATHER_H + +#include "ags/plugins/dll.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSnowRain { + +struct View { + int view = 0; + int loop = 0; + bool is_default = false; + BITMAP *bitmap = nullptr; +}; + +struct Drop { + float x = 0; + float y = 0; + int alpha = 0; + float speed = 0; + int max_y = 0; + int kind_id = 0; + int drift = 0; + float drift_speed = 0; + float drift_offset = 0; +}; + +class Weather { +public: + Weather(); + Weather(bool IsSnow); + ~Weather(); + + void Initialize(); + void InitializeParticles(); + + void RestoreGame(long file); + void SaveGame(long file); + bool ReinitializeViews(); + + bool IsActive(); + void Update(); + void UpdateWithDrift(); + void EnterRoom(); + + void SetDriftRange(int min_value, int max_value); + void SetDriftSpeed(int min_value, int max_value); + void ChangeAmount(int amount); + void SetView(int kind_id, int event, int view, int loop); + void SetDefaultView(int view, int loop); + void SetTransparency(int min_value, int max_value); + void SetWindSpeed(int value); + void SetBaseline(int top, int bottom); + void SetAmount(int amount); + void SetFallSpeed(int min_value, int max_value); + +private: + void ClipToRange(int &variable, int min, int max); + + bool mIsSnow; + + int mMinDrift; + int mMaxDrift; + int mDeltaDrift; + + int mMinDriftSpeed; + int mMaxDriftSpeed; + int mDeltaDriftSpeed; + + int mAmount; + int mTargetAmount; + + int mMinAlpha; + int mMaxAlpha; + int mDeltaAlpha; + + float mWindSpeed; + + int mTopBaseline; + int mBottomBaseline; + int mDeltaBaseline; + + int mMinFallSpeed; + int mMaxFallSpeed; + int mDeltaFallSpeed; + + Drop mParticles[2000]; + View mViews[5]; + + bool mViewsInitialized; +}; + +} // namespace AGSSnowRain +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index 74217cd2ee21..4d3554b5cedc 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -26,6 +26,7 @@ #include "ags/plugins/ags_creditz/ags_creditz.h" #include "ags/plugins/ags_flashlight/ags_flashlight.h" #include "ags/plugins/ags_pal_render/ags_pal_render.h" +#include "ags/plugins/ags_snow_rain/ags_snow_rain.h" #include "ags/ags.h" #include "ags/detection.h" #include "common/str.h" @@ -62,6 +63,9 @@ void *dlopen(const char *filename) { if (fname.equalsIgnoreCase("libAGSPalRender.so")) return new AGSPalRender::AGSPalRender(); + if (fname.equalsIgnoreCase("libAGSSnowRain.so")) + return new AGSSnowRain::AGSSnowRain(); + return nullptr; } From 72c560f0497e41e87932d9b1b1be2af688483cc5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 19:19:46 -0800 Subject: [PATCH 176/215] AGS: Made AGSSnowRain endian safe --- .../plugins/ags_snow_rain/ags_snow_rain.cpp | 10 +- engines/ags/plugins/ags_snow_rain/weather.cpp | 341 +++++++++--------- engines/ags/plugins/ags_snow_rain/weather.h | 75 ++-- engines/ags/plugins/serializer.h | 73 ++++ 4 files changed, 279 insertions(+), 220 deletions(-) create mode 100644 engines/ags/plugins/serializer.h diff --git a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp index 051a0ed63b13..36caa399997e 100644 --- a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp +++ b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp @@ -108,11 +108,13 @@ int AGSSnowRain::AGS_EngineOnEvent(int event, int data) { _rain->EnterRoom(); _snow->EnterRoom(); } else if (event == AGSE_RESTOREGAME) { - _rain->RestoreGame(data); - _snow->RestoreGame(data); + Serializer s(_engine, data, true); + _rain->SyncGame(s); + _snow->SyncGame(s); } else if (event == AGSE_SAVEGAME) { - _rain->SaveGame(data); - _snow->SaveGame(data); + Serializer s(_engine, data, false); + _rain->SyncGame(s); + _snow->SyncGame(s); } else if (event == AGSE_PRESCREENDRAW) { // Get screen size once here _engine->GetScreenDimensions(&_screenWidth, &_screenHeight , &_screenColorDepth); diff --git a/engines/ags/plugins/ags_snow_rain/weather.cpp b/engines/ags/plugins/ags_snow_rain/weather.cpp index 6771162cf96a..5b76e6ce5c7c 100644 --- a/engines/ags/plugins/ags_snow_rain/weather.cpp +++ b/engines/ags/plugins/ags_snow_rain/weather.cpp @@ -36,175 +36,156 @@ const unsigned int Version = 2; const unsigned int SaveMagic = Magic + Version; const float PI = 3.14159265f; -Weather::Weather() { - mIsSnow = false; + +void View::SyncGame(Serializer &s) { + s.syncAsInt(view); + s.syncAsInt(loop); + s.syncAsBool(is_default); + + // Pointer saved/loaded raw structure, which included bitmap pointer + int dummy = 0; + s.syncAsInt(dummy); +} + +/*------------------------------------------------------------------*/ + +Weather::Weather() : _mIsSnow(false) { Initialize(); } -Weather::Weather(bool IsSnow) { - mIsSnow = IsSnow; +Weather::Weather(bool IsSnow) : _mIsSnow(IsSnow) { Initialize(); } Weather::~Weather() = default; void Weather::Update() { - if (mTargetAmount > mAmount) - mAmount++; - else if (mTargetAmount < mAmount) - mAmount--; + if (_mTargetAmount > _mAmount) + _mAmount++; + else if (_mTargetAmount < _mAmount) + _mAmount--; if (!ReinitializeViews()) return; int i; - for (i = 0; i < mAmount * 2; i++) { - mParticles[i].y += mParticles[i].speed; - mParticles[i].x += mWindSpeed; - - if (mParticles[i].x < 0) - mParticles[i].x += _screenWidth; - - if (mParticles[i].x > _screenWidth - 1) - mParticles[i].x -= _screenWidth; - - if (mParticles[i].y > mParticles[i].max_y) { - mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight); - mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; - mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; - mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; - mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaBaseline + mTopBaseline; - } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) - _engine->BlitSpriteTranslucent(mParticles[i].x, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); + for (i = 0; i < _mAmount * 2; i++) { + _mParticles[i].y += _mParticles[i].speed; + _mParticles[i].x += _mWindSpeed; + + if (_mParticles[i].x < 0) + _mParticles[i].x += _screenWidth; + + if (_mParticles[i].x > _screenWidth - 1) + _mParticles[i].x -= _screenWidth; + + if (_mParticles[i].y > _mParticles[i].max_y) { + _mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight); + _mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; + _mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha; + _mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaFallSpeed + _mMinFallSpeed) / 50.0f; + _mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaBaseline + _mTopBaseline; + } else if ((_mParticles[i].y > 0) && (_mParticles[i].alpha > 0)) + _engine->BlitSpriteTranslucent(_mParticles[i].x, _mParticles[i].y, _mViews[_mParticles[i].kind_id].bitmap, _mParticles[i].alpha); } _engine->MarkRegionDirty(0, 0, _screenWidth, _screenHeight); } void Weather::UpdateWithDrift() { - if (mTargetAmount > mAmount) - mAmount++; - else if (mTargetAmount < mAmount) - mAmount--; + if (_mTargetAmount > _mAmount) + _mAmount++; + else if (_mTargetAmount < _mAmount) + _mAmount--; if (!ReinitializeViews()) return; int i, drift; - for (i = 0; i < mAmount * 2; i++) { - mParticles[i].y += mParticles[i].speed; - drift = mParticles[i].drift * sin((float)(mParticles[i].y + - mParticles[i].drift_offset) * mParticles[i].drift_speed * 2.0f * PI / 360.0f); + for (i = 0; i < _mAmount * 2; i++) { + _mParticles[i].y += _mParticles[i].speed; + drift = _mParticles[i].drift * sin((float)(_mParticles[i].y + + _mParticles[i].drift_offset) * _mParticles[i].drift_speed * 2.0f * PI / 360.0f); - if (signum(mWindSpeed) == signum(drift)) - mParticles[i].x += mWindSpeed; + if (signum(_mWindSpeed) == signum(drift)) + _mParticles[i].x += _mWindSpeed; else - mParticles[i].x += mWindSpeed / 4; - - if (mParticles[i].x < 0) - mParticles[i].x += _screenWidth; - - if (mParticles[i].x > _screenWidth - 1) - mParticles[i].x -= _screenWidth; - - if (mParticles[i].y > mParticles[i].max_y) { - mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight); - mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; - mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; - mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; - mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaBaseline + mTopBaseline; - mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDrift + mMinDrift; - mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; - } else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0)) - _engine->BlitSpriteTranslucent(mParticles[i].x + drift, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha); + _mParticles[i].x += _mWindSpeed / 4; + + if (_mParticles[i].x < 0) + _mParticles[i].x += _screenWidth; + + if (_mParticles[i].x > _screenWidth - 1) + _mParticles[i].x -= _screenWidth; + + if (_mParticles[i].y > _mParticles[i].max_y) { + _mParticles[i].y = -1 * (::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenHeight); + _mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; + _mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha; + _mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaFallSpeed + _mMinFallSpeed) / 50.0f; + _mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaBaseline + _mTopBaseline; + _mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDrift + _mMinDrift; + _mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDriftSpeed + _mMinDriftSpeed) / 50.0f; + } else if ((_mParticles[i].y > 0) && (_mParticles[i].alpha > 0)) + _engine->BlitSpriteTranslucent(_mParticles[i].x + drift, _mParticles[i].y, _mViews[_mParticles[i].kind_id].bitmap, _mParticles[i].alpha); } _engine->MarkRegionDirty(0, 0, _screenWidth, _screenHeight); } -static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = _engine->FRead(ptr, size * count, fileHandle); - return totalBytes / size; -} - -static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = _engine->FWrite(const_cast(ptr), size * count, fileHandle); - return totalBytes / size; -} - -void Weather::RestoreGame(long file) { - unsigned int SaveVersion = 0; - engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, file); +void Weather::SyncGame(Serializer &s) { + int saveVersion = 0; + s.syncAsInt(saveVersion); - if (SaveVersion != SaveMagic) { + if (s.isLoading() && saveVersion != SaveMagic) { _engine->AbortGame("ags_snowrain: bad save."); + return; } - // Current version - engineFileRead(&mIsSnow, 4, 1, file); - engineFileRead(&mMinDrift, 4, 1, file); - engineFileRead(&mMaxDrift, 4, 1, file); - engineFileRead(&mDeltaDrift, 4, 1, file); - engineFileRead(&mMinDriftSpeed, 4, 1, file); - engineFileRead(&mMaxDriftSpeed, 4, 1, file); - engineFileRead(&mDeltaDriftSpeed, 4, 1, file); - engineFileRead(&mAmount, 4, 1, file); - engineFileRead(&mTargetAmount, 4, 1, file); - engineFileRead(&mMinAlpha, 4, 1, file); - engineFileRead(&mMaxAlpha, 4, 1, file); - engineFileRead(&mDeltaAlpha, 4, 1, file); - engineFileRead(&mWindSpeed, 4, 1, file); - engineFileRead(&mTopBaseline, 4, 1, file); - engineFileRead(&mBottomBaseline, 4, 1, file); - engineFileRead(&mDeltaBaseline, 4, 1, file); - engineFileRead(&mMinFallSpeed, 4, 1, file); - engineFileRead(&mMaxFallSpeed, 4, 1, file); - engineFileRead(&mDeltaFallSpeed, 4, 1, file); - engineFileRead(mViews, sizeof(View) * 5, 1, file); - - InitializeParticles(); -} - -void Weather::SaveGame(long file) { - engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file); - - engineFileWrite(&mIsSnow, 4, 1, file); - engineFileWrite(&mMinDrift, 4, 1, file); - engineFileWrite(&mMaxDrift, 4, 1, file); - engineFileWrite(&mDeltaDrift, 4, 1, file); - engineFileWrite(&mMinDriftSpeed, 4, 1, file); - engineFileWrite(&mMaxDriftSpeed, 4, 1, file); - engineFileWrite(&mDeltaDriftSpeed, 4, 1, file); - engineFileWrite(&mAmount, 4, 1, file); - engineFileWrite(&mTargetAmount, 4, 1, file); - engineFileWrite(&mMinAlpha, 4, 1, file); - engineFileWrite(&mMaxAlpha, 4, 1, file); - engineFileWrite(&mDeltaAlpha, 4, 1, file); - engineFileWrite(&mWindSpeed, 4, 1, file); - engineFileWrite(&mTopBaseline, 4, 1, file); - engineFileWrite(&mBottomBaseline, 4, 1, file); - engineFileWrite(&mDeltaBaseline, 4, 1, file); - engineFileWrite(&mMinFallSpeed, 4, 1, file); - engineFileWrite(&mMaxFallSpeed, 4, 1, file); - engineFileWrite(&mDeltaFallSpeed, 4, 1, file); - engineFileWrite(mViews, sizeof(View) * 5, 1, file); + // TODO: At some point check whether the original did a packed + // structure for Weather, or if bools were padded to 4 bytes + s.syncAsBool(_mIsSnow); + s.syncAsInt(_mMinDrift); + s.syncAsInt(_mMaxDrift); + s.syncAsInt(_mDeltaDrift); + s.syncAsInt(_mMinDriftSpeed); + s.syncAsInt(_mMaxDriftSpeed); + s.syncAsInt(_mDeltaDriftSpeed); + s.syncAsInt(_mAmount); + s.syncAsInt(_mTargetAmount); + s.syncAsInt(_mMinAlpha); + s.syncAsInt(_mMaxAlpha); + s.syncAsInt(_mDeltaAlpha); + s.syncAsFloat(_mWindSpeed); + s.syncAsInt(_mTopBaseline); + s.syncAsInt(_mBottomBaseline); + s.syncAsInt(_mDeltaBaseline); + s.syncAsInt(_mMinFallSpeed); + s.syncAsInt(_mMaxFallSpeed); + s.syncAsInt(_mDeltaFallSpeed); + + for (int i = 0; i < 5; ++i) + _mViews[i].SyncGame(s); + + if (s.isLoading()) + InitializeParticles(); } bool Weather::ReinitializeViews() { - if ((mViews[4].view == -1) || (mViews[4].loop == -1)) + if ((_mViews[4].view == -1) || (_mViews[4].loop == -1)) return false; - AGSViewFrame *view_frame = _engine->GetViewFrame(mViews[4].view, mViews[4].loop, 0); + AGSViewFrame *view_frame = _engine->GetViewFrame(_mViews[4].view, _mViews[4].loop, 0); BITMAP *default_bitmap = _engine->GetSpriteGraphic(view_frame->pic); int i; for (i = 0; i < 5; i++) { - if (mViews[i].bitmap != nullptr) { - if (mViews[i].is_default) - mViews[i].bitmap = default_bitmap; + if (_mViews[i].bitmap != nullptr) { + if (_mViews[i].is_default) + _mViews[i].bitmap = default_bitmap; else { - view_frame = _engine->GetViewFrame(mViews[i].view, mViews[i].loop, 0); - mViews[i].bitmap = _engine->GetSpriteGraphic(view_frame->pic); + view_frame = _engine->GetViewFrame(_mViews[i].view, _mViews[i].loop, 0); + _mViews[i].bitmap = _engine->GetSpriteGraphic(view_frame->pic); } } } @@ -213,11 +194,11 @@ bool Weather::ReinitializeViews() { } bool Weather::IsActive() { - return (mAmount > 0) || (mTargetAmount != mAmount); + return (_mAmount > 0) || (_mTargetAmount != _mAmount); } void Weather::EnterRoom() { - mAmount = mTargetAmount; + _mAmount = _mTargetAmount; } void Weather::ClipToRange(int &variable, int min, int max) { @@ -236,37 +217,37 @@ void Weather::Initialize() { SetWindSpeed(0); SetBaseline(0, 200); - if (mIsSnow) + if (_mIsSnow) SetFallSpeed(10, 70); else SetFallSpeed(100, 300); - mViewsInitialized = false; + _mViewsInitialized = false; int i; for (i = 0; i < 5; i++) { - mViews[i].is_default = true; - mViews[i].view = -1; - mViews[i].loop = -1; - mViews[i].bitmap = nullptr; + _mViews[i].is_default = true; + _mViews[i].view = -1; + _mViews[i].loop = -1; + _mViews[i].bitmap = nullptr; } SetAmount(0); } void Weather::InitializeParticles() { - memset(mParticles, 0, sizeof(Drop) * 2000); + memset(_mParticles, 0, sizeof(Drop) * 2000); int i; for (i = 0; i < 2000; i++) { - mParticles[i].kind_id = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 5; - mParticles[i].y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % (_screenHeight * 2) - _screenHeight; - mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; - mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; - mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaFallSpeed + mMinFallSpeed) / 50.0f; - mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaBaseline + mTopBaseline; - mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDrift + mMinDrift; - mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f; - mParticles[i].drift_offset = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 100; + _mParticles[i].kind_id = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 5; + _mParticles[i].y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % (_screenHeight * 2) - _screenHeight; + _mParticles[i].x = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _screenWidth; + _mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha; + _mParticles[i].speed = (float)(::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaFallSpeed + _mMinFallSpeed) / 50.0f; + _mParticles[i].max_y = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaBaseline + _mTopBaseline; + _mParticles[i].drift = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDrift + _mMinDrift; + _mParticles[i].drift_speed = (::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaDriftSpeed + _mMinDriftSpeed) / 50.0f; + _mParticles[i].drift_offset = ::AGS::g_vm->getRandomNumber(0x7fffffff) % 100; } } @@ -283,12 +264,12 @@ void Weather::SetDriftRange(int min_value, int max_value) { if (min_value > max_value) min_value = max_value; - mMinDrift = min_value / 2; - mMaxDrift = max_value / 2; - mDeltaDrift = mMaxDrift - mMinDrift; + _mMinDrift = min_value / 2; + _mMaxDrift = max_value / 2; + _mDeltaDrift = _mMaxDrift - _mMinDrift; - if (mDeltaDrift == 0) - mDeltaDrift = 1; + if (_mDeltaDrift == 0) + _mDeltaDrift = 1; } void Weather::SetDriftSpeed(int min_value, int max_value) { @@ -304,12 +285,12 @@ void Weather::SetDriftSpeed(int min_value, int max_value) { if (min_value > max_value) min_value = max_value; - mMinDriftSpeed = min_value; - mMaxDriftSpeed = max_value; - mDeltaDriftSpeed = mMaxDriftSpeed - mMinDriftSpeed; + _mMinDriftSpeed = min_value; + _mMaxDriftSpeed = max_value; + _mDeltaDriftSpeed = _mMaxDriftSpeed - _mMinDriftSpeed; - if (mDeltaDriftSpeed == 0) - mDeltaDriftSpeed = 1; + if (_mDeltaDriftSpeed == 0) + _mDeltaDriftSpeed = 1; } void Weather::ChangeAmount(int amount) { @@ -321,7 +302,7 @@ void Weather::ChangeAmount(int amount) { ClipToRange(amount, 0, 1000); - mTargetAmount = amount; + _mTargetAmount = amount; } void Weather::SetView(int kind_id, int event, int view, int loop) { @@ -332,12 +313,12 @@ void Weather::SetView(int kind_id, int event, int view, int loop) { #endif AGSViewFrame *view_frame = _engine->GetViewFrame(view, loop, 0); - mViews[kind_id].bitmap = _engine->GetSpriteGraphic(view_frame->pic); - mViews[kind_id].is_default = false; - mViews[kind_id].view = view; - mViews[kind_id].loop = loop; + _mViews[kind_id].bitmap = _engine->GetSpriteGraphic(view_frame->pic); + _mViews[kind_id].is_default = false; + _mViews[kind_id].view = view; + _mViews[kind_id].loop = loop; - if (!mViewsInitialized) + if (!_mViewsInitialized) SetDefaultView(view, loop); } @@ -351,14 +332,14 @@ void Weather::SetDefaultView(int view, int loop) { AGSViewFrame *view_frame = _engine->GetViewFrame(view, loop, 0); BITMAP *bitmap = _engine->GetSpriteGraphic(view_frame->pic); - mViewsInitialized = true; + _mViewsInitialized = true; int i; for (i = 0; i < 5; i++) { - if (mViews[i].is_default) { - mViews[i].view = view; - mViews[i].loop = loop; - mViews[i].bitmap = bitmap; + if (_mViews[i].is_default) { + _mViews[i].view = view; + _mViews[i].loop = loop; + _mViews[i].bitmap = bitmap; } } } @@ -376,16 +357,16 @@ void Weather::SetTransparency(int min_value, int max_value) { if (min_value > max_value) min_value = max_value; - mMinAlpha = 255 - floor((float)max_value * 2.55f + 0.5f); - mMaxAlpha = 255 - floor((float)min_value * 2.55f + 0.5f); - mDeltaAlpha = mMaxAlpha - mMinAlpha; + _mMinAlpha = 255 - floor((float)max_value * 2.55f + 0.5f); + _mMaxAlpha = 255 - floor((float)min_value * 2.55f + 0.5f); + _mDeltaAlpha = _mMaxAlpha - _mMinAlpha; - if (mDeltaAlpha == 0) - mDeltaAlpha = 1; + if (_mDeltaAlpha == 0) + _mDeltaAlpha = 1; int i; for (i = 0; i < 2000; i++) - mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % mDeltaAlpha + mMinAlpha; + _mParticles[i].alpha = ::AGS::g_vm->getRandomNumber(0x7fffffff) % _mDeltaAlpha + _mMinAlpha; } void Weather::SetWindSpeed(int value) { @@ -397,7 +378,7 @@ void Weather::SetWindSpeed(int value) { ClipToRange(value, -200, 200); - mWindSpeed = (float)value / 20.0f; + _mWindSpeed = (float)value / 20.0f; } void Weather::SetBaseline(int top, int bottom) { @@ -415,12 +396,12 @@ void Weather::SetBaseline(int top, int bottom) { if (top > bottom) top = bottom; - mTopBaseline = top; - mBottomBaseline = bottom; - mDeltaBaseline = mBottomBaseline - mTopBaseline; + _mTopBaseline = top; + _mBottomBaseline = bottom; + _mDeltaBaseline = _mBottomBaseline - _mTopBaseline; - if (mDeltaBaseline == 0) - mDeltaBaseline = 1; + if (_mDeltaBaseline == 0) + _mDeltaBaseline = 1; } void Weather::SetAmount(int amount) { @@ -432,7 +413,7 @@ void Weather::SetAmount(int amount) { ClipToRange(amount, 0, 1000); - mAmount = mTargetAmount = amount; + _mAmount = _mTargetAmount = amount; InitializeParticles(); } @@ -450,12 +431,12 @@ void Weather::SetFallSpeed(int min_value, int max_value) { if (min_value > max_value) min_value = max_value; - mMinFallSpeed = min_value; - mMaxFallSpeed = max_value; - mDeltaFallSpeed = mMaxFallSpeed - mMinFallSpeed; + _mMinFallSpeed = min_value; + _mMaxFallSpeed = max_value; + _mDeltaFallSpeed = _mMaxFallSpeed - _mMinFallSpeed; - if (mDeltaFallSpeed == 0) - mDeltaFallSpeed = 1; + if (_mDeltaFallSpeed == 0) + _mDeltaFallSpeed = 1; } } // namespace AGSSnowRain diff --git a/engines/ags/plugins/ags_snow_rain/weather.h b/engines/ags/plugins/ags_snow_rain/weather.h index c05879e2ce56..a2e634c9cf31 100644 --- a/engines/ags/plugins/ags_snow_rain/weather.h +++ b/engines/ags/plugins/ags_snow_rain/weather.h @@ -24,6 +24,7 @@ #define AGS_PLUGINS_AGS_SNOW_RAIN_WEATHER_H #include "ags/plugins/dll.h" +#include "ags/plugins/serializer.h" namespace AGS3 { namespace Plugins { @@ -34,6 +35,8 @@ struct View { int loop = 0; bool is_default = false; BITMAP *bitmap = nullptr; + + void SyncGame(Serializer &s); }; struct Drop { @@ -49,6 +52,41 @@ struct Drop { }; class Weather { +private: + void ClipToRange(int &variable, int min, int max); + + bool _mIsSnow; + + int _mMinDrift = 0; + int _mMaxDrift = 0; + int _mDeltaDrift = 0; + + int _mMinDriftSpeed = 0; + int _mMaxDriftSpeed = 0; + int _mDeltaDriftSpeed = 0; + + int _mAmount = 0; + int _mTargetAmount = 0; + + int _mMinAlpha = 0; + int _mMaxAlpha = 0; + int _mDeltaAlpha = 0; + + float _mWindSpeed = 0; + + int _mTopBaseline = 0; + int _mBottomBaseline = 0; + int _mDeltaBaseline = 0; + + int _mMinFallSpeed = 0; + int _mMaxFallSpeed = 0; + int _mDeltaFallSpeed = 0; + + Drop _mParticles[2000]; + View _mViews[5]; + + bool _mViewsInitialized; + public: Weather(); Weather(bool IsSnow); @@ -57,8 +95,7 @@ class Weather { void Initialize(); void InitializeParticles(); - void RestoreGame(long file); - void SaveGame(long file); + void SyncGame(Serializer &s); bool ReinitializeViews(); bool IsActive(); @@ -77,40 +114,6 @@ class Weather { void SetAmount(int amount); void SetFallSpeed(int min_value, int max_value); -private: - void ClipToRange(int &variable, int min, int max); - - bool mIsSnow; - - int mMinDrift; - int mMaxDrift; - int mDeltaDrift; - - int mMinDriftSpeed; - int mMaxDriftSpeed; - int mDeltaDriftSpeed; - - int mAmount; - int mTargetAmount; - - int mMinAlpha; - int mMaxAlpha; - int mDeltaAlpha; - - float mWindSpeed; - - int mTopBaseline; - int mBottomBaseline; - int mDeltaBaseline; - - int mMinFallSpeed; - int mMaxFallSpeed; - int mDeltaFallSpeed; - - Drop mParticles[2000]; - View mViews[5]; - - bool mViewsInitialized; }; } // namespace AGSSnowRain diff --git a/engines/ags/plugins/serializer.h b/engines/ags/plugins/serializer.h new file mode 100644 index 000000000000..ba48c0bc25a2 --- /dev/null +++ b/engines/ags/plugins/serializer.h @@ -0,0 +1,73 @@ +/* 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 AGS_PLUGINS_SERIALIZER_H +#define AGS_PLUGINS_SERIALIZER_H + +#include "ags/engine/plugin/agsplugin.h" +#include "common/serializer.h" + +namespace AGS3 { +namespace Plugins { + +class Serializer { +private: + IAGSEngine *_engine; + long _file; + bool _isLoading; +public: + Serializer(IAGSEngine *engine, long file, bool isLoading) : + _engine(engine), _file(file), _isLoading(isLoading) {} + + bool isLoading() const { return _isLoading; } + bool isSaving() const { return !_isLoading; } + + void syncAsInt(int &value) { + byte buf[4]; + if (_isLoading) { + _engine->FRead(buf, sizeof(int32), _file); + value = READ_LE_INT32(buf); + } else { + WRITE_LE_UINT32(buf, value); + _engine->FWrite(buf, sizeof(int32), _file); + } + } + + void syncAsBool(bool &value) { + if (_isLoading) + _engine->FRead(&value, 1, _file); + else + _engine->FWrite(&value, 1, _file); + } + + void syncAsFloat(float &value) { + if (_isLoading) + _engine->FRead(&value, sizeof(float), _file); + else + _engine->FWrite(&value, sizeof(float), _file); + } +}; + +} // namespace Plugins +} // namespace AGS3 + +#endif From 01907c8fc990646bb685f22c34020f0d7f7e6a89 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 19:24:37 -0800 Subject: [PATCH 177/215] AGS: Change AGSParallax plugin to use save serializer --- .../ags/plugins/ags_parallax/ags_parallax.cpp | 69 +++++-------------- .../ags/plugins/ags_parallax/ags_parallax.h | 11 +-- engines/ags/plugins/ags_snow_rain/weather.cpp | 2 +- 3 files changed, 20 insertions(+), 62 deletions(-) diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.cpp b/engines/ags/plugins/ags_parallax/ags_parallax.cpp index a07e7382fe27..1bb6eff35497 100644 --- a/engines/ags/plugins/ags_parallax/ags_parallax.cpp +++ b/engines/ags/plugins/ags_parallax/ags_parallax.cpp @@ -85,9 +85,11 @@ int AGSParallax::AGS_EngineOnEvent(int event, int data) { _engine->GetScreenDimensions(&_screenWidth, &_screenHeight, &_screenColorDepth); _engine->UnrequestEventHook(AGSE_PRESCREENDRAW); } else if (event == AGSE_RESTOREGAME) { - RestoreGame(data); + Serializer s(_engine, data, true); + SyncGame(s); } else if (event == AGSE_SAVEGAME) { - SaveGame(data); + Serializer s(_engine, data, false); + SyncGame(s); } return 0; @@ -102,37 +104,17 @@ void AGSParallax::clear() { _enabled = false; } -size_t AGSParallax::engineFileRead(void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = _engine->FRead(ptr, size * count, fileHandle); - return totalBytes / size; -} - -size_t AGSParallax::engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) { - auto totalBytes = _engine->FWrite(const_cast(ptr), size * count, fileHandle); - return totalBytes / size; -} - -void AGSParallax::RestoreGame(long file) { - byte saveVersion[4]; - engineFileRead(&saveVersion, 4, 1, file); - - if (READ_LE_UINT32(saveVersion) != SaveMagic) { +void AGSParallax::SyncGame(Serializer &s) { + int saveVersion = SaveMagic; + s.syncAsInt(saveVersion); + if (saveVersion != SaveMagic) { _engine->AbortGame("ags_parallax: bad save."); + return; } for (int i = 0; i < MAX_SPRITES; ++i) - _sprites[i].load(_engine, file); - engineFileRead(&_enabled, sizeof(bool), 1, file); -} - -void AGSParallax::SaveGame(long file) { - byte saveVersion[4]; - WRITE_LE_UINT32(saveVersion, SaveMagic); - engineFileWrite(&SaveMagic, 4, 1, file); - - for (int i = 0; i < MAX_SPRITES; ++i) - _sprites[i].save(_engine, file); - engineFileWrite(&_enabled, 1, 1, file); + _sprites[i].SyncGame(s); + s.syncAsBool(_enabled); } void AGSParallax::Draw(bool foreground) { @@ -204,30 +186,11 @@ void AGSParallax::pxDeleteSprite(int id) { /*------------------------------------------------------------------*/ -void Sprite::save(IAGSEngine *engine, long file) { - saveInt(engine, file, x); - saveInt(engine, file, y); - saveInt(engine, file, slot); - saveInt(engine, file, speed); -} - -void Sprite::load(IAGSEngine *engine, long file) { - x = loadInt(engine, file); - y = loadInt(engine, file); - slot = loadInt(engine, file); - speed = loadInt(engine, file); -} - -void saveInt(IAGSEngine *engine, long file, int value) { - byte buf[4]; - WRITE_LE_INT32(buf, value); - engine->FWrite(buf, 4, file); -} - -int loadInt(IAGSEngine *engine, long file) { - byte buf[4]; - engine->FRead(buf, 4, file); - return READ_LE_INT32(buf); +void Sprite::SyncGame(Serializer &s) { + s.syncAsInt(x); + s.syncAsInt(y); + s.syncAsInt(slot); + s.syncAsInt(speed); } } // namespace AGSParallax diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.h b/engines/ags/plugins/ags_parallax/ags_parallax.h index 2d441e38e07a..8647a95235a2 100644 --- a/engines/ags/plugins/ags_parallax/ags_parallax.h +++ b/engines/ags/plugins/ags_parallax/ags_parallax.h @@ -24,6 +24,7 @@ #define AGS_PLUGINS_AGS_PARALLAX_AGS_PARALLAX_H #include "ags/plugins/dll.h" +#include "ags/plugins/serializer.h" namespace AGS3 { namespace Plugins { @@ -35,10 +36,7 @@ struct Sprite { int slot = -1; int speed = 0; - void save(IAGSEngine *engine, long file); - void load(IAGSEngine *engine, long file); - void saveInt(IAGSEngine *engine, long file, int value); - int loadInt(IAGSEngine *engine, long file); + void SyncGame(Serializer &s); }; #define MAX_SPEED 1000 @@ -66,10 +64,7 @@ class AGSParallax : public DLL { static void pxDeleteSprite(int id); private: - static size_t engineFileRead(void *ptr, size_t size, size_t count, long fileHandle); - static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle); - static void RestoreGame(long file); - static void SaveGame(long file); + static void SyncGame(Serializer &s); static void Draw(bool foreground); static void clear(); diff --git a/engines/ags/plugins/ags_snow_rain/weather.cpp b/engines/ags/plugins/ags_snow_rain/weather.cpp index 5b76e6ce5c7c..3798067749d0 100644 --- a/engines/ags/plugins/ags_snow_rain/weather.cpp +++ b/engines/ags/plugins/ags_snow_rain/weather.cpp @@ -134,7 +134,7 @@ void Weather::UpdateWithDrift() { } void Weather::SyncGame(Serializer &s) { - int saveVersion = 0; + int saveVersion = SaveMagic; s.syncAsInt(saveVersion); if (s.isLoading() && saveVersion != SaveMagic) { From 536f8d26523a4788ec0c63721b7aea7aa21fbe9a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 22:00:39 -0800 Subject: [PATCH 178/215] AGS: Added AGSSpriteFont plugin --- engines/ags/lib/std/map.h | 13 + engines/ags/module.mk | 9 +- .../ags_sprite_font/ags_sprite_font.cpp | 294 +++++------------- .../plugins/ags_sprite_font/ags_sprite_font.h | 59 ++++ .../ags_sprite_font/character_entry.cpp | 31 +- .../plugins/ags_sprite_font/character_entry.h | 35 ++- engines/ags/plugins/ags_sprite_font/color.cpp | 34 +- engines/ags/plugins/ags_sprite_font/color.h | 36 ++- .../plugins/ags_sprite_font/sprite_font.cpp | 31 +- .../ags/plugins/ags_sprite_font/sprite_font.h | 35 ++- .../ags_sprite_font/sprite_font_renderer.cpp | 41 ++- .../ags_sprite_font/sprite_font_renderer.h | 43 ++- .../ags_sprite_font/variable_width_font.cpp | 31 +- .../ags_sprite_font/variable_width_font.h | 45 ++- .../variable_width_sprite_font.cpp | 52 +++- .../variable_width_sprite_font.h | 43 ++- engines/ags/plugins/dll.cpp | 4 + 17 files changed, 568 insertions(+), 268 deletions(-) create mode 100644 engines/ags/plugins/ags_sprite_font/ags_sprite_font.h diff --git a/engines/ags/lib/std/map.h b/engines/ags/lib/std/map.h index d4d2b87da5fd..b64afd9f98c5 100644 --- a/engines/ags/lib/std/map.h +++ b/engines/ags/lib/std/map.h @@ -177,6 +177,19 @@ class map { size_t size() const { return _items.size(); } + + /** + * Returns the number of elements with a matching key + */ + size_t count(const Key &theKey) { + int count = 0; + for (iterator it = this->begin(); it != this->end(); ++it) { + if (it->_key == theKey) + ++count; + } + + return count; + } }; template, diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 72899f2818fc..526a60c7a3d4 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -308,7 +308,14 @@ MODULE_OBJS = \ plugins/ags_pal_render/raycast.o \ plugins/ags_parallax/ags_parallax.o \ plugins/ags_snow_rain/ags_snow_rain.o \ - plugins/ags_snow_rain/weather.o + plugins/ags_snow_rain/weather.o \ + plugins/ags_sprite_font/ags_sprite_font.o \ + plugins/ags_sprite_font/character_entry.o \ + plugins/ags_sprite_font/color.o \ + plugins/ags_sprite_font/sprite_font.o \ + plugins/ags_sprite_font/sprite_font_renderer.o \ + plugins/ags_sprite_font/variable_width_font.o \ + plugins/ags_sprite_font/variable_width_sprite_font.o ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ diff --git a/engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp b/engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp index acbc19801d6d..cf81fb57574f 100644 --- a/engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp +++ b/engines/ags/plugins/ags_sprite_font/ags_sprite_font.cpp @@ -1,33 +1,37 @@ -/*********************************************************** - * AGSBlend * - * * - * Author: Steven Poulton * - * * - * Date: 09/01/2011 * - * * - * Description: An AGS Plugin to allow true Alpha Blending * - * * - ***********************************************************/ - -#pragma region Defines_and_Includes - -#include "core/platform.h" +/* 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 "ags/plugins/ags_sprite_font/ags_sprite_font.h" +#include "ags/shared/core/platform.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { + +#pragma region Defines #define MIN_EDITOR_VERSION 1 #define MIN_ENGINE_VERSION 3 -#if AGS_PLATFORM_OS_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif - -#define THIS_IS_THE_PLUGIN -#include "plugin/agsplugin.h" -#include "SpriteFontRenderer.h" -#include "VariableWidthSpriteFont.h" - - #define DEFAULT_RGB_R_SHIFT_32 16 #define DEFAULT_RGB_G_SHIFT_32 8 #define DEFAULT_RGB_B_SHIFT_32 0 @@ -65,215 +69,71 @@ #pragma endregion +IAGSEngine *AGSSpriteFont::_engine; +SpriteFontRenderer *AGSSpriteFont::_fontRenderer; +VariableWidthSpriteFontRenderer *AGSSpriteFont::_vWidthRenderer; -#if AGS_PLATFORM_OS_WINDOWS -// The standard Windows DLL entry point - -BOOL APIENTRY DllMain(HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved) { - - switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} -#endif - - -//define engine - -IAGSEngine *engine = nullptr; -SpriteFontRenderer *fontRenderer = nullptr; -VariableWidthSpriteFontRenderer *vWidthRenderer = nullptr; - - - -void SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit) { - engine->PrintDebugConsole("AGSSpriteFont: SetSpriteFont"); - fontRenderer->SetSpriteFont(fontNum, sprite, rows, columns, charWidth, charHeight, charMin, charMax, use32bit); - engine->ReplaceFontRenderer(fontNum, fontRenderer); - -} - -void SetVariableSpriteFont(int fontNum, int sprite) { - engine->PrintDebugConsole("AGSSpriteFont: SetVariableFont"); - vWidthRenderer->SetSprite(fontNum, sprite); - engine->ReplaceFontRenderer(fontNum, vWidthRenderer); -} +#define STRINGIFY(s) STRINGIFY_X(s) +#define STRINGIFY_X(s) #s -void SetGlyph(int fontNum, int charNum, int x, int y, int width, int height) { - engine->PrintDebugConsole("AGSSpriteFont: SetGlyph"); - vWidthRenderer->SetGlyph(fontNum, charNum, x, y, width, height); -} +AGSSpriteFont::AGSSpriteFont() : DLL() { + _engine = nullptr; -void SetSpacing(int fontNum, int spacing) { - engine->PrintDebugConsole("AGSSpriteFont: SetSpacing"); - vWidthRenderer->SetSpacing(fontNum, spacing); + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); + DLL_METHOD(AGS_EngineShutdown); } -//============================================================================== -#if AGS_PLATFORM_OS_WINDOWS && !defined(BUILTIN_PLUGINS) -// ***** Design time ***** - -IAGSEditor *editor; // Editor interface - -const char *ourScriptHeader = - "import void SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit);\r\n" - "import void SetVariableSpriteFont(int fontNum, int sprite);\r\n" - "import void SetGlyph(int fontNum, int charNum, int x, int y, int width, int height);\r\n" - "import void SetSpacing(int fontNum, int spacing);\r\n" - ; - -//------------------------------------------------------------------------------ - -LPCSTR AGS_GetPluginName() { - return ("AGSSpriteFont"); +const char *AGSSpriteFont::AGS_GetPluginName() { + return "AGSSpriteFont"; } -//------------------------------------------------------------------------------ - -int AGS_EditorStartup(IAGSEditor *lpEditor) { - // User has checked the plugin to use it in their game - - // If it's an earlier version than what we need, abort. - if (lpEditor->version < MIN_EDITOR_VERSION) - return (-1); - - editor = lpEditor; - editor->RegisterScriptHeader(ourScriptHeader); +void AGSSpriteFont::AGS_EngineStartup(IAGSEngine *engine) { + engine = engine; - // Return 0 to indicate success - return (0); -} - -//------------------------------------------------------------------------------ + _engine->PrintDebugConsole("AGSSpriteFont: Init fixed width renderer"); + _fontRenderer = new SpriteFontRenderer(engine); + _engine->PrintDebugConsole("AGSSpriteFont: Init vari width renderer"); + _vWidthRenderer = new VariableWidthSpriteFontRenderer(engine); + // Make sure it's got the version with the features we need + if (_engine->version < MIN_ENGINE_VERSION) + _engine->AbortGame("Plugin needs engine version " STRINGIFY(MIN_ENGINE_VERSION) " or newer."); -void AGS_EditorShutdown() { - // User has un-checked the plugin from their game - editor->UnregisterScriptHeader(ourScriptHeader); + //register functions + _engine->PrintDebugConsole("AGSSpriteFont: Register functions"); + SCRIPT_METHOD(SetSpriteFont); + SCRIPT_METHOD(SetVariableSpriteFont); + SCRIPT_METHOD(SetGlyph); + SCRIPT_METHOD(SetSpacing); } -//------------------------------------------------------------------------------ - -void AGS_EditorProperties(HWND parent) { //*** optional *** - // User has chosen to view the Properties of the plugin - // We could load up an options dialog or something here instead - MessageBox(parent, - L"AGSSpriteFont v1.0 By Calin Leafshade", - L"About", - MB_OK | MB_ICONINFORMATION); +void AGSSpriteFont::AGS_EngineShutdown() { + delete _fontRenderer; + delete _vWidthRenderer; } -//------------------------------------------------------------------------------ - -int AGS_EditorSaveGame(char *buffer, int bufsize) { //*** optional *** - // Called by the editor when the current game is saved to disk. - // Plugin configuration can be stored in [buffer] (max [bufsize] bytes) - // Return the amount of bytes written in the buffer - return (0); +void AGSSpriteFont::SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit) { + _engine->PrintDebugConsole("AGSSpriteFont: SetSpriteFont"); + _fontRenderer->SetSpriteFont(fontNum, sprite, rows, columns, charWidth, charHeight, charMin, charMax, use32bit); + _engine->ReplaceFontRenderer(fontNum, _fontRenderer); } -//------------------------------------------------------------------------------ - -void AGS_EditorLoadGame(char *buffer, int bufsize) { //*** optional *** - // Called by the editor when a game is loaded from disk - // Previous written data can be read from [buffer] (size [bufsize]). - // Make a copy of the data, the buffer is freed after this function call. +void AGSSpriteFont::SetVariableSpriteFont(int fontNum, int sprite) { + _engine->PrintDebugConsole("AGSSpriteFont: SetVariableFont"); + _vWidthRenderer->SetSprite(fontNum, sprite); + _engine->ReplaceFontRenderer(fontNum, _vWidthRenderer); } -//============================================================================== -#endif - - -// ***** Run time ***** - -// Engine interface - -//------------------------------------------------------------------------------ - -#define REGISTER(x) engine->RegisterScriptFunction(#x, (void *) (x)); -#define STRINGIFY(s) STRINGIFY_X(s) -#define STRINGIFY_X(s) #s - - - -void AGS_EngineStartup(IAGSEngine *lpEngine) { - engine = lpEngine; - engine->PrintDebugConsole("AGSSpriteFont: Init fixed width renderer"); - fontRenderer = new SpriteFontRenderer(engine); - engine->PrintDebugConsole("AGSSpriteFont: Init vari width renderer"); - vWidthRenderer = new VariableWidthSpriteFontRenderer(engine); - // Make sure it's got the version with the features we need - if (engine->version < MIN_ENGINE_VERSION) - engine->AbortGame("Plugin needs engine version " STRINGIFY(MIN_ENGINE_VERSION) " or newer."); - - //register functions - engine->PrintDebugConsole("AGSSpriteFont: Register functions"); - REGISTER(SetSpriteFont) - REGISTER(SetVariableSpriteFont) - REGISTER(SetGlyph) - REGISTER(SetSpacing) +void AGSSpriteFont::SetGlyph(int fontNum, int charNum, int x, int y, int width, int height) { + _engine->PrintDebugConsole("AGSSpriteFont: SetGlyph"); + _vWidthRenderer->SetGlyph(fontNum, charNum, x, y, width, height); } -//------------------------------------------------------------------------------ - -void AGS_EngineShutdown() { - // Called by the game engine just before it exits. - // This gives you a chance to free any memory and do any cleanup - // that you need to do before the engine shuts down. +void AGSSpriteFont::SetSpacing(int fontNum, int spacing) { + _engine->PrintDebugConsole("AGSSpriteFont: SetSpacing"); + _vWidthRenderer->SetSpacing(fontNum, spacing); } -//------------------------------------------------------------------------------ - -int AGS_EngineOnEvent(int event, int data) { //*** optional *** - switch (event) { - /* - case AGSE_KEYPRESS: - case AGSE_MOUSECLICK: - case AGSE_POSTSCREENDRAW: - case AGSE_PRESCREENDRAW: - case AGSE_SAVEGAME: - case AGSE_RESTOREGAME: - case AGSE_PREGUIDRAW: - case AGSE_LEAVEROOM: - case AGSE_ENTERROOM: - case AGSE_TRANSITIONIN: - case AGSE_TRANSITIONOUT: - case AGSE_FINALSCREENDRAW: - case AGSE_TRANSLATETEXT: - case AGSE_SCRIPTDEBUG: - case AGSE_SPRITELOAD: - case AGSE_PRERENDER: - case AGSE_PRESAVEGAME: - case AGSE_POSTRESTOREGAME: - */ - default: - break; - } - - // Return 1 to stop event from processing further (when needed) - return (0); -} - -//------------------------------------------------------------------------------ -/* -int AGS_EngineDebugHook(const char *scriptName, - int lineNum, int reserved) //*** optional *** -{ - // Can be used to debug scripts, see documentation -} -*/ -//------------------------------------------------------------------------------ -/* -void AGS_EngineInitGfx(const char *driverID, void *data) //*** optional *** -{ - // This allows you to make changes to how the graphics driver starts up. - // See documentation -} -*/ -//.............................................................................. +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_sprite_font/ags_sprite_font.h b/engines/ags/plugins/ags_sprite_font/ags_sprite_font.h new file mode 100644 index 000000000000..449c4d7a66d3 --- /dev/null +++ b/engines/ags/plugins/ags_sprite_font/ags_sprite_font.h @@ -0,0 +1,59 @@ +/* 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 AGS_PLUGINS_AGS_SPRITE_FONT_AGS_SPRITE_FONT_H +#define AGS_PLUGINS_AGS_SPRITE_FONT_AGS_SPRITE_FONT_H + +#include "ags/plugins/dll.h" +#include "ags/plugins/serializer.h" +#include "ags/plugins/ags_sprite_font/sprite_font_renderer.h" +#include "ags/plugins/ags_sprite_font/variable_width_sprite_font.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { + +class AGSSpriteFont : public DLL { +private: + static IAGSEngine *_engine; + static SpriteFontRenderer *_fontRenderer; + static VariableWidthSpriteFontRenderer *_vWidthRenderer; +private: + static const char *AGS_GetPluginName(); + static void AGS_EngineStartup(IAGSEngine *lpEngine); + static void AGS_EngineShutdown(); + +private: + static void SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit); + static void SetVariableSpriteFont(int fontNum, int sprite); + static void SetGlyph(int fontNum, int charNum, int x, int y, int width, int height); + static void SetSpacing(int fontNum, int spacing); + +public: + AGSSpriteFont(); +}; + +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_sprite_font/character_entry.cpp b/engines/ags/plugins/ags_sprite_font/character_entry.cpp index fa0575da7f96..41376a17187f 100644 --- a/engines/ags/plugins/ags_sprite_font/character_entry.cpp +++ b/engines/ags/plugins/ags_sprite_font/character_entry.cpp @@ -1,5 +1,30 @@ -#include "CharacterEntry.h" +/* 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 "ags/plugins/ags_sprite_font/character_entry.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { CharacterEntry::CharacterEntry(void) { X = 0; @@ -11,3 +36,7 @@ CharacterEntry::CharacterEntry(void) { CharacterEntry::~CharacterEntry(void) = default; + +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_sprite_font/character_entry.h b/engines/ags/plugins/ags_sprite_font/character_entry.h index 2d2a23f1748c..de782e6d8724 100644 --- a/engines/ags/plugins/ags_sprite_font/character_entry.h +++ b/engines/ags/plugins/ags_sprite_font/character_entry.h @@ -1,4 +1,32 @@ -#pragma once +/* 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 AGS_PLUGINS_AGS_SPRITE_FONT_CHAR_ENTRY_H +#define AGS_PLUGINS_AGS_SPRITE_FONT_CHAR_ENTRY_H + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { + class CharacterEntry { public: CharacterEntry(void); @@ -10,3 +38,8 @@ class CharacterEntry { char Character; }; +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_sprite_font/color.cpp b/engines/ags/plugins/ags_sprite_font/color.cpp index 9e9c13b957fd..298118f41955 100644 --- a/engines/ags/plugins/ags_sprite_font/color.cpp +++ b/engines/ags/plugins/ags_sprite_font/color.cpp @@ -1,4 +1,30 @@ -#include "color.h" +/* 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 "ags/plugins/ags_sprite_font/color.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { int getr32(int c) { return ((c >> DEFAULT_RGB_R_SHIFT_32) & 0xFF); @@ -25,4 +51,8 @@ int makeacol32(int r, int g, int b, int a) { (g << DEFAULT_RGB_G_SHIFT_32) | (b << DEFAULT_RGB_B_SHIFT_32) | (a << DEFAULT_RGB_A_SHIFT_32)); -} \ No newline at end of file +} + +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_sprite_font/color.h b/engines/ags/plugins/ags_sprite_font/color.h index 314f02a50d2b..cd7e1859baed 100644 --- a/engines/ags/plugins/ags_sprite_font/color.h +++ b/engines/ags/plugins/ags_sprite_font/color.h @@ -1,5 +1,31 @@ -#ifndef __COLORH -#define __COLORH +/* 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 AGS_PLUGINS_AGS_SPRITE_FONT_COLOR_H +#define AGS_PLUGINS_AGS_SPRITE_FONT_COLOR_H + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define DEFAULT_RGB_R_SHIFT_32 16 @@ -18,4 +44,8 @@ int makeacol32(int r, int g, int b, int a); #pragma endregion -#endif \ No newline at end of file +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font.cpp b/engines/ags/plugins/ags_sprite_font/sprite_font.cpp index 19e4ea1997af..2681c46752c7 100644 --- a/engines/ags/plugins/ags_sprite_font/sprite_font.cpp +++ b/engines/ags/plugins/ags_sprite_font/sprite_font.cpp @@ -1,7 +1,36 @@ -#include "SpriteFont.h" +/* 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 "ags/plugins/ags_sprite_font/sprite_font.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { SpriteFont::SpriteFont(void) = default; SpriteFont::~SpriteFont(void) = default; + +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font.h b/engines/ags/plugins/ags_sprite_font/sprite_font.h index 860aaddeae96..59259c43443f 100644 --- a/engines/ags/plugins/ags_sprite_font/sprite_font.h +++ b/engines/ags/plugins/ags_sprite_font/sprite_font.h @@ -1,4 +1,32 @@ -#pragma once +/* 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 AGS_PLUGINS_AGS_SPRITE_FONT_SPRITE_FONT_H +#define AGS_PLUGINS_AGS_SPRITE_FONT_SPRITE_FONT_H + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { + class SpriteFont { public: SpriteFont(void); @@ -14,3 +42,8 @@ class SpriteFont { bool Use32bit; }; +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp index c12fca038260..2062456daaea 100644 --- a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp +++ b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp @@ -1,9 +1,31 @@ -#include "SpriteFontRenderer.h" -#include -#include -#include "color.h" - - +/* 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 "ags/plugins/ags_sprite_font/sprite_font_renderer.h" +#include "ags/plugins/ags_sprite_font/color.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { SpriteFontRenderer::SpriteFontRenderer(IAGSEngine *engine) { _engine = engine; @@ -165,7 +187,8 @@ void SpriteFontRenderer::Draw(BITMAP *src, BITMAP *dest, int destx, int desty, i _engine->ReleaseBitmapSurface(src); _engine->ReleaseBitmapSurface(dest); +} - - -} \ No newline at end of file +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h index 0fcd57684f83..7659af774541 100644 --- a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h +++ b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h @@ -1,7 +1,36 @@ -#pragma once -#include "plugin/agsplugin.h" -#include "SpriteFont.h" -#include +/* 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 AGS_PLUGINS_AGS_SPRITE_FONT_SPR_FONT_RENDERER_H +#define AGS_PLUGINS_AGS_SPRITE_FONT_SPR_FONT_RENDERER_H + +#include "ags/plugins/ags_sprite_font/sprite_font.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/lib/std/vector.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { + class SpriteFontRenderer : public IAGSFontRenderer { public: @@ -19,7 +48,6 @@ class SpriteFontRenderer : void EnsureTextValidForFont(char *text, int fontNumber) override; void SetSpriteFont(int fontNum, int sprite, int rows, int columns, int charWidth, int charHeight, int charMin, int charMax, bool use32bit); - private: SpriteFont *getFontFor(int fontNum); void Draw(BITMAP *src, BITMAP *dest, int destx, int desty, int srcx, int srcy, int width, int height); @@ -27,3 +55,8 @@ class SpriteFontRenderer : IAGSEngine *_engine; }; +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_font.cpp b/engines/ags/plugins/ags_sprite_font/variable_width_font.cpp index 41baaac170ce..5361439b0dba 100644 --- a/engines/ags/plugins/ags_sprite_font/variable_width_font.cpp +++ b/engines/ags/plugins/ags_sprite_font/variable_width_font.cpp @@ -1,5 +1,30 @@ -#include "VariableWidthFont.h" +/* 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 "ags/plugins/ags_sprite_font/variable_width_font.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { VariableWidthFont::VariableWidthFont(void) { Spacing = 0; @@ -17,3 +42,7 @@ void VariableWidthFont::SetGlyph(int character, int x, int y, int width, int hei characters[character].Height = height; characters[character].Character = character; } + +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_font.h b/engines/ags/plugins/ags_sprite_font/variable_width_font.h index 8eda7123cff0..5eb5bccbdd73 100644 --- a/engines/ags/plugins/ags_sprite_font/variable_width_font.h +++ b/engines/ags/plugins/ags_sprite_font/variable_width_font.h @@ -1,7 +1,36 @@ -#pragma once -#include -#include "CharacterEntry.h" -#include "plugin/agsplugin.h" +/* 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 AGS_PLUGINS_AGS_SPRITE_FONT_VAR_WIDTH_FONT_H +#define AGS_PLUGINS_AGS_SPRITE_FONT_VAR_WIDTH_FONT_H + +#include "ags/plugins/ags_sprite_font/character_entry.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/lib/std/map.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { + class VariableWidthFont { public: VariableWidthFont(void); @@ -11,8 +40,10 @@ class VariableWidthFont { int FontReplaced; int Spacing; std::map characters; - -private: - }; +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp index b6015ef8e1e7..827b686e9995 100644 --- a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp +++ b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.cpp @@ -1,9 +1,31 @@ -#include "VariableWidthSpriteFont.h" -#include -#include -#include "color.h" - - +/* 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 "ags/plugins/ags_sprite_font/variable_width_sprite_font.h" +#include "ags/plugins/ags_sprite_font/color.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { VariableWidthSpriteFontRenderer::VariableWidthSpriteFontRenderer(IAGSEngine *engine) { _engine = engine; @@ -22,7 +44,7 @@ bool VariableWidthSpriteFontRenderer::SupportsExtendedCharacters(int fontNumber) int VariableWidthSpriteFontRenderer::GetTextWidth(const char *text, int fontNumber) { int total = 0; VariableWidthFont *font = getFontFor(fontNumber); - for (int i = 0; i < strlen(text); i++) { + for (int i = 0; i < (int)strlen(text); i++) { if (font->characters.count(text[i]) > 0) { total += font->characters[text[i]].Width; if (text[i] != ' ') total += font->Spacing; @@ -33,7 +55,7 @@ int VariableWidthSpriteFontRenderer::GetTextWidth(const char *text, int fontNumb int VariableWidthSpriteFontRenderer::GetTextHeight(const char *text, int fontNumber) { VariableWidthFont *font = getFontFor(fontNumber); - for (int i = 0; i < strlen(text); i++) { + for (int i = 0; i < (int)strlen(text); i++) { if (font->characters.count(text[i]) > 0) { return font->characters[text[i]].Height; } @@ -50,9 +72,9 @@ void VariableWidthSpriteFontRenderer::SetSpacing(int fontNum, int spacing) { void VariableWidthSpriteFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) { VariableWidthFont *font = getFontFor(fontNumber); - std::string s(text); + Common::String s(text); - for (int i = s.length() - 1; i >= 0 ; i--) { + for (int i = (int)s.size() - 1; i >= 0 ; i--) { if (font->characters.count(s[i]) == 0) { s.erase(i, 1); } @@ -74,7 +96,7 @@ void VariableWidthSpriteFontRenderer::SetSprite(int fontNum, int spriteNum) { VariableWidthFont *VariableWidthSpriteFontRenderer::getFontFor(int fontNum) { VariableWidthFont *font; - for (int i = 0; i < _fonts.size(); i ++) { + for (int i = 0; i < (int)_fonts.size(); i ++) { font = _fonts.at(i); if (font->FontReplaced == fontNum) return font; } @@ -88,7 +110,7 @@ VariableWidthFont *VariableWidthSpriteFontRenderer::getFontFor(int fontNum) { void VariableWidthSpriteFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) { VariableWidthFont *font = getFontFor(fontNumber); int totalWidth = 0; - for (int i = 0; i < strlen(text); i++) { + for (int i = 0; i < (int)strlen(text); i++) { char c = text[i]; BITMAP *src = _engine->GetSpriteGraphic(font->SpriteNumber); @@ -175,8 +197,8 @@ void VariableWidthSpriteFontRenderer::Draw(BITMAP *src, BITMAP *dest, int destx, _engine->ReleaseBitmapSurface(src); _engine->ReleaseBitmapSurface(dest); - - - } +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h index 30b5211ca387..edfffa4d5d89 100644 --- a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h +++ b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h @@ -1,7 +1,37 @@ -#pragma once -#include "plugin/agsplugin.h" -#include "VariableWidthFont.h" -#include +/* 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 AGS_PLUGINS_AGS_SPRITE_FONT_VAR_WIDTH_SPR_FONT_H +#define AGS_PLUGINS_AGS_SPRITE_FONT_VAR_WIDTH_SPR_FONT_H + +#include "ags/plugins/dll.h" +#include "ags/plugins/serializer.h" +#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/ags_sprite_font/variable_width_font.h" + +namespace AGS3 { +namespace Plugins { +namespace AGSSpriteFont { + class VariableWidthSpriteFontRenderer : public IAGSFontRenderer { public: @@ -28,3 +58,8 @@ class VariableWidthSpriteFontRenderer : void Draw(BITMAP *src, BITMAP *dest, int destx, int desty, int srcx, int srcy, int width, int height); }; +} // namespace AGSSpriteFont +} // namespace Plugins +} // namespace AGS3 + +#endif diff --git a/engines/ags/plugins/dll.cpp b/engines/ags/plugins/dll.cpp index 4d3554b5cedc..e629c2a438cf 100644 --- a/engines/ags/plugins/dll.cpp +++ b/engines/ags/plugins/dll.cpp @@ -27,6 +27,7 @@ #include "ags/plugins/ags_flashlight/ags_flashlight.h" #include "ags/plugins/ags_pal_render/ags_pal_render.h" #include "ags/plugins/ags_snow_rain/ags_snow_rain.h" +#include "ags/plugins/ags_sprite_font/ags_sprite_font.h" #include "ags/ags.h" #include "ags/detection.h" #include "common/str.h" @@ -66,6 +67,9 @@ void *dlopen(const char *filename) { if (fname.equalsIgnoreCase("libAGSSnowRain.so")) return new AGSSnowRain::AGSSnowRain(); + if (fname.equalsIgnoreCase("libAGSSpriteFont.so")) + return new AGSSpriteFont::AGSSpriteFont(); + return nullptr; } From 7bb7bcfb546699097d9b83851fac83e18834b360 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jan 2021 22:23:09 -0800 Subject: [PATCH 179/215] AGS: gcc compilation fixes --- engines/ags/engine/plugin/agsplugin.h | 1 + .../plugins/ags_flashlight/ags_flashlight.cpp | 54 +++++++------- .../plugins/ags_pal_render/ags_pal_render.cpp | 28 +++++--- .../ags/plugins/ags_pal_render/raycast.cpp | 70 ++++++++++--------- .../ags/plugins/ags_parallax/ags_parallax.cpp | 6 +- .../plugins/ags_snow_rain/ags_snow_rain.cpp | 48 ++++++------- engines/ags/plugins/ags_snow_rain/weather.cpp | 2 +- .../ags_sprite_font/sprite_font_renderer.cpp | 11 ++- .../ags_sprite_font/sprite_font_renderer.h | 5 +- .../variable_width_sprite_font.h | 5 +- 10 files changed, 120 insertions(+), 110 deletions(-) diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/engine/plugin/agsplugin.h index 3f564c214cf6..2ab5b3873c39 100644 --- a/engines/ags/engine/plugin/agsplugin.h +++ b/engines/ags/engine/plugin/agsplugin.h @@ -31,6 +31,7 @@ #ifndef AGS_ENGINE_PLUGIN_AGSPLUGIN_H #define AGS_ENGINE_PLUGIN_AGSPLUGIN_H +#include "ags/shared/core/types.h" #include "common/array.h" namespace AGS3 { diff --git a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp index 116c4a044953..cccddec62d30 100644 --- a/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp +++ b/engines/ags/plugins/ags_flashlight/ags_flashlight.cpp @@ -126,41 +126,41 @@ void AGSFlashlight::AGS_EngineStartup(IAGSEngine *engine) { if (_engine->version < 13) _engine->AbortGame("Engine interface is too old, need newer version of AGS."); - SCRIPT_METHOD("SetFlashlightTint"); - SCRIPT_METHOD("GetFlashlightTintRed"); - SCRIPT_METHOD("GetFlashlightTintGreen"); - SCRIPT_METHOD("GetFlashlightTintBlue"); + SCRIPT_METHOD(SetFlashlightTint); + SCRIPT_METHOD(GetFlashlightTintRed); + SCRIPT_METHOD(GetFlashlightTintGreen); + SCRIPT_METHOD(GetFlashlightTintBlue); - SCRIPT_METHOD("GetFlashlightMinLightLevel"); - SCRIPT_METHOD("GetFlashlightMaxLightLevel"); + SCRIPT_METHOD(GetFlashlightMinLightLevel); + SCRIPT_METHOD(GetFlashlightMaxLightLevel); - SCRIPT_METHOD("SetFlashlightDarkness"); - SCRIPT_METHOD("GetFlashlightDarkness"); - SCRIPT_METHOD("SetFlashlightDarknessSize"); - SCRIPT_METHOD("GetFlashlightDarknessSize"); + SCRIPT_METHOD(SetFlashlightDarkness); + SCRIPT_METHOD(GetFlashlightDarkness); + SCRIPT_METHOD(SetFlashlightDarknessSize); + SCRIPT_METHOD(GetFlashlightDarknessSize); - SCRIPT_METHOD("SetFlashlightBrightness"); - SCRIPT_METHOD("GetFlashlightBrightness"); - SCRIPT_METHOD("SetFlashlightBrightnessSize"); - SCRIPT_METHOD("GetFlashlightBrightnessSize"); + SCRIPT_METHOD(SetFlashlightBrightness); + SCRIPT_METHOD(GetFlashlightBrightness); + SCRIPT_METHOD(SetFlashlightBrightnessSize); + SCRIPT_METHOD(GetFlashlightBrightnessSize); - SCRIPT_METHOD("SetFlashlightPosition"); - SCRIPT_METHOD("GetFlashlightPositionX"); - SCRIPT_METHOD("GetFlashlightPositionY"); + SCRIPT_METHOD(SetFlashlightPosition); + SCRIPT_METHOD(GetFlashlightPositionX); + SCRIPT_METHOD(GetFlashlightPositionY); - SCRIPT_METHOD("SetFlashlightFollowMouse"); - SCRIPT_METHOD("GetFlashlightFollowMouse"); + SCRIPT_METHOD(SetFlashlightFollowMouse); + SCRIPT_METHOD(GetFlashlightFollowMouse); - SCRIPT_METHOD("SetFlashlightFollowCharacter"); - SCRIPT_METHOD("GetFlashlightFollowCharacter"); - SCRIPT_METHOD("GetFlashlightCharacterDX"); - SCRIPT_METHOD("GetFlashlightCharacterDY"); - SCRIPT_METHOD("GetFlashlightCharacterHorz"); - SCRIPT_METHOD("GetFlashlightCharacterVert"); + SCRIPT_METHOD(SetFlashlightFollowCharacter); + SCRIPT_METHOD(GetFlashlightFollowCharacter); + SCRIPT_METHOD(GetFlashlightCharacterDX); + SCRIPT_METHOD(GetFlashlightCharacterDY); + SCRIPT_METHOD(GetFlashlightCharacterHorz); + SCRIPT_METHOD(GetFlashlightCharacterVert); - SCRIPT_METHOD("SetFlashlightMask"); - SCRIPT_METHOD("GetFlashlightMask"); + SCRIPT_METHOD(SetFlashlightMask); + SCRIPT_METHOD(GetFlashlightMask); _engine->RequestEventHook(AGSE_PREGUIDRAW); _engine->RequestEventHook(AGSE_PRESCREENDRAW); diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp index b7467a09f5a4..58f89b6eb32e 100644 --- a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp +++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp @@ -1068,14 +1068,18 @@ int GetTranslucentOverlayAlpha(int id) { } int SetTranslucentOverlayAlpha(int id, int alpha) { - if (alpha >= 0 && alpha < 256) overlay[id].trans = alpha; - else engine->AbortGame("CreateTranslucentOverlay: Invalid alpha selected."); + if (alpha >= 0 && alpha < 256) + overlay[id].trans = alpha; + else + engine->AbortGame("CreateTranslucentOverlay: Invalid alpha selected."); return 0; } int SetTranslucentOverlayEnabled(int id, int toggle) { - if (toggle > 0) overlay[id].enabled = true; - else overlay[id].enabled = false; + if (toggle > 0) + overlay[id].enabled = true; + else + overlay[id].enabled = false; return 0; } @@ -1085,16 +1089,18 @@ void SetCharacterReflected(int id, int refl) { } void SetObjectReflected(int id, int refl) { - if (refl > 0) Reflection.Objects[id].reflect = 1; - else Reflection.Objects[id].reflect = 0; + if (refl > 0) + Reflection.Objects[id].reflect = 1; + else + Reflection.Objects[id].reflect = 0; } int GetCharacterReflected(int id) { return Reflection.Characters[id].reflect; } -void GetObjectReflected(int id) { - Reflection.Objects[id].reflect; +int GetObjectReflected(int id) { + return Reflection.Objects[id].reflect; } void ReplaceCharacterReflectionView(int id, int view) { @@ -1131,9 +1137,10 @@ int DrawReflections(int id, int charobj = 0) { //Get character, and their sprite. if (charobj == 0) { currchar = engine->GetCharacter(id); - int view = 0; + /*int view = 0; if (Reflection.Characters[id].replaceview == 0) view = currchar->view + 1; else view = Reflection.Characters[id].replaceview; + */ AGSViewFrame *vf = engine->GetViewFrame(currchar->view + 1, currchar->loop, currchar->frame); charsprite = engine->GetSpriteGraphic(vf->pic); long scaling = currchar->flags & CHF_NOSCALING; @@ -1270,8 +1277,7 @@ int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blen if (mask > 0) maskspr = engine->GetSpriteGraphic(mask); if (!maskspr && mask > 0) { char maskerr [100]; - int cx; - cx = snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask); + snprintf(maskerr, 100, "DrawTransSprite: Can't load mask from slot %d.", mask); engine->AbortGame(maskerr); } // Get a reference to the screen we'll draw onto diff --git a/engines/ags/plugins/ags_pal_render/raycast.cpp b/engines/ags/plugins/ags_pal_render/raycast.cpp index fe26cfb8bbe7..405c7550c7e0 100644 --- a/engines/ags/plugins/ags_pal_render/raycast.cpp +++ b/engines/ags/plugins/ags_pal_render/raycast.cpp @@ -111,21 +111,21 @@ int Ray_GetNoClip() { } void Ray_DrawTile(int spr, int tile) { - BITMAP *sprite = engine->GetSpriteGraphic(spr); - unsigned char **sprarray = engine->GetRawBitmapSurface(sprite); + BITMAP *img = engine->GetSpriteGraphic(spr); + unsigned char **sprarray = engine->GetRawBitmapSurface(img); for (int y = 0; y < 64; ++y) for (int x = 0; x < 64; ++x) sprarray [y][x] = texture [tile][(texWidth * y) + x]; - engine->ReleaseBitmapSurface(sprite); + engine->ReleaseBitmapSurface(img); } void Ray_DrawOntoTile(int spr, int tile) { - BITMAP *sprite = engine->GetSpriteGraphic(spr); - unsigned char **sprarray = engine->GetRawBitmapSurface(sprite); + BITMAP *img = engine->GetSpriteGraphic(spr); + unsigned char **sprarray = engine->GetRawBitmapSurface(img); for (int y = 0; y < 64; ++y) for (int x = 0; x < 64; ++x) texture [tile][(texWidth * y) + x] = sprarray [y][x]; - engine->ReleaseBitmapSurface(sprite); + engine->ReleaseBitmapSurface(img); } int Ray_GetTileX_At(int x, int y) { @@ -351,14 +351,14 @@ void LoadHeightMap(int heightmapSlot) { void LoadMap(int worldmapSlot, int lightmapSlot, int ceilingmapSlot, int floormapSlot) { int tempw = engine->GetSpriteWidth(worldmapSlot); int temph = engine->GetSpriteHeight(worldmapSlot); - BITMAP *worldmapBm; - BITMAP *lightmapBm; - BITMAP *floormapBm; - BITMAP *ceilingmapBm; - unsigned char **wmArray; - unsigned char **lmArray; - unsigned char **fmArray; - unsigned char **cmArray; + BITMAP *worldmapBm = nullptr; + BITMAP *lightmapBm = nullptr; + BITMAP *floormapBm = nullptr; + BITMAP *ceilingmapBm = nullptr; + unsigned char **wmArray = nullptr; + unsigned char **lmArray = nullptr; + unsigned char **fmArray = nullptr; + unsigned char **cmArray = nullptr; worldmapBm = engine->GetSpriteGraphic(worldmapSlot); if (!worldmapBm) engine->AbortGame("LoadMap: Couldn't load worldmap sprite into memory."); wmArray = engine->GetRawBitmapSurface(worldmapBm); @@ -533,7 +533,7 @@ void MakeTextures(int slot) { unsigned char **texbuffer = engine->GetRawBitmapSurface(texspr); int numTilesX = sourceWidth / texWidth; int numTilesY = sourceHeight / texHeight; - int totaltiles = numTilesX * numTilesY; + //int totaltiles = numTilesX * numTilesY; for (int numX = 0; numX < numTilesX; ++numX) { for (int numY = 0; numY < numTilesY; ++numY) { for (int x = 0; x < texWidth; ++x) @@ -648,8 +648,9 @@ FLOAT_RETURN_TYPE Ray_GetDistanceAt(int x, int y) { } void Init_Raycaster() { - if (ZBuffer) return; - if (!worldMap) return; + if (ZBuffer) + return; + //if (!worldMap) return; transcolorbuffer = new unsigned char *[sWidth]; transalphabuffer = new unsigned char *[sWidth]; transslicedrawn = new bool[sWidth](); @@ -683,7 +684,7 @@ void Raycast_Render(int slot) { BITMAP *sbBm = engine->GetSpriteGraphic(skybox); if (!sbBm) engine->AbortGame("Raycast_Render: No valid skybox sprite."); if (skybox > 0) { - int bgdeg = (int)((playerrad / PI) * 180.0) + 180; + //int bgdeg = (int)((playerrad / PI) * 180.0) + 180; int xoffset = (int)(playerrad * 320.0); BITMAP *virtsc = engine->GetVirtualScreen(); engine->SetVirtualScreen(screen); @@ -702,7 +703,7 @@ void Raycast_Render(int slot) { ZBuffer[x][y] = 0; } } - int multiplier = mapWidth; + //int multiplier = mapWidth; memset(interactionmap, 0, sizeof(short) * (sHeight * sWidth)); //start the main loop for (int x = 0; x < w; x++) { @@ -725,7 +726,7 @@ void Raycast_Render(int slot) { //length of ray from one x or y-side to next x or y-side double deltaDistX = fsqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX)); double deltaDistY = fsqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY)); - double perpWallDist; + double perpWallDist = 0.0; //what direction to step in x or y-direction (either +1 or -1) int stepX; @@ -733,7 +734,7 @@ void Raycast_Render(int slot) { int prevmapX = 0; int prevmapY = 0; int hit = 0; //was there a wall hit? - int side; //was a NS or a EW wall hit? + int side = 0; //was a NS or a EW wall hit? //calculate step and initial sideDist if (rayDirX < 0) { @@ -750,13 +751,13 @@ void Raycast_Render(int slot) { stepY = 1; sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY; } - //perform DDA + // Perform DDA bool deeper = true; bool opposite = true; bool oppositedrawn = false; - double wallX; //where exactly the wall was hit + double wallX = 0; // Where exactly the wall was hit int drawStart; - int drawEnd; + int drawEnd = 0; while (hit == 0 && deeper == true) { if (opposite) { rayDirX = -rayDirX; @@ -765,7 +766,7 @@ void Raycast_Render(int slot) { stepY = -stepY; if (sideDistX < sideDistY) side = 0; else side = 1; - } else if (sideDistX < sideDistY) { //jump to next map square, OR in x-direction, OR in y-direction + } else if (sideDistX < sideDistY) { // jump to next map square, OR in x-direction, OR in y-direction sideDistX += deltaDistX; mapX += stepX; mapX = abs(mapX) % mapHeight; @@ -802,7 +803,7 @@ void Raycast_Render(int slot) { opposite = false; } } - int texside; + int texside = 0; if (rayDirX > 0 && side == 0) texside = 0; if (rayDirX < 0 && side == 0) texside = 1; if (rayDirY > 0 && side == 1) texside = 2; @@ -976,6 +977,10 @@ void Raycast_Render(int slot) { //End of loop. } + // Unused variables + (void)prevmapX; + (void)prevmapY; + //FLOOR CASTING double floorXWall, floorYWall; //x, y position of the floor texel at the bottom of the wall @@ -1002,7 +1007,8 @@ void Raycast_Render(int slot) { distWall = perpWallDist; distPlayer = 0.0; - if (drawEnd < 0) drawEnd = h - 1; //becomes < 0 when the integer overflows + if (drawEnd < 0) + drawEnd = h - 1; //becomes < 0 when the integer overflows //draw the floor from drawEnd to the bottom of the screen int drawdist = h; int expandeddraw = h >> 1; @@ -1010,7 +1016,7 @@ void Raycast_Render(int slot) { //currentDist = h / (2.0 * y - h); //you could make a small lookup table for this instead currentDist = distTable[y]; if (y > h - 1) { - if (!heightMap) break; + //if (!heightMap) break; double weight = (currentDist - distPlayer) / (distWall - distPlayer); double currentFloorX = weight * floorXWall + (1.0 - weight) * posX; @@ -1045,7 +1051,7 @@ void Raycast_Render(int slot) { if (floorcolor) floorcolor = Mix::MixColorLightLevel(floorcolor, lighting); } - if (heightMap && floorcolor > 0) { + if (/*heightMap &&*/ floorcolor > 0) { if (heightMap[cmapX][cmapY] - 1 > 0) { int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texpos] / currentDist); if (raisedfloorstart > h - 1) continue; @@ -1093,7 +1099,7 @@ void Raycast_Render(int slot) { if (ceilingcolor) ceilingcolor = Mix::MixColorLightLevel(ceilingcolor, lighting); } - if (heightMap && floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) { + if (/*heightMap &&*/ floorcolor > 0 && (currentDist < ZBuffer[x][y] || ZBuffer[x][y] == 0)) { if (heightMap[cmapX][cmapY] - 1 > 0) { int raisedfloorstart = y - (int)(texture[heightMap[cmapX][cmapY] - 1][texWidth * floorTexY + floorTexX] / currentDist); if (raisedfloorstart > h - 1) continue; @@ -1210,8 +1216,8 @@ void Raycast_Render(int slot) { // [ planeY dirY ] [ -planeY planeX ] //double invDet = 1.0 / (planeX * dirY - dirX * planeY); //required for correct matrix multiplication - double spriteX = sprite[spriteOrder[i]].x - posX; - double spriteY = sprite[spriteOrder[i]].y - posY; + //double spriteX = sprite[spriteOrder[i]].x - posX; + //double spriteY = sprite[spriteOrder[i]].y - posY; //double transformX = invDet * (dirY * spriteX - dirX * spriteY); //double transformY = invDet * (-planeY * spriteX + planeX * spriteY); //this is actually the depth inside the screen, that what Z is in 3D diff --git a/engines/ags/plugins/ags_parallax/ags_parallax.cpp b/engines/ags/plugins/ags_parallax/ags_parallax.cpp index 1bb6eff35497..0a7b123e74f2 100644 --- a/engines/ags/plugins/ags_parallax/ags_parallax.cpp +++ b/engines/ags/plugins/ags_parallax/ags_parallax.cpp @@ -62,8 +62,8 @@ void AGSParallax::AGS_EngineStartup(IAGSEngine *engine) { if (_engine->version < 13) _engine->AbortGame("Engine interface is too old, need newer version of AGS."); - SCRIPT_METHOD("pxDrawSprite"); - SCRIPT_METHOD("pxDeleteSprite"); + SCRIPT_METHOD(pxDrawSprite); + SCRIPT_METHOD(pxDeleteSprite); _engine->RequestEventHook(AGSE_PREGUIDRAW); _engine->RequestEventHook(AGSE_PRESCREENDRAW); @@ -107,7 +107,7 @@ void AGSParallax::clear() { void AGSParallax::SyncGame(Serializer &s) { int saveVersion = SaveMagic; s.syncAsInt(saveVersion); - if (saveVersion != SaveMagic) { + if ((uint)saveVersion != SaveMagic) { _engine->AbortGame("ags_parallax: bad save."); return; } diff --git a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp index 36caa399997e..92764acc2535 100644 --- a/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp +++ b/engines/ags/plugins/ags_snow_rain/ags_snow_rain.cpp @@ -57,30 +57,30 @@ void AGSSnowRain::AGS_EngineStartup(IAGSEngine *engine) { if (_engine->version < 13) _engine->AbortGame("Engine interface is too old, need newer version of AGS."); - SCRIPT_METHOD("srSetSnowDriftRange"); - SCRIPT_METHOD("srSetSnowDriftSpeed"); - SCRIPT_METHOD("srSetSnowFallSpeed"); - SCRIPT_METHOD("srChangeSnowAmount"); - SCRIPT_METHOD("srSetSnowBaseline"); - SCRIPT_METHOD("srSetSnowTransparency"); - SCRIPT_METHOD("srSetSnowDefaultView"); - SCRIPT_METHOD("srSetSnowWindSpeed"); - SCRIPT_METHOD("srSetSnowAmount"); - SCRIPT_METHOD("srSetSnowView"); - - SCRIPT_METHOD("srSetRainDriftRange"); - SCRIPT_METHOD("srSetRainDriftSpeed"); - SCRIPT_METHOD("srSetRainFallSpeed"); - SCRIPT_METHOD("srChangeRainAmount"); - SCRIPT_METHOD("srSetRainBaseline"); - SCRIPT_METHOD("srSetRainTransparency"); - SCRIPT_METHOD("srSetRainDefaultView"); - SCRIPT_METHOD("srSetRainWindSpeed"); - SCRIPT_METHOD("srSetRainAmount"); - SCRIPT_METHOD("srSetRainView"); - - SCRIPT_METHOD("srSetWindSpeed"); - SCRIPT_METHOD("srSetBaseline"); + SCRIPT_METHOD(srSetSnowDriftRange); + SCRIPT_METHOD(srSetSnowDriftSpeed); + SCRIPT_METHOD(srSetSnowFallSpeed); + SCRIPT_METHOD(srChangeSnowAmount); + SCRIPT_METHOD(srSetSnowBaseline); + SCRIPT_METHOD(srSetSnowTransparency); + SCRIPT_METHOD(srSetSnowDefaultView); + SCRIPT_METHOD(srSetSnowWindSpeed); + SCRIPT_METHOD(srSetSnowAmount); + SCRIPT_METHOD(srSetSnowView); + + SCRIPT_METHOD(srSetRainDriftRange); + SCRIPT_METHOD(srSetRainDriftSpeed); + SCRIPT_METHOD(srSetRainFallSpeed); + SCRIPT_METHOD(srChangeRainAmount); + SCRIPT_METHOD(srSetRainBaseline); + SCRIPT_METHOD(srSetRainTransparency); + SCRIPT_METHOD(srSetRainDefaultView); + SCRIPT_METHOD(srSetRainWindSpeed); + SCRIPT_METHOD(srSetRainAmount); + SCRIPT_METHOD(srSetRainView); + + SCRIPT_METHOD(srSetWindSpeed); + SCRIPT_METHOD(srSetBaseline); _engine->RequestEventHook(AGSE_PREGUIDRAW); _engine->RequestEventHook(AGSE_PRESCREENDRAW); diff --git a/engines/ags/plugins/ags_snow_rain/weather.cpp b/engines/ags/plugins/ags_snow_rain/weather.cpp index 3798067749d0..c744be9bd7bc 100644 --- a/engines/ags/plugins/ags_snow_rain/weather.cpp +++ b/engines/ags/plugins/ags_snow_rain/weather.cpp @@ -137,7 +137,7 @@ void Weather::SyncGame(Serializer &s) { int saveVersion = SaveMagic; s.syncAsInt(saveVersion); - if (s.isLoading() && saveVersion != SaveMagic) { + if (s.isLoading() && (uint)saveVersion != SaveMagic) { _engine->AbortGame("ags_snowrain: bad save."); return; } diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp index 2062456daaea..ed06779cf9de 100644 --- a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp +++ b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.cpp @@ -49,7 +49,7 @@ void SpriteFontRenderer::SetSpriteFont(int fontNum, int sprite, int rows, int co void SpriteFontRenderer::EnsureTextValidForFont(char *text, int fontNumber) { SpriteFont *font = getFontFor(fontNumber); - for (int i = 0; i < strlen(text); i++) { + for (int i = 0; i < (int)strlen(text); i++) { if (text[i] < font->MinChar || text[i] > font->MaxChar) { if (font->MinChar < 63 || font->MaxChar > 63) text[i] = 63; else text[i] = font->MinChar; @@ -65,7 +65,7 @@ bool SpriteFontRenderer::SupportsExtendedCharacters(int fontNumber) { int SpriteFontRenderer::GetTextWidth(const char *text, int fontNumber) { SpriteFont *font = getFontFor(fontNumber); - int len = strlen(text); + int len = (int)strlen(text); return font->CharWidth * len; } @@ -77,7 +77,7 @@ int SpriteFontRenderer::GetTextHeight(const char *text, int fontNumber) { SpriteFont *SpriteFontRenderer::getFontFor(int fontNum) { SpriteFont *font; - for (int i = 0; i < _fonts.size(); i ++) { + for (int i = 0; i < (int)_fonts.size(); i ++) { font = _fonts.at(i); if (font->FontReplaced == fontNum) return font; } @@ -91,13 +91,12 @@ SpriteFont *SpriteFontRenderer::getFontFor(int fontNum) { void SpriteFontRenderer::RenderText(const char *text, int fontNumber, BITMAP *destination, int x, int y, int colour) { - SpriteFont *font = getFontFor(fontNumber); - BITMAP *vScreen = _engine->GetVirtualScreen(); + //BITMAP *vScreen = _engine->GetVirtualScreen(); //_engine->SetVirtualScreen(destination); - for (int i = 0; i < strlen(text); i++) { + for (int i = 0; i < (int)strlen(text); i++) { char c = text[i]; c -= font->MinChar; int row = c / font->Columns; diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h index 7659af774541..a5f2f373a024 100644 --- a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h +++ b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h @@ -31,11 +31,10 @@ namespace AGS3 { namespace Plugins { namespace AGSSpriteFont { -class SpriteFontRenderer : - public IAGSFontRenderer { +class SpriteFontRenderer : public IAGSFontRenderer { public: SpriteFontRenderer(IAGSEngine *engine); - ~SpriteFontRenderer(void); + virtual ~SpriteFontRenderer(void); bool LoadFromDisk(int fontNumber, int fontSize) override { return true; } diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h index edfffa4d5d89..5625d21c1eb2 100644 --- a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h +++ b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h @@ -32,11 +32,10 @@ namespace AGS3 { namespace Plugins { namespace AGSSpriteFont { -class VariableWidthSpriteFontRenderer : - public IAGSFontRenderer { +class VariableWidthSpriteFontRenderer : public IAGSFontRenderer { public: VariableWidthSpriteFontRenderer(IAGSEngine *engine); - ~VariableWidthSpriteFontRenderer(void); + virtual ~VariableWidthSpriteFontRenderer(); bool LoadFromDisk(int fontNumber, int fontSize) override { return true; } From 35c2b0f08e8b516d834955b23f1524da01875e58 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 25 Jan 2021 19:40:32 -0800 Subject: [PATCH 180/215] AGS: Merged engine/plugin/ into plugins/ folder --- engines/ags/engine/ac/draw.cpp | 4 ++-- engines/ags/engine/ac/dynobj/cc_serializer.cpp | 4 ++-- engines/ags/engine/ac/event.cpp | 4 ++-- engines/ags/engine/ac/game.cpp | 4 ++-- engines/ags/engine/ac/global_translation.cpp | 4 ++-- engines/ags/engine/ac/room.cpp | 4 ++-- engines/ags/engine/ac/screen.cpp | 4 ++-- engines/ags/engine/ac/sprite.cpp | 4 ++-- engines/ags/engine/debugging/debug.cpp | 2 +- engines/ags/engine/game/game_init.cpp | 2 +- engines/ags/engine/game/savegame.cpp | 4 ++-- engines/ags/engine/game/savegame_components.cpp | 4 ++-- engines/ags/engine/main/game_file.cpp | 2 +- engines/ags/engine/main/game_run.cpp | 4 ++-- engines/ags/engine/main/quit.cpp | 2 +- engines/ags/engine/platform/base/agsplatformdriver.cpp | 2 +- engines/ags/engine/platform/linux/acpllnx.cpp | 2 +- engines/ags/engine/script/script_runtime.cpp | 2 +- engines/ags/engine/util/library_posix.h | 2 +- engines/ags/module.mk | 8 ++++---- engines/ags/plugins/ags_pal_render/pal_render.h | 2 +- engines/ags/{engine/plugin => plugins}/agsplugin.cpp | 8 ++++---- engines/ags/{engine/plugin => plugins}/agsplugin.h | 0 engines/ags/plugins/dll.h | 2 +- engines/ags/{engine/plugin => plugins}/global_plugin.cpp | 0 engines/ags/{engine/plugin => plugins}/library.cpp | 2 +- engines/ags/{engine/plugin => plugins}/library.h | 0 engines/ags/{engine/plugin => plugins}/plugin_builtin.h | 0 engines/ags/{engine/plugin => plugins}/plugin_engine.h | 0 .../ags/{engine/plugin => plugins}/pluginobjectreader.cpp | 2 +- .../ags/{engine/plugin => plugins}/pluginobjectreader.h | 0 engines/ags/plugins/serializer.h | 2 +- 32 files changed, 43 insertions(+), 43 deletions(-) rename engines/ags/{engine/plugin => plugins}/agsplugin.cpp (99%) rename engines/ags/{engine/plugin => plugins}/agsplugin.h (100%) rename engines/ags/{engine/plugin => plugins}/global_plugin.cpp (100%) rename engines/ags/{engine/plugin => plugins}/library.cpp (97%) rename engines/ags/{engine/plugin => plugins}/library.h (100%) rename engines/ags/{engine/plugin => plugins}/plugin_builtin.h (100%) rename engines/ags/{engine/plugin => plugins}/plugin_engine.h (100%) rename engines/ags/{engine/plugin => plugins}/pluginobjectreader.cpp (95%) rename engines/ags/{engine/plugin => plugins}/pluginobjectreader.h (100%) diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp index c559768d7366..69714f99ea4a 100644 --- a/engines/ags/engine/ac/draw.cpp +++ b/engines/ags/engine/ac/draw.cpp @@ -61,8 +61,8 @@ #include "ags/shared/font/fonts.h" #include "ags/shared/gui/guimain.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/ac/spritecache.h" #include "ags/engine/gfx/gfx_util.h" #include "ags/engine/gfx/graphicsdriver.h" diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp index 1e91c8c8e65f..7390b4629ca5 100644 --- a/engines/ags/engine/ac/dynobj/cc_serializer.cpp +++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp @@ -31,8 +31,8 @@ #include "ags/engine/ac/dynobj/scriptviewport.h" #include "ags/engine/ac/game.h" #include "ags/engine/debugging/debug_log.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/pluginobjectreader.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/pluginobjectreader.h" namespace AGS3 { diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp index bb7d9b23aa84..005542c0da27 100644 --- a/engines/ags/engine/ac/event.cpp +++ b/engines/ags/engine/ac/event.cpp @@ -33,8 +33,8 @@ #include "ags/engine/ac/screen.h" #include "ags/shared/script/cc_error.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/engine/script/script.h" #include "ags/shared/gfx/bitmap.h" #include "ags/engine/gfx/ddb.h" diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index f7788186da87..a862d533b35a 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -85,8 +85,8 @@ #include "ags/engine/main/graphics_mode.h" #include "ags/engine/main/main.h" #include "ags/engine/media/audio/audio_system.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/script/cc_error.h" #include "ags/engine/script/runtimescriptvalue.h" #include "ags/engine/script/script.h" diff --git a/engines/ags/engine/ac/global_translation.cpp b/engines/ags/engine/ac/global_translation.cpp index 6ee31b312e77..6fe8bb586af2 100644 --- a/engines/ags/engine/ac/global_translation.cpp +++ b/engines/ags/engine/ac/global_translation.cpp @@ -28,8 +28,8 @@ #include "ags/engine/ac/string.h" #include "ags/engine/ac/tree_map.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/util/memory.h" #include "ags/shared/core/types.h" diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp index d6c04b6a02bd..41ac25bceb25 100644 --- a/engines/ags/engine/ac/room.cpp +++ b/engines/ags/engine/ac/room.cpp @@ -60,8 +60,8 @@ #include "ags/shared/debugging/out.h" #include "ags/shared/game/room_version.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/script/cc_error.h" #include "ags/engine/script/script.h" #include "ags/engine/script/script_runtime.h" diff --git a/engines/ags/engine/ac/screen.cpp b/engines/ags/engine/ac/screen.cpp index 9306c4ac88c4..06fc83fe5573 100644 --- a/engines/ags/engine/ac/screen.cpp +++ b/engines/ags/engine/ac/screen.cpp @@ -31,8 +31,8 @@ #include "ags/engine/ac/dynobj/scriptuserobject.h" #include "ags/engine/script/script_runtime.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/gfx/bitmap.h" #include "ags/engine/gfx/graphicsdriver.h" diff --git a/engines/ags/engine/ac/sprite.cpp b/engines/ags/engine/ac/sprite.cpp index e8e1f2eeeebc..ccecda46bc28 100644 --- a/engines/ags/engine/ac/sprite.cpp +++ b/engines/ags/engine/ac/sprite.cpp @@ -26,8 +26,8 @@ #include "ags/engine/ac/sprite.h" #include "ags/engine/ac/system.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/ac/spritecache.h" #include "ags/shared/gfx/bitmap.h" #include "ags/engine/gfx/graphicsdriver.h" diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp index 016f2b471c29..44147bdefeb4 100644 --- a/engines/ags/engine/debugging/debug.cpp +++ b/engines/ags/engine/debugging/debug.cpp @@ -38,7 +38,7 @@ #include "ags/engine/main/config.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/plugin_engine.h" #include "ags/engine/script/script.h" #include "ags/shared/script/script_common.h" #include "ags/shared/script/cc_error.h" diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp index 8de53db9a165..5813e7e6c982 100644 --- a/engines/ags/engine/game/game_init.cpp +++ b/engines/ags/engine/game/game_init.cpp @@ -43,7 +43,7 @@ #include "ags/shared/gfx/bitmap.h" #include "ags/engine/gfx/ddb.h" #include "ags/shared/gui/guilabel.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/script/cc_error.h" #include "ags/engine/script/exports.h" #include "ags/engine/script/script.h" diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp index d2deb79b9d7d..085fbe669d78 100644 --- a/engines/ags/engine/game/savegame.cpp +++ b/engines/ags/engine/game/savegame.cpp @@ -52,8 +52,8 @@ #include "ags/engine/main/engine.h" #include "ags/engine/main/main.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/engine/script/script.h" #include "ags/shared/script/cc_error.h" #include "ags/shared/util/alignedstream.h" diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index 4475b1fdb64c..72a8c179cce4 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -53,8 +53,8 @@ #include "ags/shared/gui/guimain.h" #include "ags/shared/gui/guislider.h" #include "ags/shared/gui/guitextbox.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/shared/script/cc_error.h" #include "ags/engine/script/script.h" #include "ags/shared/util/filestream.h" // TODO: needed only because plugins expect file handle diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp index 545ef80b75f3..000949b62144 100644 --- a/engines/ags/engine/main/game_file.cpp +++ b/engines/ags/engine/main/game_file.cpp @@ -50,7 +50,7 @@ #include "ags/engine/ac/gamesetup.h" #include "ags/shared/game/main_game_file.h" #include "ags/engine/game/game_init.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "ags/engine/script/script.h" namespace AGS3 { diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp index 68a830ee8315..30e5eef2ff7c 100644 --- a/engines/ags/engine/main/game_run.cpp +++ b/engines/ags/engine/main/game_run.cpp @@ -57,8 +57,8 @@ #include "ags/engine/main/engine.h" #include "ags/engine/main/game_run.h" #include "ags/engine/main/update.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" #include "ags/engine/script/script.h" #include "ags/shared/ac/spritecache.h" #include "ags/engine/media/audio/audio_system.h" diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp index 822b2737175f..6d83fb3338d8 100644 --- a/engines/ags/engine/main/quit.cpp +++ b/engines/ags/engine/main/quit.cpp @@ -44,7 +44,7 @@ #include "ags/engine/gfx/graphicsdriver.h" #include "ags/shared/gfx/bitmap.h" #include "ags/shared/core/assetmanager.h" -#include "ags/engine/plugin/plugin_engine.h" +#include "ags/plugins/plugin_engine.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/engine/globals.h" #include "ags/ags.h" diff --git a/engines/ags/engine/platform/base/agsplatformdriver.cpp b/engines/ags/engine/platform/base/agsplatformdriver.cpp index 150a7f64189b..5fff43d8c07d 100644 --- a/engines/ags/engine/platform/base/agsplatformdriver.cpp +++ b/engines/ags/engine/platform/base/agsplatformdriver.cpp @@ -33,7 +33,7 @@ #include "ags/shared/util/string_utils.h" #include "ags/shared/util/stream.h" #include "ags/shared/gfx/bitmap.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "ags/engine/ac/timer.h" #include "ags/engine/media/audio/audio_system.h" #include "ags/lib/system/datetime.h" diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 415dd3dc725c..966ef23e095a 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -36,7 +36,7 @@ #include "ags/engine/ac/runtime_defines.h" #include "ags/engine/gfx/gfxdefines.h" #include "ags/engine/platform/base/agsplatformdriver.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "ags/shared/util/string.h" namespace AGS3 { diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp index 2c4a1e756907..628b792ca3f6 100644 --- a/engines/ags/engine/script/script_runtime.cpp +++ b/engines/ags/engine/script/script_runtime.cpp @@ -39,7 +39,7 @@ #include "ags/shared/script/cc_error.h" #include "ags/shared/script/cc_options.h" #include "ags/engine/script/systemimports.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "ags/engine/ac/dynobj/cc_dynamicarray.h" #include "ags/engine/ac/statobj/staticobject.h" diff --git a/engines/ags/engine/util/library_posix.h b/engines/ags/engine/util/library_posix.h index 04ab9523401c..bc9152d0d1e4 100644 --- a/engines/ags/engine/util/library_posix.h +++ b/engines/ags/engine/util/library_posix.h @@ -27,7 +27,7 @@ #include "ags/shared/core/platform.h" #include "ags/shared/util/string.h" #include "ags/shared/debugging/out.h" -#include "ags/engine/plugin/library.h" +#include "ags/plugins/library.h" #include "ags/engine/globals.h" namespace AGS3 { diff --git a/engines/ags/module.mk b/engines/ags/module.mk index 526a60c7a3d4..c04cd2c01a4c 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -287,10 +287,6 @@ MODULE_OBJS = \ engine/media/video/video.o \ engine/platform/base/agsplatformdriver.o \ engine/platform/linux/acpllnx.o \ - engine/plugin/agsplugin.o \ - engine/plugin/global_plugin.o \ - engine/plugin/library.o \ - engine/plugin/pluginobjectreader.o \ engine/script/cc_instance.o \ engine/script/executingscript.o \ engine/script/exports.o \ @@ -300,7 +296,11 @@ MODULE_OBJS = \ engine/script/script_engine.o \ engine/script/script_runtime.o \ engine/script/systemimports.o \ + plugins/agsplugin.o \ plugins/dll.o \ + plugins/global_plugin.o \ + plugins/library.o \ + plugins/pluginobjectreader.o \ plugins/ags_blend/ags_blend.o \ plugins/ags_creditz/ags_creditz.o \ plugins/ags_flashlight/ags_flashlight.o \ diff --git a/engines/ags/plugins/ags_pal_render/pal_render.h b/engines/ags/plugins/ags_pal_render/pal_render.h index 1f448174e3d9..1d61dab866c8 100644 --- a/engines/ags/plugins/ags_pal_render/pal_render.h +++ b/engines/ags/plugins/ags_pal_render/pal_render.h @@ -24,7 +24,7 @@ #define AGS_PLUGINS_AGS_PAL_RENDER_PAL_RENDER_H #include "ags/lib/allegro.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "common/algorithm.h" namespace AGS3 { diff --git a/engines/ags/engine/plugin/agsplugin.cpp b/engines/ags/plugins/agsplugin.cpp similarity index 99% rename from engines/ags/engine/plugin/agsplugin.cpp rename to engines/ags/plugins/agsplugin.cpp index 7c18d3f358df..07fccba737bd 100644 --- a/engines/ags/engine/plugin/agsplugin.cpp +++ b/engines/ags/plugins/agsplugin.cpp @@ -54,10 +54,10 @@ #include "ags/shared/gui/guidefines.h" #include "ags/engine/main/game_run.h" #include "ags/engine/main/engine.h" -#include "ags/engine/plugin/agsplugin.h" -#include "ags/engine/plugin/plugin_engine.h" -#include "ags/engine/plugin/plugin_builtin.h" -#include "ags/engine/plugin/pluginobjectreader.h" +#include "ags/plugins/agsplugin.h" +#include "ags/plugins/plugin_engine.h" +#include "ags/plugins/plugin_builtin.h" +#include "ags/plugins/pluginobjectreader.h" #include "ags/engine/script/script.h" #include "ags/engine/script/script_runtime.h" #include "ags/shared/ac/spritecache.h" diff --git a/engines/ags/engine/plugin/agsplugin.h b/engines/ags/plugins/agsplugin.h similarity index 100% rename from engines/ags/engine/plugin/agsplugin.h rename to engines/ags/plugins/agsplugin.h diff --git a/engines/ags/plugins/dll.h b/engines/ags/plugins/dll.h index 5b797a3d4977..b6406d9f5a83 100644 --- a/engines/ags/plugins/dll.h +++ b/engines/ags/plugins/dll.h @@ -24,7 +24,7 @@ #define AGS_PLUGINS_DLL_H #include "ags/shared/util/string.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "common/hashmap.h" #include "common/hash-str.h" diff --git a/engines/ags/engine/plugin/global_plugin.cpp b/engines/ags/plugins/global_plugin.cpp similarity index 100% rename from engines/ags/engine/plugin/global_plugin.cpp rename to engines/ags/plugins/global_plugin.cpp diff --git a/engines/ags/engine/plugin/library.cpp b/engines/ags/plugins/library.cpp similarity index 97% rename from engines/ags/engine/plugin/library.cpp rename to engines/ags/plugins/library.cpp index 814fab68dcf9..1fe645d8fcf3 100644 --- a/engines/ags/engine/plugin/library.cpp +++ b/engines/ags/plugins/library.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/engine/plugin/library.h" +#include "ags/plugins/library.h" #include "ags/plugins/dll.h" namespace AGS3 { diff --git a/engines/ags/engine/plugin/library.h b/engines/ags/plugins/library.h similarity index 100% rename from engines/ags/engine/plugin/library.h rename to engines/ags/plugins/library.h diff --git a/engines/ags/engine/plugin/plugin_builtin.h b/engines/ags/plugins/plugin_builtin.h similarity index 100% rename from engines/ags/engine/plugin/plugin_builtin.h rename to engines/ags/plugins/plugin_builtin.h diff --git a/engines/ags/engine/plugin/plugin_engine.h b/engines/ags/plugins/plugin_engine.h similarity index 100% rename from engines/ags/engine/plugin/plugin_engine.h rename to engines/ags/plugins/plugin_engine.h diff --git a/engines/ags/engine/plugin/pluginobjectreader.cpp b/engines/ags/plugins/pluginobjectreader.cpp similarity index 95% rename from engines/ags/engine/plugin/pluginobjectreader.cpp rename to engines/ags/plugins/pluginobjectreader.cpp index c01edae79b35..dd510ca1c096 100644 --- a/engines/ags/engine/plugin/pluginobjectreader.cpp +++ b/engines/ags/plugins/pluginobjectreader.cpp @@ -20,7 +20,7 @@ * */ -#include "ags/engine/plugin/pluginobjectreader.h" +#include "ags/plugins/pluginobjectreader.h" #include "ags/engine/ac/runtime_defines.h" namespace AGS3 { diff --git a/engines/ags/engine/plugin/pluginobjectreader.h b/engines/ags/plugins/pluginobjectreader.h similarity index 100% rename from engines/ags/engine/plugin/pluginobjectreader.h rename to engines/ags/plugins/pluginobjectreader.h diff --git a/engines/ags/plugins/serializer.h b/engines/ags/plugins/serializer.h index ba48c0bc25a2..e752ea060f78 100644 --- a/engines/ags/plugins/serializer.h +++ b/engines/ags/plugins/serializer.h @@ -23,7 +23,7 @@ #ifndef AGS_PLUGINS_SERIALIZER_H #define AGS_PLUGINS_SERIALIZER_H -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "common/serializer.h" namespace AGS3 { From b9c86d9c53ccc2db2217e0e6cf76d963ae8735c5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 25 Jan 2021 20:00:52 -0800 Subject: [PATCH 181/215] AGS: Added AGSCredits 1.1 SetCredits method --- .../ags/plugins/ags_creditz/ags_creditz.cpp | 32 ++++++++++++++----- engines/ags/plugins/ags_creditz/ags_creditz.h | 7 ++-- .../ags_sprite_font/sprite_font_renderer.h | 2 +- .../ags_sprite_font/variable_width_font.h | 2 +- .../variable_width_sprite_font.h | 2 +- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.cpp b/engines/ags/plugins/ags_creditz/ags_creditz.cpp index 3e350d820b53..639bf476d7b1 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.cpp +++ b/engines/ags/plugins/ags_creditz/ags_creditz.cpp @@ -49,7 +49,6 @@ const char *AGSCreditz::AGS_GetPluginName() { void AGSCreditz::AGS_EngineStartup(IAGSEngine *engine) { SCRIPT_METHOD(ScrollCredits); - SCRIPT_METHOD(GetCredit); SCRIPT_METHOD(IsCreditScrollingFinished); SCRIPT_METHOD(SetCreditImage); SCRIPT_METHOD(PauseScroll); @@ -74,11 +73,6 @@ void AGSCreditz::ScrollCredits(const ScriptMethodParams ¶ms) { PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, res); } -string AGSCreditz::GetCredit(const ScriptMethodParams ¶ms) { - PARAMS1(int, ID); - return nullptr; -} - int AGSCreditz::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { return true; } @@ -154,6 +148,8 @@ int AGSCreditz::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { /*------------------------------------------------------------------*/ +const char *IMAGE_TEXT = "*i*m*a*g*e*"; + AGSCreditz11::AGSCreditz11() { _version = VERSION_11; @@ -162,12 +158,31 @@ AGSCreditz11::AGSCreditz11() { void AGSCreditz11::AGS_EngineStartup(IAGSEngine *engine) { AGSCreditz::AGS_EngineStartup(engine); + SCRIPT_METHOD(SetCredit); + SCRIPT_METHOD(GetCredit); } void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { PARAMS7(int, ID, string, credit, int, colour, int, font, int, center, int, xpos, int, generateoutline); + if (ID >= _state->_credits[0].size()) + _state->_credits[0].resize(ID + 1); + + Credit &c = _state->_credits[0][ID]; + c._text = credit; + c._fontSlot = font; + c._center = center; + c._x = xpos; + c._isSet = true; + c._outline = generateoutline; +} + +const string AGSCreditz11::GetCredit(const ScriptMethodParams ¶ms) { + PARAMS1(int, ID); + + return (_state->_credits[0][ID]._text == IMAGE_TEXT) ? + "image" : _state->_credits[0][ID]._text.c_str(); } /*------------------------------------------------------------------*/ @@ -180,6 +195,7 @@ AGSCreditz20::AGSCreditz20() { void AGSCreditz20::AGS_EngineStartup(IAGSEngine *engine) { AGSCreditz::AGS_EngineStartup(engine); + SCRIPT_METHOD(SetCredit); } @@ -191,9 +207,9 @@ void AGSCreditz20::SetCredit(const ScriptMethodParams ¶ms) { _state->_credits[sequence].resize(line + 1); Credit &c = _state->_credits[sequence][line]; - c._credit = credit; + c._text = credit; c._fontSlot = font; - c._colorHeight = color; + c._color = color; c._x = x_pos; c._isSet = true; if (gen_outline > 0) diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.h b/engines/ags/plugins/ags_creditz/ags_creditz.h index 14f7ed67badf..b18669c7550c 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.h +++ b/engines/ags/plugins/ags_creditz/ags_creditz.h @@ -33,11 +33,12 @@ namespace Plugins { namespace AGSCreditz { struct Credit { - Common::String _credit; + Common::String _text; int _x = 0; int _y = 0; int _fontSlot = 0; - int _colorHeight = 0; + int _color = 0; + int _center = 0; bool _isSet = false; bool _image = false; bool _outline = false; @@ -121,7 +122,6 @@ class AGSCreditz : public DLL { // Shared Script methods static void ScrollCredits(const ScriptMethodParams ¶ms); - static string GetCredit(const ScriptMethodParams ¶ms); static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); static void SetCreditImage(const ScriptMethodParams ¶ms); static void PauseScroll(const ScriptMethodParams ¶ms); @@ -150,6 +150,7 @@ class AGSCreditz11 : public AGSCreditz { static void AGS_EngineStartup(IAGSEngine *engine); static void SetCredit(const ScriptMethodParams ¶ms); + static const string GetCredit(const ScriptMethodParams ¶ms); public: AGSCreditz11(); }; diff --git a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h index a5f2f373a024..89be9b1bbffc 100644 --- a/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h +++ b/engines/ags/plugins/ags_sprite_font/sprite_font_renderer.h @@ -24,7 +24,7 @@ #define AGS_PLUGINS_AGS_SPRITE_FONT_SPR_FONT_RENDERER_H #include "ags/plugins/ags_sprite_font/sprite_font.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "ags/lib/std/vector.h" namespace AGS3 { diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_font.h b/engines/ags/plugins/ags_sprite_font/variable_width_font.h index 5eb5bccbdd73..96c1f9e54442 100644 --- a/engines/ags/plugins/ags_sprite_font/variable_width_font.h +++ b/engines/ags/plugins/ags_sprite_font/variable_width_font.h @@ -24,7 +24,7 @@ #define AGS_PLUGINS_AGS_SPRITE_FONT_VAR_WIDTH_FONT_H #include "ags/plugins/ags_sprite_font/character_entry.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "ags/lib/std/map.h" namespace AGS3 { diff --git a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h index 5625d21c1eb2..4bd05f58ccf3 100644 --- a/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h +++ b/engines/ags/plugins/ags_sprite_font/variable_width_sprite_font.h @@ -25,7 +25,7 @@ #include "ags/plugins/dll.h" #include "ags/plugins/serializer.h" -#include "ags/engine/plugin/agsplugin.h" +#include "ags/plugins/agsplugin.h" #include "ags/plugins/ags_sprite_font/variable_width_font.h" namespace AGS3 { From 09d89665ef3e15191696732c1f9825285ff27de1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 26 Jan 2021 18:09:55 -0800 Subject: [PATCH 182/215] AGS: Implementing AGSCreditz ScrollCredits --- .../ags/plugins/ags_creditz/ags_creditz.cpp | 37 ++++++++++++++++--- engines/ags/plugins/ags_creditz/ags_creditz.h | 7 +++- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.cpp b/engines/ags/plugins/ags_creditz/ags_creditz.cpp index 639bf476d7b1..28bc707fae3b 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.cpp +++ b/engines/ags/plugins/ags_creditz/ags_creditz.cpp @@ -28,9 +28,11 @@ namespace AGSCreditz { AGSCreditz::Version AGSCreditz::_version; State *AGSCreditz::_state; +IAGSEngine *AGSCreditz::_engine; AGSCreditz::AGSCreditz() { _state = new State(); + _engine = nullptr; DLL_METHOD(AGS_GetPluginName); } @@ -48,7 +50,8 @@ const char *AGSCreditz::AGS_GetPluginName() { } void AGSCreditz::AGS_EngineStartup(IAGSEngine *engine) { - SCRIPT_METHOD(ScrollCredits); + _engine = engine; + SCRIPT_METHOD(IsCreditScrollingFinished); SCRIPT_METHOD(SetCreditImage); SCRIPT_METHOD(PauseScroll); @@ -69,10 +72,6 @@ void AGSCreditz::AGS_EngineStartup(IAGSEngine *engine) { SCRIPT_METHOD(IsStaticCreditsFinished); } -void AGSCreditz::ScrollCredits(const ScriptMethodParams ¶ms) { - PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, res); -} - int AGSCreditz::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { return true; } @@ -160,6 +159,7 @@ void AGSCreditz11::AGS_EngineStartup(IAGSEngine *engine) { AGSCreditz::AGS_EngineStartup(engine); SCRIPT_METHOD(SetCredit); + SCRIPT_METHOD(ScrollCredits); SCRIPT_METHOD(GetCredit); } @@ -178,6 +178,33 @@ void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { c._outline = generateoutline; } +void AGSCreditz11::ScrollCredits(const ScriptMethodParams ¶ms) { + PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, resolution); + + if (onoff == 1) { + _state->_creditsRunning = true; + _state->_seqSettings[0].speed = speed; + _state->_seqSettings[0].endwait = wait; + _state->_seqSettings[0].startpoint = fromY; + _state->_seqSettings[0].endpoint = toY; + _state->_seqSettings[0].automatic = isautom; + + _engine->GetScreenDimensions(&_state->_screenWidth, + &_state->_screenHeight, &_state->_screenColorDepth); + if (_state->_screenWidth == 320) { + _state->_resolutionFlag = (resolution != 2) ? 1 : 0; + } else if (_state->_screenWidth == 640) { + _state->_resolutionFlag = (resolution != 1) ? 1 : 0; + } + + } else if (onoff == 0) { + _state->_creditsRunning = false; + + } else { + _engine->AbortGame("ScrollCredits: OnOff value must be 1 or 0!"); + } +} + const string AGSCreditz11::GetCredit(const ScriptMethodParams ¶ms) { PARAMS1(int, ID); diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.h b/engines/ags/plugins/ags_creditz/ags_creditz.h index b18669c7550c..baf0b738970b 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.h +++ b/engines/ags/plugins/ags_creditz/ags_creditz.h @@ -106,6 +106,10 @@ struct State { void *_maskScreen = nullptr; void *_maski = nullptr; void *_creditScreen = nullptr; + + // Version 1.1 specific + bool _resolutionFlag = false; + int _screenWidth = 0, _screenHeight = 0, _screenColorDepth = 0; }; class AGSCreditz : public DLL { @@ -116,12 +120,12 @@ class AGSCreditz : public DLL { static Version _version; static State *_state; + static IAGSEngine *_engine; protected: static const char *AGS_GetPluginName(); static void AGS_EngineStartup(IAGSEngine *engine); // Shared Script methods - static void ScrollCredits(const ScriptMethodParams ¶ms); static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); static void SetCreditImage(const ScriptMethodParams ¶ms); static void PauseScroll(const ScriptMethodParams ¶ms); @@ -150,6 +154,7 @@ class AGSCreditz11 : public AGSCreditz { static void AGS_EngineStartup(IAGSEngine *engine); static void SetCredit(const ScriptMethodParams ¶ms); + static void ScrollCredits(const ScriptMethodParams ¶ms); static const string GetCredit(const ScriptMethodParams ¶ms); public: AGSCreditz11(); From 4405e6423d66ff5bc416a411f91433bb7d526685 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 26 Jan 2021 18:10:20 -0800 Subject: [PATCH 183/215] AGS: Hook up loading savegames from launcher --- engines/ags/ags.cpp | 8 +++++--- engines/ags/engine/ac/game.cpp | 10 ++++------ engines/ags/engine/ac/game.h | 1 - engines/ags/engine/globals.h | 2 +- engines/ags/engine/main/game_start.cpp | 12 ++++-------- engines/ags/engine/main/game_start.h | 4 ++-- 6 files changed, 16 insertions(+), 21 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index bf61c62120ed..397a338f6b77 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -65,7 +65,7 @@ namespace AGS3 { using namespace Shared; using namespace Engine; -extern HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten); +extern HSaveError load_game(int slotNumber, bool &data_overwritten); extern GameSetup usetup; extern GameState play; @@ -155,7 +155,7 @@ static int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) { } else if (scumm_stricmp(arg, "-unregistergame") == 0) { _G(justUnRegisterGame) = true; } else if ((scumm_stricmp(arg, "-loadsavedgame") == 0) && (argc > ee + 1)) { - _G(loadSaveGameOnStartup) = argv[ee + 1]; + _G(loadSaveGameOnStartup) = atoi(argv[ee + 1]); ee++; } else if ((scumm_stricmp(arg, "--enabledebugger") == 0) && (argc > ee + 1)) { strcpy(_G(editor_debugger_instance_token), argv[ee + 1]); @@ -348,6 +348,8 @@ Common::Error AGSEngine::run() { if (AGS3::debug_flags & DBG_REGONLY) return Common::kNoError; + _G(loadSaveGameOnStartup) = ConfMan.getInt("save_slot"); + #ifdef USE_CUSTOM_EXCEPTION_HANDLER if (usetup.disable_exception_handling) #endif @@ -380,7 +382,7 @@ void AGSEngine::setGraphicsMode(size_t w, size_t h) { Common::Error AGSEngine::loadGameState(int slot) { bool dataOverwritten; - (void)AGS3::load_game("", slot, dataOverwritten); + (void)AGS3::load_game(slot, dataOverwritten); return Common::kNoError; } diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index a862d533b35a..2b9683350148 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -1552,7 +1552,7 @@ bool read_savedgame_screenshot(const String &savedgame, int &want_shot) { return true; } -HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten) { +HSaveError load_game(int slotNumber, bool &data_overwritten) { data_overwritten = false; gameHasBeenRestored++; @@ -1562,6 +1562,8 @@ HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten) HSaveError err; SavegameSource src; SavegameDescription desc; + + String path = get_save_game_path(slotNumber); err = OpenSavegame(path, src, desc, kSvgDesc_EnvInfo); // saved in incompatible enviroment @@ -1602,12 +1604,8 @@ HSaveError load_game(const String &path, int slotNumber, bool &data_overwritten) } bool try_restore_save(int slot) { - return try_restore_save(get_save_game_path(slot), slot); -} - -bool try_restore_save(const Shared::String &path, int slot) { bool data_overwritten; - HSaveError err = load_game(path, slot, data_overwritten); + HSaveError err = load_game(slot, data_overwritten); if (!err) { String error = String::FromFormat("Unable to restore the saved game.\n%s", err->FullMessage().GetCStr()); diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h index 2d6c81380507..1d8c84428ef8 100644 --- a/engines/ags/engine/ac/game.h +++ b/engines/ags/engine/ac/game.h @@ -164,7 +164,6 @@ bool read_savedgame_screenshot(const Shared::String &savedgame, int &want_shot); // Tries to restore saved game and displays an error on failure; if the error occured // too late, when the game data was already overwritten, shuts engine down. bool try_restore_save(int slot); -bool try_restore_save(const Shared::String &path, int slot); void serialize_bitmap(const Shared::Bitmap *thispic, Shared::Stream *out); // On Windows we could just use IIDFromString but this is platform-independant void convert_guid_from_text_to_binary(const char *guidText, unsigned char *buffer); diff --git a/engines/ags/engine/globals.h b/engines/ags/engine/globals.h index 6cca2e29d39f..0166ce215eb2 100644 --- a/engines/ags/engine/globals.h +++ b/engines/ags/engine/globals.h @@ -90,7 +90,7 @@ class Globals { bool _justUnRegisterGame = false; bool _justTellInfo = false; std::set _tellInfoKeys; - const char *_loadSaveGameOnStartup = nullptr; + int _loadSaveGameOnStartup = -1; #if ! AGS_PLATFORM_DEFINES_PSP_VARS int _psp_video_framedrop = 1; diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp index 5ea5356fe384..d12ca06d1357 100644 --- a/engines/ags/engine/main/game_start.cpp +++ b/engines/ags/engine/main/game_start.cpp @@ -28,6 +28,7 @@ #include "ags/shared/ac/characterinfo.h" #include "ags/engine/ac/game.h" #include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/util/directory.h" #include "ags/engine/ac/gamestate.h" #include "ags/engine/ac/global_game.h" #include "ags/engine/ac/mouse.h" @@ -75,14 +76,9 @@ void start_game_init_editor_debugging() { } void start_game_load_savegame_on_startup() { - if (_G(loadSaveGameOnStartup) != nullptr) { - int saveGameNumber = 1000; - const char *sgName = strstr(_G(loadSaveGameOnStartup), "agssave."); - if (sgName != nullptr) { - sscanf(sgName, "agssave.%03d", &saveGameNumber); - } + if (_G(loadSaveGameOnStartup) != -1) { current_fade_out_effect(); - try_restore_save(_G(loadSaveGameOnStartup), saveGameNumber); + try_restore_save(_G(loadSaveGameOnStartup)); } } @@ -123,7 +119,7 @@ void do_start_game() { start_game(); } -void initialize_start_and_play_game(int override_start_room, const char *loadSaveOnStartup) { +void initialize_start_and_play_game(int override_start_room, int loadSaveOnStartup) { // try { // BEGIN try for ALI3DEXception set_cursor_mode(MODE_WALK); diff --git a/engines/ags/engine/main/game_start.h b/engines/ags/engine/main/game_start.h index 8ca81c2c602f..374400462b9d 100644 --- a/engines/ags/engine/main/game_start.h +++ b/engines/ags/engine/main/game_start.h @@ -25,8 +25,8 @@ namespace AGS3 { -void start_game(); -void initialize_start_and_play_game(int override_start_room, const char *loadSaveGameOnStartup); +extern void start_game(); +extern void initialize_start_and_play_game(int override_start_room, int loadSaveGameOnStartup); } // namespace AGS3 From 732ed93aae065ef72ca24bb0f8c5b215bd4f7b5f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 26 Jan 2021 20:51:01 -0800 Subject: [PATCH 184/215] AGS: Added savegame thumbnails At the moment, savegames made using the in-game save dialogs show the dialog in the thumbnail. Not sure if it will be possible to work around in the future, since the display of any save dialog is controlled by game scripts, and so it would be difficult to figure out a point to get a screenshot ready before the dialog has been shown --- engines/ags/engine/ac/game.cpp | 8 ++-- engines/ags/engine/ac/richgamemedia.h | 4 +- engines/ags/metaengine.cpp | 69 +++++++++++++++++++++++++++ engines/ags/metaengine.h | 27 +++++++++++ 4 files changed, 102 insertions(+), 6 deletions(-) diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index 2b9683350148..a1425eb99409 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -1017,7 +1017,9 @@ void WriteGameSetupStructBase_Aligned(Stream *out) { #define MAGICNUMBER 0xbeefcafe void create_savegame_screenshot(Bitmap *&screenShot) { - if (game.options[OPT_SAVESCREENSHOT]) { + // WORKAROUND: AGS originally only creates savegames if the game flags + // that it supports it. But we want it all the time for ScummVM GMM + if (/*game.options[OPT_SAVESCREENSHOT] */true) { int usewid = data_to_game_coord(play.screenshot_width); int usehit = data_to_game_coord(play.screenshot_height); const Rect &viewport = play.GetMainViewport(); @@ -1072,15 +1074,13 @@ void save_game(int slotn, const char *descript) { update_polled_stuff_if_runtime(); - out.reset(Shared::File::OpenFile(nametouse, Shared::kFile_Open, Shared::kFile_ReadWrite)); out->Seek(12, kSeekBegin); out->WriteInt32(screenShotOffset); out->Seek(4); out->WriteInt32(screenShotSize); - } - if (screenShot != nullptr) delete screenShot; + } } HSaveError restore_game_head_dynamic_values(Stream *in, RestoredData &r_data) { diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index c66a46d8353d..7c650edc5fd0 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -58,8 +58,8 @@ struct RICH_GAME_MEDIA_HEADER { uint32 dwMagicNumber; int dwHeaderVersion; int dwHeaderSize; - int dwThumbnailOffsetLowerDword; - int dwThumbnailOffsetHigherDword; + uint32 dwThumbnailOffsetLowerDword; + uint32 dwThumbnailOffsetHigherDword; int dwThumbnailSize; byte guidGameId[16]; uint16 szGameName[RM_MAXLENGTH]; diff --git a/engines/ags/metaengine.cpp b/engines/ags/metaengine.cpp index 977c87d3e1e3..7dcee2ddd2c8 100644 --- a/engines/ags/metaengine.cpp +++ b/engines/ags/metaengine.cpp @@ -27,7 +27,9 @@ #include "ags/shared/util/filestream.h" #include "ags/engine/ac/richgamemedia.h" #include "ags/engine/game/savegame.h" +#include "common/memstream.h" #include "common/savefile.h" +#include "image/bmp.h" const char *AGSMetaEngine::getName() const { return "ags"; @@ -78,6 +80,73 @@ SaveStateList AGSMetaEngine::listSaves(const char *target) const { return saveList; } +bool AGSMetaEngine::hasFeature(MetaEngineFeature f) const { + return + (f == kSupportsListSaves) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSupportsLoadingDuringStartup); +} + +Common::String AGSMetaEngine::getSavegameFile(int saveGameIdx, const char *target) const { + if (saveGameIdx == kSavegameFilePattern) { + // Pattern requested + return Common::String::format("%s.###", target == nullptr ? getEngineId() : target); + } else { + // Specific filename requested + return Common::String::format("%s.%03d", target == nullptr ? getEngineId() : target, saveGameIdx); + } +} + +SaveStateDescriptor AGSMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("%s%s", + ::AGS3::AGS::Shared::SAVE_FOLDER_PREFIX, + getSavegameFile(slot, target).c_str()); + + ::AGS3::AGS::Shared::FileStream saveFile(filename, ::AGS3::AGS::Shared::kFile_Open, + ::AGS3::AGS::Shared::kFile_Read); + if (saveFile.IsValid()) { + AGS3::RICH_GAME_MEDIA_HEADER rich_media_header; + rich_media_header.ReadFromFile(&saveFile); + + if (rich_media_header.dwMagicNumber == RM_MAGICNUMBER) { + SaveStateDescriptor desc; + desc.setSaveSlot(slot); + if (slot == getAutosaveSlot()) { + desc.setAutosave(true); + desc.setWriteProtectedFlag(true); + } + + // Thumbnail handling + if (rich_media_header.dwThumbnailOffsetLowerDword != 0 && + rich_media_header.dwThumbnailSize != 0) { + // Read in the thumbnail data + byte *thumbData = (byte *)malloc(rich_media_header.dwThumbnailSize); + saveFile.Seek(rich_media_header.dwThumbnailOffsetLowerDword, + AGS3::AGS::Shared::kSeekCurrent); + saveFile.Read(thumbData, rich_media_header.dwThumbnailSize); + Common::MemoryReadStream thumbStream(thumbData, + rich_media_header.dwThumbnailSize, DisposeAfterUse::YES); + + // Read in the thumbnail + Image::BitmapDecoder decoder; + if (decoder.loadStream(thumbStream)) { + const Graphics::Surface *src = decoder.getSurface(); + Graphics::Surface *dest = new Graphics::Surface(); + dest->copyFrom(*src); + + desc.setThumbnail(dest); + } + } + + return desc; + } + } + + return SaveStateDescriptor(); +} + #if PLUGIN_ENABLED_DYNAMIC(AGS) REGISTER_PLUGIN_DYNAMIC(AGS, PLUGIN_TYPE_ENGINE, AGSMetaEngine); #else diff --git a/engines/ags/metaengine.h b/engines/ags/metaengine.h index aeccb8f44751..a98963441fc4 100644 --- a/engines/ags/metaengine.h +++ b/engines/ags/metaengine.h @@ -39,6 +39,33 @@ class AGSMetaEngine : public AdvancedMetaEngine { return 999; } + /** + * Return the name of the save file for the given slot and optional target, + * or a pattern for matching filenames against. + * + * @param saveGameIdx Index of the save, or kSavegameFilePattern + * for returning a filename pattern. + * @param target Game target. If omitted, then the engine ID is used. + */ + Common::String getSavegameFile(int saveGameIdx, const char *target = nullptr) const override; + + /** + * Determine whether the engine supports the specified MetaEngine feature. + * + * Used by e.g. the launcher to determine whether to enable the Load button. + */ + bool hasFeature(MetaEngineFeature f) const override; + + /** + * Return meta information from the specified save state. + * + * Depending on the MetaEngineFeatures set, this can include + * thumbnails, save date and time, play time. + * + * @param target Name of a config manager target. + * @param slot Slot number of the save state. + */ + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override; }; #endif From ad3d03cbf610dc824c472ea7265b44960e7a6c70 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Jan 2021 18:39:22 -0800 Subject: [PATCH 185/215] AGS: Implement GMM saving & loading --- engines/ags/ags.cpp | 12 +++++++++++- engines/ags/ags.h | 16 ++++++++++++++++ engines/ags/engine/ac/game.cpp | 2 +- engines/ags/metaengine.cpp | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 397a338f6b77..ce8353863619 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -40,6 +40,7 @@ #include "ags/engine/globals.h" #include "ags/engine/ac/gamesetup.h" #include "ags/engine/ac/gamestate.h" +#include "ags/engine/ac/room.h" #include "ags/shared/core/def_version.h" #include "ags/engine/debugging/debugger.h" #include "ags/engine/debugging/debug_log.h" @@ -50,6 +51,7 @@ #include "ags/engine/main/mainheader.h" #include "ags/engine/main/main.h" #include "ags/engine/platform/base/agsplatformdriver.h" +#include "ags/engine/script/script.h" #include "ags/engine/ac/route_finder.h" #include "ags/shared/core/assetmanager.h" #include "ags/shared/util/directory.h" @@ -380,9 +382,17 @@ void AGSEngine::setGraphicsMode(size_t w, size_t h) { _screen = new ::AGS3::BITMAP(_rawScreen); } +bool AGSEngine::canLoadGameStateCurrently() { + return !::AGS3::thisroom.Options.SaveLoadDisabled && !::AGS3::inside_script; +} + +bool AGSEngine::canSaveGameStateCurrently() { + return !::AGS3::thisroom.Options.SaveLoadDisabled && !::AGS3::inside_script; +} + Common::Error AGSEngine::loadGameState(int slot) { bool dataOverwritten; - (void)AGS3::load_game(slot, dataOverwritten); + (void)AGS3::try_restore_save(slot); return Common::kNoError; } diff --git a/engines/ags/ags.h b/engines/ags/ags.h index f1004110f150..dc8ebd2561b7 100644 --- a/engines/ags/ags.h +++ b/engines/ags/ags.h @@ -110,6 +110,22 @@ class AGSEngine : public Engine { */ void setGraphicsMode(size_t w, size_t h); + bool hasFeature(EngineFeature f) const override { + return + (f == kSupportsLoadingDuringRuntime) || + (f == kSupportsSavingDuringRuntime); + }; + + /** + * Indicate whether a game state can be loaded. + */ + bool canLoadGameStateCurrently() override; + + /** + * Indicate whether a game state can be saved. + */ + bool canSaveGameStateCurrently() override; + /** * Load a savegame */ diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index a1425eb99409..af2bf4e48b8f 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -486,7 +486,7 @@ const char *Game_GetSaveSlotDescription(int slnum) { void restore_game_dialog() { can_run_delayed_command(); - if (thisroom.Options.SaveLoadDisabled == 1) { + if (thisroom.Options.SaveLoadDisabled) { DisplayMessage(983); return; } diff --git a/engines/ags/metaengine.cpp b/engines/ags/metaengine.cpp index 7dcee2ddd2c8..5061513bb673 100644 --- a/engines/ags/metaengine.cpp +++ b/engines/ags/metaengine.cpp @@ -129,7 +129,7 @@ SaveStateDescriptor AGSMetaEngine::querySaveMetaInfos(const char *target, int sl Common::MemoryReadStream thumbStream(thumbData, rich_media_header.dwThumbnailSize, DisposeAfterUse::YES); - // Read in the thumbnail + // Decode the thumbnail Image::BitmapDecoder decoder; if (decoder.loadStream(thumbStream)) { const Graphics::Surface *src = decoder.getSurface(); From 84ef10441fa0f43bf410a12974743987ce2f635b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Jan 2021 21:07:56 -0800 Subject: [PATCH 186/215] AGS: Cleanup of transparency color in Allegro stubs --- engines/ags/lib/allegro/gfx.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 8353437a6165..28327b990a1e 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -30,6 +30,11 @@ namespace AGS3 { int color_conversion; +// For Allegro, paletted sprites always use index 0 as the transparent color, +// and for higher resolution formats uses bright pink RGB 255, 0, 255 +#define TRANSPARENT_COLOR(BITMAP) ((BITMAP).format.bytesPerPixel == 1 ? 0 : \ + (BITMAP).format.RGBToColor(255, 0, 255)) + /*-------------------------------------------------------------------*/ BITMAP::BITMAP(Graphics::ManagedSurface *owner) : _owner(owner), @@ -212,7 +217,7 @@ int bitmap_color_depth(BITMAP *bmp) { int bitmap_mask_color(BITMAP *bmp) { assert(bmp->format.bytesPerPixel > 1); - return bmp->format.RGBToColor(255, 0, 255); + return TRANSPARENT_COLOR(*bmp); } void add_palette_if_needed(Graphics::ManagedSurface &src, Graphics::ManagedSurface &dest) { @@ -269,10 +274,7 @@ void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { add_palette_if_needed(spriteS, bmpS); - // For Allegro, paletted sprites always use index 0 as the transparent color, - // and for higher resolution formats uses bright pink RGB 255, 0, 255 - bmpS.transBlitFrom(spriteS, Common::Point(x, y), - (spriteS.format.bytesPerPixel == 1) ? 0 : spriteS.format.RGBToColor(255, 0, 255)); + bmpS.transBlitFrom(spriteS, Common::Point(x, y), TRANSPARENT_COLOR(spriteS)); } void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int h) { From a7e785741c4e1bcd857b62d65707cca4fa3a5721 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 29 Jan 2021 20:56:00 -0800 Subject: [PATCH 187/215] GRAPHICS: Allow ManagedSurface blitting to ignore transparency --- graphics/managed_surface.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h index 8416dcfc3577..80ef2c5669e1 100644 --- a/graphics/managed_surface.h +++ b/graphics/managed_surface.h @@ -460,6 +460,15 @@ class ManagedSurface { uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff, const Surface *mask = nullptr, bool maskOnly = false); + /** + * Does a blitFrom ignoring any transparency settings + */ + void rawBlitFrom(const Surface &src, const Common::Rect &srcRect, + const Common::Point &destPos, const uint32 *palette) { + blitFromInner(src, srcRect, Common::Rect(destPos.x, destPos.y, + destPos.x + srcRect.width(), destPos.y + srcRect.height()), palette); + } + /** * Clear the entire surface. */ From e8863980f4cc73a7ef2a7a0e91b8ec0a7c298a79 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 29 Jan 2021 20:56:39 -0800 Subject: [PATCH 188/215] GRAPHICS: ManagedSurface transBlitFrom ignore alpha matching transColor --- graphics/managed_surface.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp index e791ce5dddb9..b2b4a333683c 100644 --- a/graphics/managed_surface.cpp +++ b/graphics/managed_surface.cpp @@ -513,11 +513,19 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c const uint32 *dstPalette, const Surface *mask, bool maskOnly) { int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width(); int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height(); + byte rt1 = 0, gt1 = 0, bt1 = 0, rt2 = 0, gt2 = 0, bt2 = 0; byte *lookup = nullptr; if (srcPalette && dstPalette) lookup = createPaletteLookup(srcPalette, dstPalette); + // If we're dealing with a 32-bit source surface, we need to split up the RGB, + // since we'll want to find matching RGB pixels irrespective of the alpha + bool isTrans32 = src.format.bytesPerPixel == 4 && transColor != (uint32)-1; + if (isTrans32) { + src.format.colorToRGB(transColor, rt1, gt1, bt1); + } + // Loop through drawing output lines for (int destY = destRect.top, scaleYCtr = 0; destY < destRect.bottom; ++destY, scaleYCtr += scaleY) { if (destY < 0 || destY >= dest.h) @@ -536,7 +544,12 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c continue; TSRC srcVal = srcLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD]; - if (srcVal == transColor && !maskOnly) + if (isTrans32 && !maskOnly) { + src.format.colorToRGB(srcVal, rt2, gt2, bt2); + if (rt1 == rt2 && gt1 == gt2 && bt1 == bt2) + continue; + + } else if (srcVal == transColor && !maskOnly) continue; if (mask) { From 1bff9709cead4d432abcd32811c45e38f6e78849 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 29 Jan 2021 20:59:04 -0800 Subject: [PATCH 189/215] AGS: Fix rendering of player in KQ2+ --- engines/ags/lib/allegro/gfx.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index 28327b990a1e..b66bedf23aa2 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -224,6 +224,12 @@ void add_palette_if_needed(Graphics::ManagedSurface &src, Graphics::ManagedSurfa if (src.format.bytesPerPixel == 1 && dest.format.bytesPerPixel > 1) { byte pal[PALETTE_SIZE]; palette_to_rgb8(_current_palette, pal); + + // Set transparent color for index 0 + pal[0] = 0xff; + pal[1] = 0; + pal[2] = 0xff; + src.setPalette(pal, 0, PALETTE_COUNT); } } @@ -234,7 +240,13 @@ void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int add_palette_if_needed(srcS, destS); - destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y)); + if (dynamic_cast(&destS) != nullptr) { + destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), + Common::Point(dst_x, dst_y)); + } else { + destS.rawBlitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), + Common::Point(dst_x, dst_y), srcS.getPalette()); + } } void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, From cfd12083cb5842e2bc0025f28bea07f36556b944 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 30 Jan 2021 10:22:31 -0800 Subject: [PATCH 190/215] AGS: Added fallback detector --- engines/ags/ags.cpp | 1 - engines/ags/detection.cpp | 75 ++++++++++++++++++++++++++++++++++ engines/ags/detection.h | 9 +++- engines/ags/detection_tables.h | 16 ++++++++ 4 files changed, 99 insertions(+), 2 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index ce8353863619..3ecd5815ed3a 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -391,7 +391,6 @@ bool AGSEngine::canSaveGameStateCurrently() { } Common::Error AGSEngine::loadGameState(int slot) { - bool dataOverwritten; (void)AGS3::try_restore_save(slot); return Common::kNoError; } diff --git a/engines/ags/detection.cpp b/engines/ags/detection.cpp index 204906a2d5c9..d1afbb27162d 100644 --- a/engines/ags/detection.cpp +++ b/engines/ags/detection.cpp @@ -21,11 +21,86 @@ */ #include "base/plugins.h" +#include "common/file.h" #include "ags/detection.h" #include "ags/detection_tables.h" +namespace AGS3 { + +static const char *const HEAD_SIG = "CLIB\x1a"; +static const char *const TAIL_SIG = "CLIB\x1\x2\x3\x4SIGE"; +#define HEAD_SIG_SIZE 5 +#define TAIL_SIG_SIZE 12 + +/** + * Detect the presence of an AGS game + * TODO: This is a compact version of MFLUtil::ReadSigsAndVersion. I didn't + * use the full version due to the complexities of including it when + * plugins are enabled. In the future, though, it would be nice to figure + * out, since the full version can handle not detecting on files that are + * AGS, but only contain sounds, etc. rather than a game + */ +static bool isAGSFile(Common::File &f) { + // Check for signature at beginning of file + char buffer[16]; + if (f.read(buffer, HEAD_SIG_SIZE) == HEAD_SIG_SIZE && + !memcmp(buffer, HEAD_SIG, HEAD_SIG_SIZE)) + return true; + + // Check for signature at end of EXE files + f.seek(-TAIL_SIG_SIZE, SEEK_END); + if (f.read(buffer, TAIL_SIG_SIZE) == TAIL_SIG_SIZE && + !memcmp(buffer, TAIL_SIG, TAIL_SIG_SIZE)) + return true; + + return false; +} + +} // namespace AGS3 + AGSMetaEngineDetection::AGSMetaEngineDetection() : AdvancedMetaEngineDetection(AGS::GAME_DESCRIPTIONS, sizeof(AGS::AGSGameDescription), AGS::GAME_NAMES) { } +ADDetectedGame AGSMetaEngineDetection::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { + // Set the default values for the fallback descriptor's ADGameDescription part. + AGS::g_fallbackDesc.desc.language = Common::UNK_LANG; + AGS::g_fallbackDesc.desc.platform = Common::kPlatformDOS; + AGS::g_fallbackDesc.desc.flags = ADGF_NO_FLAGS; + + // // Set the defaults for gameid and extra + _gameid = "ags"; + _extra.clear(); + + // Scan for AGS games + for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + if (file->isDirectory()) + continue; + + Common::String filename = file->getName(); + if (!filename.hasSuffixIgnoreCase(".exe") && + !filename.hasSuffixIgnoreCase(".ags") && + !filename.equalsIgnoreCase("ac2game.dat")) + // Neither, so move on + continue; + + Common::File f; + if (!f.open(allFiles[filename])) + continue; + + if (AGS3::isAGSFile(f)) { + _filename = filename; + + AGS::g_fallbackDesc.desc.gameId = _gameid.c_str(); + AGS::g_fallbackDesc.desc.extra = _extra.c_str(); + AGS::g_fallbackDesc.desc.filesDescriptions[0].fileName = _filename.c_str(); + AGS::g_fallbackDesc.desc.filesDescriptions[0].fileSize = f.size(); + + return ADDetectedGame(&AGS::g_fallbackDesc.desc); + } + } + + return ADDetectedGame(); +} + REGISTER_PLUGIN_STATIC(AGS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, AGSMetaEngineDetection); diff --git a/engines/ags/detection.h b/engines/ags/detection.h index 9ac3d6ae35db..9c0710f37472 100644 --- a/engines/ags/detection.h +++ b/engines/ags/detection.h @@ -39,7 +39,12 @@ struct AGSGameDescription { } // namespace AGS + class AGSMetaEngineDetection : public AdvancedMetaEngineDetection { + mutable Common::String _gameid; + mutable Common::String _extra; + mutable Common::String _filename; + public: AGSMetaEngineDetection(); ~AGSMetaEngineDetection() override {} @@ -53,8 +58,10 @@ class AGSMetaEngineDetection : public AdvancedMetaEngineDetection { } const char *getOriginalCopyright() const override { - return ""; + return "AGS Engine (C) Chris Jones"; } + + ADDetectedGame fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const override; }; #endif diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 267f99bf6158..d3898996177c 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -105,4 +105,20 @@ static const AGSGameDescription GAME_DESCRIPTIONS[] = { { AD_TABLE_END_MARKER } }; +/** + * The fallback game descriptor used by the fallback detection code + */ +static AGSGameDescription g_fallbackDesc = { + { + "", + "", + AD_ENTRY1(0, 0), + Common::UNK_LANG, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO0() + }, + nullptr +}; + } // namespace AGS From 8083b34024cba5bc9fbd55fb1933b79336e93b3a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 30 Jan 2021 18:54:39 -0800 Subject: [PATCH 191/215] AGS: Added tool to scan folders and build detection entries When ScummVM is built with the new ENABLE_AGS_SCANNER define, trying to start any game will instead scan all the folders starting from the current directory downwards, and output text suitable for pasting in the detection tables. --- engines/ags/ags.cpp | 7 +- engines/ags/detection.h | 4 + engines/ags/detection_tables.h | 14 ++- engines/ags/module.mk | 5 + engines/ags/shared/core/assetmanager.cpp | 5 + engines/ags/shared/core/assetmanager.h | 1 + engines/ags/shared/util/stdio_compat.cpp | 6 +- engines/ags/shared/util/stream.h | 79 +++++++++++++ engines/ags/tests/game_scanner.cpp | 136 +++++++++++++++++++++++ engines/ags/tests/game_scanner.h | 65 +++++++++++ 10 files changed, 316 insertions(+), 6 deletions(-) create mode 100644 engines/ags/tests/game_scanner.cpp create mode 100644 engines/ags/tests/game_scanner.h diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 3ecd5815ed3a..35b4c1385bb5 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -57,7 +57,7 @@ #include "ags/shared/util/directory.h" #include "ags/shared/util/path.h" - +#include "ags/tests/game_scanner.h" #ifdef ENABLE_AGS_TESTS #include "ags/tests/test_all.h" #endif @@ -313,6 +313,11 @@ Common::Error AGSEngine::run() { const char *ARGV[] = { "scummvm.exe", filename }; const int ARGC = 2; +#if ENABLE_AGS_SCANNER + AGS3::GameScanner scanner; + scanner.scan(); + return Common::kNoError; +#endif #ifdef ENABLE_AGS_TESTS AGS3::Test_DoAllTests(); return Common::kNoError; diff --git a/engines/ags/detection.h b/engines/ags/detection.h index 9c0710f37472..892a758edf93 100644 --- a/engines/ags/detection.h +++ b/engines/ags/detection.h @@ -37,6 +37,10 @@ struct AGSGameDescription { const PluginVersion *_plugins; }; +extern const PlainGameDescriptor GAME_NAMES[]; + +extern const AGSGameDescription GAME_DESCRIPTIONS[]; + } // namespace AGS diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index d3898996177c..5fb16170cef5 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -22,9 +22,12 @@ namespace AGS { -static const PlainGameDescriptor GAME_NAMES[] = { +const PlainGameDescriptor GAME_NAMES[] = { { "ags", "Adventure Game Studio Game" }, + { "5daysastranger", "5 Days A Stranger" }, + { "7daysaskeptic", "7 Days A Skeptic" }, + { "absentparti", "Absent - Part I" }, { "atotk", "A Tale Of Two Kingdoms" }, { "bcremake", "Black Cauldron Remake" }, { "blackwell1", "The Blackwell Legacy"}, @@ -77,10 +80,13 @@ static const PlainGameDescriptor GAME_NAMES[] = { static const PluginVersion AGSCREDITZ_11[] = { { "agscreditz", 11 }, { nullptr, 0 } }; -static const AGSGameDescription GAME_DESCRIPTIONS[] = { - ENGLISH_PLUGIN("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255, AGSCREDITZ_11), +const AGSGameDescription GAME_DESCRIPTIONS[] = { + ENGLISH_ENTRY("5daysastranger", "5days.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4440143), + ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "465f972675db2da6040518221af5b0ba", 4693374), + ENGLISH_ENTRY("absentparti", "Absent - Part I.exe", "34ca36e3948aae8527dd0e90f0861a75", 31421924), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42740200), + ENGLISH_PLUGIN("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255, AGSCREDITZ_11), ENGLISH_ENTRY("blackwell1", "blackwell1.exe", "605e124cb7e0b56841c471e2d641c224", 18822697), // GOG ENGLISH_ENTRY("blackwell2", "unbound.exe", "5c3a940514d91431e8e1c372018851ca", 14493753), // GOG ENGLISH_ENTRY("blackwell3", "convergence.exe", "2260c1a21aba7ac00baf0100d4ca54f1", 172575801), // GOG @@ -98,7 +104,7 @@ static const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("primordia", "primordia.exe", "22313e59c3233001488c26f18c80cc08", 973495830), // GOG ENGLISH_ENTRY("primordia", "primordia.exe", "f2edc9c3161f1f538df9b4c59fc89e24", 978377890), // GOG ENGLISH_ENTRY("resonance", "resonance.exe", "2e635c22bcbf0ed3d46f1bcde71812d4", 849404957), // GOG - // For some macOS and iOS releases the executable was renamed to ac2game.dat + ENGLISH_ENTRY("mage", "ac2game.dat", "2e822f554994f36e0c62da2acda874da", 30492258), // GOG, Mac ENGLISH_ENTRY("unavowed", "ac2game.dat", "b1ff7d96667707daf4266975cea2bf90", 1755457364), // Steam, Mac diff --git a/engines/ags/module.mk b/engines/ags/module.mk index c04cd2c01a4c..d784b0a09830 100644 --- a/engines/ags/module.mk +++ b/engines/ags/module.mk @@ -317,6 +317,11 @@ MODULE_OBJS = \ plugins/ags_sprite_font/variable_width_font.o \ plugins/ags_sprite_font/variable_width_sprite_font.o +ifdef ENABLE_AGS_SCANNER +MODULE_OBJS += \ + tests/game_scanner.o +endif + ifdef ENABLE_AGS_TESTS MODULE_OBJS += \ tests/test_all.o \ diff --git a/engines/ags/shared/core/assetmanager.cpp b/engines/ags/shared/core/assetmanager.cpp index e3f62a8f1697..337da1c1e0cc 100644 --- a/engines/ags/shared/core/assetmanager.cpp +++ b/engines/ags/shared/core/assetmanager.cpp @@ -78,11 +78,16 @@ AssetManager::~AssetManager() { AssetError AssetManager::ReadDataFileTOC(const String &data_file, AssetLibInfo &lib) { Stream *in = ci_fopen(data_file, Shared::kFile_Open, Shared::kFile_Read); + return ReadDataFileTOC(in, lib); +} + +AssetError AssetManager::ReadDataFileTOC(Stream *in, AssetLibInfo &lib) { if (in) { MFLUtil::MFLError err = MFLUtil::ReadHeader(lib, in); delete in; return (err != MFLUtil::kMFLNoError) ? kAssetErrLibParse : kAssetNoError; } + return kAssetErrNoLibFile; } diff --git a/engines/ags/shared/core/assetmanager.h b/engines/ags/shared/core/assetmanager.h index 383c61b52dc4..987d74d2d475 100644 --- a/engines/ags/shared/core/assetmanager.h +++ b/engines/ags/shared/core/assetmanager.h @@ -92,6 +92,7 @@ class AssetManager { static bool IsDataFile(const String &data_file); // Read data file table of contents into provided struct static AssetError ReadDataFileTOC(const String &data_file, AssetLibInfo &lib); + static AssetError ReadDataFileTOC(Stream *data_file, AssetLibInfo &lib); // NOTE: this group of methods are only temporarily public static AssetError SetDataFile(const String &data_file); diff --git a/engines/ags/shared/util/stdio_compat.cpp b/engines/ags/shared/util/stdio_compat.cpp index 449aa39eb7f9..6ec93ea7d810 100644 --- a/engines/ags/shared/util/stdio_compat.cpp +++ b/engines/ags/shared/util/stdio_compat.cpp @@ -49,7 +49,11 @@ file_off_t ags_ftell(Common::Stream *stream) { } Common::FSNode getFSNode(const char *path) { - Common::FSNode node(ConfMan.get("path")); + Common::FSNode node(path); + if (node.isReadable()) + return node; + + node = Common::FSNode(ConfMan.get("path")); Common::String filePath(path); // If it's the root game folder, return the node for it diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index 4b42de45e756..5489cde19068 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -125,6 +125,85 @@ class ScummVMReadStream : public Common::SeekableReadStream { } }; +class StreamScummVMFile : public Stream { +private: + Common::SeekableReadStream *_stream; + DisposeAfterUse::Flag _disposeAfterUse; +public: + StreamScummVMFile(Common::SeekableReadStream *stream, + DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::NO) : + _stream(stream), _disposeAfterUse(disposeAfterUse) {} + ~StreamScummVMFile() override { + Close(); + } + + void Close() { + if (_disposeAfterUse == DisposeAfterUse::YES) + delete _stream; + _stream = nullptr; + } + + bool IsValid() const override { return _stream != nullptr; } + bool EOS() const override { return _stream->eos(); } + soff_t GetLength() const override { return _stream->size(); } + soff_t GetPosition() const override { return _stream->pos(); } + bool CanRead() const override { return true; } + bool CanWrite() const override { return false; } + bool CanSeek() const override { return true; } + + size_t Read(void *buffer, size_t size) override { + return _stream->read(buffer, size); + } + int32_t ReadByte() override { return _stream->readByte(); } + size_t Write(const void *buffer, size_t size) override { return 0; } + int32_t WriteByte(uint8_t b) override { return 0; } + + int8_t ReadInt8() override { return (int8)_stream->readByte(); } + int16_t ReadInt16() override { return _stream->readSint16LE(); } + int32_t ReadInt32() override { return _stream->readSint32LE(); } + int64_t ReadInt64() override { return _stream->readSint64LE(); } + bool ReadBool() override { return _stream->readByte() != 0; } + size_t ReadArray(void *buffer, size_t elem_size, size_t count) override { + return _stream->read(buffer, elem_size * count) / elem_size; + } + size_t ReadArrayOfInt8(int8_t *buffer, size_t count) override { + return _stream->read(buffer, count); + } + size_t ReadArrayOfInt16(int16_t *buffer, size_t count) override { + for (size_t i = 0; i < count; ++i) + *buffer++ = _stream->readSint16LE(); + return count; + } + size_t ReadArrayOfInt32(int32_t *buffer, size_t count) override { + for (size_t i = 0; i < count; ++i) + *buffer++ = _stream->readSint32LE(); + return count; + } + size_t ReadArrayOfInt64(int64_t *buffer, size_t count) override { + for (size_t i = 0; i < count; ++i) + *buffer++ = _stream->readSint64LE(); + return count; + } + + size_t WriteInt8(int8_t val) override { return 0; } + size_t WriteInt16(int16_t val) override { return 0; } + size_t WriteInt32(int32_t val) override { return 0; } + size_t WriteInt64(int64_t val) override { return 0; } + size_t WriteBool(bool val) override { return 0; } + size_t WriteArray(const void *buffer, size_t elem_size, size_t count) override { return 0; } + size_t WriteArrayOfInt8(const int8_t *buffer, size_t count) override { return 0; } + size_t WriteArrayOfInt16(const int16_t *buffer, size_t count) override { return 0; } + size_t WriteArrayOfInt32(const int32_t *buffer, size_t count) override { return 0; } + size_t WriteArrayOfInt64(const int64_t *buffer, size_t count) override { return 0; } + + bool Seek(soff_t offset, StreamSeek origin = kSeekCurrent) override { + return _stream->seek(offset, origin); + } + + bool HasErrors() const override { return _stream->err(); } + bool Flush() override { return true; } +}; + } // namespace Shared } // namespace AGS } // namespace AGS3 diff --git a/engines/ags/tests/game_scanner.cpp b/engines/ags/tests/game_scanner.cpp new file mode 100644 index 000000000000..3b4a7b6b4420 --- /dev/null +++ b/engines/ags/tests/game_scanner.cpp @@ -0,0 +1,136 @@ +/* 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 "ags/tests/game_scanner.h" +#include "ags/detection.h" +#include "ags/shared/ac/gamesetupstruct.h" +#include "ags/shared/core/assetmanager.h" +#include "ags/shared/util/multifilelib.h" +#include "ags/shared/util/string.h" +#include "ags/engine/main/game_file.h" +#include "common/config-manager.h" +#include "common/file.h" +#include "common/md5.h" +#include "common/unzip.h" + +namespace AGS3 { + +extern bool define_gamedata_location(const AGS::Shared::String &exe_path); +extern bool engine_try_init_gamedata(AGS::Shared::String gamepak_path); +extern GameSetupStruct game; + +void GameScanner::scan() { + Common::FSNode folder("."); //ConfMan.get("path")); + scanFolder(folder); + + for (EntryMap::iterator it = _games.begin(); it != _games.end(); ++it) { + debug("{ \"%s\", \"%s\" },", it->_key.c_str(), it->_value._gameName.c_str()); + } + debug(""); + + for (EntryMap::iterator it = _games.begin(); it != _games.end(); ++it) { + debug("ENGLISH_ENTRY(\"%s\", \"%s\", \"%s\", %u),", + it->_key.c_str(), it->_value._filename.c_str(), + it->_value._md5.c_str(), it->_value._filesize); + } + debug(""); +} + +void GameScanner::scanFolder(const Common::FSNode &folder) { + Common::FSList fslist; + folder.getChildren(fslist, Common::FSNode::kListAll); + + for (uint idx = 0; idx < fslist.size(); ++idx) { + Common::FSNode node = fslist[idx]; + Common::String filename = node.getName(); + + if (node.isDirectory()) { + scanFolder(node); + } else if (filename.hasSuffixIgnoreCase(".exe") || + filename.hasSuffixIgnoreCase(".ags") || + filename.equalsIgnoreCase("ac2game.dat")) { + Common::String path = node.getPath(); + scanFile(path); + } + } +} + +void GameScanner::scanFile(const Common::String &filename) { + Common::File f; + Common::FSNode fsNode(filename); + if (!f.open(fsNode)) + return; + + int32 size = f.size(); + Common::String md5 = Common::computeStreamMD5AsString(f, 5000); + + // Check if it's an already known game + const ::AGS::AGSGameDescription *gameP = ::AGS::GAME_DESCRIPTIONS; + for (; gameP->desc.gameId; ++gameP) { + if (size == gameP->desc.filesDescriptions[0].fileSize && + md5 == gameP->desc.filesDescriptions[0].md5) + // Known game, so skip + return; + } + + // Check the game file + AGS::Shared::AssetLibInfo lib; + AGS::Shared::StreamScummVMFile *stream = new AGS::Shared::StreamScummVMFile(&f); + if (AGS::Shared::AssetManager::ReadDataFileTOC(stream, lib) != AGS::Shared::kAssetNoError) + return; + f.close(); + + AGS::Shared::AssetManager::DestroyInstance(); + AGS::Shared::AssetManager::CreateInstance(); + AGS::Shared::AssetManager::SetDataFile(filename); + + if (!engine_try_init_gamedata(filename)) + return; + + AGS::Shared::HError err = preload_game_data(); + if (!err) + return; + + // Add an entry for the found game + Entry e; + e._filename = fsNode.getName(); + e._filesize = size; + e._gameName = game.gamename; + e._md5 = md5; + + Common::String id = convertGameNameToId(e._gameName); + _games[id] = e; +} + +Common::String GameScanner::convertGameNameToId(const Common::String &name) { + Common::String result; + + for (uint idx = 0; idx < name.size(); ++idx) { + char c = name[idx]; + if (Common::isAlnum(c)) + result += tolower(c); + } + + return result; +} + +} // namespace AGS3 diff --git a/engines/ags/tests/game_scanner.h b/engines/ags/tests/game_scanner.h new file mode 100644 index 000000000000..a798222fd6bb --- /dev/null +++ b/engines/ags/tests/game_scanner.h @@ -0,0 +1,65 @@ +/* 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 "common/hashmap.h" +#include "common/fs.h" + +namespace AGS3 { + +/** + * A support class for scanning a hierarchy of folders for AGS games, + * and printing output suitable for posting into the detection tables. + * Scanning starts from the current directory when ScummVM is started + */ +class GameScanner { + struct Entry { + Common::String _gameName; + Common::String _filename; + Common::String _md5; + size_t _filesize; + }; +private: + typedef Common::HashMap EntryMap; + EntryMap _games; +private: + /** + * Scan a folder for AGS games + */ + void scanFolder(const Common::FSNode &folder); + + /** + * Scans a single file that may be an AGS game + */ + void scanFile(const Common::String &filename); + + /** + * Convert a game name to an appropriate game Id + */ + static Common::String convertGameNameToId(const Common::String &name); +public: + /** + * Main execution method + */ + void scan(); +}; + +} // namespace AGS3 From bbb252c80064808e76b1a151f360cb50a3f26590 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 31 Jan 2021 12:22:39 -0800 Subject: [PATCH 192/215] AGS: Fixes for game scanner tool --- engines/ags/ags.cpp | 2 ++ engines/ags/tests/game_scanner.cpp | 37 +++++++++++++++++++++++------- engines/ags/tests/game_scanner.h | 12 +++++++--- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 35b4c1385bb5..a294f4761474 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -57,7 +57,9 @@ #include "ags/shared/util/directory.h" #include "ags/shared/util/path.h" +#ifdef ENABLE_AGS_SCANNER #include "ags/tests/game_scanner.h" +#endif #ifdef ENABLE_AGS_TESTS #include "ags/tests/test_all.h" #endif diff --git a/engines/ags/tests/game_scanner.cpp b/engines/ags/tests/game_scanner.cpp index 3b4a7b6b4420..73e85803495c 100644 --- a/engines/ags/tests/game_scanner.cpp +++ b/engines/ags/tests/game_scanner.cpp @@ -29,8 +29,8 @@ #include "ags/engine/main/game_file.h" #include "common/config-manager.h" #include "common/file.h" +#include "common/hashmap.h" #include "common/md5.h" -#include "common/unzip.h" namespace AGS3 { @@ -39,18 +39,23 @@ extern bool engine_try_init_gamedata(AGS::Shared::String gamepak_path); extern GameSetupStruct game; void GameScanner::scan() { + detectClashes(); + Common::FSNode folder("."); //ConfMan.get("path")); scanFolder(folder); - for (EntryMap::iterator it = _games.begin(); it != _games.end(); ++it) { - debug("{ \"%s\", \"%s\" },", it->_key.c_str(), it->_value._gameName.c_str()); + Common::HashMap gameDescs; + for (EntryArray::iterator it = _games.begin(); it != _games.end(); ++it) { + if (!gameDescs.contains(it->_id)) + debug("{ \"%s\", \"%s\" },", it->_id.c_str(), it->_gameName.c_str()); + gameDescs[it->_id] = true; } debug(""); - for (EntryMap::iterator it = _games.begin(); it != _games.end(); ++it) { + for (EntryArray::iterator it = _games.begin(); it != _games.end(); ++it) { debug("ENGLISH_ENTRY(\"%s\", \"%s\", \"%s\", %u),", - it->_key.c_str(), it->_value._filename.c_str(), - it->_value._md5.c_str(), it->_value._filesize); + it->_id.c_str(), it->_filename.c_str(), + it->_md5.c_str(), it->_filesize); } debug(""); } @@ -115,10 +120,10 @@ void GameScanner::scanFile(const Common::String &filename) { e._filename = fsNode.getName(); e._filesize = size; e._gameName = game.gamename; + e._id = convertGameNameToId(e._gameName); e._md5 = md5; - Common::String id = convertGameNameToId(e._gameName); - _games[id] = e; + _games.push_back(e); } Common::String GameScanner::convertGameNameToId(const Common::String &name) { @@ -133,4 +138,20 @@ Common::String GameScanner::convertGameNameToId(const Common::String &name) { return result; } +void GameScanner::detectClashes() { + Common::HashMap gameIds; + Common::HashMap gameNames; + + const PlainGameDescriptor *nameP = ::AGS::GAME_NAMES; + for (; nameP->gameId; ++nameP) { + if (gameIds.contains(nameP->gameId)) + debug("Duplicate game Id: %s", nameP->gameId); + gameIds[nameP->gameId] = true; + + if (gameNames.contains(nameP->description)) + debug("Duplicate game name: %s", nameP->description); + gameNames[nameP->description] = true; + } +} + } // namespace AGS3 diff --git a/engines/ags/tests/game_scanner.h b/engines/ags/tests/game_scanner.h index a798222fd6bb..b87a41190c46 100644 --- a/engines/ags/tests/game_scanner.h +++ b/engines/ags/tests/game_scanner.h @@ -20,7 +20,7 @@ * */ -#include "common/hashmap.h" +#include "common/array.h" #include "common/fs.h" namespace AGS3 { @@ -32,14 +32,15 @@ namespace AGS3 { */ class GameScanner { struct Entry { + Common::String _id; Common::String _gameName; Common::String _filename; Common::String _md5; size_t _filesize; }; private: - typedef Common::HashMap EntryMap; - EntryMap _games; + typedef Common::Array EntryArray; + EntryArray _games; private: /** * Scan a folder for AGS games @@ -55,6 +56,11 @@ class GameScanner { * Convert a game name to an appropriate game Id */ static Common::String convertGameNameToId(const Common::String &name); + + /** + * Detects clashes with game Ids in the existing detection table. + */ + static void detectClashes(); public: /** * Main execution method From 9f70c2b30fbb4825fd5d4bf6bbd5861c1c134a91 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 31 Jan 2021 12:23:04 -0800 Subject: [PATCH 193/215] AGS: Added all games from agsarchives.com to detection table --- engines/ags/detection_tables.h | 2367 +++++++++++++++++++++++++++++++- 1 file changed, 2324 insertions(+), 43 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 5fb16170cef5..2374d76e9ca4 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -25,65 +25,1188 @@ namespace AGS { const PlainGameDescriptor GAME_NAMES[] = { { "ags", "Adventure Game Studio Game" }, + // Pre-2.5 games that aren't supported by the current AGS engine + { "qfg412", "Quest for Glory 4 1/2" }, + + // Post-2.5 games that are likely supported by the AGS engine { "5daysastranger", "5 Days A Stranger" }, { "7daysaskeptic", "7 Days A Skeptic" }, - { "absentparti", "Absent - Part I" }, { "atotk", "A Tale Of Two Kingdoms" }, { "bcremake", "Black Cauldron Remake" }, - { "blackwell1", "The Blackwell Legacy"}, - { "blackwell2", "Blackwell Unbound"}, - { "blackwell3", "The Blackwell Convergence"}, - { "blackwell4", "The Blackwell Deception"}, - { "blackwell5", "The Blackwell Epiphany"}, - { "kq2agdi", "Kings Quest II - Romancing The Stones" }, + { "blackwell1", "The Blackwell Legacy" }, + { "blackwell2", "Blackwell Unbound" }, + { "blackwell3", "The Blackwell Convergence" }, + { "blackwell4", "The Blackwell Deception" }, + { "blackwell5", "The Blackwell Epiphany" }, + { "blackwellconvergence", "Blackwell Convergence" }, + { "blackwelllegacydemo", "Blackwell Legacy Demo" }, + { "blackwellunbounddemo", "Blackwell Unbound Demo" }, + { "geminirue", "Gemini Rue" }, + { "goldenwake", "A Golden Wake" }, + { "kathyrain", "Kathy Rain" }, { "kq1agdi", "King's Quest I: Quest for the Crown Remake" }, { "kq2agdi", "King's Quest II: Romancing The Stones" }, { "kq3agdi", "King's Quest III Redux: To Heir is Human" }, - { "geminirue", "Gemini Rue"}, - { "goldenwake", "A Golden Wake"}, - { "kathyrain", "Kathy Rain"}, - { "qfi", "Quest for Infamy"}, - { "oott", "Order of the Thorne: The King's Challenge"}, - { "primordia", "Primordia"}, - { "resonance", "Resonance"}, - { "mage", "Mage's Initiation: Reign of the Elements"}, - { "unavowed", "Unavowed"}, + { "mage", "Mage's Initiation: Reign of the Elements" }, + { "oott", "Order of the Thorne: The King's Challenge" }, + { "primordia", "Primordia" }, + { "qfi", "Quest for Infamy" }, + { "resonance", "Resonance" }, + { "unavowed", "Unavowed" }, + + // Unsorted games + { "10waysfromsunday", "10 Ways from Sunday" }, + { "1dayamosquito", "1 day a mosquito" }, + { "2034acaftercanadaii", "2034 A.C. (After Canada) II" }, + { "24hours", "24 Hours" }, + { "3piggiesalpha", "3piggiesAlpha" }, + { "46memorylane", "46 Memory Lane" }, + { "4ofclubs", "4 of Clubs" }, + { "6daysasacrifice", "6 Days A Sacrifice" }, + { "6mornings", "6mornings" }, + { "aazor", "Aazor" }, + { "abducted", "ABDUCTED" }, + { "absent", "Absent" }, + { "absentparti", "Absent - Part I" }, + { "access", "_Access" }, + { "aceking", "Ace King" }, + { "acequest", "Ace Quest" }, + { "achequest", "Ache Quest" }, + { "achristmasblunder", "A Christmas Blunder" }, + { "aciddd", "ACIDDD" }, + { "acureforthecommoncold", "A Cure for the Common Cold" }, + { "adaywithmichael", "A Day with Michael" }, + { "adventurequest", "Adventure Quest" }, + { "adventurequest2", "Adventure Quest 2" }, + { "adventuresofjoshanddyan", "Adventures of Josh and Dyan" }, + { "adventuresofmaxfaxepisode1", "Adventures of Max Fax (episode 1)" }, + { "adventuresofprincessmarian", "Adventures of Princess Marian" }, + { "adventuretheinsidejob", "Adventure: The Inside Job" }, + { "aerinde", "Aerinde" }, + { "aeronuts", "AeroNuts" }, + { "afriendindeed", "A Friend Indeed ..." }, + { "afrojones", "Afro Jones" }, + { "afterashadow", "After a Shadow" }, + { "agenthudson", "Agent Hudson" }, + { "agenttrinityepisode0theultimatum", "Agent Trinity - Episode 0 - The Ultimatum" }, + { "aggghost", "A G-G-Ghost!" }, + { "agitprop", "AGITPROP" }, + { "agnosticchicken", "Agnostic Chicken" }, + { "ags-mi3", "AGS MI3" }, + { "agsawards2008ceremony", "AGS Awards 2008 Ceremony " }, + { "agsdarts", "AGS Darts" }, + { "agsinvaders", "AGS Invaders" }, + { "agsjukebox", "AGS JukeBox" }, + { "agsmoduletester", "Ags Module Tester" }, + { "agsyahtzee2", "AGS Yahtzee 2" }, + { "agsyathzee", "AGS Yathzee" }, + { "agunshotinroom37", "A Gunshot in Room 37" }, + { "ahmetsagsfightgameremix", "Ahmet's AGS Fight Game Remix" }, + { "ainthegoffantabulousw", "A in the G of Fantabulous W" }, + { "airwaveifoughtthelawandthelawone", "~airwave~ - I Fought the Law, And the Law One" }, + { "akumayosagschess275", "Akumayo's AGS Chess 2.75" }, + { "alansaveschristmasandmostoftheworldtoo", "Alan saves Christmas (and most of the world too)" }, + { "albatheexplorer", "Alba the Explorer" }, + { "alienattack", "Alien Attack" }, + { "alienpuzzleinvasion", "Alien Puzzle Invasion" }, + { "alienrapeescape", "Alien Rape Escape" }, + { "alienthreat", "Alien Threat" }, + { "alientimezone", "Alien Time Zone" }, + { "aloneinthenight", "Alone in the Night" }, + { "alphadog", "Alpha Dog" }, + { "alphax", "Alpha X" }, + { "alquest1demo", "Al-Quest 1 Demo" }, + { "alysvsthephantomfelinefoe", "Alys vs. The Phantom Feline Foe" }, + { "amagicstone", "A magic stone" }, + { "amotospuf", "Amotos Puf" }, + { "amtag", "AMTAG" }, + { "anighttoremember", "A Night to Remember" }, + { "anna", "Anna" }, + { "annieandroidautomatedaffection", "Annie Android: Automated Affection" }, + { "anoblegame", "A Noble Game" }, + { "anthonysessay", "Anthony's Essay" }, + { "anticipatingmurder", "Anticipating Murder" }, + { "antiheroes", "Anti-Heroes" }, + { "apiratestale", "A pirates tale" }, + { "aplaceinthesun", "A Place In The Sun" }, + { "apprentice", "Apprentice" }, + { "apprentice2", "Apprentice 2" }, + { "apprenticedeluxe", "Apprentice Deluxe" }, + { "aprofoundjourney", "A Profound Journey" }, + { "archeos", "Archeos" }, + { "arewethereyet", "Are we there yet?" }, + { "armageddonmargaret", "Armageddon Margaret" }, + { "asecondface", "A SECOND FACE" }, + { "ashortnightmare", "A Short Nightmare" }, + { "asporia", "Asporia" }, + { "asterix", "Asterix" }, + { "astranded", "Astranded" }, + { "astron", "Astron" }, + { "aswinpathv01beta", "Aswin path v 0.1 beta" }, + { "ataleofbetrayal", "A Tale Of Betrayal" }, + { "ataleoftwokingdoms", "A Tale of Two Kingdoms" }, + { "atapi", "Atapi" }, + { "atotkjukebox", "ATOTK jukebox" }, + { "atreatandsometricks", "A Treat and Some Tricks" }, + { "aunaturel", "Au Naturel" }, + { "automation", "Automation" }, + { "averyspecialdog", "A very special dog" }, + { "awakener", "Awakener" }, + { "awakening", "Awakening" }, + { "awakeningofthesphinx", "Awakening of the Sphinx" }, + { "awalkindatomb", "A walk in da tomb" }, + { "awalkinthepark", "A Walk in the Park" }, + { "axmasevetale", "A Xmas Eve Tale" }, + { "backdoorman", "Back Door Man" }, + { "badluck", "BAD LUCK" }, + { "baldysadventure", "Baldy's Adventure" }, + { "baltazarthefamiliar", "Baltazar the Familiar" }, + { "bananamandemo", "Banana Man Demo" }, + { "bananaracer", "Banana Racer" }, + { "barndilemma", "Barn Dilemma" }, + { "barnrunner5part1", "Barn Runner 5 (Part 1)" }, + { "barnrunner5part2", "Barn Runner 5 (Part 2)" }, + { "barnrunnerholiday2", "Barn Runner: Holiday 2" }, + { "bartsquestfortv", "Bart's Quest For TV" }, + { "battlewarriors", "Battle Warriors" }, + { "beacon", "Beacon" }, + { "bear", "Bear" }, + { "beasts", "Beasts" }, + { "beautiesandbeasts", "Beauties and Beasts" }, + { "benjaminjordan", "Benjamin Jordan" }, + { "benjordancase1", "Ben Jordan Case 1" }, + { "bentheredanthat", "Ben There, Dan That!" }, + { "bernardsroom", "Bernards Room" }, + { "besieged", "besieged" }, + { "bestowersofeternity", "Bestowers of Eternity" }, + { "beyondreality", "Beyond Reality " }, + { "beyondterror", "BEYOND TERROR" }, + { "beyondthehorizon", "Beyond the horizon" }, + { "bigbadwolf3lilpiggies", "Big Bad Wolf & 3 Lil' Piggies" }, + { "bigglesonmars", "Biggles On Mars" }, + { "billyboysimportantwinelottery", "Billy Boy's Important Wine Lottery" }, + { "birdy", "Birdy" }, + { "bj7thecardinalsins", "BJ7: The Cardinal Sins" }, + { "bjcase2", "BJ Case 2" }, + { "bjcase3", "BJ Case 3" }, + { "bjcase4", "BJ Case 4" }, + { "bjcase5", "BJ Case 5" }, + { "bjcase6", "BJ Case 6" }, + { "blackmailinbrooklyn", "Blackmail In Brooklyn" }, + { "blackmorph", "Black Morph" }, + { "blackuddertodoubloonornottodoubloon", "Blackudder: To Doubloon or not to Doubloon" }, + { "bluemoon", "Blue Moon" }, + { "boardquest", "Board Quest" }, + { "bob", "BOB" }, + { "bobencavale", "Bob en cavale" }, + { "bobgoeshome", "Bob Goes Home" }, + { "bobgoeshomedeluxe", "Bob Goes Home Deluxe" }, + { "bobsquest1", "Bob's Quest 1" }, + { "bogsadventure", "Bog's Adventure" }, + { "boom", "Boom" }, + { "bowserquirkquest", "Bowser Quirk Quest" }, + { "box", "Box" }, + { "boyindahood", "Boy in da hood" }, + { "bradbradsonkeyquest", "Brad Bradson: Key Quest" }, + { "breakdownbyonedollar", "Breakdown by OneDollar" }, + { "bsg78unexpectedattherisingstar", "BSG78 - Unexpected at the Rising Star" }, + { "btd", "BTD" }, + { "bubsythebobcatinripvanbubsystarringbubsy", "Bubsy The Bobcat In Rip Van Bubsy Starring Bubsy" }, + { "buccaneer", "Buccaneer" }, + { "bullettrain", "Bullet Train" }, + { "bunawantsbeer", "Buna Wants Beer" }, + { "bunnyquest", "BunnyQuest" }, + { "burymeinthesand", "Bury Me in the Sand" }, + { "butcherstanys", "Butcher Stanys" }, + { "bytheswordconspiracy", "By the Sword: Conspiracy" }, + { "calebsdrunkenadventure", "CALEB'S DRUNKEN ADVENTURE" }, + { "calsoon2", "Calsoon 2" }, + { "capricorn", "CAPRICORN" }, + { "captaincringe", "Captain Cringe" }, + { "carrin", "Carrin" }, + { "carrotbobinzxspeccyworld", "Carrot Bob in ZX speccy world" }, + { "casablancathedayafter", "Casablanca The Day After" }, + { "castleoffire", "Castle of Fire" }, + { "catacombic", "Catacombic" }, + { "catapault", "CATapault" }, + { "cayannepepper", "CAYANNE PEPPER" }, + { "cedricandtherevolution", "Cedric and the Revolution" }, + { "celticchaos2fishermensfiends", "Celtic Chaos 2 - Fishermen's fiends" }, + { "chalksquest", "Chalk's Quest" }, + { "charliefoxtrot", "Charlie Foxtrot" }, + { "chatroom", "Chatroom" }, + { "cheerfulscience", "Cheerful Science" }, + { "chekken", "cheKKen" }, + { "chemin", "Chemin" }, + { "chezapa", "Chez Apa" }, + { "chickchaser", "Chick Chaser" }, + { "chicken", "Chicken" }, + { "chickenfraction", "Chicken Fraction" }, + { "chinesecheckers", "Chinese Checkers" }, + { "christmaspresent", "Christmas Present" }, + { "christmasquest", "Christmas Quest" }, + { "christmasquest2", "Christmas Quest 2" }, + { "christmasquest3santaslittlehelpdesk", "Christmas Quest 3: Santa's Little Helpdesk" }, + { "cirquedezale", "Cirque de Zale" }, + { "claire", "Claire" }, + { "classnotesv11", "Class Notes v1.1" }, + { "clex", "Clex" }, + { "clipl2heblinna", "Clip l2heb linna" }, + { "clubofevil", "Club of Evil" }, + { "coeldeckaflightgame", "Coel Decka Flight Game" }, + { "coinrush2", "Coin Rush 2" }, + { "colinsimpsonleavesemployme", "Colin Simpson Leaves Employme" }, + { "colourclash", "Colour Clash" }, + { "colourwise", "ColourWise" }, + { "colourwiseleveleditor", "ColourWise - Level Editor" }, + { "columbuslander", "Columbus Lander" }, + { "comradecitizenpart1", "Comrade Citizen (part 1)" }, + { "confessionsofacatburglar", "Confessions Of A Cat Burglar" }, + { "conspiracybelowzero", "Conspiracy: Below-Zero" }, + { "conspiracyofsongo", "Conspiracy of Songo" }, + { "constancethebarbarian", "Constance the Barbarian" }, + { "cosmos", "Cosmos" }, + { "cosmosquesti", "Cosmos Quest I" }, + { "cosmosquestii", "Cosmos Quest II" }, + { "cosmosquestiii", "Cosmos Quest III" }, + { "cougarsquestforfreedom", "Cougar's Quest for Freedom" }, + { "counterfeit", "Counterfeit" }, + { "cow", "cow" }, + { "coyote", "Coyote" }, + { "craftofevil", "Craft Of Evil" }, + { "crashevadedestroy", "Crash! Evade! Destroy!" }, + { "crave", "Crave" }, + { "crypt", "Crypt" }, + { "cryptic", "Cryptic" }, + { "csihunt1", "CSI Hunt 1" }, + { "cspb", "CSPB" }, + { "cuentosinconclusos", "Cuentos Inconclusos" }, + { "cyberjack", "cyberJACK" }, + { "daleks", "Daleks" }, + { "dalesfilmquest", "Dale's Film Quest" }, + { "damsel", "Damsel" }, + { "dancetilyoudrop", "Dance Til' You Drop!" }, + { "danewguys", "Da New Guys" }, + { "dangerouslandstournamentrpg", "DangerousLands Tournament+RPG" }, + { "dannydreadisoncall", "Danny Dread is On Call" }, + { "darkcave", "Dark Cave" }, + { "darkofnight", "Dark of Night" }, + { "darktimesmerrychristmas", "Dark Times (Merry Christmas)" }, + { "darum", "Darum" }, + { "davegeneric", "Dave Generic" }, + { "davidletterman", "David Letterman" }, + { "dawnswonderedatagesend", "Dawns Wondered: At Age's End" }, + { "ddddd", "DDDDD" }, + { "deadmeat", "Dead Meat" }, + { "deadofwinter", "Dead of Winter" }, + { "deathandtransfiguration", "Death and Transfiguration" }, + { "deathofanangel", "Death of an Angel" }, + { "deathsdoor", "Death's Door" }, + { "deathsquest", "Death's Quest" }, + { "deathworeendlessfeathersdisk1", "Death Wore Endless Feathers Disk 1" }, + { "demogame", "Demo Game" }, + { "demonday", "Demon Day" }, + { "derverschwundenehusky", "Der verschwundene Husky" }, + { "detectivegallo", "Detective Gallo" }, + { "detention", "Detention" }, + { "devochkaquest", "DevochkaQuest" }, + { "dgsearchofthebatterie", "DG: search of the batterie" }, + { "diamondsintheroughdemo", "Diamonds in the Rough DEMO" }, + { "diemaskennyarlathoteps", "Die Masken Nyarlathoteps" }, + { "disquiet", "Disquiet" }, + { "doctormaze", "DOCTOR MAZE" }, + { "doctormuttonchop", "Doctor Muttonchop" }, + { "donnaavengerofblood", "Donna: Avenger of Blood" }, + { "donniedarko", "Donnie Darko" }, + { "donspillacyconspiracyquest", "Don Spillacy Conspiracy Quest" }, + { "donthedweebdancedilemma", "Don the Dweeb: Dance Dilemma" }, + { "dontworryillbringthebeer", "Don't Worry, I'll Bring The Beer!" }, + { "dovadulasburn", "DoVaDuLa'S BuRn" }, + { "downfall", "Downfall" }, + { "dragonorb", "Dragon Orb" }, + { "dragontales", "DragonTales" }, + { "dreadmacfarlane", "Dread Mac Farlane" }, + { "dreadmacfarlane2", "Dread Mac Farlane 2" }, + { "dreamagine", "Dreamagine" }, + { "dreamer", "Dreamer" }, + { "dreamsequence", "dream sequence" }, + { "drlutztimetravelmachine", "Dr.Lutz Time Travel Machine" }, + { "dumbassdriversdemo", "Dumb.Ass Drivers! DEMO" }, + { "dungeonhands", "Dungeon Hands" }, + { "duskhunters", "Dusk Hunters" }, + { "dusttowater", "Dust to Water" }, + { "dutyandbeyond", "Duty and Beyond" }, + { "duzzquest", "DuzzQuest" }, + { "duzzquest2", "DuzzQuest2" }, + { "dysmaton", "Dysmaton" }, + { "earlbobbyislookingforaloodemo", "Earl Bobby is looking for a Loo - DEMO" }, + { "earlbobbyislookingforhisshoes", "Earl Bobby is looking for his Shoes" }, + { "earlbobbysballs", "Earl Bobby's Balls" }, + { "earlmansinthebreakout", "Earl Mansin: The Breakout" }, + { "earthlingpriorities", "Earthling Priorities" }, + { "easterislanddefender", "Easter Island Defender" }, + { "easy3d", "Easy3D" }, + { "edmund", "Edmund" }, + { "educatingadventuresofgirlandrabbit", "Educating Adventures of Girl and Rabbit" }, + { "eerieblue", "Eerie Blue" }, + { "electrctgui", "electrctGUI" }, + { "elevator", "Elevator" }, + { "elfer10", "Elfer 1.0" }, + { "elfmotorsinc", "Elf Motors Inc." }, + { "elforescuecraby", "ELFO: RESCUE CRABY" }, + { "eliminationbyimprovisation", "Elimination by Improvisation" }, + { "emeraldeyes", "Emerald Eyes" }, + { "emilyenough", "Emily Enough" }, + { "emmarodedemo", "Emma Ro?de (DEMO)" }, + { "emptymindblankfate", "Empty Mind - Blank Fate" }, + { "enoworld", "Enoworld" }, + { "enterthestory", "Enter The Story" }, + { "equilibrium", "Equilibrium" }, + { "erictheanteater", "Eric the Anteater" }, + { "erkadventuresinstoneagerealestate", "Erk: Adventures in Stoneage Real Estate" }, + { "errand", "Errand" }, + { "escape", "Escape" }, + { "escapefromasmallroom", "Escape From a Small Room" }, + { "escapefromevergreenforest", "Escape From Evergreen Forest" }, + { "escapefromlurrilous", "Escape from Lurrilous" }, + { "escapefromthesalemmoons", "Escape From The Salem Moons" }, + { "escapefromthezombiecity", "Escape From The Zombie City" }, + { "escapetheship", "Escape the ship" }, + { "esper", "ESPER" }, + { "eternallyus", "Eternally Us" }, + { "eventtimer", "Event Timer" }, + { "exclamation", "!" }, + { "exit", "Exit" }, + { "fadingshades", "Fading Shades" }, + { "fakethemoonlanding", "Fake the moon landing" }, + { "fallenangel", "Fallen Angel" }, + { "fallensoldier", "fallen soldier" }, + { "fanbots", "Fanbots" }, + { "farnowhere", "FAR NOWHERE" }, + { "fasmo", "Fasmo!" }, + { "fasmogoeswest", "Fasmo Goes West" }, + { "fbiquest", "FBI Quest" }, + { "fearaphobia", "FEARAPHOBIA" }, + { "featherweight", "Featherweight" }, + { "femspray", "FemSpray" }, + { "fengshuiandtheartoftvreception", "Feng Shui And The Art Of TV Reception" }, + { "feuersturmkapitel1", "Feuersturm - Kapitel 1" }, + { "feuersturmkapitel2", "Feuersturm - Kapitel 2" }, + { "feuersturmkapitel3", "Feuersturm - Kapitel 3" }, + { "fifa2003pro", "Fifa2003Pro" }, + { "fight", "Fight" }, + { "fightgame", "Fight Game" }, + { "fireflystory3d", "Firefly story 3D" }, + { "flamebarrel", "Flame Barrel" }, + { "flashbax", "Flashbax" }, + { "flowergirl", "flowergirl" }, + { "fluxworld", "Flux World" }, + { "forcemajeureiithezone", "Force majeure II: The Zone" }, + { "forfrogssakegetthefrogout", "FOR FROGS SAKE! GET THE FROG OUT!" }, + { "forgettendeath", "Forgetten Death " }, + { "fortressofwonders", "Fortress of Wonders" }, + { "fountainofunicorns", "Fountain of Unicorns" }, + { "fountainofyouthdemo", "Fountain of Youth Demo" }, + { "framed", "Framed!" }, + { "frankenpooper", "Frankenpooper" }, + { "frankthefarmhandpart1", "Frank the Farmhand Part 1" }, + { "frankthefarmhandpart2", "Frank the Farmhand Part 2" }, + { "franticfrankoabergzwerggoneberserk", "Frantic Franko: A Bergzwerg Gone Berserk" }, + { "frasiercraneseattlerampage", "Frasier Crane: Seattle Rampage" }, + { "fredandbarneymeetthefuture", "Fred and Barney meet the future" }, + { "fribbeldib", "Fribbeldib" }, + { "frogisland", "Frog Island" }, + { "fsis1000000quest", "FSi's $1000000 Quest!" }, + { "fsisalienation", "FSi's Alienation!" }, + { "fsiscotmattcehotsvd", "FSi's CotMATtCEHotSVD" }, + { "fsismhcfhr", "FSi's MHCFHR!" }, + { "fsispowercowfromuranus", "FSi's POWERCOW FROM URANUS!" }, + { "fulkinthedreamthaus", "fulk in the dreamt haus" }, + { "funsunmishaps", "Fun, Sun & Mishaps" }, + { "funwithnumbers", "Fun With Numbers" }, + { "gabyking", "GabyKing" }, + { "gamesgalore", "GAMES GALORE" }, + { "gassesuittollis3demo", "Gasse Suit Tollis 3 DEMO" }, + { "gatewayremake", "Gateway Remake" }, + { "genbu", "Genbu" }, + { "geometricshapes1circleboy", "Geometric Shapes 1: Circleboy" }, + { "gesundheitdemo", "Gesundheit! Demo" }, + { "getawayfrompluto", "Get away from PLUTO" }, + { "getfood", "Get food" }, + { "ghostdream", "Ghostdream" }, + { "ghosting", "Ghosting" }, + { "ghostvoyage", "Ghost Voyage" }, + { "glitchquest", "Glitch Quest" }, + { "glitchquestnofun", "Glitch Quest (nofun)" }, + { "gnomeshomebrewingadventure", "Gnome's Homebrewing Adventure" }, + { "gnrblexags", "Gnrblex_AGS" }, + { "goneboatfishin", "Gone Boat Fishin'" }, + { "goodmorningmrgingerbread", "Good Morning, Mr. Gingerbread!" }, + { "goodsantabadsanta", "GoodSanta, BadSanta" }, + { "gotalight", "Got a Light?" }, + { "gpslostadventure", "G P's Lost Adventure" }, + { "graveyard", "Graveyard" }, + { "gremlin", "Gremlin" }, + { "grizzlygooseofgosse", "Grizzly Goose of Gosse" }, + { "grr", "Grr!" }, + { "guardiansofgold", "Guardians of Gold" }, + { "guyslug", "Guy Slug" }, + { "guyverquestiicronos", "Guyver Quest II: Cronos" }, + { "guyverquestishoadventure", "Guyver Quest I: Sho Adventure" }, + { "gville1", "G-ville 1" }, + { "hack", "Hack" }, + { "halloween", "Halloween" }, + { "halloweenhorror", "Halloween Horror" }, + { "hallwayofadventures", "Hallway of Adventures" }, + { "hangon", "Hang On" }, + { "hansenhotel", "Hansen Hotel" }, + { "happyduckieadventure", "Happy Duckie Adventure" }, + { "hardspaceconquestofthegayliks", "Hard Space: Conquest of the Gayliks" }, + { "harrys21stbirthday", "Harry's 21st Birthday" }, + { "haventhesmallworld", "Haven - The Small World" }, + { "heartlanddeluxever11", "Heartland Deluxe Ver 1.1" }, + { "heartlandver12", "Heartland (ver 1.2)" }, + { "heavymetalnannulfthestrangestage", "Heavy Metal Nannulf: The Strange Stage" }, + { "heed", "Heed" }, + { "helpthegame", "HELP! the game" }, + { "henkstroemlostincellar", "Henk Stroem Lost In Cellar" }, + { "henman", "Hen Man" }, + { "hesgonehistorical", "He's Gone Historical" }, + { "hhgtgtowelday", "HHGTG: Towel Day" }, + { "hiddenplains", "Hidden Plains" }, + { "hiddentreasureryansfortune", "Hidden Treasure: Ryan's Fortune" }, + { "hide", "Hide" }, + { "hiliaderoleagainsthell", "Hilia Derole against Hell" }, + { "him", "Him" }, + { "hitchhikersguidetothegalaxyremake", "Hitchhiker's Guide to the Galaxy Remake" }, + { "hitthefreak", "Hit the Freak" }, + { "hlobb", "HLoBB" }, + { "hood", "Hood" }, + { "hope", "Hope" }, + { "horseparkdeluxe", "Horse Park DeLuxe" }, + { "hotel", "Hotel" }, + { "hotelhijinks", "Hotel Hijinks" }, + { "houseofhorror", "House of Horror" }, + { "howmany", "How many..." }, + { "howtheyfoundsilence", "How They Found Silence" }, + { "huongjiaoping", "Huong Jiao Ping" }, + { "huxzadventure", "Huxz Adventure" }, + { "hydeandseek", "Hyde and Seek" }, + { "iaman00b11omgwtflol", "i am a n00b!!1!!1!OMG WTF LOL" }, + { "iamjason", "IAMJASON" }, + { "iforgot", "I forgot..." }, + { "igs", "IGS" }, + { "iiispy", "IIISpy" }, + { "illuminationdiminishing", "IlluminationDiminishing" }, + { "imnotcrazyrightthecell", "I'm not crazy, right? - The Cell" }, + { "imnotcrazyrightthewell", "I'm not crazy, right? - The Well" }, + { "indianajonescomingofage", "Indiana Jones - Coming of Age" }, + { "indycositalianver", "IndyCoS - Italian ver" }, + { "infectionepii", "Infection_Ep_II" }, + { "infectionitheship", "Infection I - The ship" }, + { "inferno", "Inferno" }, + { "infinitemonkeys", "Infinite Monkeys" }, + { "insidemonkeyisland", "Inside Monkey Island" }, + { "insidemonkeyisland2cap", "Inside Monkey Island 2? cap." }, + { "inspectorgismoe", "Inspector Gismoe" }, + { "integerbattleship", "Integer Battleship" }, + { "intergalacticspacepancake", "Intergalactic Space Pancake!" }, + { "intothelight", "Into The Light" }, + { "invincibleisland", "Invincible Island" }, + { "isnkill", "ISN: Kill!" }, + { "isos", "ISOS" }, + { "itsabugslife", "It's a Bugs Life" }, + { "iwalkedapath", "I walked a path" }, + { "iwantout", "I want out!" }, + { "iwwhiiwwhitomirotpgthegame", "IWWHIIWWHITOMIROTPG: The Game!" }, + { "jacob", "Jacob" }, + { "jacquelinewhitecurseofthemummies", "Jacqueline White - Curse of the Mummies" }, + { "jamesbond", "James Bond" }, + { "jamesinneverland", "James in Neverland" }, + { "jamesperis", "James Peris" }, + { "jamesperis2demo", "James Peris 2 Demo" }, + { "javelincatch", "Javelin Catch" }, + { "jimmsquestiii", "Jimm's Quest III" }, + { "jimmysday", "Jimmy's Day" }, + { "jimmythetroublemaker", "Jimmy The Troublemaker" }, + { "joeshorriblehell", "Joe's Horrible Hell" }, + { "joesmiserablelife", "Joe's Miserable Life" }, + { "johnharrissafrakincse", "John Harris ?s a f?ra? kincse" }, + { "johnjebediahgunelisoladisepheret", "John Jebediah Gun e l'Isola di Sepheret" }, + { "johnnyrocket", "Johnny_Rocket" }, + { "johnsinclairvoodooinlondon", "John Sinclair - Voodoo in London" }, + { "jonnysmallvalley", "Jonny Smallvalley" }, + { "jorry", "Jorry" }, + { "juliusdangerous2", "Julius Dangerous 2" }, + { "juliusdangerousandthespaceinvaders", "Julius Dangerous .. and the space invaders" }, + { "justanotherpointnclickadventure", "Just Another Point n Click Adventure" }, + { "justignorethem", "Just Ignore Them" }, + { "kanjigakusei", "Kanji Gakusei" }, + { "kartquestv053", "Kart-Quest - v0.53" }, + { "keptoshi", "Keptosh I" }, + { "keys", "Keys" }, + { "killereye", "Killer Eye" }, + { "killjoseda", "Kill Joseda" }, + { "killthelights", "Kill The Lights" }, + { "kingdomlegends", "Kingdom Legends" }, + { "kingsquestiii", "Kings Quest III" }, + { "kinkyislanddemo", "Kinky Island DEMO" }, + { "knightquestforgoldenring", "Knight Quest for Golden Ring" }, + { "knightsquestiii", "Knight's Quest III" }, + { "knightsquestiv", "Knight's Quest IV" }, + { "koddurova", "??? ??????" }, + { "koffeekrisis", "Koffee Krisis" }, + { "koscheitheimmortal", "Koschei The Immortal" }, + { "kristmaskrisis", "Kristmas Krisis" }, + { "ktx1", "KTX-1" }, + { "kumastory", "Kuma Story" }, + { "labor", "Labor" }, + { "labratescape", "Lab Rat Escape" }, + { "labyrinth", "Labyrinth" }, + { "lacicuta1", "La Cicuta1" }, + { "lacroixpan", "La Croix Pan" }, + { "laffaireaspirox", "L'Affaire Aspirox" }, + { "lagrancastanya", "La Gran Castanya" }, + { "lallaveyfabianshones", "LA LLAVE Y FABIAN SHONES" }, + { "laodiseadelfracasoii", "La Odisea del Fracaso II" }, + { "laportenoire", "La porte noire" }, + { "lastnfurious", "Last'n'Furious" }, + { "laundryday", "Laundry Day" }, + { "lavablava", "Lava Blava" }, + { "lazaruswantspants", "Lazarus Wants Pants" }, + { "lazytownthenewkiddemo", "LazyTown: The New Kid (demo)" }, + { "lbstoryofcedrickdusce", "LB: Story of Cedrick DUSCE!" }, + { "legendofrovendale", "Legend of Rovendale" }, + { "legendofseththebard", "Legend of Seth the Bard" }, + { "legendsofmardaram", "Legends of Mardaram" }, + { "leisuresuitlarry2", "Leisure Suit Larry 2" }, + { "leisuresuitlarrylil", "Leisure Suit Larry: L i L" }, + { "lesmiserables", "Les Miserables" }, + { "lessurvivants", "Les Survivants" }, + { "lichdomwheresdidiputthat", "Lichdom - Where's did I put that..." }, + { "life", "Life" }, + { "lifeboatstoryofcedrick", "Lifeboat: Story of Cedrick" }, + { "lifeofdduck", "Life of D. Duck" }, + { "lifeofdduckii", "Life of D. Duck II" }, + { "liftreasureofthetanones", "Lif Treasure of the Tanones" }, + { "lightcycles", "Light Cycles" }, + { "lightningmaster", "Lightning Master" }, + { "likeafox", "Like a Fox!" }, + { "limbo", "Limbo" }, + { "limeylizardwastewizard", "Limey Lizard: Waste Wizard" }, + { "litnunforgettablememories", "LitN Unforgettable Memories" }, + { "littlegirlinunderland", "Little Girl in Underland" }, + { "livingnightmaredeluxe", "Living Nightmare Deluxe" }, + { "livingnightmareendlessdream", "Living Nightmare: Endless Dream" }, + { "livingnightmarefreedom", "Living Nightmare: Freedom" }, + { "lockedout", "Locked Out" }, + { "loftusandtheskycap", "Loftus and the Sky Cap" }, + { "lonecase", "LoneCase" }, + { "lonecase2", "Lone Case 2" }, + { "lonecase3showdown", "LoneCase3:Showdown" }, + { "lonelynight", "Lonely night" }, + { "longexpectedfriday", "Long expected Friday" }, + { "lonkeyisland", "Lonkey Island" }, + { "loomiireturnoftheswans", "Loom II Return Of The Swans" }, + { "losjovenesdelaguerra", "Los Jovenes De La Guerra" }, + { "lostanswers", "Lost Answers" }, + { "lostinparadise", "Lost In Paradise" }, + { "lostinthenightmare", "Lost In The Nightmare" }, + { "lostinthewoods", "Lost In The Woods" }, + { "lucidlucy", "LUCID LUCY" }, + { "lucylavender", "Lucy Lavender" }, + { "lukesexistentialnightmare", "Luke's Existential Nightmare" }, + { "lunarlanderprototype", "Lunar Lander Prototype" }, + { "lydiaandthemysteryofnellrenomanor", "Lydia and the Mystery of Nellreno Manor" }, + { "maggieandmax", "Maggie and Max" }, + { "magic8ball", "Magic-8-Ball" }, + { "magicalwhatevergirlrocksoutinthestoneage", "Magical Whatever Girl Rocks Out In The Stone Age" }, + { "magicballoffortune", "Magic Ball of Fortune" }, + { "magnumpm", "Magnum, P.M" }, + { "magsgame", "Mags Game" }, + { "magsic", "Magsic" }, + { "magsicii", "Magsic II" }, + { "magsjan", "MAGS-Jan" }, + { "magsjune2017", "MAGS june 2017" }, + { "magssep2007", "MAGS Sep 2007" }, + { "manboy", "Man Boy" }, + { "maniacmansiondeluxe", "Maniac Mansion Deluxe" }, + { "maniacmansionmania", "Maniac Mansion Mania" }, + { "maniacmansionmania02", "Maniac Mansion Mania 02" }, + { "mardsrevengebytk", "Mard's Revenge by TK" }, + { "martyausdemall", "Marty aus dem All" }, + { "mastersofsound", "MASTERS OF SOUND" }, + { "matttothefuture", "Matt to the Future" }, + { "medicaltheoriesofdrkur", "Medical Theories of Dr Kur" }, + { "mego2008silvesteredition", "Me Go 2008: Silvester Edition" }, + { "megoaway", "Me Go... Away!" }, + { "megocannibaljungle", "Me Go Cannibal Jungle!" }, + { "megostore", "Me Go Store!" }, + { "melrinthediscipleordeal", "Melrin: The disciple ordeal" }, + { "melrinthedragonmenace", "Melrin: The Dragon Menace" }, + { "melrinthependantquest", "Melrin: The Pendant Quest" }, + { "meltdrake3chapter1", "Melt & Drake 3 Chapter 1" }, + { "memoriesfade", "Memories Fade" }, + { "meninhats", "Men In Hats" }, + { "merrychristmas", "Merry Christmas" }, + { "messedupmothergoosedeluxemyassenhanced", "Messed-Up Mother Goose - DELUXE MY ASS: ENHANCED" }, + { "meta", "META" }, + { "meteorfamily20", "Meteor Family 2.0" }, + { "meteorheadrecycled", "METEORHEAD RECYCLED" }, + { "mi5thereturnoflechuck", "MI5 : The Return of LeChuck" }, + { "mibaddaytobedead", "MI:Bad Day to be Dead" }, + { "micarnivalofthedamned", "MI:Carnival of the Damned" }, + { "mickeymauserpart1", "Mickey Mauser: Part 1" }, + { "midastouch", "midastouch" }, + { "mikelechey", "Mike Lechey" }, + { "mikesroom2", "Mikes Room2" }, + { "milkshake", "Milkshake" }, + { "mindboggler", "MINDBOGGLER" }, + { "mindseye", "Mind's Eye" }, + { "minigame3", "Mini Game 3" }, + { "minigame4", "Mini Game 4" }, + { "missingsincemidnight", "Missing since Midnight" }, + { "mistdelaescueladearte", "Mist. de la Escuela de Arte" }, + { "mixertest", "Mixer Test" }, + { "mmm15ortmaschine", "MMM 15: Ortmaschine" }, + { "mmm4mimikryderemotionen", "MMM 4 - Mimikry der Emotionen" }, + { "mmmderklausschlgtzurck", "MMM-Der Klaus schl?gt zur?ck" }, + { "mmmepisode8", "MMM - Episode 8" }, + { "mmmradioaktiv", "MMM - Radioaktiv" }, + { "moncul", "Mon Cul!" }, + { "monkeystothemoon", "Monkeys to the Moon" }, + { "monkeywrench", "monkeywrench" }, + { "monsterfromthehountedhill", "Monster from the hounted hill" }, + { "moonlightmoggy", "Moonlight Moggy" }, + { "moose", "Moose" }, + { "moose2", "Moose 2" }, + { "mordimlaufrad", "Mord im Laufrad" }, + { "mordy2", "Mordy2" }, + { "mothersday", "Mothers Day" }, + { "motlpaa", "MOTLPAA" }, + { "mourirenmer", "Mourir en mer" }, + { "mrbee", "Mr Bee" }, + { "mrdangerscontest", "Mr. Danger's Contest" }, + { "murderinthemansion", "Murder in the Mansion" }, + { "murderofadrianelkwood", "Murder of Adrian Elkwood" }, + { "murphyssalvagejustmyluck", "Murphy's Salvage: Just My Luck" }, + { "murranchronicles1", "Murran Chronicles 1" }, + { "murranchronicles2", "Murran Chronicles 2" }, + { "mysterioushouse", "Mysterious house" }, + { "mysticseer", "Mystic Seer" }, + { "mythicalgambitflawlessfatality", "Mythical Gambit: Flawless Fatality" }, + { "nanobots", "Nanobots" }, + { "necroquest", "Necroquest" }, + { "nedysadventure", "Nedy's adventure" }, + { "nekusnewtrip", "Neku's new trip" }, + { "newgame", "New Game" }, + { "nellycootalotv15", "Nelly Cootalot v1.5" }, + { "neofeud", "Neofeud" }, + { "nesquest", "NES Quest" }, + { "news", "N.E.W.S." }, + { "nickitandrun", "Nick it and Run!!!" }, + { "nightoftheravingfeminist", "Night of the Raving Feminist " }, + { "nightwork", "Nightwork" }, + { "noactionjackson", "No-Action Jackson" }, + { "noahsquest", "Noah's Quest" }, + { "nobodycares", "Nobody Cares" }, + { "noiamspartacus", "No, I Am Spartacus!" }, + { "noisymountain", "Noisy Mountain" }, + { "nomonkeysbanana", "No Monkey's Banana" }, + { "norbisquest", "Norbi's quest" }, + { "norbisquest15", "Norbi's quest 1,5" }, + { "norbisquest2", "Norbi's quest 2" }, + { "norbiwinterspecial", "Norbi winter special" }, + { "normancooks", "Norman Cooks" }, + { "norserunereader", "Norse Rune Reader" }, + { "noughtscrosses", "Noughts & Crosses" }, + { "oceanspiritdennisscourgeoftheunderworld", "Oceanspirit Dennis: Scourge of the Underworld" }, + { "odottamaton", "Odot Tamat On" }, + { "omnipotenttarot", "Omnipotent Tarot" }, + { "onceuponacrime13b", "Once Upon A Crime 1.3B" }, + { "onceuponatime", "Once Upon A Time" }, + { "one", "One" }, + { "oneofakindadivinecomedyofmistakes", "One Of A Kind: A Divine Comedy of Mistakes" }, + { "onespytoomany", "One spy too many" }, + { "oneweekoneroom", "One Week One Room" }, + { "onleavingthebuilding", "On Leaving The Building" }, + { "onlythegooddieyoungenglishversion", "Only The Good Die Young - english version" }, + { "openquest", "OpenQuest!" }, + { "operationnovi", "Operation Novi" }, + { "operationsavebluecup", "Operation Save Blue Cup" }, + { "orangeman", "Orange man" }, + { "orowgame", "ORow Game" }, + { "osdarayofhope", "OSD: A Ray of Hope" }, + { "osdocd", "OSD:OCD" }, + { "osdthelostworldep2", "OSD.The lost world ep 2 " }, + { "osher", "Osher" }, + { "otakurivals", "Otaku Rivals " }, + { "otherworlds", "Other Worlds" }, + { "otisbuildsafire", "Otis Builds a Fire" }, + { "ouja", "Ouja" }, + { "outbreakbyabhijitkamat", "Outbreak by Abhijit Kamat" }, + { "outofgas", "Out of Gas" }, + { "overtheedge", "Over the Edge" }, + { "owlsquest", "Owl's Quest" }, + { "palettequest2", "Palette Quest 2" }, + { "pandainspace", "Panda In Space" }, + { "pandor", "Pandor" }, + { "paradiselost", "Paradise Lost" }, + { "parameciumcomplex", "Paramecium Complex" }, + { "paranormalwarriorwithin", "Paranormal Warrior Within" }, + { "party", "Party" }, + { "patchwork", "Patchwork" }, + { "paulaimwunderland", "Paula im Wunderland" }, + { "paulmooseinspaceworld", "Paul Moose In Space World" }, + { "paulquest", "Paul Quest" }, + { "pennistheultimateinpong", "Pennis: The Ultimate in Pong!" }, + { "perilsofpoom", "PERILS OF POOM" }, + { "pesterquest", "Pester Quest" }, + { "petalrose", "Petal Rose" }, + { "pharmacistjones", "Pharmacist Jones" }, + { "pickpocketrpg", "Pickpocket RPG" }, + { "pilotlight", "Pilot Light" }, + { "pimpinonparakuss", "Pimpin On Parakuss" }, + { "piratefry2", "Pirate Fry 2" }, + { "piratefry3", "Pirate Fry 3" }, + { "piratess", "Piratess" }, + { "pixelhunt", "Pixel Hunt" }, + { "pixia", "Pixia" }, + { "pixxxelhuntertheepic", "Pixxxelhunter The Epic" }, + { "plan10frommypants", "Plan10 from MY PANTS!!!" }, + { "planetxmas", "Planet Xmas" }, + { "platformerius", "Platformerius" }, + { "platformhorde", "Platform Horde" }, + { "pleurghburgdarkages", "Pleurghburg: Dark Ages" }, + { "plumberboy", "Plumberboy" }, + { "pm-cute", "PM Cute" }, + { "pmuvchvt", "PMUVCHVT" }, + { "pmxi", "PMXI" }, + { "pocketfluffyay", "PocketFluff_yay!" }, + { "politicallyyours", "Politically Yours" }, + { "pong", "Pong" }, + { "postmansquest", "Postman's Quest" }, + { "powernap", "Power Nap" }, + { "powerunlimited", "Power Unlimited" }, + { "pqtadventure", "PQTADVENTURE" }, + { "practicescript", "Practice Script" }, + { "predatorspreyforplants", "Predators Prey For Plants" }, + { "princessandallthekingdom", "Princess and all the kingdom" }, + { "princessmarianix", "Princess Marian IX" }, + { "princessmariansnowfight", "Princess Marian Snow Fight!" }, + { "princessmarianspigeonpinger", "Princess Marian's Pigeon Pinger" }, + { "princessmarianxmagichat", "Princess Marian X: Magic Hat" }, + { "principlesofevil", "Principles of Evil" }, + { "principlesofevilii", "Principles of Evil II" }, + { "prodigal", "Prodigal" }, + { "profneely", "Prof. Neely" }, + { "projectevilspyii", "Project Evilspy II" }, + { "proofoffiction", "Proof of Fiction" }, + { "prototypical", "Prototypical" }, + { "proxecto", "Proxecto" }, + { "psychopomp", "Psychopomp" }, + { "pubmasterquest2", "pub master quest.2" }, + { "pubmastersquest", "Pub Masters Quest" }, + { "puddypenguin", "Puddy Penguin" }, + { "pupupupulaisenseikkailut", "Pupu Pupulaisen Seikkailut" }, + { "purgatorio01", "Purgatorio 0.1" }, + { "purityofthesurf", "Purity of the Surf" }, + { "puzzlebotsdemo", "Puzzle Bots Demo" }, + { "pxenophobe", "PXenophobe" }, + { "quantumnauts", "QUANTUMNAUTS" }, + { "questfighter", "Quest Fighter" }, + { "questfighterii", "Quest Fighter II" }, + { "questforcinema", "QuestForCinema" }, + { "questforglory2vga", "Quest For Glory 2 VGA" }, + { "questforgloryii", "Quest for Glory II" }, + { "questforjesus", "Quest for Jesus" }, + { "questforpalette", "Quest for Palette" }, + { "questforthebluecup", "Quest for the Blue Cup" }, + { "questforyeti", "Quest for Yeti" }, + { "questforyrolg", "Quest for Yrolg" }, + { "quieromorir", "Quiero Morir" }, + { "quimbyquestanewdope", "Quimby Quest: A New Dope" }, + { "race", "R.ACE" }, + { "rackham", "Rackham" }, + { "ralphtheraven", "Ralph the Raven" }, + { "ramsesporterandtherelayforlove", "Ramses Porter and the Relay for Love" }, + { "rango", "Rango" }, + { "ratchannel", "Rat Channel" }, + { "rayandtheguitar", "Ray and the Guitar" }, + { "raybexter", "Ray Bexter" }, + { "razorsinthenight", "Razors in the Night" }, + { "reagentorange", "Re-Agent Orange" }, + { "realityonthenorm", "Reality-on-the-Norm" }, + { "recess", "Recess" }, + { "recess2", "Recess 2" }, + { "reddwarf", "Red Dwarf" }, + { "redflagg", "Red Flagg" }, + { "redpantsmeetsrobinsonclauseau", "Redpants meets Robinson Clauseau" }, + { "redpantstheprincessandthebeanstalk", "Redpants: The Princess and the Beanstalk" }, + { "reefriversquestforekoban", "Reef Rivers: Quest for Ekoban" }, + { "returntocivilization", "Return To Civilization" }, + { "revelation10", "Revelation 1.0" }, + { "rickyquest", "Ricky Quest" }, + { "righteouscity", "Righteous City" }, + { "roadofdestiny", "Road of Destiny" }, + { "roadracer", "Road Racer" }, + { "roastmothergoose", "Roast Mother Goose" }, + { "robbertredfordsavestheday", "Robbert Redford saves the day" }, + { "robbingtheprincess", "Robbing The Princess" }, + { "robertredford3", "Robert Redford 3" }, + { "robertredfordsavestheday", "Robert Redford saves the day" }, + { "robmassacreofchainsawness", "Rob: Massacre of Chainsawness" }, + { "robotragedy", "Robotragedy" }, + { "robotragedy2", "Robotragedy 2" }, + { "roccioquest", "Roccio Quest" }, + { "rockabillykid", "Rockabilly Kid" }, + { "rockburgerstreehouses", "Rock Burgers & Tree Houses" }, + { "rockrockrock", "Rock Rock Rock" }, + { "rockyroams", "Rocky roams" }, + { "rodequest2", "Rode Quest 2" }, + { "ronbeforethelegacy", "Ron- before the legacy" }, + { "ronsixteen", "RON: Sixteen" }, + { "rontimeoutintro", "RON: Time Out Intro" }, + { "roomoffear", "Room of fear " }, + { "rootofallevil", "Root of All Evil" }, + { "rosauradocelestialrescuefromdespair", "Rosaura Docelestial: Rescue from Despair" }, + { "rotnbelusebiusarrival", "RotN:Belusebius Arrival" }, + { "rowengoestowork", "Rowen Goes To Work" }, + { "rs15", "rs15" }, + { "rudeawakening", "Rude Awakening" }, + { "ryansdayout", "Ryan's Day Out" }, + { "saddsonissein", "Saddson Issein" }, + { "salazarsevilplan", "Salazar's evil plan" }, + { "sammysquest", "Sammy's Quest" }, + { "santaclausdown", "Santa Claus Down" }, + { "santassidekick", "Santas Sidekick" }, + { "satanquest", "Satan Quest" }, + { "satchsquest", "Satch's Quest" }, + { "saturdayschool", "Saturday School" }, + { "saw", "Saw" }, + { "saw2", "Saw 2" }, + { "scaredstiffa", "Scared Stiff a" }, + { "scarymaze", "Scary Maze" }, + { "schwarzweissrot", "SchwarzWeissRot" }, + { "scnider", "Scnider" }, + { "scytheisland", "Scythe Island" }, + { "searchforsanitydemo", "Search for Sanity Demo" }, + { "seashells", "Seashells" }, + { "seasongreetings2002", "Season Greetings 2002" }, + { "secretquestremake", "Secret Quest Remake" }, + { "secrets", "Secrets" }, + { "seega16engl5", "seega16_engl_5" }, + { "seegame15", "seegame15" }, + { "sevendoors", "Seven Doors" }, + { "sga", "SGA" }, + { "shadesofgreye", "Shades of Greye" }, + { "shadowsoftheempiretd", "Shadows of the Empire - TD" }, + { "shailadusithlenqute", "Shai-la du Sith : l'Enqu?te" }, + { "shailaofthesith", "Shai-la of the Sith" }, + { "shem", "Shem" }, + { "sherlock", "Sherlock" }, + { "shiftersboxoutsidein", "Shifter's Box - Outside In" }, + { "shivahdemo", "Shivahdemo" }, + { "shoot", "Shoot" }, + { "shootmyvalentine", "Shoot my Valentine" }, + { "shortcut", "ShortCut" }, + { "shrivel", "Shrivel" }, + { "shunday", "Shunday" }, + { "sierraquest1", "Sierra Quest 1" }, + { "silentknightii", "Silent Knight II" }, + { "silentknightv11", "Silent Knight v.1.1" }, + { "simonthesorcerer3demo20", "Simon the Sorcerer 3 Demo 2.0" }, + { "skippysavestheday", "Skippy Saves The Day" }, + { "slaythedragon", "Slay the Dragon" }, + { "sleepyisland", "Sleepy Island" }, + { "slimequestforpizza", "Slime-Quest for Pizza" }, + { "slugprincess", "SlugPrincess" }, + { "sma21", "SMA 2.1" }, + { "sma31", "SMA 3.1" }, + { "sma4", "SMA 4" }, + { "smavi", "SMA VI" }, + { "smileysquest", "Smiley's Quest" }, + { "smileysquest2", "Smiley's Quest 2" }, + { "smoothhide", "Smooth Hide" }, + { "snakeamagsgame", "SNAKE - a MAGS game" }, + { "snakesofavalon", "Snakes of Avalon" }, + { "snakesonaplane", "Snakes on a plane!" }, + { "sniperandspotterservingthemotherland", "Sniper and spotter serving the motherland" }, + { "sonicandfriendsinclubhouse", "Sonic and friends in: Club house" }, + { "sosk", "Sosk" }, + { "sovietunterzoegersdorfsectorii", "Soviet Unterzoegersdorf: Sector II" }, + { "sowjetunterzgersdorf", "Sowjet-Unterz?gersdorf" }, + { "spacefreakers", "Space Freakers" }, + { "spacelynxes", "Space Lynxes" }, + { "spacepirates", "Space Pirates" }, + { "spacepoolalpha", "Space Pool Alpha" }, + { "spacequest45", "Space Quest 4.5" }, + { "spacequest55demoags", "Space Quest 5.5 demo (AGS)" }, + { "spacequestiiivgapreview", "Space Quest III VGA Preview" }, + { "sqm11", "Space Quest Mania 1x1" }, + { "sqm12", "Space Quest Mania 1x2" }, + { "sqm13", "Space Quest Mania 1x3" }, + { "sqm14", "Space Quest Mania 1x4" }, + { "sqm16", "Space Quest Mania 1x6" }, + { "spacerangers", "Space Rangers " }, + { "spacerangersep52", "Space Rangers Ep 52" }, + { "spacewar", "Space war" }, + { "spacewarepisode2strikba", "Spacewar episode 2(strik.ba.)" }, + { "spellbound", "Spellbound" }, + { "spilakassinn", "Spilakassinn" }, + { "spooks", "Spooks" }, + { "spoonsiiitheunauthorizededition", "Spoons III - The Unauthorized Edition" }, + { "spotthedifference", "Spot The Difference" }, + { "sproutsofevil", "Sprouts of evil" }, + { "sqkubikgetready", "SQ Kubik (Get ready?)" }, + { "sqmania1", "SQ Mania #1" }, + { "sqmania2remakeeng", "SQ Mania 2 Remake (ENG)" }, + { "sqmaniaep5", "SQ Mania Ep5" }, + { "sram2cinomehsrevengedemo", "SRAM 2 - CINOMEH'S REVENGE (demo)" }, + { "stablepeteandthejoust", "Stable Pete and the Joust" }, + { "stairquest", "Stair Quest" }, + { "stanamespiepisode1", "Stan Ames PI, Episode 1" }, + { "stansrevenge", "Stan's Revenge" }, + { "starshipcaramba", "Starship Caramba" }, + { "starshipposeidon", "Starship Poseidon" }, + { "start", "Start" }, + { "startreknewton", "Star Trek: Newton" }, + { "stediddyip1employment", "Stediddy IP1 - Employment" }, + { "stickmeni", "Stickmen I" }, + { "stickythestickfigurepart1thecrimsonhouse", "Sticky the Stick Figure Part 1: The Crimson House" }, + { "stinkymcpoopoo", "Stinky McPooPoo" }, + { "stranded", "STRANDED" }, + { "stranger", "Stranger" }, + { "strangerinstickworld", "Stranger in Stickworld" }, + { "strangerthings", "Stranger Things" }, + { "supaevil", "Supa-EviL" }, + { "supergirl", "Supergirl" }, + { "superjazzmandemo", "Super Jazz Man (DEMO)" }, + { "superracing", "Super Racing" }, + { "surreality", "Surreality" }, + { "sweed", "Sweed" }, + { "sword", "Sword" }, + { "sydneyfindsemployment", "Sydney Finds Employment" }, + { "sydneytreadsthecatwalk", "Sydney Treads the Catwalk" }, + { "symplokelaleyendadegustavobuenocapitulo1", "Symploke. La Leyenda de Gustavo Bueno. Capitulo 1" }, + { "tales", "Tales" }, + { "talesofchickenry", "Tales of Chickenry" }, + { "tao", "Tao" }, + { "tarthenia", "Tarthenia" }, + { "teamwork", "Teamwork" }, + { "templeofspheres", "Temple of Spheres" }, + { "tenhumstombpart1", "Tenhum's Tomb Part 1" }, + { "terrorofthevampire", "Terror of the Vampire!" }, + { "test", "Test" }, + { "test5", "test5" }, + { "textparsergame", "Text Parser Game" }, + { "thatday", "ThatDay" }, + { "the30minutewar", "The 30 Minute War" }, + { "the7thsense", "The 7th Sense" }, + { "theadventureofthehero", "The Adventure of the Hero" }, + { "theadventuresoffatman", "The Adventures of Fatman" }, + { "theadventuresofturquoisem", "The Adventures of Turquoise M" }, + { "theassassin", "The Assassin" }, + { "theawakening", "The Awakening" }, + { "thebadneighbours", "The bad neighbours" }, + { "thebar", "The Bar" }, + { "thebrokenbrain", "The Broken Brain" }, + { "thebunker", "The Bunker" }, + { "thecadaversynod", "The cadaver synod" }, + { "thecan", "The Can" }, + { "thecell", "The Cell" }, + { "thechrysalis", "The Chrysalis" }, + { "thecrackwelllegacy", "The Crackwell Legacy" }, + { "thecube", "The Cube" }, + { "thecurioussilence", "The Curious Silence" }, + { "thecurseoflife", "The Curse of Life" }, + { "thedayofdarkness", "The Day Of Darkness" }, + { "thedeathoflukesimpson", "The Death of Luke Simpson" }, + { "thedevilsshroudpart1", "The Devil's Shroud-part1" }, + { "thedigitalspell", "The Digital Spell" }, + { "thedusseldorfconspiracy", "The Dusseldorf Conspiracy" }, + { "thedwarvendaggerofblitz", "The Dwarven Dagger of Blitz" }, + { "theelevator", "The Elevator" }, + { "theenergizer", "The Energizer" }, + { "theepicadventures", "The epic adventures" }, + { "theeverbeginningtale", "The Ever-Beginning Tale" }, + { "theexecutionofanneboleyn", "The Execution of Anne Boleyn" }, + { "thefarm", "the farm" }, + { "theficklehandsoffate", "The Fickle Hands of Fate" }, + { "thefind", "The Find" }, + { "thegourmet", "The Gourmet" }, + { "thegreatcasserolecaper", "The Great Casserole Caper" }, + { "thegreatstrokeoff", "The Great Stroke-Off!" }, + { "thegruglegends", "The Grug Legends" }, + { "thehamlet", "The Hamlet" }, + { "thehauntedhouse", "The Haunted House" }, + { "theheist", "The Heist" }, + { "thehobbitriseofthedragonking", "The Hobbit: Rise of the Dragon King" }, + { "thehousethatatemysoul", "The house that ate my soul" }, + { "thehuntforgoldbeard", "The hunt for Goldbeard" }, + { "thehuntforshaunbinda", "The hunt for Shaun Binda" }, + { "thehuntforshaunbindadeluxeedition", "The Hunt For Shaun Binda Deluxe Edition" }, + { "theiraqiparadox", "The Iraqi Paradox" }, + { "thejackyard", "The Jackyard" }, + { "thejourneyhome", "The Journey Home" }, + { "thejourneyofiesir", "The Journey of Iesir" }, + { "thelastharvest", "The Last Harvest" }, + { "thelastsupperawhodunnit", "THE LAST SUPPER, A WHODUNNIT" }, + { "theloneloserdemo", "The Lone Loser - DEMO" }, + { "thelongtrip", "The Long Trip" }, + { "themajesticconspiracy", "The Majestic Conspiracy" }, + { "themarionette", "The Marionette" }, + { "themccarthychronicleschapter1", "The McCarthy Chronicles Chapter 1" }, + { "themcreedcasebytk", "The McReed Case by TK" }, + { "themysteriesofstiegomoors", "The Mysteries of Stiego Moors" }, + { "themysteryofhauntedhollow", "The Mystery of Haunted Hollow" }, + { "thenetherworld", "The Netherworld" }, + { "thenextcurse", "The Next Curse" }, + { "theoraclev11", "The Oracle v1.1" }, + { "thepark", "The Park" }, + { "theperfectmurder", "The Perfect Murder" }, + { "thephantominheritance", "The Phantom Inheritance" }, + { "thequestfortheholysalsa", "The Quest for the Holy Salsa" }, + { "thequesttozooloo", "The Quest To Zooloo" }, + { "theroadtomurder", "The Road to Murder" }, + { "therobolovers", "The Robolovers" }, + { "therotaryclub", "The Rotary Club" }, + { "thesearch", "The Search" }, + { "thesecretofchunkysalsa", "The Secret of Chunky Salsa" }, + { "thesecretofgoldenriver", "The Secret of Golden River" }, + { "thesecretofhuttongrammarschool", "The Secret of Hutton Grammar School" }, + { "thesecretofmountmonkey", "The secret of Mount Monkey" }, + { "thesecretplan1runningtostandstill", "The Secret Plan 1 - Running to stand still" }, + { "theshortestjourney", "The Shortest Journey" }, + { "thesmallestpoints", "The Smallest Points" }, + { "thesnaplock", "The Snaplock" }, + { "thespoons", "The spoons" }, + { "thestarryskyaboveme", "The Starry Sky Above Me" }, + { "thestring", "The String" }, + { "thesundownmystery", "The Sundown mystery" }, + { "thetombofthemoon", "The Tomb of the Moon" }, + { "thetrap", "The Trap" }, + { "thetreasuredmedallion", "The Treasured Medallion" }, + { "thetreasureoflochinch", "The Treasure of Loch Inch" }, + { "theuncertaintymachine", "The Uncertainty Machine" }, + { "theupliftmofopartyplan", "The Uplift Mofo Party Plan" }, + { "thevacuum", "The Vacuum" }, + { "thewitch", "The witch, ..." }, + { "thisgame", "This Game" }, + { "threeguyswalkintoheaven", "Three Guys Walk Into Heaven" }, + { "tilepuzzlegame", "Tile Puzzle Game" }, + { "tiltor", "Tiltor" }, + { "timegentlemenpleasedemo", "Time Gentlemen, Please DEMO" }, + { "timequest", "Time Quest" }, + { "timequest2", "Time Quest 2" }, + { "timesinkofchronos", "Timesink of Chronos" }, + { "timothylande", "Timothy Lande" }, + { "tmateundescanso", "T?mate un descanso" }, + { "tmntturtlesintime", "TMNT: Turtles in Time" }, + { "tomhanksaway", "Tom Hanks Away" }, + { "toomanykittens", "Too Many Kittens" }, + { "totalhangoverextreamzz", "Total Hangover ExtreamZz!" }, + { "tq", "tq" }, + { "trappedinabuilding", "Trapped in a building" }, + { "trevordaisoninouterspace", "Trevor Daison in outer space" }, + { "trexandmusclesambigtroubleinspf", "Trex and Muscle SAM big trouble in SPF" }, + { "trilbysnotes", "Trilby's Notes" }, + { "trilbytheartoftheft", "Trilby: The Art Of Theft" }, + { "trivialpassyouit", "Trivial Pass You It" }, + { "tuberainbow", "Tube Rainbow" }, + { "tvbrder", "Tv? Br?der" }, + { "twelvethirteen", "Twelve Thirteen" }, + { "twelvethirteenepisode2", "Twelve Thirteen, episode 2" }, + { "twelvethirteenepisode3", "Twelve Thirteen, episode 3" }, + { "twentiesflappersvsthemummy", "Twenties Flappers vs The Mummy" }, + { "twoofakind", "Two of a Kind" }, + { "uglyfiles", "UGLY FILES" }, + { "ulitsadimitrova", "Ulitsa Dimitrova" }, + { "unboundver10", "Unbound Ver 1.0" }, + { "unfinished", "unfinished" }, + { "unganeedsmumba", "UNGA needs MUMBA" }, + { "unintelligentdesign", "Unintelligent Design" }, + { "unprofev10", "Un Profe V 1.0" }, + { "untilihaveyou", "Until I Have You" }, + { "updatequest", "Update Quest" }, + { "utopiaoftyrant", "Utopia of Tyrant" }, + { "vacationquestthing", "Vacation Quest... Thing" }, + { "valhallaextinction", "Valhalla Extinction" }, + { "valis", "valis" }, + { "vankairbreak", "van K. Airbreak" }, + { "vegetablepatchextreemturbo", "Vegetable Patch Extreem Turbo" }, + { "veggietales3d", "Veggie Tales 3D" }, + { "veteranshootout", "Veteran shootout" }, + { "vicwreckleshalloweencostume", "Vic Wreckle's Halloween Costume" }, + { "virtualpiano10", "Virtual Piano 1.0" }, + { "vohaulsrevengeii", "Vohaul's revenge II" }, + { "vpxt2", "V P x T ! 2 !" }, + { "waitingfortheloop", "Waiting For the Loop" }, + { "wallyweaseldemo", "Wally Weasel Demo" }, + { "waltersasteroid", "Walters-Asteroid" }, + { "warthogs", "Warthogs" }, + { "washedashore", "Washed Ashore" }, + { "washedashoredeluxe", "Washed Ashore Deluxe" }, + { "wasted", "Wasted" }, + { "waterquest", "WATER QUEST" }, + { "wcedit", "WCEdit... " }, + { "wearevectors", "We Are Vectors" }, + { "welcometodarklake", "Welcome to Dark Lake" }, + { "wet", "WET " }, + { "what", "what!" }, + { "whatisthatthing", "what is that thing" }, + { "whatlinusbruckmansees", "What Linus Bruckman Sees" }, + { "wherebedragons", "Where Be Dragons?" }, + { "wheredidsamgo", "Where did Sam go?" }, + { "wheresmhatma", "Where's M' Hat Ma?" }, + { "whowantstoliveagain", "Who wants to live again?" }, + { "whowantstoliveforever", "Who wants to live forever?" }, + { "williamsnightmare", "Williams Nightmare" }, + { "willowhouse", "Willow House" }, + { "willy", "Willy" }, + { "winnersdontdodrugs", "Winners Dont' Do Drugs" }, + { "winterrose", "Winter Rose" }, + { "witch", "Witch" }, + { "witchnight", "Witch Night" }, + { "witness", "Witness!" }, + { "wizardhood", "Wizardhood" }, + { "woo", "Woo" }, + { "woolyrockbottom", "Wooly Rockbottom" }, + { "worldofwarcraftquest", "World of Warcraft Quest" }, + { "worm", "Worm" }, + { "wrathofthesolonoids", "Wrath of the Solonoids " }, + { "yoda", "Yoda" }, + { "yourgame", "Your Game" }, + { "yourlate", "Your late!" }, + { "zakmckracken", "Zak McKracken" }, + { "zombieattackdemo", "Zombie Attack Demo" }, + { "zombiefish", "Zombie Fish" }, + { "zooreal", "ZooReal" }, + { "zugzwang", "Zugzwang" }, { 0, 0 } }; -#define ENGLISH_ENTRY(ID, FILENAME, MD5, SIZE) { \ - { \ - ID, \ - nullptr, \ - AD_ENTRY1s(FILENAME, MD5, SIZE), \ - Common::EN_ANY, \ - Common::kPlatformUnknown, \ - ADGF_UNSTABLE, \ - GUIO1(GUIO_NOSPEECH) \ - }, \ - nullptr \ - } - -#define ENGLISH_PLUGIN(ID, FILENAME, MD5, SIZE, PLUGIN_ARR) { \ - { \ - ID, \ - nullptr, \ - AD_ENTRY1s(FILENAME, MD5, SIZE), \ - Common::EN_ANY, \ - Common::kPlatformUnknown, \ - ADGF_UNSTABLE, \ - GUIO1(GUIO_NOSPEECH) \ - }, \ - PLUGIN_ARR \ - } +#define UNSUPPORTED_ENTRY(ID, FILENAME, MD5, SIZE) \ + {{ ID, nullptr, AD_ENTRY1s(FILENAME, MD5, SIZE), Common::EN_ANY, \ + Common::kPlatformUnknown, ADGF_UNSTABLE, GUIO0() }, nullptr } +#define ENGLISH_ENTRY(ID, FILENAME, MD5, SIZE) \ + UNSUPPORTED_ENTRY(ID, FILENAME, MD5, SIZE) + +#define ENGLISH_PLUGIN(ID, FILENAME, MD5, SIZE, PLUGIN_ARR) \ + {{ ID, nullptr, AD_ENTRY1s(FILENAME, MD5, SIZE), Common::EN_ANY, \ + Common::kPlatformUnknown, ADGF_UNSTABLE, GUIO0() }, PLUGIN_ARR } + static const PluginVersion AGSCREDITZ_11[] = { { "agscreditz", 11 }, { nullptr, 0 } }; const AGSGameDescription GAME_DESCRIPTIONS[] = { + // Pre-2.5 games that aren't supported by the current AGS engine + UNSUPPORTED_ENTRY("qfg412", "qfg.exe", "8b21668ca462b0b6b35df43c5902b074", 26674790), + + // Post-2.5 games that are likely supported by the AGS engine ENGLISH_ENTRY("5daysastranger", "5days.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4440143), ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "465f972675db2da6040518221af5b0ba", 4693374), - ENGLISH_ENTRY("absentparti", "Absent - Part I.exe", "34ca36e3948aae8527dd0e90f0861a75", 31421924), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42740200), ENGLISH_PLUGIN("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255, AGSCREDITZ_11), @@ -104,10 +1227,1168 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("primordia", "primordia.exe", "22313e59c3233001488c26f18c80cc08", 973495830), // GOG ENGLISH_ENTRY("primordia", "primordia.exe", "f2edc9c3161f1f538df9b4c59fc89e24", 978377890), // GOG ENGLISH_ENTRY("resonance", "resonance.exe", "2e635c22bcbf0ed3d46f1bcde71812d4", 849404957), // GOG - ENGLISH_ENTRY("mage", "ac2game.dat", "2e822f554994f36e0c62da2acda874da", 30492258), // GOG, Mac ENGLISH_ENTRY("unavowed", "ac2game.dat", "b1ff7d96667707daf4266975cea2bf90", 1755457364), // Steam, Mac + // Unsorted games + ENGLISH_ENTRY("10waysfromsunday", "10WaysFromSunday.exe", "495d45fb8adfd49690ae3b97921feec6", 11362765), + ENGLISH_ENTRY("1dayamosquito", "mosquito.exe", "465f972675db2da6040518221af5b0ba", 2178983), + ENGLISH_ENTRY("2034acaftercanadaii", "2034 AC II.exe", "1280ba7c269a68a9505871516319db0c", 35207006), + ENGLISH_ENTRY("24hours", "24.exe", "f120690b506dd63cd7d1112ea6af2f77", 1932370), + ENGLISH_ENTRY("3piggiesalpha", "Three Little Pigs and a Wolf.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 14180634), + ENGLISH_ENTRY("3piggiesalpha", "3piggiesAlpha.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 14181120), + ENGLISH_ENTRY("46memorylane", "diyu.exe", "e3962995a70923a8d5a8f1cf8f932eee", 66686277), + ENGLISH_ENTRY("4ofclubs", "4ofClubs.exe", "06a03fe35791b0578068ab1873455463", 5909169), + ENGLISH_ENTRY("5daysastranger", "5days.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4614351), + ENGLISH_ENTRY("6daysasacrifice", "6das.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7993899), + ENGLISH_ENTRY("6mornings", "project2.exe", "e7dac058b9bc0b42d489e474c2ddec84", 11595240), + ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4863356), + ENGLISH_ENTRY("aazor", "aazor.exe", "465f972675db2da6040518221af5b0ba", 4956212), + ENGLISH_ENTRY("abducted", "10 MINUTES.exe", "465f972675db2da6040518221af5b0ba", 2687034), + ENGLISH_ENTRY("absent", "Absent.exe", "aabdafae8b57dfc48fdf158a72326c23", 39284149), + ENGLISH_ENTRY("absentparti", "Absent - Part I.exe", "34ca36e3948aae8527dd0e90f0861a75", 31421924), + ENGLISH_ENTRY("access", "Access.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 1816218), + ENGLISH_ENTRY("aceking", "ags.exe", "f982756f0e2c2fbeca15d199b9851559", 338249917), + ENGLISH_ENTRY("acequest", "NEWGAME.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 4124225), + ENGLISH_ENTRY("achequest", "achequest.exe", "06a03fe35791b0578068ab1873455463", 2952369), + ENGLISH_ENTRY("achristmasblunder", "Blunder.exe", "35c11dc3b5f73b290489503b0a7c89e5", 1974915), + ENGLISH_ENTRY("aciddd", "acidddd.exe", "06a03fe35791b0578068ab1873455463", 1858394), + ENGLISH_ENTRY("acureforthecommoncold", "Game.exe", "06a03fe35791b0578068ab1873455463", 5247960), + ENGLISH_ENTRY("adaywithmichael", "ADWM.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 65283966), + ENGLISH_ENTRY("adventurequest", "Begin.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1584015), + ENGLISH_ENTRY("adventurequest2", "adventure.exe", "f120690b506dd63cd7d1112ea6af2f77", 4603131), + ENGLISH_ENTRY("adventuresofjoshanddyan", "JoshandDyan.exe", "90413e9ae57e222f8913b09d2bc847bc", 3053444), + ENGLISH_ENTRY("adventuresofmaxfaxepisode1", "MaxFax1.exe", "f95aa7fd4c60ae0c64ab2bca085d0d15", 111272141), + ENGLISH_ENTRY("adventuresofprincessmarian", "marian.exe", "97d700529f5cc826f230c27acf81adfd", 3637811), + ENGLISH_ENTRY("adventuretheinsidejob", "Thalia.exe", "615e806856b7730afadf1fea9a756b70", 305012295), + ENGLISH_ENTRY("aerinde", "aerinde.exe", "3d40063da244931d67726a2d9600f1e8", 31700697), + ENGLISH_ENTRY("aeronuts", "AeroNuts.exe", "e446d58cf60bf13e32d0edd470065c7d", 10984662), + ENGLISH_ENTRY("afriendindeed", "TheHouse.exe", "3128b9f90e2f954ba704414ae854d10b", 6197624), + ENGLISH_ENTRY("afrojones", "afrojones.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 4739799), + ENGLISH_ENTRY("afterashadow", "After a Shadow.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 6157553), + ENGLISH_ENTRY("agenthudson", "ah.exe", "c7916b82f00c94013a3f7706b4d333c6", 15479216), + ENGLISH_ENTRY("agenttrinityepisode0theultimatum", "TheUltimatum_03.exe", "615e73fc1874e92d60a1996c2330ea36", 3777519), + ENGLISH_ENTRY("aggghost", "verbcoin.exe", "88d4158acfc9db9299e514979f289ced", 23937962), + ENGLISH_ENTRY("agitprop", "agitprop.exe", "a524cbb1c51589903c4043b98917f1d9", 12834513), + ENGLISH_ENTRY("agnosticchicken", "chicken.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 2473154), + ENGLISH_ENTRY("ags-mi3", "ags_mi3.exe", "0500aacb6c176d47ac0f8158f055db83", 5142697), + ENGLISH_ENTRY("agsawards2008ceremony", "aa2008.exe", "2615d67c2234f387e0ffd1a375476be0", 15151764), + ENGLISH_ENTRY("agsdarts", "AGS Darts.exe", "434c43a5e1ba2a11c1bde723ffeae719", 47771575), + ENGLISH_ENTRY("agsinvaders", "AGS-Invaders.exe", "f120690b506dd63cd7d1112ea6af2f77", 1394435), + ENGLISH_ENTRY("agsjukebox", "JukeBox2.exe", "a7aef57e360306c9377164f38d317ccb", 2914973), + ENGLISH_ENTRY("agsmoduletester", "V1.0 Source.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 2020344), + ENGLISH_ENTRY("agsyahtzee2", "AGS Yahtzee 2.exe", "9e995c04d8642d6182d492c54a90b188", 71217276), + ENGLISH_ENTRY("agsyathzee", "AGS Yathzee.exe", "434c43a5e1ba2a11c1bde723ffeae719", 37295758), + ENGLISH_ENTRY("agunshotinroom37", "AGIR37.exe", "f120690b506dd63cd7d1112ea6af2f77", 1451303), + ENGLISH_ENTRY("ahmetsagsfightgameremix", "Fight.exe", "f120690b506dd63cd7d1112ea6af2f77", 2469641), + ENGLISH_ENTRY("ainthegoffantabulousw", "gfw.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7991393), + ENGLISH_ENTRY("airwaveifoughtthelawandthelawone", "~airwave~.exe", "18456f28d9bf843b087e80072c85beca", 22521544), + ENGLISH_ENTRY("akumayosagschess275", "chess.exe", "f120690b506dd63cd7d1112ea6af2f77", 1198934), + ENGLISH_ENTRY("alansaveschristmasandmostoftheworldtoo", "ALANCMAS.exe", "3f76f9c4249bdc06794c13b098229c90", 39312224), + ENGLISH_ENTRY("albatheexplorer", "alba_explorer.exe", "0500aacb6c176d47ac0f8158f055db83", 2026147), + ENGLISH_ENTRY("alienattack", "Alien Attack.exe", "06a03fe35791b0578068ab1873455463", 11045476), + ENGLISH_ENTRY("alienpuzzleinvasion", "alien.exe", "a524cbb1c51589903c4043b98917f1d9", 10552264), + ENGLISH_ENTRY("alienrapeescape", "A.R.E.exe", "39d7a558298a9f1d40c1f415daf9bb74", 4802707), + ENGLISH_ENTRY("alienthreat", "Alien Threat.exe", "f120690b506dd63cd7d1112ea6af2f77", 6341266), + ENGLISH_ENTRY("alientimezone", "ATZ.exe", "0710e2ec71042617f565c01824f0cf3c", 2911858), + ENGLISH_ENTRY("aloneinthenight", "ALONE.exe", "0710e2ec71042617f565c01824f0cf3c", 9501343), + ENGLISH_ENTRY("alphadog", "Alpha_Dog.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3329253), + ENGLISH_ENTRY("alphax", "Project SMASH.exe", "06a03fe35791b0578068ab1873455463", 25377719), + ENGLISH_ENTRY("alphax", "alphax.exe", "06a03fe35791b0578068ab1873455463", 17879795), + ENGLISH_ENTRY("alquest1demo", "AlQuest.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 20154310), + ENGLISH_ENTRY("alysvsthephantomfelinefoe", "Alys.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 22323495), + ENGLISH_ENTRY("amagicstone", "A magic stone.exe", "465f972675db2da6040518221af5b0ba", 5478520), + ENGLISH_ENTRY("amotospuf", "Amotos.exe", "06a03fe35791b0578068ab1873455463", 10771879), + ENGLISH_ENTRY("amtag", "amtag.exe", "06a03fe35791b0578068ab1873455463", 8755912), + ENGLISH_ENTRY("anighttoremember", "The Trials.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 9643993), + ENGLISH_ENTRY("anna", "Anna.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 42337759), + ENGLISH_ENTRY("annieandroidautomatedaffection", "Annie source.exe", "fc17e9b3ab53f6b4841e2a4af5c782ff", 5015270), + ENGLISH_ENTRY("anoblegame", "a_noble_game.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 3580379), + ENGLISH_ENTRY("anthonysessay", "Copy of school.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 11033611), + ENGLISH_ENTRY("anticipatingmurder", "AGS.exe", "f120690b506dd63cd7d1112ea6af2f77", 19907137), + ENGLISH_ENTRY("antiheroes", "AntiHeroes.exe", "f120690b506dd63cd7d1112ea6af2f77", 3984580), + ENGLISH_ENTRY("apiratestale", "A_PIRATES_TALE.exe", "06a03fe35791b0578068ab1873455463", 13952670), + ENGLISH_ENTRY("aplaceinthesun", "InTheSun.exe", "7a3096ac0237cb6aa8e1718e28caf039", 40359648), + ENGLISH_ENTRY("apprentice", "App.exe", "ecc8eaa38fe3adea61ffc525d2ce5c0e", 14110306), + ENGLISH_ENTRY("apprentice2", "App2.exe", "465f972675db2da6040518221af5b0ba", 34159191), + ENGLISH_ENTRY("apprenticedeluxe", "App.exe", "45ab4f29031b50c8d01d10a269f77ff5", 17488604), + ENGLISH_ENTRY("aprofoundjourney", "apj.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 920131), + ENGLISH_ENTRY("archeos", "Archeos.exe", "2ff048659aaefd20d342db6428a5f1a0", 6661410), + ENGLISH_ENTRY("archeos", "Archeos.exe", "2ff048659aaefd20d342db6428a5f1a0", 6659974), + ENGLISH_ENTRY("arewethereyet", "AREwethereyet.exe", "f120690b506dd63cd7d1112ea6af2f77", 1054672), + ENGLISH_ENTRY("armageddonmargaret", "Armageddon Margaret.exe", "3128b9f90e2f954ba704414ae854d10b", 2951568), + ENGLISH_ENTRY("armageddonmargaret", "AM_Game.exe", "06a03fe35791b0578068ab1873455463", 3640885), + ENGLISH_ENTRY("asecondface", "Eye of Geltz.exe", "0e32c4b3380e286dc0cea8550f1c045e", 7061019), + ENGLISH_ENTRY("ashortnightmare", "A_Short_Nightmare.exe", "b142b43c146c25443a1d155d441a6a81", 94221930), + ENGLISH_ENTRY("asporia", "RPG.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 7094164), + ENGLISH_ENTRY("asterix", "Asterix.exe", "06a03fe35791b0578068ab1873455463", 62405430), + ENGLISH_ENTRY("astranded", "Astranded.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 1845395), + ENGLISH_ENTRY("astron", "Astron.exe", "a0fd918609b9d139e4076fa7a0052ae1", 71101771), + ENGLISH_ENTRY("aswinpathv01beta", "AGSGAME.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 14384181), + ENGLISH_ENTRY("ataleofbetrayal", "Mags.exe", "465f972675db2da6040518221af5b0ba", 11071496), + ENGLISH_ENTRY("ataleoftwokingdoms", "ATOTK.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42785860), + ENGLISH_ENTRY("atapi", "Atapi.exe", "dd8586ebefd5c457e29b6b9845a576ea", 34114381), + ENGLISH_ENTRY("atotkjukebox", "Jukebox.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 1631992), + ENGLISH_ENTRY("atreatandsometricks", "A Treat and Some Tricks.exe", "495d45fb8adfd49690ae3b97921feec6", 33708250), + ENGLISH_ENTRY("aunaturel", "Au Naturel.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 8499426), + ENGLISH_ENTRY("automation", "automation.exe", "c16204dc8aa338e3199b2c62da0b33f4", 3943320), + ENGLISH_ENTRY("averyspecialdog", "dog.exe", "465f972675db2da6040518221af5b0ba", 2120544), + ENGLISH_ENTRY("awakener", "Awakener.exe", "3e62eafed0fc365821b7afdbf1aec3d8", 8896076), + ENGLISH_ENTRY("awakening", "EOB.exe", "a524cbb1c51589903c4043b98917f1d9", 21527657), + ENGLISH_ENTRY("awakeningofthesphinx", "awksphinx.exe", "0500aacb6c176d47ac0f8158f055db83", 7507867), + ENGLISH_ENTRY("awalkindatomb", "full game.exe", "0710e2ec71042617f565c01824f0cf3c", 1312738), + ENGLISH_ENTRY("awalkinthepark", "sag_mag_04_08.exe", "9cb3c8dc7a8ab9c44815955696be2677", 2908542), + ENGLISH_ENTRY("axmasevetale", "MAGS.exe", "71ca0d6c1c699595f28a2125948d4a84", 6489870), + ENGLISH_ENTRY("backdoorman", "hustler.exe", "2c26669a627da8e1e5159319b78ad1ce", 9558000), + ENGLISH_ENTRY("badluck", "Bad Luck.exe", "f120690b506dd63cd7d1112ea6af2f77", 10618466), + ENGLISH_ENTRY("baldysadventure", "Baldy.exe", "ea0d3284542db629f36cb6fc785e07bc", 179358984), + ENGLISH_ENTRY("baltazarthefamiliar", "Baltazar.exe", "9cb3c8dc7a8ab9c44815955696be2677", 2867294), + ENGLISH_ENTRY("bananamandemo", "Banana Man Demo.exe", "615e806856b7730afadf1fea9a756b70", 53524952), + ENGLISH_ENTRY("bananaracer", "BananaRacer.exe", "e93f9dfa8405f1ca9f881d160ab31dc2", 10452233), + ENGLISH_ENTRY("barndilemma", "woh.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 2432485), + ENGLISH_ENTRY("barnrunner5part1", "Barn Runner 5-1.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 104073543), + ENGLISH_ENTRY("barnrunner5part2", "Barn Runner 5-2.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 200879890), + ENGLISH_ENTRY("barnrunnerholiday2", "Xmas 2.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 31770973), + ENGLISH_ENTRY("bartsquestfortv", "Simpsons.exe", "0500aacb6c176d47ac0f8158f055db83", 794013), + ENGLISH_ENTRY("battlewarriors", "Battle.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 16314318), + ENGLISH_ENTRY("beacon", "Beacon.exe", "af0d268193a9220891e983d03141ec58", 24671086), + ENGLISH_ENTRY("bear", "Bear.exe", "97020973a2a635fe28eb0ba4bdfaa70b", 3258662), + ENGLISH_ENTRY("beasts", "beasts.exe", "0500aacb6c176d47ac0f8158f055db83", 1295435), + ENGLISH_ENTRY("beautiesandbeasts", "BeautiesAndBeasts.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 6507202), + ENGLISH_ENTRY("benjaminjordan", "BJ1.exe", "4b1378721f4f066f75102f3dca809224", 5678910), + ENGLISH_ENTRY("benjordancase1", "BJ1Deluxe.exe", "8275249f4ffbc28c1f10ad09a2786814", 8293704), + ENGLISH_ENTRY("bentheredanthat", "BTDT.exe", "90413e9ae57e222f8913b09d2bc847bc", 46342499), + ENGLISH_ENTRY("bernardsroom", "BernardsRoom.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 8767774), + ENGLISH_ENTRY("besieged", "besieged.exe", "615e806856b7730afadf1fea9a756b70", 11679795), + ENGLISH_ENTRY("bestowersofeternity", "Eternity.exe", "0b66a68c2c8aabe78c80e30b8b82acef", 16187539), + ENGLISH_ENTRY("beyondreality", "br.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 10879320), + ENGLISH_ENTRY("beyondterror", "BeyondTerror.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 8219797), + ENGLISH_ENTRY("beyondthehorizon", "Horizon.exe", "4d7d2addcde045dae6e0363a43f9acad", 15708563), + ENGLISH_ENTRY("bigbadwolf3lilpiggies", "Big Bad Wolf.exe", "06a03fe35791b0578068ab1873455463", 5812024), + ENGLISH_ENTRY("bigglesonmars", "Biggles On Mars.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 29048931), + ENGLISH_ENTRY("billyboysimportantwinelottery", "BillyBoy.exe", "5881d6b88386317dc9d67524a14b11d4", 4872317), + ENGLISH_ENTRY("birdy", "Birdy.exe", "06a03fe35791b0578068ab1873455463", 4250415), + ENGLISH_ENTRY("bj7thecardinalsins", "BJ7.exe", "18b284c22010850f79bc5c20054a70c4", 13714066), + ENGLISH_ENTRY("bjcase2", "BJ2.exe", "465f972675db2da6040518221af5b0ba", 6318491), + ENGLISH_ENTRY("bjcase3", "BJ3.exe", "61f113e2e52e0dd27aeb438a55dd9b8c", 10841883), + ENGLISH_ENTRY("bjcase4", "BJ4.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 15303392), + ENGLISH_ENTRY("bjcase5", "BJ5.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 13681827), + ENGLISH_ENTRY("bjcase6", "BJ6.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 18281493), + ENGLISH_ENTRY("blackmailinbrooklyn", "brooklyn.exe", "3192c36199d2b0784f866b28da7106d8", 4913695), + ENGLISH_ENTRY("blackmorph", "Liechi.exe", "46859c6f77bdb311266daa589561fa6b", 14476030), + ENGLISH_ENTRY("blackuddertodoubloonornottodoubloon", "Blackudder.exe", "338fa79960d40689063af31c671b8729", 87695958), + ENGLISH_ENTRY("blackwellconvergence", "Convergence.exe", "856a6e0e22d2cb4a45d5bbc7245ce5e8", 29935120), + ENGLISH_ENTRY("blackwelllegacydemo", "Blackwell Demo.exe", "2eeca6bae968dc61b5ed36561efc0fca", 53342880), + ENGLISH_ENTRY("blackwellunbounddemo", "Unbound_Demo.exe", "6ee842f73649ced615c44d4eb303687c", 30057537), + ENGLISH_ENTRY("bluemoon", "Blue Moon.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 14845997), + ENGLISH_ENTRY("boardquest", "Board Quest.exe", "465f972675db2da6040518221af5b0ba", 3930325), + ENGLISH_ENTRY("bob", "bob.exe", "0b7529a76f38283d6e850b8d56526fc1", 2874144), + ENGLISH_ENTRY("bobencavale", "Bob en cavale.exe", "06a03fe35791b0578068ab1873455463", 43264937), + ENGLISH_ENTRY("bobgoeshome", "Tut.exe", "0710e2ec71042617f565c01824f0cf3c", 1480234), + ENGLISH_ENTRY("bobgoeshomedeluxe", "BobDeluxe.exe", "0710e2ec71042617f565c01824f0cf3c", 1555913), + ENGLISH_ENTRY("bobsquest1", "BQ19.exe", "97d700529f5cc826f230c27acf81adfd", 2767487), + ENGLISH_ENTRY("bogsadventure", "BogsAdventure.exe", "25f919423520b921a041ec854e3a0217", 58789948), + ENGLISH_ENTRY("boom", "boom.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 934966), + ENGLISH_ENTRY("bowserquirkquest", "Bowser Quirk Quest.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3046623), + ENGLISH_ENTRY("box", "Box.exe", "0b7529a76f38283d6e850b8d56526fc1", 748638), + ENGLISH_ENTRY("boyindahood", "Boy in da hood.exe", "afe40dc1416dd51e896ee0444d799f07", 12260759), + ENGLISH_ENTRY("bradbradsonkeyquest", "BADness.exe", "0500aacb6c176d47ac0f8158f055db83", 1190580), + ENGLISH_ENTRY("breakdownbyonedollar", "Breakdown.exe", "710ac163c281a5a539ffe2386264b990", 5273352), + ENGLISH_ENTRY("bsg78unexpectedattherisingstar", "BSG-E01.exe", "cf1ff01dfb8261f791ac95a7f5f05c1c", 401029955), + ENGLISH_ENTRY("btd", "BTD.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 6450527), + ENGLISH_ENTRY("bubsythebobcatinripvanbubsystarringbubsy", "Rip Van Bubsy.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 52424482), + ENGLISH_ENTRY("buccaneer", "Buccaneer.exe", "c87aa6377abc18c1a1b2968ae6db08eb", 1576850), + ENGLISH_ENTRY("bullettrain", "Bullet Train.exe", "f120690b506dd63cd7d1112ea6af2f77", 17383747), + ENGLISH_ENTRY("bunawantsbeer", "BWB.exe", "c02022408287355175a601fd5ed1c66d", 2285202), + ENGLISH_ENTRY("bunnyquest", "BunnyQuest.exe", "28f82e420b82d07651b68114f90223c8", 1154928), + ENGLISH_ENTRY("burymeinthesand", "buryme.exe", "f10516e88ec858700804ee69d041aead", 24252498), + ENGLISH_ENTRY("butcherstanys", "Stanys.exe", "97d700529f5cc826f230c27acf81adfd", 1404933), + ENGLISH_ENTRY("bytheswordconspiracy", "bts.exe", "7dc7f61f79ba7a77d4ef8168bfd3d173", 60246329), + ENGLISH_ENTRY("calebsdrunkenadventure", "Calebdru.exe", "0b7529a76f38283d6e850b8d56526fc1", 15484923), + ENGLISH_ENTRY("calsoon2", "Looncalsoon.exe", "97d700529f5cc826f230c27acf81adfd", 18981033), + ENGLISH_ENTRY("capricorn", "capricorn.exe", "06a03fe35791b0578068ab1873455463", 4817076), + ENGLISH_ENTRY("captaincringe", "Captain_Cringe.exe", "dd8586ebefd5c457e29b6b9845a576ea", 2631464), + ENGLISH_ENTRY("carrin", "Carrin.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 2376923), + ENGLISH_ENTRY("carrotbobinzxspeccyworld", "CarrotBob.exe", "949f7440e3692b7366c2029979dee9a0", 914509), + ENGLISH_ENTRY("casablancathedayafter", "Casablanca.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4238105), + ENGLISH_ENTRY("castleoffire", "Castle of Fire.exe", "b6f0726bd5776abee0d452b8f1073850", 14800915), + ENGLISH_ENTRY("catacombic", "Catacombic.exe", "057d1aa29f6fadd83209268efcfb35a3", 7317791), + ENGLISH_ENTRY("catapault", "catapault.exe", "290afe0bac54418822f15175e474731d", 8286661), + ENGLISH_ENTRY("cayannepepper", "cPepper.exe", "06a03fe35791b0578068ab1873455463", 16117141), + ENGLISH_ENTRY("cedricandtherevolution", "elves!.exe", "b216ee957dd677023e02d900281a02d6", 10205755), + ENGLISH_ENTRY("celticchaos2fishermensfiends", "CC2.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 17463014), + ENGLISH_ENTRY("chalksquest", "Chalk.exe", "0710e2ec71042617f565c01824f0cf3c", 5138049), + ENGLISH_ENTRY("charliefoxtrot", "foxtrot.exe", "0500aacb6c176d47ac0f8158f055db83", 48626762), + ENGLISH_ENTRY("chatroom", "Chatroom.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 6760748), + ENGLISH_ENTRY("cheerfulscience", "CheerfulScience.exe", "06a03fe35791b0578068ab1873455463", 7740040), + ENGLISH_ENTRY("chekken", "cheKKen.exe", "bde175c0c4d87a59a7a082be595d08da", 13477393), + ENGLISH_ENTRY("chemin", "chemin.exe", "06a03fe35791b0578068ab1873455463", 3179064), + ENGLISH_ENTRY("chezapa", "CHEZAPA.exe", "9cf51833e787cc919837d9a8bd8fc14c", 2870327), + ENGLISH_ENTRY("chickchaser", "AMY.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7968024), + ENGLISH_ENTRY("chicken", "Chicken.exe", "f120690b506dd63cd7d1112ea6af2f77", 30627567), + ENGLISH_ENTRY("chicken", "chicken.exe", "f120690b506dd63cd7d1112ea6af2f77", 1652888), + ENGLISH_ENTRY("chickenfraction", "Chicken.exe", "0500aacb6c176d47ac0f8158f055db83", 3021315), + ENGLISH_ENTRY("chinesecheckers", "ChineseCheckers.exe", "06a03fe35791b0578068ab1873455463", 3391826), + ENGLISH_ENTRY("christmaspresent", "christmas.exe", "3128b9f90e2f954ba704414ae854d10b", 5644948), + ENGLISH_ENTRY("christmasquest", "Christmas Quest.exe", "f120690b506dd63cd7d1112ea6af2f77", 14042816), + ENGLISH_ENTRY("christmasquest2", "ChristmasQuest2.exe", "06a03fe35791b0578068ab1873455463", 22683950), + ENGLISH_ENTRY("christmasquest3santaslittlehelpdesk", "CQ3.exe", "f0a7712890942b9155193cc4488a07bc", 50854625), + ENGLISH_ENTRY("cirquedezale", "cirque.exe", "3128b9f90e2f954ba704414ae854d10b", 8547131), + ENGLISH_ENTRY("claire", "Claire.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 2781456), + ENGLISH_ENTRY("classnotesv11", "ClassNotes.exe", "0710e2ec71042617f565c01824f0cf3c", 5706836), + ENGLISH_ENTRY("clex", "Clex.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1381575), + ENGLISH_ENTRY("clipl2heblinna", "Clip goes to town.exe", "0710e2ec71042617f565c01824f0cf3c", 1690928), + ENGLISH_ENTRY("clubofevil", "Club of Evil.exe", "65f53f81071dab6b3ab8363e4c76d12e", 11838011), + ENGLISH_ENTRY("coeldeckaflightgame", "coell deca.exe", "a524cbb1c51589903c4043b98917f1d9", 5497572), + ENGLISH_ENTRY("coinrush2", "coinrsh2.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 1260438), + ENGLISH_ENTRY("colinsimpsonleavesemployme", "Office.exe", "06a03fe35791b0578068ab1873455463", 11781006), + ENGLISH_ENTRY("colourclash", "ColourClash.exe", "0241777c2537fc5d077c05cde10bfa9f", 2803703), + ENGLISH_ENTRY("colourwise", "ColourWise.exe", "473f0e2fd72b747cef62d91090ab74c7", 24461117), + ENGLISH_ENTRY("colourwiseleveleditor", "ColourWise - Level Editor.exe", "3e09048ec0763a90ffa4eaeeb8f96df5", 3365519), + ENGLISH_ENTRY("columbuslander", "Columbus Lander.exe", "779421cd8ad5268e2efdb26e04608db7", 48744943), + ENGLISH_ENTRY("comradecitizenpart1", "Citizen.exe", "06a03fe35791b0578068ab1873455463", 2174301), + ENGLISH_ENTRY("confessionsofacatburglar", "cat.exe", "0500aacb6c176d47ac0f8158f055db83", 1328541), + ENGLISH_ENTRY("conspiracybelowzero", "Conspiracy.exe", "338fa79960d40689063af31c671b8729", 395111008), + ENGLISH_ENTRY("conspiracyofsongo", "Songo.exe", "934a3d245739d7ac66c021f8409c1044", 31526905), + ENGLISH_ENTRY("constancethebarbarian", "CTB.exe", "0500aacb6c176d47ac0f8158f055db83", 1150440), + ENGLISH_ENTRY("cosmos", "space.exe", "0500aacb6c176d47ac0f8158f055db83", 3591766), + ENGLISH_ENTRY("cosmosquesti", "tfas1.exe", "ff3d6e4edfca8b4f4f1c6cbf8e2781a6", 16653211), + ENGLISH_ENTRY("cosmosquestii", "tfas2-32bit.exe", "ff3d6e4edfca8b4f4f1c6cbf8e2781a6", 118740291), + ENGLISH_ENTRY("cosmosquestiii", "CQ3.exe", "18b284c22010850f79bc5c20054a70c4", 8674790), + ENGLISH_ENTRY("cougarsquestforfreedom", "chra.exe", "0500aacb6c176d47ac0f8158f055db83", 12654043), + ENGLISH_ENTRY("counterfeit", "Counterfeit.exe", "ef1645ccd3d16691ec3908c91f340c34", 2232297), + ENGLISH_ENTRY("cow", "cow.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 134670383), + ENGLISH_ENTRY("coyote", "Coyote.exe", "a524cbb1c51589903c4043b98917f1d9", 33124533), + ENGLISH_ENTRY("craftofevil", "Craft Of Evil.exe", "4c1d9a74c4acf6771aab4be704bf0797", 22409329), + ENGLISH_ENTRY("crashevadedestroy", "CED.exe", "06a03fe35791b0578068ab1873455463", 1938399), + ENGLISH_ENTRY("crave", "Crave.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 59222727), + ENGLISH_ENTRY("crypt", "crypt.exe", "0500aacb6c176d47ac0f8158f055db83", 2089059), + ENGLISH_ENTRY("cryptic", "Cryptic.exe", "d9143b143b011d7bd8726c1bb5dabc59", 6027654), + ENGLISH_ENTRY("csihunt1", "CSI Hunt 1.exe", "06a03fe35791b0578068ab1873455463", 2190662), + ENGLISH_ENTRY("cspb", "CSPB.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 77296215), + ENGLISH_ENTRY("cuentosinconclusos", "ShSt.exe", "28f82e420b82d07651b68114f90223c8", 1013809), + ENGLISH_ENTRY("cyberjack", "brewton24.exe", "e3962995a70923a8d5a8f1cf8f932eee", 3439339), + ENGLISH_ENTRY("daleks", "Daleks.exe", "0241777c2537fc5d077c05cde10bfa9f", 2409634), + ENGLISH_ENTRY("dalesfilmquest", "dale.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 2557975), + ENGLISH_ENTRY("damsel", "Damsel.exe", "809418706c429cee5d88e8d483c906cc", 77101995), + ENGLISH_ENTRY("dancetilyoudrop", "DanceTilYouDrop.exe", "0710e2ec71042617f565c01824f0cf3c", 4822399), + ENGLISH_ENTRY("danewguys", "DaNewGuys.exe", "97020973a2a635fe28eb0ba4bdfaa70b", 11998791), + ENGLISH_ENTRY("danewguys", "DaNewGuys.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 12115013), + ENGLISH_ENTRY("dangerouslandstournamentrpg", "dlrt2.exe", "0710e2ec71042617f565c01824f0cf3c", 21636362), + ENGLISH_ENTRY("dannydreadisoncall", "On Call.exe", "ef480ccb0831e452e55456e0ca24c761", 8787649), + ENGLISH_ENTRY("darkcave", "DarkCave.exe", "0d48d8b170624e8f33bd7cd7f3ad2052", 5293954), + ENGLISH_ENTRY("darkofnight", "D_o_N.exe", "3f7bb944e107f883d183f047d9d7f698", 10261961), + ENGLISH_ENTRY("darktimesmerrychristmas", "Dark Times (Merry Christmas).exe", "1b9f13d430bb15bf30d0fd044358db68", 49043355), + ENGLISH_ENTRY("darum", "Darum.exe", "0241777c2537fc5d077c05cde10bfa9f", 4082708), + ENGLISH_ENTRY("darum", "afterlife.exe", "0241777c2537fc5d077c05cde10bfa9f", 4082712), + ENGLISH_ENTRY("davegeneric", "generic.exe", "a524cbb1c51589903c4043b98917f1d9", 2449830), + ENGLISH_ENTRY("davidletterman", "letterman.exe", "615e806856b7730afadf1fea9a756b70", 17019706), + ENGLISH_ENTRY("dawnswonderedatagesend", "myGame.exe", "75f4c7f66b1be60af5b2d65f617b91a7", 243406385), + ENGLISH_ENTRY("ddddd", "DDDDD.exe", "f3f788c1e3a7b0b40e24e453fa1b9440", 21718220), + ENGLISH_ENTRY("deadmeat", "Cold Meat.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 41382750), + ENGLISH_ENTRY("deadofwinter", "DoW.exe", "615e806856b7730afadf1fea9a756b70", 7055437), + ENGLISH_ENTRY("deathandtransfiguration", "death.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 11103314), + ENGLISH_ENTRY("deathofanangel", "Angel.exe", "f120690b506dd63cd7d1112ea6af2f77", 3906130), + ENGLISH_ENTRY("deathsdoor", "Death's Door.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 31447213), + ENGLISH_ENTRY("deathsquest", "HEHU!.exe", "949f7440e3692b7366c2029979dee9a0", 991809), + ENGLISH_ENTRY("deathworeendlessfeathersdisk1", "Cyberpunk.exe", "2aaa2609117a34adf666ea546e6dc000", 12620944), + ENGLISH_ENTRY("demogame", "Demo Game.exe", "f120690b506dd63cd7d1112ea6af2f77", 3296215), + ENGLISH_ENTRY("demonday", "Testgame.exe", "0b7529a76f38283d6e850b8d56526fc1", 6749329), + ENGLISH_ENTRY("derverschwundenehusky", "Husky.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 51932091), + ENGLISH_ENTRY("detectivegallo", "dgbuild.exe", "5f2e683b0d5e66e47f5800322982171e", 466252165), + ENGLISH_ENTRY("detention", "little.exe", "c16204dc8aa338e3199b2c62da0b33f4", 2362176), + ENGLISH_ENTRY("devochkaquest", "DevochkaQuest.exe", "84faea68bf7277610c2229be7b3e74af", 32769660), + ENGLISH_ENTRY("dgsearchofthebatterie", "dgsfb.exe", "88cf59aad15ca331ab0f854e16c84df3", 1664209), + ENGLISH_ENTRY("diamondsintheroughdemo", "Diamonds Demo.exe", "14c995189266969d538b31d1df451d3f", 2439365), + ENGLISH_ENTRY("diemaskennyarlathoteps", "ags_masken.exe", "74dc062c5f68f3d70da911f2db5737b6", 129219473), + ENGLISH_ENTRY("disquiet", "Disquiet.exe", "f90f5f612ed5879addfdd8634d093333", 9624101), + ENGLISH_ENTRY("doctormaze", "Maze.exe", "825ccacaabe2a3b0cd48d6f8deb42d72", 43934617), + ENGLISH_ENTRY("doctormuttonchop", "muttonchop.exe", "57e261dd3bb45761af4a002775e45710", 5781714), + ENGLISH_ENTRY("donnaavengerofblood", "DONNA.exe", "74aad8dfd71ed2ae9574a60be7610c43", 275096403), + ENGLISH_ENTRY("donniedarko", "Darko.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1820048), + ENGLISH_ENTRY("donspillacyconspiracyquest", "DSAQ.exe", "f120690b506dd63cd7d1112ea6af2f77", 2066918), + ENGLISH_ENTRY("donthedweebdancedilemma", "Don the Dweeb.exe", "f120690b506dd63cd7d1112ea6af2f77", 2278453), + ENGLISH_ENTRY("dontworryillbringthebeer", "Don't Worry, I'll Bring The Beer.exe", "495d45fb8adfd49690ae3b97921feec6", 4446095), + ENGLISH_ENTRY("dovadulasburn", "FILES.exe", "9cb3c8dc7a8ab9c44815955696be2677", 26489645), + ENGLISH_ENTRY("downfall", "Downfall.exe", "aabdafae8b57dfc48fdf158a72326c23", 183357927), + ENGLISH_ENTRY("dragonorb", "DragonOrb.exe", "2bc8f994a7d1e05ed45f35abf2128231", 269836732), + ENGLISH_ENTRY("dragontales", "dragont.exe", "465f972675db2da6040518221af5b0ba", 9240132), + ENGLISH_ENTRY("dreadmacfarlane", "Dread.exe", "615e806856b7730afadf1fea9a756b70", 11157310), + ENGLISH_ENTRY("dreadmacfarlane2", "Dread2.exe", "fb787304e66798ba9d0172665a34f4cf", 5332574), + ENGLISH_ENTRY("dreamagine", "Game.exe", "256752c9a97b4780fc5e6f3239c8cdf1", 11122818), + ENGLISH_ENTRY("dreamer", "LittleDreamer.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 62151801), + ENGLISH_ENTRY("dreamsequence", "dreamseq.ags", "97d700529f5cc826f230c27acf81adfd", 4724470), + ENGLISH_ENTRY("drlutztimetravelmachine", "Dr.Lutz Machine.exe", "2bc8f994a7d1e05ed45f35abf2128231", 12602529), + ENGLISH_ENTRY("dumbassdriversdemo", "dumbass.exe", "f120690b506dd63cd7d1112ea6af2f77", 40580988), + ENGLISH_ENTRY("dungeonhands", "DungeonHands.exe", "0a6704159f6f716ac80da91c430430ce", 16276450), + ENGLISH_ENTRY("dungeonhands", "DungeonHands.exe", "f80ff6c2348f2bb90d3813719f54c870", 13751518), + ENGLISH_ENTRY("duskhunters", "DuskHunters.exe", "3128b9f90e2f954ba704414ae854d10b",3029482), + ENGLISH_ENTRY("dusttowater", "Dust to Water.exe", "0e32c4b3380e286dc0cea8550f1c045e", 70459846), + ENGLISH_ENTRY("dutyandbeyond", "Deliver.exe", "0710e2ec71042617f565c01824f0cf3c", 28873258), + ENGLISH_ENTRY("duzzquest", "DuzzQuest.exe", "3128b9f90e2f954ba704414ae854d10b", 13125200), + ENGLISH_ENTRY("duzzquest2", "DuzzQuest2.exe", "8911d942c1a71458370d37ca3e5bfdda", 59088366), + ENGLISH_ENTRY("dysmaton", "Dysmaton.exe", "6e861b1f476ff7cdf036082abb271329", 140513956), + ENGLISH_ENTRY("earlbobbyislookingforaloodemo", "Demo.exe", "0e32c4b3380e286dc0cea8550f1c045e", 4221725), + ENGLISH_ENTRY("earlbobbyislookingforhisshoes", "Bobby's Shoes.exe", "bb59de174d70797d774dec76a171352d", 12735626), + ENGLISH_ENTRY("earlbobbysballs", "Bobby's Balls.exe", "bb59de174d70797d774dec76a171352d", 4006605), + ENGLISH_ENTRY("earlmansinthebreakout", "Earl Mansin.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 108987401), + ENGLISH_ENTRY("earthlingpriorities", "Earthling Priorities.exe", "9b54ea3557373188d8388ec4d1ae5eed", 21490281), + ENGLISH_ENTRY("easterislanddefender", "Moia 'n Seek.exe", "804add6fbbb791b7be195dc0097434a1", 6359079), + ENGLISH_ENTRY("easy3d", "Easy3D.exe", "06a03fe35791b0578068ab1873455463", 13361265), + ENGLISH_ENTRY("edmund", "Edmundand the potato.exe", "615e73fc1874e92d60a1996c2330ea36", 4533124), + ENGLISH_ENTRY("educatingadventuresofgirlandrabbit", "Game.exe", "82da2565c456dcfb265ded6fe3189c0b", 2877964), + ENGLISH_ENTRY("eerieblue", "EerieBlue.exe", "bacdba3c759a861e899e6b0adcbb8bd5", 96605122), + ENGLISH_ENTRY("electrctgui", "electrctGUI.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 8941606), + ENGLISH_ENTRY("elevator", "Elevator.exe", "f10516e88ec858700804ee69d041aead", 29506915), + ENGLISH_ENTRY("elfer10", "socer.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1911767), + ENGLISH_ENTRY("elfmotorsinc", "ElfMtrs.exe", "3421b46ff95c5885603086c39a038a20", 8036769), + ENGLISH_ENTRY("elforescuecraby", "elfo.exe", "31457af75a89b6141c31e8ed33a57e25", 10641021), + ENGLISH_ENTRY("eliminationbyimprovisation", "Stu2.exe", "9cf51833e787cc919837d9a8bd8fc14c", 971446), + ENGLISH_ENTRY("emeraldeyes", "Emerald.exe", "f120690b506dd63cd7d1112ea6af2f77", 2849945), + ENGLISH_ENTRY("emilyenough", "EE.exe", "97020973a2a635fe28eb0ba4bdfaa70b", 3141963), + ENGLISH_ENTRY("emmarodedemo", "Emma Roide.exe", "aefd91a131817036d224fe030e406c6e", 24919443), + ENGLISH_ENTRY("emptymindblankfate", "EMBF.exe", "18b284c22010850f79bc5c20054a70c4", 75732051), + ENGLISH_ENTRY("enoworld", "Enoworld.exe", "465f972675db2da6040518221af5b0ba", 16151170), + ENGLISH_ENTRY("enterthestory", "Enter The Story.exe", "0514661a4ba6772cf0db0cf839fc7003", 19589742), + ENGLISH_ENTRY("equilibrium", "EQ.exe", "0500aacb6c176d47ac0f8158f055db83", 8398394), + ENGLISH_ENTRY("erictheanteater", "eric.exe", "e750ecac380dca709028fc0744b9f7f6", 3865602), + ENGLISH_ENTRY("erkadventuresinstoneagerealestate", "AISRE.exe", "41e8fa920589300ed8b4aec09a658c90", 5958575), + ENGLISH_ENTRY("errand", "Errand.exe", "8212e96af620f6e02a37fdf583f79751", 4421187), + ENGLISH_ENTRY("escape", "Escape.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 962798), + ENGLISH_ENTRY("escapefromasmallroom", "game1.exe", "0b7529a76f38283d6e850b8d56526fc1", 803029), + ENGLISH_ENTRY("escapefromevergreenforest", "EFEF.exe", "2e58934bbe98335f33c20a23a6c6135a", 23855632), + ENGLISH_ENTRY("escapefromlurrilous", "EFL.exe", "4bcbc24015114752b3c7971128704689", 2756979), + ENGLISH_ENTRY("escapefromthesalemmoons", "Salem.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1394026), + ENGLISH_ENTRY("escapefromthezombiecity", "zombie.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 3216299), + ENGLISH_ENTRY("escapetheship", "Escape.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1063503), + ENGLISH_ENTRY("esper", "esper.exe", "0710e2ec71042617f565c01824f0cf3c", 17409715), + ENGLISH_ENTRY("eternallyus", "Eternally Us.exe", "3faa59edd92158ff2cbd4b9db54acf61", 43467084), + ENGLISH_ENTRY("eventtimer", "Timer.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 3000682), + ENGLISH_ENTRY("exclamation", "!.exe", "0514661a4ba6772cf0db0cf839fc7003", 2785515), + ENGLISH_ENTRY("exit", "EXIT.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 54723513), + ENGLISH_ENTRY("fadingshades", "FadingShades.exe", "f120690b506dd63cd7d1112ea6af2f77", 20166198), + ENGLISH_ENTRY("fakethemoonlanding", "OperationStarman.exe", "495d45fb8adfd49690ae3b97921feec6", 56805472), + ENGLISH_ENTRY("fallenangel", "Fallen Angel.exe", "f120690b506dd63cd7d1112ea6af2f77", 3993369), + ENGLISH_ENTRY("fallensoldier", "fallen soldier.exe", "7a3096ac0237cb6aa8e1718e28caf039", 81522018), + ENGLISH_ENTRY("fanbots", "Game.exe", "aecd482222ff54206e43a029b5f0b170", 8665702), + ENGLISH_ENTRY("farnowhere", "FAR NOWHERE.exe", "06a03fe35791b0578068ab1873455463", 77186777), + ENGLISH_ENTRY("fasmo", "fasmo.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 16778433), + ENGLISH_ENTRY("fasmogoeswest", "FasmoGoesWest.exe", "f120690b506dd63cd7d1112ea6af2f77", 15348030), + ENGLISH_ENTRY("fbiquest", "FQ.exe", "465f972675db2da6040518221af5b0ba", 3838610), + ENGLISH_ENTRY("fearaphobia", "Fearaphobia.exe", "c48d0beedcdc1b05e9e25dcd60de46a9", 9646228), + ENGLISH_ENTRY("featherweight", "Featherweight.exe", "e8b2a430042709f07183c2c249e0e0d9", 6399452), + ENGLISH_ENTRY("femspray", "Fem.exe", "01d0e6bd812abaa307bcb10fc2193416", 49176669), + ENGLISH_ENTRY("fengshuiandtheartoftvreception", "Feng Shui And The Art Of TV Reception.exe", "c1b88c284a3d821f93d78a2e88487932", 22687931), + ENGLISH_ENTRY("feuersturmkapitel1", "Feuersturm.exe", "06a03fe35791b0578068ab1873455463", 5682579), + ENGLISH_ENTRY("feuersturmkapitel2", "fs2.exe", "06a03fe35791b0578068ab1873455463", 7043558), + ENGLISH_ENTRY("feuersturmkapitel3", "feuersturm3.exe", "206478d4d39e16571682b2cddf01a78f", 7826524), + ENGLISH_ENTRY("fifa2003pro", "Soccer.exe", "475da5decb9ad2a11e64e2e2e891d8e0", 2524958), + ENGLISH_ENTRY("fight", "boxen.exe", "3128b9f90e2f954ba704414ae854d10b", 3132938), + ENGLISH_ENTRY("fightgame", "Fight Game.exe", "463f79e5db4013d1b3be647edd7e338d", 1871790), + ENGLISH_ENTRY("fightgame", "Fight Game.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3551992), + ENGLISH_ENTRY("fireflystory3d", "FFS 3D.exe", "27343924ddad3be0b97bdcaa71858b1b", 2254453), + ENGLISH_ENTRY("flamebarrel", "Flame barrel.exe", "06a03fe35791b0578068ab1873455463", 2298745), + ENGLISH_ENTRY("flashbax", "demo Flashbax.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 5527034), + ENGLISH_ENTRY("flowergirl", "flowergirl.exe", "9cb3c8dc7a8ab9c44815955696be2677", 62544543), + ENGLISH_ENTRY("fluxworld", "FluxWorld.exe", "06a03fe35791b0578068ab1873455463", 5614789), + ENGLISH_ENTRY("forcemajeureiithezone", "TheZoneDemo.exe", "b63d26c17bf292017f9a708ae9dc38ca", 18414473), + ENGLISH_ENTRY("forfrogssakegetthefrogout", "Frog2.exe", "0241777c2537fc5d077c05cde10bfa9f", 6723366), + ENGLISH_ENTRY("forgettendeath", "ForgettenDeath.exe", "06a03fe35791b0578068ab1873455463", 19427130), + ENGLISH_ENTRY("fortressofwonders", "Fortress.exe", "465f972675db2da6040518221af5b0ba", 4474304), + ENGLISH_ENTRY("fountainofunicorns", "pmvi.exe", "465f972675db2da6040518221af5b0ba", 3038012), + ENGLISH_ENTRY("fountainofyouthdemo", "foydemo.exe", "f120690b506dd63cd7d1112ea6af2f77", 14372003), + ENGLISH_ENTRY("framed", "Jhum.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 4572587), + ENGLISH_ENTRY("frankenpooper", "frankenpooper.exe", "fb3b0f6bad923958d9d9198daea125e6", 24372899), + ENGLISH_ENTRY("frankthefarmhandpart1", "Frank.exe", "0006c0a95a5f35ca0d275adecf9dfa1d", 22602166), + ENGLISH_ENTRY("frankthefarmhandpart2", "Frank2.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 63832313), + ENGLISH_ENTRY("franticfrankoabergzwerggoneberserk", "steelh1.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 118746106), + ENGLISH_ENTRY("frasiercraneseattlerampage", "FRASIER.exe", "0241777c2537fc5d077c05cde10bfa9f", 3688664), + ENGLISH_ENTRY("fredandbarneymeetthefuture", "Fred and Barney meet the future.exe", "c48d0beedcdc1b05e9e25dcd60de46a9", 234107316), + ENGLISH_ENTRY("fribbeldib", "firbbeldib.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 90835696), + ENGLISH_ENTRY("frogisland", "frog_island.exe", "465f972675db2da6040518221af5b0ba", 4355477), + ENGLISH_ENTRY("fsis1000000quest", "$1000000.exe", "0710e2ec71042617f565c01824f0cf3c", 833468), + ENGLISH_ENTRY("fsisalienation", "alienation.exe", "06a03fe35791b0578068ab1873455463", 3812243), + ENGLISH_ENTRY("fsiscotmattcehotsvd", "valgame.exe", "06a03fe35791b0578068ab1873455463", 2199912), + ENGLISH_ENTRY("fsismhcfhr", "das_id.exe", "0710e2ec71042617f565c01824f0cf3c", 1852114), + ENGLISH_ENTRY("fsispowercowfromuranus", "PowerCowen.exe", "0710e2ec71042617f565c01824f0cf3c", 1442185), + ENGLISH_ENTRY("fulkinthedreamthaus", "DreamtHaus.exe", "06a03fe35791b0578068ab1873455463", 47212093), + ENGLISH_ENTRY("funsunmishaps", "Fun, Sun & Mishaps.exe", "933200c8f306eccaaa484b1575da8528", 452348894), + ENGLISH_ENTRY("funwithnumbers", "fwn.exe", "a524cbb1c51589903c4043b98917f1d9", 18743833), + ENGLISH_ENTRY("gabyking", "GabyKing.exe", "1fd15cc387812c04447d89729b24b097", 2289131), + ENGLISH_ENTRY("gamesgalore", "gamesgalore.exe", "f120690b506dd63cd7d1112ea6af2f77", 7620552), + ENGLISH_ENTRY("gassesuittollis3demo", "Gst3_demo.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4270243), + ENGLISH_ENTRY("gatewayremake", "Gateway Remake.exe", "0241777c2537fc5d077c05cde10bfa9f", 210991212), + ENGLISH_ENTRY("genbu", "Genbu.exe", "64fcaf7da0b257ea831f89c54be0ad72", 1892238), + ENGLISH_ENTRY("geometricshapes1circleboy", "Circle1.exe", "06a03fe35791b0578068ab1873455463", 2389129), + ENGLISH_ENTRY("gesundheitdemo", "gesundheit.exe", "5554b9e0df6241d25c9a070708e54478", 49666357), + ENGLISH_ENTRY("getawayfrompluto", "Get away.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 755529), + ENGLISH_ENTRY("getfood", "getfood.exe", "495d45fb8adfd49690ae3b97921feec6", 10600153), + ENGLISH_ENTRY("ghostdream", "Ghostdream.exe", "05594881531d62e4575545f3c8fd2576", 225600520), + ENGLISH_ENTRY("ghosting", "Shawshank.exe", "9cb3c8dc7a8ab9c44815955696be2677", 2968469), + ENGLISH_ENTRY("ghostvoyage", "Ghost Voyage.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 7870814), + ENGLISH_ENTRY("glitchquest", "glitchquest.exe", "465f972675db2da6040518221af5b0ba", 3182715), + ENGLISH_ENTRY("glitchquestnofun", "GQnofun.exe", "465f972675db2da6040518221af5b0ba", 3181931), + ENGLISH_ENTRY("gnomeshomebrewingadventure", "gnomebrew.exe", "abb3aee32ae97a8475626cceefb0664e", 50307521), + ENGLISH_ENTRY("gnrblexags", "Gnrblex_AGS.exe", "476a1a39d43ea27577eacf907173e2c1", 85038656), + ENGLISH_ENTRY("goneboatfishin", "Gone Boat Fishin'.exe", "bdd1df0484e296faa348ffcb03e16273", 72936045), + ENGLISH_ENTRY("goodmorningmrgingerbread", "mister_gingerbread.exe", "b42f80733b6bd1ded5e29be2c683afa8", 7084332), + ENGLISH_ENTRY("goodsantabadsanta", "X-Mags.exe", "71ca0d6c1c699595f28a2125948d4a84", 1966547), + ENGLISH_ENTRY("gotalight", "gotalight.exe", "daa21f03e41b5d3e7fd7558be3f8616e", 4019593), + ENGLISH_ENTRY("gpslostadventure", "G.P.s Lost Adventure [Wells8892].exe", "06a03fe35791b0578068ab1873455463", 4181945), + ENGLISH_ENTRY("graveyard", "Graveyard.exe", "955b711b21d7a2df6af1bb0cccccbb08", 13699789), + ENGLISH_ENTRY("gremlin", "Gremlin.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3962167), + ENGLISH_ENTRY("grizzlygooseofgosse", "Goose Fear.exe", "b69b5887e4a33a3b8588d52fed04b730", 32123559), + ENGLISH_ENTRY("grr", "Grr!.exe", "3128b9f90e2f954ba704414ae854d10b", 26753739), + ENGLISH_ENTRY("guardiansofgold", "Guardians of Gold.exe", "933200c8f306eccaaa484b1575da8528", 429166629), + ENGLISH_ENTRY("guyslug", "GuySlug.exe", "0710e2ec71042617f565c01824f0cf3c", 1959514), + ENGLISH_ENTRY("guyverquestiicronos", "Guyver Quest 2.exe", "465f972675db2da6040518221af5b0ba", 1138940), + ENGLISH_ENTRY("guyverquestishoadventure", "Guyver Quest.exe", "465f972675db2da6040518221af5b0ba", 774591), + ENGLISH_ENTRY("gville1", "GVILLE1.exe", "c1451c6631e1bf4de6d1ed3760ca1dc9", 2340624), + ENGLISH_ENTRY("hack", "Hack.exe", "f120690b506dd63cd7d1112ea6af2f77", 4384638), + ENGLISH_ENTRY("halloween", "Halloween.exe", "3128b9f90e2f954ba704414ae854d10b", 5130336), + ENGLISH_ENTRY("halloweenhorror", "Halloween.exe", "06a03fe35791b0578068ab1873455463", 33740975), + ENGLISH_ENTRY("hallwayofadventures", "Hallway.exe", "0710e2ec71042617f565c01824f0cf3c", 7085407), + ENGLISH_ENTRY("hangon", "HangOn.exe", "6e861b1f476ff7cdf036082abb271329", 4203208), + ENGLISH_ENTRY("hansenhotel", "Hotel.exe", "3128b9f90e2f954ba704414ae854d10b", 4006863), + ENGLISH_ENTRY("happyduckieadventure", "HDA.exe", "f120690b506dd63cd7d1112ea6af2f77", 1924654), + ENGLISH_ENTRY("hardspaceconquestofthegayliks", "Hard Space!.exe", "3ecd04c0e0df079ff906ec4696d5fe23", 11494382), + ENGLISH_ENTRY("harrys21stbirthday", "harold.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 3525444), + ENGLISH_ENTRY("haventhesmallworld", "A small world.exe", "b142b43c146c25443a1d155d441a6a81", 43019171), + ENGLISH_ENTRY("heartlanddeluxever11", "Heartland.exe", "0829f8e184ed6a4bf36b14ba42003a67", 6702004), + ENGLISH_ENTRY("heartlandver12", "Heartland V1.2.exe", "261d108f9213356a351b35b54867f342", 21237374), + ENGLISH_ENTRY("heavymetalnannulfthestrangestage", "NannulfMAGS.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 21272417), + ENGLISH_ENTRY("heed", "Heed.exe", "e8b2a430042709f07183c2c249e0e0d9", 6300045), + ENGLISH_ENTRY("helpthegame", "HELP.exe", "06a03fe35791b0578068ab1873455463", 3686323), + ENGLISH_ENTRY("henkstroemlostincellar", "Henk_LIC.exe", "3128b9f90e2f954ba704414ae854d10b", 1391240), + ENGLISH_ENTRY("henman", "hen-man.exe", "615e73fc1874e92d60a1996c2330ea36", 19556067), + ENGLISH_ENTRY("hesgonehistorical", "His.exe", "465f972675db2da6040518221af5b0ba", 5768754), + ENGLISH_ENTRY("hhgtgtowelday", "TowelDay.exe", "18456f28d9bf843b087e80072c85beca", 5431338), + ENGLISH_ENTRY("hiddenplains", "eureka02.exe", "6afafd26476d17a5e2a8e41f690d3720", 384360829), + ENGLISH_ENTRY("hiddentreasureryansfortune", "HiddenTRF.exe", "504df40bf50a0859e3dc15b000dab5f6", 7345149), + ENGLISH_ENTRY("hide", "Hide.exe", "6e861b1f476ff7cdf036082abb271329", 13701886), + ENGLISH_ENTRY("hiliaderoleagainsthell", "Dark Trial demo.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 36442694), + ENGLISH_ENTRY("him", "twin.exe", "6b4ceb9e327ac99479c08d825461f4cb", 23721672), + ENGLISH_ENTRY("hitchhikersguidetothegalaxyremake", "HHGTG.exe", "e003041f4332f136920e636e39d3e127", 34956191), + ENGLISH_ENTRY("hitthefreak", "HTF.EXE", "f3a13b2d6c2e0fe04c6f466062920e23", 3103477), + ENGLISH_ENTRY("hlobb", "Boxing.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 9544151), + ENGLISH_ENTRY("hood", "hood.exe", "97d700529f5cc826f230c27acf81adfd", 1575198), + ENGLISH_ENTRY("hope", "Hope.exe", "f92eba780bd1177612e264263d34c555", 4195489), + ENGLISH_ENTRY("horseparkdeluxe", "Horse Park DeLuxe.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 22491099), + ENGLISH_ENTRY("hotel", "Hotel.exe", "615e73fc1874e92d60a1996c2330ea36", 29586297), + ENGLISH_ENTRY("hotelhijinks", "HH.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1490538), + ENGLISH_ENTRY("houseofhorror", "The House of Horror.exe", "c20fee88ad37d2d21837eee9d34f2dbe", 10120651), + ENGLISH_ENTRY("howmany", "How many.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 5925931), + ENGLISH_ENTRY("howtheyfoundsilence", "How They Found Silence.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 5322796), + ENGLISH_ENTRY("huongjiaoping", "hotpot.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 47237302), + ENGLISH_ENTRY("huxzadventure", "Huxsadv.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 2053897), + ENGLISH_ENTRY("hydeandseek", "Hyde and Seek.exe", "c2f495a688dc19e66362657dee9aa895", 28066547), + ENGLISH_ENTRY("iaman00b11omgwtflol", "DadGame.exe", "3018c5443291aec823bc63342ce4c58b", 6073887), + ENGLISH_ENTRY("iamjason", "IAMJASON.exe", "e8985d9ffbfa1eda77f2eb8d1331944a", 4843842), + ENGLISH_ENTRY("iforgot", "Forgot.exe", "6aa30185326552359c7865e55c045a74", 7743871), + ENGLISH_ENTRY("igs", "IGS.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 1204802), + ENGLISH_ENTRY("iiispy", "IIISpy.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 6696286), + ENGLISH_ENTRY("illuminationdiminishing", "IlluminationDiminishing.exe", "b142b43c146c25443a1d155d441a6a81", 49006319), + ENGLISH_ENTRY("illuminationdiminishing", "IlluminationDiminishing.exe", "b142b43c146c25443a1d155d441a6a81", 21227029), + ENGLISH_ENTRY("illuminationdiminishing", "IlluminationDiminishing.exe", "b142b43c146c25443a1d155d441a6a81", 49006279), + ENGLISH_ENTRY("imnotcrazyrightthecell", "I'm not crazy.exe", "9cb3c8dc7a8ab9c44815955696be2677", 3152216), + ENGLISH_ENTRY("imnotcrazyrightthewell", "The Well.exe", "9cb3c8dc7a8ab9c44815955696be2677", 5000358), + ENGLISH_ENTRY("indianajonescomingofage", "IndyCOA.exe", "90413e9ae57e222f8913b09d2bc847bc", 2368083), + ENGLISH_ENTRY("indycositalianver", "CoSdemo2.1-it.exe", "f120690b506dd63cd7d1112ea6af2f77", 5772985), + ENGLISH_ENTRY("infectionepii", "Infection_Ep_II_AGS.exe", "a524cbb1c51589903c4043b98917f1d9", 23691417), + ENGLISH_ENTRY("infectionitheship", "Infection I.exe", "7132ff7d6b0bc1e9f3e4bd4755390626", 25974295), + ENGLISH_ENTRY("inferno", "inf.exe", "97d700529f5cc826f230c27acf81adfd", 8783105), + ENGLISH_ENTRY("infinitemonkeys", "InfiniteMonkeys.exe", "4d7d2addcde045dae6e0363a43f9acad", 4841557), + ENGLISH_ENTRY("insidemonkeyisland", "MIIM.exe", "06a03fe35791b0578068ab1873455463", 5186306), + ENGLISH_ENTRY("insidemonkeyisland2cap", "MIIM2.exe", "06a03fe35791b0578068ab1873455463", 5885525), + ENGLISH_ENTRY("inspectorgismoe", "police.exe", "465f972675db2da6040518221af5b0ba", 2899579), + ENGLISH_ENTRY("integerbattleship", "intbattl.exe", "0500aacb6c176d47ac0f8158f055db83", 4158273), + ENGLISH_ENTRY("intergalacticspacepancake", "space.exe", "97d700529f5cc826f230c27acf81adfd", 1797309), + ENGLISH_ENTRY("intothelight", "ITL.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12146182), + ENGLISH_ENTRY("invincibleisland", "Invincible.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4218160), + ENGLISH_ENTRY("isnkill", "ISN.exe", "4d17844029d8910fbaae1bdc99e250f2", 7932669), + ENGLISH_ENTRY("isos", "ISOS.exe", "06a03fe35791b0578068ab1873455463", 7362937), + ENGLISH_ENTRY("itsabugslife", "It's a Bugs Life.exe", "c48d0beedcdc1b05e9e25dcd60de46a9", 201172081), + ENGLISH_ENTRY("iwalkedapath", "I walked a path.exe", "fd3ecd8289bebadbf775fe8a13b9c5d7", 89018261), + ENGLISH_ENTRY("iwantout", "I_want_out!.exe", "c2cb8ff1ad3028b08fd3dab91578b934", 22218677), + ENGLISH_ENTRY("iwwhiiwwhitomirotpgthegame", "IWWHIIWWHITOMIROTPG - The Game.exe", "5fd79c32d2b8bbd589f6254d611d2742", 3576019), + ENGLISH_ENTRY("jacob", "Jacob.exe", "90413e9ae57e222f8913b09d2bc847bc", 7101001), + ENGLISH_ENTRY("jacquelinewhitecurseofthemummies", "CurseOfTheMummies.exe", "e9bdea51db49da499c69e8c21a821a7f", 193723250), + ENGLISH_ENTRY("jamesbond", "platform2.exe", "949f7440e3692b7366c2029979dee9a0", 4467701), + ENGLISH_ENTRY("jamesinneverland", "JamesNeverland.exe", "06a03fe35791b0578068ab1873455463", 36488607), + ENGLISH_ENTRY("jamesperis", "James1.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 85631684), + ENGLISH_ENTRY("jamesperis2demo", "James2.exe", "06a03fe35791b0578068ab1873455463", 35766505), + ENGLISH_ENTRY("javelincatch", "JvlnCtch.exe", "3421b46ff95c5885603086c39a038a20", 1626263), + ENGLISH_ENTRY("jimmsquestiii", "JQ3.EXE", "0b7529a76f38283d6e850b8d56526fc1", 4930906), + ENGLISH_ENTRY("jimmysday", "jimmy.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 13419394), + ENGLISH_ENTRY("jimmythetroublemaker", "Jimmy The Troublemaker.exe", "25976a689b0f4d73eac69b1728377ecb", 200843118), + ENGLISH_ENTRY("joeshorriblehell", "Joe's Horrible Hell.exe", "cdcc787023c51c6fc9ffc17118f6adff", 61061393), + ENGLISH_ENTRY("joesmiserablelife", "Joe's Miserable Life.exe", "1b9f13d430bb15bf30d0fd044358db68", 36705304), + ENGLISH_ENTRY("johnharrissafrakincse", "totp.exe", "74dc062c5f68f3d70da911f2db5737b6", 36463878), + ENGLISH_ENTRY("johnjebediahgunelisoladisepheret", "JJG.exe", "a28cb95e1769ba1bfa48f850390746c2", 88957123), + ENGLISH_ENTRY("johnnyrocket", "Rocket.exe", "a524cbb1c51589903c4043b98917f1d9", 10366294), + ENGLISH_ENTRY("johnsinclairvoodooinlondon", "John Sinclair - Voodoo in London.exe", "d72e72697a755c7de395b0f6c8cbbf0d", 56795991), + ENGLISH_ENTRY("jonnysmallvalley", "Jonny Smallvalley.exe", "01d0e6bd812abaa307bcb10fc2193416", 34437869), + ENGLISH_ENTRY("jorry", "JORRY DEMO.exe", "fe5f7dc7785b335aec72a2a834629bad", 124667001), + ENGLISH_ENTRY("juliusdangerous2", "Julius Dangerous 2.exe", "e2d4a98de69b1f8e6462c387710a441a", 146931732), + ENGLISH_ENTRY("juliusdangerousandthespaceinvaders", "Julius Dangerous.exe", "ddaf3807f1fe16b2813ff832b4fb471a", 83137140), + ENGLISH_ENTRY("justanotherpointnclickadventure", "Advent.exe", "6a98b4cc2f5a55421248be53f15a6a99", 9582620), + ENGLISH_ENTRY("justignorethem", "justignorethem.exe", "7a3096ac0237cb6aa8e1718e28caf039", 98544330), + ENGLISH_ENTRY("kanjigakusei", "KanjiGakusei.exe", "c1bce0ccfa858f0f5d2fe19997d89b05", 17604764), + ENGLISH_ENTRY("kartquestv053", "Kart.exe", "465f972675db2da6040518221af5b0ba", 77317312), + ENGLISH_ENTRY("keptoshi", "Keptosh.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 2904848), + ENGLISH_ENTRY("keys", "Keys.exe", "75f4c7f66b1be60af5b2d65f617b91a7", 85582285), + ENGLISH_ENTRY("killereye", "killereye.exe", "0710e2ec71042617f565c01824f0cf3c", 1009042), + ENGLISH_ENTRY("killjoseda", "KillJD.exe", "20dc02a8f977caf5c4dc6f2a4c8d4378", 6034414), + ENGLISH_ENTRY("killthelights", "Kill The Lights.exe", "9b54ea3557373188d8388ec4d1ae5eed", 20416736), + ENGLISH_ENTRY("kingdomlegends", "Kingdom Legends.exe", "06a03fe35791b0578068ab1873455463", 2254139), + ENGLISH_ENTRY("kingsquestiii", "KQ3.exe", "f120690b506dd63cd7d1112ea6af2f77", 5883843), + ENGLISH_ENTRY("kinkyislanddemo", "KINKY.exe", "f120690b506dd63cd7d1112ea6af2f77", 10628479), + ENGLISH_ENTRY("knightquestforgoldenring", "KQuestGoldRing.exe", "f120690b506dd63cd7d1112ea6af2f77", 2582542), + ENGLISH_ENTRY("knightsquestiii", "KQ3TOM.exe", "0710e2ec71042617f565c01824f0cf3c", 8408641), + ENGLISH_ENTRY("knightsquestiv", "MAGSQuest.exe", "0500aacb6c176d47ac0f8158f055db83", 4074151), + ENGLISH_ENTRY("koddurova", "Kod Durova.exe", "615e73fc1874e92d60a1996c2330ea36", 498427333), + ENGLISH_ENTRY("koffeekrisis", "Koffee Krisis.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 2423111), + ENGLISH_ENTRY("koscheitheimmortal", "Koschei.exe", "465f972675db2da6040518221af5b0ba", 2771442), + ENGLISH_ENTRY("kristmaskrisis", "Kristmas Krisis.exe", "90413e9ae57e222f8913b09d2bc847bc", 2067681), + ENGLISH_ENTRY("ktx1", "KTX-1.exe", "615e73fc1874e92d60a1996c2330ea36", 13806290), + ENGLISH_ENTRY("kumastory", "Kuma Story.exe", "54e966a013d104bf23603c780438d089", 2893472), + ENGLISH_ENTRY("labor", "LaborEN.exe", "b9fcd61691d19d954a5cfd5fb57a6b45", 7245344), + ENGLISH_ENTRY("labratescape", "Joel.exe", "06a03fe35791b0578068ab1873455463", 3256136), + ENGLISH_ENTRY("labyrinth", "labyrnth.exe", "0710e2ec71042617f565c01824f0cf3c", 7686481), + ENGLISH_ENTRY("lacicuta1", "Cicuta1.exe", "1290e191d4f24893ce83ba0af5debd9e", 8665956), + ENGLISH_ENTRY("lacroixpan", "La Croix Pan.exe", "d9018b1792f6d959d7add4dc3f7cdb46", 12102643), + ENGLISH_ENTRY("laffaireaspirox", "L'Affaire Aspirox.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 139865345), + ENGLISH_ENTRY("lagrancastanya", "PROJECT1.exe", "c87aa6377abc18c1a1b2968ae6db08eb", 39298012), + ENGLISH_ENTRY("lallaveyfabianshones", "LLAVE.exe", "a8d73d686b2eb77caab8c05e3e1f1d57", 3374527), + ENGLISH_ENTRY("laodiseadelfracasoii", "La Odisea II.exe", "0710e2ec71042617f565c01824f0cf3c", 3083622), + ENGLISH_ENTRY("laportenoire", "proute.exe", "06a03fe35791b0578068ab1873455463", 17087125), + ENGLISH_ENTRY("lastnfurious", "Last'n'Furious.exe", "3569271305cddb7156260cce9439e543", 17696093), + ENGLISH_ENTRY("laundryday", "Laundry Day.exe", "06a03fe35791b0578068ab1873455463", 2456888), + ENGLISH_ENTRY("lavablava", "Rumble.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2294674), + ENGLISH_ENTRY("lazaruswantspants", "pants.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1311852), + ENGLISH_ENTRY("lazytownthenewkiddemo", "newkiddemo1.2.exe", "9cb3c8dc7a8ab9c44815955696be2677", 15515508), + ENGLISH_ENTRY("lbstoryofcedrickdusce", "lifeboat.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 3563681), + ENGLISH_ENTRY("legendofrovendale", "Vampire.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 10018497), + ENGLISH_ENTRY("legendofseththebard", "LOSTB 1.48.exe", "a524cbb1c51589903c4043b98917f1d9", 10669482), + ENGLISH_ENTRY("legendsofmardaram", "LOM.exe", "0710e2ec71042617f565c01824f0cf3c", 50183544), + ENGLISH_ENTRY("leisuresuitlarry2", "Larry 2.exe", "949f7440e3692b7366c2029979dee9a0", 11971760), + ENGLISH_ENTRY("leisuresuitlarrylil", "LSL.exe", "34cf71d28e1e9c55934f624969011c7e", 18440862), + ENGLISH_ENTRY("lesmiserables", "Les Miserables.exe", "0514661a4ba6772cf0db0cf839fc7003", 127582664), + ENGLISH_ENTRY("lessurvivants", "Les_Survivants.exe", "c5d2c54c20cb606519b86d3890ee7fc0", 265445972), + ENGLISH_ENTRY("lichdomwheresdidiputthat", "Lichdom.exe", "0e6ae2b49c1a38363a77024f3ce31771", 7412719), + ENGLISH_ENTRY("life", "Life.exe", "97a2a2feb82708da8f6ed30c15a7eb53", 43833851), + ENGLISH_ENTRY("lifeboatstoryofcedrick", "lifeboat.exe", "3128b9f90e2f954ba704414ae854d10b", 2952689), + ENGLISH_ENTRY("lifeofdduck", "D Duck.exe", "0710e2ec71042617f565c01824f0cf3c", 49461615), + ENGLISH_ENTRY("lifeofdduckii", "D. Duck II.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 135923689), + ENGLISH_ENTRY("liftreasureofthetanones", "Lif.exe", "18b284c22010850f79bc5c20054a70c4", 3946641), + ENGLISH_ENTRY("lightcycles", "LightCycles.exe", "495d45fb8adfd49690ae3b97921feec6", 3415108), + ENGLISH_ENTRY("lightningmaster", "Master.exe", "27343924ddad3be0b97bdcaa71858b1b", 231301393), + ENGLISH_ENTRY("likeafox", "likeafox.exe", "c7916b82f00c94013a3f7706b4d333c6", 2707737), + ENGLISH_ENTRY("limbo", "Limbo Adventure.exe", "7c10efb8990fb48ded51fbcd88a6bf17", 30800724), + ENGLISH_ENTRY("limeylizardwastewizard", "LLWW.exe", "fab982fd31570655ac3b1858bd8265e4", 33755872), + ENGLISH_ENTRY("litnunforgettablememories", "litn_umtechdemo.exe", "f120690b506dd63cd7d1112ea6af2f77", 3507831), + ENGLISH_ENTRY("littlegirlinunderland", "Underland.exe", "06a03fe35791b0578068ab1873455463", 10125940), + ENGLISH_ENTRY("livingnightmaredeluxe", "Living Nightmare.exe", "4415d633ea1a2dcd03ff0eff43f182ee", 9997554), + ENGLISH_ENTRY("livingnightmareendlessdream", "LNED.exe", "4415d633ea1a2dcd03ff0eff43f182ee", 10671309), + ENGLISH_ENTRY("livingnightmarefreedom", "LNF.exe", "6aa30185326552359c7865e55c045a74", 26580184), + ENGLISH_ENTRY("lockedout", "locked-out.exe", "465f972675db2da6040518221af5b0ba", 1930862), + ENGLISH_ENTRY("loftusandtheskycap", "loftus.exe", "4c83816b87e6e253dc8e324e89bcbca3", 24333349), + ENGLISH_ENTRY("lonecase", "LoneCase.exe", "8661936f40669fa1672dced4df0521a0", 3550717), + ENGLISH_ENTRY("lonecase2", "Lone Case 2.exe", "cb3bbab6e565fcbd57af8f33a8609210", 6015178), + ENGLISH_ENTRY("lonecase3showdown", "lc 3.exe", "893df6568c294926f7efa3f3ec2ce14d", 7997004), + ENGLISH_ENTRY("lonelynight", "Lonely night.exe", "0710e2ec71042617f565c01824f0cf3c", 2488077), + ENGLISH_ENTRY("longexpectedfriday", "LEFRIDAY.exe", "28f82e420b82d07651b68114f90223c8", 7595812), + ENGLISH_ENTRY("lonkeyisland", "lonkey.exe", "4e92c6db88a34b62eef37a621aabfb53", 44134488), + ENGLISH_ENTRY("loomiireturnoftheswans", "loom2.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 9761097), + ENGLISH_ENTRY("losjovenesdelaguerra", "guerra.exe", "97d700529f5cc826f230c27acf81adfd", 4286035), + ENGLISH_ENTRY("lostanswers", "Lost Answers.exe", "c88de182eae58fdb43e5b4e587095ff5", 254684884), + ENGLISH_ENTRY("lostinparadise", "2paradise.exe", "06a03fe35791b0578068ab1873455463", 37279978), + ENGLISH_ENTRY("lostinthenightmare", "litn.exe", "0710e2ec71042617f565c01824f0cf3c", 5492994), + ENGLISH_ENTRY("lostinthenightmare", "litn.exe", "0710e2ec71042617f565c01824f0cf3c", 5493239), + ENGLISH_ENTRY("lostinthewoods", "LITW.exe", "00328f4f1e7729144483107b96b11df8", 55203461), + ENGLISH_ENTRY("lucidlucy", "LUCID LUCY.exe", "655363c390c7ae7225c237108edf50b7", 182038828), + ENGLISH_ENTRY("lucylavender", "Lucy.exe", "c87aa6377abc18c1a1b2968ae6db08eb", 7944054), + ENGLISH_ENTRY("lukesexistentialnightmare", "Lukeexit.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 653834), + ENGLISH_ENTRY("lunarlanderprototype", "LunarLanderPrototype.exe", "495d45fb8adfd49690ae3b97921feec6", 3510282), + ENGLISH_ENTRY("lydiaandthemysteryofnellrenomanor", "LydiaW.exe", "615e73fc1874e92d60a1996c2330ea36", 33971307), + ENGLISH_ENTRY("maggieandmax", "Max.exe", "465f972675db2da6040518221af5b0ba", 5759981), + ENGLISH_ENTRY("magic8ball", "Magic-8-Ball.exe", "82da2565c456dcfb265ded6fe3189c0b", 4233735), + ENGLISH_ENTRY("magicalwhatevergirlrocksoutinthestoneage", "mwg.exe", "b2b99b5b3dcaee0fa292343c5a2c429b", 7784104), + ENGLISH_ENTRY("magicballoffortune", "Magic Ball.exe", "f120690b506dd63cd7d1112ea6af2f77", 6016698), + ENGLISH_ENTRY("magnumpm", "Magnum, P.M.exe", "06a03fe35791b0578068ab1873455463", 91711892), + ENGLISH_ENTRY("magsgame", "MAGSGAME.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 5025809), + ENGLISH_ENTRY("magsic", "Magsic.exe", "7a436b9a2e8e80c8aaaeed09ef9e3d3d", 22360144), + ENGLISH_ENTRY("magsicii", "MagsicII.exe", "28f82e420b82d07651b68114f90223c8", 30029761), + ENGLISH_ENTRY("magsjan", "MAGS-Jan.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 16729569), + ENGLISH_ENTRY("magsjune2017", "MAGS june 2017.exe", "e3962995a70923a8d5a8f1cf8f932eee", 304129558), + ENGLISH_ENTRY("magssep2007", "MAGS Sep 2007.exe", "f120690b506dd63cd7d1112ea6af2f77", 6007305), + ENGLISH_ENTRY("manboy", "Man Boy.exe", "1275885401b7d2ece491e704535707d9", 3038532), + ENGLISH_ENTRY("maniacmansiondeluxe", "Maniac.exe", "465f972675db2da6040518221af5b0ba", 10409172), + ENGLISH_ENTRY("maniacmansionmania", "MMM.exe", "465f972675db2da6040518221af5b0ba", 5476481), + ENGLISH_ENTRY("maniacmansionmania02", "MMM02.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 5830457), + ENGLISH_ENTRY("mardsrevengebytk", "MPLR.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 1771793), + ENGLISH_ENTRY("martyausdemall", "test3.exe", "0710e2ec71042617f565c01824f0cf3c", 4352013), + ENGLISH_ENTRY("mastersofsound", "MOS.exe", "bb59de174d70797d774dec76a171352d", 20298343), + ENGLISH_ENTRY("matttothefuture", "MTTF.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 5560975), + ENGLISH_ENTRY("medicaltheoriesofdrkur", "dfg.exe", "465f972675db2da6040518221af5b0ba", 3140527), + ENGLISH_ENTRY("mego2008silvesteredition", "Me Go Store III.exe", "06a03fe35791b0578068ab1873455463", 12040937), + ENGLISH_ENTRY("megoaway", "Me Go Store II.exe", "06a03fe35791b0578068ab1873455463", 6640781), + ENGLISH_ENTRY("megocannibaljungle", "mgcj.exe", "06a03fe35791b0578068ab1873455463", 7127871), + ENGLISH_ENTRY("megostore", "Me Go Store.exe", "90413e9ae57e222f8913b09d2bc847bc", 2961962), + ENGLISH_ENTRY("melrinthediscipleordeal", "Melrin.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 12822475), + ENGLISH_ENTRY("melrinthedragonmenace", "Melrin3.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 5802221), + ENGLISH_ENTRY("melrinthependantquest", "Melrin2.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 4372768), + ENGLISH_ENTRY("meltdrake3chapter1", "CaK3.exe", "97d700529f5cc826f230c27acf81adfd", 6044911), + ENGLISH_ENTRY("memoriesfade", "MemoriesFade.exe", "d5d028212a242a9841feff24ec3db3c9", 7996519), + ENGLISH_ENTRY("meninhats", "GAME.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1646510), + ENGLISH_ENTRY("merrychristmas", "Merry Christmas.exe", "172b30c282856b382464bed5fcb61e29", 4812266), + ENGLISH_ENTRY("messedupmothergoosedeluxemyassenhanced", "MMG.exe", "d642f2110a3dc0c48ab7b13f69b5caf6", 36523450), + ENGLISH_ENTRY("meta", "META.exe", "06a03fe35791b0578068ab1873455463", 10113135), + ENGLISH_ENTRY("meteorfamily20", "Meteor Family.exe", "06a03fe35791b0578068ab1873455463", 5759077), + ENGLISH_ENTRY("meteorheadrecycled", "Meteorhead.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 5081311), + ENGLISH_ENTRY("mi5thereturnoflechuck", "Demo.exe", "0500aacb6c176d47ac0f8158f055db83", 6235270), + ENGLISH_ENTRY("mibaddaytobedead", "Monkey.exe", "f120690b506dd63cd7d1112ea6af2f77", 2117238), + ENGLISH_ENTRY("micarnivalofthedamned", "MI-COD.exe", "90413e9ae57e222f8913b09d2bc847bc", 5114086), + ENGLISH_ENTRY("mickeymauserpart1", "MM.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12076323), + ENGLISH_ENTRY("midastouch", "midastouch.exe", "6e861b1f476ff7cdf036082abb271329", 10810464), + ENGLISH_ENTRY("mikelechey", "Mike Lechey.exe", "06a03fe35791b0578068ab1873455463", 2349277), + ENGLISH_ENTRY("mikesroom2", "Mikes_late.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 5001254), + ENGLISH_ENTRY("milkshake", "Milkshake.exe", "615e806856b7730afadf1fea9a756b70", 1656268), + ENGLISH_ENTRY("mindboggler", "Rebel.exe", "847ca9d174cd091b7a1b82f032bdd052", 36979705), + ENGLISH_ENTRY("mindseye", "MindsEye.exe", "8a84eb07f484540ecc59ea80bf21dc9e", 30024175), + ENGLISH_ENTRY("minigame3", "Mini Game 3.exe", "465f972675db2da6040518221af5b0ba", 3455484), + ENGLISH_ENTRY("minigame4", "Mini Game 4.exe", "465f972675db2da6040518221af5b0ba", 4954264), + ENGLISH_ENTRY("missingsincemidnight", "msm.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7989479), + ENGLISH_ENTRY("mistdelaescueladearte", "EA.exe", "465f972675db2da6040518221af5b0ba", 6732362), + ENGLISH_ENTRY("mixertest", "mixertest.exe", "0b7529a76f38283d6e850b8d56526fc1", 798369), + ENGLISH_ENTRY("mmm15ortmaschine", "MMM15.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 8957215), + ENGLISH_ENTRY("mmm4mimikryderemotionen", "mmm.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 8368739), + ENGLISH_ENTRY("mmmderklausschlgtzurck", "MMM-dksz.exe", "c1df737ef943e6e3cc09d36fcd4b1ed0", 8689677), + ENGLISH_ENTRY("mmmepisode8", "MMM - E8.exe", "45ab4f29031b50c8d01d10a269f77ff5", 5095385), + ENGLISH_ENTRY("mmmradioaktiv", "mmm_radioactive.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7665414), + ENGLISH_ENTRY("moncul", "moncul.exe", "0710e2ec71042617f565c01824f0cf3c", 1493822), + ENGLISH_ENTRY("monkeystothemoon", "Monkeys to the Moon.exe", "77d91b65ff03c1f3a8381e39c7f693cb", 8720439), + ENGLISH_ENTRY("monkeywrench", "monkeywrench.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 27454116), + ENGLISH_ENTRY("monsterfromthehountedhill", "Monster.exe", "465f972675db2da6040518221af5b0ba", 6197451), + ENGLISH_ENTRY("moonlightmoggy", "Moggy.exe", "0a6704159f6f716ac80da91c430430ce", 13336128), + ENGLISH_ENTRY("moose", "MOOSE.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 4732219), + ENGLISH_ENTRY("moose2", "MOOSE2.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 1251361), + ENGLISH_ENTRY("mordimlaufrad", "MordImLaufrad.exe", "18b284c22010850f79bc5c20054a70c4", 4396809), + ENGLISH_ENTRY("mordy2", "Mordy2.exe", "0710e2ec71042617f565c01824f0cf3c", 5186329), + ENGLISH_ENTRY("mothersday", "mothersday.exe", "0b7529a76f38283d6e850b8d56526fc1", 1816363), + ENGLISH_ENTRY("motlpaa", "MOTLPAA.exe", "0710e2ec71042617f565c01824f0cf3c", 1575258), + ENGLISH_ENTRY("mourirenmer", "Mourir.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 2519706), + ENGLISH_ENTRY("mrbee", "BEE.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 45542087), + ENGLISH_ENTRY("mrdangerscontest", "Danger.exe", "06a03fe35791b0578068ab1873455463", 7096987), + ENGLISH_ENTRY("murderinthemansion", "MitM 1.2.exe", "27df05bd72589a589c054d11d6d03c0f", 9758713), + ENGLISH_ENTRY("murderofadrianelkwood", "elkwood.exe", "06a03fe35791b0578068ab1873455463", 3685153), + ENGLISH_ENTRY("murphyssalvagejustmyluck", "space.exe", "f8029b1e9ff5ac01ae23896af44e885a", 51351465), + ENGLISH_ENTRY("murranchronicles1", "Jersey Devil.exe", "06a03fe35791b0578068ab1873455463", 20555872), + ENGLISH_ENTRY("murranchronicles2", "Talons.exe", "06a03fe35791b0578068ab1873455463", 17613066), + ENGLISH_ENTRY("mysterioushouse", "mh.exe", "495d45fb8adfd49690ae3b97921feec6", 42400316), + ENGLISH_ENTRY("mysticseer", "NickOfTime.exe", "f120690b506dd63cd7d1112ea6af2f77", 4460113), + ENGLISH_ENTRY("mythicalgambitflawlessfatality", "MGFF.exe", "4887d3dca056a0772741b42f66e018fb", 59711760), + ENGLISH_ENTRY("nanobots", "Nanobots.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 41977727), + ENGLISH_ENTRY("necroquest", "necroquest01.exe", "6d4adcef07a14b53369d23edf5117252", 12389204), + ENGLISH_ENTRY("necroquest", "necroquest01.exe", "2d111a69de0723f337bad661cb006239", 9545924), + ENGLISH_ENTRY("nedysadventure", "Nedy.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 6463558), + ENGLISH_ENTRY("nekusnewtrip", "nnt.exe", "c0c1865c3c8369e034095a725ca1ddbf", 35012412), + ENGLISH_ENTRY("nekusnewtrip", "square enix.exe", "a524cbb1c51589903c4043b98917f1d9", 10630694), + ENGLISH_ENTRY("newgame", "Newgame.exe", "0b7529a76f38283d6e850b8d56526fc1", 1453831), + ENGLISH_ENTRY("nellycootalotv15", "Nelly Cootalot.exe", "18b284c22010850f79bc5c20054a70c4", 108256323), + ENGLISH_ENTRY("neofeud", "Neofeud Demo.exe", "6e861b1f476ff7cdf036082abb271329", 1886913453), + ENGLISH_ENTRY("nesquest", "NES Quest.exe", "8b72036706da98095057df615d07460b", 20881972), + ENGLISH_ENTRY("news", "WI-AA.exe", "06a03fe35791b0578068ab1873455463", 29631312), + ENGLISH_ENTRY("nickitandrun", "NIAREnglish.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 14180082), + ENGLISH_ENTRY("nightoftheravingfeminist", "Prueba1.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 7015243), + ENGLISH_ENTRY("nightwork", "Nightwork.exe", "f10516e88ec858700804ee69d041aead", 23059420), + ENGLISH_ENTRY("noactionjackson", "current.exe", "3128b9f90e2f954ba704414ae854d10b", 28343366), + ENGLISH_ENTRY("noahsquest", "Noah's Quest.exe", "c48d0beedcdc1b05e9e25dcd60de46a9", 107188362), + ENGLISH_ENTRY("nobodycares", "Nobody Cares.exe", "618d7dce9631229b4579340b964c6810", 20897642), + ENGLISH_ENTRY("noiamspartacus", "spartacus.exe", "28f82e420b82d07651b68114f90223c8", 1133879), + ENGLISH_ENTRY("noisymountain", "NoisyMountainE.exe", "465f972675db2da6040518221af5b0ba", 8031142), + ENGLISH_ENTRY("nomonkeysbanana", "NMB.exe", "36f44e064eab15e502caeb60fd09f52d", 2750366), + ENGLISH_ENTRY("norbisquest", "Norbi's quest.exe", "3128b9f90e2f954ba704414ae854d10b", 4912333), + ENGLISH_ENTRY("norbisquest15", "Norbi 1,5.exe", "f120690b506dd63cd7d1112ea6af2f77", 5455598), + ENGLISH_ENTRY("norbisquest2", "Norbi 2.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 14114728), + ENGLISH_ENTRY("norbiwinterspecial", "NWS.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 10149860), + ENGLISH_ENTRY("normancooks", "NORMAN.exe", "4d17844029d8910fbaae1bdc99e250f2", 9397734), + ENGLISH_ENTRY("norserunereader", "NorseRuneReader.exe", "f120690b506dd63cd7d1112ea6af2f77", 2111273), + ENGLISH_ENTRY("noughtscrosses", "Noughts.exe", "615e73fc1874e92d60a1996c2330ea36", 2159904), + ENGLISH_ENTRY("oceanspiritdennisscourgeoftheunderworld", "Oceanspirit Dennis.exe", "18456f28d9bf843b087e80072c85beca", 2419770), + ENGLISH_ENTRY("odottamaton", "Odottamaton.exe", "9d9e5ea323793fc526b1533d78c4f9c6", 23822268), + ENGLISH_ENTRY("omnipotenttarot", "OmnipotentTarot.exe", "f120690b506dd63cd7d1112ea6af2f77", 7166774), + ENGLISH_ENTRY("onceuponacrime13b", "OUAC.exe", "6ee842f73649ced615c44d4eb303687c", 6580658), + ENGLISH_ENTRY("onceuponatime", "Oncetime.exe", "18b284c22010850f79bc5c20054a70c4", 11633390), + ENGLISH_ENTRY("one", "one.exe", "0710e2ec71042617f565c01824f0cf3c", 53482630), + ENGLISH_ENTRY("oneofakindadivinecomedyofmistakes", "OneOfAKind.exe", "a524cbb1c51589903c4043b98917f1d9", 4031186), + ENGLISH_ENTRY("onespytoomany", "One spy too many.exe", "c48d0beedcdc1b05e9e25dcd60de46a9", 70521403), + ENGLISH_ENTRY("oneweekoneroom", "1 week 1 room.exe", "06a03fe35791b0578068ab1873455463", 4275934), + ENGLISH_ENTRY("onleavingthebuilding", "On Leaving The Building.exe", "fd68fced8b89792d2e90be87b33d4b19", 64776995), + ENGLISH_ENTRY("onlythegooddieyoungenglishversion", "OtGDY_En.exe", "87ccd318a469128530699388f916b86f", 153980124), + ENGLISH_ENTRY("openquest", "OpenQuest.exe", "90413e9ae57e222f8913b09d2bc847bc", 3407165), + ENGLISH_ENTRY("operationnovi", "Operation Novi.exe", "465f972675db2da6040518221af5b0ba", 24583968), + ENGLISH_ENTRY("operationsavebluecup", "OSBC.exe", "f120690b506dd63cd7d1112ea6af2f77", 3040865), + ENGLISH_ENTRY("orangeman", "Orange man.exe", "c38d6846c402bfcdedcf5c34cd8bc3ee", 1960932), + ENGLISH_ENTRY("orowgame", "orowgame.exe", "0710e2ec71042617f565c01824f0cf3c", 15632750), + ENGLISH_ENTRY("osdarayofhope", "ray_of_hope.exe", "25976a689b0f4d73eac69b1728377ecb", 6595789), + ENGLISH_ENTRY("osdocd", "OSD-OCD.exe", "9dbf699a0e41550bb080813a233e73a8", 47758168), + ENGLISH_ENTRY("osdthelostworldep2", "OSD.TLW2.exe", "a80ae4d0aea21508f1df9d18f2839bcb", 22076715), + ENGLISH_ENTRY("osher", "Osher.exe", "18b284c22010850f79bc5c20054a70c4", 389177994), + ENGLISH_ENTRY("otakurivals", "Kintaro.exe", "465f972675db2da6040518221af5b0ba", 4045893), + ENGLISH_ENTRY("otherworlds", "Other Worlds.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 10669659), + ENGLISH_ENTRY("otisbuildsafire", "obaf.exe", "c8d330b58da0a00a136c52ed3a20ae23", 4260705), + ENGLISH_ENTRY("ouja", "Ouja.exe", "4d7d2addcde045dae6e0363a43f9acad", 6254682), + ENGLISH_ENTRY("outbreakbyabhijitkamat", "outbreak.exe", "0500aacb6c176d47ac0f8158f055db83", 3271348), + ENGLISH_ENTRY("outofgas", "OutOfGas.exe", "6b4ceb9e327ac99479c08d825461f4cb", 18187986), + ENGLISH_ENTRY("outofgas", "OutOfGas.exe", "f0e74b3673867316e1cb3120c4289c66", 18200877), + ENGLISH_ENTRY("overtheedge", "jdags.exe", "05f7ff300b322bc431e7cda6a07b5976", 235453751), + ENGLISH_ENTRY("owlsquest", "King.exe", "a6906aec8617b81af44cf9420731fc34", 3506408), + ENGLISH_ENTRY("palettequest2", "PaletteQuest2.exe", "2b7ae26333ba15529a8bbbdb49605133", 771805), + ENGLISH_ENTRY("pandainspace", "pandasp.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 14340176), + ENGLISH_ENTRY("pandor", "Pandor.exe", "a6dc66da890952431371b62659e58a62", 18995824), + ENGLISH_ENTRY("paradiselost", "larywilc.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 9061068), + ENGLISH_ENTRY("parameciumcomplex", "paramaecium.exe", "0500aacb6c176d47ac0f8158f055db83", 2805720), + ENGLISH_ENTRY("paranormalwarriorwithin", "BJWW.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 3538617), + ENGLISH_ENTRY("party", "Party.exe", "f120690b506dd63cd7d1112ea6af2f77", 1888987), + ENGLISH_ENTRY("patchwork", "Patchwork.exe", "bbadca125279cb808b4ed0ff4b31448d", 110767860), + ENGLISH_ENTRY("paulaimwunderland", "PaulaWunderland.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 2249299), + ENGLISH_ENTRY("paulmooseinspaceworld", "Paul Moose In Space World.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 15971406), + ENGLISH_ENTRY("paulquest", "calle.exe", "06a03fe35791b0578068ab1873455463", 3055837), + ENGLISH_ENTRY("pennistheultimateinpong", "Pennis.exe", "28f82e420b82d07651b68114f90223c8", 939611), + ENGLISH_ENTRY("perilsofpoom", "Poom.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 10455126), + ENGLISH_ENTRY("pesterquest", "PQ.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 2381566), + ENGLISH_ENTRY("petalrose", "petalrose.exe", "949f7440e3692b7366c2029979dee9a0", 748315), + ENGLISH_ENTRY("pharmacistjones", "Pharmacist Jones.exe", "00bb363ccb0acfe57893dd3ba6f1719c", 8285817), + ENGLISH_ENTRY("pickpocketrpg", "Pickpocket RPG.exe", "82da2565c456dcfb265ded6fe3189c0b", 44540638), + ENGLISH_ENTRY("pilotlight", "Pilot.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 9707781), + ENGLISH_ENTRY("pimpinonparakuss", "Squest2.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 3717277), + ENGLISH_ENTRY("piratefry2", "FryTworedo.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 8492745), + ENGLISH_ENTRY("piratefry3", "tryout.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2318881), + ENGLISH_ENTRY("piratess", "Piratess.exe", "f120690b506dd63cd7d1112ea6af2f77", 2043871), + ENGLISH_ENTRY("pixelhunt", "pixelhunt.exe", "057d1aa29f6fadd83209268efcfb35a3", 3321338), + ENGLISH_ENTRY("pixia", "Pixia.exe", "0710e2ec71042617f565c01824f0cf3c", 1286189), + ENGLISH_ENTRY("pixxxelhuntertheepic", "pixelhunter.exe", "0710e2ec71042617f565c01824f0cf3c", 1621107), + ENGLISH_ENTRY("plan10frommypants", "plan10.exe", "06a03fe35791b0578068ab1873455463", 8514311), + ENGLISH_ENTRY("planetxmas", "PlanetX.exe", "64fcaf7da0b257ea831f89c54be0ad72", 4430665), + ENGLISH_ENTRY("platformerius", "platformerius.exe", "a3ad5fa6463c0116a2ac8986841860e0", 1512479), + ENGLISH_ENTRY("platformhorde", "Platform Horde.exe", "49157a0ea75b960eded4d0811a71d3e9", 14991450), + ENGLISH_ENTRY("pleurghburgdarkages", "Pleurgh.exe", "9cf51833e787cc919837d9a8bd8fc14c", 11555983), + ENGLISH_ENTRY("plumberboy", "Plumberboy.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 4169240), + ENGLISH_ENTRY("pm-cute", "pm-cute.exe", "28f82e420b82d07651b68114f90223c8", 2728354), + ENGLISH_ENTRY("pmuvchvt", "PMUVCHVT.exe", "06a03fe35791b0578068ab1873455463", 5127419), + ENGLISH_ENTRY("pmxi", "PMXI.exe", "609aa4339aea63a0ebc1fd6a659e6d4f", 3164504), + ENGLISH_ENTRY("pocketfluffyay", "Pketfluf.exe", "0b7529a76f38283d6e850b8d56526fc1", 10858438), + ENGLISH_ENTRY("politicallyyours", "Politically Yours.exe", "031bce0ec1a563faffc19a62ea17e35f", 4640266), + ENGLISH_ENTRY("pong", "Pong.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 611249), + ENGLISH_ENTRY("postmansquest", "PQ.exe", "345685aaec400c69a1e6d5e18a63850c", 6896450), + ENGLISH_ENTRY("powernap", "powernap.exe", "615e73fc1874e92d60a1996c2330ea36", 13308487), + ENGLISH_ENTRY("powerunlimited", "PU Bordspel.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1842762), + ENGLISH_ENTRY("pqtadventure", "playpqt.exe", "0b7529a76f38283d6e850b8d56526fc1", 19914806), + ENGLISH_ENTRY("practicescript", "Practice.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 764358), + ENGLISH_ENTRY("predatorspreyforplants", "Predators Prey For Plants.exe", "d44551532361c1eeec9b167de35515d1", 2318985), + ENGLISH_ENTRY("princessandallthekingdom", "Copy of PHK.exe", "465f972675db2da6040518221af5b0ba", 24658916), + ENGLISH_ENTRY("princessmarianix", "phantom.exe", "2a486107b3f04f789c122a1d0e1f3d5f", 2067548), + ENGLISH_ENTRY("princessmariansnowfight", "pmsnow.exe", "f120690b506dd63cd7d1112ea6af2f77", 1250562), + ENGLISH_ENTRY("princessmarianspigeonpinger", "PMPP.exe", "e68aaf0cea1e5701a7bb50a757bb5f4b", 2929950), + ENGLISH_ENTRY("princessmarianxmagichat", "pmx.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 3243258), + ENGLISH_ENTRY("principlesofevil", "P of E.exe", "f120690b506dd63cd7d1112ea6af2f77", 43410398), + ENGLISH_ENTRY("principlesofevilii", "PoE II.exe", "f120690b506dd63cd7d1112ea6af2f77", 87236507), + ENGLISH_ENTRY("prodigal", "Prodigal.exe", "682a8c57c7678c99c1564fd43680f03e", 7486947), + ENGLISH_ENTRY("profneely", "ProfN.exe", "26cfa7bd1be5485e1f0385101b31e43b", 31956037), + ENGLISH_ENTRY("projectevilspyii", "Project Evilspy II.exe", "0b7529a76f38283d6e850b8d56526fc1", 1583899), + ENGLISH_ENTRY("proofoffiction", "PoF.exe", "9cf51833e787cc919837d9a8bd8fc14c", 2723885), + ENGLISH_ENTRY("prototypical", "Proto.exe", "06a03fe35791b0578068ab1873455463", 48507319), + ENGLISH_ENTRY("proxecto", "proxec.exe", "465f972675db2da6040518221af5b0ba", 2636209), + ENGLISH_ENTRY("psychopomp", "psychopomp.exe", "b142b43c146c25443a1d155d441a6a81", 23721476), + ENGLISH_ENTRY("pubmasterquest2", "shogin crystal.exe", "90baefd2f369cebe25f3aa9ad90332d2", 35191110), + ENGLISH_ENTRY("pubmastersquest", "Pub Master Quest [Demo].exe", "e1676318c8a040fcf508b817013dc8fe", 23431689), + ENGLISH_ENTRY("puddypenguin", "Penguin.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2328158), + ENGLISH_ENTRY("pupupupulaisenseikkailut", "Pupupeli.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 13453697), + ENGLISH_ENTRY("pupupupulaisenseikkailut", "Game.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 13431315), + ENGLISH_ENTRY("purgatorio01", "Purgatorio 0.1.exe", "18b284c22010850f79bc5c20054a70c4", 194293367), + ENGLISH_ENTRY("purityofthesurf", "Surf.exe", "71ca0d6c1c699595f28a2125948d4a84", 11315703), + ENGLISH_ENTRY("puzzlebotsdemo", "Puzzlebots_Demo.exe", "34b49df9cf6eadb5c3587b3921d5b72f", 354138961), + ENGLISH_ENTRY("pxenophobe", "ProjXeno.exe", "465f972675db2da6040518221af5b0ba", 79053486), + ENGLISH_ENTRY("quantumnauts", "QNDEMO.exe", "aeb2dd29e5ff839cb3ee86cf3e87e3ca", 134237367), + ENGLISH_ENTRY("questfighter", "Quest Fighter.exe", "21fd0f65dfa48de2b39cb8ec23b30889", 2914128), + ENGLISH_ENTRY("questfighterii", "Quest Fighter 2.exe", "4d7d2addcde045dae6e0363a43f9acad", 5219511), + ENGLISH_ENTRY("questforcinema", "Questforcinema.exe", "465f972675db2da6040518221af5b0ba", 2670632), + ENGLISH_ENTRY("questforglory2vga", "Game.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 5408433), + ENGLISH_ENTRY("questforgloryii", "Qfg2vga.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 20523688), + ENGLISH_ENTRY("questforjesus", "QuestForJesus.exe", "495d45fb8adfd49690ae3b97921feec6", 3973088), + ENGLISH_ENTRY("questforpalette", "Palette Quest.exe", "0710e2ec71042617f565c01824f0cf3c", 754395), + ENGLISH_ENTRY("questforthebluecup", "Quest for the Cup.exe", "9cb3c8dc7a8ab9c44815955696be2677", 8760015), + ENGLISH_ENTRY("questforyeti", "Quest For Yeti.exe", "90413e9ae57e222f8913b09d2bc847bc", 2635580), + ENGLISH_ENTRY("questforyrolg", "Quest for Yrolg.exe", "c4f5b7b29be90ba0f8128298afb917de", 9388101), + ENGLISH_ENTRY("quieromorir", "ElMito.exe", "f120690b506dd63cd7d1112ea6af2f77", 11304944), + ENGLISH_ENTRY("quimbyquestanewdope", "QQuest.exe", "615e806856b7730afadf1fea9a756b70", 8801878), + ENGLISH_ENTRY("race", "R.ACE.exe", "06a03fe35791b0578068ab1873455463", 3842314), + ENGLISH_ENTRY("rackham", "Rackham.exe", "36f44e064eab15e502caeb60fd09f52d", 3672597), + ENGLISH_ENTRY("ralphtheraven", "RalphTheRaven.exe", "0500aacb6c176d47ac0f8158f055db83", 1655198), + ENGLISH_ENTRY("ramsesporterandtherelayforlove", "Ramses Porter and the Relay for Love.exe", "a524cbb1c51589903c4043b98917f1d9", 55490676), + ENGLISH_ENTRY("rango", "Rango.exe", "618d7dce9631229b4579340b964c6810", 21059129), + ENGLISH_ENTRY("ratchannel", "Rat Channel.exe", "c5d2c54c20cb606519b86d3890ee7fc0", 303946606), + ENGLISH_ENTRY("rayandtheguitar", "The Band.exe", "465f972675db2da6040518221af5b0ba", 1518249), + ENGLISH_ENTRY("raybexter", "Ray Bexter.exe", "3e8667bab45f2e5d7237db53ab376400", 5930752), + ENGLISH_ENTRY("raybexter", "Ray Bexter.exe", "d3bc2cf3a0f72f0fbe37d9edbd5ebec3", 5680319), + ENGLISH_ENTRY("razorsinthenight", "Razors.exe", "0500aacb6c176d47ac0f8158f055db83", 25442827), + ENGLISH_ENTRY("reagentorange", "Lab.exe", "83d96faa4efefcc9c03c01b9517f23bb", 13377038), + ENGLISH_ENTRY("realityonthenorm", "RoN-DayOfComet.exe", "465f972675db2da6040518221af5b0ba", 10497989), + ENGLISH_ENTRY("recess", "Recess.exe", "c87aa6377abc18c1a1b2968ae6db08eb", 1941530), + ENGLISH_ENTRY("recess2", "Recess2.exe", "45ab4f29031b50c8d01d10a269f77ff5", 2805921), + ENGLISH_ENTRY("reddwarf", "Red Dwarf.exe", "06a03fe35791b0578068ab1873455463", 2812268), + ENGLISH_ENTRY("redflagg", "Red Flagg.exe", "5901879fafae3812f71b3a2d73bee40e", 79414802), + ENGLISH_ENTRY("redpantsmeetsrobinsonclauseau", "DBL.exe", "c0aab3e02bbaf8468770480079436f61", 15658119), + ENGLISH_ENTRY("redpantstheprincessandthebeanstalk", "Redpants - The Princess and the Beanstalk.exe", "c0aab3e02bbaf8468770480079436f61", 28517345), + ENGLISH_ENTRY("reefriversquestforekoban", "Quest for Ekoban.exe", "338fa79960d40689063af31c671b8729", 179342350), + ENGLISH_ENTRY("returntocivilization", "ReturnTo.exe", "0710e2ec71042617f565c01824f0cf3c", 3280888), + ENGLISH_ENTRY("revelation10", "Revelation.exe", "06a03fe35791b0578068ab1873455463", 14512328), + ENGLISH_ENTRY("rickyquest", "black.exe", "06a03fe35791b0578068ab1873455463", 3250100), + ENGLISH_ENTRY("righteouscity", "RCII.exe", "06a03fe35791b0578068ab1873455463", 39085407), + ENGLISH_ENTRY("righteouscity", "RC PI - 3.00.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 19786840), + ENGLISH_ENTRY("roadofdestiny", "ROD.exe", "618d7dce9631229b4579340b964c6810", 30127308), + ENGLISH_ENTRY("roadracer", "TR_Bryvis.exe", "cebb3ac5c3d2df939e7f0ec8f2975b64", 25080647), + ENGLISH_ENTRY("roastmothergoose", "RMG.exe", "00328f4f1e7729144483107b96b11df8", 46474982), + ENGLISH_ENTRY("robbertredfordsavestheday", "GAME.exe", "02635a77ab660023f59519c91329f7f5", 6537985), + ENGLISH_ENTRY("robbingtheprincess", "Princess.exe", "ac461eb75959761fe159917607c246b4", 5793384), + ENGLISH_ENTRY("robertredford3", "game.exe", "71ca0d6c1c699595f28a2125948d4a84", 10846423), + ENGLISH_ENTRY("robertredfordsavestheday", "ROBERT2.exe", "02635a77ab660023f59519c91329f7f5", 13075066), + ENGLISH_ENTRY("robmassacreofchainsawness", "Chainsaw.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 1153384), + ENGLISH_ENTRY("robotragedy", "Robotragedy.exe", "465f972675db2da6040518221af5b0ba", 130585260), + ENGLISH_ENTRY("robotragedy2", "Robotragedy 2.exe", "465f972675db2da6040518221af5b0ba", 256955387), + ENGLISH_ENTRY("roccioquest", "RoccioQuest.exe", "7727bf5360b00bfc1947455218137803", 5797284), + ENGLISH_ENTRY("rockabillykid", "Rockabilly Kid.exe", "ff3358d8f2726d544aadfde4f1ec8407", 2650305), + ENGLISH_ENTRY("rockburgerstreehouses", "RBTH.exe", "88cf59aad15ca331ab0f854e16c84df3", 1876674), + ENGLISH_ENTRY("rockrockrock", "rrr.exe", "7dd36aa863ed40ede1b09ae505e478cc", 9362761), + ENGLISH_ENTRY("rockyroams", "Rocky.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 16978200), + ENGLISH_ENTRY("rodequest2", "RQ2.exe", "12c03a3c782237821acd590fd91af4c5", 4192097), + ENGLISH_ENTRY("ronbeforethelegacy", "RONlegacy.exe", "0b7529a76f38283d6e850b8d56526fc1", 4792872), + ENGLISH_ENTRY("ronsixteen", "16c.exe", "06a03fe35791b0578068ab1873455463", 2467851), + ENGLISH_ENTRY("rontimeoutintro", "ronTOintro.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 2804752), + ENGLISH_ENTRY("roomoffear", "RoomofFear_Oct.exe", "495d45fb8adfd49690ae3b97921feec6", 17366083), + ENGLISH_ENTRY("rootofallevil", "RootOfAllEvil.exe", "c4f5b7b29be90ba0f8128298afb917de", 3957834), + ENGLISH_ENTRY("rosauradocelestialrescuefromdespair", "RosauraMAGS.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 13190949), + ENGLISH_ENTRY("rotnbelusebiusarrival", "RoNXXL.exe", "465f972675db2da6040518221af5b0ba", 9426141), + ENGLISH_ENTRY("rotnbelusebiusarrival", "ronextra.exe", "465f972675db2da6040518221af5b0ba", 9958019), + ENGLISH_ENTRY("rowengoestowork", "Rowen.exe", "a1cef60926235b85bd0e1866b19e0dc7", 3791058), + ENGLISH_ENTRY("rs15", "rs15.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 13638597), + ENGLISH_ENTRY("rudeawakening", "RudeAwakening.exe", "0710e2ec71042617f565c01824f0cf3c", 8038257), + ENGLISH_ENTRY("ryansdayout", "Ryan's Day out.exe", "06a03fe35791b0578068ab1873455463", 2573584), + ENGLISH_ENTRY("saddsonissein", "Issein.exe", "3e8667bab45f2e5d7237db53ab376400", 4070795), + ENGLISH_ENTRY("salazarsevilplan", "Jonny Smallvalley.exe", "a524cbb1c51589903c4043b98917f1d9", 64646627), + ENGLISH_ENTRY("sammysquest", "Sammy's Quest.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 7924985), + ENGLISH_ENTRY("santaclausdown", "scdown.exe", "f120690b506dd63cd7d1112ea6af2f77", 14385095), + ENGLISH_ENTRY("santassidekick", "Xmas.exe", "0710e2ec71042617f565c01824f0cf3c", 1921077), + ENGLISH_ENTRY("satanquest", "Satan.exe", "70cd70d2fc7b2a8716fc58fc9deaf259", 4779276), + ENGLISH_ENTRY("satchsquest", "Satch's.exe", "465f972675db2da6040518221af5b0ba", 1928613), + ENGLISH_ENTRY("saturdayschool", "ss.exe", "b216ee957dd677023e02d900281a02d6", 1588546), + ENGLISH_ENTRY("saw", "Saw.exe", "34a66a5033b70f4050cbe5e33a45f747", 2452460), + ENGLISH_ENTRY("saw", "Saw.exe", "f120690b506dd63cd7d1112ea6af2f77", 60869310), + ENGLISH_ENTRY("saw2", "Saw2.exe", "615e806856b7730afadf1fea9a756b70", 45338514), + ENGLISH_ENTRY("scaredstiffa", "Scared Stiff.exe", "18b284c22010850f79bc5c20054a70c4", 57878023), + ENGLISH_ENTRY("scarymaze", "Scary Maze.exe", "01823d511cc00f4de6fd920eb543c6e7", 5380554), + ENGLISH_ENTRY("schwarzweissrot", "SchwarzWeissRot - Englisch.exe", "495d45fb8adfd49690ae3b97921feec6", 82849166), + ENGLISH_ENTRY("schwarzweissrot", "SchwarzWeissRot.exe", "495d45fb8adfd49690ae3b97921feec6", 82913128), + ENGLISH_ENTRY("scnider", "scnider.exe", "3128b9f90e2f954ba704414ae854d10b", 1189237), + ENGLISH_ENTRY("scytheisland", "Scythe.exe", "0500aacb6c176d47ac0f8158f055db83", 7119760), + ENGLISH_ENTRY("searchforsanitydemo", "sfs.exe", "308d35bc34e9df29d8acce615593e3e7", 9097147), + ENGLISH_ENTRY("seashells", "Shells.exe", "0500aacb6c176d47ac0f8158f055db83", 6355325), + ENGLISH_ENTRY("seasongreetings2002", "xmas2002.exe", "97d700529f5cc826f230c27acf81adfd", 4263336), + ENGLISH_ENTRY("secretquestremake", "secretquest.exe", "f120690b506dd63cd7d1112ea6af2f77", 2121159), + ENGLISH_ENTRY("secrets", "Secrets.exe", "06a03fe35791b0578068ab1873455463", 36176884), + ENGLISH_ENTRY("seega16engl5", "house_eng_5.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1746878), + ENGLISH_ENTRY("seegame15", "housesitting_18.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1746919), + ENGLISH_ENTRY("sevendoors", "7DOORS.exe", "18b284c22010850f79bc5c20054a70c4", 113716886), + ENGLISH_ENTRY("sga", "StarGA.exe", "0710e2ec71042617f565c01824f0cf3c", 45738298), + ENGLISH_ENTRY("shadesofgreye", "Shades of Greye.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 16125855), + ENGLISH_ENTRY("shadowsoftheempiretd", "sote_td.exe", "b8cd640b45c5a79c33c7a8a8fe32ebe2", 63299246), + ENGLISH_ENTRY("shailadusithlenqute", "Shai-la Enquete.exe", "a524cbb1c51589903c4043b98917f1d9", 7489302), + ENGLISH_ENTRY("shailaofthesith", "Shaila_of_the_Sith.exe", "a524cbb1c51589903c4043b98917f1d9", 76170347), + ENGLISH_ENTRY("shem", "Shem.exe", "0710e2ec71042617f565c01824f0cf3c", 8866401), + ENGLISH_ENTRY("sherlock", "Sherlock.exe", "615e73fc1874e92d60a1996c2330ea36", 19108029), + ENGLISH_ENTRY("shiftersboxoutsidein", "Box.exe", "fc17e9b3ab53f6b4841e2a4af5c782ff", 24471804), + ENGLISH_ENTRY("shivahdemo", "shivahDemo.exe", "6e3d6225dee662ff6450a3bfa942773b", 20897850), + ENGLISH_ENTRY("shoot", "Shoot.exe", "1275885401b7d2ece491e704535707d9", 4327626), + ENGLISH_ENTRY("shootmyvalentine", "Valentine.exe", "06a03fe35791b0578068ab1873455463", 2859760), + ENGLISH_ENTRY("shortcut", "ShortCut.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 4415830), + ENGLISH_ENTRY("shrivel", "Shrivel.exe", "12c6a846b5ba9a5dde4a1b804b3e86e9", 58873190), + ENGLISH_ENTRY("shunday", "Shunday.exe", "82da2565c456dcfb265ded6fe3189c0b", 4937129), + ENGLISH_ENTRY("sierraquest1", "SierraQuest1.exe", "465f972675db2da6040518221af5b0ba", 1275381), + ENGLISH_ENTRY("silentknightii", "SilentKnight2.exe", "465f972675db2da6040518221af5b0ba", 39941166), + ENGLISH_ENTRY("silentknightv11", "Silent Knight.exe", "465f972675db2da6040518221af5b0ba", 47414163), + ENGLISH_ENTRY("simonthesorcerer3demo20", "Simon3.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 8189928), + ENGLISH_ENTRY("skippysavestheday", "First Game Test.exe", "06a03fe35791b0578068ab1873455463", 10473902), + ENGLISH_ENTRY("slaythedragon", "dragon.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 2917672), + ENGLISH_ENTRY("sleepyisland", "Sleepy Island.exe", "465f972675db2da6040518221af5b0ba", 20270790), + ENGLISH_ENTRY("slimequestforpizza", "slime.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 1661109), + ENGLISH_ENTRY("slugprincess", "SlugPrincess.exe", "28f82e420b82d07651b68114f90223c8", 12132209), + ENGLISH_ENTRY("sma21", "sma21.exe", "02094e217c23e1d40a84891ee95010cb", 7093110), + ENGLISH_ENTRY("sma31", "sma31.exe", "4d17844029d8910fbaae1bdc99e250f2", 4961734), + ENGLISH_ENTRY("sma4", "smavier.exe", "02094e217c23e1d40a84891ee95010cb", 2447360), + ENGLISH_ENTRY("smavi", "sma6.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3735081), + ENGLISH_ENTRY("smileysquest", "Smiley.exe", "90413e9ae57e222f8913b09d2bc847bc", 4938049), + ENGLISH_ENTRY("smileysquest2", "mags.exe", "3128b9f90e2f954ba704414ae854d10b", 2108492), + ENGLISH_ENTRY("smoothhide", "SmoothHide.exe", "b142b43c146c25443a1d155d441a6a81", 10006680), + ENGLISH_ENTRY("snakeamagsgame", "Snake.exe", "f120690b506dd63cd7d1112ea6af2f77", 2110526), + ENGLISH_ENTRY("snakesofavalon", "snakes.exe", "464fbeef013ac949e2011551048928cd", 52601238), + ENGLISH_ENTRY("snakesonaplane", "SOAP.exe", "06a03fe35791b0578068ab1873455463", 1589975), + ENGLISH_ENTRY("sniperandspotterservingthemotherland", "sniper and spotter 2.exe", "7a3096ac0237cb6aa8e1718e28caf039", 134215997), + ENGLISH_ENTRY("sonicandfriendsinclubhouse", "Sonic and friends.exe", "71989c04f1b9812a0df87bc4f5915d4b", 50429335), + ENGLISH_ENTRY("sosk", "Sosk.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12338591), + ENGLISH_ENTRY("sovietunterzoegersdorfsectorii", "suz2prog.exe", "47a774ff828be0ca227ee58e7dc61467", 43921618), + ENGLISH_ENTRY("sowjetunterzgersdorf", "suzoeg.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 79618213), + ENGLISH_ENTRY("spacefreakers", "Space Freakers v2.exe", "7a3096ac0237cb6aa8e1718e28caf039", 64527091), + ENGLISH_ENTRY("spacelynxes", "SpaceLynxes.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 6593042), + ENGLISH_ENTRY("spacepirates", "Space Pirates.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 3006210), + ENGLISH_ENTRY("spacepoolalpha", "SpacePool.exe", "ef1d6fdc83c91a1a8de9eaf2630737b7", 3055777), + ENGLISH_ENTRY("spacequest45", "SQ4,5.exe", "5cd8db602cedc8f04cd3ca290a4a2693", 6886082), + ENGLISH_ENTRY("spacequest55demoags", "SQ5.5.exe", "465f972675db2da6040518221af5b0ba", 16342443), + ENGLISH_ENTRY("spacequestiiivgapreview", "SQ3VGADEMO.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3630019), + ENGLISH_ENTRY("spacerangers", "SpaceRangersEp46.exe", "4f6c7ec127e8b0ce077abb357903612f", 41103057), + ENGLISH_ENTRY("spacerangersep52", "SpaceRangers52Grisli.exe", "4f6c7ec127e8b0ce077abb357903612f", 208346458), + ENGLISH_ENTRY("spacewar", "Spacewar.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 2270669), + ENGLISH_ENTRY("spacewarepisode2strikba", "Space.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4084181), + ENGLISH_ENTRY("spellbound", "Spellbound.exe", "588e5b40901f9c85df35ac60b9417eac", 8809110), + ENGLISH_ENTRY("spilakassinn", "Splakassinn.exe", "06a03fe35791b0578068ab1873455463", 2658189), + ENGLISH_ENTRY("spooks", "Spooks.exe", "0710e2ec71042617f565c01824f0cf3c", 22888238), + ENGLISH_ENTRY("spoonsiiitheunauthorizededition", "spoonsIII.exe", "2ca80bd50763378b72cd1e1cf25afac3", 16298983), + ENGLISH_ENTRY("spotthedifference", "Spot the Difference.exe", "0b7529a76f38283d6e850b8d56526fc1", 933452), + ENGLISH_ENTRY("sqm11", "SQM1.exe", "465f972675db2da6040518221af5b0ba", 1001506), + ENGLISH_ENTRY("sqm12", "SQM 1x2.exe", "465f972675db2da6040518221af5b0ba", 755146), + ENGLISH_ENTRY("sqm13", "SQM 1x3.exe", "465f972675db2da6040518221af5b0ba", 1435210), + ENGLISH_ENTRY("sqm14", "SQM 1x4.exe", "465f972675db2da6040518221af5b0ba", 1383567), + ENGLISH_ENTRY("sqm16", "SQM 1x6.exe", "465f972675db2da6040518221af5b0ba", 1400100), + ENGLISH_ENTRY("sproutsofevil", "Sprouts of evil.exe", "bdd1df0484e296faa348ffcb03e16273", 22329944), + ENGLISH_ENTRY("sqkubikgetready", "SQ Kubik.exe", "4fb72c890984548ed6782063f2230942", 2184808), + ENGLISH_ENTRY("sqmania1", "SQMania1.exe", "465f972675db2da6040518221af5b0ba", 831674), + ENGLISH_ENTRY("sqmania2remakeeng", "SQM2 RMK.exe", "465f972675db2da6040518221af5b0ba", 3029288), + ENGLISH_ENTRY("sqmaniaep5", "SQ Mania Ep5.exe", "a524cbb1c51589903c4043b98917f1d9", 2896204), + ENGLISH_ENTRY("sram2cinomehsrevengedemo", "SRAM2.exe", "e3a33d139d90f2e695292a618753b8a5", 296499943), + ENGLISH_ENTRY("stablepeteandthejoust", "StablePete.exe", "b142b43c146c25443a1d155d441a6a81", 30048075), + ENGLISH_ENTRY("stablepeteandthejoust", "StablePete.exe", "b142b43c146c25443a1d155d441a6a81", 30046740), + ENGLISH_ENTRY("stairquest", "Stair Quest.exe", "e0aeab6a2c479fde167c4c43c3abb8ca", 4550699), + ENGLISH_ENTRY("stanamespiepisode1", "NEW.exe", "f120690b506dd63cd7d1112ea6af2f77", 19194728), + ENGLISH_ENTRY("stansrevenge", "Gameisle.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 915036), + ENGLISH_ENTRY("starshipcaramba", "karamba.exe", "465f972675db2da6040518221af5b0ba", 21540340), + ENGLISH_ENTRY("starshipposeidon", "Starship Poseidon.exe", "5a9abb3094d0b3f4bc09c0c77fbb8024", 4163873), + ENGLISH_ENTRY("start", "CC1.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 18627665), + ENGLISH_ENTRY("startreknewton", "Anomaly.exe", "721e8a1dce90fc3ee31cade9a50d9e75", 8750111), + ENGLISH_ENTRY("stediddyip1employment", "stediddy1.exe", "5872fea5a958bc74c2d9ca7b2d196c42", 27136166), + ENGLISH_ENTRY("stickmeni", "stick.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2399329), + ENGLISH_ENTRY("stickythestickfigurepart1thecrimsonhouse", "Crimson House Files.exe", "3b095a7872e04769d04ab45e9c1b66eb", 3610653), + ENGLISH_ENTRY("stinkymcpoopoo", "grok.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1046039), + ENGLISH_ENTRY("stranded", "Stranded.exe", "18b284c22010850f79bc5c20054a70c4", 39791629), + ENGLISH_ENTRY("stranger", "Stranger.exe", "0500aacb6c176d47ac0f8158f055db83", 5854099), + ENGLISH_ENTRY("strangerinstickworld", "game1.exe", "a524cbb1c51589903c4043b98917f1d9", 42525810), + ENGLISH_ENTRY("strangerthings", "StrangerThings.exe", "cc19db728abbcf657db6b76afb0e92d1", 43636017), + ENGLISH_ENTRY("supaevil", "SupaEvil.exe", "0710e2ec71042617f565c01824f0cf3c", 7602318), + ENGLISH_ENTRY("supergirl", "Supergirl.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12108982), + ENGLISH_ENTRY("superjazzmandemo", "SJMdemo.exe", "0710e2ec71042617f565c01824f0cf3c", 5214882), + ENGLISH_ENTRY("superracing", "Super Racing.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 3660473), + ENGLISH_ENTRY("surreality", "Surreality.exe", "3128b9f90e2f954ba704414ae854d10b", 10773443), + ENGLISH_ENTRY("sweed", "SWeed.exe", "be65afc1ea59889c05e4e4cc143b3dbc", 2171942), + ENGLISH_ENTRY("sword", "Sword.exe", "0500aacb6c176d47ac0f8158f055db83", 1847692), + ENGLISH_ENTRY("sydneyfindsemployment", "sydney.exe", "06a03fe35791b0578068ab1873455463", 17351738), + ENGLISH_ENTRY("sydneytreadsthecatwalk", "sydney two.exe", "615e806856b7730afadf1fea9a756b70", 31480339), + ENGLISH_ENTRY("symplokelaleyendadegustavobuenocapitulo1", "Symploke.exe", "ff20c8c9dda8379607db87e7726909c6", 29996616), + ENGLISH_ENTRY("tales", "Tales.exe", "4f6c7ec127e8b0ce077abb357903612f", 112930701), + ENGLISH_ENTRY("talesofchickenry", "Chickenry.exe", "aabdafae8b57dfc48fdf158a72326c23", 50338519), + ENGLISH_ENTRY("tao", "Tao through space and time AGS.exe", "7a3096ac0237cb6aa8e1718e28caf039", 35930047), + ENGLISH_ENTRY("tarthenia", "Tarthenia.exe", "a524cbb1c51589903c4043b98917f1d9", 1047988125), + ENGLISH_ENTRY("teamwork", "teamwork.exe", "96f83f7decb523d0c621646828cad249", 3741039), + ENGLISH_ENTRY("templeofspheres", "Spheres.exe", "e9475a2e453039ca51c8c319a8c8255a", 7117373), + ENGLISH_ENTRY("tenhumstombpart1", "tomb.exe", "0710e2ec71042617f565c01824f0cf3c", 1252175), + ENGLISH_ENTRY("terrorofthevampire", "TERRVAMP.exe", "efd2b2abf965c4b50bea79a419b82cf1", 5164804), + ENGLISH_ENTRY("test", "Living Nightmare.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 3356797), + ENGLISH_ENTRY("test5", "who07.exe", "465f972675db2da6040518221af5b0ba", 1889598), + ENGLISH_ENTRY("textparsergame", "tparsergame.exe", "06a03fe35791b0578068ab1873455463", 2061002), + ENGLISH_ENTRY("thatday", "ThatDay.exe", "b142b43c146c25443a1d155d441a6a81", 9534366), + ENGLISH_ENTRY("the30minutewar", "7DG.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1659319), + ENGLISH_ENTRY("the7thsense", "7thSense.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 17972183), + ENGLISH_ENTRY("theadventureofthehero", "The Adventure of the Hero.exe", "5d20aab40290fc72ec84393464913df2", 4408710), + ENGLISH_ENTRY("theadventuresoffatman", "Fatman.exe", "853cef07077feadd0f2ccd55c5bd747b", 56375090), + ENGLISH_ENTRY("theadventuresofturquoisem", "The Adventures Of Turquoise Mcdonald.exe", "06a03fe35791b0578068ab1873455463", 2883450), + ENGLISH_ENTRY("theassassin", "the-assassin.exe", "e3962995a70923a8d5a8f1cf8f932eee", 29043438), + ENGLISH_ENTRY("theawakening", "The Awakening.exe", "0241777c2537fc5d077c05cde10bfa9f", 13613585), + ENGLISH_ENTRY("thebadneighbours", "Bad neighbour.exe", "06a03fe35791b0578068ab1873455463", 9672173), + ENGLISH_ENTRY("thebar", "one room game.exe", "465f972675db2da6040518221af5b0ba", 11660587), + ENGLISH_ENTRY("thebrokenbrain", "Brain.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 1092293), + ENGLISH_ENTRY("thebunker", "The Bunker.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12391058), + ENGLISH_ENTRY("thecadaversynod", "The cadaver synod.exe", "36f44e064eab15e502caeb60fd09f52d", 37438749), + ENGLISH_ENTRY("thecan", "TheCan.exe", "82da2565c456dcfb265ded6fe3189c0b", 72388782), + ENGLISH_ENTRY("thecell", "The Cell.exe", "b142b43c146c25443a1d155d441a6a81", 21422530), + ENGLISH_ENTRY("thecell", "Cell.exe", "0b7529a76f38283d6e850b8d56526fc1", 811527), + ENGLISH_ENTRY("thechrysalis", "Mygame.exe", "22b9c6d170613eb01afa1697b1b75cdb", 28926604), + ENGLISH_ENTRY("thecrackwelllegacy", "Crackwell.exe", "06a03fe35791b0578068ab1873455463", 2990976), + ENGLISH_ENTRY("thecube", "The Cube.exe", "97d700529f5cc826f230c27acf81adfd", 2029985), + ENGLISH_ENTRY("thecurioussilence", "silence.exe", "495d45fb8adfd49690ae3b97921feec6", 8039714), + ENGLISH_ENTRY("thecurseoflife", "TheCurse.exe", "90413e9ae57e222f8913b09d2bc847bc", 9651875), + ENGLISH_ENTRY("thedayofdarkness", "DayODark.exe", "465f972675db2da6040518221af5b0ba", 1082758), + ENGLISH_ENTRY("thedeathoflukesimpson", "LukeDead.exe", "06a03fe35791b0578068ab1873455463", 3233789), + ENGLISH_ENTRY("thedevilsshroudpart1", "DevilTorino256.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 16661573), + ENGLISH_ENTRY("thedigitalspell", "Digital.exe", "4d17844029d8910fbaae1bdc99e250f2", 14657385), + ENGLISH_ENTRY("thedusseldorfconspiracy", "dusseldorf.exe", "465f972675db2da6040518221af5b0ba", 60887427), + ENGLISH_ENTRY("thedwarvendaggerofblitz", "teste2.exe", "06a03fe35791b0578068ab1873455463", 9874658), + ENGLISH_ENTRY("theelevator", "Elevator.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 6563864), + ENGLISH_ENTRY("theenergizer", "TheEnergizer.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 54539625), + ENGLISH_ENTRY("theepicadventures", "Epic adventures.exe", "a524cbb1c51589903c4043b98917f1d9", 17723648), + ENGLISH_ENTRY("theeverbeginningtale", "RRS.exe", "36f8b37f85f446e9aaccb18d85660cde", 5006033), + ENGLISH_ENTRY("theexecutionofanneboleyn", "TheExecutionOfAnneBoleyn.exe", "6ee67d23067b0499eb8c6a1a9aabff8c", 8549540), + ENGLISH_ENTRY("thefarm", "the farm.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 88858865), + ENGLISH_ENTRY("theficklehandsoffate", "Game.exe", "2bf7a3a5f0a22a140350e29bb1ac7cfb", 4105398), + ENGLISH_ENTRY("thefind", "The Find.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 3476394), + ENGLISH_ENTRY("thegourmet", "The Gourmet.exe", "c48d0beedcdc1b05e9e25dcd60de46a9", 49995478), + ENGLISH_ENTRY("thegreatcasserolecaper", "TGCC.exe", "6ee842f73649ced615c44d4eb303687c", 10902276), + ENGLISH_ENTRY("thegreatstrokeoff", "GSO.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 84337184), + ENGLISH_ENTRY("thegruglegends", "Grug.exe", "c6acb1705dd30f82ba026e92d6af831e", 85947629), + ENGLISH_ENTRY("thehamlet", "hamlet.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4252451), + ENGLISH_ENTRY("thehauntedhouse", "HH.exe", "97d700529f5cc826f230c27acf81adfd", 29221222), + ENGLISH_ENTRY("theheist", "The Heist.exe", "261d108f9213356a351b35b54867f342", 13502430), + ENGLISH_ENTRY("thehobbitriseofthedragonking", "The Hobbit.exe", "338fa79960d40689063af31c671b8729", 113862075), + ENGLISH_ENTRY("thehousethatatemysoul", "THTFMD.exe", "f120690b506dd63cd7d1112ea6af2f77", 3930376), + ENGLISH_ENTRY("thehuntforgoldbeard", "The hunt for Goldbeard.exe", "a524cbb1c51589903c4043b98917f1d9", 4043188), + ENGLISH_ENTRY("thehuntforshaunbinda", "For Lisa Creed Made By Dan man.exe", "fd91d116e5adc4328cb22fab0b940e4d", 30753829), + ENGLISH_ENTRY("thehuntforshaunbindadeluxeedition", "For Lisa Creed Made By Dan man.exe", "5d6e936eaee9316e756bfe33ef8d3a19", 34290389), + ENGLISH_ENTRY("theiraqiparadox", "0203.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 2976283), + ENGLISH_ENTRY("thejackyard", "The Jackyard.exe", "45d092881ef70b288382426a10251df3", 101417484), + ENGLISH_ENTRY("thejourneyhome", "Part1.exe", "9cf51833e787cc919837d9a8bd8fc14c", 8355767), + ENGLISH_ENTRY("thejourneyofiesir", "The Journey of Iesir.exe", "376a3f162c7940d990325c53edc20fed", 70444514), + ENGLISH_ENTRY("thelastharvest", "The Last Harvest.exe", "f120690b506dd63cd7d1112ea6af2f77", 6253816), + ENGLISH_ENTRY("thelastsupperawhodunnit", "THE LAST SUPPER, A WHODUNNIT.exe", "37500274a7882e8087042cc6ec851e0c", 13447848), + ENGLISH_ENTRY("theloneloserdemo", "DEMO (English).exe", "0500aacb6c176d47ac0f8158f055db83", 6082095), + ENGLISH_ENTRY("thelongtrip", "longtrip.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 184362586), + ENGLISH_ENTRY("themajesticconspiracy", "Majestic.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 17929647), + ENGLISH_ENTRY("themarionette", "marionette.exe", "ff3d6e4edfca8b4f4f1c6cbf8e2781a6", 88408446), + ENGLISH_ENTRY("themccarthychronicleschapter1", "McCarthy.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 29488543), + ENGLISH_ENTRY("themcreedcasebytk", "McReedCase.exe", "4bcbc24015114752b3c7971128704689", 2982436), + ENGLISH_ENTRY("themysteriesofstiegomoors", "mystery.exe", "0710e2ec71042617f565c01824f0cf3c", 12062769), + ENGLISH_ENTRY("themysteryofhauntedhollow", "magic1.exe", "3128b9f90e2f954ba704414ae854d10b", 3338806), + ENGLISH_ENTRY("thenetherworld", "netherworld.exe", "465f972675db2da6040518221af5b0ba", 2253033), + ENGLISH_ENTRY("thenextcurse", "TNC.exe", "88cf59aad15ca331ab0f854e16c84df3", 4125146), + ENGLISH_ENTRY("theoraclev11", "The Oracle.exe", "f120690b506dd63cd7d1112ea6af2f77", 7490474), + ENGLISH_ENTRY("thepark", "park.exe", "97d700529f5cc826f230c27acf81adfd", 709265), + ENGLISH_ENTRY("theperfectmurder", "Tamz.exe", "9cf51833e787cc919837d9a8bd8fc14c", 4527709), + ENGLISH_ENTRY("thephantominheritance", "Phantom.exe", "ec04c7917c003d9e07d4514ff25bf365", 27558669), + ENGLISH_ENTRY("thequestfortheholysalsa", "TheQuestForTheHolySalsa.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 38506266), + ENGLISH_ENTRY("thequesttozooloo", "Zooloo.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 14619530), + ENGLISH_ENTRY("theroadtomurder", "lbb.exe", "465f972675db2da6040518221af5b0ba", 1020984), + ENGLISH_ENTRY("therobolovers", "The Robolovers.exe", "618d7dce9631229b4579340b964c6810", 63850620), + ENGLISH_ENTRY("therotaryclub", "The Rotary Club.exe", "01823d511cc00f4de6fd920eb543c6e7", 9641709), + ENGLISH_ENTRY("thesearch", "s??rts.exe", "465f972675db2da6040518221af5b0ba", 5465638), + ENGLISH_ENTRY("thesecretofchunkysalsa", "TSOCS.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3096950), + ENGLISH_ENTRY("thesecretofgoldenriver", "tsotgr.exe", "06a03fe35791b0578068ab1873455463", 8397455), + ENGLISH_ENTRY("thesecretofhuttongrammarschool", "1g1w.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 6584420), + ENGLISH_ENTRY("thesecretofmountmonkey", "Mmonk.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 6386620), + ENGLISH_ENTRY("thesecretplan1runningtostandstill", "thesecretplan1.exe", "bb59de174d70797d774dec76a171352d", 447931405), + ENGLISH_ENTRY("theshortestjourney", "The Shortest Journey.exe", "7c70226b560d6d9ffd9e165d6fbddd7e", 21503346), + ENGLISH_ENTRY("thesmallestpoints", "The Smallest Points.exe", "fd642138b7e6374ce0a0b9a1b0510500", 29534364), + ENGLISH_ENTRY("thesnaplock", "The Snaplock.exe", "7a3096ac0237cb6aa8e1718e28caf039", 31519102), + ENGLISH_ENTRY("thespoons", "Spoons.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 3652176), + ENGLISH_ENTRY("thestarryskyaboveme", "The Starry Sky Above Me.exe", "618d7dce9631229b4579340b964c6810", 14082659), + ENGLISH_ENTRY("thestring", "String.exe", "90413e9ae57e222f8913b09d2bc847bc", 36963577), + ENGLISH_ENTRY("thesundownmystery", "Sundown.exe", "a08ab253c4d2f255b9139f2aa5fe7006", 31839270), + ENGLISH_ENTRY("thetombofthemoon", "TotM.exe", "f120690b506dd63cd7d1112ea6af2f77", 1632811), + ENGLISH_ENTRY("thetrap", "Darcy.exe", "0500aacb6c176d47ac0f8158f055db83", 1164147), + ENGLISH_ENTRY("thetreasuredmedallion", "The Treasured Medallion.exe", "504df40bf50a0859e3dc15b000dab5f6", 1091122652), + ENGLISH_ENTRY("thetreasureoflochinch", "LochInch.exe", "6e861b1f476ff7cdf036082abb271329", 4091983), + ENGLISH_ENTRY("theuncertaintymachine", "TUMv11.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 20672955), + ENGLISH_ENTRY("theuncertaintymachine", "TUMv11.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 20670414), + ENGLISH_ENTRY("theupliftmofopartyplan", "MI5 Bob.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4092850), + ENGLISH_ENTRY("thevacuum", "Spacefiles.exe", "d0ba73645e3cbf8ccd65121417f9895f", 14805166), + ENGLISH_ENTRY("thewitch", "Witch.exe", "f120690b506dd63cd7d1112ea6af2f77", 2693486), + ENGLISH_ENTRY("thisgame", "thisgame.exe", "74aad8dfd71ed2ae9574a60be7610c43", 6271585), + ENGLISH_ENTRY("threeguyswalkintoheaven", "Three Guys Walk Into Heaven.exe", "c45653d1c856f002ceb59a5b865ab187", 2896291), + ENGLISH_ENTRY("tilepuzzlegame", "Puzzle01.exe", "615e73fc1874e92d60a1996c2330ea36", 2819964), + ENGLISH_ENTRY("tiltor", "Tiltor.exe", "f120690b506dd63cd7d1112ea6af2f77", 17561878), + ENGLISH_ENTRY("timegentlemenpleasedemo", "TGP.exe", "86a5359bac7c88f0dfa060478800dd61", 29686006), + ENGLISH_ENTRY("timequest", "gam.exe", "465f972675db2da6040518221af5b0ba", 5669007), + ENGLISH_ENTRY("timequest2", "TimeQ2.exe", "465f972675db2da6040518221af5b0ba", 5838823), + ENGLISH_ENTRY("timesinkofchronos", "Timesink.exe", "2bc8f994a7d1e05ed45f35abf2128231", 127528679), + ENGLISH_ENTRY("timothylande", "Timothy Lande.exe", "0500aacb6c176d47ac0f8158f055db83", 13874628), + ENGLISH_ENTRY("tmateundescanso", "tomate.exe", "3128b9f90e2f954ba704414ae854d10b", 8865274), + ENGLISH_ENTRY("tmntturtlesintime", "Turtles.exe", "465f972675db2da6040518221af5b0ba", 2309552), + ENGLISH_ENTRY("tomhanksaway", "Tom Hanks Away.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1589035), + ENGLISH_ENTRY("toomanykittens", "Too Many Kittens.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 3926440), + ENGLISH_ENTRY("totalhangoverextreamzz", "hangover.exe", "72a1e963da14255d2b7523133f7147d9", 1837194), + ENGLISH_ENTRY("tq", "TQ.exe", "465f972675db2da6040518221af5b0ba", 2420457), + ENGLISH_ENTRY("trappedinabuilding", "T I A B.exe", "722c8bd17ace161f1bba2d9d92806eaf", 5370873), + ENGLISH_ENTRY("trevordaisoninouterspace", "TrevorDaison.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 22641402), + ENGLISH_ENTRY("trexandmusclesambigtroubleinspf", "Trex and Muscle Sam.exe", "91696f9333f36bdba272220c644c72e7", 120822652), + ENGLISH_ENTRY("trilbysnotes", "notes.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 5736960), + ENGLISH_ENTRY("trilbytheartoftheft", "artoftheft.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 8940823), + ENGLISH_ENTRY("trivialpassyouit", "Trivial Pass You It.exe", "01823d511cc00f4de6fd920eb543c6e7", 2737077), + ENGLISH_ENTRY("tuberainbow", "Tube Rainbow.exe", "03c8c45bd00daca1a9d75d1133df5640", 5669127), + ENGLISH_ENTRY("tvbrder", "TvaBroder.exe", "7a669a96e488653db661d285bbc12783", 17875297), + ENGLISH_ENTRY("twelvethirteen", "1213.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 2942386), + ENGLISH_ENTRY("twelvethirteenepisode2", "1213_ep2.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 3602361), + ENGLISH_ENTRY("twelvethirteenepisode3", "1213_ep3.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 3205606), + ENGLISH_ENTRY("twentiesflappersvsthemummy", "Twenties Flappers vs The Mummy.exe", "a524cbb1c51589903c4043b98917f1d9", 15042196), + ENGLISH_ENTRY("twoofakind", "toak.exe", "465f972675db2da6040518221af5b0ba", 24644765), + ENGLISH_ENTRY("uglyfiles", "ugly.exe", "0394af1c29e1060fcdbacf2a3dd9b231", 4169486), + ENGLISH_ENTRY("ulitsadimitrova", "ulitsa.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 291828379), + ENGLISH_ENTRY("unboundver10", "Unbound.exe", "900b277d7e1601c65b42868cd7fae662", 10448702), + ENGLISH_ENTRY("unfinished", "mags.exe", "0710e2ec71042617f565c01824f0cf3c", 12092514), + ENGLISH_ENTRY("unganeedsmumba", "UNGA needs MUMBA.exe", "2ca6bb6d5b2710ac89fea7d69c2eaf77", 5470102), + ENGLISH_ENTRY("unintelligentdesign", "UD.exe", "5ca1bc01c5a45388bd5c84ef36077361", 6019596), + ENGLISH_ENTRY("unprofev10", "Un Profe.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 3465541), + ENGLISH_ENTRY("untilihaveyou", "Until I Have You.exe", "cda1d7e36993dd55ba5513c1c43e5b2b", 457842687), + ENGLISH_ENTRY("updatequest", "U-Quest.exe", "06a03fe35791b0578068ab1873455463", 1776804), + ENGLISH_ENTRY("utopiaoftyrant", "Utopia_of_a_Tyrant.exe", "f8a42e09e40a7ab1cd2a21f74a5e0980", 80966652), + ENGLISH_ENTRY("vacationquestthing", "MGA.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 943647), + ENGLISH_ENTRY("valhallaextinction", "MAGSjuly2016.exe", "95864ae16f51c512985007dca83c1370", 4464850), + ENGLISH_ENTRY("valis", "valis 0.70.exe", "0710e2ec71042617f565c01824f0cf3c", 4348394), + ENGLISH_ENTRY("vankairbreak", "Airbreak.exe", "28567bd2dc355a02a0ba58749e753f87", 23126775), + ENGLISH_ENTRY("vegetablepatchextreemturbo", "VPET.exe", "0b7529a76f38283d6e850b8d56526fc1", 2656540), + ENGLISH_ENTRY("veggietales3d", "Veggie Tales 3D.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 5645075), + ENGLISH_ENTRY("veteranshootout", "Vet kill.exe", "0710e2ec71042617f565c01824f0cf3c", 3641458), + ENGLISH_ENTRY("vicwreckleshalloweencostume", "vic.exe", "01d0e6bd812abaa307bcb10fc2193416", 2913241), + ENGLISH_ENTRY("virtualpiano10", "Synth.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1419081), + ENGLISH_ENTRY("vohaulsrevengeii", "SQ XII.exe", "465f972675db2da6040518221af5b0ba", 17313307), + ENGLISH_ENTRY("vpxt2", "VPET!2!.exe", "0b7529a76f38283d6e850b8d56526fc1", 12933096), + ENGLISH_ENTRY("waitingfortheloop", "WaitingForTheLoop.exe", "0241777c2537fc5d077c05cde10bfa9f", 51273604), + ENGLISH_ENTRY("wallyweaseldemo", "WallyDemo.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 12579444), + ENGLISH_ENTRY("waltersasteroid", "HDGame.exe", "465f972675db2da6040518221af5b0ba", 8390872), + ENGLISH_ENTRY("warthogs", "Warthogs.exe", "9c49b6fa0460f36d6e7558281f142683", 12448793), + ENGLISH_ENTRY("washedashore", "Achtung!.exe", "06a03fe35791b0578068ab1873455463", 7926840), + ENGLISH_ENTRY("washedashoredeluxe", "Washed.exe", "06a03fe35791b0578068ab1873455463", 2771873), + ENGLISH_ENTRY("wasted", "Wasted.exe", "f120690b506dd63cd7d1112ea6af2f77", 27870661), + ENGLISH_ENTRY("waterquest", "KOSTAS.exe", "f120690b506dd63cd7d1112ea6af2f77", 12403015), + ENGLISH_ENTRY("wcedit", "walkcyclist.exe", "1e81f0cba7e94fb658acd8e24ff1089f", 1861346), + ENGLISH_ENTRY("wearevectors", "WAV.exe", "a524cbb1c51589903c4043b98917f1d9", 5851536), + ENGLISH_ENTRY("welcometodarklake", "mystery.exe", "18b284c22010850f79bc5c20054a70c4", 5438912), + ENGLISH_ENTRY("wet", "Wet.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1271457), + ENGLISH_ENTRY("what", "what!.exe", "08cb9ad3be9f966132d0c17f0dee471c", 48181831), + ENGLISH_ENTRY("whatisthatthing", "somtin.exe", "0500aacb6c176d47ac0f8158f055db83", 1289618), + ENGLISH_ENTRY("whatlinusbruckmansees", "LinusBruckman.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 320171493), + ENGLISH_ENTRY("wherebedragons", "Where Be Dragons.exe", "d8ccbb83c73ca8520b19412ce0d8de10", 2607599), + ENGLISH_ENTRY("wheredidsamgo", "WDSG.exe", "0710e2ec71042617f565c01824f0cf3c", 4921841), + ENGLISH_ENTRY("wheresmhatma", "WMHM.exe", "25f919423520b921a041ec854e3a0217", 51766424), + ENGLISH_ENTRY("whowantstoliveagain", "Bond.exe", "465f972675db2da6040518221af5b0ba", 2497443), + ENGLISH_ENTRY("whowantstoliveforever", "WWtLF.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 6917937), + ENGLISH_ENTRY("williamsnightmare", "Killer.exe", "0b7529a76f38283d6e850b8d56526fc1", 3991683), + ENGLISH_ENTRY("willowhouse", "Game.exe", "5bc696cf7178870b21db6ac87972befd", 132161306), + ENGLISH_ENTRY("willy", "Willy.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 3403804), + ENGLISH_ENTRY("winnersdontdodrugs", "windrugs.exe", "ff3358d8f2726d544aadfde4f1ec8407", 2573704), + ENGLISH_ENTRY("winterrose", "Winter Rose.exe", "0500aacb6c176d47ac0f8158f055db83", 37444693), + ENGLISH_ENTRY("witch", "witch.exe", "06a03fe35791b0578068ab1873455463", 10110407), + ENGLISH_ENTRY("witchnight", "wnight.exe", "9cf51833e787cc919837d9a8bd8fc14c", 2792150), + ENGLISH_ENTRY("witness", "Witness!.exe", "0710e2ec71042617f565c01824f0cf3c", 803884), + ENGLISH_ENTRY("wizardhood", "wiz.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 3693530), + ENGLISH_ENTRY("woo", "Woo.exe", "06a03fe35791b0578068ab1873455463", 4771204), + ENGLISH_ENTRY("woolyrockbottom", "Wooly.exe", "261d108f9213356a351b35b54867f342", 3409152), + ENGLISH_ENTRY("worldofwarcraftquest", "IMBA.exe", "3a96a134156aeccee37daae9a7d5232d", 31743641), + ENGLISH_ENTRY("worm", "Worm.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 40704028), + ENGLISH_ENTRY("wrathofthesolonoids", "verb.exe", "0500aacb6c176d47ac0f8158f055db83", 3582078), + ENGLISH_ENTRY("yoda", "Yoda.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 2461339), + ENGLISH_ENTRY("yourgame", "Newgame.exe", "949f7440e3692b7366c2029979dee9a0", 9635719), + ENGLISH_ENTRY("yourlate", "Your late.exe", "02635a77ab660023f59519c91329f7f5", 2719997), + ENGLISH_ENTRY("zakmckracken", "Zak2.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 8686711), + ENGLISH_ENTRY("zombieattackdemo", "ZADemo.exe", "82da2565c456dcfb265ded6fe3189c0b", 20958555), + ENGLISH_ENTRY("zombiefish", "FZombie.exe", "3128b9f90e2f954ba704414ae854d10b", 4220305), + ENGLISH_ENTRY("zooreal", "zoo_real.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 24184795), + ENGLISH_ENTRY("zugzwang", "Zugzwang.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 17209702), + { AD_TABLE_END_MARKER } }; From 7bb49a1ff58c1e9153dea82472f34cf50c239687 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 31 Jan 2021 13:12:45 -0800 Subject: [PATCH 194/215] AGS: Fix compiler warnings --- engines/ags/events.cpp | 2 +- .../ags/plugins/ags_creditz/ags_creditz.cpp | 29 +++++++++---------- engines/ags/plugins/ags_creditz/ags_creditz.h | 2 +- .../plugins/ags_pal_render/ags_pal_render.cpp | 10 +++---- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/engines/ags/events.cpp b/engines/ags/events.cpp index 3bff16c29672..492210eb9f5d 100644 --- a/engines/ags/events.cpp +++ b/engines/ags/events.cpp @@ -86,7 +86,7 @@ int EventsManager::readKey() { Common::KeyState keyState = _pendingKeys.pop(); int code = getScancode(keyState.keycode) << 8; - if (keyState.ascii >= 0 && keyState.ascii <= 127) + if (keyState.ascii <= 127) code = keyState.ascii; return code; diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.cpp b/engines/ags/plugins/ags_creditz/ags_creditz.cpp index 28bc707fae3b..f88ea7ebf523 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.cpp +++ b/engines/ags/plugins/ags_creditz/ags_creditz.cpp @@ -77,18 +77,18 @@ int AGSCreditz::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { } void AGSCreditz::SetCreditImage(const ScriptMethodParams ¶ms) { - PARAMS5(int, ID, int, Slot, int, center, int, xpos, int, pixtonext); + //PARAMS5(int, ID, int, Slot, int, center, int, xpos, int, pixtonext); } void AGSCreditz::PauseScroll(const ScriptMethodParams ¶ms) { - PARAMS1(int, onoff); + //PARAMS1(int, onoff); } void AGSCreditz::ScrollReset(const ScriptMethodParams ¶ms) { } void AGSCreditz::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { - PARAMS1(int, Height); + //PARAMS1(int, Height); } int AGSCreditz::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { @@ -96,17 +96,17 @@ int AGSCreditz::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { } void AGSCreditz::SetStaticCredit(const ScriptMethodParams ¶ms) { - PARAMS8(int, ID, int, x, int, y, int, creditfont, int, creditcolour, int, centered, int, generateoutline, string, credit); + //PARAMS8(int, ID, int, x, int, y, int, creditfont, int, creditcolour, int, centered, int, generateoutline, string, credit); } string AGSCreditz::GetStaticCredit(const ScriptMethodParams ¶ms) { - PARAMS1(int, ID); + //PARAMS1(int, ID); return nullptr; } void AGSCreditz::StartEndStaticCredits(const ScriptMethodParams ¶ms) { - PARAMS2(int, onoff, int, res); + //PARAMS2(int, onoff, int, res); } int AGSCreditz::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { @@ -114,26 +114,26 @@ int AGSCreditz::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { } void AGSCreditz::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { - PARAMS1(int, Cyclesperchar); + //PARAMS1(int, Cyclesperchar); } void AGSCreditz::SetStaticPause(const ScriptMethodParams ¶ms) { - PARAMS2(int, ID, int, length); + //PARAMS2(int, ID, int, length); } void AGSCreditz::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { - PARAMS8(int, ID, int, x, int, y, int, titlefont, int, titlecolour, int, centered, int, generateoutline, string, title); + //PARAMS8(int, ID, int, x, int, y, int, titlefont, int, titlecolour, int, centered, int, generateoutline, string, title); } void AGSCreditz::ShowStaticCredit(const ScriptMethodParams ¶ms) { - PARAMS6(int, ID, int, time, int, style, int, transtime, int, sound, int, resolution); + //PARAMS6(int, ID, int, time, int, style, int, transtime, int, sound, int, resolution); } void AGSCreditz::StaticReset(const ScriptMethodParams ¶ms) { } string AGSCreditz::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { - PARAMS1(int, ID); + //PARAMS1(int, ID); return nullptr; } @@ -166,7 +166,7 @@ void AGSCreditz11::AGS_EngineStartup(IAGSEngine *engine) { void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { PARAMS7(int, ID, string, credit, int, colour, int, font, int, center, int, xpos, int, generateoutline); - if (ID >= _state->_credits[0].size()) + if (ID >= (int)_state->_credits[0].size()) _state->_credits[0].resize(ID + 1); Credit &c = _state->_credits[0][ID]; @@ -176,6 +176,7 @@ void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { c._x = xpos; c._isSet = true; c._outline = generateoutline; + c._color = colour; } void AGSCreditz11::ScrollCredits(const ScriptMethodParams ¶ms) { @@ -205,7 +206,7 @@ void AGSCreditz11::ScrollCredits(const ScriptMethodParams ¶ms) { } } -const string AGSCreditz11::GetCredit(const ScriptMethodParams ¶ms) { +string AGSCreditz11::GetCredit(const ScriptMethodParams ¶ms) { PARAMS1(int, ID); return (_state->_credits[0][ID]._text == IMAGE_TEXT) ? @@ -243,8 +244,6 @@ void AGSCreditz20::SetCredit(const ScriptMethodParams ¶ms) { c._outline = true; } - - } // namespace AGSCreditz } // namespace Plugins } // namespace AGS3 diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.h b/engines/ags/plugins/ags_creditz/ags_creditz.h index baf0b738970b..d49bddbdf5cc 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.h +++ b/engines/ags/plugins/ags_creditz/ags_creditz.h @@ -155,7 +155,7 @@ class AGSCreditz11 : public AGSCreditz { static void SetCredit(const ScriptMethodParams ¶ms); static void ScrollCredits(const ScriptMethodParams ¶ms); - static const string GetCredit(const ScriptMethodParams ¶ms); + static string GetCredit(const ScriptMethodParams ¶ms); public: AGSCreditz11(); }; diff --git a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp index 58f89b6eb32e..f0f15c35f028 100644 --- a/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp +++ b/engines/ags/plugins/ags_pal_render/ags_pal_render.cpp @@ -1130,9 +1130,9 @@ int DrawReflections(int id, int charobj = 0) { //Initialize stuff BITMAP *charsprite = nullptr; BITMAP *charsprite2 = nullptr; - AGSCharacter *currchar; + AGSCharacter *currchar = nullptr; AGSObject *currobj; - int cox, coy, coz = 0; + int cox = 0, coy = 0, coz = 0; int scale = 0; //Get character, and their sprite. if (charobj == 0) { @@ -1273,7 +1273,7 @@ int DrawReflections(int id, int charobj = 0) { int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blendmode = 0, int use_objpal = 0) { BITMAP *maskspr = nullptr; - unsigned char **maskarray; + unsigned char **maskarray = nullptr; if (mask > 0) maskspr = engine->GetSpriteGraphic(mask); if (!maskspr && mask > 0) { char maskerr [100]; @@ -1327,8 +1327,8 @@ int DrawTransSprite(int spriteId, int bg, int translevel, int mask = 0, int blen int DrawTranslucentOverlay(int spriteId, int translevel, int ox, int oy, int mask = 0, int blendmode = 0) { if (translevel == 0) return 0; - BITMAP *maskspr; - unsigned char **maskarray; + BITMAP *maskspr = nullptr; + unsigned char **maskarray = nullptr; // Get a reference to the screen we'll draw onto BITMAP *virtsc = engine->GetVirtualScreen(); //BITMAP *clutspr = engine->GetSpriteGraphic (clutslot); From 470028e29ee6866b42cccfe218babde7cdebf0f3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 31 Jan 2021 18:13:15 -0800 Subject: [PATCH 195/215] AGS: Add listing of some pre-2.5 games to game scanner --- engines/ags/tests/game_scanner.cpp | 47 +++++++++++++++++++++--------- engines/ags/tests/game_scanner.h | 1 + 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/engines/ags/tests/game_scanner.cpp b/engines/ags/tests/game_scanner.cpp index 73e85803495c..acbc39bf41c9 100644 --- a/engines/ags/tests/game_scanner.cpp +++ b/engines/ags/tests/game_scanner.cpp @@ -41,9 +41,18 @@ extern GameSetupStruct game; void GameScanner::scan() { detectClashes(); - Common::FSNode folder("."); //ConfMan.get("path")); + Common::FSNode folder("."); scanFolder(folder); + if (!_oldGames.empty()) { + debug("// Pre 2.5 games that aren't supported"); + for (EntryArray::iterator it = _oldGames.begin(); it != _oldGames.end(); ++it) { + debug("UNSUPPORTED_ENTRY(\"\", \"%s\", \"%s\", %u),", + it->_filename.c_str(), it->_md5.c_str(), it->_filesize); + } + debug(""); + } + Common::HashMap gameDescs; for (EntryArray::iterator it = _games.begin(); it != _games.end(); ++it) { if (!gameDescs.contains(it->_id)) @@ -112,18 +121,28 @@ void GameScanner::scanFile(const Common::String &filename) { return; AGS::Shared::HError err = preload_game_data(); - if (!err) - return; - - // Add an entry for the found game - Entry e; - e._filename = fsNode.getName(); - e._filesize = size; - e._gameName = game.gamename; - e._id = convertGameNameToId(e._gameName); - e._md5 = md5; - - _games.push_back(e); + if (!err) { + if (err->Code() == AGS::Shared::kMGFErr_FormatVersionTooOld) { + Entry e; + e._filename = fsNode.getName(); + e._filename.toLowercase(); + e._filesize = size; + e._md5 = md5; + + _oldGames.push_back(e); + } + } else { + // Add an entry for the found game + Entry e; + e._filename = fsNode.getName(); + e._filename.toLowercase(); + e._filesize = size; + e._gameName = game.gamename; + e._id = convertGameNameToId(e._gameName); + e._md5 = md5; + + _games.push_back(e); + } } Common::String GameScanner::convertGameNameToId(const Common::String &name) { @@ -131,7 +150,7 @@ Common::String GameScanner::convertGameNameToId(const Common::String &name) { for (uint idx = 0; idx < name.size(); ++idx) { char c = name[idx]; - if (Common::isAlnum(c)) + if (Common::isDigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'z')) result += tolower(c); } diff --git a/engines/ags/tests/game_scanner.h b/engines/ags/tests/game_scanner.h index b87a41190c46..bf9d70059f02 100644 --- a/engines/ags/tests/game_scanner.h +++ b/engines/ags/tests/game_scanner.h @@ -41,6 +41,7 @@ class GameScanner { private: typedef Common::Array EntryArray; EntryArray _games; + EntryArray _oldGames; private: /** * Scan a folder for AGS games From cb0bf50e832df4ce16a3da3072ab09c23397f0d1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 31 Jan 2021 18:13:35 -0800 Subject: [PATCH 196/215] AGS: In progress adding pre-2.5 AGS game detection entries --- engines/ags/detection_tables.h | 201 ++++++++++++++++++++++++++++++--- 1 file changed, 188 insertions(+), 13 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 2374d76e9ca4..a3e650f20e13 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -26,7 +26,71 @@ const PlainGameDescriptor GAME_NAMES[] = { { "ags", "Adventure Game Studio Game" }, // Pre-2.5 games that aren't supported by the current AGS engine + { "6da", "The 6 Day Assassin" }, + { "achristmastale", "A Christmas Tale" }, + { "adayinthefuture", "A Day In The Future" }, + { "adventuregame", "Adventure Game" }, + { "bertthenewsreader", "Bert the Newsreader" }, + { "bookofspells1", "Book of Spells 1" }, + { "bookofspells2", "Book of Spells 2" }, + { "bookofspells3", "Book of Spells 3" }, + { "bluecupontherun", "BLUECUP - on the run" }, + { "calsoon", "Calsoon" }, + { "demonslayer1", "Demon Slayer 1" }, + { "demonslayer2", "Demon Slayer 2" }, + { "demonslayer3", "Demon Slayer 3" }, + { "dirkchafberg", "Dirk Chafberg" }, + { "earwigisangry", "Earwig Is Angry!" }, + { "erniesbigadventure1", "Ernie's Big Adventure" }, + { "erniesbigadventure2", "Ernie's Big Adventure 2" }, + { "eyesofthejadesphinx", "Eyes of the Jade Sphinx" }, + { "gaeafallen", "Gaea Fallen" }, + { "grannyzombiekiller", "Granny Zombiekiller in: Mittens Murder Mystery" }, + { "gregsmountainousadventure", "Greg's Mountainous Adventure" }, + { "hermit", "Hermit" }, + { "jamesbondage", "James Bondage" }, + { "jinglebells", "Jingle Bells" }, + { "larryvales1", "Larry Vales: Traffic Division" }, + { "larryvales2", "Larry Vales II: Dead Girls are Easy" }, + { "lassi", "Lassi and Roger" }, + { "littlejonnyevil", "Little Jonny Evil" }, + { "littlewillie", "Little Willie" }, + { "ludwig", "VonLudwig" }, + { "momsquest", "Mom's Quest" }, + { "monkeyplank", "Monkey Plank" }, + { "moosewars", "Moose Wars: Desire For More Cows" }, + { "murder", "Murder" }, + { "nightoftheplumber", "Night of the Plumber" }, + { "novomestro", "Novo Mestro" }, + { "permanentdaylight", "Permanent Daylight" }, + { "perpetrator", "Perpetrator" }, + { "pointblank", "Point Blank" }, + { "pornquest", "Porn Quest" }, { "qfg412", "Quest for Glory 4 1/2" }, + { "raymondskeys", "Raymond's Keys" }, + { "richardlonghurst", "Richard Longhurst and the Box That At" }, + { "rickylonghurst", "Ricky Longhurst and the Box that Ate Time" }, + { "robblanc1", "Rob Blanc I: Better Days of a Defender of the Universe" }, + { "robblanc2", "Rob Blanc II: Planet of the Pasteurised Pestilence" }, + { "robblanc3", "Rob Blanc III: The Temporal Terrorists" }, + { "rodekill", "Rode Kill: A Day In the Life" }, + { "rodequest", "Rode Quest" }, + { "samthepiratemonkey", "Sam The Pirate Monkey" }, + { "slackerquest", "Slacker Quest" }, + { "snailquest1", "Snail Quest" }, + { "snailquest2", "Snail Quest 2" }, + { "snailquest3", "Snail Quest 3" }, + { "sol", "Sol" }, + { "space", "Space" }, + { "superdisk", "Superdisk" }, + { "thecrownofgold", "The Crown of Gold" }, + { "theisland", "The Island" }, + { "thendor", "Thendor" }, + { "thewarp", "The Warp" }, + { "tulliesworld1", "Tullie's World 1: The Roving of Candale" }, + { "tvquest", "TV Quest" }, + { "waitkey", "WaitKey();" }, + { "winfry", "Winfry" }, // Post-2.5 games that are likely supported by the AGS engine { "5daysastranger", "5 Days A Stranger" }, @@ -53,6 +117,8 @@ const PlainGameDescriptor GAME_NAMES[] = { { "qfi", "Quest for Infamy" }, { "resonance", "Resonance" }, { "unavowed", "Unavowed" }, + { "whokilledkennyrogers", "Who Killed Kenny Rogers" }, + { "winfry", "Winfry" }, // Unsorted games { "10waysfromsunday", "10 Ways from Sunday" }, @@ -442,7 +508,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "gnrblexags", "Gnrblex_AGS" }, { "goneboatfishin", "Gone Boat Fishin'" }, { "goodmorningmrgingerbread", "Good Morning, Mr. Gingerbread!" }, - { "goodsantabadsanta", "GoodSanta, BadSanta" }, + { "goodsantabadsanta", "Good Santa, Bad Santa" }, { "gotalight", "Got a Light?" }, { "gpslostadventure", "G P's Lost Adventure" }, { "graveyard", "Graveyard" }, @@ -890,7 +956,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "schwarzweissrot", "SchwarzWeissRot" }, { "scnider", "Scnider" }, { "scytheisland", "Scythe Island" }, - { "searchforsanitydemo", "Search for Sanity Demo" }, + { "searchforsanity", "Search for Sanity" }, { "seashells", "Seashells" }, { "seasongreetings2002", "Season Greetings 2002" }, { "secretquestremake", "Secret Quest Remake" }, @@ -921,10 +987,10 @@ const PlainGameDescriptor GAME_NAMES[] = { { "sleepyisland", "Sleepy Island" }, { "slimequestforpizza", "Slime-Quest for Pizza" }, { "slugprincess", "SlugPrincess" }, - { "sma21", "SMA 2.1" }, - { "sma31", "SMA 3.1" }, - { "sma4", "SMA 4" }, - { "smavi", "SMA VI" }, + { "sma2", "Second Moon Adventure Part 2" }, + { "sma3", "Second Moon Adventure Part 3 - Rest In Peace" }, + { "sma4", "Second Moon Adventure Part 4" }, + { "sma6", "Second Moon Adventure Part VI" }, { "smileysquest", "Smiley's Quest" }, { "smileysquest2", "Smiley's Quest 2" }, { "smoothhide", "Smooth Hide" }, @@ -1152,7 +1218,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "wcedit", "WCEdit... " }, { "wearevectors", "We Are Vectors" }, { "welcometodarklake", "Welcome to Dark Lake" }, - { "wet", "WET " }, + { "wet", "WET" }, { "what", "what!" }, { "whatisthatthing", "what is that thing" }, { "whatlinusbruckmansees", "What Linus Bruckman Sees" }, @@ -1190,8 +1256,14 @@ const PlainGameDescriptor GAME_NAMES[] = { #define UNSUPPORTED_ENTRY(ID, FILENAME, MD5, SIZE) \ {{ ID, nullptr, AD_ENTRY1s(FILENAME, MD5, SIZE), Common::EN_ANY, \ Common::kPlatformUnknown, ADGF_UNSTABLE, GUIO0() }, nullptr } +#define UNSUPPORTED_DEMO(ID, FILENAME, MD5, SIZE) \ + {{ ID, "Demo", AD_ENTRY1s(FILENAME, MD5, SIZE), Common::EN_ANY, \ + Common::kPlatformUnknown, ADGF_UNSTABLE | ADGF_DEMO, GUIO0() }, nullptr } + #define ENGLISH_ENTRY(ID, FILENAME, MD5, SIZE) \ UNSUPPORTED_ENTRY(ID, FILENAME, MD5, SIZE) +#define ENGLISH_DEMO(ID, FILENAME, MD5, SIZE) \ + UNSUPPORTED_DEMO(ID, FILENAME, MD5, SIZE) #define ENGLISH_PLUGIN(ID, FILENAME, MD5, SIZE, PLUGIN_ARR) \ {{ ID, nullptr, AD_ENTRY1s(FILENAME, MD5, SIZE), Common::EN_ANY, \ @@ -1202,8 +1274,111 @@ static const PluginVersion AGSCREDITZ_11[] = { { "agscreditz", 11 }, { nullptr, const AGSGameDescription GAME_DESCRIPTIONS[] = { // Pre-2.5 games that aren't supported by the current AGS engine + UNSUPPORTED_ENTRY("6da", "6da.exe", "9027912819f3a319ed9de0fd855310c3", 1608073), + UNSUPPORTED_DEMO("achristmastale", "tale.exe", "094135f05cf14fc3903e0d3697911a4e", 1484122), + UNSUPPORTED_ENTRY("adayinthefuture", "space.exe", "ecd0793124fbc9b89c6d11162e3b5851", 4120328), + UNSUPPORTED_ENTRY("adventuregame", "adventure.exe", "221637e5d62e2ca3cc146846ab0b2e49", 5533207), + UNSUPPORTED_ENTRY("bertthenewsreader", "bert.exe", "80bdce9a1052e896c7cba6a4334cecce", 2814934), + UNSUPPORTED_ENTRY("bookofspells1", "ac2game.dat", "fe66cb08bcffd094c159cd4ee72bacd3", 3442073), + UNSUPPORTED_ENTRY("bookofspells2", "ac2game.dat", "9df87a8e5bbcc7206b001c0b8316b7f9", 3263169), + UNSUPPORTED_ENTRY("bookofspells3", "ac2game.dat", "9f0181393bdceb2c0bbdb06634714023", 4806518), + UNSUPPORTED_ENTRY("bluecupontherun", "ac2game.dat", "c290455f00f630c8a52c7eceb7c663eb", 1995708), + UNSUPPORTED_ENTRY("calsoon", "calsoon.exe", "5477f4ed8f860427d1492548b677073c", 2865508), + UNSUPPORTED_ENTRY("demonslayer1", "mags.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 3820347), + UNSUPPORTED_ENTRY("demonslayer2", "bert.exe", "0c057c5e6df6f45772286986ab7b7a5b", 1726766), + UNSUPPORTED_ENTRY("demonslayer3", "tiler.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2586532), + UNSUPPORTED_ENTRY("dirkchafberg", "ac2game.dat", "be7bec4a433beb5085184b64119351c8", 1906822), + UNSUPPORTED_ENTRY("earwigisangry", "earwig.exe", "04eedea9846d380d6d9a120f657daa43", 2371856), + UNSUPPORTED_ENTRY("erniesbigadventure1", "magsjune.exe", "fc5f54dcfc82d3b991f670490a316958", 8814849), + UNSUPPORTED_ENTRY("erniesbigadventure2", "magsjuly.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 6647578), + UNSUPPORTED_ENTRY("eyesofthejadesphinx", "jade.exe", "f2fe94ab604612e4595f3c79b0245529", 10763660), + UNSUPPORTED_ENTRY("gaeafallen", "gaea_fallen.exe", "80bdce9a1052e896c7cba6a4334cecce", 11273205), + UNSUPPORTED_ENTRY("grannyzombiekiller", "mags.exe", "0c057c5e6df6f45772286986ab7b7a5b", 12855495), + UNSUPPORTED_ENTRY("gregsmountainousadventure", "mags.exe", "80a17966fc547849d43646acf89de296", 2112993), + UNSUPPORTED_ENTRY("hermit", "hermit.exe", "4689069dd6b241e38311d0586e610a8d", 13995403), + UNSUPPORTED_ENTRY("jamesbondage", "jbdos.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 2056737), + UNSUPPORTED_ENTRY("jinglebells", "jinglebells.exe", "385a593828b1edb194e984ce55cda65e", 1620588), + UNSUPPORTED_ENTRY("larryvales1", "larryvtd.exe", "610b7a3d1fd90f24d2218aa26b29d8ca", 3129645), + UNSUPPORTED_ENTRY("larryvales2", "dead.exe", "be48a6b0b81a71d34a41930623c065f1", 3946993), + UNSUPPORTED_ENTRY("lassi", "lassi.exe", "ed778afb4f46c3f2a70d330532a83a2f", 3681914), + UNSUPPORTED_ENTRY("littlejonnyevil", "lje.exe", "e93037e8efc7abc19b8978903ef5b409", 2133182), + UNSUPPORTED_ENTRY("littlewillie", "ac2game.dat", "239b11ab644222c67d981494766a3c25", 254128), + UNSUPPORTED_ENTRY("ludwig", "ludwig.exe", "727a30f9244441ad57a76086f4faa779", 3658869), + UNSUPPORTED_ENTRY("momsquest", "mom's quest.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 3173896), + UNSUPPORTED_ENTRY("monkeyplank", "plank.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 815948), + UNSUPPORTED_ENTRY("moosewars", "moose.exe", "f4585823c1b4ce97d78c8acb433bec52", 1448684), + UNSUPPORTED_ENTRY("murder", "murder.exe", "221637e5d62e2ca3cc146846ab0b2e49", 935799), + UNSUPPORTED_ENTRY("nightoftheplumber", "night of the plumber.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1703896), + UNSUPPORTED_ENTRY("novomestro", "novo.exe", "07f9921784124d9e09f39bb831e06131", 1122507), + UNSUPPORTED_ENTRY("permanentdaylight", "daylight.exe", "07f9921784124d9e09f39bb831e06131", 1799958), + UNSUPPORTED_ENTRY("perpetrator", "ac2game.dat", "56ef979be112e122e24d0cc8caea4ea4", 994303), + UNSUPPORTED_DEMO("pointblank", "future.exe", "385a593828b1edb194e984ce55cda65e", 1379714), + UNSUPPORTED_ENTRY("pornquest", "porn.exe", "04eedea9846d380d6d9a120f657daa43", 1012323), UNSUPPORTED_ENTRY("qfg412", "qfg.exe", "8b21668ca462b0b6b35df43c5902b074", 26674790), - + UNSUPPORTED_ENTRY("qfg412", "qfg.exe", "9027912819f3a319ed9de0fd855310c3", 26954823), + UNSUPPORTED_ENTRY("raymondskeys", "keys.exe", "e016cb68731d0e38fe97905dbf0d5b36", 1032178), + UNSUPPORTED_ENTRY("richardlonghurst", "rlbat-win.exe", "04eedea9846d380d6d9a120f657daa43", 7935723), + UNSUPPORTED_ENTRY("rickylonghurst", "bleach.exe", "9027912819f3a319ed9de0fd855310c3", 1174829), + UNSUPPORTED_ENTRY("robblanc1", "ac2game.dat", "29c2ced2f2e6ad764e4249b4e4c45bba", 920415), + UNSUPPORTED_ENTRY("robblanc2", "ac2game.dat", "dd6c52e5a6e9b70efef4654769f11c69", 2056386), + UNSUPPORTED_ENTRY("robblanc3", "ac2game.dat", "8f8264de3c1bd91e26b84fe37fb5e53e", 2828959), + UNSUPPORTED_ENTRY("rodekill", "rodekill.exe", "72f3c950b4d9d14580a11db885a63310", 11995954), + UNSUPPORTED_ENTRY("rodequest", "rodequest1.exe", "72f3c950b4d9d14580a11db885a63310", 1196458), + UNSUPPORTED_ENTRY("samthepiratemonkey", "monkey.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1401414), + UNSUPPORTED_ENTRY("slackerquest", "ac2game.dat", "e0998f2d2e14a55aae2291fdfab1ce7d", 1306492), + UNSUPPORTED_ENTRY("snailquest1", "snailquest.exe", "dd69243e3cc9e955215e0d556301b58e", 1095860), + UNSUPPORTED_ENTRY("snailquest2", "sq2.exe", "1bccd2edef19abc99e9683519d80c0e0", 955614), + UNSUPPORTED_ENTRY("snailquest3", "sq3.exe", "1bccd2edef19abc99e9683519d80c0e0", 1501892), + UNSUPPORTED_ENTRY("sol", "sol.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 4702799), + UNSUPPORTED_ENTRY("space", "space.exe", "094135f05cf14fc3903e0d3697911a4e", 3790026), + UNSUPPORTED_ENTRY("superdisk", "superdisk.exe", "80bdce9a1052e896c7cba6a4334cecce", 1304065), + UNSUPPORTED_ENTRY("thecrownofgold", "the crown of gold.exe", "e407143be000e44f113ba5ff1fbd17f9", 1971515), + UNSUPPORTED_ENTRY("theisland", "island.exe", "e93037e8efc7abc19b8978903ef5b409", 1814801), + UNSUPPORTED_ENTRY("thendor", "ac2game.dat", "b9c2ad76574c08bbcfd56eb1b49d2cd3", 8580708), + UNSUPPORTED_ENTRY("thewarp", "warp.exe", "9027912819f3a319ed9de0fd855310c3", 881957), + UNSUPPORTED_ENTRY("tulliesworld1", "candale.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 3936603), + UNSUPPORTED_ENTRY("tvquest", "mags.exe", "fc5f54dcfc82d3b991f670490a316958", 1318019), + UNSUPPORTED_DEMO("waitkey", "ac2game.dat", "8ddf3744922101e33305dfcd06e3b682", 445197), + UNSUPPORTED_ENTRY("whokilledkennyrogers", "mags.exe", "ed778afb4f46c3f2a70d330532a83a2f", 1240103), + UNSUPPORTED_ENTRY("winfry", "fry.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 4164041), +#ifdef TODO + UNSUPPORTED_ENTRY("", "carver2.exe", "ed778afb4f46c3f2a70d330532a83a2f", 6265594), + UNSUPPORTED_ENTRY("", "dem four.exe", "426e34f40e0dc5285af3fb5fc32a220e", 5110674), + UNSUPPORTED_ENTRY("", "mags.exe", "0c057c5e6df6f45772286986ab7b7a5b", 12855495), + UNSUPPORTED_ENTRY("", "qfc.exe", "04eedea9846d380d6d9a120f657daa43", 2038696), + UNSUPPORTED_ENTRY("", "qfc.exe", "04eedea9846d380d6d9a120f657daa43", 2038696), + UNSUPPORTED_ENTRY("", "rollinfoy.exe", "19f4045333d9c823a5439d0447d55985", 3454107), + UNSUPPORTED_ENTRY("", "tom mato's grand wing-ding.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2735158), + UNSUPPORTED_ENTRY("", "fart.exe", "fc5f54dcfc82d3b991f670490a316958", 1138006), + UNSUPPORTED_ENTRY("", "thetower.exe", "9027912819f3a319ed9de0fd855310c3", 3431385), + UNSUPPORTED_ENTRY("", "mtg.exe", "ed778afb4f46c3f2a70d330532a83a2f", 1618544), + UNSUPPORTED_ENTRY("", "assassin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2659741), + UNSUPPORTED_ENTRY("", "burns.exe", "094135f05cf14fc3903e0d3697911a4e", 2120885), + UNSUPPORTED_ENTRY("", "ripp.exe", "426e34f40e0dc5285af3fb5fc32a220e", 10489586), + UNSUPPORTED_ENTRY("", "indy.exe", "094135f05cf14fc3903e0d3697911a4e", 1545150), + UNSUPPORTED_ENTRY("", "aaron.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 1788404), + UNSUPPORTED_ENTRY("", "adventure.exe", "221637e5d62e2ca3cc146846ab0b2e49", 5533207), + UNSUPPORTED_ENTRY("", "bq2.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 2540006), + UNSUPPORTED_ENTRY("", "comp.exe", "094135f05cf14fc3903e0d3697911a4e", 2054366), + UNSUPPORTED_ENTRY("", "dart.exe", "ed778afb4f46c3f2a70d330532a83a2f", 736848), + UNSUPPORTED_ENTRY("", "burro.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 2209309), + UNSUPPORTED_ENTRY("", "exile.exe", "aad0a09714fab4de51e5488da48fd5d4", 13421451), + UNSUPPORTED_ENTRY("", "firewall demo.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 2839412), + UNSUPPORTED_ENTRY("", "lupo.exe", "19f4045333d9c823a5439d0447d55985", 1856459), + UNSUPPORTED_ENTRY("", "0112.men in brown.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2072392), + UNSUPPORTED_ENTRY("", "moose.exe", "f4585823c1b4ce97d78c8acb433bec52", 1448684), + UNSUPPORTED_ENTRY("", "greywin.exe", "80bdce9a1052e896c7cba6a4334cecce", 1283447), + UNSUPPORTED_ENTRY("", "mtsodos.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 777967), + UNSUPPORTED_ENTRY("", "mtsowin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1076035), + UNSUPPORTED_ENTRY("", "nw1demo.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1539596), + UNSUPPORTED_ENTRY("", "odysseus.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2799113), + UNSUPPORTED_ENTRY("", "pd.exe", "ecd0793124fbc9b89c6d11162e3b5851", 3853394), + UNSUPPORTED_ENTRY("", "pqwin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2500089), + UNSUPPORTED_ENTRY("", "moonsdt.exe", "9027912819f3a319ed9de0fd855310c3", 1276725), + UNSUPPORTED_ENTRY("", "stickmen.exe", "094135f05cf14fc3903e0d3697911a4e", 2145142), + UNSUPPORTED_ENTRY("", "teamwork.exe", "538274077115c6d8b4a0927dd3cceeac", 1096149), + UNSUPPORTED_ENTRY("", "blackjack.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1153092), +#endif // Post-2.5 games that are likely supported by the AGS engine ENGLISH_ENTRY("5daysastranger", "5days.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4440143), ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "465f972675db2da6040518221af5b0ba", 4693374), @@ -1632,7 +1807,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("gnrblexags", "Gnrblex_AGS.exe", "476a1a39d43ea27577eacf907173e2c1", 85038656), ENGLISH_ENTRY("goneboatfishin", "Gone Boat Fishin'.exe", "bdd1df0484e296faa348ffcb03e16273", 72936045), ENGLISH_ENTRY("goodmorningmrgingerbread", "mister_gingerbread.exe", "b42f80733b6bd1ded5e29be2c683afa8", 7084332), - ENGLISH_ENTRY("goodsantabadsanta", "X-Mags.exe", "71ca0d6c1c699595f28a2125948d4a84", 1966547), + ENGLISH_ENTRY("goodsantabadsanta", "x-mags.exe", "71ca0d6c1c699595f28a2125948d4a84", 1966547), ENGLISH_ENTRY("gotalight", "gotalight.exe", "daa21f03e41b5d3e7fd7558be3f8616e", 4019593), ENGLISH_ENTRY("gpslostadventure", "G.P.s Lost Adventure [Wells8892].exe", "06a03fe35791b0578068ab1873455463", 4181945), ENGLISH_ENTRY("graveyard", "Graveyard.exe", "955b711b21d7a2df6af1bb0cccccbb08", 13699789), @@ -2092,7 +2267,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("schwarzweissrot", "SchwarzWeissRot.exe", "495d45fb8adfd49690ae3b97921feec6", 82913128), ENGLISH_ENTRY("scnider", "scnider.exe", "3128b9f90e2f954ba704414ae854d10b", 1189237), ENGLISH_ENTRY("scytheisland", "Scythe.exe", "0500aacb6c176d47ac0f8158f055db83", 7119760), - ENGLISH_ENTRY("searchforsanitydemo", "sfs.exe", "308d35bc34e9df29d8acce615593e3e7", 9097147), + ENGLISH_DEMO("searchforsanity", "sfs.exe", "308d35bc34e9df29d8acce615593e3e7", 9097147), ENGLISH_ENTRY("seashells", "Shells.exe", "0500aacb6c176d47ac0f8158f055db83", 6355325), ENGLISH_ENTRY("seasongreetings2002", "xmas2002.exe", "97d700529f5cc826f230c27acf81adfd", 4263336), ENGLISH_ENTRY("secretquestremake", "secretquest.exe", "f120690b506dd63cd7d1112ea6af2f77", 2121159), @@ -2123,10 +2298,10 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("sleepyisland", "Sleepy Island.exe", "465f972675db2da6040518221af5b0ba", 20270790), ENGLISH_ENTRY("slimequestforpizza", "slime.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 1661109), ENGLISH_ENTRY("slugprincess", "SlugPrincess.exe", "28f82e420b82d07651b68114f90223c8", 12132209), - ENGLISH_ENTRY("sma21", "sma21.exe", "02094e217c23e1d40a84891ee95010cb", 7093110), - ENGLISH_ENTRY("sma31", "sma31.exe", "4d17844029d8910fbaae1bdc99e250f2", 4961734), + ENGLISH_ENTRY("sma2", "sma21.exe", "02094e217c23e1d40a84891ee95010cb", 7093110), + ENGLISH_ENTRY("sma3", "sma31.exe", "4d17844029d8910fbaae1bdc99e250f2", 4961734), ENGLISH_ENTRY("sma4", "smavier.exe", "02094e217c23e1d40a84891ee95010cb", 2447360), - ENGLISH_ENTRY("smavi", "sma6.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3735081), + ENGLISH_ENTRY("sma6", "sma6.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3735081), ENGLISH_ENTRY("smileysquest", "Smiley.exe", "90413e9ae57e222f8913b09d2bc847bc", 4938049), ENGLISH_ENTRY("smileysquest2", "mags.exe", "3128b9f90e2f954ba704414ae854d10b", 2108492), ENGLISH_ENTRY("smoothhide", "SmoothHide.exe", "b142b43c146c25443a1d155d441a6a81", 10006680), From 6b8b05ad12d4914944f71615d55c22677ecff40f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 1 Feb 2021 18:58:38 -0800 Subject: [PATCH 197/215] AGS: More pre 2.5 detection entries --- engines/ags/detection_tables.h | 215 ++++++++++++++++++++------------- 1 file changed, 132 insertions(+), 83 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index a3e650f20e13..5d73045d4b3e 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -27,68 +27,110 @@ const PlainGameDescriptor GAME_NAMES[] = { // Pre-2.5 games that aren't supported by the current AGS engine { "6da", "The 6 Day Assassin" }, + { "aaronsepicjourney", "Aaron's Epic Journey" }, + { "aceduswell", "Ace Duswell - Where's The Ace" }, { "achristmastale", "A Christmas Tale" }, { "adayinthefuture", "A Day In The Future" }, { "adventuregame", "Adventure Game" }, + { "asapadventure", "ASAP Adventure" }, { "bertthenewsreader", "Bert the Newsreader" }, + { "bobsquest2", "Bob's Quest 2: The quest for the AGS Blue cup award " }, { "bookofspells1", "Book of Spells 1" }, { "bookofspells2", "Book of Spells 2" }, { "bookofspells3", "Book of Spells 3" }, { "bluecupontherun", "BLUECUP - on the run" }, { "calsoon", "Calsoon" }, + { "carverisland1", "The Secret of Carver Island" }, + { "carverisland2", "Carver Island 2: Mrs. Rodriguez's Revenge" }, + { "chamber", "Chamber" }, + { "compensation", "Compensation" }, + { "darts", "Darts" }, { "demonslayer1", "Demon Slayer 1" }, { "demonslayer2", "Demon Slayer 2" }, { "demonslayer3", "Demon Slayer 3" }, + { "demonslayer4", "Demon Slayer 4" }, + { "deepbright", "Deepbright" }, { "dirkchafberg", "Dirk Chafberg" }, { "earwigisangry", "Earwig Is Angry!" }, + { "eclair1", "Eclair 1" }, + { "eclair2", "Eclair 2" }, + { "elburro", "El Burro" }, { "erniesbigadventure1", "Ernie's Big Adventure" }, { "erniesbigadventure2", "Ernie's Big Adventure 2" }, + { "exile", "Exile" }, { "eyesofthejadesphinx", "Eyes of the Jade Sphinx" }, + { "firewall", "Firewall" }, + { "floyd", "Floyd" }, { "gaeafallen", "Gaea Fallen" }, + { "gorthor", "Gorther of the Cave People" }, { "grannyzombiekiller", "Granny Zombiekiller in: Mittens Murder Mystery" }, { "gregsmountainousadventure", "Greg's Mountainous Adventure" }, + { "greysgreytadv", "Mr. Grey's Greyt Adventure" }, { "hermit", "Hermit" }, { "jamesbondage", "James Bondage" }, { "jinglebells", "Jingle Bells" }, + { "kidnapped", "Kidnapped" }, { "larryvales1", "Larry Vales: Traffic Division" }, { "larryvales2", "Larry Vales II: Dead Girls are Easy" }, + { "larryvales3", "Larry Vales III: Time Heals All 'Burns" }, { "lassi", "Lassi and Roger" }, + { "lassiandrogermeetgod", "Lassi and Roger Meet God" }, + { "lassiquesti", "Lassi Quest I" }, { "littlejonnyevil", "Little Jonny Evil" }, { "littlewillie", "Little Willie" }, + { "lsl2remake", "Leisure Suit Larry 2 Point and Click" }, { "ludwig", "VonLudwig" }, + { "lupoinutile", "Lupo Inutile" }, + { "mafio", "Mafio" }, + { "meninbrown", "Men In Brown" }, + { "midtownshootout", "Anton Ulvfot's Mid-Town Shootout" }, { "momsquest", "Mom's Quest" }, { "monkeyplank", "Monkey Plank" }, { "moosewars", "Moose Wars: Desire For More Cows" }, { "murder", "Murder" }, + { "nicholaswolfe1", "Nicholas Wolfe part I: Framed" }, { "nightoftheplumber", "Night of the Plumber" }, { "novomestro", "Novo Mestro" }, + { "odysseus", "The Trials of Odysseus Kent" }, { "permanentdaylight", "Permanent Daylight" }, { "perpetrator", "Perpetrator" }, + { "pizzaquest", "Pizza Quest" }, { "pointblank", "Point Blank" }, { "pornquest", "Porn Quest" }, + { "qfc", "Quest For Colours" }, { "qfg412", "Quest for Glory 4 1/2" }, + { "racingmanager", "Racing Manager" }, { "raymondskeys", "Raymond's Keys" }, + { "red", "Red" }, { "richardlonghurst", "Richard Longhurst and the Box That At" }, { "rickylonghurst", "Ricky Longhurst and the Box that Ate Time" }, + { "ripp", "RIPP" }, { "robblanc1", "Rob Blanc I: Better Days of a Defender of the Universe" }, { "robblanc2", "Rob Blanc II: Planet of the Pasteurised Pestilence" }, { "robblanc3", "Rob Blanc III: The Temporal Terrorists" }, { "rodekill", "Rode Kill: A Day In the Life" }, { "rodequest", "Rode Quest" }, + { "rollinfoy", "Rollinfoy" }, { "samthepiratemonkey", "Sam The Pirate Monkey" }, + { "secondmoonadv1", "Second Moon Adventure Part 1 - Night" }, { "slackerquest", "Slacker Quest" }, { "snailquest1", "Snail Quest" }, { "snailquest2", "Snail Quest 2" }, { "snailquest3", "Snail Quest 3" }, { "sol", "Sol" }, { "space", "Space" }, + { "stickmen", "Stickmen" }, { "superdisk", "Superdisk" }, { "thecrownofgold", "The Crown of Gold" }, + { "theinexperiencedassassin", "The Inexperienced Assassin" }, { "theisland", "The Island" }, { "thendor", "Thendor" }, + { "thetower", "The Tower" }, { "thewarp", "The Warp" }, + { "tommato", "Tom Mato's Grand Wing-Ding" }, { "tulliesworld1", "Tullie's World 1: The Roving of Candale" }, { "tvquest", "TV Quest" }, + { "uishowoff", "Interface Show-off" }, { "waitkey", "WaitKey();" }, { "winfry", "Winfry" }, @@ -128,10 +170,11 @@ const PlainGameDescriptor GAME_NAMES[] = { { "3piggiesalpha", "3piggiesAlpha" }, { "46memorylane", "46 Memory Lane" }, { "4ofclubs", "4 of Clubs" }, + { "5oclocklock", "5-O'clock Lock" }, { "6daysasacrifice", "6 Days A Sacrifice" }, { "6mornings", "6mornings" }, { "aazor", "Aazor" }, - { "abducted", "ABDUCTED" }, + { "abducted", "Abducted" }, { "absent", "Absent" }, { "absentparti", "Absent - Part I" }, { "access", "_Access" }, @@ -163,6 +206,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "agsdarts", "AGS Darts" }, { "agsinvaders", "AGS Invaders" }, { "agsjukebox", "AGS JukeBox" }, + { "agsmittensshooter", "AGS Mittens Shooter" }, { "agsmoduletester", "Ags Module Tester" }, { "agsyahtzee2", "AGS Yahtzee 2" }, { "agsyathzee", "AGS Yathzee" }, @@ -272,6 +316,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "boom", "Boom" }, { "bowserquirkquest", "Bowser Quirk Quest" }, { "box", "Box" }, + { "boxfight", "Boxfight" }, { "boyindahood", "Boy in da hood" }, { "bradbradsonkeyquest", "Brad Bradson: Key Quest" }, { "breakdownbyonedollar", "Breakdown by OneDollar" }, @@ -316,7 +361,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "cirquedezale", "Cirque de Zale" }, { "claire", "Claire" }, { "classnotesv11", "Class Notes v1.1" }, - { "clex", "Clex" }, { "clipl2heblinna", "Clip l2heb linna" }, { "clubofevil", "Club of Evil" }, { "coeldeckaflightgame", "Coel Decka Flight Game" }, @@ -337,6 +381,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "cosmosquestiii", "Cosmos Quest III" }, { "cougarsquestforfreedom", "Cougar's Quest for Freedom" }, { "counterfeit", "Counterfeit" }, + { "coupdecup", "Coup de Cup" }, { "cow", "cow" }, { "coyote", "Coyote" }, { "craftofevil", "Craft Of Evil" }, @@ -460,7 +505,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "feuersturmkapitel2", "Feuersturm - Kapitel 2" }, { "feuersturmkapitel3", "Feuersturm - Kapitel 3" }, { "fifa2003pro", "Fifa2003Pro" }, - { "fight", "Fight" }, { "fightgame", "Fight Game" }, { "fireflystory3d", "Firefly story 3D" }, { "flamebarrel", "Flame Barrel" }, @@ -514,6 +558,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "graveyard", "Graveyard" }, { "gremlin", "Gremlin" }, { "grizzlygooseofgosse", "Grizzly Goose of Gosse" }, + { "grok", "Grok" }, { "grr", "Grr!" }, { "guardiansofgold", "Guardians of Gold" }, { "guyslug", "Guy Slug" }, @@ -558,7 +603,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "huongjiaoping", "Huong Jiao Ping" }, { "huxzadventure", "Huxz Adventure" }, { "hydeandseek", "Hyde and Seek" }, - { "iaman00b11omgwtflol", "i am a n00b!!1!!1!OMG WTF LOL" }, { "iamjason", "IAMJASON" }, { "iforgot", "I forgot..." }, { "igs", "IGS" }, @@ -599,6 +643,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "joesmiserablelife", "Joe's Miserable Life" }, { "johnharrissafrakincse", "John Harris ?s a f?ra? kincse" }, { "johnjebediahgunelisoladisepheret", "John Jebediah Gun e l'Isola di Sepheret" }, + { "johnlosthiskey", "John Lost his key" }, { "johnnyrocket", "Johnny_Rocket" }, { "johnsinclairvoodooinlondon", "John Sinclair - Voodoo in London" }, { "jonnysmallvalley", "Jonny Smallvalley" }, @@ -701,16 +746,16 @@ const PlainGameDescriptor GAME_NAMES[] = { { "maniacmansionmania02", "Maniac Mansion Mania 02" }, { "mardsrevengebytk", "Mard's Revenge by TK" }, { "martyausdemall", "Marty aus dem All" }, - { "mastersofsound", "MASTERS OF SOUND" }, + { "mastersofsound", "Masters of Sound" }, { "matttothefuture", "Matt to the Future" }, { "medicaltheoriesofdrkur", "Medical Theories of Dr Kur" }, { "mego2008silvesteredition", "Me Go 2008: Silvester Edition" }, { "megoaway", "Me Go... Away!" }, { "megocannibaljungle", "Me Go Cannibal Jungle!" }, { "megostore", "Me Go Store!" }, - { "melrinthediscipleordeal", "Melrin: The disciple ordeal" }, - { "melrinthedragonmenace", "Melrin: The Dragon Menace" }, - { "melrinthependantquest", "Melrin: The Pendant Quest" }, + { "melrin1", "Melrin: The Disciple Ordeal" }, + { "melrin2", "Melrin: The Pendant Quest" }, + { "melrin3", "Melrin: The Dragon Menace" }, { "meltdrake3chapter1", "Melt & Drake 3 Chapter 1" }, { "memoriesfade", "Memories Fade" }, { "meninhats", "Men In Hats" }, @@ -765,7 +810,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "necroquest", "Necroquest" }, { "nedysadventure", "Nedy's adventure" }, { "nekusnewtrip", "Neku's new trip" }, - { "newgame", "New Game" }, { "nellycootalotv15", "Nelly Cootalot v1.5" }, { "neofeud", "Neofeud" }, { "nesquest", "NES Quest" }, @@ -854,7 +898,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "postmansquest", "Postman's Quest" }, { "powernap", "Power Nap" }, { "powerunlimited", "Power Unlimited" }, - { "pqtadventure", "PQTADVENTURE" }, + { "pqtadventure", "PQT Adventure" }, { "practicescript", "Practice Script" }, { "predatorspreyforplants", "Predators Prey For Plants" }, { "princessandallthekingdom", "Princess and all the kingdom" }, @@ -917,10 +961,10 @@ const PlainGameDescriptor GAME_NAMES[] = { { "roadofdestiny", "Road of Destiny" }, { "roadracer", "Road Racer" }, { "roastmothergoose", "Roast Mother Goose" }, - { "robbertredfordsavestheday", "Robbert Redford saves the day" }, { "robbingtheprincess", "Robbing The Princess" }, - { "robertredford3", "Robert Redford 3" }, - { "robertredfordsavestheday", "Robert Redford saves the day" }, + { "robertredford1", "Robert Redford saves the day Ep 1" }, + { "robertredford2", "Robert Redford saves the day Ep 2" }, + { "robertredford3", "Robert Redford saves the day Ep 3" }, { "robmassacreofchainsawness", "Rob: Massacre of Chainsawness" }, { "robotragedy", "Robotragedy" }, { "robotragedy2", "Robotragedy 2" }, @@ -964,9 +1008,9 @@ const PlainGameDescriptor GAME_NAMES[] = { { "seega16engl5", "seega16_engl_5" }, { "seegame15", "seegame15" }, { "sevendoors", "Seven Doors" }, - { "sga", "SGA" }, + { "stargateadv", "Stargate Adventure" }, { "shadesofgreye", "Shades of Greye" }, - { "shadowsoftheempiretd", "Shadows of the Empire - TD" }, + { "shadowsoftheempire", "Shadows of the Empire" }, { "shailadusithlenqute", "Shai-la du Sith : l'Enqu?te" }, { "shailaofthesith", "Shai-la of the Sith" }, { "shem", "Shem" }, @@ -1006,9 +1050,9 @@ const PlainGameDescriptor GAME_NAMES[] = { { "spacelynxes", "Space Lynxes" }, { "spacepirates", "Space Pirates" }, { "spacepoolalpha", "Space Pool Alpha" }, + { "spacequest3vgapreview", "Space Quest III VGA Preview" }, { "spacequest45", "Space Quest 4.5" }, { "spacequest55demoags", "Space Quest 5.5 demo (AGS)" }, - { "spacequestiiivgapreview", "Space Quest III VGA Preview" }, { "sqm11", "Space Quest Mania 1x1" }, { "sqm12", "Space Quest Mania 1x2" }, { "sqm13", "Space Quest Mania 1x3" }, @@ -1040,7 +1084,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "stediddyip1employment", "Stediddy IP1 - Employment" }, { "stickmeni", "Stickmen I" }, { "stickythestickfigurepart1thecrimsonhouse", "Sticky the Stick Figure Part 1: The Crimson House" }, - { "stinkymcpoopoo", "Stinky McPooPoo" }, { "stranded", "STRANDED" }, { "stranger", "Stranger" }, { "strangerinstickworld", "Stranger in Stickworld" }, @@ -1117,8 +1160,8 @@ const PlainGameDescriptor GAME_NAMES[] = { { "thejourneyhome", "The Journey Home" }, { "thejourneyofiesir", "The Journey of Iesir" }, { "thelastharvest", "The Last Harvest" }, - { "thelastsupperawhodunnit", "THE LAST SUPPER, A WHODUNNIT" }, - { "theloneloserdemo", "The Lone Loser - DEMO" }, + { "thelastsupperawhodunnit", "The Last Supper, A Whodunnit" }, + { "theloneloser", "The Lone Loser" }, { "thelongtrip", "The Long Trip" }, { "themajesticconspiracy", "The Majestic Conspiracy" }, { "themarionette", "The Marionette" }, @@ -1129,6 +1172,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "thenetherworld", "The Netherworld" }, { "thenextcurse", "The Next Curse" }, { "theoraclev11", "The Oracle v1.1" }, + { "thepaparazziprince", "The Paparazzi Prince; and the Quest for Headlines" }, { "thepark", "The Park" }, { "theperfectmurder", "The Perfect Murder" }, { "thephantominheritance", "The Phantom Inheritance" }, @@ -1186,7 +1230,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "twelvethirteenepisode3", "Twelve Thirteen, episode 3" }, { "twentiesflappersvsthemummy", "Twenties Flappers vs The Mummy" }, { "twoofakind", "Two of a Kind" }, - { "uglyfiles", "UGLY FILES" }, + { "uglyfiles", "Ugly Files" }, { "ulitsadimitrova", "Ulitsa Dimitrova" }, { "unboundver10", "Unbound Ver 1.0" }, { "unfinished", "unfinished" }, @@ -1208,7 +1252,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "vohaulsrevengeii", "Vohaul's revenge II" }, { "vpxt2", "V P x T ! 2 !" }, { "waitingfortheloop", "Waiting For the Loop" }, - { "wallyweaseldemo", "Wally Weasel Demo" }, + { "wallyweasel", "The Wacky World of Wally Weasel" }, { "waltersasteroid", "Walters-Asteroid" }, { "warthogs", "Warthogs" }, { "washedashore", "Washed Ashore" }, @@ -1229,7 +1273,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "whowantstoliveforever", "Who wants to live forever?" }, { "williamsnightmare", "Williams Nightmare" }, { "willowhouse", "Willow House" }, - { "willy", "Willy" }, { "winnersdontdodrugs", "Winners Dont' Do Drugs" }, { "winterrose", "Winter Rose" }, { "witch", "Witch" }, @@ -1242,7 +1285,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "worm", "Worm" }, { "wrathofthesolonoids", "Wrath of the Solonoids " }, { "yoda", "Yoda" }, - { "yourgame", "Your Game" }, { "yourlate", "Your late!" }, { "zakmckracken", "Zak McKracken" }, { "zombieattackdemo", "Zombie Attack Demo" }, @@ -1275,110 +1317,118 @@ static const PluginVersion AGSCREDITZ_11[] = { { "agscreditz", 11 }, { nullptr, const AGSGameDescription GAME_DESCRIPTIONS[] = { // Pre-2.5 games that aren't supported by the current AGS engine UNSUPPORTED_ENTRY("6da", "6da.exe", "9027912819f3a319ed9de0fd855310c3", 1608073), + UNSUPPORTED_ENTRY("aaronsepicjourney", "aaron.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 1788404), + UNSUPPORTED_ENTRY("aceduswell", "ace.exe", "be48a6b0b81a71d34a41930623c065f1", 3103822), UNSUPPORTED_DEMO("achristmastale", "tale.exe", "094135f05cf14fc3903e0d3697911a4e", 1484122), UNSUPPORTED_ENTRY("adayinthefuture", "space.exe", "ecd0793124fbc9b89c6d11162e3b5851", 4120328), UNSUPPORTED_ENTRY("adventuregame", "adventure.exe", "221637e5d62e2ca3cc146846ab0b2e49", 5533207), + UNSUPPORTED_ENTRY("asapadventure", "asap.exe", "8f80c91d160e333ab7f6be5208ea0533", 1405072), UNSUPPORTED_ENTRY("bertthenewsreader", "bert.exe", "80bdce9a1052e896c7cba6a4334cecce", 2814934), + UNSUPPORTED_ENTRY("blackjack", "blackjack.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1153092), + UNSUPPORTED_ENTRY("bluecupontherun", "ac2game.dat", "c290455f00f630c8a52c7eceb7c663eb", 1995708), + UNSUPPORTED_ENTRY("bobsquest2", "bq2.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 2540006), UNSUPPORTED_ENTRY("bookofspells1", "ac2game.dat", "fe66cb08bcffd094c159cd4ee72bacd3", 3442073), UNSUPPORTED_ENTRY("bookofspells2", "ac2game.dat", "9df87a8e5bbcc7206b001c0b8316b7f9", 3263169), UNSUPPORTED_ENTRY("bookofspells3", "ac2game.dat", "9f0181393bdceb2c0bbdb06634714023", 4806518), - UNSUPPORTED_ENTRY("bluecupontherun", "ac2game.dat", "c290455f00f630c8a52c7eceb7c663eb", 1995708), UNSUPPORTED_ENTRY("calsoon", "calsoon.exe", "5477f4ed8f860427d1492548b677073c", 2865508), + UNSUPPORTED_ENTRY("carverisland1", "secret.exe", "8f80c91d160e333ab7f6be5208ea0533", 3116071), + UNSUPPORTED_ENTRY("carverisland2", "carver2.exe", "ed778afb4f46c3f2a70d330532a83a2f", 6265594), + UNSUPPORTED_ENTRY("chamber", "indy.exe", "094135f05cf14fc3903e0d3697911a4e", 1545150), + UNSUPPORTED_ENTRY("compensation", "comp.exe", "094135f05cf14fc3903e0d3697911a4e", 2054366), + UNSUPPORTED_ENTRY("darts", "dart.exe", "ed778afb4f46c3f2a70d330532a83a2f", 736848), + UNSUPPORTED_DEMO("deepbright", "tc.exe", "8f80c91d160e333ab7f6be5208ea0533", 3022557), UNSUPPORTED_ENTRY("demonslayer1", "mags.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 3820347), UNSUPPORTED_ENTRY("demonslayer2", "bert.exe", "0c057c5e6df6f45772286986ab7b7a5b", 1726766), UNSUPPORTED_ENTRY("demonslayer3", "tiler.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2586532), + UNSUPPORTED_ENTRY("demonslayer4", "dem four.exe", "426e34f40e0dc5285af3fb5fc32a220e", 5110674), UNSUPPORTED_ENTRY("dirkchafberg", "ac2game.dat", "be7bec4a433beb5085184b64119351c8", 1906822), UNSUPPORTED_ENTRY("earwigisangry", "earwig.exe", "04eedea9846d380d6d9a120f657daa43", 2371856), + UNSUPPORTED_ENTRY("eclair1", "eclair 1.exe", "9fa0358760f1f1bffddd080532f586f0", 1864283), + UNSUPPORTED_ENTRY("eclair2", "eclair 2.exe", "9fa0358760f1f1bffddd080532f586f0", 5644093), + UNSUPPORTED_ENTRY("elburro", "burro.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 2209309), UNSUPPORTED_ENTRY("erniesbigadventure1", "magsjune.exe", "fc5f54dcfc82d3b991f670490a316958", 8814849), UNSUPPORTED_ENTRY("erniesbigadventure2", "magsjuly.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 6647578), + UNSUPPORTED_ENTRY("exile", "exile.exe", "aad0a09714fab4de51e5488da48fd5d4", 13421451), UNSUPPORTED_ENTRY("eyesofthejadesphinx", "jade.exe", "f2fe94ab604612e4595f3c79b0245529", 10763660), + UNSUPPORTED_DEMO("firewall", "firewall demo.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 2839412), + UNSUPPORTED_ENTRY("floyd", "floyd.exe", "9ef5bffe7b85377751c25af806345794", 5477588), UNSUPPORTED_ENTRY("gaeafallen", "gaea_fallen.exe", "80bdce9a1052e896c7cba6a4334cecce", 11273205), + UNSUPPORTED_ENTRY("gorthor", "fart.exe", "fc5f54dcfc82d3b991f670490a316958", 1138006), UNSUPPORTED_ENTRY("grannyzombiekiller", "mags.exe", "0c057c5e6df6f45772286986ab7b7a5b", 12855495), UNSUPPORTED_ENTRY("gregsmountainousadventure", "mags.exe", "80a17966fc547849d43646acf89de296", 2112993), + UNSUPPORTED_ENTRY("greysgreytadv", "greywin.exe", "80bdce9a1052e896c7cba6a4334cecce", 1283447), UNSUPPORTED_ENTRY("hermit", "hermit.exe", "4689069dd6b241e38311d0586e610a8d", 13995403), UNSUPPORTED_ENTRY("jamesbondage", "jbdos.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 2056737), UNSUPPORTED_ENTRY("jinglebells", "jinglebells.exe", "385a593828b1edb194e984ce55cda65e", 1620588), + UNSUPPORTED_ENTRY("kidnapped", "ac2game.dat", "27daca01ccbbbaf02bf6b4b85d5990b4", 1205017), UNSUPPORTED_ENTRY("larryvales1", "larryvtd.exe", "610b7a3d1fd90f24d2218aa26b29d8ca", 3129645), UNSUPPORTED_ENTRY("larryvales2", "dead.exe", "be48a6b0b81a71d34a41930623c065f1", 3946993), + UNSUPPORTED_DEMO("larryvales3", "burns.exe", "094135f05cf14fc3903e0d3697911a4e", 2120885), UNSUPPORTED_ENTRY("lassi", "lassi.exe", "ed778afb4f46c3f2a70d330532a83a2f", 3681914), + UNSUPPORTED_ENTRY("lassiandrogermeetgod", "mtg.exe", "ed778afb4f46c3f2a70d330532a83a2f", 1618544), + UNSUPPORTED_ENTRY("lassiquesti", "lassi.exe", "c391c6676099032440b206189babe76e", 1700368), UNSUPPORTED_ENTRY("littlejonnyevil", "lje.exe", "e93037e8efc7abc19b8978903ef5b409", 2133182), UNSUPPORTED_ENTRY("littlewillie", "ac2game.dat", "239b11ab644222c67d981494766a3c25", 254128), + UNSUPPORTED_ENTRY("lsl2remake", "Larry 2 Point and Click.exe", "a567a00ba22eed9f8640af6e9bd01768", 2381674), UNSUPPORTED_ENTRY("ludwig", "ludwig.exe", "727a30f9244441ad57a76086f4faa779", 3658869), + UNSUPPORTED_ENTRY("lupoinutile", "lupo.exe", "19f4045333d9c823a5439d0447d55985", 1856459), + UNSUPPORTED_ENTRY("mafio", "crimetim.exe", "be48a6b0b81a71d34a41930623c065f1", 1303660), + UNSUPPORTED_ENTRY("meninbrown", "0112.men in brown.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2072392), + UNSUPPORTED_ENTRY("midtownshootout", "mtsowin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1076035), UNSUPPORTED_ENTRY("momsquest", "mom's quest.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 3173896), UNSUPPORTED_ENTRY("monkeyplank", "plank.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 815948), + UNSUPPORTED_ENTRY("moose", "moose.exe", "f4585823c1b4ce97d78c8acb433bec52", 1448684), UNSUPPORTED_ENTRY("moosewars", "moose.exe", "f4585823c1b4ce97d78c8acb433bec52", 1448684), UNSUPPORTED_ENTRY("murder", "murder.exe", "221637e5d62e2ca3cc146846ab0b2e49", 935799), + UNSUPPORTED_DEMO("nicholaswolfe1", "nw1demo.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1539596), UNSUPPORTED_ENTRY("nightoftheplumber", "night of the plumber.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1703896), UNSUPPORTED_ENTRY("novomestro", "novo.exe", "07f9921784124d9e09f39bb831e06131", 1122507), + UNSUPPORTED_ENTRY("odysseus", "odysseus.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2799113), UNSUPPORTED_ENTRY("permanentdaylight", "daylight.exe", "07f9921784124d9e09f39bb831e06131", 1799958), UNSUPPORTED_ENTRY("perpetrator", "ac2game.dat", "56ef979be112e122e24d0cc8caea4ea4", 994303), + UNSUPPORTED_ENTRY("pizzaquest", "pqwin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2500089), UNSUPPORTED_DEMO("pointblank", "future.exe", "385a593828b1edb194e984ce55cda65e", 1379714), UNSUPPORTED_ENTRY("pornquest", "porn.exe", "04eedea9846d380d6d9a120f657daa43", 1012323), + UNSUPPORTED_ENTRY("qfc", "qfc.exe", "04eedea9846d380d6d9a120f657daa43", 2038696), UNSUPPORTED_ENTRY("qfg412", "qfg.exe", "8b21668ca462b0b6b35df43c5902b074", 26674790), - UNSUPPORTED_ENTRY("qfg412", "qfg.exe", "9027912819f3a319ed9de0fd855310c3", 26954823), + UNSUPPORTED_ENTRY("qfg412", "qfg.exe", "9027912819f3a319ed9de0fd855310c3", 26954823), + UNSUPPORTED_ENTRY("racingmanager", "raceman.exe", "465f972675db2da6040518221af5b0ba", 15971689), UNSUPPORTED_ENTRY("raymondskeys", "keys.exe", "e016cb68731d0e38fe97905dbf0d5b36", 1032178), + UNSUPPORTED_ENTRY("red", "red.exe", "be48a6b0b81a71d34a41930623c065f1", 1101194), UNSUPPORTED_ENTRY("richardlonghurst", "rlbat-win.exe", "04eedea9846d380d6d9a120f657daa43", 7935723), UNSUPPORTED_ENTRY("rickylonghurst", "bleach.exe", "9027912819f3a319ed9de0fd855310c3", 1174829), + UNSUPPORTED_ENTRY("ripp", "ripp.exe", "426e34f40e0dc5285af3fb5fc32a220e", 10489586), UNSUPPORTED_ENTRY("robblanc1", "ac2game.dat", "29c2ced2f2e6ad764e4249b4e4c45bba", 920415), UNSUPPORTED_ENTRY("robblanc2", "ac2game.dat", "dd6c52e5a6e9b70efef4654769f11c69", 2056386), UNSUPPORTED_ENTRY("robblanc3", "ac2game.dat", "8f8264de3c1bd91e26b84fe37fb5e53e", 2828959), UNSUPPORTED_ENTRY("rodekill", "rodekill.exe", "72f3c950b4d9d14580a11db885a63310", 11995954), UNSUPPORTED_ENTRY("rodequest", "rodequest1.exe", "72f3c950b4d9d14580a11db885a63310", 1196458), + UNSUPPORTED_ENTRY("rollinfoy", "rollinfoy.exe", "19f4045333d9c823a5439d0447d55985", 3454107), UNSUPPORTED_ENTRY("samthepiratemonkey", "monkey.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1401414), + UNSUPPORTED_ENTRY("secondmoonadv1", "moonsdt.exe", "9027912819f3a319ed9de0fd855310c3", 1276725), UNSUPPORTED_ENTRY("slackerquest", "ac2game.dat", "e0998f2d2e14a55aae2291fdfab1ce7d", 1306492), UNSUPPORTED_ENTRY("snailquest1", "snailquest.exe", "dd69243e3cc9e955215e0d556301b58e", 1095860), UNSUPPORTED_ENTRY("snailquest2", "sq2.exe", "1bccd2edef19abc99e9683519d80c0e0", 955614), UNSUPPORTED_ENTRY("snailquest3", "sq3.exe", "1bccd2edef19abc99e9683519d80c0e0", 1501892), UNSUPPORTED_ENTRY("sol", "sol.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 4702799), UNSUPPORTED_ENTRY("space", "space.exe", "094135f05cf14fc3903e0d3697911a4e", 3790026), + UNSUPPORTED_ENTRY("stickmen", "stickmen.exe", "094135f05cf14fc3903e0d3697911a4e", 2145142), UNSUPPORTED_ENTRY("superdisk", "superdisk.exe", "80bdce9a1052e896c7cba6a4334cecce", 1304065), + UNSUPPORTED_ENTRY("teamwork", "teamwork.exe", "538274077115c6d8b4a0927dd3cceeac", 1096149), UNSUPPORTED_ENTRY("thecrownofgold", "the crown of gold.exe", "e407143be000e44f113ba5ff1fbd17f9", 1971515), + UNSUPPORTED_ENTRY("theinexperiencedassassin", "assassin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2659741), UNSUPPORTED_ENTRY("theisland", "island.exe", "e93037e8efc7abc19b8978903ef5b409", 1814801), UNSUPPORTED_ENTRY("thendor", "ac2game.dat", "b9c2ad76574c08bbcfd56eb1b49d2cd3", 8580708), + UNSUPPORTED_ENTRY("thetower", "thetower.exe", "9027912819f3a319ed9de0fd855310c3", 3431385), UNSUPPORTED_ENTRY("thewarp", "warp.exe", "9027912819f3a319ed9de0fd855310c3", 881957), + UNSUPPORTED_ENTRY("tommato", "tom mato's grand wing-ding.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2735158), UNSUPPORTED_ENTRY("tulliesworld1", "candale.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 3936603), UNSUPPORTED_ENTRY("tvquest", "mags.exe", "fc5f54dcfc82d3b991f670490a316958", 1318019), + UNSUPPORTED_DEMO("uishowoff", "pd.exe", "ecd0793124fbc9b89c6d11162e3b5851", 3853394), UNSUPPORTED_DEMO("waitkey", "ac2game.dat", "8ddf3744922101e33305dfcd06e3b682", 445197), UNSUPPORTED_ENTRY("whokilledkennyrogers", "mags.exe", "ed778afb4f46c3f2a70d330532a83a2f", 1240103), UNSUPPORTED_ENTRY("winfry", "fry.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 4164041), -#ifdef TODO - UNSUPPORTED_ENTRY("", "carver2.exe", "ed778afb4f46c3f2a70d330532a83a2f", 6265594), - UNSUPPORTED_ENTRY("", "dem four.exe", "426e34f40e0dc5285af3fb5fc32a220e", 5110674), - UNSUPPORTED_ENTRY("", "mags.exe", "0c057c5e6df6f45772286986ab7b7a5b", 12855495), - UNSUPPORTED_ENTRY("", "qfc.exe", "04eedea9846d380d6d9a120f657daa43", 2038696), - UNSUPPORTED_ENTRY("", "qfc.exe", "04eedea9846d380d6d9a120f657daa43", 2038696), - UNSUPPORTED_ENTRY("", "rollinfoy.exe", "19f4045333d9c823a5439d0447d55985", 3454107), - UNSUPPORTED_ENTRY("", "tom mato's grand wing-ding.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2735158), - UNSUPPORTED_ENTRY("", "fart.exe", "fc5f54dcfc82d3b991f670490a316958", 1138006), - UNSUPPORTED_ENTRY("", "thetower.exe", "9027912819f3a319ed9de0fd855310c3", 3431385), - UNSUPPORTED_ENTRY("", "mtg.exe", "ed778afb4f46c3f2a70d330532a83a2f", 1618544), - UNSUPPORTED_ENTRY("", "assassin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2659741), - UNSUPPORTED_ENTRY("", "burns.exe", "094135f05cf14fc3903e0d3697911a4e", 2120885), - UNSUPPORTED_ENTRY("", "ripp.exe", "426e34f40e0dc5285af3fb5fc32a220e", 10489586), - UNSUPPORTED_ENTRY("", "indy.exe", "094135f05cf14fc3903e0d3697911a4e", 1545150), - UNSUPPORTED_ENTRY("", "aaron.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 1788404), - UNSUPPORTED_ENTRY("", "adventure.exe", "221637e5d62e2ca3cc146846ab0b2e49", 5533207), - UNSUPPORTED_ENTRY("", "bq2.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 2540006), - UNSUPPORTED_ENTRY("", "comp.exe", "094135f05cf14fc3903e0d3697911a4e", 2054366), - UNSUPPORTED_ENTRY("", "dart.exe", "ed778afb4f46c3f2a70d330532a83a2f", 736848), - UNSUPPORTED_ENTRY("", "burro.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 2209309), - UNSUPPORTED_ENTRY("", "exile.exe", "aad0a09714fab4de51e5488da48fd5d4", 13421451), - UNSUPPORTED_ENTRY("", "firewall demo.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 2839412), - UNSUPPORTED_ENTRY("", "lupo.exe", "19f4045333d9c823a5439d0447d55985", 1856459), - UNSUPPORTED_ENTRY("", "0112.men in brown.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2072392), - UNSUPPORTED_ENTRY("", "moose.exe", "f4585823c1b4ce97d78c8acb433bec52", 1448684), - UNSUPPORTED_ENTRY("", "greywin.exe", "80bdce9a1052e896c7cba6a4334cecce", 1283447), - UNSUPPORTED_ENTRY("", "mtsodos.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 777967), - UNSUPPORTED_ENTRY("", "mtsowin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1076035), - UNSUPPORTED_ENTRY("", "nw1demo.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1539596), - UNSUPPORTED_ENTRY("", "odysseus.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2799113), - UNSUPPORTED_ENTRY("", "pd.exe", "ecd0793124fbc9b89c6d11162e3b5851", 3853394), - UNSUPPORTED_ENTRY("", "pqwin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2500089), - UNSUPPORTED_ENTRY("", "moonsdt.exe", "9027912819f3a319ed9de0fd855310c3", 1276725), - UNSUPPORTED_ENTRY("", "stickmen.exe", "094135f05cf14fc3903e0d3697911a4e", 2145142), - UNSUPPORTED_ENTRY("", "teamwork.exe", "538274077115c6d8b4a0927dd3cceeac", 1096149), - UNSUPPORTED_ENTRY("", "blackjack.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1153092), -#endif + // Post-2.5 games that are likely supported by the AGS engine ENGLISH_ENTRY("5daysastranger", "5days.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4440143), ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "465f972675db2da6040518221af5b0ba", 4693374), @@ -1415,6 +1465,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("46memorylane", "diyu.exe", "e3962995a70923a8d5a8f1cf8f932eee", 66686277), ENGLISH_ENTRY("4ofclubs", "4ofClubs.exe", "06a03fe35791b0578068ab1873455463", 5909169), ENGLISH_ENTRY("5daysastranger", "5days.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4614351), + ENGLISH_ENTRY("5oclocklock", "DadGame.exe", "3018c5443291aec823bc63342ce4c58b", 6073887), ENGLISH_ENTRY("6daysasacrifice", "6das.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7993899), ENGLISH_ENTRY("6mornings", "project2.exe", "e7dac058b9bc0b42d489e474c2ddec84", 11595240), ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4863356), @@ -1451,6 +1502,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("agsdarts", "AGS Darts.exe", "434c43a5e1ba2a11c1bde723ffeae719", 47771575), ENGLISH_ENTRY("agsinvaders", "AGS-Invaders.exe", "f120690b506dd63cd7d1112ea6af2f77", 1394435), ENGLISH_ENTRY("agsjukebox", "JukeBox2.exe", "a7aef57e360306c9377164f38d317ccb", 2914973), + ENGLISH_ENTRY("agsmittensshooter", "Clex.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1381575), ENGLISH_ENTRY("agsmoduletester", "V1.0 Source.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 2020344), ENGLISH_ENTRY("agsyahtzee2", "AGS Yahtzee 2.exe", "9e995c04d8642d6182d492c54a90b188", 71217276), ENGLISH_ENTRY("agsyathzee", "AGS Yathzee.exe", "434c43a5e1ba2a11c1bde723ffeae719", 37295758), @@ -1566,6 +1618,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("boom", "boom.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 934966), ENGLISH_ENTRY("bowserquirkquest", "Bowser Quirk Quest.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3046623), ENGLISH_ENTRY("box", "Box.exe", "0b7529a76f38283d6e850b8d56526fc1", 748638), + ENGLISH_ENTRY("boxfight", "boxen.exe", "3128b9f90e2f954ba704414ae854d10b", 3132938), ENGLISH_ENTRY("boyindahood", "Boy in da hood.exe", "afe40dc1416dd51e896ee0444d799f07", 12260759), ENGLISH_ENTRY("bradbradsonkeyquest", "BADness.exe", "0500aacb6c176d47ac0f8158f055db83", 1190580), ENGLISH_ENTRY("breakdownbyonedollar", "Breakdown.exe", "710ac163c281a5a539ffe2386264b990", 5273352), @@ -1578,7 +1631,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("bunnyquest", "BunnyQuest.exe", "28f82e420b82d07651b68114f90223c8", 1154928), ENGLISH_ENTRY("burymeinthesand", "buryme.exe", "f10516e88ec858700804ee69d041aead", 24252498), ENGLISH_ENTRY("butcherstanys", "Stanys.exe", "97d700529f5cc826f230c27acf81adfd", 1404933), - ENGLISH_ENTRY("bytheswordconspiracy", "bts.exe", "7dc7f61f79ba7a77d4ef8168bfd3d173", 60246329), + ENGLISH_DEMO("bytheswordconspiracy", "bts.exe", "7dc7f61f79ba7a77d4ef8168bfd3d173", 60246329), ENGLISH_ENTRY("calebsdrunkenadventure", "Calebdru.exe", "0b7529a76f38283d6e850b8d56526fc1", 15484923), ENGLISH_ENTRY("calsoon2", "Looncalsoon.exe", "97d700529f5cc826f230c27acf81adfd", 18981033), ENGLISH_ENTRY("capricorn", "capricorn.exe", "06a03fe35791b0578068ab1873455463", 4817076), @@ -1611,7 +1664,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("cirquedezale", "cirque.exe", "3128b9f90e2f954ba704414ae854d10b", 8547131), ENGLISH_ENTRY("claire", "Claire.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 2781456), ENGLISH_ENTRY("classnotesv11", "ClassNotes.exe", "0710e2ec71042617f565c01824f0cf3c", 5706836), - ENGLISH_ENTRY("clex", "Clex.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1381575), ENGLISH_ENTRY("clipl2heblinna", "Clip goes to town.exe", "0710e2ec71042617f565c01824f0cf3c", 1690928), ENGLISH_ENTRY("clubofevil", "Club of Evil.exe", "65f53f81071dab6b3ab8363e4c76d12e", 11838011), ENGLISH_ENTRY("coeldeckaflightgame", "coell deca.exe", "a524cbb1c51589903c4043b98917f1d9", 5497572), @@ -1632,6 +1684,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("cosmosquestiii", "CQ3.exe", "18b284c22010850f79bc5c20054a70c4", 8674790), ENGLISH_ENTRY("cougarsquestforfreedom", "chra.exe", "0500aacb6c176d47ac0f8158f055db83", 12654043), ENGLISH_ENTRY("counterfeit", "Counterfeit.exe", "ef1645ccd3d16691ec3908c91f340c34", 2232297), + ENGLISH_ENTRY("coupdecup", "Newgame.exe", "949f7440e3692b7366c2029979dee9a0", 9635719), ENGLISH_ENTRY("cow", "cow.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 134670383), ENGLISH_ENTRY("coyote", "Coyote.exe", "a524cbb1c51589903c4043b98917f1d9", 33124533), ENGLISH_ENTRY("craftofevil", "Craft Of Evil.exe", "4c1d9a74c4acf6771aab4be704bf0797", 22409329), @@ -1758,7 +1811,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("feuersturmkapitel2", "fs2.exe", "06a03fe35791b0578068ab1873455463", 7043558), ENGLISH_ENTRY("feuersturmkapitel3", "feuersturm3.exe", "206478d4d39e16571682b2cddf01a78f", 7826524), ENGLISH_ENTRY("fifa2003pro", "Soccer.exe", "475da5decb9ad2a11e64e2e2e891d8e0", 2524958), - ENGLISH_ENTRY("fight", "boxen.exe", "3128b9f90e2f954ba704414ae854d10b", 3132938), ENGLISH_ENTRY("fightgame", "Fight Game.exe", "463f79e5db4013d1b3be647edd7e338d", 1871790), ENGLISH_ENTRY("fightgame", "Fight Game.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3551992), ENGLISH_ENTRY("fireflystory3d", "FFS 3D.exe", "27343924ddad3be0b97bdcaa71858b1b", 2254453), @@ -1857,7 +1909,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("huongjiaoping", "hotpot.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 47237302), ENGLISH_ENTRY("huxzadventure", "Huxsadv.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 2053897), ENGLISH_ENTRY("hydeandseek", "Hyde and Seek.exe", "c2f495a688dc19e66362657dee9aa895", 28066547), - ENGLISH_ENTRY("iaman00b11omgwtflol", "DadGame.exe", "3018c5443291aec823bc63342ce4c58b", 6073887), ENGLISH_ENTRY("iamjason", "IAMJASON.exe", "e8985d9ffbfa1eda77f2eb8d1331944a", 4843842), ENGLISH_ENTRY("iforgot", "Forgot.exe", "6aa30185326552359c7865e55c045a74", 7743871), ENGLISH_ENTRY("igs", "IGS.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 1204802), @@ -1900,6 +1951,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("joesmiserablelife", "Joe's Miserable Life.exe", "1b9f13d430bb15bf30d0fd044358db68", 36705304), ENGLISH_ENTRY("johnharrissafrakincse", "totp.exe", "74dc062c5f68f3d70da911f2db5737b6", 36463878), ENGLISH_ENTRY("johnjebediahgunelisoladisepheret", "JJG.exe", "a28cb95e1769ba1bfa48f850390746c2", 88957123), + ENGLISH_ENTRY("johnlosthiskey", "Newgame.exe", "0b7529a76f38283d6e850b8d56526fc1", 1453831), ENGLISH_ENTRY("johnnyrocket", "Rocket.exe", "a524cbb1c51589903c4043b98917f1d9", 10366294), ENGLISH_ENTRY("johnsinclairvoodooinlondon", "John Sinclair - Voodoo in London.exe", "d72e72697a755c7de395b0f6c8cbbf0d", 56795991), ENGLISH_ENTRY("jonnysmallvalley", "Jonny Smallvalley.exe", "01d0e6bd812abaa307bcb10fc2193416", 34437869), @@ -2010,9 +2062,9 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("megoaway", "Me Go Store II.exe", "06a03fe35791b0578068ab1873455463", 6640781), ENGLISH_ENTRY("megocannibaljungle", "mgcj.exe", "06a03fe35791b0578068ab1873455463", 7127871), ENGLISH_ENTRY("megostore", "Me Go Store.exe", "90413e9ae57e222f8913b09d2bc847bc", 2961962), - ENGLISH_ENTRY("melrinthediscipleordeal", "Melrin.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 12822475), - ENGLISH_ENTRY("melrinthedragonmenace", "Melrin3.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 5802221), - ENGLISH_ENTRY("melrinthependantquest", "Melrin2.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 4372768), + ENGLISH_ENTRY("melrin1", "Melrin.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 12822475), + ENGLISH_ENTRY("melrin2", "Melrin2.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 4372768), + ENGLISH_ENTRY("melrin3", "Melrin3.exe", "803e65c28364b6bf44b7c4610fcdaa5a", 5802221), ENGLISH_ENTRY("meltdrake3chapter1", "CaK3.exe", "97d700529f5cc826f230c27acf81adfd", 6044911), ENGLISH_ENTRY("memoriesfade", "MemoriesFade.exe", "d5d028212a242a9841feff24ec3db3c9", 7996519), ENGLISH_ENTRY("meninhats", "GAME.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 1646510), @@ -2069,7 +2121,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("nedysadventure", "Nedy.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 6463558), ENGLISH_ENTRY("nekusnewtrip", "nnt.exe", "c0c1865c3c8369e034095a725ca1ddbf", 35012412), ENGLISH_ENTRY("nekusnewtrip", "square enix.exe", "a524cbb1c51589903c4043b98917f1d9", 10630694), - ENGLISH_ENTRY("newgame", "Newgame.exe", "0b7529a76f38283d6e850b8d56526fc1", 1453831), ENGLISH_ENTRY("nellycootalotv15", "Nelly Cootalot.exe", "18b284c22010850f79bc5c20054a70c4", 108256323), ENGLISH_ENTRY("neofeud", "Neofeud Demo.exe", "6e861b1f476ff7cdf036082abb271329", 1886913453), ENGLISH_ENTRY("nesquest", "NES Quest.exe", "8b72036706da98095057df615d07460b", 20881972), @@ -2225,10 +2276,10 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("roadofdestiny", "ROD.exe", "618d7dce9631229b4579340b964c6810", 30127308), ENGLISH_ENTRY("roadracer", "TR_Bryvis.exe", "cebb3ac5c3d2df939e7f0ec8f2975b64", 25080647), ENGLISH_ENTRY("roastmothergoose", "RMG.exe", "00328f4f1e7729144483107b96b11df8", 46474982), - ENGLISH_ENTRY("robbertredfordsavestheday", "GAME.exe", "02635a77ab660023f59519c91329f7f5", 6537985), ENGLISH_ENTRY("robbingtheprincess", "Princess.exe", "ac461eb75959761fe159917607c246b4", 5793384), + ENGLISH_ENTRY("robertredford1", "GAME.exe", "02635a77ab660023f59519c91329f7f5", 6537985), + ENGLISH_ENTRY("robertredford2", "ROBERT2.exe", "02635a77ab660023f59519c91329f7f5", 13075066), ENGLISH_ENTRY("robertredford3", "game.exe", "71ca0d6c1c699595f28a2125948d4a84", 10846423), - ENGLISH_ENTRY("robertredfordsavestheday", "ROBERT2.exe", "02635a77ab660023f59519c91329f7f5", 13075066), ENGLISH_ENTRY("robmassacreofchainsawness", "Chainsaw.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 1153384), ENGLISH_ENTRY("robotragedy", "Robotragedy.exe", "465f972675db2da6040518221af5b0ba", 130585260), ENGLISH_ENTRY("robotragedy2", "Robotragedy 2.exe", "465f972675db2da6040518221af5b0ba", 256955387), @@ -2245,7 +2296,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("rootofallevil", "RootOfAllEvil.exe", "c4f5b7b29be90ba0f8128298afb917de", 3957834), ENGLISH_ENTRY("rosauradocelestialrescuefromdespair", "RosauraMAGS.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 13190949), ENGLISH_ENTRY("rotnbelusebiusarrival", "RoNXXL.exe", "465f972675db2da6040518221af5b0ba", 9426141), - ENGLISH_ENTRY("rotnbelusebiusarrival", "ronextra.exe", "465f972675db2da6040518221af5b0ba", 9958019), ENGLISH_ENTRY("rowengoestowork", "Rowen.exe", "a1cef60926235b85bd0e1866b19e0dc7", 3791058), ENGLISH_ENTRY("rs15", "rs15.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 13638597), ENGLISH_ENTRY("rudeawakening", "RudeAwakening.exe", "0710e2ec71042617f565c01824f0cf3c", 8038257), @@ -2275,9 +2325,9 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("seega16engl5", "house_eng_5.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1746878), ENGLISH_ENTRY("seegame15", "housesitting_18.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1746919), ENGLISH_ENTRY("sevendoors", "7DOORS.exe", "18b284c22010850f79bc5c20054a70c4", 113716886), - ENGLISH_ENTRY("sga", "StarGA.exe", "0710e2ec71042617f565c01824f0cf3c", 45738298), + ENGLISH_ENTRY("stargateadv", "StarGA.exe", "0710e2ec71042617f565c01824f0cf3c", 45738298), ENGLISH_ENTRY("shadesofgreye", "Shades of Greye.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 16125855), - ENGLISH_ENTRY("shadowsoftheempiretd", "sote_td.exe", "b8cd640b45c5a79c33c7a8a8fe32ebe2", 63299246), + ENGLISH_DEMO("shadowsoftheempire", "sote_td.exe", "b8cd640b45c5a79c33c7a8a8fe32ebe2", 63299246), ENGLISH_ENTRY("shailadusithlenqute", "Shai-la Enquete.exe", "a524cbb1c51589903c4043b98917f1d9", 7489302), ENGLISH_ENTRY("shailaofthesith", "Shaila_of_the_Sith.exe", "a524cbb1c51589903c4043b98917f1d9", 76170347), ENGLISH_ENTRY("shem", "Shem.exe", "0710e2ec71042617f565c01824f0cf3c", 8866401), @@ -2317,9 +2367,9 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("spacelynxes", "SpaceLynxes.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 6593042), ENGLISH_ENTRY("spacepirates", "Space Pirates.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 3006210), ENGLISH_ENTRY("spacepoolalpha", "SpacePool.exe", "ef1d6fdc83c91a1a8de9eaf2630737b7", 3055777), + ENGLISH_ENTRY("spacequest3vgapreview", "SQ3VGADEMO.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3630019), ENGLISH_ENTRY("spacequest45", "SQ4,5.exe", "5cd8db602cedc8f04cd3ca290a4a2693", 6886082), ENGLISH_ENTRY("spacequest55demoags", "SQ5.5.exe", "465f972675db2da6040518221af5b0ba", 16342443), - ENGLISH_ENTRY("spacequestiiivgapreview", "SQ3VGADEMO.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3630019), ENGLISH_ENTRY("spacerangers", "SpaceRangersEp46.exe", "4f6c7ec127e8b0ce077abb357903612f", 41103057), ENGLISH_ENTRY("spacerangersep52", "SpaceRangers52Grisli.exe", "4f6c7ec127e8b0ce077abb357903612f", 208346458), ENGLISH_ENTRY("spacewar", "Spacewar.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 2270669), @@ -2352,7 +2402,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("stediddyip1employment", "stediddy1.exe", "5872fea5a958bc74c2d9ca7b2d196c42", 27136166), ENGLISH_ENTRY("stickmeni", "stick.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2399329), ENGLISH_ENTRY("stickythestickfigurepart1thecrimsonhouse", "Crimson House Files.exe", "3b095a7872e04769d04ab45e9c1b66eb", 3610653), - ENGLISH_ENTRY("stinkymcpoopoo", "grok.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1046039), + ENGLISH_ENTRY("grok", "grok.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1046039), ENGLISH_ENTRY("stranded", "Stranded.exe", "18b284c22010850f79bc5c20054a70c4", 39791629), ENGLISH_ENTRY("stranger", "Stranger.exe", "0500aacb6c176d47ac0f8158f055db83", 5854099), ENGLISH_ENTRY("strangerinstickworld", "game1.exe", "a524cbb1c51589903c4043b98917f1d9", 42525810), @@ -2431,9 +2481,9 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("thejourneyofiesir", "The Journey of Iesir.exe", "376a3f162c7940d990325c53edc20fed", 70444514), ENGLISH_ENTRY("thelastharvest", "The Last Harvest.exe", "f120690b506dd63cd7d1112ea6af2f77", 6253816), ENGLISH_ENTRY("thelastsupperawhodunnit", "THE LAST SUPPER, A WHODUNNIT.exe", "37500274a7882e8087042cc6ec851e0c", 13447848), - ENGLISH_ENTRY("theloneloserdemo", "DEMO (English).exe", "0500aacb6c176d47ac0f8158f055db83", 6082095), + ENGLISH_DEMO("theloneloser", "DEMO (English).exe", "0500aacb6c176d47ac0f8158f055db83", 6082095), ENGLISH_ENTRY("thelongtrip", "longtrip.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 184362586), - ENGLISH_ENTRY("themajesticconspiracy", "Majestic.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 17929647), + ENGLISH_ENTRY("themajesticconspiracy", "majestic.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 17929647), ENGLISH_ENTRY("themarionette", "marionette.exe", "ff3d6e4edfca8b4f4f1c6cbf8e2781a6", 88408446), ENGLISH_ENTRY("themccarthychronicleschapter1", "McCarthy.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 29488543), ENGLISH_ENTRY("themcreedcasebytk", "McReedCase.exe", "4bcbc24015114752b3c7971128704689", 2982436), @@ -2442,6 +2492,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("thenetherworld", "netherworld.exe", "465f972675db2da6040518221af5b0ba", 2253033), ENGLISH_ENTRY("thenextcurse", "TNC.exe", "88cf59aad15ca331ab0f854e16c84df3", 4125146), ENGLISH_ENTRY("theoraclev11", "The Oracle.exe", "f120690b506dd63cd7d1112ea6af2f77", 7490474), + ENGLISH_ENTRY("thepaparazziprince", "Willy.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 3403804), ENGLISH_ENTRY("thepark", "park.exe", "97d700529f5cc826f230c27acf81adfd", 709265), ENGLISH_ENTRY("theperfectmurder", "Tamz.exe", "9cf51833e787cc919837d9a8bd8fc14c", 4527709), ENGLISH_ENTRY("thephantominheritance", "Phantom.exe", "ec04c7917c003d9e07d4514ff25bf365", 27558669), @@ -2522,7 +2573,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("vohaulsrevengeii", "SQ XII.exe", "465f972675db2da6040518221af5b0ba", 17313307), ENGLISH_ENTRY("vpxt2", "VPET!2!.exe", "0b7529a76f38283d6e850b8d56526fc1", 12933096), ENGLISH_ENTRY("waitingfortheloop", "WaitingForTheLoop.exe", "0241777c2537fc5d077c05cde10bfa9f", 51273604), - ENGLISH_ENTRY("wallyweaseldemo", "WallyDemo.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 12579444), + ENGLISH_DEMO("wallyweasel", "WallyDemo.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 12579444), ENGLISH_ENTRY("waltersasteroid", "HDGame.exe", "465f972675db2da6040518221af5b0ba", 8390872), ENGLISH_ENTRY("warthogs", "Warthogs.exe", "9c49b6fa0460f36d6e7558281f142683", 12448793), ENGLISH_ENTRY("washedashore", "Achtung!.exe", "06a03fe35791b0578068ab1873455463", 7926840), @@ -2543,7 +2594,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("whowantstoliveforever", "WWtLF.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 6917937), ENGLISH_ENTRY("williamsnightmare", "Killer.exe", "0b7529a76f38283d6e850b8d56526fc1", 3991683), ENGLISH_ENTRY("willowhouse", "Game.exe", "5bc696cf7178870b21db6ac87972befd", 132161306), - ENGLISH_ENTRY("willy", "Willy.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 3403804), ENGLISH_ENTRY("winnersdontdodrugs", "windrugs.exe", "ff3358d8f2726d544aadfde4f1ec8407", 2573704), ENGLISH_ENTRY("winterrose", "Winter Rose.exe", "0500aacb6c176d47ac0f8158f055db83", 37444693), ENGLISH_ENTRY("witch", "witch.exe", "06a03fe35791b0578068ab1873455463", 10110407), @@ -2556,7 +2606,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("worm", "Worm.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 40704028), ENGLISH_ENTRY("wrathofthesolonoids", "verb.exe", "0500aacb6c176d47ac0f8158f055db83", 3582078), ENGLISH_ENTRY("yoda", "Yoda.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 2461339), - ENGLISH_ENTRY("yourgame", "Newgame.exe", "949f7440e3692b7366c2029979dee9a0", 9635719), ENGLISH_ENTRY("yourlate", "Your late.exe", "02635a77ab660023f59519c91329f7f5", 2719997), ENGLISH_ENTRY("zakmckracken", "Zak2.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 8686711), ENGLISH_ENTRY("zombieattackdemo", "ZADemo.exe", "82da2565c456dcfb265ded6fe3189c0b", 20958555), From 3228a50bc381ef04aab9f92c977a91f940eef866 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 1 Feb 2021 19:22:05 -0800 Subject: [PATCH 198/215] AGS: Further groupings for detection table --- engines/ags/detection_tables.h | 157 +++++++++++++++++---------------- 1 file changed, 82 insertions(+), 75 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 5d73045d4b3e..9ab7ffe7c290 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -134,35 +134,24 @@ const PlainGameDescriptor GAME_NAMES[] = { { "waitkey", "WaitKey();" }, { "winfry", "Winfry" }, - // Post-2.5 games that are likely supported by the AGS engine - { "5daysastranger", "5 Days A Stranger" }, - { "7daysaskeptic", "7 Days A Skeptic" }, - { "atotk", "A Tale Of Two Kingdoms" }, - { "bcremake", "Black Cauldron Remake" }, + // AGDI games. They get their own grouping because they're just that awesome + { "kq1agdi", "King's Quest I: Quest for the Crown Remake" }, + { "kq2agdi", "King's Quest II: Romancing The Stones" }, + { "kq3agdi", "King's Quest III Redux: To Heir is Human" }, + { "qfg2agdi", "Quest for Glory II: Trial By Fire" }, + { "mage", "Mage's Initiation: Reign of the Elements" }, + + // Comercial games { "blackwell1", "The Blackwell Legacy" }, { "blackwell2", "Blackwell Unbound" }, { "blackwell3", "The Blackwell Convergence" }, { "blackwell4", "The Blackwell Deception" }, { "blackwell5", "The Blackwell Epiphany" }, - { "blackwellconvergence", "Blackwell Convergence" }, - { "blackwelllegacydemo", "Blackwell Legacy Demo" }, - { "blackwellunbounddemo", "Blackwell Unbound Demo" }, { "geminirue", "Gemini Rue" }, - { "goldenwake", "A Golden Wake" }, - { "kathyrain", "Kathy Rain" }, - { "kq1agdi", "King's Quest I: Quest for the Crown Remake" }, - { "kq2agdi", "King's Quest II: Romancing The Stones" }, - { "kq3agdi", "King's Quest III Redux: To Heir is Human" }, - { "mage", "Mage's Initiation: Reign of the Elements" }, - { "oott", "Order of the Thorne: The King's Challenge" }, { "primordia", "Primordia" }, - { "qfi", "Quest for Infamy" }, { "resonance", "Resonance" }, - { "unavowed", "Unavowed" }, - { "whokilledkennyrogers", "Who Killed Kenny Rogers" }, - { "winfry", "Winfry" }, - // Unsorted games + // Post-2.5 games that are likely supported by the AGS engine { "10waysfromsunday", "10 Ways from Sunday" }, { "1dayamosquito", "1 day a mosquito" }, { "2034acaftercanadaii", "2034 A.C. (After Canada) II" }, @@ -170,9 +159,11 @@ const PlainGameDescriptor GAME_NAMES[] = { { "3piggiesalpha", "3piggiesAlpha" }, { "46memorylane", "46 Memory Lane" }, { "4ofclubs", "4 of Clubs" }, + { "5daysastranger", "5 Days A Stranger" }, { "5oclocklock", "5-O'clock Lock" }, { "6daysasacrifice", "6 Days A Sacrifice" }, { "6mornings", "6mornings" }, + { "7daysaskeptic", "7 Days A Skeptic" }, { "aazor", "Aazor" }, { "abducted", "Abducted" }, { "absent", "Absent" }, @@ -256,6 +247,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "ataleofbetrayal", "A Tale Of Betrayal" }, { "ataleoftwokingdoms", "A Tale of Two Kingdoms" }, { "atapi", "Atapi" }, + { "atotk", "A Tale Of Two Kingdoms" }, { "atotkjukebox", "ATOTK jukebox" }, { "atreatandsometricks", "A Treat and Some Tricks" }, { "aunaturel", "Au Naturel" }, @@ -279,6 +271,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "barnrunnerholiday2", "Barn Runner: Holiday 2" }, { "bartsquestfortv", "Bart's Quest For TV" }, { "battlewarriors", "Battle Warriors" }, + { "bcremake", "Black Cauldron Remake" }, { "beacon", "Beacon" }, { "bear", "Bear" }, { "beasts", "Beasts" }, @@ -305,6 +298,9 @@ const PlainGameDescriptor GAME_NAMES[] = { { "blackmailinbrooklyn", "Blackmail In Brooklyn" }, { "blackmorph", "Black Morph" }, { "blackuddertodoubloonornottodoubloon", "Blackudder: To Doubloon or not to Doubloon" }, + { "blackwellconvergence", "Blackwell Convergence" }, + { "blackwelllegacydemo", "Blackwell Legacy Demo" }, + { "blackwellunbounddemo", "Blackwell Unbound Demo" }, { "bluemoon", "Blue Moon" }, { "boardquest", "Board Quest" }, { "bob", "BOB" }, @@ -550,6 +546,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "glitchquestnofun", "Glitch Quest (nofun)" }, { "gnomeshomebrewingadventure", "Gnome's Homebrewing Adventure" }, { "gnrblexags", "Gnrblex_AGS" }, + { "goldenwake", "A Golden Wake" }, { "goneboatfishin", "Gone Boat Fishin'" }, { "goodmorningmrgingerbread", "Good Morning, Mr. Gingerbread!" }, { "goodsantabadsanta", "Good Santa, Bad Santa" }, @@ -654,6 +651,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "justignorethem", "Just Ignore Them" }, { "kanjigakusei", "Kanji Gakusei" }, { "kartquestv053", "Kart-Quest - v0.53" }, + { "kathyrain", "Kathy Rain" }, { "keptoshi", "Keptosh I" }, { "keys", "Keys" }, { "killereye", "Killer Eye" }, @@ -841,6 +839,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "oneweekoneroom", "One Week One Room" }, { "onleavingthebuilding", "On Leaving The Building" }, { "onlythegooddieyoungenglishversion", "Only The Good Die Young - english version" }, + { "oott", "Order of the Thorne: The King's Challenge" }, { "openquest", "OpenQuest!" }, { "operationnovi", "Operation Novi" }, { "operationsavebluecup", "Operation Save Blue Cup" }, @@ -923,6 +922,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "purityofthesurf", "Purity of the Surf" }, { "puzzlebotsdemo", "Puzzle Bots Demo" }, { "pxenophobe", "PXenophobe" }, + { "qfi", "Quest for Infamy" }, { "quantumnauts", "QUANTUMNAUTS" }, { "questfighter", "Quest Fighter" }, { "questfighterii", "Quest Fighter II" }, @@ -1008,7 +1008,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "seega16engl5", "seega16_engl_5" }, { "seegame15", "seegame15" }, { "sevendoors", "Seven Doors" }, - { "stargateadv", "Stargate Adventure" }, { "shadesofgreye", "Shades of Greye" }, { "shadowsoftheempire", "Shadows of the Empire" }, { "shailadusithlenqute", "Shai-la du Sith : l'Enqu?te" }, @@ -1053,11 +1052,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "spacequest3vgapreview", "Space Quest III VGA Preview" }, { "spacequest45", "Space Quest 4.5" }, { "spacequest55demoags", "Space Quest 5.5 demo (AGS)" }, - { "sqm11", "Space Quest Mania 1x1" }, - { "sqm12", "Space Quest Mania 1x2" }, - { "sqm13", "Space Quest Mania 1x3" }, - { "sqm14", "Space Quest Mania 1x4" }, - { "sqm16", "Space Quest Mania 1x6" }, { "spacerangers", "Space Rangers " }, { "spacerangersep52", "Space Rangers Ep 52" }, { "spacewar", "Space war" }, @@ -1069,6 +1063,11 @@ const PlainGameDescriptor GAME_NAMES[] = { { "spotthedifference", "Spot The Difference" }, { "sproutsofevil", "Sprouts of evil" }, { "sqkubikgetready", "SQ Kubik (Get ready?)" }, + { "sqm11", "Space Quest Mania 1x1" }, + { "sqm12", "Space Quest Mania 1x2" }, + { "sqm13", "Space Quest Mania 1x3" }, + { "sqm14", "Space Quest Mania 1x4" }, + { "sqm16", "Space Quest Mania 1x6" }, { "sqmania1", "SQ Mania #1" }, { "sqmania2remakeeng", "SQ Mania 2 Remake (ENG)" }, { "sqmaniaep5", "SQ Mania Ep5" }, @@ -1077,6 +1076,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "stairquest", "Stair Quest" }, { "stanamespiepisode1", "Stan Ames PI, Episode 1" }, { "stansrevenge", "Stan's Revenge" }, + { "stargateadv", "Stargate Adventure" }, { "starshipcaramba", "Starship Caramba" }, { "starshipposeidon", "Starship Poseidon" }, { "start", "Start" }, @@ -1232,6 +1232,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "twoofakind", "Two of a Kind" }, { "uglyfiles", "Ugly Files" }, { "ulitsadimitrova", "Ulitsa Dimitrova" }, + { "unavowed", "Unavowed" }, { "unboundver10", "Unbound Ver 1.0" }, { "unfinished", "unfinished" }, { "unganeedsmumba", "UNGA needs MUMBA" }, @@ -1269,10 +1270,12 @@ const PlainGameDescriptor GAME_NAMES[] = { { "wherebedragons", "Where Be Dragons?" }, { "wheredidsamgo", "Where did Sam go?" }, { "wheresmhatma", "Where's M' Hat Ma?" }, + { "whokilledkennyrogers", "Who Killed Kenny Rogers" }, { "whowantstoliveagain", "Who wants to live again?" }, { "whowantstoliveforever", "Who wants to live forever?" }, { "williamsnightmare", "Williams Nightmare" }, { "willowhouse", "Willow House" }, + { "winfry", "Winfry" }, { "winnersdontdodrugs", "Winners Dont' Do Drugs" }, { "winterrose", "Winter Rose" }, { "witch", "Witch" }, @@ -1316,10 +1319,17 @@ static const PluginVersion AGSCREDITZ_11[] = { { "agscreditz", 11 }, { nullptr, const AGSGameDescription GAME_DESCRIPTIONS[] = { // Pre-2.5 games that aren't supported by the current AGS engine + UNSUPPORTED_DEMO("achristmastale", "tale.exe", "094135f05cf14fc3903e0d3697911a4e", 1484122), + UNSUPPORTED_DEMO("deepbright", "tc.exe", "8f80c91d160e333ab7f6be5208ea0533", 3022557), + UNSUPPORTED_DEMO("firewall", "firewall demo.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 2839412), + UNSUPPORTED_DEMO("larryvales3", "burns.exe", "094135f05cf14fc3903e0d3697911a4e", 2120885), + UNSUPPORTED_DEMO("nicholaswolfe1", "nw1demo.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1539596), + UNSUPPORTED_DEMO("pointblank", "future.exe", "385a593828b1edb194e984ce55cda65e", 1379714), + UNSUPPORTED_DEMO("uishowoff", "pd.exe", "ecd0793124fbc9b89c6d11162e3b5851", 3853394), + UNSUPPORTED_DEMO("waitkey", "ac2game.dat", "8ddf3744922101e33305dfcd06e3b682", 445197), UNSUPPORTED_ENTRY("6da", "6da.exe", "9027912819f3a319ed9de0fd855310c3", 1608073), UNSUPPORTED_ENTRY("aaronsepicjourney", "aaron.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 1788404), UNSUPPORTED_ENTRY("aceduswell", "ace.exe", "be48a6b0b81a71d34a41930623c065f1", 3103822), - UNSUPPORTED_DEMO("achristmastale", "tale.exe", "094135f05cf14fc3903e0d3697911a4e", 1484122), UNSUPPORTED_ENTRY("adayinthefuture", "space.exe", "ecd0793124fbc9b89c6d11162e3b5851", 4120328), UNSUPPORTED_ENTRY("adventuregame", "adventure.exe", "221637e5d62e2ca3cc146846ab0b2e49", 5533207), UNSUPPORTED_ENTRY("asapadventure", "asap.exe", "8f80c91d160e333ab7f6be5208ea0533", 1405072), @@ -1336,7 +1346,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { UNSUPPORTED_ENTRY("chamber", "indy.exe", "094135f05cf14fc3903e0d3697911a4e", 1545150), UNSUPPORTED_ENTRY("compensation", "comp.exe", "094135f05cf14fc3903e0d3697911a4e", 2054366), UNSUPPORTED_ENTRY("darts", "dart.exe", "ed778afb4f46c3f2a70d330532a83a2f", 736848), - UNSUPPORTED_DEMO("deepbright", "tc.exe", "8f80c91d160e333ab7f6be5208ea0533", 3022557), UNSUPPORTED_ENTRY("demonslayer1", "mags.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 3820347), UNSUPPORTED_ENTRY("demonslayer2", "bert.exe", "0c057c5e6df6f45772286986ab7b7a5b", 1726766), UNSUPPORTED_ENTRY("demonslayer3", "tiler.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2586532), @@ -1350,7 +1359,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { UNSUPPORTED_ENTRY("erniesbigadventure2", "magsjuly.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 6647578), UNSUPPORTED_ENTRY("exile", "exile.exe", "aad0a09714fab4de51e5488da48fd5d4", 13421451), UNSUPPORTED_ENTRY("eyesofthejadesphinx", "jade.exe", "f2fe94ab604612e4595f3c79b0245529", 10763660), - UNSUPPORTED_DEMO("firewall", "firewall demo.exe", "2fd8ca69f236ae1ad46edab4ba26a33d", 2839412), UNSUPPORTED_ENTRY("floyd", "floyd.exe", "9ef5bffe7b85377751c25af806345794", 5477588), UNSUPPORTED_ENTRY("gaeafallen", "gaea_fallen.exe", "80bdce9a1052e896c7cba6a4334cecce", 11273205), UNSUPPORTED_ENTRY("gorthor", "fart.exe", "fc5f54dcfc82d3b991f670490a316958", 1138006), @@ -1363,7 +1371,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { UNSUPPORTED_ENTRY("kidnapped", "ac2game.dat", "27daca01ccbbbaf02bf6b4b85d5990b4", 1205017), UNSUPPORTED_ENTRY("larryvales1", "larryvtd.exe", "610b7a3d1fd90f24d2218aa26b29d8ca", 3129645), UNSUPPORTED_ENTRY("larryvales2", "dead.exe", "be48a6b0b81a71d34a41930623c065f1", 3946993), - UNSUPPORTED_DEMO("larryvales3", "burns.exe", "094135f05cf14fc3903e0d3697911a4e", 2120885), UNSUPPORTED_ENTRY("lassi", "lassi.exe", "ed778afb4f46c3f2a70d330532a83a2f", 3681914), UNSUPPORTED_ENTRY("lassiandrogermeetgod", "mtg.exe", "ed778afb4f46c3f2a70d330532a83a2f", 1618544), UNSUPPORTED_ENTRY("lassiquesti", "lassi.exe", "c391c6676099032440b206189babe76e", 1700368), @@ -1380,14 +1387,12 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { UNSUPPORTED_ENTRY("moose", "moose.exe", "f4585823c1b4ce97d78c8acb433bec52", 1448684), UNSUPPORTED_ENTRY("moosewars", "moose.exe", "f4585823c1b4ce97d78c8acb433bec52", 1448684), UNSUPPORTED_ENTRY("murder", "murder.exe", "221637e5d62e2ca3cc146846ab0b2e49", 935799), - UNSUPPORTED_DEMO("nicholaswolfe1", "nw1demo.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1539596), UNSUPPORTED_ENTRY("nightoftheplumber", "night of the plumber.exe", "1f0edcb7fa3f8e2b1dd60fa6c0bce60f", 1703896), UNSUPPORTED_ENTRY("novomestro", "novo.exe", "07f9921784124d9e09f39bb831e06131", 1122507), UNSUPPORTED_ENTRY("odysseus", "odysseus.exe", "426e34f40e0dc5285af3fb5fc32a220e", 2799113), UNSUPPORTED_ENTRY("permanentdaylight", "daylight.exe", "07f9921784124d9e09f39bb831e06131", 1799958), UNSUPPORTED_ENTRY("perpetrator", "ac2game.dat", "56ef979be112e122e24d0cc8caea4ea4", 994303), UNSUPPORTED_ENTRY("pizzaquest", "pqwin.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2500089), - UNSUPPORTED_DEMO("pointblank", "future.exe", "385a593828b1edb194e984ce55cda65e", 1379714), UNSUPPORTED_ENTRY("pornquest", "porn.exe", "04eedea9846d380d6d9a120f657daa43", 1012323), UNSUPPORTED_ENTRY("qfc", "qfc.exe", "04eedea9846d380d6d9a120f657daa43", 2038696), UNSUPPORTED_ENTRY("qfg412", "qfg.exe", "8b21668ca462b0b6b35df43c5902b074", 26674790), @@ -1424,51 +1429,49 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { UNSUPPORTED_ENTRY("tommato", "tom mato's grand wing-ding.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 2735158), UNSUPPORTED_ENTRY("tulliesworld1", "candale.exe", "1c21bdb52bcafcafe988b30fd6bb4126", 3936603), UNSUPPORTED_ENTRY("tvquest", "mags.exe", "fc5f54dcfc82d3b991f670490a316958", 1318019), - UNSUPPORTED_DEMO("uishowoff", "pd.exe", "ecd0793124fbc9b89c6d11162e3b5851", 3853394), - UNSUPPORTED_DEMO("waitkey", "ac2game.dat", "8ddf3744922101e33305dfcd06e3b682", 445197), UNSUPPORTED_ENTRY("whokilledkennyrogers", "mags.exe", "ed778afb4f46c3f2a70d330532a83a2f", 1240103), UNSUPPORTED_ENTRY("winfry", "fry.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 4164041), - // Post-2.5 games that are likely supported by the AGS engine - ENGLISH_ENTRY("5daysastranger", "5days.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4440143), - ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "465f972675db2da6040518221af5b0ba", 4693374), - ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), - ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42740200), - ENGLISH_PLUGIN("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255, AGSCREDITZ_11), + // AGDI games. They get their own grouping because they're just that awesome + ENGLISH_ENTRY("kq1agdi", "kq1vga.exe", "688f1807c9d8df26fc0f174dc756054e", 8278611), // 4.1c + ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), // 3.1 + ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12574643), // 3.1c + ENGLISH_ENTRY("kq3agdi", "kq3redux.exe", "e569fb2ceabdc4a1609348c23ebc0821", 11986266), // 1.1 + ENGLISH_ENTRY("qfg2agdi", "qfg2vga.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 20470902), + ENGLISH_ENTRY("qfg2agdi", "qfg2vga.exe", "582e26533cf784011c7565e89905d3c4", 18224373), + + // Comercial games ENGLISH_ENTRY("blackwell1", "blackwell1.exe", "605e124cb7e0b56841c471e2d641c224", 18822697), // GOG ENGLISH_ENTRY("blackwell2", "unbound.exe", "5c3a940514d91431e8e1c372018851ca", 14493753), // GOG ENGLISH_ENTRY("blackwell3", "convergence.exe", "2260c1a21aba7ac00baf0100d4ca54f1", 172575801), // GOG ENGLISH_ENTRY("blackwell4", "deception.exe", "b3b192cf20a2f7666ddea3410dbd87cc", 303459336), // GOG ENGLISH_ENTRY("blackwell5", "epiphany.exe", "c1cddd6fcdbcd030beda9f10d4e4270a", 281849897), // GOG - ENGLISH_ENTRY("kq1agdi", "kq1vga.exe", "688f1807c9d8df26fc0f174dc756054e", 8278611), // 4.1c - ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12563246), // 3.1 - ENGLISH_ENTRY("kq2agdi", "kq2vga.exe", "40cfb7563df7dacf6530b19289a4745b", 12574643), // 3.1c - ENGLISH_ENTRY("kq3agdi", "kq3redux.exe", "e569fb2ceabdc4a1609348c23ebc0821", 11986266), // 1.1 ENGLISH_ENTRY("geminirue", "gemini rue.exe", "f3c0c7d3892bdd8963e8ce017f73de08", 61986506), // GOG - ENGLISH_ENTRY("goldenwake", "a-golden-wake.exe", "dbe281d93c914899886e77c09c3c65ec", 130844360), // Steam - ENGLISH_ENTRY("kathyrain", "kathyrain.exe", "434e24a12ba3cfb07d7b4b2f0e0bb1bf", 197487159), // Steam - ENGLISH_ENTRY("qfi", "qfi.exe", "0702df6e67ef87fd3c51d09303803126", 534847265), // GOG - ENGLISH_ENTRY("oott", "OotT-TKC.exe", "11c2421258465cba4bd773c49d918ee3", 467834855), // GOG ENGLISH_ENTRY("primordia", "primordia.exe", "22313e59c3233001488c26f18c80cc08", 973495830), // GOG ENGLISH_ENTRY("primordia", "primordia.exe", "f2edc9c3161f1f538df9b4c59fc89e24", 978377890), // GOG ENGLISH_ENTRY("resonance", "resonance.exe", "2e635c22bcbf0ed3d46f1bcde71812d4", 849404957), // GOG - ENGLISH_ENTRY("mage", "ac2game.dat", "2e822f554994f36e0c62da2acda874da", 30492258), // GOG, Mac - ENGLISH_ENTRY("unavowed", "ac2game.dat", "b1ff7d96667707daf4266975cea2bf90", 1755457364), // Steam, Mac - // Unsorted games + // Post-2.5 games that are likely supported by the AGS engine + ENGLISH_DEMO("bytheswordconspiracy", "bts.exe", "7dc7f61f79ba7a77d4ef8168bfd3d173", 60246329), + ENGLISH_DEMO("searchforsanity", "sfs.exe", "308d35bc34e9df29d8acce615593e3e7", 9097147), + ENGLISH_DEMO("shadowsoftheempire", "sote_td.exe", "b8cd640b45c5a79c33c7a8a8fe32ebe2", 63299246), + ENGLISH_DEMO("theloneloser", "DEMO (English).exe", "0500aacb6c176d47ac0f8158f055db83", 6082095), + ENGLISH_DEMO("wallyweasel", "WallyDemo.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 12579444), ENGLISH_ENTRY("10waysfromsunday", "10WaysFromSunday.exe", "495d45fb8adfd49690ae3b97921feec6", 11362765), ENGLISH_ENTRY("1dayamosquito", "mosquito.exe", "465f972675db2da6040518221af5b0ba", 2178983), ENGLISH_ENTRY("2034acaftercanadaii", "2034 AC II.exe", "1280ba7c269a68a9505871516319db0c", 35207006), ENGLISH_ENTRY("24hours", "24.exe", "f120690b506dd63cd7d1112ea6af2f77", 1932370), - ENGLISH_ENTRY("3piggiesalpha", "Three Little Pigs and a Wolf.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 14180634), ENGLISH_ENTRY("3piggiesalpha", "3piggiesAlpha.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 14181120), + ENGLISH_ENTRY("3piggiesalpha", "Three Little Pigs and a Wolf.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 14180634), ENGLISH_ENTRY("46memorylane", "diyu.exe", "e3962995a70923a8d5a8f1cf8f932eee", 66686277), ENGLISH_ENTRY("4ofclubs", "4ofClubs.exe", "06a03fe35791b0578068ab1873455463", 5909169), ENGLISH_ENTRY("5daysastranger", "5days.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4614351), + ENGLISH_ENTRY("5daysastranger", "5days.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4440143), ENGLISH_ENTRY("5oclocklock", "DadGame.exe", "3018c5443291aec823bc63342ce4c58b", 6073887), ENGLISH_ENTRY("6daysasacrifice", "6das.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7993899), ENGLISH_ENTRY("6mornings", "project2.exe", "e7dac058b9bc0b42d489e474c2ddec84", 11595240), ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 4863356), + ENGLISH_ENTRY("7daysaskeptic", "7days.exe", "465f972675db2da6040518221af5b0ba", 4693374), ENGLISH_ENTRY("aazor", "aazor.exe", "465f972675db2da6040518221af5b0ba", 4956212), ENGLISH_ENTRY("abducted", "10 MINUTES.exe", "465f972675db2da6040518221af5b0ba", 2687034), ENGLISH_ENTRY("absent", "Absent.exe", "aabdafae8b57dfc48fdf158a72326c23", 39284149), @@ -1520,8 +1523,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("alientimezone", "ATZ.exe", "0710e2ec71042617f565c01824f0cf3c", 2911858), ENGLISH_ENTRY("aloneinthenight", "ALONE.exe", "0710e2ec71042617f565c01824f0cf3c", 9501343), ENGLISH_ENTRY("alphadog", "Alpha_Dog.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3329253), - ENGLISH_ENTRY("alphax", "Project SMASH.exe", "06a03fe35791b0578068ab1873455463", 25377719), ENGLISH_ENTRY("alphax", "alphax.exe", "06a03fe35791b0578068ab1873455463", 17879795), + ENGLISH_ENTRY("alphax", "Project SMASH.exe", "06a03fe35791b0578068ab1873455463", 25377719), ENGLISH_ENTRY("alquest1demo", "AlQuest.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 20154310), ENGLISH_ENTRY("alysvsthephantomfelinefoe", "Alys.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 22323495), ENGLISH_ENTRY("amagicstone", "A magic stone.exe", "465f972675db2da6040518221af5b0ba", 5478520), @@ -1540,11 +1543,11 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("apprentice2", "App2.exe", "465f972675db2da6040518221af5b0ba", 34159191), ENGLISH_ENTRY("apprenticedeluxe", "App.exe", "45ab4f29031b50c8d01d10a269f77ff5", 17488604), ENGLISH_ENTRY("aprofoundjourney", "apj.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 920131), - ENGLISH_ENTRY("archeos", "Archeos.exe", "2ff048659aaefd20d342db6428a5f1a0", 6661410), ENGLISH_ENTRY("archeos", "Archeos.exe", "2ff048659aaefd20d342db6428a5f1a0", 6659974), + ENGLISH_ENTRY("archeos", "Archeos.exe", "2ff048659aaefd20d342db6428a5f1a0", 6661410), ENGLISH_ENTRY("arewethereyet", "AREwethereyet.exe", "f120690b506dd63cd7d1112ea6af2f77", 1054672), - ENGLISH_ENTRY("armageddonmargaret", "Armageddon Margaret.exe", "3128b9f90e2f954ba704414ae854d10b", 2951568), ENGLISH_ENTRY("armageddonmargaret", "AM_Game.exe", "06a03fe35791b0578068ab1873455463", 3640885), + ENGLISH_ENTRY("armageddonmargaret", "Armageddon Margaret.exe", "3128b9f90e2f954ba704414ae854d10b", 2951568), ENGLISH_ENTRY("asecondface", "Eye of Geltz.exe", "0e32c4b3380e286dc0cea8550f1c045e", 7061019), ENGLISH_ENTRY("ashortnightmare", "A_Short_Nightmare.exe", "b142b43c146c25443a1d155d441a6a81", 94221930), ENGLISH_ENTRY("asporia", "RPG.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 7094164), @@ -1555,6 +1558,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("ataleofbetrayal", "Mags.exe", "465f972675db2da6040518221af5b0ba", 11071496), ENGLISH_ENTRY("ataleoftwokingdoms", "ATOTK.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42785860), ENGLISH_ENTRY("atapi", "Atapi.exe", "dd8586ebefd5c457e29b6b9845a576ea", 34114381), + ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42740200), + ENGLISH_ENTRY("atotk", "atotk.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 42872046), ENGLISH_ENTRY("atotkjukebox", "Jukebox.exe", "37cf2d4d07842d45b59c6dd9387c1ee7", 1631992), ENGLISH_ENTRY("atreatandsometricks", "A Treat and Some Tricks.exe", "495d45fb8adfd49690ae3b97921feec6", 33708250), ENGLISH_ENTRY("aunaturel", "Au Naturel.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 8499426), @@ -1578,6 +1583,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("barnrunnerholiday2", "Xmas 2.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 31770973), ENGLISH_ENTRY("bartsquestfortv", "Simpsons.exe", "0500aacb6c176d47ac0f8158f055db83", 794013), ENGLISH_ENTRY("battlewarriors", "Battle.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 16314318), + ENGLISH_PLUGIN("bcremake", "bc.exe", "0710e2ec71042617f565c01824f0cf3c", 7683255, AGSCREDITZ_11), ENGLISH_ENTRY("beacon", "Beacon.exe", "af0d268193a9220891e983d03141ec58", 24671086), ENGLISH_ENTRY("bear", "Bear.exe", "97020973a2a635fe28eb0ba4bdfaa70b", 3258662), ENGLISH_ENTRY("beasts", "beasts.exe", "0500aacb6c176d47ac0f8158f055db83", 1295435), @@ -1631,7 +1637,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("bunnyquest", "BunnyQuest.exe", "28f82e420b82d07651b68114f90223c8", 1154928), ENGLISH_ENTRY("burymeinthesand", "buryme.exe", "f10516e88ec858700804ee69d041aead", 24252498), ENGLISH_ENTRY("butcherstanys", "Stanys.exe", "97d700529f5cc826f230c27acf81adfd", 1404933), - ENGLISH_DEMO("bytheswordconspiracy", "bts.exe", "7dc7f61f79ba7a77d4ef8168bfd3d173", 60246329), ENGLISH_ENTRY("calebsdrunkenadventure", "Calebdru.exe", "0b7529a76f38283d6e850b8d56526fc1", 15484923), ENGLISH_ENTRY("calsoon2", "Looncalsoon.exe", "97d700529f5cc826f230c27acf81adfd", 18981033), ENGLISH_ENTRY("capricorn", "capricorn.exe", "06a03fe35791b0578068ab1873455463", 4817076), @@ -1653,8 +1658,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("chemin", "chemin.exe", "06a03fe35791b0578068ab1873455463", 3179064), ENGLISH_ENTRY("chezapa", "CHEZAPA.exe", "9cf51833e787cc919837d9a8bd8fc14c", 2870327), ENGLISH_ENTRY("chickchaser", "AMY.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 7968024), - ENGLISH_ENTRY("chicken", "Chicken.exe", "f120690b506dd63cd7d1112ea6af2f77", 30627567), ENGLISH_ENTRY("chicken", "chicken.exe", "f120690b506dd63cd7d1112ea6af2f77", 1652888), + ENGLISH_ENTRY("chicken", "Chicken.exe", "f120690b506dd63cd7d1112ea6af2f77", 30627567), ENGLISH_ENTRY("chickenfraction", "Chicken.exe", "0500aacb6c176d47ac0f8158f055db83", 3021315), ENGLISH_ENTRY("chinesecheckers", "ChineseCheckers.exe", "06a03fe35791b0578068ab1873455463", 3391826), ENGLISH_ENTRY("christmaspresent", "christmas.exe", "3128b9f90e2f954ba704414ae854d10b", 5644948), @@ -1700,15 +1705,15 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("dalesfilmquest", "dale.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 2557975), ENGLISH_ENTRY("damsel", "Damsel.exe", "809418706c429cee5d88e8d483c906cc", 77101995), ENGLISH_ENTRY("dancetilyoudrop", "DanceTilYouDrop.exe", "0710e2ec71042617f565c01824f0cf3c", 4822399), - ENGLISH_ENTRY("danewguys", "DaNewGuys.exe", "97020973a2a635fe28eb0ba4bdfaa70b", 11998791), ENGLISH_ENTRY("danewguys", "DaNewGuys.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 12115013), + ENGLISH_ENTRY("danewguys", "DaNewGuys.exe", "97020973a2a635fe28eb0ba4bdfaa70b", 11998791), ENGLISH_ENTRY("dangerouslandstournamentrpg", "dlrt2.exe", "0710e2ec71042617f565c01824f0cf3c", 21636362), ENGLISH_ENTRY("dannydreadisoncall", "On Call.exe", "ef480ccb0831e452e55456e0ca24c761", 8787649), ENGLISH_ENTRY("darkcave", "DarkCave.exe", "0d48d8b170624e8f33bd7cd7f3ad2052", 5293954), ENGLISH_ENTRY("darkofnight", "D_o_N.exe", "3f7bb944e107f883d183f047d9d7f698", 10261961), ENGLISH_ENTRY("darktimesmerrychristmas", "Dark Times (Merry Christmas).exe", "1b9f13d430bb15bf30d0fd044358db68", 49043355), - ENGLISH_ENTRY("darum", "Darum.exe", "0241777c2537fc5d077c05cde10bfa9f", 4082708), ENGLISH_ENTRY("darum", "afterlife.exe", "0241777c2537fc5d077c05cde10bfa9f", 4082712), + ENGLISH_ENTRY("darum", "Darum.exe", "0241777c2537fc5d077c05cde10bfa9f", 4082708), ENGLISH_ENTRY("davegeneric", "generic.exe", "a524cbb1c51589903c4043b98917f1d9", 2449830), ENGLISH_ENTRY("davidletterman", "letterman.exe", "615e806856b7730afadf1fea9a756b70", 17019706), ENGLISH_ENTRY("dawnswonderedatagesend", "myGame.exe", "75f4c7f66b1be60af5b2d65f617b91a7", 243406385), @@ -1750,7 +1755,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("dumbassdriversdemo", "dumbass.exe", "f120690b506dd63cd7d1112ea6af2f77", 40580988), ENGLISH_ENTRY("dungeonhands", "DungeonHands.exe", "0a6704159f6f716ac80da91c430430ce", 16276450), ENGLISH_ENTRY("dungeonhands", "DungeonHands.exe", "f80ff6c2348f2bb90d3813719f54c870", 13751518), - ENGLISH_ENTRY("duskhunters", "DuskHunters.exe", "3128b9f90e2f954ba704414ae854d10b",3029482), + ENGLISH_ENTRY("duskhunters", "DuskHunters.exe", "3128b9f90e2f954ba704414ae854d10b", 3029482), ENGLISH_ENTRY("dusttowater", "Dust to Water.exe", "0e32c4b3380e286dc0cea8550f1c045e", 70459846), ENGLISH_ENTRY("dutyandbeyond", "Deliver.exe", "0710e2ec71042617f565c01824f0cf3c", 28873258), ENGLISH_ENTRY("duzzquest", "DuzzQuest.exe", "3128b9f90e2f954ba704414ae854d10b", 13125200), @@ -1857,6 +1862,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("glitchquestnofun", "GQnofun.exe", "465f972675db2da6040518221af5b0ba", 3181931), ENGLISH_ENTRY("gnomeshomebrewingadventure", "gnomebrew.exe", "abb3aee32ae97a8475626cceefb0664e", 50307521), ENGLISH_ENTRY("gnrblexags", "Gnrblex_AGS.exe", "476a1a39d43ea27577eacf907173e2c1", 85038656), + ENGLISH_ENTRY("goldenwake", "a-golden-wake.exe", "dbe281d93c914899886e77c09c3c65ec", 130844360), // Steam ENGLISH_ENTRY("goneboatfishin", "Gone Boat Fishin'.exe", "bdd1df0484e296faa348ffcb03e16273", 72936045), ENGLISH_ENTRY("goodmorningmrgingerbread", "mister_gingerbread.exe", "b42f80733b6bd1ded5e29be2c683afa8", 7084332), ENGLISH_ENTRY("goodsantabadsanta", "x-mags.exe", "71ca0d6c1c699595f28a2125948d4a84", 1966547), @@ -1865,6 +1871,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("graveyard", "Graveyard.exe", "955b711b21d7a2df6af1bb0cccccbb08", 13699789), ENGLISH_ENTRY("gremlin", "Gremlin.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3962167), ENGLISH_ENTRY("grizzlygooseofgosse", "Goose Fear.exe", "b69b5887e4a33a3b8588d52fed04b730", 32123559), + ENGLISH_ENTRY("grok", "grok.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1046039), ENGLISH_ENTRY("grr", "Grr!.exe", "3128b9f90e2f954ba704414ae854d10b", 26753739), ENGLISH_ENTRY("guardiansofgold", "Guardians of Gold.exe", "933200c8f306eccaaa484b1575da8528", 429166629), ENGLISH_ENTRY("guyslug", "GuySlug.exe", "0710e2ec71042617f565c01824f0cf3c", 1959514), @@ -1913,9 +1920,9 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("iforgot", "Forgot.exe", "6aa30185326552359c7865e55c045a74", 7743871), ENGLISH_ENTRY("igs", "IGS.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 1204802), ENGLISH_ENTRY("iiispy", "IIISpy.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 6696286), - ENGLISH_ENTRY("illuminationdiminishing", "IlluminationDiminishing.exe", "b142b43c146c25443a1d155d441a6a81", 49006319), ENGLISH_ENTRY("illuminationdiminishing", "IlluminationDiminishing.exe", "b142b43c146c25443a1d155d441a6a81", 21227029), ENGLISH_ENTRY("illuminationdiminishing", "IlluminationDiminishing.exe", "b142b43c146c25443a1d155d441a6a81", 49006279), + ENGLISH_ENTRY("illuminationdiminishing", "IlluminationDiminishing.exe", "b142b43c146c25443a1d155d441a6a81", 49006319), ENGLISH_ENTRY("imnotcrazyrightthecell", "I'm not crazy.exe", "9cb3c8dc7a8ab9c44815955696be2677", 3152216), ENGLISH_ENTRY("imnotcrazyrightthewell", "The Well.exe", "9cb3c8dc7a8ab9c44815955696be2677", 5000358), ENGLISH_ENTRY("indianajonescomingofage", "IndyCOA.exe", "90413e9ae57e222f8913b09d2bc847bc", 2368083), @@ -1962,6 +1969,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("justignorethem", "justignorethem.exe", "7a3096ac0237cb6aa8e1718e28caf039", 98544330), ENGLISH_ENTRY("kanjigakusei", "KanjiGakusei.exe", "c1bce0ccfa858f0f5d2fe19997d89b05", 17604764), ENGLISH_ENTRY("kartquestv053", "Kart.exe", "465f972675db2da6040518221af5b0ba", 77317312), + ENGLISH_ENTRY("kathyrain", "kathyrain.exe", "434e24a12ba3cfb07d7b4b2f0e0bb1bf", 197487159), // Steam ENGLISH_ENTRY("keptoshi", "Keptosh.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 2904848), ENGLISH_ENTRY("keys", "Keys.exe", "75f4c7f66b1be60af5b2d65f617b91a7", 85582285), ENGLISH_ENTRY("killereye", "killereye.exe", "0710e2ec71042617f565c01824f0cf3c", 1009042), @@ -2038,6 +2046,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("lukesexistentialnightmare", "Lukeexit.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 653834), ENGLISH_ENTRY("lunarlanderprototype", "LunarLanderPrototype.exe", "495d45fb8adfd49690ae3b97921feec6", 3510282), ENGLISH_ENTRY("lydiaandthemysteryofnellrenomanor", "LydiaW.exe", "615e73fc1874e92d60a1996c2330ea36", 33971307), + ENGLISH_ENTRY("mage", "ac2game.dat", "2e822f554994f36e0c62da2acda874da", 30492258), // GOG, Mac ENGLISH_ENTRY("maggieandmax", "Max.exe", "465f972675db2da6040518221af5b0ba", 5759981), ENGLISH_ENTRY("magic8ball", "Magic-8-Ball.exe", "82da2565c456dcfb265ded6fe3189c0b", 4233735), ENGLISH_ENTRY("magicalwhatevergirlrocksoutinthestoneage", "mwg.exe", "b2b99b5b3dcaee0fa292343c5a2c429b", 7784104), @@ -2116,8 +2125,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("mysticseer", "NickOfTime.exe", "f120690b506dd63cd7d1112ea6af2f77", 4460113), ENGLISH_ENTRY("mythicalgambitflawlessfatality", "MGFF.exe", "4887d3dca056a0772741b42f66e018fb", 59711760), ENGLISH_ENTRY("nanobots", "Nanobots.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 41977727), - ENGLISH_ENTRY("necroquest", "necroquest01.exe", "6d4adcef07a14b53369d23edf5117252", 12389204), ENGLISH_ENTRY("necroquest", "necroquest01.exe", "2d111a69de0723f337bad661cb006239", 9545924), + ENGLISH_ENTRY("necroquest", "necroquest01.exe", "6d4adcef07a14b53369d23edf5117252", 12389204), ENGLISH_ENTRY("nedysadventure", "Nedy.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 6463558), ENGLISH_ENTRY("nekusnewtrip", "nnt.exe", "c0c1865c3c8369e034095a725ca1ddbf", 35012412), ENGLISH_ENTRY("nekusnewtrip", "square enix.exe", "a524cbb1c51589903c4043b98917f1d9", 10630694), @@ -2152,6 +2161,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("oneweekoneroom", "1 week 1 room.exe", "06a03fe35791b0578068ab1873455463", 4275934), ENGLISH_ENTRY("onleavingthebuilding", "On Leaving The Building.exe", "fd68fced8b89792d2e90be87b33d4b19", 64776995), ENGLISH_ENTRY("onlythegooddieyoungenglishversion", "OtGDY_En.exe", "87ccd318a469128530699388f916b86f", 153980124), + ENGLISH_ENTRY("oott", "OotT-TKC.exe", "11c2421258465cba4bd773c49d918ee3", 467834855), // GOG ENGLISH_ENTRY("openquest", "OpenQuest.exe", "90413e9ae57e222f8913b09d2bc847bc", 3407165), ENGLISH_ENTRY("operationnovi", "Operation Novi.exe", "465f972675db2da6040518221af5b0ba", 24583968), ENGLISH_ENTRY("operationsavebluecup", "OSBC.exe", "f120690b506dd63cd7d1112ea6af2f77", 3040865), @@ -2230,12 +2240,13 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("pubmasterquest2", "shogin crystal.exe", "90baefd2f369cebe25f3aa9ad90332d2", 35191110), ENGLISH_ENTRY("pubmastersquest", "Pub Master Quest [Demo].exe", "e1676318c8a040fcf508b817013dc8fe", 23431689), ENGLISH_ENTRY("puddypenguin", "Penguin.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2328158), - ENGLISH_ENTRY("pupupupulaisenseikkailut", "Pupupeli.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 13453697), ENGLISH_ENTRY("pupupupulaisenseikkailut", "Game.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 13431315), + ENGLISH_ENTRY("pupupupulaisenseikkailut", "Pupupeli.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 13453697), ENGLISH_ENTRY("purgatorio01", "Purgatorio 0.1.exe", "18b284c22010850f79bc5c20054a70c4", 194293367), ENGLISH_ENTRY("purityofthesurf", "Surf.exe", "71ca0d6c1c699595f28a2125948d4a84", 11315703), ENGLISH_ENTRY("puzzlebotsdemo", "Puzzlebots_Demo.exe", "34b49df9cf6eadb5c3587b3921d5b72f", 354138961), ENGLISH_ENTRY("pxenophobe", "ProjXeno.exe", "465f972675db2da6040518221af5b0ba", 79053486), + ENGLISH_ENTRY("qfi", "qfi.exe", "0702df6e67ef87fd3c51d09303803126", 534847265), // GOG ENGLISH_ENTRY("quantumnauts", "QNDEMO.exe", "aeb2dd29e5ff839cb3ee86cf3e87e3ca", 134237367), ENGLISH_ENTRY("questfighter", "Quest Fighter.exe", "21fd0f65dfa48de2b39cb8ec23b30889", 2914128), ENGLISH_ENTRY("questfighterii", "Quest Fighter 2.exe", "4d7d2addcde045dae6e0363a43f9acad", 5219511), @@ -2271,8 +2282,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("returntocivilization", "ReturnTo.exe", "0710e2ec71042617f565c01824f0cf3c", 3280888), ENGLISH_ENTRY("revelation10", "Revelation.exe", "06a03fe35791b0578068ab1873455463", 14512328), ENGLISH_ENTRY("rickyquest", "black.exe", "06a03fe35791b0578068ab1873455463", 3250100), - ENGLISH_ENTRY("righteouscity", "RCII.exe", "06a03fe35791b0578068ab1873455463", 39085407), ENGLISH_ENTRY("righteouscity", "RC PI - 3.00.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 19786840), + ENGLISH_ENTRY("righteouscity", "RCII.exe", "06a03fe35791b0578068ab1873455463", 39085407), ENGLISH_ENTRY("roadofdestiny", "ROD.exe", "618d7dce9631229b4579340b964c6810", 30127308), ENGLISH_ENTRY("roadracer", "TR_Bryvis.exe", "cebb3ac5c3d2df939e7f0ec8f2975b64", 25080647), ENGLISH_ENTRY("roastmothergoose", "RMG.exe", "00328f4f1e7729144483107b96b11df8", 46474982), @@ -2317,7 +2328,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("schwarzweissrot", "SchwarzWeissRot.exe", "495d45fb8adfd49690ae3b97921feec6", 82913128), ENGLISH_ENTRY("scnider", "scnider.exe", "3128b9f90e2f954ba704414ae854d10b", 1189237), ENGLISH_ENTRY("scytheisland", "Scythe.exe", "0500aacb6c176d47ac0f8158f055db83", 7119760), - ENGLISH_DEMO("searchforsanity", "sfs.exe", "308d35bc34e9df29d8acce615593e3e7", 9097147), ENGLISH_ENTRY("seashells", "Shells.exe", "0500aacb6c176d47ac0f8158f055db83", 6355325), ENGLISH_ENTRY("seasongreetings2002", "xmas2002.exe", "97d700529f5cc826f230c27acf81adfd", 4263336), ENGLISH_ENTRY("secretquestremake", "secretquest.exe", "f120690b506dd63cd7d1112ea6af2f77", 2121159), @@ -2325,9 +2335,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("seega16engl5", "house_eng_5.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1746878), ENGLISH_ENTRY("seegame15", "housesitting_18.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 1746919), ENGLISH_ENTRY("sevendoors", "7DOORS.exe", "18b284c22010850f79bc5c20054a70c4", 113716886), - ENGLISH_ENTRY("stargateadv", "StarGA.exe", "0710e2ec71042617f565c01824f0cf3c", 45738298), ENGLISH_ENTRY("shadesofgreye", "Shades of Greye.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 16125855), - ENGLISH_DEMO("shadowsoftheempire", "sote_td.exe", "b8cd640b45c5a79c33c7a8a8fe32ebe2", 63299246), ENGLISH_ENTRY("shailadusithlenqute", "Shai-la Enquete.exe", "a524cbb1c51589903c4043b98917f1d9", 7489302), ENGLISH_ENTRY("shailaofthesith", "Shaila_of_the_Sith.exe", "a524cbb1c51589903c4043b98917f1d9", 76170347), ENGLISH_ENTRY("shem", "Shem.exe", "0710e2ec71042617f565c01824f0cf3c", 8866401), @@ -2379,22 +2387,23 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("spooks", "Spooks.exe", "0710e2ec71042617f565c01824f0cf3c", 22888238), ENGLISH_ENTRY("spoonsiiitheunauthorizededition", "spoonsIII.exe", "2ca80bd50763378b72cd1e1cf25afac3", 16298983), ENGLISH_ENTRY("spotthedifference", "Spot the Difference.exe", "0b7529a76f38283d6e850b8d56526fc1", 933452), + ENGLISH_ENTRY("sproutsofevil", "Sprouts of evil.exe", "bdd1df0484e296faa348ffcb03e16273", 22329944), + ENGLISH_ENTRY("sqkubikgetready", "SQ Kubik.exe", "4fb72c890984548ed6782063f2230942", 2184808), ENGLISH_ENTRY("sqm11", "SQM1.exe", "465f972675db2da6040518221af5b0ba", 1001506), ENGLISH_ENTRY("sqm12", "SQM 1x2.exe", "465f972675db2da6040518221af5b0ba", 755146), ENGLISH_ENTRY("sqm13", "SQM 1x3.exe", "465f972675db2da6040518221af5b0ba", 1435210), ENGLISH_ENTRY("sqm14", "SQM 1x4.exe", "465f972675db2da6040518221af5b0ba", 1383567), ENGLISH_ENTRY("sqm16", "SQM 1x6.exe", "465f972675db2da6040518221af5b0ba", 1400100), - ENGLISH_ENTRY("sproutsofevil", "Sprouts of evil.exe", "bdd1df0484e296faa348ffcb03e16273", 22329944), - ENGLISH_ENTRY("sqkubikgetready", "SQ Kubik.exe", "4fb72c890984548ed6782063f2230942", 2184808), ENGLISH_ENTRY("sqmania1", "SQMania1.exe", "465f972675db2da6040518221af5b0ba", 831674), ENGLISH_ENTRY("sqmania2remakeeng", "SQM2 RMK.exe", "465f972675db2da6040518221af5b0ba", 3029288), ENGLISH_ENTRY("sqmaniaep5", "SQ Mania Ep5.exe", "a524cbb1c51589903c4043b98917f1d9", 2896204), ENGLISH_ENTRY("sram2cinomehsrevengedemo", "SRAM2.exe", "e3a33d139d90f2e695292a618753b8a5", 296499943), - ENGLISH_ENTRY("stablepeteandthejoust", "StablePete.exe", "b142b43c146c25443a1d155d441a6a81", 30048075), ENGLISH_ENTRY("stablepeteandthejoust", "StablePete.exe", "b142b43c146c25443a1d155d441a6a81", 30046740), + ENGLISH_ENTRY("stablepeteandthejoust", "StablePete.exe", "b142b43c146c25443a1d155d441a6a81", 30048075), ENGLISH_ENTRY("stairquest", "Stair Quest.exe", "e0aeab6a2c479fde167c4c43c3abb8ca", 4550699), ENGLISH_ENTRY("stanamespiepisode1", "NEW.exe", "f120690b506dd63cd7d1112ea6af2f77", 19194728), ENGLISH_ENTRY("stansrevenge", "Gameisle.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 915036), + ENGLISH_ENTRY("stargateadv", "StarGA.exe", "0710e2ec71042617f565c01824f0cf3c", 45738298), ENGLISH_ENTRY("starshipcaramba", "karamba.exe", "465f972675db2da6040518221af5b0ba", 21540340), ENGLISH_ENTRY("starshipposeidon", "Starship Poseidon.exe", "5a9abb3094d0b3f4bc09c0c77fbb8024", 4163873), ENGLISH_ENTRY("start", "CC1.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 18627665), @@ -2402,7 +2411,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("stediddyip1employment", "stediddy1.exe", "5872fea5a958bc74c2d9ca7b2d196c42", 27136166), ENGLISH_ENTRY("stickmeni", "stick.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2399329), ENGLISH_ENTRY("stickythestickfigurepart1thecrimsonhouse", "Crimson House Files.exe", "3b095a7872e04769d04ab45e9c1b66eb", 3610653), - ENGLISH_ENTRY("grok", "grok.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1046039), ENGLISH_ENTRY("stranded", "Stranded.exe", "18b284c22010850f79bc5c20054a70c4", 39791629), ENGLISH_ENTRY("stranger", "Stranger.exe", "0500aacb6c176d47ac0f8158f055db83", 5854099), ENGLISH_ENTRY("strangerinstickworld", "game1.exe", "a524cbb1c51589903c4043b98917f1d9", 42525810), @@ -2442,8 +2450,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("thebunker", "The Bunker.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12391058), ENGLISH_ENTRY("thecadaversynod", "The cadaver synod.exe", "36f44e064eab15e502caeb60fd09f52d", 37438749), ENGLISH_ENTRY("thecan", "TheCan.exe", "82da2565c456dcfb265ded6fe3189c0b", 72388782), - ENGLISH_ENTRY("thecell", "The Cell.exe", "b142b43c146c25443a1d155d441a6a81", 21422530), ENGLISH_ENTRY("thecell", "Cell.exe", "0b7529a76f38283d6e850b8d56526fc1", 811527), + ENGLISH_ENTRY("thecell", "The Cell.exe", "b142b43c146c25443a1d155d441a6a81", 21422530), ENGLISH_ENTRY("thechrysalis", "Mygame.exe", "22b9c6d170613eb01afa1697b1b75cdb", 28926604), ENGLISH_ENTRY("thecrackwelllegacy", "Crackwell.exe", "06a03fe35791b0578068ab1873455463", 2990976), ENGLISH_ENTRY("thecube", "The Cube.exe", "97d700529f5cc826f230c27acf81adfd", 2029985), @@ -2481,7 +2489,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("thejourneyofiesir", "The Journey of Iesir.exe", "376a3f162c7940d990325c53edc20fed", 70444514), ENGLISH_ENTRY("thelastharvest", "The Last Harvest.exe", "f120690b506dd63cd7d1112ea6af2f77", 6253816), ENGLISH_ENTRY("thelastsupperawhodunnit", "THE LAST SUPPER, A WHODUNNIT.exe", "37500274a7882e8087042cc6ec851e0c", 13447848), - ENGLISH_DEMO("theloneloser", "DEMO (English).exe", "0500aacb6c176d47ac0f8158f055db83", 6082095), ENGLISH_ENTRY("thelongtrip", "longtrip.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 184362586), ENGLISH_ENTRY("themajesticconspiracy", "majestic.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 17929647), ENGLISH_ENTRY("themarionette", "marionette.exe", "ff3d6e4edfca8b4f4f1c6cbf8e2781a6", 88408446), @@ -2518,8 +2525,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("thetrap", "Darcy.exe", "0500aacb6c176d47ac0f8158f055db83", 1164147), ENGLISH_ENTRY("thetreasuredmedallion", "The Treasured Medallion.exe", "504df40bf50a0859e3dc15b000dab5f6", 1091122652), ENGLISH_ENTRY("thetreasureoflochinch", "LochInch.exe", "6e861b1f476ff7cdf036082abb271329", 4091983), - ENGLISH_ENTRY("theuncertaintymachine", "TUMv11.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 20672955), ENGLISH_ENTRY("theuncertaintymachine", "TUMv11.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 20670414), + ENGLISH_ENTRY("theuncertaintymachine", "TUMv11.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 20672955), ENGLISH_ENTRY("theupliftmofopartyplan", "MI5 Bob.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4092850), ENGLISH_ENTRY("thevacuum", "Spacefiles.exe", "d0ba73645e3cbf8ccd65121417f9895f", 14805166), ENGLISH_ENTRY("thewitch", "Witch.exe", "f120690b506dd63cd7d1112ea6af2f77", 2693486), @@ -2553,6 +2560,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("twoofakind", "toak.exe", "465f972675db2da6040518221af5b0ba", 24644765), ENGLISH_ENTRY("uglyfiles", "ugly.exe", "0394af1c29e1060fcdbacf2a3dd9b231", 4169486), ENGLISH_ENTRY("ulitsadimitrova", "ulitsa.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 291828379), + ENGLISH_ENTRY("unavowed", "ac2game.dat", "b1ff7d96667707daf4266975cea2bf90", 1755457364), // Steam, Mac ENGLISH_ENTRY("unboundver10", "Unbound.exe", "900b277d7e1601c65b42868cd7fae662", 10448702), ENGLISH_ENTRY("unfinished", "mags.exe", "0710e2ec71042617f565c01824f0cf3c", 12092514), ENGLISH_ENTRY("unganeedsmumba", "UNGA needs MUMBA.exe", "2ca6bb6d5b2710ac89fea7d69c2eaf77", 5470102), @@ -2573,7 +2581,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("vohaulsrevengeii", "SQ XII.exe", "465f972675db2da6040518221af5b0ba", 17313307), ENGLISH_ENTRY("vpxt2", "VPET!2!.exe", "0b7529a76f38283d6e850b8d56526fc1", 12933096), ENGLISH_ENTRY("waitingfortheloop", "WaitingForTheLoop.exe", "0241777c2537fc5d077c05cde10bfa9f", 51273604), - ENGLISH_DEMO("wallyweasel", "WallyDemo.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 12579444), ENGLISH_ENTRY("waltersasteroid", "HDGame.exe", "465f972675db2da6040518221af5b0ba", 8390872), ENGLISH_ENTRY("warthogs", "Warthogs.exe", "9c49b6fa0460f36d6e7558281f142683", 12448793), ENGLISH_ENTRY("washedashore", "Achtung!.exe", "06a03fe35791b0578068ab1873455463", 7926840), From 0d7a78bb3dd4c1aa9ac8f913756908798d72f1d1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 1 Feb 2021 20:14:50 -0800 Subject: [PATCH 199/215] AGS: Cleanup of demo detection entries --- engines/ags/detection_tables.h | 117 ++++++++++++++++----------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 9ab7ffe7c290..2a35af767f3f 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -216,7 +216,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "aloneinthenight", "Alone in the Night" }, { "alphadog", "Alpha Dog" }, { "alphax", "Alpha X" }, - { "alquest1demo", "Al-Quest 1 Demo" }, + { "alquest1", "Al-Quest 1" }, { "alysvsthephantomfelinefoe", "Alys vs. The Phantom Feline Foe" }, { "amagicstone", "A magic stone" }, { "amotospuf", "Amotos Puf" }, @@ -263,7 +263,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "badluck", "BAD LUCK" }, { "baldysadventure", "Baldy's Adventure" }, { "baltazarthefamiliar", "Baltazar the Familiar" }, - { "bananamandemo", "Banana Man Demo" }, + { "bananaman", "Banana Man" }, { "bananaracer", "Banana Racer" }, { "barndilemma", "Barn Dilemma" }, { "barnrunner5part1", "Barn Runner 5 (Part 1)" }, @@ -298,9 +298,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "blackmailinbrooklyn", "Blackmail In Brooklyn" }, { "blackmorph", "Black Morph" }, { "blackuddertodoubloonornottodoubloon", "Blackudder: To Doubloon or not to Doubloon" }, - { "blackwellconvergence", "Blackwell Convergence" }, - { "blackwelllegacydemo", "Blackwell Legacy Demo" }, - { "blackwellunbounddemo", "Blackwell Unbound Demo" }, { "bluemoon", "Blue Moon" }, { "boardquest", "Board Quest" }, { "bob", "BOB" }, @@ -418,7 +415,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "detention", "Detention" }, { "devochkaquest", "DevochkaQuest" }, { "dgsearchofthebatterie", "DG: search of the batterie" }, - { "diamondsintheroughdemo", "Diamonds in the Rough DEMO" }, + { "diamondsintherough", "Diamonds in the Rough" }, { "diemaskennyarlathoteps", "Die Masken Nyarlathoteps" }, { "disquiet", "Disquiet" }, { "doctormaze", "DOCTOR MAZE" }, @@ -438,7 +435,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "dreamer", "Dreamer" }, { "dreamsequence", "dream sequence" }, { "drlutztimetravelmachine", "Dr.Lutz Time Travel Machine" }, - { "dumbassdriversdemo", "Dumb.Ass Drivers! DEMO" }, + { "dumbassdrivers", "Dumb.Ass Drivers!" }, { "dungeonhands", "Dungeon Hands" }, { "duskhunters", "Dusk Hunters" }, { "dusttowater", "Dust to Water" }, @@ -446,7 +443,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "duzzquest", "DuzzQuest" }, { "duzzquest2", "DuzzQuest2" }, { "dysmaton", "Dysmaton" }, - { "earlbobbyislookingforaloodemo", "Earl Bobby is looking for a Loo - DEMO" }, + { "earlbobbyislookingforaloo", "Earl Bobby is looking for a Loo" }, { "earlbobbyislookingforhisshoes", "Earl Bobby is looking for his Shoes" }, { "earlbobbysballs", "Earl Bobby's Balls" }, { "earlmansinthebreakout", "Earl Mansin: The Breakout" }, @@ -464,7 +461,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "eliminationbyimprovisation", "Elimination by Improvisation" }, { "emeraldeyes", "Emerald Eyes" }, { "emilyenough", "Emily Enough" }, - { "emmarodedemo", "Emma Ro?de (DEMO)" }, + { "emmarode", "Emma Rode" }, { "emptymindblankfate", "Empty Mind - Blank Fate" }, { "enoworld", "Enoworld" }, { "enterthestory", "Enter The Story" }, @@ -512,7 +509,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "forgettendeath", "Forgetten Death " }, { "fortressofwonders", "Fortress of Wonders" }, { "fountainofunicorns", "Fountain of Unicorns" }, - { "fountainofyouthdemo", "Fountain of Youth Demo" }, + { "fountainofyouth", "Indiana Jones and the Fountain of Youth" }, { "framed", "Framed!" }, { "frankenpooper", "Frankenpooper" }, { "frankthefarmhandpart1", "Frank the Farmhand Part 1" }, @@ -532,11 +529,11 @@ const PlainGameDescriptor GAME_NAMES[] = { { "funwithnumbers", "Fun With Numbers" }, { "gabyking", "GabyKing" }, { "gamesgalore", "GAMES GALORE" }, - { "gassesuittollis3demo", "Gasse Suit Tollis 3 DEMO" }, + { "gassesuittollis3", "Gasse Suit Tollis 3" }, { "gatewayremake", "Gateway Remake" }, { "genbu", "Genbu" }, { "geometricshapes1circleboy", "Geometric Shapes 1: Circleboy" }, - { "gesundheitdemo", "Gesundheit! Demo" }, + { "gesundheit", "Gesundheit!" }, { "getawayfrompluto", "Get away from PLUTO" }, { "getfood", "Get food" }, { "ghostdream", "Ghostdream" }, @@ -631,7 +628,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "jamesbond", "James Bond" }, { "jamesinneverland", "James in Neverland" }, { "jamesperis", "James Peris" }, - { "jamesperis2demo", "James Peris 2 Demo" }, + { "jamesperis2", "James Peris 2" }, { "javelincatch", "Javelin Catch" }, { "jimmsquestiii", "Jimm's Quest III" }, { "jimmysday", "Jimmy's Day" }, @@ -659,7 +656,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "killthelights", "Kill The Lights" }, { "kingdomlegends", "Kingdom Legends" }, { "kingsquestiii", "Kings Quest III" }, - { "kinkyislanddemo", "Kinky Island DEMO" }, + { "kinkyisland", "Kinky Island" }, { "knightquestforgoldenring", "Knight Quest for Golden Ring" }, { "knightsquestiii", "Knight's Quest III" }, { "knightsquestiv", "Knight's Quest IV" }, @@ -683,7 +680,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "laundryday", "Laundry Day" }, { "lavablava", "Lava Blava" }, { "lazaruswantspants", "Lazarus Wants Pants" }, - { "lazytownthenewkiddemo", "LazyTown: The New Kid (demo)" }, + { "lazytownthenewkid", "LazyTown: The New Kid" }, { "lbstoryofcedrickdusce", "LB: Story of Cedrick DUSCE!" }, { "legendofrovendale", "Legend of Rovendale" }, { "legendofseththebard", "Legend of Seth the Bard" }, @@ -920,7 +917,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "pupupupulaisenseikkailut", "Pupu Pupulaisen Seikkailut" }, { "purgatorio01", "Purgatorio 0.1" }, { "purityofthesurf", "Purity of the Surf" }, - { "puzzlebotsdemo", "Puzzle Bots Demo" }, + { "puzzlebots", "Puzzle Bots" }, { "pxenophobe", "PXenophobe" }, { "qfi", "Quest for Infamy" }, { "quantumnauts", "QUANTUMNAUTS" }, @@ -1015,7 +1012,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "shem", "Shem" }, { "sherlock", "Sherlock" }, { "shiftersboxoutsidein", "Shifter's Box - Outside In" }, - { "shivahdemo", "Shivahdemo" }, + { "shivah", "Shivah" }, { "shoot", "Shoot" }, { "shootmyvalentine", "Shoot my Valentine" }, { "shortcut", "ShortCut" }, @@ -1024,7 +1021,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "sierraquest1", "Sierra Quest 1" }, { "silentknightii", "Silent Knight II" }, { "silentknightv11", "Silent Knight v.1.1" }, - { "simonthesorcerer3demo20", "Simon the Sorcerer 3 Demo 2.0" }, + { "simonthesorcerer3", "Simon the Sorcerer 3" }, { "skippysavestheday", "Skippy Saves The Day" }, { "slaythedragon", "Slay the Dragon" }, { "sleepyisland", "Sleepy Island" }, @@ -1049,9 +1046,9 @@ const PlainGameDescriptor GAME_NAMES[] = { { "spacelynxes", "Space Lynxes" }, { "spacepirates", "Space Pirates" }, { "spacepoolalpha", "Space Pool Alpha" }, - { "spacequest3vgapreview", "Space Quest III VGA Preview" }, + { "spacequest3vga", "Space Quest III VGA Preview" }, { "spacequest45", "Space Quest 4.5" }, - { "spacequest55demoags", "Space Quest 5.5 demo (AGS)" }, + { "spacequest55", "Space Quest 5.5" }, { "spacerangers", "Space Rangers " }, { "spacerangersep52", "Space Rangers Ep 52" }, { "spacewar", "Space war" }, @@ -1071,7 +1068,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "sqmania1", "SQ Mania #1" }, { "sqmania2remakeeng", "SQ Mania 2 Remake (ENG)" }, { "sqmaniaep5", "SQ Mania Ep5" }, - { "sram2cinomehsrevengedemo", "SRAM 2 - CINOMEH'S REVENGE (demo)" }, + { "sram2", "SRAM 2 - Cinomeh's Revenge" }, { "stablepeteandthejoust", "Stable Pete and the Joust" }, { "stairquest", "Stair Quest" }, { "stanamespiepisode1", "Stan Ames PI, Episode 1" }, @@ -1090,7 +1087,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "strangerthings", "Stranger Things" }, { "supaevil", "Supa-EviL" }, { "supergirl", "Supergirl" }, - { "superjazzmandemo", "Super Jazz Man (DEMO)" }, + { "superjazzman", "Super Jazz Man" }, { "superracing", "Super Racing" }, { "surreality", "Surreality" }, { "sweed", "Sweed" }, @@ -1206,8 +1203,8 @@ const PlainGameDescriptor GAME_NAMES[] = { { "threeguyswalkintoheaven", "Three Guys Walk Into Heaven" }, { "tilepuzzlegame", "Tile Puzzle Game" }, { "tiltor", "Tiltor" }, - { "timegentlemenpleasedemo", "Time Gentlemen, Please DEMO" }, - { "timequest", "Time Quest" }, + { "timegentlemenplease", "Time Gentlemen, Please" }, + { "timequest1", "Time Quest" }, { "timequest2", "Time Quest 2" }, { "timesinkofchronos", "Timesink of Chronos" }, { "timothylande", "Timothy Lande" }, @@ -1290,7 +1287,7 @@ const PlainGameDescriptor GAME_NAMES[] = { { "yoda", "Yoda" }, { "yourlate", "Your late!" }, { "zakmckracken", "Zak McKracken" }, - { "zombieattackdemo", "Zombie Attack Demo" }, + { "zombieattack", "Zombie Attack" }, { "zombiefish", "Zombie Fish" }, { "zooreal", "ZooReal" }, { "zugzwang", "Zugzwang" }, @@ -1452,11 +1449,45 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("resonance", "resonance.exe", "2e635c22bcbf0ed3d46f1bcde71812d4", 849404957), // GOG // Post-2.5 games that are likely supported by the AGS engine + ENGLISH_DEMO("alquest1", "AlQuest.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 20154310), + ENGLISH_DEMO("bananaman", "Banana Man Demo.exe", "615e806856b7730afadf1fea9a756b70", 53524952), + ENGLISH_DEMO("blackwell1", "Blackwell Demo.exe", "2eeca6bae968dc61b5ed36561efc0fca", 53342880), + ENGLISH_DEMO("blackwell2", "Unbound_Demo.exe", "6ee842f73649ced615c44d4eb303687c", 30057537), + ENGLISH_DEMO("blackwell3", "Convergence.exe", "856a6e0e22d2cb4a45d5bbc7245ce5e8", 29935120), ENGLISH_DEMO("bytheswordconspiracy", "bts.exe", "7dc7f61f79ba7a77d4ef8168bfd3d173", 60246329), + ENGLISH_DEMO("diamondsintherough", "Diamonds Demo.exe", "14c995189266969d538b31d1df451d3f", 2439365), + ENGLISH_DEMO("dumbassdrivers", "dumbass.exe", "f120690b506dd63cd7d1112ea6af2f77", 40580988), + ENGLISH_DEMO("earlbobbyislookingforaloo", "Demo.exe", "0e32c4b3380e286dc0cea8550f1c045e", 4221725), + ENGLISH_DEMO("emmarode", "Emma Roide.exe", "aefd91a131817036d224fe030e406c6e", 24919443), + ENGLISH_DEMO("flashbax", "demo Flashbax.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 5527034), + ENGLISH_DEMO("forcemajeureiithezone", "TheZoneDemo.exe", "b63d26c17bf292017f9a708ae9dc38ca", 18414473), + ENGLISH_DEMO("fountainofyouth", "foydemo.exe", "f120690b506dd63cd7d1112ea6af2f77", 14372003), + ENGLISH_DEMO("gassesuittollis3", "Gst3_demo.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4270243), + ENGLISH_DEMO("gesundheit", "gesundheit.exe", "5554b9e0df6241d25c9a070708e54478", 49666357), + ENGLISH_DEMO("hiliaderoleagainsthell", "Dark Trial demo.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 36442694), + ENGLISH_DEMO("indycositalianver", "CoSdemo2.1-it.exe", "f120690b506dd63cd7d1112ea6af2f77", 5772985), + ENGLISH_DEMO("jamesperis2", "James2.exe", "06a03fe35791b0578068ab1873455463", 35766505), + ENGLISH_DEMO("jorry", "JORRY DEMO.exe", "fe5f7dc7785b335aec72a2a834629bad", 124667001), + ENGLISH_DEMO("kinkyisland", "KINKY.exe", "f120690b506dd63cd7d1112ea6af2f77", 10628479), + ENGLISH_DEMO("lazytownthenewkid", "newkiddemo1.2.exe", "9cb3c8dc7a8ab9c44815955696be2677", 15515508), + ENGLISH_DEMO("litnunforgettablememories", "litn_umtechdemo.exe", "f120690b506dd63cd7d1112ea6af2f77", 3507831), + ENGLISH_DEMO("mi5thereturnoflechuck", "Demo.exe", "0500aacb6c176d47ac0f8158f055db83", 6235270), + ENGLISH_DEMO("neofeud", "Neofeud Demo.exe", "6e861b1f476ff7cdf036082abb271329", 1886913453), + ENGLISH_DEMO("pubmastersquest", "Pub Master Quest [Demo].exe", "e1676318c8a040fcf508b817013dc8fe", 23431689), + ENGLISH_DEMO("puzzlebots", "Puzzlebots_Demo.exe", "34b49df9cf6eadb5c3587b3921d5b72f", 354138961), + ENGLISH_DEMO("quantumnauts", "QNDEMO.exe", "aeb2dd29e5ff839cb3ee86cf3e87e3ca", 134237367), ENGLISH_DEMO("searchforsanity", "sfs.exe", "308d35bc34e9df29d8acce615593e3e7", 9097147), ENGLISH_DEMO("shadowsoftheempire", "sote_td.exe", "b8cd640b45c5a79c33c7a8a8fe32ebe2", 63299246), + ENGLISH_DEMO("shivah", "shivahDemo.exe", "6e3d6225dee662ff6450a3bfa942773b", 20897850), + ENGLISH_DEMO("simonthesorcerer3", "Simon3.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 8189928), + ENGLISH_DEMO("spacequest3vga", "SQ3VGADEMO.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3630019), + ENGLISH_DEMO("spacequest55", "SQ5.5.exe", "465f972675db2da6040518221af5b0ba", 16342443), + ENGLISH_DEMO("sram2", "SRAM2.exe", "e3a33d139d90f2e695292a618753b8a5", 296499943), + ENGLISH_DEMO("superjazzman", "SJMdemo.exe", "0710e2ec71042617f565c01824f0cf3c", 5214882), ENGLISH_DEMO("theloneloser", "DEMO (English).exe", "0500aacb6c176d47ac0f8158f055db83", 6082095), + ENGLISH_DEMO("timegentlemenplease", "TGP.exe", "86a5359bac7c88f0dfa060478800dd61", 29686006), ENGLISH_DEMO("wallyweasel", "WallyDemo.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 12579444), + ENGLISH_DEMO("zombieattack", "ZADemo.exe", "82da2565c456dcfb265ded6fe3189c0b", 20958555), ENGLISH_ENTRY("10waysfromsunday", "10WaysFromSunday.exe", "495d45fb8adfd49690ae3b97921feec6", 11362765), ENGLISH_ENTRY("1dayamosquito", "mosquito.exe", "465f972675db2da6040518221af5b0ba", 2178983), ENGLISH_ENTRY("2034acaftercanadaii", "2034 AC II.exe", "1280ba7c269a68a9505871516319db0c", 35207006), @@ -1525,7 +1556,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("alphadog", "Alpha_Dog.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3329253), ENGLISH_ENTRY("alphax", "alphax.exe", "06a03fe35791b0578068ab1873455463", 17879795), ENGLISH_ENTRY("alphax", "Project SMASH.exe", "06a03fe35791b0578068ab1873455463", 25377719), - ENGLISH_ENTRY("alquest1demo", "AlQuest.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 20154310), ENGLISH_ENTRY("alysvsthephantomfelinefoe", "Alys.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 22323495), ENGLISH_ENTRY("amagicstone", "A magic stone.exe", "465f972675db2da6040518221af5b0ba", 5478520), ENGLISH_ENTRY("amotospuf", "Amotos.exe", "06a03fe35791b0578068ab1873455463", 10771879), @@ -1575,7 +1605,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("badluck", "Bad Luck.exe", "f120690b506dd63cd7d1112ea6af2f77", 10618466), ENGLISH_ENTRY("baldysadventure", "Baldy.exe", "ea0d3284542db629f36cb6fc785e07bc", 179358984), ENGLISH_ENTRY("baltazarthefamiliar", "Baltazar.exe", "9cb3c8dc7a8ab9c44815955696be2677", 2867294), - ENGLISH_ENTRY("bananamandemo", "Banana Man Demo.exe", "615e806856b7730afadf1fea9a756b70", 53524952), ENGLISH_ENTRY("bananaracer", "BananaRacer.exe", "e93f9dfa8405f1ca9f881d160ab31dc2", 10452233), ENGLISH_ENTRY("barndilemma", "woh.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 2432485), ENGLISH_ENTRY("barnrunner5part1", "Barn Runner 5-1.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 104073543), @@ -1610,9 +1639,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("blackmailinbrooklyn", "brooklyn.exe", "3192c36199d2b0784f866b28da7106d8", 4913695), ENGLISH_ENTRY("blackmorph", "Liechi.exe", "46859c6f77bdb311266daa589561fa6b", 14476030), ENGLISH_ENTRY("blackuddertodoubloonornottodoubloon", "Blackudder.exe", "338fa79960d40689063af31c671b8729", 87695958), - ENGLISH_ENTRY("blackwellconvergence", "Convergence.exe", "856a6e0e22d2cb4a45d5bbc7245ce5e8", 29935120), - ENGLISH_ENTRY("blackwelllegacydemo", "Blackwell Demo.exe", "2eeca6bae968dc61b5ed36561efc0fca", 53342880), - ENGLISH_ENTRY("blackwellunbounddemo", "Unbound_Demo.exe", "6ee842f73649ced615c44d4eb303687c", 30057537), ENGLISH_ENTRY("bluemoon", "Blue Moon.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 14845997), ENGLISH_ENTRY("boardquest", "Board Quest.exe", "465f972675db2da6040518221af5b0ba", 3930325), ENGLISH_ENTRY("bob", "bob.exe", "0b7529a76f38283d6e850b8d56526fc1", 2874144), @@ -1732,7 +1758,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("detention", "little.exe", "c16204dc8aa338e3199b2c62da0b33f4", 2362176), ENGLISH_ENTRY("devochkaquest", "DevochkaQuest.exe", "84faea68bf7277610c2229be7b3e74af", 32769660), ENGLISH_ENTRY("dgsearchofthebatterie", "dgsfb.exe", "88cf59aad15ca331ab0f854e16c84df3", 1664209), - ENGLISH_ENTRY("diamondsintheroughdemo", "Diamonds Demo.exe", "14c995189266969d538b31d1df451d3f", 2439365), ENGLISH_ENTRY("diemaskennyarlathoteps", "ags_masken.exe", "74dc062c5f68f3d70da911f2db5737b6", 129219473), ENGLISH_ENTRY("disquiet", "Disquiet.exe", "f90f5f612ed5879addfdd8634d093333", 9624101), ENGLISH_ENTRY("doctormaze", "Maze.exe", "825ccacaabe2a3b0cd48d6f8deb42d72", 43934617), @@ -1752,7 +1777,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("dreamer", "LittleDreamer.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 62151801), ENGLISH_ENTRY("dreamsequence", "dreamseq.ags", "97d700529f5cc826f230c27acf81adfd", 4724470), ENGLISH_ENTRY("drlutztimetravelmachine", "Dr.Lutz Machine.exe", "2bc8f994a7d1e05ed45f35abf2128231", 12602529), - ENGLISH_ENTRY("dumbassdriversdemo", "dumbass.exe", "f120690b506dd63cd7d1112ea6af2f77", 40580988), ENGLISH_ENTRY("dungeonhands", "DungeonHands.exe", "0a6704159f6f716ac80da91c430430ce", 16276450), ENGLISH_ENTRY("dungeonhands", "DungeonHands.exe", "f80ff6c2348f2bb90d3813719f54c870", 13751518), ENGLISH_ENTRY("duskhunters", "DuskHunters.exe", "3128b9f90e2f954ba704414ae854d10b", 3029482), @@ -1761,7 +1785,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("duzzquest", "DuzzQuest.exe", "3128b9f90e2f954ba704414ae854d10b", 13125200), ENGLISH_ENTRY("duzzquest2", "DuzzQuest2.exe", "8911d942c1a71458370d37ca3e5bfdda", 59088366), ENGLISH_ENTRY("dysmaton", "Dysmaton.exe", "6e861b1f476ff7cdf036082abb271329", 140513956), - ENGLISH_ENTRY("earlbobbyislookingforaloodemo", "Demo.exe", "0e32c4b3380e286dc0cea8550f1c045e", 4221725), ENGLISH_ENTRY("earlbobbyislookingforhisshoes", "Bobby's Shoes.exe", "bb59de174d70797d774dec76a171352d", 12735626), ENGLISH_ENTRY("earlbobbysballs", "Bobby's Balls.exe", "bb59de174d70797d774dec76a171352d", 4006605), ENGLISH_ENTRY("earlmansinthebreakout", "Earl Mansin.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 108987401), @@ -1779,7 +1802,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("eliminationbyimprovisation", "Stu2.exe", "9cf51833e787cc919837d9a8bd8fc14c", 971446), ENGLISH_ENTRY("emeraldeyes", "Emerald.exe", "f120690b506dd63cd7d1112ea6af2f77", 2849945), ENGLISH_ENTRY("emilyenough", "EE.exe", "97020973a2a635fe28eb0ba4bdfaa70b", 3141963), - ENGLISH_ENTRY("emmarodedemo", "Emma Roide.exe", "aefd91a131817036d224fe030e406c6e", 24919443), ENGLISH_ENTRY("emptymindblankfate", "EMBF.exe", "18b284c22010850f79bc5c20054a70c4", 75732051), ENGLISH_ENTRY("enoworld", "Enoworld.exe", "465f972675db2da6040518221af5b0ba", 16151170), ENGLISH_ENTRY("enterthestory", "Enter The Story.exe", "0514661a4ba6772cf0db0cf839fc7003", 19589742), @@ -1820,15 +1842,12 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("fightgame", "Fight Game.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 3551992), ENGLISH_ENTRY("fireflystory3d", "FFS 3D.exe", "27343924ddad3be0b97bdcaa71858b1b", 2254453), ENGLISH_ENTRY("flamebarrel", "Flame barrel.exe", "06a03fe35791b0578068ab1873455463", 2298745), - ENGLISH_ENTRY("flashbax", "demo Flashbax.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 5527034), ENGLISH_ENTRY("flowergirl", "flowergirl.exe", "9cb3c8dc7a8ab9c44815955696be2677", 62544543), ENGLISH_ENTRY("fluxworld", "FluxWorld.exe", "06a03fe35791b0578068ab1873455463", 5614789), - ENGLISH_ENTRY("forcemajeureiithezone", "TheZoneDemo.exe", "b63d26c17bf292017f9a708ae9dc38ca", 18414473), ENGLISH_ENTRY("forfrogssakegetthefrogout", "Frog2.exe", "0241777c2537fc5d077c05cde10bfa9f", 6723366), ENGLISH_ENTRY("forgettendeath", "ForgettenDeath.exe", "06a03fe35791b0578068ab1873455463", 19427130), ENGLISH_ENTRY("fortressofwonders", "Fortress.exe", "465f972675db2da6040518221af5b0ba", 4474304), ENGLISH_ENTRY("fountainofunicorns", "pmvi.exe", "465f972675db2da6040518221af5b0ba", 3038012), - ENGLISH_ENTRY("fountainofyouthdemo", "foydemo.exe", "f120690b506dd63cd7d1112ea6af2f77", 14372003), ENGLISH_ENTRY("framed", "Jhum.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 4572587), ENGLISH_ENTRY("frankenpooper", "frankenpooper.exe", "fb3b0f6bad923958d9d9198daea125e6", 24372899), ENGLISH_ENTRY("frankthefarmhandpart1", "Frank.exe", "0006c0a95a5f35ca0d275adecf9dfa1d", 22602166), @@ -1848,11 +1867,9 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("funwithnumbers", "fwn.exe", "a524cbb1c51589903c4043b98917f1d9", 18743833), ENGLISH_ENTRY("gabyking", "GabyKing.exe", "1fd15cc387812c04447d89729b24b097", 2289131), ENGLISH_ENTRY("gamesgalore", "gamesgalore.exe", "f120690b506dd63cd7d1112ea6af2f77", 7620552), - ENGLISH_ENTRY("gassesuittollis3demo", "Gst3_demo.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 4270243), ENGLISH_ENTRY("gatewayremake", "Gateway Remake.exe", "0241777c2537fc5d077c05cde10bfa9f", 210991212), ENGLISH_ENTRY("genbu", "Genbu.exe", "64fcaf7da0b257ea831f89c54be0ad72", 1892238), ENGLISH_ENTRY("geometricshapes1circleboy", "Circle1.exe", "06a03fe35791b0578068ab1873455463", 2389129), - ENGLISH_ENTRY("gesundheitdemo", "gesundheit.exe", "5554b9e0df6241d25c9a070708e54478", 49666357), ENGLISH_ENTRY("getawayfrompluto", "Get away.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 755529), ENGLISH_ENTRY("getfood", "getfood.exe", "495d45fb8adfd49690ae3b97921feec6", 10600153), ENGLISH_ENTRY("ghostdream", "Ghostdream.exe", "05594881531d62e4575545f3c8fd2576", 225600520), @@ -1900,7 +1917,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("hiddenplains", "eureka02.exe", "6afafd26476d17a5e2a8e41f690d3720", 384360829), ENGLISH_ENTRY("hiddentreasureryansfortune", "HiddenTRF.exe", "504df40bf50a0859e3dc15b000dab5f6", 7345149), ENGLISH_ENTRY("hide", "Hide.exe", "6e861b1f476ff7cdf036082abb271329", 13701886), - ENGLISH_ENTRY("hiliaderoleagainsthell", "Dark Trial demo.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 36442694), ENGLISH_ENTRY("him", "twin.exe", "6b4ceb9e327ac99479c08d825461f4cb", 23721672), ENGLISH_ENTRY("hitchhikersguidetothegalaxyremake", "HHGTG.exe", "e003041f4332f136920e636e39d3e127", 34956191), ENGLISH_ENTRY("hitthefreak", "HTF.EXE", "f3a13b2d6c2e0fe04c6f466062920e23", 3103477), @@ -1926,7 +1942,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("imnotcrazyrightthecell", "I'm not crazy.exe", "9cb3c8dc7a8ab9c44815955696be2677", 3152216), ENGLISH_ENTRY("imnotcrazyrightthewell", "The Well.exe", "9cb3c8dc7a8ab9c44815955696be2677", 5000358), ENGLISH_ENTRY("indianajonescomingofage", "IndyCOA.exe", "90413e9ae57e222f8913b09d2bc847bc", 2368083), - ENGLISH_ENTRY("indycositalianver", "CoSdemo2.1-it.exe", "f120690b506dd63cd7d1112ea6af2f77", 5772985), ENGLISH_ENTRY("infectionepii", "Infection_Ep_II_AGS.exe", "a524cbb1c51589903c4043b98917f1d9", 23691417), ENGLISH_ENTRY("infectionitheship", "Infection I.exe", "7132ff7d6b0bc1e9f3e4bd4755390626", 25974295), ENGLISH_ENTRY("inferno", "inf.exe", "97d700529f5cc826f230c27acf81adfd", 8783105), @@ -1949,7 +1964,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("jamesbond", "platform2.exe", "949f7440e3692b7366c2029979dee9a0", 4467701), ENGLISH_ENTRY("jamesinneverland", "JamesNeverland.exe", "06a03fe35791b0578068ab1873455463", 36488607), ENGLISH_ENTRY("jamesperis", "James1.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 85631684), - ENGLISH_ENTRY("jamesperis2demo", "James2.exe", "06a03fe35791b0578068ab1873455463", 35766505), ENGLISH_ENTRY("javelincatch", "JvlnCtch.exe", "3421b46ff95c5885603086c39a038a20", 1626263), ENGLISH_ENTRY("jimmsquestiii", "JQ3.EXE", "0b7529a76f38283d6e850b8d56526fc1", 4930906), ENGLISH_ENTRY("jimmysday", "jimmy.exe", "089fab88e6e1075a2f5b271f6f5b3c57", 13419394), @@ -1962,7 +1976,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("johnnyrocket", "Rocket.exe", "a524cbb1c51589903c4043b98917f1d9", 10366294), ENGLISH_ENTRY("johnsinclairvoodooinlondon", "John Sinclair - Voodoo in London.exe", "d72e72697a755c7de395b0f6c8cbbf0d", 56795991), ENGLISH_ENTRY("jonnysmallvalley", "Jonny Smallvalley.exe", "01d0e6bd812abaa307bcb10fc2193416", 34437869), - ENGLISH_ENTRY("jorry", "JORRY DEMO.exe", "fe5f7dc7785b335aec72a2a834629bad", 124667001), ENGLISH_ENTRY("juliusdangerous2", "Julius Dangerous 2.exe", "e2d4a98de69b1f8e6462c387710a441a", 146931732), ENGLISH_ENTRY("juliusdangerousandthespaceinvaders", "Julius Dangerous.exe", "ddaf3807f1fe16b2813ff832b4fb471a", 83137140), ENGLISH_ENTRY("justanotherpointnclickadventure", "Advent.exe", "6a98b4cc2f5a55421248be53f15a6a99", 9582620), @@ -1977,7 +1990,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("killthelights", "Kill The Lights.exe", "9b54ea3557373188d8388ec4d1ae5eed", 20416736), ENGLISH_ENTRY("kingdomlegends", "Kingdom Legends.exe", "06a03fe35791b0578068ab1873455463", 2254139), ENGLISH_ENTRY("kingsquestiii", "KQ3.exe", "f120690b506dd63cd7d1112ea6af2f77", 5883843), - ENGLISH_ENTRY("kinkyislanddemo", "KINKY.exe", "f120690b506dd63cd7d1112ea6af2f77", 10628479), ENGLISH_ENTRY("knightquestforgoldenring", "KQuestGoldRing.exe", "f120690b506dd63cd7d1112ea6af2f77", 2582542), ENGLISH_ENTRY("knightsquestiii", "KQ3TOM.exe", "0710e2ec71042617f565c01824f0cf3c", 8408641), ENGLISH_ENTRY("knightsquestiv", "MAGSQuest.exe", "0500aacb6c176d47ac0f8158f055db83", 4074151), @@ -2001,7 +2013,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("laundryday", "Laundry Day.exe", "06a03fe35791b0578068ab1873455463", 2456888), ENGLISH_ENTRY("lavablava", "Rumble.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2294674), ENGLISH_ENTRY("lazaruswantspants", "pants.exe", "9cf51833e787cc919837d9a8bd8fc14c", 1311852), - ENGLISH_ENTRY("lazytownthenewkiddemo", "newkiddemo1.2.exe", "9cb3c8dc7a8ab9c44815955696be2677", 15515508), ENGLISH_ENTRY("lbstoryofcedrickdusce", "lifeboat.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 3563681), ENGLISH_ENTRY("legendofrovendale", "Vampire.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 10018497), ENGLISH_ENTRY("legendofseththebard", "LOSTB 1.48.exe", "a524cbb1c51589903c4043b98917f1d9", 10669482), @@ -2021,7 +2032,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("likeafox", "likeafox.exe", "c7916b82f00c94013a3f7706b4d333c6", 2707737), ENGLISH_ENTRY("limbo", "Limbo Adventure.exe", "7c10efb8990fb48ded51fbcd88a6bf17", 30800724), ENGLISH_ENTRY("limeylizardwastewizard", "LLWW.exe", "fab982fd31570655ac3b1858bd8265e4", 33755872), - ENGLISH_ENTRY("litnunforgettablememories", "litn_umtechdemo.exe", "f120690b506dd63cd7d1112ea6af2f77", 3507831), ENGLISH_ENTRY("littlegirlinunderland", "Underland.exe", "06a03fe35791b0578068ab1873455463", 10125940), ENGLISH_ENTRY("livingnightmaredeluxe", "Living Nightmare.exe", "4415d633ea1a2dcd03ff0eff43f182ee", 9997554), ENGLISH_ENTRY("livingnightmareendlessdream", "LNED.exe", "4415d633ea1a2dcd03ff0eff43f182ee", 10671309), @@ -2082,7 +2092,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("meta", "META.exe", "06a03fe35791b0578068ab1873455463", 10113135), ENGLISH_ENTRY("meteorfamily20", "Meteor Family.exe", "06a03fe35791b0578068ab1873455463", 5759077), ENGLISH_ENTRY("meteorheadrecycled", "Meteorhead.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 5081311), - ENGLISH_ENTRY("mi5thereturnoflechuck", "Demo.exe", "0500aacb6c176d47ac0f8158f055db83", 6235270), ENGLISH_ENTRY("mibaddaytobedead", "Monkey.exe", "f120690b506dd63cd7d1112ea6af2f77", 2117238), ENGLISH_ENTRY("micarnivalofthedamned", "MI-COD.exe", "90413e9ae57e222f8913b09d2bc847bc", 5114086), ENGLISH_ENTRY("mickeymauserpart1", "MM.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12076323), @@ -2131,7 +2140,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("nekusnewtrip", "nnt.exe", "c0c1865c3c8369e034095a725ca1ddbf", 35012412), ENGLISH_ENTRY("nekusnewtrip", "square enix.exe", "a524cbb1c51589903c4043b98917f1d9", 10630694), ENGLISH_ENTRY("nellycootalotv15", "Nelly Cootalot.exe", "18b284c22010850f79bc5c20054a70c4", 108256323), - ENGLISH_ENTRY("neofeud", "Neofeud Demo.exe", "6e861b1f476ff7cdf036082abb271329", 1886913453), ENGLISH_ENTRY("nesquest", "NES Quest.exe", "8b72036706da98095057df615d07460b", 20881972), ENGLISH_ENTRY("news", "WI-AA.exe", "06a03fe35791b0578068ab1873455463", 29631312), ENGLISH_ENTRY("nickitandrun", "NIAREnglish.exe", "b25674056fe8cc0b7bf0a4409c5c5bfc", 14180082), @@ -2238,16 +2246,13 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("proxecto", "proxec.exe", "465f972675db2da6040518221af5b0ba", 2636209), ENGLISH_ENTRY("psychopomp", "psychopomp.exe", "b142b43c146c25443a1d155d441a6a81", 23721476), ENGLISH_ENTRY("pubmasterquest2", "shogin crystal.exe", "90baefd2f369cebe25f3aa9ad90332d2", 35191110), - ENGLISH_ENTRY("pubmastersquest", "Pub Master Quest [Demo].exe", "e1676318c8a040fcf508b817013dc8fe", 23431689), ENGLISH_ENTRY("puddypenguin", "Penguin.exe", "f3a13b2d6c2e0fe04c6f466062920e23", 2328158), ENGLISH_ENTRY("pupupupulaisenseikkailut", "Game.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 13431315), ENGLISH_ENTRY("pupupupulaisenseikkailut", "Pupupeli.exe", "23a67b6de10ec35e9f5a4dfc7d928222", 13453697), ENGLISH_ENTRY("purgatorio01", "Purgatorio 0.1.exe", "18b284c22010850f79bc5c20054a70c4", 194293367), ENGLISH_ENTRY("purityofthesurf", "Surf.exe", "71ca0d6c1c699595f28a2125948d4a84", 11315703), - ENGLISH_ENTRY("puzzlebotsdemo", "Puzzlebots_Demo.exe", "34b49df9cf6eadb5c3587b3921d5b72f", 354138961), ENGLISH_ENTRY("pxenophobe", "ProjXeno.exe", "465f972675db2da6040518221af5b0ba", 79053486), ENGLISH_ENTRY("qfi", "qfi.exe", "0702df6e67ef87fd3c51d09303803126", 534847265), // GOG - ENGLISH_ENTRY("quantumnauts", "QNDEMO.exe", "aeb2dd29e5ff839cb3ee86cf3e87e3ca", 134237367), ENGLISH_ENTRY("questfighter", "Quest Fighter.exe", "21fd0f65dfa48de2b39cb8ec23b30889", 2914128), ENGLISH_ENTRY("questfighterii", "Quest Fighter 2.exe", "4d7d2addcde045dae6e0363a43f9acad", 5219511), ENGLISH_ENTRY("questforcinema", "Questforcinema.exe", "465f972675db2da6040518221af5b0ba", 2670632), @@ -2341,7 +2346,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("shem", "Shem.exe", "0710e2ec71042617f565c01824f0cf3c", 8866401), ENGLISH_ENTRY("sherlock", "Sherlock.exe", "615e73fc1874e92d60a1996c2330ea36", 19108029), ENGLISH_ENTRY("shiftersboxoutsidein", "Box.exe", "fc17e9b3ab53f6b4841e2a4af5c782ff", 24471804), - ENGLISH_ENTRY("shivahdemo", "shivahDemo.exe", "6e3d6225dee662ff6450a3bfa942773b", 20897850), ENGLISH_ENTRY("shoot", "Shoot.exe", "1275885401b7d2ece491e704535707d9", 4327626), ENGLISH_ENTRY("shootmyvalentine", "Valentine.exe", "06a03fe35791b0578068ab1873455463", 2859760), ENGLISH_ENTRY("shortcut", "ShortCut.exe", "95b7dd55f6e15c8a2118856ed9fe8ff9", 4415830), @@ -2350,7 +2354,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("sierraquest1", "SierraQuest1.exe", "465f972675db2da6040518221af5b0ba", 1275381), ENGLISH_ENTRY("silentknightii", "SilentKnight2.exe", "465f972675db2da6040518221af5b0ba", 39941166), ENGLISH_ENTRY("silentknightv11", "Silent Knight.exe", "465f972675db2da6040518221af5b0ba", 47414163), - ENGLISH_ENTRY("simonthesorcerer3demo20", "Simon3.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 8189928), ENGLISH_ENTRY("skippysavestheday", "First Game Test.exe", "06a03fe35791b0578068ab1873455463", 10473902), ENGLISH_ENTRY("slaythedragon", "dragon.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 2917672), ENGLISH_ENTRY("sleepyisland", "Sleepy Island.exe", "465f972675db2da6040518221af5b0ba", 20270790), @@ -2375,9 +2378,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("spacelynxes", "SpaceLynxes.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 6593042), ENGLISH_ENTRY("spacepirates", "Space Pirates.exe", "95dcf736be87cf7d40bf64d5b078c4b7", 3006210), ENGLISH_ENTRY("spacepoolalpha", "SpacePool.exe", "ef1d6fdc83c91a1a8de9eaf2630737b7", 3055777), - ENGLISH_ENTRY("spacequest3vgapreview", "SQ3VGADEMO.exe", "64fcaf7da0b257ea831f89c54be0ad72", 3630019), ENGLISH_ENTRY("spacequest45", "SQ4,5.exe", "5cd8db602cedc8f04cd3ca290a4a2693", 6886082), - ENGLISH_ENTRY("spacequest55demoags", "SQ5.5.exe", "465f972675db2da6040518221af5b0ba", 16342443), ENGLISH_ENTRY("spacerangers", "SpaceRangersEp46.exe", "4f6c7ec127e8b0ce077abb357903612f", 41103057), ENGLISH_ENTRY("spacerangersep52", "SpaceRangers52Grisli.exe", "4f6c7ec127e8b0ce077abb357903612f", 208346458), ENGLISH_ENTRY("spacewar", "Spacewar.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 2270669), @@ -2397,7 +2398,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("sqmania1", "SQMania1.exe", "465f972675db2da6040518221af5b0ba", 831674), ENGLISH_ENTRY("sqmania2remakeeng", "SQM2 RMK.exe", "465f972675db2da6040518221af5b0ba", 3029288), ENGLISH_ENTRY("sqmaniaep5", "SQ Mania Ep5.exe", "a524cbb1c51589903c4043b98917f1d9", 2896204), - ENGLISH_ENTRY("sram2cinomehsrevengedemo", "SRAM2.exe", "e3a33d139d90f2e695292a618753b8a5", 296499943), ENGLISH_ENTRY("stablepeteandthejoust", "StablePete.exe", "b142b43c146c25443a1d155d441a6a81", 30046740), ENGLISH_ENTRY("stablepeteandthejoust", "StablePete.exe", "b142b43c146c25443a1d155d441a6a81", 30048075), ENGLISH_ENTRY("stairquest", "Stair Quest.exe", "e0aeab6a2c479fde167c4c43c3abb8ca", 4550699), @@ -2417,7 +2417,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("strangerthings", "StrangerThings.exe", "cc19db728abbcf657db6b76afb0e92d1", 43636017), ENGLISH_ENTRY("supaevil", "SupaEvil.exe", "0710e2ec71042617f565c01824f0cf3c", 7602318), ENGLISH_ENTRY("supergirl", "Supergirl.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 12108982), - ENGLISH_ENTRY("superjazzmandemo", "SJMdemo.exe", "0710e2ec71042617f565c01824f0cf3c", 5214882), ENGLISH_ENTRY("superracing", "Super Racing.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 3660473), ENGLISH_ENTRY("surreality", "Surreality.exe", "3128b9f90e2f954ba704414ae854d10b", 10773443), ENGLISH_ENTRY("sweed", "SWeed.exe", "be65afc1ea59889c05e4e4cc143b3dbc", 2171942), @@ -2534,8 +2533,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("threeguyswalkintoheaven", "Three Guys Walk Into Heaven.exe", "c45653d1c856f002ceb59a5b865ab187", 2896291), ENGLISH_ENTRY("tilepuzzlegame", "Puzzle01.exe", "615e73fc1874e92d60a1996c2330ea36", 2819964), ENGLISH_ENTRY("tiltor", "Tiltor.exe", "f120690b506dd63cd7d1112ea6af2f77", 17561878), - ENGLISH_ENTRY("timegentlemenpleasedemo", "TGP.exe", "86a5359bac7c88f0dfa060478800dd61", 29686006), - ENGLISH_ENTRY("timequest", "gam.exe", "465f972675db2da6040518221af5b0ba", 5669007), + ENGLISH_ENTRY("timequest1", "gam.exe", "465f972675db2da6040518221af5b0ba", 5669007), ENGLISH_ENTRY("timequest2", "TimeQ2.exe", "465f972675db2da6040518221af5b0ba", 5838823), ENGLISH_ENTRY("timesinkofchronos", "Timesink.exe", "2bc8f994a7d1e05ed45f35abf2128231", 127528679), ENGLISH_ENTRY("timothylande", "Timothy Lande.exe", "0500aacb6c176d47ac0f8158f055db83", 13874628), @@ -2615,7 +2613,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("yoda", "Yoda.exe", "a01a9639ce30bdcd5bf82e528b51fa06", 2461339), ENGLISH_ENTRY("yourlate", "Your late.exe", "02635a77ab660023f59519c91329f7f5", 2719997), ENGLISH_ENTRY("zakmckracken", "Zak2.exe", "e88fd6a23a5e498d7b0d50e3bb914085", 8686711), - ENGLISH_ENTRY("zombieattackdemo", "ZADemo.exe", "82da2565c456dcfb265ded6fe3189c0b", 20958555), ENGLISH_ENTRY("zombiefish", "FZombie.exe", "3128b9f90e2f954ba704414ae854d10b", 4220305), ENGLISH_ENTRY("zooreal", "zoo_real.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 24184795), ENGLISH_ENTRY("zugzwang", "Zugzwang.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 17209702), From f67e9f7e753d3eea51d1b873eb18f9ae59179431 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 2 Feb 2021 20:08:19 -0800 Subject: [PATCH 200/215] AGS: Savegame screenshots now exclude in-game save dialogs --- engines/ags/ags.cpp | 6 ++++-- engines/ags/engine/ac/game.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index a294f4761474..d1d707a941b7 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -390,11 +390,13 @@ void AGSEngine::setGraphicsMode(size_t w, size_t h) { } bool AGSEngine::canLoadGameStateCurrently() { - return !::AGS3::thisroom.Options.SaveLoadDisabled && !::AGS3::inside_script; + return !::AGS3::thisroom.Options.SaveLoadDisabled && + !::AGS3::inside_script && !AGS3::play.fast_forward; } bool AGSEngine::canSaveGameStateCurrently() { - return !::AGS3::thisroom.Options.SaveLoadDisabled && !::AGS3::inside_script; + return !::AGS3::thisroom.Options.SaveLoadDisabled && + !::AGS3::inside_script && !AGS3::play.fast_forward; } Common::Error AGSEngine::loadGameState(int slot) { diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index af2bf4e48b8f..f3aa47e3ab09 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -70,6 +70,7 @@ #include "ags/engine/ac/dynobj/cc_audioclip.h" #include "ags/engine/ac/dynobj/scriptcamera.h" #include "ags/engine/debugging/debug_log.h" +#include "ags/engine/debugging/debugger.h" #include "ags/shared/debugging/out.h" #include "ags/engine/device/mousew32.h" #include "ags/shared/font/fonts.h" @@ -1020,6 +1021,11 @@ void create_savegame_screenshot(Bitmap *&screenShot) { // WORKAROUND: AGS originally only creates savegames if the game flags // that it supports it. But we want it all the time for ScummVM GMM if (/*game.options[OPT_SAVESCREENSHOT] */true) { + // Render the view without any UI elements + int old_flags = debug_flags; + debug_flags |= DBG_NOIFACE; + construct_game_scene(true); + int usewid = data_to_game_coord(play.screenshot_width); int usehit = data_to_game_coord(play.screenshot_height); const Rect &viewport = play.GetMainViewport(); @@ -1032,6 +1038,10 @@ void create_savegame_screenshot(Bitmap *&screenShot) { quit("!Invalid game.screenshot_width/height, must be from 16x16 to screen res"); screenShot = CopyScreenIntoBitmap(usewid, usehit); + + // Restore original screen + debug_flags = old_flags; + construct_game_scene(true); } } From c20eaabef940282c72021d3e09dd76f018e980cf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 2 Feb 2021 20:14:18 -0800 Subject: [PATCH 201/215] AGS: Cleanup of qfg2 vga detection entries --- engines/ags/detection_tables.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 2a35af767f3f..83ebaf7b1175 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -1436,6 +1436,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("kq3agdi", "kq3redux.exe", "e569fb2ceabdc4a1609348c23ebc0821", 11986266), // 1.1 ENGLISH_ENTRY("qfg2agdi", "qfg2vga.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 20470902), ENGLISH_ENTRY("qfg2agdi", "qfg2vga.exe", "582e26533cf784011c7565e89905d3c4", 18224373), + ENGLISH_ENTRY("qfg2agdi", "Game.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 5408433), // Comercial games ENGLISH_ENTRY("blackwell1", "blackwell1.exe", "605e124cb7e0b56841c471e2d641c224", 18822697), // GOG @@ -2256,8 +2257,6 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("questfighter", "Quest Fighter.exe", "21fd0f65dfa48de2b39cb8ec23b30889", 2914128), ENGLISH_ENTRY("questfighterii", "Quest Fighter 2.exe", "4d7d2addcde045dae6e0363a43f9acad", 5219511), ENGLISH_ENTRY("questforcinema", "Questforcinema.exe", "465f972675db2da6040518221af5b0ba", 2670632), - ENGLISH_ENTRY("questforglory2vga", "Game.exe", "3b7cceb3e4bdb031dc5d8f290936e94b", 5408433), - ENGLISH_ENTRY("questforgloryii", "Qfg2vga.exe", "6cddccb3744ec5c6af7c398fb7b3b11c", 20523688), ENGLISH_ENTRY("questforjesus", "QuestForJesus.exe", "495d45fb8adfd49690ae3b97921feec6", 3973088), ENGLISH_ENTRY("questforpalette", "Palette Quest.exe", "0710e2ec71042617f565c01824f0cf3c", 754395), ENGLISH_ENTRY("questforthebluecup", "Quest for the Cup.exe", "9cb3c8dc7a8ab9c44815955696be2677", 8760015), From 064d1ae7f9f2bb4fecbe4f90e615d565020ac6bf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 2 Feb 2021 20:21:45 -0800 Subject: [PATCH 202/215] AGS: Added AGS contributors to credits.pl --- devtools/credits.pl | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/devtools/credits.pl b/devtools/credits.pl index 880113f08acc..6f348c775364 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -558,9 +558,48 @@ sub add_paragraph { begin_section("AGS"); add_person("Paul Gilbert", "dreammaster", ""); + add_person("Thierry Crozat", "criezy", ""); + add_person("Chris Jones", "Pumaman", "Creator"); + add_person("Alan Van Drake", "", "AGS"); + add_person("Benjamin Penney", "", "AGS"); + add_person("Benoit Pierre", "", "AGS"); + add_person("Bernhard Rosenkraenzer", "", "AGS"); + add_person("Cristian Morales Vega", "", "AGS"); + add_person("Edward Rudd", "", "AGS"); + add_person("Erico Vieira Porto", "", "AGS"); + add_person("Ferdinand Thiessen", "", "AGS"); + add_person("Francesco Ariis", "", "AGS"); + add_person("Gilad Shaham", "", "AGS"); + add_person("Ivan Mogilko", "", "AGS"); + add_person("Janet Gilbert", "", "AGS"); + add_person("Jochen Schleu", "", "AGS"); + add_person("Joe Lee", "", "AGS"); + add_person("John Steele Scott", "", "AGS"); + add_person("Martin Sedlak", "", "AGS"); + add_person("Matthew Gambrell", "", "AGS"); + add_person("Michael Rittenhouse", "", "AGS"); + add_person("Morgan Willcock", "", "AGS"); + add_person("Nick Sonneveld", "", "AGS"); + add_person("Ori Avtalion", "", "AGS"); + add_person("Paul Wilkinson", "", "AGS"); + add_person("Per Olav Flaten", "", "AGS"); + add_person("Piotr Wieczorek", "", "AGS"); + add_person("Ryan O'Connor", "", "AGS"); + add_person("Scott Baker", "", "AGS"); + add_person("Shane Stevens", "", "AGS"); + add_person("Shawn R. Walker", "", "AGS"); + add_person("Stefano Collavini", "", "AGS"); + add_person("Steve McCrea", "", "AGS"); + add_person("Steven Poulton", "", "AGS"); + add_person("Sunit Das", "", "AGS"); + add_person("Tobias Hansen", "", "AGS"); + add_person("Tom Vandepoele", "", "AGS"); + add_person("Tzach Shabtay", "", "AGS"); + add_person("", "rofl0r", "AGS"); add_person("", "AGA", "AgsCreditz"); end_section(); + begin_section("Avalanche"); add_person("Peter Bozsó", "uruk", ""); add_person("Arnaud Boutonné", "Strangerke", ""); From f3a23d2e07bfa0ecdfd7850e8efc4b9ea022fc9f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 2 Feb 2021 20:28:46 -0800 Subject: [PATCH 203/215] AGS: Minor detection table cleanups --- engines/ags/detection_tables.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/engines/ags/detection_tables.h b/engines/ags/detection_tables.h index 83ebaf7b1175..10c16f54b508 100644 --- a/engines/ags/detection_tables.h +++ b/engines/ags/detection_tables.h @@ -112,7 +112,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "rodequest", "Rode Quest" }, { "rollinfoy", "Rollinfoy" }, { "samthepiratemonkey", "Sam The Pirate Monkey" }, - { "secondmoonadv1", "Second Moon Adventure Part 1 - Night" }, { "slackerquest", "Slacker Quest" }, { "snailquest1", "Snail Quest" }, { "snailquest2", "Snail Quest 2" }, @@ -924,8 +923,6 @@ const PlainGameDescriptor GAME_NAMES[] = { { "questfighter", "Quest Fighter" }, { "questfighterii", "Quest Fighter II" }, { "questforcinema", "QuestForCinema" }, - { "questforglory2vga", "Quest For Glory 2 VGA" }, - { "questforgloryii", "Quest for Glory II" }, { "questforjesus", "Quest for Jesus" }, { "questforpalette", "Quest for Palette" }, { "questforthebluecup", "Quest for the Blue Cup" }, @@ -1019,14 +1016,15 @@ const PlainGameDescriptor GAME_NAMES[] = { { "shrivel", "Shrivel" }, { "shunday", "Shunday" }, { "sierraquest1", "Sierra Quest 1" }, - { "silentknightii", "Silent Knight II" }, - { "silentknightv11", "Silent Knight v.1.1" }, + { "silentknight1", "Silent Knight" }, + { "silentknight2", "Silent Knight II" }, { "simonthesorcerer3", "Simon the Sorcerer 3" }, { "skippysavestheday", "Skippy Saves The Day" }, { "slaythedragon", "Slay the Dragon" }, { "sleepyisland", "Sleepy Island" }, { "slimequestforpizza", "Slime-Quest for Pizza" }, { "slugprincess", "SlugPrincess" }, + { "sma1", "Second Moon Adventure Part 1 - Night" }, { "sma2", "Second Moon Adventure Part 2" }, { "sma3", "Second Moon Adventure Part 3 - Rest In Peace" }, { "sma4", "Second Moon Adventure Part 4" }, @@ -1407,7 +1405,7 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { UNSUPPORTED_ENTRY("rodequest", "rodequest1.exe", "72f3c950b4d9d14580a11db885a63310", 1196458), UNSUPPORTED_ENTRY("rollinfoy", "rollinfoy.exe", "19f4045333d9c823a5439d0447d55985", 3454107), UNSUPPORTED_ENTRY("samthepiratemonkey", "monkey.exe", "73f87b30f84e9c34ab09ec8dd7ae109d", 1401414), - UNSUPPORTED_ENTRY("secondmoonadv1", "moonsdt.exe", "9027912819f3a319ed9de0fd855310c3", 1276725), + UNSUPPORTED_ENTRY("sma1", "moonsdt.exe", "9027912819f3a319ed9de0fd855310c3", 1276725), UNSUPPORTED_ENTRY("slackerquest", "ac2game.dat", "e0998f2d2e14a55aae2291fdfab1ce7d", 1306492), UNSUPPORTED_ENTRY("snailquest1", "snailquest.exe", "dd69243e3cc9e955215e0d556301b58e", 1095860), UNSUPPORTED_ENTRY("snailquest2", "sq2.exe", "1bccd2edef19abc99e9683519d80c0e0", 955614), @@ -2351,8 +2349,8 @@ const AGSGameDescription GAME_DESCRIPTIONS[] = { ENGLISH_ENTRY("shrivel", "Shrivel.exe", "12c6a846b5ba9a5dde4a1b804b3e86e9", 58873190), ENGLISH_ENTRY("shunday", "Shunday.exe", "82da2565c456dcfb265ded6fe3189c0b", 4937129), ENGLISH_ENTRY("sierraquest1", "SierraQuest1.exe", "465f972675db2da6040518221af5b0ba", 1275381), - ENGLISH_ENTRY("silentknightii", "SilentKnight2.exe", "465f972675db2da6040518221af5b0ba", 39941166), - ENGLISH_ENTRY("silentknightv11", "Silent Knight.exe", "465f972675db2da6040518221af5b0ba", 47414163), + ENGLISH_ENTRY("silentknight1", "Silent Knight.exe", "465f972675db2da6040518221af5b0ba", 47414163), + ENGLISH_ENTRY("silentknight2", "SilentKnight2.exe", "465f972675db2da6040518221af5b0ba", 39941166), ENGLISH_ENTRY("skippysavestheday", "First Game Test.exe", "06a03fe35791b0578068ab1873455463", 10473902), ENGLISH_ENTRY("slaythedragon", "dragon.exe", "3c5bd1713959ff469cb46ebe5542cfcf", 2917672), ENGLISH_ENTRY("sleepyisland", "Sleepy Island.exe", "465f972675db2da6040518221af5b0ba", 20270790), From ce5f3245a7b1f97de74d8865f991c18c583e29a7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 2 Feb 2021 20:45:09 -0800 Subject: [PATCH 204/215] AGS: Show md5 when AGS game found in fallbackDetect --- engines/ags/detection.cpp | 11 ++++++++++- engines/ags/detection.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/engines/ags/detection.cpp b/engines/ags/detection.cpp index d1afbb27162d..98e00590a612 100644 --- a/engines/ags/detection.cpp +++ b/engines/ags/detection.cpp @@ -22,6 +22,7 @@ #include "base/plugins.h" #include "common/file.h" +#include "common/md5.h" #include "ags/detection.h" #include "ags/detection_tables.h" @@ -90,13 +91,21 @@ ADDetectedGame AGSMetaEngineDetection::fallbackDetect(const FileMap &allFiles, c if (AGS3::isAGSFile(f)) { _filename = filename; + f.seek(0); + _md5 = Common::computeStreamMD5AsString(f, 5000); AGS::g_fallbackDesc.desc.gameId = _gameid.c_str(); AGS::g_fallbackDesc.desc.extra = _extra.c_str(); AGS::g_fallbackDesc.desc.filesDescriptions[0].fileName = _filename.c_str(); AGS::g_fallbackDesc.desc.filesDescriptions[0].fileSize = f.size(); + AGS::g_fallbackDesc.desc.filesDescriptions[0].md5 = _md5.c_str(); - return ADDetectedGame(&AGS::g_fallbackDesc.desc); + ADDetectedGame game(&AGS::g_fallbackDesc.desc); + game.matchedFiles[_filename].md5 = _md5; + game.matchedFiles[_filename].size = f.size(); + + game.hasUnknownFiles = true; + return game; } } diff --git a/engines/ags/detection.h b/engines/ags/detection.h index 892a758edf93..6b8c759f9a4d 100644 --- a/engines/ags/detection.h +++ b/engines/ags/detection.h @@ -48,6 +48,7 @@ class AGSMetaEngineDetection : public AdvancedMetaEngineDetection { mutable Common::String _gameid; mutable Common::String _extra; mutable Common::String _filename; + mutable Common::String _md5; public: AGSMetaEngineDetection(); From f5f299ed6c50b8f91f3bf28132499e8504d737a5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 2 Feb 2021 21:46:56 -0800 Subject: [PATCH 205/215] AGS: Further separate methods in two AgsCreditz classes --- .../ags/plugins/ags_creditz/ags_creditz.cpp | 249 +++++++++++++----- engines/ags/plugins/ags_creditz/ags_creditz.h | 44 +++- 2 files changed, 217 insertions(+), 76 deletions(-) diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.cpp b/engines/ags/plugins/ags_creditz/ags_creditz.cpp index f88ea7ebf523..a840159af7f5 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.cpp +++ b/engines/ags/plugins/ags_creditz/ags_creditz.cpp @@ -33,25 +33,33 @@ IAGSEngine *AGSCreditz::_engine; AGSCreditz::AGSCreditz() { _state = new State(); _engine = nullptr; - - DLL_METHOD(AGS_GetPluginName); } AGSCreditz::~AGSCreditz() { delete _state; } +/*------------------------------------------------------------------*/ + +const char *IMAGE_TEXT = "*i*m*a*g*e*"; + +AGSCreditz11::AGSCreditz11() : AGSCreditz() { + _version = VERSION_11; + + DLL_METHOD(AGS_GetPluginName); + DLL_METHOD(AGS_EngineStartup); +} -const char *AGSCreditz::AGS_GetPluginName() { - if (_version == VERSION_11) - return "AGSCreditz v1.1 by AJA"; - else - return "AGSCreditz 2.0 (by Dima Software: AJA)"; +const char *AGSCreditz11::AGS_GetPluginName() { + return "AGSCreditz v1.1 by AJA"; } -void AGSCreditz::AGS_EngineStartup(IAGSEngine *engine) { +void AGSCreditz11::AGS_EngineStartup(IAGSEngine *engine) { _engine = engine; + SCRIPT_METHOD(SetCredit); + SCRIPT_METHOD(ScrollCredits); + SCRIPT_METHOD(GetCredit); SCRIPT_METHOD(IsCreditScrollingFinished); SCRIPT_METHOD(SetCreditImage); SCRIPT_METHOD(PauseScroll); @@ -72,114 +80,187 @@ void AGSCreditz::AGS_EngineStartup(IAGSEngine *engine) { SCRIPT_METHOD(IsStaticCreditsFinished); } -int AGSCreditz::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { + PARAMS7(int, ID, string, credit, int, colour, int, font, int, center, int, xpos, int, generateoutline); + + if (ID >= (int)_state->_credits[0].size()) + _state->_credits[0].resize(ID + 1); + + Credit &c = _state->_credits[0][ID]; + c._text = credit; + c._fontSlot = font; + c._center = center; + c._x = xpos; + c._isSet = true; + c._outline = generateoutline; + c._color = colour; +} + +void AGSCreditz11::ScrollCredits(const ScriptMethodParams ¶ms) { + PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, resolution); + + if (onoff == 1) { + _state->_creditsRunning = true; + _state->_seqSettings[0].speed = speed; + _state->_seqSettings[0].endwait = wait; + _state->_seqSettings[0].startpoint = fromY; + _state->_seqSettings[0].endpoint = toY; + _state->_seqSettings[0].automatic = isautom; + + _engine->GetScreenDimensions(&_state->_screenWidth, + &_state->_screenHeight, &_state->_screenColorDepth); + if (_state->_screenWidth == 320) { + _state->_resolutionFlag = (resolution != 2) ? 1 : 0; + } else if (_state->_screenWidth == 640) { + _state->_resolutionFlag = (resolution != 1) ? 1 : 0; + } + + } else if (onoff == 0) { + _state->_creditsRunning = false; + + } else { + _engine->AbortGame("ScrollCredits: OnOff value must be 1 or 0!"); + } +} + +string AGSCreditz11::GetCredit(const ScriptMethodParams ¶ms) { + PARAMS1(int, ID); + + return (_state->_credits[0][ID]._text == IMAGE_TEXT) ? + "image" : _state->_credits[0][ID]._text.c_str(); +} + +int AGSCreditz11::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { return true; } -void AGSCreditz::SetCreditImage(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetCreditImage(const ScriptMethodParams ¶ms) { //PARAMS5(int, ID, int, Slot, int, center, int, xpos, int, pixtonext); } -void AGSCreditz::PauseScroll(const ScriptMethodParams ¶ms) { +void AGSCreditz11::PauseScroll(const ScriptMethodParams ¶ms) { //PARAMS1(int, onoff); } -void AGSCreditz::ScrollReset(const ScriptMethodParams ¶ms) { +void AGSCreditz11::ScrollReset(const ScriptMethodParams ¶ms) { } -void AGSCreditz::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { //PARAMS1(int, Height); } -int AGSCreditz::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { +int AGSCreditz11::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { return 0; } -void AGSCreditz::SetStaticCredit(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetStaticCredit(const ScriptMethodParams ¶ms) { //PARAMS8(int, ID, int, x, int, y, int, creditfont, int, creditcolour, int, centered, int, generateoutline, string, credit); } -string AGSCreditz::GetStaticCredit(const ScriptMethodParams ¶ms) { +string AGSCreditz11::GetStaticCredit(const ScriptMethodParams ¶ms) { //PARAMS1(int, ID); return nullptr; } -void AGSCreditz::StartEndStaticCredits(const ScriptMethodParams ¶ms) { +void AGSCreditz11::StartEndStaticCredits(const ScriptMethodParams ¶ms) { //PARAMS2(int, onoff, int, res); } -int AGSCreditz::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { +int AGSCreditz11::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { return 0; } -void AGSCreditz::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { //PARAMS1(int, Cyclesperchar); } -void AGSCreditz::SetStaticPause(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetStaticPause(const ScriptMethodParams ¶ms) { //PARAMS2(int, ID, int, length); } -void AGSCreditz::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { //PARAMS8(int, ID, int, x, int, y, int, titlefont, int, titlecolour, int, centered, int, generateoutline, string, title); } -void AGSCreditz::ShowStaticCredit(const ScriptMethodParams ¶ms) { +void AGSCreditz11::ShowStaticCredit(const ScriptMethodParams ¶ms) { //PARAMS6(int, ID, int, time, int, style, int, transtime, int, sound, int, resolution); } -void AGSCreditz::StaticReset(const ScriptMethodParams ¶ms) { +void AGSCreditz11::StaticReset(const ScriptMethodParams ¶ms) { } -string AGSCreditz::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { +string AGSCreditz11::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { //PARAMS1(int, ID); return nullptr; } -void AGSCreditz::SetStaticCreditImage(const ScriptMethodParams ¶ms) { +void AGSCreditz11::SetStaticCreditImage(const ScriptMethodParams ¶ms) { //int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time) { } -int AGSCreditz::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { +int AGSCreditz11::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { return true; } /*------------------------------------------------------------------*/ -const char *IMAGE_TEXT = "*i*m*a*g*e*"; - -AGSCreditz11::AGSCreditz11() { - _version = VERSION_11; +AGSCreditz20::AGSCreditz20() : AGSCreditz() { + _version = VERSION_20; + DLL_METHOD(AGS_GetPluginName); DLL_METHOD(AGS_EngineStartup); } -void AGSCreditz11::AGS_EngineStartup(IAGSEngine *engine) { - AGSCreditz::AGS_EngineStartup(engine); +const char *AGSCreditz20::AGS_GetPluginName() { + return "AGSCreditz v1.1 by AJA"; +} + +void AGSCreditz20::AGS_EngineStartup(IAGSEngine *engine) { + _engine = engine; SCRIPT_METHOD(SetCredit); SCRIPT_METHOD(ScrollCredits); SCRIPT_METHOD(GetCredit); + SCRIPT_METHOD(IsCreditScrollingFinished); + SCRIPT_METHOD(SetCreditImage); + SCRIPT_METHOD(PauseScroll); + SCRIPT_METHOD(ScrollReset); + SCRIPT_METHOD(SetEmptyLineHeight); + SCRIPT_METHOD(GetEmptyLineHeight); + SCRIPT_METHOD(SetStaticCredit); + SCRIPT_METHOD(GetStaticCredit); + SCRIPT_METHOD(StartEndStaticCredits); + SCRIPT_METHOD(GetCurrentStaticCredit); + SCRIPT_METHOD(SetDefaultStaticDelay); + SCRIPT_METHOD(SetStaticPause); + SCRIPT_METHOD(SetStaticCreditTitle); + SCRIPT_METHOD(ShowStaticCredit); + SCRIPT_METHOD(StaticReset); + SCRIPT_METHOD(GetStaticCreditTitle); + SCRIPT_METHOD(SetStaticCreditImage); + SCRIPT_METHOD(IsStaticCreditsFinished); } -void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { - PARAMS7(int, ID, string, credit, int, colour, int, font, int, center, int, xpos, int, generateoutline); +void AGSCreditz20::SetCredit(const ScriptMethodParams ¶ms) { + PARAMS7(int, sequence, int, line, string, credit, int, x_pos, int, font, int, color, int, gen_outline); - if (ID >= (int)_state->_credits[0].size()) - _state->_credits[0].resize(ID + 1); + assert(sequence >= 0 && sequence <= 10); + if (line >= (int)_state->_credits[sequence].size()) + _state->_credits[sequence].resize(line + 1); - Credit &c = _state->_credits[0][ID]; + Credit &c = _state->_credits[sequence][line]; c._text = credit; c._fontSlot = font; - c._center = center; - c._x = xpos; + c._color = color; + c._x = x_pos; c._isSet = true; - c._outline = generateoutline; - c._color = colour; + if (gen_outline > 0) + c._outline = true; } -void AGSCreditz11::ScrollCredits(const ScriptMethodParams ¶ms) { + +void AGSCreditz20::ScrollCredits(const ScriptMethodParams ¶ms) { PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, resolution); if (onoff == 1) { @@ -206,42 +287,84 @@ void AGSCreditz11::ScrollCredits(const ScriptMethodParams ¶ms) { } } -string AGSCreditz11::GetCredit(const ScriptMethodParams ¶ms) { +string AGSCreditz20::GetCredit(const ScriptMethodParams ¶ms) { PARAMS1(int, ID); return (_state->_credits[0][ID]._text == IMAGE_TEXT) ? "image" : _state->_credits[0][ID]._text.c_str(); } -/*------------------------------------------------------------------*/ +int AGSCreditz20::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { + return true; +} -AGSCreditz20::AGSCreditz20() { - _version = VERSION_20; +void AGSCreditz20::SetCreditImage(const ScriptMethodParams ¶ms) { + //PARAMS5(int, ID, int, Slot, int, center, int, xpos, int, pixtonext); +} - DLL_METHOD(AGS_EngineStartup); +void AGSCreditz20::PauseScroll(const ScriptMethodParams ¶ms) { + //PARAMS1(int, onoff); } -void AGSCreditz20::AGS_EngineStartup(IAGSEngine *engine) { - AGSCreditz::AGS_EngineStartup(engine); +void AGSCreditz20::ScrollReset(const ScriptMethodParams ¶ms) { +} - SCRIPT_METHOD(SetCredit); +void AGSCreditz20::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { + //PARAMS1(int, Height); } -void AGSCreditz20::SetCredit(const ScriptMethodParams ¶ms) { - PARAMS7(int, sequence, int, line, string, credit, int, x_pos, int, font, int, color, int, gen_outline); +int AGSCreditz20::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { + return 0; +} - assert(sequence >= 0 && sequence <= 10); - if (line >= (int)_state->_credits[sequence].size()) - _state->_credits[sequence].resize(line + 1); +void AGSCreditz20::SetStaticCredit(const ScriptMethodParams ¶ms) { + //PARAMS8(int, ID, int, x, int, y, int, creditfont, int, creditcolour, int, centered, int, generateoutline, string, credit); - Credit &c = _state->_credits[sequence][line]; - c._text = credit; - c._fontSlot = font; - c._color = color; - c._x = x_pos; - c._isSet = true; - if (gen_outline > 0) - c._outline = true; +} + +string AGSCreditz20::GetStaticCredit(const ScriptMethodParams ¶ms) { + //PARAMS1(int, ID); + return nullptr; +} + +void AGSCreditz20::StartEndStaticCredits(const ScriptMethodParams ¶ms) { + //PARAMS2(int, onoff, int, res); +} + +int AGSCreditz20::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { + return 0; +} + +void AGSCreditz20::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { + //PARAMS1(int, Cyclesperchar); +} + +void AGSCreditz20::SetStaticPause(const ScriptMethodParams ¶ms) { + //PARAMS2(int, ID, int, length); +} + +void AGSCreditz20::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { + //PARAMS8(int, ID, int, x, int, y, int, titlefont, int, titlecolour, int, centered, int, generateoutline, string, title); +} + +void AGSCreditz20::ShowStaticCredit(const ScriptMethodParams ¶ms) { + //PARAMS6(int, ID, int, time, int, style, int, transtime, int, sound, int, resolution); +} + +void AGSCreditz20::StaticReset(const ScriptMethodParams ¶ms) { +} + +string AGSCreditz20::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { + //PARAMS1(int, ID); + return nullptr; +} + +void AGSCreditz20::SetStaticCreditImage(const ScriptMethodParams ¶ms) { + //int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time) { +} + +int AGSCreditz20::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { + return true; } } // namespace AGSCreditz diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.h b/engines/ags/plugins/ags_creditz/ags_creditz.h index d49bddbdf5cc..fb5bcbb7a29f 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.h +++ b/engines/ags/plugins/ags_creditz/ags_creditz.h @@ -121,11 +121,19 @@ class AGSCreditz : public DLL { static Version _version; static State *_state; static IAGSEngine *_engine; -protected: +public: + AGSCreditz(); + ~AGSCreditz(); +}; + +class AGSCreditz11 : public AGSCreditz { +private: static const char *AGS_GetPluginName(); static void AGS_EngineStartup(IAGSEngine *engine); - // Shared Script methods + static void SetCredit(const ScriptMethodParams ¶ms); + static void ScrollCredits(const ScriptMethodParams ¶ms); + static string GetCredit(const ScriptMethodParams ¶ms); static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); static void SetCreditImage(const ScriptMethodParams ¶ms); static void PauseScroll(const ScriptMethodParams ¶ms); @@ -144,27 +152,37 @@ class AGSCreditz : public DLL { static string GetStaticCreditTitle(const ScriptMethodParams ¶ms); static void SetStaticCreditImage(const ScriptMethodParams ¶ms); static int IsStaticCreditsFinished(const ScriptMethodParams ¶ms); -public: - AGSCreditz(); - ~AGSCreditz(); -}; -class AGSCreditz11 : public AGSCreditz { -private: - static void AGS_EngineStartup(IAGSEngine *engine); - - static void SetCredit(const ScriptMethodParams ¶ms); - static void ScrollCredits(const ScriptMethodParams ¶ms); - static string GetCredit(const ScriptMethodParams ¶ms); public: AGSCreditz11(); }; class AGSCreditz20 : public AGSCreditz { private: + static const char *AGS_GetPluginName(); static void AGS_EngineStartup(IAGSEngine *engine); static void SetCredit(const ScriptMethodParams ¶ms); + static void ScrollCredits(const ScriptMethodParams ¶ms); + static string GetCredit(const ScriptMethodParams ¶ms); + static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); + static void SetCreditImage(const ScriptMethodParams ¶ms); + static void PauseScroll(const ScriptMethodParams ¶ms); + static void ScrollReset(const ScriptMethodParams ¶ms); + static void SetEmptyLineHeight(const ScriptMethodParams ¶ms); + static int GetEmptyLineHeight(const ScriptMethodParams ¶ms); + static void SetStaticCredit(const ScriptMethodParams ¶ms); + static string GetStaticCredit(const ScriptMethodParams ¶ms); + static void StartEndStaticCredits(const ScriptMethodParams ¶ms); + static int GetCurrentStaticCredit(const ScriptMethodParams ¶ms); + static void SetDefaultStaticDelay(const ScriptMethodParams ¶ms); + static void SetStaticPause(const ScriptMethodParams ¶ms); + static void SetStaticCreditTitle(const ScriptMethodParams ¶ms); + static void ShowStaticCredit(const ScriptMethodParams ¶ms); + static void StaticReset(const ScriptMethodParams ¶ms); + static string GetStaticCreditTitle(const ScriptMethodParams ¶ms); + static void SetStaticCreditImage(const ScriptMethodParams ¶ms); + static int IsStaticCreditsFinished(const ScriptMethodParams ¶ms); public: AGSCreditz20(); }; From 0dd6589c7810247381a29037e81b5bc712cfdc88 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 3 Feb 2021 19:21:56 -0800 Subject: [PATCH 206/215] AGS: Implemented AGSCreditz overall script methods --- .../ags/plugins/ags_creditz/ags_creditz.cpp | 276 ++++++++++++------ engines/ags/plugins/ags_creditz/ags_creditz.h | 35 +-- 2 files changed, 212 insertions(+), 99 deletions(-) diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.cpp b/engines/ags/plugins/ags_creditz/ags_creditz.cpp index a840159af7f5..9100cc5aa80b 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.cpp +++ b/engines/ags/plugins/ags_creditz/ags_creditz.cpp @@ -93,7 +93,7 @@ void AGSCreditz11::SetCredit(const ScriptMethodParams ¶ms) { c._x = xpos; c._isSet = true; c._outline = generateoutline; - c._color = colour; + c._colorHeight = colour; } void AGSCreditz11::ScrollCredits(const ScriptMethodParams ¶ms) { @@ -213,33 +213,59 @@ AGSCreditz20::AGSCreditz20() : AGSCreditz() { } const char *AGSCreditz20::AGS_GetPluginName() { - return "AGSCreditz v1.1 by AJA"; + return "AGSCreditz 2.0 (by Dima Software: AJA)"; } void AGSCreditz20::AGS_EngineStartup(IAGSEngine *engine) { _engine = engine; + SCRIPT_METHOD(RunCreditSequence); SCRIPT_METHOD(SetCredit); - SCRIPT_METHOD(ScrollCredits); SCRIPT_METHOD(GetCredit); - SCRIPT_METHOD(IsCreditScrollingFinished); + SCRIPT_METHOD(CreditsSettings); + SCRIPT_METHOD(SequenceSettings); + SCRIPT_METHOD(IsSequenceFinished); + SCRIPT_METHOD(PauseScrolling); SCRIPT_METHOD(SetCreditImage); - SCRIPT_METHOD(PauseScroll); - SCRIPT_METHOD(ScrollReset); - SCRIPT_METHOD(SetEmptyLineHeight); - SCRIPT_METHOD(GetEmptyLineHeight); + SCRIPT_METHOD(ResetSequence); + SCRIPT_METHOD(SetStaticCredit); - SCRIPT_METHOD(GetStaticCredit); - SCRIPT_METHOD(StartEndStaticCredits); - SCRIPT_METHOD(GetCurrentStaticCredit); - SCRIPT_METHOD(SetDefaultStaticDelay); - SCRIPT_METHOD(SetStaticPause); SCRIPT_METHOD(SetStaticCreditTitle); + SCRIPT_METHOD(SetStaticPause); + SCRIPT_METHOD(RunStaticCreditSequence); + SCRIPT_METHOD(IsStaticSequenceFinished); SCRIPT_METHOD(ShowStaticCredit); - SCRIPT_METHOD(StaticReset); - SCRIPT_METHOD(GetStaticCreditTitle); - SCRIPT_METHOD(SetStaticCreditImage); - SCRIPT_METHOD(IsStaticCreditsFinished); + SCRIPT_METHOD(SetStaticImage); + SCRIPT_METHOD(GetCurrentStaticCredit); +} + +void AGSCreditz20::RunCreditSequence(const ScriptMethodParams ¶ms) { + PARAMS1(int, sequence); + + if (!_state->_creditsRunning) { + _state->_seqSettings[sequence].finished = false; + _state->_creditsRunning = true; + _state->_creditSequence = sequence; + + _engine->GetScreenDimensions(&_state->_screenWidth, &_state->_screenHeight, + &_state->_screenColorDepth); + + if (_state->_seqSettings[sequence].automatic) { + calculateSequenceHeight(sequence); + _state->_yPos = _state->_screenHeight + 1; + } else { + _state->_yPos = _state->_seqSettings[sequence].startpoint; + } + + _state->_speedPoint = 0; + _state->_timer = 0; + draw(); + } else { + _state->_paused = false; + _state->_creditsRunning = false; + _state->_creditSequence = -1; + _state->_seqSettings[sequence].finished = true; + } } void AGSCreditz20::SetCredit(const ScriptMethodParams ¶ms) { @@ -252,119 +278,205 @@ void AGSCreditz20::SetCredit(const ScriptMethodParams ¶ms) { Credit &c = _state->_credits[sequence][line]; c._text = credit; c._fontSlot = font; - c._color = color; + c._colorHeight = color; c._x = x_pos; c._isSet = true; if (gen_outline > 0) c._outline = true; } +string AGSCreditz20::GetCredit(const ScriptMethodParams ¶ms) { + PARAMS2(int, sequence, int, ID); -void AGSCreditz20::ScrollCredits(const ScriptMethodParams ¶ms) { - PARAMS7(int, onoff, int, speed, int, fromY, int, toY, int, isautom, int, wait, int, resolution); + return _state->_credits[sequence][ID]._text.c_str(); +} - if (onoff == 1) { - _state->_creditsRunning = true; - _state->_seqSettings[0].speed = speed; - _state->_seqSettings[0].endwait = wait; - _state->_seqSettings[0].startpoint = fromY; - _state->_seqSettings[0].endpoint = toY; - _state->_seqSettings[0].automatic = isautom; +void AGSCreditz20::CreditsSettings(const ScriptMethodParams ¶ms) { + PARAMS1(int, emptylineheight); - _engine->GetScreenDimensions(&_state->_screenWidth, - &_state->_screenHeight, &_state->_screenColorDepth); - if (_state->_screenWidth == 320) { - _state->_resolutionFlag = (resolution != 2) ? 1 : 0; - } else if (_state->_screenWidth == 640) { - _state->_resolutionFlag = (resolution != 1) ? 1 : 0; - } + if (emptylineheight >= 0) + _state->_emptyLineHeight = emptylineheight; +} - } else if (onoff == 0) { - _state->_creditsRunning = false; +void AGSCreditz20::SequenceSettings(const ScriptMethodParams ¶ms) { + PARAMS6(int, sequence, int, startpoint, int, endpoint, int, speed, int, automatic, int, endwait); - } else { - _engine->AbortGame("ScrollCredits: OnOff value must be 1 or 0!"); - } + _state->_seqSettings[sequence].startpoint = startpoint; + _state->_seqSettings[sequence].endpoint = endpoint; + _state->_seqSettings[sequence].speed = speed; + _state->_seqSettings[sequence].automatic = automatic; + _state->_seqSettings[sequence].endwait = endwait; } -string AGSCreditz20::GetCredit(const ScriptMethodParams ¶ms) { - PARAMS1(int, ID); +int AGSCreditz20::IsSequenceFinished(const ScriptMethodParams ¶ms) { + PARAMS1(int, sequence); - return (_state->_credits[0][ID]._text == IMAGE_TEXT) ? - "image" : _state->_credits[0][ID]._text.c_str(); + if (_state->_seqSettings[sequence].finished) { + _state->_seqSettings[sequence].finished = false; + return 1; + } + + return 0; } -int AGSCreditz20::IsCreditScrollingFinished(const ScriptMethodParams ¶ms) { - return true; +void AGSCreditz20::PauseScrolling(const ScriptMethodParams ¶ms) { + if (_state->_creditsRunning) { + _state->_paused = !_state->_paused; + } } void AGSCreditz20::SetCreditImage(const ScriptMethodParams ¶ms) { - //PARAMS5(int, ID, int, Slot, int, center, int, xpos, int, pixtonext); -} + PARAMS5(int, sequence, int, line, int, xPos, int, slot, int, height); -void AGSCreditz20::PauseScroll(const ScriptMethodParams ¶ms) { - //PARAMS1(int, onoff); -} + assert(sequence >= 0 && sequence <= 10); + if (line >= (int)_state->_credits[sequence].size()) + _state->_credits[sequence].resize(line + 1); -void AGSCreditz20::ScrollReset(const ScriptMethodParams ¶ms) { + _state->_credits[sequence][line]._image = true; + _state->_credits[sequence][line]._isSet = true; + _state->_credits[sequence][line]._x = xPos; + _state->_credits[sequence][line]._fontSlot = slot; + _state->_credits[sequence][line]._colorHeight = height; } -void AGSCreditz20::SetEmptyLineHeight(const ScriptMethodParams ¶ms) { - //PARAMS1(int, Height); -} +void AGSCreditz20::ResetSequence(const ScriptMethodParams ¶ms) { + PARAMS1(int, seqtype); -int AGSCreditz20::GetEmptyLineHeight(const ScriptMethodParams ¶ms) { - return 0; + for (int i = 0; i < 10; ++i) { + if (seqtype != 2) + // Scrolling + _state->_credits[i].clear(); + else + // Static + _state->_stCredits[i].clear(); + } } void AGSCreditz20::SetStaticCredit(const ScriptMethodParams ¶ms) { - //PARAMS8(int, ID, int, x, int, y, int, creditfont, int, creditcolour, int, centered, int, generateoutline, string, credit); + PARAMS8(int, sequence, int, id, string, credit, int, xPos, int, yPos, + int, font, int, color, int, genOutline); -} + assert(sequence >= 0 && sequence <= 10); + if (id >= (int)_state->_stCredits[sequence].size()) + _state->_stCredits[sequence].resize(id + 1); -string AGSCreditz20::GetStaticCredit(const ScriptMethodParams ¶ms) { - //PARAMS1(int, ID); - return nullptr; -} + _state->_stCredits[sequence][id].credit = credit; + _state->_stCredits[sequence][id].x = xPos; + _state->_stCredits[sequence][id].y = yPos; + _state->_stCredits[sequence][id].font = font; + _state->_stCredits[sequence][id].color = color; -void AGSCreditz20::StartEndStaticCredits(const ScriptMethodParams ¶ms) { - //PARAMS2(int, onoff, int, res); + if (genOutline > 0) + _state->_stCredits[sequence][id].outline = true; } -int AGSCreditz20::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { - return 0; -} +void AGSCreditz20::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { + PARAMS8(int, sequence, int, id, string, title, int, xPos, int, yPos, + int, font, int, color, int, genOutline); -void AGSCreditz20::SetDefaultStaticDelay(const ScriptMethodParams ¶ms) { - //PARAMS1(int, Cyclesperchar); + assert(sequence >= 0 && sequence < 10); + if (id >= (int)_state->_stCredits[sequence].size()) + _state->_stCredits[sequence].resize(id + 1); + + _state->_stCredits[sequence][id].title = title; + _state->_stCredits[sequence][id].title_x = xPos; + _state->_stCredits[sequence][id].title_y = yPos; + _state->_stCredits[sequence][id].title_font = font; + _state->_stCredits[sequence][id].title_color = color; + + if (genOutline > 0) + _state->_stCredits[sequence][id].title_outline = true; } void AGSCreditz20::SetStaticPause(const ScriptMethodParams ¶ms) { - //PARAMS2(int, ID, int, length); + PARAMS3(int, sequence, int, id, int, length); + + assert(sequence >= 0 && sequence <= 10); + if (id >= (int)_state->_stCredits[sequence].size()) + _state->_stCredits[sequence].resize(id + 1); + + _state->_stCredits[sequence][id].pause = length; } -void AGSCreditz20::SetStaticCreditTitle(const ScriptMethodParams ¶ms) { - //PARAMS8(int, ID, int, x, int, y, int, titlefont, int, titlecolour, int, centered, int, generateoutline, string, title); +void AGSCreditz20::RunStaticCreditSequence(const ScriptMethodParams ¶ms) { + PARAMS2(int, sequence, int, speed); + + if (!_state->_creditsRunning) { + _state->_stSeqSettings[sequence].finished = false; + _state->_stSeqSettings[sequence].speed = speed; + _state->_creditSequence = sequence; + _state->_staticCredits = true; + _state->_creditsRunning = true; + _state->_currentStatic = 1; + _state->_timer = 0; + draw(); + + } else { + _state->_staticCredits = false; + _state->_creditSequence = -1; + _state->_stSeqSettings[sequence].finished = false; + _state->_creditsRunning = false; + _state->_currentStatic = 0; + _state->_timer = 0; + } } -void AGSCreditz20::ShowStaticCredit(const ScriptMethodParams ¶ms) { - //PARAMS6(int, ID, int, time, int, style, int, transtime, int, sound, int, resolution); +int AGSCreditz20::IsStaticSequenceFinished(const ScriptMethodParams ¶ms) { + PARAMS1(int, sequence); + + int result = (_state->_stSeqSettings[sequence].finished) ? 1 : 0; + _state->_stSeqSettings[sequence].finished = false; + + return result; } -void AGSCreditz20::StaticReset(const ScriptMethodParams ¶ms) { +void AGSCreditz20::ShowStaticCredit(const ScriptMethodParams ¶ms) { + PARAMS6(int, sequence, int, id, int, time, int, style, + int, styleSettings1, int, styleSettings2); + + _state->_creditSequence = sequence; + _state->_creditsRunning = true; + _state->_staticCredits = true; + _state->_singleStatic.id = id; + _state->_singleStatic.time = time; + _state->_singleStatic.style = style; + _state->_singleStatic.settings1 = styleSettings1; + _state->_singleStatic.settings2 = styleSettings2; + _state->_singleStatic.bool_ = true; + _state->_stSeqSettings[sequence].finished = false; + _state->_timer = 0; + _state->_timer2 = 0; + _state->_numChars = 0; + draw(); +} + +void AGSCreditz20::SetStaticImage(const ScriptMethodParams ¶ms) { + PARAMS6(int, sequence, int, id, int, slot, int, xPos, int, yPos, int, length); + + assert(sequence >= 0 && sequence < 10); + if (id >= (int)_state->_stCredits[sequence].size()) + _state->_stCredits[sequence].resize(id + 1); + + _state->_stCredits[sequence][id].image = true; + _state->_stCredits[sequence][id].image_slot = slot; + _state->_stCredits[sequence][id].x = xPos; + _state->_stCredits[sequence][id].y = yPos; + _state->_stCredits[sequence][id].image_time = length; } -string AGSCreditz20::GetStaticCreditTitle(const ScriptMethodParams ¶ms) { - //PARAMS1(int, ID); - return nullptr; +int AGSCreditz20::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { + int result = -1; + if (_state->_creditsRunning && _state->_staticCredits) + result = _state->_currentStatic; + + return result; } -void AGSCreditz20::SetStaticCreditImage(const ScriptMethodParams ¶ms) { - //int ID, int x, int y, int Slot, int Hcentered, int Vcentered, int time) { +int AGSCreditz20::calculateSequenceHeight(int sequence) { + return 0; } -int AGSCreditz20::IsStaticCreditsFinished(const ScriptMethodParams ¶ms) { - return true; +void AGSCreditz20::draw() { } } // namespace AGSCreditz diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.h b/engines/ags/plugins/ags_creditz/ags_creditz.h index fb5bcbb7a29f..df3f373b308e 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.h +++ b/engines/ags/plugins/ags_creditz/ags_creditz.h @@ -37,7 +37,7 @@ struct Credit { int _x = 0; int _y = 0; int _fontSlot = 0; - int _color = 0; + int _colorHeight = 0; int _center = 0; bool _isSet = false; bool _image = false; @@ -83,7 +83,7 @@ struct SingleStatic { int id = 0; int time = 0; int style = 0; - int settings = 01; + int settings1 = 01; int settings2 = 0; bool bool_ = false; }; @@ -162,27 +162,28 @@ class AGSCreditz20 : public AGSCreditz { static const char *AGS_GetPluginName(); static void AGS_EngineStartup(IAGSEngine *engine); + static void RunCreditSequence(const ScriptMethodParams ¶ms); static void SetCredit(const ScriptMethodParams ¶ms); - static void ScrollCredits(const ScriptMethodParams ¶ms); static string GetCredit(const ScriptMethodParams ¶ms); - static int IsCreditScrollingFinished(const ScriptMethodParams ¶ms); + static void CreditsSettings(const ScriptMethodParams ¶ms); + static void SequenceSettings(const ScriptMethodParams ¶ms); + static int IsSequenceFinished(const ScriptMethodParams ¶ms); + static void PauseScrolling(const ScriptMethodParams ¶ms); static void SetCreditImage(const ScriptMethodParams ¶ms); - static void PauseScroll(const ScriptMethodParams ¶ms); - static void ScrollReset(const ScriptMethodParams ¶ms); - static void SetEmptyLineHeight(const ScriptMethodParams ¶ms); - static int GetEmptyLineHeight(const ScriptMethodParams ¶ms); + static void ResetSequence(const ScriptMethodParams ¶ms); + static void SetStaticCredit(const ScriptMethodParams ¶ms); - static string GetStaticCredit(const ScriptMethodParams ¶ms); - static void StartEndStaticCredits(const ScriptMethodParams ¶ms); - static int GetCurrentStaticCredit(const ScriptMethodParams ¶ms); - static void SetDefaultStaticDelay(const ScriptMethodParams ¶ms); - static void SetStaticPause(const ScriptMethodParams ¶ms); static void SetStaticCreditTitle(const ScriptMethodParams ¶ms); + static void SetStaticPause(const ScriptMethodParams ¶ms); + static void RunStaticCreditSequence(const ScriptMethodParams ¶ms); + static int IsStaticSequenceFinished(const ScriptMethodParams ¶ms); static void ShowStaticCredit(const ScriptMethodParams ¶ms); - static void StaticReset(const ScriptMethodParams ¶ms); - static string GetStaticCreditTitle(const ScriptMethodParams ¶ms); - static void SetStaticCreditImage(const ScriptMethodParams ¶ms); - static int IsStaticCreditsFinished(const ScriptMethodParams ¶ms); + static void SetStaticImage(const ScriptMethodParams ¶ms); + static int GetCurrentStaticCredit(const ScriptMethodParams ¶ms); + +private: + static int calculateSequenceHeight(int sequence); + static void draw(); public: AGSCreditz20(); }; From cf662a08250eb4ca25d140b241fe14c66d6b5b70 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 3 Feb 2021 19:57:44 -0800 Subject: [PATCH 207/215] AGS: Methods to read/write arrays that have safe save/load methods --- engines/ags/engine/game/savegame_components.cpp | 5 ++--- engines/ags/lib/allegro/color.cpp | 15 +++++++++++++++ engines/ags/lib/allegro/color.h | 9 +++++++++ engines/ags/shared/util/stream.h | 12 ++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp index 72a8c179cce4..6aa01c745704 100644 --- a/engines/ags/engine/game/savegame_components.cpp +++ b/engines/ags/engine/game/savegame_components.cpp @@ -207,8 +207,7 @@ HSaveError WriteGameState(PStream out) { // Game base game.WriteForSavegame(out); // Game palette - // TODO: probably no need to save this for hi/true-res game - out->WriteArray(palette, sizeof(color), 256); + out->SafeWriteArray(palette, PALETTE_COUNT); if (loaded_game_file_version <= kGameVersion_272) { // Global variables @@ -297,7 +296,7 @@ HSaveError ReadGameState(PStream in, int32_t cmp_ver, const PreservedParams &pp, // Game base game.ReadFromSavegame(in); // Game palette - in->ReadArray(palette, sizeof(color), 256); + in->SafeReadArray(palette, PALETTE_COUNT); if (loaded_game_file_version <= kGameVersion_272) { // Legacy interaction global variables diff --git a/engines/ags/lib/allegro/color.cpp b/engines/ags/lib/allegro/color.cpp index 0ae8c76b3fdd..3c8e7af25379 100644 --- a/engines/ags/lib/allegro/color.cpp +++ b/engines/ags/lib/allegro/color.cpp @@ -24,6 +24,7 @@ #include "ags/lib/allegro/system.h" #include "ags/lib/allegro/aintern.h" #include "ags/shared/core/types.h" +#include "ags/shared/util/stream.h" #include "common/textconsole.h" #include "common/system.h" #include "graphics/palette.h" @@ -49,6 +50,20 @@ int _rgb_a_shift_32 = 0; RGB_MAP *rgb_map; COLOR_MAP *color_map; +void color::readFromFile(AGS::Shared::Stream *file) { + r = file->ReadByte(); + g = file->ReadByte(); + b = file->ReadByte(); + filler = file->ReadByte(); +} + +void color::writeToFile(AGS::Shared::Stream *file) const { + file->WriteByte(r); + file->WriteByte(g); + file->WriteByte(b); + file->WriteByte(filler); +} + void set_color(int idx, const RGB *p) { _current_palette[idx] = *p; diff --git a/engines/ags/lib/allegro/color.h b/engines/ags/lib/allegro/color.h index db793f2fade7..8c9922502ea1 100644 --- a/engines/ags/lib/allegro/color.h +++ b/engines/ags/lib/allegro/color.h @@ -39,11 +39,20 @@ namespace AGS3 { class BITMAP; +namespace AGS { +namespace Shared { +class Stream; +} // namespace Shared +} // namespace AGS + #include "common/pack-start.h" // START STRUCT PACKING struct color { byte r, g, b; byte filler; + + void readFromFile(AGS::Shared::Stream *file); + void writeToFile(AGS::Shared::Stream *file) const; } PACKED_STRUCT; typedef color RGB; diff --git a/engines/ags/shared/util/stream.h b/engines/ags/shared/util/stream.h index 5489cde19068..281c56dcda8d 100644 --- a/engines/ags/shared/util/stream.h +++ b/engines/ags/shared/util/stream.h @@ -83,6 +83,18 @@ class Stream : public IAGSStream { // Fill the requested number of bytes with particular value size_t WriteByteCount(uint8_t b, size_t count); + + template + inline void SafeReadArray(T *arr, size_t count) { + for (size_t i = 0; i < count; ++i, ++arr) + arr->readFromFile(this); + } + + template + inline void SafeWriteArray(const T *arr, size_t count) { + for (size_t i = 0; i < count; ++i, ++arr) + arr->writeToFile(this); + } }; class ScummVMReadStream : public Common::SeekableReadStream { From 0feb06024e735861c2c3e0a0f9b682f767bd4a20 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 3 Feb 2021 20:13:12 -0800 Subject: [PATCH 208/215] AGS: Further cleaning up read/write structure arrays --- engines/ags/engine/ac/game.cpp | 2 +- engines/ags/shared/ac/gamesetupstructbase.cpp | 4 ++-- engines/ags/shared/game/room_file.cpp | 2 +- engines/ags/shared/util/compress.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp index f3aa47e3ab09..abd02ed02e88 100644 --- a/engines/ags/engine/ac/game.cpp +++ b/engines/ags/engine/ac/game.cpp @@ -1226,7 +1226,7 @@ void ReadCharacterExtras_Aligned(Stream *in) { } void restore_game_palette(Stream *in) { - in->ReadArray(&palette[0], sizeof(color), 256); + in->SafeReadArray(&palette[0], PALETTE_COUNT); } void restore_game_dialogs(Stream *in) { diff --git a/engines/ags/shared/ac/gamesetupstructbase.cpp b/engines/ags/shared/ac/gamesetupstructbase.cpp index 8c665fb5f551..24fd031bd354 100644 --- a/engines/ags/shared/ac/gamesetupstructbase.cpp +++ b/engines/ags/shared/ac/gamesetupstructbase.cpp @@ -155,7 +155,7 @@ void GameSetupStructBase::ReadFromFile(Stream *in) { } in->Read(&paluses[0], 256); // colors are an array of chars - in->Read(&defpal[0], sizeof(color) * 256); + in->SafeReadArray(&defpal[0], PALETTE_COUNT); numviews = in->ReadInt32(); numcharacters = in->ReadInt32(); playercharacter = in->ReadInt32(); @@ -199,7 +199,7 @@ void GameSetupStructBase::WriteToFile(Stream *out) { out->WriteArrayOfInt32(options, 100); out->Write(&paluses[0], 256); // colors are an array of chars - out->Write(&defpal[0], sizeof(color) * 256); + out->SafeWriteArray(&defpal[0], PALETTE_COUNT); out->WriteInt32(numviews); out->WriteInt32(numcharacters); out->WriteInt32(playercharacter); diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp index b39bb7059d4b..11f5baf9fe8d 100644 --- a/engines/ags/shared/game/room_file.cpp +++ b/engines/ags/shared/game/room_file.cpp @@ -675,7 +675,7 @@ HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool g } // sync bpalettes[0] with room.pal - memcpy(room->BgFrames[0].Palette, room->Palette, sizeof(color) * 256); + memcpy(room->BgFrames[0].Palette, room->Palette, sizeof(color) * PALETTE_COUNT); return HRoomFileError::None(); } diff --git a/engines/ags/shared/util/compress.cpp b/engines/ags/shared/util/compress.cpp index 0b8a4559667a..b9d423c445ba 100644 --- a/engines/ags/shared/util/compress.cpp +++ b/engines/ags/shared/util/compress.cpp @@ -295,7 +295,7 @@ void save_lzw(Stream *out, const Bitmap *bmpp, const color *pall) { // Now open same file for reading, and begin writing compressed data into required output stream lz_temp_s = ci_fopen(lztempfnm); soff_t temp_sz = lz_temp_s->GetLength(); - out->WriteArray(&pall[0], sizeof(color), 256); + out->SafeWriteArray(&pall[0], PALETTE_COUNT); out->WriteInt32(temp_sz); soff_t gobacto = out->GetPosition(); @@ -321,7 +321,7 @@ void load_lzw(Stream *in, Bitmap **dst_bmp, int dst_bpp, color *pall) { unsigned char *membuffer; int arin; - in->Read(&pall[0], sizeof(color) * 256); + in->SafeReadArray(&pall[0], PALETTE_COUNT); maxsize = in->ReadInt32(); uncompsiz = in->ReadInt32(); From 79c129b8ffeb0a2a1042fc8472f7b62cbd771de0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 3 Feb 2021 22:10:32 -0800 Subject: [PATCH 209/215] AGS: Fix savegame magic number to match standalone savegames --- engines/ags/engine/ac/richgamemedia.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/engine/ac/richgamemedia.h b/engines/ags/engine/ac/richgamemedia.h index 7c650edc5fd0..02cc2ee9ae17 100644 --- a/engines/ags/engine/ac/richgamemedia.h +++ b/engines/ags/engine/ac/richgamemedia.h @@ -31,7 +31,7 @@ namespace AGS3 { // Windows Vista Rich Save Games, modified to be platform-agnostic #define RM_MAXLENGTH 1024 -#define RM_MAGICNUMBER MKTAG('R', 'G', 'M', 'H') +#define RM_MAGICNUMBER MKTAG('H', 'M', 'G', 'R') // Forward declaration namespace AGS { From afbb9abf8da51215849e134421afef2bc40b36a8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 3 Feb 2021 22:29:26 -0800 Subject: [PATCH 210/215] AGS: Starting to add AgsCreditz 2.0 support methods --- .../ags/plugins/ags_creditz/ags_creditz.cpp | 38 ++++++++++++++++++- engines/ags/plugins/ags_creditz/ags_creditz.h | 3 +- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.cpp b/engines/ags/plugins/ags_creditz/ags_creditz.cpp index 9100cc5aa80b..bf56f30036d7 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.cpp +++ b/engines/ags/plugins/ags_creditz/ags_creditz.cpp @@ -472,8 +472,42 @@ int AGSCreditz20::GetCurrentStaticCredit(const ScriptMethodParams ¶ms) { return result; } -int AGSCreditz20::calculateSequenceHeight(int sequence) { - return 0; +void AGSCreditz20::calculateSequenceHeight(int sequence) { + int height, creditHeight, dum; + height = 0; + + for (uint currentCredit = 0; currentCredit < _state->_credits[sequence].size(); + ++currentCredit) { + + if (_state->_credits[sequence][currentCredit]._isSet) { + if (_state->_credits[sequence][currentCredit]._image) { + if (_state->_credits[sequence][currentCredit]._colorHeight < 0) + creditHeight = _engine->GetSpriteHeight(_state->_credits[sequence][currentCredit]._fontSlot); + else + creditHeight = _state->_credits[sequence][currentCredit]._colorHeight; + } else { + _engine->GetTextExtent(_state->_credits[sequence][currentCredit]._fontSlot, + _state->_credits[sequence][currentCredit]._text.c_str(), + &dum, &creditHeight); + } + + height += creditHeight; + } else { + height += VGACheck(_state->_emptyLineHeight); + } + } + + _state->_calculatedSequenceHeight = height; +} + +int AGSCreditz20::VGACheck(int value) { + int screenX, dum; + _engine->GetScreenDimensions(&screenX, &dum, &dum); + + if (screenX == 640) + return value * 2; + else + return value; } void AGSCreditz20::draw() { diff --git a/engines/ags/plugins/ags_creditz/ags_creditz.h b/engines/ags/plugins/ags_creditz/ags_creditz.h index df3f373b308e..d56583256be4 100644 --- a/engines/ags/plugins/ags_creditz/ags_creditz.h +++ b/engines/ags/plugins/ags_creditz/ags_creditz.h @@ -182,7 +182,8 @@ class AGSCreditz20 : public AGSCreditz { static int GetCurrentStaticCredit(const ScriptMethodParams ¶ms); private: - static int calculateSequenceHeight(int sequence); + static void calculateSequenceHeight(int sequence); + static int VGACheck(int value); static void draw(); public: AGSCreditz20(); From 32d78582f4c5c6561de1bb4ffcb28e9c2cff7fb3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 4 Feb 2021 20:00:46 -0800 Subject: [PATCH 211/215] AGS: SHow GUI error dialog for unsupported games --- engines/ags/ags.cpp | 2 +- engines/ags/engine/ac/route_finder.cpp | 3 ++- engines/ags/engine/platform/linux/acpllnx.cpp | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index d1d707a941b7..0a3cbfcdc17c 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -368,7 +368,7 @@ Common::Error AGSEngine::run() { // Do shutdown stuff ::AGS3::quit_free(); - return result ? Common::kUnknownError : Common::kNoError; + return Common::kNoError; } #ifdef USE_CUSTOM_EXCEPTION_HANDLER else { diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp index 421f08cb5474..ba69558cd5d9 100644 --- a/engines/ags/engine/ac/route_finder.cpp +++ b/engines/ags/engine/ac/route_finder.cpp @@ -119,7 +119,8 @@ void init_pathfinder(GameDataVersion game_file_version) { } void shutdown_pathfinder() { - route_finder_impl->shutdown_pathfinder(); + if (route_finder_impl) + route_finder_impl->shutdown_pathfinder(); } void set_wallscreen(Bitmap *wallscreen) { diff --git a/engines/ags/engine/platform/linux/acpllnx.cpp b/engines/ags/engine/platform/linux/acpllnx.cpp index 966ef23e095a..87e78d7140af 100644 --- a/engines/ags/engine/platform/linux/acpllnx.cpp +++ b/engines/ags/engine/platform/linux/acpllnx.cpp @@ -21,6 +21,7 @@ */ #include "ags/shared/core/platform.h" +#include "ags/ags.h" #if AGS_PLATFORM_OS_LINUX @@ -81,15 +82,15 @@ int AGSLinux::CDPlayerCommand(int cmdd, int datt) { } void AGSLinux::DisplayAlert(const char *text, ...) { - char displbuf[2000]; va_list ap; va_start(ap, text); - vsprintf(displbuf, text, ap); + Common::String msg = Common::String::vformat(text, ap); va_end(ap); + if (_logToStdErr) - debug("ERROR: %s\n", displbuf); + debug("ERROR: %s\n", msg.c_str()); else - debug("ERROR: %s\n", displbuf); + ::AGS::g_vm->GUIError(msg); } size_t BuildXDGPath(char *destPath, size_t destSize) { From c25451fe2248590b266484727e19bdf381c5005c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 4 Feb 2021 21:52:40 -0800 Subject: [PATCH 212/215] GRAPHICS: Support 24-bit surfaces as dest for blitFrom --- graphics/managed_surface.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp index b2b4a333683c..f3e6e7923cec 100644 --- a/graphics/managed_surface.cpp +++ b/graphics/managed_surface.cpp @@ -253,9 +253,9 @@ void ManagedSurface::blitFromInner(const Surface &src, const Common::Rect &srcRe return; if (format != src.format) { - // When the pixel format differs, the destination must be 2 or 4 bytes per pixel, - // and the source be 2/4 bytes as well or be paletted - assert(format.bytesPerPixel == 2 || format.bytesPerPixel == 4); + // When the pixel format differs, the destination must be non-paletted + assert(format.bytesPerPixel == 2 || format.bytesPerPixel == 3 + || format.bytesPerPixel == 4); assert(src.format.bytesPerPixel == 2 || src.format.bytesPerPixel == 4 || (src.format.bytesPerPixel == 1 && srcPalette)); } @@ -322,8 +322,13 @@ void ManagedSurface::blitFromInner(const Surface &src, const Common::Rect &srcRe destPixel = format.ARGBToColor(0xff, rDest, gDest, bDest); if (format.bytesPerPixel == 2) *(uint16 *)destVal = destPixel; - else + else if (format.bytesPerPixel == 4) *(uint32 *)destVal = destPixel; + else { + destVal[0] = rDest; + destVal[1] = gDest; + destVal[2] = bDest; + } } } } From 19350d17606130d1597d86bca3d8fbdc55cd0abb Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 4 Feb 2021 21:53:09 -0800 Subject: [PATCH 213/215] AGS: Fix starting up early 2.5 paletted games --- engines/ags/lib/allegro/gfx.cpp | 27 +++++++++++++++------------ engines/ags/lib/allegro/gfx.h | 1 + engines/ags/shared/gfx/image.cpp | 31 ++++++++++--------------------- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/engines/ags/lib/allegro/gfx.cpp b/engines/ags/lib/allegro/gfx.cpp index b66bedf23aa2..ffa5872ec805 100644 --- a/engines/ags/lib/allegro/gfx.cpp +++ b/engines/ags/lib/allegro/gfx.cpp @@ -153,7 +153,11 @@ BITMAP *create_bitmap_ex(int color_depth, int width, int height) { error("Invalid color depth"); } - return new Surface(width, height, format); + BITMAP *bitmap = new Surface(width, height, format); + if (color_depth == 8) + add_palette_if_needed(bitmap->getSurface()); + + return bitmap; } BITMAP *create_sub_bitmap(BITMAP *parent, int x, int y, int width, int height) { @@ -216,12 +220,11 @@ int bitmap_color_depth(BITMAP *bmp) { } int bitmap_mask_color(BITMAP *bmp) { - assert(bmp->format.bytesPerPixel > 1); return TRANSPARENT_COLOR(*bmp); } -void add_palette_if_needed(Graphics::ManagedSurface &src, Graphics::ManagedSurface &dest) { - if (src.format.bytesPerPixel == 1 && dest.format.bytesPerPixel > 1) { +void add_palette_if_needed(Graphics::ManagedSurface &surf) { + if (surf.format.bytesPerPixel == 1) { byte pal[PALETTE_SIZE]; palette_to_rgb8(_current_palette, pal); @@ -230,7 +233,7 @@ void add_palette_if_needed(Graphics::ManagedSurface &src, Graphics::ManagedSurfa pal[1] = 0; pal[2] = 0xff; - src.setPalette(pal, 0, PALETTE_COUNT); + surf.setPalette(pal, 0, PALETTE_COUNT); } } @@ -238,7 +241,7 @@ void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; - add_palette_if_needed(srcS, destS); + add_palette_if_needed(srcS); if (dynamic_cast(&destS) != nullptr) { destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), @@ -254,7 +257,7 @@ void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, i Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; - add_palette_if_needed(srcS, destS); + add_palette_if_needed(srcS); destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height)); @@ -264,7 +267,7 @@ void masked_blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_ Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; - add_palette_if_needed(srcS, destS); + add_palette_if_needed(srcS); destS.blitFrom(srcS, Common::Rect(src_x, src_y, src_x + width, src_y + height), Common::Point(dst_x, dst_y)); } @@ -274,7 +277,7 @@ void masked_stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int sour Graphics::ManagedSurface &srcS = **src; Graphics::ManagedSurface &destS = **dest; - add_palette_if_needed(srcS, destS); + add_palette_if_needed(srcS); destS.transBlitFrom(srcS, Common::Rect(source_x, source_y, source_x + source_width, source_y + source_height), Common::Rect(dest_x, dest_y, dest_x + dest_width, dest_y + dest_height)); @@ -284,7 +287,7 @@ void draw_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y) { Graphics::ManagedSurface &bmpS = **bmp; Graphics::ManagedSurface &spriteS = **sprite; - add_palette_if_needed(spriteS, bmpS); + add_palette_if_needed(spriteS); bmpS.transBlitFrom(spriteS, Common::Point(x, y), TRANSPARENT_COLOR(spriteS)); } @@ -293,7 +296,7 @@ void stretch_sprite(BITMAP *bmp, const BITMAP *sprite, int x, int y, int w, int Graphics::ManagedSurface &bmpS = **bmp; Graphics::ManagedSurface &spriteS = **sprite; - add_palette_if_needed(spriteS, bmpS); + add_palette_if_needed(spriteS); bmpS.transBlitFrom(spriteS, Common::Rect(0, 0, sprite->w, sprite->h), Common::Rect(x, y, x + w, y + h)); @@ -343,7 +346,7 @@ void draw_sprite_h_flip(BITMAP *bmp, const BITMAP *sprite, int x, int y) { Graphics::ManagedSurface &bmpS = **bmp; Graphics::ManagedSurface &spriteS = **sprite; - add_palette_if_needed(spriteS, bmpS); + add_palette_if_needed(spriteS); bmpS.transBlitFrom(spriteS, Common::Point(x, y), (uint)-1, true); } diff --git a/engines/ags/lib/allegro/gfx.h b/engines/ags/lib/allegro/gfx.h index b5006e55af55..dfa900e46af3 100644 --- a/engines/ags/lib/allegro/gfx.h +++ b/engines/ags/lib/allegro/gfx.h @@ -291,6 +291,7 @@ AL_FUNC(void, stretch_sprite, (BITMAP *bmp, const BITMAP *sprite, int x, int y, extern void clear_to_color(BITMAP *bitmap, int color); extern int bitmap_color_depth(BITMAP *bmp); extern int bitmap_mask_color(BITMAP *bmp); +extern void add_palette_if_needed(Graphics::ManagedSurface &surf); extern void blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height); extern void masked_blit(const BITMAP *src, BITMAP *dest, int src_x, int src_y, int dst_x, int dst_y, int width, int height); extern void stretch_blit(const BITMAP *src, BITMAP *dest, int source_x, int source_y, int source_width, int source_height, diff --git a/engines/ags/shared/gfx/image.cpp b/engines/ags/shared/gfx/image.cpp index 055dcba4e051..b29c6d8c61f7 100644 --- a/engines/ags/shared/gfx/image.cpp +++ b/engines/ags/shared/gfx/image.cpp @@ -111,28 +111,23 @@ int save_bitmap(Common::WriteStream &out, BITMAP *bmp, const RGB *pal) { const Graphics::PixelFormat requiredFormat_3byte(3, 8, 8, 8, 0, 0, 8, 16, 0); #endif - Graphics::ManagedSurface &src = bmp->getSurface(); - Graphics::Surface *tmp = nullptr; - const Graphics::Surface *surface; + const Graphics::ManagedSurface &src = bmp->getSurface(); + Graphics::ManagedSurface surface(bmp->w, bmp->h, requiredFormat_3byte); + surface.rawBlitFrom(bmp->getSurface(), Common::Rect(0, 0, src.w, src.h), + Common::Point(0, 0), src.getPalette()); - if (bmp->format == requiredFormat_3byte) { - surface = &src.rawSurface(); - } else { - surface = tmp = src.rawSurface().convertTo(requiredFormat_3byte); - } - - int dstPitch = surface->w * 3; + int dstPitch = surface.w * 3; int extraDataLength = (dstPitch % 4) ? 4 - (dstPitch % 4) : 0; int padding = 0; out.writeByte('B'); out.writeByte('M'); - out.writeUint32LE(surface->h * dstPitch + 54); + out.writeUint32LE(surface.h * dstPitch + 54); out.writeUint32LE(0); out.writeUint32LE(54); out.writeUint32LE(40); - out.writeUint32LE(surface->w); - out.writeUint32LE(surface->h); + out.writeUint32LE(surface.w); + out.writeUint32LE(surface.h); out.writeUint16LE(1); out.writeUint16LE(24); out.writeUint32LE(0); @@ -142,17 +137,11 @@ int save_bitmap(Common::WriteStream &out, BITMAP *bmp, const RGB *pal) { out.writeUint32LE(0); out.writeUint32LE(0); - for (uint y = surface->h; y-- > 0;) { - out.write((const void *)surface->getBasePtr(0, y), dstPitch); + for (uint y = surface.h; y-- > 0;) { + out.write((const void *)surface.getBasePtr(0, y), dstPitch); out.write(&padding, extraDataLength); } - // free tmp surface - if (tmp) { - tmp->free(); - delete tmp; - } - return true; } From b60a629bfbbf50a944321e7c2db222ab04f1d9a1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 6 Feb 2021 16:30:37 -0800 Subject: [PATCH 214/215] AGS: Remove unused local --- engines/ags/ags.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp index 0a3cbfcdc17c..486a4e522c90 100644 --- a/engines/ags/ags.cpp +++ b/engines/ags/ags.cpp @@ -363,7 +363,7 @@ Common::Error AGSEngine::run() { if (usetup.disable_exception_handling) #endif { - int result = AGS3::initialize_engine(startup_opts); + AGS3::initialize_engine(startup_opts); // Do shutdown stuff ::AGS3::quit_free(); From c0abf0b0841154506e7874d25e5fcb3847c4f2bc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 6 Feb 2021 16:33:25 -0800 Subject: [PATCH 215/215] AGS: Fix std::unordered_map insert to ignore duplicates --- engines/ags/lib/std/map.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engines/ags/lib/std/map.h b/engines/ags/lib/std/map.h index b64afd9f98c5..fec3fbc66e68 100644 --- a/engines/ags/lib/std/map.h +++ b/engines/ags/lib/std/map.h @@ -197,6 +197,11 @@ template, class unordered_map : public Common::HashMap { public: pair insert(pair elem) { + // unordered_map doesn't replace already existing keys + if (this->contains(elem.first)) + return pair(elem.first, this->operator[](elem.first)); + + // Add item to map this->operator[](elem.first) = elem.second; return elem; }